aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYING340
-rw-r--r--COPYING.buildbot282
-rw-r--r--COPYING.decorator25
-rw-r--r--COPYING.htpasswd28
-rw-r--r--COPYING.jinja231
-rw-r--r--COPYING.setuptools22
-rw-r--r--COPYING.sqlalchemy17
-rw-r--r--COPYING.tempita7
-rw-r--r--COPYING.twisted17
-rw-r--r--README113
-rw-r--r--README-GOOGLE-CLOUD68
-rw-r--r--README-NEW-AUTOBUILDER362
-rw-r--r--README-QUICKSTART6
-rwxr-xr-xab-prserv79
-rw-r--r--autobuilder.pth.in15
-rwxr-xr-xbin/buildbot5
-rwxr-xr-xbin/buildworker5
-rwxr-xr-xbin/buildworker-janitor133
-rwxr-xr-xbin/cftp5
-rwxr-xr-xbin/checkvnc10
-rwxr-xr-xbin/ckeygen5
-rwxr-xr-xbin/conch5
-rwxr-xr-xbin/forcebuild.py187
-rwxr-xr-xbin/htpasswd123
-rwxr-xr-xbin/lore5
-rwxr-xr-xbin/mailmail5
-rwxr-xr-xbin/manhole5
-rwxr-xr-xbin/migrate10
-rwxr-xr-xbin/migrate-repository10
-rwxr-xr-xbin/pyhtmlizer5
-rwxr-xr-xbin/tap2deb5
-rwxr-xr-xbin/tap2rpm5
-rwxr-xr-xbin/tapconvert5
-rwxr-xr-xbin/tkconch5
-rwxr-xr-xbin/trial5
-rwxr-xr-xbin/twistd5
-rwxr-xr-xbin/worker-init39
-rw-r--r--buildset-config.autobuilder-qa/test_fail_conditions.conf20
-rw-r--r--buildset-config.controller/build-appliance.conf30
-rw-r--r--buildset-config.controller/buildtools.conf24
-rw-r--r--buildset-config.controller/eclipse-plugin-neon.conf11
-rw-r--r--buildset-config.controller/eclipse-plugin-oxygen.conf11
-rw-r--r--buildset-config.controller/nightly-arm-lsb.conf36
-rw-r--r--buildset-config.controller/nightly-arm.conf44
-rw-r--r--buildset-config.controller/nightly-arm64.conf35
-rw-r--r--buildset-config.controller/nightly-checkuri.conf25
-rw-r--r--buildset-config.controller/nightly-deb-non-deb.conf16
-rw-r--r--buildset-config.controller/nightly-mips-lsb.conf36
-rw-r--r--buildset-config.controller/nightly-mips.conf39
-rw-r--r--buildset-config.controller/nightly-mips64.conf35
-rw-r--r--buildset-config.controller/nightly-multilib.conf49
-rw-r--r--buildset-config.controller/nightly-musl-x86-64.conf19
-rw-r--r--buildset-config.controller/nightly-musl.conf18
-rw-r--r--buildset-config.controller/nightly-no-x11.conf24
-rw-r--r--buildset-config.controller/nightly-non-gpl3.conf21
-rw-r--r--buildset-config.controller/nightly-oe-selftest.conf21
-rw-r--r--buildset-config.controller/nightly-oecore.conf29
-rw-r--r--buildset-config.controller/nightly-packagemanagers.conf24
-rw-r--r--buildset-config.controller/nightly-ppc-lsb.conf36
-rw-r--r--buildset-config.controller/nightly-ppc.conf38
-rw-r--r--buildset-config.controller/nightly-qa-extras.conf83
-rw-r--r--buildset-config.controller/nightly-refkit.conf34
-rw-r--r--buildset-config.controller/nightly-rpm-non-rpm.conf18
-rw-r--r--buildset-config.controller/nightly-uclibc.conf18
-rw-r--r--buildset-config.controller/nightly-wic.conf40
-rw-r--r--buildset-config.controller/nightly-world-lsb.conf25
-rw-r--r--buildset-config.controller/nightly-world.conf17
-rw-r--r--buildset-config.controller/nightly-x32.conf30
-rw-r--r--buildset-config.controller/nightly-x86-64-lsb.conf36
-rw-r--r--buildset-config.controller/nightly-x86-64.conf40
-rw-r--r--buildset-config.controller/nightly-x86-lsb.conf35
-rw-r--r--buildset-config.controller/nightly-x86.conf41
-rw-r--r--buildset-config.controller/nightly.conf170
-rw-r--r--buildset-config.controller/poky-tiny.conf18
-rw-r--r--buildset-config.controller/update-buildhistory.conf13
-rw-r--r--buildset-config.controller/yoctoAB.conf12
-rw-r--r--buildset-config.examples/awesomefirmware.conf36
-rw-r--r--buildset-config.examples/gitpoller.conf33
-rw-r--r--buildset-config.examples/hello.conf16
-rw-r--r--buildset-config.examples/webhobbish.conf48
-rw-r--r--buildset-config.freescale/nightly-fsl-arm-lsb.conf41
-rw-r--r--buildset-config.freescale/nightly-fsl-arm.conf46
-rw-r--r--buildset-config.freescale/nightly-fsl-ppc-lsb.conf32
-rw-r--r--buildset-config.freescale/nightly-fsl-ppc.conf33
-rw-r--r--buildset-config.iot-devkit/iot-devkit.conf34
-rw-r--r--buildset-config.iot-devkit/yoctoAB.conf2
-rw-r--r--buildset-config.kernel/kernel-arm-lsb.conf58
-rw-r--r--buildset-config.kernel/kernel-arm.conf52
-rw-r--r--buildset-config.kernel/kernel-arm64.conf52
-rw-r--r--buildset-config.kernel/kernel-mips-lsb.conf58
-rw-r--r--buildset-config.kernel/kernel-mips.conf52
-rw-r--r--buildset-config.kernel/kernel-ppc-lsb.conf58
-rw-r--r--buildset-config.kernel/kernel-ppc.conf52
-rw-r--r--buildset-config.kernel/kernel-x86-64-lsb.conf58
-rw-r--r--buildset-config.kernel/kernel-x86-64.conf52
-rw-r--r--buildset-config.kernel/kernel-x86-lsb.conf58
-rw-r--r--buildset-config.kernel/kernel-x86.conf52
-rw-r--r--buildset-config.kernel/nightly-kernel.conf63
-rw-r--r--buildset-config.kernel/yoctoAB.conf5
-rw-r--r--buildset-config.meta-intel-isg/crystalforest-lsb.conf31
-rw-r--r--buildset-config.meta-intel-isg/crystalforest.conf24
-rw-r--r--buildset-config.meta-intel-isg/nightly-isg.conf30
-rw-r--r--buildset-config.meta-intel-isg/yoctoAB.conf2
-rw-r--r--buildset-config.meta-intel/intel-core2-32-lsb-rt.conf64
-rw-r--r--buildset-config.meta-intel/intel-core2-32-lsb.conf60
-rw-r--r--buildset-config.meta-intel/intel-core2-32-rt.conf57
-rw-r--r--buildset-config.meta-intel/intel-core2-32.conf58
-rw-r--r--buildset-config.meta-intel/intel-corei7-64-lsb-rt.conf62
-rw-r--r--buildset-config.meta-intel/intel-corei7-64-lsb.conf60
-rw-r--r--buildset-config.meta-intel/intel-corei7-64-rt.conf56
-rw-r--r--buildset-config.meta-intel/intel-corei7-64.conf59
-rw-r--r--buildset-config.meta-intel/intel-quark.conf58
-rw-r--r--buildset-config.meta-intel/jasperforest-lsb.conf58
-rw-r--r--buildset-config.meta-intel/jasperforest.conf51
-rw-r--r--buildset-config.meta-intel/nightly-meta-intel-world.conf55
-rw-r--r--buildset-config.meta-intel/nightly-meta-intel.conf106
-rw-r--r--buildset-config.meta-intel/nightly-musl-core2-32.conf53
-rw-r--r--buildset-config.meta-intel/nightly-musl.conf53
-rw-r--r--buildset-config.meta-intel/nightly-x32.conf58
-rw-r--r--buildset-config.meta-intel/nuc-lsb.conf58
-rw-r--r--buildset-config.meta-intel/nuc.conf52
-rw-r--r--buildset-config.meta-intel/sugarbay-lsb.conf58
-rw-r--r--buildset-config.meta-intel/sugarbay.conf52
-rw-r--r--buildset-config.meta-intel/yoctoAB.conf5
-rw-r--r--buildset-config.tizen/nightly-tizen-ivi.conf24
-rw-r--r--buildset-config.tizen/nightly-tizen.conf24
-rw-r--r--buildset-config.tizen/nightly.conf52
-rw-r--r--buildset-config.tizen/update-buildhistory.conf8
-rw-r--r--buildset-config.tizen/yoctoAB.conf2
-rw-r--r--buildset-config.toaster/toaster-build.conf29
-rw-r--r--buildset-config.toaster/toaster-tests.conf20
-rw-r--r--buildset-config.toaster/yoctoAB.conf2
l---------buildset-config.yocto-qa/buildtools.conf1
l---------buildset-config.yocto-qa/eclipse-plugin-neon.conf1
-rw-r--r--buildset-config.yocto-qa/intel-corei7-64-daft.conf59
l---------buildset-config.yocto-qa/nightly-arm.conf1
l---------buildset-config.yocto-qa/nightly-multilib.conf1
-rw-r--r--buildset-config.yocto-qa/nightly-oe-build-perf-test.conf27
l---------buildset-config.yocto-qa/nightly-oe-selftest.conf1
l---------buildset-config.yocto-qa/nightly-oecore.conf1
l---------buildset-config.yocto-qa/nightly-packagemanagers.conf1
-rw-r--r--buildset-config.yocto-qa/nightly-qa-distro.conf49
l---------buildset-config.yocto-qa/nightly-qa-extras.conf1
l---------buildset-config.yocto-qa/nightly-world.conf1
l---------buildset-config.yocto-qa/nightly-x32.conf1
l---------buildset-config.yocto-qa/nightly-x86-64-lsb.conf1
l---------buildset-config.yocto-qa/nightly-x86.conf1
l---------buildset-config.yocto-qa/poky-tiny.conf1
-rw-r--r--config/autobuilder.conf.example100
-rw-r--r--config/autobuilder.conf.readme48
-rw-r--r--docs/YoctoAutobuilderDevelopersDocument.html1
-rw-r--r--docs/images/image00.pngbin28784 -> 0 bytes
-rw-r--r--docs/images/image01.pngbin67622 -> 0 bytes
-rw-r--r--etc/distro-version/Meego-1.11424
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/PKG-INFO55
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/SOURCES.txt137
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/entry_points.txt4
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/requires.txt4
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/top_level.txt1
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/__init__.py69
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_debugsupport.c78
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/__init__.py225
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_bundle.py49
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_constants.py267
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_native.py45
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/tests.py80
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_stringdefs.py130
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/bccache.py301
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/compiler.py1649
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/constants.py32
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/debug.py339
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/defaults.py40
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py1121
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/exceptions.py143
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/ext.py612
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/filters.py801
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/lexer.py681
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/loaders.py450
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/meta.py102
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/nodes.py910
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/optimizer.py68
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/parser.py896
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/runtime.py548
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/sandbox.py361
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/tests.py161
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/__init__.py95
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/api.py245
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/core_tags.py285
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/debug.py60
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/doctests.py29
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/ext.py455
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/filters.py356
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/imports.py141
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/inheritance.py227
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/lexnparse.py387
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/loader.py190
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/regression.py255
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/__init__.py0
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/broken.html3
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/foo/test.html1
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/syntaxerror.html4
-rw-r--r--lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/test.html1
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/security.py165
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/tests.py93
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/utils.py82
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/utils.py601
-rwxr-xr-xlib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/visitor.py87
-rw-r--r--lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO137
-rw-r--r--lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt544
-rw-r--r--lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt2
-rw-r--r--lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt1
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/__init__.py122
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mxodbc.py150
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mysqldb.py150
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/pyodbc.py124
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/zxJDBC.py58
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.py7
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.sobin37050 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.py7
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.sobin45289 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/databases/__init__.py37
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/__init__.py19
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/__init__.py0
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/base.py450
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/__init__.py18
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/base.py582
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/mysqldb.py68
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/__init__.py22
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/base.py700
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/kinterbasdb.py167
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/__init__.py9
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/base.py593
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/informixdb.py73
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/__init__.py9
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/base.py1116
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/sapdb.py23
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/__init__.py26
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/adodbapi.py69
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/base.py1456
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/information_schema.py96
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/mxodbc.py93
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pymssql.py109
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pyodbc.py221
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/zxjdbc.py75
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/__init__.py27
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/base.py2571
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqlconnector.py135
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqldb.py79
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/oursql.py266
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pymysql.py38
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pyodbc.py82
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/zxjdbc.py117
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/__init__.py23
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/base.py1139
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/cx_oracle.py718
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/zxjdbc.py215
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgres.py16
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/__init__.py20
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/base.py1449
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pg8000.py121
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/psycopg2.py334
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pypostgresql.py73
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/zxjdbc.py42
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/__init__.py20
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/base.py753
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/pysqlite.py247
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/__init__.py26
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/base.py434
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/mxodbc.py23
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pyodbc.py83
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pysybase.py100
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/__init__.py301
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py2995
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/ddl.py172
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/default.py801
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/reflection.py477
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/strategies.py242
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/threadlocal.py126
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/url.py221
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/event.py347
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/events.py429
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/exc.py238
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/associationproxy.py912
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/compiler.py355
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative.py1425
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/horizontal_shard.py128
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/hybrid.py425
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/mutable.py554
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/orderinglist.py321
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/serializer.py161
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/sqlsoup.py797
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/interfaces.py305
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/log.py212
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/__init__.py1278
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/attributes.py1335
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/collections.py1473
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dependency.py1161
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/deprecated_interfaces.py583
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/descriptor_props.py405
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dynamic.py313
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/evaluator.py111
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/events.py1046
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/exc.py119
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/identity.py254
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/instrumentation.py691
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/interfaces.py754
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py2825
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/properties.py1250
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py2936
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/scoping.py133
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py1725
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/shard.py15
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/state.py557
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/strategies.py1300
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/sync.py107
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py583
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py625
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/pool.py958
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/processors.py109
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/schema.py2950
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/__init__.py66
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py1793
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/expression.py5127
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/functions.py134
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/operators.py154
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/util.py717
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/visitors.py266
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/types.py2140
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/__init__.py32
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/_collections.py897
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/compat.py211
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/deprecations.py118
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/langhelpers.py791
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/queue.py191
-rwxr-xr-xlib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/topological.py83
-rw-r--r--lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/PKG-INFO32
-rw-r--r--lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/SOURCES.txt10
-rw-r--r--lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/top_level.txt1
-rw-r--r--lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/zip-safe1
-rwxr-xr-xlib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/__init__.py1183
-rwxr-xr-xlib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/_looper.py163
-rwxr-xr-xlib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/compat3.py45
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO14
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt801
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt5
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt1
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/cftp15
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/ckeygen15
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/conch15
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/lore16
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/mailmail20
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/manhole16
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/pyhtmlizer12
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2deb16
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2rpm19
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tapconvert12
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tkconch15
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/trial18
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/twistd14
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/__init__.py24
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/__init__.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py674
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/internet.py408
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/reactors.py83
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/service.py413
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/strports.py103
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/test_internet.py252
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py18
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py37
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py308
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py9
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py73
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py21
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py256
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py107
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py478
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py96
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py102
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py16
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py138
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py29
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py450
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py1087
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py186
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py868
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py402
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py75
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py340
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py146
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py124
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py49
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py11
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py73
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py26
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py329
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py832
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py190
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py512
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py572
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py38
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py294
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py281
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py117
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py637
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py141
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py934
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py181
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py809
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py48
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py348
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py42
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py1617
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py848
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py95
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py87
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py1086
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py208
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py49
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py399
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py975
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py279
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py609
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py80
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py552
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py730
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py171
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py765
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py560
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py496
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py644
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py1037
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py372
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py47
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py102
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py706
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py82
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py1256
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py995
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py173
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py767
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py101
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py2225
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py1077
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py67
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS414
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README11
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py121
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py11
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py240
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py197
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py457
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/copyright.py39
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/__init__.py13
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/_digest.py129
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/checkers.py268
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/credentials.py483
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/error.py41
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/pamauth.py79
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/portal.py121
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/strcred.py270
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/__init__.py9
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/adbapi.py483
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/__init__.py12
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_baseprocess.py62
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_dumbwin32proc.py388
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_glibbase.py387
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_newtls.py270
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_oldtls.py381
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_pollingfile.py300
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixserialport.py74
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixstdio.py175
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.c101
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.sobin20487 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_signals.py184
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_ssl.py32
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sslverify.py749
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_threadedselect.py361
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32serialport.py126
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32stdio.py124
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/abstract.py517
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/address.py146
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/base.py1190
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/cfreactor.py501
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/default.py56
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/defer.py1561
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/endpoints.py1347
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py394
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/error.py448
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/fdesc.py118
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gireactor.py139
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/glib2reactor.py44
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk2reactor.py114
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk3reactor.py65
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtkreactor.py250
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/inotify.py405
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/interfaces.py2083
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/abstract.py400
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/build.bat4
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/const.py26
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/interfaces.py47
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/acceptex.pxi46
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/connectex.pxi47
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.c6376
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.pyx312
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c62
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.h51
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsarecv.pxi76
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsasend.pxi30
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/notes.txt24
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/reactor.py275
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/setup.py23
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/tcp.py578
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/udp.py382
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/kqreactor.py305
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/main.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pollreactor.py187
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py652
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/process.py1074
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/protocol.py830
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pyuisupport.py37
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/qtreactor.py19
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/reactor.py38
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/selectreactor.py203
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/serialport.py87
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/ssl.py203
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/stdio.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/task.py793
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tcp.py1172
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_posixifaces.py131
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_win32ifaces.py119
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/connectionmixins.py649
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/not-a-certificate1
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing1.pem26
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2-duplicate.pem26
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2.pem26
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fakeendpoint.py66
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/inlinecb_tests.py92
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/process_helper.py33
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/reactormixins.py409
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_abstract.py56
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_address.py292
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_base.py272
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_baseprocess.py73
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_core.py331
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_default.py83
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_endpoints.py2021
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_epollreactor.py246
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_fdset.py394
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_filedescriptor.py41
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_glibbase.py66
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtk3reactor.py152
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtkreactor.py95
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inlinecb.py13
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inotify.py504
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_interfaces.py53
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_iocp.py150
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_main.py38
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_newtls.py194
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_pollingfile.py46
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixbase.py387
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixprocess.py340
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_process.py711
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_protocol.py357
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_qtreactor.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_serialport.py72
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_sigchld.py194
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_socket.py128
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_stdio.py195
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tcp.py2077
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_threads.py218
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_time.py66
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tls.py432
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp.py197
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp_internals.py165
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_unix.py558
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_win32events.py183
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/threads.py123
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tksupport.py75
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py347
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/unix.py518
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/utils.py219
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/win32eventreactor.py430
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxreactor.py184
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxsupport.py61
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/__init__.py21
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/default.py56
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/docbook.py68
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/htmlbook.py49
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/indexer.py50
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/latex.py463
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lint.py204
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lmath.py85
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/man2lore.py295
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/numberer.py33
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/process.py120
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/lore.py155
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/slides.py359
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/template.mgp24
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/__init__.py1
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out.html2
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out_multiple.html5
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_unnumbered_out.html2
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test.xhtml21
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test2.xhtml22
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out.html2
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out2.html2
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple.html9
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple3.html9
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple4.html9
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/template.tpl13
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_docbook.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_latex.py146
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lint.py132
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lmath.py72
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lore.py1198
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_man2lore.py169
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_scripts.py27
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_slides.py85
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/texi.py109
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/NEWS161
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/README3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/tree.py1122
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-lat1.ent196
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-special.ent80
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-symbol.ent237
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-strict.dtd978
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-transitional.dtd1201
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/__init__.py15
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/alias.py435
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/bounce.py60
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/imap4.py6208
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/mail.py333
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/maildir.py518
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pb.py115
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3.py1071
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3client.py706
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/protocols.py233
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relay.py114
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relaymanager.py631
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/mailmail.py366
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/smtp.py1934
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/tap.py333
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/pop3testserver.py314
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/rfc822.message86
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/server.pem36
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_bounce.py32
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_imap.py4829
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mail.py2062
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mailmail.py75
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_options.py247
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3.py1071
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3client.py582
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_scripts.py18
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_smtp.py1520
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/NEWS309
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/README6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/__init__.py8
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/_inspectro.py369
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/explorer.py654
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.glade342
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.py219
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/inspectro.glade510
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/logview.glade39
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/service.py399
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/telnet.py117
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/test_explorer.py102
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/__init__.py7
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.glade268
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.py375
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/__init__.py4
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/test_gtk2manhole.py48
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/__init__.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/authority.py334
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/cache.py124
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/client.py955
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/common.py278
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/dns.py1954
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/error.py95
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/hosts.py157
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/resolve.py59
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/root.py446
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/secondary.py179
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/server.py205
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/srvconnect.py211
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/tap.py150
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_cache.py129
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_client.py678
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_common.py71
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_dns.py1501
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_hosts.py232
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_names.py956
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_rootresolve.py705
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_srvconnect.py169
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_tap.py99
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/NEWS243
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/README3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/__init__.py11
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/database.py1051
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/news.py90
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/nntp.py1036
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/tap.py138
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_database.py224
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_news.py107
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_nntp.py197
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/NEWS112
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/README4
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/__init__.py20
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ethernet.py56
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ip.py72
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/raw.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/rawudp.py55
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ethernet.py226
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ip.py417
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_rawudp.py327
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/NEWS62
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/README4
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/tuntap.py170
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/aot.py560
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/crefutil.py163
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/dirdbm.py358
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/sob.py227
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/styles.py262
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/test_styles.py55
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugin.py255
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/__init__.py17
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_anonymous.py40
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_file.py60
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_memory.py68
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_sshkeys.py51
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_unix.py138
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_conch.py18
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_core.py9
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_ftp.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_inet.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_lore.py38
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_mail.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_manhole.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_names.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_news.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_portforward.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_qtstub.py45
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_reactors.py42
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_runner.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_socks.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_telnet.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_trial.py59
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_web.py11
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_words.py43
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/__init__.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/amp.py2705
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/basic.py939
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/dict.py362
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/finger.py42
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ftp.py2955
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/nmea.py209
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/rockwell.py268
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py297
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ident.py231
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/loopback.py372
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/memcache.py758
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/mouseman.py127
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/pcp.py204
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/policies.py725
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/portforward.py87
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/postfix.py112
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/shoutcast.py111
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/sip.py1347
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/socks.py240
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/stateful.py52
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/telnet.py325
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/test_tls.py1499
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/tls.py613
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/wire.py90
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/__init__.py13
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.c3348
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.pyx285
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.c66
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.sobin17422 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_inotify.py101
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_release.py1371
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py668
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/compat.py208
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/components.py438
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/constants.py377
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/context.py133
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/deprecate.py534
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/dist.py427
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/failure.py650
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/fakepwd.py219
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/filepath.py1442
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/finalize.py46
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/formmethod.py363
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hashlib.py24
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hook.py176
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/htmlizer.py91
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/lockfile.py214
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/log.py627
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/logfile.py323
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/modules.py758
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/monkey.py73
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/procutils.py45
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/randbytes.py131
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/rebuild.py271
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/reflect.py827
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/release.py63
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/roots.py248
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/runtime.py144
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.c502
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.sobin33218 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/shortcut.py76
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/syslog.py107
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/systemd.py87
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/__init__.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/deprecatedattributes.py21
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/modules_helpers.py64
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/pullpipe.py40
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_components.py770
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_constants.py778
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_deprecate.py767
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_dist.py526
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_fakepwd.py386
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_hashlib.py90
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_htmlizer.py41
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_inotify.py120
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_release.py2598
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_runtime.py106
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_sendmsg.py543
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_shellcomp.py623
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_syslog.py151
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_systemd.py173
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_util.py928
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_versions.py323
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_win32.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zipstream.py367
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zshcomp.py228
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/text.py208
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadable.py118
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadpool.py240
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/twisted-completion.zsh33
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/urlpath.py122
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/usage.py973
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/util.py998
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/versions.py249
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/win32.py164
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zippath.py268
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zipstream.py319
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/README.txt9
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_cftp34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_ckeygen34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_conch34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_lore34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_manhole34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_mktap34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_pyhtmlizer34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2deb34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2rpm34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tapconvert34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkconch34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkmktap34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_trial34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_twistd34
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_websetroot34
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zshcomp.py824
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/__init__.py15
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetd.py70
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdconf.py194
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdtap.py163
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.c57
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.sobin17404 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmon.py310
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmontap.py73
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmon.py477
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmontap.py87
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/NEWS107
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/README3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/__init__.py27
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistd_unix.py349
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistw.py50
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/htmlizer.py69
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/manhole.py69
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2deb.py281
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2rpm.py331
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tapconvert.py57
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_scripts.py178
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_tap2rpm.py399
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tkunzip.py290
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/trial.py371
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/twistd.py30
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/__init__.py12
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py358
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/flavors.py590
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/interfaces.py28
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/jelly.py1151
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/pb.py1434
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/publish.py142
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/__init__.py12
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/gtk2util.py218
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/login2.glade461
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tktree.py204
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tkutil.py397
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/util.py215
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/ftp.py69
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/manhole.py54
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/portforward.py27
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/socks.py38
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/telnet.py32
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/_preamble.py17
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/crash_test_dummy.py34
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/generator_failure_tests.py178
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/iosim.py270
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/mock_win32process.py48
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder1.py15
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder2.py16
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_basic.py57
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra1.py23
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra2.py35
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_cmdline.py5
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_echoer.py11
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_fds.py40
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_linger.py17
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_reader.py12
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_signal.py8
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_stdinreader.py23
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tester.py37
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tty.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_twisted.py43
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/proto_helpers.py567
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.c1443
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.py7
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.pyx21
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.sobin42264 -> 0 bytes
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_IE.py4
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_VE.py4
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_ZDE.py4
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/server.pem36
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/ssl_helpers.py26
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_consumer.py39
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_halfclose.py66
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_hostpeer.py32
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_lastwrite.py45
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_loseconn.py48
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_producer.py55
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_write.py31
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_writeseq.py30
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_abstract.py83
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_adbapi.py819
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_amp.py3178
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_application.py878
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_banana.py278
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_compat.py252
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_context.py15
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_cooperator.py669
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defer.py2002
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defgen.py314
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dict.py22
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_digestauth.py671
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dirdbm.py170
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_doc.py104
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_epoll.py158
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_error.py170
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_explorer.py236
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_factories.py197
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_failure.py595
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_fdesc.py235
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_finger.py67
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_formmethod.py98
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp.py3111
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp_options.py80
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_hook.py150
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_htb.py109
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ident.py194
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_import.py75
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_internet.py1396
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_iutils.py296
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_jelly.py671
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_lockfile.py445
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_log.py773
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_logfile.py320
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_loopback.py419
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_manhole.py75
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_memcache.py663
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_modules.py478
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_monkey.py161
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_newcred.py445
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_nmea.py115
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_paths.py1622
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pb.py1846
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pbfailure.py475
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pcp.py368
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_persisted.py377
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_plugin.py719
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_policies.py736
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_postfix.py108
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_process.py2561
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_protocols.py1260
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_randbytes.py119
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_rebuild.py252
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_reflect.py873
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_roots.py63
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_shortcut.py26
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sip.py984
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sob.py172
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_socks.py498
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ssl.py726
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sslverify.py558
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stateful.py81
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stdio.py371
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strcred.py657
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strerror.py151
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stringtransport.py279
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strports.py133
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_task.py739
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp.py1820
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp_internals.py249
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_text.py242
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadable.py103
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadpool.py526
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threads.py412
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tpfile.py52
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_twistd.py1549
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_udp.py721
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_unix.py405
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_usage.py584
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/testutils.py55
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/CREDITS60
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/ChangeLog.Old3888
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/NEWS1809
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/README14
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/__init__.py52
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/itrial.py251
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/reporter.py1245
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/runner.py861
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/detests.py201
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/erroneous.py167
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite.py21
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite2.py21
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite3.py28
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockdoctest.py104
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduleself.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduletest.py11
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/notpython2
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/novars.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/packages.py156
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/sample.py108
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/scripttest.py14
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/skipping.py268
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/suppression.py112
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_assertions.py1026
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_deferred.py220
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_doctest.py64
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_keyboard.py113
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_loader.py611
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_log.py235
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_output.py162
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_plugins.py46
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_pyunitcompat.py222
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_reporter.py1650
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_runner.py1034
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_script.py443
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_test_visitor.py82
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_testcase.py68
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_tests.py1379
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_util.py584
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_warning.py472
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/weird.py22
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/unittest.py1778
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/util.py430
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/__init__.py15
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/__init__.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/basic.py59
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/digest.py54
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py225
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_element.py185
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_flatten.py314
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_newclient.py1502
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_stan.py325
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/client.py1600
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/demo.py24
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/distrib.py373
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/domhelpers.py268
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/error.py381
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/failure.xhtml71
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/guard.py17
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/html.py49
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http.py1818
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http_headers.py277
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/iweb.py526
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/microdom.py1028
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/proxy.py303
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/resource.py319
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/rewrite.py52
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/script.py170
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/server.py592
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/soap.py154
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/static.py1033
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/sux.py636
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/tap.py232
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/template.py566
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/__init__.py7
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/_util.py77
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_cgi.py270
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_distrib.py434
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_domhelpers.py306
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_error.py151
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_flatten.py348
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http.py1663
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http_headers.py616
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_httpauth.py634
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_newclient.py2521
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_proxy.py544
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_resource.py80
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_script.py70
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_soap.py114
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_stan.py139
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_static.py1486
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_tap.py196
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_template.py810
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_util.py380
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_vhost.py105
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_web.py1079
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_webclient.py3144
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_wsgi.py1572
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xml.py1105
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xmlrpc.py849
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/NEWS573
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/README6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py299
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/util.py433
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/vhost.py135
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/wsgi.py403
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/xmlrpc.py590
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/_version.py3
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/ewords.py34
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/baseaccount.py62
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basechat.py512
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basesupport.py270
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/instancemessenger.glade3165
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/interfaces.py364
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/ircsupport.py263
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/locals.py26
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/pbsupport.py260
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/iwords.py266
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/irc.py3302
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/__init__.py8
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/client.py368
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/component.py474
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/error.py336
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/ijabber.py199
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jid.py249
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jstrports.py31
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl.py243
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl_mechanisms.py240
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmlstream.py1136
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmpp_stringprep.py253
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/msn.py2479
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/oscar.py1235
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/service.py1223
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/tap.py74
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/__init__.py1
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basechat.py68
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basesupport.py97
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_domish.py434
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc.py1898
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc_service.py216
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_ircsupport.py79
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberclient.py414
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbercomponent.py422
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbererror.py342
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjid.py225
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjstrports.py34
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersasl.py272
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersaslmechanisms.py90
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmlstream.py1334
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmppstringprep.py92
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_msn.py522
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_oscar.py24
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_service.py995
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_tap.py78
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xishutil.py345
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmlstream.py224
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmpproutertap.py84
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xpath.py260
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/NEWS369
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/README5
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/domish.py848
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/utility.py372
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xmlstream.py261
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpath.py333
-rw-r--r--lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.g375
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.py508
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xmpproutertap.py30
-rw-r--r--lib/python2.7/site-packages/autobuilder/Autobuilder.py396
-rw-r--r--lib/python2.7/site-packages/autobuilder/BuildSet.py185
-rw-r--r--lib/python2.7/site-packages/autobuilder/YoctoMailer.py109
-rw-r--r--lib/python2.7/site-packages/autobuilder/Yocto_Message_Formatter.py79
-rw-r--r--lib/python2.7/site-packages/autobuilder/__init__.py0
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/AddKernelProps.py60
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/BitbakeSelftest.py32
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py52
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/BuildImages.py195
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/BuildToolchainImages.py53
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckBSPExists.py74
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckForGPLv3.py50
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckForMinnow.py50
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckForWorldLsb.py51
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py119
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutToasterLayers.py71
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CheckYoctoCompat.py56
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py361
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CreateBBLayersConf.py124
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CreateCurrentLink.py50
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CreateGPLTarball.py40
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CreateIntelBSPPackage.py102
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/CreateWicImages.py57
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/DaftFlash.py39
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py44
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/DeleteGoogleVMs.py52
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/DownloadErrorReports.py42
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/GetBitbakeVersion.py51
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/GetDistroVersion.py113
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/GetLayerVersion.py55
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/HelloWorld.py48
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ModBBLayersConf.py40
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/NoOp.py16
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py48
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ProvisionGoogleVMs.py90
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py315
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/PublishDistroData.py57
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/PublishLayerTarballs.py79
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RemoveTmpFiles.py65
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ResolveLayerHead.py73
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunBitbakeSelftest.py28
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunESDKSanityTests.py113
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunOeBuildPerfTest.py78
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py109
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunPreamble.py30
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunSDKSanityTests.py116
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/RunSanityTests.py139
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ScrapeTargets.py67
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/SendErrorReport.py78
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/SendOePerfEmail.py64
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/SendQAEmail.py103
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/SetDest.py107
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/SetupDistroData.py37
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/Sleep.py58
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/TarballOeBuildPerfTest.py33
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/TestFailStep.py30
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ToasterRunTests.py31
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ToasterSetupVenv.py31
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStart.py32
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStop.py33
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/TriggerBuilds.py52
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/UpdateBuildHistory.py49
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/UploadToasterEventlog.py58
-rw-r--r--lib/python2.7/site-packages/autobuilder/buildsteps/__init__.py0
-rw-r--r--lib/python2.7/site-packages/autobuilder/config.py27
-rw-r--r--lib/python2.7/site-packages/autobuilder/lib/ABTools.py79
-rw-r--r--lib/python2.7/site-packages/autobuilder/lib/__init__.py0
-rw-r--r--lib/python2.7/site-packages/autobuilder/lib/buildsteps.py158
-rw-r--r--lib/python2.7/site-packages/autobuilder/lib/daft.py118
-rw-r--r--lib/python2.7/site-packages/autobuilder/lib/wiki.py206
-rw-r--r--lib/python2.7/site-packages/autobuilder/release/download.py38
-rw-r--r--lib/python2.7/site-packages/autobuilder/release/git.py47
-rw-r--r--lib/python2.7/site-packages/autobuilder/release/tabs.py27
-rw-r--r--lib/python2.7/site-packages/autobuilder/release/title.py159
-rw-r--r--lib/python2.7/site-packages/autobuilder/status/__init__.py0
-rw-r--r--lib/python2.7/site-packages/autobuilder/status/wikilog.py459
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO30
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt640
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/requires.txt5
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/scripts/buildbot4
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/top_level.txt1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py48
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.pngbin783 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py1049
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py319
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py302
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py183
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py95
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py277
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py289
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py119
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py204
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py244
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py168
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py305
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py507
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py72
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py192
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py161
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py412
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade684
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py186
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py551
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py59
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py91
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py891
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py50
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py730
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py14
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py79
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py284
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py80
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py202
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py257
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py125
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py206
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py283
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py30
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py139
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py144
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py37
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py36
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py63
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py119
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py36
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py68
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py64
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py52
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py34
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py539
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py288
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py93
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py145
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py151
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py233
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py1216
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py310
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py323
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py779
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py83
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py53
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py213
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py49
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py34
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py120
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py187
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py155
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py492
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py567
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py629
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py253
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py544
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py985
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py136
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py202
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py494
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py474
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py689
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py297
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py112
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py45
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py234
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py184
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py58
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py24
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py453
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py256
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py148
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py666
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py95
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py410
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py94
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py304
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py172
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl42
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py56
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py150
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py110
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py92
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py731
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg126
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py54
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py115
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py79
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py180
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py48
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py359
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py19
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py104
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py479
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py583
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py149
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py68
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py386
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py586
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py699
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py798
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py475
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py382
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py324
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py25
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py118
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py149
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py442
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py39
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py276
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py220
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py188
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py806
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py607
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py332
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py632
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py136
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py744
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py275
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpgbin1822 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css604
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.icobin1150 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt11
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt12
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py341
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py80
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py147
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py87
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py54
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py177
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py118
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py57
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py121
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py203
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py741
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py96
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html11
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html10
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html37
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html238
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html45
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html184
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html50
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html68
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html76
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html19
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html76
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html276
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html37
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html5
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml39
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html16
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html288
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html65
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html30
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html28
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html90
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html36
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html34
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html140
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py84
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py90
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py813
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py1097
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py207
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py46
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py91
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py213
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py174
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py137
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py77
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py304
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py611
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py756
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py270
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py230
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py244
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py302
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py481
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py338
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py1173
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py354
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py434
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py381
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py640
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py102
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py632
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py224
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py408
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py57
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py1224
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py112
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py67
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py86
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py47
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py294
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py24
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py76
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py67
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py107
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py191
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py116
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py48
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py65
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py228
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py282
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py110
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py81
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py283
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py113
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py129
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py85
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py580
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py178
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py99
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py214
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py58
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py238
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py265
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py627
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py237
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py135
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py86
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py1207
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py191
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py106
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py729
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py159
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py430
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py522
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py87
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py176
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py107
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py140
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py81
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py124
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py234
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py120
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py135
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py58
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py185
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py161
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py212
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py182
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py473
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py567
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py98
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py259
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py213
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py823
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py427
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py346
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py1031
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py272
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py53
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py146
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py81
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py233
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py1407
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py51
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py304
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py152
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py82
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py523
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py452
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py153
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py506
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py168
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py208
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py206
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py309
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py173
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py62
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py211
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py727
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py268
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py169
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py214
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py70
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py971
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py119
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py108
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py126
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py33
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py46
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py258
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py100
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py195
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py135
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py67
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py47
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py336
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py816
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py95
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py147
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py43
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py55
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py227
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py98
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py168
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py205
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py90
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py107
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py239
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py617
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py229
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py55
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py372
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py128
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py64
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py56
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py445
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py194
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py836
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py381
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py137
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py482
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py765
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py1457
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py863
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py74
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py106
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py423
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py613
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py1477
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py86
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py267
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py502
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py824
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py323
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py194
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py72
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py69
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py108
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py576
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py88
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py130
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py42
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py22
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py77
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py64
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py62
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py41
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py41
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py54
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py149
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py116
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py80
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py51
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py50
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py24
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py142
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py256
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py204
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py311
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py85
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py232
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py142
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py69
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py60
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py42
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py48
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO16
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt87
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/requires.txt1
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/scripts/buildslave4
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/top_level.txt1
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/VERSION1
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/__init__.py44
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/bot.py547
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/base.py618
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bk.py116
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bzr.py193
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/cvs.py134
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/darcs.py101
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/fs.py244
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/git.py218
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/hg.py285
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/mtn.py202
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/p4.py221
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/registry.py48
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/repo.py225
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/shell.py58
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/svn.py210
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/transfer.py435
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/utils.py100
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/exceptions.py23
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/interfaces.py71
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/__init__.py50
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug4881.py213
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug5079.py49
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/testcase_assert.py48
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/pbutil.py144
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/runprocess.py859
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/base.py34
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/logwatcher.py116
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/runner.py465
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/startup.py134
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/__init__.py61
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/remote.py31
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/runprocess.py183
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/slavebuilder.py38
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/test_extra_coverage.py23
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/runprocess-scripts.py108
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot.py379
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot_BuildSlave.py234
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_base.py127
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bk.py68
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bzr.py77
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_cvs.py63
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_darcs.py137
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_fs.py219
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_git.py701
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_hg.py327
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_mtn.py527
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_p4.py186
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_registry.py36
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_shell.py52
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_svn.py102
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_transfer.py527
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_utils.py133
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_runprocess.py700
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_base.py93
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_runner.py306
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_util.py71
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/command.py140
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/compat.py33
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/misc.py127
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/sourcecommand.py83
-rw-r--r--lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/util.py86
-rw-r--r--lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/PKG-INFO100
-rw-r--r--lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/SOURCES.txt12
-rw-r--r--lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/top_level.txt1
-rwxr-xr-xlib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/decorator.py251
-rw-r--r--lib/python2.7/site-packages/easy-install.pth13
-rwxr-xr-xlib/python2.7/site-packages/easy_install9
-rwxr-xr-xlib/python2.7/site-packages/easy_install-2.79
-rw-r--r--lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/PKG-INFO12
-rw-r--r--lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/SOURCES.txt26
-rw-r--r--lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/top_level.txt1
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/__init__.py9
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/easter.py92
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/parser.py886
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/relativedelta.py432
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py1097
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tz.py951
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tzwin.py180
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/__init__.py87
-rw-r--r--lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/zoneinfo-2010g.tar.gzbin171995 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/PKG-INFO1453
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/SOURCES.txt107
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/requires.txt8
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/top_level.txt1
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/__init__.py86
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/_internal_utils.py42
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/adapters.py503
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/api.py150
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/auth.py288
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cacert.pem5689
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/certs.py25
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/compat.py68
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cookies.py542
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/exceptions.py116
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/hooks.py34
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/models.py922
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/__init__.py36
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/__init__.py32
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5freq.py925
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5prober.py42
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardetect.py80
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardistribution.py231
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetgroupprober.py106
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetprober.py62
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/codingstatemachine.py61
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/compat.py34
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/constants.py39
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/cp949prober.py44
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escprober.py86
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escsm.py242
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/eucjpprober.py90
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrfreq.py596
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrprober.py42
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwfreq.py428
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwprober.py41
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312freq.py472
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312prober.py41
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/hebrewprober.py283
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jisfreq.py569
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jpcntx.py227
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langbulgarianmodel.py229
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langcyrillicmodel.py329
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langgreekmodel.py225
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhebrewmodel.py201
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhungarianmodel.py225
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langthaimodel.py200
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/latin1prober.py139
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcharsetprober.py86
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcsgroupprober.py54
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcssm.py572
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcharsetprober.py120
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcsgroupprober.py69
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sjisprober.py91
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/universaldetector.py170
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/utf8prober.py76
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/__init__.py1
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/codec.py118
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/compat.py12
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/core.py387
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/idnadata.py1584
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/intranges.py46
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/uts46data.py7633
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/__init__.py97
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/_collections.py324
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connection.py369
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connectionpool.py899
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/__init__.py0
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/appengine.py296
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/ntlmpool.py112
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/pyopenssl.py450
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/socks.py188
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/exceptions.py246
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/fields.py178
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/filepost.py94
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/__init__.py5
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/__init__.py0
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/makefile.py53
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ordered_dict.py259
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/six.py868
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py19
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py157
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/poolmanager.py363
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/request.py148
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/response.py618
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/__init__.py52
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/connection.py130
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/request.py118
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/response.py81
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/retry.py389
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/selectors.py524
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py336
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/timeout.py242
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/url.py226
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/wait.py40
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/sessions.py725
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/status_codes.py91
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/structures.py105
-rw-r--r--lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/utils.py827
-rw-r--r--lib/python2.7/site-packages/setuptools-0.6c11-py2.7.eggbin332005 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/setuptools.pth1
-rw-r--r--lib/python2.7/site-packages/site.py82
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/PKG-INFO54
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/SOURCES.txt112
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/entry_points.txt5
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/requires.txt7
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/top_level.txt1
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/__init__.py11
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/__init__.py28
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/ansisql.py292
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/constraint.py199
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/__init__.py10
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/firebird.py93
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/mysql.py65
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/oracle.py108
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/postgres.py42
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/sqlite.py153
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/visitor.py78
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/schema.py655
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/exceptions.py87
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/__init__.py15
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/__init__.py0
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_changeset.py910
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_constraint.py298
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/__init__.py18
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/base.py32
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/database.py204
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/models.py14
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/pathed.py77
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/shell.py34
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/warnings.py90
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/__init__.py0
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/test_docs.py18
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/__init__.py0
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_api.py126
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_cfgparse.py27
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_database.py11
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_genmodel.py209
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_keyedinstance.py45
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_pathed.py51
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_repository.py218
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_runchangeset.py52
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schema.py203
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schemadiff.py209
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_script.py268
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_shell.py556
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_template.py70
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_util.py129
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_version.py166
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/__init__.py5
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/api.py384
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/cfgparse.py27
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/config.py14
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/genmodel.py285
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/migrate_repository.py100
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/pathed.py75
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/repository.py242
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schema.py220
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schemadiff.py292
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/__init__.py6
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/base.py57
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/py.py160
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/sql.py49
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/shell.py214
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/template.py93
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/__init__.py0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/default.py_tmpl12
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/pylons.py_tmpl30
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/__init__.py0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/README4
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/__init__.py0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/migrate.cfg25
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/versions/__init__.py0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/README4
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/__init__.py0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/migrate.cfg25
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/versions/__init__.py0
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/__init__.py0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/default.py_tmpl13
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/pylons.py_tmpl13
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/default.py_tmpl0
-rw-r--r--lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/pylons.py_tmpl0
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/__init__.py179
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/importpath.py16
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/keyedinstance.py36
-rwxr-xr-xlib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/version.py238
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO275
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt65
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt1
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/namespace_packages.txt1
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt1
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe1
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt4
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt1
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/__init__.py7
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.ru.txt803
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt829
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/__init__.py79
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_flatten.py35
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.c1682
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.py7
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py692
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.ru.txt540
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.txt543
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/advice.py201
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/__init__.py2
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/idatetime.py575
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/interfaces.py102
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/mapping.py125
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/sequence.py160
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/__init__.py2
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/basemapping.py107
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_idatetime.py47
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_import_interfaces.py29
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/declarations.py1395
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/document.py105
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/exceptions.py67
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.ru.txt156
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.txt152
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/index.txt29
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interface.py833
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interfaces.py746
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/ro.py69
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/__init__.py13
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/dummy.py22
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/foodforthought.txt61
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/ifoo.py26
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m1.py21
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m2.py15
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/odd.py129
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_adapter.py412
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_advice.py185
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_declarations.py428
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_document.py69
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_element.py41
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_interface.py473
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_odd_declarations.py216
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_sorting.py55
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_verify.py200
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/unitfixtures.py140
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.py115
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.txt127
-rw-r--r--yocto-autobuilder-setup200
-rwxr-xr-xyocto-controller/Makefile28
-rw-r--r--yocto-controller/buildbot.tac.example32
-rw-r--r--yocto-controller/buildbot.tac.standard32
-rw-r--r--yocto-controller/controller.cfg.example150
-rw-r--r--yocto-controller/public_html/bg_gradient.jpgbin1822 -> 0 bytes
-rw-r--r--yocto-controller/public_html/default.css546
-rw-r--r--yocto-controller/public_html/favicon.icobin1150 -> 0 bytes
-rw-r--r--yocto-controller/public_html/robots.txt10
-rw-r--r--yocto-controller/templates/README.txt12
-rw-r--r--yocto-controller/yoctoABConfig.py20
-rwxr-xr-xyocto-start-autobuilder99
-rwxr-xr-xyocto-stop-autobuilder94
-rw-r--r--yocto-worker/Makefile28
-rw-r--r--yocto-worker/buildbot.tac.example49
2149 files changed, 7 insertions, 591090 deletions
diff --git a/COPYING b/COPYING
deleted file mode 100644
index 3912109b..00000000
--- a/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/COPYING.buildbot b/COPYING.buildbot
deleted file mode 100644
index 197851cf..00000000
--- a/COPYING.buildbot
+++ /dev/null
@@ -1,282 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
-GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-
diff --git a/COPYING.decorator b/COPYING.decorator
deleted file mode 100644
index 25fcce9e..00000000
--- a/COPYING.decorator
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright 2007-2011 Michele Simionato
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
diff --git a/COPYING.htpasswd b/COPYING.htpasswd
deleted file mode 100644
index 51b6572f..00000000
--- a/COPYING.htpasswd
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (C) 2003-2015 Edgewall Software
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/COPYING.jinja2 b/COPYING.jinja2
deleted file mode 100644
index 31bf900e..00000000
--- a/COPYING.jinja2
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
- * The names of the contributors may not be used to endorse or
- promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/COPYING.setuptools b/COPYING.setuptools
deleted file mode 100644
index e4662ddc..00000000
--- a/COPYING.setuptools
+++ /dev/null
@@ -1,22 +0,0 @@
-ZPL 2.1
-Zope Public License (ZPL) Version 2.1
-
-A copyright notice accompanies this license document that identifies the copyright holders.
-
-This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF).
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the following disclaimer.
-Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution.
-Names of the copyright holders must not be used to endorse or promote products derived from this software without prior written permission from the copyright holders.
-The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of the copyright holders. Use of them is covered by separate agreement
-with the copyright holders.
-If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
-Disclaimer
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS`` AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOS
-E ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE G
-OODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISI
-NG IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff --git a/COPYING.sqlalchemy b/COPYING.sqlalchemy
deleted file mode 100644
index fb950dc6..00000000
--- a/COPYING.sqlalchemy
+++ /dev/null
@@ -1,17 +0,0 @@
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/COPYING.tempita b/COPYING.tempita
deleted file mode 100644
index 162a553e..00000000
--- a/COPYING.tempita
+++ /dev/null
@@ -1,7 +0,0 @@
-Copyright (c) 2008 Ian Bicking and Contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/COPYING.twisted b/COPYING.twisted
deleted file mode 100644
index fb950dc6..00000000
--- a/COPYING.twisted
+++ /dev/null
@@ -1,17 +0,0 @@
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/README b/README
index bba3f762..43345a95 100644
--- a/README
+++ b/README
@@ -1,111 +1,12 @@
-Setting up a Yocto Autobuilder Build Cluster
-============================================
+This is the repository for the Yocto Autobuilder with buildbot 'eight'. This is deprecated
+and no longer supported.
-Most autobuilder setups are individual to the circumstances of the
-user. This document outlines some of the configuration options/files,
-autobuilder setup gotchas and general autobuilder best practices.
+Please use:
-Setup to run headless sanity tests
-===================================
+http://git.yoctoproject.org/cgit/cgit.cgi/yocto-autobuilder2/
-If you plan on using the yocto autobuilder to run sanity testing,
-you will need to:
+in conjunction with:
-1. Install tight-vnc client and server.
+http://git.yoctoproject.org/cgit/cgit.cgi/yocto-autobuilder-helper/
-2. Set up tap devs by running poky/scripts/runqemu-gen-tapdevs.
- You MUST disable interface control on these new tap interfaces;
- some services include NetworkManager, connman, or wicd.
-
-3. Add "xterm*vt100*geometry: 80x50+10+10" to .Xdefaults
-
-4. Setup and start vnc session as the autobuilder user.
-
-5. You MUST manually connect to the vnc session at least once prior to
- running a qemu sanity test (Something is getting set during the initial
- connection that I haven't figured out yet. Manually connecting seems to
- set up the session correctly.)
-
-Adding additional build workers
-===============================
-
-The production yocto autobuilder uses a cluster of build workers, all
-sharing the same SSTATE_DIR and DL_DIR via an NFS4 mounted NAS. The main
-nightly trigger prepopulates the DL_DIR, allowing the workers to not have
-to deal with a lot of downloading. In theory you could also run your build
-workers with NO_NETWORK to enforce a single point of populating DL_DIR.
-
-Running multiple build workers is fairly simple, but does require some setup:
-
-a. Ensure the settings in autobuilder.conf are valid for each buildworker,
- As certain variables are set within this file that are work with the
- local configuruation on each builder.
-
-b. Within yocto-controller/controller.cfg add your worker to the
- c['workers'] list inside of the BUILDWORKERS section
-
-c. For each build worker change the WORKER SETTINGS section of
- yocto-worker/buildbot.tac to match the settings in controller.cfg.
-
-d. Workers must reside in the same path as the controller, even if they are
- on completely different machines.
-
-Triggered Builds
-================
-
-There is a limitation to using the TriggerBuilds build step. The builder using
-it needs to know several properties of the builds to be triggered. To get these
-properties, repos information of the builds to be triggered must be added to the
-builder, and a CheckOutLayers build step must be called some time before the
-TriggerBuilds call.
-
-Setting up build history
-========================
-
-Build History is used to track changes to packages and images. By default
-the autobuilder does not collect build history. The production autobuilder
-does have this functionality enabled.
-
-Setting up build history requires the following steps:
-
-1. Create an empty git repo. Make a single commit to it and the create and
- push branches for each of the nightly core architectures (ie. mips, ppc,
- x86...)
-
-2. Find a central location to create a clone for this. This works best if
- you have a set up similar to the production autobuilder (NAS with many
- builders)
-
-3. Run the following:
-
- # This is an example of how to set up a local build history checkout. Paths
- # obviously are situation dependant.
- mkdir /nas/buildhistory
- cd /nas/buildhistory
- git clone ssh://git@git.myproject.org/buildhistory
- git clone ssh://git@git.myproject.org/buildhistory nightly-arm
- git clone ssh://git@git.myproject.org/buildhistory nightly-x86
- git clone ssh://git@git.myproject.org/buildhistory nightly-x86-64
- git clone ssh://git@git.myproject.org/buildhistory nightly-ppc
- git clone ssh://git@git.myproject.org/buildhistory nightly-mips
- for x in `ls|grep nightly` do cd $x; git checkout $x; cd /nas/buildhistory; done
-
-4. Within the autobuilder.conf of EACH slave change the following:
-
- BUILD_HISTORY_COLLECT = True
- BUILD_HISTORY_DIR = "/nas/buildhistory"
- BUILD_HISTORY_REPO = "ssh://git@git.myproject.org/buildhistory"
-
-Files used for Yocto-Autobuilder Configuration
-==============================================
-
-Name: config/autobuilder.conf
-Purpose:
-This file is used to set autobuilder wide parameters, like where various build
-artifacts are published to, DL_DIR, SSTATE_DIR or if build artifacts should be
-published (needed for production autobuilders, not needed for desktop builders)
-
-Name: buildset-config/yoctoAB.conf
-Purpose:
-This is the main yocto autobuilder config. Documentation for this and associated
-format is in README-NEW-AUTOBUILDER
+which is for buildbot 'nine' and is actively developed/maintained.
diff --git a/README-GOOGLE-CLOUD b/README-GOOGLE-CLOUD
deleted file mode 100644
index 34c80a99..00000000
--- a/README-GOOGLE-CLOUD
+++ /dev/null
@@ -1,68 +0,0 @@
-Limitations
-------------
-The current implementation of the Google Cloud building has a couple of
-limitations.
-
-First of all, Google's gcloud command line tool is required for
-all functions (see https://developers.google.com/cloud/sdk/gcloud/).
-
-Next, the controller machine is required to be authenticated with Google's cloud
-system (see https://developers.google.com/cloud/sdk/gcloud/reference/auth/).
-
-Third, the workers must be on a network which has the worker port
-(port 9989 by default) open. This can be done by setting up a network and
-using that network in the ProvisionGoogleVM builstep. Example commands to
-set up a network:
-
-gcloud compute networks create autobuilder-network
-gcloud compute firewall-rules autobuilder-allow --network autobuilder-network \
- --allow tcp:8010 tcp:9989 tcp:80 tcp:22
-
-This sets up a network that is suitable for both controllers and workers, as
-it allows all default autobuilder connections, as well as ssh and http. The
-key:value pair 'network':'autobuilder-network' can then be added to your
-ProvisionGoogleVMs buildstep, allowing provisioned machines to connect to
-controllers.
-
-Fourth, additional workers must be added to yocto-controller/controller.cfg
-with the format:
- BuildWorker("worker<N>", "<WORKER-PASSWORD>", max_builds=3)
-where N is 0...however many workers you want and WORKER-PASSWORD is the default
-password. For example, if I wanted to add three workers for the cloud builder:
-
- c['workers'] = [BuildWorker("example-worker", "eeieHim8V", max_builds=3),]
-
-would be changed to this:
-
- c['workers'] = [BuildWorker("example-worker", "eeieHim8V", max_builds=3),
- BuildWorker("worker0", "eeieHim8V", max_builds=3),
- BuildWorker("worker1", "eeieHim8V", max_builds=3),
- BuildWorker("worker2", "eeieHim8V", max_builds=3),]
-
-Finally, the worker-init script is only an example and has a couple
-limitations itself. It has only been tested for debian VMs and will likely not
-work on others. Also, the <HOST_ADDR> and <PASS> fields will need to be
-manually edited in it if your autobuilder was created before the addition of
-the GoogleVM buildsteps or if the controller machine is behind a firewall.
-
-HowTo
-----------
-
-Assuming that the limitations above have been dealt with, this will provision
-one new VM and completely set it up, including connections
-
- {'ProvisionGoogleVMs':{
- 'vmname':'autobuilder-worker-startup-test',
- 'vmcount':1,
- 'zone':'us-central1-a',
- 'machine':'n1-standard-4',
- 'disksize':'230GB',
- 'startupscript':'/path/to/yocto-autobuilder/bin/worker-init',
- 'network':'autobuilder-network'}}
-
-And this will delete the entire VM when you are finished with it:
-
- {'DeleteGoogleVMs': {}}
-
-Note that the current implementation of DeleteGoogleVM requires that its in the
-same buildset as CreateGoogleVM.
diff --git a/README-NEW-AUTOBUILDER b/README-NEW-AUTOBUILDER
deleted file mode 100644
index c37c8c41..00000000
--- a/README-NEW-AUTOBUILDER
+++ /dev/null
@@ -1,362 +0,0 @@
-Introduction
-------------
-
-Prior versions of the yocto-autobuilder required an extensive knowledge of
-buildbot as well as basic python. Over the years, as more targets were added
-the main configuation file had become hard to maintain, harder to read and,
-frankly, was not utilizing the power of buildbot. This document will explain
-some of the rational behind the refactor, introduce end users to the new
-configuration language, introduce the concept of customized buildsteps and
-give some basic instruction on how to modify an autobuilder setup.
-
-TODO
-------------
-- buildhistory is not functional
-- still missing some needed build targets
- - oe-core
- - fsl
- - p1022ds
- - bunch of meta-intel
- -
-- minor UI cleanup for toggling of triggered layers
-- bbpriority needs to work
-- verify buildappsrcrev
-- deploy stuff
-- killing triggers. this has been a long standing issue. look into
-
-What is it
-------------
-
-Yocto Autobuilder is essentially some extension to the vanilla build bot.
-This extension mainly addresses configuration file handling and Yocto specific
-build steps.
-For better maintainability, the Autobuilder (see Autobuilder.py located at
-lib/python2.7/site-packages/autobuilder/), handles configuration from multiple
-files.
-Additional build steps such as CheckOutLayers.py or CreateBBLayersConf are
-Yocto specific and simplify the bulders configuration.
-
-Setup
-------------
-
-Nothing here has changed much.
-
-git clone git://git.yoctoproject.org/yocto-autobuilder
-cd yocto-autobuilder
-. ./yocto-autobuilder-setup
-yocto-start-autobuilder both
-
-Configuration
--------------
-
-In the bad old days, the yocto-autobuilder configuration was stored in a single
-file. This file contained both build target definitions as well as helper code/
-custom buildsteps. This was obviously a "bad thing". We've now removed all
-build target configuration out into the config/* directory
-
-Files
------
-
-There are two needed files in this directory. One file, autobuilder.conf, is a
-global definition file which sets various globals that controllers and workers need
-to know about. This hasn't really changed from prior versions.
-
-One new file is yoctoAB.conf. This is the only required file needed for build
-target definitions. However, as it would be a bad practice to have all build
-targets within a single file, you may define build targets in other *.conf files.
-As long as those conf files live within the config directory, the
-yocto-autobuilder will automatically load them. This allows us to keep things
-nice and neat.
-
-yoctoAB.conf:
--------------
-
-The main BuildSets section required for the configuration contains a single
-property:
-
-[BuildSets]
-order: ['nightly', 'nightly-x86']
-
-The order property tells buildbot what order you wish to display build targets
-in on the waterfall page. This can not be used with vanilla buildbot as there is
-a small patch required to utilize this functionality.
-
-buildset configuration
--------------
-
-Each buildset must start with a section name followed by at three to four
-properties:
-
-builders: A string or list of builders used to build the buildset
-
-repos: A list of dicts. Each item will contain a dict entry:
-
- 'name_of_repo':
- {'repourl':'git://path.to/git_repo',
- 'bbpriority':'1',
- 'branch':'master'}}
-
- Either poky or openembedded must be the first repo listed, as that is
- the base directory for building, and anything listed before it will be
- deleted when the base directory is checked out.
-
-NOTE: bbpriority is currently not used
-
-props: A list of dicts. This is used when you need to add properties to a
- builder. An example of this would be build-appliance which needs to have
- a buildappsrcrev property passed so it knows which version from the poky
- repo to pull. prop_type is basically buildbot scheduler properties with
- the args sent as dict pairs. See:
- http://buildbot.net/buildbot/docs/0.8.6/manual/cfg-schedulers.html#forcesched-parameters
-
-steps: A list of dicts. These steps can be either custom buildsteps or basic
- buildbot buildsteps with args passed as dict pairs. Custom buildsteps
- that we utilize are in lib/python2.7/site-packages/autobuilder/buildsteps.
-
- CreateBBLayersConf: This build step creates the bblayers.conf used by the
- build system to determine which layers to use and where to find them.
-
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer':'True',
- 'bspprovider':'intel',
- 'bbtextprepend':'text_to_prepend',
- 'bbtextappend':'text_to_append',
- 'layerdirs': ['layerdir1', 'layerdir2', ...]}}
-
- buildprovider: Optional and defaults to 'yocto'. If this is set to
- 'yocto', then it adds the layers' 'meta', 'meta-yocto' and
- 'meta-yocto-bsp' to BBLAYERS. If set to 'oe', then only 'meta' is
- added to BBLAYERS.
-
- bsplayer: Optional and defaults to False. Set this to 'True' if you
- want to use an established BSP layer and include its default layers.
-
- bspprovider: Required if bsplayer is set to True. Defines the BSP
- provider so the default layers can be included. At this time only
- 'intel', 'fsl-ppc' and 'fsl-arm' are recognized.
-
- bbtextprepend: Prepends the given text to bblayers.conf. Use \n in
- the text to start a new line and always end the text with a \n. For
- example:
- 'bbtextprepend': '#Adding one comment line\n#Adding a second comment line\n'
-
- bbtextappend: Appends the given text to bblayers.conf. Same format
- as bbtextprepend.
-
- layerdirs: Used to add layers to BBLAYERS. Layers are added in the
- order specified and are added after the layers created by the
- buildprovider. For example:
- 'layerdirs': ['meta-openembedded/meta-oe',
- 'meta-openembedded/meta-networking',
- 'meta-openembedded/meta-gnome']
- will append the layers meta-openembedded/meta-oe,
- meta-openembedded/meta-networking, and meta-openembedded/meta-gnome
- to BBLAYERS. Note that this will override any default layers from a
- bspprovider.
-
-scheduler: A list of dicts. Each item defines a scheduler associated with this
- buildset:
-
- 'name_of_scheduler':
- {'type': 'Nightly'}
-
- The scheduler type is specified by the 'type' property, where supported
- values are 'Nightly' or 'SingleBranchScheduler', with 'Nightly' as the
- default. Additional properties are used to configure the scheduler and
- are type-specific:
-
- Nightly scheduler properties:
- month: The month in which to start the build, with January = 1.
- This defaults to '*', meaning every month.
- dayOfWeek: The day of the week in which to start the build, with
- Monday = 1. This defaults to '*', meaning every day.
- hour: The hour of the day in which to start the build, with
- 12:00 AM = 0. This must be set by the user.
- minute: The minute of the hour in which to start the build, with
- 0 to 59 as valid values. This must be set by the user.
-
- SingleBranchScheduler properties:
- repository: the repository to attach the scheduler to; this
- is the repo name from the 'repos' section; the branch which
- the scheduler is attached to matches that in the repo
- definition.
-
- stable-timer: how long (in seconds) to wait after change before
- triggering build to allow for changes to settle. Defaults
- to 60 seconds.
-
- change-user: the user name which the remote hook will use; the
- default value is the repository name as per the 'repository'
- property.
-
- change-password: password which the remote hook will use; the
- default is the buildbot default 'changepw' -- if your
- autobuilder is publically accessible, you want to keep this
- secret to avoid injection of arbitrary changes into your
- autobuilder.
-
- changesource: the type of changesource to use for the scheduler;
- the default setting is a PBChangeSource. Only other valid
- option is 'GitPoller' for a GitPoller changesource. See the
- official Buildbot documentation at
- http://docs.buildbot.net/latest/manual/cfg-changesources.html
- for more information on changesources.
-
- interval: The interval between polling for changes. Only valid
- for GitPoller changesources. Defaults to 300 seconds (five
- minutes).
-
- Extra Notes on SingleBranchScheduler setup
- ------------------------------------------
-
- There is one SBS scheduler for each repository in the buildset, i.e.,
- if your buildset contains more repositories, and you want build
- triggered by changes to any of them, you need to define a scheduler
- for each. This also means that you can mix and match, e.g., only
- do nightly rebuilds for some repos and immediate for others.
-
- The scheduler change filter is set up to watch changes only in the
- single repository specified. If you are using a PBChangeSource, you
- have to set up your repository hook to send the repository url in the
- change set with the --repository argument to git_buildbot.py, e.g.,
- your git post-receive hook could look something like:
-
- #!/bin/sh
- echo "$1 $2 $3" | \
- git_buildbot.py --repository="git://some_repo..."
-
- For local testing, you can use a post-merge hook instead, along
- these lines:
-
- #!/bin/sh
- PRE=$(git rev-parse 'HEAD@{1}')
- POST=$(git rev-parse HEAD)
- SYMNAME=$(git rev-parse --symbolic-full-name HEAD)
- echo "$PRE $POST $SYMNAME" | \
- git_buildbot.py --repository="file:///where_your_repo_is"
-
- Because of the way builbot change sources work, your change user
- names must not collide with the user names used by your workers.
-
- If you are using a GitPoller changesource and you specify a valid
- repository but an non-existent branch, Buildbot will silently ignore
- your scheduler. If a repository has changed recently but your build
- has not triggered, validate that your repository and branch settings
- are valid.
-
- For either a PBChangeSource or a GitPoller changesource, the
- scheduler will not see the initial repository discovery as a change.
- If you are using a SingleBranchScheduler schedule, it is good
- practice to force a build to verify the buildset works correctly.
-
-Example of PBChangeSource:
-
-[nightly-x86]
-builders: 'builder1'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'bbpriority':'1',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'bbpriority':'2',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato'}},
- {'PublishArtifacts': {'artifacts': ['qemux86', 'atom-pc']}}]
-scheduler: [{'dev-branch-scheduler' :
- {'type':'SingleBranchScheduler',
- 'repository':'poky',
- 'stable-timer':30,
- 'change-password':'secret_change_password'}}]
-
-
-Example of MultiBranch GitPoller:
-
-[git-poller]
-builders: 'example-worker'
-repos: [{'poky-contrib':
- {'repourl':'git://git.yoctoproject.org/poky-contrib',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp'},
- 'branch':'tgraydon/poky'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/poky-contrib',
- 'branch':'tgraydon/meta-qt3'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['qemux86', 'atom-pc']}}]
-scheduler: [{'git-poller-scheduler':
- {'type':'SingleBranchScheduler',
- 'changesource':'GitPoller',
- 'repository':'poky-contrib',
- 'branch':'tgraydon/poky',
- 'interval':3600},
- 'stable-timer':300}}]
-scheduler: [{'git-poller-scheduler':
- {'type':'SingleBranchScheduler',
- 'changesource':'GitPoller',
- 'repository':'poky-contrib',
- 'branch':'tgraydon/meta-qt3',
- 'interval':3600},
- 'stable-timer':300}}]
-
-Note that the 'change-password' property is not used for GitPoller. This
-buildset config may also be found in the build-config.examples directory.
-
-
-Adding Buildsteps
--------------
-I've included the basic buildsteps required to do general building as well as an
-example buildstep called HelloWorld.py.
-
-from buildbot.steps.shell import ShellCommand
-
-class HelloWorld(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Hello World"
- def __init__(self, factory, argdict=None, **kwargs):
- self.firstname=""
- self.lastname=""
- self.factory = factory
- for k, v in argdict.iteritems():
- if k=="name":
- self.firstname=v
- elif k=="lastname":
- self.lastname=v
- else:
- setattr(self, k, v)
- self.description = "Hello World"
- self.command = "echo 'Hello World " + self.firstname + " " + self.lastname + "'"
- ShellCommand.__init__(self, **kwargs)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
-
-We see that this is an inherited class (from ShellCommand) that overrides the
-__init__ and describe methods of ShellCommand. All custom buildsteps MUST override
-__init__ of the inherited class, adding the argdict and kwargs properties to the
-class. This allows us to pass arguments specific to the custom buildstep in via
-an argument dictionary while allowing us to pass arguments in that will get passed
-up to the inherited class as a keyworded, variable length argument list.
-
-We do this so that adding buildsteps is essentially drag and drop. By adding a
-custom buildstep to lib/python2.7/site-packages/autobuilder/buildsteps you can
-just reference it within your config file without making any changes to the core
-Autobuilder codebase.
-
-
diff --git a/README-QUICKSTART b/README-QUICKSTART
deleted file mode 100644
index 809722f7..00000000
--- a/README-QUICKSTART
+++ /dev/null
@@ -1,6 +0,0 @@
-Setting up yocto-autobuilder in four easy steps:
-------------------------------------------------
-git clone git://git.yoctoproject.org/yocto-autobuilder
-cd yocto-autobuilder
-. ./yocto-autobuilder-setup
-yocto-start-autobuilder both
diff --git a/ab-prserv b/ab-prserv
deleted file mode 100755
index c1aa3615..00000000
--- a/ab-prserv
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-#
-# Autobuilder PR Service Startup Script
-# Elizabeth Flanagan <elizabeth.flanagan@intel.com>
-#
-##
-# Copyright (C) 2011-2016 Intel Corp.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import os, sys, optparse, subprocess, datetime
-from socket import gethostname
-from ConfigParser import SafeConfigParser
-
-usage = """%prog [options] start|stop
-
-Start/stop the autobuilder PR server instance.
-"""
-prserv_file = "prserv_export"
-parser = optparse.OptionParser(usage=usage)
-options, args = parser.parse_args( sys.argv )
-
-if len(args) != 2 or (sys.argv[1] != "start" and sys.argv[1] != "stop") :
- parser.error("""
- You must specify if you wish to stop or start.
-
- """ + usage )
-AB_BASE=os.path.dirname(os.path.abspath(sys.argv[0]))
-
-parser = SafeConfigParser()
-parser.read('config/autobuilder.conf')
-print
-print "Reading " + os.path.join(AB_BASE, "config/autobuilder.conf")
-print
-os.environ["WORKERBASEDIR"] = AB_BASE.strip('"') + "/yocto-worker"
-print ' Setting %s to %s' % ("WORKERBASEDIR", AB_BASE + "/yocto-worker")
-
-for section_name in parser.sections():
- for name, value in parser.items(section_name):
- if "PRSERV" in name.upper():
- locals()[name.upper()]=value
- print " Setting %s to %s" % (name.upper(), value)
-
-if PRSERV_HOST and PRSERV_PORT:
- if os.path.isdir(os.path.join(AB_BASE, "bitbake/.git")):
- print " Updating PRSERV "
- os.chdir(os.path.join(AB_BASE, "bitbake"))
- subprocess.call(["git", "pull"])
- os.chdir(AB_BASE)
- else:
- print " Cloning PRSERV "
- os.chdir(AB_BASE)
- subprocess.call(["git", "clone", "git://git.openembedded.org/bitbake"])
-
- sys.path.insert(0, os.path.join(AB_BASE, "bitbake/lib"))
-
- if sys.argv[1] == "start":
- if PRSERV_PORT == "0":
- subprocess.call(["./bitbake/bin/bitbake-prserv", "--start", "--host", PRSERV_HOST, "--port", PRSERV_PORT])
- else:
- subprocess.call(["./bitbake/bin/bitbake-prserv", "--start"])
-
- if sys.argv[1] == "stop":
- subprocess.call(["./bitbake/bin/bitbake-prserv", "--stop"])
-else:
- print "PRSERV_HOST and PRSERV_PORT must exist in config/autobuilder.conf"
- sys.exit(1)
diff --git a/autobuilder.pth.in b/autobuilder.pth.in
deleted file mode 100644
index 987126b0..00000000
--- a/autobuilder.pth.in
+++ /dev/null
@@ -1,15 +0,0 @@
-<YPABDIR>/lib/python2.7/site-packages/
-<YPABDIR>/lib/python2.7/site-packages/autobuilder
-<YPABDIR>/lib/python2.7/site-packages/autobuilder/buildsteps
-<YPABDIR>/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg
-<YPABDIR>/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg
-<YPABDIR>/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg
-<YPABDIR>/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg
diff --git a/bin/buildbot b/bin/buildbot
deleted file mode 100755
index 124cab9e..00000000
--- a/bin/buildbot
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'buildbot==0.8.8','buildbot'
-__requires__ = 'buildbot==0.8.8'
-import pkg_resources
-pkg_resources.run_script('buildbot==0.8.8', 'buildbot')
diff --git a/bin/buildworker b/bin/buildworker
deleted file mode 100755
index 643c38fe..00000000
--- a/bin/buildworker
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'buildbot-slave==0.8.8','buildslave'
-__requires__ = 'buildbot-slave==0.8.8'
-import pkg_resources
-pkg_resources.run_script('buildbot-slave==0.8.8', 'buildslave')
diff --git a/bin/buildworker-janitor b/bin/buildworker-janitor
deleted file mode 100755
index 3d0bb68e..00000000
--- a/bin/buildworker-janitor
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/python
-'''
-Created on Feb 19, 2014
-
-__author__ = "Richard Purdie"
-__copyright__ = "Copyright 2014, Linux Foundation"
-__credits__ = ["Richard Purdie"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Richard Purdie"
-__email__ = "richard.purdie@linuxfoundation.org"
-'''
-
-from __future__ import print_function
-import signal
-import os
-import sys
-import ConfigParser
-import threading
-import time
-
-tmpfile = '/tmp/.buildworker-janitor'+os.getcwd().replace('/', '-')
-
-if len(sys.argv) < 2:
- print("Please specify the path to the config file on the commandline as the first argument")
- sys.exit(1)
-
-config = ConfigParser.ConfigParser()
-config.read(sys.argv[1])
-
-sections = {}
-for section in config.sections():
- sections[section] = dict(config.items(section))
-
-if "GitSettings" not in sections:
- print("There is no GitSettings section in the configuration file?")
- sys.exit(1)
-
-gitsettings = sections["GitSettings"]
-
-if "ogit_trash_dir" not in gitsettings:
- print("Please set OGIT_TRASH_DIR in the configuration file")
- sys.exit(1)
-
-if "ogit_mirror_dir" not in gitsettings:
- print("Please set OGIT_MIRROR_DIR in the configuration file")
- sys.exit(1)
-
-trashdir = gitsettings["ogit_trash_dir"].replace('"','').replace("'",'')
-mirrordir = gitsettings["ogit_mirror_dir"].replace('"','').replace("'",'')
-
-mirrorlist = [
- "git://git.yoctoproject.org/meta-fsl-arm",
- "git://git.yoctoproject.org/meta-fsl-ppc",
- "git://git.yoctoproject.org/meta-intel",
- "git://git.yoctoproject.org/meta-minnow",
- "git://git.yoctoproject.org/meta-qt3",
- "git://git.yoctoproject.org/meta-qt4",
- "git://git.yoctoproject.org/poky",
- "git://git.yoctoproject.org/eclipse-poky-kepler",
- "git://git.yoctoproject.org/eclipse-poky-juno"
-]
-
-def trash_processor(trashdir):
- print("Monitoring trashdir %s" % trashdir)
- if not os.path.exists(trashdir):
- os.makedirs(trashdir)
- if trashdir == "/":
- print("Not prepared to use a trashdir of /")
- return
- while True:
- try:
- files = os.listdir(trashdir)
- if files:
- os.system("ionice -c 3 rm %s/* -rf" % trashdir)
- else:
- time.sleep(120*60) # 30 minutes
- except Exception as e:
- print("Exception %s in trash cleaner" % str(e))
- time.sleep(60) # 1 minute timeout to prevent crazy looping
- pass
- return
-
-def mirror_processor(mirrordir):
- print("Updating mirrors in %s" % mirrordir)
- mirrorpaths = []
- for mirror in mirrorlist:
- mirrorpaths.append(os.path.join(mirrordir, mirror.split("/")[2], mirror.split("/", 3)[3]))
- if not os.path.exists(mirrorpaths[-1] + "/.git/"):
- os.system("git clone %s %s" % (mirror, mirrorpaths[-1]))
- while True:
- for path in mirrorpaths:
- os.chdir(path)
- os.system("git fetch --prune --all")
- time.sleep(30*60) # 30 minutes
- return
-
-#Check to see if this is running already. If so, kill it and rerun
-if os.path.exists(tmpfile) and os.path.isfile(tmpfile):
- print("A prior PID file exists. Attempting to kill.")
- with open(tmpfile, 'r') as f:
- pid=f.readline()
- try:
- os.kill(int(pid), signal.SIGKILL)
- # We need to sleep for a second or two just to give the SIGKILL time
- time.sleep(2)
- except OSError as ex:
- print("""We weren't able to kill the prior buildworker-janitor. Trying again.""")
- pass
- # Check if the process that we killed is alive.
- try:
- os.kill(int(pid), 0)
- except OSError as ex:
- pass
-elif os.path.exists(tmpfile) and not os.path.isfile(tmpfile):
- raise Exception("""/tmp/.buildworker-janitor is a director. remove it to continue.""")
-try:
- os.unlink(tmpfile)
-except:
- pass
-with open(tmpfile, 'w') as f:
- print(os.getpid(), file=f)
-
-threads = []
-threads.append(threading.Thread(target=trash_processor, args=(trashdir,)))
-threads[-1].start()
-threads.append(threading.Thread(target=mirror_processor, args=(mirrordir,)))
-threads[-1].start()
-
-# wait for all threads to finish
-for t in threads:
- t.join()
-sys.exit(0)
diff --git a/bin/cftp b/bin/cftp
deleted file mode 100755
index 7936fcdf..00000000
--- a/bin/cftp
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','cftp'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'cftp')
diff --git a/bin/checkvnc b/bin/checkvnc
deleted file mode 100755
index 11e03bb3..00000000
--- a/bin/checkvnc
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-#
-# check if vnc server is running, and if not, cleanup and restart
-#
-grep ':170D' /proc/net/tcp > /dev/null
-if [ $? != 0 ]; then
- echo "Xvnc not running, attempting restart"
- vncserver -kill :1
- vncserver
-fi
diff --git a/bin/ckeygen b/bin/ckeygen
deleted file mode 100755
index b7fd5e7b..00000000
--- a/bin/ckeygen
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','ckeygen'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'ckeygen')
diff --git a/bin/conch b/bin/conch
deleted file mode 100755
index 3a6e7189..00000000
--- a/bin/conch
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','conch'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'conch')
diff --git a/bin/forcebuild.py b/bin/forcebuild.py
deleted file mode 100755
index e6770a4f..00000000
--- a/bin/forcebuild.py
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env python
-
-# YoctoAutobuilder force build script
-#
-# Copyright (C) 2017 Intel Corporation
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import urllib2
-import urllib
-import cookielib
-import uuid
-import sys
-import argparse
-import json
-from bs4 import BeautifulSoup
-
-class YoctoAutobuilderAPI(object):
- def __init__(self, server):
- self.server = server
- self.opener = urllib2.build_opener(
- urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
-
- def login(self, user, passwd):
- data = urllib.urlencode(dict(username=user,
- passwd=passwd))
- url = self.server + "/login"
- request = urllib2.Request(url, data)
- result = self.opener.open(request).read()
- if result.find("The username or password you entered were not correct") > 0:
- print("Invalid username or password")
- return 1
- return 0
-
- def _get_builders(self):
- url = "%s/json/builders/?as_text=1" % (self.server)
- request = urllib2.Request(url)
- json_raw_data = self.opener.open(request)
-
- return json.load(json_raw_data)
-
- def list_builders(self):
- builders = self._get_builders()
-
- if builders:
- print('Available builders:\n')
- for builder in builders:
- print(builder)
- return 0
- else:
- print('No available builders in this server.')
- return 1
-
- def _get_options_by_builder(self, builder):
- options = {}
-
- url = "%s/builders/%s" % (self.server, builder)
- request = urllib2.Request(url)
- html = self.opener.open(request).read()
-
- inputs = BeautifulSoup(html, 'lxml').find_all('input')
- for input in inputs:
- type = input.attrs['type']
- if type == 'submit':
- continue
-
- options[input.attrs['name']] = input.attrs['value']
-
- selects = BeautifulSoup(html, 'lxml').find_all('select')
- for select in selects:
- value = select.find_all('option', selected=True)[0].getText()
- options[select.attrs['name']] = value
-
- return options
-
- def list_options(self, builder):
- builders = self._get_builders()
- if not builder in builders:
- print('Builder %s specified isn\'t available' % builder)
- return 1
-
- opts = self._get_options_by_builder(builder)
- print('Available options in builder %s:\n' % (builder))
- for name in opts:
- value = opts[name]
- print('Name: %s, Default value: %s' % (name, value))
-
- def force_build(self, builder, opts, idle_check=False):
- builders = self._get_builders()
- if not builder in builders:
- print('Builder specified isn\'t available')
- return 1
-
- state = builders[builder]['state']
- if idle_check and not state == 'idle':
- print('Builder %s specified isn\'t IDLE, current state %s' \
- % (builder, state))
- return 1
-
- if opts:
- # FIXME: transform string argument into dictionary, security?
- opts = eval(opts)
- else:
- opts = {}
- current_opts = self._get_options_by_builder(builder)
- for opt in opts:
- if not opt in current_opts:
- print('Option %s isn\'t supported by builder %s' % \
- (opt, builder))
- return 1
- else:
- current_opts[opt] = opts[opt]
-
- url_params = urllib.urlencode(current_opts)
- url = "%s/builders/%s/force" % (self.server, builder)
- request = urllib2.Request(url, url_params)
- result = self.opener.open(request)
- if 'Forced build' in result.read():
- return 0
- else:
- print("Failed to force build")
- return 1
-
-def main():
- parser = argparse.ArgumentParser(description="Yocto Autobuilder force build script",
- add_help=False)
- parser.add_argument('-s', '--server', help='Server URL',
- action='store', required=True)
-
- parser.add_argument('-u', '--username', action='store', required=True)
- parser.add_argument('-p', '--password', action='store', required=True)
-
- group = parser.add_mutually_exclusive_group()
- group.add_argument('--list-builders', help='List available builders',
- action='store_true')
- group.add_argument('--list-options', help='List options by builder',
- action='store', metavar='BUILDER')
- group.add_argument('--force-build', help='Force build by builder',
- action='store', metavar='BUILDER')
- group.add_argument('--force-build-idle', help='Force build by builder if is idle',
- action='store', metavar='BUILDER')
-
- parser.add_argument('-o', '--options', help='Custom options by operation',
- action='store')
-
- parser.add_argument('-d', '--debug', help='Enable debug output',
- action='store_true')
- parser.add_argument('-q', '--quiet', help='Print only errors',
- action='store_true')
-
- parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
- help='show this help message and exit')
-
- args = parser.parse_args()
-
- api = YoctoAutobuilderAPI(args.server)
- if api.login(args.username, args.password):
- return 1
-
- if args.list_builders:
- return api.list_builders()
- elif args.list_options:
- return api.list_options(args.list_options)
- elif args.force_build:
- return api.force_build(args.force_build, args.options)
- elif args.force_build_idle:
- return api.force_build(args.force_build_idle, args.options, idle_check=True)
-
-if __name__ == '__main__':
- try:
- ret = main()
- except Exception:
- ret = 1
- import traceback
- traceback.print_exc()
- sys.exit(ret)
diff --git a/bin/htpasswd b/bin/htpasswd
deleted file mode 100755
index 8af117b7..00000000
--- a/bin/htpasswd
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python
-"""Replacement for htpasswd"""
-# Original author: Eli Carter
-
-import os
-import sys
-import random
-from optparse import OptionParser
-
-# We need a crypt module, but Windows doesn't have one by default. Try to find
-# one, and tell the user if we can't.
-try:
- import crypt
-except ImportError:
- try:
- import fcrypt as crypt
- except ImportError:
- sys.stderr.write("Cannot find a crypt module. "
- "Possibly http://carey.geek.nz/code/python-fcrypt/\n")
- sys.exit(1)
-
-
-def salt():
- """Returns a string of 2 randome letters"""
- letters = 'abcdefghijklmnopqrstuvwxyz' \
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
- '0123456789/.'
- return random.choice(letters) + random.choice(letters)
-
-
-class HtpasswdFile:
- """A class for manipulating htpasswd files."""
-
- def __init__(self, filename, create=False):
- self.entries = []
- self.filename = filename
- if not create:
- if os.path.exists(self.filename):
- self.load()
- else:
- raise Exception("%s does not exist" % self.filename)
-
- def load(self):
- """Read the htpasswd file into memory."""
- lines = open(self.filename, 'r').readlines()
- self.entries = []
- for line in lines:
- username, pwhash = line.split(':')
- entry = [username, pwhash.rstrip()]
- self.entries.append(entry)
-
- def save(self):
- """Write the htpasswd file to disk"""
- open(self.filename, 'w').writelines(["%s:%s\n" % (entry[0], entry[1])
- for entry in self.entries])
-
- def update(self, username, password):
- """Replace the entry for the given user, or add it if new."""
- pwhash = crypt.crypt(password, salt())
- matching_entries = [entry for entry in self.entries
- if entry[0] == username]
- if matching_entries:
- matching_entries[0][1] = pwhash
- else:
- self.entries.append([username, pwhash])
-
- def delete(self, username):
- """Remove the entry for the given user."""
- self.entries = [entry for entry in self.entries
- if entry[0] != username]
-
-
-def main():
- """%prog [-c] -b filename username password
- Create or update an htpasswd file"""
- # For now, we only care about the use cases that affect tests/functional.py
- parser = OptionParser(usage=main.__doc__)
- parser.add_option('-b', action='store_true', dest='batch', default=False,
- help='Batch mode; password is passed on the command line IN THE CLEAR.'
- )
- parser.add_option('-c', action='store_true', dest='create', default=False,
- help='Create a new htpasswd file, overwriting any existing file.')
- parser.add_option('-D', action='store_true', dest='delete_user',
- default=False, help='Remove the given user from the password file.')
-
- options, args = parser.parse_args()
-
- def syntax_error(msg):
- """Utility function for displaying fatal error messages with usage
- help.
- """
- sys.stderr.write("Syntax error: " + msg)
- sys.stderr.write(parser.get_usage())
- sys.exit(1)
-
- if not options.batch:
- syntax_error("Only batch mode is supported\n")
-
- # Non-option arguments
- if len(args) < 2:
- syntax_error("Insufficient number of arguments.\n")
- filename, username = args[:2]
- if options.delete_user:
- if len(args) != 2:
- syntax_error("Incorrect number of arguments.\n")
- password = None
- else:
- if len(args) != 3:
- syntax_error("Incorrect number of arguments.\n")
- password = args[2]
-
- passwdfile = HtpasswdFile(filename, create=options.create)
-
- if options.delete_user:
- passwdfile.delete(username)
- else:
- passwdfile.update(username, password)
-
- passwdfile.save()
-
-
-if __name__ == '__main__':
- main()
diff --git a/bin/lore b/bin/lore
deleted file mode 100755
index 52b04af3..00000000
--- a/bin/lore
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','lore'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'lore')
diff --git a/bin/mailmail b/bin/mailmail
deleted file mode 100755
index f31920da..00000000
--- a/bin/mailmail
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','mailmail'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'mailmail')
diff --git a/bin/manhole b/bin/manhole
deleted file mode 100755
index 40dc7249..00000000
--- a/bin/manhole
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','manhole'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'manhole')
diff --git a/bin/migrate b/bin/migrate
deleted file mode 100755
index 49736bd5..00000000
--- a/bin/migrate
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-ENTRY-SCRIPT: 'sqlalchemy-migrate==0.7.2','console_scripts','migrate'
-__requires__ = 'sqlalchemy-migrate==0.7.2'
-import sys
-from pkg_resources import load_entry_point
-
-if __name__ == '__main__':
- sys.exit(
- load_entry_point('sqlalchemy-migrate==0.7.2', 'console_scripts', 'migrate')()
- )
diff --git a/bin/migrate-repository b/bin/migrate-repository
deleted file mode 100755
index d90b6206..00000000
--- a/bin/migrate-repository
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-ENTRY-SCRIPT: 'sqlalchemy-migrate==0.7.2','console_scripts','migrate-repository'
-__requires__ = 'sqlalchemy-migrate==0.7.2'
-import sys
-from pkg_resources import load_entry_point
-
-if __name__ == '__main__':
- sys.exit(
- load_entry_point('sqlalchemy-migrate==0.7.2', 'console_scripts', 'migrate-repository')()
- )
diff --git a/bin/pyhtmlizer b/bin/pyhtmlizer
deleted file mode 100755
index 97bad8de..00000000
--- a/bin/pyhtmlizer
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','pyhtmlizer'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'pyhtmlizer')
diff --git a/bin/tap2deb b/bin/tap2deb
deleted file mode 100755
index 5096cea4..00000000
--- a/bin/tap2deb
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','tap2deb'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'tap2deb')
diff --git a/bin/tap2rpm b/bin/tap2rpm
deleted file mode 100755
index c92462aa..00000000
--- a/bin/tap2rpm
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','tap2rpm'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'tap2rpm')
diff --git a/bin/tapconvert b/bin/tapconvert
deleted file mode 100755
index b472cbd8..00000000
--- a/bin/tapconvert
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','tapconvert'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'tapconvert')
diff --git a/bin/tkconch b/bin/tkconch
deleted file mode 100755
index 5aad346d..00000000
--- a/bin/tkconch
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','tkconch'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'tkconch')
diff --git a/bin/trial b/bin/trial
deleted file mode 100755
index 12248a0b..00000000
--- a/bin/trial
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','trial'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'trial')
diff --git a/bin/twistd b/bin/twistd
deleted file mode 100755
index 167dc811..00000000
--- a/bin/twistd
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-# EASY-INSTALL-SCRIPT: 'Twisted==12.2.0','twistd'
-__requires__ = 'Twisted==12.2.0'
-import pkg_resources
-pkg_resources.run_script('Twisted==12.2.0', 'twistd')
diff --git a/bin/worker-init b/bin/worker-init
deleted file mode 100755
index 7c6f827a..00000000
--- a/bin/worker-init
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-if [ ! -f /var/log/firstboot.log ]
-then
- START_SECTOR=$(fdisk -l | grep sda1 | sed 's/\*//' | awk '{ print $2 }')
- echo -e "d\nn\n\n\n$START_SECTOR\n\nw\n" | fdisk /dev/sda
- touch /var/log/firstboot.log
- reboot
-fi
-
-if [ ! -f /var/log/secondboot.log ]
-then
- resize2fs /dev/sda1
- sudo apt-get update
- yes | sudo apt-get install make
- yes | sudo apt-get install git
- yes | sudo apt-get install gcc
- yes | sudo apt-get install g++
- yes | sudo apt-get install diffstat
- yes | sudo apt-get install texinfo
- yes | sudo apt-get install bzip2
- yes | sudo apt-get install gawk
- yes | sudo apt-get install chrpath
- yes | sudo apt-get install libsdl1.2-dev
- yes "dummyinfo" | adduser autobuilder
- touch /var/log/secondboot.log
-fi
-
-WORKER_NUM=$(uname -n | grep -o [0-9])
-
-cd /home/autobuilder
-su autobuilder -c "yes 'yes' | git clone git://git.yoctoproject.org/yocto-autobuilder"
-
-cd yocto-autobuilder
-su autobuilder -c '. ./yocto-autobuilder-setup'
-su autobuilder -c "sed -i 's/example-worker/worker'$WORKER_NUM'/' yocto-worker/buildbot.tac"
-su autobuilder -c 'sed -i "s/passwd =.*/passwd = '"'"'<PASS>'"'"'/" yocto-worker/buildbot.tac'
-su autobuilder -c 'sed -i "s/buildmaster_host =.*/buildmaster_host = '"'"'<HOST_ADDR>'"'"'/" yocto-worker/buildbot.tac'
-su autobuilder -c '. ./yocto-autobuilder-setup; ./yocto-start-autobuilder worker &'
diff --git a/buildset-config.autobuilder-qa/test_fail_conditions.conf b/buildset-config.autobuilder-qa/test_fail_conditions.conf
deleted file mode 100644
index 67e69c95..00000000
--- a/buildset-config.autobuilder-qa/test_fail_conditions.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-[test_fail_conditions]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'bbpriority':'1',
- 'branch':'danny'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'bbpriority':'1',
- 'branch':'danny'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'bbpriority':'2',
- 'branch':'danny'}},
- {'meta-minnow':
- {'repourl':'git://git.yoctoproject.org/meta-minnow',
- 'bbpriority':'2',
- 'branch':'danny'}}]
-steps: [{'TestFailStep':{}}]
-
diff --git a/buildset-config.controller/build-appliance.conf b/buildset-config.controller/build-appliance.conf
deleted file mode 100644
index cd9972bf..00000000
--- a/buildset-config.controller/build-appliance.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-[build-appliance]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'buildappsrcrev':{'prop_type':'StringParameter', 'default':'AUTOREV',
- 'name': 'buildappsrcrev',
- 'required': True,
- 'size': '70',
- 'label':'<h3> Build appliance src revision. Use DEFAULT to take the srcrev currently in the recipe:</h3>'}},
- {'deploy_artifacts':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'deploy_artifacts',
- 'label':'<hr><h3> Do we want to deploy artifacts? </br>Selecting False speeds up autobuilder time and saves space on the cluster by not publishing artifacts:</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildapp': True,
- 'atextprepend': 'SOURCE_MIRROR_FETCH = "1"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'universe -c fetch'}},
- {'BuildImages': {'images': 'build-appliance-image'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['build-appliance', 'md5sums']}}]
-
diff --git a/buildset-config.controller/buildtools.conf b/buildset-config.controller/buildtools.conf
deleted file mode 100644
index 27ece6ac..00000000
--- a/buildset-config.controller/buildtools.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[buildtools]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'deploy_artifacts':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'deploy_artifacts',
- 'label':'<hr><h3> Do we want to deploy artifacts? </br>Selecting False speeds up autobuilder time and saves space on the cluster by not publishing artifacts:</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'buildtools-tarball'}},
- {'BuildImages': {'images': 'uninative-tarball'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildapp': True}},
- {'BuildImages': {'images': 'uninative-tarball'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'PublishArtifacts': {'artifacts': ['buildtools-tarball', 'uninative', 'md5sums']}}]
diff --git a/buildset-config.controller/eclipse-plugin-neon.conf b/buildset-config.controller/eclipse-plugin-neon.conf
deleted file mode 100644
index 0a262d2f..00000000
--- a/buildset-config.controller/eclipse-plugin-neon.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-[eclipse-plugin-neon]
-builders: 'example-worker'
-repos: [{'eclipse-poky-neon':
- {'repourl':'git://git.yoctoproject.org/eclipse-poky',
- 'branch':'neon-master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'BuildEclipsePlugin': {'eclipsedir': 'eclipse-poky-neon'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['eclipse-plugin-neon']}}]
-
diff --git a/buildset-config.controller/eclipse-plugin-oxygen.conf b/buildset-config.controller/eclipse-plugin-oxygen.conf
deleted file mode 100644
index 96775623..00000000
--- a/buildset-config.controller/eclipse-plugin-oxygen.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-[eclipse-plugin-oxygen]
-builders: 'example-worker'
-repos: [{'eclipse-poky-oxygen':
- {'repourl':'git://git.yoctoproject.org/eclipse-poky',
- 'branch':'oxygen-master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'BuildEclipsePlugin': {'eclipsedir': 'eclipse-poky-oxygen'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['eclipse-plugin-oxygen']}}]
-
diff --git a/buildset-config.controller/nightly-arm-lsb.conf b/buildset-config.controller/nightly-arm-lsb.conf
deleted file mode 100644
index 46f7cda7..00000000
--- a/buildset-config.controller/nightly-arm-lsb.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-[nightly-arm-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'RunSanityTests': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'CreateAutoConf': {'machine': 'beaglebone-yocto',
- 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb',
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemuarm', 'beaglebone-yocto', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-arm.conf b/buildset-config.controller/nightly-arm.conf
deleted file mode 100644
index cd56a1b6..00000000
--- a/buildset-config.controller/nightly-arm.conf
+++ /dev/null
@@ -1,44 +0,0 @@
-[nightly-arm]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'beaglebone-yocto',
- 'SDKMACHINE' : 'i686', 'distro': 'poky',
- 'buildinfo': True}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato-sdk-ptest'}},
- {'CreateAutoConf': {'machine': 'beaglebone-yocto',
- 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal core-image-sato'}},
- {'RunESDKSanityTests': {'images': 'core-image-minimal core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemuarm', 'beaglebone-yocto', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-arm64.conf b/buildset-config.controller/nightly-arm64.conf
deleted file mode 100644
index 530f1f72..00000000
--- a/buildset-config.controller/nightly-arm64.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-[nightly-arm64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuarm64', 'SDKMACHINE' :'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'qemuarm64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemuarm64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'RunESDKSanityTests': {'images': 'core-image-minimal'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemuarm64', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-checkuri.conf b/buildset-config.controller/nightly-checkuri.conf
deleted file mode 100644
index dd2e06c6..00000000
--- a/buildset-config.controller/nightly-checkuri.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-[nightly-checkuri]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'prserv': False,
- 'atextprepend': 'SOURCE_MIRROR_FETCH = "1"\n',
- 'atextappend': 'BB_NUMBER_THREADS = "1"\ndo_checkuri_pn-lsof = ""\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'universe -c checkuri'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-selftest']}},
- {'RunOeSelftest': {'tests': 'distrodata.Distrodata.test_checkpkg'}},
- ]
diff --git a/buildset-config.controller/nightly-deb-non-deb.conf b/buildset-config.controller/nightly-deb-non-deb.conf
deleted file mode 100644
index b97d81f8..00000000
--- a/buildset-config.controller/nightly-deb-non-deb.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-[nightly-deb-non-deb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'packages': 'deb'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-mips-lsb.conf b/buildset-config.controller/nightly-mips-lsb.conf
deleted file mode 100644
index 7e44fa0a..00000000
--- a/buildset-config.controller/nightly-mips-lsb.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-[nightly-mips-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'RunSanityTests': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'CreateAutoConf': {'machine': 'routerstationpro',
- 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb',
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemumips', 'routerstationpro', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-mips.conf b/buildset-config.controller/nightly-mips.conf
deleted file mode 100644
index c7b79d1b..00000000
--- a/buildset-config.controller/nightly-mips.conf
+++ /dev/null
@@ -1,39 +0,0 @@
-[nightly-mips]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'routerstationpro',
- 'SDKMACHINE' : 'i686', 'distro': 'poky',
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato-sdk-ptest'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal core-image-sato'}},
- {'RunESDKSanityTests': {'images': 'core-image-minimal core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemumips', 'routerstationpro', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-mips64.conf b/buildset-config.controller/nightly-mips64.conf
deleted file mode 100644
index 41b70d4f..00000000
--- a/buildset-config.controller/nightly-mips64.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-[nightly-mips64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemumips64', 'SDKMACHINE' :'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'qemumips64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemumips64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemumips64', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-multilib.conf b/buildset-config.controller/nightly-multilib.conf
deleted file mode 100644
index 2c842f5f..00000000
--- a/buildset-config.controller/nightly-multilib.conf
+++ /dev/null
@@ -1,49 +0,0 @@
-[nightly-multilib]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'multilib': True,
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'lib32-core-image-minimal'}},
- {'RunSanityTests': {'images': 'lib32-core-image-minimal',
- 'scene' : 'sanity:boot', 'suites' : 'ping'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'multilib': True,
- 'distro': 'poky', 'packages' : 'ipk'}},
- {'BuildImages': {'images': 'lib32-core-image-minimal'}},
- {'RunSanityTests': {'images': 'lib32-core-image-minimal',
- 'scene' : 'sanity:boot', 'suites' : 'ping'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'multilib': 'lib32',
- 'distro': 'poky',
- 'atextappend' : '\nRPM_PREFER_ELF_ARCH = "1"\nIMAGE_INSTALL_append = " lib32-connman-gnome gdk-pixbuf-loader-jpeg lib32-gdk-pixbuf-loader-jpeg gdk-pixbuf-loader-png lib32-gdk-pixbuf-loader-png pango-module-basic-fc lib32-pango-module-basic-fc"\n'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'multilib'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'multilib': 'lib32',
- 'distro': 'poky', 'packages' : 'ipk',
- 'atextappend' : '\nIMAGE_INSTALL_append = " lib32-connman-gnome gdk-pixbuf-loader-jpeg lib32-gdk-pixbuf-loader-jpeg gdk-pixbuf-loader-png lib32-gdk-pixbuf-loader-png pango-module-basic-fc lib32-pango-module-basic-fc"\n'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'multilib'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'multilib': 'lib64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'lib64-core-image-sato lib64-core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'qemumips64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False,
- 'distro': 'poky',
- 'atextappend' : '\nrequire conf/multilib.conf\nMULTILIBS = "multilib:lib64 multilib:lib32"\nDEFAULTTUNE = "mips64-n32"\nDEFAULTTUNE_virtclass-multilib-lib64 = "mips64"\nDEFAULTTUNE_virtclass-multilib-lib32 = "mips32r2"\n'}},
- {'BuildImages': {'images': 'core-image-minimal'}},
- {'RunSanityTests': {'images': 'core-image-minimal'}},
- {'BuildImages': {'images': '-c populate_sdk core-image-minimal'}},
- {'RunSDKSanityTests': {'images': 'core-image-minimal'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-musl-x86-64.conf b/buildset-config.controller/nightly-musl-x86-64.conf
deleted file mode 100644
index 403110cd..00000000
--- a/buildset-config.controller/nightly-musl-x86-64.conf
+++ /dev/null
@@ -1,19 +0,0 @@
-[nightly-musl-x86-64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nTCLIBC="musl"\n',
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal core-image-full-cmdline core-image-sato-sdk world'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-full-cmdline core-image-sato-sdk'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-musl.conf b/buildset-config.controller/nightly-musl.conf
deleted file mode 100644
index da98e01e..00000000
--- a/buildset-config.controller/nightly-musl.conf
+++ /dev/null
@@ -1,18 +0,0 @@
-[nightly-musl]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nTCLIBC="musl"\n' }},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal core-image-full-cmdline core-image-sato-sdk world'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-full-cmdline core-image-sato-sdk'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-no-x11.conf b/buildset-config.controller/nightly-no-x11.conf
deleted file mode 100644
index fa6a5a8a..00000000
--- a/buildset-config.controller/nightly-no-x11.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[nightly-no-x11]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextappend' : '\nDISTRO_FEATURES_remove = "x11"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-full-cmdline core-image-weston world'}},
- {'RunSanityTests': {'images': 'core-image-full-cmdline core-image-weston'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}}]
diff --git a/buildset-config.controller/nightly-non-gpl3.conf b/buildset-config.controller/nightly-non-gpl3.conf
deleted file mode 100644
index 7c82fb9e..00000000
--- a/buildset-config.controller/nightly-non-gpl3.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-[nightly-non-gpl3]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-gplv2':
- {'repourl':'git://git.yoctoproject.org/meta-gplv2',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'gplv3': False, 'distro': 'poky',
- 'buildhistory' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal core-image-basic'}},
- {'CheckForGPLv3':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-oe-selftest.conf b/buildset-config.controller/nightly-oe-selftest.conf
deleted file mode 100644
index 3c2b0cdb..00000000
--- a/buildset-config.controller/nightly-oe-selftest.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-[nightly-oe-selftest]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'packages': 'rpm',
- 'buildhistory' : False, 'prserv': False,
- 'atextappend': 'RPM_GPG_SIGN_CHUNK = "1"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'SELFTEST-PRE'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-selftest']}},
- {'RunOeSelftest': {'skiptests': 'distrodata.Distrodata.test_checkpkg'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- ]
diff --git a/buildset-config.controller/nightly-oecore.conf b/buildset-config.controller/nightly-oecore.conf
deleted file mode 100644
index e943a8e9..00000000
--- a/buildset-config.controller/nightly-oecore.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-[nightly-oecore]
-builders: 'example-worker'
-repos: [{'oecore':
- {'repourl':'git://git.openembedded.org/openembedded-core',
- 'layerversion':{'core':'meta'},
- 'branch':'master'}},
- {'bitbake':
- {'repourl':'git://git.openembedded.org/bitbake',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'oecore'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686',
- 'distro': 'oecore', 'buildhistory' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'oe'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686',
- 'distro': 'oecore', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'x86_64',
- 'distro': 'oecore', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}
- ]
diff --git a/buildset-config.controller/nightly-packagemanagers.conf b/buildset-config.controller/nightly-packagemanagers.conf
deleted file mode 100644
index 986cef32..00000000
--- a/buildset-config.controller/nightly-packagemanagers.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[nightly-packagemanagers]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'packages': 'rpm'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images' : 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images' : 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'packages': 'ipk'}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images' : 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'packages': 'deb'}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-ppc-lsb.conf b/buildset-config.controller/nightly-ppc-lsb.conf
deleted file mode 100644
index b6abb8ec..00000000
--- a/buildset-config.controller/nightly-ppc-lsb.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-[nightly-ppc-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'RunSanityTests': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'CreateAutoConf': {'machine': 'mpc8315e-rdb', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : False,
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemuppc', 'mpc8315e-rdb', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-ppc.conf b/buildset-config.controller/nightly-ppc.conf
deleted file mode 100644
index a7cdbc8d..00000000
--- a/buildset-config.controller/nightly-ppc.conf
+++ /dev/null
@@ -1,38 +0,0 @@
-[nightly-ppc]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'mpc8315e-rdb', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato-sdk-ptest'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal core-image-sato'}},
- {'RunESDKSanityTests': {'images': 'core-image-minimal core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemuppc', 'mpc8315e-rdb', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-qa-extras.conf b/buildset-config.controller/nightly-qa-extras.conf
deleted file mode 100644
index 7aeb903a..00000000
--- a/buildset-config.controller/nightly-qa-extras.conf
+++ /dev/null
@@ -1,83 +0,0 @@
-[nightly-qa-extras]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-mingw':
- {'repourl':'git://git.yoctoproject.org/meta-mingw',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextappend' : '\nIMAGE_FEATURES_append = " read-only-rootfs"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal'}},
- {'RunSanityTests': {'images': 'core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextappend' : '\nROOT_HOME = "/root"\n'}},
- {'BuildImages': {'images': 'core-image-minimal'}},
- {'RunSanityTests': {'images': 'core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextappend' : '\nDISTRO_FEATURES_append = " api-documentation"\n'}},
- {'BuildImages': {'images': 'core-image-sato:do_populate_sdk'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686-mingw32', 'distro': 'poky', 'buildhistory' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-mingw']}},
- {'BuildImages': {'images': 'core-image-minimal -c populate_sdk'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE': 'x86_64',
- 'distro': 'poky', 'buildhistory': False,
- 'atextappend': '\nSDK_EXT_TYPE = "full"\n'}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato:do_populate_sdk_ext'}},
- {'BuildImages': {'images': 'core-image-sato -S none'}},
- {'RemoveTmpFiles': {}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'tmpdir': 'newtmp',
- 'lockedsigs': True}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'tmpdir': 'sdktmp'}},
- {'BuildImages': {'images': 'core-image-sato:do_populate_sdk_ext'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nIMAGE_INSTALL_append = " logrotate"\n'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'logrotate'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nDISTRO_FEATURES_append = " pam"\n'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'pam'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nIMAGE_INSTALL_append = " service hello-mod"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-skeleton']}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'skeletoninit'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'initmgr' : 'systemd sysvinit'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'systemd'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'initmgr' : 'sysvinit systemd'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'initmgr' : 'systemd'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'systemd'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-refkit.conf b/buildset-config.controller/nightly-refkit.conf
deleted file mode 100644
index d36908cd..00000000
--- a/buildset-config.controller/nightly-refkit.conf
+++ /dev/null
@@ -1,34 +0,0 @@
-[nightly-refkit]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'refkit':
- {'repourl':'git://git.yoctoproject.org/intel-iot-refkit',
- 'branch':'master',
- 'autoinclude': False,
- 'submodules': True}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {'submodules': True}},
- {'RunPreamble': {'altcmd': 'refkit/oe-init-build-env'}},
- {'GetDistroVersion' : {'distro': 'refkit'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'packages': 'ipk',
- 'distro': 'refkit', 'buildhistory' : False,
- 'prserv': False, 'nosstate': True,
- 'SDKMACHINE' : 'x86_64',
- 'atextappend': '\nrequire conf/distro/include/refkit-ci.inc\nSUPPORTED_RECIPES_CHECK_append = " warn"\nSUPPORTED_RECIPES_CHECK_remove = "fatal"\n'}},
- {'ModBBLayersConf': {'sub': [['openembedded-core/meta', '#YPDIR/meta'],
- ['openembedded-core/meta-selftest',
- '#YPDIR/meta-selftest']]}},
- {'ScrapeTargets': {'source': 'refkit/meta-refkit/conf/distro/include/refkit-ci.inc',
- 'targetsvar': 'REFKIT_CI_BUILD_TARGETS'}},
- {'BuildImages': {'images': '#SCRAPEDTARGETS',
- 'oeinit': 'refkit/oe-init-build-env',
- 'overrideenv': ['BITBAKEDIR=#YPDIR/bitbake', 'OEROOT=#YPDIR/meta']}},
- {'ScrapeTargets': {'source': 'refkit/meta-refkit/conf/distro/include/refkit-ci.inc',
- 'targetsvar': 'REFKIT_CI_POSTBUILD_SELFTESTS'}},
- {'RunOeSelftest': {'tests': '#SCRAPEDTARGETS'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}
- ]
diff --git a/buildset-config.controller/nightly-rpm-non-rpm.conf b/buildset-config.controller/nightly-rpm-non-rpm.conf
deleted file mode 100644
index 4ac743a9..00000000
--- a/buildset-config.controller/nightly-rpm-non-rpm.conf
+++ /dev/null
@@ -1,18 +0,0 @@
-[nightly-rpm-non-rpm]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'packages': 'rpm'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images' : 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images' : 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-uclibc.conf b/buildset-config.controller/nightly-uclibc.conf
deleted file mode 100644
index 40931a7e..00000000
--- a/buildset-config.controller/nightly-uclibc.conf
+++ /dev/null
@@ -1,18 +0,0 @@
-[nightly-uclibc]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nTCLIBC="uclibc"\n' }},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
-
diff --git a/buildset-config.controller/nightly-wic.conf b/buildset-config.controller/nightly-wic.conf
deleted file mode 100644
index 676de2b0..00000000
--- a/buildset-config.controller/nightly-wic.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-[nightly-wic]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers':{}},
- {'RunPreamble':{}},
- {'GetDistroVersion':{'distro': 'poky'}},
- {'CreateBBLayersConf':{'buildprovider':'yocto'}},
- {'CreateAutoConf':{'machine':'qemux86', 'buildinfo': True,
- 'atextappend':'\nIMAGE_FSTYPES += " hddimg"\nMACHINE_FEATURES_append = " efi"\n'}},
- {'BuildImages':{'images':'wic-tools'}},
- {'BuildImages':{'images':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk-gpt', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'mkefidisk', 'target_img':'core-image-sato'}},
- {'CreateAutoConf':{'machine':'genericx86', 'atextappend':'\nIMAGE_FSTYPES += " hddimg"\nMACHINE_FEATURES_append = " efi"\n'}},
- {'BuildImages':{'images':'wic-tools'}},
- {'BuildImages':{'images':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk-gpt', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'mkefidisk', 'target_img':'core-image-sato'}},
- {'CreateAutoConf':{'machine':'qemux86-64', 'buildinfo': True,
- 'atextappend':'\nIMAGE_FSTYPES += " hddimg"\nMACHINE_FEATURES_append = " efi"\n'}},
- {'BuildImages':{'images':'wic-tools'}},
- {'BuildImages':{'images':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk-gpt', 'target_img':'core-image-sato'}},
- {'CreateAutoConf':{'machine':'genericx86-64', 'buildinfo': True,
- 'atextappend':'\nIMAGE_FSTYPES += " hddimg"\nMACHINE_FEATURES_append = " efi"\n'}},
- {'BuildImages':{'images':'wic-tools'}},
- {'BuildImages':{'images':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'directdisk-gpt', 'target_img':'core-image-sato'}},
- {'CreateWicImages':{'wic_img_type':'mkefidisk', 'target_img':'core-image-sato'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'PublishArtifacts': {'artifacts': ['qemux86', 'qemux86-64', 'genericx86', 'genericx86-64']}}]
diff --git a/buildset-config.controller/nightly-world-lsb.conf b/buildset-config.controller/nightly-world-lsb.conf
deleted file mode 100644
index afc75467..00000000
--- a/buildset-config.controller/nightly-world-lsb.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-[nightly-world-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CheckForWorldLsb':{}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'multilib': True,
- 'atextprepend': 'QTDEMOS_remove = "qmmp"\n',
- 'distro': 'poky-lsb'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'world'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-world.conf b/buildset-config.controller/nightly-world.conf
deleted file mode 100644
index 44458bf4..00000000
--- a/buildset-config.controller/nightly-world.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-[nightly-world]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'multilib': True,
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'world'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.controller/nightly-x32.conf b/buildset-config.controller/nightly-x32.conf
deleted file mode 100644
index 04d88163..00000000
--- a/buildset-config.controller/nightly-x32.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-[nightly-x32]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'GetBitbakeVersion': {}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'x32': True,
- 'distro': 'poky', 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'PublishLayerTarballs':{}},
- {'BuildImages': {'images': 'core-image-minimal core-image-sato'}},
- {'RunSanityTests': {'images': 'core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'x32': True,
- 'distro': 'poky', 'buildinfo': True}},
- {'RunSanityTests': {'images': 'core-image-sato', 'suitesappend' : 'x32lib'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['md5sums']}}]
diff --git a/buildset-config.controller/nightly-x86-64-lsb.conf b/buildset-config.controller/nightly-x86-64-lsb.conf
deleted file mode 100644
index 2f0eb4af..00000000
--- a/buildset-config.controller/nightly-x86-64-lsb.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-[nightly-x86-64-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : True,
- 'buildinfo': True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'RunSanityTests': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'CreateAutoConf': {'machine': 'genericx86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : False,
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemux86-64', 'genericx86-64', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-x86-64.conf b/buildset-config.controller/nightly-x86-64.conf
deleted file mode 100644
index 2db18dc7..00000000
--- a/buildset-config.controller/nightly-x86-64.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-[nightly-x86-64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'atextappend': '\nIMAGE_FSTYPES_append = " wic wic.bmap"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'genericx86-64', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky',
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato-sdk-ptest'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal core-image-sato'}},
- {'RunESDKSanityTests': {'images': 'core-image-minimal core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemux86-64', 'genericx86-64', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-x86-lsb.conf b/buildset-config.controller/nightly-x86-lsb.conf
deleted file mode 100644
index 5a29b0c4..00000000
--- a/buildset-config.controller/nightly-x86-lsb.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-[nightly-x86-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'buildhistory' : True, 'distro': 'poky-lsb'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'RunSanityTests': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'CreateAutoConf': {'machine': 'genericx86', 'SDKMACHINE' : 'i686',
- 'buildhistory' : False, 'distro': 'poky-lsb',
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-sdk'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemux86', 'genericx86', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly-x86.conf b/buildset-config.controller/nightly-x86.conf
deleted file mode 100644
index 5b4775cf..00000000
--- a/buildset-config.controller/nightly-x86.conf
+++ /dev/null
@@ -1,41 +0,0 @@
-[nightly-x86]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'buildinfo': True,
- 'atextappend': '\nIMAGE_FSTYPES_append = " wic wic.bmap"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'RunSanityTests': {'images': 'core-image-minimal core-image-sato core-image-sato-sdk'}},
- {'CreateAutoConf': {'machine': 'genericx86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'buildinfo': True}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato-sdk-ptest'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False}},
- {'BuildToolchainImages': {}},
- {'RunSDKSanityTests': {'images': 'core-image-sato'}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal core-image-sato'}},
- {'RunESDKSanityTests': {'images': 'core-image-minimal core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['qemux86', 'genericx86', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.controller/nightly.conf b/buildset-config.controller/nightly.conf
deleted file mode 100644
index e17d3fdf..00000000
--- a/buildset-config.controller/nightly.conf
+++ /dev/null
@@ -1,170 +0,0 @@
-[nightly]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'branch':'master'}},
- {'oecore':
- {'repourl':'git://git.openembedded.org/openembedded-core',
- 'layerversion':'core',
- 'checkout':False,
- 'branch':'master'}},
- {'bitbake':
- {'repourl':'git://git.openembedded.org/bitbake',
- 'checkout':False,
- 'branch':'master'}},
- {'eclipse-poky-neon':
- {'repourl':'git://git.yoctoproject.org/eclipse-poky',
- 'checkout':False,
- 'branch':'neon-master'}},
- {'eclipse-poky-oxygen':
- {'repourl':'git://git.yoctoproject.org/eclipse-poky',
- 'checkout':False,
- 'branch':'oxygen-master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-mingw':
- {'repourl':'git://git.yoctoproject.org/meta-mingw',
- 'branch':'master'}},
- {'meta-gplv2':
- {'repourl':'git://git.yoctoproject.org/meta-gplv2',
- 'branch':'master'}}]
-props: [{'release_me':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'release_me',
- 'label':'<h3> Generate a release?:</h3>'}},
- {'poky_name':{'prop_type':'ChoiceStringParameter',
- 'choices': ['', 'sumo', 'rocko', 'pyro', 'morty'],
- 'name': 'poky_name',
- 'label':'<h3> Name of the poky release.<br>For further info on release names see <a href="https://wiki.yoctoproject.org/wiki/Releases"> Releases </a> </h3>'}},
- {'is_milestone':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'is_milestone',
- 'label':'<h3> If this a milestone release (M1 - M3)? If so the poky number and poky name will be appended with a "+snapshot"</h3>'}},
- {'poky_number':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'poky_number',
- 'label':'<h3> Poky Release Number (10.0.0, 11.0.1 etc.):</h3>'}},
- {'yocto_number':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'yocto_number',
- 'label':'<h3> Yocto Project Release Number (1.5, 1.6 etc.):</h3>'}},
- {'milestone_number':{'prop_type':'ChoiceStringParameter',
- 'choices': ['', 'M1', 'M2', 'M3'],
- 'name': 'milestone_number',
- 'label':'<h3> Milestone number: </h3>'}},
- {'rc_number':{'prop_type':'ChoiceStringParameter',
- 'choices': ['', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6', 'rc7', 'rc8', 'rc9'],
- 'name': 'rc_number',
- 'label':'<h3> Release candidate number: </h3>'}},
- {'send_email':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'send_email',
- 'label':'<h3> Send QA alert emails?:</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}},
- {'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr><h3> Should a Toaster event log be created as part of the image creation?:</h3>'}},
- {'deploy_artifacts':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'deploy_artifacts',
- 'label':'<hr><h3> Do we want to deploy artifacts? </br>Selecting False speeds up autobuilder time and saves space on the cluster by not publishing artifacts:</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CheckYoctoCompat': {'layers': ['meta-poky', 'meta-yocto-bsp',
- 'meta-mingw', 'meta-gplv2']}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky',
- 'atextprepend': 'SOURCE_MIRROR_FETCH = "1"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'universe -c fetch'}},
- {'TriggerBuilds': {'copy_properties': ['custom_create_eventlog',
- 'custom_yocto_number', 'is_release', 'custom_deploy_artifacts'],
- 'schedulerName': 'main-build', 'waitForFinish': 'True',
- 'schedulerNames': {'nightly-arm': {}, 'nightly-arm-lsb': {},
- 'nightly-mips': {}, 'nightly-mips-lsb': {},
- 'nightly-multilib': {}, 'nightly-x32': {},
- 'nightly-ppc': {}, 'nightly-ppc-lsb': {},
- 'nightly-x86-64': {}, 'nightly-x86-64-lsb': {},
- 'nightly-x86': {}, 'nightly-x86-lsb': {},
- 'nightly-packagemanagers': {},
- 'nightly-mips64': {}, 'nightly-arm64': {},
- 'nightly-rpm-non-rpm': {}, 'nightly-deb-non-deb': {}},
- 'schedulerNames_nowait' : {'nightly-uclibc':{}, 'build-appliance': {},
- 'eclipse-plugin-neon': {},
- 'eclipse-plugin-oxygen': {},
- 'nightly-non-gpl3': {}, 'nightly-oecore': {},
- 'nightly-world':{},'nightly-wic':{},
- 'nightly-world-lsb':{},
- 'poky-tiny': {}, 'buildtools': {},
- 'nightly-musl': {}, 'nightly-no-x11': {},
- 'nightly-musl-x86-64': {},
- 'nightly-qa-extras': {}, 'nightly-oe-selftest': {}
- }}},
- {'PrepPkgIndex' : {}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'atom-pc', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemuarm64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'beaglebone-yocto', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemumips64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'routerstationpro', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'mpc8315e-rdb', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'adtdev':True}},
- {'BuildImages': {'images': 'package-index'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'BuildImages': {'images': 'adt-installer'}},
- {'PublishArtifacts': {'artifacts': ['adt-installer']}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'adtdev':True}},
- {'BuildImages': {'images': 'adt-installer'}},
- {'PublishArtifacts': {'artifacts': ['adt-installer-QA', 'adtrepo-dev']}},
- {'BitbakeSelftest': {}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'TriggerBuilds': {'schedulerName': 'buildhistory',
- 'waitForFinish': 'False',
- 'schedulerNames': {},
- 'schedulerNames_nowait' : {'update-buildhistory': {}}}},
- {'SendQAEmail': {}},
- {'CreateCurrentLink' : {}}]
diff --git a/buildset-config.controller/poky-tiny.conf b/buildset-config.controller/poky-tiny.conf
deleted file mode 100644
index 1ddbf6fb..00000000
--- a/buildset-config.controller/poky-tiny.conf
+++ /dev/null
@@ -1,18 +0,0 @@
-[poky-tiny]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky-tiny'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'PublishArtifacts': {'artifacts': ['tiny', 'md5sums']}}]
-
diff --git a/buildset-config.controller/update-buildhistory.conf b/buildset-config.controller/update-buildhistory.conf
deleted file mode 100644
index 66023e31..00000000
--- a/buildset-config.controller/update-buildhistory.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-[update-buildhistory]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-steps: [{'UpdateBuildHistory': {'machines': ['nightly-arm', 'nightly-arm64',
- 'nightly-arm-lsb', 'nightly-mips',
- 'nightly-mips-lsb', 'nightly-ppc',
- 'nightly-ppc-lsb', 'nightly-x86',
- 'nightly-x86-64', 'nightly-x86-64-lsb',
- 'nightly-x86-lsb']}}]
-
diff --git a/buildset-config.controller/yoctoAB.conf b/buildset-config.controller/yoctoAB.conf
deleted file mode 100644
index 515294d5..00000000
--- a/buildset-config.controller/yoctoAB.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-[BuildSets]
-order: ['nightly', 'eclipse-plugin-neon', 'eclipse-plugin-oxygen',
- 'nightly-arm', 'nightly-arm64', 'nightly-arm-lsb',
- 'nightly-mips', 'nightly-mips64', 'nightly-mips-lsb',
- 'nightly-ppc', 'nightly-ppc-lsb', 'nightly-no-x11',
- 'nightly-x86-64', 'nightly-x86-64-lsb', 'nightly-x86',
- 'nightly-x86-lsb', 'nightly-x32', 'nightly-multilib',
- 'nightly-musl', 'nightly-musl-x86-64',
- 'nightly-world', 'nightly-world-lsb', 'nightly-non-gpl3',
- 'nightly-oecore', 'nightly-wic', 'poky-tiny',
- 'build-appliance', 'nightly-qa-extras',
- 'nightly-packagemanagers']
diff --git a/buildset-config.examples/awesomefirmware.conf b/buildset-config.examples/awesomefirmware.conf
deleted file mode 100644
index 7f510273..00000000
--- a/buildset-config.examples/awesomefirmware.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-[awesomefirmware]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'branch':'master'}}]
-props: [{'release_tarball':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'release_tarball',
- 'label':'<h3> Generate a source tarball for release?:</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'genericx86-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky',
- 'atextappend': 'INHERIT += "archiver"\n\
- ARCHIVER_MODE[src] = "patched"\n\
- ARCHIVER_MODE[diff] = "1"\n\
- ARCHIVER_MODE[dumpdata] = "1"\n\
- ARCHIVER_MODE[srpm] = "1"\n\
- COPYLEFT_LICENSE_INCLUDE = "GPL* LGPL*"\n\
- COPYLEFT_LICENSE_EXCLUDE = "CLOSED Proprietary"\n\
- COPYLEFT_RECIPE_TYPES = "target"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-minimal'}},
- {'CreateGPLTarball': {}},
- {'PublishArtifacts': {'artifacts': ['genericx86-64']}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'SendQAEmail': {}},
- {'CreateCurrentLink' : {}}]
diff --git a/buildset-config.examples/gitpoller.conf b/buildset-config.examples/gitpoller.conf
deleted file mode 100644
index 12fe4da4..00000000
--- a/buildset-config.examples/gitpoller.conf
+++ /dev/null
@@ -1,33 +0,0 @@
-[git-poller]
-builders: 'example-worker'
-repos: [{'poky-contrib':
- {'repourl':'git://git.yoctoproject.org/poky-contrib',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'tgraydon/poky'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/poky-contrib',
- 'branch':'tgraydon/meta-qt3'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['qemux86', 'atom-pc']}}]
-scheduler: [{'git-poller-scheduler':
- {'type':'SingleBranchScheduler',
- 'changesource':'GitPoller',
- 'repository':'poky-contrib',
- 'branch':'tgraydon/poky',
- 'interval':'3600,
- 'stable-timer':300}}]
-scheduler: [{'git-poller-scheduler':
- {'type':'SingleBranchScheduler',
- 'changesource':'GitPoller',
- 'repository':'poky-contrib',
- 'branch':'tgraydon/meta-qt3',
- 'interval':'3600,
- 'stable-timer':300}}]
diff --git a/buildset-config.examples/hello.conf b/buildset-config.examples/hello.conf
deleted file mode 100644
index b38185cc..00000000
--- a/buildset-config.examples/hello.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-[hello]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'firstname':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'firstname',
- 'label':'<h3> firstname:</h3>'}},
- {'lastname':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'lastname',
- 'label':'<h3> lastname:</h3>'}}]
-steps: [{'HelloWorld':{'firstname':'foo', 'lastname':'bar'}},
- {'HelloWorld':{}}]
diff --git a/buildset-config.examples/webhobbish.conf b/buildset-config.examples/webhobbish.conf
deleted file mode 100644
index 77b3511f..00000000
--- a/buildset-config.examples/webhobbish.conf
+++ /dev/null
@@ -1,48 +0,0 @@
-[webhobbish]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'bbpriority':'1',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'bbpriority':'2',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'bbpriority':'2',
- 'branch':'master'}}]
-props: [ {'email':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'email',
- 'label':'<h3> Email alert when complete:</h3>'}},
- {'machine':{'prop_type':'ChoiceStringParameter',
- 'default': 'qemux86',
- 'choices' : ['qemux86', 'qemuarm', 'qemumips',
- 'qemuppc', 'qemux86-64', 'beaglebone-yocto',
- 'atom-pc', 'routerstationpro', 'mpc8315e-rdb'],
- 'name': 'machine',
- 'required': True,
- 'label':'<h3> Machine:</h3>'}},
- {'image':{'prop_type':'ChoiceStringParameter',
- 'default': 'core-image-minimal',
- 'choices' : ['core-image-base', 'core-image-minimal',
- 'core-image-minimal-dev',
- 'core-image-minimal-initramfs',
- 'core-image-minimal-mtdutils',
- 'core-image-rt-sdk', 'core-image-rt',
- 'core-image-directfb', 'core-image-x11',
- 'core-image-clutter', 'core-image-sato-sdk',
- 'core-image-sato', 'core-image-sato-dev',
- 'core-image-lsb', 'core-image-lsb-sdk',
- 'core-image-basic', 'core-image-lsb-dev'],
- 'name': 'image',
- 'required': True,
- 'label':'<h3> Image Type:</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky',
- 'atextprepend': 'SOURCE_MIRROR_FETCH = "1"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'universe -c fetch'}}]
diff --git a/buildset-config.freescale/nightly-fsl-arm-lsb.conf b/buildset-config.freescale/nightly-fsl-arm-lsb.conf
deleted file mode 100644
index 83bb1108..00000000
--- a/buildset-config.freescale/nightly-fsl-arm-lsb.conf
+++ /dev/null
@@ -1,41 +0,0 @@
-[nightly-fsl-arm-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-fsl-arm':
- {'repourl':'git://git.yoctoproject.org/meta-fsl-arm',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'imx53qsb', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer' : True, 'bspprovider' : 'fsl-arm'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'CreateAutoConf': {'machine': 'imx6qsabresd', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky-lsb', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'CreateAutoConf': {'machine': 'imx28evk', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky-lsb', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['imx53qsb', 'imx6qsabresd', 'imx28evk', 'md5sums']}}]
diff --git a/buildset-config.freescale/nightly-fsl-arm.conf b/buildset-config.freescale/nightly-fsl-arm.conf
deleted file mode 100644
index ae99fb28..00000000
--- a/buildset-config.freescale/nightly-fsl-arm.conf
+++ /dev/null
@@ -1,46 +0,0 @@
-[nightly-fsl-arm]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-fsl-arm':
- {'repourl':'git://git.yoctoproject.org/meta-fsl-arm',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'imx53qsb', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer' : True, 'bspprovider' : 'fsl-arm'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'CreateAutoConf': {'machine': 'imx53qsb', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildToolchainImages': {}},
- {'CreateAutoConf': {'machine': 'imx53qsb', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'imx6qsabresd', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'CreateAutoConf': {'machine': 'imx28evk', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['imx53qsb', 'imx6qsabresd', 'imx28evk', 'ipk', 'toolchain', 'md5sums']}}]
diff --git a/buildset-config.freescale/nightly-fsl-ppc-lsb.conf b/buildset-config.freescale/nightly-fsl-ppc-lsb.conf
deleted file mode 100644
index 5db62cdd..00000000
--- a/buildset-config.freescale/nightly-fsl-ppc-lsb.conf
+++ /dev/null
@@ -1,32 +0,0 @@
-[nightly-fsl-ppc-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-fsl-ppc':
- {'repourl':'git://git.yoctoproject.org/meta-fsl-ppc',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'p1022ds', 'SDKMACHINE' : 'i686',
- 'distro': 'poky-lsb', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer' : True, 'bspprovider' : 'fsl-ppc'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['p1022ds', 'md5sums']}}]
-
diff --git a/buildset-config.freescale/nightly-fsl-ppc.conf b/buildset-config.freescale/nightly-fsl-ppc.conf
deleted file mode 100644
index ba4250c8..00000000
--- a/buildset-config.freescale/nightly-fsl-ppc.conf
+++ /dev/null
@@ -1,33 +0,0 @@
-[nightly-fsl-ppc]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-fsl-ppc':
- {'repourl':'git://git.yoctoproject.org/meta-fsl-ppc',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'p1022ds', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer' : True, 'bspprovider' : 'fsl-ppc'}},
- {'GetBitbakeVersion': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev'}},
- {'BuildToolchainImages': {}},
- {'CreateAutoConf': {'machine': 'p1022ds', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky', 'buildhistory' : False,
- 'atextprepend': 'ACCEPT_FSL_EULA = "1"\n',
- 'devkernel' : False}},
- {'BuildToolchainImages': {}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['p1022ds', 'ipk', 'toolchain', 'md5sums']}}]
-
diff --git a/buildset-config.iot-devkit/iot-devkit.conf b/buildset-config.iot-devkit/iot-devkit.conf
deleted file mode 100644
index 795c805a..00000000
--- a/buildset-config.iot-devkit/iot-devkit.conf
+++ /dev/null
@@ -1,34 +0,0 @@
-[iot-devkit]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yocto':'meta-yocto', 'poky':'meta-poky', 'yoctobsp':'meta-yocto-bsp'},
- 'branch':'dizzy'}},
- {'meta-intel-iot-devkit':
- {'repourl':'git://git.yoctoproject.org/meta-intel-iot-devkit',
- 'branch':'master'}},
- {'meta-intel-iot-middleware':
- {'repourl':'git://git.yoctoproject.org/meta-intel-iot-middleware',
- 'branch':'dizzy'}},
- {'meta-intel-quark':
- {'repourl':'git://git.yoctoproject.org/meta-intel-quark',
- 'branch':'dizzy'}},
- {'meta-intel-galileo':
- {'repourl':'git://git.yoctoproject.org/meta-intel-galileo',
- 'branch':'dizzy'}},
- {'meta-openembedded':
- {'repourl':'git://git.openembedded.org/meta-openembedded',
- 'branch':'dizzy'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'quark', 'SDKMACHINE' : 'x86_64', 'distro': 'iot-devkit-multilibc'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-yocto', 'meta-intel-iot-devkit',
- 'meta-intel-iot-middleware', 'meta-intel-quark', 'meta-intel-galileo', 'meta-openembedded/meta-oe',
- 'meta-openembedded/meta-filesystems']}},
- {'BuildImages': {'images': 'iot-devkit-image iot-devkit-prof-image iot-devkit-prof-dev-image'}},
- {'PublishLayerTarballs':{}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'PublishArtifacts': {'artifacts': ['quark', 'ipk', 'md5sums']}}]
diff --git a/buildset-config.iot-devkit/yoctoAB.conf b/buildset-config.iot-devkit/yoctoAB.conf
deleted file mode 100644
index 0c0cf334..00000000
--- a/buildset-config.iot-devkit/yoctoAB.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[BuildSets]
-order: ['iot-devkit']
diff --git a/buildset-config.kernel/kernel-arm-lsb.conf b/buildset-config.kernel/kernel-arm-lsb.conf
deleted file mode 100644
index 5a1d5765..00000000
--- a/buildset-config.kernel/kernel-arm-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[kernel-arm-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-arm.conf b/buildset-config.kernel/kernel-arm.conf
deleted file mode 100644
index c9ebcf4c..00000000
--- a/buildset-config.kernel/kernel-arm.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[kernel-arm]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-arm64.conf b/buildset-config.kernel/kernel-arm64.conf
deleted file mode 100644
index f05f8e3e..00000000
--- a/buildset-config.kernel/kernel-arm64.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[kernel-arm64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuarm64', 'SDKMACHINE' :'i686', 'distro': 'poky', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-mips-lsb.conf b/buildset-config.kernel/kernel-mips-lsb.conf
deleted file mode 100644
index c34879f1..00000000
--- a/buildset-config.kernel/kernel-mips-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[kernel-mips-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-mips.conf b/buildset-config.kernel/kernel-mips.conf
deleted file mode 100644
index 236e8791..00000000
--- a/buildset-config.kernel/kernel-mips.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[kernel-mips]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-ppc-lsb.conf b/buildset-config.kernel/kernel-ppc-lsb.conf
deleted file mode 100644
index 3bdc8901..00000000
--- a/buildset-config.kernel/kernel-ppc-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[kernel-ppc-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-ppc.conf b/buildset-config.kernel/kernel-ppc.conf
deleted file mode 100644
index 45b341fa..00000000
--- a/buildset-config.kernel/kernel-ppc.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[kernel-ppc]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-x86-64-lsb.conf b/buildset-config.kernel/kernel-x86-64-lsb.conf
deleted file mode 100644
index 944367db..00000000
--- a/buildset-config.kernel/kernel-x86-64-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[kernel-x86-64-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-x86-64.conf b/buildset-config.kernel/kernel-x86-64.conf
deleted file mode 100644
index a52d5b45..00000000
--- a/buildset-config.kernel/kernel-x86-64.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[kernel-x86-64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-x86-lsb.conf b/buildset-config.kernel/kernel-x86-lsb.conf
deleted file mode 100644
index 0d730144..00000000
--- a/buildset-config.kernel/kernel-x86-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[kernel-x86-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'buildhistory' : False, 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel="linux-yocto-dev"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/kernel-x86.conf b/buildset-config.kernel/kernel-x86.conf
deleted file mode 100644
index 146e9a42..00000000
--- a/buildset-config.kernel/kernel-x86.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[kernel-x86]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'buildhistory' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-kernel-dev'}},
- {'RunSanityTests': {'images': 'core-image-kernel-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.kernel/nightly-kernel.conf b/buildset-config.kernel/nightly-kernel.conf
deleted file mode 100644
index 981f7d8d..00000000
--- a/buildset-config.kernel/nightly-kernel.conf
+++ /dev/null
@@ -1,63 +0,0 @@
-[nightly-kernel]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky',
- 'atextprepend': 'SOURCE_MIRROR_FETCH = "1"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'universe -c fetch'}},
- {'TriggerBuilds': {'schedulerName': 'main-build', 'waitForFinish': 'True',
- 'copy_properties': ['custom_kmeta', 'custom_kbranch',
- 'custom_srcrev_meta', 'custom_srcuri_meta',
- 'custom_srcrev_machine', 'custom_srcuri_machine'],
- 'schedulerNames': {'kernel-arm': {}, 'kernel-arm-lsb': {},
- 'kernel-mips': {}, 'kernel-mips-lsb': {},
- 'kernel-ppc': {}, 'kernel-ppc-lsb': {},
- 'kernel-x86-64': {}, 'kernel-x86-64-lsb': {},
- 'kernel-x86': {}, 'kernel-x86-lsb': {}, 'kernel-arm64': {}},
- 'schedulerNames_nowait' : {}}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'SendQAEmail': {}}]
diff --git a/buildset-config.kernel/yoctoAB.conf b/buildset-config.kernel/yoctoAB.conf
deleted file mode 100644
index c5636d08..00000000
--- a/buildset-config.kernel/yoctoAB.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-[BuildSets]
-order: ['nightly-kernel', 'kernel-arm', 'kernel-arm-lsb', 'kernel-mips',
- 'kernel-mips-lsb', 'kernel-ppc', 'kernel-ppc-lsb',
- 'kernel-x86-64', 'kernel-x86-64-lsb', 'kernel-x86',
- 'kernel-x86-lsb']
diff --git a/buildset-config.meta-intel-isg/crystalforest-lsb.conf b/buildset-config.meta-intel-isg/crystalforest-lsb.conf
deleted file mode 100644
index 34cc65dc..00000000
--- a/buildset-config.meta-intel-isg/crystalforest-lsb.conf
+++ /dev/null
@@ -1,31 +0,0 @@
-[crystalforest-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'bbpriority':'1',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'bbpriority':'1',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'bbpriority':'2',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'crystalforest-server', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel', 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'BuildImages': {'images': 'core-image-lsb LSB-QT-IMAGES'}},
- {'CreateAutoConf': {'machine': 'crystalforest-gladden', 'SDKMACHINE' : 'i686', 'distro': 'poky-lsb', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel', 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'BuildImages': {'images': 'core-image-lsb LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'crystalforest-server', 'crystalforest-gladden']}}]
-
diff --git a/buildset-config.meta-intel-isg/crystalforest.conf b/buildset-config.meta-intel-isg/crystalforest.conf
deleted file mode 100644
index 729e6a39..00000000
--- a/buildset-config.meta-intel-isg/crystalforest.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[crystalforest]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'bbpriority':'1',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'bbpriority':'2',
- 'branch':'master'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'crystalforest-server', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'CreateAutoConf': {'machine': 'crystalforest-gladden', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel'}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'crystalforest-server', 'crystalforest-gladden']}}]
-
diff --git a/buildset-config.meta-intel-isg/nightly-isg.conf b/buildset-config.meta-intel-isg/nightly-isg.conf
deleted file mode 100644
index 79ae7348..00000000
--- a/buildset-config.meta-intel-isg/nightly-isg.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-[nightly-isg]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'branch':'master'}}]
-props: [{'release_me':{'prop_type':'BooleanParameter',
- 'default': False,
- 'name': 'release_me',
- 'required': True,
- 'label':'<h3> Generate a release?:</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'TriggerBuilds': {'schedulerName': 'main-build', 'waitForFinish': 'True',
- 'schedulerNames': {'crystalforest':{}, 'crystalforest-lsb':{}},
- 'schedulerNames_nowait' : {}
- }},
- {'CreateIntelBSPPackage': {'machine': 'crystalforest'}},
- {'CreateIntelBSPPackage': {'machine': 'crystalforest-lsb'}},
- {'CreateCurrentLink' : {}}
- ]
diff --git a/buildset-config.meta-intel-isg/yoctoAB.conf b/buildset-config.meta-intel-isg/yoctoAB.conf
deleted file mode 100644
index f4326d95..00000000
--- a/buildset-config.meta-intel-isg/yoctoAB.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[BuildSets]
-order: ['nightly-isg', 'crystalforest', 'crystalforest-lsb']
diff --git a/buildset-config.meta-intel/intel-core2-32-lsb-rt.conf b/buildset-config.meta-intel/intel-core2-32-lsb-rt.conf
deleted file mode 100644
index a31d624e..00000000
--- a/buildset-config.meta-intel/intel-core2-32-lsb-rt.conf
+++ /dev/null
@@ -1,64 +0,0 @@
-[intel-core2-32-lsb-rt]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky-lsb'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'CreateAutoConf': {'machine': 'intel-core2-32',
- 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky-lsb',
- 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel_linuxstdbase = "linux-intel-rt"\n'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-rt'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-core2-32']}}]
-
diff --git a/buildset-config.meta-intel/intel-core2-32-lsb.conf b/buildset-config.meta-intel/intel-core2-32-lsb.conf
deleted file mode 100644
index 1aba3971..00000000
--- a/buildset-config.meta-intel/intel-core2-32-lsb.conf
+++ /dev/null
@@ -1,60 +0,0 @@
-[intel-core2-32-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky-lsb'}},
- {'CreateAutoConf': {'machine': 'intel-core2-32', 'SDKMACHINE' : 'x86_64', 'distro': 'poky-lsb'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-core2-32']}}]
diff --git a/buildset-config.meta-intel/intel-core2-32-rt.conf b/buildset-config.meta-intel/intel-core2-32-rt.conf
deleted file mode 100644
index df04d980..00000000
--- a/buildset-config.meta-intel/intel-core2-32-rt.conf
+++ /dev/null
@@ -1,57 +0,0 @@
-[intel-core2-32-rt]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'CreateAutoConf': {'machine': 'intel-core2-32',
- 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky',
- 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel = "linux-intel-rt"\n'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-rt'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-core2-32']}}]
-
diff --git a/buildset-config.meta-intel/intel-core2-32.conf b/buildset-config.meta-intel/intel-core2-32.conf
deleted file mode 100644
index a5849722..00000000
--- a/buildset-config.meta-intel/intel-core2-32.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[intel-core2-32]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-core2-32', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'intel-core2-32', 'SDKMACHINE' : 'i686', 'distro': 'poky'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-core2-32']}}]
diff --git a/buildset-config.meta-intel/intel-corei7-64-lsb-rt.conf b/buildset-config.meta-intel/intel-corei7-64-lsb-rt.conf
deleted file mode 100644
index 76e0f9f1..00000000
--- a/buildset-config.meta-intel/intel-corei7-64-lsb-rt.conf
+++ /dev/null
@@ -1,62 +0,0 @@
-[intel-corei7-64-lsb-rt]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64',
- 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky-lsb',
- 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel_linuxstdbase = "linux-intel-rt"\n'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-rt'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-corei7-64']}}]
diff --git a/buildset-config.meta-intel/intel-corei7-64-lsb.conf b/buildset-config.meta-intel/intel-corei7-64-lsb.conf
deleted file mode 100644
index 60dda30a..00000000
--- a/buildset-config.meta-intel/intel-corei7-64-lsb.conf
+++ /dev/null
@@ -1,60 +0,0 @@
-[intel-corei7-64-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky-lsb'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-corei7-64']}}]
diff --git a/buildset-config.meta-intel/intel-corei7-64-rt.conf b/buildset-config.meta-intel/intel-corei7-64-rt.conf
deleted file mode 100644
index f80666c8..00000000
--- a/buildset-config.meta-intel/intel-corei7-64-rt.conf
+++ /dev/null
@@ -1,56 +0,0 @@
-[intel-corei7-64-rt]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64',
- 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky',
- 'atextappend' : '\nPREFERRED_PROVIDER_virtual/kernel = "linux-intel-rt"\n'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-rt'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-corei7-64']}}]
diff --git a/buildset-config.meta-intel/intel-corei7-64.conf b/buildset-config.meta-intel/intel-corei7-64.conf
deleted file mode 100644
index 6337cefa..00000000
--- a/buildset-config.meta-intel/intel-corei7-64.conf
+++ /dev/null
@@ -1,59 +0,0 @@
-[intel-corei7-64]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-corei7-64']}}]
diff --git a/buildset-config.meta-intel/intel-quark.conf b/buildset-config.meta-intel/intel-quark.conf
deleted file mode 100644
index 931ead0e..00000000
--- a/buildset-config.meta-intel/intel-quark.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[intel-quark]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-quark', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'BuildImages': {'images': '-c populate_sdk_ext core-image-minimal'}},
- {'CreateAutoConf': {'machine': 'intel-quark', 'SDKMACHINE' : 'i686', 'distro': 'poky'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'intel-quark']}}]
diff --git a/buildset-config.meta-intel/jasperforest-lsb.conf b/buildset-config.meta-intel/jasperforest-lsb.conf
deleted file mode 100644
index 5344f28a..00000000
--- a/buildset-config.meta-intel/jasperforest-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[jasperforest-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'jasperforest', 'SDKMACHINE' : 'x86_64', 'distro': 'poky-lsb', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel','layerdirs': ['meta-intel', 'meta-intel/meta-jasperforest', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'jasperforest']}}]
-
diff --git a/buildset-config.meta-intel/jasperforest.conf b/buildset-config.meta-intel/jasperforest.conf
deleted file mode 100644
index 64833dad..00000000
--- a/buildset-config.meta-intel/jasperforest.conf
+++ /dev/null
@@ -1,51 +0,0 @@
-[jasperforest]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'jasperforest', 'SDKMACHINE' : 'x86_64', 'distro': 'poky', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'jasperforest']}}]
diff --git a/buildset-config.meta-intel/nightly-meta-intel-world.conf b/buildset-config.meta-intel/nightly-meta-intel-world.conf
deleted file mode 100644
index 654c4f98..00000000
--- a/buildset-config.meta-intel/nightly-meta-intel-world.conf
+++ /dev/null
@@ -1,55 +0,0 @@
-[nightly-meta-intel-world]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-core2-32', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'emgd': 'False', 'pvr': 'False',
- 'buildhistory' : 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk'], 'bsplayer': True, 'bspprovider': 'intel'}},
- {'BuildImages': {'images': 'world'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'emgd': 'False', 'pvr': 'False',
- 'buildhistory' : 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk'], 'bsplayer': True, 'bspprovider': 'intel'}},
- {'BuildImages': {'images': 'world'}}]
diff --git a/buildset-config.meta-intel/nightly-meta-intel.conf b/buildset-config.meta-intel/nightly-meta-intel.conf
deleted file mode 100644
index dc654894..00000000
--- a/buildset-config.meta-intel/nightly-meta-intel.conf
+++ /dev/null
@@ -1,106 +0,0 @@
-[nightly-meta-intel]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'release_me':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'release_me',
- 'label':'<h3> Generate a release?:</h3>'}},
- {'poky_name':{'prop_type':'ChoiceStringParameter',
- 'choices': ['', 'pyro', 'morty', 'krogoth', 'jethro', 'fido'],
- 'name': 'poky_name',
- 'label':'<h3> Name of the poky release.<br>For further info on release names see <a href="https://wiki.yoctoproject.org/wiki/Releases"> Releases </a> </h3>'}},
- {'is_milestone':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'is_milestone',
- 'label':'<h3> If this a milestone release? If so the poky number and poky name will be appended with a "+snapshot"</h3>'}},
- {'poky_number':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'poky_number',
- 'label':'<h3> Poky Release Number (10.0.0, 11.0.1 etc.):</h3>'}},
- {'yocto_number':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'yocto_number',
- 'label':'<h3> Yocto Project Release Number (1.5, 1.6 etc.):</h3>'}},
- {'milestone_number':{'prop_type':'ChoiceStringParameter',
- 'choices': ['', 'M1', 'M2', 'M3', 'M4'],
- 'name': 'milestone_number',
- 'label':'<h3> Milestone number: </h3>'}},
- {'rc_number':{'prop_type':'ChoiceStringParameter',
- 'choices': ['', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6', 'rc7', 'rc8', 'rc9'],
- 'name': 'rc_number',
- 'label':'<h3> Release candidate number: </h3>'}},
- {'send_email':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'send_email',
- 'label':'<h3> Send QA alert emails?:</h3>'}},
- {'deploy_artifacts':{'prop_type':'ChoiceStringParameter',
- 'choices': ['True', 'False'],
- 'name': 'deploy_artifacts',
- 'label':'<hr><h3> Do we want to deploy artifacts? </br>This speeds up autobuilder time and saves space on the cluster:</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': '',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is blank):</h3>'}},
- {'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckYoctoCompat': {'layers': ['meta-intel']}},
- {'TriggerBuilds': {'copy_properties': ['custom_deploy_artifacts', 'custom_prefered_kernel', 'custom_kmeta', 'custom_kbranch', 'custom_srcrev_meta', 'custom_srcrev_machine', 'custom_srcuri_meta', 'custom_srcuri_machine'],
- 'schedulerName': 'main-build', 'waitForFinish': 'True',
- 'schedulerNames': {'intel-core2-32':{}, 'intel-core2-32-lsb':{},
- 'intel-core2-32-lsb-rt':{}, 'intel-core2-32-rt':{},
- 'intel-corei7-64':{}, 'intel-corei7-64-lsb':{},
- 'intel-corei7-64-lsb-rt':{}, 'intel-corei7-64-rt':{},
- 'intel-quark':{}, 'nightly-musl':{},
- 'nightly-musl-core2-32':{}, 'nightly-x32':{}},
- 'schedulerNames_nowait' : {'nightly-meta-intel-world':{}}}},
- {'CreateIntelBSPPackage': {'machine': 'intel-core2-32'}},
- {'CreateIntelBSPPackage': {'machine': 'intel-corei7-64'}},
- {'CreateIntelBSPPackage': {'machine': 'intel-quark'}},
- {'SendQAEmail': {}},
- {'CreateCurrentLink' : {}}]
diff --git a/buildset-config.meta-intel/nightly-musl-core2-32.conf b/buildset-config.meta-intel/nightly-musl-core2-32.conf
deleted file mode 100644
index e83d03c4..00000000
--- a/buildset-config.meta-intel/nightly-musl-core2-32.conf
+++ /dev/null
@@ -1,53 +0,0 @@
-[nightly-musl-core2-32]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-core2-32', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nTCLIBC="musl"\n' }},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'BuildImages': {'images': 'core-image-minimal core-image-full-cmdline core-image-sato world'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.meta-intel/nightly-musl.conf b/buildset-config.meta-intel/nightly-musl.conf
deleted file mode 100644
index 7687825d..00000000
--- a/buildset-config.meta-intel/nightly-musl.conf
+++ /dev/null
@@ -1,53 +0,0 @@
-[nightly-musl]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'distro': 'poky',
- 'atextappend' : '\nTCLIBC="musl"\n' }},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'BuildImages': {'images': 'core-image-minimal core-image-full-cmdline core-image-sato world'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}]
diff --git a/buildset-config.meta-intel/nightly-x32.conf b/buildset-config.meta-intel/nightly-x32.conf
deleted file mode 100644
index 47e65976..00000000
--- a/buildset-config.meta-intel/nightly-x32.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[nightly-x32]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is blank):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is blank):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'GetBitbakeVersion': {}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'x86_64',
- 'buildhistory' : False, 'x32': True,
- 'distro': 'poky',
- 'atextappend' : '\nrequire conf/multilib.conf\nMULTILIBS = "multilib:libx32"\nDEFAULTTUNE_virtclass-multilib-libx32 = "corei7-64-x32"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'PublishLayerTarballs':{}},
- {'BuildImages': {'images': 'core-image-minimal core-image-sato'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'UploadToasterEventlog': {}},
- {'PublishArtifacts': {'artifacts': ['md5sums']}}]
diff --git a/buildset-config.meta-intel/nuc-lsb.conf b/buildset-config.meta-intel/nuc-lsb.conf
deleted file mode 100644
index 641191f9..00000000
--- a/buildset-config.meta-intel/nuc-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[nuc-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'nuc', 'SDKMACHINE' : 'x86_64', 'distro': 'poky-lsb', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel','layerdirs': ['meta-intel', 'meta-intel/meta-nuc', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'nuc']}}]
-
diff --git a/buildset-config.meta-intel/nuc.conf b/buildset-config.meta-intel/nuc.conf
deleted file mode 100644
index 1506b56a..00000000
--- a/buildset-config.meta-intel/nuc.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[nuc]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'nuc', 'SDKMACHINE' : 'x86_64', 'distro': 'poky', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'nuc']}}]
-
diff --git a/buildset-config.meta-intel/sugarbay-lsb.conf b/buildset-config.meta-intel/sugarbay-lsb.conf
deleted file mode 100644
index d199b7a5..00000000
--- a/buildset-config.meta-intel/sugarbay-lsb.conf
+++ /dev/null
@@ -1,58 +0,0 @@
-[sugarbay-lsb]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'sugarbay', 'SDKMACHINE' : 'x86_64', 'distro': 'poky-lsb', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel','layerdirs': ['meta-intel', 'meta-intel/meta-sugarbay', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-lsb core-image-lsb-dev core-image-lsb-sdk LSB-QT-IMAGES'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'sugarbay']}}]
-
diff --git a/buildset-config.meta-intel/sugarbay.conf b/buildset-config.meta-intel/sugarbay.conf
deleted file mode 100644
index 9dd3ee0f..00000000
--- a/buildset-config.meta-intel/sugarbay.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[sugarbay]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'sugarbay', 'SDKMACHINE' : 'i686', 'distro': 'poky', 'emgd': 'False', 'pvr': 'False'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'bsplayer': True, 'bspprovider': 'intel'}},
- {'AddKernelProps': {}},
- {'BuildImages': {'images': 'core-image-sato core-image-sato-sdk core-image-minimal core-image-sato-sdk-ptest'}},
- {'PublishLayerTarballs':{}},
- {'PublishArtifacts': {'artifacts': ['conf', 'sugarbay']}}]
-
diff --git a/buildset-config.meta-intel/yoctoAB.conf b/buildset-config.meta-intel/yoctoAB.conf
deleted file mode 100644
index 646fd90f..00000000
--- a/buildset-config.meta-intel/yoctoAB.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-[BuildSets]
-order: ['nightly-meta-intel', 'nightly-meta-intel-world', 'nightly-musl',
- 'nightly-musl-core2-32', 'nightly-x32', 'intel-corei7-64',
- 'intel-corei7-64-lsb', 'intel-corei7-64-rt', 'intel-corei7-64-lsb-rt',
- 'intel-core2-32', 'intel-core2-32-rt', 'intel-core2-32-lsb-rt', 'intel-quark']
diff --git a/buildset-config.tizen/nightly-tizen-ivi.conf b/buildset-config.tizen/nightly-tizen-ivi.conf
deleted file mode 100644
index f1735a68..00000000
--- a/buildset-config.tizen/nightly-tizen-ivi.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[nightly-tizen-ivi]
-builders: 'example-worker'
-repos: [{'oecoreivi':
- {'repourl':'git://review.tizen.org/scm/bb/tizen-distro',
- 'layerversion':{'core':'meta'},
- 'branch':'tizen-ivi'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {'altcmd':'tizen-ivi-init-build-env'}},
- {'GetDistroVersion' : {'distro': 'oecore'}},
- {'CreateAutoConf': {'machine': 'genericx86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'oecore', 'packages': 'rpm',
- 'buildhistory' : True}},
- {'CreateBBLayersConf': {'buildprovider' : 'oe',
- 'layerdirs': ['meta-openembedded/meta-oe', 'meta-openembedded/meta-multimedia', \
- 'meta-openembedded/meta-ruby', 'meta-openembedded/meta-systemd', \
- 'meta-openembedded/meta-gnome', 'meta-tizen/meta-tizen-adaptation/meta', \
- 'meta-tizen/meta-tizen-adaptation/meta-oe', 'meta-tizen/meta-tizen-common-base', \
- 'meta-tizen/meta-tizen-common-share', 'meta-tizen/meta-tizen-common-devtools', \
- 'meta-tizen/meta-tizen-common-demo', 'meta-tizen/meta-tizen-ivi']}},
- {'BuildImages': {'images': 'tizen-ivi-Modello-image'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}
- ]
diff --git a/buildset-config.tizen/nightly-tizen.conf b/buildset-config.tizen/nightly-tizen.conf
deleted file mode 100644
index c969bb9d..00000000
--- a/buildset-config.tizen/nightly-tizen.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[nightly-tizen]
-builders: 'example-worker'
-repos: [{'oecore':
- {'repourl':'git://review.tizen.org/scm/bb/tizen-distro',
- 'layerversion':{'core':'meta'},
- 'branch':'tizen'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {'altcmd':'tizen-common-init-build-env'}},
- {'GetDistroVersion' : {'distro': 'oecore'}},
- {'CreateAutoConf': {'machine': 'genericx86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'oecore', 'buildhistory' : False}},
- {'CreateBBLayersConf': {'buildprovider' : 'oe',
- 'layerdirs': ['meta-openembedded/meta-oe', 'meta-openembedded/meta-multimedia', \
- 'meta-openembedded/meta-ruby', 'meta-openembedded/meta-systemd', \
- 'meta-openembedded/meta-gnome', 'meta-tizen/meta-tizen-adaptation/meta', \
- 'meta-tizen/meta-tizen-adaptation/meta-oe', 'meta-tizen/meta-tizen-common-base', \
- 'meta-tizen/meta-tizen-common-share', 'meta-tizen/meta-tizen-common-devtools', \
- 'meta-tizen/meta-tizen-common-demo']}},
- {'BuildImages': {'images': 'tizen-common-core-image-crosswalk-dev'}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}}
- ]
-
diff --git a/buildset-config.tizen/nightly.conf b/buildset-config.tizen/nightly.conf
deleted file mode 100644
index 3abefab1..00000000
--- a/buildset-config.tizen/nightly.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-[nightly]
-builders: 'example-worker'
-repos: [{'oecore':
- {'repourl':'git://review.tizen.org/scm/bb/tizen-distro',
- 'layerversion':{'core':'meta'},
- 'branch':'tizen'}},
- {'oecoreivi':
- {'repourl':'git://review.tizen.org/scm/bb/tizen-distro',
- 'layerversion':{'core':'meta'},
- 'checkout':False,
- 'branch':'tizen-ivi'}}]
-props: [{'release_me':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'release_me',
- 'label':'<h3> Generate a release?:</h3>'}},
- {'poky_name':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'tizen_name',
- 'label':'<h3> Tizen Release Name:</h3>'}},
- {'poky_number':{'prop_type':'StringParameter',
- 'size': 10,
- 'name': 'tizen_number',
- 'label':'<h3> Tizen Release Number (10.0.0, 10.0.0+snapshot, 11.0.1 etc.):</h3>'}},
- {'send_email':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'send_email',
- 'label':'<h3> Send QA alert emails?:</h3>'}},
- {'prefered_kernel':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'prefered_kernel',
- 'default': 'linux-yocto',
- 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'oecore'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky',
- 'atextprepend': 'SOURCE_MIRROR_FETCH = "1"\n'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'BuildImages': {'images': 'universe -c fetch'}},
- {'TriggerBuilds': {'schedulerName': 'main-build', 'waitForFinish': 'True',
- 'schedulerNames': {'nightly-tizen-ivi': {}, 'nightly-tizen': {}},
- 'schedulerNames_nowait' : {}}},
- {'DownloadErrorReports': {}},
- {'SendErrorReport': {}},
- {'TriggerBuilds': {'schedulerName': 'buildhistory',
- 'waitForFinish': 'False',
- 'schedulerNames': {},
- 'schedulerNames_nowait' : {'update-buildhistory': {}}}},
- {'SendQAEmail': {}},
- {'CreateCurrentLink' : {}}]
diff --git a/buildset-config.tizen/update-buildhistory.conf b/buildset-config.tizen/update-buildhistory.conf
deleted file mode 100644
index 024eb57a..00000000
--- a/buildset-config.tizen/update-buildhistory.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-[update-buildhistory]
-builders: 'example-worker'
-repos: [{'oecore':
- {'repourl':'git://review.tizen.org/scm/bb/tizen-distro',
- 'layerversion':{'core':'meta'},
- 'branch':'tizen'}}]
-steps: [{'UpdateBuildHistory': {'machines': ['nightly-tizen', 'nightly-tizen-ivi']}}]
-
diff --git a/buildset-config.tizen/yoctoAB.conf b/buildset-config.tizen/yoctoAB.conf
deleted file mode 100644
index c76036cd..00000000
--- a/buildset-config.tizen/yoctoAB.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[BuildSets]
-order: ['nightly', 'nightly-tizen-ivi']
diff --git a/buildset-config.toaster/toaster-build.conf b/buildset-config.toaster/toaster-build.conf
deleted file mode 100644
index 09a03e23..00000000
--- a/buildset-config.toaster/toaster-build.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-[toaster-build]
-builders: 'example-worker'
-props: [{'atext':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'atext',
- 'default': '',
- 'label':'<hr><h3> auto.conf:</h3>'}},
- {'bbtext':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'bbtext',
- 'default': '',
- 'label':'<hr><h3> bblayers.conf:</h3>'}},
- {'images':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'images',
- 'default': '',
- 'label':'<hr><h3> images:</h3>'}},
- {'layers':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'layers',
- 'default': '',
- 'label':'<hr><h3> repo string (ast):</h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutToasterLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'atext' : '#TOASTER'}},
- {'CreateBBLayersConf': {'bbtext' : '#TOASTER'}},
- {'BuildImages': {'images': '#TOASTER'}}]
diff --git a/buildset-config.toaster/toaster-tests.conf b/buildset-config.toaster/toaster-tests.conf
deleted file mode 100644
index 8590c485..00000000
--- a/buildset-config.toaster/toaster-tests.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-[toaster-tests]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master' }}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'ToasterSetupVenv': {}},
- {'ToasterStart': {}},
- {'Sleep': {'time': '120'}},
- {'ToasterRunTests': {}},
- {'ToasterStop': {}},
- ]
diff --git a/buildset-config.toaster/yoctoAB.conf b/buildset-config.toaster/yoctoAB.conf
deleted file mode 100644
index 614e39cc..00000000
--- a/buildset-config.toaster/yoctoAB.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[BuildSets]
-order: ['toaster-tests']
diff --git a/buildset-config.yocto-qa/buildtools.conf b/buildset-config.yocto-qa/buildtools.conf
deleted file mode 120000
index 39febc4c..00000000
--- a/buildset-config.yocto-qa/buildtools.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/buildtools.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/eclipse-plugin-neon.conf b/buildset-config.yocto-qa/eclipse-plugin-neon.conf
deleted file mode 120000
index efe2a112..00000000
--- a/buildset-config.yocto-qa/eclipse-plugin-neon.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/eclipse-plugin-neon.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/intel-corei7-64-daft.conf b/buildset-config.yocto-qa/intel-corei7-64-daft.conf
deleted file mode 100644
index cb3bcdad..00000000
--- a/buildset-config.yocto-qa/intel-corei7-64-daft.conf
+++ /dev/null
@@ -1,59 +0,0 @@
-[intel-corei7-64-daft]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'meta-intel':
- {'repourl':'git://git.yoctoproject.org/meta-intel',
- 'layerversion':{'intel':'meta-intel'},
- 'branch':'master'}}]
-props: [{'kmeta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kmeta',
- 'default': '',
- 'label':'<hr><h3> branch for KMETA_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_meta':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_meta',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KMETA_${MACHINE} (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_meta':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_meta',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KMETA append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'kbranch':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'kbranch',
- 'default': '',
- 'label':'<hr><h3> branch for KBRANCH_${MACHINE} (default is blank):</h3>'}},
- {'srcrev_machine':{'prop_type':'StringParameter',
- 'size': 15,
- 'name': 'srcrev_machine',
- 'default': '${AUTOREV}',
- 'label':'<hr><h3> SRCREV for KBRANCH. (default is ${AUTOREV}):<br></h3>'}},
- {'srcuri_machine':{'prop_type':'StringParameter',
- 'size': 50,
- 'name': 'srcuri_machine',
- 'default': '',
- 'label':'<hr><h3> SRC_URI_pn-linux-yocto KBRANCH append. (default is blank).<br> This should be constructed as *just* the git uri portion of the string. <br>(git://git.yoctoproject.org/linux-yocto-3.19.git</h3>'}},
- {'dut':{'prop_type':'ChoiceStringParameter',
- 'choices': ['Minnowboard1'],
- 'name': 'dut',
- 'label':'<hr><h3>Selects DUT for flashing.<br></h3>'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'CheckBSPExists': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'intel-corei7-64', 'SDKMACHINE' : 'x86_64',
- 'distro': 'poky'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto',
- 'bsplayer': True, 'bspprovider': 'intel',
- 'layerdirs': ['meta-intel', 'meta-intel/meta-tlk']}},
- {'AddKernelProps': {}},
- {'DaftGetDevices': {}},
- {'BuildImages': {'images': 'core-image-sato'}},
- {'DaftFlash':{}},
- {'RunSanityTests': {'images': 'core-image-sato'}},]
diff --git a/buildset-config.yocto-qa/nightly-arm.conf b/buildset-config.yocto-qa/nightly-arm.conf
deleted file mode 120000
index 2b8c3c22..00000000
--- a/buildset-config.yocto-qa/nightly-arm.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-arm.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-multilib.conf b/buildset-config.yocto-qa/nightly-multilib.conf
deleted file mode 120000
index af3e7b7f..00000000
--- a/buildset-config.yocto-qa/nightly-multilib.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-multilib.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-oe-build-perf-test.conf b/buildset-config.yocto-qa/nightly-oe-build-perf-test.conf
deleted file mode 100644
index c88d3a8a..00000000
--- a/buildset-config.yocto-qa/nightly-oe-build-perf-test.conf
+++ /dev/null
@@ -1,27 +0,0 @@
-[nightly-oe-build-perf-test]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}}]
-props: [{'machine':{'prop_type':'ChoiceStringParameter',
- 'choices': ['qemux86', 'qemuarm', 'qemumips', 'qemuppc', 'qemux86-64', 'qemuarm64', 'qemumips64'],
- 'name': 'machine',
- 'label':'<hr>Selects machine for performance measurement.'}},
- {'create_eventlog':{'prop_type':'ChoiceStringParameter',
- 'choices': ['False', 'True'],
- 'name': 'create_eventlog',
- 'label':'<hr>Create Toaster event log as part of image creation?:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'GetDistroVersion' : {'distro': 'poky'}},
- {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'i686',
- 'distro': 'poky', 'buildhistory' : True,
- 'atextappend' : 'CONNECTIVITY_CHECK_URIS = ""'}},
- {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
- {'GetBitbakeVersion': {}},
- {'RunOeBuildPerfTest': {}},
- {'TarballOeBuildPerfTest': {}},
- {'SendOePerfEmail': {}},
- ]
diff --git a/buildset-config.yocto-qa/nightly-oe-selftest.conf b/buildset-config.yocto-qa/nightly-oe-selftest.conf
deleted file mode 120000
index 9dee6660..00000000
--- a/buildset-config.yocto-qa/nightly-oe-selftest.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-oe-selftest.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-oecore.conf b/buildset-config.yocto-qa/nightly-oecore.conf
deleted file mode 120000
index dbe1050b..00000000
--- a/buildset-config.yocto-qa/nightly-oecore.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-oecore.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-packagemanagers.conf b/buildset-config.yocto-qa/nightly-packagemanagers.conf
deleted file mode 120000
index 8e69fc04..00000000
--- a/buildset-config.yocto-qa/nightly-packagemanagers.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-packagemanagers.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-qa-distro.conf b/buildset-config.yocto-qa/nightly-qa-distro.conf
deleted file mode 100644
index 0d02d156..00000000
--- a/buildset-config.yocto-qa/nightly-qa-distro.conf
+++ /dev/null
@@ -1,49 +0,0 @@
-[nightly-qa-distro]
-builders: 'example-worker'
-repos: [{'poky':
- {'repourl':'git://git.yoctoproject.org/poky',
- 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp', 'yocto':'meta-yocto', 'poky':'meta-poky'},
- 'branch':'master'}},
- {'oecore':
- {'repourl':'git://git.openembedded.org/openembedded-core',
- 'layerversion':'core',
- 'checkout':False,
- 'branch':'master'}},
- {'bitbake':
- {'repourl':'git://git.openembedded.org/bitbake',
- 'checkout':False,
- 'branch':'master'}},
- {'eclipse-poky-neon':
- {'repourl':'git://git.yoctoproject.org/eclipse-poky',
- 'checkout':False,
- 'branch':'neon-master'}},
- {'meta-qt4':
- {'repourl':'git://git.yoctoproject.org/meta-qt4',
- 'branch':'master'}},
- {'meta-qt3':
- {'repourl':'git://git.yoctoproject.org/meta-qt3',
- 'branch':'master'}}]
-props: [{'fp_date':{'prop_type':'StringParameter',
- 'size': 20,
- 'name': 'fp_date',
- 'label':'Full Pass date:'}}]
-steps: [{'SetDest':{}},
- {'CheckOutLayers': {}},
- {'RunPreamble': {}},
- {'TriggerBuilds': {'schedulerName': 'dist-build',
- 'waitForFinish': 'True',
- 'schedulerNames': {
- 'nightly-oe-selftest': {},
- 'nightly-oecore': {},
- 'nightly-packagemanagers': {},
- 'nightly-world': {},
- 'nightly-arm': {},
- 'nightly-multilib': {},
- 'nightly-x86-64-lsb': {},
- 'nightly-x86': {},
- 'nightly-x32': {},
- 'poky-tiny': {},
- 'nightly-qa-extras': {},
- 'buildtools': {}},
- 'eclipse-plugin-neon': {},
- 'schedulerNames_nowait': {}}},]
diff --git a/buildset-config.yocto-qa/nightly-qa-extras.conf b/buildset-config.yocto-qa/nightly-qa-extras.conf
deleted file mode 120000
index d6d1e205..00000000
--- a/buildset-config.yocto-qa/nightly-qa-extras.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-qa-extras.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-world.conf b/buildset-config.yocto-qa/nightly-world.conf
deleted file mode 120000
index 347b5353..00000000
--- a/buildset-config.yocto-qa/nightly-world.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-world.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-x32.conf b/buildset-config.yocto-qa/nightly-x32.conf
deleted file mode 120000
index 2837f7bc..00000000
--- a/buildset-config.yocto-qa/nightly-x32.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-x32.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-x86-64-lsb.conf b/buildset-config.yocto-qa/nightly-x86-64-lsb.conf
deleted file mode 120000
index 38b9217e..00000000
--- a/buildset-config.yocto-qa/nightly-x86-64-lsb.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-x86-64-lsb.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/nightly-x86.conf b/buildset-config.yocto-qa/nightly-x86.conf
deleted file mode 120000
index 7b9701a2..00000000
--- a/buildset-config.yocto-qa/nightly-x86.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/nightly-x86.conf \ No newline at end of file
diff --git a/buildset-config.yocto-qa/poky-tiny.conf b/buildset-config.yocto-qa/poky-tiny.conf
deleted file mode 120000
index 874e27e0..00000000
--- a/buildset-config.yocto-qa/poky-tiny.conf
+++ /dev/null
@@ -1 +0,0 @@
-../buildset-config.controller/poky-tiny.conf \ No newline at end of file
diff --git a/config/autobuilder.conf.example b/config/autobuilder.conf.example
deleted file mode 100644
index 7a56447a..00000000
--- a/config/autobuilder.conf.example
+++ /dev/null
@@ -1,100 +0,0 @@
-[GitSettings]
-OPTIMIZED_GIT_CLONE = True
-OGIT_TRASH_DIR = /tmp/yocto-autobuilder/git/trash
-OGIT_MIRROR_DIR = /tmp/yocto-autobuilder/git/mirror
-OGIT_TRASH_CRON_TIME = "0 0 * * *"
-OGIT_TRASH_NICE_LEVEL = "19"
-
-[BuildHistorySettings]
-BUILD_HISTORY_COLLECT = True
-BUILD_HISTORY_DIR = "/tmp/yocto-autobuilder/buildhistory"
-BUILD_HISTORY_REPO = "file:////tmp/yocto-autobuilder/buildhistory-repo"
-BUILD_HISTORY_WHITELIST = "{'git://git.yoctoproject.org/poky':['master']}"
-BUILD_HISTORY_THROWAWAY_WHITELIST = "{'git://git.yoctoproject.org/poky':['master-next']}"
-BUILD_HISTORY_WEB = False
-BUILD_HISTORY_WEB_DIR = "/tmp/buildhistory-web"
-PRSERV_HOST = "localhost"
-PRSERV_PORT = "0"
-
-[ErrorReportSettings]
-ERROR_REPORT_COLLECT = True
-#ERROR_REPORT_SERVER = "http://yourerrorreport.url.com"
-#ERROR_REPORT_DIR = "/path/to/error/logs"
-#ERROR_REPORT_EMAIL = "autobuilder@error-report.yourproject.org"
-#ERROR_REPORT_NAME = "MyProject Autobuilder"
-
-[PublishSettings]
-PUBLISH_BUILDS = True
-PUBLISH_SOURCE_MIRROR = False
-PUBLISH_SSTATE = False
-GEN_IMG_MD5 = True
-MACHINE_PUBLISH_DIR = "machines"
-BA_PUBLISH_DIR = "build-appliance"
-QEMU_PUBLISH_DIR = "/machines/qemu"
-RPM_PUBLISH_DIR = "rpm"
-DEB_PUBLISH_DIR = "deb"
-IPK_PUBLISH_DIR = "ipk"
-MARKED_RELEASE_DIR = "releases"
-ADT_INST_PUBLISH_DIR = "adt-installer"
-ADTQA_INST_PUBLISH_DIR = "adt-installer-QA"
-SSTATE_PUBLISH_DIR = "/tmp/yocto-autobuilder/sstate_mirror"
-SSTATE_RELEASE_DIR = "/tmp/yocto-autobuilder/builds/sstate"
-SOURCE_PUBLISH_DIR = "/tmp/yocto-autobuilder/source"
-BUILD_PUBLISH_DIR = "/tmp/yocto-autobuilder/builds"
-RELEASE_PUBLISH_DIR = "/tmp/yocto-autobuilder/builds"
-X86TC_PUBLISH_DIR = "toolchain/i686"
-X8664TC_PUBLISH_DIR = "toolchain/x86_64"
-
-[ToasterSettings]
-#TOASTER_UPLOAD_URL = "http://localhost:8000/orm/eventfile"
-
-[BuildSettings]
-DL_DIR = "/tmp/yocto-autobuilder/downloads"
-SSTATE_DIR = "/tmp/yocto-autobuilder/sstate"
-SSTATE_MIRROR_BASE = "http://sstate.yoctoproject.org/"
-#TMP_DIR = "/tmp/yocto-autobuilder/tmp"
-IMAGE_FSTYPES = ""
-BB_NUMBER_THREADS = "16"
-PARALLEL_MAKE_NUM = "16"
-RESOLVE_TRIGGERED_HEAD = True
-DEVKERNEL_MUT_REPO = "{'git://git.yoctoproject.org/poky-contrib':['stage/master_under_test', 'sgw/mut']}"
-DEVKERNEL = "linux-yocto-dev"
-
-[TestSettings]
-QEMU_USE_KVM = "True"
-
-[ADTREPO Settings]
-ADTREPO_POPULATE = False
-ADTREPO_DEV_POPULATE = True
-ADTREPO_URL = "http://adtrepo.yoctoproject.org/"
-ADTREPO_PATH = "/tmp/adtrepo.yoctoproject.org/"
-ADTREPO_DEV_URL = "http://adtrepo-dev.yoctoproject.org/"
-ADTREPO_DEV_PATH = "/tmp/adtrepo-dev/"
-
-[IASettings]
-EMGD_DRIVER_DIR = "/tmp/yocto-autobuilder/emgd-driver"
-
-[WebServer]
-WEB_ROOT = "/var/www/"
-WEB_URL = "http://autobuilder.yoctoproject.org/"
-
-[QAEmail]
-QA_MAIL_TO = "root@localhost otherperson@localhost"
-QA_MAIL_CC = "buildcc@localhost"
-QA_MAIL_BCC = "buildbcc@localhost"
-QA_MAIL_SIG = "Multiline\nSig\nLine"
-
-[Buildlogger]
-BUILDLOG_TO_WIKI = False
-
-[Performance]
-PERFORMANCE_PUBLISH_DIR = "/tmp/yocto-autobuilder/performance"
-PERFORMANCE_SEND_EMAIL = "False"
-PERFORMANCE_MAIL_TO = "root@localhost otherperson@localhost"
-PERFORMANCE_MAIL_CC = "buildcc@localhost"
-PERFORMANCE_MAIL_BCC = "buildbcc@localhost"
-PERFORMANCE_MAIL_SIG = "Multiline\nSig\nLine"
-
-[Daft]
-DAFT_WORKER_DEVICES_CFG = "/etc/daft/devices.cfg"
-DAFT_WORKER_WORKSPACE = "/home/ab/workspace"
diff --git a/config/autobuilder.conf.readme b/config/autobuilder.conf.readme
deleted file mode 100644
index 16c3f3e8..00000000
--- a/config/autobuilder.conf.readme
+++ /dev/null
@@ -1,48 +0,0 @@
-
-config/autobuilder.conf
-=======================
-
- PublishSettings
- ===============
-
- PUBLISH_BUILDS:
- Determines if build artifacts are copied into a release directory,
- as opposed to created just to see if they were successfully built.
- Generally not used for developer autobuilders, it's quite useful for
- production autobuilders.
-
- PUBLISH_SOURCE_MIRROR:
- Publish where source depedences are fetched from.
-
- PUBLISH_SSTATE:
- If True, use to sync sstate to sstate mirror
-
- BUILD_HISTORY_COLLECT:
- Collects and pushes buildhistory artifacts if True. Defaults to False
-
- BuildSettings
- =============
-
- SOURCE_DL_DIR:
- autobuilder worker's DL_DIR
-
- SOURCE_SSTATE_DIR:
- SState directory for non-lsb builds
-
- LSB_SSTATE_DIR:
- SState directory for lsb builds. This should usually be the same as
- SOURCE_SSTATE_DIR, however is left in for historical reasons.
-
- BUILD_HISTORY_DIR:
- Local checkout of the build history repository
-
- BUILD_HISTORY_REPO:
- Main repository to store build history statistics
-
- IASettings
- ==========
-
- EMGD_DRIVER_DIR:
- Older versions of the crownbay meta-intel BSP required a third party
- binary driver to have been predownloaded. This points to the location
- of the EMGD driver binary.
diff --git a/docs/YoctoAutobuilderDevelopersDocument.html b/docs/YoctoAutobuilderDevelopersDocument.html
deleted file mode 100644
index 7fcbb4bc..00000000
--- a/docs/YoctoAutobuilderDevelopersDocument.html
+++ /dev/null
@@ -1 +0,0 @@
-<html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type"><style type="text/css">ol.lst-kix_eogk2g9lz4ou-0.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-0 0}ol.lst-kix_z44608xc5z5-0.start{counter-reset:lst-ctn-kix_z44608xc5z5-0 0}ol.lst-kix_z44608xc5z5-8{list-style-type:none}ol.lst-kix_55zebeya5hie-2.start{counter-reset:lst-ctn-kix_55zebeya5hie-2 0}ol.lst-kix_z44608xc5z5-6{list-style-type:none}ol.lst-kix_z44608xc5z5-7{list-style-type:none}ol.lst-kix_z44608xc5z5-4{list-style-type:none}ol.lst-kix_z44608xc5z5-5{list-style-type:none}ol.lst-kix_z44608xc5z5-2{list-style-type:none}ol.lst-kix_z44608xc5z5-3{list-style-type:none}ol.lst-kix_z44608xc5z5-0{list-style-type:none}ol.lst-kix_z44608xc5z5-1{list-style-type:none}.lst-kix_w6ctxtwswacj-0>li:before{content:"\0025cf "}.lst-kix_w6ctxtwswacj-1>li:before{content:"\0025cb "}.lst-kix_55zebeya5hie-7>li{counter-increment:lst-ctn-kix_55zebeya5hie-7}.lst-kix_w6ctxtwswacj-6>li:before{content:"\0025cf "}.lst-kix_w6ctxtwswacj-8>li:before{content:"\0025a0 "}.lst-kix_w6ctxtwswacj-5>li:before{content:"\0025a0 "}.lst-kix_w6ctxtwswacj-2>li:before{content:"\0025a0 "}.lst-kix_w6ctxtwswacj-4>li:before{content:"\0025cb "}ul.lst-kix_vgo489ljcome-8{list-style-type:none}.lst-kix_w6ctxtwswacj-3>li:before{content:"\0025cf "}.lst-kix_w6ctxtwswacj-7>li:before{content:"\0025cb "}.lst-kix_55zebeya5hie-3>li{counter-increment:lst-ctn-kix_55zebeya5hie-3}ul.lst-kix_qrb1a1jgz3rn-4{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-3{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-6{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-5{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-0{list-style-type:none}.lst-kix_55zebeya5hie-0>li{counter-increment:lst-ctn-kix_55zebeya5hie-0}ul.lst-kix_qrb1a1jgz3rn-2{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-1{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-8{list-style-type:none}ul.lst-kix_qrb1a1jgz3rn-7{list-style-type:none}.lst-kix_2vtha56u4mwf-6>li:before{content:"- "}ol.lst-kix_eogk2g9lz4ou-7.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-7 0}.lst-kix_2vtha56u4mwf-4>li:before{content:"- "}.lst-kix_2vtha56u4mwf-8>li:before{content:"- "}.lst-kix_z44608xc5z5-3>li{counter-increment:lst-ctn-kix_z44608xc5z5-3}.lst-kix_ivvjgdhufo4a-7>li:before{content:"- "}ul.lst-kix_2vtha56u4mwf-7{list-style-type:none}.lst-kix_ivvjgdhufo4a-3>li:before{content:"- "}ul.lst-kix_2vtha56u4mwf-6{list-style-type:none}ul.lst-kix_2vtha56u4mwf-8{list-style-type:none}.lst-kix_ivvjgdhufo4a-5>li:before{content:"- "}ul.lst-kix_2vtha56u4mwf-1{list-style-type:none}ul.lst-kix_2vtha56u4mwf-0{list-style-type:none}ul.lst-kix_2vtha56u4mwf-3{list-style-type:none}ul.lst-kix_2vtha56u4mwf-2{list-style-type:none}ul.lst-kix_2vtha56u4mwf-5{list-style-type:none}ul.lst-kix_2vtha56u4mwf-4{list-style-type:none}ul.lst-kix_5jxi9skcdaiv-7{list-style-type:none}ul.lst-kix_5jxi9skcdaiv-8{list-style-type:none}.lst-kix_5jxi9skcdaiv-4>li:before{content:"\0025cb "}.lst-kix_5jxi9skcdaiv-8>li:before{content:"\0025a0 "}ul.lst-kix_5jxi9skcdaiv-1{list-style-type:none}ul.lst-kix_5jxi9skcdaiv-2{list-style-type:none}ul.lst-kix_5jxi9skcdaiv-0{list-style-type:none}ul.lst-kix_5jxi9skcdaiv-5{list-style-type:none}ul.lst-kix_5jxi9skcdaiv-6{list-style-type:none}.lst-kix_ivvjgdhufo4a-1>li:before{content:"- "}ul.lst-kix_5jxi9skcdaiv-3{list-style-type:none}.lst-kix_5jxi9skcdaiv-6>li:before{content:"\0025cf "}ul.lst-kix_5jxi9skcdaiv-4{list-style-type:none}ul.lst-kix_vgo489ljcome-5{list-style-type:none}ul.lst-kix_vgo489ljcome-4{list-style-type:none}ul.lst-kix_vgo489ljcome-7{list-style-type:none}ul.lst-kix_e6cn8ienuo6k-8{list-style-type:none}ul.lst-kix_vgo489ljcome-6{list-style-type:none}ul.lst-kix_e6cn8ienuo6k-7{list-style-type:none}ul.lst-kix_vgo489ljcome-1{list-style-type:none}ul.lst-kix_e6cn8ienuo6k-6{list-style-type:none}.lst-kix_2vtha56u4mwf-0>li:before{content:"- "}ul.lst-kix_vgo489ljcome-0{list-style-type:none}.lst-kix_5jxi9skcdaiv-0>li:before{content:"\0025cf "}ul.lst-kix_e6cn8ienuo6k-5{list-style-type:none}.lst-kix_rxf8talb6b1y-5>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-5}ul.lst-kix_vgo489ljcome-3{list-style-type:none}ul.lst-kix_e6cn8ienuo6k-4{list-style-type:none}ul.lst-kix_vgo489ljcome-2{list-style-type:none}ul.lst-kix_e6cn8ienuo6k-3{list-style-type:none}.lst-kix_eogk2g9lz4ou-2>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-2}ul.lst-kix_e6cn8ienuo6k-2{list-style-type:none}.lst-kix_2vtha56u4mwf-2>li:before{content:"- "}ul.lst-kix_e6cn8ienuo6k-1{list-style-type:none}ul.lst-kix_e6cn8ienuo6k-0{list-style-type:none}.lst-kix_z44608xc5z5-2>li{counter-increment:lst-ctn-kix_z44608xc5z5-2}.lst-kix_5jxi9skcdaiv-2>li:before{content:"\0025a0 "}.lst-kix_z44608xc5z5-1>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-1,lower-latin) ". "}.lst-kix_55zebeya5hie-4>li{counter-increment:lst-ctn-kix_55zebeya5hie-4}.lst-kix_z44608xc5z5-5>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-5,lower-roman) ". "}ol.lst-kix_eogk2g9lz4ou-5.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-5 0}.lst-kix_z44608xc5z5-7>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-7,lower-latin) ". "}ol.lst-kix_55zebeya5hie-2{list-style-type:none}ol.lst-kix_55zebeya5hie-3{list-style-type:none}ol.lst-kix_55zebeya5hie-4{list-style-type:none}ol.lst-kix_55zebeya5hie-5{list-style-type:none}ol.lst-kix_55zebeya5hie-6{list-style-type:none}ol.lst-kix_55zebeya5hie-7{list-style-type:none}ol.lst-kix_55zebeya5hie-8{list-style-type:none}.lst-kix_z44608xc5z5-3>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-3,decimal) ". "}ul.lst-kix_jqwplanlf6ac-8{list-style-type:none}ol.lst-kix_55zebeya5hie-0.start{counter-reset:lst-ctn-kix_55zebeya5hie-0 0}ul.lst-kix_jqwplanlf6ac-6{list-style-type:none}ul.lst-kix_jqwplanlf6ac-7{list-style-type:none}ul.lst-kix_jqwplanlf6ac-4{list-style-type:none}ul.lst-kix_jqwplanlf6ac-5{list-style-type:none}ul.lst-kix_jqwplanlf6ac-2{list-style-type:none}ul.lst-kix_jqwplanlf6ac-3{list-style-type:none}ul.lst-kix_jqwplanlf6ac-0{list-style-type:none}ul.lst-kix_jqwplanlf6ac-1{list-style-type:none}.lst-kix_rxf8talb6b1y-6>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-6}.lst-kix_eogk2g9lz4ou-3>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-3}ol.lst-kix_55zebeya5hie-0{list-style-type:none}ol.lst-kix_55zebeya5hie-1{list-style-type:none}.lst-kix_vgo489ljcome-0>li:before{content:"\0025cf "}.lst-kix_vgo489ljcome-2>li:before{content:"\0025a0 "}ul.lst-kix_inqgee5fh4k6-6{list-style-type:none}.lst-kix_vgo489ljcome-6>li:before{content:"\0025cf "}ul.lst-kix_inqgee5fh4k6-7{list-style-type:none}.lst-kix_e6cn8ienuo6k-0>li:before{content:"- "}.lst-kix_e6cn8ienuo6k-1>li:before{content:"- "}.lst-kix_e6cn8ienuo6k-4>li:before{content:"- "}.lst-kix_e6cn8ienuo6k-5>li:before{content:"- "}ul.lst-kix_inqgee5fh4k6-8{list-style-type:none}ul.lst-kix_inqgee5fh4k6-2{list-style-type:none}ul.lst-kix_inqgee5fh4k6-3{list-style-type:none}ul.lst-kix_inqgee5fh4k6-4{list-style-type:none}ul.lst-kix_inqgee5fh4k6-5{list-style-type:none}ul.lst-kix_inqgee5fh4k6-0{list-style-type:none}.lst-kix_vgo489ljcome-3>li:before{content:"\0025cf "}ul.lst-kix_inqgee5fh4k6-1{list-style-type:none}.lst-kix_1ypaffc481r0-7>li:before{content:"- "}.lst-kix_1ypaffc481r0-4>li:before{content:"- "}.lst-kix_1ypaffc481r0-8>li:before{content:"- "}.lst-kix_vgo489ljcome-7>li:before{content:"\0025cb "}.lst-kix_1ypaffc481r0-0>li:before{content:"- "}.lst-kix_1ypaffc481r0-3>li:before{content:"- "}ul.lst-kix_j6pu4ozg1h9q-0{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-3{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-4{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-1{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-2{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-7{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-8{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-5{list-style-type:none}ul.lst-kix_j6pu4ozg1h9q-6{list-style-type:none}.lst-kix_inqgee5fh4k6-5>li:before{content:"- "}.lst-kix_inqgee5fh4k6-2>li:before{content:"- "}.lst-kix_inqgee5fh4k6-6>li:before{content:"- "}ol.lst-kix_eogk2g9lz4ou-2.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-2 0}.lst-kix_inqgee5fh4k6-1>li:before{content:"- "}.lst-kix_eogk2g9lz4ou-7>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-7}.lst-kix_hte491cj00mg-1>li:before{content:"- "}.lst-kix_qrb1a1jgz3rn-2>li:before{content:"\0025a0 "}.lst-kix_hte491cj00mg-0>li:before{content:"- "}.lst-kix_hte491cj00mg-4>li:before{content:"- "}.lst-kix_z44608xc5z5-7>li{counter-increment:lst-ctn-kix_z44608xc5z5-7}.lst-kix_qrb1a1jgz3rn-3>li:before{content:"\0025cf "}ol.lst-kix_eogk2g9lz4ou-3.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-3 0}.lst-kix_hte491cj00mg-8>li:before{content:"- "}.lst-kix_hte491cj00mg-5>li:before{content:"- "}.lst-kix_qrb1a1jgz3rn-6>li:before{content:"\0025cf "}.lst-kix_qrb1a1jgz3rn-7>li:before{content:"\0025cb "}.lst-kix_2vtha56u4mwf-7>li:before{content:"- "}.lst-kix_eogk2g9lz4ou-0>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-0,decimal) ". "}.lst-kix_ivvjgdhufo4a-2>li:before{content:"- "}.lst-kix_ivvjgdhufo4a-6>li:before{content:"- "}.lst-kix_55zebeya5hie-2>li{counter-increment:lst-ctn-kix_55zebeya5hie-2}.lst-kix_rxf8talb6b1y-4>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-4}.lst-kix_rxf8talb6b1y-1>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-1,lower-latin) ". "}.lst-kix_eogk2g9lz4ou-4>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-4,lower-latin) ". "}.lst-kix_5jxi9skcdaiv-7>li:before{content:"\0025cb "}ol.lst-kix_rxf8talb6b1y-8{list-style-type:none}.lst-kix_eogk2g9lz4ou-5>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-5}.lst-kix_j6pu4ozg1h9q-2>li:before{content:"\0025a0 "}ol.lst-kix_eogk2g9lz4ou-1.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-1 0}.lst-kix_rxf8talb6b1y-5>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-5,lower-roman) ". "}.lst-kix_5jxi9skcdaiv-3>li:before{content:"\0025cf "}ol.lst-kix_rxf8talb6b1y-6{list-style-type:none}.lst-kix_2vtha56u4mwf-3>li:before{content:"- "}ol.lst-kix_rxf8talb6b1y-7{list-style-type:none}ol.lst-kix_rxf8talb6b1y-4{list-style-type:none}ol.lst-kix_rxf8talb6b1y-5{list-style-type:none}ol.lst-kix_rxf8talb6b1y-2{list-style-type:none}.lst-kix_rxf8talb6b1y-2>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-2}ol.lst-kix_rxf8talb6b1y-3{list-style-type:none}ol.lst-kix_rxf8talb6b1y-0{list-style-type:none}ol.lst-kix_rxf8talb6b1y-1{list-style-type:none}.lst-kix_z44608xc5z5-5>li{counter-increment:lst-ctn-kix_z44608xc5z5-5}.lst-kix_z44608xc5z5-0>li{counter-increment:lst-ctn-kix_z44608xc5z5-0}.lst-kix_z44608xc5z5-2>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-2,lower-roman) ". "}.lst-kix_z44608xc5z5-6>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-6,decimal) ". "}.lst-kix_alogm9c9t96n-1>li:before{content:"\0025cb "}.lst-kix_sdy6fqgzk2k7-8>li:before{content:"\0025a0 "}.lst-kix_jqwplanlf6ac-8>li:before{content:"\0025a0 "}.lst-kix_jqwplanlf6ac-4>li:before{content:"\0025cb "}.lst-kix_j6pu4ozg1h9q-6>li:before{content:"\0025cf "}.lst-kix_jqwplanlf6ac-0>li:before{content:"\0025cf "}.lst-kix_sdy6fqgzk2k7-0>li:before{content:"\0025cf "}.lst-kix_sdy6fqgzk2k7-4>li:before{content:"\0025cb "}.lst-kix_eogk2g9lz4ou-0>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-0}.lst-kix_alogm9c9t96n-5>li:before{content:"\0025a0 "}.lst-kix_iun8hna84yne-3>li:before{content:"\0025cf "}.lst-kix_e6cn8ienuo6k-8>li:before{content:"- "}.lst-kix_iun8hna84yne-7>li:before{content:"\0025cb "}ol.lst-kix_z44608xc5z5-6.start{counter-reset:lst-ctn-kix_z44608xc5z5-6 0}.lst-kix_55zebeya5hie-0>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-0,decimal) ". "}ol.lst-kix_rxf8talb6b1y-5.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-5 0}.lst-kix_eogk2g9lz4ou-8>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-8}.lst-kix_z44608xc5z5-8>li{counter-increment:lst-ctn-kix_z44608xc5z5-8}ol.lst-kix_55zebeya5hie-8.start{counter-reset:lst-ctn-kix_55zebeya5hie-8 0}.lst-kix_eogk2g9lz4ou-1>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-1}ol.lst-kix_z44608xc5z5-1.start{counter-reset:lst-ctn-kix_z44608xc5z5-1 0}ol.lst-kix_rxf8talb6b1y-0.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-0 0}.lst-kix_rxf8talb6b1y-7>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-7}.lst-kix_rxf8talb6b1y-0>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-0,decimal) ". "}.lst-kix_55zebeya5hie-6>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-6,decimal) ". "}.lst-kix_55zebeya5hie-8>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-8,lower-roman) ". "}.lst-kix_z44608xc5z5-4>li{counter-increment:lst-ctn-kix_z44608xc5z5-4}.lst-kix_z44608xc5z5-1>li{counter-increment:lst-ctn-kix_z44608xc5z5-1}.lst-kix_eogk2g9lz4ou-8>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-8,lower-roman) ". "}.lst-kix_55zebeya5hie-7>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-7,lower-latin) ". "}.lst-kix_55zebeya5hie-4>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-4,lower-latin) ". "}.lst-kix_55zebeya5hie-2>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-2,lower-roman) ". "}.lst-kix_55zebeya5hie-1>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-1,lower-latin) ". "}ol.lst-kix_55zebeya5hie-3.start{counter-reset:lst-ctn-kix_55zebeya5hie-3 0}.lst-kix_55zebeya5hie-5>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-5,lower-roman) ". "}.lst-kix_55zebeya5hie-3>li:before{content:"" counter(lst-ctn-kix_55zebeya5hie-3,decimal) ". "}ol.lst-kix_55zebeya5hie-1.start{counter-reset:lst-ctn-kix_55zebeya5hie-1 0}.lst-kix_eogk2g9lz4ou-1>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-1,lower-latin) ". "}.lst-kix_eogk2g9lz4ou-5>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-5,lower-roman) ". "}.lst-kix_eogk2g9lz4ou-7>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-7,lower-latin) ". "}.lst-kix_eogk2g9lz4ou-3>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-3,decimal) ". "}ol.lst-kix_eogk2g9lz4ou-4.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-4 0}.lst-kix_eogk2g9lz4ou-4>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-4}.lst-kix_j6pu4ozg1h9q-3>li:before{content:"\0025cf "}.lst-kix_j6pu4ozg1h9q-5>li:before{content:"\0025a0 "}.lst-kix_rxf8talb6b1y-2>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-2,lower-roman) ". "}.lst-kix_j6pu4ozg1h9q-1>li:before{content:"\0025cb "}.lst-kix_rxf8talb6b1y-4>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-4,lower-latin) ". "}.lst-kix_rxf8talb6b1y-6>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-6,decimal) ". "}.lst-kix_rxf8talb6b1y-8>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-8,lower-roman) ". "}.lst-kix_alogm9c9t96n-0>li:before{content:"\0025cf "}.lst-kix_iun8hna84yne-8>li:before{content:"\0025a0 "}.lst-kix_alogm9c9t96n-2>li:before{content:"\0025a0 "}.lst-kix_jqwplanlf6ac-7>li:before{content:"\0025cb "}.lst-kix_sdy6fqgzk2k7-7>li:before{content:"\0025cb "}.lst-kix_jqwplanlf6ac-3>li:before{content:"\0025cf "}.lst-kix_iun8hna84yne-0>li:before{content:"\0025cf "}.lst-kix_j6pu4ozg1h9q-7>li:before{content:"\0025cb "}.lst-kix_jqwplanlf6ac-5>li:before{content:"\0025a0 "}.lst-kix_sdy6fqgzk2k7-1>li:before{content:"\0025cb "}ol.lst-kix_eogk2g9lz4ou-6.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-6 0}.lst-kix_rxf8talb6b1y-0>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-0}.lst-kix_sdy6fqgzk2k7-3>li:before{content:"\0025cf "}.lst-kix_55zebeya5hie-5>li{counter-increment:lst-ctn-kix_55zebeya5hie-5}.lst-kix_sdy6fqgzk2k7-5>li:before{content:"\0025a0 "}.lst-kix_jqwplanlf6ac-1>li:before{content:"\0025cb "}.lst-kix_iun8hna84yne-2>li:before{content:"\0025a0 "}.lst-kix_alogm9c9t96n-6>li:before{content:"\0025cf "}.lst-kix_iun8hna84yne-4>li:before{content:"\0025cb "}.lst-kix_alogm9c9t96n-4>li:before{content:"\0025cb "}.lst-kix_alogm9c9t96n-8>li:before{content:"\0025a0 "}.lst-kix_e6cn8ienuo6k-7>li:before{content:"- "}.lst-kix_iun8hna84yne-6>li:before{content:"\0025cf "}.lst-kix_vgo489ljcome-8>li:before{content:"\0025a0 "}.lst-kix_e6cn8ienuo6k-2>li:before{content:"- "}.lst-kix_e6cn8ienuo6k-3>li:before{content:"- "}.lst-kix_vgo489ljcome-5>li:before{content:"\0025a0 "}.lst-kix_vgo489ljcome-4>li:before{content:"\0025cb "}ol.lst-kix_rxf8talb6b1y-2.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-2 0}.lst-kix_55zebeya5hie-6>li{counter-increment:lst-ctn-kix_55zebeya5hie-6}ol.lst-kix_z44608xc5z5-3.start{counter-reset:lst-ctn-kix_z44608xc5z5-3 0}.lst-kix_1ypaffc481r0-5>li:before{content:"- "}.lst-kix_1ypaffc481r0-6>li:before{content:"- "}ul.lst-kix_iun8hna84yne-5{list-style-type:none}ul.lst-kix_iun8hna84yne-4{list-style-type:none}ul.lst-kix_iun8hna84yne-3{list-style-type:none}.lst-kix_1ypaffc481r0-1>li:before{content:"- "}ul.lst-kix_iun8hna84yne-2{list-style-type:none}ul.lst-kix_iun8hna84yne-8{list-style-type:none}ul.lst-kix_w6ctxtwswacj-8{list-style-type:none}ul.lst-kix_iun8hna84yne-7{list-style-type:none}.lst-kix_1ypaffc481r0-2>li:before{content:"- "}ul.lst-kix_iun8hna84yne-6{list-style-type:none}ul.lst-kix_1ypaffc481r0-8{list-style-type:none}.lst-kix_rxf8talb6b1y-8>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-8}ul.lst-kix_iun8hna84yne-1{list-style-type:none}ul.lst-kix_iun8hna84yne-0{list-style-type:none}ul.lst-kix_1ypaffc481r0-0{list-style-type:none}ol.lst-kix_55zebeya5hie-5.start{counter-reset:lst-ctn-kix_55zebeya5hie-5 0}ul.lst-kix_1ypaffc481r0-1{list-style-type:none}ul.lst-kix_1ypaffc481r0-2{list-style-type:none}ul.lst-kix_1ypaffc481r0-3{list-style-type:none}ul.lst-kix_1ypaffc481r0-4{list-style-type:none}ul.lst-kix_1ypaffc481r0-5{list-style-type:none}ol.lst-kix_eogk2g9lz4ou-8.start{counter-reset:lst-ctn-kix_eogk2g9lz4ou-8 0}ul.lst-kix_1ypaffc481r0-6{list-style-type:none}ul.lst-kix_1ypaffc481r0-7{list-style-type:none}.lst-kix_inqgee5fh4k6-4>li:before{content:"- "}.lst-kix_inqgee5fh4k6-3>li:before{content:"- "}ul.lst-kix_sdy6fqgzk2k7-1{list-style-type:none}.lst-kix_rxf8talb6b1y-1>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-1}ul.lst-kix_sdy6fqgzk2k7-0{list-style-type:none}.lst-kix_inqgee5fh4k6-0>li:before{content:"- "}ol.lst-kix_rxf8talb6b1y-8.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-8 0}ol.lst-kix_z44608xc5z5-8.start{counter-reset:lst-ctn-kix_z44608xc5z5-8 0}.lst-kix_qrb1a1jgz3rn-1>li:before{content:"\0025cb "}.lst-kix_hte491cj00mg-2>li:before{content:"- "}.lst-kix_qrb1a1jgz3rn-0>li:before{content:"\0025cf "}.lst-kix_qrb1a1jgz3rn-5>li:before{content:"\0025a0 "}.lst-kix_qrb1a1jgz3rn-4>li:before{content:"\0025cb "}ol.lst-kix_eogk2g9lz4ou-0{list-style-type:none}ol.lst-kix_z44608xc5z5-2.start{counter-reset:lst-ctn-kix_z44608xc5z5-2 0}.lst-kix_hte491cj00mg-3>li:before{content:"- "}ol.lst-kix_eogk2g9lz4ou-5{list-style-type:none}ol.lst-kix_rxf8talb6b1y-1.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-1 0}ol.lst-kix_rxf8talb6b1y-7.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-7 0}ol.lst-kix_eogk2g9lz4ou-6{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-8{list-style-type:none}ol.lst-kix_eogk2g9lz4ou-7{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-7{list-style-type:none}ol.lst-kix_eogk2g9lz4ou-8{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-6{list-style-type:none}.lst-kix_qrb1a1jgz3rn-8>li:before{content:"\0025a0 "}ol.lst-kix_eogk2g9lz4ou-1{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-5{list-style-type:none}ol.lst-kix_eogk2g9lz4ou-2{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-4{list-style-type:none}ol.lst-kix_eogk2g9lz4ou-3{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-3{list-style-type:none}ol.lst-kix_eogk2g9lz4ou-4{list-style-type:none}ul.lst-kix_sdy6fqgzk2k7-2{list-style-type:none}.lst-kix_inqgee5fh4k6-8>li:before{content:"- "}.lst-kix_inqgee5fh4k6-7>li:before{content:"- "}.lst-kix_hte491cj00mg-7>li:before{content:"- "}.lst-kix_hte491cj00mg-6>li:before{content:"- "}.lst-kix_55zebeya5hie-1>li{counter-increment:lst-ctn-kix_55zebeya5hie-1}.lst-kix_eogk2g9lz4ou-2>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-2,lower-roman) ". "}.lst-kix_ivvjgdhufo4a-8>li:before{content:"- "}.lst-kix_2vtha56u4mwf-5>li:before{content:"- "}ol.lst-kix_rxf8talb6b1y-6.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-6 0}ul.lst-kix_ivvjgdhufo4a-0{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-1{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-2{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-3{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-4{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-5{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-6{list-style-type:none}.lst-kix_eogk2g9lz4ou-6>li:before{content:"" counter(lst-ctn-kix_eogk2g9lz4ou-6,decimal) ". "}ul.lst-kix_ivvjgdhufo4a-7{list-style-type:none}ul.lst-kix_ivvjgdhufo4a-8{list-style-type:none}.lst-kix_ivvjgdhufo4a-4>li:before{content:"- "}ol.lst-kix_55zebeya5hie-4.start{counter-reset:lst-ctn-kix_55zebeya5hie-4 0}.lst-kix_j6pu4ozg1h9q-4>li:before{content:"\0025cb "}ul.lst-kix_alogm9c9t96n-3{list-style-type:none}ul.lst-kix_alogm9c9t96n-4{list-style-type:none}ul.lst-kix_alogm9c9t96n-5{list-style-type:none}ul.lst-kix_alogm9c9t96n-6{list-style-type:none}.lst-kix_5jxi9skcdaiv-5>li:before{content:"\0025a0 "}ol.lst-kix_rxf8talb6b1y-3.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-3 0}ul.lst-kix_alogm9c9t96n-0{list-style-type:none}ul.lst-kix_alogm9c9t96n-1{list-style-type:none}.lst-kix_rxf8talb6b1y-3>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-3,decimal) ". "}ol.lst-kix_z44608xc5z5-7.start{counter-reset:lst-ctn-kix_z44608xc5z5-7 0}ul.lst-kix_alogm9c9t96n-2{list-style-type:none}.lst-kix_j6pu4ozg1h9q-0>li:before{content:"\0025cf "}ul.lst-kix_alogm9c9t96n-7{list-style-type:none}.lst-kix_ivvjgdhufo4a-0>li:before{content:"- "}ul.lst-kix_alogm9c9t96n-8{list-style-type:none}.lst-kix_5jxi9skcdaiv-1>li:before{content:"\0025cb "}.lst-kix_rxf8talb6b1y-7>li:before{content:"" counter(lst-ctn-kix_rxf8talb6b1y-7,lower-latin) ". "}.lst-kix_2vtha56u4mwf-1>li:before{content:"- "}ol.lst-kix_z44608xc5z5-4.start{counter-reset:lst-ctn-kix_z44608xc5z5-4 0}ol.lst-kix_rxf8talb6b1y-4.start{counter-reset:lst-ctn-kix_rxf8talb6b1y-4 0}.lst-kix_z44608xc5z5-0>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-0,decimal) ". "}.lst-kix_z44608xc5z5-6>li{counter-increment:lst-ctn-kix_z44608xc5z5-6}.lst-kix_alogm9c9t96n-3>li:before{content:"\0025cf "}ol.lst-kix_55zebeya5hie-6.start{counter-reset:lst-ctn-kix_55zebeya5hie-6 0}ul.lst-kix_w6ctxtwswacj-6{list-style-type:none}ul.lst-kix_w6ctxtwswacj-7{list-style-type:none}ul.lst-kix_w6ctxtwswacj-4{list-style-type:none}.lst-kix_jqwplanlf6ac-6>li:before{content:"\0025cf "}ul.lst-kix_w6ctxtwswacj-5{list-style-type:none}ul.lst-kix_hte491cj00mg-0{list-style-type:none}ul.lst-kix_w6ctxtwswacj-2{list-style-type:none}ul.lst-kix_hte491cj00mg-1{list-style-type:none}ul.lst-kix_w6ctxtwswacj-3{list-style-type:none}.lst-kix_sdy6fqgzk2k7-6>li:before{content:"\0025cf "}ul.lst-kix_hte491cj00mg-2{list-style-type:none}ul.lst-kix_w6ctxtwswacj-0{list-style-type:none}ul.lst-kix_hte491cj00mg-3{list-style-type:none}ul.lst-kix_w6ctxtwswacj-1{list-style-type:none}ul.lst-kix_hte491cj00mg-4{list-style-type:none}ul.lst-kix_hte491cj00mg-5{list-style-type:none}ul.lst-kix_hte491cj00mg-6{list-style-type:none}.lst-kix_z44608xc5z5-4>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-4,lower-latin) ". "}ul.lst-kix_hte491cj00mg-7{list-style-type:none}ul.lst-kix_hte491cj00mg-8{list-style-type:none}.lst-kix_sdy6fqgzk2k7-2>li:before{content:"\0025a0 "}ol.lst-kix_55zebeya5hie-7.start{counter-reset:lst-ctn-kix_55zebeya5hie-7 0}ol.lst-kix_z44608xc5z5-5.start{counter-reset:lst-ctn-kix_z44608xc5z5-5 0}.lst-kix_j6pu4ozg1h9q-8>li:before{content:"\0025a0 "}.lst-kix_jqwplanlf6ac-2>li:before{content:"\0025a0 "}.lst-kix_iun8hna84yne-1>li:before{content:"\0025cb "}.lst-kix_55zebeya5hie-8>li{counter-increment:lst-ctn-kix_55zebeya5hie-8}.lst-kix_rxf8talb6b1y-3>li{counter-increment:lst-ctn-kix_rxf8talb6b1y-3}.lst-kix_eogk2g9lz4ou-6>li{counter-increment:lst-ctn-kix_eogk2g9lz4ou-6}.lst-kix_z44608xc5z5-8>li:before{content:"" counter(lst-ctn-kix_z44608xc5z5-8,lower-roman) ". "}.lst-kix_alogm9c9t96n-7>li:before{content:"\0025cb "}.lst-kix_iun8hna84yne-5>li:before{content:"\0025a0 "}.lst-kix_vgo489ljcome-1>li:before{content:"\0025cb "}.lst-kix_e6cn8ienuo6k-6>li:before{content:"- "}ol{margin:0;padding:0}.c9{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:156.8pt;border-top-color:#000000;border-bottom-style:solid}.c36{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:199.5pt;border-top-color:#000000;border-bottom-style:solid}.c28{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:102.8pt;border-top-color:#000000;border-bottom-style:solid}.c52{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:57.8pt;border-top-color:#000000;border-bottom-style:solid}.c13{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:264.8pt;border-top-color:#000000;border-bottom-style:solid}.c21{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:126pt;border-top-color:#000000;border-bottom-style:solid}.c1{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:284.2pt;border-top-color:#000000;border-bottom-style:solid}.c38{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:78pt;border-top-color:#000000;border-bottom-style:solid}.c59{border-right-style:solid;padding:5pt 5pt 5pt 5pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:468pt;border-top-color:#000000;border-bottom-style:solid}.c29{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:170.2pt;border-top-color:#000000;border-bottom-style:solid}.c35{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:268.5pt;border-top-color:#000000;border-bottom-style:solid}.c44{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:105.8pt;border-top-color:#000000;border-bottom-style:solid}.c5{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:185.2pt;border-top-color:#000000;border-bottom-style:solid}.c48{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:96pt;border-top-color:#000000;border-bottom-style:solid}.c34{border-right-style:solid;padding:5pt 5pt 5pt 5pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:147pt;border-top-color:#000000;border-bottom-style:solid}.c18{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:51pt;border-top-color:#000000;border-bottom-style:solid}.c43{border-right-style:solid;padding:5pt 5pt 5pt 5pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:228.8pt;border-top-color:#000000;border-bottom-style:solid}.c46{border-right-style:solid;padding:5pt 5pt 5pt 5pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:111pt;border-top-color:#000000;border-bottom-style:solid}.c40{border-right-style:solid;padding:2.9pt 2.9pt 2.9pt 2.9pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:269.2pt;border-top-color:#000000;border-bottom-style:solid}.c0{color:#000000;font-weight:normal;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c8{color:#000000;font-weight:normal;text-decoration:none;vertical-align:baseline;font-size:10pt;font-family:"Arial";font-style:normal}.c30{color:#000000;text-decoration:none;vertical-align:baseline;font-size:11pt;font-style:normal}.c7{padding-top:0pt;padding-bottom:0pt;line-height:1.15;text-align:left}.c4{padding-top:0pt;padding-bottom:0pt;line-height:1.0;text-align:left}.c42{border-collapse:collapse;margin-right:auto}.c3{orphans:2;widows:2;direction:ltr}.c57{background-color:#ffffff;max-width:468pt;padding:72pt 72pt 72pt 72pt}.c24{font-size:14pt;font-weight:bold}.c19{padding:0;margin:0}.c23{margin-left:36pt;padding-left:0pt}.c22{margin-left:108pt;padding-left:0pt}.c20{padding-top:8pt;height:10pt}.c26{margin-left:144pt;padding-left:0pt}.c49{margin-left:36pt;text-indent:36pt}.c41{margin-left:72pt;padding-left:0pt}.c10{color:#1155cc;text-decoration:underline}.c17{color:inherit;text-decoration:inherit}.c2{color:#100f0c;text-decoration:underline}.c47{font-size:10pt}.c6{height:11pt}.c54{font-size:11pt}.c58{height:13pt}.c50{text-align:right}.c45{padding-top:0pt}.c37{font-size:8pt}.c56{text-decoration:underline}.c33{height:10pt}.c25{color:#100f0c}.c32{padding-top:8pt}.c12{line-height:1.0}.c39{font-size:9pt}.c14{font-family:"Arial"}.c51{font-style:italic}.c15{height:0pt}.c16{page-break-after:avoid}.c31{font-weight:normal}.c11{font-size:12pt}.c55{padding-bottom:10pt}.c53{height:24pt}.c27{font-weight:bold}.title{padding-top:0pt;color:#000000;font-weight:bold;font-size:24pt;padding-bottom:0pt;font-family:"Arial";line-height:1.15;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:13pt;padding-bottom:10pt;font-family:"Trebuchet MS";line-height:1.15;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:10pt;color:#000000;font-size:16pt;padding-bottom:0pt;font-family:"Trebuchet MS";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:10pt;color:#000000;font-weight:bold;font-size:13pt;padding-bottom:0pt;font-family:"Trebuchet MS";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:8pt;color:#666666;font-weight:bold;font-size:12pt;padding-bottom:0pt;font-family:"Trebuchet MS";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:8pt;color:#666666;text-decoration:underline;font-size:11pt;padding-bottom:0pt;font-family:"Trebuchet MS";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:8pt;color:#000000;font-size:10pt;padding-bottom:0pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:0pt;color:#000000;font-size:10pt;padding-bottom:0pt;font-family:"Courier New";line-height:1.0;page-break-after:avoid;orphans:2;widows:2;text-align:left}</style></head><body class="c57"><p class="c3 title"><a name="h.jym5tjorc2rp"></a><span>Yocto Autobuilder Developers Manual<br></span></p><p class="c3"><span class="c31">Contributors<br></span><span class="c31">Elizabeth Flanagan </span><span>&lt;</span><span class="c10"><a class="c17" href="mailto:elizabeth.flanagan@intel.com">elizabeth.flanagan@intel.com</a></span><span>&gt;</span></p><p class="c3"><span class="c31">California Sullivan &nbsp;</span><span>&lt;</span><span class="c10"><a class="c17" href="mailto:california.l.sullivan@intel.com">california.l.sullivan@intel.com</a></span><span>&gt;</span></p><p class="c3"><span class="c31">Michael Halstead </span><span>&lt;</span><span class="c10"><a class="c17" href="mailto:michael@yoctoproject.org">michael@yoctoproject.org</a></span><span>&gt; </span></p><p class="c3"><span>Bryan Evenson &lt;</span><span class="c10"><a class="c17" href="mailto:bevenson@melinkcorp.com">bevenson@melinkcorp.com</a></span><span>&gt;<br>Stefan Agner &lt;</span><span class="c10"><a class="c17" href="mailto:stefan@agner.ch">stefan@agner.ch</a></span><span>&gt;</span></p><p class="c3"><span>Sipke Vriend &lt;</span><span class="c10"><a class="c17" href="mailto:sipke.vriend@xilinx.com">sipke.vriend@xilinx.com</a></span><span>&gt;</span></p><p class="c3"><span>Tomas Frydrych &lt;</span><span class="c10"><a class="c17" href="mailto:tomas@sleepfive.com">tomas@sleepfive.com</a></span><span>&gt;</span></p><p class="c3"><span>Scott Rifenbark &lt;</span><span class="c10"><a class="c17" href="mailto:scott.m.rifenbark@intel.com">scott.m.rifenbark@intel.com</a></span><span>&gt;</span></p><p class="c3"><span>Tracy Graydon &lt;</span><span class="c10"><a class="c17" href="mailto:tracy.graydon@intel.com">tracy.graydon@intel.com</a></span><span>&gt;</span></p><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Copyright &copy; 2015 Linux Foundation</span></p><p class="c3"><span><br>Coding Standards Section modified from the Yocto Project Development Manual by Scott Rifenbark &lt;</span><span class="c10"><a class="c17" href="mailto:Scott.m.rifenbark@intel.com">scott.m.rifenbark@intel.com</a></span><span>&gt; Copyright &copy; 2010 2014 Linux Foundation<br></span></p><p class="c3"><span>The section on schedulers comes from work initially done by Tomas Frydrych &lt;</span><span class="c10"><a class="c17" href="mailto:tomas@sleepfive.com">tomas@sleepfive.com</a></span><span>&gt; and Bryan Evenson &lt;</span><span class="c10"><a class="c17" href="mailto:bevenson@melinkcorp.com">bevenson@melinkcorp.com</a></span><span>&gt; </span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Permission is granted to copy, distribute and/or modify this document under the terms of the</span><span><a class="c17" href="https://www.google.com/url?q=http://creativecommons.org/licenses/by-sa/2.0/uk/&amp;sa=D&amp;usg=AFQjCNGppO3ltlRjxEgzMQRcuSRF-CqxbQ">&nbsp;</a></span><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://creativecommons.org/licenses/by-sa/2.0/uk/&amp;sa=D&amp;usg=AFQjCNGppO3ltlRjxEgzMQRcuSRF-CqxbQ">Creative Commons Attribution-Share Alike 2.0 UK: England &amp; Wales</a></span><span>&nbsp;as published by Creative Commons. </span></p><p class="c3 c6"><span class="c27"></span></p><p class="c3 c6"><span class="c27"></span></p><a href="#" name="6fc8c91e5e6cccac69232ddf9775e7e2d8f66e4e"></a><a href="#" name="0"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c46" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Commit</span></p></td><td class="c43" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Author(s)</span></p></td><td class="c34" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Date</span></p></td></tr><tr class="c15"><td class="c46" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Initial draft</span></p></td><td class="c43" colspan="1" rowspan="1"><p class="c4 c3"><span>California Sullivan &lt;</span><span class="c10"><a class="c17" href="mailto:california.l.sullivan@intel.com">california.l.sullivan@intel.com</a></span><span class="c0">&gt;<br>Elizabeth Flanagan &lt;elizabeth.flanagan@intel.com&gt;</span></p><p class="c4 c3"><span>Michael Halstead<br>&lt;</span><span class="c10"><a class="c17" href="mailto:michael@yoctoproject.org">michael@yoctoproject.org</a></span><span class="c0">&gt;</span></p></td><td class="c34" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">September 15th 2014</span></p></td></tr><tr class="c15"><td class="c46" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Add GEN_IMG_MD5</span></p></td><td class="c43" colspan="1" rowspan="1"><p class="c4 c3"><span>Elizabeth Flanagan &lt;</span><span class="c10"><a class="c17" href="mailto:elizabeth.flanagan@intel.com">elizabeth.flanagan@intel.com</a></span><span class="c0">&gt;</span></p></td><td class="c34" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">September 29th 2014</span></p></td></tr><tr class="c15"><td class="c46" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Add EAM/AD Info</span></p></td><td class="c43" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Tracy Graydon</span></p><p class="c4 c3"><span>&lt;</span><span class="c10"><a class="c17" href="mailto:tracy.graydon@intel.com">tracy.graydon@intel.com</a></span><span class="c0">&gt;</span></p></td><td class="c34" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">September 9th 2015</span></p></td></tr><tr class="c15"><td class="c46" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Add Large Scale deployment information.</span></p></td><td class="c43" colspan="1" rowspan="1"><p class="c4 c3"><span>Elizabeth Flanagan &lt;</span><span class="c10"><a class="c17" href="mailto:elizabeth.flanagan@intel.com">elizabeth.flanagan@intel.com</a></span><span class="c0">&gt;</span></p></td><td class="c34" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">October 14th 2015</span></p></td></tr></tbody></table><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><p class="c3 c6 c16 subtitle"><a name="h.wx1tk3vobc5e"></a></p><hr style="page-break-before:always;display:none;"><p class="c3 c6 c16 subtitle"><a name="h.qtdfesrl9t67"></a></p><p class="c3 c16 subtitle"><a name="h.campvdj3pgpk"></a><span class="c14">Table of Contents</span></p><ol class="c19 lst-kix_55zebeya5hie-0 start" start="1"><li class="c3 c23"><span>Introduction</span></li><li class="c3 c23"><span>Contributing to the yocto-autobuilder</span></li><li class="c3 c23"><span>Getting Started</span></li><li class="c3 c23"><span>Setting up automated testing</span></li><li class="c3 c23"><span>Introduction to the yocto-autobuilder</span></li><li class="c3 c23"><span>High Level Architectural Overview</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1 start" start="1"><li class="c3 c41"><span>Introduction and Philosophy</span></li><li class="c3 c41"><span>Terminology (Beth but with review from everyone else)</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22"><span>What is a buildset</span></li><li class="c3 c22"><span>What is a factory</span></li><li class="c3 c22"><span>What is a build-worker? </span></li><li class="c3 c22"><span>What is a build-controller?</span></li><li class="c3 c22"><span>What is a scheduler?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-3 start" start="1"><li class="c3 c26"><span>What schedulers do we support?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1" start="3"><li class="c3 c41"><span>What patches we have made to buildbot and why?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22"><span>yoctogit.py</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1" start="4"><li class="c3 c41"><span>What projects are contained within it?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22 c6"><span></span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1" start="5"><li class="c3 c41"><span>Config files</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22"><span>What is the format of the autobuilder.conf file?</span></li><li class="c3 c22"><span>How do I change the global configuration file?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1" start="6"><li class="c3 c41"><span>Buildsets</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22"><span>what is a buildset?</span></li><li class="c3 c22"><span>Is the format of a buildset?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-3 start" start="1"><li class="c3 c26"><span>builders</span></li><li class="c3 c26"><span>repos</span></li><li class="c3 c26"><span>props</span></li><li class="c3 c26"><span>steps</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2" start="3"><li class="c3 c22"><span>How do I create my own buildset?</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1" start="7"><li class="c3 c41"><span>Buildsteps</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22"><span>what is a buildstep?</span></li><li class="c3 c22"><span>what is the format requirements of a buildstep?</span></li><li class="c3 c22"><span>How do I create my own buildstep?</span></li><li class="c3 c22"><span>Buildstep Class Documentation</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1" start="8"><li class="c7 c3 c41"><span>Release JSON</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-2 start" start="1"><li class="c3 c22"><span>(Note: Stub this out. The functionality isn&rsquo;t done yet, but perhaps thinking about how this is all done will manifest it into existence)</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-0" start="7"><li class="c3 c23"><span>Advanced Topics:</span></li></ol><ol class="c19 lst-kix_55zebeya5hie-1 start" start="1"><li class="c3 c41"><span>How do I debug?</span></li><li class="c3 c41"><span>How do I optimize it/make it faster?</span></li><li class="c3 c41"><span>Should I use it </span><span>versus</span><span>&nbsp;another CI solution?</span></li><li class="c3 c41"><span>Are there &ldquo;gotchas&rdquo; in using the yocto autobuilder?</span></li><li class="c3 c41"><span>why Should I use/not use DL_DIR to maintain GPL compliance?</span></li><li class="c3 c41"><span>why Should I use/not use &nbsp;an exposed SSTATE_DIR mirror?</span></li><li class="c3 c41"><span>Do I maintain a large autobuilder cluster?</span></li><li class="c3 c41"><span>Doing embedded Linux distribution releases with the yocto-autobuilder</span></li><li class="c3 c41"><span>Use EAM/AD with yocto-autobuilder?</span></li></ol><hr style="page-break-before:always;display:none;"><p class="c3 c6"><span></span></p><p class="c3 c16 subtitle"><a name="h.2ksayeu0zwky"></a><span class="c14">Introduction</span></p><p class="c3"><span>The yocto-autobuilder is a continuous integration system as well as the build and release tool used by the Yocto Project and its end users. The main purpose of the yocto-autobuilder is to replicate many of the steps that an end user would take to build an embedded Linux distribution, test the build output of a build run and perform most of the Yocto Project release. &nbsp;The current production yocto-autobuilder is found at http://autobuilder.yoctoproject.org/main/<br><br>The core of the yocto-autobuilder is Buildbot, currently at 0.8.8 with a few Yocto Project specific patches. However the yocto-autobuilder is not like most Buildbot implementations. Most Buildbot implementations treat Buildbot as an out of the box CI solution. <br><br>The yocto-autobuilder utilizes Buildbot as set of libraries. Think of the yocto-autobuilder as an abstraction layer around Buildbot that allows you to interact with Buildbot and generate Buildbot configuration files without actually having to know the intricacies around Buildbot. For more information on design philosophies regarding the yocto-autobuilder see the section </span><span class="c51">&ldquo;High Level Architectural Overview: Introduction and Philosophy&rdquo; </span><span><br><br>The yocto-autobuilder was initially written by Richard Purdie &lt;</span><span class="c10"><a class="c17" href="mailto:rp@linuxfoundation.org">richard.purdie@linuxfoundation.org</a></span><span>&gt;. In December 2012, it was entirely rewritten by Elizabeth &lsquo;pidge&rsquo; Flanagan &lt;</span><span class="c10"><a class="c17" href="mailto:elizabeth.flanagan@intel.com">elizabeth.flanagan@intel.com</a></span><span>&gt;, who is the current maintainer. <br><br>The current production Yocto Project yocto-autobuilder infrastructure is maintained by both Elizabeth Flanagan and Michael Halstead &lt;</span><span class="c10"><a class="c17" href="mailto:michael@yoctoproject.org">michael@yoctoproject.org</a></span><span>&gt;. The majority of discussion related to the yocto-autobuilder occurs on the Yocto Project mailing list &lt;</span><span class="c10"><a class="c17" href="mailto:yocto@yoctoproject.org">yocto@yoctoproject.org</a></span><span>&gt; as well as the #yocto channel on FreeNode irc servers.<br><br>The yocto-autobuilder code is licensed under the GNU General Public License version 2 (GPL-2.0). Dependencies packaged with the yocto-autobuilder are licensed under their associated licenses as denoted in the COPYING* files within the yocto-autobuilder root directory.</span></p><p class="c3 c6"><span></span></p><p class="c3 c16 c55 subtitle"><a name="h.yi4ca48vcpk5"></a><span class="c14">Contributing to the yocto-autobuilder</span></p><p class="c3"><span>The yocto-autobuilder is an open source project and as such we welcome community contributions. Because the yocto-autobuilder is extremely configurable and flexible, we recognize that developers will want to extend, configure or optimize it for their specific uses.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>We ask that if you contribute a patch to the yocto-autobuilder that you make the patch as generic as possible. If you have, for example, written a buildstep that is useful to your organization and is probably useful to the overall project, we ask that you make it so that specific things (strings, emails, etc.) that would be specific to your organization are abstracted out into the global configuration file (autobuilder.conf.example).</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>When you send a patch, be sure to include a &quot;Signed-off-by:&quot; line in the same style as required by the Linux kernel. Adding this line signifies that you, the submitter, have agreed to the Developer&#39;s Certificate of Origin 1.1 as follows:</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Developer&#39;s Certificate of Origin 1.1</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;By making a contribution to this project, I certify that:</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(a) The contribution was created in whole or in part by me and I</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;have the right to submit it under the open source license</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indicated in the file; or</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(b) The contribution is based upon previous work that, to the best</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of my knowledge, is covered under an appropriate open source</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;license and I have the right under that license to submit that</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;work with modifications, whether created in whole or in part</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;by me, under the same open source license (unless I am</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;permitted to submit under a different license), as indicated</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in the file; or</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(c) The contribution was provided directly to me by some other</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person who certified (a), (b) or (c) and I have not modified</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(d) I understand and agree that this project and the contribution</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are public and that a record of the contribution (including all</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;personal information I submit with it, including my sign-off) is</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maintained indefinitely and may be redistributed consistent with</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this project or the open source license(s) involved.</span></p><p class="c3"><span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="c3"><span>For each commit, you must provide a single-line summary of the change submitted and you should almost always provide a more detailed description of what you did (i.e. the body of the commit message). The only exceptions for not providing a detailed description would be if your change is a simple, self-explanatory change that needs no further description beyond the summary.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>We recommend that contributors follow the PEP8 Coding Guidelines http://legacy.python.org/dev/peps/pep-0008/ especially with regard to spaces v. tabs (PROTIP: 4 spaces. Always)</span></p><p class="c3 c16 subtitle"><a name="h.doastvd1t2ls"></a><span class="c14">Getting Started</span></p><p class="c3"><span>The quickest method to get a basic yocto-autobuilder instance in place is to do the following:<br></span></p><h6 class="c3 c16"><a name="h.9p9c4o3dqhmk"></a><span class="c14">git clone git://git.yoctoproject.org/yocto-autobuilder<br>cd yocto-autobuilder<br>. ./yocto-autobuilder-setup<br>yocto-start-autobuilder both</span></h6><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>This will set up a basic yocto-autobuilder controller and a single worker on a single machine. The yocto-autobuilder utilizes (generally) a single controller and one or more workers. These systems can be started and stopped independently of each other. In order to start or stop either the worker or controller independently:<br></span></p><h6 class="c3 c16"><a name="h.pr5ymd9g0mr4"></a><span class="c14"><br>. ./yocto-autobuilder-setup<br>yocto-stop-autobuilder worker</span></h6><h6 class="c3 c12 c16"><a name="h.istcggivldtj"></a><span class="c14">yocto-stop-autobuilder controller</span></h6><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><h6 class="c3 c12 c16"><a name="h.ke1bc65w47hl"></a><span class="c14">. ./yocto-autobuilder-setup<br>yocto-start-autobuilder worker</span></h6><h6 class="c3 c12 c16"><a name="h.wpo9jnurjl79"></a><span class="c14">yocto-start-autobuilder controller</span></h6><p class="c3 c6"><span></span></p><p class="c3"><span>Please be aware that you MUST either setup a ~/.bashrc with the contents of ./yocto-autobuilder-setup or make it so that the file is sourced prior to trying to starting or stopping any portion of the yocto-autobuilder.<br></span></p><p class="c3"><span>Do keep in mind that this is a very basic setup, with a single machine, single controller and a single worker utilizing the default buildsets we use for Yocto Project releases. These buildsets are rather large and are meant to be utilized in a large scale cluster.<br><br>Most instances of the yocto-autobuilder are generally part of a large scale infrastructure utilizing many workers. For details on how to set up and maintain large scale yocto-autobuilder infrastructures like this, please see the section &ldquo;</span><span class="c51">Advanced Topics: Maintaining and Setting up yocto-autobuilder clusters.</span><span>&rdquo;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>During the initial run of . ./yocto-autobuilder-setup a generated username and password will be created. This is to ensure that some level of security is enabled during the initial configuration. <br><br>/</span></p><a href="#" name="e8e6272cbd362f7bd467d769160af02b37b52ce8"></a><a href="#" name="1"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c59" colspan="1" rowspan="1"><h6 class="c4 c3 c16"><a name="h.4f106rdknz78"></a><span class="c8">Creating buildset-config from buildset-config.controller</span></h6><h6 class="c4 c3 c33 c16"><a name="h.o4hnmo5f8z11"></a></h6><h6 class="c4 c3 c16"><a name="h.y63owuyqehu6"></a><span class="c8">&nbsp;You&#39;ve not setup the autobuilder before. Generating a username/password</span></h6><h6 class="c4 c3 c16"><a name="h.wbhuzh1o9o3q"></a><span class="c8">&nbsp;combo for you.</span></h6><h6 class="c4 c3 c33 c16"><a name="h.2jzqx6sc42ab"></a></h6><h6 class="c4 c3 c16"><a name="h.4c59e8uktdfv"></a><span class="c8">&nbsp;Username = 4wEWTMh6G</span></h6><h6 class="c4 c3 c16"><a name="h.aeg2537uq8gj"></a><span class="c8">&nbsp;Password = uARwXSBTe</span></h6><h6 class="c4 c3 c33 c16"><a name="h.9tvldpn14pfw"></a></h6><h6 class="c4 c3 c16"><a name="h.hqiucuunsz6q"></a><span class="c8">&nbsp;Modifying the following files with this username/password:</span></h6><h6 class="c4 c3 c33 c16"><a name="h.n2pe9dwqjx3s"></a></h6><h6 class="c4 c3 c16"><a name="h.4npiq3anszjm"></a><span class="c8">&nbsp;/home/pidge/yocto-autobuilder/yocto-controller/controller.cfg</span></h6><h6 class="c4 c3 c16"><a name="h.6ujk481uku2l"></a><span class="c8">&nbsp;/home/pidge/yocto-autobuilder/yocto-worker/buildbot.tac</span></h6><h6 class="c4 c3 c33 c16"><a name="h.we2xzgi2ttwz"></a></h6><h6 class="c4 c3 c16"><a name="h.llaj9impgd1z"></a><span class="c8">&nbsp;If you wish to use your own generated username and password please</span></h6><h6 class="c4 c3 c16"><a name="h.qvh7bg51mqni"></a><span class="c8">&nbsp;modify the above files as needed. Please see the README for more</span></h6><h6 class="c4 c3 c16"><a name="h.dqw6anxrz7oe"></a><span class="c8">&nbsp;information.</span></h6><p class="c4 c3 c6"><a name="h.qbv67e6yvnkn"></a></p></td></tr></tbody></table><h6 class="c3 c33 c16"><a name="h.5z5cb3tmfssd"></a></h6><p class="c3"><span class="c47 c51">Initial setup of the yocto-autobuilder showing automatically generated username and password</span></p><h6 class="c3 c33 c16"><a name="h.e8uhxmssgmu3"></a></h6><p class="c3"><span>This password and username is displayed on the terminal during the initial configuration and is also added to the default configuration files. In order to change the automatically generated usernames and passwords you must edit the yocto-controller/controller.cfg file and the yocto-worker/buildbot.tac file<br><br>&lt;Insert image of files and where to change what&gt;<br></span></p><hr style="page-break-before:always;display:none;"><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><p class="c3 c16 subtitle"><a name="h.hbtu8yu4bn5c"></a><span class="c14">Setting up automated testing</span></p><p class="c3"><span>The yocto-autobuilder has the ability to run the Yocto Project automated test suites. This is run by the RunSanityTests build steps.<br><br>In order to be able to run these, you must set up your workers to be able to run qemu with virtual network tap devices. There are a few ways of setting these up, but probably the best method to do so securely is to utilise the runqemu-gen-tapdevs script in scripts directory of the the poky repo.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span class="c27">Setup prerequisites:</span><span><br> &nbsp; &nbsp; &nbsp;- &nbsp; &nbsp;you will need a checkout of poky (git clone git://git.yoctoproject.org/poky)<br> &nbsp; &nbsp; &nbsp;- &nbsp; &nbsp;you will need a native-sysroot (we suggest building your own or downloading one from the yocto project download site at downloads.yoctoproject.org/releases/yocto)</span></p><ul class="c19 lst-kix_2vtha56u4mwf-0 start"><li class="c3 c23"><span>you will need to disable NetworkManager as it seems to remove tap devs</span></li></ul><p class="c3 c6"><span></span></p><p class="c3"><span>You will need to run the script as root:</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>&nbsp;sudo ./scripts/runqemu-gen-tapdevs &lt;uid of the build user&gt; &lt;gid of the build user&gt; &lt;num of tap devices. we use 24 on our servers&gt; &lt;native-sysroot-basedir&gt;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Once this is complete, you should setup a vnc session and log into it at least once.<br><br>1. Install tight-vnc client and server.</span></p><p class="c3"><span>2. Set up tap devs by running poky/scripts/runqemu-gen-tapdevs</span></p><p class="c3"><span>3. Add &quot;xterm*vt100*geometry: 80x50+10+10&quot; to .Xdefaults</span></p><p class="c3"><span>4. Setup and start vnc session as the autobuilder user.</span></p><p class="c3"><span>5. You MUST manually connect to the vnc session at least once prior to</span></p><p class="c3"><span>&nbsp; &nbsp;running a qemu sanity test (Something is getting set during the initial</span></p><p class="c3"><span>&nbsp; &nbsp;connection that I haven&#39;t figured out yet. Manually connecting seems to</span></p><p class="c3"><span>&nbsp; &nbsp;set up the session correctly.)</span></p><p class="c3 c16 subtitle"><a name="h.hf4hiordgw9a"></a><span class="c14"><br>Introductory use of the yocto-autobuilder</span></p><p class="c3"><span>Following the above steps you should have a functional yocto-autobuilder running on your host system. You should be able to point a web browser to port 8010 of the machine you have set the yocto-autobuilder up on and see a functional autobuilder (i.e. </span><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://localhost:8010&amp;sa=D&amp;usg=AFQjCNF9aARYDQmN-e4hI_YU28rL8ye5HA">http://localhost:8010</a></span><span>&nbsp;or </span><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://myawesomeautobuilder.foo.org:8010&amp;sa=D&amp;usg=AFQjCNFqUYmElBex7_pf2_Gi33xck6Ra6g">http://myawesomeautobuilder.foo.org:8010</a></span><span><a class="c17" href="https://www.google.com/url?q=http://myawesomeautobuilder.foo.org:8010&amp;sa=D&amp;usg=AFQjCNFqUYmElBex7_pf2_Gi33xck6Ra6g">) </a></span></p><p class="c3 c6"><span></span></p><h5 class="c3 c16"><a name="h.eugat8d5osss"></a><span style="overflow: hidden; display: inline-block; margin: -0.00px 0.00px; border: 2.67px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 653.63px; height: 373.50px;"><img alt="openscreen.png" src="images/image01.png" style="width: 653.63px; height: 373.50px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span><span><br>Initial Screen on first startup of the yocto-autobuilder</span></h5><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><p class="c3"><span>If you do not see this screen, a few things may have gone wrong.</span></p><ul class="c19 lst-kix_w6ctxtwswacj-0 start"><li class="c3 c23"><span>Proxy issues/network issues/firewall issues</span></li><li class="c3 c23"><span>The controller never started</span></li></ul><p class="c3"><span><br>For more details on debugging a yocto-autobuilder instance see &ldquo;</span><span class="c51">Advanced Topics: Debugging a broken yocto-autobuilder&rdquo;</span><span><br></span></p><p class="c3 c16 subtitle"><a name="h.s3sfsvc42osf"></a><span class="c14">High Level Architectural Overview</span></p><h2 class="c3 c16 c58"><a name="h.nagxed8fq7sr"></a></h2><h2 class="c3 c16"><a name="h.v1umf6wh8cv"></a><span class="c14">Introduction and Philosophy</span></h2><h6 class="c3 c16 c33"><a name="h.z3mo5bsprul0"></a></h6><p class="c3"><span>The yocto-autobuilder was initially a standard Buildbot implementation. In it&rsquo;s initial incarnation it was a simple 600 line configuration file. As the needs of the Yocto Project grew, the yocto-autobuilder was relied on more and more to support the project. It became apparent in mid-2012 that the initial design of the yocto-autobuilder wasn&rsquo;t flexible enough to deal with the needs of the project.<br><br>The re-write of the yocto-autobuilder started out with a few design goals:</span></p><p class="c3 c6"><span></span></p><ol class="c19 lst-kix_z44608xc5z5-0 start" start="1"><li class="c3 c23"><span>The yocto-autobuilder is not a &lsquo;reference design&rsquo;. It is a product and should be developed as if it were used by those outside the Yocto Project.</span></li><li class="c3 c23"><span>Casual users of the yocto-autobuilder should never have to see the inner workings of Buildbot.</span></li><li class="c3 c23"><span>Developer users of the yocto-autobuilder should have a stable and standard API to utilize that limits the amount of Buildbot knowledge they need to have.</span></li><li class="c3 c23"><span>Code, configuration and buildset definitions will never again be in a single unmaintainable file.</span></li><li class="c3 c23"><span>Conditional buildsteps will always be written at the buildstep layer. We will never utilize doStepIf.</span></li><li class="c3 c23"><span>Buildsteps should have a clearly defined standard.</span></li><li class="c3 c23"><span>Buildset definitions should be written as configuration, not code.</span></li><li class="c3 c23"><span>We will support the ability to build prior Yocto Project releases for a minimum of what was initially a year (we can currently build with minor issues as far back as 1.4)</span></li><li class="c3 c23"><span>The yocto-autobuilder cluster used by the Yocto Project will share between worker nodes as much common data (SSTATE_DIR, DL_DIR) as possible in order to speed up build times.</span></li></ol><p class="c3"><span><br>The current yocto-autobuilder code base has been operational since the 1.3 release. The Yocto Project autobuilder infrastructure consists of a NAS which contains the SSTATE_DIR and DL_DIR common to all builders operating on all workers, one controller and ten physical machines running two to three workers a piece. This allows us to build, test and release, around .25 TB of build artifacts and around 250,000 build artifacts (around 140 images across 17 different MACHINES) in around 3 to 11 hours depending on the size of the changeset being built and the number of things that need to be rebuilt due to the change.</span></p><p class="c3 c6"><span></span></p><h5 class="c3 c16 c20"><a name="h.vx9ilulew8hf"></a></h5><ul class="c19 lst-kix_jqwplanlf6ac-0 start"><li class="c3 c23"><span>Terminology (Beth but with review from everyone else)</span></li></ul><ul class="c19 lst-kix_jqwplanlf6ac-1 start"><li class="c3 c41"><span>What is a build-worker? (Beth)</span></li><li class="c3 c41"><span>What is a build-controller? (Beth)</span></li><li class="c3 c41"><span>What is a scheduler? (Cal)</span></li></ul><ul class="c19 lst-kix_jqwplanlf6ac-2 start"><li class="c3 c22"><span>What schedulers do we support?</span></li></ul><ul class="c19 lst-kix_jqwplanlf6ac-0"><li class="c3 c23"><span>What patches we have made to buildbot and why? (Beth)</span></li></ul><ul class="c19 lst-kix_jqwplanlf6ac-1 start"><li class="c3 c41"><span>yoctogit.py</span></li></ul><ul class="c19 lst-kix_jqwplanlf6ac-0"><li class="c3 c23"><span>What projects are contained within it? (Beth)</span></li></ul><ul class="c19 lst-kix_jqwplanlf6ac-1 start"><li class="c3 c41 c6"><span></span></li></ul><h2 class="c3 c16"><a name="h.om7ekjlsi0z1"></a><span class="c14">Config files</span></h2><h3 class="c3 c16"><a name="h.db796lhd1kp5"></a><span class="c14">What is the format of the autobuilder.conf file?</span></h3><p class="c3"><span>The autobuilder.conf file is used to set autobuilder wide parameters, like where various build<br>artifacts are published to, DL_DIR, SSTATE_DIR or if build artifacts should be<br>published.</span></p><p class="c3 c6"><span></span></p><a href="#" name="d53b2ae8b8588625772cffe614678439c574ecbb"></a><a href="#" name="2"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Field</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Type</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Description</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">OPTIMIZED_GIT_CLONE</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">OGIT_TRASH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory </span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Provides the trash directory.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">OGIT_MIRROR_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory </span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Provides the mirror directory.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">OGIT_TRASH_CRON_TIME</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Crontab input string for ogit trash process</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c3 c7"><span class="c0">OGIT_TRASH_NICE_LEVEL</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">int string </span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Sets the nice level of the ogit trash process.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BUILD_HISTORY_COLLECT</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Turns build history collection on or off.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BUILD_HISTORY_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to use for buildhistory.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BUILD_HISTORY_REPO</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">URL string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Repo to use for buildhistory.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ERROR_REPORT_COLLECT</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Turns error report collection on or off.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ERROR_REPORT_SERVER</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">URL</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Server to send error reports.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ERROR_REPORT_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to store error reports.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PUBLISH_BUILDS</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean </span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Turns build publishing on or off.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PUBLISH_SOURCE_MIRROR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Turns source mirrow publishing on or off.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PUBLISH_SSTATE</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Turns sstate publishing on or off.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">MAINTAIN_PERSISTDB</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Turns persistent database maintaining on or off.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">GEN_IMG_MD5</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">During PublishArtifacts step it will generate and publish the md5sums of the image if True</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">MACHINE_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Subdirectory within BUILD_PUBLISH_DIR to publish machine artifacts.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BA_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Build appliance publishing directory</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">QEMU_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Subdirectory within BUILD_PUBLISH_DIR to publish QEMU artifacts.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RPM_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Subdirectory within BUILD_PUBLISH_DIR to publish RPM artifacts.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">DEB_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Subdirectory to publish debian packages.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">IPK_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Subdirectory within BUILD_PUBLISH_DIR to publish IPK artifacts.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">MARKED_RELEASE_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">No longer used.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADT_INST_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory the adt-installer is published to under DEST</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTQA_INST_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory the QA version of the adt-installer is published to under DEST</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">SSTATE_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to publish sstate.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">SOURCE_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to publish source code.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BUILD_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to publish builds.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RELEASE_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Release directory.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">X86TC_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory the x86 toolchain is published to under DEST</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">X8664TC_PUBLISH_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory the x86-64 toolchain is published to under DEST</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">DL_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to store downloads.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">SSTATE_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to store sstate.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">TMP_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">tmp directory path.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">IMAGE_FSTYPES</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PERSISTDB_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Directory to store the persistdb</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BB_NUMBER_THREADS</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">int string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Sets BB_THREADS in auto.conf</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PARALLEL_MAKE_NUM</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">int string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Number of threads to use while using make.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RESOLVE_TRIGGERED_HEAD</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">We immediately resolve what FETCH_HEAD is for a build and utilize that commit hash for all triggered builds</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">DEVKERNEL_MUT_REPO</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">URL to git repo and list of branches used.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">DEVKERNEL</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Name of dev kernel.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTREPO_POPULATE</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTREPO_DEV_POPULATE</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">boolean</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTREPO_URL</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">URL string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTREPO_PATH</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTREPO_DEV_URL</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">URL string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ADTREPO_DEV_PATH</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">EMGD_DRIVER_DIR</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">WEB_ROOT</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">directory string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Base of web visible directory.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">WEB_URL</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">URL string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">QA_MAIL_TO</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">List of email addresses to send QA email to.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">QA_MAIL_CC</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">List of email addresses to CC QA email to.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">QA_MAIL_BCC</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">List of email addresses to BCC QA email to.</span></p></td></tr><tr class="c15"><td class="c29" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">QA_MAIL_SIG</span></p></td><td class="c18" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">string</span></p></td><td class="c13" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Signature to use in sent emails.</span></p></td></tr></tbody></table><p class="c3 c6"><span></span></p><h3 class="c3 c16"><a name="h.wd202ph67o7"></a><span class="c14">How do I change the global configuration file?</span></h3><p class="c3"><span>Change the values of a field by editing the value to the right of the &lsquo;=&rsquo; sign. Also, some fields may be commented out via a &lsquo;#&rsquo; sign. These can be removed to make the property take effect. Make sure to restart the autobuilder after changing anything in the configuration file.</span></p><p class="c3 c6"><span></span></p><ul class="c19 lst-kix_jqwplanlf6ac-0"><li class="c3 c23"><span>yocto-controller/controller.cfg file</span></li><li class="c3 c23"><span>yocto-worker/buildbot.tac file</span></li></ul><h2 class="c3 c16"><a name="h.vnf90xbhrwjc"></a><span class="c14">Buildsets</span></h2><h3 class="c3 c16"><a name="h.qf6tfuw8jqm0"></a><span class="c14">What is a buildset?</span></h3><p class="c3"><span>A buildset is a configuration file that tells the yocto-autobuilder parser basic information and the buildsteps necessary to create a Buildbot build factory. The buildset directory&rsquo;s contents are parsed during start of the yocto-autobuilder controller and a Buildbot configuration is generated from these files.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Buildset files are essentially python abstract syntax trees.<br></span></p><h6 class="c3 c16"><a name="h.4dbznzj5rggu"></a><span class="c14"><br>[buildset-name]<br>builders: [&#39;example-worker&#39;, &#39;other-example-worker&#39;]<br>repos: [{&#39;poky&#39;:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&#39;repourl&#39;:&#39;git://git.yoctoproject.org/poky&#39;,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;branch&#39;:&#39;daisy&#39;}}]</span></h6><h6 class="c3 c16"><a name="h.5kwvg67t3an5"></a><span class="c14">props: [{&#39;choice-box&#39;:</span></h6><h6 class="c3 c16"><a name="h.5fgu0v85dh0g"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&#39;prop_type&#39;:&#39;ChoiceStringParameter&#39;,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;name&#39;: &#39;choice-box&#39;,</span></h6><h6 class="c3 c16"><a name="h.5g2ekwgm1jfj"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;choice&#39;:[&#39;option-one&#39;, &#39;option-two&#39;],<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;label&#39;:&#39;&lt;hr&gt;&lt;h3&gt;CHOICE_BOX_HEADING:&lt;/h3&gt;&#39;}}]<br>steps: [{&#39;SetDest&#39;:{}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;CheckOutLayers&#39;: {}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;RunPreamble&#39;: {}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;CreateAutoConf&#39;: {&#39;machine&#39;: &#39;example-machine&#39;, &#39;distro&#39;: </span><span class="c14">&#39;poky</span><span class="c14">&#39;}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;CreateBBLayersConf&#39;: {}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;BuildImages&#39;: {&#39;images&#39;: &#39;custom-example-image&#39;}}]</span></h6><h6 class="c3 c16"><a name="h.xd4wdmfmj77e"></a><span class="c14">scheduler: [{&#39;name-of-scheduler&#39;: {&#39;type&#39;:&#39;Nightly&#39;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;repository&#39;:&#39;poky&#39;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;hour&#39;:0,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;minute&#39;:0}}]</span></h6><p class="c3 c6"><span></span></p><p class="c3"><span><br>Buildsets have at least three, possibly five sections within them - builders, repos, props, steps and schedulers with the props and schedulers sections being optional. Buildsets within the buildset-config directory will appear on the waterfall page of the autobuilder.</span></p><h3 class="c3 c16"><a name="h.w3tgcacgyifm"></a><span class="c14">What is the format of a buildset?</span></h3><h4 class="c3 c16"><a name="h.c4lqgy2sahkw"></a><span class="c14">builders</span></h4><p class="c3"><span>A list of workers that a buildset should use. </span><span>If only one worker is being used by the buildset, a string can be used instead of a list.</span></p><p class="c3 c6"><span></span></p><h6 class="c3 c12 c16"><a name="h.f44wht3o5rws"></a><span class="c14">builders: &#39;example-worker&#39;</span></h6><p class="c3 c6"><span></span></p><p class="c3"><span>or</span></p><p class="c3 c6"><span></span></p><h6 class="c3 c16"><a name="h.2ngd9qpgxcos"></a><span class="c14">builders: [&#39;example-worker&#39;, &#39;other-example-worker&#39;]</span></h6><h4 class="c3 c16"><a name="h.em6hs1tnm7lt"></a><span class="c14">repos</span></h4><p class="c3"><span>A list of dictionaries that provides information about the repositories that are needed for a buildset. NOTE: Either the poky or oe-core repository must be listed first in the repos section because anything above them will be deleted when poky or oe-core is re-checked out, as they are the root directories for building.</span></p><p class="c3 c6"><span></span></p><h6 class="c3 c16"><a name="h.bpjmcf9uh9bb"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp;{&#39;name-of-repo&#39;:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&#39;repourl&#39;:&#39;git://path.to/git_repo&#39;,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;layerversion&#39;:&#39;core&#39;,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;checkout&#39;:False,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;branch&#39;:&#39;master&#39;}},</span></h6><p class="c3"><span><br>&lt;Note from Beth: I want a description of each field. &gt;</span></p><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><a href="#" name="209e4464ce1dfe52a3722731ffec524cd25691a6"></a><a href="#" name="3"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Field</span></p></td><td class="c44" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Optional/Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Description</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">repourl</span></p></td><td class="c44" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The repository that a git clone will be attempted from.</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">layerversion</span></p></td><td class="c44" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">checkout</span></p></td><td class="c44" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Defaults to True. If false, the repo&rsquo;s information is loaded but it is not checked out.</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">branch</span></p></td><td class="c44" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The branch of the repository to use.</span></p></td></tr></tbody></table><p class="c3 c6"><span></span></p><h4 class="c3 c16"><a name="h.j33sgw3t462r"></a><span class="c14">props</span></h4><p class="c3"><span>A list of dictionaries that allows you to add custom properties to a build through the web interface. These are abstractions of Buildbot parameters as described in the </span><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://docs.buildbot.net/0.8.8/manual/cfg-schedulers.html?highlight%3Dchoicestringparameter%23forcescheduler-parameters&amp;sa=D&amp;usg=AFQjCNHjw8TzyQZch2kC5e1NzUbX4O4LkQ">ForceSched Parameters</a></span><span>&nbsp;section of the Buildbot manual. The yocto-autobuilder supports the following parameters: </span><span>FixedParameter, StringParameter, BooleanParameter and &nbsp;ChoiceStringParameter.<br><br>We currently do not support: UserNameParameter, IntParameter and TextParameter</span></p><p class="c3 c6"><span></span></p><h6 class="c3 c16"><a name="h.8y09uxyhmcju"></a><span class="c14">props: [{&#39;myname&#39;:{&#39;prop_type&#39;:&#39;ChoiceStringParameter&#39;,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;name&#39;: &#39;myname&#39;,</span></h6><h6 class="c3 c16"><a name="h.42mwfz2rv51u"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;choice&#39;:[&#39;David&#39;,&#39;Jessica&#39;],<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;label&#39;:&#39;&lt;hr&gt;&lt;h3&gt; Your name is?:&lt;/h3&gt;&#39;}}]</span></h6><h5 class="c3 c33 c16"><a name="h.pf05wrnpj1sz"></a></h5><a href="#" name="ec7487d31f43f85448dd3b16849d1b3231f846d1"></a><a href="#" name="4"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Field </span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Optional/Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Description</span></p></td></tr><tr class="c53"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">prop_type</span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required. </span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The type of property to add.</span></p></td></tr><tr class="c15"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">name</span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c3 c4"><span class="c0">Adds custom_&lt;name&gt; to properties. If missing it uses the prop key</span></p></td></tr><tr class="c15"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">choice</span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required if using ChoiceStringParameter</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">A list of choices for ChoiceStringParameter</span></p></td></tr><tr class="c15"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">label</span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The text displayed next to the property on the force build page</span></p></td></tr><tr class="c15"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">default</span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Sets the default selection of a property. If a ChoiceStringParameter, if this is missing, we default to the first entry in the list.</span></p></td></tr><tr class="c15"><td class="c52" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">required</span></p></td><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Defaults to True. If True, a selection is required to start the build (functionality currently broken. Beth, patch this. Also, should Default to False)</span></p></td></tr></tbody></table><p class="c3 c6"><span></span></p><h4 class="c3 c16 c32"><a name="h.3cxfnuu7ilam"></a><span class="c14">steps</span></h4><p class="c3"><span>A list of the buildsteps that are to be done by the buildset, and any parameters that are required by the buildsteps.</span></p><h6 class="c3 c33 c16"><a name="h.5q55yuyfsgws"></a></h6><h6 class="c3 c16"><a name="h.pygwy5w88k7v"></a><span class="c14">steps: [{&#39;SetDest&#39;:{}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;CheckOutLayers&#39;: {}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;RunPreamble&#39;: {}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;CreateAutoConf&#39;: {&#39;machine&#39;: &#39;qemux86&#39;, &#39;distro&#39;: &#39;poky-tiny&#39;}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;CreateBBLayersConf&#39;: {}},<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;BuildImages&#39;: {&#39;images&#39;: &#39;core-image-minimal&#39;}}]</span></h6><p class="c3 c6"><span></span></p><h4 class="c3 c32 c16"><a name="h.ggityiknheep"></a><span class="c14">schedulers:</span></h4><p class="c3"><span>A list of dicts. Each item defines a scheduler associated with this buildset:</span></p><h6 class="c3 c33 c16"><a name="h.vzt5v3r246h5"></a></h6><h6 class="c3 c16"><a name="h.jro17iphjvso"></a><span class="c14">&nbsp; &nbsp; &#39;name_of_scheduler&#39;:<br> &nbsp; &nbsp; &nbsp; &nbsp;{&#39;type&#39;: &#39;Nightly&#39;,</span></h6><h6 class="c3 c16"><a name="h.pjcs10qwili7"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;repo&#39;: &#39;poky&#39;,</span></h6><h6 class="c3 c16"><a name="h.joaedpr66itq"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;hour&#39;: 0,</span></h6><h6 class="c3 c16"><a name="h.29udekf7bojg"></a><span class="c14">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;minute&#39;: 0}</span></h6><h5 class="c3 c16"><a name="h.w2ghdxw00hav"></a><span><br>The scheduler type is specified by the &#39;type&#39; property, where supported values are &#39;Nightly&#39; or &#39;SingleBranchScheduler&#39;, with &#39;Nightly&#39; as the default. Additional properties are used to configure the scheduler and are type-specific:<br><br></span><span class="c27">Nightly scheduler properties:</span></h5><p class="c3 c6"><span></span></p><a href="#" name="095a6afba3165bb677687adebd131eecbcff29e1"></a><a href="#" name="5"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Property</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c14 c27 c30">Required/Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Description</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">month</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The month in which to start the build, with January = 1. This defaults to &#39;*&#39;, meaning every month.</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">dayOfWeek</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The day of the week in which to start the build, with Monday = 1. This defaults to &#39;*&#39;, meaning every day.</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">hour</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The hour of the day in which to start the build, with 12:00 AM = 0.</span></p></td></tr><tr class="c15"><td class="c38" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">minute</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required</span></p></td><td class="c1" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The minute of the hour in which to start the build, with 0 to 59 as valid values.</span></p></td></tr></tbody></table><h5 class="c3 c16"><a name="h.6qrq5vlptfqm"></a><span><br></span><span class="c27">SingleBranchScheduler properties:</span></h5><p class="c3 c6"><span></span></p><a href="#" name="973600197440cdb5920d7726621de039a4b94aca"></a><a href="#" name="6"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c48" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Property</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Optional/Required</span></p></td><td class="c40" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Description</span></p></td></tr><tr class="c15"><td class="c48" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">repository</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Required</span></p></td><td class="c40" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">the repository to attach the scheduler to; this is the repo name from the &#39;repos&#39; section; the branch which &nbsp;the scheduler is attached to matches that in the repo definition.</span></p></td></tr><tr class="c15"><td class="c48" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">stable-timer</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c40" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">how long (in seconds) to wait after change before triggering build to allow for changes to settle.</span></p></td></tr><tr class="c15"><td class="c48" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">change-user</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c40" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">the user name which the remote hook will use; the &nbsp;default value is the repository name as per the &#39;repository&#39; property.</span></p></td></tr><tr class="c15"><td class="c48" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">change-password</span></p></td><td class="c28" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Optional</span></p></td><td class="c40" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">password which the remote hook will use; the default is the buildbot default &#39;changepw&#39; -- if your autobuilder is publically accessible, you want to keep this secret to avoid injection of arbitrary changes into your autobuilder.<br></span></p></td></tr></tbody></table><h5 class="c3 c16"><a name="h.9xpudqajj26x"></a><span><br></span><span class="c27">Extra Notes on SingleBranchScheduler setup</span><span><br></span></h5><p class="c3"><span>There is one SBS scheduler for each repository in the buildset, i.e., if your buildset contains more repositories, and you want build triggered by changes to any of them, you need to define a scheduler for each. This also means that you can mix and match, e.g., only do nightly rebuilds for some repos and immediate for others.<br></span></p><p class="c3"><span>The scheduler change filter is set up to watch changes only in the single repository specified, so you have to set up your repository hook to sent the repository url in the change set with the --repository argument to git_buildbot.py, e.g., your git post-receive &nbsp;hook could look something like:<br></span></p><h6 class="c3 c16"><a name="h.xrluuas8ukd9"></a><span class="c14"><br> &nbsp; &nbsp;#!/bin/sh<br> &nbsp; &nbsp;echo &quot;$1 $2 $3&quot; | git_buildbot.py --repository=&quot;git://some_repo...&quot;<br></span></h6><p class="c3"><span><br>For local testing, you can use a post-merge hook instead, along these lines:</span></p><h6 class="c3 c16"><a name="h.64rcw99ffkjq"></a><span class="c14"><br> &nbsp; &nbsp;#!/bin/sh<br> &nbsp; &nbsp;PRE=$(git rev-parse &#39;HEAD@{1}&#39;)<br> &nbsp; &nbsp;POST=$(git rev-parse HEAD)<br> &nbsp; &nbsp;SYMNAME=$(git rev-parse --symbolic-full-name HEAD)<br> &nbsp; &nbsp;echo &quot;$PRE $POST $SYMNAME&quot; | \<br> &nbsp; &nbsp;git_buildbot.py --repository=&quot;file:///where_your_repo_is&quot;</span></h6><p class="c3"><span><br>Because of the way buildbot change sources work, your change user names must not collide with the user names used by your </span><span>workers. </span><span>.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>If you are using a GitPoller changesource and you specify a valid repository but an non-existent branch, Buildbot will silently ignore your scheduler. If a repository has changed recently but your build has not triggered, validate that your repository and branch settings are valid.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>For either a PBChangeSource or a GitPoller changesource, the scheduler will not see the initial repository discovery as a change. If you are using a SingleBranchScheduler schedule, it is good practice to force a build to verify the buildset works correctly.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Example of PBChangeSource:</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[nightly-x86]</span></p><p class="c3"><span>builders: &#39;builder1&#39;</span></p><p class="c3"><span>repos: [{&#39;poky&#39;:</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;repourl&#39;:&#39;git://git.yoctoproject.org/poky&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;bbpriority&#39;:&#39;1&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;branch&#39;:&#39;master&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;meta-qt3&#39;:</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;repourl&#39;:&#39;git://git.yoctoproject.org/meta-qt3&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;bbpriority&#39;:&#39;2&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;branch&#39;:&#39;master&#39;}}]</span></p><p class="c3"><span>steps: [{&#39;SetDest&#39;:{}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;CheckOutLayers&#39;: {}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;RunPreamble&#39;: {}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;CreateAutoConf&#39;: {&#39;machine&#39;: &#39;qemux86&#39;, &#39;SDKMACHINE&#39; : &#39;i686&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;distro&#39;: &#39;poky&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;CreateBBLayersConf&#39;: {&#39;buildprovider&#39; : &#39;yocto&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;BuildImages&#39;: {&#39;images&#39;: &#39;core-image-sato core-image-sato-dev&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;RunSanityTests&#39;: {&#39;images&#39;: &#39;core-image-minimal core-image-sato&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;PublishArtifacts&#39;: {&#39;artifacts&#39;: [&#39;qemux86&#39;, &#39;atom-pc&#39;]}}]</span></p><p class="c3"><span>scheduler: [{&#39;dev-branch-scheduler&#39; :</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;type&#39;:&#39;SingleBranchScheduler&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;repository&#39;:&#39;poky&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;stable-timer&#39;:30,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;change-password&#39;:&#39;secret_change_password&#39;}}]</span></p><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Example of MultiBranch GitPoller:</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[git-poller]</span></p><p class="c3"><span>builders: &#39;example-worker&#39;</span></p><p class="c3"><span>repos: [{&#39;poky-contrib&#39;:</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;repourl&#39;:&#39;git://git.yoctoproject.org/poky-contrib&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;layerversion&#39;:{&#39;core&#39;:&#39;meta&#39;, &#39;yoctobsp&#39;:&#39;meta-yocto-bsp&#39;},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;branch&#39;:&#39;tgraydon/poky&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;meta-qt3&#39;:</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;repourl&#39;:&#39;git://git.yoctoproject.org/poky-contrib&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;branch&#39;:&#39;tgraydon/meta-qt3&#39;}}]</span></p><p class="c3"><span>steps: [{&#39;SetDest&#39;:{}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;CheckOutLayers&#39;: {}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;RunPreamble&#39;: {}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;GetDistroVersion&#39; : {&#39;distro&#39;: &#39;poky&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;CreateAutoConf&#39;: {&#39;machine&#39;: &#39;qemux86&#39;, &#39;SDKMACHINE&#39; : &#39;i686&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;distro&#39;: &#39;poky&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;CreateBBLayersConf&#39;: {&#39;buildprovider&#39; : &#39;yocto&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;BuildImages&#39;: {&#39;images&#39;: &#39;core-image-sato&#39;}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;PublishLayerTarballs&#39;:{}},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; {&#39;PublishArtifacts&#39;: {&#39;artifacts&#39;: [&#39;qemux86&#39;, &#39;atom-pc&#39;]}}]</span></p><p class="c3"><span>scheduler: [{&#39;git-poller-scheduler&#39;:</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;type&#39;:&#39;SingleBranchScheduler&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;changesource&#39;:&#39;GitPoller&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;repository&#39;:&#39;poky-contrib&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;branch&#39;:&#39;tgraydon/poky&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;interval&#39;:3600},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;stable-timer&#39;:300}}]</span></p><p class="c3"><span>scheduler: [{&#39;git-poller-scheduler&#39;:</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;type&#39;:&#39;SingleBranchScheduler&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;changesource&#39;:&#39;GitPoller&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;repository&#39;:&#39;poky-contrib&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;branch&#39;:&#39;tgraydon/meta-qt3&#39;,</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;interval&#39;:3600},</span></p><p class="c3"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;stable-timer&#39;:300}}]</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Note that the &#39;change-password&#39; property is not used for GitPoller. This </span></p><p class="c3"><span>buildset config may also be found in the build-config.examples directory.</span></p><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><h3 class="c3 c16"><a name="h.fs6mwzkke7xv"></a><span class="c14">How do I create my own buildset?</span></h3><ol class="c19 lst-kix_rxf8talb6b1y-0 start" start="1"><li class="c3 c23"><span>Make a new &lt;buildset-name&gt;.conf file and put it in the buildset-config directory.</span></li><li class="c3 c23"><span>Add the [&lt;buildset-name&gt;] field with a name unique within the buildset-config directory. A best practice is to make the name of the file without the .conf and the name of the buildset the same. Example: foo.conf and [foo]</span></li><li class="c3 c23"><span>Add the workers you want to build with to the builders field.</span></li><li class="c3 c23"><span>Identify the repositories and branches needed to build what you want, and add them to the repos field. Either the poky or oe-core repository must be listed first in the repos section because anything above them will be deleted when poky or oe-core is re-checked out, as they are the root directories for building.</span></li><li class="c3 c23"><span>If it needs any custom properties, add them to the props section.</span></li><li class="c3 c23"><span>Identify the steps that are needed to complete your build. For basic builds, usually at least </span><span class="c47">&#39;SetDest&#39;</span><span>,</span><span class="c47">&nbsp;&#39;CheckOutLayers&#39;</span><span>,</span><span class="c47">&nbsp;&#39;RunPreamble&#39;</span><span>,</span><span class="c47">&nbsp;&#39;CreateAutoConf&#39;</span><span>,</span><span class="c47">&nbsp;&#39;CreateBBLayersConf&#39;</span><span>,</span><span class="c47">&nbsp;and &#39;BuildImages&#39;</span><span>&nbsp;are used. Fill out these and any other relevant steps with the necessary information.</span></li></ol><p class="c3 c6"><span></span></p><h2 class="c3 c16"><a name="h.7q7e3fqn2tp3"></a><span class="c14">Buildsteps</span></h2><p class="c3"><span>A buildstep is a python class used to make BuildBot do a certain task.</span></p><p class="c3"><span>There are a number of buildsteps available by default that will take care of most basic building needs. For other tasks you can create your own buildstep.</span></p><ul class="c19 lst-kix_jqwplanlf6ac-0"><li class="c3 c23"><span class="c27">what is the format requirements of a buildstep? (Beth)</span></li></ul><h3 class="c3 c16"><a name="h.n147nqwecmii"></a><span class="c14">How do I create my own buildstep?</span></h3><p class="c3"><span>Creating your own buildstep is easy as long as you know about a few key functions, variables, and functions to override. First, import ShellCommand from buildbot.steps.shell and use that as your new buildstep&rsquo;s type. For example, class Foo(ShellCommand). Then, use the table below.</span></p><p class="c3 c6"><span></span></p><a href="#" name="b64fb990852e8dc6477fd50e5aec7606a45925a7"></a><a href="#" name="7"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Item</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Purpose</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">__init__(self, factory, argdict=None, **kwargs)</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">The contents of this function will be ran when the builder using this buildstep is initialized. Anything that only needs computed once and is available on startup can be done here.</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">ShellCommand.__init__(self, **kwargs)</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Initializes the buildstep with any arguments in kwargs. Should be called inside def __init__.</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><h6 class="c4 c3 c16"><a name="h.q4ej01figa2j"></a><span class="c54 c14">def start(self)</span></h6></td><td class="c35" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Override this function to make the buildstep do something when the autobuilder gets to this buildstep. If you are using self.command, you will want to call ShellCommand.start() at the end of this function. If start is not overridden, the default ShellCommand.start() is called by itself.</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><h6 class="c4 c3 c16"><a name="h.q4ej01figa2j"></a><span class="c0">self.command</span></h6></td><td class="c35" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">A string of the command(s) to be ran when calling</span></p><p class="c7 c3"><span class="c0">ShellCommand.start().</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">def commandComplete(self, cmd)</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Override this function to make the buildstep do something when ShellCommand.start() completes.</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">cmd.didFail()</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">Useful in commandComplete. Returns whether or not the command failed.</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">self.setProperty(&ldquo;name&rdquo;, value)</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">Sets a builder&rsquo;s &ldquo;name&rdquo; property with &lt;value&gt;. This can be used for communication across buildsteps.</span></p></td></tr><tr class="c15"><td class="c36" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">self.getProperty(&quot;name&quot;)</span></p></td><td class="c35" colspan="1" rowspan="1"><p class="c7 c3"><span class="c0">Gets the builder&rsquo;s &ldquo;name&rdquo; property.</span></p></td></tr></tbody></table><p class="c7 c3 c6"><span></span></p><p class="c3"><span>To take input from a buildset .conf file, use the argdict as shown in other buildsteps. The buildstep will get attributes with the name of keys and the values of the values. For example, if the &ldquo;foo&rdquo;: &ldquo;bar&rdquo; was the input in the buildset, the buildstep would get self.foo=&rdquo;bar&rdquo;. </span></p><p class="c3 c6"><span></span></p><h3 class="c3 c16"><a name="h.q4peqc6rvcl2"></a><span class="c14">Default buildsteps</span></h3><p class="c3 c6"><span></span></p><a href="#" name="67b4a9385858399219ed198527614921011bae18"></a><a href="#" name="8"></a><table cellpadding="0" cellspacing="0" class="c42"><tbody><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Buildstep</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Purpose</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c30 c14 c27">Parameters</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BuildEclipsePlugin</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Runs the Yocto Project Eclipse plugin builder</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&ldquo;images&rdquo;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BuildImages</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Uses Bitbake to build the images listed in the space-separated &#39;images&#39; string.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">BuildToolChainImages</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Runs bitbake&#39;s environment setup script, then runs bitbake to build the toolchain images.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">CheckBSPExists</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Checks whether a board support package exists. If the BSP is no longer supported, the build is stopped without counting as a failure. Otherwise, it continues as usual.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">CheckOutLayers</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Uses git to check out the layers required by the build.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">CreateAutoConf</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Creates the auto.conf file, which sets many properties that are used by bitbake.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;adtdev&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;atext&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;atextappend&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;atextprepend&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;buildapp&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;buildhistory&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;distro&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;emgd&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;initmgr&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;machine&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;multilib&quot;: string or bool</span></p><p class="c4 c3"><span class="c0">&quot;nosstate&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;packages&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;pvr&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;swabber&quot;: bool</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">CreateBBLayersConf</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Creates the bblayers.conf file, which tells bitbake which</span></p><p class="c4 c3"><span class="c0">directories to find the layers required by the build.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;bbtext&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;bbtextappend&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;bbtextprepend&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;bsplayer&quot;: bool</span></p><p class="c4 c3"><span class="c0">&quot;bspprovider&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;buildprovider&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;layerdirs&quot;: [string]</span></p><p class="c4 c3"><span class="c0">&quot;x32abi&quot;: bool</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">CreateCurrentLink</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Deletes &lt;DEST&gt;/../CURRENT/ then creates a symbolic link from &lt;DEST&gt; to &lt;DEST&gt;/../CURRENT/.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">CreateIntelBSPPackage</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Creates Intel&#39;s BSP package.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;machine&quot;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">GetDistroVersion</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Gets the version of the current build&#39;s ditribution if it is poky, oecore, or angstrom. If the distribution is none of these, the build step fails.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;distro&quot;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">GetLayerVersion</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Gets the version number of a layer. If it can not find one, the version number defaults to one. Once the version is found, the corresponding property is set as well.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">HelloWorld</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Simply writes a hello world message into the console.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;lastname&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;name&quot;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">NoOp</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Simply exits with a success status.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PrepPkgIndex</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Copies or links the ipk directory to a tmp directory within the autobuilder so that bitbake package-index can be ran on it.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PublishArtifacts</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Publishes selected items to their respective publish directories.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;artifacts&quot;: [string]</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">PublishLayerTarballs</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Packages a layer as tarballs and publish them in the directory the DEST property points to.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">ResolveLayerHead</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Gets the git commit hash of the layer head, then updates the properties keeping track of the layer head.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RunBitbakeSelftest</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Runs bitbake&#39;s environment setp script followed by bitbake&#39;s self test.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RunOeSelftest</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Runs the bitbake environment setup script, then if the meta-selftest layer exists, oe-selftest is ran. If it doesn&#39;t exist, only the setup script is ran.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RunPreamble</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Runs the bitbake environment setup script. This script is required to be ran before most bitbake functions, and is therefore needed for most building through the autobuilder.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">RunSanityTests</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Runs sanity tests via bitbake&#39;s testimage or qemuimagetest_standalone commands.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;images&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;scene&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;suites&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;suitesappend&quot;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">SendErrorReport</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Sends error reports to a given server.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">SetDest</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Sets the DEST property if it hasn&#39;t been set already.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;target&quot;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Sleep</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Puts the autobuilder to sleep for the inputted number of seconds. In addition, if &quot;funny&quot; is set to &quot;True&quot;, a funny string is shown on the web interface for that buildstep.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&quot;funny&quot;: string</span></p><p class="c4 c3"><span class="c0">&quot;time&quot;: string</span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">TestFailStep</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Completes immediately and exits with a failure status. Its used to test if failing build steps work properly.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3 c6"><span class="c0"></span></p></td></tr><tr class="c15"><td class="c21" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">TriggerBuilds</span></p></td><td class="c5" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">Starts other builds.</span></p></td><td class="c9" colspan="1" rowspan="1"><p class="c4 c3"><span class="c0">&ldquo;schedulerName&rdquo;: string</span></p><p class="c4 c3"><span class="c0">&ldquo;waitForFinish&rdquo;: boolean</span></p><p class="c4 c3"><span class="c0">&ldquo;schedulerNames&rsquo;: {string:{}}</span></p><p class="c4 c3"><span class="c0">&ldquo;schedulerNames_nowait&rsquo;: {string:{}}</span></p></td></tr></tbody></table><p class="c3 c6"><span></span></p><hr style="page-break-before:always;display:none;"><p class="c3 c16 subtitle"><a name="h.ez3seudiwyhm"></a><span class="c14">Advanced Topics and Questions</span></p><h2 class="c3 c16"><a name="h.yhlxm8i0n5b1"></a><span class="c14">Debugging a broken yocto-autobuilder</span></h2><p class="c3 c6"><span></span></p><p class="c3"><span>The first thing you should do is to verify that the controller and workers are up and running:</span></p><p class="c3 c6"><span></span></p><h6 class="c3 c12 c16"><a name="h.sknvp460p8ru"></a><span class="c37 c14">[pidge@fuath yocto-autobuilder]$ ps aux|grep twist</span></h6><h6 class="c3 c12 c16"><a name="h.qi5f1ry0jscm"></a><span class="c37 c14">pidge &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4545 &nbsp;0.1 &nbsp;0.1 1388716 49080 ? &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sl &nbsp; 16:04 &nbsp; 0:01 /usr/bin/python /home/pidge/yocto-autobuilder/bin/twistd --no_save -y buildbot.tac</span></h6><h6 class="c3 c12 c16"><a name="h.mg04etp33ahf"></a><span class="c14 c37">pidge &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4549 &nbsp;0.0 &nbsp;0.0 306340 19292 ? &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sl &nbsp; 16:04 &nbsp; 0:00 /usr/bin/python /home/pidge/yocto-autobuilder/bin/twistd --no_save -y buildbot.tac</span></h6><h6 class="c3 c12 c16"><a name="h.417j4dy4fng7"></a><span class="c37 c14">pidge &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4985 &nbsp;0.0 &nbsp;0.0 112672 &nbsp;2148 pts/0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S+ &nbsp; 16:24 &nbsp; 0:00 grep --color=auto twist</span></h6><p class="c3 c6"><span></span></p><p class="c3"><span>In the above example we see that there are two twistd processes. One should be the controller, the other the worker. The next place we will want to check is the yocto-controller/twistd.log file.</span></p><h5 class="c3 c32 c16"><a name="h.mvtlfawtntuj"></a><span class="c39">./yocto-stop-autobuilder controller; ./yocto-start-autobuilder controller; tail -f yocto-controller/twistd.log</span></h5><h5 class="c3 c32 c16"><a name="h.k651hdex6d9g"></a><span class="c39">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.parseRepos(buildset)<br> &nbsp; &nbsp; &nbsp;File &quot;/home/pidge/yocto-autobuilder/lib/python2.7/site-packages/autobuilder/Autobuilder.py&quot;, line 111, in parseRepos<br> &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for layer in ast.literal_eval(self.configdict[buildset][&#39;repos&#39;]):<br> &nbsp; &nbsp; &nbsp;File &quot;/usr/lib64/python2.7/ast.py&quot;, line 49, in literal_eval<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node_or_string = parse(node_or_string, mode=&#39;eval&#39;)<br> &nbsp; &nbsp; &nbsp;File &quot;/usr/lib64/python2.7/ast.py&quot;, line 37, in parse<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return compile(source, filename, mode, PyCF_ONLY_AST)<br> &nbsp; &nbsp;exceptions.SyntaxError: invalid syntax (&lt;unknown&gt;, line 36) &nbsp; &nbsp;</span></h5><h5 class="c3 c32 c16"><a name="h.23mni4ugh8e1"></a><span class="c39">2014-09-15 16:28:44-0700 [-] Configuration Errors:<br>2014-09-15 16:28:44-0700 [-] &nbsp; error while parsing config file: invalid syntax (&lt;unknown&gt;, line 36) (traceback in logfile)<br>2014-09-15 16:28:44-0700 [-] Halting master.<br>2014-09-15 16:28:44-0700 [-] Main loop terminated.<br>2014-09-15 16:28:44-0700 [-] Server Shut Down.</span></h5><p class="c3"><span><br>In the above log snippet we can see that the yocto-autobuilder threw a SyntaxError around the ability to parse some python AST. This indicates that the issue is somewhere in our buildset configs. This is usually seen if you have failed to add correct notation, for example the colon to indicate a dictionary key:value pair or a comma to split list entries, &nbsp;or you have failed to properly close either quotes, brackets or braces. No matter what, when this error is seen, it is generally an issue with improperly constructed buildsets.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>In the below case, the issue is a bit more obvious to identify and easy to debug</span></p><p class="c3 c6"><span></span></p><h5 class="c3 c16"><a name="h.z0oh3kqan7r"></a><span class="c39">&nbsp; &nbsp; &nbsp; File &quot;/home/pidge/yocto-autobuilder/lib/python2.7/site-packages/autobuilder/BuildSet.py&quot;, line 173, in __init__<br> &nbsp; &nbsp;</span><span class="c39">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c39">m = __import__ (step)<br> &nbsp; &nbsp; &nbsp;File &quot;/home/pidge/yocto-autobuilder/lib/python2.7/site-packages/autobuilder/buildsteps/BuildImages.py&quot;, line 17, in &lt;module&gt;<br> &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;import foobar<br> &nbsp; &nbsp;exceptions.ImportError: No module named foobar</span></h5><h5 class="c3 c16"><a name="h.mt3y7s49lkj3"></a><span class="c39">2014-09-15 16:39:31-0700 [-] Configuration Errors:<br>2014-09-15 16:39:31-0700 [-] &nbsp; error while parsing config file: No module named foobar (traceback in logfile)<br>2014-09-15 16:39:31-0700 [-] Halting master.<br>2014-09-15 16:39:31-0700 [-] Main loop terminated.<br>2014-09-15 16:39:31-0700 [-] Server Shut Down.</span></h5><h5 class="c3 c33 c16"><a name="h.hrtfbgkvsrt3"></a></h5><p class="c3"><span>In this case, we&rsquo;re trying to import a module named foobar into the BuildImages buildstep. It either does not exist or is not in our PYTHONPATH, so the start fails.<br><br>One of the less common issues people run across is a build worker not connecting to the controller. There could be a lot of reasons for this, most of them involving an inability of the worker to connect to the controller port.<br><br>First, check the yocto-worker/twistd.log as well as the yocto-controller/twistd.log. These will generally give you a good idea as to what is going on. Next, check the yocto-worker/buildbot.tac file and ensure that the worker is pointed to the correct controller, port and utilizes the correct password. Lastly, check that the buildsets are referencing the name of the worker as defined in yocto-worker/buildbot.tac.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>TODO:</span></p><p class="c3 c6"><span></span></p><ul class="c19 lst-kix_qrb1a1jgz3rn-0 start"><li class="c3 c23"><span>Yoctogit. The fast git source buildstep. Why we use it, what it does. What does buildjanitor do?</span></li><li class="c3 c23"><span>How do I optimize it/make it faster? (Beth)</span></li><li class="c3 c23"><span>Should I use it verses another CI solution? (Beth)</span></li><li class="c3 c23"><span>Are the &ldquo;gotchas&rdquo; in using the yocto autobuilder? (Cal) And (Beth)</span></li><li class="c3 c23"><span>Why should I use/not use DL_DIR to maintain GPL compliance? (Beth)</span></li><li class="c3 c23"><span>Why should I use/not use &nbsp;an exposed SSTATE_DIR mirror?(Beth)</span></li><li class="c3 c23"><span class="c51">Maintaining and Setting up yocto-autobuilder clusters.</span></li><li class="c3 c23"><span>Doing embedded Linux distribution releases with the yocto-autobuilder(Beth)</span></li></ul><p class="c3 c6"><span></span></p><p class="c3"><span class="c24">Maintaining and Setting up yocto-autobuilder clusters</span></p><p class="c3 c6"><span class="c24"></span></p><p class="c3"><span>The Yocto autobuilder is most useful when deployed in a large organisation. This allows not just a CI solution, but also allows for the autobuilder to provide a source mirror, an sstate mirror for developers to utilize, automated testing, buildhistory and error reporting integration.<br></span></p><p class="c3 c6"><span></span></p><p class="c3"><span class="c27">Example Setup:<br></span></p><p class="c3"><span style="overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 624.00px; height: 381.33px;"><img alt="sclae.png" src="images/image00.png" style="width: 624.00px; height: 381.33px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span><span><br></span></p><p class="c3"><span>In the above image, we have set up a cluster of workers. These workers all point to the same controller. They also share an NFS mount. (NOTE: It is imperative that all workers and the NAS utilize the same UUID as the build user!)<br><br>The workers will utilise the NAS as a shared DL_DIR/SSTATE_DIR. This enables a bit of speedup. It also ensures that we only keep one version of DL_DIR and SSTATE_DIR, thus minimizing disk space.<br><br>We have also mounted the NAS via our webserver and are using the artifacts provided by the autobuilder to populate a Source Mirror, an SSTATE mirror, the QA Build Website and the Release Build Website.<br></span></p><p class="c3"><span class="c27">Setting up a cluster<br><br></span><span>Using the above scenario, we will set up a cluster. We are going to assume for this exercise that the name of the build user is &ldquo;builder&rdquo; and that our mount point to the NAS for all workers and the webserver is &ldquo;/mnt/yab-nas01&rdquo;.<br></span><span class="c27">Setting up the controller:<br></span><span>Git clone the yocto-autobuilder repo and run through the normal setup on your controller.<br>You will want to modify your yocto-controller/controller.cfg to include your workers.<br><br>from buildbot.buildslave import BuildSlave as BuildWorker</span></p><p class="c3"><span>c[&#39;workers&#39;] = [BuildWorker(&quot;worker1&quot;, &quot;password&quot;, max_builds=3),</span></p><p class="c3 c49"><span>BuildWorker(&quot;worker2&quot;, &quot;password&quot;, max_builds=3),</span></p><p class="c3 c49"><span>BuildWorker(&quot;worker3&quot;, &quot;password&quot;, max_builds=3),]</span></p><p class="c3"><span><br>You will also want to modify your config/autobuilder.conf:<br></span></p><p class="c3"><span>[GitSettings]</span></p><p class="c3"><span>OPTIMIZED_GIT_CLONE = True</span></p><p class="c3"><span>#Set the next two lines to somewhere local to the machine</span></p><p class="c3"><span>OGIT_TRASH_DIR = /home/builder/yocto-autobuilder/git/trash</span></p><p class="c3"><span>OGIT_MIRROR_DIR = /home/builder/yocto-autobuilder/git/mirror</span></p><p class="c3"><span>OGIT_TRASH_CRON_TIME = &quot;0 0 * * *&quot;</span></p><p class="c3"><span>OGIT_TRASH_NICE_LEVEL = &quot;19&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[BuildHistorySettings]</span></p><p class="c3"><span>BUILD_HISTORY_COLLECT = True</span></p><p class="c3"><span>BUILD_HISTORY_DIR = &quot;/mnt/yab-nas01/buildhistory&quot;</span></p><p class="c3"><span>BUILD_HISTORY_REPO = &quot;file://///mnt/yab-nas01/buildhistory-repo&quot;</span></p><p class="c3"><span>BUILD_HISTORY_WHITELIST = &quot;{&#39;git://git.yoctoproject.org/poky&#39;:[&#39;master&#39;]}&quot;</span></p><p class="c3"><span>BUILD_HISTORY_WEB = False</span></p><p class="c3"><span>BUILD_HISTORY_WEB_DIR = &quot;/mnt/yab-nas01/buildhistory-web&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[ErrorReportSettings]</span></p><p class="c3"><span>ERROR_REPORT_COLLECT = True</span></p><p class="c3"><span>ERROR_REPORT_SERVER = &quot;http://yourerrorreport.url.com&quot;</span></p><p class="c3"><span>ERROR_REPORT_DIR = &quot;/mnt/yab-nas01/error_logs&quot;</span></p><p class="c3"><span>ERROR_REPORT_EMAIL = &quot;autobuilder@error-report.yourproject.org&quot;</span></p><p class="c3"><span>ERROR_REPORT_NAME = &quot;MyProject Autobuilder&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[PublishSettings]</span></p><p class="c3"><span>PUBLISH_BUILDS = True</span></p><p class="c3"><span>PUBLISH_SOURCE_MIRROR = False</span></p><p class="c3"><span>PUBLISH_SSTATE = False</span></p><p class="c3"><span>MAINTAIN_PERSISTDB = True</span></p><p class="c3"><span>GEN_IMG_MD5 = True</span></p><p class="c3"><span>MACHINE_PUBLISH_DIR = &quot;machines&quot;</span></p><p class="c3"><span>BA_PUBLISH_DIR = &quot;build-appliance&quot;</span></p><p class="c3"><span>QEMU_PUBLISH_DIR = &quot;/machines/qemu&quot;</span></p><p class="c3"><span>RPM_PUBLISH_DIR = &quot;rpm&quot;</span></p><p class="c3"><span>DEB_PUBLISH_DIR = &quot;deb&quot;</span></p><p class="c3"><span>IPK_PUBLISH_DIR = &quot;ipk&quot;</span></p><p class="c3"><span>MARKED_RELEASE_DIR = &quot;releases&quot;</span></p><p class="c3"><span>ADT_INST_PUBLISH_DIR = &quot;adt-installer&quot;</span></p><p class="c3"><span>ADTQA_INST_PUBLISH_DIR = &quot;adt-installer-QA&quot;</span></p><p class="c3"><span>SSTATE_PUBLISH_DIR = &quot;/mnt/yab-nas01/sstate_mirror&quot;</span></p><p class="c3"><span>SOURCE_PUBLISH_DIR = &quot;/mnt/yab-nas01/source&quot;</span></p><p class="c3"><span>BUILD_PUBLISH_DIR = &quot;/mnt/yab-nas01/builds&quot;</span></p><p class="c3"><span>RELEASE_PUBLISH_DIR = &quot;/mnt/yab-nas01/releases&quot;</span></p><p class="c3"><span>X86TC_PUBLISH_DIR = &quot;toolchain/i686&quot;</span></p><p class="c3"><span>X8664TC_PUBLISH_DIR = &quot;toolchain/x86_64&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[ToasterSettings]</span></p><p class="c3"><span>TOASTER_UPLOAD_URL = &quot;http://localhost:8000/orm/eventfile&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[BuildSettings]</span></p><p class="c3"><span>DL_DIR = &quot;/mnt/yab-nas01/downloads&quot;</span></p><p class="c3"><span>SSTATE_DIR = &quot;/mnt/yab-nas01/sstate&quot;</span></p><p class="c3"><span>IMAGE_FSTYPES = &quot; tar.gz&quot;</span></p><p class="c3"><span>PERSISTDB_DIR = &quot;/home/builder/persistdb&quot;</span></p><p class="c3"><span>BB_NUMBER_THREADS = &quot;16&quot;</span></p><p class="c3"><span>PARALLEL_MAKE_NUM = &quot;16&quot;</span></p><p class="c3"><span>RESOLVE_TRIGGERED_HEAD = True</span></p><p class="c3"><span>DEVKERNEL_MUT_REPO = &quot;{&#39;git://git.yoctoproject.org/poky-contrib&#39;:[&#39;stage/master_under_test&#39;, &#39;sgw/mut&#39;]}&quot;</span></p><p class="c3"><span>DEVKERNEL = &quot;linux-yocto-dev&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[ADTREPO Settings]</span></p><p class="c3"><span>ADTREPO_POPULATE = False</span></p><p class="c3"><span>ADTREPO_DEV_POPULATE = True</span></p><p class="c3"><span>ADTREPO_URL = &quot;http://adtrepo.yoctoproject.org/&quot;</span></p><p class="c3"><span>ADTREPO_PATH = &quot;/tmp/adtrepo.yoctoproject.org/&quot;</span></p><p class="c3"><span>ADTREPO_DEV_URL = &quot;http://adtrepo-dev.yoctoproject.org/&quot;</span></p><p class="c3"><span>ADTREPO_DEV_PATH = &quot;/tmp/adtrepo-dev/&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[WebServer]</span></p><p class="c3"><span>WEB_ROOT = &quot;/var/www/&quot;</span></p><p class="c3"><span>WEB_URL = &quot;http://mycoolproject.org/&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>[QAEmail]</span></p><p class="c3"><span>QA_MAIL_TO = &quot;root@localhost otherperson@localhost&quot;</span></p><p class="c3"><span>QA_MAIL_CC = &quot;buildcc@localhost&quot;</span></p><p class="c3"><span>QA_MAIL_BCC = &quot;buildbcc@localhost&quot;</span></p><p class="c3"><span>QA_MAIL_SIG = &quot;Multiline\nSig\nLine&quot;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span class="c27">Note: You must use this config for each build worker.<br></span></p><p class="c3"><span>You will now need to ensure that all your buildset-config files use the correct builders. Modify the &lsquo;builders:&rsquo; field to have a list of builders. e.g.:<br><br>builders: [&lsquo;worker1&rsquo;, &lsquo;worker2&rsquo;, &lsquo;worker3&rsquo;]</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>At this point you should be ready to set up each worker. You will need to copy the autobuilder.conf to each workers config dir, set up each worker with the correct builder name and password in the yocto-worker/buildbot.tac file and then start each worker and allow them to connect to the controller.<br><br></span><span class="c27">Notes:<br></span><span><br>- It is probably not a bad idea to have a cron job sync the results of your autobuilder DL_DIR to another directory. This ensures a source history that will keep you from losing any previously built source.<br><br>- It&rsquo;s also not a bad idea to set up cron jobs to clean up artifacts. Full adt-repos and releases can be fairly large (in the TB range and doing it multiple times a day can cause issues)<br><br>- If you are running qemu based sanity tests, you will need to ensure that you set up each worker to be able to run sanity testing. Please ensure you have enough tapdevs. For each worker that runs 3 builds concurrently we generally set up 24 tapdevs with runqemu-gen-tapdevs.<br><br>- From an IP protection standpoint, if you are building protected IP source, you do not want to expose your DL_DIR and SSTATE_DIR outside of your organisation.<br></span></p><p class="c3 c12"><span class="c24">Using EAM/AD with Yocto-Autobuilder</span></p><p class="c3"><span>In the current version of yocto-autobuilder (Buildbot 0.8.8), using EAM/AD for authentication must be done via reverse proxy and Kerberos. Later versions of Buildbot are able to use LDAP for authentication but this is not implemented in 0.8.8. Hence, for this example configuration, reverse proxy and Kerberos are used here.</span></p><p class="c3 c6"><span></span></p><p class="c3 c12"><span>This example configuration is based on a Fedora 20 installation running Apache. This is also a &ldquo;workstation&rdquo; configuration. That is, it is assumed that one is trying to connect to a corporate or similar EAM/AD setup, and that the Kerberos server is running elsewhere. &nbsp;Therefore, this documentation does not cover setting up a Kerberos server.</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span class="c11 c27">Set Up the Reverse Proxy for Apache</span></p><p class="c3 c6 c12"><span class="c11 c27"></span></p><p class="c3 c12"><span class="c54">Setting up the reverse proxy is simple, and details are available here:</span></p><p class="c3 c12"><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://httpd.apache.org/docs/2.0/mod/mod_proxy.html%23forwardreverse&amp;sa=D&amp;usg=AFQjCNEOOxKhmYSu4Uc6qy_5UUZxbljtFQ">http://httpd.apache.org/docs/2.0/mod/mod_proxy.html - forwardreverse</a></span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>You do not need to enable the forward proxy just to use reverse proxy. If you don&rsquo;t need to use the forward proxy, it is best to disable it for the sake of security. &nbsp;</span></p><p class="c3 c12"><span>To enable the reverse proxy only, add a section like this to your httpd.conf file.</span></p><p class="c3 c6 c45 c12"><span></span></p><p class="c3 c45 c12"><span>ProxyRequests Off</span></p><p class="c3 c6 c12 c45"><span></span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c45 c12"><span>&lt;Proxy *&gt;</span></p><p class="c3 c45 c12"><span>&nbsp; &nbsp;Order deny,allow</span></p><p class="c3 c45 c12"><span>&nbsp; &nbsp;Allow from all</span></p><p class="c3 c45 c12"><span>&lt;/Proxy&gt;</span></p><p class="c3 c6 c45 c12"><span></span></p><p class="c3 c45 c12"><span>ProxyPass /buildbot/ http://myhost.somewhere.com:8010/</span></p><p class="c3 c45 c12"><span>ProxyPassReverse /buildbot/ http://myhost.somewhere.com:8010/ </span></p><p class="c3 c12"><span>Be mindful of the trailing slashes. If your autobuilder webStatus page doesn&rsquo;t load, you have likely mismatched your slashes. Note that the port here is the autobuilder default. Adjust yours accordingly. This also assumes that Apache is running on the default port of 80.</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>Once you have that in place stop and restart Apache to load the new config.</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span class="c11">Edit the Autobuilder Config</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>Now you need to tell the autobuilder about this change by editing yocto-autobuilder/yocto-controller/controller.cfg. &nbsp;In the section labeled &ldquo;PROJECT IDENTITY,&rdquo; you need to set the URLs to correspond to your reverse proxy settings.</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>Example:</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3 c12"><span>####################</span></p><p class="c3 c12"><span># PROJECT IDENTITY #</span></p><p class="c3 c12"><span>####################</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>&lt;snip&gt;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>c[&#39;title&#39;] = &quot;The Yocto Autobuilder&quot;</span></p><p class="c3 c12"><span>c[&#39;titleURL&#39;] = &quot;http://myhost.somewhere.com:8010/buildbot/&quot;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span># the &#39;buildbotURL&#39; string should point to the location where the buildbot&#39;s</span></p><p class="c3 c12"><span># internal web server (usually the html.WebStatus page) is visible. This</span></p><p class="c3 c12"><span># typically uses the port number set in the Waterfall &#39;status&#39; entry, but</span></p><p class="c3 c12"><span># with an externally-visible host name which the buildbot cannot figure out</span></p><p class="c3 c12"><span># without some help.</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>c[&#39;buildbotURL&#39;] = &quot;http://myhost.somewhere.com:8010/buildbot/&quot;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>Note that this matches the URL in the reverse proxy config. If you drop a trailing slash here, your autobuilder page will not likely come up, or subpages will not come up properly.</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>Also note that the default for c[&#39;titleURL&#39;] uses https. If you are not using https as your buildbotURL, you&rsquo;ll want to change that.</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>Once this config is complete, you should now be able to load your autobuilder webStatus page, and subpages (waterfall, grid, buiders, etc.) using the newly defined URL: http://myhost.somewhere.com/buildbot</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span class="c11">Configure Kerberos</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3 c12"><span class="c25">Kerberos documentation may be found at</span><span class="c2"><a class="c17" href="https://www.google.com/url?q=http://web.mit.edu/kerberos/krb5-latest/doc/&amp;sa=D&amp;usg=AFQjCNEpowNezSNoamflGo5lCA3MDa2u0Q">&nbsp;</a></span><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://web.mit.edu/kerberos/krb5-latest/doc/&amp;sa=D&amp;usg=AFQjCNEpowNezSNoamflGo5lCA3MDa2u0Q">http://web.mit.edu/kerberos/krb5-latest/doc/</a></span><span class="c25">. </span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span class="c25">Fedora&rsquo;s Security guide at</span><span class="c2"><a class="c17" href="https://www.google.com/url?q=https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html&amp;sa=D&amp;usg=AFQjCNFMHurwESBlDwinrX4NMX2JUxlSNg">&nbsp;</a></span><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html&amp;sa=D&amp;usg=AFQjCNFMHurwESBlDwinrX4NMX2JUxlSNg">https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html</a></span></p><p class="c3 c6 c12"><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html&amp;sa=D&amp;usg=AFQjCNFMHurwESBlDwinrX4NMX2JUxlSNg"></a></span></p><p class="c3 c12"><span class="c25">A CentOS guide:</span><span class="c2"><a class="c17" href="https://www.google.com/url?q=https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-kerberos-server.html&amp;sa=D&amp;usg=AFQjCNGyP3-LBz32pZ7HKXvQJFwqhNux1Q">&nbsp;</a></span><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-kerberos-server.html&amp;sa=D&amp;usg=AFQjCNGyP3-LBz32pZ7HKXvQJFwqhNux1Q">https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-kerberos-server.html</a></span></p><p class="c3 c6 c12"><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-kerberos-server.html&amp;sa=D&amp;usg=AFQjCNGyP3-LBz32pZ7HKXvQJFwqhNux1Q"></a></span></p><p class="c3 c12"><span>Detailed explanations of commands, etc., are available in the above references. Please refer to the documentation for a more info on the various steps/commands. Obviously, the first step is to install the required packages: krb5-libs, krb5-server, and krb5-workstation and any missing dependencies.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>You will also need a working krb5.conf configuration or have the information know to create one.</span></p><p class="c3 c6"><span></span></p><p class="c3"><span class="c56">Example krb5.conf file</span><span>:</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3 c12"><span>[logging]</span></p><p class="c3 c12"><span>&nbsp; default = FILE:/var/log/krb5libs.log</span></p><p class="c3 c12"><span>&nbsp; kdc = FILE:/var/log/krb5kdc.log</span></p><p class="c3 c12"><span>&nbsp; admin_server = FILE:/var/log/kadmind.log</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>[libdefaults]</span></p><p class="c3 c12"><span>&nbsp; default_realm = CORP.FOO.COM</span></p><p class="c3 c12"><span>&nbsp; dns_lookup_realm = false</span></p><p class="c3 c12"><span>&nbsp; dns_lookup_kdc = false</span></p><p class="c3 c12"><span>&nbsp; ticket_lifetime = 24h</span></p><p class="c3 c12"><span>&nbsp; renew_lifetime = 7d</span></p><p class="c3 c12"><span>&nbsp; forwardable = yes</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>[realms]</span></p><p class="c3 c12"><span>&nbsp;CORP.FOO.COM = {</span></p><p class="c3 c12"><span>&nbsp; kdc = CORP.FOO.COM:88</span></p><p class="c3 c12"><span>&nbsp; admin_server = corp.foo.com:&lt;port&gt;</span></p><p class="c3 c12"><span>&nbsp; default_domain = corp.foo.com</span></p><p class="c3 c12"><span>&nbsp;}</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>[domain_realm]</span></p><p class="c3 c12"><span>.example.com = CORP.FOO.COM</span></p><p class="c3 c12"><span>example.com = CORP.FOO.COM</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Next, create the database using the kdb5_util command:</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>$ kdb5_util create &ndash;s</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>Then edit /var/Kerberos/krb5kdc/kadm5.acl. You should be able to use something along the lines of:</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>*/admin@EXAMPLE.COM &nbsp;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>Now you can create the first principal by running:</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>$ kadmin.local &ndash;q &ldquo;addprinc &lt;username&gt;/admin&rdquo;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>Once you have completed that, start the services:</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>$ service krb5kdc start</span></p><p class="c3 c12"><span>$ service kadmin start</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>Now run kinit to test:</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>$ kinit &lt;username&gt;</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3 c12"><span>You should be prompted for the user password, which should authenticate successfully using the user&rsquo;s EAM/AD password.</span></p><p class="c3 c6 c12"><span></span></p><p class="c3 c12"><span>You should now also have an /etc/krb.keytab file. You will need this for the Apache and the autobuilder to authenticate against.</span></p><p class="c3 c12"><span>&nbsp;</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span class="c11">Revisit Apache Conf</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Apache needs to be configured to use Kerberos for authentication. You will need to add something similar to this to your httpd.conf file:</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&lt;Location &quot;/&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p><p class="c3"><span>&nbsp; AuthType Kerberos</span></p><p class="c3"><span>&nbsp; AuthName &quot;Buildbot&quot;</span></p><p class="c3"><span>&nbsp; KrbMethodNegotiate On</span></p><p class="c3"><span>&nbsp; KrbMethodK5Passwd On</span></p><p class="c3"><span>&nbsp; KrbAuthRealms CORP.FOO.COM</span></p><p class="c3"><span>&nbsp; KrbVerifyKDC off</span></p><p class="c3"><span>&nbsp; KrbServiceName Any</span></p><p class="c3"><span>&nbsp; Krb5KeyTab /etc/krb.keytab</span></p><p class="c3"><span>&nbsp; KrbSaveCredentials Off</span></p><p class="c3"><span>&nbsp; require valid-user</span></p><p class="c3"><span>&nbsp; Order allow,deny</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&nbsp; Satisfy Any</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&nbsp; #] SSO</span></p><p class="c3"><span>&nbsp; RewriteEngine On</span></p><p class="c3"><span>&nbsp; RewriteCond %{LA-U:REMOTE_USER} (.+)$</span></p><p class="c3"><span>&nbsp; RewriteRule . - [E=RU:%1,NS]</span></p><p class="c3"><span>&nbsp; RequestHeader set REMOTE_USER %{RU}e</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&lt;/Location&gt;</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Adjust the path to your krb.keytab file and Realm accordingly.</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Note:</span><span class="c25">&nbsp;This config is copied straight from</span><span class="c2"><a class="c17" href="https://www.google.com/url?q=http://docs.buildbot.net/latest/manual/cfg-www.html&amp;sa=D&amp;usg=AFQjCNFzV5K-aZtLzktAUhNHDhu_YZjr3A">&nbsp;</a></span><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://docs.buildbot.net/latest/manual/cfg-www.html&amp;sa=D&amp;usg=AFQjCNFzV5K-aZtLzktAUhNHDhu_YZjr3A">http://docs.buildbot.net/latest/manual/cfg-www.html</a></span><span class="c25">&nbsp;with minor adjustments to genericize the Realm and path to the keytab file. Be aware that this doc is for a newer version of BuildBot and the backend auth component has been significantly rewritten. While this Apache conf works, the other configuration information (for plugins, etc) in this doc is NOT implemented in 0.8.8.</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Restart httpd services to pick up the new config.</span></p><p class="c3 c6"><span></span></p><p class="c3 c6"><span></span></p><p class="c3"><span class="c25">Revisit Autobuilder Config</span></p><p class="c7 c3"><span class="c25">&nbsp;</span></p><p class="c7 c3"><span class="c25">Lastly, revisit the autobuilder config to set the path to the krb.keytab file. In the &ldquo;STATUS TARGETS&rdquo; section of yocto-controller/controller.cfg, adjust the path accordingly. Change the line:</span></p><p class="c7 c3 c6"><span class="c25"></span></p><p class="c7 c3"><span class="c25">authz_cfg=Authz(auth=HTPasswdAuth(&#39;&#39;&lt;HTPASSWDPATH&gt;&#39;),</span></p><p class="c7 c3"><span class="c25">&nbsp;</span></p><p class="c7 c3"><span class="c25">to</span></p><p class="c7 c3"><span class="c25">&nbsp;</span></p><p class="c7 c3"><span class="c25">authz_cfg=Authz(auth=HTPasswdAuth(&#39;&#39;/etc/krb.keytab&#39;), </span></p><p class="c7 c3"><span class="c25">&nbsp;</span></p><p class="c7 c3"><span class="c25">(Or whatever the correct path and filename is for your setup.)</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Example:</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>###################</span></p><p class="c3"><span># STATUS TARGETS #</span></p><p class="c3"><span>###################</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>&lt;snip&gt;</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>c[&#39;status&#39;] = []</span></p><p class="c3"><span>from buildbot.status.html import WebStatus</span></p><p class="c3"><span>from buildbot.status.web.authz import Authz</span></p><p class="c3"><span>from buildbot.status.web.auth import HTPasswdAuth</span></p><p class="c3"><span>authz_cfg=Authz(auth=HTPasswdAuth(&#39;/etc/krb.keytab&#39;),</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;forceBuild = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stopBuild = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stopAllBuilds = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cancelAllPendingBuilds = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cancelPendingBuild = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gracefulShutdown = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;forceAllBuilds = False,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stopChange = False,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanShutdown = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;showUsersPage = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pauseSlave = &#39;auth&#39;,</span></p><p class="c3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pingBuilder = False)</span></p><p class="c3"><span>c[&#39;status&#39;].append(WebStatus(http_port=8010, authz=authz_cfg))</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>You should now be prompted for your EAM/AD username and password when accessing your autobuilder. </span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span class="c11">References</span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Kerberos Documentation:</span></p><p class="c3"><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://web.mit.edu/kerberos/krb5-latest/doc/&amp;sa=D&amp;usg=AFQjCNEpowNezSNoamflGo5lCA3MDa2u0Q">http://web.mit.edu/kerberos/krb5-latest/doc/</a></span><span class="c25">. </span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Fedora&rsquo;s Security Guide:</span></p><p class="c3"><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html&amp;sa=D&amp;usg=AFQjCNFMHurwESBlDwinrX4NMX2JUxlSNg">https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html</a></span></p><p class="c3 c6"><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://docs.fedoraproject.org/en-US/Fedora/19/html/Security_Guide/sect-Security_Guide-Kerberos-Configuring_a_Kerberos_5_Client.html&amp;sa=D&amp;usg=AFQjCNFMHurwESBlDwinrX4NMX2JUxlSNg"></a></span></p><p class="c3"><span>CentOS Guide:</span></p><p class="c3"><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-kerberos-server.html&amp;sa=D&amp;usg=AFQjCNGyP3-LBz32pZ7HKXvQJFwqhNux1Q">https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-kerberos-server.html</a></span></p><p class="c3"><span>&nbsp;</span></p><p class="c3"><span>Apache mod_proxy:</span></p><p class="c3"><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://httpd.apache.org/docs/2.0/mod/mod_proxy.html%23forwardreverse&amp;sa=D&amp;usg=AFQjCNEOOxKhmYSu4Uc6qy_5UUZxbljtFQ">http://httpd.apache.org/docs/2.0/mod/mod_proxy.html - forwardreverse</a></span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Buildbot 0.8.8 Documentation:</span></p><p class="c3"><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://docs.buildbot.net/0.8.8/index.html&amp;sa=D&amp;usg=AFQjCNGR49KMI4YiHgb0RhWaqCjRhi52yg">http://docs.buildbot.net/0.8.8/index.html</a></span><span class="c25">&nbsp;</span></p><p class="c3 c6"><span></span></p><p class="c3"><span>Buildbot Latest Documentation with Apache config for using Kerberos:</span></p><p class="c3"><span class="c10"><a class="c17" href="https://www.google.com/url?q=http://docs.buildbot.net/latest/manual/cfg-www.html&amp;sa=D&amp;usg=AFQjCNFzV5K-aZtLzktAUhNHDhu_YZjr3A">http://docs.buildbot.net/latest/manual/cfg-www.html</a></span></p><p class="c3 c6"><span class="c10"></span></p><p class="c3"><span>RunningLight lcnc-buildbot Reverse Proxy with Debian/Ubuntu examples:</span></p><p class="c3 c12"><span class="c10"><a class="c17" href="https://www.google.com/url?q=https://github.com/RunningLight/lcnc-buildbot/blob/master/HOW-TO-reverse-proxy&amp;sa=D&amp;usg=AFQjCNFc6u5rG9fmE5fAUkweude7TGVZhA">https://github.com/RunningLight/lcnc-buildbot/blob/master/HOW-TO-reverse-proxy</a></span></p><p class="c3 c6 c12"><span></span></p><div><p class="c3 c6 c50"><span></span></p></div></body></html>
diff --git a/docs/images/image00.png b/docs/images/image00.png
deleted file mode 100644
index fba7ddbb..00000000
--- a/docs/images/image00.png
+++ /dev/null
Binary files differ
diff --git a/docs/images/image01.png b/docs/images/image01.png
deleted file mode 100644
index 969d3bb8..00000000
--- a/docs/images/image01.png
+++ /dev/null
Binary files differ
diff --git a/etc/distro-version/Meego-1.1 b/etc/distro-version/Meego-1.1
deleted file mode 100644
index c6d9ffbf..00000000
--- a/etc/distro-version/Meego-1.1
+++ /dev/null
@@ -1,1424 +0,0 @@
-aaa-meego-accelerator
-abattis-cantarell-fonts
-acct
-acl
-acpid
-adns
-alsa-lib
-alsa-plugins
-alsa-utils
-anerley
-anthy
-apr
-apr-util
-aria2
-asciidoc
-aspell
-aspell-en
-atk
-atproxy
-attica
-attr
-audiofile
-augeas
-autoconf
-autoconf213
-autogen
-automake
-automake14
-automake17
-automoc4
-autotrace
-avahi
-babl
-baekmuk-ttf-fonts
-banshee
-banshee-1-branding-meego
-basesystem
-bash
-bash-x86
-bc
-bcm-bt-firmware
-binutils
-bisho
-bison
-bitmap
-bitstream-vera-fonts
-bluetooth-ivi
-bluetooth-qt
-bluez
-bme-rx-51-bin
-boardname
-boost
-bootchart
-bootstub
-btrfs-progs
-bugle
-build
-build-compare
-busybox
-buteo-sync-plugin-google
-buteo-sync-plugins
-buteo-syncfw
-buteo-syncml
-byacc
-bzip2
-bzip2-libs-x86
-bzip2-x86
-c-ares
-ca-certificates
-cabextract
-cairo
-calligra
-catdoc
-ccache
-cdrkit
-cedevicemanager
-cglaunch
-check
-cheese
-chrome-meego-extension
-chromium
-chrpath
-chunckfive-accents-fonts
-cjkuni-fonts
-clean-device
-cloog
-clutter
-clutter-box2d
-clutter-gesture
-clutter-gst
-clutter-gtk
-clutter-imcontext
-cmake
-cmake-gui
-compat-libstdc++-33
-compat-telepathy-qt4
-compface
-connman
-connman-qt
-ConsoleKit
-contacts
-contactsd
-contextkit
-contextkit-maemo
-contextkit-meego
-coreutils
-coreutils-x86
-corewatcher
-corkscrew
-cpio
-cppcheck
-cppunit
-crashsplash
-crda
-createrepo
-cronie
-crontabs
-cross-armv5tel-binutils
-cross-armv5tel-binutils-accel
-cross-armv5tel-gcc
-cross-armv5tel-gcc-accel
-cross-armv7hl-binutils
-cross-armv7hl-binutils-accel
-cross-armv7hl-gcc
-cross-armv7hl-gcc-accel
-cross-armv7l-binutils
-cross-armv7l-binutils-accel
-cross-armv7l-gcc
-cross-armv7l-gcc-accel
-cross-armv7l-platformfile
-cross-armv7tnhl-platformfile
-cryptsetup-luks
-cscope
-ctags
-ctdb
-cups
-curl
-cvs
-cyrus-sasl
-d-feet
-db4
-db4-x86
-dblatex
-dbus
-dbus-glib
-dbus-python
-dejagnu
-dejavu-fonts
-deltarpm
-desktop-backgrounds
-desktop-file-utils
-dev86
-devhelp
-device-mapper
-dia
-dialog
-diffstat
-diffutils
-diffutils-x86
-distcc
-djvulibre
-dlt-daemon
-dmidecode
-dnsmasq
-docbook-dtds
-docbook-style-dsssl
-docbook-style-xsl
-docbook-utils
-dos2unix
-dosfstools
-dotconf
-doxygen
-doxygen-x86
-doxymacs
-driconf
-droid-fonts
-dsp-tools
-dvd+rw-tools
-dvipdfm
-dvipdfmx
-dvipng
-e2fsprogs
-eat
-ecryptfs-utils
-ed
-eggdbus
-eject
-elfutils
-elfutils-libelf-x86
-elfutils-libs-x86
-elfutils-x86
-emacs
-emgd-bin
-emgd-gui
-empathy
-enchant
-eog
-eog-plugins
-esound
-etherboot
-ethtool
-evince
-evolution
-evolution-data-server
-evtest
-exempi
-exiv2
-expat
-expect
-fakechroot
-fakeroot
-farsight2
-fastjar
-fdupes
-fdupes-x86
-fennec-qt-branding-meego
-festival
-festival-freebsoft-utils
-file
-file-libs-x86
-file-roller
-file-x86
-filesystem
-findutils
-findutils-x86
-flac
-flex
-folks
-fontconfig
-fontforge
-fontpackages
-foomatic-db
-fortune-mod
-freeglut
-freepats
-freerdp
-freetype
-fribidi
-frozen-bubble
-fslint
-FUR
-fuse
-fuse-sshfs
-fvkbd
-fw-update
-gamin
-gammu
-garage-client-services
-garage-netbook-ui
-gawk
-gawk-x86
-gc
-gcalctool
-gcc
-GConf-dbus
-gconf-editor
-gd
-gdb
-gdbm
-gdbus-binding-tool
-gdk-pixbuf
-gdu-nautilus-extension
-gedit
-gegl
-generic-backgrounds
-generic-logos
-geoclue
-gettext
-ghostscript
-ghostscript-fonts
-giflib
-gillius-collection-fonts
-gimp
-git
-glade3
-gles-libs
-glew
-glib-networking
-glib2
-glibc
-glibc-arm
-glibc-devel-arm
-glibc-headers-arm
-glibc-x86
-gmime
-gmp
-gmp-x86
-gnome-bluetooth
-gnome-common
-gnome-control-center-netbook
-gnome-desktop
-gnome-disk-utility
-gnome-doc-utils
-gnome-games
-gnome-icon-theme
-gnome-keyring
-gnome-media
-gnome-menus
-gnome-mime-data
-gnome-packagekit
-gnome-panel
-gnome-python2
-gnome-screensaver
-gnome-session
-gnome-settings-daemon
-gnome-sharp2
-gnome-terminal
-gnome-themes
-gnome-user-docs
-gnome-user-share
-gnome-utils
-gnome-vfs2
-gnonlin
-gnu-efi
-gnuchess
-gnupg
-gnupg2
-gnutls
-gobject-introspection
-google-gadgets
-gperf
-gpgme
-gphotofs
-gpsbabel
-gpsd
-gpsdrive
-graphviz
-grep
-grilo
-grilo-plugins
-groff
-grub
-grubby
-gsl
-gsm
-gssdp
-gst-dsp
-gst-plugins-bad-free
-gst-plugins-base
-gst-plugins-camera
-gst-plugins-dvbsub
-gst-plugins-farsight
-gst-plugins-flumpegdemux
-gst-plugins-good
-gst-plugins-teletext
-gst-plugins-va
-gst-v4l2-camsrc
-gst-vabuffer
-gstreamer
-gstreamer-editing-services
-gstreamer-python
-gthumb
-gtk-doc
-gtk-sharp2
-gtk2
-gtk2-engines
-gtkglext
-gtkhtml3
-gtksourceview2
-gtkspell
-guile
-gupnp
-gupnp-av
-gupnp-dlna
-gupnp-igd
-gupnp-tools
-gupnp-ui
-gupnp-vala
-gvfs
-gwenhywfar
-gypsy
-gzip
-gzip-x86
-hardlink
-help2man
-hfp
-hicolor-icon-theme
-html2ps
-hunspell
-hunspell-en
-hvd-comic-serif-fonts
-hwdata
-i2c-tools
-iasl
-icon-naming-utils
-icu
-id3lib
-ilmbase
-image-configurations
-image-manager
-ImageMagick
-imake
-indent
-inotify-tools
-installer-shell
-intel-gpu-tools
-Intel-WiMAX-Binary-Supplicant
-intltool
-iproute
-iptables
-iputils
-iso-codes
-isomd5sum
-ividesktop
-ivihome
-iw
-jadetex
-jana
-jasper
-joe
-joystick
-json-c
-json-glib
-junction-fonts
-kasumi
-kbd
-kcal-eds
-kcalcore
-kde-mobile
-kernel
-kernel-adaptation-connext
-kernel-adaptation-intel-automotive
-kernel-adaptation-medfield
-kernel-adaptation-mrst
-kernel-adaptation-n900
-kernel-adaptation-oaktrail
-kernel-adaptation-pc
-kernel-adaptation-pinetrail
-kernel-headers
-kernel-headers-arm
-kexec-tools
-keyutils
-kickstarter
-kmod-virtiogl
-kpartx
-krb5
-ladspa
-lapack
-latencytop
-latex2html
-layermanager
-lcms
-league-gothic-fonts
-less
-lftp
-libaccounts-glib
-libaccounts-qt
-libacl-x86
-libaio
-libao
-libarchive
-libart_lgpl
-libassuan
-libasyncns
-libatasmart
-libatomic_ops
-libattr-x86
-libbonobo
-libbonoboui
-libburn
-libcal-rx-51-bin
-libcanberra
-libcap
-libcap-ng
-libcap-x86
-libcdio
-libcgroup
-libchamplain
-libchewing
-libCI
-libcmtspeech-ifx
-libcmtspeechdata
-libcommhistory
-libcqpid
-libcreds3
-libcroco
-libdaemon
-libdbus-c++
-libdiscid
-libdmx
-libdres
-libdrm
-libdsme
-libealarm
-libedit
-libeigen2
-libenca
-liberation-fonts
-libevent
-libexif
-libfakekey
-libffi
-libfontenc
-libgcc-x86
-libgcrypt
-libgda
-libgdata
-libgdbus
-libgdiplus0
-libgdl
-libgee
-libggz
-libglade2
-libgnome
-libgnome-keyring
-libgnomecanvas
-libgnomecups
-libgnomekbd
-libgnomeprint22
-libgnomeprintui22
-libgnomeui
-libgpg-error
-libgphoto2
-libgsf
-libgtop2
-libgweather
-libhangul
-libical
-libICE
-libid3tag
-libIDL
-libidn
-libiodata
-libiphb
-libiptcdata
-libisofs
-libjingle
-libjpeg
-libksba
-liblua-x86
-libmatchbox
-libmeegochat
-libmicrohttpd
-libmikmod
-libmlocknice
-libmng
-libmp4v2
-libmtp
-libngf
-libnice
-libnl
-libnotify
-libofono-qt
-libofx
-libogg
-liboil
-libopenraw
-libopensync
-libopensync-plugin-vformat
-libpaper
-libpcap
-libpciaccess
-libpng
-libppu-bin
-libprolog
-libpthread-stubs
-libqmlog
-libqterminalmode
-libqtsparql
-libqtsparql-tracker-extensions
-libqttracker
-libquill
-libquillmetadata
-librapi2
-librds
-libresource
-libresourceqt
-librsvg2
-libsamplerate
-libsatsolver
-libsexy
-libsigc++
-libsignon
-libsignon-glib
-libsignoncrypto-qt
-libsilc
-libSM
-libsmack
-libsmbios
-libsndfile
-libsocialweb
-libsocialweb-keys
-libsocialweb-qml
-libsocialweb-qt
-libsoup
-libspectre
-libspiro
-libssh
-libstdc++-x86
-libsynce
-libsyncml
-libtalloc
-libtar
-libtasn1
-libtdb
-libtdb-compat
-libtee
-libthai
-libtheora
-libthumbnailer
-libtiff
-libtool
-libtrace
-libuninameslist
-libunique
-libusb
-libusb1
-libuser
-libutempter
-libv4l
-libva
-libvisual
-libvorbis
-libvpx
-libwbxml2
-libwl1251-bin
-libwnck
-libwsbm
-libX11
-libXau
-libXaw
-libxcb
-libXcomposite
-libXcursor
-libXdamage
-libXdmcp
-libXevie
-libXext
-libXfixes
-libXfont
-libXfontcache
-libXft
-libXi
-libXinerama
-libxkbfile
-libxklavier
-libxml2
-libxml2-python
-libXmu
-libXpm
-libXrandr
-libXrender
-libXres
-libXScrnSaver
-libxslt
-libXt
-libXTrap
-libXtst
-libXv
-libXvMC
-libXxf86dga
-libXxf86misc
-libXxf86vm
-libzip
-libzypp
-libzypp-bindings
-linux-firmware
-lirc
-lklug-fonts
-lockdev
-logrotate
-lohit-assamese-fonts
-lohit-bengali-fonts
-lohit-gujarati-fonts
-lohit-hindi-fonts
-lohit-kannada-fonts
-lohit-malayalam-fonts
-lohit-oriya-fonts
-lohit-punjabi-fonts
-lohit-tamil-fonts
-lohit-telugu-fonts
-loudmouth
-lpsolve
-lrzsz
-lsof
-ltrace
-lua
-lzo
-m17n-contrib
-m17n-db
-m17n-lib
-m2crypto
-m4
-mad-developer
-madeo-uplayer
-maemo-video-thumbnailer
-mailcap
-mailx
-make
-makebootfat
-MAKEDEV
-maliit-framework
-maliit-plugins
-man
-man-pages
-marmazon
-matchbox-keyboard
-matchbox-panel
-matchbox-window-manager
-media-explorer
-meego-app-browser
-meego-app-calculator
-meego-app-calendar
-meego-app-camera
-meego-app-clocks
-meego-app-contacts
-meego-app-email
-meego-app-fingerpaint
-meego-app-im
-meego-app-music
-meego-app-notes
-meego-app-photos
-meego-app-tasks
-meego-app-video
-meego-bookmarks
-meego-cross-armv5tel-sysroot
-meego-cross-armv7hl-sysroot
-meego-cross-armv7l-sysroot
-meego-cursor-theme
-meego-facebook-plugins
-meego-ivi-configs
-meego-lsb
-meego-menus
-meego-netbook-help
-meego-netbook-settings
-meego-netbook-theme
-meego-netbook-user-skel
-meego-osc-plugins
-meego-packaging-tools
-meego-panel-applications
-meego-panel-datetime
-meego-panel-devices
-meego-panel-myzone
-meego-panel-networks
-meego-panel-pasteboard
-meego-panel-people
-meego-panel-status
-meego-panel-web
-meego-panel-zones
-meego-qml-launcher
-meego-release
-meego-rpm-config
-meego-sdk-qemugl-addon
-meego-simulator-launcher
-meego-sound-theme
-meego-tv-browser
-meego-tv-IRinterface
-meego-tv-ux-settings
-meego-ux-appgrid
-meego-ux-components
-meego-ux-compositor
-meego-ux-content
-meego-ux-content-socialweb
-meego-ux-daemon
-meego-ux-ivi
-meego-ux-ivi-theme
-meego-ux-media
-meego-ux-panels
-meego-ux-settings
-meego-ux-settings-socialweb
-meego-ux-sharing
-meego-ux-sharing-email
-meego-ux-sharing-socialweb
-meego-ux-theme
-meego-ux-translations
-meego-ux-user-skel
-meegolabs-ux-components
-meld
-memuse
-mesa
-mesa-demos
-mic2
-min
-mingetty
-minicom
-mkcal
-mkdevnodes
-mkinitrd
-mlite
-mlocate
-mobile-broadband-provider-info
-module-init-tools
-monit
-monitor-call-audio-setting-mid
-mono-addins
-mono-core
-mono-zeroconf
-mozilla-filesystem
-mpage
-mpc
-mpc-x86
-mpfr
-mpfr-x86
-mssf-crypto
-mtd-utils
-mtdev
-mtools
-mutter
-mutter-meego-tv
-mutter-netbook
-mx
-myuppy-fonts
-n900-camera-firmware
-nano
-nasm
-nautilus
-nautilus-python
-navit
-navit-maps
-nc
-ncurses
-ncurses-libs-x86
-ndesk-dbus
-ndesk-dbus-glib
-neon
-net-tools
-netbook-backgrounds
-netbook-icon-theme
-netpbm
-neverball
-newt
-newt-python
-nfs-utils
-ngfd
-nobdy
-nokia-n900-configs
-nokia-n900-rescue-initrd
-nokia-usb-networking
-nolo-qemu
-notification-daemon
-notify-sharp
-nspr
-nspr-x86
-nss
-nss-mdns
-nss-softokn-freebl-x86
-nss-x86
-ntp
-o3read
-obex-data-server
-obexd
-ofono
-ohm
-ohm-plugins-misc
-openconnect
-OpenCV
-OpenEXR
-opengl-games-utils
-openjade
-openjpeg
-openldap
-openobex
-opensp
-openssh
-openssl
-openssl-certs
-openvpn
-ORBit2
-orc
-org
-orientation-contextkit-sensor
-osc
-ots
-package-groups
-PackageKit
-pacrunner
-pakchois
-pam
-pam_pkcs11
-pango
-paps
-papyon
-parted
-passivetex
-passwd
-patch
-patch-x86
-patchelf
-patchutils
-pax
-pciutils
-pcre
-perl
-perl-Archive-Zip
-perl-Array-Compare
-perl-Config-IniFiles
-perl-Convert-ASN1
-perl-Convert-BinHex
-perl-Crypt-SSLeay
-perl-Date-Manip
-perl-Devel-StackTrace
-perl-Devel-Symdump
-perl-Error
-perl-ExtUtils-Depends
-perl-ExtUtils-MakeMaker-Coverage
-perl-ExtUtils-PkgConfig
-perl-File-BaseDir
-perl-File-DesktopEntry
-perl-File-MimeInfo
-perl-File-Which
-perl-Finance-Quote
-perl-Font-TTF
-perl-gettext
-perl-Glib
-perl-HTML-Parser
-perl-HTML-TableExtract
-perl-HTML-Tagset
-perl-HTML-Tree
-perl-IO-Socket-INET6
-perl-IO-Socket-SSL
-perl-IO-stringy
-perl-JSON
-perl-libwww-perl
-perl-libxml-perl
-perl-MailTools
-perl-MIME-Lite
-perl-MIME-tools
-perl-Net-LibIDN
-perl-Net-SMTP-SSL
-perl-Net-SSLeay
-perl-Parse-Yapp
-perl-Pod-Coverage
-perl-SDL
-perl-SGMLSpm
-perl-SOAP-Lite
-perl-Socket6
-perl-Sub-Uplevel
-perl-SVG
-perl-SVG-Parser
-perl-Test-Exception
-perl-Test-MockObject
-perl-Test-NoWarnings
-perl-Test-Number-Delta
-perl-Test-Pod
-perl-Test-Pod-Coverage
-perl-Test-Tester
-perl-Test-Warn
-perl-Text-Unidecode
-perl-Tie-IxHash
-perl-TimeDate
-perl-Tk
-perl-Tree-DAG_Node
-perl-UNIVERSAL-can
-perl-UNIVERSAL-isa
-perl-URI
-perl-XML-DOM
-perl-XML-LibXML
-perl-XML-NamespaceSupport
-perl-XML-Parser
-perl-XML-RegExp
-perl-XML-SAX
-perl-XML-Simple
-perl-XML-TreeBuilder
-perl-XML-XQL
-perl-YAML
-persistman
-phidgetlinux
-phonesim
-phonon
-pidgin
-pidgin-sipe
-pixman
-pkcs11-helper
-pkgconfig
-plib
-plymouth-lite
-pm-utils
-pmtools
-pocketsphinx
-poedit
-policy-settings-basic-mfld
-policy-settings-basic-n900
-policy-settings-tablet
-polkit
-polkit-gnome
-poppler
-poppler-data
-poppler-qt
-popt
-popt-x86
-post-build-checks
-poster
-powerstatemgr
-powertop
-ppl
-ppp
-prelink
-procps
-psb-headers
-psb-video
-psb-video-mdfld
-psb-video-mrst
-psb-video-oaktrail
-psmisc
-psutils
-pth
-pulseaudio
-pulseaudio-modules-mfld
-pulseaudio-modules-n900
-pulseaudio-modules-nokia
-pulseaudio-policy-enforcement
-pulseaudio-settings-mfld
-pulseaudio-settings-n900
-pulseaudio-settings-tablet
-pycairo
-pyclutter
-pygobject2
-pygpgme
-pygtk2
-pygtkglext
-pykickstart
-PyOpenGL
-pyOpenSSL
-pyorbit
-python
-python-adns
-python-argparse
-python-chardet
-python-cheetah
-python-Coherence
-python-configobj
-python-crypto
-python-dateutil
-python-decorator
-python-docutils
-python-dtopt
-python-enchant
-python-formencode
-python-fpconst
-python-gdata
-python-imaging
-python-iniparse
-python-louie
-python-lxml
-python-magic
-python-markdown
-python-mutagen
-python-nose
-python-numeric
-python-paste
-python-paste-deploy
-python-pycurl
-python-pygments
-python-reportlab
-python-setuptools
-python-sexy
-python-simplejson
-python-sqlite2
-python-telepathy
-python-tempita
-python-toscawidgets
-python-tw-forms
-python-twisted
-python-twisted-conch
-python-twisted-core
-python-twisted-lore
-python-twisted-mail
-python-twisted-names
-python-twisted-news
-python-twisted-runner
-python-twisted-web
-python-twisted-web2
-python-twisted-words
-python-urlgrabber
-python-webob
-python-which
-python-wsgiproxy
-python-yaml
-python-zope-filesystem
-python-zope-interface
-python-ZSI
-pytz
-pyxdg
-PyXML
-qca2
-qca2-ossl
-qemu
-qflasher
-qjson
-qmf
-qml-gesturearea
-qmsystem
-qpid-cpp
-qt
-qt-creator
-qt-folks
-qt-mobility
-qt-mobility-geoservices-cloudmade
-qt-mobility-mediaservice-dbus
-qt-obex-ftp-library
-qtcontacts-eds
-qtcontacts-tracker
-qterminalmodeclient
-qtgst-qmlsink
-qtgstreamer
-qttas-server
-qtwebkit
-quicksynergy
-quillimagefilter
-quilt
-quota
-raleway-fonts
-rarian
-rdsd
-rdsquery
-readline
-recode
-rest
-rfkill
-rootfiles
-rpm
-rpm-build-x86
-rpm-libs-x86
-rpm-python
-rpm-x86
-rpmcheck
-rpmdevtools
-rpmlint
-rpmlint-MeeGo
-rpmlint-mini
-rpmlint-mini-x86
-rpmorphan
-rpmreaper
-rsync
-rtkit
-ruby
-rubygems
-rygel
-samba
-sample-media
-scim
-scim-anthy
-scim-bridge
-scim-chewing
-scim-hangul
-scim-m17n
-scim-panel-vkb-gtk
-scim-pinyin
-scim-skk
-scons
-screen
-SDL
-SDL_gfx
-SDL_image
-SDL_mixer
-SDL_net
-SDL_Pango
-SDL_ttf
-sed
-sed-x86
-sensorfw
-sensorfw-pegatron
-setup
-setuptool
-sg3_utils
-sgml-common
-shadow-utils
-shared-mime-info
-sharutils
-signon-digest
-signon-oauth2
-skkdic
-slang
-slib
-smem
-smshistory
-SOAPpy
-sofia-sip
-sorts-mill-goudy-fonts
-sound-theme-freedesktop
-soundtouch
-spectacle
-speech-dispatcher
-speex
-sphinxbase
-sqlite
-sqlite-x86
-squashfs-tools
-ssmtp
-startup-notification
-strace
-subversion
-sudo
-swi-prolog
-swig
-symlinks
-syncevolution
-syncevolution-gtk
-synergy
-sysfsutils
-sysinfod-rx51
-syslinux
-sysprof
-systemd
-t1lib
-tablet-target-config
-taglib
-taglib-sharp
-tar
-tar-x86
-tasks
-tcl
-tcp_wrappers
-tcpdump
-tcsh
-teckit
-telepathy-butterfly
-telepathy-farsight
-telepathy-farstream
-telepathy-filesystem
-telepathy-gabble
-telepathy-glib
-telepathy-haze
-telepathy-idle
-telepathy-logger
-telepathy-logger-qt4
-telepathy-mission-control
-telepathy-qt4
-telepathy-qt4-yell
-telepathy-ring
-telepathy-salut
-telepathy-sofiasip
-telepathy-stream-engine
-telepathy-yell
-test-definition
-testrunner-lite
-texi2html
-texinfo
-texlive
-texlive-texmf
-texlive-texmf-errata
-ti-kfmapp
-ti-omap3-sgx
-ti-uim
-ti-wl1251-firmware
-tig
-time
-timed
-tinycdb
-tix
-tk
-tmpwatch
-tone-generator
-totem
-totem-pl-parser
-tpm-tools
-traceroute
-tracker
-tracker-upnp
-transifex-client
-trousers
-tsc2007-config
-ttmkfdir
-tumbler
-tzdata
-u-boot
-udev
-udev-rules
-udiskie
-udisks
-un-core-fonts
-unzip
-upower
-urw-fonts
-usb-modeswitch
-usb-modeswitch-data
-usbutils
-usermode
-usleep
-utfs
-uthash
-util-linux
-uuid
-uxlaunch
-v8
-vala
-valgrind
-vamp-plugin-sdk
-vibrant-icon-theme
-vim
-vino
-vlgothic-fonts
-voicecallhistory
-vorbis-tools
-vpnc
-vte
-w3m
-wayland
-WebKit
-wget
-wildmidi
-WiMAX-Network-Service
-wimax-tools
-wireless-regdb
-wireless-tools
-wl1251-cal-bin
-wlanconfig
-wpa_supplicant
-wv
-wxGTK
-wxPython
-Xaw3d
-xbacklight
-xbindkeys
-xbmc
-xbmc-addon-awx
-xbmc-addon-executor
-xcb-proto
-xcb-util
-xdg-user-dirs
-xdg-user-dirs-gtk
-xdg-utils
-xdvipdfmx
-xerces-c
-xhtml1-dtds
-xhtml2fo-style-xsl
-xinput_calibrator
-xkeyboard-config
-xmlrpc-c
-xmltex
-xmlto
-xorg-x11-apps
-xorg-x11-drv-evdev
-xorg-x11-drv-fbdev
-xorg-x11-drv-fbdev-sgx
-xorg-x11-drv-intel
-xorg-x11-drv-joystick
-xorg-x11-drv-keyboard
-xorg-x11-drv-kvm
-xorg-x11-drv-mga
-xorg-x11-drv-mouse
-xorg-x11-drv-mtev
-xorg-x11-drv-omapfb
-xorg-x11-drv-synaptics
-xorg-x11-drv-vesa
-xorg-x11-drv-vmmouse
-xorg-x11-drv-vmware
-xorg-x11-drv-void
-xorg-x11-drv-wacom
-xorg-x11-filesystem
-xorg-x11-font-utils
-xorg-x11-fonts
-xorg-x11-meego-configs
-xorg-x11-proto-bigreqsproto
-xorg-x11-proto-compositeproto
-xorg-x11-proto-damageproto
-xorg-x11-proto-dmxproto
-xorg-x11-proto-dri2proto
-xorg-x11-proto-evieext
-xorg-x11-proto-fixesproto
-xorg-x11-proto-fontcacheproto
-xorg-x11-proto-fontsproto
-xorg-x11-proto-glproto
-xorg-x11-proto-inputproto
-xorg-x11-proto-kbproto
-xorg-x11-proto-randrproto
-xorg-x11-proto-recordproto
-xorg-x11-proto-renderproto
-xorg-x11-proto-resourceproto
-xorg-x11-proto-scrnsaverproto
-xorg-x11-proto-trapproto
-xorg-x11-proto-videoproto
-xorg-x11-proto-xcmiscproto
-xorg-x11-proto-xextproto
-xorg-x11-proto-xf86bigfontproto
-xorg-x11-proto-xf86dgaproto
-xorg-x11-proto-xf86driproto
-xorg-x11-proto-xf86miscproto
-xorg-x11-proto-xf86rushproto
-xorg-x11-proto-xf86vidmodeproto
-xorg-x11-proto-xineramaproto
-xorg-x11-proto-xproto
-xorg-x11-proto-xproxymanagementprotocol
-xorg-x11-server
-xorg-x11-server-utils
-xorg-x11-twm
-xorg-x11-util-macros
-xorg-x11-utils
-xorg-x11-utils-iceauth
-xorg-x11-utils-rgb
-xorg-x11-utils-sessreg
-xorg-x11-utils-xcmsdb
-xorg-x11-utils-xdpyinfo
-xorg-x11-utils-xdriinfo
-xorg-x11-utils-xev
-xorg-x11-utils-xfd
-xorg-x11-utils-xfontsel
-xorg-x11-utils-xgamma
-xorg-x11-utils-xhost
-xorg-x11-utils-xinput
-xorg-x11-utils-xlsatoms
-xorg-x11-utils-xlsclients
-xorg-x11-utils-xlsfonts
-xorg-x11-utils-xmodmap
-xorg-x11-utils-xprop
-xorg-x11-utils-xrandr
-xorg-x11-utils-xrdb
-xorg-x11-utils-xrefresh
-xorg-x11-utils-xset
-xorg-x11-utils-xsetroot
-xorg-x11-utils-xvinfo
-xorg-x11-utils-xwininfo
-xorg-x11-xauth
-xorg-x11-xbitmaps
-xorg-x11-xinit
-xorg-x11-xkb-utils
-xorg-x11-xtrans-devel
-xrestop
-xterm
-xz
-xz-libs-x86
-yasm
-yelp
-yum
-yum-metadata-parser
-yum-utils
-zenity
-zile
-zip
-zlib
-zlib-x86
-zsh
-zvbi
-zypper
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 16ccc6c5..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,55 +0,0 @@
-Metadata-Version: 1.1
-Name: Jinja2
-Version: 2.6
-Summary: A small but fast and easy to use stand-alone template engine written in pure python.
-Home-page: http://jinja.pocoo.org/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-License: BSD
-Description:
- Jinja2
- ~~~~~~
-
- Jinja2 is a template engine written in pure Python. It provides a
- `Django`_ inspired non-XML syntax but supports inline expressions and
- an optional `sandboxed`_ environment.
-
- Nutshell
- --------
-
- Here a small example of a Jinja template::
-
- {% extends 'base.html' %}
- {% block title %}Memberlist{% endblock %}
- {% block content %}
- <ul>
- {% for user in users %}
- <li><a href="{{ user.url }}">{{ user.username }}</a></li>
- {% endfor %}
- </ul>
- {% endblock %}
-
- Philosophy
- ----------
-
- Application logic is for the controller but don't try to make the life
- for the template designer too hard by giving him too few functionality.
-
- For more informations visit the new `Jinja2 webpage`_ and `documentation`_.
-
- .. _sandboxed: http://en.wikipedia.org/wiki/Sandbox_(computer_security)
- .. _Django: http://www.djangoproject.com/
- .. _Jinja2 webpage: http://jinja.pocoo.org/
- .. _documentation: http://jinja.pocoo.org/2/documentation/
-
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Text Processing :: Markup :: HTML
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 7dc4a14f..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-AUTHORS
-CHANGES
-LICENSE
-MANIFEST.in
-Makefile
-setup.cfg
-setup.py
-Jinja2.egg-info/PKG-INFO
-Jinja2.egg-info/SOURCES.txt
-Jinja2.egg-info/dependency_links.txt
-Jinja2.egg-info/entry_points.txt
-Jinja2.egg-info/not-zip-safe
-Jinja2.egg-info/requires.txt
-Jinja2.egg-info/top_level.txt
-artwork/jinjalogo.svg
-custom_fixers/__init__.py
-custom_fixers/fix_alt_unicode.py
-custom_fixers/fix_broken_reraising.py
-custom_fixers/fix_xrange2.py
-docs/.DS_Store
-docs/._.DS_Store
-docs/Makefile
-docs/api.rst
-docs/cache_extension.py
-docs/changelog.rst
-docs/conf.py
-docs/contents.rst.inc
-docs/extensions.rst
-docs/faq.rst
-docs/index.rst
-docs/integration.rst
-docs/intro.rst
-docs/jinjaext.py
-docs/jinjastyle.sty
-docs/latexindex.rst
-docs/logo.pdf
-docs/sandbox.rst
-docs/switching.rst
-docs/templates.rst
-docs/tricks.rst
-docs/_static/.ignore
-docs/_static/jinja-small.png
-docs/_templates/sidebarintro.html
-docs/_templates/sidebarlogo.html
-docs/_themes/LICENSE
-docs/_themes/README
-docs/_themes/jinja/layout.html
-docs/_themes/jinja/relations.html
-docs/_themes/jinja/theme.conf
-docs/_themes/jinja/static/jinja.css_t
-examples/bench.py
-examples/profile.py
-examples/basic/cycle.py
-examples/basic/debugger.py
-examples/basic/inheritance.py
-examples/basic/test.py
-examples/basic/test2.py
-examples/basic/test2.pyc
-examples/basic/test_filter_and_linestatements.py
-examples/basic/test_loop_filter.py
-examples/basic/translate.py
-examples/basic/templates/broken.html
-examples/basic/templates/subbroken.html
-examples/rwbench/djangoext.py
-examples/rwbench/rwbench.py
-examples/rwbench/django/_form.html
-examples/rwbench/django/_input_field.html
-examples/rwbench/django/_textarea.html
-examples/rwbench/django/index.html
-examples/rwbench/django/layout.html
-examples/rwbench/genshi/helpers.html
-examples/rwbench/genshi/index.html
-examples/rwbench/genshi/layout.html
-examples/rwbench/jinja/helpers.html
-examples/rwbench/jinja/index.html
-examples/rwbench/jinja/layout.html
-examples/rwbench/mako/helpers.html
-examples/rwbench/mako/index.html
-examples/rwbench/mako/layout.html
-ext/JinjaTemplates.tmbundle.tar.gz
-ext/djangojinja2.py
-ext/inlinegettext.py
-ext/jinja.el
-ext/Vim/jinja.vim
-ext/django2jinja/django2jinja.py
-ext/django2jinja/example.py
-ext/django2jinja/templates/index.html
-ext/django2jinja/templates/layout.html
-ext/django2jinja/templates/subtemplate.html
-jinja2/__init__.py
-jinja2/_debugsupport.c
-jinja2/_stringdefs.py
-jinja2/bccache.py
-jinja2/compiler.py
-jinja2/constants.py
-jinja2/debug.py
-jinja2/defaults.py
-jinja2/environment.py
-jinja2/exceptions.py
-jinja2/ext.py
-jinja2/filters.py
-jinja2/lexer.py
-jinja2/loaders.py
-jinja2/meta.py
-jinja2/nodes.py
-jinja2/optimizer.py
-jinja2/parser.py
-jinja2/runtime.py
-jinja2/sandbox.py
-jinja2/tests.py
-jinja2/utils.py
-jinja2/visitor.py
-jinja2/_markupsafe/__init__.py
-jinja2/_markupsafe/_bundle.py
-jinja2/_markupsafe/_constants.py
-jinja2/_markupsafe/_native.py
-jinja2/_markupsafe/tests.py
-jinja2/testsuite/__init__.py
-jinja2/testsuite/api.py
-jinja2/testsuite/core_tags.py
-jinja2/testsuite/debug.py
-jinja2/testsuite/doctests.py
-jinja2/testsuite/ext.py
-jinja2/testsuite/filters.py
-jinja2/testsuite/imports.py
-jinja2/testsuite/inheritance.py
-jinja2/testsuite/lexnparse.py
-jinja2/testsuite/loader.py
-jinja2/testsuite/regression.py
-jinja2/testsuite/security.py
-jinja2/testsuite/tests.py
-jinja2/testsuite/utils.py
-jinja2/testsuite/res/__init__.py
-jinja2/testsuite/res/templates/broken.html
-jinja2/testsuite/res/templates/syntaxerror.html
-jinja2/testsuite/res/templates/test.html
-jinja2/testsuite/res/templates/foo/test.html \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/entry_points.txt b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/entry_points.txt
deleted file mode 100644
index 32e6b753..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/entry_points.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
- [babel.extractors]
- jinja2 = jinja2.ext:babel_extract[i18n]
- \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/requires.txt
deleted file mode 100644
index c17d5332..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-[i18n]
-Babel>=0.8 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 7f7afbf3..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-jinja2
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/__init__.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/__init__.py
deleted file mode 100755
index 0cf967d7..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/__init__.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2
- ~~~~~~
-
- Jinja2 is a template engine written in pure Python. It provides a
- Django inspired non-XML syntax but supports inline expressions and
- an optional sandboxed environment.
-
- Nutshell
- --------
-
- Here a small example of a Jinja2 template::
-
- {% extends 'base.html' %}
- {% block title %}Memberlist{% endblock %}
- {% block content %}
- <ul>
- {% for user in users %}
- <li><a href="{{ user.url }}">{{ user.username }}</a></li>
- {% endfor %}
- </ul>
- {% endblock %}
-
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-__docformat__ = 'restructuredtext en'
-__version__ = '2.6'
-
-# high level interface
-from jinja2.environment import Environment, Template
-
-# loaders
-from jinja2.loaders import BaseLoader, FileSystemLoader, PackageLoader, \
- DictLoader, FunctionLoader, PrefixLoader, ChoiceLoader, \
- ModuleLoader
-
-# bytecode caches
-from jinja2.bccache import BytecodeCache, FileSystemBytecodeCache, \
- MemcachedBytecodeCache
-
-# undefined types
-from jinja2.runtime import Undefined, DebugUndefined, StrictUndefined
-
-# exceptions
-from jinja2.exceptions import TemplateError, UndefinedError, \
- TemplateNotFound, TemplatesNotFound, TemplateSyntaxError, \
- TemplateAssertionError
-
-# decorators and public utilities
-from jinja2.filters import environmentfilter, contextfilter, \
- evalcontextfilter
-from jinja2.utils import Markup, escape, clear_caches, \
- environmentfunction, evalcontextfunction, contextfunction, \
- is_undefined
-
-__all__ = [
- 'Environment', 'Template', 'BaseLoader', 'FileSystemLoader',
- 'PackageLoader', 'DictLoader', 'FunctionLoader', 'PrefixLoader',
- 'ChoiceLoader', 'BytecodeCache', 'FileSystemBytecodeCache',
- 'MemcachedBytecodeCache', 'Undefined', 'DebugUndefined',
- 'StrictUndefined', 'TemplateError', 'UndefinedError', 'TemplateNotFound',
- 'TemplatesNotFound', 'TemplateSyntaxError', 'TemplateAssertionError',
- 'ModuleLoader', 'environmentfilter', 'contextfilter', 'Markup', 'escape',
- 'environmentfunction', 'contextfunction', 'clear_caches', 'is_undefined',
- 'evalcontextfilter', 'evalcontextfunction'
-]
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_debugsupport.c b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_debugsupport.c
deleted file mode 100644
index e756d8e1..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_debugsupport.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * jinja2._debugsupport
- * ~~~~~~~~~~~~~~~~~~~~
- *
- * C implementation of `tb_set_next`.
- *
- * :copyright: (c) 2010 by the Jinja Team.
- * :license: BSD.
- */
-
-#include <Python.h>
-
-
-static PyObject*
-tb_set_next(PyObject *self, PyObject *args)
-{
- PyTracebackObject *tb, *old;
- PyObject *next;
-
- if (!PyArg_ParseTuple(args, "O!O:tb_set_next", &PyTraceBack_Type, &tb, &next))
- return NULL;
- if (next == Py_None)
- next = NULL;
- else if (!PyTraceBack_Check(next)) {
- PyErr_SetString(PyExc_TypeError,
- "tb_set_next arg 2 must be traceback or None");
- return NULL;
- }
- else
- Py_INCREF(next);
-
- old = tb->tb_next;
- tb->tb_next = (PyTracebackObject*)next;
- Py_XDECREF(old);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef module_methods[] = {
- {"tb_set_next", (PyCFunction)tb_set_next, METH_VARARGS,
- "Set the tb_next member of a traceback object."},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-
-#if PY_MAJOR_VERSION < 3
-
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-PyMODINIT_FUNC
-init_debugsupport(void)
-{
- Py_InitModule3("jinja2._debugsupport", module_methods, "");
-}
-
-#else /* Python 3.x module initialization */
-
-static struct PyModuleDef module_definition = {
- PyModuleDef_HEAD_INIT,
- "jinja2._debugsupport",
- NULL,
- -1,
- module_methods,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-PyMODINIT_FUNC
-PyInit__debugsupport(void)
-{
- return PyModule_Create(&module_definition);
-}
-
-#endif
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/__init__.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/__init__.py
deleted file mode 100755
index ec7bd572..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/__init__.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- markupsafe
- ~~~~~~~~~~
-
- Implements a Markup string.
-
- :copyright: (c) 2010 by Armin Ronacher.
- :license: BSD, see LICENSE for more details.
-"""
-import re
-from itertools import imap
-
-
-__all__ = ['Markup', 'soft_unicode', 'escape', 'escape_silent']
-
-
-_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
-_entity_re = re.compile(r'&([^;]+);')
-
-
-class Markup(unicode):
- r"""Marks a string as being safe for inclusion in HTML/XML output without
- needing to be escaped. This implements the `__html__` interface a couple
- of frameworks and web applications use. :class:`Markup` is a direct
- subclass of `unicode` and provides all the methods of `unicode` just that
- it escapes arguments passed and always returns `Markup`.
-
- The `escape` function returns markup objects so that double escaping can't
- happen.
-
- The constructor of the :class:`Markup` class can be used for three
- different things: When passed an unicode object it's assumed to be safe,
- when passed an object with an HTML representation (has an `__html__`
- method) that representation is used, otherwise the object passed is
- converted into a unicode string and then assumed to be safe:
-
- >>> Markup("Hello <em>World</em>!")
- Markup(u'Hello <em>World</em>!')
- >>> class Foo(object):
- ... def __html__(self):
- ... return '<a href="#">foo</a>'
- ...
- >>> Markup(Foo())
- Markup(u'<a href="#">foo</a>')
-
- If you want object passed being always treated as unsafe you can use the
- :meth:`escape` classmethod to create a :class:`Markup` object:
-
- >>> Markup.escape("Hello <em>World</em>!")
- Markup(u'Hello &lt;em&gt;World&lt;/em&gt;!')
-
- Operations on a markup string are markup aware which means that all
- arguments are passed through the :func:`escape` function:
-
- >>> em = Markup("<em>%s</em>")
- >>> em % "foo & bar"
- Markup(u'<em>foo &amp; bar</em>')
- >>> strong = Markup("<strong>%(text)s</strong>")
- >>> strong % {'text': '<blink>hacker here</blink>'}
- Markup(u'<strong>&lt;blink&gt;hacker here&lt;/blink&gt;</strong>')
- >>> Markup("<em>Hello</em> ") + "<foo>"
- Markup(u'<em>Hello</em> &lt;foo&gt;')
- """
- __slots__ = ()
-
- def __new__(cls, base=u'', encoding=None, errors='strict'):
- if hasattr(base, '__html__'):
- base = base.__html__()
- if encoding is None:
- return unicode.__new__(cls, base)
- return unicode.__new__(cls, base, encoding, errors)
-
- def __html__(self):
- return self
-
- def __add__(self, other):
- if hasattr(other, '__html__') or isinstance(other, basestring):
- return self.__class__(unicode(self) + unicode(escape(other)))
- return NotImplemented
-
- def __radd__(self, other):
- if hasattr(other, '__html__') or isinstance(other, basestring):
- return self.__class__(unicode(escape(other)) + unicode(self))
- return NotImplemented
-
- def __mul__(self, num):
- if isinstance(num, (int, long)):
- return self.__class__(unicode.__mul__(self, num))
- return NotImplemented
- __rmul__ = __mul__
-
- def __mod__(self, arg):
- if isinstance(arg, tuple):
- arg = tuple(imap(_MarkupEscapeHelper, arg))
- else:
- arg = _MarkupEscapeHelper(arg)
- return self.__class__(unicode.__mod__(self, arg))
-
- def __repr__(self):
- return '%s(%s)' % (
- self.__class__.__name__,
- unicode.__repr__(self)
- )
-
- def join(self, seq):
- return self.__class__(unicode.join(self, imap(escape, seq)))
- join.__doc__ = unicode.join.__doc__
-
- def split(self, *args, **kwargs):
- return map(self.__class__, unicode.split(self, *args, **kwargs))
- split.__doc__ = unicode.split.__doc__
-
- def rsplit(self, *args, **kwargs):
- return map(self.__class__, unicode.rsplit(self, *args, **kwargs))
- rsplit.__doc__ = unicode.rsplit.__doc__
-
- def splitlines(self, *args, **kwargs):
- return map(self.__class__, unicode.splitlines(self, *args, **kwargs))
- splitlines.__doc__ = unicode.splitlines.__doc__
-
- def unescape(self):
- r"""Unescape markup again into an unicode string. This also resolves
- known HTML4 and XHTML entities:
-
- >>> Markup("Main &raquo; <em>About</em>").unescape()
- u'Main \xbb <em>About</em>'
- """
- from jinja2._markupsafe._constants import HTML_ENTITIES
- def handle_match(m):
- name = m.group(1)
- if name in HTML_ENTITIES:
- return unichr(HTML_ENTITIES[name])
- try:
- if name[:2] in ('#x', '#X'):
- return unichr(int(name[2:], 16))
- elif name.startswith('#'):
- return unichr(int(name[1:]))
- except ValueError:
- pass
- return u''
- return _entity_re.sub(handle_match, unicode(self))
-
- def striptags(self):
- r"""Unescape markup into an unicode string and strip all tags. This
- also resolves known HTML4 and XHTML entities. Whitespace is
- normalized to one:
-
- >>> Markup("Main &raquo; <em>About</em>").striptags()
- u'Main \xbb About'
- """
- stripped = u' '.join(_striptags_re.sub('', self).split())
- return Markup(stripped).unescape()
-
- @classmethod
- def escape(cls, s):
- """Escape the string. Works like :func:`escape` with the difference
- that for subclasses of :class:`Markup` this function would return the
- correct subclass.
- """
- rv = escape(s)
- if rv.__class__ is not cls:
- return cls(rv)
- return rv
-
- def make_wrapper(name):
- orig = getattr(unicode, name)
- def func(self, *args, **kwargs):
- args = _escape_argspec(list(args), enumerate(args))
- _escape_argspec(kwargs, kwargs.iteritems())
- return self.__class__(orig(self, *args, **kwargs))
- func.__name__ = orig.__name__
- func.__doc__ = orig.__doc__
- return func
-
- for method in '__getitem__', 'capitalize', \
- 'title', 'lower', 'upper', 'replace', 'ljust', \
- 'rjust', 'lstrip', 'rstrip', 'center', 'strip', \
- 'translate', 'expandtabs', 'swapcase', 'zfill':
- locals()[method] = make_wrapper(method)
-
- # new in python 2.5
- if hasattr(unicode, 'partition'):
- partition = make_wrapper('partition'),
- rpartition = make_wrapper('rpartition')
-
- # new in python 2.6
- if hasattr(unicode, 'format'):
- format = make_wrapper('format')
-
- # not in python 3
- if hasattr(unicode, '__getslice__'):
- __getslice__ = make_wrapper('__getslice__')
-
- del method, make_wrapper
-
-
-def _escape_argspec(obj, iterable):
- """Helper for various string-wrapped functions."""
- for key, value in iterable:
- if hasattr(value, '__html__') or isinstance(value, basestring):
- obj[key] = escape(value)
- return obj
-
-
-class _MarkupEscapeHelper(object):
- """Helper for Markup.__mod__"""
-
- def __init__(self, obj):
- self.obj = obj
-
- __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x])
- __str__ = lambda s: str(escape(s.obj))
- __unicode__ = lambda s: unicode(escape(s.obj))
- __repr__ = lambda s: str(escape(repr(s.obj)))
- __int__ = lambda s: int(s.obj)
- __float__ = lambda s: float(s.obj)
-
-
-# we have to import it down here as the speedups and native
-# modules imports the markup type which is define above.
-try:
- from jinja2._markupsafe._speedups import escape, escape_silent, soft_unicode
-except ImportError:
- from jinja2._markupsafe._native import escape, escape_silent, soft_unicode
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_bundle.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_bundle.py
deleted file mode 100755
index e694faf2..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_bundle.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2._markupsafe._bundle
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This script pulls in markupsafe from a source folder and
- bundles it with Jinja2. It does not pull in the speedups
- module though.
-
- :copyright: Copyright 2010 by the Jinja team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-import sys
-import os
-import re
-
-
-def rewrite_imports(lines):
- for idx, line in enumerate(lines):
- new_line = re.sub(r'(import|from)\s+markupsafe\b',
- r'\1 jinja2._markupsafe', line)
- if new_line != line:
- lines[idx] = new_line
-
-
-def main():
- if len(sys.argv) != 2:
- print 'error: only argument is path to markupsafe'
- sys.exit(1)
- basedir = os.path.dirname(__file__)
- markupdir = sys.argv[1]
- for filename in os.listdir(markupdir):
- if filename.endswith('.py'):
- f = open(os.path.join(markupdir, filename))
- try:
- lines = list(f)
- finally:
- f.close()
- rewrite_imports(lines)
- f = open(os.path.join(basedir, filename), 'w')
- try:
- for line in lines:
- f.write(line)
- finally:
- f.close()
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_constants.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_constants.py
deleted file mode 100755
index 919bf03c..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_constants.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- markupsafe._constants
- ~~~~~~~~~~~~~~~~~~~~~
-
- Highlevel implementation of the Markup string.
-
- :copyright: (c) 2010 by Armin Ronacher.
- :license: BSD, see LICENSE for more details.
-"""
-
-
-HTML_ENTITIES = {
- 'AElig': 198,
- 'Aacute': 193,
- 'Acirc': 194,
- 'Agrave': 192,
- 'Alpha': 913,
- 'Aring': 197,
- 'Atilde': 195,
- 'Auml': 196,
- 'Beta': 914,
- 'Ccedil': 199,
- 'Chi': 935,
- 'Dagger': 8225,
- 'Delta': 916,
- 'ETH': 208,
- 'Eacute': 201,
- 'Ecirc': 202,
- 'Egrave': 200,
- 'Epsilon': 917,
- 'Eta': 919,
- 'Euml': 203,
- 'Gamma': 915,
- 'Iacute': 205,
- 'Icirc': 206,
- 'Igrave': 204,
- 'Iota': 921,
- 'Iuml': 207,
- 'Kappa': 922,
- 'Lambda': 923,
- 'Mu': 924,
- 'Ntilde': 209,
- 'Nu': 925,
- 'OElig': 338,
- 'Oacute': 211,
- 'Ocirc': 212,
- 'Ograve': 210,
- 'Omega': 937,
- 'Omicron': 927,
- 'Oslash': 216,
- 'Otilde': 213,
- 'Ouml': 214,
- 'Phi': 934,
- 'Pi': 928,
- 'Prime': 8243,
- 'Psi': 936,
- 'Rho': 929,
- 'Scaron': 352,
- 'Sigma': 931,
- 'THORN': 222,
- 'Tau': 932,
- 'Theta': 920,
- 'Uacute': 218,
- 'Ucirc': 219,
- 'Ugrave': 217,
- 'Upsilon': 933,
- 'Uuml': 220,
- 'Xi': 926,
- 'Yacute': 221,
- 'Yuml': 376,
- 'Zeta': 918,
- 'aacute': 225,
- 'acirc': 226,
- 'acute': 180,
- 'aelig': 230,
- 'agrave': 224,
- 'alefsym': 8501,
- 'alpha': 945,
- 'amp': 38,
- 'and': 8743,
- 'ang': 8736,
- 'apos': 39,
- 'aring': 229,
- 'asymp': 8776,
- 'atilde': 227,
- 'auml': 228,
- 'bdquo': 8222,
- 'beta': 946,
- 'brvbar': 166,
- 'bull': 8226,
- 'cap': 8745,
- 'ccedil': 231,
- 'cedil': 184,
- 'cent': 162,
- 'chi': 967,
- 'circ': 710,
- 'clubs': 9827,
- 'cong': 8773,
- 'copy': 169,
- 'crarr': 8629,
- 'cup': 8746,
- 'curren': 164,
- 'dArr': 8659,
- 'dagger': 8224,
- 'darr': 8595,
- 'deg': 176,
- 'delta': 948,
- 'diams': 9830,
- 'divide': 247,
- 'eacute': 233,
- 'ecirc': 234,
- 'egrave': 232,
- 'empty': 8709,
- 'emsp': 8195,
- 'ensp': 8194,
- 'epsilon': 949,
- 'equiv': 8801,
- 'eta': 951,
- 'eth': 240,
- 'euml': 235,
- 'euro': 8364,
- 'exist': 8707,
- 'fnof': 402,
- 'forall': 8704,
- 'frac12': 189,
- 'frac14': 188,
- 'frac34': 190,
- 'frasl': 8260,
- 'gamma': 947,
- 'ge': 8805,
- 'gt': 62,
- 'hArr': 8660,
- 'harr': 8596,
- 'hearts': 9829,
- 'hellip': 8230,
- 'iacute': 237,
- 'icirc': 238,
- 'iexcl': 161,
- 'igrave': 236,
- 'image': 8465,
- 'infin': 8734,
- 'int': 8747,
- 'iota': 953,
- 'iquest': 191,
- 'isin': 8712,
- 'iuml': 239,
- 'kappa': 954,
- 'lArr': 8656,
- 'lambda': 955,
- 'lang': 9001,
- 'laquo': 171,
- 'larr': 8592,
- 'lceil': 8968,
- 'ldquo': 8220,
- 'le': 8804,
- 'lfloor': 8970,
- 'lowast': 8727,
- 'loz': 9674,
- 'lrm': 8206,
- 'lsaquo': 8249,
- 'lsquo': 8216,
- 'lt': 60,
- 'macr': 175,
- 'mdash': 8212,
- 'micro': 181,
- 'middot': 183,
- 'minus': 8722,
- 'mu': 956,
- 'nabla': 8711,
- 'nbsp': 160,
- 'ndash': 8211,
- 'ne': 8800,
- 'ni': 8715,
- 'not': 172,
- 'notin': 8713,
- 'nsub': 8836,
- 'ntilde': 241,
- 'nu': 957,
- 'oacute': 243,
- 'ocirc': 244,
- 'oelig': 339,
- 'ograve': 242,
- 'oline': 8254,
- 'omega': 969,
- 'omicron': 959,
- 'oplus': 8853,
- 'or': 8744,
- 'ordf': 170,
- 'ordm': 186,
- 'oslash': 248,
- 'otilde': 245,
- 'otimes': 8855,
- 'ouml': 246,
- 'para': 182,
- 'part': 8706,
- 'permil': 8240,
- 'perp': 8869,
- 'phi': 966,
- 'pi': 960,
- 'piv': 982,
- 'plusmn': 177,
- 'pound': 163,
- 'prime': 8242,
- 'prod': 8719,
- 'prop': 8733,
- 'psi': 968,
- 'quot': 34,
- 'rArr': 8658,
- 'radic': 8730,
- 'rang': 9002,
- 'raquo': 187,
- 'rarr': 8594,
- 'rceil': 8969,
- 'rdquo': 8221,
- 'real': 8476,
- 'reg': 174,
- 'rfloor': 8971,
- 'rho': 961,
- 'rlm': 8207,
- 'rsaquo': 8250,
- 'rsquo': 8217,
- 'sbquo': 8218,
- 'scaron': 353,
- 'sdot': 8901,
- 'sect': 167,
- 'shy': 173,
- 'sigma': 963,
- 'sigmaf': 962,
- 'sim': 8764,
- 'spades': 9824,
- 'sub': 8834,
- 'sube': 8838,
- 'sum': 8721,
- 'sup': 8835,
- 'sup1': 185,
- 'sup2': 178,
- 'sup3': 179,
- 'supe': 8839,
- 'szlig': 223,
- 'tau': 964,
- 'there4': 8756,
- 'theta': 952,
- 'thetasym': 977,
- 'thinsp': 8201,
- 'thorn': 254,
- 'tilde': 732,
- 'times': 215,
- 'trade': 8482,
- 'uArr': 8657,
- 'uacute': 250,
- 'uarr': 8593,
- 'ucirc': 251,
- 'ugrave': 249,
- 'uml': 168,
- 'upsih': 978,
- 'upsilon': 965,
- 'uuml': 252,
- 'weierp': 8472,
- 'xi': 958,
- 'yacute': 253,
- 'yen': 165,
- 'yuml': 255,
- 'zeta': 950,
- 'zwj': 8205,
- 'zwnj': 8204
-}
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_native.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_native.py
deleted file mode 100755
index 7b95828e..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/_native.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- markupsafe._native
- ~~~~~~~~~~~~~~~~~~
-
- Native Python implementation the C module is not compiled.
-
- :copyright: (c) 2010 by Armin Ronacher.
- :license: BSD, see LICENSE for more details.
-"""
-from jinja2._markupsafe import Markup
-
-
-def escape(s):
- """Convert the characters &, <, >, ' and " in string s to HTML-safe
- sequences. Use this if you need to display text that might contain
- such characters in HTML. Marks return value as markup string.
- """
- if hasattr(s, '__html__'):
- return s.__html__()
- return Markup(unicode(s)
- .replace('&', '&amp;')
- .replace('>', '&gt;')
- .replace('<', '&lt;')
- .replace("'", '&#39;')
- .replace('"', '&#34;')
- )
-
-
-def escape_silent(s):
- """Like :func:`escape` but converts `None` into an empty
- markup string.
- """
- if s is None:
- return Markup()
- return escape(s)
-
-
-def soft_unicode(s):
- """Make a string unicode if it isn't already. That way a markup
- string is not converted back to unicode.
- """
- if not isinstance(s, unicode):
- s = unicode(s)
- return s
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/tests.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/tests.py
deleted file mode 100755
index c1ce3943..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_markupsafe/tests.py
+++ /dev/null
@@ -1,80 +0,0 @@
-import gc
-import unittest
-from jinja2._markupsafe import Markup, escape, escape_silent
-
-
-class MarkupTestCase(unittest.TestCase):
-
- def test_markup_operations(self):
- # adding two strings should escape the unsafe one
- unsafe = '<script type="application/x-some-script">alert("foo");</script>'
- safe = Markup('<em>username</em>')
- assert unsafe + safe == unicode(escape(unsafe)) + unicode(safe)
-
- # string interpolations are safe to use too
- assert Markup('<em>%s</em>') % '<bad user>' == \
- '<em>&lt;bad user&gt;</em>'
- assert Markup('<em>%(username)s</em>') % {
- 'username': '<bad user>'
- } == '<em>&lt;bad user&gt;</em>'
-
- # an escaped object is markup too
- assert type(Markup('foo') + 'bar') is Markup
-
- # and it implements __html__ by returning itself
- x = Markup("foo")
- assert x.__html__() is x
-
- # it also knows how to treat __html__ objects
- class Foo(object):
- def __html__(self):
- return '<em>awesome</em>'
- def __unicode__(self):
- return 'awesome'
- assert Markup(Foo()) == '<em>awesome</em>'
- assert Markup('<strong>%s</strong>') % Foo() == \
- '<strong><em>awesome</em></strong>'
-
- # escaping and unescaping
- assert escape('"<>&\'') == '&#34;&lt;&gt;&amp;&#39;'
- assert Markup("<em>Foo &amp; Bar</em>").striptags() == "Foo & Bar"
- assert Markup("&lt;test&gt;").unescape() == "<test>"
-
- def test_all_set(self):
- import jinja2._markupsafe as markup
- for item in markup.__all__:
- getattr(markup, item)
-
- def test_escape_silent(self):
- assert escape_silent(None) == Markup()
- assert escape(None) == Markup(None)
- assert escape_silent('<foo>') == Markup(u'&lt;foo&gt;')
-
-
-class MarkupLeakTestCase(unittest.TestCase):
-
- def test_markup_leaks(self):
- counts = set()
- for count in xrange(20):
- for item in xrange(1000):
- escape("foo")
- escape("<foo>")
- escape(u"foo")
- escape(u"<foo>")
- counts.add(len(gc.get_objects()))
- assert len(counts) == 1, 'ouch, c extension seems to leak objects'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(MarkupTestCase))
-
- # this test only tests the c extension
- if not hasattr(escape, 'func_code'):
- suite.addTest(unittest.makeSuite(MarkupLeakTestCase))
-
- return suite
-
-
-if __name__ == '__main__':
- unittest.main(defaultTest='suite')
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_stringdefs.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_stringdefs.py
deleted file mode 100755
index 1161b7f4..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/_stringdefs.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2._stringdefs
- ~~~~~~~~~~~~~~~~~~
-
- Strings of all Unicode characters of a certain category.
- Used for matching in Unicode-aware languages. Run to regenerate.
-
- Inspired by chartypes_create.py from the MoinMoin project, original
- implementation from Pygments.
-
- :copyright: Copyright 2006-2009 by the Jinja team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-
-Cc = u'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f'
-
-Cf = u'\xad\u0600\u0601\u0602\u0603\u06dd\u070f\u17b4\u17b5\u200b\u200c\u200d\u200e\u200f\u202a\u202b\u202c\u202d\u202e\u2060\u2061\u2062\u2063\u206a\u206b\u206c\u206d\u206e\u206f\ufeff\ufff9\ufffa\ufffb'
-
-Cn = u'\u0242\u0243\u0244\u0245\u0246\u0247\u0248\u0249\u024a\u024b\u024c\u024d\u024e\u024f\u0370\u0371\u0372\u0373\u0376\u0377\u0378\u0379\u037b\u037c\u037d\u037f\u0380\u0381\u0382\u0383\u038b\u038d\u03a2\u03cf\u0487\u04cf\u04fa\u04fb\u04fc\u04fd\u04fe\u04ff\u0510\u0511\u0512\u0513\u0514\u0515\u0516\u0517\u0518\u0519\u051a\u051b\u051c\u051d\u051e\u051f\u0520\u0521\u0522\u0523\u0524\u0525\u0526\u0527\u0528\u0529\u052a\u052b\u052c\u052d\u052e\u052f\u0530\u0557\u0558\u0560\u0588\u058b\u058c\u058d\u058e\u058f\u0590\u05ba\u05c8\u05c9\u05ca\u05cb\u05cc\u05cd\u05ce\u05cf\u05eb\u05ec\u05ed\u05ee\u05ef\u05f5\u05f6\u05f7\u05f8\u05f9\u05fa\u05fb\u05fc\u05fd\u05fe\u05ff\u0604\u0605\u0606\u0607\u0608\u0609\u060a\u0616\u0617\u0618\u0619\u061a\u061c\u061d\u0620\u063b\u063c\u063d\u063e\u063f\u065f\u070e\u074b\u074c\u076e\u076f\u0770\u0771\u0772\u0773\u0774\u0775\u0776\u0777\u0778\u0779\u077a\u077b\u077c\u077d\u077e\u077f\u07b2\u07b3\u07b4\u07b5\u07b6\u07b7\u07b8\u07b9\u07ba\u07bb\u07bc\u07bd\u07be\u07bf\u07c0\u07c1\u07c2\u07c3\u07c4\u07c5\u07c6\u07c7\u07c8\u07c9\u07ca\u07cb\u07cc\u07cd\u07ce\u07cf\u07d0\u07d1\u07d2\u07d3\u07d4\u07d5\u07d6\u07d7\u07d8\u07d9\u07da\u07db\u07dc\u07dd\u07de\u07df\u07e0\u07e1\u07e2\u07e3\u07e4\u07e5\u07e6\u07e7\u07e8\u07e9\u07ea\u07eb\u07ec\u07ed\u07ee\u07ef\u07f0\u07f1\u07f2\u07f3\u07f4\u07f5\u07f6\u07f7\u07f8\u07f9\u07fa\u07fb\u07fc\u07fd\u07fe\u07ff\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f\u0810\u0811\u0812\u0813\u0814\u0815\u0816\u0817\u0818\u0819\u081a\u081b\u081c\u081d\u081e\u081f\u0820\u0821\u0822\u0823\u0824\u0825\u0826\u0827\u0828\u0829\u082a\u082b\u082c\u082d\u082e\u082f\u0830\u0831\u0832\u0833\u0834\u0835\u0836\u0837\u0838\u0839\u083a\u083b\u083c\u083d\u083e\u083f\u0840\u0841\u0842\u0843\u0844\u0845\u0846\u0847\u0848\u0849\u084a\u084b\u084c\u084d\u084e\u084f\u0850\u0851\u0852\u0853\u0854\u0855\u0856\u0857\u0858\u0859\u085a\u085b\u085c\u085d\u085e\u085f\u0860\u0861\u0862\u0863\u0864\u0865\u0866\u0867\u0868\u0869\u086a\u086b\u086c\u086d\u086e\u086f\u0870\u0871\u0872\u0873\u0874\u0875\u0876\u0877\u0878\u0879\u087a\u087b\u087c\u087d\u087e\u087f\u0880\u0881\u0882\u0883\u0884\u0885\u0886\u0887\u0888\u0889\u088a\u088b\u088c\u088d\u088e\u088f\u0890\u0891\u0892\u0893\u0894\u0895\u0896\u0897\u0898\u0899\u089a\u089b\u089c\u089d\u089e\u089f\u08a0\u08a1\u08a2\u08a3\u08a4\u08a5\u08a6\u08a7\u08a8\u08a9\u08aa\u08ab\u08ac\u08ad\u08ae\u08af\u08b0\u08b1\u08b2\u08b3\u08b4\u08b5\u08b6\u08b7\u08b8\u08b9\u08ba\u08bb\u08bc\u08bd\u08be\u08bf\u08c0\u08c1\u08c2\u08c3\u08c4\u08c5\u08c6\u08c7\u08c8\u08c9\u08ca\u08cb\u08cc\u08cd\u08ce\u08cf\u08d0\u08d1\u08d2\u08d3\u08d4\u08d5\u08d6\u08d7\u08d8\u08d9\u08da\u08db\u08dc\u08dd\u08de\u08df\u08e0\u08e1\u08e2\u08e3\u08e4\u08e5\u08e6\u08e7\u08e8\u08e9\u08ea\u08eb\u08ec\u08ed\u08ee\u08ef\u08f0\u08f1\u08f2\u08f3\u08f4\u08f5\u08f6\u08f7\u08f8\u08f9\u08fa\u08fb\u08fc\u08fd\u08fe\u08ff\u0900\u093a\u093b\u094e\u094f\u0955\u0956\u0957\u0971\u0972\u0973\u0974\u0975\u0976\u0977\u0978\u0979\u097a\u097b\u097c\u097e\u097f\u0980\u0984\u098d\u098e\u0991\u0992\u09a9\u09b1\u09b3\u09b4\u09b5\u09ba\u09bb\u09c5\u09c6\u09c9\u09ca\u09cf\u09d0\u09d1\u09d2\u09d3\u09d4\u09d5\u09d6\u09d8\u09d9\u09da\u09db\u09de\u09e4\u09e5\u09fb\u09fc\u09fd\u09fe\u09ff\u0a00\u0a04\u0a0b\u0a0c\u0a0d\u0a0e\u0a11\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a\u0a3b\u0a3d\u0a43\u0a44\u0a45\u0a46\u0a49\u0a4a\u0a4e\u0a4f\u0a50\u0a51\u0a52\u0a53\u0a54\u0a55\u0a56\u0a57\u0a58\u0a5d\u0a5f\u0a60\u0a61\u0a62\u0a63\u0a64\u0a65\u0a75\u0a76\u0a77\u0a78\u0a79\u0a7a\u0a7b\u0a7c\u0a7d\u0a7e\u0a7f\u0a80\u0a84\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba\u0abb\u0ac6\u0aca\u0ace\u0acf\u0ad1\u0ad2\u0ad3\u0ad4\u0ad5\u0ad6\u0ad7\u0ad8\u0ad9\u0ada\u0adb\u0adc\u0add\u0ade\u0adf\u0ae4\u0ae5\u0af0\u0af2\u0af3\u0af4\u0af5\u0af6\u0af7\u0af8\u0af9\u0afa\u0afb\u0afc\u0afd\u0afe\u0aff\u0b00\u0b04\u0b0d\u0b0e\u0b11\u0b12\u0b29\u0b31\u0b34\u0b3a\u0b3b\u0b44\u0b45\u0b46\u0b49\u0b4a\u0b4e\u0b4f\u0b50\u0b51\u0b52\u0b53\u0b54\u0b55\u0b58\u0b59\u0b5a\u0b5b\u0b5e\u0b62\u0b63\u0b64\u0b65\u0b72\u0b73\u0b74\u0b75\u0b76\u0b77\u0b78\u0b79\u0b7a\u0b7b\u0b7c\u0b7d\u0b7e\u0b7f\u0b80\u0b81\u0b84\u0b8b\u0b8c\u0b8d\u0b91\u0b96\u0b97\u0b98\u0b9b\u0b9d\u0ba0\u0ba1\u0ba2\u0ba5\u0ba6\u0ba7\u0bab\u0bac\u0bad\u0bba\u0bbb\u0bbc\u0bbd\u0bc3\u0bc4\u0bc5\u0bc9\u0bce\u0bcf\u0bd0\u0bd1\u0bd2\u0bd3\u0bd4\u0bd5\u0bd6\u0bd8\u0bd9\u0bda\u0bdb\u0bdc\u0bdd\u0bde\u0bdf\u0be0\u0be1\u0be2\u0be3\u0be4\u0be5\u0bfb\u0bfc\u0bfd\u0bfe\u0bff\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a\u0c3b\u0c3c\u0c3d\u0c45\u0c49\u0c4e\u0c4f\u0c50\u0c51\u0c52\u0c53\u0c54\u0c57\u0c58\u0c59\u0c5a\u0c5b\u0c5c\u0c5d\u0c5e\u0c5f\u0c62\u0c63\u0c64\u0c65\u0c70\u0c71\u0c72\u0c73\u0c74\u0c75\u0c76\u0c77\u0c78\u0c79\u0c7a\u0c7b\u0c7c\u0c7d\u0c7e\u0c7f\u0c80\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba\u0cbb\u0cc5\u0cc9\u0cce\u0ccf\u0cd0\u0cd1\u0cd2\u0cd3\u0cd4\u0cd7\u0cd8\u0cd9\u0cda\u0cdb\u0cdc\u0cdd\u0cdf\u0ce2\u0ce3\u0ce4\u0ce5\u0cf0\u0cf1\u0cf2\u0cf3\u0cf4\u0cf5\u0cf6\u0cf7\u0cf8\u0cf9\u0cfa\u0cfb\u0cfc\u0cfd\u0cfe\u0cff\u0d00\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a\u0d3b\u0d3c\u0d3d\u0d44\u0d45\u0d49\u0d4e\u0d4f\u0d50\u0d51\u0d52\u0d53\u0d54\u0d55\u0d56\u0d58\u0d59\u0d5a\u0d5b\u0d5c\u0d5d\u0d5e\u0d5f\u0d62\u0d63\u0d64\u0d65\u0d70\u0d71\u0d72\u0d73\u0d74\u0d75\u0d76\u0d77\u0d78\u0d79\u0d7a\u0d7b\u0d7c\u0d7d\u0d7e\u0d7f\u0d80\u0d81\u0d84\u0d97\u0d98\u0d99\u0db2\u0dbc\u0dbe\u0dbf\u0dc7\u0dc8\u0dc9\u0dcb\u0dcc\u0dcd\u0dce\u0dd5\u0dd7\u0de0\u0de1\u0de2\u0de3\u0de4\u0de5\u0de6\u0de7\u0de8\u0de9\u0dea\u0deb\u0dec\u0ded\u0dee\u0def\u0df0\u0df1\u0df5\u0df6\u0df7\u0df8\u0df9\u0dfa\u0dfb\u0dfc\u0dfd\u0dfe\u0dff\u0e00\u0e3b\u0e3c\u0e3d\u0e3e\u0e5c\u0e5d\u0e5e\u0e5f\u0e60\u0e61\u0e62\u0e63\u0e64\u0e65\u0e66\u0e67\u0e68\u0e69\u0e6a\u0e6b\u0e6c\u0e6d\u0e6e\u0e6f\u0e70\u0e71\u0e72\u0e73\u0e74\u0e75\u0e76\u0e77\u0e78\u0e79\u0e7a\u0e7b\u0e7c\u0e7d\u0e7e\u0e7f\u0e80\u0e83\u0e85\u0e86\u0e89\u0e8b\u0e8c\u0e8e\u0e8f\u0e90\u0e91\u0e92\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8\u0ea9\u0eac\u0eba\u0ebe\u0ebf\u0ec5\u0ec7\u0ece\u0ecf\u0eda\u0edb\u0ede\u0edf\u0ee0\u0ee1\u0ee2\u0ee3\u0ee4\u0ee5\u0ee6\u0ee7\u0ee8\u0ee9\u0eea\u0eeb\u0eec\u0eed\u0eee\u0eef\u0ef0\u0ef1\u0ef2\u0ef3\u0ef4\u0ef5\u0ef6\u0ef7\u0ef8\u0ef9\u0efa\u0efb\u0efc\u0efd\u0efe\u0eff\u0f48\u0f6b\u0f6c\u0f6d\u0f6e\u0f6f\u0f70\u0f8c\u0f8d\u0f8e\u0f8f\u0f98\u0fbd\u0fcd\u0fce\u0fd2\u0fd3\u0fd4\u0fd5\u0fd6\u0fd7\u0fd8\u0fd9\u0fda\u0fdb\u0fdc\u0fdd\u0fde\u0fdf\u0fe0\u0fe1\u0fe2\u0fe3\u0fe4\u0fe5\u0fe6\u0fe7\u0fe8\u0fe9\u0fea\u0feb\u0fec\u0fed\u0fee\u0fef\u0ff0\u0ff1\u0ff2\u0ff3\u0ff4\u0ff5\u0ff6\u0ff7\u0ff8\u0ff9\u0ffa\u0ffb\u0ffc\u0ffd\u0ffe\u0fff\u1022\u1028\u102b\u1033\u1034\u1035\u103a\u103b\u103c\u103d\u103e\u103f\u105a\u105b\u105c\u105d\u105e\u105f\u1060\u1061\u1062\u1063\u1064\u1065\u1066\u1067\u1068\u1069\u106a\u106b\u106c\u106d\u106e\u106f\u1070\u1071\u1072\u1073\u1074\u1075\u1076\u1077\u1078\u1079\u107a\u107b\u107c\u107d\u107e\u107f\u1080\u1081\u1082\u1083\u1084\u1085\u1086\u1087\u1088\u1089\u108a\u108b\u108c\u108d\u108e\u108f\u1090\u1091\u1092\u1093\u1094\u1095\u1096\u1097\u1098\u1099\u109a\u109b\u109c\u109d\u109e\u109f\u10c6\u10c7\u10c8\u10c9\u10ca\u10cb\u10cc\u10cd\u10ce\u10cf\u10fd\u10fe\u10ff\u115a\u115b\u115c\u115d\u115e\u11a3\u11a4\u11a5\u11a6\u11a7\u11fa\u11fb\u11fc\u11fd\u11fe\u11ff\u1249\u124e\u124f\u1257\u1259\u125e\u125f\u1289\u128e\u128f\u12b1\u12b6\u12b7\u12bf\u12c1\u12c6\u12c7\u12d7\u1311\u1316\u1317\u135b\u135c\u135d\u135e\u137d\u137e\u137f\u139a\u139b\u139c\u139d\u139e\u139f\u13f5\u13f6\u13f7\u13f8\u13f9\u13fa\u13fb\u13fc\u13fd\u13fe\u13ff\u1400\u1677\u1678\u1679\u167a\u167b\u167c\u167d\u167e\u167f\u169d\u169e\u169f\u16f1\u16f2\u16f3\u16f4\u16f5\u16f6\u16f7\u16f8\u16f9\u16fa\u16fb\u16fc\u16fd\u16fe\u16ff\u170d\u1715\u1716\u1717\u1718\u1719\u171a\u171b\u171c\u171d\u171e\u171f\u1737\u1738\u1739\u173a\u173b\u173c\u173d\u173e\u173f\u1754\u1755\u1756\u1757\u1758\u1759\u175a\u175b\u175c\u175d\u175e\u175f\u176d\u1771\u1774\u1775\u1776\u1777\u1778\u1779\u177a\u177b\u177c\u177d\u177e\u177f\u17de\u17df\u17ea\u17eb\u17ec\u17ed\u17ee\u17ef\u17fa\u17fb\u17fc\u17fd\u17fe\u17ff\u180f\u181a\u181b\u181c\u181d\u181e\u181f\u1878\u1879\u187a\u187b\u187c\u187d\u187e\u187f\u18aa\u18ab\u18ac\u18ad\u18ae\u18af\u18b0\u18b1\u18b2\u18b3\u18b4\u18b5\u18b6\u18b7\u18b8\u18b9\u18ba\u18bb\u18bc\u18bd\u18be\u18bf\u18c0\u18c1\u18c2\u18c3\u18c4\u18c5\u18c6\u18c7\u18c8\u18c9\u18ca\u18cb\u18cc\u18cd\u18ce\u18cf\u18d0\u18d1\u18d2\u18d3\u18d4\u18d5\u18d6\u18d7\u18d8\u18d9\u18da\u18db\u18dc\u18dd\u18de\u18df\u18e0\u18e1\u18e2\u18e3\u18e4\u18e5\u18e6\u18e7\u18e8\u18e9\u18ea\u18eb\u18ec\u18ed\u18ee\u18ef\u18f0\u18f1\u18f2\u18f3\u18f4\u18f5\u18f6\u18f7\u18f8\u18f9\u18fa\u18fb\u18fc\u18fd\u18fe\u18ff\u191d\u191e\u191f\u192c\u192d\u192e\u192f\u193c\u193d\u193e\u193f\u1941\u1942\u1943\u196e\u196f\u1975\u1976\u1977\u1978\u1979\u197a\u197b\u197c\u197d\u197e\u197f\u19aa\u19ab\u19ac\u19ad\u19ae\u19af\u19ca\u19cb\u19cc\u19cd\u19ce\u19cf\u19da\u19db\u19dc\u19dd\u1a1c\u1a1d\u1a20\u1a21\u1a22\u1a23\u1a24\u1a25\u1a26\u1a27\u1a28\u1a29\u1a2a\u1a2b\u1a2c\u1a2d\u1a2e\u1a2f\u1a30\u1a31\u1a32\u1a33\u1a34\u1a35\u1a36\u1a37\u1a38\u1a39\u1a3a\u1a3b\u1a3c\u1a3d\u1a3e\u1a3f\u1a40\u1a41\u1a42\u1a43\u1a44\u1a45\u1a46\u1a47\u1a48\u1a49\u1a4a\u1a4b\u1a4c\u1a4d\u1a4e\u1a4f\u1a50\u1a51\u1a52\u1a53\u1a54\u1a55\u1a56\u1a57\u1a58\u1a59\u1a5a\u1a5b\u1a5c\u1a5d\u1a5e\u1a5f\u1a60\u1a61\u1a62\u1a63\u1a64\u1a65\u1a66\u1a67\u1a68\u1a69\u1a6a\u1a6b\u1a6c\u1a6d\u1a6e\u1a6f\u1a70\u1a71\u1a72\u1a73\u1a74\u1a75\u1a76\u1a77\u1a78\u1a79\u1a7a\u1a7b\u1a7c\u1a7d\u1a7e\u1a7f\u1a80\u1a81\u1a82\u1a83\u1a84\u1a85\u1a86\u1a87\u1a88\u1a89\u1a8a\u1a8b\u1a8c\u1a8d\u1a8e\u1a8f\u1a90\u1a91\u1a92\u1a93\u1a94\u1a95\u1a96\u1a97\u1a98\u1a99\u1a9a\u1a9b\u1a9c\u1a9d\u1a9e\u1a9f\u1aa0\u1aa1\u1aa2\u1aa3\u1aa4\u1aa5\u1aa6\u1aa7\u1aa8\u1aa9\u1aaa\u1aab\u1aac\u1aad\u1aae\u1aaf\u1ab0\u1ab1\u1ab2\u1ab3\u1ab4\u1ab5\u1ab6\u1ab7\u1ab8\u1ab9\u1aba\u1abb\u1abc\u1abd\u1abe\u1abf\u1ac0\u1ac1\u1ac2\u1ac3\u1ac4\u1ac5\u1ac6\u1ac7\u1ac8\u1ac9\u1aca\u1acb\u1acc\u1acd\u1ace\u1acf\u1ad0\u1ad1\u1ad2\u1ad3\u1ad4\u1ad5\u1ad6\u1ad7\u1ad8\u1ad9\u1ada\u1adb\u1adc\u1add\u1ade\u1adf\u1ae0\u1ae1\u1ae2\u1ae3\u1ae4\u1ae5\u1ae6\u1ae7\u1ae8\u1ae9\u1aea\u1aeb\u1aec\u1aed\u1aee\u1aef\u1af0\u1af1\u1af2\u1af3\u1af4\u1af5\u1af6\u1af7\u1af8\u1af9\u1afa\u1afb\u1afc\u1afd\u1afe\u1aff\u1b00\u1b01\u1b02\u1b03\u1b04\u1b05\u1b06\u1b07\u1b08\u1b09\u1b0a\u1b0b\u1b0c\u1b0d\u1b0e\u1b0f\u1b10\u1b11\u1b12\u1b13\u1b14\u1b15\u1b16\u1b17\u1b18\u1b19\u1b1a\u1b1b\u1b1c\u1b1d\u1b1e\u1b1f\u1b20\u1b21\u1b22\u1b23\u1b24\u1b25\u1b26\u1b27\u1b28\u1b29\u1b2a\u1b2b\u1b2c\u1b2d\u1b2e\u1b2f\u1b30\u1b31\u1b32\u1b33\u1b34\u1b35\u1b36\u1b37\u1b38\u1b39\u1b3a\u1b3b\u1b3c\u1b3d\u1b3e\u1b3f\u1b40\u1b41\u1b42\u1b43\u1b44\u1b45\u1b46\u1b47\u1b48\u1b49\u1b4a\u1b4b\u1b4c\u1b4d\u1b4e\u1b4f\u1b50\u1b51\u1b52\u1b53\u1b54\u1b55\u1b56\u1b57\u1b58\u1b59\u1b5a\u1b5b\u1b5c\u1b5d\u1b5e\u1b5f\u1b60\u1b61\u1b62\u1b63\u1b64\u1b65\u1b66\u1b67\u1b68\u1b69\u1b6a\u1b6b\u1b6c\u1b6d\u1b6e\u1b6f\u1b70\u1b71\u1b72\u1b73\u1b74\u1b75\u1b76\u1b77\u1b78\u1b79\u1b7a\u1b7b\u1b7c\u1b7d\u1b7e\u1b7f\u1b80\u1b81\u1b82\u1b83\u1b84\u1b85\u1b86\u1b87\u1b88\u1b89\u1b8a\u1b8b\u1b8c\u1b8d\u1b8e\u1b8f\u1b90\u1b91\u1b92\u1b93\u1b94\u1b95\u1b96\u1b97\u1b98\u1b99\u1b9a\u1b9b\u1b9c\u1b9d\u1b9e\u1b9f\u1ba0\u1ba1\u1ba2\u1ba3\u1ba4\u1ba5\u1ba6\u1ba7\u1ba8\u1ba9\u1baa\u1bab\u1bac\u1bad\u1bae\u1baf\u1bb0\u1bb1\u1bb2\u1bb3\u1bb4\u1bb5\u1bb6\u1bb7\u1bb8\u1bb9\u1bba\u1bbb\u1bbc\u1bbd\u1bbe\u1bbf\u1bc0\u1bc1\u1bc2\u1bc3\u1bc4\u1bc5\u1bc6\u1bc7\u1bc8\u1bc9\u1bca\u1bcb\u1bcc\u1bcd\u1bce\u1bcf\u1bd0\u1bd1\u1bd2\u1bd3\u1bd4\u1bd5\u1bd6\u1bd7\u1bd8\u1bd9\u1bda\u1bdb\u1bdc\u1bdd\u1bde\u1bdf\u1be0\u1be1\u1be2\u1be3\u1be4\u1be5\u1be6\u1be7\u1be8\u1be9\u1bea\u1beb\u1bec\u1bed\u1bee\u1bef\u1bf0\u1bf1\u1bf2\u1bf3\u1bf4\u1bf5\u1bf6\u1bf7\u1bf8\u1bf9\u1bfa\u1bfb\u1bfc\u1bfd\u1bfe\u1bff\u1c00\u1c01\u1c02\u1c03\u1c04\u1c05\u1c06\u1c07\u1c08\u1c09\u1c0a\u1c0b\u1c0c\u1c0d\u1c0e\u1c0f\u1c10\u1c11\u1c12\u1c13\u1c14\u1c15\u1c16\u1c17\u1c18\u1c19\u1c1a\u1c1b\u1c1c\u1c1d\u1c1e\u1c1f\u1c20\u1c21\u1c22\u1c23\u1c24\u1c25\u1c26\u1c27\u1c28\u1c29\u1c2a\u1c2b\u1c2c\u1c2d\u1c2e\u1c2f\u1c30\u1c31\u1c32\u1c33\u1c34\u1c35\u1c36\u1c37\u1c38\u1c39\u1c3a\u1c3b\u1c3c\u1c3d\u1c3e\u1c3f\u1c40\u1c41\u1c42\u1c43\u1c44\u1c45\u1c46\u1c47\u1c48\u1c49\u1c4a\u1c4b\u1c4c\u1c4d\u1c4e\u1c4f\u1c50\u1c51\u1c52\u1c53\u1c54\u1c55\u1c56\u1c57\u1c58\u1c59\u1c5a\u1c5b\u1c5c\u1c5d\u1c5e\u1c5f\u1c60\u1c61\u1c62\u1c63\u1c64\u1c65\u1c66\u1c67\u1c68\u1c69\u1c6a\u1c6b\u1c6c\u1c6d\u1c6e\u1c6f\u1c70\u1c71\u1c72\u1c73\u1c74\u1c75\u1c76\u1c77\u1c78\u1c79\u1c7a\u1c7b\u1c7c\u1c7d\u1c7e\u1c7f\u1c80\u1c81\u1c82\u1c83\u1c84\u1c85\u1c86\u1c87\u1c88\u1c89\u1c8a\u1c8b\u1c8c\u1c8d\u1c8e\u1c8f\u1c90\u1c91\u1c92\u1c93\u1c94\u1c95\u1c96\u1c97\u1c98\u1c99\u1c9a\u1c9b\u1c9c\u1c9d\u1c9e\u1c9f\u1ca0\u1ca1\u1ca2\u1ca3\u1ca4\u1ca5\u1ca6\u1ca7\u1ca8\u1ca9\u1caa\u1cab\u1cac\u1cad\u1cae\u1caf\u1cb0\u1cb1\u1cb2\u1cb3\u1cb4\u1cb5\u1cb6\u1cb7\u1cb8\u1cb9\u1cba\u1cbb\u1cbc\u1cbd\u1cbe\u1cbf\u1cc0\u1cc1\u1cc2\u1cc3\u1cc4\u1cc5\u1cc6\u1cc7\u1cc8\u1cc9\u1cca\u1ccb\u1ccc\u1ccd\u1cce\u1ccf\u1cd0\u1cd1\u1cd2\u1cd3\u1cd4\u1cd5\u1cd6\u1cd7\u1cd8\u1cd9\u1cda\u1cdb\u1cdc\u1cdd\u1cde\u1cdf\u1ce0\u1ce1\u1ce2\u1ce3\u1ce4\u1ce5\u1ce6\u1ce7\u1ce8\u1ce9\u1cea\u1ceb\u1cec\u1ced\u1cee\u1cef\u1cf0\u1cf1\u1cf2\u1cf3\u1cf4\u1cf5\u1cf6\u1cf7\u1cf8\u1cf9\u1cfa\u1cfb\u1cfc\u1cfd\u1cfe\u1cff\u1dc4\u1dc5\u1dc6\u1dc7\u1dc8\u1dc9\u1dca\u1dcb\u1dcc\u1dcd\u1dce\u1dcf\u1dd0\u1dd1\u1dd2\u1dd3\u1dd4\u1dd5\u1dd6\u1dd7\u1dd8\u1dd9\u1dda\u1ddb\u1ddc\u1ddd\u1dde\u1ddf\u1de0\u1de1\u1de2\u1de3\u1de4\u1de5\u1de6\u1de7\u1de8\u1de9\u1dea\u1deb\u1dec\u1ded\u1dee\u1def\u1df0\u1df1\u1df2\u1df3\u1df4\u1df5\u1df6\u1df7\u1df8\u1df9\u1dfa\u1dfb\u1dfc\u1dfd\u1dfe\u1dff\u1e9c\u1e9d\u1e9e\u1e9f\u1efa\u1efb\u1efc\u1efd\u1efe\u1eff\u1f16\u1f17\u1f1e\u1f1f\u1f46\u1f47\u1f4e\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e\u1f7f\u1fb5\u1fc5\u1fd4\u1fd5\u1fdc\u1ff0\u1ff1\u1ff5\u1fff\u2064\u2065\u2066\u2067\u2068\u2069\u2072\u2073\u208f\u2095\u2096\u2097\u2098\u2099\u209a\u209b\u209c\u209d\u209e\u209f\u20b6\u20b7\u20b8\u20b9\u20ba\u20bb\u20bc\u20bd\u20be\u20bf\u20c0\u20c1\u20c2\u20c3\u20c4\u20c5\u20c6\u20c7\u20c8\u20c9\u20ca\u20cb\u20cc\u20cd\u20ce\u20cf\u20ec\u20ed\u20ee\u20ef\u20f0\u20f1\u20f2\u20f3\u20f4\u20f5\u20f6\u20f7\u20f8\u20f9\u20fa\u20fb\u20fc\u20fd\u20fe\u20ff\u214d\u214e\u214f\u2150\u2151\u2152\u2184\u2185\u2186\u2187\u2188\u2189\u218a\u218b\u218c\u218d\u218e\u218f\u23dc\u23dd\u23de\u23df\u23e0\u23e1\u23e2\u23e3\u23e4\u23e5\u23e6\u23e7\u23e8\u23e9\u23ea\u23eb\u23ec\u23ed\u23ee\u23ef\u23f0\u23f1\u23f2\u23f3\u23f4\u23f5\u23f6\u23f7\u23f8\u23f9\u23fa\u23fb\u23fc\u23fd\u23fe\u23ff\u2427\u2428\u2429\u242a\u242b\u242c\u242d\u242e\u242f\u2430\u2431\u2432\u2433\u2434\u2435\u2436\u2437\u2438\u2439\u243a\u243b\u243c\u243d\u243e\u243f\u244b\u244c\u244d\u244e\u244f\u2450\u2451\u2452\u2453\u2454\u2455\u2456\u2457\u2458\u2459\u245a\u245b\u245c\u245d\u245e\u245f\u269d\u269e\u269f\u26b2\u26b3\u26b4\u26b5\u26b6\u26b7\u26b8\u26b9\u26ba\u26bb\u26bc\u26bd\u26be\u26bf\u26c0\u26c1\u26c2\u26c3\u26c4\u26c5\u26c6\u26c7\u26c8\u26c9\u26ca\u26cb\u26cc\u26cd\u26ce\u26cf\u26d0\u26d1\u26d2\u26d3\u26d4\u26d5\u26d6\u26d7\u26d8\u26d9\u26da\u26db\u26dc\u26dd\u26de\u26df\u26e0\u26e1\u26e2\u26e3\u26e4\u26e5\u26e6\u26e7\u26e8\u26e9\u26ea\u26eb\u26ec\u26ed\u26ee\u26ef\u26f0\u26f1\u26f2\u26f3\u26f4\u26f5\u26f6\u26f7\u26f8\u26f9\u26fa\u26fb\u26fc\u26fd\u26fe\u26ff\u2700\u2705\u270a\u270b\u2728\u274c\u274e\u2753\u2754\u2755\u2757\u275f\u2760\u2795\u2796\u2797\u27b0\u27bf\u27c7\u27c8\u27c9\u27ca\u27cb\u27cc\u27cd\u27ce\u27cf\u27ec\u27ed\u27ee\u27ef\u2b14\u2b15\u2b16\u2b17\u2b18\u2b19\u2b1a\u2b1b\u2b1c\u2b1d\u2b1e\u2b1f\u2b20\u2b21\u2b22\u2b23\u2b24\u2b25\u2b26\u2b27\u2b28\u2b29\u2b2a\u2b2b\u2b2c\u2b2d\u2b2e\u2b2f\u2b30\u2b31\u2b32\u2b33\u2b34\u2b35\u2b36\u2b37\u2b38\u2b39\u2b3a\u2b3b\u2b3c\u2b3d\u2b3e\u2b3f\u2b40\u2b41\u2b42\u2b43\u2b44\u2b45\u2b46\u2b47\u2b48\u2b49\u2b4a\u2b4b\u2b4c\u2b4d\u2b4e\u2b4f\u2b50\u2b51\u2b52\u2b53\u2b54\u2b55\u2b56\u2b57\u2b58\u2b59\u2b5a\u2b5b\u2b5c\u2b5d\u2b5e\u2b5f\u2b60\u2b61\u2b62\u2b63\u2b64\u2b65\u2b66\u2b67\u2b68\u2b69\u2b6a\u2b6b\u2b6c\u2b6d\u2b6e\u2b6f\u2b70\u2b71\u2b72\u2b73\u2b74\u2b75\u2b76\u2b77\u2b78\u2b79\u2b7a\u2b7b\u2b7c\u2b7d\u2b7e\u2b7f\u2b80\u2b81\u2b82\u2b83\u2b84\u2b85\u2b86\u2b87\u2b88\u2b89\u2b8a\u2b8b\u2b8c\u2b8d\u2b8e\u2b8f\u2b90\u2b91\u2b92\u2b93\u2b94\u2b95\u2b96\u2b97\u2b98\u2b99\u2b9a\u2b9b\u2b9c\u2b9d\u2b9e\u2b9f\u2ba0\u2ba1\u2ba2\u2ba3\u2ba4\u2ba5\u2ba6\u2ba7\u2ba8\u2ba9\u2baa\u2bab\u2bac\u2bad\u2bae\u2baf\u2bb0\u2bb1\u2bb2\u2bb3\u2bb4\u2bb5\u2bb6\u2bb7\u2bb8\u2bb9\u2bba\u2bbb\u2bbc\u2bbd\u2bbe\u2bbf\u2bc0\u2bc1\u2bc2\u2bc3\u2bc4\u2bc5\u2bc6\u2bc7\u2bc8\u2bc9\u2bca\u2bcb\u2bcc\u2bcd\u2bce\u2bcf\u2bd0\u2bd1\u2bd2\u2bd3\u2bd4\u2bd5\u2bd6\u2bd7\u2bd8\u2bd9\u2bda\u2bdb\u2bdc\u2bdd\u2bde\u2bdf\u2be0\u2be1\u2be2\u2be3\u2be4\u2be5\u2be6\u2be7\u2be8\u2be9\u2bea\u2beb\u2bec\u2bed\u2bee\u2bef\u2bf0\u2bf1\u2bf2\u2bf3\u2bf4\u2bf5\u2bf6\u2bf7\u2bf8\u2bf9\u2bfa\u2bfb\u2bfc\u2bfd\u2bfe\u2bff\u2c2f\u2c5f\u2c60\u2c61\u2c62\u2c63\u2c64\u2c65\u2c66\u2c67\u2c68\u2c69\u2c6a\u2c6b\u2c6c\u2c6d\u2c6e\u2c6f\u2c70\u2c71\u2c72\u2c73\u2c74\u2c75\u2c76\u2c77\u2c78\u2c79\u2c7a\u2c7b\u2c7c\u2c7d\u2c7e\u2c7f\u2ceb\u2cec\u2ced\u2cee\u2cef\u2cf0\u2cf1\u2cf2\u2cf3\u2cf4\u2cf5\u2cf6\u2cf7\u2cf8\u2d26\u2d27\u2d28\u2d29\u2d2a\u2d2b\u2d2c\u2d2d\u2d2e\u2d2f\u2d66\u2d67\u2d68\u2d69\u2d6a\u2d6b\u2d6c\u2d6d\u2d6e\u2d70\u2d71\u2d72\u2d73\u2d74\u2d75\u2d76\u2d77\u2d78\u2d79\u2d7a\u2d7b\u2d7c\u2d7d\u2d7e\u2d7f\u2d97\u2d98\u2d99\u2d9a\u2d9b\u2d9c\u2d9d\u2d9e\u2d9f\u2da7\u2daf\u2db7\u2dbf\u2dc7\u2dcf\u2dd7\u2ddf\u2de0\u2de1\u2de2\u2de3\u2de4\u2de5\u2de6\u2de7\u2de8\u2de9\u2dea\u2deb\u2dec\u2ded\u2dee\u2def\u2df0\u2df1\u2df2\u2df3\u2df4\u2df5\u2df6\u2df7\u2df8\u2df9\u2dfa\u2dfb\u2dfc\u2dfd\u2dfe\u2dff\u2e18\u2e19\u2e1a\u2e1b\u2e1e\u2e1f\u2e20\u2e21\u2e22\u2e23\u2e24\u2e25\u2e26\u2e27\u2e28\u2e29\u2e2a\u2e2b\u2e2c\u2e2d\u2e2e\u2e2f\u2e30\u2e31\u2e32\u2e33\u2e34\u2e35\u2e36\u2e37\u2e38\u2e39\u2e3a\u2e3b\u2e3c\u2e3d\u2e3e\u2e3f\u2e40\u2e41\u2e42\u2e43\u2e44\u2e45\u2e46\u2e47\u2e48\u2e49\u2e4a\u2e4b\u2e4c\u2e4d\u2e4e\u2e4f\u2e50\u2e51\u2e52\u2e53\u2e54\u2e55\u2e56\u2e57\u2e58\u2e59\u2e5a\u2e5b\u2e5c\u2e5d\u2e5e\u2e5f\u2e60\u2e61\u2e62\u2e63\u2e64\u2e65\u2e66\u2e67\u2e68\u2e69\u2e6a\u2e6b\u2e6c\u2e6d\u2e6e\u2e6f\u2e70\u2e71\u2e72\u2e73\u2e74\u2e75\u2e76\u2e77\u2e78\u2e79\u2e7a\u2e7b\u2e7c\u2e7d\u2e7e\u2e7f\u2e9a\u2ef4\u2ef5\u2ef6\u2ef7\u2ef8\u2ef9\u2efa\u2efb\u2efc\u2efd\u2efe\u2eff\u2fd6\u2fd7\u2fd8\u2fd9\u2fda\u2fdb\u2fdc\u2fdd\u2fde\u2fdf\u2fe0\u2fe1\u2fe2\u2fe3\u2fe4\u2fe5\u2fe6\u2fe7\u2fe8\u2fe9\u2fea\u2feb\u2fec\u2fed\u2fee\u2fef\u2ffc\u2ffd\u2ffe\u2fff\u3040\u3097\u3098\u3100\u3101\u3102\u3103\u3104\u312d\u312e\u312f\u3130\u318f\u31b8\u31b9\u31ba\u31bb\u31bc\u31bd\u31be\u31bf\u31d0\u31d1\u31d2\u31d3\u31d4\u31d5\u31d6\u31d7\u31d8\u31d9\u31da\u31db\u31dc\u31dd\u31de\u31df\u31e0\u31e1\u31e2\u31e3\u31e4\u31e5\u31e6\u31e7\u31e8\u31e9\u31ea\u31eb\u31ec\u31ed\u31ee\u31ef\u321f\u3244\u3245\u3246\u3247\u3248\u3249\u324a\u324b\u324c\u324d\u324e\u324f\u32ff\u4db6\u4db7\u4db8\u4db9\u4dba\u4dbb\u4dbc\u4dbd\u4dbe\u4dbf\u9fbc\u9fbd\u9fbe\u9fbf\u9fc0\u9fc1\u9fc2\u9fc3\u9fc4\u9fc5\u9fc6\u9fc7\u9fc8\u9fc9\u9fca\u9fcb\u9fcc\u9fcd\u9fce\u9fcf\u9fd0\u9fd1\u9fd2\u9fd3\u9fd4\u9fd5\u9fd6\u9fd7\u9fd8\u9fd9\u9fda\u9fdb\u9fdc\u9fdd\u9fde\u9fdf\u9fe0\u9fe1\u9fe2\u9fe3\u9fe4\u9fe5\u9fe6\u9fe7\u9fe8\u9fe9\u9fea\u9feb\u9fec\u9fed\u9fee\u9fef\u9ff0\u9ff1\u9ff2\u9ff3\u9ff4\u9ff5\u9ff6\u9ff7\u9ff8\u9ff9\u9ffa\u9ffb\u9ffc\u9ffd\u9ffe\u9fff\ua48d\ua48e\ua48f\ua4c7\ua4c8\ua4c9\ua4ca\ua4cb\ua4cc\ua4cd\ua4ce\ua4cf\ua4d0\ua4d1\ua4d2\ua4d3\ua4d4\ua4d5\ua4d6\ua4d7\ua4d8\ua4d9\ua4da\ua4db\ua4dc\ua4dd\ua4de\ua4df\ua4e0\ua4e1\ua4e2\ua4e3\ua4e4\ua4e5\ua4e6\ua4e7\ua4e8\ua4e9\ua4ea\ua4eb\ua4ec\ua4ed\ua4ee\ua4ef\ua4f0\ua4f1\ua4f2\ua4f3\ua4f4\ua4f5\ua4f6\ua4f7\ua4f8\ua4f9\ua4fa\ua4fb\ua4fc\ua4fd\ua4fe\ua4ff\ua500\ua501\ua502\ua503\ua504\ua505\ua506\ua507\ua508\ua509\ua50a\ua50b\ua50c\ua50d\ua50e\ua50f\ua510\ua511\ua512\ua513\ua514\ua515\ua516\ua517\ua518\ua519\ua51a\ua51b\ua51c\ua51d\ua51e\ua51f\ua520\ua521\ua522\ua523\ua524\ua525\ua526\ua527\ua528\ua529\ua52a\ua52b\ua52c\ua52d\ua52e\ua52f\ua530\ua531\ua532\ua533\ua534\ua535\ua536\ua537\ua538\ua539\ua53a\ua53b\ua53c\ua53d\ua53e\ua53f\ua540\ua541\ua542\ua543\ua544\ua545\ua546\ua547\ua548\ua549\ua54a\ua54b\ua54c\ua54d\ua54e\ua54f\ua550\ua551\ua552\ua553\ua554\ua555\ua556\ua557\ua558\ua559\ua55a\ua55b\ua55c\ua55d\ua55e\ua55f\ua560\ua561\ua562\ua563\ua564\ua565\ua566\ua567\ua568\ua569\ua56a\ua56b\ua56c\ua56d\ua56e\ua56f\ua570\ua571\ua572\ua573\ua574\ua575\ua576\ua577\ua578\ua579\ua57a\ua57b\ua57c\ua57d\ua57e\ua57f\ua580\ua581\ua582\ua583\ua584\ua585\ua586\ua587\ua588\ua589\ua58a\ua58b\ua58c\ua58d\ua58e\ua58f\ua590\ua591\ua592\ua593\ua594\ua595\ua596\ua597\ua598\ua599\ua59a\ua59b\ua59c\ua59d\ua59e\ua59f\ua5a0\ua5a1\ua5a2\ua5a3\ua5a4\ua5a5\ua5a6\ua5a7\ua5a8\ua5a9\ua5aa\ua5ab\ua5ac\ua5ad\ua5ae\ua5af\ua5b0\ua5b1\ua5b2\ua5b3\ua5b4\ua5b5\ua5b6\ua5b7\ua5b8\ua5b9\ua5ba\ua5bb\ua5bc\ua5bd\ua5be\ua5bf\ua5c0\ua5c1\ua5c2\ua5c3\ua5c4\ua5c5\ua5c6\ua5c7\ua5c8\ua5c9\ua5ca\ua5cb\ua5cc\ua5cd\ua5ce\ua5cf\ua5d0\ua5d1\ua5d2\ua5d3\ua5d4\ua5d5\ua5d6\ua5d7\ua5d8\ua5d9\ua5da\ua5db\ua5dc\ua5dd\ua5de\ua5df\ua5e0\ua5e1\ua5e2\ua5e3\ua5e4\ua5e5\ua5e6\ua5e7\ua5e8\ua5e9\ua5ea\ua5eb\ua5ec\ua5ed\ua5ee\ua5ef\ua5f0\ua5f1\ua5f2\ua5f3\ua5f4\ua5f5\ua5f6\ua5f7\ua5f8\ua5f9\ua5fa\ua5fb\ua5fc\ua5fd\ua5fe\ua5ff\ua600\ua601\ua602\ua603\ua604\ua605\ua606\ua607\ua608\ua609\ua60a\ua60b\ua60c\ua60d\ua60e\ua60f\ua610\ua611\ua612\ua613\ua614\ua615\ua616\ua617\ua618\ua619\ua61a\ua61b\ua61c\ua61d\ua61e\ua61f\ua620\ua621\ua622\ua623\ua624\ua625\ua626\ua627\ua628\ua629\ua62a\ua62b\ua62c\ua62d\ua62e\ua62f\ua630\ua631\ua632\ua633\ua634\ua635\ua636\ua637\ua638\ua639\ua63a\ua63b\ua63c\ua63d\ua63e\ua63f\ua640\ua641\ua642\ua643\ua644\ua645\ua646\ua647\ua648\ua649\ua64a\ua64b\ua64c\ua64d\ua64e\ua64f\ua650\ua651\ua652\ua653\ua654\ua655\ua656\ua657\ua658\ua659\ua65a\ua65b\ua65c\ua65d\ua65e\ua65f\ua660\ua661\ua662\ua663\ua664\ua665\ua666\ua667\ua668\ua669\ua66a\ua66b\ua66c\ua66d\ua66e\ua66f\ua670\ua671\ua672\ua673\ua674\ua675\ua676\ua677\ua678\ua679\ua67a\ua67b\ua67c\ua67d\ua67e\ua67f\ua680\ua681\ua682\ua683\ua684\ua685\ua686\ua687\ua688\ua689\ua68a\ua68b\ua68c\ua68d\ua68e\ua68f\ua690\ua691\ua692\ua693\ua694\ua695\ua696\ua697\ua698\ua699\ua69a\ua69b\ua69c\ua69d\ua69e\ua69f\ua6a0\ua6a1\ua6a2\ua6a3\ua6a4\ua6a5\ua6a6\ua6a7\ua6a8\ua6a9\ua6aa\ua6ab\ua6ac\ua6ad\ua6ae\ua6af\ua6b0\ua6b1\ua6b2\ua6b3\ua6b4\ua6b5\ua6b6\ua6b7\ua6b8\ua6b9\ua6ba\ua6bb\ua6bc\ua6bd\ua6be\ua6bf\ua6c0\ua6c1\ua6c2\ua6c3\ua6c4\ua6c5\ua6c6\ua6c7\ua6c8\ua6c9\ua6ca\ua6cb\ua6cc\ua6cd\ua6ce\ua6cf\ua6d0\ua6d1\ua6d2\ua6d3\ua6d4\ua6d5\ua6d6\ua6d7\ua6d8\ua6d9\ua6da\ua6db\ua6dc\ua6dd\ua6de\ua6df\ua6e0\ua6e1\ua6e2\ua6e3\ua6e4\ua6e5\ua6e6\ua6e7\ua6e8\ua6e9\ua6ea\ua6eb\ua6ec\ua6ed\ua6ee\ua6ef\ua6f0\ua6f1\ua6f2\ua6f3\ua6f4\ua6f5\ua6f6\ua6f7\ua6f8\ua6f9\ua6fa\ua6fb\ua6fc\ua6fd\ua6fe\ua6ff\ua717\ua718\ua719\ua71a\ua71b\ua71c\ua71d\ua71e\ua71f\ua720\ua721\ua722\ua723\ua724\ua725\ua726\ua727\ua728\ua729\ua72a\ua72b\ua72c\ua72d\ua72e\ua72f\ua730\ua731\ua732\ua733\ua734\ua735\ua736\ua737\ua738\ua739\ua73a\ua73b\ua73c\ua73d\ua73e\ua73f\ua740\ua741\ua742\ua743\ua744\ua745\ua746\ua747\ua748\ua749\ua74a\ua74b\ua74c\ua74d\ua74e\ua74f\ua750\ua751\ua752\ua753\ua754\ua755\ua756\ua757\ua758\ua759\ua75a\ua75b\ua75c\ua75d\ua75e\ua75f\ua760\ua761\ua762\ua763\ua764\ua765\ua766\ua767\ua768\ua769\ua76a\ua76b\ua76c\ua76d\ua76e\ua76f\ua770\ua771\ua772\ua773\ua774\ua775\ua776\ua777\ua778\ua779\ua77a\ua77b\ua77c\ua77d\ua77e\ua77f\ua780\ua781\ua782\ua783\ua784\ua785\ua786\ua787\ua788\ua789\ua78a\ua78b\ua78c\ua78d\ua78e\ua78f\ua790\ua791\ua792\ua793\ua794\ua795\ua796\ua797\ua798\ua799\ua79a\ua79b\ua79c\ua79d\ua79e\ua79f\ua7a0\ua7a1\ua7a2\ua7a3\ua7a4\ua7a5\ua7a6\ua7a7\ua7a8\ua7a9\ua7aa\ua7ab\ua7ac\ua7ad\ua7ae\ua7af\ua7b0\ua7b1\ua7b2\ua7b3\ua7b4\ua7b5\ua7b6\ua7b7\ua7b8\ua7b9\ua7ba\ua7bb\ua7bc\ua7bd\ua7be\ua7bf\ua7c0\ua7c1\ua7c2\ua7c3\ua7c4\ua7c5\ua7c6\ua7c7\ua7c8\ua7c9\ua7ca\ua7cb\ua7cc\ua7cd\ua7ce\ua7cf\ua7d0\ua7d1\ua7d2\ua7d3\ua7d4\ua7d5\ua7d6\ua7d7\ua7d8\ua7d9\ua7da\ua7db\ua7dc\ua7dd\ua7de\ua7df\ua7e0\ua7e1\ua7e2\ua7e3\ua7e4\ua7e5\ua7e6\ua7e7\ua7e8\ua7e9\ua7ea\ua7eb\ua7ec\ua7ed\ua7ee\ua7ef\ua7f0\ua7f1\ua7f2\ua7f3\ua7f4\ua7f5\ua7f6\ua7f7\ua7f8\ua7f9\ua7fa\ua7fb\ua7fc\ua7fd\ua7fe\ua7ff\ua82c\ua82d\ua82e\ua82f\ua830\ua831\ua832\ua833\ua834\ua835\ua836\ua837\ua838\ua839\ua83a\ua83b\ua83c\ua83d\ua83e\ua83f\ua840\ua841\ua842\ua843\ua844\ua845\ua846\ua847\ua848\ua849\ua84a\ua84b\ua84c\ua84d\ua84e\ua84f\ua850\ua851\ua852\ua853\ua854\ua855\ua856\ua857\ua858\ua859\ua85a\ua85b\ua85c\ua85d\ua85e\ua85f\ua860\ua861\ua862\ua863\ua864\ua865\ua866\ua867\ua868\ua869\ua86a\ua86b\ua86c\ua86d\ua86e\ua86f\ua870\ua871\ua872\ua873\ua874\ua875\ua876\ua877\ua878\ua879\ua87a\ua87b\ua87c\ua87d\ua87e\ua87f\ua880\ua881\ua882\ua883\ua884\ua885\ua886\ua887\ua888\ua889\ua88a\ua88b\ua88c\ua88d\ua88e\ua88f\ua890\ua891\ua892\ua893\ua894\ua895\ua896\ua897\ua898\ua899\ua89a\ua89b\ua89c\ua89d\ua89e\ua89f\ua8a0\ua8a1\ua8a2\ua8a3\ua8a4\ua8a5\ua8a6\ua8a7\ua8a8\ua8a9\ua8aa\ua8ab\ua8ac\ua8ad\ua8ae\ua8af\ua8b0\ua8b1\ua8b2\ua8b3\ua8b4\ua8b5\ua8b6\ua8b7\ua8b8\ua8b9\ua8ba\ua8bb\ua8bc\ua8bd\ua8be\ua8bf\ua8c0\ua8c1\ua8c2\ua8c3\ua8c4\ua8c5\ua8c6\ua8c7\ua8c8\ua8c9\ua8ca\ua8cb\ua8cc\ua8cd\ua8ce\ua8cf\ua8d0\ua8d1\ua8d2\ua8d3\ua8d4\ua8d5\ua8d6\ua8d7\ua8d8\ua8d9\ua8da\ua8db\ua8dc\ua8dd\ua8de\ua8df\ua8e0\ua8e1\ua8e2\ua8e3\ua8e4\ua8e5\ua8e6\ua8e7\ua8e8\ua8e9\ua8ea\ua8eb\ua8ec\ua8ed\ua8ee\ua8ef\ua8f0\ua8f1\ua8f2\ua8f3\ua8f4\ua8f5\ua8f6\ua8f7\ua8f8\ua8f9\ua8fa\ua8fb\ua8fc\ua8fd\ua8fe\ua8ff\ua900\ua901\ua902\ua903\ua904\ua905\ua906\ua907\ua908\ua909\ua90a\ua90b\ua90c\ua90d\ua90e\ua90f\ua910\ua911\ua912\ua913\ua914\ua915\ua916\ua917\ua918\ua919\ua91a\ua91b\ua91c\ua91d\ua91e\ua91f\ua920\ua921\ua922\ua923\ua924\ua925\ua926\ua927\ua928\ua929\ua92a\ua92b\ua92c\ua92d\ua92e\ua92f\ua930\ua931\ua932\ua933\ua934\ua935\ua936\ua937\ua938\ua939\ua93a\ua93b\ua93c\ua93d\ua93e\ua93f\ua940\ua941\ua942\ua943\ua944\ua945\ua946\ua947\ua948\ua949\ua94a\ua94b\ua94c\ua94d\ua94e\ua94f\ua950\ua951\ua952\ua953\ua954\ua955\ua956\ua957\ua958\ua959\ua95a\ua95b\ua95c\ua95d\ua95e\ua95f\ua960\ua961\ua962\ua963\ua964\ua965\ua966\ua967\ua968\ua969\ua96a\ua96b\ua96c\ua96d\ua96e\ua96f\ua970\ua971\ua972\ua973\ua974\ua975\ua976\ua977\ua978\ua979\ua97a\ua97b\ua97c\ua97d\ua97e\ua97f\ua980\ua981\ua982\ua983\ua984\ua985\ua986\ua987\ua988\ua989\ua98a\ua98b\ua98c\ua98d\ua98e\ua98f\ua990\ua991\ua992\ua993\ua994\ua995\ua996\ua997\ua998\ua999\ua99a\ua99b\ua99c\ua99d\ua99e\ua99f\ua9a0\ua9a1\ua9a2\ua9a3\ua9a4\ua9a5\ua9a6\ua9a7\ua9a8\ua9a9\ua9aa\ua9ab\ua9ac\ua9ad\ua9ae\ua9af\ua9b0\ua9b1\ua9b2\ua9b3\ua9b4\ua9b5\ua9b6\ua9b7\ua9b8\ua9b9\ua9ba\ua9bb\ua9bc\ua9bd\ua9be\ua9bf\ua9c0\ua9c1\ua9c2\ua9c3\ua9c4\ua9c5\ua9c6\ua9c7\ua9c8\ua9c9\ua9ca\ua9cb\ua9cc\ua9cd\ua9ce\ua9cf\ua9d0\ua9d1\ua9d2\ua9d3\ua9d4\ua9d5\ua9d6\ua9d7\ua9d8\ua9d9\ua9da\ua9db\ua9dc\ua9dd\ua9de\ua9df\ua9e0\ua9e1\ua9e2\ua9e3\ua9e4\ua9e5\ua9e6\ua9e7\ua9e8\ua9e9\ua9ea\ua9eb\ua9ec\ua9ed\ua9ee\ua9ef\ua9f0\ua9f1\ua9f2\ua9f3\ua9f4\ua9f5\ua9f6\ua9f7\ua9f8\ua9f9\ua9fa\ua9fb\ua9fc\ua9fd\ua9fe\ua9ff\uaa00\uaa01\uaa02\uaa03\uaa04\uaa05\uaa06\uaa07\uaa08\uaa09\uaa0a\uaa0b\uaa0c\uaa0d\uaa0e\uaa0f\uaa10\uaa11\uaa12\uaa13\uaa14\uaa15\uaa16\uaa17\uaa18\uaa19\uaa1a\uaa1b\uaa1c\uaa1d\uaa1e\uaa1f\uaa20\uaa21\uaa22\uaa23\uaa24\uaa25\uaa26\uaa27\uaa28\uaa29\uaa2a\uaa2b\uaa2c\uaa2d\uaa2e\uaa2f\uaa30\uaa31\uaa32\uaa33\uaa34\uaa35\uaa36\uaa37\uaa38\uaa39\uaa3a\uaa3b\uaa3c\uaa3d\uaa3e\uaa3f\uaa40\uaa41\uaa42\uaa43\uaa44\uaa45\uaa46\uaa47\uaa48\uaa49\uaa4a\uaa4b\uaa4c\uaa4d\uaa4e\uaa4f\uaa50\uaa51\uaa52\uaa53\uaa54\uaa55\uaa56\uaa57\uaa58\uaa59\uaa5a\uaa5b\uaa5c\uaa5d\uaa5e\uaa5f\uaa60\uaa61\uaa62\uaa63\uaa64\uaa65\uaa66\uaa67\uaa68\uaa69\uaa6a\uaa6b\uaa6c\uaa6d\uaa6e\uaa6f\uaa70\uaa71\uaa72\uaa73\uaa74\uaa75\uaa76\uaa77\uaa78\uaa79\uaa7a\uaa7b\uaa7c\uaa7d\uaa7e\uaa7f\uaa80\uaa81\uaa82\uaa83\uaa84\uaa85\uaa86\uaa87\uaa88\uaa89\uaa8a\uaa8b\uaa8c\uaa8d\uaa8e\uaa8f\uaa90\uaa91\uaa92\uaa93\uaa94\uaa95\uaa96\uaa97\uaa98\uaa99\uaa9a\uaa9b\uaa9c\uaa9d\uaa9e\uaa9f\uaaa0\uaaa1\uaaa2\uaaa3\uaaa4\uaaa5\uaaa6\uaaa7\uaaa8\uaaa9\uaaaa\uaaab\uaaac\uaaad\uaaae\uaaaf\uaab0\uaab1\uaab2\uaab3\uaab4\uaab5\uaab6\uaab7\uaab8\uaab9\uaaba\uaabb\uaabc\uaabd\uaabe\uaabf\uaac0\uaac1\uaac2\uaac3\uaac4\uaac5\uaac6\uaac7\uaac8\uaac9\uaaca\uaacb\uaacc\uaacd\uaace\uaacf\uaad0\uaad1\uaad2\uaad3\uaad4\uaad5\uaad6\uaad7\uaad8\uaad9\uaada\uaadb\uaadc\uaadd\uaade\uaadf\uaae0\uaae1\uaae2\uaae3\uaae4\uaae5\uaae6\uaae7\uaae8\uaae9\uaaea\uaaeb\uaaec\uaaed\uaaee\uaaef\uaaf0\uaaf1\uaaf2\uaaf3\uaaf4\uaaf5\uaaf6\uaaf7\uaaf8\uaaf9\uaafa\uaafb\uaafc\uaafd\uaafe\uaaff\uab00\uab01\uab02\uab03\uab04\uab05\uab06\uab07\uab08\uab09\uab0a\uab0b\uab0c\uab0d\uab0e\uab0f\uab10\uab11\uab12\uab13\uab14\uab15\uab16\uab17\uab18\uab19\uab1a\uab1b\uab1c\uab1d\uab1e\uab1f\uab20\uab21\uab22\uab23\uab24\uab25\uab26\uab27\uab28\uab29\uab2a\uab2b\uab2c\uab2d\uab2e\uab2f\uab30\uab31\uab32\uab33\uab34\uab35\uab36\uab37\uab38\uab39\uab3a\uab3b\uab3c\uab3d\uab3e\uab3f\uab40\uab41\uab42\uab43\uab44\uab45\uab46\uab47\uab48\uab49\uab4a\uab4b\uab4c\uab4d\uab4e\uab4f\uab50\uab51\uab52\uab53\uab54\uab55\uab56\uab57\uab58\uab59\uab5a\uab5b\uab5c\uab5d\uab5e\uab5f\uab60\uab61\uab62\uab63\uab64\uab65\uab66\uab67\uab68\uab69\uab6a\uab6b\uab6c\uab6d\uab6e\uab6f\uab70\uab71\uab72\uab73\uab74\uab75\uab76\uab77\uab78\uab79\uab7a\uab7b\uab7c\uab7d\uab7e\uab7f\uab80\uab81\uab82\uab83\uab84\uab85\uab86\uab87\uab88\uab89\uab8a\uab8b\uab8c\uab8d\uab8e\uab8f\uab90\uab91\uab92\uab93\uab94\uab95\uab96\uab97\uab98\uab99\uab9a\uab9b\uab9c\uab9d\uab9e\uab9f\uaba0\uaba1\uaba2\uaba3\uaba4\uaba5\uaba6\uaba7\uaba8\uaba9\uabaa\uabab\uabac\uabad\uabae\uabaf\uabb0\uabb1\uabb2\uabb3\uabb4\uabb5\uabb6\uabb7\uabb8\uabb9\uabba\uabbb\uabbc\uabbd\uabbe\uabbf\uabc0\uabc1\uabc2\uabc3\uabc4\uabc5\uabc6\uabc7\uabc8\uabc9\uabca\uabcb\uabcc\uabcd\uabce\uabcf\uabd0\uabd1\uabd2\uabd3\uabd4\uabd5\uabd6\uabd7\uabd8\uabd9\uabda\uabdb\uabdc\uabdd\uabde\uabdf\uabe0\uabe1\uabe2\uabe3\uabe4\uabe5\uabe6\uabe7\uabe8\uabe9\uabea\uabeb\uabec\uabed\uabee\uabef\uabf0\uabf1\uabf2\uabf3\uabf4\uabf5\uabf6\uabf7\uabf8\uabf9\uabfa\uabfb\uabfc\uabfd\uabfe\uabff\ud7a4\ud7a5\ud7a6\ud7a7\ud7a8\ud7a9\ud7aa\ud7ab\ud7ac\ud7ad\ud7ae\ud7af\ud7b0\ud7b1\ud7b2\ud7b3\ud7b4\ud7b5\ud7b6\ud7b7\ud7b8\ud7b9\ud7ba\ud7bb\ud7bc\ud7bd\ud7be\ud7bf\ud7c0\ud7c1\ud7c2\ud7c3\ud7c4\ud7c5\ud7c6\ud7c7\ud7c8\ud7c9\ud7ca\ud7cb\ud7cc\ud7cd\ud7ce\ud7cf\ud7d0\ud7d1\ud7d2\ud7d3\ud7d4\ud7d5\ud7d6\ud7d7\ud7d8\ud7d9\ud7da\ud7db\ud7dc\ud7dd\ud7de\ud7df\ud7e0\ud7e1\ud7e2\ud7e3\ud7e4\ud7e5\ud7e6\ud7e7\ud7e8\ud7e9\ud7ea\ud7eb\ud7ec\ud7ed\ud7ee\ud7ef\ud7f0\ud7f1\ud7f2\ud7f3\ud7f4\ud7f5\ud7f6\ud7f7\ud7f8\ud7f9\ud7fa\ud7fb\ud7fc\ud7fd\ud7fe\ud7ff\ufa2e\ufa2f\ufa6b\ufa6c\ufa6d\ufa6e\ufa6f\ufada\ufadb\ufadc\ufadd\ufade\ufadf\ufae0\ufae1\ufae2\ufae3\ufae4\ufae5\ufae6\ufae7\ufae8\ufae9\ufaea\ufaeb\ufaec\ufaed\ufaee\ufaef\ufaf0\ufaf1\ufaf2\ufaf3\ufaf4\ufaf5\ufaf6\ufaf7\ufaf8\ufaf9\ufafa\ufafb\ufafc\ufafd\ufafe\ufaff\ufb07\ufb08\ufb09\ufb0a\ufb0b\ufb0c\ufb0d\ufb0e\ufb0f\ufb10\ufb11\ufb12\ufb18\ufb19\ufb1a\ufb1b\ufb1c\ufb37\ufb3d\ufb3f\ufb42\ufb45\ufbb2\ufbb3\ufbb4\ufbb5\ufbb6\ufbb7\ufbb8\ufbb9\ufbba\ufbbb\ufbbc\ufbbd\ufbbe\ufbbf\ufbc0\ufbc1\ufbc2\ufbc3\ufbc4\ufbc5\ufbc6\ufbc7\ufbc8\ufbc9\ufbca\ufbcb\ufbcc\ufbcd\ufbce\ufbcf\ufbd0\ufbd1\ufbd2\ufd40\ufd41\ufd42\ufd43\ufd44\ufd45\ufd46\ufd47\ufd48\ufd49\ufd4a\ufd4b\ufd4c\ufd4d\ufd4e\ufd4f\ufd90\ufd91\ufdc8\ufdc9\ufdca\ufdcb\ufdcc\ufdcd\ufdce\ufdcf\ufdd0\ufdd1\ufdd2\ufdd3\ufdd4\ufdd5\ufdd6\ufdd7\ufdd8\ufdd9\ufdda\ufddb\ufddc\ufddd\ufdde\ufddf\ufde0\ufde1\ufde2\ufde3\ufde4\ufde5\ufde6\ufde7\ufde8\ufde9\ufdea\ufdeb\ufdec\ufded\ufdee\ufdef\ufdfe\ufdff\ufe1a\ufe1b\ufe1c\ufe1d\ufe1e\ufe1f\ufe24\ufe25\ufe26\ufe27\ufe28\ufe29\ufe2a\ufe2b\ufe2c\ufe2d\ufe2e\ufe2f\ufe53\ufe67\ufe6c\ufe6d\ufe6e\ufe6f\ufe75\ufefd\ufefe\uff00\uffbf\uffc0\uffc1\uffc8\uffc9\uffd0\uffd1\uffd8\uffd9\uffdd\uffde\uffdf\uffe7\uffef\ufff0\ufff1\ufff2\ufff3\ufff4\ufff5\ufff6\ufff7\ufff8\ufffe'
-
-Co = u'\ue000\ue001\ue002\ue003\ue004\ue005\ue006\ue007\ue008\ue009\ue00a\ue00b\ue00c\ue00d\ue00e\ue00f\ue010\ue011\ue012\ue013\ue014\ue015\ue016\ue017\ue018\ue019\ue01a\ue01b\ue01c\ue01d\ue01e\ue01f\ue020\ue021\ue022\ue023\ue024\ue025\ue026\ue027\ue028\ue029\ue02a\ue02b\ue02c\ue02d\ue02e\ue02f\ue030\ue031\ue032\ue033\ue034\ue035\ue036\ue037\ue038\ue039\ue03a\ue03b\ue03c\ue03d\ue03e\ue03f\ue040\ue041\ue042\ue043\ue044\ue045\ue046\ue047\ue048\ue049\ue04a\ue04b\ue04c\ue04d\ue04e\ue04f\ue050\ue051\ue052\ue053\ue054\ue055\ue056\ue057\ue058\ue059\ue05a\ue05b\ue05c\ue05d\ue05e\ue05f\ue060\ue061\ue062\ue063\ue064\ue065\ue066\ue067\ue068\ue069\ue06a\ue06b\ue06c\ue06d\ue06e\ue06f\ue070\ue071\ue072\ue073\ue074\ue075\ue076\ue077\ue078\ue079\ue07a\ue07b\ue07c\ue07d\ue07e\ue07f\ue080\ue081\ue082\ue083\ue084\ue085\ue086\ue087\ue088\ue089\ue08a\ue08b\ue08c\ue08d\ue08e\ue08f\ue090\ue091\ue092\ue093\ue094\ue095\ue096\ue097\ue098\ue099\ue09a\ue09b\ue09c\ue09d\ue09e\ue09f\ue0a0\ue0a1\ue0a2\ue0a3\ue0a4\ue0a5\ue0a6\ue0a7\ue0a8\ue0a9\ue0aa\ue0ab\ue0ac\ue0ad\ue0ae\ue0af\ue0b0\ue0b1\ue0b2\ue0b3\ue0b4\ue0b5\ue0b6\ue0b7\ue0b8\ue0b9\ue0ba\ue0bb\ue0bc\ue0bd\ue0be\ue0bf\ue0c0\ue0c1\ue0c2\ue0c3\ue0c4\ue0c5\ue0c6\ue0c7\ue0c8\ue0c9\ue0ca\ue0cb\ue0cc\ue0cd\ue0ce\ue0cf\ue0d0\ue0d1\ue0d2\ue0d3\ue0d4\ue0d5\ue0d6\ue0d7\ue0d8\ue0d9\ue0da\ue0db\ue0dc\ue0dd\ue0de\ue0df\ue0e0\ue0e1\ue0e2\ue0e3\ue0e4\ue0e5\ue0e6\ue0e7\ue0e8\ue0e9\ue0ea\ue0eb\ue0ec\ue0ed\ue0ee\ue0ef\ue0f0\ue0f1\ue0f2\ue0f3\ue0f4\ue0f5\ue0f6\ue0f7\ue0f8\ue0f9\ue0fa\ue0fb\ue0fc\ue0fd\ue0fe\ue0ff\ue100\ue101\ue102\ue103\ue104\ue105\ue106\ue107\ue108\ue109\ue10a\ue10b\ue10c\ue10d\ue10e\ue10f\ue110\ue111\ue112\ue113\ue114\ue115\ue116\ue117\ue118\ue119\ue11a\ue11b\ue11c\ue11d\ue11e\ue11f\ue120\ue121\ue122\ue123\ue124\ue125\ue126\ue127\ue128\ue129\ue12a\ue12b\ue12c\ue12d\ue12e\ue12f\ue130\ue131\ue132\ue133\ue134\ue135\ue136\ue137\ue138\ue139\ue13a\ue13b\ue13c\ue13d\ue13e\ue13f\ue140\ue141\ue142\ue143\ue144\ue145\ue146\ue147\ue148\ue149\ue14a\ue14b\ue14c\ue14d\ue14e\ue14f\ue150\ue151\ue152\ue153\ue154\ue155\ue156\ue157\ue158\ue159\ue15a\ue15b\ue15c\ue15d\ue15e\ue15f\ue160\ue161\ue162\ue163\ue164\ue165\ue166\ue167\ue168\ue169\ue16a\ue16b\ue16c\ue16d\ue16e\ue16f\ue170\ue171\ue172\ue173\ue174\ue175\ue176\ue177\ue178\ue179\ue17a\ue17b\ue17c\ue17d\ue17e\ue17f\ue180\ue181\ue182\ue183\ue184\ue185\ue186\ue187\ue188\ue189\ue18a\ue18b\ue18c\ue18d\ue18e\ue18f\ue190\ue191\ue192\ue193\ue194\ue195\ue196\ue197\ue198\ue199\ue19a\ue19b\ue19c\ue19d\ue19e\ue19f\ue1a0\ue1a1\ue1a2\ue1a3\ue1a4\ue1a5\ue1a6\ue1a7\ue1a8\ue1a9\ue1aa\ue1ab\ue1ac\ue1ad\ue1ae\ue1af\ue1b0\ue1b1\ue1b2\ue1b3\ue1b4\ue1b5\ue1b6\ue1b7\ue1b8\ue1b9\ue1ba\ue1bb\ue1bc\ue1bd\ue1be\ue1bf\ue1c0\ue1c1\ue1c2\ue1c3\ue1c4\ue1c5\ue1c6\ue1c7\ue1c8\ue1c9\ue1ca\ue1cb\ue1cc\ue1cd\ue1ce\ue1cf\ue1d0\ue1d1\ue1d2\ue1d3\ue1d4\ue1d5\ue1d6\ue1d7\ue1d8\ue1d9\ue1da\ue1db\ue1dc\ue1dd\ue1de\ue1df\ue1e0\ue1e1\ue1e2\ue1e3\ue1e4\ue1e5\ue1e6\ue1e7\ue1e8\ue1e9\ue1ea\ue1eb\ue1ec\ue1ed\ue1ee\ue1ef\ue1f0\ue1f1\ue1f2\ue1f3\ue1f4\ue1f5\ue1f6\ue1f7\ue1f8\ue1f9\ue1fa\ue1fb\ue1fc\ue1fd\ue1fe\ue1ff\ue200\ue201\ue202\ue203\ue204\ue205\ue206\ue207\ue208\ue209\ue20a\ue20b\ue20c\ue20d\ue20e\ue20f\ue210\ue211\ue212\ue213\ue214\ue215\ue216\ue217\ue218\ue219\ue21a\ue21b\ue21c\ue21d\ue21e\ue21f\ue220\ue221\ue222\ue223\ue224\ue225\ue226\ue227\ue228\ue229\ue22a\ue22b\ue22c\ue22d\ue22e\ue22f\ue230\ue231\ue232\ue233\ue234\ue235\ue236\ue237\ue238\ue239\ue23a\ue23b\ue23c\ue23d\ue23e\ue23f\ue240\ue241\ue242\ue243\ue244\ue245\ue246\ue247\ue248\ue249\ue24a\ue24b\ue24c\ue24d\ue24e\ue24f\ue250\ue251\ue252\ue253\ue254\ue255\ue256\ue257\ue258\ue259\ue25a\ue25b\ue25c\ue25d\ue25e\ue25f\ue260\ue261\ue262\ue263\ue264\ue265\ue266\ue267\ue268\ue269\ue26a\ue26b\ue26c\ue26d\ue26e\ue26f\ue270\ue271\ue272\ue273\ue274\ue275\ue276\ue277\ue278\ue279\ue27a\ue27b\ue27c\ue27d\ue27e\ue27f\ue280\ue281\ue282\ue283\ue284\ue285\ue286\ue287\ue288\ue289\ue28a\ue28b\ue28c\ue28d\ue28e\ue28f\ue290\ue291\ue292\ue293\ue294\ue295\ue296\ue297\ue298\ue299\ue29a\ue29b\ue29c\ue29d\ue29e\ue29f\ue2a0\ue2a1\ue2a2\ue2a3\ue2a4\ue2a5\ue2a6\ue2a7\ue2a8\ue2a9\ue2aa\ue2ab\ue2ac\ue2ad\ue2ae\ue2af\ue2b0\ue2b1\ue2b2\ue2b3\ue2b4\ue2b5\ue2b6\ue2b7\ue2b8\ue2b9\ue2ba\ue2bb\ue2bc\ue2bd\ue2be\ue2bf\ue2c0\ue2c1\ue2c2\ue2c3\ue2c4\ue2c5\ue2c6\ue2c7\ue2c8\ue2c9\ue2ca\ue2cb\ue2cc\ue2cd\ue2ce\ue2cf\ue2d0\ue2d1\ue2d2\ue2d3\ue2d4\ue2d5\ue2d6\ue2d7\ue2d8\ue2d9\ue2da\ue2db\ue2dc\ue2dd\ue2de\ue2df\ue2e0\ue2e1\ue2e2\ue2e3\ue2e4\ue2e5\ue2e6\ue2e7\ue2e8\ue2e9\ue2ea\ue2eb\ue2ec\ue2ed\ue2ee\ue2ef\ue2f0\ue2f1\ue2f2\ue2f3\ue2f4\ue2f5\ue2f6\ue2f7\ue2f8\ue2f9\ue2fa\ue2fb\ue2fc\ue2fd\ue2fe\ue2ff\ue300\ue301\ue302\ue303\ue304\ue305\ue306\ue307\ue308\ue309\ue30a\ue30b\ue30c\ue30d\ue30e\ue30f\ue310\ue311\ue312\ue313\ue314\ue315\ue316\ue317\ue318\ue319\ue31a\ue31b\ue31c\ue31d\ue31e\ue31f\ue320\ue321\ue322\ue323\ue324\ue325\ue326\ue327\ue328\ue329\ue32a\ue32b\ue32c\ue32d\ue32e\ue32f\ue330\ue331\ue332\ue333\ue334\ue335\ue336\ue337\ue338\ue339\ue33a\ue33b\ue33c\ue33d\ue33e\ue33f\ue340\ue341\ue342\ue343\ue344\ue345\ue346\ue347\ue348\ue349\ue34a\ue34b\ue34c\ue34d\ue34e\ue34f\ue350\ue351\ue352\ue353\ue354\ue355\ue356\ue357\ue358\ue359\ue35a\ue35b\ue35c\ue35d\ue35e\ue35f\ue360\ue361\ue362\ue363\ue364\ue365\ue366\ue367\ue368\ue369\ue36a\ue36b\ue36c\ue36d\ue36e\ue36f\ue370\ue371\ue372\ue373\ue374\ue375\ue376\ue377\ue378\ue379\ue37a\ue37b\ue37c\ue37d\ue37e\ue37f\ue380\ue381\ue382\ue383\ue384\ue385\ue386\ue387\ue388\ue389\ue38a\ue38b\ue38c\ue38d\ue38e\ue38f\ue390\ue391\ue392\ue393\ue394\ue395\ue396\ue397\ue398\ue399\ue39a\ue39b\ue39c\ue39d\ue39e\ue39f\ue3a0\ue3a1\ue3a2\ue3a3\ue3a4\ue3a5\ue3a6\ue3a7\ue3a8\ue3a9\ue3aa\ue3ab\ue3ac\ue3ad\ue3ae\ue3af\ue3b0\ue3b1\ue3b2\ue3b3\ue3b4\ue3b5\ue3b6\ue3b7\ue3b8\ue3b9\ue3ba\ue3bb\ue3bc\ue3bd\ue3be\ue3bf\ue3c0\ue3c1\ue3c2\ue3c3\ue3c4\ue3c5\ue3c6\ue3c7\ue3c8\ue3c9\ue3ca\ue3cb\ue3cc\ue3cd\ue3ce\ue3cf\ue3d0\ue3d1\ue3d2\ue3d3\ue3d4\ue3d5\ue3d6\ue3d7\ue3d8\ue3d9\ue3da\ue3db\ue3dc\ue3dd\ue3de\ue3df\ue3e0\ue3e1\ue3e2\ue3e3\ue3e4\ue3e5\ue3e6\ue3e7\ue3e8\ue3e9\ue3ea\ue3eb\ue3ec\ue3ed\ue3ee\ue3ef\ue3f0\ue3f1\ue3f2\ue3f3\ue3f4\ue3f5\ue3f6\ue3f7\ue3f8\ue3f9\ue3fa\ue3fb\ue3fc\ue3fd\ue3fe\ue3ff\ue400\ue401\ue402\ue403\ue404\ue405\ue406\ue407\ue408\ue409\ue40a\ue40b\ue40c\ue40d\ue40e\ue40f\ue410\ue411\ue412\ue413\ue414\ue415\ue416\ue417\ue418\ue419\ue41a\ue41b\ue41c\ue41d\ue41e\ue41f\ue420\ue421\ue422\ue423\ue424\ue425\ue426\ue427\ue428\ue429\ue42a\ue42b\ue42c\ue42d\ue42e\ue42f\ue430\ue431\ue432\ue433\ue434\ue435\ue436\ue437\ue438\ue439\ue43a\ue43b\ue43c\ue43d\ue43e\ue43f\ue440\ue441\ue442\ue443\ue444\ue445\ue446\ue447\ue448\ue449\ue44a\ue44b\ue44c\ue44d\ue44e\ue44f\ue450\ue451\ue452\ue453\ue454\ue455\ue456\ue457\ue458\ue459\ue45a\ue45b\ue45c\ue45d\ue45e\ue45f\ue460\ue461\ue462\ue463\ue464\ue465\ue466\ue467\ue468\ue469\ue46a\ue46b\ue46c\ue46d\ue46e\ue46f\ue470\ue471\ue472\ue473\ue474\ue475\ue476\ue477\ue478\ue479\ue47a\ue47b\ue47c\ue47d\ue47e\ue47f\ue480\ue481\ue482\ue483\ue484\ue485\ue486\ue487\ue488\ue489\ue48a\ue48b\ue48c\ue48d\ue48e\ue48f\ue490\ue491\ue492\ue493\ue494\ue495\ue496\ue497\ue498\ue499\ue49a\ue49b\ue49c\ue49d\ue49e\ue49f\ue4a0\ue4a1\ue4a2\ue4a3\ue4a4\ue4a5\ue4a6\ue4a7\ue4a8\ue4a9\ue4aa\ue4ab\ue4ac\ue4ad\ue4ae\ue4af\ue4b0\ue4b1\ue4b2\ue4b3\ue4b4\ue4b5\ue4b6\ue4b7\ue4b8\ue4b9\ue4ba\ue4bb\ue4bc\ue4bd\ue4be\ue4bf\ue4c0\ue4c1\ue4c2\ue4c3\ue4c4\ue4c5\ue4c6\ue4c7\ue4c8\ue4c9\ue4ca\ue4cb\ue4cc\ue4cd\ue4ce\ue4cf\ue4d0\ue4d1\ue4d2\ue4d3\ue4d4\ue4d5\ue4d6\ue4d7\ue4d8\ue4d9\ue4da\ue4db\ue4dc\ue4dd\ue4de\ue4df\ue4e0\ue4e1\ue4e2\ue4e3\ue4e4\ue4e5\ue4e6\ue4e7\ue4e8\ue4e9\ue4ea\ue4eb\ue4ec\ue4ed\ue4ee\ue4ef\ue4f0\ue4f1\ue4f2\ue4f3\ue4f4\ue4f5\ue4f6\ue4f7\ue4f8\ue4f9\ue4fa\ue4fb\ue4fc\ue4fd\ue4fe\ue4ff\ue500\ue501\ue502\ue503\ue504\ue505\ue506\ue507\ue508\ue509\ue50a\ue50b\ue50c\ue50d\ue50e\ue50f\ue510\ue511\ue512\ue513\ue514\ue515\ue516\ue517\ue518\ue519\ue51a\ue51b\ue51c\ue51d\ue51e\ue51f\ue520\ue521\ue522\ue523\ue524\ue525\ue526\ue527\ue528\ue529\ue52a\ue52b\ue52c\ue52d\ue52e\ue52f\ue530\ue531\ue532\ue533\ue534\ue535\ue536\ue537\ue538\ue539\ue53a\ue53b\ue53c\ue53d\ue53e\ue53f\ue540\ue541\ue542\ue543\ue544\ue545\ue546\ue547\ue548\ue549\ue54a\ue54b\ue54c\ue54d\ue54e\ue54f\ue550\ue551\ue552\ue553\ue554\ue555\ue556\ue557\ue558\ue559\ue55a\ue55b\ue55c\ue55d\ue55e\ue55f\ue560\ue561\ue562\ue563\ue564\ue565\ue566\ue567\ue568\ue569\ue56a\ue56b\ue56c\ue56d\ue56e\ue56f\ue570\ue571\ue572\ue573\ue574\ue575\ue576\ue577\ue578\ue579\ue57a\ue57b\ue57c\ue57d\ue57e\ue57f\ue580\ue581\ue582\ue583\ue584\ue585\ue586\ue587\ue588\ue589\ue58a\ue58b\ue58c\ue58d\ue58e\ue58f\ue590\ue591\ue592\ue593\ue594\ue595\ue596\ue597\ue598\ue599\ue59a\ue59b\ue59c\ue59d\ue59e\ue59f\ue5a0\ue5a1\ue5a2\ue5a3\ue5a4\ue5a5\ue5a6\ue5a7\ue5a8\ue5a9\ue5aa\ue5ab\ue5ac\ue5ad\ue5ae\ue5af\ue5b0\ue5b1\ue5b2\ue5b3\ue5b4\ue5b5\ue5b6\ue5b7\ue5b8\ue5b9\ue5ba\ue5bb\ue5bc\ue5bd\ue5be\ue5bf\ue5c0\ue5c1\ue5c2\ue5c3\ue5c4\ue5c5\ue5c6\ue5c7\ue5c8\ue5c9\ue5ca\ue5cb\ue5cc\ue5cd\ue5ce\ue5cf\ue5d0\ue5d1\ue5d2\ue5d3\ue5d4\ue5d5\ue5d6\ue5d7\ue5d8\ue5d9\ue5da\ue5db\ue5dc\ue5dd\ue5de\ue5df\ue5e0\ue5e1\ue5e2\ue5e3\ue5e4\ue5e5\ue5e6\ue5e7\ue5e8\ue5e9\ue5ea\ue5eb\ue5ec\ue5ed\ue5ee\ue5ef\ue5f0\ue5f1\ue5f2\ue5f3\ue5f4\ue5f5\ue5f6\ue5f7\ue5f8\ue5f9\ue5fa\ue5fb\ue5fc\ue5fd\ue5fe\ue5ff\ue600\ue601\ue602\ue603\ue604\ue605\ue606\ue607\ue608\ue609\ue60a\ue60b\ue60c\ue60d\ue60e\ue60f\ue610\ue611\ue612\ue613\ue614\ue615\ue616\ue617\ue618\ue619\ue61a\ue61b\ue61c\ue61d\ue61e\ue61f\ue620\ue621\ue622\ue623\ue624\ue625\ue626\ue627\ue628\ue629\ue62a\ue62b\ue62c\ue62d\ue62e\ue62f\ue630\ue631\ue632\ue633\ue634\ue635\ue636\ue637\ue638\ue639\ue63a\ue63b\ue63c\ue63d\ue63e\ue63f\ue640\ue641\ue642\ue643\ue644\ue645\ue646\ue647\ue648\ue649\ue64a\ue64b\ue64c\ue64d\ue64e\ue64f\ue650\ue651\ue652\ue653\ue654\ue655\ue656\ue657\ue658\ue659\ue65a\ue65b\ue65c\ue65d\ue65e\ue65f\ue660\ue661\ue662\ue663\ue664\ue665\ue666\ue667\ue668\ue669\ue66a\ue66b\ue66c\ue66d\ue66e\ue66f\ue670\ue671\ue672\ue673\ue674\ue675\ue676\ue677\ue678\ue679\ue67a\ue67b\ue67c\ue67d\ue67e\ue67f\ue680\ue681\ue682\ue683\ue684\ue685\ue686\ue687\ue688\ue689\ue68a\ue68b\ue68c\ue68d\ue68e\ue68f\ue690\ue691\ue692\ue693\ue694\ue695\ue696\ue697\ue698\ue699\ue69a\ue69b\ue69c\ue69d\ue69e\ue69f\ue6a0\ue6a1\ue6a2\ue6a3\ue6a4\ue6a5\ue6a6\ue6a7\ue6a8\ue6a9\ue6aa\ue6ab\ue6ac\ue6ad\ue6ae\ue6af\ue6b0\ue6b1\ue6b2\ue6b3\ue6b4\ue6b5\ue6b6\ue6b7\ue6b8\ue6b9\ue6ba\ue6bb\ue6bc\ue6bd\ue6be\ue6bf\ue6c0\ue6c1\ue6c2\ue6c3\ue6c4\ue6c5\ue6c6\ue6c7\ue6c8\ue6c9\ue6ca\ue6cb\ue6cc\ue6cd\ue6ce\ue6cf\ue6d0\ue6d1\ue6d2\ue6d3\ue6d4\ue6d5\ue6d6\ue6d7\ue6d8\ue6d9\ue6da\ue6db\ue6dc\ue6dd\ue6de\ue6df\ue6e0\ue6e1\ue6e2\ue6e3\ue6e4\ue6e5\ue6e6\ue6e7\ue6e8\ue6e9\ue6ea\ue6eb\ue6ec\ue6ed\ue6ee\ue6ef\ue6f0\ue6f1\ue6f2\ue6f3\ue6f4\ue6f5\ue6f6\ue6f7\ue6f8\ue6f9\ue6fa\ue6fb\ue6fc\ue6fd\ue6fe\ue6ff\ue700\ue701\ue702\ue703\ue704\ue705\ue706\ue707\ue708\ue709\ue70a\ue70b\ue70c\ue70d\ue70e\ue70f\ue710\ue711\ue712\ue713\ue714\ue715\ue716\ue717\ue718\ue719\ue71a\ue71b\ue71c\ue71d\ue71e\ue71f\ue720\ue721\ue722\ue723\ue724\ue725\ue726\ue727\ue728\ue729\ue72a\ue72b\ue72c\ue72d\ue72e\ue72f\ue730\ue731\ue732\ue733\ue734\ue735\ue736\ue737\ue738\ue739\ue73a\ue73b\ue73c\ue73d\ue73e\ue73f\ue740\ue741\ue742\ue743\ue744\ue745\ue746\ue747\ue748\ue749\ue74a\ue74b\ue74c\ue74d\ue74e\ue74f\ue750\ue751\ue752\ue753\ue754\ue755\ue756\ue757\ue758\ue759\ue75a\ue75b\ue75c\ue75d\ue75e\ue75f\ue760\ue761\ue762\ue763\ue764\ue765\ue766\ue767\ue768\ue769\ue76a\ue76b\ue76c\ue76d\ue76e\ue76f\ue770\ue771\ue772\ue773\ue774\ue775\ue776\ue777\ue778\ue779\ue77a\ue77b\ue77c\ue77d\ue77e\ue77f\ue780\ue781\ue782\ue783\ue784\ue785\ue786\ue787\ue788\ue789\ue78a\ue78b\ue78c\ue78d\ue78e\ue78f\ue790\ue791\ue792\ue793\ue794\ue795\ue796\ue797\ue798\ue799\ue79a\ue79b\ue79c\ue79d\ue79e\ue79f\ue7a0\ue7a1\ue7a2\ue7a3\ue7a4\ue7a5\ue7a6\ue7a7\ue7a8\ue7a9\ue7aa\ue7ab\ue7ac\ue7ad\ue7ae\ue7af\ue7b0\ue7b1\ue7b2\ue7b3\ue7b4\ue7b5\ue7b6\ue7b7\ue7b8\ue7b9\ue7ba\ue7bb\ue7bc\ue7bd\ue7be\ue7bf\ue7c0\ue7c1\ue7c2\ue7c3\ue7c4\ue7c5\ue7c6\ue7c7\ue7c8\ue7c9\ue7ca\ue7cb\ue7cc\ue7cd\ue7ce\ue7cf\ue7d0\ue7d1\ue7d2\ue7d3\ue7d4\ue7d5\ue7d6\ue7d7\ue7d8\ue7d9\ue7da\ue7db\ue7dc\ue7dd\ue7de\ue7df\ue7e0\ue7e1\ue7e2\ue7e3\ue7e4\ue7e5\ue7e6\ue7e7\ue7e8\ue7e9\ue7ea\ue7eb\ue7ec\ue7ed\ue7ee\ue7ef\ue7f0\ue7f1\ue7f2\ue7f3\ue7f4\ue7f5\ue7f6\ue7f7\ue7f8\ue7f9\ue7fa\ue7fb\ue7fc\ue7fd\ue7fe\ue7ff\ue800\ue801\ue802\ue803\ue804\ue805\ue806\ue807\ue808\ue809\ue80a\ue80b\ue80c\ue80d\ue80e\ue80f\ue810\ue811\ue812\ue813\ue814\ue815\ue816\ue817\ue818\ue819\ue81a\ue81b\ue81c\ue81d\ue81e\ue81f\ue820\ue821\ue822\ue823\ue824\ue825\ue826\ue827\ue828\ue829\ue82a\ue82b\ue82c\ue82d\ue82e\ue82f\ue830\ue831\ue832\ue833\ue834\ue835\ue836\ue837\ue838\ue839\ue83a\ue83b\ue83c\ue83d\ue83e\ue83f\ue840\ue841\ue842\ue843\ue844\ue845\ue846\ue847\ue848\ue849\ue84a\ue84b\ue84c\ue84d\ue84e\ue84f\ue850\ue851\ue852\ue853\ue854\ue855\ue856\ue857\ue858\ue859\ue85a\ue85b\ue85c\ue85d\ue85e\ue85f\ue860\ue861\ue862\ue863\ue864\ue865\ue866\ue867\ue868\ue869\ue86a\ue86b\ue86c\ue86d\ue86e\ue86f\ue870\ue871\ue872\ue873\ue874\ue875\ue876\ue877\ue878\ue879\ue87a\ue87b\ue87c\ue87d\ue87e\ue87f\ue880\ue881\ue882\ue883\ue884\ue885\ue886\ue887\ue888\ue889\ue88a\ue88b\ue88c\ue88d\ue88e\ue88f\ue890\ue891\ue892\ue893\ue894\ue895\ue896\ue897\ue898\ue899\ue89a\ue89b\ue89c\ue89d\ue89e\ue89f\ue8a0\ue8a1\ue8a2\ue8a3\ue8a4\ue8a5\ue8a6\ue8a7\ue8a8\ue8a9\ue8aa\ue8ab\ue8ac\ue8ad\ue8ae\ue8af\ue8b0\ue8b1\ue8b2\ue8b3\ue8b4\ue8b5\ue8b6\ue8b7\ue8b8\ue8b9\ue8ba\ue8bb\ue8bc\ue8bd\ue8be\ue8bf\ue8c0\ue8c1\ue8c2\ue8c3\ue8c4\ue8c5\ue8c6\ue8c7\ue8c8\ue8c9\ue8ca\ue8cb\ue8cc\ue8cd\ue8ce\ue8cf\ue8d0\ue8d1\ue8d2\ue8d3\ue8d4\ue8d5\ue8d6\ue8d7\ue8d8\ue8d9\ue8da\ue8db\ue8dc\ue8dd\ue8de\ue8df\ue8e0\ue8e1\ue8e2\ue8e3\ue8e4\ue8e5\ue8e6\ue8e7\ue8e8\ue8e9\ue8ea\ue8eb\ue8ec\ue8ed\ue8ee\ue8ef\ue8f0\ue8f1\ue8f2\ue8f3\ue8f4\ue8f5\ue8f6\ue8f7\ue8f8\ue8f9\ue8fa\ue8fb\ue8fc\ue8fd\ue8fe\ue8ff\ue900\ue901\ue902\ue903\ue904\ue905\ue906\ue907\ue908\ue909\ue90a\ue90b\ue90c\ue90d\ue90e\ue90f\ue910\ue911\ue912\ue913\ue914\ue915\ue916\ue917\ue918\ue919\ue91a\ue91b\ue91c\ue91d\ue91e\ue91f\ue920\ue921\ue922\ue923\ue924\ue925\ue926\ue927\ue928\ue929\ue92a\ue92b\ue92c\ue92d\ue92e\ue92f\ue930\ue931\ue932\ue933\ue934\ue935\ue936\ue937\ue938\ue939\ue93a\ue93b\ue93c\ue93d\ue93e\ue93f\ue940\ue941\ue942\ue943\ue944\ue945\ue946\ue947\ue948\ue949\ue94a\ue94b\ue94c\ue94d\ue94e\ue94f\ue950\ue951\ue952\ue953\ue954\ue955\ue956\ue957\ue958\ue959\ue95a\ue95b\ue95c\ue95d\ue95e\ue95f\ue960\ue961\ue962\ue963\ue964\ue965\ue966\ue967\ue968\ue969\ue96a\ue96b\ue96c\ue96d\ue96e\ue96f\ue970\ue971\ue972\ue973\ue974\ue975\ue976\ue977\ue978\ue979\ue97a\ue97b\ue97c\ue97d\ue97e\ue97f\ue980\ue981\ue982\ue983\ue984\ue985\ue986\ue987\ue988\ue989\ue98a\ue98b\ue98c\ue98d\ue98e\ue98f\ue990\ue991\ue992\ue993\ue994\ue995\ue996\ue997\ue998\ue999\ue99a\ue99b\ue99c\ue99d\ue99e\ue99f\ue9a0\ue9a1\ue9a2\ue9a3\ue9a4\ue9a5\ue9a6\ue9a7\ue9a8\ue9a9\ue9aa\ue9ab\ue9ac\ue9ad\ue9ae\ue9af\ue9b0\ue9b1\ue9b2\ue9b3\ue9b4\ue9b5\ue9b6\ue9b7\ue9b8\ue9b9\ue9ba\ue9bb\ue9bc\ue9bd\ue9be\ue9bf\ue9c0\ue9c1\ue9c2\ue9c3\ue9c4\ue9c5\ue9c6\ue9c7\ue9c8\ue9c9\ue9ca\ue9cb\ue9cc\ue9cd\ue9ce\ue9cf\ue9d0\ue9d1\ue9d2\ue9d3\ue9d4\ue9d5\ue9d6\ue9d7\ue9d8\ue9d9\ue9da\ue9db\ue9dc\ue9dd\ue9de\ue9df\ue9e0\ue9e1\ue9e2\ue9e3\ue9e4\ue9e5\ue9e6\ue9e7\ue9e8\ue9e9\ue9ea\ue9eb\ue9ec\ue9ed\ue9ee\ue9ef\ue9f0\ue9f1\ue9f2\ue9f3\ue9f4\ue9f5\ue9f6\ue9f7\ue9f8\ue9f9\ue9fa\ue9fb\ue9fc\ue9fd\ue9fe\ue9ff\uea00\uea01\uea02\uea03\uea04\uea05\uea06\uea07\uea08\uea09\uea0a\uea0b\uea0c\uea0d\uea0e\uea0f\uea10\uea11\uea12\uea13\uea14\uea15\uea16\uea17\uea18\uea19\uea1a\uea1b\uea1c\uea1d\uea1e\uea1f\uea20\uea21\uea22\uea23\uea24\uea25\uea26\uea27\uea28\uea29\uea2a\uea2b\uea2c\uea2d\uea2e\uea2f\uea30\uea31\uea32\uea33\uea34\uea35\uea36\uea37\uea38\uea39\uea3a\uea3b\uea3c\uea3d\uea3e\uea3f\uea40\uea41\uea42\uea43\uea44\uea45\uea46\uea47\uea48\uea49\uea4a\uea4b\uea4c\uea4d\uea4e\uea4f\uea50\uea51\uea52\uea53\uea54\uea55\uea56\uea57\uea58\uea59\uea5a\uea5b\uea5c\uea5d\uea5e\uea5f\uea60\uea61\uea62\uea63\uea64\uea65\uea66\uea67\uea68\uea69\uea6a\uea6b\uea6c\uea6d\uea6e\uea6f\uea70\uea71\uea72\uea73\uea74\uea75\uea76\uea77\uea78\uea79\uea7a\uea7b\uea7c\uea7d\uea7e\uea7f\uea80\uea81\uea82\uea83\uea84\uea85\uea86\uea87\uea88\uea89\uea8a\uea8b\uea8c\uea8d\uea8e\uea8f\uea90\uea91\uea92\uea93\uea94\uea95\uea96\uea97\uea98\uea99\uea9a\uea9b\uea9c\uea9d\uea9e\uea9f\ueaa0\ueaa1\ueaa2\ueaa3\ueaa4\ueaa5\ueaa6\ueaa7\ueaa8\ueaa9\ueaaa\ueaab\ueaac\ueaad\ueaae\ueaaf\ueab0\ueab1\ueab2\ueab3\ueab4\ueab5\ueab6\ueab7\ueab8\ueab9\ueaba\ueabb\ueabc\ueabd\ueabe\ueabf\ueac0\ueac1\ueac2\ueac3\ueac4\ueac5\ueac6\ueac7\ueac8\ueac9\ueaca\ueacb\ueacc\ueacd\ueace\ueacf\uead0\uead1\uead2\uead3\uead4\uead5\uead6\uead7\uead8\uead9\ueada\ueadb\ueadc\ueadd\ueade\ueadf\ueae0\ueae1\ueae2\ueae3\ueae4\ueae5\ueae6\ueae7\ueae8\ueae9\ueaea\ueaeb\ueaec\ueaed\ueaee\ueaef\ueaf0\ueaf1\ueaf2\ueaf3\ueaf4\ueaf5\ueaf6\ueaf7\ueaf8\ueaf9\ueafa\ueafb\ueafc\ueafd\ueafe\ueaff\ueb00\ueb01\ueb02\ueb03\ueb04\ueb05\ueb06\ueb07\ueb08\ueb09\ueb0a\ueb0b\ueb0c\ueb0d\ueb0e\ueb0f\ueb10\ueb11\ueb12\ueb13\ueb14\ueb15\ueb16\ueb17\ueb18\ueb19\ueb1a\ueb1b\ueb1c\ueb1d\ueb1e\ueb1f\ueb20\ueb21\ueb22\ueb23\ueb24\ueb25\ueb26\ueb27\ueb28\ueb29\ueb2a\ueb2b\ueb2c\ueb2d\ueb2e\ueb2f\ueb30\ueb31\ueb32\ueb33\ueb34\ueb35\ueb36\ueb37\ueb38\ueb39\ueb3a\ueb3b\ueb3c\ueb3d\ueb3e\ueb3f\ueb40\ueb41\ueb42\ueb43\ueb44\ueb45\ueb46\ueb47\ueb48\ueb49\ueb4a\ueb4b\ueb4c\ueb4d\ueb4e\ueb4f\ueb50\ueb51\ueb52\ueb53\ueb54\ueb55\ueb56\ueb57\ueb58\ueb59\ueb5a\ueb5b\ueb5c\ueb5d\ueb5e\ueb5f\ueb60\ueb61\ueb62\ueb63\ueb64\ueb65\ueb66\ueb67\ueb68\ueb69\ueb6a\ueb6b\ueb6c\ueb6d\ueb6e\ueb6f\ueb70\ueb71\ueb72\ueb73\ueb74\ueb75\ueb76\ueb77\ueb78\ueb79\ueb7a\ueb7b\ueb7c\ueb7d\ueb7e\ueb7f\ueb80\ueb81\ueb82\ueb83\ueb84\ueb85\ueb86\ueb87\ueb88\ueb89\ueb8a\ueb8b\ueb8c\ueb8d\ueb8e\ueb8f\ueb90\ueb91\ueb92\ueb93\ueb94\ueb95\ueb96\ueb97\ueb98\ueb99\ueb9a\ueb9b\ueb9c\ueb9d\ueb9e\ueb9f\ueba0\ueba1\ueba2\ueba3\ueba4\ueba5\ueba6\ueba7\ueba8\ueba9\uebaa\uebab\uebac\uebad\uebae\uebaf\uebb0\uebb1\uebb2\uebb3\uebb4\uebb5\uebb6\uebb7\uebb8\uebb9\uebba\uebbb\uebbc\uebbd\uebbe\uebbf\uebc0\uebc1\uebc2\uebc3\uebc4\uebc5\uebc6\uebc7\uebc8\uebc9\uebca\uebcb\uebcc\uebcd\uebce\uebcf\uebd0\uebd1\uebd2\uebd3\uebd4\uebd5\uebd6\uebd7\uebd8\uebd9\uebda\uebdb\uebdc\uebdd\uebde\uebdf\uebe0\uebe1\uebe2\uebe3\uebe4\uebe5\uebe6\uebe7\uebe8\uebe9\uebea\uebeb\uebec\uebed\uebee\uebef\uebf0\uebf1\uebf2\uebf3\uebf4\uebf5\uebf6\uebf7\uebf8\uebf9\uebfa\uebfb\uebfc\uebfd\uebfe\uebff\uec00\uec01\uec02\uec03\uec04\uec05\uec06\uec07\uec08\uec09\uec0a\uec0b\uec0c\uec0d\uec0e\uec0f\uec10\uec11\uec12\uec13\uec14\uec15\uec16\uec17\uec18\uec19\uec1a\uec1b\uec1c\uec1d\uec1e\uec1f\uec20\uec21\uec22\uec23\uec24\uec25\uec26\uec27\uec28\uec29\uec2a\uec2b\uec2c\uec2d\uec2e\uec2f\uec30\uec31\uec32\uec33\uec34\uec35\uec36\uec37\uec38\uec39\uec3a\uec3b\uec3c\uec3d\uec3e\uec3f\uec40\uec41\uec42\uec43\uec44\uec45\uec46\uec47\uec48\uec49\uec4a\uec4b\uec4c\uec4d\uec4e\uec4f\uec50\uec51\uec52\uec53\uec54\uec55\uec56\uec57\uec58\uec59\uec5a\uec5b\uec5c\uec5d\uec5e\uec5f\uec60\uec61\uec62\uec63\uec64\uec65\uec66\uec67\uec68\uec69\uec6a\uec6b\uec6c\uec6d\uec6e\uec6f\uec70\uec71\uec72\uec73\uec74\uec75\uec76\uec77\uec78\uec79\uec7a\uec7b\uec7c\uec7d\uec7e\uec7f\uec80\uec81\uec82\uec83\uec84\uec85\uec86\uec87\uec88\uec89\uec8a\uec8b\uec8c\uec8d\uec8e\uec8f\uec90\uec91\uec92\uec93\uec94\uec95\uec96\uec97\uec98\uec99\uec9a\uec9b\uec9c\uec9d\uec9e\uec9f\ueca0\ueca1\ueca2\ueca3\ueca4\ueca5\ueca6\ueca7\ueca8\ueca9\uecaa\uecab\uecac\uecad\uecae\uecaf\uecb0\uecb1\uecb2\uecb3\uecb4\uecb5\uecb6\uecb7\uecb8\uecb9\uecba\uecbb\uecbc\uecbd\uecbe\uecbf\uecc0\uecc1\uecc2\uecc3\uecc4\uecc5\uecc6\uecc7\uecc8\uecc9\uecca\ueccb\ueccc\ueccd\uecce\ueccf\uecd0\uecd1\uecd2\uecd3\uecd4\uecd5\uecd6\uecd7\uecd8\uecd9\uecda\uecdb\uecdc\uecdd\uecde\uecdf\uece0\uece1\uece2\uece3\uece4\uece5\uece6\uece7\uece8\uece9\uecea\ueceb\uecec\ueced\uecee\uecef\uecf0\uecf1\uecf2\uecf3\uecf4\uecf5\uecf6\uecf7\uecf8\uecf9\uecfa\uecfb\uecfc\uecfd\uecfe\uecff\ued00\ued01\ued02\ued03\ued04\ued05\ued06\ued07\ued08\ued09\ued0a\ued0b\ued0c\ued0d\ued0e\ued0f\ued10\ued11\ued12\ued13\ued14\ued15\ued16\ued17\ued18\ued19\ued1a\ued1b\ued1c\ued1d\ued1e\ued1f\ued20\ued21\ued22\ued23\ued24\ued25\ued26\ued27\ued28\ued29\ued2a\ued2b\ued2c\ued2d\ued2e\ued2f\ued30\ued31\ued32\ued33\ued34\ued35\ued36\ued37\ued38\ued39\ued3a\ued3b\ued3c\ued3d\ued3e\ued3f\ued40\ued41\ued42\ued43\ued44\ued45\ued46\ued47\ued48\ued49\ued4a\ued4b\ued4c\ued4d\ued4e\ued4f\ued50\ued51\ued52\ued53\ued54\ued55\ued56\ued57\ued58\ued59\ued5a\ued5b\ued5c\ued5d\ued5e\ued5f\ued60\ued61\ued62\ued63\ued64\ued65\ued66\ued67\ued68\ued69\ued6a\ued6b\ued6c\ued6d\ued6e\ued6f\ued70\ued71\ued72\ued73\ued74\ued75\ued76\ued77\ued78\ued79\ued7a\ued7b\ued7c\ued7d\ued7e\ued7f\ued80\ued81\ued82\ued83\ued84\ued85\ued86\ued87\ued88\ued89\ued8a\ued8b\ued8c\ued8d\ued8e\ued8f\ued90\ued91\ued92\ued93\ued94\ued95\ued96\ued97\ued98\ued99\ued9a\ued9b\ued9c\ued9d\ued9e\ued9f\ueda0\ueda1\ueda2\ueda3\ueda4\ueda5\ueda6\ueda7\ueda8\ueda9\uedaa\uedab\uedac\uedad\uedae\uedaf\uedb0\uedb1\uedb2\uedb3\uedb4\uedb5\uedb6\uedb7\uedb8\uedb9\uedba\uedbb\uedbc\uedbd\uedbe\uedbf\uedc0\uedc1\uedc2\uedc3\uedc4\uedc5\uedc6\uedc7\uedc8\uedc9\uedca\uedcb\uedcc\uedcd\uedce\uedcf\uedd0\uedd1\uedd2\uedd3\uedd4\uedd5\uedd6\uedd7\uedd8\uedd9\uedda\ueddb\ueddc\ueddd\uedde\ueddf\uede0\uede1\uede2\uede3\uede4\uede5\uede6\uede7\uede8\uede9\uedea\uedeb\uedec\ueded\uedee\uedef\uedf0\uedf1\uedf2\uedf3\uedf4\uedf5\uedf6\uedf7\uedf8\uedf9\uedfa\uedfb\uedfc\uedfd\uedfe\uedff\uee00\uee01\uee02\uee03\uee04\uee05\uee06\uee07\uee08\uee09\uee0a\uee0b\uee0c\uee0d\uee0e\uee0f\uee10\uee11\uee12\uee13\uee14\uee15\uee16\uee17\uee18\uee19\uee1a\uee1b\uee1c\uee1d\uee1e\uee1f\uee20\uee21\uee22\uee23\uee24\uee25\uee26\uee27\uee28\uee29\uee2a\uee2b\uee2c\uee2d\uee2e\uee2f\uee30\uee31\uee32\uee33\uee34\uee35\uee36\uee37\uee38\uee39\uee3a\uee3b\uee3c\uee3d\uee3e\uee3f\uee40\uee41\uee42\uee43\uee44\uee45\uee46\uee47\uee48\uee49\uee4a\uee4b\uee4c\uee4d\uee4e\uee4f\uee50\uee51\uee52\uee53\uee54\uee55\uee56\uee57\uee58\uee59\uee5a\uee5b\uee5c\uee5d\uee5e\uee5f\uee60\uee61\uee62\uee63\uee64\uee65\uee66\uee67\uee68\uee69\uee6a\uee6b\uee6c\uee6d\uee6e\uee6f\uee70\uee71\uee72\uee73\uee74\uee75\uee76\uee77\uee78\uee79\uee7a\uee7b\uee7c\uee7d\uee7e\uee7f\uee80\uee81\uee82\uee83\uee84\uee85\uee86\uee87\uee88\uee89\uee8a\uee8b\uee8c\uee8d\uee8e\uee8f\uee90\uee91\uee92\uee93\uee94\uee95\uee96\uee97\uee98\uee99\uee9a\uee9b\uee9c\uee9d\uee9e\uee9f\ueea0\ueea1\ueea2\ueea3\ueea4\ueea5\ueea6\ueea7\ueea8\ueea9\ueeaa\ueeab\ueeac\ueead\ueeae\ueeaf\ueeb0\ueeb1\ueeb2\ueeb3\ueeb4\ueeb5\ueeb6\ueeb7\ueeb8\ueeb9\ueeba\ueebb\ueebc\ueebd\ueebe\ueebf\ueec0\ueec1\ueec2\ueec3\ueec4\ueec5\ueec6\ueec7\ueec8\ueec9\ueeca\ueecb\ueecc\ueecd\ueece\ueecf\ueed0\ueed1\ueed2\ueed3\ueed4\ueed5\ueed6\ueed7\ueed8\ueed9\ueeda\ueedb\ueedc\ueedd\ueede\ueedf\ueee0\ueee1\ueee2\ueee3\ueee4\ueee5\ueee6\ueee7\ueee8\ueee9\ueeea\ueeeb\ueeec\ueeed\ueeee\ueeef\ueef0\ueef1\ueef2\ueef3\ueef4\ueef5\ueef6\ueef7\ueef8\ueef9\ueefa\ueefb\ueefc\ueefd\ueefe\ueeff\uef00\uef01\uef02\uef03\uef04\uef05\uef06\uef07\uef08\uef09\uef0a\uef0b\uef0c\uef0d\uef0e\uef0f\uef10\uef11\uef12\uef13\uef14\uef15\uef16\uef17\uef18\uef19\uef1a\uef1b\uef1c\uef1d\uef1e\uef1f\uef20\uef21\uef22\uef23\uef24\uef25\uef26\uef27\uef28\uef29\uef2a\uef2b\uef2c\uef2d\uef2e\uef2f\uef30\uef31\uef32\uef33\uef34\uef35\uef36\uef37\uef38\uef39\uef3a\uef3b\uef3c\uef3d\uef3e\uef3f\uef40\uef41\uef42\uef43\uef44\uef45\uef46\uef47\uef48\uef49\uef4a\uef4b\uef4c\uef4d\uef4e\uef4f\uef50\uef51\uef52\uef53\uef54\uef55\uef56\uef57\uef58\uef59\uef5a\uef5b\uef5c\uef5d\uef5e\uef5f\uef60\uef61\uef62\uef63\uef64\uef65\uef66\uef67\uef68\uef69\uef6a\uef6b\uef6c\uef6d\uef6e\uef6f\uef70\uef71\uef72\uef73\uef74\uef75\uef76\uef77\uef78\uef79\uef7a\uef7b\uef7c\uef7d\uef7e\uef7f\uef80\uef81\uef82\uef83\uef84\uef85\uef86\uef87\uef88\uef89\uef8a\uef8b\uef8c\uef8d\uef8e\uef8f\uef90\uef91\uef92\uef93\uef94\uef95\uef96\uef97\uef98\uef99\uef9a\uef9b\uef9c\uef9d\uef9e\uef9f\uefa0\uefa1\uefa2\uefa3\uefa4\uefa5\uefa6\uefa7\uefa8\uefa9\uefaa\uefab\uefac\uefad\uefae\uefaf\uefb0\uefb1\uefb2\uefb3\uefb4\uefb5\uefb6\uefb7\uefb8\uefb9\uefba\uefbb\uefbc\uefbd\uefbe\uefbf\uefc0\uefc1\uefc2\uefc3\uefc4\uefc5\uefc6\uefc7\uefc8\uefc9\uefca\uefcb\uefcc\uefcd\uefce\uefcf\uefd0\uefd1\uefd2\uefd3\uefd4\uefd5\uefd6\uefd7\uefd8\uefd9\uefda\uefdb\uefdc\uefdd\uefde\uefdf\uefe0\uefe1\uefe2\uefe3\uefe4\uefe5\uefe6\uefe7\uefe8\uefe9\uefea\uefeb\uefec\uefed\uefee\uefef\ueff0\ueff1\ueff2\ueff3\ueff4\ueff5\ueff6\ueff7\ueff8\ueff9\ueffa\ueffb\ueffc\ueffd\ueffe\uefff\uf000\uf001\uf002\uf003\uf004\uf005\uf006\uf007\uf008\uf009\uf00a\uf00b\uf00c\uf00d\uf00e\uf00f\uf010\uf011\uf012\uf013\uf014\uf015\uf016\uf017\uf018\uf019\uf01a\uf01b\uf01c\uf01d\uf01e\uf01f\uf020\uf021\uf022\uf023\uf024\uf025\uf026\uf027\uf028\uf029\uf02a\uf02b\uf02c\uf02d\uf02e\uf02f\uf030\uf031\uf032\uf033\uf034\uf035\uf036\uf037\uf038\uf039\uf03a\uf03b\uf03c\uf03d\uf03e\uf03f\uf040\uf041\uf042\uf043\uf044\uf045\uf046\uf047\uf048\uf049\uf04a\uf04b\uf04c\uf04d\uf04e\uf04f\uf050\uf051\uf052\uf053\uf054\uf055\uf056\uf057\uf058\uf059\uf05a\uf05b\uf05c\uf05d\uf05e\uf05f\uf060\uf061\uf062\uf063\uf064\uf065\uf066\uf067\uf068\uf069\uf06a\uf06b\uf06c\uf06d\uf06e\uf06f\uf070\uf071\uf072\uf073\uf074\uf075\uf076\uf077\uf078\uf079\uf07a\uf07b\uf07c\uf07d\uf07e\uf07f\uf080\uf081\uf082\uf083\uf084\uf085\uf086\uf087\uf088\uf089\uf08a\uf08b\uf08c\uf08d\uf08e\uf08f\uf090\uf091\uf092\uf093\uf094\uf095\uf096\uf097\uf098\uf099\uf09a\uf09b\uf09c\uf09d\uf09e\uf09f\uf0a0\uf0a1\uf0a2\uf0a3\uf0a4\uf0a5\uf0a6\uf0a7\uf0a8\uf0a9\uf0aa\uf0ab\uf0ac\uf0ad\uf0ae\uf0af\uf0b0\uf0b1\uf0b2\uf0b3\uf0b4\uf0b5\uf0b6\uf0b7\uf0b8\uf0b9\uf0ba\uf0bb\uf0bc\uf0bd\uf0be\uf0bf\uf0c0\uf0c1\uf0c2\uf0c3\uf0c4\uf0c5\uf0c6\uf0c7\uf0c8\uf0c9\uf0ca\uf0cb\uf0cc\uf0cd\uf0ce\uf0cf\uf0d0\uf0d1\uf0d2\uf0d3\uf0d4\uf0d5\uf0d6\uf0d7\uf0d8\uf0d9\uf0da\uf0db\uf0dc\uf0dd\uf0de\uf0df\uf0e0\uf0e1\uf0e2\uf0e3\uf0e4\uf0e5\uf0e6\uf0e7\uf0e8\uf0e9\uf0ea\uf0eb\uf0ec\uf0ed\uf0ee\uf0ef\uf0f0\uf0f1\uf0f2\uf0f3\uf0f4\uf0f5\uf0f6\uf0f7\uf0f8\uf0f9\uf0fa\uf0fb\uf0fc\uf0fd\uf0fe\uf0ff\uf100\uf101\uf102\uf103\uf104\uf105\uf106\uf107\uf108\uf109\uf10a\uf10b\uf10c\uf10d\uf10e\uf10f\uf110\uf111\uf112\uf113\uf114\uf115\uf116\uf117\uf118\uf119\uf11a\uf11b\uf11c\uf11d\uf11e\uf11f\uf120\uf121\uf122\uf123\uf124\uf125\uf126\uf127\uf128\uf129\uf12a\uf12b\uf12c\uf12d\uf12e\uf12f\uf130\uf131\uf132\uf133\uf134\uf135\uf136\uf137\uf138\uf139\uf13a\uf13b\uf13c\uf13d\uf13e\uf13f\uf140\uf141\uf142\uf143\uf144\uf145\uf146\uf147\uf148\uf149\uf14a\uf14b\uf14c\uf14d\uf14e\uf14f\uf150\uf151\uf152\uf153\uf154\uf155\uf156\uf157\uf158\uf159\uf15a\uf15b\uf15c\uf15d\uf15e\uf15f\uf160\uf161\uf162\uf163\uf164\uf165\uf166\uf167\uf168\uf169\uf16a\uf16b\uf16c\uf16d\uf16e\uf16f\uf170\uf171\uf172\uf173\uf174\uf175\uf176\uf177\uf178\uf179\uf17a\uf17b\uf17c\uf17d\uf17e\uf17f\uf180\uf181\uf182\uf183\uf184\uf185\uf186\uf187\uf188\uf189\uf18a\uf18b\uf18c\uf18d\uf18e\uf18f\uf190\uf191\uf192\uf193\uf194\uf195\uf196\uf197\uf198\uf199\uf19a\uf19b\uf19c\uf19d\uf19e\uf19f\uf1a0\uf1a1\uf1a2\uf1a3\uf1a4\uf1a5\uf1a6\uf1a7\uf1a8\uf1a9\uf1aa\uf1ab\uf1ac\uf1ad\uf1ae\uf1af\uf1b0\uf1b1\uf1b2\uf1b3\uf1b4\uf1b5\uf1b6\uf1b7\uf1b8\uf1b9\uf1ba\uf1bb\uf1bc\uf1bd\uf1be\uf1bf\uf1c0\uf1c1\uf1c2\uf1c3\uf1c4\uf1c5\uf1c6\uf1c7\uf1c8\uf1c9\uf1ca\uf1cb\uf1cc\uf1cd\uf1ce\uf1cf\uf1d0\uf1d1\uf1d2\uf1d3\uf1d4\uf1d5\uf1d6\uf1d7\uf1d8\uf1d9\uf1da\uf1db\uf1dc\uf1dd\uf1de\uf1df\uf1e0\uf1e1\uf1e2\uf1e3\uf1e4\uf1e5\uf1e6\uf1e7\uf1e8\uf1e9\uf1ea\uf1eb\uf1ec\uf1ed\uf1ee\uf1ef\uf1f0\uf1f1\uf1f2\uf1f3\uf1f4\uf1f5\uf1f6\uf1f7\uf1f8\uf1f9\uf1fa\uf1fb\uf1fc\uf1fd\uf1fe\uf1ff\uf200\uf201\uf202\uf203\uf204\uf205\uf206\uf207\uf208\uf209\uf20a\uf20b\uf20c\uf20d\uf20e\uf20f\uf210\uf211\uf212\uf213\uf214\uf215\uf216\uf217\uf218\uf219\uf21a\uf21b\uf21c\uf21d\uf21e\uf21f\uf220\uf221\uf222\uf223\uf224\uf225\uf226\uf227\uf228\uf229\uf22a\uf22b\uf22c\uf22d\uf22e\uf22f\uf230\uf231\uf232\uf233\uf234\uf235\uf236\uf237\uf238\uf239\uf23a\uf23b\uf23c\uf23d\uf23e\uf23f\uf240\uf241\uf242\uf243\uf244\uf245\uf246\uf247\uf248\uf249\uf24a\uf24b\uf24c\uf24d\uf24e\uf24f\uf250\uf251\uf252\uf253\uf254\uf255\uf256\uf257\uf258\uf259\uf25a\uf25b\uf25c\uf25d\uf25e\uf25f\uf260\uf261\uf262\uf263\uf264\uf265\uf266\uf267\uf268\uf269\uf26a\uf26b\uf26c\uf26d\uf26e\uf26f\uf270\uf271\uf272\uf273\uf274\uf275\uf276\uf277\uf278\uf279\uf27a\uf27b\uf27c\uf27d\uf27e\uf27f\uf280\uf281\uf282\uf283\uf284\uf285\uf286\uf287\uf288\uf289\uf28a\uf28b\uf28c\uf28d\uf28e\uf28f\uf290\uf291\uf292\uf293\uf294\uf295\uf296\uf297\uf298\uf299\uf29a\uf29b\uf29c\uf29d\uf29e\uf29f\uf2a0\uf2a1\uf2a2\uf2a3\uf2a4\uf2a5\uf2a6\uf2a7\uf2a8\uf2a9\uf2aa\uf2ab\uf2ac\uf2ad\uf2ae\uf2af\uf2b0\uf2b1\uf2b2\uf2b3\uf2b4\uf2b5\uf2b6\uf2b7\uf2b8\uf2b9\uf2ba\uf2bb\uf2bc\uf2bd\uf2be\uf2bf\uf2c0\uf2c1\uf2c2\uf2c3\uf2c4\uf2c5\uf2c6\uf2c7\uf2c8\uf2c9\uf2ca\uf2cb\uf2cc\uf2cd\uf2ce\uf2cf\uf2d0\uf2d1\uf2d2\uf2d3\uf2d4\uf2d5\uf2d6\uf2d7\uf2d8\uf2d9\uf2da\uf2db\uf2dc\uf2dd\uf2de\uf2df\uf2e0\uf2e1\uf2e2\uf2e3\uf2e4\uf2e5\uf2e6\uf2e7\uf2e8\uf2e9\uf2ea\uf2eb\uf2ec\uf2ed\uf2ee\uf2ef\uf2f0\uf2f1\uf2f2\uf2f3\uf2f4\uf2f5\uf2f6\uf2f7\uf2f8\uf2f9\uf2fa\uf2fb\uf2fc\uf2fd\uf2fe\uf2ff\uf300\uf301\uf302\uf303\uf304\uf305\uf306\uf307\uf308\uf309\uf30a\uf30b\uf30c\uf30d\uf30e\uf30f\uf310\uf311\uf312\uf313\uf314\uf315\uf316\uf317\uf318\uf319\uf31a\uf31b\uf31c\uf31d\uf31e\uf31f\uf320\uf321\uf322\uf323\uf324\uf325\uf326\uf327\uf328\uf329\uf32a\uf32b\uf32c\uf32d\uf32e\uf32f\uf330\uf331\uf332\uf333\uf334\uf335\uf336\uf337\uf338\uf339\uf33a\uf33b\uf33c\uf33d\uf33e\uf33f\uf340\uf341\uf342\uf343\uf344\uf345\uf346\uf347\uf348\uf349\uf34a\uf34b\uf34c\uf34d\uf34e\uf34f\uf350\uf351\uf352\uf353\uf354\uf355\uf356\uf357\uf358\uf359\uf35a\uf35b\uf35c\uf35d\uf35e\uf35f\uf360\uf361\uf362\uf363\uf364\uf365\uf366\uf367\uf368\uf369\uf36a\uf36b\uf36c\uf36d\uf36e\uf36f\uf370\uf371\uf372\uf373\uf374\uf375\uf376\uf377\uf378\uf379\uf37a\uf37b\uf37c\uf37d\uf37e\uf37f\uf380\uf381\uf382\uf383\uf384\uf385\uf386\uf387\uf388\uf389\uf38a\uf38b\uf38c\uf38d\uf38e\uf38f\uf390\uf391\uf392\uf393\uf394\uf395\uf396\uf397\uf398\uf399\uf39a\uf39b\uf39c\uf39d\uf39e\uf39f\uf3a0\uf3a1\uf3a2\uf3a3\uf3a4\uf3a5\uf3a6\uf3a7\uf3a8\uf3a9\uf3aa\uf3ab\uf3ac\uf3ad\uf3ae\uf3af\uf3b0\uf3b1\uf3b2\uf3b3\uf3b4\uf3b5\uf3b6\uf3b7\uf3b8\uf3b9\uf3ba\uf3bb\uf3bc\uf3bd\uf3be\uf3bf\uf3c0\uf3c1\uf3c2\uf3c3\uf3c4\uf3c5\uf3c6\uf3c7\uf3c8\uf3c9\uf3ca\uf3cb\uf3cc\uf3cd\uf3ce\uf3cf\uf3d0\uf3d1\uf3d2\uf3d3\uf3d4\uf3d5\uf3d6\uf3d7\uf3d8\uf3d9\uf3da\uf3db\uf3dc\uf3dd\uf3de\uf3df\uf3e0\uf3e1\uf3e2\uf3e3\uf3e4\uf3e5\uf3e6\uf3e7\uf3e8\uf3e9\uf3ea\uf3eb\uf3ec\uf3ed\uf3ee\uf3ef\uf3f0\uf3f1\uf3f2\uf3f3\uf3f4\uf3f5\uf3f6\uf3f7\uf3f8\uf3f9\uf3fa\uf3fb\uf3fc\uf3fd\uf3fe\uf3ff\uf400\uf401\uf402\uf403\uf404\uf405\uf406\uf407\uf408\uf409\uf40a\uf40b\uf40c\uf40d\uf40e\uf40f\uf410\uf411\uf412\uf413\uf414\uf415\uf416\uf417\uf418\uf419\uf41a\uf41b\uf41c\uf41d\uf41e\uf41f\uf420\uf421\uf422\uf423\uf424\uf425\uf426\uf427\uf428\uf429\uf42a\uf42b\uf42c\uf42d\uf42e\uf42f\uf430\uf431\uf432\uf433\uf434\uf435\uf436\uf437\uf438\uf439\uf43a\uf43b\uf43c\uf43d\uf43e\uf43f\uf440\uf441\uf442\uf443\uf444\uf445\uf446\uf447\uf448\uf449\uf44a\uf44b\uf44c\uf44d\uf44e\uf44f\uf450\uf451\uf452\uf453\uf454\uf455\uf456\uf457\uf458\uf459\uf45a\uf45b\uf45c\uf45d\uf45e\uf45f\uf460\uf461\uf462\uf463\uf464\uf465\uf466\uf467\uf468\uf469\uf46a\uf46b\uf46c\uf46d\uf46e\uf46f\uf470\uf471\uf472\uf473\uf474\uf475\uf476\uf477\uf478\uf479\uf47a\uf47b\uf47c\uf47d\uf47e\uf47f\uf480\uf481\uf482\uf483\uf484\uf485\uf486\uf487\uf488\uf489\uf48a\uf48b\uf48c\uf48d\uf48e\uf48f\uf490\uf491\uf492\uf493\uf494\uf495\uf496\uf497\uf498\uf499\uf49a\uf49b\uf49c\uf49d\uf49e\uf49f\uf4a0\uf4a1\uf4a2\uf4a3\uf4a4\uf4a5\uf4a6\uf4a7\uf4a8\uf4a9\uf4aa\uf4ab\uf4ac\uf4ad\uf4ae\uf4af\uf4b0\uf4b1\uf4b2\uf4b3\uf4b4\uf4b5\uf4b6\uf4b7\uf4b8\uf4b9\uf4ba\uf4bb\uf4bc\uf4bd\uf4be\uf4bf\uf4c0\uf4c1\uf4c2\uf4c3\uf4c4\uf4c5\uf4c6\uf4c7\uf4c8\uf4c9\uf4ca\uf4cb\uf4cc\uf4cd\uf4ce\uf4cf\uf4d0\uf4d1\uf4d2\uf4d3\uf4d4\uf4d5\uf4d6\uf4d7\uf4d8\uf4d9\uf4da\uf4db\uf4dc\uf4dd\uf4de\uf4df\uf4e0\uf4e1\uf4e2\uf4e3\uf4e4\uf4e5\uf4e6\uf4e7\uf4e8\uf4e9\uf4ea\uf4eb\uf4ec\uf4ed\uf4ee\uf4ef\uf4f0\uf4f1\uf4f2\uf4f3\uf4f4\uf4f5\uf4f6\uf4f7\uf4f8\uf4f9\uf4fa\uf4fb\uf4fc\uf4fd\uf4fe\uf4ff\uf500\uf501\uf502\uf503\uf504\uf505\uf506\uf507\uf508\uf509\uf50a\uf50b\uf50c\uf50d\uf50e\uf50f\uf510\uf511\uf512\uf513\uf514\uf515\uf516\uf517\uf518\uf519\uf51a\uf51b\uf51c\uf51d\uf51e\uf51f\uf520\uf521\uf522\uf523\uf524\uf525\uf526\uf527\uf528\uf529\uf52a\uf52b\uf52c\uf52d\uf52e\uf52f\uf530\uf531\uf532\uf533\uf534\uf535\uf536\uf537\uf538\uf539\uf53a\uf53b\uf53c\uf53d\uf53e\uf53f\uf540\uf541\uf542\uf543\uf544\uf545\uf546\uf547\uf548\uf549\uf54a\uf54b\uf54c\uf54d\uf54e\uf54f\uf550\uf551\uf552\uf553\uf554\uf555\uf556\uf557\uf558\uf559\uf55a\uf55b\uf55c\uf55d\uf55e\uf55f\uf560\uf561\uf562\uf563\uf564\uf565\uf566\uf567\uf568\uf569\uf56a\uf56b\uf56c\uf56d\uf56e\uf56f\uf570\uf571\uf572\uf573\uf574\uf575\uf576\uf577\uf578\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf582\uf583\uf584\uf585\uf586\uf587\uf588\uf589\uf58a\uf58b\uf58c\uf58d\uf58e\uf58f\uf590\uf591\uf592\uf593\uf594\uf595\uf596\uf597\uf598\uf599\uf59a\uf59b\uf59c\uf59d\uf59e\uf59f\uf5a0\uf5a1\uf5a2\uf5a3\uf5a4\uf5a5\uf5a6\uf5a7\uf5a8\uf5a9\uf5aa\uf5ab\uf5ac\uf5ad\uf5ae\uf5af\uf5b0\uf5b1\uf5b2\uf5b3\uf5b4\uf5b5\uf5b6\uf5b7\uf5b8\uf5b9\uf5ba\uf5bb\uf5bc\uf5bd\uf5be\uf5bf\uf5c0\uf5c1\uf5c2\uf5c3\uf5c4\uf5c5\uf5c6\uf5c7\uf5c8\uf5c9\uf5ca\uf5cb\uf5cc\uf5cd\uf5ce\uf5cf\uf5d0\uf5d1\uf5d2\uf5d3\uf5d4\uf5d5\uf5d6\uf5d7\uf5d8\uf5d9\uf5da\uf5db\uf5dc\uf5dd\uf5de\uf5df\uf5e0\uf5e1\uf5e2\uf5e3\uf5e4\uf5e5\uf5e6\uf5e7\uf5e8\uf5e9\uf5ea\uf5eb\uf5ec\uf5ed\uf5ee\uf5ef\uf5f0\uf5f1\uf5f2\uf5f3\uf5f4\uf5f5\uf5f6\uf5f7\uf5f8\uf5f9\uf5fa\uf5fb\uf5fc\uf5fd\uf5fe\uf5ff\uf600\uf601\uf602\uf603\uf604\uf605\uf606\uf607\uf608\uf609\uf60a\uf60b\uf60c\uf60d\uf60e\uf60f\uf610\uf611\uf612\uf613\uf614\uf615\uf616\uf617\uf618\uf619\uf61a\uf61b\uf61c\uf61d\uf61e\uf61f\uf620\uf621\uf622\uf623\uf624\uf625\uf626\uf627\uf628\uf629\uf62a\uf62b\uf62c\uf62d\uf62e\uf62f\uf630\uf631\uf632\uf633\uf634\uf635\uf636\uf637\uf638\uf639\uf63a\uf63b\uf63c\uf63d\uf63e\uf63f\uf640\uf641\uf642\uf643\uf644\uf645\uf646\uf647\uf648\uf649\uf64a\uf64b\uf64c\uf64d\uf64e\uf64f\uf650\uf651\uf652\uf653\uf654\uf655\uf656\uf657\uf658\uf659\uf65a\uf65b\uf65c\uf65d\uf65e\uf65f\uf660\uf661\uf662\uf663\uf664\uf665\uf666\uf667\uf668\uf669\uf66a\uf66b\uf66c\uf66d\uf66e\uf66f\uf670\uf671\uf672\uf673\uf674\uf675\uf676\uf677\uf678\uf679\uf67a\uf67b\uf67c\uf67d\uf67e\uf67f\uf680\uf681\uf682\uf683\uf684\uf685\uf686\uf687\uf688\uf689\uf68a\uf68b\uf68c\uf68d\uf68e\uf68f\uf690\uf691\uf692\uf693\uf694\uf695\uf696\uf697\uf698\uf699\uf69a\uf69b\uf69c\uf69d\uf69e\uf69f\uf6a0\uf6a1\uf6a2\uf6a3\uf6a4\uf6a5\uf6a6\uf6a7\uf6a8\uf6a9\uf6aa\uf6ab\uf6ac\uf6ad\uf6ae\uf6af\uf6b0\uf6b1\uf6b2\uf6b3\uf6b4\uf6b5\uf6b6\uf6b7\uf6b8\uf6b9\uf6ba\uf6bb\uf6bc\uf6bd\uf6be\uf6bf\uf6c0\uf6c1\uf6c2\uf6c3\uf6c4\uf6c5\uf6c6\uf6c7\uf6c8\uf6c9\uf6ca\uf6cb\uf6cc\uf6cd\uf6ce\uf6cf\uf6d0\uf6d1\uf6d2\uf6d3\uf6d4\uf6d5\uf6d6\uf6d7\uf6d8\uf6d9\uf6da\uf6db\uf6dc\uf6dd\uf6de\uf6df\uf6e0\uf6e1\uf6e2\uf6e3\uf6e4\uf6e5\uf6e6\uf6e7\uf6e8\uf6e9\uf6ea\uf6eb\uf6ec\uf6ed\uf6ee\uf6ef\uf6f0\uf6f1\uf6f2\uf6f3\uf6f4\uf6f5\uf6f6\uf6f7\uf6f8\uf6f9\uf6fa\uf6fb\uf6fc\uf6fd\uf6fe\uf6ff\uf700\uf701\uf702\uf703\uf704\uf705\uf706\uf707\uf708\uf709\uf70a\uf70b\uf70c\uf70d\uf70e\uf70f\uf710\uf711\uf712\uf713\uf714\uf715\uf716\uf717\uf718\uf719\uf71a\uf71b\uf71c\uf71d\uf71e\uf71f\uf720\uf721\uf722\uf723\uf724\uf725\uf726\uf727\uf728\uf729\uf72a\uf72b\uf72c\uf72d\uf72e\uf72f\uf730\uf731\uf732\uf733\uf734\uf735\uf736\uf737\uf738\uf739\uf73a\uf73b\uf73c\uf73d\uf73e\uf73f\uf740\uf741\uf742\uf743\uf744\uf745\uf746\uf747\uf748\uf749\uf74a\uf74b\uf74c\uf74d\uf74e\uf74f\uf750\uf751\uf752\uf753\uf754\uf755\uf756\uf757\uf758\uf759\uf75a\uf75b\uf75c\uf75d\uf75e\uf75f\uf760\uf761\uf762\uf763\uf764\uf765\uf766\uf767\uf768\uf769\uf76a\uf76b\uf76c\uf76d\uf76e\uf76f\uf770\uf771\uf772\uf773\uf774\uf775\uf776\uf777\uf778\uf779\uf77a\uf77b\uf77c\uf77d\uf77e\uf77f\uf780\uf781\uf782\uf783\uf784\uf785\uf786\uf787\uf788\uf789\uf78a\uf78b\uf78c\uf78d\uf78e\uf78f\uf790\uf791\uf792\uf793\uf794\uf795\uf796\uf797\uf798\uf799\uf79a\uf79b\uf79c\uf79d\uf79e\uf79f\uf7a0\uf7a1\uf7a2\uf7a3\uf7a4\uf7a5\uf7a6\uf7a7\uf7a8\uf7a9\uf7aa\uf7ab\uf7ac\uf7ad\uf7ae\uf7af\uf7b0\uf7b1\uf7b2\uf7b3\uf7b4\uf7b5\uf7b6\uf7b7\uf7b8\uf7b9\uf7ba\uf7bb\uf7bc\uf7bd\uf7be\uf7bf\uf7c0\uf7c1\uf7c2\uf7c3\uf7c4\uf7c5\uf7c6\uf7c7\uf7c8\uf7c9\uf7ca\uf7cb\uf7cc\uf7cd\uf7ce\uf7cf\uf7d0\uf7d1\uf7d2\uf7d3\uf7d4\uf7d5\uf7d6\uf7d7\uf7d8\uf7d9\uf7da\uf7db\uf7dc\uf7dd\uf7de\uf7df\uf7e0\uf7e1\uf7e2\uf7e3\uf7e4\uf7e5\uf7e6\uf7e7\uf7e8\uf7e9\uf7ea\uf7eb\uf7ec\uf7ed\uf7ee\uf7ef\uf7f0\uf7f1\uf7f2\uf7f3\uf7f4\uf7f5\uf7f6\uf7f7\uf7f8\uf7f9\uf7fa\uf7fb\uf7fc\uf7fd\uf7fe\uf7ff\uf800\uf801\uf802\uf803\uf804\uf805\uf806\uf807\uf808\uf809\uf80a\uf80b\uf80c\uf80d\uf80e\uf80f\uf810\uf811\uf812\uf813\uf814\uf815\uf816\uf817\uf818\uf819\uf81a\uf81b\uf81c\uf81d\uf81e\uf81f\uf820\uf821\uf822\uf823\uf824\uf825\uf826\uf827\uf828\uf829\uf82a\uf82b\uf82c\uf82d\uf82e\uf82f\uf830\uf831\uf832\uf833\uf834\uf835\uf836\uf837\uf838\uf839\uf83a\uf83b\uf83c\uf83d\uf83e\uf83f\uf840\uf841\uf842\uf843\uf844\uf845\uf846\uf847\uf848\uf849\uf84a\uf84b\uf84c\uf84d\uf84e\uf84f\uf850\uf851\uf852\uf853\uf854\uf855\uf856\uf857\uf858\uf859\uf85a\uf85b\uf85c\uf85d\uf85e\uf85f\uf860\uf861\uf862\uf863\uf864\uf865\uf866\uf867\uf868\uf869\uf86a\uf86b\uf86c\uf86d\uf86e\uf86f\uf870\uf871\uf872\uf873\uf874\uf875\uf876\uf877\uf878\uf879\uf87a\uf87b\uf87c\uf87d\uf87e\uf87f\uf880\uf881\uf882\uf883\uf884\uf885\uf886\uf887\uf888\uf889\uf88a\uf88b\uf88c\uf88d\uf88e\uf88f\uf890\uf891\uf892\uf893\uf894\uf895\uf896\uf897\uf898\uf899\uf89a\uf89b\uf89c\uf89d\uf89e\uf89f\uf8a0\uf8a1\uf8a2\uf8a3\uf8a4\uf8a5\uf8a6\uf8a7\uf8a8\uf8a9\uf8aa\uf8ab\uf8ac\uf8ad\uf8ae\uf8af\uf8b0\uf8b1\uf8b2\uf8b3\uf8b4\uf8b5\uf8b6\uf8b7\uf8b8\uf8b9\uf8ba\uf8bb\uf8bc\uf8bd\uf8be\uf8bf\uf8c0\uf8c1\uf8c2\uf8c3\uf8c4\uf8c5\uf8c6\uf8c7\uf8c8\uf8c9\uf8ca\uf8cb\uf8cc\uf8cd\uf8ce\uf8cf\uf8d0\uf8d1\uf8d2\uf8d3\uf8d4\uf8d5\uf8d6\uf8d7\uf8d8\uf8d9\uf8da\uf8db\uf8dc\uf8dd\uf8de\uf8df\uf8e0\uf8e1\uf8e2\uf8e3\uf8e4\uf8e5\uf8e6\uf8e7\uf8e8\uf8e9\uf8ea\uf8eb\uf8ec\uf8ed\uf8ee\uf8ef\uf8f0\uf8f1\uf8f2\uf8f3\uf8f4\uf8f5\uf8f6\uf8f7\uf8f8\uf8f9\uf8fa\uf8fb\uf8fc\uf8fd\uf8fe\uf8ff'
-
-try:
- Cs = eval(r"'\ud800\ud801\ud802\ud803\ud804\ud805\ud806\ud807\ud808\ud809\ud80a\ud80b\ud80c\ud80d\ud80e\ud80f\ud810\ud811\ud812\ud813\ud814\ud815\ud816\ud817\ud818\ud819\ud81a\ud81b\ud81c\ud81d\ud81e\ud81f\ud820\ud821\ud822\ud823\ud824\ud825\ud826\ud827\ud828\ud829\ud82a\ud82b\ud82c\ud82d\ud82e\ud82f\ud830\ud831\ud832\ud833\ud834\ud835\ud836\ud837\ud838\ud839\ud83a\ud83b\ud83c\ud83d\ud83e\ud83f\ud840\ud841\ud842\ud843\ud844\ud845\ud846\ud847\ud848\ud849\ud84a\ud84b\ud84c\ud84d\ud84e\ud84f\ud850\ud851\ud852\ud853\ud854\ud855\ud856\ud857\ud858\ud859\ud85a\ud85b\ud85c\ud85d\ud85e\ud85f\ud860\ud861\ud862\ud863\ud864\ud865\ud866\ud867\ud868\ud869\ud86a\ud86b\ud86c\ud86d\ud86e\ud86f\ud870\ud871\ud872\ud873\ud874\ud875\ud876\ud877\ud878\ud879\ud87a\ud87b\ud87c\ud87d\ud87e\ud87f\ud880\ud881\ud882\ud883\ud884\ud885\ud886\ud887\ud888\ud889\ud88a\ud88b\ud88c\ud88d\ud88e\ud88f\ud890\ud891\ud892\ud893\ud894\ud895\ud896\ud897\ud898\ud899\ud89a\ud89b\ud89c\ud89d\ud89e\ud89f\ud8a0\ud8a1\ud8a2\ud8a3\ud8a4\ud8a5\ud8a6\ud8a7\ud8a8\ud8a9\ud8aa\ud8ab\ud8ac\ud8ad\ud8ae\ud8af\ud8b0\ud8b1\ud8b2\ud8b3\ud8b4\ud8b5\ud8b6\ud8b7\ud8b8\ud8b9\ud8ba\ud8bb\ud8bc\ud8bd\ud8be\ud8bf\ud8c0\ud8c1\ud8c2\ud8c3\ud8c4\ud8c5\ud8c6\ud8c7\ud8c8\ud8c9\ud8ca\ud8cb\ud8cc\ud8cd\ud8ce\ud8cf\ud8d0\ud8d1\ud8d2\ud8d3\ud8d4\ud8d5\ud8d6\ud8d7\ud8d8\ud8d9\ud8da\ud8db\ud8dc\ud8dd\ud8de\ud8df\ud8e0\ud8e1\ud8e2\ud8e3\ud8e4\ud8e5\ud8e6\ud8e7\ud8e8\ud8e9\ud8ea\ud8eb\ud8ec\ud8ed\ud8ee\ud8ef\ud8f0\ud8f1\ud8f2\ud8f3\ud8f4\ud8f5\ud8f6\ud8f7\ud8f8\ud8f9\ud8fa\ud8fb\ud8fc\ud8fd\ud8fe\ud8ff\ud900\ud901\ud902\ud903\ud904\ud905\ud906\ud907\ud908\ud909\ud90a\ud90b\ud90c\ud90d\ud90e\ud90f\ud910\ud911\ud912\ud913\ud914\ud915\ud916\ud917\ud918\ud919\ud91a\ud91b\ud91c\ud91d\ud91e\ud91f\ud920\ud921\ud922\ud923\ud924\ud925\ud926\ud927\ud928\ud929\ud92a\ud92b\ud92c\ud92d\ud92e\ud92f\ud930\ud931\ud932\ud933\ud934\ud935\ud936\ud937\ud938\ud939\ud93a\ud93b\ud93c\ud93d\ud93e\ud93f\ud940\ud941\ud942\ud943\ud944\ud945\ud946\ud947\ud948\ud949\ud94a\ud94b\ud94c\ud94d\ud94e\ud94f\ud950\ud951\ud952\ud953\ud954\ud955\ud956\ud957\ud958\ud959\ud95a\ud95b\ud95c\ud95d\ud95e\ud95f\ud960\ud961\ud962\ud963\ud964\ud965\ud966\ud967\ud968\ud969\ud96a\ud96b\ud96c\ud96d\ud96e\ud96f\ud970\ud971\ud972\ud973\ud974\ud975\ud976\ud977\ud978\ud979\ud97a\ud97b\ud97c\ud97d\ud97e\ud97f\ud980\ud981\ud982\ud983\ud984\ud985\ud986\ud987\ud988\ud989\ud98a\ud98b\ud98c\ud98d\ud98e\ud98f\ud990\ud991\ud992\ud993\ud994\ud995\ud996\ud997\ud998\ud999\ud99a\ud99b\ud99c\ud99d\ud99e\ud99f\ud9a0\ud9a1\ud9a2\ud9a3\ud9a4\ud9a5\ud9a6\ud9a7\ud9a8\ud9a9\ud9aa\ud9ab\ud9ac\ud9ad\ud9ae\ud9af\ud9b0\ud9b1\ud9b2\ud9b3\ud9b4\ud9b5\ud9b6\ud9b7\ud9b8\ud9b9\ud9ba\ud9bb\ud9bc\ud9bd\ud9be\ud9bf\ud9c0\ud9c1\ud9c2\ud9c3\ud9c4\ud9c5\ud9c6\ud9c7\ud9c8\ud9c9\ud9ca\ud9cb\ud9cc\ud9cd\ud9ce\ud9cf\ud9d0\ud9d1\ud9d2\ud9d3\ud9d4\ud9d5\ud9d6\ud9d7\ud9d8\ud9d9\ud9da\ud9db\ud9dc\ud9dd\ud9de\ud9df\ud9e0\ud9e1\ud9e2\ud9e3\ud9e4\ud9e5\ud9e6\ud9e7\ud9e8\ud9e9\ud9ea\ud9eb\ud9ec\ud9ed\ud9ee\ud9ef\ud9f0\ud9f1\ud9f2\ud9f3\ud9f4\ud9f5\ud9f6\ud9f7\ud9f8\ud9f9\ud9fa\ud9fb\ud9fc\ud9fd\ud9fe\ud9ff\uda00\uda01\uda02\uda03\uda04\uda05\uda06\uda07\uda08\uda09\uda0a\uda0b\uda0c\uda0d\uda0e\uda0f\uda10\uda11\uda12\uda13\uda14\uda15\uda16\uda17\uda18\uda19\uda1a\uda1b\uda1c\uda1d\uda1e\uda1f\uda20\uda21\uda22\uda23\uda24\uda25\uda26\uda27\uda28\uda29\uda2a\uda2b\uda2c\uda2d\uda2e\uda2f\uda30\uda31\uda32\uda33\uda34\uda35\uda36\uda37\uda38\uda39\uda3a\uda3b\uda3c\uda3d\uda3e\uda3f\uda40\uda41\uda42\uda43\uda44\uda45\uda46\uda47\uda48\uda49\uda4a\uda4b\uda4c\uda4d\uda4e\uda4f\uda50\uda51\uda52\uda53\uda54\uda55\uda56\uda57\uda58\uda59\uda5a\uda5b\uda5c\uda5d\uda5e\uda5f\uda60\uda61\uda62\uda63\uda64\uda65\uda66\uda67\uda68\uda69\uda6a\uda6b\uda6c\uda6d\uda6e\uda6f\uda70\uda71\uda72\uda73\uda74\uda75\uda76\uda77\uda78\uda79\uda7a\uda7b\uda7c\uda7d\uda7e\uda7f\uda80\uda81\uda82\uda83\uda84\uda85\uda86\uda87\uda88\uda89\uda8a\uda8b\uda8c\uda8d\uda8e\uda8f\uda90\uda91\uda92\uda93\uda94\uda95\uda96\uda97\uda98\uda99\uda9a\uda9b\uda9c\uda9d\uda9e\uda9f\udaa0\udaa1\udaa2\udaa3\udaa4\udaa5\udaa6\udaa7\udaa8\udaa9\udaaa\udaab\udaac\udaad\udaae\udaaf\udab0\udab1\udab2\udab3\udab4\udab5\udab6\udab7\udab8\udab9\udaba\udabb\udabc\udabd\udabe\udabf\udac0\udac1\udac2\udac3\udac4\udac5\udac6\udac7\udac8\udac9\udaca\udacb\udacc\udacd\udace\udacf\udad0\udad1\udad2\udad3\udad4\udad5\udad6\udad7\udad8\udad9\udada\udadb\udadc\udadd\udade\udadf\udae0\udae1\udae2\udae3\udae4\udae5\udae6\udae7\udae8\udae9\udaea\udaeb\udaec\udaed\udaee\udaef\udaf0\udaf1\udaf2\udaf3\udaf4\udaf5\udaf6\udaf7\udaf8\udaf9\udafa\udafb\udafc\udafd\udafe\udaff\udb00\udb01\udb02\udb03\udb04\udb05\udb06\udb07\udb08\udb09\udb0a\udb0b\udb0c\udb0d\udb0e\udb0f\udb10\udb11\udb12\udb13\udb14\udb15\udb16\udb17\udb18\udb19\udb1a\udb1b\udb1c\udb1d\udb1e\udb1f\udb20\udb21\udb22\udb23\udb24\udb25\udb26\udb27\udb28\udb29\udb2a\udb2b\udb2c\udb2d\udb2e\udb2f\udb30\udb31\udb32\udb33\udb34\udb35\udb36\udb37\udb38\udb39\udb3a\udb3b\udb3c\udb3d\udb3e\udb3f\udb40\udb41\udb42\udb43\udb44\udb45\udb46\udb47\udb48\udb49\udb4a\udb4b\udb4c\udb4d\udb4e\udb4f\udb50\udb51\udb52\udb53\udb54\udb55\udb56\udb57\udb58\udb59\udb5a\udb5b\udb5c\udb5d\udb5e\udb5f\udb60\udb61\udb62\udb63\udb64\udb65\udb66\udb67\udb68\udb69\udb6a\udb6b\udb6c\udb6d\udb6e\udb6f\udb70\udb71\udb72\udb73\udb74\udb75\udb76\udb77\udb78\udb79\udb7a\udb7b\udb7c\udb7d\udb7e\udb7f\udb80\udb81\udb82\udb83\udb84\udb85\udb86\udb87\udb88\udb89\udb8a\udb8b\udb8c\udb8d\udb8e\udb8f\udb90\udb91\udb92\udb93\udb94\udb95\udb96\udb97\udb98\udb99\udb9a\udb9b\udb9c\udb9d\udb9e\udb9f\udba0\udba1\udba2\udba3\udba4\udba5\udba6\udba7\udba8\udba9\udbaa\udbab\udbac\udbad\udbae\udbaf\udbb0\udbb1\udbb2\udbb3\udbb4\udbb5\udbb6\udbb7\udbb8\udbb9\udbba\udbbb\udbbc\udbbd\udbbe\udbbf\udbc0\udbc1\udbc2\udbc3\udbc4\udbc5\udbc6\udbc7\udbc8\udbc9\udbca\udbcb\udbcc\udbcd\udbce\udbcf\udbd0\udbd1\udbd2\udbd3\udbd4\udbd5\udbd6\udbd7\udbd8\udbd9\udbda\udbdb\udbdc\udbdd\udbde\udbdf\udbe0\udbe1\udbe2\udbe3\udbe4\udbe5\udbe6\udbe7\udbe8\udbe9\udbea\udbeb\udbec\udbed\udbee\udbef\udbf0\udbf1\udbf2\udbf3\udbf4\udbf5\udbf6\udbf7\udbf8\udbf9\udbfa\udbfb\udbfc\udbfd\udbfe\U0010fc00\udc01\udc02\udc03\udc04\udc05\udc06\udc07\udc08\udc09\udc0a\udc0b\udc0c\udc0d\udc0e\udc0f\udc10\udc11\udc12\udc13\udc14\udc15\udc16\udc17\udc18\udc19\udc1a\udc1b\udc1c\udc1d\udc1e\udc1f\udc20\udc21\udc22\udc23\udc24\udc25\udc26\udc27\udc28\udc29\udc2a\udc2b\udc2c\udc2d\udc2e\udc2f\udc30\udc31\udc32\udc33\udc34\udc35\udc36\udc37\udc38\udc39\udc3a\udc3b\udc3c\udc3d\udc3e\udc3f\udc40\udc41\udc42\udc43\udc44\udc45\udc46\udc47\udc48\udc49\udc4a\udc4b\udc4c\udc4d\udc4e\udc4f\udc50\udc51\udc52\udc53\udc54\udc55\udc56\udc57\udc58\udc59\udc5a\udc5b\udc5c\udc5d\udc5e\udc5f\udc60\udc61\udc62\udc63\udc64\udc65\udc66\udc67\udc68\udc69\udc6a\udc6b\udc6c\udc6d\udc6e\udc6f\udc70\udc71\udc72\udc73\udc74\udc75\udc76\udc77\udc78\udc79\udc7a\udc7b\udc7c\udc7d\udc7e\udc7f\udc80\udc81\udc82\udc83\udc84\udc85\udc86\udc87\udc88\udc89\udc8a\udc8b\udc8c\udc8d\udc8e\udc8f\udc90\udc91\udc92\udc93\udc94\udc95\udc96\udc97\udc98\udc99\udc9a\udc9b\udc9c\udc9d\udc9e\udc9f\udca0\udca1\udca2\udca3\udca4\udca5\udca6\udca7\udca8\udca9\udcaa\udcab\udcac\udcad\udcae\udcaf\udcb0\udcb1\udcb2\udcb3\udcb4\udcb5\udcb6\udcb7\udcb8\udcb9\udcba\udcbb\udcbc\udcbd\udcbe\udcbf\udcc0\udcc1\udcc2\udcc3\udcc4\udcc5\udcc6\udcc7\udcc8\udcc9\udcca\udccb\udccc\udccd\udcce\udccf\udcd0\udcd1\udcd2\udcd3\udcd4\udcd5\udcd6\udcd7\udcd8\udcd9\udcda\udcdb\udcdc\udcdd\udcde\udcdf\udce0\udce1\udce2\udce3\udce4\udce5\udce6\udce7\udce8\udce9\udcea\udceb\udcec\udced\udcee\udcef\udcf0\udcf1\udcf2\udcf3\udcf4\udcf5\udcf6\udcf7\udcf8\udcf9\udcfa\udcfb\udcfc\udcfd\udcfe\udcff\udd00\udd01\udd02\udd03\udd04\udd05\udd06\udd07\udd08\udd09\udd0a\udd0b\udd0c\udd0d\udd0e\udd0f\udd10\udd11\udd12\udd13\udd14\udd15\udd16\udd17\udd18\udd19\udd1a\udd1b\udd1c\udd1d\udd1e\udd1f\udd20\udd21\udd22\udd23\udd24\udd25\udd26\udd27\udd28\udd29\udd2a\udd2b\udd2c\udd2d\udd2e\udd2f\udd30\udd31\udd32\udd33\udd34\udd35\udd36\udd37\udd38\udd39\udd3a\udd3b\udd3c\udd3d\udd3e\udd3f\udd40\udd41\udd42\udd43\udd44\udd45\udd46\udd47\udd48\udd49\udd4a\udd4b\udd4c\udd4d\udd4e\udd4f\udd50\udd51\udd52\udd53\udd54\udd55\udd56\udd57\udd58\udd59\udd5a\udd5b\udd5c\udd5d\udd5e\udd5f\udd60\udd61\udd62\udd63\udd64\udd65\udd66\udd67\udd68\udd69\udd6a\udd6b\udd6c\udd6d\udd6e\udd6f\udd70\udd71\udd72\udd73\udd74\udd75\udd76\udd77\udd78\udd79\udd7a\udd7b\udd7c\udd7d\udd7e\udd7f\udd80\udd81\udd82\udd83\udd84\udd85\udd86\udd87\udd88\udd89\udd8a\udd8b\udd8c\udd8d\udd8e\udd8f\udd90\udd91\udd92\udd93\udd94\udd95\udd96\udd97\udd98\udd99\udd9a\udd9b\udd9c\udd9d\udd9e\udd9f\udda0\udda1\udda2\udda3\udda4\udda5\udda6\udda7\udda8\udda9\uddaa\uddab\uddac\uddad\uddae\uddaf\uddb0\uddb1\uddb2\uddb3\uddb4\uddb5\uddb6\uddb7\uddb8\uddb9\uddba\uddbb\uddbc\uddbd\uddbe\uddbf\uddc0\uddc1\uddc2\uddc3\uddc4\uddc5\uddc6\uddc7\uddc8\uddc9\uddca\uddcb\uddcc\uddcd\uddce\uddcf\uddd0\uddd1\uddd2\uddd3\uddd4\uddd5\uddd6\uddd7\uddd8\uddd9\uddda\udddb\udddc\udddd\uddde\udddf\udde0\udde1\udde2\udde3\udde4\udde5\udde6\udde7\udde8\udde9\uddea\uddeb\uddec\udded\uddee\uddef\uddf0\uddf1\uddf2\uddf3\uddf4\uddf5\uddf6\uddf7\uddf8\uddf9\uddfa\uddfb\uddfc\uddfd\uddfe\uddff\ude00\ude01\ude02\ude03\ude04\ude05\ude06\ude07\ude08\ude09\ude0a\ude0b\ude0c\ude0d\ude0e\ude0f\ude10\ude11\ude12\ude13\ude14\ude15\ude16\ude17\ude18\ude19\ude1a\ude1b\ude1c\ude1d\ude1e\ude1f\ude20\ude21\ude22\ude23\ude24\ude25\ude26\ude27\ude28\ude29\ude2a\ude2b\ude2c\ude2d\ude2e\ude2f\ude30\ude31\ude32\ude33\ude34\ude35\ude36\ude37\ude38\ude39\ude3a\ude3b\ude3c\ude3d\ude3e\ude3f\ude40\ude41\ude42\ude43\ude44\ude45\ude46\ude47\ude48\ude49\ude4a\ude4b\ude4c\ude4d\ude4e\ude4f\ude50\ude51\ude52\ude53\ude54\ude55\ude56\ude57\ude58\ude59\ude5a\ude5b\ude5c\ude5d\ude5e\ude5f\ude60\ude61\ude62\ude63\ude64\ude65\ude66\ude67\ude68\ude69\ude6a\ude6b\ude6c\ude6d\ude6e\ude6f\ude70\ude71\ude72\ude73\ude74\ude75\ude76\ude77\ude78\ude79\ude7a\ude7b\ude7c\ude7d\ude7e\ude7f\ude80\ude81\ude82\ude83\ude84\ude85\ude86\ude87\ude88\ude89\ude8a\ude8b\ude8c\ude8d\ude8e\ude8f\ude90\ude91\ude92\ude93\ude94\ude95\ude96\ude97\ude98\ude99\ude9a\ude9b\ude9c\ude9d\ude9e\ude9f\udea0\udea1\udea2\udea3\udea4\udea5\udea6\udea7\udea8\udea9\udeaa\udeab\udeac\udead\udeae\udeaf\udeb0\udeb1\udeb2\udeb3\udeb4\udeb5\udeb6\udeb7\udeb8\udeb9\udeba\udebb\udebc\udebd\udebe\udebf\udec0\udec1\udec2\udec3\udec4\udec5\udec6\udec7\udec8\udec9\udeca\udecb\udecc\udecd\udece\udecf\uded0\uded1\uded2\uded3\uded4\uded5\uded6\uded7\uded8\uded9\udeda\udedb\udedc\udedd\udede\udedf\udee0\udee1\udee2\udee3\udee4\udee5\udee6\udee7\udee8\udee9\udeea\udeeb\udeec\udeed\udeee\udeef\udef0\udef1\udef2\udef3\udef4\udef5\udef6\udef7\udef8\udef9\udefa\udefb\udefc\udefd\udefe\udeff\udf00\udf01\udf02\udf03\udf04\udf05\udf06\udf07\udf08\udf09\udf0a\udf0b\udf0c\udf0d\udf0e\udf0f\udf10\udf11\udf12\udf13\udf14\udf15\udf16\udf17\udf18\udf19\udf1a\udf1b\udf1c\udf1d\udf1e\udf1f\udf20\udf21\udf22\udf23\udf24\udf25\udf26\udf27\udf28\udf29\udf2a\udf2b\udf2c\udf2d\udf2e\udf2f\udf30\udf31\udf32\udf33\udf34\udf35\udf36\udf37\udf38\udf39\udf3a\udf3b\udf3c\udf3d\udf3e\udf3f\udf40\udf41\udf42\udf43\udf44\udf45\udf46\udf47\udf48\udf49\udf4a\udf4b\udf4c\udf4d\udf4e\udf4f\udf50\udf51\udf52\udf53\udf54\udf55\udf56\udf57\udf58\udf59\udf5a\udf5b\udf5c\udf5d\udf5e\udf5f\udf60\udf61\udf62\udf63\udf64\udf65\udf66\udf67\udf68\udf69\udf6a\udf6b\udf6c\udf6d\udf6e\udf6f\udf70\udf71\udf72\udf73\udf74\udf75\udf76\udf77\udf78\udf79\udf7a\udf7b\udf7c\udf7d\udf7e\udf7f\udf80\udf81\udf82\udf83\udf84\udf85\udf86\udf87\udf88\udf89\udf8a\udf8b\udf8c\udf8d\udf8e\udf8f\udf90\udf91\udf92\udf93\udf94\udf95\udf96\udf97\udf98\udf99\udf9a\udf9b\udf9c\udf9d\udf9e\udf9f\udfa0\udfa1\udfa2\udfa3\udfa4\udfa5\udfa6\udfa7\udfa8\udfa9\udfaa\udfab\udfac\udfad\udfae\udfaf\udfb0\udfb1\udfb2\udfb3\udfb4\udfb5\udfb6\udfb7\udfb8\udfb9\udfba\udfbb\udfbc\udfbd\udfbe\udfbf\udfc0\udfc1\udfc2\udfc3\udfc4\udfc5\udfc6\udfc7\udfc8\udfc9\udfca\udfcb\udfcc\udfcd\udfce\udfcf\udfd0\udfd1\udfd2\udfd3\udfd4\udfd5\udfd6\udfd7\udfd8\udfd9\udfda\udfdb\udfdc\udfdd\udfde\udfdf\udfe0\udfe1\udfe2\udfe3\udfe4\udfe5\udfe6\udfe7\udfe8\udfe9\udfea\udfeb\udfec\udfed\udfee\udfef\udff0\udff1\udff2\udff3\udff4\udff5\udff6\udff7\udff8\udff9\udffa\udffb\udffc\udffd\udffe\udfff'")
-except UnicodeDecodeError:
- Cs = '' # Jython can't handle isolated surrogates
-
-Ll = u'abcdefghijklmnopqrstuvwxyz\xaa\xb5\xba\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\u0101\u0103\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d\u012f\u0131\u0133\u0135\u0137\u0138\u013a\u013c\u013e\u0140\u0142\u0144\u0146\u0148\u0149\u014b\u014d\u014f\u0151\u0153\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173\u0175\u0177\u017a\u017c\u017e\u017f\u0180\u0183\u0185\u0188\u018c\u018d\u0192\u0195\u0199\u019a\u019b\u019e\u01a1\u01a3\u01a5\u01a8\u01aa\u01ab\u01ad\u01b0\u01b4\u01b6\u01b9\u01ba\u01bd\u01be\u01bf\u01c6\u01c9\u01cc\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc\u01dd\u01df\u01e1\u01e3\u01e5\u01e7\u01e9\u01eb\u01ed\u01ef\u01f0\u01f3\u01f5\u01f9\u01fb\u01fd\u01ff\u0201\u0203\u0205\u0207\u0209\u020b\u020d\u020f\u0211\u0213\u0215\u0217\u0219\u021b\u021d\u021f\u0221\u0223\u0225\u0227\u0229\u022b\u022d\u022f\u0231\u0233\u0234\u0235\u0236\u0237\u0238\u0239\u023c\u023f\u0240\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025a\u025b\u025c\u025d\u025e\u025f\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026a\u026b\u026c\u026d\u026e\u026f\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027a\u027b\u027c\u027d\u027e\u027f\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028a\u028b\u028c\u028d\u028e\u028f\u0290\u0291\u0292\u0293\u0294\u0295\u0296\u0297\u0298\u0299\u029a\u029b\u029c\u029d\u029e\u029f\u02a0\u02a1\u02a2\u02a3\u02a4\u02a5\u02a6\u02a7\u02a8\u02a9\u02aa\u02ab\u02ac\u02ad\u02ae\u02af\u0390\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\u03d0\u03d1\u03d5\u03d6\u03d7\u03d9\u03db\u03dd\u03df\u03e1\u03e3\u03e5\u03e7\u03e9\u03eb\u03ed\u03ef\u03f0\u03f1\u03f2\u03f3\u03f5\u03f8\u03fb\u03fc\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045d\u045e\u045f\u0461\u0463\u0465\u0467\u0469\u046b\u046d\u046f\u0471\u0473\u0475\u0477\u0479\u047b\u047d\u047f\u0481\u048b\u048d\u048f\u0491\u0493\u0495\u0497\u0499\u049b\u049d\u049f\u04a1\u04a3\u04a5\u04a7\u04a9\u04ab\u04ad\u04af\u04b1\u04b3\u04b5\u04b7\u04b9\u04bb\u04bd\u04bf\u04c2\u04c4\u04c6\u04c8\u04ca\u04cc\u04ce\u04d1\u04d3\u04d5\u04d7\u04d9\u04db\u04dd\u04df\u04e1\u04e3\u04e5\u04e7\u04e9\u04eb\u04ed\u04ef\u04f1\u04f3\u04f5\u04f7\u04f9\u0501\u0503\u0505\u0507\u0509\u050b\u050d\u050f\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d\u057e\u057f\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587\u1d00\u1d01\u1d02\u1d03\u1d04\u1d05\u1d06\u1d07\u1d08\u1d09\u1d0a\u1d0b\u1d0c\u1d0d\u1d0e\u1d0f\u1d10\u1d11\u1d12\u1d13\u1d14\u1d15\u1d16\u1d17\u1d18\u1d19\u1d1a\u1d1b\u1d1c\u1d1d\u1d1e\u1d1f\u1d20\u1d21\u1d22\u1d23\u1d24\u1d25\u1d26\u1d27\u1d28\u1d29\u1d2a\u1d2b\u1d62\u1d63\u1d64\u1d65\u1d66\u1d67\u1d68\u1d69\u1d6a\u1d6b\u1d6c\u1d6d\u1d6e\u1d6f\u1d70\u1d71\u1d72\u1d73\u1d74\u1d75\u1d76\u1d77\u1d79\u1d7a\u1d7b\u1d7c\u1d7d\u1d7e\u1d7f\u1d80\u1d81\u1d82\u1d83\u1d84\u1d85\u1d86\u1d87\u1d88\u1d89\u1d8a\u1d8b\u1d8c\u1d8d\u1d8e\u1d8f\u1d90\u1d91\u1d92\u1d93\u1d94\u1d95\u1d96\u1d97\u1d98\u1d99\u1d9a\u1e01\u1e03\u1e05\u1e07\u1e09\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1e1f\u1e21\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e2d\u1e2f\u1e31\u1e33\u1e35\u1e37\u1e39\u1e3b\u1e3d\u1e3f\u1e41\u1e43\u1e45\u1e47\u1e49\u1e4b\u1e4d\u1e4f\u1e51\u1e53\u1e55\u1e57\u1e59\u1e5b\u1e5d\u1e5f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e6b\u1e6d\u1e6f\u1e71\u1e73\u1e75\u1e77\u1e79\u1e7b\u1e7d\u1e7f\u1e81\u1e83\u1e85\u1e87\u1e89\u1e8b\u1e8d\u1e8f\u1e91\u1e93\u1e95\u1e96\u1e97\u1e98\u1e99\u1e9a\u1e9b\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u1ec9\u1ecb\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u1ef3\u1ef5\u1ef7\u1ef9\u1f00\u1f01\u1f02\u1f03\u1f04\u1f05\u1f06\u1f07\u1f10\u1f11\u1f12\u1f13\u1f14\u1f15\u1f20\u1f21\u1f22\u1f23\u1f24\u1f25\u1f26\u1f27\u1f30\u1f31\u1f32\u1f33\u1f34\u1f35\u1f36\u1f37\u1f40\u1f41\u1f42\u1f43\u1f44\u1f45\u1f50\u1f51\u1f52\u1f53\u1f54\u1f55\u1f56\u1f57\u1f60\u1f61\u1f62\u1f63\u1f64\u1f65\u1f66\u1f67\u1f70\u1f71\u1f72\u1f73\u1f74\u1f75\u1f76\u1f77\u1f78\u1f79\u1f7a\u1f7b\u1f7c\u1f7d\u1f80\u1f81\u1f82\u1f83\u1f84\u1f85\u1f86\u1f87\u1f90\u1f91\u1f92\u1f93\u1f94\u1f95\u1f96\u1f97\u1fa0\u1fa1\u1fa2\u1fa3\u1fa4\u1fa5\u1fa6\u1fa7\u1fb0\u1fb1\u1fb2\u1fb3\u1fb4\u1fb6\u1fb7\u1fbe\u1fc2\u1fc3\u1fc4\u1fc6\u1fc7\u1fd0\u1fd1\u1fd2\u1fd3\u1fd6\u1fd7\u1fe0\u1fe1\u1fe2\u1fe3\u1fe4\u1fe5\u1fe6\u1fe7\u1ff2\u1ff3\u1ff4\u1ff6\u1ff7\u2071\u207f\u210a\u210e\u210f\u2113\u212f\u2134\u2139\u213c\u213d\u2146\u2147\u2148\u2149\u2c30\u2c31\u2c32\u2c33\u2c34\u2c35\u2c36\u2c37\u2c38\u2c39\u2c3a\u2c3b\u2c3c\u2c3d\u2c3e\u2c3f\u2c40\u2c41\u2c42\u2c43\u2c44\u2c45\u2c46\u2c47\u2c48\u2c49\u2c4a\u2c4b\u2c4c\u2c4d\u2c4e\u2c4f\u2c50\u2c51\u2c52\u2c53\u2c54\u2c55\u2c56\u2c57\u2c58\u2c59\u2c5a\u2c5b\u2c5c\u2c5d\u2c5e\u2c81\u2c83\u2c85\u2c87\u2c89\u2c8b\u2c8d\u2c8f\u2c91\u2c93\u2c95\u2c97\u2c99\u2c9b\u2c9d\u2c9f\u2ca1\u2ca3\u2ca5\u2ca7\u2ca9\u2cab\u2cad\u2caf\u2cb1\u2cb3\u2cb5\u2cb7\u2cb9\u2cbb\u2cbd\u2cbf\u2cc1\u2cc3\u2cc5\u2cc7\u2cc9\u2ccb\u2ccd\u2ccf\u2cd1\u2cd3\u2cd5\u2cd7\u2cd9\u2cdb\u2cdd\u2cdf\u2ce1\u2ce3\u2ce4\u2d00\u2d01\u2d02\u2d03\u2d04\u2d05\u2d06\u2d07\u2d08\u2d09\u2d0a\u2d0b\u2d0c\u2d0d\u2d0e\u2d0f\u2d10\u2d11\u2d12\u2d13\u2d14\u2d15\u2d16\u2d17\u2d18\u2d19\u2d1a\u2d1b\u2d1c\u2d1d\u2d1e\u2d1f\u2d20\u2d21\u2d22\u2d23\u2d24\u2d25\ufb00\ufb01\ufb02\ufb03\ufb04\ufb05\ufb06\ufb13\ufb14\ufb15\ufb16\ufb17\uff41\uff42\uff43\uff44\uff45\uff46\uff47\uff48\uff49\uff4a\uff4b\uff4c\uff4d\uff4e\uff4f\uff50\uff51\uff52\uff53\uff54\uff55\uff56\uff57\uff58\uff59\uff5a'
-
-Lm = u'\u02b0\u02b1\u02b2\u02b3\u02b4\u02b5\u02b6\u02b7\u02b8\u02b9\u02ba\u02bb\u02bc\u02bd\u02be\u02bf\u02c0\u02c1\u02c6\u02c7\u02c8\u02c9\u02ca\u02cb\u02cc\u02cd\u02ce\u02cf\u02d0\u02d1\u02e0\u02e1\u02e2\u02e3\u02e4\u02ee\u037a\u0559\u0640\u06e5\u06e6\u0e46\u0ec6\u10fc\u17d7\u1843\u1d2c\u1d2d\u1d2e\u1d2f\u1d30\u1d31\u1d32\u1d33\u1d34\u1d35\u1d36\u1d37\u1d38\u1d39\u1d3a\u1d3b\u1d3c\u1d3d\u1d3e\u1d3f\u1d40\u1d41\u1d42\u1d43\u1d44\u1d45\u1d46\u1d47\u1d48\u1d49\u1d4a\u1d4b\u1d4c\u1d4d\u1d4e\u1d4f\u1d50\u1d51\u1d52\u1d53\u1d54\u1d55\u1d56\u1d57\u1d58\u1d59\u1d5a\u1d5b\u1d5c\u1d5d\u1d5e\u1d5f\u1d60\u1d61\u1d78\u1d9b\u1d9c\u1d9d\u1d9e\u1d9f\u1da0\u1da1\u1da2\u1da3\u1da4\u1da5\u1da6\u1da7\u1da8\u1da9\u1daa\u1dab\u1dac\u1dad\u1dae\u1daf\u1db0\u1db1\u1db2\u1db3\u1db4\u1db5\u1db6\u1db7\u1db8\u1db9\u1dba\u1dbb\u1dbc\u1dbd\u1dbe\u1dbf\u2090\u2091\u2092\u2093\u2094\u2d6f\u3005\u3031\u3032\u3033\u3034\u3035\u303b\u309d\u309e\u30fc\u30fd\u30fe\ua015\uff70\uff9e\uff9f'
-
-Lo = u'\u01bb\u01c0\u01c1\u01c2\u01c3\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05f0\u05f1\u05f2\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u066e\u066f\u0671\u0672\u0673\u0674\u0675\u0676\u0677\u0678\u0679\u067a\u067b\u067c\u067d\u067e\u067f\u0680\u0681\u0682\u0683\u0684\u0685\u0686\u0687\u0688\u0689\u068a\u068b\u068c\u068d\u068e\u068f\u0690\u0691\u0692\u0693\u0694\u0695\u0696\u0697\u0698\u0699\u069a\u069b\u069c\u069d\u069e\u069f\u06a0\u06a1\u06a2\u06a3\u06a4\u06a5\u06a6\u06a7\u06a8\u06a9\u06aa\u06ab\u06ac\u06ad\u06ae\u06af\u06b0\u06b1\u06b2\u06b3\u06b4\u06b5\u06b6\u06b7\u06b8\u06b9\u06ba\u06bb\u06bc\u06bd\u06be\u06bf\u06c0\u06c1\u06c2\u06c3\u06c4\u06c5\u06c6\u06c7\u06c8\u06c9\u06ca\u06cb\u06cc\u06cd\u06ce\u06cf\u06d0\u06d1\u06d2\u06d3\u06d5\u06ee\u06ef\u06fa\u06fb\u06fc\u06ff\u0710\u0712\u0713\u0714\u0715\u0716\u0717\u0718\u0719\u071a\u071b\u071c\u071d\u071e\u071f\u0720\u0721\u0722\u0723\u0724\u0725\u0726\u0727\u0728\u0729\u072a\u072b\u072c\u072d\u072e\u072f\u074d\u074e\u074f\u0750\u0751\u0752\u0753\u0754\u0755\u0756\u0757\u0758\u0759\u075a\u075b\u075c\u075d\u075e\u075f\u0760\u0761\u0762\u0763\u0764\u0765\u0766\u0767\u0768\u0769\u076a\u076b\u076c\u076d\u0780\u0781\u0782\u0783\u0784\u0785\u0786\u0787\u0788\u0789\u078a\u078b\u078c\u078d\u078e\u078f\u0790\u0791\u0792\u0793\u0794\u0795\u0796\u0797\u0798\u0799\u079a\u079b\u079c\u079d\u079e\u079f\u07a0\u07a1\u07a2\u07a3\u07a4\u07a5\u07b1\u0904\u0905\u0906\u0907\u0908\u0909\u090a\u090b\u090c\u090d\u090e\u090f\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\u091b\u091c\u091d\u091e\u091f\u0920\u0921\u0922\u0923\u0924\u0925\u0926\u0927\u0928\u0929\u092a\u092b\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934\u0935\u0936\u0937\u0938\u0939\u093d\u0950\u0958\u0959\u095a\u095b\u095c\u095d\u095e\u095f\u0960\u0961\u097d\u0985\u0986\u0987\u0988\u0989\u098a\u098b\u098c\u098f\u0990\u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099a\u099b\u099c\u099d\u099e\u099f\u09a0\u09a1\u09a2\u09a3\u09a4\u09a5\u09a6\u09a7\u09a8\u09aa\u09ab\u09ac\u09ad\u09ae\u09af\u09b0\u09b2\u09b6\u09b7\u09b8\u09b9\u09bd\u09ce\u09dc\u09dd\u09df\u09e0\u09e1\u09f0\u09f1\u0a05\u0a06\u0a07\u0a08\u0a09\u0a0a\u0a0f\u0a10\u0a13\u0a14\u0a15\u0a16\u0a17\u0a18\u0a19\u0a1a\u0a1b\u0a1c\u0a1d\u0a1e\u0a1f\u0a20\u0a21\u0a22\u0a23\u0a24\u0a25\u0a26\u0a27\u0a28\u0a2a\u0a2b\u0a2c\u0a2d\u0a2e\u0a2f\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5a\u0a5b\u0a5c\u0a5e\u0a72\u0a73\u0a74\u0a85\u0a86\u0a87\u0a88\u0a89\u0a8a\u0a8b\u0a8c\u0a8d\u0a8f\u0a90\u0a91\u0a93\u0a94\u0a95\u0a96\u0a97\u0a98\u0a99\u0a9a\u0a9b\u0a9c\u0a9d\u0a9e\u0a9f\u0aa0\u0aa1\u0aa2\u0aa3\u0aa4\u0aa5\u0aa6\u0aa7\u0aa8\u0aaa\u0aab\u0aac\u0aad\u0aae\u0aaf\u0ab0\u0ab2\u0ab3\u0ab5\u0ab6\u0ab7\u0ab8\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05\u0b06\u0b07\u0b08\u0b09\u0b0a\u0b0b\u0b0c\u0b0f\u0b10\u0b13\u0b14\u0b15\u0b16\u0b17\u0b18\u0b19\u0b1a\u0b1b\u0b1c\u0b1d\u0b1e\u0b1f\u0b20\u0b21\u0b22\u0b23\u0b24\u0b25\u0b26\u0b27\u0b28\u0b2a\u0b2b\u0b2c\u0b2d\u0b2e\u0b2f\u0b30\u0b32\u0b33\u0b35\u0b36\u0b37\u0b38\u0b39\u0b3d\u0b5c\u0b5d\u0b5f\u0b60\u0b61\u0b71\u0b83\u0b85\u0b86\u0b87\u0b88\u0b89\u0b8a\u0b8e\u0b8f\u0b90\u0b92\u0b93\u0b94\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0ba9\u0baa\u0bae\u0baf\u0bb0\u0bb1\u0bb2\u0bb3\u0bb4\u0bb5\u0bb6\u0bb7\u0bb8\u0bb9\u0c05\u0c06\u0c07\u0c08\u0c09\u0c0a\u0c0b\u0c0c\u0c0e\u0c0f\u0c10\u0c12\u0c13\u0c14\u0c15\u0c16\u0c17\u0c18\u0c19\u0c1a\u0c1b\u0c1c\u0c1d\u0c1e\u0c1f\u0c20\u0c21\u0c22\u0c23\u0c24\u0c25\u0c26\u0c27\u0c28\u0c2a\u0c2b\u0c2c\u0c2d\u0c2e\u0c2f\u0c30\u0c31\u0c32\u0c33\u0c35\u0c36\u0c37\u0c38\u0c39\u0c60\u0c61\u0c85\u0c86\u0c87\u0c88\u0c89\u0c8a\u0c8b\u0c8c\u0c8e\u0c8f\u0c90\u0c92\u0c93\u0c94\u0c95\u0c96\u0c97\u0c98\u0c99\u0c9a\u0c9b\u0c9c\u0c9d\u0c9e\u0c9f\u0ca0\u0ca1\u0ca2\u0ca3\u0ca4\u0ca5\u0ca6\u0ca7\u0ca8\u0caa\u0cab\u0cac\u0cad\u0cae\u0caf\u0cb0\u0cb1\u0cb2\u0cb3\u0cb5\u0cb6\u0cb7\u0cb8\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0d05\u0d06\u0d07\u0d08\u0d09\u0d0a\u0d0b\u0d0c\u0d0e\u0d0f\u0d10\u0d12\u0d13\u0d14\u0d15\u0d16\u0d17\u0d18\u0d19\u0d1a\u0d1b\u0d1c\u0d1d\u0d1e\u0d1f\u0d20\u0d21\u0d22\u0d23\u0d24\u0d25\u0d26\u0d27\u0d28\u0d2a\u0d2b\u0d2c\u0d2d\u0d2e\u0d2f\u0d30\u0d31\u0d32\u0d33\u0d34\u0d35\u0d36\u0d37\u0d38\u0d39\u0d60\u0d61\u0d85\u0d86\u0d87\u0d88\u0d89\u0d8a\u0d8b\u0d8c\u0d8d\u0d8e\u0d8f\u0d90\u0d91\u0d92\u0d93\u0d94\u0d95\u0d96\u0d9a\u0d9b\u0d9c\u0d9d\u0d9e\u0d9f\u0da0\u0da1\u0da2\u0da3\u0da4\u0da5\u0da6\u0da7\u0da8\u0da9\u0daa\u0dab\u0dac\u0dad\u0dae\u0daf\u0db0\u0db1\u0db3\u0db4\u0db5\u0db6\u0db7\u0db8\u0db9\u0dba\u0dbb\u0dbd\u0dc0\u0dc1\u0dc2\u0dc3\u0dc4\u0dc5\u0dc6\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e32\u0e33\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eaf\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4\u0edc\u0edd\u0f00\u0f40\u0f41\u0f42\u0f43\u0f44\u0f45\u0f46\u0f47\u0f49\u0f4a\u0f4b\u0f4c\u0f4d\u0f4e\u0f4f\u0f50\u0f51\u0f52\u0f53\u0f54\u0f55\u0f56\u0f57\u0f58\u0f59\u0f5a\u0f5b\u0f5c\u0f5d\u0f5e\u0f5f\u0f60\u0f61\u0f62\u0f63\u0f64\u0f65\u0f66\u0f67\u0f68\u0f69\u0f6a\u0f88\u0f89\u0f8a\u0f8b\u1000\u1001\u1002\u1003\u1004\u1005\u1006\u1007\u1008\u1009\u100a\u100b\u100c\u100d\u100e\u100f\u1010\u1011\u1012\u1013\u1014\u1015\u1016\u1017\u1018\u1019\u101a\u101b\u101c\u101d\u101e\u101f\u1020\u1021\u1023\u1024\u1025\u1026\u1027\u1029\u102a\u1050\u1051\u1052\u1053\u1054\u1055\u10d0\u10d1\u10d2\u10d3\u10d4\u10d5\u10d6\u10d7\u10d8\u10d9\u10da\u10db\u10dc\u10dd\u10de\u10df\u10e0\u10e1\u10e2\u10e3\u10e4\u10e5\u10e6\u10e7\u10e8\u10e9\u10ea\u10eb\u10ec\u10ed\u10ee\u10ef\u10f0\u10f1\u10f2\u10f3\u10f4\u10f5\u10f6\u10f7\u10f8\u10f9\u10fa\u1100\u1101\u1102\u1103\u1104\u1105\u1106\u1107\u1108\u1109\u110a\u110b\u110c\u110d\u110e\u110f\u1110\u1111\u1112\u1113\u1114\u1115\u1116\u1117\u1118\u1119\u111a\u111b\u111c\u111d\u111e\u111f\u1120\u1121\u1122\u1123\u1124\u1125\u1126\u1127\u1128\u1129\u112a\u112b\u112c\u112d\u112e\u112f\u1130\u1131\u1132\u1133\u1134\u1135\u1136\u1137\u1138\u1139\u113a\u113b\u113c\u113d\u113e\u113f\u1140\u1141\u1142\u1143\u1144\u1145\u1146\u1147\u1148\u1149\u114a\u114b\u114c\u114d\u114e\u114f\u1150\u1151\u1152\u1153\u1154\u1155\u1156\u1157\u1158\u1159\u115f\u1160\u1161\u1162\u1163\u1164\u1165\u1166\u1167\u1168\u1169\u116a\u116b\u116c\u116d\u116e\u116f\u1170\u1171\u1172\u1173\u1174\u1175\u1176\u1177\u1178\u1179\u117a\u117b\u117c\u117d\u117e\u117f\u1180\u1181\u1182\u1183\u1184\u1185\u1186\u1187\u1188\u1189\u118a\u118b\u118c\u118d\u118e\u118f\u1190\u1191\u1192\u1193\u1194\u1195\u1196\u1197\u1198\u1199\u119a\u119b\u119c\u119d\u119e\u119f\u11a0\u11a1\u11a2\u11a8\u11a9\u11aa\u11ab\u11ac\u11ad\u11ae\u11af\u11b0\u11b1\u11b2\u11b3\u11b4\u11b5\u11b6\u11b7\u11b8\u11b9\u11ba\u11bb\u11bc\u11bd\u11be\u11bf\u11c0\u11c1\u11c2\u11c3\u11c4\u11c5\u11c6\u11c7\u11c8\u11c9\u11ca\u11cb\u11cc\u11cd\u11ce\u11cf\u11d0\u11d1\u11d2\u11d3\u11d4\u11d5\u11d6\u11d7\u11d8\u11d9\u11da\u11db\u11dc\u11dd\u11de\u11df\u11e0\u11e1\u11e2\u11e3\u11e4\u11e5\u11e6\u11e7\u11e8\u11e9\u11ea\u11eb\u11ec\u11ed\u11ee\u11ef\u11f0\u11f1\u11f2\u11f3\u11f4\u11f5\u11f6\u11f7\u11f8\u11f9\u1200\u1201\u1202\u1203\u1204\u1205\u1206\u1207\u1208\u1209\u120a\u120b\u120c\u120d\u120e\u120f\u1210\u1211\u1212\u1213\u1214\u1215\u1216\u1217\u1218\u1219\u121a\u121b\u121c\u121d\u121e\u121f\u1220\u1221\u1222\u1223\u1224\u1225\u1226\u1227\u1228\u1229\u122a\u122b\u122c\u122d\u122e\u122f\u1230\u1231\u1232\u1233\u1234\u1235\u1236\u1237\u1238\u1239\u123a\u123b\u123c\u123d\u123e\u123f\u1240\u1241\u1242\u1243\u1244\u1245\u1246\u1247\u1248\u124a\u124b\u124c\u124d\u1250\u1251\u1252\u1253\u1254\u1255\u1256\u1258\u125a\u125b\u125c\u125d\u1260\u1261\u1262\u1263\u1264\u1265\u1266\u1267\u1268\u1269\u126a\u126b\u126c\u126d\u126e\u126f\u1270\u1271\u1272\u1273\u1274\u1275\u1276\u1277\u1278\u1279\u127a\u127b\u127c\u127d\u127e\u127f\u1280\u1281\u1282\u1283\u1284\u1285\u1286\u1287\u1288\u128a\u128b\u128c\u128d\u1290\u1291\u1292\u1293\u1294\u1295\u1296\u1297\u1298\u1299\u129a\u129b\u129c\u129d\u129e\u129f\u12a0\u12a1\u12a2\u12a3\u12a4\u12a5\u12a6\u12a7\u12a8\u12a9\u12aa\u12ab\u12ac\u12ad\u12ae\u12af\u12b0\u12b2\u12b3\u12b4\u12b5\u12b8\u12b9\u12ba\u12bb\u12bc\u12bd\u12be\u12c0\u12c2\u12c3\u12c4\u12c5\u12c8\u12c9\u12ca\u12cb\u12cc\u12cd\u12ce\u12cf\u12d0\u12d1\u12d2\u12d3\u12d4\u12d5\u12d6\u12d8\u12d9\u12da\u12db\u12dc\u12dd\u12de\u12df\u12e0\u12e1\u12e2\u12e3\u12e4\u12e5\u12e6\u12e7\u12e8\u12e9\u12ea\u12eb\u12ec\u12ed\u12ee\u12ef\u12f0\u12f1\u12f2\u12f3\u12f4\u12f5\u12f6\u12f7\u12f8\u12f9\u12fa\u12fb\u12fc\u12fd\u12fe\u12ff\u1300\u1301\u1302\u1303\u1304\u1305\u1306\u1307\u1308\u1309\u130a\u130b\u130c\u130d\u130e\u130f\u1310\u1312\u1313\u1314\u1315\u1318\u1319\u131a\u131b\u131c\u131d\u131e\u131f\u1320\u1321\u1322\u1323\u1324\u1325\u1326\u1327\u1328\u1329\u132a\u132b\u132c\u132d\u132e\u132f\u1330\u1331\u1332\u1333\u1334\u1335\u1336\u1337\u1338\u1339\u133a\u133b\u133c\u133d\u133e\u133f\u1340\u1341\u1342\u1343\u1344\u1345\u1346\u1347\u1348\u1349\u134a\u134b\u134c\u134d\u134e\u134f\u1350\u1351\u1352\u1353\u1354\u1355\u1356\u1357\u1358\u1359\u135a\u1380\u1381\u1382\u1383\u1384\u1385\u1386\u1387\u1388\u1389\u138a\u138b\u138c\u138d\u138e\u138f\u13a0\u13a1\u13a2\u13a3\u13a4\u13a5\u13a6\u13a7\u13a8\u13a9\u13aa\u13ab\u13ac\u13ad\u13ae\u13af\u13b0\u13b1\u13b2\u13b3\u13b4\u13b5\u13b6\u13b7\u13b8\u13b9\u13ba\u13bb\u13bc\u13bd\u13be\u13bf\u13c0\u13c1\u13c2\u13c3\u13c4\u13c5\u13c6\u13c7\u13c8\u13c9\u13ca\u13cb\u13cc\u13cd\u13ce\u13cf\u13d0\u13d1\u13d2\u13d3\u13d4\u13d5\u13d6\u13d7\u13d8\u13d9\u13da\u13db\u13dc\u13dd\u13de\u13df\u13e0\u13e1\u13e2\u13e3\u13e4\u13e5\u13e6\u13e7\u13e8\u13e9\u13ea\u13eb\u13ec\u13ed\u13ee\u13ef\u13f0\u13f1\u13f2\u13f3\u13f4\u1401\u1402\u1403\u1404\u1405\u1406\u1407\u1408\u1409\u140a\u140b\u140c\u140d\u140e\u140f\u1410\u1411\u1412\u1413\u1414\u1415\u1416\u1417\u1418\u1419\u141a\u141b\u141c\u141d\u141e\u141f\u1420\u1421\u1422\u1423\u1424\u1425\u1426\u1427\u1428\u1429\u142a\u142b\u142c\u142d\u142e\u142f\u1430\u1431\u1432\u1433\u1434\u1435\u1436\u1437\u1438\u1439\u143a\u143b\u143c\u143d\u143e\u143f\u1440\u1441\u1442\u1443\u1444\u1445\u1446\u1447\u1448\u1449\u144a\u144b\u144c\u144d\u144e\u144f\u1450\u1451\u1452\u1453\u1454\u1455\u1456\u1457\u1458\u1459\u145a\u145b\u145c\u145d\u145e\u145f\u1460\u1461\u1462\u1463\u1464\u1465\u1466\u1467\u1468\u1469\u146a\u146b\u146c\u146d\u146e\u146f\u1470\u1471\u1472\u1473\u1474\u1475\u1476\u1477\u1478\u1479\u147a\u147b\u147c\u147d\u147e\u147f\u1480\u1481\u1482\u1483\u1484\u1485\u1486\u1487\u1488\u1489\u148a\u148b\u148c\u148d\u148e\u148f\u1490\u1491\u1492\u1493\u1494\u1495\u1496\u1497\u1498\u1499\u149a\u149b\u149c\u149d\u149e\u149f\u14a0\u14a1\u14a2\u14a3\u14a4\u14a5\u14a6\u14a7\u14a8\u14a9\u14aa\u14ab\u14ac\u14ad\u14ae\u14af\u14b0\u14b1\u14b2\u14b3\u14b4\u14b5\u14b6\u14b7\u14b8\u14b9\u14ba\u14bb\u14bc\u14bd\u14be\u14bf\u14c0\u14c1\u14c2\u14c3\u14c4\u14c5\u14c6\u14c7\u14c8\u14c9\u14ca\u14cb\u14cc\u14cd\u14ce\u14cf\u14d0\u14d1\u14d2\u14d3\u14d4\u14d5\u14d6\u14d7\u14d8\u14d9\u14da\u14db\u14dc\u14dd\u14de\u14df\u14e0\u14e1\u14e2\u14e3\u14e4\u14e5\u14e6\u14e7\u14e8\u14e9\u14ea\u14eb\u14ec\u14ed\u14ee\u14ef\u14f0\u14f1\u14f2\u14f3\u14f4\u14f5\u14f6\u14f7\u14f8\u14f9\u14fa\u14fb\u14fc\u14fd\u14fe\u14ff\u1500\u1501\u1502\u1503\u1504\u1505\u1506\u1507\u1508\u1509\u150a\u150b\u150c\u150d\u150e\u150f\u1510\u1511\u1512\u1513\u1514\u1515\u1516\u1517\u1518\u1519\u151a\u151b\u151c\u151d\u151e\u151f\u1520\u1521\u1522\u1523\u1524\u1525\u1526\u1527\u1528\u1529\u152a\u152b\u152c\u152d\u152e\u152f\u1530\u1531\u1532\u1533\u1534\u1535\u1536\u1537\u1538\u1539\u153a\u153b\u153c\u153d\u153e\u153f\u1540\u1541\u1542\u1543\u1544\u1545\u1546\u1547\u1548\u1549\u154a\u154b\u154c\u154d\u154e\u154f\u1550\u1551\u1552\u1553\u1554\u1555\u1556\u1557\u1558\u1559\u155a\u155b\u155c\u155d\u155e\u155f\u1560\u1561\u1562\u1563\u1564\u1565\u1566\u1567\u1568\u1569\u156a\u156b\u156c\u156d\u156e\u156f\u1570\u1571\u1572\u1573\u1574\u1575\u1576\u1577\u1578\u1579\u157a\u157b\u157c\u157d\u157e\u157f\u1580\u1581\u1582\u1583\u1584\u1585\u1586\u1587\u1588\u1589\u158a\u158b\u158c\u158d\u158e\u158f\u1590\u1591\u1592\u1593\u1594\u1595\u1596\u1597\u1598\u1599\u159a\u159b\u159c\u159d\u159e\u159f\u15a0\u15a1\u15a2\u15a3\u15a4\u15a5\u15a6\u15a7\u15a8\u15a9\u15aa\u15ab\u15ac\u15ad\u15ae\u15af\u15b0\u15b1\u15b2\u15b3\u15b4\u15b5\u15b6\u15b7\u15b8\u15b9\u15ba\u15bb\u15bc\u15bd\u15be\u15bf\u15c0\u15c1\u15c2\u15c3\u15c4\u15c5\u15c6\u15c7\u15c8\u15c9\u15ca\u15cb\u15cc\u15cd\u15ce\u15cf\u15d0\u15d1\u15d2\u15d3\u15d4\u15d5\u15d6\u15d7\u15d8\u15d9\u15da\u15db\u15dc\u15dd\u15de\u15df\u15e0\u15e1\u15e2\u15e3\u15e4\u15e5\u15e6\u15e7\u15e8\u15e9\u15ea\u15eb\u15ec\u15ed\u15ee\u15ef\u15f0\u15f1\u15f2\u15f3\u15f4\u15f5\u15f6\u15f7\u15f8\u15f9\u15fa\u15fb\u15fc\u15fd\u15fe\u15ff\u1600\u1601\u1602\u1603\u1604\u1605\u1606\u1607\u1608\u1609\u160a\u160b\u160c\u160d\u160e\u160f\u1610\u1611\u1612\u1613\u1614\u1615\u1616\u1617\u1618\u1619\u161a\u161b\u161c\u161d\u161e\u161f\u1620\u1621\u1622\u1623\u1624\u1625\u1626\u1627\u1628\u1629\u162a\u162b\u162c\u162d\u162e\u162f\u1630\u1631\u1632\u1633\u1634\u1635\u1636\u1637\u1638\u1639\u163a\u163b\u163c\u163d\u163e\u163f\u1640\u1641\u1642\u1643\u1644\u1645\u1646\u1647\u1648\u1649\u164a\u164b\u164c\u164d\u164e\u164f\u1650\u1651\u1652\u1653\u1654\u1655\u1656\u1657\u1658\u1659\u165a\u165b\u165c\u165d\u165e\u165f\u1660\u1661\u1662\u1663\u1664\u1665\u1666\u1667\u1668\u1669\u166a\u166b\u166c\u166f\u1670\u1671\u1672\u1673\u1674\u1675\u1676\u1681\u1682\u1683\u1684\u1685\u1686\u1687\u1688\u1689\u168a\u168b\u168c\u168d\u168e\u168f\u1690\u1691\u1692\u1693\u1694\u1695\u1696\u1697\u1698\u1699\u169a\u16a0\u16a1\u16a2\u16a3\u16a4\u16a5\u16a6\u16a7\u16a8\u16a9\u16aa\u16ab\u16ac\u16ad\u16ae\u16af\u16b0\u16b1\u16b2\u16b3\u16b4\u16b5\u16b6\u16b7\u16b8\u16b9\u16ba\u16bb\u16bc\u16bd\u16be\u16bf\u16c0\u16c1\u16c2\u16c3\u16c4\u16c5\u16c6\u16c7\u16c8\u16c9\u16ca\u16cb\u16cc\u16cd\u16ce\u16cf\u16d0\u16d1\u16d2\u16d3\u16d4\u16d5\u16d6\u16d7\u16d8\u16d9\u16da\u16db\u16dc\u16dd\u16de\u16df\u16e0\u16e1\u16e2\u16e3\u16e4\u16e5\u16e6\u16e7\u16e8\u16e9\u16ea\u1700\u1701\u1702\u1703\u1704\u1705\u1706\u1707\u1708\u1709\u170a\u170b\u170c\u170e\u170f\u1710\u1711\u1720\u1721\u1722\u1723\u1724\u1725\u1726\u1727\u1728\u1729\u172a\u172b\u172c\u172d\u172e\u172f\u1730\u1731\u1740\u1741\u1742\u1743\u1744\u1745\u1746\u1747\u1748\u1749\u174a\u174b\u174c\u174d\u174e\u174f\u1750\u1751\u1760\u1761\u1762\u1763\u1764\u1765\u1766\u1767\u1768\u1769\u176a\u176b\u176c\u176e\u176f\u1770\u1780\u1781\u1782\u1783\u1784\u1785\u1786\u1787\u1788\u1789\u178a\u178b\u178c\u178d\u178e\u178f\u1790\u1791\u1792\u1793\u1794\u1795\u1796\u1797\u1798\u1799\u179a\u179b\u179c\u179d\u179e\u179f\u17a0\u17a1\u17a2\u17a3\u17a4\u17a5\u17a6\u17a7\u17a8\u17a9\u17aa\u17ab\u17ac\u17ad\u17ae\u17af\u17b0\u17b1\u17b2\u17b3\u17dc\u1820\u1821\u1822\u1823\u1824\u1825\u1826\u1827\u1828\u1829\u182a\u182b\u182c\u182d\u182e\u182f\u1830\u1831\u1832\u1833\u1834\u1835\u1836\u1837\u1838\u1839\u183a\u183b\u183c\u183d\u183e\u183f\u1840\u1841\u1842\u1844\u1845\u1846\u1847\u1848\u1849\u184a\u184b\u184c\u184d\u184e\u184f\u1850\u1851\u1852\u1853\u1854\u1855\u1856\u1857\u1858\u1859\u185a\u185b\u185c\u185d\u185e\u185f\u1860\u1861\u1862\u1863\u1864\u1865\u1866\u1867\u1868\u1869\u186a\u186b\u186c\u186d\u186e\u186f\u1870\u1871\u1872\u1873\u1874\u1875\u1876\u1877\u1880\u1881\u1882\u1883\u1884\u1885\u1886\u1887\u1888\u1889\u188a\u188b\u188c\u188d\u188e\u188f\u1890\u1891\u1892\u1893\u1894\u1895\u1896\u1897\u1898\u1899\u189a\u189b\u189c\u189d\u189e\u189f\u18a0\u18a1\u18a2\u18a3\u18a4\u18a5\u18a6\u18a7\u18a8\u1900\u1901\u1902\u1903\u1904\u1905\u1906\u1907\u1908\u1909\u190a\u190b\u190c\u190d\u190e\u190f\u1910\u1911\u1912\u1913\u1914\u1915\u1916\u1917\u1918\u1919\u191a\u191b\u191c\u1950\u1951\u1952\u1953\u1954\u1955\u1956\u1957\u1958\u1959\u195a\u195b\u195c\u195d\u195e\u195f\u1960\u1961\u1962\u1963\u1964\u1965\u1966\u1967\u1968\u1969\u196a\u196b\u196c\u196d\u1970\u1971\u1972\u1973\u1974\u1980\u1981\u1982\u1983\u1984\u1985\u1986\u1987\u1988\u1989\u198a\u198b\u198c\u198d\u198e\u198f\u1990\u1991\u1992\u1993\u1994\u1995\u1996\u1997\u1998\u1999\u199a\u199b\u199c\u199d\u199e\u199f\u19a0\u19a1\u19a2\u19a3\u19a4\u19a5\u19a6\u19a7\u19a8\u19a9\u19c1\u19c2\u19c3\u19c4\u19c5\u19c6\u19c7\u1a00\u1a01\u1a02\u1a03\u1a04\u1a05\u1a06\u1a07\u1a08\u1a09\u1a0a\u1a0b\u1a0c\u1a0d\u1a0e\u1a0f\u1a10\u1a11\u1a12\u1a13\u1a14\u1a15\u1a16\u2135\u2136\u2137\u2138\u2d30\u2d31\u2d32\u2d33\u2d34\u2d35\u2d36\u2d37\u2d38\u2d39\u2d3a\u2d3b\u2d3c\u2d3d\u2d3e\u2d3f\u2d40\u2d41\u2d42\u2d43\u2d44\u2d45\u2d46\u2d47\u2d48\u2d49\u2d4a\u2d4b\u2d4c\u2d4d\u2d4e\u2d4f\u2d50\u2d51\u2d52\u2d53\u2d54\u2d55\u2d56\u2d57\u2d58\u2d59\u2d5a\u2d5b\u2d5c\u2d5d\u2d5e\u2d5f\u2d60\u2d61\u2d62\u2d63\u2d64\u2d65\u2d80\u2d81\u2d82\u2d83\u2d84\u2d85\u2d86\u2d87\u2d88\u2d89\u2d8a\u2d8b\u2d8c\u2d8d\u2d8e\u2d8f\u2d90\u2d91\u2d92\u2d93\u2d94\u2d95\u2d96\u2da0\u2da1\u2da2\u2da3\u2da4\u2da5\u2da6\u2da8\u2da9\u2daa\u2dab\u2dac\u2dad\u2dae\u2db0\u2db1\u2db2\u2db3\u2db4\u2db5\u2db6\u2db8\u2db9\u2dba\u2dbb\u2dbc\u2dbd\u2dbe\u2dc0\u2dc1\u2dc2\u2dc3\u2dc4\u2dc5\u2dc6\u2dc8\u2dc9\u2dca\u2dcb\u2dcc\u2dcd\u2dce\u2dd0\u2dd1\u2dd2\u2dd3\u2dd4\u2dd5\u2dd6\u2dd8\u2dd9\u2dda\u2ddb\u2ddc\u2ddd\u2dde\u3006\u303c\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\u3090\u3091\u3092\u3093\u3094\u3095\u3096\u309f\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30ff\u3105\u3106\u3107\u3108\u3109\u310a\u310b\u310c\u310d\u310e\u310f\u3110\u3111\u3112\u3113\u3114\u3115\u3116\u3117\u3118\u3119\u311a\u311b\u311c\u311d\u311e\u311f\u3120\u3121\u3122\u3123\u3124\u3125\u3126\u3127\u3128\u3129\u312a\u312b\u312c\u3131\u3132\u3133\u3134\u3135\u3136\u3137\u3138\u3139\u313a\u313b\u313c\u313d\u313e\u313f\u3140\u3141\u3142\u3143\u3144\u3145\u3146\u3147\u3148\u3149\u314a\u314b\u314c\u314d\u314e\u314f\u3150\u3151\u3152\u3153\u3154\u3155\u3156\u3157\u3158\u3159\u315a\u315b\u315c\u315d\u315e\u315f\u3160\u3161\u3162\u3163\u3164\u3165\u3166\u3167\u3168\u3169\u316a\u316b\u316c\u316d\u316e\u316f\u3170\u3171\u3172\u3173\u3174\u3175\u3176\u3177\u3178\u3179\u317a\u317b\u317c\u317d\u317e\u317f\u3180\u3181\u3182\u3183\u3184\u3185\u3186\u3187\u3188\u3189\u318a\u318b\u318c\u318d\u318e\u31a0\u31a1\u31a2\u31a3\u31a4\u31a5\u31a6\u31a7\u31a8\u31a9\u31aa\u31ab\u31ac\u31ad\u31ae\u31af\u31b0\u31b1\u31b2\u31b3\u31b4\u31b5\u31b6\u31b7\u31f0\u31f1\u31f2\u31f3\u31f4\u31f5\u31f6\u31f7\u31f8\u31f9\u31fa\u31fb\u31fc\u31fd\u31fe\u31ff\u3400\u3401\u3402\u3403\u3404\u3405\u3406\u3407\u3408\u3409\u340a\u340b\u340c\u340d\u340e\u340f\u3410\u3411\u3412\u3413\u3414\u3415\u3416\u3417\u3418\u3419\u341a\u341b\u341c\u341d\u341e\u341f\u3420\u3421\u3422\u3423\u3424\u3425\u3426\u3427\u3428\u3429\u342a\u342b\u342c\u342d\u342e\u342f\u3430\u3431\u3432\u3433\u3434\u3435\u3436\u3437\u3438\u3439\u343a\u343b\u343c\u343d\u343e\u343f\u3440\u3441\u3442\u3443\u3444\u3445\u3446\u3447\u3448\u3449\u344a\u344b\u344c\u344d\u344e\u344f\u3450\u3451\u3452\u3453\u3454\u3455\u3456\u3457\u3458\u3459\u345a\u345b\u345c\u345d\u345e\u345f\u3460\u3461\u3462\u3463\u3464\u3465\u3466\u3467\u3468\u3469\u346a\u346b\u346c\u346d\u346e\u346f\u3470\u3471\u3472\u3473\u3474\u3475\u3476\u3477\u3478\u3479\u347a\u347b\u347c\u347d\u347e\u347f\u3480\u3481\u3482\u3483\u3484\u3485\u3486\u3487\u3488\u3489\u348a\u348b\u348c\u348d\u348e\u348f\u3490\u3491\u3492\u3493\u3494\u3495\u3496\u3497\u3498\u3499\u349a\u349b\u349c\u349d\u349e\u349f\u34a0\u34a1\u34a2\u34a3\u34a4\u34a5\u34a6\u34a7\u34a8\u34a9\u34aa\u34ab\u34ac\u34ad\u34ae\u34af\u34b0\u34b1\u34b2\u34b3\u34b4\u34b5\u34b6\u34b7\u34b8\u34b9\u34ba\u34bb\u34bc\u34bd\u34be\u34bf\u34c0\u34c1\u34c2\u34c3\u34c4\u34c5\u34c6\u34c7\u34c8\u34c9\u34ca\u34cb\u34cc\u34cd\u34ce\u34cf\u34d0\u34d1\u34d2\u34d3\u34d4\u34d5\u34d6\u34d7\u34d8\u34d9\u34da\u34db\u34dc\u34dd\u34de\u34df\u34e0\u34e1\u34e2\u34e3\u34e4\u34e5\u34e6\u34e7\u34e8\u34e9\u34ea\u34eb\u34ec\u34ed\u34ee\u34ef\u34f0\u34f1\u34f2\u34f3\u34f4\u34f5\u34f6\u34f7\u34f8\u34f9\u34fa\u34fb\u34fc\u34fd\u34fe\u34ff\u3500\u3501\u3502\u3503\u3504\u3505\u3506\u3507\u3508\u3509\u350a\u350b\u350c\u350d\u350e\u350f\u3510\u3511\u3512\u3513\u3514\u3515\u3516\u3517\u3518\u3519\u351a\u351b\u351c\u351d\u351e\u351f\u3520\u3521\u3522\u3523\u3524\u3525\u3526\u3527\u3528\u3529\u352a\u352b\u352c\u352d\u352e\u352f\u3530\u3531\u3532\u3533\u3534\u3535\u3536\u3537\u3538\u3539\u353a\u353b\u353c\u353d\u353e\u353f\u3540\u3541\u3542\u3543\u3544\u3545\u3546\u3547\u3548\u3549\u354a\u354b\u354c\u354d\u354e\u354f\u3550\u3551\u3552\u3553\u3554\u3555\u3556\u3557\u3558\u3559\u355a\u355b\u355c\u355d\u355e\u355f\u3560\u3561\u3562\u3563\u3564\u3565\u3566\u3567\u3568\u3569\u356a\u356b\u356c\u356d\u356e\u356f\u3570\u3571\u3572\u3573\u3574\u3575\u3576\u3577\u3578\u3579\u357a\u357b\u357c\u357d\u357e\u357f\u3580\u3581\u3582\u3583\u3584\u3585\u3586\u3587\u3588\u3589\u358a\u358b\u358c\u358d\u358e\u358f\u3590\u3591\u3592\u3593\u3594\u3595\u3596\u3597\u3598\u3599\u359a\u359b\u359c\u359d\u359e\u359f\u35a0\u35a1\u35a2\u35a3\u35a4\u35a5\u35a6\u35a7\u35a8\u35a9\u35aa\u35ab\u35ac\u35ad\u35ae\u35af\u35b0\u35b1\u35b2\u35b3\u35b4\u35b5\u35b6\u35b7\u35b8\u35b9\u35ba\u35bb\u35bc\u35bd\u35be\u35bf\u35c0\u35c1\u35c2\u35c3\u35c4\u35c5\u35c6\u35c7\u35c8\u35c9\u35ca\u35cb\u35cc\u35cd\u35ce\u35cf\u35d0\u35d1\u35d2\u35d3\u35d4\u35d5\u35d6\u35d7\u35d8\u35d9\u35da\u35db\u35dc\u35dd\u35de\u35df\u35e0\u35e1\u35e2\u35e3\u35e4\u35e5\u35e6\u35e7\u35e8\u35e9\u35ea\u35eb\u35ec\u35ed\u35ee\u35ef\u35f0\u35f1\u35f2\u35f3\u35f4\u35f5\u35f6\u35f7\u35f8\u35f9\u35fa\u35fb\u35fc\u35fd\u35fe\u35ff\u3600\u3601\u3602\u3603\u3604\u3605\u3606\u3607\u3608\u3609\u360a\u360b\u360c\u360d\u360e\u360f\u3610\u3611\u3612\u3613\u3614\u3615\u3616\u3617\u3618\u3619\u361a\u361b\u361c\u361d\u361e\u361f\u3620\u3621\u3622\u3623\u3624\u3625\u3626\u3627\u3628\u3629\u362a\u362b\u362c\u362d\u362e\u362f\u3630\u3631\u3632\u3633\u3634\u3635\u3636\u3637\u3638\u3639\u363a\u363b\u363c\u363d\u363e\u363f\u3640\u3641\u3642\u3643\u3644\u3645\u3646\u3647\u3648\u3649\u364a\u364b\u364c\u364d\u364e\u364f\u3650\u3651\u3652\u3653\u3654\u3655\u3656\u3657\u3658\u3659\u365a\u365b\u365c\u365d\u365e\u365f\u3660\u3661\u3662\u3663\u3664\u3665\u3666\u3667\u3668\u3669\u366a\u366b\u366c\u366d\u366e\u366f\u3670\u3671\u3672\u3673\u3674\u3675\u3676\u3677\u3678\u3679\u367a\u367b\u367c\u367d\u367e\u367f\u3680\u3681\u3682\u3683\u3684\u3685\u3686\u3687\u3688\u3689\u368a\u368b\u368c\u368d\u368e\u368f\u3690\u3691\u3692\u3693\u3694\u3695\u3696\u3697\u3698\u3699\u369a\u369b\u369c\u369d\u369e\u369f\u36a0\u36a1\u36a2\u36a3\u36a4\u36a5\u36a6\u36a7\u36a8\u36a9\u36aa\u36ab\u36ac\u36ad\u36ae\u36af\u36b0\u36b1\u36b2\u36b3\u36b4\u36b5\u36b6\u36b7\u36b8\u36b9\u36ba\u36bb\u36bc\u36bd\u36be\u36bf\u36c0\u36c1\u36c2\u36c3\u36c4\u36c5\u36c6\u36c7\u36c8\u36c9\u36ca\u36cb\u36cc\u36cd\u36ce\u36cf\u36d0\u36d1\u36d2\u36d3\u36d4\u36d5\u36d6\u36d7\u36d8\u36d9\u36da\u36db\u36dc\u36dd\u36de\u36df\u36e0\u36e1\u36e2\u36e3\u36e4\u36e5\u36e6\u36e7\u36e8\u36e9\u36ea\u36eb\u36ec\u36ed\u36ee\u36ef\u36f0\u36f1\u36f2\u36f3\u36f4\u36f5\u36f6\u36f7\u36f8\u36f9\u36fa\u36fb\u36fc\u36fd\u36fe\u36ff\u3700\u3701\u3702\u3703\u3704\u3705\u3706\u3707\u3708\u3709\u370a\u370b\u370c\u370d\u370e\u370f\u3710\u3711\u3712\u3713\u3714\u3715\u3716\u3717\u3718\u3719\u371a\u371b\u371c\u371d\u371e\u371f\u3720\u3721\u3722\u3723\u3724\u3725\u3726\u3727\u3728\u3729\u372a\u372b\u372c\u372d\u372e\u372f\u3730\u3731\u3732\u3733\u3734\u3735\u3736\u3737\u3738\u3739\u373a\u373b\u373c\u373d\u373e\u373f\u3740\u3741\u3742\u3743\u3744\u3745\u3746\u3747\u3748\u3749\u374a\u374b\u374c\u374d\u374e\u374f\u3750\u3751\u3752\u3753\u3754\u3755\u3756\u3757\u3758\u3759\u375a\u375b\u375c\u375d\u375e\u375f\u3760\u3761\u3762\u3763\u3764\u3765\u3766\u3767\u3768\u3769\u376a\u376b\u376c\u376d\u376e\u376f\u3770\u3771\u3772\u3773\u3774\u3775\u3776\u3777\u3778\u3779\u377a\u377b\u377c\u377d\u377e\u377f\u3780\u3781\u3782\u3783\u3784\u3785\u3786\u3787\u3788\u3789\u378a\u378b\u378c\u378d\u378e\u378f\u3790\u3791\u3792\u3793\u3794\u3795\u3796\u3797\u3798\u3799\u379a\u379b\u379c\u379d\u379e\u379f\u37a0\u37a1\u37a2\u37a3\u37a4\u37a5\u37a6\u37a7\u37a8\u37a9\u37aa\u37ab\u37ac\u37ad\u37ae\u37af\u37b0\u37b1\u37b2\u37b3\u37b4\u37b5\u37b6\u37b7\u37b8\u37b9\u37ba\u37bb\u37bc\u37bd\u37be\u37bf\u37c0\u37c1\u37c2\u37c3\u37c4\u37c5\u37c6\u37c7\u37c8\u37c9\u37ca\u37cb\u37cc\u37cd\u37ce\u37cf\u37d0\u37d1\u37d2\u37d3\u37d4\u37d5\u37d6\u37d7\u37d8\u37d9\u37da\u37db\u37dc\u37dd\u37de\u37df\u37e0\u37e1\u37e2\u37e3\u37e4\u37e5\u37e6\u37e7\u37e8\u37e9\u37ea\u37eb\u37ec\u37ed\u37ee\u37ef\u37f0\u37f1\u37f2\u37f3\u37f4\u37f5\u37f6\u37f7\u37f8\u37f9\u37fa\u37fb\u37fc\u37fd\u37fe\u37ff\u3800\u3801\u3802\u3803\u3804\u3805\u3806\u3807\u3808\u3809\u380a\u380b\u380c\u380d\u380e\u380f\u3810\u3811\u3812\u3813\u3814\u3815\u3816\u3817\u3818\u3819\u381a\u381b\u381c\u381d\u381e\u381f\u3820\u3821\u3822\u3823\u3824\u3825\u3826\u3827\u3828\u3829\u382a\u382b\u382c\u382d\u382e\u382f\u3830\u3831\u3832\u3833\u3834\u3835\u3836\u3837\u3838\u3839\u383a\u383b\u383c\u383d\u383e\u383f\u3840\u3841\u3842\u3843\u3844\u3845\u3846\u3847\u3848\u3849\u384a\u384b\u384c\u384d\u384e\u384f\u3850\u3851\u3852\u3853\u3854\u3855\u3856\u3857\u3858\u3859\u385a\u385b\u385c\u385d\u385e\u385f\u3860\u3861\u3862\u3863\u3864\u3865\u3866\u3867\u3868\u3869\u386a\u386b\u386c\u386d\u386e\u386f\u3870\u3871\u3872\u3873\u3874\u3875\u3876\u3877\u3878\u3879\u387a\u387b\u387c\u387d\u387e\u387f\u3880\u3881\u3882\u3883\u3884\u3885\u3886\u3887\u3888\u3889\u388a\u388b\u388c\u388d\u388e\u388f\u3890\u3891\u3892\u3893\u3894\u3895\u3896\u3897\u3898\u3899\u389a\u389b\u389c\u389d\u389e\u389f\u38a0\u38a1\u38a2\u38a3\u38a4\u38a5\u38a6\u38a7\u38a8\u38a9\u38aa\u38ab\u38ac\u38ad\u38ae\u38af\u38b0\u38b1\u38b2\u38b3\u38b4\u38b5\u38b6\u38b7\u38b8\u38b9\u38ba\u38bb\u38bc\u38bd\u38be\u38bf\u38c0\u38c1\u38c2\u38c3\u38c4\u38c5\u38c6\u38c7\u38c8\u38c9\u38ca\u38cb\u38cc\u38cd\u38ce\u38cf\u38d0\u38d1\u38d2\u38d3\u38d4\u38d5\u38d6\u38d7\u38d8\u38d9\u38da\u38db\u38dc\u38dd\u38de\u38df\u38e0\u38e1\u38e2\u38e3\u38e4\u38e5\u38e6\u38e7\u38e8\u38e9\u38ea\u38eb\u38ec\u38ed\u38ee\u38ef\u38f0\u38f1\u38f2\u38f3\u38f4\u38f5\u38f6\u38f7\u38f8\u38f9\u38fa\u38fb\u38fc\u38fd\u38fe\u38ff\u3900\u3901\u3902\u3903\u3904\u3905\u3906\u3907\u3908\u3909\u390a\u390b\u390c\u390d\u390e\u390f\u3910\u3911\u3912\u3913\u3914\u3915\u3916\u3917\u3918\u3919\u391a\u391b\u391c\u391d\u391e\u391f\u3920\u3921\u3922\u3923\u3924\u3925\u3926\u3927\u3928\u3929\u392a\u392b\u392c\u392d\u392e\u392f\u3930\u3931\u3932\u3933\u3934\u3935\u3936\u3937\u3938\u3939\u393a\u393b\u393c\u393d\u393e\u393f\u3940\u3941\u3942\u3943\u3944\u3945\u3946\u3947\u3948\u3949\u394a\u394b\u394c\u394d\u394e\u394f\u3950\u3951\u3952\u3953\u3954\u3955\u3956\u3957\u3958\u3959\u395a\u395b\u395c\u395d\u395e\u395f\u3960\u3961\u3962\u3963\u3964\u3965\u3966\u3967\u3968\u3969\u396a\u396b\u396c\u396d\u396e\u396f\u3970\u3971\u3972\u3973\u3974\u3975\u3976\u3977\u3978\u3979\u397a\u397b\u397c\u397d\u397e\u397f\u3980\u3981\u3982\u3983\u3984\u3985\u3986\u3987\u3988\u3989\u398a\u398b\u398c\u398d\u398e\u398f\u3990\u3991\u3992\u3993\u3994\u3995\u3996\u3997\u3998\u3999\u399a\u399b\u399c\u399d\u399e\u399f\u39a0\u39a1\u39a2\u39a3\u39a4\u39a5\u39a6\u39a7\u39a8\u39a9\u39aa\u39ab\u39ac\u39ad\u39ae\u39af\u39b0\u39b1\u39b2\u39b3\u39b4\u39b5\u39b6\u39b7\u39b8\u39b9\u39ba\u39bb\u39bc\u39bd\u39be\u39bf\u39c0\u39c1\u39c2\u39c3\u39c4\u39c5\u39c6\u39c7\u39c8\u39c9\u39ca\u39cb\u39cc\u39cd\u39ce\u39cf\u39d0\u39d1\u39d2\u39d3\u39d4\u39d5\u39d6\u39d7\u39d8\u39d9\u39da\u39db\u39dc\u39dd\u39de\u39df\u39e0\u39e1\u39e2\u39e3\u39e4\u39e5\u39e6\u39e7\u39e8\u39e9\u39ea\u39eb\u39ec\u39ed\u39ee\u39ef\u39f0\u39f1\u39f2\u39f3\u39f4\u39f5\u39f6\u39f7\u39f8\u39f9\u39fa\u39fb\u39fc\u39fd\u39fe\u39ff\u3a00\u3a01\u3a02\u3a03\u3a04\u3a05\u3a06\u3a07\u3a08\u3a09\u3a0a\u3a0b\u3a0c\u3a0d\u3a0e\u3a0f\u3a10\u3a11\u3a12\u3a13\u3a14\u3a15\u3a16\u3a17\u3a18\u3a19\u3a1a\u3a1b\u3a1c\u3a1d\u3a1e\u3a1f\u3a20\u3a21\u3a22\u3a23\u3a24\u3a25\u3a26\u3a27\u3a28\u3a29\u3a2a\u3a2b\u3a2c\u3a2d\u3a2e\u3a2f\u3a30\u3a31\u3a32\u3a33\u3a34\u3a35\u3a36\u3a37\u3a38\u3a39\u3a3a\u3a3b\u3a3c\u3a3d\u3a3e\u3a3f\u3a40\u3a41\u3a42\u3a43\u3a44\u3a45\u3a46\u3a47\u3a48\u3a49\u3a4a\u3a4b\u3a4c\u3a4d\u3a4e\u3a4f\u3a50\u3a51\u3a52\u3a53\u3a54\u3a55\u3a56\u3a57\u3a58\u3a59\u3a5a\u3a5b\u3a5c\u3a5d\u3a5e\u3a5f\u3a60\u3a61\u3a62\u3a63\u3a64\u3a65\u3a66\u3a67\u3a68\u3a69\u3a6a\u3a6b\u3a6c\u3a6d\u3a6e\u3a6f\u3a70\u3a71\u3a72\u3a73\u3a74\u3a75\u3a76\u3a77\u3a78\u3a79\u3a7a\u3a7b\u3a7c\u3a7d\u3a7e\u3a7f\u3a80\u3a81\u3a82\u3a83\u3a84\u3a85\u3a86\u3a87\u3a88\u3a89\u3a8a\u3a8b\u3a8c\u3a8d\u3a8e\u3a8f\u3a90\u3a91\u3a92\u3a93\u3a94\u3a95\u3a96\u3a97\u3a98\u3a99\u3a9a\u3a9b\u3a9c\u3a9d\u3a9e\u3a9f\u3aa0\u3aa1\u3aa2\u3aa3\u3aa4\u3aa5\u3aa6\u3aa7\u3aa8\u3aa9\u3aaa\u3aab\u3aac\u3aad\u3aae\u3aaf\u3ab0\u3ab1\u3ab2\u3ab3\u3ab4\u3ab5\u3ab6\u3ab7\u3ab8\u3ab9\u3aba\u3abb\u3abc\u3abd\u3abe\u3abf\u3ac0\u3ac1\u3ac2\u3ac3\u3ac4\u3ac5\u3ac6\u3ac7\u3ac8\u3ac9\u3aca\u3acb\u3acc\u3acd\u3ace\u3acf\u3ad0\u3ad1\u3ad2\u3ad3\u3ad4\u3ad5\u3ad6\u3ad7\u3ad8\u3ad9\u3ada\u3adb\u3adc\u3add\u3ade\u3adf\u3ae0\u3ae1\u3ae2\u3ae3\u3ae4\u3ae5\u3ae6\u3ae7\u3ae8\u3ae9\u3aea\u3aeb\u3aec\u3aed\u3aee\u3aef\u3af0\u3af1\u3af2\u3af3\u3af4\u3af5\u3af6\u3af7\u3af8\u3af9\u3afa\u3afb\u3afc\u3afd\u3afe\u3aff\u3b00\u3b01\u3b02\u3b03\u3b04\u3b05\u3b06\u3b07\u3b08\u3b09\u3b0a\u3b0b\u3b0c\u3b0d\u3b0e\u3b0f\u3b10\u3b11\u3b12\u3b13\u3b14\u3b15\u3b16\u3b17\u3b18\u3b19\u3b1a\u3b1b\u3b1c\u3b1d\u3b1e\u3b1f\u3b20\u3b21\u3b22\u3b23\u3b24\u3b25\u3b26\u3b27\u3b28\u3b29\u3b2a\u3b2b\u3b2c\u3b2d\u3b2e\u3b2f\u3b30\u3b31\u3b32\u3b33\u3b34\u3b35\u3b36\u3b37\u3b38\u3b39\u3b3a\u3b3b\u3b3c\u3b3d\u3b3e\u3b3f\u3b40\u3b41\u3b42\u3b43\u3b44\u3b45\u3b46\u3b47\u3b48\u3b49\u3b4a\u3b4b\u3b4c\u3b4d\u3b4e\u3b4f\u3b50\u3b51\u3b52\u3b53\u3b54\u3b55\u3b56\u3b57\u3b58\u3b59\u3b5a\u3b5b\u3b5c\u3b5d\u3b5e\u3b5f\u3b60\u3b61\u3b62\u3b63\u3b64\u3b65\u3b66\u3b67\u3b68\u3b69\u3b6a\u3b6b\u3b6c\u3b6d\u3b6e\u3b6f\u3b70\u3b71\u3b72\u3b73\u3b74\u3b75\u3b76\u3b77\u3b78\u3b79\u3b7a\u3b7b\u3b7c\u3b7d\u3b7e\u3b7f\u3b80\u3b81\u3b82\u3b83\u3b84\u3b85\u3b86\u3b87\u3b88\u3b89\u3b8a\u3b8b\u3b8c\u3b8d\u3b8e\u3b8f\u3b90\u3b91\u3b92\u3b93\u3b94\u3b95\u3b96\u3b97\u3b98\u3b99\u3b9a\u3b9b\u3b9c\u3b9d\u3b9e\u3b9f\u3ba0\u3ba1\u3ba2\u3ba3\u3ba4\u3ba5\u3ba6\u3ba7\u3ba8\u3ba9\u3baa\u3bab\u3bac\u3bad\u3bae\u3baf\u3bb0\u3bb1\u3bb2\u3bb3\u3bb4\u3bb5\u3bb6\u3bb7\u3bb8\u3bb9\u3bba\u3bbb\u3bbc\u3bbd\u3bbe\u3bbf\u3bc0\u3bc1\u3bc2\u3bc3\u3bc4\u3bc5\u3bc6\u3bc7\u3bc8\u3bc9\u3bca\u3bcb\u3bcc\u3bcd\u3bce\u3bcf\u3bd0\u3bd1\u3bd2\u3bd3\u3bd4\u3bd5\u3bd6\u3bd7\u3bd8\u3bd9\u3bda\u3bdb\u3bdc\u3bdd\u3bde\u3bdf\u3be0\u3be1\u3be2\u3be3\u3be4\u3be5\u3be6\u3be7\u3be8\u3be9\u3bea\u3beb\u3bec\u3bed\u3bee\u3bef\u3bf0\u3bf1\u3bf2\u3bf3\u3bf4\u3bf5\u3bf6\u3bf7\u3bf8\u3bf9\u3bfa\u3bfb\u3bfc\u3bfd\u3bfe\u3bff\u3c00\u3c01\u3c02\u3c03\u3c04\u3c05\u3c06\u3c07\u3c08\u3c09\u3c0a\u3c0b\u3c0c\u3c0d\u3c0e\u3c0f\u3c10\u3c11\u3c12\u3c13\u3c14\u3c15\u3c16\u3c17\u3c18\u3c19\u3c1a\u3c1b\u3c1c\u3c1d\u3c1e\u3c1f\u3c20\u3c21\u3c22\u3c23\u3c24\u3c25\u3c26\u3c27\u3c28\u3c29\u3c2a\u3c2b\u3c2c\u3c2d\u3c2e\u3c2f\u3c30\u3c31\u3c32\u3c33\u3c34\u3c35\u3c36\u3c37\u3c38\u3c39\u3c3a\u3c3b\u3c3c\u3c3d\u3c3e\u3c3f\u3c40\u3c41\u3c42\u3c43\u3c44\u3c45\u3c46\u3c47\u3c48\u3c49\u3c4a\u3c4b\u3c4c\u3c4d\u3c4e\u3c4f\u3c50\u3c51\u3c52\u3c53\u3c54\u3c55\u3c56\u3c57\u3c58\u3c59\u3c5a\u3c5b\u3c5c\u3c5d\u3c5e\u3c5f\u3c60\u3c61\u3c62\u3c63\u3c64\u3c65\u3c66\u3c67\u3c68\u3c69\u3c6a\u3c6b\u3c6c\u3c6d\u3c6e\u3c6f\u3c70\u3c71\u3c72\u3c73\u3c74\u3c75\u3c76\u3c77\u3c78\u3c79\u3c7a\u3c7b\u3c7c\u3c7d\u3c7e\u3c7f\u3c80\u3c81\u3c82\u3c83\u3c84\u3c85\u3c86\u3c87\u3c88\u3c89\u3c8a\u3c8b\u3c8c\u3c8d\u3c8e\u3c8f\u3c90\u3c91\u3c92\u3c93\u3c94\u3c95\u3c96\u3c97\u3c98\u3c99\u3c9a\u3c9b\u3c9c\u3c9d\u3c9e\u3c9f\u3ca0\u3ca1\u3ca2\u3ca3\u3ca4\u3ca5\u3ca6\u3ca7\u3ca8\u3ca9\u3caa\u3cab\u3cac\u3cad\u3cae\u3caf\u3cb0\u3cb1\u3cb2\u3cb3\u3cb4\u3cb5\u3cb6\u3cb7\u3cb8\u3cb9\u3cba\u3cbb\u3cbc\u3cbd\u3cbe\u3cbf\u3cc0\u3cc1\u3cc2\u3cc3\u3cc4\u3cc5\u3cc6\u3cc7\u3cc8\u3cc9\u3cca\u3ccb\u3ccc\u3ccd\u3cce\u3ccf\u3cd0\u3cd1\u3cd2\u3cd3\u3cd4\u3cd5\u3cd6\u3cd7\u3cd8\u3cd9\u3cda\u3cdb\u3cdc\u3cdd\u3cde\u3cdf\u3ce0\u3ce1\u3ce2\u3ce3\u3ce4\u3ce5\u3ce6\u3ce7\u3ce8\u3ce9\u3cea\u3ceb\u3cec\u3ced\u3cee\u3cef\u3cf0\u3cf1\u3cf2\u3cf3\u3cf4\u3cf5\u3cf6\u3cf7\u3cf8\u3cf9\u3cfa\u3cfb\u3cfc\u3cfd\u3cfe\u3cff\u3d00\u3d01\u3d02\u3d03\u3d04\u3d05\u3d06\u3d07\u3d08\u3d09\u3d0a\u3d0b\u3d0c\u3d0d\u3d0e\u3d0f\u3d10\u3d11\u3d12\u3d13\u3d14\u3d15\u3d16\u3d17\u3d18\u3d19\u3d1a\u3d1b\u3d1c\u3d1d\u3d1e\u3d1f\u3d20\u3d21\u3d22\u3d23\u3d24\u3d25\u3d26\u3d27\u3d28\u3d29\u3d2a\u3d2b\u3d2c\u3d2d\u3d2e\u3d2f\u3d30\u3d31\u3d32\u3d33\u3d34\u3d35\u3d36\u3d37\u3d38\u3d39\u3d3a\u3d3b\u3d3c\u3d3d\u3d3e\u3d3f\u3d40\u3d41\u3d42\u3d43\u3d44\u3d45\u3d46\u3d47\u3d48\u3d49\u3d4a\u3d4b\u3d4c\u3d4d\u3d4e\u3d4f\u3d50\u3d51\u3d52\u3d53\u3d54\u3d55\u3d56\u3d57\u3d58\u3d59\u3d5a\u3d5b\u3d5c\u3d5d\u3d5e\u3d5f\u3d60\u3d61\u3d62\u3d63\u3d64\u3d65\u3d66\u3d67\u3d68\u3d69\u3d6a\u3d6b\u3d6c\u3d6d\u3d6e\u3d6f\u3d70\u3d71\u3d72\u3d73\u3d74\u3d75\u3d76\u3d77\u3d78\u3d79\u3d7a\u3d7b\u3d7c\u3d7d\u3d7e\u3d7f\u3d80\u3d81\u3d82\u3d83\u3d84\u3d85\u3d86\u3d87\u3d88\u3d89\u3d8a\u3d8b\u3d8c\u3d8d\u3d8e\u3d8f\u3d90\u3d91\u3d92\u3d93\u3d94\u3d95\u3d96\u3d97\u3d98\u3d99\u3d9a\u3d9b\u3d9c\u3d9d\u3d9e\u3d9f\u3da0\u3da1\u3da2\u3da3\u3da4\u3da5\u3da6\u3da7\u3da8\u3da9\u3daa\u3dab\u3dac\u3dad\u3dae\u3daf\u3db0\u3db1\u3db2\u3db3\u3db4\u3db5\u3db6\u3db7\u3db8\u3db9\u3dba\u3dbb\u3dbc\u3dbd\u3dbe\u3dbf\u3dc0\u3dc1\u3dc2\u3dc3\u3dc4\u3dc5\u3dc6\u3dc7\u3dc8\u3dc9\u3dca\u3dcb\u3dcc\u3dcd\u3dce\u3dcf\u3dd0\u3dd1\u3dd2\u3dd3\u3dd4\u3dd5\u3dd6\u3dd7\u3dd8\u3dd9\u3dda\u3ddb\u3ddc\u3ddd\u3dde\u3ddf\u3de0\u3de1\u3de2\u3de3\u3de4\u3de5\u3de6\u3de7\u3de8\u3de9\u3dea\u3deb\u3dec\u3ded\u3dee\u3def\u3df0\u3df1\u3df2\u3df3\u3df4\u3df5\u3df6\u3df7\u3df8\u3df9\u3dfa\u3dfb\u3dfc\u3dfd\u3dfe\u3dff\u3e00\u3e01\u3e02\u3e03\u3e04\u3e05\u3e06\u3e07\u3e08\u3e09\u3e0a\u3e0b\u3e0c\u3e0d\u3e0e\u3e0f\u3e10\u3e11\u3e12\u3e13\u3e14\u3e15\u3e16\u3e17\u3e18\u3e19\u3e1a\u3e1b\u3e1c\u3e1d\u3e1e\u3e1f\u3e20\u3e21\u3e22\u3e23\u3e24\u3e25\u3e26\u3e27\u3e28\u3e29\u3e2a\u3e2b\u3e2c\u3e2d\u3e2e\u3e2f\u3e30\u3e31\u3e32\u3e33\u3e34\u3e35\u3e36\u3e37\u3e38\u3e39\u3e3a\u3e3b\u3e3c\u3e3d\u3e3e\u3e3f\u3e40\u3e41\u3e42\u3e43\u3e44\u3e45\u3e46\u3e47\u3e48\u3e49\u3e4a\u3e4b\u3e4c\u3e4d\u3e4e\u3e4f\u3e50\u3e51\u3e52\u3e53\u3e54\u3e55\u3e56\u3e57\u3e58\u3e59\u3e5a\u3e5b\u3e5c\u3e5d\u3e5e\u3e5f\u3e60\u3e61\u3e62\u3e63\u3e64\u3e65\u3e66\u3e67\u3e68\u3e69\u3e6a\u3e6b\u3e6c\u3e6d\u3e6e\u3e6f\u3e70\u3e71\u3e72\u3e73\u3e74\u3e75\u3e76\u3e77\u3e78\u3e79\u3e7a\u3e7b\u3e7c\u3e7d\u3e7e\u3e7f\u3e80\u3e81\u3e82\u3e83\u3e84\u3e85\u3e86\u3e87\u3e88\u3e89\u3e8a\u3e8b\u3e8c\u3e8d\u3e8e\u3e8f\u3e90\u3e91\u3e92\u3e93\u3e94\u3e95\u3e96\u3e97\u3e98\u3e99\u3e9a\u3e9b\u3e9c\u3e9d\u3e9e\u3e9f\u3ea0\u3ea1\u3ea2\u3ea3\u3ea4\u3ea5\u3ea6\u3ea7\u3ea8\u3ea9\u3eaa\u3eab\u3eac\u3ead\u3eae\u3eaf\u3eb0\u3eb1\u3eb2\u3eb3\u3eb4\u3eb5\u3eb6\u3eb7\u3eb8\u3eb9\u3eba\u3ebb\u3ebc\u3ebd\u3ebe\u3ebf\u3ec0\u3ec1\u3ec2\u3ec3\u3ec4\u3ec5\u3ec6\u3ec7\u3ec8\u3ec9\u3eca\u3ecb\u3ecc\u3ecd\u3ece\u3ecf\u3ed0\u3ed1\u3ed2\u3ed3\u3ed4\u3ed5\u3ed6\u3ed7\u3ed8\u3ed9\u3eda\u3edb\u3edc\u3edd\u3ede\u3edf\u3ee0\u3ee1\u3ee2\u3ee3\u3ee4\u3ee5\u3ee6\u3ee7\u3ee8\u3ee9\u3eea\u3eeb\u3eec\u3eed\u3eee\u3eef\u3ef0\u3ef1\u3ef2\u3ef3\u3ef4\u3ef5\u3ef6\u3ef7\u3ef8\u3ef9\u3efa\u3efb\u3efc\u3efd\u3efe\u3eff\u3f00\u3f01\u3f02\u3f03\u3f04\u3f05\u3f06\u3f07\u3f08\u3f09\u3f0a\u3f0b\u3f0c\u3f0d\u3f0e\u3f0f\u3f10\u3f11\u3f12\u3f13\u3f14\u3f15\u3f16\u3f17\u3f18\u3f19\u3f1a\u3f1b\u3f1c\u3f1d\u3f1e\u3f1f\u3f20\u3f21\u3f22\u3f23\u3f24\u3f25\u3f26\u3f27\u3f28\u3f29\u3f2a\u3f2b\u3f2c\u3f2d\u3f2e\u3f2f\u3f30\u3f31\u3f32\u3f33\u3f34\u3f35\u3f36\u3f37\u3f38\u3f39\u3f3a\u3f3b\u3f3c\u3f3d\u3f3e\u3f3f\u3f40\u3f41\u3f42\u3f43\u3f44\u3f45\u3f46\u3f47\u3f48\u3f49\u3f4a\u3f4b\u3f4c\u3f4d\u3f4e\u3f4f\u3f50\u3f51\u3f52\u3f53\u3f54\u3f55\u3f56\u3f57\u3f58\u3f59\u3f5a\u3f5b\u3f5c\u3f5d\u3f5e\u3f5f\u3f60\u3f61\u3f62\u3f63\u3f64\u3f65\u3f66\u3f67\u3f68\u3f69\u3f6a\u3f6b\u3f6c\u3f6d\u3f6e\u3f6f\u3f70\u3f71\u3f72\u3f73\u3f74\u3f75\u3f76\u3f77\u3f78\u3f79\u3f7a\u3f7b\u3f7c\u3f7d\u3f7e\u3f7f\u3f80\u3f81\u3f82\u3f83\u3f84\u3f85\u3f86\u3f87\u3f88\u3f89\u3f8a\u3f8b\u3f8c\u3f8d\u3f8e\u3f8f\u3f90\u3f91\u3f92\u3f93\u3f94\u3f95\u3f96\u3f97\u3f98\u3f99\u3f9a\u3f9b\u3f9c\u3f9d\u3f9e\u3f9f\u3fa0\u3fa1\u3fa2\u3fa3\u3fa4\u3fa5\u3fa6\u3fa7\u3fa8\u3fa9\u3faa\u3fab\u3fac\u3fad\u3fae\u3faf\u3fb0\u3fb1\u3fb2\u3fb3\u3fb4\u3fb5\u3fb6\u3fb7\u3fb8\u3fb9\u3fba\u3fbb\u3fbc\u3fbd\u3fbe\u3fbf\u3fc0\u3fc1\u3fc2\u3fc3\u3fc4\u3fc5\u3fc6\u3fc7\u3fc8\u3fc9\u3fca\u3fcb\u3fcc\u3fcd\u3fce\u3fcf\u3fd0\u3fd1\u3fd2\u3fd3\u3fd4\u3fd5\u3fd6\u3fd7\u3fd8\u3fd9\u3fda\u3fdb\u3fdc\u3fdd\u3fde\u3fdf\u3fe0\u3fe1\u3fe2\u3fe3\u3fe4\u3fe5\u3fe6\u3fe7\u3fe8\u3fe9\u3fea\u3feb\u3fec\u3fed\u3fee\u3fef\u3ff0\u3ff1\u3ff2\u3ff3\u3ff4\u3ff5\u3ff6\u3ff7\u3ff8\u3ff9\u3ffa\u3ffb\u3ffc\u3ffd\u3ffe\u3fff\u4000\u4001\u4002\u4003\u4004\u4005\u4006\u4007\u4008\u4009\u400a\u400b\u400c\u400d\u400e\u400f\u4010\u4011\u4012\u4013\u4014\u4015\u4016\u4017\u4018\u4019\u401a\u401b\u401c\u401d\u401e\u401f\u4020\u4021\u4022\u4023\u4024\u4025\u4026\u4027\u4028\u4029\u402a\u402b\u402c\u402d\u402e\u402f\u4030\u4031\u4032\u4033\u4034\u4035\u4036\u4037\u4038\u4039\u403a\u403b\u403c\u403d\u403e\u403f\u4040\u4041\u4042\u4043\u4044\u4045\u4046\u4047\u4048\u4049\u404a\u404b\u404c\u404d\u404e\u404f\u4050\u4051\u4052\u4053\u4054\u4055\u4056\u4057\u4058\u4059\u405a\u405b\u405c\u405d\u405e\u405f\u4060\u4061\u4062\u4063\u4064\u4065\u4066\u4067\u4068\u4069\u406a\u406b\u406c\u406d\u406e\u406f\u4070\u4071\u4072\u4073\u4074\u4075\u4076\u4077\u4078\u4079\u407a\u407b\u407c\u407d\u407e\u407f\u4080\u4081\u4082\u4083\u4084\u4085\u4086\u4087\u4088\u4089\u408a\u408b\u408c\u408d\u408e\u408f\u4090\u4091\u4092\u4093\u4094\u4095\u4096\u4097\u4098\u4099\u409a\u409b\u409c\u409d\u409e\u409f\u40a0\u40a1\u40a2\u40a3\u40a4\u40a5\u40a6\u40a7\u40a8\u40a9\u40aa\u40ab\u40ac\u40ad\u40ae\u40af\u40b0\u40b1\u40b2\u40b3\u40b4\u40b5\u40b6\u40b7\u40b8\u40b9\u40ba\u40bb\u40bc\u40bd\u40be\u40bf\u40c0\u40c1\u40c2\u40c3\u40c4\u40c5\u40c6\u40c7\u40c8\u40c9\u40ca\u40cb\u40cc\u40cd\u40ce\u40cf\u40d0\u40d1\u40d2\u40d3\u40d4\u40d5\u40d6\u40d7\u40d8\u40d9\u40da\u40db\u40dc\u40dd\u40de\u40df\u40e0\u40e1\u40e2\u40e3\u40e4\u40e5\u40e6\u40e7\u40e8\u40e9\u40ea\u40eb\u40ec\u40ed\u40ee\u40ef\u40f0\u40f1\u40f2\u40f3\u40f4\u40f5\u40f6\u40f7\u40f8\u40f9\u40fa\u40fb\u40fc\u40fd\u40fe\u40ff\u4100\u4101\u4102\u4103\u4104\u4105\u4106\u4107\u4108\u4109\u410a\u410b\u410c\u410d\u410e\u410f\u4110\u4111\u4112\u4113\u4114\u4115\u4116\u4117\u4118\u4119\u411a\u411b\u411c\u411d\u411e\u411f\u4120\u4121\u4122\u4123\u4124\u4125\u4126\u4127\u4128\u4129\u412a\u412b\u412c\u412d\u412e\u412f\u4130\u4131\u4132\u4133\u4134\u4135\u4136\u4137\u4138\u4139\u413a\u413b\u413c\u413d\u413e\u413f\u4140\u4141\u4142\u4143\u4144\u4145\u4146\u4147\u4148\u4149\u414a\u414b\u414c\u414d\u414e\u414f\u4150\u4151\u4152\u4153\u4154\u4155\u4156\u4157\u4158\u4159\u415a\u415b\u415c\u415d\u415e\u415f\u4160\u4161\u4162\u4163\u4164\u4165\u4166\u4167\u4168\u4169\u416a\u416b\u416c\u416d\u416e\u416f\u4170\u4171\u4172\u4173\u4174\u4175\u4176\u4177\u4178\u4179\u417a\u417b\u417c\u417d\u417e\u417f\u4180\u4181\u4182\u4183\u4184\u4185\u4186\u4187\u4188\u4189\u418a\u418b\u418c\u418d\u418e\u418f\u4190\u4191\u4192\u4193\u4194\u4195\u4196\u4197\u4198\u4199\u419a\u419b\u419c\u419d\u419e\u419f\u41a0\u41a1\u41a2\u41a3\u41a4\u41a5\u41a6\u41a7\u41a8\u41a9\u41aa\u41ab\u41ac\u41ad\u41ae\u41af\u41b0\u41b1\u41b2\u41b3\u41b4\u41b5\u41b6\u41b7\u41b8\u41b9\u41ba\u41bb\u41bc\u41bd\u41be\u41bf\u41c0\u41c1\u41c2\u41c3\u41c4\u41c5\u41c6\u41c7\u41c8\u41c9\u41ca\u41cb\u41cc\u41cd\u41ce\u41cf\u41d0\u41d1\u41d2\u41d3\u41d4\u41d5\u41d6\u41d7\u41d8\u41d9\u41da\u41db\u41dc\u41dd\u41de\u41df\u41e0\u41e1\u41e2\u41e3\u41e4\u41e5\u41e6\u41e7\u41e8\u41e9\u41ea\u41eb\u41ec\u41ed\u41ee\u41ef\u41f0\u41f1\u41f2\u41f3\u41f4\u41f5\u41f6\u41f7\u41f8\u41f9\u41fa\u41fb\u41fc\u41fd\u41fe\u41ff\u4200\u4201\u4202\u4203\u4204\u4205\u4206\u4207\u4208\u4209\u420a\u420b\u420c\u420d\u420e\u420f\u4210\u4211\u4212\u4213\u4214\u4215\u4216\u4217\u4218\u4219\u421a\u421b\u421c\u421d\u421e\u421f\u4220\u4221\u4222\u4223\u4224\u4225\u4226\u4227\u4228\u4229\u422a\u422b\u422c\u422d\u422e\u422f\u4230\u4231\u4232\u4233\u4234\u4235\u4236\u4237\u4238\u4239\u423a\u423b\u423c\u423d\u423e\u423f\u4240\u4241\u4242\u4243\u4244\u4245\u4246\u4247\u4248\u4249\u424a\u424b\u424c\u424d\u424e\u424f\u4250\u4251\u4252\u4253\u4254\u4255\u4256\u4257\u4258\u4259\u425a\u425b\u425c\u425d\u425e\u425f\u4260\u4261\u4262\u4263\u4264\u4265\u4266\u4267\u4268\u4269\u426a\u426b\u426c\u426d\u426e\u426f\u4270\u4271\u4272\u4273\u4274\u4275\u4276\u4277\u4278\u4279\u427a\u427b\u427c\u427d\u427e\u427f\u4280\u4281\u4282\u4283\u4284\u4285\u4286\u4287\u4288\u4289\u428a\u428b\u428c\u428d\u428e\u428f\u4290\u4291\u4292\u4293\u4294\u4295\u4296\u4297\u4298\u4299\u429a\u429b\u429c\u429d\u429e\u429f\u42a0\u42a1\u42a2\u42a3\u42a4\u42a5\u42a6\u42a7\u42a8\u42a9\u42aa\u42ab\u42ac\u42ad\u42ae\u42af\u42b0\u42b1\u42b2\u42b3\u42b4\u42b5\u42b6\u42b7\u42b8\u42b9\u42ba\u42bb\u42bc\u42bd\u42be\u42bf\u42c0\u42c1\u42c2\u42c3\u42c4\u42c5\u42c6\u42c7\u42c8\u42c9\u42ca\u42cb\u42cc\u42cd\u42ce\u42cf\u42d0\u42d1\u42d2\u42d3\u42d4\u42d5\u42d6\u42d7\u42d8\u42d9\u42da\u42db\u42dc\u42dd\u42de\u42df\u42e0\u42e1\u42e2\u42e3\u42e4\u42e5\u42e6\u42e7\u42e8\u42e9\u42ea\u42eb\u42ec\u42ed\u42ee\u42ef\u42f0\u42f1\u42f2\u42f3\u42f4\u42f5\u42f6\u42f7\u42f8\u42f9\u42fa\u42fb\u42fc\u42fd\u42fe\u42ff\u4300\u4301\u4302\u4303\u4304\u4305\u4306\u4307\u4308\u4309\u430a\u430b\u430c\u430d\u430e\u430f\u4310\u4311\u4312\u4313\u4314\u4315\u4316\u4317\u4318\u4319\u431a\u431b\u431c\u431d\u431e\u431f\u4320\u4321\u4322\u4323\u4324\u4325\u4326\u4327\u4328\u4329\u432a\u432b\u432c\u432d\u432e\u432f\u4330\u4331\u4332\u4333\u4334\u4335\u4336\u4337\u4338\u4339\u433a\u433b\u433c\u433d\u433e\u433f\u4340\u4341\u4342\u4343\u4344\u4345\u4346\u4347\u4348\u4349\u434a\u434b\u434c\u434d\u434e\u434f\u4350\u4351\u4352\u4353\u4354\u4355\u4356\u4357\u4358\u4359\u435a\u435b\u435c\u435d\u435e\u435f\u4360\u4361\u4362\u4363\u4364\u4365\u4366\u4367\u4368\u4369\u436a\u436b\u436c\u436d\u436e\u436f\u4370\u4371\u4372\u4373\u4374\u4375\u4376\u4377\u4378\u4379\u437a\u437b\u437c\u437d\u437e\u437f\u4380\u4381\u4382\u4383\u4384\u4385\u4386\u4387\u4388\u4389\u438a\u438b\u438c\u438d\u438e\u438f\u4390\u4391\u4392\u4393\u4394\u4395\u4396\u4397\u4398\u4399\u439a\u439b\u439c\u439d\u439e\u439f\u43a0\u43a1\u43a2\u43a3\u43a4\u43a5\u43a6\u43a7\u43a8\u43a9\u43aa\u43ab\u43ac\u43ad\u43ae\u43af\u43b0\u43b1\u43b2\u43b3\u43b4\u43b5\u43b6\u43b7\u43b8\u43b9\u43ba\u43bb\u43bc\u43bd\u43be\u43bf\u43c0\u43c1\u43c2\u43c3\u43c4\u43c5\u43c6\u43c7\u43c8\u43c9\u43ca\u43cb\u43cc\u43cd\u43ce\u43cf\u43d0\u43d1\u43d2\u43d3\u43d4\u43d5\u43d6\u43d7\u43d8\u43d9\u43da\u43db\u43dc\u43dd\u43de\u43df\u43e0\u43e1\u43e2\u43e3\u43e4\u43e5\u43e6\u43e7\u43e8\u43e9\u43ea\u43eb\u43ec\u43ed\u43ee\u43ef\u43f0\u43f1\u43f2\u43f3\u43f4\u43f5\u43f6\u43f7\u43f8\u43f9\u43fa\u43fb\u43fc\u43fd\u43fe\u43ff\u4400\u4401\u4402\u4403\u4404\u4405\u4406\u4407\u4408\u4409\u440a\u440b\u440c\u440d\u440e\u440f\u4410\u4411\u4412\u4413\u4414\u4415\u4416\u4417\u4418\u4419\u441a\u441b\u441c\u441d\u441e\u441f\u4420\u4421\u4422\u4423\u4424\u4425\u4426\u4427\u4428\u4429\u442a\u442b\u442c\u442d\u442e\u442f\u4430\u4431\u4432\u4433\u4434\u4435\u4436\u4437\u4438\u4439\u443a\u443b\u443c\u443d\u443e\u443f\u4440\u4441\u4442\u4443\u4444\u4445\u4446\u4447\u4448\u4449\u444a\u444b\u444c\u444d\u444e\u444f\u4450\u4451\u4452\u4453\u4454\u4455\u4456\u4457\u4458\u4459\u445a\u445b\u445c\u445d\u445e\u445f\u4460\u4461\u4462\u4463\u4464\u4465\u4466\u4467\u4468\u4469\u446a\u446b\u446c\u446d\u446e\u446f\u4470\u4471\u4472\u4473\u4474\u4475\u4476\u4477\u4478\u4479\u447a\u447b\u447c\u447d\u447e\u447f\u4480\u4481\u4482\u4483\u4484\u4485\u4486\u4487\u4488\u4489\u448a\u448b\u448c\u448d\u448e\u448f\u4490\u4491\u4492\u4493\u4494\u4495\u4496\u4497\u4498\u4499\u449a\u449b\u449c\u449d\u449e\u449f\u44a0\u44a1\u44a2\u44a3\u44a4\u44a5\u44a6\u44a7\u44a8\u44a9\u44aa\u44ab\u44ac\u44ad\u44ae\u44af\u44b0\u44b1\u44b2\u44b3\u44b4\u44b5\u44b6\u44b7\u44b8\u44b9\u44ba\u44bb\u44bc\u44bd\u44be\u44bf\u44c0\u44c1\u44c2\u44c3\u44c4\u44c5\u44c6\u44c7\u44c8\u44c9\u44ca\u44cb\u44cc\u44cd\u44ce\u44cf\u44d0\u44d1\u44d2\u44d3\u44d4\u44d5\u44d6\u44d7\u44d8\u44d9\u44da\u44db\u44dc\u44dd\u44de\u44df\u44e0\u44e1\u44e2\u44e3\u44e4\u44e5\u44e6\u44e7\u44e8\u44e9\u44ea\u44eb\u44ec\u44ed\u44ee\u44ef\u44f0\u44f1\u44f2\u44f3\u44f4\u44f5\u44f6\u44f7\u44f8\u44f9\u44fa\u44fb\u44fc\u44fd\u44fe\u44ff\u4500\u4501\u4502\u4503\u4504\u4505\u4506\u4507\u4508\u4509\u450a\u450b\u450c\u450d\u450e\u450f\u4510\u4511\u4512\u4513\u4514\u4515\u4516\u4517\u4518\u4519\u451a\u451b\u451c\u451d\u451e\u451f\u4520\u4521\u4522\u4523\u4524\u4525\u4526\u4527\u4528\u4529\u452a\u452b\u452c\u452d\u452e\u452f\u4530\u4531\u4532\u4533\u4534\u4535\u4536\u4537\u4538\u4539\u453a\u453b\u453c\u453d\u453e\u453f\u4540\u4541\u4542\u4543\u4544\u4545\u4546\u4547\u4548\u4549\u454a\u454b\u454c\u454d\u454e\u454f\u4550\u4551\u4552\u4553\u4554\u4555\u4556\u4557\u4558\u4559\u455a\u455b\u455c\u455d\u455e\u455f\u4560\u4561\u4562\u4563\u4564\u4565\u4566\u4567\u4568\u4569\u456a\u456b\u456c\u456d\u456e\u456f\u4570\u4571\u4572\u4573\u4574\u4575\u4576\u4577\u4578\u4579\u457a\u457b\u457c\u457d\u457e\u457f\u4580\u4581\u4582\u4583\u4584\u4585\u4586\u4587\u4588\u4589\u458a\u458b\u458c\u458d\u458e\u458f\u4590\u4591\u4592\u4593\u4594\u4595\u4596\u4597\u4598\u4599\u459a\u459b\u459c\u459d\u459e\u459f\u45a0\u45a1\u45a2\u45a3\u45a4\u45a5\u45a6\u45a7\u45a8\u45a9\u45aa\u45ab\u45ac\u45ad\u45ae\u45af\u45b0\u45b1\u45b2\u45b3\u45b4\u45b5\u45b6\u45b7\u45b8\u45b9\u45ba\u45bb\u45bc\u45bd\u45be\u45bf\u45c0\u45c1\u45c2\u45c3\u45c4\u45c5\u45c6\u45c7\u45c8\u45c9\u45ca\u45cb\u45cc\u45cd\u45ce\u45cf\u45d0\u45d1\u45d2\u45d3\u45d4\u45d5\u45d6\u45d7\u45d8\u45d9\u45da\u45db\u45dc\u45dd\u45de\u45df\u45e0\u45e1\u45e2\u45e3\u45e4\u45e5\u45e6\u45e7\u45e8\u45e9\u45ea\u45eb\u45ec\u45ed\u45ee\u45ef\u45f0\u45f1\u45f2\u45f3\u45f4\u45f5\u45f6\u45f7\u45f8\u45f9\u45fa\u45fb\u45fc\u45fd\u45fe\u45ff\u4600\u4601\u4602\u4603\u4604\u4605\u4606\u4607\u4608\u4609\u460a\u460b\u460c\u460d\u460e\u460f\u4610\u4611\u4612\u4613\u4614\u4615\u4616\u4617\u4618\u4619\u461a\u461b\u461c\u461d\u461e\u461f\u4620\u4621\u4622\u4623\u4624\u4625\u4626\u4627\u4628\u4629\u462a\u462b\u462c\u462d\u462e\u462f\u4630\u4631\u4632\u4633\u4634\u4635\u4636\u4637\u4638\u4639\u463a\u463b\u463c\u463d\u463e\u463f\u4640\u4641\u4642\u4643\u4644\u4645\u4646\u4647\u4648\u4649\u464a\u464b\u464c\u464d\u464e\u464f\u4650\u4651\u4652\u4653\u4654\u4655\u4656\u4657\u4658\u4659\u465a\u465b\u465c\u465d\u465e\u465f\u4660\u4661\u4662\u4663\u4664\u4665\u4666\u4667\u4668\u4669\u466a\u466b\u466c\u466d\u466e\u466f\u4670\u4671\u4672\u4673\u4674\u4675\u4676\u4677\u4678\u4679\u467a\u467b\u467c\u467d\u467e\u467f\u4680\u4681\u4682\u4683\u4684\u4685\u4686\u4687\u4688\u4689\u468a\u468b\u468c\u468d\u468e\u468f\u4690\u4691\u4692\u4693\u4694\u4695\u4696\u4697\u4698\u4699\u469a\u469b\u469c\u469d\u469e\u469f\u46a0\u46a1\u46a2\u46a3\u46a4\u46a5\u46a6\u46a7\u46a8\u46a9\u46aa\u46ab\u46ac\u46ad\u46ae\u46af\u46b0\u46b1\u46b2\u46b3\u46b4\u46b5\u46b6\u46b7\u46b8\u46b9\u46ba\u46bb\u46bc\u46bd\u46be\u46bf\u46c0\u46c1\u46c2\u46c3\u46c4\u46c5\u46c6\u46c7\u46c8\u46c9\u46ca\u46cb\u46cc\u46cd\u46ce\u46cf\u46d0\u46d1\u46d2\u46d3\u46d4\u46d5\u46d6\u46d7\u46d8\u46d9\u46da\u46db\u46dc\u46dd\u46de\u46df\u46e0\u46e1\u46e2\u46e3\u46e4\u46e5\u46e6\u46e7\u46e8\u46e9\u46ea\u46eb\u46ec\u46ed\u46ee\u46ef\u46f0\u46f1\u46f2\u46f3\u46f4\u46f5\u46f6\u46f7\u46f8\u46f9\u46fa\u46fb\u46fc\u46fd\u46fe\u46ff\u4700\u4701\u4702\u4703\u4704\u4705\u4706\u4707\u4708\u4709\u470a\u470b\u470c\u470d\u470e\u470f\u4710\u4711\u4712\u4713\u4714\u4715\u4716\u4717\u4718\u4719\u471a\u471b\u471c\u471d\u471e\u471f\u4720\u4721\u4722\u4723\u4724\u4725\u4726\u4727\u4728\u4729\u472a\u472b\u472c\u472d\u472e\u472f\u4730\u4731\u4732\u4733\u4734\u4735\u4736\u4737\u4738\u4739\u473a\u473b\u473c\u473d\u473e\u473f\u4740\u4741\u4742\u4743\u4744\u4745\u4746\u4747\u4748\u4749\u474a\u474b\u474c\u474d\u474e\u474f\u4750\u4751\u4752\u4753\u4754\u4755\u4756\u4757\u4758\u4759\u475a\u475b\u475c\u475d\u475e\u475f\u4760\u4761\u4762\u4763\u4764\u4765\u4766\u4767\u4768\u4769\u476a\u476b\u476c\u476d\u476e\u476f\u4770\u4771\u4772\u4773\u4774\u4775\u4776\u4777\u4778\u4779\u477a\u477b\u477c\u477d\u477e\u477f\u4780\u4781\u4782\u4783\u4784\u4785\u4786\u4787\u4788\u4789\u478a\u478b\u478c\u478d\u478e\u478f\u4790\u4791\u4792\u4793\u4794\u4795\u4796\u4797\u4798\u4799\u479a\u479b\u479c\u479d\u479e\u479f\u47a0\u47a1\u47a2\u47a3\u47a4\u47a5\u47a6\u47a7\u47a8\u47a9\u47aa\u47ab\u47ac\u47ad\u47ae\u47af\u47b0\u47b1\u47b2\u47b3\u47b4\u47b5\u47b6\u47b7\u47b8\u47b9\u47ba\u47bb\u47bc\u47bd\u47be\u47bf\u47c0\u47c1\u47c2\u47c3\u47c4\u47c5\u47c6\u47c7\u47c8\u47c9\u47ca\u47cb\u47cc\u47cd\u47ce\u47cf\u47d0\u47d1\u47d2\u47d3\u47d4\u47d5\u47d6\u47d7\u47d8\u47d9\u47da\u47db\u47dc\u47dd\u47de\u47df\u47e0\u47e1\u47e2\u47e3\u47e4\u47e5\u47e6\u47e7\u47e8\u47e9\u47ea\u47eb\u47ec\u47ed\u47ee\u47ef\u47f0\u47f1\u47f2\u47f3\u47f4\u47f5\u47f6\u47f7\u47f8\u47f9\u47fa\u47fb\u47fc\u47fd\u47fe\u47ff\u4800\u4801\u4802\u4803\u4804\u4805\u4806\u4807\u4808\u4809\u480a\u480b\u480c\u480d\u480e\u480f\u4810\u4811\u4812\u4813\u4814\u4815\u4816\u4817\u4818\u4819\u481a\u481b\u481c\u481d\u481e\u481f\u4820\u4821\u4822\u4823\u4824\u4825\u4826\u4827\u4828\u4829\u482a\u482b\u482c\u482d\u482e\u482f\u4830\u4831\u4832\u4833\u4834\u4835\u4836\u4837\u4838\u4839\u483a\u483b\u483c\u483d\u483e\u483f\u4840\u4841\u4842\u4843\u4844\u4845\u4846\u4847\u4848\u4849\u484a\u484b\u484c\u484d\u484e\u484f\u4850\u4851\u4852\u4853\u4854\u4855\u4856\u4857\u4858\u4859\u485a\u485b\u485c\u485d\u485e\u485f\u4860\u4861\u4862\u4863\u4864\u4865\u4866\u4867\u4868\u4869\u486a\u486b\u486c\u486d\u486e\u486f\u4870\u4871\u4872\u4873\u4874\u4875\u4876\u4877\u4878\u4879\u487a\u487b\u487c\u487d\u487e\u487f\u4880\u4881\u4882\u4883\u4884\u4885\u4886\u4887\u4888\u4889\u488a\u488b\u488c\u488d\u488e\u488f\u4890\u4891\u4892\u4893\u4894\u4895\u4896\u4897\u4898\u4899\u489a\u489b\u489c\u489d\u489e\u489f\u48a0\u48a1\u48a2\u48a3\u48a4\u48a5\u48a6\u48a7\u48a8\u48a9\u48aa\u48ab\u48ac\u48ad\u48ae\u48af\u48b0\u48b1\u48b2\u48b3\u48b4\u48b5\u48b6\u48b7\u48b8\u48b9\u48ba\u48bb\u48bc\u48bd\u48be\u48bf\u48c0\u48c1\u48c2\u48c3\u48c4\u48c5\u48c6\u48c7\u48c8\u48c9\u48ca\u48cb\u48cc\u48cd\u48ce\u48cf\u48d0\u48d1\u48d2\u48d3\u48d4\u48d5\u48d6\u48d7\u48d8\u48d9\u48da\u48db\u48dc\u48dd\u48de\u48df\u48e0\u48e1\u48e2\u48e3\u48e4\u48e5\u48e6\u48e7\u48e8\u48e9\u48ea\u48eb\u48ec\u48ed\u48ee\u48ef\u48f0\u48f1\u48f2\u48f3\u48f4\u48f5\u48f6\u48f7\u48f8\u48f9\u48fa\u48fb\u48fc\u48fd\u48fe\u48ff\u4900\u4901\u4902\u4903\u4904\u4905\u4906\u4907\u4908\u4909\u490a\u490b\u490c\u490d\u490e\u490f\u4910\u4911\u4912\u4913\u4914\u4915\u4916\u4917\u4918\u4919\u491a\u491b\u491c\u491d\u491e\u491f\u4920\u4921\u4922\u4923\u4924\u4925\u4926\u4927\u4928\u4929\u492a\u492b\u492c\u492d\u492e\u492f\u4930\u4931\u4932\u4933\u4934\u4935\u4936\u4937\u4938\u4939\u493a\u493b\u493c\u493d\u493e\u493f\u4940\u4941\u4942\u4943\u4944\u4945\u4946\u4947\u4948\u4949\u494a\u494b\u494c\u494d\u494e\u494f\u4950\u4951\u4952\u4953\u4954\u4955\u4956\u4957\u4958\u4959\u495a\u495b\u495c\u495d\u495e\u495f\u4960\u4961\u4962\u4963\u4964\u4965\u4966\u4967\u4968\u4969\u496a\u496b\u496c\u496d\u496e\u496f\u4970\u4971\u4972\u4973\u4974\u4975\u4976\u4977\u4978\u4979\u497a\u497b\u497c\u497d\u497e\u497f\u4980\u4981\u4982\u4983\u4984\u4985\u4986\u4987\u4988\u4989\u498a\u498b\u498c\u498d\u498e\u498f\u4990\u4991\u4992\u4993\u4994\u4995\u4996\u4997\u4998\u4999\u499a\u499b\u499c\u499d\u499e\u499f\u49a0\u49a1\u49a2\u49a3\u49a4\u49a5\u49a6\u49a7\u49a8\u49a9\u49aa\u49ab\u49ac\u49ad\u49ae\u49af\u49b0\u49b1\u49b2\u49b3\u49b4\u49b5\u49b6\u49b7\u49b8\u49b9\u49ba\u49bb\u49bc\u49bd\u49be\u49bf\u49c0\u49c1\u49c2\u49c3\u49c4\u49c5\u49c6\u49c7\u49c8\u49c9\u49ca\u49cb\u49cc\u49cd\u49ce\u49cf\u49d0\u49d1\u49d2\u49d3\u49d4\u49d5\u49d6\u49d7\u49d8\u49d9\u49da\u49db\u49dc\u49dd\u49de\u49df\u49e0\u49e1\u49e2\u49e3\u49e4\u49e5\u49e6\u49e7\u49e8\u49e9\u49ea\u49eb\u49ec\u49ed\u49ee\u49ef\u49f0\u49f1\u49f2\u49f3\u49f4\u49f5\u49f6\u49f7\u49f8\u49f9\u49fa\u49fb\u49fc\u49fd\u49fe\u49ff\u4a00\u4a01\u4a02\u4a03\u4a04\u4a05\u4a06\u4a07\u4a08\u4a09\u4a0a\u4a0b\u4a0c\u4a0d\u4a0e\u4a0f\u4a10\u4a11\u4a12\u4a13\u4a14\u4a15\u4a16\u4a17\u4a18\u4a19\u4a1a\u4a1b\u4a1c\u4a1d\u4a1e\u4a1f\u4a20\u4a21\u4a22\u4a23\u4a24\u4a25\u4a26\u4a27\u4a28\u4a29\u4a2a\u4a2b\u4a2c\u4a2d\u4a2e\u4a2f\u4a30\u4a31\u4a32\u4a33\u4a34\u4a35\u4a36\u4a37\u4a38\u4a39\u4a3a\u4a3b\u4a3c\u4a3d\u4a3e\u4a3f\u4a40\u4a41\u4a42\u4a43\u4a44\u4a45\u4a46\u4a47\u4a48\u4a49\u4a4a\u4a4b\u4a4c\u4a4d\u4a4e\u4a4f\u4a50\u4a51\u4a52\u4a53\u4a54\u4a55\u4a56\u4a57\u4a58\u4a59\u4a5a\u4a5b\u4a5c\u4a5d\u4a5e\u4a5f\u4a60\u4a61\u4a62\u4a63\u4a64\u4a65\u4a66\u4a67\u4a68\u4a69\u4a6a\u4a6b\u4a6c\u4a6d\u4a6e\u4a6f\u4a70\u4a71\u4a72\u4a73\u4a74\u4a75\u4a76\u4a77\u4a78\u4a79\u4a7a\u4a7b\u4a7c\u4a7d\u4a7e\u4a7f\u4a80\u4a81\u4a82\u4a83\u4a84\u4a85\u4a86\u4a87\u4a88\u4a89\u4a8a\u4a8b\u4a8c\u4a8d\u4a8e\u4a8f\u4a90\u4a91\u4a92\u4a93\u4a94\u4a95\u4a96\u4a97\u4a98\u4a99\u4a9a\u4a9b\u4a9c\u4a9d\u4a9e\u4a9f\u4aa0\u4aa1\u4aa2\u4aa3\u4aa4\u4aa5\u4aa6\u4aa7\u4aa8\u4aa9\u4aaa\u4aab\u4aac\u4aad\u4aae\u4aaf\u4ab0\u4ab1\u4ab2\u4ab3\u4ab4\u4ab5\u4ab6\u4ab7\u4ab8\u4ab9\u4aba\u4abb\u4abc\u4abd\u4abe\u4abf\u4ac0\u4ac1\u4ac2\u4ac3\u4ac4\u4ac5\u4ac6\u4ac7\u4ac8\u4ac9\u4aca\u4acb\u4acc\u4acd\u4ace\u4acf\u4ad0\u4ad1\u4ad2\u4ad3\u4ad4\u4ad5\u4ad6\u4ad7\u4ad8\u4ad9\u4ada\u4adb\u4adc\u4add\u4ade\u4adf\u4ae0\u4ae1\u4ae2\u4ae3\u4ae4\u4ae5\u4ae6\u4ae7\u4ae8\u4ae9\u4aea\u4aeb\u4aec\u4aed\u4aee\u4aef\u4af0\u4af1\u4af2\u4af3\u4af4\u4af5\u4af6\u4af7\u4af8\u4af9\u4afa\u4afb\u4afc\u4afd\u4afe\u4aff\u4b00\u4b01\u4b02\u4b03\u4b04\u4b05\u4b06\u4b07\u4b08\u4b09\u4b0a\u4b0b\u4b0c\u4b0d\u4b0e\u4b0f\u4b10\u4b11\u4b12\u4b13\u4b14\u4b15\u4b16\u4b17\u4b18\u4b19\u4b1a\u4b1b\u4b1c\u4b1d\u4b1e\u4b1f\u4b20\u4b21\u4b22\u4b23\u4b24\u4b25\u4b26\u4b27\u4b28\u4b29\u4b2a\u4b2b\u4b2c\u4b2d\u4b2e\u4b2f\u4b30\u4b31\u4b32\u4b33\u4b34\u4b35\u4b36\u4b37\u4b38\u4b39\u4b3a\u4b3b\u4b3c\u4b3d\u4b3e\u4b3f\u4b40\u4b41\u4b42\u4b43\u4b44\u4b45\u4b46\u4b47\u4b48\u4b49\u4b4a\u4b4b\u4b4c\u4b4d\u4b4e\u4b4f\u4b50\u4b51\u4b52\u4b53\u4b54\u4b55\u4b56\u4b57\u4b58\u4b59\u4b5a\u4b5b\u4b5c\u4b5d\u4b5e\u4b5f\u4b60\u4b61\u4b62\u4b63\u4b64\u4b65\u4b66\u4b67\u4b68\u4b69\u4b6a\u4b6b\u4b6c\u4b6d\u4b6e\u4b6f\u4b70\u4b71\u4b72\u4b73\u4b74\u4b75\u4b76\u4b77\u4b78\u4b79\u4b7a\u4b7b\u4b7c\u4b7d\u4b7e\u4b7f\u4b80\u4b81\u4b82\u4b83\u4b84\u4b85\u4b86\u4b87\u4b88\u4b89\u4b8a\u4b8b\u4b8c\u4b8d\u4b8e\u4b8f\u4b90\u4b91\u4b92\u4b93\u4b94\u4b95\u4b96\u4b97\u4b98\u4b99\u4b9a\u4b9b\u4b9c\u4b9d\u4b9e\u4b9f\u4ba0\u4ba1\u4ba2\u4ba3\u4ba4\u4ba5\u4ba6\u4ba7\u4ba8\u4ba9\u4baa\u4bab\u4bac\u4bad\u4bae\u4baf\u4bb0\u4bb1\u4bb2\u4bb3\u4bb4\u4bb5\u4bb6\u4bb7\u4bb8\u4bb9\u4bba\u4bbb\u4bbc\u4bbd\u4bbe\u4bbf\u4bc0\u4bc1\u4bc2\u4bc3\u4bc4\u4bc5\u4bc6\u4bc7\u4bc8\u4bc9\u4bca\u4bcb\u4bcc\u4bcd\u4bce\u4bcf\u4bd0\u4bd1\u4bd2\u4bd3\u4bd4\u4bd5\u4bd6\u4bd7\u4bd8\u4bd9\u4bda\u4bdb\u4bdc\u4bdd\u4bde\u4bdf\u4be0\u4be1\u4be2\u4be3\u4be4\u4be5\u4be6\u4be7\u4be8\u4be9\u4bea\u4beb\u4bec\u4bed\u4bee\u4bef\u4bf0\u4bf1\u4bf2\u4bf3\u4bf4\u4bf5\u4bf6\u4bf7\u4bf8\u4bf9\u4bfa\u4bfb\u4bfc\u4bfd\u4bfe\u4bff\u4c00\u4c01\u4c02\u4c03\u4c04\u4c05\u4c06\u4c07\u4c08\u4c09\u4c0a\u4c0b\u4c0c\u4c0d\u4c0e\u4c0f\u4c10\u4c11\u4c12\u4c13\u4c14\u4c15\u4c16\u4c17\u4c18\u4c19\u4c1a\u4c1b\u4c1c\u4c1d\u4c1e\u4c1f\u4c20\u4c21\u4c22\u4c23\u4c24\u4c25\u4c26\u4c27\u4c28\u4c29\u4c2a\u4c2b\u4c2c\u4c2d\u4c2e\u4c2f\u4c30\u4c31\u4c32\u4c33\u4c34\u4c35\u4c36\u4c37\u4c38\u4c39\u4c3a\u4c3b\u4c3c\u4c3d\u4c3e\u4c3f\u4c40\u4c41\u4c42\u4c43\u4c44\u4c45\u4c46\u4c47\u4c48\u4c49\u4c4a\u4c4b\u4c4c\u4c4d\u4c4e\u4c4f\u4c50\u4c51\u4c52\u4c53\u4c54\u4c55\u4c56\u4c57\u4c58\u4c59\u4c5a\u4c5b\u4c5c\u4c5d\u4c5e\u4c5f\u4c60\u4c61\u4c62\u4c63\u4c64\u4c65\u4c66\u4c67\u4c68\u4c69\u4c6a\u4c6b\u4c6c\u4c6d\u4c6e\u4c6f\u4c70\u4c71\u4c72\u4c73\u4c74\u4c75\u4c76\u4c77\u4c78\u4c79\u4c7a\u4c7b\u4c7c\u4c7d\u4c7e\u4c7f\u4c80\u4c81\u4c82\u4c83\u4c84\u4c85\u4c86\u4c87\u4c88\u4c89\u4c8a\u4c8b\u4c8c\u4c8d\u4c8e\u4c8f\u4c90\u4c91\u4c92\u4c93\u4c94\u4c95\u4c96\u4c97\u4c98\u4c99\u4c9a\u4c9b\u4c9c\u4c9d\u4c9e\u4c9f\u4ca0\u4ca1\u4ca2\u4ca3\u4ca4\u4ca5\u4ca6\u4ca7\u4ca8\u4ca9\u4caa\u4cab\u4cac\u4cad\u4cae\u4caf\u4cb0\u4cb1\u4cb2\u4cb3\u4cb4\u4cb5\u4cb6\u4cb7\u4cb8\u4cb9\u4cba\u4cbb\u4cbc\u4cbd\u4cbe\u4cbf\u4cc0\u4cc1\u4cc2\u4cc3\u4cc4\u4cc5\u4cc6\u4cc7\u4cc8\u4cc9\u4cca\u4ccb\u4ccc\u4ccd\u4cce\u4ccf\u4cd0\u4cd1\u4cd2\u4cd3\u4cd4\u4cd5\u4cd6\u4cd7\u4cd8\u4cd9\u4cda\u4cdb\u4cdc\u4cdd\u4cde\u4cdf\u4ce0\u4ce1\u4ce2\u4ce3\u4ce4\u4ce5\u4ce6\u4ce7\u4ce8\u4ce9\u4cea\u4ceb\u4cec\u4ced\u4cee\u4cef\u4cf0\u4cf1\u4cf2\u4cf3\u4cf4\u4cf5\u4cf6\u4cf7\u4cf8\u4cf9\u4cfa\u4cfb\u4cfc\u4cfd\u4cfe\u4cff\u4d00\u4d01\u4d02\u4d03\u4d04\u4d05\u4d06\u4d07\u4d08\u4d09\u4d0a\u4d0b\u4d0c\u4d0d\u4d0e\u4d0f\u4d10\u4d11\u4d12\u4d13\u4d14\u4d15\u4d16\u4d17\u4d18\u4d19\u4d1a\u4d1b\u4d1c\u4d1d\u4d1e\u4d1f\u4d20\u4d21\u4d22\u4d23\u4d24\u4d25\u4d26\u4d27\u4d28\u4d29\u4d2a\u4d2b\u4d2c\u4d2d\u4d2e\u4d2f\u4d30\u4d31\u4d32\u4d33\u4d34\u4d35\u4d36\u4d37\u4d38\u4d39\u4d3a\u4d3b\u4d3c\u4d3d\u4d3e\u4d3f\u4d40\u4d41\u4d42\u4d43\u4d44\u4d45\u4d46\u4d47\u4d48\u4d49\u4d4a\u4d4b\u4d4c\u4d4d\u4d4e\u4d4f\u4d50\u4d51\u4d52\u4d53\u4d54\u4d55\u4d56\u4d57\u4d58\u4d59\u4d5a\u4d5b\u4d5c\u4d5d\u4d5e\u4d5f\u4d60\u4d61\u4d62\u4d63\u4d64\u4d65\u4d66\u4d67\u4d68\u4d69\u4d6a\u4d6b\u4d6c\u4d6d\u4d6e\u4d6f\u4d70\u4d71\u4d72\u4d73\u4d74\u4d75\u4d76\u4d77\u4d78\u4d79\u4d7a\u4d7b\u4d7c\u4d7d\u4d7e\u4d7f\u4d80\u4d81\u4d82\u4d83\u4d84\u4d85\u4d86\u4d87\u4d88\u4d89\u4d8a\u4d8b\u4d8c\u4d8d\u4d8e\u4d8f\u4d90\u4d91\u4d92\u4d93\u4d94\u4d95\u4d96\u4d97\u4d98\u4d99\u4d9a\u4d9b\u4d9c\u4d9d\u4d9e\u4d9f\u4da0\u4da1\u4da2\u4da3\u4da4\u4da5\u4da6\u4da7\u4da8\u4da9\u4daa\u4dab\u4dac\u4dad\u4dae\u4daf\u4db0\u4db1\u4db2\u4db3\u4db4\u4db5\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d\u4e0e\u4e0f\u4e10\u4e11\u4e12\u4e13\u4e14\u4e15\u4e16\u4e17\u4e18\u4e19\u4e1a\u4e1b\u4e1c\u4e1d\u4e1e\u4e1f\u4e20\u4e21\u4e22\u4e23\u4e24\u4e25\u4e26\u4e27\u4e28\u4e29\u4e2a\u4e2b\u4e2c\u4e2d\u4e2e\u4e2f\u4e30\u4e31\u4e32\u4e33\u4e34\u4e35\u4e36\u4e37\u4e38\u4e39\u4e3a\u4e3b\u4e3c\u4e3d\u4e3e\u4e3f\u4e40\u4e41\u4e42\u4e43\u4e44\u4e45\u4e46\u4e47\u4e48\u4e49\u4e4a\u4e4b\u4e4c\u4e4d\u4e4e\u4e4f\u4e50\u4e51\u4e52\u4e53\u4e54\u4e55\u4e56\u4e57\u4e58\u4e59\u4e5a\u4e5b\u4e5c\u4e5d\u4e5e\u4e5f\u4e60\u4e61\u4e62\u4e63\u4e64\u4e65\u4e66\u4e67\u4e68\u4e69\u4e6a\u4e6b\u4e6c\u4e6d\u4e6e\u4e6f\u4e70\u4e71\u4e72\u4e73\u4e74\u4e75\u4e76\u4e77\u4e78\u4e79\u4e7a\u4e7b\u4e7c\u4e7d\u4e7e\u4e7f\u4e80\u4e81\u4e82\u4e83\u4e84\u4e85\u4e86\u4e87\u4e88\u4e89\u4e8a\u4e8b\u4e8c\u4e8d\u4e8e\u4e8f\u4e90\u4e91\u4e92\u4e93\u4e94\u4e95\u4e96\u4e97\u4e98\u4e99\u4e9a\u4e9b\u4e9c\u4e9d\u4e9e\u4e9f\u4ea0\u4ea1\u4ea2\u4ea3\u4ea4\u4ea5\u4ea6\u4ea7\u4ea8\u4ea9\u4eaa\u4eab\u4eac\u4ead\u4eae\u4eaf\u4eb0\u4eb1\u4eb2\u4eb3\u4eb4\u4eb5\u4eb6\u4eb7\u4eb8\u4eb9\u4eba\u4ebb\u4ebc\u4ebd\u4ebe\u4ebf\u4ec0\u4ec1\u4ec2\u4ec3\u4ec4\u4ec5\u4ec6\u4ec7\u4ec8\u4ec9\u4eca\u4ecb\u4ecc\u4ecd\u4ece\u4ecf\u4ed0\u4ed1\u4ed2\u4ed3\u4ed4\u4ed5\u4ed6\u4ed7\u4ed8\u4ed9\u4eda\u4edb\u4edc\u4edd\u4ede\u4edf\u4ee0\u4ee1\u4ee2\u4ee3\u4ee4\u4ee5\u4ee6\u4ee7\u4ee8\u4ee9\u4eea\u4eeb\u4eec\u4eed\u4eee\u4eef\u4ef0\u4ef1\u4ef2\u4ef3\u4ef4\u4ef5\u4ef6\u4ef7\u4ef8\u4ef9\u4efa\u4efb\u4efc\u4efd\u4efe\u4eff\u4f00\u4f01\u4f02\u4f03\u4f04\u4f05\u4f06\u4f07\u4f08\u4f09\u4f0a\u4f0b\u4f0c\u4f0d\u4f0e\u4f0f\u4f10\u4f11\u4f12\u4f13\u4f14\u4f15\u4f16\u4f17\u4f18\u4f19\u4f1a\u4f1b\u4f1c\u4f1d\u4f1e\u4f1f\u4f20\u4f21\u4f22\u4f23\u4f24\u4f25\u4f26\u4f27\u4f28\u4f29\u4f2a\u4f2b\u4f2c\u4f2d\u4f2e\u4f2f\u4f30\u4f31\u4f32\u4f33\u4f34\u4f35\u4f36\u4f37\u4f38\u4f39\u4f3a\u4f3b\u4f3c\u4f3d\u4f3e\u4f3f\u4f40\u4f41\u4f42\u4f43\u4f44\u4f45\u4f46\u4f47\u4f48\u4f49\u4f4a\u4f4b\u4f4c\u4f4d\u4f4e\u4f4f\u4f50\u4f51\u4f52\u4f53\u4f54\u4f55\u4f56\u4f57\u4f58\u4f59\u4f5a\u4f5b\u4f5c\u4f5d\u4f5e\u4f5f\u4f60\u4f61\u4f62\u4f63\u4f64\u4f65\u4f66\u4f67\u4f68\u4f69\u4f6a\u4f6b\u4f6c\u4f6d\u4f6e\u4f6f\u4f70\u4f71\u4f72\u4f73\u4f74\u4f75\u4f76\u4f77\u4f78\u4f79\u4f7a\u4f7b\u4f7c\u4f7d\u4f7e\u4f7f\u4f80\u4f81\u4f82\u4f83\u4f84\u4f85\u4f86\u4f87\u4f88\u4f89\u4f8a\u4f8b\u4f8c\u4f8d\u4f8e\u4f8f\u4f90\u4f91\u4f92\u4f93\u4f94\u4f95\u4f96\u4f97\u4f98\u4f99\u4f9a\u4f9b\u4f9c\u4f9d\u4f9e\u4f9f\u4fa0\u4fa1\u4fa2\u4fa3\u4fa4\u4fa5\u4fa6\u4fa7\u4fa8\u4fa9\u4faa\u4fab\u4fac\u4fad\u4fae\u4faf\u4fb0\u4fb1\u4fb2\u4fb3\u4fb4\u4fb5\u4fb6\u4fb7\u4fb8\u4fb9\u4fba\u4fbb\u4fbc\u4fbd\u4fbe\u4fbf\u4fc0\u4fc1\u4fc2\u4fc3\u4fc4\u4fc5\u4fc6\u4fc7\u4fc8\u4fc9\u4fca\u4fcb\u4fcc\u4fcd\u4fce\u4fcf\u4fd0\u4fd1\u4fd2\u4fd3\u4fd4\u4fd5\u4fd6\u4fd7\u4fd8\u4fd9\u4fda\u4fdb\u4fdc\u4fdd\u4fde\u4fdf\u4fe0\u4fe1\u4fe2\u4fe3\u4fe4\u4fe5\u4fe6\u4fe7\u4fe8\u4fe9\u4fea\u4feb\u4fec\u4fed\u4fee\u4fef\u4ff0\u4ff1\u4ff2\u4ff3\u4ff4\u4ff5\u4ff6\u4ff7\u4ff8\u4ff9\u4ffa\u4ffb\u4ffc\u4ffd\u4ffe\u4fff\u5000\u5001\u5002\u5003\u5004\u5005\u5006\u5007\u5008\u5009\u500a\u500b\u500c\u500d\u500e\u500f\u5010\u5011\u5012\u5013\u5014\u5015\u5016\u5017\u5018\u5019\u501a\u501b\u501c\u501d\u501e\u501f\u5020\u5021\u5022\u5023\u5024\u5025\u5026\u5027\u5028\u5029\u502a\u502b\u502c\u502d\u502e\u502f\u5030\u5031\u5032\u5033\u5034\u5035\u5036\u5037\u5038\u5039\u503a\u503b\u503c\u503d\u503e\u503f\u5040\u5041\u5042\u5043\u5044\u5045\u5046\u5047\u5048\u5049\u504a\u504b\u504c\u504d\u504e\u504f\u5050\u5051\u5052\u5053\u5054\u5055\u5056\u5057\u5058\u5059\u505a\u505b\u505c\u505d\u505e\u505f\u5060\u5061\u5062\u5063\u5064\u5065\u5066\u5067\u5068\u5069\u506a\u506b\u506c\u506d\u506e\u506f\u5070\u5071\u5072\u5073\u5074\u5075\u5076\u5077\u5078\u5079\u507a\u507b\u507c\u507d\u507e\u507f\u5080\u5081\u5082\u5083\u5084\u5085\u5086\u5087\u5088\u5089\u508a\u508b\u508c\u508d\u508e\u508f\u5090\u5091\u5092\u5093\u5094\u5095\u5096\u5097\u5098\u5099\u509a\u509b\u509c\u509d\u509e\u509f\u50a0\u50a1\u50a2\u50a3\u50a4\u50a5\u50a6\u50a7\u50a8\u50a9\u50aa\u50ab\u50ac\u50ad\u50ae\u50af\u50b0\u50b1\u50b2\u50b3\u50b4\u50b5\u50b6\u50b7\u50b8\u50b9\u50ba\u50bb\u50bc\u50bd\u50be\u50bf\u50c0\u50c1\u50c2\u50c3\u50c4\u50c5\u50c6\u50c7\u50c8\u50c9\u50ca\u50cb\u50cc\u50cd\u50ce\u50cf\u50d0\u50d1\u50d2\u50d3\u50d4\u50d5\u50d6\u50d7\u50d8\u50d9\u50da\u50db\u50dc\u50dd\u50de\u50df\u50e0\u50e1\u50e2\u50e3\u50e4\u50e5\u50e6\u50e7\u50e8\u50e9\u50ea\u50eb\u50ec\u50ed\u50ee\u50ef\u50f0\u50f1\u50f2\u50f3\u50f4\u50f5\u50f6\u50f7\u50f8\u50f9\u50fa\u50fb\u50fc\u50fd\u50fe\u50ff\u5100\u5101\u5102\u5103\u5104\u5105\u5106\u5107\u5108\u5109\u510a\u510b\u510c\u510d\u510e\u510f\u5110\u5111\u5112\u5113\u5114\u5115\u5116\u5117\u5118\u5119\u511a\u511b\u511c\u511d\u511e\u511f\u5120\u5121\u5122\u5123\u5124\u5125\u5126\u5127\u5128\u5129\u512a\u512b\u512c\u512d\u512e\u512f\u5130\u5131\u5132\u5133\u5134\u5135\u5136\u5137\u5138\u5139\u513a\u513b\u513c\u513d\u513e\u513f\u5140\u5141\u5142\u5143\u5144\u5145\u5146\u5147\u5148\u5149\u514a\u514b\u514c\u514d\u514e\u514f\u5150\u5151\u5152\u5153\u5154\u5155\u5156\u5157\u5158\u5159\u515a\u515b\u515c\u515d\u515e\u515f\u5160\u5161\u5162\u5163\u5164\u5165\u5166\u5167\u5168\u5169\u516a\u516b\u516c\u516d\u516e\u516f\u5170\u5171\u5172\u5173\u5174\u5175\u5176\u5177\u5178\u5179\u517a\u517b\u517c\u517d\u517e\u517f\u5180\u5181\u5182\u5183\u5184\u5185\u5186\u5187\u5188\u5189\u518a\u518b\u518c\u518d\u518e\u518f\u5190\u5191\u5192\u5193\u5194\u5195\u5196\u5197\u5198\u5199\u519a\u519b\u519c\u519d\u519e\u519f\u51a0\u51a1\u51a2\u51a3\u51a4\u51a5\u51a6\u51a7\u51a8\u51a9\u51aa\u51ab\u51ac\u51ad\u51ae\u51af\u51b0\u51b1\u51b2\u51b3\u51b4\u51b5\u51b6\u51b7\u51b8\u51b9\u51ba\u51bb\u51bc\u51bd\u51be\u51bf\u51c0\u51c1\u51c2\u51c3\u51c4\u51c5\u51c6\u51c7\u51c8\u51c9\u51ca\u51cb\u51cc\u51cd\u51ce\u51cf\u51d0\u51d1\u51d2\u51d3\u51d4\u51d5\u51d6\u51d7\u51d8\u51d9\u51da\u51db\u51dc\u51dd\u51de\u51df\u51e0\u51e1\u51e2\u51e3\u51e4\u51e5\u51e6\u51e7\u51e8\u51e9\u51ea\u51eb\u51ec\u51ed\u51ee\u51ef\u51f0\u51f1\u51f2\u51f3\u51f4\u51f5\u51f6\u51f7\u51f8\u51f9\u51fa\u51fb\u51fc\u51fd\u51fe\u51ff\u5200\u5201\u5202\u5203\u5204\u5205\u5206\u5207\u5208\u5209\u520a\u520b\u520c\u520d\u520e\u520f\u5210\u5211\u5212\u5213\u5214\u5215\u5216\u5217\u5218\u5219\u521a\u521b\u521c\u521d\u521e\u521f\u5220\u5221\u5222\u5223\u5224\u5225\u5226\u5227\u5228\u5229\u522a\u522b\u522c\u522d\u522e\u522f\u5230\u5231\u5232\u5233\u5234\u5235\u5236\u5237\u5238\u5239\u523a\u523b\u523c\u523d\u523e\u523f\u5240\u5241\u5242\u5243\u5244\u5245\u5246\u5247\u5248\u5249\u524a\u524b\u524c\u524d\u524e\u524f\u5250\u5251\u5252\u5253\u5254\u5255\u5256\u5257\u5258\u5259\u525a\u525b\u525c\u525d\u525e\u525f\u5260\u5261\u5262\u5263\u5264\u5265\u5266\u5267\u5268\u5269\u526a\u526b\u526c\u526d\u526e\u526f\u5270\u5271\u5272\u5273\u5274\u5275\u5276\u5277\u5278\u5279\u527a\u527b\u527c\u527d\u527e\u527f\u5280\u5281\u5282\u5283\u5284\u5285\u5286\u5287\u5288\u5289\u528a\u528b\u528c\u528d\u528e\u528f\u5290\u5291\u5292\u5293\u5294\u5295\u5296\u5297\u5298\u5299\u529a\u529b\u529c\u529d\u529e\u529f\u52a0\u52a1\u52a2\u52a3\u52a4\u52a5\u52a6\u52a7\u52a8\u52a9\u52aa\u52ab\u52ac\u52ad\u52ae\u52af\u52b0\u52b1\u52b2\u52b3\u52b4\u52b5\u52b6\u52b7\u52b8\u52b9\u52ba\u52bb\u52bc\u52bd\u52be\u52bf\u52c0\u52c1\u52c2\u52c3\u52c4\u52c5\u52c6\u52c7\u52c8\u52c9\u52ca\u52cb\u52cc\u52cd\u52ce\u52cf\u52d0\u52d1\u52d2\u52d3\u52d4\u52d5\u52d6\u52d7\u52d8\u52d9\u52da\u52db\u52dc\u52dd\u52de\u52df\u52e0\u52e1\u52e2\u52e3\u52e4\u52e5\u52e6\u52e7\u52e8\u52e9\u52ea\u52eb\u52ec\u52ed\u52ee\u52ef\u52f0\u52f1\u52f2\u52f3\u52f4\u52f5\u52f6\u52f7\u52f8\u52f9\u52fa\u52fb\u52fc\u52fd\u52fe\u52ff\u5300\u5301\u5302\u5303\u5304\u5305\u5306\u5307\u5308\u5309\u530a\u530b\u530c\u530d\u530e\u530f\u5310\u5311\u5312\u5313\u5314\u5315\u5316\u5317\u5318\u5319\u531a\u531b\u531c\u531d\u531e\u531f\u5320\u5321\u5322\u5323\u5324\u5325\u5326\u5327\u5328\u5329\u532a\u532b\u532c\u532d\u532e\u532f\u5330\u5331\u5332\u5333\u5334\u5335\u5336\u5337\u5338\u5339\u533a\u533b\u533c\u533d\u533e\u533f\u5340\u5341\u5342\u5343\u5344\u5345\u5346\u5347\u5348\u5349\u534a\u534b\u534c\u534d\u534e\u534f\u5350\u5351\u5352\u5353\u5354\u5355\u5356\u5357\u5358\u5359\u535a\u535b\u535c\u535d\u535e\u535f\u5360\u5361\u5362\u5363\u5364\u5365\u5366\u5367\u5368\u5369\u536a\u536b\u536c\u536d\u536e\u536f\u5370\u5371\u5372\u5373\u5374\u5375\u5376\u5377\u5378\u5379\u537a\u537b\u537c\u537d\u537e\u537f\u5380\u5381\u5382\u5383\u5384\u5385\u5386\u5387\u5388\u5389\u538a\u538b\u538c\u538d\u538e\u538f\u5390\u5391\u5392\u5393\u5394\u5395\u5396\u5397\u5398\u5399\u539a\u539b\u539c\u539d\u539e\u539f\u53a0\u53a1\u53a2\u53a3\u53a4\u53a5\u53a6\u53a7\u53a8\u53a9\u53aa\u53ab\u53ac\u53ad\u53ae\u53af\u53b0\u53b1\u53b2\u53b3\u53b4\u53b5\u53b6\u53b7\u53b8\u53b9\u53ba\u53bb\u53bc\u53bd\u53be\u53bf\u53c0\u53c1\u53c2\u53c3\u53c4\u53c5\u53c6\u53c7\u53c8\u53c9\u53ca\u53cb\u53cc\u53cd\u53ce\u53cf\u53d0\u53d1\u53d2\u53d3\u53d4\u53d5\u53d6\u53d7\u53d8\u53d9\u53da\u53db\u53dc\u53dd\u53de\u53df\u53e0\u53e1\u53e2\u53e3\u53e4\u53e5\u53e6\u53e7\u53e8\u53e9\u53ea\u53eb\u53ec\u53ed\u53ee\u53ef\u53f0\u53f1\u53f2\u53f3\u53f4\u53f5\u53f6\u53f7\u53f8\u53f9\u53fa\u53fb\u53fc\u53fd\u53fe\u53ff\u5400\u5401\u5402\u5403\u5404\u5405\u5406\u5407\u5408\u5409\u540a\u540b\u540c\u540d\u540e\u540f\u5410\u5411\u5412\u5413\u5414\u5415\u5416\u5417\u5418\u5419\u541a\u541b\u541c\u541d\u541e\u541f\u5420\u5421\u5422\u5423\u5424\u5425\u5426\u5427\u5428\u5429\u542a\u542b\u542c\u542d\u542e\u542f\u5430\u5431\u5432\u5433\u5434\u5435\u5436\u5437\u5438\u5439\u543a\u543b\u543c\u543d\u543e\u543f\u5440\u5441\u5442\u5443\u5444\u5445\u5446\u5447\u5448\u5449\u544a\u544b\u544c\u544d\u544e\u544f\u5450\u5451\u5452\u5453\u5454\u5455\u5456\u5457\u5458\u5459\u545a\u545b\u545c\u545d\u545e\u545f\u5460\u5461\u5462\u5463\u5464\u5465\u5466\u5467\u5468\u5469\u546a\u546b\u546c\u546d\u546e\u546f\u5470\u5471\u5472\u5473\u5474\u5475\u5476\u5477\u5478\u5479\u547a\u547b\u547c\u547d\u547e\u547f\u5480\u5481\u5482\u5483\u5484\u5485\u5486\u5487\u5488\u5489\u548a\u548b\u548c\u548d\u548e\u548f\u5490\u5491\u5492\u5493\u5494\u5495\u5496\u5497\u5498\u5499\u549a\u549b\u549c\u549d\u549e\u549f\u54a0\u54a1\u54a2\u54a3\u54a4\u54a5\u54a6\u54a7\u54a8\u54a9\u54aa\u54ab\u54ac\u54ad\u54ae\u54af\u54b0\u54b1\u54b2\u54b3\u54b4\u54b5\u54b6\u54b7\u54b8\u54b9\u54ba\u54bb\u54bc\u54bd\u54be\u54bf\u54c0\u54c1\u54c2\u54c3\u54c4\u54c5\u54c6\u54c7\u54c8\u54c9\u54ca\u54cb\u54cc\u54cd\u54ce\u54cf\u54d0\u54d1\u54d2\u54d3\u54d4\u54d5\u54d6\u54d7\u54d8\u54d9\u54da\u54db\u54dc\u54dd\u54de\u54df\u54e0\u54e1\u54e2\u54e3\u54e4\u54e5\u54e6\u54e7\u54e8\u54e9\u54ea\u54eb\u54ec\u54ed\u54ee\u54ef\u54f0\u54f1\u54f2\u54f3\u54f4\u54f5\u54f6\u54f7\u54f8\u54f9\u54fa\u54fb\u54fc\u54fd\u54fe\u54ff\u5500\u5501\u5502\u5503\u5504\u5505\u5506\u5507\u5508\u5509\u550a\u550b\u550c\u550d\u550e\u550f\u5510\u5511\u5512\u5513\u5514\u5515\u5516\u5517\u5518\u5519\u551a\u551b\u551c\u551d\u551e\u551f\u5520\u5521\u5522\u5523\u5524\u5525\u5526\u5527\u5528\u5529\u552a\u552b\u552c\u552d\u552e\u552f\u5530\u5531\u5532\u5533\u5534\u5535\u5536\u5537\u5538\u5539\u553a\u553b\u553c\u553d\u553e\u553f\u5540\u5541\u5542\u5543\u5544\u5545\u5546\u5547\u5548\u5549\u554a\u554b\u554c\u554d\u554e\u554f\u5550\u5551\u5552\u5553\u5554\u5555\u5556\u5557\u5558\u5559\u555a\u555b\u555c\u555d\u555e\u555f\u5560\u5561\u5562\u5563\u5564\u5565\u5566\u5567\u5568\u5569\u556a\u556b\u556c\u556d\u556e\u556f\u5570\u5571\u5572\u5573\u5574\u5575\u5576\u5577\u5578\u5579\u557a\u557b\u557c\u557d\u557e\u557f\u5580\u5581\u5582\u5583\u5584\u5585\u5586\u5587\u5588\u5589\u558a\u558b\u558c\u558d\u558e\u558f\u5590\u5591\u5592\u5593\u5594\u5595\u5596\u5597\u5598\u5599\u559a\u559b\u559c\u559d\u559e\u559f\u55a0\u55a1\u55a2\u55a3\u55a4\u55a5\u55a6\u55a7\u55a8\u55a9\u55aa\u55ab\u55ac\u55ad\u55ae\u55af\u55b0\u55b1\u55b2\u55b3\u55b4\u55b5\u55b6\u55b7\u55b8\u55b9\u55ba\u55bb\u55bc\u55bd\u55be\u55bf\u55c0\u55c1\u55c2\u55c3\u55c4\u55c5\u55c6\u55c7\u55c8\u55c9\u55ca\u55cb\u55cc\u55cd\u55ce\u55cf\u55d0\u55d1\u55d2\u55d3\u55d4\u55d5\u55d6\u55d7\u55d8\u55d9\u55da\u55db\u55dc\u55dd\u55de\u55df\u55e0\u55e1\u55e2\u55e3\u55e4\u55e5\u55e6\u55e7\u55e8\u55e9\u55ea\u55eb\u55ec\u55ed\u55ee\u55ef\u55f0\u55f1\u55f2\u55f3\u55f4\u55f5\u55f6\u55f7\u55f8\u55f9\u55fa\u55fb\u55fc\u55fd\u55fe\u55ff\u5600\u5601\u5602\u5603\u5604\u5605\u5606\u5607\u5608\u5609\u560a\u560b\u560c\u560d\u560e\u560f\u5610\u5611\u5612\u5613\u5614\u5615\u5616\u5617\u5618\u5619\u561a\u561b\u561c\u561d\u561e\u561f\u5620\u5621\u5622\u5623\u5624\u5625\u5626\u5627\u5628\u5629\u562a\u562b\u562c\u562d\u562e\u562f\u5630\u5631\u5632\u5633\u5634\u5635\u5636\u5637\u5638\u5639\u563a\u563b\u563c\u563d\u563e\u563f\u5640\u5641\u5642\u5643\u5644\u5645\u5646\u5647\u5648\u5649\u564a\u564b\u564c\u564d\u564e\u564f\u5650\u5651\u5652\u5653\u5654\u5655\u5656\u5657\u5658\u5659\u565a\u565b\u565c\u565d\u565e\u565f\u5660\u5661\u5662\u5663\u5664\u5665\u5666\u5667\u5668\u5669\u566a\u566b\u566c\u566d\u566e\u566f\u5670\u5671\u5672\u5673\u5674\u5675\u5676\u5677\u5678\u5679\u567a\u567b\u567c\u567d\u567e\u567f\u5680\u5681\u5682\u5683\u5684\u5685\u5686\u5687\u5688\u5689\u568a\u568b\u568c\u568d\u568e\u568f\u5690\u5691\u5692\u5693\u5694\u5695\u5696\u5697\u5698\u5699\u569a\u569b\u569c\u569d\u569e\u569f\u56a0\u56a1\u56a2\u56a3\u56a4\u56a5\u56a6\u56a7\u56a8\u56a9\u56aa\u56ab\u56ac\u56ad\u56ae\u56af\u56b0\u56b1\u56b2\u56b3\u56b4\u56b5\u56b6\u56b7\u56b8\u56b9\u56ba\u56bb\u56bc\u56bd\u56be\u56bf\u56c0\u56c1\u56c2\u56c3\u56c4\u56c5\u56c6\u56c7\u56c8\u56c9\u56ca\u56cb\u56cc\u56cd\u56ce\u56cf\u56d0\u56d1\u56d2\u56d3\u56d4\u56d5\u56d6\u56d7\u56d8\u56d9\u56da\u56db\u56dc\u56dd\u56de\u56df\u56e0\u56e1\u56e2\u56e3\u56e4\u56e5\u56e6\u56e7\u56e8\u56e9\u56ea\u56eb\u56ec\u56ed\u56ee\u56ef\u56f0\u56f1\u56f2\u56f3\u56f4\u56f5\u56f6\u56f7\u56f8\u56f9\u56fa\u56fb\u56fc\u56fd\u56fe\u56ff\u5700\u5701\u5702\u5703\u5704\u5705\u5706\u5707\u5708\u5709\u570a\u570b\u570c\u570d\u570e\u570f\u5710\u5711\u5712\u5713\u5714\u5715\u5716\u5717\u5718\u5719\u571a\u571b\u571c\u571d\u571e\u571f\u5720\u5721\u5722\u5723\u5724\u5725\u5726\u5727\u5728\u5729\u572a\u572b\u572c\u572d\u572e\u572f\u5730\u5731\u5732\u5733\u5734\u5735\u5736\u5737\u5738\u5739\u573a\u573b\u573c\u573d\u573e\u573f\u5740\u5741\u5742\u5743\u5744\u5745\u5746\u5747\u5748\u5749\u574a\u574b\u574c\u574d\u574e\u574f\u5750\u5751\u5752\u5753\u5754\u5755\u5756\u5757\u5758\u5759\u575a\u575b\u575c\u575d\u575e\u575f\u5760\u5761\u5762\u5763\u5764\u5765\u5766\u5767\u5768\u5769\u576a\u576b\u576c\u576d\u576e\u576f\u5770\u5771\u5772\u5773\u5774\u5775\u5776\u5777\u5778\u5779\u577a\u577b\u577c\u577d\u577e\u577f\u5780\u5781\u5782\u5783\u5784\u5785\u5786\u5787\u5788\u5789\u578a\u578b\u578c\u578d\u578e\u578f\u5790\u5791\u5792\u5793\u5794\u5795\u5796\u5797\u5798\u5799\u579a\u579b\u579c\u579d\u579e\u579f\u57a0\u57a1\u57a2\u57a3\u57a4\u57a5\u57a6\u57a7\u57a8\u57a9\u57aa\u57ab\u57ac\u57ad\u57ae\u57af\u57b0\u57b1\u57b2\u57b3\u57b4\u57b5\u57b6\u57b7\u57b8\u57b9\u57ba\u57bb\u57bc\u57bd\u57be\u57bf\u57c0\u57c1\u57c2\u57c3\u57c4\u57c5\u57c6\u57c7\u57c8\u57c9\u57ca\u57cb\u57cc\u57cd\u57ce\u57cf\u57d0\u57d1\u57d2\u57d3\u57d4\u57d5\u57d6\u57d7\u57d8\u57d9\u57da\u57db\u57dc\u57dd\u57de\u57df\u57e0\u57e1\u57e2\u57e3\u57e4\u57e5\u57e6\u57e7\u57e8\u57e9\u57ea\u57eb\u57ec\u57ed\u57ee\u57ef\u57f0\u57f1\u57f2\u57f3\u57f4\u57f5\u57f6\u57f7\u57f8\u57f9\u57fa\u57fb\u57fc\u57fd\u57fe\u57ff\u5800\u5801\u5802\u5803\u5804\u5805\u5806\u5807\u5808\u5809\u580a\u580b\u580c\u580d\u580e\u580f\u5810\u5811\u5812\u5813\u5814\u5815\u5816\u5817\u5818\u5819\u581a\u581b\u581c\u581d\u581e\u581f\u5820\u5821\u5822\u5823\u5824\u5825\u5826\u5827\u5828\u5829\u582a\u582b\u582c\u582d\u582e\u582f\u5830\u5831\u5832\u5833\u5834\u5835\u5836\u5837\u5838\u5839\u583a\u583b\u583c\u583d\u583e\u583f\u5840\u5841\u5842\u5843\u5844\u5845\u5846\u5847\u5848\u5849\u584a\u584b\u584c\u584d\u584e\u584f\u5850\u5851\u5852\u5853\u5854\u5855\u5856\u5857\u5858\u5859\u585a\u585b\u585c\u585d\u585e\u585f\u5860\u5861\u5862\u5863\u5864\u5865\u5866\u5867\u5868\u5869\u586a\u586b\u586c\u586d\u586e\u586f\u5870\u5871\u5872\u5873\u5874\u5875\u5876\u5877\u5878\u5879\u587a\u587b\u587c\u587d\u587e\u587f\u5880\u5881\u5882\u5883\u5884\u5885\u5886\u5887\u5888\u5889\u588a\u588b\u588c\u588d\u588e\u588f\u5890\u5891\u5892\u5893\u5894\u5895\u5896\u5897\u5898\u5899\u589a\u589b\u589c\u589d\u589e\u589f\u58a0\u58a1\u58a2\u58a3\u58a4\u58a5\u58a6\u58a7\u58a8\u58a9\u58aa\u58ab\u58ac\u58ad\u58ae\u58af\u58b0\u58b1\u58b2\u58b3\u58b4\u58b5\u58b6\u58b7\u58b8\u58b9\u58ba\u58bb\u58bc\u58bd\u58be\u58bf\u58c0\u58c1\u58c2\u58c3\u58c4\u58c5\u58c6\u58c7\u58c8\u58c9\u58ca\u58cb\u58cc\u58cd\u58ce\u58cf\u58d0\u58d1\u58d2\u58d3\u58d4\u58d5\u58d6\u58d7\u58d8\u58d9\u58da\u58db\u58dc\u58dd\u58de\u58df\u58e0\u58e1\u58e2\u58e3\u58e4\u58e5\u58e6\u58e7\u58e8\u58e9\u58ea\u58eb\u58ec\u58ed\u58ee\u58ef\u58f0\u58f1\u58f2\u58f3\u58f4\u58f5\u58f6\u58f7\u58f8\u58f9\u58fa\u58fb\u58fc\u58fd\u58fe\u58ff\u5900\u5901\u5902\u5903\u5904\u5905\u5906\u5907\u5908\u5909\u590a\u590b\u590c\u590d\u590e\u590f\u5910\u5911\u5912\u5913\u5914\u5915\u5916\u5917\u5918\u5919\u591a\u591b\u591c\u591d\u591e\u591f\u5920\u5921\u5922\u5923\u5924\u5925\u5926\u5927\u5928\u5929\u592a\u592b\u592c\u592d\u592e\u592f\u5930\u5931\u5932\u5933\u5934\u5935\u5936\u5937\u5938\u5939\u593a\u593b\u593c\u593d\u593e\u593f\u5940\u5941\u5942\u5943\u5944\u5945\u5946\u5947\u5948\u5949\u594a\u594b\u594c\u594d\u594e\u594f\u5950\u5951\u5952\u5953\u5954\u5955\u5956\u5957\u5958\u5959\u595a\u595b\u595c\u595d\u595e\u595f\u5960\u5961\u5962\u5963\u5964\u5965\u5966\u5967\u5968\u5969\u596a\u596b\u596c\u596d\u596e\u596f\u5970\u5971\u5972\u5973\u5974\u5975\u5976\u5977\u5978\u5979\u597a\u597b\u597c\u597d\u597e\u597f\u5980\u5981\u5982\u5983\u5984\u5985\u5986\u5987\u5988\u5989\u598a\u598b\u598c\u598d\u598e\u598f\u5990\u5991\u5992\u5993\u5994\u5995\u5996\u5997\u5998\u5999\u599a\u599b\u599c\u599d\u599e\u599f\u59a0\u59a1\u59a2\u59a3\u59a4\u59a5\u59a6\u59a7\u59a8\u59a9\u59aa\u59ab\u59ac\u59ad\u59ae\u59af\u59b0\u59b1\u59b2\u59b3\u59b4\u59b5\u59b6\u59b7\u59b8\u59b9\u59ba\u59bb\u59bc\u59bd\u59be\u59bf\u59c0\u59c1\u59c2\u59c3\u59c4\u59c5\u59c6\u59c7\u59c8\u59c9\u59ca\u59cb\u59cc\u59cd\u59ce\u59cf\u59d0\u59d1\u59d2\u59d3\u59d4\u59d5\u59d6\u59d7\u59d8\u59d9\u59da\u59db\u59dc\u59dd\u59de\u59df\u59e0\u59e1\u59e2\u59e3\u59e4\u59e5\u59e6\u59e7\u59e8\u59e9\u59ea\u59eb\u59ec\u59ed\u59ee\u59ef\u59f0\u59f1\u59f2\u59f3\u59f4\u59f5\u59f6\u59f7\u59f8\u59f9\u59fa\u59fb\u59fc\u59fd\u59fe\u59ff\u5a00\u5a01\u5a02\u5a03\u5a04\u5a05\u5a06\u5a07\u5a08\u5a09\u5a0a\u5a0b\u5a0c\u5a0d\u5a0e\u5a0f\u5a10\u5a11\u5a12\u5a13\u5a14\u5a15\u5a16\u5a17\u5a18\u5a19\u5a1a\u5a1b\u5a1c\u5a1d\u5a1e\u5a1f\u5a20\u5a21\u5a22\u5a23\u5a24\u5a25\u5a26\u5a27\u5a28\u5a29\u5a2a\u5a2b\u5a2c\u5a2d\u5a2e\u5a2f\u5a30\u5a31\u5a32\u5a33\u5a34\u5a35\u5a36\u5a37\u5a38\u5a39\u5a3a\u5a3b\u5a3c\u5a3d\u5a3e\u5a3f\u5a40\u5a41\u5a42\u5a43\u5a44\u5a45\u5a46\u5a47\u5a48\u5a49\u5a4a\u5a4b\u5a4c\u5a4d\u5a4e\u5a4f\u5a50\u5a51\u5a52\u5a53\u5a54\u5a55\u5a56\u5a57\u5a58\u5a59\u5a5a\u5a5b\u5a5c\u5a5d\u5a5e\u5a5f\u5a60\u5a61\u5a62\u5a63\u5a64\u5a65\u5a66\u5a67\u5a68\u5a69\u5a6a\u5a6b\u5a6c\u5a6d\u5a6e\u5a6f\u5a70\u5a71\u5a72\u5a73\u5a74\u5a75\u5a76\u5a77\u5a78\u5a79\u5a7a\u5a7b\u5a7c\u5a7d\u5a7e\u5a7f\u5a80\u5a81\u5a82\u5a83\u5a84\u5a85\u5a86\u5a87\u5a88\u5a89\u5a8a\u5a8b\u5a8c\u5a8d\u5a8e\u5a8f\u5a90\u5a91\u5a92\u5a93\u5a94\u5a95\u5a96\u5a97\u5a98\u5a99\u5a9a\u5a9b\u5a9c\u5a9d\u5a9e\u5a9f\u5aa0\u5aa1\u5aa2\u5aa3\u5aa4\u5aa5\u5aa6\u5aa7\u5aa8\u5aa9\u5aaa\u5aab\u5aac\u5aad\u5aae\u5aaf\u5ab0\u5ab1\u5ab2\u5ab3\u5ab4\u5ab5\u5ab6\u5ab7\u5ab8\u5ab9\u5aba\u5abb\u5abc\u5abd\u5abe\u5abf\u5ac0\u5ac1\u5ac2\u5ac3\u5ac4\u5ac5\u5ac6\u5ac7\u5ac8\u5ac9\u5aca\u5acb\u5acc\u5acd\u5ace\u5acf\u5ad0\u5ad1\u5ad2\u5ad3\u5ad4\u5ad5\u5ad6\u5ad7\u5ad8\u5ad9\u5ada\u5adb\u5adc\u5add\u5ade\u5adf\u5ae0\u5ae1\u5ae2\u5ae3\u5ae4\u5ae5\u5ae6\u5ae7\u5ae8\u5ae9\u5aea\u5aeb\u5aec\u5aed\u5aee\u5aef\u5af0\u5af1\u5af2\u5af3\u5af4\u5af5\u5af6\u5af7\u5af8\u5af9\u5afa\u5afb\u5afc\u5afd\u5afe\u5aff\u5b00\u5b01\u5b02\u5b03\u5b04\u5b05\u5b06\u5b07\u5b08\u5b09\u5b0a\u5b0b\u5b0c\u5b0d\u5b0e\u5b0f\u5b10\u5b11\u5b12\u5b13\u5b14\u5b15\u5b16\u5b17\u5b18\u5b19\u5b1a\u5b1b\u5b1c\u5b1d\u5b1e\u5b1f\u5b20\u5b21\u5b22\u5b23\u5b24\u5b25\u5b26\u5b27\u5b28\u5b29\u5b2a\u5b2b\u5b2c\u5b2d\u5b2e\u5b2f\u5b30\u5b31\u5b32\u5b33\u5b34\u5b35\u5b36\u5b37\u5b38\u5b39\u5b3a\u5b3b\u5b3c\u5b3d\u5b3e\u5b3f\u5b40\u5b41\u5b42\u5b43\u5b44\u5b45\u5b46\u5b47\u5b48\u5b49\u5b4a\u5b4b\u5b4c\u5b4d\u5b4e\u5b4f\u5b50\u5b51\u5b52\u5b53\u5b54\u5b55\u5b56\u5b57\u5b58\u5b59\u5b5a\u5b5b\u5b5c\u5b5d\u5b5e\u5b5f\u5b60\u5b61\u5b62\u5b63\u5b64\u5b65\u5b66\u5b67\u5b68\u5b69\u5b6a\u5b6b\u5b6c\u5b6d\u5b6e\u5b6f\u5b70\u5b71\u5b72\u5b73\u5b74\u5b75\u5b76\u5b77\u5b78\u5b79\u5b7a\u5b7b\u5b7c\u5b7d\u5b7e\u5b7f\u5b80\u5b81\u5b82\u5b83\u5b84\u5b85\u5b86\u5b87\u5b88\u5b89\u5b8a\u5b8b\u5b8c\u5b8d\u5b8e\u5b8f\u5b90\u5b91\u5b92\u5b93\u5b94\u5b95\u5b96\u5b97\u5b98\u5b99\u5b9a\u5b9b\u5b9c\u5b9d\u5b9e\u5b9f\u5ba0\u5ba1\u5ba2\u5ba3\u5ba4\u5ba5\u5ba6\u5ba7\u5ba8\u5ba9\u5baa\u5bab\u5bac\u5bad\u5bae\u5baf\u5bb0\u5bb1\u5bb2\u5bb3\u5bb4\u5bb5\u5bb6\u5bb7\u5bb8\u5bb9\u5bba\u5bbb\u5bbc\u5bbd\u5bbe\u5bbf\u5bc0\u5bc1\u5bc2\u5bc3\u5bc4\u5bc5\u5bc6\u5bc7\u5bc8\u5bc9\u5bca\u5bcb\u5bcc\u5bcd\u5bce\u5bcf\u5bd0\u5bd1\u5bd2\u5bd3\u5bd4\u5bd5\u5bd6\u5bd7\u5bd8\u5bd9\u5bda\u5bdb\u5bdc\u5bdd\u5bde\u5bdf\u5be0\u5be1\u5be2\u5be3\u5be4\u5be5\u5be6\u5be7\u5be8\u5be9\u5bea\u5beb\u5bec\u5bed\u5bee\u5bef\u5bf0\u5bf1\u5bf2\u5bf3\u5bf4\u5bf5\u5bf6\u5bf7\u5bf8\u5bf9\u5bfa\u5bfb\u5bfc\u5bfd\u5bfe\u5bff\u5c00\u5c01\u5c02\u5c03\u5c04\u5c05\u5c06\u5c07\u5c08\u5c09\u5c0a\u5c0b\u5c0c\u5c0d\u5c0e\u5c0f\u5c10\u5c11\u5c12\u5c13\u5c14\u5c15\u5c16\u5c17\u5c18\u5c19\u5c1a\u5c1b\u5c1c\u5c1d\u5c1e\u5c1f\u5c20\u5c21\u5c22\u5c23\u5c24\u5c25\u5c26\u5c27\u5c28\u5c29\u5c2a\u5c2b\u5c2c\u5c2d\u5c2e\u5c2f\u5c30\u5c31\u5c32\u5c33\u5c34\u5c35\u5c36\u5c37\u5c38\u5c39\u5c3a\u5c3b\u5c3c\u5c3d\u5c3e\u5c3f\u5c40\u5c41\u5c42\u5c43\u5c44\u5c45\u5c46\u5c47\u5c48\u5c49\u5c4a\u5c4b\u5c4c\u5c4d\u5c4e\u5c4f\u5c50\u5c51\u5c52\u5c53\u5c54\u5c55\u5c56\u5c57\u5c58\u5c59\u5c5a\u5c5b\u5c5c\u5c5d\u5c5e\u5c5f\u5c60\u5c61\u5c62\u5c63\u5c64\u5c65\u5c66\u5c67\u5c68\u5c69\u5c6a\u5c6b\u5c6c\u5c6d\u5c6e\u5c6f\u5c70\u5c71\u5c72\u5c73\u5c74\u5c75\u5c76\u5c77\u5c78\u5c79\u5c7a\u5c7b\u5c7c\u5c7d\u5c7e\u5c7f\u5c80\u5c81\u5c82\u5c83\u5c84\u5c85\u5c86\u5c87\u5c88\u5c89\u5c8a\u5c8b\u5c8c\u5c8d\u5c8e\u5c8f\u5c90\u5c91\u5c92\u5c93\u5c94\u5c95\u5c96\u5c97\u5c98\u5c99\u5c9a\u5c9b\u5c9c\u5c9d\u5c9e\u5c9f\u5ca0\u5ca1\u5ca2\u5ca3\u5ca4\u5ca5\u5ca6\u5ca7\u5ca8\u5ca9\u5caa\u5cab\u5cac\u5cad\u5cae\u5caf\u5cb0\u5cb1\u5cb2\u5cb3\u5cb4\u5cb5\u5cb6\u5cb7\u5cb8\u5cb9\u5cba\u5cbb\u5cbc\u5cbd\u5cbe\u5cbf\u5cc0\u5cc1\u5cc2\u5cc3\u5cc4\u5cc5\u5cc6\u5cc7\u5cc8\u5cc9\u5cca\u5ccb\u5ccc\u5ccd\u5cce\u5ccf\u5cd0\u5cd1\u5cd2\u5cd3\u5cd4\u5cd5\u5cd6\u5cd7\u5cd8\u5cd9\u5cda\u5cdb\u5cdc\u5cdd\u5cde\u5cdf\u5ce0\u5ce1\u5ce2\u5ce3\u5ce4\u5ce5\u5ce6\u5ce7\u5ce8\u5ce9\u5cea\u5ceb\u5cec\u5ced\u5cee\u5cef\u5cf0\u5cf1\u5cf2\u5cf3\u5cf4\u5cf5\u5cf6\u5cf7\u5cf8\u5cf9\u5cfa\u5cfb\u5cfc\u5cfd\u5cfe\u5cff\u5d00\u5d01\u5d02\u5d03\u5d04\u5d05\u5d06\u5d07\u5d08\u5d09\u5d0a\u5d0b\u5d0c\u5d0d\u5d0e\u5d0f\u5d10\u5d11\u5d12\u5d13\u5d14\u5d15\u5d16\u5d17\u5d18\u5d19\u5d1a\u5d1b\u5d1c\u5d1d\u5d1e\u5d1f\u5d20\u5d21\u5d22\u5d23\u5d24\u5d25\u5d26\u5d27\u5d28\u5d29\u5d2a\u5d2b\u5d2c\u5d2d\u5d2e\u5d2f\u5d30\u5d31\u5d32\u5d33\u5d34\u5d35\u5d36\u5d37\u5d38\u5d39\u5d3a\u5d3b\u5d3c\u5d3d\u5d3e\u5d3f\u5d40\u5d41\u5d42\u5d43\u5d44\u5d45\u5d46\u5d47\u5d48\u5d49\u5d4a\u5d4b\u5d4c\u5d4d\u5d4e\u5d4f\u5d50\u5d51\u5d52\u5d53\u5d54\u5d55\u5d56\u5d57\u5d58\u5d59\u5d5a\u5d5b\u5d5c\u5d5d\u5d5e\u5d5f\u5d60\u5d61\u5d62\u5d63\u5d64\u5d65\u5d66\u5d67\u5d68\u5d69\u5d6a\u5d6b\u5d6c\u5d6d\u5d6e\u5d6f\u5d70\u5d71\u5d72\u5d73\u5d74\u5d75\u5d76\u5d77\u5d78\u5d79\u5d7a\u5d7b\u5d7c\u5d7d\u5d7e\u5d7f\u5d80\u5d81\u5d82\u5d83\u5d84\u5d85\u5d86\u5d87\u5d88\u5d89\u5d8a\u5d8b\u5d8c\u5d8d\u5d8e\u5d8f\u5d90\u5d91\u5d92\u5d93\u5d94\u5d95\u5d96\u5d97\u5d98\u5d99\u5d9a\u5d9b\u5d9c\u5d9d\u5d9e\u5d9f\u5da0\u5da1\u5da2\u5da3\u5da4\u5da5\u5da6\u5da7\u5da8\u5da9\u5daa\u5dab\u5dac\u5dad\u5dae\u5daf\u5db0\u5db1\u5db2\u5db3\u5db4\u5db5\u5db6\u5db7\u5db8\u5db9\u5dba\u5dbb\u5dbc\u5dbd\u5dbe\u5dbf\u5dc0\u5dc1\u5dc2\u5dc3\u5dc4\u5dc5\u5dc6\u5dc7\u5dc8\u5dc9\u5dca\u5dcb\u5dcc\u5dcd\u5dce\u5dcf\u5dd0\u5dd1\u5dd2\u5dd3\u5dd4\u5dd5\u5dd6\u5dd7\u5dd8\u5dd9\u5dda\u5ddb\u5ddc\u5ddd\u5dde\u5ddf\u5de0\u5de1\u5de2\u5de3\u5de4\u5de5\u5de6\u5de7\u5de8\u5de9\u5dea\u5deb\u5dec\u5ded\u5dee\u5def\u5df0\u5df1\u5df2\u5df3\u5df4\u5df5\u5df6\u5df7\u5df8\u5df9\u5dfa\u5dfb\u5dfc\u5dfd\u5dfe\u5dff\u5e00\u5e01\u5e02\u5e03\u5e04\u5e05\u5e06\u5e07\u5e08\u5e09\u5e0a\u5e0b\u5e0c\u5e0d\u5e0e\u5e0f\u5e10\u5e11\u5e12\u5e13\u5e14\u5e15\u5e16\u5e17\u5e18\u5e19\u5e1a\u5e1b\u5e1c\u5e1d\u5e1e\u5e1f\u5e20\u5e21\u5e22\u5e23\u5e24\u5e25\u5e26\u5e27\u5e28\u5e29\u5e2a\u5e2b\u5e2c\u5e2d\u5e2e\u5e2f\u5e30\u5e31\u5e32\u5e33\u5e34\u5e35\u5e36\u5e37\u5e38\u5e39\u5e3a\u5e3b\u5e3c\u5e3d\u5e3e\u5e3f\u5e40\u5e41\u5e42\u5e43\u5e44\u5e45\u5e46\u5e47\u5e48\u5e49\u5e4a\u5e4b\u5e4c\u5e4d\u5e4e\u5e4f\u5e50\u5e51\u5e52\u5e53\u5e54\u5e55\u5e56\u5e57\u5e58\u5e59\u5e5a\u5e5b\u5e5c\u5e5d\u5e5e\u5e5f\u5e60\u5e61\u5e62\u5e63\u5e64\u5e65\u5e66\u5e67\u5e68\u5e69\u5e6a\u5e6b\u5e6c\u5e6d\u5e6e\u5e6f\u5e70\u5e71\u5e72\u5e73\u5e74\u5e75\u5e76\u5e77\u5e78\u5e79\u5e7a\u5e7b\u5e7c\u5e7d\u5e7e\u5e7f\u5e80\u5e81\u5e82\u5e83\u5e84\u5e85\u5e86\u5e87\u5e88\u5e89\u5e8a\u5e8b\u5e8c\u5e8d\u5e8e\u5e8f\u5e90\u5e91\u5e92\u5e93\u5e94\u5e95\u5e96\u5e97\u5e98\u5e99\u5e9a\u5e9b\u5e9c\u5e9d\u5e9e\u5e9f\u5ea0\u5ea1\u5ea2\u5ea3\u5ea4\u5ea5\u5ea6\u5ea7\u5ea8\u5ea9\u5eaa\u5eab\u5eac\u5ead\u5eae\u5eaf\u5eb0\u5eb1\u5eb2\u5eb3\u5eb4\u5eb5\u5eb6\u5eb7\u5eb8\u5eb9\u5eba\u5ebb\u5ebc\u5ebd\u5ebe\u5ebf\u5ec0\u5ec1\u5ec2\u5ec3\u5ec4\u5ec5\u5ec6\u5ec7\u5ec8\u5ec9\u5eca\u5ecb\u5ecc\u5ecd\u5ece\u5ecf\u5ed0\u5ed1\u5ed2\u5ed3\u5ed4\u5ed5\u5ed6\u5ed7\u5ed8\u5ed9\u5eda\u5edb\u5edc\u5edd\u5ede\u5edf\u5ee0\u5ee1\u5ee2\u5ee3\u5ee4\u5ee5\u5ee6\u5ee7\u5ee8\u5ee9\u5eea\u5eeb\u5eec\u5eed\u5eee\u5eef\u5ef0\u5ef1\u5ef2\u5ef3\u5ef4\u5ef5\u5ef6\u5ef7\u5ef8\u5ef9\u5efa\u5efb\u5efc\u5efd\u5efe\u5eff\u5f00\u5f01\u5f02\u5f03\u5f04\u5f05\u5f06\u5f07\u5f08\u5f09\u5f0a\u5f0b\u5f0c\u5f0d\u5f0e\u5f0f\u5f10\u5f11\u5f12\u5f13\u5f14\u5f15\u5f16\u5f17\u5f18\u5f19\u5f1a\u5f1b\u5f1c\u5f1d\u5f1e\u5f1f\u5f20\u5f21\u5f22\u5f23\u5f24\u5f25\u5f26\u5f27\u5f28\u5f29\u5f2a\u5f2b\u5f2c\u5f2d\u5f2e\u5f2f\u5f30\u5f31\u5f32\u5f33\u5f34\u5f35\u5f36\u5f37\u5f38\u5f39\u5f3a\u5f3b\u5f3c\u5f3d\u5f3e\u5f3f\u5f40\u5f41\u5f42\u5f43\u5f44\u5f45\u5f46\u5f47\u5f48\u5f49\u5f4a\u5f4b\u5f4c\u5f4d\u5f4e\u5f4f\u5f50\u5f51\u5f52\u5f53\u5f54\u5f55\u5f56\u5f57\u5f58\u5f59\u5f5a\u5f5b\u5f5c\u5f5d\u5f5e\u5f5f\u5f60\u5f61\u5f62\u5f63\u5f64\u5f65\u5f66\u5f67\u5f68\u5f69\u5f6a\u5f6b\u5f6c\u5f6d\u5f6e\u5f6f\u5f70\u5f71\u5f72\u5f73\u5f74\u5f75\u5f76\u5f77\u5f78\u5f79\u5f7a\u5f7b\u5f7c\u5f7d\u5f7e\u5f7f\u5f80\u5f81\u5f82\u5f83\u5f84\u5f85\u5f86\u5f87\u5f88\u5f89\u5f8a\u5f8b\u5f8c\u5f8d\u5f8e\u5f8f\u5f90\u5f91\u5f92\u5f93\u5f94\u5f95\u5f96\u5f97\u5f98\u5f99\u5f9a\u5f9b\u5f9c\u5f9d\u5f9e\u5f9f\u5fa0\u5fa1\u5fa2\u5fa3\u5fa4\u5fa5\u5fa6\u5fa7\u5fa8\u5fa9\u5faa\u5fab\u5fac\u5fad\u5fae\u5faf\u5fb0\u5fb1\u5fb2\u5fb3\u5fb4\u5fb5\u5fb6\u5fb7\u5fb8\u5fb9\u5fba\u5fbb\u5fbc\u5fbd\u5fbe\u5fbf\u5fc0\u5fc1\u5fc2\u5fc3\u5fc4\u5fc5\u5fc6\u5fc7\u5fc8\u5fc9\u5fca\u5fcb\u5fcc\u5fcd\u5fce\u5fcf\u5fd0\u5fd1\u5fd2\u5fd3\u5fd4\u5fd5\u5fd6\u5fd7\u5fd8\u5fd9\u5fda\u5fdb\u5fdc\u5fdd\u5fde\u5fdf\u5fe0\u5fe1\u5fe2\u5fe3\u5fe4\u5fe5\u5fe6\u5fe7\u5fe8\u5fe9\u5fea\u5feb\u5fec\u5fed\u5fee\u5fef\u5ff0\u5ff1\u5ff2\u5ff3\u5ff4\u5ff5\u5ff6\u5ff7\u5ff8\u5ff9\u5ffa\u5ffb\u5ffc\u5ffd\u5ffe\u5fff\u6000\u6001\u6002\u6003\u6004\u6005\u6006\u6007\u6008\u6009\u600a\u600b\u600c\u600d\u600e\u600f\u6010\u6011\u6012\u6013\u6014\u6015\u6016\u6017\u6018\u6019\u601a\u601b\u601c\u601d\u601e\u601f\u6020\u6021\u6022\u6023\u6024\u6025\u6026\u6027\u6028\u6029\u602a\u602b\u602c\u602d\u602e\u602f\u6030\u6031\u6032\u6033\u6034\u6035\u6036\u6037\u6038\u6039\u603a\u603b\u603c\u603d\u603e\u603f\u6040\u6041\u6042\u6043\u6044\u6045\u6046\u6047\u6048\u6049\u604a\u604b\u604c\u604d\u604e\u604f\u6050\u6051\u6052\u6053\u6054\u6055\u6056\u6057\u6058\u6059\u605a\u605b\u605c\u605d\u605e\u605f\u6060\u6061\u6062\u6063\u6064\u6065\u6066\u6067\u6068\u6069\u606a\u606b\u606c\u606d\u606e\u606f\u6070\u6071\u6072\u6073\u6074\u6075\u6076\u6077\u6078\u6079\u607a\u607b\u607c\u607d\u607e\u607f\u6080\u6081\u6082\u6083\u6084\u6085\u6086\u6087\u6088\u6089\u608a\u608b\u608c\u608d\u608e\u608f\u6090\u6091\u6092\u6093\u6094\u6095\u6096\u6097\u6098\u6099\u609a\u609b\u609c\u609d\u609e\u609f\u60a0\u60a1\u60a2\u60a3\u60a4\u60a5\u60a6\u60a7\u60a8\u60a9\u60aa\u60ab\u60ac\u60ad\u60ae\u60af\u60b0\u60b1\u60b2\u60b3\u60b4\u60b5\u60b6\u60b7\u60b8\u60b9\u60ba\u60bb\u60bc\u60bd\u60be\u60bf\u60c0\u60c1\u60c2\u60c3\u60c4\u60c5\u60c6\u60c7\u60c8\u60c9\u60ca\u60cb\u60cc\u60cd\u60ce\u60cf\u60d0\u60d1\u60d2\u60d3\u60d4\u60d5\u60d6\u60d7\u60d8\u60d9\u60da\u60db\u60dc\u60dd\u60de\u60df\u60e0\u60e1\u60e2\u60e3\u60e4\u60e5\u60e6\u60e7\u60e8\u60e9\u60ea\u60eb\u60ec\u60ed\u60ee\u60ef\u60f0\u60f1\u60f2\u60f3\u60f4\u60f5\u60f6\u60f7\u60f8\u60f9\u60fa\u60fb\u60fc\u60fd\u60fe\u60ff\u6100\u6101\u6102\u6103\u6104\u6105\u6106\u6107\u6108\u6109\u610a\u610b\u610c\u610d\u610e\u610f\u6110\u6111\u6112\u6113\u6114\u6115\u6116\u6117\u6118\u6119\u611a\u611b\u611c\u611d\u611e\u611f\u6120\u6121\u6122\u6123\u6124\u6125\u6126\u6127\u6128\u6129\u612a\u612b\u612c\u612d\u612e\u612f\u6130\u6131\u6132\u6133\u6134\u6135\u6136\u6137\u6138\u6139\u613a\u613b\u613c\u613d\u613e\u613f\u6140\u6141\u6142\u6143\u6144\u6145\u6146\u6147\u6148\u6149\u614a\u614b\u614c\u614d\u614e\u614f\u6150\u6151\u6152\u6153\u6154\u6155\u6156\u6157\u6158\u6159\u615a\u615b\u615c\u615d\u615e\u615f\u6160\u6161\u6162\u6163\u6164\u6165\u6166\u6167\u6168\u6169\u616a\u616b\u616c\u616d\u616e\u616f\u6170\u6171\u6172\u6173\u6174\u6175\u6176\u6177\u6178\u6179\u617a\u617b\u617c\u617d\u617e\u617f\u6180\u6181\u6182\u6183\u6184\u6185\u6186\u6187\u6188\u6189\u618a\u618b\u618c\u618d\u618e\u618f\u6190\u6191\u6192\u6193\u6194\u6195\u6196\u6197\u6198\u6199\u619a\u619b\u619c\u619d\u619e\u619f\u61a0\u61a1\u61a2\u61a3\u61a4\u61a5\u61a6\u61a7\u61a8\u61a9\u61aa\u61ab\u61ac\u61ad\u61ae\u61af\u61b0\u61b1\u61b2\u61b3\u61b4\u61b5\u61b6\u61b7\u61b8\u61b9\u61ba\u61bb\u61bc\u61bd\u61be\u61bf\u61c0\u61c1\u61c2\u61c3\u61c4\u61c5\u61c6\u61c7\u61c8\u61c9\u61ca\u61cb\u61cc\u61cd\u61ce\u61cf\u61d0\u61d1\u61d2\u61d3\u61d4\u61d5\u61d6\u61d7\u61d8\u61d9\u61da\u61db\u61dc\u61dd\u61de\u61df\u61e0\u61e1\u61e2\u61e3\u61e4\u61e5\u61e6\u61e7\u61e8\u61e9\u61ea\u61eb\u61ec\u61ed\u61ee\u61ef\u61f0\u61f1\u61f2\u61f3\u61f4\u61f5\u61f6\u61f7\u61f8\u61f9\u61fa\u61fb\u61fc\u61fd\u61fe\u61ff\u6200\u6201\u6202\u6203\u6204\u6205\u6206\u6207\u6208\u6209\u620a\u620b\u620c\u620d\u620e\u620f\u6210\u6211\u6212\u6213\u6214\u6215\u6216\u6217\u6218\u6219\u621a\u621b\u621c\u621d\u621e\u621f\u6220\u6221\u6222\u6223\u6224\u6225\u6226\u6227\u6228\u6229\u622a\u622b\u622c\u622d\u622e\u622f\u6230\u6231\u6232\u6233\u6234\u6235\u6236\u6237\u6238\u6239\u623a\u623b\u623c\u623d\u623e\u623f\u6240\u6241\u6242\u6243\u6244\u6245\u6246\u6247\u6248\u6249\u624a\u624b\u624c\u624d\u624e\u624f\u6250\u6251\u6252\u6253\u6254\u6255\u6256\u6257\u6258\u6259\u625a\u625b\u625c\u625d\u625e\u625f\u6260\u6261\u6262\u6263\u6264\u6265\u6266\u6267\u6268\u6269\u626a\u626b\u626c\u626d\u626e\u626f\u6270\u6271\u6272\u6273\u6274\u6275\u6276\u6277\u6278\u6279\u627a\u627b\u627c\u627d\u627e\u627f\u6280\u6281\u6282\u6283\u6284\u6285\u6286\u6287\u6288\u6289\u628a\u628b\u628c\u628d\u628e\u628f\u6290\u6291\u6292\u6293\u6294\u6295\u6296\u6297\u6298\u6299\u629a\u629b\u629c\u629d\u629e\u629f\u62a0\u62a1\u62a2\u62a3\u62a4\u62a5\u62a6\u62a7\u62a8\u62a9\u62aa\u62ab\u62ac\u62ad\u62ae\u62af\u62b0\u62b1\u62b2\u62b3\u62b4\u62b5\u62b6\u62b7\u62b8\u62b9\u62ba\u62bb\u62bc\u62bd\u62be\u62bf\u62c0\u62c1\u62c2\u62c3\u62c4\u62c5\u62c6\u62c7\u62c8\u62c9\u62ca\u62cb\u62cc\u62cd\u62ce\u62cf\u62d0\u62d1\u62d2\u62d3\u62d4\u62d5\u62d6\u62d7\u62d8\u62d9\u62da\u62db\u62dc\u62dd\u62de\u62df\u62e0\u62e1\u62e2\u62e3\u62e4\u62e5\u62e6\u62e7\u62e8\u62e9\u62ea\u62eb\u62ec\u62ed\u62ee\u62ef\u62f0\u62f1\u62f2\u62f3\u62f4\u62f5\u62f6\u62f7\u62f8\u62f9\u62fa\u62fb\u62fc\u62fd\u62fe\u62ff\u6300\u6301\u6302\u6303\u6304\u6305\u6306\u6307\u6308\u6309\u630a\u630b\u630c\u630d\u630e\u630f\u6310\u6311\u6312\u6313\u6314\u6315\u6316\u6317\u6318\u6319\u631a\u631b\u631c\u631d\u631e\u631f\u6320\u6321\u6322\u6323\u6324\u6325\u6326\u6327\u6328\u6329\u632a\u632b\u632c\u632d\u632e\u632f\u6330\u6331\u6332\u6333\u6334\u6335\u6336\u6337\u6338\u6339\u633a\u633b\u633c\u633d\u633e\u633f\u6340\u6341\u6342\u6343\u6344\u6345\u6346\u6347\u6348\u6349\u634a\u634b\u634c\u634d\u634e\u634f\u6350\u6351\u6352\u6353\u6354\u6355\u6356\u6357\u6358\u6359\u635a\u635b\u635c\u635d\u635e\u635f\u6360\u6361\u6362\u6363\u6364\u6365\u6366\u6367\u6368\u6369\u636a\u636b\u636c\u636d\u636e\u636f\u6370\u6371\u6372\u6373\u6374\u6375\u6376\u6377\u6378\u6379\u637a\u637b\u637c\u637d\u637e\u637f\u6380\u6381\u6382\u6383\u6384\u6385\u6386\u6387\u6388\u6389\u638a\u638b\u638c\u638d\u638e\u638f\u6390\u6391\u6392\u6393\u6394\u6395\u6396\u6397\u6398\u6399\u639a\u639b\u639c\u639d\u639e\u639f\u63a0\u63a1\u63a2\u63a3\u63a4\u63a5\u63a6\u63a7\u63a8\u63a9\u63aa\u63ab\u63ac\u63ad\u63ae\u63af\u63b0\u63b1\u63b2\u63b3\u63b4\u63b5\u63b6\u63b7\u63b8\u63b9\u63ba\u63bb\u63bc\u63bd\u63be\u63bf\u63c0\u63c1\u63c2\u63c3\u63c4\u63c5\u63c6\u63c7\u63c8\u63c9\u63ca\u63cb\u63cc\u63cd\u63ce\u63cf\u63d0\u63d1\u63d2\u63d3\u63d4\u63d5\u63d6\u63d7\u63d8\u63d9\u63da\u63db\u63dc\u63dd\u63de\u63df\u63e0\u63e1\u63e2\u63e3\u63e4\u63e5\u63e6\u63e7\u63e8\u63e9\u63ea\u63eb\u63ec\u63ed\u63ee\u63ef\u63f0\u63f1\u63f2\u63f3\u63f4\u63f5\u63f6\u63f7\u63f8\u63f9\u63fa\u63fb\u63fc\u63fd\u63fe\u63ff\u6400\u6401\u6402\u6403\u6404\u6405\u6406\u6407\u6408\u6409\u640a\u640b\u640c\u640d\u640e\u640f\u6410\u6411\u6412\u6413\u6414\u6415\u6416\u6417\u6418\u6419\u641a\u641b\u641c\u641d\u641e\u641f\u6420\u6421\u6422\u6423\u6424\u6425\u6426\u6427\u6428\u6429\u642a\u642b\u642c\u642d\u642e\u642f\u6430\u6431\u6432\u6433\u6434\u6435\u6436\u6437\u6438\u6439\u643a\u643b\u643c\u643d\u643e\u643f\u6440\u6441\u6442\u6443\u6444\u6445\u6446\u6447\u6448\u6449\u644a\u644b\u644c\u644d\u644e\u644f\u6450\u6451\u6452\u6453\u6454\u6455\u6456\u6457\u6458\u6459\u645a\u645b\u645c\u645d\u645e\u645f\u6460\u6461\u6462\u6463\u6464\u6465\u6466\u6467\u6468\u6469\u646a\u646b\u646c\u646d\u646e\u646f\u6470\u6471\u6472\u6473\u6474\u6475\u6476\u6477\u6478\u6479\u647a\u647b\u647c\u647d\u647e\u647f\u6480\u6481\u6482\u6483\u6484\u6485\u6486\u6487\u6488\u6489\u648a\u648b\u648c\u648d\u648e\u648f\u6490\u6491\u6492\u6493\u6494\u6495\u6496\u6497\u6498\u6499\u649a\u649b\u649c\u649d\u649e\u649f\u64a0\u64a1\u64a2\u64a3\u64a4\u64a5\u64a6\u64a7\u64a8\u64a9\u64aa\u64ab\u64ac\u64ad\u64ae\u64af\u64b0\u64b1\u64b2\u64b3\u64b4\u64b5\u64b6\u64b7\u64b8\u64b9\u64ba\u64bb\u64bc\u64bd\u64be\u64bf\u64c0\u64c1\u64c2\u64c3\u64c4\u64c5\u64c6\u64c7\u64c8\u64c9\u64ca\u64cb\u64cc\u64cd\u64ce\u64cf\u64d0\u64d1\u64d2\u64d3\u64d4\u64d5\u64d6\u64d7\u64d8\u64d9\u64da\u64db\u64dc\u64dd\u64de\u64df\u64e0\u64e1\u64e2\u64e3\u64e4\u64e5\u64e6\u64e7\u64e8\u64e9\u64ea\u64eb\u64ec\u64ed\u64ee\u64ef\u64f0\u64f1\u64f2\u64f3\u64f4\u64f5\u64f6\u64f7\u64f8\u64f9\u64fa\u64fb\u64fc\u64fd\u64fe\u64ff\u6500\u6501\u6502\u6503\u6504\u6505\u6506\u6507\u6508\u6509\u650a\u650b\u650c\u650d\u650e\u650f\u6510\u6511\u6512\u6513\u6514\u6515\u6516\u6517\u6518\u6519\u651a\u651b\u651c\u651d\u651e\u651f\u6520\u6521\u6522\u6523\u6524\u6525\u6526\u6527\u6528\u6529\u652a\u652b\u652c\u652d\u652e\u652f\u6530\u6531\u6532\u6533\u6534\u6535\u6536\u6537\u6538\u6539\u653a\u653b\u653c\u653d\u653e\u653f\u6540\u6541\u6542\u6543\u6544\u6545\u6546\u6547\u6548\u6549\u654a\u654b\u654c\u654d\u654e\u654f\u6550\u6551\u6552\u6553\u6554\u6555\u6556\u6557\u6558\u6559\u655a\u655b\u655c\u655d\u655e\u655f\u6560\u6561\u6562\u6563\u6564\u6565\u6566\u6567\u6568\u6569\u656a\u656b\u656c\u656d\u656e\u656f\u6570\u6571\u6572\u6573\u6574\u6575\u6576\u6577\u6578\u6579\u657a\u657b\u657c\u657d\u657e\u657f\u6580\u6581\u6582\u6583\u6584\u6585\u6586\u6587\u6588\u6589\u658a\u658b\u658c\u658d\u658e\u658f\u6590\u6591\u6592\u6593\u6594\u6595\u6596\u6597\u6598\u6599\u659a\u659b\u659c\u659d\u659e\u659f\u65a0\u65a1\u65a2\u65a3\u65a4\u65a5\u65a6\u65a7\u65a8\u65a9\u65aa\u65ab\u65ac\u65ad\u65ae\u65af\u65b0\u65b1\u65b2\u65b3\u65b4\u65b5\u65b6\u65b7\u65b8\u65b9\u65ba\u65bb\u65bc\u65bd\u65be\u65bf\u65c0\u65c1\u65c2\u65c3\u65c4\u65c5\u65c6\u65c7\u65c8\u65c9\u65ca\u65cb\u65cc\u65cd\u65ce\u65cf\u65d0\u65d1\u65d2\u65d3\u65d4\u65d5\u65d6\u65d7\u65d8\u65d9\u65da\u65db\u65dc\u65dd\u65de\u65df\u65e0\u65e1\u65e2\u65e3\u65e4\u65e5\u65e6\u65e7\u65e8\u65e9\u65ea\u65eb\u65ec\u65ed\u65ee\u65ef\u65f0\u65f1\u65f2\u65f3\u65f4\u65f5\u65f6\u65f7\u65f8\u65f9\u65fa\u65fb\u65fc\u65fd\u65fe\u65ff\u6600\u6601\u6602\u6603\u6604\u6605\u6606\u6607\u6608\u6609\u660a\u660b\u660c\u660d\u660e\u660f\u6610\u6611\u6612\u6613\u6614\u6615\u6616\u6617\u6618\u6619\u661a\u661b\u661c\u661d\u661e\u661f\u6620\u6621\u6622\u6623\u6624\u6625\u6626\u6627\u6628\u6629\u662a\u662b\u662c\u662d\u662e\u662f\u6630\u6631\u6632\u6633\u6634\u6635\u6636\u6637\u6638\u6639\u663a\u663b\u663c\u663d\u663e\u663f\u6640\u6641\u6642\u6643\u6644\u6645\u6646\u6647\u6648\u6649\u664a\u664b\u664c\u664d\u664e\u664f\u6650\u6651\u6652\u6653\u6654\u6655\u6656\u6657\u6658\u6659\u665a\u665b\u665c\u665d\u665e\u665f\u6660\u6661\u6662\u6663\u6664\u6665\u6666\u6667\u6668\u6669\u666a\u666b\u666c\u666d\u666e\u666f\u6670\u6671\u6672\u6673\u6674\u6675\u6676\u6677\u6678\u6679\u667a\u667b\u667c\u667d\u667e\u667f\u6680\u6681\u6682\u6683\u6684\u6685\u6686\u6687\u6688\u6689\u668a\u668b\u668c\u668d\u668e\u668f\u6690\u6691\u6692\u6693\u6694\u6695\u6696\u6697\u6698\u6699\u669a\u669b\u669c\u669d\u669e\u669f\u66a0\u66a1\u66a2\u66a3\u66a4\u66a5\u66a6\u66a7\u66a8\u66a9\u66aa\u66ab\u66ac\u66ad\u66ae\u66af\u66b0\u66b1\u66b2\u66b3\u66b4\u66b5\u66b6\u66b7\u66b8\u66b9\u66ba\u66bb\u66bc\u66bd\u66be\u66bf\u66c0\u66c1\u66c2\u66c3\u66c4\u66c5\u66c6\u66c7\u66c8\u66c9\u66ca\u66cb\u66cc\u66cd\u66ce\u66cf\u66d0\u66d1\u66d2\u66d3\u66d4\u66d5\u66d6\u66d7\u66d8\u66d9\u66da\u66db\u66dc\u66dd\u66de\u66df\u66e0\u66e1\u66e2\u66e3\u66e4\u66e5\u66e6\u66e7\u66e8\u66e9\u66ea\u66eb\u66ec\u66ed\u66ee\u66ef\u66f0\u66f1\u66f2\u66f3\u66f4\u66f5\u66f6\u66f7\u66f8\u66f9\u66fa\u66fb\u66fc\u66fd\u66fe\u66ff\u6700\u6701\u6702\u6703\u6704\u6705\u6706\u6707\u6708\u6709\u670a\u670b\u670c\u670d\u670e\u670f\u6710\u6711\u6712\u6713\u6714\u6715\u6716\u6717\u6718\u6719\u671a\u671b\u671c\u671d\u671e\u671f\u6720\u6721\u6722\u6723\u6724\u6725\u6726\u6727\u6728\u6729\u672a\u672b\u672c\u672d\u672e\u672f\u6730\u6731\u6732\u6733\u6734\u6735\u6736\u6737\u6738\u6739\u673a\u673b\u673c\u673d\u673e\u673f\u6740\u6741\u6742\u6743\u6744\u6745\u6746\u6747\u6748\u6749\u674a\u674b\u674c\u674d\u674e\u674f\u6750\u6751\u6752\u6753\u6754\u6755\u6756\u6757\u6758\u6759\u675a\u675b\u675c\u675d\u675e\u675f\u6760\u6761\u6762\u6763\u6764\u6765\u6766\u6767\u6768\u6769\u676a\u676b\u676c\u676d\u676e\u676f\u6770\u6771\u6772\u6773\u6774\u6775\u6776\u6777\u6778\u6779\u677a\u677b\u677c\u677d\u677e\u677f\u6780\u6781\u6782\u6783\u6784\u6785\u6786\u6787\u6788\u6789\u678a\u678b\u678c\u678d\u678e\u678f\u6790\u6791\u6792\u6793\u6794\u6795\u6796\u6797\u6798\u6799\u679a\u679b\u679c\u679d\u679e\u679f\u67a0\u67a1\u67a2\u67a3\u67a4\u67a5\u67a6\u67a7\u67a8\u67a9\u67aa\u67ab\u67ac\u67ad\u67ae\u67af\u67b0\u67b1\u67b2\u67b3\u67b4\u67b5\u67b6\u67b7\u67b8\u67b9\u67ba\u67bb\u67bc\u67bd\u67be\u67bf\u67c0\u67c1\u67c2\u67c3\u67c4\u67c5\u67c6\u67c7\u67c8\u67c9\u67ca\u67cb\u67cc\u67cd\u67ce\u67cf\u67d0\u67d1\u67d2\u67d3\u67d4\u67d5\u67d6\u67d7\u67d8\u67d9\u67da\u67db\u67dc\u67dd\u67de\u67df\u67e0\u67e1\u67e2\u67e3\u67e4\u67e5\u67e6\u67e7\u67e8\u67e9\u67ea\u67eb\u67ec\u67ed\u67ee\u67ef\u67f0\u67f1\u67f2\u67f3\u67f4\u67f5\u67f6\u67f7\u67f8\u67f9\u67fa\u67fb\u67fc\u67fd\u67fe\u67ff\u6800\u6801\u6802\u6803\u6804\u6805\u6806\u6807\u6808\u6809\u680a\u680b\u680c\u680d\u680e\u680f\u6810\u6811\u6812\u6813\u6814\u6815\u6816\u6817\u6818\u6819\u681a\u681b\u681c\u681d\u681e\u681f\u6820\u6821\u6822\u6823\u6824\u6825\u6826\u6827\u6828\u6829\u682a\u682b\u682c\u682d\u682e\u682f\u6830\u6831\u6832\u6833\u6834\u6835\u6836\u6837\u6838\u6839\u683a\u683b\u683c\u683d\u683e\u683f\u6840\u6841\u6842\u6843\u6844\u6845\u6846\u6847\u6848\u6849\u684a\u684b\u684c\u684d\u684e\u684f\u6850\u6851\u6852\u6853\u6854\u6855\u6856\u6857\u6858\u6859\u685a\u685b\u685c\u685d\u685e\u685f\u6860\u6861\u6862\u6863\u6864\u6865\u6866\u6867\u6868\u6869\u686a\u686b\u686c\u686d\u686e\u686f\u6870\u6871\u6872\u6873\u6874\u6875\u6876\u6877\u6878\u6879\u687a\u687b\u687c\u687d\u687e\u687f\u6880\u6881\u6882\u6883\u6884\u6885\u6886\u6887\u6888\u6889\u688a\u688b\u688c\u688d\u688e\u688f\u6890\u6891\u6892\u6893\u6894\u6895\u6896\u6897\u6898\u6899\u689a\u689b\u689c\u689d\u689e\u689f\u68a0\u68a1\u68a2\u68a3\u68a4\u68a5\u68a6\u68a7\u68a8\u68a9\u68aa\u68ab\u68ac\u68ad\u68ae\u68af\u68b0\u68b1\u68b2\u68b3\u68b4\u68b5\u68b6\u68b7\u68b8\u68b9\u68ba\u68bb\u68bc\u68bd\u68be\u68bf\u68c0\u68c1\u68c2\u68c3\u68c4\u68c5\u68c6\u68c7\u68c8\u68c9\u68ca\u68cb\u68cc\u68cd\u68ce\u68cf\u68d0\u68d1\u68d2\u68d3\u68d4\u68d5\u68d6\u68d7\u68d8\u68d9\u68da\u68db\u68dc\u68dd\u68de\u68df\u68e0\u68e1\u68e2\u68e3\u68e4\u68e5\u68e6\u68e7\u68e8\u68e9\u68ea\u68eb\u68ec\u68ed\u68ee\u68ef\u68f0\u68f1\u68f2\u68f3\u68f4\u68f5\u68f6\u68f7\u68f8\u68f9\u68fa\u68fb\u68fc\u68fd\u68fe\u68ff\u6900\u6901\u6902\u6903\u6904\u6905\u6906\u6907\u6908\u6909\u690a\u690b\u690c\u690d\u690e\u690f\u6910\u6911\u6912\u6913\u6914\u6915\u6916\u6917\u6918\u6919\u691a\u691b\u691c\u691d\u691e\u691f\u6920\u6921\u6922\u6923\u6924\u6925\u6926\u6927\u6928\u6929\u692a\u692b\u692c\u692d\u692e\u692f\u6930\u6931\u6932\u6933\u6934\u6935\u6936\u6937\u6938\u6939\u693a\u693b\u693c\u693d\u693e\u693f\u6940\u6941\u6942\u6943\u6944\u6945\u6946\u6947\u6948\u6949\u694a\u694b\u694c\u694d\u694e\u694f\u6950\u6951\u6952\u6953\u6954\u6955\u6956\u6957\u6958\u6959\u695a\u695b\u695c\u695d\u695e\u695f\u6960\u6961\u6962\u6963\u6964\u6965\u6966\u6967\u6968\u6969\u696a\u696b\u696c\u696d\u696e\u696f\u6970\u6971\u6972\u6973\u6974\u6975\u6976\u6977\u6978\u6979\u697a\u697b\u697c\u697d\u697e\u697f\u6980\u6981\u6982\u6983\u6984\u6985\u6986\u6987\u6988\u6989\u698a\u698b\u698c\u698d\u698e\u698f\u6990\u6991\u6992\u6993\u6994\u6995\u6996\u6997\u6998\u6999\u699a\u699b\u699c\u699d\u699e\u699f\u69a0\u69a1\u69a2\u69a3\u69a4\u69a5\u69a6\u69a7\u69a8\u69a9\u69aa\u69ab\u69ac\u69ad\u69ae\u69af\u69b0\u69b1\u69b2\u69b3\u69b4\u69b5\u69b6\u69b7\u69b8\u69b9\u69ba\u69bb\u69bc\u69bd\u69be\u69bf\u69c0\u69c1\u69c2\u69c3\u69c4\u69c5\u69c6\u69c7\u69c8\u69c9\u69ca\u69cb\u69cc\u69cd\u69ce\u69cf\u69d0\u69d1\u69d2\u69d3\u69d4\u69d5\u69d6\u69d7\u69d8\u69d9\u69da\u69db\u69dc\u69dd\u69de\u69df\u69e0\u69e1\u69e2\u69e3\u69e4\u69e5\u69e6\u69e7\u69e8\u69e9\u69ea\u69eb\u69ec\u69ed\u69ee\u69ef\u69f0\u69f1\u69f2\u69f3\u69f4\u69f5\u69f6\u69f7\u69f8\u69f9\u69fa\u69fb\u69fc\u69fd\u69fe\u69ff\u6a00\u6a01\u6a02\u6a03\u6a04\u6a05\u6a06\u6a07\u6a08\u6a09\u6a0a\u6a0b\u6a0c\u6a0d\u6a0e\u6a0f\u6a10\u6a11\u6a12\u6a13\u6a14\u6a15\u6a16\u6a17\u6a18\u6a19\u6a1a\u6a1b\u6a1c\u6a1d\u6a1e\u6a1f\u6a20\u6a21\u6a22\u6a23\u6a24\u6a25\u6a26\u6a27\u6a28\u6a29\u6a2a\u6a2b\u6a2c\u6a2d\u6a2e\u6a2f\u6a30\u6a31\u6a32\u6a33\u6a34\u6a35\u6a36\u6a37\u6a38\u6a39\u6a3a\u6a3b\u6a3c\u6a3d\u6a3e\u6a3f\u6a40\u6a41\u6a42\u6a43\u6a44\u6a45\u6a46\u6a47\u6a48\u6a49\u6a4a\u6a4b\u6a4c\u6a4d\u6a4e\u6a4f\u6a50\u6a51\u6a52\u6a53\u6a54\u6a55\u6a56\u6a57\u6a58\u6a59\u6a5a\u6a5b\u6a5c\u6a5d\u6a5e\u6a5f\u6a60\u6a61\u6a62\u6a63\u6a64\u6a65\u6a66\u6a67\u6a68\u6a69\u6a6a\u6a6b\u6a6c\u6a6d\u6a6e\u6a6f\u6a70\u6a71\u6a72\u6a73\u6a74\u6a75\u6a76\u6a77\u6a78\u6a79\u6a7a\u6a7b\u6a7c\u6a7d\u6a7e\u6a7f\u6a80\u6a81\u6a82\u6a83\u6a84\u6a85\u6a86\u6a87\u6a88\u6a89\u6a8a\u6a8b\u6a8c\u6a8d\u6a8e\u6a8f\u6a90\u6a91\u6a92\u6a93\u6a94\u6a95\u6a96\u6a97\u6a98\u6a99\u6a9a\u6a9b\u6a9c\u6a9d\u6a9e\u6a9f\u6aa0\u6aa1\u6aa2\u6aa3\u6aa4\u6aa5\u6aa6\u6aa7\u6aa8\u6aa9\u6aaa\u6aab\u6aac\u6aad\u6aae\u6aaf\u6ab0\u6ab1\u6ab2\u6ab3\u6ab4\u6ab5\u6ab6\u6ab7\u6ab8\u6ab9\u6aba\u6abb\u6abc\u6abd\u6abe\u6abf\u6ac0\u6ac1\u6ac2\u6ac3\u6ac4\u6ac5\u6ac6\u6ac7\u6ac8\u6ac9\u6aca\u6acb\u6acc\u6acd\u6ace\u6acf\u6ad0\u6ad1\u6ad2\u6ad3\u6ad4\u6ad5\u6ad6\u6ad7\u6ad8\u6ad9\u6ada\u6adb\u6adc\u6add\u6ade\u6adf\u6ae0\u6ae1\u6ae2\u6ae3\u6ae4\u6ae5\u6ae6\u6ae7\u6ae8\u6ae9\u6aea\u6aeb\u6aec\u6aed\u6aee\u6aef\u6af0\u6af1\u6af2\u6af3\u6af4\u6af5\u6af6\u6af7\u6af8\u6af9\u6afa\u6afb\u6afc\u6afd\u6afe\u6aff\u6b00\u6b01\u6b02\u6b03\u6b04\u6b05\u6b06\u6b07\u6b08\u6b09\u6b0a\u6b0b\u6b0c\u6b0d\u6b0e\u6b0f\u6b10\u6b11\u6b12\u6b13\u6b14\u6b15\u6b16\u6b17\u6b18\u6b19\u6b1a\u6b1b\u6b1c\u6b1d\u6b1e\u6b1f\u6b20\u6b21\u6b22\u6b23\u6b24\u6b25\u6b26\u6b27\u6b28\u6b29\u6b2a\u6b2b\u6b2c\u6b2d\u6b2e\u6b2f\u6b30\u6b31\u6b32\u6b33\u6b34\u6b35\u6b36\u6b37\u6b38\u6b39\u6b3a\u6b3b\u6b3c\u6b3d\u6b3e\u6b3f\u6b40\u6b41\u6b42\u6b43\u6b44\u6b45\u6b46\u6b47\u6b48\u6b49\u6b4a\u6b4b\u6b4c\u6b4d\u6b4e\u6b4f\u6b50\u6b51\u6b52\u6b53\u6b54\u6b55\u6b56\u6b57\u6b58\u6b59\u6b5a\u6b5b\u6b5c\u6b5d\u6b5e\u6b5f\u6b60\u6b61\u6b62\u6b63\u6b64\u6b65\u6b66\u6b67\u6b68\u6b69\u6b6a\u6b6b\u6b6c\u6b6d\u6b6e\u6b6f\u6b70\u6b71\u6b72\u6b73\u6b74\u6b75\u6b76\u6b77\u6b78\u6b79\u6b7a\u6b7b\u6b7c\u6b7d\u6b7e\u6b7f\u6b80\u6b81\u6b82\u6b83\u6b84\u6b85\u6b86\u6b87\u6b88\u6b89\u6b8a\u6b8b\u6b8c\u6b8d\u6b8e\u6b8f\u6b90\u6b91\u6b92\u6b93\u6b94\u6b95\u6b96\u6b97\u6b98\u6b99\u6b9a\u6b9b\u6b9c\u6b9d\u6b9e\u6b9f\u6ba0\u6ba1\u6ba2\u6ba3\u6ba4\u6ba5\u6ba6\u6ba7\u6ba8\u6ba9\u6baa\u6bab\u6bac\u6bad\u6bae\u6baf\u6bb0\u6bb1\u6bb2\u6bb3\u6bb4\u6bb5\u6bb6\u6bb7\u6bb8\u6bb9\u6bba\u6bbb\u6bbc\u6bbd\u6bbe\u6bbf\u6bc0\u6bc1\u6bc2\u6bc3\u6bc4\u6bc5\u6bc6\u6bc7\u6bc8\u6bc9\u6bca\u6bcb\u6bcc\u6bcd\u6bce\u6bcf\u6bd0\u6bd1\u6bd2\u6bd3\u6bd4\u6bd5\u6bd6\u6bd7\u6bd8\u6bd9\u6bda\u6bdb\u6bdc\u6bdd\u6bde\u6bdf\u6be0\u6be1\u6be2\u6be3\u6be4\u6be5\u6be6\u6be7\u6be8\u6be9\u6bea\u6beb\u6bec\u6bed\u6bee\u6bef\u6bf0\u6bf1\u6bf2\u6bf3\u6bf4\u6bf5\u6bf6\u6bf7\u6bf8\u6bf9\u6bfa\u6bfb\u6bfc\u6bfd\u6bfe\u6bff\u6c00\u6c01\u6c02\u6c03\u6c04\u6c05\u6c06\u6c07\u6c08\u6c09\u6c0a\u6c0b\u6c0c\u6c0d\u6c0e\u6c0f\u6c10\u6c11\u6c12\u6c13\u6c14\u6c15\u6c16\u6c17\u6c18\u6c19\u6c1a\u6c1b\u6c1c\u6c1d\u6c1e\u6c1f\u6c20\u6c21\u6c22\u6c23\u6c24\u6c25\u6c26\u6c27\u6c28\u6c29\u6c2a\u6c2b\u6c2c\u6c2d\u6c2e\u6c2f\u6c30\u6c31\u6c32\u6c33\u6c34\u6c35\u6c36\u6c37\u6c38\u6c39\u6c3a\u6c3b\u6c3c\u6c3d\u6c3e\u6c3f\u6c40\u6c41\u6c42\u6c43\u6c44\u6c45\u6c46\u6c47\u6c48\u6c49\u6c4a\u6c4b\u6c4c\u6c4d\u6c4e\u6c4f\u6c50\u6c51\u6c52\u6c53\u6c54\u6c55\u6c56\u6c57\u6c58\u6c59\u6c5a\u6c5b\u6c5c\u6c5d\u6c5e\u6c5f\u6c60\u6c61\u6c62\u6c63\u6c64\u6c65\u6c66\u6c67\u6c68\u6c69\u6c6a\u6c6b\u6c6c\u6c6d\u6c6e\u6c6f\u6c70\u6c71\u6c72\u6c73\u6c74\u6c75\u6c76\u6c77\u6c78\u6c79\u6c7a\u6c7b\u6c7c\u6c7d\u6c7e\u6c7f\u6c80\u6c81\u6c82\u6c83\u6c84\u6c85\u6c86\u6c87\u6c88\u6c89\u6c8a\u6c8b\u6c8c\u6c8d\u6c8e\u6c8f\u6c90\u6c91\u6c92\u6c93\u6c94\u6c95\u6c96\u6c97\u6c98\u6c99\u6c9a\u6c9b\u6c9c\u6c9d\u6c9e\u6c9f\u6ca0\u6ca1\u6ca2\u6ca3\u6ca4\u6ca5\u6ca6\u6ca7\u6ca8\u6ca9\u6caa\u6cab\u6cac\u6cad\u6cae\u6caf\u6cb0\u6cb1\u6cb2\u6cb3\u6cb4\u6cb5\u6cb6\u6cb7\u6cb8\u6cb9\u6cba\u6cbb\u6cbc\u6cbd\u6cbe\u6cbf\u6cc0\u6cc1\u6cc2\u6cc3\u6cc4\u6cc5\u6cc6\u6cc7\u6cc8\u6cc9\u6cca\u6ccb\u6ccc\u6ccd\u6cce\u6ccf\u6cd0\u6cd1\u6cd2\u6cd3\u6cd4\u6cd5\u6cd6\u6cd7\u6cd8\u6cd9\u6cda\u6cdb\u6cdc\u6cdd\u6cde\u6cdf\u6ce0\u6ce1\u6ce2\u6ce3\u6ce4\u6ce5\u6ce6\u6ce7\u6ce8\u6ce9\u6cea\u6ceb\u6cec\u6ced\u6cee\u6cef\u6cf0\u6cf1\u6cf2\u6cf3\u6cf4\u6cf5\u6cf6\u6cf7\u6cf8\u6cf9\u6cfa\u6cfb\u6cfc\u6cfd\u6cfe\u6cff\u6d00\u6d01\u6d02\u6d03\u6d04\u6d05\u6d06\u6d07\u6d08\u6d09\u6d0a\u6d0b\u6d0c\u6d0d\u6d0e\u6d0f\u6d10\u6d11\u6d12\u6d13\u6d14\u6d15\u6d16\u6d17\u6d18\u6d19\u6d1a\u6d1b\u6d1c\u6d1d\u6d1e\u6d1f\u6d20\u6d21\u6d22\u6d23\u6d24\u6d25\u6d26\u6d27\u6d28\u6d29\u6d2a\u6d2b\u6d2c\u6d2d\u6d2e\u6d2f\u6d30\u6d31\u6d32\u6d33\u6d34\u6d35\u6d36\u6d37\u6d38\u6d39\u6d3a\u6d3b\u6d3c\u6d3d\u6d3e\u6d3f\u6d40\u6d41\u6d42\u6d43\u6d44\u6d45\u6d46\u6d47\u6d48\u6d49\u6d4a\u6d4b\u6d4c\u6d4d\u6d4e\u6d4f\u6d50\u6d51\u6d52\u6d53\u6d54\u6d55\u6d56\u6d57\u6d58\u6d59\u6d5a\u6d5b\u6d5c\u6d5d\u6d5e\u6d5f\u6d60\u6d61\u6d62\u6d63\u6d64\u6d65\u6d66\u6d67\u6d68\u6d69\u6d6a\u6d6b\u6d6c\u6d6d\u6d6e\u6d6f\u6d70\u6d71\u6d72\u6d73\u6d74\u6d75\u6d76\u6d77\u6d78\u6d79\u6d7a\u6d7b\u6d7c\u6d7d\u6d7e\u6d7f\u6d80\u6d81\u6d82\u6d83\u6d84\u6d85\u6d86\u6d87\u6d88\u6d89\u6d8a\u6d8b\u6d8c\u6d8d\u6d8e\u6d8f\u6d90\u6d91\u6d92\u6d93\u6d94\u6d95\u6d96\u6d97\u6d98\u6d99\u6d9a\u6d9b\u6d9c\u6d9d\u6d9e\u6d9f\u6da0\u6da1\u6da2\u6da3\u6da4\u6da5\u6da6\u6da7\u6da8\u6da9\u6daa\u6dab\u6dac\u6dad\u6dae\u6daf\u6db0\u6db1\u6db2\u6db3\u6db4\u6db5\u6db6\u6db7\u6db8\u6db9\u6dba\u6dbb\u6dbc\u6dbd\u6dbe\u6dbf\u6dc0\u6dc1\u6dc2\u6dc3\u6dc4\u6dc5\u6dc6\u6dc7\u6dc8\u6dc9\u6dca\u6dcb\u6dcc\u6dcd\u6dce\u6dcf\u6dd0\u6dd1\u6dd2\u6dd3\u6dd4\u6dd5\u6dd6\u6dd7\u6dd8\u6dd9\u6dda\u6ddb\u6ddc\u6ddd\u6dde\u6ddf\u6de0\u6de1\u6de2\u6de3\u6de4\u6de5\u6de6\u6de7\u6de8\u6de9\u6dea\u6deb\u6dec\u6ded\u6dee\u6def\u6df0\u6df1\u6df2\u6df3\u6df4\u6df5\u6df6\u6df7\u6df8\u6df9\u6dfa\u6dfb\u6dfc\u6dfd\u6dfe\u6dff\u6e00\u6e01\u6e02\u6e03\u6e04\u6e05\u6e06\u6e07\u6e08\u6e09\u6e0a\u6e0b\u6e0c\u6e0d\u6e0e\u6e0f\u6e10\u6e11\u6e12\u6e13\u6e14\u6e15\u6e16\u6e17\u6e18\u6e19\u6e1a\u6e1b\u6e1c\u6e1d\u6e1e\u6e1f\u6e20\u6e21\u6e22\u6e23\u6e24\u6e25\u6e26\u6e27\u6e28\u6e29\u6e2a\u6e2b\u6e2c\u6e2d\u6e2e\u6e2f\u6e30\u6e31\u6e32\u6e33\u6e34\u6e35\u6e36\u6e37\u6e38\u6e39\u6e3a\u6e3b\u6e3c\u6e3d\u6e3e\u6e3f\u6e40\u6e41\u6e42\u6e43\u6e44\u6e45\u6e46\u6e47\u6e48\u6e49\u6e4a\u6e4b\u6e4c\u6e4d\u6e4e\u6e4f\u6e50\u6e51\u6e52\u6e53\u6e54\u6e55\u6e56\u6e57\u6e58\u6e59\u6e5a\u6e5b\u6e5c\u6e5d\u6e5e\u6e5f\u6e60\u6e61\u6e62\u6e63\u6e64\u6e65\u6e66\u6e67\u6e68\u6e69\u6e6a\u6e6b\u6e6c\u6e6d\u6e6e\u6e6f\u6e70\u6e71\u6e72\u6e73\u6e74\u6e75\u6e76\u6e77\u6e78\u6e79\u6e7a\u6e7b\u6e7c\u6e7d\u6e7e\u6e7f\u6e80\u6e81\u6e82\u6e83\u6e84\u6e85\u6e86\u6e87\u6e88\u6e89\u6e8a\u6e8b\u6e8c\u6e8d\u6e8e\u6e8f\u6e90\u6e91\u6e92\u6e93\u6e94\u6e95\u6e96\u6e97\u6e98\u6e99\u6e9a\u6e9b\u6e9c\u6e9d\u6e9e\u6e9f\u6ea0\u6ea1\u6ea2\u6ea3\u6ea4\u6ea5\u6ea6\u6ea7\u6ea8\u6ea9\u6eaa\u6eab\u6eac\u6ead\u6eae\u6eaf\u6eb0\u6eb1\u6eb2\u6eb3\u6eb4\u6eb5\u6eb6\u6eb7\u6eb8\u6eb9\u6eba\u6ebb\u6ebc\u6ebd\u6ebe\u6ebf\u6ec0\u6ec1\u6ec2\u6ec3\u6ec4\u6ec5\u6ec6\u6ec7\u6ec8\u6ec9\u6eca\u6ecb\u6ecc\u6ecd\u6ece\u6ecf\u6ed0\u6ed1\u6ed2\u6ed3\u6ed4\u6ed5\u6ed6\u6ed7\u6ed8\u6ed9\u6eda\u6edb\u6edc\u6edd\u6ede\u6edf\u6ee0\u6ee1\u6ee2\u6ee3\u6ee4\u6ee5\u6ee6\u6ee7\u6ee8\u6ee9\u6eea\u6eeb\u6eec\u6eed\u6eee\u6eef\u6ef0\u6ef1\u6ef2\u6ef3\u6ef4\u6ef5\u6ef6\u6ef7\u6ef8\u6ef9\u6efa\u6efb\u6efc\u6efd\u6efe\u6eff\u6f00\u6f01\u6f02\u6f03\u6f04\u6f05\u6f06\u6f07\u6f08\u6f09\u6f0a\u6f0b\u6f0c\u6f0d\u6f0e\u6f0f\u6f10\u6f11\u6f12\u6f13\u6f14\u6f15\u6f16\u6f17\u6f18\u6f19\u6f1a\u6f1b\u6f1c\u6f1d\u6f1e\u6f1f\u6f20\u6f21\u6f22\u6f23\u6f24\u6f25\u6f26\u6f27\u6f28\u6f29\u6f2a\u6f2b\u6f2c\u6f2d\u6f2e\u6f2f\u6f30\u6f31\u6f32\u6f33\u6f34\u6f35\u6f36\u6f37\u6f38\u6f39\u6f3a\u6f3b\u6f3c\u6f3d\u6f3e\u6f3f\u6f40\u6f41\u6f42\u6f43\u6f44\u6f45\u6f46\u6f47\u6f48\u6f49\u6f4a\u6f4b\u6f4c\u6f4d\u6f4e\u6f4f\u6f50\u6f51\u6f52\u6f53\u6f54\u6f55\u6f56\u6f57\u6f58\u6f59\u6f5a\u6f5b\u6f5c\u6f5d\u6f5e\u6f5f\u6f60\u6f61\u6f62\u6f63\u6f64\u6f65\u6f66\u6f67\u6f68\u6f69\u6f6a\u6f6b\u6f6c\u6f6d\u6f6e\u6f6f\u6f70\u6f71\u6f72\u6f73\u6f74\u6f75\u6f76\u6f77\u6f78\u6f79\u6f7a\u6f7b\u6f7c\u6f7d\u6f7e\u6f7f\u6f80\u6f81\u6f82\u6f83\u6f84\u6f85\u6f86\u6f87\u6f88\u6f89\u6f8a\u6f8b\u6f8c\u6f8d\u6f8e\u6f8f\u6f90\u6f91\u6f92\u6f93\u6f94\u6f95\u6f96\u6f97\u6f98\u6f99\u6f9a\u6f9b\u6f9c\u6f9d\u6f9e\u6f9f\u6fa0\u6fa1\u6fa2\u6fa3\u6fa4\u6fa5\u6fa6\u6fa7\u6fa8\u6fa9\u6faa\u6fab\u6fac\u6fad\u6fae\u6faf\u6fb0\u6fb1\u6fb2\u6fb3\u6fb4\u6fb5\u6fb6\u6fb7\u6fb8\u6fb9\u6fba\u6fbb\u6fbc\u6fbd\u6fbe\u6fbf\u6fc0\u6fc1\u6fc2\u6fc3\u6fc4\u6fc5\u6fc6\u6fc7\u6fc8\u6fc9\u6fca\u6fcb\u6fcc\u6fcd\u6fce\u6fcf\u6fd0\u6fd1\u6fd2\u6fd3\u6fd4\u6fd5\u6fd6\u6fd7\u6fd8\u6fd9\u6fda\u6fdb\u6fdc\u6fdd\u6fde\u6fdf\u6fe0\u6fe1\u6fe2\u6fe3\u6fe4\u6fe5\u6fe6\u6fe7\u6fe8\u6fe9\u6fea\u6feb\u6fec\u6fed\u6fee\u6fef\u6ff0\u6ff1\u6ff2\u6ff3\u6ff4\u6ff5\u6ff6\u6ff7\u6ff8\u6ff9\u6ffa\u6ffb\u6ffc\u6ffd\u6ffe\u6fff\u7000\u7001\u7002\u7003\u7004\u7005\u7006\u7007\u7008\u7009\u700a\u700b\u700c\u700d\u700e\u700f\u7010\u7011\u7012\u7013\u7014\u7015\u7016\u7017\u7018\u7019\u701a\u701b\u701c\u701d\u701e\u701f\u7020\u7021\u7022\u7023\u7024\u7025\u7026\u7027\u7028\u7029\u702a\u702b\u702c\u702d\u702e\u702f\u7030\u7031\u7032\u7033\u7034\u7035\u7036\u7037\u7038\u7039\u703a\u703b\u703c\u703d\u703e\u703f\u7040\u7041\u7042\u7043\u7044\u7045\u7046\u7047\u7048\u7049\u704a\u704b\u704c\u704d\u704e\u704f\u7050\u7051\u7052\u7053\u7054\u7055\u7056\u7057\u7058\u7059\u705a\u705b\u705c\u705d\u705e\u705f\u7060\u7061\u7062\u7063\u7064\u7065\u7066\u7067\u7068\u7069\u706a\u706b\u706c\u706d\u706e\u706f\u7070\u7071\u7072\u7073\u7074\u7075\u7076\u7077\u7078\u7079\u707a\u707b\u707c\u707d\u707e\u707f\u7080\u7081\u7082\u7083\u7084\u7085\u7086\u7087\u7088\u7089\u708a\u708b\u708c\u708d\u708e\u708f\u7090\u7091\u7092\u7093\u7094\u7095\u7096\u7097\u7098\u7099\u709a\u709b\u709c\u709d\u709e\u709f\u70a0\u70a1\u70a2\u70a3\u70a4\u70a5\u70a6\u70a7\u70a8\u70a9\u70aa\u70ab\u70ac\u70ad\u70ae\u70af\u70b0\u70b1\u70b2\u70b3\u70b4\u70b5\u70b6\u70b7\u70b8\u70b9\u70ba\u70bb\u70bc\u70bd\u70be\u70bf\u70c0\u70c1\u70c2\u70c3\u70c4\u70c5\u70c6\u70c7\u70c8\u70c9\u70ca\u70cb\u70cc\u70cd\u70ce\u70cf\u70d0\u70d1\u70d2\u70d3\u70d4\u70d5\u70d6\u70d7\u70d8\u70d9\u70da\u70db\u70dc\u70dd\u70de\u70df\u70e0\u70e1\u70e2\u70e3\u70e4\u70e5\u70e6\u70e7\u70e8\u70e9\u70ea\u70eb\u70ec\u70ed\u70ee\u70ef\u70f0\u70f1\u70f2\u70f3\u70f4\u70f5\u70f6\u70f7\u70f8\u70f9\u70fa\u70fb\u70fc\u70fd\u70fe\u70ff\u7100\u7101\u7102\u7103\u7104\u7105\u7106\u7107\u7108\u7109\u710a\u710b\u710c\u710d\u710e\u710f\u7110\u7111\u7112\u7113\u7114\u7115\u7116\u7117\u7118\u7119\u711a\u711b\u711c\u711d\u711e\u711f\u7120\u7121\u7122\u7123\u7124\u7125\u7126\u7127\u7128\u7129\u712a\u712b\u712c\u712d\u712e\u712f\u7130\u7131\u7132\u7133\u7134\u7135\u7136\u7137\u7138\u7139\u713a\u713b\u713c\u713d\u713e\u713f\u7140\u7141\u7142\u7143\u7144\u7145\u7146\u7147\u7148\u7149\u714a\u714b\u714c\u714d\u714e\u714f\u7150\u7151\u7152\u7153\u7154\u7155\u7156\u7157\u7158\u7159\u715a\u715b\u715c\u715d\u715e\u715f\u7160\u7161\u7162\u7163\u7164\u7165\u7166\u7167\u7168\u7169\u716a\u716b\u716c\u716d\u716e\u716f\u7170\u7171\u7172\u7173\u7174\u7175\u7176\u7177\u7178\u7179\u717a\u717b\u717c\u717d\u717e\u717f\u7180\u7181\u7182\u7183\u7184\u7185\u7186\u7187\u7188\u7189\u718a\u718b\u718c\u718d\u718e\u718f\u7190\u7191\u7192\u7193\u7194\u7195\u7196\u7197\u7198\u7199\u719a\u719b\u719c\u719d\u719e\u719f\u71a0\u71a1\u71a2\u71a3\u71a4\u71a5\u71a6\u71a7\u71a8\u71a9\u71aa\u71ab\u71ac\u71ad\u71ae\u71af\u71b0\u71b1\u71b2\u71b3\u71b4\u71b5\u71b6\u71b7\u71b8\u71b9\u71ba\u71bb\u71bc\u71bd\u71be\u71bf\u71c0\u71c1\u71c2\u71c3\u71c4\u71c5\u71c6\u71c7\u71c8\u71c9\u71ca\u71cb\u71cc\u71cd\u71ce\u71cf\u71d0\u71d1\u71d2\u71d3\u71d4\u71d5\u71d6\u71d7\u71d8\u71d9\u71da\u71db\u71dc\u71dd\u71de\u71df\u71e0\u71e1\u71e2\u71e3\u71e4\u71e5\u71e6\u71e7\u71e8\u71e9\u71ea\u71eb\u71ec\u71ed\u71ee\u71ef\u71f0\u71f1\u71f2\u71f3\u71f4\u71f5\u71f6\u71f7\u71f8\u71f9\u71fa\u71fb\u71fc\u71fd\u71fe\u71ff\u7200\u7201\u7202\u7203\u7204\u7205\u7206\u7207\u7208\u7209\u720a\u720b\u720c\u720d\u720e\u720f\u7210\u7211\u7212\u7213\u7214\u7215\u7216\u7217\u7218\u7219\u721a\u721b\u721c\u721d\u721e\u721f\u7220\u7221\u7222\u7223\u7224\u7225\u7226\u7227\u7228\u7229\u722a\u722b\u722c\u722d\u722e\u722f\u7230\u7231\u7232\u7233\u7234\u7235\u7236\u7237\u7238\u7239\u723a\u723b\u723c\u723d\u723e\u723f\u7240\u7241\u7242\u7243\u7244\u7245\u7246\u7247\u7248\u7249\u724a\u724b\u724c\u724d\u724e\u724f\u7250\u7251\u7252\u7253\u7254\u7255\u7256\u7257\u7258\u7259\u725a\u725b\u725c\u725d\u725e\u725f\u7260\u7261\u7262\u7263\u7264\u7265\u7266\u7267\u7268\u7269\u726a\u726b\u726c\u726d\u726e\u726f\u7270\u7271\u7272\u7273\u7274\u7275\u7276\u7277\u7278\u7279\u727a\u727b\u727c\u727d\u727e\u727f\u7280\u7281\u7282\u7283\u7284\u7285\u7286\u7287\u7288\u7289\u728a\u728b\u728c\u728d\u728e\u728f\u7290\u7291\u7292\u7293\u7294\u7295\u7296\u7297\u7298\u7299\u729a\u729b\u729c\u729d\u729e\u729f\u72a0\u72a1\u72a2\u72a3\u72a4\u72a5\u72a6\u72a7\u72a8\u72a9\u72aa\u72ab\u72ac\u72ad\u72ae\u72af\u72b0\u72b1\u72b2\u72b3\u72b4\u72b5\u72b6\u72b7\u72b8\u72b9\u72ba\u72bb\u72bc\u72bd\u72be\u72bf\u72c0\u72c1\u72c2\u72c3\u72c4\u72c5\u72c6\u72c7\u72c8\u72c9\u72ca\u72cb\u72cc\u72cd\u72ce\u72cf\u72d0\u72d1\u72d2\u72d3\u72d4\u72d5\u72d6\u72d7\u72d8\u72d9\u72da\u72db\u72dc\u72dd\u72de\u72df\u72e0\u72e1\u72e2\u72e3\u72e4\u72e5\u72e6\u72e7\u72e8\u72e9\u72ea\u72eb\u72ec\u72ed\u72ee\u72ef\u72f0\u72f1\u72f2\u72f3\u72f4\u72f5\u72f6\u72f7\u72f8\u72f9\u72fa\u72fb\u72fc\u72fd\u72fe\u72ff\u7300\u7301\u7302\u7303\u7304\u7305\u7306\u7307\u7308\u7309\u730a\u730b\u730c\u730d\u730e\u730f\u7310\u7311\u7312\u7313\u7314\u7315\u7316\u7317\u7318\u7319\u731a\u731b\u731c\u731d\u731e\u731f\u7320\u7321\u7322\u7323\u7324\u7325\u7326\u7327\u7328\u7329\u732a\u732b\u732c\u732d\u732e\u732f\u7330\u7331\u7332\u7333\u7334\u7335\u7336\u7337\u7338\u7339\u733a\u733b\u733c\u733d\u733e\u733f\u7340\u7341\u7342\u7343\u7344\u7345\u7346\u7347\u7348\u7349\u734a\u734b\u734c\u734d\u734e\u734f\u7350\u7351\u7352\u7353\u7354\u7355\u7356\u7357\u7358\u7359\u735a\u735b\u735c\u735d\u735e\u735f\u7360\u7361\u7362\u7363\u7364\u7365\u7366\u7367\u7368\u7369\u736a\u736b\u736c\u736d\u736e\u736f\u7370\u7371\u7372\u7373\u7374\u7375\u7376\u7377\u7378\u7379\u737a\u737b\u737c\u737d\u737e\u737f\u7380\u7381\u7382\u7383\u7384\u7385\u7386\u7387\u7388\u7389\u738a\u738b\u738c\u738d\u738e\u738f\u7390\u7391\u7392\u7393\u7394\u7395\u7396\u7397\u7398\u7399\u739a\u739b\u739c\u739d\u739e\u739f\u73a0\u73a1\u73a2\u73a3\u73a4\u73a5\u73a6\u73a7\u73a8\u73a9\u73aa\u73ab\u73ac\u73ad\u73ae\u73af\u73b0\u73b1\u73b2\u73b3\u73b4\u73b5\u73b6\u73b7\u73b8\u73b9\u73ba\u73bb\u73bc\u73bd\u73be\u73bf\u73c0\u73c1\u73c2\u73c3\u73c4\u73c5\u73c6\u73c7\u73c8\u73c9\u73ca\u73cb\u73cc\u73cd\u73ce\u73cf\u73d0\u73d1\u73d2\u73d3\u73d4\u73d5\u73d6\u73d7\u73d8\u73d9\u73da\u73db\u73dc\u73dd\u73de\u73df\u73e0\u73e1\u73e2\u73e3\u73e4\u73e5\u73e6\u73e7\u73e8\u73e9\u73ea\u73eb\u73ec\u73ed\u73ee\u73ef\u73f0\u73f1\u73f2\u73f3\u73f4\u73f5\u73f6\u73f7\u73f8\u73f9\u73fa\u73fb\u73fc\u73fd\u73fe\u73ff\u7400\u7401\u7402\u7403\u7404\u7405\u7406\u7407\u7408\u7409\u740a\u740b\u740c\u740d\u740e\u740f\u7410\u7411\u7412\u7413\u7414\u7415\u7416\u7417\u7418\u7419\u741a\u741b\u741c\u741d\u741e\u741f\u7420\u7421\u7422\u7423\u7424\u7425\u7426\u7427\u7428\u7429\u742a\u742b\u742c\u742d\u742e\u742f\u7430\u7431\u7432\u7433\u7434\u7435\u7436\u7437\u7438\u7439\u743a\u743b\u743c\u743d\u743e\u743f\u7440\u7441\u7442\u7443\u7444\u7445\u7446\u7447\u7448\u7449\u744a\u744b\u744c\u744d\u744e\u744f\u7450\u7451\u7452\u7453\u7454\u7455\u7456\u7457\u7458\u7459\u745a\u745b\u745c\u745d\u745e\u745f\u7460\u7461\u7462\u7463\u7464\u7465\u7466\u7467\u7468\u7469\u746a\u746b\u746c\u746d\u746e\u746f\u7470\u7471\u7472\u7473\u7474\u7475\u7476\u7477\u7478\u7479\u747a\u747b\u747c\u747d\u747e\u747f\u7480\u7481\u7482\u7483\u7484\u7485\u7486\u7487\u7488\u7489\u748a\u748b\u748c\u748d\u748e\u748f\u7490\u7491\u7492\u7493\u7494\u7495\u7496\u7497\u7498\u7499\u749a\u749b\u749c\u749d\u749e\u749f\u74a0\u74a1\u74a2\u74a3\u74a4\u74a5\u74a6\u74a7\u74a8\u74a9\u74aa\u74ab\u74ac\u74ad\u74ae\u74af\u74b0\u74b1\u74b2\u74b3\u74b4\u74b5\u74b6\u74b7\u74b8\u74b9\u74ba\u74bb\u74bc\u74bd\u74be\u74bf\u74c0\u74c1\u74c2\u74c3\u74c4\u74c5\u74c6\u74c7\u74c8\u74c9\u74ca\u74cb\u74cc\u74cd\u74ce\u74cf\u74d0\u74d1\u74d2\u74d3\u74d4\u74d5\u74d6\u74d7\u74d8\u74d9\u74da\u74db\u74dc\u74dd\u74de\u74df\u74e0\u74e1\u74e2\u74e3\u74e4\u74e5\u74e6\u74e7\u74e8\u74e9\u74ea\u74eb\u74ec\u74ed\u74ee\u74ef\u74f0\u74f1\u74f2\u74f3\u74f4\u74f5\u74f6\u74f7\u74f8\u74f9\u74fa\u74fb\u74fc\u74fd\u74fe\u74ff\u7500\u7501\u7502\u7503\u7504\u7505\u7506\u7507\u7508\u7509\u750a\u750b\u750c\u750d\u750e\u750f\u7510\u7511\u7512\u7513\u7514\u7515\u7516\u7517\u7518\u7519\u751a\u751b\u751c\u751d\u751e\u751f\u7520\u7521\u7522\u7523\u7524\u7525\u7526\u7527\u7528\u7529\u752a\u752b\u752c\u752d\u752e\u752f\u7530\u7531\u7532\u7533\u7534\u7535\u7536\u7537\u7538\u7539\u753a\u753b\u753c\u753d\u753e\u753f\u7540\u7541\u7542\u7543\u7544\u7545\u7546\u7547\u7548\u7549\u754a\u754b\u754c\u754d\u754e\u754f\u7550\u7551\u7552\u7553\u7554\u7555\u7556\u7557\u7558\u7559\u755a\u755b\u755c\u755d\u755e\u755f\u7560\u7561\u7562\u7563\u7564\u7565\u7566\u7567\u7568\u7569\u756a\u756b\u756c\u756d\u756e\u756f\u7570\u7571\u7572\u7573\u7574\u7575\u7576\u7577\u7578\u7579\u757a\u757b\u757c\u757d\u757e\u757f\u7580\u7581\u7582\u7583\u7584\u7585\u7586\u7587\u7588\u7589\u758a\u758b\u758c\u758d\u758e\u758f\u7590\u7591\u7592\u7593\u7594\u7595\u7596\u7597\u7598\u7599\u759a\u759b\u759c\u759d\u759e\u759f\u75a0\u75a1\u75a2\u75a3\u75a4\u75a5\u75a6\u75a7\u75a8\u75a9\u75aa\u75ab\u75ac\u75ad\u75ae\u75af\u75b0\u75b1\u75b2\u75b3\u75b4\u75b5\u75b6\u75b7\u75b8\u75b9\u75ba\u75bb\u75bc\u75bd\u75be\u75bf\u75c0\u75c1\u75c2\u75c3\u75c4\u75c5\u75c6\u75c7\u75c8\u75c9\u75ca\u75cb\u75cc\u75cd\u75ce\u75cf\u75d0\u75d1\u75d2\u75d3\u75d4\u75d5\u75d6\u75d7\u75d8\u75d9\u75da\u75db\u75dc\u75dd\u75de\u75df\u75e0\u75e1\u75e2\u75e3\u75e4\u75e5\u75e6\u75e7\u75e8\u75e9\u75ea\u75eb\u75ec\u75ed\u75ee\u75ef\u75f0\u75f1\u75f2\u75f3\u75f4\u75f5\u75f6\u75f7\u75f8\u75f9\u75fa\u75fb\u75fc\u75fd\u75fe\u75ff\u7600\u7601\u7602\u7603\u7604\u7605\u7606\u7607\u7608\u7609\u760a\u760b\u760c\u760d\u760e\u760f\u7610\u7611\u7612\u7613\u7614\u7615\u7616\u7617\u7618\u7619\u761a\u761b\u761c\u761d\u761e\u761f\u7620\u7621\u7622\u7623\u7624\u7625\u7626\u7627\u7628\u7629\u762a\u762b\u762c\u762d\u762e\u762f\u7630\u7631\u7632\u7633\u7634\u7635\u7636\u7637\u7638\u7639\u763a\u763b\u763c\u763d\u763e\u763f\u7640\u7641\u7642\u7643\u7644\u7645\u7646\u7647\u7648\u7649\u764a\u764b\u764c\u764d\u764e\u764f\u7650\u7651\u7652\u7653\u7654\u7655\u7656\u7657\u7658\u7659\u765a\u765b\u765c\u765d\u765e\u765f\u7660\u7661\u7662\u7663\u7664\u7665\u7666\u7667\u7668\u7669\u766a\u766b\u766c\u766d\u766e\u766f\u7670\u7671\u7672\u7673\u7674\u7675\u7676\u7677\u7678\u7679\u767a\u767b\u767c\u767d\u767e\u767f\u7680\u7681\u7682\u7683\u7684\u7685\u7686\u7687\u7688\u7689\u768a\u768b\u768c\u768d\u768e\u768f\u7690\u7691\u7692\u7693\u7694\u7695\u7696\u7697\u7698\u7699\u769a\u769b\u769c\u769d\u769e\u769f\u76a0\u76a1\u76a2\u76a3\u76a4\u76a5\u76a6\u76a7\u76a8\u76a9\u76aa\u76ab\u76ac\u76ad\u76ae\u76af\u76b0\u76b1\u76b2\u76b3\u76b4\u76b5\u76b6\u76b7\u76b8\u76b9\u76ba\u76bb\u76bc\u76bd\u76be\u76bf\u76c0\u76c1\u76c2\u76c3\u76c4\u76c5\u76c6\u76c7\u76c8\u76c9\u76ca\u76cb\u76cc\u76cd\u76ce\u76cf\u76d0\u76d1\u76d2\u76d3\u76d4\u76d5\u76d6\u76d7\u76d8\u76d9\u76da\u76db\u76dc\u76dd\u76de\u76df\u76e0\u76e1\u76e2\u76e3\u76e4\u76e5\u76e6\u76e7\u76e8\u76e9\u76ea\u76eb\u76ec\u76ed\u76ee\u76ef\u76f0\u76f1\u76f2\u76f3\u76f4\u76f5\u76f6\u76f7\u76f8\u76f9\u76fa\u76fb\u76fc\u76fd\u76fe\u76ff\u7700\u7701\u7702\u7703\u7704\u7705\u7706\u7707\u7708\u7709\u770a\u770b\u770c\u770d\u770e\u770f\u7710\u7711\u7712\u7713\u7714\u7715\u7716\u7717\u7718\u7719\u771a\u771b\u771c\u771d\u771e\u771f\u7720\u7721\u7722\u7723\u7724\u7725\u7726\u7727\u7728\u7729\u772a\u772b\u772c\u772d\u772e\u772f\u7730\u7731\u7732\u7733\u7734\u7735\u7736\u7737\u7738\u7739\u773a\u773b\u773c\u773d\u773e\u773f\u7740\u7741\u7742\u7743\u7744\u7745\u7746\u7747\u7748\u7749\u774a\u774b\u774c\u774d\u774e\u774f\u7750\u7751\u7752\u7753\u7754\u7755\u7756\u7757\u7758\u7759\u775a\u775b\u775c\u775d\u775e\u775f\u7760\u7761\u7762\u7763\u7764\u7765\u7766\u7767\u7768\u7769\u776a\u776b\u776c\u776d\u776e\u776f\u7770\u7771\u7772\u7773\u7774\u7775\u7776\u7777\u7778\u7779\u777a\u777b\u777c\u777d\u777e\u777f\u7780\u7781\u7782\u7783\u7784\u7785\u7786\u7787\u7788\u7789\u778a\u778b\u778c\u778d\u778e\u778f\u7790\u7791\u7792\u7793\u7794\u7795\u7796\u7797\u7798\u7799\u779a\u779b\u779c\u779d\u779e\u779f\u77a0\u77a1\u77a2\u77a3\u77a4\u77a5\u77a6\u77a7\u77a8\u77a9\u77aa\u77ab\u77ac\u77ad\u77ae\u77af\u77b0\u77b1\u77b2\u77b3\u77b4\u77b5\u77b6\u77b7\u77b8\u77b9\u77ba\u77bb\u77bc\u77bd\u77be\u77bf\u77c0\u77c1\u77c2\u77c3\u77c4\u77c5\u77c6\u77c7\u77c8\u77c9\u77ca\u77cb\u77cc\u77cd\u77ce\u77cf\u77d0\u77d1\u77d2\u77d3\u77d4\u77d5\u77d6\u77d7\u77d8\u77d9\u77da\u77db\u77dc\u77dd\u77de\u77df\u77e0\u77e1\u77e2\u77e3\u77e4\u77e5\u77e6\u77e7\u77e8\u77e9\u77ea\u77eb\u77ec\u77ed\u77ee\u77ef\u77f0\u77f1\u77f2\u77f3\u77f4\u77f5\u77f6\u77f7\u77f8\u77f9\u77fa\u77fb\u77fc\u77fd\u77fe\u77ff\u7800\u7801\u7802\u7803\u7804\u7805\u7806\u7807\u7808\u7809\u780a\u780b\u780c\u780d\u780e\u780f\u7810\u7811\u7812\u7813\u7814\u7815\u7816\u7817\u7818\u7819\u781a\u781b\u781c\u781d\u781e\u781f\u7820\u7821\u7822\u7823\u7824\u7825\u7826\u7827\u7828\u7829\u782a\u782b\u782c\u782d\u782e\u782f\u7830\u7831\u7832\u7833\u7834\u7835\u7836\u7837\u7838\u7839\u783a\u783b\u783c\u783d\u783e\u783f\u7840\u7841\u7842\u7843\u7844\u7845\u7846\u7847\u7848\u7849\u784a\u784b\u784c\u784d\u784e\u784f\u7850\u7851\u7852\u7853\u7854\u7855\u7856\u7857\u7858\u7859\u785a\u785b\u785c\u785d\u785e\u785f\u7860\u7861\u7862\u7863\u7864\u7865\u7866\u7867\u7868\u7869\u786a\u786b\u786c\u786d\u786e\u786f\u7870\u7871\u7872\u7873\u7874\u7875\u7876\u7877\u7878\u7879\u787a\u787b\u787c\u787d\u787e\u787f\u7880\u7881\u7882\u7883\u7884\u7885\u7886\u7887\u7888\u7889\u788a\u788b\u788c\u788d\u788e\u788f\u7890\u7891\u7892\u7893\u7894\u7895\u7896\u7897\u7898\u7899\u789a\u789b\u789c\u789d\u789e\u789f\u78a0\u78a1\u78a2\u78a3\u78a4\u78a5\u78a6\u78a7\u78a8\u78a9\u78aa\u78ab\u78ac\u78ad\u78ae\u78af\u78b0\u78b1\u78b2\u78b3\u78b4\u78b5\u78b6\u78b7\u78b8\u78b9\u78ba\u78bb\u78bc\u78bd\u78be\u78bf\u78c0\u78c1\u78c2\u78c3\u78c4\u78c5\u78c6\u78c7\u78c8\u78c9\u78ca\u78cb\u78cc\u78cd\u78ce\u78cf\u78d0\u78d1\u78d2\u78d3\u78d4\u78d5\u78d6\u78d7\u78d8\u78d9\u78da\u78db\u78dc\u78dd\u78de\u78df\u78e0\u78e1\u78e2\u78e3\u78e4\u78e5\u78e6\u78e7\u78e8\u78e9\u78ea\u78eb\u78ec\u78ed\u78ee\u78ef\u78f0\u78f1\u78f2\u78f3\u78f4\u78f5\u78f6\u78f7\u78f8\u78f9\u78fa\u78fb\u78fc\u78fd\u78fe\u78ff\u7900\u7901\u7902\u7903\u7904\u7905\u7906\u7907\u7908\u7909\u790a\u790b\u790c\u790d\u790e\u790f\u7910\u7911\u7912\u7913\u7914\u7915\u7916\u7917\u7918\u7919\u791a\u791b\u791c\u791d\u791e\u791f\u7920\u7921\u7922\u7923\u7924\u7925\u7926\u7927\u7928\u7929\u792a\u792b\u792c\u792d\u792e\u792f\u7930\u7931\u7932\u7933\u7934\u7935\u7936\u7937\u7938\u7939\u793a\u793b\u793c\u793d\u793e\u793f\u7940\u7941\u7942\u7943\u7944\u7945\u7946\u7947\u7948\u7949\u794a\u794b\u794c\u794d\u794e\u794f\u7950\u7951\u7952\u7953\u7954\u7955\u7956\u7957\u7958\u7959\u795a\u795b\u795c\u795d\u795e\u795f\u7960\u7961\u7962\u7963\u7964\u7965\u7966\u7967\u7968\u7969\u796a\u796b\u796c\u796d\u796e\u796f\u7970\u7971\u7972\u7973\u7974\u7975\u7976\u7977\u7978\u7979\u797a\u797b\u797c\u797d\u797e\u797f\u7980\u7981\u7982\u7983\u7984\u7985\u7986\u7987\u7988\u7989\u798a\u798b\u798c\u798d\u798e\u798f\u7990\u7991\u7992\u7993\u7994\u7995\u7996\u7997\u7998\u7999\u799a\u799b\u799c\u799d\u799e\u799f\u79a0\u79a1\u79a2\u79a3\u79a4\u79a5\u79a6\u79a7\u79a8\u79a9\u79aa\u79ab\u79ac\u79ad\u79ae\u79af\u79b0\u79b1\u79b2\u79b3\u79b4\u79b5\u79b6\u79b7\u79b8\u79b9\u79ba\u79bb\u79bc\u79bd\u79be\u79bf\u79c0\u79c1\u79c2\u79c3\u79c4\u79c5\u79c6\u79c7\u79c8\u79c9\u79ca\u79cb\u79cc\u79cd\u79ce\u79cf\u79d0\u79d1\u79d2\u79d3\u79d4\u79d5\u79d6\u79d7\u79d8\u79d9\u79da\u79db\u79dc\u79dd\u79de\u79df\u79e0\u79e1\u79e2\u79e3\u79e4\u79e5\u79e6\u79e7\u79e8\u79e9\u79ea\u79eb\u79ec\u79ed\u79ee\u79ef\u79f0\u79f1\u79f2\u79f3\u79f4\u79f5\u79f6\u79f7\u79f8\u79f9\u79fa\u79fb\u79fc\u79fd\u79fe\u79ff\u7a00\u7a01\u7a02\u7a03\u7a04\u7a05\u7a06\u7a07\u7a08\u7a09\u7a0a\u7a0b\u7a0c\u7a0d\u7a0e\u7a0f\u7a10\u7a11\u7a12\u7a13\u7a14\u7a15\u7a16\u7a17\u7a18\u7a19\u7a1a\u7a1b\u7a1c\u7a1d\u7a1e\u7a1f\u7a20\u7a21\u7a22\u7a23\u7a24\u7a25\u7a26\u7a27\u7a28\u7a29\u7a2a\u7a2b\u7a2c\u7a2d\u7a2e\u7a2f\u7a30\u7a31\u7a32\u7a33\u7a34\u7a35\u7a36\u7a37\u7a38\u7a39\u7a3a\u7a3b\u7a3c\u7a3d\u7a3e\u7a3f\u7a40\u7a41\u7a42\u7a43\u7a44\u7a45\u7a46\u7a47\u7a48\u7a49\u7a4a\u7a4b\u7a4c\u7a4d\u7a4e\u7a4f\u7a50\u7a51\u7a52\u7a53\u7a54\u7a55\u7a56\u7a57\u7a58\u7a59\u7a5a\u7a5b\u7a5c\u7a5d\u7a5e\u7a5f\u7a60\u7a61\u7a62\u7a63\u7a64\u7a65\u7a66\u7a67\u7a68\u7a69\u7a6a\u7a6b\u7a6c\u7a6d\u7a6e\u7a6f\u7a70\u7a71\u7a72\u7a73\u7a74\u7a75\u7a76\u7a77\u7a78\u7a79\u7a7a\u7a7b\u7a7c\u7a7d\u7a7e\u7a7f\u7a80\u7a81\u7a82\u7a83\u7a84\u7a85\u7a86\u7a87\u7a88\u7a89\u7a8a\u7a8b\u7a8c\u7a8d\u7a8e\u7a8f\u7a90\u7a91\u7a92\u7a93\u7a94\u7a95\u7a96\u7a97\u7a98\u7a99\u7a9a\u7a9b\u7a9c\u7a9d\u7a9e\u7a9f\u7aa0\u7aa1\u7aa2\u7aa3\u7aa4\u7aa5\u7aa6\u7aa7\u7aa8\u7aa9\u7aaa\u7aab\u7aac\u7aad\u7aae\u7aaf\u7ab0\u7ab1\u7ab2\u7ab3\u7ab4\u7ab5\u7ab6\u7ab7\u7ab8\u7ab9\u7aba\u7abb\u7abc\u7abd\u7abe\u7abf\u7ac0\u7ac1\u7ac2\u7ac3\u7ac4\u7ac5\u7ac6\u7ac7\u7ac8\u7ac9\u7aca\u7acb\u7acc\u7acd\u7ace\u7acf\u7ad0\u7ad1\u7ad2\u7ad3\u7ad4\u7ad5\u7ad6\u7ad7\u7ad8\u7ad9\u7ada\u7adb\u7adc\u7add\u7ade\u7adf\u7ae0\u7ae1\u7ae2\u7ae3\u7ae4\u7ae5\u7ae6\u7ae7\u7ae8\u7ae9\u7aea\u7aeb\u7aec\u7aed\u7aee\u7aef\u7af0\u7af1\u7af2\u7af3\u7af4\u7af5\u7af6\u7af7\u7af8\u7af9\u7afa\u7afb\u7afc\u7afd\u7afe\u7aff\u7b00\u7b01\u7b02\u7b03\u7b04\u7b05\u7b06\u7b07\u7b08\u7b09\u7b0a\u7b0b\u7b0c\u7b0d\u7b0e\u7b0f\u7b10\u7b11\u7b12\u7b13\u7b14\u7b15\u7b16\u7b17\u7b18\u7b19\u7b1a\u7b1b\u7b1c\u7b1d\u7b1e\u7b1f\u7b20\u7b21\u7b22\u7b23\u7b24\u7b25\u7b26\u7b27\u7b28\u7b29\u7b2a\u7b2b\u7b2c\u7b2d\u7b2e\u7b2f\u7b30\u7b31\u7b32\u7b33\u7b34\u7b35\u7b36\u7b37\u7b38\u7b39\u7b3a\u7b3b\u7b3c\u7b3d\u7b3e\u7b3f\u7b40\u7b41\u7b42\u7b43\u7b44\u7b45\u7b46\u7b47\u7b48\u7b49\u7b4a\u7b4b\u7b4c\u7b4d\u7b4e\u7b4f\u7b50\u7b51\u7b52\u7b53\u7b54\u7b55\u7b56\u7b57\u7b58\u7b59\u7b5a\u7b5b\u7b5c\u7b5d\u7b5e\u7b5f\u7b60\u7b61\u7b62\u7b63\u7b64\u7b65\u7b66\u7b67\u7b68\u7b69\u7b6a\u7b6b\u7b6c\u7b6d\u7b6e\u7b6f\u7b70\u7b71\u7b72\u7b73\u7b74\u7b75\u7b76\u7b77\u7b78\u7b79\u7b7a\u7b7b\u7b7c\u7b7d\u7b7e\u7b7f\u7b80\u7b81\u7b82\u7b83\u7b84\u7b85\u7b86\u7b87\u7b88\u7b89\u7b8a\u7b8b\u7b8c\u7b8d\u7b8e\u7b8f\u7b90\u7b91\u7b92\u7b93\u7b94\u7b95\u7b96\u7b97\u7b98\u7b99\u7b9a\u7b9b\u7b9c\u7b9d\u7b9e\u7b9f\u7ba0\u7ba1\u7ba2\u7ba3\u7ba4\u7ba5\u7ba6\u7ba7\u7ba8\u7ba9\u7baa\u7bab\u7bac\u7bad\u7bae\u7baf\u7bb0\u7bb1\u7bb2\u7bb3\u7bb4\u7bb5\u7bb6\u7bb7\u7bb8\u7bb9\u7bba\u7bbb\u7bbc\u7bbd\u7bbe\u7bbf\u7bc0\u7bc1\u7bc2\u7bc3\u7bc4\u7bc5\u7bc6\u7bc7\u7bc8\u7bc9\u7bca\u7bcb\u7bcc\u7bcd\u7bce\u7bcf\u7bd0\u7bd1\u7bd2\u7bd3\u7bd4\u7bd5\u7bd6\u7bd7\u7bd8\u7bd9\u7bda\u7bdb\u7bdc\u7bdd\u7bde\u7bdf\u7be0\u7be1\u7be2\u7be3\u7be4\u7be5\u7be6\u7be7\u7be8\u7be9\u7bea\u7beb\u7bec\u7bed\u7bee\u7bef\u7bf0\u7bf1\u7bf2\u7bf3\u7bf4\u7bf5\u7bf6\u7bf7\u7bf8\u7bf9\u7bfa\u7bfb\u7bfc\u7bfd\u7bfe\u7bff\u7c00\u7c01\u7c02\u7c03\u7c04\u7c05\u7c06\u7c07\u7c08\u7c09\u7c0a\u7c0b\u7c0c\u7c0d\u7c0e\u7c0f\u7c10\u7c11\u7c12\u7c13\u7c14\u7c15\u7c16\u7c17\u7c18\u7c19\u7c1a\u7c1b\u7c1c\u7c1d\u7c1e\u7c1f\u7c20\u7c21\u7c22\u7c23\u7c24\u7c25\u7c26\u7c27\u7c28\u7c29\u7c2a\u7c2b\u7c2c\u7c2d\u7c2e\u7c2f\u7c30\u7c31\u7c32\u7c33\u7c34\u7c35\u7c36\u7c37\u7c38\u7c39\u7c3a\u7c3b\u7c3c\u7c3d\u7c3e\u7c3f\u7c40\u7c41\u7c42\u7c43\u7c44\u7c45\u7c46\u7c47\u7c48\u7c49\u7c4a\u7c4b\u7c4c\u7c4d\u7c4e\u7c4f\u7c50\u7c51\u7c52\u7c53\u7c54\u7c55\u7c56\u7c57\u7c58\u7c59\u7c5a\u7c5b\u7c5c\u7c5d\u7c5e\u7c5f\u7c60\u7c61\u7c62\u7c63\u7c64\u7c65\u7c66\u7c67\u7c68\u7c69\u7c6a\u7c6b\u7c6c\u7c6d\u7c6e\u7c6f\u7c70\u7c71\u7c72\u7c73\u7c74\u7c75\u7c76\u7c77\u7c78\u7c79\u7c7a\u7c7b\u7c7c\u7c7d\u7c7e\u7c7f\u7c80\u7c81\u7c82\u7c83\u7c84\u7c85\u7c86\u7c87\u7c88\u7c89\u7c8a\u7c8b\u7c8c\u7c8d\u7c8e\u7c8f\u7c90\u7c91\u7c92\u7c93\u7c94\u7c95\u7c96\u7c97\u7c98\u7c99\u7c9a\u7c9b\u7c9c\u7c9d\u7c9e\u7c9f\u7ca0\u7ca1\u7ca2\u7ca3\u7ca4\u7ca5\u7ca6\u7ca7\u7ca8\u7ca9\u7caa\u7cab\u7cac\u7cad\u7cae\u7caf\u7cb0\u7cb1\u7cb2\u7cb3\u7cb4\u7cb5\u7cb6\u7cb7\u7cb8\u7cb9\u7cba\u7cbb\u7cbc\u7cbd\u7cbe\u7cbf\u7cc0\u7cc1\u7cc2\u7cc3\u7cc4\u7cc5\u7cc6\u7cc7\u7cc8\u7cc9\u7cca\u7ccb\u7ccc\u7ccd\u7cce\u7ccf\u7cd0\u7cd1\u7cd2\u7cd3\u7cd4\u7cd5\u7cd6\u7cd7\u7cd8\u7cd9\u7cda\u7cdb\u7cdc\u7cdd\u7cde\u7cdf\u7ce0\u7ce1\u7ce2\u7ce3\u7ce4\u7ce5\u7ce6\u7ce7\u7ce8\u7ce9\u7cea\u7ceb\u7cec\u7ced\u7cee\u7cef\u7cf0\u7cf1\u7cf2\u7cf3\u7cf4\u7cf5\u7cf6\u7cf7\u7cf8\u7cf9\u7cfa\u7cfb\u7cfc\u7cfd\u7cfe\u7cff\u7d00\u7d01\u7d02\u7d03\u7d04\u7d05\u7d06\u7d07\u7d08\u7d09\u7d0a\u7d0b\u7d0c\u7d0d\u7d0e\u7d0f\u7d10\u7d11\u7d12\u7d13\u7d14\u7d15\u7d16\u7d17\u7d18\u7d19\u7d1a\u7d1b\u7d1c\u7d1d\u7d1e\u7d1f\u7d20\u7d21\u7d22\u7d23\u7d24\u7d25\u7d26\u7d27\u7d28\u7d29\u7d2a\u7d2b\u7d2c\u7d2d\u7d2e\u7d2f\u7d30\u7d31\u7d32\u7d33\u7d34\u7d35\u7d36\u7d37\u7d38\u7d39\u7d3a\u7d3b\u7d3c\u7d3d\u7d3e\u7d3f\u7d40\u7d41\u7d42\u7d43\u7d44\u7d45\u7d46\u7d47\u7d48\u7d49\u7d4a\u7d4b\u7d4c\u7d4d\u7d4e\u7d4f\u7d50\u7d51\u7d52\u7d53\u7d54\u7d55\u7d56\u7d57\u7d58\u7d59\u7d5a\u7d5b\u7d5c\u7d5d\u7d5e\u7d5f\u7d60\u7d61\u7d62\u7d63\u7d64\u7d65\u7d66\u7d67\u7d68\u7d69\u7d6a\u7d6b\u7d6c\u7d6d\u7d6e\u7d6f\u7d70\u7d71\u7d72\u7d73\u7d74\u7d75\u7d76\u7d77\u7d78\u7d79\u7d7a\u7d7b\u7d7c\u7d7d\u7d7e\u7d7f\u7d80\u7d81\u7d82\u7d83\u7d84\u7d85\u7d86\u7d87\u7d88\u7d89\u7d8a\u7d8b\u7d8c\u7d8d\u7d8e\u7d8f\u7d90\u7d91\u7d92\u7d93\u7d94\u7d95\u7d96\u7d97\u7d98\u7d99\u7d9a\u7d9b\u7d9c\u7d9d\u7d9e\u7d9f\u7da0\u7da1\u7da2\u7da3\u7da4\u7da5\u7da6\u7da7\u7da8\u7da9\u7daa\u7dab\u7dac\u7dad\u7dae\u7daf\u7db0\u7db1\u7db2\u7db3\u7db4\u7db5\u7db6\u7db7\u7db8\u7db9\u7dba\u7dbb\u7dbc\u7dbd\u7dbe\u7dbf\u7dc0\u7dc1\u7dc2\u7dc3\u7dc4\u7dc5\u7dc6\u7dc7\u7dc8\u7dc9\u7dca\u7dcb\u7dcc\u7dcd\u7dce\u7dcf\u7dd0\u7dd1\u7dd2\u7dd3\u7dd4\u7dd5\u7dd6\u7dd7\u7dd8\u7dd9\u7dda\u7ddb\u7ddc\u7ddd\u7dde\u7ddf\u7de0\u7de1\u7de2\u7de3\u7de4\u7de5\u7de6\u7de7\u7de8\u7de9\u7dea\u7deb\u7dec\u7ded\u7dee\u7def\u7df0\u7df1\u7df2\u7df3\u7df4\u7df5\u7df6\u7df7\u7df8\u7df9\u7dfa\u7dfb\u7dfc\u7dfd\u7dfe\u7dff\u7e00\u7e01\u7e02\u7e03\u7e04\u7e05\u7e06\u7e07\u7e08\u7e09\u7e0a\u7e0b\u7e0c\u7e0d\u7e0e\u7e0f\u7e10\u7e11\u7e12\u7e13\u7e14\u7e15\u7e16\u7e17\u7e18\u7e19\u7e1a\u7e1b\u7e1c\u7e1d\u7e1e\u7e1f\u7e20\u7e21\u7e22\u7e23\u7e24\u7e25\u7e26\u7e27\u7e28\u7e29\u7e2a\u7e2b\u7e2c\u7e2d\u7e2e\u7e2f\u7e30\u7e31\u7e32\u7e33\u7e34\u7e35\u7e36\u7e37\u7e38\u7e39\u7e3a\u7e3b\u7e3c\u7e3d\u7e3e\u7e3f\u7e40\u7e41\u7e42\u7e43\u7e44\u7e45\u7e46\u7e47\u7e48\u7e49\u7e4a\u7e4b\u7e4c\u7e4d\u7e4e\u7e4f\u7e50\u7e51\u7e52\u7e53\u7e54\u7e55\u7e56\u7e57\u7e58\u7e59\u7e5a\u7e5b\u7e5c\u7e5d\u7e5e\u7e5f\u7e60\u7e61\u7e62\u7e63\u7e64\u7e65\u7e66\u7e67\u7e68\u7e69\u7e6a\u7e6b\u7e6c\u7e6d\u7e6e\u7e6f\u7e70\u7e71\u7e72\u7e73\u7e74\u7e75\u7e76\u7e77\u7e78\u7e79\u7e7a\u7e7b\u7e7c\u7e7d\u7e7e\u7e7f\u7e80\u7e81\u7e82\u7e83\u7e84\u7e85\u7e86\u7e87\u7e88\u7e89\u7e8a\u7e8b\u7e8c\u7e8d\u7e8e\u7e8f\u7e90\u7e91\u7e92\u7e93\u7e94\u7e95\u7e96\u7e97\u7e98\u7e99\u7e9a\u7e9b\u7e9c\u7e9d\u7e9e\u7e9f\u7ea0\u7ea1\u7ea2\u7ea3\u7ea4\u7ea5\u7ea6\u7ea7\u7ea8\u7ea9\u7eaa\u7eab\u7eac\u7ead\u7eae\u7eaf\u7eb0\u7eb1\u7eb2\u7eb3\u7eb4\u7eb5\u7eb6\u7eb7\u7eb8\u7eb9\u7eba\u7ebb\u7ebc\u7ebd\u7ebe\u7ebf\u7ec0\u7ec1\u7ec2\u7ec3\u7ec4\u7ec5\u7ec6\u7ec7\u7ec8\u7ec9\u7eca\u7ecb\u7ecc\u7ecd\u7ece\u7ecf\u7ed0\u7ed1\u7ed2\u7ed3\u7ed4\u7ed5\u7ed6\u7ed7\u7ed8\u7ed9\u7eda\u7edb\u7edc\u7edd\u7ede\u7edf\u7ee0\u7ee1\u7ee2\u7ee3\u7ee4\u7ee5\u7ee6\u7ee7\u7ee8\u7ee9\u7eea\u7eeb\u7eec\u7eed\u7eee\u7eef\u7ef0\u7ef1\u7ef2\u7ef3\u7ef4\u7ef5\u7ef6\u7ef7\u7ef8\u7ef9\u7efa\u7efb\u7efc\u7efd\u7efe\u7eff\u7f00\u7f01\u7f02\u7f03\u7f04\u7f05\u7f06\u7f07\u7f08\u7f09\u7f0a\u7f0b\u7f0c\u7f0d\u7f0e\u7f0f\u7f10\u7f11\u7f12\u7f13\u7f14\u7f15\u7f16\u7f17\u7f18\u7f19\u7f1a\u7f1b\u7f1c\u7f1d\u7f1e\u7f1f\u7f20\u7f21\u7f22\u7f23\u7f24\u7f25\u7f26\u7f27\u7f28\u7f29\u7f2a\u7f2b\u7f2c\u7f2d\u7f2e\u7f2f\u7f30\u7f31\u7f32\u7f33\u7f34\u7f35\u7f36\u7f37\u7f38\u7f39\u7f3a\u7f3b\u7f3c\u7f3d\u7f3e\u7f3f\u7f40\u7f41\u7f42\u7f43\u7f44\u7f45\u7f46\u7f47\u7f48\u7f49\u7f4a\u7f4b\u7f4c\u7f4d\u7f4e\u7f4f\u7f50\u7f51\u7f52\u7f53\u7f54\u7f55\u7f56\u7f57\u7f58\u7f59\u7f5a\u7f5b\u7f5c\u7f5d\u7f5e\u7f5f\u7f60\u7f61\u7f62\u7f63\u7f64\u7f65\u7f66\u7f67\u7f68\u7f69\u7f6a\u7f6b\u7f6c\u7f6d\u7f6e\u7f6f\u7f70\u7f71\u7f72\u7f73\u7f74\u7f75\u7f76\u7f77\u7f78\u7f79\u7f7a\u7f7b\u7f7c\u7f7d\u7f7e\u7f7f\u7f80\u7f81\u7f82\u7f83\u7f84\u7f85\u7f86\u7f87\u7f88\u7f89\u7f8a\u7f8b\u7f8c\u7f8d\u7f8e\u7f8f\u7f90\u7f91\u7f92\u7f93\u7f94\u7f95\u7f96\u7f97\u7f98\u7f99\u7f9a\u7f9b\u7f9c\u7f9d\u7f9e\u7f9f\u7fa0\u7fa1\u7fa2\u7fa3\u7fa4\u7fa5\u7fa6\u7fa7\u7fa8\u7fa9\u7faa\u7fab\u7fac\u7fad\u7fae\u7faf\u7fb0\u7fb1\u7fb2\u7fb3\u7fb4\u7fb5\u7fb6\u7fb7\u7fb8\u7fb9\u7fba\u7fbb\u7fbc\u7fbd\u7fbe\u7fbf\u7fc0\u7fc1\u7fc2\u7fc3\u7fc4\u7fc5\u7fc6\u7fc7\u7fc8\u7fc9\u7fca\u7fcb\u7fcc\u7fcd\u7fce\u7fcf\u7fd0\u7fd1\u7fd2\u7fd3\u7fd4\u7fd5\u7fd6\u7fd7\u7fd8\u7fd9\u7fda\u7fdb\u7fdc\u7fdd\u7fde\u7fdf\u7fe0\u7fe1\u7fe2\u7fe3\u7fe4\u7fe5\u7fe6\u7fe7\u7fe8\u7fe9\u7fea\u7feb\u7fec\u7fed\u7fee\u7fef\u7ff0\u7ff1\u7ff2\u7ff3\u7ff4\u7ff5\u7ff6\u7ff7\u7ff8\u7ff9\u7ffa\u7ffb\u7ffc\u7ffd\u7ffe\u7fff\u8000\u8001\u8002\u8003\u8004\u8005\u8006\u8007\u8008\u8009\u800a\u800b\u800c\u800d\u800e\u800f\u8010\u8011\u8012\u8013\u8014\u8015\u8016\u8017\u8018\u8019\u801a\u801b\u801c\u801d\u801e\u801f\u8020\u8021\u8022\u8023\u8024\u8025\u8026\u8027\u8028\u8029\u802a\u802b\u802c\u802d\u802e\u802f\u8030\u8031\u8032\u8033\u8034\u8035\u8036\u8037\u8038\u8039\u803a\u803b\u803c\u803d\u803e\u803f\u8040\u8041\u8042\u8043\u8044\u8045\u8046\u8047\u8048\u8049\u804a\u804b\u804c\u804d\u804e\u804f\u8050\u8051\u8052\u8053\u8054\u8055\u8056\u8057\u8058\u8059\u805a\u805b\u805c\u805d\u805e\u805f\u8060\u8061\u8062\u8063\u8064\u8065\u8066\u8067\u8068\u8069\u806a\u806b\u806c\u806d\u806e\u806f\u8070\u8071\u8072\u8073\u8074\u8075\u8076\u8077\u8078\u8079\u807a\u807b\u807c\u807d\u807e\u807f\u8080\u8081\u8082\u8083\u8084\u8085\u8086\u8087\u8088\u8089\u808a\u808b\u808c\u808d\u808e\u808f\u8090\u8091\u8092\u8093\u8094\u8095\u8096\u8097\u8098\u8099\u809a\u809b\u809c\u809d\u809e\u809f\u80a0\u80a1\u80a2\u80a3\u80a4\u80a5\u80a6\u80a7\u80a8\u80a9\u80aa\u80ab\u80ac\u80ad\u80ae\u80af\u80b0\u80b1\u80b2\u80b3\u80b4\u80b5\u80b6\u80b7\u80b8\u80b9\u80ba\u80bb\u80bc\u80bd\u80be\u80bf\u80c0\u80c1\u80c2\u80c3\u80c4\u80c5\u80c6\u80c7\u80c8\u80c9\u80ca\u80cb\u80cc\u80cd\u80ce\u80cf\u80d0\u80d1\u80d2\u80d3\u80d4\u80d5\u80d6\u80d7\u80d8\u80d9\u80da\u80db\u80dc\u80dd\u80de\u80df\u80e0\u80e1\u80e2\u80e3\u80e4\u80e5\u80e6\u80e7\u80e8\u80e9\u80ea\u80eb\u80ec\u80ed\u80ee\u80ef\u80f0\u80f1\u80f2\u80f3\u80f4\u80f5\u80f6\u80f7\u80f8\u80f9\u80fa\u80fb\u80fc\u80fd\u80fe\u80ff\u8100\u8101\u8102\u8103\u8104\u8105\u8106\u8107\u8108\u8109\u810a\u810b\u810c\u810d\u810e\u810f\u8110\u8111\u8112\u8113\u8114\u8115\u8116\u8117\u8118\u8119\u811a\u811b\u811c\u811d\u811e\u811f\u8120\u8121\u8122\u8123\u8124\u8125\u8126\u8127\u8128\u8129\u812a\u812b\u812c\u812d\u812e\u812f\u8130\u8131\u8132\u8133\u8134\u8135\u8136\u8137\u8138\u8139\u813a\u813b\u813c\u813d\u813e\u813f\u8140\u8141\u8142\u8143\u8144\u8145\u8146\u8147\u8148\u8149\u814a\u814b\u814c\u814d\u814e\u814f\u8150\u8151\u8152\u8153\u8154\u8155\u8156\u8157\u8158\u8159\u815a\u815b\u815c\u815d\u815e\u815f\u8160\u8161\u8162\u8163\u8164\u8165\u8166\u8167\u8168\u8169\u816a\u816b\u816c\u816d\u816e\u816f\u8170\u8171\u8172\u8173\u8174\u8175\u8176\u8177\u8178\u8179\u817a\u817b\u817c\u817d\u817e\u817f\u8180\u8181\u8182\u8183\u8184\u8185\u8186\u8187\u8188\u8189\u818a\u818b\u818c\u818d\u818e\u818f\u8190\u8191\u8192\u8193\u8194\u8195\u8196\u8197\u8198\u8199\u819a\u819b\u819c\u819d\u819e\u819f\u81a0\u81a1\u81a2\u81a3\u81a4\u81a5\u81a6\u81a7\u81a8\u81a9\u81aa\u81ab\u81ac\u81ad\u81ae\u81af\u81b0\u81b1\u81b2\u81b3\u81b4\u81b5\u81b6\u81b7\u81b8\u81b9\u81ba\u81bb\u81bc\u81bd\u81be\u81bf\u81c0\u81c1\u81c2\u81c3\u81c4\u81c5\u81c6\u81c7\u81c8\u81c9\u81ca\u81cb\u81cc\u81cd\u81ce\u81cf\u81d0\u81d1\u81d2\u81d3\u81d4\u81d5\u81d6\u81d7\u81d8\u81d9\u81da\u81db\u81dc\u81dd\u81de\u81df\u81e0\u81e1\u81e2\u81e3\u81e4\u81e5\u81e6\u81e7\u81e8\u81e9\u81ea\u81eb\u81ec\u81ed\u81ee\u81ef\u81f0\u81f1\u81f2\u81f3\u81f4\u81f5\u81f6\u81f7\u81f8\u81f9\u81fa\u81fb\u81fc\u81fd\u81fe\u81ff\u8200\u8201\u8202\u8203\u8204\u8205\u8206\u8207\u8208\u8209\u820a\u820b\u820c\u820d\u820e\u820f\u8210\u8211\u8212\u8213\u8214\u8215\u8216\u8217\u8218\u8219\u821a\u821b\u821c\u821d\u821e\u821f\u8220\u8221\u8222\u8223\u8224\u8225\u8226\u8227\u8228\u8229\u822a\u822b\u822c\u822d\u822e\u822f\u8230\u8231\u8232\u8233\u8234\u8235\u8236\u8237\u8238\u8239\u823a\u823b\u823c\u823d\u823e\u823f\u8240\u8241\u8242\u8243\u8244\u8245\u8246\u8247\u8248\u8249\u824a\u824b\u824c\u824d\u824e\u824f\u8250\u8251\u8252\u8253\u8254\u8255\u8256\u8257\u8258\u8259\u825a\u825b\u825c\u825d\u825e\u825f\u8260\u8261\u8262\u8263\u8264\u8265\u8266\u8267\u8268\u8269\u826a\u826b\u826c\u826d\u826e\u826f\u8270\u8271\u8272\u8273\u8274\u8275\u8276\u8277\u8278\u8279\u827a\u827b\u827c\u827d\u827e\u827f\u8280\u8281\u8282\u8283\u8284\u8285\u8286\u8287\u8288\u8289\u828a\u828b\u828c\u828d\u828e\u828f\u8290\u8291\u8292\u8293\u8294\u8295\u8296\u8297\u8298\u8299\u829a\u829b\u829c\u829d\u829e\u829f\u82a0\u82a1\u82a2\u82a3\u82a4\u82a5\u82a6\u82a7\u82a8\u82a9\u82aa\u82ab\u82ac\u82ad\u82ae\u82af\u82b0\u82b1\u82b2\u82b3\u82b4\u82b5\u82b6\u82b7\u82b8\u82b9\u82ba\u82bb\u82bc\u82bd\u82be\u82bf\u82c0\u82c1\u82c2\u82c3\u82c4\u82c5\u82c6\u82c7\u82c8\u82c9\u82ca\u82cb\u82cc\u82cd\u82ce\u82cf\u82d0\u82d1\u82d2\u82d3\u82d4\u82d5\u82d6\u82d7\u82d8\u82d9\u82da\u82db\u82dc\u82dd\u82de\u82df\u82e0\u82e1\u82e2\u82e3\u82e4\u82e5\u82e6\u82e7\u82e8\u82e9\u82ea\u82eb\u82ec\u82ed\u82ee\u82ef\u82f0\u82f1\u82f2\u82f3\u82f4\u82f5\u82f6\u82f7\u82f8\u82f9\u82fa\u82fb\u82fc\u82fd\u82fe\u82ff\u8300\u8301\u8302\u8303\u8304\u8305\u8306\u8307\u8308\u8309\u830a\u830b\u830c\u830d\u830e\u830f\u8310\u8311\u8312\u8313\u8314\u8315\u8316\u8317\u8318\u8319\u831a\u831b\u831c\u831d\u831e\u831f\u8320\u8321\u8322\u8323\u8324\u8325\u8326\u8327\u8328\u8329\u832a\u832b\u832c\u832d\u832e\u832f\u8330\u8331\u8332\u8333\u8334\u8335\u8336\u8337\u8338\u8339\u833a\u833b\u833c\u833d\u833e\u833f\u8340\u8341\u8342\u8343\u8344\u8345\u8346\u8347\u8348\u8349\u834a\u834b\u834c\u834d\u834e\u834f\u8350\u8351\u8352\u8353\u8354\u8355\u8356\u8357\u8358\u8359\u835a\u835b\u835c\u835d\u835e\u835f\u8360\u8361\u8362\u8363\u8364\u8365\u8366\u8367\u8368\u8369\u836a\u836b\u836c\u836d\u836e\u836f\u8370\u8371\u8372\u8373\u8374\u8375\u8376\u8377\u8378\u8379\u837a\u837b\u837c\u837d\u837e\u837f\u8380\u8381\u8382\u8383\u8384\u8385\u8386\u8387\u8388\u8389\u838a\u838b\u838c\u838d\u838e\u838f\u8390\u8391\u8392\u8393\u8394\u8395\u8396\u8397\u8398\u8399\u839a\u839b\u839c\u839d\u839e\u839f\u83a0\u83a1\u83a2\u83a3\u83a4\u83a5\u83a6\u83a7\u83a8\u83a9\u83aa\u83ab\u83ac\u83ad\u83ae\u83af\u83b0\u83b1\u83b2\u83b3\u83b4\u83b5\u83b6\u83b7\u83b8\u83b9\u83ba\u83bb\u83bc\u83bd\u83be\u83bf\u83c0\u83c1\u83c2\u83c3\u83c4\u83c5\u83c6\u83c7\u83c8\u83c9\u83ca\u83cb\u83cc\u83cd\u83ce\u83cf\u83d0\u83d1\u83d2\u83d3\u83d4\u83d5\u83d6\u83d7\u83d8\u83d9\u83da\u83db\u83dc\u83dd\u83de\u83df\u83e0\u83e1\u83e2\u83e3\u83e4\u83e5\u83e6\u83e7\u83e8\u83e9\u83ea\u83eb\u83ec\u83ed\u83ee\u83ef\u83f0\u83f1\u83f2\u83f3\u83f4\u83f5\u83f6\u83f7\u83f8\u83f9\u83fa\u83fb\u83fc\u83fd\u83fe\u83ff\u8400\u8401\u8402\u8403\u8404\u8405\u8406\u8407\u8408\u8409\u840a\u840b\u840c\u840d\u840e\u840f\u8410\u8411\u8412\u8413\u8414\u8415\u8416\u8417\u8418\u8419\u841a\u841b\u841c\u841d\u841e\u841f\u8420\u8421\u8422\u8423\u8424\u8425\u8426\u8427\u8428\u8429\u842a\u842b\u842c\u842d\u842e\u842f\u8430\u8431\u8432\u8433\u8434\u8435\u8436\u8437\u8438\u8439\u843a\u843b\u843c\u843d\u843e\u843f\u8440\u8441\u8442\u8443\u8444\u8445\u8446\u8447\u8448\u8449\u844a\u844b\u844c\u844d\u844e\u844f\u8450\u8451\u8452\u8453\u8454\u8455\u8456\u8457\u8458\u8459\u845a\u845b\u845c\u845d\u845e\u845f\u8460\u8461\u8462\u8463\u8464\u8465\u8466\u8467\u8468\u8469\u846a\u846b\u846c\u846d\u846e\u846f\u8470\u8471\u8472\u8473\u8474\u8475\u8476\u8477\u8478\u8479\u847a\u847b\u847c\u847d\u847e\u847f\u8480\u8481\u8482\u8483\u8484\u8485\u8486\u8487\u8488\u8489\u848a\u848b\u848c\u848d\u848e\u848f\u8490\u8491\u8492\u8493\u8494\u8495\u8496\u8497\u8498\u8499\u849a\u849b\u849c\u849d\u849e\u849f\u84a0\u84a1\u84a2\u84a3\u84a4\u84a5\u84a6\u84a7\u84a8\u84a9\u84aa\u84ab\u84ac\u84ad\u84ae\u84af\u84b0\u84b1\u84b2\u84b3\u84b4\u84b5\u84b6\u84b7\u84b8\u84b9\u84ba\u84bb\u84bc\u84bd\u84be\u84bf\u84c0\u84c1\u84c2\u84c3\u84c4\u84c5\u84c6\u84c7\u84c8\u84c9\u84ca\u84cb\u84cc\u84cd\u84ce\u84cf\u84d0\u84d1\u84d2\u84d3\u84d4\u84d5\u84d6\u84d7\u84d8\u84d9\u84da\u84db\u84dc\u84dd\u84de\u84df\u84e0\u84e1\u84e2\u84e3\u84e4\u84e5\u84e6\u84e7\u84e8\u84e9\u84ea\u84eb\u84ec\u84ed\u84ee\u84ef\u84f0\u84f1\u84f2\u84f3\u84f4\u84f5\u84f6\u84f7\u84f8\u84f9\u84fa\u84fb\u84fc\u84fd\u84fe\u84ff\u8500\u8501\u8502\u8503\u8504\u8505\u8506\u8507\u8508\u8509\u850a\u850b\u850c\u850d\u850e\u850f\u8510\u8511\u8512\u8513\u8514\u8515\u8516\u8517\u8518\u8519\u851a\u851b\u851c\u851d\u851e\u851f\u8520\u8521\u8522\u8523\u8524\u8525\u8526\u8527\u8528\u8529\u852a\u852b\u852c\u852d\u852e\u852f\u8530\u8531\u8532\u8533\u8534\u8535\u8536\u8537\u8538\u8539\u853a\u853b\u853c\u853d\u853e\u853f\u8540\u8541\u8542\u8543\u8544\u8545\u8546\u8547\u8548\u8549\u854a\u854b\u854c\u854d\u854e\u854f\u8550\u8551\u8552\u8553\u8554\u8555\u8556\u8557\u8558\u8559\u855a\u855b\u855c\u855d\u855e\u855f\u8560\u8561\u8562\u8563\u8564\u8565\u8566\u8567\u8568\u8569\u856a\u856b\u856c\u856d\u856e\u856f\u8570\u8571\u8572\u8573\u8574\u8575\u8576\u8577\u8578\u8579\u857a\u857b\u857c\u857d\u857e\u857f\u8580\u8581\u8582\u8583\u8584\u8585\u8586\u8587\u8588\u8589\u858a\u858b\u858c\u858d\u858e\u858f\u8590\u8591\u8592\u8593\u8594\u8595\u8596\u8597\u8598\u8599\u859a\u859b\u859c\u859d\u859e\u859f\u85a0\u85a1\u85a2\u85a3\u85a4\u85a5\u85a6\u85a7\u85a8\u85a9\u85aa\u85ab\u85ac\u85ad\u85ae\u85af\u85b0\u85b1\u85b2\u85b3\u85b4\u85b5\u85b6\u85b7\u85b8\u85b9\u85ba\u85bb\u85bc\u85bd\u85be\u85bf\u85c0\u85c1\u85c2\u85c3\u85c4\u85c5\u85c6\u85c7\u85c8\u85c9\u85ca\u85cb\u85cc\u85cd\u85ce\u85cf\u85d0\u85d1\u85d2\u85d3\u85d4\u85d5\u85d6\u85d7\u85d8\u85d9\u85da\u85db\u85dc\u85dd\u85de\u85df\u85e0\u85e1\u85e2\u85e3\u85e4\u85e5\u85e6\u85e7\u85e8\u85e9\u85ea\u85eb\u85ec\u85ed\u85ee\u85ef\u85f0\u85f1\u85f2\u85f3\u85f4\u85f5\u85f6\u85f7\u85f8\u85f9\u85fa\u85fb\u85fc\u85fd\u85fe\u85ff\u8600\u8601\u8602\u8603\u8604\u8605\u8606\u8607\u8608\u8609\u860a\u860b\u860c\u860d\u860e\u860f\u8610\u8611\u8612\u8613\u8614\u8615\u8616\u8617\u8618\u8619\u861a\u861b\u861c\u861d\u861e\u861f\u8620\u8621\u8622\u8623\u8624\u8625\u8626\u8627\u8628\u8629\u862a\u862b\u862c\u862d\u862e\u862f\u8630\u8631\u8632\u8633\u8634\u8635\u8636\u8637\u8638\u8639\u863a\u863b\u863c\u863d\u863e\u863f\u8640\u8641\u8642\u8643\u8644\u8645\u8646\u8647\u8648\u8649\u864a\u864b\u864c\u864d\u864e\u864f\u8650\u8651\u8652\u8653\u8654\u8655\u8656\u8657\u8658\u8659\u865a\u865b\u865c\u865d\u865e\u865f\u8660\u8661\u8662\u8663\u8664\u8665\u8666\u8667\u8668\u8669\u866a\u866b\u866c\u866d\u866e\u866f\u8670\u8671\u8672\u8673\u8674\u8675\u8676\u8677\u8678\u8679\u867a\u867b\u867c\u867d\u867e\u867f\u8680\u8681\u8682\u8683\u8684\u8685\u8686\u8687\u8688\u8689\u868a\u868b\u868c\u868d\u868e\u868f\u8690\u8691\u8692\u8693\u8694\u8695\u8696\u8697\u8698\u8699\u869a\u869b\u869c\u869d\u869e\u869f\u86a0\u86a1\u86a2\u86a3\u86a4\u86a5\u86a6\u86a7\u86a8\u86a9\u86aa\u86ab\u86ac\u86ad\u86ae\u86af\u86b0\u86b1\u86b2\u86b3\u86b4\u86b5\u86b6\u86b7\u86b8\u86b9\u86ba\u86bb\u86bc\u86bd\u86be\u86bf\u86c0\u86c1\u86c2\u86c3\u86c4\u86c5\u86c6\u86c7\u86c8\u86c9\u86ca\u86cb\u86cc\u86cd\u86ce\u86cf\u86d0\u86d1\u86d2\u86d3\u86d4\u86d5\u86d6\u86d7\u86d8\u86d9\u86da\u86db\u86dc\u86dd\u86de\u86df\u86e0\u86e1\u86e2\u86e3\u86e4\u86e5\u86e6\u86e7\u86e8\u86e9\u86ea\u86eb\u86ec\u86ed\u86ee\u86ef\u86f0\u86f1\u86f2\u86f3\u86f4\u86f5\u86f6\u86f7\u86f8\u86f9\u86fa\u86fb\u86fc\u86fd\u86fe\u86ff\u8700\u8701\u8702\u8703\u8704\u8705\u8706\u8707\u8708\u8709\u870a\u870b\u870c\u870d\u870e\u870f\u8710\u8711\u8712\u8713\u8714\u8715\u8716\u8717\u8718\u8719\u871a\u871b\u871c\u871d\u871e\u871f\u8720\u8721\u8722\u8723\u8724\u8725\u8726\u8727\u8728\u8729\u872a\u872b\u872c\u872d\u872e\u872f\u8730\u8731\u8732\u8733\u8734\u8735\u8736\u8737\u8738\u8739\u873a\u873b\u873c\u873d\u873e\u873f\u8740\u8741\u8742\u8743\u8744\u8745\u8746\u8747\u8748\u8749\u874a\u874b\u874c\u874d\u874e\u874f\u8750\u8751\u8752\u8753\u8754\u8755\u8756\u8757\u8758\u8759\u875a\u875b\u875c\u875d\u875e\u875f\u8760\u8761\u8762\u8763\u8764\u8765\u8766\u8767\u8768\u8769\u876a\u876b\u876c\u876d\u876e\u876f\u8770\u8771\u8772\u8773\u8774\u8775\u8776\u8777\u8778\u8779\u877a\u877b\u877c\u877d\u877e\u877f\u8780\u8781\u8782\u8783\u8784\u8785\u8786\u8787\u8788\u8789\u878a\u878b\u878c\u878d\u878e\u878f\u8790\u8791\u8792\u8793\u8794\u8795\u8796\u8797\u8798\u8799\u879a\u879b\u879c\u879d\u879e\u879f\u87a0\u87a1\u87a2\u87a3\u87a4\u87a5\u87a6\u87a7\u87a8\u87a9\u87aa\u87ab\u87ac\u87ad\u87ae\u87af\u87b0\u87b1\u87b2\u87b3\u87b4\u87b5\u87b6\u87b7\u87b8\u87b9\u87ba\u87bb\u87bc\u87bd\u87be\u87bf\u87c0\u87c1\u87c2\u87c3\u87c4\u87c5\u87c6\u87c7\u87c8\u87c9\u87ca\u87cb\u87cc\u87cd\u87ce\u87cf\u87d0\u87d1\u87d2\u87d3\u87d4\u87d5\u87d6\u87d7\u87d8\u87d9\u87da\u87db\u87dc\u87dd\u87de\u87df\u87e0\u87e1\u87e2\u87e3\u87e4\u87e5\u87e6\u87e7\u87e8\u87e9\u87ea\u87eb\u87ec\u87ed\u87ee\u87ef\u87f0\u87f1\u87f2\u87f3\u87f4\u87f5\u87f6\u87f7\u87f8\u87f9\u87fa\u87fb\u87fc\u87fd\u87fe\u87ff\u8800\u8801\u8802\u8803\u8804\u8805\u8806\u8807\u8808\u8809\u880a\u880b\u880c\u880d\u880e\u880f\u8810\u8811\u8812\u8813\u8814\u8815\u8816\u8817\u8818\u8819\u881a\u881b\u881c\u881d\u881e\u881f\u8820\u8821\u8822\u8823\u8824\u8825\u8826\u8827\u8828\u8829\u882a\u882b\u882c\u882d\u882e\u882f\u8830\u8831\u8832\u8833\u8834\u8835\u8836\u8837\u8838\u8839\u883a\u883b\u883c\u883d\u883e\u883f\u8840\u8841\u8842\u8843\u8844\u8845\u8846\u8847\u8848\u8849\u884a\u884b\u884c\u884d\u884e\u884f\u8850\u8851\u8852\u8853\u8854\u8855\u8856\u8857\u8858\u8859\u885a\u885b\u885c\u885d\u885e\u885f\u8860\u8861\u8862\u8863\u8864\u8865\u8866\u8867\u8868\u8869\u886a\u886b\u886c\u886d\u886e\u886f\u8870\u8871\u8872\u8873\u8874\u8875\u8876\u8877\u8878\u8879\u887a\u887b\u887c\u887d\u887e\u887f\u8880\u8881\u8882\u8883\u8884\u8885\u8886\u8887\u8888\u8889\u888a\u888b\u888c\u888d\u888e\u888f\u8890\u8891\u8892\u8893\u8894\u8895\u8896\u8897\u8898\u8899\u889a\u889b\u889c\u889d\u889e\u889f\u88a0\u88a1\u88a2\u88a3\u88a4\u88a5\u88a6\u88a7\u88a8\u88a9\u88aa\u88ab\u88ac\u88ad\u88ae\u88af\u88b0\u88b1\u88b2\u88b3\u88b4\u88b5\u88b6\u88b7\u88b8\u88b9\u88ba\u88bb\u88bc\u88bd\u88be\u88bf\u88c0\u88c1\u88c2\u88c3\u88c4\u88c5\u88c6\u88c7\u88c8\u88c9\u88ca\u88cb\u88cc\u88cd\u88ce\u88cf\u88d0\u88d1\u88d2\u88d3\u88d4\u88d5\u88d6\u88d7\u88d8\u88d9\u88da\u88db\u88dc\u88dd\u88de\u88df\u88e0\u88e1\u88e2\u88e3\u88e4\u88e5\u88e6\u88e7\u88e8\u88e9\u88ea\u88eb\u88ec\u88ed\u88ee\u88ef\u88f0\u88f1\u88f2\u88f3\u88f4\u88f5\u88f6\u88f7\u88f8\u88f9\u88fa\u88fb\u88fc\u88fd\u88fe\u88ff\u8900\u8901\u8902\u8903\u8904\u8905\u8906\u8907\u8908\u8909\u890a\u890b\u890c\u890d\u890e\u890f\u8910\u8911\u8912\u8913\u8914\u8915\u8916\u8917\u8918\u8919\u891a\u891b\u891c\u891d\u891e\u891f\u8920\u8921\u8922\u8923\u8924\u8925\u8926\u8927\u8928\u8929\u892a\u892b\u892c\u892d\u892e\u892f\u8930\u8931\u8932\u8933\u8934\u8935\u8936\u8937\u8938\u8939\u893a\u893b\u893c\u893d\u893e\u893f\u8940\u8941\u8942\u8943\u8944\u8945\u8946\u8947\u8948\u8949\u894a\u894b\u894c\u894d\u894e\u894f\u8950\u8951\u8952\u8953\u8954\u8955\u8956\u8957\u8958\u8959\u895a\u895b\u895c\u895d\u895e\u895f\u8960\u8961\u8962\u8963\u8964\u8965\u8966\u8967\u8968\u8969\u896a\u896b\u896c\u896d\u896e\u896f\u8970\u8971\u8972\u8973\u8974\u8975\u8976\u8977\u8978\u8979\u897a\u897b\u897c\u897d\u897e\u897f\u8980\u8981\u8982\u8983\u8984\u8985\u8986\u8987\u8988\u8989\u898a\u898b\u898c\u898d\u898e\u898f\u8990\u8991\u8992\u8993\u8994\u8995\u8996\u8997\u8998\u8999\u899a\u899b\u899c\u899d\u899e\u899f\u89a0\u89a1\u89a2\u89a3\u89a4\u89a5\u89a6\u89a7\u89a8\u89a9\u89aa\u89ab\u89ac\u89ad\u89ae\u89af\u89b0\u89b1\u89b2\u89b3\u89b4\u89b5\u89b6\u89b7\u89b8\u89b9\u89ba\u89bb\u89bc\u89bd\u89be\u89bf\u89c0\u89c1\u89c2\u89c3\u89c4\u89c5\u89c6\u89c7\u89c8\u89c9\u89ca\u89cb\u89cc\u89cd\u89ce\u89cf\u89d0\u89d1\u89d2\u89d3\u89d4\u89d5\u89d6\u89d7\u89d8\u89d9\u89da\u89db\u89dc\u89dd\u89de\u89df\u89e0\u89e1\u89e2\u89e3\u89e4\u89e5\u89e6\u89e7\u89e8\u89e9\u89ea\u89eb\u89ec\u89ed\u89ee\u89ef\u89f0\u89f1\u89f2\u89f3\u89f4\u89f5\u89f6\u89f7\u89f8\u89f9\u89fa\u89fb\u89fc\u89fd\u89fe\u89ff\u8a00\u8a01\u8a02\u8a03\u8a04\u8a05\u8a06\u8a07\u8a08\u8a09\u8a0a\u8a0b\u8a0c\u8a0d\u8a0e\u8a0f\u8a10\u8a11\u8a12\u8a13\u8a14\u8a15\u8a16\u8a17\u8a18\u8a19\u8a1a\u8a1b\u8a1c\u8a1d\u8a1e\u8a1f\u8a20\u8a21\u8a22\u8a23\u8a24\u8a25\u8a26\u8a27\u8a28\u8a29\u8a2a\u8a2b\u8a2c\u8a2d\u8a2e\u8a2f\u8a30\u8a31\u8a32\u8a33\u8a34\u8a35\u8a36\u8a37\u8a38\u8a39\u8a3a\u8a3b\u8a3c\u8a3d\u8a3e\u8a3f\u8a40\u8a41\u8a42\u8a43\u8a44\u8a45\u8a46\u8a47\u8a48\u8a49\u8a4a\u8a4b\u8a4c\u8a4d\u8a4e\u8a4f\u8a50\u8a51\u8a52\u8a53\u8a54\u8a55\u8a56\u8a57\u8a58\u8a59\u8a5a\u8a5b\u8a5c\u8a5d\u8a5e\u8a5f\u8a60\u8a61\u8a62\u8a63\u8a64\u8a65\u8a66\u8a67\u8a68\u8a69\u8a6a\u8a6b\u8a6c\u8a6d\u8a6e\u8a6f\u8a70\u8a71\u8a72\u8a73\u8a74\u8a75\u8a76\u8a77\u8a78\u8a79\u8a7a\u8a7b\u8a7c\u8a7d\u8a7e\u8a7f\u8a80\u8a81\u8a82\u8a83\u8a84\u8a85\u8a86\u8a87\u8a88\u8a89\u8a8a\u8a8b\u8a8c\u8a8d\u8a8e\u8a8f\u8a90\u8a91\u8a92\u8a93\u8a94\u8a95\u8a96\u8a97\u8a98\u8a99\u8a9a\u8a9b\u8a9c\u8a9d\u8a9e\u8a9f\u8aa0\u8aa1\u8aa2\u8aa3\u8aa4\u8aa5\u8aa6\u8aa7\u8aa8\u8aa9\u8aaa\u8aab\u8aac\u8aad\u8aae\u8aaf\u8ab0\u8ab1\u8ab2\u8ab3\u8ab4\u8ab5\u8ab6\u8ab7\u8ab8\u8ab9\u8aba\u8abb\u8abc\u8abd\u8abe\u8abf\u8ac0\u8ac1\u8ac2\u8ac3\u8ac4\u8ac5\u8ac6\u8ac7\u8ac8\u8ac9\u8aca\u8acb\u8acc\u8acd\u8ace\u8acf\u8ad0\u8ad1\u8ad2\u8ad3\u8ad4\u8ad5\u8ad6\u8ad7\u8ad8\u8ad9\u8ada\u8adb\u8adc\u8add\u8ade\u8adf\u8ae0\u8ae1\u8ae2\u8ae3\u8ae4\u8ae5\u8ae6\u8ae7\u8ae8\u8ae9\u8aea\u8aeb\u8aec\u8aed\u8aee\u8aef\u8af0\u8af1\u8af2\u8af3\u8af4\u8af5\u8af6\u8af7\u8af8\u8af9\u8afa\u8afb\u8afc\u8afd\u8afe\u8aff\u8b00\u8b01\u8b02\u8b03\u8b04\u8b05\u8b06\u8b07\u8b08\u8b09\u8b0a\u8b0b\u8b0c\u8b0d\u8b0e\u8b0f\u8b10\u8b11\u8b12\u8b13\u8b14\u8b15\u8b16\u8b17\u8b18\u8b19\u8b1a\u8b1b\u8b1c\u8b1d\u8b1e\u8b1f\u8b20\u8b21\u8b22\u8b23\u8b24\u8b25\u8b26\u8b27\u8b28\u8b29\u8b2a\u8b2b\u8b2c\u8b2d\u8b2e\u8b2f\u8b30\u8b31\u8b32\u8b33\u8b34\u8b35\u8b36\u8b37\u8b38\u8b39\u8b3a\u8b3b\u8b3c\u8b3d\u8b3e\u8b3f\u8b40\u8b41\u8b42\u8b43\u8b44\u8b45\u8b46\u8b47\u8b48\u8b49\u8b4a\u8b4b\u8b4c\u8b4d\u8b4e\u8b4f\u8b50\u8b51\u8b52\u8b53\u8b54\u8b55\u8b56\u8b57\u8b58\u8b59\u8b5a\u8b5b\u8b5c\u8b5d\u8b5e\u8b5f\u8b60\u8b61\u8b62\u8b63\u8b64\u8b65\u8b66\u8b67\u8b68\u8b69\u8b6a\u8b6b\u8b6c\u8b6d\u8b6e\u8b6f\u8b70\u8b71\u8b72\u8b73\u8b74\u8b75\u8b76\u8b77\u8b78\u8b79\u8b7a\u8b7b\u8b7c\u8b7d\u8b7e\u8b7f\u8b80\u8b81\u8b82\u8b83\u8b84\u8b85\u8b86\u8b87\u8b88\u8b89\u8b8a\u8b8b\u8b8c\u8b8d\u8b8e\u8b8f\u8b90\u8b91\u8b92\u8b93\u8b94\u8b95\u8b96\u8b97\u8b98\u8b99\u8b9a\u8b9b\u8b9c\u8b9d\u8b9e\u8b9f\u8ba0\u8ba1\u8ba2\u8ba3\u8ba4\u8ba5\u8ba6\u8ba7\u8ba8\u8ba9\u8baa\u8bab\u8bac\u8bad\u8bae\u8baf\u8bb0\u8bb1\u8bb2\u8bb3\u8bb4\u8bb5\u8bb6\u8bb7\u8bb8\u8bb9\u8bba\u8bbb\u8bbc\u8bbd\u8bbe\u8bbf\u8bc0\u8bc1\u8bc2\u8bc3\u8bc4\u8bc5\u8bc6\u8bc7\u8bc8\u8bc9\u8bca\u8bcb\u8bcc\u8bcd\u8bce\u8bcf\u8bd0\u8bd1\u8bd2\u8bd3\u8bd4\u8bd5\u8bd6\u8bd7\u8bd8\u8bd9\u8bda\u8bdb\u8bdc\u8bdd\u8bde\u8bdf\u8be0\u8be1\u8be2\u8be3\u8be4\u8be5\u8be6\u8be7\u8be8\u8be9\u8bea\u8beb\u8bec\u8bed\u8bee\u8bef\u8bf0\u8bf1\u8bf2\u8bf3\u8bf4\u8bf5\u8bf6\u8bf7\u8bf8\u8bf9\u8bfa\u8bfb\u8bfc\u8bfd\u8bfe\u8bff\u8c00\u8c01\u8c02\u8c03\u8c04\u8c05\u8c06\u8c07\u8c08\u8c09\u8c0a\u8c0b\u8c0c\u8c0d\u8c0e\u8c0f\u8c10\u8c11\u8c12\u8c13\u8c14\u8c15\u8c16\u8c17\u8c18\u8c19\u8c1a\u8c1b\u8c1c\u8c1d\u8c1e\u8c1f\u8c20\u8c21\u8c22\u8c23\u8c24\u8c25\u8c26\u8c27\u8c28\u8c29\u8c2a\u8c2b\u8c2c\u8c2d\u8c2e\u8c2f\u8c30\u8c31\u8c32\u8c33\u8c34\u8c35\u8c36\u8c37\u8c38\u8c39\u8c3a\u8c3b\u8c3c\u8c3d\u8c3e\u8c3f\u8c40\u8c41\u8c42\u8c43\u8c44\u8c45\u8c46\u8c47\u8c48\u8c49\u8c4a\u8c4b\u8c4c\u8c4d\u8c4e\u8c4f\u8c50\u8c51\u8c52\u8c53\u8c54\u8c55\u8c56\u8c57\u8c58\u8c59\u8c5a\u8c5b\u8c5c\u8c5d\u8c5e\u8c5f\u8c60\u8c61\u8c62\u8c63\u8c64\u8c65\u8c66\u8c67\u8c68\u8c69\u8c6a\u8c6b\u8c6c\u8c6d\u8c6e\u8c6f\u8c70\u8c71\u8c72\u8c73\u8c74\u8c75\u8c76\u8c77\u8c78\u8c79\u8c7a\u8c7b\u8c7c\u8c7d\u8c7e\u8c7f\u8c80\u8c81\u8c82\u8c83\u8c84\u8c85\u8c86\u8c87\u8c88\u8c89\u8c8a\u8c8b\u8c8c\u8c8d\u8c8e\u8c8f\u8c90\u8c91\u8c92\u8c93\u8c94\u8c95\u8c96\u8c97\u8c98\u8c99\u8c9a\u8c9b\u8c9c\u8c9d\u8c9e\u8c9f\u8ca0\u8ca1\u8ca2\u8ca3\u8ca4\u8ca5\u8ca6\u8ca7\u8ca8\u8ca9\u8caa\u8cab\u8cac\u8cad\u8cae\u8caf\u8cb0\u8cb1\u8cb2\u8cb3\u8cb4\u8cb5\u8cb6\u8cb7\u8cb8\u8cb9\u8cba\u8cbb\u8cbc\u8cbd\u8cbe\u8cbf\u8cc0\u8cc1\u8cc2\u8cc3\u8cc4\u8cc5\u8cc6\u8cc7\u8cc8\u8cc9\u8cca\u8ccb\u8ccc\u8ccd\u8cce\u8ccf\u8cd0\u8cd1\u8cd2\u8cd3\u8cd4\u8cd5\u8cd6\u8cd7\u8cd8\u8cd9\u8cda\u8cdb\u8cdc\u8cdd\u8cde\u8cdf\u8ce0\u8ce1\u8ce2\u8ce3\u8ce4\u8ce5\u8ce6\u8ce7\u8ce8\u8ce9\u8cea\u8ceb\u8cec\u8ced\u8cee\u8cef\u8cf0\u8cf1\u8cf2\u8cf3\u8cf4\u8cf5\u8cf6\u8cf7\u8cf8\u8cf9\u8cfa\u8cfb\u8cfc\u8cfd\u8cfe\u8cff\u8d00\u8d01\u8d02\u8d03\u8d04\u8d05\u8d06\u8d07\u8d08\u8d09\u8d0a\u8d0b\u8d0c\u8d0d\u8d0e\u8d0f\u8d10\u8d11\u8d12\u8d13\u8d14\u8d15\u8d16\u8d17\u8d18\u8d19\u8d1a\u8d1b\u8d1c\u8d1d\u8d1e\u8d1f\u8d20\u8d21\u8d22\u8d23\u8d24\u8d25\u8d26\u8d27\u8d28\u8d29\u8d2a\u8d2b\u8d2c\u8d2d\u8d2e\u8d2f\u8d30\u8d31\u8d32\u8d33\u8d34\u8d35\u8d36\u8d37\u8d38\u8d39\u8d3a\u8d3b\u8d3c\u8d3d\u8d3e\u8d3f\u8d40\u8d41\u8d42\u8d43\u8d44\u8d45\u8d46\u8d47\u8d48\u8d49\u8d4a\u8d4b\u8d4c\u8d4d\u8d4e\u8d4f\u8d50\u8d51\u8d52\u8d53\u8d54\u8d55\u8d56\u8d57\u8d58\u8d59\u8d5a\u8d5b\u8d5c\u8d5d\u8d5e\u8d5f\u8d60\u8d61\u8d62\u8d63\u8d64\u8d65\u8d66\u8d67\u8d68\u8d69\u8d6a\u8d6b\u8d6c\u8d6d\u8d6e\u8d6f\u8d70\u8d71\u8d72\u8d73\u8d74\u8d75\u8d76\u8d77\u8d78\u8d79\u8d7a\u8d7b\u8d7c\u8d7d\u8d7e\u8d7f\u8d80\u8d81\u8d82\u8d83\u8d84\u8d85\u8d86\u8d87\u8d88\u8d89\u8d8a\u8d8b\u8d8c\u8d8d\u8d8e\u8d8f\u8d90\u8d91\u8d92\u8d93\u8d94\u8d95\u8d96\u8d97\u8d98\u8d99\u8d9a\u8d9b\u8d9c\u8d9d\u8d9e\u8d9f\u8da0\u8da1\u8da2\u8da3\u8da4\u8da5\u8da6\u8da7\u8da8\u8da9\u8daa\u8dab\u8dac\u8dad\u8dae\u8daf\u8db0\u8db1\u8db2\u8db3\u8db4\u8db5\u8db6\u8db7\u8db8\u8db9\u8dba\u8dbb\u8dbc\u8dbd\u8dbe\u8dbf\u8dc0\u8dc1\u8dc2\u8dc3\u8dc4\u8dc5\u8dc6\u8dc7\u8dc8\u8dc9\u8dca\u8dcb\u8dcc\u8dcd\u8dce\u8dcf\u8dd0\u8dd1\u8dd2\u8dd3\u8dd4\u8dd5\u8dd6\u8dd7\u8dd8\u8dd9\u8dda\u8ddb\u8ddc\u8ddd\u8dde\u8ddf\u8de0\u8de1\u8de2\u8de3\u8de4\u8de5\u8de6\u8de7\u8de8\u8de9\u8dea\u8deb\u8dec\u8ded\u8dee\u8def\u8df0\u8df1\u8df2\u8df3\u8df4\u8df5\u8df6\u8df7\u8df8\u8df9\u8dfa\u8dfb\u8dfc\u8dfd\u8dfe\u8dff\u8e00\u8e01\u8e02\u8e03\u8e04\u8e05\u8e06\u8e07\u8e08\u8e09\u8e0a\u8e0b\u8e0c\u8e0d\u8e0e\u8e0f\u8e10\u8e11\u8e12\u8e13\u8e14\u8e15\u8e16\u8e17\u8e18\u8e19\u8e1a\u8e1b\u8e1c\u8e1d\u8e1e\u8e1f\u8e20\u8e21\u8e22\u8e23\u8e24\u8e25\u8e26\u8e27\u8e28\u8e29\u8e2a\u8e2b\u8e2c\u8e2d\u8e2e\u8e2f\u8e30\u8e31\u8e32\u8e33\u8e34\u8e35\u8e36\u8e37\u8e38\u8e39\u8e3a\u8e3b\u8e3c\u8e3d\u8e3e\u8e3f\u8e40\u8e41\u8e42\u8e43\u8e44\u8e45\u8e46\u8e47\u8e48\u8e49\u8e4a\u8e4b\u8e4c\u8e4d\u8e4e\u8e4f\u8e50\u8e51\u8e52\u8e53\u8e54\u8e55\u8e56\u8e57\u8e58\u8e59\u8e5a\u8e5b\u8e5c\u8e5d\u8e5e\u8e5f\u8e60\u8e61\u8e62\u8e63\u8e64\u8e65\u8e66\u8e67\u8e68\u8e69\u8e6a\u8e6b\u8e6c\u8e6d\u8e6e\u8e6f\u8e70\u8e71\u8e72\u8e73\u8e74\u8e75\u8e76\u8e77\u8e78\u8e79\u8e7a\u8e7b\u8e7c\u8e7d\u8e7e\u8e7f\u8e80\u8e81\u8e82\u8e83\u8e84\u8e85\u8e86\u8e87\u8e88\u8e89\u8e8a\u8e8b\u8e8c\u8e8d\u8e8e\u8e8f\u8e90\u8e91\u8e92\u8e93\u8e94\u8e95\u8e96\u8e97\u8e98\u8e99\u8e9a\u8e9b\u8e9c\u8e9d\u8e9e\u8e9f\u8ea0\u8ea1\u8ea2\u8ea3\u8ea4\u8ea5\u8ea6\u8ea7\u8ea8\u8ea9\u8eaa\u8eab\u8eac\u8ead\u8eae\u8eaf\u8eb0\u8eb1\u8eb2\u8eb3\u8eb4\u8eb5\u8eb6\u8eb7\u8eb8\u8eb9\u8eba\u8ebb\u8ebc\u8ebd\u8ebe\u8ebf\u8ec0\u8ec1\u8ec2\u8ec3\u8ec4\u8ec5\u8ec6\u8ec7\u8ec8\u8ec9\u8eca\u8ecb\u8ecc\u8ecd\u8ece\u8ecf\u8ed0\u8ed1\u8ed2\u8ed3\u8ed4\u8ed5\u8ed6\u8ed7\u8ed8\u8ed9\u8eda\u8edb\u8edc\u8edd\u8ede\u8edf\u8ee0\u8ee1\u8ee2\u8ee3\u8ee4\u8ee5\u8ee6\u8ee7\u8ee8\u8ee9\u8eea\u8eeb\u8eec\u8eed\u8eee\u8eef\u8ef0\u8ef1\u8ef2\u8ef3\u8ef4\u8ef5\u8ef6\u8ef7\u8ef8\u8ef9\u8efa\u8efb\u8efc\u8efd\u8efe\u8eff\u8f00\u8f01\u8f02\u8f03\u8f04\u8f05\u8f06\u8f07\u8f08\u8f09\u8f0a\u8f0b\u8f0c\u8f0d\u8f0e\u8f0f\u8f10\u8f11\u8f12\u8f13\u8f14\u8f15\u8f16\u8f17\u8f18\u8f19\u8f1a\u8f1b\u8f1c\u8f1d\u8f1e\u8f1f\u8f20\u8f21\u8f22\u8f23\u8f24\u8f25\u8f26\u8f27\u8f28\u8f29\u8f2a\u8f2b\u8f2c\u8f2d\u8f2e\u8f2f\u8f30\u8f31\u8f32\u8f33\u8f34\u8f35\u8f36\u8f37\u8f38\u8f39\u8f3a\u8f3b\u8f3c\u8f3d\u8f3e\u8f3f\u8f40\u8f41\u8f42\u8f43\u8f44\u8f45\u8f46\u8f47\u8f48\u8f49\u8f4a\u8f4b\u8f4c\u8f4d\u8f4e\u8f4f\u8f50\u8f51\u8f52\u8f53\u8f54\u8f55\u8f56\u8f57\u8f58\u8f59\u8f5a\u8f5b\u8f5c\u8f5d\u8f5e\u8f5f\u8f60\u8f61\u8f62\u8f63\u8f64\u8f65\u8f66\u8f67\u8f68\u8f69\u8f6a\u8f6b\u8f6c\u8f6d\u8f6e\u8f6f\u8f70\u8f71\u8f72\u8f73\u8f74\u8f75\u8f76\u8f77\u8f78\u8f79\u8f7a\u8f7b\u8f7c\u8f7d\u8f7e\u8f7f\u8f80\u8f81\u8f82\u8f83\u8f84\u8f85\u8f86\u8f87\u8f88\u8f89\u8f8a\u8f8b\u8f8c\u8f8d\u8f8e\u8f8f\u8f90\u8f91\u8f92\u8f93\u8f94\u8f95\u8f96\u8f97\u8f98\u8f99\u8f9a\u8f9b\u8f9c\u8f9d\u8f9e\u8f9f\u8fa0\u8fa1\u8fa2\u8fa3\u8fa4\u8fa5\u8fa6\u8fa7\u8fa8\u8fa9\u8faa\u8fab\u8fac\u8fad\u8fae\u8faf\u8fb0\u8fb1\u8fb2\u8fb3\u8fb4\u8fb5\u8fb6\u8fb7\u8fb8\u8fb9\u8fba\u8fbb\u8fbc\u8fbd\u8fbe\u8fbf\u8fc0\u8fc1\u8fc2\u8fc3\u8fc4\u8fc5\u8fc6\u8fc7\u8fc8\u8fc9\u8fca\u8fcb\u8fcc\u8fcd\u8fce\u8fcf\u8fd0\u8fd1\u8fd2\u8fd3\u8fd4\u8fd5\u8fd6\u8fd7\u8fd8\u8fd9\u8fda\u8fdb\u8fdc\u8fdd\u8fde\u8fdf\u8fe0\u8fe1\u8fe2\u8fe3\u8fe4\u8fe5\u8fe6\u8fe7\u8fe8\u8fe9\u8fea\u8feb\u8fec\u8fed\u8fee\u8fef\u8ff0\u8ff1\u8ff2\u8ff3\u8ff4\u8ff5\u8ff6\u8ff7\u8ff8\u8ff9\u8ffa\u8ffb\u8ffc\u8ffd\u8ffe\u8fff\u9000\u9001\u9002\u9003\u9004\u9005\u9006\u9007\u9008\u9009\u900a\u900b\u900c\u900d\u900e\u900f\u9010\u9011\u9012\u9013\u9014\u9015\u9016\u9017\u9018\u9019\u901a\u901b\u901c\u901d\u901e\u901f\u9020\u9021\u9022\u9023\u9024\u9025\u9026\u9027\u9028\u9029\u902a\u902b\u902c\u902d\u902e\u902f\u9030\u9031\u9032\u9033\u9034\u9035\u9036\u9037\u9038\u9039\u903a\u903b\u903c\u903d\u903e\u903f\u9040\u9041\u9042\u9043\u9044\u9045\u9046\u9047\u9048\u9049\u904a\u904b\u904c\u904d\u904e\u904f\u9050\u9051\u9052\u9053\u9054\u9055\u9056\u9057\u9058\u9059\u905a\u905b\u905c\u905d\u905e\u905f\u9060\u9061\u9062\u9063\u9064\u9065\u9066\u9067\u9068\u9069\u906a\u906b\u906c\u906d\u906e\u906f\u9070\u9071\u9072\u9073\u9074\u9075\u9076\u9077\u9078\u9079\u907a\u907b\u907c\u907d\u907e\u907f\u9080\u9081\u9082\u9083\u9084\u9085\u9086\u9087\u9088\u9089\u908a\u908b\u908c\u908d\u908e\u908f\u9090\u9091\u9092\u9093\u9094\u9095\u9096\u9097\u9098\u9099\u909a\u909b\u909c\u909d\u909e\u909f\u90a0\u90a1\u90a2\u90a3\u90a4\u90a5\u90a6\u90a7\u90a8\u90a9\u90aa\u90ab\u90ac\u90ad\u90ae\u90af\u90b0\u90b1\u90b2\u90b3\u90b4\u90b5\u90b6\u90b7\u90b8\u90b9\u90ba\u90bb\u90bc\u90bd\u90be\u90bf\u90c0\u90c1\u90c2\u90c3\u90c4\u90c5\u90c6\u90c7\u90c8\u90c9\u90ca\u90cb\u90cc\u90cd\u90ce\u90cf\u90d0\u90d1\u90d2\u90d3\u90d4\u90d5\u90d6\u90d7\u90d8\u90d9\u90da\u90db\u90dc\u90dd\u90de\u90df\u90e0\u90e1\u90e2\u90e3\u90e4\u90e5\u90e6\u90e7\u90e8\u90e9\u90ea\u90eb\u90ec\u90ed\u90ee\u90ef\u90f0\u90f1\u90f2\u90f3\u90f4\u90f5\u90f6\u90f7\u90f8\u90f9\u90fa\u90fb\u90fc\u90fd\u90fe\u90ff\u9100\u9101\u9102\u9103\u9104\u9105\u9106\u9107\u9108\u9109\u910a\u910b\u910c\u910d\u910e\u910f\u9110\u9111\u9112\u9113\u9114\u9115\u9116\u9117\u9118\u9119\u911a\u911b\u911c\u911d\u911e\u911f\u9120\u9121\u9122\u9123\u9124\u9125\u9126\u9127\u9128\u9129\u912a\u912b\u912c\u912d\u912e\u912f\u9130\u9131\u9132\u9133\u9134\u9135\u9136\u9137\u9138\u9139\u913a\u913b\u913c\u913d\u913e\u913f\u9140\u9141\u9142\u9143\u9144\u9145\u9146\u9147\u9148\u9149\u914a\u914b\u914c\u914d\u914e\u914f\u9150\u9151\u9152\u9153\u9154\u9155\u9156\u9157\u9158\u9159\u915a\u915b\u915c\u915d\u915e\u915f\u9160\u9161\u9162\u9163\u9164\u9165\u9166\u9167\u9168\u9169\u916a\u916b\u916c\u916d\u916e\u916f\u9170\u9171\u9172\u9173\u9174\u9175\u9176\u9177\u9178\u9179\u917a\u917b\u917c\u917d\u917e\u917f\u9180\u9181\u9182\u9183\u9184\u9185\u9186\u9187\u9188\u9189\u918a\u918b\u918c\u918d\u918e\u918f\u9190\u9191\u9192\u9193\u9194\u9195\u9196\u9197\u9198\u9199\u919a\u919b\u919c\u919d\u919e\u919f\u91a0\u91a1\u91a2\u91a3\u91a4\u91a5\u91a6\u91a7\u91a8\u91a9\u91aa\u91ab\u91ac\u91ad\u91ae\u91af\u91b0\u91b1\u91b2\u91b3\u91b4\u91b5\u91b6\u91b7\u91b8\u91b9\u91ba\u91bb\u91bc\u91bd\u91be\u91bf\u91c0\u91c1\u91c2\u91c3\u91c4\u91c5\u91c6\u91c7\u91c8\u91c9\u91ca\u91cb\u91cc\u91cd\u91ce\u91cf\u91d0\u91d1\u91d2\u91d3\u91d4\u91d5\u91d6\u91d7\u91d8\u91d9\u91da\u91db\u91dc\u91dd\u91de\u91df\u91e0\u91e1\u91e2\u91e3\u91e4\u91e5\u91e6\u91e7\u91e8\u91e9\u91ea\u91eb\u91ec\u91ed\u91ee\u91ef\u91f0\u91f1\u91f2\u91f3\u91f4\u91f5\u91f6\u91f7\u91f8\u91f9\u91fa\u91fb\u91fc\u91fd\u91fe\u91ff\u9200\u9201\u9202\u9203\u9204\u9205\u9206\u9207\u9208\u9209\u920a\u920b\u920c\u920d\u920e\u920f\u9210\u9211\u9212\u9213\u9214\u9215\u9216\u9217\u9218\u9219\u921a\u921b\u921c\u921d\u921e\u921f\u9220\u9221\u9222\u9223\u9224\u9225\u9226\u9227\u9228\u9229\u922a\u922b\u922c\u922d\u922e\u922f\u9230\u9231\u9232\u9233\u9234\u9235\u9236\u9237\u9238\u9239\u923a\u923b\u923c\u923d\u923e\u923f\u9240\u9241\u9242\u9243\u9244\u9245\u9246\u9247\u9248\u9249\u924a\u924b\u924c\u924d\u924e\u924f\u9250\u9251\u9252\u9253\u9254\u9255\u9256\u9257\u9258\u9259\u925a\u925b\u925c\u925d\u925e\u925f\u9260\u9261\u9262\u9263\u9264\u9265\u9266\u9267\u9268\u9269\u926a\u926b\u926c\u926d\u926e\u926f\u9270\u9271\u9272\u9273\u9274\u9275\u9276\u9277\u9278\u9279\u927a\u927b\u927c\u927d\u927e\u927f\u9280\u9281\u9282\u9283\u9284\u9285\u9286\u9287\u9288\u9289\u928a\u928b\u928c\u928d\u928e\u928f\u9290\u9291\u9292\u9293\u9294\u9295\u9296\u9297\u9298\u9299\u929a\u929b\u929c\u929d\u929e\u929f\u92a0\u92a1\u92a2\u92a3\u92a4\u92a5\u92a6\u92a7\u92a8\u92a9\u92aa\u92ab\u92ac\u92ad\u92ae\u92af\u92b0\u92b1\u92b2\u92b3\u92b4\u92b5\u92b6\u92b7\u92b8\u92b9\u92ba\u92bb\u92bc\u92bd\u92be\u92bf\u92c0\u92c1\u92c2\u92c3\u92c4\u92c5\u92c6\u92c7\u92c8\u92c9\u92ca\u92cb\u92cc\u92cd\u92ce\u92cf\u92d0\u92d1\u92d2\u92d3\u92d4\u92d5\u92d6\u92d7\u92d8\u92d9\u92da\u92db\u92dc\u92dd\u92de\u92df\u92e0\u92e1\u92e2\u92e3\u92e4\u92e5\u92e6\u92e7\u92e8\u92e9\u92ea\u92eb\u92ec\u92ed\u92ee\u92ef\u92f0\u92f1\u92f2\u92f3\u92f4\u92f5\u92f6\u92f7\u92f8\u92f9\u92fa\u92fb\u92fc\u92fd\u92fe\u92ff\u9300\u9301\u9302\u9303\u9304\u9305\u9306\u9307\u9308\u9309\u930a\u930b\u930c\u930d\u930e\u930f\u9310\u9311\u9312\u9313\u9314\u9315\u9316\u9317\u9318\u9319\u931a\u931b\u931c\u931d\u931e\u931f\u9320\u9321\u9322\u9323\u9324\u9325\u9326\u9327\u9328\u9329\u932a\u932b\u932c\u932d\u932e\u932f\u9330\u9331\u9332\u9333\u9334\u9335\u9336\u9337\u9338\u9339\u933a\u933b\u933c\u933d\u933e\u933f\u9340\u9341\u9342\u9343\u9344\u9345\u9346\u9347\u9348\u9349\u934a\u934b\u934c\u934d\u934e\u934f\u9350\u9351\u9352\u9353\u9354\u9355\u9356\u9357\u9358\u9359\u935a\u935b\u935c\u935d\u935e\u935f\u9360\u9361\u9362\u9363\u9364\u9365\u9366\u9367\u9368\u9369\u936a\u936b\u936c\u936d\u936e\u936f\u9370\u9371\u9372\u9373\u9374\u9375\u9376\u9377\u9378\u9379\u937a\u937b\u937c\u937d\u937e\u937f\u9380\u9381\u9382\u9383\u9384\u9385\u9386\u9387\u9388\u9389\u938a\u938b\u938c\u938d\u938e\u938f\u9390\u9391\u9392\u9393\u9394\u9395\u9396\u9397\u9398\u9399\u939a\u939b\u939c\u939d\u939e\u939f\u93a0\u93a1\u93a2\u93a3\u93a4\u93a5\u93a6\u93a7\u93a8\u93a9\u93aa\u93ab\u93ac\u93ad\u93ae\u93af\u93b0\u93b1\u93b2\u93b3\u93b4\u93b5\u93b6\u93b7\u93b8\u93b9\u93ba\u93bb\u93bc\u93bd\u93be\u93bf\u93c0\u93c1\u93c2\u93c3\u93c4\u93c5\u93c6\u93c7\u93c8\u93c9\u93ca\u93cb\u93cc\u93cd\u93ce\u93cf\u93d0\u93d1\u93d2\u93d3\u93d4\u93d5\u93d6\u93d7\u93d8\u93d9\u93da\u93db\u93dc\u93dd\u93de\u93df\u93e0\u93e1\u93e2\u93e3\u93e4\u93e5\u93e6\u93e7\u93e8\u93e9\u93ea\u93eb\u93ec\u93ed\u93ee\u93ef\u93f0\u93f1\u93f2\u93f3\u93f4\u93f5\u93f6\u93f7\u93f8\u93f9\u93fa\u93fb\u93fc\u93fd\u93fe\u93ff\u9400\u9401\u9402\u9403\u9404\u9405\u9406\u9407\u9408\u9409\u940a\u940b\u940c\u940d\u940e\u940f\u9410\u9411\u9412\u9413\u9414\u9415\u9416\u9417\u9418\u9419\u941a\u941b\u941c\u941d\u941e\u941f\u9420\u9421\u9422\u9423\u9424\u9425\u9426\u9427\u9428\u9429\u942a\u942b\u942c\u942d\u942e\u942f\u9430\u9431\u9432\u9433\u9434\u9435\u9436\u9437\u9438\u9439\u943a\u943b\u943c\u943d\u943e\u943f\u9440\u9441\u9442\u9443\u9444\u9445\u9446\u9447\u9448\u9449\u944a\u944b\u944c\u944d\u944e\u944f\u9450\u9451\u9452\u9453\u9454\u9455\u9456\u9457\u9458\u9459\u945a\u945b\u945c\u945d\u945e\u945f\u9460\u9461\u9462\u9463\u9464\u9465\u9466\u9467\u9468\u9469\u946a\u946b\u946c\u946d\u946e\u946f\u9470\u9471\u9472\u9473\u9474\u9475\u9476\u9477\u9478\u9479\u947a\u947b\u947c\u947d\u947e\u947f\u9480\u9481\u9482\u9483\u9484\u9485\u9486\u9487\u9488\u9489\u948a\u948b\u948c\u948d\u948e\u948f\u9490\u9491\u9492\u9493\u9494\u9495\u9496\u9497\u9498\u9499\u949a\u949b\u949c\u949d\u949e\u949f\u94a0\u94a1\u94a2\u94a3\u94a4\u94a5\u94a6\u94a7\u94a8\u94a9\u94aa\u94ab\u94ac\u94ad\u94ae\u94af\u94b0\u94b1\u94b2\u94b3\u94b4\u94b5\u94b6\u94b7\u94b8\u94b9\u94ba\u94bb\u94bc\u94bd\u94be\u94bf\u94c0\u94c1\u94c2\u94c3\u94c4\u94c5\u94c6\u94c7\u94c8\u94c9\u94ca\u94cb\u94cc\u94cd\u94ce\u94cf\u94d0\u94d1\u94d2\u94d3\u94d4\u94d5\u94d6\u94d7\u94d8\u94d9\u94da\u94db\u94dc\u94dd\u94de\u94df\u94e0\u94e1\u94e2\u94e3\u94e4\u94e5\u94e6\u94e7\u94e8\u94e9\u94ea\u94eb\u94ec\u94ed\u94ee\u94ef\u94f0\u94f1\u94f2\u94f3\u94f4\u94f5\u94f6\u94f7\u94f8\u94f9\u94fa\u94fb\u94fc\u94fd\u94fe\u94ff\u9500\u9501\u9502\u9503\u9504\u9505\u9506\u9507\u9508\u9509\u950a\u950b\u950c\u950d\u950e\u950f\u9510\u9511\u9512\u9513\u9514\u9515\u9516\u9517\u9518\u9519\u951a\u951b\u951c\u951d\u951e\u951f\u9520\u9521\u9522\u9523\u9524\u9525\u9526\u9527\u9528\u9529\u952a\u952b\u952c\u952d\u952e\u952f\u9530\u9531\u9532\u9533\u9534\u9535\u9536\u9537\u9538\u9539\u953a\u953b\u953c\u953d\u953e\u953f\u9540\u9541\u9542\u9543\u9544\u9545\u9546\u9547\u9548\u9549\u954a\u954b\u954c\u954d\u954e\u954f\u9550\u9551\u9552\u9553\u9554\u9555\u9556\u9557\u9558\u9559\u955a\u955b\u955c\u955d\u955e\u955f\u9560\u9561\u9562\u9563\u9564\u9565\u9566\u9567\u9568\u9569\u956a\u956b\u956c\u956d\u956e\u956f\u9570\u9571\u9572\u9573\u9574\u9575\u9576\u9577\u9578\u9579\u957a\u957b\u957c\u957d\u957e\u957f\u9580\u9581\u9582\u9583\u9584\u9585\u9586\u9587\u9588\u9589\u958a\u958b\u958c\u958d\u958e\u958f\u9590\u9591\u9592\u9593\u9594\u9595\u9596\u9597\u9598\u9599\u959a\u959b\u959c\u959d\u959e\u959f\u95a0\u95a1\u95a2\u95a3\u95a4\u95a5\u95a6\u95a7\u95a8\u95a9\u95aa\u95ab\u95ac\u95ad\u95ae\u95af\u95b0\u95b1\u95b2\u95b3\u95b4\u95b5\u95b6\u95b7\u95b8\u95b9\u95ba\u95bb\u95bc\u95bd\u95be\u95bf\u95c0\u95c1\u95c2\u95c3\u95c4\u95c5\u95c6\u95c7\u95c8\u95c9\u95ca\u95cb\u95cc\u95cd\u95ce\u95cf\u95d0\u95d1\u95d2\u95d3\u95d4\u95d5\u95d6\u95d7\u95d8\u95d9\u95da\u95db\u95dc\u95dd\u95de\u95df\u95e0\u95e1\u95e2\u95e3\u95e4\u95e5\u95e6\u95e7\u95e8\u95e9\u95ea\u95eb\u95ec\u95ed\u95ee\u95ef\u95f0\u95f1\u95f2\u95f3\u95f4\u95f5\u95f6\u95f7\u95f8\u95f9\u95fa\u95fb\u95fc\u95fd\u95fe\u95ff\u9600\u9601\u9602\u9603\u9604\u9605\u9606\u9607\u9608\u9609\u960a\u960b\u960c\u960d\u960e\u960f\u9610\u9611\u9612\u9613\u9614\u9615\u9616\u9617\u9618\u9619\u961a\u961b\u961c\u961d\u961e\u961f\u9620\u9621\u9622\u9623\u9624\u9625\u9626\u9627\u9628\u9629\u962a\u962b\u962c\u962d\u962e\u962f\u9630\u9631\u9632\u9633\u9634\u9635\u9636\u9637\u9638\u9639\u963a\u963b\u963c\u963d\u963e\u963f\u9640\u9641\u9642\u9643\u9644\u9645\u9646\u9647\u9648\u9649\u964a\u964b\u964c\u964d\u964e\u964f\u9650\u9651\u9652\u9653\u9654\u9655\u9656\u9657\u9658\u9659\u965a\u965b\u965c\u965d\u965e\u965f\u9660\u9661\u9662\u9663\u9664\u9665\u9666\u9667\u9668\u9669\u966a\u966b\u966c\u966d\u966e\u966f\u9670\u9671\u9672\u9673\u9674\u9675\u9676\u9677\u9678\u9679\u967a\u967b\u967c\u967d\u967e\u967f\u9680\u9681\u9682\u9683\u9684\u9685\u9686\u9687\u9688\u9689\u968a\u968b\u968c\u968d\u968e\u968f\u9690\u9691\u9692\u9693\u9694\u9695\u9696\u9697\u9698\u9699\u969a\u969b\u969c\u969d\u969e\u969f\u96a0\u96a1\u96a2\u96a3\u96a4\u96a5\u96a6\u96a7\u96a8\u96a9\u96aa\u96ab\u96ac\u96ad\u96ae\u96af\u96b0\u96b1\u96b2\u96b3\u96b4\u96b5\u96b6\u96b7\u96b8\u96b9\u96ba\u96bb\u96bc\u96bd\u96be\u96bf\u96c0\u96c1\u96c2\u96c3\u96c4\u96c5\u96c6\u96c7\u96c8\u96c9\u96ca\u96cb\u96cc\u96cd\u96ce\u96cf\u96d0\u96d1\u96d2\u96d3\u96d4\u96d5\u96d6\u96d7\u96d8\u96d9\u96da\u96db\u96dc\u96dd\u96de\u96df\u96e0\u96e1\u96e2\u96e3\u96e4\u96e5\u96e6\u96e7\u96e8\u96e9\u96ea\u96eb\u96ec\u96ed\u96ee\u96ef\u96f0\u96f1\u96f2\u96f3\u96f4\u96f5\u96f6\u96f7\u96f8\u96f9\u96fa\u96fb\u96fc\u96fd\u96fe\u96ff\u9700\u9701\u9702\u9703\u9704\u9705\u9706\u9707\u9708\u9709\u970a\u970b\u970c\u970d\u970e\u970f\u9710\u9711\u9712\u9713\u9714\u9715\u9716\u9717\u9718\u9719\u971a\u971b\u971c\u971d\u971e\u971f\u9720\u9721\u9722\u9723\u9724\u9725\u9726\u9727\u9728\u9729\u972a\u972b\u972c\u972d\u972e\u972f\u9730\u9731\u9732\u9733\u9734\u9735\u9736\u9737\u9738\u9739\u973a\u973b\u973c\u973d\u973e\u973f\u9740\u9741\u9742\u9743\u9744\u9745\u9746\u9747\u9748\u9749\u974a\u974b\u974c\u974d\u974e\u974f\u9750\u9751\u9752\u9753\u9754\u9755\u9756\u9757\u9758\u9759\u975a\u975b\u975c\u975d\u975e\u975f\u9760\u9761\u9762\u9763\u9764\u9765\u9766\u9767\u9768\u9769\u976a\u976b\u976c\u976d\u976e\u976f\u9770\u9771\u9772\u9773\u9774\u9775\u9776\u9777\u9778\u9779\u977a\u977b\u977c\u977d\u977e\u977f\u9780\u9781\u9782\u9783\u9784\u9785\u9786\u9787\u9788\u9789\u978a\u978b\u978c\u978d\u978e\u978f\u9790\u9791\u9792\u9793\u9794\u9795\u9796\u9797\u9798\u9799\u979a\u979b\u979c\u979d\u979e\u979f\u97a0\u97a1\u97a2\u97a3\u97a4\u97a5\u97a6\u97a7\u97a8\u97a9\u97aa\u97ab\u97ac\u97ad\u97ae\u97af\u97b0\u97b1\u97b2\u97b3\u97b4\u97b5\u97b6\u97b7\u97b8\u97b9\u97ba\u97bb\u97bc\u97bd\u97be\u97bf\u97c0\u97c1\u97c2\u97c3\u97c4\u97c5\u97c6\u97c7\u97c8\u97c9\u97ca\u97cb\u97cc\u97cd\u97ce\u97cf\u97d0\u97d1\u97d2\u97d3\u97d4\u97d5\u97d6\u97d7\u97d8\u97d9\u97da\u97db\u97dc\u97dd\u97de\u97df\u97e0\u97e1\u97e2\u97e3\u97e4\u97e5\u97e6\u97e7\u97e8\u97e9\u97ea\u97eb\u97ec\u97ed\u97ee\u97ef\u97f0\u97f1\u97f2\u97f3\u97f4\u97f5\u97f6\u97f7\u97f8\u97f9\u97fa\u97fb\u97fc\u97fd\u97fe\u97ff\u9800\u9801\u9802\u9803\u9804\u9805\u9806\u9807\u9808\u9809\u980a\u980b\u980c\u980d\u980e\u980f\u9810\u9811\u9812\u9813\u9814\u9815\u9816\u9817\u9818\u9819\u981a\u981b\u981c\u981d\u981e\u981f\u9820\u9821\u9822\u9823\u9824\u9825\u9826\u9827\u9828\u9829\u982a\u982b\u982c\u982d\u982e\u982f\u9830\u9831\u9832\u9833\u9834\u9835\u9836\u9837\u9838\u9839\u983a\u983b\u983c\u983d\u983e\u983f\u9840\u9841\u9842\u9843\u9844\u9845\u9846\u9847\u9848\u9849\u984a\u984b\u984c\u984d\u984e\u984f\u9850\u9851\u9852\u9853\u9854\u9855\u9856\u9857\u9858\u9859\u985a\u985b\u985c\u985d\u985e\u985f\u9860\u9861\u9862\u9863\u9864\u9865\u9866\u9867\u9868\u9869\u986a\u986b\u986c\u986d\u986e\u986f\u9870\u9871\u9872\u9873\u9874\u9875\u9876\u9877\u9878\u9879\u987a\u987b\u987c\u987d\u987e\u987f\u9880\u9881\u9882\u9883\u9884\u9885\u9886\u9887\u9888\u9889\u988a\u988b\u988c\u988d\u988e\u988f\u9890\u9891\u9892\u9893\u9894\u9895\u9896\u9897\u9898\u9899\u989a\u989b\u989c\u989d\u989e\u989f\u98a0\u98a1\u98a2\u98a3\u98a4\u98a5\u98a6\u98a7\u98a8\u98a9\u98aa\u98ab\u98ac\u98ad\u98ae\u98af\u98b0\u98b1\u98b2\u98b3\u98b4\u98b5\u98b6\u98b7\u98b8\u98b9\u98ba\u98bb\u98bc\u98bd\u98be\u98bf\u98c0\u98c1\u98c2\u98c3\u98c4\u98c5\u98c6\u98c7\u98c8\u98c9\u98ca\u98cb\u98cc\u98cd\u98ce\u98cf\u98d0\u98d1\u98d2\u98d3\u98d4\u98d5\u98d6\u98d7\u98d8\u98d9\u98da\u98db\u98dc\u98dd\u98de\u98df\u98e0\u98e1\u98e2\u98e3\u98e4\u98e5\u98e6\u98e7\u98e8\u98e9\u98ea\u98eb\u98ec\u98ed\u98ee\u98ef\u98f0\u98f1\u98f2\u98f3\u98f4\u98f5\u98f6\u98f7\u98f8\u98f9\u98fa\u98fb\u98fc\u98fd\u98fe\u98ff\u9900\u9901\u9902\u9903\u9904\u9905\u9906\u9907\u9908\u9909\u990a\u990b\u990c\u990d\u990e\u990f\u9910\u9911\u9912\u9913\u9914\u9915\u9916\u9917\u9918\u9919\u991a\u991b\u991c\u991d\u991e\u991f\u9920\u9921\u9922\u9923\u9924\u9925\u9926\u9927\u9928\u9929\u992a\u992b\u992c\u992d\u992e\u992f\u9930\u9931\u9932\u9933\u9934\u9935\u9936\u9937\u9938\u9939\u993a\u993b\u993c\u993d\u993e\u993f\u9940\u9941\u9942\u9943\u9944\u9945\u9946\u9947\u9948\u9949\u994a\u994b\u994c\u994d\u994e\u994f\u9950\u9951\u9952\u9953\u9954\u9955\u9956\u9957\u9958\u9959\u995a\u995b\u995c\u995d\u995e\u995f\u9960\u9961\u9962\u9963\u9964\u9965\u9966\u9967\u9968\u9969\u996a\u996b\u996c\u996d\u996e\u996f\u9970\u9971\u9972\u9973\u9974\u9975\u9976\u9977\u9978\u9979\u997a\u997b\u997c\u997d\u997e\u997f\u9980\u9981\u9982\u9983\u9984\u9985\u9986\u9987\u9988\u9989\u998a\u998b\u998c\u998d\u998e\u998f\u9990\u9991\u9992\u9993\u9994\u9995\u9996\u9997\u9998\u9999\u999a\u999b\u999c\u999d\u999e\u999f\u99a0\u99a1\u99a2\u99a3\u99a4\u99a5\u99a6\u99a7\u99a8\u99a9\u99aa\u99ab\u99ac\u99ad\u99ae\u99af\u99b0\u99b1\u99b2\u99b3\u99b4\u99b5\u99b6\u99b7\u99b8\u99b9\u99ba\u99bb\u99bc\u99bd\u99be\u99bf\u99c0\u99c1\u99c2\u99c3\u99c4\u99c5\u99c6\u99c7\u99c8\u99c9\u99ca\u99cb\u99cc\u99cd\u99ce\u99cf\u99d0\u99d1\u99d2\u99d3\u99d4\u99d5\u99d6\u99d7\u99d8\u99d9\u99da\u99db\u99dc\u99dd\u99de\u99df\u99e0\u99e1\u99e2\u99e3\u99e4\u99e5\u99e6\u99e7\u99e8\u99e9\u99ea\u99eb\u99ec\u99ed\u99ee\u99ef\u99f0\u99f1\u99f2\u99f3\u99f4\u99f5\u99f6\u99f7\u99f8\u99f9\u99fa\u99fb\u99fc\u99fd\u99fe\u99ff\u9a00\u9a01\u9a02\u9a03\u9a04\u9a05\u9a06\u9a07\u9a08\u9a09\u9a0a\u9a0b\u9a0c\u9a0d\u9a0e\u9a0f\u9a10\u9a11\u9a12\u9a13\u9a14\u9a15\u9a16\u9a17\u9a18\u9a19\u9a1a\u9a1b\u9a1c\u9a1d\u9a1e\u9a1f\u9a20\u9a21\u9a22\u9a23\u9a24\u9a25\u9a26\u9a27\u9a28\u9a29\u9a2a\u9a2b\u9a2c\u9a2d\u9a2e\u9a2f\u9a30\u9a31\u9a32\u9a33\u9a34\u9a35\u9a36\u9a37\u9a38\u9a39\u9a3a\u9a3b\u9a3c\u9a3d\u9a3e\u9a3f\u9a40\u9a41\u9a42\u9a43\u9a44\u9a45\u9a46\u9a47\u9a48\u9a49\u9a4a\u9a4b\u9a4c\u9a4d\u9a4e\u9a4f\u9a50\u9a51\u9a52\u9a53\u9a54\u9a55\u9a56\u9a57\u9a58\u9a59\u9a5a\u9a5b\u9a5c\u9a5d\u9a5e\u9a5f\u9a60\u9a61\u9a62\u9a63\u9a64\u9a65\u9a66\u9a67\u9a68\u9a69\u9a6a\u9a6b\u9a6c\u9a6d\u9a6e\u9a6f\u9a70\u9a71\u9a72\u9a73\u9a74\u9a75\u9a76\u9a77\u9a78\u9a79\u9a7a\u9a7b\u9a7c\u9a7d\u9a7e\u9a7f\u9a80\u9a81\u9a82\u9a83\u9a84\u9a85\u9a86\u9a87\u9a88\u9a89\u9a8a\u9a8b\u9a8c\u9a8d\u9a8e\u9a8f\u9a90\u9a91\u9a92\u9a93\u9a94\u9a95\u9a96\u9a97\u9a98\u9a99\u9a9a\u9a9b\u9a9c\u9a9d\u9a9e\u9a9f\u9aa0\u9aa1\u9aa2\u9aa3\u9aa4\u9aa5\u9aa6\u9aa7\u9aa8\u9aa9\u9aaa\u9aab\u9aac\u9aad\u9aae\u9aaf\u9ab0\u9ab1\u9ab2\u9ab3\u9ab4\u9ab5\u9ab6\u9ab7\u9ab8\u9ab9\u9aba\u9abb\u9abc\u9abd\u9abe\u9abf\u9ac0\u9ac1\u9ac2\u9ac3\u9ac4\u9ac5\u9ac6\u9ac7\u9ac8\u9ac9\u9aca\u9acb\u9acc\u9acd\u9ace\u9acf\u9ad0\u9ad1\u9ad2\u9ad3\u9ad4\u9ad5\u9ad6\u9ad7\u9ad8\u9ad9\u9ada\u9adb\u9adc\u9add\u9ade\u9adf\u9ae0\u9ae1\u9ae2\u9ae3\u9ae4\u9ae5\u9ae6\u9ae7\u9ae8\u9ae9\u9aea\u9aeb\u9aec\u9aed\u9aee\u9aef\u9af0\u9af1\u9af2\u9af3\u9af4\u9af5\u9af6\u9af7\u9af8\u9af9\u9afa\u9afb\u9afc\u9afd\u9afe\u9aff\u9b00\u9b01\u9b02\u9b03\u9b04\u9b05\u9b06\u9b07\u9b08\u9b09\u9b0a\u9b0b\u9b0c\u9b0d\u9b0e\u9b0f\u9b10\u9b11\u9b12\u9b13\u9b14\u9b15\u9b16\u9b17\u9b18\u9b19\u9b1a\u9b1b\u9b1c\u9b1d\u9b1e\u9b1f\u9b20\u9b21\u9b22\u9b23\u9b24\u9b25\u9b26\u9b27\u9b28\u9b29\u9b2a\u9b2b\u9b2c\u9b2d\u9b2e\u9b2f\u9b30\u9b31\u9b32\u9b33\u9b34\u9b35\u9b36\u9b37\u9b38\u9b39\u9b3a\u9b3b\u9b3c\u9b3d\u9b3e\u9b3f\u9b40\u9b41\u9b42\u9b43\u9b44\u9b45\u9b46\u9b47\u9b48\u9b49\u9b4a\u9b4b\u9b4c\u9b4d\u9b4e\u9b4f\u9b50\u9b51\u9b52\u9b53\u9b54\u9b55\u9b56\u9b57\u9b58\u9b59\u9b5a\u9b5b\u9b5c\u9b5d\u9b5e\u9b5f\u9b60\u9b61\u9b62\u9b63\u9b64\u9b65\u9b66\u9b67\u9b68\u9b69\u9b6a\u9b6b\u9b6c\u9b6d\u9b6e\u9b6f\u9b70\u9b71\u9b72\u9b73\u9b74\u9b75\u9b76\u9b77\u9b78\u9b79\u9b7a\u9b7b\u9b7c\u9b7d\u9b7e\u9b7f\u9b80\u9b81\u9b82\u9b83\u9b84\u9b85\u9b86\u9b87\u9b88\u9b89\u9b8a\u9b8b\u9b8c\u9b8d\u9b8e\u9b8f\u9b90\u9b91\u9b92\u9b93\u9b94\u9b95\u9b96\u9b97\u9b98\u9b99\u9b9a\u9b9b\u9b9c\u9b9d\u9b9e\u9b9f\u9ba0\u9ba1\u9ba2\u9ba3\u9ba4\u9ba5\u9ba6\u9ba7\u9ba8\u9ba9\u9baa\u9bab\u9bac\u9bad\u9bae\u9baf\u9bb0\u9bb1\u9bb2\u9bb3\u9bb4\u9bb5\u9bb6\u9bb7\u9bb8\u9bb9\u9bba\u9bbb\u9bbc\u9bbd\u9bbe\u9bbf\u9bc0\u9bc1\u9bc2\u9bc3\u9bc4\u9bc5\u9bc6\u9bc7\u9bc8\u9bc9\u9bca\u9bcb\u9bcc\u9bcd\u9bce\u9bcf\u9bd0\u9bd1\u9bd2\u9bd3\u9bd4\u9bd5\u9bd6\u9bd7\u9bd8\u9bd9\u9bda\u9bdb\u9bdc\u9bdd\u9bde\u9bdf\u9be0\u9be1\u9be2\u9be3\u9be4\u9be5\u9be6\u9be7\u9be8\u9be9\u9bea\u9beb\u9bec\u9bed\u9bee\u9bef\u9bf0\u9bf1\u9bf2\u9bf3\u9bf4\u9bf5\u9bf6\u9bf7\u9bf8\u9bf9\u9bfa\u9bfb\u9bfc\u9bfd\u9bfe\u9bff\u9c00\u9c01\u9c02\u9c03\u9c04\u9c05\u9c06\u9c07\u9c08\u9c09\u9c0a\u9c0b\u9c0c\u9c0d\u9c0e\u9c0f\u9c10\u9c11\u9c12\u9c13\u9c14\u9c15\u9c16\u9c17\u9c18\u9c19\u9c1a\u9c1b\u9c1c\u9c1d\u9c1e\u9c1f\u9c20\u9c21\u9c22\u9c23\u9c24\u9c25\u9c26\u9c27\u9c28\u9c29\u9c2a\u9c2b\u9c2c\u9c2d\u9c2e\u9c2f\u9c30\u9c31\u9c32\u9c33\u9c34\u9c35\u9c36\u9c37\u9c38\u9c39\u9c3a\u9c3b\u9c3c\u9c3d\u9c3e\u9c3f\u9c40\u9c41\u9c42\u9c43\u9c44\u9c45\u9c46\u9c47\u9c48\u9c49\u9c4a\u9c4b\u9c4c\u9c4d\u9c4e\u9c4f\u9c50\u9c51\u9c52\u9c53\u9c54\u9c55\u9c56\u9c57\u9c58\u9c59\u9c5a\u9c5b\u9c5c\u9c5d\u9c5e\u9c5f\u9c60\u9c61\u9c62\u9c63\u9c64\u9c65\u9c66\u9c67\u9c68\u9c69\u9c6a\u9c6b\u9c6c\u9c6d\u9c6e\u9c6f\u9c70\u9c71\u9c72\u9c73\u9c74\u9c75\u9c76\u9c77\u9c78\u9c79\u9c7a\u9c7b\u9c7c\u9c7d\u9c7e\u9c7f\u9c80\u9c81\u9c82\u9c83\u9c84\u9c85\u9c86\u9c87\u9c88\u9c89\u9c8a\u9c8b\u9c8c\u9c8d\u9c8e\u9c8f\u9c90\u9c91\u9c92\u9c93\u9c94\u9c95\u9c96\u9c97\u9c98\u9c99\u9c9a\u9c9b\u9c9c\u9c9d\u9c9e\u9c9f\u9ca0\u9ca1\u9ca2\u9ca3\u9ca4\u9ca5\u9ca6\u9ca7\u9ca8\u9ca9\u9caa\u9cab\u9cac\u9cad\u9cae\u9caf\u9cb0\u9cb1\u9cb2\u9cb3\u9cb4\u9cb5\u9cb6\u9cb7\u9cb8\u9cb9\u9cba\u9cbb\u9cbc\u9cbd\u9cbe\u9cbf\u9cc0\u9cc1\u9cc2\u9cc3\u9cc4\u9cc5\u9cc6\u9cc7\u9cc8\u9cc9\u9cca\u9ccb\u9ccc\u9ccd\u9cce\u9ccf\u9cd0\u9cd1\u9cd2\u9cd3\u9cd4\u9cd5\u9cd6\u9cd7\u9cd8\u9cd9\u9cda\u9cdb\u9cdc\u9cdd\u9cde\u9cdf\u9ce0\u9ce1\u9ce2\u9ce3\u9ce4\u9ce5\u9ce6\u9ce7\u9ce8\u9ce9\u9cea\u9ceb\u9cec\u9ced\u9cee\u9cef\u9cf0\u9cf1\u9cf2\u9cf3\u9cf4\u9cf5\u9cf6\u9cf7\u9cf8\u9cf9\u9cfa\u9cfb\u9cfc\u9cfd\u9cfe\u9cff\u9d00\u9d01\u9d02\u9d03\u9d04\u9d05\u9d06\u9d07\u9d08\u9d09\u9d0a\u9d0b\u9d0c\u9d0d\u9d0e\u9d0f\u9d10\u9d11\u9d12\u9d13\u9d14\u9d15\u9d16\u9d17\u9d18\u9d19\u9d1a\u9d1b\u9d1c\u9d1d\u9d1e\u9d1f\u9d20\u9d21\u9d22\u9d23\u9d24\u9d25\u9d26\u9d27\u9d28\u9d29\u9d2a\u9d2b\u9d2c\u9d2d\u9d2e\u9d2f\u9d30\u9d31\u9d32\u9d33\u9d34\u9d35\u9d36\u9d37\u9d38\u9d39\u9d3a\u9d3b\u9d3c\u9d3d\u9d3e\u9d3f\u9d40\u9d41\u9d42\u9d43\u9d44\u9d45\u9d46\u9d47\u9d48\u9d49\u9d4a\u9d4b\u9d4c\u9d4d\u9d4e\u9d4f\u9d50\u9d51\u9d52\u9d53\u9d54\u9d55\u9d56\u9d57\u9d58\u9d59\u9d5a\u9d5b\u9d5c\u9d5d\u9d5e\u9d5f\u9d60\u9d61\u9d62\u9d63\u9d64\u9d65\u9d66\u9d67\u9d68\u9d69\u9d6a\u9d6b\u9d6c\u9d6d\u9d6e\u9d6f\u9d70\u9d71\u9d72\u9d73\u9d74\u9d75\u9d76\u9d77\u9d78\u9d79\u9d7a\u9d7b\u9d7c\u9d7d\u9d7e\u9d7f\u9d80\u9d81\u9d82\u9d83\u9d84\u9d85\u9d86\u9d87\u9d88\u9d89\u9d8a\u9d8b\u9d8c\u9d8d\u9d8e\u9d8f\u9d90\u9d91\u9d92\u9d93\u9d94\u9d95\u9d96\u9d97\u9d98\u9d99\u9d9a\u9d9b\u9d9c\u9d9d\u9d9e\u9d9f\u9da0\u9da1\u9da2\u9da3\u9da4\u9da5\u9da6\u9da7\u9da8\u9da9\u9daa\u9dab\u9dac\u9dad\u9dae\u9daf\u9db0\u9db1\u9db2\u9db3\u9db4\u9db5\u9db6\u9db7\u9db8\u9db9\u9dba\u9dbb\u9dbc\u9dbd\u9dbe\u9dbf\u9dc0\u9dc1\u9dc2\u9dc3\u9dc4\u9dc5\u9dc6\u9dc7\u9dc8\u9dc9\u9dca\u9dcb\u9dcc\u9dcd\u9dce\u9dcf\u9dd0\u9dd1\u9dd2\u9dd3\u9dd4\u9dd5\u9dd6\u9dd7\u9dd8\u9dd9\u9dda\u9ddb\u9ddc\u9ddd\u9dde\u9ddf\u9de0\u9de1\u9de2\u9de3\u9de4\u9de5\u9de6\u9de7\u9de8\u9de9\u9dea\u9deb\u9dec\u9ded\u9dee\u9def\u9df0\u9df1\u9df2\u9df3\u9df4\u9df5\u9df6\u9df7\u9df8\u9df9\u9dfa\u9dfb\u9dfc\u9dfd\u9dfe\u9dff\u9e00\u9e01\u9e02\u9e03\u9e04\u9e05\u9e06\u9e07\u9e08\u9e09\u9e0a\u9e0b\u9e0c\u9e0d\u9e0e\u9e0f\u9e10\u9e11\u9e12\u9e13\u9e14\u9e15\u9e16\u9e17\u9e18\u9e19\u9e1a\u9e1b\u9e1c\u9e1d\u9e1e\u9e1f\u9e20\u9e21\u9e22\u9e23\u9e24\u9e25\u9e26\u9e27\u9e28\u9e29\u9e2a\u9e2b\u9e2c\u9e2d\u9e2e\u9e2f\u9e30\u9e31\u9e32\u9e33\u9e34\u9e35\u9e36\u9e37\u9e38\u9e39\u9e3a\u9e3b\u9e3c\u9e3d\u9e3e\u9e3f\u9e40\u9e41\u9e42\u9e43\u9e44\u9e45\u9e46\u9e47\u9e48\u9e49\u9e4a\u9e4b\u9e4c\u9e4d\u9e4e\u9e4f\u9e50\u9e51\u9e52\u9e53\u9e54\u9e55\u9e56\u9e57\u9e58\u9e59\u9e5a\u9e5b\u9e5c\u9e5d\u9e5e\u9e5f\u9e60\u9e61\u9e62\u9e63\u9e64\u9e65\u9e66\u9e67\u9e68\u9e69\u9e6a\u9e6b\u9e6c\u9e6d\u9e6e\u9e6f\u9e70\u9e71\u9e72\u9e73\u9e74\u9e75\u9e76\u9e77\u9e78\u9e79\u9e7a\u9e7b\u9e7c\u9e7d\u9e7e\u9e7f\u9e80\u9e81\u9e82\u9e83\u9e84\u9e85\u9e86\u9e87\u9e88\u9e89\u9e8a\u9e8b\u9e8c\u9e8d\u9e8e\u9e8f\u9e90\u9e91\u9e92\u9e93\u9e94\u9e95\u9e96\u9e97\u9e98\u9e99\u9e9a\u9e9b\u9e9c\u9e9d\u9e9e\u9e9f\u9ea0\u9ea1\u9ea2\u9ea3\u9ea4\u9ea5\u9ea6\u9ea7\u9ea8\u9ea9\u9eaa\u9eab\u9eac\u9ead\u9eae\u9eaf\u9eb0\u9eb1\u9eb2\u9eb3\u9eb4\u9eb5\u9eb6\u9eb7\u9eb8\u9eb9\u9eba\u9ebb\u9ebc\u9ebd\u9ebe\u9ebf\u9ec0\u9ec1\u9ec2\u9ec3\u9ec4\u9ec5\u9ec6\u9ec7\u9ec8\u9ec9\u9eca\u9ecb\u9ecc\u9ecd\u9ece\u9ecf\u9ed0\u9ed1\u9ed2\u9ed3\u9ed4\u9ed5\u9ed6\u9ed7\u9ed8\u9ed9\u9eda\u9edb\u9edc\u9edd\u9ede\u9edf\u9ee0\u9ee1\u9ee2\u9ee3\u9ee4\u9ee5\u9ee6\u9ee7\u9ee8\u9ee9\u9eea\u9eeb\u9eec\u9eed\u9eee\u9eef\u9ef0\u9ef1\u9ef2\u9ef3\u9ef4\u9ef5\u9ef6\u9ef7\u9ef8\u9ef9\u9efa\u9efb\u9efc\u9efd\u9efe\u9eff\u9f00\u9f01\u9f02\u9f03\u9f04\u9f05\u9f06\u9f07\u9f08\u9f09\u9f0a\u9f0b\u9f0c\u9f0d\u9f0e\u9f0f\u9f10\u9f11\u9f12\u9f13\u9f14\u9f15\u9f16\u9f17\u9f18\u9f19\u9f1a\u9f1b\u9f1c\u9f1d\u9f1e\u9f1f\u9f20\u9f21\u9f22\u9f23\u9f24\u9f25\u9f26\u9f27\u9f28\u9f29\u9f2a\u9f2b\u9f2c\u9f2d\u9f2e\u9f2f\u9f30\u9f31\u9f32\u9f33\u9f34\u9f35\u9f36\u9f37\u9f38\u9f39\u9f3a\u9f3b\u9f3c\u9f3d\u9f3e\u9f3f\u9f40\u9f41\u9f42\u9f43\u9f44\u9f45\u9f46\u9f47\u9f48\u9f49\u9f4a\u9f4b\u9f4c\u9f4d\u9f4e\u9f4f\u9f50\u9f51\u9f52\u9f53\u9f54\u9f55\u9f56\u9f57\u9f58\u9f59\u9f5a\u9f5b\u9f5c\u9f5d\u9f5e\u9f5f\u9f60\u9f61\u9f62\u9f63\u9f64\u9f65\u9f66\u9f67\u9f68\u9f69\u9f6a\u9f6b\u9f6c\u9f6d\u9f6e\u9f6f\u9f70\u9f71\u9f72\u9f73\u9f74\u9f75\u9f76\u9f77\u9f78\u9f79\u9f7a\u9f7b\u9f7c\u9f7d\u9f7e\u9f7f\u9f80\u9f81\u9f82\u9f83\u9f84\u9f85\u9f86\u9f87\u9f88\u9f89\u9f8a\u9f8b\u9f8c\u9f8d\u9f8e\u9f8f\u9f90\u9f91\u9f92\u9f93\u9f94\u9f95\u9f96\u9f97\u9f98\u9f99\u9f9a\u9f9b\u9f9c\u9f9d\u9f9e\u9f9f\u9fa0\u9fa1\u9fa2\u9fa3\u9fa4\u9fa5\u9fa6\u9fa7\u9fa8\u9fa9\u9faa\u9fab\u9fac\u9fad\u9fae\u9faf\u9fb0\u9fb1\u9fb2\u9fb3\u9fb4\u9fb5\u9fb6\u9fb7\u9fb8\u9fb9\u9fba\u9fbb\ua000\ua001\ua002\ua003\ua004\ua005\ua006\ua007\ua008\ua009\ua00a\ua00b\ua00c\ua00d\ua00e\ua00f\ua010\ua011\ua012\ua013\ua014\ua016\ua017\ua018\ua019\ua01a\ua01b\ua01c\ua01d\ua01e\ua01f\ua020\ua021\ua022\ua023\ua024\ua025\ua026\ua027\ua028\ua029\ua02a\ua02b\ua02c\ua02d\ua02e\ua02f\ua030\ua031\ua032\ua033\ua034\ua035\ua036\ua037\ua038\ua039\ua03a\ua03b\ua03c\ua03d\ua03e\ua03f\ua040\ua041\ua042\ua043\ua044\ua045\ua046\ua047\ua048\ua049\ua04a\ua04b\ua04c\ua04d\ua04e\ua04f\ua050\ua051\ua052\ua053\ua054\ua055\ua056\ua057\ua058\ua059\ua05a\ua05b\ua05c\ua05d\ua05e\ua05f\ua060\ua061\ua062\ua063\ua064\ua065\ua066\ua067\ua068\ua069\ua06a\ua06b\ua06c\ua06d\ua06e\ua06f\ua070\ua071\ua072\ua073\ua074\ua075\ua076\ua077\ua078\ua079\ua07a\ua07b\ua07c\ua07d\ua07e\ua07f\ua080\ua081\ua082\ua083\ua084\ua085\ua086\ua087\ua088\ua089\ua08a\ua08b\ua08c\ua08d\ua08e\ua08f\ua090\ua091\ua092\ua093\ua094\ua095\ua096\ua097\ua098\ua099\ua09a\ua09b\ua09c\ua09d\ua09e\ua09f\ua0a0\ua0a1\ua0a2\ua0a3\ua0a4\ua0a5\ua0a6\ua0a7\ua0a8\ua0a9\ua0aa\ua0ab\ua0ac\ua0ad\ua0ae\ua0af\ua0b0\ua0b1\ua0b2\ua0b3\ua0b4\ua0b5\ua0b6\ua0b7\ua0b8\ua0b9\ua0ba\ua0bb\ua0bc\ua0bd\ua0be\ua0bf\ua0c0\ua0c1\ua0c2\ua0c3\ua0c4\ua0c5\ua0c6\ua0c7\ua0c8\ua0c9\ua0ca\ua0cb\ua0cc\ua0cd\ua0ce\ua0cf\ua0d0\ua0d1\ua0d2\ua0d3\ua0d4\ua0d5\ua0d6\ua0d7\ua0d8\ua0d9\ua0da\ua0db\ua0dc\ua0dd\ua0de\ua0df\ua0e0\ua0e1\ua0e2\ua0e3\ua0e4\ua0e5\ua0e6\ua0e7\ua0e8\ua0e9\ua0ea\ua0eb\ua0ec\ua0ed\ua0ee\ua0ef\ua0f0\ua0f1\ua0f2\ua0f3\ua0f4\ua0f5\ua0f6\ua0f7\ua0f8\ua0f9\ua0fa\ua0fb\ua0fc\ua0fd\ua0fe\ua0ff\ua100\ua101\ua102\ua103\ua104\ua105\ua106\ua107\ua108\ua109\ua10a\ua10b\ua10c\ua10d\ua10e\ua10f\ua110\ua111\ua112\ua113\ua114\ua115\ua116\ua117\ua118\ua119\ua11a\ua11b\ua11c\ua11d\ua11e\ua11f\ua120\ua121\ua122\ua123\ua124\ua125\ua126\ua127\ua128\ua129\ua12a\ua12b\ua12c\ua12d\ua12e\ua12f\ua130\ua131\ua132\ua133\ua134\ua135\ua136\ua137\ua138\ua139\ua13a\ua13b\ua13c\ua13d\ua13e\ua13f\ua140\ua141\ua142\ua143\ua144\ua145\ua146\ua147\ua148\ua149\ua14a\ua14b\ua14c\ua14d\ua14e\ua14f\ua150\ua151\ua152\ua153\ua154\ua155\ua156\ua157\ua158\ua159\ua15a\ua15b\ua15c\ua15d\ua15e\ua15f\ua160\ua161\ua162\ua163\ua164\ua165\ua166\ua167\ua168\ua169\ua16a\ua16b\ua16c\ua16d\ua16e\ua16f\ua170\ua171\ua172\ua173\ua174\ua175\ua176\ua177\ua178\ua179\ua17a\ua17b\ua17c\ua17d\ua17e\ua17f\ua180\ua181\ua182\ua183\ua184\ua185\ua186\ua187\ua188\ua189\ua18a\ua18b\ua18c\ua18d\ua18e\ua18f\ua190\ua191\ua192\ua193\ua194\ua195\ua196\ua197\ua198\ua199\ua19a\ua19b\ua19c\ua19d\ua19e\ua19f\ua1a0\ua1a1\ua1a2\ua1a3\ua1a4\ua1a5\ua1a6\ua1a7\ua1a8\ua1a9\ua1aa\ua1ab\ua1ac\ua1ad\ua1ae\ua1af\ua1b0\ua1b1\ua1b2\ua1b3\ua1b4\ua1b5\ua1b6\ua1b7\ua1b8\ua1b9\ua1ba\ua1bb\ua1bc\ua1bd\ua1be\ua1bf\ua1c0\ua1c1\ua1c2\ua1c3\ua1c4\ua1c5\ua1c6\ua1c7\ua1c8\ua1c9\ua1ca\ua1cb\ua1cc\ua1cd\ua1ce\ua1cf\ua1d0\ua1d1\ua1d2\ua1d3\ua1d4\ua1d5\ua1d6\ua1d7\ua1d8\ua1d9\ua1da\ua1db\ua1dc\ua1dd\ua1de\ua1df\ua1e0\ua1e1\ua1e2\ua1e3\ua1e4\ua1e5\ua1e6\ua1e7\ua1e8\ua1e9\ua1ea\ua1eb\ua1ec\ua1ed\ua1ee\ua1ef\ua1f0\ua1f1\ua1f2\ua1f3\ua1f4\ua1f5\ua1f6\ua1f7\ua1f8\ua1f9\ua1fa\ua1fb\ua1fc\ua1fd\ua1fe\ua1ff\ua200\ua201\ua202\ua203\ua204\ua205\ua206\ua207\ua208\ua209\ua20a\ua20b\ua20c\ua20d\ua20e\ua20f\ua210\ua211\ua212\ua213\ua214\ua215\ua216\ua217\ua218\ua219\ua21a\ua21b\ua21c\ua21d\ua21e\ua21f\ua220\ua221\ua222\ua223\ua224\ua225\ua226\ua227\ua228\ua229\ua22a\ua22b\ua22c\ua22d\ua22e\ua22f\ua230\ua231\ua232\ua233\ua234\ua235\ua236\ua237\ua238\ua239\ua23a\ua23b\ua23c\ua23d\ua23e\ua23f\ua240\ua241\ua242\ua243\ua244\ua245\ua246\ua247\ua248\ua249\ua24a\ua24b\ua24c\ua24d\ua24e\ua24f\ua250\ua251\ua252\ua253\ua254\ua255\ua256\ua257\ua258\ua259\ua25a\ua25b\ua25c\ua25d\ua25e\ua25f\ua260\ua261\ua262\ua263\ua264\ua265\ua266\ua267\ua268\ua269\ua26a\ua26b\ua26c\ua26d\ua26e\ua26f\ua270\ua271\ua272\ua273\ua274\ua275\ua276\ua277\ua278\ua279\ua27a\ua27b\ua27c\ua27d\ua27e\ua27f\ua280\ua281\ua282\ua283\ua284\ua285\ua286\ua287\ua288\ua289\ua28a\ua28b\ua28c\ua28d\ua28e\ua28f\ua290\ua291\ua292\ua293\ua294\ua295\ua296\ua297\ua298\ua299\ua29a\ua29b\ua29c\ua29d\ua29e\ua29f\ua2a0\ua2a1\ua2a2\ua2a3\ua2a4\ua2a5\ua2a6\ua2a7\ua2a8\ua2a9\ua2aa\ua2ab\ua2ac\ua2ad\ua2ae\ua2af\ua2b0\ua2b1\ua2b2\ua2b3\ua2b4\ua2b5\ua2b6\ua2b7\ua2b8\ua2b9\ua2ba\ua2bb\ua2bc\ua2bd\ua2be\ua2bf\ua2c0\ua2c1\ua2c2\ua2c3\ua2c4\ua2c5\ua2c6\ua2c7\ua2c8\ua2c9\ua2ca\ua2cb\ua2cc\ua2cd\ua2ce\ua2cf\ua2d0\ua2d1\ua2d2\ua2d3\ua2d4\ua2d5\ua2d6\ua2d7\ua2d8\ua2d9\ua2da\ua2db\ua2dc\ua2dd\ua2de\ua2df\ua2e0\ua2e1\ua2e2\ua2e3\ua2e4\ua2e5\ua2e6\ua2e7\ua2e8\ua2e9\ua2ea\ua2eb\ua2ec\ua2ed\ua2ee\ua2ef\ua2f0\ua2f1\ua2f2\ua2f3\ua2f4\ua2f5\ua2f6\ua2f7\ua2f8\ua2f9\ua2fa\ua2fb\ua2fc\ua2fd\ua2fe\ua2ff\ua300\ua301\ua302\ua303\ua304\ua305\ua306\ua307\ua308\ua309\ua30a\ua30b\ua30c\ua30d\ua30e\ua30f\ua310\ua311\ua312\ua313\ua314\ua315\ua316\ua317\ua318\ua319\ua31a\ua31b\ua31c\ua31d\ua31e\ua31f\ua320\ua321\ua322\ua323\ua324\ua325\ua326\ua327\ua328\ua329\ua32a\ua32b\ua32c\ua32d\ua32e\ua32f\ua330\ua331\ua332\ua333\ua334\ua335\ua336\ua337\ua338\ua339\ua33a\ua33b\ua33c\ua33d\ua33e\ua33f\ua340\ua341\ua342\ua343\ua344\ua345\ua346\ua347\ua348\ua349\ua34a\ua34b\ua34c\ua34d\ua34e\ua34f\ua350\ua351\ua352\ua353\ua354\ua355\ua356\ua357\ua358\ua359\ua35a\ua35b\ua35c\ua35d\ua35e\ua35f\ua360\ua361\ua362\ua363\ua364\ua365\ua366\ua367\ua368\ua369\ua36a\ua36b\ua36c\ua36d\ua36e\ua36f\ua370\ua371\ua372\ua373\ua374\ua375\ua376\ua377\ua378\ua379\ua37a\ua37b\ua37c\ua37d\ua37e\ua37f\ua380\ua381\ua382\ua383\ua384\ua385\ua386\ua387\ua388\ua389\ua38a\ua38b\ua38c\ua38d\ua38e\ua38f\ua390\ua391\ua392\ua393\ua394\ua395\ua396\ua397\ua398\ua399\ua39a\ua39b\ua39c\ua39d\ua39e\ua39f\ua3a0\ua3a1\ua3a2\ua3a3\ua3a4\ua3a5\ua3a6\ua3a7\ua3a8\ua3a9\ua3aa\ua3ab\ua3ac\ua3ad\ua3ae\ua3af\ua3b0\ua3b1\ua3b2\ua3b3\ua3b4\ua3b5\ua3b6\ua3b7\ua3b8\ua3b9\ua3ba\ua3bb\ua3bc\ua3bd\ua3be\ua3bf\ua3c0\ua3c1\ua3c2\ua3c3\ua3c4\ua3c5\ua3c6\ua3c7\ua3c8\ua3c9\ua3ca\ua3cb\ua3cc\ua3cd\ua3ce\ua3cf\ua3d0\ua3d1\ua3d2\ua3d3\ua3d4\ua3d5\ua3d6\ua3d7\ua3d8\ua3d9\ua3da\ua3db\ua3dc\ua3dd\ua3de\ua3df\ua3e0\ua3e1\ua3e2\ua3e3\ua3e4\ua3e5\ua3e6\ua3e7\ua3e8\ua3e9\ua3ea\ua3eb\ua3ec\ua3ed\ua3ee\ua3ef\ua3f0\ua3f1\ua3f2\ua3f3\ua3f4\ua3f5\ua3f6\ua3f7\ua3f8\ua3f9\ua3fa\ua3fb\ua3fc\ua3fd\ua3fe\ua3ff\ua400\ua401\ua402\ua403\ua404\ua405\ua406\ua407\ua408\ua409\ua40a\ua40b\ua40c\ua40d\ua40e\ua40f\ua410\ua411\ua412\ua413\ua414\ua415\ua416\ua417\ua418\ua419\ua41a\ua41b\ua41c\ua41d\ua41e\ua41f\ua420\ua421\ua422\ua423\ua424\ua425\ua426\ua427\ua428\ua429\ua42a\ua42b\ua42c\ua42d\ua42e\ua42f\ua430\ua431\ua432\ua433\ua434\ua435\ua436\ua437\ua438\ua439\ua43a\ua43b\ua43c\ua43d\ua43e\ua43f\ua440\ua441\ua442\ua443\ua444\ua445\ua446\ua447\ua448\ua449\ua44a\ua44b\ua44c\ua44d\ua44e\ua44f\ua450\ua451\ua452\ua453\ua454\ua455\ua456\ua457\ua458\ua459\ua45a\ua45b\ua45c\ua45d\ua45e\ua45f\ua460\ua461\ua462\ua463\ua464\ua465\ua466\ua467\ua468\ua469\ua46a\ua46b\ua46c\ua46d\ua46e\ua46f\ua470\ua471\ua472\ua473\ua474\ua475\ua476\ua477\ua478\ua479\ua47a\ua47b\ua47c\ua47d\ua47e\ua47f\ua480\ua481\ua482\ua483\ua484\ua485\ua486\ua487\ua488\ua489\ua48a\ua48b\ua48c\ua800\ua801\ua803\ua804\ua805\ua807\ua808\ua809\ua80a\ua80c\ua80d\ua80e\ua80f\ua810\ua811\ua812\ua813\ua814\ua815\ua816\ua817\ua818\ua819\ua81a\ua81b\ua81c\ua81d\ua81e\ua81f\ua820\ua821\ua822\uac00\uac01\uac02\uac03\uac04\uac05\uac06\uac07\uac08\uac09\uac0a\uac0b\uac0c\uac0d\uac0e\uac0f\uac10\uac11\uac12\uac13\uac14\uac15\uac16\uac17\uac18\uac19\uac1a\uac1b\uac1c\uac1d\uac1e\uac1f\uac20\uac21\uac22\uac23\uac24\uac25\uac26\uac27\uac28\uac29\uac2a\uac2b\uac2c\uac2d\uac2e\uac2f\uac30\uac31\uac32\uac33\uac34\uac35\uac36\uac37\uac38\uac39\uac3a\uac3b\uac3c\uac3d\uac3e\uac3f\uac40\uac41\uac42\uac43\uac44\uac45\uac46\uac47\uac48\uac49\uac4a\uac4b\uac4c\uac4d\uac4e\uac4f\uac50\uac51\uac52\uac53\uac54\uac55\uac56\uac57\uac58\uac59\uac5a\uac5b\uac5c\uac5d\uac5e\uac5f\uac60\uac61\uac62\uac63\uac64\uac65\uac66\uac67\uac68\uac69\uac6a\uac6b\uac6c\uac6d\uac6e\uac6f\uac70\uac71\uac72\uac73\uac74\uac75\uac76\uac77\uac78\uac79\uac7a\uac7b\uac7c\uac7d\uac7e\uac7f\uac80\uac81\uac82\uac83\uac84\uac85\uac86\uac87\uac88\uac89\uac8a\uac8b\uac8c\uac8d\uac8e\uac8f\uac90\uac91\uac92\uac93\uac94\uac95\uac96\uac97\uac98\uac99\uac9a\uac9b\uac9c\uac9d\uac9e\uac9f\uaca0\uaca1\uaca2\uaca3\uaca4\uaca5\uaca6\uaca7\uaca8\uaca9\uacaa\uacab\uacac\uacad\uacae\uacaf\uacb0\uacb1\uacb2\uacb3\uacb4\uacb5\uacb6\uacb7\uacb8\uacb9\uacba\uacbb\uacbc\uacbd\uacbe\uacbf\uacc0\uacc1\uacc2\uacc3\uacc4\uacc5\uacc6\uacc7\uacc8\uacc9\uacca\uaccb\uaccc\uaccd\uacce\uaccf\uacd0\uacd1\uacd2\uacd3\uacd4\uacd5\uacd6\uacd7\uacd8\uacd9\uacda\uacdb\uacdc\uacdd\uacde\uacdf\uace0\uace1\uace2\uace3\uace4\uace5\uace6\uace7\uace8\uace9\uacea\uaceb\uacec\uaced\uacee\uacef\uacf0\uacf1\uacf2\uacf3\uacf4\uacf5\uacf6\uacf7\uacf8\uacf9\uacfa\uacfb\uacfc\uacfd\uacfe\uacff\uad00\uad01\uad02\uad03\uad04\uad05\uad06\uad07\uad08\uad09\uad0a\uad0b\uad0c\uad0d\uad0e\uad0f\uad10\uad11\uad12\uad13\uad14\uad15\uad16\uad17\uad18\uad19\uad1a\uad1b\uad1c\uad1d\uad1e\uad1f\uad20\uad21\uad22\uad23\uad24\uad25\uad26\uad27\uad28\uad29\uad2a\uad2b\uad2c\uad2d\uad2e\uad2f\uad30\uad31\uad32\uad33\uad34\uad35\uad36\uad37\uad38\uad39\uad3a\uad3b\uad3c\uad3d\uad3e\uad3f\uad40\uad41\uad42\uad43\uad44\uad45\uad46\uad47\uad48\uad49\uad4a\uad4b\uad4c\uad4d\uad4e\uad4f\uad50\uad51\uad52\uad53\uad54\uad55\uad56\uad57\uad58\uad59\uad5a\uad5b\uad5c\uad5d\uad5e\uad5f\uad60\uad61\uad62\uad63\uad64\uad65\uad66\uad67\uad68\uad69\uad6a\uad6b\uad6c\uad6d\uad6e\uad6f\uad70\uad71\uad72\uad73\uad74\uad75\uad76\uad77\uad78\uad79\uad7a\uad7b\uad7c\uad7d\uad7e\uad7f\uad80\uad81\uad82\uad83\uad84\uad85\uad86\uad87\uad88\uad89\uad8a\uad8b\uad8c\uad8d\uad8e\uad8f\uad90\uad91\uad92\uad93\uad94\uad95\uad96\uad97\uad98\uad99\uad9a\uad9b\uad9c\uad9d\uad9e\uad9f\uada0\uada1\uada2\uada3\uada4\uada5\uada6\uada7\uada8\uada9\uadaa\uadab\uadac\uadad\uadae\uadaf\uadb0\uadb1\uadb2\uadb3\uadb4\uadb5\uadb6\uadb7\uadb8\uadb9\uadba\uadbb\uadbc\uadbd\uadbe\uadbf\uadc0\uadc1\uadc2\uadc3\uadc4\uadc5\uadc6\uadc7\uadc8\uadc9\uadca\uadcb\uadcc\uadcd\uadce\uadcf\uadd0\uadd1\uadd2\uadd3\uadd4\uadd5\uadd6\uadd7\uadd8\uadd9\uadda\uaddb\uaddc\uaddd\uadde\uaddf\uade0\uade1\uade2\uade3\uade4\uade5\uade6\uade7\uade8\uade9\uadea\uadeb\uadec\uaded\uadee\uadef\uadf0\uadf1\uadf2\uadf3\uadf4\uadf5\uadf6\uadf7\uadf8\uadf9\uadfa\uadfb\uadfc\uadfd\uadfe\uadff\uae00\uae01\uae02\uae03\uae04\uae05\uae06\uae07\uae08\uae09\uae0a\uae0b\uae0c\uae0d\uae0e\uae0f\uae10\uae11\uae12\uae13\uae14\uae15\uae16\uae17\uae18\uae19\uae1a\uae1b\uae1c\uae1d\uae1e\uae1f\uae20\uae21\uae22\uae23\uae24\uae25\uae26\uae27\uae28\uae29\uae2a\uae2b\uae2c\uae2d\uae2e\uae2f\uae30\uae31\uae32\uae33\uae34\uae35\uae36\uae37\uae38\uae39\uae3a\uae3b\uae3c\uae3d\uae3e\uae3f\uae40\uae41\uae42\uae43\uae44\uae45\uae46\uae47\uae48\uae49\uae4a\uae4b\uae4c\uae4d\uae4e\uae4f\uae50\uae51\uae52\uae53\uae54\uae55\uae56\uae57\uae58\uae59\uae5a\uae5b\uae5c\uae5d\uae5e\uae5f\uae60\uae61\uae62\uae63\uae64\uae65\uae66\uae67\uae68\uae69\uae6a\uae6b\uae6c\uae6d\uae6e\uae6f\uae70\uae71\uae72\uae73\uae74\uae75\uae76\uae77\uae78\uae79\uae7a\uae7b\uae7c\uae7d\uae7e\uae7f\uae80\uae81\uae82\uae83\uae84\uae85\uae86\uae87\uae88\uae89\uae8a\uae8b\uae8c\uae8d\uae8e\uae8f\uae90\uae91\uae92\uae93\uae94\uae95\uae96\uae97\uae98\uae99\uae9a\uae9b\uae9c\uae9d\uae9e\uae9f\uaea0\uaea1\uaea2\uaea3\uaea4\uaea5\uaea6\uaea7\uaea8\uaea9\uaeaa\uaeab\uaeac\uaead\uaeae\uaeaf\uaeb0\uaeb1\uaeb2\uaeb3\uaeb4\uaeb5\uaeb6\uaeb7\uaeb8\uaeb9\uaeba\uaebb\uaebc\uaebd\uaebe\uaebf\uaec0\uaec1\uaec2\uaec3\uaec4\uaec5\uaec6\uaec7\uaec8\uaec9\uaeca\uaecb\uaecc\uaecd\uaece\uaecf\uaed0\uaed1\uaed2\uaed3\uaed4\uaed5\uaed6\uaed7\uaed8\uaed9\uaeda\uaedb\uaedc\uaedd\uaede\uaedf\uaee0\uaee1\uaee2\uaee3\uaee4\uaee5\uaee6\uaee7\uaee8\uaee9\uaeea\uaeeb\uaeec\uaeed\uaeee\uaeef\uaef0\uaef1\uaef2\uaef3\uaef4\uaef5\uaef6\uaef7\uaef8\uaef9\uaefa\uaefb\uaefc\uaefd\uaefe\uaeff\uaf00\uaf01\uaf02\uaf03\uaf04\uaf05\uaf06\uaf07\uaf08\uaf09\uaf0a\uaf0b\uaf0c\uaf0d\uaf0e\uaf0f\uaf10\uaf11\uaf12\uaf13\uaf14\uaf15\uaf16\uaf17\uaf18\uaf19\uaf1a\uaf1b\uaf1c\uaf1d\uaf1e\uaf1f\uaf20\uaf21\uaf22\uaf23\uaf24\uaf25\uaf26\uaf27\uaf28\uaf29\uaf2a\uaf2b\uaf2c\uaf2d\uaf2e\uaf2f\uaf30\uaf31\uaf32\uaf33\uaf34\uaf35\uaf36\uaf37\uaf38\uaf39\uaf3a\uaf3b\uaf3c\uaf3d\uaf3e\uaf3f\uaf40\uaf41\uaf42\uaf43\uaf44\uaf45\uaf46\uaf47\uaf48\uaf49\uaf4a\uaf4b\uaf4c\uaf4d\uaf4e\uaf4f\uaf50\uaf51\uaf52\uaf53\uaf54\uaf55\uaf56\uaf57\uaf58\uaf59\uaf5a\uaf5b\uaf5c\uaf5d\uaf5e\uaf5f\uaf60\uaf61\uaf62\uaf63\uaf64\uaf65\uaf66\uaf67\uaf68\uaf69\uaf6a\uaf6b\uaf6c\uaf6d\uaf6e\uaf6f\uaf70\uaf71\uaf72\uaf73\uaf74\uaf75\uaf76\uaf77\uaf78\uaf79\uaf7a\uaf7b\uaf7c\uaf7d\uaf7e\uaf7f\uaf80\uaf81\uaf82\uaf83\uaf84\uaf85\uaf86\uaf87\uaf88\uaf89\uaf8a\uaf8b\uaf8c\uaf8d\uaf8e\uaf8f\uaf90\uaf91\uaf92\uaf93\uaf94\uaf95\uaf96\uaf97\uaf98\uaf99\uaf9a\uaf9b\uaf9c\uaf9d\uaf9e\uaf9f\uafa0\uafa1\uafa2\uafa3\uafa4\uafa5\uafa6\uafa7\uafa8\uafa9\uafaa\uafab\uafac\uafad\uafae\uafaf\uafb0\uafb1\uafb2\uafb3\uafb4\uafb5\uafb6\uafb7\uafb8\uafb9\uafba\uafbb\uafbc\uafbd\uafbe\uafbf\uafc0\uafc1\uafc2\uafc3\uafc4\uafc5\uafc6\uafc7\uafc8\uafc9\uafca\uafcb\uafcc\uafcd\uafce\uafcf\uafd0\uafd1\uafd2\uafd3\uafd4\uafd5\uafd6\uafd7\uafd8\uafd9\uafda\uafdb\uafdc\uafdd\uafde\uafdf\uafe0\uafe1\uafe2\uafe3\uafe4\uafe5\uafe6\uafe7\uafe8\uafe9\uafea\uafeb\uafec\uafed\uafee\uafef\uaff0\uaff1\uaff2\uaff3\uaff4\uaff5\uaff6\uaff7\uaff8\uaff9\uaffa\uaffb\uaffc\uaffd\uaffe\uafff\ub000\ub001\ub002\ub003\ub004\ub005\ub006\ub007\ub008\ub009\ub00a\ub00b\ub00c\ub00d\ub00e\ub00f\ub010\ub011\ub012\ub013\ub014\ub015\ub016\ub017\ub018\ub019\ub01a\ub01b\ub01c\ub01d\ub01e\ub01f\ub020\ub021\ub022\ub023\ub024\ub025\ub026\ub027\ub028\ub029\ub02a\ub02b\ub02c\ub02d\ub02e\ub02f\ub030\ub031\ub032\ub033\ub034\ub035\ub036\ub037\ub038\ub039\ub03a\ub03b\ub03c\ub03d\ub03e\ub03f\ub040\ub041\ub042\ub043\ub044\ub045\ub046\ub047\ub048\ub049\ub04a\ub04b\ub04c\ub04d\ub04e\ub04f\ub050\ub051\ub052\ub053\ub054\ub055\ub056\ub057\ub058\ub059\ub05a\ub05b\ub05c\ub05d\ub05e\ub05f\ub060\ub061\ub062\ub063\ub064\ub065\ub066\ub067\ub068\ub069\ub06a\ub06b\ub06c\ub06d\ub06e\ub06f\ub070\ub071\ub072\ub073\ub074\ub075\ub076\ub077\ub078\ub079\ub07a\ub07b\ub07c\ub07d\ub07e\ub07f\ub080\ub081\ub082\ub083\ub084\ub085\ub086\ub087\ub088\ub089\ub08a\ub08b\ub08c\ub08d\ub08e\ub08f\ub090\ub091\ub092\ub093\ub094\ub095\ub096\ub097\ub098\ub099\ub09a\ub09b\ub09c\ub09d\ub09e\ub09f\ub0a0\ub0a1\ub0a2\ub0a3\ub0a4\ub0a5\ub0a6\ub0a7\ub0a8\ub0a9\ub0aa\ub0ab\ub0ac\ub0ad\ub0ae\ub0af\ub0b0\ub0b1\ub0b2\ub0b3\ub0b4\ub0b5\ub0b6\ub0b7\ub0b8\ub0b9\ub0ba\ub0bb\ub0bc\ub0bd\ub0be\ub0bf\ub0c0\ub0c1\ub0c2\ub0c3\ub0c4\ub0c5\ub0c6\ub0c7\ub0c8\ub0c9\ub0ca\ub0cb\ub0cc\ub0cd\ub0ce\ub0cf\ub0d0\ub0d1\ub0d2\ub0d3\ub0d4\ub0d5\ub0d6\ub0d7\ub0d8\ub0d9\ub0da\ub0db\ub0dc\ub0dd\ub0de\ub0df\ub0e0\ub0e1\ub0e2\ub0e3\ub0e4\ub0e5\ub0e6\ub0e7\ub0e8\ub0e9\ub0ea\ub0eb\ub0ec\ub0ed\ub0ee\ub0ef\ub0f0\ub0f1\ub0f2\ub0f3\ub0f4\ub0f5\ub0f6\ub0f7\ub0f8\ub0f9\ub0fa\ub0fb\ub0fc\ub0fd\ub0fe\ub0ff\ub100\ub101\ub102\ub103\ub104\ub105\ub106\ub107\ub108\ub109\ub10a\ub10b\ub10c\ub10d\ub10e\ub10f\ub110\ub111\ub112\ub113\ub114\ub115\ub116\ub117\ub118\ub119\ub11a\ub11b\ub11c\ub11d\ub11e\ub11f\ub120\ub121\ub122\ub123\ub124\ub125\ub126\ub127\ub128\ub129\ub12a\ub12b\ub12c\ub12d\ub12e\ub12f\ub130\ub131\ub132\ub133\ub134\ub135\ub136\ub137\ub138\ub139\ub13a\ub13b\ub13c\ub13d\ub13e\ub13f\ub140\ub141\ub142\ub143\ub144\ub145\ub146\ub147\ub148\ub149\ub14a\ub14b\ub14c\ub14d\ub14e\ub14f\ub150\ub151\ub152\ub153\ub154\ub155\ub156\ub157\ub158\ub159\ub15a\ub15b\ub15c\ub15d\ub15e\ub15f\ub160\ub161\ub162\ub163\ub164\ub165\ub166\ub167\ub168\ub169\ub16a\ub16b\ub16c\ub16d\ub16e\ub16f\ub170\ub171\ub172\ub173\ub174\ub175\ub176\ub177\ub178\ub179\ub17a\ub17b\ub17c\ub17d\ub17e\ub17f\ub180\ub181\ub182\ub183\ub184\ub185\ub186\ub187\ub188\ub189\ub18a\ub18b\ub18c\ub18d\ub18e\ub18f\ub190\ub191\ub192\ub193\ub194\ub195\ub196\ub197\ub198\ub199\ub19a\ub19b\ub19c\ub19d\ub19e\ub19f\ub1a0\ub1a1\ub1a2\ub1a3\ub1a4\ub1a5\ub1a6\ub1a7\ub1a8\ub1a9\ub1aa\ub1ab\ub1ac\ub1ad\ub1ae\ub1af\ub1b0\ub1b1\ub1b2\ub1b3\ub1b4\ub1b5\ub1b6\ub1b7\ub1b8\ub1b9\ub1ba\ub1bb\ub1bc\ub1bd\ub1be\ub1bf\ub1c0\ub1c1\ub1c2\ub1c3\ub1c4\ub1c5\ub1c6\ub1c7\ub1c8\ub1c9\ub1ca\ub1cb\ub1cc\ub1cd\ub1ce\ub1cf\ub1d0\ub1d1\ub1d2\ub1d3\ub1d4\ub1d5\ub1d6\ub1d7\ub1d8\ub1d9\ub1da\ub1db\ub1dc\ub1dd\ub1de\ub1df\ub1e0\ub1e1\ub1e2\ub1e3\ub1e4\ub1e5\ub1e6\ub1e7\ub1e8\ub1e9\ub1ea\ub1eb\ub1ec\ub1ed\ub1ee\ub1ef\ub1f0\ub1f1\ub1f2\ub1f3\ub1f4\ub1f5\ub1f6\ub1f7\ub1f8\ub1f9\ub1fa\ub1fb\ub1fc\ub1fd\ub1fe\ub1ff\ub200\ub201\ub202\ub203\ub204\ub205\ub206\ub207\ub208\ub209\ub20a\ub20b\ub20c\ub20d\ub20e\ub20f\ub210\ub211\ub212\ub213\ub214\ub215\ub216\ub217\ub218\ub219\ub21a\ub21b\ub21c\ub21d\ub21e\ub21f\ub220\ub221\ub222\ub223\ub224\ub225\ub226\ub227\ub228\ub229\ub22a\ub22b\ub22c\ub22d\ub22e\ub22f\ub230\ub231\ub232\ub233\ub234\ub235\ub236\ub237\ub238\ub239\ub23a\ub23b\ub23c\ub23d\ub23e\ub23f\ub240\ub241\ub242\ub243\ub244\ub245\ub246\ub247\ub248\ub249\ub24a\ub24b\ub24c\ub24d\ub24e\ub24f\ub250\ub251\ub252\ub253\ub254\ub255\ub256\ub257\ub258\ub259\ub25a\ub25b\ub25c\ub25d\ub25e\ub25f\ub260\ub261\ub262\ub263\ub264\ub265\ub266\ub267\ub268\ub269\ub26a\ub26b\ub26c\ub26d\ub26e\ub26f\ub270\ub271\ub272\ub273\ub274\ub275\ub276\ub277\ub278\ub279\ub27a\ub27b\ub27c\ub27d\ub27e\ub27f\ub280\ub281\ub282\ub283\ub284\ub285\ub286\ub287\ub288\ub289\ub28a\ub28b\ub28c\ub28d\ub28e\ub28f\ub290\ub291\ub292\ub293\ub294\ub295\ub296\ub297\ub298\ub299\ub29a\ub29b\ub29c\ub29d\ub29e\ub29f\ub2a0\ub2a1\ub2a2\ub2a3\ub2a4\ub2a5\ub2a6\ub2a7\ub2a8\ub2a9\ub2aa\ub2ab\ub2ac\ub2ad\ub2ae\ub2af\ub2b0\ub2b1\ub2b2\ub2b3\ub2b4\ub2b5\ub2b6\ub2b7\ub2b8\ub2b9\ub2ba\ub2bb\ub2bc\ub2bd\ub2be\ub2bf\ub2c0\ub2c1\ub2c2\ub2c3\ub2c4\ub2c5\ub2c6\ub2c7\ub2c8\ub2c9\ub2ca\ub2cb\ub2cc\ub2cd\ub2ce\ub2cf\ub2d0\ub2d1\ub2d2\ub2d3\ub2d4\ub2d5\ub2d6\ub2d7\ub2d8\ub2d9\ub2da\ub2db\ub2dc\ub2dd\ub2de\ub2df\ub2e0\ub2e1\ub2e2\ub2e3\ub2e4\ub2e5\ub2e6\ub2e7\ub2e8\ub2e9\ub2ea\ub2eb\ub2ec\ub2ed\ub2ee\ub2ef\ub2f0\ub2f1\ub2f2\ub2f3\ub2f4\ub2f5\ub2f6\ub2f7\ub2f8\ub2f9\ub2fa\ub2fb\ub2fc\ub2fd\ub2fe\ub2ff\ub300\ub301\ub302\ub303\ub304\ub305\ub306\ub307\ub308\ub309\ub30a\ub30b\ub30c\ub30d\ub30e\ub30f\ub310\ub311\ub312\ub313\ub314\ub315\ub316\ub317\ub318\ub319\ub31a\ub31b\ub31c\ub31d\ub31e\ub31f\ub320\ub321\ub322\ub323\ub324\ub325\ub326\ub327\ub328\ub329\ub32a\ub32b\ub32c\ub32d\ub32e\ub32f\ub330\ub331\ub332\ub333\ub334\ub335\ub336\ub337\ub338\ub339\ub33a\ub33b\ub33c\ub33d\ub33e\ub33f\ub340\ub341\ub342\ub343\ub344\ub345\ub346\ub347\ub348\ub349\ub34a\ub34b\ub34c\ub34d\ub34e\ub34f\ub350\ub351\ub352\ub353\ub354\ub355\ub356\ub357\ub358\ub359\ub35a\ub35b\ub35c\ub35d\ub35e\ub35f\ub360\ub361\ub362\ub363\ub364\ub365\ub366\ub367\ub368\ub369\ub36a\ub36b\ub36c\ub36d\ub36e\ub36f\ub370\ub371\ub372\ub373\ub374\ub375\ub376\ub377\ub378\ub379\ub37a\ub37b\ub37c\ub37d\ub37e\ub37f\ub380\ub381\ub382\ub383\ub384\ub385\ub386\ub387\ub388\ub389\ub38a\ub38b\ub38c\ub38d\ub38e\ub38f\ub390\ub391\ub392\ub393\ub394\ub395\ub396\ub397\ub398\ub399\ub39a\ub39b\ub39c\ub39d\ub39e\ub39f\ub3a0\ub3a1\ub3a2\ub3a3\ub3a4\ub3a5\ub3a6\ub3a7\ub3a8\ub3a9\ub3aa\ub3ab\ub3ac\ub3ad\ub3ae\ub3af\ub3b0\ub3b1\ub3b2\ub3b3\ub3b4\ub3b5\ub3b6\ub3b7\ub3b8\ub3b9\ub3ba\ub3bb\ub3bc\ub3bd\ub3be\ub3bf\ub3c0\ub3c1\ub3c2\ub3c3\ub3c4\ub3c5\ub3c6\ub3c7\ub3c8\ub3c9\ub3ca\ub3cb\ub3cc\ub3cd\ub3ce\ub3cf\ub3d0\ub3d1\ub3d2\ub3d3\ub3d4\ub3d5\ub3d6\ub3d7\ub3d8\ub3d9\ub3da\ub3db\ub3dc\ub3dd\ub3de\ub3df\ub3e0\ub3e1\ub3e2\ub3e3\ub3e4\ub3e5\ub3e6\ub3e7\ub3e8\ub3e9\ub3ea\ub3eb\ub3ec\ub3ed\ub3ee\ub3ef\ub3f0\ub3f1\ub3f2\ub3f3\ub3f4\ub3f5\ub3f6\ub3f7\ub3f8\ub3f9\ub3fa\ub3fb\ub3fc\ub3fd\ub3fe\ub3ff\ub400\ub401\ub402\ub403\ub404\ub405\ub406\ub407\ub408\ub409\ub40a\ub40b\ub40c\ub40d\ub40e\ub40f\ub410\ub411\ub412\ub413\ub414\ub415\ub416\ub417\ub418\ub419\ub41a\ub41b\ub41c\ub41d\ub41e\ub41f\ub420\ub421\ub422\ub423\ub424\ub425\ub426\ub427\ub428\ub429\ub42a\ub42b\ub42c\ub42d\ub42e\ub42f\ub430\ub431\ub432\ub433\ub434\ub435\ub436\ub437\ub438\ub439\ub43a\ub43b\ub43c\ub43d\ub43e\ub43f\ub440\ub441\ub442\ub443\ub444\ub445\ub446\ub447\ub448\ub449\ub44a\ub44b\ub44c\ub44d\ub44e\ub44f\ub450\ub451\ub452\ub453\ub454\ub455\ub456\ub457\ub458\ub459\ub45a\ub45b\ub45c\ub45d\ub45e\ub45f\ub460\ub461\ub462\ub463\ub464\ub465\ub466\ub467\ub468\ub469\ub46a\ub46b\ub46c\ub46d\ub46e\ub46f\ub470\ub471\ub472\ub473\ub474\ub475\ub476\ub477\ub478\ub479\ub47a\ub47b\ub47c\ub47d\ub47e\ub47f\ub480\ub481\ub482\ub483\ub484\ub485\ub486\ub487\ub488\ub489\ub48a\ub48b\ub48c\ub48d\ub48e\ub48f\ub490\ub491\ub492\ub493\ub494\ub495\ub496\ub497\ub498\ub499\ub49a\ub49b\ub49c\ub49d\ub49e\ub49f\ub4a0\ub4a1\ub4a2\ub4a3\ub4a4\ub4a5\ub4a6\ub4a7\ub4a8\ub4a9\ub4aa\ub4ab\ub4ac\ub4ad\ub4ae\ub4af\ub4b0\ub4b1\ub4b2\ub4b3\ub4b4\ub4b5\ub4b6\ub4b7\ub4b8\ub4b9\ub4ba\ub4bb\ub4bc\ub4bd\ub4be\ub4bf\ub4c0\ub4c1\ub4c2\ub4c3\ub4c4\ub4c5\ub4c6\ub4c7\ub4c8\ub4c9\ub4ca\ub4cb\ub4cc\ub4cd\ub4ce\ub4cf\ub4d0\ub4d1\ub4d2\ub4d3\ub4d4\ub4d5\ub4d6\ub4d7\ub4d8\ub4d9\ub4da\ub4db\ub4dc\ub4dd\ub4de\ub4df\ub4e0\ub4e1\ub4e2\ub4e3\ub4e4\ub4e5\ub4e6\ub4e7\ub4e8\ub4e9\ub4ea\ub4eb\ub4ec\ub4ed\ub4ee\ub4ef\ub4f0\ub4f1\ub4f2\ub4f3\ub4f4\ub4f5\ub4f6\ub4f7\ub4f8\ub4f9\ub4fa\ub4fb\ub4fc\ub4fd\ub4fe\ub4ff\ub500\ub501\ub502\ub503\ub504\ub505\ub506\ub507\ub508\ub509\ub50a\ub50b\ub50c\ub50d\ub50e\ub50f\ub510\ub511\ub512\ub513\ub514\ub515\ub516\ub517\ub518\ub519\ub51a\ub51b\ub51c\ub51d\ub51e\ub51f\ub520\ub521\ub522\ub523\ub524\ub525\ub526\ub527\ub528\ub529\ub52a\ub52b\ub52c\ub52d\ub52e\ub52f\ub530\ub531\ub532\ub533\ub534\ub535\ub536\ub537\ub538\ub539\ub53a\ub53b\ub53c\ub53d\ub53e\ub53f\ub540\ub541\ub542\ub543\ub544\ub545\ub546\ub547\ub548\ub549\ub54a\ub54b\ub54c\ub54d\ub54e\ub54f\ub550\ub551\ub552\ub553\ub554\ub555\ub556\ub557\ub558\ub559\ub55a\ub55b\ub55c\ub55d\ub55e\ub55f\ub560\ub561\ub562\ub563\ub564\ub565\ub566\ub567\ub568\ub569\ub56a\ub56b\ub56c\ub56d\ub56e\ub56f\ub570\ub571\ub572\ub573\ub574\ub575\ub576\ub577\ub578\ub579\ub57a\ub57b\ub57c\ub57d\ub57e\ub57f\ub580\ub581\ub582\ub583\ub584\ub585\ub586\ub587\ub588\ub589\ub58a\ub58b\ub58c\ub58d\ub58e\ub58f\ub590\ub591\ub592\ub593\ub594\ub595\ub596\ub597\ub598\ub599\ub59a\ub59b\ub59c\ub59d\ub59e\ub59f\ub5a0\ub5a1\ub5a2\ub5a3\ub5a4\ub5a5\ub5a6\ub5a7\ub5a8\ub5a9\ub5aa\ub5ab\ub5ac\ub5ad\ub5ae\ub5af\ub5b0\ub5b1\ub5b2\ub5b3\ub5b4\ub5b5\ub5b6\ub5b7\ub5b8\ub5b9\ub5ba\ub5bb\ub5bc\ub5bd\ub5be\ub5bf\ub5c0\ub5c1\ub5c2\ub5c3\ub5c4\ub5c5\ub5c6\ub5c7\ub5c8\ub5c9\ub5ca\ub5cb\ub5cc\ub5cd\ub5ce\ub5cf\ub5d0\ub5d1\ub5d2\ub5d3\ub5d4\ub5d5\ub5d6\ub5d7\ub5d8\ub5d9\ub5da\ub5db\ub5dc\ub5dd\ub5de\ub5df\ub5e0\ub5e1\ub5e2\ub5e3\ub5e4\ub5e5\ub5e6\ub5e7\ub5e8\ub5e9\ub5ea\ub5eb\ub5ec\ub5ed\ub5ee\ub5ef\ub5f0\ub5f1\ub5f2\ub5f3\ub5f4\ub5f5\ub5f6\ub5f7\ub5f8\ub5f9\ub5fa\ub5fb\ub5fc\ub5fd\ub5fe\ub5ff\ub600\ub601\ub602\ub603\ub604\ub605\ub606\ub607\ub608\ub609\ub60a\ub60b\ub60c\ub60d\ub60e\ub60f\ub610\ub611\ub612\ub613\ub614\ub615\ub616\ub617\ub618\ub619\ub61a\ub61b\ub61c\ub61d\ub61e\ub61f\ub620\ub621\ub622\ub623\ub624\ub625\ub626\ub627\ub628\ub629\ub62a\ub62b\ub62c\ub62d\ub62e\ub62f\ub630\ub631\ub632\ub633\ub634\ub635\ub636\ub637\ub638\ub639\ub63a\ub63b\ub63c\ub63d\ub63e\ub63f\ub640\ub641\ub642\ub643\ub644\ub645\ub646\ub647\ub648\ub649\ub64a\ub64b\ub64c\ub64d\ub64e\ub64f\ub650\ub651\ub652\ub653\ub654\ub655\ub656\ub657\ub658\ub659\ub65a\ub65b\ub65c\ub65d\ub65e\ub65f\ub660\ub661\ub662\ub663\ub664\ub665\ub666\ub667\ub668\ub669\ub66a\ub66b\ub66c\ub66d\ub66e\ub66f\ub670\ub671\ub672\ub673\ub674\ub675\ub676\ub677\ub678\ub679\ub67a\ub67b\ub67c\ub67d\ub67e\ub67f\ub680\ub681\ub682\ub683\ub684\ub685\ub686\ub687\ub688\ub689\ub68a\ub68b\ub68c\ub68d\ub68e\ub68f\ub690\ub691\ub692\ub693\ub694\ub695\ub696\ub697\ub698\ub699\ub69a\ub69b\ub69c\ub69d\ub69e\ub69f\ub6a0\ub6a1\ub6a2\ub6a3\ub6a4\ub6a5\ub6a6\ub6a7\ub6a8\ub6a9\ub6aa\ub6ab\ub6ac\ub6ad\ub6ae\ub6af\ub6b0\ub6b1\ub6b2\ub6b3\ub6b4\ub6b5\ub6b6\ub6b7\ub6b8\ub6b9\ub6ba\ub6bb\ub6bc\ub6bd\ub6be\ub6bf\ub6c0\ub6c1\ub6c2\ub6c3\ub6c4\ub6c5\ub6c6\ub6c7\ub6c8\ub6c9\ub6ca\ub6cb\ub6cc\ub6cd\ub6ce\ub6cf\ub6d0\ub6d1\ub6d2\ub6d3\ub6d4\ub6d5\ub6d6\ub6d7\ub6d8\ub6d9\ub6da\ub6db\ub6dc\ub6dd\ub6de\ub6df\ub6e0\ub6e1\ub6e2\ub6e3\ub6e4\ub6e5\ub6e6\ub6e7\ub6e8\ub6e9\ub6ea\ub6eb\ub6ec\ub6ed\ub6ee\ub6ef\ub6f0\ub6f1\ub6f2\ub6f3\ub6f4\ub6f5\ub6f6\ub6f7\ub6f8\ub6f9\ub6fa\ub6fb\ub6fc\ub6fd\ub6fe\ub6ff\ub700\ub701\ub702\ub703\ub704\ub705\ub706\ub707\ub708\ub709\ub70a\ub70b\ub70c\ub70d\ub70e\ub70f\ub710\ub711\ub712\ub713\ub714\ub715\ub716\ub717\ub718\ub719\ub71a\ub71b\ub71c\ub71d\ub71e\ub71f\ub720\ub721\ub722\ub723\ub724\ub725\ub726\ub727\ub728\ub729\ub72a\ub72b\ub72c\ub72d\ub72e\ub72f\ub730\ub731\ub732\ub733\ub734\ub735\ub736\ub737\ub738\ub739\ub73a\ub73b\ub73c\ub73d\ub73e\ub73f\ub740\ub741\ub742\ub743\ub744\ub745\ub746\ub747\ub748\ub749\ub74a\ub74b\ub74c\ub74d\ub74e\ub74f\ub750\ub751\ub752\ub753\ub754\ub755\ub756\ub757\ub758\ub759\ub75a\ub75b\ub75c\ub75d\ub75e\ub75f\ub760\ub761\ub762\ub763\ub764\ub765\ub766\ub767\ub768\ub769\ub76a\ub76b\ub76c\ub76d\ub76e\ub76f\ub770\ub771\ub772\ub773\ub774\ub775\ub776\ub777\ub778\ub779\ub77a\ub77b\ub77c\ub77d\ub77e\ub77f\ub780\ub781\ub782\ub783\ub784\ub785\ub786\ub787\ub788\ub789\ub78a\ub78b\ub78c\ub78d\ub78e\ub78f\ub790\ub791\ub792\ub793\ub794\ub795\ub796\ub797\ub798\ub799\ub79a\ub79b\ub79c\ub79d\ub79e\ub79f\ub7a0\ub7a1\ub7a2\ub7a3\ub7a4\ub7a5\ub7a6\ub7a7\ub7a8\ub7a9\ub7aa\ub7ab\ub7ac\ub7ad\ub7ae\ub7af\ub7b0\ub7b1\ub7b2\ub7b3\ub7b4\ub7b5\ub7b6\ub7b7\ub7b8\ub7b9\ub7ba\ub7bb\ub7bc\ub7bd\ub7be\ub7bf\ub7c0\ub7c1\ub7c2\ub7c3\ub7c4\ub7c5\ub7c6\ub7c7\ub7c8\ub7c9\ub7ca\ub7cb\ub7cc\ub7cd\ub7ce\ub7cf\ub7d0\ub7d1\ub7d2\ub7d3\ub7d4\ub7d5\ub7d6\ub7d7\ub7d8\ub7d9\ub7da\ub7db\ub7dc\ub7dd\ub7de\ub7df\ub7e0\ub7e1\ub7e2\ub7e3\ub7e4\ub7e5\ub7e6\ub7e7\ub7e8\ub7e9\ub7ea\ub7eb\ub7ec\ub7ed\ub7ee\ub7ef\ub7f0\ub7f1\ub7f2\ub7f3\ub7f4\ub7f5\ub7f6\ub7f7\ub7f8\ub7f9\ub7fa\ub7fb\ub7fc\ub7fd\ub7fe\ub7ff\ub800\ub801\ub802\ub803\ub804\ub805\ub806\ub807\ub808\ub809\ub80a\ub80b\ub80c\ub80d\ub80e\ub80f\ub810\ub811\ub812\ub813\ub814\ub815\ub816\ub817\ub818\ub819\ub81a\ub81b\ub81c\ub81d\ub81e\ub81f\ub820\ub821\ub822\ub823\ub824\ub825\ub826\ub827\ub828\ub829\ub82a\ub82b\ub82c\ub82d\ub82e\ub82f\ub830\ub831\ub832\ub833\ub834\ub835\ub836\ub837\ub838\ub839\ub83a\ub83b\ub83c\ub83d\ub83e\ub83f\ub840\ub841\ub842\ub843\ub844\ub845\ub846\ub847\ub848\ub849\ub84a\ub84b\ub84c\ub84d\ub84e\ub84f\ub850\ub851\ub852\ub853\ub854\ub855\ub856\ub857\ub858\ub859\ub85a\ub85b\ub85c\ub85d\ub85e\ub85f\ub860\ub861\ub862\ub863\ub864\ub865\ub866\ub867\ub868\ub869\ub86a\ub86b\ub86c\ub86d\ub86e\ub86f\ub870\ub871\ub872\ub873\ub874\ub875\ub876\ub877\ub878\ub879\ub87a\ub87b\ub87c\ub87d\ub87e\ub87f\ub880\ub881\ub882\ub883\ub884\ub885\ub886\ub887\ub888\ub889\ub88a\ub88b\ub88c\ub88d\ub88e\ub88f\ub890\ub891\ub892\ub893\ub894\ub895\ub896\ub897\ub898\ub899\ub89a\ub89b\ub89c\ub89d\ub89e\ub89f\ub8a0\ub8a1\ub8a2\ub8a3\ub8a4\ub8a5\ub8a6\ub8a7\ub8a8\ub8a9\ub8aa\ub8ab\ub8ac\ub8ad\ub8ae\ub8af\ub8b0\ub8b1\ub8b2\ub8b3\ub8b4\ub8b5\ub8b6\ub8b7\ub8b8\ub8b9\ub8ba\ub8bb\ub8bc\ub8bd\ub8be\ub8bf\ub8c0\ub8c1\ub8c2\ub8c3\ub8c4\ub8c5\ub8c6\ub8c7\ub8c8\ub8c9\ub8ca\ub8cb\ub8cc\ub8cd\ub8ce\ub8cf\ub8d0\ub8d1\ub8d2\ub8d3\ub8d4\ub8d5\ub8d6\ub8d7\ub8d8\ub8d9\ub8da\ub8db\ub8dc\ub8dd\ub8de\ub8df\ub8e0\ub8e1\ub8e2\ub8e3\ub8e4\ub8e5\ub8e6\ub8e7\ub8e8\ub8e9\ub8ea\ub8eb\ub8ec\ub8ed\ub8ee\ub8ef\ub8f0\ub8f1\ub8f2\ub8f3\ub8f4\ub8f5\ub8f6\ub8f7\ub8f8\ub8f9\ub8fa\ub8fb\ub8fc\ub8fd\ub8fe\ub8ff\ub900\ub901\ub902\ub903\ub904\ub905\ub906\ub907\ub908\ub909\ub90a\ub90b\ub90c\ub90d\ub90e\ub90f\ub910\ub911\ub912\ub913\ub914\ub915\ub916\ub917\ub918\ub919\ub91a\ub91b\ub91c\ub91d\ub91e\ub91f\ub920\ub921\ub922\ub923\ub924\ub925\ub926\ub927\ub928\ub929\ub92a\ub92b\ub92c\ub92d\ub92e\ub92f\ub930\ub931\ub932\ub933\ub934\ub935\ub936\ub937\ub938\ub939\ub93a\ub93b\ub93c\ub93d\ub93e\ub93f\ub940\ub941\ub942\ub943\ub944\ub945\ub946\ub947\ub948\ub949\ub94a\ub94b\ub94c\ub94d\ub94e\ub94f\ub950\ub951\ub952\ub953\ub954\ub955\ub956\ub957\ub958\ub959\ub95a\ub95b\ub95c\ub95d\ub95e\ub95f\ub960\ub961\ub962\ub963\ub964\ub965\ub966\ub967\ub968\ub969\ub96a\ub96b\ub96c\ub96d\ub96e\ub96f\ub970\ub971\ub972\ub973\ub974\ub975\ub976\ub977\ub978\ub979\ub97a\ub97b\ub97c\ub97d\ub97e\ub97f\ub980\ub981\ub982\ub983\ub984\ub985\ub986\ub987\ub988\ub989\ub98a\ub98b\ub98c\ub98d\ub98e\ub98f\ub990\ub991\ub992\ub993\ub994\ub995\ub996\ub997\ub998\ub999\ub99a\ub99b\ub99c\ub99d\ub99e\ub99f\ub9a0\ub9a1\ub9a2\ub9a3\ub9a4\ub9a5\ub9a6\ub9a7\ub9a8\ub9a9\ub9aa\ub9ab\ub9ac\ub9ad\ub9ae\ub9af\ub9b0\ub9b1\ub9b2\ub9b3\ub9b4\ub9b5\ub9b6\ub9b7\ub9b8\ub9b9\ub9ba\ub9bb\ub9bc\ub9bd\ub9be\ub9bf\ub9c0\ub9c1\ub9c2\ub9c3\ub9c4\ub9c5\ub9c6\ub9c7\ub9c8\ub9c9\ub9ca\ub9cb\ub9cc\ub9cd\ub9ce\ub9cf\ub9d0\ub9d1\ub9d2\ub9d3\ub9d4\ub9d5\ub9d6\ub9d7\ub9d8\ub9d9\ub9da\ub9db\ub9dc\ub9dd\ub9de\ub9df\ub9e0\ub9e1\ub9e2\ub9e3\ub9e4\ub9e5\ub9e6\ub9e7\ub9e8\ub9e9\ub9ea\ub9eb\ub9ec\ub9ed\ub9ee\ub9ef\ub9f0\ub9f1\ub9f2\ub9f3\ub9f4\ub9f5\ub9f6\ub9f7\ub9f8\ub9f9\ub9fa\ub9fb\ub9fc\ub9fd\ub9fe\ub9ff\uba00\uba01\uba02\uba03\uba04\uba05\uba06\uba07\uba08\uba09\uba0a\uba0b\uba0c\uba0d\uba0e\uba0f\uba10\uba11\uba12\uba13\uba14\uba15\uba16\uba17\uba18\uba19\uba1a\uba1b\uba1c\uba1d\uba1e\uba1f\uba20\uba21\uba22\uba23\uba24\uba25\uba26\uba27\uba28\uba29\uba2a\uba2b\uba2c\uba2d\uba2e\uba2f\uba30\uba31\uba32\uba33\uba34\uba35\uba36\uba37\uba38\uba39\uba3a\uba3b\uba3c\uba3d\uba3e\uba3f\uba40\uba41\uba42\uba43\uba44\uba45\uba46\uba47\uba48\uba49\uba4a\uba4b\uba4c\uba4d\uba4e\uba4f\uba50\uba51\uba52\uba53\uba54\uba55\uba56\uba57\uba58\uba59\uba5a\uba5b\uba5c\uba5d\uba5e\uba5f\uba60\uba61\uba62\uba63\uba64\uba65\uba66\uba67\uba68\uba69\uba6a\uba6b\uba6c\uba6d\uba6e\uba6f\uba70\uba71\uba72\uba73\uba74\uba75\uba76\uba77\uba78\uba79\uba7a\uba7b\uba7c\uba7d\uba7e\uba7f\uba80\uba81\uba82\uba83\uba84\uba85\uba86\uba87\uba88\uba89\uba8a\uba8b\uba8c\uba8d\uba8e\uba8f\uba90\uba91\uba92\uba93\uba94\uba95\uba96\uba97\uba98\uba99\uba9a\uba9b\uba9c\uba9d\uba9e\uba9f\ubaa0\ubaa1\ubaa2\ubaa3\ubaa4\ubaa5\ubaa6\ubaa7\ubaa8\ubaa9\ubaaa\ubaab\ubaac\ubaad\ubaae\ubaaf\ubab0\ubab1\ubab2\ubab3\ubab4\ubab5\ubab6\ubab7\ubab8\ubab9\ubaba\ubabb\ubabc\ubabd\ubabe\ubabf\ubac0\ubac1\ubac2\ubac3\ubac4\ubac5\ubac6\ubac7\ubac8\ubac9\ubaca\ubacb\ubacc\ubacd\ubace\ubacf\ubad0\ubad1\ubad2\ubad3\ubad4\ubad5\ubad6\ubad7\ubad8\ubad9\ubada\ubadb\ubadc\ubadd\ubade\ubadf\ubae0\ubae1\ubae2\ubae3\ubae4\ubae5\ubae6\ubae7\ubae8\ubae9\ubaea\ubaeb\ubaec\ubaed\ubaee\ubaef\ubaf0\ubaf1\ubaf2\ubaf3\ubaf4\ubaf5\ubaf6\ubaf7\ubaf8\ubaf9\ubafa\ubafb\ubafc\ubafd\ubafe\ubaff\ubb00\ubb01\ubb02\ubb03\ubb04\ubb05\ubb06\ubb07\ubb08\ubb09\ubb0a\ubb0b\ubb0c\ubb0d\ubb0e\ubb0f\ubb10\ubb11\ubb12\ubb13\ubb14\ubb15\ubb16\ubb17\ubb18\ubb19\ubb1a\ubb1b\ubb1c\ubb1d\ubb1e\ubb1f\ubb20\ubb21\ubb22\ubb23\ubb24\ubb25\ubb26\ubb27\ubb28\ubb29\ubb2a\ubb2b\ubb2c\ubb2d\ubb2e\ubb2f\ubb30\ubb31\ubb32\ubb33\ubb34\ubb35\ubb36\ubb37\ubb38\ubb39\ubb3a\ubb3b\ubb3c\ubb3d\ubb3e\ubb3f\ubb40\ubb41\ubb42\ubb43\ubb44\ubb45\ubb46\ubb47\ubb48\ubb49\ubb4a\ubb4b\ubb4c\ubb4d\ubb4e\ubb4f\ubb50\ubb51\ubb52\ubb53\ubb54\ubb55\ubb56\ubb57\ubb58\ubb59\ubb5a\ubb5b\ubb5c\ubb5d\ubb5e\ubb5f\ubb60\ubb61\ubb62\ubb63\ubb64\ubb65\ubb66\ubb67\ubb68\ubb69\ubb6a\ubb6b\ubb6c\ubb6d\ubb6e\ubb6f\ubb70\ubb71\ubb72\ubb73\ubb74\ubb75\ubb76\ubb77\ubb78\ubb79\ubb7a\ubb7b\ubb7c\ubb7d\ubb7e\ubb7f\ubb80\ubb81\ubb82\ubb83\ubb84\ubb85\ubb86\ubb87\ubb88\ubb89\ubb8a\ubb8b\ubb8c\ubb8d\ubb8e\ubb8f\ubb90\ubb91\ubb92\ubb93\ubb94\ubb95\ubb96\ubb97\ubb98\ubb99\ubb9a\ubb9b\ubb9c\ubb9d\ubb9e\ubb9f\ubba0\ubba1\ubba2\ubba3\ubba4\ubba5\ubba6\ubba7\ubba8\ubba9\ubbaa\ubbab\ubbac\ubbad\ubbae\ubbaf\ubbb0\ubbb1\ubbb2\ubbb3\ubbb4\ubbb5\ubbb6\ubbb7\ubbb8\ubbb9\ubbba\ubbbb\ubbbc\ubbbd\ubbbe\ubbbf\ubbc0\ubbc1\ubbc2\ubbc3\ubbc4\ubbc5\ubbc6\ubbc7\ubbc8\ubbc9\ubbca\ubbcb\ubbcc\ubbcd\ubbce\ubbcf\ubbd0\ubbd1\ubbd2\ubbd3\ubbd4\ubbd5\ubbd6\ubbd7\ubbd8\ubbd9\ubbda\ubbdb\ubbdc\ubbdd\ubbde\ubbdf\ubbe0\ubbe1\ubbe2\ubbe3\ubbe4\ubbe5\ubbe6\ubbe7\ubbe8\ubbe9\ubbea\ubbeb\ubbec\ubbed\ubbee\ubbef\ubbf0\ubbf1\ubbf2\ubbf3\ubbf4\ubbf5\ubbf6\ubbf7\ubbf8\ubbf9\ubbfa\ubbfb\ubbfc\ubbfd\ubbfe\ubbff\ubc00\ubc01\ubc02\ubc03\ubc04\ubc05\ubc06\ubc07\ubc08\ubc09\ubc0a\ubc0b\ubc0c\ubc0d\ubc0e\ubc0f\ubc10\ubc11\ubc12\ubc13\ubc14\ubc15\ubc16\ubc17\ubc18\ubc19\ubc1a\ubc1b\ubc1c\ubc1d\ubc1e\ubc1f\ubc20\ubc21\ubc22\ubc23\ubc24\ubc25\ubc26\ubc27\ubc28\ubc29\ubc2a\ubc2b\ubc2c\ubc2d\ubc2e\ubc2f\ubc30\ubc31\ubc32\ubc33\ubc34\ubc35\ubc36\ubc37\ubc38\ubc39\ubc3a\ubc3b\ubc3c\ubc3d\ubc3e\ubc3f\ubc40\ubc41\ubc42\ubc43\ubc44\ubc45\ubc46\ubc47\ubc48\ubc49\ubc4a\ubc4b\ubc4c\ubc4d\ubc4e\ubc4f\ubc50\ubc51\ubc52\ubc53\ubc54\ubc55\ubc56\ubc57\ubc58\ubc59\ubc5a\ubc5b\ubc5c\ubc5d\ubc5e\ubc5f\ubc60\ubc61\ubc62\ubc63\ubc64\ubc65\ubc66\ubc67\ubc68\ubc69\ubc6a\ubc6b\ubc6c\ubc6d\ubc6e\ubc6f\ubc70\ubc71\ubc72\ubc73\ubc74\ubc75\ubc76\ubc77\ubc78\ubc79\ubc7a\ubc7b\ubc7c\ubc7d\ubc7e\ubc7f\ubc80\ubc81\ubc82\ubc83\ubc84\ubc85\ubc86\ubc87\ubc88\ubc89\ubc8a\ubc8b\ubc8c\ubc8d\ubc8e\ubc8f\ubc90\ubc91\ubc92\ubc93\ubc94\ubc95\ubc96\ubc97\ubc98\ubc99\ubc9a\ubc9b\ubc9c\ubc9d\ubc9e\ubc9f\ubca0\ubca1\ubca2\ubca3\ubca4\ubca5\ubca6\ubca7\ubca8\ubca9\ubcaa\ubcab\ubcac\ubcad\ubcae\ubcaf\ubcb0\ubcb1\ubcb2\ubcb3\ubcb4\ubcb5\ubcb6\ubcb7\ubcb8\ubcb9\ubcba\ubcbb\ubcbc\ubcbd\ubcbe\ubcbf\ubcc0\ubcc1\ubcc2\ubcc3\ubcc4\ubcc5\ubcc6\ubcc7\ubcc8\ubcc9\ubcca\ubccb\ubccc\ubccd\ubcce\ubccf\ubcd0\ubcd1\ubcd2\ubcd3\ubcd4\ubcd5\ubcd6\ubcd7\ubcd8\ubcd9\ubcda\ubcdb\ubcdc\ubcdd\ubcde\ubcdf\ubce0\ubce1\ubce2\ubce3\ubce4\ubce5\ubce6\ubce7\ubce8\ubce9\ubcea\ubceb\ubcec\ubced\ubcee\ubcef\ubcf0\ubcf1\ubcf2\ubcf3\ubcf4\ubcf5\ubcf6\ubcf7\ubcf8\ubcf9\ubcfa\ubcfb\ubcfc\ubcfd\ubcfe\ubcff\ubd00\ubd01\ubd02\ubd03\ubd04\ubd05\ubd06\ubd07\ubd08\ubd09\ubd0a\ubd0b\ubd0c\ubd0d\ubd0e\ubd0f\ubd10\ubd11\ubd12\ubd13\ubd14\ubd15\ubd16\ubd17\ubd18\ubd19\ubd1a\ubd1b\ubd1c\ubd1d\ubd1e\ubd1f\ubd20\ubd21\ubd22\ubd23\ubd24\ubd25\ubd26\ubd27\ubd28\ubd29\ubd2a\ubd2b\ubd2c\ubd2d\ubd2e\ubd2f\ubd30\ubd31\ubd32\ubd33\ubd34\ubd35\ubd36\ubd37\ubd38\ubd39\ubd3a\ubd3b\ubd3c\ubd3d\ubd3e\ubd3f\ubd40\ubd41\ubd42\ubd43\ubd44\ubd45\ubd46\ubd47\ubd48\ubd49\ubd4a\ubd4b\ubd4c\ubd4d\ubd4e\ubd4f\ubd50\ubd51\ubd52\ubd53\ubd54\ubd55\ubd56\ubd57\ubd58\ubd59\ubd5a\ubd5b\ubd5c\ubd5d\ubd5e\ubd5f\ubd60\ubd61\ubd62\ubd63\ubd64\ubd65\ubd66\ubd67\ubd68\ubd69\ubd6a\ubd6b\ubd6c\ubd6d\ubd6e\ubd6f\ubd70\ubd71\ubd72\ubd73\ubd74\ubd75\ubd76\ubd77\ubd78\ubd79\ubd7a\ubd7b\ubd7c\ubd7d\ubd7e\ubd7f\ubd80\ubd81\ubd82\ubd83\ubd84\ubd85\ubd86\ubd87\ubd88\ubd89\ubd8a\ubd8b\ubd8c\ubd8d\ubd8e\ubd8f\ubd90\ubd91\ubd92\ubd93\ubd94\ubd95\ubd96\ubd97\ubd98\ubd99\ubd9a\ubd9b\ubd9c\ubd9d\ubd9e\ubd9f\ubda0\ubda1\ubda2\ubda3\ubda4\ubda5\ubda6\ubda7\ubda8\ubda9\ubdaa\ubdab\ubdac\ubdad\ubdae\ubdaf\ubdb0\ubdb1\ubdb2\ubdb3\ubdb4\ubdb5\ubdb6\ubdb7\ubdb8\ubdb9\ubdba\ubdbb\ubdbc\ubdbd\ubdbe\ubdbf\ubdc0\ubdc1\ubdc2\ubdc3\ubdc4\ubdc5\ubdc6\ubdc7\ubdc8\ubdc9\ubdca\ubdcb\ubdcc\ubdcd\ubdce\ubdcf\ubdd0\ubdd1\ubdd2\ubdd3\ubdd4\ubdd5\ubdd6\ubdd7\ubdd8\ubdd9\ubdda\ubddb\ubddc\ubddd\ubdde\ubddf\ubde0\ubde1\ubde2\ubde3\ubde4\ubde5\ubde6\ubde7\ubde8\ubde9\ubdea\ubdeb\ubdec\ubded\ubdee\ubdef\ubdf0\ubdf1\ubdf2\ubdf3\ubdf4\ubdf5\ubdf6\ubdf7\ubdf8\ubdf9\ubdfa\ubdfb\ubdfc\ubdfd\ubdfe\ubdff\ube00\ube01\ube02\ube03\ube04\ube05\ube06\ube07\ube08\ube09\ube0a\ube0b\ube0c\ube0d\ube0e\ube0f\ube10\ube11\ube12\ube13\ube14\ube15\ube16\ube17\ube18\ube19\ube1a\ube1b\ube1c\ube1d\ube1e\ube1f\ube20\ube21\ube22\ube23\ube24\ube25\ube26\ube27\ube28\ube29\ube2a\ube2b\ube2c\ube2d\ube2e\ube2f\ube30\ube31\ube32\ube33\ube34\ube35\ube36\ube37\ube38\ube39\ube3a\ube3b\ube3c\ube3d\ube3e\ube3f\ube40\ube41\ube42\ube43\ube44\ube45\ube46\ube47\ube48\ube49\ube4a\ube4b\ube4c\ube4d\ube4e\ube4f\ube50\ube51\ube52\ube53\ube54\ube55\ube56\ube57\ube58\ube59\ube5a\ube5b\ube5c\ube5d\ube5e\ube5f\ube60\ube61\ube62\ube63\ube64\ube65\ube66\ube67\ube68\ube69\ube6a\ube6b\ube6c\ube6d\ube6e\ube6f\ube70\ube71\ube72\ube73\ube74\ube75\ube76\ube77\ube78\ube79\ube7a\ube7b\ube7c\ube7d\ube7e\ube7f\ube80\ube81\ube82\ube83\ube84\ube85\ube86\ube87\ube88\ube89\ube8a\ube8b\ube8c\ube8d\ube8e\ube8f\ube90\ube91\ube92\ube93\ube94\ube95\ube96\ube97\ube98\ube99\ube9a\ube9b\ube9c\ube9d\ube9e\ube9f\ubea0\ubea1\ubea2\ubea3\ubea4\ubea5\ubea6\ubea7\ubea8\ubea9\ubeaa\ubeab\ubeac\ubead\ubeae\ubeaf\ubeb0\ubeb1\ubeb2\ubeb3\ubeb4\ubeb5\ubeb6\ubeb7\ubeb8\ubeb9\ubeba\ubebb\ubebc\ubebd\ubebe\ubebf\ubec0\ubec1\ubec2\ubec3\ubec4\ubec5\ubec6\ubec7\ubec8\ubec9\ubeca\ubecb\ubecc\ubecd\ubece\ubecf\ubed0\ubed1\ubed2\ubed3\ubed4\ubed5\ubed6\ubed7\ubed8\ubed9\ubeda\ubedb\ubedc\ubedd\ubede\ubedf\ubee0\ubee1\ubee2\ubee3\ubee4\ubee5\ubee6\ubee7\ubee8\ubee9\ubeea\ubeeb\ubeec\ubeed\ubeee\ubeef\ubef0\ubef1\ubef2\ubef3\ubef4\ubef5\ubef6\ubef7\ubef8\ubef9\ubefa\ubefb\ubefc\ubefd\ubefe\ubeff\ubf00\ubf01\ubf02\ubf03\ubf04\ubf05\ubf06\ubf07\ubf08\ubf09\ubf0a\ubf0b\ubf0c\ubf0d\ubf0e\ubf0f\ubf10\ubf11\ubf12\ubf13\ubf14\ubf15\ubf16\ubf17\ubf18\ubf19\ubf1a\ubf1b\ubf1c\ubf1d\ubf1e\ubf1f\ubf20\ubf21\ubf22\ubf23\ubf24\ubf25\ubf26\ubf27\ubf28\ubf29\ubf2a\ubf2b\ubf2c\ubf2d\ubf2e\ubf2f\ubf30\ubf31\ubf32\ubf33\ubf34\ubf35\ubf36\ubf37\ubf38\ubf39\ubf3a\ubf3b\ubf3c\ubf3d\ubf3e\ubf3f\ubf40\ubf41\ubf42\ubf43\ubf44\ubf45\ubf46\ubf47\ubf48\ubf49\ubf4a\ubf4b\ubf4c\ubf4d\ubf4e\ubf4f\ubf50\ubf51\ubf52\ubf53\ubf54\ubf55\ubf56\ubf57\ubf58\ubf59\ubf5a\ubf5b\ubf5c\ubf5d\ubf5e\ubf5f\ubf60\ubf61\ubf62\ubf63\ubf64\ubf65\ubf66\ubf67\ubf68\ubf69\ubf6a\ubf6b\ubf6c\ubf6d\ubf6e\ubf6f\ubf70\ubf71\ubf72\ubf73\ubf74\ubf75\ubf76\ubf77\ubf78\ubf79\ubf7a\ubf7b\ubf7c\ubf7d\ubf7e\ubf7f\ubf80\ubf81\ubf82\ubf83\ubf84\ubf85\ubf86\ubf87\ubf88\ubf89\ubf8a\ubf8b\ubf8c\ubf8d\ubf8e\ubf8f\ubf90\ubf91\ubf92\ubf93\ubf94\ubf95\ubf96\ubf97\ubf98\ubf99\ubf9a\ubf9b\ubf9c\ubf9d\ubf9e\ubf9f\ubfa0\ubfa1\ubfa2\ubfa3\ubfa4\ubfa5\ubfa6\ubfa7\ubfa8\ubfa9\ubfaa\ubfab\ubfac\ubfad\ubfae\ubfaf\ubfb0\ubfb1\ubfb2\ubfb3\ubfb4\ubfb5\ubfb6\ubfb7\ubfb8\ubfb9\ubfba\ubfbb\ubfbc\ubfbd\ubfbe\ubfbf\ubfc0\ubfc1\ubfc2\ubfc3\ubfc4\ubfc5\ubfc6\ubfc7\ubfc8\ubfc9\ubfca\ubfcb\ubfcc\ubfcd\ubfce\ubfcf\ubfd0\ubfd1\ubfd2\ubfd3\ubfd4\ubfd5\ubfd6\ubfd7\ubfd8\ubfd9\ubfda\ubfdb\ubfdc\ubfdd\ubfde\ubfdf\ubfe0\ubfe1\ubfe2\ubfe3\ubfe4\ubfe5\ubfe6\ubfe7\ubfe8\ubfe9\ubfea\ubfeb\ubfec\ubfed\ubfee\ubfef\ubff0\ubff1\ubff2\ubff3\ubff4\ubff5\ubff6\ubff7\ubff8\ubff9\ubffa\ubffb\ubffc\ubffd\ubffe\ubfff\uc000\uc001\uc002\uc003\uc004\uc005\uc006\uc007\uc008\uc009\uc00a\uc00b\uc00c\uc00d\uc00e\uc00f\uc010\uc011\uc012\uc013\uc014\uc015\uc016\uc017\uc018\uc019\uc01a\uc01b\uc01c\uc01d\uc01e\uc01f\uc020\uc021\uc022\uc023\uc024\uc025\uc026\uc027\uc028\uc029\uc02a\uc02b\uc02c\uc02d\uc02e\uc02f\uc030\uc031\uc032\uc033\uc034\uc035\uc036\uc037\uc038\uc039\uc03a\uc03b\uc03c\uc03d\uc03e\uc03f\uc040\uc041\uc042\uc043\uc044\uc045\uc046\uc047\uc048\uc049\uc04a\uc04b\uc04c\uc04d\uc04e\uc04f\uc050\uc051\uc052\uc053\uc054\uc055\uc056\uc057\uc058\uc059\uc05a\uc05b\uc05c\uc05d\uc05e\uc05f\uc060\uc061\uc062\uc063\uc064\uc065\uc066\uc067\uc068\uc069\uc06a\uc06b\uc06c\uc06d\uc06e\uc06f\uc070\uc071\uc072\uc073\uc074\uc075\uc076\uc077\uc078\uc079\uc07a\uc07b\uc07c\uc07d\uc07e\uc07f\uc080\uc081\uc082\uc083\uc084\uc085\uc086\uc087\uc088\uc089\uc08a\uc08b\uc08c\uc08d\uc08e\uc08f\uc090\uc091\uc092\uc093\uc094\uc095\uc096\uc097\uc098\uc099\uc09a\uc09b\uc09c\uc09d\uc09e\uc09f\uc0a0\uc0a1\uc0a2\uc0a3\uc0a4\uc0a5\uc0a6\uc0a7\uc0a8\uc0a9\uc0aa\uc0ab\uc0ac\uc0ad\uc0ae\uc0af\uc0b0\uc0b1\uc0b2\uc0b3\uc0b4\uc0b5\uc0b6\uc0b7\uc0b8\uc0b9\uc0ba\uc0bb\uc0bc\uc0bd\uc0be\uc0bf\uc0c0\uc0c1\uc0c2\uc0c3\uc0c4\uc0c5\uc0c6\uc0c7\uc0c8\uc0c9\uc0ca\uc0cb\uc0cc\uc0cd\uc0ce\uc0cf\uc0d0\uc0d1\uc0d2\uc0d3\uc0d4\uc0d5\uc0d6\uc0d7\uc0d8\uc0d9\uc0da\uc0db\uc0dc\uc0dd\uc0de\uc0df\uc0e0\uc0e1\uc0e2\uc0e3\uc0e4\uc0e5\uc0e6\uc0e7\uc0e8\uc0e9\uc0ea\uc0eb\uc0ec\uc0ed\uc0ee\uc0ef\uc0f0\uc0f1\uc0f2\uc0f3\uc0f4\uc0f5\uc0f6\uc0f7\uc0f8\uc0f9\uc0fa\uc0fb\uc0fc\uc0fd\uc0fe\uc0ff\uc100\uc101\uc102\uc103\uc104\uc105\uc106\uc107\uc108\uc109\uc10a\uc10b\uc10c\uc10d\uc10e\uc10f\uc110\uc111\uc112\uc113\uc114\uc115\uc116\uc117\uc118\uc119\uc11a\uc11b\uc11c\uc11d\uc11e\uc11f\uc120\uc121\uc122\uc123\uc124\uc125\uc126\uc127\uc128\uc129\uc12a\uc12b\uc12c\uc12d\uc12e\uc12f\uc130\uc131\uc132\uc133\uc134\uc135\uc136\uc137\uc138\uc139\uc13a\uc13b\uc13c\uc13d\uc13e\uc13f\uc140\uc141\uc142\uc143\uc144\uc145\uc146\uc147\uc148\uc149\uc14a\uc14b\uc14c\uc14d\uc14e\uc14f\uc150\uc151\uc152\uc153\uc154\uc155\uc156\uc157\uc158\uc159\uc15a\uc15b\uc15c\uc15d\uc15e\uc15f\uc160\uc161\uc162\uc163\uc164\uc165\uc166\uc167\uc168\uc169\uc16a\uc16b\uc16c\uc16d\uc16e\uc16f\uc170\uc171\uc172\uc173\uc174\uc175\uc176\uc177\uc178\uc179\uc17a\uc17b\uc17c\uc17d\uc17e\uc17f\uc180\uc181\uc182\uc183\uc184\uc185\uc186\uc187\uc188\uc189\uc18a\uc18b\uc18c\uc18d\uc18e\uc18f\uc190\uc191\uc192\uc193\uc194\uc195\uc196\uc197\uc198\uc199\uc19a\uc19b\uc19c\uc19d\uc19e\uc19f\uc1a0\uc1a1\uc1a2\uc1a3\uc1a4\uc1a5\uc1a6\uc1a7\uc1a8\uc1a9\uc1aa\uc1ab\uc1ac\uc1ad\uc1ae\uc1af\uc1b0\uc1b1\uc1b2\uc1b3\uc1b4\uc1b5\uc1b6\uc1b7\uc1b8\uc1b9\uc1ba\uc1bb\uc1bc\uc1bd\uc1be\uc1bf\uc1c0\uc1c1\uc1c2\uc1c3\uc1c4\uc1c5\uc1c6\uc1c7\uc1c8\uc1c9\uc1ca\uc1cb\uc1cc\uc1cd\uc1ce\uc1cf\uc1d0\uc1d1\uc1d2\uc1d3\uc1d4\uc1d5\uc1d6\uc1d7\uc1d8\uc1d9\uc1da\uc1db\uc1dc\uc1dd\uc1de\uc1df\uc1e0\uc1e1\uc1e2\uc1e3\uc1e4\uc1e5\uc1e6\uc1e7\uc1e8\uc1e9\uc1ea\uc1eb\uc1ec\uc1ed\uc1ee\uc1ef\uc1f0\uc1f1\uc1f2\uc1f3\uc1f4\uc1f5\uc1f6\uc1f7\uc1f8\uc1f9\uc1fa\uc1fb\uc1fc\uc1fd\uc1fe\uc1ff\uc200\uc201\uc202\uc203\uc204\uc205\uc206\uc207\uc208\uc209\uc20a\uc20b\uc20c\uc20d\uc20e\uc20f\uc210\uc211\uc212\uc213\uc214\uc215\uc216\uc217\uc218\uc219\uc21a\uc21b\uc21c\uc21d\uc21e\uc21f\uc220\uc221\uc222\uc223\uc224\uc225\uc226\uc227\uc228\uc229\uc22a\uc22b\uc22c\uc22d\uc22e\uc22f\uc230\uc231\uc232\uc233\uc234\uc235\uc236\uc237\uc238\uc239\uc23a\uc23b\uc23c\uc23d\uc23e\uc23f\uc240\uc241\uc242\uc243\uc244\uc245\uc246\uc247\uc248\uc249\uc24a\uc24b\uc24c\uc24d\uc24e\uc24f\uc250\uc251\uc252\uc253\uc254\uc255\uc256\uc257\uc258\uc259\uc25a\uc25b\uc25c\uc25d\uc25e\uc25f\uc260\uc261\uc262\uc263\uc264\uc265\uc266\uc267\uc268\uc269\uc26a\uc26b\uc26c\uc26d\uc26e\uc26f\uc270\uc271\uc272\uc273\uc274\uc275\uc276\uc277\uc278\uc279\uc27a\uc27b\uc27c\uc27d\uc27e\uc27f\uc280\uc281\uc282\uc283\uc284\uc285\uc286\uc287\uc288\uc289\uc28a\uc28b\uc28c\uc28d\uc28e\uc28f\uc290\uc291\uc292\uc293\uc294\uc295\uc296\uc297\uc298\uc299\uc29a\uc29b\uc29c\uc29d\uc29e\uc29f\uc2a0\uc2a1\uc2a2\uc2a3\uc2a4\uc2a5\uc2a6\uc2a7\uc2a8\uc2a9\uc2aa\uc2ab\uc2ac\uc2ad\uc2ae\uc2af\uc2b0\uc2b1\uc2b2\uc2b3\uc2b4\uc2b5\uc2b6\uc2b7\uc2b8\uc2b9\uc2ba\uc2bb\uc2bc\uc2bd\uc2be\uc2bf\uc2c0\uc2c1\uc2c2\uc2c3\uc2c4\uc2c5\uc2c6\uc2c7\uc2c8\uc2c9\uc2ca\uc2cb\uc2cc\uc2cd\uc2ce\uc2cf\uc2d0\uc2d1\uc2d2\uc2d3\uc2d4\uc2d5\uc2d6\uc2d7\uc2d8\uc2d9\uc2da\uc2db\uc2dc\uc2dd\uc2de\uc2df\uc2e0\uc2e1\uc2e2\uc2e3\uc2e4\uc2e5\uc2e6\uc2e7\uc2e8\uc2e9\uc2ea\uc2eb\uc2ec\uc2ed\uc2ee\uc2ef\uc2f0\uc2f1\uc2f2\uc2f3\uc2f4\uc2f5\uc2f6\uc2f7\uc2f8\uc2f9\uc2fa\uc2fb\uc2fc\uc2fd\uc2fe\uc2ff\uc300\uc301\uc302\uc303\uc304\uc305\uc306\uc307\uc308\uc309\uc30a\uc30b\uc30c\uc30d\uc30e\uc30f\uc310\uc311\uc312\uc313\uc314\uc315\uc316\uc317\uc318\uc319\uc31a\uc31b\uc31c\uc31d\uc31e\uc31f\uc320\uc321\uc322\uc323\uc324\uc325\uc326\uc327\uc328\uc329\uc32a\uc32b\uc32c\uc32d\uc32e\uc32f\uc330\uc331\uc332\uc333\uc334\uc335\uc336\uc337\uc338\uc339\uc33a\uc33b\uc33c\uc33d\uc33e\uc33f\uc340\uc341\uc342\uc343\uc344\uc345\uc346\uc347\uc348\uc349\uc34a\uc34b\uc34c\uc34d\uc34e\uc34f\uc350\uc351\uc352\uc353\uc354\uc355\uc356\uc357\uc358\uc359\uc35a\uc35b\uc35c\uc35d\uc35e\uc35f\uc360\uc361\uc362\uc363\uc364\uc365\uc366\uc367\uc368\uc369\uc36a\uc36b\uc36c\uc36d\uc36e\uc36f\uc370\uc371\uc372\uc373\uc374\uc375\uc376\uc377\uc378\uc379\uc37a\uc37b\uc37c\uc37d\uc37e\uc37f\uc380\uc381\uc382\uc383\uc384\uc385\uc386\uc387\uc388\uc389\uc38a\uc38b\uc38c\uc38d\uc38e\uc38f\uc390\uc391\uc392\uc393\uc394\uc395\uc396\uc397\uc398\uc399\uc39a\uc39b\uc39c\uc39d\uc39e\uc39f\uc3a0\uc3a1\uc3a2\uc3a3\uc3a4\uc3a5\uc3a6\uc3a7\uc3a8\uc3a9\uc3aa\uc3ab\uc3ac\uc3ad\uc3ae\uc3af\uc3b0\uc3b1\uc3b2\uc3b3\uc3b4\uc3b5\uc3b6\uc3b7\uc3b8\uc3b9\uc3ba\uc3bb\uc3bc\uc3bd\uc3be\uc3bf\uc3c0\uc3c1\uc3c2\uc3c3\uc3c4\uc3c5\uc3c6\uc3c7\uc3c8\uc3c9\uc3ca\uc3cb\uc3cc\uc3cd\uc3ce\uc3cf\uc3d0\uc3d1\uc3d2\uc3d3\uc3d4\uc3d5\uc3d6\uc3d7\uc3d8\uc3d9\uc3da\uc3db\uc3dc\uc3dd\uc3de\uc3df\uc3e0\uc3e1\uc3e2\uc3e3\uc3e4\uc3e5\uc3e6\uc3e7\uc3e8\uc3e9\uc3ea\uc3eb\uc3ec\uc3ed\uc3ee\uc3ef\uc3f0\uc3f1\uc3f2\uc3f3\uc3f4\uc3f5\uc3f6\uc3f7\uc3f8\uc3f9\uc3fa\uc3fb\uc3fc\uc3fd\uc3fe\uc3ff\uc400\uc401\uc402\uc403\uc404\uc405\uc406\uc407\uc408\uc409\uc40a\uc40b\uc40c\uc40d\uc40e\uc40f\uc410\uc411\uc412\uc413\uc414\uc415\uc416\uc417\uc418\uc419\uc41a\uc41b\uc41c\uc41d\uc41e\uc41f\uc420\uc421\uc422\uc423\uc424\uc425\uc426\uc427\uc428\uc429\uc42a\uc42b\uc42c\uc42d\uc42e\uc42f\uc430\uc431\uc432\uc433\uc434\uc435\uc436\uc437\uc438\uc439\uc43a\uc43b\uc43c\uc43d\uc43e\uc43f\uc440\uc441\uc442\uc443\uc444\uc445\uc446\uc447\uc448\uc449\uc44a\uc44b\uc44c\uc44d\uc44e\uc44f\uc450\uc451\uc452\uc453\uc454\uc455\uc456\uc457\uc458\uc459\uc45a\uc45b\uc45c\uc45d\uc45e\uc45f\uc460\uc461\uc462\uc463\uc464\uc465\uc466\uc467\uc468\uc469\uc46a\uc46b\uc46c\uc46d\uc46e\uc46f\uc470\uc471\uc472\uc473\uc474\uc475\uc476\uc477\uc478\uc479\uc47a\uc47b\uc47c\uc47d\uc47e\uc47f\uc480\uc481\uc482\uc483\uc484\uc485\uc486\uc487\uc488\uc489\uc48a\uc48b\uc48c\uc48d\uc48e\uc48f\uc490\uc491\uc492\uc493\uc494\uc495\uc496\uc497\uc498\uc499\uc49a\uc49b\uc49c\uc49d\uc49e\uc49f\uc4a0\uc4a1\uc4a2\uc4a3\uc4a4\uc4a5\uc4a6\uc4a7\uc4a8\uc4a9\uc4aa\uc4ab\uc4ac\uc4ad\uc4ae\uc4af\uc4b0\uc4b1\uc4b2\uc4b3\uc4b4\uc4b5\uc4b6\uc4b7\uc4b8\uc4b9\uc4ba\uc4bb\uc4bc\uc4bd\uc4be\uc4bf\uc4c0\uc4c1\uc4c2\uc4c3\uc4c4\uc4c5\uc4c6\uc4c7\uc4c8\uc4c9\uc4ca\uc4cb\uc4cc\uc4cd\uc4ce\uc4cf\uc4d0\uc4d1\uc4d2\uc4d3\uc4d4\uc4d5\uc4d6\uc4d7\uc4d8\uc4d9\uc4da\uc4db\uc4dc\uc4dd\uc4de\uc4df\uc4e0\uc4e1\uc4e2\uc4e3\uc4e4\uc4e5\uc4e6\uc4e7\uc4e8\uc4e9\uc4ea\uc4eb\uc4ec\uc4ed\uc4ee\uc4ef\uc4f0\uc4f1\uc4f2\uc4f3\uc4f4\uc4f5\uc4f6\uc4f7\uc4f8\uc4f9\uc4fa\uc4fb\uc4fc\uc4fd\uc4fe\uc4ff\uc500\uc501\uc502\uc503\uc504\uc505\uc506\uc507\uc508\uc509\uc50a\uc50b\uc50c\uc50d\uc50e\uc50f\uc510\uc511\uc512\uc513\uc514\uc515\uc516\uc517\uc518\uc519\uc51a\uc51b\uc51c\uc51d\uc51e\uc51f\uc520\uc521\uc522\uc523\uc524\uc525\uc526\uc527\uc528\uc529\uc52a\uc52b\uc52c\uc52d\uc52e\uc52f\uc530\uc531\uc532\uc533\uc534\uc535\uc536\uc537\uc538\uc539\uc53a\uc53b\uc53c\uc53d\uc53e\uc53f\uc540\uc541\uc542\uc543\uc544\uc545\uc546\uc547\uc548\uc549\uc54a\uc54b\uc54c\uc54d\uc54e\uc54f\uc550\uc551\uc552\uc553\uc554\uc555\uc556\uc557\uc558\uc559\uc55a\uc55b\uc55c\uc55d\uc55e\uc55f\uc560\uc561\uc562\uc563\uc564\uc565\uc566\uc567\uc568\uc569\uc56a\uc56b\uc56c\uc56d\uc56e\uc56f\uc570\uc571\uc572\uc573\uc574\uc575\uc576\uc577\uc578\uc579\uc57a\uc57b\uc57c\uc57d\uc57e\uc57f\uc580\uc581\uc582\uc583\uc584\uc585\uc586\uc587\uc588\uc589\uc58a\uc58b\uc58c\uc58d\uc58e\uc58f\uc590\uc591\uc592\uc593\uc594\uc595\uc596\uc597\uc598\uc599\uc59a\uc59b\uc59c\uc59d\uc59e\uc59f\uc5a0\uc5a1\uc5a2\uc5a3\uc5a4\uc5a5\uc5a6\uc5a7\uc5a8\uc5a9\uc5aa\uc5ab\uc5ac\uc5ad\uc5ae\uc5af\uc5b0\uc5b1\uc5b2\uc5b3\uc5b4\uc5b5\uc5b6\uc5b7\uc5b8\uc5b9\uc5ba\uc5bb\uc5bc\uc5bd\uc5be\uc5bf\uc5c0\uc5c1\uc5c2\uc5c3\uc5c4\uc5c5\uc5c6\uc5c7\uc5c8\uc5c9\uc5ca\uc5cb\uc5cc\uc5cd\uc5ce\uc5cf\uc5d0\uc5d1\uc5d2\uc5d3\uc5d4\uc5d5\uc5d6\uc5d7\uc5d8\uc5d9\uc5da\uc5db\uc5dc\uc5dd\uc5de\uc5df\uc5e0\uc5e1\uc5e2\uc5e3\uc5e4\uc5e5\uc5e6\uc5e7\uc5e8\uc5e9\uc5ea\uc5eb\uc5ec\uc5ed\uc5ee\uc5ef\uc5f0\uc5f1\uc5f2\uc5f3\uc5f4\uc5f5\uc5f6\uc5f7\uc5f8\uc5f9\uc5fa\uc5fb\uc5fc\uc5fd\uc5fe\uc5ff\uc600\uc601\uc602\uc603\uc604\uc605\uc606\uc607\uc608\uc609\uc60a\uc60b\uc60c\uc60d\uc60e\uc60f\uc610\uc611\uc612\uc613\uc614\uc615\uc616\uc617\uc618\uc619\uc61a\uc61b\uc61c\uc61d\uc61e\uc61f\uc620\uc621\uc622\uc623\uc624\uc625\uc626\uc627\uc628\uc629\uc62a\uc62b\uc62c\uc62d\uc62e\uc62f\uc630\uc631\uc632\uc633\uc634\uc635\uc636\uc637\uc638\uc639\uc63a\uc63b\uc63c\uc63d\uc63e\uc63f\uc640\uc641\uc642\uc643\uc644\uc645\uc646\uc647\uc648\uc649\uc64a\uc64b\uc64c\uc64d\uc64e\uc64f\uc650\uc651\uc652\uc653\uc654\uc655\uc656\uc657\uc658\uc659\uc65a\uc65b\uc65c\uc65d\uc65e\uc65f\uc660\uc661\uc662\uc663\uc664\uc665\uc666\uc667\uc668\uc669\uc66a\uc66b\uc66c\uc66d\uc66e\uc66f\uc670\uc671\uc672\uc673\uc674\uc675\uc676\uc677\uc678\uc679\uc67a\uc67b\uc67c\uc67d\uc67e\uc67f\uc680\uc681\uc682\uc683\uc684\uc685\uc686\uc687\uc688\uc689\uc68a\uc68b\uc68c\uc68d\uc68e\uc68f\uc690\uc691\uc692\uc693\uc694\uc695\uc696\uc697\uc698\uc699\uc69a\uc69b\uc69c\uc69d\uc69e\uc69f\uc6a0\uc6a1\uc6a2\uc6a3\uc6a4\uc6a5\uc6a6\uc6a7\uc6a8\uc6a9\uc6aa\uc6ab\uc6ac\uc6ad\uc6ae\uc6af\uc6b0\uc6b1\uc6b2\uc6b3\uc6b4\uc6b5\uc6b6\uc6b7\uc6b8\uc6b9\uc6ba\uc6bb\uc6bc\uc6bd\uc6be\uc6bf\uc6c0\uc6c1\uc6c2\uc6c3\uc6c4\uc6c5\uc6c6\uc6c7\uc6c8\uc6c9\uc6ca\uc6cb\uc6cc\uc6cd\uc6ce\uc6cf\uc6d0\uc6d1\uc6d2\uc6d3\uc6d4\uc6d5\uc6d6\uc6d7\uc6d8\uc6d9\uc6da\uc6db\uc6dc\uc6dd\uc6de\uc6df\uc6e0\uc6e1\uc6e2\uc6e3\uc6e4\uc6e5\uc6e6\uc6e7\uc6e8\uc6e9\uc6ea\uc6eb\uc6ec\uc6ed\uc6ee\uc6ef\uc6f0\uc6f1\uc6f2\uc6f3\uc6f4\uc6f5\uc6f6\uc6f7\uc6f8\uc6f9\uc6fa\uc6fb\uc6fc\uc6fd\uc6fe\uc6ff\uc700\uc701\uc702\uc703\uc704\uc705\uc706\uc707\uc708\uc709\uc70a\uc70b\uc70c\uc70d\uc70e\uc70f\uc710\uc711\uc712\uc713\uc714\uc715\uc716\uc717\uc718\uc719\uc71a\uc71b\uc71c\uc71d\uc71e\uc71f\uc720\uc721\uc722\uc723\uc724\uc725\uc726\uc727\uc728\uc729\uc72a\uc72b\uc72c\uc72d\uc72e\uc72f\uc730\uc731\uc732\uc733\uc734\uc735\uc736\uc737\uc738\uc739\uc73a\uc73b\uc73c\uc73d\uc73e\uc73f\uc740\uc741\uc742\uc743\uc744\uc745\uc746\uc747\uc748\uc749\uc74a\uc74b\uc74c\uc74d\uc74e\uc74f\uc750\uc751\uc752\uc753\uc754\uc755\uc756\uc757\uc758\uc759\uc75a\uc75b\uc75c\uc75d\uc75e\uc75f\uc760\uc761\uc762\uc763\uc764\uc765\uc766\uc767\uc768\uc769\uc76a\uc76b\uc76c\uc76d\uc76e\uc76f\uc770\uc771\uc772\uc773\uc774\uc775\uc776\uc777\uc778\uc779\uc77a\uc77b\uc77c\uc77d\uc77e\uc77f\uc780\uc781\uc782\uc783\uc784\uc785\uc786\uc787\uc788\uc789\uc78a\uc78b\uc78c\uc78d\uc78e\uc78f\uc790\uc791\uc792\uc793\uc794\uc795\uc796\uc797\uc798\uc799\uc79a\uc79b\uc79c\uc79d\uc79e\uc79f\uc7a0\uc7a1\uc7a2\uc7a3\uc7a4\uc7a5\uc7a6\uc7a7\uc7a8\uc7a9\uc7aa\uc7ab\uc7ac\uc7ad\uc7ae\uc7af\uc7b0\uc7b1\uc7b2\uc7b3\uc7b4\uc7b5\uc7b6\uc7b7\uc7b8\uc7b9\uc7ba\uc7bb\uc7bc\uc7bd\uc7be\uc7bf\uc7c0\uc7c1\uc7c2\uc7c3\uc7c4\uc7c5\uc7c6\uc7c7\uc7c8\uc7c9\uc7ca\uc7cb\uc7cc\uc7cd\uc7ce\uc7cf\uc7d0\uc7d1\uc7d2\uc7d3\uc7d4\uc7d5\uc7d6\uc7d7\uc7d8\uc7d9\uc7da\uc7db\uc7dc\uc7dd\uc7de\uc7df\uc7e0\uc7e1\uc7e2\uc7e3\uc7e4\uc7e5\uc7e6\uc7e7\uc7e8\uc7e9\uc7ea\uc7eb\uc7ec\uc7ed\uc7ee\uc7ef\uc7f0\uc7f1\uc7f2\uc7f3\uc7f4\uc7f5\uc7f6\uc7f7\uc7f8\uc7f9\uc7fa\uc7fb\uc7fc\uc7fd\uc7fe\uc7ff\uc800\uc801\uc802\uc803\uc804\uc805\uc806\uc807\uc808\uc809\uc80a\uc80b\uc80c\uc80d\uc80e\uc80f\uc810\uc811\uc812\uc813\uc814\uc815\uc816\uc817\uc818\uc819\uc81a\uc81b\uc81c\uc81d\uc81e\uc81f\uc820\uc821\uc822\uc823\uc824\uc825\uc826\uc827\uc828\uc829\uc82a\uc82b\uc82c\uc82d\uc82e\uc82f\uc830\uc831\uc832\uc833\uc834\uc835\uc836\uc837\uc838\uc839\uc83a\uc83b\uc83c\uc83d\uc83e\uc83f\uc840\uc841\uc842\uc843\uc844\uc845\uc846\uc847\uc848\uc849\uc84a\uc84b\uc84c\uc84d\uc84e\uc84f\uc850\uc851\uc852\uc853\uc854\uc855\uc856\uc857\uc858\uc859\uc85a\uc85b\uc85c\uc85d\uc85e\uc85f\uc860\uc861\uc862\uc863\uc864\uc865\uc866\uc867\uc868\uc869\uc86a\uc86b\uc86c\uc86d\uc86e\uc86f\uc870\uc871\uc872\uc873\uc874\uc875\uc876\uc877\uc878\uc879\uc87a\uc87b\uc87c\uc87d\uc87e\uc87f\uc880\uc881\uc882\uc883\uc884\uc885\uc886\uc887\uc888\uc889\uc88a\uc88b\uc88c\uc88d\uc88e\uc88f\uc890\uc891\uc892\uc893\uc894\uc895\uc896\uc897\uc898\uc899\uc89a\uc89b\uc89c\uc89d\uc89e\uc89f\uc8a0\uc8a1\uc8a2\uc8a3\uc8a4\uc8a5\uc8a6\uc8a7\uc8a8\uc8a9\uc8aa\uc8ab\uc8ac\uc8ad\uc8ae\uc8af\uc8b0\uc8b1\uc8b2\uc8b3\uc8b4\uc8b5\uc8b6\uc8b7\uc8b8\uc8b9\uc8ba\uc8bb\uc8bc\uc8bd\uc8be\uc8bf\uc8c0\uc8c1\uc8c2\uc8c3\uc8c4\uc8c5\uc8c6\uc8c7\uc8c8\uc8c9\uc8ca\uc8cb\uc8cc\uc8cd\uc8ce\uc8cf\uc8d0\uc8d1\uc8d2\uc8d3\uc8d4\uc8d5\uc8d6\uc8d7\uc8d8\uc8d9\uc8da\uc8db\uc8dc\uc8dd\uc8de\uc8df\uc8e0\uc8e1\uc8e2\uc8e3\uc8e4\uc8e5\uc8e6\uc8e7\uc8e8\uc8e9\uc8ea\uc8eb\uc8ec\uc8ed\uc8ee\uc8ef\uc8f0\uc8f1\uc8f2\uc8f3\uc8f4\uc8f5\uc8f6\uc8f7\uc8f8\uc8f9\uc8fa\uc8fb\uc8fc\uc8fd\uc8fe\uc8ff\uc900\uc901\uc902\uc903\uc904\uc905\uc906\uc907\uc908\uc909\uc90a\uc90b\uc90c\uc90d\uc90e\uc90f\uc910\uc911\uc912\uc913\uc914\uc915\uc916\uc917\uc918\uc919\uc91a\uc91b\uc91c\uc91d\uc91e\uc91f\uc920\uc921\uc922\uc923\uc924\uc925\uc926\uc927\uc928\uc929\uc92a\uc92b\uc92c\uc92d\uc92e\uc92f\uc930\uc931\uc932\uc933\uc934\uc935\uc936\uc937\uc938\uc939\uc93a\uc93b\uc93c\uc93d\uc93e\uc93f\uc940\uc941\uc942\uc943\uc944\uc945\uc946\uc947\uc948\uc949\uc94a\uc94b\uc94c\uc94d\uc94e\uc94f\uc950\uc951\uc952\uc953\uc954\uc955\uc956\uc957\uc958\uc959\uc95a\uc95b\uc95c\uc95d\uc95e\uc95f\uc960\uc961\uc962\uc963\uc964\uc965\uc966\uc967\uc968\uc969\uc96a\uc96b\uc96c\uc96d\uc96e\uc96f\uc970\uc971\uc972\uc973\uc974\uc975\uc976\uc977\uc978\uc979\uc97a\uc97b\uc97c\uc97d\uc97e\uc97f\uc980\uc981\uc982\uc983\uc984\uc985\uc986\uc987\uc988\uc989\uc98a\uc98b\uc98c\uc98d\uc98e\uc98f\uc990\uc991\uc992\uc993\uc994\uc995\uc996\uc997\uc998\uc999\uc99a\uc99b\uc99c\uc99d\uc99e\uc99f\uc9a0\uc9a1\uc9a2\uc9a3\uc9a4\uc9a5\uc9a6\uc9a7\uc9a8\uc9a9\uc9aa\uc9ab\uc9ac\uc9ad\uc9ae\uc9af\uc9b0\uc9b1\uc9b2\uc9b3\uc9b4\uc9b5\uc9b6\uc9b7\uc9b8\uc9b9\uc9ba\uc9bb\uc9bc\uc9bd\uc9be\uc9bf\uc9c0\uc9c1\uc9c2\uc9c3\uc9c4\uc9c5\uc9c6\uc9c7\uc9c8\uc9c9\uc9ca\uc9cb\uc9cc\uc9cd\uc9ce\uc9cf\uc9d0\uc9d1\uc9d2\uc9d3\uc9d4\uc9d5\uc9d6\uc9d7\uc9d8\uc9d9\uc9da\uc9db\uc9dc\uc9dd\uc9de\uc9df\uc9e0\uc9e1\uc9e2\uc9e3\uc9e4\uc9e5\uc9e6\uc9e7\uc9e8\uc9e9\uc9ea\uc9eb\uc9ec\uc9ed\uc9ee\uc9ef\uc9f0\uc9f1\uc9f2\uc9f3\uc9f4\uc9f5\uc9f6\uc9f7\uc9f8\uc9f9\uc9fa\uc9fb\uc9fc\uc9fd\uc9fe\uc9ff\uca00\uca01\uca02\uca03\uca04\uca05\uca06\uca07\uca08\uca09\uca0a\uca0b\uca0c\uca0d\uca0e\uca0f\uca10\uca11\uca12\uca13\uca14\uca15\uca16\uca17\uca18\uca19\uca1a\uca1b\uca1c\uca1d\uca1e\uca1f\uca20\uca21\uca22\uca23\uca24\uca25\uca26\uca27\uca28\uca29\uca2a\uca2b\uca2c\uca2d\uca2e\uca2f\uca30\uca31\uca32\uca33\uca34\uca35\uca36\uca37\uca38\uca39\uca3a\uca3b\uca3c\uca3d\uca3e\uca3f\uca40\uca41\uca42\uca43\uca44\uca45\uca46\uca47\uca48\uca49\uca4a\uca4b\uca4c\uca4d\uca4e\uca4f\uca50\uca51\uca52\uca53\uca54\uca55\uca56\uca57\uca58\uca59\uca5a\uca5b\uca5c\uca5d\uca5e\uca5f\uca60\uca61\uca62\uca63\uca64\uca65\uca66\uca67\uca68\uca69\uca6a\uca6b\uca6c\uca6d\uca6e\uca6f\uca70\uca71\uca72\uca73\uca74\uca75\uca76\uca77\uca78\uca79\uca7a\uca7b\uca7c\uca7d\uca7e\uca7f\uca80\uca81\uca82\uca83\uca84\uca85\uca86\uca87\uca88\uca89\uca8a\uca8b\uca8c\uca8d\uca8e\uca8f\uca90\uca91\uca92\uca93\uca94\uca95\uca96\uca97\uca98\uca99\uca9a\uca9b\uca9c\uca9d\uca9e\uca9f\ucaa0\ucaa1\ucaa2\ucaa3\ucaa4\ucaa5\ucaa6\ucaa7\ucaa8\ucaa9\ucaaa\ucaab\ucaac\ucaad\ucaae\ucaaf\ucab0\ucab1\ucab2\ucab3\ucab4\ucab5\ucab6\ucab7\ucab8\ucab9\ucaba\ucabb\ucabc\ucabd\ucabe\ucabf\ucac0\ucac1\ucac2\ucac3\ucac4\ucac5\ucac6\ucac7\ucac8\ucac9\ucaca\ucacb\ucacc\ucacd\ucace\ucacf\ucad0\ucad1\ucad2\ucad3\ucad4\ucad5\ucad6\ucad7\ucad8\ucad9\ucada\ucadb\ucadc\ucadd\ucade\ucadf\ucae0\ucae1\ucae2\ucae3\ucae4\ucae5\ucae6\ucae7\ucae8\ucae9\ucaea\ucaeb\ucaec\ucaed\ucaee\ucaef\ucaf0\ucaf1\ucaf2\ucaf3\ucaf4\ucaf5\ucaf6\ucaf7\ucaf8\ucaf9\ucafa\ucafb\ucafc\ucafd\ucafe\ucaff\ucb00\ucb01\ucb02\ucb03\ucb04\ucb05\ucb06\ucb07\ucb08\ucb09\ucb0a\ucb0b\ucb0c\ucb0d\ucb0e\ucb0f\ucb10\ucb11\ucb12\ucb13\ucb14\ucb15\ucb16\ucb17\ucb18\ucb19\ucb1a\ucb1b\ucb1c\ucb1d\ucb1e\ucb1f\ucb20\ucb21\ucb22\ucb23\ucb24\ucb25\ucb26\ucb27\ucb28\ucb29\ucb2a\ucb2b\ucb2c\ucb2d\ucb2e\ucb2f\ucb30\ucb31\ucb32\ucb33\ucb34\ucb35\ucb36\ucb37\ucb38\ucb39\ucb3a\ucb3b\ucb3c\ucb3d\ucb3e\ucb3f\ucb40\ucb41\ucb42\ucb43\ucb44\ucb45\ucb46\ucb47\ucb48\ucb49\ucb4a\ucb4b\ucb4c\ucb4d\ucb4e\ucb4f\ucb50\ucb51\ucb52\ucb53\ucb54\ucb55\ucb56\ucb57\ucb58\ucb59\ucb5a\ucb5b\ucb5c\ucb5d\ucb5e\ucb5f\ucb60\ucb61\ucb62\ucb63\ucb64\ucb65\ucb66\ucb67\ucb68\ucb69\ucb6a\ucb6b\ucb6c\ucb6d\ucb6e\ucb6f\ucb70\ucb71\ucb72\ucb73\ucb74\ucb75\ucb76\ucb77\ucb78\ucb79\ucb7a\ucb7b\ucb7c\ucb7d\ucb7e\ucb7f\ucb80\ucb81\ucb82\ucb83\ucb84\ucb85\ucb86\ucb87\ucb88\ucb89\ucb8a\ucb8b\ucb8c\ucb8d\ucb8e\ucb8f\ucb90\ucb91\ucb92\ucb93\ucb94\ucb95\ucb96\ucb97\ucb98\ucb99\ucb9a\ucb9b\ucb9c\ucb9d\ucb9e\ucb9f\ucba0\ucba1\ucba2\ucba3\ucba4\ucba5\ucba6\ucba7\ucba8\ucba9\ucbaa\ucbab\ucbac\ucbad\ucbae\ucbaf\ucbb0\ucbb1\ucbb2\ucbb3\ucbb4\ucbb5\ucbb6\ucbb7\ucbb8\ucbb9\ucbba\ucbbb\ucbbc\ucbbd\ucbbe\ucbbf\ucbc0\ucbc1\ucbc2\ucbc3\ucbc4\ucbc5\ucbc6\ucbc7\ucbc8\ucbc9\ucbca\ucbcb\ucbcc\ucbcd\ucbce\ucbcf\ucbd0\ucbd1\ucbd2\ucbd3\ucbd4\ucbd5\ucbd6\ucbd7\ucbd8\ucbd9\ucbda\ucbdb\ucbdc\ucbdd\ucbde\ucbdf\ucbe0\ucbe1\ucbe2\ucbe3\ucbe4\ucbe5\ucbe6\ucbe7\ucbe8\ucbe9\ucbea\ucbeb\ucbec\ucbed\ucbee\ucbef\ucbf0\ucbf1\ucbf2\ucbf3\ucbf4\ucbf5\ucbf6\ucbf7\ucbf8\ucbf9\ucbfa\ucbfb\ucbfc\ucbfd\ucbfe\ucbff\ucc00\ucc01\ucc02\ucc03\ucc04\ucc05\ucc06\ucc07\ucc08\ucc09\ucc0a\ucc0b\ucc0c\ucc0d\ucc0e\ucc0f\ucc10\ucc11\ucc12\ucc13\ucc14\ucc15\ucc16\ucc17\ucc18\ucc19\ucc1a\ucc1b\ucc1c\ucc1d\ucc1e\ucc1f\ucc20\ucc21\ucc22\ucc23\ucc24\ucc25\ucc26\ucc27\ucc28\ucc29\ucc2a\ucc2b\ucc2c\ucc2d\ucc2e\ucc2f\ucc30\ucc31\ucc32\ucc33\ucc34\ucc35\ucc36\ucc37\ucc38\ucc39\ucc3a\ucc3b\ucc3c\ucc3d\ucc3e\ucc3f\ucc40\ucc41\ucc42\ucc43\ucc44\ucc45\ucc46\ucc47\ucc48\ucc49\ucc4a\ucc4b\ucc4c\ucc4d\ucc4e\ucc4f\ucc50\ucc51\ucc52\ucc53\ucc54\ucc55\ucc56\ucc57\ucc58\ucc59\ucc5a\ucc5b\ucc5c\ucc5d\ucc5e\ucc5f\ucc60\ucc61\ucc62\ucc63\ucc64\ucc65\ucc66\ucc67\ucc68\ucc69\ucc6a\ucc6b\ucc6c\ucc6d\ucc6e\ucc6f\ucc70\ucc71\ucc72\ucc73\ucc74\ucc75\ucc76\ucc77\ucc78\ucc79\ucc7a\ucc7b\ucc7c\ucc7d\ucc7e\ucc7f\ucc80\ucc81\ucc82\ucc83\ucc84\ucc85\ucc86\ucc87\ucc88\ucc89\ucc8a\ucc8b\ucc8c\ucc8d\ucc8e\ucc8f\ucc90\ucc91\ucc92\ucc93\ucc94\ucc95\ucc96\ucc97\ucc98\ucc99\ucc9a\ucc9b\ucc9c\ucc9d\ucc9e\ucc9f\ucca0\ucca1\ucca2\ucca3\ucca4\ucca5\ucca6\ucca7\ucca8\ucca9\uccaa\uccab\uccac\uccad\uccae\uccaf\uccb0\uccb1\uccb2\uccb3\uccb4\uccb5\uccb6\uccb7\uccb8\uccb9\uccba\uccbb\uccbc\uccbd\uccbe\uccbf\uccc0\uccc1\uccc2\uccc3\uccc4\uccc5\uccc6\uccc7\uccc8\uccc9\uccca\ucccb\ucccc\ucccd\uccce\ucccf\uccd0\uccd1\uccd2\uccd3\uccd4\uccd5\uccd6\uccd7\uccd8\uccd9\uccda\uccdb\uccdc\uccdd\uccde\uccdf\ucce0\ucce1\ucce2\ucce3\ucce4\ucce5\ucce6\ucce7\ucce8\ucce9\uccea\ucceb\uccec\ucced\uccee\uccef\uccf0\uccf1\uccf2\uccf3\uccf4\uccf5\uccf6\uccf7\uccf8\uccf9\uccfa\uccfb\uccfc\uccfd\uccfe\uccff\ucd00\ucd01\ucd02\ucd03\ucd04\ucd05\ucd06\ucd07\ucd08\ucd09\ucd0a\ucd0b\ucd0c\ucd0d\ucd0e\ucd0f\ucd10\ucd11\ucd12\ucd13\ucd14\ucd15\ucd16\ucd17\ucd18\ucd19\ucd1a\ucd1b\ucd1c\ucd1d\ucd1e\ucd1f\ucd20\ucd21\ucd22\ucd23\ucd24\ucd25\ucd26\ucd27\ucd28\ucd29\ucd2a\ucd2b\ucd2c\ucd2d\ucd2e\ucd2f\ucd30\ucd31\ucd32\ucd33\ucd34\ucd35\ucd36\ucd37\ucd38\ucd39\ucd3a\ucd3b\ucd3c\ucd3d\ucd3e\ucd3f\ucd40\ucd41\ucd42\ucd43\ucd44\ucd45\ucd46\ucd47\ucd48\ucd49\ucd4a\ucd4b\ucd4c\ucd4d\ucd4e\ucd4f\ucd50\ucd51\ucd52\ucd53\ucd54\ucd55\ucd56\ucd57\ucd58\ucd59\ucd5a\ucd5b\ucd5c\ucd5d\ucd5e\ucd5f\ucd60\ucd61\ucd62\ucd63\ucd64\ucd65\ucd66\ucd67\ucd68\ucd69\ucd6a\ucd6b\ucd6c\ucd6d\ucd6e\ucd6f\ucd70\ucd71\ucd72\ucd73\ucd74\ucd75\ucd76\ucd77\ucd78\ucd79\ucd7a\ucd7b\ucd7c\ucd7d\ucd7e\ucd7f\ucd80\ucd81\ucd82\ucd83\ucd84\ucd85\ucd86\ucd87\ucd88\ucd89\ucd8a\ucd8b\ucd8c\ucd8d\ucd8e\ucd8f\ucd90\ucd91\ucd92\ucd93\ucd94\ucd95\ucd96\ucd97\ucd98\ucd99\ucd9a\ucd9b\ucd9c\ucd9d\ucd9e\ucd9f\ucda0\ucda1\ucda2\ucda3\ucda4\ucda5\ucda6\ucda7\ucda8\ucda9\ucdaa\ucdab\ucdac\ucdad\ucdae\ucdaf\ucdb0\ucdb1\ucdb2\ucdb3\ucdb4\ucdb5\ucdb6\ucdb7\ucdb8\ucdb9\ucdba\ucdbb\ucdbc\ucdbd\ucdbe\ucdbf\ucdc0\ucdc1\ucdc2\ucdc3\ucdc4\ucdc5\ucdc6\ucdc7\ucdc8\ucdc9\ucdca\ucdcb\ucdcc\ucdcd\ucdce\ucdcf\ucdd0\ucdd1\ucdd2\ucdd3\ucdd4\ucdd5\ucdd6\ucdd7\ucdd8\ucdd9\ucdda\ucddb\ucddc\ucddd\ucdde\ucddf\ucde0\ucde1\ucde2\ucde3\ucde4\ucde5\ucde6\ucde7\ucde8\ucde9\ucdea\ucdeb\ucdec\ucded\ucdee\ucdef\ucdf0\ucdf1\ucdf2\ucdf3\ucdf4\ucdf5\ucdf6\ucdf7\ucdf8\ucdf9\ucdfa\ucdfb\ucdfc\ucdfd\ucdfe\ucdff\uce00\uce01\uce02\uce03\uce04\uce05\uce06\uce07\uce08\uce09\uce0a\uce0b\uce0c\uce0d\uce0e\uce0f\uce10\uce11\uce12\uce13\uce14\uce15\uce16\uce17\uce18\uce19\uce1a\uce1b\uce1c\uce1d\uce1e\uce1f\uce20\uce21\uce22\uce23\uce24\uce25\uce26\uce27\uce28\uce29\uce2a\uce2b\uce2c\uce2d\uce2e\uce2f\uce30\uce31\uce32\uce33\uce34\uce35\uce36\uce37\uce38\uce39\uce3a\uce3b\uce3c\uce3d\uce3e\uce3f\uce40\uce41\uce42\uce43\uce44\uce45\uce46\uce47\uce48\uce49\uce4a\uce4b\uce4c\uce4d\uce4e\uce4f\uce50\uce51\uce52\uce53\uce54\uce55\uce56\uce57\uce58\uce59\uce5a\uce5b\uce5c\uce5d\uce5e\uce5f\uce60\uce61\uce62\uce63\uce64\uce65\uce66\uce67\uce68\uce69\uce6a\uce6b\uce6c\uce6d\uce6e\uce6f\uce70\uce71\uce72\uce73\uce74\uce75\uce76\uce77\uce78\uce79\uce7a\uce7b\uce7c\uce7d\uce7e\uce7f\uce80\uce81\uce82\uce83\uce84\uce85\uce86\uce87\uce88\uce89\uce8a\uce8b\uce8c\uce8d\uce8e\uce8f\uce90\uce91\uce92\uce93\uce94\uce95\uce96\uce97\uce98\uce99\uce9a\uce9b\uce9c\uce9d\uce9e\uce9f\ucea0\ucea1\ucea2\ucea3\ucea4\ucea5\ucea6\ucea7\ucea8\ucea9\uceaa\uceab\uceac\ucead\uceae\uceaf\uceb0\uceb1\uceb2\uceb3\uceb4\uceb5\uceb6\uceb7\uceb8\uceb9\uceba\ucebb\ucebc\ucebd\ucebe\ucebf\ucec0\ucec1\ucec2\ucec3\ucec4\ucec5\ucec6\ucec7\ucec8\ucec9\uceca\ucecb\ucecc\ucecd\ucece\ucecf\uced0\uced1\uced2\uced3\uced4\uced5\uced6\uced7\uced8\uced9\uceda\ucedb\ucedc\ucedd\ucede\ucedf\ucee0\ucee1\ucee2\ucee3\ucee4\ucee5\ucee6\ucee7\ucee8\ucee9\uceea\uceeb\uceec\uceed\uceee\uceef\ucef0\ucef1\ucef2\ucef3\ucef4\ucef5\ucef6\ucef7\ucef8\ucef9\ucefa\ucefb\ucefc\ucefd\ucefe\uceff\ucf00\ucf01\ucf02\ucf03\ucf04\ucf05\ucf06\ucf07\ucf08\ucf09\ucf0a\ucf0b\ucf0c\ucf0d\ucf0e\ucf0f\ucf10\ucf11\ucf12\ucf13\ucf14\ucf15\ucf16\ucf17\ucf18\ucf19\ucf1a\ucf1b\ucf1c\ucf1d\ucf1e\ucf1f\ucf20\ucf21\ucf22\ucf23\ucf24\ucf25\ucf26\ucf27\ucf28\ucf29\ucf2a\ucf2b\ucf2c\ucf2d\ucf2e\ucf2f\ucf30\ucf31\ucf32\ucf33\ucf34\ucf35\ucf36\ucf37\ucf38\ucf39\ucf3a\ucf3b\ucf3c\ucf3d\ucf3e\ucf3f\ucf40\ucf41\ucf42\ucf43\ucf44\ucf45\ucf46\ucf47\ucf48\ucf49\ucf4a\ucf4b\ucf4c\ucf4d\ucf4e\ucf4f\ucf50\ucf51\ucf52\ucf53\ucf54\ucf55\ucf56\ucf57\ucf58\ucf59\ucf5a\ucf5b\ucf5c\ucf5d\ucf5e\ucf5f\ucf60\ucf61\ucf62\ucf63\ucf64\ucf65\ucf66\ucf67\ucf68\ucf69\ucf6a\ucf6b\ucf6c\ucf6d\ucf6e\ucf6f\ucf70\ucf71\ucf72\ucf73\ucf74\ucf75\ucf76\ucf77\ucf78\ucf79\ucf7a\ucf7b\ucf7c\ucf7d\ucf7e\ucf7f\ucf80\ucf81\ucf82\ucf83\ucf84\ucf85\ucf86\ucf87\ucf88\ucf89\ucf8a\ucf8b\ucf8c\ucf8d\ucf8e\ucf8f\ucf90\ucf91\ucf92\ucf93\ucf94\ucf95\ucf96\ucf97\ucf98\ucf99\ucf9a\ucf9b\ucf9c\ucf9d\ucf9e\ucf9f\ucfa0\ucfa1\ucfa2\ucfa3\ucfa4\ucfa5\ucfa6\ucfa7\ucfa8\ucfa9\ucfaa\ucfab\ucfac\ucfad\ucfae\ucfaf\ucfb0\ucfb1\ucfb2\ucfb3\ucfb4\ucfb5\ucfb6\ucfb7\ucfb8\ucfb9\ucfba\ucfbb\ucfbc\ucfbd\ucfbe\ucfbf\ucfc0\ucfc1\ucfc2\ucfc3\ucfc4\ucfc5\ucfc6\ucfc7\ucfc8\ucfc9\ucfca\ucfcb\ucfcc\ucfcd\ucfce\ucfcf\ucfd0\ucfd1\ucfd2\ucfd3\ucfd4\ucfd5\ucfd6\ucfd7\ucfd8\ucfd9\ucfda\ucfdb\ucfdc\ucfdd\ucfde\ucfdf\ucfe0\ucfe1\ucfe2\ucfe3\ucfe4\ucfe5\ucfe6\ucfe7\ucfe8\ucfe9\ucfea\ucfeb\ucfec\ucfed\ucfee\ucfef\ucff0\ucff1\ucff2\ucff3\ucff4\ucff5\ucff6\ucff7\ucff8\ucff9\ucffa\ucffb\ucffc\ucffd\ucffe\ucfff\ud000\ud001\ud002\ud003\ud004\ud005\ud006\ud007\ud008\ud009\ud00a\ud00b\ud00c\ud00d\ud00e\ud00f\ud010\ud011\ud012\ud013\ud014\ud015\ud016\ud017\ud018\ud019\ud01a\ud01b\ud01c\ud01d\ud01e\ud01f\ud020\ud021\ud022\ud023\ud024\ud025\ud026\ud027\ud028\ud029\ud02a\ud02b\ud02c\ud02d\ud02e\ud02f\ud030\ud031\ud032\ud033\ud034\ud035\ud036\ud037\ud038\ud039\ud03a\ud03b\ud03c\ud03d\ud03e\ud03f\ud040\ud041\ud042\ud043\ud044\ud045\ud046\ud047\ud048\ud049\ud04a\ud04b\ud04c\ud04d\ud04e\ud04f\ud050\ud051\ud052\ud053\ud054\ud055\ud056\ud057\ud058\ud059\ud05a\ud05b\ud05c\ud05d\ud05e\ud05f\ud060\ud061\ud062\ud063\ud064\ud065\ud066\ud067\ud068\ud069\ud06a\ud06b\ud06c\ud06d\ud06e\ud06f\ud070\ud071\ud072\ud073\ud074\ud075\ud076\ud077\ud078\ud079\ud07a\ud07b\ud07c\ud07d\ud07e\ud07f\ud080\ud081\ud082\ud083\ud084\ud085\ud086\ud087\ud088\ud089\ud08a\ud08b\ud08c\ud08d\ud08e\ud08f\ud090\ud091\ud092\ud093\ud094\ud095\ud096\ud097\ud098\ud099\ud09a\ud09b\ud09c\ud09d\ud09e\ud09f\ud0a0\ud0a1\ud0a2\ud0a3\ud0a4\ud0a5\ud0a6\ud0a7\ud0a8\ud0a9\ud0aa\ud0ab\ud0ac\ud0ad\ud0ae\ud0af\ud0b0\ud0b1\ud0b2\ud0b3\ud0b4\ud0b5\ud0b6\ud0b7\ud0b8\ud0b9\ud0ba\ud0bb\ud0bc\ud0bd\ud0be\ud0bf\ud0c0\ud0c1\ud0c2\ud0c3\ud0c4\ud0c5\ud0c6\ud0c7\ud0c8\ud0c9\ud0ca\ud0cb\ud0cc\ud0cd\ud0ce\ud0cf\ud0d0\ud0d1\ud0d2\ud0d3\ud0d4\ud0d5\ud0d6\ud0d7\ud0d8\ud0d9\ud0da\ud0db\ud0dc\ud0dd\ud0de\ud0df\ud0e0\ud0e1\ud0e2\ud0e3\ud0e4\ud0e5\ud0e6\ud0e7\ud0e8\ud0e9\ud0ea\ud0eb\ud0ec\ud0ed\ud0ee\ud0ef\ud0f0\ud0f1\ud0f2\ud0f3\ud0f4\ud0f5\ud0f6\ud0f7\ud0f8\ud0f9\ud0fa\ud0fb\ud0fc\ud0fd\ud0fe\ud0ff\ud100\ud101\ud102\ud103\ud104\ud105\ud106\ud107\ud108\ud109\ud10a\ud10b\ud10c\ud10d\ud10e\ud10f\ud110\ud111\ud112\ud113\ud114\ud115\ud116\ud117\ud118\ud119\ud11a\ud11b\ud11c\ud11d\ud11e\ud11f\ud120\ud121\ud122\ud123\ud124\ud125\ud126\ud127\ud128\ud129\ud12a\ud12b\ud12c\ud12d\ud12e\ud12f\ud130\ud131\ud132\ud133\ud134\ud135\ud136\ud137\ud138\ud139\ud13a\ud13b\ud13c\ud13d\ud13e\ud13f\ud140\ud141\ud142\ud143\ud144\ud145\ud146\ud147\ud148\ud149\ud14a\ud14b\ud14c\ud14d\ud14e\ud14f\ud150\ud151\ud152\ud153\ud154\ud155\ud156\ud157\ud158\ud159\ud15a\ud15b\ud15c\ud15d\ud15e\ud15f\ud160\ud161\ud162\ud163\ud164\ud165\ud166\ud167\ud168\ud169\ud16a\ud16b\ud16c\ud16d\ud16e\ud16f\ud170\ud171\ud172\ud173\ud174\ud175\ud176\ud177\ud178\ud179\ud17a\ud17b\ud17c\ud17d\ud17e\ud17f\ud180\ud181\ud182\ud183\ud184\ud185\ud186\ud187\ud188\ud189\ud18a\ud18b\ud18c\ud18d\ud18e\ud18f\ud190\ud191\ud192\ud193\ud194\ud195\ud196\ud197\ud198\ud199\ud19a\ud19b\ud19c\ud19d\ud19e\ud19f\ud1a0\ud1a1\ud1a2\ud1a3\ud1a4\ud1a5\ud1a6\ud1a7\ud1a8\ud1a9\ud1aa\ud1ab\ud1ac\ud1ad\ud1ae\ud1af\ud1b0\ud1b1\ud1b2\ud1b3\ud1b4\ud1b5\ud1b6\ud1b7\ud1b8\ud1b9\ud1ba\ud1bb\ud1bc\ud1bd\ud1be\ud1bf\ud1c0\ud1c1\ud1c2\ud1c3\ud1c4\ud1c5\ud1c6\ud1c7\ud1c8\ud1c9\ud1ca\ud1cb\ud1cc\ud1cd\ud1ce\ud1cf\ud1d0\ud1d1\ud1d2\ud1d3\ud1d4\ud1d5\ud1d6\ud1d7\ud1d8\ud1d9\ud1da\ud1db\ud1dc\ud1dd\ud1de\ud1df\ud1e0\ud1e1\ud1e2\ud1e3\ud1e4\ud1e5\ud1e6\ud1e7\ud1e8\ud1e9\ud1ea\ud1eb\ud1ec\ud1ed\ud1ee\ud1ef\ud1f0\ud1f1\ud1f2\ud1f3\ud1f4\ud1f5\ud1f6\ud1f7\ud1f8\ud1f9\ud1fa\ud1fb\ud1fc\ud1fd\ud1fe\ud1ff\ud200\ud201\ud202\ud203\ud204\ud205\ud206\ud207\ud208\ud209\ud20a\ud20b\ud20c\ud20d\ud20e\ud20f\ud210\ud211\ud212\ud213\ud214\ud215\ud216\ud217\ud218\ud219\ud21a\ud21b\ud21c\ud21d\ud21e\ud21f\ud220\ud221\ud222\ud223\ud224\ud225\ud226\ud227\ud228\ud229\ud22a\ud22b\ud22c\ud22d\ud22e\ud22f\ud230\ud231\ud232\ud233\ud234\ud235\ud236\ud237\ud238\ud239\ud23a\ud23b\ud23c\ud23d\ud23e\ud23f\ud240\ud241\ud242\ud243\ud244\ud245\ud246\ud247\ud248\ud249\ud24a\ud24b\ud24c\ud24d\ud24e\ud24f\ud250\ud251\ud252\ud253\ud254\ud255\ud256\ud257\ud258\ud259\ud25a\ud25b\ud25c\ud25d\ud25e\ud25f\ud260\ud261\ud262\ud263\ud264\ud265\ud266\ud267\ud268\ud269\ud26a\ud26b\ud26c\ud26d\ud26e\ud26f\ud270\ud271\ud272\ud273\ud274\ud275\ud276\ud277\ud278\ud279\ud27a\ud27b\ud27c\ud27d\ud27e\ud27f\ud280\ud281\ud282\ud283\ud284\ud285\ud286\ud287\ud288\ud289\ud28a\ud28b\ud28c\ud28d\ud28e\ud28f\ud290\ud291\ud292\ud293\ud294\ud295\ud296\ud297\ud298\ud299\ud29a\ud29b\ud29c\ud29d\ud29e\ud29f\ud2a0\ud2a1\ud2a2\ud2a3\ud2a4\ud2a5\ud2a6\ud2a7\ud2a8\ud2a9\ud2aa\ud2ab\ud2ac\ud2ad\ud2ae\ud2af\ud2b0\ud2b1\ud2b2\ud2b3\ud2b4\ud2b5\ud2b6\ud2b7\ud2b8\ud2b9\ud2ba\ud2bb\ud2bc\ud2bd\ud2be\ud2bf\ud2c0\ud2c1\ud2c2\ud2c3\ud2c4\ud2c5\ud2c6\ud2c7\ud2c8\ud2c9\ud2ca\ud2cb\ud2cc\ud2cd\ud2ce\ud2cf\ud2d0\ud2d1\ud2d2\ud2d3\ud2d4\ud2d5\ud2d6\ud2d7\ud2d8\ud2d9\ud2da\ud2db\ud2dc\ud2dd\ud2de\ud2df\ud2e0\ud2e1\ud2e2\ud2e3\ud2e4\ud2e5\ud2e6\ud2e7\ud2e8\ud2e9\ud2ea\ud2eb\ud2ec\ud2ed\ud2ee\ud2ef\ud2f0\ud2f1\ud2f2\ud2f3\ud2f4\ud2f5\ud2f6\ud2f7\ud2f8\ud2f9\ud2fa\ud2fb\ud2fc\ud2fd\ud2fe\ud2ff\ud300\ud301\ud302\ud303\ud304\ud305\ud306\ud307\ud308\ud309\ud30a\ud30b\ud30c\ud30d\ud30e\ud30f\ud310\ud311\ud312\ud313\ud314\ud315\ud316\ud317\ud318\ud319\ud31a\ud31b\ud31c\ud31d\ud31e\ud31f\ud320\ud321\ud322\ud323\ud324\ud325\ud326\ud327\ud328\ud329\ud32a\ud32b\ud32c\ud32d\ud32e\ud32f\ud330\ud331\ud332\ud333\ud334\ud335\ud336\ud337\ud338\ud339\ud33a\ud33b\ud33c\ud33d\ud33e\ud33f\ud340\ud341\ud342\ud343\ud344\ud345\ud346\ud347\ud348\ud349\ud34a\ud34b\ud34c\ud34d\ud34e\ud34f\ud350\ud351\ud352\ud353\ud354\ud355\ud356\ud357\ud358\ud359\ud35a\ud35b\ud35c\ud35d\ud35e\ud35f\ud360\ud361\ud362\ud363\ud364\ud365\ud366\ud367\ud368\ud369\ud36a\ud36b\ud36c\ud36d\ud36e\ud36f\ud370\ud371\ud372\ud373\ud374\ud375\ud376\ud377\ud378\ud379\ud37a\ud37b\ud37c\ud37d\ud37e\ud37f\ud380\ud381\ud382\ud383\ud384\ud385\ud386\ud387\ud388\ud389\ud38a\ud38b\ud38c\ud38d\ud38e\ud38f\ud390\ud391\ud392\ud393\ud394\ud395\ud396\ud397\ud398\ud399\ud39a\ud39b\ud39c\ud39d\ud39e\ud39f\ud3a0\ud3a1\ud3a2\ud3a3\ud3a4\ud3a5\ud3a6\ud3a7\ud3a8\ud3a9\ud3aa\ud3ab\ud3ac\ud3ad\ud3ae\ud3af\ud3b0\ud3b1\ud3b2\ud3b3\ud3b4\ud3b5\ud3b6\ud3b7\ud3b8\ud3b9\ud3ba\ud3bb\ud3bc\ud3bd\ud3be\ud3bf\ud3c0\ud3c1\ud3c2\ud3c3\ud3c4\ud3c5\ud3c6\ud3c7\ud3c8\ud3c9\ud3ca\ud3cb\ud3cc\ud3cd\ud3ce\ud3cf\ud3d0\ud3d1\ud3d2\ud3d3\ud3d4\ud3d5\ud3d6\ud3d7\ud3d8\ud3d9\ud3da\ud3db\ud3dc\ud3dd\ud3de\ud3df\ud3e0\ud3e1\ud3e2\ud3e3\ud3e4\ud3e5\ud3e6\ud3e7\ud3e8\ud3e9\ud3ea\ud3eb\ud3ec\ud3ed\ud3ee\ud3ef\ud3f0\ud3f1\ud3f2\ud3f3\ud3f4\ud3f5\ud3f6\ud3f7\ud3f8\ud3f9\ud3fa\ud3fb\ud3fc\ud3fd\ud3fe\ud3ff\ud400\ud401\ud402\ud403\ud404\ud405\ud406\ud407\ud408\ud409\ud40a\ud40b\ud40c\ud40d\ud40e\ud40f\ud410\ud411\ud412\ud413\ud414\ud415\ud416\ud417\ud418\ud419\ud41a\ud41b\ud41c\ud41d\ud41e\ud41f\ud420\ud421\ud422\ud423\ud424\ud425\ud426\ud427\ud428\ud429\ud42a\ud42b\ud42c\ud42d\ud42e\ud42f\ud430\ud431\ud432\ud433\ud434\ud435\ud436\ud437\ud438\ud439\ud43a\ud43b\ud43c\ud43d\ud43e\ud43f\ud440\ud441\ud442\ud443\ud444\ud445\ud446\ud447\ud448\ud449\ud44a\ud44b\ud44c\ud44d\ud44e\ud44f\ud450\ud451\ud452\ud453\ud454\ud455\ud456\ud457\ud458\ud459\ud45a\ud45b\ud45c\ud45d\ud45e\ud45f\ud460\ud461\ud462\ud463\ud464\ud465\ud466\ud467\ud468\ud469\ud46a\ud46b\ud46c\ud46d\ud46e\ud46f\ud470\ud471\ud472\ud473\ud474\ud475\ud476\ud477\ud478\ud479\ud47a\ud47b\ud47c\ud47d\ud47e\ud47f\ud480\ud481\ud482\ud483\ud484\ud485\ud486\ud487\ud488\ud489\ud48a\ud48b\ud48c\ud48d\ud48e\ud48f\ud490\ud491\ud492\ud493\ud494\ud495\ud496\ud497\ud498\ud499\ud49a\ud49b\ud49c\ud49d\ud49e\ud49f\ud4a0\ud4a1\ud4a2\ud4a3\ud4a4\ud4a5\ud4a6\ud4a7\ud4a8\ud4a9\ud4aa\ud4ab\ud4ac\ud4ad\ud4ae\ud4af\ud4b0\ud4b1\ud4b2\ud4b3\ud4b4\ud4b5\ud4b6\ud4b7\ud4b8\ud4b9\ud4ba\ud4bb\ud4bc\ud4bd\ud4be\ud4bf\ud4c0\ud4c1\ud4c2\ud4c3\ud4c4\ud4c5\ud4c6\ud4c7\ud4c8\ud4c9\ud4ca\ud4cb\ud4cc\ud4cd\ud4ce\ud4cf\ud4d0\ud4d1\ud4d2\ud4d3\ud4d4\ud4d5\ud4d6\ud4d7\ud4d8\ud4d9\ud4da\ud4db\ud4dc\ud4dd\ud4de\ud4df\ud4e0\ud4e1\ud4e2\ud4e3\ud4e4\ud4e5\ud4e6\ud4e7\ud4e8\ud4e9\ud4ea\ud4eb\ud4ec\ud4ed\ud4ee\ud4ef\ud4f0\ud4f1\ud4f2\ud4f3\ud4f4\ud4f5\ud4f6\ud4f7\ud4f8\ud4f9\ud4fa\ud4fb\ud4fc\ud4fd\ud4fe\ud4ff\ud500\ud501\ud502\ud503\ud504\ud505\ud506\ud507\ud508\ud509\ud50a\ud50b\ud50c\ud50d\ud50e\ud50f\ud510\ud511\ud512\ud513\ud514\ud515\ud516\ud517\ud518\ud519\ud51a\ud51b\ud51c\ud51d\ud51e\ud51f\ud520\ud521\ud522\ud523\ud524\ud525\ud526\ud527\ud528\ud529\ud52a\ud52b\ud52c\ud52d\ud52e\ud52f\ud530\ud531\ud532\ud533\ud534\ud535\ud536\ud537\ud538\ud539\ud53a\ud53b\ud53c\ud53d\ud53e\ud53f\ud540\ud541\ud542\ud543\ud544\ud545\ud546\ud547\ud548\ud549\ud54a\ud54b\ud54c\ud54d\ud54e\ud54f\ud550\ud551\ud552\ud553\ud554\ud555\ud556\ud557\ud558\ud559\ud55a\ud55b\ud55c\ud55d\ud55e\ud55f\ud560\ud561\ud562\ud563\ud564\ud565\ud566\ud567\ud568\ud569\ud56a\ud56b\ud56c\ud56d\ud56e\ud56f\ud570\ud571\ud572\ud573\ud574\ud575\ud576\ud577\ud578\ud579\ud57a\ud57b\ud57c\ud57d\ud57e\ud57f\ud580\ud581\ud582\ud583\ud584\ud585\ud586\ud587\ud588\ud589\ud58a\ud58b\ud58c\ud58d\ud58e\ud58f\ud590\ud591\ud592\ud593\ud594\ud595\ud596\ud597\ud598\ud599\ud59a\ud59b\ud59c\ud59d\ud59e\ud59f\ud5a0\ud5a1\ud5a2\ud5a3\ud5a4\ud5a5\ud5a6\ud5a7\ud5a8\ud5a9\ud5aa\ud5ab\ud5ac\ud5ad\ud5ae\ud5af\ud5b0\ud5b1\ud5b2\ud5b3\ud5b4\ud5b5\ud5b6\ud5b7\ud5b8\ud5b9\ud5ba\ud5bb\ud5bc\ud5bd\ud5be\ud5bf\ud5c0\ud5c1\ud5c2\ud5c3\ud5c4\ud5c5\ud5c6\ud5c7\ud5c8\ud5c9\ud5ca\ud5cb\ud5cc\ud5cd\ud5ce\ud5cf\ud5d0\ud5d1\ud5d2\ud5d3\ud5d4\ud5d5\ud5d6\ud5d7\ud5d8\ud5d9\ud5da\ud5db\ud5dc\ud5dd\ud5de\ud5df\ud5e0\ud5e1\ud5e2\ud5e3\ud5e4\ud5e5\ud5e6\ud5e7\ud5e8\ud5e9\ud5ea\ud5eb\ud5ec\ud5ed\ud5ee\ud5ef\ud5f0\ud5f1\ud5f2\ud5f3\ud5f4\ud5f5\ud5f6\ud5f7\ud5f8\ud5f9\ud5fa\ud5fb\ud5fc\ud5fd\ud5fe\ud5ff\ud600\ud601\ud602\ud603\ud604\ud605\ud606\ud607\ud608\ud609\ud60a\ud60b\ud60c\ud60d\ud60e\ud60f\ud610\ud611\ud612\ud613\ud614\ud615\ud616\ud617\ud618\ud619\ud61a\ud61b\ud61c\ud61d\ud61e\ud61f\ud620\ud621\ud622\ud623\ud624\ud625\ud626\ud627\ud628\ud629\ud62a\ud62b\ud62c\ud62d\ud62e\ud62f\ud630\ud631\ud632\ud633\ud634\ud635\ud636\ud637\ud638\ud639\ud63a\ud63b\ud63c\ud63d\ud63e\ud63f\ud640\ud641\ud642\ud643\ud644\ud645\ud646\ud647\ud648\ud649\ud64a\ud64b\ud64c\ud64d\ud64e\ud64f\ud650\ud651\ud652\ud653\ud654\ud655\ud656\ud657\ud658\ud659\ud65a\ud65b\ud65c\ud65d\ud65e\ud65f\ud660\ud661\ud662\ud663\ud664\ud665\ud666\ud667\ud668\ud669\ud66a\ud66b\ud66c\ud66d\ud66e\ud66f\ud670\ud671\ud672\ud673\ud674\ud675\ud676\ud677\ud678\ud679\ud67a\ud67b\ud67c\ud67d\ud67e\ud67f\ud680\ud681\ud682\ud683\ud684\ud685\ud686\ud687\ud688\ud689\ud68a\ud68b\ud68c\ud68d\ud68e\ud68f\ud690\ud691\ud692\ud693\ud694\ud695\ud696\ud697\ud698\ud699\ud69a\ud69b\ud69c\ud69d\ud69e\ud69f\ud6a0\ud6a1\ud6a2\ud6a3\ud6a4\ud6a5\ud6a6\ud6a7\ud6a8\ud6a9\ud6aa\ud6ab\ud6ac\ud6ad\ud6ae\ud6af\ud6b0\ud6b1\ud6b2\ud6b3\ud6b4\ud6b5\ud6b6\ud6b7\ud6b8\ud6b9\ud6ba\ud6bb\ud6bc\ud6bd\ud6be\ud6bf\ud6c0\ud6c1\ud6c2\ud6c3\ud6c4\ud6c5\ud6c6\ud6c7\ud6c8\ud6c9\ud6ca\ud6cb\ud6cc\ud6cd\ud6ce\ud6cf\ud6d0\ud6d1\ud6d2\ud6d3\ud6d4\ud6d5\ud6d6\ud6d7\ud6d8\ud6d9\ud6da\ud6db\ud6dc\ud6dd\ud6de\ud6df\ud6e0\ud6e1\ud6e2\ud6e3\ud6e4\ud6e5\ud6e6\ud6e7\ud6e8\ud6e9\ud6ea\ud6eb\ud6ec\ud6ed\ud6ee\ud6ef\ud6f0\ud6f1\ud6f2\ud6f3\ud6f4\ud6f5\ud6f6\ud6f7\ud6f8\ud6f9\ud6fa\ud6fb\ud6fc\ud6fd\ud6fe\ud6ff\ud700\ud701\ud702\ud703\ud704\ud705\ud706\ud707\ud708\ud709\ud70a\ud70b\ud70c\ud70d\ud70e\ud70f\ud710\ud711\ud712\ud713\ud714\ud715\ud716\ud717\ud718\ud719\ud71a\ud71b\ud71c\ud71d\ud71e\ud71f\ud720\ud721\ud722\ud723\ud724\ud725\ud726\ud727\ud728\ud729\ud72a\ud72b\ud72c\ud72d\ud72e\ud72f\ud730\ud731\ud732\ud733\ud734\ud735\ud736\ud737\ud738\ud739\ud73a\ud73b\ud73c\ud73d\ud73e\ud73f\ud740\ud741\ud742\ud743\ud744\ud745\ud746\ud747\ud748\ud749\ud74a\ud74b\ud74c\ud74d\ud74e\ud74f\ud750\ud751\ud752\ud753\ud754\ud755\ud756\ud757\ud758\ud759\ud75a\ud75b\ud75c\ud75d\ud75e\ud75f\ud760\ud761\ud762\ud763\ud764\ud765\ud766\ud767\ud768\ud769\ud76a\ud76b\ud76c\ud76d\ud76e\ud76f\ud770\ud771\ud772\ud773\ud774\ud775\ud776\ud777\ud778\ud779\ud77a\ud77b\ud77c\ud77d\ud77e\ud77f\ud780\ud781\ud782\ud783\ud784\ud785\ud786\ud787\ud788\ud789\ud78a\ud78b\ud78c\ud78d\ud78e\ud78f\ud790\ud791\ud792\ud793\ud794\ud795\ud796\ud797\ud798\ud799\ud79a\ud79b\ud79c\ud79d\ud79e\ud79f\ud7a0\ud7a1\ud7a2\ud7a3\uf900\uf901\uf902\uf903\uf904\uf905\uf906\uf907\uf908\uf909\uf90a\uf90b\uf90c\uf90d\uf90e\uf90f\uf910\uf911\uf912\uf913\uf914\uf915\uf916\uf917\uf918\uf919\uf91a\uf91b\uf91c\uf91d\uf91e\uf91f\uf920\uf921\uf922\uf923\uf924\uf925\uf926\uf927\uf928\uf929\uf92a\uf92b\uf92c\uf92d\uf92e\uf92f\uf930\uf931\uf932\uf933\uf934\uf935\uf936\uf937\uf938\uf939\uf93a\uf93b\uf93c\uf93d\uf93e\uf93f\uf940\uf941\uf942\uf943\uf944\uf945\uf946\uf947\uf948\uf949\uf94a\uf94b\uf94c\uf94d\uf94e\uf94f\uf950\uf951\uf952\uf953\uf954\uf955\uf956\uf957\uf958\uf959\uf95a\uf95b\uf95c\uf95d\uf95e\uf95f\uf960\uf961\uf962\uf963\uf964\uf965\uf966\uf967\uf968\uf969\uf96a\uf96b\uf96c\uf96d\uf96e\uf96f\uf970\uf971\uf972\uf973\uf974\uf975\uf976\uf977\uf978\uf979\uf97a\uf97b\uf97c\uf97d\uf97e\uf97f\uf980\uf981\uf982\uf983\uf984\uf985\uf986\uf987\uf988\uf989\uf98a\uf98b\uf98c\uf98d\uf98e\uf98f\uf990\uf991\uf992\uf993\uf994\uf995\uf996\uf997\uf998\uf999\uf99a\uf99b\uf99c\uf99d\uf99e\uf99f\uf9a0\uf9a1\uf9a2\uf9a3\uf9a4\uf9a5\uf9a6\uf9a7\uf9a8\uf9a9\uf9aa\uf9ab\uf9ac\uf9ad\uf9ae\uf9af\uf9b0\uf9b1\uf9b2\uf9b3\uf9b4\uf9b5\uf9b6\uf9b7\uf9b8\uf9b9\uf9ba\uf9bb\uf9bc\uf9bd\uf9be\uf9bf\uf9c0\uf9c1\uf9c2\uf9c3\uf9c4\uf9c5\uf9c6\uf9c7\uf9c8\uf9c9\uf9ca\uf9cb\uf9cc\uf9cd\uf9ce\uf9cf\uf9d0\uf9d1\uf9d2\uf9d3\uf9d4\uf9d5\uf9d6\uf9d7\uf9d8\uf9d9\uf9da\uf9db\uf9dc\uf9dd\uf9de\uf9df\uf9e0\uf9e1\uf9e2\uf9e3\uf9e4\uf9e5\uf9e6\uf9e7\uf9e8\uf9e9\uf9ea\uf9eb\uf9ec\uf9ed\uf9ee\uf9ef\uf9f0\uf9f1\uf9f2\uf9f3\uf9f4\uf9f5\uf9f6\uf9f7\uf9f8\uf9f9\uf9fa\uf9fb\uf9fc\uf9fd\uf9fe\uf9ff\ufa00\ufa01\ufa02\ufa03\ufa04\ufa05\ufa06\ufa07\ufa08\ufa09\ufa0a\ufa0b\ufa0c\ufa0d\ufa0e\ufa0f\ufa10\ufa11\ufa12\ufa13\ufa14\ufa15\ufa16\ufa17\ufa18\ufa19\ufa1a\ufa1b\ufa1c\ufa1d\ufa1e\ufa1f\ufa20\ufa21\ufa22\ufa23\ufa24\ufa25\ufa26\ufa27\ufa28\ufa29\ufa2a\ufa2b\ufa2c\ufa2d\ufa30\ufa31\ufa32\ufa33\ufa34\ufa35\ufa36\ufa37\ufa38\ufa39\ufa3a\ufa3b\ufa3c\ufa3d\ufa3e\ufa3f\ufa40\ufa41\ufa42\ufa43\ufa44\ufa45\ufa46\ufa47\ufa48\ufa49\ufa4a\ufa4b\ufa4c\ufa4d\ufa4e\ufa4f\ufa50\ufa51\ufa52\ufa53\ufa54\ufa55\ufa56\ufa57\ufa58\ufa59\ufa5a\ufa5b\ufa5c\ufa5d\ufa5e\ufa5f\ufa60\ufa61\ufa62\ufa63\ufa64\ufa65\ufa66\ufa67\ufa68\ufa69\ufa6a\ufa70\ufa71\ufa72\ufa73\ufa74\ufa75\ufa76\ufa77\ufa78\ufa79\ufa7a\ufa7b\ufa7c\ufa7d\ufa7e\ufa7f\ufa80\ufa81\ufa82\ufa83\ufa84\ufa85\ufa86\ufa87\ufa88\ufa89\ufa8a\ufa8b\ufa8c\ufa8d\ufa8e\ufa8f\ufa90\ufa91\ufa92\ufa93\ufa94\ufa95\ufa96\ufa97\ufa98\ufa99\ufa9a\ufa9b\ufa9c\ufa9d\ufa9e\ufa9f\ufaa0\ufaa1\ufaa2\ufaa3\ufaa4\ufaa5\ufaa6\ufaa7\ufaa8\ufaa9\ufaaa\ufaab\ufaac\ufaad\ufaae\ufaaf\ufab0\ufab1\ufab2\ufab3\ufab4\ufab5\ufab6\ufab7\ufab8\ufab9\ufaba\ufabb\ufabc\ufabd\ufabe\ufabf\ufac0\ufac1\ufac2\ufac3\ufac4\ufac5\ufac6\ufac7\ufac8\ufac9\ufaca\ufacb\ufacc\ufacd\uface\ufacf\ufad0\ufad1\ufad2\ufad3\ufad4\ufad5\ufad6\ufad7\ufad8\ufad9\ufb1d\ufb1f\ufb20\ufb21\ufb22\ufb23\ufb24\ufb25\ufb26\ufb27\ufb28\ufb2a\ufb2b\ufb2c\ufb2d\ufb2e\ufb2f\ufb30\ufb31\ufb32\ufb33\ufb34\ufb35\ufb36\ufb38\ufb39\ufb3a\ufb3b\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46\ufb47\ufb48\ufb49\ufb4a\ufb4b\ufb4c\ufb4d\ufb4e\ufb4f\ufb50\ufb51\ufb52\ufb53\ufb54\ufb55\ufb56\ufb57\ufb58\ufb59\ufb5a\ufb5b\ufb5c\ufb5d\ufb5e\ufb5f\ufb60\ufb61\ufb62\ufb63\ufb64\ufb65\ufb66\ufb67\ufb68\ufb69\ufb6a\ufb6b\ufb6c\ufb6d\ufb6e\ufb6f\ufb70\ufb71\ufb72\ufb73\ufb74\ufb75\ufb76\ufb77\ufb78\ufb79\ufb7a\ufb7b\ufb7c\ufb7d\ufb7e\ufb7f\ufb80\ufb81\ufb82\ufb83\ufb84\ufb85\ufb86\ufb87\ufb88\ufb89\ufb8a\ufb8b\ufb8c\ufb8d\ufb8e\ufb8f\ufb90\ufb91\ufb92\ufb93\ufb94\ufb95\ufb96\ufb97\ufb98\ufb99\ufb9a\ufb9b\ufb9c\ufb9d\ufb9e\ufb9f\ufba0\ufba1\ufba2\ufba3\ufba4\ufba5\ufba6\ufba7\ufba8\ufba9\ufbaa\ufbab\ufbac\ufbad\ufbae\ufbaf\ufbb0\ufbb1\ufbd3\ufbd4\ufbd5\ufbd6\ufbd7\ufbd8\ufbd9\ufbda\ufbdb\ufbdc\ufbdd\ufbde\ufbdf\ufbe0\ufbe1\ufbe2\ufbe3\ufbe4\ufbe5\ufbe6\ufbe7\ufbe8\ufbe9\ufbea\ufbeb\ufbec\ufbed\ufbee\ufbef\ufbf0\ufbf1\ufbf2\ufbf3\ufbf4\ufbf5\ufbf6\ufbf7\ufbf8\ufbf9\ufbfa\ufbfb\ufbfc\ufbfd\ufbfe\ufbff\ufc00\ufc01\ufc02\ufc03\ufc04\ufc05\ufc06\ufc07\ufc08\ufc09\ufc0a\ufc0b\ufc0c\ufc0d\ufc0e\ufc0f\ufc10\ufc11\ufc12\ufc13\ufc14\ufc15\ufc16\ufc17\ufc18\ufc19\ufc1a\ufc1b\ufc1c\ufc1d\ufc1e\ufc1f\ufc20\ufc21\ufc22\ufc23\ufc24\ufc25\ufc26\ufc27\ufc28\ufc29\ufc2a\ufc2b\ufc2c\ufc2d\ufc2e\ufc2f\ufc30\ufc31\ufc32\ufc33\ufc34\ufc35\ufc36\ufc37\ufc38\ufc39\ufc3a\ufc3b\ufc3c\ufc3d\ufc3e\ufc3f\ufc40\ufc41\ufc42\ufc43\ufc44\ufc45\ufc46\ufc47\ufc48\ufc49\ufc4a\ufc4b\ufc4c\ufc4d\ufc4e\ufc4f\ufc50\ufc51\ufc52\ufc53\ufc54\ufc55\ufc56\ufc57\ufc58\ufc59\ufc5a\ufc5b\ufc5c\ufc5d\ufc5e\ufc5f\ufc60\ufc61\ufc62\ufc63\ufc64\ufc65\ufc66\ufc67\ufc68\ufc69\ufc6a\ufc6b\ufc6c\ufc6d\ufc6e\ufc6f\ufc70\ufc71\ufc72\ufc73\ufc74\ufc75\ufc76\ufc77\ufc78\ufc79\ufc7a\ufc7b\ufc7c\ufc7d\ufc7e\ufc7f\ufc80\ufc81\ufc82\ufc83\ufc84\ufc85\ufc86\ufc87\ufc88\ufc89\ufc8a\ufc8b\ufc8c\ufc8d\ufc8e\ufc8f\ufc90\ufc91\ufc92\ufc93\ufc94\ufc95\ufc96\ufc97\ufc98\ufc99\ufc9a\ufc9b\ufc9c\ufc9d\ufc9e\ufc9f\ufca0\ufca1\ufca2\ufca3\ufca4\ufca5\ufca6\ufca7\ufca8\ufca9\ufcaa\ufcab\ufcac\ufcad\ufcae\ufcaf\ufcb0\ufcb1\ufcb2\ufcb3\ufcb4\ufcb5\ufcb6\ufcb7\ufcb8\ufcb9\ufcba\ufcbb\ufcbc\ufcbd\ufcbe\ufcbf\ufcc0\ufcc1\ufcc2\ufcc3\ufcc4\ufcc5\ufcc6\ufcc7\ufcc8\ufcc9\ufcca\ufccb\ufccc\ufccd\ufcce\ufccf\ufcd0\ufcd1\ufcd2\ufcd3\ufcd4\ufcd5\ufcd6\ufcd7\ufcd8\ufcd9\ufcda\ufcdb\ufcdc\ufcdd\ufcde\ufcdf\ufce0\ufce1\ufce2\ufce3\ufce4\ufce5\ufce6\ufce7\ufce8\ufce9\ufcea\ufceb\ufcec\ufced\ufcee\ufcef\ufcf0\ufcf1\ufcf2\ufcf3\ufcf4\ufcf5\ufcf6\ufcf7\ufcf8\ufcf9\ufcfa\ufcfb\ufcfc\ufcfd\ufcfe\ufcff\ufd00\ufd01\ufd02\ufd03\ufd04\ufd05\ufd06\ufd07\ufd08\ufd09\ufd0a\ufd0b\ufd0c\ufd0d\ufd0e\ufd0f\ufd10\ufd11\ufd12\ufd13\ufd14\ufd15\ufd16\ufd17\ufd18\ufd19\ufd1a\ufd1b\ufd1c\ufd1d\ufd1e\ufd1f\ufd20\ufd21\ufd22\ufd23\ufd24\ufd25\ufd26\ufd27\ufd28\ufd29\ufd2a\ufd2b\ufd2c\ufd2d\ufd2e\ufd2f\ufd30\ufd31\ufd32\ufd33\ufd34\ufd35\ufd36\ufd37\ufd38\ufd39\ufd3a\ufd3b\ufd3c\ufd3d\ufd50\ufd51\ufd52\ufd53\ufd54\ufd55\ufd56\ufd57\ufd58\ufd59\ufd5a\ufd5b\ufd5c\ufd5d\ufd5e\ufd5f\ufd60\ufd61\ufd62\ufd63\ufd64\ufd65\ufd66\ufd67\ufd68\ufd69\ufd6a\ufd6b\ufd6c\ufd6d\ufd6e\ufd6f\ufd70\ufd71\ufd72\ufd73\ufd74\ufd75\ufd76\ufd77\ufd78\ufd79\ufd7a\ufd7b\ufd7c\ufd7d\ufd7e\ufd7f\ufd80\ufd81\ufd82\ufd83\ufd84\ufd85\ufd86\ufd87\ufd88\ufd89\ufd8a\ufd8b\ufd8c\ufd8d\ufd8e\ufd8f\ufd92\ufd93\ufd94\ufd95\ufd96\ufd97\ufd98\ufd99\ufd9a\ufd9b\ufd9c\ufd9d\ufd9e\ufd9f\ufda0\ufda1\ufda2\ufda3\ufda4\ufda5\ufda6\ufda7\ufda8\ufda9\ufdaa\ufdab\ufdac\ufdad\ufdae\ufdaf\ufdb0\ufdb1\ufdb2\ufdb3\ufdb4\ufdb5\ufdb6\ufdb7\ufdb8\ufdb9\ufdba\ufdbb\ufdbc\ufdbd\ufdbe\ufdbf\ufdc0\ufdc1\ufdc2\ufdc3\ufdc4\ufdc5\ufdc6\ufdc7\ufdf0\ufdf1\ufdf2\ufdf3\ufdf4\ufdf5\ufdf6\ufdf7\ufdf8\ufdf9\ufdfa\ufdfb\ufe70\ufe71\ufe72\ufe73\ufe74\ufe76\ufe77\ufe78\ufe79\ufe7a\ufe7b\ufe7c\ufe7d\ufe7e\ufe7f\ufe80\ufe81\ufe82\ufe83\ufe84\ufe85\ufe86\ufe87\ufe88\ufe89\ufe8a\ufe8b\ufe8c\ufe8d\ufe8e\ufe8f\ufe90\ufe91\ufe92\ufe93\ufe94\ufe95\ufe96\ufe97\ufe98\ufe99\ufe9a\ufe9b\ufe9c\ufe9d\ufe9e\ufe9f\ufea0\ufea1\ufea2\ufea3\ufea4\ufea5\ufea6\ufea7\ufea8\ufea9\ufeaa\ufeab\ufeac\ufead\ufeae\ufeaf\ufeb0\ufeb1\ufeb2\ufeb3\ufeb4\ufeb5\ufeb6\ufeb7\ufeb8\ufeb9\ufeba\ufebb\ufebc\ufebd\ufebe\ufebf\ufec0\ufec1\ufec2\ufec3\ufec4\ufec5\ufec6\ufec7\ufec8\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed2\ufed3\ufed4\ufed5\ufed6\ufed7\ufed8\ufed9\ufeda\ufedb\ufedc\ufedd\ufede\ufedf\ufee0\ufee1\ufee2\ufee3\ufee4\ufee5\ufee6\ufee7\ufee8\ufee9\ufeea\ufeeb\ufeec\ufeed\ufeee\ufeef\ufef0\ufef1\ufef2\ufef3\ufef4\ufef5\ufef6\ufef7\ufef8\ufef9\ufefa\ufefb\ufefc\uff66\uff67\uff68\uff69\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7a\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89\uff8a\uff8b\uff8c\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95\uff96\uff97\uff98\uff99\uff9a\uff9b\uff9c\uff9d\uffa0\uffa1\uffa2\uffa3\uffa4\uffa5\uffa6\uffa7\uffa8\uffa9\uffaa\uffab\uffac\uffad\uffae\uffaf\uffb0\uffb1\uffb2\uffb3\uffb4\uffb5\uffb6\uffb7\uffb8\uffb9\uffba\uffbb\uffbc\uffbd\uffbe\uffc2\uffc3\uffc4\uffc5\uffc6\uffc7\uffca\uffcb\uffcc\uffcd\uffce\uffcf\uffd2\uffd3\uffd4\uffd5\uffd6\uffd7\uffda\uffdb\uffdc'
-
-Lt = u'\u01c5\u01c8\u01cb\u01f2\u1f88\u1f89\u1f8a\u1f8b\u1f8c\u1f8d\u1f8e\u1f8f\u1f98\u1f99\u1f9a\u1f9b\u1f9c\u1f9d\u1f9e\u1f9f\u1fa8\u1fa9\u1faa\u1fab\u1fac\u1fad\u1fae\u1faf\u1fbc\u1fcc\u1ffc'
-
-Lu = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\u0100\u0102\u0104\u0106\u0108\u010a\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170\u0172\u0174\u0176\u0178\u0179\u017b\u017d\u0181\u0182\u0184\u0186\u0187\u0189\u018a\u018b\u018e\u018f\u0190\u0191\u0193\u0194\u0196\u0197\u0198\u019c\u019d\u019f\u01a0\u01a2\u01a4\u01a6\u01a7\u01a9\u01ac\u01ae\u01af\u01b1\u01b2\u01b3\u01b5\u01b7\u01b8\u01bc\u01c4\u01c7\u01ca\u01cd\u01cf\u01d1\u01d3\u01d5\u01d7\u01d9\u01db\u01de\u01e0\u01e2\u01e4\u01e6\u01e8\u01ea\u01ec\u01ee\u01f1\u01f4\u01f6\u01f7\u01f8\u01fa\u01fc\u01fe\u0200\u0202\u0204\u0206\u0208\u020a\u020c\u020e\u0210\u0212\u0214\u0216\u0218\u021a\u021c\u021e\u0220\u0222\u0224\u0226\u0228\u022a\u022c\u022e\u0230\u0232\u023a\u023b\u023d\u023e\u0241\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03d2\u03d3\u03d4\u03d8\u03da\u03dc\u03de\u03e0\u03e2\u03e4\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u03f7\u03f9\u03fa\u03fd\u03fe\u03ff\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u040d\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0460\u0462\u0464\u0466\u0468\u046a\u046c\u046e\u0470\u0472\u0474\u0476\u0478\u047a\u047c\u047e\u0480\u048a\u048c\u048e\u0490\u0492\u0494\u0496\u0498\u049a\u049c\u049e\u04a0\u04a2\u04a4\u04a6\u04a8\u04aa\u04ac\u04ae\u04b0\u04b2\u04b4\u04b6\u04b8\u04ba\u04bc\u04be\u04c0\u04c1\u04c3\u04c5\u04c7\u04c9\u04cb\u04cd\u04d0\u04d2\u04d4\u04d6\u04d8\u04da\u04dc\u04de\u04e0\u04e2\u04e4\u04e6\u04e8\u04ea\u04ec\u04ee\u04f0\u04f2\u04f4\u04f6\u04f8\u0500\u0502\u0504\u0506\u0508\u050a\u050c\u050e\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u10a0\u10a1\u10a2\u10a3\u10a4\u10a5\u10a6\u10a7\u10a8\u10a9\u10aa\u10ab\u10ac\u10ad\u10ae\u10af\u10b0\u10b1\u10b2\u10b3\u10b4\u10b5\u10b6\u10b7\u10b8\u10b9\u10ba\u10bb\u10bc\u10bd\u10be\u10bf\u10c0\u10c1\u10c2\u10c3\u10c4\u10c5\u1e00\u1e02\u1e04\u1e06\u1e08\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1e1e\u1e20\u1e22\u1e24\u1e26\u1e28\u1e2a\u1e2c\u1e2e\u1e30\u1e32\u1e34\u1e36\u1e38\u1e3a\u1e3c\u1e3e\u1e40\u1e42\u1e44\u1e46\u1e48\u1e4a\u1e4c\u1e4e\u1e50\u1e52\u1e54\u1e56\u1e58\u1e5a\u1e5c\u1e5e\u1e60\u1e62\u1e64\u1e66\u1e68\u1e6a\u1e6c\u1e6e\u1e70\u1e72\u1e74\u1e76\u1e78\u1e7a\u1e7c\u1e7e\u1e80\u1e82\u1e84\u1e86\u1e88\u1e8a\u1e8c\u1e8e\u1e90\u1e92\u1e94\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u1ec8\u1eca\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u1ef2\u1ef4\u1ef6\u1ef8\u1f08\u1f09\u1f0a\u1f0b\u1f0c\u1f0d\u1f0e\u1f0f\u1f18\u1f19\u1f1a\u1f1b\u1f1c\u1f1d\u1f28\u1f29\u1f2a\u1f2b\u1f2c\u1f2d\u1f2e\u1f2f\u1f38\u1f39\u1f3a\u1f3b\u1f3c\u1f3d\u1f3e\u1f3f\u1f48\u1f49\u1f4a\u1f4b\u1f4c\u1f4d\u1f59\u1f5b\u1f5d\u1f5f\u1f68\u1f69\u1f6a\u1f6b\u1f6c\u1f6d\u1f6e\u1f6f\u1fb8\u1fb9\u1fba\u1fbb\u1fc8\u1fc9\u1fca\u1fcb\u1fd8\u1fd9\u1fda\u1fdb\u1fe8\u1fe9\u1fea\u1feb\u1fec\u1ff8\u1ff9\u1ffa\u1ffb\u2102\u2107\u210b\u210c\u210d\u2110\u2111\u2112\u2115\u2119\u211a\u211b\u211c\u211d\u2124\u2126\u2128\u212a\u212b\u212c\u212d\u2130\u2131\u2133\u213e\u213f\u2145\u2c00\u2c01\u2c02\u2c03\u2c04\u2c05\u2c06\u2c07\u2c08\u2c09\u2c0a\u2c0b\u2c0c\u2c0d\u2c0e\u2c0f\u2c10\u2c11\u2c12\u2c13\u2c14\u2c15\u2c16\u2c17\u2c18\u2c19\u2c1a\u2c1b\u2c1c\u2c1d\u2c1e\u2c1f\u2c20\u2c21\u2c22\u2c23\u2c24\u2c25\u2c26\u2c27\u2c28\u2c29\u2c2a\u2c2b\u2c2c\u2c2d\u2c2e\u2c80\u2c82\u2c84\u2c86\u2c88\u2c8a\u2c8c\u2c8e\u2c90\u2c92\u2c94\u2c96\u2c98\u2c9a\u2c9c\u2c9e\u2ca0\u2ca2\u2ca4\u2ca6\u2ca8\u2caa\u2cac\u2cae\u2cb0\u2cb2\u2cb4\u2cb6\u2cb8\u2cba\u2cbc\u2cbe\u2cc0\u2cc2\u2cc4\u2cc6\u2cc8\u2cca\u2ccc\u2cce\u2cd0\u2cd2\u2cd4\u2cd6\u2cd8\u2cda\u2cdc\u2cde\u2ce0\u2ce2\uff21\uff22\uff23\uff24\uff25\uff26\uff27\uff28\uff29\uff2a\uff2b\uff2c\uff2d\uff2e\uff2f\uff30\uff31\uff32\uff33\uff34\uff35\uff36\uff37\uff38\uff39\uff3a'
-
-Mc = u'\u0903\u093e\u093f\u0940\u0949\u094a\u094b\u094c\u0982\u0983\u09be\u09bf\u09c0\u09c7\u09c8\u09cb\u09cc\u09d7\u0a03\u0a3e\u0a3f\u0a40\u0a83\u0abe\u0abf\u0ac0\u0ac9\u0acb\u0acc\u0b02\u0b03\u0b3e\u0b40\u0b47\u0b48\u0b4b\u0b4c\u0b57\u0bbe\u0bbf\u0bc1\u0bc2\u0bc6\u0bc7\u0bc8\u0bca\u0bcb\u0bcc\u0bd7\u0c01\u0c02\u0c03\u0c41\u0c42\u0c43\u0c44\u0c82\u0c83\u0cbe\u0cc0\u0cc1\u0cc2\u0cc3\u0cc4\u0cc7\u0cc8\u0cca\u0ccb\u0cd5\u0cd6\u0d02\u0d03\u0d3e\u0d3f\u0d40\u0d46\u0d47\u0d48\u0d4a\u0d4b\u0d4c\u0d57\u0d82\u0d83\u0dcf\u0dd0\u0dd1\u0dd8\u0dd9\u0dda\u0ddb\u0ddc\u0ddd\u0dde\u0ddf\u0df2\u0df3\u0f3e\u0f3f\u0f7f\u102c\u1031\u1038\u1056\u1057\u17b6\u17be\u17bf\u17c0\u17c1\u17c2\u17c3\u17c4\u17c5\u17c7\u17c8\u1923\u1924\u1925\u1926\u1929\u192a\u192b\u1930\u1931\u1933\u1934\u1935\u1936\u1937\u1938\u19b0\u19b1\u19b2\u19b3\u19b4\u19b5\u19b6\u19b7\u19b8\u19b9\u19ba\u19bb\u19bc\u19bd\u19be\u19bf\u19c0\u19c8\u19c9\u1a19\u1a1a\u1a1b\ua802\ua823\ua824\ua827'
-
-Me = u'\u0488\u0489\u06de\u20dd\u20de\u20df\u20e0\u20e2\u20e3\u20e4'
-
-Mn = u'\u0300\u0301\u0302\u0303\u0304\u0305\u0306\u0307\u0308\u0309\u030a\u030b\u030c\u030d\u030e\u030f\u0310\u0311\u0312\u0313\u0314\u0315\u0316\u0317\u0318\u0319\u031a\u031b\u031c\u031d\u031e\u031f\u0320\u0321\u0322\u0323\u0324\u0325\u0326\u0327\u0328\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u0330\u0331\u0332\u0333\u0334\u0335\u0336\u0337\u0338\u0339\u033a\u033b\u033c\u033d\u033e\u033f\u0340\u0341\u0342\u0343\u0344\u0345\u0346\u0347\u0348\u0349\u034a\u034b\u034c\u034d\u034e\u034f\u0350\u0351\u0352\u0353\u0354\u0355\u0356\u0357\u0358\u0359\u035a\u035b\u035c\u035d\u035e\u035f\u0360\u0361\u0362\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036a\u036b\u036c\u036d\u036e\u036f\u0483\u0484\u0485\u0486\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059a\u059b\u059c\u059d\u059e\u059f\u05a0\u05a1\u05a2\u05a3\u05a4\u05a5\u05a6\u05a7\u05a8\u05a9\u05aa\u05ab\u05ac\u05ad\u05ae\u05af\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9\u05bb\u05bc\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610\u0611\u0612\u0613\u0614\u0615\u064b\u064c\u064d\u064e\u064f\u0650\u0651\u0652\u0653\u0654\u0655\u0656\u0657\u0658\u0659\u065a\u065b\u065c\u065d\u065e\u0670\u06d6\u06d7\u06d8\u06d9\u06da\u06db\u06dc\u06df\u06e0\u06e1\u06e2\u06e3\u06e4\u06e7\u06e8\u06ea\u06eb\u06ec\u06ed\u0711\u0730\u0731\u0732\u0733\u0734\u0735\u0736\u0737\u0738\u0739\u073a\u073b\u073c\u073d\u073e\u073f\u0740\u0741\u0742\u0743\u0744\u0745\u0746\u0747\u0748\u0749\u074a\u07a6\u07a7\u07a8\u07a9\u07aa\u07ab\u07ac\u07ad\u07ae\u07af\u07b0\u0901\u0902\u093c\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u094d\u0951\u0952\u0953\u0954\u0962\u0963\u0981\u09bc\u09c1\u09c2\u09c3\u09c4\u09cd\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b\u0a4c\u0a4d\u0a70\u0a71\u0a81\u0a82\u0abc\u0ac1\u0ac2\u0ac3\u0ac4\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3f\u0b41\u0b42\u0b43\u0b4d\u0b56\u0b82\u0bc0\u0bcd\u0c3e\u0c3f\u0c40\u0c46\u0c47\u0c48\u0c4a\u0c4b\u0c4c\u0c4d\u0c55\u0c56\u0cbc\u0cbf\u0cc6\u0ccc\u0ccd\u0d41\u0d42\u0d43\u0d4d\u0dca\u0dd2\u0dd3\u0dd4\u0dd6\u0e31\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0eb1\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\u0ebb\u0ebc\u0ec8\u0ec9\u0eca\u0ecb\u0ecc\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71\u0f72\u0f73\u0f74\u0f75\u0f76\u0f77\u0f78\u0f79\u0f7a\u0f7b\u0f7c\u0f7d\u0f7e\u0f80\u0f81\u0f82\u0f83\u0f84\u0f86\u0f87\u0f90\u0f91\u0f92\u0f93\u0f94\u0f95\u0f96\u0f97\u0f99\u0f9a\u0f9b\u0f9c\u0f9d\u0f9e\u0f9f\u0fa0\u0fa1\u0fa2\u0fa3\u0fa4\u0fa5\u0fa6\u0fa7\u0fa8\u0fa9\u0faa\u0fab\u0fac\u0fad\u0fae\u0faf\u0fb0\u0fb1\u0fb2\u0fb3\u0fb4\u0fb5\u0fb6\u0fb7\u0fb8\u0fb9\u0fba\u0fbb\u0fbc\u0fc6\u102d\u102e\u102f\u1030\u1032\u1036\u1037\u1039\u1058\u1059\u135f\u1712\u1713\u1714\u1732\u1733\u1734\u1752\u1753\u1772\u1773\u17b7\u17b8\u17b9\u17ba\u17bb\u17bc\u17bd\u17c6\u17c9\u17ca\u17cb\u17cc\u17cd\u17ce\u17cf\u17d0\u17d1\u17d2\u17d3\u17dd\u180b\u180c\u180d\u18a9\u1920\u1921\u1922\u1927\u1928\u1932\u1939\u193a\u193b\u1a17\u1a18\u1dc0\u1dc1\u1dc2\u1dc3\u20d0\u20d1\u20d2\u20d3\u20d4\u20d5\u20d6\u20d7\u20d8\u20d9\u20da\u20db\u20dc\u20e1\u20e5\u20e6\u20e7\u20e8\u20e9\u20ea\u20eb\u302a\u302b\u302c\u302d\u302e\u302f\u3099\u309a\ua806\ua80b\ua825\ua826\ufb1e\ufe00\ufe01\ufe02\ufe03\ufe04\ufe05\ufe06\ufe07\ufe08\ufe09\ufe0a\ufe0b\ufe0c\ufe0d\ufe0e\ufe0f\ufe20\ufe21\ufe22\ufe23'
-
-Nd = u'0123456789\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u0a66\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0b66\u0b67\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0be6\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0c66\u0c67\u0c68\u0c69\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0d66\u0d67\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\u0f20\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u17e0\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u1946\u1947\u1948\u1949\u194a\u194b\u194c\u194d\u194e\u194f\u19d0\u19d1\u19d2\u19d3\u19d4\u19d5\u19d6\u19d7\u19d8\u19d9\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19'
-
-Nl = u'\u16ee\u16ef\u16f0\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216a\u216b\u216c\u216d\u216e\u216f\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217a\u217b\u217c\u217d\u217e\u217f\u2180\u2181\u2182\u2183\u3007\u3021\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029\u3038\u3039\u303a'
-
-No = u'\xb2\xb3\xb9\xbc\xbd\xbe\u09f4\u09f5\u09f6\u09f7\u09f8\u09f9\u0bf0\u0bf1\u0bf2\u0f2a\u0f2b\u0f2c\u0f2d\u0f2e\u0f2f\u0f30\u0f31\u0f32\u0f33\u1369\u136a\u136b\u136c\u136d\u136e\u136f\u1370\u1371\u1372\u1373\u1374\u1375\u1376\u1377\u1378\u1379\u137a\u137b\u137c\u17f0\u17f1\u17f2\u17f3\u17f4\u17f5\u17f6\u17f7\u17f8\u17f9\u2070\u2074\u2075\u2076\u2077\u2078\u2079\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215a\u215b\u215c\u215d\u215e\u215f\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2469\u246a\u246b\u246c\u246d\u246e\u246f\u2470\u2471\u2472\u2473\u2474\u2475\u2476\u2477\u2478\u2479\u247a\u247b\u247c\u247d\u247e\u247f\u2480\u2481\u2482\u2483\u2484\u2485\u2486\u2487\u2488\u2489\u248a\u248b\u248c\u248d\u248e\u248f\u2490\u2491\u2492\u2493\u2494\u2495\u2496\u2497\u2498\u2499\u249a\u249b\u24ea\u24eb\u24ec\u24ed\u24ee\u24ef\u24f0\u24f1\u24f2\u24f3\u24f4\u24f5\u24f6\u24f7\u24f8\u24f9\u24fa\u24fb\u24fc\u24fd\u24fe\u24ff\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e\u277f\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u2789\u278a\u278b\u278c\u278d\u278e\u278f\u2790\u2791\u2792\u2793\u2cfd\u3192\u3193\u3194\u3195\u3220\u3221\u3222\u3223\u3224\u3225\u3226\u3227\u3228\u3229\u3251\u3252\u3253\u3254\u3255\u3256\u3257\u3258\u3259\u325a\u325b\u325c\u325d\u325e\u325f\u3280\u3281\u3282\u3283\u3284\u3285\u3286\u3287\u3288\u3289\u32b1\u32b2\u32b3\u32b4\u32b5\u32b6\u32b7\u32b8\u32b9\u32ba\u32bb\u32bc\u32bd\u32be\u32bf'
-
-Pc = u'_\u203f\u2040\u2054\ufe33\ufe34\ufe4d\ufe4e\ufe4f\uff3f'
-
-Pd = u'-\u058a\u1806\u2010\u2011\u2012\u2013\u2014\u2015\u2e17\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d'
-
-Pe = u')]}\u0f3b\u0f3d\u169c\u2046\u207e\u208e\u232a\u23b5\u2769\u276b\u276d\u276f\u2771\u2773\u2775\u27c6\u27e7\u27e9\u27eb\u2984\u2986\u2988\u298a\u298c\u298e\u2990\u2992\u2994\u2996\u2998\u29d9\u29db\u29fd\u3009\u300b\u300d\u300f\u3011\u3015\u3017\u3019\u301b\u301e\u301f\ufd3f\ufe18\ufe36\ufe38\ufe3a\ufe3c\ufe3e\ufe40\ufe42\ufe44\ufe48\ufe5a\ufe5c\ufe5e\uff09\uff3d\uff5d\uff60\uff63'
-
-Pf = u'\xbb\u2019\u201d\u203a\u2e03\u2e05\u2e0a\u2e0d\u2e1d'
-
-Pi = u'\xab\u2018\u201b\u201c\u201f\u2039\u2e02\u2e04\u2e09\u2e0c\u2e1c'
-
-Po = u'!"#%&\'*,./:;?@\\\xa1\xb7\xbf\u037e\u0387\u055a\u055b\u055c\u055d\u055e\u055f\u0589\u05be\u05c0\u05c3\u05c6\u05f3\u05f4\u060c\u060d\u061b\u061e\u061f\u066a\u066b\u066c\u066d\u06d4\u0700\u0701\u0702\u0703\u0704\u0705\u0706\u0707\u0708\u0709\u070a\u070b\u070c\u070d\u0964\u0965\u0970\u0df4\u0e4f\u0e5a\u0e5b\u0f04\u0f05\u0f06\u0f07\u0f08\u0f09\u0f0a\u0f0b\u0f0c\u0f0d\u0f0e\u0f0f\u0f10\u0f11\u0f12\u0f85\u0fd0\u0fd1\u104a\u104b\u104c\u104d\u104e\u104f\u10fb\u1361\u1362\u1363\u1364\u1365\u1366\u1367\u1368\u166d\u166e\u16eb\u16ec\u16ed\u1735\u1736\u17d4\u17d5\u17d6\u17d8\u17d9\u17da\u1800\u1801\u1802\u1803\u1804\u1805\u1807\u1808\u1809\u180a\u1944\u1945\u19de\u19df\u1a1e\u1a1f\u2016\u2017\u2020\u2021\u2022\u2023\u2024\u2025\u2026\u2027\u2030\u2031\u2032\u2033\u2034\u2035\u2036\u2037\u2038\u203b\u203c\u203d\u203e\u2041\u2042\u2043\u2047\u2048\u2049\u204a\u204b\u204c\u204d\u204e\u204f\u2050\u2051\u2053\u2055\u2056\u2057\u2058\u2059\u205a\u205b\u205c\u205d\u205e\u23b6\u2cf9\u2cfa\u2cfb\u2cfc\u2cfe\u2cff\u2e00\u2e01\u2e06\u2e07\u2e08\u2e0b\u2e0e\u2e0f\u2e10\u2e11\u2e12\u2e13\u2e14\u2e15\u2e16\u3001\u3002\u3003\u303d\u30fb\ufe10\ufe11\ufe12\ufe13\ufe14\ufe15\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49\ufe4a\ufe4b\ufe4c\ufe50\ufe51\ufe52\ufe54\ufe55\ufe56\ufe57\ufe5f\ufe60\ufe61\ufe68\ufe6a\ufe6b\uff01\uff02\uff03\uff05\uff06\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65'
-
-Ps = u'([{\u0f3a\u0f3c\u169b\u201a\u201e\u2045\u207d\u208d\u2329\u23b4\u2768\u276a\u276c\u276e\u2770\u2772\u2774\u27c5\u27e6\u27e8\u27ea\u2983\u2985\u2987\u2989\u298b\u298d\u298f\u2991\u2993\u2995\u2997\u29d8\u29da\u29fc\u3008\u300a\u300c\u300e\u3010\u3014\u3016\u3018\u301a\u301d\ufd3e\ufe17\ufe35\ufe37\ufe39\ufe3b\ufe3d\ufe3f\ufe41\ufe43\ufe47\ufe59\ufe5b\ufe5d\uff08\uff3b\uff5b\uff5f\uff62'
-
-Sc = u'$\xa2\xa3\xa4\xa5\u060b\u09f2\u09f3\u0af1\u0bf9\u0e3f\u17db\u20a0\u20a1\u20a2\u20a3\u20a4\u20a5\u20a6\u20a7\u20a8\u20a9\u20aa\u20ab\u20ac\u20ad\u20ae\u20af\u20b0\u20b1\u20b2\u20b3\u20b4\u20b5\ufdfc\ufe69\uff04\uffe0\uffe1\uffe5\uffe6'
-
-Sk = u'^`\xa8\xaf\xb4\xb8\u02c2\u02c3\u02c4\u02c5\u02d2\u02d3\u02d4\u02d5\u02d6\u02d7\u02d8\u02d9\u02da\u02db\u02dc\u02dd\u02de\u02df\u02e5\u02e6\u02e7\u02e8\u02e9\u02ea\u02eb\u02ec\u02ed\u02ef\u02f0\u02f1\u02f2\u02f3\u02f4\u02f5\u02f6\u02f7\u02f8\u02f9\u02fa\u02fb\u02fc\u02fd\u02fe\u02ff\u0374\u0375\u0384\u0385\u1fbd\u1fbf\u1fc0\u1fc1\u1fcd\u1fce\u1fcf\u1fdd\u1fde\u1fdf\u1fed\u1fee\u1fef\u1ffd\u1ffe\u309b\u309c\ua700\ua701\ua702\ua703\ua704\ua705\ua706\ua707\ua708\ua709\ua70a\ua70b\ua70c\ua70d\ua70e\ua70f\ua710\ua711\ua712\ua713\ua714\ua715\ua716\uff3e\uff40\uffe3'
-
-Sm = u'+<=>|~\xac\xb1\xd7\xf7\u03f6\u2044\u2052\u207a\u207b\u207c\u208a\u208b\u208c\u2140\u2141\u2142\u2143\u2144\u214b\u2190\u2191\u2192\u2193\u2194\u219a\u219b\u21a0\u21a3\u21a6\u21ae\u21ce\u21cf\u21d2\u21d4\u21f4\u21f5\u21f6\u21f7\u21f8\u21f9\u21fa\u21fb\u21fc\u21fd\u21fe\u21ff\u2200\u2201\u2202\u2203\u2204\u2205\u2206\u2207\u2208\u2209\u220a\u220b\u220c\u220d\u220e\u220f\u2210\u2211\u2212\u2213\u2214\u2215\u2216\u2217\u2218\u2219\u221a\u221b\u221c\u221d\u221e\u221f\u2220\u2221\u2222\u2223\u2224\u2225\u2226\u2227\u2228\u2229\u222a\u222b\u222c\u222d\u222e\u222f\u2230\u2231\u2232\u2233\u2234\u2235\u2236\u2237\u2238\u2239\u223a\u223b\u223c\u223d\u223e\u223f\u2240\u2241\u2242\u2243\u2244\u2245\u2246\u2247\u2248\u2249\u224a\u224b\u224c\u224d\u224e\u224f\u2250\u2251\u2252\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225a\u225b\u225c\u225d\u225e\u225f\u2260\u2261\u2262\u2263\u2264\u2265\u2266\u2267\u2268\u2269\u226a\u226b\u226c\u226d\u226e\u226f\u2270\u2271\u2272\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227a\u227b\u227c\u227d\u227e\u227f\u2280\u2281\u2282\u2283\u2284\u2285\u2286\u2287\u2288\u2289\u228a\u228b\u228c\u228d\u228e\u228f\u2290\u2291\u2292\u2293\u2294\u2295\u2296\u2297\u2298\u2299\u229a\u229b\u229c\u229d\u229e\u229f\u22a0\u22a1\u22a2\u22a3\u22a4\u22a5\u22a6\u22a7\u22a8\u22a9\u22aa\u22ab\u22ac\u22ad\u22ae\u22af\u22b0\u22b1\u22b2\u22b3\u22b4\u22b5\u22b6\u22b7\u22b8\u22b9\u22ba\u22bb\u22bc\u22bd\u22be\u22bf\u22c0\u22c1\u22c2\u22c3\u22c4\u22c5\u22c6\u22c7\u22c8\u22c9\u22ca\u22cb\u22cc\u22cd\u22ce\u22cf\u22d0\u22d1\u22d2\u22d3\u22d4\u22d5\u22d6\u22d7\u22d8\u22d9\u22da\u22db\u22dc\u22dd\u22de\u22df\u22e0\u22e1\u22e2\u22e3\u22e4\u22e5\u22e6\u22e7\u22e8\u22e9\u22ea\u22eb\u22ec\u22ed\u22ee\u22ef\u22f0\u22f1\u22f2\u22f3\u22f4\u22f5\u22f6\u22f7\u22f8\u22f9\u22fa\u22fb\u22fc\u22fd\u22fe\u22ff\u2308\u2309\u230a\u230b\u2320\u2321\u237c\u239b\u239c\u239d\u239e\u239f\u23a0\u23a1\u23a2\u23a3\u23a4\u23a5\u23a6\u23a7\u23a8\u23a9\u23aa\u23ab\u23ac\u23ad\u23ae\u23af\u23b0\u23b1\u23b2\u23b3\u25b7\u25c1\u25f8\u25f9\u25fa\u25fb\u25fc\u25fd\u25fe\u25ff\u266f\u27c0\u27c1\u27c2\u27c3\u27c4\u27d0\u27d1\u27d2\u27d3\u27d4\u27d5\u27d6\u27d7\u27d8\u27d9\u27da\u27db\u27dc\u27dd\u27de\u27df\u27e0\u27e1\u27e2\u27e3\u27e4\u27e5\u27f0\u27f1\u27f2\u27f3\u27f4\u27f5\u27f6\u27f7\u27f8\u27f9\u27fa\u27fb\u27fc\u27fd\u27fe\u27ff\u2900\u2901\u2902\u2903\u2904\u2905\u2906\u2907\u2908\u2909\u290a\u290b\u290c\u290d\u290e\u290f\u2910\u2911\u2912\u2913\u2914\u2915\u2916\u2917\u2918\u2919\u291a\u291b\u291c\u291d\u291e\u291f\u2920\u2921\u2922\u2923\u2924\u2925\u2926\u2927\u2928\u2929\u292a\u292b\u292c\u292d\u292e\u292f\u2930\u2931\u2932\u2933\u2934\u2935\u2936\u2937\u2938\u2939\u293a\u293b\u293c\u293d\u293e\u293f\u2940\u2941\u2942\u2943\u2944\u2945\u2946\u2947\u2948\u2949\u294a\u294b\u294c\u294d\u294e\u294f\u2950\u2951\u2952\u2953\u2954\u2955\u2956\u2957\u2958\u2959\u295a\u295b\u295c\u295d\u295e\u295f\u2960\u2961\u2962\u2963\u2964\u2965\u2966\u2967\u2968\u2969\u296a\u296b\u296c\u296d\u296e\u296f\u2970\u2971\u2972\u2973\u2974\u2975\u2976\u2977\u2978\u2979\u297a\u297b\u297c\u297d\u297e\u297f\u2980\u2981\u2982\u2999\u299a\u299b\u299c\u299d\u299e\u299f\u29a0\u29a1\u29a2\u29a3\u29a4\u29a5\u29a6\u29a7\u29a8\u29a9\u29aa\u29ab\u29ac\u29ad\u29ae\u29af\u29b0\u29b1\u29b2\u29b3\u29b4\u29b5\u29b6\u29b7\u29b8\u29b9\u29ba\u29bb\u29bc\u29bd\u29be\u29bf\u29c0\u29c1\u29c2\u29c3\u29c4\u29c5\u29c6\u29c7\u29c8\u29c9\u29ca\u29cb\u29cc\u29cd\u29ce\u29cf\u29d0\u29d1\u29d2\u29d3\u29d4\u29d5\u29d6\u29d7\u29dc\u29dd\u29de\u29df\u29e0\u29e1\u29e2\u29e3\u29e4\u29e5\u29e6\u29e7\u29e8\u29e9\u29ea\u29eb\u29ec\u29ed\u29ee\u29ef\u29f0\u29f1\u29f2\u29f3\u29f4\u29f5\u29f6\u29f7\u29f8\u29f9\u29fa\u29fb\u29fe\u29ff\u2a00\u2a01\u2a02\u2a03\u2a04\u2a05\u2a06\u2a07\u2a08\u2a09\u2a0a\u2a0b\u2a0c\u2a0d\u2a0e\u2a0f\u2a10\u2a11\u2a12\u2a13\u2a14\u2a15\u2a16\u2a17\u2a18\u2a19\u2a1a\u2a1b\u2a1c\u2a1d\u2a1e\u2a1f\u2a20\u2a21\u2a22\u2a23\u2a24\u2a25\u2a26\u2a27\u2a28\u2a29\u2a2a\u2a2b\u2a2c\u2a2d\u2a2e\u2a2f\u2a30\u2a31\u2a32\u2a33\u2a34\u2a35\u2a36\u2a37\u2a38\u2a39\u2a3a\u2a3b\u2a3c\u2a3d\u2a3e\u2a3f\u2a40\u2a41\u2a42\u2a43\u2a44\u2a45\u2a46\u2a47\u2a48\u2a49\u2a4a\u2a4b\u2a4c\u2a4d\u2a4e\u2a4f\u2a50\u2a51\u2a52\u2a53\u2a54\u2a55\u2a56\u2a57\u2a58\u2a59\u2a5a\u2a5b\u2a5c\u2a5d\u2a5e\u2a5f\u2a60\u2a61\u2a62\u2a63\u2a64\u2a65\u2a66\u2a67\u2a68\u2a69\u2a6a\u2a6b\u2a6c\u2a6d\u2a6e\u2a6f\u2a70\u2a71\u2a72\u2a73\u2a74\u2a75\u2a76\u2a77\u2a78\u2a79\u2a7a\u2a7b\u2a7c\u2a7d\u2a7e\u2a7f\u2a80\u2a81\u2a82\u2a83\u2a84\u2a85\u2a86\u2a87\u2a88\u2a89\u2a8a\u2a8b\u2a8c\u2a8d\u2a8e\u2a8f\u2a90\u2a91\u2a92\u2a93\u2a94\u2a95\u2a96\u2a97\u2a98\u2a99\u2a9a\u2a9b\u2a9c\u2a9d\u2a9e\u2a9f\u2aa0\u2aa1\u2aa2\u2aa3\u2aa4\u2aa5\u2aa6\u2aa7\u2aa8\u2aa9\u2aaa\u2aab\u2aac\u2aad\u2aae\u2aaf\u2ab0\u2ab1\u2ab2\u2ab3\u2ab4\u2ab5\u2ab6\u2ab7\u2ab8\u2ab9\u2aba\u2abb\u2abc\u2abd\u2abe\u2abf\u2ac0\u2ac1\u2ac2\u2ac3\u2ac4\u2ac5\u2ac6\u2ac7\u2ac8\u2ac9\u2aca\u2acb\u2acc\u2acd\u2ace\u2acf\u2ad0\u2ad1\u2ad2\u2ad3\u2ad4\u2ad5\u2ad6\u2ad7\u2ad8\u2ad9\u2ada\u2adb\u2adc\u2add\u2ade\u2adf\u2ae0\u2ae1\u2ae2\u2ae3\u2ae4\u2ae5\u2ae6\u2ae7\u2ae8\u2ae9\u2aea\u2aeb\u2aec\u2aed\u2aee\u2aef\u2af0\u2af1\u2af2\u2af3\u2af4\u2af5\u2af6\u2af7\u2af8\u2af9\u2afa\u2afb\u2afc\u2afd\u2afe\u2aff\ufb29\ufe62\ufe64\ufe65\ufe66\uff0b\uff1c\uff1d\uff1e\uff5c\uff5e\uffe2\uffe9\uffea\uffeb\uffec'
-
-So = u'\xa6\xa7\xa9\xae\xb0\xb6\u0482\u060e\u060f\u06e9\u06fd\u06fe\u09fa\u0b70\u0bf3\u0bf4\u0bf5\u0bf6\u0bf7\u0bf8\u0bfa\u0f01\u0f02\u0f03\u0f13\u0f14\u0f15\u0f16\u0f17\u0f1a\u0f1b\u0f1c\u0f1d\u0f1e\u0f1f\u0f34\u0f36\u0f38\u0fbe\u0fbf\u0fc0\u0fc1\u0fc2\u0fc3\u0fc4\u0fc5\u0fc7\u0fc8\u0fc9\u0fca\u0fcb\u0fcc\u0fcf\u1360\u1390\u1391\u1392\u1393\u1394\u1395\u1396\u1397\u1398\u1399\u1940\u19e0\u19e1\u19e2\u19e3\u19e4\u19e5\u19e6\u19e7\u19e8\u19e9\u19ea\u19eb\u19ec\u19ed\u19ee\u19ef\u19f0\u19f1\u19f2\u19f3\u19f4\u19f5\u19f6\u19f7\u19f8\u19f9\u19fa\u19fb\u19fc\u19fd\u19fe\u19ff\u2100\u2101\u2103\u2104\u2105\u2106\u2108\u2109\u2114\u2116\u2117\u2118\u211e\u211f\u2120\u2121\u2122\u2123\u2125\u2127\u2129\u212e\u2132\u213a\u213b\u214a\u214c\u2195\u2196\u2197\u2198\u2199\u219c\u219d\u219e\u219f\u21a1\u21a2\u21a4\u21a5\u21a7\u21a8\u21a9\u21aa\u21ab\u21ac\u21ad\u21af\u21b0\u21b1\u21b2\u21b3\u21b4\u21b5\u21b6\u21b7\u21b8\u21b9\u21ba\u21bb\u21bc\u21bd\u21be\u21bf\u21c0\u21c1\u21c2\u21c3\u21c4\u21c5\u21c6\u21c7\u21c8\u21c9\u21ca\u21cb\u21cc\u21cd\u21d0\u21d1\u21d3\u21d5\u21d6\u21d7\u21d8\u21d9\u21da\u21db\u21dc\u21dd\u21de\u21df\u21e0\u21e1\u21e2\u21e3\u21e4\u21e5\u21e6\u21e7\u21e8\u21e9\u21ea\u21eb\u21ec\u21ed\u21ee\u21ef\u21f0\u21f1\u21f2\u21f3\u2300\u2301\u2302\u2303\u2304\u2305\u2306\u2307\u230c\u230d\u230e\u230f\u2310\u2311\u2312\u2313\u2314\u2315\u2316\u2317\u2318\u2319\u231a\u231b\u231c\u231d\u231e\u231f\u2322\u2323\u2324\u2325\u2326\u2327\u2328\u232b\u232c\u232d\u232e\u232f\u2330\u2331\u2332\u2333\u2334\u2335\u2336\u2337\u2338\u2339\u233a\u233b\u233c\u233d\u233e\u233f\u2340\u2341\u2342\u2343\u2344\u2345\u2346\u2347\u2348\u2349\u234a\u234b\u234c\u234d\u234e\u234f\u2350\u2351\u2352\u2353\u2354\u2355\u2356\u2357\u2358\u2359\u235a\u235b\u235c\u235d\u235e\u235f\u2360\u2361\u2362\u2363\u2364\u2365\u2366\u2367\u2368\u2369\u236a\u236b\u236c\u236d\u236e\u236f\u2370\u2371\u2372\u2373\u2374\u2375\u2376\u2377\u2378\u2379\u237a\u237b\u237d\u237e\u237f\u2380\u2381\u2382\u2383\u2384\u2385\u2386\u2387\u2388\u2389\u238a\u238b\u238c\u238d\u238e\u238f\u2390\u2391\u2392\u2393\u2394\u2395\u2396\u2397\u2398\u2399\u239a\u23b7\u23b8\u23b9\u23ba\u23bb\u23bc\u23bd\u23be\u23bf\u23c0\u23c1\u23c2\u23c3\u23c4\u23c5\u23c6\u23c7\u23c8\u23c9\u23ca\u23cb\u23cc\u23cd\u23ce\u23cf\u23d0\u23d1\u23d2\u23d3\u23d4\u23d5\u23d6\u23d7\u23d8\u23d9\u23da\u23db\u2400\u2401\u2402\u2403\u2404\u2405\u2406\u2407\u2408\u2409\u240a\u240b\u240c\u240d\u240e\u240f\u2410\u2411\u2412\u2413\u2414\u2415\u2416\u2417\u2418\u2419\u241a\u241b\u241c\u241d\u241e\u241f\u2420\u2421\u2422\u2423\u2424\u2425\u2426\u2440\u2441\u2442\u2443\u2444\u2445\u2446\u2447\u2448\u2449\u244a\u249c\u249d\u249e\u249f\u24a0\u24a1\u24a2\u24a3\u24a4\u24a5\u24a6\u24a7\u24a8\u24a9\u24aa\u24ab\u24ac\u24ad\u24ae\u24af\u24b0\u24b1\u24b2\u24b3\u24b4\u24b5\u24b6\u24b7\u24b8\u24b9\u24ba\u24bb\u24bc\u24bd\u24be\u24bf\u24c0\u24c1\u24c2\u24c3\u24c4\u24c5\u24c6\u24c7\u24c8\u24c9\u24ca\u24cb\u24cc\u24cd\u24ce\u24cf\u24d0\u24d1\u24d2\u24d3\u24d4\u24d5\u24d6\u24d7\u24d8\u24d9\u24da\u24db\u24dc\u24dd\u24de\u24df\u24e0\u24e1\u24e2\u24e3\u24e4\u24e5\u24e6\u24e7\u24e8\u24e9\u2500\u2501\u2502\u2503\u2504\u2505\u2506\u2507\u2508\u2509\u250a\u250b\u250c\u250d\u250e\u250f\u2510\u2511\u2512\u2513\u2514\u2515\u2516\u2517\u2518\u2519\u251a\u251b\u251c\u251d\u251e\u251f\u2520\u2521\u2522\u2523\u2524\u2525\u2526\u2527\u2528\u2529\u252a\u252b\u252c\u252d\u252e\u252f\u2530\u2531\u2532\u2533\u2534\u2535\u2536\u2537\u2538\u2539\u253a\u253b\u253c\u253d\u253e\u253f\u2540\u2541\u2542\u2543\u2544\u2545\u2546\u2547\u2548\u2549\u254a\u254b\u254c\u254d\u254e\u254f\u2550\u2551\u2552\u2553\u2554\u2555\u2556\u2557\u2558\u2559\u255a\u255b\u255c\u255d\u255e\u255f\u2560\u2561\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569\u256a\u256b\u256c\u256d\u256e\u256f\u2570\u2571\u2572\u2573\u2574\u2575\u2576\u2577\u2578\u2579\u257a\u257b\u257c\u257d\u257e\u257f\u2580\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588\u2589\u258a\u258b\u258c\u258d\u258e\u258f\u2590\u2591\u2592\u2593\u2594\u2595\u2596\u2597\u2598\u2599\u259a\u259b\u259c\u259d\u259e\u259f\u25a0\u25a1\u25a2\u25a3\u25a4\u25a5\u25a6\u25a7\u25a8\u25a9\u25aa\u25ab\u25ac\u25ad\u25ae\u25af\u25b0\u25b1\u25b2\u25b3\u25b4\u25b5\u25b6\u25b8\u25b9\u25ba\u25bb\u25bc\u25bd\u25be\u25bf\u25c0\u25c2\u25c3\u25c4\u25c5\u25c6\u25c7\u25c8\u25c9\u25ca\u25cb\u25cc\u25cd\u25ce\u25cf\u25d0\u25d1\u25d2\u25d3\u25d4\u25d5\u25d6\u25d7\u25d8\u25d9\u25da\u25db\u25dc\u25dd\u25de\u25df\u25e0\u25e1\u25e2\u25e3\u25e4\u25e5\u25e6\u25e7\u25e8\u25e9\u25ea\u25eb\u25ec\u25ed\u25ee\u25ef\u25f0\u25f1\u25f2\u25f3\u25f4\u25f5\u25f6\u25f7\u2600\u2601\u2602\u2603\u2604\u2605\u2606\u2607\u2608\u2609\u260a\u260b\u260c\u260d\u260e\u260f\u2610\u2611\u2612\u2613\u2614\u2615\u2616\u2617\u2618\u2619\u261a\u261b\u261c\u261d\u261e\u261f\u2620\u2621\u2622\u2623\u2624\u2625\u2626\u2627\u2628\u2629\u262a\u262b\u262c\u262d\u262e\u262f\u2630\u2631\u2632\u2633\u2634\u2635\u2636\u2637\u2638\u2639\u263a\u263b\u263c\u263d\u263e\u263f\u2640\u2641\u2642\u2643\u2644\u2645\u2646\u2647\u2648\u2649\u264a\u264b\u264c\u264d\u264e\u264f\u2650\u2651\u2652\u2653\u2654\u2655\u2656\u2657\u2658\u2659\u265a\u265b\u265c\u265d\u265e\u265f\u2660\u2661\u2662\u2663\u2664\u2665\u2666\u2667\u2668\u2669\u266a\u266b\u266c\u266d\u266e\u2670\u2671\u2672\u2673\u2674\u2675\u2676\u2677\u2678\u2679\u267a\u267b\u267c\u267d\u267e\u267f\u2680\u2681\u2682\u2683\u2684\u2685\u2686\u2687\u2688\u2689\u268a\u268b\u268c\u268d\u268e\u268f\u2690\u2691\u2692\u2693\u2694\u2695\u2696\u2697\u2698\u2699\u269a\u269b\u269c\u26a0\u26a1\u26a2\u26a3\u26a4\u26a5\u26a6\u26a7\u26a8\u26a9\u26aa\u26ab\u26ac\u26ad\u26ae\u26af\u26b0\u26b1\u2701\u2702\u2703\u2704\u2706\u2707\u2708\u2709\u270c\u270d\u270e\u270f\u2710\u2711\u2712\u2713\u2714\u2715\u2716\u2717\u2718\u2719\u271a\u271b\u271c\u271d\u271e\u271f\u2720\u2721\u2722\u2723\u2724\u2725\u2726\u2727\u2729\u272a\u272b\u272c\u272d\u272e\u272f\u2730\u2731\u2732\u2733\u2734\u2735\u2736\u2737\u2738\u2739\u273a\u273b\u273c\u273d\u273e\u273f\u2740\u2741\u2742\u2743\u2744\u2745\u2746\u2747\u2748\u2749\u274a\u274b\u274d\u274f\u2750\u2751\u2752\u2756\u2758\u2759\u275a\u275b\u275c\u275d\u275e\u2761\u2762\u2763\u2764\u2765\u2766\u2767\u2794\u2798\u2799\u279a\u279b\u279c\u279d\u279e\u279f\u27a0\u27a1\u27a2\u27a3\u27a4\u27a5\u27a6\u27a7\u27a8\u27a9\u27aa\u27ab\u27ac\u27ad\u27ae\u27af\u27b1\u27b2\u27b3\u27b4\u27b5\u27b6\u27b7\u27b8\u27b9\u27ba\u27bb\u27bc\u27bd\u27be\u2800\u2801\u2802\u2803\u2804\u2805\u2806\u2807\u2808\u2809\u280a\u280b\u280c\u280d\u280e\u280f\u2810\u2811\u2812\u2813\u2814\u2815\u2816\u2817\u2818\u2819\u281a\u281b\u281c\u281d\u281e\u281f\u2820\u2821\u2822\u2823\u2824\u2825\u2826\u2827\u2828\u2829\u282a\u282b\u282c\u282d\u282e\u282f\u2830\u2831\u2832\u2833\u2834\u2835\u2836\u2837\u2838\u2839\u283a\u283b\u283c\u283d\u283e\u283f\u2840\u2841\u2842\u2843\u2844\u2845\u2846\u2847\u2848\u2849\u284a\u284b\u284c\u284d\u284e\u284f\u2850\u2851\u2852\u2853\u2854\u2855\u2856\u2857\u2858\u2859\u285a\u285b\u285c\u285d\u285e\u285f\u2860\u2861\u2862\u2863\u2864\u2865\u2866\u2867\u2868\u2869\u286a\u286b\u286c\u286d\u286e\u286f\u2870\u2871\u2872\u2873\u2874\u2875\u2876\u2877\u2878\u2879\u287a\u287b\u287c\u287d\u287e\u287f\u2880\u2881\u2882\u2883\u2884\u2885\u2886\u2887\u2888\u2889\u288a\u288b\u288c\u288d\u288e\u288f\u2890\u2891\u2892\u2893\u2894\u2895\u2896\u2897\u2898\u2899\u289a\u289b\u289c\u289d\u289e\u289f\u28a0\u28a1\u28a2\u28a3\u28a4\u28a5\u28a6\u28a7\u28a8\u28a9\u28aa\u28ab\u28ac\u28ad\u28ae\u28af\u28b0\u28b1\u28b2\u28b3\u28b4\u28b5\u28b6\u28b7\u28b8\u28b9\u28ba\u28bb\u28bc\u28bd\u28be\u28bf\u28c0\u28c1\u28c2\u28c3\u28c4\u28c5\u28c6\u28c7\u28c8\u28c9\u28ca\u28cb\u28cc\u28cd\u28ce\u28cf\u28d0\u28d1\u28d2\u28d3\u28d4\u28d5\u28d6\u28d7\u28d8\u28d9\u28da\u28db\u28dc\u28dd\u28de\u28df\u28e0\u28e1\u28e2\u28e3\u28e4\u28e5\u28e6\u28e7\u28e8\u28e9\u28ea\u28eb\u28ec\u28ed\u28ee\u28ef\u28f0\u28f1\u28f2\u28f3\u28f4\u28f5\u28f6\u28f7\u28f8\u28f9\u28fa\u28fb\u28fc\u28fd\u28fe\u28ff\u2b00\u2b01\u2b02\u2b03\u2b04\u2b05\u2b06\u2b07\u2b08\u2b09\u2b0a\u2b0b\u2b0c\u2b0d\u2b0e\u2b0f\u2b10\u2b11\u2b12\u2b13\u2ce5\u2ce6\u2ce7\u2ce8\u2ce9\u2cea\u2e80\u2e81\u2e82\u2e83\u2e84\u2e85\u2e86\u2e87\u2e88\u2e89\u2e8a\u2e8b\u2e8c\u2e8d\u2e8e\u2e8f\u2e90\u2e91\u2e92\u2e93\u2e94\u2e95\u2e96\u2e97\u2e98\u2e99\u2e9b\u2e9c\u2e9d\u2e9e\u2e9f\u2ea0\u2ea1\u2ea2\u2ea3\u2ea4\u2ea5\u2ea6\u2ea7\u2ea8\u2ea9\u2eaa\u2eab\u2eac\u2ead\u2eae\u2eaf\u2eb0\u2eb1\u2eb2\u2eb3\u2eb4\u2eb5\u2eb6\u2eb7\u2eb8\u2eb9\u2eba\u2ebb\u2ebc\u2ebd\u2ebe\u2ebf\u2ec0\u2ec1\u2ec2\u2ec3\u2ec4\u2ec5\u2ec6\u2ec7\u2ec8\u2ec9\u2eca\u2ecb\u2ecc\u2ecd\u2ece\u2ecf\u2ed0\u2ed1\u2ed2\u2ed3\u2ed4\u2ed5\u2ed6\u2ed7\u2ed8\u2ed9\u2eda\u2edb\u2edc\u2edd\u2ede\u2edf\u2ee0\u2ee1\u2ee2\u2ee3\u2ee4\u2ee5\u2ee6\u2ee7\u2ee8\u2ee9\u2eea\u2eeb\u2eec\u2eed\u2eee\u2eef\u2ef0\u2ef1\u2ef2\u2ef3\u2f00\u2f01\u2f02\u2f03\u2f04\u2f05\u2f06\u2f07\u2f08\u2f09\u2f0a\u2f0b\u2f0c\u2f0d\u2f0e\u2f0f\u2f10\u2f11\u2f12\u2f13\u2f14\u2f15\u2f16\u2f17\u2f18\u2f19\u2f1a\u2f1b\u2f1c\u2f1d\u2f1e\u2f1f\u2f20\u2f21\u2f22\u2f23\u2f24\u2f25\u2f26\u2f27\u2f28\u2f29\u2f2a\u2f2b\u2f2c\u2f2d\u2f2e\u2f2f\u2f30\u2f31\u2f32\u2f33\u2f34\u2f35\u2f36\u2f37\u2f38\u2f39\u2f3a\u2f3b\u2f3c\u2f3d\u2f3e\u2f3f\u2f40\u2f41\u2f42\u2f43\u2f44\u2f45\u2f46\u2f47\u2f48\u2f49\u2f4a\u2f4b\u2f4c\u2f4d\u2f4e\u2f4f\u2f50\u2f51\u2f52\u2f53\u2f54\u2f55\u2f56\u2f57\u2f58\u2f59\u2f5a\u2f5b\u2f5c\u2f5d\u2f5e\u2f5f\u2f60\u2f61\u2f62\u2f63\u2f64\u2f65\u2f66\u2f67\u2f68\u2f69\u2f6a\u2f6b\u2f6c\u2f6d\u2f6e\u2f6f\u2f70\u2f71\u2f72\u2f73\u2f74\u2f75\u2f76\u2f77\u2f78\u2f79\u2f7a\u2f7b\u2f7c\u2f7d\u2f7e\u2f7f\u2f80\u2f81\u2f82\u2f83\u2f84\u2f85\u2f86\u2f87\u2f88\u2f89\u2f8a\u2f8b\u2f8c\u2f8d\u2f8e\u2f8f\u2f90\u2f91\u2f92\u2f93\u2f94\u2f95\u2f96\u2f97\u2f98\u2f99\u2f9a\u2f9b\u2f9c\u2f9d\u2f9e\u2f9f\u2fa0\u2fa1\u2fa2\u2fa3\u2fa4\u2fa5\u2fa6\u2fa7\u2fa8\u2fa9\u2faa\u2fab\u2fac\u2fad\u2fae\u2faf\u2fb0\u2fb1\u2fb2\u2fb3\u2fb4\u2fb5\u2fb6\u2fb7\u2fb8\u2fb9\u2fba\u2fbb\u2fbc\u2fbd\u2fbe\u2fbf\u2fc0\u2fc1\u2fc2\u2fc3\u2fc4\u2fc5\u2fc6\u2fc7\u2fc8\u2fc9\u2fca\u2fcb\u2fcc\u2fcd\u2fce\u2fcf\u2fd0\u2fd1\u2fd2\u2fd3\u2fd4\u2fd5\u2ff0\u2ff1\u2ff2\u2ff3\u2ff4\u2ff5\u2ff6\u2ff7\u2ff8\u2ff9\u2ffa\u2ffb\u3004\u3012\u3013\u3020\u3036\u3037\u303e\u303f\u3190\u3191\u3196\u3197\u3198\u3199\u319a\u319b\u319c\u319d\u319e\u319f\u31c0\u31c1\u31c2\u31c3\u31c4\u31c5\u31c6\u31c7\u31c8\u31c9\u31ca\u31cb\u31cc\u31cd\u31ce\u31cf\u3200\u3201\u3202\u3203\u3204\u3205\u3206\u3207\u3208\u3209\u320a\u320b\u320c\u320d\u320e\u320f\u3210\u3211\u3212\u3213\u3214\u3215\u3216\u3217\u3218\u3219\u321a\u321b\u321c\u321d\u321e\u322a\u322b\u322c\u322d\u322e\u322f\u3230\u3231\u3232\u3233\u3234\u3235\u3236\u3237\u3238\u3239\u323a\u323b\u323c\u323d\u323e\u323f\u3240\u3241\u3242\u3243\u3250\u3260\u3261\u3262\u3263\u3264\u3265\u3266\u3267\u3268\u3269\u326a\u326b\u326c\u326d\u326e\u326f\u3270\u3271\u3272\u3273\u3274\u3275\u3276\u3277\u3278\u3279\u327a\u327b\u327c\u327d\u327e\u327f\u328a\u328b\u328c\u328d\u328e\u328f\u3290\u3291\u3292\u3293\u3294\u3295\u3296\u3297\u3298\u3299\u329a\u329b\u329c\u329d\u329e\u329f\u32a0\u32a1\u32a2\u32a3\u32a4\u32a5\u32a6\u32a7\u32a8\u32a9\u32aa\u32ab\u32ac\u32ad\u32ae\u32af\u32b0\u32c0\u32c1\u32c2\u32c3\u32c4\u32c5\u32c6\u32c7\u32c8\u32c9\u32ca\u32cb\u32cc\u32cd\u32ce\u32cf\u32d0\u32d1\u32d2\u32d3\u32d4\u32d5\u32d6\u32d7\u32d8\u32d9\u32da\u32db\u32dc\u32dd\u32de\u32df\u32e0\u32e1\u32e2\u32e3\u32e4\u32e5\u32e6\u32e7\u32e8\u32e9\u32ea\u32eb\u32ec\u32ed\u32ee\u32ef\u32f0\u32f1\u32f2\u32f3\u32f4\u32f5\u32f6\u32f7\u32f8\u32f9\u32fa\u32fb\u32fc\u32fd\u32fe\u3300\u3301\u3302\u3303\u3304\u3305\u3306\u3307\u3308\u3309\u330a\u330b\u330c\u330d\u330e\u330f\u3310\u3311\u3312\u3313\u3314\u3315\u3316\u3317\u3318\u3319\u331a\u331b\u331c\u331d\u331e\u331f\u3320\u3321\u3322\u3323\u3324\u3325\u3326\u3327\u3328\u3329\u332a\u332b\u332c\u332d\u332e\u332f\u3330\u3331\u3332\u3333\u3334\u3335\u3336\u3337\u3338\u3339\u333a\u333b\u333c\u333d\u333e\u333f\u3340\u3341\u3342\u3343\u3344\u3345\u3346\u3347\u3348\u3349\u334a\u334b\u334c\u334d\u334e\u334f\u3350\u3351\u3352\u3353\u3354\u3355\u3356\u3357\u3358\u3359\u335a\u335b\u335c\u335d\u335e\u335f\u3360\u3361\u3362\u3363\u3364\u3365\u3366\u3367\u3368\u3369\u336a\u336b\u336c\u336d\u336e\u336f\u3370\u3371\u3372\u3373\u3374\u3375\u3376\u3377\u3378\u3379\u337a\u337b\u337c\u337d\u337e\u337f\u3380\u3381\u3382\u3383\u3384\u3385\u3386\u3387\u3388\u3389\u338a\u338b\u338c\u338d\u338e\u338f\u3390\u3391\u3392\u3393\u3394\u3395\u3396\u3397\u3398\u3399\u339a\u339b\u339c\u339d\u339e\u339f\u33a0\u33a1\u33a2\u33a3\u33a4\u33a5\u33a6\u33a7\u33a8\u33a9\u33aa\u33ab\u33ac\u33ad\u33ae\u33af\u33b0\u33b1\u33b2\u33b3\u33b4\u33b5\u33b6\u33b7\u33b8\u33b9\u33ba\u33bb\u33bc\u33bd\u33be\u33bf\u33c0\u33c1\u33c2\u33c3\u33c4\u33c5\u33c6\u33c7\u33c8\u33c9\u33ca\u33cb\u33cc\u33cd\u33ce\u33cf\u33d0\u33d1\u33d2\u33d3\u33d4\u33d5\u33d6\u33d7\u33d8\u33d9\u33da\u33db\u33dc\u33dd\u33de\u33df\u33e0\u33e1\u33e2\u33e3\u33e4\u33e5\u33e6\u33e7\u33e8\u33e9\u33ea\u33eb\u33ec\u33ed\u33ee\u33ef\u33f0\u33f1\u33f2\u33f3\u33f4\u33f5\u33f6\u33f7\u33f8\u33f9\u33fa\u33fb\u33fc\u33fd\u33fe\u33ff\u4dc0\u4dc1\u4dc2\u4dc3\u4dc4\u4dc5\u4dc6\u4dc7\u4dc8\u4dc9\u4dca\u4dcb\u4dcc\u4dcd\u4dce\u4dcf\u4dd0\u4dd1\u4dd2\u4dd3\u4dd4\u4dd5\u4dd6\u4dd7\u4dd8\u4dd9\u4dda\u4ddb\u4ddc\u4ddd\u4dde\u4ddf\u4de0\u4de1\u4de2\u4de3\u4de4\u4de5\u4de6\u4de7\u4de8\u4de9\u4dea\u4deb\u4dec\u4ded\u4dee\u4def\u4df0\u4df1\u4df2\u4df3\u4df4\u4df5\u4df6\u4df7\u4df8\u4df9\u4dfa\u4dfb\u4dfc\u4dfd\u4dfe\u4dff\ua490\ua491\ua492\ua493\ua494\ua495\ua496\ua497\ua498\ua499\ua49a\ua49b\ua49c\ua49d\ua49e\ua49f\ua4a0\ua4a1\ua4a2\ua4a3\ua4a4\ua4a5\ua4a6\ua4a7\ua4a8\ua4a9\ua4aa\ua4ab\ua4ac\ua4ad\ua4ae\ua4af\ua4b0\ua4b1\ua4b2\ua4b3\ua4b4\ua4b5\ua4b6\ua4b7\ua4b8\ua4b9\ua4ba\ua4bb\ua4bc\ua4bd\ua4be\ua4bf\ua4c0\ua4c1\ua4c2\ua4c3\ua4c4\ua4c5\ua4c6\ua828\ua829\ua82a\ua82b\ufdfd\uffe4\uffe8\uffed\uffee\ufffc\ufffd'
-
-Zl = u'\u2028'
-
-Zp = u'\u2029'
-
-Zs = u' \xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
-
-cats = ['Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', 'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs']
-
-def combine(*args):
- return u''.join([globals()[cat] for cat in args])
-
-xid_start = u'\u0041-\u005A\u005F\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u01BA\u01BB\u01BC-\u01BF\u01C0-\u01C3\u01C4-\u0241\u0250-\u02AF\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u076D\u0780-\u07A5\u07B1\u0904-\u0939\u093D\u0950\u0958-\u0961\u097D\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E40-\u0E45\u0E46\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDD\u0F00\u0F40-\u0F47\u0F49-\u0F6A\u0F88-\u0F8B\u1000-\u1021\u1023-\u1027\u1029-\u102A\u1050-\u1055\u10A0-\u10C5\u10D0-\u10FA\u10FC\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1842\u1843\u1844-\u1877\u1880-\u18A8\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19A9\u19C1-\u19C7\u1A00-\u1A16\u1D00-\u1D2B\u1D2C-\u1D61\u1D62-\u1D77\u1D78\u1D79-\u1D9A\u1D9B-\u1DBF\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u2094\u2102\u2107\u210A-\u2113\u2115\u2118\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212E\u212F-\u2131\u2133-\u2134\u2135-\u2138\u2139\u213C-\u213F\u2145-\u2149\u2160-\u2183\u2C00-\u2C2E\u2C30-\u2C5E\u2C80-\u2CE4\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005\u3006\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303A\u303B\u303C\u3041-\u3096\u309D-\u309E\u309F\u30A1-\u30FA\u30FC-\u30FE\u30FF\u3105-\u312C\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FBB\uA000-\uA014\uA015\uA016-\uA48C\uA800-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFC5D\uFC64-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDF9\uFE71\uFE73\uFE77\uFE79\uFE7B\uFE7D\uFE7F-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFF6F\uFF70\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC'
-
-xid_continue = u'\u0030-\u0039\u0041-\u005A\u005F\u0061-\u007A\u00AA\u00B5\u00B7\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u01BA\u01BB\u01BC-\u01BF\u01C0-\u01C3\u01C4-\u0241\u0250-\u02AF\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u0300-\u036F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481\u0483-\u0486\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u0615\u0621-\u063A\u0640\u0641-\u064A\u064B-\u065E\u0660-\u0669\u066E-\u066F\u0670\u0671-\u06D3\u06D5\u06D6-\u06DC\u06DF-\u06E4\u06E5-\u06E6\u06E7-\u06E8\u06EA-\u06ED\u06EE-\u06EF\u06F0-\u06F9\u06FA-\u06FC\u06FF\u0710\u0711\u0712-\u072F\u0730-\u074A\u074D-\u076D\u0780-\u07A5\u07A6-\u07B0\u07B1\u0901-\u0902\u0903\u0904-\u0939\u093C\u093D\u093E-\u0940\u0941-\u0948\u0949-\u094C\u094D\u0950\u0951-\u0954\u0958-\u0961\u0962-\u0963\u0966-\u096F\u097D\u0981\u0982-\u0983\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC\u09BD\u09BE-\u09C0\u09C1-\u09C4\u09C7-\u09C8\u09CB-\u09CC\u09CD\u09CE\u09D7\u09DC-\u09DD\u09DF-\u09E1\u09E2-\u09E3\u09E6-\u09EF\u09F0-\u09F1\u0A01-\u0A02\u0A03\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A3C\u0A3E-\u0A40\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A70-\u0A71\u0A72-\u0A74\u0A81-\u0A82\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABC\u0ABD\u0ABE-\u0AC0\u0AC1-\u0AC5\u0AC7-\u0AC8\u0AC9\u0ACB-\u0ACC\u0ACD\u0AD0\u0AE0-\u0AE1\u0AE2-\u0AE3\u0AE6-\u0AEF\u0B01\u0B02-\u0B03\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3C\u0B3D\u0B3E\u0B3F\u0B40\u0B41-\u0B43\u0B47-\u0B48\u0B4B-\u0B4C\u0B4D\u0B56\u0B57\u0B5C-\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BBF\u0BC0\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BCD\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3E-\u0C40\u0C41-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C60-\u0C61\u0C66-\u0C6F\u0C82-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC\u0CBD\u0CBE\u0CBF\u0CC0-\u0CC4\u0CC6\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CCC-\u0CCD\u0CD5-\u0CD6\u0CDE\u0CE0-\u0CE1\u0CE6-\u0CEF\u0D02-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D3E-\u0D40\u0D41-\u0D43\u0D46-\u0D48\u0D4A-\u0D4C\u0D4D\u0D57\u0D60-\u0D61\u0D66-\u0D6F\u0D82-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD1\u0DD2-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2-\u0DF3\u0E01-\u0E30\u0E31\u0E32-\u0E33\u0E34-\u0E3A\u0E40-\u0E45\u0E46\u0E47-\u0E4E\u0E50-\u0E59\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB1\u0EB2-\u0EB3\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDD\u0F00\u0F18-\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F3F\u0F40-\u0F47\u0F49-\u0F6A\u0F71-\u0F7E\u0F7F\u0F80-\u0F84\u0F86-\u0F87\u0F88-\u0F8B\u0F90-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1021\u1023-\u1027\u1029-\u102A\u102C\u102D-\u1030\u1031\u1032\u1036-\u1037\u1038\u1039\u1040-\u1049\u1050-\u1055\u1056-\u1057\u1058-\u1059\u10A0-\u10C5\u10D0-\u10FA\u10FC\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1712-\u1714\u1720-\u1731\u1732-\u1734\u1740-\u1751\u1752-\u1753\u1760-\u176C\u176E-\u1770\u1772-\u1773\u1780-\u17B3\u17B6\u17B7-\u17BD\u17BE-\u17C5\u17C6\u17C7-\u17C8\u17C9-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1842\u1843\u1844-\u1877\u1880-\u18A8\u18A9\u1900-\u191C\u1920-\u1922\u1923-\u1926\u1927-\u1928\u1929-\u192B\u1930-\u1931\u1932\u1933-\u1938\u1939-\u193B\u1946-\u194F\u1950-\u196D\u1970-\u1974\u1980-\u19A9\u19B0-\u19C0\u19C1-\u19C7\u19C8-\u19C9\u19D0-\u19D9\u1A00-\u1A16\u1A17-\u1A18\u1A19-\u1A1B\u1D00-\u1D2B\u1D2C-\u1D61\u1D62-\u1D77\u1D78\u1D79-\u1D9A\u1D9B-\u1DBF\u1DC0-\u1DC3\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F-\u2040\u2054\u2071\u207F\u2090-\u2094\u20D0-\u20DC\u20E1\u20E5-\u20EB\u2102\u2107\u210A-\u2113\u2115\u2118\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212E\u212F-\u2131\u2133-\u2134\u2135-\u2138\u2139\u213C-\u213F\u2145-\u2149\u2160-\u2183\u2C00-\u2C2E\u2C30-\u2C5E\u2C80-\u2CE4\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005\u3006\u3007\u3021-\u3029\u302A-\u302F\u3031-\u3035\u3038-\u303A\u303B\u303C\u3041-\u3096\u3099-\u309A\u309D-\u309E\u309F\u30A1-\u30FA\u30FC-\u30FE\u30FF\u3105-\u312C\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FBB\uA000-\uA014\uA015\uA016-\uA48C\uA800-\uA801\uA802\uA803-\uA805\uA806\uA807-\uA80A\uA80B\uA80C-\uA822\uA823-\uA824\uA825-\uA826\uA827\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1E\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFC5D\uFC64-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDF9\uFE00-\uFE0F\uFE20-\uFE23\uFE33-\uFE34\uFE4D-\uFE4F\uFE71\uFE73\uFE77\uFE79\uFE7B\uFE7D\uFE7F-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFF6F\uFF70\uFF71-\uFF9D\uFF9E-\uFF9F\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC'
-
-def allexcept(*args):
- newcats = cats[:]
- for arg in args:
- newcats.remove(arg)
- return u''.join([globals()[cat] for cat in newcats])
-
-if __name__ == '__main__':
- import unicodedata
-
- categories = {}
-
- f = open(__file__.rstrip('co'))
- try:
- content = f.read()
- finally:
- f.close()
-
- header = content[:content.find('Cc =')]
- footer = content[content.find("def combine("):]
-
- for code in range(65535):
- c = unichr(code)
- cat = unicodedata.category(c)
- categories.setdefault(cat, []).append(c)
-
- f = open(__file__, 'w')
- f.write(header)
-
- for cat in sorted(categories):
- val = u''.join(categories[cat])
- if cat == 'Cs':
- # Jython can't handle isolated surrogates
- f.write("""\
-try:
- Cs = eval(r"%r")
-except UnicodeDecodeError:
- Cs = '' # Jython can't handle isolated surrogates\n\n""" % val)
- else:
- f.write('%s = %r\n\n' % (cat, val))
- f.write('cats = %r\n\n' % sorted(categories.keys()))
-
- f.write(footer)
- f.close()
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/bccache.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/bccache.py
deleted file mode 100755
index 0b0ccad1..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/bccache.py
+++ /dev/null
@@ -1,301 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.bccache
- ~~~~~~~~~~~~~~
-
- This module implements the bytecode cache system Jinja is optionally
- using. This is useful if you have very complex template situations and
- the compiliation of all those templates slow down your application too
- much.
-
- Situations where this is useful are often forking web applications that
- are initialized on the first request.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD.
-"""
-from os import path, listdir
-import sys
-import marshal
-import tempfile
-import cPickle as pickle
-import fnmatch
-try:
- from hashlib import sha1
-except ImportError:
- from sha import new as sha1
-from jinja2.utils import open_if_exists
-
-
-# marshal works better on 3.x, one hack less required
-if sys.version_info > (3, 0):
- from io import BytesIO
- marshal_dump = marshal.dump
- marshal_load = marshal.load
-else:
- from cStringIO import StringIO as BytesIO
-
- def marshal_dump(code, f):
- if isinstance(f, file):
- marshal.dump(code, f)
- else:
- f.write(marshal.dumps(code))
-
- def marshal_load(f):
- if isinstance(f, file):
- return marshal.load(f)
- return marshal.loads(f.read())
-
-
-bc_version = 2
-
-# magic version used to only change with new jinja versions. With 2.6
-# we change this to also take Python version changes into account. The
-# reason for this is that Python tends to segfault if fed earlier bytecode
-# versions because someone thought it would be a good idea to reuse opcodes
-# or make Python incompatible with earlier versions.
-bc_magic = 'j2'.encode('ascii') + \
- pickle.dumps(bc_version, 2) + \
- pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1])
-
-
-class Bucket(object):
- """Buckets are used to store the bytecode for one template. It's created
- and initialized by the bytecode cache and passed to the loading functions.
-
- The buckets get an internal checksum from the cache assigned and use this
- to automatically reject outdated cache material. Individual bytecode
- cache subclasses don't have to care about cache invalidation.
- """
-
- def __init__(self, environment, key, checksum):
- self.environment = environment
- self.key = key
- self.checksum = checksum
- self.reset()
-
- def reset(self):
- """Resets the bucket (unloads the bytecode)."""
- self.code = None
-
- def load_bytecode(self, f):
- """Loads bytecode from a file or file like object."""
- # make sure the magic header is correct
- magic = f.read(len(bc_magic))
- if magic != bc_magic:
- self.reset()
- return
- # the source code of the file changed, we need to reload
- checksum = pickle.load(f)
- if self.checksum != checksum:
- self.reset()
- return
- self.code = marshal_load(f)
-
- def write_bytecode(self, f):
- """Dump the bytecode into the file or file like object passed."""
- if self.code is None:
- raise TypeError('can\'t write empty bucket')
- f.write(bc_magic)
- pickle.dump(self.checksum, f, 2)
- marshal_dump(self.code, f)
-
- def bytecode_from_string(self, string):
- """Load bytecode from a string."""
- self.load_bytecode(BytesIO(string))
-
- def bytecode_to_string(self):
- """Return the bytecode as string."""
- out = BytesIO()
- self.write_bytecode(out)
- return out.getvalue()
-
-
-class BytecodeCache(object):
- """To implement your own bytecode cache you have to subclass this class
- and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of
- these methods are passed a :class:`~jinja2.bccache.Bucket`.
-
- A very basic bytecode cache that saves the bytecode on the file system::
-
- from os import path
-
- class MyCache(BytecodeCache):
-
- def __init__(self, directory):
- self.directory = directory
-
- def load_bytecode(self, bucket):
- filename = path.join(self.directory, bucket.key)
- if path.exists(filename):
- with open(filename, 'rb') as f:
- bucket.load_bytecode(f)
-
- def dump_bytecode(self, bucket):
- filename = path.join(self.directory, bucket.key)
- with open(filename, 'wb') as f:
- bucket.write_bytecode(f)
-
- A more advanced version of a filesystem based bytecode cache is part of
- Jinja2.
- """
-
- def load_bytecode(self, bucket):
- """Subclasses have to override this method to load bytecode into a
- bucket. If they are not able to find code in the cache for the
- bucket, it must not do anything.
- """
- raise NotImplementedError()
-
- def dump_bytecode(self, bucket):
- """Subclasses have to override this method to write the bytecode
- from a bucket back to the cache. If it unable to do so it must not
- fail silently but raise an exception.
- """
- raise NotImplementedError()
-
- def clear(self):
- """Clears the cache. This method is not used by Jinja2 but should be
- implemented to allow applications to clear the bytecode cache used
- by a particular environment.
- """
-
- def get_cache_key(self, name, filename=None):
- """Returns the unique hash key for this template name."""
- hash = sha1(name.encode('utf-8'))
- if filename is not None:
- filename = '|' + filename
- if isinstance(filename, unicode):
- filename = filename.encode('utf-8')
- hash.update(filename)
- return hash.hexdigest()
-
- def get_source_checksum(self, source):
- """Returns a checksum for the source."""
- return sha1(source.encode('utf-8')).hexdigest()
-
- def get_bucket(self, environment, name, filename, source):
- """Return a cache bucket for the given template. All arguments are
- mandatory but filename may be `None`.
- """
- key = self.get_cache_key(name, filename)
- checksum = self.get_source_checksum(source)
- bucket = Bucket(environment, key, checksum)
- self.load_bytecode(bucket)
- return bucket
-
- def set_bucket(self, bucket):
- """Put the bucket into the cache."""
- self.dump_bytecode(bucket)
-
-
-class FileSystemBytecodeCache(BytecodeCache):
- """A bytecode cache that stores bytecode on the filesystem. It accepts
- two arguments: The directory where the cache items are stored and a
- pattern string that is used to build the filename.
-
- If no directory is specified the system temporary items folder is used.
-
- The pattern can be used to have multiple separate caches operate on the
- same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s``
- is replaced with the cache key.
-
- >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
-
- This bytecode cache supports clearing of the cache using the clear method.
- """
-
- def __init__(self, directory=None, pattern='__jinja2_%s.cache'):
- if directory is None:
- directory = tempfile.gettempdir()
- self.directory = directory
- self.pattern = pattern
-
- def _get_cache_filename(self, bucket):
- return path.join(self.directory, self.pattern % bucket.key)
-
- def load_bytecode(self, bucket):
- f = open_if_exists(self._get_cache_filename(bucket), 'rb')
- if f is not None:
- try:
- bucket.load_bytecode(f)
- finally:
- f.close()
-
- def dump_bytecode(self, bucket):
- f = open(self._get_cache_filename(bucket), 'wb')
- try:
- bucket.write_bytecode(f)
- finally:
- f.close()
-
- def clear(self):
- # imported lazily here because google app-engine doesn't support
- # write access on the file system and the function does not exist
- # normally.
- from os import remove
- files = fnmatch.filter(listdir(self.directory), self.pattern % '*')
- for filename in files:
- try:
- remove(path.join(self.directory, filename))
- except OSError:
- pass
-
-
-class MemcachedBytecodeCache(BytecodeCache):
- """This class implements a bytecode cache that uses a memcache cache for
- storing the information. It does not enforce a specific memcache library
- (tummy's memcache or cmemcache) but will accept any class that provides
- the minimal interface required.
-
- Libraries compatible with this class:
-
- - `werkzeug <http://werkzeug.pocoo.org/>`_.contrib.cache
- - `python-memcached <http://www.tummy.com/Community/software/python-memcached/>`_
- - `cmemcache <http://gijsbert.org/cmemcache/>`_
-
- (Unfortunately the django cache interface is not compatible because it
- does not support storing binary data, only unicode. You can however pass
- the underlying cache client to the bytecode cache which is available
- as `django.core.cache.cache._client`.)
-
- The minimal interface for the client passed to the constructor is this:
-
- .. class:: MinimalClientInterface
-
- .. method:: set(key, value[, timeout])
-
- Stores the bytecode in the cache. `value` is a string and
- `timeout` the timeout of the key. If timeout is not provided
- a default timeout or no timeout should be assumed, if it's
- provided it's an integer with the number of seconds the cache
- item should exist.
-
- .. method:: get(key)
-
- Returns the value for the cache key. If the item does not
- exist in the cache the return value must be `None`.
-
- The other arguments to the constructor are the prefix for all keys that
- is added before the actual cache key and the timeout for the bytecode in
- the cache system. We recommend a high (or no) timeout.
-
- This bytecode cache does not support clearing of used items in the cache.
- The clear method is a no-operation function.
- """
-
- def __init__(self, client, prefix='jinja2/bytecode/', timeout=None):
- self.client = client
- self.prefix = prefix
- self.timeout = timeout
-
- def load_bytecode(self, bucket):
- code = self.client.get(self.prefix + bucket.key)
- if code is not None:
- bucket.bytecode_from_string(code)
-
- def dump_bytecode(self, bucket):
- args = (self.prefix + bucket.key, bucket.bytecode_to_string())
- if self.timeout is not None:
- args += (self.timeout,)
- self.client.set(*args)
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/compiler.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/compiler.py
deleted file mode 100755
index b21cb386..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/compiler.py
+++ /dev/null
@@ -1,1649 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.compiler
- ~~~~~~~~~~~~~~~
-
- Compiles nodes into python code.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-from cStringIO import StringIO
-from itertools import chain
-from copy import deepcopy
-from jinja2 import nodes
-from jinja2.nodes import EvalContext
-from jinja2.visitor import NodeVisitor
-from jinja2.exceptions import TemplateAssertionError
-from jinja2.utils import Markup, concat, escape, is_python_keyword, next
-
-
-operators = {
- 'eq': '==',
- 'ne': '!=',
- 'gt': '>',
- 'gteq': '>=',
- 'lt': '<',
- 'lteq': '<=',
- 'in': 'in',
- 'notin': 'not in'
-}
-
-try:
- exec '(0 if 0 else 0)'
-except SyntaxError:
- have_condexpr = False
-else:
- have_condexpr = True
-
-
-# what method to iterate over items do we want to use for dict iteration
-# in generated code? on 2.x let's go with iteritems, on 3.x with items
-if hasattr(dict, 'iteritems'):
- dict_item_iter = 'iteritems'
-else:
- dict_item_iter = 'items'
-
-
-# does if 0: dummy(x) get us x into the scope?
-def unoptimize_before_dead_code():
- x = 42
- def f():
- if 0: dummy(x)
- return f
-unoptimize_before_dead_code = bool(unoptimize_before_dead_code().func_closure)
-
-
-def generate(node, environment, name, filename, stream=None,
- defer_init=False):
- """Generate the python source for a node tree."""
- if not isinstance(node, nodes.Template):
- raise TypeError('Can\'t compile non template nodes')
- generator = CodeGenerator(environment, name, filename, stream, defer_init)
- generator.visit(node)
- if stream is None:
- return generator.stream.getvalue()
-
-
-def has_safe_repr(value):
- """Does the node have a safe representation?"""
- if value is None or value is NotImplemented or value is Ellipsis:
- return True
- if isinstance(value, (bool, int, long, float, complex, basestring,
- xrange, Markup)):
- return True
- if isinstance(value, (tuple, list, set, frozenset)):
- for item in value:
- if not has_safe_repr(item):
- return False
- return True
- elif isinstance(value, dict):
- for key, value in value.iteritems():
- if not has_safe_repr(key):
- return False
- if not has_safe_repr(value):
- return False
- return True
- return False
-
-
-def find_undeclared(nodes, names):
- """Check if the names passed are accessed undeclared. The return value
- is a set of all the undeclared names from the sequence of names found.
- """
- visitor = UndeclaredNameVisitor(names)
- try:
- for node in nodes:
- visitor.visit(node)
- except VisitorExit:
- pass
- return visitor.undeclared
-
-
-class Identifiers(object):
- """Tracks the status of identifiers in frames."""
-
- def __init__(self):
- # variables that are known to be declared (probably from outer
- # frames or because they are special for the frame)
- self.declared = set()
-
- # undeclared variables from outer scopes
- self.outer_undeclared = set()
-
- # names that are accessed without being explicitly declared by
- # this one or any of the outer scopes. Names can appear both in
- # declared and undeclared.
- self.undeclared = set()
-
- # names that are declared locally
- self.declared_locally = set()
-
- # names that are declared by parameters
- self.declared_parameter = set()
-
- def add_special(self, name):
- """Register a special name like `loop`."""
- self.undeclared.discard(name)
- self.declared.add(name)
-
- def is_declared(self, name):
- """Check if a name is declared in this or an outer scope."""
- if name in self.declared_locally or name in self.declared_parameter:
- return True
- return name in self.declared
-
- def copy(self):
- return deepcopy(self)
-
-
-class Frame(object):
- """Holds compile time information for us."""
-
- def __init__(self, eval_ctx, parent=None):
- self.eval_ctx = eval_ctx
- self.identifiers = Identifiers()
-
- # a toplevel frame is the root + soft frames such as if conditions.
- self.toplevel = False
-
- # the root frame is basically just the outermost frame, so no if
- # conditions. This information is used to optimize inheritance
- # situations.
- self.rootlevel = False
-
- # in some dynamic inheritance situations the compiler needs to add
- # write tests around output statements.
- self.require_output_check = parent and parent.require_output_check
-
- # inside some tags we are using a buffer rather than yield statements.
- # this for example affects {% filter %} or {% macro %}. If a frame
- # is buffered this variable points to the name of the list used as
- # buffer.
- self.buffer = None
-
- # the name of the block we're in, otherwise None.
- self.block = parent and parent.block or None
-
- # a set of actually assigned names
- self.assigned_names = set()
-
- # the parent of this frame
- self.parent = parent
-
- if parent is not None:
- self.identifiers.declared.update(
- parent.identifiers.declared |
- parent.identifiers.declared_parameter |
- parent.assigned_names
- )
- self.identifiers.outer_undeclared.update(
- parent.identifiers.undeclared -
- self.identifiers.declared
- )
- self.buffer = parent.buffer
-
- def copy(self):
- """Create a copy of the current one."""
- rv = object.__new__(self.__class__)
- rv.__dict__.update(self.__dict__)
- rv.identifiers = object.__new__(self.identifiers.__class__)
- rv.identifiers.__dict__.update(self.identifiers.__dict__)
- return rv
-
- def inspect(self, nodes):
- """Walk the node and check for identifiers. If the scope is hard (eg:
- enforce on a python level) overrides from outer scopes are tracked
- differently.
- """
- visitor = FrameIdentifierVisitor(self.identifiers)
- for node in nodes:
- visitor.visit(node)
-
- def find_shadowed(self, extra=()):
- """Find all the shadowed names. extra is an iterable of variables
- that may be defined with `add_special` which may occour scoped.
- """
- i = self.identifiers
- return (i.declared | i.outer_undeclared) & \
- (i.declared_locally | i.declared_parameter) | \
- set(x for x in extra if i.is_declared(x))
-
- def inner(self):
- """Return an inner frame."""
- return Frame(self.eval_ctx, self)
-
- def soft(self):
- """Return a soft frame. A soft frame may not be modified as
- standalone thing as it shares the resources with the frame it
- was created of, but it's not a rootlevel frame any longer.
- """
- rv = self.copy()
- rv.rootlevel = False
- return rv
-
- __copy__ = copy
-
-
-class VisitorExit(RuntimeError):
- """Exception used by the `UndeclaredNameVisitor` to signal a stop."""
-
-
-class DependencyFinderVisitor(NodeVisitor):
- """A visitor that collects filter and test calls."""
-
- def __init__(self):
- self.filters = set()
- self.tests = set()
-
- def visit_Filter(self, node):
- self.generic_visit(node)
- self.filters.add(node.name)
-
- def visit_Test(self, node):
- self.generic_visit(node)
- self.tests.add(node.name)
-
- def visit_Block(self, node):
- """Stop visiting at blocks."""
-
-
-class UndeclaredNameVisitor(NodeVisitor):
- """A visitor that checks if a name is accessed without being
- declared. This is different from the frame visitor as it will
- not stop at closure frames.
- """
-
- def __init__(self, names):
- self.names = set(names)
- self.undeclared = set()
-
- def visit_Name(self, node):
- if node.ctx == 'load' and node.name in self.names:
- self.undeclared.add(node.name)
- if self.undeclared == self.names:
- raise VisitorExit()
- else:
- self.names.discard(node.name)
-
- def visit_Block(self, node):
- """Stop visiting a blocks."""
-
-
-class FrameIdentifierVisitor(NodeVisitor):
- """A visitor for `Frame.inspect`."""
-
- def __init__(self, identifiers):
- self.identifiers = identifiers
-
- def visit_Name(self, node):
- """All assignments to names go through this function."""
- if node.ctx == 'store':
- self.identifiers.declared_locally.add(node.name)
- elif node.ctx == 'param':
- self.identifiers.declared_parameter.add(node.name)
- elif node.ctx == 'load' and not \
- self.identifiers.is_declared(node.name):
- self.identifiers.undeclared.add(node.name)
-
- def visit_If(self, node):
- self.visit(node.test)
- real_identifiers = self.identifiers
-
- old_names = real_identifiers.declared_locally | \
- real_identifiers.declared_parameter
-
- def inner_visit(nodes):
- if not nodes:
- return set()
- self.identifiers = real_identifiers.copy()
- for subnode in nodes:
- self.visit(subnode)
- rv = self.identifiers.declared_locally - old_names
- # we have to remember the undeclared variables of this branch
- # because we will have to pull them.
- real_identifiers.undeclared.update(self.identifiers.undeclared)
- self.identifiers = real_identifiers
- return rv
-
- body = inner_visit(node.body)
- else_ = inner_visit(node.else_ or ())
-
- # the differences between the two branches are also pulled as
- # undeclared variables
- real_identifiers.undeclared.update(body.symmetric_difference(else_) -
- real_identifiers.declared)
-
- # remember those that are declared.
- real_identifiers.declared_locally.update(body | else_)
-
- def visit_Macro(self, node):
- self.identifiers.declared_locally.add(node.name)
-
- def visit_Import(self, node):
- self.generic_visit(node)
- self.identifiers.declared_locally.add(node.target)
-
- def visit_FromImport(self, node):
- self.generic_visit(node)
- for name in node.names:
- if isinstance(name, tuple):
- self.identifiers.declared_locally.add(name[1])
- else:
- self.identifiers.declared_locally.add(name)
-
- def visit_Assign(self, node):
- """Visit assignments in the correct order."""
- self.visit(node.node)
- self.visit(node.target)
-
- def visit_For(self, node):
- """Visiting stops at for blocks. However the block sequence
- is visited as part of the outer scope.
- """
- self.visit(node.iter)
-
- def visit_CallBlock(self, node):
- self.visit(node.call)
-
- def visit_FilterBlock(self, node):
- self.visit(node.filter)
-
- def visit_Scope(self, node):
- """Stop visiting at scopes."""
-
- def visit_Block(self, node):
- """Stop visiting at blocks."""
-
-
-class CompilerExit(Exception):
- """Raised if the compiler encountered a situation where it just
- doesn't make sense to further process the code. Any block that
- raises such an exception is not further processed.
- """
-
-
-class CodeGenerator(NodeVisitor):
-
- def __init__(self, environment, name, filename, stream=None,
- defer_init=False):
- if stream is None:
- stream = StringIO()
- self.environment = environment
- self.name = name
- self.filename = filename
- self.stream = stream
- self.created_block_context = False
- self.defer_init = defer_init
-
- # aliases for imports
- self.import_aliases = {}
-
- # a registry for all blocks. Because blocks are moved out
- # into the global python scope they are registered here
- self.blocks = {}
-
- # the number of extends statements so far
- self.extends_so_far = 0
-
- # some templates have a rootlevel extends. In this case we
- # can safely assume that we're a child template and do some
- # more optimizations.
- self.has_known_extends = False
-
- # the current line number
- self.code_lineno = 1
-
- # registry of all filters and tests (global, not block local)
- self.tests = {}
- self.filters = {}
-
- # the debug information
- self.debug_info = []
- self._write_debug_info = None
-
- # the number of new lines before the next write()
- self._new_lines = 0
-
- # the line number of the last written statement
- self._last_line = 0
-
- # true if nothing was written so far.
- self._first_write = True
-
- # used by the `temporary_identifier` method to get new
- # unique, temporary identifier
- self._last_identifier = 0
-
- # the current indentation
- self._indentation = 0
-
- # -- Various compilation helpers
-
- def fail(self, msg, lineno):
- """Fail with a :exc:`TemplateAssertionError`."""
- raise TemplateAssertionError(msg, lineno, self.name, self.filename)
-
- def temporary_identifier(self):
- """Get a new unique identifier."""
- self._last_identifier += 1
- return 't_%d' % self._last_identifier
-
- def buffer(self, frame):
- """Enable buffering for the frame from that point onwards."""
- frame.buffer = self.temporary_identifier()
- self.writeline('%s = []' % frame.buffer)
-
- def return_buffer_contents(self, frame):
- """Return the buffer contents of the frame."""
- if frame.eval_ctx.volatile:
- self.writeline('if context.eval_ctx.autoescape:')
- self.indent()
- self.writeline('return Markup(concat(%s))' % frame.buffer)
- self.outdent()
- self.writeline('else:')
- self.indent()
- self.writeline('return concat(%s)' % frame.buffer)
- self.outdent()
- elif frame.eval_ctx.autoescape:
- self.writeline('return Markup(concat(%s))' % frame.buffer)
- else:
- self.writeline('return concat(%s)' % frame.buffer)
-
- def indent(self):
- """Indent by one."""
- self._indentation += 1
-
- def outdent(self, step=1):
- """Outdent by step."""
- self._indentation -= step
-
- def start_write(self, frame, node=None):
- """Yield or write into the frame buffer."""
- if frame.buffer is None:
- self.writeline('yield ', node)
- else:
- self.writeline('%s.append(' % frame.buffer, node)
-
- def end_write(self, frame):
- """End the writing process started by `start_write`."""
- if frame.buffer is not None:
- self.write(')')
-
- def simple_write(self, s, frame, node=None):
- """Simple shortcut for start_write + write + end_write."""
- self.start_write(frame, node)
- self.write(s)
- self.end_write(frame)
-
- def blockvisit(self, nodes, frame):
- """Visit a list of nodes as block in a frame. If the current frame
- is no buffer a dummy ``if 0: yield None`` is written automatically
- unless the force_generator parameter is set to False.
- """
- if frame.buffer is None:
- self.writeline('if 0: yield None')
- else:
- self.writeline('pass')
- try:
- for node in nodes:
- self.visit(node, frame)
- except CompilerExit:
- pass
-
- def write(self, x):
- """Write a string into the output stream."""
- if self._new_lines:
- if not self._first_write:
- self.stream.write('\n' * self._new_lines)
- self.code_lineno += self._new_lines
- if self._write_debug_info is not None:
- self.debug_info.append((self._write_debug_info,
- self.code_lineno))
- self._write_debug_info = None
- self._first_write = False
- self.stream.write(' ' * self._indentation)
- self._new_lines = 0
- self.stream.write(x)
-
- def writeline(self, x, node=None, extra=0):
- """Combination of newline and write."""
- self.newline(node, extra)
- self.write(x)
-
- def newline(self, node=None, extra=0):
- """Add one or more newlines before the next write."""
- self._new_lines = max(self._new_lines, 1 + extra)
- if node is not None and node.lineno != self._last_line:
- self._write_debug_info = node.lineno
- self._last_line = node.lineno
-
- def signature(self, node, frame, extra_kwargs=None):
- """Writes a function call to the stream for the current node.
- A leading comma is added automatically. The extra keyword
- arguments may not include python keywords otherwise a syntax
- error could occour. The extra keyword arguments should be given
- as python dict.
- """
- # if any of the given keyword arguments is a python keyword
- # we have to make sure that no invalid call is created.
- kwarg_workaround = False
- for kwarg in chain((x.key for x in node.kwargs), extra_kwargs or ()):
- if is_python_keyword(kwarg):
- kwarg_workaround = True
- break
-
- for arg in node.args:
- self.write(', ')
- self.visit(arg, frame)
-
- if not kwarg_workaround:
- for kwarg in node.kwargs:
- self.write(', ')
- self.visit(kwarg, frame)
- if extra_kwargs is not None:
- for key, value in extra_kwargs.iteritems():
- self.write(', %s=%s' % (key, value))
- if node.dyn_args:
- self.write(', *')
- self.visit(node.dyn_args, frame)
-
- if kwarg_workaround:
- if node.dyn_kwargs is not None:
- self.write(', **dict({')
- else:
- self.write(', **{')
- for kwarg in node.kwargs:
- self.write('%r: ' % kwarg.key)
- self.visit(kwarg.value, frame)
- self.write(', ')
- if extra_kwargs is not None:
- for key, value in extra_kwargs.iteritems():
- self.write('%r: %s, ' % (key, value))
- if node.dyn_kwargs is not None:
- self.write('}, **')
- self.visit(node.dyn_kwargs, frame)
- self.write(')')
- else:
- self.write('}')
-
- elif node.dyn_kwargs is not None:
- self.write(', **')
- self.visit(node.dyn_kwargs, frame)
-
- def pull_locals(self, frame):
- """Pull all the references identifiers into the local scope."""
- for name in frame.identifiers.undeclared:
- self.writeline('l_%s = context.resolve(%r)' % (name, name))
-
- def pull_dependencies(self, nodes):
- """Pull all the dependencies."""
- visitor = DependencyFinderVisitor()
- for node in nodes:
- visitor.visit(node)
- for dependency in 'filters', 'tests':
- mapping = getattr(self, dependency)
- for name in getattr(visitor, dependency):
- if name not in mapping:
- mapping[name] = self.temporary_identifier()
- self.writeline('%s = environment.%s[%r]' %
- (mapping[name], dependency, name))
-
- def unoptimize_scope(self, frame):
- """Disable Python optimizations for the frame."""
- # XXX: this is not that nice but it has no real overhead. It
- # mainly works because python finds the locals before dead code
- # is removed. If that breaks we have to add a dummy function
- # that just accepts the arguments and does nothing.
- if frame.identifiers.declared:
- self.writeline('%sdummy(%s)' % (
- unoptimize_before_dead_code and 'if 0: ' or '',
- ', '.join('l_' + name for name in frame.identifiers.declared)
- ))
-
- def push_scope(self, frame, extra_vars=()):
- """This function returns all the shadowed variables in a dict
- in the form name: alias and will write the required assignments
- into the current scope. No indentation takes place.
-
- This also predefines locally declared variables from the loop
- body because under some circumstances it may be the case that
-
- `extra_vars` is passed to `Frame.find_shadowed`.
- """
- aliases = {}
- for name in frame.find_shadowed(extra_vars):
- aliases[name] = ident = self.temporary_identifier()
- self.writeline('%s = l_%s' % (ident, name))
- to_declare = set()
- for name in frame.identifiers.declared_locally:
- if name not in aliases:
- to_declare.add('l_' + name)
- if to_declare:
- self.writeline(' = '.join(to_declare) + ' = missing')
- return aliases
-
- def pop_scope(self, aliases, frame):
- """Restore all aliases and delete unused variables."""
- for name, alias in aliases.iteritems():
- self.writeline('l_%s = %s' % (name, alias))
- to_delete = set()
- for name in frame.identifiers.declared_locally:
- if name not in aliases:
- to_delete.add('l_' + name)
- if to_delete:
- # we cannot use the del statement here because enclosed
- # scopes can trigger a SyntaxError:
- # a = 42; b = lambda: a; del a
- self.writeline(' = '.join(to_delete) + ' = missing')
-
- def function_scoping(self, node, frame, children=None,
- find_special=True):
- """In Jinja a few statements require the help of anonymous
- functions. Those are currently macros and call blocks and in
- the future also recursive loops. As there is currently
- technical limitation that doesn't allow reading and writing a
- variable in a scope where the initial value is coming from an
- outer scope, this function tries to fall back with a common
- error message. Additionally the frame passed is modified so
- that the argumetns are collected and callers are looked up.
-
- This will return the modified frame.
- """
- # we have to iterate twice over it, make sure that works
- if children is None:
- children = node.iter_child_nodes()
- children = list(children)
- func_frame = frame.inner()
- func_frame.inspect(children)
-
- # variables that are undeclared (accessed before declaration) and
- # declared locally *and* part of an outside scope raise a template
- # assertion error. Reason: we can't generate reasonable code from
- # it without aliasing all the variables.
- # this could be fixed in Python 3 where we have the nonlocal
- # keyword or if we switch to bytecode generation
- overriden_closure_vars = (
- func_frame.identifiers.undeclared &
- func_frame.identifiers.declared &
- (func_frame.identifiers.declared_locally |
- func_frame.identifiers.declared_parameter)
- )
- if overriden_closure_vars:
- self.fail('It\'s not possible to set and access variables '
- 'derived from an outer scope! (affects: %s)' %
- ', '.join(sorted(overriden_closure_vars)), node.lineno)
-
- # remove variables from a closure from the frame's undeclared
- # identifiers.
- func_frame.identifiers.undeclared -= (
- func_frame.identifiers.undeclared &
- func_frame.identifiers.declared
- )
-
- # no special variables for this scope, abort early
- if not find_special:
- return func_frame
-
- func_frame.accesses_kwargs = False
- func_frame.accesses_varargs = False
- func_frame.accesses_caller = False
- func_frame.arguments = args = ['l_' + x.name for x in node.args]
-
- undeclared = find_undeclared(children, ('caller', 'kwargs', 'varargs'))
-
- if 'caller' in undeclared:
- func_frame.accesses_caller = True
- func_frame.identifiers.add_special('caller')
- args.append('l_caller')
- if 'kwargs' in undeclared:
- func_frame.accesses_kwargs = True
- func_frame.identifiers.add_special('kwargs')
- args.append('l_kwargs')
- if 'varargs' in undeclared:
- func_frame.accesses_varargs = True
- func_frame.identifiers.add_special('varargs')
- args.append('l_varargs')
- return func_frame
-
- def macro_body(self, node, frame, children=None):
- """Dump the function def of a macro or call block."""
- frame = self.function_scoping(node, frame, children)
- # macros are delayed, they never require output checks
- frame.require_output_check = False
- args = frame.arguments
- # XXX: this is an ugly fix for the loop nesting bug
- # (tests.test_old_bugs.test_loop_call_bug). This works around
- # a identifier nesting problem we have in general. It's just more
- # likely to happen in loops which is why we work around it. The
- # real solution would be "nonlocal" all the identifiers that are
- # leaking into a new python frame and might be used both unassigned
- # and assigned.
- if 'loop' in frame.identifiers.declared:
- args = args + ['l_loop=l_loop']
- self.writeline('def macro(%s):' % ', '.join(args), node)
- self.indent()
- self.buffer(frame)
- self.pull_locals(frame)
- self.blockvisit(node.body, frame)
- self.return_buffer_contents(frame)
- self.outdent()
- return frame
-
- def macro_def(self, node, frame):
- """Dump the macro definition for the def created by macro_body."""
- arg_tuple = ', '.join(repr(x.name) for x in node.args)
- name = getattr(node, 'name', None)
- if len(node.args) == 1:
- arg_tuple += ','
- self.write('Macro(environment, macro, %r, (%s), (' %
- (name, arg_tuple))
- for arg in node.defaults:
- self.visit(arg, frame)
- self.write(', ')
- self.write('), %r, %r, %r)' % (
- bool(frame.accesses_kwargs),
- bool(frame.accesses_varargs),
- bool(frame.accesses_caller)
- ))
-
- def position(self, node):
- """Return a human readable position for the node."""
- rv = 'line %d' % node.lineno
- if self.name is not None:
- rv += ' in ' + repr(self.name)
- return rv
-
- # -- Statement Visitors
-
- def visit_Template(self, node, frame=None):
- assert frame is None, 'no root frame allowed'
- eval_ctx = EvalContext(self.environment, self.name)
-
- from jinja2.runtime import __all__ as exported
- self.writeline('from __future__ import division')
- self.writeline('from jinja2.runtime import ' + ', '.join(exported))
- if not unoptimize_before_dead_code:
- self.writeline('dummy = lambda *x: None')
-
- # if we want a deferred initialization we cannot move the
- # environment into a local name
- envenv = not self.defer_init and ', environment=environment' or ''
-
- # do we have an extends tag at all? If not, we can save some
- # overhead by just not processing any inheritance code.
- have_extends = node.find(nodes.Extends) is not None
-
- # find all blocks
- for block in node.find_all(nodes.Block):
- if block.name in self.blocks:
- self.fail('block %r defined twice' % block.name, block.lineno)
- self.blocks[block.name] = block
-
- # find all imports and import them
- for import_ in node.find_all(nodes.ImportedName):
- if import_.importname not in self.import_aliases:
- imp = import_.importname
- self.import_aliases[imp] = alias = self.temporary_identifier()
- if '.' in imp:
- module, obj = imp.rsplit('.', 1)
- self.writeline('from %s import %s as %s' %
- (module, obj, alias))
- else:
- self.writeline('import %s as %s' % (imp, alias))
-
- # add the load name
- self.writeline('name = %r' % self.name)
-
- # generate the root render function.
- self.writeline('def root(context%s):' % envenv, extra=1)
-
- # process the root
- frame = Frame(eval_ctx)
- frame.inspect(node.body)
- frame.toplevel = frame.rootlevel = True
- frame.require_output_check = have_extends and not self.has_known_extends
- self.indent()
- if have_extends:
- self.writeline('parent_template = None')
- if 'self' in find_undeclared(node.body, ('self',)):
- frame.identifiers.add_special('self')
- self.writeline('l_self = TemplateReference(context)')
- self.pull_locals(frame)
- self.pull_dependencies(node.body)
- self.blockvisit(node.body, frame)
- self.outdent()
-
- # make sure that the parent root is called.
- if have_extends:
- if not self.has_known_extends:
- self.indent()
- self.writeline('if parent_template is not None:')
- self.indent()
- self.writeline('for event in parent_template.'
- 'root_render_func(context):')
- self.indent()
- self.writeline('yield event')
- self.outdent(2 + (not self.has_known_extends))
-
- # at this point we now have the blocks collected and can visit them too.
- for name, block in self.blocks.iteritems():
- block_frame = Frame(eval_ctx)
- block_frame.inspect(block.body)
- block_frame.block = name
- self.writeline('def block_%s(context%s):' % (name, envenv),
- block, 1)
- self.indent()
- undeclared = find_undeclared(block.body, ('self', 'super'))
- if 'self' in undeclared:
- block_frame.identifiers.add_special('self')
- self.writeline('l_self = TemplateReference(context)')
- if 'super' in undeclared:
- block_frame.identifiers.add_special('super')
- self.writeline('l_super = context.super(%r, '
- 'block_%s)' % (name, name))
- self.pull_locals(block_frame)
- self.pull_dependencies(block.body)
- self.blockvisit(block.body, block_frame)
- self.outdent()
-
- self.writeline('blocks = {%s}' % ', '.join('%r: block_%s' % (x, x)
- for x in self.blocks),
- extra=1)
-
- # add a function that returns the debug info
- self.writeline('debug_info = %r' % '&'.join('%s=%s' % x for x
- in self.debug_info))
-
- def visit_Block(self, node, frame):
- """Call a block and register it for the template."""
- level = 1
- if frame.toplevel:
- # if we know that we are a child template, there is no need to
- # check if we are one
- if self.has_known_extends:
- return
- if self.extends_so_far > 0:
- self.writeline('if parent_template is None:')
- self.indent()
- level += 1
- context = node.scoped and 'context.derived(locals())' or 'context'
- self.writeline('for event in context.blocks[%r][0](%s):' % (
- node.name, context), node)
- self.indent()
- self.simple_write('event', frame)
- self.outdent(level)
-
- def visit_Extends(self, node, frame):
- """Calls the extender."""
- if not frame.toplevel:
- self.fail('cannot use extend from a non top-level scope',
- node.lineno)
-
- # if the number of extends statements in general is zero so
- # far, we don't have to add a check if something extended
- # the template before this one.
- if self.extends_so_far > 0:
-
- # if we have a known extends we just add a template runtime
- # error into the generated code. We could catch that at compile
- # time too, but i welcome it not to confuse users by throwing the
- # same error at different times just "because we can".
- if not self.has_known_extends:
- self.writeline('if parent_template is not None:')
- self.indent()
- self.writeline('raise TemplateRuntimeError(%r)' %
- 'extended multiple times')
- self.outdent()
-
- # if we have a known extends already we don't need that code here
- # as we know that the template execution will end here.
- if self.has_known_extends:
- raise CompilerExit()
-
- self.writeline('parent_template = environment.get_template(', node)
- self.visit(node.template, frame)
- self.write(', %r)' % self.name)
- self.writeline('for name, parent_block in parent_template.'
- 'blocks.%s():' % dict_item_iter)
- self.indent()
- self.writeline('context.blocks.setdefault(name, []).'
- 'append(parent_block)')
- self.outdent()
-
- # if this extends statement was in the root level we can take
- # advantage of that information and simplify the generated code
- # in the top level from this point onwards
- if frame.rootlevel:
- self.has_known_extends = True
-
- # and now we have one more
- self.extends_so_far += 1
-
- def visit_Include(self, node, frame):
- """Handles includes."""
- if node.with_context:
- self.unoptimize_scope(frame)
- if node.ignore_missing:
- self.writeline('try:')
- self.indent()
-
- func_name = 'get_or_select_template'
- if isinstance(node.template, nodes.Const):
- if isinstance(node.template.value, basestring):
- func_name = 'get_template'
- elif isinstance(node.template.value, (tuple, list)):
- func_name = 'select_template'
- elif isinstance(node.template, (nodes.Tuple, nodes.List)):
- func_name = 'select_template'
-
- self.writeline('template = environment.%s(' % func_name, node)
- self.visit(node.template, frame)
- self.write(', %r)' % self.name)
- if node.ignore_missing:
- self.outdent()
- self.writeline('except TemplateNotFound:')
- self.indent()
- self.writeline('pass')
- self.outdent()
- self.writeline('else:')
- self.indent()
-
- if node.with_context:
- self.writeline('for event in template.root_render_func('
- 'template.new_context(context.parent, True, '
- 'locals())):')
- else:
- self.writeline('for event in template.module._body_stream:')
-
- self.indent()
- self.simple_write('event', frame)
- self.outdent()
-
- if node.ignore_missing:
- self.outdent()
-
- def visit_Import(self, node, frame):
- """Visit regular imports."""
- if node.with_context:
- self.unoptimize_scope(frame)
- self.writeline('l_%s = ' % node.target, node)
- if frame.toplevel:
- self.write('context.vars[%r] = ' % node.target)
- self.write('environment.get_template(')
- self.visit(node.template, frame)
- self.write(', %r).' % self.name)
- if node.with_context:
- self.write('make_module(context.parent, True, locals())')
- else:
- self.write('module')
- if frame.toplevel and not node.target.startswith('_'):
- self.writeline('context.exported_vars.discard(%r)' % node.target)
- frame.assigned_names.add(node.target)
-
- def visit_FromImport(self, node, frame):
- """Visit named imports."""
- self.newline(node)
- self.write('included_template = environment.get_template(')
- self.visit(node.template, frame)
- self.write(', %r).' % self.name)
- if node.with_context:
- self.write('make_module(context.parent, True)')
- else:
- self.write('module')
-
- var_names = []
- discarded_names = []
- for name in node.names:
- if isinstance(name, tuple):
- name, alias = name
- else:
- alias = name
- self.writeline('l_%s = getattr(included_template, '
- '%r, missing)' % (alias, name))
- self.writeline('if l_%s is missing:' % alias)
- self.indent()
- self.writeline('l_%s = environment.undefined(%r %% '
- 'included_template.__name__, '
- 'name=%r)' %
- (alias, 'the template %%r (imported on %s) does '
- 'not export the requested name %s' % (
- self.position(node),
- repr(name)
- ), name))
- self.outdent()
- if frame.toplevel:
- var_names.append(alias)
- if not alias.startswith('_'):
- discarded_names.append(alias)
- frame.assigned_names.add(alias)
-
- if var_names:
- if len(var_names) == 1:
- name = var_names[0]
- self.writeline('context.vars[%r] = l_%s' % (name, name))
- else:
- self.writeline('context.vars.update({%s})' % ', '.join(
- '%r: l_%s' % (name, name) for name in var_names
- ))
- if discarded_names:
- if len(discarded_names) == 1:
- self.writeline('context.exported_vars.discard(%r)' %
- discarded_names[0])
- else:
- self.writeline('context.exported_vars.difference_'
- 'update((%s))' % ', '.join(map(repr, discarded_names)))
-
- def visit_For(self, node, frame):
- # when calculating the nodes for the inner frame we have to exclude
- # the iterator contents from it
- children = node.iter_child_nodes(exclude=('iter',))
- if node.recursive:
- loop_frame = self.function_scoping(node, frame, children,
- find_special=False)
- else:
- loop_frame = frame.inner()
- loop_frame.inspect(children)
-
- # try to figure out if we have an extended loop. An extended loop
- # is necessary if the loop is in recursive mode if the special loop
- # variable is accessed in the body.
- extended_loop = node.recursive or 'loop' in \
- find_undeclared(node.iter_child_nodes(
- only=('body',)), ('loop',))
-
- # if we don't have an recursive loop we have to find the shadowed
- # variables at that point. Because loops can be nested but the loop
- # variable is a special one we have to enforce aliasing for it.
- if not node.recursive:
- aliases = self.push_scope(loop_frame, ('loop',))
-
- # otherwise we set up a buffer and add a function def
- else:
- self.writeline('def loop(reciter, loop_render_func):', node)
- self.indent()
- self.buffer(loop_frame)
- aliases = {}
-
- # make sure the loop variable is a special one and raise a template
- # assertion error if a loop tries to write to loop
- if extended_loop:
- loop_frame.identifiers.add_special('loop')
- for name in node.find_all(nodes.Name):
- if name.ctx == 'store' and name.name == 'loop':
- self.fail('Can\'t assign to special loop variable '
- 'in for-loop target', name.lineno)
-
- self.pull_locals(loop_frame)
- if node.else_:
- iteration_indicator = self.temporary_identifier()
- self.writeline('%s = 1' % iteration_indicator)
-
- # Create a fake parent loop if the else or test section of a
- # loop is accessing the special loop variable and no parent loop
- # exists.
- if 'loop' not in aliases and 'loop' in find_undeclared(
- node.iter_child_nodes(only=('else_', 'test')), ('loop',)):
- self.writeline("l_loop = environment.undefined(%r, name='loop')" %
- ("'loop' is undefined. the filter section of a loop as well "
- "as the else block don't have access to the special 'loop'"
- " variable of the current loop. Because there is no parent "
- "loop it's undefined. Happened in loop on %s" %
- self.position(node)))
-
- self.writeline('for ', node)
- self.visit(node.target, loop_frame)
- self.write(extended_loop and ', l_loop in LoopContext(' or ' in ')
-
- # if we have an extened loop and a node test, we filter in the
- # "outer frame".
- if extended_loop and node.test is not None:
- self.write('(')
- self.visit(node.target, loop_frame)
- self.write(' for ')
- self.visit(node.target, loop_frame)
- self.write(' in ')
- if node.recursive:
- self.write('reciter')
- else:
- self.visit(node.iter, loop_frame)
- self.write(' if (')
- test_frame = loop_frame.copy()
- self.visit(node.test, test_frame)
- self.write('))')
-
- elif node.recursive:
- self.write('reciter')
- else:
- self.visit(node.iter, loop_frame)
-
- if node.recursive:
- self.write(', recurse=loop_render_func):')
- else:
- self.write(extended_loop and '):' or ':')
-
- # tests in not extended loops become a continue
- if not extended_loop and node.test is not None:
- self.indent()
- self.writeline('if not ')
- self.visit(node.test, loop_frame)
- self.write(':')
- self.indent()
- self.writeline('continue')
- self.outdent(2)
-
- self.indent()
- self.blockvisit(node.body, loop_frame)
- if node.else_:
- self.writeline('%s = 0' % iteration_indicator)
- self.outdent()
-
- if node.else_:
- self.writeline('if %s:' % iteration_indicator)
- self.indent()
- self.blockvisit(node.else_, loop_frame)
- self.outdent()
-
- # reset the aliases if there are any.
- if not node.recursive:
- self.pop_scope(aliases, loop_frame)
-
- # if the node was recursive we have to return the buffer contents
- # and start the iteration code
- if node.recursive:
- self.return_buffer_contents(loop_frame)
- self.outdent()
- self.start_write(frame, node)
- self.write('loop(')
- self.visit(node.iter, frame)
- self.write(', loop)')
- self.end_write(frame)
-
- def visit_If(self, node, frame):
- if_frame = frame.soft()
- self.writeline('if ', node)
- self.visit(node.test, if_frame)
- self.write(':')
- self.indent()
- self.blockvisit(node.body, if_frame)
- self.outdent()
- if node.else_:
- self.writeline('else:')
- self.indent()
- self.blockvisit(node.else_, if_frame)
- self.outdent()
-
- def visit_Macro(self, node, frame):
- macro_frame = self.macro_body(node, frame)
- self.newline()
- if frame.toplevel:
- if not node.name.startswith('_'):
- self.write('context.exported_vars.add(%r)' % node.name)
- self.writeline('context.vars[%r] = ' % node.name)
- self.write('l_%s = ' % node.name)
- self.macro_def(node, macro_frame)
- frame.assigned_names.add(node.name)
-
- def visit_CallBlock(self, node, frame):
- children = node.iter_child_nodes(exclude=('call',))
- call_frame = self.macro_body(node, frame, children)
- self.writeline('caller = ')
- self.macro_def(node, call_frame)
- self.start_write(frame, node)
- self.visit_Call(node.call, call_frame, forward_caller=True)
- self.end_write(frame)
-
- def visit_FilterBlock(self, node, frame):
- filter_frame = frame.inner()
- filter_frame.inspect(node.iter_child_nodes())
- aliases = self.push_scope(filter_frame)
- self.pull_locals(filter_frame)
- self.buffer(filter_frame)
- self.blockvisit(node.body, filter_frame)
- self.start_write(frame, node)
- self.visit_Filter(node.filter, filter_frame)
- self.end_write(frame)
- self.pop_scope(aliases, filter_frame)
-
- def visit_ExprStmt(self, node, frame):
- self.newline(node)
- self.visit(node.node, frame)
-
- def visit_Output(self, node, frame):
- # if we have a known extends statement, we don't output anything
- # if we are in a require_output_check section
- if self.has_known_extends and frame.require_output_check:
- return
-
- if self.environment.finalize:
- finalize = lambda x: unicode(self.environment.finalize(x))
- else:
- finalize = unicode
-
- # if we are inside a frame that requires output checking, we do so
- outdent_later = False
- if frame.require_output_check:
- self.writeline('if parent_template is None:')
- self.indent()
- outdent_later = True
-
- # try to evaluate as many chunks as possible into a static
- # string at compile time.
- body = []
- for child in node.nodes:
- try:
- const = child.as_const(frame.eval_ctx)
- except nodes.Impossible:
- body.append(child)
- continue
- # the frame can't be volatile here, becaus otherwise the
- # as_const() function would raise an Impossible exception
- # at that point.
- try:
- if frame.eval_ctx.autoescape:
- if hasattr(const, '__html__'):
- const = const.__html__()
- else:
- const = escape(const)
- const = finalize(const)
- except Exception:
- # if something goes wrong here we evaluate the node
- # at runtime for easier debugging
- body.append(child)
- continue
- if body and isinstance(body[-1], list):
- body[-1].append(const)
- else:
- body.append([const])
-
- # if we have less than 3 nodes or a buffer we yield or extend/append
- if len(body) < 3 or frame.buffer is not None:
- if frame.buffer is not None:
- # for one item we append, for more we extend
- if len(body) == 1:
- self.writeline('%s.append(' % frame.buffer)
- else:
- self.writeline('%s.extend((' % frame.buffer)
- self.indent()
- for item in body:
- if isinstance(item, list):
- val = repr(concat(item))
- if frame.buffer is None:
- self.writeline('yield ' + val)
- else:
- self.writeline(val + ', ')
- else:
- if frame.buffer is None:
- self.writeline('yield ', item)
- else:
- self.newline(item)
- close = 1
- if frame.eval_ctx.volatile:
- self.write('(context.eval_ctx.autoescape and'
- ' escape or to_string)(')
- elif frame.eval_ctx.autoescape:
- self.write('escape(')
- else:
- self.write('to_string(')
- if self.environment.finalize is not None:
- self.write('environment.finalize(')
- close += 1
- self.visit(item, frame)
- self.write(')' * close)
- if frame.buffer is not None:
- self.write(', ')
- if frame.buffer is not None:
- # close the open parentheses
- self.outdent()
- self.writeline(len(body) == 1 and ')' or '))')
-
- # otherwise we create a format string as this is faster in that case
- else:
- format = []
- arguments = []
- for item in body:
- if isinstance(item, list):
- format.append(concat(item).replace('%', '%%'))
- else:
- format.append('%s')
- arguments.append(item)
- self.writeline('yield ')
- self.write(repr(concat(format)) + ' % (')
- idx = -1
- self.indent()
- for argument in arguments:
- self.newline(argument)
- close = 0
- if frame.eval_ctx.volatile:
- self.write('(context.eval_ctx.autoescape and'
- ' escape or to_string)(')
- close += 1
- elif frame.eval_ctx.autoescape:
- self.write('escape(')
- close += 1
- if self.environment.finalize is not None:
- self.write('environment.finalize(')
- close += 1
- self.visit(argument, frame)
- self.write(')' * close + ', ')
- self.outdent()
- self.writeline(')')
-
- if outdent_later:
- self.outdent()
-
- def visit_Assign(self, node, frame):
- self.newline(node)
- # toplevel assignments however go into the local namespace and
- # the current template's context. We create a copy of the frame
- # here and add a set so that the Name visitor can add the assigned
- # names here.
- if frame.toplevel:
- assignment_frame = frame.copy()
- assignment_frame.toplevel_assignments = set()
- else:
- assignment_frame = frame
- self.visit(node.target, assignment_frame)
- self.write(' = ')
- self.visit(node.node, frame)
-
- # make sure toplevel assignments are added to the context.
- if frame.toplevel:
- public_names = [x for x in assignment_frame.toplevel_assignments
- if not x.startswith('_')]
- if len(assignment_frame.toplevel_assignments) == 1:
- name = next(iter(assignment_frame.toplevel_assignments))
- self.writeline('context.vars[%r] = l_%s' % (name, name))
- else:
- self.writeline('context.vars.update({')
- for idx, name in enumerate(assignment_frame.toplevel_assignments):
- if idx:
- self.write(', ')
- self.write('%r: l_%s' % (name, name))
- self.write('})')
- if public_names:
- if len(public_names) == 1:
- self.writeline('context.exported_vars.add(%r)' %
- public_names[0])
- else:
- self.writeline('context.exported_vars.update((%s))' %
- ', '.join(map(repr, public_names)))
-
- # -- Expression Visitors
-
- def visit_Name(self, node, frame):
- if node.ctx == 'store' and frame.toplevel:
- frame.toplevel_assignments.add(node.name)
- self.write('l_' + node.name)
- frame.assigned_names.add(node.name)
-
- def visit_Const(self, node, frame):
- val = node.value
- if isinstance(val, float):
- self.write(str(val))
- else:
- self.write(repr(val))
-
- def visit_TemplateData(self, node, frame):
- try:
- self.write(repr(node.as_const(frame.eval_ctx)))
- except nodes.Impossible:
- self.write('(context.eval_ctx.autoescape and Markup or identity)(%r)'
- % node.data)
-
- def visit_Tuple(self, node, frame):
- self.write('(')
- idx = -1
- for idx, item in enumerate(node.items):
- if idx:
- self.write(', ')
- self.visit(item, frame)
- self.write(idx == 0 and ',)' or ')')
-
- def visit_List(self, node, frame):
- self.write('[')
- for idx, item in enumerate(node.items):
- if idx:
- self.write(', ')
- self.visit(item, frame)
- self.write(']')
-
- def visit_Dict(self, node, frame):
- self.write('{')
- for idx, item in enumerate(node.items):
- if idx:
- self.write(', ')
- self.visit(item.key, frame)
- self.write(': ')
- self.visit(item.value, frame)
- self.write('}')
-
- def binop(operator, interceptable=True):
- def visitor(self, node, frame):
- if self.environment.sandboxed and \
- operator in self.environment.intercepted_binops:
- self.write('environment.call_binop(context, %r, ' % operator)
- self.visit(node.left, frame)
- self.write(', ')
- self.visit(node.right, frame)
- else:
- self.write('(')
- self.visit(node.left, frame)
- self.write(' %s ' % operator)
- self.visit(node.right, frame)
- self.write(')')
- return visitor
-
- def uaop(operator, interceptable=True):
- def visitor(self, node, frame):
- if self.environment.sandboxed and \
- operator in self.environment.intercepted_unops:
- self.write('environment.call_unop(context, %r, ' % operator)
- self.visit(node.node, frame)
- else:
- self.write('(' + operator)
- self.visit(node.node, frame)
- self.write(')')
- return visitor
-
- visit_Add = binop('+')
- visit_Sub = binop('-')
- visit_Mul = binop('*')
- visit_Div = binop('/')
- visit_FloorDiv = binop('//')
- visit_Pow = binop('**')
- visit_Mod = binop('%')
- visit_And = binop('and', interceptable=False)
- visit_Or = binop('or', interceptable=False)
- visit_Pos = uaop('+')
- visit_Neg = uaop('-')
- visit_Not = uaop('not ', interceptable=False)
- del binop, uaop
-
- def visit_Concat(self, node, frame):
- if frame.eval_ctx.volatile:
- func_name = '(context.eval_ctx.volatile and' \
- ' markup_join or unicode_join)'
- elif frame.eval_ctx.autoescape:
- func_name = 'markup_join'
- else:
- func_name = 'unicode_join'
- self.write('%s((' % func_name)
- for arg in node.nodes:
- self.visit(arg, frame)
- self.write(', ')
- self.write('))')
-
- def visit_Compare(self, node, frame):
- self.visit(node.expr, frame)
- for op in node.ops:
- self.visit(op, frame)
-
- def visit_Operand(self, node, frame):
- self.write(' %s ' % operators[node.op])
- self.visit(node.expr, frame)
-
- def visit_Getattr(self, node, frame):
- self.write('environment.getattr(')
- self.visit(node.node, frame)
- self.write(', %r)' % node.attr)
-
- def visit_Getitem(self, node, frame):
- # slices bypass the environment getitem method.
- if isinstance(node.arg, nodes.Slice):
- self.visit(node.node, frame)
- self.write('[')
- self.visit(node.arg, frame)
- self.write(']')
- else:
- self.write('environment.getitem(')
- self.visit(node.node, frame)
- self.write(', ')
- self.visit(node.arg, frame)
- self.write(')')
-
- def visit_Slice(self, node, frame):
- if node.start is not None:
- self.visit(node.start, frame)
- self.write(':')
- if node.stop is not None:
- self.visit(node.stop, frame)
- if node.step is not None:
- self.write(':')
- self.visit(node.step, frame)
-
- def visit_Filter(self, node, frame):
- self.write(self.filters[node.name] + '(')
- func = self.environment.filters.get(node.name)
- if func is None:
- self.fail('no filter named %r' % node.name, node.lineno)
- if getattr(func, 'contextfilter', False):
- self.write('context, ')
- elif getattr(func, 'evalcontextfilter', False):
- self.write('context.eval_ctx, ')
- elif getattr(func, 'environmentfilter', False):
- self.write('environment, ')
-
- # if the filter node is None we are inside a filter block
- # and want to write to the current buffer
- if node.node is not None:
- self.visit(node.node, frame)
- elif frame.eval_ctx.volatile:
- self.write('(context.eval_ctx.autoescape and'
- ' Markup(concat(%s)) or concat(%s))' %
- (frame.buffer, frame.buffer))
- elif frame.eval_ctx.autoescape:
- self.write('Markup(concat(%s))' % frame.buffer)
- else:
- self.write('concat(%s)' % frame.buffer)
- self.signature(node, frame)
- self.write(')')
-
- def visit_Test(self, node, frame):
- self.write(self.tests[node.name] + '(')
- if node.name not in self.environment.tests:
- self.fail('no test named %r' % node.name, node.lineno)
- self.visit(node.node, frame)
- self.signature(node, frame)
- self.write(')')
-
- def visit_CondExpr(self, node, frame):
- def write_expr2():
- if node.expr2 is not None:
- return self.visit(node.expr2, frame)
- self.write('environment.undefined(%r)' % ('the inline if-'
- 'expression on %s evaluated to false and '
- 'no else section was defined.' % self.position(node)))
-
- if not have_condexpr:
- self.write('((')
- self.visit(node.test, frame)
- self.write(') and (')
- self.visit(node.expr1, frame)
- self.write(',) or (')
- write_expr2()
- self.write(',))[0]')
- else:
- self.write('(')
- self.visit(node.expr1, frame)
- self.write(' if ')
- self.visit(node.test, frame)
- self.write(' else ')
- write_expr2()
- self.write(')')
-
- def visit_Call(self, node, frame, forward_caller=False):
- if self.environment.sandboxed:
- self.write('environment.call(context, ')
- else:
- self.write('context.call(')
- self.visit(node.node, frame)
- extra_kwargs = forward_caller and {'caller': 'caller'} or None
- self.signature(node, frame, extra_kwargs)
- self.write(')')
-
- def visit_Keyword(self, node, frame):
- self.write(node.key + '=')
- self.visit(node.value, frame)
-
- # -- Unused nodes for extensions
-
- def visit_MarkSafe(self, node, frame):
- self.write('Markup(')
- self.visit(node.expr, frame)
- self.write(')')
-
- def visit_MarkSafeIfAutoescape(self, node, frame):
- self.write('(context.eval_ctx.autoescape and Markup or identity)(')
- self.visit(node.expr, frame)
- self.write(')')
-
- def visit_EnvironmentAttribute(self, node, frame):
- self.write('environment.' + node.name)
-
- def visit_ExtensionAttribute(self, node, frame):
- self.write('environment.extensions[%r].%s' % (node.identifier, node.name))
-
- def visit_ImportedName(self, node, frame):
- self.write(self.import_aliases[node.importname])
-
- def visit_InternalName(self, node, frame):
- self.write(node.name)
-
- def visit_ContextReference(self, node, frame):
- self.write('context')
-
- def visit_Continue(self, node, frame):
- self.writeline('continue', node)
-
- def visit_Break(self, node, frame):
- self.writeline('break', node)
-
- def visit_Scope(self, node, frame):
- scope_frame = frame.inner()
- scope_frame.inspect(node.iter_child_nodes())
- aliases = self.push_scope(scope_frame)
- self.pull_locals(scope_frame)
- self.blockvisit(node.body, scope_frame)
- self.pop_scope(aliases, scope_frame)
-
- def visit_EvalContextModifier(self, node, frame):
- for keyword in node.options:
- self.writeline('context.eval_ctx.%s = ' % keyword.key)
- self.visit(keyword.value, frame)
- try:
- val = keyword.value.as_const(frame.eval_ctx)
- except nodes.Impossible:
- frame.eval_ctx.volatile = True
- else:
- setattr(frame.eval_ctx, keyword.key, val)
-
- def visit_ScopedEvalContextModifier(self, node, frame):
- old_ctx_name = self.temporary_identifier()
- safed_ctx = frame.eval_ctx.save()
- self.writeline('%s = context.eval_ctx.save()' % old_ctx_name)
- self.visit_EvalContextModifier(node, frame)
- for child in node.body:
- self.visit(child, frame)
- frame.eval_ctx.revert(safed_ctx)
- self.writeline('context.eval_ctx.revert(%s)' % old_ctx_name)
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/constants.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/constants.py
deleted file mode 100755
index cab203cc..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/constants.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja.constants
- ~~~~~~~~~~~~~~~
-
- Various constants.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-
-
-#: list of lorem ipsum words used by the lipsum() helper function
-LOREM_IPSUM_WORDS = u'''\
-a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at
-auctor augue bibendum blandit class commodo condimentum congue consectetuer
-consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus
-diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend
-elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames
-faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac
-hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum
-justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem
-luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie
-mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non
-nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque
-penatibus per pharetra phasellus placerat platea porta porttitor posuere
-potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus
-ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit
-sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor
-tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices
-ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus
-viverra volutpat vulputate'''
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/debug.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/debug.py
deleted file mode 100755
index 2af22223..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/debug.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.debug
- ~~~~~~~~~~~~
-
- Implements the debug interface for Jinja. This module does some pretty
- ugly stuff with the Python traceback system in order to achieve tracebacks
- with correct line numbers, locals and contents.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import sys
-import traceback
-from types import TracebackType
-from jinja2.utils import CodeType, missing, internal_code
-from jinja2.exceptions import TemplateSyntaxError
-
-# on pypy we can take advantage of transparent proxies
-try:
- from __pypy__ import tproxy
-except ImportError:
- tproxy = None
-
-
-# how does the raise helper look like?
-try:
- exec "raise TypeError, 'foo'"
-except SyntaxError:
- raise_helper = 'raise __jinja_exception__[1]'
-except TypeError:
- raise_helper = 'raise __jinja_exception__[0], __jinja_exception__[1]'
-
-
-class TracebackFrameProxy(object):
- """Proxies a traceback frame."""
-
- def __init__(self, tb):
- self.tb = tb
- self._tb_next = None
-
- @property
- def tb_next(self):
- return self._tb_next
-
- def set_next(self, next):
- if tb_set_next is not None:
- try:
- tb_set_next(self.tb, next and next.tb or None)
- except Exception:
- # this function can fail due to all the hackery it does
- # on various python implementations. We just catch errors
- # down and ignore them if necessary.
- pass
- self._tb_next = next
-
- @property
- def is_jinja_frame(self):
- return '__jinja_template__' in self.tb.tb_frame.f_globals
-
- def __getattr__(self, name):
- return getattr(self.tb, name)
-
-
-def make_frame_proxy(frame):
- proxy = TracebackFrameProxy(frame)
- if tproxy is None:
- return proxy
- def operation_handler(operation, *args, **kwargs):
- if operation in ('__getattribute__', '__getattr__'):
- return getattr(proxy, args[0])
- elif operation == '__setattr__':
- proxy.__setattr__(*args, **kwargs)
- else:
- return getattr(proxy, operation)(*args, **kwargs)
- return tproxy(TracebackType, operation_handler)
-
-
-class ProcessedTraceback(object):
- """Holds a Jinja preprocessed traceback for priting or reraising."""
-
- def __init__(self, exc_type, exc_value, frames):
- assert frames, 'no frames for this traceback?'
- self.exc_type = exc_type
- self.exc_value = exc_value
- self.frames = frames
-
- # newly concatenate the frames (which are proxies)
- prev_tb = None
- for tb in self.frames:
- if prev_tb is not None:
- prev_tb.set_next(tb)
- prev_tb = tb
- prev_tb.set_next(None)
-
- def render_as_text(self, limit=None):
- """Return a string with the traceback."""
- lines = traceback.format_exception(self.exc_type, self.exc_value,
- self.frames[0], limit=limit)
- return ''.join(lines).rstrip()
-
- def render_as_html(self, full=False):
- """Return a unicode string with the traceback as rendered HTML."""
- from jinja2.debugrenderer import render_traceback
- return u'%s\n\n<!--\n%s\n-->' % (
- render_traceback(self, full=full),
- self.render_as_text().decode('utf-8', 'replace')
- )
-
- @property
- def is_template_syntax_error(self):
- """`True` if this is a template syntax error."""
- return isinstance(self.exc_value, TemplateSyntaxError)
-
- @property
- def exc_info(self):
- """Exception info tuple with a proxy around the frame objects."""
- return self.exc_type, self.exc_value, self.frames[0]
-
- @property
- def standard_exc_info(self):
- """Standard python exc_info for re-raising"""
- tb = self.frames[0]
- # the frame will be an actual traceback (or transparent proxy) if
- # we are on pypy or a python implementation with support for tproxy
- if type(tb) is not TracebackType:
- tb = tb.tb
- return self.exc_type, self.exc_value, tb
-
-
-def make_traceback(exc_info, source_hint=None):
- """Creates a processed traceback object from the exc_info."""
- exc_type, exc_value, tb = exc_info
- if isinstance(exc_value, TemplateSyntaxError):
- exc_info = translate_syntax_error(exc_value, source_hint)
- initial_skip = 0
- else:
- initial_skip = 1
- return translate_exception(exc_info, initial_skip)
-
-
-def translate_syntax_error(error, source=None):
- """Rewrites a syntax error to please traceback systems."""
- error.source = source
- error.translated = True
- exc_info = (error.__class__, error, None)
- filename = error.filename
- if filename is None:
- filename = '<unknown>'
- return fake_exc_info(exc_info, filename, error.lineno)
-
-
-def translate_exception(exc_info, initial_skip=0):
- """If passed an exc_info it will automatically rewrite the exceptions
- all the way down to the correct line numbers and frames.
- """
- tb = exc_info[2]
- frames = []
-
- # skip some internal frames if wanted
- for x in xrange(initial_skip):
- if tb is not None:
- tb = tb.tb_next
- initial_tb = tb
-
- while tb is not None:
- # skip frames decorated with @internalcode. These are internal
- # calls we can't avoid and that are useless in template debugging
- # output.
- if tb.tb_frame.f_code in internal_code:
- tb = tb.tb_next
- continue
-
- # save a reference to the next frame if we override the current
- # one with a faked one.
- next = tb.tb_next
-
- # fake template exceptions
- template = tb.tb_frame.f_globals.get('__jinja_template__')
- if template is not None:
- lineno = template.get_corresponding_lineno(tb.tb_lineno)
- tb = fake_exc_info(exc_info[:2] + (tb,), template.filename,
- lineno)[2]
-
- frames.append(make_frame_proxy(tb))
- tb = next
-
- # if we don't have any exceptions in the frames left, we have to
- # reraise it unchanged.
- # XXX: can we backup here? when could this happen?
- if not frames:
- raise exc_info[0], exc_info[1], exc_info[2]
-
- return ProcessedTraceback(exc_info[0], exc_info[1], frames)
-
-
-def fake_exc_info(exc_info, filename, lineno):
- """Helper for `translate_exception`."""
- exc_type, exc_value, tb = exc_info
-
- # figure the real context out
- if tb is not None:
- real_locals = tb.tb_frame.f_locals.copy()
- ctx = real_locals.get('context')
- if ctx:
- locals = ctx.get_all()
- else:
- locals = {}
- for name, value in real_locals.iteritems():
- if name.startswith('l_') and value is not missing:
- locals[name[2:]] = value
-
- # if there is a local called __jinja_exception__, we get
- # rid of it to not break the debug functionality.
- locals.pop('__jinja_exception__', None)
- else:
- locals = {}
-
- # assamble fake globals we need
- globals = {
- '__name__': filename,
- '__file__': filename,
- '__jinja_exception__': exc_info[:2],
-
- # we don't want to keep the reference to the template around
- # to not cause circular dependencies, but we mark it as Jinja
- # frame for the ProcessedTraceback
- '__jinja_template__': None
- }
-
- # and fake the exception
- code = compile('\n' * (lineno - 1) + raise_helper, filename, 'exec')
-
- # if it's possible, change the name of the code. This won't work
- # on some python environments such as google appengine
- try:
- if tb is None:
- location = 'template'
- else:
- function = tb.tb_frame.f_code.co_name
- if function == 'root':
- location = 'top-level template code'
- elif function.startswith('block_'):
- location = 'block "%s"' % function[6:]
- else:
- location = 'template'
- code = CodeType(0, code.co_nlocals, code.co_stacksize,
- code.co_flags, code.co_code, code.co_consts,
- code.co_names, code.co_varnames, filename,
- location, code.co_firstlineno,
- code.co_lnotab, (), ())
- except:
- pass
-
- # execute the code and catch the new traceback
- try:
- exec code in globals, locals
- except:
- exc_info = sys.exc_info()
- new_tb = exc_info[2].tb_next
-
- # return without this frame
- return exc_info[:2] + (new_tb,)
-
-
-def _init_ugly_crap():
- """This function implements a few ugly things so that we can patch the
- traceback objects. The function returned allows resetting `tb_next` on
- any python traceback object. Do not attempt to use this on non cpython
- interpreters
- """
- import ctypes
- from types import TracebackType
-
- # figure out side of _Py_ssize_t
- if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'):
- _Py_ssize_t = ctypes.c_int64
- else:
- _Py_ssize_t = ctypes.c_int
-
- # regular python
- class _PyObject(ctypes.Structure):
- pass
- _PyObject._fields_ = [
- ('ob_refcnt', _Py_ssize_t),
- ('ob_type', ctypes.POINTER(_PyObject))
- ]
-
- # python with trace
- if hasattr(sys, 'getobjects'):
- class _PyObject(ctypes.Structure):
- pass
- _PyObject._fields_ = [
- ('_ob_next', ctypes.POINTER(_PyObject)),
- ('_ob_prev', ctypes.POINTER(_PyObject)),
- ('ob_refcnt', _Py_ssize_t),
- ('ob_type', ctypes.POINTER(_PyObject))
- ]
-
- class _Traceback(_PyObject):
- pass
- _Traceback._fields_ = [
- ('tb_next', ctypes.POINTER(_Traceback)),
- ('tb_frame', ctypes.POINTER(_PyObject)),
- ('tb_lasti', ctypes.c_int),
- ('tb_lineno', ctypes.c_int)
- ]
-
- def tb_set_next(tb, next):
- """Set the tb_next attribute of a traceback object."""
- if not (isinstance(tb, TracebackType) and
- (next is None or isinstance(next, TracebackType))):
- raise TypeError('tb_set_next arguments must be traceback objects')
- obj = _Traceback.from_address(id(tb))
- if tb.tb_next is not None:
- old = _Traceback.from_address(id(tb.tb_next))
- old.ob_refcnt -= 1
- if next is None:
- obj.tb_next = ctypes.POINTER(_Traceback)()
- else:
- next = _Traceback.from_address(id(next))
- next.ob_refcnt += 1
- obj.tb_next = ctypes.pointer(next)
-
- return tb_set_next
-
-
-# try to get a tb_set_next implementation if we don't have transparent
-# proxies.
-tb_set_next = None
-if tproxy is None:
- try:
- from jinja2._debugsupport import tb_set_next
- except ImportError:
- try:
- tb_set_next = _init_ugly_crap()
- except:
- pass
- del _init_ugly_crap
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/defaults.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/defaults.py
deleted file mode 100755
index d2d45443..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/defaults.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.defaults
- ~~~~~~~~~~~~~~~
-
- Jinja default filters and tags.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-from jinja2.utils import generate_lorem_ipsum, Cycler, Joiner
-
-
-# defaults for the parser / lexer
-BLOCK_START_STRING = '{%'
-BLOCK_END_STRING = '%}'
-VARIABLE_START_STRING = '{{'
-VARIABLE_END_STRING = '}}'
-COMMENT_START_STRING = '{#'
-COMMENT_END_STRING = '#}'
-LINE_STATEMENT_PREFIX = None
-LINE_COMMENT_PREFIX = None
-TRIM_BLOCKS = False
-NEWLINE_SEQUENCE = '\n'
-
-
-# default filters, tests and namespace
-from jinja2.filters import FILTERS as DEFAULT_FILTERS
-from jinja2.tests import TESTS as DEFAULT_TESTS
-DEFAULT_NAMESPACE = {
- 'range': xrange,
- 'dict': lambda **kw: kw,
- 'lipsum': generate_lorem_ipsum,
- 'cycler': Cycler,
- 'joiner': Joiner
-}
-
-
-# export all constants
-__all__ = tuple(x for x in locals().keys() if x.isupper())
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py
deleted file mode 100755
index 7a9a59fc..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py
+++ /dev/null
@@ -1,1121 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.environment
- ~~~~~~~~~~~~~~~~~~
-
- Provides a class that holds runtime and parsing time options.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import os
-import sys
-from jinja2 import nodes
-from jinja2.defaults import *
-from jinja2.lexer import get_lexer, TokenStream
-from jinja2.parser import Parser
-from jinja2.optimizer import optimize
-from jinja2.compiler import generate
-from jinja2.runtime import Undefined, new_context
-from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \
- TemplatesNotFound
-from jinja2.utils import import_string, LRUCache, Markup, missing, \
- concat, consume, internalcode, _encode_filename
-
-
-# for direct template usage we have up to ten living environments
-_spontaneous_environments = LRUCache(10)
-
-# the function to create jinja traceback objects. This is dynamically
-# imported on the first exception in the exception handler.
-_make_traceback = None
-
-
-def get_spontaneous_environment(*args):
- """Return a new spontaneous environment. A spontaneous environment is an
- unnamed and unaccessible (in theory) environment that is used for
- templates generated from a string and not from the file system.
- """
- try:
- env = _spontaneous_environments.get(args)
- except TypeError:
- return Environment(*args)
- if env is not None:
- return env
- _spontaneous_environments[args] = env = Environment(*args)
- env.shared = True
- return env
-
-
-def create_cache(size):
- """Return the cache class for the given size."""
- if size == 0:
- return None
- if size < 0:
- return {}
- return LRUCache(size)
-
-
-def copy_cache(cache):
- """Create an empty copy of the given cache."""
- if cache is None:
- return None
- elif type(cache) is dict:
- return {}
- return LRUCache(cache.capacity)
-
-
-def load_extensions(environment, extensions):
- """Load the extensions from the list and bind it to the environment.
- Returns a dict of instanciated environments.
- """
- result = {}
- for extension in extensions:
- if isinstance(extension, basestring):
- extension = import_string(extension)
- result[extension.identifier] = extension(environment)
- return result
-
-
-def _environment_sanity_check(environment):
- """Perform a sanity check on the environment."""
- assert issubclass(environment.undefined, Undefined), 'undefined must ' \
- 'be a subclass of undefined because filters depend on it.'
- assert environment.block_start_string != \
- environment.variable_start_string != \
- environment.comment_start_string, 'block, variable and comment ' \
- 'start strings must be different'
- assert environment.newline_sequence in ('\r', '\r\n', '\n'), \
- 'newline_sequence set to unknown line ending string.'
- return environment
-
-
-class Environment(object):
- r"""The core component of Jinja is the `Environment`. It contains
- important shared variables like configuration, filters, tests,
- globals and others. Instances of this class may be modified if
- they are not shared and if no template was loaded so far.
- Modifications on environments after the first template was loaded
- will lead to surprising effects and undefined behavior.
-
- Here the possible initialization parameters:
-
- `block_start_string`
- The string marking the begin of a block. Defaults to ``'{%'``.
-
- `block_end_string`
- The string marking the end of a block. Defaults to ``'%}'``.
-
- `variable_start_string`
- The string marking the begin of a print statement.
- Defaults to ``'{{'``.
-
- `variable_end_string`
- The string marking the end of a print statement. Defaults to
- ``'}}'``.
-
- `comment_start_string`
- The string marking the begin of a comment. Defaults to ``'{#'``.
-
- `comment_end_string`
- The string marking the end of a comment. Defaults to ``'#}'``.
-
- `line_statement_prefix`
- If given and a string, this will be used as prefix for line based
- statements. See also :ref:`line-statements`.
-
- `line_comment_prefix`
- If given and a string, this will be used as prefix for line based
- based comments. See also :ref:`line-statements`.
-
- .. versionadded:: 2.2
-
- `trim_blocks`
- If this is set to ``True`` the first newline after a block is
- removed (block, not variable tag!). Defaults to `False`.
-
- `newline_sequence`
- The sequence that starts a newline. Must be one of ``'\r'``,
- ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a
- useful default for Linux and OS X systems as well as web
- applications.
-
- `extensions`
- List of Jinja extensions to use. This can either be import paths
- as strings or extension classes. For more information have a
- look at :ref:`the extensions documentation <jinja-extensions>`.
-
- `optimized`
- should the optimizer be enabled? Default is `True`.
-
- `undefined`
- :class:`Undefined` or a subclass of it that is used to represent
- undefined values in the template.
-
- `finalize`
- A callable that can be used to process the result of a variable
- expression before it is output. For example one can convert
- `None` implicitly into an empty string here.
-
- `autoescape`
- If set to true the XML/HTML autoescaping feature is enabled by
- default. For more details about auto escaping see
- :class:`~jinja2.utils.Markup`. As of Jinja 2.4 this can also
- be a callable that is passed the template name and has to
- return `True` or `False` depending on autoescape should be
- enabled by default.
-
- .. versionchanged:: 2.4
- `autoescape` can now be a function
-
- `loader`
- The template loader for this environment.
-
- `cache_size`
- The size of the cache. Per default this is ``50`` which means
- that if more than 50 templates are loaded the loader will clean
- out the least recently used template. If the cache size is set to
- ``0`` templates are recompiled all the time, if the cache size is
- ``-1`` the cache will not be cleaned.
-
- `auto_reload`
- Some loaders load templates from locations where the template
- sources may change (ie: file system or database). If
- `auto_reload` is set to `True` (default) every time a template is
- requested the loader checks if the source changed and if yes, it
- will reload the template. For higher performance it's possible to
- disable that.
-
- `bytecode_cache`
- If set to a bytecode cache object, this object will provide a
- cache for the internal Jinja bytecode so that templates don't
- have to be parsed if they were not changed.
-
- See :ref:`bytecode-cache` for more information.
- """
-
- #: if this environment is sandboxed. Modifying this variable won't make
- #: the environment sandboxed though. For a real sandboxed environment
- #: have a look at jinja2.sandbox. This flag alone controls the code
- #: generation by the compiler.
- sandboxed = False
-
- #: True if the environment is just an overlay
- overlayed = False
-
- #: the environment this environment is linked to if it is an overlay
- linked_to = None
-
- #: shared environments have this set to `True`. A shared environment
- #: must not be modified
- shared = False
-
- #: these are currently EXPERIMENTAL undocumented features.
- exception_handler = None
- exception_formatter = None
-
- def __init__(self,
- block_start_string=BLOCK_START_STRING,
- block_end_string=BLOCK_END_STRING,
- variable_start_string=VARIABLE_START_STRING,
- variable_end_string=VARIABLE_END_STRING,
- comment_start_string=COMMENT_START_STRING,
- comment_end_string=COMMENT_END_STRING,
- line_statement_prefix=LINE_STATEMENT_PREFIX,
- line_comment_prefix=LINE_COMMENT_PREFIX,
- trim_blocks=TRIM_BLOCKS,
- newline_sequence=NEWLINE_SEQUENCE,
- extensions=(),
- optimized=True,
- undefined=Undefined,
- finalize=None,
- autoescape=False,
- loader=None,
- cache_size=50,
- auto_reload=True,
- bytecode_cache=None):
- # !!Important notice!!
- # The constructor accepts quite a few arguments that should be
- # passed by keyword rather than position. However it's important to
- # not change the order of arguments because it's used at least
- # internally in those cases:
- # - spontaneus environments (i18n extension and Template)
- # - unittests
- # If parameter changes are required only add parameters at the end
- # and don't change the arguments (or the defaults!) of the arguments
- # existing already.
-
- # lexer / parser information
- self.block_start_string = block_start_string
- self.block_end_string = block_end_string
- self.variable_start_string = variable_start_string
- self.variable_end_string = variable_end_string
- self.comment_start_string = comment_start_string
- self.comment_end_string = comment_end_string
- self.line_statement_prefix = line_statement_prefix
- self.line_comment_prefix = line_comment_prefix
- self.trim_blocks = trim_blocks
- self.newline_sequence = newline_sequence
-
- # runtime information
- self.undefined = undefined
- self.optimized = optimized
- self.finalize = finalize
- self.autoescape = autoescape
-
- # defaults
- self.filters = DEFAULT_FILTERS.copy()
- self.tests = DEFAULT_TESTS.copy()
- self.globals = DEFAULT_NAMESPACE.copy()
-
- # set the loader provided
- self.loader = loader
- self.bytecode_cache = None
- self.cache = create_cache(cache_size)
- self.bytecode_cache = bytecode_cache
- self.auto_reload = auto_reload
-
- # load extensions
- self.extensions = load_extensions(self, extensions)
-
- _environment_sanity_check(self)
-
- def add_extension(self, extension):
- """Adds an extension after the environment was created.
-
- .. versionadded:: 2.5
- """
- self.extensions.update(load_extensions(self, [extension]))
-
- def extend(self, **attributes):
- """Add the items to the instance of the environment if they do not exist
- yet. This is used by :ref:`extensions <writing-extensions>` to register
- callbacks and configuration values without breaking inheritance.
- """
- for key, value in attributes.iteritems():
- if not hasattr(self, key):
- setattr(self, key, value)
-
- def overlay(self, block_start_string=missing, block_end_string=missing,
- variable_start_string=missing, variable_end_string=missing,
- comment_start_string=missing, comment_end_string=missing,
- line_statement_prefix=missing, line_comment_prefix=missing,
- trim_blocks=missing, extensions=missing, optimized=missing,
- undefined=missing, finalize=missing, autoescape=missing,
- loader=missing, cache_size=missing, auto_reload=missing,
- bytecode_cache=missing):
- """Create a new overlay environment that shares all the data with the
- current environment except of cache and the overridden attributes.
- Extensions cannot be removed for an overlayed environment. An overlayed
- environment automatically gets all the extensions of the environment it
- is linked to plus optional extra extensions.
-
- Creating overlays should happen after the initial environment was set
- up completely. Not all attributes are truly linked, some are just
- copied over so modifications on the original environment may not shine
- through.
- """
- args = dict(locals())
- del args['self'], args['cache_size'], args['extensions']
-
- rv = object.__new__(self.__class__)
- rv.__dict__.update(self.__dict__)
- rv.overlayed = True
- rv.linked_to = self
-
- for key, value in args.iteritems():
- if value is not missing:
- setattr(rv, key, value)
-
- if cache_size is not missing:
- rv.cache = create_cache(cache_size)
- else:
- rv.cache = copy_cache(self.cache)
-
- rv.extensions = {}
- for key, value in self.extensions.iteritems():
- rv.extensions[key] = value.bind(rv)
- if extensions is not missing:
- rv.extensions.update(load_extensions(rv, extensions))
-
- return _environment_sanity_check(rv)
-
- lexer = property(get_lexer, doc="The lexer for this environment.")
-
- def iter_extensions(self):
- """Iterates over the extensions by priority."""
- return iter(sorted(self.extensions.values(),
- key=lambda x: x.priority))
-
- def getitem(self, obj, argument):
- """Get an item or attribute of an object but prefer the item."""
- try:
- return obj[argument]
- except (TypeError, LookupError):
- if isinstance(argument, basestring):
- try:
- attr = str(argument)
- except Exception:
- pass
- else:
- try:
- return getattr(obj, attr)
- except AttributeError:
- pass
- return self.undefined(obj=obj, name=argument)
-
- def getattr(self, obj, attribute):
- """Get an item or attribute of an object but prefer the attribute.
- Unlike :meth:`getitem` the attribute *must* be a bytestring.
- """
- try:
- return getattr(obj, attribute)
- except AttributeError:
- pass
- try:
- return obj[attribute]
- except (TypeError, LookupError, AttributeError):
- return self.undefined(obj=obj, name=attribute)
-
- @internalcode
- def parse(self, source, name=None, filename=None):
- """Parse the sourcecode and return the abstract syntax tree. This
- tree of nodes is used by the compiler to convert the template into
- executable source- or bytecode. This is useful for debugging or to
- extract information from templates.
-
- If you are :ref:`developing Jinja2 extensions <writing-extensions>`
- this gives you a good overview of the node tree generated.
- """
- try:
- return self._parse(source, name, filename)
- except TemplateSyntaxError:
- exc_info = sys.exc_info()
- self.handle_exception(exc_info, source_hint=source)
-
- def _parse(self, source, name, filename):
- """Internal parsing function used by `parse` and `compile`."""
- return Parser(self, source, name, _encode_filename(filename)).parse()
-
- def lex(self, source, name=None, filename=None):
- """Lex the given sourcecode and return a generator that yields
- tokens as tuples in the form ``(lineno, token_type, value)``.
- This can be useful for :ref:`extension development <writing-extensions>`
- and debugging templates.
-
- This does not perform preprocessing. If you want the preprocessing
- of the extensions to be applied you have to filter source through
- the :meth:`preprocess` method.
- """
- source = unicode(source)
- try:
- return self.lexer.tokeniter(source, name, filename)
- except TemplateSyntaxError:
- exc_info = sys.exc_info()
- self.handle_exception(exc_info, source_hint=source)
-
- def preprocess(self, source, name=None, filename=None):
- """Preprocesses the source with all extensions. This is automatically
- called for all parsing and compiling methods but *not* for :meth:`lex`
- because there you usually only want the actual source tokenized.
- """
- return reduce(lambda s, e: e.preprocess(s, name, filename),
- self.iter_extensions(), unicode(source))
-
- def _tokenize(self, source, name, filename=None, state=None):
- """Called by the parser to do the preprocessing and filtering
- for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`.
- """
- source = self.preprocess(source, name, filename)
- stream = self.lexer.tokenize(source, name, filename, state)
- for ext in self.iter_extensions():
- stream = ext.filter_stream(stream)
- if not isinstance(stream, TokenStream):
- stream = TokenStream(stream, name, filename)
- return stream
-
- def _generate(self, source, name, filename, defer_init=False):
- """Internal hook that can be overriden to hook a different generate
- method in.
-
- .. versionadded:: 2.5
- """
- return generate(source, self, name, filename, defer_init=defer_init)
-
- def _compile(self, source, filename):
- """Internal hook that can be overriden to hook a different compile
- method in.
-
- .. versionadded:: 2.5
- """
- return compile(source, filename, 'exec')
-
- @internalcode
- def compile(self, source, name=None, filename=None, raw=False,
- defer_init=False):
- """Compile a node or template source code. The `name` parameter is
- the load name of the template after it was joined using
- :meth:`join_path` if necessary, not the filename on the file system.
- the `filename` parameter is the estimated filename of the template on
- the file system. If the template came from a database or memory this
- can be omitted.
-
- The return value of this method is a python code object. If the `raw`
- parameter is `True` the return value will be a string with python
- code equivalent to the bytecode returned otherwise. This method is
- mainly used internally.
-
- `defer_init` is use internally to aid the module code generator. This
- causes the generated code to be able to import without the global
- environment variable to be set.
-
- .. versionadded:: 2.4
- `defer_init` parameter added.
- """
- source_hint = None
- try:
- if isinstance(source, basestring):
- source_hint = source
- source = self._parse(source, name, filename)
- if self.optimized:
- source = optimize(source, self)
- source = self._generate(source, name, filename,
- defer_init=defer_init)
- if raw:
- return source
- if filename is None:
- filename = '<template>'
- else:
- filename = _encode_filename(filename)
- return self._compile(source, filename)
- except TemplateSyntaxError:
- exc_info = sys.exc_info()
- self.handle_exception(exc_info, source_hint=source)
-
- def compile_expression(self, source, undefined_to_none=True):
- """A handy helper method that returns a callable that accepts keyword
- arguments that appear as variables in the expression. If called it
- returns the result of the expression.
-
- This is useful if applications want to use the same rules as Jinja
- in template "configuration files" or similar situations.
-
- Example usage:
-
- >>> env = Environment()
- >>> expr = env.compile_expression('foo == 42')
- >>> expr(foo=23)
- False
- >>> expr(foo=42)
- True
-
- Per default the return value is converted to `None` if the
- expression returns an undefined value. This can be changed
- by setting `undefined_to_none` to `False`.
-
- >>> env.compile_expression('var')() is None
- True
- >>> env.compile_expression('var', undefined_to_none=False)()
- Undefined
-
- .. versionadded:: 2.1
- """
- parser = Parser(self, source, state='variable')
- exc_info = None
- try:
- expr = parser.parse_expression()
- if not parser.stream.eos:
- raise TemplateSyntaxError('chunk after expression',
- parser.stream.current.lineno,
- None, None)
- expr.set_environment(self)
- except TemplateSyntaxError:
- exc_info = sys.exc_info()
- if exc_info is not None:
- self.handle_exception(exc_info, source_hint=source)
- body = [nodes.Assign(nodes.Name('result', 'store'), expr, lineno=1)]
- template = self.from_string(nodes.Template(body, lineno=1))
- return TemplateExpression(template, undefined_to_none)
-
- def compile_templates(self, target, extensions=None, filter_func=None,
- zip='deflated', log_function=None,
- ignore_errors=True, py_compile=False):
- """Finds all the templates the loader can find, compiles them
- and stores them in `target`. If `zip` is `None`, instead of in a
- zipfile, the templates will be will be stored in a directory.
- By default a deflate zip algorithm is used, to switch to
- the stored algorithm, `zip` can be set to ``'stored'``.
-
- `extensions` and `filter_func` are passed to :meth:`list_templates`.
- Each template returned will be compiled to the target folder or
- zipfile.
-
- By default template compilation errors are ignored. In case a
- log function is provided, errors are logged. If you want template
- syntax errors to abort the compilation you can set `ignore_errors`
- to `False` and you will get an exception on syntax errors.
-
- If `py_compile` is set to `True` .pyc files will be written to the
- target instead of standard .py files.
-
- .. versionadded:: 2.4
- """
- from jinja2.loaders import ModuleLoader
-
- if log_function is None:
- log_function = lambda x: None
-
- if py_compile:
- import imp, marshal
- py_header = imp.get_magic() + \
- u'\xff\xff\xff\xff'.encode('iso-8859-15')
-
- def write_file(filename, data, mode):
- if zip:
- info = ZipInfo(filename)
- info.external_attr = 0755 << 16L
- zip_file.writestr(info, data)
- else:
- f = open(os.path.join(target, filename), mode)
- try:
- f.write(data)
- finally:
- f.close()
-
- if zip is not None:
- from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED
- zip_file = ZipFile(target, 'w', dict(deflated=ZIP_DEFLATED,
- stored=ZIP_STORED)[zip])
- log_function('Compiling into Zip archive "%s"' % target)
- else:
- if not os.path.isdir(target):
- os.makedirs(target)
- log_function('Compiling into folder "%s"' % target)
-
- try:
- for name in self.list_templates(extensions, filter_func):
- source, filename, _ = self.loader.get_source(self, name)
- try:
- code = self.compile(source, name, filename, True, True)
- except TemplateSyntaxError, e:
- if not ignore_errors:
- raise
- log_function('Could not compile "%s": %s' % (name, e))
- continue
-
- filename = ModuleLoader.get_module_filename(name)
-
- if py_compile:
- c = self._compile(code, _encode_filename(filename))
- write_file(filename + 'c', py_header +
- marshal.dumps(c), 'wb')
- log_function('Byte-compiled "%s" as %s' %
- (name, filename + 'c'))
- else:
- write_file(filename, code, 'w')
- log_function('Compiled "%s" as %s' % (name, filename))
- finally:
- if zip:
- zip_file.close()
-
- log_function('Finished compiling templates')
-
- def list_templates(self, extensions=None, filter_func=None):
- """Returns a list of templates for this environment. This requires
- that the loader supports the loader's
- :meth:`~BaseLoader.list_templates` method.
-
- If there are other files in the template folder besides the
- actual templates, the returned list can be filtered. There are two
- ways: either `extensions` is set to a list of file extensions for
- templates, or a `filter_func` can be provided which is a callable that
- is passed a template name and should return `True` if it should end up
- in the result list.
-
- If the loader does not support that, a :exc:`TypeError` is raised.
-
- .. versionadded:: 2.4
- """
- x = self.loader.list_templates()
- if extensions is not None:
- if filter_func is not None:
- raise TypeError('either extensions or filter_func '
- 'can be passed, but not both')
- filter_func = lambda x: '.' in x and \
- x.rsplit('.', 1)[1] in extensions
- if filter_func is not None:
- x = filter(filter_func, x)
- return x
-
- def handle_exception(self, exc_info=None, rendered=False, source_hint=None):
- """Exception handling helper. This is used internally to either raise
- rewritten exceptions or return a rendered traceback for the template.
- """
- global _make_traceback
- if exc_info is None:
- exc_info = sys.exc_info()
-
- # the debugging module is imported when it's used for the first time.
- # we're doing a lot of stuff there and for applications that do not
- # get any exceptions in template rendering there is no need to load
- # all of that.
- if _make_traceback is None:
- from jinja2.debug import make_traceback as _make_traceback
- traceback = _make_traceback(exc_info, source_hint)
- if rendered and self.exception_formatter is not None:
- return self.exception_formatter(traceback)
- if self.exception_handler is not None:
- self.exception_handler(traceback)
- exc_type, exc_value, tb = traceback.standard_exc_info
- raise exc_type, exc_value, tb
-
- def join_path(self, template, parent):
- """Join a template with the parent. By default all the lookups are
- relative to the loader root so this method returns the `template`
- parameter unchanged, but if the paths should be relative to the
- parent template, this function can be used to calculate the real
- template name.
-
- Subclasses may override this method and implement template path
- joining here.
- """
- return template
-
- @internalcode
- def _load_template(self, name, globals):
- if self.loader is None:
- raise TypeError('no loader for this environment specified')
- if self.cache is not None:
- template = self.cache.get(name)
- if template is not None and (not self.auto_reload or \
- template.is_up_to_date):
- return template
- template = self.loader.load(self, name, globals)
- if self.cache is not None:
- self.cache[name] = template
- return template
-
- @internalcode
- def get_template(self, name, parent=None, globals=None):
- """Load a template from the loader. If a loader is configured this
- method ask the loader for the template and returns a :class:`Template`.
- If the `parent` parameter is not `None`, :meth:`join_path` is called
- to get the real template name before loading.
-
- The `globals` parameter can be used to provide template wide globals.
- These variables are available in the context at render time.
-
- If the template does not exist a :exc:`TemplateNotFound` exception is
- raised.
-
- .. versionchanged:: 2.4
- If `name` is a :class:`Template` object it is returned from the
- function unchanged.
- """
- if isinstance(name, Template):
- return name
- if parent is not None:
- name = self.join_path(name, parent)
- return self._load_template(name, self.make_globals(globals))
-
- @internalcode
- def select_template(self, names, parent=None, globals=None):
- """Works like :meth:`get_template` but tries a number of templates
- before it fails. If it cannot find any of the templates, it will
- raise a :exc:`TemplatesNotFound` exception.
-
- .. versionadded:: 2.3
-
- .. versionchanged:: 2.4
- If `names` contains a :class:`Template` object it is returned
- from the function unchanged.
- """
- if not names:
- raise TemplatesNotFound(message=u'Tried to select from an empty list '
- u'of templates.')
- globals = self.make_globals(globals)
- for name in names:
- if isinstance(name, Template):
- return name
- if parent is not None:
- name = self.join_path(name, parent)
- try:
- return self._load_template(name, globals)
- except TemplateNotFound:
- pass
- raise TemplatesNotFound(names)
-
- @internalcode
- def get_or_select_template(self, template_name_or_list,
- parent=None, globals=None):
- """Does a typecheck and dispatches to :meth:`select_template`
- if an iterable of template names is given, otherwise to
- :meth:`get_template`.
-
- .. versionadded:: 2.3
- """
- if isinstance(template_name_or_list, basestring):
- return self.get_template(template_name_or_list, parent, globals)
- elif isinstance(template_name_or_list, Template):
- return template_name_or_list
- return self.select_template(template_name_or_list, parent, globals)
-
- def from_string(self, source, globals=None, template_class=None):
- """Load a template from a string. This parses the source given and
- returns a :class:`Template` object.
- """
- globals = self.make_globals(globals)
- cls = template_class or self.template_class
- return cls.from_code(self, self.compile(source), globals, None)
-
- def make_globals(self, d):
- """Return a dict for the globals."""
- if not d:
- return self.globals
- return dict(self.globals, **d)
-
-
-class Template(object):
- """The central template object. This class represents a compiled template
- and is used to evaluate it.
-
- Normally the template object is generated from an :class:`Environment` but
- it also has a constructor that makes it possible to create a template
- instance directly using the constructor. It takes the same arguments as
- the environment constructor but it's not possible to specify a loader.
-
- Every template object has a few methods and members that are guaranteed
- to exist. However it's important that a template object should be
- considered immutable. Modifications on the object are not supported.
-
- Template objects created from the constructor rather than an environment
- do have an `environment` attribute that points to a temporary environment
- that is probably shared with other templates created with the constructor
- and compatible settings.
-
- >>> template = Template('Hello {{ name }}!')
- >>> template.render(name='John Doe')
- u'Hello John Doe!'
-
- >>> stream = template.stream(name='John Doe')
- >>> stream.next()
- u'Hello John Doe!'
- >>> stream.next()
- Traceback (most recent call last):
- ...
- StopIteration
- """
-
- def __new__(cls, source,
- block_start_string=BLOCK_START_STRING,
- block_end_string=BLOCK_END_STRING,
- variable_start_string=VARIABLE_START_STRING,
- variable_end_string=VARIABLE_END_STRING,
- comment_start_string=COMMENT_START_STRING,
- comment_end_string=COMMENT_END_STRING,
- line_statement_prefix=LINE_STATEMENT_PREFIX,
- line_comment_prefix=LINE_COMMENT_PREFIX,
- trim_blocks=TRIM_BLOCKS,
- newline_sequence=NEWLINE_SEQUENCE,
- extensions=(),
- optimized=True,
- undefined=Undefined,
- finalize=None,
- autoescape=False):
- env = get_spontaneous_environment(
- block_start_string, block_end_string, variable_start_string,
- variable_end_string, comment_start_string, comment_end_string,
- line_statement_prefix, line_comment_prefix, trim_blocks,
- newline_sequence, frozenset(extensions), optimized, undefined,
- finalize, autoescape, None, 0, False, None)
- return env.from_string(source, template_class=cls)
-
- @classmethod
- def from_code(cls, environment, code, globals, uptodate=None):
- """Creates a template object from compiled code and the globals. This
- is used by the loaders and environment to create a template object.
- """
- namespace = {
- 'environment': environment,
- '__file__': code.co_filename
- }
- exec code in namespace
- rv = cls._from_namespace(environment, namespace, globals)
- rv._uptodate = uptodate
- return rv
-
- @classmethod
- def from_module_dict(cls, environment, module_dict, globals):
- """Creates a template object from a module. This is used by the
- module loader to create a template object.
-
- .. versionadded:: 2.4
- """
- return cls._from_namespace(environment, module_dict, globals)
-
- @classmethod
- def _from_namespace(cls, environment, namespace, globals):
- t = object.__new__(cls)
- t.environment = environment
- t.globals = globals
- t.name = namespace['name']
- t.filename = namespace['__file__']
- t.blocks = namespace['blocks']
-
- # render function and module
- t.root_render_func = namespace['root']
- t._module = None
-
- # debug and loader helpers
- t._debug_info = namespace['debug_info']
- t._uptodate = None
-
- # store the reference
- namespace['environment'] = environment
- namespace['__jinja_template__'] = t
-
- return t
-
- def render(self, *args, **kwargs):
- """This method accepts the same arguments as the `dict` constructor:
- A dict, a dict subclass or some keyword arguments. If no arguments
- are given the context will be empty. These two calls do the same::
-
- template.render(knights='that say nih')
- template.render({'knights': 'that say nih'})
-
- This will return the rendered template as unicode string.
- """
- vars = dict(*args, **kwargs)
- try:
- return concat(self.root_render_func(self.new_context(vars)))
- except Exception:
- exc_info = sys.exc_info()
- return self.environment.handle_exception(exc_info, True)
-
- def stream(self, *args, **kwargs):
- """Works exactly like :meth:`generate` but returns a
- :class:`TemplateStream`.
- """
- return TemplateStream(self.generate(*args, **kwargs))
-
- def generate(self, *args, **kwargs):
- """For very large templates it can be useful to not render the whole
- template at once but evaluate each statement after another and yield
- piece for piece. This method basically does exactly that and returns
- a generator that yields one item after another as unicode strings.
-
- It accepts the same arguments as :meth:`render`.
- """
- vars = dict(*args, **kwargs)
- try:
- for event in self.root_render_func(self.new_context(vars)):
- yield event
- except Exception:
- exc_info = sys.exc_info()
- else:
- return
- yield self.environment.handle_exception(exc_info, True)
-
- def new_context(self, vars=None, shared=False, locals=None):
- """Create a new :class:`Context` for this template. The vars
- provided will be passed to the template. Per default the globals
- are added to the context. If shared is set to `True` the data
- is passed as it to the context without adding the globals.
-
- `locals` can be a dict of local variables for internal usage.
- """
- return new_context(self.environment, self.name, self.blocks,
- vars, shared, self.globals, locals)
-
- def make_module(self, vars=None, shared=False, locals=None):
- """This method works like the :attr:`module` attribute when called
- without arguments but it will evaluate the template on every call
- rather than caching it. It's also possible to provide
- a dict which is then used as context. The arguments are the same
- as for the :meth:`new_context` method.
- """
- return TemplateModule(self, self.new_context(vars, shared, locals))
-
- @property
- def module(self):
- """The template as module. This is used for imports in the
- template runtime but is also useful if one wants to access
- exported template variables from the Python layer:
-
- >>> t = Template('{% macro foo() %}42{% endmacro %}23')
- >>> unicode(t.module)
- u'23'
- >>> t.module.foo()
- u'42'
- """
- if self._module is not None:
- return self._module
- self._module = rv = self.make_module()
- return rv
-
- def get_corresponding_lineno(self, lineno):
- """Return the source line number of a line number in the
- generated bytecode as they are not in sync.
- """
- for template_line, code_line in reversed(self.debug_info):
- if code_line <= lineno:
- return template_line
- return 1
-
- @property
- def is_up_to_date(self):
- """If this variable is `False` there is a newer version available."""
- if self._uptodate is None:
- return True
- return self._uptodate()
-
- @property
- def debug_info(self):
- """The debug info mapping."""
- return [tuple(map(int, x.split('='))) for x in
- self._debug_info.split('&')]
-
- def __repr__(self):
- if self.name is None:
- name = 'memory:%x' % id(self)
- else:
- name = repr(self.name)
- return '<%s %s>' % (self.__class__.__name__, name)
-
-
-class TemplateModule(object):
- """Represents an imported template. All the exported names of the
- template are available as attributes on this object. Additionally
- converting it into an unicode- or bytestrings renders the contents.
- """
-
- def __init__(self, template, context):
- self._body_stream = list(template.root_render_func(context))
- self.__dict__.update(context.get_exported())
- self.__name__ = template.name
-
- def __html__(self):
- return Markup(concat(self._body_stream))
-
- def __str__(self):
- return unicode(self).encode('utf-8')
-
- # unicode goes after __str__ because we configured 2to3 to rename
- # __unicode__ to __str__. because the 2to3 tree is not designed to
- # remove nodes from it, we leave the above __str__ around and let
- # it override at runtime.
- def __unicode__(self):
- return concat(self._body_stream)
-
- def __repr__(self):
- if self.__name__ is None:
- name = 'memory:%x' % id(self)
- else:
- name = repr(self.__name__)
- return '<%s %s>' % (self.__class__.__name__, name)
-
-
-class TemplateExpression(object):
- """The :meth:`jinja2.Environment.compile_expression` method returns an
- instance of this object. It encapsulates the expression-like access
- to the template with an expression it wraps.
- """
-
- def __init__(self, template, undefined_to_none):
- self._template = template
- self._undefined_to_none = undefined_to_none
-
- def __call__(self, *args, **kwargs):
- context = self._template.new_context(dict(*args, **kwargs))
- consume(self._template.root_render_func(context))
- rv = context.vars['result']
- if self._undefined_to_none and isinstance(rv, Undefined):
- rv = None
- return rv
-
-
-class TemplateStream(object):
- """A template stream works pretty much like an ordinary python generator
- but it can buffer multiple items to reduce the number of total iterations.
- Per default the output is unbuffered which means that for every unbuffered
- instruction in the template one unicode string is yielded.
-
- If buffering is enabled with a buffer size of 5, five items are combined
- into a new unicode string. This is mainly useful if you are streaming
- big templates to a client via WSGI which flushes after each iteration.
- """
-
- def __init__(self, gen):
- self._gen = gen
- self.disable_buffering()
-
- def dump(self, fp, encoding=None, errors='strict'):
- """Dump the complete stream into a file or file-like object.
- Per default unicode strings are written, if you want to encode
- before writing specifiy an `encoding`.
-
- Example usage::
-
- Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
- """
- close = False
- if isinstance(fp, basestring):
- fp = file(fp, 'w')
- close = True
- try:
- if encoding is not None:
- iterable = (x.encode(encoding, errors) for x in self)
- else:
- iterable = self
- if hasattr(fp, 'writelines'):
- fp.writelines(iterable)
- else:
- for item in iterable:
- fp.write(item)
- finally:
- if close:
- fp.close()
-
- def disable_buffering(self):
- """Disable the output buffering."""
- self._next = self._gen.next
- self.buffered = False
-
- def enable_buffering(self, size=5):
- """Enable buffering. Buffer `size` items before yielding them."""
- if size <= 1:
- raise ValueError('buffer size too small')
-
- def generator(next):
- buf = []
- c_size = 0
- push = buf.append
-
- while 1:
- try:
- while c_size < size:
- c = next()
- push(c)
- if c:
- c_size += 1
- except StopIteration:
- if not c_size:
- return
- yield concat(buf)
- del buf[:]
- c_size = 0
-
- self.buffered = True
- self._next = generator(self._gen.next).next
-
- def __iter__(self):
- return self
-
- def next(self):
- return self._next()
-
-
-# hook in default template class. if anyone reads this comment: ignore that
-# it's possible to use custom templates ;-)
-Environment.template_class = Template
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/exceptions.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/exceptions.py
deleted file mode 100755
index 771f6a8d..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/exceptions.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.exceptions
- ~~~~~~~~~~~~~~~~~
-
- Jinja exceptions.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-
-
-class TemplateError(Exception):
- """Baseclass for all template errors."""
-
- def __init__(self, message=None):
- if message is not None:
- message = unicode(message).encode('utf-8')
- Exception.__init__(self, message)
-
- @property
- def message(self):
- if self.args:
- message = self.args[0]
- if message is not None:
- return message.decode('utf-8', 'replace')
-
-
-class TemplateNotFound(IOError, LookupError, TemplateError):
- """Raised if a template does not exist."""
-
- # looks weird, but removes the warning descriptor that just
- # bogusly warns us about message being deprecated
- message = None
-
- def __init__(self, name, message=None):
- IOError.__init__(self)
- if message is None:
- message = name
- self.message = message
- self.name = name
- self.templates = [name]
-
- def __str__(self):
- return self.message.encode('utf-8')
-
- # unicode goes after __str__ because we configured 2to3 to rename
- # __unicode__ to __str__. because the 2to3 tree is not designed to
- # remove nodes from it, we leave the above __str__ around and let
- # it override at runtime.
- def __unicode__(self):
- return self.message
-
-
-class TemplatesNotFound(TemplateNotFound):
- """Like :class:`TemplateNotFound` but raised if multiple templates
- are selected. This is a subclass of :class:`TemplateNotFound`
- exception, so just catching the base exception will catch both.
-
- .. versionadded:: 2.2
- """
-
- def __init__(self, names=(), message=None):
- if message is None:
- message = u'non of the templates given were found: ' + \
- u', '.join(map(unicode, names))
- TemplateNotFound.__init__(self, names and names[-1] or None, message)
- self.templates = list(names)
-
-
-class TemplateSyntaxError(TemplateError):
- """Raised to tell the user that there is a problem with the template."""
-
- def __init__(self, message, lineno, name=None, filename=None):
- TemplateError.__init__(self, message)
- self.lineno = lineno
- self.name = name
- self.filename = filename
- self.source = None
-
- # this is set to True if the debug.translate_syntax_error
- # function translated the syntax error into a new traceback
- self.translated = False
-
- def __str__(self):
- return unicode(self).encode('utf-8')
-
- # unicode goes after __str__ because we configured 2to3 to rename
- # __unicode__ to __str__. because the 2to3 tree is not designed to
- # remove nodes from it, we leave the above __str__ around and let
- # it override at runtime.
- def __unicode__(self):
- # for translated errors we only return the message
- if self.translated:
- return self.message
-
- # otherwise attach some stuff
- location = 'line %d' % self.lineno
- name = self.filename or self.name
- if name:
- location = 'File "%s", %s' % (name, location)
- lines = [self.message, ' ' + location]
-
- # if the source is set, add the line to the output
- if self.source is not None:
- try:
- line = self.source.splitlines()[self.lineno - 1]
- except IndexError:
- line = None
- if line:
- lines.append(' ' + line.strip())
-
- return u'\n'.join(lines)
-
-
-class TemplateAssertionError(TemplateSyntaxError):
- """Like a template syntax error, but covers cases where something in the
- template caused an error at compile time that wasn't necessarily caused
- by a syntax error. However it's a direct subclass of
- :exc:`TemplateSyntaxError` and has the same attributes.
- """
-
-
-class TemplateRuntimeError(TemplateError):
- """A generic runtime error in the template engine. Under some situations
- Jinja may raise this exception.
- """
-
-
-class UndefinedError(TemplateRuntimeError):
- """Raised if a template tries to operate on :class:`Undefined`."""
-
-
-class SecurityError(TemplateRuntimeError):
- """Raised if a template tries to do something insecure if the
- sandbox is enabled.
- """
-
-
-class FilterArgumentError(TemplateRuntimeError):
- """This error is raised if a filter was called with inappropriate
- arguments
- """
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/ext.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/ext.py
deleted file mode 100755
index 5ba6efdb..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/ext.py
+++ /dev/null
@@ -1,612 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.ext
- ~~~~~~~~~~
-
- Jinja extensions allow to add custom tags similar to the way django custom
- tags work. By default two example extensions exist: an i18n and a cache
- extension.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD.
-"""
-from collections import deque
-from jinja2 import nodes
-from jinja2.defaults import *
-from jinja2.environment import Environment
-from jinja2.runtime import Undefined, concat
-from jinja2.exceptions import TemplateAssertionError, TemplateSyntaxError
-from jinja2.utils import contextfunction, import_string, Markup, next
-
-
-# the only real useful gettext functions for a Jinja template. Note
-# that ugettext must be assigned to gettext as Jinja doesn't support
-# non unicode strings.
-GETTEXT_FUNCTIONS = ('_', 'gettext', 'ngettext')
-
-
-class ExtensionRegistry(type):
- """Gives the extension an unique identifier."""
-
- def __new__(cls, name, bases, d):
- rv = type.__new__(cls, name, bases, d)
- rv.identifier = rv.__module__ + '.' + rv.__name__
- return rv
-
-
-class Extension(object):
- """Extensions can be used to add extra functionality to the Jinja template
- system at the parser level. Custom extensions are bound to an environment
- but may not store environment specific data on `self`. The reason for
- this is that an extension can be bound to another environment (for
- overlays) by creating a copy and reassigning the `environment` attribute.
-
- As extensions are created by the environment they cannot accept any
- arguments for configuration. One may want to work around that by using
- a factory function, but that is not possible as extensions are identified
- by their import name. The correct way to configure the extension is
- storing the configuration values on the environment. Because this way the
- environment ends up acting as central configuration storage the
- attributes may clash which is why extensions have to ensure that the names
- they choose for configuration are not too generic. ``prefix`` for example
- is a terrible name, ``fragment_cache_prefix`` on the other hand is a good
- name as includes the name of the extension (fragment cache).
- """
- __metaclass__ = ExtensionRegistry
-
- #: if this extension parses this is the list of tags it's listening to.
- tags = set()
-
- #: the priority of that extension. This is especially useful for
- #: extensions that preprocess values. A lower value means higher
- #: priority.
- #:
- #: .. versionadded:: 2.4
- priority = 100
-
- def __init__(self, environment):
- self.environment = environment
-
- def bind(self, environment):
- """Create a copy of this extension bound to another environment."""
- rv = object.__new__(self.__class__)
- rv.__dict__.update(self.__dict__)
- rv.environment = environment
- return rv
-
- def preprocess(self, source, name, filename=None):
- """This method is called before the actual lexing and can be used to
- preprocess the source. The `filename` is optional. The return value
- must be the preprocessed source.
- """
- return source
-
- def filter_stream(self, stream):
- """It's passed a :class:`~jinja2.lexer.TokenStream` that can be used
- to filter tokens returned. This method has to return an iterable of
- :class:`~jinja2.lexer.Token`\s, but it doesn't have to return a
- :class:`~jinja2.lexer.TokenStream`.
-
- In the `ext` folder of the Jinja2 source distribution there is a file
- called `inlinegettext.py` which implements a filter that utilizes this
- method.
- """
- return stream
-
- def parse(self, parser):
- """If any of the :attr:`tags` matched this method is called with the
- parser as first argument. The token the parser stream is pointing at
- is the name token that matched. This method has to return one or a
- list of multiple nodes.
- """
- raise NotImplementedError()
-
- def attr(self, name, lineno=None):
- """Return an attribute node for the current extension. This is useful
- to pass constants on extensions to generated template code.
-
- ::
-
- self.attr('_my_attribute', lineno=lineno)
- """
- return nodes.ExtensionAttribute(self.identifier, name, lineno=lineno)
-
- def call_method(self, name, args=None, kwargs=None, dyn_args=None,
- dyn_kwargs=None, lineno=None):
- """Call a method of the extension. This is a shortcut for
- :meth:`attr` + :class:`jinja2.nodes.Call`.
- """
- if args is None:
- args = []
- if kwargs is None:
- kwargs = []
- return nodes.Call(self.attr(name, lineno=lineno), args, kwargs,
- dyn_args, dyn_kwargs, lineno=lineno)
-
-
-@contextfunction
-def _gettext_alias(__context, *args, **kwargs):
- return __context.call(__context.resolve('gettext'), *args, **kwargs)
-
-
-def _make_new_gettext(func):
- @contextfunction
- def gettext(__context, __string, **variables):
- rv = __context.call(func, __string)
- if __context.eval_ctx.autoescape:
- rv = Markup(rv)
- return rv % variables
- return gettext
-
-
-def _make_new_ngettext(func):
- @contextfunction
- def ngettext(__context, __singular, __plural, __num, **variables):
- variables.setdefault('num', __num)
- rv = __context.call(func, __singular, __plural, __num)
- if __context.eval_ctx.autoescape:
- rv = Markup(rv)
- return rv % variables
- return ngettext
-
-
-class InternationalizationExtension(Extension):
- """This extension adds gettext support to Jinja2."""
- tags = set(['trans'])
-
- # TODO: the i18n extension is currently reevaluating values in a few
- # situations. Take this example:
- # {% trans count=something() %}{{ count }} foo{% pluralize
- # %}{{ count }} fooss{% endtrans %}
- # something is called twice here. One time for the gettext value and
- # the other time for the n-parameter of the ngettext function.
-
- def __init__(self, environment):
- Extension.__init__(self, environment)
- environment.globals['_'] = _gettext_alias
- environment.extend(
- install_gettext_translations=self._install,
- install_null_translations=self._install_null,
- install_gettext_callables=self._install_callables,
- uninstall_gettext_translations=self._uninstall,
- extract_translations=self._extract,
- newstyle_gettext=False
- )
-
- def _install(self, translations, newstyle=None):
- gettext = getattr(translations, 'ugettext', None)
- if gettext is None:
- gettext = translations.gettext
- ngettext = getattr(translations, 'ungettext', None)
- if ngettext is None:
- ngettext = translations.ngettext
- self._install_callables(gettext, ngettext, newstyle)
-
- def _install_null(self, newstyle=None):
- self._install_callables(
- lambda x: x,
- lambda s, p, n: (n != 1 and (p,) or (s,))[0],
- newstyle
- )
-
- def _install_callables(self, gettext, ngettext, newstyle=None):
- if newstyle is not None:
- self.environment.newstyle_gettext = newstyle
- if self.environment.newstyle_gettext:
- gettext = _make_new_gettext(gettext)
- ngettext = _make_new_ngettext(ngettext)
- self.environment.globals.update(
- gettext=gettext,
- ngettext=ngettext
- )
-
- def _uninstall(self, translations):
- for key in 'gettext', 'ngettext':
- self.environment.globals.pop(key, None)
-
- def _extract(self, source, gettext_functions=GETTEXT_FUNCTIONS):
- if isinstance(source, basestring):
- source = self.environment.parse(source)
- return extract_from_ast(source, gettext_functions)
-
- def parse(self, parser):
- """Parse a translatable tag."""
- lineno = next(parser.stream).lineno
- num_called_num = False
-
- # find all the variables referenced. Additionally a variable can be
- # defined in the body of the trans block too, but this is checked at
- # a later state.
- plural_expr = None
- variables = {}
- while parser.stream.current.type != 'block_end':
- if variables:
- parser.stream.expect('comma')
-
- # skip colon for python compatibility
- if parser.stream.skip_if('colon'):
- break
-
- name = parser.stream.expect('name')
- if name.value in variables:
- parser.fail('translatable variable %r defined twice.' %
- name.value, name.lineno,
- exc=TemplateAssertionError)
-
- # expressions
- if parser.stream.current.type == 'assign':
- next(parser.stream)
- variables[name.value] = var = parser.parse_expression()
- else:
- variables[name.value] = var = nodes.Name(name.value, 'load')
-
- if plural_expr is None:
- plural_expr = var
- num_called_num = name.value == 'num'
-
- parser.stream.expect('block_end')
-
- plural = plural_names = None
- have_plural = False
- referenced = set()
-
- # now parse until endtrans or pluralize
- singular_names, singular = self._parse_block(parser, True)
- if singular_names:
- referenced.update(singular_names)
- if plural_expr is None:
- plural_expr = nodes.Name(singular_names[0], 'load')
- num_called_num = singular_names[0] == 'num'
-
- # if we have a pluralize block, we parse that too
- if parser.stream.current.test('name:pluralize'):
- have_plural = True
- next(parser.stream)
- if parser.stream.current.type != 'block_end':
- name = parser.stream.expect('name')
- if name.value not in variables:
- parser.fail('unknown variable %r for pluralization' %
- name.value, name.lineno,
- exc=TemplateAssertionError)
- plural_expr = variables[name.value]
- num_called_num = name.value == 'num'
- parser.stream.expect('block_end')
- plural_names, plural = self._parse_block(parser, False)
- next(parser.stream)
- referenced.update(plural_names)
- else:
- next(parser.stream)
-
- # register free names as simple name expressions
- for var in referenced:
- if var not in variables:
- variables[var] = nodes.Name(var, 'load')
-
- if not have_plural:
- plural_expr = None
- elif plural_expr is None:
- parser.fail('pluralize without variables', lineno)
-
- node = self._make_node(singular, plural, variables, plural_expr,
- bool(referenced),
- num_called_num and have_plural)
- node.set_lineno(lineno)
- return node
-
- def _parse_block(self, parser, allow_pluralize):
- """Parse until the next block tag with a given name."""
- referenced = []
- buf = []
- while 1:
- if parser.stream.current.type == 'data':
- buf.append(parser.stream.current.value.replace('%', '%%'))
- next(parser.stream)
- elif parser.stream.current.type == 'variable_begin':
- next(parser.stream)
- name = parser.stream.expect('name').value
- referenced.append(name)
- buf.append('%%(%s)s' % name)
- parser.stream.expect('variable_end')
- elif parser.stream.current.type == 'block_begin':
- next(parser.stream)
- if parser.stream.current.test('name:endtrans'):
- break
- elif parser.stream.current.test('name:pluralize'):
- if allow_pluralize:
- break
- parser.fail('a translatable section can have only one '
- 'pluralize section')
- parser.fail('control structures in translatable sections are '
- 'not allowed')
- elif parser.stream.eos:
- parser.fail('unclosed translation block')
- else:
- assert False, 'internal parser error'
-
- return referenced, concat(buf)
-
- def _make_node(self, singular, plural, variables, plural_expr,
- vars_referenced, num_called_num):
- """Generates a useful node from the data provided."""
- # no variables referenced? no need to escape for old style
- # gettext invocations only if there are vars.
- if not vars_referenced and not self.environment.newstyle_gettext:
- singular = singular.replace('%%', '%')
- if plural:
- plural = plural.replace('%%', '%')
-
- # singular only:
- if plural_expr is None:
- gettext = nodes.Name('gettext', 'load')
- node = nodes.Call(gettext, [nodes.Const(singular)],
- [], None, None)
-
- # singular and plural
- else:
- ngettext = nodes.Name('ngettext', 'load')
- node = nodes.Call(ngettext, [
- nodes.Const(singular),
- nodes.Const(plural),
- plural_expr
- ], [], None, None)
-
- # in case newstyle gettext is used, the method is powerful
- # enough to handle the variable expansion and autoescape
- # handling itself
- if self.environment.newstyle_gettext:
- for key, value in variables.iteritems():
- # the function adds that later anyways in case num was
- # called num, so just skip it.
- if num_called_num and key == 'num':
- continue
- node.kwargs.append(nodes.Keyword(key, value))
-
- # otherwise do that here
- else:
- # mark the return value as safe if we are in an
- # environment with autoescaping turned on
- node = nodes.MarkSafeIfAutoescape(node)
- if variables:
- node = nodes.Mod(node, nodes.Dict([
- nodes.Pair(nodes.Const(key), value)
- for key, value in variables.items()
- ]))
- return nodes.Output([node])
-
-
-class ExprStmtExtension(Extension):
- """Adds a `do` tag to Jinja2 that works like the print statement just
- that it doesn't print the return value.
- """
- tags = set(['do'])
-
- def parse(self, parser):
- node = nodes.ExprStmt(lineno=next(parser.stream).lineno)
- node.node = parser.parse_tuple()
- return node
-
-
-class LoopControlExtension(Extension):
- """Adds break and continue to the template engine."""
- tags = set(['break', 'continue'])
-
- def parse(self, parser):
- token = next(parser.stream)
- if token.value == 'break':
- return nodes.Break(lineno=token.lineno)
- return nodes.Continue(lineno=token.lineno)
-
-
-class WithExtension(Extension):
- """Adds support for a django-like with block."""
- tags = set(['with'])
-
- def parse(self, parser):
- node = nodes.Scope(lineno=next(parser.stream).lineno)
- assignments = []
- while parser.stream.current.type != 'block_end':
- lineno = parser.stream.current.lineno
- if assignments:
- parser.stream.expect('comma')
- target = parser.parse_assign_target()
- parser.stream.expect('assign')
- expr = parser.parse_expression()
- assignments.append(nodes.Assign(target, expr, lineno=lineno))
- node.body = assignments + \
- list(parser.parse_statements(('name:endwith',),
- drop_needle=True))
- return node
-
-
-class AutoEscapeExtension(Extension):
- """Changes auto escape rules for a scope."""
- tags = set(['autoescape'])
-
- def parse(self, parser):
- node = nodes.ScopedEvalContextModifier(lineno=next(parser.stream).lineno)
- node.options = [
- nodes.Keyword('autoescape', parser.parse_expression())
- ]
- node.body = parser.parse_statements(('name:endautoescape',),
- drop_needle=True)
- return nodes.Scope([node])
-
-
-def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
- babel_style=True):
- """Extract localizable strings from the given template node. Per
- default this function returns matches in babel style that means non string
- parameters as well as keyword arguments are returned as `None`. This
- allows Babel to figure out what you really meant if you are using
- gettext functions that allow keyword arguments for placeholder expansion.
- If you don't want that behavior set the `babel_style` parameter to `False`
- which causes only strings to be returned and parameters are always stored
- in tuples. As a consequence invalid gettext calls (calls without a single
- string parameter or string parameters after non-string parameters) are
- skipped.
-
- This example explains the behavior:
-
- >>> from jinja2 import Environment
- >>> env = Environment()
- >>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}')
- >>> list(extract_from_ast(node))
- [(1, '_', 'foo'), (1, '_', ()), (1, 'ngettext', ('foo', 'bar', None))]
- >>> list(extract_from_ast(node, babel_style=False))
- [(1, '_', ('foo',)), (1, 'ngettext', ('foo', 'bar'))]
-
- For every string found this function yields a ``(lineno, function,
- message)`` tuple, where:
-
- * ``lineno`` is the number of the line on which the string was found,
- * ``function`` is the name of the ``gettext`` function used (if the
- string was extracted from embedded Python code), and
- * ``message`` is the string itself (a ``unicode`` object, or a tuple
- of ``unicode`` objects for functions with multiple string arguments).
-
- This extraction function operates on the AST and is because of that unable
- to extract any comments. For comment support you have to use the babel
- extraction interface or extract comments yourself.
- """
- for node in node.find_all(nodes.Call):
- if not isinstance(node.node, nodes.Name) or \
- node.node.name not in gettext_functions:
- continue
-
- strings = []
- for arg in node.args:
- if isinstance(arg, nodes.Const) and \
- isinstance(arg.value, basestring):
- strings.append(arg.value)
- else:
- strings.append(None)
-
- for arg in node.kwargs:
- strings.append(None)
- if node.dyn_args is not None:
- strings.append(None)
- if node.dyn_kwargs is not None:
- strings.append(None)
-
- if not babel_style:
- strings = tuple(x for x in strings if x is not None)
- if not strings:
- continue
- else:
- if len(strings) == 1:
- strings = strings[0]
- else:
- strings = tuple(strings)
- yield node.lineno, node.node.name, strings
-
-
-class _CommentFinder(object):
- """Helper class to find comments in a token stream. Can only
- find comments for gettext calls forwards. Once the comment
- from line 4 is found, a comment for line 1 will not return a
- usable value.
- """
-
- def __init__(self, tokens, comment_tags):
- self.tokens = tokens
- self.comment_tags = comment_tags
- self.offset = 0
- self.last_lineno = 0
-
- def find_backwards(self, offset):
- try:
- for _, token_type, token_value in \
- reversed(self.tokens[self.offset:offset]):
- if token_type in ('comment', 'linecomment'):
- try:
- prefix, comment = token_value.split(None, 1)
- except ValueError:
- continue
- if prefix in self.comment_tags:
- return [comment.rstrip()]
- return []
- finally:
- self.offset = offset
-
- def find_comments(self, lineno):
- if not self.comment_tags or self.last_lineno > lineno:
- return []
- for idx, (token_lineno, _, _) in enumerate(self.tokens[self.offset:]):
- if token_lineno > lineno:
- return self.find_backwards(self.offset + idx)
- return self.find_backwards(len(self.tokens))
-
-
-def babel_extract(fileobj, keywords, comment_tags, options):
- """Babel extraction method for Jinja templates.
-
- .. versionchanged:: 2.3
- Basic support for translation comments was added. If `comment_tags`
- is now set to a list of keywords for extraction, the extractor will
- try to find the best preceeding comment that begins with one of the
- keywords. For best results, make sure to not have more than one
- gettext call in one line of code and the matching comment in the
- same line or the line before.
-
- .. versionchanged:: 2.5.1
- The `newstyle_gettext` flag can be set to `True` to enable newstyle
- gettext calls.
-
- :param fileobj: the file-like object the messages should be extracted from
- :param keywords: a list of keywords (i.e. function names) that should be
- recognized as translation functions
- :param comment_tags: a list of translator tags to search for and include
- in the results.
- :param options: a dictionary of additional options (optional)
- :return: an iterator over ``(lineno, funcname, message, comments)`` tuples.
- (comments will be empty currently)
- """
- extensions = set()
- for extension in options.get('extensions', '').split(','):
- extension = extension.strip()
- if not extension:
- continue
- extensions.add(import_string(extension))
- if InternationalizationExtension not in extensions:
- extensions.add(InternationalizationExtension)
-
- def getbool(options, key, default=False):
- options.get(key, str(default)).lower() in ('1', 'on', 'yes', 'true')
-
- environment = Environment(
- options.get('block_start_string', BLOCK_START_STRING),
- options.get('block_end_string', BLOCK_END_STRING),
- options.get('variable_start_string', VARIABLE_START_STRING),
- options.get('variable_end_string', VARIABLE_END_STRING),
- options.get('comment_start_string', COMMENT_START_STRING),
- options.get('comment_end_string', COMMENT_END_STRING),
- options.get('line_statement_prefix') or LINE_STATEMENT_PREFIX,
- options.get('line_comment_prefix') or LINE_COMMENT_PREFIX,
- getbool(options, 'trim_blocks', TRIM_BLOCKS),
- NEWLINE_SEQUENCE, frozenset(extensions),
- cache_size=0,
- auto_reload=False
- )
-
- if getbool(options, 'newstyle_gettext'):
- environment.newstyle_gettext = True
-
- source = fileobj.read().decode(options.get('encoding', 'utf-8'))
- try:
- node = environment.parse(source)
- tokens = list(environment.lex(environment.preprocess(source)))
- except TemplateSyntaxError, e:
- # skip templates with syntax errors
- return
-
- finder = _CommentFinder(tokens, comment_tags)
- for lineno, func, message in extract_from_ast(node, keywords):
- yield lineno, func, message, finder.find_comments(lineno)
-
-
-#: nicer import names
-i18n = InternationalizationExtension
-do = ExprStmtExtension
-loopcontrols = LoopControlExtension
-with_ = WithExtension
-autoescape = AutoEscapeExtension
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/filters.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/filters.py
deleted file mode 100755
index 1ef47f95..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/filters.py
+++ /dev/null
@@ -1,801 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.filters
- ~~~~~~~~~~~~~~
-
- Bundled jinja filters.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import re
-import math
-from random import choice
-from operator import itemgetter
-from itertools import imap, groupby
-from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode
-from jinja2.runtime import Undefined
-from jinja2.exceptions import FilterArgumentError, SecurityError
-
-
-_word_re = re.compile(r'\w+(?u)')
-
-
-def contextfilter(f):
- """Decorator for marking context dependent filters. The current
- :class:`Context` will be passed as first argument.
- """
- f.contextfilter = True
- return f
-
-
-def evalcontextfilter(f):
- """Decorator for marking eval-context dependent filters. An eval
- context object is passed as first argument. For more information
- about the eval context, see :ref:`eval-context`.
-
- .. versionadded:: 2.4
- """
- f.evalcontextfilter = True
- return f
-
-
-def environmentfilter(f):
- """Decorator for marking evironment dependent filters. The current
- :class:`Environment` is passed to the filter as first argument.
- """
- f.environmentfilter = True
- return f
-
-
-def make_attrgetter(environment, attribute):
- """Returns a callable that looks up the given attribute from a
- passed object with the rules of the environment. Dots are allowed
- to access attributes of attributes.
- """
- if not isinstance(attribute, basestring) or '.' not in attribute:
- return lambda x: environment.getitem(x, attribute)
- attribute = attribute.split('.')
- def attrgetter(item):
- for part in attribute:
- item = environment.getitem(item, part)
- return item
- return attrgetter
-
-
-def do_forceescape(value):
- """Enforce HTML escaping. This will probably double escape variables."""
- if hasattr(value, '__html__'):
- value = value.__html__()
- return escape(unicode(value))
-
-
-@evalcontextfilter
-def do_replace(eval_ctx, s, old, new, count=None):
- """Return a copy of the value with all occurrences of a substring
- replaced with a new one. The first argument is the substring
- that should be replaced, the second is the replacement string.
- If the optional third argument ``count`` is given, only the first
- ``count`` occurrences are replaced:
-
- .. sourcecode:: jinja
-
- {{ "Hello World"|replace("Hello", "Goodbye") }}
- -> Goodbye World
-
- {{ "aaaaargh"|replace("a", "d'oh, ", 2) }}
- -> d'oh, d'oh, aaargh
- """
- if count is None:
- count = -1
- if not eval_ctx.autoescape:
- return unicode(s).replace(unicode(old), unicode(new), count)
- if hasattr(old, '__html__') or hasattr(new, '__html__') and \
- not hasattr(s, '__html__'):
- s = escape(s)
- else:
- s = soft_unicode(s)
- return s.replace(soft_unicode(old), soft_unicode(new), count)
-
-
-def do_upper(s):
- """Convert a value to uppercase."""
- return soft_unicode(s).upper()
-
-
-def do_lower(s):
- """Convert a value to lowercase."""
- return soft_unicode(s).lower()
-
-
-@evalcontextfilter
-def do_xmlattr(_eval_ctx, d, autospace=True):
- """Create an SGML/XML attribute string based on the items in a dict.
- All values that are neither `none` nor `undefined` are automatically
- escaped:
-
- .. sourcecode:: html+jinja
-
- <ul{{ {'class': 'my_list', 'missing': none,
- 'id': 'list-%d'|format(variable)}|xmlattr }}>
- ...
- </ul>
-
- Results in something like this:
-
- .. sourcecode:: html
-
- <ul class="my_list" id="list-42">
- ...
- </ul>
-
- As you can see it automatically prepends a space in front of the item
- if the filter returned something unless the second parameter is false.
- """
- rv = u' '.join(
- u'%s="%s"' % (escape(key), escape(value))
- for key, value in d.iteritems()
- if value is not None and not isinstance(value, Undefined)
- )
- if autospace and rv:
- rv = u' ' + rv
- if _eval_ctx.autoescape:
- rv = Markup(rv)
- return rv
-
-
-def do_capitalize(s):
- """Capitalize a value. The first character will be uppercase, all others
- lowercase.
- """
- return soft_unicode(s).capitalize()
-
-
-def do_title(s):
- """Return a titlecased version of the value. I.e. words will start with
- uppercase letters, all remaining characters are lowercase.
- """
- return soft_unicode(s).title()
-
-
-def do_dictsort(value, case_sensitive=False, by='key'):
- """Sort a dict and yield (key, value) pairs. Because python dicts are
- unsorted you may want to use this function to order them by either
- key or value:
-
- .. sourcecode:: jinja
-
- {% for item in mydict|dictsort %}
- sort the dict by key, case insensitive
-
- {% for item in mydict|dicsort(true) %}
- sort the dict by key, case sensitive
-
- {% for item in mydict|dictsort(false, 'value') %}
- sort the dict by key, case insensitive, sorted
- normally and ordered by value.
- """
- if by == 'key':
- pos = 0
- elif by == 'value':
- pos = 1
- else:
- raise FilterArgumentError('You can only sort by either '
- '"key" or "value"')
- def sort_func(item):
- value = item[pos]
- if isinstance(value, basestring) and not case_sensitive:
- value = value.lower()
- return value
-
- return sorted(value.items(), key=sort_func)
-
-
-@environmentfilter
-def do_sort(environment, value, reverse=False, case_sensitive=False,
- attribute=None):
- """Sort an iterable. Per default it sorts ascending, if you pass it
- true as first argument it will reverse the sorting.
-
- If the iterable is made of strings the third parameter can be used to
- control the case sensitiveness of the comparison which is disabled by
- default.
-
- .. sourcecode:: jinja
-
- {% for item in iterable|sort %}
- ...
- {% endfor %}
-
- It is also possible to sort by an attribute (for example to sort
- by the date of an object) by specifying the `attribute` parameter:
-
- .. sourcecode:: jinja
-
- {% for item in iterable|sort(attribute='date') %}
- ...
- {% endfor %}
-
- .. versionchanged:: 2.6
- The `attribute` parameter was added.
- """
- if not case_sensitive:
- def sort_func(item):
- if isinstance(item, basestring):
- item = item.lower()
- return item
- else:
- sort_func = None
- if attribute is not None:
- getter = make_attrgetter(environment, attribute)
- def sort_func(item, processor=sort_func or (lambda x: x)):
- return processor(getter(item))
- return sorted(value, key=sort_func, reverse=reverse)
-
-
-def do_default(value, default_value=u'', boolean=False):
- """If the value is undefined it will return the passed default value,
- otherwise the value of the variable:
-
- .. sourcecode:: jinja
-
- {{ my_variable|default('my_variable is not defined') }}
-
- This will output the value of ``my_variable`` if the variable was
- defined, otherwise ``'my_variable is not defined'``. If you want
- to use default with variables that evaluate to false you have to
- set the second parameter to `true`:
-
- .. sourcecode:: jinja
-
- {{ ''|default('the string was empty', true) }}
- """
- if (boolean and not value) or isinstance(value, Undefined):
- return default_value
- return value
-
-
-@evalcontextfilter
-def do_join(eval_ctx, value, d=u'', attribute=None):
- """Return a string which is the concatenation of the strings in the
- sequence. The separator between elements is an empty string per
- default, you can define it with the optional parameter:
-
- .. sourcecode:: jinja
-
- {{ [1, 2, 3]|join('|') }}
- -> 1|2|3
-
- {{ [1, 2, 3]|join }}
- -> 123
-
- It is also possible to join certain attributes of an object:
-
- .. sourcecode:: jinja
-
- {{ users|join(', ', attribute='username') }}
-
- .. versionadded:: 2.6
- The `attribute` parameter was added.
- """
- if attribute is not None:
- value = imap(make_attrgetter(eval_ctx.environment, attribute), value)
-
- # no automatic escaping? joining is a lot eaiser then
- if not eval_ctx.autoescape:
- return unicode(d).join(imap(unicode, value))
-
- # if the delimiter doesn't have an html representation we check
- # if any of the items has. If yes we do a coercion to Markup
- if not hasattr(d, '__html__'):
- value = list(value)
- do_escape = False
- for idx, item in enumerate(value):
- if hasattr(item, '__html__'):
- do_escape = True
- else:
- value[idx] = unicode(item)
- if do_escape:
- d = escape(d)
- else:
- d = unicode(d)
- return d.join(value)
-
- # no html involved, to normal joining
- return soft_unicode(d).join(imap(soft_unicode, value))
-
-
-def do_center(value, width=80):
- """Centers the value in a field of a given width."""
- return unicode(value).center(width)
-
-
-@environmentfilter
-def do_first(environment, seq):
- """Return the first item of a sequence."""
- try:
- return iter(seq).next()
- except StopIteration:
- return environment.undefined('No first item, sequence was empty.')
-
-
-@environmentfilter
-def do_last(environment, seq):
- """Return the last item of a sequence."""
- try:
- return iter(reversed(seq)).next()
- except StopIteration:
- return environment.undefined('No last item, sequence was empty.')
-
-
-@environmentfilter
-def do_random(environment, seq):
- """Return a random item from the sequence."""
- try:
- return choice(seq)
- except IndexError:
- return environment.undefined('No random item, sequence was empty.')
-
-
-def do_filesizeformat(value, binary=False):
- """Format the value like a 'human-readable' file size (i.e. 13 kB,
- 4.1 MB, 102 Bytes, etc). Per default decimal prefixes are used (Mega,
- Giga, etc.), if the second parameter is set to `True` the binary
- prefixes are used (Mebi, Gibi).
- """
- bytes = float(value)
- base = binary and 1024 or 1000
- prefixes = [
- (binary and "KiB" or "kB"),
- (binary and "MiB" or "MB"),
- (binary and "GiB" or "GB"),
- (binary and "TiB" or "TB"),
- (binary and "PiB" or "PB"),
- (binary and "EiB" or "EB"),
- (binary and "ZiB" or "ZB"),
- (binary and "YiB" or "YB")
- ]
- if bytes == 1:
- return "1 Byte"
- elif bytes < base:
- return "%d Bytes" % bytes
- else:
- for i, prefix in enumerate(prefixes):
- unit = base * base ** (i + 1)
- if bytes < unit:
- return "%.1f %s" % ((bytes / unit), prefix)
- return "%.1f %s" % ((bytes / unit), prefix)
-
-
-def do_pprint(value, verbose=False):
- """Pretty print a variable. Useful for debugging.
-
- With Jinja 1.2 onwards you can pass it a parameter. If this parameter
- is truthy the output will be more verbose (this requires `pretty`)
- """
- return pformat(value, verbose=verbose)
-
-
-@evalcontextfilter
-def do_urlize(eval_ctx, value, trim_url_limit=None, nofollow=False):
- """Converts URLs in plain text into clickable links.
-
- If you pass the filter an additional integer it will shorten the urls
- to that number. Also a third argument exists that makes the urls
- "nofollow":
-
- .. sourcecode:: jinja
-
- {{ mytext|urlize(40, true) }}
- links are shortened to 40 chars and defined with rel="nofollow"
- """
- rv = urlize(value, trim_url_limit, nofollow)
- if eval_ctx.autoescape:
- rv = Markup(rv)
- return rv
-
-
-def do_indent(s, width=4, indentfirst=False):
- """Return a copy of the passed string, each line indented by
- 4 spaces. The first line is not indented. If you want to
- change the number of spaces or indent the first line too
- you can pass additional parameters to the filter:
-
- .. sourcecode:: jinja
-
- {{ mytext|indent(2, true) }}
- indent by two spaces and indent the first line too.
- """
- indention = u' ' * width
- rv = (u'\n' + indention).join(s.splitlines())
- if indentfirst:
- rv = indention + rv
- return rv
-
-
-def do_truncate(s, length=255, killwords=False, end='...'):
- """Return a truncated copy of the string. The length is specified
- with the first parameter which defaults to ``255``. If the second
- parameter is ``true`` the filter will cut the text at length. Otherwise
- it will try to save the last word. If the text was in fact
- truncated it will append an ellipsis sign (``"..."``). If you want a
- different ellipsis sign than ``"..."`` you can specify it using the
- third parameter.
-
- .. sourcecode jinja::
-
- {{ mytext|truncate(300, false, '&raquo;') }}
- truncate mytext to 300 chars, don't split up words, use a
- right pointing double arrow as ellipsis sign.
- """
- if len(s) <= length:
- return s
- elif killwords:
- return s[:length] + end
- words = s.split(' ')
- result = []
- m = 0
- for word in words:
- m += len(word) + 1
- if m > length:
- break
- result.append(word)
- result.append(end)
- return u' '.join(result)
-
-@environmentfilter
-def do_wordwrap(environment, s, width=79, break_long_words=True):
- """
- Return a copy of the string passed to the filter wrapped after
- ``79`` characters. You can override this default using the first
- parameter. If you set the second parameter to `false` Jinja will not
- split words apart if they are longer than `width`.
- """
- import textwrap
- return environment.newline_sequence.join(textwrap.wrap(s, width=width, expand_tabs=False,
- replace_whitespace=False,
- break_long_words=break_long_words))
-
-
-def do_wordcount(s):
- """Count the words in that string."""
- return len(_word_re.findall(s))
-
-
-def do_int(value, default=0):
- """Convert the value into an integer. If the
- conversion doesn't work it will return ``0``. You can
- override this default using the first parameter.
- """
- try:
- return int(value)
- except (TypeError, ValueError):
- # this quirk is necessary so that "42.23"|int gives 42.
- try:
- return int(float(value))
- except (TypeError, ValueError):
- return default
-
-
-def do_float(value, default=0.0):
- """Convert the value into a floating point number. If the
- conversion doesn't work it will return ``0.0``. You can
- override this default using the first parameter.
- """
- try:
- return float(value)
- except (TypeError, ValueError):
- return default
-
-
-def do_format(value, *args, **kwargs):
- """
- Apply python string formatting on an object:
-
- .. sourcecode:: jinja
-
- {{ "%s - %s"|format("Hello?", "Foo!") }}
- -> Hello? - Foo!
- """
- if args and kwargs:
- raise FilterArgumentError('can\'t handle positional and keyword '
- 'arguments at the same time')
- return soft_unicode(value) % (kwargs or args)
-
-
-def do_trim(value):
- """Strip leading and trailing whitespace."""
- return soft_unicode(value).strip()
-
-
-def do_striptags(value):
- """Strip SGML/XML tags and replace adjacent whitespace by one space.
- """
- if hasattr(value, '__html__'):
- value = value.__html__()
- return Markup(unicode(value)).striptags()
-
-
-def do_slice(value, slices, fill_with=None):
- """Slice an iterator and return a list of lists containing
- those items. Useful if you want to create a div containing
- three ul tags that represent columns:
-
- .. sourcecode:: html+jinja
-
- <div class="columwrapper">
- {%- for column in items|slice(3) %}
- <ul class="column-{{ loop.index }}">
- {%- for item in column %}
- <li>{{ item }}</li>
- {%- endfor %}
- </ul>
- {%- endfor %}
- </div>
-
- If you pass it a second argument it's used to fill missing
- values on the last iteration.
- """
- seq = list(value)
- length = len(seq)
- items_per_slice = length // slices
- slices_with_extra = length % slices
- offset = 0
- for slice_number in xrange(slices):
- start = offset + slice_number * items_per_slice
- if slice_number < slices_with_extra:
- offset += 1
- end = offset + (slice_number + 1) * items_per_slice
- tmp = seq[start:end]
- if fill_with is not None and slice_number >= slices_with_extra:
- tmp.append(fill_with)
- yield tmp
-
-
-def do_batch(value, linecount, fill_with=None):
- """
- A filter that batches items. It works pretty much like `slice`
- just the other way round. It returns a list of lists with the
- given number of items. If you provide a second parameter this
- is used to fill missing items. See this example:
-
- .. sourcecode:: html+jinja
-
- <table>
- {%- for row in items|batch(3, '&nbsp;') %}
- <tr>
- {%- for column in row %}
- <td>{{ column }}</td>
- {%- endfor %}
- </tr>
- {%- endfor %}
- </table>
- """
- result = []
- tmp = []
- for item in value:
- if len(tmp) == linecount:
- yield tmp
- tmp = []
- tmp.append(item)
- if tmp:
- if fill_with is not None and len(tmp) < linecount:
- tmp += [fill_with] * (linecount - len(tmp))
- yield tmp
-
-
-def do_round(value, precision=0, method='common'):
- """Round the number to a given precision. The first
- parameter specifies the precision (default is ``0``), the
- second the rounding method:
-
- - ``'common'`` rounds either up or down
- - ``'ceil'`` always rounds up
- - ``'floor'`` always rounds down
-
- If you don't specify a method ``'common'`` is used.
-
- .. sourcecode:: jinja
-
- {{ 42.55|round }}
- -> 43.0
- {{ 42.55|round(1, 'floor') }}
- -> 42.5
-
- Note that even if rounded to 0 precision, a float is returned. If
- you need a real integer, pipe it through `int`:
-
- .. sourcecode:: jinja
-
- {{ 42.55|round|int }}
- -> 43
- """
- if not method in ('common', 'ceil', 'floor'):
- raise FilterArgumentError('method must be common, ceil or floor')
- if method == 'common':
- return round(value, precision)
- func = getattr(math, method)
- return func(value * (10 ** precision)) / (10 ** precision)
-
-
-@environmentfilter
-def do_groupby(environment, value, attribute):
- """Group a sequence of objects by a common attribute.
-
- If you for example have a list of dicts or objects that represent persons
- with `gender`, `first_name` and `last_name` attributes and you want to
- group all users by genders you can do something like the following
- snippet:
-
- .. sourcecode:: html+jinja
-
- <ul>
- {% for group in persons|groupby('gender') %}
- <li>{{ group.grouper }}<ul>
- {% for person in group.list %}
- <li>{{ person.first_name }} {{ person.last_name }}</li>
- {% endfor %}</ul></li>
- {% endfor %}
- </ul>
-
- Additionally it's possible to use tuple unpacking for the grouper and
- list:
-
- .. sourcecode:: html+jinja
-
- <ul>
- {% for grouper, list in persons|groupby('gender') %}
- ...
- {% endfor %}
- </ul>
-
- As you can see the item we're grouping by is stored in the `grouper`
- attribute and the `list` contains all the objects that have this grouper
- in common.
-
- .. versionchanged:: 2.6
- It's now possible to use dotted notation to group by the child
- attribute of another attribute.
- """
- expr = make_attrgetter(environment, attribute)
- return sorted(map(_GroupTuple, groupby(sorted(value, key=expr), expr)))
-
-
-class _GroupTuple(tuple):
- __slots__ = ()
- grouper = property(itemgetter(0))
- list = property(itemgetter(1))
-
- def __new__(cls, (key, value)):
- return tuple.__new__(cls, (key, list(value)))
-
-
-@environmentfilter
-def do_sum(environment, iterable, attribute=None, start=0):
- """Returns the sum of a sequence of numbers plus the value of parameter
- 'start' (which defaults to 0). When the sequence is empty it returns
- start.
-
- It is also possible to sum up only certain attributes:
-
- .. sourcecode:: jinja
-
- Total: {{ items|sum(attribute='price') }}
-
- .. versionchanged:: 2.6
- The `attribute` parameter was added to allow suming up over
- attributes. Also the `start` parameter was moved on to the right.
- """
- if attribute is not None:
- iterable = imap(make_attrgetter(environment, attribute), iterable)
- return sum(iterable, start)
-
-
-def do_list(value):
- """Convert the value into a list. If it was a string the returned list
- will be a list of characters.
- """
- return list(value)
-
-
-def do_mark_safe(value):
- """Mark the value as safe which means that in an environment with automatic
- escaping enabled this variable will not be escaped.
- """
- return Markup(value)
-
-
-def do_mark_unsafe(value):
- """Mark a value as unsafe. This is the reverse operation for :func:`safe`."""
- return unicode(value)
-
-
-def do_reverse(value):
- """Reverse the object or return an iterator the iterates over it the other
- way round.
- """
- if isinstance(value, basestring):
- return value[::-1]
- try:
- return reversed(value)
- except TypeError:
- try:
- rv = list(value)
- rv.reverse()
- return rv
- except TypeError:
- raise FilterArgumentError('argument must be iterable')
-
-
-@environmentfilter
-def do_attr(environment, obj, name):
- """Get an attribute of an object. ``foo|attr("bar")`` works like
- ``foo["bar"]`` just that always an attribute is returned and items are not
- looked up.
-
- See :ref:`Notes on subscriptions <notes-on-subscriptions>` for more details.
- """
- try:
- name = str(name)
- except UnicodeError:
- pass
- else:
- try:
- value = getattr(obj, name)
- except AttributeError:
- pass
- else:
- if environment.sandboxed and not \
- environment.is_safe_attribute(obj, name, value):
- return environment.unsafe_undefined(obj, name)
- return value
- return environment.undefined(obj=obj, name=name)
-
-
-FILTERS = {
- 'attr': do_attr,
- 'replace': do_replace,
- 'upper': do_upper,
- 'lower': do_lower,
- 'escape': escape,
- 'e': escape,
- 'forceescape': do_forceescape,
- 'capitalize': do_capitalize,
- 'title': do_title,
- 'default': do_default,
- 'd': do_default,
- 'join': do_join,
- 'count': len,
- 'dictsort': do_dictsort,
- 'sort': do_sort,
- 'length': len,
- 'reverse': do_reverse,
- 'center': do_center,
- 'indent': do_indent,
- 'title': do_title,
- 'capitalize': do_capitalize,
- 'first': do_first,
- 'last': do_last,
- 'random': do_random,
- 'filesizeformat': do_filesizeformat,
- 'pprint': do_pprint,
- 'truncate': do_truncate,
- 'wordwrap': do_wordwrap,
- 'wordcount': do_wordcount,
- 'int': do_int,
- 'float': do_float,
- 'string': soft_unicode,
- 'list': do_list,
- 'urlize': do_urlize,
- 'format': do_format,
- 'trim': do_trim,
- 'striptags': do_striptags,
- 'slice': do_slice,
- 'batch': do_batch,
- 'sum': do_sum,
- 'abs': abs,
- 'round': do_round,
- 'groupby': do_groupby,
- 'safe': do_mark_safe,
- 'xmlattr': do_xmlattr
-}
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/lexer.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/lexer.py
deleted file mode 100755
index 0d3f6961..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/lexer.py
+++ /dev/null
@@ -1,681 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.lexer
- ~~~~~~~~~~~~
-
- This module implements a Jinja / Python combination lexer. The
- `Lexer` class provided by this module is used to do some preprocessing
- for Jinja.
-
- On the one hand it filters out invalid operators like the bitshift
- operators we don't allow in templates. On the other hand it separates
- template code and python code in expressions.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import re
-from operator import itemgetter
-from collections import deque
-from jinja2.exceptions import TemplateSyntaxError
-from jinja2.utils import LRUCache, next
-
-
-# cache for the lexers. Exists in order to be able to have multiple
-# environments with the same lexer
-_lexer_cache = LRUCache(50)
-
-# static regular expressions
-whitespace_re = re.compile(r'\s+', re.U)
-string_re = re.compile(r"('([^'\\]*(?:\\.[^'\\]*)*)'"
- r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
-integer_re = re.compile(r'\d+')
-
-# we use the unicode identifier rule if this python version is able
-# to handle unicode identifiers, otherwise the standard ASCII one.
-try:
- compile('föö', '<unknown>', 'eval')
-except SyntaxError:
- name_re = re.compile(r'\b[a-zA-Z_][a-zA-Z0-9_]*\b')
-else:
- from jinja2 import _stringdefs
- name_re = re.compile(r'[%s][%s]*' % (_stringdefs.xid_start,
- _stringdefs.xid_continue))
-
-float_re = re.compile(r'(?<!\.)\d+\.\d+')
-newline_re = re.compile(r'(\r\n|\r|\n)')
-
-# internal the tokens and keep references to them
-TOKEN_ADD = intern('add')
-TOKEN_ASSIGN = intern('assign')
-TOKEN_COLON = intern('colon')
-TOKEN_COMMA = intern('comma')
-TOKEN_DIV = intern('div')
-TOKEN_DOT = intern('dot')
-TOKEN_EQ = intern('eq')
-TOKEN_FLOORDIV = intern('floordiv')
-TOKEN_GT = intern('gt')
-TOKEN_GTEQ = intern('gteq')
-TOKEN_LBRACE = intern('lbrace')
-TOKEN_LBRACKET = intern('lbracket')
-TOKEN_LPAREN = intern('lparen')
-TOKEN_LT = intern('lt')
-TOKEN_LTEQ = intern('lteq')
-TOKEN_MOD = intern('mod')
-TOKEN_MUL = intern('mul')
-TOKEN_NE = intern('ne')
-TOKEN_PIPE = intern('pipe')
-TOKEN_POW = intern('pow')
-TOKEN_RBRACE = intern('rbrace')
-TOKEN_RBRACKET = intern('rbracket')
-TOKEN_RPAREN = intern('rparen')
-TOKEN_SEMICOLON = intern('semicolon')
-TOKEN_SUB = intern('sub')
-TOKEN_TILDE = intern('tilde')
-TOKEN_WHITESPACE = intern('whitespace')
-TOKEN_FLOAT = intern('float')
-TOKEN_INTEGER = intern('integer')
-TOKEN_NAME = intern('name')
-TOKEN_STRING = intern('string')
-TOKEN_OPERATOR = intern('operator')
-TOKEN_BLOCK_BEGIN = intern('block_begin')
-TOKEN_BLOCK_END = intern('block_end')
-TOKEN_VARIABLE_BEGIN = intern('variable_begin')
-TOKEN_VARIABLE_END = intern('variable_end')
-TOKEN_RAW_BEGIN = intern('raw_begin')
-TOKEN_RAW_END = intern('raw_end')
-TOKEN_COMMENT_BEGIN = intern('comment_begin')
-TOKEN_COMMENT_END = intern('comment_end')
-TOKEN_COMMENT = intern('comment')
-TOKEN_LINESTATEMENT_BEGIN = intern('linestatement_begin')
-TOKEN_LINESTATEMENT_END = intern('linestatement_end')
-TOKEN_LINECOMMENT_BEGIN = intern('linecomment_begin')
-TOKEN_LINECOMMENT_END = intern('linecomment_end')
-TOKEN_LINECOMMENT = intern('linecomment')
-TOKEN_DATA = intern('data')
-TOKEN_INITIAL = intern('initial')
-TOKEN_EOF = intern('eof')
-
-# bind operators to token types
-operators = {
- '+': TOKEN_ADD,
- '-': TOKEN_SUB,
- '/': TOKEN_DIV,
- '//': TOKEN_FLOORDIV,
- '*': TOKEN_MUL,
- '%': TOKEN_MOD,
- '**': TOKEN_POW,
- '~': TOKEN_TILDE,
- '[': TOKEN_LBRACKET,
- ']': TOKEN_RBRACKET,
- '(': TOKEN_LPAREN,
- ')': TOKEN_RPAREN,
- '{': TOKEN_LBRACE,
- '}': TOKEN_RBRACE,
- '==': TOKEN_EQ,
- '!=': TOKEN_NE,
- '>': TOKEN_GT,
- '>=': TOKEN_GTEQ,
- '<': TOKEN_LT,
- '<=': TOKEN_LTEQ,
- '=': TOKEN_ASSIGN,
- '.': TOKEN_DOT,
- ':': TOKEN_COLON,
- '|': TOKEN_PIPE,
- ',': TOKEN_COMMA,
- ';': TOKEN_SEMICOLON
-}
-
-reverse_operators = dict([(v, k) for k, v in operators.iteritems()])
-assert len(operators) == len(reverse_operators), 'operators dropped'
-operator_re = re.compile('(%s)' % '|'.join(re.escape(x) for x in
- sorted(operators, key=lambda x: -len(x))))
-
-ignored_tokens = frozenset([TOKEN_COMMENT_BEGIN, TOKEN_COMMENT,
- TOKEN_COMMENT_END, TOKEN_WHITESPACE,
- TOKEN_WHITESPACE, TOKEN_LINECOMMENT_BEGIN,
- TOKEN_LINECOMMENT_END, TOKEN_LINECOMMENT])
-ignore_if_empty = frozenset([TOKEN_WHITESPACE, TOKEN_DATA,
- TOKEN_COMMENT, TOKEN_LINECOMMENT])
-
-
-def _describe_token_type(token_type):
- if token_type in reverse_operators:
- return reverse_operators[token_type]
- return {
- TOKEN_COMMENT_BEGIN: 'begin of comment',
- TOKEN_COMMENT_END: 'end of comment',
- TOKEN_COMMENT: 'comment',
- TOKEN_LINECOMMENT: 'comment',
- TOKEN_BLOCK_BEGIN: 'begin of statement block',
- TOKEN_BLOCK_END: 'end of statement block',
- TOKEN_VARIABLE_BEGIN: 'begin of print statement',
- TOKEN_VARIABLE_END: 'end of print statement',
- TOKEN_LINESTATEMENT_BEGIN: 'begin of line statement',
- TOKEN_LINESTATEMENT_END: 'end of line statement',
- TOKEN_DATA: 'template data / text',
- TOKEN_EOF: 'end of template'
- }.get(token_type, token_type)
-
-
-def describe_token(token):
- """Returns a description of the token."""
- if token.type == 'name':
- return token.value
- return _describe_token_type(token.type)
-
-
-def describe_token_expr(expr):
- """Like `describe_token` but for token expressions."""
- if ':' in expr:
- type, value = expr.split(':', 1)
- if type == 'name':
- return value
- else:
- type = expr
- return _describe_token_type(type)
-
-
-def count_newlines(value):
- """Count the number of newline characters in the string. This is
- useful for extensions that filter a stream.
- """
- return len(newline_re.findall(value))
-
-
-def compile_rules(environment):
- """Compiles all the rules from the environment into a list of rules."""
- e = re.escape
- rules = [
- (len(environment.comment_start_string), 'comment',
- e(environment.comment_start_string)),
- (len(environment.block_start_string), 'block',
- e(environment.block_start_string)),
- (len(environment.variable_start_string), 'variable',
- e(environment.variable_start_string))
- ]
-
- if environment.line_statement_prefix is not None:
- rules.append((len(environment.line_statement_prefix), 'linestatement',
- r'^\s*' + e(environment.line_statement_prefix)))
- if environment.line_comment_prefix is not None:
- rules.append((len(environment.line_comment_prefix), 'linecomment',
- r'(?:^|(?<=\S))[^\S\r\n]*' +
- e(environment.line_comment_prefix)))
-
- return [x[1:] for x in sorted(rules, reverse=True)]
-
-
-class Failure(object):
- """Class that raises a `TemplateSyntaxError` if called.
- Used by the `Lexer` to specify known errors.
- """
-
- def __init__(self, message, cls=TemplateSyntaxError):
- self.message = message
- self.error_class = cls
-
- def __call__(self, lineno, filename):
- raise self.error_class(self.message, lineno, filename)
-
-
-class Token(tuple):
- """Token class."""
- __slots__ = ()
- lineno, type, value = (property(itemgetter(x)) for x in range(3))
-
- def __new__(cls, lineno, type, value):
- return tuple.__new__(cls, (lineno, intern(str(type)), value))
-
- def __str__(self):
- if self.type in reverse_operators:
- return reverse_operators[self.type]
- elif self.type == 'name':
- return self.value
- return self.type
-
- def test(self, expr):
- """Test a token against a token expression. This can either be a
- token type or ``'token_type:token_value'``. This can only test
- against string values and types.
- """
- # here we do a regular string equality check as test_any is usually
- # passed an iterable of not interned strings.
- if self.type == expr:
- return True
- elif ':' in expr:
- return expr.split(':', 1) == [self.type, self.value]
- return False
-
- def test_any(self, *iterable):
- """Test against multiple token expressions."""
- for expr in iterable:
- if self.test(expr):
- return True
- return False
-
- def __repr__(self):
- return 'Token(%r, %r, %r)' % (
- self.lineno,
- self.type,
- self.value
- )
-
-
-class TokenStreamIterator(object):
- """The iterator for tokenstreams. Iterate over the stream
- until the eof token is reached.
- """
-
- def __init__(self, stream):
- self.stream = stream
-
- def __iter__(self):
- return self
-
- def next(self):
- token = self.stream.current
- if token.type is TOKEN_EOF:
- self.stream.close()
- raise StopIteration()
- next(self.stream)
- return token
-
-
-class TokenStream(object):
- """A token stream is an iterable that yields :class:`Token`\s. The
- parser however does not iterate over it but calls :meth:`next` to go
- one token ahead. The current active token is stored as :attr:`current`.
- """
-
- def __init__(self, generator, name, filename):
- self._next = iter(generator).next
- self._pushed = deque()
- self.name = name
- self.filename = filename
- self.closed = False
- self.current = Token(1, TOKEN_INITIAL, '')
- next(self)
-
- def __iter__(self):
- return TokenStreamIterator(self)
-
- def __nonzero__(self):
- return bool(self._pushed) or self.current.type is not TOKEN_EOF
-
- eos = property(lambda x: not x, doc="Are we at the end of the stream?")
-
- def push(self, token):
- """Push a token back to the stream."""
- self._pushed.append(token)
-
- def look(self):
- """Look at the next token."""
- old_token = next(self)
- result = self.current
- self.push(result)
- self.current = old_token
- return result
-
- def skip(self, n=1):
- """Got n tokens ahead."""
- for x in xrange(n):
- next(self)
-
- def next_if(self, expr):
- """Perform the token test and return the token if it matched.
- Otherwise the return value is `None`.
- """
- if self.current.test(expr):
- return next(self)
-
- def skip_if(self, expr):
- """Like :meth:`next_if` but only returns `True` or `False`."""
- return self.next_if(expr) is not None
-
- def next(self):
- """Go one token ahead and return the old one"""
- rv = self.current
- if self._pushed:
- self.current = self._pushed.popleft()
- elif self.current.type is not TOKEN_EOF:
- try:
- self.current = self._next()
- except StopIteration:
- self.close()
- return rv
-
- def close(self):
- """Close the stream."""
- self.current = Token(self.current.lineno, TOKEN_EOF, '')
- self._next = None
- self.closed = True
-
- def expect(self, expr):
- """Expect a given token type and return it. This accepts the same
- argument as :meth:`jinja2.lexer.Token.test`.
- """
- if not self.current.test(expr):
- expr = describe_token_expr(expr)
- if self.current.type is TOKEN_EOF:
- raise TemplateSyntaxError('unexpected end of template, '
- 'expected %r.' % expr,
- self.current.lineno,
- self.name, self.filename)
- raise TemplateSyntaxError("expected token %r, got %r" %
- (expr, describe_token(self.current)),
- self.current.lineno,
- self.name, self.filename)
- try:
- return self.current
- finally:
- next(self)
-
-
-def get_lexer(environment):
- """Return a lexer which is probably cached."""
- key = (environment.block_start_string,
- environment.block_end_string,
- environment.variable_start_string,
- environment.variable_end_string,
- environment.comment_start_string,
- environment.comment_end_string,
- environment.line_statement_prefix,
- environment.line_comment_prefix,
- environment.trim_blocks,
- environment.newline_sequence)
- lexer = _lexer_cache.get(key)
- if lexer is None:
- lexer = Lexer(environment)
- _lexer_cache[key] = lexer
- return lexer
-
-
-class Lexer(object):
- """Class that implements a lexer for a given environment. Automatically
- created by the environment class, usually you don't have to do that.
-
- Note that the lexer is not automatically bound to an environment.
- Multiple environments can share the same lexer.
- """
-
- def __init__(self, environment):
- # shortcuts
- c = lambda x: re.compile(x, re.M | re.S)
- e = re.escape
-
- # lexing rules for tags
- tag_rules = [
- (whitespace_re, TOKEN_WHITESPACE, None),
- (float_re, TOKEN_FLOAT, None),
- (integer_re, TOKEN_INTEGER, None),
- (name_re, TOKEN_NAME, None),
- (string_re, TOKEN_STRING, None),
- (operator_re, TOKEN_OPERATOR, None)
- ]
-
- # assamble the root lexing rule. because "|" is ungreedy
- # we have to sort by length so that the lexer continues working
- # as expected when we have parsing rules like <% for block and
- # <%= for variables. (if someone wants asp like syntax)
- # variables are just part of the rules if variable processing
- # is required.
- root_tag_rules = compile_rules(environment)
-
- # block suffix if trimming is enabled
- block_suffix_re = environment.trim_blocks and '\\n?' or ''
-
- self.newline_sequence = environment.newline_sequence
-
- # global lexing rules
- self.rules = {
- 'root': [
- # directives
- (c('(.*?)(?:%s)' % '|'.join(
- [r'(?P<raw_begin>(?:\s*%s\-|%s)\s*raw\s*(?:\-%s\s*|%s))' % (
- e(environment.block_start_string),
- e(environment.block_start_string),
- e(environment.block_end_string),
- e(environment.block_end_string)
- )] + [
- r'(?P<%s_begin>\s*%s\-|%s)' % (n, r, r)
- for n, r in root_tag_rules
- ])), (TOKEN_DATA, '#bygroup'), '#bygroup'),
- # data
- (c('.+'), TOKEN_DATA, None)
- ],
- # comments
- TOKEN_COMMENT_BEGIN: [
- (c(r'(.*?)((?:\-%s\s*|%s)%s)' % (
- e(environment.comment_end_string),
- e(environment.comment_end_string),
- block_suffix_re
- )), (TOKEN_COMMENT, TOKEN_COMMENT_END), '#pop'),
- (c('(.)'), (Failure('Missing end of comment tag'),), None)
- ],
- # blocks
- TOKEN_BLOCK_BEGIN: [
- (c('(?:\-%s\s*|%s)%s' % (
- e(environment.block_end_string),
- e(environment.block_end_string),
- block_suffix_re
- )), TOKEN_BLOCK_END, '#pop'),
- ] + tag_rules,
- # variables
- TOKEN_VARIABLE_BEGIN: [
- (c('\-%s\s*|%s' % (
- e(environment.variable_end_string),
- e(environment.variable_end_string)
- )), TOKEN_VARIABLE_END, '#pop')
- ] + tag_rules,
- # raw block
- TOKEN_RAW_BEGIN: [
- (c('(.*?)((?:\s*%s\-|%s)\s*endraw\s*(?:\-%s\s*|%s%s))' % (
- e(environment.block_start_string),
- e(environment.block_start_string),
- e(environment.block_end_string),
- e(environment.block_end_string),
- block_suffix_re
- )), (TOKEN_DATA, TOKEN_RAW_END), '#pop'),
- (c('(.)'), (Failure('Missing end of raw directive'),), None)
- ],
- # line statements
- TOKEN_LINESTATEMENT_BEGIN: [
- (c(r'\s*(\n|$)'), TOKEN_LINESTATEMENT_END, '#pop')
- ] + tag_rules,
- # line comments
- TOKEN_LINECOMMENT_BEGIN: [
- (c(r'(.*?)()(?=\n|$)'), (TOKEN_LINECOMMENT,
- TOKEN_LINECOMMENT_END), '#pop')
- ]
- }
-
- def _normalize_newlines(self, value):
- """Called for strings and template data to normlize it to unicode."""
- return newline_re.sub(self.newline_sequence, value)
-
- def tokenize(self, source, name=None, filename=None, state=None):
- """Calls tokeniter + tokenize and wraps it in a token stream.
- """
- stream = self.tokeniter(source, name, filename, state)
- return TokenStream(self.wrap(stream, name, filename), name, filename)
-
- def wrap(self, stream, name=None, filename=None):
- """This is called with the stream as returned by `tokenize` and wraps
- every token in a :class:`Token` and converts the value.
- """
- for lineno, token, value in stream:
- if token in ignored_tokens:
- continue
- elif token == 'linestatement_begin':
- token = 'block_begin'
- elif token == 'linestatement_end':
- token = 'block_end'
- # we are not interested in those tokens in the parser
- elif token in ('raw_begin', 'raw_end'):
- continue
- elif token == 'data':
- value = self._normalize_newlines(value)
- elif token == 'keyword':
- token = value
- elif token == 'name':
- value = str(value)
- elif token == 'string':
- # try to unescape string
- try:
- value = self._normalize_newlines(value[1:-1]) \
- .encode('ascii', 'backslashreplace') \
- .decode('unicode-escape')
- except Exception, e:
- msg = str(e).split(':')[-1].strip()
- raise TemplateSyntaxError(msg, lineno, name, filename)
- # if we can express it as bytestring (ascii only)
- # we do that for support of semi broken APIs
- # as datetime.datetime.strftime. On python 3 this
- # call becomes a noop thanks to 2to3
- try:
- value = str(value)
- except UnicodeError:
- pass
- elif token == 'integer':
- value = int(value)
- elif token == 'float':
- value = float(value)
- elif token == 'operator':
- token = operators[value]
- yield Token(lineno, token, value)
-
- def tokeniter(self, source, name, filename=None, state=None):
- """This method tokenizes the text and returns the tokens in a
- generator. Use this method if you just want to tokenize a template.
- """
- source = '\n'.join(unicode(source).splitlines())
- pos = 0
- lineno = 1
- stack = ['root']
- if state is not None and state != 'root':
- assert state in ('variable', 'block'), 'invalid state'
- stack.append(state + '_begin')
- else:
- state = 'root'
- statetokens = self.rules[stack[-1]]
- source_length = len(source)
-
- balancing_stack = []
-
- while 1:
- # tokenizer loop
- for regex, tokens, new_state in statetokens:
- m = regex.match(source, pos)
- # if no match we try again with the next rule
- if m is None:
- continue
-
- # we only match blocks and variables if brances / parentheses
- # are balanced. continue parsing with the lower rule which
- # is the operator rule. do this only if the end tags look
- # like operators
- if balancing_stack and \
- tokens in ('variable_end', 'block_end',
- 'linestatement_end'):
- continue
-
- # tuples support more options
- if isinstance(tokens, tuple):
- for idx, token in enumerate(tokens):
- # failure group
- if token.__class__ is Failure:
- raise token(lineno, filename)
- # bygroup is a bit more complex, in that case we
- # yield for the current token the first named
- # group that matched
- elif token == '#bygroup':
- for key, value in m.groupdict().iteritems():
- if value is not None:
- yield lineno, key, value
- lineno += value.count('\n')
- break
- else:
- raise RuntimeError('%r wanted to resolve '
- 'the token dynamically'
- ' but no group matched'
- % regex)
- # normal group
- else:
- data = m.group(idx + 1)
- if data or token not in ignore_if_empty:
- yield lineno, token, data
- lineno += data.count('\n')
-
- # strings as token just are yielded as it.
- else:
- data = m.group()
- # update brace/parentheses balance
- if tokens == 'operator':
- if data == '{':
- balancing_stack.append('}')
- elif data == '(':
- balancing_stack.append(')')
- elif data == '[':
- balancing_stack.append(']')
- elif data in ('}', ')', ']'):
- if not balancing_stack:
- raise TemplateSyntaxError('unexpected \'%s\'' %
- data, lineno, name,
- filename)
- expected_op = balancing_stack.pop()
- if expected_op != data:
- raise TemplateSyntaxError('unexpected \'%s\', '
- 'expected \'%s\'' %
- (data, expected_op),
- lineno, name,
- filename)
- # yield items
- if data or tokens not in ignore_if_empty:
- yield lineno, tokens, data
- lineno += data.count('\n')
-
- # fetch new position into new variable so that we can check
- # if there is a internal parsing error which would result
- # in an infinite loop
- pos2 = m.end()
-
- # handle state changes
- if new_state is not None:
- # remove the uppermost state
- if new_state == '#pop':
- stack.pop()
- # resolve the new state by group checking
- elif new_state == '#bygroup':
- for key, value in m.groupdict().iteritems():
- if value is not None:
- stack.append(key)
- break
- else:
- raise RuntimeError('%r wanted to resolve the '
- 'new state dynamically but'
- ' no group matched' %
- regex)
- # direct state name given
- else:
- stack.append(new_state)
- statetokens = self.rules[stack[-1]]
- # we are still at the same position and no stack change.
- # this means a loop without break condition, avoid that and
- # raise error
- elif pos2 == pos:
- raise RuntimeError('%r yielded empty string without '
- 'stack change' % regex)
- # publish new function and start again
- pos = pos2
- break
- # if loop terminated without break we havn't found a single match
- # either we are at the end of the file or we have a problem
- else:
- # end of text
- if pos >= source_length:
- return
- # something went wrong
- raise TemplateSyntaxError('unexpected char %r at %d' %
- (source[pos], pos), lineno,
- name, filename)
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/loaders.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/loaders.py
deleted file mode 100755
index 419a9c8c..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/loaders.py
+++ /dev/null
@@ -1,450 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.loaders
- ~~~~~~~~~~~~~~
-
- Jinja loader classes.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import os
-import sys
-import weakref
-from types import ModuleType
-from os import path
-try:
- from hashlib import sha1
-except ImportError:
- from sha import new as sha1
-from jinja2.exceptions import TemplateNotFound
-from jinja2.utils import LRUCache, open_if_exists, internalcode
-
-
-def split_template_path(template):
- """Split a path into segments and perform a sanity check. If it detects
- '..' in the path it will raise a `TemplateNotFound` error.
- """
- pieces = []
- for piece in template.split('/'):
- if path.sep in piece \
- or (path.altsep and path.altsep in piece) or \
- piece == path.pardir:
- raise TemplateNotFound(template)
- elif piece and piece != '.':
- pieces.append(piece)
- return pieces
-
-
-class BaseLoader(object):
- """Baseclass for all loaders. Subclass this and override `get_source` to
- implement a custom loading mechanism. The environment provides a
- `get_template` method that calls the loader's `load` method to get the
- :class:`Template` object.
-
- A very basic example for a loader that looks up templates on the file
- system could look like this::
-
- from jinja2 import BaseLoader, TemplateNotFound
- from os.path import join, exists, getmtime
-
- class MyLoader(BaseLoader):
-
- def __init__(self, path):
- self.path = path
-
- def get_source(self, environment, template):
- path = join(self.path, template)
- if not exists(path):
- raise TemplateNotFound(template)
- mtime = getmtime(path)
- with file(path) as f:
- source = f.read().decode('utf-8')
- return source, path, lambda: mtime == getmtime(path)
- """
-
- #: if set to `False` it indicates that the loader cannot provide access
- #: to the source of templates.
- #:
- #: .. versionadded:: 2.4
- has_source_access = True
-
- def get_source(self, environment, template):
- """Get the template source, filename and reload helper for a template.
- It's passed the environment and template name and has to return a
- tuple in the form ``(source, filename, uptodate)`` or raise a
- `TemplateNotFound` error if it can't locate the template.
-
- The source part of the returned tuple must be the source of the
- template as unicode string or a ASCII bytestring. The filename should
- be the name of the file on the filesystem if it was loaded from there,
- otherwise `None`. The filename is used by python for the tracebacks
- if no loader extension is used.
-
- The last item in the tuple is the `uptodate` function. If auto
- reloading is enabled it's always called to check if the template
- changed. No arguments are passed so the function must store the
- old state somewhere (for example in a closure). If it returns `False`
- the template will be reloaded.
- """
- if not self.has_source_access:
- raise RuntimeError('%s cannot provide access to the source' %
- self.__class__.__name__)
- raise TemplateNotFound(template)
-
- def list_templates(self):
- """Iterates over all templates. If the loader does not support that
- it should raise a :exc:`TypeError` which is the default behavior.
- """
- raise TypeError('this loader cannot iterate over all templates')
-
- @internalcode
- def load(self, environment, name, globals=None):
- """Loads a template. This method looks up the template in the cache
- or loads one by calling :meth:`get_source`. Subclasses should not
- override this method as loaders working on collections of other
- loaders (such as :class:`PrefixLoader` or :class:`ChoiceLoader`)
- will not call this method but `get_source` directly.
- """
- code = None
- if globals is None:
- globals = {}
-
- # first we try to get the source for this template together
- # with the filename and the uptodate function.
- source, filename, uptodate = self.get_source(environment, name)
-
- # try to load the code from the bytecode cache if there is a
- # bytecode cache configured.
- bcc = environment.bytecode_cache
- if bcc is not None:
- bucket = bcc.get_bucket(environment, name, filename, source)
- code = bucket.code
-
- # if we don't have code so far (not cached, no longer up to
- # date) etc. we compile the template
- if code is None:
- code = environment.compile(source, name, filename)
-
- # if the bytecode cache is available and the bucket doesn't
- # have a code so far, we give the bucket the new code and put
- # it back to the bytecode cache.
- if bcc is not None and bucket.code is None:
- bucket.code = code
- bcc.set_bucket(bucket)
-
- return environment.template_class.from_code(environment, code,
- globals, uptodate)
-
-
-class FileSystemLoader(BaseLoader):
- """Loads templates from the file system. This loader can find templates
- in folders on the file system and is the preferred way to load them.
-
- The loader takes the path to the templates as string, or if multiple
- locations are wanted a list of them which is then looked up in the
- given order:
-
- >>> loader = FileSystemLoader('/path/to/templates')
- >>> loader = FileSystemLoader(['/path/to/templates', '/other/path'])
-
- Per default the template encoding is ``'utf-8'`` which can be changed
- by setting the `encoding` parameter to something else.
- """
-
- def __init__(self, searchpath, encoding='utf-8'):
- if isinstance(searchpath, basestring):
- searchpath = [searchpath]
- self.searchpath = list(searchpath)
- self.encoding = encoding
-
- def get_source(self, environment, template):
- pieces = split_template_path(template)
- for searchpath in self.searchpath:
- filename = path.join(searchpath, *pieces)
- f = open_if_exists(filename)
- if f is None:
- continue
- try:
- contents = f.read().decode(self.encoding)
- finally:
- f.close()
-
- mtime = path.getmtime(filename)
- def uptodate():
- try:
- return path.getmtime(filename) == mtime
- except OSError:
- return False
- return contents, filename, uptodate
- raise TemplateNotFound(template)
-
- def list_templates(self):
- found = set()
- for searchpath in self.searchpath:
- for dirpath, dirnames, filenames in os.walk(searchpath):
- for filename in filenames:
- template = os.path.join(dirpath, filename) \
- [len(searchpath):].strip(os.path.sep) \
- .replace(os.path.sep, '/')
- if template[:2] == './':
- template = template[2:]
- if template not in found:
- found.add(template)
- return sorted(found)
-
-
-class PackageLoader(BaseLoader):
- """Load templates from python eggs or packages. It is constructed with
- the name of the python package and the path to the templates in that
- package::
-
- loader = PackageLoader('mypackage', 'views')
-
- If the package path is not given, ``'templates'`` is assumed.
-
- Per default the template encoding is ``'utf-8'`` which can be changed
- by setting the `encoding` parameter to something else. Due to the nature
- of eggs it's only possible to reload templates if the package was loaded
- from the file system and not a zip file.
- """
-
- def __init__(self, package_name, package_path='templates',
- encoding='utf-8'):
- from pkg_resources import DefaultProvider, ResourceManager, \
- get_provider
- provider = get_provider(package_name)
- self.encoding = encoding
- self.manager = ResourceManager()
- self.filesystem_bound = isinstance(provider, DefaultProvider)
- self.provider = provider
- self.package_path = package_path
-
- def get_source(self, environment, template):
- pieces = split_template_path(template)
- p = '/'.join((self.package_path,) + tuple(pieces))
- if not self.provider.has_resource(p):
- raise TemplateNotFound(template)
-
- filename = uptodate = None
- if self.filesystem_bound:
- filename = self.provider.get_resource_filename(self.manager, p)
- mtime = path.getmtime(filename)
- def uptodate():
- try:
- return path.getmtime(filename) == mtime
- except OSError:
- return False
-
- source = self.provider.get_resource_string(self.manager, p)
- return source.decode(self.encoding), filename, uptodate
-
- def list_templates(self):
- path = self.package_path
- if path[:2] == './':
- path = path[2:]
- elif path == '.':
- path = ''
- offset = len(path)
- results = []
- def _walk(path):
- for filename in self.provider.resource_listdir(path):
- fullname = path + '/' + filename
- if self.provider.resource_isdir(fullname):
- _walk(fullname)
- else:
- results.append(fullname[offset:].lstrip('/'))
- _walk(path)
- results.sort()
- return results
-
-
-class DictLoader(BaseLoader):
- """Loads a template from a python dict. It's passed a dict of unicode
- strings bound to template names. This loader is useful for unittesting:
-
- >>> loader = DictLoader({'index.html': 'source here'})
-
- Because auto reloading is rarely useful this is disabled per default.
- """
-
- def __init__(self, mapping):
- self.mapping = mapping
-
- def get_source(self, environment, template):
- if template in self.mapping:
- source = self.mapping[template]
- return source, None, lambda: source != self.mapping.get(template)
- raise TemplateNotFound(template)
-
- def list_templates(self):
- return sorted(self.mapping)
-
-
-class FunctionLoader(BaseLoader):
- """A loader that is passed a function which does the loading. The
- function becomes the name of the template passed and has to return either
- an unicode string with the template source, a tuple in the form ``(source,
- filename, uptodatefunc)`` or `None` if the template does not exist.
-
- >>> def load_template(name):
- ... if name == 'index.html':
- ... return '...'
- ...
- >>> loader = FunctionLoader(load_template)
-
- The `uptodatefunc` is a function that is called if autoreload is enabled
- and has to return `True` if the template is still up to date. For more
- details have a look at :meth:`BaseLoader.get_source` which has the same
- return value.
- """
-
- def __init__(self, load_func):
- self.load_func = load_func
-
- def get_source(self, environment, template):
- rv = self.load_func(template)
- if rv is None:
- raise TemplateNotFound(template)
- elif isinstance(rv, basestring):
- return rv, None, None
- return rv
-
-
-class PrefixLoader(BaseLoader):
- """A loader that is passed a dict of loaders where each loader is bound
- to a prefix. The prefix is delimited from the template by a slash per
- default, which can be changed by setting the `delimiter` argument to
- something else::
-
- loader = PrefixLoader({
- 'app1': PackageLoader('mypackage.app1'),
- 'app2': PackageLoader('mypackage.app2')
- })
-
- By loading ``'app1/index.html'`` the file from the app1 package is loaded,
- by loading ``'app2/index.html'`` the file from the second.
- """
-
- def __init__(self, mapping, delimiter='/'):
- self.mapping = mapping
- self.delimiter = delimiter
-
- def get_source(self, environment, template):
- try:
- prefix, name = template.split(self.delimiter, 1)
- loader = self.mapping[prefix]
- except (ValueError, KeyError):
- raise TemplateNotFound(template)
- try:
- return loader.get_source(environment, name)
- except TemplateNotFound:
- # re-raise the exception with the correct fileame here.
- # (the one that includes the prefix)
- raise TemplateNotFound(template)
-
- def list_templates(self):
- result = []
- for prefix, loader in self.mapping.iteritems():
- for template in loader.list_templates():
- result.append(prefix + self.delimiter + template)
- return result
-
-
-class ChoiceLoader(BaseLoader):
- """This loader works like the `PrefixLoader` just that no prefix is
- specified. If a template could not be found by one loader the next one
- is tried.
-
- >>> loader = ChoiceLoader([
- ... FileSystemLoader('/path/to/user/templates'),
- ... FileSystemLoader('/path/to/system/templates')
- ... ])
-
- This is useful if you want to allow users to override builtin templates
- from a different location.
- """
-
- def __init__(self, loaders):
- self.loaders = loaders
-
- def get_source(self, environment, template):
- for loader in self.loaders:
- try:
- return loader.get_source(environment, template)
- except TemplateNotFound:
- pass
- raise TemplateNotFound(template)
-
- def list_templates(self):
- found = set()
- for loader in self.loaders:
- found.update(loader.list_templates())
- return sorted(found)
-
-
-class _TemplateModule(ModuleType):
- """Like a normal module but with support for weak references"""
-
-
-class ModuleLoader(BaseLoader):
- """This loader loads templates from precompiled templates.
-
- Example usage:
-
- >>> loader = ChoiceLoader([
- ... ModuleLoader('/path/to/compiled/templates'),
- ... FileSystemLoader('/path/to/templates')
- ... ])
-
- Templates can be precompiled with :meth:`Environment.compile_templates`.
- """
-
- has_source_access = False
-
- def __init__(self, path):
- package_name = '_jinja2_module_templates_%x' % id(self)
-
- # create a fake module that looks for the templates in the
- # path given.
- mod = _TemplateModule(package_name)
- if isinstance(path, basestring):
- path = [path]
- else:
- path = list(path)
- mod.__path__ = path
-
- sys.modules[package_name] = weakref.proxy(mod,
- lambda x: sys.modules.pop(package_name, None))
-
- # the only strong reference, the sys.modules entry is weak
- # so that the garbage collector can remove it once the
- # loader that created it goes out of business.
- self.module = mod
- self.package_name = package_name
-
- @staticmethod
- def get_template_key(name):
- return 'tmpl_' + sha1(name.encode('utf-8')).hexdigest()
-
- @staticmethod
- def get_module_filename(name):
- return ModuleLoader.get_template_key(name) + '.py'
-
- @internalcode
- def load(self, environment, name, globals=None):
- key = self.get_template_key(name)
- module = '%s.%s' % (self.package_name, key)
- mod = getattr(self.module, module, None)
- if mod is None:
- try:
- mod = __import__(module, None, None, ['root'])
- except ImportError:
- raise TemplateNotFound(name)
-
- # remove the entry from sys.modules, we only want the attribute
- # on the module object we have stored on the loader.
- sys.modules.pop(module, None)
-
- return environment.template_class.from_module_dict(
- environment, mod.__dict__, globals)
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/meta.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/meta.py
deleted file mode 100755
index 3a779a5e..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/meta.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.meta
- ~~~~~~~~~~~
-
- This module implements various functions that exposes information about
- templates that might be interesting for various kinds of applications.
-
- :copyright: (c) 2010 by the Jinja Team, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-from jinja2 import nodes
-from jinja2.compiler import CodeGenerator
-
-
-class TrackingCodeGenerator(CodeGenerator):
- """We abuse the code generator for introspection."""
-
- def __init__(self, environment):
- CodeGenerator.__init__(self, environment, '<introspection>',
- '<introspection>')
- self.undeclared_identifiers = set()
-
- def write(self, x):
- """Don't write."""
-
- def pull_locals(self, frame):
- """Remember all undeclared identifiers."""
- self.undeclared_identifiers.update(frame.identifiers.undeclared)
-
-
-def find_undeclared_variables(ast):
- """Returns a set of all variables in the AST that will be looked up from
- the context at runtime. Because at compile time it's not known which
- variables will be used depending on the path the execution takes at
- runtime, all variables are returned.
-
- >>> from jinja2 import Environment, meta
- >>> env = Environment()
- >>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
- >>> meta.find_undeclared_variables(ast)
- set(['bar'])
-
- .. admonition:: Implementation
-
- Internally the code generator is used for finding undeclared variables.
- This is good to know because the code generator might raise a
- :exc:`TemplateAssertionError` during compilation and as a matter of
- fact this function can currently raise that exception as well.
- """
- codegen = TrackingCodeGenerator(ast.environment)
- codegen.visit(ast)
- return codegen.undeclared_identifiers
-
-
-def find_referenced_templates(ast):
- """Finds all the referenced templates from the AST. This will return an
- iterator over all the hardcoded template extensions, inclusions and
- imports. If dynamic inheritance or inclusion is used, `None` will be
- yielded.
-
- >>> from jinja2 import Environment, meta
- >>> env = Environment()
- >>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
- >>> list(meta.find_referenced_templates(ast))
- ['layout.html', None]
-
- This function is useful for dependency tracking. For example if you want
- to rebuild parts of the website after a layout template has changed.
- """
- for node in ast.find_all((nodes.Extends, nodes.FromImport, nodes.Import,
- nodes.Include)):
- if not isinstance(node.template, nodes.Const):
- # a tuple with some non consts in there
- if isinstance(node.template, (nodes.Tuple, nodes.List)):
- for template_name in node.template.items:
- # something const, only yield the strings and ignore
- # non-string consts that really just make no sense
- if isinstance(template_name, nodes.Const):
- if isinstance(template_name.value, basestring):
- yield template_name.value
- # something dynamic in there
- else:
- yield None
- # something dynamic we don't know about here
- else:
- yield None
- continue
- # constant is a basestring, direct template name
- if isinstance(node.template.value, basestring):
- yield node.template.value
- # a tuple or list (latter *should* not happen) made of consts,
- # yield the consts that are strings. We could warn here for
- # non string values
- elif isinstance(node, nodes.Include) and \
- isinstance(node.template.value, (tuple, list)):
- for template_name in node.template.value:
- if isinstance(template_name, basestring):
- yield template_name
- # something else we don't care about, we could warn here
- else:
- yield None
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/nodes.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/nodes.py
deleted file mode 100755
index f9da1da5..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/nodes.py
+++ /dev/null
@@ -1,910 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.nodes
- ~~~~~~~~~~~~
-
- This module implements additional nodes derived from the ast base node.
-
- It also provides some node tree helper functions like `in_lineno` and
- `get_nodes` used by the parser and translator in order to normalize
- python and jinja nodes.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import operator
-from itertools import chain, izip
-from collections import deque
-from jinja2.utils import Markup, MethodType, FunctionType
-
-
-#: the types we support for context functions
-_context_function_types = (FunctionType, MethodType)
-
-
-_binop_to_func = {
- '*': operator.mul,
- '/': operator.truediv,
- '//': operator.floordiv,
- '**': operator.pow,
- '%': operator.mod,
- '+': operator.add,
- '-': operator.sub
-}
-
-_uaop_to_func = {
- 'not': operator.not_,
- '+': operator.pos,
- '-': operator.neg
-}
-
-_cmpop_to_func = {
- 'eq': operator.eq,
- 'ne': operator.ne,
- 'gt': operator.gt,
- 'gteq': operator.ge,
- 'lt': operator.lt,
- 'lteq': operator.le,
- 'in': lambda a, b: a in b,
- 'notin': lambda a, b: a not in b
-}
-
-
-class Impossible(Exception):
- """Raised if the node could not perform a requested action."""
-
-
-class NodeType(type):
- """A metaclass for nodes that handles the field and attribute
- inheritance. fields and attributes from the parent class are
- automatically forwarded to the child."""
-
- def __new__(cls, name, bases, d):
- for attr in 'fields', 'attributes':
- storage = []
- storage.extend(getattr(bases[0], attr, ()))
- storage.extend(d.get(attr, ()))
- assert len(bases) == 1, 'multiple inheritance not allowed'
- assert len(storage) == len(set(storage)), 'layout conflict'
- d[attr] = tuple(storage)
- d.setdefault('abstract', False)
- return type.__new__(cls, name, bases, d)
-
-
-class EvalContext(object):
- """Holds evaluation time information. Custom attributes can be attached
- to it in extensions.
- """
-
- def __init__(self, environment, template_name=None):
- self.environment = environment
- if callable(environment.autoescape):
- self.autoescape = environment.autoescape(template_name)
- else:
- self.autoescape = environment.autoescape
- self.volatile = False
-
- def save(self):
- return self.__dict__.copy()
-
- def revert(self, old):
- self.__dict__.clear()
- self.__dict__.update(old)
-
-
-def get_eval_context(node, ctx):
- if ctx is None:
- if node.environment is None:
- raise RuntimeError('if no eval context is passed, the '
- 'node must have an attached '
- 'environment.')
- return EvalContext(node.environment)
- return ctx
-
-
-class Node(object):
- """Baseclass for all Jinja2 nodes. There are a number of nodes available
- of different types. There are three major types:
-
- - :class:`Stmt`: statements
- - :class:`Expr`: expressions
- - :class:`Helper`: helper nodes
- - :class:`Template`: the outermost wrapper node
-
- All nodes have fields and attributes. Fields may be other nodes, lists,
- or arbitrary values. Fields are passed to the constructor as regular
- positional arguments, attributes as keyword arguments. Each node has
- two attributes: `lineno` (the line number of the node) and `environment`.
- The `environment` attribute is set at the end of the parsing process for
- all nodes automatically.
- """
- __metaclass__ = NodeType
- fields = ()
- attributes = ('lineno', 'environment')
- abstract = True
-
- def __init__(self, *fields, **attributes):
- if self.abstract:
- raise TypeError('abstract nodes are not instanciable')
- if fields:
- if len(fields) != len(self.fields):
- if not self.fields:
- raise TypeError('%r takes 0 arguments' %
- self.__class__.__name__)
- raise TypeError('%r takes 0 or %d argument%s' % (
- self.__class__.__name__,
- len(self.fields),
- len(self.fields) != 1 and 's' or ''
- ))
- for name, arg in izip(self.fields, fields):
- setattr(self, name, arg)
- for attr in self.attributes:
- setattr(self, attr, attributes.pop(attr, None))
- if attributes:
- raise TypeError('unknown attribute %r' %
- iter(attributes).next())
-
- def iter_fields(self, exclude=None, only=None):
- """This method iterates over all fields that are defined and yields
- ``(key, value)`` tuples. Per default all fields are returned, but
- it's possible to limit that to some fields by providing the `only`
- parameter or to exclude some using the `exclude` parameter. Both
- should be sets or tuples of field names.
- """
- for name in self.fields:
- if (exclude is only is None) or \
- (exclude is not None and name not in exclude) or \
- (only is not None and name in only):
- try:
- yield name, getattr(self, name)
- except AttributeError:
- pass
-
- def iter_child_nodes(self, exclude=None, only=None):
- """Iterates over all direct child nodes of the node. This iterates
- over all fields and yields the values of they are nodes. If the value
- of a field is a list all the nodes in that list are returned.
- """
- for field, item in self.iter_fields(exclude, only):
- if isinstance(item, list):
- for n in item:
- if isinstance(n, Node):
- yield n
- elif isinstance(item, Node):
- yield item
-
- def find(self, node_type):
- """Find the first node of a given type. If no such node exists the
- return value is `None`.
- """
- for result in self.find_all(node_type):
- return result
-
- def find_all(self, node_type):
- """Find all the nodes of a given type. If the type is a tuple,
- the check is performed for any of the tuple items.
- """
- for child in self.iter_child_nodes():
- if isinstance(child, node_type):
- yield child
- for result in child.find_all(node_type):
- yield result
-
- def set_ctx(self, ctx):
- """Reset the context of a node and all child nodes. Per default the
- parser will all generate nodes that have a 'load' context as it's the
- most common one. This method is used in the parser to set assignment
- targets and other nodes to a store context.
- """
- todo = deque([self])
- while todo:
- node = todo.popleft()
- if 'ctx' in node.fields:
- node.ctx = ctx
- todo.extend(node.iter_child_nodes())
- return self
-
- def set_lineno(self, lineno, override=False):
- """Set the line numbers of the node and children."""
- todo = deque([self])
- while todo:
- node = todo.popleft()
- if 'lineno' in node.attributes:
- if node.lineno is None or override:
- node.lineno = lineno
- todo.extend(node.iter_child_nodes())
- return self
-
- def set_environment(self, environment):
- """Set the environment for all nodes."""
- todo = deque([self])
- while todo:
- node = todo.popleft()
- node.environment = environment
- todo.extend(node.iter_child_nodes())
- return self
-
- def __eq__(self, other):
- return type(self) is type(other) and \
- tuple(self.iter_fields()) == tuple(other.iter_fields())
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return '%s(%s)' % (
- self.__class__.__name__,
- ', '.join('%s=%r' % (arg, getattr(self, arg, None)) for
- arg in self.fields)
- )
-
-
-class Stmt(Node):
- """Base node for all statements."""
- abstract = True
-
-
-class Helper(Node):
- """Nodes that exist in a specific context only."""
- abstract = True
-
-
-class Template(Node):
- """Node that represents a template. This must be the outermost node that
- is passed to the compiler.
- """
- fields = ('body',)
-
-
-class Output(Stmt):
- """A node that holds multiple expressions which are then printed out.
- This is used both for the `print` statement and the regular template data.
- """
- fields = ('nodes',)
-
-
-class Extends(Stmt):
- """Represents an extends statement."""
- fields = ('template',)
-
-
-class For(Stmt):
- """The for loop. `target` is the target for the iteration (usually a
- :class:`Name` or :class:`Tuple`), `iter` the iterable. `body` is a list
- of nodes that are used as loop-body, and `else_` a list of nodes for the
- `else` block. If no else node exists it has to be an empty list.
-
- For filtered nodes an expression can be stored as `test`, otherwise `None`.
- """
- fields = ('target', 'iter', 'body', 'else_', 'test', 'recursive')
-
-
-class If(Stmt):
- """If `test` is true, `body` is rendered, else `else_`."""
- fields = ('test', 'body', 'else_')
-
-
-class Macro(Stmt):
- """A macro definition. `name` is the name of the macro, `args` a list of
- arguments and `defaults` a list of defaults if there are any. `body` is
- a list of nodes for the macro body.
- """
- fields = ('name', 'args', 'defaults', 'body')
-
-
-class CallBlock(Stmt):
- """Like a macro without a name but a call instead. `call` is called with
- the unnamed macro as `caller` argument this node holds.
- """
- fields = ('call', 'args', 'defaults', 'body')
-
-
-class FilterBlock(Stmt):
- """Node for filter sections."""
- fields = ('body', 'filter')
-
-
-class Block(Stmt):
- """A node that represents a block."""
- fields = ('name', 'body', 'scoped')
-
-
-class Include(Stmt):
- """A node that represents the include tag."""
- fields = ('template', 'with_context', 'ignore_missing')
-
-
-class Import(Stmt):
- """A node that represents the import tag."""
- fields = ('template', 'target', 'with_context')
-
-
-class FromImport(Stmt):
- """A node that represents the from import tag. It's important to not
- pass unsafe names to the name attribute. The compiler translates the
- attribute lookups directly into getattr calls and does *not* use the
- subscript callback of the interface. As exported variables may not
- start with double underscores (which the parser asserts) this is not a
- problem for regular Jinja code, but if this node is used in an extension
- extra care must be taken.
-
- The list of names may contain tuples if aliases are wanted.
- """
- fields = ('template', 'names', 'with_context')
-
-
-class ExprStmt(Stmt):
- """A statement that evaluates an expression and discards the result."""
- fields = ('node',)
-
-
-class Assign(Stmt):
- """Assigns an expression to a target."""
- fields = ('target', 'node')
-
-
-class Expr(Node):
- """Baseclass for all expressions."""
- abstract = True
-
- def as_const(self, eval_ctx=None):
- """Return the value of the expression as constant or raise
- :exc:`Impossible` if this was not possible.
-
- An :class:`EvalContext` can be provided, if none is given
- a default context is created which requires the nodes to have
- an attached environment.
-
- .. versionchanged:: 2.4
- the `eval_ctx` parameter was added.
- """
- raise Impossible()
-
- def can_assign(self):
- """Check if it's possible to assign something to this node."""
- return False
-
-
-class BinExpr(Expr):
- """Baseclass for all binary expressions."""
- fields = ('left', 'right')
- operator = None
- abstract = True
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- # intercepted operators cannot be folded at compile time
- if self.environment.sandboxed and \
- self.operator in self.environment.intercepted_binops:
- raise Impossible()
- f = _binop_to_func[self.operator]
- try:
- return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx))
- except Exception:
- raise Impossible()
-
-
-class UnaryExpr(Expr):
- """Baseclass for all unary expressions."""
- fields = ('node',)
- operator = None
- abstract = True
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- # intercepted operators cannot be folded at compile time
- if self.environment.sandboxed and \
- self.operator in self.environment.intercepted_unops:
- raise Impossible()
- f = _uaop_to_func[self.operator]
- try:
- return f(self.node.as_const(eval_ctx))
- except Exception:
- raise Impossible()
-
-
-class Name(Expr):
- """Looks up a name or stores a value in a name.
- The `ctx` of the node can be one of the following values:
-
- - `store`: store a value in the name
- - `load`: load that name
- - `param`: like `store` but if the name was defined as function parameter.
- """
- fields = ('name', 'ctx')
-
- def can_assign(self):
- return self.name not in ('true', 'false', 'none',
- 'True', 'False', 'None')
-
-
-class Literal(Expr):
- """Baseclass for literals."""
- abstract = True
-
-
-class Const(Literal):
- """All constant values. The parser will return this node for simple
- constants such as ``42`` or ``"foo"`` but it can be used to store more
- complex values such as lists too. Only constants with a safe
- representation (objects where ``eval(repr(x)) == x`` is true).
- """
- fields = ('value',)
-
- def as_const(self, eval_ctx=None):
- return self.value
-
- @classmethod
- def from_untrusted(cls, value, lineno=None, environment=None):
- """Return a const object if the value is representable as
- constant value in the generated code, otherwise it will raise
- an `Impossible` exception.
- """
- from compiler import has_safe_repr
- if not has_safe_repr(value):
- raise Impossible()
- return cls(value, lineno=lineno, environment=environment)
-
-
-class TemplateData(Literal):
- """A constant template string."""
- fields = ('data',)
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- if eval_ctx.volatile:
- raise Impossible()
- if eval_ctx.autoescape:
- return Markup(self.data)
- return self.data
-
-
-class Tuple(Literal):
- """For loop unpacking and some other things like multiple arguments
- for subscripts. Like for :class:`Name` `ctx` specifies if the tuple
- is used for loading the names or storing.
- """
- fields = ('items', 'ctx')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return tuple(x.as_const(eval_ctx) for x in self.items)
-
- def can_assign(self):
- for item in self.items:
- if not item.can_assign():
- return False
- return True
-
-
-class List(Literal):
- """Any list literal such as ``[1, 2, 3]``"""
- fields = ('items',)
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return [x.as_const(eval_ctx) for x in self.items]
-
-
-class Dict(Literal):
- """Any dict literal such as ``{1: 2, 3: 4}``. The items must be a list of
- :class:`Pair` nodes.
- """
- fields = ('items',)
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return dict(x.as_const(eval_ctx) for x in self.items)
-
-
-class Pair(Helper):
- """A key, value pair for dicts."""
- fields = ('key', 'value')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
-
-
-class Keyword(Helper):
- """A key, value pair for keyword arguments where key is a string."""
- fields = ('key', 'value')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return self.key, self.value.as_const(eval_ctx)
-
-
-class CondExpr(Expr):
- """A conditional expression (inline if expression). (``{{
- foo if bar else baz }}``)
- """
- fields = ('test', 'expr1', 'expr2')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- if self.test.as_const(eval_ctx):
- return self.expr1.as_const(eval_ctx)
-
- # if we evaluate to an undefined object, we better do that at runtime
- if self.expr2 is None:
- raise Impossible()
-
- return self.expr2.as_const(eval_ctx)
-
-
-class Filter(Expr):
- """This node applies a filter on an expression. `name` is the name of
- the filter, the rest of the fields are the same as for :class:`Call`.
-
- If the `node` of a filter is `None` the contents of the last buffer are
- filtered. Buffers are created by macros and filter blocks.
- """
- fields = ('node', 'name', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- if eval_ctx.volatile or self.node is None:
- raise Impossible()
- # we have to be careful here because we call filter_ below.
- # if this variable would be called filter, 2to3 would wrap the
- # call in a list beause it is assuming we are talking about the
- # builtin filter function here which no longer returns a list in
- # python 3. because of that, do not rename filter_ to filter!
- filter_ = self.environment.filters.get(self.name)
- if filter_ is None or getattr(filter_, 'contextfilter', False):
- raise Impossible()
- obj = self.node.as_const(eval_ctx)
- args = [x.as_const(eval_ctx) for x in self.args]
- if getattr(filter_, 'evalcontextfilter', False):
- args.insert(0, eval_ctx)
- elif getattr(filter_, 'environmentfilter', False):
- args.insert(0, self.environment)
- kwargs = dict(x.as_const(eval_ctx) for x in self.kwargs)
- if self.dyn_args is not None:
- try:
- args.extend(self.dyn_args.as_const(eval_ctx))
- except Exception:
- raise Impossible()
- if self.dyn_kwargs is not None:
- try:
- kwargs.update(self.dyn_kwargs.as_const(eval_ctx))
- except Exception:
- raise Impossible()
- try:
- return filter_(obj, *args, **kwargs)
- except Exception:
- raise Impossible()
-
-
-class Test(Expr):
- """Applies a test on an expression. `name` is the name of the test, the
- rest of the fields are the same as for :class:`Call`.
- """
- fields = ('node', 'name', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
-
-
-class Call(Expr):
- """Calls an expression. `args` is a list of arguments, `kwargs` a list
- of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args`
- and `dyn_kwargs` has to be either `None` or a node that is used as
- node for dynamic positional (``*args``) or keyword (``**kwargs``)
- arguments.
- """
- fields = ('node', 'args', 'kwargs', 'dyn_args', 'dyn_kwargs')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- if eval_ctx.volatile:
- raise Impossible()
- obj = self.node.as_const(eval_ctx)
-
- # don't evaluate context functions
- args = [x.as_const(eval_ctx) for x in self.args]
- if isinstance(obj, _context_function_types):
- if getattr(obj, 'contextfunction', False):
- raise Impossible()
- elif getattr(obj, 'evalcontextfunction', False):
- args.insert(0, eval_ctx)
- elif getattr(obj, 'environmentfunction', False):
- args.insert(0, self.environment)
-
- kwargs = dict(x.as_const(eval_ctx) for x in self.kwargs)
- if self.dyn_args is not None:
- try:
- args.extend(self.dyn_args.as_const(eval_ctx))
- except Exception:
- raise Impossible()
- if self.dyn_kwargs is not None:
- try:
- kwargs.update(self.dyn_kwargs.as_const(eval_ctx))
- except Exception:
- raise Impossible()
- try:
- return obj(*args, **kwargs)
- except Exception:
- raise Impossible()
-
-
-class Getitem(Expr):
- """Get an attribute or item from an expression and prefer the item."""
- fields = ('node', 'arg', 'ctx')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- if self.ctx != 'load':
- raise Impossible()
- try:
- return self.environment.getitem(self.node.as_const(eval_ctx),
- self.arg.as_const(eval_ctx))
- except Exception:
- raise Impossible()
-
- def can_assign(self):
- return False
-
-
-class Getattr(Expr):
- """Get an attribute or item from an expression that is a ascii-only
- bytestring and prefer the attribute.
- """
- fields = ('node', 'attr', 'ctx')
-
- def as_const(self, eval_ctx=None):
- if self.ctx != 'load':
- raise Impossible()
- try:
- eval_ctx = get_eval_context(self, eval_ctx)
- return self.environment.getattr(self.node.as_const(eval_ctx),
- self.attr)
- except Exception:
- raise Impossible()
-
- def can_assign(self):
- return False
-
-
-class Slice(Expr):
- """Represents a slice object. This must only be used as argument for
- :class:`Subscript`.
- """
- fields = ('start', 'stop', 'step')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- def const(obj):
- if obj is None:
- return None
- return obj.as_const(eval_ctx)
- return slice(const(self.start), const(self.stop), const(self.step))
-
-
-class Concat(Expr):
- """Concatenates the list of expressions provided after converting them to
- unicode.
- """
- fields = ('nodes',)
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return ''.join(unicode(x.as_const(eval_ctx)) for x in self.nodes)
-
-
-class Compare(Expr):
- """Compares an expression with some other expressions. `ops` must be a
- list of :class:`Operand`\s.
- """
- fields = ('expr', 'ops')
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- result = value = self.expr.as_const(eval_ctx)
- try:
- for op in self.ops:
- new_value = op.expr.as_const(eval_ctx)
- result = _cmpop_to_func[op.op](value, new_value)
- value = new_value
- except Exception:
- raise Impossible()
- return result
-
-
-class Operand(Helper):
- """Holds an operator and an expression."""
- fields = ('op', 'expr')
-
-if __debug__:
- Operand.__doc__ += '\nThe following operators are available: ' + \
- ', '.join(sorted('``%s``' % x for x in set(_binop_to_func) |
- set(_uaop_to_func) | set(_cmpop_to_func)))
-
-
-class Mul(BinExpr):
- """Multiplies the left with the right node."""
- operator = '*'
-
-
-class Div(BinExpr):
- """Divides the left by the right node."""
- operator = '/'
-
-
-class FloorDiv(BinExpr):
- """Divides the left by the right node and truncates conver the
- result into an integer by truncating.
- """
- operator = '//'
-
-
-class Add(BinExpr):
- """Add the left to the right node."""
- operator = '+'
-
-
-class Sub(BinExpr):
- """Substract the right from the left node."""
- operator = '-'
-
-
-class Mod(BinExpr):
- """Left modulo right."""
- operator = '%'
-
-
-class Pow(BinExpr):
- """Left to the power of right."""
- operator = '**'
-
-
-class And(BinExpr):
- """Short circuited AND."""
- operator = 'and'
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)
-
-
-class Or(BinExpr):
- """Short circuited OR."""
- operator = 'or'
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)
-
-
-class Not(UnaryExpr):
- """Negate the expression."""
- operator = 'not'
-
-
-class Neg(UnaryExpr):
- """Make the expression negative."""
- operator = '-'
-
-
-class Pos(UnaryExpr):
- """Make the expression positive (noop for most expressions)"""
- operator = '+'
-
-
-# Helpers for extensions
-
-
-class EnvironmentAttribute(Expr):
- """Loads an attribute from the environment object. This is useful for
- extensions that want to call a callback stored on the environment.
- """
- fields = ('name',)
-
-
-class ExtensionAttribute(Expr):
- """Returns the attribute of an extension bound to the environment.
- The identifier is the identifier of the :class:`Extension`.
-
- This node is usually constructed by calling the
- :meth:`~jinja2.ext.Extension.attr` method on an extension.
- """
- fields = ('identifier', 'name')
-
-
-class ImportedName(Expr):
- """If created with an import name the import name is returned on node
- access. For example ``ImportedName('cgi.escape')`` returns the `escape`
- function from the cgi module on evaluation. Imports are optimized by the
- compiler so there is no need to assign them to local variables.
- """
- fields = ('importname',)
-
-
-class InternalName(Expr):
- """An internal name in the compiler. You cannot create these nodes
- yourself but the parser provides a
- :meth:`~jinja2.parser.Parser.free_identifier` method that creates
- a new identifier for you. This identifier is not available from the
- template and is not threated specially by the compiler.
- """
- fields = ('name',)
-
- def __init__(self):
- raise TypeError('Can\'t create internal names. Use the '
- '`free_identifier` method on a parser.')
-
-
-class MarkSafe(Expr):
- """Mark the wrapped expression as safe (wrap it as `Markup`)."""
- fields = ('expr',)
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- return Markup(self.expr.as_const(eval_ctx))
-
-
-class MarkSafeIfAutoescape(Expr):
- """Mark the wrapped expression as safe (wrap it as `Markup`) but
- only if autoescaping is active.
-
- .. versionadded:: 2.5
- """
- fields = ('expr',)
-
- def as_const(self, eval_ctx=None):
- eval_ctx = get_eval_context(self, eval_ctx)
- if eval_ctx.volatile:
- raise Impossible()
- expr = self.expr.as_const(eval_ctx)
- if eval_ctx.autoescape:
- return Markup(expr)
- return expr
-
-
-class ContextReference(Expr):
- """Returns the current template context. It can be used like a
- :class:`Name` node, with a ``'load'`` ctx and will return the
- current :class:`~jinja2.runtime.Context` object.
-
- Here an example that assigns the current template name to a
- variable named `foo`::
-
- Assign(Name('foo', ctx='store'),
- Getattr(ContextReference(), 'name'))
- """
-
-
-class Continue(Stmt):
- """Continue a loop."""
-
-
-class Break(Stmt):
- """Break a loop."""
-
-
-class Scope(Stmt):
- """An artificial scope."""
- fields = ('body',)
-
-
-class EvalContextModifier(Stmt):
- """Modifies the eval context. For each option that should be modified,
- a :class:`Keyword` has to be added to the :attr:`options` list.
-
- Example to change the `autoescape` setting::
-
- EvalContextModifier(options=[Keyword('autoescape', Const(True))])
- """
- fields = ('options',)
-
-
-class ScopedEvalContextModifier(EvalContextModifier):
- """Modifies the eval context and reverts it later. Works exactly like
- :class:`EvalContextModifier` but will only modify the
- :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
- """
- fields = ('body',)
-
-
-# make sure nobody creates custom nodes
-def _failing_new(*args, **kwargs):
- raise TypeError('can\'t create custom node types')
-NodeType.__new__ = staticmethod(_failing_new); del _failing_new
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/optimizer.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/optimizer.py
deleted file mode 100755
index 00eab115..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/optimizer.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.optimizer
- ~~~~~~~~~~~~~~~~
-
- The jinja optimizer is currently trying to constant fold a few expressions
- and modify the AST in place so that it should be easier to evaluate it.
-
- Because the AST does not contain all the scoping information and the
- compiler has to find that out, we cannot do all the optimizations we
- want. For example loop unrolling doesn't work because unrolled loops would
- have a different scoping.
-
- The solution would be a second syntax tree that has the scoping rules stored.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD.
-"""
-from jinja2 import nodes
-from jinja2.visitor import NodeTransformer
-
-
-def optimize(node, environment):
- """The context hint can be used to perform an static optimization
- based on the context given."""
- optimizer = Optimizer(environment)
- return optimizer.visit(node)
-
-
-class Optimizer(NodeTransformer):
-
- def __init__(self, environment):
- self.environment = environment
-
- def visit_If(self, node):
- """Eliminate dead code."""
- # do not optimize ifs that have a block inside so that it doesn't
- # break super().
- if node.find(nodes.Block) is not None:
- return self.generic_visit(node)
- try:
- val = self.visit(node.test).as_const()
- except nodes.Impossible:
- return self.generic_visit(node)
- if val:
- body = node.body
- else:
- body = node.else_
- result = []
- for node in body:
- result.extend(self.visit_list(node))
- return result
-
- def fold(self, node):
- """Do constant folding."""
- node = self.generic_visit(node)
- try:
- return nodes.Const.from_untrusted(node.as_const(),
- lineno=node.lineno,
- environment=self.environment)
- except nodes.Impossible:
- return node
-
- visit_Add = visit_Sub = visit_Mul = visit_Div = visit_FloorDiv = \
- visit_Pow = visit_Mod = visit_And = visit_Or = visit_Pos = visit_Neg = \
- visit_Not = visit_Compare = visit_Getitem = visit_Getattr = visit_Call = \
- visit_Filter = visit_Test = visit_CondExpr = fold
- del fold
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/parser.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/parser.py
deleted file mode 100755
index d44229ad..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/parser.py
+++ /dev/null
@@ -1,896 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.parser
- ~~~~~~~~~~~~~
-
- Implements the template parser.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-from jinja2 import nodes
-from jinja2.exceptions import TemplateSyntaxError, TemplateAssertionError
-from jinja2.utils import next
-from jinja2.lexer import describe_token, describe_token_expr
-
-
-#: statements that callinto
-_statement_keywords = frozenset(['for', 'if', 'block', 'extends', 'print',
- 'macro', 'include', 'from', 'import',
- 'set'])
-_compare_operators = frozenset(['eq', 'ne', 'lt', 'lteq', 'gt', 'gteq'])
-
-
-class Parser(object):
- """This is the central parsing class Jinja2 uses. It's passed to
- extensions and can be used to parse expressions or statements.
- """
-
- def __init__(self, environment, source, name=None, filename=None,
- state=None):
- self.environment = environment
- self.stream = environment._tokenize(source, name, filename, state)
- self.name = name
- self.filename = filename
- self.closed = False
- self.extensions = {}
- for extension in environment.iter_extensions():
- for tag in extension.tags:
- self.extensions[tag] = extension.parse
- self._last_identifier = 0
- self._tag_stack = []
- self._end_token_stack = []
-
- def fail(self, msg, lineno=None, exc=TemplateSyntaxError):
- """Convenience method that raises `exc` with the message, passed
- line number or last line number as well as the current name and
- filename.
- """
- if lineno is None:
- lineno = self.stream.current.lineno
- raise exc(msg, lineno, self.name, self.filename)
-
- def _fail_ut_eof(self, name, end_token_stack, lineno):
- expected = []
- for exprs in end_token_stack:
- expected.extend(map(describe_token_expr, exprs))
- if end_token_stack:
- currently_looking = ' or '.join(
- "'%s'" % describe_token_expr(expr)
- for expr in end_token_stack[-1])
- else:
- currently_looking = None
-
- if name is None:
- message = ['Unexpected end of template.']
- else:
- message = ['Encountered unknown tag \'%s\'.' % name]
-
- if currently_looking:
- if name is not None and name in expected:
- message.append('You probably made a nesting mistake. Jinja '
- 'is expecting this tag, but currently looking '
- 'for %s.' % currently_looking)
- else:
- message.append('Jinja was looking for the following tags: '
- '%s.' % currently_looking)
-
- if self._tag_stack:
- message.append('The innermost block that needs to be '
- 'closed is \'%s\'.' % self._tag_stack[-1])
-
- self.fail(' '.join(message), lineno)
-
- def fail_unknown_tag(self, name, lineno=None):
- """Called if the parser encounters an unknown tag. Tries to fail
- with a human readable error message that could help to identify
- the problem.
- """
- return self._fail_ut_eof(name, self._end_token_stack, lineno)
-
- def fail_eof(self, end_tokens=None, lineno=None):
- """Like fail_unknown_tag but for end of template situations."""
- stack = list(self._end_token_stack)
- if end_tokens is not None:
- stack.append(end_tokens)
- return self._fail_ut_eof(None, stack, lineno)
-
- def is_tuple_end(self, extra_end_rules=None):
- """Are we at the end of a tuple?"""
- if self.stream.current.type in ('variable_end', 'block_end', 'rparen'):
- return True
- elif extra_end_rules is not None:
- return self.stream.current.test_any(extra_end_rules)
- return False
-
- def free_identifier(self, lineno=None):
- """Return a new free identifier as :class:`~jinja2.nodes.InternalName`."""
- self._last_identifier += 1
- rv = object.__new__(nodes.InternalName)
- nodes.Node.__init__(rv, 'fi%d' % self._last_identifier, lineno=lineno)
- return rv
-
- def parse_statement(self):
- """Parse a single statement."""
- token = self.stream.current
- if token.type != 'name':
- self.fail('tag name expected', token.lineno)
- self._tag_stack.append(token.value)
- pop_tag = True
- try:
- if token.value in _statement_keywords:
- return getattr(self, 'parse_' + self.stream.current.value)()
- if token.value == 'call':
- return self.parse_call_block()
- if token.value == 'filter':
- return self.parse_filter_block()
- ext = self.extensions.get(token.value)
- if ext is not None:
- return ext(self)
-
- # did not work out, remove the token we pushed by accident
- # from the stack so that the unknown tag fail function can
- # produce a proper error message.
- self._tag_stack.pop()
- pop_tag = False
- self.fail_unknown_tag(token.value, token.lineno)
- finally:
- if pop_tag:
- self._tag_stack.pop()
-
- def parse_statements(self, end_tokens, drop_needle=False):
- """Parse multiple statements into a list until one of the end tokens
- is reached. This is used to parse the body of statements as it also
- parses template data if appropriate. The parser checks first if the
- current token is a colon and skips it if there is one. Then it checks
- for the block end and parses until if one of the `end_tokens` is
- reached. Per default the active token in the stream at the end of
- the call is the matched end token. If this is not wanted `drop_needle`
- can be set to `True` and the end token is removed.
- """
- # the first token may be a colon for python compatibility
- self.stream.skip_if('colon')
-
- # in the future it would be possible to add whole code sections
- # by adding some sort of end of statement token and parsing those here.
- self.stream.expect('block_end')
- result = self.subparse(end_tokens)
-
- # we reached the end of the template too early, the subparser
- # does not check for this, so we do that now
- if self.stream.current.type == 'eof':
- self.fail_eof(end_tokens)
-
- if drop_needle:
- next(self.stream)
- return result
-
- def parse_set(self):
- """Parse an assign statement."""
- lineno = next(self.stream).lineno
- target = self.parse_assign_target()
- self.stream.expect('assign')
- expr = self.parse_tuple()
- return nodes.Assign(target, expr, lineno=lineno)
-
- def parse_for(self):
- """Parse a for loop."""
- lineno = self.stream.expect('name:for').lineno
- target = self.parse_assign_target(extra_end_rules=('name:in',))
- self.stream.expect('name:in')
- iter = self.parse_tuple(with_condexpr=False,
- extra_end_rules=('name:recursive',))
- test = None
- if self.stream.skip_if('name:if'):
- test = self.parse_expression()
- recursive = self.stream.skip_if('name:recursive')
- body = self.parse_statements(('name:endfor', 'name:else'))
- if next(self.stream).value == 'endfor':
- else_ = []
- else:
- else_ = self.parse_statements(('name:endfor',), drop_needle=True)
- return nodes.For(target, iter, body, else_, test,
- recursive, lineno=lineno)
-
- def parse_if(self):
- """Parse an if construct."""
- node = result = nodes.If(lineno=self.stream.expect('name:if').lineno)
- while 1:
- node.test = self.parse_tuple(with_condexpr=False)
- node.body = self.parse_statements(('name:elif', 'name:else',
- 'name:endif'))
- token = next(self.stream)
- if token.test('name:elif'):
- new_node = nodes.If(lineno=self.stream.current.lineno)
- node.else_ = [new_node]
- node = new_node
- continue
- elif token.test('name:else'):
- node.else_ = self.parse_statements(('name:endif',),
- drop_needle=True)
- else:
- node.else_ = []
- break
- return result
-
- def parse_block(self):
- node = nodes.Block(lineno=next(self.stream).lineno)
- node.name = self.stream.expect('name').value
- node.scoped = self.stream.skip_if('name:scoped')
-
- # common problem people encounter when switching from django
- # to jinja. we do not support hyphens in block names, so let's
- # raise a nicer error message in that case.
- if self.stream.current.type == 'sub':
- self.fail('Block names in Jinja have to be valid Python '
- 'identifiers and may not contain hypens, use an '
- 'underscore instead.')
-
- node.body = self.parse_statements(('name:endblock',), drop_needle=True)
- self.stream.skip_if('name:' + node.name)
- return node
-
- def parse_extends(self):
- node = nodes.Extends(lineno=next(self.stream).lineno)
- node.template = self.parse_expression()
- return node
-
- def parse_import_context(self, node, default):
- if self.stream.current.test_any('name:with', 'name:without') and \
- self.stream.look().test('name:context'):
- node.with_context = next(self.stream).value == 'with'
- self.stream.skip()
- else:
- node.with_context = default
- return node
-
- def parse_include(self):
- node = nodes.Include(lineno=next(self.stream).lineno)
- node.template = self.parse_expression()
- if self.stream.current.test('name:ignore') and \
- self.stream.look().test('name:missing'):
- node.ignore_missing = True
- self.stream.skip(2)
- else:
- node.ignore_missing = False
- return self.parse_import_context(node, True)
-
- def parse_import(self):
- node = nodes.Import(lineno=next(self.stream).lineno)
- node.template = self.parse_expression()
- self.stream.expect('name:as')
- node.target = self.parse_assign_target(name_only=True).name
- return self.parse_import_context(node, False)
-
- def parse_from(self):
- node = nodes.FromImport(lineno=next(self.stream).lineno)
- node.template = self.parse_expression()
- self.stream.expect('name:import')
- node.names = []
-
- def parse_context():
- if self.stream.current.value in ('with', 'without') and \
- self.stream.look().test('name:context'):
- node.with_context = next(self.stream).value == 'with'
- self.stream.skip()
- return True
- return False
-
- while 1:
- if node.names:
- self.stream.expect('comma')
- if self.stream.current.type == 'name':
- if parse_context():
- break
- target = self.parse_assign_target(name_only=True)
- if target.name.startswith('_'):
- self.fail('names starting with an underline can not '
- 'be imported', target.lineno,
- exc=TemplateAssertionError)
- if self.stream.skip_if('name:as'):
- alias = self.parse_assign_target(name_only=True)
- node.names.append((target.name, alias.name))
- else:
- node.names.append(target.name)
- if parse_context() or self.stream.current.type != 'comma':
- break
- else:
- break
- if not hasattr(node, 'with_context'):
- node.with_context = False
- self.stream.skip_if('comma')
- return node
-
- def parse_signature(self, node):
- node.args = args = []
- node.defaults = defaults = []
- self.stream.expect('lparen')
- while self.stream.current.type != 'rparen':
- if args:
- self.stream.expect('comma')
- arg = self.parse_assign_target(name_only=True)
- arg.set_ctx('param')
- if self.stream.skip_if('assign'):
- defaults.append(self.parse_expression())
- args.append(arg)
- self.stream.expect('rparen')
-
- def parse_call_block(self):
- node = nodes.CallBlock(lineno=next(self.stream).lineno)
- if self.stream.current.type == 'lparen':
- self.parse_signature(node)
- else:
- node.args = []
- node.defaults = []
-
- node.call = self.parse_expression()
- if not isinstance(node.call, nodes.Call):
- self.fail('expected call', node.lineno)
- node.body = self.parse_statements(('name:endcall',), drop_needle=True)
- return node
-
- def parse_filter_block(self):
- node = nodes.FilterBlock(lineno=next(self.stream).lineno)
- node.filter = self.parse_filter(None, start_inline=True)
- node.body = self.parse_statements(('name:endfilter',),
- drop_needle=True)
- return node
-
- def parse_macro(self):
- node = nodes.Macro(lineno=next(self.stream).lineno)
- node.name = self.parse_assign_target(name_only=True).name
- self.parse_signature(node)
- node.body = self.parse_statements(('name:endmacro',),
- drop_needle=True)
- return node
-
- def parse_print(self):
- node = nodes.Output(lineno=next(self.stream).lineno)
- node.nodes = []
- while self.stream.current.type != 'block_end':
- if node.nodes:
- self.stream.expect('comma')
- node.nodes.append(self.parse_expression())
- return node
-
- def parse_assign_target(self, with_tuple=True, name_only=False,
- extra_end_rules=None):
- """Parse an assignment target. As Jinja2 allows assignments to
- tuples, this function can parse all allowed assignment targets. Per
- default assignments to tuples are parsed, that can be disable however
- by setting `with_tuple` to `False`. If only assignments to names are
- wanted `name_only` can be set to `True`. The `extra_end_rules`
- parameter is forwarded to the tuple parsing function.
- """
- if name_only:
- token = self.stream.expect('name')
- target = nodes.Name(token.value, 'store', lineno=token.lineno)
- else:
- if with_tuple:
- target = self.parse_tuple(simplified=True,
- extra_end_rules=extra_end_rules)
- else:
- target = self.parse_primary()
- target.set_ctx('store')
- if not target.can_assign():
- self.fail('can\'t assign to %r' % target.__class__.
- __name__.lower(), target.lineno)
- return target
-
- def parse_expression(self, with_condexpr=True):
- """Parse an expression. Per default all expressions are parsed, if
- the optional `with_condexpr` parameter is set to `False` conditional
- expressions are not parsed.
- """
- if with_condexpr:
- return self.parse_condexpr()
- return self.parse_or()
-
- def parse_condexpr(self):
- lineno = self.stream.current.lineno
- expr1 = self.parse_or()
- while self.stream.skip_if('name:if'):
- expr2 = self.parse_or()
- if self.stream.skip_if('name:else'):
- expr3 = self.parse_condexpr()
- else:
- expr3 = None
- expr1 = nodes.CondExpr(expr2, expr1, expr3, lineno=lineno)
- lineno = self.stream.current.lineno
- return expr1
-
- def parse_or(self):
- lineno = self.stream.current.lineno
- left = self.parse_and()
- while self.stream.skip_if('name:or'):
- right = self.parse_and()
- left = nodes.Or(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_and(self):
- lineno = self.stream.current.lineno
- left = self.parse_not()
- while self.stream.skip_if('name:and'):
- right = self.parse_not()
- left = nodes.And(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_not(self):
- if self.stream.current.test('name:not'):
- lineno = next(self.stream).lineno
- return nodes.Not(self.parse_not(), lineno=lineno)
- return self.parse_compare()
-
- def parse_compare(self):
- lineno = self.stream.current.lineno
- expr = self.parse_add()
- ops = []
- while 1:
- token_type = self.stream.current.type
- if token_type in _compare_operators:
- next(self.stream)
- ops.append(nodes.Operand(token_type, self.parse_add()))
- elif self.stream.skip_if('name:in'):
- ops.append(nodes.Operand('in', self.parse_add()))
- elif self.stream.current.test('name:not') and \
- self.stream.look().test('name:in'):
- self.stream.skip(2)
- ops.append(nodes.Operand('notin', self.parse_add()))
- else:
- break
- lineno = self.stream.current.lineno
- if not ops:
- return expr
- return nodes.Compare(expr, ops, lineno=lineno)
-
- def parse_add(self):
- lineno = self.stream.current.lineno
- left = self.parse_sub()
- while self.stream.current.type == 'add':
- next(self.stream)
- right = self.parse_sub()
- left = nodes.Add(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_sub(self):
- lineno = self.stream.current.lineno
- left = self.parse_concat()
- while self.stream.current.type == 'sub':
- next(self.stream)
- right = self.parse_concat()
- left = nodes.Sub(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_concat(self):
- lineno = self.stream.current.lineno
- args = [self.parse_mul()]
- while self.stream.current.type == 'tilde':
- next(self.stream)
- args.append(self.parse_mul())
- if len(args) == 1:
- return args[0]
- return nodes.Concat(args, lineno=lineno)
-
- def parse_mul(self):
- lineno = self.stream.current.lineno
- left = self.parse_div()
- while self.stream.current.type == 'mul':
- next(self.stream)
- right = self.parse_div()
- left = nodes.Mul(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_div(self):
- lineno = self.stream.current.lineno
- left = self.parse_floordiv()
- while self.stream.current.type == 'div':
- next(self.stream)
- right = self.parse_floordiv()
- left = nodes.Div(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_floordiv(self):
- lineno = self.stream.current.lineno
- left = self.parse_mod()
- while self.stream.current.type == 'floordiv':
- next(self.stream)
- right = self.parse_mod()
- left = nodes.FloorDiv(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_mod(self):
- lineno = self.stream.current.lineno
- left = self.parse_pow()
- while self.stream.current.type == 'mod':
- next(self.stream)
- right = self.parse_pow()
- left = nodes.Mod(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_pow(self):
- lineno = self.stream.current.lineno
- left = self.parse_unary()
- while self.stream.current.type == 'pow':
- next(self.stream)
- right = self.parse_unary()
- left = nodes.Pow(left, right, lineno=lineno)
- lineno = self.stream.current.lineno
- return left
-
- def parse_unary(self, with_filter=True):
- token_type = self.stream.current.type
- lineno = self.stream.current.lineno
- if token_type == 'sub':
- next(self.stream)
- node = nodes.Neg(self.parse_unary(False), lineno=lineno)
- elif token_type == 'add':
- next(self.stream)
- node = nodes.Pos(self.parse_unary(False), lineno=lineno)
- else:
- node = self.parse_primary()
- node = self.parse_postfix(node)
- if with_filter:
- node = self.parse_filter_expr(node)
- return node
-
- def parse_primary(self):
- token = self.stream.current
- if token.type == 'name':
- if token.value in ('true', 'false', 'True', 'False'):
- node = nodes.Const(token.value in ('true', 'True'),
- lineno=token.lineno)
- elif token.value in ('none', 'None'):
- node = nodes.Const(None, lineno=token.lineno)
- else:
- node = nodes.Name(token.value, 'load', lineno=token.lineno)
- next(self.stream)
- elif token.type == 'string':
- next(self.stream)
- buf = [token.value]
- lineno = token.lineno
- while self.stream.current.type == 'string':
- buf.append(self.stream.current.value)
- next(self.stream)
- node = nodes.Const(''.join(buf), lineno=lineno)
- elif token.type in ('integer', 'float'):
- next(self.stream)
- node = nodes.Const(token.value, lineno=token.lineno)
- elif token.type == 'lparen':
- next(self.stream)
- node = self.parse_tuple(explicit_parentheses=True)
- self.stream.expect('rparen')
- elif token.type == 'lbracket':
- node = self.parse_list()
- elif token.type == 'lbrace':
- node = self.parse_dict()
- else:
- self.fail("unexpected '%s'" % describe_token(token), token.lineno)
- return node
-
- def parse_tuple(self, simplified=False, with_condexpr=True,
- extra_end_rules=None, explicit_parentheses=False):
- """Works like `parse_expression` but if multiple expressions are
- delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created.
- This method could also return a regular expression instead of a tuple
- if no commas where found.
-
- The default parsing mode is a full tuple. If `simplified` is `True`
- only names and literals are parsed. The `no_condexpr` parameter is
- forwarded to :meth:`parse_expression`.
-
- Because tuples do not require delimiters and may end in a bogus comma
- an extra hint is needed that marks the end of a tuple. For example
- for loops support tuples between `for` and `in`. In that case the
- `extra_end_rules` is set to ``['name:in']``.
-
- `explicit_parentheses` is true if the parsing was triggered by an
- expression in parentheses. This is used to figure out if an empty
- tuple is a valid expression or not.
- """
- lineno = self.stream.current.lineno
- if simplified:
- parse = self.parse_primary
- elif with_condexpr:
- parse = self.parse_expression
- else:
- parse = lambda: self.parse_expression(with_condexpr=False)
- args = []
- is_tuple = False
- while 1:
- if args:
- self.stream.expect('comma')
- if self.is_tuple_end(extra_end_rules):
- break
- args.append(parse())
- if self.stream.current.type == 'comma':
- is_tuple = True
- else:
- break
- lineno = self.stream.current.lineno
-
- if not is_tuple:
- if args:
- return args[0]
-
- # if we don't have explicit parentheses, an empty tuple is
- # not a valid expression. This would mean nothing (literally
- # nothing) in the spot of an expression would be an empty
- # tuple.
- if not explicit_parentheses:
- self.fail('Expected an expression, got \'%s\'' %
- describe_token(self.stream.current))
-
- return nodes.Tuple(args, 'load', lineno=lineno)
-
- def parse_list(self):
- token = self.stream.expect('lbracket')
- items = []
- while self.stream.current.type != 'rbracket':
- if items:
- self.stream.expect('comma')
- if self.stream.current.type == 'rbracket':
- break
- items.append(self.parse_expression())
- self.stream.expect('rbracket')
- return nodes.List(items, lineno=token.lineno)
-
- def parse_dict(self):
- token = self.stream.expect('lbrace')
- items = []
- while self.stream.current.type != 'rbrace':
- if items:
- self.stream.expect('comma')
- if self.stream.current.type == 'rbrace':
- break
- key = self.parse_expression()
- self.stream.expect('colon')
- value = self.parse_expression()
- items.append(nodes.Pair(key, value, lineno=key.lineno))
- self.stream.expect('rbrace')
- return nodes.Dict(items, lineno=token.lineno)
-
- def parse_postfix(self, node):
- while 1:
- token_type = self.stream.current.type
- if token_type == 'dot' or token_type == 'lbracket':
- node = self.parse_subscript(node)
- # calls are valid both after postfix expressions (getattr
- # and getitem) as well as filters and tests
- elif token_type == 'lparen':
- node = self.parse_call(node)
- else:
- break
- return node
-
- def parse_filter_expr(self, node):
- while 1:
- token_type = self.stream.current.type
- if token_type == 'pipe':
- node = self.parse_filter(node)
- elif token_type == 'name' and self.stream.current.value == 'is':
- node = self.parse_test(node)
- # calls are valid both after postfix expressions (getattr
- # and getitem) as well as filters and tests
- elif token_type == 'lparen':
- node = self.parse_call(node)
- else:
- break
- return node
-
- def parse_subscript(self, node):
- token = next(self.stream)
- if token.type == 'dot':
- attr_token = self.stream.current
- next(self.stream)
- if attr_token.type == 'name':
- return nodes.Getattr(node, attr_token.value, 'load',
- lineno=token.lineno)
- elif attr_token.type != 'integer':
- self.fail('expected name or number', attr_token.lineno)
- arg = nodes.Const(attr_token.value, lineno=attr_token.lineno)
- return nodes.Getitem(node, arg, 'load', lineno=token.lineno)
- if token.type == 'lbracket':
- priority_on_attribute = False
- args = []
- while self.stream.current.type != 'rbracket':
- if args:
- self.stream.expect('comma')
- args.append(self.parse_subscribed())
- self.stream.expect('rbracket')
- if len(args) == 1:
- arg = args[0]
- else:
- arg = nodes.Tuple(args, 'load', lineno=token.lineno)
- return nodes.Getitem(node, arg, 'load', lineno=token.lineno)
- self.fail('expected subscript expression', self.lineno)
-
- def parse_subscribed(self):
- lineno = self.stream.current.lineno
-
- if self.stream.current.type == 'colon':
- next(self.stream)
- args = [None]
- else:
- node = self.parse_expression()
- if self.stream.current.type != 'colon':
- return node
- next(self.stream)
- args = [node]
-
- if self.stream.current.type == 'colon':
- args.append(None)
- elif self.stream.current.type not in ('rbracket', 'comma'):
- args.append(self.parse_expression())
- else:
- args.append(None)
-
- if self.stream.current.type == 'colon':
- next(self.stream)
- if self.stream.current.type not in ('rbracket', 'comma'):
- args.append(self.parse_expression())
- else:
- args.append(None)
- else:
- args.append(None)
-
- return nodes.Slice(lineno=lineno, *args)
-
- def parse_call(self, node):
- token = self.stream.expect('lparen')
- args = []
- kwargs = []
- dyn_args = dyn_kwargs = None
- require_comma = False
-
- def ensure(expr):
- if not expr:
- self.fail('invalid syntax for function call expression',
- token.lineno)
-
- while self.stream.current.type != 'rparen':
- if require_comma:
- self.stream.expect('comma')
- # support for trailing comma
- if self.stream.current.type == 'rparen':
- break
- if self.stream.current.type == 'mul':
- ensure(dyn_args is None and dyn_kwargs is None)
- next(self.stream)
- dyn_args = self.parse_expression()
- elif self.stream.current.type == 'pow':
- ensure(dyn_kwargs is None)
- next(self.stream)
- dyn_kwargs = self.parse_expression()
- else:
- ensure(dyn_args is None and dyn_kwargs is None)
- if self.stream.current.type == 'name' and \
- self.stream.look().type == 'assign':
- key = self.stream.current.value
- self.stream.skip(2)
- value = self.parse_expression()
- kwargs.append(nodes.Keyword(key, value,
- lineno=value.lineno))
- else:
- ensure(not kwargs)
- args.append(self.parse_expression())
-
- require_comma = True
- self.stream.expect('rparen')
-
- if node is None:
- return args, kwargs, dyn_args, dyn_kwargs
- return nodes.Call(node, args, kwargs, dyn_args, dyn_kwargs,
- lineno=token.lineno)
-
- def parse_filter(self, node, start_inline=False):
- while self.stream.current.type == 'pipe' or start_inline:
- if not start_inline:
- next(self.stream)
- token = self.stream.expect('name')
- name = token.value
- while self.stream.current.type == 'dot':
- next(self.stream)
- name += '.' + self.stream.expect('name').value
- if self.stream.current.type == 'lparen':
- args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
- else:
- args = []
- kwargs = []
- dyn_args = dyn_kwargs = None
- node = nodes.Filter(node, name, args, kwargs, dyn_args,
- dyn_kwargs, lineno=token.lineno)
- start_inline = False
- return node
-
- def parse_test(self, node):
- token = next(self.stream)
- if self.stream.current.test('name:not'):
- next(self.stream)
- negated = True
- else:
- negated = False
- name = self.stream.expect('name').value
- while self.stream.current.type == 'dot':
- next(self.stream)
- name += '.' + self.stream.expect('name').value
- dyn_args = dyn_kwargs = None
- kwargs = []
- if self.stream.current.type == 'lparen':
- args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
- elif self.stream.current.type in ('name', 'string', 'integer',
- 'float', 'lparen', 'lbracket',
- 'lbrace') and not \
- self.stream.current.test_any('name:else', 'name:or',
- 'name:and'):
- if self.stream.current.test('name:is'):
- self.fail('You cannot chain multiple tests with is')
- args = [self.parse_expression()]
- else:
- args = []
- node = nodes.Test(node, name, args, kwargs, dyn_args,
- dyn_kwargs, lineno=token.lineno)
- if negated:
- node = nodes.Not(node, lineno=token.lineno)
- return node
-
- def subparse(self, end_tokens=None):
- body = []
- data_buffer = []
- add_data = data_buffer.append
-
- if end_tokens is not None:
- self._end_token_stack.append(end_tokens)
-
- def flush_data():
- if data_buffer:
- lineno = data_buffer[0].lineno
- body.append(nodes.Output(data_buffer[:], lineno=lineno))
- del data_buffer[:]
-
- try:
- while self.stream:
- token = self.stream.current
- if token.type == 'data':
- if token.value:
- add_data(nodes.TemplateData(token.value,
- lineno=token.lineno))
- next(self.stream)
- elif token.type == 'variable_begin':
- next(self.stream)
- add_data(self.parse_tuple(with_condexpr=True))
- self.stream.expect('variable_end')
- elif token.type == 'block_begin':
- flush_data()
- next(self.stream)
- if end_tokens is not None and \
- self.stream.current.test_any(*end_tokens):
- return body
- rv = self.parse_statement()
- if isinstance(rv, list):
- body.extend(rv)
- else:
- body.append(rv)
- self.stream.expect('block_end')
- else:
- raise AssertionError('internal parsing error')
-
- flush_data()
- finally:
- if end_tokens is not None:
- self._end_token_stack.pop()
-
- return body
-
- def parse(self):
- """Parse the whole template into a `Template` node."""
- result = nodes.Template(self.subparse(), lineno=1)
- result.set_environment(self.environment)
- return result
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/runtime.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/runtime.py
deleted file mode 100755
index a4a47a28..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/runtime.py
+++ /dev/null
@@ -1,548 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.runtime
- ~~~~~~~~~~~~~~
-
- Runtime helpers.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD.
-"""
-from itertools import chain, imap
-from jinja2.nodes import EvalContext, _context_function_types
-from jinja2.utils import Markup, partial, soft_unicode, escape, missing, \
- concat, internalcode, next, object_type_repr
-from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \
- TemplateNotFound
-
-
-# these variables are exported to the template runtime
-__all__ = ['LoopContext', 'TemplateReference', 'Macro', 'Markup',
- 'TemplateRuntimeError', 'missing', 'concat', 'escape',
- 'markup_join', 'unicode_join', 'to_string', 'identity',
- 'TemplateNotFound']
-
-#: the name of the function that is used to convert something into
-#: a string. 2to3 will adopt that automatically and the generated
-#: code can take advantage of it.
-to_string = unicode
-
-#: the identity function. Useful for certain things in the environment
-identity = lambda x: x
-
-
-def markup_join(seq):
- """Concatenation that escapes if necessary and converts to unicode."""
- buf = []
- iterator = imap(soft_unicode, seq)
- for arg in iterator:
- buf.append(arg)
- if hasattr(arg, '__html__'):
- return Markup(u'').join(chain(buf, iterator))
- return concat(buf)
-
-
-def unicode_join(seq):
- """Simple args to unicode conversion and concatenation."""
- return concat(imap(unicode, seq))
-
-
-def new_context(environment, template_name, blocks, vars=None,
- shared=None, globals=None, locals=None):
- """Internal helper to for context creation."""
- if vars is None:
- vars = {}
- if shared:
- parent = vars
- else:
- parent = dict(globals or (), **vars)
- if locals:
- # if the parent is shared a copy should be created because
- # we don't want to modify the dict passed
- if shared:
- parent = dict(parent)
- for key, value in locals.iteritems():
- if key[:2] == 'l_' and value is not missing:
- parent[key[2:]] = value
- return Context(environment, parent, template_name, blocks)
-
-
-class TemplateReference(object):
- """The `self` in templates."""
-
- def __init__(self, context):
- self.__context = context
-
- def __getitem__(self, name):
- blocks = self.__context.blocks[name]
- return BlockReference(name, self.__context, blocks, 0)
-
- def __repr__(self):
- return '<%s %r>' % (
- self.__class__.__name__,
- self.__context.name
- )
-
-
-class Context(object):
- """The template context holds the variables of a template. It stores the
- values passed to the template and also the names the template exports.
- Creating instances is neither supported nor useful as it's created
- automatically at various stages of the template evaluation and should not
- be created by hand.
-
- The context is immutable. Modifications on :attr:`parent` **must not**
- happen and modifications on :attr:`vars` are allowed from generated
- template code only. Template filters and global functions marked as
- :func:`contextfunction`\s get the active context passed as first argument
- and are allowed to access the context read-only.
-
- The template context supports read only dict operations (`get`,
- `keys`, `values`, `items`, `iterkeys`, `itervalues`, `iteritems`,
- `__getitem__`, `__contains__`). Additionally there is a :meth:`resolve`
- method that doesn't fail with a `KeyError` but returns an
- :class:`Undefined` object for missing variables.
- """
- __slots__ = ('parent', 'vars', 'environment', 'eval_ctx', 'exported_vars',
- 'name', 'blocks', '__weakref__')
-
- def __init__(self, environment, parent, name, blocks):
- self.parent = parent
- self.vars = {}
- self.environment = environment
- self.eval_ctx = EvalContext(self.environment, name)
- self.exported_vars = set()
- self.name = name
-
- # create the initial mapping of blocks. Whenever template inheritance
- # takes place the runtime will update this mapping with the new blocks
- # from the template.
- self.blocks = dict((k, [v]) for k, v in blocks.iteritems())
-
- def super(self, name, current):
- """Render a parent block."""
- try:
- blocks = self.blocks[name]
- index = blocks.index(current) + 1
- blocks[index]
- except LookupError:
- return self.environment.undefined('there is no parent block '
- 'called %r.' % name,
- name='super')
- return BlockReference(name, self, blocks, index)
-
- def get(self, key, default=None):
- """Returns an item from the template context, if it doesn't exist
- `default` is returned.
- """
- try:
- return self[key]
- except KeyError:
- return default
-
- def resolve(self, key):
- """Looks up a variable like `__getitem__` or `get` but returns an
- :class:`Undefined` object with the name of the name looked up.
- """
- if key in self.vars:
- return self.vars[key]
- if key in self.parent:
- return self.parent[key]
- return self.environment.undefined(name=key)
-
- def get_exported(self):
- """Get a new dict with the exported variables."""
- return dict((k, self.vars[k]) for k in self.exported_vars)
-
- def get_all(self):
- """Return a copy of the complete context as dict including the
- exported variables.
- """
- return dict(self.parent, **self.vars)
-
- @internalcode
- def call(__self, __obj, *args, **kwargs):
- """Call the callable with the arguments and keyword arguments
- provided but inject the active context or environment as first
- argument if the callable is a :func:`contextfunction` or
- :func:`environmentfunction`.
- """
- if __debug__:
- __traceback_hide__ = True
- if isinstance(__obj, _context_function_types):
- if getattr(__obj, 'contextfunction', 0):
- args = (__self,) + args
- elif getattr(__obj, 'evalcontextfunction', 0):
- args = (__self.eval_ctx,) + args
- elif getattr(__obj, 'environmentfunction', 0):
- args = (__self.environment,) + args
- try:
- return __obj(*args, **kwargs)
- except StopIteration:
- return __self.environment.undefined('value was undefined because '
- 'a callable raised a '
- 'StopIteration exception')
-
- def derived(self, locals=None):
- """Internal helper function to create a derived context."""
- context = new_context(self.environment, self.name, {},
- self.parent, True, None, locals)
- context.vars.update(self.vars)
- context.eval_ctx = self.eval_ctx
- context.blocks.update((k, list(v)) for k, v in self.blocks.iteritems())
- return context
-
- def _all(meth):
- proxy = lambda self: getattr(self.get_all(), meth)()
- proxy.__doc__ = getattr(dict, meth).__doc__
- proxy.__name__ = meth
- return proxy
-
- keys = _all('keys')
- values = _all('values')
- items = _all('items')
-
- # not available on python 3
- if hasattr(dict, 'iterkeys'):
- iterkeys = _all('iterkeys')
- itervalues = _all('itervalues')
- iteritems = _all('iteritems')
- del _all
-
- def __contains__(self, name):
- return name in self.vars or name in self.parent
-
- def __getitem__(self, key):
- """Lookup a variable or raise `KeyError` if the variable is
- undefined.
- """
- item = self.resolve(key)
- if isinstance(item, Undefined):
- raise KeyError(key)
- return item
-
- def __repr__(self):
- return '<%s %s of %r>' % (
- self.__class__.__name__,
- repr(self.get_all()),
- self.name
- )
-
-
-# register the context as mapping if possible
-try:
- from collections import Mapping
- Mapping.register(Context)
-except ImportError:
- pass
-
-
-class BlockReference(object):
- """One block on a template reference."""
-
- def __init__(self, name, context, stack, depth):
- self.name = name
- self._context = context
- self._stack = stack
- self._depth = depth
-
- @property
- def super(self):
- """Super the block."""
- if self._depth + 1 >= len(self._stack):
- return self._context.environment. \
- undefined('there is no parent block called %r.' %
- self.name, name='super')
- return BlockReference(self.name, self._context, self._stack,
- self._depth + 1)
-
- @internalcode
- def __call__(self):
- rv = concat(self._stack[self._depth](self._context))
- if self._context.eval_ctx.autoescape:
- rv = Markup(rv)
- return rv
-
-
-class LoopContext(object):
- """A loop context for dynamic iteration."""
-
- def __init__(self, iterable, recurse=None):
- self._iterator = iter(iterable)
- self._recurse = recurse
- self.index0 = -1
-
- # try to get the length of the iterable early. This must be done
- # here because there are some broken iterators around where there
- # __len__ is the number of iterations left (i'm looking at your
- # listreverseiterator!).
- try:
- self._length = len(iterable)
- except (TypeError, AttributeError):
- self._length = None
-
- def cycle(self, *args):
- """Cycles among the arguments with the current loop index."""
- if not args:
- raise TypeError('no items for cycling given')
- return args[self.index0 % len(args)]
-
- first = property(lambda x: x.index0 == 0)
- last = property(lambda x: x.index0 + 1 == x.length)
- index = property(lambda x: x.index0 + 1)
- revindex = property(lambda x: x.length - x.index0)
- revindex0 = property(lambda x: x.length - x.index)
-
- def __len__(self):
- return self.length
-
- def __iter__(self):
- return LoopContextIterator(self)
-
- @internalcode
- def loop(self, iterable):
- if self._recurse is None:
- raise TypeError('Tried to call non recursive loop. Maybe you '
- "forgot the 'recursive' modifier.")
- return self._recurse(iterable, self._recurse)
-
- # a nifty trick to enhance the error message if someone tried to call
- # the the loop without or with too many arguments.
- __call__ = loop
- del loop
-
- @property
- def length(self):
- if self._length is None:
- # if was not possible to get the length of the iterator when
- # the loop context was created (ie: iterating over a generator)
- # we have to convert the iterable into a sequence and use the
- # length of that.
- iterable = tuple(self._iterator)
- self._iterator = iter(iterable)
- self._length = len(iterable) + self.index0 + 1
- return self._length
-
- def __repr__(self):
- return '<%s %r/%r>' % (
- self.__class__.__name__,
- self.index,
- self.length
- )
-
-
-class LoopContextIterator(object):
- """The iterator for a loop context."""
- __slots__ = ('context',)
-
- def __init__(self, context):
- self.context = context
-
- def __iter__(self):
- return self
-
- def next(self):
- ctx = self.context
- ctx.index0 += 1
- return next(ctx._iterator), ctx
-
-
-class Macro(object):
- """Wraps a macro function."""
-
- def __init__(self, environment, func, name, arguments, defaults,
- catch_kwargs, catch_varargs, caller):
- self._environment = environment
- self._func = func
- self._argument_count = len(arguments)
- self.name = name
- self.arguments = arguments
- self.defaults = defaults
- self.catch_kwargs = catch_kwargs
- self.catch_varargs = catch_varargs
- self.caller = caller
-
- @internalcode
- def __call__(self, *args, **kwargs):
- # try to consume the positional arguments
- arguments = list(args[:self._argument_count])
- off = len(arguments)
-
- # if the number of arguments consumed is not the number of
- # arguments expected we start filling in keyword arguments
- # and defaults.
- if off != self._argument_count:
- for idx, name in enumerate(self.arguments[len(arguments):]):
- try:
- value = kwargs.pop(name)
- except KeyError:
- try:
- value = self.defaults[idx - self._argument_count + off]
- except IndexError:
- value = self._environment.undefined(
- 'parameter %r was not provided' % name, name=name)
- arguments.append(value)
-
- # it's important that the order of these arguments does not change
- # if not also changed in the compiler's `function_scoping` method.
- # the order is caller, keyword arguments, positional arguments!
- if self.caller:
- caller = kwargs.pop('caller', None)
- if caller is None:
- caller = self._environment.undefined('No caller defined',
- name='caller')
- arguments.append(caller)
- if self.catch_kwargs:
- arguments.append(kwargs)
- elif kwargs:
- raise TypeError('macro %r takes no keyword argument %r' %
- (self.name, next(iter(kwargs))))
- if self.catch_varargs:
- arguments.append(args[self._argument_count:])
- elif len(args) > self._argument_count:
- raise TypeError('macro %r takes not more than %d argument(s)' %
- (self.name, len(self.arguments)))
- return self._func(*arguments)
-
- def __repr__(self):
- return '<%s %s>' % (
- self.__class__.__name__,
- self.name is None and 'anonymous' or repr(self.name)
- )
-
-
-class Undefined(object):
- """The default undefined type. This undefined type can be printed and
- iterated over, but every other access will raise an :exc:`UndefinedError`:
-
- >>> foo = Undefined(name='foo')
- >>> str(foo)
- ''
- >>> not foo
- True
- >>> foo + 42
- Traceback (most recent call last):
- ...
- UndefinedError: 'foo' is undefined
- """
- __slots__ = ('_undefined_hint', '_undefined_obj', '_undefined_name',
- '_undefined_exception')
-
- def __init__(self, hint=None, obj=missing, name=None, exc=UndefinedError):
- self._undefined_hint = hint
- self._undefined_obj = obj
- self._undefined_name = name
- self._undefined_exception = exc
-
- @internalcode
- def _fail_with_undefined_error(self, *args, **kwargs):
- """Regular callback function for undefined objects that raises an
- `UndefinedError` on call.
- """
- if self._undefined_hint is None:
- if self._undefined_obj is missing:
- hint = '%r is undefined' % self._undefined_name
- elif not isinstance(self._undefined_name, basestring):
- hint = '%s has no element %r' % (
- object_type_repr(self._undefined_obj),
- self._undefined_name
- )
- else:
- hint = '%r has no attribute %r' % (
- object_type_repr(self._undefined_obj),
- self._undefined_name
- )
- else:
- hint = self._undefined_hint
- raise self._undefined_exception(hint)
-
- @internalcode
- def __getattr__(self, name):
- if name[:2] == '__':
- raise AttributeError(name)
- return self._fail_with_undefined_error()
-
- __add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
- __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
- __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
- __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
- __float__ = __complex__ = __pow__ = __rpow__ = \
- _fail_with_undefined_error
-
- def __str__(self):
- return unicode(self).encode('utf-8')
-
- # unicode goes after __str__ because we configured 2to3 to rename
- # __unicode__ to __str__. because the 2to3 tree is not designed to
- # remove nodes from it, we leave the above __str__ around and let
- # it override at runtime.
- def __unicode__(self):
- return u''
-
- def __len__(self):
- return 0
-
- def __iter__(self):
- if 0:
- yield None
-
- def __nonzero__(self):
- return False
-
- def __repr__(self):
- return 'Undefined'
-
-
-class DebugUndefined(Undefined):
- """An undefined that returns the debug info when printed.
-
- >>> foo = DebugUndefined(name='foo')
- >>> str(foo)
- '{{ foo }}'
- >>> not foo
- True
- >>> foo + 42
- Traceback (most recent call last):
- ...
- UndefinedError: 'foo' is undefined
- """
- __slots__ = ()
-
- def __unicode__(self):
- if self._undefined_hint is None:
- if self._undefined_obj is missing:
- return u'{{ %s }}' % self._undefined_name
- return '{{ no such element: %s[%r] }}' % (
- object_type_repr(self._undefined_obj),
- self._undefined_name
- )
- return u'{{ undefined value printed: %s }}' % self._undefined_hint
-
-
-class StrictUndefined(Undefined):
- """An undefined that barks on print and iteration as well as boolean
- tests and all kinds of comparisons. In other words: you can do nothing
- with it except checking if it's defined using the `defined` test.
-
- >>> foo = StrictUndefined(name='foo')
- >>> str(foo)
- Traceback (most recent call last):
- ...
- UndefinedError: 'foo' is undefined
- >>> not foo
- Traceback (most recent call last):
- ...
- UndefinedError: 'foo' is undefined
- >>> foo + 42
- Traceback (most recent call last):
- ...
- UndefinedError: 'foo' is undefined
- """
- __slots__ = ()
- __iter__ = __unicode__ = __str__ = __len__ = __nonzero__ = __eq__ = \
- __ne__ = __bool__ = Undefined._fail_with_undefined_error
-
-
-# remove remaining slots attributes, after the metaclass did the magic they
-# are unneeded and irritating as they contain wrong data for the subclasses.
-del Undefined.__slots__, DebugUndefined.__slots__, StrictUndefined.__slots__
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/sandbox.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/sandbox.py
deleted file mode 100755
index a1cbb29a..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/sandbox.py
+++ /dev/null
@@ -1,361 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.sandbox
- ~~~~~~~~~~~~~~
-
- Adds a sandbox layer to Jinja as it was the default behavior in the old
- Jinja 1 releases. This sandbox is slightly different from Jinja 1 as the
- default behavior is easier to use.
-
- The behavior can be changed by subclassing the environment.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD.
-"""
-import operator
-from jinja2.environment import Environment
-from jinja2.exceptions import SecurityError
-from jinja2.utils import FunctionType, MethodType, TracebackType, CodeType, \
- FrameType, GeneratorType
-
-
-#: maximum number of items a range may produce
-MAX_RANGE = 100000
-
-#: attributes of function objects that are considered unsafe.
-UNSAFE_FUNCTION_ATTRIBUTES = set(['func_closure', 'func_code', 'func_dict',
- 'func_defaults', 'func_globals'])
-
-#: unsafe method attributes. function attributes are unsafe for methods too
-UNSAFE_METHOD_ATTRIBUTES = set(['im_class', 'im_func', 'im_self'])
-
-
-import warnings
-
-# make sure we don't warn in python 2.6 about stuff we don't care about
-warnings.filterwarnings('ignore', 'the sets module', DeprecationWarning,
- module='jinja2.sandbox')
-
-from collections import deque
-
-_mutable_set_types = (set,)
-_mutable_mapping_types = (dict,)
-_mutable_sequence_types = (list,)
-
-
-# on python 2.x we can register the user collection types
-try:
- from UserDict import UserDict, DictMixin
- from UserList import UserList
- _mutable_mapping_types += (UserDict, DictMixin)
- _mutable_set_types += (UserList,)
-except ImportError:
- pass
-
-# if sets is still available, register the mutable set from there as well
-try:
- from sets import Set
- _mutable_set_types += (Set,)
-except ImportError:
- pass
-
-#: register Python 2.6 abstract base classes
-try:
- from collections import MutableSet, MutableMapping, MutableSequence
- _mutable_set_types += (MutableSet,)
- _mutable_mapping_types += (MutableMapping,)
- _mutable_sequence_types += (MutableSequence,)
-except ImportError:
- pass
-
-_mutable_spec = (
- (_mutable_set_types, frozenset([
- 'add', 'clear', 'difference_update', 'discard', 'pop', 'remove',
- 'symmetric_difference_update', 'update'
- ])),
- (_mutable_mapping_types, frozenset([
- 'clear', 'pop', 'popitem', 'setdefault', 'update'
- ])),
- (_mutable_sequence_types, frozenset([
- 'append', 'reverse', 'insert', 'sort', 'extend', 'remove'
- ])),
- (deque, frozenset([
- 'append', 'appendleft', 'clear', 'extend', 'extendleft', 'pop',
- 'popleft', 'remove', 'rotate'
- ]))
-)
-
-
-def safe_range(*args):
- """A range that can't generate ranges with a length of more than
- MAX_RANGE items.
- """
- rng = xrange(*args)
- if len(rng) > MAX_RANGE:
- raise OverflowError('range too big, maximum size for range is %d' %
- MAX_RANGE)
- return rng
-
-
-def unsafe(f):
- """Marks a function or method as unsafe.
-
- ::
-
- @unsafe
- def delete(self):
- pass
- """
- f.unsafe_callable = True
- return f
-
-
-def is_internal_attribute(obj, attr):
- """Test if the attribute given is an internal python attribute. For
- example this function returns `True` for the `func_code` attribute of
- python objects. This is useful if the environment method
- :meth:`~SandboxedEnvironment.is_safe_attribute` is overriden.
-
- >>> from jinja2.sandbox import is_internal_attribute
- >>> is_internal_attribute(lambda: None, "func_code")
- True
- >>> is_internal_attribute((lambda x:x).func_code, 'co_code')
- True
- >>> is_internal_attribute(str, "upper")
- False
- """
- if isinstance(obj, FunctionType):
- if attr in UNSAFE_FUNCTION_ATTRIBUTES:
- return True
- elif isinstance(obj, MethodType):
- if attr in UNSAFE_FUNCTION_ATTRIBUTES or \
- attr in UNSAFE_METHOD_ATTRIBUTES:
- return True
- elif isinstance(obj, type):
- if attr == 'mro':
- return True
- elif isinstance(obj, (CodeType, TracebackType, FrameType)):
- return True
- elif isinstance(obj, GeneratorType):
- if attr == 'gi_frame':
- return True
- return attr.startswith('__')
-
-
-def modifies_known_mutable(obj, attr):
- """This function checks if an attribute on a builtin mutable object
- (list, dict, set or deque) would modify it if called. It also supports
- the "user"-versions of the objects (`sets.Set`, `UserDict.*` etc.) and
- with Python 2.6 onwards the abstract base classes `MutableSet`,
- `MutableMapping`, and `MutableSequence`.
-
- >>> modifies_known_mutable({}, "clear")
- True
- >>> modifies_known_mutable({}, "keys")
- False
- >>> modifies_known_mutable([], "append")
- True
- >>> modifies_known_mutable([], "index")
- False
-
- If called with an unsupported object (such as unicode) `False` is
- returned.
-
- >>> modifies_known_mutable("foo", "upper")
- False
- """
- for typespec, unsafe in _mutable_spec:
- if isinstance(obj, typespec):
- return attr in unsafe
- return False
-
-
-class SandboxedEnvironment(Environment):
- """The sandboxed environment. It works like the regular environment but
- tells the compiler to generate sandboxed code. Additionally subclasses of
- this environment may override the methods that tell the runtime what
- attributes or functions are safe to access.
-
- If the template tries to access insecure code a :exc:`SecurityError` is
- raised. However also other exceptions may occour during the rendering so
- the caller has to ensure that all exceptions are catched.
- """
- sandboxed = True
-
- #: default callback table for the binary operators. A copy of this is
- #: available on each instance of a sandboxed environment as
- #: :attr:`binop_table`
- default_binop_table = {
- '+': operator.add,
- '-': operator.sub,
- '*': operator.mul,
- '/': operator.truediv,
- '//': operator.floordiv,
- '**': operator.pow,
- '%': operator.mod
- }
-
- #: default callback table for the unary operators. A copy of this is
- #: available on each instance of a sandboxed environment as
- #: :attr:`unop_table`
- default_unop_table = {
- '+': operator.pos,
- '-': operator.neg
- }
-
- #: a set of binary operators that should be intercepted. Each operator
- #: that is added to this set (empty by default) is delegated to the
- #: :meth:`call_binop` method that will perform the operator. The default
- #: operator callback is specified by :attr:`binop_table`.
- #:
- #: The following binary operators are interceptable:
- #: ``//``, ``%``, ``+``, ``*``, ``-``, ``/``, and ``**``
- #:
- #: The default operation form the operator table corresponds to the
- #: builtin function. Intercepted calls are always slower than the native
- #: operator call, so make sure only to intercept the ones you are
- #: interested in.
- #:
- #: .. versionadded:: 2.6
- intercepted_binops = frozenset()
-
- #: a set of unary operators that should be intercepted. Each operator
- #: that is added to this set (empty by default) is delegated to the
- #: :meth:`call_unop` method that will perform the operator. The default
- #: operator callback is specified by :attr:`unop_table`.
- #:
- #: The following unary operators are interceptable: ``+``, ``-``
- #:
- #: The default operation form the operator table corresponds to the
- #: builtin function. Intercepted calls are always slower than the native
- #: operator call, so make sure only to intercept the ones you are
- #: interested in.
- #:
- #: .. versionadded:: 2.6
- intercepted_unops = frozenset()
-
- def intercept_unop(self, operator):
- """Called during template compilation with the name of a unary
- operator to check if it should be intercepted at runtime. If this
- method returns `True`, :meth:`call_unop` is excuted for this unary
- operator. The default implementation of :meth:`call_unop` will use
- the :attr:`unop_table` dictionary to perform the operator with the
- same logic as the builtin one.
-
- The following unary operators are interceptable: ``+`` and ``-``
-
- Intercepted calls are always slower than the native operator call,
- so make sure only to intercept the ones you are interested in.
-
- .. versionadded:: 2.6
- """
- return False
-
-
- def __init__(self, *args, **kwargs):
- Environment.__init__(self, *args, **kwargs)
- self.globals['range'] = safe_range
- self.binop_table = self.default_binop_table.copy()
- self.unop_table = self.default_unop_table.copy()
-
- def is_safe_attribute(self, obj, attr, value):
- """The sandboxed environment will call this method to check if the
- attribute of an object is safe to access. Per default all attributes
- starting with an underscore are considered private as well as the
- special attributes of internal python objects as returned by the
- :func:`is_internal_attribute` function.
- """
- return not (attr.startswith('_') or is_internal_attribute(obj, attr))
-
- def is_safe_callable(self, obj):
- """Check if an object is safely callable. Per default a function is
- considered safe unless the `unsafe_callable` attribute exists and is
- True. Override this method to alter the behavior, but this won't
- affect the `unsafe` decorator from this module.
- """
- return not (getattr(obj, 'unsafe_callable', False) or
- getattr(obj, 'alters_data', False))
-
- def call_binop(self, context, operator, left, right):
- """For intercepted binary operator calls (:meth:`intercepted_binops`)
- this function is executed instead of the builtin operator. This can
- be used to fine tune the behavior of certain operators.
-
- .. versionadded:: 2.6
- """
- return self.binop_table[operator](left, right)
-
- def call_unop(self, context, operator, arg):
- """For intercepted unary operator calls (:meth:`intercepted_unops`)
- this function is executed instead of the builtin operator. This can
- be used to fine tune the behavior of certain operators.
-
- .. versionadded:: 2.6
- """
- return self.unop_table[operator](arg)
-
- def getitem(self, obj, argument):
- """Subscribe an object from sandboxed code."""
- try:
- return obj[argument]
- except (TypeError, LookupError):
- if isinstance(argument, basestring):
- try:
- attr = str(argument)
- except Exception:
- pass
- else:
- try:
- value = getattr(obj, attr)
- except AttributeError:
- pass
- else:
- if self.is_safe_attribute(obj, argument, value):
- return value
- return self.unsafe_undefined(obj, argument)
- return self.undefined(obj=obj, name=argument)
-
- def getattr(self, obj, attribute):
- """Subscribe an object from sandboxed code and prefer the
- attribute. The attribute passed *must* be a bytestring.
- """
- try:
- value = getattr(obj, attribute)
- except AttributeError:
- try:
- return obj[attribute]
- except (TypeError, LookupError):
- pass
- else:
- if self.is_safe_attribute(obj, attribute, value):
- return value
- return self.unsafe_undefined(obj, attribute)
- return self.undefined(obj=obj, name=attribute)
-
- def unsafe_undefined(self, obj, attribute):
- """Return an undefined object for unsafe attributes."""
- return self.undefined('access to attribute %r of %r '
- 'object is unsafe.' % (
- attribute,
- obj.__class__.__name__
- ), name=attribute, obj=obj, exc=SecurityError)
-
- def call(__self, __context, __obj, *args, **kwargs):
- """Call an object from sandboxed code."""
- # the double prefixes are to avoid double keyword argument
- # errors when proxying the call.
- if not __self.is_safe_callable(__obj):
- raise SecurityError('%r is not safely callable' % (__obj,))
- return __context.call(__obj, *args, **kwargs)
-
-
-class ImmutableSandboxedEnvironment(SandboxedEnvironment):
- """Works exactly like the regular `SandboxedEnvironment` but does not
- permit modifications on the builtin mutable objects `list`, `set`, and
- `dict` by using the :func:`modifies_known_mutable` function.
- """
-
- def is_safe_attribute(self, obj, attr, value):
- if not SandboxedEnvironment.is_safe_attribute(self, obj, attr, value):
- return False
- return not modifies_known_mutable(obj, attr)
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/tests.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/tests.py
deleted file mode 100755
index 50510b0d..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/tests.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.tests
- ~~~~~~~~~~~~
-
- Jinja test functions. Used with the "is" operator.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import re
-from jinja2.runtime import Undefined
-
-try:
- from collections import Mapping as MappingType
-except ImportError:
- import UserDict
- MappingType = (UserDict.UserDict, UserDict.DictMixin, dict)
-
-# nose, nothing here to test
-__test__ = False
-
-
-number_re = re.compile(r'^-?\d+(\.\d+)?$')
-regex_type = type(number_re)
-
-
-try:
- test_callable = callable
-except NameError:
- def test_callable(x):
- return hasattr(x, '__call__')
-
-
-def test_odd(value):
- """Return true if the variable is odd."""
- return value % 2 == 1
-
-
-def test_even(value):
- """Return true if the variable is even."""
- return value % 2 == 0
-
-
-def test_divisibleby(value, num):
- """Check if a variable is divisible by a number."""
- return value % num == 0
-
-
-def test_defined(value):
- """Return true if the variable is defined:
-
- .. sourcecode:: jinja
-
- {% if variable is defined %}
- value of variable: {{ variable }}
- {% else %}
- variable is not defined
- {% endif %}
-
- See the :func:`default` filter for a simple way to set undefined
- variables.
- """
- return not isinstance(value, Undefined)
-
-
-def test_undefined(value):
- """Like :func:`defined` but the other way round."""
- return isinstance(value, Undefined)
-
-
-def test_none(value):
- """Return true if the variable is none."""
- return value is None
-
-
-def test_lower(value):
- """Return true if the variable is lowercased."""
- return unicode(value).islower()
-
-
-def test_upper(value):
- """Return true if the variable is uppercased."""
- return unicode(value).isupper()
-
-
-def test_string(value):
- """Return true if the object is a string."""
- return isinstance(value, basestring)
-
-
-def test_mapping(value):
- """Return true if the object is a mapping (dict etc.).
-
- .. versionadded:: 2.6
- """
- return isinstance(value, MappingType)
-
-
-def test_number(value):
- """Return true if the variable is a number."""
- return isinstance(value, (int, long, float, complex))
-
-
-def test_sequence(value):
- """Return true if the variable is a sequence. Sequences are variables
- that are iterable.
- """
- try:
- len(value)
- value.__getitem__
- except:
- return False
- return True
-
-
-def test_sameas(value, other):
- """Check if an object points to the same memory address than another
- object:
-
- .. sourcecode:: jinja
-
- {% if foo.attribute is sameas false %}
- the foo attribute really is the `False` singleton
- {% endif %}
- """
- return value is other
-
-
-def test_iterable(value):
- """Check if it's possible to iterate over an object."""
- try:
- iter(value)
- except TypeError:
- return False
- return True
-
-
-def test_escaped(value):
- """Check if the value is escaped."""
- return hasattr(value, '__html__')
-
-
-TESTS = {
- 'odd': test_odd,
- 'even': test_even,
- 'divisibleby': test_divisibleby,
- 'defined': test_defined,
- 'undefined': test_undefined,
- 'none': test_none,
- 'lower': test_lower,
- 'upper': test_upper,
- 'string': test_string,
- 'mapping': test_mapping,
- 'number': test_number,
- 'sequence': test_sequence,
- 'iterable': test_iterable,
- 'callable': test_callable,
- 'sameas': test_sameas,
- 'escaped': test_escaped
-}
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/__init__.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/__init__.py
deleted file mode 100755
index 1f10ef68..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/__init__.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite
- ~~~~~~~~~~~~~~~~
-
- All the unittests of Jinja2. These tests can be executed by
- either running run-tests.py using multiple Python versions at
- the same time.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import os
-import re
-import sys
-import unittest
-from traceback import format_exception
-from jinja2 import loaders
-
-
-here = os.path.dirname(os.path.abspath(__file__))
-
-dict_loader = loaders.DictLoader({
- 'justdict.html': 'FOO'
-})
-package_loader = loaders.PackageLoader('jinja2.testsuite.res', 'templates')
-filesystem_loader = loaders.FileSystemLoader(here + '/res/templates')
-function_loader = loaders.FunctionLoader({'justfunction.html': 'FOO'}.get)
-choice_loader = loaders.ChoiceLoader([dict_loader, package_loader])
-prefix_loader = loaders.PrefixLoader({
- 'a': filesystem_loader,
- 'b': dict_loader
-})
-
-
-class JinjaTestCase(unittest.TestCase):
-
- ### use only these methods for testing. If you need standard
- ### unittest method, wrap them!
-
- def setup(self):
- pass
-
- def teardown(self):
- pass
-
- def setUp(self):
- self.setup()
-
- def tearDown(self):
- self.teardown()
-
- def assert_equal(self, a, b):
- return self.assertEqual(a, b)
-
- def assert_raises(self, *args, **kwargs):
- return self.assertRaises(*args, **kwargs)
-
- def assert_traceback_matches(self, callback, expected_tb):
- try:
- callback()
- except Exception, e:
- tb = format_exception(*sys.exc_info())
- if re.search(expected_tb.strip(), ''.join(tb)) is None:
- raise self.fail('Traceback did not match:\n\n%s\nexpected:\n%s'
- % (''.join(tb), expected_tb))
- else:
- self.fail('Expected exception')
-
-
-def suite():
- from jinja2.testsuite import ext, filters, tests, core_tags, \
- loader, inheritance, imports, lexnparse, security, api, \
- regression, debug, utils, doctests
- suite = unittest.TestSuite()
- suite.addTest(ext.suite())
- suite.addTest(filters.suite())
- suite.addTest(tests.suite())
- suite.addTest(core_tags.suite())
- suite.addTest(loader.suite())
- suite.addTest(inheritance.suite())
- suite.addTest(imports.suite())
- suite.addTest(lexnparse.suite())
- suite.addTest(security.suite())
- suite.addTest(api.suite())
- suite.addTest(regression.suite())
- suite.addTest(debug.suite())
- suite.addTest(utils.suite())
-
- # doctests will not run on python 3 currently. Too many issues
- # with that, do not test that on that platform.
- if sys.version_info < (3, 0):
- suite.addTest(doctests.suite())
-
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/api.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/api.py
deleted file mode 100755
index c8f96347..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/api.py
+++ /dev/null
@@ -1,245 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.api
- ~~~~~~~~~~~~~~~~~~~~
-
- Tests the public API and related stuff.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment, Undefined, DebugUndefined, \
- StrictUndefined, UndefinedError, meta, \
- is_undefined, Template, DictLoader
-from jinja2.utils import Cycler
-
-env = Environment()
-
-
-class ExtendedAPITestCase(JinjaTestCase):
-
- def test_item_and_attribute(self):
- from jinja2.sandbox import SandboxedEnvironment
-
- for env in Environment(), SandboxedEnvironment():
- # the |list is necessary for python3
- tmpl = env.from_string('{{ foo.items()|list }}')
- assert tmpl.render(foo={'items': 42}) == "[('items', 42)]"
- tmpl = env.from_string('{{ foo|attr("items")()|list }}')
- assert tmpl.render(foo={'items': 42}) == "[('items', 42)]"
- tmpl = env.from_string('{{ foo["items"] }}')
- assert tmpl.render(foo={'items': 42}) == '42'
-
- def test_finalizer(self):
- def finalize_none_empty(value):
- if value is None:
- value = u''
- return value
- env = Environment(finalize=finalize_none_empty)
- tmpl = env.from_string('{% for item in seq %}|{{ item }}{% endfor %}')
- assert tmpl.render(seq=(None, 1, "foo")) == '||1|foo'
- tmpl = env.from_string('<{{ none }}>')
- assert tmpl.render() == '<>'
-
- def test_cycler(self):
- items = 1, 2, 3
- c = Cycler(*items)
- for item in items + items:
- assert c.current == item
- assert c.next() == item
- c.next()
- assert c.current == 2
- c.reset()
- assert c.current == 1
-
- def test_expressions(self):
- expr = env.compile_expression("foo")
- assert expr() is None
- assert expr(foo=42) == 42
- expr2 = env.compile_expression("foo", undefined_to_none=False)
- assert is_undefined(expr2())
-
- expr = env.compile_expression("42 + foo")
- assert expr(foo=42) == 84
-
- def test_template_passthrough(self):
- t = Template('Content')
- assert env.get_template(t) is t
- assert env.select_template([t]) is t
- assert env.get_or_select_template([t]) is t
- assert env.get_or_select_template(t) is t
-
- def test_autoescape_autoselect(self):
- def select_autoescape(name):
- if name is None or '.' not in name:
- return False
- return name.endswith('.html')
- env = Environment(autoescape=select_autoescape,
- loader=DictLoader({
- 'test.txt': '{{ foo }}',
- 'test.html': '{{ foo }}'
- }))
- t = env.get_template('test.txt')
- assert t.render(foo='<foo>') == '<foo>'
- t = env.get_template('test.html')
- assert t.render(foo='<foo>') == '&lt;foo&gt;'
- t = env.from_string('{{ foo }}')
- assert t.render(foo='<foo>') == '<foo>'
-
-
-class MetaTestCase(JinjaTestCase):
-
- def test_find_undeclared_variables(self):
- ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
- x = meta.find_undeclared_variables(ast)
- assert x == set(['bar'])
-
- ast = env.parse('{% set foo = 42 %}{{ bar + foo }}'
- '{% macro meh(x) %}{{ x }}{% endmacro %}'
- '{% for item in seq %}{{ muh(item) + meh(seq) }}{% endfor %}')
- x = meta.find_undeclared_variables(ast)
- assert x == set(['bar', 'seq', 'muh'])
-
- def test_find_refererenced_templates(self):
- ast = env.parse('{% extends "layout.html" %}{% include helper %}')
- i = meta.find_referenced_templates(ast)
- assert i.next() == 'layout.html'
- assert i.next() is None
- assert list(i) == []
-
- ast = env.parse('{% extends "layout.html" %}'
- '{% from "test.html" import a, b as c %}'
- '{% import "meh.html" as meh %}'
- '{% include "muh.html" %}')
- i = meta.find_referenced_templates(ast)
- assert list(i) == ['layout.html', 'test.html', 'meh.html', 'muh.html']
-
- def test_find_included_templates(self):
- ast = env.parse('{% include ["foo.html", "bar.html"] %}')
- i = meta.find_referenced_templates(ast)
- assert list(i) == ['foo.html', 'bar.html']
-
- ast = env.parse('{% include ("foo.html", "bar.html") %}')
- i = meta.find_referenced_templates(ast)
- assert list(i) == ['foo.html', 'bar.html']
-
- ast = env.parse('{% include ["foo.html", "bar.html", foo] %}')
- i = meta.find_referenced_templates(ast)
- assert list(i) == ['foo.html', 'bar.html', None]
-
- ast = env.parse('{% include ("foo.html", "bar.html", foo) %}')
- i = meta.find_referenced_templates(ast)
- assert list(i) == ['foo.html', 'bar.html', None]
-
-
-class StreamingTestCase(JinjaTestCase):
-
- def test_basic_streaming(self):
- tmpl = env.from_string("<ul>{% for item in seq %}<li>{{ loop.index "
- "}} - {{ item }}</li>{%- endfor %}</ul>")
- stream = tmpl.stream(seq=range(4))
- self.assert_equal(stream.next(), '<ul>')
- self.assert_equal(stream.next(), '<li>1 - 0</li>')
- self.assert_equal(stream.next(), '<li>2 - 1</li>')
- self.assert_equal(stream.next(), '<li>3 - 2</li>')
- self.assert_equal(stream.next(), '<li>4 - 3</li>')
- self.assert_equal(stream.next(), '</ul>')
-
- def test_buffered_streaming(self):
- tmpl = env.from_string("<ul>{% for item in seq %}<li>{{ loop.index "
- "}} - {{ item }}</li>{%- endfor %}</ul>")
- stream = tmpl.stream(seq=range(4))
- stream.enable_buffering(size=3)
- self.assert_equal(stream.next(), u'<ul><li>1 - 0</li><li>2 - 1</li>')
- self.assert_equal(stream.next(), u'<li>3 - 2</li><li>4 - 3</li></ul>')
-
- def test_streaming_behavior(self):
- tmpl = env.from_string("")
- stream = tmpl.stream()
- assert not stream.buffered
- stream.enable_buffering(20)
- assert stream.buffered
- stream.disable_buffering()
- assert not stream.buffered
-
-
-class UndefinedTestCase(JinjaTestCase):
-
- def test_stopiteration_is_undefined(self):
- def test():
- raise StopIteration()
- t = Template('A{{ test() }}B')
- assert t.render(test=test) == 'AB'
- t = Template('A{{ test().missingattribute }}B')
- self.assert_raises(UndefinedError, t.render, test=test)
-
- def test_undefined_and_special_attributes(self):
- try:
- Undefined('Foo').__dict__
- except AttributeError:
- pass
- else:
- assert False, "Expected actual attribute error"
-
- def test_default_undefined(self):
- env = Environment(undefined=Undefined)
- self.assert_equal(env.from_string('{{ missing }}').render(), u'')
- self.assert_raises(UndefinedError,
- env.from_string('{{ missing.attribute }}').render)
- self.assert_equal(env.from_string('{{ missing|list }}').render(), '[]')
- self.assert_equal(env.from_string('{{ missing is not defined }}').render(), 'True')
- self.assert_equal(env.from_string('{{ foo.missing }}').render(foo=42), '')
- self.assert_equal(env.from_string('{{ not missing }}').render(), 'True')
-
- def test_debug_undefined(self):
- env = Environment(undefined=DebugUndefined)
- self.assert_equal(env.from_string('{{ missing }}').render(), '{{ missing }}')
- self.assert_raises(UndefinedError,
- env.from_string('{{ missing.attribute }}').render)
- self.assert_equal(env.from_string('{{ missing|list }}').render(), '[]')
- self.assert_equal(env.from_string('{{ missing is not defined }}').render(), 'True')
- self.assert_equal(env.from_string('{{ foo.missing }}').render(foo=42),
- u"{{ no such element: int object['missing'] }}")
- self.assert_equal(env.from_string('{{ not missing }}').render(), 'True')
-
- def test_strict_undefined(self):
- env = Environment(undefined=StrictUndefined)
- self.assert_raises(UndefinedError, env.from_string('{{ missing }}').render)
- self.assert_raises(UndefinedError, env.from_string('{{ missing.attribute }}').render)
- self.assert_raises(UndefinedError, env.from_string('{{ missing|list }}').render)
- self.assert_equal(env.from_string('{{ missing is not defined }}').render(), 'True')
- self.assert_raises(UndefinedError, env.from_string('{{ foo.missing }}').render, foo=42)
- self.assert_raises(UndefinedError, env.from_string('{{ not missing }}').render)
-
- def test_indexing_gives_undefined(self):
- t = Template("{{ var[42].foo }}")
- self.assert_raises(UndefinedError, t.render, var=0)
-
- def test_none_gives_proper_error(self):
- try:
- Environment().getattr(None, 'split')()
- except UndefinedError, e:
- assert e.message == "'None' has no attribute 'split'"
- else:
- assert False, 'expected exception'
-
- def test_object_repr(self):
- try:
- Undefined(obj=42, name='upper')()
- except UndefinedError, e:
- assert e.message == "'int object' has no attribute 'upper'"
- else:
- assert False, 'expected exception'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ExtendedAPITestCase))
- suite.addTest(unittest.makeSuite(MetaTestCase))
- suite.addTest(unittest.makeSuite(StreamingTestCase))
- suite.addTest(unittest.makeSuite(UndefinedTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/core_tags.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/core_tags.py
deleted file mode 100755
index 2b5f5801..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/core_tags.py
+++ /dev/null
@@ -1,285 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.core_tags
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Test the core tags like for and if.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment, TemplateSyntaxError, UndefinedError, \
- DictLoader
-
-env = Environment()
-
-
-class ForLoopTestCase(JinjaTestCase):
-
- def test_simple(self):
- tmpl = env.from_string('{% for item in seq %}{{ item }}{% endfor %}')
- assert tmpl.render(seq=range(10)) == '0123456789'
-
- def test_else(self):
- tmpl = env.from_string('{% for item in seq %}XXX{% else %}...{% endfor %}')
- assert tmpl.render() == '...'
-
- def test_empty_blocks(self):
- tmpl = env.from_string('<{% for item in seq %}{% else %}{% endfor %}>')
- assert tmpl.render() == '<>'
-
- def test_context_vars(self):
- tmpl = env.from_string('''{% for item in seq -%}
- {{ loop.index }}|{{ loop.index0 }}|{{ loop.revindex }}|{{
- loop.revindex0 }}|{{ loop.first }}|{{ loop.last }}|{{
- loop.length }}###{% endfor %}''')
- one, two, _ = tmpl.render(seq=[0, 1]).split('###')
- (one_index, one_index0, one_revindex, one_revindex0, one_first,
- one_last, one_length) = one.split('|')
- (two_index, two_index0, two_revindex, two_revindex0, two_first,
- two_last, two_length) = two.split('|')
-
- assert int(one_index) == 1 and int(two_index) == 2
- assert int(one_index0) == 0 and int(two_index0) == 1
- assert int(one_revindex) == 2 and int(two_revindex) == 1
- assert int(one_revindex0) == 1 and int(two_revindex0) == 0
- assert one_first == 'True' and two_first == 'False'
- assert one_last == 'False' and two_last == 'True'
- assert one_length == two_length == '2'
-
- def test_cycling(self):
- tmpl = env.from_string('''{% for item in seq %}{{
- loop.cycle('<1>', '<2>') }}{% endfor %}{%
- for item in seq %}{{ loop.cycle(*through) }}{% endfor %}''')
- output = tmpl.render(seq=range(4), through=('<1>', '<2>'))
- assert output == '<1><2>' * 4
-
- def test_scope(self):
- tmpl = env.from_string('{% for item in seq %}{% endfor %}{{ item }}')
- output = tmpl.render(seq=range(10))
- assert not output
-
- def test_varlen(self):
- def inner():
- for item in range(5):
- yield item
- tmpl = env.from_string('{% for item in iter %}{{ item }}{% endfor %}')
- output = tmpl.render(iter=inner())
- assert output == '01234'
-
- def test_noniter(self):
- tmpl = env.from_string('{% for item in none %}...{% endfor %}')
- self.assert_raises(TypeError, tmpl.render)
-
- def test_recursive(self):
- tmpl = env.from_string('''{% for item in seq recursive -%}
- [{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}''')
- assert tmpl.render(seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a='a')])
- ]) == '[1<[1][2]>][2<[1][2]>][3<[a]>]'
-
- def test_looploop(self):
- tmpl = env.from_string('''{% for row in table %}
- {%- set rowloop = loop -%}
- {% for cell in row -%}
- [{{ rowloop.index }}|{{ loop.index }}]
- {%- endfor %}
- {%- endfor %}''')
- assert tmpl.render(table=['ab', 'cd']) == '[1|1][1|2][2|1][2|2]'
-
- def test_reversed_bug(self):
- tmpl = env.from_string('{% for i in items %}{{ i }}'
- '{% if not loop.last %}'
- ',{% endif %}{% endfor %}')
- assert tmpl.render(items=reversed([3, 2, 1])) == '1,2,3'
-
- def test_loop_errors(self):
- tmpl = env.from_string('''{% for item in [1] if loop.index
- == 0 %}...{% endfor %}''')
- self.assert_raises(UndefinedError, tmpl.render)
- tmpl = env.from_string('''{% for item in [] %}...{% else
- %}{{ loop }}{% endfor %}''')
- assert tmpl.render() == ''
-
- def test_loop_filter(self):
- tmpl = env.from_string('{% for item in range(10) if item '
- 'is even %}[{{ item }}]{% endfor %}')
- assert tmpl.render() == '[0][2][4][6][8]'
- tmpl = env.from_string('''
- {%- for item in range(10) if item is even %}[{{
- loop.index }}:{{ item }}]{% endfor %}''')
- assert tmpl.render() == '[1:0][2:2][3:4][4:6][5:8]'
-
- def test_loop_unassignable(self):
- self.assert_raises(TemplateSyntaxError, env.from_string,
- '{% for loop in seq %}...{% endfor %}')
-
- def test_scoped_special_var(self):
- t = env.from_string('{% for s in seq %}[{{ loop.first }}{% for c in s %}'
- '|{{ loop.first }}{% endfor %}]{% endfor %}')
- assert t.render(seq=('ab', 'cd')) == '[True|True|False][False|True|False]'
-
- def test_scoped_loop_var(self):
- t = env.from_string('{% for x in seq %}{{ loop.first }}'
- '{% for y in seq %}{% endfor %}{% endfor %}')
- assert t.render(seq='ab') == 'TrueFalse'
- t = env.from_string('{% for x in seq %}{% for y in seq %}'
- '{{ loop.first }}{% endfor %}{% endfor %}')
- assert t.render(seq='ab') == 'TrueFalseTrueFalse'
-
- def test_recursive_empty_loop_iter(self):
- t = env.from_string('''
- {%- for item in foo recursive -%}{%- endfor -%}
- ''')
- assert t.render(dict(foo=[])) == ''
-
- def test_call_in_loop(self):
- t = env.from_string('''
- {%- macro do_something() -%}
- [{{ caller() }}]
- {%- endmacro %}
-
- {%- for i in [1, 2, 3] %}
- {%- call do_something() -%}
- {{ i }}
- {%- endcall %}
- {%- endfor -%}
- ''')
- assert t.render() == '[1][2][3]'
-
- def test_scoping_bug(self):
- t = env.from_string('''
- {%- for item in foo %}...{{ item }}...{% endfor %}
- {%- macro item(a) %}...{{ a }}...{% endmacro %}
- {{- item(2) -}}
- ''')
- assert t.render(foo=(1,)) == '...1......2...'
-
- def test_unpacking(self):
- tmpl = env.from_string('{% for a, b, c in [[1, 2, 3]] %}'
- '{{ a }}|{{ b }}|{{ c }}{% endfor %}')
- assert tmpl.render() == '1|2|3'
-
-
-class IfConditionTestCase(JinjaTestCase):
-
- def test_simple(self):
- tmpl = env.from_string('''{% if true %}...{% endif %}''')
- assert tmpl.render() == '...'
-
- def test_elif(self):
- tmpl = env.from_string('''{% if false %}XXX{% elif true
- %}...{% else %}XXX{% endif %}''')
- assert tmpl.render() == '...'
-
- def test_else(self):
- tmpl = env.from_string('{% if false %}XXX{% else %}...{% endif %}')
- assert tmpl.render() == '...'
-
- def test_empty(self):
- tmpl = env.from_string('[{% if true %}{% else %}{% endif %}]')
- assert tmpl.render() == '[]'
-
- def test_complete(self):
- tmpl = env.from_string('{% if a %}A{% elif b %}B{% elif c == d %}'
- 'C{% else %}D{% endif %}')
- assert tmpl.render(a=0, b=False, c=42, d=42.0) == 'C'
-
- def test_no_scope(self):
- tmpl = env.from_string('{% if a %}{% set foo = 1 %}{% endif %}{{ foo }}')
- assert tmpl.render(a=True) == '1'
- tmpl = env.from_string('{% if true %}{% set foo = 1 %}{% endif %}{{ foo }}')
- assert tmpl.render() == '1'
-
-
-class MacrosTestCase(JinjaTestCase):
- env = Environment(trim_blocks=True)
-
- def test_simple(self):
- tmpl = self.env.from_string('''\
-{% macro say_hello(name) %}Hello {{ name }}!{% endmacro %}
-{{ say_hello('Peter') }}''')
- assert tmpl.render() == 'Hello Peter!'
-
- def test_scoping(self):
- tmpl = self.env.from_string('''\
-{% macro level1(data1) %}
-{% macro level2(data2) %}{{ data1 }}|{{ data2 }}{% endmacro %}
-{{ level2('bar') }}{% endmacro %}
-{{ level1('foo') }}''')
- assert tmpl.render() == 'foo|bar'
-
- def test_arguments(self):
- tmpl = self.env.from_string('''\
-{% macro m(a, b, c='c', d='d') %}{{ a }}|{{ b }}|{{ c }}|{{ d }}{% endmacro %}
-{{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}''')
- assert tmpl.render() == '||c|d|a||c|d|a|b|c|d|1|2|3|d'
-
- def test_varargs(self):
- tmpl = self.env.from_string('''\
-{% macro test() %}{{ varargs|join('|') }}{% endmacro %}\
-{{ test(1, 2, 3) }}''')
- assert tmpl.render() == '1|2|3'
-
- def test_simple_call(self):
- tmpl = self.env.from_string('''\
-{% macro test() %}[[{{ caller() }}]]{% endmacro %}\
-{% call test() %}data{% endcall %}''')
- assert tmpl.render() == '[[data]]'
-
- def test_complex_call(self):
- tmpl = self.env.from_string('''\
-{% macro test() %}[[{{ caller('data') }}]]{% endmacro %}\
-{% call(data) test() %}{{ data }}{% endcall %}''')
- assert tmpl.render() == '[[data]]'
-
- def test_caller_undefined(self):
- tmpl = self.env.from_string('''\
-{% set caller = 42 %}\
-{% macro test() %}{{ caller is not defined }}{% endmacro %}\
-{{ test() }}''')
- assert tmpl.render() == 'True'
-
- def test_include(self):
- self.env = Environment(loader=DictLoader({'include':
- '{% macro test(foo) %}[{{ foo }}]{% endmacro %}'}))
- tmpl = self.env.from_string('{% from "include" import test %}{{ test("foo") }}')
- assert tmpl.render() == '[foo]'
-
- def test_macro_api(self):
- tmpl = self.env.from_string('{% macro foo(a, b) %}{% endmacro %}'
- '{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}'
- '{% macro baz() %}{{ caller() }}{% endmacro %}')
- assert tmpl.module.foo.arguments == ('a', 'b')
- assert tmpl.module.foo.defaults == ()
- assert tmpl.module.foo.name == 'foo'
- assert not tmpl.module.foo.caller
- assert not tmpl.module.foo.catch_kwargs
- assert not tmpl.module.foo.catch_varargs
- assert tmpl.module.bar.arguments == ()
- assert tmpl.module.bar.defaults == ()
- assert not tmpl.module.bar.caller
- assert tmpl.module.bar.catch_kwargs
- assert tmpl.module.bar.catch_varargs
- assert tmpl.module.baz.caller
-
- def test_callself(self):
- tmpl = self.env.from_string('{% macro foo(x) %}{{ x }}{% if x > 1 %}|'
- '{{ foo(x - 1) }}{% endif %}{% endmacro %}'
- '{{ foo(5) }}')
- assert tmpl.render() == '5|4|3|2|1'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ForLoopTestCase))
- suite.addTest(unittest.makeSuite(IfConditionTestCase))
- suite.addTest(unittest.makeSuite(MacrosTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/debug.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/debug.py
deleted file mode 100755
index 7552dec3..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/debug.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.debug
- ~~~~~~~~~~~~~~~~~~~~~~
-
- Tests the debug system.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import sys
-import unittest
-
-from jinja2.testsuite import JinjaTestCase, filesystem_loader
-
-from jinja2 import Environment, TemplateSyntaxError
-
-env = Environment(loader=filesystem_loader)
-
-
-class DebugTestCase(JinjaTestCase):
-
- if sys.version_info[:2] != (2, 4):
- def test_runtime_error(self):
- def test():
- tmpl.render(fail=lambda: 1 / 0)
- tmpl = env.get_template('broken.html')
- self.assert_traceback_matches(test, r'''
- File ".*?broken.html", line 2, in (top-level template code|<module>)
- \{\{ fail\(\) \}\}
- File ".*?debug.pyc?", line \d+, in <lambda>
- tmpl\.render\(fail=lambda: 1 / 0\)
-ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero
-''')
-
- def test_syntax_error(self):
- # XXX: the .*? is necessary for python3 which does not hide
- # some of the stack frames we don't want to show. Not sure
- # what's up with that, but that is not that critical. Should
- # be fixed though.
- self.assert_traceback_matches(lambda: env.get_template('syntaxerror.html'), r'''(?sm)
- File ".*?syntaxerror.html", line 4, in (template|<module>)
- \{% endif %\}.*?
-(jinja2\.exceptions\.)?TemplateSyntaxError: Encountered unknown tag 'endif'. Jinja was looking for the following tags: 'endfor' or 'else'. The innermost block that needs to be closed is 'for'.
- ''')
-
- def test_regular_syntax_error(self):
- def test():
- raise TemplateSyntaxError('wtf', 42)
- self.assert_traceback_matches(test, r'''
- File ".*debug.pyc?", line \d+, in test
- raise TemplateSyntaxError\('wtf', 42\)
-(jinja2\.exceptions\.)?TemplateSyntaxError: wtf
- line 42''')
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(DebugTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/doctests.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/doctests.py
deleted file mode 100755
index 616d3b6e..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/doctests.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.doctests
- ~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The doctests. Collects all tests we want to test from
- the Jinja modules.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-import doctest
-
-
-def suite():
- from jinja2 import utils, sandbox, runtime, meta, loaders, \
- ext, environment, bccache, nodes
- suite = unittest.TestSuite()
- suite.addTest(doctest.DocTestSuite(utils))
- suite.addTest(doctest.DocTestSuite(sandbox))
- suite.addTest(doctest.DocTestSuite(runtime))
- suite.addTest(doctest.DocTestSuite(meta))
- suite.addTest(doctest.DocTestSuite(loaders))
- suite.addTest(doctest.DocTestSuite(ext))
- suite.addTest(doctest.DocTestSuite(environment))
- suite.addTest(doctest.DocTestSuite(bccache))
- suite.addTest(doctest.DocTestSuite(nodes))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/ext.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/ext.py
deleted file mode 100755
index 6ca6c228..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/ext.py
+++ /dev/null
@@ -1,455 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.ext
- ~~~~~~~~~~~~~~~~~~~~
-
- Tests for the extensions.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import re
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment, DictLoader, contextfunction, nodes
-from jinja2.exceptions import TemplateAssertionError
-from jinja2.ext import Extension
-from jinja2.lexer import Token, count_newlines
-from jinja2.utils import next
-
-# 2.x / 3.x
-try:
- from io import BytesIO
-except ImportError:
- from StringIO import StringIO as BytesIO
-
-
-importable_object = 23
-
-_gettext_re = re.compile(r'_\((.*?)\)(?s)')
-
-
-i18n_templates = {
- 'master.html': '<title>{{ page_title|default(_("missing")) }}</title>'
- '{% block body %}{% endblock %}',
- 'child.html': '{% extends "master.html" %}{% block body %}'
- '{% trans %}watch out{% endtrans %}{% endblock %}',
- 'plural.html': '{% trans user_count %}One user online{% pluralize %}'
- '{{ user_count }} users online{% endtrans %}',
- 'stringformat.html': '{{ _("User: %(num)s")|format(num=user_count) }}'
-}
-
-newstyle_i18n_templates = {
- 'master.html': '<title>{{ page_title|default(_("missing")) }}</title>'
- '{% block body %}{% endblock %}',
- 'child.html': '{% extends "master.html" %}{% block body %}'
- '{% trans %}watch out{% endtrans %}{% endblock %}',
- 'plural.html': '{% trans user_count %}One user online{% pluralize %}'
- '{{ user_count }} users online{% endtrans %}',
- 'stringformat.html': '{{ _("User: %(num)s", num=user_count) }}',
- 'ngettext.html': '{{ ngettext("%(num)s apple", "%(num)s apples", apples) }}',
- 'ngettext_long.html': '{% trans num=apples %}{{ num }} apple{% pluralize %}'
- '{{ num }} apples{% endtrans %}',
- 'transvars1.html': '{% trans %}User: {{ num }}{% endtrans %}',
- 'transvars2.html': '{% trans num=count %}User: {{ num }}{% endtrans %}',
- 'transvars3.html': '{% trans count=num %}User: {{ count }}{% endtrans %}',
- 'novars.html': '{% trans %}%(hello)s{% endtrans %}',
- 'vars.html': '{% trans %}{{ foo }}%(foo)s{% endtrans %}',
- 'explicitvars.html': '{% trans foo="42" %}%(foo)s{% endtrans %}'
-}
-
-
-languages = {
- 'de': {
- 'missing': u'fehlend',
- 'watch out': u'pass auf',
- 'One user online': u'Ein Benutzer online',
- '%(user_count)s users online': u'%(user_count)s Benutzer online',
- 'User: %(num)s': u'Benutzer: %(num)s',
- 'User: %(count)s': u'Benutzer: %(count)s',
- '%(num)s apple': u'%(num)s Apfel',
- '%(num)s apples': u'%(num)s Äpfel'
- }
-}
-
-
-@contextfunction
-def gettext(context, string):
- language = context.get('LANGUAGE', 'en')
- return languages.get(language, {}).get(string, string)
-
-
-@contextfunction
-def ngettext(context, s, p, n):
- language = context.get('LANGUAGE', 'en')
- if n != 1:
- return languages.get(language, {}).get(p, p)
- return languages.get(language, {}).get(s, s)
-
-
-i18n_env = Environment(
- loader=DictLoader(i18n_templates),
- extensions=['jinja2.ext.i18n']
-)
-i18n_env.globals.update({
- '_': gettext,
- 'gettext': gettext,
- 'ngettext': ngettext
-})
-
-newstyle_i18n_env = Environment(
- loader=DictLoader(newstyle_i18n_templates),
- extensions=['jinja2.ext.i18n']
-)
-newstyle_i18n_env.install_gettext_callables(gettext, ngettext, newstyle=True)
-
-class TestExtension(Extension):
- tags = set(['test'])
- ext_attr = 42
-
- def parse(self, parser):
- return nodes.Output([self.call_method('_dump', [
- nodes.EnvironmentAttribute('sandboxed'),
- self.attr('ext_attr'),
- nodes.ImportedName(__name__ + '.importable_object'),
- nodes.ContextReference()
- ])]).set_lineno(next(parser.stream).lineno)
-
- def _dump(self, sandboxed, ext_attr, imported_object, context):
- return '%s|%s|%s|%s' % (
- sandboxed,
- ext_attr,
- imported_object,
- context.blocks
- )
-
-
-class PreprocessorExtension(Extension):
-
- def preprocess(self, source, name, filename=None):
- return source.replace('[[TEST]]', '({{ foo }})')
-
-
-class StreamFilterExtension(Extension):
-
- def filter_stream(self, stream):
- for token in stream:
- if token.type == 'data':
- for t in self.interpolate(token):
- yield t
- else:
- yield token
-
- def interpolate(self, token):
- pos = 0
- end = len(token.value)
- lineno = token.lineno
- while 1:
- match = _gettext_re.search(token.value, pos)
- if match is None:
- break
- value = token.value[pos:match.start()]
- if value:
- yield Token(lineno, 'data', value)
- lineno += count_newlines(token.value)
- yield Token(lineno, 'variable_begin', None)
- yield Token(lineno, 'name', 'gettext')
- yield Token(lineno, 'lparen', None)
- yield Token(lineno, 'string', match.group(1))
- yield Token(lineno, 'rparen', None)
- yield Token(lineno, 'variable_end', None)
- pos = match.end()
- if pos < end:
- yield Token(lineno, 'data', token.value[pos:])
-
-
-class ExtensionsTestCase(JinjaTestCase):
-
- def test_extend_late(self):
- env = Environment()
- env.add_extension('jinja2.ext.autoescape')
- t = env.from_string('{% autoescape true %}{{ "<test>" }}{% endautoescape %}')
- assert t.render() == '&lt;test&gt;'
-
- def test_loop_controls(self):
- env = Environment(extensions=['jinja2.ext.loopcontrols'])
-
- tmpl = env.from_string('''
- {%- for item in [1, 2, 3, 4] %}
- {%- if item % 2 == 0 %}{% continue %}{% endif -%}
- {{ item }}
- {%- endfor %}''')
- assert tmpl.render() == '13'
-
- tmpl = env.from_string('''
- {%- for item in [1, 2, 3, 4] %}
- {%- if item > 2 %}{% break %}{% endif -%}
- {{ item }}
- {%- endfor %}''')
- assert tmpl.render() == '12'
-
- def test_do(self):
- env = Environment(extensions=['jinja2.ext.do'])
- tmpl = env.from_string('''
- {%- set items = [] %}
- {%- for char in "foo" %}
- {%- do items.append(loop.index0 ~ char) %}
- {%- endfor %}{{ items|join(', ') }}''')
- assert tmpl.render() == '0f, 1o, 2o'
-
- def test_with(self):
- env = Environment(extensions=['jinja2.ext.with_'])
- tmpl = env.from_string('''\
- {% with a=42, b=23 -%}
- {{ a }} = {{ b }}
- {% endwith -%}
- {{ a }} = {{ b }}\
- ''')
- assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] \
- == ['42 = 23', '1 = 2']
-
- def test_extension_nodes(self):
- env = Environment(extensions=[TestExtension])
- tmpl = env.from_string('{% test %}')
- assert tmpl.render() == 'False|42|23|{}'
-
- def test_identifier(self):
- assert TestExtension.identifier == __name__ + '.TestExtension'
-
- def test_rebinding(self):
- original = Environment(extensions=[TestExtension])
- overlay = original.overlay()
- for env in original, overlay:
- for ext in env.extensions.itervalues():
- assert ext.environment is env
-
- def test_preprocessor_extension(self):
- env = Environment(extensions=[PreprocessorExtension])
- tmpl = env.from_string('{[[TEST]]}')
- assert tmpl.render(foo=42) == '{(42)}'
-
- def test_streamfilter_extension(self):
- env = Environment(extensions=[StreamFilterExtension])
- env.globals['gettext'] = lambda x: x.upper()
- tmpl = env.from_string('Foo _(bar) Baz')
- out = tmpl.render()
- assert out == 'Foo BAR Baz'
-
- def test_extension_ordering(self):
- class T1(Extension):
- priority = 1
- class T2(Extension):
- priority = 2
- env = Environment(extensions=[T1, T2])
- ext = list(env.iter_extensions())
- assert ext[0].__class__ is T1
- assert ext[1].__class__ is T2
-
-
-class InternationalizationTestCase(JinjaTestCase):
-
- def test_trans(self):
- tmpl = i18n_env.get_template('child.html')
- assert tmpl.render(LANGUAGE='de') == '<title>fehlend</title>pass auf'
-
- def test_trans_plural(self):
- tmpl = i18n_env.get_template('plural.html')
- assert tmpl.render(LANGUAGE='de', user_count=1) == 'Ein Benutzer online'
- assert tmpl.render(LANGUAGE='de', user_count=2) == '2 Benutzer online'
-
- def test_complex_plural(self):
- tmpl = i18n_env.from_string('{% trans foo=42, count=2 %}{{ count }} item{% '
- 'pluralize count %}{{ count }} items{% endtrans %}')
- assert tmpl.render() == '2 items'
- self.assert_raises(TemplateAssertionError, i18n_env.from_string,
- '{% trans foo %}...{% pluralize bar %}...{% endtrans %}')
-
- def test_trans_stringformatting(self):
- tmpl = i18n_env.get_template('stringformat.html')
- assert tmpl.render(LANGUAGE='de', user_count=5) == 'Benutzer: 5'
-
- def test_extract(self):
- from jinja2.ext import babel_extract
- source = BytesIO('''
- {{ gettext('Hello World') }}
- {% trans %}Hello World{% endtrans %}
- {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
- '''.encode('ascii')) # make python 3 happy
- assert list(babel_extract(source, ('gettext', 'ngettext', '_'), [], {})) == [
- (2, 'gettext', u'Hello World', []),
- (3, 'gettext', u'Hello World', []),
- (4, 'ngettext', (u'%(users)s user', u'%(users)s users', None), [])
- ]
-
- def test_comment_extract(self):
- from jinja2.ext import babel_extract
- source = BytesIO('''
- {# trans first #}
- {{ gettext('Hello World') }}
- {% trans %}Hello World{% endtrans %}{# trans second #}
- {#: third #}
- {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
- '''.encode('utf-8')) # make python 3 happy
- assert list(babel_extract(source, ('gettext', 'ngettext', '_'), ['trans', ':'], {})) == [
- (3, 'gettext', u'Hello World', ['first']),
- (4, 'gettext', u'Hello World', ['second']),
- (6, 'ngettext', (u'%(users)s user', u'%(users)s users', None), ['third'])
- ]
-
-
-class NewstyleInternationalizationTestCase(JinjaTestCase):
-
- def test_trans(self):
- tmpl = newstyle_i18n_env.get_template('child.html')
- assert tmpl.render(LANGUAGE='de') == '<title>fehlend</title>pass auf'
-
- def test_trans_plural(self):
- tmpl = newstyle_i18n_env.get_template('plural.html')
- assert tmpl.render(LANGUAGE='de', user_count=1) == 'Ein Benutzer online'
- assert tmpl.render(LANGUAGE='de', user_count=2) == '2 Benutzer online'
-
- def test_complex_plural(self):
- tmpl = newstyle_i18n_env.from_string('{% trans foo=42, count=2 %}{{ count }} item{% '
- 'pluralize count %}{{ count }} items{% endtrans %}')
- assert tmpl.render() == '2 items'
- self.assert_raises(TemplateAssertionError, i18n_env.from_string,
- '{% trans foo %}...{% pluralize bar %}...{% endtrans %}')
-
- def test_trans_stringformatting(self):
- tmpl = newstyle_i18n_env.get_template('stringformat.html')
- assert tmpl.render(LANGUAGE='de', user_count=5) == 'Benutzer: 5'
-
- def test_newstyle_plural(self):
- tmpl = newstyle_i18n_env.get_template('ngettext.html')
- assert tmpl.render(LANGUAGE='de', apples=1) == '1 Apfel'
- assert tmpl.render(LANGUAGE='de', apples=5) == u'5 Äpfel'
-
- def test_autoescape_support(self):
- env = Environment(extensions=['jinja2.ext.autoescape',
- 'jinja2.ext.i18n'])
- env.install_gettext_callables(lambda x: u'<strong>Wert: %(name)s</strong>',
- lambda s, p, n: s, newstyle=True)
- t = env.from_string('{% autoescape ae %}{{ gettext("foo", name='
- '"<test>") }}{% endautoescape %}')
- assert t.render(ae=True) == '<strong>Wert: &lt;test&gt;</strong>'
- assert t.render(ae=False) == '<strong>Wert: <test></strong>'
-
- def test_num_used_twice(self):
- tmpl = newstyle_i18n_env.get_template('ngettext_long.html')
- assert tmpl.render(apples=5, LANGUAGE='de') == u'5 Äpfel'
-
- def test_num_called_num(self):
- source = newstyle_i18n_env.compile('''
- {% trans num=3 %}{{ num }} apple{% pluralize
- %}{{ num }} apples{% endtrans %}
- ''', raw=True)
- # quite hacky, but the only way to properly test that. The idea is
- # that the generated code does not pass num twice (although that
- # would work) for better performance. This only works on the
- # newstyle gettext of course
- assert re.search(r"l_ngettext, u?'\%\(num\)s apple', u?'\%\(num\)s "
- r"apples', 3", source) is not None
-
- def test_trans_vars(self):
- t1 = newstyle_i18n_env.get_template('transvars1.html')
- t2 = newstyle_i18n_env.get_template('transvars2.html')
- t3 = newstyle_i18n_env.get_template('transvars3.html')
- assert t1.render(num=1, LANGUAGE='de') == 'Benutzer: 1'
- assert t2.render(count=23, LANGUAGE='de') == 'Benutzer: 23'
- assert t3.render(num=42, LANGUAGE='de') == 'Benutzer: 42'
-
- def test_novars_vars_escaping(self):
- t = newstyle_i18n_env.get_template('novars.html')
- assert t.render() == '%(hello)s'
- t = newstyle_i18n_env.get_template('vars.html')
- assert t.render(foo='42') == '42%(foo)s'
- t = newstyle_i18n_env.get_template('explicitvars.html')
- assert t.render() == '%(foo)s'
-
-
-class AutoEscapeTestCase(JinjaTestCase):
-
- def test_scoped_setting(self):
- env = Environment(extensions=['jinja2.ext.autoescape'],
- autoescape=True)
- tmpl = env.from_string('''
- {{ "<HelloWorld>" }}
- {% autoescape false %}
- {{ "<HelloWorld>" }}
- {% endautoescape %}
- {{ "<HelloWorld>" }}
- ''')
- assert tmpl.render().split() == \
- [u'&lt;HelloWorld&gt;', u'<HelloWorld>', u'&lt;HelloWorld&gt;']
-
- env = Environment(extensions=['jinja2.ext.autoescape'],
- autoescape=False)
- tmpl = env.from_string('''
- {{ "<HelloWorld>" }}
- {% autoescape true %}
- {{ "<HelloWorld>" }}
- {% endautoescape %}
- {{ "<HelloWorld>" }}
- ''')
- assert tmpl.render().split() == \
- [u'<HelloWorld>', u'&lt;HelloWorld&gt;', u'<HelloWorld>']
-
- def test_nonvolatile(self):
- env = Environment(extensions=['jinja2.ext.autoescape'],
- autoescape=True)
- tmpl = env.from_string('{{ {"foo": "<test>"}|xmlattr|escape }}')
- assert tmpl.render() == ' foo="&lt;test&gt;"'
- tmpl = env.from_string('{% autoescape false %}{{ {"foo": "<test>"}'
- '|xmlattr|escape }}{% endautoescape %}')
- assert tmpl.render() == ' foo=&#34;&amp;lt;test&amp;gt;&#34;'
-
- def test_volatile(self):
- env = Environment(extensions=['jinja2.ext.autoescape'],
- autoescape=True)
- tmpl = env.from_string('{% autoescape foo %}{{ {"foo": "<test>"}'
- '|xmlattr|escape }}{% endautoescape %}')
- assert tmpl.render(foo=False) == ' foo=&#34;&amp;lt;test&amp;gt;&#34;'
- assert tmpl.render(foo=True) == ' foo="&lt;test&gt;"'
-
- def test_scoping(self):
- env = Environment(extensions=['jinja2.ext.autoescape'])
- tmpl = env.from_string('{% autoescape true %}{% set x = "<x>" %}{{ x }}'
- '{% endautoescape %}{{ x }}{{ "<y>" }}')
- assert tmpl.render(x=1) == '&lt;x&gt;1<y>'
-
- def test_volatile_scoping(self):
- env = Environment(extensions=['jinja2.ext.autoescape'])
- tmplsource = '''
- {% autoescape val %}
- {% macro foo(x) %}
- [{{ x }}]
- {% endmacro %}
- {{ foo().__class__.__name__ }}
- {% endautoescape %}
- {{ '<testing>' }}
- '''
- tmpl = env.from_string(tmplsource)
- assert tmpl.render(val=True).split()[0] == 'Markup'
- assert tmpl.render(val=False).split()[0] == unicode.__name__
-
- # looking at the source we should see <testing> there in raw
- # (and then escaped as well)
- env = Environment(extensions=['jinja2.ext.autoescape'])
- pysource = env.compile(tmplsource, raw=True)
- assert '<testing>\\n' in pysource
-
- env = Environment(extensions=['jinja2.ext.autoescape'],
- autoescape=True)
- pysource = env.compile(tmplsource, raw=True)
- assert '&lt;testing&gt;\\n' in pysource
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ExtensionsTestCase))
- suite.addTest(unittest.makeSuite(InternationalizationTestCase))
- suite.addTest(unittest.makeSuite(NewstyleInternationalizationTestCase))
- suite.addTest(unittest.makeSuite(AutoEscapeTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/filters.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/filters.py
deleted file mode 100755
index aefe7682..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/filters.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.filters
- ~~~~~~~~~~~~~~~~~~~~~~~~
-
- Tests for the jinja filters.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Markup, Environment
-
-env = Environment()
-
-
-class FilterTestCase(JinjaTestCase):
-
- def test_capitalize(self):
- tmpl = env.from_string('{{ "foo bar"|capitalize }}')
- assert tmpl.render() == 'Foo bar'
-
- def test_center(self):
- tmpl = env.from_string('{{ "foo"|center(9) }}')
- assert tmpl.render() == ' foo '
-
- def test_default(self):
- tmpl = env.from_string(
- "{{ missing|default('no') }}|{{ false|default('no') }}|"
- "{{ false|default('no', true) }}|{{ given|default('no') }}"
- )
- assert tmpl.render(given='yes') == 'no|False|no|yes'
-
- def test_dictsort(self):
- tmpl = env.from_string(
- '{{ foo|dictsort }}|'
- '{{ foo|dictsort(true) }}|'
- '{{ foo|dictsort(false, "value") }}'
- )
- out = tmpl.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3})
- assert out == ("[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]|"
- "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]|"
- "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]")
-
- def test_batch(self):
- tmpl = env.from_string("{{ foo|batch(3)|list }}|"
- "{{ foo|batch(3, 'X')|list }}")
- out = tmpl.render(foo=range(10))
- assert out == ("[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|"
- "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]")
-
- def test_slice(self):
- tmpl = env.from_string('{{ foo|slice(3)|list }}|'
- '{{ foo|slice(3, "X")|list }}')
- out = tmpl.render(foo=range(10))
- assert out == ("[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
- "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]")
-
- def test_escape(self):
- tmpl = env.from_string('''{{ '<">&'|escape }}''')
- out = tmpl.render()
- assert out == '&lt;&#34;&gt;&amp;'
-
- def test_striptags(self):
- tmpl = env.from_string('''{{ foo|striptags }}''')
- out = tmpl.render(foo=' <p>just a small \n <a href="#">'
- 'example</a> link</p>\n<p>to a webpage</p> '
- '<!-- <p>and some commented stuff</p> -->')
- assert out == 'just a small example link to a webpage'
-
- def test_filesizeformat(self):
- tmpl = env.from_string(
- '{{ 100|filesizeformat }}|'
- '{{ 1000|filesizeformat }}|'
- '{{ 1000000|filesizeformat }}|'
- '{{ 1000000000|filesizeformat }}|'
- '{{ 1000000000000|filesizeformat }}|'
- '{{ 100|filesizeformat(true) }}|'
- '{{ 1000|filesizeformat(true) }}|'
- '{{ 1000000|filesizeformat(true) }}|'
- '{{ 1000000000|filesizeformat(true) }}|'
- '{{ 1000000000000|filesizeformat(true) }}'
- )
- out = tmpl.render()
- assert out == (
- '100 Bytes|0.0 kB|0.0 MB|0.0 GB|0.0 TB|100 Bytes|'
- '1000 Bytes|1.0 KiB|0.9 MiB|0.9 GiB'
- )
-
- def test_first(self):
- tmpl = env.from_string('{{ foo|first }}')
- out = tmpl.render(foo=range(10))
- assert out == '0'
-
- def test_float(self):
- tmpl = env.from_string('{{ "42"|float }}|'
- '{{ "ajsghasjgd"|float }}|'
- '{{ "32.32"|float }}')
- out = tmpl.render()
- assert out == '42.0|0.0|32.32'
-
- def test_format(self):
- tmpl = env.from_string('''{{ "%s|%s"|format("a", "b") }}''')
- out = tmpl.render()
- assert out == 'a|b'
-
- def test_indent(self):
- tmpl = env.from_string('{{ foo|indent(2) }}|{{ foo|indent(2, true) }}')
- text = '\n'.join([' '.join(['foo', 'bar'] * 2)] * 2)
- out = tmpl.render(foo=text)
- assert out == ('foo bar foo bar\n foo bar foo bar| '
- 'foo bar foo bar\n foo bar foo bar')
-
- def test_int(self):
- tmpl = env.from_string('{{ "42"|int }}|{{ "ajsghasjgd"|int }}|'
- '{{ "32.32"|int }}')
- out = tmpl.render()
- assert out == '42|0|32'
-
- def test_join(self):
- tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}')
- out = tmpl.render()
- assert out == '1|2|3'
-
- env2 = Environment(autoescape=True)
- tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
- assert tmpl.render() == '&lt;foo&gt;<span>foo</span>'
-
- def test_join_attribute(self):
- class User(object):
- def __init__(self, username):
- self.username = username
- tmpl = env.from_string('''{{ users|join(', ', 'username') }}''')
- assert tmpl.render(users=map(User, ['foo', 'bar'])) == 'foo, bar'
-
- def test_last(self):
- tmpl = env.from_string('''{{ foo|last }}''')
- out = tmpl.render(foo=range(10))
- assert out == '9'
-
- def test_length(self):
- tmpl = env.from_string('''{{ "hello world"|length }}''')
- out = tmpl.render()
- assert out == '11'
-
- def test_lower(self):
- tmpl = env.from_string('''{{ "FOO"|lower }}''')
- out = tmpl.render()
- assert out == 'foo'
-
- def test_pprint(self):
- from pprint import pformat
- tmpl = env.from_string('''{{ data|pprint }}''')
- data = range(1000)
- assert tmpl.render(data=data) == pformat(data)
-
- def test_random(self):
- tmpl = env.from_string('''{{ seq|random }}''')
- seq = range(100)
- for _ in range(10):
- assert int(tmpl.render(seq=seq)) in seq
-
- def test_reverse(self):
- tmpl = env.from_string('{{ "foobar"|reverse|join }}|'
- '{{ [1, 2, 3]|reverse|list }}')
- assert tmpl.render() == 'raboof|[3, 2, 1]'
-
- def test_string(self):
- x = [1, 2, 3, 4, 5]
- tmpl = env.from_string('''{{ obj|string }}''')
- assert tmpl.render(obj=x) == unicode(x)
-
- def test_title(self):
- tmpl = env.from_string('''{{ "foo bar"|title }}''')
- assert tmpl.render() == "Foo Bar"
-
- def test_truncate(self):
- tmpl = env.from_string(
- '{{ data|truncate(15, true, ">>>") }}|'
- '{{ data|truncate(15, false, ">>>") }}|'
- '{{ smalldata|truncate(15) }}'
- )
- out = tmpl.render(data='foobar baz bar' * 1000,
- smalldata='foobar baz bar')
- assert out == 'foobar baz barf>>>|foobar baz >>>|foobar baz bar'
-
- def test_upper(self):
- tmpl = env.from_string('{{ "foo"|upper }}')
- assert tmpl.render() == 'FOO'
-
- def test_urlize(self):
- tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
- assert tmpl.render() == 'foo <a href="http://www.example.com/">'\
- 'http://www.example.com/</a> bar'
-
- def test_wordcount(self):
- tmpl = env.from_string('{{ "foo bar baz"|wordcount }}')
- assert tmpl.render() == '3'
-
- def test_block(self):
- tmpl = env.from_string('{% filter lower|escape %}<HEHE>{% endfilter %}')
- assert tmpl.render() == '&lt;hehe&gt;'
-
- def test_chaining(self):
- tmpl = env.from_string('''{{ ['<foo>', '<bar>']|first|upper|escape }}''')
- assert tmpl.render() == '&lt;FOO&gt;'
-
- def test_sum(self):
- tmpl = env.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''')
- assert tmpl.render() == '21'
-
- def test_sum_attributes(self):
- tmpl = env.from_string('''{{ values|sum('value') }}''')
- assert tmpl.render(values=[
- {'value': 23},
- {'value': 1},
- {'value': 18},
- ]) == '42'
-
- def test_sum_attributes_nested(self):
- tmpl = env.from_string('''{{ values|sum('real.value') }}''')
- assert tmpl.render(values=[
- {'real': {'value': 23}},
- {'real': {'value': 1}},
- {'real': {'value': 18}},
- ]) == '42'
-
- def test_abs(self):
- tmpl = env.from_string('''{{ -1|abs }}|{{ 1|abs }}''')
- assert tmpl.render() == '1|1', tmpl.render()
-
- def test_round_positive(self):
- tmpl = env.from_string('{{ 2.7|round }}|{{ 2.1|round }}|'
- "{{ 2.1234|round(3, 'floor') }}|"
- "{{ 2.1|round(0, 'ceil') }}")
- assert tmpl.render() == '3.0|2.0|2.123|3.0', tmpl.render()
-
- def test_round_negative(self):
- tmpl = env.from_string('{{ 21.3|round(-1)}}|'
- "{{ 21.3|round(-1, 'ceil')}}|"
- "{{ 21.3|round(-1, 'floor')}}")
- assert tmpl.render() == '20.0|30.0|20.0',tmpl.render()
-
- def test_xmlattr(self):
- tmpl = env.from_string("{{ {'foo': 42, 'bar': 23, 'fish': none, "
- "'spam': missing, 'blub:blub': '<?>'}|xmlattr }}")
- out = tmpl.render().split()
- assert len(out) == 3
- assert 'foo="42"' in out
- assert 'bar="23"' in out
- assert 'blub:blub="&lt;?&gt;"' in out
-
- def test_sort1(self):
- tmpl = env.from_string('{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}')
- assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
-
- def test_sort2(self):
- tmpl = env.from_string('{{ "".join(["c", "A", "b", "D"]|sort) }}')
- assert tmpl.render() == 'AbcD'
-
- def test_sort3(self):
- tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''')
- assert tmpl.render() == "['Bar', 'blah', 'foo']"
-
- def test_sort4(self):
- class Magic(object):
- def __init__(self, value):
- self.value = value
- def __unicode__(self):
- return unicode(self.value)
- tmpl = env.from_string('''{{ items|sort(attribute='value')|join }}''')
- assert tmpl.render(items=map(Magic, [3, 2, 4, 1])) == '1234'
-
- def test_groupby(self):
- tmpl = env.from_string('''
- {%- for grouper, list in [{'foo': 1, 'bar': 2},
- {'foo': 2, 'bar': 3},
- {'foo': 1, 'bar': 1},
- {'foo': 3, 'bar': 4}]|groupby('foo') -%}
- {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}|
- {%- endfor %}''')
- assert tmpl.render().split('|') == [
- "1: 1, 2: 1, 1",
- "2: 2, 3",
- "3: 3, 4",
- ""
- ]
-
- def test_groupby_tuple_index(self):
- tmpl = env.from_string('''
- {%- for grouper, list in [('a', 1), ('a', 2), ('b', 1)]|groupby(0) -%}
- {{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}|
- {%- endfor %}''')
- assert tmpl.render() == 'a:1:2|b:1|'
-
- def test_groupby_multidot(self):
- class Date(object):
- def __init__(self, day, month, year):
- self.day = day
- self.month = month
- self.year = year
- class Article(object):
- def __init__(self, title, *date):
- self.date = Date(*date)
- self.title = title
- articles = [
- Article('aha', 1, 1, 1970),
- Article('interesting', 2, 1, 1970),
- Article('really?', 3, 1, 1970),
- Article('totally not', 1, 1, 1971)
- ]
- tmpl = env.from_string('''
- {%- for year, list in articles|groupby('date.year') -%}
- {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}|
- {%- endfor %}''')
- assert tmpl.render(articles=articles).split('|') == [
- '1970[aha][interesting][really?]',
- '1971[totally not]',
- ''
- ]
-
- def test_filtertag(self):
- tmpl = env.from_string("{% filter upper|replace('FOO', 'foo') %}"
- "foobar{% endfilter %}")
- assert tmpl.render() == 'fooBAR'
-
- def test_replace(self):
- env = Environment()
- tmpl = env.from_string('{{ string|replace("o", 42) }}')
- assert tmpl.render(string='<foo>') == '<f4242>'
- env = Environment(autoescape=True)
- tmpl = env.from_string('{{ string|replace("o", 42) }}')
- assert tmpl.render(string='<foo>') == '&lt;f4242&gt;'
- tmpl = env.from_string('{{ string|replace("<", 42) }}')
- assert tmpl.render(string='<foo>') == '42foo&gt;'
- tmpl = env.from_string('{{ string|replace("o", ">x<") }}')
- assert tmpl.render(string=Markup('foo')) == 'f&gt;x&lt;&gt;x&lt;'
-
- def test_forceescape(self):
- tmpl = env.from_string('{{ x|forceescape }}')
- assert tmpl.render(x=Markup('<div />')) == u'&lt;div /&gt;'
-
- def test_safe(self):
- env = Environment(autoescape=True)
- tmpl = env.from_string('{{ "<div>foo</div>"|safe }}')
- assert tmpl.render() == '<div>foo</div>'
- tmpl = env.from_string('{{ "<div>foo</div>" }}')
- assert tmpl.render() == '&lt;div&gt;foo&lt;/div&gt;'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(FilterTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/imports.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/imports.py
deleted file mode 100755
index 1cb12cbd..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/imports.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.imports
- ~~~~~~~~~~~~~~~~~~~~~~~~
-
- Tests the import features (with includes).
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment, DictLoader
-from jinja2.exceptions import TemplateNotFound, TemplatesNotFound
-
-
-test_env = Environment(loader=DictLoader(dict(
- module='{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}',
- header='[{{ foo }}|{{ 23 }}]',
- o_printer='({{ o }})'
-)))
-test_env.globals['bar'] = 23
-
-
-class ImportsTestCase(JinjaTestCase):
-
- def test_context_imports(self):
- t = test_env.from_string('{% import "module" as m %}{{ m.test() }}')
- assert t.render(foo=42) == '[|23]'
- t = test_env.from_string('{% import "module" as m without context %}{{ m.test() }}')
- assert t.render(foo=42) == '[|23]'
- t = test_env.from_string('{% import "module" as m with context %}{{ m.test() }}')
- assert t.render(foo=42) == '[42|23]'
- t = test_env.from_string('{% from "module" import test %}{{ test() }}')
- assert t.render(foo=42) == '[|23]'
- t = test_env.from_string('{% from "module" import test without context %}{{ test() }}')
- assert t.render(foo=42) == '[|23]'
- t = test_env.from_string('{% from "module" import test with context %}{{ test() }}')
- assert t.render(foo=42) == '[42|23]'
-
- def test_trailing_comma(self):
- test_env.from_string('{% from "foo" import bar, baz with context %}')
- test_env.from_string('{% from "foo" import bar, baz, with context %}')
- test_env.from_string('{% from "foo" import bar, with context %}')
- test_env.from_string('{% from "foo" import bar, with, context %}')
- test_env.from_string('{% from "foo" import bar, with with context %}')
-
- def test_exports(self):
- m = test_env.from_string('''
- {% macro toplevel() %}...{% endmacro %}
- {% macro __private() %}...{% endmacro %}
- {% set variable = 42 %}
- {% for item in [1] %}
- {% macro notthere() %}{% endmacro %}
- {% endfor %}
- ''').module
- assert m.toplevel() == '...'
- assert not hasattr(m, '__missing')
- assert m.variable == 42
- assert not hasattr(m, 'notthere')
-
-
-class IncludesTestCase(JinjaTestCase):
-
- def test_context_include(self):
- t = test_env.from_string('{% include "header" %}')
- assert t.render(foo=42) == '[42|23]'
- t = test_env.from_string('{% include "header" with context %}')
- assert t.render(foo=42) == '[42|23]'
- t = test_env.from_string('{% include "header" without context %}')
- assert t.render(foo=42) == '[|23]'
-
- def test_choice_includes(self):
- t = test_env.from_string('{% include ["missing", "header"] %}')
- assert t.render(foo=42) == '[42|23]'
-
- t = test_env.from_string('{% include ["missing", "missing2"] ignore missing %}')
- assert t.render(foo=42) == ''
-
- t = test_env.from_string('{% include ["missing", "missing2"] %}')
- self.assert_raises(TemplateNotFound, t.render)
- try:
- t.render()
- except TemplatesNotFound, e:
- assert e.templates == ['missing', 'missing2']
- assert e.name == 'missing2'
- else:
- assert False, 'thou shalt raise'
-
- def test_includes(t, **ctx):
- ctx['foo'] = 42
- assert t.render(ctx) == '[42|23]'
-
- t = test_env.from_string('{% include ["missing", "header"] %}')
- test_includes(t)
- t = test_env.from_string('{% include x %}')
- test_includes(t, x=['missing', 'header'])
- t = test_env.from_string('{% include [x, "header"] %}')
- test_includes(t, x='missing')
- t = test_env.from_string('{% include x %}')
- test_includes(t, x='header')
- t = test_env.from_string('{% include x %}')
- test_includes(t, x='header')
- t = test_env.from_string('{% include [x] %}')
- test_includes(t, x='header')
-
- def test_include_ignoring_missing(self):
- t = test_env.from_string('{% include "missing" %}')
- self.assert_raises(TemplateNotFound, t.render)
- for extra in '', 'with context', 'without context':
- t = test_env.from_string('{% include "missing" ignore missing ' +
- extra + ' %}')
- assert t.render() == ''
-
- def test_context_include_with_overrides(self):
- env = Environment(loader=DictLoader(dict(
- main="{% for item in [1, 2, 3] %}{% include 'item' %}{% endfor %}",
- item="{{ item }}"
- )))
- assert env.get_template("main").render() == "123"
-
- def test_unoptimized_scopes(self):
- t = test_env.from_string("""
- {% macro outer(o) %}
- {% macro inner() %}
- {% include "o_printer" %}
- {% endmacro %}
- {{ inner() }}
- {% endmacro %}
- {{ outer("FOO") }}
- """)
- assert t.render().strip() == '(FOO)'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ImportsTestCase))
- suite.addTest(unittest.makeSuite(IncludesTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/inheritance.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/inheritance.py
deleted file mode 100755
index 355aa0c9..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/inheritance.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.inheritance
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Tests the template inheritance feature.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment, DictLoader
-
-
-LAYOUTTEMPLATE = '''\
-|{% block block1 %}block 1 from layout{% endblock %}
-|{% block block2 %}block 2 from layout{% endblock %}
-|{% block block3 %}
-{% block block4 %}nested block 4 from layout{% endblock %}
-{% endblock %}|'''
-
-LEVEL1TEMPLATE = '''\
-{% extends "layout" %}
-{% block block1 %}block 1 from level1{% endblock %}'''
-
-LEVEL2TEMPLATE = '''\
-{% extends "level1" %}
-{% block block2 %}{% block block5 %}nested block 5 from level2{%
-endblock %}{% endblock %}'''
-
-LEVEL3TEMPLATE = '''\
-{% extends "level2" %}
-{% block block5 %}block 5 from level3{% endblock %}
-{% block block4 %}block 4 from level3{% endblock %}
-'''
-
-LEVEL4TEMPLATE = '''\
-{% extends "level3" %}
-{% block block3 %}block 3 from level4{% endblock %}
-'''
-
-WORKINGTEMPLATE = '''\
-{% extends "layout" %}
-{% block block1 %}
- {% if false %}
- {% block block2 %}
- this should workd
- {% endblock %}
- {% endif %}
-{% endblock %}
-'''
-
-env = Environment(loader=DictLoader({
- 'layout': LAYOUTTEMPLATE,
- 'level1': LEVEL1TEMPLATE,
- 'level2': LEVEL2TEMPLATE,
- 'level3': LEVEL3TEMPLATE,
- 'level4': LEVEL4TEMPLATE,
- 'working': WORKINGTEMPLATE
-}), trim_blocks=True)
-
-
-class InheritanceTestCase(JinjaTestCase):
-
- def test_layout(self):
- tmpl = env.get_template('layout')
- assert tmpl.render() == ('|block 1 from layout|block 2 from '
- 'layout|nested block 4 from layout|')
-
- def test_level1(self):
- tmpl = env.get_template('level1')
- assert tmpl.render() == ('|block 1 from level1|block 2 from '
- 'layout|nested block 4 from layout|')
-
- def test_level2(self):
- tmpl = env.get_template('level2')
- assert tmpl.render() == ('|block 1 from level1|nested block 5 from '
- 'level2|nested block 4 from layout|')
-
- def test_level3(self):
- tmpl = env.get_template('level3')
- assert tmpl.render() == ('|block 1 from level1|block 5 from level3|'
- 'block 4 from level3|')
-
- def test_level4(sel):
- tmpl = env.get_template('level4')
- assert tmpl.render() == ('|block 1 from level1|block 5 from '
- 'level3|block 3 from level4|')
-
- def test_super(self):
- env = Environment(loader=DictLoader({
- 'a': '{% block intro %}INTRO{% endblock %}|'
- 'BEFORE|{% block data %}INNER{% endblock %}|AFTER',
- 'b': '{% extends "a" %}{% block data %}({{ '
- 'super() }}){% endblock %}',
- 'c': '{% extends "b" %}{% block intro %}--{{ '
- 'super() }}--{% endblock %}\n{% block data '
- '%}[{{ super() }}]{% endblock %}'
- }))
- tmpl = env.get_template('c')
- assert tmpl.render() == '--INTRO--|BEFORE|[(INNER)]|AFTER'
-
- def test_working(self):
- tmpl = env.get_template('working')
-
- def test_reuse_blocks(self):
- tmpl = env.from_string('{{ self.foo() }}|{% block foo %}42'
- '{% endblock %}|{{ self.foo() }}')
- assert tmpl.render() == '42|42|42'
-
- def test_preserve_blocks(self):
- env = Environment(loader=DictLoader({
- 'a': '{% if false %}{% block x %}A{% endblock %}{% endif %}{{ self.x() }}',
- 'b': '{% extends "a" %}{% block x %}B{{ super() }}{% endblock %}'
- }))
- tmpl = env.get_template('b')
- assert tmpl.render() == 'BA'
-
- def test_dynamic_inheritance(self):
- env = Environment(loader=DictLoader({
- 'master1': 'MASTER1{% block x %}{% endblock %}',
- 'master2': 'MASTER2{% block x %}{% endblock %}',
- 'child': '{% extends master %}{% block x %}CHILD{% endblock %}'
- }))
- tmpl = env.get_template('child')
- for m in range(1, 3):
- assert tmpl.render(master='master%d' % m) == 'MASTER%dCHILD' % m
-
- def test_multi_inheritance(self):
- env = Environment(loader=DictLoader({
- 'master1': 'MASTER1{% block x %}{% endblock %}',
- 'master2': 'MASTER2{% block x %}{% endblock %}',
- 'child': '''{% if master %}{% extends master %}{% else %}{% extends
- 'master1' %}{% endif %}{% block x %}CHILD{% endblock %}'''
- }))
- tmpl = env.get_template('child')
- assert tmpl.render(master='master2') == 'MASTER2CHILD'
- assert tmpl.render(master='master1') == 'MASTER1CHILD'
- assert tmpl.render() == 'MASTER1CHILD'
-
- def test_scoped_block(self):
- env = Environment(loader=DictLoader({
- 'master.html': '{% for item in seq %}[{% block item scoped %}'
- '{% endblock %}]{% endfor %}'
- }))
- t = env.from_string('{% extends "master.html" %}{% block item %}'
- '{{ item }}{% endblock %}')
- assert t.render(seq=range(5)) == '[0][1][2][3][4]'
-
- def test_super_in_scoped_block(self):
- env = Environment(loader=DictLoader({
- 'master.html': '{% for item in seq %}[{% block item scoped %}'
- '{{ item }}{% endblock %}]{% endfor %}'
- }))
- t = env.from_string('{% extends "master.html" %}{% block item %}'
- '{{ super() }}|{{ item * 2 }}{% endblock %}')
- assert t.render(seq=range(5)) == '[0|0][1|2][2|4][3|6][4|8]'
-
- def test_scoped_block_after_inheritance(self):
- env = Environment(loader=DictLoader({
- 'layout.html': '''
- {% block useless %}{% endblock %}
- ''',
- 'index.html': '''
- {%- extends 'layout.html' %}
- {% from 'helpers.html' import foo with context %}
- {% block useless %}
- {% for x in [1, 2, 3] %}
- {% block testing scoped %}
- {{ foo(x) }}
- {% endblock %}
- {% endfor %}
- {% endblock %}
- ''',
- 'helpers.html': '''
- {% macro foo(x) %}{{ the_foo + x }}{% endmacro %}
- '''
- }))
- rv = env.get_template('index.html').render(the_foo=42).split()
- assert rv == ['43', '44', '45']
-
-
-class BugFixTestCase(JinjaTestCase):
-
- def test_fixed_macro_scoping_bug(self):
- assert Environment(loader=DictLoader({
- 'test.html': '''\
- {% extends 'details.html' %}
-
- {% macro my_macro() %}
- my_macro
- {% endmacro %}
-
- {% block inner_box %}
- {{ my_macro() }}
- {% endblock %}
- ''',
- 'details.html': '''\
- {% extends 'standard.html' %}
-
- {% macro my_macro() %}
- my_macro
- {% endmacro %}
-
- {% block content %}
- {% block outer_box %}
- outer_box
- {% block inner_box %}
- inner_box
- {% endblock %}
- {% endblock %}
- {% endblock %}
- ''',
- 'standard.html': '''
- {% block content %}&nbsp;{% endblock %}
- '''
- })).get_template("test.html").render().split() == [u'outer_box', u'my_macro']
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(InheritanceTestCase))
- suite.addTest(unittest.makeSuite(BugFixTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/lexnparse.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/lexnparse.py
deleted file mode 100755
index 562df624..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/lexnparse.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.lexnparse
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- All the unittests regarding lexing, parsing and syntax.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import sys
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment, Template, TemplateSyntaxError, \
- UndefinedError, nodes
-
-env = Environment()
-
-
-# how does a string look like in jinja syntax?
-if sys.version_info < (3, 0):
- def jinja_string_repr(string):
- return repr(string)[1:]
-else:
- jinja_string_repr = repr
-
-
-class LexerTestCase(JinjaTestCase):
-
- def test_raw1(self):
- tmpl = env.from_string('{% raw %}foo{% endraw %}|'
- '{%raw%}{{ bar }}|{% baz %}{% endraw %}')
- assert tmpl.render() == 'foo|{{ bar }}|{% baz %}'
-
- def test_raw2(self):
- tmpl = env.from_string('1 {%- raw -%} 2 {%- endraw -%} 3')
- assert tmpl.render() == '123'
-
- def test_balancing(self):
- env = Environment('{%', '%}', '${', '}')
- tmpl = env.from_string('''{% for item in seq
- %}${{'foo': item}|upper}{% endfor %}''')
- assert tmpl.render(seq=range(3)) == "{'FOO': 0}{'FOO': 1}{'FOO': 2}"
-
- def test_comments(self):
- env = Environment('<!--', '-->', '{', '}')
- tmpl = env.from_string('''\
-<ul>
-<!--- for item in seq -->
- <li>{item}</li>
-<!--- endfor -->
-</ul>''')
- assert tmpl.render(seq=range(3)) == ("<ul>\n <li>0</li>\n "
- "<li>1</li>\n <li>2</li>\n</ul>")
-
- def test_string_escapes(self):
- for char in u'\0', u'\u2668', u'\xe4', u'\t', u'\r', u'\n':
- tmpl = env.from_string('{{ %s }}' % jinja_string_repr(char))
- assert tmpl.render() == char
- assert env.from_string('{{ "\N{HOT SPRINGS}" }}').render() == u'\u2668'
-
- def test_bytefallback(self):
- from pprint import pformat
- tmpl = env.from_string(u'''{{ 'foo'|pprint }}|{{ 'bär'|pprint }}''')
- assert tmpl.render() == pformat('foo') + '|' + pformat(u'bär')
-
- def test_operators(self):
- from jinja2.lexer import operators
- for test, expect in operators.iteritems():
- if test in '([{}])':
- continue
- stream = env.lexer.tokenize('{{ %s }}' % test)
- stream.next()
- assert stream.current.type == expect
-
- def test_normalizing(self):
- for seq in '\r', '\r\n', '\n':
- env = Environment(newline_sequence=seq)
- tmpl = env.from_string('1\n2\r\n3\n4\n')
- result = tmpl.render()
- assert result.replace(seq, 'X') == '1X2X3X4'
-
-
-class ParserTestCase(JinjaTestCase):
-
- def test_php_syntax(self):
- env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->')
- tmpl = env.from_string('''\
-<!-- I'm a comment, I'm not interesting -->\
-<? for item in seq -?>
- <?= item ?>
-<?- endfor ?>''')
- assert tmpl.render(seq=range(5)) == '01234'
-
- def test_erb_syntax(self):
- env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>')
- tmpl = env.from_string('''\
-<%# I'm a comment, I'm not interesting %>\
-<% for item in seq -%>
- <%= item %>
-<%- endfor %>''')
- assert tmpl.render(seq=range(5)) == '01234'
-
- def test_comment_syntax(self):
- env = Environment('<!--', '-->', '${', '}', '<!--#', '-->')
- tmpl = env.from_string('''\
-<!--# I'm a comment, I'm not interesting -->\
-<!-- for item in seq --->
- ${item}
-<!--- endfor -->''')
- assert tmpl.render(seq=range(5)) == '01234'
-
- def test_balancing(self):
- tmpl = env.from_string('''{{{'foo':'bar'}.foo}}''')
- assert tmpl.render() == 'bar'
-
- def test_start_comment(self):
- tmpl = env.from_string('''{# foo comment
-and bar comment #}
-{% macro blub() %}foo{% endmacro %}
-{{ blub() }}''')
- assert tmpl.render().strip() == 'foo'
-
- def test_line_syntax(self):
- env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%')
- tmpl = env.from_string('''\
-<%# regular comment %>
-% for item in seq:
- ${item}
-% endfor''')
- assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \
- range(5)
-
- env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##')
- tmpl = env.from_string('''\
-<%# regular comment %>
-% for item in seq:
- ${item} ## the rest of the stuff
-% endfor''')
- assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \
- range(5)
-
- def test_line_syntax_priority(self):
- # XXX: why is the whitespace there in front of the newline?
- env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#')
- tmpl = env.from_string('''\
-/* ignore me.
- I'm a multiline comment */
-## for item in seq:
-* ${item} # this is just extra stuff
-## endfor''')
- assert tmpl.render(seq=[1, 2]).strip() == '* 1\n* 2'
- env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##')
- tmpl = env.from_string('''\
-/* ignore me.
- I'm a multiline comment */
-# for item in seq:
-* ${item} ## this is just extra stuff
- ## extra stuff i just want to ignore
-# endfor''')
- assert tmpl.render(seq=[1, 2]).strip() == '* 1\n\n* 2'
-
- def test_error_messages(self):
- def assert_error(code, expected):
- try:
- Template(code)
- except TemplateSyntaxError, e:
- assert str(e) == expected, 'unexpected error message'
- else:
- assert False, 'that was suposed to be an error'
-
- assert_error('{% for item in seq %}...{% endif %}',
- "Encountered unknown tag 'endif'. Jinja was looking "
- "for the following tags: 'endfor' or 'else'. The "
- "innermost block that needs to be closed is 'for'.")
- assert_error('{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}',
- "Encountered unknown tag 'endfor'. Jinja was looking for "
- "the following tags: 'elif' or 'else' or 'endif'. The "
- "innermost block that needs to be closed is 'if'.")
- assert_error('{% if foo %}',
- "Unexpected end of template. Jinja was looking for the "
- "following tags: 'elif' or 'else' or 'endif'. The "
- "innermost block that needs to be closed is 'if'.")
- assert_error('{% for item in seq %}',
- "Unexpected end of template. Jinja was looking for the "
- "following tags: 'endfor' or 'else'. The innermost block "
- "that needs to be closed is 'for'.")
- assert_error('{% block foo-bar-baz %}',
- "Block names in Jinja have to be valid Python identifiers "
- "and may not contain hypens, use an underscore instead.")
- assert_error('{% unknown_tag %}',
- "Encountered unknown tag 'unknown_tag'.")
-
-
-class SyntaxTestCase(JinjaTestCase):
-
- def test_call(self):
- env = Environment()
- env.globals['foo'] = lambda a, b, c, e, g: a + b + c + e + g
- tmpl = env.from_string("{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}")
- assert tmpl.render() == 'abdfh'
-
- def test_slicing(self):
- tmpl = env.from_string('{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}')
- assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
-
- def test_attr(self):
- tmpl = env.from_string("{{ foo.bar }}|{{ foo['bar'] }}")
- assert tmpl.render(foo={'bar': 42}) == '42|42'
-
- def test_subscript(self):
- tmpl = env.from_string("{{ foo[0] }}|{{ foo[-1] }}")
- assert tmpl.render(foo=[0, 1, 2]) == '0|2'
-
- def test_tuple(self):
- tmpl = env.from_string('{{ () }}|{{ (1,) }}|{{ (1, 2) }}')
- assert tmpl.render() == '()|(1,)|(1, 2)'
-
- def test_math(self):
- tmpl = env.from_string('{{ (1 + 1 * 2) - 3 / 2 }}|{{ 2**3 }}')
- assert tmpl.render() == '1.5|8'
-
- def test_div(self):
- tmpl = env.from_string('{{ 3 // 2 }}|{{ 3 / 2 }}|{{ 3 % 2 }}')
- assert tmpl.render() == '1|1.5|1'
-
- def test_unary(self):
- tmpl = env.from_string('{{ +3 }}|{{ -3 }}')
- assert tmpl.render() == '3|-3'
-
- def test_concat(self):
- tmpl = env.from_string("{{ [1, 2] ~ 'foo' }}")
- assert tmpl.render() == '[1, 2]foo'
-
- def test_compare(self):
- tmpl = env.from_string('{{ 1 > 0 }}|{{ 1 >= 1 }}|{{ 2 < 3 }}|'
- '{{ 2 == 2 }}|{{ 1 <= 1 }}')
- assert tmpl.render() == 'True|True|True|True|True'
-
- def test_inop(self):
- tmpl = env.from_string('{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}')
- assert tmpl.render() == 'True|False'
-
- def test_literals(self):
- tmpl = env.from_string('{{ [] }}|{{ {} }}|{{ () }}')
- assert tmpl.render().lower() == '[]|{}|()'
-
- def test_bool(self):
- tmpl = env.from_string('{{ true and false }}|{{ false '
- 'or true }}|{{ not false }}')
- assert tmpl.render() == 'False|True|True'
-
- def test_grouping(self):
- tmpl = env.from_string('{{ (true and false) or (false and true) and not false }}')
- assert tmpl.render() == 'False'
-
- def test_django_attr(self):
- tmpl = env.from_string('{{ [1, 2, 3].0 }}|{{ [[1]].0.0 }}')
- assert tmpl.render() == '1|1'
-
- def test_conditional_expression(self):
- tmpl = env.from_string('''{{ 0 if true else 1 }}''')
- assert tmpl.render() == '0'
-
- def test_short_conditional_expression(self):
- tmpl = env.from_string('<{{ 1 if false }}>')
- assert tmpl.render() == '<>'
-
- tmpl = env.from_string('<{{ (1 if false).bar }}>')
- self.assert_raises(UndefinedError, tmpl.render)
-
- def test_filter_priority(self):
- tmpl = env.from_string('{{ "foo"|upper + "bar"|upper }}')
- assert tmpl.render() == 'FOOBAR'
-
- def test_function_calls(self):
- tests = [
- (True, '*foo, bar'),
- (True, '*foo, *bar'),
- (True, '*foo, bar=42'),
- (True, '**foo, *bar'),
- (True, '**foo, bar'),
- (False, 'foo, bar'),
- (False, 'foo, bar=42'),
- (False, 'foo, bar=23, *args'),
- (False, 'a, b=c, *d, **e'),
- (False, '*foo, **bar')
- ]
- for should_fail, sig in tests:
- if should_fail:
- self.assert_raises(TemplateSyntaxError,
- env.from_string, '{{ foo(%s) }}' % sig)
- else:
- env.from_string('foo(%s)' % sig)
-
- def test_tuple_expr(self):
- for tmpl in [
- '{{ () }}',
- '{{ (1, 2) }}',
- '{{ (1, 2,) }}',
- '{{ 1, }}',
- '{{ 1, 2 }}',
- '{% for foo, bar in seq %}...{% endfor %}',
- '{% for x in foo, bar %}...{% endfor %}',
- '{% for x in foo, %}...{% endfor %}'
- ]:
- assert env.from_string(tmpl)
-
- def test_trailing_comma(self):
- tmpl = env.from_string('{{ (1, 2,) }}|{{ [1, 2,] }}|{{ {1: 2,} }}')
- assert tmpl.render().lower() == '(1, 2)|[1, 2]|{1: 2}'
-
- def test_block_end_name(self):
- env.from_string('{% block foo %}...{% endblock foo %}')
- self.assert_raises(TemplateSyntaxError, env.from_string,
- '{% block x %}{% endblock y %}')
-
- def test_contant_casing(self):
- for const in True, False, None:
- tmpl = env.from_string('{{ %s }}|{{ %s }}|{{ %s }}' % (
- str(const), str(const).lower(), str(const).upper()
- ))
- assert tmpl.render() == '%s|%s|' % (const, const)
-
- def test_test_chaining(self):
- self.assert_raises(TemplateSyntaxError, env.from_string,
- '{{ foo is string is sequence }}')
- env.from_string('{{ 42 is string or 42 is number }}'
- ).render() == 'True'
-
- def test_string_concatenation(self):
- tmpl = env.from_string('{{ "foo" "bar" "baz" }}')
- assert tmpl.render() == 'foobarbaz'
-
- def test_notin(self):
- bar = xrange(100)
- tmpl = env.from_string('''{{ not 42 in bar }}''')
- assert tmpl.render(bar=bar) == unicode(not 42 in bar)
-
- def test_implicit_subscribed_tuple(self):
- class Foo(object):
- def __getitem__(self, x):
- return x
- t = env.from_string('{{ foo[1, 2] }}')
- assert t.render(foo=Foo()) == u'(1, 2)'
-
- def test_raw2(self):
- tmpl = env.from_string('{% raw %}{{ FOO }} and {% BAR %}{% endraw %}')
- assert tmpl.render() == '{{ FOO }} and {% BAR %}'
-
- def test_const(self):
- tmpl = env.from_string('{{ true }}|{{ false }}|{{ none }}|'
- '{{ none is defined }}|{{ missing is defined }}')
- assert tmpl.render() == 'True|False|None|True|False'
-
- def test_neg_filter_priority(self):
- node = env.parse('{{ -1|foo }}')
- assert isinstance(node.body[0].nodes[0], nodes.Filter)
- assert isinstance(node.body[0].nodes[0].node, nodes.Neg)
-
- def test_const_assign(self):
- constass1 = '''{% set true = 42 %}'''
- constass2 = '''{% for none in seq %}{% endfor %}'''
- for tmpl in constass1, constass2:
- self.assert_raises(TemplateSyntaxError, env.from_string, tmpl)
-
- def test_localset(self):
- tmpl = env.from_string('''{% set foo = 0 %}\
-{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}\
-{{ foo }}''')
- assert tmpl.render() == '0'
-
- def test_parse_unary(self):
- tmpl = env.from_string('{{ -foo["bar"] }}')
- assert tmpl.render(foo={'bar': 42}) == '-42'
- tmpl = env.from_string('{{ -foo["bar"]|abs }}')
- assert tmpl.render(foo={'bar': 42}) == '42'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(LexerTestCase))
- suite.addTest(unittest.makeSuite(ParserTestCase))
- suite.addTest(unittest.makeSuite(SyntaxTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/loader.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/loader.py
deleted file mode 100755
index fb1e53d4..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/loader.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.loader
- ~~~~~~~~~~~~~~~~~~~~~~~
-
- Test the loaders.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import os
-import sys
-import tempfile
-import shutil
-import unittest
-
-from jinja2.testsuite import JinjaTestCase, dict_loader, \
- package_loader, filesystem_loader, function_loader, \
- choice_loader, prefix_loader
-
-from jinja2 import Environment, loaders
-from jinja2.loaders import split_template_path
-from jinja2.exceptions import TemplateNotFound
-
-
-class LoaderTestCase(JinjaTestCase):
-
- def test_dict_loader(self):
- env = Environment(loader=dict_loader)
- tmpl = env.get_template('justdict.html')
- assert tmpl.render().strip() == 'FOO'
- self.assert_raises(TemplateNotFound, env.get_template, 'missing.html')
-
- def test_package_loader(self):
- env = Environment(loader=package_loader)
- tmpl = env.get_template('test.html')
- assert tmpl.render().strip() == 'BAR'
- self.assert_raises(TemplateNotFound, env.get_template, 'missing.html')
-
- def test_filesystem_loader(self):
- env = Environment(loader=filesystem_loader)
- tmpl = env.get_template('test.html')
- assert tmpl.render().strip() == 'BAR'
- tmpl = env.get_template('foo/test.html')
- assert tmpl.render().strip() == 'FOO'
- self.assert_raises(TemplateNotFound, env.get_template, 'missing.html')
-
- def test_choice_loader(self):
- env = Environment(loader=choice_loader)
- tmpl = env.get_template('justdict.html')
- assert tmpl.render().strip() == 'FOO'
- tmpl = env.get_template('test.html')
- assert tmpl.render().strip() == 'BAR'
- self.assert_raises(TemplateNotFound, env.get_template, 'missing.html')
-
- def test_function_loader(self):
- env = Environment(loader=function_loader)
- tmpl = env.get_template('justfunction.html')
- assert tmpl.render().strip() == 'FOO'
- self.assert_raises(TemplateNotFound, env.get_template, 'missing.html')
-
- def test_prefix_loader(self):
- env = Environment(loader=prefix_loader)
- tmpl = env.get_template('a/test.html')
- assert tmpl.render().strip() == 'BAR'
- tmpl = env.get_template('b/justdict.html')
- assert tmpl.render().strip() == 'FOO'
- self.assert_raises(TemplateNotFound, env.get_template, 'missing')
-
- def test_caching(self):
- changed = False
- class TestLoader(loaders.BaseLoader):
- def get_source(self, environment, template):
- return u'foo', None, lambda: not changed
- env = Environment(loader=TestLoader(), cache_size=-1)
- tmpl = env.get_template('template')
- assert tmpl is env.get_template('template')
- changed = True
- assert tmpl is not env.get_template('template')
- changed = False
-
- env = Environment(loader=TestLoader(), cache_size=0)
- assert env.get_template('template') \
- is not env.get_template('template')
-
- env = Environment(loader=TestLoader(), cache_size=2)
- t1 = env.get_template('one')
- t2 = env.get_template('two')
- assert t2 is env.get_template('two')
- assert t1 is env.get_template('one')
- t3 = env.get_template('three')
- assert 'one' in env.cache
- assert 'two' not in env.cache
- assert 'three' in env.cache
-
- def test_split_template_path(self):
- assert split_template_path('foo/bar') == ['foo', 'bar']
- assert split_template_path('./foo/bar') == ['foo', 'bar']
- self.assert_raises(TemplateNotFound, split_template_path, '../foo')
-
-
-class ModuleLoaderTestCase(JinjaTestCase):
- archive = None
-
- def compile_down(self, zip='deflated', py_compile=False):
- super(ModuleLoaderTestCase, self).setup()
- log = []
- self.reg_env = Environment(loader=prefix_loader)
- if zip is not None:
- self.archive = tempfile.mkstemp(suffix='.zip')[1]
- else:
- self.archive = tempfile.mkdtemp()
- self.reg_env.compile_templates(self.archive, zip=zip,
- log_function=log.append,
- py_compile=py_compile)
- self.mod_env = Environment(loader=loaders.ModuleLoader(self.archive))
- return ''.join(log)
-
- def teardown(self):
- super(ModuleLoaderTestCase, self).teardown()
- if hasattr(self, 'mod_env'):
- if os.path.isfile(self.archive):
- os.remove(self.archive)
- else:
- shutil.rmtree(self.archive)
- self.archive = None
-
- def test_log(self):
- log = self.compile_down()
- assert 'Compiled "a/foo/test.html" as ' \
- 'tmpl_a790caf9d669e39ea4d280d597ec891c4ef0404a' in log
- assert 'Finished compiling templates' in log
- assert 'Could not compile "a/syntaxerror.html": ' \
- 'Encountered unknown tag \'endif\'' in log
-
- def _test_common(self):
- tmpl1 = self.reg_env.get_template('a/test.html')
- tmpl2 = self.mod_env.get_template('a/test.html')
- assert tmpl1.render() == tmpl2.render()
-
- tmpl1 = self.reg_env.get_template('b/justdict.html')
- tmpl2 = self.mod_env.get_template('b/justdict.html')
- assert tmpl1.render() == tmpl2.render()
-
- def test_deflated_zip_compile(self):
- self.compile_down(zip='deflated')
- self._test_common()
-
- def test_stored_zip_compile(self):
- self.compile_down(zip='stored')
- self._test_common()
-
- def test_filesystem_compile(self):
- self.compile_down(zip=None)
- self._test_common()
-
- def test_weak_references(self):
- self.compile_down()
- tmpl = self.mod_env.get_template('a/test.html')
- key = loaders.ModuleLoader.get_template_key('a/test.html')
- name = self.mod_env.loader.module.__name__
-
- assert hasattr(self.mod_env.loader.module, key)
- assert name in sys.modules
-
- # unset all, ensure the module is gone from sys.modules
- self.mod_env = tmpl = None
-
- try:
- import gc
- gc.collect()
- except:
- pass
-
- assert name not in sys.modules
-
- def test_byte_compilation(self):
- log = self.compile_down(py_compile=True)
- assert 'Byte-compiled "a/test.html"' in log
- tmpl1 = self.mod_env.get_template('a/test.html')
- mod = self.mod_env.loader.module. \
- tmpl_3c4ddf650c1a73df961a6d3d2ce2752f1b8fd490
- assert mod.__file__.endswith('.pyc')
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(LoaderTestCase))
- suite.addTest(unittest.makeSuite(ModuleLoaderTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/regression.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/regression.py
deleted file mode 100755
index 4db90769..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/regression.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.regression
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Tests corner cases and bugs.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Template, Environment, DictLoader, TemplateSyntaxError, \
- TemplateNotFound, PrefixLoader
-
-env = Environment()
-
-
-class CornerTestCase(JinjaTestCase):
-
- def test_assigned_scoping(self):
- t = env.from_string('''
- {%- for item in (1, 2, 3, 4) -%}
- [{{ item }}]
- {%- endfor %}
- {{- item -}}
- ''')
- assert t.render(item=42) == '[1][2][3][4]42'
-
- t = env.from_string('''
- {%- for item in (1, 2, 3, 4) -%}
- [{{ item }}]
- {%- endfor %}
- {%- set item = 42 %}
- {{- item -}}
- ''')
- assert t.render() == '[1][2][3][4]42'
-
- t = env.from_string('''
- {%- set item = 42 %}
- {%- for item in (1, 2, 3, 4) -%}
- [{{ item }}]
- {%- endfor %}
- {{- item -}}
- ''')
- assert t.render() == '[1][2][3][4]42'
-
- def test_closure_scoping(self):
- t = env.from_string('''
- {%- set wrapper = "<FOO>" %}
- {%- for item in (1, 2, 3, 4) %}
- {%- macro wrapper() %}[{{ item }}]{% endmacro %}
- {{- wrapper() }}
- {%- endfor %}
- {{- wrapper -}}
- ''')
- assert t.render() == '[1][2][3][4]<FOO>'
-
- t = env.from_string('''
- {%- for item in (1, 2, 3, 4) %}
- {%- macro wrapper() %}[{{ item }}]{% endmacro %}
- {{- wrapper() }}
- {%- endfor %}
- {%- set wrapper = "<FOO>" %}
- {{- wrapper -}}
- ''')
- assert t.render() == '[1][2][3][4]<FOO>'
-
- t = env.from_string('''
- {%- for item in (1, 2, 3, 4) %}
- {%- macro wrapper() %}[{{ item }}]{% endmacro %}
- {{- wrapper() }}
- {%- endfor %}
- {{- wrapper -}}
- ''')
- assert t.render(wrapper=23) == '[1][2][3][4]23'
-
-
-class BugTestCase(JinjaTestCase):
-
- def test_keyword_folding(self):
- env = Environment()
- env.filters['testing'] = lambda value, some: value + some
- assert env.from_string("{{ 'test'|testing(some='stuff') }}") \
- .render() == 'teststuff'
-
- def test_extends_output_bugs(self):
- env = Environment(loader=DictLoader({
- 'parent.html': '(({% block title %}{% endblock %}))'
- }))
-
- t = env.from_string('{% if expr %}{% extends "parent.html" %}{% endif %}'
- '[[{% block title %}title{% endblock %}]]'
- '{% for item in [1, 2, 3] %}({{ item }}){% endfor %}')
- assert t.render(expr=False) == '[[title]](1)(2)(3)'
- assert t.render(expr=True) == '((title))'
-
- def test_urlize_filter_escaping(self):
- tmpl = env.from_string('{{ "http://www.example.org/<foo"|urlize }}')
- assert tmpl.render() == '<a href="http://www.example.org/&lt;foo">http://www.example.org/&lt;foo</a>'
-
- def test_loop_call_loop(self):
- tmpl = env.from_string('''
-
- {% macro test() %}
- {{ caller() }}
- {% endmacro %}
-
- {% for num1 in range(5) %}
- {% call test() %}
- {% for num2 in range(10) %}
- {{ loop.index }}
- {% endfor %}
- {% endcall %}
- {% endfor %}
-
- ''')
-
- assert tmpl.render().split() == map(unicode, range(1, 11)) * 5
-
- def test_weird_inline_comment(self):
- env = Environment(line_statement_prefix='%')
- self.assert_raises(TemplateSyntaxError, env.from_string,
- '% for item in seq {# missing #}\n...% endfor')
-
- def test_old_macro_loop_scoping_bug(self):
- tmpl = env.from_string('{% for i in (1, 2) %}{{ i }}{% endfor %}'
- '{% macro i() %}3{% endmacro %}{{ i() }}')
- assert tmpl.render() == '123'
-
- def test_partial_conditional_assignments(self):
- tmpl = env.from_string('{% if b %}{% set a = 42 %}{% endif %}{{ a }}')
- assert tmpl.render(a=23) == '23'
- assert tmpl.render(b=True) == '42'
-
- def test_stacked_locals_scoping_bug(self):
- env = Environment(line_statement_prefix='#')
- t = env.from_string('''\
-# for j in [1, 2]:
-# set x = 1
-# for i in [1, 2]:
-# print x
-# if i % 2 == 0:
-# set x = x + 1
-# endif
-# endfor
-# endfor
-# if a
-# print 'A'
-# elif b
-# print 'B'
-# elif c == d
-# print 'C'
-# else
-# print 'D'
-# endif
- ''')
- assert t.render(a=0, b=False, c=42, d=42.0) == '1111C'
-
- def test_stacked_locals_scoping_bug_twoframe(self):
- t = Template('''
- {% set x = 1 %}
- {% for item in foo %}
- {% if item == 1 %}
- {% set x = 2 %}
- {% endif %}
- {% endfor %}
- {{ x }}
- ''')
- rv = t.render(foo=[1]).strip()
- assert rv == u'1'
-
- def test_call_with_args(self):
- t = Template("""{% macro dump_users(users) -%}
- <ul>
- {%- for user in users -%}
- <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
- {%- endfor -%}
- </ul>
- {%- endmacro -%}
-
- {% call(user) dump_users(list_of_user) -%}
- <dl>
- <dl>Realname</dl>
- <dd>{{ user.realname|e }}</dd>
- <dl>Description</dl>
- <dd>{{ user.description }}</dd>
- </dl>
- {% endcall %}""")
-
- assert [x.strip() for x in t.render(list_of_user=[{
- 'username':'apo',
- 'realname':'something else',
- 'description':'test'
- }]).splitlines()] == [
- u'<ul><li><p>apo</p><dl>',
- u'<dl>Realname</dl>',
- u'<dd>something else</dd>',
- u'<dl>Description</dl>',
- u'<dd>test</dd>',
- u'</dl>',
- u'</li></ul>'
- ]
-
- def test_empty_if_condition_fails(self):
- self.assert_raises(TemplateSyntaxError, Template, '{% if %}....{% endif %}')
- self.assert_raises(TemplateSyntaxError, Template, '{% if foo %}...{% elif %}...{% endif %}')
- self.assert_raises(TemplateSyntaxError, Template, '{% for x in %}..{% endfor %}')
-
- def test_recursive_loop_bug(self):
- tpl1 = Template("""
- {% for p in foo recursive%}
- {{p.bar}}
- {% for f in p.fields recursive%}
- {{f.baz}}
- {{p.bar}}
- {% if f.rec %}
- {{ loop(f.sub) }}
- {% endif %}
- {% endfor %}
- {% endfor %}
- """)
-
- tpl2 = Template("""
- {% for p in foo%}
- {{p.bar}}
- {% for f in p.fields recursive%}
- {{f.baz}}
- {{p.bar}}
- {% if f.rec %}
- {{ loop(f.sub) }}
- {% endif %}
- {% endfor %}
- {% endfor %}
- """)
-
- def test_correct_prefix_loader_name(self):
- env = Environment(loader=PrefixLoader({
- 'foo': DictLoader({})
- }))
- try:
- env.get_template('foo/bar.html')
- except TemplateNotFound, e:
- assert e.name == 'foo/bar.html'
- else:
- assert False, 'expected error here'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(CornerTestCase))
- suite.addTest(unittest.makeSuite(BugTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/__init__.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/broken.html b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/broken.html
deleted file mode 100644
index 77669fae..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/broken.html
+++ /dev/null
@@ -1,3 +0,0 @@
-Before
-{{ fail() }}
-After
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/foo/test.html b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/foo/test.html
deleted file mode 100644
index b7d6715e..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/foo/test.html
+++ /dev/null
@@ -1 +0,0 @@
-FOO
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/syntaxerror.html b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/syntaxerror.html
deleted file mode 100644
index f21b8179..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/syntaxerror.html
+++ /dev/null
@@ -1,4 +0,0 @@
-Foo
-{% for item in broken %}
- ...
-{% endif %}
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/test.html b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/test.html
deleted file mode 100644
index ba578e48..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/res/templates/test.html
+++ /dev/null
@@ -1 +0,0 @@
-BAR
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/security.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/security.py
deleted file mode 100755
index 4518eac6..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/security.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.security
- ~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Checks the sandbox and other security features.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Environment
-from jinja2.sandbox import SandboxedEnvironment, \
- ImmutableSandboxedEnvironment, unsafe
-from jinja2 import Markup, escape
-from jinja2.exceptions import SecurityError, TemplateSyntaxError, \
- TemplateRuntimeError
-
-
-class PrivateStuff(object):
-
- def bar(self):
- return 23
-
- @unsafe
- def foo(self):
- return 42
-
- def __repr__(self):
- return 'PrivateStuff'
-
-
-class PublicStuff(object):
- bar = lambda self: 23
- _foo = lambda self: 42
-
- def __repr__(self):
- return 'PublicStuff'
-
-
-class SandboxTestCase(JinjaTestCase):
-
- def test_unsafe(self):
- env = SandboxedEnvironment()
- self.assert_raises(SecurityError, env.from_string("{{ foo.foo() }}").render,
- foo=PrivateStuff())
- self.assert_equal(env.from_string("{{ foo.bar() }}").render(foo=PrivateStuff()), '23')
-
- self.assert_raises(SecurityError, env.from_string("{{ foo._foo() }}").render,
- foo=PublicStuff())
- self.assert_equal(env.from_string("{{ foo.bar() }}").render(foo=PublicStuff()), '23')
- self.assert_equal(env.from_string("{{ foo.__class__ }}").render(foo=42), '')
- self.assert_equal(env.from_string("{{ foo.func_code }}").render(foo=lambda:None), '')
- # security error comes from __class__ already.
- self.assert_raises(SecurityError, env.from_string(
- "{{ foo.__class__.__subclasses__() }}").render, foo=42)
-
- def test_immutable_environment(self):
- env = ImmutableSandboxedEnvironment()
- self.assert_raises(SecurityError, env.from_string(
- '{{ [].append(23) }}').render)
- self.assert_raises(SecurityError, env.from_string(
- '{{ {1:2}.clear() }}').render)
-
- def test_restricted(self):
- env = SandboxedEnvironment()
- self.assert_raises(TemplateSyntaxError, env.from_string,
- "{% for item.attribute in seq %}...{% endfor %}")
- self.assert_raises(TemplateSyntaxError, env.from_string,
- "{% for foo, bar.baz in seq %}...{% endfor %}")
-
- def test_markup_operations(self):
- # adding two strings should escape the unsafe one
- unsafe = '<script type="application/x-some-script">alert("foo");</script>'
- safe = Markup('<em>username</em>')
- assert unsafe + safe == unicode(escape(unsafe)) + unicode(safe)
-
- # string interpolations are safe to use too
- assert Markup('<em>%s</em>') % '<bad user>' == \
- '<em>&lt;bad user&gt;</em>'
- assert Markup('<em>%(username)s</em>') % {
- 'username': '<bad user>'
- } == '<em>&lt;bad user&gt;</em>'
-
- # an escaped object is markup too
- assert type(Markup('foo') + 'bar') is Markup
-
- # and it implements __html__ by returning itself
- x = Markup("foo")
- assert x.__html__() is x
-
- # it also knows how to treat __html__ objects
- class Foo(object):
- def __html__(self):
- return '<em>awesome</em>'
- def __unicode__(self):
- return 'awesome'
- assert Markup(Foo()) == '<em>awesome</em>'
- assert Markup('<strong>%s</strong>') % Foo() == \
- '<strong><em>awesome</em></strong>'
-
- # escaping and unescaping
- assert escape('"<>&\'') == '&#34;&lt;&gt;&amp;&#39;'
- assert Markup("<em>Foo &amp; Bar</em>").striptags() == "Foo & Bar"
- assert Markup("&lt;test&gt;").unescape() == "<test>"
-
- def test_template_data(self):
- env = Environment(autoescape=True)
- t = env.from_string('{% macro say_hello(name) %}'
- '<p>Hello {{ name }}!</p>{% endmacro %}'
- '{{ say_hello("<blink>foo</blink>") }}')
- escaped_out = '<p>Hello &lt;blink&gt;foo&lt;/blink&gt;!</p>'
- assert t.render() == escaped_out
- assert unicode(t.module) == escaped_out
- assert escape(t.module) == escaped_out
- assert t.module.say_hello('<blink>foo</blink>') == escaped_out
- assert escape(t.module.say_hello('<blink>foo</blink>')) == escaped_out
-
- def test_attr_filter(self):
- env = SandboxedEnvironment()
- tmpl = env.from_string('{{ cls|attr("__subclasses__")() }}')
- self.assert_raises(SecurityError, tmpl.render, cls=int)
-
- def test_binary_operator_intercepting(self):
- def disable_op(left, right):
- raise TemplateRuntimeError('that operator so does not work')
- for expr, ctx, rv in ('1 + 2', {}, '3'), ('a + 2', {'a': 2}, '4'):
- env = SandboxedEnvironment()
- env.binop_table['+'] = disable_op
- t = env.from_string('{{ %s }}' % expr)
- assert t.render(ctx) == rv
- env.intercepted_binops = frozenset(['+'])
- t = env.from_string('{{ %s }}' % expr)
- try:
- t.render(ctx)
- except TemplateRuntimeError, e:
- pass
- else:
- self.fail('expected runtime error')
-
- def test_unary_operator_intercepting(self):
- def disable_op(arg):
- raise TemplateRuntimeError('that operator so does not work')
- for expr, ctx, rv in ('-1', {}, '-1'), ('-a', {'a': 2}, '-2'):
- env = SandboxedEnvironment()
- env.unop_table['-'] = disable_op
- t = env.from_string('{{ %s }}' % expr)
- assert t.render(ctx) == rv
- env.intercepted_unops = frozenset(['-'])
- t = env.from_string('{{ %s }}' % expr)
- try:
- t.render(ctx)
- except TemplateRuntimeError, e:
- pass
- else:
- self.fail('expected runtime error')
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(SandboxTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/tests.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/tests.py
deleted file mode 100755
index 3ece7a8f..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/tests.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.tests
- ~~~~~~~~~~~~~~~~~~~~~~
-
- Who tests the tests?
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import unittest
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2 import Markup, Environment
-
-env = Environment()
-
-
-class TestsTestCase(JinjaTestCase):
-
- def test_defined(self):
- tmpl = env.from_string('{{ missing is defined }}|{{ true is defined }}')
- assert tmpl.render() == 'False|True'
-
- def test_even(self):
- tmpl = env.from_string('''{{ 1 is even }}|{{ 2 is even }}''')
- assert tmpl.render() == 'False|True'
-
- def test_odd(self):
- tmpl = env.from_string('''{{ 1 is odd }}|{{ 2 is odd }}''')
- assert tmpl.render() == 'True|False'
-
- def test_lower(self):
- tmpl = env.from_string('''{{ "foo" is lower }}|{{ "FOO" is lower }}''')
- assert tmpl.render() == 'True|False'
-
- def test_typechecks(self):
- tmpl = env.from_string('''
- {{ 42 is undefined }}
- {{ 42 is defined }}
- {{ 42 is none }}
- {{ none is none }}
- {{ 42 is number }}
- {{ 42 is string }}
- {{ "foo" is string }}
- {{ "foo" is sequence }}
- {{ [1] is sequence }}
- {{ range is callable }}
- {{ 42 is callable }}
- {{ range(5) is iterable }}
- {{ {} is mapping }}
- {{ mydict is mapping }}
- {{ [] is mapping }}
- ''')
- class MyDict(dict):
- pass
- assert tmpl.render(mydict=MyDict()).split() == [
- 'False', 'True', 'False', 'True', 'True', 'False',
- 'True', 'True', 'True', 'True', 'False', 'True',
- 'True', 'True', 'False'
- ]
-
- def test_sequence(self):
- tmpl = env.from_string(
- '{{ [1, 2, 3] is sequence }}|'
- '{{ "foo" is sequence }}|'
- '{{ 42 is sequence }}'
- )
- assert tmpl.render() == 'True|True|False'
-
- def test_upper(self):
- tmpl = env.from_string('{{ "FOO" is upper }}|{{ "foo" is upper }}')
- assert tmpl.render() == 'True|False'
-
- def test_sameas(self):
- tmpl = env.from_string('{{ foo is sameas false }}|'
- '{{ 0 is sameas false }}')
- assert tmpl.render(foo=False) == 'True|False'
-
- def test_no_paren_for_arg1(self):
- tmpl = env.from_string('{{ foo is sameas none }}')
- assert tmpl.render(foo=None) == 'True'
-
- def test_escaped(self):
- env = Environment(autoescape=True)
- tmpl = env.from_string('{{ x is escaped }}|{{ y is escaped }}')
- assert tmpl.render(x='foo', y=Markup('foo')) == 'False|True'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestsTestCase))
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/utils.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/utils.py
deleted file mode 100755
index be2e902f..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/testsuite/utils.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.testsuite.utils
- ~~~~~~~~~~~~~~~~~~~~~~
-
- Tests utilities jinja uses.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import gc
-import unittest
-
-import pickle
-
-from jinja2.testsuite import JinjaTestCase
-
-from jinja2.utils import LRUCache, escape, object_type_repr
-
-
-class LRUCacheTestCase(JinjaTestCase):
-
- def test_simple(self):
- d = LRUCache(3)
- d["a"] = 1
- d["b"] = 2
- d["c"] = 3
- d["a"]
- d["d"] = 4
- assert len(d) == 3
- assert 'a' in d and 'c' in d and 'd' in d and 'b' not in d
-
- def test_pickleable(self):
- cache = LRUCache(2)
- cache["foo"] = 42
- cache["bar"] = 23
- cache["foo"]
-
- for protocol in range(3):
- copy = pickle.loads(pickle.dumps(cache, protocol))
- assert copy.capacity == cache.capacity
- assert copy._mapping == cache._mapping
- assert copy._queue == cache._queue
-
-
-class HelpersTestCase(JinjaTestCase):
-
- def test_object_type_repr(self):
- class X(object):
- pass
- self.assert_equal(object_type_repr(42), 'int object')
- self.assert_equal(object_type_repr([]), 'list object')
- self.assert_equal(object_type_repr(X()),
- 'jinja2.testsuite.utils.X object')
- self.assert_equal(object_type_repr(None), 'None')
- self.assert_equal(object_type_repr(Ellipsis), 'Ellipsis')
-
-
-class MarkupLeakTestCase(JinjaTestCase):
-
- def test_markup_leaks(self):
- counts = set()
- for count in xrange(20):
- for item in xrange(1000):
- escape("foo")
- escape("<foo>")
- escape(u"foo")
- escape(u"<foo>")
- counts.add(len(gc.get_objects()))
- assert len(counts) == 1, 'ouch, c extension seems to leak objects'
-
-
-def suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(LRUCacheTestCase))
- suite.addTest(unittest.makeSuite(HelpersTestCase))
-
- # this test only tests the c extension
- if not hasattr(escape, 'func_code'):
- suite.addTest(unittest.makeSuite(MarkupLeakTestCase))
-
- return suite
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/utils.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/utils.py
deleted file mode 100755
index 49e9e9ae..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/utils.py
+++ /dev/null
@@ -1,601 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.utils
- ~~~~~~~~~~~~
-
- Utility functions.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-import re
-import sys
-import errno
-try:
- from thread import allocate_lock
-except ImportError:
- from dummy_thread import allocate_lock
-from collections import deque
-from itertools import imap
-
-
-_word_split_re = re.compile(r'(\s+)')
-_punctuation_re = re.compile(
- '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % (
- '|'.join(imap(re.escape, ('(', '<', '&lt;'))),
- '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '&gt;')))
- )
-)
-_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
-_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
-_entity_re = re.compile(r'&([^;]+);')
-_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
-_digits = '0123456789'
-
-# special singleton representing missing values for the runtime
-missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
-
-# internal code
-internal_code = set()
-
-
-# concatenate a list of strings and convert them to unicode.
-# unfortunately there is a bug in python 2.4 and lower that causes
-# unicode.join trash the traceback.
-_concat = u''.join
-try:
- def _test_gen_bug():
- raise TypeError(_test_gen_bug)
- yield None
- _concat(_test_gen_bug())
-except TypeError, _error:
- if not _error.args or _error.args[0] is not _test_gen_bug:
- def concat(gen):
- try:
- return _concat(list(gen))
- except Exception:
- # this hack is needed so that the current frame
- # does not show up in the traceback.
- exc_type, exc_value, tb = sys.exc_info()
- raise exc_type, exc_value, tb.tb_next
- else:
- concat = _concat
- del _test_gen_bug, _error
-
-
-# for python 2.x we create outselves a next() function that does the
-# basics without exception catching.
-try:
- next = next
-except NameError:
- def next(x):
- return x.next()
-
-
-# if this python version is unable to deal with unicode filenames
-# when passed to encode we let this function encode it properly.
-# This is used in a couple of places. As far as Jinja is concerned
-# filenames are unicode *or* bytestrings in 2.x and unicode only in
-# 3.x because compile cannot handle bytes
-if sys.version_info < (3, 0):
- def _encode_filename(filename):
- if isinstance(filename, unicode):
- return filename.encode('utf-8')
- return filename
-else:
- def _encode_filename(filename):
- assert filename is None or isinstance(filename, str), \
- 'filenames must be strings'
- return filename
-
-from keyword import iskeyword as is_python_keyword
-
-
-# common types. These do exist in the special types module too which however
-# does not exist in IronPython out of the box. Also that way we don't have
-# to deal with implementation specific stuff here
-class _C(object):
- def method(self): pass
-def _func():
- yield None
-FunctionType = type(_func)
-GeneratorType = type(_func())
-MethodType = type(_C.method)
-CodeType = type(_C.method.func_code)
-try:
- raise TypeError()
-except TypeError:
- _tb = sys.exc_info()[2]
- TracebackType = type(_tb)
- FrameType = type(_tb.tb_frame)
-del _C, _tb, _func
-
-
-def contextfunction(f):
- """This decorator can be used to mark a function or method context callable.
- A context callable is passed the active :class:`Context` as first argument when
- called from the template. This is useful if a function wants to get access
- to the context or functions provided on the context object. For example
- a function that returns a sorted list of template variables the current
- template exports could look like this::
-
- @contextfunction
- def get_exported_names(context):
- return sorted(context.exported_vars)
- """
- f.contextfunction = True
- return f
-
-
-def evalcontextfunction(f):
- """This decoraotr can be used to mark a function or method as an eval
- context callable. This is similar to the :func:`contextfunction`
- but instead of passing the context, an evaluation context object is
- passed. For more information about the eval context, see
- :ref:`eval-context`.
-
- .. versionadded:: 2.4
- """
- f.evalcontextfunction = True
- return f
-
-
-def environmentfunction(f):
- """This decorator can be used to mark a function or method as environment
- callable. This decorator works exactly like the :func:`contextfunction`
- decorator just that the first argument is the active :class:`Environment`
- and not context.
- """
- f.environmentfunction = True
- return f
-
-
-def internalcode(f):
- """Marks the function as internally used"""
- internal_code.add(f.func_code)
- return f
-
-
-def is_undefined(obj):
- """Check if the object passed is undefined. This does nothing more than
- performing an instance check against :class:`Undefined` but looks nicer.
- This can be used for custom filters or tests that want to react to
- undefined variables. For example a custom default filter can look like
- this::
-
- def default(var, default=''):
- if is_undefined(var):
- return default
- return var
- """
- from jinja2.runtime import Undefined
- return isinstance(obj, Undefined)
-
-
-def consume(iterable):
- """Consumes an iterable without doing anything with it."""
- for event in iterable:
- pass
-
-
-def clear_caches():
- """Jinja2 keeps internal caches for environments and lexers. These are
- used so that Jinja2 doesn't have to recreate environments and lexers all
- the time. Normally you don't have to care about that but if you are
- messuring memory consumption you may want to clean the caches.
- """
- from jinja2.environment import _spontaneous_environments
- from jinja2.lexer import _lexer_cache
- _spontaneous_environments.clear()
- _lexer_cache.clear()
-
-
-def import_string(import_name, silent=False):
- """Imports an object based on a string. This use useful if you want to
- use import paths as endpoints or something similar. An import path can
- be specified either in dotted notation (``xml.sax.saxutils.escape``)
- or with a colon as object delimiter (``xml.sax.saxutils:escape``).
-
- If the `silent` is True the return value will be `None` if the import
- fails.
-
- :return: imported object
- """
- try:
- if ':' in import_name:
- module, obj = import_name.split(':', 1)
- elif '.' in import_name:
- items = import_name.split('.')
- module = '.'.join(items[:-1])
- obj = items[-1]
- else:
- return __import__(import_name)
- return getattr(__import__(module, None, None, [obj]), obj)
- except (ImportError, AttributeError):
- if not silent:
- raise
-
-
-def open_if_exists(filename, mode='rb'):
- """Returns a file descriptor for the filename if that file exists,
- otherwise `None`.
- """
- try:
- return open(filename, mode)
- except IOError, e:
- if e.errno not in (errno.ENOENT, errno.EISDIR):
- raise
-
-
-def object_type_repr(obj):
- """Returns the name of the object's type. For some recognized
- singletons the name of the object is returned instead. (For
- example for `None` and `Ellipsis`).
- """
- if obj is None:
- return 'None'
- elif obj is Ellipsis:
- return 'Ellipsis'
- # __builtin__ in 2.x, builtins in 3.x
- if obj.__class__.__module__ in ('__builtin__', 'builtins'):
- name = obj.__class__.__name__
- else:
- name = obj.__class__.__module__ + '.' + obj.__class__.__name__
- return '%s object' % name
-
-
-def pformat(obj, verbose=False):
- """Prettyprint an object. Either use the `pretty` library or the
- builtin `pprint`.
- """
- try:
- from pretty import pretty
- return pretty(obj, verbose=verbose)
- except ImportError:
- from pprint import pformat
- return pformat(obj)
-
-
-def urlize(text, trim_url_limit=None, nofollow=False):
- """Converts any URLs in text into clickable links. Works on http://,
- https:// and www. links. Links can have trailing punctuation (periods,
- commas, close-parens) and leading punctuation (opening parens) and
- it'll still do the right thing.
-
- If trim_url_limit is not None, the URLs in link text will be limited
- to trim_url_limit characters.
-
- If nofollow is True, the URLs in link text will get a rel="nofollow"
- attribute.
- """
- trim_url = lambda x, limit=trim_url_limit: limit is not None \
- and (x[:limit] + (len(x) >=limit and '...'
- or '')) or x
- words = _word_split_re.split(unicode(escape(text)))
- nofollow_attr = nofollow and ' rel="nofollow"' or ''
- for i, word in enumerate(words):
- match = _punctuation_re.match(word)
- if match:
- lead, middle, trail = match.groups()
- if middle.startswith('www.') or (
- '@' not in middle and
- not middle.startswith('http://') and
- len(middle) > 0 and
- middle[0] in _letters + _digits and (
- middle.endswith('.org') or
- middle.endswith('.net') or
- middle.endswith('.com')
- )):
- middle = '<a href="http://%s"%s>%s</a>' % (middle,
- nofollow_attr, trim_url(middle))
- if middle.startswith('http://') or \
- middle.startswith('https://'):
- middle = '<a href="%s"%s>%s</a>' % (middle,
- nofollow_attr, trim_url(middle))
- if '@' in middle and not middle.startswith('www.') and \
- not ':' in middle and _simple_email_re.match(middle):
- middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
- if lead + middle + trail != word:
- words[i] = lead + middle + trail
- return u''.join(words)
-
-
-def generate_lorem_ipsum(n=5, html=True, min=20, max=100):
- """Generate some lorem impsum for the template."""
- from jinja2.constants import LOREM_IPSUM_WORDS
- from random import choice, randrange
- words = LOREM_IPSUM_WORDS.split()
- result = []
-
- for _ in xrange(n):
- next_capitalized = True
- last_comma = last_fullstop = 0
- word = None
- last = None
- p = []
-
- # each paragraph contains out of 20 to 100 words.
- for idx, _ in enumerate(xrange(randrange(min, max))):
- while True:
- word = choice(words)
- if word != last:
- last = word
- break
- if next_capitalized:
- word = word.capitalize()
- next_capitalized = False
- # add commas
- if idx - randrange(3, 8) > last_comma:
- last_comma = idx
- last_fullstop += 2
- word += ','
- # add end of sentences
- if idx - randrange(10, 20) > last_fullstop:
- last_comma = last_fullstop = idx
- word += '.'
- next_capitalized = True
- p.append(word)
-
- # ensure that the paragraph ends with a dot.
- p = u' '.join(p)
- if p.endswith(','):
- p = p[:-1] + '.'
- elif not p.endswith('.'):
- p += '.'
- result.append(p)
-
- if not html:
- return u'\n\n'.join(result)
- return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result))
-
-
-class LRUCache(object):
- """A simple LRU Cache implementation."""
-
- # this is fast for small capacities (something below 1000) but doesn't
- # scale. But as long as it's only used as storage for templates this
- # won't do any harm.
-
- def __init__(self, capacity):
- self.capacity = capacity
- self._mapping = {}
- self._queue = deque()
- self._postinit()
-
- def _postinit(self):
- # alias all queue methods for faster lookup
- self._popleft = self._queue.popleft
- self._pop = self._queue.pop
- if hasattr(self._queue, 'remove'):
- self._remove = self._queue.remove
- self._wlock = allocate_lock()
- self._append = self._queue.append
-
- def _remove(self, obj):
- """Python 2.4 compatibility."""
- for idx, item in enumerate(self._queue):
- if item == obj:
- del self._queue[idx]
- break
-
- def __getstate__(self):
- return {
- 'capacity': self.capacity,
- '_mapping': self._mapping,
- '_queue': self._queue
- }
-
- def __setstate__(self, d):
- self.__dict__.update(d)
- self._postinit()
-
- def __getnewargs__(self):
- return (self.capacity,)
-
- def copy(self):
- """Return an shallow copy of the instance."""
- rv = self.__class__(self.capacity)
- rv._mapping.update(self._mapping)
- rv._queue = deque(self._queue)
- return rv
-
- def get(self, key, default=None):
- """Return an item from the cache dict or `default`"""
- try:
- return self[key]
- except KeyError:
- return default
-
- def setdefault(self, key, default=None):
- """Set `default` if the key is not in the cache otherwise
- leave unchanged. Return the value of this key.
- """
- try:
- return self[key]
- except KeyError:
- self[key] = default
- return default
-
- def clear(self):
- """Clear the cache."""
- self._wlock.acquire()
- try:
- self._mapping.clear()
- self._queue.clear()
- finally:
- self._wlock.release()
-
- def __contains__(self, key):
- """Check if a key exists in this cache."""
- return key in self._mapping
-
- def __len__(self):
- """Return the current size of the cache."""
- return len(self._mapping)
-
- def __repr__(self):
- return '<%s %r>' % (
- self.__class__.__name__,
- self._mapping
- )
-
- def __getitem__(self, key):
- """Get an item from the cache. Moves the item up so that it has the
- highest priority then.
-
- Raise an `KeyError` if it does not exist.
- """
- rv = self._mapping[key]
- if self._queue[-1] != key:
- try:
- self._remove(key)
- except ValueError:
- # if something removed the key from the container
- # when we read, ignore the ValueError that we would
- # get otherwise.
- pass
- self._append(key)
- return rv
-
- def __setitem__(self, key, value):
- """Sets the value for an item. Moves the item up so that it
- has the highest priority then.
- """
- self._wlock.acquire()
- try:
- if key in self._mapping:
- try:
- self._remove(key)
- except ValueError:
- # __getitem__ is not locked, it might happen
- pass
- elif len(self._mapping) == self.capacity:
- del self._mapping[self._popleft()]
- self._append(key)
- self._mapping[key] = value
- finally:
- self._wlock.release()
-
- def __delitem__(self, key):
- """Remove an item from the cache dict.
- Raise an `KeyError` if it does not exist.
- """
- self._wlock.acquire()
- try:
- del self._mapping[key]
- try:
- self._remove(key)
- except ValueError:
- # __getitem__ is not locked, it might happen
- pass
- finally:
- self._wlock.release()
-
- def items(self):
- """Return a list of items."""
- result = [(key, self._mapping[key]) for key in list(self._queue)]
- result.reverse()
- return result
-
- def iteritems(self):
- """Iterate over all items."""
- return iter(self.items())
-
- def values(self):
- """Return a list of all values."""
- return [x[1] for x in self.items()]
-
- def itervalue(self):
- """Iterate over all values."""
- return iter(self.values())
-
- def keys(self):
- """Return a list of all keys ordered by most recent usage."""
- return list(self)
-
- def iterkeys(self):
- """Iterate over all keys in the cache dict, ordered by
- the most recent usage.
- """
- return reversed(tuple(self._queue))
-
- __iter__ = iterkeys
-
- def __reversed__(self):
- """Iterate over the values in the cache dict, oldest items
- coming first.
- """
- return iter(tuple(self._queue))
-
- __copy__ = copy
-
-
-# register the LRU cache as mutable mapping if possible
-try:
- from collections import MutableMapping
- MutableMapping.register(LRUCache)
-except ImportError:
- pass
-
-
-class Cycler(object):
- """A cycle helper for templates."""
-
- def __init__(self, *items):
- if not items:
- raise RuntimeError('at least one item has to be provided')
- self.items = items
- self.reset()
-
- def reset(self):
- """Resets the cycle."""
- self.pos = 0
-
- @property
- def current(self):
- """Returns the current item."""
- return self.items[self.pos]
-
- def next(self):
- """Goes one item ahead and returns it."""
- rv = self.current
- self.pos = (self.pos + 1) % len(self.items)
- return rv
-
-
-class Joiner(object):
- """A joining helper for templates."""
-
- def __init__(self, sep=u', '):
- self.sep = sep
- self.used = False
-
- def __call__(self):
- if not self.used:
- self.used = True
- return u''
- return self.sep
-
-
-# try markupsafe first, if that fails go with Jinja2's bundled version
-# of markupsafe. Markupsafe was previously Jinja2's implementation of
-# the Markup object but was moved into a separate package in a patchleve
-# release
-try:
- from markupsafe import Markup, escape, soft_unicode
-except ImportError:
- from jinja2._markupsafe import Markup, escape, soft_unicode
-
-
-# partials
-try:
- from functools import partial
-except ImportError:
- class partial(object):
- def __init__(self, _func, *args, **kwargs):
- self._func = _func
- self._args = args
- self._kwargs = kwargs
- def __call__(self, *args, **kwargs):
- kwargs.update(self._kwargs)
- return self._func(*(self._args + args), **kwargs)
diff --git a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/visitor.py b/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/visitor.py
deleted file mode 100755
index 413e7c30..00000000
--- a/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/visitor.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.visitor
- ~~~~~~~~~~~~~~
-
- This module implements a visitor for the nodes.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD.
-"""
-from jinja2.nodes import Node
-
-
-class NodeVisitor(object):
- """Walks the abstract syntax tree and call visitor functions for every
- node found. The visitor functions may return values which will be
- forwarded by the `visit` method.
-
- Per default the visitor functions for the nodes are ``'visit_'`` +
- class name of the node. So a `TryFinally` node visit function would
- be `visit_TryFinally`. This behavior can be changed by overriding
- the `get_visitor` function. If no visitor function exists for a node
- (return value `None`) the `generic_visit` visitor is used instead.
- """
-
- def get_visitor(self, node):
- """Return the visitor function for this node or `None` if no visitor
- exists for this node. In that case the generic visit function is
- used instead.
- """
- method = 'visit_' + node.__class__.__name__
- return getattr(self, method, None)
-
- def visit(self, node, *args, **kwargs):
- """Visit a node."""
- f = self.get_visitor(node)
- if f is not None:
- return f(node, *args, **kwargs)
- return self.generic_visit(node, *args, **kwargs)
-
- def generic_visit(self, node, *args, **kwargs):
- """Called if no explicit visitor function exists for a node."""
- for node in node.iter_child_nodes():
- self.visit(node, *args, **kwargs)
-
-
-class NodeTransformer(NodeVisitor):
- """Walks the abstract syntax tree and allows modifications of nodes.
-
- The `NodeTransformer` will walk the AST and use the return value of the
- visitor functions to replace or remove the old node. If the return
- value of the visitor function is `None` the node will be removed
- from the previous location otherwise it's replaced with the return
- value. The return value may be the original node in which case no
- replacement takes place.
- """
-
- def generic_visit(self, node, *args, **kwargs):
- for field, old_value in node.iter_fields():
- if isinstance(old_value, list):
- new_values = []
- for value in old_value:
- if isinstance(value, Node):
- value = self.visit(value, *args, **kwargs)
- if value is None:
- continue
- elif not isinstance(value, Node):
- new_values.extend(value)
- continue
- new_values.append(value)
- old_value[:] = new_values
- elif isinstance(old_value, Node):
- new_node = self.visit(old_value, *args, **kwargs)
- if new_node is None:
- delattr(node, field)
- else:
- setattr(node, field, new_node)
- return node
-
- def visit_list(self, node, *args, **kwargs):
- """As transformers may return lists in some places this method
- can be used to enforce a list as return value.
- """
- rv = self.visit(node, *args, **kwargs)
- if not isinstance(rv, list):
- rv = [rv]
- return rv
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 005a0d30..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,137 +0,0 @@
-Metadata-Version: 1.1
-Name: SQLAlchemy
-Version: 0.7.0
-Summary: Database Abstraction Library
-Home-page: http://www.sqlalchemy.org
-Author: Mike Bayer
-Author-email: mike_mp@zzzcomputing.com
-License: MIT License
-Description: SQLAlchemy is:
-
- * The Python SQL toolkit and Object Relational Mapper
- that gives application developers the full power and
- flexibility of SQL. SQLAlchemy provides a full suite
- of well known enterprise-level persistence patterns,
- designed for efficient and high-performing database
- access, adapted into a simple and Pythonic domain
- language.
- * extremely easy to use for all the basic tasks, such
- as: accessing pooled connections, constructing SQL
- from Python expressions, finding object instances, and
- commiting object modifications back to the database.
- * powerful enough for complicated tasks, such as: eager
- load a graph of objects and their dependencies via
- joins; map recursive adjacency structures
- automatically; map objects to not just tables but to
- any arbitrary join or select statement; combine
- multiple tables together to load whole sets of
- otherwise unrelated objects from a single result set;
- commit entire graphs of object changes in one step.
- * built to conform to what DBAs demand, including the
- ability to swap out generated SQL with hand-optimized
- statements, full usage of bind parameters for all
- literal values, fully transactionalized and consistent
- updates using Unit of Work.
- * modular. Different parts of SQLAlchemy can be used
- independently of the rest, including the connection
- pool, SQL construction, and ORM. SQLAlchemy is
- constructed in an open style that allows plenty of
- customization, with an architecture that supports
- custom datatypes, custom SQL extensions, and ORM
- plugins which can augment or extend mapping
- functionality.
-
- SQLAlchemy's Philosophy:
-
- * SQL databases behave less and less like object
- collections the more size and performance start to
- matter; object collections behave less and less like
- tables and rows the more abstraction starts to matter.
- SQLAlchemy aims to accomodate both of these
- principles.
- * Your classes aren't tables, and your objects aren't
- rows. Databases aren't just collections of tables;
- they're relational algebra engines. You don't have to
- select from just tables, you can select from joins,
- subqueries, and unions. Database and domain concepts
- should be visibly decoupled from the beginning,
- allowing both sides to develop to their full
- potential.
- * For example, table metadata (objects that describe
- tables) are declared distinctly from the classes
- theyre designed to store. That way database
- relationship concepts don't interfere with your object
- design concepts, and vice-versa; the transition from
- table-mapping to selectable-mapping is seamless; a
- class can be mapped against the database in more than
- one way. SQLAlchemy provides a powerful mapping layer
- that can work as automatically or as manually as you
- choose, determining relationships based on foreign
- keys or letting you define the join conditions
- explicitly, to bridge the gap between database and
- domain.
-
- SQLAlchemy's Advantages:
-
- * The Unit Of Work system organizes pending CRUD
- operations into queues and commits them all in one
- batch. It then performs a topological "dependency
- sort" of all items to be committed and deleted and
- groups redundant statements together. This produces
- the maxiumum efficiency and transaction safety, and
- minimizes chances of deadlocks. Modeled after Fowler's
- "Unit of Work" pattern as well as Java Hibernate.
- * Function-based query construction allows boolean
- expressions, operators, functions, table aliases,
- selectable subqueries, create/update/insert/delete
- queries, correlated updates, correlated EXISTS
- clauses, UNION clauses, inner and outer joins, bind
- parameters, free mixing of literal text within
- expressions, as little or as much as desired.
- Query-compilation is vendor-specific; the same query
- object can be compiled into any number of resulting
- SQL strings depending on its compilation algorithm.
- * Database mapping and class design are totally
- separate. Persisted objects have no subclassing
- requirement (other than 'object') and are POPO's :
- plain old Python objects. They retain serializability
- (pickling) for usage in various caching systems and
- session objects. SQLAlchemy "decorates" classes with
- non-intrusive property accessors to automatically log
- object creates and modifications with the UnitOfWork
- engine, to lazyload related data, as well as to track
- attribute change histories.
- * Custom list classes can be used with eagerly or lazily
- loaded child object lists, allowing rich relationships
- to be created on the fly as SQLAlchemy appends child
- objects to an object attribute.
- * Composite (multiple-column) primary keys are
- supported, as are "association" objects that represent
- the middle of a "many-to-many" relationship.
- * Self-referential tables and mappers are supported.
- Adjacency list structures can be created, saved, and
- deleted with proper cascading, with no extra
- programming.
- * Data mapping can be used in a row-based manner. Any
- bizarre hyper-optimized query that you or your DBA can
- cook up, you can run in SQLAlchemy, and as long as it
- returns the expected columns within a rowset, you can
- get your objects from it. For a rowset that contains
- more than one kind of object per row, multiple mappers
- can be chained together to return multiple object
- instance lists from a single database round trip.
- * The type system allows pre- and post- processing of
- data, both at the bind parameter and the result set
- level. User-defined types can be freely mixed with
- built-in types. Generic types as well as SQL-specific
- types are available.
-
-
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Database :: Front-Ends
-Classifier: Operating System :: OS Independent
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index c0a438c2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,544 +0,0 @@
-CHANGES
-CHANGES_PRE_06
-LICENSE
-MANIFEST.in
-README
-README.py3k
-README.unittests
-distribute_setup.py
-ez_setup.py
-sa2to3.py
-setup.cfg
-setup.py
-sqla_nose.py
-doc/contents.html
-doc/copyright.html
-doc/genindex.html
-doc/index.html
-doc/intro.html
-doc/search.html
-doc/searchindex.js
-doc/_images/sqla_arch_small.png
-doc/_images/sqla_engine_arch.png
-doc/_sources/contents.txt
-doc/_sources/copyright.txt
-doc/_sources/index.txt
-doc/_sources/intro.txt
-doc/_sources/core/compiler.txt
-doc/_sources/core/connections.txt
-doc/_sources/core/engines.txt
-doc/_sources/core/event.txt
-doc/_sources/core/events.txt
-doc/_sources/core/exceptions.txt
-doc/_sources/core/expression_api.txt
-doc/_sources/core/index.txt
-doc/_sources/core/interfaces.txt
-doc/_sources/core/internals.txt
-doc/_sources/core/pooling.txt
-doc/_sources/core/schema.txt
-doc/_sources/core/serializer.txt
-doc/_sources/core/tutorial.txt
-doc/_sources/core/types.txt
-doc/_sources/dialects/access.txt
-doc/_sources/dialects/drizzle.txt
-doc/_sources/dialects/firebird.txt
-doc/_sources/dialects/index.txt
-doc/_sources/dialects/informix.txt
-doc/_sources/dialects/maxdb.txt
-doc/_sources/dialects/mssql.txt
-doc/_sources/dialects/mysql.txt
-doc/_sources/dialects/oracle.txt
-doc/_sources/dialects/postgresql.txt
-doc/_sources/dialects/sqlite.txt
-doc/_sources/dialects/sybase.txt
-doc/_sources/orm/collections.txt
-doc/_sources/orm/deprecated.txt
-doc/_sources/orm/events.txt
-doc/_sources/orm/examples.txt
-doc/_sources/orm/exceptions.txt
-doc/_sources/orm/index.txt
-doc/_sources/orm/inheritance.txt
-doc/_sources/orm/interfaces.txt
-doc/_sources/orm/internals.txt
-doc/_sources/orm/loading.txt
-doc/_sources/orm/mapper_config.txt
-doc/_sources/orm/query.txt
-doc/_sources/orm/relationships.txt
-doc/_sources/orm/session.txt
-doc/_sources/orm/tutorial.txt
-doc/_sources/orm/extensions/associationproxy.txt
-doc/_sources/orm/extensions/declarative.txt
-doc/_sources/orm/extensions/horizontal_shard.txt
-doc/_sources/orm/extensions/hybrid.txt
-doc/_sources/orm/extensions/index.txt
-doc/_sources/orm/extensions/mutable.txt
-doc/_sources/orm/extensions/orderinglist.txt
-doc/_sources/orm/extensions/sqlsoup.txt
-doc/_static/basic.css
-doc/_static/default.css
-doc/_static/docs.css
-doc/_static/doctools.js
-doc/_static/file.png
-doc/_static/init.js
-doc/_static/jquery.js
-doc/_static/minus.png
-doc/_static/plus.png
-doc/_static/pygments.css
-doc/_static/searchtools.js
-doc/_static/sidebar.js
-doc/_static/underscore.js
-doc/build/Makefile
-doc/build/conf.py
-doc/build/contents.rst
-doc/build/copyright.rst
-doc/build/index.rst
-doc/build/intro.rst
-doc/build/requirements.txt
-doc/build/sqla_arch_small.png
-doc/build/testdocs.py
-doc/build/builder/__init__.py
-doc/build/builder/builders.py
-doc/build/builder/util.py
-doc/build/core/compiler.rst
-doc/build/core/connections.rst
-doc/build/core/engines.rst
-doc/build/core/event.rst
-doc/build/core/events.rst
-doc/build/core/exceptions.rst
-doc/build/core/expression_api.rst
-doc/build/core/index.rst
-doc/build/core/interfaces.rst
-doc/build/core/internals.rst
-doc/build/core/pooling.rst
-doc/build/core/schema.rst
-doc/build/core/serializer.rst
-doc/build/core/sqla_engine_arch.png
-doc/build/core/tutorial.rst
-doc/build/core/types.rst
-doc/build/dialects/access.rst
-doc/build/dialects/drizzle.rst
-doc/build/dialects/firebird.rst
-doc/build/dialects/index.rst
-doc/build/dialects/informix.rst
-doc/build/dialects/maxdb.rst
-doc/build/dialects/mssql.rst
-doc/build/dialects/mysql.rst
-doc/build/dialects/oracle.rst
-doc/build/dialects/postgresql.rst
-doc/build/dialects/sqlite.rst
-doc/build/dialects/sybase.rst
-doc/build/orm/collections.rst
-doc/build/orm/deprecated.rst
-doc/build/orm/events.rst
-doc/build/orm/examples.rst
-doc/build/orm/exceptions.rst
-doc/build/orm/index.rst
-doc/build/orm/inheritance.rst
-doc/build/orm/interfaces.rst
-doc/build/orm/internals.rst
-doc/build/orm/loading.rst
-doc/build/orm/mapper_config.rst
-doc/build/orm/query.rst
-doc/build/orm/relationships.rst
-doc/build/orm/session.rst
-doc/build/orm/tutorial.rst
-doc/build/orm/extensions/associationproxy.rst
-doc/build/orm/extensions/declarative.rst
-doc/build/orm/extensions/horizontal_shard.rst
-doc/build/orm/extensions/hybrid.rst
-doc/build/orm/extensions/index.rst
-doc/build/orm/extensions/mutable.rst
-doc/build/orm/extensions/orderinglist.rst
-doc/build/orm/extensions/sqlsoup.rst
-doc/build/static/docs.css
-doc/build/static/init.js
-doc/build/templates/genindex.mako
-doc/build/templates/layout.mako
-doc/build/templates/page.mako
-doc/build/templates/search.mako
-doc/build/templates/site_base.mako
-doc/build/templates/static_base.mako
-doc/build/texinputs/sphinx.sty
-doc/core/compiler.html
-doc/core/connections.html
-doc/core/engines.html
-doc/core/event.html
-doc/core/events.html
-doc/core/exceptions.html
-doc/core/expression_api.html
-doc/core/index.html
-doc/core/interfaces.html
-doc/core/internals.html
-doc/core/pooling.html
-doc/core/schema.html
-doc/core/serializer.html
-doc/core/tutorial.html
-doc/core/types.html
-doc/dialects/access.html
-doc/dialects/drizzle.html
-doc/dialects/firebird.html
-doc/dialects/index.html
-doc/dialects/informix.html
-doc/dialects/maxdb.html
-doc/dialects/mssql.html
-doc/dialects/mysql.html
-doc/dialects/oracle.html
-doc/dialects/postgresql.html
-doc/dialects/sqlite.html
-doc/dialects/sybase.html
-doc/orm/collections.html
-doc/orm/deprecated.html
-doc/orm/events.html
-doc/orm/examples.html
-doc/orm/exceptions.html
-doc/orm/index.html
-doc/orm/inheritance.html
-doc/orm/interfaces.html
-doc/orm/internals.html
-doc/orm/loading.html
-doc/orm/mapper_config.html
-doc/orm/query.html
-doc/orm/relationships.html
-doc/orm/session.html
-doc/orm/tutorial.html
-doc/orm/extensions/associationproxy.html
-doc/orm/extensions/declarative.html
-doc/orm/extensions/horizontal_shard.html
-doc/orm/extensions/hybrid.html
-doc/orm/extensions/index.html
-doc/orm/extensions/mutable.html
-doc/orm/extensions/orderinglist.html
-doc/orm/extensions/sqlsoup.html
-examples/__init__.py
-examples/adjacency_list/__init__.py
-examples/adjacency_list/adjacency_list.py
-examples/association/__init__.py
-examples/association/basic_association.py
-examples/association/dict_of_sets_with_default.py
-examples/association/proxied_association.py
-examples/beaker_caching/__init__.py
-examples/beaker_caching/advanced.py
-examples/beaker_caching/caching_query.py
-examples/beaker_caching/environment.py
-examples/beaker_caching/fixture_data.py
-examples/beaker_caching/helloworld.py
-examples/beaker_caching/local_session_caching.py
-examples/beaker_caching/model.py
-examples/beaker_caching/relation_caching.py
-examples/custom_attributes/__init__.py
-examples/custom_attributes/custom_management.py
-examples/custom_attributes/listen_for_events.py
-examples/dynamic_dict/__init__.py
-examples/dynamic_dict/dynamic_dict.py
-examples/elementtree/__init__.py
-examples/elementtree/adjacency_list.py
-examples/elementtree/optimized_al.py
-examples/elementtree/pickle.py
-examples/elementtree/test.xml
-examples/elementtree/test2.xml
-examples/elementtree/test3.xml
-examples/generic_associations/__init__.py
-examples/generic_associations/discriminator_on_association.py
-examples/generic_associations/table_per_association.py
-examples/generic_associations/table_per_related.py
-examples/graphs/__init__.py
-examples/graphs/directed_graph.py
-examples/inheritance/__init__.py
-examples/inheritance/concrete.py
-examples/inheritance/polymorph.py
-examples/inheritance/single.py
-examples/large_collection/__init__.py
-examples/large_collection/large_collection.py
-examples/nested_sets/__init__.py
-examples/nested_sets/nested_sets.py
-examples/postgis/__init__.py
-examples/postgis/postgis.py
-examples/sharding/__init__.py
-examples/sharding/attribute_shard.py
-examples/versioning/__init__.py
-examples/versioning/history_meta.py
-examples/versioning/test_versioning.py
-examples/vertical/__init__.py
-examples/vertical/dictlike-polymorphic.py
-examples/vertical/dictlike.py
-lib/SQLAlchemy.egg-info/PKG-INFO
-lib/SQLAlchemy.egg-info/SOURCES.txt
-lib/SQLAlchemy.egg-info/dependency_links.txt
-lib/SQLAlchemy.egg-info/top_level.txt
-lib/sqlalchemy/__init__.py
-lib/sqlalchemy/event.py
-lib/sqlalchemy/events.py
-lib/sqlalchemy/exc.py
-lib/sqlalchemy/interfaces.py
-lib/sqlalchemy/log.py
-lib/sqlalchemy/pool.py
-lib/sqlalchemy/processors.py
-lib/sqlalchemy/schema.py
-lib/sqlalchemy/types.py
-lib/sqlalchemy/cextension/processors.c
-lib/sqlalchemy/cextension/resultproxy.c
-lib/sqlalchemy/connectors/__init__.py
-lib/sqlalchemy/connectors/mxodbc.py
-lib/sqlalchemy/connectors/mysqldb.py
-lib/sqlalchemy/connectors/pyodbc.py
-lib/sqlalchemy/connectors/zxJDBC.py
-lib/sqlalchemy/databases/__init__.py
-lib/sqlalchemy/dialects/__init__.py
-lib/sqlalchemy/dialects/postgres.py
-lib/sqlalchemy/dialects/type_migration_guidelines.txt
-lib/sqlalchemy/dialects/access/__init__.py
-lib/sqlalchemy/dialects/access/base.py
-lib/sqlalchemy/dialects/drizzle/__init__.py
-lib/sqlalchemy/dialects/drizzle/base.py
-lib/sqlalchemy/dialects/drizzle/mysqldb.py
-lib/sqlalchemy/dialects/firebird/__init__.py
-lib/sqlalchemy/dialects/firebird/base.py
-lib/sqlalchemy/dialects/firebird/kinterbasdb.py
-lib/sqlalchemy/dialects/informix/__init__.py
-lib/sqlalchemy/dialects/informix/base.py
-lib/sqlalchemy/dialects/informix/informixdb.py
-lib/sqlalchemy/dialects/maxdb/__init__.py
-lib/sqlalchemy/dialects/maxdb/base.py
-lib/sqlalchemy/dialects/maxdb/sapdb.py
-lib/sqlalchemy/dialects/mssql/__init__.py
-lib/sqlalchemy/dialects/mssql/adodbapi.py
-lib/sqlalchemy/dialects/mssql/base.py
-lib/sqlalchemy/dialects/mssql/information_schema.py
-lib/sqlalchemy/dialects/mssql/mxodbc.py
-lib/sqlalchemy/dialects/mssql/pymssql.py
-lib/sqlalchemy/dialects/mssql/pyodbc.py
-lib/sqlalchemy/dialects/mssql/zxjdbc.py
-lib/sqlalchemy/dialects/mysql/__init__.py
-lib/sqlalchemy/dialects/mysql/base.py
-lib/sqlalchemy/dialects/mysql/mysqlconnector.py
-lib/sqlalchemy/dialects/mysql/mysqldb.py
-lib/sqlalchemy/dialects/mysql/oursql.py
-lib/sqlalchemy/dialects/mysql/pymysql.py
-lib/sqlalchemy/dialects/mysql/pyodbc.py
-lib/sqlalchemy/dialects/mysql/zxjdbc.py
-lib/sqlalchemy/dialects/oracle/__init__.py
-lib/sqlalchemy/dialects/oracle/base.py
-lib/sqlalchemy/dialects/oracle/cx_oracle.py
-lib/sqlalchemy/dialects/oracle/zxjdbc.py
-lib/sqlalchemy/dialects/postgresql/__init__.py
-lib/sqlalchemy/dialects/postgresql/base.py
-lib/sqlalchemy/dialects/postgresql/pg8000.py
-lib/sqlalchemy/dialects/postgresql/psycopg2.py
-lib/sqlalchemy/dialects/postgresql/pypostgresql.py
-lib/sqlalchemy/dialects/postgresql/zxjdbc.py
-lib/sqlalchemy/dialects/sqlite/__init__.py
-lib/sqlalchemy/dialects/sqlite/base.py
-lib/sqlalchemy/dialects/sqlite/pysqlite.py
-lib/sqlalchemy/dialects/sybase/__init__.py
-lib/sqlalchemy/dialects/sybase/base.py
-lib/sqlalchemy/dialects/sybase/mxodbc.py
-lib/sqlalchemy/dialects/sybase/pyodbc.py
-lib/sqlalchemy/dialects/sybase/pysybase.py
-lib/sqlalchemy/engine/__init__.py
-lib/sqlalchemy/engine/base.py
-lib/sqlalchemy/engine/ddl.py
-lib/sqlalchemy/engine/default.py
-lib/sqlalchemy/engine/reflection.py
-lib/sqlalchemy/engine/strategies.py
-lib/sqlalchemy/engine/threadlocal.py
-lib/sqlalchemy/engine/url.py
-lib/sqlalchemy/ext/__init__.py
-lib/sqlalchemy/ext/associationproxy.py
-lib/sqlalchemy/ext/compiler.py
-lib/sqlalchemy/ext/declarative.py
-lib/sqlalchemy/ext/horizontal_shard.py
-lib/sqlalchemy/ext/hybrid.py
-lib/sqlalchemy/ext/mutable.py
-lib/sqlalchemy/ext/orderinglist.py
-lib/sqlalchemy/ext/serializer.py
-lib/sqlalchemy/ext/sqlsoup.py
-lib/sqlalchemy/orm/__init__.py
-lib/sqlalchemy/orm/attributes.py
-lib/sqlalchemy/orm/collections.py
-lib/sqlalchemy/orm/dependency.py
-lib/sqlalchemy/orm/deprecated_interfaces.py
-lib/sqlalchemy/orm/descriptor_props.py
-lib/sqlalchemy/orm/dynamic.py
-lib/sqlalchemy/orm/evaluator.py
-lib/sqlalchemy/orm/events.py
-lib/sqlalchemy/orm/exc.py
-lib/sqlalchemy/orm/identity.py
-lib/sqlalchemy/orm/instrumentation.py
-lib/sqlalchemy/orm/interfaces.py
-lib/sqlalchemy/orm/mapper.py
-lib/sqlalchemy/orm/properties.py
-lib/sqlalchemy/orm/query.py
-lib/sqlalchemy/orm/scoping.py
-lib/sqlalchemy/orm/session.py
-lib/sqlalchemy/orm/shard.py
-lib/sqlalchemy/orm/state.py
-lib/sqlalchemy/orm/strategies.py
-lib/sqlalchemy/orm/sync.py
-lib/sqlalchemy/orm/unitofwork.py
-lib/sqlalchemy/orm/util.py
-lib/sqlalchemy/sql/__init__.py
-lib/sqlalchemy/sql/compiler.py
-lib/sqlalchemy/sql/expression.py
-lib/sqlalchemy/sql/functions.py
-lib/sqlalchemy/sql/operators.py
-lib/sqlalchemy/sql/util.py
-lib/sqlalchemy/sql/visitors.py
-lib/sqlalchemy/util/__init__.py
-lib/sqlalchemy/util/_collections.py
-lib/sqlalchemy/util/compat.py
-lib/sqlalchemy/util/deprecations.py
-lib/sqlalchemy/util/langhelpers.py
-lib/sqlalchemy/util/queue.py
-lib/sqlalchemy/util/topological.py
-test/__init__.py
-test/binary_data_one.dat
-test/binary_data_two.dat
-test/aaa_profiling/__init__.py
-test/aaa_profiling/test_compiler.py
-test/aaa_profiling/test_memusage.py
-test/aaa_profiling/test_orm.py
-test/aaa_profiling/test_pool.py
-test/aaa_profiling/test_resultset.py
-test/aaa_profiling/test_zoomark.py
-test/aaa_profiling/test_zoomark_orm.py
-test/base/__init__.py
-test/base/test_dependency.py
-test/base/test_events.py
-test/base/test_except.py
-test/base/test_utils.py
-test/bootstrap/__init__.py
-test/bootstrap/config.py
-test/bootstrap/noseplugin.py
-test/dialect/__init__.py
-test/dialect/test_access.py
-test/dialect/test_firebird.py
-test/dialect/test_informix.py
-test/dialect/test_maxdb.py
-test/dialect/test_mssql.py
-test/dialect/test_mxodbc.py
-test/dialect/test_mysql.py
-test/dialect/test_oracle.py
-test/dialect/test_postgresql.py
-test/dialect/test_sqlite.py
-test/dialect/test_sybase.py
-test/engine/__init__.py
-test/engine/test_bind.py
-test/engine/test_ddlevents.py
-test/engine/test_execute.py
-test/engine/test_parseconnect.py
-test/engine/test_pool.py
-test/engine/test_reconnect.py
-test/engine/test_reflection.py
-test/engine/test_transaction.py
-test/ex/__init__.py
-test/ex/test_examples.py
-test/ext/__init__.py
-test/ext/test_associationproxy.py
-test/ext/test_compiler.py
-test/ext/test_declarative.py
-test/ext/test_horizontal_shard.py
-test/ext/test_hybrid.py
-test/ext/test_mutable.py
-test/ext/test_orderinglist.py
-test/ext/test_serializer.py
-test/ext/test_sqlsoup.py
-test/lib/__init__.py
-test/lib/assertsql.py
-test/lib/engines.py
-test/lib/entities.py
-test/lib/fixtures.py
-test/lib/orm.py
-test/lib/pickleable.py
-test/lib/profiling.py
-test/lib/requires.py
-test/lib/schema.py
-test/lib/testing.py
-test/lib/util.py
-test/orm/__init__.py
-test/orm/_fixtures.py
-test/orm/test_association.py
-test/orm/test_assorted_eager.py
-test/orm/test_attributes.py
-test/orm/test_backref_mutations.py
-test/orm/test_bind.py
-test/orm/test_cascade.py
-test/orm/test_collection.py
-test/orm/test_compile.py
-test/orm/test_composites.py
-test/orm/test_cycles.py
-test/orm/test_defaults.py
-test/orm/test_deprecations.py
-test/orm/test_descriptor.py
-test/orm/test_dynamic.py
-test/orm/test_eager_relations.py
-test/orm/test_evaluator.py
-test/orm/test_events.py
-test/orm/test_expire.py
-test/orm/test_extendedattr.py
-test/orm/test_froms.py
-test/orm/test_generative.py
-test/orm/test_immediate_load.py
-test/orm/test_instrumentation.py
-test/orm/test_joins.py
-test/orm/test_lazy_relations.py
-test/orm/test_legacy_mutable.py
-test/orm/test_load_on_fks.py
-test/orm/test_manytomany.py
-test/orm/test_mapper.py
-test/orm/test_merge.py
-test/orm/test_naturalpks.py
-test/orm/test_onetoone.py
-test/orm/test_pickled.py
-test/orm/test_query.py
-test/orm/test_relationships.py
-test/orm/test_scoping.py
-test/orm/test_selectable.py
-test/orm/test_session.py
-test/orm/test_subquery_relations.py
-test/orm/test_sync.py
-test/orm/test_transaction.py
-test/orm/test_unitofwork.py
-test/orm/test_unitofworkv2.py
-test/orm/test_update_delete.py
-test/orm/test_utils.py
-test/orm/test_versioning.py
-test/orm/inheritance/__init__.py
-test/orm/inheritance/test_abc_inheritance.py
-test/orm/inheritance/test_abc_polymorphic.py
-test/orm/inheritance/test_basic.py
-test/orm/inheritance/test_concrete.py
-test/orm/inheritance/test_magazine.py
-test/orm/inheritance/test_manytomany.py
-test/orm/inheritance/test_poly_linked_list.py
-test/orm/inheritance/test_polymorph.py
-test/orm/inheritance/test_polymorph2.py
-test/orm/inheritance/test_productspec.py
-test/orm/inheritance/test_query.py
-test/orm/inheritance/test_selects.py
-test/orm/inheritance/test_single.py
-test/perf/insertspeed.py
-test/perf/large_flush.py
-test/perf/objselectspeed.py
-test/perf/objupdatespeed.py
-test/perf/orm2010.py
-test/perf/ormsession.py
-test/perf/sessions.py
-test/perf/stress_all.py
-test/perf/stresstest.py
-test/perf/threaded_compile.py
-test/sql/__init__.py
-test/sql/test_case_statement.py
-test/sql/test_compiler.py
-test/sql/test_constraints.py
-test/sql/test_defaults.py
-test/sql/test_functions.py
-test/sql/test_generative.py
-test/sql/test_labels.py
-test/sql/test_metadata.py
-test/sql/test_query.py
-test/sql/test_quote.py
-test/sql/test_returning.py
-test/sql/test_rowcount.py
-test/sql/test_selectable.py
-test/sql/test_types.py
-test/sql/test_unicode.py \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt
deleted file mode 100644
index 1b5ded15..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-sqlalchemy/cprocessors.so
-sqlalchemy/cresultproxy.so
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 39fb2bef..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-sqlalchemy
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/__init__.py
deleted file mode 100755
index 6d8a0825..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/__init__.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# sqlalchemy/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-import inspect
-import sys
-
-import sqlalchemy.exc as exceptions
-
-from sqlalchemy.sql import (
- alias,
- and_,
- asc,
- between,
- bindparam,
- case,
- cast,
- collate,
- delete,
- desc,
- distinct,
- except_,
- except_all,
- exists,
- extract,
- func,
- insert,
- intersect,
- intersect_all,
- join,
- literal,
- literal_column,
- modifier,
- not_,
- null,
- or_,
- outerjoin,
- outparam,
- over,
- select,
- subquery,
- text,
- tuple_,
- type_coerce,
- union,
- union_all,
- update,
- )
-
-from sqlalchemy.types import (
- BLOB,
- BOOLEAN,
- BigInteger,
- Binary,
- Boolean,
- CHAR,
- CLOB,
- DATE,
- DATETIME,
- DECIMAL,
- Date,
- DateTime,
- Enum,
- FLOAT,
- Float,
- INT,
- INTEGER,
- Integer,
- Interval,
- LargeBinary,
- NCHAR,
- NVARCHAR,
- NUMERIC,
- Numeric,
- PickleType,
- REAL,
- SMALLINT,
- SmallInteger,
- String,
- TEXT,
- TIME,
- TIMESTAMP,
- Text,
- Time,
- TypeDecorator,
- Unicode,
- UnicodeText,
- VARCHAR,
- )
-
-
-from sqlalchemy.schema import (
- CheckConstraint,
- Column,
- ColumnDefault,
- Constraint,
- DDL,
- DefaultClause,
- FetchedValue,
- ForeignKey,
- ForeignKeyConstraint,
- Index,
- MetaData,
- PassiveDefault,
- PrimaryKeyConstraint,
- Sequence,
- Table,
- ThreadLocalMetaData,
- UniqueConstraint,
- )
-
-from sqlalchemy.engine import create_engine, engine_from_config
-
-
-__all__ = sorted(name for name, obj in locals().items()
- if not (name.startswith('_') or inspect.ismodule(obj)))
-
-__version__ = '0.7.0'
-
-del inspect, sys
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/__init__.py
deleted file mode 100755
index 340c5b8f..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# connectors/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-
-class Connector(object):
- pass
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mxodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mxodbc.py
deleted file mode 100755
index 5573dda4..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mxodbc.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# connectors/mxodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Provide an SQLALchemy connector for the eGenix mxODBC commercial
-Python adapter for ODBC. This is not a free product, but eGenix
-provides SQLAlchemy with a license for use in continuous integration
-testing.
-
-This has been tested for use with mxODBC 3.1.2 on SQL Server 2005
-and 2008, using the SQL Server Native driver. However, it is
-possible for this to be used on other database platforms.
-
-For more info on mxODBC, see http://www.egenix.com/
-
-"""
-
-import sys
-import re
-import warnings
-
-from sqlalchemy.connectors import Connector
-
-class MxODBCConnector(Connector):
- driver='mxodbc'
-
- supports_sane_multi_rowcount = False
- supports_unicode_statements = False
- supports_unicode_binds = False
-
- supports_native_decimal = True
-
- @classmethod
- def dbapi(cls):
- # this classmethod will normally be replaced by an instance
- # attribute of the same name, so this is normally only called once.
- cls._load_mx_exceptions()
- platform = sys.platform
- if platform == 'win32':
- from mx.ODBC import Windows as module
- # this can be the string "linux2", and possibly others
- elif 'linux' in platform:
- from mx.ODBC import unixODBC as module
- elif platform == 'darwin':
- from mx.ODBC import iODBC as module
- else:
- raise ImportError, "Unrecognized platform for mxODBC import"
- return module
-
- @classmethod
- def _load_mx_exceptions(cls):
- """ Import mxODBC exception classes into the module namespace,
- as if they had been imported normally. This is done here
- to avoid requiring all SQLAlchemy users to install mxODBC.
- """
- global InterfaceError, ProgrammingError
- from mx.ODBC import InterfaceError
- from mx.ODBC import ProgrammingError
-
- def on_connect(self):
- def connect(conn):
- conn.stringformat = self.dbapi.MIXED_STRINGFORMAT
- conn.datetimeformat = self.dbapi.PYDATETIME_DATETIMEFORMAT
- conn.decimalformat = self.dbapi.DECIMAL_DECIMALFORMAT
- conn.errorhandler = self._error_handler()
- return connect
-
- def _error_handler(self):
- """ Return a handler that adjusts mxODBC's raised Warnings to
- emit Python standard warnings.
- """
- from mx.ODBC.Error import Warning as MxOdbcWarning
- def error_handler(connection, cursor, errorclass, errorvalue):
-
- if issubclass(errorclass, MxOdbcWarning):
- errorclass.__bases__ = (Warning,)
- warnings.warn(message=str(errorvalue),
- category=errorclass,
- stacklevel=2)
- else:
- raise errorclass, errorvalue
- return error_handler
-
- def create_connect_args(self, url):
- """ Return a tuple of *args,**kwargs for creating a connection.
-
- The mxODBC 3.x connection constructor looks like this:
-
- connect(dsn, user='', password='',
- clear_auto_commit=1, errorhandler=None)
-
- This method translates the values in the provided uri
- into args and kwargs needed to instantiate an mxODBC Connection.
-
- The arg 'errorhandler' is not used by SQLAlchemy and will
- not be populated.
-
- """
- opts = url.translate_connect_args(username='user')
- opts.update(url.query)
- args = opts.pop('host')
- opts.pop('port', None)
- opts.pop('database', None)
- return (args,), opts
-
- def is_disconnect(self, e, connection, cursor):
- # TODO: eGenix recommends checking connection.closed here
- # Does that detect dropped connections ?
- if isinstance(e, self.dbapi.ProgrammingError):
- return "connection already closed" in str(e)
- elif isinstance(e, self.dbapi.Error):
- return '[08S01]' in str(e)
- else:
- return False
-
- def _get_server_version_info(self, connection):
- # eGenix suggests using conn.dbms_version instead
- # of what we're doing here
- dbapi_con = connection.connection
- version = []
- r = re.compile('[.\-]')
- # 18 == pyodbc.SQL_DBMS_VER
- for n in r.split(dbapi_con.getinfo(18)[1]):
- try:
- version.append(int(n))
- except ValueError:
- version.append(n)
- return tuple(version)
-
- def do_execute(self, cursor, statement, parameters, context=None):
- if context:
- native_odbc_execute = context.execution_options.\
- get('native_odbc_execute', 'auto')
- if native_odbc_execute is True:
- # user specified native_odbc_execute=True
- cursor.execute(statement, parameters)
- elif native_odbc_execute is False:
- # user specified native_odbc_execute=False
- cursor.executedirect(statement, parameters)
- elif context.is_crud:
- # statement is UPDATE, DELETE, INSERT
- cursor.execute(statement, parameters)
- else:
- # all other statements
- cursor.executedirect(statement, parameters)
- else:
- cursor.executedirect(statement, parameters)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mysqldb.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mysqldb.py
deleted file mode 100755
index 189c412a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/mysqldb.py
+++ /dev/null
@@ -1,150 +0,0 @@
-"""Define behaviors common to MySQLdb dialects.
-
-Currently includes MySQL and Drizzle.
-
-"""
-
-from sqlalchemy.connectors import Connector
-from sqlalchemy.engine import base as engine_base, default
-from sqlalchemy.sql import operators as sql_operators
-from sqlalchemy import exc, log, schema, sql, types as sqltypes, util
-from sqlalchemy import processors
-import re
-
-# the subclassing of Connector by all classes
-# here is not strictly necessary
-
-class MySQLDBExecutionContext(Connector):
-
- @property
- def rowcount(self):
- if hasattr(self, '_rowcount'):
- return self._rowcount
- else:
- return self.cursor.rowcount
-
-class MySQLDBCompiler(Connector):
- def visit_mod(self, binary, **kw):
- return self.process(binary.left) + " %% " + self.process(binary.right)
-
- def post_process_text(self, text):
- return text.replace('%', '%%')
-
-class MySQLDBIdentifierPreparer(Connector):
-
- def _escape_identifier(self, value):
- value = value.replace(self.escape_quote, self.escape_to_quote)
- return value.replace("%", "%%")
-
-class MySQLDBConnector(Connector):
- driver = 'mysqldb'
- supports_unicode_statements = False
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = True
-
- supports_native_decimal = True
-
- default_paramstyle = 'format'
-
- @classmethod
- def dbapi(cls):
- # is overridden when pymysql is used
- return __import__('MySQLdb')
-
- def do_executemany(self, cursor, statement, parameters, context=None):
- rowcount = cursor.executemany(statement, parameters)
- if context is not None:
- context._rowcount = rowcount
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(database='db', username='user',
- password='passwd')
- opts.update(url.query)
-
- util.coerce_kw_type(opts, 'compress', bool)
- util.coerce_kw_type(opts, 'connect_timeout', int)
- util.coerce_kw_type(opts, 'client_flag', int)
- util.coerce_kw_type(opts, 'local_infile', int)
- # Note: using either of the below will cause all strings to be returned
- # as Unicode, both in raw SQL operations and with column types like
- # String and MSString.
- util.coerce_kw_type(opts, 'use_unicode', bool)
- util.coerce_kw_type(opts, 'charset', str)
-
- # Rich values 'cursorclass' and 'conv' are not supported via
- # query string.
-
- ssl = {}
- for key in ['ssl_ca', 'ssl_key', 'ssl_cert', 'ssl_capath', 'ssl_cipher']:
- if key in opts:
- ssl[key[4:]] = opts[key]
- util.coerce_kw_type(ssl, key[4:], str)
- del opts[key]
- if ssl:
- opts['ssl'] = ssl
-
- # FOUND_ROWS must be set in CLIENT_FLAGS to enable
- # supports_sane_rowcount.
- client_flag = opts.get('client_flag', 0)
- if self.dbapi is not None:
- try:
- CLIENT_FLAGS = __import__(
- self.dbapi.__name__ + '.constants.CLIENT'
- ).constants.CLIENT
- client_flag |= CLIENT_FLAGS.FOUND_ROWS
- except (AttributeError, ImportError):
- pass
- opts['client_flag'] = client_flag
- return [[], opts]
-
- def _get_server_version_info(self, connection):
- dbapi_con = connection.connection
- version = []
- r = re.compile('[.\-]')
- for n in r.split(dbapi_con.get_server_info()):
- try:
- version.append(int(n))
- except ValueError:
- version.append(n)
- return tuple(version)
-
- def _extract_error_code(self, exception):
- return exception.args[0]
-
- def _detect_charset(self, connection):
- """Sniff out the character set in use for connection results."""
-
- # Note: MySQL-python 1.2.1c7 seems to ignore changes made
- # on a connection via set_character_set()
- if self.server_version_info < (4, 1, 0):
- try:
- return connection.connection.character_set_name()
- except AttributeError:
- # < 1.2.1 final MySQL-python drivers have no charset support.
- # a query is needed.
- pass
-
- # Prefer 'character_set_results' for the current connection over the
- # value in the driver. SET NAMES or individual variable SETs will
- # change the charset without updating the driver's view of the world.
- #
- # If it's decided that issuing that sort of SQL leaves you SOL, then
- # this can prefer the driver value.
- rs = connection.execute("SHOW VARIABLES LIKE 'character_set%%'")
- opts = dict([(row[0], row[1]) for row in self._compat_fetchall(rs)])
-
- if 'character_set_results' in opts:
- return opts['character_set_results']
- try:
- return connection.connection.character_set_name()
- except AttributeError:
- # Still no charset on < 1.2.1 final...
- if 'character_set' in opts:
- return opts['character_set']
- else:
- util.warn(
- "Could not detect the connection character set with this "
- "combination of MySQL server and MySQL-python. "
- "MySQL-python >= 1.2.2 is recommended. Assuming latin1.")
- return 'latin1'
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/pyodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/pyodbc.py
deleted file mode 100755
index 3f6d6cb5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/pyodbc.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# connectors/pyodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.connectors import Connector
-from sqlalchemy.util import asbool
-
-import sys
-import re
-import urllib
-
-class PyODBCConnector(Connector):
- driver='pyodbc'
-
- supports_sane_multi_rowcount = False
- # PyODBC unicode is broken on UCS-4 builds
- supports_unicode = sys.maxunicode == 65535
- supports_unicode_statements = supports_unicode
- supports_native_decimal = True
- default_paramstyle = 'named'
-
- # for non-DSN connections, this should
- # hold the desired driver name
- pyodbc_driver_name = None
-
- # will be set to True after initialize()
- # if the freetds.so is detected
- freetds = False
-
- @classmethod
- def dbapi(cls):
- return __import__('pyodbc')
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- opts.update(url.query)
-
- keys = opts
- query = url.query
-
- connect_args = {}
- for param in ('ansi', 'unicode_results', 'autocommit'):
- if param in keys:
- connect_args[param] = asbool(keys.pop(param))
-
- if 'odbc_connect' in keys:
- connectors = [urllib.unquote_plus(keys.pop('odbc_connect'))]
- else:
- dsn_connection = 'dsn' in keys or \
- ('host' in keys and 'database' not in keys)
- if dsn_connection:
- connectors= ['dsn=%s' % (keys.pop('host', '') or \
- keys.pop('dsn', ''))]
- else:
- port = ''
- if 'port' in keys and not 'port' in query:
- port = ',%d' % int(keys.pop('port'))
-
- connectors = ["DRIVER={%s}" %
- keys.pop('driver', self.pyodbc_driver_name),
- 'Server=%s%s' % (keys.pop('host', ''), port),
- 'Database=%s' % keys.pop('database', '') ]
-
- user = keys.pop("user", None)
- if user:
- connectors.append("UID=%s" % user)
- connectors.append("PWD=%s" % keys.pop('password', ''))
- else:
- connectors.append("Trusted_Connection=Yes")
-
- # if set to 'Yes', the ODBC layer will try to automagically
- # convert textual data from your database encoding to your
- # client encoding. This should obviously be set to 'No' if
- # you query a cp1253 encoded database from a latin1 client...
- if 'odbc_autotranslate' in keys:
- connectors.append("AutoTranslate=%s" %
- keys.pop("odbc_autotranslate"))
-
- connectors.extend(['%s=%s' % (k,v) for k,v in keys.iteritems()])
- return [[";".join (connectors)], connect_args]
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, self.dbapi.ProgrammingError):
- return "The cursor's connection has been closed." in str(e) or \
- 'Attempt to use a closed connection.' in str(e)
- elif isinstance(e, self.dbapi.Error):
- return '[08S01]' in str(e)
- else:
- return False
-
- def initialize(self, connection):
- # determine FreeTDS first. can't issue SQL easily
- # without getting unicode_statements/binds set up.
-
- pyodbc = self.dbapi
-
- dbapi_con = connection.connection
-
- self.freetds = bool(re.match(r".*libtdsodbc.*\.so",
- dbapi_con.getinfo(pyodbc.SQL_DRIVER_NAME)
- ))
-
- # the "Py2K only" part here is theoretical.
- # have not tried pyodbc + python3.1 yet.
- # Py2K
- self.supports_unicode_statements = not self.freetds
- self.supports_unicode_binds = not self.freetds
- # end Py2K
-
- # run other initialization which asks for user name, etc.
- super(PyODBCConnector, self).initialize(connection)
-
- def _get_server_version_info(self, connection):
- dbapi_con = connection.connection
- version = []
- r = re.compile('[.\-]')
- for n in r.split(dbapi_con.getinfo(self.dbapi.SQL_DBMS_VER)):
- try:
- version.append(int(n))
- except ValueError:
- version.append(n)
- return tuple(version)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/zxJDBC.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/zxJDBC.py
deleted file mode 100755
index 20bf9d9c..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/connectors/zxJDBC.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# connectors/zxJDBC.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-import sys
-from sqlalchemy.connectors import Connector
-
-class ZxJDBCConnector(Connector):
- driver = 'zxjdbc'
-
- supports_sane_rowcount = False
- supports_sane_multi_rowcount = False
-
- supports_unicode_binds = True
- supports_unicode_statements = sys.version > '2.5.0+'
- description_encoding = None
- default_paramstyle = 'qmark'
-
- jdbc_db_name = None
- jdbc_driver_name = None
-
- @classmethod
- def dbapi(cls):
- from com.ziclix.python.sql import zxJDBC
- return zxJDBC
-
- def _driver_kwargs(self):
- """Return kw arg dict to be sent to connect()."""
- return {}
-
- def _create_jdbc_url(self, url):
- """Create a JDBC url from a :class:`~sqlalchemy.engine.url.URL`"""
- return 'jdbc:%s://%s%s/%s' % (self.jdbc_db_name, url.host,
- url.port is not None
- and ':%s' % url.port or '',
- url.database)
-
- def create_connect_args(self, url):
- opts = self._driver_kwargs()
- opts.update(url.query)
- return [
- [self._create_jdbc_url(url),
- url.username, url.password,
- self.jdbc_driver_name],
- opts]
-
- def is_disconnect(self, e, connection, cursor):
- if not isinstance(e, self.dbapi.ProgrammingError):
- return False
- e = str(e)
- return 'connection is closed' in e or 'cursor is closed' in e
-
- def _get_server_version_info(self, connection):
- # use connection.connection.dbversion, and parse appropriately
- # to get a tuple
- raise NotImplementedError()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.py
deleted file mode 100755
index 4f5a32f8..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'cprocessors.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.so b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.so
deleted file mode 100755
index 2ad6ad69..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cprocessors.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.py
deleted file mode 100755
index dd863cec..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'cresultproxy.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.so b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.so
deleted file mode 100755
index 0fa2cd5f..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/cresultproxy.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/databases/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/databases/__init__.py
deleted file mode 100755
index dddc8f68..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/databases/__init__.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# databases/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Include imports from the sqlalchemy.dialects package for backwards
-compatibility with pre 0.6 versions.
-
-"""
-from sqlalchemy.dialects.sqlite import base as sqlite
-from sqlalchemy.dialects.postgresql import base as postgresql
-postgres = postgresql
-from sqlalchemy.dialects.mysql import base as mysql
-from sqlalchemy.dialects.drizzle import base as drizzle
-from sqlalchemy.dialects.oracle import base as oracle
-from sqlalchemy.dialects.firebird import base as firebird
-from sqlalchemy.dialects.maxdb import base as maxdb
-from sqlalchemy.dialects.informix import base as informix
-from sqlalchemy.dialects.mssql import base as mssql
-from sqlalchemy.dialects.access import base as access
-from sqlalchemy.dialects.sybase import base as sybase
-
-
-__all__ = (
- 'access',
- 'drizzle',
- 'firebird',
- 'informix',
- 'maxdb',
- 'mssql',
- 'mysql',
- 'postgresql',
- 'sqlite',
- 'oracle',
- 'sybase',
- )
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/__init__.py
deleted file mode 100755
index 48e578a0..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# dialects/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-__all__ = (
-# 'access',
- 'drizzle',
- 'firebird',
-# 'informix',
-# 'maxdb',
- 'mssql',
- 'mysql',
- 'oracle',
- 'postgresql',
- 'sqlite',
- 'sybase',
- )
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/base.py
deleted file mode 100755
index 7c62dcc3..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/access/base.py
+++ /dev/null
@@ -1,450 +0,0 @@
-# access/base.py
-# Copyright (C) 2007-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# Copyright (C) 2007 Paul Johnston, paj@pajhome.org.uk
-# Portions derived from jet2sql.py by Matt Keranen, mksql@yahoo.com
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for the Microsoft Access database.
-
-This dialect is *not* ported to SQLAlchemy 0.6 or 0.7.
-
-This dialect is *not* tested on SQLAlchemy 0.6 or 0.7.
-
-
-"""
-from sqlalchemy import sql, schema, types, exc, pool
-from sqlalchemy.sql import compiler, expression
-from sqlalchemy.engine import default, base, reflection
-from sqlalchemy import processors
-
-class AcNumeric(types.Numeric):
- def get_col_spec(self):
- return "NUMERIC"
-
- def bind_processor(self, dialect):
- return processors.to_str
-
- def result_processor(self, dialect, coltype):
- return None
-
-class AcFloat(types.Float):
- def get_col_spec(self):
- return "FLOAT"
-
- def bind_processor(self, dialect):
- """By converting to string, we can use Decimal types round-trip."""
- return processors.to_str
-
-class AcInteger(types.Integer):
- def get_col_spec(self):
- return "INTEGER"
-
-class AcTinyInteger(types.Integer):
- def get_col_spec(self):
- return "TINYINT"
-
-class AcSmallInteger(types.SmallInteger):
- def get_col_spec(self):
- return "SMALLINT"
-
-class AcDateTime(types.DateTime):
- def get_col_spec(self):
- return "DATETIME"
-
-class AcDate(types.Date):
-
- def get_col_spec(self):
- return "DATETIME"
-
-class AcText(types.Text):
- def get_col_spec(self):
- return "MEMO"
-
-class AcString(types.String):
- def get_col_spec(self):
- return "TEXT" + (self.length and ("(%d)" % self.length) or "")
-
-class AcUnicode(types.Unicode):
- def get_col_spec(self):
- return "TEXT" + (self.length and ("(%d)" % self.length) or "")
-
- def bind_processor(self, dialect):
- return None
-
- def result_processor(self, dialect, coltype):
- return None
-
-class AcChar(types.CHAR):
- def get_col_spec(self):
- return "TEXT" + (self.length and ("(%d)" % self.length) or "")
-
-class AcBinary(types.LargeBinary):
- def get_col_spec(self):
- return "BINARY"
-
-class AcBoolean(types.Boolean):
- def get_col_spec(self):
- return "YESNO"
-
-class AcTimeStamp(types.TIMESTAMP):
- def get_col_spec(self):
- return "TIMESTAMP"
-
-class AccessExecutionContext(default.DefaultExecutionContext):
- def _has_implicit_sequence(self, column):
- if column.primary_key and column.autoincrement:
- if isinstance(column.type, types.Integer) and \
- not column.foreign_keys:
- if column.default is None or \
- (isinstance(column.default, schema.Sequence) and \
- column.default.optional):
- return True
- return False
-
- def post_exec(self):
- """If we inserted into a row with a COUNTER column, fetch the ID"""
-
- if self.compiled.isinsert:
- tbl = self.compiled.statement.table
- if not hasattr(tbl, 'has_sequence'):
- tbl.has_sequence = None
- for column in tbl.c:
- if getattr(column, 'sequence', False) or \
- self._has_implicit_sequence(column):
- tbl.has_sequence = column
- break
-
- if bool(tbl.has_sequence):
- # TBD: for some reason _last_inserted_ids doesn't exist here
- # (but it does at corresponding point in mssql???)
- #if not len(self._last_inserted_ids) or
- # self._last_inserted_ids[0] is None:
- self.cursor.execute("SELECT @@identity AS lastrowid")
- row = self.cursor.fetchone()
- self._last_inserted_ids = [int(row[0])]
- #+ self._last_inserted_ids[1:]
- # print "LAST ROW ID", self._last_inserted_ids
-
- super(AccessExecutionContext, self).post_exec()
-
-
-const, daoEngine = None, None
-class AccessDialect(default.DefaultDialect):
- colspecs = {
- types.Unicode : AcUnicode,
- types.Integer : AcInteger,
- types.SmallInteger: AcSmallInteger,
- types.Numeric : AcNumeric,
- types.Float : AcFloat,
- types.DateTime : AcDateTime,
- types.Date : AcDate,
- types.String : AcString,
- types.LargeBinary : AcBinary,
- types.Boolean : AcBoolean,
- types.Text : AcText,
- types.CHAR: AcChar,
- types.TIMESTAMP: AcTimeStamp,
- }
- name = 'access'
- supports_sane_rowcount = False
- supports_sane_multi_rowcount = False
-
- ported_sqla_06 = False
-
- def type_descriptor(self, typeobj):
- newobj = types.adapt_type(typeobj, self.colspecs)
- return newobj
-
- def __init__(self, **params):
- super(AccessDialect, self).__init__(**params)
- self.text_as_varchar = False
- self._dtbs = None
-
- @classmethod
- def dbapi(cls):
- import win32com.client, pythoncom
-
- global const, daoEngine
- if const is None:
- const = win32com.client.constants
- for suffix in (".36", ".35", ".30"):
- try:
- daoEngine = win32com.client.\
- gencache.\
- EnsureDispatch("DAO.DBEngine" + suffix)
- break
- except pythoncom.com_error:
- pass
- else:
- raise exc.InvalidRequestError(
- "Can't find a DB engine. Check "
- "http://support.microsoft.com/kb/239114 for details.")
-
- import pyodbc as module
- return module
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args()
- connectors = ["Driver={Microsoft Access Driver (*.mdb)}"]
- connectors.append("Dbq=%s" % opts["database"])
- user = opts.get("username", None)
- if user:
- connectors.append("UID=%s" % user)
- connectors.append("PWD=%s" % opts.get("password", ""))
- return [[";".join(connectors)], {}]
-
- def last_inserted_ids(self):
- return self.context.last_inserted_ids
-
- def do_execute(self, cursor, statement, params, context=None):
- if params == {}:
- params = ()
- super(AccessDialect, self).\
- do_execute(cursor, statement, params, **kwargs)
-
- def _execute(self, c, statement, parameters):
- try:
- if parameters == {}:
- parameters = ()
- c.execute(statement, parameters)
- self.context.rowcount = c.rowcount
- except Exception, e:
- raise exc.DBAPIError.instance(statement, parameters, e)
-
- def has_table(self, connection, tablename, schema=None):
- # This approach seems to be more reliable that using DAO
- try:
- connection.execute('select top 1 * from [%s]' % tablename)
- return True
- except Exception, e:
- return False
-
- def reflecttable(self, connection, table, include_columns):
- # This is defined in the function, as it relies on win32com constants,
- # that aren't imported until dbapi method is called
- if not hasattr(self, 'ischema_names'):
- self.ischema_names = {
- const.dbByte: AcBinary,
- const.dbInteger: AcInteger,
- const.dbLong: AcInteger,
- const.dbSingle: AcFloat,
- const.dbDouble: AcFloat,
- const.dbDate: AcDateTime,
- const.dbLongBinary: AcBinary,
- const.dbMemo: AcText,
- const.dbBoolean: AcBoolean,
- const.dbText: AcUnicode, # All Access strings are
- # unicode
- const.dbCurrency: AcNumeric,
- }
-
- # A fresh DAO connection is opened for each reflection
- # This is necessary, so we get the latest updates
- dtbs = daoEngine.OpenDatabase(connection.engine.url.database)
-
- try:
- for tbl in dtbs.TableDefs:
- if tbl.Name.lower() == table.name.lower():
- break
- else:
- raise exc.NoSuchTableError(table.name)
-
- for col in tbl.Fields:
- coltype = self.ischema_names[col.Type]
- if col.Type == const.dbText:
- coltype = coltype(col.Size)
-
- colargs = \
- {
- 'nullable': not(col.Required or
- col.Attributes & const.dbAutoIncrField),
- }
- default = col.DefaultValue
-
- if col.Attributes & const.dbAutoIncrField:
- colargs['default'] = schema.Sequence(col.Name + '_seq')
- elif default:
- if col.Type == const.dbBoolean:
- default = default == 'Yes' and '1' or '0'
- colargs['server_default'] = \
- schema.DefaultClause(sql.text(default))
-
- table.append_column(
- schema.Column(col.Name, coltype, **colargs))
-
- # TBD: check constraints
-
- # Find primary key columns first
- for idx in tbl.Indexes:
- if idx.Primary:
- for col in idx.Fields:
- thecol = table.c[col.Name]
- table.primary_key.add(thecol)
- if isinstance(thecol.type, AcInteger) and \
- not (thecol.default and
- isinstance(
- thecol.default.arg,
- schema.Sequence
- )):
- thecol.autoincrement = False
-
- # Then add other indexes
- for idx in tbl.Indexes:
- if not idx.Primary:
- if len(idx.Fields) == 1:
- col = table.c[idx.Fields[0].Name]
- if not col.primary_key:
- col.index = True
- col.unique = idx.Unique
- else:
- pass # TBD: multi-column indexes
-
-
- for fk in dtbs.Relations:
- if fk.ForeignTable != table.name:
- continue
- scols = [c.ForeignName for c in fk.Fields]
- rcols = ['%s.%s' % (fk.Table, c.Name) for c in fk.Fields]
- table.append_constraint(
- schema.ForeignKeyConstraint(scols, rcols,\
- link_to_name=True))
-
- finally:
- dtbs.Close()
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- # A fresh DAO connection is opened for each reflection
- # This is necessary, so we get the latest updates
- dtbs = daoEngine.OpenDatabase(connection.engine.url.database)
-
- names = [t.Name for t in dtbs.TableDefs
- if t.Name[:4] != "MSys" and t.Name[:4] != "~TMP"]
- dtbs.Close()
- return names
-
-
-class AccessCompiler(compiler.SQLCompiler):
- extract_map = compiler.SQLCompiler.extract_map.copy()
- extract_map.update ({
- 'month': 'm',
- 'day': 'd',
- 'year': 'yyyy',
- 'second': 's',
- 'hour': 'h',
- 'doy': 'y',
- 'minute': 'n',
- 'quarter': 'q',
- 'dow': 'w',
- 'week': 'ww'
- })
-
- def visit_select_precolumns(self, select):
- """Access puts TOP, it's version of LIMIT here """
- s = select.distinct and "DISTINCT " or ""
- if select.limit:
- s += "TOP %s " % (select.limit)
- if select.offset:
- raise exc.InvalidRequestError(
- 'Access does not support LIMIT with an offset')
- return s
-
- def limit_clause(self, select):
- """Limit in access is after the select keyword"""
- return ""
-
- def binary_operator_string(self, binary):
- """Access uses "mod" instead of "%" """
- return binary.operator == '%' and 'mod' or binary.operator
-
- def label_select_column(self, select, column, asfrom):
- if isinstance(column, expression.Function):
- return column.label()
- else:
- return super(AccessCompiler, self).\
- label_select_column(select, column, asfrom)
-
- function_rewrites = {'current_date': 'now',
- 'current_timestamp': 'now',
- 'length': 'len',
- }
- def visit_function(self, func):
- """Access function names differ from the ANSI SQL names;
- rewrite common ones"""
- func.name = self.function_rewrites.get(func.name, func.name)
- return super(AccessCompiler, self).visit_function(func)
-
- def for_update_clause(self, select):
- """FOR UPDATE is not supported by Access; silently ignore"""
- return ''
-
- # Strip schema
- def visit_table(self, table, asfrom=False, **kwargs):
- if asfrom:
- return self.preparer.quote(table.name, table.quote)
- else:
- return ""
-
- def visit_join(self, join, asfrom=False, **kwargs):
- return (self.process(join.left, asfrom=True) + \
- (join.isouter and " LEFT OUTER JOIN " or " INNER JOIN ") + \
- self.process(join.right, asfrom=True) + " ON " + \
- self.process(join.onclause))
-
- def visit_extract(self, extract, **kw):
- field = self.extract_map.get(extract.field, extract.field)
- return 'DATEPART("%s", %s)' % \
- (field, self.process(extract.expr, **kw))
-
-class AccessDDLCompiler(compiler.DDLCompiler):
- def get_column_specification(self, column, **kwargs):
- colspec = self.preparer.format_column(column) + " " + \
- column.type.dialect_impl(self.dialect).get_col_spec()
-
- # install a sequence if we have an implicit IDENTITY column
- if (not getattr(column.table, 'has_sequence', False)) and \
- column.primary_key and \
- column.autoincrement and \
- isinstance(column.type, types.Integer) and \
- not column.foreign_keys:
- if column.default is None or \
- (isinstance(column.default, schema.Sequence) and
- column.default.optional):
- column.sequence = schema.Sequence(column.name + '_seq')
-
- if not column.nullable:
- colspec += " NOT NULL"
-
- if hasattr(column, 'sequence'):
- column.table.has_sequence = column
- colspec = self.preparer.format_column(column) + " counter"
- else:
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- return colspec
-
- def visit_drop_index(self, drop):
- index = drop.element
- self.append("\nDROP INDEX [%s].[%s]" % \
- (index.table.name,
- self._index_identifier(index.name)))
-
-class AccessIdentifierPreparer(compiler.IdentifierPreparer):
- reserved_words = compiler.RESERVED_WORDS.copy()
- reserved_words.update(['value', 'text'])
- def __init__(self, dialect):
- super(AccessIdentifierPreparer, self).\
- __init__(dialect, initial_quote='[', final_quote=']')
-
-
-dialect = AccessDialect
-dialect.poolclass = pool.SingletonThreadPool
-dialect.statement_compiler = AccessCompiler
-dialect.ddlcompiler = AccessDDLCompiler
-dialect.preparer = AccessIdentifierPreparer
-dialect.execution_ctx_cls = AccessExecutionContext
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/__init__.py
deleted file mode 100755
index bbd716f5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from sqlalchemy.dialects.drizzle import base, mysqldb
-
-# default dialect
-base.dialect = mysqldb.dialect
-
-from sqlalchemy.dialects.drizzle.base import \
- BIGINT, BINARY, BLOB, BOOLEAN, CHAR, DATE, DATETIME, \
- DECIMAL, DOUBLE, ENUM, \
- FLOAT, INTEGER, \
- NUMERIC, REAL, TEXT, TIME, TIMESTAMP, \
- VARBINARY, VARCHAR, dialect
-
-__all__ = (
-'BIGINT', 'BINARY', 'BLOB', 'BOOLEAN', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'DOUBLE',
-'ENUM', 'FLOAT', 'INTEGER',
-'NUMERIC', 'SET', 'REAL', 'TEXT', 'TIME', 'TIMESTAMP',
-'VARBINARY', 'VARCHAR', 'dialect'
-)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/base.py
deleted file mode 100755
index ca2678e5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/base.py
+++ /dev/null
@@ -1,582 +0,0 @@
-# drizzle/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# Copyright (C) 2010-2011 Monty Taylor <mordred@inaugust.com>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Drizzle database.
-
-Supported Versions and Features
--------------------------------
-
-SQLAlchemy supports the Drizzle database starting with 2010.08.
-with capabilities increasing with more modern servers.
-
-Most available DBAPI drivers are supported; see below.
-
-===================================== ===============
-Feature Minimum Version
-===================================== ===============
-sqlalchemy.orm 2010.08
-Table Reflection 2010.08
-DDL Generation 2010.08
-utf8/Full Unicode Connections 2010.08
-Transactions 2010.08
-Two-Phase Transactions 2010.08
-Nested Transactions 2010.08
-===================================== ===============
-
-See the official Drizzle documentation for detailed information about features
-supported in any given server release.
-
-Connecting
-----------
-
-See the API documentation on individual drivers for details on connecting.
-
-Connection Timeouts
--------------------
-
-Drizzle features an automatic connection close behavior, for connections that
-have been idle for eight hours or more. To circumvent having this issue, use
-the ``pool_recycle`` option which controls the maximum age of any connection::
-
- engine = create_engine('drizzle+mysqldb://...', pool_recycle=3600)
-
-Storage Engines
----------------
-
-Drizzle defaults to the ``InnoDB`` storage engine, which is transactional.
-
-Storage engines can be elected when creating tables in SQLAlchemy by supplying
-a ``drizzle_engine='whatever'`` to the ``Table`` constructor. Any Drizzle table
-creation option can be specified in this syntax::
-
- Table('mytable', metadata,
- Column('data', String(32)),
- drizzle_engine='InnoDB',
- )
-
-Keys
-----
-
-Not all Drizzle storage engines support foreign keys. For ``BlitzDB`` and
-similar engines, the information loaded by table reflection will not include
-foreign keys. For these tables, you may supply a
-:class:`~sqlalchemy.ForeignKeyConstraint` at reflection time::
-
- Table('mytable', metadata,
- ForeignKeyConstraint(['other_id'], ['othertable.other_id']),
- autoload=True
- )
-
-When creating tables, SQLAlchemy will automatically set ``AUTO_INCREMENT`` on
-an integer primary key column::
-
- >>> t = Table('mytable', metadata,
- ... Column('mytable_id', Integer, primary_key=True)
- ... )
- >>> t.create()
- CREATE TABLE mytable (
- id INTEGER NOT NULL AUTO_INCREMENT,
- PRIMARY KEY (id)
- )
-
-You can disable this behavior by supplying ``autoincrement=False`` to the
-:class:`~sqlalchemy.Column`. This flag can also be used to enable
-auto-increment on a secondary column in a multi-column key for some storage
-engines::
-
- Table('mytable', metadata,
- Column('gid', Integer, primary_key=True, autoincrement=False),
- Column('id', Integer, primary_key=True)
- )
-
-Drizzle SQL Extensions
-----------------------
-
-Many of the Drizzle SQL extensions are handled through SQLAlchemy's generic
-function and operator support::
-
- table.select(table.c.password==func.md5('plaintext'))
- table.select(table.c.username.op('regexp')('^[a-d]'))
-
-And of course any valid Drizzle statement can be executed as a string as well.
-
-Some limited direct support for Drizzle extensions to SQL is currently
-available.
-
-* SELECT pragma::
-
- select(..., prefixes=['HIGH_PRIORITY', 'SQL_SMALL_RESULT'])
-
-* UPDATE with LIMIT::
-
- update(..., drizzle_limit=10)
-
-"""
-
-import datetime, inspect, re, sys
-
-from sqlalchemy import schema as sa_schema
-from sqlalchemy import exc, log, sql, util
-from sqlalchemy.sql import operators as sql_operators
-from sqlalchemy.sql import functions as sql_functions
-from sqlalchemy.sql import compiler
-from array import array as _array
-
-from sqlalchemy.engine import reflection
-from sqlalchemy.engine import base as engine_base, default
-from sqlalchemy import types as sqltypes
-from sqlalchemy.dialects.mysql import base as mysql_dialect
-
-from sqlalchemy.types import DATE, DATETIME, BOOLEAN, TIME, \
- BLOB, BINARY, VARBINARY
-
-class _NumericType(object):
- """Base for Drizzle numeric types."""
-
- def __init__(self, **kw):
- super(_NumericType, self).__init__(**kw)
-
-class _FloatType(_NumericType, sqltypes.Float):
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- if isinstance(self, (REAL, DOUBLE)) and \
- (
- (precision is None and scale is not None) or
- (precision is not None and scale is None)
- ):
- raise exc.ArgumentError(
- "You must specify both precision and scale or omit "
- "both altogether.")
-
- super(_FloatType, self).__init__(precision=precision, asdecimal=asdecimal, **kw)
- self.scale = scale
-
-class _StringType(mysql_dialect._StringType):
- """Base for Drizzle string types."""
-
- def __init__(self, collation=None,
- binary=False,
- **kw):
- kw['national'] = False
- super(_StringType, self).__init__(collation=collation,
- binary=binary,
- **kw)
-
-
-class NUMERIC(_NumericType, sqltypes.NUMERIC):
- """Drizzle NUMERIC type."""
-
- __visit_name__ = 'NUMERIC'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a NUMERIC.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- """
- super(NUMERIC, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
-
-
-class DECIMAL(_NumericType, sqltypes.DECIMAL):
- """Drizzle DECIMAL type."""
-
- __visit_name__ = 'DECIMAL'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a DECIMAL.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- """
- super(DECIMAL, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
-
-class DOUBLE(_FloatType):
- """Drizzle DOUBLE type."""
-
- __visit_name__ = 'DOUBLE'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a DOUBLE.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- """
- super(DOUBLE, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
-class REAL(_FloatType, sqltypes.REAL):
- """Drizzle REAL type."""
-
- __visit_name__ = 'REAL'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a REAL.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- """
- super(REAL, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
-class FLOAT(_FloatType, sqltypes.FLOAT):
- """Drizzle FLOAT type."""
-
- __visit_name__ = 'FLOAT'
-
- def __init__(self, precision=None, scale=None, asdecimal=False, **kw):
- """Construct a FLOAT.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- """
- super(FLOAT, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
- def bind_processor(self, dialect):
- return None
-
-class INTEGER(sqltypes.INTEGER):
- """Drizzle INTEGER type."""
-
- __visit_name__ = 'INTEGER'
-
- def __init__(self, **kw):
- """Construct an INTEGER.
-
- """
- super(INTEGER, self).__init__(**kw)
-
-class BIGINT(sqltypes.BIGINT):
- """Drizzle BIGINTEGER type."""
-
- __visit_name__ = 'BIGINT'
-
- def __init__(self, **kw):
- """Construct a BIGINTEGER.
-
- """
- super(BIGINT, self).__init__(**kw)
-
-
-class _DrizzleTime(mysql_dialect._MSTime):
- """Drizzle TIME type."""
-
-class TIMESTAMP(sqltypes.TIMESTAMP):
- """Drizzle TIMESTAMP type."""
- __visit_name__ = 'TIMESTAMP'
-
-class TEXT(_StringType, sqltypes.TEXT):
- """Drizzle TEXT type, for text up to 2^16 characters."""
-
- __visit_name__ = 'TEXT'
-
- def __init__(self, length=None, **kw):
- """Construct a TEXT.
-
- :param length: Optional, if provided the server may optimize storage
- by substituting the smallest TEXT type sufficient to store
- ``length`` characters.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(TEXT, self).__init__(length=length, **kw)
-
-class VARCHAR(_StringType, sqltypes.VARCHAR):
- """Drizzle VARCHAR type, for variable-length character data."""
-
- __visit_name__ = 'VARCHAR'
-
- def __init__(self, length=None, **kwargs):
- """Construct a VARCHAR.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(VARCHAR, self).__init__(length=length, **kwargs)
-
-class CHAR(_StringType, sqltypes.CHAR):
- """Drizzle CHAR type, for fixed-length character data."""
-
- __visit_name__ = 'CHAR'
-
- def __init__(self, length=None, **kwargs):
- """Construct a CHAR.
-
- :param length: Maximum data length, in characters.
-
- :param binary: Optional, use the default binary collation for the
- national character set. This does not affect the type of data
- stored, use a BINARY type for binary data.
-
- :param collation: Optional, request a particular collation. Must be
- compatible with the national character set.
-
- """
- super(CHAR, self).__init__(length=length, **kwargs)
-
-class ENUM(mysql_dialect.ENUM):
- """Drizzle ENUM type."""
-
- def __init__(self, *enums, **kw):
- """Construct an ENUM.
-
- Example:
-
- Column('myenum', ENUM("foo", "bar", "baz"))
-
- :param enums: The range of valid values for this ENUM. Values will be
- quoted when generating the schema according to the quoting flag (see
- below).
-
- :param strict: Defaults to False: ensure that a given value is in this
- ENUM's range of permissible values when inserting or updating rows.
- Note that Drizzle will not raise a fatal error if you attempt to store
- an out of range value- an alternate value will be stored instead.
- (See Drizzle ENUM documentation.)
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- :param quoting: Defaults to 'auto': automatically determine enum value
- quoting. If all enum values are surrounded by the same quoting
- character, then use 'quoted' mode. Otherwise, use 'unquoted' mode.
-
- 'quoted': values in enums are already quoted, they will be used
- directly when generating the schema - this usage is deprecated.
-
- 'unquoted': values in enums are not quoted, they will be escaped and
- surrounded by single quotes when generating the schema.
-
- Previous versions of this type always required manually quoted
- values to be supplied; future versions will always quote the string
- literals for you. This is a transitional option.
-
- """
- super(ENUM, self).__init__(*enums, **kw)
-
-class _DrizzleBoolean(sqltypes.Boolean):
- def get_dbapi_type(self, dbapi):
- return dbapi.NUMERIC
-
-colspecs = {
- sqltypes.Numeric: NUMERIC,
- sqltypes.Float: FLOAT,
- sqltypes.Time: _DrizzleTime,
- sqltypes.Enum: ENUM,
- sqltypes.Boolean: _DrizzleBoolean,
-}
-
-# All the types we have in Drizzle
-ischema_names = {
- 'BIGINT': BIGINT,
- 'BINARY': BINARY,
- 'BLOB': BLOB,
- 'BOOLEAN': BOOLEAN,
- 'CHAR': CHAR,
- 'DATE': DATE,
- 'DATETIME': DATETIME,
- 'DECIMAL': DECIMAL,
- 'DOUBLE': DOUBLE,
- 'ENUM': ENUM,
- 'FLOAT': FLOAT,
- 'INT': INTEGER,
- 'INTEGER': INTEGER,
- 'NUMERIC': NUMERIC,
- 'TEXT': TEXT,
- 'TIME': TIME,
- 'TIMESTAMP': TIMESTAMP,
- 'VARBINARY': VARBINARY,
- 'VARCHAR': VARCHAR,
-}
-
-class DrizzleCompiler(mysql_dialect.MySQLCompiler):
-
- def visit_typeclause(self, typeclause):
- type_ = typeclause.type.dialect_impl(self.dialect)
- if isinstance(type_, sqltypes.Integer):
- return 'INTEGER'
- else:
- return super(DrizzleCompiler, self).visit_typeclause(typeclause)
-
- def visit_cast(self, cast, **kwargs):
- type_ = self.process(cast.typeclause)
- if type_ is None:
- return self.process(cast.clause)
-
- return 'CAST(%s AS %s)' % (self.process(cast.clause), type_)
-
-
-class DrizzleDDLCompiler(mysql_dialect.MySQLDDLCompiler):
- pass
-
-class DrizzleTypeCompiler(mysql_dialect.MySQLTypeCompiler):
- def _extend_numeric(self, type_, spec):
- return spec
-
- def _extend_string(self, type_, defaults, spec):
- """Extend a string-type declaration with standard SQL
- COLLATE annotations and Drizzle specific extensions.
-
- """
-
- def attr(name):
- return getattr(type_, name, defaults.get(name))
-
- if attr('collation'):
- collation = 'COLLATE %s' % type_.collation
- elif attr('binary'):
- collation = 'BINARY'
- else:
- collation = None
-
- return ' '.join([c for c in (spec, collation)
- if c is not None])
-
- def visit_NCHAR(self, type):
- raise NotImplementedError("Drizzle does not support NCHAR")
-
- def visit_NVARCHAR(self, type):
- raise NotImplementedError("Drizzle does not support NVARCHAR")
-
- def visit_FLOAT(self, type_):
- if type_.scale is not None and type_.precision is not None:
- return "FLOAT(%s, %s)" % (type_.precision, type_.scale)
- else:
- return "FLOAT"
-
- def visit_BOOLEAN(self, type_):
- return "BOOLEAN"
-
- def visit_BLOB(self, type_):
- return "BLOB"
-
-
-class DrizzleExecutionContext(mysql_dialect.MySQLExecutionContext):
- pass
-
-class DrizzleIdentifierPreparer(mysql_dialect.MySQLIdentifierPreparer):
- pass
-
-class DrizzleDialect(mysql_dialect.MySQLDialect):
- """Details of the Drizzle dialect. Not used directly in application code."""
-
- name = 'drizzle'
-
- _supports_cast = True
- supports_sequences = False
- supports_native_boolean = True
- supports_views = False
-
-
- default_paramstyle = 'format'
- colspecs = colspecs
-
- statement_compiler = DrizzleCompiler
- ddl_compiler = DrizzleDDLCompiler
- type_compiler = DrizzleTypeCompiler
- ischema_names = ischema_names
- preparer = DrizzleIdentifierPreparer
-
- def on_connect(self):
- """Force autocommit - Drizzle Bug#707842 doesn't set this
- properly"""
- def connect(conn):
- conn.autocommit(False)
- return connect
-
- def do_commit(self, connection):
- """Execute a COMMIT."""
-
- connection.commit()
-
- def do_rollback(self, connection):
- """Execute a ROLLBACK."""
-
- connection.rollback()
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- """Return a Unicode SHOW TABLES from a given schema."""
- if schema is not None:
- current_schema = schema
- else:
- current_schema = self.default_schema_name
-
- charset = 'utf8'
- rp = connection.execute("SHOW TABLES FROM %s" %
- self.identifier_preparer.quote_identifier(current_schema))
- return [row[0] for row in self._compat_fetchall(rp, charset=charset)]
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- raise NotImplementedError
-
- def _detect_casing(self, connection):
- """Sniff out identifier case sensitivity.
-
- Cached per-connection. This value can not change without a server
- restart.
-
- """
- return 0
-
- def _detect_collations(self, connection):
- """Pull the active COLLATIONS list from the server.
-
- Cached per-connection.
- """
-
- collations = {}
- charset = self._connection_charset
- rs = connection.execute('SELECT CHARACTER_SET_NAME, COLLATION_NAME from data_dictionary.COLLATIONS')
- for row in self._compat_fetchall(rs, charset):
- collations[row[0]] = row[1]
- return collations
-
- def _detect_ansiquotes(self, connection):
- """Detect and adjust for the ANSI_QUOTES sql mode."""
-
- self._server_ansiquotes = False
-
- self._backslash_escapes = False
-
-log.class_logger(DrizzleDialect)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/mysqldb.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/mysqldb.py
deleted file mode 100755
index dcf02609..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/drizzle/mysqldb.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""Support for the Drizzle database via the Drizzle-python adapter.
-
-Drizzle-Python is available at:
-
- http://sourceforge.net/projects/mysql-python
-
-At least version 1.2.1 or 1.2.2 should be used.
-
-Connecting
------------
-
-Connect string format::
-
- drizzle+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
-
-Character Sets
---------------
-
-Drizzle is all utf8 all the time.
-
-Known Issues
--------------
-
-Drizzle-python at least as of version 1.2.2 has a serious memory leak related
-to unicode conversion, a feature which is disabled via ``use_unicode=0``.
-The recommended connection form with SQLAlchemy is::
-
- engine = create_engine('mysql://scott:tiger@localhost/test?charset=utf8&use_unicode=0', pool_recycle=3600)
-
-
-"""
-
-from sqlalchemy.dialects.drizzle.base import (DrizzleDialect,
- DrizzleExecutionContext,
- DrizzleCompiler, DrizzleIdentifierPreparer)
-from sqlalchemy.connectors.mysqldb import (
- MySQLDBExecutionContext,
- MySQLDBCompiler,
- MySQLDBIdentifierPreparer,
- MySQLDBConnector
- )
-
-class DrizzleExecutionContext_mysqldb(
- MySQLDBExecutionContext,
- DrizzleExecutionContext):
- pass
-
-
-class DrizzleCompiler_mysqldb(MySQLDBCompiler, DrizzleCompiler):
- pass
-
-
-class DrizzleIdentifierPreparer_mysqldb(
- MySQLDBIdentifierPreparer,
- DrizzleIdentifierPreparer):
- pass
-
-class DrizzleDialect_mysqldb(MySQLDBConnector, DrizzleDialect):
- execution_ctx_cls = DrizzleExecutionContext_mysqldb
- statement_compiler = DrizzleCompiler_mysqldb
- preparer = DrizzleIdentifierPreparer_mysqldb
-
- def _detect_charset(self, connection):
- """Sniff out the character set in use for connection results."""
- return 'utf8'
-
-
-dialect = DrizzleDialect_mysqldb
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/__init__.py
deleted file mode 100755
index e87b5bb5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# firebird/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.firebird import base, kinterbasdb
-
-base.dialect = kinterbasdb.dialect
-
-from sqlalchemy.dialects.firebird.base import \
- SMALLINT, BIGINT, FLOAT, FLOAT, DATE, TIME, \
- TEXT, NUMERIC, FLOAT, TIMESTAMP, VARCHAR, CHAR, BLOB,\
- dialect
-
-__all__ = (
- 'SMALLINT', 'BIGINT', 'FLOAT', 'FLOAT', 'DATE', 'TIME',
- 'TEXT', 'NUMERIC', 'FLOAT', 'TIMESTAMP', 'VARCHAR', 'CHAR', 'BLOB',
- 'dialect'
-)
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/base.py
deleted file mode 100755
index 5f07b57b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/base.py
+++ /dev/null
@@ -1,700 +0,0 @@
-# firebird/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for the Firebird database.
-
-Connectivity is usually supplied via the kinterbasdb_ DBAPI module.
-
-Dialects
-~~~~~~~~
-
-Firebird offers two distinct dialects_ (not to be confused with a
-SQLAlchemy ``Dialect``):
-
-dialect 1
- This is the old syntax and behaviour, inherited from Interbase pre-6.0.
-
-dialect 3
- This is the newer and supported syntax, introduced in Interbase 6.0.
-
-The SQLAlchemy Firebird dialect detects these versions and
-adjusts its representation of SQL accordingly. However,
-support for dialect 1 is not well tested and probably has
-incompatibilities.
-
-Locking Behavior
-~~~~~~~~~~~~~~~~
-
-Firebird locks tables aggressively. For this reason, a DROP TABLE may
-hang until other transactions are released. SQLAlchemy does its best
-to release transactions as quickly as possible. The most common cause
-of hanging transactions is a non-fully consumed result set, i.e.::
-
- result = engine.execute("select * from table")
- row = result.fetchone()
- return
-
-Where above, the ``ResultProxy`` has not been fully consumed. The
-connection will be returned to the pool and the transactional state
-rolled back once the Python garbage collector reclaims the objects
-which hold onto the connection, which often occurs asynchronously.
-The above use case can be alleviated by calling ``first()`` on the
-``ResultProxy`` which will fetch the first row and immediately close
-all remaining cursor/connection resources.
-
-RETURNING support
-~~~~~~~~~~~~~~~~~
-
-Firebird 2.0 supports returning a result set from inserts, and 2.1
-extends that to deletes and updates. This is generically exposed by
-the SQLAlchemy ``returning()`` method, such as::
-
- # INSERT..RETURNING
- result = table.insert().returning(table.c.col1, table.c.col2).\\
- values(name='foo')
- print result.fetchall()
-
- # UPDATE..RETURNING
- raises = empl.update().returning(empl.c.id, empl.c.salary).\\
- where(empl.c.sales>100).\\
- values(dict(salary=empl.c.salary * 1.1))
- print raises.fetchall()
-
-
-.. _dialects: http://mc-computing.com/Databases/Firebird/SQL_Dialect.html
-
-"""
-
-import datetime, re
-
-from sqlalchemy import schema as sa_schema
-from sqlalchemy import exc, types as sqltypes, sql, util
-from sqlalchemy.sql import expression
-from sqlalchemy.engine import base, default, reflection
-from sqlalchemy.sql import compiler
-
-
-from sqlalchemy.types import (BIGINT, BLOB, BOOLEAN, DATE,
- FLOAT, INTEGER, NUMERIC, SMALLINT,
- TEXT, TIME, TIMESTAMP)
-
-
-RESERVED_WORDS = set([
- "active", "add", "admin", "after", "all", "alter", "and", "any", "as",
- "asc", "ascending", "at", "auto", "avg", "before", "begin", "between",
- "bigint", "bit_length", "blob", "both", "by", "case", "cast", "char",
- "character", "character_length", "char_length", "check", "close",
- "collate", "column", "commit", "committed", "computed", "conditional",
- "connect", "constraint", "containing", "count", "create", "cross",
- "cstring", "current", "current_connection", "current_date",
- "current_role", "current_time", "current_timestamp",
- "current_transaction", "current_user", "cursor", "database", "date",
- "day", "dec", "decimal", "declare", "default", "delete", "desc",
- "descending", "disconnect", "distinct", "do", "domain", "double",
- "drop", "else", "end", "entry_point", "escape", "exception",
- "execute", "exists", "exit", "external", "extract", "fetch", "file",
- "filter", "float", "for", "foreign", "from", "full", "function",
- "gdscode", "generator", "gen_id", "global", "grant", "group",
- "having", "hour", "if", "in", "inactive", "index", "inner",
- "input_type", "insensitive", "insert", "int", "integer", "into", "is",
- "isolation", "join", "key", "leading", "left", "length", "level",
- "like", "long", "lower", "manual", "max", "maximum_segment", "merge",
- "min", "minute", "module_name", "month", "names", "national",
- "natural", "nchar", "no", "not", "null", "numeric", "octet_length",
- "of", "on", "only", "open", "option", "or", "order", "outer",
- "output_type", "overflow", "page", "pages", "page_size", "parameter",
- "password", "plan", "position", "post_event", "precision", "primary",
- "privileges", "procedure", "protected", "rdb$db_key", "read", "real",
- "record_version", "recreate", "recursive", "references", "release",
- "reserv", "reserving", "retain", "returning_values", "returns",
- "revoke", "right", "rollback", "rows", "row_count", "savepoint",
- "schema", "second", "segment", "select", "sensitive", "set", "shadow",
- "shared", "singular", "size", "smallint", "snapshot", "some", "sort",
- "sqlcode", "stability", "start", "starting", "starts", "statistics",
- "sub_type", "sum", "suspend", "table", "then", "time", "timestamp",
- "to", "trailing", "transaction", "trigger", "trim", "uncommitted",
- "union", "unique", "update", "upper", "user", "using", "value",
- "values", "varchar", "variable", "varying", "view", "wait", "when",
- "where", "while", "with", "work", "write", "year",
- ])
-
-
-class _StringType(sqltypes.String):
- """Base for Firebird string types."""
-
- def __init__(self, charset = None, **kw):
- self.charset = charset
- super(_StringType, self).__init__(**kw)
-
-class VARCHAR(_StringType, sqltypes.VARCHAR):
- """Firebird VARCHAR type"""
- __visit_name__ = 'VARCHAR'
-
- def __init__(self, length = None, **kwargs):
- super(VARCHAR, self).__init__(length=length, **kwargs)
-
-class CHAR(_StringType, sqltypes.CHAR):
- """Firebird CHAR type"""
- __visit_name__ = 'CHAR'
-
- def __init__(self, length = None, **kwargs):
- super(CHAR, self).__init__(length=length, **kwargs)
-
-colspecs = {
-}
-
-ischema_names = {
- 'SHORT': SMALLINT,
- 'LONG': BIGINT,
- 'QUAD': FLOAT,
- 'FLOAT': FLOAT,
- 'DATE': DATE,
- 'TIME': TIME,
- 'TEXT': TEXT,
- 'INT64': NUMERIC,
- 'DOUBLE': FLOAT,
- 'TIMESTAMP': TIMESTAMP,
- 'VARYING': VARCHAR,
- 'CSTRING': CHAR,
- 'BLOB': BLOB,
- }
-
-
-# TODO: date conversion types (should be implemented as _FBDateTime,
-# _FBDate, etc. as bind/result functionality is required)
-
-class FBTypeCompiler(compiler.GenericTypeCompiler):
- def visit_boolean(self, type_):
- return self.visit_SMALLINT(type_)
-
- def visit_datetime(self, type_):
- return self.visit_TIMESTAMP(type_)
-
- def visit_TEXT(self, type_):
- return "BLOB SUB_TYPE 1"
-
- def visit_BLOB(self, type_):
- return "BLOB SUB_TYPE 0"
-
- def _extend_string(self, type_, basic):
- charset = getattr(type_, 'charset', None)
- if charset is None:
- return basic
- else:
- return '%s CHARACTER SET %s' % (basic, charset)
-
- def visit_CHAR(self, type_):
- basic = super(FBTypeCompiler, self).visit_CHAR(type_)
- return self._extend_string(type_, basic)
-
- def visit_VARCHAR(self, type_):
- basic = super(FBTypeCompiler, self).visit_VARCHAR(type_)
- return self._extend_string(type_, basic)
-
-
-
-class FBCompiler(sql.compiler.SQLCompiler):
- """Firebird specific idiosincrasies"""
-
- def visit_mod(self, binary, **kw):
- # Firebird lacks a builtin modulo operator, but there is
- # an equivalent function in the ib_udf library.
- return "mod(%s, %s)" % (
- self.process(binary.left),
- self.process(binary.right))
-
- def visit_alias(self, alias, asfrom=False, **kwargs):
- if self.dialect._version_two:
- return super(FBCompiler, self).\
- visit_alias(alias, asfrom=asfrom, **kwargs)
- else:
- # Override to not use the AS keyword which FB 1.5 does not like
- if asfrom:
- alias_name = isinstance(alias.name,
- expression._generated_label) and \
- self._truncated_identifier("alias",
- alias.name) or alias.name
-
- return self.process(
- alias.original, asfrom=asfrom, **kwargs) + \
- " " + \
- self.preparer.format_alias(alias, alias_name)
- else:
- return self.process(alias.original, **kwargs)
-
- def visit_substring_func(self, func, **kw):
- s = self.process(func.clauses.clauses[0])
- start = self.process(func.clauses.clauses[1])
- if len(func.clauses.clauses) > 2:
- length = self.process(func.clauses.clauses[2])
- return "SUBSTRING(%s FROM %s FOR %s)" % (s, start, length)
- else:
- return "SUBSTRING(%s FROM %s)" % (s, start)
-
- def visit_length_func(self, function, **kw):
- if self.dialect._version_two:
- return "char_length" + self.function_argspec(function)
- else:
- return "strlen" + self.function_argspec(function)
-
- visit_char_length_func = visit_length_func
-
- def function_argspec(self, func, **kw):
- # TODO: this probably will need to be
- # narrowed to a fixed list, some no-arg functions
- # may require parens - see similar example in the oracle
- # dialect
- if func.clauses is not None and len(func.clauses):
- return self.process(func.clause_expr)
- else:
- return ""
-
- def default_from(self):
- return " FROM rdb$database"
-
- def visit_sequence(self, seq):
- return "gen_id(%s, 1)" % self.preparer.format_sequence(seq)
-
- def get_select_precolumns(self, select):
- """Called when building a ``SELECT`` statement, position is just
- before column list Firebird puts the limit and offset right
- after the ``SELECT``...
- """
-
- result = ""
- if select._limit:
- result += "FIRST %s " % self.process(sql.literal(select._limit))
- if select._offset:
- result +="SKIP %s " % self.process(sql.literal(select._offset))
- if select._distinct:
- result += "DISTINCT "
- return result
-
- def limit_clause(self, select):
- """Already taken care of in the `get_select_precolumns` method."""
-
- return ""
-
- def returning_clause(self, stmt, returning_cols):
-
- columns = [
- self.process(
- self.label_select_column(None, c, asfrom=False),
- within_columns_clause=True,
- result_map=self.result_map
- )
- for c in expression._select_iterables(returning_cols)
- ]
- return 'RETURNING ' + ', '.join(columns)
-
-
-class FBDDLCompiler(sql.compiler.DDLCompiler):
- """Firebird syntactic idiosincrasies"""
-
- def visit_create_sequence(self, create):
- """Generate a ``CREATE GENERATOR`` statement for the sequence."""
-
- # no syntax for these
- # http://www.firebirdsql.org/manual/generatorguide-sqlsyntax.html
- if create.element.start is not None:
- raise NotImplemented(
- "Firebird SEQUENCE doesn't support START WITH")
- if create.element.increment is not None:
- raise NotImplemented(
- "Firebird SEQUENCE doesn't support INCREMENT BY")
-
- if self.dialect._version_two:
- return "CREATE SEQUENCE %s" % \
- self.preparer.format_sequence(create.element)
- else:
- return "CREATE GENERATOR %s" % \
- self.preparer.format_sequence(create.element)
-
- def visit_drop_sequence(self, drop):
- """Generate a ``DROP GENERATOR`` statement for the sequence."""
-
- if self.dialect._version_two:
- return "DROP SEQUENCE %s" % \
- self.preparer.format_sequence(drop.element)
- else:
- return "DROP GENERATOR %s" % \
- self.preparer.format_sequence(drop.element)
-
-
-class FBIdentifierPreparer(sql.compiler.IdentifierPreparer):
- """Install Firebird specific reserved words."""
-
- reserved_words = RESERVED_WORDS
-
- def __init__(self, dialect):
- super(FBIdentifierPreparer, self).__init__(dialect, omit_schema=True)
-
-
-class FBExecutionContext(default.DefaultExecutionContext):
- def fire_sequence(self, seq, type_):
- """Get the next value from the sequence using ``gen_id()``."""
-
- return self._execute_scalar(
- "SELECT gen_id(%s, 1) FROM rdb$database" %
- self.dialect.identifier_preparer.format_sequence(seq),
- type_
- )
-
-
-class FBDialect(default.DefaultDialect):
- """Firebird dialect"""
-
- name = 'firebird'
-
- max_identifier_length = 31
-
- supports_sequences = True
- sequences_optional = False
- supports_default_values = True
- postfetch_lastrowid = False
-
- supports_native_boolean = False
-
- requires_name_normalize = True
- supports_empty_insert = False
-
- statement_compiler = FBCompiler
- ddl_compiler = FBDDLCompiler
- preparer = FBIdentifierPreparer
- type_compiler = FBTypeCompiler
- execution_ctx_cls = FBExecutionContext
-
- colspecs = colspecs
- ischema_names = ischema_names
-
- # defaults to dialect ver. 3,
- # will be autodetected off upon
- # first connect
- _version_two = True
-
- def initialize(self, connection):
- super(FBDialect, self).initialize(connection)
- self._version_two = ('firebird' in self.server_version_info and \
- self.server_version_info >= (2, )
- ) or \
- ('interbase' in self.server_version_info and \
- self.server_version_info >= (6, )
- )
-
- if not self._version_two:
- # TODO: whatever other pre < 2.0 stuff goes here
- self.ischema_names = ischema_names.copy()
- self.ischema_names['TIMESTAMP'] = sqltypes.DATE
- self.colspecs = {
- sqltypes.DateTime: sqltypes.DATE
- }
-
- self.implicit_returning = self._version_two and \
- self.__dict__.get('implicit_returning', True)
-
- def normalize_name(self, name):
- # Remove trailing spaces: FB uses a CHAR() type,
- # that is padded with spaces
- name = name and name.rstrip()
- if name is None:
- return None
- elif name.upper() == name and \
- not self.identifier_preparer._requires_quotes(name.lower()):
- return name.lower()
- else:
- return name
-
- def denormalize_name(self, name):
- if name is None:
- return None
- elif name.lower() == name and \
- not self.identifier_preparer._requires_quotes(name.lower()):
- return name.upper()
- else:
- return name
-
- def has_table(self, connection, table_name, schema=None):
- """Return ``True`` if the given table exists, ignoring
- the `schema`."""
-
- tblqry = """
- SELECT 1 AS has_table FROM rdb$database
- WHERE EXISTS (SELECT rdb$relation_name
- FROM rdb$relations
- WHERE rdb$relation_name=?)
- """
- c = connection.execute(tblqry, [self.denormalize_name(table_name)])
- return c.first() is not None
-
- def has_sequence(self, connection, sequence_name, schema=None):
- """Return ``True`` if the given sequence (generator) exists."""
-
- genqry = """
- SELECT 1 AS has_sequence FROM rdb$database
- WHERE EXISTS (SELECT rdb$generator_name
- FROM rdb$generators
- WHERE rdb$generator_name=?)
- """
- c = connection.execute(genqry, [self.denormalize_name(sequence_name)])
- return c.first() is not None
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- s = """
- SELECT DISTINCT rdb$relation_name
- FROM rdb$relation_fields
- WHERE rdb$system_flag=0 AND rdb$view_context IS NULL
- """
- return [self.normalize_name(row[0]) for row in connection.execute(s)]
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- s = """
- SELECT distinct rdb$view_name
- FROM rdb$view_relations
- """
- return [self.normalize_name(row[0]) for row in connection.execute(s)]
-
- @reflection.cache
- def get_view_definition(self, connection, view_name, schema=None, **kw):
- qry = """
- SELECT rdb$view_source AS view_source
- FROM rdb$relations
- WHERE rdb$relation_name=?
- """
- rp = connection.execute(qry, [self.denormalize_name(view_name)])
- row = rp.first()
- if row:
- return row['view_source']
- else:
- return None
-
- @reflection.cache
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- # Query to extract the PK/FK constrained fields of the given table
- keyqry = """
- SELECT se.rdb$field_name AS fname
- FROM rdb$relation_constraints rc
- JOIN rdb$index_segments se ON rc.rdb$index_name=se.rdb$index_name
- WHERE rc.rdb$constraint_type=? AND rc.rdb$relation_name=?
- """
- tablename = self.denormalize_name(table_name)
- # get primary key fields
- c = connection.execute(keyqry, ["PRIMARY KEY", tablename])
- pkfields = [self.normalize_name(r['fname']) for r in c.fetchall()]
- return pkfields
-
- @reflection.cache
- def get_column_sequence(self, connection,
- table_name, column_name,
- schema=None, **kw):
- tablename = self.denormalize_name(table_name)
- colname = self.denormalize_name(column_name)
- # Heuristic-query to determine the generator associated to a PK field
- genqry = """
- SELECT trigdep.rdb$depended_on_name AS fgenerator
- FROM rdb$dependencies tabdep
- JOIN rdb$dependencies trigdep
- ON tabdep.rdb$dependent_name=trigdep.rdb$dependent_name
- AND trigdep.rdb$depended_on_type=14
- AND trigdep.rdb$dependent_type=2
- JOIN rdb$triggers trig ON
- trig.rdb$trigger_name=tabdep.rdb$dependent_name
- WHERE tabdep.rdb$depended_on_name=?
- AND tabdep.rdb$depended_on_type=0
- AND trig.rdb$trigger_type=1
- AND tabdep.rdb$field_name=?
- AND (SELECT count(*)
- FROM rdb$dependencies trigdep2
- WHERE trigdep2.rdb$dependent_name = trigdep.rdb$dependent_name) = 2
- """
- genr = connection.execute(genqry, [tablename, colname]).first()
- if genr is not None:
- return dict(name=self.normalize_name(genr['fgenerator']))
-
- @reflection.cache
- def get_columns(self, connection, table_name, schema=None, **kw):
- # Query to extract the details of all the fields of the given table
- tblqry = """
- SELECT r.rdb$field_name AS fname,
- r.rdb$null_flag AS null_flag,
- t.rdb$type_name AS ftype,
- f.rdb$field_sub_type AS stype,
- f.rdb$field_length/
- COALESCE(cs.rdb$bytes_per_character,1) AS flen,
- f.rdb$field_precision AS fprec,
- f.rdb$field_scale AS fscale,
- COALESCE(r.rdb$default_source,
- f.rdb$default_source) AS fdefault
- FROM rdb$relation_fields r
- JOIN rdb$fields f ON r.rdb$field_source=f.rdb$field_name
- JOIN rdb$types t
- ON t.rdb$type=f.rdb$field_type AND
- t.rdb$field_name='RDB$FIELD_TYPE'
- LEFT JOIN rdb$character_sets cs ON
- f.rdb$character_set_id=cs.rdb$character_set_id
- WHERE f.rdb$system_flag=0 AND r.rdb$relation_name=?
- ORDER BY r.rdb$field_position
- """
- # get the PK, used to determine the eventual associated sequence
- pkey_cols = self.get_primary_keys(connection, table_name)
-
- tablename = self.denormalize_name(table_name)
- # get all of the fields for this table
- c = connection.execute(tblqry, [tablename])
- cols = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- name = self.normalize_name(row['fname'])
- orig_colname = row['fname']
-
- # get the data type
- colspec = row['ftype'].rstrip()
- coltype = self.ischema_names.get(colspec)
- if coltype is None:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (colspec, name))
- coltype = sqltypes.NULLTYPE
- elif colspec == 'INT64':
- coltype = coltype(
- precision=row['fprec'],
- scale=row['fscale'] * -1)
- elif colspec in ('VARYING', 'CSTRING'):
- coltype = coltype(row['flen'])
- elif colspec == 'TEXT':
- coltype = TEXT(row['flen'])
- elif colspec == 'BLOB':
- if row['stype'] == 1:
- coltype = TEXT()
- else:
- coltype = BLOB()
- else:
- coltype = coltype()
-
- # does it have a default value?
- defvalue = None
- if row['fdefault'] is not None:
- # the value comes down as "DEFAULT 'value'": there may be
- # more than one whitespace around the "DEFAULT" keyword
- # and it may also be lower case
- # (see also http://tracker.firebirdsql.org/browse/CORE-356)
- defexpr = row['fdefault'].lstrip()
- assert defexpr[:8].rstrip().upper() == \
- 'DEFAULT', "Unrecognized default value: %s" % \
- defexpr
- defvalue = defexpr[8:].strip()
- if defvalue == 'NULL':
- # Redundant
- defvalue = None
- col_d = {
- 'name' : name,
- 'type' : coltype,
- 'nullable' : not bool(row['null_flag']),
- 'default' : defvalue,
- 'autoincrement':defvalue is None
- }
-
- if orig_colname.lower() == orig_colname:
- col_d['quote'] = True
-
- # if the PK is a single field, try to see if its linked to
- # a sequence thru a trigger
- if len(pkey_cols)==1 and name==pkey_cols[0]:
- seq_d = self.get_column_sequence(connection, tablename, name)
- if seq_d is not None:
- col_d['sequence'] = seq_d
-
- cols.append(col_d)
- return cols
-
- @reflection.cache
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
- # Query to extract the details of each UK/FK of the given table
- fkqry = """
- SELECT rc.rdb$constraint_name AS cname,
- cse.rdb$field_name AS fname,
- ix2.rdb$relation_name AS targetrname,
- se.rdb$field_name AS targetfname
- FROM rdb$relation_constraints rc
- JOIN rdb$indices ix1 ON ix1.rdb$index_name=rc.rdb$index_name
- JOIN rdb$indices ix2 ON ix2.rdb$index_name=ix1.rdb$foreign_key
- JOIN rdb$index_segments cse ON
- cse.rdb$index_name=ix1.rdb$index_name
- JOIN rdb$index_segments se
- ON se.rdb$index_name=ix2.rdb$index_name
- AND se.rdb$field_position=cse.rdb$field_position
- WHERE rc.rdb$constraint_type=? AND rc.rdb$relation_name=?
- ORDER BY se.rdb$index_name, se.rdb$field_position
- """
- tablename = self.denormalize_name(table_name)
-
- c = connection.execute(fkqry, ["FOREIGN KEY", tablename])
- fks = util.defaultdict(lambda:{
- 'name' : None,
- 'constrained_columns' : [],
- 'referred_schema' : None,
- 'referred_table' : None,
- 'referred_columns' : []
- })
-
- for row in c:
- cname = self.normalize_name(row['cname'])
- fk = fks[cname]
- if not fk['name']:
- fk['name'] = cname
- fk['referred_table'] = self.normalize_name(row['targetrname'])
- fk['constrained_columns'].append(
- self.normalize_name(row['fname']))
- fk['referred_columns'].append(
- self.normalize_name(row['targetfname']))
- return fks.values()
-
- @reflection.cache
- def get_indexes(self, connection, table_name, schema=None, **kw):
- qry = """
- SELECT ix.rdb$index_name AS index_name,
- ix.rdb$unique_flag AS unique_flag,
- ic.rdb$field_name AS field_name
- FROM rdb$indices ix
- JOIN rdb$index_segments ic
- ON ix.rdb$index_name=ic.rdb$index_name
- LEFT OUTER JOIN rdb$relation_constraints
- ON rdb$relation_constraints.rdb$index_name =
- ic.rdb$index_name
- WHERE ix.rdb$relation_name=? AND ix.rdb$foreign_key IS NULL
- AND rdb$relation_constraints.rdb$constraint_type IS NULL
- ORDER BY index_name, field_name
- """
- c = connection.execute(qry, [self.denormalize_name(table_name)])
-
- indexes = util.defaultdict(dict)
- for row in c:
- indexrec = indexes[row['index_name']]
- if 'name' not in indexrec:
- indexrec['name'] = self.normalize_name(row['index_name'])
- indexrec['column_names'] = []
- indexrec['unique'] = bool(row['unique_flag'])
-
- indexrec['column_names'].append(
- self.normalize_name(row['field_name']))
-
- return indexes.values()
-
- def do_execute(self, cursor, statement, parameters, context=None):
- # kinterbase does not accept a None, but wants an empty list
- # when there are no arguments.
- cursor.execute(statement, parameters or [])
-
- def do_rollback(self, connection):
- # Use the retaining feature, that keeps the transaction going
- connection.rollback(True)
-
- def do_commit(self, connection):
- # Use the retaining feature, that keeps the transaction going
- connection.commit(True)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/kinterbasdb.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/kinterbasdb.py
deleted file mode 100755
index ebb7805a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/firebird/kinterbasdb.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# firebird/kinterbasdb.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-The most common way to connect to a Firebird engine is implemented by
-kinterbasdb__, currently maintained__ directly by the Firebird people.
-
-The connection URL is of the form
-``firebird[+kinterbasdb]://user:password@host:port/path/to/db[?key=value&key=value...]``.
-
-Kinterbasedb backend specific keyword arguments are:
-
-* type_conv - select the kind of mapping done on the types: by default
- SQLAlchemy uses 200 with Unicode, datetime and decimal support (see
- details__).
-
-* concurrency_level - set the backend policy with regards to threading
- issues: by default SQLAlchemy uses policy 1 (see details__).
-
-* enable_rowcount - True by default, setting this to False disables
- the usage of "cursor.rowcount" with the
- Kinterbasdb dialect, which SQLAlchemy ordinarily calls upon automatically
- after any UPDATE or DELETE statement. When disabled, SQLAlchemy's
- ResultProxy will return -1 for result.rowcount. The rationale here is
- that Kinterbasdb requires a second round trip to the database when
- .rowcount is called - since SQLA's resultproxy automatically closes
- the cursor after a non-result-returning statement, rowcount must be
- called, if at all, before the result object is returned. Additionally,
- cursor.rowcount may not return correct results with older versions
- of Firebird, and setting this flag to False will also cause the
- SQLAlchemy ORM to ignore its usage. The behavior can also be controlled on a
- per-execution basis using the `enable_rowcount` option with
- :meth:`execution_options()`::
-
- conn = engine.connect().execution_options(enable_rowcount=True)
- r = conn.execute(stmt)
- print r.rowcount
-
-__ http://sourceforge.net/projects/kinterbasdb
-__ http://firebirdsql.org/index.php?op=devel&sub=python
-__ http://kinterbasdb.sourceforge.net/dist_docs/usage.html#adv_param_conv_dynamic_type_translation
-__ http://kinterbasdb.sourceforge.net/dist_docs/usage.html#special_issue_concurrency
-"""
-
-from sqlalchemy.dialects.firebird.base import FBDialect, \
- FBCompiler, FBExecutionContext
-from sqlalchemy import util, types as sqltypes
-from sqlalchemy.util.compat import decimal
-from re import match
-
-
-class _FBNumeric_kinterbasdb(sqltypes.Numeric):
- def bind_processor(self, dialect):
- def process(value):
- if isinstance(value, decimal.Decimal):
- return str(value)
- else:
- return value
- return process
-
-class FBExecutionContext_kinterbasdb(FBExecutionContext):
- @property
- def rowcount(self):
- if self.execution_options.get('enable_rowcount',
- self.dialect.enable_rowcount):
- return self.cursor.rowcount
- else:
- return -1
-
-class FBDialect_kinterbasdb(FBDialect):
- driver = 'kinterbasdb'
- supports_sane_rowcount = False
- supports_sane_multi_rowcount = False
- execution_ctx_cls = FBExecutionContext_kinterbasdb
-
- supports_native_decimal = True
-
- colspecs = util.update_copy(
- FBDialect.colspecs,
- {
- sqltypes.Numeric:_FBNumeric_kinterbasdb,
- }
-
- )
-
- def __init__(self, type_conv=200, concurrency_level=1,
- enable_rowcount=True, **kwargs):
- super(FBDialect_kinterbasdb, self).__init__(**kwargs)
- self.enable_rowcount = enable_rowcount
- self.type_conv = type_conv
- self.concurrency_level = concurrency_level
- if enable_rowcount:
- self.supports_sane_rowcount = True
-
- @classmethod
- def dbapi(cls):
- k = __import__('kinterbasdb')
- return k
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- if opts.get('port'):
- opts['host'] = "%s/%s" % (opts['host'], opts['port'])
- del opts['port']
- opts.update(url.query)
-
- util.coerce_kw_type(opts, 'type_conv', int)
-
- type_conv = opts.pop('type_conv', self.type_conv)
- concurrency_level = opts.pop('concurrency_level',
- self.concurrency_level)
-
- if self.dbapi is not None:
- initialized = getattr(self.dbapi, 'initialized', None)
- if initialized is None:
- # CVS rev 1.96 changed the name of the attribute:
- # http://kinterbasdb.cvs.sourceforge.net/viewvc/kinterbasdb/Kinterbasdb-3.0/__init__.py?r1=1.95&r2=1.96
- initialized = getattr(self.dbapi, '_initialized', False)
- if not initialized:
- self.dbapi.init(type_conv=type_conv,
- concurrency_level=concurrency_level)
- return ([], opts)
-
- def _get_server_version_info(self, connection):
- """Get the version of the Firebird server used by a connection.
-
- Returns a tuple of (`major`, `minor`, `build`), three integers
- representing the version of the attached server.
- """
-
- # This is the simpler approach (the other uses the services api),
- # that for backward compatibility reasons returns a string like
- # LI-V6.3.3.12981 Firebird 2.0
- # where the first version is a fake one resembling the old
- # Interbase signature.
-
- fbconn = connection.connection
- version = fbconn.server_version
-
- return self._parse_version_info(version)
-
- def _parse_version_info(self, version):
- m = match('\w+-V(\d+)\.(\d+)\.(\d+)\.(\d+)( \w+ (\d+)\.(\d+))?', version)
- if not m:
- raise AssertionError(
- "Could not determine version from string '%s'" % version)
-
- if m.group(5) != None:
- return tuple([int(x) for x in m.group(6, 7, 4)] + ['firebird'])
- else:
- return tuple([int(x) for x in m.group(1, 2, 3)] + ['interbase'])
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, (self.dbapi.OperationalError,
- self.dbapi.ProgrammingError)):
- msg = str(e)
- return ('Unable to complete network request to host' in msg or
- 'Invalid connection state' in msg or
- 'Invalid cursor state' in msg or
- 'connection shutdown' in msg)
- else:
- return False
-
-dialect = FBDialect_kinterbasdb
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/__init__.py
deleted file mode 100755
index 9dfd0ca5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# informix/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.informix import base, informixdb
-
-base.dialect = informixdb.dialect \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/base.py
deleted file mode 100755
index f6749e5c..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/base.py
+++ /dev/null
@@ -1,593 +0,0 @@
-# informix/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# coding: gbk
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Informix database.
-
-This dialect is mostly functional as of SQLAlchemy 0.6.5.
-
-
-"""
-
-
-import datetime
-
-from sqlalchemy import sql, schema, exc, pool, util
-from sqlalchemy.sql import compiler, text
-from sqlalchemy.engine import default, reflection
-from sqlalchemy import types as sqltypes
-
-RESERVED_WORDS = set(
- ["abs", "absolute", "access", "access_method", "acos", "active", "add",
- "address", "add_months", "admin", "after", "aggregate", "alignment",
- "all", "allocate", "all_rows", "altere", "and", "ansi", "any", "append",
- "array", "as", "asc", "ascii", "asin", "at", "atan", "atan2", "attach",
- "attributes", "audit", "authentication", "authid", "authorization",
- "authorized", "auto", "autofree", "auto_reprepare", "auto_stat_mode",
- "avg", "avoid_execute", "avoid_fact", "avoid_full", "avoid_hash",
- "avoid_index", "avoid_index_sj", "avoid_multi_index", "avoid_nl",
- "avoid_star_join", "avoid_subqf", "based", "before", "begin",
- "between", "bigint", "bigserial", "binary", "bitand", "bitandnot",
- "bitnot", "bitor", "bitxor", "blob", "blobdir", "boolean", "both",
- "bound_impl_pdq", "buffered", "builtin", "by", "byte", "cache", "call",
- "cannothash", "cardinality", "cascade", "case", "cast", "ceil", "char",
- "character", "character_length", "char_length", "check", "class",
- "class_origin", "client", "clob", "clobdir", "close", "cluster",
- "clustersize", "cobol", "codeset", "collation", "collection",
- "column", "columns", "commit", "committed", "commutator", "component",
- "components", "concat", "concurrent", "connect", "connection",
- "connection_name", "connect_by_iscycle", "connect_by_isleaf",
- "connect_by_rootconst", "constraint", "constraints", "constructor",
- "context", "continue", "copy", "cos", "costfunc", "count", "crcols",
- "create", "cross", "current", "current_role", "currval", "cursor",
- "cycle", "database", "datafiles", "dataskip", "date", "datetime",
- "day", "dba", "dbdate", "dbinfo", "dbpassword", "dbsecadm",
- "dbservername", "deallocate", "debug", "debugmode", "debug_env", "dec",
- "decimal", "declare", "decode", "decrypt_binary", "decrypt_char",
- "dec_t", "default", "default_role", "deferred", "deferred_prepare",
- "define", "delay", "delete", "deleting", "delimited", "delimiter",
- "deluxe", "desc", "describe", "descriptor", "detach", "diagnostics",
- "directives", "dirty", "disable", "disabled", "disconnect", "disk",
- "distinct", "distributebinary", "distributesreferences",
- "distributions", "document", "domain", "donotdistribute", "dormant",
- "double", "drop", "dtime_t", "each", "elif", "else", "enabled",
- "encryption", "encrypt_aes", "encrypt_tdes", "end", "enum",
- "environment", "error", "escape", "exception", "exclusive", "exec",
- "execute", "executeanywhere", "exemption", "exists", "exit", "exp",
- "explain", "explicit", "express", "expression", "extdirectives",
- "extend", "extent", "external", "fact", "false", "far", "fetch",
- "file", "filetoblob", "filetoclob", "fillfactor", "filtering", "first",
- "first_rows", "fixchar", "fixed", "float", "floor", "flush", "for",
- "force", "forced", "force_ddl_exec", "foreach", "foreign", "format",
- "format_units", "fortran", "found", "fraction", "fragment",
- "fragments", "free", "from", "full", "function", "general", "get",
- "gethint", "global", "go", "goto", "grant", "greaterthan",
- "greaterthanorequal", "group", "handlesnulls", "hash", "having", "hdr",
- "hex", "high", "hint", "hold", "home", "hour", "idslbacreadarray",
- "idslbacreadset", "idslbacreadtree", "idslbacrules",
- "idslbacwritearray", "idslbacwriteset", "idslbacwritetree",
- "idssecuritylabel", "if", "ifx_auto_reprepare", "ifx_batchedread_table",
- "ifx_int8_t", "ifx_lo_create_spec_t", "ifx_lo_stat_t", "immediate",
- "implicit", "implicit_pdq", "in", "inactive", "increment", "index",
- "indexes", "index_all", "index_sj", "indicator", "informix", "init",
- "initcap", "inline", "inner", "inout", "insert", "inserting", "instead",
- "int", "int8", "integ", "integer", "internal", "internallength",
- "interval", "into", "intrvl_t", "is", "iscanonical", "isolation",
- "item", "iterator", "java", "join", "keep", "key", "label", "labeleq",
- "labelge", "labelglb", "labelgt", "labelle", "labellt", "labellub",
- "labeltostring", "language", "last", "last_day", "leading", "left",
- "length", "lessthan", "lessthanorequal", "let", "level", "like",
- "limit", "list", "listing", "load", "local", "locator", "lock", "locks",
- "locopy", "loc_t", "log", "log10", "logn", "long", "loop", "lotofile",
- "low", "lower", "lpad", "ltrim", "lvarchar", "matched", "matches",
- "max", "maxerrors", "maxlen", "maxvalue", "mdy", "median", "medium",
- "memory", "memory_resident", "merge", "message_length", "message_text",
- "middle", "min", "minute", "minvalue", "mod", "mode", "moderate",
- "modify", "module", "money", "month", "months_between", "mounting",
- "multiset", "multi_index", "name", "nchar", "negator", "new", "next",
- "nextval", "next_day", "no", "nocache", "nocycle", "nomaxvalue",
- "nomigrate", "nominvalue", "none", "non_dim", "non_resident", "noorder",
- "normal", "not", "notemplatearg", "notequal", "null", "nullif",
- "numeric", "numrows", "numtodsinterval", "numtoyminterval", "nvarchar",
- "nvl", "octet_length", "of", "off", "old", "on", "online", "only",
- "opaque", "opclass", "open", "optcompind", "optical", "optimization",
- "option", "or", "order", "ordered", "out", "outer", "output",
- "override", "page", "parallelizable", "parameter", "partition",
- "pascal", "passedbyvalue", "password", "pdqpriority", "percaltl_cos",
- "pipe", "pli", "pload", "policy", "pow", "power", "precision",
- "prepare", "previous", "primary", "prior", "private", "privileges",
- "procedure", "properties", "public", "put", "raise", "range", "raw",
- "read", "real", "recordend", "references", "referencing", "register",
- "rejectfile", "relative", "release", "remainder", "rename",
- "reoptimization", "repeatable", "replace", "replication", "reserve",
- "resolution", "resource", "restart", "restrict", "resume", "retain",
- "retainupdatelocks", "return", "returned_sqlstate", "returning",
- "returns", "reuse", "revoke", "right", "robin", "role", "rollback",
- "rollforward", "root", "round", "routine", "row", "rowid", "rowids",
- "rows", "row_count", "rpad", "rtrim", "rule", "sameas", "samples",
- "sampling", "save", "savepoint", "schema", "scroll", "seclabel_by_comp",
- "seclabel_by_name", "seclabel_to_char", "second", "secondary",
- "section", "secured", "security", "selconst", "select", "selecting",
- "selfunc", "selfuncargs", "sequence", "serial", "serial8",
- "serializable", "serveruuid", "server_name", "session", "set",
- "setsessionauth", "share", "short", "siblings", "signed", "sin",
- "sitename", "size", "skall", "skinhibit", "skip", "skshow",
- "smallfloat", "smallint", "some", "specific", "sql", "sqlcode",
- "sqlcontext", "sqlerror", "sqlstate", "sqlwarning", "sqrt",
- "stability", "stack", "standard", "start", "star_join", "statchange",
- "statement", "static", "statistics", "statlevel", "status", "stdev",
- "step", "stop", "storage", "store", "strategies", "string",
- "stringtolabel", "struct", "style", "subclass_origin", "substr",
- "substring", "sum", "support", "sync", "synonym", "sysdate",
- "sysdbclose", "sysdbopen", "system", "sys_connect_by_path", "table",
- "tables", "tan", "task", "temp", "template", "test", "text", "then",
- "time", "timeout", "to", "today", "to_char", "to_date",
- "to_dsinterval", "to_number", "to_yminterval", "trace", "trailing",
- "transaction", "transition", "tree", "trigger", "triggers", "trim",
- "true", "trunc", "truncate", "trusted", "type", "typedef", "typeid",
- "typename", "typeof", "uid", "uncommitted", "under", "union",
- "unique", "units", "unknown", "unload", "unlock", "unsigned",
- "update", "updating", "upon", "upper", "usage", "use",
- "uselastcommitted", "user", "use_hash", "use_nl", "use_subqf",
- "using", "value", "values", "var", "varchar", "variable", "variance",
- "variant", "varying", "vercols", "view", "violations", "void",
- "volatile", "wait", "warning", "weekday", "when", "whenever", "where",
- "while", "with", "without", "work", "write", "writedown", "writeup",
- "xadatasource", "xid", "xload", "xunload", "year"
- ])
-
-class InfoDateTime(sqltypes.DateTime):
- def bind_processor(self, dialect):
- def process(value):
- if value is not None:
- if value.microsecond:
- value = value.replace(microsecond=0)
- return value
- return process
-
-class InfoTime(sqltypes.Time):
- def bind_processor(self, dialect):
- def process(value):
- if value is not None:
- if value.microsecond:
- value = value.replace(microsecond=0)
- return value
- return process
-
- def result_processor(self, dialect, coltype):
- def process(value):
- if isinstance(value, datetime.datetime):
- return value.time()
- else:
- return value
- return process
-
-colspecs = {
- sqltypes.DateTime : InfoDateTime,
- sqltypes.TIMESTAMP: InfoDateTime,
- sqltypes.Time: InfoTime,
-}
-
-
-ischema_names = {
- 0 : sqltypes.CHAR, # CHAR
- 1 : sqltypes.SMALLINT, # SMALLINT
- 2 : sqltypes.INTEGER, # INT
- 3 : sqltypes.FLOAT, # Float
- 3 : sqltypes.Float, # SmallFloat
- 5 : sqltypes.DECIMAL, # DECIMAL
- 6 : sqltypes.Integer, # Serial
- 7 : sqltypes.DATE, # DATE
- 8 : sqltypes.Numeric, # MONEY
- 10 : sqltypes.DATETIME, # DATETIME
- 11 : sqltypes.LargeBinary, # BYTE
- 12 : sqltypes.TEXT, # TEXT
- 13 : sqltypes.VARCHAR, # VARCHAR
- 15 : sqltypes.NCHAR, # NCHAR
- 16 : sqltypes.NVARCHAR, # NVARCHAR
- 17 : sqltypes.Integer, # INT8
- 18 : sqltypes.Integer, # Serial8
- 43 : sqltypes.String, # LVARCHAR
- -1 : sqltypes.BLOB, # BLOB
- -1 : sqltypes.CLOB, # CLOB
-}
-
-
-class InfoTypeCompiler(compiler.GenericTypeCompiler):
- def visit_DATETIME(self, type_):
- return "DATETIME YEAR TO SECOND"
-
- def visit_TIME(self, type_):
- return "DATETIME HOUR TO SECOND"
-
- def visit_TIMESTAMP(self, type_):
- return "DATETIME YEAR TO SECOND"
-
- def visit_large_binary(self, type_):
- return "BYTE"
-
- def visit_boolean(self, type_):
- return "SMALLINT"
-
-class InfoSQLCompiler(compiler.SQLCompiler):
- def default_from(self):
- return " from systables where tabname = 'systables' "
-
- def get_select_precolumns(self, select):
- s = ""
- if select._offset:
- s += "SKIP %s " % select._offset
- if select._limit:
- s += "FIRST %s " % select._limit
- s += select._distinct and "DISTINCT " or ""
- return s
-
- def visit_select(self, select, asfrom=False, parens=True, **kw):
- text = compiler.SQLCompiler.visit_select(self, select, asfrom, parens, **kw)
- if asfrom and parens and self.dialect.server_version_info < (11,):
- #assuming that 11 version doesn't need this, not tested
- return "table(multiset" + text + ")"
- else:
- return text
-
- def limit_clause(self, select):
- return ""
-
- def visit_function(self, func, **kw):
- if func.name.lower() == 'current_date':
- return "today"
- elif func.name.lower() == 'current_time':
- return "CURRENT HOUR TO SECOND"
- elif func.name.lower() in ('current_timestamp', 'now'):
- return "CURRENT YEAR TO SECOND"
- else:
- return compiler.SQLCompiler.visit_function(self, func, **kw)
-
- def visit_mod(self, binary, **kw):
- return "MOD(%s, %s)" % (self.process(binary.left), self.process(binary.right))
-
-
-class InfoDDLCompiler(compiler.DDLCompiler):
-
- def visit_add_constraint(self, create):
- preparer = self.preparer
- return "ALTER TABLE %s ADD CONSTRAINT %s" % (
- self.preparer.format_table(create.element.table),
- self.process(create.element)
- )
-
- def get_column_specification(self, column, **kw):
- colspec = self.preparer.format_column(column)
- first = None
- if column.primary_key and column.autoincrement:
- try:
- first = [c for c in column.table.primary_key.columns
- if (c.autoincrement and
- isinstance(c.type, sqltypes.Integer) and
- not c.foreign_keys)].pop(0)
- except IndexError:
- pass
-
- if column is first:
- colspec += " SERIAL"
- else:
- colspec += " " + self.dialect.type_compiler.process(column.type)
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- if not column.nullable:
- colspec += " NOT NULL"
-
- return colspec
-
- def get_column_default_string(self, column):
- if (isinstance(column.server_default, schema.DefaultClause) and
- isinstance(column.server_default.arg, basestring)):
- if isinstance(column.type, (sqltypes.Integer, sqltypes.Numeric)):
- return self.sql_compiler.process(text(column.server_default.arg))
-
- return super(InfoDDLCompiler, self).get_column_default_string(column)
-
- ### Informix wants the constraint name at the end, hence this ist c&p from sql/compiler.py
- def visit_primary_key_constraint(self, constraint):
- if len(constraint) == 0:
- return ''
- text = "PRIMARY KEY "
- text += "(%s)" % ', '.join(self.preparer.quote(c.name, c.quote)
- for c in constraint)
- text += self.define_constraint_deferrability(constraint)
-
- if constraint.name is not None:
- text += " CONSTRAINT %s" % self.preparer.format_constraint(constraint)
- return text
-
- def visit_foreign_key_constraint(self, constraint):
- preparer = self.dialect.identifier_preparer
- remote_table = list(constraint._elements.values())[0].column.table
- text = "FOREIGN KEY (%s) REFERENCES %s (%s)" % (
- ', '.join(preparer.quote(f.parent.name, f.parent.quote)
- for f in constraint._elements.values()),
- preparer.format_table(remote_table),
- ', '.join(preparer.quote(f.column.name, f.column.quote)
- for f in constraint._elements.values())
- )
- text += self.define_constraint_cascades(constraint)
- text += self.define_constraint_deferrability(constraint)
-
- if constraint.name is not None:
- text += " CONSTRAINT %s " % \
- preparer.format_constraint(constraint)
- return text
-
- def visit_unique_constraint(self, constraint):
- text = "UNIQUE (%s)" % (', '.join(self.preparer.quote(c.name, c.quote) for c in constraint))
- text += self.define_constraint_deferrability(constraint)
-
- if constraint.name is not None:
- text += "CONSTRAINT %s " % self.preparer.format_constraint(constraint)
- return text
-
-class InformixIdentifierPreparer(compiler.IdentifierPreparer):
-
- reserved_words = RESERVED_WORDS
-
-
-class InformixDialect(default.DefaultDialect):
- name = 'informix'
-
- max_identifier_length = 128 # adjusts at runtime based on server version
-
- type_compiler = InfoTypeCompiler
- statement_compiler = InfoSQLCompiler
- ddl_compiler = InfoDDLCompiler
- colspecs = colspecs
- ischema_names = ischema_names
- preparer = InformixIdentifierPreparer
- default_paramstyle = 'qmark'
-
- def __init__(self, has_transactions=True, *args, **kwargs):
- self.has_transactions = has_transactions
- default.DefaultDialect.__init__(self, *args, **kwargs)
-
- def initialize(self, connection):
- super(InformixDialect, self).initialize(connection)
-
- # http://www.querix.com/support/knowledge-base/error_number_message/error_200
- if self.server_version_info < (9, 2):
- self.max_identifier_length = 18
- else:
- self.max_identifier_length = 128
-
- def do_begin(self, connection):
- cu = connection.cursor()
- cu.execute('SET LOCK MODE TO WAIT')
- if self.has_transactions:
- cu.execute('SET ISOLATION TO REPEATABLE READ')
-
- def do_commit(self, connection):
- if self.has_transactions:
- connection.commit()
-
- def do_rollback(self, connection):
- if self.has_transactions:
- connection.rollback()
-
- def _get_table_names(self, connection, schema, type, **kw):
- schema = schema or self.default_schema_name
- s = "select tabname, owner from systables where owner=? and tabtype=?"
- return [row[0] for row in connection.execute(s, schema, type)]
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- return self._get_table_names(connection, schema, 'T', **kw)
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- return self._get_table_names(connection, schema, 'V', **kw)
-
- @reflection.cache
- def get_schema_names(self, connection, **kw):
- s = "select owner from systables"
- return [row[0] for row in connection.execute(s)]
-
- def has_table(self, connection, table_name, schema=None):
- schema = schema or self.default_schema_name
- cursor = connection.execute(
- """select tabname from systables where tabname=? and owner=?""",
- table_name, schema)
- return cursor.first() is not None
-
- @reflection.cache
- def get_columns(self, connection, table_name, schema=None, **kw):
- schema = schema or self.default_schema_name
- c = connection.execute(
- """select colname, coltype, collength, t3.default, t1.colno from
- syscolumns as t1 , systables as t2 , OUTER sysdefaults as t3
- where t1.tabid = t2.tabid and t2.tabname=? and t2.owner=?
- and t3.tabid = t2.tabid and t3.colno = t1.colno
- order by t1.colno""", table_name, schema)
-
- primary_cols = self.get_primary_keys(connection, table_name, schema, **kw)
-
- columns = []
- rows = c.fetchall()
- for name, colattr, collength, default, colno in rows:
- name = name.lower()
-
- autoincrement = False
- primary_key = False
-
- if name in primary_cols:
- primary_key = True
-
- # in 7.31, coltype = 0x000
- # ^^-- column type
- # ^-- 1 not null, 0 null
- not_nullable, coltype = divmod(colattr, 256)
- if coltype not in (0, 13) and default:
- default = default.split()[-1]
-
- if coltype == 6: # Serial, mark as autoincrement
- autoincrement = True
-
- if coltype == 0 or coltype == 13: # char, varchar
- coltype = ischema_names[coltype](collength)
- if default:
- default = "'%s'" % default
- elif coltype == 5: # decimal
- precision, scale = (collength & 0xFF00) >> 8, collength & 0xFF
- if scale == 255:
- scale = 0
- coltype = sqltypes.Numeric(precision, scale)
- else:
- try:
- coltype = ischema_names[coltype]
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, name))
- coltype = sqltypes.NULLTYPE
-
- column_info = dict(name=name, type=coltype, nullable=not not_nullable,
- default=default, autoincrement=autoincrement,
- primary_key=primary_key)
- columns.append(column_info)
- return columns
-
- @reflection.cache
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
- schema_sel = schema or self.default_schema_name
- c = connection.execute(
- """select t1.constrname as cons_name,
- t4.colname as local_column, t7.tabname as remote_table,
- t6.colname as remote_column, t7.owner as remote_owner
- from sysconstraints as t1 , systables as t2 ,
- sysindexes as t3 , syscolumns as t4 ,
- sysreferences as t5 , syscolumns as t6 , systables as t7 ,
- sysconstraints as t8 , sysindexes as t9
- where t1.tabid = t2.tabid and t2.tabname=? and t2.owner=? and t1.constrtype = 'R'
- and t3.tabid = t2.tabid and t3.idxname = t1.idxname
- and t4.tabid = t2.tabid and t4.colno in (t3.part1, t3.part2, t3.part3,
- t3.part4, t3.part5, t3.part6, t3.part7, t3.part8, t3.part9, t3.part10,
- t3.part11, t3.part11, t3.part12, t3.part13, t3.part4, t3.part15, t3.part16)
- and t5.constrid = t1.constrid and t8.constrid = t5.primary
- and t6.tabid = t5.ptabid and t6.colno in (t9.part1, t9.part2, t9.part3,
- t9.part4, t9.part5, t9.part6, t9.part7, t9.part8, t9.part9, t9.part10,
- t9.part11, t9.part11, t9.part12, t9.part13, t9.part4, t9.part15, t9.part16) and t9.idxname =
- t8.idxname
- and t7.tabid = t5.ptabid""", table_name, schema_sel)
-
-
- def fkey_rec():
- return {
- 'name' : None,
- 'constrained_columns' : [],
- 'referred_schema' : None,
- 'referred_table' : None,
- 'referred_columns' : []
- }
-
- fkeys = util.defaultdict(fkey_rec)
-
- rows = c.fetchall()
- for cons_name, local_column, \
- remote_table, remote_column, remote_owner in rows:
-
- rec = fkeys[cons_name]
- rec['name'] = cons_name
- local_cols, remote_cols = \
- rec['constrained_columns'], rec['referred_columns']
-
- if not rec['referred_table']:
- rec['referred_table'] = remote_table
- if schema is not None:
- rec['referred_schema'] = remote_owner
-
- if local_column not in local_cols:
- local_cols.append(local_column)
- if remote_column not in remote_cols:
- remote_cols.append(remote_column)
-
- return fkeys.values()
-
- @reflection.cache
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- schema = schema or self.default_schema_name
-
- # Select the column positions from sysindexes for sysconstraints
- data = connection.execute(
- """select t2.*
- from systables as t1, sysindexes as t2, sysconstraints as t3
- where t1.tabid=t2.tabid and t1.tabname=? and t1.owner=?
- and t2.idxname=t3.idxname and t3.constrtype='P'""",
- table_name, schema
- ).fetchall()
-
- colpositions = set()
-
- for row in data:
- colpos = set([getattr(row, 'part%d' % x) for x in range(1,16)])
- colpositions |= colpos
-
- if not len(colpositions):
- return []
-
- # Select the column names using the columnpositions
- # TODO: Maybe cache a bit of those col infos (eg select all colnames for one table)
- place_holder = ','.join('?'*len(colpositions))
- c = connection.execute(
- """select t1.colname
- from syscolumns as t1, systables as t2
- where t2.tabname=? and t1.tabid = t2.tabid and
- t1.colno in (%s)""" % place_holder,
- table_name, *colpositions
- ).fetchall()
-
- return reduce(lambda x,y: list(x)+list(y), c, [])
-
- @reflection.cache
- def get_indexes(self, connection, table_name, schema, **kw):
- # TODO: schema...
- c = connection.execute(
- """select t1.*
- from sysindexes as t1 , systables as t2
- where t1.tabid = t2.tabid and t2.tabname=?""",
- table_name)
-
- indexes = []
- for row in c.fetchall():
- colnames = [getattr(row, 'part%d' % x) for x in range(1,16)]
- colnames = [x for x in colnames if x]
- place_holder = ','.join('?'*len(colnames))
- c = connection.execute(
- """select t1.colname
- from syscolumns as t1, systables as t2
- where t2.tabname=? and t1.tabid = t2.tabid and
- t1.colno in (%s)""" % place_holder,
- table_name, *colnames
- ).fetchall()
- c = reduce(lambda x,y: list(x)+list(y), c, [])
- indexes.append({
- 'name': row.idxname,
- 'unique': row.idxtype.lower() == 'u',
- 'column_names': c
- })
- return indexes
-
- @reflection.cache
- def get_view_definition(self, connection, view_name, schema=None, **kw):
- schema = schema or self.default_schema_name
- c = connection.execute(
- """select t1.viewtext
- from sysviews as t1 , systables as t2
- where t1.tabid=t2.tabid and t2.tabname=?
- and t2.owner=? order by seqno""",
- view_name, schema).fetchall()
-
- return ''.join([row[0] for row in c])
-
- def _get_default_schema_name(self, connection):
- return connection.execute('select CURRENT_ROLE from systables').scalar()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/informixdb.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/informixdb.py
deleted file mode 100755
index 1b6833af..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/informix/informixdb.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# informix/informixdb.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for the informixdb DBAPI.
-
-informixdb is available at:
-
- http://informixdb.sourceforge.net/
-
-Connecting
-^^^^^^^^^^
-
-Sample informix connection::
-
- engine = create_engine('informix+informixdb://user:password@host/dbname')
-
-"""
-
-import re
-
-from sqlalchemy.dialects.informix.base import InformixDialect
-from sqlalchemy.engine import default
-
-VERSION_RE = re.compile(r'(\d+)\.(\d+)(.+\d+)')
-
-class InformixExecutionContext_informixdb(default.DefaultExecutionContext):
- def post_exec(self):
- if self.isinsert:
- self._lastrowid = self.cursor.sqlerrd[1]
-
- def get_lastrowid(self):
- return self._lastrowid
-
-
-class InformixDialect_informixdb(InformixDialect):
- driver = 'informixdb'
- execution_ctx_cls = InformixExecutionContext_informixdb
-
- @classmethod
- def dbapi(cls):
- return __import__('informixdb')
-
- def create_connect_args(self, url):
- if url.host:
- dsn = '%s@%s' % (url.database, url.host)
- else:
- dsn = url.database
-
- if url.username:
- opt = {'user': url.username, 'password': url.password}
- else:
- opt = {}
-
- return ([dsn], opt)
-
- def _get_server_version_info(self, connection):
- # http://informixdb.sourceforge.net/manual.html#inspecting-version-numbers
- v = VERSION_RE.split(connection.connection.dbms_version)
- return (int(v[1]), int(v[2]), v[3])
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, self.dbapi.OperationalError):
- return 'closed the connection' in str(e) \
- or 'connection not open' in str(e)
- else:
- return False
-
-
-dialect = InformixDialect_informixdb
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/__init__.py
deleted file mode 100755
index 0a39965b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# maxdb/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.maxdb import base, sapdb
-
-base.dialect = sapdb.dialect \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/base.py
deleted file mode 100755
index a6d43a2a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/base.py
+++ /dev/null
@@ -1,1116 +0,0 @@
-# maxdb/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MaxDB database.
-
-This dialect is *not* ported to SQLAlchemy 0.6 or 0.7.
-
-This dialect is *not* tested on SQLAlchemy 0.6 or 0.7.
-
-Overview
---------
-
-The ``maxdb`` dialect is **experimental** and has only been tested on 7.6.03.007
-and 7.6.00.037. Of these, **only 7.6.03.007 will work** with SQLAlchemy's ORM.
-The earlier version has severe ``LEFT JOIN`` limitations and will return
-incorrect results from even very simple ORM queries.
-
-Only the native Python DB-API is currently supported. ODBC driver support
-is a future enhancement.
-
-Connecting
-----------
-
-The username is case-sensitive. If you usually connect to the
-database with sqlcli and other tools in lower case, you likely need to
-use upper case for DB-API.
-
-Implementation Notes
---------------------
-
-With the 7.6.00.37 driver and Python 2.5, it seems that all DB-API
-generated exceptions are broken and can cause Python to crash.
-
-For 'somecol.in_([])' to work, the IN operator's generation must be changed
-to cast 'NULL' to a numeric, i.e. NUM(NULL). The DB-API doesn't accept a
-bind parameter there, so that particular generation must inline the NULL value,
-which depends on [ticket:807].
-
-The DB-API is very picky about where bind params may be used in queries.
-
-Bind params for some functions (e.g. MOD) need type information supplied.
-The dialect does not yet do this automatically.
-
-Max will occasionally throw up 'bad sql, compile again' exceptions for
-perfectly valid SQL. The dialect does not currently handle these, more
-research is needed.
-
-MaxDB 7.5 and Sap DB <= 7.4 reportedly do not support schemas. A very
-slightly different version of this dialect would be required to support
-those versions, and can easily be added if there is demand. Some other
-required components such as an Max-aware 'old oracle style' join compiler
-(thetas with (+) outer indicators) are already done and available for
-integration- email the devel list if you're interested in working on
-this.
-
-Versions tested: 7.6.03.07 and 7.6.00.37, native Python DB-API
-
-* MaxDB has severe limitations on OUTER JOINs, which are essential to ORM
- eager loading. And rather than raise an error if a SELECT can't be serviced,
- the database simply returns incorrect results.
-* Version 7.6.03.07 seems to JOIN properly, however the docs do not show the
- OUTER restrictions being lifted (as of this writing), and no changelog is
- available to confirm either. If you are using a different server version and
- your tasks require the ORM or any semi-advanced SQL through the SQL layer,
- running the SQLAlchemy test suite against your database is HIGHLY
- recommended before you begin.
-* Version 7.6.00.37 is LHS/RHS sensitive in `FROM lhs LEFT OUTER JOIN rhs ON
- lhs.col=rhs.col` vs `rhs.col=lhs.col`!
-* Version 7.6.00.37 is confused by `SELECT DISTINCT col as alias FROM t ORDER
- BY col` - these aliased, DISTINCT, ordered queries need to be re-written to
- order by the alias name.
-* Version 7.6.x supports creating a SAVEPOINT but not its RELEASE.
-* MaxDB supports autoincrement-style columns (DEFAULT SERIAL) and independent
- sequences. When including a DEFAULT SERIAL column in an insert, 0 needs to
- be inserted rather than NULL to generate a value.
-* MaxDB supports ANSI and "old Oracle style" theta joins with (+) outer join
- indicators.
-* The SQLAlchemy dialect is schema-aware and probably won't function correctly
- on server versions (pre-7.6?). Support for schema-less server versions could
- be added if there's call.
-* ORDER BY is not supported in subqueries. LIMIT is not supported in
- subqueries. In 7.6.00.37, TOP does work in subqueries, but without limit not
- so useful. OFFSET does not work in 7.6 despite being in the docs. Row number
- tricks in WHERE via ROWNO may be possible but it only seems to allow
- less-than comparison!
-* Version 7.6.03.07 can't LIMIT if a derived table is in FROM: `SELECT * FROM
- (SELECT * FROM a) LIMIT 2`
-* MaxDB does not support sql's CAST and can only usefullly cast two types.
- There isn't much implicit type conversion, so be precise when creating
- `PassiveDefaults` in DDL generation: `'3'` and `3` aren't the same.
-
-sapdb.dbapi
-^^^^^^^^^^^
-
-* As of 2007-10-22 the Python 2.4 and 2.5 compatible versions of the DB-API
- are no longer available. A forum posting at SAP states that the Python
- driver will be available again "in the future". The last release from MySQL
- AB works if you can find it.
-* sequence.NEXTVAL skips every other value!
-* No rowcount for executemany()
-* If an INSERT into a table with a DEFAULT SERIAL column inserts the results
- of a function `INSERT INTO t VALUES (LENGTH('foo'))`, the cursor won't have
- the serial id. It needs to be manually yanked from tablename.CURRVAL.
-* Super-duper picky about where bind params can be placed. Not smart about
- converting Python types for some functions, such as `MOD(5, ?)`.
-* LONG (text, binary) values in result sets are read-once. The dialect uses a
- caching RowProxy when these types are present.
-* Connection objects seem like they want to be either `close()`d or garbage
- collected, but not both. There's a warning issued but it seems harmless.
-
-
-"""
-import datetime, itertools, re
-
-from sqlalchemy import exc, schema, sql, util, processors
-from sqlalchemy.sql import operators as sql_operators, expression as sql_expr
-from sqlalchemy.sql import compiler, visitors
-from sqlalchemy.engine import base as engine_base, default, reflection
-from sqlalchemy import types as sqltypes
-
-
-class _StringType(sqltypes.String):
- _type = None
-
- def __init__(self, length=None, encoding=None, **kw):
- super(_StringType, self).__init__(length=length, **kw)
- self.encoding = encoding
-
- def bind_processor(self, dialect):
- if self.encoding == 'unicode':
- return None
- else:
- def process(value):
- if isinstance(value, unicode):
- return value.encode(dialect.encoding)
- else:
- return value
- return process
-
- def result_processor(self, dialect, coltype):
- #XXX: this code is probably very slow and one should try (if at all
- # possible) to determine the correct code path on a per-connection
- # basis (ie, here in result_processor, instead of inside the processor
- # function itself) and probably also use a few generic
- # processors, or possibly per query (though there is no mechanism
- # for that yet).
- def process(value):
- while True:
- if value is None:
- return None
- elif isinstance(value, unicode):
- return value
- elif isinstance(value, str):
- if self.convert_unicode or dialect.convert_unicode:
- return value.decode(dialect.encoding)
- else:
- return value
- elif hasattr(value, 'read'):
- # some sort of LONG, snarf and retry
- value = value.read(value.remainingLength())
- continue
- else:
- # unexpected type, return as-is
- return value
- return process
-
-
-class MaxString(_StringType):
- _type = 'VARCHAR'
-
-
-class MaxUnicode(_StringType):
- _type = 'VARCHAR'
-
- def __init__(self, length=None, **kw):
- kw['encoding'] = 'unicode'
- super(MaxUnicode, self).__init__(length=length, **kw)
-
-
-class MaxChar(_StringType):
- _type = 'CHAR'
-
-
-class MaxText(_StringType):
- _type = 'LONG'
-
- def __init__(self, length=None, **kw):
- super(MaxText, self).__init__(length, **kw)
-
- def get_col_spec(self):
- spec = 'LONG'
- if self.encoding is not None:
- spec = ' '.join((spec, self.encoding))
- elif self.convert_unicode:
- spec = ' '.join((spec, 'UNICODE'))
-
- return spec
-
-
-class MaxNumeric(sqltypes.Numeric):
- """The FIXED (also NUMERIC, DECIMAL) data type."""
-
- def __init__(self, precision=None, scale=None, **kw):
- kw.setdefault('asdecimal', True)
- super(MaxNumeric, self).__init__(scale=scale, precision=precision,
- **kw)
-
- def bind_processor(self, dialect):
- return None
-
-
-class MaxTimestamp(sqltypes.DateTime):
- def bind_processor(self, dialect):
- def process(value):
- if value is None:
- return None
- elif isinstance(value, basestring):
- return value
- elif dialect.datetimeformat == 'internal':
- ms = getattr(value, 'microsecond', 0)
- return value.strftime("%Y%m%d%H%M%S" + ("%06u" % ms))
- elif dialect.datetimeformat == 'iso':
- ms = getattr(value, 'microsecond', 0)
- return value.strftime("%Y-%m-%d %H:%M:%S." + ("%06u" % ms))
- else:
- raise exc.InvalidRequestError(
- "datetimeformat '%s' is not supported." % (
- dialect.datetimeformat,))
- return process
-
- def result_processor(self, dialect, coltype):
- if dialect.datetimeformat == 'internal':
- def process(value):
- if value is None:
- return None
- else:
- return datetime.datetime(
- *[int(v)
- for v in (value[0:4], value[4:6], value[6:8],
- value[8:10], value[10:12], value[12:14],
- value[14:])])
- elif dialect.datetimeformat == 'iso':
- def process(value):
- if value is None:
- return None
- else:
- return datetime.datetime(
- *[int(v)
- for v in (value[0:4], value[5:7], value[8:10],
- value[11:13], value[14:16], value[17:19],
- value[20:])])
- else:
- raise exc.InvalidRequestError(
- "datetimeformat '%s' is not supported." %
- dialect.datetimeformat)
- return process
-
-
-class MaxDate(sqltypes.Date):
- def bind_processor(self, dialect):
- def process(value):
- if value is None:
- return None
- elif isinstance(value, basestring):
- return value
- elif dialect.datetimeformat == 'internal':
- return value.strftime("%Y%m%d")
- elif dialect.datetimeformat == 'iso':
- return value.strftime("%Y-%m-%d")
- else:
- raise exc.InvalidRequestError(
- "datetimeformat '%s' is not supported." % (
- dialect.datetimeformat,))
- return process
-
- def result_processor(self, dialect, coltype):
- if dialect.datetimeformat == 'internal':
- def process(value):
- if value is None:
- return None
- else:
- return datetime.date(int(value[0:4]), int(value[4:6]),
- int(value[6:8]))
- elif dialect.datetimeformat == 'iso':
- def process(value):
- if value is None:
- return None
- else:
- return datetime.date(int(value[0:4]), int(value[5:7]),
- int(value[8:10]))
- else:
- raise exc.InvalidRequestError(
- "datetimeformat '%s' is not supported." %
- dialect.datetimeformat)
- return process
-
-
-class MaxTime(sqltypes.Time):
- def bind_processor(self, dialect):
- def process(value):
- if value is None:
- return None
- elif isinstance(value, basestring):
- return value
- elif dialect.datetimeformat == 'internal':
- return value.strftime("%H%M%S")
- elif dialect.datetimeformat == 'iso':
- return value.strftime("%H-%M-%S")
- else:
- raise exc.InvalidRequestError(
- "datetimeformat '%s' is not supported." % (
- dialect.datetimeformat,))
- return process
-
- def result_processor(self, dialect, coltype):
- if dialect.datetimeformat == 'internal':
- def process(value):
- if value is None:
- return None
- else:
- return datetime.time(int(value[0:4]), int(value[4:6]),
- int(value[6:8]))
- elif dialect.datetimeformat == 'iso':
- def process(value):
- if value is None:
- return None
- else:
- return datetime.time(int(value[0:4]), int(value[5:7]),
- int(value[8:10]))
- else:
- raise exc.InvalidRequestError(
- "datetimeformat '%s' is not supported." %
- dialect.datetimeformat)
- return process
-
-
-class MaxBlob(sqltypes.LargeBinary):
- def bind_processor(self, dialect):
- return processors.to_str
-
- def result_processor(self, dialect, coltype):
- def process(value):
- if value is None:
- return None
- else:
- return value.read(value.remainingLength())
- return process
-
-class MaxDBTypeCompiler(compiler.GenericTypeCompiler):
- def _string_spec(self, string_spec, type_):
- if type_.length is None:
- spec = 'LONG'
- else:
- spec = '%s(%s)' % (string_spec, type_.length)
-
- if getattr(type_, 'encoding'):
- spec = ' '.join([spec, getattr(type_, 'encoding').upper()])
- return spec
-
- def visit_text(self, type_):
- spec = 'LONG'
- if getattr(type_, 'encoding', None):
- spec = ' '.join((spec, type_.encoding))
- elif type_.convert_unicode:
- spec = ' '.join((spec, 'UNICODE'))
-
- return spec
-
- def visit_char(self, type_):
- return self._string_spec("CHAR", type_)
-
- def visit_string(self, type_):
- return self._string_spec("VARCHAR", type_)
-
- def visit_large_binary(self, type_):
- return "LONG BYTE"
-
- def visit_numeric(self, type_):
- if type_.scale and type_.precision:
- return 'FIXED(%s, %s)' % (type_.precision, type_.scale)
- elif type_.precision:
- return 'FIXED(%s)' % type_.precision
- else:
- return 'INTEGER'
-
- def visit_BOOLEAN(self, type_):
- return "BOOLEAN"
-
-colspecs = {
- sqltypes.Numeric: MaxNumeric,
- sqltypes.DateTime: MaxTimestamp,
- sqltypes.Date: MaxDate,
- sqltypes.Time: MaxTime,
- sqltypes.String: MaxString,
- sqltypes.Unicode:MaxUnicode,
- sqltypes.LargeBinary: MaxBlob,
- sqltypes.Text: MaxText,
- sqltypes.CHAR: MaxChar,
- sqltypes.TIMESTAMP: MaxTimestamp,
- sqltypes.BLOB: MaxBlob,
- sqltypes.Unicode: MaxUnicode,
- }
-
-ischema_names = {
- 'boolean': sqltypes.BOOLEAN,
- 'char': sqltypes.CHAR,
- 'character': sqltypes.CHAR,
- 'date': sqltypes.DATE,
- 'fixed': sqltypes.Numeric,
- 'float': sqltypes.FLOAT,
- 'int': sqltypes.INT,
- 'integer': sqltypes.INT,
- 'long binary': sqltypes.BLOB,
- 'long unicode': sqltypes.Text,
- 'long': sqltypes.Text,
- 'long': sqltypes.Text,
- 'smallint': sqltypes.SmallInteger,
- 'time': sqltypes.Time,
- 'timestamp': sqltypes.TIMESTAMP,
- 'varchar': sqltypes.VARCHAR,
- }
-
-# TODO: migrate this to sapdb.py
-class MaxDBExecutionContext(default.DefaultExecutionContext):
- def post_exec(self):
- # DB-API bug: if there were any functions as values,
- # then do another select and pull CURRVAL from the
- # autoincrement column's implicit sequence... ugh
- if self.compiled.isinsert and not self.executemany:
- table = self.compiled.statement.table
- index, serial_col = _autoserial_column(table)
-
- if serial_col and (not self.compiled._safeserial or
- not(self._last_inserted_ids) or
- self._last_inserted_ids[index] in (None, 0)):
- if table.schema:
- sql = "SELECT %s.CURRVAL FROM DUAL" % (
- self.compiled.preparer.format_table(table))
- else:
- sql = "SELECT CURRENT_SCHEMA.%s.CURRVAL FROM DUAL" % (
- self.compiled.preparer.format_table(table))
-
- rs = self.cursor.execute(sql)
- id = rs.fetchone()[0]
-
- if not self._last_inserted_ids:
- # This shouldn't ever be > 1? Right?
- self._last_inserted_ids = \
- [None] * len(table.primary_key.columns)
- self._last_inserted_ids[index] = id
-
- super(MaxDBExecutionContext, self).post_exec()
-
- def get_result_proxy(self):
- if self.cursor.description is not None:
- for column in self.cursor.description:
- if column[1] in ('Long Binary', 'Long', 'Long Unicode'):
- return MaxDBResultProxy(self)
- return engine_base.ResultProxy(self)
-
- @property
- def rowcount(self):
- if hasattr(self, '_rowcount'):
- return self._rowcount
- else:
- return self.cursor.rowcount
-
- def fire_sequence(self, seq):
- if seq.optional:
- return None
- return self._execute_scalar("SELECT %s.NEXTVAL FROM DUAL" % (
- self.dialect.identifier_preparer.format_sequence(seq)))
-
-class MaxDBCachedColumnRow(engine_base.RowProxy):
- """A RowProxy that only runs result_processors once per column."""
-
- def __init__(self, parent, row):
- super(MaxDBCachedColumnRow, self).__init__(parent, row)
- self.columns = {}
- self._row = row
- self._parent = parent
-
- def _get_col(self, key):
- if key not in self.columns:
- self.columns[key] = self._parent._get_col(self._row, key)
- return self.columns[key]
-
- def __iter__(self):
- for i in xrange(len(self._row)):
- yield self._get_col(i)
-
- def __repr__(self):
- return repr(list(self))
-
- def __eq__(self, other):
- return ((other is self) or
- (other == tuple([self._get_col(key)
- for key in xrange(len(self._row))])))
- def __getitem__(self, key):
- if isinstance(key, slice):
- indices = key.indices(len(self._row))
- return tuple([self._get_col(i) for i in xrange(*indices)])
- else:
- return self._get_col(key)
-
- def __getattr__(self, name):
- try:
- return self._get_col(name)
- except KeyError:
- raise AttributeError(name)
-
-
-class MaxDBResultProxy(engine_base.ResultProxy):
- _process_row = MaxDBCachedColumnRow
-
-class MaxDBCompiler(compiler.SQLCompiler):
-
- function_conversion = {
- 'CURRENT_DATE': 'DATE',
- 'CURRENT_TIME': 'TIME',
- 'CURRENT_TIMESTAMP': 'TIMESTAMP',
- }
-
- # These functions must be written without parens when called with no
- # parameters. e.g. 'SELECT DATE FROM DUAL' not 'SELECT DATE() FROM DUAL'
- bare_functions = set([
- 'CURRENT_SCHEMA', 'DATE', 'FALSE', 'SYSDBA', 'TIME', 'TIMESTAMP',
- 'TIMEZONE', 'TRANSACTION', 'TRUE', 'USER', 'UID', 'USERGROUP',
- 'UTCDATE', 'UTCDIFF'])
-
- def visit_mod(self, binary, **kw):
- return "mod(%s, %s)" % \
- (self.process(binary.left), self.process(binary.right))
-
- def default_from(self):
- return ' FROM DUAL'
-
- def for_update_clause(self, select):
- clause = select.for_update
- if clause is True:
- return " WITH LOCK EXCLUSIVE"
- elif clause is None:
- return ""
- elif clause == "read":
- return " WITH LOCK"
- elif clause == "ignore":
- return " WITH LOCK (IGNORE) EXCLUSIVE"
- elif clause == "nowait":
- return " WITH LOCK (NOWAIT) EXCLUSIVE"
- elif isinstance(clause, basestring):
- return " WITH LOCK %s" % clause.upper()
- elif not clause:
- return ""
- else:
- return " WITH LOCK EXCLUSIVE"
-
- def function_argspec(self, fn, **kw):
- if fn.name.upper() in self.bare_functions:
- return ""
- elif len(fn.clauses) > 0:
- return compiler.SQLCompiler.function_argspec(self, fn, **kw)
- else:
- return ""
-
- def visit_function(self, fn, **kw):
- transform = self.function_conversion.get(fn.name.upper(), None)
- if transform:
- fn = fn._clone()
- fn.name = transform
- return super(MaxDBCompiler, self).visit_function(fn, **kw)
-
- def visit_cast(self, cast, **kwargs):
- # MaxDB only supports casts * to NUMERIC, * to VARCHAR or
- # date/time to VARCHAR. Casts of LONGs will fail.
- if isinstance(cast.type, (sqltypes.Integer, sqltypes.Numeric)):
- return "NUM(%s)" % self.process(cast.clause)
- elif isinstance(cast.type, sqltypes.String):
- return "CHR(%s)" % self.process(cast.clause)
- else:
- return self.process(cast.clause)
-
- def visit_sequence(self, sequence):
- if sequence.optional:
- return None
- else:
- return (
- self.dialect.identifier_preparer.format_sequence(sequence) +
- ".NEXTVAL")
-
- class ColumnSnagger(visitors.ClauseVisitor):
- def __init__(self):
- self.count = 0
- self.column = None
- def visit_column(self, column):
- self.column = column
- self.count += 1
-
- def _find_labeled_columns(self, columns, use_labels=False):
- labels = {}
- for column in columns:
- if isinstance(column, basestring):
- continue
- snagger = self.ColumnSnagger()
- snagger.traverse(column)
- if snagger.count == 1:
- if isinstance(column, sql_expr._Label):
- labels[unicode(snagger.column)] = column.name
- elif use_labels:
- labels[unicode(snagger.column)] = column._label
-
- return labels
-
- def order_by_clause(self, select, **kw):
- order_by = self.process(select._order_by_clause, **kw)
-
- # ORDER BY clauses in DISTINCT queries must reference aliased
- # inner columns by alias name, not true column name.
- if order_by and getattr(select, '_distinct', False):
- labels = self._find_labeled_columns(select.inner_columns,
- select.use_labels)
- if labels:
- for needs_alias in labels.keys():
- r = re.compile(r'(^| )(%s)(,| |$)' %
- re.escape(needs_alias))
- order_by = r.sub((r'\1%s\3' % labels[needs_alias]),
- order_by)
-
- # No ORDER BY in subqueries.
- if order_by:
- if self.is_subquery():
- # It's safe to simply drop the ORDER BY if there is no
- # LIMIT. Right? Other dialects seem to get away with
- # dropping order.
- if select._limit:
- raise exc.InvalidRequestError(
- "MaxDB does not support ORDER BY in subqueries")
- else:
- return ""
- return " ORDER BY " + order_by
- else:
- return ""
-
- def get_select_precolumns(self, select):
- # Convert a subquery's LIMIT to TOP
- sql = select._distinct and 'DISTINCT ' or ''
- if self.is_subquery() and select._limit:
- if select._offset:
- raise exc.InvalidRequestError(
- 'MaxDB does not support LIMIT with an offset.')
- sql += 'TOP %s ' % select._limit
- return sql
-
- def limit_clause(self, select):
- # The docs say offsets are supported with LIMIT. But they're not.
- # TODO: maybe emulate by adding a ROWNO/ROWNUM predicate?
- # TODO: does MaxDB support bind params for LIMIT / TOP ?
- if self.is_subquery():
- # sub queries need TOP
- return ''
- elif select._offset:
- raise exc.InvalidRequestError(
- 'MaxDB does not support LIMIT with an offset.')
- else:
- return ' \n LIMIT %s' % (select._limit,)
-
- def visit_insert(self, insert):
- self.isinsert = True
- self._safeserial = True
-
- colparams = self._get_colparams(insert)
- for value in (insert.parameters or {}).itervalues():
- if isinstance(value, sql_expr.Function):
- self._safeserial = False
- break
-
- return ''.join(('INSERT INTO ',
- self.preparer.format_table(insert.table),
- ' (',
- ', '.join([self.preparer.format_column(c[0])
- for c in colparams]),
- ') VALUES (',
- ', '.join([c[1] for c in colparams]),
- ')'))
-
-
-class MaxDBIdentifierPreparer(compiler.IdentifierPreparer):
- reserved_words = set([
- 'abs', 'absolute', 'acos', 'adddate', 'addtime', 'all', 'alpha',
- 'alter', 'any', 'ascii', 'asin', 'atan', 'atan2', 'avg', 'binary',
- 'bit', 'boolean', 'byte', 'case', 'ceil', 'ceiling', 'char',
- 'character', 'check', 'chr', 'column', 'concat', 'constraint', 'cos',
- 'cosh', 'cot', 'count', 'cross', 'curdate', 'current', 'curtime',
- 'database', 'date', 'datediff', 'day', 'dayname', 'dayofmonth',
- 'dayofweek', 'dayofyear', 'dec', 'decimal', 'decode', 'default',
- 'degrees', 'delete', 'digits', 'distinct', 'double', 'except',
- 'exists', 'exp', 'expand', 'first', 'fixed', 'float', 'floor', 'for',
- 'from', 'full', 'get_objectname', 'get_schema', 'graphic', 'greatest',
- 'group', 'having', 'hex', 'hextoraw', 'hour', 'ifnull', 'ignore',
- 'index', 'initcap', 'inner', 'insert', 'int', 'integer', 'internal',
- 'intersect', 'into', 'join', 'key', 'last', 'lcase', 'least', 'left',
- 'length', 'lfill', 'list', 'ln', 'locate', 'log', 'log10', 'long',
- 'longfile', 'lower', 'lpad', 'ltrim', 'makedate', 'maketime',
- 'mapchar', 'max', 'mbcs', 'microsecond', 'min', 'minute', 'mod',
- 'month', 'monthname', 'natural', 'nchar', 'next', 'no', 'noround',
- 'not', 'now', 'null', 'num', 'numeric', 'object', 'of', 'on',
- 'order', 'packed', 'pi', 'power', 'prev', 'primary', 'radians',
- 'real', 'reject', 'relative', 'replace', 'rfill', 'right', 'round',
- 'rowid', 'rowno', 'rpad', 'rtrim', 'second', 'select', 'selupd',
- 'serial', 'set', 'show', 'sign', 'sin', 'sinh', 'smallint', 'some',
- 'soundex', 'space', 'sqrt', 'stamp', 'statistics', 'stddev',
- 'subdate', 'substr', 'substring', 'subtime', 'sum', 'sysdba',
- 'table', 'tan', 'tanh', 'time', 'timediff', 'timestamp', 'timezone',
- 'to', 'toidentifier', 'transaction', 'translate', 'trim', 'trunc',
- 'truncate', 'ucase', 'uid', 'unicode', 'union', 'update', 'upper',
- 'user', 'usergroup', 'using', 'utcdate', 'utcdiff', 'value', 'values',
- 'varchar', 'vargraphic', 'variance', 'week', 'weekofyear', 'when',
- 'where', 'with', 'year', 'zoned' ])
-
- def _normalize_name(self, name):
- if name is None:
- return None
- if name.isupper():
- lc_name = name.lower()
- if not self._requires_quotes(lc_name):
- return lc_name
- return name
-
- def _denormalize_name(self, name):
- if name is None:
- return None
- elif (name.islower() and
- not self._requires_quotes(name)):
- return name.upper()
- else:
- return name
-
- def _maybe_quote_identifier(self, name):
- if self._requires_quotes(name):
- return self.quote_identifier(name)
- else:
- return name
-
-
-class MaxDBDDLCompiler(compiler.DDLCompiler):
- def get_column_specification(self, column, **kw):
- colspec = [self.preparer.format_column(column),
- self.dialect.type_compiler.process(column.type)]
-
- if not column.nullable:
- colspec.append('NOT NULL')
-
- default = column.default
- default_str = self.get_column_default_string(column)
-
- # No DDL default for columns specified with non-optional sequence-
- # this defaulting behavior is entirely client-side. (And as a
- # consequence, non-reflectable.)
- if (default and isinstance(default, schema.Sequence) and
- not default.optional):
- pass
- # Regular default
- elif default_str is not None:
- colspec.append('DEFAULT %s' % default_str)
- # Assign DEFAULT SERIAL heuristically
- elif column.primary_key and column.autoincrement:
- # For SERIAL on a non-primary key member, use
- # DefaultClause(text('SERIAL'))
- try:
- first = [c for c in column.table.primary_key.columns
- if (c.autoincrement and
- (isinstance(c.type, sqltypes.Integer) or
- (isinstance(c.type, MaxNumeric) and
- c.type.precision)) and
- not c.foreign_keys)].pop(0)
- if column is first:
- colspec.append('DEFAULT SERIAL')
- except IndexError:
- pass
- return ' '.join(colspec)
-
- def get_column_default_string(self, column):
- if isinstance(column.server_default, schema.DefaultClause):
- if isinstance(column.default.arg, basestring):
- if isinstance(column.type, sqltypes.Integer):
- return str(column.default.arg)
- else:
- return "'%s'" % column.default.arg
- else:
- return unicode(self._compile(column.default.arg, None))
- else:
- return None
-
- def visit_create_sequence(self, create):
- """Creates a SEQUENCE.
-
- TODO: move to module doc?
-
- start
- With an integer value, set the START WITH option.
-
- increment
- An integer value to increment by. Default is the database default.
-
- maxdb_minvalue
- maxdb_maxvalue
- With an integer value, sets the corresponding sequence option.
-
- maxdb_no_minvalue
- maxdb_no_maxvalue
- Defaults to False. If true, sets the corresponding sequence option.
-
- maxdb_cycle
- Defaults to False. If true, sets the CYCLE option.
-
- maxdb_cache
- With an integer value, sets the CACHE option.
-
- maxdb_no_cache
- Defaults to False. If true, sets NOCACHE.
- """
- sequence = create.element
-
- if (not sequence.optional and
- (not self.checkfirst or
- not self.dialect.has_sequence(self.connection, sequence.name))):
-
- ddl = ['CREATE SEQUENCE',
- self.preparer.format_sequence(sequence)]
-
- sequence.increment = 1
-
- if sequence.increment is not None:
- ddl.extend(('INCREMENT BY', str(sequence.increment)))
-
- if sequence.start is not None:
- ddl.extend(('START WITH', str(sequence.start)))
-
- opts = dict([(pair[0][6:].lower(), pair[1])
- for pair in sequence.kwargs.items()
- if pair[0].startswith('maxdb_')])
-
- if 'maxvalue' in opts:
- ddl.extend(('MAXVALUE', str(opts['maxvalue'])))
- elif opts.get('no_maxvalue', False):
- ddl.append('NOMAXVALUE')
- if 'minvalue' in opts:
- ddl.extend(('MINVALUE', str(opts['minvalue'])))
- elif opts.get('no_minvalue', False):
- ddl.append('NOMINVALUE')
-
- if opts.get('cycle', False):
- ddl.append('CYCLE')
-
- if 'cache' in opts:
- ddl.extend(('CACHE', str(opts['cache'])))
- elif opts.get('no_cache', False):
- ddl.append('NOCACHE')
-
- return ' '.join(ddl)
-
-
-class MaxDBDialect(default.DefaultDialect):
- name = 'maxdb'
- supports_alter = True
- supports_unicode_statements = True
- max_identifier_length = 32
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = False
-
- preparer = MaxDBIdentifierPreparer
- statement_compiler = MaxDBCompiler
- ddl_compiler = MaxDBDDLCompiler
- execution_ctx_cls = MaxDBExecutionContext
-
- ported_sqla_06 = False
-
- colspecs = colspecs
- ischema_names = ischema_names
-
- # MaxDB-specific
- datetimeformat = 'internal'
-
- def __init__(self, _raise_known_sql_errors=False, **kw):
- super(MaxDBDialect, self).__init__(**kw)
- self._raise_known = _raise_known_sql_errors
-
- if self.dbapi is None:
- self.dbapi_type_map = {}
- else:
- self.dbapi_type_map = {
- 'Long Binary': MaxBlob(),
- 'Long byte_t': MaxBlob(),
- 'Long Unicode': MaxText(),
- 'Timestamp': MaxTimestamp(),
- 'Date': MaxDate(),
- 'Time': MaxTime(),
- datetime.datetime: MaxTimestamp(),
- datetime.date: MaxDate(),
- datetime.time: MaxTime(),
- }
-
- def do_execute(self, cursor, statement, parameters, context=None):
- res = cursor.execute(statement, parameters)
- if isinstance(res, int) and context is not None:
- context._rowcount = res
-
- def do_release_savepoint(self, connection, name):
- # Does MaxDB truly support RELEASE SAVEPOINT <id>? All my attempts
- # produce "SUBTRANS COMMIT/ROLLBACK not allowed without SUBTRANS
- # BEGIN SQLSTATE: I7065"
- # Note that ROLLBACK TO works fine. In theory, a RELEASE should
- # just free up some transactional resources early, before the overall
- # COMMIT/ROLLBACK so omitting it should be relatively ok.
- pass
-
- def _get_default_schema_name(self, connection):
- return self.identifier_preparer._normalize_name(
- connection.execute(
- 'SELECT CURRENT_SCHEMA FROM DUAL').scalar())
-
- def has_table(self, connection, table_name, schema=None):
- denormalize = self.identifier_preparer._denormalize_name
- bind = [denormalize(table_name)]
- if schema is None:
- sql = ("SELECT tablename FROM TABLES "
- "WHERE TABLES.TABLENAME=? AND"
- " TABLES.SCHEMANAME=CURRENT_SCHEMA ")
- else:
- sql = ("SELECT tablename FROM TABLES "
- "WHERE TABLES.TABLENAME = ? AND"
- " TABLES.SCHEMANAME=? ")
- bind.append(denormalize(schema))
-
- rp = connection.execute(sql, bind)
- return bool(rp.first())
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- if schema is None:
- sql = (" SELECT TABLENAME FROM TABLES WHERE "
- " SCHEMANAME=CURRENT_SCHEMA ")
- rs = connection.execute(sql)
- else:
- sql = (" SELECT TABLENAME FROM TABLES WHERE "
- " SCHEMANAME=? ")
- matchname = self.identifier_preparer._denormalize_name(schema)
- rs = connection.execute(sql, matchname)
- normalize = self.identifier_preparer._normalize_name
- return [normalize(row[0]) for row in rs]
-
- def reflecttable(self, connection, table, include_columns):
- denormalize = self.identifier_preparer._denormalize_name
- normalize = self.identifier_preparer._normalize_name
-
- st = ('SELECT COLUMNNAME, MODE, DATATYPE, CODETYPE, LEN, DEC, '
- ' NULLABLE, "DEFAULT", DEFAULTFUNCTION '
- 'FROM COLUMNS '
- 'WHERE TABLENAME=? AND SCHEMANAME=%s '
- 'ORDER BY POS')
-
- fk = ('SELECT COLUMNNAME, FKEYNAME, '
- ' REFSCHEMANAME, REFTABLENAME, REFCOLUMNNAME, RULE, '
- ' (CASE WHEN REFSCHEMANAME = CURRENT_SCHEMA '
- ' THEN 1 ELSE 0 END) AS in_schema '
- 'FROM FOREIGNKEYCOLUMNS '
- 'WHERE TABLENAME=? AND SCHEMANAME=%s '
- 'ORDER BY FKEYNAME ')
-
- params = [denormalize(table.name)]
- if not table.schema:
- st = st % 'CURRENT_SCHEMA'
- fk = fk % 'CURRENT_SCHEMA'
- else:
- st = st % '?'
- fk = fk % '?'
- params.append(denormalize(table.schema))
-
- rows = connection.execute(st, params).fetchall()
- if not rows:
- raise exc.NoSuchTableError(table.fullname)
-
- include_columns = set(include_columns or [])
-
- for row in rows:
- (name, mode, col_type, encoding, length, scale,
- nullable, constant_def, func_def) = row
-
- name = normalize(name)
-
- if include_columns and name not in include_columns:
- continue
-
- type_args, type_kw = [], {}
- if col_type == 'FIXED':
- type_args = length, scale
- # Convert FIXED(10) DEFAULT SERIAL to our Integer
- if (scale == 0 and
- func_def is not None and func_def.startswith('SERIAL')):
- col_type = 'INTEGER'
- type_args = length,
- elif col_type in 'FLOAT':
- type_args = length,
- elif col_type in ('CHAR', 'VARCHAR'):
- type_args = length,
- type_kw['encoding'] = encoding
- elif col_type == 'LONG':
- type_kw['encoding'] = encoding
-
- try:
- type_cls = ischema_names[col_type.lower()]
- type_instance = type_cls(*type_args, **type_kw)
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (col_type, name))
- type_instance = sqltypes.NullType
-
- col_kw = {'autoincrement': False}
- col_kw['nullable'] = (nullable == 'YES')
- col_kw['primary_key'] = (mode == 'KEY')
-
- if func_def is not None:
- if func_def.startswith('SERIAL'):
- if col_kw['primary_key']:
- # No special default- let the standard autoincrement
- # support handle SERIAL pk columns.
- col_kw['autoincrement'] = True
- else:
- # strip current numbering
- col_kw['server_default'] = schema.DefaultClause(
- sql.text('SERIAL'))
- col_kw['autoincrement'] = True
- else:
- col_kw['server_default'] = schema.DefaultClause(
- sql.text(func_def))
- elif constant_def is not None:
- col_kw['server_default'] = schema.DefaultClause(sql.text(
- "'%s'" % constant_def.replace("'", "''")))
-
- table.append_column(schema.Column(name, type_instance, **col_kw))
-
- fk_sets = itertools.groupby(connection.execute(fk, params),
- lambda row: row.FKEYNAME)
- for fkeyname, fkey in fk_sets:
- fkey = list(fkey)
- if include_columns:
- key_cols = set([r.COLUMNNAME for r in fkey])
- if key_cols != include_columns:
- continue
-
- columns, referants = [], []
- quote = self.identifier_preparer._maybe_quote_identifier
-
- for row in fkey:
- columns.append(normalize(row.COLUMNNAME))
- if table.schema or not row.in_schema:
- referants.append('.'.join(
- [quote(normalize(row[c]))
- for c in ('REFSCHEMANAME', 'REFTABLENAME',
- 'REFCOLUMNNAME')]))
- else:
- referants.append('.'.join(
- [quote(normalize(row[c]))
- for c in ('REFTABLENAME', 'REFCOLUMNNAME')]))
-
- constraint_kw = {'name': fkeyname.lower()}
- if fkey[0].RULE is not None:
- rule = fkey[0].RULE
- if rule.startswith('DELETE '):
- rule = rule[7:]
- constraint_kw['ondelete'] = rule
-
- table_kw = {}
- if table.schema or not row.in_schema:
- table_kw['schema'] = normalize(fkey[0].REFSCHEMANAME)
-
- ref_key = schema._get_table_key(normalize(fkey[0].REFTABLENAME),
- table_kw.get('schema'))
- if ref_key not in table.metadata.tables:
- schema.Table(normalize(fkey[0].REFTABLENAME),
- table.metadata,
- autoload=True, autoload_with=connection,
- **table_kw)
-
- constraint = schema.ForeignKeyConstraint(
- columns, referants, link_to_name=True,
- **constraint_kw)
- table.append_constraint(constraint)
-
- def has_sequence(self, connection, name):
- # [ticket:726] makes this schema-aware.
- denormalize = self.identifier_preparer._denormalize_name
- sql = ("SELECT sequence_name FROM SEQUENCES "
- "WHERE SEQUENCE_NAME=? ")
-
- rp = connection.execute(sql, denormalize(name))
- return bool(rp.first())
-
-
-def _autoserial_column(table):
- """Finds the effective DEFAULT SERIAL column of a Table, if any."""
-
- for index, col in enumerate(table.primary_key.columns):
- if (isinstance(col.type, (sqltypes.Integer, sqltypes.Numeric)) and
- col.autoincrement):
- if isinstance(col.default, schema.Sequence):
- if col.default.optional:
- return index, col
- elif (col.default is None or
- (not isinstance(col.server_default, schema.DefaultClause))):
- return index, col
-
- return None, None
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/sapdb.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/sapdb.py
deleted file mode 100755
index da04d809..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/maxdb/sapdb.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# maxdb/sapdb.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.maxdb.base import MaxDBDialect
-
-class MaxDBDialect_sapdb(MaxDBDialect):
- driver = 'sapdb'
-
- @classmethod
- def dbapi(cls):
- from sapdb import dbapi as _dbapi
- return _dbapi
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- opts.update(url.query)
- return [], opts
-
-
-dialect = MaxDBDialect_sapdb \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/__init__.py
deleted file mode 100755
index 6e7bae44..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# mssql/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.mssql import base, pyodbc, adodbapi, \
- pymssql, zxjdbc, mxodbc
-
-base.dialect = pyodbc.dialect
-
-from sqlalchemy.dialects.mssql.base import \
- INTEGER, BIGINT, SMALLINT, TINYINT, VARCHAR, NVARCHAR, CHAR, \
- NCHAR, TEXT, NTEXT, DECIMAL, NUMERIC, FLOAT, DATETIME,\
- DATETIME2, DATETIMEOFFSET, DATE, TIME, SMALLDATETIME, \
- BINARY, VARBINARY, BIT, REAL, IMAGE, TIMESTAMP,\
- MONEY, SMALLMONEY, UNIQUEIDENTIFIER, SQL_VARIANT, dialect
-
-
-__all__ = (
- 'INTEGER', 'BIGINT', 'SMALLINT', 'TINYINT', 'VARCHAR', 'NVARCHAR', 'CHAR',
- 'NCHAR', 'TEXT', 'NTEXT', 'DECIMAL', 'NUMERIC', 'FLOAT', 'DATETIME',
- 'DATETIME2', 'DATETIMEOFFSET', 'DATE', 'TIME', 'SMALLDATETIME',
- 'BINARY', 'VARBINARY', 'BIT', 'REAL', 'IMAGE', 'TIMESTAMP',
- 'MONEY', 'SMALLMONEY', 'UNIQUEIDENTIFIER', 'SQL_VARIANT', 'dialect'
-) \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/adodbapi.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/adodbapi.py
deleted file mode 100755
index f2d945de..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/adodbapi.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# mssql/adodbapi.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-The adodbapi dialect is not implemented for 0.6 at this time.
-
-"""
-import datetime
-from sqlalchemy import types as sqltypes, util
-from sqlalchemy.dialects.mssql.base import MSDateTime, MSDialect
-import sys
-
-class MSDateTime_adodbapi(MSDateTime):
- def result_processor(self, dialect, coltype):
- def process(value):
- # adodbapi will return datetimes with empty time
- # values as datetime.date() objects.
- # Promote them back to full datetime.datetime()
- if type(value) is datetime.date:
- return datetime.datetime(value.year, value.month, value.day)
- return value
- return process
-
-
-class MSDialect_adodbapi(MSDialect):
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = True
- supports_unicode = sys.maxunicode == 65535
- supports_unicode_statements = True
- driver = 'adodbapi'
-
- @classmethod
- def import_dbapi(cls):
- import adodbapi as module
- return module
-
- colspecs = util.update_copy(
- MSDialect.colspecs,
- {
- sqltypes.DateTime:MSDateTime_adodbapi
- }
- )
-
- def create_connect_args(self, url):
- keys = url.query
-
- connectors = ["Provider=SQLOLEDB"]
- if 'port' in keys:
- connectors.append ("Data Source=%s, %s" %
- (keys.get("host"), keys.get("port")))
- else:
- connectors.append ("Data Source=%s" % keys.get("host"))
- connectors.append ("Initial Catalog=%s" % keys.get("database"))
- user = keys.get("user")
- if user:
- connectors.append("User Id=%s" % user)
- connectors.append("Password=%s" % keys.get("password", ""))
- else:
- connectors.append("Integrated Security=SSPI")
- return [[";".join (connectors)], {}]
-
- def is_disconnect(self, e, connection, cursor):
- return isinstance(e, self.dbapi.adodbapi.DatabaseError) and \
- "'connection failure'" in str(e)
-
-dialect = MSDialect_adodbapi
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/base.py
deleted file mode 100755
index e349092f..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/base.py
+++ /dev/null
@@ -1,1456 +0,0 @@
-# mssql/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Microsoft SQL Server database.
-
-Connecting
-----------
-
-See the individual driver sections below for details on connecting.
-
-Auto Increment Behavior
------------------------
-
-``IDENTITY`` columns are supported by using SQLAlchemy
-``schema.Sequence()`` objects. In other words::
-
- from sqlalchemy import Table, Integer, Sequence, Column
-
- Table('test', metadata,
- Column('id', Integer,
- Sequence('blah',100,10), primary_key=True),
- Column('name', String(20))
- ).create(some_engine)
-
-would yield::
-
- CREATE TABLE test (
- id INTEGER NOT NULL IDENTITY(100,10) PRIMARY KEY,
- name VARCHAR(20) NULL,
- )
-
-Note that the ``start`` and ``increment`` values for sequences are
-optional and will default to 1,1.
-
-Implicit ``autoincrement`` behavior works the same in MSSQL as it
-does in other dialects and results in an ``IDENTITY`` column.
-
-* Support for ``SET IDENTITY_INSERT ON`` mode (automagic on / off for
- ``INSERT`` s)
-
-* Support for auto-fetching of ``@@IDENTITY/@@SCOPE_IDENTITY()`` on
- ``INSERT``
-
-Collation Support
------------------
-
-MSSQL specific string types support a collation parameter that
-creates a column-level specific collation for the column. The
-collation parameter accepts a Windows Collation Name or a SQL
-Collation Name. Supported types are MSChar, MSNChar, MSString,
-MSNVarchar, MSText, and MSNText. For example::
-
- from sqlalchemy.dialects.mssql import VARCHAR
- Column('login', VARCHAR(32, collation='Latin1_General_CI_AS'))
-
-When such a column is associated with a :class:`.Table`, the
-CREATE TABLE statement for this column will yield::
-
- login VARCHAR(32) COLLATE Latin1_General_CI_AS NULL
-
-LIMIT/OFFSET Support
---------------------
-
-MSSQL has no support for the LIMIT or OFFSET keysowrds. LIMIT is
-supported directly through the ``TOP`` Transact SQL keyword::
-
- select.limit
-
-will yield::
-
- SELECT TOP n
-
-If using SQL Server 2005 or above, LIMIT with OFFSET
-support is available through the ``ROW_NUMBER OVER`` construct.
-For versions below 2005, LIMIT with OFFSET usage will fail.
-
-Nullability
------------
-MSSQL has support for three levels of column nullability. The default
-nullability allows nulls and is explicit in the CREATE TABLE
-construct::
-
- name VARCHAR(20) NULL
-
-If ``nullable=None`` is specified then no specification is made. In
-other words the database's configured default is used. This will
-render::
-
- name VARCHAR(20)
-
-If ``nullable`` is ``True`` or ``False`` then the column will be
-``NULL` or ``NOT NULL`` respectively.
-
-Date / Time Handling
---------------------
-DATE and TIME are supported. Bind parameters are converted
-to datetime.datetime() objects as required by most MSSQL drivers,
-and results are processed from strings if needed.
-The DATE and TIME types are not available for MSSQL 2005 and
-previous - if a server version below 2008 is detected, DDL
-for these types will be issued as DATETIME.
-
-Compatibility Levels
---------------------
-MSSQL supports the notion of setting compatibility levels at the
-database level. This allows, for instance, to run a database that
-is compatibile with SQL2000 while running on a SQL2005 database
-server. ``server_version_info`` will always return the database
-server version information (in this case SQL2005) and not the
-compatibiility level information. Because of this, if running under
-a backwards compatibility mode SQAlchemy may attempt to use T-SQL
-statements that are unable to be parsed by the database server.
-
-Triggers
---------
-
-SQLAlchemy by default uses OUTPUT INSERTED to get at newly
-generated primary key values via IDENTITY columns or other
-server side defaults. MS-SQL does not
-allow the usage of OUTPUT INSERTED on tables that have triggers.
-To disable the usage of OUTPUT INSERTED on a per-table basis,
-specify ``implicit_returning=False`` for each :class:`.Table`
-which has triggers::
-
- Table('mytable', metadata,
- Column('id', Integer, primary_key=True),
- # ...,
- implicit_returning=False
- )
-
-Declarative form::
-
- class MyClass(Base):
- # ...
- __table_args__ = {'implicit_returning':False}
-
-
-This option can also be specified engine-wide using the
-``implicit_returning=False`` argument on :func:`.create_engine`.
-
-Enabling Snapshot Isolation
----------------------------
-
-Not necessarily specific to SQLAlchemy, SQL Server has a default transaction
-isolation mode that locks entire tables, and causes even mildly concurrent
-applications to have long held locks and frequent deadlocks.
-Enabling snapshot isolation for the database as a whole is recommended
-for modern levels of concurrency support. This is accomplished via the
-following ALTER DATABASE commands executed at the SQL prompt::
-
- ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
-
- ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
-
-Background on SQL Server snapshot isolation is available at
-http://msdn.microsoft.com/en-us/library/ms175095.aspx.
-
-Known Issues
-------------
-
-* No support for more than one ``IDENTITY`` column per table
-* reflection of indexes does not work with versions older than
- SQL Server 2005
-
-"""
-import datetime, operator, re
-
-from sqlalchemy import sql, schema as sa_schema, exc, util
-from sqlalchemy.sql import select, compiler, expression, \
- operators as sql_operators, \
- util as sql_util
-from sqlalchemy.engine import default, base, reflection
-from sqlalchemy import types as sqltypes
-from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, DECIMAL, NUMERIC, \
- FLOAT, TIMESTAMP, DATETIME, DATE, BINARY,\
- VARBINARY, BLOB
-
-
-from sqlalchemy.dialects.mssql import information_schema as ischema
-
-MS_2008_VERSION = (10,)
-MS_2005_VERSION = (9,)
-MS_2000_VERSION = (8,)
-
-RESERVED_WORDS = set(
- ['add', 'all', 'alter', 'and', 'any', 'as', 'asc', 'authorization',
- 'backup', 'begin', 'between', 'break', 'browse', 'bulk', 'by', 'cascade',
- 'case', 'check', 'checkpoint', 'close', 'clustered', 'coalesce',
- 'collate', 'column', 'commit', 'compute', 'constraint', 'contains',
- 'containstable', 'continue', 'convert', 'create', 'cross', 'current',
- 'current_date', 'current_time', 'current_timestamp', 'current_user',
- 'cursor', 'database', 'dbcc', 'deallocate', 'declare', 'default',
- 'delete', 'deny', 'desc', 'disk', 'distinct', 'distributed', 'double',
- 'drop', 'dump', 'else', 'end', 'errlvl', 'escape', 'except', 'exec',
- 'execute', 'exists', 'exit', 'external', 'fetch', 'file', 'fillfactor',
- 'for', 'foreign', 'freetext', 'freetexttable', 'from', 'full',
- 'function', 'goto', 'grant', 'group', 'having', 'holdlock', 'identity',
- 'identity_insert', 'identitycol', 'if', 'in', 'index', 'inner', 'insert',
- 'intersect', 'into', 'is', 'join', 'key', 'kill', 'left', 'like',
- 'lineno', 'load', 'merge', 'national', 'nocheck', 'nonclustered', 'not',
- 'null', 'nullif', 'of', 'off', 'offsets', 'on', 'open', 'opendatasource',
- 'openquery', 'openrowset', 'openxml', 'option', 'or', 'order', 'outer',
- 'over', 'percent', 'pivot', 'plan', 'precision', 'primary', 'print',
- 'proc', 'procedure', 'public', 'raiserror', 'read', 'readtext',
- 'reconfigure', 'references', 'replication', 'restore', 'restrict',
- 'return', 'revert', 'revoke', 'right', 'rollback', 'rowcount',
- 'rowguidcol', 'rule', 'save', 'schema', 'securityaudit', 'select',
- 'session_user', 'set', 'setuser', 'shutdown', 'some', 'statistics',
- 'system_user', 'table', 'tablesample', 'textsize', 'then', 'to', 'top',
- 'tran', 'transaction', 'trigger', 'truncate', 'tsequal', 'union',
- 'unique', 'unpivot', 'update', 'updatetext', 'use', 'user', 'values',
- 'varying', 'view', 'waitfor', 'when', 'where', 'while', 'with',
- 'writetext',
- ])
-
-
-class REAL(sqltypes.REAL):
- __visit_name__ = 'REAL'
-
- def __init__(self, **kw):
- # REAL is a synonym for FLOAT(24) on SQL server
- kw['precision'] = 24
- super(REAL, self).__init__(**kw)
-
-class TINYINT(sqltypes.Integer):
- __visit_name__ = 'TINYINT'
-
-
-# MSSQL DATE/TIME types have varied behavior, sometimes returning
-# strings. MSDate/TIME check for everything, and always
-# filter bind parameters into datetime objects (required by pyodbc,
-# not sure about other dialects).
-
-class _MSDate(sqltypes.Date):
- def bind_processor(self, dialect):
- def process(value):
- if type(value) == datetime.date:
- return datetime.datetime(value.year, value.month, value.day)
- else:
- return value
- return process
-
- _reg = re.compile(r"(\d+)-(\d+)-(\d+)")
- def result_processor(self, dialect, coltype):
- def process(value):
- if isinstance(value, datetime.datetime):
- return value.date()
- elif isinstance(value, basestring):
- return datetime.date(*[
- int(x or 0)
- for x in self._reg.match(value).groups()
- ])
- else:
- return value
- return process
-
-class TIME(sqltypes.TIME):
- def __init__(self, precision=None, **kwargs):
- self.precision = precision
- super(TIME, self).__init__()
-
- __zero_date = datetime.date(1900, 1, 1)
-
- def bind_processor(self, dialect):
- def process(value):
- if isinstance(value, datetime.datetime):
- value = datetime.datetime.combine(
- self.__zero_date, value.time())
- elif isinstance(value, datetime.time):
- value = datetime.datetime.combine(self.__zero_date, value)
- return value
- return process
-
- _reg = re.compile(r"(\d+):(\d+):(\d+)(?:\.(\d+))?")
- def result_processor(self, dialect, coltype):
- def process(value):
- if isinstance(value, datetime.datetime):
- return value.time()
- elif isinstance(value, basestring):
- return datetime.time(*[
- int(x or 0)
- for x in self._reg.match(value).groups()])
- else:
- return value
- return process
-
-class _DateTimeBase(object):
- def bind_processor(self, dialect):
- def process(value):
- if type(value) == datetime.date:
- return datetime.datetime(value.year, value.month, value.day)
- else:
- return value
- return process
-
-class _MSDateTime(_DateTimeBase, sqltypes.DateTime):
- pass
-
-class SMALLDATETIME(_DateTimeBase, sqltypes.DateTime):
- __visit_name__ = 'SMALLDATETIME'
-
-class DATETIME2(_DateTimeBase, sqltypes.DateTime):
- __visit_name__ = 'DATETIME2'
-
- def __init__(self, precision=None, **kw):
- super(DATETIME2, self).__init__(**kw)
- self.precision = precision
-
-
-# TODO: is this not an Interval ?
-class DATETIMEOFFSET(sqltypes.TypeEngine):
- __visit_name__ = 'DATETIMEOFFSET'
-
- def __init__(self, precision=None, **kwargs):
- self.precision = precision
-
-class _StringType(object):
- """Base for MSSQL string types."""
-
- def __init__(self, collation=None):
- self.collation = collation
-
-class TEXT(_StringType, sqltypes.TEXT):
- """MSSQL TEXT type, for variable-length text up to 2^31 characters."""
-
- def __init__(self, length=None, collation=None, **kw):
- """Construct a TEXT.
-
- :param collation: Optional, a column-level collation for this string
- value. Accepts a Windows Collation Name or a SQL Collation Name.
-
- """
- _StringType.__init__(self, collation)
- sqltypes.Text.__init__(self, length, **kw)
-
-class NTEXT(_StringType, sqltypes.UnicodeText):
- """MSSQL NTEXT type, for variable-length unicode text up to 2^30
- characters."""
-
- __visit_name__ = 'NTEXT'
-
- def __init__(self, length=None, collation=None, **kw):
- """Construct a NTEXT.
-
- :param collation: Optional, a column-level collation for this string
- value. Accepts a Windows Collation Name or a SQL Collation Name.
-
- """
- _StringType.__init__(self, collation)
- sqltypes.UnicodeText.__init__(self, length, **kw)
-
-
-class VARCHAR(_StringType, sqltypes.VARCHAR):
- """MSSQL VARCHAR type, for variable-length non-Unicode data with a maximum
- of 8,000 characters."""
-
- def __init__(self, length=None, collation=None, **kw):
- """Construct a VARCHAR.
-
- :param length: Optinal, maximum data length, in characters.
-
- :param convert_unicode: defaults to False. If True, convert
- ``unicode`` data sent to the database to a ``str``
- bytestring, and convert bytestrings coming back from the
- database into ``unicode``.
-
- Bytestrings are encoded using the dialect's
- :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which
- defaults to `utf-8`.
-
- If False, may be overridden by
- :attr:`sqlalchemy.engine.base.Dialect.convert_unicode`.
-
- :param collation: Optional, a column-level collation for this string
- value. Accepts a Windows Collation Name or a SQL Collation Name.
-
- """
- _StringType.__init__(self, collation)
- sqltypes.VARCHAR.__init__(self, length, **kw)
-
-class NVARCHAR(_StringType, sqltypes.NVARCHAR):
- """MSSQL NVARCHAR type.
-
- For variable-length unicode character data up to 4,000 characters."""
-
- def __init__(self, length=None, collation=None, **kw):
- """Construct a NVARCHAR.
-
- :param length: Optional, Maximum data length, in characters.
-
- :param collation: Optional, a column-level collation for this string
- value. Accepts a Windows Collation Name or a SQL Collation Name.
-
- """
- _StringType.__init__(self, collation)
- sqltypes.NVARCHAR.__init__(self, length, **kw)
-
-class CHAR(_StringType, sqltypes.CHAR):
- """MSSQL CHAR type, for fixed-length non-Unicode data with a maximum
- of 8,000 characters."""
-
- def __init__(self, length=None, collation=None, **kw):
- """Construct a CHAR.
-
- :param length: Optinal, maximum data length, in characters.
-
- :param convert_unicode: defaults to False. If True, convert
- ``unicode`` data sent to the database to a ``str``
- bytestring, and convert bytestrings coming back from the
- database into ``unicode``.
-
- Bytestrings are encoded using the dialect's
- :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which
- defaults to `utf-8`.
-
- If False, may be overridden by
- :attr:`sqlalchemy.engine.base.Dialect.convert_unicode`.
-
- :param collation: Optional, a column-level collation for this string
- value. Accepts a Windows Collation Name or a SQL Collation Name.
-
- """
- _StringType.__init__(self, collation)
- sqltypes.CHAR.__init__(self, length, **kw)
-
-class NCHAR(_StringType, sqltypes.NCHAR):
- """MSSQL NCHAR type.
-
- For fixed-length unicode character data up to 4,000 characters."""
-
- def __init__(self, length=None, collation=None, **kw):
- """Construct an NCHAR.
-
- :param length: Optional, Maximum data length, in characters.
-
- :param collation: Optional, a column-level collation for this string
- value. Accepts a Windows Collation Name or a SQL Collation Name.
-
- """
- _StringType.__init__(self, collation)
- sqltypes.NCHAR.__init__(self, length, **kw)
-
-class IMAGE(sqltypes.LargeBinary):
- __visit_name__ = 'IMAGE'
-
-class BIT(sqltypes.TypeEngine):
- __visit_name__ = 'BIT'
-
-
-class MONEY(sqltypes.TypeEngine):
- __visit_name__ = 'MONEY'
-
-class SMALLMONEY(sqltypes.TypeEngine):
- __visit_name__ = 'SMALLMONEY'
-
-class UNIQUEIDENTIFIER(sqltypes.TypeEngine):
- __visit_name__ = "UNIQUEIDENTIFIER"
-
-class SQL_VARIANT(sqltypes.TypeEngine):
- __visit_name__ = 'SQL_VARIANT'
-
-# old names.
-MSDateTime = _MSDateTime
-MSDate = _MSDate
-MSReal = REAL
-MSTinyInteger = TINYINT
-MSTime = TIME
-MSSmallDateTime = SMALLDATETIME
-MSDateTime2 = DATETIME2
-MSDateTimeOffset = DATETIMEOFFSET
-MSText = TEXT
-MSNText = NTEXT
-MSString = VARCHAR
-MSNVarchar = NVARCHAR
-MSChar = CHAR
-MSNChar = NCHAR
-MSBinary = BINARY
-MSVarBinary = VARBINARY
-MSImage = IMAGE
-MSBit = BIT
-MSMoney = MONEY
-MSSmallMoney = SMALLMONEY
-MSUniqueIdentifier = UNIQUEIDENTIFIER
-MSVariant = SQL_VARIANT
-
-ischema_names = {
- 'int' : INTEGER,
- 'bigint': BIGINT,
- 'smallint' : SMALLINT,
- 'tinyint' : TINYINT,
- 'varchar' : VARCHAR,
- 'nvarchar' : NVARCHAR,
- 'char' : CHAR,
- 'nchar' : NCHAR,
- 'text' : TEXT,
- 'ntext' : NTEXT,
- 'decimal' : DECIMAL,
- 'numeric' : NUMERIC,
- 'float' : FLOAT,
- 'datetime' : DATETIME,
- 'datetime2' : DATETIME2,
- 'datetimeoffset' : DATETIMEOFFSET,
- 'date': DATE,
- 'time': TIME,
- 'smalldatetime' : SMALLDATETIME,
- 'binary' : BINARY,
- 'varbinary' : VARBINARY,
- 'bit': BIT,
- 'real' : REAL,
- 'image' : IMAGE,
- 'timestamp': TIMESTAMP,
- 'money': MONEY,
- 'smallmoney': SMALLMONEY,
- 'uniqueidentifier': UNIQUEIDENTIFIER,
- 'sql_variant': SQL_VARIANT,
-}
-
-
-class MSTypeCompiler(compiler.GenericTypeCompiler):
- def _extend(self, spec, type_, length=None):
- """Extend a string-type declaration with standard SQL
- COLLATE annotations.
-
- """
-
- if getattr(type_, 'collation', None):
- collation = 'COLLATE %s' % type_.collation
- else:
- collation = None
-
- if not length:
- length = type_.length
-
- if length:
- spec = spec + "(%s)" % length
-
- return ' '.join([c for c in (spec, collation)
- if c is not None])
-
- def visit_FLOAT(self, type_):
- precision = getattr(type_, 'precision', None)
- if precision is None:
- return "FLOAT"
- else:
- return "FLOAT(%(precision)s)" % {'precision': precision}
-
- def visit_TINYINT(self, type_):
- return "TINYINT"
-
- def visit_DATETIMEOFFSET(self, type_):
- if type_.precision:
- return "DATETIMEOFFSET(%s)" % type_.precision
- else:
- return "DATETIMEOFFSET"
-
- def visit_TIME(self, type_):
- precision = getattr(type_, 'precision', None)
- if precision:
- return "TIME(%s)" % precision
- else:
- return "TIME"
-
- def visit_DATETIME2(self, type_):
- precision = getattr(type_, 'precision', None)
- if precision:
- return "DATETIME2(%s)" % precision
- else:
- return "DATETIME2"
-
- def visit_SMALLDATETIME(self, type_):
- return "SMALLDATETIME"
-
- def visit_unicode(self, type_):
- return self.visit_NVARCHAR(type_)
-
- def visit_unicode_text(self, type_):
- return self.visit_NTEXT(type_)
-
- def visit_NTEXT(self, type_):
- return self._extend("NTEXT", type_)
-
- def visit_TEXT(self, type_):
- return self._extend("TEXT", type_)
-
- def visit_VARCHAR(self, type_):
- return self._extend("VARCHAR", type_,
- length = type_.length or 'max')
-
- def visit_CHAR(self, type_):
- return self._extend("CHAR", type_)
-
- def visit_NCHAR(self, type_):
- return self._extend("NCHAR", type_)
-
- def visit_NVARCHAR(self, type_):
- return self._extend("NVARCHAR", type_,
- length = type_.length or 'max')
-
- def visit_date(self, type_):
- if self.dialect.server_version_info < MS_2008_VERSION:
- return self.visit_DATETIME(type_)
- else:
- return self.visit_DATE(type_)
-
- def visit_time(self, type_):
- if self.dialect.server_version_info < MS_2008_VERSION:
- return self.visit_DATETIME(type_)
- else:
- return self.visit_TIME(type_)
-
- def visit_large_binary(self, type_):
- return self.visit_IMAGE(type_)
-
- def visit_IMAGE(self, type_):
- return "IMAGE"
-
- def visit_VARBINARY(self, type_):
- return self._extend(
- "VARBINARY",
- type_,
- length=type_.length or 'max')
-
- def visit_boolean(self, type_):
- return self.visit_BIT(type_)
-
- def visit_BIT(self, type_):
- return "BIT"
-
- def visit_MONEY(self, type_):
- return "MONEY"
-
- def visit_SMALLMONEY(self, type_):
- return 'SMALLMONEY'
-
- def visit_UNIQUEIDENTIFIER(self, type_):
- return "UNIQUEIDENTIFIER"
-
- def visit_SQL_VARIANT(self, type_):
- return 'SQL_VARIANT'
-
-class MSExecutionContext(default.DefaultExecutionContext):
- _enable_identity_insert = False
- _select_lastrowid = False
- _result_proxy = None
- _lastrowid = None
-
- def pre_exec(self):
- """Activate IDENTITY_INSERT if needed."""
-
- if self.isinsert:
- tbl = self.compiled.statement.table
- seq_column = tbl._autoincrement_column
- insert_has_sequence = seq_column is not None
-
- if insert_has_sequence:
- self._enable_identity_insert = \
- seq_column.key in self.compiled_parameters[0]
- else:
- self._enable_identity_insert = False
-
- self._select_lastrowid = insert_has_sequence and \
- not self.compiled.returning and \
- not self._enable_identity_insert and \
- not self.executemany
-
- if self._enable_identity_insert:
- self.cursor.execute("SET IDENTITY_INSERT %s ON" %
- self.dialect.identifier_preparer.format_table(tbl))
-
- def post_exec(self):
- """Disable IDENTITY_INSERT if enabled."""
-
- if self._select_lastrowid:
- if self.dialect.use_scope_identity:
- self.cursor.execute(
- "SELECT scope_identity() AS lastrowid", ())
- else:
- self.cursor.execute("SELECT @@identity AS lastrowid", ())
- # fetchall() ensures the cursor is consumed without closing it
- row = self.cursor.fetchall()[0]
- self._lastrowid = int(row[0])
-
- if (self.isinsert or self.isupdate or self.isdelete) and \
- self.compiled.returning:
- self._result_proxy = base.FullyBufferedResultProxy(self)
-
- if self._enable_identity_insert:
- self.cursor.execute(
- "SET IDENTITY_INSERT %s OFF" %
- self.dialect.identifier_preparer.
- format_table(self.compiled.statement.table)
- )
-
- def get_lastrowid(self):
- return self._lastrowid
-
- def handle_dbapi_exception(self, e):
- if self._enable_identity_insert:
- try:
- self.cursor.execute(
- "SET IDENTITY_INSERT %s OFF" %
- self.dialect.identifier_preparer.\
- format_table(self.compiled.statement.table)
- )
- except:
- pass
-
- def get_result_proxy(self):
- if self._result_proxy:
- return self._result_proxy
- else:
- return base.ResultProxy(self)
-
-class MSSQLCompiler(compiler.SQLCompiler):
- returning_precedes_values = True
-
- extract_map = util.update_copy(
- compiler.SQLCompiler.extract_map,
- {
- 'doy': 'dayofyear',
- 'dow': 'weekday',
- 'milliseconds': 'millisecond',
- 'microseconds': 'microsecond'
- })
-
- def __init__(self, *args, **kwargs):
- self.tablealiases = {}
- super(MSSQLCompiler, self).__init__(*args, **kwargs)
-
- def visit_now_func(self, fn, **kw):
- return "CURRENT_TIMESTAMP"
-
- def visit_current_date_func(self, fn, **kw):
- return "GETDATE()"
-
- def visit_length_func(self, fn, **kw):
- return "LEN%s" % self.function_argspec(fn, **kw)
-
- def visit_char_length_func(self, fn, **kw):
- return "LEN%s" % self.function_argspec(fn, **kw)
-
- def visit_concat_op(self, binary, **kw):
- return "%s + %s" % \
- (self.process(binary.left, **kw),
- self.process(binary.right, **kw))
-
- def visit_match_op(self, binary, **kw):
- return "CONTAINS (%s, %s)" % (
- self.process(binary.left, **kw),
- self.process(binary.right, **kw))
-
- def get_select_precolumns(self, select):
- """ MS-SQL puts TOP, it's version of LIMIT here """
- if select._distinct or select._limit:
- s = select._distinct and "DISTINCT " or ""
-
- # ODBC drivers and possibly others
- # don't support bind params in the SELECT clause on SQL Server.
- # so have to use literal here.
- if select._limit:
- if not select._offset:
- s += "TOP %d " % select._limit
- return s
- return compiler.SQLCompiler.get_select_precolumns(self, select)
-
- def limit_clause(self, select):
- # Limit in mssql is after the select keyword
- return ""
-
- def visit_select(self, select, **kwargs):
- """Look for ``LIMIT`` and OFFSET in a select statement, and if
- so tries to wrap it in a subquery with ``row_number()`` criterion.
-
- """
- if not getattr(select, '_mssql_visit', None) and select._offset:
- # to use ROW_NUMBER(), an ORDER BY is required.
- orderby = self.process(select._order_by_clause)
- if not orderby:
- raise exc.InvalidRequestError('MSSQL requires an order_by when '
- 'using an offset.')
-
- _offset = select._offset
- _limit = select._limit
- select._mssql_visit = True
- select = select.column(
- sql.literal_column("ROW_NUMBER() OVER (ORDER BY %s)" \
- % orderby).label("mssql_rn")
- ).order_by(None).alias()
-
- mssql_rn = sql.column('mssql_rn')
- limitselect = sql.select([c for c in select.c if
- c.key!='mssql_rn'])
- limitselect.append_whereclause(mssql_rn> _offset)
- if _limit is not None:
- limitselect.append_whereclause(mssql_rn<=(_limit + _offset))
- return self.process(limitselect, iswrapper=True, **kwargs)
- else:
- return compiler.SQLCompiler.visit_select(self, select, **kwargs)
-
- def _schema_aliased_table(self, table):
- if getattr(table, 'schema', None) is not None:
- if table not in self.tablealiases:
- self.tablealiases[table] = table.alias()
- return self.tablealiases[table]
- else:
- return None
-
- def visit_table(self, table, mssql_aliased=False, **kwargs):
- if mssql_aliased is table:
- return super(MSSQLCompiler, self).visit_table(table, **kwargs)
-
- # alias schema-qualified tables
- alias = self._schema_aliased_table(table)
- if alias is not None:
- return self.process(alias, mssql_aliased=table, **kwargs)
- else:
- return super(MSSQLCompiler, self).visit_table(table, **kwargs)
-
- def visit_alias(self, alias, **kwargs):
- # translate for schema-qualified table aliases
- kwargs['mssql_aliased'] = alias.original
- return super(MSSQLCompiler, self).visit_alias(alias, **kwargs)
-
- def visit_extract(self, extract, **kw):
- field = self.extract_map.get(extract.field, extract.field)
- return 'DATEPART("%s", %s)' % \
- (field, self.process(extract.expr, **kw))
-
- def visit_rollback_to_savepoint(self, savepoint_stmt):
- return ("ROLLBACK TRANSACTION %s"
- % self.preparer.format_savepoint(savepoint_stmt))
-
- def visit_column(self, column, result_map=None, **kwargs):
- if column.table is not None and \
- (not self.isupdate and not self.isdelete) or self.is_subquery():
- # translate for schema-qualified table aliases
- t = self._schema_aliased_table(column.table)
- if t is not None:
- converted = expression._corresponding_column_or_error(
- t, column)
-
- if result_map is not None:
- result_map[column.name.lower()] = \
- (column.name, (column, ),
- column.type)
-
- return super(MSSQLCompiler, self).\
- visit_column(converted,
- result_map=None, **kwargs)
-
- return super(MSSQLCompiler, self).visit_column(column,
- result_map=result_map,
- **kwargs)
-
- def visit_binary(self, binary, **kwargs):
- """Move bind parameters to the right-hand side of an operator, where
- possible.
-
- """
- if (
- isinstance(binary.left, expression._BindParamClause)
- and binary.operator == operator.eq
- and not isinstance(binary.right, expression._BindParamClause)
- ):
- return self.process(
- expression._BinaryExpression(binary.right,
- binary.left,
- binary.operator),
- **kwargs)
- else:
- if (
- (binary.operator is operator.eq or
- binary.operator is operator.ne)
- and (
- (isinstance(binary.left, expression._FromGrouping)
- and isinstance(binary.left.element,
- expression._ScalarSelect))
- or (isinstance(binary.right, expression._FromGrouping)
- and isinstance(binary.right.element,
- expression._ScalarSelect))
- or isinstance(binary.left, expression._ScalarSelect)
- or isinstance(binary.right, expression._ScalarSelect)
- )
- ):
- op = binary.operator == operator.eq and "IN" or "NOT IN"
- return self.process(
- expression._BinaryExpression(binary.left,
- binary.right, op),
- **kwargs)
- return super(MSSQLCompiler, self).visit_binary(binary, **kwargs)
-
- def returning_clause(self, stmt, returning_cols):
-
- if self.isinsert or self.isupdate:
- target = stmt.table.alias("inserted")
- else:
- target = stmt.table.alias("deleted")
-
- adapter = sql_util.ClauseAdapter(target)
- def col_label(col):
- adapted = adapter.traverse(col)
- if isinstance(col, expression._Label):
- return adapted.label(c.key)
- else:
- return self.label_select_column(None, adapted, asfrom=False)
-
- columns = [
- self.process(
- col_label(c),
- within_columns_clause=True,
- result_map=self.result_map
- )
- for c in expression._select_iterables(returning_cols)
- ]
- return 'OUTPUT ' + ', '.join(columns)
-
- def label_select_column(self, select, column, asfrom):
- if isinstance(column, expression.Function):
- return column.label(None)
- else:
- return super(MSSQLCompiler, self).\
- label_select_column(select, column, asfrom)
-
- def for_update_clause(self, select):
- # "FOR UPDATE" is only allowed on "DECLARE CURSOR" which
- # SQLAlchemy doesn't use
- return ''
-
- def order_by_clause(self, select, **kw):
- order_by = self.process(select._order_by_clause, **kw)
-
- # MSSQL only allows ORDER BY in subqueries if there is a LIMIT
- if order_by and (not self.is_subquery() or select._limit):
- return " ORDER BY " + order_by
- else:
- return ""
-
-class MSSQLStrictCompiler(MSSQLCompiler):
- """A subclass of MSSQLCompiler which disables the usage of bind
- parameters where not allowed natively by MS-SQL.
-
- A dialect may use this compiler on a platform where native
- binds are used.
-
- """
- ansi_bind_rules = True
-
- def visit_in_op(self, binary, **kw):
- kw['literal_binds'] = True
- return "%s IN %s" % (
- self.process(binary.left, **kw),
- self.process(binary.right, **kw)
- )
-
- def visit_notin_op(self, binary, **kw):
- kw['literal_binds'] = True
- return "%s NOT IN %s" % (
- self.process(binary.left, **kw),
- self.process(binary.right, **kw)
- )
-
- def visit_function(self, func, **kw):
- kw['literal_binds'] = True
- return super(MSSQLStrictCompiler, self).visit_function(func, **kw)
-
- def render_literal_value(self, value, type_):
- """
- For date and datetime values, convert to a string
- format acceptable to MSSQL. That seems to be the
- so-called ODBC canonical date format which looks
- like this:
-
- yyyy-mm-dd hh:mi:ss.mmm(24h)
-
- For other data types, call the base class implementation.
- """
- # datetime and date are both subclasses of datetime.date
- if issubclass(type(value), datetime.date):
- # SQL Server wants single quotes around the date string.
- return "'" + str(value) + "'"
- else:
- return super(MSSQLStrictCompiler, self).\
- render_literal_value(value, type_)
-
-class MSDDLCompiler(compiler.DDLCompiler):
- def get_column_specification(self, column, **kwargs):
- colspec = (self.preparer.format_column(column) + " "
- + self.dialect.type_compiler.process(column.type))
-
- if column.nullable is not None:
- if not column.nullable or column.primary_key:
- colspec += " NOT NULL"
- else:
- colspec += " NULL"
-
- if column.table is None:
- raise exc.InvalidRequestError(
- "mssql requires Table-bound columns "
- "in order to generate DDL")
-
- seq_col = column.table._autoincrement_column
-
- # install a IDENTITY Sequence if we have an implicit IDENTITY column
- if seq_col is column:
- sequence = isinstance(column.default, sa_schema.Sequence) and \
- column.default
- if sequence:
- start, increment = sequence.start or 1, \
- sequence.increment or 1
- else:
- start, increment = 1, 1
- colspec += " IDENTITY(%s,%s)" % (start, increment)
- else:
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- return colspec
-
- def visit_drop_index(self, drop):
- return "\nDROP INDEX %s.%s" % (
- self.preparer.quote_identifier(drop.element.table.name),
- self.preparer.quote(
- self._index_identifier(drop.element.name),
- drop.element.quote)
- )
-
-
-class MSIdentifierPreparer(compiler.IdentifierPreparer):
- reserved_words = RESERVED_WORDS
-
- def __init__(self, dialect):
- super(MSIdentifierPreparer, self).__init__(dialect, initial_quote='[',
- final_quote=']')
-
- def _escape_identifier(self, value):
- return value
-
- def quote_schema(self, schema, force=True):
- """Prepare a quoted table and schema name."""
- result = '.'.join([self.quote(x, force) for x in schema.split('.')])
- return result
-
-class MSDialect(default.DefaultDialect):
- name = 'mssql'
- supports_default_values = True
- supports_empty_insert = False
- execution_ctx_cls = MSExecutionContext
- use_scope_identity = True
- max_identifier_length = 128
- schema_name = "dbo"
-
- colspecs = {
- sqltypes.DateTime : _MSDateTime,
- sqltypes.Date : _MSDate,
- sqltypes.Time : TIME,
- }
-
- ischema_names = ischema_names
-
- supports_native_boolean = False
- supports_unicode_binds = True
- postfetch_lastrowid = True
-
- server_version_info = ()
-
- statement_compiler = MSSQLCompiler
- ddl_compiler = MSDDLCompiler
- type_compiler = MSTypeCompiler
- preparer = MSIdentifierPreparer
-
- def __init__(self,
- query_timeout=None,
- use_scope_identity=True,
- max_identifier_length=None,
- schema_name=u"dbo", **opts):
- self.query_timeout = int(query_timeout or 0)
- self.schema_name = schema_name
-
- self.use_scope_identity = use_scope_identity
- self.max_identifier_length = int(max_identifier_length or 0) or \
- self.max_identifier_length
- super(MSDialect, self).__init__(**opts)
-
- def do_savepoint(self, connection, name):
- util.warn("Savepoint support in mssql is experimental and "
- "may lead to data loss.")
- connection.execute("IF @@TRANCOUNT = 0 BEGIN TRANSACTION")
- connection.execute("SAVE TRANSACTION %s" % name)
-
- def do_release_savepoint(self, connection, name):
- pass
-
- def initialize(self, connection):
- super(MSDialect, self).initialize(connection)
- if self.server_version_info[0] not in range(8, 17):
- # FreeTDS with version 4.2 seems to report here
- # a number like "95.10.255". Don't know what
- # that is. So emit warning.
- util.warn(
- "Unrecognized server version info '%s'. Version specific "
- "behaviors may not function properly. If using ODBC "
- "with FreeTDS, ensure server version 7.0 or 8.0, not 4.2, "
- "is configured in the FreeTDS configuration." %
- ".".join(str(x) for x in self.server_version_info) )
- if self.server_version_info >= MS_2005_VERSION and \
- 'implicit_returning' not in self.__dict__:
- self.implicit_returning = True
-
- def _get_default_schema_name(self, connection):
- user_name = connection.scalar("SELECT user_name() as user_name;")
- if user_name is not None:
- # now, get the default schema
- query = sql.text("""
- SELECT default_schema_name FROM
- sys.database_principals
- WHERE name = :name
- AND type = 'S'
- """)
- try:
- default_schema_name = connection.scalar(query, name=user_name)
- if default_schema_name is not None:
- return unicode(default_schema_name)
- except:
- pass
- return self.schema_name
-
-
- def has_table(self, connection, tablename, schema=None):
- current_schema = schema or self.default_schema_name
- columns = ischema.columns
- if current_schema:
- whereclause = sql.and_(columns.c.table_name==tablename,
- columns.c.table_schema==current_schema)
- else:
- whereclause = columns.c.table_name==tablename
- s = sql.select([columns], whereclause)
- c = connection.execute(s)
- return c.first() is not None
-
- @reflection.cache
- def get_schema_names(self, connection, **kw):
- s = sql.select([ischema.schemata.c.schema_name],
- order_by=[ischema.schemata.c.schema_name]
- )
- schema_names = [r[0] for r in connection.execute(s)]
- return schema_names
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- current_schema = schema or self.default_schema_name
- tables = ischema.tables
- s = sql.select([tables.c.table_name],
- sql.and_(
- tables.c.table_schema == current_schema,
- tables.c.table_type == u'BASE TABLE'
- ),
- order_by=[tables.c.table_name]
- )
- table_names = [r[0] for r in connection.execute(s)]
- return table_names
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- current_schema = schema or self.default_schema_name
- tables = ischema.tables
- s = sql.select([tables.c.table_name],
- sql.and_(
- tables.c.table_schema == current_schema,
- tables.c.table_type == u'VIEW'
- ),
- order_by=[tables.c.table_name]
- )
- view_names = [r[0] for r in connection.execute(s)]
- return view_names
-
- @reflection.cache
- def get_indexes(self, connection, tablename, schema=None, **kw):
- # using system catalogs, don't support index reflection
- # below MS 2005
- if self.server_version_info < MS_2005_VERSION:
- return []
-
- current_schema = schema or self.default_schema_name
- full_tname = "%s.%s" % (current_schema, tablename)
-
- rp = connection.execute(
- sql.text("select ind.index_id, ind.is_unique, ind.name "
- "from sys.indexes as ind join sys.tables as tab on "
- "ind.object_id=tab.object_id "
- "join sys.schemas as sch on sch.schema_id=tab.schema_id "
- "where tab.name = :tabname "
- "and sch.name=:schname "
- "and ind.is_primary_key=0",
- bindparams=[
- sql.bindparam('tabname', tablename,
- sqltypes.String(convert_unicode=True)),
- sql.bindparam('schname', current_schema,
- sqltypes.String(convert_unicode=True))
- ]
- )
- )
- indexes = {}
- for row in rp:
- indexes[row['index_id']] = {
- 'name':row['name'],
- 'unique':row['is_unique'] == 1,
- 'column_names':[]
- }
- rp = connection.execute(
- sql.text(
- "select ind_col.index_id, ind_col.object_id, col.name "
- "from sys.columns as col "
- "join sys.tables as tab on tab.object_id=col.object_id "
- "join sys.index_columns as ind_col on "
- "(ind_col.column_id=col.column_id and "
- "ind_col.object_id=tab.object_id) "
- "join sys.schemas as sch on sch.schema_id=tab.schema_id "
- "where tab.name=:tabname "
- "and sch.name=:schname",
- bindparams=[
- sql.bindparam('tabname', tablename,
- sqltypes.String(convert_unicode=True)),
- sql.bindparam('schname', current_schema,
- sqltypes.String(convert_unicode=True))
- ]),
- )
- for row in rp:
- if row['index_id'] in indexes:
- indexes[row['index_id']]['column_names'].append(row['name'])
-
- return indexes.values()
-
- @reflection.cache
- def get_view_definition(self, connection, viewname, schema=None, **kw):
- current_schema = schema or self.default_schema_name
-
- rp = connection.execute(
- sql.text(
- "select definition from sys.sql_modules as mod, "
- "sys.views as views, "
- "sys.schemas as sch"
- " where "
- "mod.object_id=views.object_id and "
- "views.schema_id=sch.schema_id and "
- "views.name=:viewname and sch.name=:schname",
- bindparams=[
- sql.bindparam('viewname', viewname,
- sqltypes.String(convert_unicode=True)),
- sql.bindparam('schname', current_schema,
- sqltypes.String(convert_unicode=True))
- ]
- )
- )
-
- if rp:
- view_def = rp.scalar()
- return view_def
-
- @reflection.cache
- def get_columns(self, connection, tablename, schema=None, **kw):
- # Get base columns
- current_schema = schema or self.default_schema_name
- columns = ischema.columns
- if current_schema:
- whereclause = sql.and_(columns.c.table_name==tablename,
- columns.c.table_schema==current_schema)
- else:
- whereclause = columns.c.table_name==tablename
- s = sql.select([columns], whereclause,
- order_by=[columns.c.ordinal_position])
- c = connection.execute(s)
- cols = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- (name, type, nullable, charlen,
- numericprec, numericscale, default, collation) = (
- row[columns.c.column_name],
- row[columns.c.data_type],
- row[columns.c.is_nullable] == 'YES',
- row[columns.c.character_maximum_length],
- row[columns.c.numeric_precision],
- row[columns.c.numeric_scale],
- row[columns.c.column_default],
- row[columns.c.collation_name]
- )
- coltype = self.ischema_names.get(type, None)
-
- kwargs = {}
- if coltype in (MSString, MSChar, MSNVarchar, MSNChar, MSText,
- MSNText, MSBinary, MSVarBinary,
- sqltypes.LargeBinary):
- kwargs['length'] = charlen
- if collation:
- kwargs['collation'] = collation
- if coltype == MSText or \
- (coltype in (MSString, MSNVarchar) and charlen == -1):
- kwargs.pop('length')
-
- if coltype is None:
- util.warn(
- "Did not recognize type '%s' of column '%s'" %
- (type, name))
- coltype = sqltypes.NULLTYPE
- else:
- if issubclass(coltype, sqltypes.Numeric) and \
- coltype is not MSReal:
- kwargs['scale'] = numericscale
- kwargs['precision'] = numericprec
-
- coltype = coltype(**kwargs)
- cdict = {
- 'name' : name,
- 'type' : coltype,
- 'nullable' : nullable,
- 'default' : default,
- 'autoincrement':False,
- }
- cols.append(cdict)
- # autoincrement and identity
- colmap = {}
- for col in cols:
- colmap[col['name']] = col
- # We also run an sp_columns to check for identity columns:
- cursor = connection.execute("sp_columns @table_name = '%s', "
- "@table_owner = '%s'"
- % (tablename, current_schema))
- ic = None
- while True:
- row = cursor.fetchone()
- if row is None:
- break
- (col_name, type_name) = row[3], row[5]
- if type_name.endswith("identity") and col_name in colmap:
- ic = col_name
- colmap[col_name]['autoincrement'] = True
- colmap[col_name]['sequence'] = dict(
- name='%s_identity' % col_name)
- break
- cursor.close()
-
- if ic is not None and self.server_version_info >= MS_2005_VERSION:
- table_fullname = "%s.%s" % (current_schema, tablename)
- cursor = connection.execute(
- "select ident_seed('%s'), ident_incr('%s')"
- % (table_fullname, table_fullname)
- )
-
- row = cursor.first()
- if row is not None and row[0] is not None:
- colmap[ic]['sequence'].update({
- 'start' : int(row[0]),
- 'increment' : int(row[1])
- })
- return cols
-
- @reflection.cache
- def get_primary_keys(self, connection, tablename, schema=None, **kw):
- current_schema = schema or self.default_schema_name
- pkeys = []
- # information_schema.referential_constraints
- RR = ischema.ref_constraints
- # information_schema.table_constraints
- TC = ischema.constraints
- # information_schema.constraint_column_usage:
- # the constrained column
- C = ischema.key_constraints.alias('C')
- # information_schema.constraint_column_usage:
- # the referenced column
- R = ischema.key_constraints.alias('R')
-
- # Primary key constraints
- s = sql.select([C.c.column_name, TC.c.constraint_type],
- sql.and_(TC.c.constraint_name == C.c.constraint_name,
- C.c.table_name == tablename,
- C.c.table_schema == current_schema)
- )
- c = connection.execute(s)
- for row in c:
- if 'PRIMARY' in row[TC.c.constraint_type.name]:
- pkeys.append(row[0])
- return pkeys
-
- @reflection.cache
- def get_foreign_keys(self, connection, tablename, schema=None, **kw):
- current_schema = schema or self.default_schema_name
- # Add constraints
- #information_schema.referential_constraints
- RR = ischema.ref_constraints
- # information_schema.table_constraints
- TC = ischema.constraints
- # information_schema.constraint_column_usage:
- # the constrained column
- C = ischema.key_constraints.alias('C')
- # information_schema.constraint_column_usage:
- # the referenced column
- R = ischema.key_constraints.alias('R')
-
- # Foreign key constraints
- s = sql.select([C.c.column_name,
- R.c.table_schema, R.c.table_name, R.c.column_name,
- RR.c.constraint_name, RR.c.match_option,
- RR.c.update_rule,
- RR.c.delete_rule],
- sql.and_(C.c.table_name == tablename,
- C.c.table_schema == current_schema,
- C.c.constraint_name == RR.c.constraint_name,
- R.c.constraint_name ==
- RR.c.unique_constraint_name,
- C.c.ordinal_position == R.c.ordinal_position
- ),
- order_by = [
- RR.c.constraint_name,
- R.c.ordinal_position])
-
-
- # group rows by constraint ID, to handle multi-column FKs
- fkeys = []
- fknm, scols, rcols = (None, [], [])
-
- def fkey_rec():
- return {
- 'name' : None,
- 'constrained_columns' : [],
- 'referred_schema' : None,
- 'referred_table' : None,
- 'referred_columns' : []
- }
-
- fkeys = util.defaultdict(fkey_rec)
-
- for r in connection.execute(s).fetchall():
- scol, rschema, rtbl, rcol, rfknm, fkmatch, fkuprule, fkdelrule = r
-
- rec = fkeys[rfknm]
- rec['name'] = rfknm
- if not rec['referred_table']:
- rec['referred_table'] = rtbl
-
- if schema is not None or current_schema != rschema:
- rec['referred_schema'] = rschema
-
- local_cols, remote_cols = \
- rec['constrained_columns'],\
- rec['referred_columns']
-
- local_cols.append(scol)
- remote_cols.append(rcol)
-
- return fkeys.values()
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/information_schema.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/information_schema.py
deleted file mode 100755
index 87dd0a16..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/information_schema.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# mssql/information_schema.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-# TODO: should be using the sys. catalog with SQL Server, not information schema
-
-from sqlalchemy import Table, MetaData, Column
-from sqlalchemy.types import String, Unicode, Integer, TypeDecorator
-
-ischema = MetaData()
-
-class CoerceUnicode(TypeDecorator):
- impl = Unicode
-
- def process_bind_param(self, value, dialect):
- if isinstance(value, str):
- value = value.decode(dialect.encoding)
- return value
-
-schemata = Table("SCHEMATA", ischema,
- Column("CATALOG_NAME", CoerceUnicode, key="catalog_name"),
- Column("SCHEMA_NAME", CoerceUnicode, key="schema_name"),
- Column("SCHEMA_OWNER", CoerceUnicode, key="schema_owner"),
- schema="INFORMATION_SCHEMA")
-
-tables = Table("TABLES", ischema,
- Column("TABLE_CATALOG", CoerceUnicode, key="table_catalog"),
- Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
- Column("TABLE_NAME", CoerceUnicode, key="table_name"),
- Column("TABLE_TYPE", String(convert_unicode=True), key="table_type"),
- schema="INFORMATION_SCHEMA")
-
-columns = Table("COLUMNS", ischema,
- Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
- Column("TABLE_NAME", CoerceUnicode, key="table_name"),
- Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
- Column("IS_NULLABLE", Integer, key="is_nullable"),
- Column("DATA_TYPE", String, key="data_type"),
- Column("ORDINAL_POSITION", Integer, key="ordinal_position"),
- Column("CHARACTER_MAXIMUM_LENGTH", Integer, key="character_maximum_length"),
- Column("NUMERIC_PRECISION", Integer, key="numeric_precision"),
- Column("NUMERIC_SCALE", Integer, key="numeric_scale"),
- Column("COLUMN_DEFAULT", Integer, key="column_default"),
- Column("COLLATION_NAME", String, key="collation_name"),
- schema="INFORMATION_SCHEMA")
-
-constraints = Table("TABLE_CONSTRAINTS", ischema,
- Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
- Column("TABLE_NAME", CoerceUnicode, key="table_name"),
- Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
- Column("CONSTRAINT_TYPE", String(convert_unicode=True), key="constraint_type"),
- schema="INFORMATION_SCHEMA")
-
-column_constraints = Table("CONSTRAINT_COLUMN_USAGE", ischema,
- Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
- Column("TABLE_NAME", CoerceUnicode, key="table_name"),
- Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
- Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
- schema="INFORMATION_SCHEMA")
-
-key_constraints = Table("KEY_COLUMN_USAGE", ischema,
- Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
- Column("TABLE_NAME", CoerceUnicode, key="table_name"),
- Column("COLUMN_NAME", CoerceUnicode, key="column_name"),
- Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
- Column("ORDINAL_POSITION", Integer, key="ordinal_position"),
- schema="INFORMATION_SCHEMA")
-
-ref_constraints = Table("REFERENTIAL_CONSTRAINTS", ischema,
- Column("CONSTRAINT_CATALOG", CoerceUnicode, key="constraint_catalog"),
- Column("CONSTRAINT_SCHEMA", CoerceUnicode, key="constraint_schema"),
- Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
- # TODO: is CATLOG misspelled ?
- Column("UNIQUE_CONSTRAINT_CATLOG", CoerceUnicode,
- key="unique_constraint_catalog"),
-
- Column("UNIQUE_CONSTRAINT_SCHEMA", CoerceUnicode,
- key="unique_constraint_schema"),
- Column("UNIQUE_CONSTRAINT_NAME", CoerceUnicode,
- key="unique_constraint_name"),
- Column("MATCH_OPTION", String, key="match_option"),
- Column("UPDATE_RULE", String, key="update_rule"),
- Column("DELETE_RULE", String, key="delete_rule"),
- schema="INFORMATION_SCHEMA")
-
-views = Table("VIEWS", ischema,
- Column("TABLE_CATALOG", CoerceUnicode, key="table_catalog"),
- Column("TABLE_SCHEMA", CoerceUnicode, key="table_schema"),
- Column("TABLE_NAME", CoerceUnicode, key="table_name"),
- Column("VIEW_DEFINITION", CoerceUnicode, key="view_definition"),
- Column("CHECK_OPTION", String, key="check_option"),
- Column("IS_UPDATABLE", String, key="is_updatable"),
- schema="INFORMATION_SCHEMA")
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/mxodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/mxodbc.py
deleted file mode 100755
index 6a830509..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/mxodbc.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# mssql/mxodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for MS-SQL via mxODBC.
-
-mxODBC is available at:
-
- http://www.egenix.com/
-
-This was tested with mxODBC 3.1.2 and the SQL Server Native
-Client connected to MSSQL 2005 and 2008 Express Editions.
-
-Connecting
-~~~~~~~~~~
-
-Connection is via DSN::
-
- mssql+mxodbc://<username>:<password>@<dsnname>
-
-Execution Modes
-~~~~~~~~~~~~~~~
-
-mxODBC features two styles of statement execution, using the
-``cursor.execute()`` and ``cursor.executedirect()`` methods (the second being
-an extension to the DBAPI specification). The former makes use of a particular
-API call specific to the SQL Server Native Client ODBC driver known
-SQLDescribeParam, while the latter does not.
-
-mxODBC apparently only makes repeated use of a single prepared statement
-when SQLDescribeParam is used. The advantage to prepared statement reuse is
-one of performance. The disadvantage is that SQLDescribeParam has a limited
-set of scenarios in which bind parameters are understood, including that they
-cannot be placed within the argument lists of function calls, anywhere outside
-the FROM, or even within subqueries within the FROM clause - making the usage
-of bind parameters within SELECT statements impossible for all but the most
-simplistic statements.
-
-For this reason, the mxODBC dialect uses the "native" mode by default only for
-INSERT, UPDATE, and DELETE statements, and uses the escaped string mode for
-all other statements.
-
-This behavior can be controlled via
-:meth:`~sqlalchemy.sql.expression.Executable.execution_options` using the
-``native_odbc_execute`` flag with a value of ``True`` or ``False``, where a
-value of ``True`` will unconditionally use native bind parameters and a value
-of ``False`` will uncondtionally use string-escaped parameters.
-
-"""
-
-
-from sqlalchemy import types as sqltypes
-from sqlalchemy.connectors.mxodbc import MxODBCConnector
-from sqlalchemy.dialects.mssql.pyodbc import MSExecutionContext_pyodbc
-from sqlalchemy.dialects.mssql.base import (MSDialect,
- MSSQLStrictCompiler,
- _MSDateTime, _MSDate, TIME)
-
-
-
-class MSExecutionContext_mxodbc(MSExecutionContext_pyodbc):
- """
- The pyodbc execution context is useful for enabling
- SELECT SCOPE_IDENTITY in cases where OUTPUT clause
- does not work (tables with insert triggers).
- """
- #todo - investigate whether the pyodbc execution context
- # is really only being used in cases where OUTPUT
- # won't work.
-
-class MSDialect_mxodbc(MxODBCConnector, MSDialect):
-
- # TODO: may want to use this only if FreeTDS is not in use,
- # since FreeTDS doesn't seem to use native binds.
- statement_compiler = MSSQLStrictCompiler
- execution_ctx_cls = MSExecutionContext_mxodbc
- colspecs = {
- #sqltypes.Numeric : _MSNumeric,
- sqltypes.DateTime : _MSDateTime,
- sqltypes.Date : _MSDate,
- sqltypes.Time : TIME,
- }
-
-
- def __init__(self, description_encoding='latin-1', **params):
- super(MSDialect_mxodbc, self).__init__(**params)
- self.description_encoding = description_encoding
-
-dialect = MSDialect_mxodbc
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pymssql.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pymssql.py
deleted file mode 100755
index 8bc0ad95..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pymssql.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# mssql/pymssql.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for the pymssql dialect.
-
-This dialect supports pymssql 1.0 and greater.
-
-pymssql is available at:
-
- http://pymssql.sourceforge.net/
-
-Connecting
-^^^^^^^^^^
-
-Sample connect string::
-
- mssql+pymssql://<username>:<password>@<freetds_name>
-
-Adding "?charset=utf8" or similar will cause pymssql to return
-strings as Python unicode objects. This can potentially improve
-performance in some scenarios as decoding of strings is
-handled natively.
-
-Limitations
-^^^^^^^^^^^
-
-pymssql inherits a lot of limitations from FreeTDS, including:
-
-* no support for multibyte schema identifiers
-* poor support for large decimals
-* poor support for binary fields
-* poor support for VARCHAR/CHAR fields over 255 characters
-
-Please consult the pymssql documentation for further information.
-
-"""
-from sqlalchemy.dialects.mssql.base import MSDialect
-from sqlalchemy import types as sqltypes, util, processors
-import re
-
-class _MSNumeric_pymssql(sqltypes.Numeric):
- def result_processor(self, dialect, type_):
- if not self.asdecimal:
- return processors.to_float
- else:
- return sqltypes.Numeric.result_processor(self, dialect, type_)
-
-class MSDialect_pymssql(MSDialect):
- supports_sane_rowcount = False
- max_identifier_length = 30
- driver = 'pymssql'
-
- colspecs = util.update_copy(
- MSDialect.colspecs,
- {
- sqltypes.Numeric:_MSNumeric_pymssql,
- sqltypes.Float:sqltypes.Float,
- }
- )
- @classmethod
- def dbapi(cls):
- module = __import__('pymssql')
- # pymmsql doesn't have a Binary method. we use string
- # TODO: monkeypatching here is less than ideal
- module.Binary = str
-
- client_ver = tuple(int(x) for x in module.__version__.split("."))
- if client_ver < (1, ):
- util.warn("The pymssql dialect expects at least "
- "the 1.0 series of the pymssql DBAPI.")
- return module
-
- def __init__(self, **params):
- super(MSDialect_pymssql, self).__init__(**params)
- self.use_scope_identity = True
-
- def _get_server_version_info(self, connection):
- vers = connection.scalar("select @@version")
- m = re.match(
- r"Microsoft SQL Server.*? - (\d+).(\d+).(\d+).(\d+)", vers)
- if m:
- return tuple(int(x) for x in m.group(1, 2, 3, 4))
- else:
- return None
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- opts.update(url.query)
- port = opts.pop('port', None)
- if port and 'host' in opts:
- opts['host'] = "%s:%s" % (opts['host'], port)
- return [[], opts]
-
- def is_disconnect(self, e, connection, cursor):
- for msg in (
- "Error 10054",
- "Not connected to any MS SQL server",
- "Connection is closed"
- ):
- if msg in str(e):
- return True
- else:
- return False
-
-dialect = MSDialect_pymssql
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pyodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pyodbc.py
deleted file mode 100755
index 9b88dce2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/pyodbc.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# mssql/pyodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for MS-SQL via pyodbc.
-
-pyodbc is available at:
-
- http://pypi.python.org/pypi/pyodbc/
-
-Connecting
-^^^^^^^^^^
-
-Examples of pyodbc connection string URLs:
-
-* ``mssql+pyodbc://mydsn`` - connects using the specified DSN named ``mydsn``.
- The connection string that is created will appear like::
-
- dsn=mydsn;Trusted_Connection=Yes
-
-* ``mssql+pyodbc://user:pass@mydsn`` - connects using the DSN named
- ``mydsn`` passing in the ``UID`` and ``PWD`` information. The
- connection string that is created will appear like::
-
- dsn=mydsn;UID=user;PWD=pass
-
-* ``mssql+pyodbc://user:pass@mydsn/?LANGUAGE=us_english`` - connects
- using the DSN named ``mydsn`` passing in the ``UID`` and ``PWD``
- information, plus the additional connection configuration option
- ``LANGUAGE``. The connection string that is created will appear
- like::
-
- dsn=mydsn;UID=user;PWD=pass;LANGUAGE=us_english
-
-* ``mssql+pyodbc://user:pass@host/db`` - connects using a connection string
- dynamically created that would appear like::
-
- DRIVER={SQL Server};Server=host;Database=db;UID=user;PWD=pass
-
-* ``mssql+pyodbc://user:pass@host:123/db`` - connects using a connection
- string that is dynamically created, which also includes the port
- information using the comma syntax. If your connection string
- requires the port information to be passed as a ``port`` keyword
- see the next example. This will create the following connection
- string::
-
- DRIVER={SQL Server};Server=host,123;Database=db;UID=user;PWD=pass
-
-* ``mssql+pyodbc://user:pass@host/db?port=123`` - connects using a connection
- string that is dynamically created that includes the port
- information as a separate ``port`` keyword. This will create the
- following connection string::
-
- DRIVER={SQL Server};Server=host;Database=db;UID=user;PWD=pass;port=123
-
-If you require a connection string that is outside the options
-presented above, use the ``odbc_connect`` keyword to pass in a
-urlencoded connection string. What gets passed in will be urldecoded
-and passed directly.
-
-For example::
-
- mssql+pyodbc:///?odbc_connect=dsn%3Dmydsn%3BDatabase%3Ddb
-
-would create the following connection string::
-
- dsn=mydsn;Database=db
-
-Encoding your connection string can be easily accomplished through
-the python shell. For example::
-
- >>> import urllib
- >>> urllib.quote_plus('dsn=mydsn;Database=db')
- 'dsn%3Dmydsn%3BDatabase%3Ddb'
-
-
-"""
-
-from sqlalchemy.dialects.mssql.base import MSExecutionContext, MSDialect
-from sqlalchemy.connectors.pyodbc import PyODBCConnector
-from sqlalchemy import types as sqltypes, util
-import decimal
-
-class _MSNumeric_pyodbc(sqltypes.Numeric):
- """Turns Decimals with adjusted() < 0 or > 7 into strings.
-
- This is the only method that is proven to work with Pyodbc+MSSQL
- without crashing (floats can be used but seem to cause sporadic
- crashes).
-
- """
-
- def bind_processor(self, dialect):
-
- super_process = super(_MSNumeric_pyodbc, self).\
- bind_processor(dialect)
-
- if not dialect._need_decimal_fix:
- return super_process
-
- def process(value):
- if self.asdecimal and \
- isinstance(value, decimal.Decimal):
-
- adjusted = value.adjusted()
- if adjusted < 0:
- return self._small_dec_to_string(value)
- elif adjusted > 7:
- return self._large_dec_to_string(value)
-
- if super_process:
- return super_process(value)
- else:
- return value
- return process
-
- # these routines needed for older versions of pyodbc.
- # as of 2.1.8 this logic is integrated.
-
- def _small_dec_to_string(self, value):
- return "%s0.%s%s" % (
- (value < 0 and '-' or ''),
- '0' * (abs(value.adjusted()) - 1),
- "".join([str(nint) for nint in value.as_tuple()[1]]))
-
- def _large_dec_to_string(self, value):
- _int = value.as_tuple()[1]
- if 'E' in str(value):
- result = "%s%s%s" % (
- (value < 0 and '-' or ''),
- "".join([str(s) for s in _int]),
- "0" * (value.adjusted() - (len(_int)-1)))
- else:
- if (len(_int) - 1) > value.adjusted():
- result = "%s%s.%s" % (
- (value < 0 and '-' or ''),
- "".join(
- [str(s) for s in _int][0:value.adjusted() + 1]),
- "".join(
- [str(s) for s in _int][value.adjusted() + 1:]))
- else:
- result = "%s%s" % (
- (value < 0 and '-' or ''),
- "".join(
- [str(s) for s in _int][0:value.adjusted() + 1]))
- return result
-
-
-class MSExecutionContext_pyodbc(MSExecutionContext):
- _embedded_scope_identity = False
-
- def pre_exec(self):
- """where appropriate, issue "select scope_identity()" in the same
- statement.
-
- Background on why "scope_identity()" is preferable to "@@identity":
- http://msdn.microsoft.com/en-us/library/ms190315.aspx
-
- Background on why we attempt to embed "scope_identity()" into the same
- statement as the INSERT:
- http://code.google.com/p/pyodbc/wiki/FAQs#How_do_I_retrieve_autogenerated/identity_values?
-
- """
-
- super(MSExecutionContext_pyodbc, self).pre_exec()
-
- # don't embed the scope_identity select into an
- # "INSERT .. DEFAULT VALUES"
- if self._select_lastrowid and \
- self.dialect.use_scope_identity and \
- len(self.parameters[0]):
- self._embedded_scope_identity = True
-
- self.statement += "; select scope_identity()"
-
- def post_exec(self):
- if self._embedded_scope_identity:
- # Fetch the last inserted id from the manipulated statement
- # We may have to skip over a number of result sets with
- # no data (due to triggers, etc.)
- while True:
- try:
- # fetchall() ensures the cursor is consumed
- # without closing it (FreeTDS particularly)
- row = self.cursor.fetchall()[0]
- break
- except self.dialect.dbapi.Error, e:
- # no way around this - nextset() consumes the previous set
- # so we need to just keep flipping
- self.cursor.nextset()
-
- self._lastrowid = int(row[0])
- else:
- super(MSExecutionContext_pyodbc, self).post_exec()
-
-
-class MSDialect_pyodbc(PyODBCConnector, MSDialect):
-
- execution_ctx_cls = MSExecutionContext_pyodbc
-
- pyodbc_driver_name = 'SQL Server'
-
- colspecs = util.update_copy(
- MSDialect.colspecs,
- {
- sqltypes.Numeric:_MSNumeric_pyodbc
- }
- )
-
- def __init__(self, description_encoding='latin-1', **params):
- super(MSDialect_pyodbc, self).__init__(**params)
- self.description_encoding = description_encoding
- self.use_scope_identity = self.dbapi and \
- hasattr(self.dbapi.Cursor, 'nextset')
- self._need_decimal_fix = self.dbapi and \
- tuple(self.dbapi.version.split(".")) < (2, 1, 8)
-
-dialect = MSDialect_pyodbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/zxjdbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/zxjdbc.py
deleted file mode 100755
index c293adbe..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mssql/zxjdbc.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# mssql/zxjdbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Microsoft SQL Server database via the zxjdbc JDBC
-connector.
-
-JDBC Driver
------------
-
-Requires the jTDS driver, available from: http://jtds.sourceforge.net/
-
-Connecting
-----------
-
-URLs are of the standard form of
-``mssql+zxjdbc://user:pass@host:port/dbname[?key=value&key=value...]``.
-
-Additional arguments which may be specified either as query string
-arguments on the URL, or as keyword arguments to
-:func:`~sqlalchemy.create_engine()` will be passed as Connection
-properties to the underlying JDBC driver.
-
-"""
-from sqlalchemy.connectors.zxJDBC import ZxJDBCConnector
-from sqlalchemy.dialects.mssql.base import MSDialect, MSExecutionContext
-from sqlalchemy.engine import base
-
-class MSExecutionContext_zxjdbc(MSExecutionContext):
-
- _embedded_scope_identity = False
-
- def pre_exec(self):
- super(MSExecutionContext_zxjdbc, self).pre_exec()
- # scope_identity after the fact returns null in jTDS so we must
- # embed it
- if self._select_lastrowid and self.dialect.use_scope_identity:
- self._embedded_scope_identity = True
- self.statement += "; SELECT scope_identity()"
-
- def post_exec(self):
- if self._embedded_scope_identity:
- while True:
- try:
- row = self.cursor.fetchall()[0]
- break
- except self.dialect.dbapi.Error, e:
- self.cursor.nextset()
- self._lastrowid = int(row[0])
-
- if (self.isinsert or self.isupdate or self.isdelete) and \
- self.compiled.returning:
- self._result_proxy = base.FullyBufferedResultProxy(self)
-
- if self._enable_identity_insert:
- table = self.dialect.identifier_preparer.format_table(
- self.compiled.statement.table)
- self.cursor.execute("SET IDENTITY_INSERT %s OFF" % table)
-
-
-class MSDialect_zxjdbc(ZxJDBCConnector, MSDialect):
- jdbc_db_name = 'jtds:sqlserver'
- jdbc_driver_name = 'net.sourceforge.jtds.jdbc.Driver'
-
- execution_ctx_cls = MSExecutionContext_zxjdbc
-
- def _get_server_version_info(self, connection):
- return tuple(
- int(x)
- for x in connection.connection.dbversion.split('.')
- )
-
-dialect = MSDialect_zxjdbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/__init__.py
deleted file mode 100755
index 7cab573e..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# mysql/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.mysql import base, mysqldb, oursql, \
- pyodbc, zxjdbc, mysqlconnector, pymysql
-
-# default dialect
-base.dialect = mysqldb.dialect
-
-from sqlalchemy.dialects.mysql.base import \
- BIGINT, BINARY, BIT, BLOB, BOOLEAN, CHAR, DATE, DATETIME, \
- DECIMAL, DOUBLE, ENUM, DECIMAL,\
- FLOAT, INTEGER, INTEGER, LONGBLOB, LONGTEXT, MEDIUMBLOB, \
- MEDIUMINT, MEDIUMTEXT, NCHAR, \
- NVARCHAR, NUMERIC, SET, SMALLINT, REAL, TEXT, TIME, TIMESTAMP, \
- TINYBLOB, TINYINT, TINYTEXT,\
- VARBINARY, VARCHAR, YEAR, dialect
-
-__all__ = (
-'BIGINT', 'BINARY', 'BIT', 'BLOB', 'BOOLEAN', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'DOUBLE',
-'ENUM', 'DECIMAL', 'FLOAT', 'INTEGER', 'INTEGER', 'LONGBLOB', 'LONGTEXT', 'MEDIUMBLOB', 'MEDIUMINT',
-'MEDIUMTEXT', 'NCHAR', 'NVARCHAR', 'NUMERIC', 'SET', 'SMALLINT', 'REAL', 'TEXT', 'TIME', 'TIMESTAMP',
-'TINYBLOB', 'TINYINT', 'TINYTEXT', 'VARBINARY', 'VARCHAR', 'YEAR', 'dialect'
-)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/base.py
deleted file mode 100755
index 33dc8a73..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/base.py
+++ /dev/null
@@ -1,2571 +0,0 @@
-# mysql/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database.
-
-Supported Versions and Features
--------------------------------
-
-SQLAlchemy supports 6 major MySQL versions: 3.23, 4.0, 4.1, 5.0, 5.1 and 6.0,
-with capabilities increasing with more modern servers.
-
-Versions 4.1 and higher support the basic SQL functionality that SQLAlchemy
-uses in the ORM and SQL expressions. These versions pass the applicable tests
-in the suite 100%. No heroic measures are taken to work around major missing
-SQL features- if your server version does not support sub-selects, for
-example, they won't work in SQLAlchemy either.
-
-Most available DBAPI drivers are supported; see below.
-
-===================================== ===============
-Feature Minimum Version
-===================================== ===============
-sqlalchemy.orm 4.1.1
-Table Reflection 3.23.x
-DDL Generation 4.1.1
-utf8/Full Unicode Connections 4.1.1
-Transactions 3.23.15
-Two-Phase Transactions 5.0.3
-Nested Transactions 5.0.3
-===================================== ===============
-
-See the official MySQL documentation for detailed information about features
-supported in any given server release.
-
-Connecting
-----------
-
-See the API documentation on individual drivers for details on connecting.
-
-Connection Timeouts
--------------------
-
-MySQL features an automatic connection close behavior, for connections that have
-been idle for eight hours or more. To circumvent having this issue, use the
-``pool_recycle`` option which controls the maximum age of any connection::
-
- engine = create_engine('mysql+mysqldb://...', pool_recycle=3600)
-
-Storage Engines
----------------
-
-Most MySQL server installations have a default table type of ``MyISAM``, a
-non-transactional table type. During a transaction, non-transactional storage
-engines do not participate and continue to store table changes in autocommit
-mode. For fully atomic transactions, all participating tables must use a
-transactional engine such as ``InnoDB``, ``Falcon``, ``SolidDB``, `PBXT`, etc.
-
-Storage engines can be elected when creating tables in SQLAlchemy by supplying
-a ``mysql_engine='whatever'`` to the ``Table`` constructor. Any MySQL table
-creation option can be specified in this syntax::
-
- Table('mytable', metadata,
- Column('data', String(32)),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
-Keys
-----
-
-Not all MySQL storage engines support foreign keys. For ``MyISAM`` and
-similar engines, the information loaded by table reflection will not include
-foreign keys. For these tables, you may supply a
-:class:`~sqlalchemy.ForeignKeyConstraint` at reflection time::
-
- Table('mytable', metadata,
- ForeignKeyConstraint(['other_id'], ['othertable.other_id']),
- autoload=True
- )
-
-When creating tables, SQLAlchemy will automatically set ``AUTO_INCREMENT`` on
-an integer primary key column::
-
- >>> t = Table('mytable', metadata,
- ... Column('mytable_id', Integer, primary_key=True)
- ... )
- >>> t.create()
- CREATE TABLE mytable (
- id INTEGER NOT NULL AUTO_INCREMENT,
- PRIMARY KEY (id)
- )
-
-You can disable this behavior by supplying ``autoincrement=False`` to the
-:class:`~sqlalchemy.Column`. This flag can also be used to enable
-auto-increment on a secondary column in a multi-column key for some storage
-engines::
-
- Table('mytable', metadata,
- Column('gid', Integer, primary_key=True, autoincrement=False),
- Column('id', Integer, primary_key=True)
- )
-
-SQL Mode
---------
-
-MySQL SQL modes are supported. Modes that enable ``ANSI_QUOTES`` (such as
-``ANSI``) require an engine option to modify SQLAlchemy's quoting style.
-When using an ANSI-quoting mode, supply ``use_ansiquotes=True`` when
-creating your ``Engine``::
-
- create_engine('mysql://localhost/test', use_ansiquotes=True)
-
-This is an engine-wide option and is not toggleable on a per-connection basis.
-SQLAlchemy does not presume to ``SET sql_mode`` for you with this option. For
-the best performance, set the quoting style server-wide in ``my.cnf`` or by
-supplying ``--sql-mode`` to ``mysqld``. You can also use a
-:class:`sqlalchemy.pool.Pool` listener hook to issue a ``SET SESSION
-sql_mode='...'`` on connect to configure each connection.
-
-If you do not specify ``use_ansiquotes``, the regular MySQL quoting style is
-used by default.
-
-If you do issue a ``SET sql_mode`` through SQLAlchemy, the dialect must be
-updated if the quoting style is changed. Again, this change will affect all
-connections::
-
- connection.execute('SET sql_mode="ansi"')
- connection.dialect.use_ansiquotes = True
-
-MySQL SQL Extensions
---------------------
-
-Many of the MySQL SQL extensions are handled through SQLAlchemy's generic
-function and operator support::
-
- table.select(table.c.password==func.md5('plaintext'))
- table.select(table.c.username.op('regexp')('^[a-d]'))
-
-And of course any valid MySQL statement can be executed as a string as well.
-
-Some limited direct support for MySQL extensions to SQL is currently
-available.
-
-* SELECT pragma::
-
- select(..., prefixes=['HIGH_PRIORITY', 'SQL_SMALL_RESULT'])
-
-* UPDATE with LIMIT::
-
- update(..., mysql_limit=10)
-
-"""
-
-import datetime, inspect, re, sys
-
-from sqlalchemy import schema as sa_schema
-from sqlalchemy import exc, log, sql, util
-from sqlalchemy.sql import operators as sql_operators
-from sqlalchemy.sql import functions as sql_functions
-from sqlalchemy.sql import compiler
-from array import array as _array
-
-from sqlalchemy.engine import reflection
-from sqlalchemy.engine import base as engine_base, default
-from sqlalchemy import types as sqltypes
-
-from sqlalchemy.types import DATE, DATETIME, BOOLEAN, TIME, \
- BLOB, BINARY, VARBINARY
-
-RESERVED_WORDS = set(
- ['accessible', 'add', 'all', 'alter', 'analyze','and', 'as', 'asc',
- 'asensitive', 'before', 'between', 'bigint', 'binary', 'blob', 'both',
- 'by', 'call', 'cascade', 'case', 'change', 'char', 'character', 'check',
- 'collate', 'column', 'condition', 'constraint', 'continue', 'convert',
- 'create', 'cross', 'current_date', 'current_time', 'current_timestamp',
- 'current_user', 'cursor', 'database', 'databases', 'day_hour',
- 'day_microsecond', 'day_minute', 'day_second', 'dec', 'decimal',
- 'declare', 'default', 'delayed', 'delete', 'desc', 'describe',
- 'deterministic', 'distinct', 'distinctrow', 'div', 'double', 'drop',
- 'dual', 'each', 'else', 'elseif', 'enclosed', 'escaped', 'exists',
- 'exit', 'explain', 'false', 'fetch', 'float', 'float4', 'float8',
- 'for', 'force', 'foreign', 'from', 'fulltext', 'grant', 'group', 'having',
- 'high_priority', 'hour_microsecond', 'hour_minute', 'hour_second', 'if',
- 'ignore', 'in', 'index', 'infile', 'inner', 'inout', 'insensitive',
- 'insert', 'int', 'int1', 'int2', 'int3', 'int4', 'int8', 'integer',
- 'interval', 'into', 'is', 'iterate', 'join', 'key', 'keys', 'kill',
- 'leading', 'leave', 'left', 'like', 'limit', 'linear', 'lines', 'load',
- 'localtime', 'localtimestamp', 'lock', 'long', 'longblob', 'longtext',
- 'loop', 'low_priority', 'master_ssl_verify_server_cert', 'match',
- 'mediumblob', 'mediumint', 'mediumtext', 'middleint',
- 'minute_microsecond', 'minute_second', 'mod', 'modifies', 'natural',
- 'not', 'no_write_to_binlog', 'null', 'numeric', 'on', 'optimize',
- 'option', 'optionally', 'or', 'order', 'out', 'outer', 'outfile',
- 'precision', 'primary', 'procedure', 'purge', 'range', 'read', 'reads',
- 'read_only', 'read_write', 'real', 'references', 'regexp', 'release',
- 'rename', 'repeat', 'replace', 'require', 'restrict', 'return',
- 'revoke', 'right', 'rlike', 'schema', 'schemas', 'second_microsecond',
- 'select', 'sensitive', 'separator', 'set', 'show', 'smallint', 'spatial',
- 'specific', 'sql', 'sqlexception', 'sqlstate', 'sqlwarning',
- 'sql_big_result', 'sql_calc_found_rows', 'sql_small_result', 'ssl',
- 'starting', 'straight_join', 'table', 'terminated', 'then', 'tinyblob',
- 'tinyint', 'tinytext', 'to', 'trailing', 'trigger', 'true', 'undo',
- 'union', 'unique', 'unlock', 'unsigned', 'update', 'usage', 'use',
- 'using', 'utc_date', 'utc_time', 'utc_timestamp', 'values', 'varbinary',
- 'varchar', 'varcharacter', 'varying', 'when', 'where', 'while', 'with',
- 'write', 'x509', 'xor', 'year_month', 'zerofill', # 5.0
- 'columns', 'fields', 'privileges', 'soname', 'tables', # 4.1
- 'accessible', 'linear', 'master_ssl_verify_server_cert', 'range',
- 'read_only', 'read_write', # 5.1
- ])
-
-AUTOCOMMIT_RE = re.compile(
- r'\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER|LOAD +DATA|REPLACE)',
- re.I | re.UNICODE)
-SET_RE = re.compile(
- r'\s*SET\s+(?:(?:GLOBAL|SESSION)\s+)?\w',
- re.I | re.UNICODE)
-
-
-class _NumericType(object):
- """Base for MySQL numeric types."""
-
- def __init__(self, unsigned=False, zerofill=False, **kw):
- self.unsigned = unsigned
- self.zerofill = zerofill
- super(_NumericType, self).__init__(**kw)
-
-class _FloatType(_NumericType, sqltypes.Float):
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- if isinstance(self, (REAL, DOUBLE)) and \
- (
- (precision is None and scale is not None) or
- (precision is not None and scale is None)
- ):
- raise exc.ArgumentError(
- "You must specify both precision and scale or omit "
- "both altogether.")
-
- super(_FloatType, self).__init__(precision=precision, asdecimal=asdecimal, **kw)
- self.scale = scale
-
-class _IntegerType(_NumericType, sqltypes.Integer):
- def __init__(self, display_width=None, **kw):
- self.display_width = display_width
- super(_IntegerType, self).__init__(**kw)
-
-class _StringType(sqltypes.String):
- """Base for MySQL string types."""
-
- def __init__(self, charset=None, collation=None,
- ascii=False, binary=False,
- national=False, **kw):
- self.charset = charset
- # allow collate= or collation=
- self.collation = kw.pop('collate', collation)
- self.ascii = ascii
- # We have to munge the 'unicode' param strictly as a dict
- # otherwise 2to3 will turn it into str.
- self.__dict__['unicode'] = kw.get('unicode', False)
- # sqltypes.String does not accept the 'unicode' arg at all.
- if 'unicode' in kw:
- del kw['unicode']
- self.binary = binary
- self.national = national
- super(_StringType, self).__init__(**kw)
-
- def __repr__(self):
- attributes = inspect.getargspec(self.__init__)[0][1:]
- attributes.extend(inspect.getargspec(_StringType.__init__)[0][1:])
-
- params = {}
- for attr in attributes:
- val = getattr(self, attr)
- if val is not None and val is not False:
- params[attr] = val
-
- return "%s(%s)" % (self.__class__.__name__,
- ', '.join(['%s=%r' % (k, params[k]) for k in params]))
-
-
-class NUMERIC(_NumericType, sqltypes.NUMERIC):
- """MySQL NUMERIC type."""
-
- __visit_name__ = 'NUMERIC'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a NUMERIC.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(NUMERIC, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
-
-
-class DECIMAL(_NumericType, sqltypes.DECIMAL):
- """MySQL DECIMAL type."""
-
- __visit_name__ = 'DECIMAL'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a DECIMAL.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(DECIMAL, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
-
-class DOUBLE(_FloatType):
- """MySQL DOUBLE type."""
-
- __visit_name__ = 'DOUBLE'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a DOUBLE.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(DOUBLE, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
-class REAL(_FloatType, sqltypes.REAL):
- """MySQL REAL type."""
-
- __visit_name__ = 'REAL'
-
- def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
- """Construct a REAL.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(REAL, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
-class FLOAT(_FloatType, sqltypes.FLOAT):
- """MySQL FLOAT type."""
-
- __visit_name__ = 'FLOAT'
-
- def __init__(self, precision=None, scale=None, asdecimal=False, **kw):
- """Construct a FLOAT.
-
- :param precision: Total digits in this number. If scale and precision
- are both None, values are stored to limits allowed by the server.
-
- :param scale: The number of digits after the decimal point.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(FLOAT, self).__init__(precision=precision, scale=scale,
- asdecimal=asdecimal, **kw)
-
- def bind_processor(self, dialect):
- return None
-
-class INTEGER(_IntegerType, sqltypes.INTEGER):
- """MySQL INTEGER type."""
-
- __visit_name__ = 'INTEGER'
-
- def __init__(self, display_width=None, **kw):
- """Construct an INTEGER.
-
- :param display_width: Optional, maximum display width for this number.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(INTEGER, self).__init__(display_width=display_width, **kw)
-
-class BIGINT(_IntegerType, sqltypes.BIGINT):
- """MySQL BIGINTEGER type."""
-
- __visit_name__ = 'BIGINT'
-
- def __init__(self, display_width=None, **kw):
- """Construct a BIGINTEGER.
-
- :param display_width: Optional, maximum display width for this number.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(BIGINT, self).__init__(display_width=display_width, **kw)
-
-class MEDIUMINT(_IntegerType):
- """MySQL MEDIUMINTEGER type."""
-
- __visit_name__ = 'MEDIUMINT'
-
- def __init__(self, display_width=None, **kw):
- """Construct a MEDIUMINTEGER
-
- :param display_width: Optional, maximum display width for this number.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(MEDIUMINT, self).__init__(display_width=display_width, **kw)
-
-class TINYINT(_IntegerType):
- """MySQL TINYINT type."""
-
- __visit_name__ = 'TINYINT'
-
- def __init__(self, display_width=None, **kw):
- """Construct a TINYINT.
-
- Note: following the usual MySQL conventions, TINYINT(1) columns
- reflected during Table(..., autoload=True) are treated as
- Boolean columns.
-
- :param display_width: Optional, maximum display width for this number.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(TINYINT, self).__init__(display_width=display_width, **kw)
-
-class SMALLINT(_IntegerType, sqltypes.SMALLINT):
- """MySQL SMALLINTEGER type."""
-
- __visit_name__ = 'SMALLINT'
-
- def __init__(self, display_width=None, **kw):
- """Construct a SMALLINTEGER.
-
- :param display_width: Optional, maximum display width for this number.
-
- :param unsigned: a boolean, optional.
-
- :param zerofill: Optional. If true, values will be stored as strings
- left-padded with zeros. Note that this does not effect the values
- returned by the underlying database API, which continue to be
- numeric.
-
- """
- super(SMALLINT, self).__init__(display_width=display_width, **kw)
-
-class BIT(sqltypes.TypeEngine):
- """MySQL BIT type.
-
- This type is for MySQL 5.0.3 or greater for MyISAM, and 5.0.5 or greater for
- MyISAM, MEMORY, InnoDB and BDB. For older versions, use a MSTinyInteger()
- type.
-
- """
-
- __visit_name__ = 'BIT'
-
- def __init__(self, length=None):
- """Construct a BIT.
-
- :param length: Optional, number of bits.
-
- """
- self.length = length
-
- def result_processor(self, dialect, coltype):
- """Convert a MySQL's 64 bit, variable length binary string to a long.
-
- TODO: this is MySQL-db, pyodbc specific. OurSQL and mysqlconnector
- already do this, so this logic should be moved to those dialects.
-
- """
-
- def process(value):
- if value is not None:
- v = 0L
- for i in map(ord, value):
- v = v << 8 | i
- return v
- return value
- return process
-
-class _MSTime(sqltypes.Time):
- """MySQL TIME type."""
-
- __visit_name__ = 'TIME'
-
- def result_processor(self, dialect, coltype):
- time = datetime.time
- def process(value):
- # convert from a timedelta value
- if value is not None:
- seconds = value.seconds
- minutes = seconds / 60
- return time(minutes / 60, minutes % 60, seconds - minutes * 60)
- else:
- return None
- return process
-
-class TIMESTAMP(sqltypes.TIMESTAMP):
- """MySQL TIMESTAMP type."""
- __visit_name__ = 'TIMESTAMP'
-
-class YEAR(sqltypes.TypeEngine):
- """MySQL YEAR type, for single byte storage of years 1901-2155."""
-
- __visit_name__ = 'YEAR'
-
- def __init__(self, display_width=None):
- self.display_width = display_width
-
-class TEXT(_StringType, sqltypes.TEXT):
- """MySQL TEXT type, for text up to 2^16 characters."""
-
- __visit_name__ = 'TEXT'
-
- def __init__(self, length=None, **kw):
- """Construct a TEXT.
-
- :param length: Optional, if provided the server may optimize storage
- by substituting the smallest TEXT type sufficient to store
- ``length`` characters.
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param national: Optional. If true, use the server's configured
- national character set.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(TEXT, self).__init__(length=length, **kw)
-
-class TINYTEXT(_StringType):
- """MySQL TINYTEXT type, for text up to 2^8 characters."""
-
- __visit_name__ = 'TINYTEXT'
-
- def __init__(self, **kwargs):
- """Construct a TINYTEXT.
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param national: Optional. If true, use the server's configured
- national character set.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(TINYTEXT, self).__init__(**kwargs)
-
-class MEDIUMTEXT(_StringType):
- """MySQL MEDIUMTEXT type, for text up to 2^24 characters."""
-
- __visit_name__ = 'MEDIUMTEXT'
-
- def __init__(self, **kwargs):
- """Construct a MEDIUMTEXT.
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param national: Optional. If true, use the server's configured
- national character set.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(MEDIUMTEXT, self).__init__(**kwargs)
-
-class LONGTEXT(_StringType):
- """MySQL LONGTEXT type, for text up to 2^32 characters."""
-
- __visit_name__ = 'LONGTEXT'
-
- def __init__(self, **kwargs):
- """Construct a LONGTEXT.
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param national: Optional. If true, use the server's configured
- national character set.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(LONGTEXT, self).__init__(**kwargs)
-
-
-class VARCHAR(_StringType, sqltypes.VARCHAR):
- """MySQL VARCHAR type, for variable-length character data."""
-
- __visit_name__ = 'VARCHAR'
-
- def __init__(self, length=None, **kwargs):
- """Construct a VARCHAR.
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param national: Optional. If true, use the server's configured
- national character set.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- super(VARCHAR, self).__init__(length=length, **kwargs)
-
-class CHAR(_StringType, sqltypes.CHAR):
- """MySQL CHAR type, for fixed-length character data."""
-
- __visit_name__ = 'CHAR'
-
- def __init__(self, length=None, **kwargs):
- """Construct a CHAR.
-
- :param length: Maximum data length, in characters.
-
- :param binary: Optional, use the default binary collation for the
- national character set. This does not affect the type of data
- stored, use a BINARY type for binary data.
-
- :param collation: Optional, request a particular collation. Must be
- compatible with the national character set.
-
- """
- super(CHAR, self).__init__(length=length, **kwargs)
-
-class NVARCHAR(_StringType, sqltypes.NVARCHAR):
- """MySQL NVARCHAR type.
-
- For variable-length character data in the server's configured national
- character set.
- """
-
- __visit_name__ = 'NVARCHAR'
-
- def __init__(self, length=None, **kwargs):
- """Construct an NVARCHAR.
-
- :param length: Maximum data length, in characters.
-
- :param binary: Optional, use the default binary collation for the
- national character set. This does not affect the type of data
- stored, use a BINARY type for binary data.
-
- :param collation: Optional, request a particular collation. Must be
- compatible with the national character set.
-
- """
- kwargs['national'] = True
- super(NVARCHAR, self).__init__(length=length, **kwargs)
-
-
-class NCHAR(_StringType, sqltypes.NCHAR):
- """MySQL NCHAR type.
-
- For fixed-length character data in the server's configured national
- character set.
- """
-
- __visit_name__ = 'NCHAR'
-
- def __init__(self, length=None, **kwargs):
- """Construct an NCHAR.
-
- :param length: Maximum data length, in characters.
-
- :param binary: Optional, use the default binary collation for the
- national character set. This does not affect the type of data
- stored, use a BINARY type for binary data.
-
- :param collation: Optional, request a particular collation. Must be
- compatible with the national character set.
-
- """
- kwargs['national'] = True
- super(NCHAR, self).__init__(length=length, **kwargs)
-
-
-
-
-class TINYBLOB(sqltypes._Binary):
- """MySQL TINYBLOB type, for binary data up to 2^8 bytes."""
-
- __visit_name__ = 'TINYBLOB'
-
-class MEDIUMBLOB(sqltypes._Binary):
- """MySQL MEDIUMBLOB type, for binary data up to 2^24 bytes."""
-
- __visit_name__ = 'MEDIUMBLOB'
-
-class LONGBLOB(sqltypes._Binary):
- """MySQL LONGBLOB type, for binary data up to 2^32 bytes."""
-
- __visit_name__ = 'LONGBLOB'
-
-class ENUM(sqltypes.Enum, _StringType):
- """MySQL ENUM type."""
-
- __visit_name__ = 'ENUM'
-
- def __init__(self, *enums, **kw):
- """Construct an ENUM.
-
- Example:
-
- Column('myenum', MSEnum("foo", "bar", "baz"))
-
- :param enums: The range of valid values for this ENUM. Values will be
- quoted when generating the schema according to the quoting flag (see
- below).
-
- :param strict: Defaults to False: ensure that a given value is in this
- ENUM's range of permissible values when inserting or updating rows.
- Note that MySQL will not raise a fatal error if you attempt to store
- an out of range value- an alternate value will be stored instead.
- (See MySQL ENUM documentation.)
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- :param quoting: Defaults to 'auto': automatically determine enum value
- quoting. If all enum values are surrounded by the same quoting
- character, then use 'quoted' mode. Otherwise, use 'unquoted' mode.
-
- 'quoted': values in enums are already quoted, they will be used
- directly when generating the schema - this usage is deprecated.
-
- 'unquoted': values in enums are not quoted, they will be escaped and
- surrounded by single quotes when generating the schema.
-
- Previous versions of this type always required manually quoted
- values to be supplied; future versions will always quote the string
- literals for you. This is a transitional option.
-
- """
- self.quoting = kw.pop('quoting', 'auto')
-
- if self.quoting == 'auto' and len(enums):
- # What quoting character are we using?
- q = None
- for e in enums:
- if len(e) == 0:
- self.quoting = 'unquoted'
- break
- elif q is None:
- q = e[0]
-
- if e[0] != q or e[-1] != q:
- self.quoting = 'unquoted'
- break
- else:
- self.quoting = 'quoted'
-
- if self.quoting == 'quoted':
- util.warn_deprecated(
- 'Manually quoting ENUM value literals is deprecated. Supply '
- 'unquoted values and use the quoting= option in cases of '
- 'ambiguity.')
- enums = self._strip_enums(enums)
-
- self.strict = kw.pop('strict', False)
- length = max([len(v) for v in enums] + [0])
- kw.pop('metadata', None)
- kw.pop('schema', None)
- kw.pop('name', None)
- kw.pop('quote', None)
- kw.pop('native_enum', None)
- _StringType.__init__(self, length=length, **kw)
- sqltypes.Enum.__init__(self, *enums)
-
- @classmethod
- def _strip_enums(cls, enums):
- strip_enums = []
- for a in enums:
- if a[0:1] == '"' or a[0:1] == "'":
- # strip enclosing quotes and unquote interior
- a = a[1:-1].replace(a[0] * 2, a[0])
- strip_enums.append(a)
- return strip_enums
-
- def bind_processor(self, dialect):
- super_convert = super(ENUM, self).bind_processor(dialect)
- def process(value):
- if self.strict and value is not None and value not in self.enums:
- raise exc.InvalidRequestError('"%s" not a valid value for '
- 'this enum' % value)
- if super_convert:
- return super_convert(value)
- else:
- return value
- return process
-
- def adapt(self, impltype, **kw):
- kw['strict'] = self.strict
- return sqltypes.Enum.adapt(self, impltype, **kw)
-
-class SET(_StringType):
- """MySQL SET type."""
-
- __visit_name__ = 'SET'
-
- def __init__(self, *values, **kw):
- """Construct a SET.
-
- Example::
-
- Column('myset', MSSet("'foo'", "'bar'", "'baz'"))
-
- :param values: The range of valid values for this SET. Values will be
- used exactly as they appear when generating schemas. Strings must
- be quoted, as in the example above. Single-quotes are suggested for
- ANSI compatibility and are required for portability to servers with
- ANSI_QUOTES enabled.
-
- :param charset: Optional, a column-level character set for this string
- value. Takes precedence to 'ascii' or 'unicode' short-hand.
-
- :param collation: Optional, a column-level collation for this string
- value. Takes precedence to 'binary' short-hand.
-
- :param ascii: Defaults to False: short-hand for the ``latin1``
- character set, generates ASCII in schema.
-
- :param unicode: Defaults to False: short-hand for the ``ucs2``
- character set, generates UNICODE in schema.
-
- :param binary: Defaults to False: short-hand, pick the binary
- collation type that matches the column's character set. Generates
- BINARY in schema. This does not affect the type of data stored,
- only the collation of character data.
-
- """
- self._ddl_values = values
-
- strip_values = []
- for a in values:
- if a[0:1] == '"' or a[0:1] == "'":
- # strip enclosing quotes and unquote interior
- a = a[1:-1].replace(a[0] * 2, a[0])
- strip_values.append(a)
-
- self.values = strip_values
- kw.setdefault('length', max([len(v) for v in strip_values] + [0]))
- super(SET, self).__init__(**kw)
-
- def result_processor(self, dialect, coltype):
- def process(value):
- # The good news:
- # No ',' quoting issues- commas aren't allowed in SET values
- # The bad news:
- # Plenty of driver inconsistencies here.
- if isinstance(value, util.set_types):
- # ..some versions convert '' to an empty set
- if not value:
- value.add('')
- # ..some return sets.Set, even for pythons that have __builtin__.set
- if not isinstance(value, set):
- value = set(value)
- return value
- # ...and some versions return strings
- if value is not None:
- return set(value.split(','))
- else:
- return value
- return process
-
- def bind_processor(self, dialect):
- super_convert = super(SET, self).bind_processor(dialect)
- def process(value):
- if value is None or isinstance(value, (int, long, basestring)):
- pass
- else:
- if None in value:
- value = set(value)
- value.remove(None)
- value.add('')
- value = ','.join(value)
- if super_convert:
- return super_convert(value)
- else:
- return value
- return process
-
-# old names
-MSTime = _MSTime
-MSSet = SET
-MSEnum = ENUM
-MSLongBlob = LONGBLOB
-MSMediumBlob = MEDIUMBLOB
-MSTinyBlob = TINYBLOB
-MSBlob = BLOB
-MSBinary = BINARY
-MSVarBinary = VARBINARY
-MSNChar = NCHAR
-MSNVarChar = NVARCHAR
-MSChar = CHAR
-MSString = VARCHAR
-MSLongText = LONGTEXT
-MSMediumText = MEDIUMTEXT
-MSTinyText = TINYTEXT
-MSText = TEXT
-MSYear = YEAR
-MSTimeStamp = TIMESTAMP
-MSBit = BIT
-MSSmallInteger = SMALLINT
-MSTinyInteger = TINYINT
-MSMediumInteger = MEDIUMINT
-MSBigInteger = BIGINT
-MSNumeric = NUMERIC
-MSDecimal = DECIMAL
-MSDouble = DOUBLE
-MSReal = REAL
-MSFloat = FLOAT
-MSInteger = INTEGER
-
-colspecs = {
- sqltypes.Numeric: NUMERIC,
- sqltypes.Float: FLOAT,
- sqltypes.Time: _MSTime,
- sqltypes.Enum: ENUM,
-}
-
-# Everything 3.23 through 5.1 excepting OpenGIS types.
-ischema_names = {
- 'bigint': BIGINT,
- 'binary': BINARY,
- 'bit': BIT,
- 'blob': BLOB,
- 'boolean': BOOLEAN,
- 'char': CHAR,
- 'date': DATE,
- 'datetime': DATETIME,
- 'decimal': DECIMAL,
- 'double': DOUBLE,
- 'enum': ENUM,
- 'fixed': DECIMAL,
- 'float': FLOAT,
- 'int': INTEGER,
- 'integer': INTEGER,
- 'longblob': LONGBLOB,
- 'longtext': LONGTEXT,
- 'mediumblob': MEDIUMBLOB,
- 'mediumint': MEDIUMINT,
- 'mediumtext': MEDIUMTEXT,
- 'nchar': NCHAR,
- 'nvarchar': NVARCHAR,
- 'numeric': NUMERIC,
- 'set': SET,
- 'smallint': SMALLINT,
- 'text': TEXT,
- 'time': TIME,
- 'timestamp': TIMESTAMP,
- 'tinyblob': TINYBLOB,
- 'tinyint': TINYINT,
- 'tinytext': TINYTEXT,
- 'varbinary': VARBINARY,
- 'varchar': VARCHAR,
- 'year': YEAR,
-}
-
-class MySQLExecutionContext(default.DefaultExecutionContext):
-
- def should_autocommit_text(self, statement):
- return AUTOCOMMIT_RE.match(statement)
-
-class MySQLCompiler(compiler.SQLCompiler):
-
- extract_map = compiler.SQLCompiler.extract_map.copy()
- extract_map.update ({
- 'milliseconds': 'millisecond',
- })
-
- def visit_random_func(self, fn, **kw):
- return "rand%s" % self.function_argspec(fn)
-
- def visit_utc_timestamp_func(self, fn, **kw):
- return "UTC_TIMESTAMP"
-
- def visit_sysdate_func(self, fn, **kw):
- return "SYSDATE()"
-
- def visit_concat_op(self, binary, **kw):
- return "concat(%s, %s)" % (self.process(binary.left), self.process(binary.right))
-
- def visit_match_op(self, binary, **kw):
- return "MATCH (%s) AGAINST (%s IN BOOLEAN MODE)" % (self.process(binary.left), self.process(binary.right))
-
- def get_from_hint_text(self, table, text):
- return text
-
- def visit_typeclause(self, typeclause):
- type_ = typeclause.type.dialect_impl(self.dialect)
- if isinstance(type_, sqltypes.Integer):
- if getattr(type_, 'unsigned', False):
- return 'UNSIGNED INTEGER'
- else:
- return 'SIGNED INTEGER'
- elif isinstance(type_, sqltypes.TIMESTAMP):
- return 'DATETIME'
- elif isinstance(type_, (sqltypes.DECIMAL, sqltypes.DateTime, sqltypes.Date, sqltypes.Time)):
- return self.dialect.type_compiler.process(type_)
- elif isinstance(type_, sqltypes.Text):
- return 'CHAR'
- elif (isinstance(type_, sqltypes.String) and not
- isinstance(type_, (ENUM, SET))):
- if getattr(type_, 'length'):
- return 'CHAR(%s)' % type_.length
- else:
- return 'CHAR'
- elif isinstance(type_, sqltypes._Binary):
- return 'BINARY'
- elif isinstance(type_, sqltypes.NUMERIC):
- return self.dialect.type_compiler.process(type_).replace('NUMERIC', 'DECIMAL')
- else:
- return None
-
- def visit_cast(self, cast, **kwargs):
- # No cast until 4, no decimals until 5.
- if not self.dialect._supports_cast:
- return self.process(cast.clause)
-
- type_ = self.process(cast.typeclause)
- if type_ is None:
- return self.process(cast.clause)
-
- return 'CAST(%s AS %s)' % (self.process(cast.clause), type_)
-
- def render_literal_value(self, value, type_):
- value = super(MySQLCompiler, self).render_literal_value(value, type_)
- if self.dialect._backslash_escapes:
- value = value.replace('\\', '\\\\')
- return value
-
- def get_select_precolumns(self, select):
- """Add special MySQL keywords in place of DISTINCT.
-
- .. note:: this usage is deprecated. :meth:`.Select.prefix_with`
- should be used for special keywords at the start
- of a SELECT.
-
- """
- if isinstance(select._distinct, basestring):
- return select._distinct.upper() + " "
- elif select._distinct:
- return "DISTINCT "
- else:
- return ""
-
- def visit_join(self, join, asfrom=False, **kwargs):
- # 'JOIN ... ON ...' for inner joins isn't available until 4.0.
- # Apparently < 3.23.17 requires theta joins for inner joins
- # (but not outer). Not generating these currently, but
- # support can be added, preferably after dialects are
- # refactored to be version-sensitive.
- return ''.join(
- (self.process(join.left, asfrom=True, **kwargs),
- (join.isouter and " LEFT OUTER JOIN " or " INNER JOIN "),
- self.process(join.right, asfrom=True, **kwargs),
- " ON ",
- self.process(join.onclause, **kwargs)))
-
- def for_update_clause(self, select):
- if select.for_update == 'read':
- return ' LOCK IN SHARE MODE'
- else:
- return super(MySQLCompiler, self).for_update_clause(select)
-
- def limit_clause(self, select):
- # MySQL supports:
- # LIMIT <limit>
- # LIMIT <offset>, <limit>
- # and in server versions > 3.3:
- # LIMIT <limit> OFFSET <offset>
- # The latter is more readable for offsets but we're stuck with the
- # former until we can refine dialects by server revision.
-
- limit, offset = select._limit, select._offset
-
- if (limit, offset) == (None, None):
- return ''
- elif offset is not None:
- # As suggested by the MySQL docs, need to apply an
- # artificial limit if one wasn't provided
- # http://dev.mysql.com/doc/refman/5.0/en/select.html
- if limit is None:
- # hardwire the upper limit. Currently
- # needed by OurSQL with Python 3
- # (https://bugs.launchpad.net/oursql/+bug/686232),
- # but also is consistent with the usage of the upper
- # bound as part of MySQL's "syntax" for OFFSET with
- # no LIMIT
- return ' \n LIMIT %s, %s' % (
- self.process(sql.literal(offset)),
- "18446744073709551615")
- else:
- return ' \n LIMIT %s, %s' % (
- self.process(sql.literal(offset)),
- self.process(sql.literal(limit)))
- else:
- # No offset provided, so just use the limit
- return ' \n LIMIT %s' % (self.process(sql.literal(limit)),)
-
- def visit_update(self, update_stmt):
- self.stack.append({'from': set([update_stmt.table])})
-
- self.isupdate = True
- colparams = self._get_colparams(update_stmt)
-
- text = "UPDATE " + self.preparer.format_table(update_stmt.table) + \
- " SET " + ', '.join(["%s=%s" % (self.preparer.format_column(c[0]), c[1]) for c in colparams])
-
- if update_stmt._whereclause is not None:
- text += " WHERE " + self.process(update_stmt._whereclause)
-
- limit = update_stmt.kwargs.get('%s_limit' % self.dialect.name, None)
- if limit:
- text += " LIMIT %s" % limit
-
- self.stack.pop(-1)
-
- return text
-
-# ug. "InnoDB needs indexes on foreign keys and referenced keys [...].
-# Starting with MySQL 4.1.2, these indexes are created automatically.
-# In older versions, the indexes must be created explicitly or the
-# creation of foreign key constraints fails."
-
-class MySQLDDLCompiler(compiler.DDLCompiler):
- def create_table_constraints(self, table):
- """Get table constraints."""
- constraint_string = super(MySQLDDLCompiler, self).create_table_constraints(table)
-
- engine_key = '%s_engine' % self.dialect.name
- is_innodb = table.kwargs.has_key(engine_key) and \
- table.kwargs[engine_key].lower() == 'innodb'
-
- auto_inc_column = table._autoincrement_column
-
- if is_innodb and \
- auto_inc_column is not None and \
- auto_inc_column is not list(table.primary_key)[0]:
- if constraint_string:
- constraint_string += ", \n\t"
- constraint_string += "KEY `idx_autoinc_%s`(`%s`)" % (auto_inc_column.name, \
- self.preparer.format_column(auto_inc_column))
-
- return constraint_string
-
-
- def get_column_specification(self, column, **kw):
- """Builds column DDL."""
-
- colspec = [self.preparer.format_column(column),
- self.dialect.type_compiler.process(column.type)
- ]
-
- default = self.get_column_default_string(column)
- if default is not None:
- colspec.append('DEFAULT ' + default)
-
- is_timestamp = isinstance(column.type, sqltypes.TIMESTAMP)
- if not column.nullable and not is_timestamp:
- colspec.append('NOT NULL')
-
- elif column.nullable and is_timestamp and default is None:
- colspec.append('NULL')
-
- if column is column.table._autoincrement_column and column.server_default is None:
- colspec.append('AUTO_INCREMENT')
-
- return ' '.join(colspec)
-
- def post_create_table(self, table):
- """Build table-level CREATE options like ENGINE and COLLATE."""
-
- table_opts = []
- for k in table.kwargs:
- if k.startswith('%s_' % self.dialect.name):
- opt = k[len(self.dialect.name)+1:].upper()
-
- arg = table.kwargs[k]
- if opt in _options_of_type_string:
- arg = "'%s'" % arg.replace("\\", "\\\\").replace("'", "''")
-
- if opt in ('DATA_DIRECTORY', 'INDEX_DIRECTORY',
- 'DEFAULT_CHARACTER_SET', 'CHARACTER_SET',
- 'DEFAULT_CHARSET',
- 'DEFAULT_COLLATE'):
- opt = opt.replace('_', ' ')
-
- joiner = '='
- if opt in ('TABLESPACE', 'DEFAULT CHARACTER SET',
- 'CHARACTER SET', 'COLLATE'):
- joiner = ' '
-
- table_opts.append(joiner.join((opt, arg)))
- return ' '.join(table_opts)
-
- def visit_drop_index(self, drop):
- index = drop.element
-
- return "\nDROP INDEX %s ON %s" % \
- (self.preparer.quote(self._index_identifier(index.name), index.quote),
- self.preparer.format_table(index.table))
-
- def visit_drop_constraint(self, drop):
- constraint = drop.element
- if isinstance(constraint, sa_schema.ForeignKeyConstraint):
- qual = "FOREIGN KEY "
- const = self.preparer.format_constraint(constraint)
- elif isinstance(constraint, sa_schema.PrimaryKeyConstraint):
- qual = "PRIMARY KEY "
- const = ""
- elif isinstance(constraint, sa_schema.UniqueConstraint):
- qual = "INDEX "
- const = self.preparer.format_constraint(constraint)
- else:
- qual = ""
- const = self.preparer.format_constraint(constraint)
- return "ALTER TABLE %s DROP %s%s" % \
- (self.preparer.format_table(constraint.table),
- qual, const)
-
-class MySQLTypeCompiler(compiler.GenericTypeCompiler):
- def _extend_numeric(self, type_, spec):
- "Extend a numeric-type declaration with MySQL specific extensions."
-
- if not self._mysql_type(type_):
- return spec
-
- if type_.unsigned:
- spec += ' UNSIGNED'
- if type_.zerofill:
- spec += ' ZEROFILL'
- return spec
-
- def _extend_string(self, type_, defaults, spec):
- """Extend a string-type declaration with standard SQL CHARACTER SET /
- COLLATE annotations and MySQL specific extensions.
-
- """
-
- def attr(name):
- return getattr(type_, name, defaults.get(name))
-
- if attr('charset'):
- charset = 'CHARACTER SET %s' % attr('charset')
- elif attr('ascii'):
- charset = 'ASCII'
- elif attr('unicode'):
- charset = 'UNICODE'
- else:
- charset = None
-
- if attr('collation'):
- collation = 'COLLATE %s' % type_.collation
- elif attr('binary'):
- collation = 'BINARY'
- else:
- collation = None
-
- if attr('national'):
- # NATIONAL (aka NCHAR/NVARCHAR) trumps charsets.
- return ' '.join([c for c in ('NATIONAL', spec, collation)
- if c is not None])
- return ' '.join([c for c in (spec, charset, collation)
- if c is not None])
-
- def _mysql_type(self, type_):
- return isinstance(type_, (_StringType, _NumericType))
-
- def visit_NUMERIC(self, type_):
- if type_.precision is None:
- return self._extend_numeric(type_, "NUMERIC")
- elif type_.scale is None:
- return self._extend_numeric(type_,
- "NUMERIC(%(precision)s)" %
- {'precision': type_.precision})
- else:
- return self._extend_numeric(type_,
- "NUMERIC(%(precision)s, %(scale)s)" %
- {'precision': type_.precision, 'scale' : type_.scale})
-
- def visit_DECIMAL(self, type_):
- if type_.precision is None:
- return self._extend_numeric(type_, "DECIMAL")
- elif type_.scale is None:
- return self._extend_numeric(type_,
- "DECIMAL(%(precision)s)" %
- {'precision': type_.precision})
- else:
- return self._extend_numeric(type_,
- "DECIMAL(%(precision)s, %(scale)s)" %
- {'precision': type_.precision, 'scale' : type_.scale})
-
- def visit_DOUBLE(self, type_):
- if type_.precision is not None and type_.scale is not None:
- return self._extend_numeric(type_, "DOUBLE(%(precision)s, %(scale)s)" %
- {'precision': type_.precision,
- 'scale' : type_.scale})
- else:
- return self._extend_numeric(type_, 'DOUBLE')
-
- def visit_REAL(self, type_):
- if type_.precision is not None and type_.scale is not None:
- return self._extend_numeric(type_, "REAL(%(precision)s, %(scale)s)" %
- {'precision': type_.precision,
- 'scale' : type_.scale})
- else:
- return self._extend_numeric(type_, 'REAL')
-
- def visit_FLOAT(self, type_):
- if self._mysql_type(type_) and \
- type_.scale is not None and \
- type_.precision is not None:
- return self._extend_numeric(type_,
- "FLOAT(%s, %s)" % (type_.precision, type_.scale))
- elif type_.precision is not None:
- return self._extend_numeric(type_, "FLOAT(%s)" % (type_.precision,))
- else:
- return self._extend_numeric(type_, "FLOAT")
-
- def visit_INTEGER(self, type_):
- if self._mysql_type(type_) and type_.display_width is not None:
- return self._extend_numeric(type_,
- "INTEGER(%(display_width)s)" %
- {'display_width': type_.display_width})
- else:
- return self._extend_numeric(type_, "INTEGER")
-
- def visit_BIGINT(self, type_):
- if self._mysql_type(type_) and type_.display_width is not None:
- return self._extend_numeric(type_,
- "BIGINT(%(display_width)s)" %
- {'display_width': type_.display_width})
- else:
- return self._extend_numeric(type_, "BIGINT")
-
- def visit_MEDIUMINT(self, type_):
- if self._mysql_type(type_) and type_.display_width is not None:
- return self._extend_numeric(type_,
- "MEDIUMINT(%(display_width)s)" %
- {'display_width': type_.display_width})
- else:
- return self._extend_numeric(type_, "MEDIUMINT")
-
- def visit_TINYINT(self, type_):
- if self._mysql_type(type_) and type_.display_width is not None:
- return self._extend_numeric(type_, "TINYINT(%s)" % type_.display_width)
- else:
- return self._extend_numeric(type_, "TINYINT")
-
- def visit_SMALLINT(self, type_):
- if self._mysql_type(type_) and type_.display_width is not None:
- return self._extend_numeric(type_,
- "SMALLINT(%(display_width)s)" %
- {'display_width': type_.display_width}
- )
- else:
- return self._extend_numeric(type_, "SMALLINT")
-
- def visit_BIT(self, type_):
- if type_.length is not None:
- return "BIT(%s)" % type_.length
- else:
- return "BIT"
-
- def visit_DATETIME(self, type_):
- return "DATETIME"
-
- def visit_DATE(self, type_):
- return "DATE"
-
- def visit_TIME(self, type_):
- return "TIME"
-
- def visit_TIMESTAMP(self, type_):
- return 'TIMESTAMP'
-
- def visit_YEAR(self, type_):
- if type_.display_width is None:
- return "YEAR"
- else:
- return "YEAR(%s)" % type_.display_width
-
- def visit_TEXT(self, type_):
- if type_.length:
- return self._extend_string(type_, {}, "TEXT(%d)" % type_.length)
- else:
- return self._extend_string(type_, {}, "TEXT")
-
- def visit_TINYTEXT(self, type_):
- return self._extend_string(type_, {}, "TINYTEXT")
-
- def visit_MEDIUMTEXT(self, type_):
- return self._extend_string(type_, {}, "MEDIUMTEXT")
-
- def visit_LONGTEXT(self, type_):
- return self._extend_string(type_, {}, "LONGTEXT")
-
- def visit_VARCHAR(self, type_):
- if type_.length:
- return self._extend_string(type_, {}, "VARCHAR(%d)" % type_.length)
- else:
- raise exc.InvalidRequestError(
- "VARCHAR requires a length on dialect %s" %
- self.dialect.name)
-
- def visit_CHAR(self, type_):
- if type_.length:
- return self._extend_string(type_, {}, "CHAR(%(length)s)" % {'length' : type_.length})
- else:
- return self._extend_string(type_, {}, "CHAR")
-
- def visit_NVARCHAR(self, type_):
- # We'll actually generate the equiv. "NATIONAL VARCHAR" instead
- # of "NVARCHAR".
- if type_.length:
- return self._extend_string(type_, {'national':True}, "VARCHAR(%(length)s)" % {'length': type_.length})
- else:
- raise exc.InvalidRequestError(
- "NVARCHAR requires a length on dialect %s" %
- self.dialect.name)
-
- def visit_NCHAR(self, type_):
- # We'll actually generate the equiv. "NATIONAL CHAR" instead of "NCHAR".
- if type_.length:
- return self._extend_string(type_, {'national':True}, "CHAR(%(length)s)" % {'length': type_.length})
- else:
- return self._extend_string(type_, {'national':True}, "CHAR")
-
- def visit_VARBINARY(self, type_):
- return "VARBINARY(%d)" % type_.length
-
- def visit_large_binary(self, type_):
- return self.visit_BLOB(type_)
-
- def visit_enum(self, type_):
- if not type_.native_enum:
- return super(MySQLTypeCompiler, self).visit_enum(type_)
- else:
- return self.visit_ENUM(type_)
-
- def visit_BLOB(self, type_):
- if type_.length:
- return "BLOB(%d)" % type_.length
- else:
- return "BLOB"
-
- def visit_TINYBLOB(self, type_):
- return "TINYBLOB"
-
- def visit_MEDIUMBLOB(self, type_):
- return "MEDIUMBLOB"
-
- def visit_LONGBLOB(self, type_):
- return "LONGBLOB"
-
- def visit_ENUM(self, type_):
- quoted_enums = []
- for e in type_.enums:
- quoted_enums.append("'%s'" % e.replace("'", "''"))
- return self._extend_string(type_, {}, "ENUM(%s)" % ",".join(quoted_enums))
-
- def visit_SET(self, type_):
- return self._extend_string(type_, {}, "SET(%s)" % ",".join(type_._ddl_values))
-
- def visit_BOOLEAN(self, type):
- return "BOOL"
-
-
-class MySQLIdentifierPreparer(compiler.IdentifierPreparer):
-
- reserved_words = RESERVED_WORDS
-
- def __init__(self, dialect, server_ansiquotes=False, **kw):
- if not server_ansiquotes:
- quote = "`"
- else:
- quote = '"'
-
- super(MySQLIdentifierPreparer, self).__init__(
- dialect,
- initial_quote=quote,
- escape_quote=quote)
-
- def _quote_free_identifiers(self, *ids):
- """Unilaterally identifier-quote any number of strings."""
-
- return tuple([self.quote_identifier(i) for i in ids if i is not None])
-
-class MySQLDialect(default.DefaultDialect):
- """Details of the MySQL dialect. Not used directly in application code."""
-
- name = 'mysql'
- supports_alter = True
-
- # identifiers are 64, however aliases can be 255...
- max_identifier_length = 255
- max_index_name_length = 64
-
- supports_native_enum = True
-
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = False
-
- default_paramstyle = 'format'
- colspecs = colspecs
-
- statement_compiler = MySQLCompiler
- ddl_compiler = MySQLDDLCompiler
- type_compiler = MySQLTypeCompiler
- ischema_names = ischema_names
- preparer = MySQLIdentifierPreparer
-
- # default SQL compilation settings -
- # these are modified upon initialize(),
- # i.e. first connect
- _backslash_escapes = True
- _server_ansiquotes = False
-
- def __init__(self, use_ansiquotes=None, **kwargs):
- default.DefaultDialect.__init__(self, **kwargs)
-
- def do_commit(self, connection):
- """Execute a COMMIT."""
-
- # COMMIT/ROLLBACK were introduced in 3.23.15.
- # Yes, we have at least one user who has to talk to these old versions!
- #
- # Ignore commit/rollback if support isn't present, otherwise even basic
- # operations via autocommit fail.
- try:
- connection.commit()
- except:
- if self.server_version_info < (3, 23, 15):
- args = sys.exc_info()[1].args
- if args and args[0] == 1064:
- return
- raise
-
- def do_rollback(self, connection):
- """Execute a ROLLBACK."""
-
- try:
- connection.rollback()
- except:
- if self.server_version_info < (3, 23, 15):
- args = sys.exc_info()[1].args
- if args and args[0] == 1064:
- return
- raise
-
- def do_begin_twophase(self, connection, xid):
- connection.execute(sql.text("XA BEGIN :xid"), xid=xid)
-
- def do_prepare_twophase(self, connection, xid):
- connection.execute(sql.text("XA END :xid"), xid=xid)
- connection.execute(sql.text("XA PREPARE :xid"), xid=xid)
-
- def do_rollback_twophase(self, connection, xid, is_prepared=True,
- recover=False):
- if not is_prepared:
- connection.execute(sql.text("XA END :xid"), xid=xid)
- connection.execute(sql.text("XA ROLLBACK :xid"), xid=xid)
-
- def do_commit_twophase(self, connection, xid, is_prepared=True,
- recover=False):
- if not is_prepared:
- self.do_prepare_twophase(connection, xid)
- connection.execute(sql.text("XA COMMIT :xid"), xid=xid)
-
- def do_recover_twophase(self, connection):
- resultset = connection.execute("XA RECOVER")
- return [row['data'][0:row['gtrid_length']] for row in resultset]
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, self.dbapi.OperationalError):
- return self._extract_error_code(e) in \
- (2006, 2013, 2014, 2045, 2055)
- elif isinstance(e, self.dbapi.InterfaceError):
- # if underlying connection is closed,
- # this is the error you get
- return "(0, '')" in str(e)
- else:
- return False
-
- def _compat_fetchall(self, rp, charset=None):
- """Proxy result rows to smooth over MySQL-Python driver inconsistencies."""
-
- return [_DecodingRowProxy(row, charset) for row in rp.fetchall()]
-
- def _compat_fetchone(self, rp, charset=None):
- """Proxy a result row to smooth over MySQL-Python driver inconsistencies."""
-
- return _DecodingRowProxy(rp.fetchone(), charset)
-
- def _compat_first(self, rp, charset=None):
- """Proxy a result row to smooth over MySQL-Python driver inconsistencies."""
-
- return _DecodingRowProxy(rp.first(), charset)
-
- def _extract_error_code(self, exception):
- raise NotImplementedError()
-
- def _get_default_schema_name(self, connection):
- return connection.execute('SELECT DATABASE()').scalar()
-
-
- def has_table(self, connection, table_name, schema=None):
- # SHOW TABLE STATUS LIKE and SHOW TABLES LIKE do not function properly
- # on macosx (and maybe win?) with multibyte table names.
- #
- # TODO: if this is not a problem on win, make the strategy swappable
- # based on platform. DESCRIBE is slower.
-
- # [ticket:726]
- # full_name = self.identifier_preparer.format_table(table,
- # use_schema=True)
-
-
- full_name = '.'.join(self.identifier_preparer._quote_free_identifiers(
- schema, table_name))
-
- st = "DESCRIBE %s" % full_name
- rs = None
- try:
- try:
- rs = connection.execute(st)
- have = rs.rowcount > 0
- rs.close()
- return have
- except exc.DBAPIError, e:
- if self._extract_error_code(e.orig) == 1146:
- return False
- raise
- finally:
- if rs:
- rs.close()
-
- def initialize(self, connection):
- default.DefaultDialect.initialize(self, connection)
- self._connection_charset = self._detect_charset(connection)
- self._server_casing = self._detect_casing(connection)
- self._server_collations = self._detect_collations(connection)
- self._detect_ansiquotes(connection)
- if self._server_ansiquotes:
- # if ansiquotes == True, build a new IdentifierPreparer
- # with the new setting
- self.identifier_preparer = self.preparer(self,
- server_ansiquotes=self._server_ansiquotes)
-
- @property
- def _supports_cast(self):
- return self.server_version_info is None or \
- self.server_version_info >= (4, 0, 2)
-
- @reflection.cache
- def get_schema_names(self, connection, **kw):
- rp = connection.execute("SHOW schemas")
- return [r[0] for r in rp]
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- """Return a Unicode SHOW TABLES from a given schema."""
- if schema is not None:
- current_schema = schema
- else:
- current_schema = self.default_schema_name
-
- charset = self._connection_charset
- if self.server_version_info < (5, 0, 2):
- rp = connection.execute("SHOW TABLES FROM %s" %
- self.identifier_preparer.quote_identifier(current_schema))
- return [row[0] for row in self._compat_fetchall(rp, charset=charset)]
- else:
- rp = connection.execute("SHOW FULL TABLES FROM %s" %
- self.identifier_preparer.quote_identifier(current_schema))
-
- return [row[0] for row in self._compat_fetchall(rp, charset=charset)\
- if row[1] == 'BASE TABLE']
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- charset = self._connection_charset
- if self.server_version_info < (5, 0, 2):
- raise NotImplementedError
- if schema is None:
- schema = self.default_schema_name
- if self.server_version_info < (5, 0, 2):
- return self.get_table_names(connection, schema)
- charset = self._connection_charset
- rp = connection.execute("SHOW FULL TABLES FROM %s" %
- self.identifier_preparer.quote_identifier(schema))
- return [row[0] for row in self._compat_fetchall(rp, charset=charset)\
- if row[1] == 'VIEW']
-
- @reflection.cache
- def get_table_options(self, connection, table_name, schema=None, **kw):
-
- parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
- return parsed_state.table_options
-
- @reflection.cache
- def get_columns(self, connection, table_name, schema=None, **kw):
- parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
- return parsed_state.columns
-
- @reflection.cache
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
- for key in parsed_state.keys:
- if key['type'] == 'PRIMARY':
- # There can be only one.
- ##raise Exception, str(key)
- return [s[0] for s in key['columns']]
- return []
-
- @reflection.cache
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
-
- parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
- default_schema = None
-
- fkeys = []
-
- for spec in parsed_state.constraints:
- # only FOREIGN KEYs
- ref_name = spec['table'][-1]
- ref_schema = len(spec['table']) > 1 and spec['table'][-2] or schema
-
- if not ref_schema:
- if default_schema is None:
- default_schema = \
- connection.dialect.default_schema_name
- if schema == default_schema:
- ref_schema = schema
-
- loc_names = spec['local']
- ref_names = spec['foreign']
-
- con_kw = {}
- for opt in ('name', 'onupdate', 'ondelete'):
- if spec.get(opt, False):
- con_kw[opt] = spec[opt]
-
- fkey_d = {
- 'name' : spec['name'],
- 'constrained_columns' : loc_names,
- 'referred_schema' : ref_schema,
- 'referred_table' : ref_name,
- 'referred_columns' : ref_names,
- 'options' : con_kw
- }
- fkeys.append(fkey_d)
- return fkeys
-
- @reflection.cache
- def get_indexes(self, connection, table_name, schema=None, **kw):
-
- parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
-
- indexes = []
- for spec in parsed_state.keys:
- unique = False
- flavor = spec['type']
- if flavor == 'PRIMARY':
- continue
- if flavor == 'UNIQUE':
- unique = True
- elif flavor in (None, 'FULLTEXT', 'SPATIAL'):
- pass
- else:
- self.logger.info(
- "Converting unknown KEY type %s to a plain KEY" % flavor)
- pass
- index_d = {}
- index_d['name'] = spec['name']
- index_d['column_names'] = [s[0] for s in spec['columns']]
- index_d['unique'] = unique
- index_d['type'] = flavor
- indexes.append(index_d)
- return indexes
-
- @reflection.cache
- def get_view_definition(self, connection, view_name, schema=None, **kw):
-
- charset = self._connection_charset
- full_name = '.'.join(self.identifier_preparer._quote_free_identifiers(
- schema, view_name))
- sql = self._show_create_table(connection, None, charset,
- full_name=full_name)
- return sql
-
- def _parsed_state_or_create(self, connection, table_name, schema=None, **kw):
- return self._setup_parser(
- connection,
- table_name,
- schema,
- info_cache=kw.get('info_cache', None)
- )
-
- @util.memoized_property
- def _tabledef_parser(self):
- """return the MySQLTableDefinitionParser, generate if needed.
-
- The deferred creation ensures that the dialect has
- retrieved server version information first.
-
- """
- if (self.server_version_info < (4, 1) and self._server_ansiquotes):
- # ANSI_QUOTES doesn't affect SHOW CREATE TABLE on < 4.1
- preparer = self.preparer(self, server_ansiquotes=False)
- else:
- preparer = self.identifier_preparer
- return MySQLTableDefinitionParser(self, preparer)
-
- @reflection.cache
- def _setup_parser(self, connection, table_name, schema=None, **kw):
- charset = self._connection_charset
- parser = self._tabledef_parser
- full_name = '.'.join(self.identifier_preparer._quote_free_identifiers(
- schema, table_name))
- sql = self._show_create_table(connection, None, charset,
- full_name=full_name)
- if sql.startswith('CREATE ALGORITHM'):
- # Adapt views to something table-like.
- columns = self._describe_table(connection, None, charset,
- full_name=full_name)
- sql = parser._describe_to_create(table_name, columns)
- return parser.parse(sql, charset)
-
- def _adjust_casing(self, table, charset=None):
- """Adjust Table name to the server case sensitivity, if needed."""
-
- casing = self._server_casing
-
- # For winxx database hosts. TODO: is this really needed?
- if casing == 1 and table.name != table.name.lower():
- table.name = table.name.lower()
- lc_alias = sa_schema._get_table_key(table.name, table.schema)
- table.metadata.tables[lc_alias] = table
-
- def _detect_charset(self, connection):
- raise NotImplementedError()
-
- def _detect_casing(self, connection):
- """Sniff out identifier case sensitivity.
-
- Cached per-connection. This value can not change without a server
- restart.
-
- """
- # http://dev.mysql.com/doc/refman/5.0/en/name-case-sensitivity.html
-
- charset = self._connection_charset
- row = self._compat_first(connection.execute(
- "SHOW VARIABLES LIKE 'lower_case_table_names'"),
- charset=charset)
- if not row:
- cs = 0
- else:
- # 4.0.15 returns OFF or ON according to [ticket:489]
- # 3.23 doesn't, 4.0.27 doesn't..
- if row[1] == 'OFF':
- cs = 0
- elif row[1] == 'ON':
- cs = 1
- else:
- cs = int(row[1])
- return cs
-
- def _detect_collations(self, connection):
- """Pull the active COLLATIONS list from the server.
-
- Cached per-connection.
- """
-
- collations = {}
- if self.server_version_info < (4, 1, 0):
- pass
- else:
- charset = self._connection_charset
- rs = connection.execute('SHOW COLLATION')
- for row in self._compat_fetchall(rs, charset):
- collations[row[0]] = row[1]
- return collations
-
- def _detect_ansiquotes(self, connection):
- """Detect and adjust for the ANSI_QUOTES sql mode."""
-
- row = self._compat_first(
- connection.execute("SHOW VARIABLES LIKE 'sql_mode'"),
- charset=self._connection_charset)
-
- if not row:
- mode = ''
- else:
- mode = row[1] or ''
- # 4.0
- if mode.isdigit():
- mode_no = int(mode)
- mode = (mode_no | 4 == mode_no) and 'ANSI_QUOTES' or ''
-
- self._server_ansiquotes = 'ANSI_QUOTES' in mode
-
- # as of MySQL 5.0.1
- self._backslash_escapes = 'NO_BACKSLASH_ESCAPES' not in mode
-
- def _show_create_table(self, connection, table, charset=None,
- full_name=None):
- """Run SHOW CREATE TABLE for a ``Table``."""
-
- if full_name is None:
- full_name = self.identifier_preparer.format_table(table)
- st = "SHOW CREATE TABLE %s" % full_name
-
- rp = None
- try:
- rp = connection.execute(st)
- except exc.DBAPIError, e:
- if self._extract_error_code(e.orig) == 1146:
- raise exc.NoSuchTableError(full_name)
- else:
- raise
- row = self._compat_first(rp, charset=charset)
- if not row:
- raise exc.NoSuchTableError(full_name)
- return row[1].strip()
-
- return sql
-
- def _describe_table(self, connection, table, charset=None,
- full_name=None):
- """Run DESCRIBE for a ``Table`` and return processed rows."""
-
- if full_name is None:
- full_name = self.identifier_preparer.format_table(table)
- st = "DESCRIBE %s" % full_name
-
- rp, rows = None, None
- try:
- try:
- rp = connection.execute(st)
- except exc.DBAPIError, e:
- if self._extract_error_code(e.orig) == 1146:
- raise exc.NoSuchTableError(full_name)
- else:
- raise
- rows = self._compat_fetchall(rp, charset=charset)
- finally:
- if rp:
- rp.close()
- return rows
-
-class ReflectedState(object):
- """Stores raw information about a SHOW CREATE TABLE statement."""
-
- def __init__(self):
- self.columns = []
- self.table_options = {}
- self.table_name = None
- self.keys = []
- self.constraints = []
-
-class MySQLTableDefinitionParser(object):
- """Parses the results of a SHOW CREATE TABLE statement."""
-
- def __init__(self, dialect, preparer):
- self.dialect = dialect
- self.preparer = preparer
- self._prep_regexes()
-
- def parse(self, show_create, charset):
- state = ReflectedState()
- state.charset = charset
- for line in re.split(r'\r?\n', show_create):
- if line.startswith(' ' + self.preparer.initial_quote):
- self._parse_column(line, state)
- # a regular table options line
- elif line.startswith(') '):
- self._parse_table_options(line, state)
- # an ANSI-mode table options line
- elif line == ')':
- pass
- elif line.startswith('CREATE '):
- self._parse_table_name(line, state)
- # Not present in real reflection, but may be if loading from a file.
- elif not line:
- pass
- else:
- type_, spec = self._parse_constraints(line)
- if type_ is None:
- util.warn("Unknown schema content: %r" % line)
- elif type_ == 'key':
- state.keys.append(spec)
- elif type_ == 'constraint':
- state.constraints.append(spec)
- else:
- pass
-
- return state
-
- def _parse_constraints(self, line):
- """Parse a KEY or CONSTRAINT line.
-
- :param line: A line of SHOW CREATE TABLE output
- """
-
- # KEY
- m = self._re_key.match(line)
- if m:
- spec = m.groupdict()
- # convert columns into name, length pairs
- spec['columns'] = self._parse_keyexprs(spec['columns'])
- return 'key', spec
-
- # CONSTRAINT
- m = self._re_constraint.match(line)
- if m:
- spec = m.groupdict()
- spec['table'] = \
- self.preparer.unformat_identifiers(spec['table'])
- spec['local'] = [c[0]
- for c in self._parse_keyexprs(spec['local'])]
- spec['foreign'] = [c[0]
- for c in self._parse_keyexprs(spec['foreign'])]
- return 'constraint', spec
-
- # PARTITION and SUBPARTITION
- m = self._re_partition.match(line)
- if m:
- # Punt!
- return 'partition', line
-
- # No match.
- return (None, line)
-
- def _parse_table_name(self, line, state):
- """Extract the table name.
-
- :param line: The first line of SHOW CREATE TABLE
- """
-
- regex, cleanup = self._pr_name
- m = regex.match(line)
- if m:
- state.table_name = cleanup(m.group('name'))
-
- def _parse_table_options(self, line, state):
- """Build a dictionary of all reflected table-level options.
-
- :param line: The final line of SHOW CREATE TABLE output.
- """
-
- options = {}
-
- if not line or line == ')':
- pass
-
- else:
- rest_of_line = line[:]
- for regex, cleanup in self._pr_options:
- m = regex.search(rest_of_line)
- if not m:
- continue
- directive, value = m.group('directive'), m.group('val')
- if cleanup:
- value = cleanup(value)
- options[directive.lower()] = value
- rest_of_line = regex.sub('', rest_of_line)
-
- for nope in ('auto_increment', 'data directory', 'index directory'):
- options.pop(nope, None)
-
- for opt, val in options.items():
- state.table_options['%s_%s' % (self.dialect.name, opt)] = val
-
- def _parse_column(self, line, state):
- """Extract column details.
-
- Falls back to a 'minimal support' variant if full parse fails.
-
- :param line: Any column-bearing line from SHOW CREATE TABLE
- """
-
- spec = None
- m = self._re_column.match(line)
- if m:
- spec = m.groupdict()
- spec['full'] = True
- else:
- m = self._re_column_loose.match(line)
- if m:
- spec = m.groupdict()
- spec['full'] = False
- if not spec:
- util.warn("Unknown column definition %r" % line)
- return
- if not spec['full']:
- util.warn("Incomplete reflection of column definition %r" % line)
-
- name, type_, args, notnull = \
- spec['name'], spec['coltype'], spec['arg'], spec['notnull']
-
- try:
- col_type = self.dialect.ischema_names[type_]
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (type_, name))
- col_type = sqltypes.NullType
-
- # Column type positional arguments eg. varchar(32)
- if args is None or args == '':
- type_args = []
- elif args[0] == "'" and args[-1] == "'":
- type_args = self._re_csv_str.findall(args)
- else:
- type_args = [int(v) for v in self._re_csv_int.findall(args)]
-
- # Column type keyword options
- type_kw = {}
- for kw in ('unsigned', 'zerofill'):
- if spec.get(kw, False):
- type_kw[kw] = True
- for kw in ('charset', 'collate'):
- if spec.get(kw, False):
- type_kw[kw] = spec[kw]
-
- if type_ == 'enum':
- type_args = ENUM._strip_enums(type_args)
-
- type_instance = col_type(*type_args, **type_kw)
-
- col_args, col_kw = [], {}
-
- # NOT NULL
- col_kw['nullable'] = True
- if spec.get('notnull', False):
- col_kw['nullable'] = False
-
- # AUTO_INCREMENT
- if spec.get('autoincr', False):
- col_kw['autoincrement'] = True
- elif issubclass(col_type, sqltypes.Integer):
- col_kw['autoincrement'] = False
-
- # DEFAULT
- default = spec.get('default', None)
-
- if default == 'NULL':
- # eliminates the need to deal with this later.
- default = None
-
- col_d = dict(name=name, type=type_instance, default=default)
- col_d.update(col_kw)
- state.columns.append(col_d)
-
- def _describe_to_create(self, table_name, columns):
- """Re-format DESCRIBE output as a SHOW CREATE TABLE string.
-
- DESCRIBE is a much simpler reflection and is sufficient for
- reflecting views for runtime use. This method formats DDL
- for columns only- keys are omitted.
-
- :param columns: A sequence of DESCRIBE or SHOW COLUMNS 6-tuples.
- SHOW FULL COLUMNS FROM rows must be rearranged for use with
- this function.
- """
-
- buffer = []
- for row in columns:
- (name, col_type, nullable, default, extra) = \
- [row[i] for i in (0, 1, 2, 4, 5)]
-
- line = [' ']
- line.append(self.preparer.quote_identifier(name))
- line.append(col_type)
- if not nullable:
- line.append('NOT NULL')
- if default:
- if 'auto_increment' in default:
- pass
- elif (col_type.startswith('timestamp') and
- default.startswith('C')):
- line.append('DEFAULT')
- line.append(default)
- elif default == 'NULL':
- line.append('DEFAULT')
- line.append(default)
- else:
- line.append('DEFAULT')
- line.append("'%s'" % default.replace("'", "''"))
- if extra:
- line.append(extra)
-
- buffer.append(' '.join(line))
-
- return ''.join([('CREATE TABLE %s (\n' %
- self.preparer.quote_identifier(table_name)),
- ',\n'.join(buffer),
- '\n) '])
-
- def _parse_keyexprs(self, identifiers):
- """Unpack '"col"(2),"col" ASC'-ish strings into components."""
-
- return self._re_keyexprs.findall(identifiers)
-
- def _prep_regexes(self):
- """Pre-compile regular expressions."""
-
- self._re_columns = []
- self._pr_options = []
-
- _final = self.preparer.final_quote
-
- quotes = dict(zip(('iq', 'fq', 'esc_fq'),
- [re.escape(s) for s in
- (self.preparer.initial_quote,
- _final,
- self.preparer._escape_identifier(_final))]))
-
- self._pr_name = _pr_compile(
- r'^CREATE (?:\w+ +)?TABLE +'
- r'%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +\($' % quotes,
- self.preparer._unescape_identifier)
-
- # `col`,`col2`(32),`col3`(15) DESC
- #
- # Note: ASC and DESC aren't reflected, so we'll punt...
- self._re_keyexprs = _re_compile(
- r'(?:'
- r'(?:%(iq)s((?:%(esc_fq)s|[^%(fq)s])+)%(fq)s)'
- r'(?:\((\d+)\))?(?=\,|$))+' % quotes)
-
- # 'foo' or 'foo','bar' or 'fo,o','ba''a''r'
- self._re_csv_str = _re_compile(r'\x27(?:\x27\x27|[^\x27])*\x27')
-
- # 123 or 123,456
- self._re_csv_int = _re_compile(r'\d+')
-
-
- # `colname` <type> [type opts]
- # (NOT NULL | NULL)
- # DEFAULT ('value' | CURRENT_TIMESTAMP...)
- # COMMENT 'comment'
- # COLUMN_FORMAT (FIXED|DYNAMIC|DEFAULT)
- # STORAGE (DISK|MEMORY)
- self._re_column = _re_compile(
- r' '
- r'%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +'
- r'(?P<coltype>\w+)'
- r'(?:\((?P<arg>(?:\d+|\d+,\d+|'
- r'(?:\x27(?:\x27\x27|[^\x27])*\x27,?)+))\))?'
- r'(?: +(?P<unsigned>UNSIGNED))?'
- r'(?: +(?P<zerofill>ZEROFILL))?'
- r'(?: +CHARACTER SET +(?P<charset>[\w_]+))?'
- r'(?: +COLLATE +(?P<collate>[\w_]+))?'
- r'(?: +(?P<notnull>NOT NULL))?'
- r'(?: +DEFAULT +(?P<default>'
- r'(?:NULL|\x27(?:\x27\x27|[^\x27])*\x27|\w+'
- r'(?: +ON UPDATE \w+)?)'
- r'))?'
- r'(?: +(?P<autoincr>AUTO_INCREMENT))?'
- r'(?: +COMMENT +(P<comment>(?:\x27\x27|[^\x27])+))?'
- r'(?: +COLUMN_FORMAT +(?P<colfmt>\w+))?'
- r'(?: +STORAGE +(?P<storage>\w+))?'
- r'(?: +(?P<extra>.*))?'
- r',?$'
- % quotes
- )
-
- # Fallback, try to parse as little as possible
- self._re_column_loose = _re_compile(
- r' '
- r'%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +'
- r'(?P<coltype>\w+)'
- r'(?:\((?P<arg>(?:\d+|\d+,\d+|\x27(?:\x27\x27|[^\x27])+\x27))\))?'
- r'.*?(?P<notnull>NOT NULL)?'
- % quotes
- )
-
- # (PRIMARY|UNIQUE|FULLTEXT|SPATIAL) INDEX `name` (USING (BTREE|HASH))?
- # (`col` (ASC|DESC)?, `col` (ASC|DESC)?)
- # KEY_BLOCK_SIZE size | WITH PARSER name
- self._re_key = _re_compile(
- r' '
- r'(?:(?P<type>\S+) )?KEY'
- r'(?: +%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s)?'
- r'(?: +USING +(?P<using_pre>\S+))?'
- r' +\((?P<columns>.+?)\)'
- r'(?: +USING +(?P<using_post>\S+))?'
- r'(?: +KEY_BLOCK_SIZE +(?P<keyblock>\S+))?'
- r'(?: +WITH PARSER +(?P<parser>\S+))?'
- r',?$'
- % quotes
- )
-
- # CONSTRAINT `name` FOREIGN KEY (`local_col`)
- # REFERENCES `remote` (`remote_col`)
- # MATCH FULL | MATCH PARTIAL | MATCH SIMPLE
- # ON DELETE CASCADE ON UPDATE RESTRICT
- #
- # unique constraints come back as KEYs
- kw = quotes.copy()
- kw['on'] = 'RESTRICT|CASCASDE|SET NULL|NOACTION'
- self._re_constraint = _re_compile(
- r' '
- r'CONSTRAINT +'
- r'%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +'
- r'FOREIGN KEY +'
- r'\((?P<local>[^\)]+?)\) REFERENCES +'
- r'(?P<table>%(iq)s[^%(fq)s]+%(fq)s(?:\.%(iq)s[^%(fq)s]+%(fq)s)?) +'
- r'\((?P<foreign>[^\)]+?)\)'
- r'(?: +(?P<match>MATCH \w+))?'
- r'(?: +ON DELETE (?P<ondelete>%(on)s))?'
- r'(?: +ON UPDATE (?P<onupdate>%(on)s))?'
- % kw
- )
-
- # PARTITION
- #
- # punt!
- self._re_partition = _re_compile(
- r' '
- r'(?:SUB)?PARTITION')
-
- # Table-level options (COLLATE, ENGINE, etc.)
- # Do the string options first, since they have quoted strings we need to get rid of.
- for option in _options_of_type_string:
- self._add_option_string(option)
-
- for option in ('ENGINE', 'TYPE', 'AUTO_INCREMENT',
- 'AVG_ROW_LENGTH', 'CHARACTER SET',
- 'DEFAULT CHARSET', 'CHECKSUM',
- 'COLLATE', 'DELAY_KEY_WRITE', 'INSERT_METHOD',
- 'MAX_ROWS', 'MIN_ROWS', 'PACK_KEYS', 'ROW_FORMAT',
- 'KEY_BLOCK_SIZE'):
- self._add_option_word(option)
-
- self._add_option_regex('UNION', r'\([^\)]+\)')
- self._add_option_regex('TABLESPACE', r'.*? STORAGE DISK')
- self._add_option_regex('RAID_TYPE',
- r'\w+\s+RAID_CHUNKS\s*\=\s*\w+RAID_CHUNKSIZE\s*=\s*\w+')
-
- _optional_equals = r'(?:\s*(?:=\s*)|\s+)'
-
- def _add_option_string(self, directive):
- regex = (r'(?P<directive>%s)%s'
- r"'(?P<val>(?:[^']|'')*?)'(?!')" %
- (re.escape(directive), self._optional_equals))
- self._pr_options.append(
- _pr_compile(regex, lambda v: v.replace("\\\\","\\").replace("''", "'")))
-
- def _add_option_word(self, directive):
- regex = (r'(?P<directive>%s)%s'
- r'(?P<val>\w+)' %
- (re.escape(directive), self._optional_equals))
- self._pr_options.append(_pr_compile(regex))
-
- def _add_option_regex(self, directive, regex):
- regex = (r'(?P<directive>%s)%s'
- r'(?P<val>%s)' %
- (re.escape(directive), self._optional_equals, regex))
- self._pr_options.append(_pr_compile(regex))
-
-_options_of_type_string = ('COMMENT', 'DATA DIRECTORY', 'INDEX DIRECTORY',
- 'PASSWORD', 'CONNECTION')
-
-log.class_logger(MySQLTableDefinitionParser)
-log.class_logger(MySQLDialect)
-
-
-class _DecodingRowProxy(object):
- """Return unicode-decoded values based on type inspection.
-
- Smooth over data type issues (esp. with alpha driver versions) and
- normalize strings as Unicode regardless of user-configured driver
- encoding settings.
-
- """
-
- # Some MySQL-python versions can return some columns as
- # sets.Set(['value']) (seriously) but thankfully that doesn't
- # seem to come up in DDL queries.
-
- def __init__(self, rowproxy, charset):
- self.rowproxy = rowproxy
- self.charset = charset
-
- def __getitem__(self, index):
- item = self.rowproxy[index]
- if isinstance(item, _array):
- item = item.tostring()
- # Py2K
- if self.charset and isinstance(item, str):
- # end Py2K
- # Py3K
- #if self.charset and isinstance(item, bytes):
- return item.decode(self.charset)
- else:
- return item
-
- def __getattr__(self, attr):
- item = getattr(self.rowproxy, attr)
- if isinstance(item, _array):
- item = item.tostring()
- # Py2K
- if self.charset and isinstance(item, str):
- # end Py2K
- # Py3K
- #if self.charset and isinstance(item, bytes):
- return item.decode(self.charset)
- else:
- return item
-
-
-def _pr_compile(regex, cleanup=None):
- """Prepare a 2-tuple of compiled regex and callable."""
-
- return (_re_compile(regex), cleanup)
-
-def _re_compile(regex):
- """Compile a string to regex, I and UNICODE."""
-
- return re.compile(regex, re.I | re.UNICODE)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqlconnector.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqlconnector.py
deleted file mode 100755
index 035ebe45..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqlconnector.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# mysql/mysqlconnector.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database via the MySQL Connector/Python adapter.
-
-MySQL Connector/Python is available at:
-
- https://launchpad.net/myconnpy
-
-Connecting
------------
-
-Connect string format::
-
- mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
-
-"""
-
-import re
-
-from sqlalchemy.dialects.mysql.base import (MySQLDialect,
- MySQLExecutionContext, MySQLCompiler, MySQLIdentifierPreparer,
- BIT)
-
-from sqlalchemy.engine import base as engine_base, default
-from sqlalchemy.sql import operators as sql_operators
-from sqlalchemy import exc, log, schema, sql, types as sqltypes, util
-from sqlalchemy import processors
-
-class MySQLExecutionContext_mysqlconnector(MySQLExecutionContext):
-
- def get_lastrowid(self):
- return self.cursor.lastrowid
-
-
-class MySQLCompiler_mysqlconnector(MySQLCompiler):
- def visit_mod(self, binary, **kw):
- return self.process(binary.left) + " %% " + self.process(binary.right)
-
- def post_process_text(self, text):
- return text.replace('%', '%%')
-
-class MySQLIdentifierPreparer_mysqlconnector(MySQLIdentifierPreparer):
-
- def _escape_identifier(self, value):
- value = value.replace(self.escape_quote, self.escape_to_quote)
- return value.replace("%", "%%")
-
-class _myconnpyBIT(BIT):
- def result_processor(self, dialect, coltype):
- """MySQL-connector already converts mysql bits, so."""
-
- return None
-
-class MySQLDialect_mysqlconnector(MySQLDialect):
- driver = 'mysqlconnector'
- supports_unicode_statements = True
- supports_unicode_binds = True
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = True
-
- supports_native_decimal = True
-
- default_paramstyle = 'format'
- execution_ctx_cls = MySQLExecutionContext_mysqlconnector
- statement_compiler = MySQLCompiler_mysqlconnector
-
- preparer = MySQLIdentifierPreparer_mysqlconnector
-
- colspecs = util.update_copy(
- MySQLDialect.colspecs,
- {
- BIT: _myconnpyBIT,
- }
- )
-
- @classmethod
- def dbapi(cls):
- from mysql import connector
- return connector
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- opts.update(url.query)
-
- util.coerce_kw_type(opts, 'buffered', bool)
- util.coerce_kw_type(opts, 'raise_on_warnings', bool)
- opts['buffered'] = True
- opts['raise_on_warnings'] = True
-
- # FOUND_ROWS must be set in ClientFlag to enable
- # supports_sane_rowcount.
- if self.dbapi is not None:
- try:
- from mysql.connector.constants import ClientFlag
- client_flags = opts.get('client_flags', ClientFlag.get_default())
- client_flags |= ClientFlag.FOUND_ROWS
- opts['client_flags'] = client_flags
- except:
- pass
- return [[], opts]
-
- def _get_server_version_info(self, connection):
- dbapi_con = connection.connection
-
- from mysql.connector.constants import ClientFlag
- dbapi_con.set_client_flag(ClientFlag.FOUND_ROWS)
-
- version = dbapi_con.get_server_version()
- return tuple(version)
-
- def _detect_charset(self, connection):
- return connection.connection.get_characterset_info()
-
- def _extract_error_code(self, exception):
- return exception.errno
-
- def is_disconnect(self, e, connection, cursor):
- errnos = (2006, 2013, 2014, 2045, 2055, 2048)
- exceptions = (self.dbapi.OperationalError,self.dbapi.InterfaceError)
- if isinstance(e, exceptions):
- return e.errno in errnos
- else:
- return False
-
- def _compat_fetchall(self, rp, charset=None):
- return rp.fetchall()
-
- def _compat_fetchone(self, rp, charset=None):
- return rp.fetchone()
-
-dialect = MySQLDialect_mysqlconnector
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqldb.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqldb.py
deleted file mode 100755
index 1b0ea85c..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/mysqldb.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# mysql/mysqldb.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database via the MySQL-python adapter.
-
-MySQL-Python is available at:
-
- http://sourceforge.net/projects/mysql-python
-
-At least version 1.2.1 or 1.2.2 should be used.
-
-Connecting
------------
-
-Connect string format::
-
- mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
-
-Character Sets
---------------
-
-Many MySQL server installations default to a ``latin1`` encoding for client
-connections. All data sent through the connection will be converted into
-``latin1``, even if you have ``utf8`` or another character set on your tables
-and columns. With versions 4.1 and higher, you can change the connection
-character set either through server configuration or by including the
-``charset`` parameter in the URL used for ``create_engine``. The ``charset``
-option is passed through to MySQL-Python and has the side-effect of also
-enabling ``use_unicode`` in the driver by default. For regular encoded
-strings, also pass ``use_unicode=0`` in the connection arguments::
-
- # set client encoding to utf8; all strings come back as unicode
- create_engine('mysql+mysqldb:///mydb?charset=utf8')
-
- # set client encoding to utf8; all strings come back as utf8 str
- create_engine('mysql+mysqldb:///mydb?charset=utf8&use_unicode=0')
-
-Known Issues
--------------
-
-MySQL-python version 1.2.2 has a serious memory leak related
-to unicode conversion, a feature which is disabled via ``use_unicode=0``.
-Using a more recent version of MySQL-python is recommended. The
-recommended connection form with SQLAlchemy is::
-
- engine = create_engine('mysql://scott:tiger@localhost/test?charset=utf8&use_unicode=0', pool_recycle=3600)
-
-
-"""
-
-from sqlalchemy.dialects.mysql.base import (MySQLDialect, MySQLExecutionContext,
- MySQLCompiler, MySQLIdentifierPreparer)
-from sqlalchemy.connectors.mysqldb import (
- MySQLDBExecutionContext,
- MySQLDBCompiler,
- MySQLDBIdentifierPreparer,
- MySQLDBConnector
- )
-
-class MySQLExecutionContext_mysqldb(MySQLDBExecutionContext, MySQLExecutionContext):
- pass
-
-
-class MySQLCompiler_mysqldb(MySQLDBCompiler, MySQLCompiler):
- pass
-
-
-class MySQLIdentifierPreparer_mysqldb(MySQLDBIdentifierPreparer, MySQLIdentifierPreparer):
- pass
-
-class MySQLDialect_mysqldb(MySQLDBConnector, MySQLDialect):
- execution_ctx_cls = MySQLExecutionContext_mysqldb
- statement_compiler = MySQLCompiler_mysqldb
- preparer = MySQLIdentifierPreparer_mysqldb
-
-dialect = MySQLDialect_mysqldb
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/oursql.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/oursql.py
deleted file mode 100755
index 4ea4f56b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/oursql.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# mysql/oursql.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database via the oursql adapter.
-
-OurSQL is available at:
-
- http://packages.python.org/oursql/
-
-Connecting
------------
-
-Connect string format::
-
- mysql+oursql://<user>:<password>@<host>[:<port>]/<dbname>
-
-Character Sets
---------------
-
-oursql defaults to using ``utf8`` as the connection charset, but other
-encodings may be used instead. Like the MySQL-Python driver, unicode support
-can be completely disabled::
-
- # oursql sets the connection charset to utf8 automatically; all strings come
- # back as utf8 str
- create_engine('mysql+oursql:///mydb?use_unicode=0')
-
-To not automatically use ``utf8`` and instead use whatever the connection
-defaults to, there is a separate parameter::
-
- # use the default connection charset; all strings come back as unicode
- create_engine('mysql+oursql:///mydb?default_charset=1')
-
- # use latin1 as the connection charset; all strings come back as unicode
- create_engine('mysql+oursql:///mydb?charset=latin1')
-"""
-
-import re
-
-from sqlalchemy.dialects.mysql.base import (BIT, MySQLDialect, MySQLExecutionContext,
- MySQLCompiler, MySQLIdentifierPreparer)
-from sqlalchemy.engine import base as engine_base, default
-from sqlalchemy.sql import operators as sql_operators
-from sqlalchemy import exc, log, schema, sql, types as sqltypes, util
-from sqlalchemy import processors
-
-
-
-class _oursqlBIT(BIT):
- def result_processor(self, dialect, coltype):
- """oursql already converts mysql bits, so."""
-
- return None
-
-
-class MySQLExecutionContext_oursql(MySQLExecutionContext):
-
- @property
- def plain_query(self):
- return self.execution_options.get('_oursql_plain_query', False)
-
-class MySQLDialect_oursql(MySQLDialect):
- driver = 'oursql'
-# Py2K
- supports_unicode_binds = True
- supports_unicode_statements = True
-# end Py2K
-
- supports_native_decimal = True
-
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = True
- execution_ctx_cls = MySQLExecutionContext_oursql
-
- colspecs = util.update_copy(
- MySQLDialect.colspecs,
- {
- sqltypes.Time: sqltypes.Time,
- BIT: _oursqlBIT,
- }
- )
-
- @classmethod
- def dbapi(cls):
- return __import__('oursql')
-
- def do_execute(self, cursor, statement, parameters, context=None):
- """Provide an implementation of *cursor.execute(statement, parameters)*."""
-
- if context and context.plain_query:
- cursor.execute(statement, plain_query=True)
- else:
- cursor.execute(statement, parameters)
-
- def do_begin(self, connection):
- connection.cursor().execute('BEGIN', plain_query=True)
-
- def _xa_query(self, connection, query, xid):
-# Py2K
- arg = connection.connection._escape_string(xid)
-# end Py2K
-# Py3K
-# charset = self._connection_charset
-# arg = connection.connection._escape_string(xid.encode(charset)).decode(charset)
- connection.execution_options(_oursql_plain_query=True).execute(query % arg)
-
- # Because mysql is bad, these methods have to be
- # reimplemented to use _PlainQuery. Basically, some queries
- # refuse to return any data if they're run through
- # the parameterized query API, or refuse to be parameterized
- # in the first place.
- def do_begin_twophase(self, connection, xid):
- self._xa_query(connection, 'XA BEGIN "%s"', xid)
-
- def do_prepare_twophase(self, connection, xid):
- self._xa_query(connection, 'XA END "%s"', xid)
- self._xa_query(connection, 'XA PREPARE "%s"', xid)
-
- def do_rollback_twophase(self, connection, xid, is_prepared=True,
- recover=False):
- if not is_prepared:
- self._xa_query(connection, 'XA END "%s"', xid)
- self._xa_query(connection, 'XA ROLLBACK "%s"', xid)
-
- def do_commit_twophase(self, connection, xid, is_prepared=True,
- recover=False):
- if not is_prepared:
- self.do_prepare_twophase(connection, xid)
- self._xa_query(connection, 'XA COMMIT "%s"', xid)
-
- # Q: why didn't we need all these "plain_query" overrides earlier ?
- # am i on a newer/older version of OurSQL ?
- def has_table(self, connection, table_name, schema=None):
- return MySQLDialect.has_table(self,
- connection.connect().\
- execution_options(_oursql_plain_query=True),
- table_name, schema)
-
- def get_table_options(self, connection, table_name, schema=None, **kw):
- return MySQLDialect.get_table_options(self,
- connection.connect().\
- execution_options(_oursql_plain_query=True),
- table_name,
- schema = schema,
- **kw
- )
-
-
- def get_columns(self, connection, table_name, schema=None, **kw):
- return MySQLDialect.get_columns(self,
- connection.connect().\
- execution_options(_oursql_plain_query=True),
- table_name,
- schema=schema,
- **kw
- )
-
- def get_view_names(self, connection, schema=None, **kw):
- return MySQLDialect.get_view_names(self,
- connection.connect().\
- execution_options(_oursql_plain_query=True),
- schema=schema,
- **kw
- )
-
- def get_table_names(self, connection, schema=None, **kw):
- return MySQLDialect.get_table_names(self,
- connection.connect().\
- execution_options(_oursql_plain_query=True),
- schema
- )
-
- def get_schema_names(self, connection, **kw):
- return MySQLDialect.get_schema_names(self,
- connection.connect().\
- execution_options(_oursql_plain_query=True),
- **kw
- )
-
- def initialize(self, connection):
- return MySQLDialect.initialize(
- self,
- connection.execution_options(_oursql_plain_query=True)
- )
-
- def _show_create_table(self, connection, table, charset=None,
- full_name=None):
- return MySQLDialect._show_create_table(self,
- connection.contextual_connect(close_with_result=True).
- execution_options(_oursql_plain_query=True),
- table, charset, full_name)
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, self.dbapi.ProgrammingError):
- return e.errno is None and 'cursor' not in e.args[1] and e.args[1].endswith('closed')
- else:
- return e.errno in (2006, 2013, 2014, 2045, 2055)
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(database='db', username='user',
- password='passwd')
- opts.update(url.query)
-
- util.coerce_kw_type(opts, 'port', int)
- util.coerce_kw_type(opts, 'compress', bool)
- util.coerce_kw_type(opts, 'autoping', bool)
-
- util.coerce_kw_type(opts, 'default_charset', bool)
- if opts.pop('default_charset', False):
- opts['charset'] = None
- else:
- util.coerce_kw_type(opts, 'charset', str)
- opts['use_unicode'] = opts.get('use_unicode', True)
- util.coerce_kw_type(opts, 'use_unicode', bool)
-
- # FOUND_ROWS must be set in CLIENT_FLAGS to enable
- # supports_sane_rowcount.
- opts.setdefault('found_rows', True)
-
- ssl = {}
- for key in ['ssl_ca', 'ssl_key', 'ssl_cert',
- 'ssl_capath', 'ssl_cipher']:
- if key in opts:
- ssl[key[4:]] = opts[key]
- util.coerce_kw_type(ssl, key[4:], str)
- del opts[key]
- if ssl:
- opts['ssl'] = ssl
-
- return [[], opts]
-
- def _get_server_version_info(self, connection):
- dbapi_con = connection.connection
- version = []
- r = re.compile('[.\-]')
- for n in r.split(dbapi_con.server_info):
- try:
- version.append(int(n))
- except ValueError:
- version.append(n)
- return tuple(version)
-
- def _extract_error_code(self, exception):
- return exception.errno
-
- def _detect_charset(self, connection):
- """Sniff out the character set in use for connection results."""
-
- return connection.connection.charset
-
- def _compat_fetchall(self, rp, charset=None):
- """oursql isn't super-broken like MySQLdb, yaaay."""
- return rp.fetchall()
-
- def _compat_fetchone(self, rp, charset=None):
- """oursql isn't super-broken like MySQLdb, yaaay."""
- return rp.fetchone()
-
- def _compat_first(self, rp, charset=None):
- return rp.first()
-
-
-dialect = MySQLDialect_oursql
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pymysql.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pymysql.py
deleted file mode 100755
index dee3dfea..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pymysql.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# mysql/pymysql.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database via the pymysql adapter.
-
-pymysql is available at:
-
- http://code.google.com/p/pymysql/
-
-Connecting
-----------
-
-Connect string::
-
- mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
-
-MySQL-Python Compatibility
---------------------------
-
-The pymysql DBAPI is a pure Python port of the MySQL-python (MySQLdb) driver,
-and targets 100% compatibility. Most behavioral notes for MySQL-python apply to
-the pymysql driver as well.
-
-"""
-
-from sqlalchemy.dialects.mysql.mysqldb import MySQLDialect_mysqldb
-
-class MySQLDialect_pymysql(MySQLDialect_mysqldb):
- driver = 'pymysql'
-
- @classmethod
- def dbapi(cls):
- return __import__('pymysql')
-
-dialect = MySQLDialect_pymysql \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pyodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pyodbc.py
deleted file mode 100755
index 84d43cf2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/pyodbc.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# mysql/pyodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database via the pyodbc adapter.
-
-pyodbc is available at:
-
- http://pypi.python.org/pypi/pyodbc/
-
-Connecting
-----------
-
-Connect string::
-
- mysql+pyodbc://<username>:<password>@<dsnname>
-
-Limitations
------------
-
-The mysql-pyodbc dialect is subject to unresolved character encoding issues
-which exist within the current ODBC drivers available.
-(see http://code.google.com/p/pyodbc/issues/detail?id=25). Consider usage
-of OurSQL, MySQLdb, or MySQL-connector/Python.
-
-"""
-
-from sqlalchemy.dialects.mysql.base import MySQLDialect, MySQLExecutionContext
-from sqlalchemy.connectors.pyodbc import PyODBCConnector
-from sqlalchemy.engine import base as engine_base
-from sqlalchemy import util
-import re
-
-class MySQLExecutionContext_pyodbc(MySQLExecutionContext):
-
- def get_lastrowid(self):
- cursor = self.create_cursor()
- cursor.execute("SELECT LAST_INSERT_ID()")
- lastrowid = cursor.fetchone()[0]
- cursor.close()
- return lastrowid
-
-class MySQLDialect_pyodbc(PyODBCConnector, MySQLDialect):
- supports_unicode_statements = False
- execution_ctx_cls = MySQLExecutionContext_pyodbc
-
- pyodbc_driver_name = "MySQL"
-
- def __init__(self, **kw):
- # deal with http://code.google.com/p/pyodbc/issues/detail?id=25
- kw.setdefault('convert_unicode', True)
- super(MySQLDialect_pyodbc, self).__init__(**kw)
-
- def _detect_charset(self, connection):
- """Sniff out the character set in use for connection results."""
-
- # Prefer 'character_set_results' for the current connection over the
- # value in the driver. SET NAMES or individual variable SETs will
- # change the charset without updating the driver's view of the world.
- #
- # If it's decided that issuing that sort of SQL leaves you SOL, then
- # this can prefer the driver value.
- rs = connection.execute("SHOW VARIABLES LIKE 'character_set%%'")
- opts = dict([(row[0], row[1]) for row in self._compat_fetchall(rs)])
- for key in ('character_set_connection', 'character_set'):
- if opts.get(key, None):
- return opts[key]
-
- util.warn("Could not detect the connection character set. Assuming latin1.")
- return 'latin1'
-
- def _extract_error_code(self, exception):
- m = re.compile(r"\((\d+)\)").search(str(exception.args))
- c = m.group(1)
- if c:
- return int(c)
- else:
- return None
-
-dialect = MySQLDialect_pyodbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/zxjdbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/zxjdbc.py
deleted file mode 100755
index a56fb6a5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/mysql/zxjdbc.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# mysql/zxjdbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the MySQL database via Jython's zxjdbc JDBC connector.
-
-JDBC Driver
------------
-
-The official MySQL JDBC driver is at
-http://dev.mysql.com/downloads/connector/j/.
-
-Connecting
-----------
-
-Connect string format:
-
- mysql+zxjdbc://<user>:<password>@<hostname>[:<port>]/<database>
-
-Character Sets
---------------
-
-SQLAlchemy zxjdbc dialects pass unicode straight through to the
-zxjdbc/JDBC layer. To allow multiple character sets to be sent from the
-MySQL Connector/J JDBC driver, by default SQLAlchemy sets its
-``characterEncoding`` connection property to ``UTF-8``. It may be
-overriden via a ``create_engine`` URL parameter.
-
-"""
-import re
-
-from sqlalchemy import types as sqltypes, util
-from sqlalchemy.connectors.zxJDBC import ZxJDBCConnector
-from sqlalchemy.dialects.mysql.base import BIT, MySQLDialect, MySQLExecutionContext
-
-class _ZxJDBCBit(BIT):
- def result_processor(self, dialect, coltype):
- """Converts boolean or byte arrays from MySQL Connector/J to longs."""
- def process(value):
- if value is None:
- return value
- if isinstance(value, bool):
- return int(value)
- v = 0L
- for i in value:
- v = v << 8 | (i & 0xff)
- value = v
- return value
- return process
-
-
-class MySQLExecutionContext_zxjdbc(MySQLExecutionContext):
- def get_lastrowid(self):
- cursor = self.create_cursor()
- cursor.execute("SELECT LAST_INSERT_ID()")
- lastrowid = cursor.fetchone()[0]
- cursor.close()
- return lastrowid
-
-
-class MySQLDialect_zxjdbc(ZxJDBCConnector, MySQLDialect):
- jdbc_db_name = 'mysql'
- jdbc_driver_name = 'com.mysql.jdbc.Driver'
-
- execution_ctx_cls = MySQLExecutionContext_zxjdbc
-
- colspecs = util.update_copy(
- MySQLDialect.colspecs,
- {
- sqltypes.Time: sqltypes.Time,
- BIT: _ZxJDBCBit
- }
- )
-
- def _detect_charset(self, connection):
- """Sniff out the character set in use for connection results."""
- # Prefer 'character_set_results' for the current connection over the
- # value in the driver. SET NAMES or individual variable SETs will
- # change the charset without updating the driver's view of the world.
- #
- # If it's decided that issuing that sort of SQL leaves you SOL, then
- # this can prefer the driver value.
- rs = connection.execute("SHOW VARIABLES LIKE 'character_set%%'")
- opts = dict((row[0], row[1]) for row in self._compat_fetchall(rs))
- for key in ('character_set_connection', 'character_set'):
- if opts.get(key, None):
- return opts[key]
-
- util.warn("Could not detect the connection character set. Assuming latin1.")
- return 'latin1'
-
- def _driver_kwargs(self):
- """return kw arg dict to be sent to connect()."""
- return dict(characterEncoding='UTF-8', yearIsDateType='false')
-
- def _extract_error_code(self, exception):
- # e.g.: DBAPIError: (Error) Table 'test.u2' doesn't exist
- # [SQLCode: 1146], [SQLState: 42S02] 'DESCRIBE `u2`' ()
- m = re.compile(r"\[SQLCode\: (\d+)\]").search(str(exception.args))
- c = m.group(1)
- if c:
- return int(c)
-
- def _get_server_version_info(self,connection):
- dbapi_con = connection.connection
- version = []
- r = re.compile('[.\-]')
- for n in r.split(dbapi_con.dbversion):
- try:
- version.append(int(n))
- except ValueError:
- version.append(n)
- return tuple(version)
-
-dialect = MySQLDialect_zxjdbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/__init__.py
deleted file mode 100755
index 59267c5e..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# oracle/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.oracle import base, cx_oracle, zxjdbc
-
-base.dialect = cx_oracle.dialect
-
-from sqlalchemy.dialects.oracle.base import \
- VARCHAR, NVARCHAR, CHAR, DATE, DATETIME, NUMBER,\
- BLOB, BFILE, CLOB, NCLOB, TIMESTAMP, RAW,\
- FLOAT, DOUBLE_PRECISION, LONG, dialect, INTERVAL,\
- VARCHAR2, NVARCHAR2
-
-
-__all__ = (
-'VARCHAR', 'NVARCHAR', 'CHAR', 'DATE', 'DATETIME', 'NUMBER',
-'BLOB', 'BFILE', 'CLOB', 'NCLOB', 'TIMESTAMP', 'RAW',
-'FLOAT', 'DOUBLE_PRECISION', 'LONG', 'dialect', 'INTERVAL',
-'VARCHAR2', 'NVARCHAR2', 'ROWID'
-)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/base.py
deleted file mode 100755
index 14e6309c..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/base.py
+++ /dev/null
@@ -1,1139 +0,0 @@
-# oracle/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Oracle database.
-
-Oracle version 8 through current (11g at the time of this writing) are supported.
-
-For information on connecting via specific drivers, see the documentation
-for that driver.
-
-Connect Arguments
------------------
-
-The dialect supports several :func:`~sqlalchemy.create_engine()` arguments which
-affect the behavior of the dialect regardless of driver in use.
-
-* *use_ansi* - Use ANSI JOIN constructs (see the section on Oracle 8). Defaults
- to ``True``. If ``False``, Oracle-8 compatible constructs are used for joins.
-
-* *optimize_limits* - defaults to ``False``. see the section on LIMIT/OFFSET.
-
-* *use_binds_for_limits* - defaults to ``True``. see the section on LIMIT/OFFSET.
-
-Auto Increment Behavior
------------------------
-
-SQLAlchemy Table objects which include integer primary keys are usually assumed to have
-"autoincrementing" behavior, meaning they can generate their own primary key values upon
-INSERT. Since Oracle has no "autoincrement" feature, SQLAlchemy relies upon sequences
-to produce these values. With the Oracle dialect, *a sequence must always be explicitly
-specified to enable autoincrement*. This is divergent with the majority of documentation
-examples which assume the usage of an autoincrement-capable database. To specify sequences,
-use the sqlalchemy.schema.Sequence object which is passed to a Column construct::
-
- t = Table('mytable', metadata,
- Column('id', Integer, Sequence('id_seq'), primary_key=True),
- Column(...), ...
- )
-
-This step is also required when using table reflection, i.e. autoload=True::
-
- t = Table('mytable', metadata,
- Column('id', Integer, Sequence('id_seq'), primary_key=True),
- autoload=True
- )
-
-Identifier Casing
------------------
-
-In Oracle, the data dictionary represents all case insensitive identifier names
-using UPPERCASE text. SQLAlchemy on the other hand considers an all-lower case identifier
-name to be case insensitive. The Oracle dialect converts all case insensitive identifiers
-to and from those two formats during schema level communication, such as reflection of
-tables and indexes. Using an UPPERCASE name on the SQLAlchemy side indicates a
-case sensitive identifier, and SQLAlchemy will quote the name - this will cause mismatches
-against data dictionary data received from Oracle, so unless identifier names have been
-truly created as case sensitive (i.e. using quoted names), all lowercase names should be
-used on the SQLAlchemy side.
-
-Unicode
--------
-
-SQLAlchemy 0.6 uses the "native unicode" mode provided as of cx_oracle 5. cx_oracle 5.0.2
-or greater is recommended for support of NCLOB. If not using cx_oracle 5, the NLS_LANG
-environment variable needs to be set in order for the oracle client library to use
-proper encoding, such as "AMERICAN_AMERICA.UTF8".
-
-Also note that Oracle supports unicode data through the NVARCHAR and NCLOB data types.
-When using the SQLAlchemy Unicode and UnicodeText types, these DDL types will be used
-within CREATE TABLE statements. Usage of VARCHAR2 and CLOB with unicode text still
-requires NLS_LANG to be set.
-
-LIMIT/OFFSET Support
---------------------
-
-Oracle has no support for the LIMIT or OFFSET keywords. SQLAlchemy uses
-a wrapped subquery approach in conjunction with ROWNUM. The exact methodology
-is taken from
-http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html .
-
-There are two options which affect its behavior:
-
-* the "FIRST ROWS()" optimization keyword is not used by default. To enable the usage of this
- optimization directive, specify ``optimize_limits=True`` to :func:`.create_engine`.
-* the values passed for the limit/offset are sent as bound parameters. Some users have observed
- that Oracle produces a poor query plan when the values are sent as binds and not
- rendered literally. To render the limit/offset values literally within the SQL
- statement, specify ``use_binds_for_limits=False`` to :func:`.create_engine`.
-
-Some users have reported better performance when the entirely different approach of a
-window query is used, i.e. ROW_NUMBER() OVER (ORDER BY), to provide LIMIT/OFFSET (note
-that the majority of users don't observe this). To suit this case the
-method used for LIMIT/OFFSET can be replaced entirely. See the recipe at
-http://www.sqlalchemy.org/trac/wiki/UsageRecipes/WindowFunctionsByDefault
-which installs a select compiler that overrides the generation of limit/offset with
-a window function.
-
-ON UPDATE CASCADE
------------------
-
-Oracle doesn't have native ON UPDATE CASCADE functionality. A trigger based solution
-is available at http://asktom.oracle.com/tkyte/update_cascade/index.html .
-
-When using the SQLAlchemy ORM, the ORM has limited ability to manually issue
-cascading updates - specify ForeignKey objects using the
-"deferrable=True, initially='deferred'" keyword arguments,
-and specify "passive_updates=False" on each relationship().
-
-Oracle 8 Compatibility
-----------------------
-
-When Oracle 8 is detected, the dialect internally configures itself to the following
-behaviors:
-
-* the use_ansi flag is set to False. This has the effect of converting all
- JOIN phrases into the WHERE clause, and in the case of LEFT OUTER JOIN
- makes use of Oracle's (+) operator.
-
-* the NVARCHAR2 and NCLOB datatypes are no longer generated as DDL when
- the :class:`~sqlalchemy.types.Unicode` is used - VARCHAR2 and CLOB are issued
- instead. This because these types don't seem to work correctly on Oracle 8
- even though they are available. The :class:`~sqlalchemy.types.NVARCHAR`
- and :class:`~sqlalchemy.dialects.oracle.NCLOB` types will always generate NVARCHAR2 and NCLOB.
-
-* the "native unicode" mode is disabled when using cx_oracle, i.e. SQLAlchemy
- encodes all Python unicode objects to "string" before passing in as bind parameters.
-
-Synonym/DBLINK Reflection
--------------------------
-
-When using reflection with Table objects, the dialect can optionally search for tables
-indicated by synonyms that reference DBLINK-ed tables by passing the flag
-oracle_resolve_synonyms=True as a keyword argument to the Table construct. If DBLINK
-is not in use this flag should be left off.
-
-"""
-
-import random, re
-
-from sqlalchemy import schema as sa_schema
-from sqlalchemy import util, sql, log
-from sqlalchemy.engine import default, base, reflection
-from sqlalchemy.sql import compiler, visitors, expression
-from sqlalchemy.sql import operators as sql_operators, functions as sql_functions
-from sqlalchemy import types as sqltypes
-from sqlalchemy.types import VARCHAR, NVARCHAR, CHAR, DATE, DATETIME, \
- BLOB, CLOB, TIMESTAMP, FLOAT
-
-RESERVED_WORDS = \
- set('SHARE RAW DROP BETWEEN FROM DESC OPTION PRIOR LONG THEN '\
- 'DEFAULT ALTER IS INTO MINUS INTEGER NUMBER GRANT IDENTIFIED '\
- 'ALL TO ORDER ON FLOAT DATE HAVING CLUSTER NOWAIT RESOURCE '\
- 'ANY TABLE INDEX FOR UPDATE WHERE CHECK SMALLINT WITH DELETE '\
- 'BY ASC REVOKE LIKE SIZE RENAME NOCOMPRESS NULL GROUP VALUES '\
- 'AS IN VIEW EXCLUSIVE COMPRESS SYNONYM SELECT INSERT EXISTS '\
- 'NOT TRIGGER ELSE CREATE INTERSECT PCTFREE DISTINCT USER '\
- 'CONNECT SET MODE OF UNIQUE VARCHAR2 VARCHAR LOCK OR CHAR '\
- 'DECIMAL UNION PUBLIC AND START UID COMMENT'.split())
-
-NO_ARG_FNS = set('UID CURRENT_DATE SYSDATE USER '
- 'CURRENT_TIME CURRENT_TIMESTAMP'.split())
-
-class RAW(sqltypes.LargeBinary):
- pass
-OracleRaw = RAW
-
-class NCLOB(sqltypes.Text):
- __visit_name__ = 'NCLOB'
-
-VARCHAR2 = VARCHAR
-NVARCHAR2 = NVARCHAR
-
-class NUMBER(sqltypes.Numeric, sqltypes.Integer):
- __visit_name__ = 'NUMBER'
-
- def __init__(self, precision=None, scale=None, asdecimal=None):
- if asdecimal is None:
- asdecimal = bool(scale and scale > 0)
-
- super(NUMBER, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal)
-
- def adapt(self, impltype):
- ret = super(NUMBER, self).adapt(impltype)
- # leave a hint for the DBAPI handler
- ret._is_oracle_number = True
- return ret
-
- @property
- def _type_affinity(self):
- if bool(self.scale and self.scale > 0):
- return sqltypes.Numeric
- else:
- return sqltypes.Integer
-
-
-class DOUBLE_PRECISION(sqltypes.Numeric):
- __visit_name__ = 'DOUBLE_PRECISION'
- def __init__(self, precision=None, scale=None, asdecimal=None):
- if asdecimal is None:
- asdecimal = False
-
- super(DOUBLE_PRECISION, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal)
-
-class BFILE(sqltypes.LargeBinary):
- __visit_name__ = 'BFILE'
-
-class LONG(sqltypes.Text):
- __visit_name__ = 'LONG'
-
-class INTERVAL(sqltypes.TypeEngine):
- __visit_name__ = 'INTERVAL'
-
- def __init__(self,
- day_precision=None,
- second_precision=None):
- """Construct an INTERVAL.
-
- Note that only DAY TO SECOND intervals are currently supported.
- This is due to a lack of support for YEAR TO MONTH intervals
- within available DBAPIs (cx_oracle and zxjdbc).
-
- :param day_precision: the day precision value. this is the number of digits
- to store for the day field. Defaults to "2"
- :param second_precision: the second precision value. this is the number of digits
- to store for the fractional seconds field. Defaults to "6".
-
- """
- self.day_precision = day_precision
- self.second_precision = second_precision
-
- @classmethod
- def _adapt_from_generic_interval(cls, interval):
- return INTERVAL(day_precision=interval.day_precision,
- second_precision=interval.second_precision)
-
- @property
- def _type_affinity(self):
- return sqltypes.Interval
-
-class ROWID(sqltypes.TypeEngine):
- """Oracle ROWID type.
-
- When used in a cast() or similar, generates ROWID.
-
- """
- __visit_name__ = 'ROWID'
-
-
-
-class _OracleBoolean(sqltypes.Boolean):
- def get_dbapi_type(self, dbapi):
- return dbapi.NUMBER
-
-colspecs = {
- sqltypes.Boolean : _OracleBoolean,
- sqltypes.Interval : INTERVAL,
-}
-
-ischema_names = {
- 'VARCHAR2' : VARCHAR,
- 'NVARCHAR2' : NVARCHAR,
- 'CHAR' : CHAR,
- 'DATE' : DATE,
- 'NUMBER' : NUMBER,
- 'BLOB' : BLOB,
- 'BFILE' : BFILE,
- 'CLOB' : CLOB,
- 'NCLOB' : NCLOB,
- 'TIMESTAMP' : TIMESTAMP,
- 'TIMESTAMP WITH TIME ZONE' : TIMESTAMP,
- 'INTERVAL DAY TO SECOND' : INTERVAL,
- 'RAW' : RAW,
- 'FLOAT' : FLOAT,
- 'DOUBLE PRECISION' : DOUBLE_PRECISION,
- 'LONG' : LONG,
-}
-
-
-class OracleTypeCompiler(compiler.GenericTypeCompiler):
- # Note:
- # Oracle DATE == DATETIME
- # Oracle does not allow milliseconds in DATE
- # Oracle does not support TIME columns
-
- def visit_datetime(self, type_):
- return self.visit_DATE(type_)
-
- def visit_float(self, type_):
- return self.visit_FLOAT(type_)
-
- def visit_unicode(self, type_):
- if self.dialect._supports_nchar:
- return self.visit_NVARCHAR(type_)
- else:
- return self.visit_VARCHAR(type_)
-
- def visit_INTERVAL(self, type_):
- return "INTERVAL DAY%s TO SECOND%s" % (
- type_.day_precision is not None and
- "(%d)" % type_.day_precision or
- "",
- type_.second_precision is not None and
- "(%d)" % type_.second_precision or
- "",
- )
-
- def visit_TIMESTAMP(self, type_):
- if type_.timezone:
- return "TIMESTAMP WITH TIME ZONE"
- else:
- return "TIMESTAMP"
-
- def visit_DOUBLE_PRECISION(self, type_):
- return self._generate_numeric(type_, "DOUBLE PRECISION")
-
- def visit_NUMBER(self, type_, **kw):
- return self._generate_numeric(type_, "NUMBER", **kw)
-
- def _generate_numeric(self, type_, name, precision=None, scale=None):
- if precision is None:
- precision = type_.precision
-
- if scale is None:
- scale = getattr(type_, 'scale', None)
-
- if precision is None:
- return name
- elif scale is None:
- return "%(name)s(%(precision)s)" % {'name':name,'precision': precision}
- else:
- return "%(name)s(%(precision)s, %(scale)s)" % {'name':name,'precision': precision, 'scale' : scale}
-
- def visit_VARCHAR(self, type_):
- if self.dialect._supports_char_length:
- return "VARCHAR(%(length)s CHAR)" % {'length' : type_.length}
- else:
- return "VARCHAR(%(length)s)" % {'length' : type_.length}
-
- def visit_NVARCHAR(self, type_):
- return "NVARCHAR2(%(length)s)" % {'length' : type_.length}
-
- def visit_text(self, type_):
- return self.visit_CLOB(type_)
-
- def visit_unicode_text(self, type_):
- if self.dialect._supports_nchar:
- return self.visit_NCLOB(type_)
- else:
- return self.visit_CLOB(type_)
-
- def visit_large_binary(self, type_):
- return self.visit_BLOB(type_)
-
- def visit_big_integer(self, type_):
- return self.visit_NUMBER(type_, precision=19)
-
- def visit_boolean(self, type_):
- return self.visit_SMALLINT(type_)
-
- def visit_RAW(self, type_):
- return "RAW(%(length)s)" % {'length' : type_.length}
-
- def visit_ROWID(self, type_):
- return "ROWID"
-
-class OracleCompiler(compiler.SQLCompiler):
- """Oracle compiler modifies the lexical structure of Select
- statements to work under non-ANSI configured Oracle databases, if
- the use_ansi flag is False.
- """
-
- compound_keywords = util.update_copy(
- compiler.SQLCompiler.compound_keywords,
- {
- expression.CompoundSelect.EXCEPT : 'MINUS'
- }
- )
-
- def __init__(self, *args, **kwargs):
- self.__wheres = {}
- self._quoted_bind_names = {}
- super(OracleCompiler, self).__init__(*args, **kwargs)
-
- def visit_mod(self, binary, **kw):
- return "mod(%s, %s)" % (self.process(binary.left), self.process(binary.right))
-
- def visit_now_func(self, fn, **kw):
- return "CURRENT_TIMESTAMP"
-
- def visit_char_length_func(self, fn, **kw):
- return "LENGTH" + self.function_argspec(fn, **kw)
-
- def visit_match_op(self, binary, **kw):
- return "CONTAINS (%s, %s)" % (self.process(binary.left), self.process(binary.right))
-
- def get_select_hint_text(self, byfroms):
- return " ".join(
- "/*+ %s */" % text for table, text in byfroms.items()
- )
-
- def function_argspec(self, fn, **kw):
- if len(fn.clauses) > 0 or fn.name.upper() not in NO_ARG_FNS:
- return compiler.SQLCompiler.function_argspec(self, fn, **kw)
- else:
- return ""
-
- def default_from(self):
- """Called when a ``SELECT`` statement has no froms,
- and no ``FROM`` clause is to be appended.
-
- The Oracle compiler tacks a "FROM DUAL" to the statement.
- """
-
- return " FROM DUAL"
-
- def visit_join(self, join, **kwargs):
- if self.dialect.use_ansi:
- return compiler.SQLCompiler.visit_join(self, join, **kwargs)
- else:
- kwargs['asfrom'] = True
- return self.process(join.left, **kwargs) + \
- ", " + self.process(join.right, **kwargs)
-
- def _get_nonansi_join_whereclause(self, froms):
- clauses = []
-
- def visit_join(join):
- if join.isouter:
- def visit_binary(binary):
- if binary.operator == sql_operators.eq:
- if binary.left.table is join.right:
- binary.left = _OuterJoinColumn(binary.left)
- elif binary.right.table is join.right:
- binary.right = _OuterJoinColumn(binary.right)
- clauses.append(visitors.cloned_traverse(join.onclause, {},
- {'binary':visit_binary}))
- else:
- clauses.append(join.onclause)
-
- for j in join.left, join.right:
- if isinstance(j, expression.Join):
- visit_join(j)
-
- for f in froms:
- if isinstance(f, expression.Join):
- visit_join(f)
-
- if not clauses:
- return None
- else:
- return sql.and_(*clauses)
-
- def visit_outer_join_column(self, vc):
- return self.process(vc.column) + "(+)"
-
- def visit_sequence(self, seq):
- return self.dialect.identifier_preparer.format_sequence(seq) + ".nextval"
-
- def visit_alias(self, alias, asfrom=False, ashint=False, **kwargs):
- """Oracle doesn't like ``FROM table AS alias``. Is the AS standard SQL??"""
-
- if asfrom or ashint:
- alias_name = isinstance(alias.name, expression._generated_label) and \
- self._truncated_identifier("alias", alias.name) or alias.name
-
- if ashint:
- return alias_name
- elif asfrom:
- return self.process(alias.original, asfrom=asfrom, **kwargs) + \
- " " + self.preparer.format_alias(alias, alias_name)
- else:
- return self.process(alias.original, **kwargs)
-
- def returning_clause(self, stmt, returning_cols):
-
- def create_out_param(col, i):
- bindparam = sql.outparam("ret_%d" % i, type_=col.type)
- self.binds[bindparam.key] = bindparam
- return self.bindparam_string(self._truncate_bindparam(bindparam))
-
- columnlist = list(expression._select_iterables(returning_cols))
-
- # within_columns_clause =False so that labels (foo AS bar) don't render
- columns = [self.process(c, within_columns_clause=False, result_map=self.result_map) for c in columnlist]
-
- binds = [create_out_param(c, i) for i, c in enumerate(columnlist)]
-
- return 'RETURNING ' + ', '.join(columns) + " INTO " + ", ".join(binds)
-
- def _TODO_visit_compound_select(self, select):
- """Need to determine how to get ``LIMIT``/``OFFSET`` into a ``UNION`` for Oracle."""
- pass
-
- def visit_select(self, select, **kwargs):
- """Look for ``LIMIT`` and OFFSET in a select statement, and if
- so tries to wrap it in a subquery with ``rownum`` criterion.
- """
-
- if not getattr(select, '_oracle_visit', None):
- if not self.dialect.use_ansi:
- if self.stack and 'from' in self.stack[-1]:
- existingfroms = self.stack[-1]['from']
- else:
- existingfroms = None
-
- froms = select._get_display_froms(existingfroms)
- whereclause = self._get_nonansi_join_whereclause(froms)
- if whereclause is not None:
- select = select.where(whereclause)
- select._oracle_visit = True
-
- if select._limit is not None or select._offset is not None:
- # See http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
- #
- # Generalized form of an Oracle pagination query:
- # select ... from (
- # select /*+ FIRST_ROWS(N) */ ...., rownum as ora_rn from (
- # select distinct ... where ... order by ...
- # ) where ROWNUM <= :limit+:offset
- # ) where ora_rn > :offset
- # Outer select and "ROWNUM as ora_rn" can be dropped if limit=0
-
- # TODO: use annotations instead of clone + attr set ?
- select = select._generate()
- select._oracle_visit = True
-
- # Wrap the middle select and add the hint
- limitselect = sql.select([c for c in select.c])
- if select._limit and self.dialect.optimize_limits:
- limitselect = limitselect.prefix_with("/*+ FIRST_ROWS(%d) */" % select._limit)
-
- limitselect._oracle_visit = True
- limitselect._is_wrapper = True
-
- # If needed, add the limiting clause
- if select._limit is not None:
- max_row = select._limit
- if select._offset is not None:
- max_row += select._offset
- if not self.dialect.use_binds_for_limits:
- max_row = sql.literal_column("%d" % max_row)
- limitselect.append_whereclause(
- sql.literal_column("ROWNUM")<=max_row)
-
- # If needed, add the ora_rn, and wrap again with offset.
- if select._offset is None:
- limitselect.for_update = select.for_update
- select = limitselect
- else:
- limitselect = limitselect.column(
- sql.literal_column("ROWNUM").label("ora_rn"))
- limitselect._oracle_visit = True
- limitselect._is_wrapper = True
-
- offsetselect = sql.select(
- [c for c in limitselect.c if c.key!='ora_rn'])
- offsetselect._oracle_visit = True
- offsetselect._is_wrapper = True
-
- offset_value = select._offset
- if not self.dialect.use_binds_for_limits:
- offset_value = sql.literal_column("%d" % offset_value)
- offsetselect.append_whereclause(
- sql.literal_column("ora_rn")>offset_value)
-
- offsetselect.for_update = select.for_update
- select = offsetselect
-
- kwargs['iswrapper'] = getattr(select, '_is_wrapper', False)
- return compiler.SQLCompiler.visit_select(self, select, **kwargs)
-
- def limit_clause(self, select):
- return ""
-
- def for_update_clause(self, select):
- if self.is_subquery():
- return ""
- elif select.for_update == "nowait":
- return " FOR UPDATE NOWAIT"
- else:
- return super(OracleCompiler, self).for_update_clause(select)
-
-class OracleDDLCompiler(compiler.DDLCompiler):
-
- def define_constraint_cascades(self, constraint):
- text = ""
- if constraint.ondelete is not None:
- text += " ON DELETE %s" % constraint.ondelete
-
- # oracle has no ON UPDATE CASCADE -
- # its only available via triggers http://asktom.oracle.com/tkyte/update_cascade/index.html
- if constraint.onupdate is not None:
- util.warn(
- "Oracle does not contain native UPDATE CASCADE "
- "functionality - onupdates will not be rendered for foreign keys. "
- "Consider using deferrable=True, initially='deferred' or triggers.")
-
- return text
-
-class OracleIdentifierPreparer(compiler.IdentifierPreparer):
-
- reserved_words = set([x.lower() for x in RESERVED_WORDS])
- illegal_initial_characters = set(xrange(0, 10)).union(["_", "$"])
-
- def _bindparam_requires_quotes(self, value):
- """Return True if the given identifier requires quoting."""
- lc_value = value.lower()
- return (lc_value in self.reserved_words
- or value[0] in self.illegal_initial_characters
- or not self.legal_characters.match(unicode(value))
- )
-
- def format_savepoint(self, savepoint):
- name = re.sub(r'^_+', '', savepoint.ident)
- return super(OracleIdentifierPreparer, self).format_savepoint(savepoint, name)
-
-
-class OracleExecutionContext(default.DefaultExecutionContext):
- def fire_sequence(self, seq, type_):
- return self._execute_scalar("SELECT " +
- self.dialect.identifier_preparer.format_sequence(seq) +
- ".nextval FROM DUAL", type_)
-
-class OracleDialect(default.DefaultDialect):
- name = 'oracle'
- supports_alter = True
- supports_unicode_statements = False
- supports_unicode_binds = False
- max_identifier_length = 30
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = False
-
- supports_sequences = True
- sequences_optional = False
- postfetch_lastrowid = False
-
- default_paramstyle = 'named'
- colspecs = colspecs
- ischema_names = ischema_names
- requires_name_normalize = True
-
- supports_default_values = False
- supports_empty_insert = False
-
- statement_compiler = OracleCompiler
- ddl_compiler = OracleDDLCompiler
- type_compiler = OracleTypeCompiler
- preparer = OracleIdentifierPreparer
- execution_ctx_cls = OracleExecutionContext
-
- reflection_options = ('oracle_resolve_synonyms', )
-
- def __init__(self,
- use_ansi=True,
- optimize_limits=False,
- use_binds_for_limits=True,
- **kwargs):
- default.DefaultDialect.__init__(self, **kwargs)
- self.use_ansi = use_ansi
- self.optimize_limits = optimize_limits
- self.use_binds_for_limits = use_binds_for_limits
-
- def initialize(self, connection):
- super(OracleDialect, self).initialize(connection)
- self.implicit_returning = self.__dict__.get(
- 'implicit_returning',
- self.server_version_info > (10, )
- )
-
- if self._is_oracle_8:
- self.colspecs = self.colspecs.copy()
- self.colspecs.pop(sqltypes.Interval)
- self.use_ansi = False
-
- @property
- def _is_oracle_8(self):
- return self.server_version_info and \
- self.server_version_info < (9, )
-
- @property
- def _supports_char_length(self):
- return not self._is_oracle_8
-
- @property
- def _supports_nchar(self):
- return not self._is_oracle_8
-
- def do_release_savepoint(self, connection, name):
- # Oracle does not support RELEASE SAVEPOINT
- pass
-
- def has_table(self, connection, table_name, schema=None):
- if not schema:
- schema = self.default_schema_name
- cursor = connection.execute(
- sql.text("SELECT table_name FROM all_tables "
- "WHERE table_name = :name AND owner = :schema_name"),
- name=self.denormalize_name(table_name), schema_name=self.denormalize_name(schema))
- return cursor.first() is not None
-
- def has_sequence(self, connection, sequence_name, schema=None):
- if not schema:
- schema = self.default_schema_name
- cursor = connection.execute(
- sql.text("SELECT sequence_name FROM all_sequences "
- "WHERE sequence_name = :name AND sequence_owner = :schema_name"),
- name=self.denormalize_name(sequence_name), schema_name=self.denormalize_name(schema))
- return cursor.first() is not None
-
- def normalize_name(self, name):
- if name is None:
- return None
- # Py2K
- if isinstance(name, str):
- name = name.decode(self.encoding)
- # end Py2K
- if name.upper() == name and \
- not self.identifier_preparer._requires_quotes(name.lower()):
- return name.lower()
- else:
- return name
-
- def denormalize_name(self, name):
- if name is None:
- return None
- elif name.lower() == name and not self.identifier_preparer._requires_quotes(name.lower()):
- name = name.upper()
- # Py2K
- if not self.supports_unicode_binds:
- name = name.encode(self.encoding)
- else:
- name = unicode(name)
- # end Py2K
- return name
-
- def _get_default_schema_name(self, connection):
- return self.normalize_name(connection.execute(u'SELECT USER FROM DUAL').scalar())
-
- def _resolve_synonym(self, connection, desired_owner=None, desired_synonym=None, desired_table=None):
- """search for a local synonym matching the given desired owner/name.
-
- if desired_owner is None, attempts to locate a distinct owner.
-
- returns the actual name, owner, dblink name, and synonym name if found.
- """
-
- q = "SELECT owner, table_owner, table_name, db_link, synonym_name FROM all_synonyms WHERE "
- clauses = []
- params = {}
- if desired_synonym:
- clauses.append("synonym_name = :synonym_name")
- params['synonym_name'] = desired_synonym
- if desired_owner:
- clauses.append("table_owner = :desired_owner")
- params['desired_owner'] = desired_owner
- if desired_table:
- clauses.append("table_name = :tname")
- params['tname'] = desired_table
-
- q += " AND ".join(clauses)
-
- result = connection.execute(sql.text(q), **params)
- if desired_owner:
- row = result.first()
- if row:
- return row['table_name'], row['table_owner'], row['db_link'], row['synonym_name']
- else:
- return None, None, None, None
- else:
- rows = result.fetchall()
- if len(rows) > 1:
- raise AssertionError("There are multiple tables visible to the schema, you must specify owner")
- elif len(rows) == 1:
- row = rows[0]
- return row['table_name'], row['table_owner'], row['db_link'], row['synonym_name']
- else:
- return None, None, None, None
-
- @reflection.cache
- def _prepare_reflection_args(self, connection, table_name, schema=None,
- resolve_synonyms=False, dblink='', **kw):
-
- if resolve_synonyms:
- actual_name, owner, dblink, synonym = self._resolve_synonym(
- connection,
- desired_owner=self.denormalize_name(schema),
- desired_synonym=self.denormalize_name(table_name)
- )
- else:
- actual_name, owner, dblink, synonym = None, None, None, None
- if not actual_name:
- actual_name = self.denormalize_name(table_name)
- if not dblink:
- dblink = ''
- if not owner:
- owner = self.denormalize_name(schema or self.default_schema_name)
- return (actual_name, owner, dblink, synonym)
-
- @reflection.cache
- def get_schema_names(self, connection, **kw):
- s = "SELECT username FROM all_users ORDER BY username"
- cursor = connection.execute(s,)
- return [self.normalize_name(row[0]) for row in cursor]
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- schema = self.denormalize_name(schema or self.default_schema_name)
-
- # note that table_names() isnt loading DBLINKed or synonym'ed tables
- if schema is None:
- schema = self.default_schema_name
- s = sql.text(
- "SELECT table_name FROM all_tables "
- "WHERE nvl(tablespace_name, 'no tablespace') NOT IN ('SYSTEM', 'SYSAUX') "
- "AND OWNER = :owner "
- "AND IOT_NAME IS NULL")
- cursor = connection.execute(s, owner=schema)
- return [self.normalize_name(row[0]) for row in cursor]
-
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- schema = self.denormalize_name(schema or self.default_schema_name)
- s = sql.text("SELECT view_name FROM all_views WHERE owner = :owner")
- cursor = connection.execute(s, owner=self.denormalize_name(schema))
- return [self.normalize_name(row[0]) for row in cursor]
-
- @reflection.cache
- def get_columns(self, connection, table_name, schema=None, **kw):
- """
-
- kw arguments can be:
-
- oracle_resolve_synonyms
-
- dblink
-
- """
-
- resolve_synonyms = kw.get('oracle_resolve_synonyms', False)
- dblink = kw.get('dblink', '')
- info_cache = kw.get('info_cache')
-
- (table_name, schema, dblink, synonym) = \
- self._prepare_reflection_args(connection, table_name, schema,
- resolve_synonyms, dblink,
- info_cache=info_cache)
- columns = []
- if self._supports_char_length:
- char_length_col = 'char_length'
- else:
- char_length_col = 'data_length'
-
- c = connection.execute(sql.text(
- "SELECT column_name, data_type, %(char_length_col)s, data_precision, data_scale, "
- "nullable, data_default FROM ALL_TAB_COLUMNS%(dblink)s "
- "WHERE table_name = :table_name AND owner = :owner "
- "ORDER BY column_id" % {'dblink': dblink, 'char_length_col':char_length_col}),
- table_name=table_name, owner=schema)
-
- for row in c:
- (colname, orig_colname, coltype, length, precision, scale, nullable, default) = \
- (self.normalize_name(row[0]), row[0], row[1], row[2], row[3], row[4], row[5]=='Y', row[6])
-
- if coltype == 'NUMBER' :
- coltype = NUMBER(precision, scale)
- elif coltype in ('VARCHAR2', 'NVARCHAR2', 'CHAR'):
- coltype = self.ischema_names.get(coltype)(length)
- elif 'WITH TIME ZONE' in coltype:
- coltype = TIMESTAMP(timezone=True)
- else:
- coltype = re.sub(r'\(\d+\)', '', coltype)
- try:
- coltype = self.ischema_names[coltype]
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, colname))
- coltype = sqltypes.NULLTYPE
-
- cdict = {
- 'name': colname,
- 'type': coltype,
- 'nullable': nullable,
- 'default': default,
- 'autoincrement':default is None
- }
- if orig_colname.lower() == orig_colname:
- cdict['quote'] = True
-
- columns.append(cdict)
- return columns
-
- @reflection.cache
- def get_indexes(self, connection, table_name, schema=None,
- resolve_synonyms=False, dblink='', **kw):
-
-
- info_cache = kw.get('info_cache')
- (table_name, schema, dblink, synonym) = \
- self._prepare_reflection_args(connection, table_name, schema,
- resolve_synonyms, dblink,
- info_cache=info_cache)
- indexes = []
- q = sql.text("""
- SELECT a.index_name, a.column_name, b.uniqueness
- FROM ALL_IND_COLUMNS%(dblink)s a,
- ALL_INDEXES%(dblink)s b
- WHERE
- a.index_name = b.index_name
- AND a.table_owner = b.table_owner
- AND a.table_name = b.table_name
-
- AND a.table_name = :table_name
- AND a.table_owner = :schema
- ORDER BY a.index_name, a.column_position""" % {'dblink': dblink})
- rp = connection.execute(q, table_name=self.denormalize_name(table_name),
- schema=self.denormalize_name(schema))
- indexes = []
- last_index_name = None
- pkeys = self.get_primary_keys(connection, table_name, schema,
- resolve_synonyms=resolve_synonyms,
- dblink=dblink,
- info_cache=kw.get('info_cache'))
- uniqueness = dict(NONUNIQUE=False, UNIQUE=True)
-
- oracle_sys_col = re.compile(r'SYS_NC\d+\$', re.IGNORECASE)
-
- def upper_name_set(names):
- return set([i.upper() for i in names])
-
- pk_names = upper_name_set(pkeys)
-
- def remove_if_primary_key(index):
- # don't include the primary key index
- if index is not None and \
- upper_name_set(index['column_names']) == pk_names:
- indexes.pop()
-
- index = None
- for rset in rp:
- if rset.index_name != last_index_name:
- remove_if_primary_key(index)
- index = dict(name=self.normalize_name(rset.index_name), column_names=[])
- indexes.append(index)
- index['unique'] = uniqueness.get(rset.uniqueness, False)
-
- # filter out Oracle SYS_NC names. could also do an outer join
- # to the all_tab_columns table and check for real col names there.
- if not oracle_sys_col.match(rset.column_name):
- index['column_names'].append(self.normalize_name(rset.column_name))
- last_index_name = rset.index_name
- remove_if_primary_key(index)
- return indexes
-
- @reflection.cache
- def _get_constraint_data(self, connection, table_name, schema=None,
- dblink='', **kw):
-
- rp = connection.execute(
- sql.text("""SELECT
- ac.constraint_name,
- ac.constraint_type,
- loc.column_name AS local_column,
- rem.table_name AS remote_table,
- rem.column_name AS remote_column,
- rem.owner AS remote_owner,
- loc.position as loc_pos,
- rem.position as rem_pos
- FROM all_constraints%(dblink)s ac,
- all_cons_columns%(dblink)s loc,
- all_cons_columns%(dblink)s rem
- WHERE ac.table_name = :table_name
- AND ac.constraint_type IN ('R','P')
- AND ac.owner = :owner
- AND ac.owner = loc.owner
- AND ac.constraint_name = loc.constraint_name
- AND ac.r_owner = rem.owner(+)
- AND ac.r_constraint_name = rem.constraint_name(+)
- AND (rem.position IS NULL or loc.position=rem.position)
- ORDER BY ac.constraint_name, loc.position""" % {'dblink': dblink}),
- table_name=table_name, owner=schema)
- constraint_data = rp.fetchall()
- return constraint_data
-
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- """
-
- kw arguments can be:
-
- oracle_resolve_synonyms
-
- dblink
-
- """
- return self._get_primary_keys(connection, table_name, schema, **kw)[0]
-
- @reflection.cache
- def _get_primary_keys(self, connection, table_name, schema=None, **kw):
- resolve_synonyms = kw.get('oracle_resolve_synonyms', False)
- dblink = kw.get('dblink', '')
- info_cache = kw.get('info_cache')
-
- (table_name, schema, dblink, synonym) = \
- self._prepare_reflection_args(connection, table_name, schema,
- resolve_synonyms, dblink,
- info_cache=info_cache)
- pkeys = []
- constraint_name = None
- constraint_data = self._get_constraint_data(connection, table_name,
- schema, dblink,
- info_cache=kw.get('info_cache'))
-
- for row in constraint_data:
- #print "ROW:" , row
- (cons_name, cons_type, local_column, remote_table, remote_column, remote_owner) = \
- row[0:2] + tuple([self.normalize_name(x) for x in row[2:6]])
- if cons_type == 'P':
- if constraint_name is None:
- constraint_name = self.normalize_name(cons_name)
- pkeys.append(local_column)
- return pkeys, constraint_name
-
- def get_pk_constraint(self, connection, table_name, schema=None, **kw):
- cols, name = self._get_primary_keys(connection, table_name, schema=schema, **kw)
-
- return {
- 'constrained_columns':cols,
- 'name':name
- }
-
- @reflection.cache
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
- """
-
- kw arguments can be:
-
- oracle_resolve_synonyms
-
- dblink
-
- """
-
- requested_schema = schema # to check later on
- resolve_synonyms = kw.get('oracle_resolve_synonyms', False)
- dblink = kw.get('dblink', '')
- info_cache = kw.get('info_cache')
-
- (table_name, schema, dblink, synonym) = \
- self._prepare_reflection_args(connection, table_name, schema,
- resolve_synonyms, dblink,
- info_cache=info_cache)
-
- constraint_data = self._get_constraint_data(connection, table_name,
- schema, dblink,
- info_cache=kw.get('info_cache'))
-
- def fkey_rec():
- return {
- 'name' : None,
- 'constrained_columns' : [],
- 'referred_schema' : None,
- 'referred_table' : None,
- 'referred_columns' : []
- }
-
- fkeys = util.defaultdict(fkey_rec)
-
- for row in constraint_data:
- (cons_name, cons_type, local_column, remote_table, remote_column, remote_owner) = \
- row[0:2] + tuple([self.normalize_name(x) for x in row[2:6]])
-
- if cons_type == 'R':
- if remote_table is None:
- # ticket 363
- util.warn(
- ("Got 'None' querying 'table_name' from "
- "all_cons_columns%(dblink)s - does the user have "
- "proper rights to the table?") % {'dblink':dblink})
- continue
-
- rec = fkeys[cons_name]
- rec['name'] = cons_name
- local_cols, remote_cols = rec['constrained_columns'], rec['referred_columns']
-
- if not rec['referred_table']:
- if resolve_synonyms:
- ref_remote_name, ref_remote_owner, ref_dblink, ref_synonym = \
- self._resolve_synonym(
- connection,
- desired_owner=self.denormalize_name(remote_owner),
- desired_table=self.denormalize_name(remote_table)
- )
- if ref_synonym:
- remote_table = self.normalize_name(ref_synonym)
- remote_owner = self.normalize_name(ref_remote_owner)
-
- rec['referred_table'] = remote_table
-
- if requested_schema is not None or self.denormalize_name(remote_owner) != schema:
- rec['referred_schema'] = remote_owner
-
- local_cols.append(local_column)
- remote_cols.append(remote_column)
-
- return fkeys.values()
-
- @reflection.cache
- def get_view_definition(self, connection, view_name, schema=None,
- resolve_synonyms=False, dblink='', **kw):
- info_cache = kw.get('info_cache')
- (view_name, schema, dblink, synonym) = \
- self._prepare_reflection_args(connection, view_name, schema,
- resolve_synonyms, dblink,
- info_cache=info_cache)
- s = sql.text("""
- SELECT text FROM all_views
- WHERE owner = :schema
- AND view_name = :view_name
- """)
- rp = connection.execute(s,
- view_name=view_name, schema=schema).scalar()
- if rp:
- return rp.decode(self.encoding)
- else:
- return None
-
-
-
-class _OuterJoinColumn(sql.ClauseElement):
- __visit_name__ = 'outer_join_column'
-
- def __init__(self, column):
- self.column = column
-
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/cx_oracle.py
deleted file mode 100755
index a917aac0..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/cx_oracle.py
+++ /dev/null
@@ -1,718 +0,0 @@
-# oracle/cx_oracle.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Oracle database via the cx_oracle driver.
-
-Driver
-------
-
-The Oracle dialect uses the cx_oracle driver, available at
-http://cx-oracle.sourceforge.net/ . The dialect has several behaviors
-which are specifically tailored towards compatibility with this module.
-Version 5.0 or greater is **strongly** recommended, as SQLAlchemy makes
-extensive use of the cx_oracle output converters for numeric and
-string conversions.
-
-Connecting
-----------
-
-Connecting with create_engine() uses the standard URL approach of
-``oracle://user:pass@host:port/dbname[?key=value&key=value...]``. If dbname is present, the
-host, port, and dbname tokens are converted to a TNS name using the cx_oracle
-:func:`makedsn()` function. Otherwise, the host token is taken directly as a TNS name.
-
-Additional arguments which may be specified either as query string arguments on the
-URL, or as keyword arguments to :func:`~sqlalchemy.create_engine()` are:
-
-* *allow_twophase* - enable two-phase transactions. Defaults to ``True``.
-
-* *arraysize* - set the cx_oracle.arraysize value on cursors, in SQLAlchemy
- it defaults to 50. See the section on "LOB Objects" below.
-
-* *auto_convert_lobs* - defaults to True, see the section on LOB objects.
-
-* *auto_setinputsizes* - the cx_oracle.setinputsizes() call is issued for all bind parameters.
- This is required for LOB datatypes but can be disabled to reduce overhead. Defaults
- to ``True``.
-
-* *mode* - This is given the string value of SYSDBA or SYSOPER, or alternatively an
- integer value. This value is only available as a URL query string argument.
-
-* *threaded* - enable multithreaded access to cx_oracle connections. Defaults
- to ``True``. Note that this is the opposite default of cx_oracle itself.
-
-Unicode
--------
-
-cx_oracle 5 fully supports Python unicode objects. SQLAlchemy will pass
-all unicode strings directly to cx_oracle, and additionally uses an output
-handler so that all string based result values are returned as unicode as well.
-
-Note that this behavior is disabled when Oracle 8 is detected, as it has been
-observed that issues remain when passing Python unicodes to cx_oracle with Oracle 8.
-
-LOB Objects
------------
-
-cx_oracle returns oracle LOBs using the cx_oracle.LOB object. SQLAlchemy converts
-these to strings so that the interface of the Binary type is consistent with that of
-other backends, and so that the linkage to a live cursor is not needed in scenarios
-like result.fetchmany() and result.fetchall(). This means that by default, LOB
-objects are fully fetched unconditionally by SQLAlchemy, and the linkage to a live
-cursor is broken.
-
-To disable this processing, pass ``auto_convert_lobs=False`` to :func:`create_engine()`.
-
-Two Phase Transaction Support
------------------------------
-
-Two Phase transactions are implemented using XA transactions. Success has been reported
-with this feature but it should be regarded as experimental.
-
-Precision Numerics
-------------------
-
-The SQLAlchemy dialect goes thorugh a lot of steps to ensure
-that decimal numbers are sent and received with full accuracy.
-An "outputtypehandler" callable is associated with each
-cx_oracle connection object which detects numeric types and
-receives them as string values, instead of receiving a Python
-``float`` directly, which is then passed to the Python
-``Decimal`` constructor. The :class:`.Numeric` and
-:class:`.Float` types under the cx_oracle dialect are aware of
-this behavior, and will coerce the ``Decimal`` to ``float`` if
-the ``asdecimal`` flag is ``False`` (default on :class:`.Float`,
-optional on :class:`.Numeric`).
-
-The handler attempts to use the "precision" and "scale"
-attributes of the result set column to best determine if
-subsequent incoming values should be received as ``Decimal`` as
-opposed to int (in which case no processing is added). There are
-several scenarios where OCI_ does not provide unambiguous data
-as to the numeric type, including some situations where
-individual rows may return a combination of floating point and
-integer values. Certain values for "precision" and "scale" have
-been observed to determine this scenario. When it occurs, the
-outputtypehandler receives as string and then passes off to a
-processing function which detects, for each returned value, if a
-decimal point is present, and if so converts to ``Decimal``,
-otherwise to int. The intention is that simple int-based
-statements like "SELECT my_seq.nextval() FROM DUAL" continue to
-return ints and not ``Decimal`` objects, and that any kind of
-floating point value is received as a string so that there is no
-floating point loss of precision.
-
-The "decimal point is present" logic itself is also sensitive to
-locale. Under OCI_, this is controlled by the NLS_LANG
-environment variable. Upon first connection, the dialect runs a
-test to determine the current "decimal" character, which can be
-a comma "," for european locales. From that point forward the
-outputtypehandler uses that character to represent a decimal
-point (this behavior is new in version 0.6.6). Note that
-cx_oracle 5.0.3 or greater is required when dealing with
-numerics with locale settings that don't use a period "." as the
-decimal character.
-
-.. _OCI: http://www.oracle.com/technetwork/database/features/oci/index.html
-
-"""
-
-from sqlalchemy.dialects.oracle.base import OracleCompiler, OracleDialect, \
- RESERVED_WORDS, OracleExecutionContext
-from sqlalchemy.dialects.oracle import base as oracle
-from sqlalchemy.engine import base
-from sqlalchemy import types as sqltypes, util, exc, processors
-from datetime import datetime
-import random
-import collections
-from sqlalchemy.util.compat import decimal
-import re
-
-class _OracleNumeric(sqltypes.Numeric):
- def bind_processor(self, dialect):
- # cx_oracle accepts Decimal objects and floats
- return None
-
- def result_processor(self, dialect, coltype):
- # we apply a cx_oracle type handler to all connections
- # that converts floating point strings to Decimal().
- # However, in some subquery situations, Oracle doesn't
- # give us enough information to determine int or Decimal.
- # It could even be int/Decimal differently on each row,
- # regardless of the scale given for the originating type.
- # So we still need an old school isinstance() handler
- # here for decimals.
-
- if dialect.supports_native_decimal:
- if self.asdecimal:
- if self.scale is None:
- fstring = "%.10f"
- else:
- fstring = "%%.%df" % self.scale
- def to_decimal(value):
- if value is None:
- return None
- elif isinstance(value, decimal.Decimal):
- return value
- else:
- return decimal.Decimal(fstring % value)
- return to_decimal
- else:
- if self.precision is None and self.scale is None:
- return processors.to_float
- elif not getattr(self, '_is_oracle_number', False) \
- and self.scale is not None:
- return processors.to_float
- else:
- return None
- else:
- # cx_oracle 4 behavior, will assume
- # floats
- return super(_OracleNumeric, self).\
- result_processor(dialect, coltype)
-
-class _OracleDate(sqltypes.Date):
- def bind_processor(self, dialect):
- return None
-
- def result_processor(self, dialect, coltype):
- def process(value):
- if value is not None:
- return value.date()
- else:
- return value
- return process
-
-class _LOBMixin(object):
- def result_processor(self, dialect, coltype):
- if not dialect.auto_convert_lobs:
- # return the cx_oracle.LOB directly.
- return None
-
- def process(value):
- if value is not None:
- return value.read()
- else:
- return value
- return process
-
-class _NativeUnicodeMixin(object):
- # Py3K
- #pass
- # Py2K
- def bind_processor(self, dialect):
- if dialect._cx_oracle_with_unicode:
- def process(value):
- if value is None:
- return value
- else:
- return unicode(value)
- return process
- else:
- return super(_NativeUnicodeMixin, self).bind_processor(dialect)
- # end Py2K
-
- # we apply a connection output handler that returns
- # unicode in all cases, so the "native_unicode" flag
- # will be set for the default String.result_processor.
-
-class _OracleChar(_NativeUnicodeMixin, sqltypes.CHAR):
- def get_dbapi_type(self, dbapi):
- return dbapi.FIXED_CHAR
-
-class _OracleNVarChar(_NativeUnicodeMixin, sqltypes.NVARCHAR):
- def get_dbapi_type(self, dbapi):
- return getattr(dbapi, 'UNICODE', dbapi.STRING)
-
-class _OracleText(_LOBMixin, sqltypes.Text):
- def get_dbapi_type(self, dbapi):
- return dbapi.CLOB
-
-class _OracleString(_NativeUnicodeMixin, sqltypes.String):
- pass
-
-class _OracleUnicodeText(_LOBMixin, _NativeUnicodeMixin, sqltypes.UnicodeText):
- def get_dbapi_type(self, dbapi):
- return dbapi.NCLOB
-
- def result_processor(self, dialect, coltype):
- lob_processor = _LOBMixin.result_processor(self, dialect, coltype)
- if lob_processor is None:
- return None
-
- string_processor = sqltypes.UnicodeText.result_processor(self, dialect, coltype)
-
- if string_processor is None:
- return lob_processor
- else:
- def process(value):
- return string_processor(lob_processor(value))
- return process
-
-class _OracleInteger(sqltypes.Integer):
- def result_processor(self, dialect, coltype):
- def to_int(val):
- if val is not None:
- val = int(val)
- return val
- return to_int
-
-class _OracleBinary(_LOBMixin, sqltypes.LargeBinary):
- def get_dbapi_type(self, dbapi):
- return dbapi.BLOB
-
- def bind_processor(self, dialect):
- return None
-
-class _OracleInterval(oracle.INTERVAL):
- def get_dbapi_type(self, dbapi):
- return dbapi.INTERVAL
-
-class _OracleRaw(oracle.RAW):
- pass
-
-class _OracleRowid(oracle.ROWID):
- def get_dbapi_type(self, dbapi):
- return dbapi.ROWID
-
-class OracleCompiler_cx_oracle(OracleCompiler):
- def bindparam_string(self, name):
- if self.preparer._bindparam_requires_quotes(name):
- quoted_name = '"%s"' % name
- self._quoted_bind_names[name] = quoted_name
- return OracleCompiler.bindparam_string(self, quoted_name)
- else:
- return OracleCompiler.bindparam_string(self, name)
-
-
-class OracleExecutionContext_cx_oracle(OracleExecutionContext):
-
- def pre_exec(self):
- quoted_bind_names = \
- getattr(self.compiled, '_quoted_bind_names', None)
- if quoted_bind_names:
- if not self.dialect.supports_unicode_statements:
- # if DBAPI doesn't accept unicode statements,
- # keys in self.parameters would have been encoded
- # here. so convert names in quoted_bind_names
- # to encoded as well.
- quoted_bind_names = \
- dict(
- (fromname.encode(self.dialect.encoding),
- toname.encode(self.dialect.encoding))
- for fromname, toname in
- quoted_bind_names.items()
- )
- for param in self.parameters:
- for fromname, toname in quoted_bind_names.items():
- param[toname] = param[fromname]
- del param[fromname]
-
- if self.dialect.auto_setinputsizes:
- # cx_oracle really has issues when you setinputsizes
- # on String, including that outparams/RETURNING
- # breaks for varchars
- self.set_input_sizes(quoted_bind_names,
- exclude_types=self.dialect._cx_oracle_string_types
- )
-
- # if a single execute, check for outparams
- if len(self.compiled_parameters) == 1:
- for bindparam in self.compiled.binds.values():
- if bindparam.isoutparam:
- dbtype = bindparam.type.dialect_impl(self.dialect).\
- get_dbapi_type(self.dialect.dbapi)
- if not hasattr(self, 'out_parameters'):
- self.out_parameters = {}
- if dbtype is None:
- raise exc.InvalidRequestError("Cannot create out parameter for parameter "
- "%r - it's type %r is not supported by"
- " cx_oracle" %
- (name, bindparam.type)
- )
- name = self.compiled.bind_names[bindparam]
- self.out_parameters[name] = self.cursor.var(dbtype)
- self.parameters[0][quoted_bind_names.get(name, name)] = \
- self.out_parameters[name]
-
- def create_cursor(self):
- c = self._dbapi_connection.cursor()
- if self.dialect.arraysize:
- c.arraysize = self.dialect.arraysize
-
- return c
-
- def get_result_proxy(self):
- if hasattr(self, 'out_parameters') and self.compiled.returning:
- returning_params = dict(
- (k, v.getvalue())
- for k, v in self.out_parameters.items()
- )
- return ReturningResultProxy(self, returning_params)
-
- result = None
- if self.cursor.description is not None:
- for column in self.cursor.description:
- type_code = column[1]
- if type_code in self.dialect._cx_oracle_binary_types:
- result = base.BufferedColumnResultProxy(self)
-
- if result is None:
- result = base.ResultProxy(self)
-
- if hasattr(self, 'out_parameters'):
- if self.compiled_parameters is not None and \
- len(self.compiled_parameters) == 1:
- result.out_parameters = out_parameters = {}
-
- for bind, name in self.compiled.bind_names.items():
- if name in self.out_parameters:
- type = bind.type
- impl_type = type.dialect_impl(self.dialect)
- dbapi_type = impl_type.get_dbapi_type(self.dialect.dbapi)
- result_processor = impl_type.\
- result_processor(self.dialect,
- dbapi_type)
- if result_processor is not None:
- out_parameters[name] = \
- result_processor(self.out_parameters[name].getvalue())
- else:
- out_parameters[name] = self.out_parameters[name].getvalue()
- else:
- result.out_parameters = dict(
- (k, v.getvalue())
- for k, v in self.out_parameters.items()
- )
-
- return result
-
-class OracleExecutionContext_cx_oracle_with_unicode(OracleExecutionContext_cx_oracle):
- """Support WITH_UNICODE in Python 2.xx.
-
- WITH_UNICODE allows cx_Oracle's Python 3 unicode handling
- behavior under Python 2.x. This mode in some cases disallows
- and in other cases silently passes corrupted data when
- non-Python-unicode strings (a.k.a. plain old Python strings)
- are passed as arguments to connect(), the statement sent to execute(),
- or any of the bind parameter keys or values sent to execute().
- This optional context therefore ensures that all statements are
- passed as Python unicode objects.
-
- """
- def __init__(self, *arg, **kw):
- OracleExecutionContext_cx_oracle.__init__(self, *arg, **kw)
- self.statement = unicode(self.statement)
-
- def _execute_scalar(self, stmt):
- return super(OracleExecutionContext_cx_oracle_with_unicode, self).\
- _execute_scalar(unicode(stmt))
-
-class ReturningResultProxy(base.FullyBufferedResultProxy):
- """Result proxy which stuffs the _returning clause + outparams into the fetch."""
-
- def __init__(self, context, returning_params):
- self._returning_params = returning_params
- super(ReturningResultProxy, self).__init__(context)
-
- def _cursor_description(self):
- returning = self.context.compiled.returning
-
- ret = []
- for c in returning:
- if hasattr(c, 'name'):
- ret.append((c.name, c.type))
- else:
- ret.append((c.anon_label, c.type))
- return ret
-
- def _buffer_rows(self):
- return collections.deque([tuple(self._returning_params["ret_%d" % i]
- for i, c in enumerate(self._returning_params))])
-
-class OracleDialect_cx_oracle(OracleDialect):
- execution_ctx_cls = OracleExecutionContext_cx_oracle
- statement_compiler = OracleCompiler_cx_oracle
-
- driver = "cx_oracle"
-
- colspecs = colspecs = {
- sqltypes.Numeric: _OracleNumeric,
- sqltypes.Date : _OracleDate, # generic type, assume datetime.date is desired
- oracle.DATE: oracle.DATE, # non generic type - passthru
- sqltypes.LargeBinary : _OracleBinary,
- sqltypes.Boolean : oracle._OracleBoolean,
- sqltypes.Interval : _OracleInterval,
- oracle.INTERVAL : _OracleInterval,
- sqltypes.Text : _OracleText,
- sqltypes.String : _OracleString,
- sqltypes.UnicodeText : _OracleUnicodeText,
- sqltypes.CHAR : _OracleChar,
- sqltypes.Integer : _OracleInteger, # this is only needed for OUT parameters.
- # it would be nice if we could not use it otherwise.
- oracle.RAW: _OracleRaw,
- sqltypes.Unicode: _OracleNVarChar,
- sqltypes.NVARCHAR : _OracleNVarChar,
- oracle.ROWID: _OracleRowid,
- }
-
-
- execute_sequence_format = list
-
- def __init__(self,
- auto_setinputsizes=True,
- auto_convert_lobs=True,
- threaded=True,
- allow_twophase=True,
- arraysize=50, **kwargs):
- OracleDialect.__init__(self, **kwargs)
- self.threaded = threaded
- self.arraysize = arraysize
- self.allow_twophase = allow_twophase
- self.supports_timestamp = self.dbapi is None or hasattr(self.dbapi, 'TIMESTAMP' )
- self.auto_setinputsizes = auto_setinputsizes
- self.auto_convert_lobs = auto_convert_lobs
-
- if hasattr(self.dbapi, 'version'):
- self.cx_oracle_ver = tuple([int(x) for x in self.dbapi.version.split('.')])
- else:
- self.cx_oracle_ver = (0, 0, 0)
-
- def types(*names):
- return set([
- getattr(self.dbapi, name, None) for name in names
- ]).difference([None])
-
- self._cx_oracle_string_types = types("STRING", "UNICODE", "NCLOB", "CLOB")
- self._cx_oracle_unicode_types = types("UNICODE", "NCLOB")
- self._cx_oracle_binary_types = types("BFILE", "CLOB", "NCLOB", "BLOB")
- self.supports_unicode_binds = self.cx_oracle_ver >= (5, 0)
- self.supports_native_decimal = self.cx_oracle_ver >= (5, 0)
- self._cx_oracle_native_nvarchar = self.cx_oracle_ver >= (5, 0)
-
- if self.cx_oracle_ver is None:
- # this occurs in tests with mock DBAPIs
- self._cx_oracle_string_types = set()
- self._cx_oracle_with_unicode = False
- elif self.cx_oracle_ver >= (5,) and not hasattr(self.dbapi, 'UNICODE'):
- # cx_Oracle WITH_UNICODE mode. *only* python
- # unicode objects accepted for anything
- self.supports_unicode_statements = True
- self.supports_unicode_binds = True
- self._cx_oracle_with_unicode = True
- # Py2K
- # There's really no reason to run with WITH_UNICODE under Python 2.x.
- # Give the user a hint.
- util.warn("cx_Oracle is compiled under Python 2.xx using the "
- "WITH_UNICODE flag. Consider recompiling cx_Oracle without "
- "this flag, which is in no way necessary for full support of Unicode. "
- "Otherwise, all string-holding bind parameters must "
- "be explicitly typed using SQLAlchemy's String type or one of its subtypes,"
- "or otherwise be passed as Python unicode. Plain Python strings "
- "passed as bind parameters will be silently corrupted by cx_Oracle."
- )
- self.execution_ctx_cls = OracleExecutionContext_cx_oracle_with_unicode
- # end Py2K
- else:
- self._cx_oracle_with_unicode = False
-
- if self.cx_oracle_ver is None or \
- not self.auto_convert_lobs or \
- not hasattr(self.dbapi, 'CLOB'):
- self.dbapi_type_map = {}
- else:
- # only use this for LOB objects. using it for strings, dates
- # etc. leads to a little too much magic, reflection doesn't know if it should
- # expect encoded strings or unicodes, etc.
- self.dbapi_type_map = {
- self.dbapi.CLOB: oracle.CLOB(),
- self.dbapi.NCLOB:oracle.NCLOB(),
- self.dbapi.BLOB: oracle.BLOB(),
- self.dbapi.BINARY: oracle.RAW(),
- }
- @classmethod
- def dbapi(cls):
- import cx_Oracle
- return cx_Oracle
-
- def initialize(self, connection):
- super(OracleDialect_cx_oracle, self).initialize(connection)
- if self._is_oracle_8:
- self.supports_unicode_binds = False
- self._detect_decimal_char(connection)
-
- def _detect_decimal_char(self, connection):
- """detect if the decimal separator character is not '.', as
- is the case with european locale settings for NLS_LANG.
-
- cx_oracle itself uses similar logic when it formats Python
- Decimal objects to strings on the bind side (as of 5.0.3),
- as Oracle sends/receives string numerics only in the
- current locale.
-
- """
- if self.cx_oracle_ver < (5,):
- # no output type handlers before version 5
- return
-
- cx_Oracle = self.dbapi
- conn = connection.connection
-
- # override the output_type_handler that's
- # on the cx_oracle connection with a plain
- # one on the cursor
-
- def output_type_handler(cursor, name, defaultType,
- size, precision, scale):
- return cursor.var(
- cx_Oracle.STRING,
- 255, arraysize=cursor.arraysize)
-
- cursor = conn.cursor()
- cursor.outputtypehandler = output_type_handler
- cursor.execute("SELECT 0.1 FROM DUAL")
- val = cursor.fetchone()[0]
- cursor.close()
- char = re.match(r"([\.,])", val).group(1)
- if char != '.':
- _detect_decimal = self._detect_decimal
- self._detect_decimal = \
- lambda value: _detect_decimal(value.replace(char, '.'))
- self._to_decimal = \
- lambda value: decimal.Decimal(value.replace(char, '.'))
-
- def _detect_decimal(self, value):
- if "." in value:
- return decimal.Decimal(value)
- else:
- return int(value)
-
- _to_decimal = decimal.Decimal
-
- def on_connect(self):
- if self.cx_oracle_ver < (5,):
- # no output type handlers before version 5
- return
-
- cx_Oracle = self.dbapi
- def output_type_handler(cursor, name, defaultType,
- size, precision, scale):
- # convert all NUMBER with precision + positive scale to Decimal
- # this almost allows "native decimal" mode.
- if defaultType == cx_Oracle.NUMBER and precision and scale > 0:
- return cursor.var(
- cx_Oracle.STRING,
- 255,
- outconverter=self._to_decimal,
- arraysize=cursor.arraysize)
- # if NUMBER with zero precision and 0 or neg scale, this appears
- # to indicate "ambiguous". Use a slower converter that will
- # make a decision based on each value received - the type
- # may change from row to row (!). This kills
- # off "native decimal" mode, handlers still needed.
- elif defaultType == cx_Oracle.NUMBER \
- and not precision and scale <= 0:
- return cursor.var(
- cx_Oracle.STRING,
- 255,
- outconverter=self._detect_decimal,
- arraysize=cursor.arraysize)
- # allow all strings to come back natively as Unicode
- elif defaultType in (cx_Oracle.STRING, cx_Oracle.FIXED_CHAR):
- return cursor.var(unicode, size, cursor.arraysize)
-
- def on_connect(conn):
- conn.outputtypehandler = output_type_handler
-
- return on_connect
-
- def create_connect_args(self, url):
- dialect_opts = dict(url.query)
- for opt in ('use_ansi', 'auto_setinputsizes', 'auto_convert_lobs',
- 'threaded', 'allow_twophase'):
- if opt in dialect_opts:
- util.coerce_kw_type(dialect_opts, opt, bool)
- setattr(self, opt, dialect_opts[opt])
-
- if url.database:
- # if we have a database, then we have a remote host
- port = url.port
- if port:
- port = int(port)
- else:
- port = 1521
- dsn = self.dbapi.makedsn(url.host, port, url.database)
- else:
- # we have a local tnsname
- dsn = url.host
-
- opts = dict(
- user=url.username,
- password=url.password,
- dsn=dsn,
- threaded=self.threaded,
- twophase=self.allow_twophase,
- )
-
- # Py2K
- if self._cx_oracle_with_unicode:
- for k, v in opts.items():
- if isinstance(v, str):
- opts[k] = unicode(v)
- else:
- for k, v in opts.items():
- if isinstance(v, unicode):
- opts[k] = str(v)
- # end Py2K
-
- if 'mode' in url.query:
- opts['mode'] = url.query['mode']
- if isinstance(opts['mode'], basestring):
- mode = opts['mode'].upper()
- if mode == 'SYSDBA':
- opts['mode'] = self.dbapi.SYSDBA
- elif mode == 'SYSOPER':
- opts['mode'] = self.dbapi.SYSOPER
- else:
- util.coerce_kw_type(opts, 'mode', int)
- return ([], opts)
-
- def _get_server_version_info(self, connection):
- return tuple(
- int(x)
- for x in connection.connection.version.split('.')
- )
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, self.dbapi.InterfaceError):
- return "not connected" in str(e)
- else:
- return "ORA-03114" in str(e) or "ORA-03113" in str(e)
-
- def create_xid(self):
- """create a two-phase transaction ID.
-
- this id will be passed to do_begin_twophase(), do_rollback_twophase(),
- do_commit_twophase(). its format is unspecified."""
-
- id = random.randint(0, 2 ** 128)
- return (0x1234, "%032x" % id, "%032x" % 9)
-
- def do_begin_twophase(self, connection, xid):
- connection.connection.begin(*xid)
-
- def do_prepare_twophase(self, connection, xid):
- connection.connection.prepare()
-
- def do_rollback_twophase(self, connection, xid, is_prepared=True, recover=False):
- self.do_rollback(connection.connection)
-
- def do_commit_twophase(self, connection, xid, is_prepared=True, recover=False):
- self.do_commit(connection.connection)
-
- def do_recover_twophase(self, connection):
- pass
-
-dialect = OracleDialect_cx_oracle
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/zxjdbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/zxjdbc.py
deleted file mode 100755
index 6ec33972..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/oracle/zxjdbc.py
+++ /dev/null
@@ -1,215 +0,0 @@
-# oracle/zxjdbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the Oracle database via the zxjdbc JDBC connector.
-
-JDBC Driver
------------
-
-The official Oracle JDBC driver is at
-http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html.
-
-"""
-import decimal
-import re
-
-from sqlalchemy import sql, types as sqltypes, util
-from sqlalchemy.connectors.zxJDBC import ZxJDBCConnector
-from sqlalchemy.dialects.oracle.base import OracleCompiler, OracleDialect, OracleExecutionContext
-from sqlalchemy.engine import base, default
-from sqlalchemy.sql import expression
-
-SQLException = zxJDBC = None
-
-class _ZxJDBCDate(sqltypes.Date):
-
- def result_processor(self, dialect, coltype):
- def process(value):
- if value is None:
- return None
- else:
- return value.date()
- return process
-
-
-class _ZxJDBCNumeric(sqltypes.Numeric):
-
- def result_processor(self, dialect, coltype):
- #XXX: does the dialect return Decimal or not???
- # if it does (in all cases), we could use a None processor as well as
- # the to_float generic processor
- if self.asdecimal:
- def process(value):
- if isinstance(value, decimal.Decimal):
- return value
- else:
- return decimal.Decimal(str(value))
- else:
- def process(value):
- if isinstance(value, decimal.Decimal):
- return float(value)
- else:
- return value
- return process
-
-
-class OracleCompiler_zxjdbc(OracleCompiler):
-
- def returning_clause(self, stmt, returning_cols):
- self.returning_cols = list(expression._select_iterables(returning_cols))
-
- # within_columns_clause=False so that labels (foo AS bar) don't render
- columns = [self.process(c, within_columns_clause=False, result_map=self.result_map)
- for c in self.returning_cols]
-
- if not hasattr(self, 'returning_parameters'):
- self.returning_parameters = []
-
- binds = []
- for i, col in enumerate(self.returning_cols):
- dbtype = col.type.dialect_impl(self.dialect).get_dbapi_type(self.dialect.dbapi)
- self.returning_parameters.append((i + 1, dbtype))
-
- bindparam = sql.bindparam("ret_%d" % i, value=ReturningParam(dbtype))
- self.binds[bindparam.key] = bindparam
- binds.append(self.bindparam_string(self._truncate_bindparam(bindparam)))
-
- return 'RETURNING ' + ', '.join(columns) + " INTO " + ", ".join(binds)
-
-
-class OracleExecutionContext_zxjdbc(OracleExecutionContext):
-
- def pre_exec(self):
- if hasattr(self.compiled, 'returning_parameters'):
- # prepare a zxJDBC statement so we can grab its underlying
- # OraclePreparedStatement's getReturnResultSet later
- self.statement = self.cursor.prepare(self.statement)
-
- def get_result_proxy(self):
- if hasattr(self.compiled, 'returning_parameters'):
- rrs = None
- try:
- try:
- rrs = self.statement.__statement__.getReturnResultSet()
- rrs.next()
- except SQLException, sqle:
- msg = '%s [SQLCode: %d]' % (sqle.getMessage(), sqle.getErrorCode())
- if sqle.getSQLState() is not None:
- msg += ' [SQLState: %s]' % sqle.getSQLState()
- raise zxJDBC.Error(msg)
- else:
- row = tuple(self.cursor.datahandler.getPyObject(rrs, index, dbtype)
- for index, dbtype in self.compiled.returning_parameters)
- return ReturningResultProxy(self, row)
- finally:
- if rrs is not None:
- try:
- rrs.close()
- except SQLException:
- pass
- self.statement.close()
-
- return base.ResultProxy(self)
-
- def create_cursor(self):
- cursor = self._dbapi_connection.cursor()
- cursor.datahandler = self.dialect.DataHandler(cursor.datahandler)
- return cursor
-
-
-class ReturningResultProxy(base.FullyBufferedResultProxy):
-
- """ResultProxy backed by the RETURNING ResultSet results."""
-
- def __init__(self, context, returning_row):
- self._returning_row = returning_row
- super(ReturningResultProxy, self).__init__(context)
-
- def _cursor_description(self):
- ret = []
- for c in self.context.compiled.returning_cols:
- if hasattr(c, 'name'):
- ret.append((c.name, c.type))
- else:
- ret.append((c.anon_label, c.type))
- return ret
-
- def _buffer_rows(self):
- return [self._returning_row]
-
-
-class ReturningParam(object):
-
- """A bindparam value representing a RETURNING parameter.
-
- Specially handled by OracleReturningDataHandler.
- """
-
- def __init__(self, type):
- self.type = type
-
- def __eq__(self, other):
- if isinstance(other, ReturningParam):
- return self.type == other.type
- return NotImplemented
-
- def __ne__(self, other):
- if isinstance(other, ReturningParam):
- return self.type != other.type
- return NotImplemented
-
- def __repr__(self):
- kls = self.__class__
- return '<%s.%s object at 0x%x type=%s>' % (kls.__module__, kls.__name__, id(self),
- self.type)
-
-
-class OracleDialect_zxjdbc(ZxJDBCConnector, OracleDialect):
- jdbc_db_name = 'oracle'
- jdbc_driver_name = 'oracle.jdbc.OracleDriver'
-
- statement_compiler = OracleCompiler_zxjdbc
- execution_ctx_cls = OracleExecutionContext_zxjdbc
-
- colspecs = util.update_copy(
- OracleDialect.colspecs,
- {
- sqltypes.Date : _ZxJDBCDate,
- sqltypes.Numeric: _ZxJDBCNumeric
- }
- )
-
- def __init__(self, *args, **kwargs):
- super(OracleDialect_zxjdbc, self).__init__(*args, **kwargs)
- global SQLException, zxJDBC
- from java.sql import SQLException
- from com.ziclix.python.sql import zxJDBC
- from com.ziclix.python.sql.handler import OracleDataHandler
- class OracleReturningDataHandler(OracleDataHandler):
-
- """zxJDBC DataHandler that specially handles ReturningParam."""
-
- def setJDBCObject(self, statement, index, object, dbtype=None):
- if type(object) is ReturningParam:
- statement.registerReturnParameter(index, object.type)
- elif dbtype is None:
- OracleDataHandler.setJDBCObject(self, statement, index, object)
- else:
- OracleDataHandler.setJDBCObject(self, statement, index, object, dbtype)
- self.DataHandler = OracleReturningDataHandler
-
- def initialize(self, connection):
- super(OracleDialect_zxjdbc, self).initialize(connection)
- self.implicit_returning = connection.connection.driverversion >= '10.2'
-
- def _create_jdbc_url(self, url):
- return 'jdbc:oracle:thin:@%s:%s:%s' % (url.host, url.port or 1521, url.database)
-
- def _get_server_version_info(self, connection):
- version = re.search(r'Release ([\d\.]+)', connection.connection.dbversion).group(1)
- return tuple(int(x) for x in version.split('.'))
-
-dialect = OracleDialect_zxjdbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgres.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgres.py
deleted file mode 100755
index 48d1a8c3..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgres.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# dialects/postgres.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-# backwards compat with the old name
-from sqlalchemy.util import warn_deprecated
-
-warn_deprecated(
- "The SQLAlchemy PostgreSQL dialect has been renamed from 'postgres' to 'postgresql'. "
- "The new URL format is postgresql[+driver]://<user>:<pass>@<host>/<dbname>"
- )
-
-from sqlalchemy.dialects.postgresql import *
-from sqlalchemy.dialects.postgresql import base
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/__init__.py
deleted file mode 100755
index 481a7fb7..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# postgresql/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.postgresql import base, psycopg2, pg8000, pypostgresql, zxjdbc
-
-base.dialect = psycopg2.dialect
-
-from sqlalchemy.dialects.postgresql.base import \
- INTEGER, BIGINT, SMALLINT, VARCHAR, CHAR, TEXT, NUMERIC, FLOAT, REAL, INET, \
- CIDR, UUID, BIT, MACADDR, DOUBLE_PRECISION, TIMESTAMP, TIME,\
- DATE, BYTEA, BOOLEAN, INTERVAL, ARRAY, ENUM, dialect
-
-__all__ = (
-'INTEGER', 'BIGINT', 'SMALLINT', 'VARCHAR', 'CHAR', 'TEXT', 'NUMERIC', 'FLOAT', 'REAL', 'INET',
-'CIDR', 'UUID', 'BIT', 'MACADDR', 'DOUBLE_PRECISION', 'TIMESTAMP', 'TIME',
-'DATE', 'BYTEA', 'BOOLEAN', 'INTERVAL', 'ARRAY', 'ENUM', 'dialect'
-)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/base.py
deleted file mode 100755
index 3193cde9..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/base.py
+++ /dev/null
@@ -1,1449 +0,0 @@
-# postgresql/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the PostgreSQL database.
-
-For information on connecting using specific drivers, see the documentation
-section regarding that driver.
-
-Sequences/SERIAL
-----------------
-
-PostgreSQL supports sequences, and SQLAlchemy uses these as the default means
-of creating new primary key values for integer-based primary key columns. When
-creating tables, SQLAlchemy will issue the ``SERIAL`` datatype for
-integer-based primary key columns, which generates a sequence and server side
-default corresponding to the column.
-
-To specify a specific named sequence to be used for primary key generation,
-use the :func:`~sqlalchemy.schema.Sequence` construct::
-
- Table('sometable', metadata,
- Column('id', Integer, Sequence('some_id_seq'), primary_key=True)
- )
-
-When SQLAlchemy issues a single INSERT statement, to fulfill the contract of
-having the "last insert identifier" available, a RETURNING clause is added to
-the INSERT statement which specifies the primary key columns should be
-returned after the statement completes. The RETURNING functionality only takes
-place if Postgresql 8.2 or later is in use. As a fallback approach, the
-sequence, whether specified explicitly or implicitly via ``SERIAL``, is
-executed independently beforehand, the returned value to be used in the
-subsequent insert. Note that when an
-:func:`~sqlalchemy.sql.expression.insert()` construct is executed using
-"executemany" semantics, the "last inserted identifier" functionality does not
-apply; no RETURNING clause is emitted nor is the sequence pre-executed in this
-case.
-
-To force the usage of RETURNING by default off, specify the flag
-``implicit_returning=False`` to :func:`.create_engine`.
-
-Transaction Isolation Level
----------------------------
-
-:func:`.create_engine` accepts an ``isolation_level`` parameter which results
-in the command ``SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL
-<level>`` being invoked for every new connection. Valid values for this
-parameter are ``READ_COMMITTED``, ``READ_UNCOMMITTED``, ``REPEATABLE_READ``,
-and ``SERIALIZABLE``. Note that the psycopg2 dialect does *not* use this
-technique and uses psycopg2-specific APIs (see that dialect for details).
-
-INSERT/UPDATE...RETURNING
--------------------------
-
-The dialect supports PG 8.2's ``INSERT..RETURNING``, ``UPDATE..RETURNING`` and
-``DELETE..RETURNING`` syntaxes. ``INSERT..RETURNING`` is used by default
-for single-row INSERT statements in order to fetch newly generated
-primary key identifiers. To specify an explicit ``RETURNING`` clause,
-use the :meth:`._UpdateBase.returning` method on a per-statement basis::
-
- # INSERT..RETURNING
- result = table.insert().returning(table.c.col1, table.c.col2).\\
- values(name='foo')
- print result.fetchall()
-
- # UPDATE..RETURNING
- result = table.update().returning(table.c.col1, table.c.col2).\\
- where(table.c.name=='foo').values(name='bar')
- print result.fetchall()
-
- # DELETE..RETURNING
- result = table.delete().returning(table.c.col1, table.c.col2).\\
- where(table.c.name=='foo')
- print result.fetchall()
-
-Indexes
--------
-
-PostgreSQL supports partial indexes. To create them pass a postgresql_where
-option to the Index constructor::
-
- Index('my_index', my_table.c.id, postgresql_where=tbl.c.value > 10)
-
-"""
-
-import re
-
-from sqlalchemy import sql, schema, exc, util
-from sqlalchemy.engine import default, reflection
-from sqlalchemy.sql import compiler, expression, util as sql_util
-from sqlalchemy import types as sqltypes
-
-try:
- from uuid import UUID as _python_UUID
-except ImportError:
- _python_UUID = None
-
-from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, VARCHAR, \
- CHAR, TEXT, FLOAT, NUMERIC, \
- DATE, BOOLEAN, REAL
-
-RESERVED_WORDS = set(
- ["all", "analyse", "analyze", "and", "any", "array", "as", "asc",
- "asymmetric", "both", "case", "cast", "check", "collate", "column",
- "constraint", "create", "current_catalog", "current_date",
- "current_role", "current_time", "current_timestamp", "current_user",
- "default", "deferrable", "desc", "distinct", "do", "else", "end",
- "except", "false", "fetch", "for", "foreign", "from", "grant", "group",
- "having", "in", "initially", "intersect", "into", "leading", "limit",
- "localtime", "localtimestamp", "new", "not", "null", "off", "offset",
- "old", "on", "only", "or", "order", "placing", "primary", "references",
- "returning", "select", "session_user", "some", "symmetric", "table",
- "then", "to", "trailing", "true", "union", "unique", "user", "using",
- "variadic", "when", "where", "window", "with", "authorization",
- "between", "binary", "cross", "current_schema", "freeze", "full",
- "ilike", "inner", "is", "isnull", "join", "left", "like", "natural",
- "notnull", "outer", "over", "overlaps", "right", "similar", "verbose"
- ])
-
-_DECIMAL_TYPES = (1231, 1700)
-_FLOAT_TYPES = (700, 701, 1021, 1022)
-_INT_TYPES = (20, 21, 23, 26, 1005, 1007, 1016)
-
-class BYTEA(sqltypes.LargeBinary):
- __visit_name__ = 'BYTEA'
-
-class DOUBLE_PRECISION(sqltypes.Float):
- __visit_name__ = 'DOUBLE_PRECISION'
-
-class INET(sqltypes.TypeEngine):
- __visit_name__ = "INET"
-PGInet = INET
-
-class CIDR(sqltypes.TypeEngine):
- __visit_name__ = "CIDR"
-PGCidr = CIDR
-
-class MACADDR(sqltypes.TypeEngine):
- __visit_name__ = "MACADDR"
-PGMacAddr = MACADDR
-
-class TIMESTAMP(sqltypes.TIMESTAMP):
- def __init__(self, timezone=False, precision=None):
- super(TIMESTAMP, self).__init__(timezone=timezone)
- self.precision = precision
-
-
-class TIME(sqltypes.TIME):
- def __init__(self, timezone=False, precision=None):
- super(TIME, self).__init__(timezone=timezone)
- self.precision = precision
-
-class INTERVAL(sqltypes.TypeEngine):
- """Postgresql INTERVAL type.
-
- The INTERVAL type may not be supported on all DBAPIs.
- It is known to work on psycopg2 and not pg8000 or zxjdbc.
-
- """
- __visit_name__ = 'INTERVAL'
- def __init__(self, precision=None):
- self.precision = precision
-
- @classmethod
- def _adapt_from_generic_interval(cls, interval):
- return INTERVAL(precision=interval.second_precision)
-
- @property
- def _type_affinity(self):
- return sqltypes.Interval
-
-PGInterval = INTERVAL
-
-class BIT(sqltypes.TypeEngine):
- __visit_name__ = 'BIT'
- def __init__(self, length=None, varying=False):
- if not varying:
- # BIT without VARYING defaults to length 1
- self.length = length or 1
- else:
- # but BIT VARYING can be unlimited-length, so no default
- self.length = length
- self.varying = varying
-
-PGBit = BIT
-
-class UUID(sqltypes.TypeEngine):
- """Postgresql UUID type.
-
- Represents the UUID column type, interpreting
- data either as natively returned by the DBAPI
- or as Python uuid objects.
-
- The UUID type may not be supported on all DBAPIs.
- It is known to work on psycopg2 and not pg8000.
-
- """
- __visit_name__ = 'UUID'
-
- def __init__(self, as_uuid=False):
- """Construct a UUID type.
-
-
- :param as_uuid=False: if True, values will be interpreted
- as Python uuid objects, converting to/from string via the
- DBAPI.
-
- """
- if as_uuid and _python_UUID is None:
- raise NotImplementedError(
- "This version of Python does not support the native UUID type."
- )
- self.as_uuid = as_uuid
-
- def bind_processor(self, dialect):
- if self.as_uuid:
- def process(value):
- if value is not None:
- value = str(value)
- return value
- return process
- else:
- return None
-
- def result_processor(self, dialect, coltype):
- if self.as_uuid:
- def process(value):
- if value is not None:
- value = _python_UUID(value)
- return value
- return process
- else:
- return None
-
-PGUuid = UUID
-
-class ARRAY(sqltypes.MutableType, sqltypes.Concatenable, sqltypes.TypeEngine):
- """Postgresql ARRAY type.
-
- Represents values as Python lists.
-
- The ARRAY type may not be supported on all DBAPIs.
- It is known to work on psycopg2 and not pg8000.
-
-
- """
- __visit_name__ = 'ARRAY'
-
- def __init__(self, item_type, mutable=False, as_tuple=False):
- """Construct an ARRAY.
-
- E.g.::
-
- Column('myarray', ARRAY(Integer))
-
- Arguments are:
-
- :param item_type: The data type of items of this array. Note that
- dimensionality is irrelevant here, so multi-dimensional arrays like
- ``INTEGER[][]``, are constructed as ``ARRAY(Integer)``, not as
- ``ARRAY(ARRAY(Integer))`` or such. The type mapping figures out on
- the fly
-
- :param mutable=False: Specify whether lists passed to this
- class should be considered mutable - this enables
- "mutable types" mode in the ORM. Be sure to read the
- notes for :class:`.MutableType` regarding ORM
- performance implications (default changed from ``True`` in
- 0.7.0).
-
- .. note:: This functionality is now superseded by the
- ``sqlalchemy.ext.mutable`` extension described in
- :ref:`mutable_toplevel`.
-
- :param as_tuple=False: Specify whether return results
- should be converted to tuples from lists. DBAPIs such
- as psycopg2 return lists by default. When tuples are
- returned, the results are hashable. This flag can only
- be set to ``True`` when ``mutable`` is set to
- ``False``. (new in 0.6.5)
-
- """
- if isinstance(item_type, ARRAY):
- raise ValueError("Do not nest ARRAY types; ARRAY(basetype) "
- "handles multi-dimensional arrays of basetype")
- if isinstance(item_type, type):
- item_type = item_type()
- self.item_type = item_type
- self.mutable = mutable
- if mutable and as_tuple:
- raise exc.ArgumentError(
- "mutable must be set to False if as_tuple is True."
- )
- self.as_tuple = as_tuple
-
- def copy_value(self, value):
- if value is None:
- return None
- elif self.mutable:
- return list(value)
- else:
- return value
-
- def compare_values(self, x, y):
- return x == y
-
- def is_mutable(self):
- return self.mutable
-
- def bind_processor(self, dialect):
- item_proc = self.item_type.dialect_impl(dialect).bind_processor(dialect)
- if item_proc:
- def convert_item(item):
- if isinstance(item, (list, tuple)):
- return [convert_item(child) for child in item]
- else:
- return item_proc(item)
- else:
- def convert_item(item):
- if isinstance(item, (list, tuple)):
- return [convert_item(child) for child in item]
- else:
- return item
- def process(value):
- if value is None:
- return value
- return [convert_item(item) for item in value]
- return process
-
- def result_processor(self, dialect, coltype):
- item_proc = self.item_type.dialect_impl(dialect).result_processor(dialect, coltype)
- if item_proc:
- def convert_item(item):
- if isinstance(item, list):
- r = [convert_item(child) for child in item]
- if self.as_tuple:
- r = tuple(r)
- return r
- else:
- return item_proc(item)
- else:
- def convert_item(item):
- if isinstance(item, list):
- r = [convert_item(child) for child in item]
- if self.as_tuple:
- r = tuple(r)
- return r
- else:
- return item
- def process(value):
- if value is None:
- return value
- r = [convert_item(item) for item in value]
- if self.as_tuple:
- r = tuple(r)
- return r
- return process
-PGArray = ARRAY
-
-class ENUM(sqltypes.Enum):
-
- def create(self, bind=None, checkfirst=True):
- if not bind.dialect.supports_native_enum:
- return
-
- if not checkfirst or \
- not bind.dialect.has_type(bind, self.name, schema=self.schema):
- bind.execute(CreateEnumType(self))
-
- def drop(self, bind=None, checkfirst=True):
- if not bind.dialect.supports_native_enum:
- return
-
- if not checkfirst or \
- bind.dialect.has_type(bind, self.name, schema=self.schema):
- bind.execute(DropEnumType(self))
-
- def _on_table_create(self, event, target, bind, **kw):
- self.create(bind=bind, checkfirst=True)
-
- def _on_metadata_create(self, event, target, bind, **kw):
- if self.metadata is not None:
- self.create(bind=bind, checkfirst=True)
-
- def _on_metadata_drop(self, event, target, bind, **kw):
- self.drop(bind=bind, checkfirst=True)
-
-colspecs = {
- sqltypes.Interval:INTERVAL,
- sqltypes.Enum:ENUM,
-}
-
-ischema_names = {
- 'integer' : INTEGER,
- 'bigint' : BIGINT,
- 'smallint' : SMALLINT,
- 'character varying' : VARCHAR,
- 'character' : CHAR,
- '"char"' : sqltypes.String,
- 'name' : sqltypes.String,
- 'text' : TEXT,
- 'numeric' : NUMERIC,
- 'float' : FLOAT,
- 'real' : REAL,
- 'inet': INET,
- 'cidr': CIDR,
- 'uuid': UUID,
- 'bit': BIT,
- 'bit varying': BIT,
- 'macaddr': MACADDR,
- 'double precision' : DOUBLE_PRECISION,
- 'timestamp' : TIMESTAMP,
- 'timestamp with time zone' : TIMESTAMP,
- 'timestamp without time zone' : TIMESTAMP,
- 'time with time zone' : TIME,
- 'time without time zone' : TIME,
- 'date' : DATE,
- 'time': TIME,
- 'bytea' : BYTEA,
- 'boolean' : BOOLEAN,
- 'interval':INTERVAL,
- 'interval year to month':INTERVAL,
- 'interval day to second':INTERVAL,
-}
-
-
-
-class PGCompiler(compiler.SQLCompiler):
-
- def visit_match_op(self, binary, **kw):
- return "%s @@ to_tsquery(%s)" % (
- self.process(binary.left),
- self.process(binary.right))
-
- def visit_ilike_op(self, binary, **kw):
- escape = binary.modifiers.get("escape", None)
- return '%s ILIKE %s' % \
- (self.process(binary.left), self.process(binary.right)) \
- + (escape and
- (' ESCAPE ' + self.render_literal_value(escape, None))
- or '')
-
- def visit_notilike_op(self, binary, **kw):
- escape = binary.modifiers.get("escape", None)
- return '%s NOT ILIKE %s' % \
- (self.process(binary.left), self.process(binary.right)) \
- + (escape and
- (' ESCAPE ' + self.render_literal_value(escape, None))
- or '')
-
- def render_literal_value(self, value, type_):
- value = super(PGCompiler, self).render_literal_value(value, type_)
- # TODO: need to inspect "standard_conforming_strings"
- if self.dialect._backslash_escapes:
- value = value.replace('\\', '\\\\')
- return value
-
- def visit_sequence(self, seq):
- return "nextval('%s')" % self.preparer.format_sequence(seq)
-
- def limit_clause(self, select):
- text = ""
- if select._limit is not None:
- text += " \n LIMIT " + self.process(sql.literal(select._limit))
- if select._offset is not None:
- if select._limit is None:
- text += " \n LIMIT ALL"
- text += " OFFSET " + self.process(sql.literal(select._offset))
- return text
-
- def get_select_precolumns(self, select):
- if select._distinct is not False:
- if select._distinct is True:
- return "DISTINCT "
- elif isinstance(select._distinct, (list, tuple)):
- return "DISTINCT ON (" + ', '.join(
- [self.process(col) for col in select._distinct]
- )+ ") "
- else:
- return "DISTINCT ON (" + self.process(select._distinct) + ") "
- else:
- return ""
-
- def for_update_clause(self, select):
- if select.for_update == 'nowait':
- return " FOR UPDATE NOWAIT"
- else:
- return super(PGCompiler, self).for_update_clause(select)
-
- def returning_clause(self, stmt, returning_cols):
-
- columns = [
- self.process(
- self.label_select_column(None, c, asfrom=False),
- within_columns_clause=True,
- result_map=self.result_map)
- for c in expression._select_iterables(returning_cols)
- ]
-
- return 'RETURNING ' + ', '.join(columns)
-
- def visit_extract(self, extract, **kwargs):
- field = self.extract_map.get(extract.field, extract.field)
- if extract.expr.type:
- affinity = extract.expr.type._type_affinity
- else:
- affinity = None
-
- casts = {
- sqltypes.Date:'date',
- sqltypes.DateTime:'timestamp',
- sqltypes.Interval:'interval', sqltypes.Time:'time'
- }
- cast = casts.get(affinity, None)
- if isinstance(extract.expr, sql.ColumnElement) and cast is not None:
- expr = extract.expr.op('::')(sql.literal_column(cast))
- else:
- expr = extract.expr
- return "EXTRACT(%s FROM %s)" % (
- field, self.process(expr))
-
-class PGDDLCompiler(compiler.DDLCompiler):
- def get_column_specification(self, column, **kwargs):
- colspec = self.preparer.format_column(column)
- impl_type = column.type.dialect_impl(self.dialect)
- if column.primary_key and \
- column is column.table._autoincrement_column and \
- not isinstance(impl_type, sqltypes.SmallInteger) and \
- (
- column.default is None or
- (
- isinstance(column.default, schema.Sequence) and
- column.default.optional
- )
- ):
- if isinstance(impl_type, sqltypes.BigInteger):
- colspec += " BIGSERIAL"
- else:
- colspec += " SERIAL"
- else:
- colspec += " " + self.dialect.type_compiler.process(column.type)
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- if not column.nullable:
- colspec += " NOT NULL"
- return colspec
-
- def visit_create_enum_type(self, create):
- type_ = create.element
-
- return "CREATE TYPE %s AS ENUM (%s)" % (
- self.preparer.format_type(type_),
- ",".join("'%s'" % e for e in type_.enums)
- )
-
- def visit_drop_enum_type(self, drop):
- type_ = drop.element
-
- return "DROP TYPE %s" % (
- self.preparer.format_type(type_)
- )
-
- def visit_create_index(self, create):
- preparer = self.preparer
- index = create.element
- text = "CREATE "
- if index.unique:
- text += "UNIQUE "
- text += "INDEX %s ON %s (%s)" \
- % (preparer.quote(
- self._index_identifier(index.name), index.quote),
- preparer.format_table(index.table),
- ', '.join([preparer.format_column(c)
- for c in index.columns]))
-
- if "postgres_where" in index.kwargs:
- whereclause = index.kwargs['postgres_where']
- util.warn_deprecated(
- "The 'postgres_where' argument has been renamed "
- "to 'postgresql_where'.")
- elif 'postgresql_where' in index.kwargs:
- whereclause = index.kwargs['postgresql_where']
- else:
- whereclause = None
-
- if whereclause is not None:
- whereclause = sql_util.expression_as_ddl(whereclause)
- where_compiled = self.sql_compiler.process(whereclause)
- text += " WHERE " + where_compiled
- return text
-
-
-class PGTypeCompiler(compiler.GenericTypeCompiler):
- def visit_INET(self, type_):
- return "INET"
-
- def visit_CIDR(self, type_):
- return "CIDR"
-
- def visit_MACADDR(self, type_):
- return "MACADDR"
-
- def visit_FLOAT(self, type_):
- if not type_.precision:
- return "FLOAT"
- else:
- return "FLOAT(%(precision)s)" % {'precision': type_.precision}
-
- def visit_DOUBLE_PRECISION(self, type_):
- return "DOUBLE PRECISION"
-
- def visit_BIGINT(self, type_):
- return "BIGINT"
-
- def visit_datetime(self, type_):
- return self.visit_TIMESTAMP(type_)
-
- def visit_enum(self, type_):
- if not type_.native_enum or not self.dialect.supports_native_enum:
- return super(PGTypeCompiler, self).visit_enum(type_)
- else:
- return self.visit_ENUM(type_)
-
- def visit_ENUM(self, type_):
- return self.dialect.identifier_preparer.format_type(type_)
-
- def visit_TIMESTAMP(self, type_):
- return "TIMESTAMP%s %s" % (
- getattr(type_, 'precision', None) and "(%d)" %
- type_.precision or "",
- (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE"
- )
-
- def visit_TIME(self, type_):
- return "TIME%s %s" % (
- getattr(type_, 'precision', None) and "(%d)" %
- type_.precision or "",
- (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE"
- )
-
- def visit_INTERVAL(self, type_):
- if type_.precision is not None:
- return "INTERVAL(%d)" % type_.precision
- else:
- return "INTERVAL"
-
- def visit_BIT(self, type_):
- if type_.varying:
- compiled = "BIT VARYING"
- if type_.length is not None:
- compiled += "(%d)" % type_.length
- else:
- compiled = "BIT(%d)" % type_.length
- return compiled
-
- def visit_UUID(self, type_):
- return "UUID"
-
- def visit_large_binary(self, type_):
- return self.visit_BYTEA(type_)
-
- def visit_BYTEA(self, type_):
- return "BYTEA"
-
- def visit_ARRAY(self, type_):
- return self.process(type_.item_type) + '[]'
-
-
-class PGIdentifierPreparer(compiler.IdentifierPreparer):
-
- reserved_words = RESERVED_WORDS
-
- def _unquote_identifier(self, value):
- if value[0] == self.initial_quote:
- value = value[1:-1].\
- replace(self.escape_to_quote, self.escape_quote)
- return value
-
- def format_type(self, type_, use_schema=True):
- if not type_.name:
- raise exc.ArgumentError("Postgresql ENUM type requires a name.")
-
- name = self.quote(type_.name, type_.quote)
- if not self.omit_schema and use_schema and type_.schema is not None:
- name = self.quote_schema(type_.schema, type_.quote) + "." + name
- return name
-
-class PGInspector(reflection.Inspector):
-
- def __init__(self, conn):
- reflection.Inspector.__init__(self, conn)
-
- def get_table_oid(self, table_name, schema=None):
- """Return the oid from `table_name` and `schema`."""
-
- return self.dialect.get_table_oid(self.bind, table_name, schema,
- info_cache=self.info_cache)
-
-class CreateEnumType(schema._CreateDropBase):
- __visit_name__ = "create_enum_type"
-
-class DropEnumType(schema._CreateDropBase):
- __visit_name__ = "drop_enum_type"
-
-class PGExecutionContext(default.DefaultExecutionContext):
- def fire_sequence(self, seq, type_):
- return self._execute_scalar(("select nextval('%s')" % \
- self.dialect.identifier_preparer.format_sequence(seq)), type_)
-
- def get_insert_default(self, column):
- if column.primary_key and column is column.table._autoincrement_column:
- if column.server_default and column.server_default.has_argument:
-
- # pre-execute passive defaults on primary key columns
- return self._execute_scalar("select %s" %
- column.server_default.arg, column.type)
-
- elif (column.default is None or
- (column.default.is_sequence and
- column.default.optional)):
-
- # execute the sequence associated with a SERIAL primary
- # key column. for non-primary-key SERIAL, the ID just
- # generates server side.
-
- try:
- seq_name = column._postgresql_seq_name
- except AttributeError:
- tab = column.table.name
- col = column.name
- tab = tab[0:29 + max(0, (29 - len(col)))]
- col = col[0:29 + max(0, (29 - len(tab)))]
- column._postgresql_seq_name = seq_name = "%s_%s_seq" % (tab, col)
-
- sch = column.table.schema
- if sch is not None:
- exc = "select nextval('\"%s\".\"%s\"')" % \
- (sch, seq_name)
- else:
- exc = "select nextval('\"%s\"')" % \
- (seq_name, )
-
- return self._execute_scalar(exc, column.type)
-
- return super(PGExecutionContext, self).get_insert_default(column)
-
-class PGDialect(default.DefaultDialect):
- name = 'postgresql'
- supports_alter = True
- max_identifier_length = 63
- supports_sane_rowcount = True
-
- supports_native_enum = True
- supports_native_boolean = True
-
- supports_sequences = True
- sequences_optional = True
- preexecute_autoincrement_sequences = True
- postfetch_lastrowid = False
-
- supports_default_values = True
- supports_empty_insert = False
- default_paramstyle = 'pyformat'
- ischema_names = ischema_names
- colspecs = colspecs
-
- statement_compiler = PGCompiler
- ddl_compiler = PGDDLCompiler
- type_compiler = PGTypeCompiler
- preparer = PGIdentifierPreparer
- execution_ctx_cls = PGExecutionContext
- inspector = PGInspector
- isolation_level = None
-
- # TODO: need to inspect "standard_conforming_strings"
- _backslash_escapes = True
-
- def __init__(self, isolation_level=None, **kwargs):
- default.DefaultDialect.__init__(self, **kwargs)
- self.isolation_level = isolation_level
-
- def initialize(self, connection):
- super(PGDialect, self).initialize(connection)
- self.implicit_returning = self.server_version_info > (8, 2) and \
- self.__dict__.get('implicit_returning', True)
- self.supports_native_enum = self.server_version_info >= (8, 3)
- if not self.supports_native_enum:
- self.colspecs = self.colspecs.copy()
- # pop base Enum type
- self.colspecs.pop(sqltypes.Enum, None)
- # psycopg2, others may have placed ENUM here as well
- self.colspecs.pop(ENUM, None)
-
- def on_connect(self):
- if self.isolation_level is not None:
- def connect(conn):
- self.set_isolation_level(conn, self.isolation_level)
- return connect
- else:
- return None
-
- _isolation_lookup = set(['SERIALIZABLE',
- 'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ'])
-
- def set_isolation_level(self, connection, level):
- level = level.replace('_', ' ')
- if level not in self._isolation_lookup:
- raise exc.ArgumentError(
- "Invalid value '%s' for isolation_level. "
- "Valid isolation levels for %s are %s" %
- (level, self.name, ", ".join(self._isolation_lookup))
- )
- cursor = connection.cursor()
- cursor.execute(
- "SET SESSION CHARACTERISTICS AS TRANSACTION "
- "ISOLATION LEVEL %s" % level)
- cursor.execute("COMMIT")
- cursor.close()
-
- def get_isolation_level(self, connection):
- cursor = connection.cursor()
- cursor.execute('show transaction isolation level')
- val = cursor.fetchone()[0]
- cursor.close()
- return val.upper()
-
- def do_begin_twophase(self, connection, xid):
- self.do_begin(connection.connection)
-
- def do_prepare_twophase(self, connection, xid):
- connection.execute("PREPARE TRANSACTION '%s'" % xid)
-
- def do_rollback_twophase(self, connection, xid,
- is_prepared=True, recover=False):
- if is_prepared:
- if recover:
- #FIXME: ugly hack to get out of transaction
- # context when commiting recoverable transactions
- # Must find out a way how to make the dbapi not
- # open a transaction.
- connection.execute("ROLLBACK")
- connection.execute("ROLLBACK PREPARED '%s'" % xid)
- connection.execute("BEGIN")
- self.do_rollback(connection.connection)
- else:
- self.do_rollback(connection.connection)
-
- def do_commit_twophase(self, connection, xid,
- is_prepared=True, recover=False):
- if is_prepared:
- if recover:
- connection.execute("ROLLBACK")
- connection.execute("COMMIT PREPARED '%s'" % xid)
- connection.execute("BEGIN")
- self.do_rollback(connection.connection)
- else:
- self.do_commit(connection.connection)
-
- def do_recover_twophase(self, connection):
- resultset = connection.execute(
- sql.text("SELECT gid FROM pg_prepared_xacts"))
- return [row[0] for row in resultset]
-
- def _get_default_schema_name(self, connection):
- return connection.scalar("select current_schema()")
-
- def has_table(self, connection, table_name, schema=None):
- # seems like case gets folded in pg_class...
- if schema is None:
- cursor = connection.execute(
- sql.text(
- "select relname from pg_class c join pg_namespace n on "
- "n.oid=c.relnamespace where n.nspname=current_schema() and "
- "lower(relname)=:name",
- bindparams=[
- sql.bindparam('name', unicode(table_name.lower()),
- type_=sqltypes.Unicode)]
- )
- )
- else:
- cursor = connection.execute(
- sql.text(
- "select relname from pg_class c join pg_namespace n on "
- "n.oid=c.relnamespace where n.nspname=:schema and "
- "lower(relname)=:name",
- bindparams=[
- sql.bindparam('name',
- unicode(table_name.lower()), type_=sqltypes.Unicode),
- sql.bindparam('schema',
- unicode(schema), type_=sqltypes.Unicode)]
- )
- )
- return bool(cursor.first())
-
- def has_sequence(self, connection, sequence_name, schema=None):
- if schema is None:
- cursor = connection.execute(
- sql.text(
- "SELECT relname FROM pg_class c join pg_namespace n on "
- "n.oid=c.relnamespace where relkind='S' and "
- "n.nspname=current_schema() "
- "and lower(relname)=:name",
- bindparams=[
- sql.bindparam('name', unicode(sequence_name.lower()),
- type_=sqltypes.Unicode)
- ]
- )
- )
- else:
- cursor = connection.execute(
- sql.text(
- "SELECT relname FROM pg_class c join pg_namespace n on "
- "n.oid=c.relnamespace where relkind='S' and "
- "n.nspname=:schema and lower(relname)=:name",
- bindparams=[
- sql.bindparam('name', unicode(sequence_name.lower()),
- type_=sqltypes.Unicode),
- sql.bindparam('schema',
- unicode(schema), type_=sqltypes.Unicode)
- ]
- )
- )
-
- return bool(cursor.first())
-
- def has_type(self, connection, type_name, schema=None):
- bindparams = [
- sql.bindparam('typname',
- unicode(type_name), type_=sqltypes.Unicode),
- sql.bindparam('nspname',
- unicode(schema), type_=sqltypes.Unicode),
- ]
- if schema is not None:
- query = """
- SELECT EXISTS (
- SELECT * FROM pg_catalog.pg_type t, pg_catalog.pg_namespace n
- WHERE t.typnamespace = n.oid
- AND t.typname = :typname
- AND n.nspname = :nspname
- )
- """
- else:
- query = """
- SELECT EXISTS (
- SELECT * FROM pg_catalog.pg_type t
- WHERE t.typname = :typname
- AND pg_type_is_visible(t.oid)
- )
- """
- cursor = connection.execute(sql.text(query, bindparams=bindparams))
- return bool(cursor.scalar())
-
- def _get_server_version_info(self, connection):
- v = connection.execute("select version()").scalar()
- m = re.match('PostgreSQL (\d+)\.(\d+)(?:\.(\d+))?(?:devel)?', v)
- if not m:
- raise AssertionError(
- "Could not determine version from string '%s'" % v)
- return tuple([int(x) for x in m.group(1, 2, 3) if x is not None])
-
- @reflection.cache
- def get_table_oid(self, connection, table_name, schema=None, **kw):
- """Fetch the oid for schema.table_name.
-
- Several reflection methods require the table oid. The idea for using
- this method is that it can be fetched one time and cached for
- subsequent calls.
-
- """
- table_oid = None
- if schema is not None:
- schema_where_clause = "n.nspname = :schema"
- else:
- schema_where_clause = "pg_catalog.pg_table_is_visible(c.oid)"
- query = """
- SELECT c.oid
- FROM pg_catalog.pg_class c
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
- WHERE (%s)
- AND c.relname = :table_name AND c.relkind in ('r','v')
- """ % schema_where_clause
- # Since we're binding to unicode, table_name and schema_name must be
- # unicode.
- table_name = unicode(table_name)
- if schema is not None:
- schema = unicode(schema)
- s = sql.text(query, bindparams=[
- sql.bindparam('table_name', type_=sqltypes.Unicode),
- sql.bindparam('schema', type_=sqltypes.Unicode)
- ],
- typemap={'oid':sqltypes.Integer}
- )
- c = connection.execute(s, table_name=table_name, schema=schema)
- table_oid = c.scalar()
- if table_oid is None:
- raise exc.NoSuchTableError(table_name)
- return table_oid
-
- @reflection.cache
- def get_schema_names(self, connection, **kw):
- s = """
- SELECT nspname
- FROM pg_namespace
- ORDER BY nspname
- """
- rp = connection.execute(s)
- # what about system tables?
- # Py3K
- #schema_names = [row[0] for row in rp \
- # if not row[0].startswith('pg_')]
- # Py2K
- schema_names = [row[0].decode(self.encoding) for row in rp \
- if not row[0].startswith('pg_')]
- # end Py2K
- return schema_names
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- if schema is not None:
- current_schema = schema
- else:
- current_schema = self.default_schema_name
-
- result = connection.execute(
- sql.text(u"SELECT relname FROM pg_class c "
- "WHERE relkind = 'r' "
- "AND '%s' = (select nspname from pg_namespace n "
- "where n.oid = c.relnamespace) " %
- current_schema,
- typemap = {'relname':sqltypes.Unicode}
- )
- )
- return [row[0] for row in result]
-
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- if schema is not None:
- current_schema = schema
- else:
- current_schema = self.default_schema_name
- s = """
- SELECT relname
- FROM pg_class c
- WHERE relkind = 'v'
- AND '%(schema)s' = (select nspname from pg_namespace n
- where n.oid = c.relnamespace)
- """ % dict(schema=current_schema)
- # Py3K
- #view_names = [row[0] for row in connection.execute(s)]
- # Py2K
- view_names = [row[0].decode(self.encoding)
- for row in connection.execute(s)]
- # end Py2K
- return view_names
-
- @reflection.cache
- def get_view_definition(self, connection, view_name, schema=None, **kw):
- if schema is not None:
- current_schema = schema
- else:
- current_schema = self.default_schema_name
- s = """
- SELECT definition FROM pg_views
- WHERE schemaname = :schema
- AND viewname = :view_name
- """
- rp = connection.execute(sql.text(s),
- view_name=view_name, schema=current_schema)
- if rp:
- # Py3K
- #view_def = rp.scalar()
- # Py2K
- view_def = rp.scalar().decode(self.encoding)
- # end Py2K
- return view_def
-
- @reflection.cache
- def get_columns(self, connection, table_name, schema=None, **kw):
-
- table_oid = self.get_table_oid(connection, table_name, schema,
- info_cache=kw.get('info_cache'))
- SQL_COLS = """
- SELECT a.attname,
- pg_catalog.format_type(a.atttypid, a.atttypmod),
- (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid)
- for 128)
- FROM pg_catalog.pg_attrdef d
- WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum
- AND a.atthasdef)
- AS DEFAULT,
- a.attnotnull, a.attnum, a.attrelid as table_oid
- FROM pg_catalog.pg_attribute a
- WHERE a.attrelid = :table_oid
- AND a.attnum > 0 AND NOT a.attisdropped
- ORDER BY a.attnum
- """
- s = sql.text(SQL_COLS,
- bindparams=[sql.bindparam('table_oid', type_=sqltypes.Integer)],
- typemap={'attname':sqltypes.Unicode, 'default':sqltypes.Unicode}
- )
- c = connection.execute(s, table_oid=table_oid)
- rows = c.fetchall()
- domains = self._load_domains(connection)
- enums = self._load_enums(connection)
-
- # format columns
- columns = []
- for name, format_type, default, notnull, attnum, table_oid in rows:
- ## strip (5) from character varying(5), timestamp(5)
- # with time zone, etc
- attype = re.sub(r'\([\d,]+\)', '', format_type)
-
- # strip '[]' from integer[], etc.
- attype = re.sub(r'\[\]', '', attype)
-
- nullable = not notnull
- is_array = format_type.endswith('[]')
- charlen = re.search('\(([\d,]+)\)', format_type)
- if charlen:
- charlen = charlen.group(1)
- kwargs = {}
- args = None
-
- if attype == 'numeric':
- if charlen:
- prec, scale = charlen.split(',')
- args = (int(prec), int(scale))
- else:
- args = ()
- elif attype == 'double precision':
- args = (53, )
- elif attype == 'integer':
- args = ()
- elif attype in ('timestamp with time zone',
- 'time with time zone'):
- kwargs['timezone'] = True
- if charlen:
- kwargs['precision'] = int(charlen)
- args = ()
- elif attype in ('timestamp without time zone',
- 'time without time zone', 'time'):
- kwargs['timezone'] = False
- if charlen:
- kwargs['precision'] = int(charlen)
- args = ()
- elif attype == 'bit varying':
- kwargs['varying'] = True
- if charlen:
- args = (int(charlen),)
- else:
- args = ()
- elif attype in ('interval','interval year to month',
- 'interval day to second'):
- if charlen:
- kwargs['precision'] = int(charlen)
- args = ()
- elif charlen:
- args = (int(charlen),)
- else:
- args = ()
-
- while True:
- if attype in self.ischema_names:
- coltype = self.ischema_names[attype]
- break
- elif attype in enums:
- enum = enums[attype]
- coltype = ENUM
- if "." in attype:
- kwargs['schema'], kwargs['name'] = attype.split('.')
- else:
- kwargs['name'] = attype
- args = tuple(enum['labels'])
- break
- elif attype in domains:
- domain = domains[attype]
- attype = domain['attype']
- # A table can't override whether the domain is nullable.
- nullable = domain['nullable']
- if domain['default'] and not default:
- # It can, however, override the default
- # value, but can't set it to null.
- default = domain['default']
- continue
- else:
- coltype = None
- break
-
- if coltype:
- coltype = coltype(*args, **kwargs)
- if is_array:
- coltype = ARRAY(coltype)
- else:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (attype, name))
- coltype = sqltypes.NULLTYPE
- # adjust the default value
- autoincrement = False
- if default is not None:
- match = re.search(r"""(nextval\(')([^']+)('.*$)""", default)
- if match is not None:
- autoincrement = True
- # the default is related to a Sequence
- sch = schema
- if '.' not in match.group(2) and sch is not None:
- # unconditionally quote the schema name. this could
- # later be enhanced to obey quoting rules /
- # "quote schema"
- default = match.group(1) + \
- ('"%s"' % sch) + '.' + \
- match.group(2) + match.group(3)
-
- column_info = dict(name=name, type=coltype, nullable=nullable,
- default=default, autoincrement=autoincrement)
- columns.append(column_info)
- return columns
-
- @reflection.cache
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- table_oid = self.get_table_oid(connection, table_name, schema,
- info_cache=kw.get('info_cache'))
- PK_SQL = """
- SELECT attname FROM pg_attribute
- WHERE attrelid = (
- SELECT indexrelid FROM pg_index i
- WHERE i.indrelid = :table_oid
- AND i.indisprimary = 't')
- ORDER BY attnum
- """
- t = sql.text(PK_SQL, typemap={'attname':sqltypes.Unicode})
- c = connection.execute(t, table_oid=table_oid)
- primary_keys = [r[0] for r in c.fetchall()]
- return primary_keys
-
- @reflection.cache
- def get_pk_constraint(self, connection, table_name, schema=None, **kw):
- cols = self.get_primary_keys(connection, table_name,
- schema=schema, **kw)
-
- table_oid = self.get_table_oid(connection, table_name, schema,
- info_cache=kw.get('info_cache'))
-
- PK_CONS_SQL = """
- SELECT conname
- FROM pg_catalog.pg_constraint r
- WHERE r.conrelid = :table_oid AND r.contype = 'p'
- ORDER BY 1
- """
- t = sql.text(PK_CONS_SQL, typemap={'conname':sqltypes.Unicode})
- c = connection.execute(t, table_oid=table_oid)
- name = c.scalar()
- return {
- 'constrained_columns':cols,
- 'name':name
- }
-
- @reflection.cache
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
- preparer = self.identifier_preparer
- table_oid = self.get_table_oid(connection, table_name, schema,
- info_cache=kw.get('info_cache'))
- FK_SQL = """
- SELECT conname, pg_catalog.pg_get_constraintdef(oid, true) as condef
- FROM pg_catalog.pg_constraint r
- WHERE r.conrelid = :table AND r.contype = 'f'
- ORDER BY 1
- """
-
- t = sql.text(FK_SQL, typemap={
- 'conname':sqltypes.Unicode,
- 'condef':sqltypes.Unicode})
- c = connection.execute(t, table=table_oid)
- fkeys = []
- for conname, condef in c.fetchall():
- m = re.search('FOREIGN KEY \((.*?)\) REFERENCES '
- '(?:(.*?)\.)?(.*?)\((.*?)\)', condef).groups()
- constrained_columns, referred_schema, \
- referred_table, referred_columns = m
- constrained_columns = [preparer._unquote_identifier(x)
- for x in re.split(r'\s*,\s*', constrained_columns)]
- if referred_schema:
- referred_schema =\
- preparer._unquote_identifier(referred_schema)
- elif schema is not None and schema == self.default_schema_name:
- # no schema (i.e. its the default schema), and the table we're
- # reflecting has the default schema explicit, then use that.
- # i.e. try to use the user's conventions
- referred_schema = schema
- referred_table = preparer._unquote_identifier(referred_table)
- referred_columns = [preparer._unquote_identifier(x)
- for x in re.split(r'\s*,\s', referred_columns)]
- fkey_d = {
- 'name' : conname,
- 'constrained_columns' : constrained_columns,
- 'referred_schema' : referred_schema,
- 'referred_table' : referred_table,
- 'referred_columns' : referred_columns
- }
- fkeys.append(fkey_d)
- return fkeys
-
- @reflection.cache
- def get_indexes(self, connection, table_name, schema, **kw):
- table_oid = self.get_table_oid(connection, table_name, schema,
- info_cache=kw.get('info_cache'))
-
- IDX_SQL = """
- SELECT
- i.relname as relname,
- ix.indisunique, ix.indexprs, ix.indpred,
- a.attname
- FROM
- pg_class t
- join pg_index ix on t.oid = ix.indrelid
- join pg_class i on i.oid=ix.indexrelid
- left outer join
- pg_attribute a
- on t.oid=a.attrelid and a.attnum=ANY(ix.indkey)
- WHERE
- t.relkind = 'r'
- and t.oid = :table_oid
- and ix.indisprimary = 'f'
- ORDER BY
- t.relname,
- i.relname
- """
-
- t = sql.text(IDX_SQL, typemap={'attname':sqltypes.Unicode})
- c = connection.execute(t, table_oid=table_oid)
-
- index_names = {}
- indexes = []
- sv_idx_name = None
- for row in c.fetchall():
- idx_name, unique, expr, prd, col = row
- if expr:
- if idx_name != sv_idx_name:
- util.warn(
- "Skipped unsupported reflection of "
- "expression-based index %s"
- % idx_name)
- sv_idx_name = idx_name
- continue
- if prd and not idx_name == sv_idx_name:
- util.warn(
- "Predicate of partial index %s ignored during reflection"
- % idx_name)
- sv_idx_name = idx_name
- if idx_name in index_names:
- index_d = index_names[idx_name]
- else:
- index_d = {'column_names':[]}
- indexes.append(index_d)
- index_names[idx_name] = index_d
- index_d['name'] = idx_name
- if col is not None:
- index_d['column_names'].append(col)
- index_d['unique'] = unique
- return indexes
-
- def _load_enums(self, connection):
- if not self.supports_native_enum:
- return {}
-
- ## Load data types for enums:
- SQL_ENUMS = """
- SELECT t.typname as "name",
- -- no enum defaults in 8.4 at least
- -- t.typdefault as "default",
- pg_catalog.pg_type_is_visible(t.oid) as "visible",
- n.nspname as "schema",
- e.enumlabel as "label"
- FROM pg_catalog.pg_type t
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
- LEFT JOIN pg_catalog.pg_constraint r ON t.oid = r.contypid
- LEFT JOIN pg_catalog.pg_enum e ON t.oid = e.enumtypid
- WHERE t.typtype = 'e'
- ORDER BY "name", e.oid -- e.oid gives us label order
- """
-
- s = sql.text(SQL_ENUMS, typemap={
- 'attname':sqltypes.Unicode,
- 'label':sqltypes.Unicode})
- c = connection.execute(s)
-
- enums = {}
- for enum in c.fetchall():
- if enum['visible']:
- # 'visible' just means whether or not the enum is in a
- # schema that's on the search path -- or not overriden by
- # a schema with higher presedence. If it's not visible,
- # it will be prefixed with the schema-name when it's used.
- name = enum['name']
- else:
- name = "%s.%s" % (enum['schema'], enum['name'])
-
- if name in enums:
- enums[name]['labels'].append(enum['label'])
- else:
- enums[name] = {
- 'labels': [enum['label']],
- }
-
- return enums
-
- def _load_domains(self, connection):
- ## Load data types for domains:
- SQL_DOMAINS = """
- SELECT t.typname as "name",
- pg_catalog.format_type(t.typbasetype, t.typtypmod) as "attype",
- not t.typnotnull as "nullable",
- t.typdefault as "default",
- pg_catalog.pg_type_is_visible(t.oid) as "visible",
- n.nspname as "schema"
- FROM pg_catalog.pg_type t
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
- LEFT JOIN pg_catalog.pg_constraint r ON t.oid = r.contypid
- WHERE t.typtype = 'd'
- """
-
- s = sql.text(SQL_DOMAINS, typemap={'attname':sqltypes.Unicode})
- c = connection.execute(s)
-
- domains = {}
- for domain in c.fetchall():
- ## strip (30) from character varying(30)
- attype = re.search('([^\(]+)', domain['attype']).group(1)
- if domain['visible']:
- # 'visible' just means whether or not the domain is in a
- # schema that's on the search path -- or not overriden by
- # a schema with higher presedence. If it's not visible,
- # it will be prefixed with the schema-name when it's used.
- name = domain['name']
- else:
- name = "%s.%s" % (domain['schema'], domain['name'])
-
- domains[name] = {
- 'attype':attype,
- 'nullable': domain['nullable'],
- 'default': domain['default']
- }
-
- return domains
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pg8000.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pg8000.py
deleted file mode 100755
index ac927edb..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pg8000.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# postgresql/pg8000.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the PostgreSQL database via the pg8000 driver.
-
-Connecting
-----------
-
-URLs are of the form
-``postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]``.
-
-Unicode
--------
-
-pg8000 requires that the postgresql client encoding be
-configured in the postgresql.conf file in order to use encodings
-other than ascii. Set this value to the same value as the
-"encoding" parameter on create_engine(), usually "utf-8".
-
-Interval
---------
-
-Passing data from/to the Interval type is not supported as of
-yet.
-
-"""
-from sqlalchemy import util, exc
-from sqlalchemy.util.compat import decimal
-from sqlalchemy import processors
-from sqlalchemy import types as sqltypes
-from sqlalchemy.dialects.postgresql.base import PGDialect, \
- PGCompiler, PGIdentifierPreparer, PGExecutionContext,\
- _DECIMAL_TYPES, _FLOAT_TYPES, _INT_TYPES
-
-class _PGNumeric(sqltypes.Numeric):
- def result_processor(self, dialect, coltype):
- if self.asdecimal:
- if coltype in _FLOAT_TYPES:
- return processors.to_decimal_processor_factory(decimal.Decimal)
- elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
- # pg8000 returns Decimal natively for 1700
- return None
- else:
- raise exc.InvalidRequestError(
- "Unknown PG numeric type: %d" % coltype)
- else:
- if coltype in _FLOAT_TYPES:
- # pg8000 returns float natively for 701
- return None
- elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
- return processors.to_float
- else:
- raise exc.InvalidRequestError(
- "Unknown PG numeric type: %d" % coltype)
-
-
-class _PGNumericNoBind(_PGNumeric):
- def bind_processor(self, dialect):
- return None
-
-class PGExecutionContext_pg8000(PGExecutionContext):
- pass
-
-
-class PGCompiler_pg8000(PGCompiler):
- def visit_mod(self, binary, **kw):
- return self.process(binary.left) + " %% " + self.process(binary.right)
-
- def post_process_text(self, text):
- if '%%' in text:
- util.warn("The SQLAlchemy postgresql dialect now automatically escapes '%' in text() "
- "expressions to '%%'.")
- return text.replace('%', '%%')
-
-
-class PGIdentifierPreparer_pg8000(PGIdentifierPreparer):
- def _escape_identifier(self, value):
- value = value.replace(self.escape_quote, self.escape_to_quote)
- return value.replace('%', '%%')
-
-
-class PGDialect_pg8000(PGDialect):
- driver = 'pg8000'
-
- supports_unicode_statements = True
-
- supports_unicode_binds = True
-
- default_paramstyle = 'format'
- supports_sane_multi_rowcount = False
- execution_ctx_cls = PGExecutionContext_pg8000
- statement_compiler = PGCompiler_pg8000
- preparer = PGIdentifierPreparer_pg8000
- description_encoding = 'use_encoding'
-
- colspecs = util.update_copy(
- PGDialect.colspecs,
- {
- sqltypes.Numeric : _PGNumericNoBind,
- sqltypes.Float : _PGNumeric
- }
- )
-
- @classmethod
- def dbapi(cls):
- return __import__('pg8000').dbapi
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- if 'port' in opts:
- opts['port'] = int(opts['port'])
- opts.update(url.query)
- return ([], opts)
-
- def is_disconnect(self, e, connection, cursor):
- return "connection is closed" in str(e)
-
-dialect = PGDialect_pg8000
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/psycopg2.py
deleted file mode 100755
index 2a3b4297..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/psycopg2.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# postgresql/psycopg2.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the PostgreSQL database via the psycopg2 driver.
-
-Driver
-------
-
-The psycopg2 driver is available at http://pypi.python.org/pypi/psycopg2/ .
-The dialect has several behaviors which are specifically tailored towards compatibility
-with this module.
-
-Note that psycopg1 is **not** supported.
-
-Connecting
-----------
-
-URLs are of the form
-``postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]``.
-
-psycopg2-specific keyword arguments which are accepted by
-:func:`.create_engine()` are:
-
-* *server_side_cursors* - Enable the usage of "server side cursors" for SQL
- statements which support this feature. What this essentially means from a
- psycopg2 point of view is that the cursor is created using a name, e.g.
- ``connection.cursor('some name')``, which has the effect that result rows are
- not immediately pre-fetched and buffered after statement execution, but are
- instead left on the server and only retrieved as needed. SQLAlchemy's
- :class:`~sqlalchemy.engine.base.ResultProxy` uses special row-buffering
- behavior when this feature is enabled, such that groups of 100 rows at a
- time are fetched over the wire to reduce conversational overhead.
- Note that the ``stream_results=True`` execution option is a more targeted
- way of enabling this mode on a per-execution basis.
-* *use_native_unicode* - Enable the usage of Psycopg2 "native unicode" mode
- per connection. True by default.
-
-Per-Statement/Connection Execution Options
--------------------------------------------
-
-The following DBAPI-specific options are respected when used with
-:meth:`.Connection.execution_options`, :meth:`.Executable.execution_options`,
-:meth:`.Query.execution_options`, in addition to those not specific to DBAPIs:
-
-* isolation_level - Set the transaction isolation level for the lifespan of a
- :class:`.Connection` (can only be set on a connection, not a statement or query).
- This includes the options ``SERIALIZABLE``, ``READ COMMITTED``,
- ``READ UNCOMMITTED`` and ``REPEATABLE READ``.
-* stream_results - Enable or disable usage of server side cursors.
- If ``None`` or not set, the ``server_side_cursors`` option of the :class:`.Engine` is used.
-
-Unicode
--------
-
-By default, the psycopg2 driver uses the ``psycopg2.extensions.UNICODE``
-extension, such that the DBAPI receives and returns all strings as Python
-Unicode objects directly - SQLAlchemy passes these values through without
-change. Note that this setting requires that the PG client encoding be set to
-one which can accomodate the kind of character data being passed - typically
-``utf-8``. If the Postgresql database is configured for ``SQL_ASCII``
-encoding, which is often the default for PG installations, it may be necessary
-for non-ascii strings to be encoded into a specific encoding before being
-passed to the DBAPI. If changing the database's client encoding setting is not
-an option, specify ``use_native_unicode=False`` as a keyword argument to
-``create_engine()``, and take note of the ``encoding`` setting as well, which
-also defaults to ``utf-8``. Note that disabling "native unicode" mode has a
-slight performance penalty, as SQLAlchemy now must translate unicode strings
-to/from an encoding such as utf-8, a task that is handled more efficiently
-within the Psycopg2 driver natively.
-
-Transactions
-------------
-
-The psycopg2 dialect fully supports SAVEPOINT and two-phase commit operations.
-
-Transaction Isolation Level
----------------------------
-
-The ``isolation_level`` parameter of :func:`.create_engine` here makes use
-psycopg2's ``set_isolation_level()`` connection method, rather than
-issuing a ``SET SESSION CHARACTERISTICS`` command. This because psycopg2
-resets the isolation level on each new transaction, and needs to know
-at the API level what level should be used.
-
-NOTICE logging
----------------
-
-The psycopg2 dialect will log Postgresql NOTICE messages via the
-``sqlalchemy.dialects.postgresql`` logger::
-
- import logging
- logging.getLogger('sqlalchemy.dialects.postgresql').setLevel(logging.INFO)
-
-
-"""
-
-import random
-import re
-import logging
-
-from sqlalchemy import util, exc
-from sqlalchemy.util.compat import decimal
-from sqlalchemy import processors
-from sqlalchemy.engine import base
-from sqlalchemy.sql import expression
-from sqlalchemy import types as sqltypes
-from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler, \
- PGIdentifierPreparer, PGExecutionContext, \
- ENUM, ARRAY, _DECIMAL_TYPES, _FLOAT_TYPES,\
- _INT_TYPES
-
-
-logger = logging.getLogger('sqlalchemy.dialects.postgresql')
-
-
-class _PGNumeric(sqltypes.Numeric):
- def bind_processor(self, dialect):
- return None
-
- def result_processor(self, dialect, coltype):
- if self.asdecimal:
- if coltype in _FLOAT_TYPES:
- return processors.to_decimal_processor_factory(decimal.Decimal)
- elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
- # pg8000 returns Decimal natively for 1700
- return None
- else:
- raise exc.InvalidRequestError(
- "Unknown PG numeric type: %d" % coltype)
- else:
- if coltype in _FLOAT_TYPES:
- # pg8000 returns float natively for 701
- return None
- elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
- return processors.to_float
- else:
- raise exc.InvalidRequestError(
- "Unknown PG numeric type: %d" % coltype)
-
-class _PGEnum(ENUM):
- def __init__(self, *arg, **kw):
- super(_PGEnum, self).__init__(*arg, **kw)
- # Py2K
- if self.convert_unicode:
- self.convert_unicode = "force"
- # end Py2K
-
-class _PGArray(ARRAY):
- def __init__(self, *arg, **kw):
- super(_PGArray, self).__init__(*arg, **kw)
- # Py2K
- # FIXME: this check won't work for setups that
- # have convert_unicode only on their create_engine().
- if isinstance(self.item_type, sqltypes.String) and \
- self.item_type.convert_unicode:
- self.item_type.convert_unicode = "force"
- # end Py2K
-
-# When we're handed literal SQL, ensure it's a SELECT-query. Since
-# 8.3, combining cursors and "FOR UPDATE" has been fine.
-SERVER_SIDE_CURSOR_RE = re.compile(
- r'\s*SELECT',
- re.I | re.UNICODE)
-
-class PGExecutionContext_psycopg2(PGExecutionContext):
- def create_cursor(self):
- # TODO: coverage for server side cursors + select.for_update()
-
- if self.dialect.server_side_cursors:
- is_server_side = \
- self.execution_options.get('stream_results', True) and (
- (self.compiled and isinstance(self.compiled.statement, expression.Selectable) \
- or \
- (
- (not self.compiled or
- isinstance(self.compiled.statement, expression._TextClause))
- and self.statement and SERVER_SIDE_CURSOR_RE.match(self.statement))
- )
- )
- else:
- is_server_side = self.execution_options.get('stream_results', False)
-
- self.__is_server_side = is_server_side
- if is_server_side:
- # use server-side cursors:
- # http://lists.initd.org/pipermail/psycopg/2007-January/005251.html
- ident = "c_%s_%s" % (hex(id(self))[2:], hex(random.randint(0, 65535))[2:])
- return self._dbapi_connection.cursor(ident)
- else:
- return self._dbapi_connection.cursor()
-
- def get_result_proxy(self):
- # TODO: ouch
- if logger.isEnabledFor(logging.INFO):
- self._log_notices(self.cursor)
-
- if self.__is_server_side:
- return base.BufferedRowResultProxy(self)
- else:
- return base.ResultProxy(self)
-
- def _log_notices(self, cursor):
- for notice in cursor.connection.notices:
- # NOTICE messages have a
- # newline character at the end
- logger.info(notice.rstrip())
-
- cursor.connection.notices[:] = []
-
-
-class PGCompiler_psycopg2(PGCompiler):
- def visit_mod(self, binary, **kw):
- return self.process(binary.left) + " %% " + self.process(binary.right)
-
- def post_process_text(self, text):
- return text.replace('%', '%%')
-
-
-class PGIdentifierPreparer_psycopg2(PGIdentifierPreparer):
- def _escape_identifier(self, value):
- value = value.replace(self.escape_quote, self.escape_to_quote)
- return value.replace('%', '%%')
-
-class PGDialect_psycopg2(PGDialect):
- driver = 'psycopg2'
- # Py2K
- supports_unicode_statements = False
- # end Py2K
- default_paramstyle = 'pyformat'
- supports_sane_multi_rowcount = False
- execution_ctx_cls = PGExecutionContext_psycopg2
- statement_compiler = PGCompiler_psycopg2
- preparer = PGIdentifierPreparer_psycopg2
- psycopg2_version = (0, 0)
-
- colspecs = util.update_copy(
- PGDialect.colspecs,
- {
- sqltypes.Numeric : _PGNumeric,
- ENUM : _PGEnum, # needs force_unicode
- sqltypes.Enum : _PGEnum, # needs force_unicode
- ARRAY : _PGArray, # needs force_unicode
- }
- )
-
- def __init__(self, server_side_cursors=False, use_native_unicode=True, **kwargs):
- PGDialect.__init__(self, **kwargs)
- self.server_side_cursors = server_side_cursors
- self.use_native_unicode = use_native_unicode
- self.supports_unicode_binds = use_native_unicode
- if self.dbapi and hasattr(self.dbapi, '__version__'):
- m = re.match(r'(\d+)\.(\d+)(?:\.(\d+))?',
- self.dbapi.__version__)
- if m:
- self.psycopg2_version = tuple(
- int(x)
- for x in m.group(1, 2, 3)
- if x is not None)
-
- @classmethod
- def dbapi(cls):
- psycopg = __import__('psycopg2')
- return psycopg
-
- @util.memoized_property
- def _isolation_lookup(self):
- extensions = __import__('psycopg2.extensions').extensions
- return {
- 'READ COMMITTED':extensions.ISOLATION_LEVEL_READ_COMMITTED,
- 'READ UNCOMMITTED':extensions.ISOLATION_LEVEL_READ_UNCOMMITTED,
- 'REPEATABLE READ':extensions.ISOLATION_LEVEL_REPEATABLE_READ,
- 'SERIALIZABLE':extensions.ISOLATION_LEVEL_SERIALIZABLE
- }
-
- def set_isolation_level(self, connection, level):
- try:
- level = self._isolation_lookup[level.replace('_', ' ')]
- except KeyError:
- raise exc.ArgumentError(
- "Invalid value '%s' for isolation_level. "
- "Valid isolation levels for %s are %s" %
- (level, self.name, ", ".join(self._isolation_lookup))
- )
-
- connection.set_isolation_level(level)
-
- def on_connect(self):
- if self.isolation_level is not None:
- def base_on_connect(conn):
- self.set_isolation_level(conn, self.isolation_level)
- else:
- base_on_connect = None
-
- if self.dbapi and self.use_native_unicode:
- extensions = __import__('psycopg2.extensions').extensions
- def connect(conn):
- extensions.register_type(extensions.UNICODE, conn)
- if base_on_connect:
- base_on_connect(conn)
- return connect
- else:
- return base_on_connect
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- if 'port' in opts:
- opts['port'] = int(opts['port'])
- opts.update(url.query)
- return ([], opts)
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, self.dbapi.OperationalError):
- # these error messages from libpq: interfaces/libpq/fe-misc.c.
- # TODO: these are sent through gettext in libpq and we can't
- # check within other locales - consider using connection.closed
- return 'closed the connection' in str(e) or \
- 'connection not open' in str(e) or \
- 'could not receive data from server' in str(e)
- elif isinstance(e, self.dbapi.InterfaceError):
- # psycopg2 client errors, psycopg2/conenction.h, psycopg2/cursor.h
- return 'connection already closed' in str(e) or \
- 'cursor already closed' in str(e)
- elif isinstance(e, self.dbapi.ProgrammingError):
- # not sure where this path is originally from, it may
- # be obsolete. It really says "losed", not "closed".
- return "losed the connection unexpectedly" in str(e)
- else:
- return False
-
-dialect = PGDialect_psycopg2
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pypostgresql.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pypostgresql.py
deleted file mode 100755
index a137a624..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/pypostgresql.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# postgresql/pypostgresql.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the PostgreSQL database via py-postgresql.
-
-Connecting
-----------
-
-URLs are of the form ``postgresql+pypostgresql://user@password@host:port/dbname[?key=value&key=value...]``.
-
-
-"""
-from sqlalchemy import util
-from sqlalchemy import types as sqltypes
-from sqlalchemy.dialects.postgresql.base import PGDialect, PGExecutionContext
-from sqlalchemy import processors
-
-class PGNumeric(sqltypes.Numeric):
- def bind_processor(self, dialect):
- return processors.to_str
-
- def result_processor(self, dialect, coltype):
- if self.asdecimal:
- return None
- else:
- return processors.to_float
-
-class PGExecutionContext_pypostgresql(PGExecutionContext):
- pass
-
-class PGDialect_pypostgresql(PGDialect):
- driver = 'pypostgresql'
-
- supports_unicode_statements = True
- supports_unicode_binds = True
- description_encoding = None
- default_paramstyle = 'pyformat'
-
- # requires trunk version to support sane rowcounts
- # TODO: use dbapi version information to set this flag appropariately
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = False
-
- execution_ctx_cls = PGExecutionContext_pypostgresql
- colspecs = util.update_copy(
- PGDialect.colspecs,
- {
- sqltypes.Numeric : PGNumeric,
- sqltypes.Float: sqltypes.Float, # prevents PGNumeric from being used
- }
- )
-
- @classmethod
- def dbapi(cls):
- from postgresql.driver import dbapi20
- return dbapi20
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user')
- if 'port' in opts:
- opts['port'] = int(opts['port'])
- else:
- opts['port'] = 5432
- opts.update(url.query)
- return ([], opts)
-
- def is_disconnect(self, e, connection, cursor):
- return "connection is closed" in str(e)
-
-dialect = PGDialect_pypostgresql
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/zxjdbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/zxjdbc.py
deleted file mode 100755
index f64b42ac..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/postgresql/zxjdbc.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# postgresql/zxjdbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the PostgreSQL database via the zxjdbc JDBC connector.
-
-JDBC Driver
------------
-
-The official Postgresql JDBC driver is at http://jdbc.postgresql.org/.
-
-"""
-from sqlalchemy.connectors.zxJDBC import ZxJDBCConnector
-from sqlalchemy.dialects.postgresql.base import PGDialect, PGExecutionContext
-
-class PGExecutionContext_zxjdbc(PGExecutionContext):
-
- def create_cursor(self):
- cursor = self._dbapi_connection.cursor()
- cursor.datahandler = self.dialect.DataHandler(cursor.datahandler)
- return cursor
-
-
-class PGDialect_zxjdbc(ZxJDBCConnector, PGDialect):
- jdbc_db_name = 'postgresql'
- jdbc_driver_name = 'org.postgresql.Driver'
-
- execution_ctx_cls = PGExecutionContext_zxjdbc
-
- supports_native_decimal = True
-
- def __init__(self, *args, **kwargs):
- super(PGDialect_zxjdbc, self).__init__(*args, **kwargs)
- from com.ziclix.python.sql.handler import PostgresqlDataHandler
- self.DataHandler = PostgresqlDataHandler
-
- def _get_server_version_info(self, connection):
- return tuple(int(x) for x in connection.connection.dbversion.split('.'))
-
-dialect = PGDialect_zxjdbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/__init__.py
deleted file mode 100755
index d939d51c..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# sqlite/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.sqlite import base, pysqlite
-
-# default dialect
-base.dialect = pysqlite.dialect
-
-
-from sqlalchemy.dialects.sqlite.base import \
- BLOB, BOOLEAN, CHAR, DATE, DATETIME, DECIMAL, FLOAT, INTEGER, REAL,\
- NUMERIC, SMALLINT, TEXT, TIME, TIMESTAMP, VARCHAR, dialect
-
-__all__ = (
- 'BLOB', 'BOOLEAN', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'FLOAT', 'INTEGER',
- 'NUMERIC', 'SMALLINT', 'TEXT', 'TIME', 'TIMESTAMP', 'VARCHAR', 'dialect', 'REAL'
-) \ No newline at end of file
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/base.py
deleted file mode 100755
index 4ab50931..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/base.py
+++ /dev/null
@@ -1,753 +0,0 @@
-# sqlite/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the SQLite database.
-
-For information on connecting using a specific driver, see the documentation
-section regarding that driver.
-
-Date and Time Types
--------------------
-
-SQLite does not have built-in DATE, TIME, or DATETIME types, and pysqlite does not provide
-out of the box functionality for translating values between Python `datetime` objects
-and a SQLite-supported format. SQLAlchemy's own :class:`~sqlalchemy.types.DateTime`
-and related types provide date formatting and parsing functionality when SQlite is used.
-The implementation classes are :class:`.DATETIME`, :class:`.DATE` and :class:`.TIME`.
-These types represent dates and times as ISO formatted strings, which also nicely
-support ordering. There's no reliance on typical "libc" internals for these functions
-so historical dates are fully supported.
-
-Auto Incrementing Behavior
---------------------------
-
-Background on SQLite's autoincrement is at: http://sqlite.org/autoinc.html
-
-Two things to note:
-
-* The AUTOINCREMENT keyword is **not** required for SQLite tables to
- generate primary key values automatically. AUTOINCREMENT only means that
- the algorithm used to generate ROWID values should be slightly different.
-* SQLite does **not** generate primary key (i.e. ROWID) values, even for
- one column, if the table has a composite (i.e. multi-column) primary key.
- This is regardless of the AUTOINCREMENT keyword being present or not.
-
-To specifically render the AUTOINCREMENT keyword on the primary key
-column when rendering DDL, add the flag ``sqlite_autoincrement=True``
-to the Table construct::
-
- Table('sometable', metadata,
- Column('id', Integer, primary_key=True),
- sqlite_autoincrement=True)
-
-Transaction Isolation Level
----------------------------
-
-:func:`create_engine` accepts an ``isolation_level`` parameter which results in
-the command ``PRAGMA read_uncommitted <level>`` being invoked for every new
-connection. Valid values for this parameter are ``SERIALIZABLE`` and
-``READ UNCOMMITTED`` corresponding to a value of 0 and 1, respectively.
-
-"""
-
-import datetime, re
-
-from sqlalchemy import sql, exc
-from sqlalchemy.engine import default, base, reflection
-from sqlalchemy import types as sqltypes
-from sqlalchemy import util
-from sqlalchemy.sql import compiler
-from sqlalchemy import processors
-
-from sqlalchemy.types import BLOB, BOOLEAN, CHAR, DATE, DATETIME, DECIMAL,\
- FLOAT, REAL, INTEGER, NUMERIC, SMALLINT, TEXT, TIME, TIMESTAMP, VARCHAR
-
-class _DateTimeMixin(object):
- _reg = None
- _storage_format = None
-
- def __init__(self, storage_format=None, regexp=None, **kw):
- super(_DateTimeMixin, self).__init__(**kw)
- if regexp is not None:
- self._reg = re.compile(regexp)
- if storage_format is not None:
- self._storage_format = storage_format
-
-class DATETIME(_DateTimeMixin, sqltypes.DateTime):
- """Represent a Python datetime object in SQLite using a string.
-
- The default string storage format is::
-
- "%04d-%02d-%02d %02d:%02d:%02d.%06d" % (value.year,
- value.month, value.day,
- value.hour, value.minute,
- value.second, value.microsecond)
-
- e.g.::
-
- 2011-03-15 12:05:57.10558
-
- The storage format can be customized to some degree using the
- ``storage_format`` and ``regexp`` parameters, such as::
-
- import re
- from sqlalchemy.dialects.sqlite import DATETIME
-
- dt = DATETIME(
- storage_format="%04d/%02d/%02d %02d-%02d-%02d-%06d",
- regexp=re.compile("(\d+)/(\d+)/(\d+) (\d+)-(\d+)-(\d+)(?:-(\d+))?")
- )
-
- :param storage_format: format string which will be appled to the
- tuple ``(value.year, value.month, value.day, value.hour,
- value.minute, value.second, value.microsecond)``, given a
- Python datetime.datetime() object.
-
- :param regexp: regular expression which will be applied to
- incoming result rows. The resulting match object is appled to
- the Python datetime() constructor via ``*map(int,
- match_obj.groups(0))``.
- """
-
- _storage_format = "%04d-%02d-%02d %02d:%02d:%02d.%06d"
-
- def bind_processor(self, dialect):
- datetime_datetime = datetime.datetime
- datetime_date = datetime.date
- format = self._storage_format
- def process(value):
- if value is None:
- return None
- elif isinstance(value, datetime_datetime):
- return format % (value.year, value.month, value.day,
- value.hour, value.minute, value.second,
- value.microsecond)
- elif isinstance(value, datetime_date):
- return format % (value.year, value.month, value.day,
- 0, 0, 0, 0)
- else:
- raise TypeError("SQLite DateTime type only accepts Python "
- "datetime and date objects as input.")
- return process
-
- def result_processor(self, dialect, coltype):
- if self._reg:
- return processors.str_to_datetime_processor_factory(
- self._reg, datetime.datetime)
- else:
- return processors.str_to_datetime
-
-class DATE(_DateTimeMixin, sqltypes.Date):
- """Represent a Python date object in SQLite using a string.
-
- The default string storage format is::
-
- "%04d-%02d-%02d" % (value.year, value.month, value.day)
-
- e.g.::
-
- 2011-03-15
-
- The storage format can be customized to some degree using the
- ``storage_format`` and ``regexp`` parameters, such as::
-
- import re
- from sqlalchemy.dialects.sqlite import DATE
-
- d = DATE(
- storage_format="%02d/%02d/%02d",
- regexp=re.compile("(\d+)/(\d+)/(\d+)")
- )
-
- :param storage_format: format string which will be appled to the
- tuple ``(value.year, value.month, value.day)``,
- given a Python datetime.date() object.
-
- :param regexp: regular expression which will be applied to
- incoming result rows. The resulting match object is appled to
- the Python date() constructor via ``*map(int,
- match_obj.groups(0))``.
-
- """
-
- _storage_format = "%04d-%02d-%02d"
-
- def bind_processor(self, dialect):
- datetime_date = datetime.date
- format = self._storage_format
- def process(value):
- if value is None:
- return None
- elif isinstance(value, datetime_date):
- return format % (value.year, value.month, value.day)
- else:
- raise TypeError("SQLite Date type only accepts Python "
- "date objects as input.")
- return process
-
- def result_processor(self, dialect, coltype):
- if self._reg:
- return processors.str_to_datetime_processor_factory(
- self._reg, datetime.date)
- else:
- return processors.str_to_date
-
-class TIME(_DateTimeMixin, sqltypes.Time):
- """Represent a Python time object in SQLite using a string.
-
- The default string storage format is::
-
- "%02d:%02d:%02d.%06d" % (value.hour, value.minute,
- value.second,
- value.microsecond)
-
- e.g.::
-
- 12:05:57.10558
-
- The storage format can be customized to some degree using the
- ``storage_format`` and ``regexp`` parameters, such as::
-
- import re
- from sqlalchemy.dialects.sqlite import TIME
-
- t = TIME(
- storage_format="%02d-%02d-%02d-%06d",
- regexp=re.compile("(\d+)-(\d+)-(\d+)-(?:-(\d+))?")
- )
-
- :param storage_format: format string which will be appled
- to the tuple ``(value.hour, value.minute, value.second,
- value.microsecond)``, given a Python datetime.time() object.
-
- :param regexp: regular expression which will be applied to
- incoming result rows. The resulting match object is appled to
- the Python time() constructor via ``*map(int,
- match_obj.groups(0))``.
-
- """
-
- _storage_format = "%02d:%02d:%02d.%06d"
-
- def bind_processor(self, dialect):
- datetime_time = datetime.time
- format = self._storage_format
- def process(value):
- if value is None:
- return None
- elif isinstance(value, datetime_time):
- return format % (value.hour, value.minute, value.second,
- value.microsecond)
- else:
- raise TypeError("SQLite Time type only accepts Python "
- "time objects as input.")
- return process
-
- def result_processor(self, dialect, coltype):
- if self._reg:
- return processors.str_to_datetime_processor_factory(
- self._reg, datetime.time)
- else:
- return processors.str_to_time
-
-colspecs = {
- sqltypes.Date: DATE,
- sqltypes.DateTime: DATETIME,
- sqltypes.Time: TIME,
-}
-
-ischema_names = {
- 'BLOB': sqltypes.BLOB,
- 'BOOL': sqltypes.BOOLEAN,
- 'BOOLEAN': sqltypes.BOOLEAN,
- 'CHAR': sqltypes.CHAR,
- 'DATE': sqltypes.DATE,
- 'DATETIME': sqltypes.DATETIME,
- 'DECIMAL': sqltypes.DECIMAL,
- 'FLOAT': sqltypes.FLOAT,
- 'INT': sqltypes.INTEGER,
- 'INTEGER': sqltypes.INTEGER,
- 'NUMERIC': sqltypes.NUMERIC,
- 'REAL': sqltypes.REAL,
- 'SMALLINT': sqltypes.SMALLINT,
- 'TEXT': sqltypes.TEXT,
- 'TIME': sqltypes.TIME,
- 'TIMESTAMP': sqltypes.TIMESTAMP,
- 'VARCHAR': sqltypes.VARCHAR,
-}
-
-
-
-class SQLiteCompiler(compiler.SQLCompiler):
- extract_map = util.update_copy(
- compiler.SQLCompiler.extract_map,
- {
- 'month': '%m',
- 'day': '%d',
- 'year': '%Y',
- 'second': '%S',
- 'hour': '%H',
- 'doy': '%j',
- 'minute': '%M',
- 'epoch': '%s',
- 'dow': '%w',
- 'week': '%W'
- })
-
- def visit_now_func(self, fn, **kw):
- return "CURRENT_TIMESTAMP"
-
- def visit_char_length_func(self, fn, **kw):
- return "length%s" % self.function_argspec(fn)
-
- def visit_cast(self, cast, **kwargs):
- if self.dialect.supports_cast:
- return super(SQLiteCompiler, self).visit_cast(cast)
- else:
- return self.process(cast.clause)
-
- def visit_extract(self, extract, **kw):
- try:
- return "CAST(STRFTIME('%s', %s) AS INTEGER)" % (
- self.extract_map[extract.field], self.process(extract.expr, **kw))
- except KeyError:
- raise exc.ArgumentError(
- "%s is not a valid extract argument." % extract.field)
-
- def limit_clause(self, select):
- text = ""
- if select._limit is not None:
- text += "\n LIMIT " + self.process(sql.literal(select._limit))
- if select._offset is not None:
- if select._limit is None:
- text += "\n LIMIT " + self.process(sql.literal(-1))
- text += " OFFSET " + self.process(sql.literal(select._offset))
- else:
- text += " OFFSET " + self.process(sql.literal(0))
- return text
-
- def for_update_clause(self, select):
- # sqlite has no "FOR UPDATE" AFAICT
- return ''
-
-
-class SQLiteDDLCompiler(compiler.DDLCompiler):
-
- def get_column_specification(self, column, **kwargs):
- colspec = self.preparer.format_column(column) + " " + self.dialect.type_compiler.process(column.type)
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- if not column.nullable:
- colspec += " NOT NULL"
-
- if column.primary_key and \
- column.table.kwargs.get('sqlite_autoincrement', False) and \
- len(column.table.primary_key.columns) == 1 and \
- issubclass(column.type._type_affinity, sqltypes.Integer) and \
- not column.foreign_keys:
- colspec += " PRIMARY KEY AUTOINCREMENT"
-
- return colspec
-
- def visit_primary_key_constraint(self, constraint):
- # for columns with sqlite_autoincrement=True,
- # the PRIMARY KEY constraint can only be inline
- # with the column itself.
- if len(constraint.columns) == 1:
- c = list(constraint)[0]
- if c.primary_key and \
- c.table.kwargs.get('sqlite_autoincrement', False) and \
- issubclass(c.type._type_affinity, sqltypes.Integer) and \
- not c.foreign_keys:
- return None
-
- return super(SQLiteDDLCompiler, self).\
- visit_primary_key_constraint(constraint)
-
- def visit_foreign_key_constraint(self, constraint):
-
- local_table = constraint._elements.values()[0].parent.table
- remote_table = list(constraint._elements.values())[0].column.table
-
- if local_table.schema != remote_table.schema:
- return None
- else:
- return super(SQLiteDDLCompiler, self).visit_foreign_key_constraint(constraint)
-
- def define_constraint_remote_table(self, constraint, table, preparer):
- """Format the remote table clause of a CREATE CONSTRAINT clause."""
-
- return preparer.format_table(table, use_schema=False)
-
- def visit_create_index(self, create):
- index = create.element
- preparer = self.preparer
- text = "CREATE "
- if index.unique:
- text += "UNIQUE "
- text += "INDEX %s ON %s (%s)" \
- % (preparer.format_index(index,
- name=self._index_identifier(index.name)),
- preparer.format_table(index.table, use_schema=False),
- ', '.join(preparer.quote(c.name, c.quote)
- for c in index.columns))
- return text
-
-class SQLiteTypeCompiler(compiler.GenericTypeCompiler):
- def visit_large_binary(self, type_):
- return self.visit_BLOB(type_)
-
-class SQLiteIdentifierPreparer(compiler.IdentifierPreparer):
- reserved_words = set([
- 'add', 'after', 'all', 'alter', 'analyze', 'and', 'as', 'asc',
- 'attach', 'autoincrement', 'before', 'begin', 'between', 'by',
- 'cascade', 'case', 'cast', 'check', 'collate', 'column', 'commit',
- 'conflict', 'constraint', 'create', 'cross', 'current_date',
- 'current_time', 'current_timestamp', 'database', 'default',
- 'deferrable', 'deferred', 'delete', 'desc', 'detach', 'distinct',
- 'drop', 'each', 'else', 'end', 'escape', 'except', 'exclusive',
- 'explain', 'false', 'fail', 'for', 'foreign', 'from', 'full', 'glob',
- 'group', 'having', 'if', 'ignore', 'immediate', 'in', 'index',
- 'indexed', 'initially', 'inner', 'insert', 'instead', 'intersect', 'into', 'is',
- 'isnull', 'join', 'key', 'left', 'like', 'limit', 'match', 'natural',
- 'not', 'notnull', 'null', 'of', 'offset', 'on', 'or', 'order', 'outer',
- 'plan', 'pragma', 'primary', 'query', 'raise', 'references',
- 'reindex', 'rename', 'replace', 'restrict', 'right', 'rollback',
- 'row', 'select', 'set', 'table', 'temp', 'temporary', 'then', 'to',
- 'transaction', 'trigger', 'true', 'union', 'unique', 'update', 'using',
- 'vacuum', 'values', 'view', 'virtual', 'when', 'where',
- ])
-
- def format_index(self, index, use_schema=True, name=None):
- """Prepare a quoted index and schema name."""
-
- if name is None:
- name = index.name
- result = self.quote(name, index.quote)
- if not self.omit_schema and use_schema and getattr(index.table, "schema", None):
- result = self.quote_schema(index.table.schema, index.table.quote_schema) + "." + result
- return result
-
-class SQLiteExecutionContext(default.DefaultExecutionContext):
- def get_result_proxy(self):
- rp = base.ResultProxy(self)
- if rp._metadata:
- # adjust for dotted column names. SQLite
- # in the case of UNION may store col names as
- # "tablename.colname"
- # in cursor.description
- for colname in rp._metadata.keys:
- if "." in colname:
- trunc_col = colname.split(".")[1]
- rp._metadata._set_keymap_synonym(trunc_col, colname)
- return rp
-
-class SQLiteDialect(default.DefaultDialect):
- name = 'sqlite'
- supports_alter = False
- supports_unicode_statements = True
- supports_unicode_binds = True
- supports_default_values = True
- supports_empty_insert = False
- supports_cast = True
-
- default_paramstyle = 'qmark'
- statement_compiler = SQLiteCompiler
- ddl_compiler = SQLiteDDLCompiler
- type_compiler = SQLiteTypeCompiler
- preparer = SQLiteIdentifierPreparer
- ischema_names = ischema_names
- colspecs = colspecs
- isolation_level = None
- execution_ctx_cls = SQLiteExecutionContext
-
- supports_cast = True
- supports_default_values = True
-
- def __init__(self, isolation_level=None, native_datetime=False, **kwargs):
- default.DefaultDialect.__init__(self, **kwargs)
- self.isolation_level = isolation_level
-
- # this flag used by pysqlite dialect, and perhaps others in the
- # future, to indicate the driver is handling date/timestamp
- # conversions (and perhaps datetime/time as well on some
- # hypothetical driver ?)
- self.native_datetime = native_datetime
-
- if self.dbapi is not None:
- self.supports_default_values = \
- self.dbapi.sqlite_version_info >= (3, 3, 8)
- self.supports_cast = \
- self.dbapi.sqlite_version_info >= (3, 2, 3)
-
- _isolation_lookup = {
- 'READ UNCOMMITTED':1,
- 'SERIALIZABLE':0
- }
- def set_isolation_level(self, connection, level):
- try:
- isolation_level = self._isolation_lookup[level.replace('_', ' ')]
- except KeyError:
- raise exc.ArgumentError(
- "Invalid value '%s' for isolation_level. "
- "Valid isolation levels for %s are %s" %
- (level, self.name, ", ".join(self._isolation_lookup))
- )
- cursor = connection.cursor()
- cursor.execute("PRAGMA read_uncommitted = %d" % isolation_level)
- cursor.close()
-
- def get_isolation_level(self, connection):
- cursor = connection.cursor()
- cursor.execute('PRAGMA read_uncommitted')
- value = cursor.fetchone()[0]
- cursor.close()
- if value == 0:
- return "SERIALIZABLE"
- elif value == 1:
- return "READ UNCOMMITTED"
- else:
- assert False, "Unknown isolation level %s" % value
-
- def on_connect(self):
- if self.isolation_level is not None:
- def connect(conn):
- self.set_isolation_level(conn, self.isolation_level)
- return connect
- else:
- return None
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- if schema is not None:
- qschema = self.identifier_preparer.quote_identifier(schema)
- master = '%s.sqlite_master' % qschema
- s = ("SELECT name FROM %s "
- "WHERE type='table' ORDER BY name") % (master,)
- rs = connection.execute(s)
- else:
- try:
- s = ("SELECT name FROM "
- " (SELECT * FROM sqlite_master UNION ALL "
- " SELECT * FROM sqlite_temp_master) "
- "WHERE type='table' ORDER BY name")
- rs = connection.execute(s)
- except exc.DBAPIError:
- raise
- s = ("SELECT name FROM sqlite_master "
- "WHERE type='table' ORDER BY name")
- rs = connection.execute(s)
-
- return [row[0] for row in rs]
-
- def has_table(self, connection, table_name, schema=None):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- cursor = _pragma_cursor(connection.execute("%stable_info(%s)" % (pragma, qtable)))
- row = cursor.fetchone()
-
- # consume remaining rows, to work around
- # http://www.sqlite.org/cvstrac/tktview?tn=1884
- while not cursor.closed and cursor.fetchone() is not None:
- pass
-
- return (row is not None)
-
- @reflection.cache
- def get_view_names(self, connection, schema=None, **kw):
- if schema is not None:
- qschema = self.identifier_preparer.quote_identifier(schema)
- master = '%s.sqlite_master' % qschema
- s = ("SELECT name FROM %s "
- "WHERE type='view' ORDER BY name") % (master,)
- rs = connection.execute(s)
- else:
- try:
- s = ("SELECT name FROM "
- " (SELECT * FROM sqlite_master UNION ALL "
- " SELECT * FROM sqlite_temp_master) "
- "WHERE type='view' ORDER BY name")
- rs = connection.execute(s)
- except exc.DBAPIError:
- raise
- s = ("SELECT name FROM sqlite_master "
- "WHERE type='view' ORDER BY name")
- rs = connection.execute(s)
-
- return [row[0] for row in rs]
-
- @reflection.cache
- def get_view_definition(self, connection, view_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- qschema = self.identifier_preparer.quote_identifier(schema)
- master = '%s.sqlite_master' % qschema
- s = ("SELECT sql FROM %s WHERE name = '%s'"
- "AND type='view'") % (master, view_name)
- rs = connection.execute(s)
- else:
- try:
- s = ("SELECT sql FROM "
- " (SELECT * FROM sqlite_master UNION ALL "
- " SELECT * FROM sqlite_temp_master) "
- "WHERE name = '%s' "
- "AND type='view'") % view_name
- rs = connection.execute(s)
- except exc.DBAPIError:
- raise
- s = ("SELECT sql FROM sqlite_master WHERE name = '%s' "
- "AND type='view'") % view_name
- rs = connection.execute(s)
-
- result = rs.fetchall()
- if result:
- return result[0].sql
-
- @reflection.cache
- def get_columns(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%stable_info(%s)" % (pragma, qtable)))
- found_table = False
- columns = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- (name, type_, nullable, default, has_default, primary_key) = (row[1], row[2].upper(), not row[3], row[4], row[4] is not None, row[5])
- name = re.sub(r'^\"|\"$', '', name)
- if default:
- default = re.sub(r"^\'|\'$", '', default)
- match = re.match(r'(\w+)(\(.*?\))?', type_)
- if match:
- coltype = match.group(1)
- args = match.group(2)
- else:
- coltype = "VARCHAR"
- args = ''
- try:
- coltype = self.ischema_names[coltype]
- if args is not None:
- args = re.findall(r'(\d+)', args)
- coltype = coltype(*[int(a) for a in args])
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, name))
- coltype = sqltypes.NullType()
-
- columns.append({
- 'name' : name,
- 'type' : coltype,
- 'nullable' : nullable,
- 'default' : default,
- 'autoincrement':default is None,
- 'primary_key': primary_key
- })
- return columns
-
- @reflection.cache
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- cols = self.get_columns(connection, table_name, schema, **kw)
- pkeys = []
- for col in cols:
- if col['primary_key']:
- pkeys.append(col['name'])
- return pkeys
-
- @reflection.cache
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%sforeign_key_list(%s)" % (pragma, qtable)))
- fkeys = []
- fks = {}
- while True:
- row = c.fetchone()
- if row is None:
- break
- (constraint_name, rtbl, lcol, rcol) = (row[0], row[2], row[3], row[4])
- # sqlite won't return rcol if the table
- # was created with REFERENCES <tablename>, no col
- if rcol is None:
- rcol = lcol
- rtbl = re.sub(r'^\"|\"$', '', rtbl)
- lcol = re.sub(r'^\"|\"$', '', lcol)
- rcol = re.sub(r'^\"|\"$', '', rcol)
- try:
- fk = fks[constraint_name]
- except KeyError:
- fk = {
- 'name' : constraint_name,
- 'constrained_columns' : [],
- 'referred_schema' : None,
- 'referred_table' : rtbl,
- 'referred_columns' : []
- }
- fkeys.append(fk)
- fks[constraint_name] = fk
-
- # look up the table based on the given table's engine, not 'self',
- # since it could be a ProxyEngine
- if lcol not in fk['constrained_columns']:
- fk['constrained_columns'].append(lcol)
- if rcol not in fk['referred_columns']:
- fk['referred_columns'].append(rcol)
- return fkeys
-
- @reflection.cache
- def get_indexes(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- include_auto_indexes = kw.pop('include_auto_indexes', False)
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%sindex_list(%s)" % (pragma, qtable)))
- indexes = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- # ignore implicit primary key index.
- # http://www.mail-archive.com/sqlite-users@sqlite.org/msg30517.html
- elif not include_auto_indexes and row[1].startswith('sqlite_autoindex'):
- continue
-
- indexes.append(dict(name=row[1], column_names=[], unique=row[2]))
- # loop thru unique indexes to get the column names.
- for idx in indexes:
- c = connection.execute("%sindex_info(%s)" % (pragma, quote(idx['name'])))
- cols = idx['column_names']
- while True:
- row = c.fetchone()
- if row is None:
- break
- cols.append(row[2])
- return indexes
-
-
-def _pragma_cursor(cursor):
- """work around SQLite issue whereby cursor.description
- is blank when PRAGMA returns no rows."""
-
- if cursor.closed:
- cursor.fetchone = lambda: None
- return cursor
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/pysqlite.py
deleted file mode 100755
index d426b1bb..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sqlite/pysqlite.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# sqlite/pysqlite.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for the SQLite database via pysqlite.
-
-Note that pysqlite is the same driver as the ``sqlite3``
-module included with the Python distribution.
-
-Driver
-------
-
-When using Python 2.5 and above, the built in ``sqlite3`` driver is
-already installed and no additional installation is needed. Otherwise,
-the ``pysqlite2`` driver needs to be present. This is the same driver as
-``sqlite3``, just with a different name.
-
-The ``pysqlite2`` driver will be loaded first, and if not found, ``sqlite3``
-is loaded. This allows an explicitly installed pysqlite driver to take
-precedence over the built in one. As with all dialects, a specific
-DBAPI module may be provided to :func:`~sqlalchemy.create_engine()` to control
-this explicitly::
-
- from sqlite3 import dbapi2 as sqlite
- e = create_engine('sqlite+pysqlite:///file.db', module=sqlite)
-
-Full documentation on pysqlite is available at:
-`<http://www.initd.org/pub/software/pysqlite/doc/usage-guide.html>`_
-
-Connect Strings
----------------
-
-The file specification for the SQLite database is taken as the "database" portion of
-the URL. Note that the format of a url is::
-
- driver://user:pass@host/database
-
-This means that the actual filename to be used starts with the characters to the
-**right** of the third slash. So connecting to a relative filepath looks like::
-
- # relative path
- e = create_engine('sqlite:///path/to/database.db')
-
-An absolute path, which is denoted by starting with a slash, means you need **four**
-slashes::
-
- # absolute path
- e = create_engine('sqlite:////path/to/database.db')
-
-To use a Windows path, regular drive specifications and backslashes can be used.
-Double backslashes are probably needed::
-
- # absolute path on Windows
- e = create_engine('sqlite:///C:\\\\path\\\\to\\\\database.db')
-
-The sqlite ``:memory:`` identifier is the default if no filepath is present. Specify
-``sqlite://`` and nothing else::
-
- # in-memory database
- e = create_engine('sqlite://')
-
-Compatibility with sqlite3 "native" date and datetime types
------------------------------------------------------------
-
-The pysqlite driver includes the sqlite3.PARSE_DECLTYPES and
-sqlite3.PARSE_COLNAMES options, which have the effect of any column
-or expression explicitly cast as "date" or "timestamp" will be converted
-to a Python date or datetime object. The date and datetime types provided
-with the pysqlite dialect are not currently compatible with these options,
-since they render the ISO date/datetime including microseconds, which
-pysqlite's driver does not. Additionally, SQLAlchemy does not at
-this time automatically render the "cast" syntax required for the
-freestanding functions "current_timestamp" and "current_date" to return
-datetime/date types natively. Unfortunately, pysqlite
-does not provide the standard DBAPI types in ``cursor.description``,
-leaving SQLAlchemy with no way to detect these types on the fly
-without expensive per-row type checks.
-
-Keeping in mind that pysqlite's parsing option is not recommended,
-nor should be necessary, for use with SQLAlchemy, usage of PARSE_DECLTYPES
-can be forced if one configures "native_datetime=True" on create_engine()::
-
- engine = create_engine('sqlite://',
- connect_args={'detect_types': sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES},
- native_datetime=True
- )
-
-With this flag enabled, the DATE and TIMESTAMP types (but note - not the DATETIME
-or TIME types...confused yet ?) will not perform any bind parameter or result
-processing. Execution of "func.current_date()" will return a string.
-"func.current_timestamp()" is registered as returning a DATETIME type in
-SQLAlchemy, so this function still receives SQLAlchemy-level result processing.
-
-Pooling Behavior
-------------------
-
-Pysqlite connections do not support being moved between threads, unless
-the ``check_same_thread`` Pysqlite flag is set to ``False``. In addition,
-when using an in-memory SQLite database, the full database exists only within
-the scope of a single connection. It is reported that an in-memory
-database does not support being shared between threads regardless of the
-``check_same_thread`` flag - which means that a multithreaded
-application **cannot** share data from a ``:memory:`` database across threads
-unless access to the connection is limited to a single worker thread which communicates
-through a queueing mechanism to concurrent threads.
-
-To provide for these two behaviors, the pysqlite dialect will select a :class:`.Pool`
-implementation suitable:
-
-* When a ``:memory:`` SQLite database is specified, the dialect will use :class:`.SingletonThreadPool`.
- This pool maintains a single connection per thread, so that all access to the engine within
- the current thread use the same ``:memory:`` database.
-* When a file-based database is specified, the dialect will use :class:`.NullPool` as the source
- of connections. This pool closes and discards connections which are returned to the pool immediately.
- SQLite file-based connections have extermely low overhead, so pooling is not necessary.
- The scheme also prevents a connection from being used again in a different thread
- and works best with SQLite's coarse-grained file locking.
-
- .. note:: The default selection of :class:`.NullPool` for SQLite file-based databases
- is new in SQLAlchemy 0.7. Previous versions
- select :class:`.SingletonThreadPool` by
- default for all SQLite databases.
-
-Unicode
--------
-
-In contrast to SQLAlchemy's active handling of date and time types for pysqlite, pysqlite's
-default behavior regarding Unicode is that all strings are returned as Python unicode objects
-in all cases. So even if the :class:`~sqlalchemy.types.Unicode` type is
-*not* used, you will still always receive unicode data back from a result set. It is
-**strongly** recommended that you do use the :class:`~sqlalchemy.types.Unicode` type
-to represent strings, since it will raise a warning if a non-unicode Python string is
-passed from the user application. Mixing the usage of non-unicode objects with returned unicode objects can
-quickly create confusion, particularly when using the ORM as internal data is not
-always represented by an actual database result string.
-
-"""
-
-from sqlalchemy.dialects.sqlite.base import SQLiteDialect, DATETIME, DATE
-from sqlalchemy import exc, pool
-from sqlalchemy import types as sqltypes
-from sqlalchemy import util
-
-import os
-
-class _SQLite_pysqliteTimeStamp(DATETIME):
- def bind_processor(self, dialect):
- if dialect.native_datetime:
- return None
- else:
- return DATETIME.bind_processor(self, dialect)
-
- def result_processor(self, dialect, coltype):
- if dialect.native_datetime:
- return None
- else:
- return DATETIME.result_processor(self, dialect, coltype)
-
-class _SQLite_pysqliteDate(DATE):
- def bind_processor(self, dialect):
- if dialect.native_datetime:
- return None
- else:
- return DATE.bind_processor(self, dialect)
-
- def result_processor(self, dialect, coltype):
- if dialect.native_datetime:
- return None
- else:
- return DATE.result_processor(self, dialect, coltype)
-
-class SQLiteDialect_pysqlite(SQLiteDialect):
- default_paramstyle = 'qmark'
-
- colspecs = util.update_copy(
- SQLiteDialect.colspecs,
- {
- sqltypes.Date:_SQLite_pysqliteDate,
- sqltypes.TIMESTAMP:_SQLite_pysqliteTimeStamp,
- }
- )
-
- # Py3K
- #description_encoding = None
-
- driver = 'pysqlite'
-
- def __init__(self, **kwargs):
- SQLiteDialect.__init__(self, **kwargs)
-
- if self.dbapi is not None:
- sqlite_ver = self.dbapi.version_info
- if sqlite_ver < (2, 1, 3):
- util.warn(
- ("The installed version of pysqlite2 (%s) is out-dated "
- "and will cause errors in some cases. Version 2.1.3 "
- "or greater is recommended.") %
- '.'.join([str(subver) for subver in sqlite_ver]))
-
- @classmethod
- def dbapi(cls):
- try:
- from pysqlite2 import dbapi2 as sqlite
- except ImportError, e:
- try:
- from sqlite3 import dbapi2 as sqlite #try the 2.5+ stdlib name.
- except ImportError:
- raise e
- return sqlite
-
- @classmethod
- def get_pool_class(cls, url):
- if url.database and url.database != ':memory:':
- return pool.NullPool
- else:
- return pool.SingletonThreadPool
-
- def _get_server_version_info(self, connection):
- return self.dbapi.sqlite_version_info
-
- def create_connect_args(self, url):
- if url.username or url.password or url.host or url.port:
- raise exc.ArgumentError(
- "Invalid SQLite URL: %s\n"
- "Valid SQLite URL forms are:\n"
- " sqlite:///:memory: (or, sqlite://)\n"
- " sqlite:///relative/path/to/file.db\n"
- " sqlite:////absolute/path/to/file.db" % (url,))
- filename = url.database or ':memory:'
- if filename != ':memory:':
- filename = os.path.abspath(filename)
-
- opts = url.query.copy()
- util.coerce_kw_type(opts, 'timeout', float)
- util.coerce_kw_type(opts, 'isolation_level', str)
- util.coerce_kw_type(opts, 'detect_types', int)
- util.coerce_kw_type(opts, 'check_same_thread', bool)
- util.coerce_kw_type(opts, 'cached_statements', int)
-
- return ([filename], opts)
-
- def is_disconnect(self, e, connection, cursor):
- return isinstance(e, self.dbapi.ProgrammingError) and "Cannot operate on a closed database." in str(e)
-
-dialect = SQLiteDialect_pysqlite
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/__init__.py
deleted file mode 100755
index 1481c6d9..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# sybase/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.dialects.sybase import base, pysybase, pyodbc
-
-
-from base import CHAR, VARCHAR, TIME, NCHAR, NVARCHAR,\
- TEXT,DATE,DATETIME, FLOAT, NUMERIC,\
- BIGINT,INT, INTEGER, SMALLINT, BINARY,\
- VARBINARY,UNITEXT,UNICHAR,UNIVARCHAR,\
- IMAGE,BIT,MONEY,SMALLMONEY,TINYINT
-
-# default dialect
-base.dialect = pyodbc.dialect
-
-__all__ = (
- 'CHAR', 'VARCHAR', 'TIME', 'NCHAR', 'NVARCHAR',
- 'TEXT','DATE','DATETIME', 'FLOAT', 'NUMERIC',
- 'BIGINT','INT', 'INTEGER', 'SMALLINT', 'BINARY',
- 'VARBINARY','UNITEXT','UNICHAR','UNIVARCHAR',
- 'IMAGE','BIT','MONEY','SMALLMONEY','TINYINT',
- 'dialect'
-)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/base.py
deleted file mode 100755
index 3c470604..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/base.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# sybase/base.py
-# Copyright (C) 2010-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# get_select_precolumns(), limit_clause() implementation
-# copyright (C) 2007 Fisch Asset Management
-# AG http://www.fam.ch, with coding by Alexander Houben
-# alexander.houben@thor-solutions.ch
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for Sybase Adaptive Server Enterprise (ASE).
-
-Note that this dialect is no longer specific to Sybase iAnywhere.
-ASE is the primary support platform.
-
-"""
-
-import operator
-from sqlalchemy.sql import compiler, expression, text, bindparam
-from sqlalchemy.engine import default, base, reflection
-from sqlalchemy import types as sqltypes
-from sqlalchemy.sql import operators as sql_operators
-from sqlalchemy import schema as sa_schema
-from sqlalchemy import util, sql, exc
-
-from sqlalchemy.types import CHAR, VARCHAR, TIME, NCHAR, NVARCHAR,\
- TEXT,DATE,DATETIME, FLOAT, NUMERIC,\
- BIGINT,INT, INTEGER, SMALLINT, BINARY,\
- VARBINARY, DECIMAL, TIMESTAMP, Unicode,\
- UnicodeText
-
-RESERVED_WORDS = set([
- "add", "all", "alter", "and",
- "any", "as", "asc", "backup",
- "begin", "between", "bigint", "binary",
- "bit", "bottom", "break", "by",
- "call", "capability", "cascade", "case",
- "cast", "char", "char_convert", "character",
- "check", "checkpoint", "close", "comment",
- "commit", "connect", "constraint", "contains",
- "continue", "convert", "create", "cross",
- "cube", "current", "current_timestamp", "current_user",
- "cursor", "date", "dbspace", "deallocate",
- "dec", "decimal", "declare", "default",
- "delete", "deleting", "desc", "distinct",
- "do", "double", "drop", "dynamic",
- "else", "elseif", "encrypted", "end",
- "endif", "escape", "except", "exception",
- "exec", "execute", "existing", "exists",
- "externlogin", "fetch", "first", "float",
- "for", "force", "foreign", "forward",
- "from", "full", "goto", "grant",
- "group", "having", "holdlock", "identified",
- "if", "in", "index", "index_lparen",
- "inner", "inout", "insensitive", "insert",
- "inserting", "install", "instead", "int",
- "integer", "integrated", "intersect", "into",
- "iq", "is", "isolation", "join",
- "key", "lateral", "left", "like",
- "lock", "login", "long", "match",
- "membership", "message", "mode", "modify",
- "natural", "new", "no", "noholdlock",
- "not", "notify", "null", "numeric",
- "of", "off", "on", "open",
- "option", "options", "or", "order",
- "others", "out", "outer", "over",
- "passthrough", "precision", "prepare", "primary",
- "print", "privileges", "proc", "procedure",
- "publication", "raiserror", "readtext", "real",
- "reference", "references", "release", "remote",
- "remove", "rename", "reorganize", "resource",
- "restore", "restrict", "return", "revoke",
- "right", "rollback", "rollup", "save",
- "savepoint", "scroll", "select", "sensitive",
- "session", "set", "setuser", "share",
- "smallint", "some", "sqlcode", "sqlstate",
- "start", "stop", "subtrans", "subtransaction",
- "synchronize", "syntax_error", "table", "temporary",
- "then", "time", "timestamp", "tinyint",
- "to", "top", "tran", "trigger",
- "truncate", "tsequal", "unbounded", "union",
- "unique", "unknown", "unsigned", "update",
- "updating", "user", "using", "validate",
- "values", "varbinary", "varchar", "variable",
- "varying", "view", "wait", "waitfor",
- "when", "where", "while", "window",
- "with", "with_cube", "with_lparen", "with_rollup",
- "within", "work", "writetext",
- ])
-
-
-class _SybaseUnitypeMixin(object):
- """these types appear to return a buffer object."""
-
- def result_processor(self, dialect, coltype):
- def process(value):
- if value is not None:
- return str(value) #.decode("ucs-2")
- else:
- return None
- return process
-
-class UNICHAR(_SybaseUnitypeMixin, sqltypes.Unicode):
- __visit_name__ = 'UNICHAR'
-
-class UNIVARCHAR(_SybaseUnitypeMixin, sqltypes.Unicode):
- __visit_name__ = 'UNIVARCHAR'
-
-class UNITEXT(_SybaseUnitypeMixin, sqltypes.UnicodeText):
- __visit_name__ = 'UNITEXT'
-
-class TINYINT(sqltypes.Integer):
- __visit_name__ = 'TINYINT'
-
-class BIT(sqltypes.TypeEngine):
- __visit_name__ = 'BIT'
-
-class MONEY(sqltypes.TypeEngine):
- __visit_name__ = "MONEY"
-
-class SMALLMONEY(sqltypes.TypeEngine):
- __visit_name__ = "SMALLMONEY"
-
-class UNIQUEIDENTIFIER(sqltypes.TypeEngine):
- __visit_name__ = "UNIQUEIDENTIFIER"
-
-class IMAGE(sqltypes.LargeBinary):
- __visit_name__ = 'IMAGE'
-
-
-class SybaseTypeCompiler(compiler.GenericTypeCompiler):
- def visit_large_binary(self, type_):
- return self.visit_IMAGE(type_)
-
- def visit_boolean(self, type_):
- return self.visit_BIT(type_)
-
- def visit_unicode(self, type_):
- return self.visit_NVARCHAR(type_)
-
- def visit_UNICHAR(self, type_):
- return "UNICHAR(%d)" % type_.length
-
- def visit_UNIVARCHAR(self, type_):
- return "UNIVARCHAR(%d)" % type_.length
-
- def visit_UNITEXT(self, type_):
- return "UNITEXT"
-
- def visit_TINYINT(self, type_):
- return "TINYINT"
-
- def visit_IMAGE(self, type_):
- return "IMAGE"
-
- def visit_BIT(self, type_):
- return "BIT"
-
- def visit_MONEY(self, type_):
- return "MONEY"
-
- def visit_SMALLMONEY(self, type_):
- return "SMALLMONEY"
-
- def visit_UNIQUEIDENTIFIER(self, type_):
- return "UNIQUEIDENTIFIER"
-
-ischema_names = {
- 'integer' : INTEGER,
- 'unsigned int' : INTEGER, # TODO: unsigned flags
- 'unsigned smallint' : SMALLINT, # TODO: unsigned flags
- 'unsigned bigint' : BIGINT, # TODO: unsigned flags
- 'bigint': BIGINT,
- 'smallint' : SMALLINT,
- 'tinyint' : TINYINT,
- 'varchar' : VARCHAR,
- 'long varchar' : TEXT, # TODO
- 'char' : CHAR,
- 'decimal' : DECIMAL,
- 'numeric' : NUMERIC,
- 'float' : FLOAT,
- 'double' : NUMERIC, # TODO
- 'binary' : BINARY,
- 'varbinary' : VARBINARY,
- 'bit': BIT,
- 'image' : IMAGE,
- 'timestamp': TIMESTAMP,
- 'money': MONEY,
- 'smallmoney': MONEY,
- 'uniqueidentifier': UNIQUEIDENTIFIER,
-
-}
-
-
-class SybaseExecutionContext(default.DefaultExecutionContext):
- _enable_identity_insert = False
-
- def set_ddl_autocommit(self, connection, value):
- """Must be implemented by subclasses to accommodate DDL executions.
-
- "connection" is the raw unwrapped DBAPI connection. "value"
- is True or False. when True, the connection should be configured
- such that a DDL can take place subsequently. when False,
- a DDL has taken place and the connection should be resumed
- into non-autocommit mode.
-
- """
- raise NotImplementedError()
-
- def pre_exec(self):
- if self.isinsert:
- tbl = self.compiled.statement.table
- seq_column = tbl._autoincrement_column
- insert_has_sequence = seq_column is not None
-
- if insert_has_sequence:
- self._enable_identity_insert = \
- seq_column.key in self.compiled_parameters[0]
- else:
- self._enable_identity_insert = False
-
- if self._enable_identity_insert:
- self.cursor.execute("SET IDENTITY_INSERT %s ON" %
- self.dialect.identifier_preparer.format_table(tbl))
-
- if self.isddl:
- # TODO: to enhance this, we can detect "ddl in tran" on the
- # database settings. this error message should be improved to
- # include a note about that.
- if not self.should_autocommit:
- raise exc.InvalidRequestError(
- "The Sybase dialect only supports "
- "DDL in 'autocommit' mode at this time.")
-
- self.root_connection.engine.logger.info(
- "AUTOCOMMIT (Assuming no Sybase 'ddl in tran')")
-
- self.set_ddl_autocommit(
- self.root_connection.connection.connection,
- True)
-
-
- def post_exec(self):
- if self.isddl:
- self.set_ddl_autocommit(self.root_connection, False)
-
- if self._enable_identity_insert:
- self.cursor.execute(
- "SET IDENTITY_INSERT %s OFF" %
- self.dialect.identifier_preparer.
- format_table(self.compiled.statement.table)
- )
-
- def get_lastrowid(self):
- cursor = self.create_cursor()
- cursor.execute("SELECT @@identity AS lastrowid")
- lastrowid = cursor.fetchone()[0]
- cursor.close()
- return lastrowid
-
-class SybaseSQLCompiler(compiler.SQLCompiler):
- ansi_bind_rules = True
-
- extract_map = util.update_copy(
- compiler.SQLCompiler.extract_map,
- {
- 'doy': 'dayofyear',
- 'dow': 'weekday',
- 'milliseconds': 'millisecond'
- })
-
- def get_select_precolumns(self, select):
- s = select._distinct and "DISTINCT " or ""
- # TODO: don't think Sybase supports
- # bind params for FIRST / TOP
- if select._limit:
- #if select._limit == 1:
- #s += "FIRST "
- #else:
- #s += "TOP %s " % (select._limit,)
- s += "TOP %s " % (select._limit,)
- if select._offset:
- if not select._limit:
- # FIXME: sybase doesn't allow an offset without a limit
- # so use a huge value for TOP here
- s += "TOP 1000000 "
- s += "START AT %s " % (select._offset+1,)
- return s
-
- def get_from_hint_text(self, table, text):
- return text
-
- def limit_clause(self, select):
- # Limit in sybase is after the select keyword
- return ""
-
- def visit_extract(self, extract, **kw):
- field = self.extract_map.get(extract.field, extract.field)
- return 'DATEPART("%s", %s)' % (
- field, self.process(extract.expr, **kw))
-
- def for_update_clause(self, select):
- # "FOR UPDATE" is only allowed on "DECLARE CURSOR"
- # which SQLAlchemy doesn't use
- return ''
-
- def order_by_clause(self, select, **kw):
- kw['literal_binds'] = True
- order_by = self.process(select._order_by_clause, **kw)
-
- # SybaseSQL only allows ORDER BY in subqueries if there is a LIMIT
- if order_by and (not self.is_subquery() or select._limit):
- return " ORDER BY " + order_by
- else:
- return ""
-
-
-class SybaseDDLCompiler(compiler.DDLCompiler):
- def get_column_specification(self, column, **kwargs):
- colspec = self.preparer.format_column(column) + " " + \
- self.dialect.type_compiler.process(column.type)
-
- if column.table is None:
- raise exc.InvalidRequestError(
- "The Sybase dialect requires Table-bound "
- "columns in order to generate DDL")
- seq_col = column.table._autoincrement_column
-
- # install a IDENTITY Sequence if we have an implicit IDENTITY column
- if seq_col is column:
- sequence = isinstance(column.default, sa_schema.Sequence) \
- and column.default
- if sequence:
- start, increment = sequence.start or 1, \
- sequence.increment or 1
- else:
- start, increment = 1, 1
- if (start, increment) == (1, 1):
- colspec += " IDENTITY"
- else:
- # TODO: need correct syntax for this
- colspec += " IDENTITY(%s,%s)" % (start, increment)
- else:
- if column.nullable is not None:
- if not column.nullable or column.primary_key:
- colspec += " NOT NULL"
- else:
- colspec += " NULL"
-
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- return colspec
-
- def visit_drop_index(self, drop):
- index = drop.element
- return "\nDROP INDEX %s.%s" % (
- self.preparer.quote_identifier(index.table.name),
- self.preparer.quote(
- self._index_identifier(index.name), index.quote)
- )
-
-class SybaseIdentifierPreparer(compiler.IdentifierPreparer):
- reserved_words = RESERVED_WORDS
-
-class SybaseDialect(default.DefaultDialect):
- name = 'sybase'
- supports_unicode_statements = False
- supports_sane_rowcount = False
- supports_sane_multi_rowcount = False
-
- supports_native_boolean = False
- supports_unicode_binds = False
- postfetch_lastrowid = True
-
- colspecs = {}
- ischema_names = ischema_names
-
- type_compiler = SybaseTypeCompiler
- statement_compiler = SybaseSQLCompiler
- ddl_compiler = SybaseDDLCompiler
- preparer = SybaseIdentifierPreparer
-
- def _get_default_schema_name(self, connection):
- return connection.scalar(
- text("SELECT user_name() as user_name",
- typemap={'user_name':Unicode})
- )
-
- def initialize(self, connection):
- super(SybaseDialect, self).initialize(connection)
- if self.server_version_info is not None and\
- self.server_version_info < (15, ):
- self.max_identifier_length = 30
- else:
- self.max_identifier_length = 255
-
- @reflection.cache
- def get_table_names(self, connection, schema=None, **kw):
- if schema is None:
- schema = self.default_schema_name
-
- result = connection.execute(
- text("select sysobjects.name from sysobjects, sysusers "
- "where sysobjects.uid=sysusers.uid and "
- "sysusers.name=:schemaname and "
- "sysobjects.type='U'",
- bindparams=[
- bindparam('schemaname', schema)
- ])
- )
- return [r[0] for r in result]
-
- def has_table(self, connection, tablename, schema=None):
- if schema is None:
- schema = self.default_schema_name
-
- result = connection.execute(
- text("select sysobjects.name from sysobjects, sysusers "
- "where sysobjects.uid=sysusers.uid and "
- "sysobjects.name=:tablename and "
- "sysusers.name=:schemaname and "
- "sysobjects.type='U'",
- bindparams=[
- bindparam('tablename', tablename),
- bindparam('schemaname', schema)
- ])
- )
- return result.scalar() is not None
-
- def reflecttable(self, connection, table, include_columns):
- raise NotImplementedError()
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/mxodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/mxodbc.py
deleted file mode 100755
index 756c0b28..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/mxodbc.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# sybase/mxodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for Sybase via mxodbc.
-
-This dialect is a stub only and is likely non functional at this time.
-
-
-"""
-from sqlalchemy.dialects.sybase.base import SybaseDialect, SybaseExecutionContext
-from sqlalchemy.connectors.mxodbc import MxODBCConnector
-
-class SybaseExecutionContext_mxodbc(SybaseExecutionContext):
- pass
-
-class SybaseDialect_mxodbc(MxODBCConnector, SybaseDialect):
- execution_ctx_cls = SybaseExecutionContext_mxodbc
-
-dialect = SybaseDialect_mxodbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pyodbc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pyodbc.py
deleted file mode 100755
index c8480cb4..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pyodbc.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# sybase/pyodbc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for Sybase via pyodbc.
-
-http://pypi.python.org/pypi/pyodbc/
-
-Connect strings are of the form::
-
- sybase+pyodbc://<username>:<password>@<dsn>/
- sybase+pyodbc://<username>:<password>@<host>/<database>
-
-Unicode Support
----------------
-
-The pyodbc driver currently supports usage of these Sybase types with
-Unicode or multibyte strings::
-
- CHAR
- NCHAR
- NVARCHAR
- TEXT
- VARCHAR
-
-Currently *not* supported are::
-
- UNICHAR
- UNITEXT
- UNIVARCHAR
-
-"""
-
-from sqlalchemy.dialects.sybase.base import SybaseDialect,\
- SybaseExecutionContext
-from sqlalchemy.connectors.pyodbc import PyODBCConnector
-from sqlalchemy import types as sqltypes, util, processors
-from sqlalchemy.util.compat import decimal
-
-class _SybNumeric_pyodbc(sqltypes.Numeric):
- """Turns Decimals with adjusted() < -6 into floats.
-
- It's not yet known how to get decimals with many
- significant digits or very large adjusted() into Sybase
- via pyodbc.
-
- """
-
- def bind_processor(self, dialect):
- super_process = super(_SybNumeric_pyodbc,self).\
- bind_processor(dialect)
-
- def process(value):
- if self.asdecimal and \
- isinstance(value, decimal.Decimal):
-
- if value.adjusted() < -6:
- return processors.to_float(value)
-
- if super_process:
- return super_process(value)
- else:
- return value
- return process
-
-class SybaseExecutionContext_pyodbc(SybaseExecutionContext):
- def set_ddl_autocommit(self, connection, value):
- if value:
- connection.autocommit = True
- else:
- connection.autocommit = False
-
-class SybaseDialect_pyodbc(PyODBCConnector, SybaseDialect):
- execution_ctx_cls = SybaseExecutionContext_pyodbc
-
- colspecs = {
- sqltypes.Numeric:_SybNumeric_pyodbc,
- }
-
-dialect = SybaseDialect_pyodbc
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pysybase.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pysybase.py
deleted file mode 100755
index e12cf07d..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/dialects/sybase/pysybase.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# sybase/pysybase.py
-# Copyright (C) 2010-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Support for Sybase via the python-sybase driver.
-
-http://python-sybase.sourceforge.net/
-
-Connect strings are of the form::
-
- sybase+pysybase://<username>:<password>@<dsn>/[database name]
-
-Unicode Support
----------------
-
-The python-sybase driver does not appear to support non-ASCII strings of any
-kind at this time.
-
-"""
-
-from sqlalchemy import types as sqltypes, processors
-from sqlalchemy.dialects.sybase.base import SybaseDialect, \
- SybaseExecutionContext, SybaseSQLCompiler
-
-
-class _SybNumeric(sqltypes.Numeric):
- def result_processor(self, dialect, type_):
- if not self.asdecimal:
- return processors.to_float
- else:
- return sqltypes.Numeric.result_processor(self, dialect, type_)
-
-class SybaseExecutionContext_pysybase(SybaseExecutionContext):
-
- def set_ddl_autocommit(self, dbapi_connection, value):
- if value:
- # call commit() on the Sybase connection directly,
- # to avoid any side effects of calling a Connection
- # transactional method inside of pre_exec()
- dbapi_connection.commit()
-
- def pre_exec(self):
- SybaseExecutionContext.pre_exec(self)
-
- for param in self.parameters:
- for key in list(param):
- param["@" + key] = param[key]
- del param[key]
-
-
-class SybaseSQLCompiler_pysybase(SybaseSQLCompiler):
- def bindparam_string(self, name):
- return "@" + name
-
-class SybaseDialect_pysybase(SybaseDialect):
- driver = 'pysybase'
- execution_ctx_cls = SybaseExecutionContext_pysybase
- statement_compiler = SybaseSQLCompiler_pysybase
-
- colspecs={
- sqltypes.Numeric:_SybNumeric,
- sqltypes.Float:sqltypes.Float
- }
-
- @classmethod
- def dbapi(cls):
- import Sybase
- return Sybase
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username='user', password='passwd')
-
- return ([opts.pop('host')], opts)
-
- def do_executemany(self, cursor, statement, parameters, context=None):
- # calling python-sybase executemany yields:
- # TypeError: string too long for buffer
- for param in parameters:
- cursor.execute(statement, param)
-
- def _get_server_version_info(self, connection):
- vers = connection.scalar("select @@version_number")
- # i.e. 15500, 15000, 12500 == (15, 5, 0, 0), (15, 0, 0, 0),
- # (12, 5, 0, 0)
- return (vers / 1000, vers % 1000 / 100, vers % 100 / 10, vers % 10)
-
- def is_disconnect(self, e, connection, cursor):
- if isinstance(e, (self.dbapi.OperationalError,
- self.dbapi.ProgrammingError)):
- msg = str(e)
- return ('Unable to complete network request to host' in msg or
- 'Invalid connection state' in msg or
- 'Invalid cursor state' in msg)
- else:
- return False
-
-dialect = SybaseDialect_pysybase
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/__init__.py
deleted file mode 100755
index 010cc22d..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/__init__.py
+++ /dev/null
@@ -1,301 +0,0 @@
-# engine/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""SQL connections, SQL execution and high-level DB-API interface.
-
-The engine package defines the basic components used to interface
-DB-API modules with higher-level statement construction,
-connection-management, execution and result contexts. The primary
-"entry point" class into this package is the Engine and it's public
-constructor ``create_engine()``.
-
-This package includes:
-
-base.py
- Defines interface classes and some implementation classes which
- comprise the basic components used to interface between a DB-API,
- constructed and plain-text statements, connections, transactions,
- and results.
-
-default.py
- Contains default implementations of some of the components defined
- in base.py. All current database dialects use the classes in
- default.py as base classes for their own database-specific
- implementations.
-
-strategies.py
- The mechanics of constructing ``Engine`` objects are represented
- here. Defines the ``EngineStrategy`` class which represents how
- to go from arguments specified to the ``create_engine()``
- function, to a fully constructed ``Engine``, including
- initialization of connection pooling, dialects, and specific
- subclasses of ``Engine``.
-
-threadlocal.py
- The ``TLEngine`` class is defined here, which is a subclass of
- the generic ``Engine`` and tracks ``Connection`` and
- ``Transaction`` objects against the identity of the current
- thread. This allows certain programming patterns based around
- the concept of a "thread-local connection" to be possible.
- The ``TLEngine`` is created by using the "threadlocal" engine
- strategy in conjunction with the ``create_engine()`` function.
-
-url.py
- Defines the ``URL`` class which represents the individual
- components of a string URL passed to ``create_engine()``. Also
- defines a basic module-loading strategy for the dialect specifier
- within a URL.
-"""
-
-# not sure what this was used for
-#import sqlalchemy.databases
-
-from sqlalchemy.engine.base import (
- BufferedColumnResultProxy,
- BufferedColumnRow,
- BufferedRowResultProxy,
- Compiled,
- Connectable,
- Connection,
- Dialect,
- Engine,
- ExecutionContext,
- NestedTransaction,
- ResultProxy,
- RootTransaction,
- RowProxy,
- Transaction,
- TwoPhaseTransaction,
- TypeCompiler
- )
-from sqlalchemy.engine import strategies
-from sqlalchemy import util
-
-
-__all__ = (
- 'BufferedColumnResultProxy',
- 'BufferedColumnRow',
- 'BufferedRowResultProxy',
- 'Compiled',
- 'Connectable',
- 'Connection',
- 'Dialect',
- 'Engine',
- 'ExecutionContext',
- 'NestedTransaction',
- 'ResultProxy',
- 'RootTransaction',
- 'RowProxy',
- 'Transaction',
- 'TwoPhaseTransaction',
- 'TypeCompiler',
- 'create_engine',
- 'engine_from_config',
- )
-
-
-default_strategy = 'plain'
-def create_engine(*args, **kwargs):
- """Create a new Engine instance.
-
- The standard method of specifying the engine is via URL as the
- first positional argument, to indicate the appropriate database
- dialect and connection arguments, with additional keyword
- arguments sent as options to the dialect and resulting Engine.
-
- The URL is a string in the form
- ``dialect+driver://user:password@host/dbname[?key=value..]``, where
- ``dialect`` is a database name such as ``mysql``, ``oracle``,
- ``postgresql``, etc., and ``driver`` the name of a DBAPI, such as
- ``psycopg2``, ``pyodbc``, ``cx_oracle``, etc. Alternatively,
- the URL can be an instance of :class:`~sqlalchemy.engine.url.URL`.
-
- `**kwargs` takes a wide variety of options which are routed
- towards their appropriate components. Arguments may be
- specific to the Engine, the underlying Dialect, as well as the
- Pool. Specific dialects also accept keyword arguments that
- are unique to that dialect. Here, we describe the parameters
- that are common to most ``create_engine()`` usage.
-
- :param assert_unicode: Deprecated. A warning is raised in all cases when a non-Unicode
- object is passed when SQLAlchemy would coerce into an encoding
- (note: but **not** when the DBAPI handles unicode objects natively).
- To suppress or raise this warning to an
- error, use the Python warnings filter documented at:
- http://docs.python.org/library/warnings.html
-
- :param connect_args: a dictionary of options which will be
- passed directly to the DBAPI's ``connect()`` method as
- additional keyword arguments.
-
- :param convert_unicode=False: if set to True, all
- String/character based types will convert Python Unicode values to raw
- byte values sent to the DBAPI as bind parameters, and all raw byte values to
- Python Unicode coming out in result sets. This is an
- engine-wide method to provide Unicode conversion across the
- board for those DBAPIs that do not accept Python Unicode objects
- as input. For Unicode conversion on a column-by-column level, use
- the ``Unicode`` column type instead, described in :ref:`types_toplevel`. Note that
- many DBAPIs have the ability to return Python Unicode objects in
- result sets directly - SQLAlchemy will use these modes of operation
- if possible and will also attempt to detect "Unicode returns"
- behavior by the DBAPI upon first connect by the
- :class:`.Engine`. When this is detected, string values in
- result sets are passed through without further processing.
-
- :param creator: a callable which returns a DBAPI connection.
- This creation function will be passed to the underlying
- connection pool and will be used to create all new database
- connections. Usage of this function causes connection
- parameters specified in the URL argument to be bypassed.
-
- :param echo=False: if True, the Engine will log all statements
- as well as a repr() of their parameter lists to the engines
- logger, which defaults to sys.stdout. The ``echo`` attribute of
- ``Engine`` can be modified at any time to turn logging on and
- off. If set to the string ``"debug"``, result rows will be
- printed to the standard output as well. This flag ultimately
- controls a Python logger; see :ref:`dbengine_logging` for
- information on how to configure logging directly.
-
- :param echo_pool=False: if True, the connection pool will log
- all checkouts/checkins to the logging stream, which defaults to
- sys.stdout. This flag ultimately controls a Python logger; see
- :ref:`dbengine_logging` for information on how to configure logging
- directly.
-
- :param encoding='utf-8': the encoding to use for all Unicode
- translations, both by engine-wide unicode conversion as well as
- the ``Unicode`` type object.
-
- :param execution_options: Dictionary execution options which will
- be applied to all connections. See
- :meth:`~sqlalchemy.engine.base.Connection.execution_options`
-
- :param implicit_returning=True: When ``True``, a RETURNING-
- compatible construct, if available, will be used to
- fetch newly generated primary key values when a single row
- INSERT statement is emitted with no existing returning()
- clause. This applies to those backends which support RETURNING
- or a compatible construct, including Postgresql, Firebird, Oracle,
- Microsoft SQL Server. Set this to ``False`` to disable
- the automatic usage of RETURNING.
-
- :param label_length=None: optional integer value which limits
- the size of dynamically generated column labels to that many
- characters. If less than 6, labels are generated as
- "_(counter)". If ``None``, the value of
- ``dialect.max_identifier_length`` is used instead.
-
- :param listeners: A list of one or more
- :class:`~sqlalchemy.interfaces.PoolListener` objects which will
- receive connection pool events.
-
- :param logging_name: String identifier which will be used within
- the "name" field of logging records generated within the
- "sqlalchemy.engine" logger. Defaults to a hexstring of the
- object's id.
-
- :param max_overflow=10: the number of connections to allow in
- connection pool "overflow", that is connections that can be
- opened above and beyond the pool_size setting, which defaults
- to five. this is only used with :class:`~sqlalchemy.pool.QueuePool`.
-
- :param module=None: reference to a Python module object (the module itself, not
- its string name). Specifies an alternate DBAPI module to be used
- by the engine's dialect. Each sub-dialect references a specific DBAPI which
- will be imported before first connect. This parameter causes the
- import to be bypassed, and the given module to be used instead.
- Can be used for testing of DBAPIs as well as to inject "mock"
- DBAPI implementations into the :class:`.Engine`.
-
- :param pool=None: an already-constructed instance of
- :class:`~sqlalchemy.pool.Pool`, such as a
- :class:`~sqlalchemy.pool.QueuePool` instance. If non-None, this
- pool will be used directly as the underlying connection pool
- for the engine, bypassing whatever connection parameters are
- present in the URL argument. For information on constructing
- connection pools manually, see :ref:`pooling_toplevel`.
-
- :param poolclass=None: a :class:`~sqlalchemy.pool.Pool`
- subclass, which will be used to create a connection pool
- instance using the connection parameters given in the URL. Note
- this differs from ``pool`` in that you don't actually
- instantiate the pool in this case, you just indicate what type
- of pool to be used.
-
- :param pool_logging_name: String identifier which will be used within
- the "name" field of logging records generated within the
- "sqlalchemy.pool" logger. Defaults to a hexstring of the object's
- id.
-
- :param pool_size=5: the number of connections to keep open
- inside the connection pool. This used with :class:`~sqlalchemy.pool.QueuePool` as
- well as :class:`~sqlalchemy.pool.SingletonThreadPool`. With
- :class:`~sqlalchemy.pool.QueuePool`, a ``pool_size`` setting
- of 0 indicates no limit; to disable pooling, set ``poolclass`` to
- :class:`~sqlalchemy.pool.NullPool` instead.
-
- :param pool_recycle=-1: this setting causes the pool to recycle
- connections after the given number of seconds has passed. It
- defaults to -1, or no timeout. For example, setting to 3600
- means connections will be recycled after one hour. Note that
- MySQL in particular will disconnect automatically if no
- activity is detected on a connection for eight hours (although
- this is configurable with the MySQLDB connection itself and the
- server configuration as well).
-
- :param pool_timeout=30: number of seconds to wait before giving
- up on getting a connection from the pool. This is only used
- with :class:`~sqlalchemy.pool.QueuePool`.
-
- :param strategy='plain': selects alternate engine implementations.
- Currently available is the ``threadlocal``
- strategy, which is described in :ref:`threadlocal_strategy`.
-
- """
-
- strategy = kwargs.pop('strategy', default_strategy)
- strategy = strategies.strategies[strategy]
- return strategy.create(*args, **kwargs)
-
-def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
- """Create a new Engine instance using a configuration dictionary.
-
- The dictionary is typically produced from a config file where keys
- are prefixed, such as sqlalchemy.url, sqlalchemy.echo, etc. The
- 'prefix' argument indicates the prefix to be searched for.
-
- A select set of keyword arguments will be "coerced" to their
- expected type based on string values. In a future release, this
- functionality will be expanded and include dialect-specific
- arguments.
- """
-
- opts = _coerce_config(configuration, prefix)
- opts.update(kwargs)
- url = opts.pop('url')
- return create_engine(url, **opts)
-
-def _coerce_config(configuration, prefix):
- """Convert configuration values to expected types."""
-
- options = dict((key[len(prefix):], configuration[key])
- for key in configuration
- if key.startswith(prefix))
- for option, type_ in (
- ('convert_unicode', util.bool_or_str('force')),
- ('pool_timeout', int),
- ('echo', util.bool_or_str('debug')),
- ('echo_pool', util.bool_or_str('debug')),
- ('pool_recycle', int),
- ('pool_size', int),
- ('max_overflow', int),
- ('pool_threadlocal', bool),
- ('use_native_unicode', bool),
- ):
- util.coerce_kw_type(options, option, type_)
- return options
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py
deleted file mode 100755
index 31fdd7fb..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py
+++ /dev/null
@@ -1,2995 +0,0 @@
-# engine/base.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-
-"""Basic components for SQL execution and interfacing with DB-API.
-
-Defines the basic components used to interface DB-API modules with
-higher-level statement-construction, connection-management, execution
-and result contexts.
-"""
-
-__all__ = [
- 'BufferedColumnResultProxy', 'BufferedColumnRow',
- 'BufferedRowResultProxy','Compiled', 'Connectable', 'Connection',
- 'Dialect', 'Engine','ExecutionContext', 'NestedTransaction',
- 'ResultProxy', 'RootTransaction','RowProxy', 'SchemaIterator',
- 'StringIO', 'Transaction', 'TwoPhaseTransaction',
- 'connection_memoize']
-
-import inspect, StringIO, sys, operator
-from itertools import izip
-from sqlalchemy import exc, schema, util, types, log, interfaces, \
- event, events
-from sqlalchemy.sql import expression
-from sqlalchemy import processors
-import collections
-
-class Dialect(object):
- """Define the behavior of a specific database and DB-API combination.
-
- Any aspect of metadata definition, SQL query generation,
- execution, result-set handling, or anything else which varies
- between databases is defined under the general category of the
- Dialect. The Dialect acts as a factory for other
- database-specific object implementations including
- ExecutionContext, Compiled, DefaultGenerator, and TypeEngine.
-
- All Dialects implement the following attributes:
-
- name
- identifying name for the dialect from a DBAPI-neutral point of view
- (i.e. 'sqlite')
-
- driver
- identifying name for the dialect's DBAPI
-
- positional
- True if the paramstyle for this Dialect is positional.
-
- paramstyle
- the paramstyle to be used (some DB-APIs support multiple
- paramstyles).
-
- convert_unicode
- True if Unicode conversion should be applied to all ``str``
- types.
-
- encoding
- type of encoding to use for unicode, usually defaults to
- 'utf-8'.
-
- statement_compiler
- a :class:`~Compiled` class used to compile SQL statements
-
- ddl_compiler
- a :class:`~Compiled` class used to compile DDL statements
-
- server_version_info
- a tuple containing a version number for the DB backend in use.
- This value is only available for supporting dialects, and is
- typically populated during the initial connection to the database.
-
- default_schema_name
- the name of the default schema. This value is only available for
- supporting dialects, and is typically populated during the
- initial connection to the database.
-
- execution_ctx_cls
- a :class:`.ExecutionContext` class used to handle statement execution
-
- execute_sequence_format
- either the 'tuple' or 'list' type, depending on what cursor.execute()
- accepts for the second argument (they vary).
-
- preparer
- a :class:`~sqlalchemy.sql.compiler.IdentifierPreparer` class used to
- quote identifiers.
-
- supports_alter
- ``True`` if the database supports ``ALTER TABLE``.
-
- max_identifier_length
- The maximum length of identifier names.
-
- supports_unicode_statements
- Indicate whether the DB-API can receive SQL statements as Python
- unicode strings
-
- supports_unicode_binds
- Indicate whether the DB-API can receive string bind parameters
- as Python unicode strings
-
- supports_sane_rowcount
- Indicate whether the dialect properly implements rowcount for
- ``UPDATE`` and ``DELETE`` statements.
-
- supports_sane_multi_rowcount
- Indicate whether the dialect properly implements rowcount for
- ``UPDATE`` and ``DELETE`` statements when executed via
- executemany.
-
- preexecute_autoincrement_sequences
- True if 'implicit' primary key functions must be executed separately
- in order to get their value. This is currently oriented towards
- Postgresql.
-
- implicit_returning
- use RETURNING or equivalent during INSERT execution in order to load
- newly generated primary keys and other column defaults in one execution,
- which are then available via inserted_primary_key.
- If an insert statement has returning() specified explicitly,
- the "implicit" functionality is not used and inserted_primary_key
- will not be available.
-
- dbapi_type_map
- A mapping of DB-API type objects present in this Dialect's
- DB-API implementation mapped to TypeEngine implementations used
- by the dialect.
-
- This is used to apply types to result sets based on the DB-API
- types present in cursor.description; it only takes effect for
- result sets against textual statements where no explicit
- typemap was present.
-
- colspecs
- A dictionary of TypeEngine classes from sqlalchemy.types mapped
- to subclasses that are specific to the dialect class. This
- dictionary is class-level only and is not accessed from the
- dialect instance itself.
-
- supports_default_values
- Indicates if the construct ``INSERT INTO tablename DEFAULT
- VALUES`` is supported
-
- supports_sequences
- Indicates if the dialect supports CREATE SEQUENCE or similar.
-
- sequences_optional
- If True, indicates if the "optional" flag on the Sequence() construct
- should signal to not generate a CREATE SEQUENCE. Applies only to
- dialects that support sequences. Currently used only to allow Postgresql
- SERIAL to be used on a column that specifies Sequence() for usage on
- other backends.
-
- supports_native_enum
- Indicates if the dialect supports a native ENUM construct.
- This will prevent types.Enum from generating a CHECK
- constraint when that type is used.
-
- supports_native_boolean
- Indicates if the dialect supports a native boolean construct.
- This will prevent types.Boolean from generating a CHECK
- constraint when that type is used.
-
- """
-
- def create_connect_args(self, url):
- """Build DB-API compatible connection arguments.
-
- Given a :class:`~sqlalchemy.engine.url.URL` object, returns a tuple
- consisting of a `*args`/`**kwargs` suitable to send directly
- to the dbapi's connect function.
-
- """
-
- raise NotImplementedError()
-
- @classmethod
- def type_descriptor(cls, typeobj):
- """Transform a generic type to a dialect-specific type.
-
- Dialect classes will usually use the
- :func:`~sqlalchemy.types.adapt_type` function in the types module to
- make this job easy.
-
- The returned result is cached *per dialect class* so can
- contain no dialect-instance state.
-
- """
-
- raise NotImplementedError()
-
- def initialize(self, connection):
- """Called during strategized creation of the dialect with a
- connection.
-
- Allows dialects to configure options based on server version info or
- other properties.
-
- The connection passed here is a SQLAlchemy Connection object,
- with full capabilities.
-
- The initalize() method of the base dialect should be called via
- super().
-
- """
-
- pass
-
- def reflecttable(self, connection, table, include_columns=None):
- """Load table description from the database.
-
- Given a :class:`.Connection` and a
- :class:`~sqlalchemy.schema.Table` object, reflect its columns and
- properties from the database. If include_columns (a list or
- set) is specified, limit the autoload to the given column
- names.
-
- The default implementation uses the
- :class:`~sqlalchemy.engine.reflection.Inspector` interface to
- provide the output, building upon the granular table/column/
- constraint etc. methods of :class:`.Dialect`.
-
- """
-
- raise NotImplementedError()
-
- def get_columns(self, connection, table_name, schema=None, **kw):
- """Return information about columns in `table_name`.
-
- Given a :class:`.Connection`, a string
- `table_name`, and an optional string `schema`, return column
- information as a list of dictionaries with these keys:
-
- name
- the column's name
-
- type
- [sqlalchemy.types#TypeEngine]
-
- nullable
- boolean
-
- default
- the column's default value
-
- autoincrement
- boolean
-
- sequence
- a dictionary of the form
- {'name' : str, 'start' :int, 'increment': int}
-
- Additional column attributes may be present.
- """
-
- raise NotImplementedError()
-
- def get_primary_keys(self, connection, table_name, schema=None, **kw):
- """Return information about primary keys in `table_name`.
-
- Given a :class:`.Connection`, a string
- `table_name`, and an optional string `schema`, return primary
- key information as a list of column names.
-
- """
- raise NotImplementedError()
-
- def get_pk_constraint(self, table_name, schema=None, **kw):
- """Return information about the primary key constraint on
- table_name`.
-
- Given a string `table_name`, and an optional string `schema`, return
- primary key information as a dictionary with these keys:
-
- constrained_columns
- a list of column names that make up the primary key
-
- name
- optional name of the primary key constraint.
-
- """
- raise NotImplementedError()
-
- def get_foreign_keys(self, connection, table_name, schema=None, **kw):
- """Return information about foreign_keys in `table_name`.
-
- Given a :class:`.Connection`, a string
- `table_name`, and an optional string `schema`, return foreign
- key information as a list of dicts with these keys:
-
- name
- the constraint's name
-
- constrained_columns
- a list of column names that make up the foreign key
-
- referred_schema
- the name of the referred schema
-
- referred_table
- the name of the referred table
-
- referred_columns
- a list of column names in the referred table that correspond to
- constrained_columns
- """
-
- raise NotImplementedError()
-
- def get_table_names(self, connection, schema=None, **kw):
- """Return a list of table names for `schema`."""
-
- raise NotImplementedError
-
- def get_view_names(self, connection, schema=None, **kw):
- """Return a list of all view names available in the database.
-
- schema:
- Optional, retrieve names from a non-default schema.
- """
-
- raise NotImplementedError()
-
- def get_view_definition(self, connection, view_name, schema=None, **kw):
- """Return view definition.
-
- Given a :class:`.Connection`, a string
- `view_name`, and an optional string `schema`, return the view
- definition.
- """
-
- raise NotImplementedError()
-
- def get_indexes(self, connection, table_name, schema=None, **kw):
- """Return information about indexes in `table_name`.
-
- Given a :class:`.Connection`, a string
- `table_name` and an optional string `schema`, return index
- information as a list of dictionaries with these keys:
-
- name
- the index's name
-
- column_names
- list of column names in order
-
- unique
- boolean
- """
-
- raise NotImplementedError()
-
- def normalize_name(self, name):
- """convert the given name to lowercase if it is detected as
- case insensitive.
-
- this method is only used if the dialect defines
- requires_name_normalize=True.
-
- """
- raise NotImplementedError()
-
- def denormalize_name(self, name):
- """convert the given name to a case insensitive identifier
- for the backend if it is an all-lowercase name.
-
- this method is only used if the dialect defines
- requires_name_normalize=True.
-
- """
- raise NotImplementedError()
-
- def has_table(self, connection, table_name, schema=None):
- """Check the existence of a particular table in the database.
-
- Given a :class:`.Connection` object and a string
- `table_name`, return True if the given table (possibly within
- the specified `schema`) exists in the database, False
- otherwise.
- """
-
- raise NotImplementedError()
-
- def has_sequence(self, connection, sequence_name, schema=None):
- """Check the existence of a particular sequence in the database.
-
- Given a :class:`.Connection` object and a string
- `sequence_name`, return True if the given sequence exists in
- the database, False otherwise.
- """
-
- raise NotImplementedError()
-
- def _get_server_version_info(self, connection):
- """Retrieve the server version info from the given connection.
-
- This is used by the default implementation to populate the
- "server_version_info" attribute and is called exactly
- once upon first connect.
-
- """
-
- raise NotImplementedError()
-
- def _get_default_schema_name(self, connection):
- """Return the string name of the currently selected schema from
- the given connection.
-
- This is used by the default implementation to populate the
- "default_schema_name" attribute and is called exactly
- once upon first connect.
-
- """
-
- raise NotImplementedError()
-
- def do_begin(self, connection):
- """Provide an implementation of *connection.begin()*, given a
- DB-API connection."""
-
- raise NotImplementedError()
-
- def do_rollback(self, connection):
- """Provide an implementation of *connection.rollback()*, given
- a DB-API connection."""
-
- raise NotImplementedError()
-
- def create_xid(self):
- """Create a two-phase transaction ID.
-
- This id will be passed to do_begin_twophase(),
- do_rollback_twophase(), do_commit_twophase(). Its format is
- unspecified.
- """
-
- raise NotImplementedError()
-
- def do_commit(self, connection):
- """Provide an implementation of *connection.commit()*, given a
- DB-API connection."""
-
- raise NotImplementedError()
-
- def do_savepoint(self, connection, name):
- """Create a savepoint with the given name on a SQLAlchemy
- connection."""
-
- raise NotImplementedError()
-
- def do_rollback_to_savepoint(self, connection, name):
- """Rollback a SQL Alchemy connection to the named savepoint."""
-
- raise NotImplementedError()
-
- def do_release_savepoint(self, connection, name):
- """Release the named savepoint on a SQL Alchemy connection."""
-
- raise NotImplementedError()
-
- def do_begin_twophase(self, connection, xid):
- """Begin a two phase transaction on the given connection."""
-
- raise NotImplementedError()
-
- def do_prepare_twophase(self, connection, xid):
- """Prepare a two phase transaction on the given connection."""
-
- raise NotImplementedError()
-
- def do_rollback_twophase(self, connection, xid, is_prepared=True,
- recover=False):
- """Rollback a two phase transaction on the given connection."""
-
- raise NotImplementedError()
-
- def do_commit_twophase(self, connection, xid, is_prepared=True,
- recover=False):
- """Commit a two phase transaction on the given connection."""
-
- raise NotImplementedError()
-
- def do_recover_twophase(self, connection):
- """Recover list of uncommited prepared two phase transaction
- identifiers on the given connection."""
-
- raise NotImplementedError()
-
- def do_executemany(self, cursor, statement, parameters, context=None):
- """Provide an implementation of *cursor.executemany(statement,
- parameters)*."""
-
- raise NotImplementedError()
-
- def do_execute(self, cursor, statement, parameters, context=None):
- """Provide an implementation of *cursor.execute(statement,
- parameters)*."""
-
- raise NotImplementedError()
-
- def is_disconnect(self, e, connection, cursor):
- """Return True if the given DB-API error indicates an invalid
- connection"""
-
- raise NotImplementedError()
-
- def connect(self):
- """return a callable which sets up a newly created DBAPI connection.
-
- The callable accepts a single argument "conn" which is the
- DBAPI connection itself. It has no return value.
-
- This is used to set dialect-wide per-connection options such as
- isolation modes, unicode modes, etc.
-
- If a callable is returned, it will be assembled into a pool listener
- that receives the direct DBAPI connection, with all wrappers removed.
-
- If None is returned, no listener will be generated.
-
- """
- return None
-
- def reset_isolation_level(self, dbapi_conn):
- """Given a DBAPI connection, revert its isolation to the default."""
-
- raise NotImplementedError()
-
- def set_isolation_level(self, dbapi_conn, level):
- """Given a DBAPI connection, set its isolation level."""
-
- raise NotImplementedError()
-
- def get_isolation_level(self, dbapi_conn):
- """Given a DBAPI connection, return its isolation level."""
-
- raise NotImplementedError()
-
-
-class ExecutionContext(object):
- """A messenger object for a Dialect that corresponds to a single
- execution.
-
- ExecutionContext should have these data members:
-
- connection
- Connection object which can be freely used by default value
- generators to execute SQL. This Connection should reference the
- same underlying connection/transactional resources of
- root_connection.
-
- root_connection
- Connection object which is the source of this ExecutionContext. This
- Connection may have close_with_result=True set, in which case it can
- only be used once.
-
- dialect
- dialect which created this ExecutionContext.
-
- cursor
- DB-API cursor procured from the connection,
-
- compiled
- if passed to constructor, sqlalchemy.engine.base.Compiled object
- being executed,
-
- statement
- string version of the statement to be executed. Is either
- passed to the constructor, or must be created from the
- sql.Compiled object by the time pre_exec() has completed.
-
- parameters
- bind parameters passed to the execute() method. For compiled
- statements, this is a dictionary or list of dictionaries. For
- textual statements, it should be in a format suitable for the
- dialect's paramstyle (i.e. dict or list of dicts for non
- positional, list or list of lists/tuples for positional).
-
- isinsert
- True if the statement is an INSERT.
-
- isupdate
- True if the statement is an UPDATE.
-
- should_autocommit
- True if the statement is a "committable" statement.
-
- postfetch_cols
- a list of Column objects for which a server-side default or
- inline SQL expression value was fired off. Applies to inserts
- and updates.
- """
-
- def create_cursor(self):
- """Return a new cursor generated from this ExecutionContext's
- connection.
-
- Some dialects may wish to change the behavior of
- connection.cursor(), such as postgresql which may return a PG
- "server side" cursor.
- """
-
- raise NotImplementedError()
-
- def pre_exec(self):
- """Called before an execution of a compiled statement.
-
- If a compiled statement was passed to this ExecutionContext,
- the `statement` and `parameters` datamembers must be
- initialized after this statement is complete.
- """
-
- raise NotImplementedError()
-
- def post_exec(self):
- """Called after the execution of a compiled statement.
-
- If a compiled statement was passed to this ExecutionContext,
- the `last_insert_ids`, `last_inserted_params`, etc.
- datamembers should be available after this method completes.
- """
-
- raise NotImplementedError()
-
- def result(self):
- """Return a result object corresponding to this ExecutionContext.
-
- Returns a ResultProxy.
- """
-
- raise NotImplementedError()
-
- def handle_dbapi_exception(self, e):
- """Receive a DBAPI exception which occurred upon execute, result
- fetch, etc."""
-
- raise NotImplementedError()
-
- def should_autocommit_text(self, statement):
- """Parse the given textual statement and return True if it refers to
- a "committable" statement"""
-
- raise NotImplementedError()
-
- def lastrow_has_defaults(self):
- """Return True if the last INSERT or UPDATE row contained
- inlined or database-side defaults.
- """
-
- raise NotImplementedError()
-
- def get_rowcount(self):
- """Return the number of rows produced (by a SELECT query)
- or affected (by an INSERT/UPDATE/DELETE statement).
-
- Note that this row count may not be properly implemented
- in some dialects; this is indicated by the
- ``supports_sane_rowcount`` and ``supports_sane_multi_rowcount``
- dialect attributes.
-
- """
-
- raise NotImplementedError()
-
-
-class Compiled(object):
- """Represent a compiled SQL or DDL expression.
-
- The ``__str__`` method of the ``Compiled`` object should produce
- the actual text of the statement. ``Compiled`` objects are
- specific to their underlying database dialect, and also may
- or may not be specific to the columns referenced within a
- particular set of bind parameters. In no case should the
- ``Compiled`` object be dependent on the actual values of those
- bind parameters, even though it may reference those values as
- defaults.
- """
-
- def __init__(self, dialect, statement, bind=None):
- """Construct a new ``Compiled`` object.
-
- :param dialect: ``Dialect`` to compile against.
-
- :param statement: ``ClauseElement`` to be compiled.
-
- :param bind: Optional Engine or Connection to compile this
- statement against.
- """
-
- self.dialect = dialect
- self.bind = bind
- if statement is not None:
- self.statement = statement
- self.can_execute = statement.supports_execution
- self.string = self.process(self.statement)
-
- @util.deprecated("0.7", ":class:`.Compiled` objects now compile "
- "within the constructor.")
- def compile(self):
- """Produce the internal string representation of this element."""
- pass
-
- @property
- def sql_compiler(self):
- """Return a Compiled that is capable of processing SQL expressions.
-
- If this compiler is one, it would likely just return 'self'.
-
- """
-
- raise NotImplementedError()
-
- def process(self, obj, **kwargs):
- return obj._compiler_dispatch(self, **kwargs)
-
- def __str__(self):
- """Return the string text of the generated SQL or DDL."""
-
- return self.string or ''
-
- def construct_params(self, params=None):
- """Return the bind params for this compiled object.
-
- :param params: a dict of string/object pairs whos values will
- override bind values compiled in to the
- statement.
- """
-
- raise NotImplementedError()
-
- @property
- def params(self):
- """Return the bind params for this compiled object."""
- return self.construct_params()
-
- def execute(self, *multiparams, **params):
- """Execute this compiled object."""
-
- e = self.bind
- if e is None:
- raise exc.UnboundExecutionError(
- "This Compiled object is not bound to any Engine "
- "or Connection.")
- return e._execute_compiled(self, multiparams, params)
-
- def scalar(self, *multiparams, **params):
- """Execute this compiled object and return the result's
- scalar value."""
-
- return self.execute(*multiparams, **params).scalar()
-
-
-class TypeCompiler(object):
- """Produces DDL specification for TypeEngine objects."""
-
- def __init__(self, dialect):
- self.dialect = dialect
-
- def process(self, type_):
- return type_._compiler_dispatch(self)
-
-
-class Connectable(object):
- """Interface for an object which supports execution of SQL constructs.
-
- The two implementations of ``Connectable`` are :class:`.Connection` and
- :class:`.Engine`.
-
- Connectable must also implement the 'dialect' member which references a
- :class:`.Dialect` instance.
- """
-
- def contextual_connect(self):
- """Return a Connection object which may be part of an ongoing
- context."""
-
- raise NotImplementedError()
-
- def create(self, entity, **kwargs):
- """Create a table or index given an appropriate schema object."""
-
- raise NotImplementedError()
-
- def drop(self, entity, **kwargs):
- """Drop a table or index given an appropriate schema object."""
-
- raise NotImplementedError()
-
- def execute(self, object, *multiparams, **params):
- """Executes the given construct and returns a :class:`.ResultProxy`."""
- raise NotImplementedError()
-
- def scalar(self, object, *multiparams, **params):
- """Executes and returns the first column of the first row.
-
- The underlying cursor is closed after execution.
- """
- raise NotImplementedError()
-
- def _execute_clauseelement(self, elem, multiparams=None, params=None):
- raise NotImplementedError()
-
-
-class Connection(Connectable):
- """Provides high-level functionality for a wrapped DB-API connection.
-
- Provides execution support for string-based SQL statements as well as
- :class:`.ClauseElement`, :class:`.Compiled` and :class:`.DefaultGenerator`
- objects. Provides a :meth:`begin` method to return :class:`.Transaction`
- objects.
-
- The Connection object is **not** thread-safe. While a Connection can be
- shared among threads using properly synchronized access, it is still
- possible that the underlying DBAPI connection may not support shared
- access between threads. Check the DBAPI documentation for details.
-
- The Connection object represents a single dbapi connection checked out
- from the connection pool. In this state, the connection pool has no affect
- upon the connection, including its expiration or timeout state. For the
- connection pool to properly manage connections, connections should be
- returned to the connection pool (i.e. ``connection.close()``) whenever the
- connection is not in use.
-
- .. index::
- single: thread safety; Connection
-
- """
-
- def __init__(self, engine, connection=None, close_with_result=False,
- _branch=False, _execution_options=None):
- """Construct a new Connection.
-
- The constructor here is not public and is only called only by an
- :class:`.Engine`. See :meth:`.Engine.connect` and
- :meth:`.Engine.contextual_connect` methods.
-
- """
- self.engine = engine
- self.dialect = engine.dialect
- self.__connection = connection or engine.raw_connection()
- self.__transaction = None
- self.should_close_with_result = close_with_result
- self.__savepoint_seq = 0
- self.__branch = _branch
- self.__invalid = False
- self._has_events = engine._has_events
- self._echo = self.engine._should_log_info()
- if _execution_options:
- self._execution_options =\
- engine._execution_options.union(_execution_options)
- else:
- self._execution_options = engine._execution_options
-
- def _branch(self):
- """Return a new Connection which references this Connection's
- engine and connection; but does not have close_with_result enabled,
- and also whose close() method does nothing.
-
- This is used to execute "sub" statements within a single execution,
- usually an INSERT statement.
- """
-
- return self.engine._connection_cls(
- self.engine,
- self.__connection, _branch=True)
-
- def _clone(self):
- """Create a shallow copy of this Connection.
-
- """
- c = self.__class__.__new__(self.__class__)
- c.__dict__ = self.__dict__.copy()
- return c
-
- def execution_options(self, **opt):
- """ Set non-SQL options for the connection which take effect
- during execution.
-
- The method returns a copy of this :class:`.Connection` which references
- the same underlying DBAPI connection, but also defines the given
- execution options which will take effect for a call to
- :meth:`execute`. As the new :class:`.Connection` references the same
- underlying resource, it is probably best to ensure that the copies
- would be discarded immediately, which is implicit if used as in::
-
- result = connection.execution_options(stream_results=True).\\
- execute(stmt)
-
- :meth:`.Connection.execution_options` accepts all options as those
- accepted by :meth:`.Executable.execution_options`. Additionally,
- it includes options that are applicable only to
- :class:`.Connection`.
-
- :param autocommit: Available on: Connection, statement.
- When True, a COMMIT will be invoked after execution
- when executed in 'autocommit' mode, i.e. when an explicit
- transaction is not begun on the connection. Note that DBAPI
- connections by default are always in a transaction - SQLAlchemy uses
- rules applied to different kinds of statements to determine if
- COMMIT will be invoked in order to provide its "autocommit" feature.
- Typically, all INSERT/UPDATE/DELETE statements as well as
- CREATE/DROP statements have autocommit behavior enabled; SELECT
- constructs do not. Use this option when invoking a SELECT or other
- specific SQL construct where COMMIT is desired (typically when
- calling stored procedures and such), and an explicit
- transaction is not in progress.
-
- :param compiled_cache: Available on: Connection.
- A dictionary where :class:`.Compiled` objects
- will be cached when the :class:`.Connection` compiles a clause
- expression into a :class:`.Compiled` object.
- It is the user's responsibility to
- manage the size of this dictionary, which will have keys
- corresponding to the dialect, clause element, the column
- names within the VALUES or SET clause of an INSERT or UPDATE,
- as well as the "batch" mode for an INSERT or UPDATE statement.
- The format of this dictionary is not guaranteed to stay the
- same in future releases.
-
- Note that the ORM makes use of its own "compiled" caches for
- some operations, including flush operations. The caching
- used by the ORM internally supersedes a cache dictionary
- specified here.
-
- :param isolation_level: Available on: Connection.
- Set the transaction isolation level for
- the lifespan of this connection. Valid values include
- those string values accepted by the ``isolation_level``
- parameter passed to :func:`.create_engine`, and are
- database specific, including those for :ref:`sqlite_toplevel`,
- :ref:`postgresql_toplevel` - see those dialect's documentation
- for further info.
-
- Note that this option necessarily affects the underying
- DBAPI connection for the lifespan of the originating
- :class:`.Connection`, and is not per-execution. This
- setting is not removed until the underying DBAPI connection
- is returned to the connection pool, i.e.
- the :meth:`.Connection.close` method is called.
-
- :param stream_results: Available on: Connection, statement.
- Indicate to the dialect that results should be
- "streamed" and not pre-buffered, if possible. This is a limitation
- of many DBAPIs. The flag is currently understood only by the
- psycopg2 dialect.
-
- """
- c = self._clone()
- c._execution_options = c._execution_options.union(opt)
- if 'isolation_level' in opt:
- c._set_isolation_level()
- return c
-
- def _set_isolation_level(self):
- self.dialect.set_isolation_level(self.connection,
- self._execution_options['isolation_level'])
- self.connection._connection_record.finalize_callback = \
- self.dialect.reset_isolation_level
-
- @property
- def closed(self):
- """Return True if this connection is closed."""
-
- return not self.__invalid and '_Connection__connection' \
- not in self.__dict__
-
- @property
- def invalidated(self):
- """Return True if this connection was invalidated."""
-
- return self.__invalid
-
- @property
- def connection(self):
- "The underlying DB-API connection managed by this Connection."
-
- try:
- return self.__connection
- except AttributeError:
- return self._revalidate_connection()
-
- def _revalidate_connection(self):
- if self.__invalid:
- if self.__transaction is not None:
- raise exc.InvalidRequestError(
- "Can't reconnect until invalid "
- "transaction is rolled back")
- self.__connection = self.engine.raw_connection()
- self.__invalid = False
- return self.__connection
- raise exc.ResourceClosedError("This Connection is closed")
-
- @property
- def _connection_is_valid(self):
- # use getattr() for is_valid to support exceptions raised in
- # dialect initializer, where the connection is not wrapped in
- # _ConnectionFairy
-
- return getattr(self.__connection, 'is_valid', False)
-
- @property
- def info(self):
- """A collection of per-DB-API connection instance properties."""
-
- return self.connection.info
-
- def connect(self):
- """Returns self.
-
- This ``Connectable`` interface method returns self, allowing
- Connections to be used interchangably with Engines in most
- situations that require a bind.
- """
-
- return self
-
- def contextual_connect(self, **kwargs):
- """Returns self.
-
- This ``Connectable`` interface method returns self, allowing
- Connections to be used interchangably with Engines in most
- situations that require a bind.
- """
-
- return self
-
- def invalidate(self, exception=None):
- """Invalidate the underlying DBAPI connection associated with
- this Connection.
-
- The underlying DB-API connection is literally closed (if
- possible), and is discarded. Its source connection pool will
- typically lazily create a new connection to replace it.
-
- Upon the next usage, this Connection will attempt to reconnect
- to the pool with a new connection.
-
- Transactions in progress remain in an "opened" state (even though the
- actual transaction is gone); these must be explicitly rolled back
- before a reconnect on this Connection can proceed. This is to prevent
- applications from accidentally continuing their transactional
- operations in a non-transactional state.
-
- """
- if self.invalidated:
- return
-
- if self.closed:
- raise exc.ResourceClosedError("This Connection is closed")
-
- if self._connection_is_valid:
- self.__connection.invalidate(exception)
- del self.__connection
- self.__invalid = True
-
-
- def detach(self):
- """Detach the underlying DB-API connection from its connection pool.
-
- This Connection instance will remain useable. When closed,
- the DB-API connection will be literally closed and not
- returned to its pool. The pool will typically lazily create a
- new connection to replace the detached connection.
-
- This method can be used to insulate the rest of an application
- from a modified state on a connection (such as a transaction
- isolation level or similar). Also see
- :class:`~sqlalchemy.interfaces.PoolListener` for a mechanism to modify
- connection state when connections leave and return to their
- connection pool.
- """
-
- self.__connection.detach()
-
- def begin(self):
- """Begin a transaction and return a Transaction handle.
-
- Repeated calls to ``begin`` on the same Connection will create
- a lightweight, emulated nested transaction. Only the
- outermost transaction may ``commit``. Calls to ``commit`` on
- inner transactions are ignored. Any transaction in the
- hierarchy may ``rollback``, however.
- """
-
- if self.__transaction is None:
- self.__transaction = RootTransaction(self)
- return self.__transaction
- else:
- return Transaction(self, self.__transaction)
-
- def begin_nested(self):
- """Begin a nested transaction and return a Transaction handle.
-
- Nested transactions require SAVEPOINT support in the
- underlying database. Any transaction in the hierarchy may
- ``commit`` and ``rollback``, however the outermost transaction
- still controls the overall ``commit`` or ``rollback`` of the
- transaction of a whole.
- """
-
- if self.__transaction is None:
- self.__transaction = RootTransaction(self)
- else:
- self.__transaction = NestedTransaction(self, self.__transaction)
- return self.__transaction
-
- def begin_twophase(self, xid=None):
- """Begin a two-phase or XA transaction and return a Transaction
- handle.
-
- :param xid: the two phase transaction id. If not supplied, a
- random id will be generated.
-
- """
-
- if self.__transaction is not None:
- raise exc.InvalidRequestError(
- "Cannot start a two phase transaction when a transaction "
- "is already in progress.")
- if xid is None:
- xid = self.engine.dialect.create_xid();
- self.__transaction = TwoPhaseTransaction(self, xid)
- return self.__transaction
-
- def recover_twophase(self):
- return self.engine.dialect.do_recover_twophase(self)
-
- def rollback_prepared(self, xid, recover=False):
- self.engine.dialect.do_rollback_twophase(self, xid, recover=recover)
-
- def commit_prepared(self, xid, recover=False):
- self.engine.dialect.do_commit_twophase(self, xid, recover=recover)
-
- def in_transaction(self):
- """Return True if a transaction is in progress."""
-
- return self.__transaction is not None
-
- def _begin_impl(self):
- if self._echo:
- self.engine.logger.info("BEGIN (implicit)")
-
- if self._has_events:
- self.engine.dispatch.begin(self)
-
- try:
- self.engine.dialect.do_begin(self.connection)
- except Exception, e:
- self._handle_dbapi_exception(e, None, None, None, None)
- raise
-
- def _rollback_impl(self):
- if self._has_events:
- self.engine.dispatch.rollback(self)
-
- if not self.closed and not self.invalidated and \
- self._connection_is_valid:
- if self._echo:
- self.engine.logger.info("ROLLBACK")
- try:
- self.engine.dialect.do_rollback(self.connection)
- self.__transaction = None
- except Exception, e:
- self._handle_dbapi_exception(e, None, None, None, None)
- raise
- else:
- self.__transaction = None
-
- def _commit_impl(self):
- if self._has_events:
- self.engine.dispatch.commit(self)
-
- if self._echo:
- self.engine.logger.info("COMMIT")
- try:
- self.engine.dialect.do_commit(self.connection)
- self.__transaction = None
- except Exception, e:
- self._handle_dbapi_exception(e, None, None, None, None)
- raise
-
- def _savepoint_impl(self, name=None):
- if self._has_events:
- self.engine.dispatch.savepoint(self, name)
-
- if name is None:
- self.__savepoint_seq += 1
- name = 'sa_savepoint_%s' % self.__savepoint_seq
- if self._connection_is_valid:
- self.engine.dialect.do_savepoint(self, name)
- return name
-
- def _rollback_to_savepoint_impl(self, name, context):
- if self._has_events:
- self.engine.dispatch.rollback_savepoint(self, name, context)
-
- if self._connection_is_valid:
- self.engine.dialect.do_rollback_to_savepoint(self, name)
- self.__transaction = context
-
- def _release_savepoint_impl(self, name, context):
- if self._has_events:
- self.engine.dispatch.release_savepoint(self, name, context)
-
- if self._connection_is_valid:
- self.engine.dialect.do_release_savepoint(self, name)
- self.__transaction = context
-
- def _begin_twophase_impl(self, xid):
- if self._has_events:
- self.engine.dispatch.begin_twophase(self, xid)
-
- if self._connection_is_valid:
- self.engine.dialect.do_begin_twophase(self, xid)
-
- def _prepare_twophase_impl(self, xid):
- if self._has_events:
- self.engine.dispatch.prepare_twophase(self, xid)
-
- if self._connection_is_valid:
- assert isinstance(self.__transaction, TwoPhaseTransaction)
- self.engine.dialect.do_prepare_twophase(self, xid)
-
- def _rollback_twophase_impl(self, xid, is_prepared):
- if self._has_events:
- self.engine.dispatch.rollback_twophase(self, xid, is_prepared)
-
- if self._connection_is_valid:
- assert isinstance(self.__transaction, TwoPhaseTransaction)
- self.engine.dialect.do_rollback_twophase(self, xid, is_prepared)
- self.__transaction = None
-
- def _commit_twophase_impl(self, xid, is_prepared):
- if self._has_events:
- self.engine.dispatch.commit_twophase(self, xid, is_prepared)
-
- if self._connection_is_valid:
- assert isinstance(self.__transaction, TwoPhaseTransaction)
- self.engine.dialect.do_commit_twophase(self, xid, is_prepared)
- self.__transaction = None
-
- def _autorollback(self):
- if not self.in_transaction():
- self._rollback_impl()
-
- def close(self):
- """Close this Connection."""
-
- try:
- conn = self.__connection
- except AttributeError:
- return
- if not self.__branch:
- conn.close()
- self.__invalid = False
- del self.__connection
- self.__transaction = None
-
- def scalar(self, object, *multiparams, **params):
- """Executes and returns the first column of the first row.
-
- The underlying result/cursor is closed after execution.
- """
-
- return self.execute(object, *multiparams, **params).scalar()
-
- def execute(self, object, *multiparams, **params):
- """Executes the given construct and returns a :class:`.ResultProxy`.
-
- The construct can be one of:
-
- * a textual SQL string
- * any :class:`.ClauseElement` construct that is also
- a subclass of :class:`.Executable`, such as a
- :func:`expression.select` construct
- * a :class:`.FunctionElement`, such as that generated
- by :attr:`.func`, will be automatically wrapped in
- a SELECT statement, which is then executed.
- * a :class:`.DDLElement` object
- * a :class:`.DefaultGenerator` object
- * a :class:`.Compiled` object
-
- """
- for c in type(object).__mro__:
- if c in Connection.executors:
- return Connection.executors[c](
- self,
- object,
- multiparams,
- params)
- else:
- raise exc.InvalidRequestError(
- "Unexecutable object type: %s" %
- type(object))
-
- def __distill_params(self, multiparams, params):
- """Given arguments from the calling form *multiparams, **params,
- return a list of bind parameter structures, usually a list of
- dictionaries.
-
- In the case of 'raw' execution which accepts positional parameters,
- it may be a list of tuples or lists.
-
- """
-
- if not multiparams:
- if params:
- return [params]
- else:
- return []
- elif len(multiparams) == 1:
- zero = multiparams[0]
- if isinstance(zero, (list, tuple)):
- if not zero or hasattr(zero[0], '__iter__'):
- return zero
- else:
- return [zero]
- elif hasattr(zero, 'keys'):
- return [zero]
- else:
- return [[zero]]
- else:
- if hasattr(multiparams[0], '__iter__'):
- return multiparams
- else:
- return [multiparams]
-
- def _execute_function(self, func, multiparams, params):
- """Execute a sql.FunctionElement object."""
-
- return self._execute_clauseelement(func.select(),
- multiparams, params)
-
- def _execute_default(self, default, multiparams, params):
- """Execute a schema.ColumnDefault object."""
-
- if self._has_events:
- for fn in self.engine.dispatch.before_execute:
- default, multiparams, params = \
- fn(self, default, multiparams, params)
-
- try:
- try:
- conn = self.__connection
- except AttributeError:
- conn = self._revalidate_connection()
-
- dialect = self.dialect
- ctx = dialect.execution_ctx_cls._init_default(
- dialect, self, conn)
- except Exception, e:
- self._handle_dbapi_exception(e, None, None, None, None)
- raise
-
- ret = ctx._exec_default(default, None)
- if self.should_close_with_result:
- self.close()
-
- if self._has_events:
- self.engine.dispatch.after_execute(self,
- default, multiparams, params, ret)
-
- return ret
-
- def _execute_ddl(self, ddl, multiparams, params):
- """Execute a schema.DDL object."""
-
- if self._has_events:
- for fn in self.engine.dispatch.before_execute:
- ddl, multiparams, params = \
- fn(self, ddl, multiparams, params)
-
- dialect = self.dialect
-
- compiled = ddl.compile(dialect=dialect)
- ret = self._execute_context(
- dialect,
- dialect.execution_ctx_cls._init_ddl,
- compiled,
- None,
- compiled
- )
- if self._has_events:
- self.engine.dispatch.after_execute(self,
- ddl, multiparams, params, ret)
- return ret
-
- def _execute_clauseelement(self, elem, multiparams, params):
- """Execute a sql.ClauseElement object."""
-
- if self._has_events:
- for fn in self.engine.dispatch.before_execute:
- elem, multiparams, params = \
- fn(self, elem, multiparams, params)
-
- distilled_params = self.__distill_params(multiparams, params)
- if distilled_params:
- keys = distilled_params[0].keys()
- else:
- keys = []
-
- dialect = self.dialect
- if 'compiled_cache' in self._execution_options:
- key = dialect, elem, tuple(keys), len(distilled_params) > 1
- if key in self._execution_options['compiled_cache']:
- compiled_sql = self._execution_options['compiled_cache'][key]
- else:
- compiled_sql = elem.compile(
- dialect=dialect, column_keys=keys,
- inline=len(distilled_params) > 1)
- self._execution_options['compiled_cache'][key] = compiled_sql
- else:
- compiled_sql = elem.compile(
- dialect=dialect, column_keys=keys,
- inline=len(distilled_params) > 1)
-
-
- ret = self._execute_context(
- dialect,
- dialect.execution_ctx_cls._init_compiled,
- compiled_sql,
- distilled_params,
- compiled_sql, distilled_params
- )
- if self._has_events:
- self.engine.dispatch.after_execute(self,
- elem, multiparams, params, ret)
- return ret
-
- def _execute_compiled(self, compiled, multiparams, params):
- """Execute a sql.Compiled object."""
-
- if self._has_events:
- for fn in self.engine.dispatch.before_execute:
- compiled, multiparams, params = \
- fn(self, compiled, multiparams, params)
-
- dialect = self.dialect
- parameters=self.__distill_params(multiparams, params)
- ret = self._execute_context(
- dialect,
- dialect.execution_ctx_cls._init_compiled,
- compiled,
- parameters,
- compiled, parameters
- )
- if self._has_events:
- self.engine.dispatch.after_execute(self,
- compiled, multiparams, params, ret)
- return ret
-
- def _execute_text(self, statement, multiparams, params):
- """Execute a string SQL statement."""
-
- if self._has_events:
- for fn in self.engine.dispatch.before_execute:
- statement, multiparams, params = \
- fn(self, statement, multiparams, params)
-
- dialect = self.dialect
- parameters = self.__distill_params(multiparams, params)
- ret = self._execute_context(
- dialect,
- dialect.execution_ctx_cls._init_statement,
- statement,
- parameters,
- statement, parameters
- )
- if self._has_events:
- self.engine.dispatch.after_execute(self,
- statement, multiparams, params, ret)
- return ret
-
- def _execute_context(self, dialect, constructor,
- statement, parameters,
- *args):
- """Create an :class:`.ExecutionContext` and execute, returning
- a :class:`.ResultProxy`."""
-
- try:
- try:
- conn = self.__connection
- except AttributeError:
- conn = self._revalidate_connection()
-
- context = constructor(dialect, self, conn, *args)
- except Exception, e:
- self._handle_dbapi_exception(e,
- str(statement), parameters,
- None, None)
- raise
-
- if context.compiled:
- context.pre_exec()
-
- cursor, statement, parameters = context.cursor, \
- context.statement, \
- context.parameters
-
- if not context.executemany:
- parameters = parameters[0]
-
- if self._has_events:
- for fn in self.engine.dispatch.before_cursor_execute:
- statement, parameters = \
- fn(self, cursor, statement, parameters,
- context, context.executemany)
-
- if self._echo:
- self.engine.logger.info(statement)
- self.engine.logger.info("%r", parameters)
- try:
- if context.executemany:
- self.dialect.do_executemany(
- cursor,
- statement,
- parameters,
- context)
- else:
- self.dialect.do_execute(
- cursor,
- statement,
- parameters,
- context)
- except Exception, e:
- self._handle_dbapi_exception(
- e,
- statement,
- parameters,
- cursor,
- context)
- raise
-
-
- if self._has_events:
- self.engine.dispatch.after_cursor_execute(self, cursor,
- statement,
- parameters,
- context,
- context.executemany)
-
- if context.compiled:
- context.post_exec()
-
- if context.isinsert and not context.executemany:
- context.post_insert()
-
- # create a resultproxy, get rowcount/implicit RETURNING
- # rows, close cursor if no further results pending
- result = context.get_result_proxy()
-
- if context.isinsert:
- if context._is_implicit_returning:
- context._fetch_implicit_returning(result)
- result.close(_autoclose_connection=False)
- elif not context._is_explicit_returning:
- result.close(_autoclose_connection=False)
- elif result._metadata is None:
- # no results, get rowcount
- # (which requires open cursor on some drivers
- # such as kintersbasdb, mxodbc),
- result.rowcount
- result.close(_autoclose_connection=False)
-
- if self.__transaction is None and context.should_autocommit:
- self._commit_impl()
-
- if result.closed and self.should_close_with_result:
- self.close()
-
- return result
-
- def _cursor_execute(self, cursor, statement, parameters):
- """Execute a statement + params on the given cursor.
-
- Adds appropriate logging and exception handling.
-
- This method is used by DefaultDialect for special-case
- executions, such as for sequences and column defaults.
- The path of statement execution in the majority of cases
- terminates at _execute_context().
-
- """
- if self._echo:
- self.engine.logger.info(statement)
- self.engine.logger.info("%r", parameters)
- try:
- self.dialect.do_execute(
- cursor,
- statement,
- parameters)
- except Exception, e:
- self._handle_dbapi_exception(
- e,
- statement,
- parameters,
- cursor,
- None)
- raise
-
- def _safe_close_cursor(self, cursor):
- """Close the given cursor, catching exceptions
- and turning into log warnings.
-
- """
- try:
- cursor.close()
- except Exception, e:
- try:
- ex_text = str(e)
- except TypeError:
- ex_text = repr(e)
- self.connection._logger.warn("Error closing cursor: %s", ex_text)
-
- if isinstance(e, (SystemExit, KeyboardInterrupt)):
- raise
-
- def _handle_dbapi_exception(self,
- e,
- statement,
- parameters,
- cursor,
- context):
- if getattr(self, '_reentrant_error', False):
- # Py3K
- #raise exc.DBAPIError.instance(statement, parameters, e,
- # self.dialect.dbapi.Error) from e
- # Py2K
- raise exc.DBAPIError.instance(statement,
- parameters,
- e,
- self.dialect.dbapi.Error), \
- None, sys.exc_info()[2]
- # end Py2K
- self._reentrant_error = True
- try:
- # non-DBAPI error - if we already got a context,
- # or theres no string statement, don't wrap it
- should_wrap = isinstance(e, self.dialect.dbapi.Error) or \
- (statement is not None and context is None)
-
- if should_wrap and context:
- context.handle_dbapi_exception(e)
-
- is_disconnect = isinstance(e, self.dialect.dbapi.Error) and \
- self.dialect.is_disconnect(e, self.__connection, cursor)
- if is_disconnect:
- self.invalidate(e)
- self.engine.dispose()
- else:
- if cursor:
- self._safe_close_cursor(cursor)
- self._autorollback()
- if self.should_close_with_result:
- self.close()
-
- if not should_wrap:
- return
-
- # Py3K
- #raise exc.DBAPIError.instance(
- # statement,
- # parameters,
- # e,
- # self.dialect.dbapi.Error,
- # connection_invalidated=is_disconnect) \
- # from e
- # Py2K
- raise exc.DBAPIError.instance(
- statement,
- parameters,
- e,
- self.dialect.dbapi.Error,
- connection_invalidated=is_disconnect), \
- None, sys.exc_info()[2]
- # end Py2K
-
- finally:
- del self._reentrant_error
-
- # poor man's multimethod/generic function thingy
- executors = {
- expression.FunctionElement: _execute_function,
- expression.ClauseElement: _execute_clauseelement,
- Compiled: _execute_compiled,
- schema.SchemaItem: _execute_default,
- schema.DDLElement: _execute_ddl,
- basestring: _execute_text
- }
-
- def create(self, entity, **kwargs):
- """Create a Table or Index given an appropriate Schema object."""
-
- return self.engine.create(entity, connection=self, **kwargs)
-
- def drop(self, entity, **kwargs):
- """Drop a Table or Index given an appropriate Schema object."""
-
- return self.engine.drop(entity, connection=self, **kwargs)
-
- def reflecttable(self, table, include_columns=None):
- """Reflect the columns in the given string table name from the
- database."""
-
- return self.engine.reflecttable(table, self, include_columns)
-
- def default_schema_name(self):
- return self.engine.dialect.get_default_schema_name(self)
-
- def transaction(self, callable_, *args, **kwargs):
- """Execute the given function within a transaction boundary.
-
- This is a shortcut for explicitly calling `begin()` and `commit()`
- and optionally `rollback()` when exceptions are raised. The
- given `*args` and `**kwargs` will be passed to the function.
-
- See also transaction() on engine.
-
- """
-
- trans = self.begin()
- try:
- ret = self.run_callable(callable_, *args, **kwargs)
- trans.commit()
- return ret
- except:
- trans.rollback()
- raise
-
- def run_callable(self, callable_, *args, **kwargs):
- return callable_(self, *args, **kwargs)
-
-
-class Transaction(object):
- """Represent a Transaction in progress.
-
- The object provides :meth:`.rollback` and :meth:`.commit`
- methods in order to control transaction boundaries. It
- also implements a context manager interface so that
- the Python ``with`` statement can be used with the
- :meth:`.Connection.begin` method.
-
- The Transaction object is **not** threadsafe.
-
- .. index::
- single: thread safety; Transaction
- """
-
- def __init__(self, connection, parent):
- """The constructor for :class:`.Transaction` is private
- and is called from within the :class:`.Connection.begin`
- implementation.
-
- """
- self.connection = connection
- self._parent = parent or self
- self.is_active = True
-
- def close(self):
- """Close this :class:`.Transaction`.
-
- If this transaction is the base transaction in a begin/commit
- nesting, the transaction will rollback(). Otherwise, the
- method returns.
-
- This is used to cancel a Transaction without affecting the scope of
- an enclosing transaction.
-
- """
- if not self._parent.is_active:
- return
- if self._parent is self:
- self.rollback()
-
- def rollback(self):
- """Roll back this :class:`.Transaction`.
-
- """
- if not self._parent.is_active:
- return
- self._do_rollback()
- self.is_active = False
-
- def _do_rollback(self):
- self._parent.rollback()
-
- def commit(self):
- """Commit this :class:`.Transaction`."""
-
- if not self._parent.is_active:
- raise exc.InvalidRequestError("This transaction is inactive")
- self._do_commit()
- self.is_active = False
-
- def _do_commit(self):
- pass
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- if type is None and self.is_active:
- self.commit()
- else:
- self.rollback()
-
-
-class RootTransaction(Transaction):
- def __init__(self, connection):
- super(RootTransaction, self).__init__(connection, None)
- self.connection._begin_impl()
-
- def _do_rollback(self):
- if self.is_active:
- self.connection._rollback_impl()
-
- def _do_commit(self):
- if self.is_active:
- self.connection._commit_impl()
-
-
-class NestedTransaction(Transaction):
- def __init__(self, connection, parent):
- super(NestedTransaction, self).__init__(connection, parent)
- self._savepoint = self.connection._savepoint_impl()
-
- def _do_rollback(self):
- if self.is_active:
- self.connection._rollback_to_savepoint_impl(
- self._savepoint, self._parent)
-
- def _do_commit(self):
- if self.is_active:
- self.connection._release_savepoint_impl(
- self._savepoint, self._parent)
-
-
-class TwoPhaseTransaction(Transaction):
- def __init__(self, connection, xid):
- super(TwoPhaseTransaction, self).__init__(connection, None)
- self._is_prepared = False
- self.xid = xid
- self.connection._begin_twophase_impl(self.xid)
-
- def prepare(self):
- if not self._parent.is_active:
- raise exc.InvalidRequestError("This transaction is inactive")
- self.connection._prepare_twophase_impl(self.xid)
- self._is_prepared = True
-
- def _do_rollback(self):
- self.connection._rollback_twophase_impl(self.xid, self._is_prepared)
-
- def _do_commit(self):
- self.connection._commit_twophase_impl(self.xid, self._is_prepared)
-
-
-class Engine(Connectable, log.Identified):
- """
- Connects a :class:`~sqlalchemy.pool.Pool` and
- :class:`~sqlalchemy.engine.base.Dialect` together to provide a source
- of database connectivity and behavior.
-
- An :class:`.Engine` object is instantiated publically using the
- :func:`~sqlalchemy.create_engine` function.
-
- """
-
- _execution_options = util.immutabledict()
- _has_events = False
- _connection_cls = Connection
-
- def __init__(self, pool, dialect, url,
- logging_name=None, echo=None, proxy=None,
- execution_options=None
- ):
- self.pool = pool
- self.url = url
- self.dialect = dialect
- if logging_name:
- self.logging_name = logging_name
- self.echo = echo
- self.engine = self
- log.instance_logger(self, echoflag=echo)
- if proxy:
- interfaces.ConnectionProxy._adapt_listener(self, proxy)
- if execution_options:
- if 'isolation_level' in execution_options:
- raise exc.ArgumentError(
- "'isolation_level' execution option may "
- "only be specified on Connection.execution_options(). "
- "To set engine-wide isolation level, "
- "use the isolation_level argument to create_engine()."
- )
- self.update_execution_options(**execution_options)
-
- dispatch = event.dispatcher(events.ConnectionEvents)
-
- def update_execution_options(self, **opt):
- """update the execution_options dictionary of this :class:`.Engine`.
-
- For details on execution_options, see
- :meth:`Connection.execution_options` as well as
- :meth:`sqlalchemy.sql.expression.Executable.execution_options`.
-
- """
- self._execution_options = \
- self._execution_options.union(opt)
-
- @property
- def name(self):
- """String name of the :class:`~sqlalchemy.engine.Dialect` in use by
- this ``Engine``."""
-
- return self.dialect.name
-
- @property
- def driver(self):
- """Driver name of the :class:`~sqlalchemy.engine.Dialect` in use by
- this ``Engine``."""
-
- return self.dialect.driver
-
- echo = log.echo_property()
-
- def __repr__(self):
- return 'Engine(%s)' % str(self.url)
-
- def dispose(self):
- """Dispose of the connection pool used by this :class:`.Engine`.
-
- A new connection pool is created immediately after the old one has
- been disposed. This new pool, like all SQLAlchemy connection pools,
- does not make any actual connections to the database until one is
- first requested.
-
- This method has two general use cases:
-
- * When a dropped connection is detected, it is assumed that all
- connections held by the pool are potentially dropped, and
- the entire pool is replaced.
-
- * An application may want to use :meth:`dispose` within a test
- suite that is creating multiple engines.
-
- It is critical to note that :meth:`dispose` does **not** guarantee
- that the application will release all open database connections - only
- those connections that are checked into the pool are closed.
- Connections which remain checked out or have been detached from
- the engine are not affected.
-
- """
- self.pool.dispose()
- self.pool = self.pool.recreate()
-
- def create(self, entity, connection=None, **kwargs):
- """Create a table or index within this engine's database connection
- given a schema object."""
-
- from sqlalchemy.engine import ddl
-
- self._run_visitor(ddl.SchemaGenerator, entity,
- connection=connection, **kwargs)
-
- def drop(self, entity, connection=None, **kwargs):
- """Drop a table or index within this engine's database connection
- given a schema object."""
-
- from sqlalchemy.engine import ddl
-
- self._run_visitor(ddl.SchemaDropper, entity,
- connection=connection, **kwargs)
-
- def _execute_default(self, default):
- connection = self.contextual_connect()
- try:
- return connection._execute_default(default, (), {})
- finally:
- connection.close()
-
- @property
- def func(self):
- return expression._FunctionGenerator(bind=self)
-
- def text(self, text, *args, **kwargs):
- """Return a :func:`~sqlalchemy.sql.expression.text` construct,
- bound to this engine.
-
- This is equivalent to::
-
- text("SELECT * FROM table", bind=engine)
-
- """
-
- return expression.text(text, bind=self, *args, **kwargs)
-
- def _run_visitor(self, visitorcallable, element,
- connection=None, **kwargs):
- if connection is None:
- conn = self.contextual_connect(close_with_result=False)
- else:
- conn = connection
- try:
- visitorcallable(self.dialect, conn,
- **kwargs).traverse_single(element)
- finally:
- if connection is None:
- conn.close()
-
- def transaction(self, callable_, *args, **kwargs):
- """Execute the given function within a transaction boundary.
-
- This is a shortcut for explicitly calling `begin()` and `commit()`
- and optionally `rollback()` when exceptions are raised. The
- given `*args` and `**kwargs` will be passed to the function.
-
- The connection used is that of contextual_connect().
-
- See also the similar method on Connection itself.
-
- """
-
- conn = self.contextual_connect()
- try:
- return conn.transaction(callable_, *args, **kwargs)
- finally:
- conn.close()
-
- def run_callable(self, callable_, *args, **kwargs):
- conn = self.contextual_connect()
- try:
- return conn.run_callable(callable_, *args, **kwargs)
- finally:
- conn.close()
-
- def execute(self, statement, *multiparams, **params):
- """Executes the given construct and returns a :class:`.ResultProxy`.
-
- The arguments are the same as those used by
- :meth:`.Connection.execute`.
-
- Here, a :class:`.Connection` is acquired using the
- :meth:`~.Engine.contextual_connect` method, and the statement executed
- with that connection. The returned :class:`.ResultProxy` is flagged
- such that when the :class:`.ResultProxy` is exhausted and its
- underlying cursor is closed, the :class:`.Connection` created here
- will also be closed, which allows its associated DBAPI connection
- resource to be returned to the connection pool.
-
- """
-
- connection = self.contextual_connect(close_with_result=True)
- return connection.execute(statement, *multiparams, **params)
-
- def scalar(self, statement, *multiparams, **params):
- return self.execute(statement, *multiparams, **params).scalar()
-
- def _execute_clauseelement(self, elem, multiparams=None, params=None):
- connection = self.contextual_connect(close_with_result=True)
- return connection._execute_clauseelement(elem, multiparams, params)
-
- def _execute_compiled(self, compiled, multiparams, params):
- connection = self.contextual_connect(close_with_result=True)
- return connection._execute_compiled(compiled, multiparams, params)
-
- def connect(self, **kwargs):
- """Return a new :class:`.Connection` object.
-
- The :class:`.Connection`, upon construction, will procure a DBAPI connection
- from the :class:`.Pool` referenced by this :class:`.Engine`,
- returning it back to the :class:`.Pool` after the :meth:`.Connection.close`
- method is called.
-
- """
-
- return self._connection_cls(self, **kwargs)
-
- def contextual_connect(self, close_with_result=False, **kwargs):
- """Return a :class:`.Connection` object which may be part of some ongoing context.
-
- By default, this method does the same thing as :meth:`.Engine.connect`.
- Subclasses of :class:`.Engine` may override this method
- to provide contextual behavior.
-
- :param close_with_result: When True, the first :class:`.ResultProxy` created
- by the :class:`.Connection` will call the :meth:`.Connection.close` method
- of that connection as soon as any pending result rows are exhausted.
- This is used to supply the "connectionless execution" behavior provided
- by the :meth:`.Engine.execute` method.
-
- """
-
- return self._connection_cls(self,
- self.pool.connect(),
- close_with_result=close_with_result,
- **kwargs)
-
- def table_names(self, schema=None, connection=None):
- """Return a list of all table names available in the database.
-
- :param schema: Optional, retrieve names from a non-default schema.
-
- :param connection: Optional, use a specified connection. Default is
- the ``contextual_connect`` for this ``Engine``.
- """
-
- if connection is None:
- conn = self.contextual_connect()
- else:
- conn = connection
- if not schema:
- schema = self.dialect.default_schema_name
- try:
- return self.dialect.get_table_names(conn, schema)
- finally:
- if connection is None:
- conn.close()
-
- def reflecttable(self, table, connection=None, include_columns=None):
- """Given a Table object, reflects its columns and properties from the
- database."""
-
- if connection is None:
- conn = self.contextual_connect()
- else:
- conn = connection
- try:
- self.dialect.reflecttable(conn, table, include_columns)
- finally:
- if connection is None:
- conn.close()
-
- def has_table(self, table_name, schema=None):
- return self.run_callable(self.dialect.has_table, table_name, schema)
-
- def raw_connection(self):
- """Return a DB-API connection."""
-
- return self.pool.unique_connection()
-
-
-# This reconstructor is necessary so that pickles with the C extension or
-# without use the same Binary format.
-try:
- # We need a different reconstructor on the C extension so that we can
- # add extra checks that fields have correctly been initialized by
- # __setstate__.
- from sqlalchemy.cresultproxy import safe_rowproxy_reconstructor
-
- # The extra function embedding is needed so that the
- # reconstructor function has the same signature whether or not
- # the extension is present.
- def rowproxy_reconstructor(cls, state):
- return safe_rowproxy_reconstructor(cls, state)
-except ImportError:
- def rowproxy_reconstructor(cls, state):
- obj = cls.__new__(cls)
- obj.__setstate__(state)
- return obj
-
-try:
- from sqlalchemy.cresultproxy import BaseRowProxy
-except ImportError:
- class BaseRowProxy(object):
- __slots__ = ('_parent', '_row', '_processors', '_keymap')
-
- def __init__(self, parent, row, processors, keymap):
- """RowProxy objects are constructed by ResultProxy objects."""
-
- self._parent = parent
- self._row = row
- self._processors = processors
- self._keymap = keymap
-
- def __reduce__(self):
- return (rowproxy_reconstructor,
- (self.__class__, self.__getstate__()))
-
- def values(self):
- """Return the values represented by this RowProxy as a list."""
- return list(self)
-
- def __iter__(self):
- for processor, value in izip(self._processors, self._row):
- if processor is None:
- yield value
- else:
- yield processor(value)
-
- def __len__(self):
- return len(self._row)
-
- def __getitem__(self, key):
- try:
- processor, index = self._keymap[key]
- except KeyError:
- processor, index = self._parent._key_fallback(key)
- except TypeError:
- if isinstance(key, slice):
- l = []
- for processor, value in izip(self._processors[key],
- self._row[key]):
- if processor is None:
- l.append(value)
- else:
- l.append(processor(value))
- return tuple(l)
- else:
- raise
- if index is None:
- raise exc.InvalidRequestError(
- "Ambiguous column name '%s' in result set! "
- "try 'use_labels' option on select statement." % key)
- if processor is not None:
- return processor(self._row[index])
- else:
- return self._row[index]
-
- def __getattr__(self, name):
- try:
- # TODO: no test coverage here
- return self[name]
- except KeyError, e:
- raise AttributeError(e.args[0])
-
-
-class RowProxy(BaseRowProxy):
- """Proxy values from a single cursor row.
-
- Mostly follows "ordered dictionary" behavior, mapping result
- values to the string-based column name, the integer position of
- the result in the row, as well as Column instances which can be
- mapped to the original Columns that produced this result set (for
- results that correspond to constructed SQL expressions).
- """
- __slots__ = ()
-
- def __contains__(self, key):
- return self._parent._has_key(self._row, key)
-
- def __getstate__(self):
- return {
- '_parent': self._parent,
- '_row': tuple(self)
- }
-
- def __setstate__(self, state):
- self._parent = parent = state['_parent']
- self._row = state['_row']
- self._processors = parent._processors
- self._keymap = parent._keymap
-
- __hash__ = None
-
- def __eq__(self, other):
- return other is self or other == tuple(self)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return repr(tuple(self))
-
- def has_key(self, key):
- """Return True if this RowProxy contains the given key."""
-
- return self._parent._has_key(self._row, key)
-
- def items(self):
- """Return a list of tuples, each tuple containing a key/value pair."""
- # TODO: no coverage here
- return [(key, self[key]) for key in self.iterkeys()]
-
- def keys(self):
- """Return the list of keys as strings represented by this RowProxy."""
-
- return self._parent.keys
-
- def iterkeys(self):
- return iter(self._parent.keys)
-
- def itervalues(self):
- return iter(self)
-
-try:
- # Register RowProxy with Sequence,
- # so sequence protocol is implemented
- from collections import Sequence
- Sequence.register(RowProxy)
-except ImportError:
- pass
-
-
-class ResultMetaData(object):
- """Handle cursor.description, applying additional info from an execution
- context."""
-
- def __init__(self, parent, metadata):
- self._processors = processors = []
-
- # We do not strictly need to store the processor in the key mapping,
- # though it is faster in the Python version (probably because of the
- # saved attribute lookup self._processors)
- self._keymap = keymap = {}
- self.keys = []
- context = parent.context
- dialect = context.dialect
- typemap = dialect.dbapi_type_map
-
- for i, rec in enumerate(metadata):
- colname = rec[0]
- coltype = rec[1]
-
- if dialect.description_encoding:
- colname = dialect._description_decoder(colname)
-
- if context.result_map:
- try:
- name, obj, type_ = context.result_map[colname.lower()]
- except KeyError:
- name, obj, type_ = \
- colname, None, typemap.get(coltype, types.NULLTYPE)
- else:
- name, obj, type_ = \
- colname, None, typemap.get(coltype, types.NULLTYPE)
-
- processor = type_._cached_result_processor(dialect, coltype)
-
- processors.append(processor)
- rec = (processor, i)
-
- # indexes as keys. This is only needed for the Python version of
- # RowProxy (the C version uses a faster path for integer indexes).
- keymap[i] = rec
-
- # Column names as keys
- if keymap.setdefault(name.lower(), rec) is not rec:
- # We do not raise an exception directly because several
- # columns colliding by name is not a problem as long as the
- # user does not try to access them (ie use an index directly,
- # or the more precise ColumnElement)
- keymap[name.lower()] = (processor, None)
-
- if dialect.requires_name_normalize:
- colname = dialect.normalize_name(colname)
-
- self.keys.append(colname)
- if obj:
- for o in obj:
- keymap[o] = rec
-
- if parent._echo:
- context.engine.logger.debug(
- "Col %r", tuple(x[0] for x in metadata))
-
- def _set_keymap_synonym(self, name, origname):
- """Set a synonym for the given name.
-
- Some dialects (SQLite at the moment) may use this to
- adjust the column names that are significant within a
- row.
-
- """
- rec = (processor, i) = self._keymap[origname.lower()]
- if self._keymap.setdefault(name, rec) is not rec:
- self._keymap[name] = (processor, None)
-
- def _key_fallback(self, key):
- map = self._keymap
- result = None
- if isinstance(key, basestring):
- result = map.get(key.lower())
- # fallback for targeting a ColumnElement to a textual expression
- # this is a rare use case which only occurs when matching text()
- # constructs to ColumnElements, and after a pickle/unpickle roundtrip
- elif isinstance(key, expression.ColumnElement):
- if key._label and key._label.lower() in map:
- result = map[key._label.lower()]
- elif hasattr(key, 'name') and key.name.lower() in map:
- result = map[key.name.lower()]
- if result is None:
- raise exc.NoSuchColumnError(
- "Could not locate column in row for column '%s'" % key)
- else:
- map[key] = result
- return result
-
- def _has_key(self, row, key):
- if key in self._keymap:
- return True
- else:
- try:
- self._key_fallback(key)
- return True
- except exc.NoSuchColumnError:
- return False
-
- def __getstate__(self):
- return {
- '_pickled_keymap': dict(
- (key, index)
- for key, (processor, index) in self._keymap.iteritems()
- if isinstance(key, (basestring, int))
- ),
- 'keys': self.keys
- }
-
- def __setstate__(self, state):
- # the row has been processed at pickling time so we don't need any
- # processor anymore
- self._processors = [None for _ in xrange(len(state['keys']))]
- self._keymap = keymap = {}
- for key, index in state['_pickled_keymap'].iteritems():
- keymap[key] = (None, index)
- self.keys = state['keys']
- self._echo = False
-
-
-class ResultProxy(object):
- """Wraps a DB-API cursor object to provide easier access to row columns.
-
- Individual columns may be accessed by their integer position,
- case-insensitive column name, or by ``schema.Column``
- object. e.g.::
-
- row = fetchone()
-
- col1 = row[0] # access via integer position
-
- col2 = row['col2'] # access via name
-
- col3 = row[mytable.c.mycol] # access via Column object.
-
- ``ResultProxy`` also handles post-processing of result column
- data using ``TypeEngine`` objects, which are referenced from
- the originating SQL statement that produced this result set.
-
- """
-
- _process_row = RowProxy
- out_parameters = None
- _can_close_connection = False
-
- def __init__(self, context):
- self.context = context
- self.dialect = context.dialect
- self.closed = False
- self.cursor = self._saved_cursor = context.cursor
- self.connection = context.root_connection
- self._echo = self.connection._echo and \
- context.engine._should_log_debug()
- self._init_metadata()
-
- def _init_metadata(self):
- metadata = self._cursor_description()
- if metadata is None:
- self._metadata = None
- else:
- self._metadata = ResultMetaData(self, metadata)
-
- def keys(self):
- """Return the current set of string keys for rows."""
- if self._metadata:
- return self._metadata.keys
- else:
- return []
-
- @util.memoized_property
- def rowcount(self):
- """Return the 'rowcount' for this result.
-
- The 'rowcount' reports the number of rows affected
- by an UPDATE or DELETE statement. It has *no* other
- uses and is not intended to provide the number of rows
- present from a SELECT.
-
- Note that this row count may not be properly implemented in some
- dialects; this is indicated by
- :meth:`~sqlalchemy.engine.base.ResultProxy.supports_sane_rowcount()`
- and
- :meth:`~sqlalchemy.engine.base.ResultProxy.supports_sane_multi_rowcount()`.
- ``rowcount()`` also may not work at this time for a statement that
- uses ``returning()``.
-
- """
- try:
- return self.context.rowcount
- except Exception, e:
- self.connection._handle_dbapi_exception(
- e, None, None, self.cursor, self.context)
- raise
-
- @property
- def lastrowid(self):
- """return the 'lastrowid' accessor on the DBAPI cursor.
-
- This is a DBAPI specific method and is only functional
- for those backends which support it, for statements
- where it is appropriate. It's behavior is not
- consistent across backends.
-
- Usage of this method is normally unnecessary; the
- :attr:`~ResultProxy.inserted_primary_key` attribute provides a
- tuple of primary key values for a newly inserted row,
- regardless of database backend.
-
- """
- try:
- return self._saved_cursor.lastrowid
- except Exception, e:
- self.connection._handle_dbapi_exception(
- e, None, None,
- self._saved_cursor, self.context)
- raise
-
- @property
- def returns_rows(self):
- """True if this :class:`.ResultProxy` returns rows.
-
- I.e. if it is legal to call the methods
- :meth:`~.ResultProxy.fetchone`,
- :meth:`~.ResultProxy.fetchmany`
- :meth:`~.ResultProxy.fetchall`.
-
- """
- return self._metadata is not None
-
- @property
- def is_insert(self):
- """True if this :class:`.ResultProxy` is the result
- of a executing an expression language compiled
- :func:`.expression.insert` construct.
-
- When True, this implies that the
- :attr:`inserted_primary_key` attribute is accessible,
- assuming the statement did not include
- a user defined "returning" construct.
-
- """
- return self.context.isinsert
-
- def _cursor_description(self):
- """May be overridden by subclasses."""
-
- return self._saved_cursor.description
-
- def close(self, _autoclose_connection=True):
- """Close this ResultProxy.
-
- Closes the underlying DBAPI cursor corresponding to the execution.
-
- Note that any data cached within this ResultProxy is still available.
- For some types of results, this may include buffered rows.
-
- If this ResultProxy was generated from an implicit execution,
- the underlying Connection will also be closed (returns the
- underlying DBAPI connection to the connection pool.)
-
- This method is called automatically when:
-
- * all result rows are exhausted using the fetchXXX() methods.
- * cursor.description is None.
-
- """
-
- if not self.closed:
- self.closed = True
- self.connection._safe_close_cursor(self.cursor)
- if _autoclose_connection and \
- self.connection.should_close_with_result:
- self.connection.close()
- # allow consistent errors
- self.cursor = None
-
- def __iter__(self):
- while True:
- row = self.fetchone()
- if row is None:
- raise StopIteration
- else:
- yield row
-
- @util.memoized_property
- def inserted_primary_key(self):
- """Return the primary key for the row just inserted.
-
- The return value is a list of scalar values
- corresponding to the list of primary key columns
- in the target table.
-
- This only applies to single row :func:`.insert`
- constructs which did not explicitly specify
- :meth:`.Insert.returning`.
-
- Note that primary key columns which specify a
- server_default clause,
- or otherwise do not qualify as "autoincrement"
- columns (see the notes at :class:`.Column`), and were
- generated using the database-side default, will
- appear in this list as ``None`` unless the backend
- supports "returning" and the insert statement executed
- with the "implicit returning" enabled.
-
- """
-
- if not self.context.isinsert:
- raise exc.InvalidRequestError(
- "Statement is not an insert() expression construct.")
- elif self.context._is_explicit_returning:
- raise exc.InvalidRequestError(
- "Can't call inserted_primary_key when returning() "
- "is used.")
-
- return self.context.inserted_primary_key
-
- @util.deprecated("0.6", "Use :attr:`.ResultProxy.inserted_primary_key`")
- def last_inserted_ids(self):
- """Return the primary key for the row just inserted."""
-
- return self.inserted_primary_key
-
- def last_updated_params(self):
- """Return the collection of updated parameters from this
- execution.
-
- """
- if self.context.executemany:
- return self.context.compiled_parameters
- else:
- return self.context.compiled_parameters[0]
-
- def last_inserted_params(self):
- """Return the collection of inserted parameters from this
- execution.
-
- """
- if self.context.executemany:
- return self.context.compiled_parameters
- else:
- return self.context.compiled_parameters[0]
-
- def lastrow_has_defaults(self):
- """Return ``lastrow_has_defaults()`` from the underlying
- ExecutionContext.
-
- See ExecutionContext for details.
- """
-
- return self.context.lastrow_has_defaults()
-
- def postfetch_cols(self):
- """Return ``postfetch_cols()`` from the underlying ExecutionContext.
-
- See ExecutionContext for details.
- """
-
- return self.context.postfetch_cols
-
- def prefetch_cols(self):
- return self.context.prefetch_cols
-
- def supports_sane_rowcount(self):
- """Return ``supports_sane_rowcount`` from the dialect."""
-
- return self.dialect.supports_sane_rowcount
-
- def supports_sane_multi_rowcount(self):
- """Return ``supports_sane_multi_rowcount`` from the dialect."""
-
- return self.dialect.supports_sane_multi_rowcount
-
- def _fetchone_impl(self):
- try:
- return self.cursor.fetchone()
- except AttributeError:
- self._non_result()
-
- def _fetchmany_impl(self, size=None):
- try:
- if size is None:
- return self.cursor.fetchmany()
- else:
- return self.cursor.fetchmany(size)
- except AttributeError:
- self._non_result()
-
- def _fetchall_impl(self):
- try:
- return self.cursor.fetchall()
- except AttributeError:
- self._non_result()
-
- def _non_result(self):
- if self._metadata is None:
- raise exc.ResourceClosedError(
- "This result object does not return rows. "
- "It has been closed automatically.",
- )
- else:
- raise exc.ResourceClosedError("This result object is closed.")
-
- def process_rows(self, rows):
- process_row = self._process_row
- metadata = self._metadata
- keymap = metadata._keymap
- processors = metadata._processors
- if self._echo:
- log = self.context.engine.logger.debug
- l = []
- for row in rows:
- log("Row %r", row)
- l.append(process_row(metadata, row, processors, keymap))
- return l
- else:
- return [process_row(metadata, row, processors, keymap)
- for row in rows]
-
- def fetchall(self):
- """Fetch all rows, just like DB-API ``cursor.fetchall()``."""
-
- try:
- l = self.process_rows(self._fetchall_impl())
- self.close()
- return l
- except Exception, e:
- self.connection._handle_dbapi_exception(
- e, None, None,
- self.cursor, self.context)
- raise
-
- def fetchmany(self, size=None):
- """Fetch many rows, just like DB-API
- ``cursor.fetchmany(size=cursor.arraysize)``.
-
- If rows are present, the cursor remains open after this is called.
- Else the cursor is automatically closed and an empty list is returned.
-
- """
-
- try:
- l = self.process_rows(self._fetchmany_impl(size))
- if len(l) == 0:
- self.close()
- return l
- except Exception, e:
- self.connection._handle_dbapi_exception(
- e, None, None,
- self.cursor, self.context)
- raise
-
- def fetchone(self):
- """Fetch one row, just like DB-API ``cursor.fetchone()``.
-
- If a row is present, the cursor remains open after this is called.
- Else the cursor is automatically closed and None is returned.
-
- """
- try:
- row = self._fetchone_impl()
- if row is not None:
- return self.process_rows([row])[0]
- else:
- self.close()
- return None
- except Exception, e:
- self.connection._handle_dbapi_exception(
- e, None, None,
- self.cursor, self.context)
- raise
-
- def first(self):
- """Fetch the first row and then close the result set unconditionally.
-
- Returns None if no row is present.
-
- """
- if self._metadata is None:
- self._non_result()
-
- try:
- row = self._fetchone_impl()
- except Exception, e:
- self.connection._handle_dbapi_exception(
- e, None, None,
- self.cursor, self.context)
- raise
-
- try:
- if row is not None:
- return self.process_rows([row])[0]
- else:
- return None
- finally:
- self.close()
-
- def scalar(self):
- """Fetch the first column of the first row, and close the result set.
-
- Returns None if no row is present.
-
- """
- row = self.first()
- if row is not None:
- return row[0]
- else:
- return None
-
-class BufferedRowResultProxy(ResultProxy):
- """A ResultProxy with row buffering behavior.
-
- ``ResultProxy`` that buffers the contents of a selection of rows
- before ``fetchone()`` is called. This is to allow the results of
- ``cursor.description`` to be available immediately, when
- interfacing with a DB-API that requires rows to be consumed before
- this information is available (currently psycopg2, when used with
- server-side cursors).
-
- The pre-fetching behavior fetches only one row initially, and then
- grows its buffer size by a fixed amount with each successive need
- for additional rows up to a size of 100.
- """
-
- def _init_metadata(self):
- self.__buffer_rows()
- super(BufferedRowResultProxy, self)._init_metadata()
-
- # this is a "growth chart" for the buffering of rows.
- # each successive __buffer_rows call will use the next
- # value in the list for the buffer size until the max
- # is reached
- size_growth = {
- 1 : 5,
- 5 : 10,
- 10 : 20,
- 20 : 50,
- 50 : 100,
- 100 : 250,
- 250 : 500,
- 500 : 1000
- }
-
- def __buffer_rows(self):
- size = getattr(self, '_bufsize', 1)
- self.__rowbuffer = collections.deque(self.cursor.fetchmany(size))
- self._bufsize = self.size_growth.get(size, size)
-
- def _fetchone_impl(self):
- if self.closed:
- return None
- if not self.__rowbuffer:
- self.__buffer_rows()
- if not self.__rowbuffer:
- return None
- return self.__rowbuffer.popleft()
-
- def _fetchmany_impl(self, size=None):
- if size is None:
- return self._fetchall_impl()
- result = []
- for x in range(0, size):
- row = self._fetchone_impl()
- if row is None:
- break
- result.append(row)
- return result
-
- def _fetchall_impl(self):
- self.__rowbuffer.extend(self.cursor.fetchall())
- ret = self.__rowbuffer
- self.__rowbuffer = collections.deque()
- return ret
-
-class FullyBufferedResultProxy(ResultProxy):
- """A result proxy that buffers rows fully upon creation.
-
- Used for operations where a result is to be delivered
- after the database conversation can not be continued,
- such as MSSQL INSERT...OUTPUT after an autocommit.
-
- """
- def _init_metadata(self):
- super(FullyBufferedResultProxy, self)._init_metadata()
- self.__rowbuffer = self._buffer_rows()
-
- def _buffer_rows(self):
- return collections.deque(self.cursor.fetchall())
-
- def _fetchone_impl(self):
- if self.__rowbuffer:
- return self.__rowbuffer.popleft()
- else:
- return None
-
- def _fetchmany_impl(self, size=None):
- if size is None:
- return self._fetchall_impl()
- result = []
- for x in range(0, size):
- row = self._fetchone_impl()
- if row is None:
- break
- result.append(row)
- return result
-
- def _fetchall_impl(self):
- ret = self.__rowbuffer
- self.__rowbuffer = collections.deque()
- return ret
-
-class BufferedColumnRow(RowProxy):
- def __init__(self, parent, row, processors, keymap):
- # preprocess row
- row = list(row)
- # this is a tad faster than using enumerate
- index = 0
- for processor in parent._orig_processors:
- if processor is not None:
- row[index] = processor(row[index])
- index += 1
- row = tuple(row)
- super(BufferedColumnRow, self).__init__(parent, row,
- processors, keymap)
-
-class BufferedColumnResultProxy(ResultProxy):
- """A ResultProxy with column buffering behavior.
-
- ``ResultProxy`` that loads all columns into memory each time
- fetchone() is called. If fetchmany() or fetchall() are called,
- the full grid of results is fetched. This is to operate with
- databases where result rows contain "live" results that fall out
- of scope unless explicitly fetched. Currently this includes
- cx_Oracle LOB objects.
-
- """
-
- _process_row = BufferedColumnRow
-
- def _init_metadata(self):
- super(BufferedColumnResultProxy, self)._init_metadata()
- metadata = self._metadata
- # orig_processors will be used to preprocess each row when they are
- # constructed.
- metadata._orig_processors = metadata._processors
- # replace the all type processors by None processors.
- metadata._processors = [None for _ in xrange(len(metadata.keys))]
- keymap = {}
- for k, (func, index) in metadata._keymap.iteritems():
- keymap[k] = (None, index)
- self._metadata._keymap = keymap
-
- def fetchall(self):
- # can't call cursor.fetchall(), since rows must be
- # fully processed before requesting more from the DBAPI.
- l = []
- while True:
- row = self.fetchone()
- if row is None:
- break
- l.append(row)
- return l
-
- def fetchmany(self, size=None):
- # can't call cursor.fetchmany(), since rows must be
- # fully processed before requesting more from the DBAPI.
- if size is None:
- return self.fetchall()
- l = []
- for i in xrange(size):
- row = self.fetchone()
- if row is None:
- break
- l.append(row)
- return l
-
-def connection_memoize(key):
- """Decorator, memoize a function in a connection.info stash.
-
- Only applicable to functions which take no arguments other than a
- connection. The memo will be stored in ``connection.info[key]``.
- """
-
- @util.decorator
- def decorated(fn, self, connection):
- connection = connection.connect()
- try:
- return connection.info[key]
- except KeyError:
- connection.info[key] = val = fn(self, connection)
- return val
-
- return decorated
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/ddl.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/ddl.py
deleted file mode 100755
index 79958baa..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/ddl.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# engine/ddl.py
-# Copyright (C) 2009-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Routines to handle CREATE/DROP workflow."""
-
-from sqlalchemy import engine, schema
-from sqlalchemy.sql import util as sql_util
-
-
-class DDLBase(schema.SchemaVisitor):
- def __init__(self, connection):
- self.connection = connection
-
-class SchemaGenerator(DDLBase):
- def __init__(self, dialect, connection, checkfirst=False, tables=None, **kwargs):
- super(SchemaGenerator, self).__init__(connection, **kwargs)
- self.checkfirst = checkfirst
- self.tables = tables and set(tables) or None
- self.preparer = dialect.identifier_preparer
- self.dialect = dialect
-
- def _can_create_table(self, table):
- self.dialect.validate_identifier(table.name)
- if table.schema:
- self.dialect.validate_identifier(table.schema)
- return not self.checkfirst or \
- not self.dialect.has_table(self.connection,
- table.name, schema=table.schema)
-
- def _can_create_sequence(self, sequence):
- return self.dialect.supports_sequences and \
- (
- (not self.dialect.sequences_optional or
- not sequence.optional) and
- (
- not self.checkfirst or
- not self.dialect.has_sequence(
- self.connection,
- sequence.name,
- schema=sequence.schema)
- )
- )
-
- def visit_metadata(self, metadata):
- if self.tables:
- tables = self.tables
- else:
- tables = metadata.tables.values()
- collection = [t for t in sql_util.sort_tables(tables)
- if self._can_create_table(t)]
- seq_coll = [s for s in metadata._sequences.values()
- if s.column is None and self._can_create_sequence(s)]
-
- metadata.dispatch.before_create(metadata, self.connection,
- tables=collection,
- checkfirst=self.checkfirst)
-
- for seq in seq_coll:
- self.traverse_single(seq, create_ok=True)
-
- for table in collection:
- self.traverse_single(table, create_ok=True)
-
- metadata.dispatch.after_create(metadata, self.connection,
- tables=collection,
- checkfirst=self.checkfirst)
-
- def visit_table(self, table, create_ok=False):
- if not create_ok and not self._can_create_table(table):
- return
-
- table.dispatch.before_create(table, self.connection,
- checkfirst=self.checkfirst)
-
- for column in table.columns:
- if column.default is not None:
- self.traverse_single(column.default)
-
- self.connection.execute(schema.CreateTable(table))
-
- if hasattr(table, 'indexes'):
- for index in table.indexes:
- self.traverse_single(index)
-
- table.dispatch.after_create(table, self.connection,
- checkfirst=self.checkfirst)
-
- def visit_sequence(self, sequence, create_ok=False):
- if not create_ok and not self._can_create_sequence(sequence):
- return
- self.connection.execute(schema.CreateSequence(sequence))
-
- def visit_index(self, index):
- self.connection.execute(schema.CreateIndex(index))
-
-
-class SchemaDropper(DDLBase):
- def __init__(self, dialect, connection, checkfirst=False, tables=None, **kwargs):
- super(SchemaDropper, self).__init__(connection, **kwargs)
- self.checkfirst = checkfirst
- self.tables = tables
- self.preparer = dialect.identifier_preparer
- self.dialect = dialect
-
- def visit_metadata(self, metadata):
- if self.tables:
- tables = self.tables
- else:
- tables = metadata.tables.values()
- collection = [t for t in reversed(sql_util.sort_tables(tables))
- if self._can_drop_table(t)]
- seq_coll = [s for s in metadata._sequences.values()
- if s.column is None and self._can_drop_sequence(s)]
-
- metadata.dispatch.before_drop(metadata, self.connection,
- tables=collection,
- checkfirst=self.checkfirst)
-
- for table in collection:
- self.traverse_single(table, drop_ok=True)
-
- for seq in seq_coll:
- self.traverse_single(seq, drop_ok=True)
-
- metadata.dispatch.after_drop(metadata, self.connection,
- tables=collection,
- checkfirst=self.checkfirst)
-
- def _can_drop_table(self, table):
- self.dialect.validate_identifier(table.name)
- if table.schema:
- self.dialect.validate_identifier(table.schema)
- return not self.checkfirst or self.dialect.has_table(self.connection,
- table.name, schema=table.schema)
-
- def _can_drop_sequence(self, sequence):
- return self.dialect.supports_sequences and \
- ((not self.dialect.sequences_optional or
- not sequence.optional) and
- (not self.checkfirst or
- self.dialect.has_sequence(
- self.connection,
- sequence.name,
- schema=sequence.schema))
- )
-
- def visit_index(self, index):
- self.connection.execute(schema.DropIndex(index))
-
- def visit_table(self, table, drop_ok=False):
- if not drop_ok and not self._can_drop_table(table):
- return
-
- table.dispatch.before_drop(table, self.connection,
- checkfirst=self.checkfirst)
-
- for column in table.columns:
- if column.default is not None:
- self.traverse_single(column.default)
-
- self.connection.execute(schema.DropTable(table))
-
- table.dispatch.after_drop(table, self.connection,
- checkfirst=self.checkfirst)
-
- def visit_sequence(self, sequence, drop_ok=False):
- if not drop_ok and not self._can_drop_sequence(sequence):
- return
- self.connection.execute(schema.DropSequence(sequence))
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/default.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/default.py
deleted file mode 100755
index 9f6c5010..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/default.py
+++ /dev/null
@@ -1,801 +0,0 @@
-# engine/default.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Default implementations of per-dialect sqlalchemy.engine classes.
-
-These are semi-private implementation classes which are only of importance
-to database dialect authors; dialects will usually use the classes here
-as the base class for their own corresponding classes.
-
-"""
-
-import re, random
-from sqlalchemy.engine import base, reflection
-from sqlalchemy.sql import compiler, expression
-from sqlalchemy import exc, types as sqltypes, util, pool, processors
-import codecs
-import weakref
-
-AUTOCOMMIT_REGEXP = re.compile(
- r'\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)',
- re.I | re.UNICODE)
-
-
-class DefaultDialect(base.Dialect):
- """Default implementation of Dialect"""
-
- statement_compiler = compiler.SQLCompiler
- ddl_compiler = compiler.DDLCompiler
- type_compiler = compiler.GenericTypeCompiler
- preparer = compiler.IdentifierPreparer
- supports_alter = True
-
- # most DBAPIs happy with this for execute().
- # not cx_oracle.
- execute_sequence_format = tuple
-
- supports_views = True
- supports_sequences = False
- sequences_optional = False
- preexecute_autoincrement_sequences = False
- postfetch_lastrowid = True
- implicit_returning = False
-
- supports_native_enum = False
- supports_native_boolean = False
-
- # if the NUMERIC type
- # returns decimal.Decimal.
- # *not* the FLOAT type however.
- supports_native_decimal = False
-
- # Py3K
- #supports_unicode_statements = True
- #supports_unicode_binds = True
- #returns_unicode_strings = True
- #description_encoding = None
- # Py2K
- supports_unicode_statements = False
- supports_unicode_binds = False
- returns_unicode_strings = False
- description_encoding = 'use_encoding'
- # end Py2K
-
-
- name = 'default'
-
- # length at which to truncate
- # any identifier.
- max_identifier_length = 9999
-
- # length at which to truncate
- # the name of an index.
- # Usually None to indicate
- # 'use max_identifier_length'.
- # thanks to MySQL, sigh
- max_index_name_length = None
-
- supports_sane_rowcount = True
- supports_sane_multi_rowcount = True
- dbapi_type_map = {}
- colspecs = {}
- default_paramstyle = 'named'
- supports_default_values = False
- supports_empty_insert = True
-
- server_version_info = None
-
- # indicates symbol names are
- # UPPERCASEd if they are case insensitive
- # within the database.
- # if this is True, the methods normalize_name()
- # and denormalize_name() must be provided.
- requires_name_normalize = False
-
- reflection_options = ()
-
- def __init__(self, convert_unicode=False, assert_unicode=False,
- encoding='utf-8', paramstyle=None, dbapi=None,
- implicit_returning=None,
- label_length=None, **kwargs):
-
- if not getattr(self, 'ported_sqla_06', True):
- util.warn(
- "The %s dialect is not yet ported to SQLAlchemy 0.6/0.7" %
- self.name)
-
- self.convert_unicode = convert_unicode
- if assert_unicode:
- util.warn_deprecated(
- "assert_unicode is deprecated. "
- "SQLAlchemy emits a warning in all cases where it "
- "would otherwise like to encode a Python unicode object "
- "into a specific encoding but a plain bytestring is "
- "received. "
- "This does *not* apply to DBAPIs that coerce Unicode "
- "natively.")
-
- self.encoding = encoding
- self.positional = False
- self._ischema = None
- self.dbapi = dbapi
- if paramstyle is not None:
- self.paramstyle = paramstyle
- elif self.dbapi is not None:
- self.paramstyle = self.dbapi.paramstyle
- else:
- self.paramstyle = self.default_paramstyle
- if implicit_returning is not None:
- self.implicit_returning = implicit_returning
- self.positional = self.paramstyle in ('qmark', 'format', 'numeric')
- self.identifier_preparer = self.preparer(self)
- self.type_compiler = self.type_compiler(self)
-
- if label_length and label_length > self.max_identifier_length:
- raise exc.ArgumentError(
- "Label length of %d is greater than this dialect's"
- " maximum identifier length of %d" %
- (label_length, self.max_identifier_length))
- self.label_length = label_length
-
- if self.description_encoding == 'use_encoding':
- self._description_decoder = processors.to_unicode_processor_factory(
- encoding
- )
- elif self.description_encoding is not None:
- self._description_decoder = processors.to_unicode_processor_factory(
- self.description_encoding
- )
- self._encoder = codecs.getencoder(self.encoding)
- self._decoder = processors.to_unicode_processor_factory(self.encoding)
-
- @util.memoized_property
- def _type_memos(self):
- return weakref.WeakKeyDictionary()
-
- @property
- def dialect_description(self):
- return self.name + "+" + self.driver
-
- @classmethod
- def get_pool_class(cls, url):
- return getattr(cls, 'poolclass', pool.QueuePool)
-
- def initialize(self, connection):
- try:
- self.server_version_info = \
- self._get_server_version_info(connection)
- except NotImplementedError:
- self.server_version_info = None
- try:
- self.default_schema_name = \
- self._get_default_schema_name(connection)
- except NotImplementedError:
- self.default_schema_name = None
-
- try:
- self.default_isolation_level = \
- self.get_isolation_level(connection.connection)
- except NotImplementedError:
- self.default_isolation_level = None
-
- self.returns_unicode_strings = self._check_unicode_returns(connection)
-
- self.do_rollback(connection.connection)
-
- def on_connect(self):
- """return a callable which sets up a newly created DBAPI connection.
-
- This is used to set dialect-wide per-connection options such as
- isolation modes, unicode modes, etc.
-
- If a callable is returned, it will be assembled into a pool listener
- that receives the direct DBAPI connection, with all wrappers removed.
-
- If None is returned, no listener will be generated.
-
- """
- return None
-
- def _check_unicode_returns(self, connection):
- # Py2K
- if self.supports_unicode_statements:
- cast_to = unicode
- else:
- cast_to = str
- # end Py2K
- # Py3K
- #cast_to = str
- def check_unicode(type_):
- cursor = connection.connection.cursor()
- try:
- cursor.execute(
- cast_to(
- expression.select(
- [expression.cast(
- expression.literal_column(
- "'test unicode returns'"), type_)
- ]).compile(dialect=self)
- )
- )
- row = cursor.fetchone()
-
- return isinstance(row[0], unicode)
- finally:
- cursor.close()
-
- # detect plain VARCHAR
- unicode_for_varchar = check_unicode(sqltypes.VARCHAR(60))
-
- # detect if there's an NVARCHAR type with different behavior available
- unicode_for_unicode = check_unicode(sqltypes.Unicode(60))
-
- if unicode_for_unicode and not unicode_for_varchar:
- return "conditional"
- else:
- return unicode_for_varchar
-
- def type_descriptor(self, typeobj):
- """Provide a database-specific ``TypeEngine`` object, given
- the generic object which comes from the types module.
-
- This method looks for a dictionary called
- ``colspecs`` as a class or instance-level variable,
- and passes on to ``types.adapt_type()``.
-
- """
- return sqltypes.adapt_type(typeobj, self.colspecs)
-
- def reflecttable(self, connection, table, include_columns):
- insp = reflection.Inspector.from_engine(connection)
- return insp.reflecttable(table, include_columns)
-
- def get_pk_constraint(self, conn, table_name, schema=None, **kw):
- """Compatiblity method, adapts the result of get_primary_keys()
- for those dialects which don't implement get_pk_constraint().
-
- """
- return {
- 'constrained_columns':
- self.get_primary_keys(conn, table_name,
- schema=schema, **kw)
- }
-
- def validate_identifier(self, ident):
- if len(ident) > self.max_identifier_length:
- raise exc.IdentifierError(
- "Identifier '%s' exceeds maximum length of %d characters" %
- (ident, self.max_identifier_length)
- )
-
- def connect(self, *cargs, **cparams):
- return self.dbapi.connect(*cargs, **cparams)
-
- def create_connect_args(self, url):
- opts = url.translate_connect_args()
- opts.update(url.query)
- return [[], opts]
-
- def do_begin(self, connection):
- """Implementations might want to put logic here for turning
- autocommit on/off, etc.
- """
-
- pass
-
- def do_rollback(self, connection):
- """Implementations might want to put logic here for turning
- autocommit on/off, etc.
- """
-
- connection.rollback()
-
- def do_commit(self, connection):
- """Implementations might want to put logic here for turning
- autocommit on/off, etc.
- """
-
- connection.commit()
-
- def create_xid(self):
- """Create a random two-phase transaction ID.
-
- This id will be passed to do_begin_twophase(), do_rollback_twophase(),
- do_commit_twophase(). Its format is unspecified.
- """
-
- return "_sa_%032x" % random.randint(0, 2 ** 128)
-
- def do_savepoint(self, connection, name):
- connection.execute(expression.SavepointClause(name))
-
- def do_rollback_to_savepoint(self, connection, name):
- connection.execute(expression.RollbackToSavepointClause(name))
-
- def do_release_savepoint(self, connection, name):
- connection.execute(expression.ReleaseSavepointClause(name))
-
- def do_executemany(self, cursor, statement, parameters, context=None):
- cursor.executemany(statement, parameters)
-
- def do_execute(self, cursor, statement, parameters, context=None):
- cursor.execute(statement, parameters)
-
- def is_disconnect(self, e, connection, cursor):
- return False
-
- def reset_isolation_level(self, dbapi_conn):
- # default_isolation_level is read from the first conenction
- # after the initial set of 'isolation_level', if any, so is
- # the configured default of this dialect.
- self.set_isolation_level(dbapi_conn, self.default_isolation_level)
-
-class DefaultExecutionContext(base.ExecutionContext):
- isinsert = False
- isupdate = False
- isdelete = False
- isddl = False
- executemany = False
- result_map = None
- compiled = None
- statement = None
- _is_implicit_returning = False
- _is_explicit_returning = False
-
- @classmethod
- def _init_ddl(cls, dialect, connection, dbapi_connection, compiled_ddl):
- """Initialize execution context for a DDLElement construct."""
-
- self = cls.__new__(cls)
- self.dialect = dialect
- self.root_connection = connection
- self._dbapi_connection = dbapi_connection
- self.engine = connection.engine
-
- self.compiled = compiled = compiled_ddl
- self.isddl = True
-
- self.execution_options = compiled.statement._execution_options
- if connection._execution_options:
- self.execution_options = dict(self.execution_options)
- self.execution_options.update(connection._execution_options)
-
- if not dialect.supports_unicode_statements:
- self.unicode_statement = unicode(compiled)
- self.statement = dialect._encoder(self.unicode_statement)[0]
- else:
- self.statement = self.unicode_statement = unicode(compiled)
-
- self.cursor = self.create_cursor()
- self.compiled_parameters = []
-
- if dialect.positional:
- self.parameters = [dialect.execute_sequence_format()]
- else:
- self.parameters = [{}]
-
- return self
-
- @classmethod
- def _init_compiled(cls, dialect, connection, dbapi_connection, compiled, parameters):
- """Initialize execution context for a Compiled construct."""
-
- self = cls.__new__(cls)
- self.dialect = dialect
- self.root_connection = connection
- self._dbapi_connection = dbapi_connection
- self.engine = connection.engine
-
- self.compiled = compiled
-
- if not compiled.can_execute:
- raise exc.ArgumentError("Not an executable clause")
-
- self.execution_options = compiled.statement._execution_options
- if connection._execution_options:
- self.execution_options = dict(self.execution_options)
- self.execution_options.update(connection._execution_options)
-
- # compiled clauseelement. process bind params, process table defaults,
- # track collections used by ResultProxy to target and process results
-
- self.result_map = compiled.result_map
-
- self.unicode_statement = unicode(compiled)
- if not dialect.supports_unicode_statements:
- self.statement = self.unicode_statement.encode(self.dialect.encoding)
- else:
- self.statement = self.unicode_statement
-
- self.isinsert = compiled.isinsert
- self.isupdate = compiled.isupdate
- self.isdelete = compiled.isdelete
-
- if self.isinsert or self.isupdate or self.isdelete:
- self._is_explicit_returning = compiled.statement._returning
- self._is_implicit_returning = compiled.returning and \
- not compiled.statement._returning
-
- if not parameters:
- self.compiled_parameters = [compiled.construct_params()]
- else:
- self.compiled_parameters = \
- [compiled.construct_params(m, _group_number=grp) for
- grp,m in enumerate(parameters)]
-
- self.executemany = len(parameters) > 1
-
- self.cursor = self.create_cursor()
- if self.isinsert or self.isupdate:
- self.postfetch_cols = self.compiled.postfetch
- self.prefetch_cols = self.compiled.prefetch
- self.__process_defaults()
-
- processors = compiled._bind_processors
-
- # Convert the dictionary of bind parameter values
- # into a dict or list to be sent to the DBAPI's
- # execute() or executemany() method.
- parameters = []
- if dialect.positional:
- for compiled_params in self.compiled_parameters:
- param = []
- for key in self.compiled.positiontup:
- if key in processors:
- param.append(processors[key](compiled_params[key]))
- else:
- param.append(compiled_params[key])
- parameters.append(dialect.execute_sequence_format(param))
- else:
- encode = not dialect.supports_unicode_statements
- for compiled_params in self.compiled_parameters:
- param = {}
- if encode:
- for key in compiled_params:
- if key in processors:
- param[dialect._encoder(key)[0]] = \
- processors[key](compiled_params[key])
- else:
- param[dialect._encoder(key)[0]] = compiled_params[key]
- else:
- for key in compiled_params:
- if key in processors:
- param[key] = processors[key](compiled_params[key])
- else:
- param[key] = compiled_params[key]
- parameters.append(param)
- self.parameters = dialect.execute_sequence_format(parameters)
-
- return self
-
- @classmethod
- def _init_statement(cls, dialect, connection, dbapi_connection, statement, parameters):
- """Initialize execution context for a string SQL statement."""
-
- self = cls.__new__(cls)
- self.dialect = dialect
- self.root_connection = connection
- self._dbapi_connection = dbapi_connection
- self.engine = connection.engine
-
- # plain text statement
- self.execution_options = connection._execution_options
-
- if not parameters:
- if self.dialect.positional:
- self.parameters = [dialect.execute_sequence_format()]
- else:
- self.parameters = [{}]
- elif isinstance(parameters[0], dialect.execute_sequence_format):
- self.parameters = parameters
- elif isinstance(parameters[0], dict):
- if dialect.supports_unicode_statements:
- self.parameters = parameters
- else:
- self.parameters= [
- dict((dialect._encoder(k)[0], d[k]) for k in d)
- for d in parameters
- ] or [{}]
- else:
- self.parameters = [dialect.execute_sequence_format(p)
- for p in parameters]
-
- self.executemany = len(parameters) > 1
-
- if not dialect.supports_unicode_statements and isinstance(statement, unicode):
- self.unicode_statement = statement
- self.statement = dialect._encoder(statement)[0]
- else:
- self.statement = self.unicode_statement = statement
-
- self.cursor = self.create_cursor()
- return self
-
- @classmethod
- def _init_default(cls, dialect, connection, dbapi_connection):
- """Initialize execution context for a ColumnDefault construct."""
-
- self = cls.__new__(cls)
- self.dialect = dialect
- self.root_connection = connection
- self._dbapi_connection = dbapi_connection
- self.engine = connection.engine
- self.execution_options = connection._execution_options
- self.cursor = self.create_cursor()
- return self
-
- @util.memoized_property
- def is_crud(self):
- return self.isinsert or self.isupdate or self.isdelete
-
- @util.memoized_property
- def should_autocommit(self):
- autocommit = self.execution_options.get('autocommit',
- not self.compiled and
- self.statement and
- expression.PARSE_AUTOCOMMIT
- or False)
-
- if autocommit is expression.PARSE_AUTOCOMMIT:
- return self.should_autocommit_text(self.unicode_statement)
- else:
- return autocommit
-
- def _execute_scalar(self, stmt, type_):
- """Execute a string statement on the current cursor, returning a
- scalar result.
-
- Used to fire off sequences, default phrases, and "select lastrowid"
- types of statements individually or in the context of a parent INSERT
- or UPDATE statement.
-
- """
-
- conn = self.root_connection
- if isinstance(stmt, unicode) and \
- not self.dialect.supports_unicode_statements:
- stmt = self.dialect._encoder(stmt)[0]
-
- if self.dialect.positional:
- default_params = self.dialect.execute_sequence_format()
- else:
- default_params = {}
-
- conn._cursor_execute(self.cursor, stmt, default_params)
- r = self.cursor.fetchone()[0]
- if type_ is not None:
- # apply type post processors to the result
- proc = type_._cached_result_processor(
- self.dialect,
- self.cursor.description[0][1]
- )
- if proc:
- return proc(r)
- return r
-
- @property
- def connection(self):
- return self.root_connection._branch()
-
- def should_autocommit_text(self, statement):
- return AUTOCOMMIT_REGEXP.match(statement)
-
- def create_cursor(self):
- return self._dbapi_connection.cursor()
-
- def pre_exec(self):
- pass
-
- def post_exec(self):
- pass
-
- def get_lastrowid(self):
- """return self.cursor.lastrowid, or equivalent, after an INSERT.
-
- This may involve calling special cursor functions,
- issuing a new SELECT on the cursor (or a new one),
- or returning a stored value that was
- calculated within post_exec().
-
- This function will only be called for dialects
- which support "implicit" primary key generation,
- keep preexecute_autoincrement_sequences set to False,
- and when no explicit id value was bound to the
- statement.
-
- The function is called once, directly after
- post_exec() and before the transaction is committed
- or ResultProxy is generated. If the post_exec()
- method assigns a value to `self._lastrowid`, the
- value is used in place of calling get_lastrowid().
-
- Note that this method is *not* equivalent to the
- ``lastrowid`` method on ``ResultProxy``, which is a
- direct proxy to the DBAPI ``lastrowid`` accessor
- in all cases.
-
- """
- return self.cursor.lastrowid
-
- def handle_dbapi_exception(self, e):
- pass
-
- def get_result_proxy(self):
- return base.ResultProxy(self)
-
- @property
- def rowcount(self):
- return self.cursor.rowcount
-
- def supports_sane_rowcount(self):
- return self.dialect.supports_sane_rowcount
-
- def supports_sane_multi_rowcount(self):
- return self.dialect.supports_sane_multi_rowcount
-
- def post_insert(self):
- if not self._is_implicit_returning and \
- self.dialect.postfetch_lastrowid and \
- (not self.inserted_primary_key or \
- None in self.inserted_primary_key):
-
- table = self.compiled.statement.table
- lastrowid = self.get_lastrowid()
-
- autoinc_col = table._autoincrement_column
- if autoinc_col is not None:
- # apply type post processors to the lastrowid
- proc = autoinc_col.type._cached_result_processor(self.dialect, None)
- if proc is not None:
- lastrowid = proc(lastrowid)
-
- self.inserted_primary_key = [
- c is autoinc_col and lastrowid or v
- for c, v in zip(
- table.primary_key,
- self.inserted_primary_key)
- ]
-
- def _fetch_implicit_returning(self, resultproxy):
- table = self.compiled.statement.table
- row = resultproxy.fetchone()
-
- ipk = []
- for c, v in zip(table.primary_key, self.inserted_primary_key):
- if v is not None:
- ipk.append(v)
- else:
- ipk.append(row[c])
-
- self.inserted_primary_key = ipk
-
- def lastrow_has_defaults(self):
- return (self.isinsert or self.isupdate) and \
- bool(self.postfetch_cols)
-
- def set_input_sizes(self, translate=None, exclude_types=None):
- """Given a cursor and ClauseParameters, call the appropriate
- style of ``setinputsizes()`` on the cursor, using DB-API types
- from the bind parameter's ``TypeEngine`` objects.
-
- This method only called by those dialects which require it,
- currently cx_oracle.
-
- """
-
- if not hasattr(self.compiled, 'bind_names'):
- return
-
- types = dict(
- (self.compiled.bind_names[bindparam], bindparam.type)
- for bindparam in self.compiled.bind_names)
-
- if self.dialect.positional:
- inputsizes = []
- for key in self.compiled.positiontup:
- typeengine = types[key]
- dbtype = typeengine.dialect_impl(self.dialect).get_dbapi_type(self.dialect.dbapi)
- if dbtype is not None and (not exclude_types or dbtype not in exclude_types):
- inputsizes.append(dbtype)
- try:
- self.cursor.setinputsizes(*inputsizes)
- except Exception, e:
- self.root_connection._handle_dbapi_exception(e, None, None, None, self)
- raise
- else:
- inputsizes = {}
- for key in self.compiled.bind_names.values():
- typeengine = types[key]
- dbtype = typeengine.dialect_impl(self.dialect).get_dbapi_type(self.dialect.dbapi)
- if dbtype is not None and (not exclude_types or dbtype not in exclude_types):
- if translate:
- key = translate.get(key, key)
- inputsizes[self.dialect._encoder(key)[0]] = dbtype
- try:
- self.cursor.setinputsizes(**inputsizes)
- except Exception, e:
- self.root_connection._handle_dbapi_exception(e, None, None, None, self)
- raise
-
- def _exec_default(self, default, type_):
- if default.is_sequence:
- return self.fire_sequence(default, type_)
- elif default.is_callable:
- return default.arg(self)
- elif default.is_clause_element:
- # TODO: expensive branching here should be
- # pulled into _exec_scalar()
- conn = self.connection
- c = expression.select([default.arg]).compile(bind=conn)
- return conn._execute_compiled(c, (), {}).scalar()
- else:
- return default.arg
-
- def get_insert_default(self, column):
- if column.default is None:
- return None
- else:
- return self._exec_default(column.default, column.type)
-
- def get_update_default(self, column):
- if column.onupdate is None:
- return None
- else:
- return self._exec_default(column.onupdate, column.type)
-
- def __process_defaults(self):
- """Generate default values for compiled insert/update statements,
- and generate inserted_primary_key collection.
- """
-
- if self.executemany:
- if len(self.compiled.prefetch):
- scalar_defaults = {}
-
- # pre-determine scalar Python-side defaults
- # to avoid many calls of get_insert_default()/
- # get_update_default()
- for c in self.prefetch_cols:
- if self.isinsert and c.default and c.default.is_scalar:
- scalar_defaults[c] = c.default.arg
- elif self.isupdate and c.onupdate and c.onupdate.is_scalar:
- scalar_defaults[c] = c.onupdate.arg
-
- for param in self.compiled_parameters:
- self.current_parameters = param
- for c in self.prefetch_cols:
- if c in scalar_defaults:
- val = scalar_defaults[c]
- elif self.isinsert:
- val = self.get_insert_default(c)
- else:
- val = self.get_update_default(c)
- if val is not None:
- param[c.key] = val
- del self.current_parameters
- else:
- self.current_parameters = compiled_parameters = \
- self.compiled_parameters[0]
-
- for c in self.compiled.prefetch:
- if self.isinsert:
- val = self.get_insert_default(c)
- else:
- val = self.get_update_default(c)
-
- if val is not None:
- compiled_parameters[c.key] = val
- del self.current_parameters
-
- if self.isinsert:
- self.inserted_primary_key = [
- self.compiled_parameters[0].get(c.key, None)
- for c in self.compiled.\
- statement.table.primary_key
- ]
-
-
-DefaultDialect.execution_ctx_cls = DefaultExecutionContext
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/reflection.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/reflection.py
deleted file mode 100755
index ca436032..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/reflection.py
+++ /dev/null
@@ -1,477 +0,0 @@
-# engine/reflection.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Provides an abstraction for obtaining database schema information.
-
-Usage Notes:
-
-Here are some general conventions when accessing the low level inspector
-methods such as get_table_names, get_columns, etc.
-
-1. Inspector methods return lists of dicts in most cases for the following
- reasons:
-
- * They're both standard types that can be serialized.
- * Using a dict instead of a tuple allows easy expansion of attributes.
- * Using a list for the outer structure maintains order and is easy to work
- with (e.g. list comprehension [d['name'] for d in cols]).
-
-2. Records that contain a name, such as the column name in a column record
- use the key 'name'. So for most return values, each record will have a
- 'name' attribute..
-"""
-
-import sqlalchemy
-from sqlalchemy import exc, sql
-from sqlalchemy import util
-from sqlalchemy.types import TypeEngine
-from sqlalchemy import schema as sa_schema
-
-
-@util.decorator
-def cache(fn, self, con, *args, **kw):
- info_cache = kw.get('info_cache', None)
- if info_cache is None:
- return fn(self, con, *args, **kw)
- key = (
- fn.__name__,
- tuple(a for a in args if isinstance(a, basestring)),
- tuple((k, v) for k, v in kw.iteritems() if isinstance(v, (basestring, int, float)))
- )
- ret = info_cache.get(key)
- if ret is None:
- ret = fn(self, con, *args, **kw)
- info_cache[key] = ret
- return ret
-
-
-class Inspector(object):
- """Performs database schema inspection.
-
- The Inspector acts as a proxy to the reflection methods of the
- :class:`~sqlalchemy.engine.base.Dialect`, providing a
- consistent interface as well as caching support for previously
- fetched metadata.
-
- The preferred method to construct an :class:`.Inspector` is via the
- :meth:`Inspector.from_engine` method. I.e.::
-
- engine = create_engine('...')
- insp = Inspector.from_engine(engine)
-
- Where above, the :class:`~sqlalchemy.engine.base.Dialect` may opt
- to return an :class:`.Inspector` subclass that provides additional
- methods specific to the dialect's target database.
-
- """
-
- def __init__(self, bind):
- """Initialize a new :class:`.Inspector`.
-
- :param bind: a :class:`~sqlalchemy.engine.base.Connectable`,
- which is typically an instance of
- :class:`~sqlalchemy.engine.base.Engine` or
- :class:`~sqlalchemy.engine.base.Connection`.
-
- For a dialect-specific instance of :class:`.Inspector`, see
- :meth:`Inspector.from_engine`
-
- """
- # this might not be a connection, it could be an engine.
- self.bind = bind
-
- # set the engine
- if hasattr(bind, 'engine'):
- self.engine = bind.engine
- else:
- self.engine = bind
-
- if self.engine is bind:
- # if engine, ensure initialized
- bind.connect().close()
-
- self.dialect = self.engine.dialect
- self.info_cache = {}
-
- @classmethod
- def from_engine(cls, bind):
- """Construct a new dialect-specific Inspector object from the given engine or connection.
-
- :param bind: a :class:`~sqlalchemy.engine.base.Connectable`,
- which is typically an instance of
- :class:`~sqlalchemy.engine.base.Engine` or
- :class:`~sqlalchemy.engine.base.Connection`.
-
- This method differs from direct a direct constructor call of :class:`.Inspector`
- in that the :class:`~sqlalchemy.engine.base.Dialect` is given a chance to provide
- a dialect-specific :class:`.Inspector` instance, which may provide additional
- methods.
-
- See the example at :class:`.Inspector`.
-
- """
- if hasattr(bind.dialect, 'inspector'):
- return bind.dialect.inspector(bind)
- return Inspector(bind)
-
- @property
- def default_schema_name(self):
- """Return the default schema name presented by the dialect
- for the current engine's database user.
-
- E.g. this is typically ``public`` for Postgresql and ``dbo``
- for SQL Server.
-
- """
- return self.dialect.default_schema_name
-
- def get_schema_names(self):
- """Return all schema names.
- """
-
- if hasattr(self.dialect, 'get_schema_names'):
- return self.dialect.get_schema_names(self.bind,
- info_cache=self.info_cache)
- return []
-
- def get_table_names(self, schema=None, order_by=None):
- """Return all table names in `schema`.
-
- :param schema: Optional, retrieve names from a non-default schema.
- :param order_by: Optional, may be the string "foreign_key" to sort
- the result on foreign key dependencies.
-
- This should probably not return view names or maybe it should return
- them with an indicator t or v.
- """
-
- if hasattr(self.dialect, 'get_table_names'):
- tnames = self.dialect.get_table_names(self.bind,
- schema,
- info_cache=self.info_cache)
- else:
- tnames = self.engine.table_names(schema)
- if order_by == 'foreign_key':
- ordered_tnames = tnames[:]
- # Order based on foreign key dependencies.
- for tname in tnames:
- table_pos = tnames.index(tname)
- fkeys = self.get_foreign_keys(tname, schema)
- for fkey in fkeys:
- rtable = fkey['referred_table']
- if rtable in ordered_tnames:
- ref_pos = ordered_tnames.index(rtable)
- # Make sure it's lower in the list than anything it
- # references.
- if table_pos > ref_pos:
- ordered_tnames.pop(table_pos) # rtable moves up 1
- # insert just below rtable
- ordered_tnames.index(ref_pos, tname)
- tnames = ordered_tnames
- return tnames
-
- def get_table_options(self, table_name, schema=None, **kw):
- """Return a dictionary of options specified when the table of the given name was created.
-
- This currently includes some options that apply to MySQL tables.
-
- """
- if hasattr(self.dialect, 'get_table_options'):
- return self.dialect.get_table_options(self.bind, table_name, schema,
- info_cache=self.info_cache,
- **kw)
- return {}
-
- def get_view_names(self, schema=None):
- """Return all view names in `schema`.
-
- :param schema: Optional, retrieve names from a non-default schema.
- """
-
- return self.dialect.get_view_names(self.bind, schema,
- info_cache=self.info_cache)
-
- def get_view_definition(self, view_name, schema=None):
- """Return definition for `view_name`.
-
- :param schema: Optional, retrieve names from a non-default schema.
- """
-
- return self.dialect.get_view_definition(
- self.bind, view_name, schema, info_cache=self.info_cache)
-
- def get_columns(self, table_name, schema=None, **kw):
- """Return information about columns in `table_name`.
-
- Given a string `table_name` and an optional string `schema`, return
- column information as a list of dicts with these keys:
-
- name
- the column's name
-
- type
- :class:`~sqlalchemy.types.TypeEngine`
-
- nullable
- boolean
-
- default
- the column's default value
-
- attrs
- dict containing optional column attributes
- """
-
- col_defs = self.dialect.get_columns(self.bind, table_name, schema,
- info_cache=self.info_cache,
- **kw)
- for col_def in col_defs:
- # make this easy and only return instances for coltype
- coltype = col_def['type']
- if not isinstance(coltype, TypeEngine):
- col_def['type'] = coltype()
- return col_defs
-
- def get_primary_keys(self, table_name, schema=None, **kw):
- """Return information about primary keys in `table_name`.
-
- Given a string `table_name`, and an optional string `schema`, return
- primary key information as a list of column names.
- """
-
- pkeys = self.dialect.get_primary_keys(self.bind, table_name, schema,
- info_cache=self.info_cache,
- **kw)
-
- return pkeys
-
- def get_pk_constraint(self, table_name, schema=None, **kw):
- """Return information about primary key constraint on `table_name`.
-
- Given a string `table_name`, and an optional string `schema`, return
- primary key information as a dictionary with these keys:
-
- constrained_columns
- a list of column names that make up the primary key
-
- name
- optional name of the primary key constraint.
-
- """
- pkeys = self.dialect.get_pk_constraint(self.bind, table_name, schema,
- info_cache=self.info_cache,
- **kw)
-
- return pkeys
-
-
- def get_foreign_keys(self, table_name, schema=None, **kw):
- """Return information about foreign_keys in `table_name`.
-
- Given a string `table_name`, and an optional string `schema`, return
- foreign key information as a list of dicts with these keys:
-
- constrained_columns
- a list of column names that make up the foreign key
-
- referred_schema
- the name of the referred schema
-
- referred_table
- the name of the referred table
-
- referred_columns
- a list of column names in the referred table that correspond to
- constrained_columns
-
- name
- optional name of the foreign key constraint.
-
- \**kw
- other options passed to the dialect's get_foreign_keys() method.
-
- """
-
- fk_defs = self.dialect.get_foreign_keys(self.bind, table_name, schema,
- info_cache=self.info_cache,
- **kw)
- return fk_defs
-
- def get_indexes(self, table_name, schema=None, **kw):
- """Return information about indexes in `table_name`.
-
- Given a string `table_name` and an optional string `schema`, return
- index information as a list of dicts with these keys:
-
- name
- the index's name
-
- column_names
- list of column names in order
-
- unique
- boolean
-
- \**kw
- other options passed to the dialect's get_indexes() method.
- """
-
- indexes = self.dialect.get_indexes(self.bind, table_name,
- schema,
- info_cache=self.info_cache, **kw)
- return indexes
-
- def reflecttable(self, table, include_columns):
- """Given a Table object, load its internal constructs based on introspection.
-
- This is the underlying method used by most dialects to produce
- table reflection. Direct usage is like::
-
- from sqlalchemy import create_engine, MetaData, Table
- from sqlalchemy.engine import reflection
-
- engine = create_engine('...')
- meta = MetaData()
- user_table = Table('user', meta)
- insp = Inspector.from_engine(engine)
- insp.reflecttable(user_table, None)
-
- :param table: a :class:`~sqlalchemy.schema.Table` instance.
- :param include_columns: a list of string column names to include
- in the reflection process. If ``None``, all columns are reflected.
-
- """
- dialect = self.bind.dialect
-
- # MySQL dialect does this. Applicable with other dialects?
- if hasattr(dialect, '_connection_charset') \
- and hasattr(dialect, '_adjust_casing'):
- charset = dialect._connection_charset
- dialect._adjust_casing(table)
-
- # table attributes we might need.
- reflection_options = dict(
- (k, table.kwargs.get(k)) for k in dialect.reflection_options if k in table.kwargs)
-
- schema = table.schema
- table_name = table.name
-
- # apply table options
- tbl_opts = self.get_table_options(table_name, schema, **table.kwargs)
- if tbl_opts:
- table.kwargs.update(tbl_opts)
-
- # table.kwargs will need to be passed to each reflection method. Make
- # sure keywords are strings.
- tblkw = table.kwargs.copy()
- for (k, v) in tblkw.items():
- del tblkw[k]
- tblkw[str(k)] = v
-
- # Py2K
- if isinstance(schema, str):
- schema = schema.decode(dialect.encoding)
- if isinstance(table_name, str):
- table_name = table_name.decode(dialect.encoding)
- # end Py2K
-
- # columns
- found_table = False
- for col_d in self.get_columns(table_name, schema, **tblkw):
- found_table = True
- table.dispatch.column_reflect(table, col_d)
-
- name = col_d['name']
- if include_columns and name not in include_columns:
- continue
-
- coltype = col_d['type']
- col_kw = {
- 'nullable':col_d['nullable'],
- }
- for k in ('autoincrement', 'quote', 'info', 'key'):
- if k in col_d:
- col_kw[k] = col_d[k]
-
- colargs = []
- if col_d.get('default') is not None:
- # the "default" value is assumed to be a literal SQL expression,
- # so is wrapped in text() so that no quoting occurs on re-issuance.
- colargs.append(
- sa_schema.DefaultClause(
- sql.text(col_d['default']), _reflected=True
- )
- )
-
- if 'sequence' in col_d:
- # TODO: mssql, maxdb and sybase are using this.
- seq = col_d['sequence']
- sequence = sa_schema.Sequence(seq['name'], 1, 1)
- if 'start' in seq:
- sequence.start = seq['start']
- if 'increment' in seq:
- sequence.increment = seq['increment']
- colargs.append(sequence)
-
- col = sa_schema.Column(name, coltype, *colargs, **col_kw)
- table.append_column(col)
-
- if not found_table:
- raise exc.NoSuchTableError(table.name)
-
- # Primary keys
- pk_cons = self.get_pk_constraint(table_name, schema, **tblkw)
- if pk_cons:
- primary_key_constraint = sa_schema.PrimaryKeyConstraint(name=pk_cons.get('name'),
- *[table.c[pk] for pk in pk_cons['constrained_columns']
- if pk in table.c]
- )
-
- table.append_constraint(primary_key_constraint)
-
- # Foreign keys
- fkeys = self.get_foreign_keys(table_name, schema, **tblkw)
- for fkey_d in fkeys:
- conname = fkey_d['name']
- constrained_columns = fkey_d['constrained_columns']
- referred_schema = fkey_d['referred_schema']
- referred_table = fkey_d['referred_table']
- referred_columns = fkey_d['referred_columns']
- refspec = []
- if referred_schema is not None:
- sa_schema.Table(referred_table, table.metadata,
- autoload=True, schema=referred_schema,
- autoload_with=self.bind,
- **reflection_options
- )
- for column in referred_columns:
- refspec.append(".".join(
- [referred_schema, referred_table, column]))
- else:
- sa_schema.Table(referred_table, table.metadata, autoload=True,
- autoload_with=self.bind,
- **reflection_options
- )
- for column in referred_columns:
- refspec.append(".".join([referred_table, column]))
- table.append_constraint(
- sa_schema.ForeignKeyConstraint(constrained_columns, refspec,
- conname, link_to_name=True))
- # Indexes
- indexes = self.get_indexes(table_name, schema)
- for index_d in indexes:
- name = index_d['name']
- columns = index_d['column_names']
- unique = index_d['unique']
- flavor = index_d.get('type', 'unknown type')
- if include_columns and \
- not set(columns).issubset(include_columns):
- util.warn(
- "Omitting %s KEY for (%s), key covers omitted columns." %
- (flavor, ', '.join(columns)))
- continue
- sa_schema.Index(name, *[table.columns[c] for c in columns],
- **dict(unique=unique))
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/strategies.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/strategies.py
deleted file mode 100755
index eee19ee1..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/strategies.py
+++ /dev/null
@@ -1,242 +0,0 @@
-# engine/strategies.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Strategies for creating new instances of Engine types.
-
-These are semi-private implementation classes which provide the
-underlying behavior for the "strategy" keyword argument available on
-:func:`~sqlalchemy.engine.create_engine`. Current available options are
-``plain``, ``threadlocal``, and ``mock``.
-
-New strategies can be added via new ``EngineStrategy`` classes.
-"""
-
-from operator import attrgetter
-
-from sqlalchemy.engine import base, threadlocal, url
-from sqlalchemy import util, exc, event
-from sqlalchemy import pool as poollib
-
-strategies = {}
-
-
-class EngineStrategy(object):
- """An adaptor that processes input arguements and produces an Engine.
-
- Provides a ``create`` method that receives input arguments and
- produces an instance of base.Engine or a subclass.
-
- """
-
- def __init__(self):
- strategies[self.name] = self
-
- def create(self, *args, **kwargs):
- """Given arguments, returns a new Engine instance."""
-
- raise NotImplementedError()
-
-
-class DefaultEngineStrategy(EngineStrategy):
- """Base class for built-in stratgies."""
-
- def create(self, name_or_url, **kwargs):
- # create url.URL object
- u = url.make_url(name_or_url)
-
- dialect_cls = u.get_dialect()
-
- dialect_args = {}
- # consume dialect arguments from kwargs
- for k in util.get_cls_kwargs(dialect_cls):
- if k in kwargs:
- dialect_args[k] = kwargs.pop(k)
-
- dbapi = kwargs.pop('module', None)
- if dbapi is None:
- dbapi_args = {}
- for k in util.get_func_kwargs(dialect_cls.dbapi):
- if k in kwargs:
- dbapi_args[k] = kwargs.pop(k)
- dbapi = dialect_cls.dbapi(**dbapi_args)
-
- dialect_args['dbapi'] = dbapi
-
- # create dialect
- dialect = dialect_cls(**dialect_args)
-
- # assemble connection arguments
- (cargs, cparams) = dialect.create_connect_args(u)
- cparams.update(kwargs.pop('connect_args', {}))
-
- # look for existing pool or create
- pool = kwargs.pop('pool', None)
- if pool is None:
- def connect():
- try:
- return dialect.connect(*cargs, **cparams)
- except Exception, e:
- # Py3K
- #raise exc.DBAPIError.instance(None, None,
- # e, dialect.dbapi.Error) from e
- # Py2K
- import sys
- raise exc.DBAPIError.instance(
- None, None, e, dialect.dbapi.Error), \
- None, sys.exc_info()[2]
- # end Py2K
-
- creator = kwargs.pop('creator', connect)
-
- poolclass = kwargs.pop('poolclass', None)
- if poolclass is None:
- poolclass = dialect_cls.get_pool_class(u)
- pool_args = {}
-
- # consume pool arguments from kwargs, translating a few of
- # the arguments
- translate = {'logging_name': 'pool_logging_name',
- 'echo': 'echo_pool',
- 'timeout': 'pool_timeout',
- 'recycle': 'pool_recycle',
- 'events':'pool_events',
- 'use_threadlocal':'pool_threadlocal'}
- for k in util.get_cls_kwargs(poolclass):
- tk = translate.get(k, k)
- if tk in kwargs:
- pool_args[k] = kwargs.pop(tk)
- pool = poolclass(creator, **pool_args)
- else:
- if isinstance(pool, poollib._DBProxy):
- pool = pool.get_pool(*cargs, **cparams)
- else:
- pool = pool
-
- # create engine.
- engineclass = self.engine_cls
- engine_args = {}
- for k in util.get_cls_kwargs(engineclass):
- if k in kwargs:
- engine_args[k] = kwargs.pop(k)
-
- _initialize = kwargs.pop('_initialize', True)
-
- # all kwargs should be consumed
- if kwargs:
- raise TypeError(
- "Invalid argument(s) %s sent to create_engine(), "
- "using configuration %s/%s/%s. Please check that the "
- "keyword arguments are appropriate for this combination "
- "of components." % (','.join("'%s'" % k for k in kwargs),
- dialect.__class__.__name__,
- pool.__class__.__name__,
- engineclass.__name__))
-
- engine = engineclass(pool, dialect, u, **engine_args)
-
- if _initialize:
- do_on_connect = dialect.on_connect()
- if do_on_connect:
- def on_connect(dbapi_connection, connection_record):
- conn = getattr(dbapi_connection, '_sqla_unwrap', dbapi_connection)
- if conn is None:
- return
- do_on_connect(conn)
-
- event.listen(pool, 'first_connect', on_connect)
- event.listen(pool, 'connect', on_connect)
-
- def first_connect(dbapi_connection, connection_record):
- c = base.Connection(engine, connection=dbapi_connection)
-
- # TODO: removing this allows the on connect activities
- # to generate events. tests currently assume these aren't
- # sent. do we want users to get all the initial connect
- # activities as events ?
- c._has_events = False
-
- dialect.initialize(c)
- event.listen(pool, 'first_connect', first_connect)
-
- return engine
-
-
-class PlainEngineStrategy(DefaultEngineStrategy):
- """Strategy for configuring a regular Engine."""
-
- name = 'plain'
- engine_cls = base.Engine
-
-PlainEngineStrategy()
-
-
-class ThreadLocalEngineStrategy(DefaultEngineStrategy):
- """Strategy for configuring an Engine with thredlocal behavior."""
-
- name = 'threadlocal'
- engine_cls = threadlocal.TLEngine
-
-ThreadLocalEngineStrategy()
-
-
-class MockEngineStrategy(EngineStrategy):
- """Strategy for configuring an Engine-like object with mocked execution.
-
- Produces a single mock Connectable object which dispatches
- statement execution to a passed-in function.
-
- """
-
- name = 'mock'
-
- def create(self, name_or_url, executor, **kwargs):
- # create url.URL object
- u = url.make_url(name_or_url)
-
- dialect_cls = u.get_dialect()
-
- dialect_args = {}
- # consume dialect arguments from kwargs
- for k in util.get_cls_kwargs(dialect_cls):
- if k in kwargs:
- dialect_args[k] = kwargs.pop(k)
-
- # create dialect
- dialect = dialect_cls(**dialect_args)
-
- return MockEngineStrategy.MockConnection(dialect, executor)
-
- class MockConnection(base.Connectable):
- def __init__(self, dialect, execute):
- self._dialect = dialect
- self.execute = execute
-
- engine = property(lambda s: s)
- dialect = property(attrgetter('_dialect'))
- name = property(lambda s: s._dialect.name)
-
- def contextual_connect(self, **kwargs):
- return self
-
- def compiler(self, statement, parameters, **kwargs):
- return self._dialect.compiler(
- statement, parameters, engine=self, **kwargs)
-
- def create(self, entity, **kwargs):
- kwargs['checkfirst'] = False
- from sqlalchemy.engine import ddl
-
- ddl.SchemaGenerator(self.dialect, self, **kwargs).traverse(entity)
-
- def drop(self, entity, **kwargs):
- kwargs['checkfirst'] = False
- from sqlalchemy.engine import ddl
- ddl.SchemaDropper(self.dialect, self, **kwargs).traverse(entity)
-
- def execute(self, object, *multiparams, **params):
- raise NotImplementedError()
-
-MockEngineStrategy()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/threadlocal.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/threadlocal.py
deleted file mode 100755
index 45780ad0..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/threadlocal.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# engine/threadlocal.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Provides a thread-local transactional wrapper around the root Engine class.
-
-The ``threadlocal`` module is invoked when using the ``strategy="threadlocal"`` flag
-with :func:`~sqlalchemy.engine.create_engine`. This module is semi-private and is
-invoked automatically when the threadlocal engine strategy is used.
-"""
-
-from sqlalchemy import util, event
-from sqlalchemy.engine import base
-import weakref
-
-class TLConnection(base.Connection):
- def __init__(self, *arg, **kw):
- super(TLConnection, self).__init__(*arg, **kw)
- self.__opencount = 0
-
- def _increment_connect(self):
- self.__opencount += 1
- return self
-
- def close(self):
- if self.__opencount == 1:
- base.Connection.close(self)
- self.__opencount -= 1
-
- def _force_close(self):
- self.__opencount = 0
- base.Connection.close(self)
-
-class TLEngine(base.Engine):
- """An Engine that includes support for thread-local managed transactions."""
-
- _tl_connection_cls = TLConnection
-
- def __init__(self, *args, **kwargs):
- super(TLEngine, self).__init__(*args, **kwargs)
- self._connections = util.threading.local()
-
-
- def contextual_connect(self, **kw):
- if not hasattr(self._connections, 'conn'):
- connection = None
- else:
- connection = self._connections.conn()
-
- if connection is None or connection.closed:
- # guards against pool-level reapers, if desired.
- # or not connection.connection.is_valid:
- connection = self._tl_connection_cls(self, self.pool.connect(), **kw)
- self._connections.conn = conn = weakref.ref(connection)
-
- return connection._increment_connect()
-
- def begin_twophase(self, xid=None):
- if not hasattr(self._connections, 'trans'):
- self._connections.trans = []
- self._connections.trans.append(self.contextual_connect().begin_twophase(xid=xid))
- return self
-
- def begin_nested(self):
- if not hasattr(self._connections, 'trans'):
- self._connections.trans = []
- self._connections.trans.append(self.contextual_connect().begin_nested())
- return self
-
- def begin(self):
- if not hasattr(self._connections, 'trans'):
- self._connections.trans = []
- self._connections.trans.append(self.contextual_connect().begin())
- return self
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- if type is None:
- self.commit()
- else:
- self.rollback()
-
- def prepare(self):
- if not hasattr(self._connections, 'trans') or \
- not self._connections.trans:
- return
- self._connections.trans[-1].prepare()
-
- def commit(self):
- if not hasattr(self._connections, 'trans') or \
- not self._connections.trans:
- return
- trans = self._connections.trans.pop(-1)
- trans.commit()
-
- def rollback(self):
- if not hasattr(self._connections, 'trans') or \
- not self._connections.trans:
- return
- trans = self._connections.trans.pop(-1)
- trans.rollback()
-
- def dispose(self):
- self._connections = util.threading.local()
- super(TLEngine, self).dispose()
-
- @property
- def closed(self):
- return not hasattr(self._connections, 'conn') or \
- self._connections.conn() is None or \
- self._connections.conn().closed
-
- def close(self):
- if not self.closed:
- self.contextual_connect().close()
- connection = self._connections.conn()
- connection._force_close()
- del self._connections.conn
- self._connections.trans = []
-
- def __repr__(self):
- return 'TLEngine(%s)' % str(self.url)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/url.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/url.py
deleted file mode 100755
index 7d5e0692..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/engine/url.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# engine/url.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Provides the :class:`~sqlalchemy.engine.url.URL` class which encapsulates
-information about a database connection specification.
-
-The URL object is created automatically when :func:`~sqlalchemy.engine.create_engine` is called
-with a string argument; alternatively, the URL is a public-facing construct which can
-be used directly and is also accepted directly by ``create_engine()``.
-"""
-
-import re, cgi, sys, urllib
-from sqlalchemy import exc
-
-
-class URL(object):
- """
- Represent the components of a URL used to connect to a database.
-
- This object is suitable to be passed directly to a
- ``create_engine()`` call. The fields of the URL are parsed from a
- string by the ``module-level make_url()`` function. the string
- format of the URL is an RFC-1738-style string.
-
- All initialization parameters are available as public attributes.
-
- :param drivername: the name of the database backend.
- This name will correspond to a module in sqlalchemy/databases
- or a third party plug-in.
-
- :param username: The user name.
-
- :param password: database password.
-
- :param host: The name of the host.
-
- :param port: The port number.
-
- :param database: The database name.
-
- :param query: A dictionary of options to be passed to the
- dialect and/or the DBAPI upon connect.
-
- """
-
- def __init__(self, drivername, username=None, password=None,
- host=None, port=None, database=None, query=None):
- self.drivername = drivername
- self.username = username
- self.password = password
- self.host = host
- if port is not None:
- self.port = int(port)
- else:
- self.port = None
- self.database = database
- self.query = query or {}
-
- def __str__(self):
- s = self.drivername + "://"
- if self.username is not None:
- s += self.username
- if self.password is not None:
- s += ':' + urllib.quote_plus(self.password)
- s += "@"
- if self.host is not None:
- s += self.host
- if self.port is not None:
- s += ':' + str(self.port)
- if self.database is not None:
- s += '/' + self.database
- if self.query:
- keys = self.query.keys()
- keys.sort()
- s += '?' + "&".join("%s=%s" % (k, self.query[k]) for k in keys)
- return s
-
- def __hash__(self):
- return hash(str(self))
-
- def __eq__(self, other):
- return \
- isinstance(other, URL) and \
- self.drivername == other.drivername and \
- self.username == other.username and \
- self.password == other.password and \
- self.host == other.host and \
- self.database == other.database and \
- self.query == other.query
-
- def get_dialect(self):
- """Return the SQLAlchemy database dialect class corresponding
- to this URL's driver name.
- """
-
- try:
- if '+' in self.drivername:
- dialect, driver = self.drivername.split('+')
- else:
- dialect, driver = self.drivername, 'base'
-
- module = __import__('sqlalchemy.dialects.%s' % (dialect, )).dialects
- module = getattr(module, dialect)
- module = getattr(module, driver)
-
- return module.dialect
- except ImportError:
- module = self._load_entry_point()
- if module is not None:
- return module
- else:
- raise exc.ArgumentError(
- "Could not determine dialect for '%s'." % self.drivername)
-
- def _load_entry_point(self):
- """attempt to load this url's dialect from entry points, or return None
- if pkg_resources is not installed or there is no matching entry point.
-
- Raise ImportError if the actual load fails.
-
- """
- try:
- import pkg_resources
- except ImportError:
- return None
-
- for res in pkg_resources.iter_entry_points('sqlalchemy.dialects'):
- if res.name == self.drivername:
- return res.load()
- else:
- return None
-
- def translate_connect_args(self, names=[], **kw):
- """Translate url attributes into a dictionary of connection arguments.
-
- Returns attributes of this url (`host`, `database`, `username`,
- `password`, `port`) as a plain dictionary. The attribute names are
- used as the keys by default. Unset or false attributes are omitted
- from the final dictionary.
-
- :param \**kw: Optional, alternate key names for url attributes.
-
- :param names: Deprecated. Same purpose as the keyword-based alternate names,
- but correlates the name to the original positionally.
- """
-
- translated = {}
- attribute_names = ['host', 'database', 'username', 'password', 'port']
- for sname in attribute_names:
- if names:
- name = names.pop(0)
- elif sname in kw:
- name = kw[sname]
- else:
- name = sname
- if name is not None and getattr(self, sname, False):
- translated[name] = getattr(self, sname)
- return translated
-
-def make_url(name_or_url):
- """Given a string or unicode instance, produce a new URL instance.
-
- The given string is parsed according to the RFC 1738 spec. If an
- existing URL object is passed, just returns the object.
- """
-
- if isinstance(name_or_url, basestring):
- return _parse_rfc1738_args(name_or_url)
- else:
- return name_or_url
-
-def _parse_rfc1738_args(name):
- pattern = re.compile(r'''
- (?P<name>[\w\+]+)://
- (?:
- (?P<username>[^:/]*)
- (?::(?P<password>[^/]*))?
- @)?
- (?:
- (?P<host>[^/:]*)
- (?::(?P<port>[^/]*))?
- )?
- (?:/(?P<database>.*))?
- '''
- , re.X)
-
- m = pattern.match(name)
- if m is not None:
- components = m.groupdict()
- if components['database'] is not None:
- tokens = components['database'].split('?', 2)
- components['database'] = tokens[0]
- query = (len(tokens) > 1 and dict(cgi.parse_qsl(tokens[1]))) or None
- # Py2K
- if query is not None:
- query = dict((k.encode('ascii'), query[k]) for k in query)
- # end Py2K
- else:
- query = None
- components['query'] = query
-
- if components['password'] is not None:
- components['password'] = urllib.unquote_plus(components['password'])
-
- name = components.pop('name')
- return URL(name, **components)
- else:
- raise exc.ArgumentError(
- "Could not parse rfc1738 URL from string '%s'" % name)
-
-def _parse_keyvalue_args(name):
- m = re.match( r'(\w+)://(.*)', name)
- if m is not None:
- (name, args) = m.group(1, 2)
- opts = dict( cgi.parse_qsl( args ) )
- return URL(name, *opts)
- else:
- return None
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/event.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/event.py
deleted file mode 100755
index 4be227c5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/event.py
+++ /dev/null
@@ -1,347 +0,0 @@
-# sqlalchemy/event.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Base event API."""
-
-from sqlalchemy import util, exc
-
-CANCEL = util.symbol('CANCEL')
-NO_RETVAL = util.symbol('NO_RETVAL')
-
-def listen(target, identifier, fn, *args, **kw):
- """Register a listener function for the given target.
-
- e.g.::
-
- from sqlalchemy import event
- from sqlalchemy.schema import UniqueConstraint
-
- def unique_constraint_name(const, table):
- const.name = "uq_%s_%s" % (
- table.name,
- list(const.columns)[0].name
- )
- event.listen(
- UniqueConstraint,
- "after_parent_attach",
- unique_constraint_name)
-
- """
-
- for evt_cls in _registrars[identifier]:
- tgt = evt_cls._accept_with(target)
- if tgt is not None:
- tgt.dispatch._listen(tgt, identifier, fn, *args, **kw)
- return
- raise exc.InvalidRequestError("No such event '%s' for target '%s'" %
- (identifier,target))
-
-def listens_for(target, identifier, *args, **kw):
- """Decorate a function as a listener for the given target + identifier.
-
- e.g.::
-
- from sqlalchemy import event
- from sqlalchemy.schema import UniqueConstraint
-
- @event.listens_for(UniqueConstraint, "after_parent_attach")
- def unique_constraint_name(const, table):
- const.name = "uq_%s_%s" % (
- table.name,
- list(const.columns)[0].name
- )
- """
- def decorate(fn):
- listen(target, identifier, fn, *args, **kw)
- return fn
- return decorate
-
-def remove(target, identifier, fn):
- """Remove an event listener.
-
- Note that some event removals, particularly for those event dispatchers
- which create wrapper functions and secondary even listeners, may not yet
- be supported.
-
- """
- for evt_cls in _registrars[identifier]:
- for tgt in evt_cls._accept_with(target):
- tgt.dispatch._remove(identifier, tgt, fn, *args, **kw)
- return
-
-_registrars = util.defaultdict(list)
-
-def _is_event_name(name):
- return not name.startswith('_') and name != 'dispatch'
-
-class _UnpickleDispatch(object):
- """Serializable callable that re-generates an instance of :class:`_Dispatch`
- given a particular :class:`.Events` subclass.
-
- """
- def __call__(self, _parent_cls):
- for cls in _parent_cls.__mro__:
- if 'dispatch' in cls.__dict__:
- return cls.__dict__['dispatch'].dispatch_cls(_parent_cls)
- else:
- raise AttributeError("No class with a 'dispatch' member present.")
-
-class _Dispatch(object):
- """Mirror the event listening definitions of an Events class with
- listener collections.
-
- Classes which define a "dispatch" member will return a
- non-instantiated :class:`._Dispatch` subclass when the member
- is accessed at the class level. When the "dispatch" member is
- accessed at the instance level of its owner, an instance
- of the :class:`._Dispatch` class is returned.
-
- A :class:`._Dispatch` class is generated for each :class:`.Events`
- class defined, by the :func:`._create_dispatcher_class` function.
- The original :class:`.Events` classes remain untouched.
- This decouples the construction of :class:`.Events` subclasses from
- the implementation used by the event internals, and allows
- inspecting tools like Sphinx to work in an unsurprising
- way against the public API.
-
- """
-
- def __init__(self, _parent_cls):
- self._parent_cls = _parent_cls
-
- def __reduce__(self):
- return _UnpickleDispatch(), (self._parent_cls, )
-
- def _update(self, other, only_propagate=True):
- """Populate from the listeners in another :class:`_Dispatch`
- object."""
-
- for ls in _event_descriptors(other):
- getattr(self, ls.name)._update(ls, only_propagate=only_propagate)
-
-def _event_descriptors(target):
- return [getattr(target, k) for k in dir(target) if _is_event_name(k)]
-
-class _EventMeta(type):
- """Intercept new Event subclasses and create
- associated _Dispatch classes."""
-
- def __init__(cls, classname, bases, dict_):
- _create_dispatcher_class(cls, classname, bases, dict_)
- return type.__init__(cls, classname, bases, dict_)
-
-def _create_dispatcher_class(cls, classname, bases, dict_):
- """Create a :class:`._Dispatch` class corresponding to an
- :class:`.Events` class."""
-
- # there's all kinds of ways to do this,
- # i.e. make a Dispatch class that shares the '_listen' method
- # of the Event class, this is the straight monkeypatch.
- dispatch_base = getattr(cls, 'dispatch', _Dispatch)
- cls.dispatch = dispatch_cls = type("%sDispatch" % classname,
- (dispatch_base, ), {})
- dispatch_cls._listen = cls._listen
- dispatch_cls._clear = cls._clear
-
- for k in dict_:
- if _is_event_name(k):
- setattr(dispatch_cls, k, _DispatchDescriptor(dict_[k]))
- _registrars[k].append(cls)
-
-def _remove_dispatcher(cls):
- for k in dir(cls):
- if _is_event_name(k):
- _registrars[k].remove(cls)
- if not _registrars[k]:
- del _registrars[k]
-
-class Events(object):
- """Define event listening functions for a particular target type."""
-
-
- __metaclass__ = _EventMeta
-
- @classmethod
- def _accept_with(cls, target):
- # Mapper, ClassManager, Session override this to
- # also accept classes, scoped_sessions, sessionmakers, etc.
- if hasattr(target, 'dispatch') and (
- isinstance(target.dispatch, cls.dispatch) or \
- isinstance(target.dispatch, type) and \
- issubclass(target.dispatch, cls.dispatch)
- ):
- return target
- else:
- return None
-
- @classmethod
- def _listen(cls, target, identifier, fn, propagate=False, insert=False):
- if insert:
- getattr(target.dispatch, identifier).insert(fn, target, propagate)
- else:
- getattr(target.dispatch, identifier).append(fn, target, propagate)
-
- @classmethod
- def _remove(cls, target, identifier, fn):
- getattr(target.dispatch, identifier).remove(fn, target)
-
- @classmethod
- def _clear(cls):
- for attr in dir(cls.dispatch):
- if _is_event_name(attr):
- getattr(cls.dispatch, attr).clear()
-
-class _DispatchDescriptor(object):
- """Class-level attributes on :class:`._Dispatch` classes."""
-
- def __init__(self, fn):
- self.__name__ = fn.__name__
- self.__doc__ = fn.__doc__
- self._clslevel = util.defaultdict(list)
-
- def insert(self, obj, target, propagate):
- assert isinstance(target, type), \
- "Class-level Event targets must be classes."
-
- stack = [target]
- while stack:
- cls = stack.pop(0)
- stack.extend(cls.__subclasses__())
- self._clslevel[cls].insert(0, obj)
-
- def append(self, obj, target, propagate):
- assert isinstance(target, type), \
- "Class-level Event targets must be classes."
-
- stack = [target]
- while stack:
- cls = stack.pop(0)
- stack.extend(cls.__subclasses__())
- self._clslevel[cls].append(obj)
-
- def remove(self, obj, target):
- stack = [target]
- while stack:
- cls = stack.pop(0)
- stack.extend(cls.__subclasses__())
- self._clslevel[cls].remove(obj)
-
- def clear(self):
- """Clear all class level listeners"""
-
- for dispatcher in self._clslevel.values():
- dispatcher[:] = []
-
- def __get__(self, obj, cls):
- if obj is None:
- return self
- obj.__dict__[self.__name__] = result = \
- _ListenerCollection(self, obj._parent_cls)
- return result
-
-class _ListenerCollection(object):
- """Instance-level attributes on instances of :class:`._Dispatch`.
-
- Represents a collection of listeners.
-
- """
-
- _exec_once = False
-
- def __init__(self, parent, target_cls):
- self.parent_listeners = parent._clslevel[target_cls]
- self.name = parent.__name__
- self.listeners = []
- self.propagate = set()
-
- def exec_once(self, *args, **kw):
- """Execute this event, but only if it has not been
- executed already for this collection."""
-
- if not self._exec_once:
- self(*args, **kw)
- self._exec_once = True
-
- def __call__(self, *args, **kw):
- """Execute this event."""
-
- for fn in self.parent_listeners:
- fn(*args, **kw)
- for fn in self.listeners:
- fn(*args, **kw)
-
- # I'm not entirely thrilled about the overhead here,
- # but this allows class-level listeners to be added
- # at any point.
- #
- # alternatively, _DispatchDescriptor could notify
- # all _ListenerCollection objects, but then we move
- # to a higher memory model, i.e.weakrefs to all _ListenerCollection
- # objects, the _DispatchDescriptor collection repeated
- # for all instances.
-
- def __len__(self):
- return len(self.parent_listeners + self.listeners)
-
- def __iter__(self):
- return iter(self.parent_listeners + self.listeners)
-
- def __getitem__(self, index):
- return (self.parent_listeners + self.listeners)[index]
-
- def __nonzero__(self):
- return bool(self.listeners or self.parent_listeners)
-
- def _update(self, other, only_propagate=True):
- """Populate from the listeners in another :class:`_Dispatch`
- object."""
-
- existing_listeners = self.listeners
- existing_listener_set = set(existing_listeners)
- self.propagate.update(other.propagate)
- existing_listeners.extend([l for l
- in other.listeners
- if l not in existing_listener_set
- and not only_propagate or l in self.propagate
- ])
-
- def insert(self, obj, target, propagate):
- if obj not in self.listeners:
- self.listeners.insert(0, obj)
- if propagate:
- self.propagate.add(obj)
-
- def append(self, obj, target, propagate):
- if obj not in self.listeners:
- self.listeners.append(obj)
- if propagate:
- self.propagate.add(obj)
-
- def remove(self, obj, target):
- if obj in self.listeners:
- self.listeners.remove(obj)
- self.propagate.discard(obj)
-
- def clear(self):
- self.listeners[:] = []
- self.propagate.clear()
-
-class dispatcher(object):
- """Descriptor used by target classes to
- deliver the _Dispatch class at the class level
- and produce new _Dispatch instances for target
- instances.
-
- """
- def __init__(self, events):
- self.dispatch_cls = events.dispatch
- self.events = events
-
- def __get__(self, obj, cls):
- if obj is None:
- return self.dispatch_cls
- obj.__dict__['dispatch'] = disp = self.dispatch_cls(cls)
- return disp
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/events.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/events.py
deleted file mode 100755
index 50637705..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/events.py
+++ /dev/null
@@ -1,429 +0,0 @@
-# sqlalchemy/events.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Core event interfaces."""
-
-from sqlalchemy import event, exc
-
-class DDLEvents(event.Events):
- """
- Define event listeners for schema objects,
- that is, :class:`.SchemaItem` and :class:`.SchemaEvent`
- subclasses, including :class:`.MetaData`, :class:`.Table`,
- :class:`.Column`.
-
- :class:`.MetaData` and :class:`.Table` support events
- specifically regarding when CREATE and DROP
- DDL is emitted to the database.
-
- Attachment events are also provided to customize
- behavior whenever a child schema element is associated
- with a parent, such as, when a :class:`.Column` is associated
- with its :class:`.Table`, when a :class:`.ForeignKeyConstraint`
- is associated with a :class:`.Table`, etc.
-
- Example using the ``after_create`` event::
-
- from sqlalchemy import event
- from sqlalchemy import Table, Column, Metadata, Integer
-
- m = MetaData()
- some_table = Table('some_table', m, Column('data', Integer))
-
- def after_create(target, connection, **kw):
- connection.execute("ALTER TABLE %s SET name=foo_%s" %
- (target.name, target.name))
-
- event.listen(some_table, "after_create", after_create)
-
- DDL events integrate closely with the
- :class:`.DDL` class and the :class:`.DDLElement` hierarchy
- of DDL clause constructs, which are themselves appropriate
- as listener callables::
-
- from sqlalchemy import DDL
- event.listen(
- some_table,
- "after_create",
- DDL("ALTER TABLE %(table)s SET name=foo_%(table)s")
- )
-
- The methods here define the name of an event as well
- as the names of members that are passed to listener
- functions.
-
- See also:
-
- :ref:`event_toplevel`
-
- :class:`.DDLElement`
-
- :class:`.DDL`
-
- :ref:`schema_ddl_sequences`
-
- """
-
- def before_create(self, target, connection, **kw):
- """Called before CREATE statments are emitted.
-
- :param target: the :class:`.MetaData` or :class:`.Table`
- object which is the target of the event.
- :param connection: the :class:`.Connection` where the
- CREATE statement or statements will be emitted.
- :param \**kw: additional keyword arguments relevant
- to the event. Currently this includes the ``tables``
- argument in the case of a :class:`.MetaData` object,
- which is the list of :class:`.Table` objects for which
- CREATE will be emitted.
-
- """
-
- def after_create(self, target, connection, **kw):
- """Called after CREATE statments are emitted.
-
- :param target: the :class:`.MetaData` or :class:`.Table`
- object which is the target of the event.
- :param connection: the :class:`.Connection` where the
- CREATE statement or statements have been emitted.
- :param \**kw: additional keyword arguments relevant
- to the event. Currently this includes the ``tables``
- argument in the case of a :class:`.MetaData` object,
- which is the list of :class:`.Table` objects for which
- CREATE has been emitted.
-
- """
-
- def before_drop(self, target, connection, **kw):
- """Called before DROP statments are emitted.
-
- :param target: the :class:`.MetaData` or :class:`.Table`
- object which is the target of the event.
- :param connection: the :class:`.Connection` where the
- DROP statement or statements will be emitted.
- :param \**kw: additional keyword arguments relevant
- to the event. Currently this includes the ``tables``
- argument in the case of a :class:`.MetaData` object,
- which is the list of :class:`.Table` objects for which
- DROP will be emitted.
-
- """
-
- def after_drop(self, target, connection, **kw):
- """Called after DROP statments are emitted.
-
- :param target: the :class:`.MetaData` or :class:`.Table`
- object which is the target of the event.
- :param connection: the :class:`.Connection` where the
- DROP statement or statements have been emitted.
- :param \**kw: additional keyword arguments relevant
- to the event. Currently this includes the ``tables``
- argument in the case of a :class:`.MetaData` object,
- which is the list of :class:`.Table` objects for which
- DROP has been emitted.
-
- """
-
- def before_parent_attach(self, target, parent):
- """Called before a :class:`.SchemaItem` is associated with
- a parent :class:`.SchemaItem`.
-
- :param target: the target object
- :param parent: the parent to which the target is being attached.
-
- :func:`.event.listen` also accepts a modifier for this event:
-
- :param propagate=False: When True, the listener function will
- be established for any copies made of the target object,
- i.e. those copies that are generated when
- :meth:`.Table.tometadata` is used.
-
- """
-
- def after_parent_attach(self, target, parent):
- """Called after a :class:`.SchemaItem` is associated with
- a parent :class:`.SchemaItem`.
-
- :param target: the target object
- :param parent: the parent to which the target is being attached.
-
- :func:`.event.listen` also accepts a modifier for this event:
-
- :param propagate=False: When True, the listener function will
- be established for any copies made of the target object,
- i.e. those copies that are generated when
- :meth:`.Table.tometadata` is used.
-
- """
-
- def column_reflect(self, table, column_info):
- """Called for each unit of 'column info' retrieved when
- a :class:`.Table` is being reflected.
-
- The dictionary of column information as returned by the
- dialect is passed, and can be modified. The dictionary
- is that returned in each element of the list returned
- by :meth:`.reflection.Inspector.get_columns`.
-
- The event is called before any action is taken against
- this dictionary, and the contents can be modified.
- The :class:`.Column` specific arguments ``info``, ``key``,
- and ``quote`` can also be added to the dictionary and
- will be passed to the constructor of :class:`.Column`.
-
- Note that this event is only meaningful if either
- associated with the :class:`.Table` class across the
- board, e.g.::
-
- from sqlalchemy.schema import Table
- from sqlalchemy import event
-
- def listen_for_reflect(table, column_info):
- "receive a column_reflect event"
- # ...
-
- event.listen(
- Table,
- 'column_reflect',
- listen_for_reflect)
-
- ...or with a specific :class:`.Table` instance using
- the ``listeners`` argument::
-
- def listen_for_reflect(table, column_info):
- "receive a column_reflect event"
- # ...
-
- t = Table(
- 'sometable',
- autoload=True,
- listeners=[
- ('column_reflect', listen_for_reflect)
- ])
-
- This because the reflection process initiated by ``autoload=True``
- completes within the scope of the constructor for :class:`.Table`.
-
- """
-
-class SchemaEventTarget(object):
- """Base class for elements that are the targets of :class:`.DDLEvents` events.
-
- This includes :class:`.SchemaItem` as well as :class:`.SchemaType`.
-
- """
- dispatch = event.dispatcher(DDLEvents)
-
- def _set_parent(self, parent):
- """Associate with this SchemaEvent's parent object."""
-
- raise NotImplementedError()
-
- def _set_parent_with_dispatch(self, parent):
- self.dispatch.before_parent_attach(self, parent)
- self._set_parent(parent)
- self.dispatch.after_parent_attach(self, parent)
-
-class PoolEvents(event.Events):
- """Available events for :class:`.Pool`.
-
- The methods here define the name of an event as well
- as the names of members that are passed to listener
- functions.
-
- e.g.::
-
- from sqlalchemy import event
-
- def my_on_checkout(dbapi_conn, connection_rec, connection_proxy):
- "handle an on checkout event"
-
- events.listen(Pool, 'checkout', my_on_checkout)
-
- In addition to accepting the :class:`.Pool` class and :class:`.Pool` instances,
- :class:`.PoolEvents` also accepts :class:`.Engine` objects and
- the :class:`.Engine` class as targets, which will be resolved
- to the ``.pool`` attribute of the given engine or the :class:`.Pool`
- class::
-
- engine = create_engine("postgresql://scott:tiger@localhost/test")
-
- # will associate with engine.pool
- events.listen(engine, 'checkout', my_on_checkout)
-
- """
-
- @classmethod
- def _accept_with(cls, target):
- from sqlalchemy.engine import Engine
- from sqlalchemy.pool import Pool
-
- if isinstance(target, type):
- if issubclass(target, Engine):
- return Pool
- elif issubclass(target, Pool):
- return target
- elif isinstance(target, Engine):
- return target.pool
- else:
- return target
-
- def connect(self, dbapi_connection, connection_record):
- """Called once for each new DB-API connection or Pool's ``creator()``.
-
- :param dbapi_con:
- A newly connected raw DB-API connection (not a SQLAlchemy
- ``Connection`` wrapper).
-
- :param con_record:
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
- def first_connect(self, dbapi_connection, connection_record):
- """Called exactly once for the first DB-API connection.
-
- :param dbapi_con:
- A newly connected raw DB-API connection (not a SQLAlchemy
- ``Connection`` wrapper).
-
- :param con_record:
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
- def checkout(self, dbapi_connection, connection_record, connection_proxy):
- """Called when a connection is retrieved from the Pool.
-
- :param dbapi_con:
- A raw DB-API connection
-
- :param con_record:
- The ``_ConnectionRecord`` that persistently manages the connection
-
- :param con_proxy:
- The ``_ConnectionFairy`` which manages the connection for the span of
- the current checkout.
-
- If you raise an ``exc.DisconnectionError``, the current
- connection will be disposed and a fresh connection retrieved.
- Processing of all checkout listeners will abort and restart
- using the new connection.
- """
-
- def checkin(self, dbapi_connection, connection_record):
- """Called when a connection returns to the pool.
-
- Note that the connection may be closed, and may be None if the
- connection has been invalidated. ``checkin`` will not be called
- for detached connections. (They do not return to the pool.)
-
- :param dbapi_con:
- A raw DB-API connection
-
- :param con_record:
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
-class ConnectionEvents(event.Events):
- """Available events for :class:`.Connection`.
-
- The methods here define the name of an event as well as the names of members that are passed to listener functions.
-
- e.g.::
-
- from sqlalchemy import event, create_engine
-
- def before_execute(conn, clauseelement, multiparams, params):
- log.info("Received statement: %s" % clauseelement)
-
- engine = create_engine('postgresql://scott:tiger@localhost/test')
- event.listen(engine, "before_execute", before_execute)
-
- Some events allow modifiers to the listen() function.
-
- :param retval=False: Applies to the :meth:`.before_execute` and
- :meth:`.before_cursor_execute` events only. When True, the
- user-defined event function must have a return value, which
- is a tuple of parameters that replace the given statement
- and parameters. See those methods for a description of
- specific return arguments.
-
- """
-
- @classmethod
- def _listen(cls, target, identifier, fn, retval=False):
- target._has_events = True
-
- if not retval:
- if identifier == 'before_execute':
- orig_fn = fn
- def wrap(conn, clauseelement, multiparams, params):
- orig_fn(conn, clauseelement, multiparams, params)
- return clauseelement, multiparams, params
- fn = wrap
- elif identifier == 'before_cursor_execute':
- orig_fn = fn
- def wrap(conn, cursor, statement,
- parameters, context, executemany):
- orig_fn(conn, cursor, statement,
- parameters, context, executemany)
- return statement, parameters
- fn = wrap
-
- elif retval and identifier not in ('before_execute', 'before_cursor_execute'):
- raise exc.ArgumentError(
- "Only the 'before_execute' and "
- "'before_cursor_execute' engine "
- "event listeners accept the 'retval=True' "
- "argument.")
- event.Events._listen(target, identifier, fn)
-
- def before_execute(self, conn, clauseelement, multiparams, params):
- """Intercept high level execute() events."""
-
- def after_execute(self, conn, clauseelement, multiparams, params, result):
- """Intercept high level execute() events."""
-
- def before_cursor_execute(self, conn, cursor, statement,
- parameters, context, executemany):
- """Intercept low-level cursor execute() events."""
-
- def after_cursor_execute(self, conn, cursor, statement,
- parameters, context, executemany):
- """Intercept low-level cursor execute() events."""
-
- def begin(self, conn):
- """Intercept begin() events."""
-
- def rollback(self, conn):
- """Intercept rollback() events."""
-
- def commit(self, conn):
- """Intercept commit() events."""
-
- def savepoint(self, conn, name=None):
- """Intercept savepoint() events."""
-
- def rollback_savepoint(self, conn, name, context):
- """Intercept rollback_savepoint() events."""
-
- def release_savepoint(self, conn, name, context):
- """Intercept release_savepoint() events."""
-
- def begin_twophase(self, conn, xid):
- """Intercept begin_twophase() events."""
-
- def prepare_twophase(self, conn, xid):
- """Intercept prepare_twophase() events."""
-
- def rollback_twophase(self, conn, xid, is_prepared):
- """Intercept rollback_twophase() events."""
-
- def commit_twophase(self, conn, xid, is_prepared):
- """Intercept commit_twophase() events."""
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/exc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/exc.py
deleted file mode 100755
index 3e88ee3a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/exc.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# sqlalchemy/exc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Exceptions used with SQLAlchemy.
-
-The base exception class is :class:`.SQLAlchemyError`. Exceptions which are raised as a
-result of DBAPI exceptions are all subclasses of
-:class:`.DBAPIError`.
-
-"""
-
-
-class SQLAlchemyError(Exception):
- """Generic error class."""
-
-
-class ArgumentError(SQLAlchemyError):
- """Raised when an invalid or conflicting function argument is supplied.
-
- This error generally corresponds to construction time state errors.
-
- """
-
-
-class CircularDependencyError(SQLAlchemyError):
- """Raised by topological sorts when a circular dependency is detected"""
- def __init__(self, message, cycles, edges):
- message += ": cycles: %r all edges: %r" % (cycles, edges)
- SQLAlchemyError.__init__(self, message)
- self.cycles = cycles
- self.edges = edges
-
-class CompileError(SQLAlchemyError):
- """Raised when an error occurs during SQL compilation"""
-
-class IdentifierError(SQLAlchemyError):
- """Raised when a schema name is beyond the max character limit"""
-
-# Moved to orm.exc; compatibility definition installed by orm import until 0.6
-ConcurrentModificationError = None
-
-class DisconnectionError(SQLAlchemyError):
- """A disconnect is detected on a raw DB-API connection.
-
- This error is raised and consumed internally by a connection pool. It can
- be raised by a ``PoolListener`` so that the host pool forces a disconnect.
-
- """
-
-
-# Moved to orm.exc; compatibility definition installed by orm import until 0.6
-FlushError = None
-
-class TimeoutError(SQLAlchemyError):
- """Raised when a connection pool times out on getting a connection."""
-
-
-class InvalidRequestError(SQLAlchemyError):
- """SQLAlchemy was asked to do something it can't do.
-
- This error generally corresponds to runtime state errors.
-
- """
-
-class ResourceClosedError(InvalidRequestError):
- """An operation was requested from a connection, cursor, or other
- object that's in a closed state."""
-
-class NoSuchColumnError(KeyError, InvalidRequestError):
- """A nonexistent column is requested from a ``RowProxy``."""
-
-class NoReferenceError(InvalidRequestError):
- """Raised by ``ForeignKey`` to indicate a reference cannot be resolved."""
-
-class NoReferencedTableError(NoReferenceError):
- """Raised by ``ForeignKey`` when the referred ``Table`` cannot be located."""
-
- def __init__(self, message, tname):
- NoReferenceError.__init__(self, message)
- self.table_name = tname
-
-class NoReferencedColumnError(NoReferenceError):
- """Raised by ``ForeignKey`` when the referred ``Column`` cannot be located."""
-
- def __init__(self, message, tname, cname):
- NoReferenceError.__init__(self, message)
- self.table_name = tname
- self.column_name = cname
-
-class NoSuchTableError(InvalidRequestError):
- """Table does not exist or is not visible to a connection."""
-
-
-class UnboundExecutionError(InvalidRequestError):
- """SQL was attempted without a database connection to execute it on."""
-
-
-# Moved to orm.exc; compatibility definition installed by orm import until 0.6
-UnmappedColumnError = None
-
-class StatementError(SQLAlchemyError):
- """An error occurred during execution of a SQL statement.
-
- :class:`.StatementError` wraps the exception raised
- during execution, and features :attr:`.statement`
- and :attr:`.params` attributes which supply context regarding
- the specifics of the statement which had an issue.
-
- The wrapped exception object is available in
- the :attr:`.orig` attribute.
-
- """
-
- def __init__(self, message, statement, params, orig):
- SQLAlchemyError.__init__(self, message)
- self.statement = statement
- self.params = params
- self.orig = orig
-
- def __str__(self):
- if isinstance(self.params, (list, tuple)) and \
- len(self.params) > 10 and \
- isinstance(self.params[0], (list, dict, tuple)):
- return ' '.join((SQLAlchemyError.__str__(self),
- repr(self.statement),
- repr(self.params[:2]),
- '... and a total of %i bound parameter sets' % len(self.params)))
- return ' '.join((SQLAlchemyError.__str__(self),
- repr(self.statement), repr(self.params)))
-
-class DBAPIError(StatementError):
- """Raised when the execution of a database operation fails.
-
- ``DBAPIError`` wraps exceptions raised by the DB-API underlying the
- database operation. Driver-specific implementations of the standard
- DB-API exception types are wrapped by matching sub-types of SQLAlchemy's
- ``DBAPIError`` when possible. DB-API's ``Error`` type maps to
- ``DBAPIError`` in SQLAlchemy, otherwise the names are identical. Note
- that there is no guarantee that different DB-API implementations will
- raise the same exception type for any given error condition.
-
- :class:`.DBAPIError` features :attr:`.statement`
- and :attr:`.params` attributes which supply context regarding
- the specifics of the statement which had an issue, for the
- typical case when the error was raised within the context of
- emitting a SQL statement.
-
- The wrapped exception object is available in the :attr:`.orig` attribute.
- Its type and properties are DB-API implementation specific.
-
- """
-
- @classmethod
- def instance(cls, statement, params,
- orig,
- dbapi_base_err,
- connection_invalidated=False):
- # Don't ever wrap these, just return them directly as if
- # DBAPIError didn't exist.
- if isinstance(orig, (KeyboardInterrupt, SystemExit)):
- return orig
-
- if orig is not None:
- # not a DBAPI error, statement is present.
- # raise a StatementError
- if not isinstance(orig, dbapi_base_err) and statement:
- return StatementError(str(orig), statement, params, orig)
-
- name, glob = orig.__class__.__name__, globals()
- if name in glob and issubclass(glob[name], DBAPIError):
- cls = glob[name]
-
- return cls(statement, params, orig, connection_invalidated)
-
- def __init__(self, statement, params, orig, connection_invalidated=False):
- try:
- text = str(orig)
- except (KeyboardInterrupt, SystemExit):
- raise
- except Exception, e:
- text = 'Error in str() of DB-API-generated exception: ' + str(e)
- StatementError.__init__(
- self,
- '(%s) %s' % (orig.__class__.__name__, text),
- statement,
- params,
- orig
- )
- self.connection_invalidated = connection_invalidated
-
-
-class InterfaceError(DBAPIError):
- """Wraps a DB-API InterfaceError."""
-
-
-class DatabaseError(DBAPIError):
- """Wraps a DB-API DatabaseError."""
-
-
-class DataError(DatabaseError):
- """Wraps a DB-API DataError."""
-
-
-class OperationalError(DatabaseError):
- """Wraps a DB-API OperationalError."""
-
-
-class IntegrityError(DatabaseError):
- """Wraps a DB-API IntegrityError."""
-
-
-class InternalError(DatabaseError):
- """Wraps a DB-API InternalError."""
-
-
-class ProgrammingError(DatabaseError):
- """Wraps a DB-API ProgrammingError."""
-
-
-class NotSupportedError(DatabaseError):
- """Wraps a DB-API NotSupportedError."""
-
-
-# Warnings
-
-class SADeprecationWarning(DeprecationWarning):
- """Issued once per usage of a deprecated API."""
-
-
-class SAPendingDeprecationWarning(PendingDeprecationWarning):
- """Issued once per usage of a deprecated API."""
-
-
-class SAWarning(RuntimeWarning):
- """Issued at runtime."""
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/__init__.py
deleted file mode 100755
index a66421b2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# ext/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/associationproxy.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/associationproxy.py
deleted file mode 100755
index 31bfa90f..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/associationproxy.py
+++ /dev/null
@@ -1,912 +0,0 @@
-# ext/associationproxy.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Contain the ``AssociationProxy`` class.
-
-The ``AssociationProxy`` is a Python property object which provides
-transparent proxied access to the endpoint of an association object.
-
-See the example ``examples/association/proxied_association.py``.
-
-"""
-import itertools
-import operator
-import weakref
-from sqlalchemy import exceptions
-from sqlalchemy import orm
-from sqlalchemy import util
-from sqlalchemy.orm import collections
-from sqlalchemy.sql import not_
-
-
-def association_proxy(target_collection, attr, **kw):
- """Return a Python property implementing a view of a target
- attribute which references an attribute on members of the
- target.
-
- Implements a read/write view over an instance's *target_collection*,
- extracting *attr* from each member of the collection. The property acts
- somewhat like this list comprehension::
-
- [getattr(member, *attr*)
- for member in getattr(instance, *target_collection*)]
-
- Unlike the list comprehension, the collection returned by the property is
- always in sync with *target_collection*, and mutations made to either
- collection will be reflected in both.
-
- The association proxy also works with scalar attributes, which in
- turn reference scalar attributes or collections.
-
- Implements a Python property representing a relationship as a collection of
- simpler values, or a scalar value. The proxied property will mimic the collection type of
- the target (list, dict or set), or, in the case of a one to one relationship,
- a simple scalar value.
-
- :param target_collection: Name of the relationship attribute we'll proxy to,
- usually created with :func:`~sqlalchemy.orm.relationship`.
-
- :param attr: Attribute on the associated instance or instances we'll proxy for.
-
- For example, given a target collection of [obj1, obj2], a list created
- by this proxy property would look like [getattr(obj1, *attr*),
- getattr(obj2, *attr*)]
-
- If the relationship is one-to-one or otherwise uselist=False, then simply:
- getattr(obj, *attr*)
-
- :param creator: optional.
-
- When new items are added to this proxied collection, new instances of
- the class collected by the target collection will be created. For list
- and set collections, the target class constructor will be called with
- the 'value' for the new instance. For dict types, two arguments are
- passed: key and value.
-
- If you want to construct instances differently, supply a *creator*
- function that takes arguments as above and returns instances.
-
- For scalar relationships, creator() will be called if the target is None.
- If the target is present, set operations are proxied to setattr() on the
- associated object.
-
- If you have an associated object with multiple attributes, you may set
- up multiple association proxies mapping to different attributes. See
- the unit tests for examples, and for examples of how creator() functions
- can be used to construct the scalar relationship on-demand in this
- situation.
-
- :param \*\*kw: Passes along any other keyword arguments to
- :class:`.AssociationProxy`.
-
- """
- return AssociationProxy(target_collection, attr, **kw)
-
-
-class AssociationProxy(object):
- """A descriptor that presents a read/write view of an object attribute."""
-
- def __init__(self, target_collection, attr, creator=None,
- getset_factory=None, proxy_factory=None,
- proxy_bulk_set=None):
- """Arguments are:
-
- target_collection
- Name of the collection we'll proxy to, usually created with
- 'relationship()' in a mapper setup.
-
- attr
- Attribute on the collected instances we'll proxy for. For example,
- given a target collection of [obj1, obj2], a list created by this
- proxy property would look like [getattr(obj1, attr), getattr(obj2,
- attr)]
-
- creator
- Optional. When new items are added to this proxied collection, new
- instances of the class collected by the target collection will be
- created. For list and set collections, the target class constructor
- will be called with the 'value' for the new instance. For dict
- types, two arguments are passed: key and value.
-
- If you want to construct instances differently, supply a 'creator'
- function that takes arguments as above and returns instances.
-
- getset_factory
- Optional. Proxied attribute access is automatically handled by
- routines that get and set values based on the `attr` argument for
- this proxy.
-
- If you would like to customize this behavior, you may supply a
- `getset_factory` callable that produces a tuple of `getter` and
- `setter` functions. The factory is called with two arguments, the
- abstract type of the underlying collection and this proxy instance.
-
- proxy_factory
- Optional. The type of collection to emulate is determined by
- sniffing the target collection. If your collection type can't be
- determined by duck typing or you'd like to use a different
- collection implementation, you may supply a factory function to
- produce those collections. Only applicable to non-scalar relationships.
-
- proxy_bulk_set
- Optional, use with proxy_factory. See the _set() method for
- details.
-
- """
- self.target_collection = target_collection
- self.value_attr = attr
- self.creator = creator
- self.getset_factory = getset_factory
- self.proxy_factory = proxy_factory
- self.proxy_bulk_set = proxy_bulk_set
-
- self.owning_class = None
- self.key = '_%s_%s_%s' % (
- type(self).__name__, target_collection, id(self))
- self.collection_class = None
-
- def _get_property(self):
- return (orm.class_mapper(self.owning_class).
- get_property(self.target_collection))
-
- @util.memoized_property
- def target_class(self):
- """The class the proxy is attached to."""
- return self._get_property().mapper.class_
-
- @util.memoized_property
- def scalar(self):
- scalar = not self._get_property().uselist
- if scalar:
- self._initialize_scalar_accessors()
- return scalar
-
- @util.memoized_property
- def _value_is_scalar(self):
- return not self._get_property().\
- mapper.get_property(self.value_attr).uselist
-
- def __get__(self, obj, class_):
- if self.owning_class is None:
- self.owning_class = class_ and class_ or type(obj)
- if obj is None:
- return self
-
- if self.scalar:
- return self._scalar_get(getattr(obj, self.target_collection))
- else:
- try:
- # If the owning instance is reborn (orm session resurrect,
- # etc.), refresh the proxy cache.
- creator_id, proxy = getattr(obj, self.key)
- if id(obj) == creator_id:
- return proxy
- except AttributeError:
- pass
- proxy = self._new(_lazy_collection(obj, self.target_collection))
- setattr(obj, self.key, (id(obj), proxy))
- return proxy
-
- def __set__(self, obj, values):
- if self.owning_class is None:
- self.owning_class = type(obj)
-
- if self.scalar:
- creator = self.creator and self.creator or self.target_class
- target = getattr(obj, self.target_collection)
- if target is None:
- setattr(obj, self.target_collection, creator(values))
- else:
- self._scalar_set(target, values)
- else:
- proxy = self.__get__(obj, None)
- if proxy is not values:
- proxy.clear()
- self._set(proxy, values)
-
- def __delete__(self, obj):
- if self.owning_class is None:
- self.owning_class = type(obj)
- delattr(obj, self.key)
-
- def _initialize_scalar_accessors(self):
- if self.getset_factory:
- get, set = self.getset_factory(None, self)
- else:
- get, set = self._default_getset(None)
- self._scalar_get, self._scalar_set = get, set
-
- def _default_getset(self, collection_class):
- attr = self.value_attr
- getter = operator.attrgetter(attr)
- if collection_class is dict:
- setter = lambda o, k, v: setattr(o, attr, v)
- else:
- setter = lambda o, v: setattr(o, attr, v)
- return getter, setter
-
- def _new(self, lazy_collection):
- creator = self.creator and self.creator or self.target_class
- self.collection_class = util.duck_type_collection(lazy_collection())
-
- if self.proxy_factory:
- return self.proxy_factory(lazy_collection, creator, self.value_attr, self)
-
- if self.getset_factory:
- getter, setter = self.getset_factory(self.collection_class, self)
- else:
- getter, setter = self._default_getset(self.collection_class)
-
- if self.collection_class is list:
- return _AssociationList(lazy_collection, creator, getter, setter, self)
- elif self.collection_class is dict:
- return _AssociationDict(lazy_collection, creator, getter, setter, self)
- elif self.collection_class is set:
- return _AssociationSet(lazy_collection, creator, getter, setter, self)
- else:
- raise exceptions.ArgumentError(
- 'could not guess which interface to use for '
- 'collection_class "%s" backing "%s"; specify a '
- 'proxy_factory and proxy_bulk_set manually' %
- (self.collection_class.__name__, self.target_collection))
-
- def _inflate(self, proxy):
- creator = self.creator and self.creator or self.target_class
-
- if self.getset_factory:
- getter, setter = self.getset_factory(self.collection_class, self)
- else:
- getter, setter = self._default_getset(self.collection_class)
-
- proxy.creator = creator
- proxy.getter = getter
- proxy.setter = setter
-
- def _set(self, proxy, values):
- if self.proxy_bulk_set:
- self.proxy_bulk_set(proxy, values)
- elif self.collection_class is list:
- proxy.extend(values)
- elif self.collection_class is dict:
- proxy.update(values)
- elif self.collection_class is set:
- proxy.update(values)
- else:
- raise exceptions.ArgumentError(
- 'no proxy_bulk_set supplied for custom '
- 'collection_class implementation')
-
- @property
- def _comparator(self):
- return self._get_property().comparator
-
- def any(self, criterion=None, **kwargs):
- if self._value_is_scalar:
- value_expr = getattr(self.target_class, self.value_attr).has(criterion, **kwargs)
- else:
- value_expr = getattr(self.target_class, self.value_attr).any(criterion, **kwargs)
-
- # check _value_is_scalar here, otherwise
- # we're scalar->scalar - call .any() so that
- # the "can't call any() on a scalar" msg is raised.
- if self.scalar and not self._value_is_scalar:
- return self._comparator.has(
- value_expr
- )
- else:
- return self._comparator.any(
- value_expr
- )
-
- def has(self, criterion=None, **kwargs):
- return self._comparator.has(
- getattr(self.target_class, self.value_attr).has(criterion, **kwargs)
- )
-
- def contains(self, obj):
- if self.scalar and not self._value_is_scalar:
- return self._comparator.has(
- getattr(self.target_class, self.value_attr).contains(obj)
- )
- else:
- return self._comparator.any(**{self.value_attr: obj})
-
- def __eq__(self, obj):
- return self._comparator.has(**{self.value_attr: obj})
-
- def __ne__(self, obj):
- return not_(self.__eq__(obj))
-
-
-class _lazy_collection(object):
- def __init__(self, obj, target):
- self.ref = weakref.ref(obj)
- self.target = target
-
- def __call__(self):
- obj = self.ref()
- if obj is None:
- raise exceptions.InvalidRequestError(
- "stale association proxy, parent object has gone out of "
- "scope")
- return getattr(obj, self.target)
-
- def __getstate__(self):
- return {'obj':self.ref(), 'target':self.target}
-
- def __setstate__(self, state):
- self.ref = weakref.ref(state['obj'])
- self.target = state['target']
-
-class _AssociationCollection(object):
- def __init__(self, lazy_collection, creator, getter, setter, parent):
- """Constructs an _AssociationCollection.
-
- This will always be a subclass of either _AssociationList,
- _AssociationSet, or _AssociationDict.
-
- lazy_collection
- A callable returning a list-based collection of entities (usually an
- object attribute managed by a SQLAlchemy relationship())
-
- creator
- A function that creates new target entities. Given one parameter:
- value. This assertion is assumed::
-
- obj = creator(somevalue)
- assert getter(obj) == somevalue
-
- getter
- A function. Given an associated object, return the 'value'.
-
- setter
- A function. Given an associated object and a value, store that
- value on the object.
-
- """
- self.lazy_collection = lazy_collection
- self.creator = creator
- self.getter = getter
- self.setter = setter
- self.parent = parent
-
- col = property(lambda self: self.lazy_collection())
-
- def __len__(self):
- return len(self.col)
-
- def __nonzero__(self):
- return bool(self.col)
-
- def __getstate__(self):
- return {'parent':self.parent, 'lazy_collection':self.lazy_collection}
-
- def __setstate__(self, state):
- self.parent = state['parent']
- self.lazy_collection = state['lazy_collection']
- self.parent._inflate(self)
-
-class _AssociationList(_AssociationCollection):
- """Generic, converting, list-to-list proxy."""
-
- def _create(self, value):
- return self.creator(value)
-
- def _get(self, object):
- return self.getter(object)
-
- def _set(self, object, value):
- return self.setter(object, value)
-
- def __getitem__(self, index):
- return self._get(self.col[index])
-
- def __setitem__(self, index, value):
- if not isinstance(index, slice):
- self._set(self.col[index], value)
- else:
- if index.stop is None:
- stop = len(self)
- elif index.stop < 0:
- stop = len(self) + index.stop
- else:
- stop = index.stop
- step = index.step or 1
-
- rng = range(index.start or 0, stop, step)
- if step == 1:
- for i in rng:
- del self[index.start]
- i = index.start
- for item in value:
- self.insert(i, item)
- i += 1
- else:
- if len(value) != len(rng):
- raise ValueError(
- "attempt to assign sequence of size %s to "
- "extended slice of size %s" % (len(value),
- len(rng)))
- for i, item in zip(rng, value):
- self._set(self.col[i], item)
-
- def __delitem__(self, index):
- del self.col[index]
-
- def __contains__(self, value):
- for member in self.col:
- # testlib.pragma exempt:__eq__
- if self._get(member) == value:
- return True
- return False
-
- def __getslice__(self, start, end):
- return [self._get(member) for member in self.col[start:end]]
-
- def __setslice__(self, start, end, values):
- members = [self._create(v) for v in values]
- self.col[start:end] = members
-
- def __delslice__(self, start, end):
- del self.col[start:end]
-
- def __iter__(self):
- """Iterate over proxied values.
-
- For the actual domain objects, iterate over .col instead or
- just use the underlying collection directly from its property
- on the parent.
- """
-
- for member in self.col:
- yield self._get(member)
- raise StopIteration
-
- def append(self, value):
- item = self._create(value)
- self.col.append(item)
-
- def count(self, value):
- return sum([1 for _ in
- itertools.ifilter(lambda v: v == value, iter(self))])
-
- def extend(self, values):
- for v in values:
- self.append(v)
-
- def insert(self, index, value):
- self.col[index:index] = [self._create(value)]
-
- def pop(self, index=-1):
- return self.getter(self.col.pop(index))
-
- def remove(self, value):
- for i, val in enumerate(self):
- if val == value:
- del self.col[i]
- return
- raise ValueError("value not in list")
-
- def reverse(self):
- """Not supported, use reversed(mylist)"""
-
- raise NotImplementedError
-
- def sort(self):
- """Not supported, use sorted(mylist)"""
-
- raise NotImplementedError
-
- def clear(self):
- del self.col[0:len(self.col)]
-
- def __eq__(self, other):
- return list(self) == other
-
- def __ne__(self, other):
- return list(self) != other
-
- def __lt__(self, other):
- return list(self) < other
-
- def __le__(self, other):
- return list(self) <= other
-
- def __gt__(self, other):
- return list(self) > other
-
- def __ge__(self, other):
- return list(self) >= other
-
- def __cmp__(self, other):
- return cmp(list(self), other)
-
- def __add__(self, iterable):
- try:
- other = list(iterable)
- except TypeError:
- return NotImplemented
- return list(self) + other
-
- def __radd__(self, iterable):
- try:
- other = list(iterable)
- except TypeError:
- return NotImplemented
- return other + list(self)
-
- def __mul__(self, n):
- if not isinstance(n, int):
- return NotImplemented
- return list(self) * n
- __rmul__ = __mul__
-
- def __iadd__(self, iterable):
- self.extend(iterable)
- return self
-
- def __imul__(self, n):
- # unlike a regular list *=, proxied __imul__ will generate unique
- # backing objects for each copy. *= on proxied lists is a bit of
- # a stretch anyhow, and this interpretation of the __imul__ contract
- # is more plausibly useful than copying the backing objects.
- if not isinstance(n, int):
- return NotImplemented
- if n == 0:
- self.clear()
- elif n > 1:
- self.extend(list(self) * (n - 1))
- return self
-
- def copy(self):
- return list(self)
-
- def __repr__(self):
- return repr(list(self))
-
- def __hash__(self):
- raise TypeError("%s objects are unhashable" % type(self).__name__)
-
- for func_name, func in locals().items():
- if (util.callable(func) and func.func_name == func_name and
- not func.__doc__ and hasattr(list, func_name)):
- func.__doc__ = getattr(list, func_name).__doc__
- del func_name, func
-
-
-_NotProvided = util.symbol('_NotProvided')
-class _AssociationDict(_AssociationCollection):
- """Generic, converting, dict-to-dict proxy."""
-
- def _create(self, key, value):
- return self.creator(key, value)
-
- def _get(self, object):
- return self.getter(object)
-
- def _set(self, object, key, value):
- return self.setter(object, key, value)
-
- def __getitem__(self, key):
- return self._get(self.col[key])
-
- def __setitem__(self, key, value):
- if key in self.col:
- self._set(self.col[key], key, value)
- else:
- self.col[key] = self._create(key, value)
-
- def __delitem__(self, key):
- del self.col[key]
-
- def __contains__(self, key):
- # testlib.pragma exempt:__hash__
- return key in self.col
-
- def has_key(self, key):
- # testlib.pragma exempt:__hash__
- return key in self.col
-
- def __iter__(self):
- return self.col.iterkeys()
-
- def clear(self):
- self.col.clear()
-
- def __eq__(self, other):
- return dict(self) == other
-
- def __ne__(self, other):
- return dict(self) != other
-
- def __lt__(self, other):
- return dict(self) < other
-
- def __le__(self, other):
- return dict(self) <= other
-
- def __gt__(self, other):
- return dict(self) > other
-
- def __ge__(self, other):
- return dict(self) >= other
-
- def __cmp__(self, other):
- return cmp(dict(self), other)
-
- def __repr__(self):
- return repr(dict(self.items()))
-
- def get(self, key, default=None):
- try:
- return self[key]
- except KeyError:
- return default
-
- def setdefault(self, key, default=None):
- if key not in self.col:
- self.col[key] = self._create(key, default)
- return default
- else:
- return self[key]
-
- def keys(self):
- return self.col.keys()
-
- def iterkeys(self):
- return self.col.iterkeys()
-
- def values(self):
- return [ self._get(member) for member in self.col.values() ]
-
- def itervalues(self):
- for key in self.col:
- yield self._get(self.col[key])
- raise StopIteration
-
- def items(self):
- return [(k, self._get(self.col[k])) for k in self]
-
- def iteritems(self):
- for key in self.col:
- yield (key, self._get(self.col[key]))
- raise StopIteration
-
- def pop(self, key, default=_NotProvided):
- if default is _NotProvided:
- member = self.col.pop(key)
- else:
- member = self.col.pop(key, default)
- return self._get(member)
-
- def popitem(self):
- item = self.col.popitem()
- return (item[0], self._get(item[1]))
-
- def update(self, *a, **kw):
- if len(a) > 1:
- raise TypeError('update expected at most 1 arguments, got %i' %
- len(a))
- elif len(a) == 1:
- seq_or_map = a[0]
- for item in seq_or_map:
- if isinstance(item, tuple):
- self[item[0]] = item[1]
- else:
- self[item] = seq_or_map[item]
-
- for key, value in kw:
- self[key] = value
-
- def copy(self):
- return dict(self.items())
-
- def __hash__(self):
- raise TypeError("%s objects are unhashable" % type(self).__name__)
-
- for func_name, func in locals().items():
- if (util.callable(func) and func.func_name == func_name and
- not func.__doc__ and hasattr(dict, func_name)):
- func.__doc__ = getattr(dict, func_name).__doc__
- del func_name, func
-
-
-class _AssociationSet(_AssociationCollection):
- """Generic, converting, set-to-set proxy."""
-
- def _create(self, value):
- return self.creator(value)
-
- def _get(self, object):
- return self.getter(object)
-
- def _set(self, object, value):
- return self.setter(object, value)
-
- def __len__(self):
- return len(self.col)
-
- def __nonzero__(self):
- if self.col:
- return True
- else:
- return False
-
- def __contains__(self, value):
- for member in self.col:
- # testlib.pragma exempt:__eq__
- if self._get(member) == value:
- return True
- return False
-
- def __iter__(self):
- """Iterate over proxied values.
-
- For the actual domain objects, iterate over .col instead or just use
- the underlying collection directly from its property on the parent.
-
- """
- for member in self.col:
- yield self._get(member)
- raise StopIteration
-
- def add(self, value):
- if value not in self:
- self.col.add(self._create(value))
-
- # for discard and remove, choosing a more expensive check strategy rather
- # than call self.creator()
- def discard(self, value):
- for member in self.col:
- if self._get(member) == value:
- self.col.discard(member)
- break
-
- def remove(self, value):
- for member in self.col:
- if self._get(member) == value:
- self.col.discard(member)
- return
- raise KeyError(value)
-
- def pop(self):
- if not self.col:
- raise KeyError('pop from an empty set')
- member = self.col.pop()
- return self._get(member)
-
- def update(self, other):
- for value in other:
- self.add(value)
-
- def __ior__(self, other):
- if not collections._set_binops_check_strict(self, other):
- return NotImplemented
- for value in other:
- self.add(value)
- return self
-
- def _set(self):
- return set(iter(self))
-
- def union(self, other):
- return set(self).union(other)
-
- __or__ = union
-
- def difference(self, other):
- return set(self).difference(other)
-
- __sub__ = difference
-
- def difference_update(self, other):
- for value in other:
- self.discard(value)
-
- def __isub__(self, other):
- if not collections._set_binops_check_strict(self, other):
- return NotImplemented
- for value in other:
- self.discard(value)
- return self
-
- def intersection(self, other):
- return set(self).intersection(other)
-
- __and__ = intersection
-
- def intersection_update(self, other):
- want, have = self.intersection(other), set(self)
-
- remove, add = have - want, want - have
-
- for value in remove:
- self.remove(value)
- for value in add:
- self.add(value)
-
- def __iand__(self, other):
- if not collections._set_binops_check_strict(self, other):
- return NotImplemented
- want, have = self.intersection(other), set(self)
-
- remove, add = have - want, want - have
-
- for value in remove:
- self.remove(value)
- for value in add:
- self.add(value)
- return self
-
- def symmetric_difference(self, other):
- return set(self).symmetric_difference(other)
-
- __xor__ = symmetric_difference
-
- def symmetric_difference_update(self, other):
- want, have = self.symmetric_difference(other), set(self)
-
- remove, add = have - want, want - have
-
- for value in remove:
- self.remove(value)
- for value in add:
- self.add(value)
-
- def __ixor__(self, other):
- if not collections._set_binops_check_strict(self, other):
- return NotImplemented
- want, have = self.symmetric_difference(other), set(self)
-
- remove, add = have - want, want - have
-
- for value in remove:
- self.remove(value)
- for value in add:
- self.add(value)
- return self
-
- def issubset(self, other):
- return set(self).issubset(other)
-
- def issuperset(self, other):
- return set(self).issuperset(other)
-
- def clear(self):
- self.col.clear()
-
- def copy(self):
- return set(self)
-
- def __eq__(self, other):
- return set(self) == other
-
- def __ne__(self, other):
- return set(self) != other
-
- def __lt__(self, other):
- return set(self) < other
-
- def __le__(self, other):
- return set(self) <= other
-
- def __gt__(self, other):
- return set(self) > other
-
- def __ge__(self, other):
- return set(self) >= other
-
- def __repr__(self):
- return repr(set(self))
-
- def __hash__(self):
- raise TypeError("%s objects are unhashable" % type(self).__name__)
-
- for func_name, func in locals().items():
- if (util.callable(func) and func.func_name == func_name and
- not func.__doc__ and hasattr(set, func_name)):
- func.__doc__ = getattr(set, func_name).__doc__
- del func_name, func
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/compiler.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/compiler.py
deleted file mode 100755
index 7b083774..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/compiler.py
+++ /dev/null
@@ -1,355 +0,0 @@
-# ext/compiler.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Provides an API for creation of custom ClauseElements and compilers.
-
-Synopsis
-========
-
-Usage involves the creation of one or more :class:`~sqlalchemy.sql.expression.ClauseElement`
-subclasses and one or more callables defining its compilation::
-
- from sqlalchemy.ext.compiler import compiles
- from sqlalchemy.sql.expression import ColumnClause
-
- class MyColumn(ColumnClause):
- pass
-
- @compiles(MyColumn)
- def compile_mycolumn(element, compiler, **kw):
- return "[%s]" % element.name
-
-Above, ``MyColumn`` extends :class:`~sqlalchemy.sql.expression.ColumnClause`,
-the base expression element for named column objects. The ``compiles``
-decorator registers itself with the ``MyColumn`` class so that it is invoked
-when the object is compiled to a string::
-
- from sqlalchemy import select
-
- s = select([MyColumn('x'), MyColumn('y')])
- print str(s)
-
-Produces::
-
- SELECT [x], [y]
-
-Dialect-specific compilation rules
-==================================
-
-Compilers can also be made dialect-specific. The appropriate compiler will be
-invoked for the dialect in use::
-
- from sqlalchemy.schema import DDLElement
-
- class AlterColumn(DDLElement):
-
- def __init__(self, column, cmd):
- self.column = column
- self.cmd = cmd
-
- @compiles(AlterColumn)
- def visit_alter_column(element, compiler, **kw):
- return "ALTER COLUMN %s ..." % element.column.name
-
- @compiles(AlterColumn, 'postgresql')
- def visit_alter_column(element, compiler, **kw):
- return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name, element.column.name)
-
-The second ``visit_alter_table`` will be invoked when any ``postgresql`` dialect is used.
-
-Compiling sub-elements of a custom expression construct
-=======================================================
-
-The ``compiler`` argument is the :class:`~sqlalchemy.engine.base.Compiled`
-object in use. This object can be inspected for any information about the
-in-progress compilation, including ``compiler.dialect``,
-``compiler.statement`` etc. The :class:`~sqlalchemy.sql.compiler.SQLCompiler`
-and :class:`~sqlalchemy.sql.compiler.DDLCompiler` both include a ``process()``
-method which can be used for compilation of embedded attributes::
-
- from sqlalchemy.sql.expression import Executable, ClauseElement
-
- class InsertFromSelect(Executable, ClauseElement):
- def __init__(self, table, select):
- self.table = table
- self.select = select
-
- @compiles(InsertFromSelect)
- def visit_insert_from_select(element, compiler, **kw):
- return "INSERT INTO %s (%s)" % (
- compiler.process(element.table, asfrom=True),
- compiler.process(element.select)
- )
-
- insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
- print insert
-
-Produces::
-
- "INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z FROM mytable WHERE mytable.x > :x_1)"
-
-Cross Compiling between SQL and DDL compilers
----------------------------------------------
-
-SQL and DDL constructs are each compiled using different base compilers - ``SQLCompiler``
-and ``DDLCompiler``. A common need is to access the compilation rules of SQL expressions
-from within a DDL expression. The ``DDLCompiler`` includes an accessor ``sql_compiler`` for this reason, such as below where we generate a CHECK
-constraint that embeds a SQL expression::
-
- @compiles(MyConstraint)
- def compile_my_constraint(constraint, ddlcompiler, **kw):
- return "CONSTRAINT %s CHECK (%s)" % (
- constraint.name,
- ddlcompiler.sql_compiler.process(constraint.expression)
- )
-
-Changing the default compilation of existing constructs
-=======================================================
-
-The compiler extension applies just as well to the existing constructs. When overriding
-the compilation of a built in SQL construct, the @compiles decorator is invoked upon
-the appropriate class (be sure to use the class, i.e. ``Insert`` or ``Select``, instead of the creation function such as ``insert()`` or ``select()``).
-
-Within the new compilation function, to get at the "original" compilation routine,
-use the appropriate visit_XXX method - this because compiler.process() will call upon the
-overriding routine and cause an endless loop. Such as, to add "prefix" to all insert statements::
-
- from sqlalchemy.sql.expression import Insert
-
- @compiles(Insert)
- def prefix_inserts(insert, compiler, **kw):
- return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
-
-The above compiler will prefix all INSERT statements with "some prefix" when compiled.
-
-.. _type_compilation_extension:
-
-Changing Compilation of Types
-=============================
-
-``compiler`` works for types, too, such as below where we implement the MS-SQL specific 'max' keyword for ``String``/``VARCHAR``::
-
- @compiles(String, 'mssql')
- @compiles(VARCHAR, 'mssql')
- def compile_varchar(element, compiler, **kw):
- if element.length == 'max':
- return "VARCHAR('max')"
- else:
- return compiler.visit_VARCHAR(element, **kw)
-
- foo = Table('foo', metadata,
- Column('data', VARCHAR('max'))
- )
-
-Subclassing Guidelines
-======================
-
-A big part of using the compiler extension is subclassing SQLAlchemy
-expression constructs. To make this easier, the expression and
-schema packages feature a set of "bases" intended for common tasks.
-A synopsis is as follows:
-
-* :class:`~sqlalchemy.sql.expression.ClauseElement` - This is the root
- expression class. Any SQL expression can be derived from this base, and is
- probably the best choice for longer constructs such as specialized INSERT
- statements.
-
-* :class:`~sqlalchemy.sql.expression.ColumnElement` - The root of all
- "column-like" elements. Anything that you'd place in the "columns" clause of
- a SELECT statement (as well as order by and group by) can derive from this -
- the object will automatically have Python "comparison" behavior.
-
- :class:`~sqlalchemy.sql.expression.ColumnElement` classes want to have a
- ``type`` member which is expression's return type. This can be established
- at the instance level in the constructor, or at the class level if its
- generally constant::
-
- class timestamp(ColumnElement):
- type = TIMESTAMP()
-
-* :class:`~sqlalchemy.sql.expression.FunctionElement` - This is a hybrid of a
- ``ColumnElement`` and a "from clause" like object, and represents a SQL
- function or stored procedure type of call. Since most databases support
- statements along the line of "SELECT FROM <some function>"
- ``FunctionElement`` adds in the ability to be used in the FROM clause of a
- ``select()`` construct::
-
- from sqlalchemy.sql.expression import FunctionElement
-
- class coalesce(FunctionElement):
- name = 'coalesce'
-
- @compiles(coalesce)
- def compile(element, compiler, **kw):
- return "coalesce(%s)" % compiler.process(element.clauses)
-
- @compiles(coalesce, 'oracle')
- def compile(element, compiler, **kw):
- if len(element.clauses) > 2:
- raise TypeError("coalesce only supports two arguments on Oracle")
- return "nvl(%s)" % compiler.process(element.clauses)
-
-* :class:`~sqlalchemy.schema.DDLElement` - The root of all DDL expressions,
- like CREATE TABLE, ALTER TABLE, etc. Compilation of ``DDLElement``
- subclasses is issued by a ``DDLCompiler`` instead of a ``SQLCompiler``.
- ``DDLElement`` also features ``Table`` and ``MetaData`` event hooks via the
- ``execute_at()`` method, allowing the construct to be invoked during CREATE
- TABLE and DROP TABLE sequences.
-
-* :class:`~sqlalchemy.sql.expression.Executable` - This is a mixin which should be
- used with any expression class that represents a "standalone" SQL statement that
- can be passed directly to an ``execute()`` method. It is already implicit
- within ``DDLElement`` and ``FunctionElement``.
-
-Further Examples
-================
-
-"UTC timestamp" function
--------------------------
-
-A function that works like "CURRENT_TIMESTAMP" except applies the appropriate conversions
-so that the time is in UTC time. Timestamps are best stored in relational databases
-as UTC, without time zones. UTC so that your database doesn't think time has gone
-backwards in the hour when daylight savings ends, without timezones because timezones
-are like character encodings - they're best applied only at the endpoints of an
-application (i.e. convert to UTC upon user input, re-apply desired timezone upon display).
-
-For Postgresql and Microsoft SQL Server::
-
- from sqlalchemy.sql import expression
- from sqlalchemy.ext.compiler import compiles
- from sqlalchemy.types import DateTime
-
- class utcnow(expression.FunctionElement):
- type = DateTime()
-
- @compiles(utcnow, 'postgresql')
- def pg_utcnow(element, compiler, **kw):
- return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
-
- @compiles(utcnow, 'mssql')
- def ms_utcnow(element, compiler, **kw):
- return "GETUTCDATE()"
-
-Example usage::
-
- from sqlalchemy import (
- Table, Column, Integer, String, DateTime, MetaData
- )
- metadata = MetaData()
- event = Table("event", metadata,
- Column("id", Integer, primary_key=True),
- Column("description", String(50), nullable=False),
- Column("timestamp", DateTime, server_default=utcnow())
- )
-
-"GREATEST" function
--------------------
-
-The "GREATEST" function is given any number of arguments and returns the one that is
-of the highest value - it's equivalent to Python's ``max`` function. A SQL
-standard version versus a CASE based version which only accommodates two
-arguments::
-
- from sqlalchemy.sql import expression
- from sqlalchemy.ext.compiler import compiles
- from sqlalchemy.types import Numeric
-
- class greatest(expression.FunctionElement):
- type = Numeric()
- name = 'greatest'
-
- @compiles(greatest)
- def default_greatest(element, compiler, **kw):
- return compiler.visit_function(element)
-
- @compiles(greatest, 'sqlite')
- @compiles(greatest, 'mssql')
- @compiles(greatest, 'oracle')
- def case_greatest(element, compiler, **kw):
- arg1, arg2 = list(element.clauses)
- return "CASE WHEN %s > %s THEN %s ELSE %s END" % (
- compiler.process(arg1),
- compiler.process(arg2),
- compiler.process(arg1),
- compiler.process(arg2),
- )
-
-Example usage::
-
- Session.query(Account).\\
- filter(
- greatest(
- Account.checking_balance,
- Account.savings_balance) > 10000
- )
-
-"false" expression
-------------------
-
-Render a "false" constant expression, rendering as "0" on platforms that don't have a "false" constant::
-
- from sqlalchemy.sql import expression
- from sqlalchemy.ext.compiler import compiles
-
- class sql_false(expression.ColumnElement):
- pass
-
- @compiles(sql_false)
- def default_false(element, compiler, **kw):
- return "false"
-
- @compiles(sql_false, 'mssql')
- @compiles(sql_false, 'mysql')
- @compiles(sql_false, 'oracle')
- def int_false(element, compiler, **kw):
- return "0"
-
-Example usage::
-
- from sqlalchemy import select, union_all
-
- exp = union_all(
- select([users.c.name, sql_false().label("enrolled")]),
- select([customers.c.name, customers.c.enrolled])
- )
-
-"""
-
-def compiles(class_, *specs):
- def decorate(fn):
- existing = class_.__dict__.get('_compiler_dispatcher', None)
- existing_dispatch = class_.__dict__.get('_compiler_dispatch')
- if not existing:
- existing = _dispatcher()
-
- if existing_dispatch:
- existing.specs['default'] = existing_dispatch
-
- # TODO: why is the lambda needed ?
- setattr(class_, '_compiler_dispatch', lambda *arg, **kw: existing(*arg, **kw))
- setattr(class_, '_compiler_dispatcher', existing)
-
- if specs:
- for s in specs:
- existing.specs[s] = fn
-
- else:
- existing.specs['default'] = fn
- return fn
- return decorate
-
-class _dispatcher(object):
- def __init__(self):
- self.specs = {}
-
- def __call__(self, element, compiler, **kw):
- # TODO: yes, this could also switch off of DBAPI in use.
- fn = self.specs.get(compiler.dialect.name, None)
- if not fn:
- fn = self.specs['default']
- return fn(element, compiler, **kw)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative.py
deleted file mode 100755
index 62a11705..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative.py
+++ /dev/null
@@ -1,1425 +0,0 @@
-# ext/declarative.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Synopsis
-========
-
-SQLAlchemy object-relational configuration involves the
-combination of :class:`.Table`, :func:`.mapper`, and class
-objects to define a mapped class.
-:mod:`~sqlalchemy.ext.declarative` allows all three to be
-expressed at once within the class declaration. As much as
-possible, regular SQLAlchemy schema and ORM constructs are
-used directly, so that configuration between "classical" ORM
-usage and declarative remain highly similar.
-
-As a simple example::
-
- from sqlalchemy.ext.declarative import declarative_base
-
- Base = declarative_base()
-
- class SomeClass(Base):
- __tablename__ = 'some_table'
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
-
-Above, the :func:`declarative_base` callable returns a new base class from
-which all mapped classes should inherit. When the class definition is
-completed, a new :class:`.Table` and
-:func:`.mapper` will have been generated.
-
-The resulting table and mapper are accessible via
-``__table__`` and ``__mapper__`` attributes on the
-``SomeClass`` class::
-
- # access the mapped Table
- SomeClass.__table__
-
- # access the Mapper
- SomeClass.__mapper__
-
-Defining Attributes
-===================
-
-In the previous example, the :class:`.Column` objects are
-automatically named with the name of the attribute to which they are
-assigned.
-
-To name columns explicitly with a name distinct from their mapped attribute,
-just give the column a name. Below, column "some_table_id" is mapped to the
-"id" attribute of `SomeClass`, but in SQL will be represented as "some_table_id"::
-
- class SomeClass(Base):
- __tablename__ = 'some_table'
- id = Column("some_table_id", Integer, primary_key=True)
-
-Attributes may be added to the class after its construction, and they will be
-added to the underlying :class:`.Table` and
-:func:`.mapper()` definitions as appropriate::
-
- SomeClass.data = Column('data', Unicode)
- SomeClass.related = relationship(RelatedInfo)
-
-Classes which are constructed using declarative can interact freely
-with classes that are mapped explicitly with :func:`mapper`.
-
-It is recommended, though not required, that all tables
-share the same underlying :class:`~sqlalchemy.schema.MetaData` object,
-so that string-configured :class:`~sqlalchemy.schema.ForeignKey`
-references can be resolved without issue.
-
-Accessing the MetaData
-=======================
-
-The :func:`declarative_base` base class contains a
-:class:`.MetaData` object where newly defined
-:class:`.Table` objects are collected. This object is
-intended to be accessed directly for
-:class:`.MetaData`-specific operations. Such as, to issue
-CREATE statements for all tables::
-
- engine = create_engine('sqlite://')
- Base.metadata.create_all(engine)
-
-The usual techniques of associating :class:`.MetaData:` with :class:`.Engine`
-apply, such as assigning to the ``bind`` attribute::
-
- Base.metadata.bind = create_engine('sqlite://')
-
-To associate the engine with the :func:`declarative_base` at time
-of construction, the ``bind`` argument is accepted::
-
- Base = declarative_base(bind=create_engine('sqlite://'))
-
-:func:`declarative_base` can also receive a pre-existing
-:class:`.MetaData` object, which allows a
-declarative setup to be associated with an already
-existing traditional collection of :class:`~sqlalchemy.schema.Table`
-objects::
-
- mymetadata = MetaData()
- Base = declarative_base(metadata=mymetadata)
-
-Configuring Relationships
-=========================
-
-Relationships to other classes are done in the usual way, with the added
-feature that the class specified to :func:`~sqlalchemy.orm.relationship`
-may be a string name. The "class registry" associated with ``Base``
-is used at mapper compilation time to resolve the name into the actual
-class object, which is expected to have been defined once the mapper
-configuration is used::
-
- class User(Base):
- __tablename__ = 'users'
-
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
- addresses = relationship("Address", backref="user")
-
- class Address(Base):
- __tablename__ = 'addresses'
-
- id = Column(Integer, primary_key=True)
- email = Column(String(50))
- user_id = Column(Integer, ForeignKey('users.id'))
-
-Column constructs, since they are just that, are immediately usable,
-as below where we define a primary join condition on the ``Address``
-class using them::
-
- class Address(Base):
- __tablename__ = 'addresses'
-
- id = Column(Integer, primary_key=True)
- email = Column(String(50))
- user_id = Column(Integer, ForeignKey('users.id'))
- user = relationship(User, primaryjoin=user_id == User.id)
-
-In addition to the main argument for :func:`~sqlalchemy.orm.relationship`,
-other arguments which depend upon the columns present on an as-yet
-undefined class may also be specified as strings. These strings are
-evaluated as Python expressions. The full namespace available within
-this evaluation includes all classes mapped for this declarative base,
-as well as the contents of the ``sqlalchemy`` package, including
-expression functions like :func:`~sqlalchemy.sql.expression.desc` and
-:attr:`~sqlalchemy.sql.expression.func`::
-
- class User(Base):
- # ....
- addresses = relationship("Address",
- order_by="desc(Address.email)",
- primaryjoin="Address.user_id==User.id")
-
-As an alternative to string-based attributes, attributes may also be
-defined after all classes have been created. Just add them to the target
-class after the fact::
-
- User.addresses = relationship(Address,
- primaryjoin=Address.user_id==User.id)
-
-Configuring Many-to-Many Relationships
-======================================
-
-Many-to-many relationships are also declared in the same way
-with declarative as with traditional mappings. The
-``secondary`` argument to
-:func:`.relationship` is as usual passed a
-:class:`.Table` object, which is typically declared in the
-traditional way. The :class:`.Table` usually shares
-the :class:`.MetaData` object used by the declarative base::
-
- keywords = Table(
- 'keywords', Base.metadata,
- Column('author_id', Integer, ForeignKey('authors.id')),
- Column('keyword_id', Integer, ForeignKey('keywords.id'))
- )
-
- class Author(Base):
- __tablename__ = 'authors'
- id = Column(Integer, primary_key=True)
- keywords = relationship("Keyword", secondary=keywords)
-
-As with traditional mapping, its generally not a good idea to use
-a :class:`.Table` as the "secondary" argument which is also mapped to
-a class, unless the :class:`.relationship` is declared with ``viewonly=True``.
-Otherwise, the unit-of-work system may attempt duplicate INSERT and
-DELETE statements against the underlying table.
-
-.. _declarative_sql_expressions:
-
-Defining SQL Expressions
-========================
-
-The usage of :func:`.column_property` with Declarative to define
-load-time, mapped SQL expressions is
-pretty much the same as that described in
-:ref:`mapper_sql_expressions`. Local columns within the same
-class declaration can be referenced directly::
-
- class User(Base):
- __tablename__ = 'user'
- id = Column(Integer, primary_key=True)
- firstname = Column(String)
- lastname = Column(String)
- fullname = column_property(
- firstname + " " + lastname
- )
-
-Correlated subqueries reference the :class:`.Column` objects they
-need either from the local class definition or from remote
-classes::
-
- from sqlalchemy.sql import func
-
- class Address(Base):
- __tablename__ = 'address'
-
- id = Column('id', Integer, primary_key=True)
- user_id = Column(Integer, ForeignKey('user.id'))
-
- class User(Base):
- __tablename__ = 'user'
-
- id = Column(Integer, primary_key=True)
- name = Column(String)
-
- address_count = column_property(
- select([func.count(Address.id)]).\\
- where(Address.user_id==id)
- )
-
-In the case that the ``address_count`` attribute above doesn't have access to
-``Address`` when ``User`` is defined, the ``address_count`` attribute should
-be added to ``User`` when both ``User`` and ``Address`` are available (i.e.
-there is no string based "late compilation" feature like there is with
-:func:`.relationship` at this time). Note we reference the ``id`` column
-attribute of ``User`` with its class when we are no longer in the declaration
-of the ``User`` class::
-
- User.address_count = column_property(
- select([func.count(Address.id)]).\\
- where(Address.user_id==User.id)
- )
-
-Table Configuration
-===================
-
-Table arguments other than the name, metadata, and mapped Column
-arguments are specified using the ``__table_args__`` class attribute.
-This attribute accommodates both positional as well as keyword
-arguments that are normally sent to the
-:class:`~sqlalchemy.schema.Table` constructor.
-The attribute can be specified in one of two forms. One is as a
-dictionary::
-
- class MyClass(Base):
- __tablename__ = 'sometable'
- __table_args__ = {'mysql_engine':'InnoDB'}
-
-The other, a tuple, where each argument is positional
-(usually constraints)::
-
- class MyClass(Base):
- __tablename__ = 'sometable'
- __table_args__ = (
- ForeignKeyConstraint(['id'], ['remote_table.id']),
- UniqueConstraint('foo'),
- )
-
-Keyword arguments can be specified with the above form by
-specifying the last argument as a dictionary::
-
- class MyClass(Base):
- __tablename__ = 'sometable'
- __table_args__ = (
- ForeignKeyConstraint(['id'], ['remote_table.id']),
- UniqueConstraint('foo'),
- {'autoload':True}
- )
-
-Using a Hybrid Approach with __table__
-=======================================
-
-As an alternative to ``__tablename__``, a direct
-:class:`~sqlalchemy.schema.Table` construct may be used. The
-:class:`~sqlalchemy.schema.Column` objects, which in this case require
-their names, will be added to the mapping just like a regular mapping
-to a table::
-
- class MyClass(Base):
- __table__ = Table('my_table', Base.metadata,
- Column('id', Integer, primary_key=True),
- Column('name', String(50))
- )
-
-``__table__`` provides a more focused point of control for establishing
-table metadata, while still getting most of the benefits of using declarative.
-An application that uses reflection might want to load table metadata elsewhere
-and simply pass it to declarative classes::
-
- from sqlalchemy.ext.declarative import declarative_base
-
- Base = declarative_base()
- Base.metadata.reflect(some_engine)
-
- class User(Base):
- __table__ = metadata.tables['user']
-
- class Address(Base):
- __table__ = metadata.tables['address']
-
-Some configuration schemes may find it more appropriate to use ``__table__``,
-such as those which already take advantage of the data-driven nature of
-:class:`.Table` to customize and/or automate schema definition. See
-the wiki example `NamingConventions <http://www.sqlalchemy.org/trac/wiki/UsageRecipes/NamingConventions>`_
-for one such example.
-
-Mapper Configuration
-====================
-
-Declarative makes use of the :func:`~.orm.mapper` function internally
-when it creates the mapping to the declared table. The options
-for :func:`~.orm.mapper` are passed directly through via the ``__mapper_args__``
-class attribute. As always, arguments which reference locally
-mapped columns can reference them directly from within the
-class declaration::
-
- from datetime import datetime
-
- class Widget(Base):
- __tablename__ = 'widgets'
-
- id = Column(Integer, primary_key=True)
- timestamp = Column(DateTime, nullable=False)
-
- __mapper_args__ = {
- 'version_id_col': timestamp,
- 'version_id_generator': lambda v:datetime.now()
- }
-
-.. _declarative_inheritance:
-
-Inheritance Configuration
-=========================
-
-Declarative supports all three forms of inheritance as intuitively
-as possible. The ``inherits`` mapper keyword argument is not needed
-as declarative will determine this from the class itself. The various
-"polymorphic" keyword arguments are specified using ``__mapper_args__``.
-
-Joined Table Inheritance
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Joined table inheritance is defined as a subclass that defines its own
-table::
-
- class Person(Base):
- __tablename__ = 'people'
- id = Column(Integer, primary_key=True)
- discriminator = Column('type', String(50))
- __mapper_args__ = {'polymorphic_on': discriminator}
-
- class Engineer(Person):
- __tablename__ = 'engineers'
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
- id = Column(Integer, ForeignKey('people.id'), primary_key=True)
- primary_language = Column(String(50))
-
-Note that above, the ``Engineer.id`` attribute, since it shares the
-same attribute name as the ``Person.id`` attribute, will in fact
-represent the ``people.id`` and ``engineers.id`` columns together, and
-will render inside a query as ``"people.id"``.
-To provide the ``Engineer`` class with an attribute that represents
-only the ``engineers.id`` column, give it a different attribute name::
-
- class Engineer(Person):
- __tablename__ = 'engineers'
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
- engineer_id = Column('id', Integer, ForeignKey('people.id'),
- primary_key=True)
- primary_language = Column(String(50))
-
-Single Table Inheritance
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Single table inheritance is defined as a subclass that does not have
-its own table; you just leave out the ``__table__`` and ``__tablename__``
-attributes::
-
- class Person(Base):
- __tablename__ = 'people'
- id = Column(Integer, primary_key=True)
- discriminator = Column('type', String(50))
- __mapper_args__ = {'polymorphic_on': discriminator}
-
- class Engineer(Person):
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
- primary_language = Column(String(50))
-
-When the above mappers are configured, the ``Person`` class is mapped
-to the ``people`` table *before* the ``primary_language`` column is
-defined, and this column will not be included in its own mapping.
-When ``Engineer`` then defines the ``primary_language`` column, the
-column is added to the ``people`` table so that it is included in the
-mapping for ``Engineer`` and is also part of the table's full set of
-columns. Columns which are not mapped to ``Person`` are also excluded
-from any other single or joined inheriting classes using the
-``exclude_properties`` mapper argument. Below, ``Manager`` will have
-all the attributes of ``Person`` and ``Manager`` but *not* the
-``primary_language`` attribute of ``Engineer``::
-
- class Manager(Person):
- __mapper_args__ = {'polymorphic_identity': 'manager'}
- golf_swing = Column(String(50))
-
-The attribute exclusion logic is provided by the
-``exclude_properties`` mapper argument, and declarative's default
-behavior can be disabled by passing an explicit ``exclude_properties``
-collection (empty or otherwise) to the ``__mapper_args__``.
-
-Concrete Table Inheritance
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Concrete is defined as a subclass which has its own table and sets the
-``concrete`` keyword argument to ``True``::
-
- class Person(Base):
- __tablename__ = 'people'
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
-
- class Engineer(Person):
- __tablename__ = 'engineers'
- __mapper_args__ = {'concrete':True}
- id = Column(Integer, primary_key=True)
- primary_language = Column(String(50))
- name = Column(String(50))
-
-Usage of an abstract base class is a little less straightforward as it
-requires usage of :func:`~sqlalchemy.orm.util.polymorphic_union`::
-
- engineers = Table('engineers', Base.metadata,
- Column('id', Integer, primary_key=True),
- Column('name', String(50)),
- Column('primary_language', String(50))
- )
- managers = Table('managers', Base.metadata,
- Column('id', Integer, primary_key=True),
- Column('name', String(50)),
- Column('golf_swing', String(50))
- )
-
- punion = polymorphic_union({
- 'engineer':engineers,
- 'manager':managers
- }, 'type', 'punion')
-
- class Person(Base):
- __table__ = punion
- __mapper_args__ = {'polymorphic_on':punion.c.type}
-
- class Engineer(Person):
- __table__ = engineers
- __mapper_args__ = {'polymorphic_identity':'engineer', 'concrete':True}
-
- class Manager(Person):
- __table__ = managers
- __mapper_args__ = {'polymorphic_identity':'manager', 'concrete':True}
-
-
-Mixin Classes
-==============
-
-A common need when using :mod:`~sqlalchemy.ext.declarative` is to
-share some functionality, often a set of columns, across many
-classes. The normal Python idiom would be to put this common code into
-a base class and have all the other classes subclass this class.
-
-When using :mod:`~sqlalchemy.ext.declarative`, this need is met by
-using a "mixin class". A mixin class is one that isn't mapped to a
-table and doesn't subclass the declarative :class:`.Base`. For example::
-
- class MyMixin(object):
-
- __table_args__ = {'mysql_engine': 'InnoDB'}
- __mapper_args__= {'always_refresh': True}
-
- id = Column(Integer, primary_key=True)
-
-
- class MyModel(Base,MyMixin):
- __tablename__ = 'test'
-
- name = Column(String(1000))
-
-Where above, the class ``MyModel`` will contain an "id" column
-as well as ``__table_args__`` and ``__mapper_args__`` defined
-by the ``MyMixin`` mixin class.
-
-Mixing in Columns
-~~~~~~~~~~~~~~~~~
-
-The most basic way to specify a column on a mixin is by simple
-declaration::
-
- class TimestampMixin(object):
- created_at = Column(DateTime, default=func.now())
-
- class MyModel(Base, TimestampMixin):
- __tablename__ = 'test'
-
- id = Column(Integer, primary_key=True)
- name = Column(String(1000))
-
-Where above, all declarative classes that include ``TimestampMixin``
-will also have a column ``created_at`` that applies a timestamp to
-all row insertions.
-
-Those familiar with the SQLAlchemy expression language know that
-the object identity of clause elements defines their role in a schema.
-Two ``Table`` objects ``a`` and ``b`` may both have a column called
-``id``, but the way these are differentiated is that ``a.c.id``
-and ``b.c.id`` are two distinct Python objects, referencing their
-parent tables ``a`` and ``b`` respectively.
-
-In the case of the mixin column, it seems that only one
-:class:`.Column` object is explicitly created, yet the ultimate
-``created_at`` column above must exist as a distinct Python object
-for each separate destination class. To accomplish this, the declarative
-extension creates a **copy** of each :class:`.Column` object encountered on
-a class that is detected as a mixin.
-
-This copy mechanism is limited to simple columns that have no foreign
-keys, as a :class:`.ForeignKey` itself contains references to columns
-which can't be properly recreated at this level. For columns that
-have foreign keys, as well as for the variety of mapper-level constructs
-that require destination-explicit context, the
-:func:`~.declared_attr` decorator (renamed from ``sqlalchemy.util.classproperty`` in 0.6.5)
-is provided so that
-patterns common to many classes can be defined as callables::
-
- from sqlalchemy.ext.declarative import declared_attr
-
- class ReferenceAddressMixin(object):
- @declared_attr
- def address_id(cls):
- return Column(Integer, ForeignKey('address.id'))
-
- class User(Base, ReferenceAddressMixin):
- __tablename__ = 'user'
- id = Column(Integer, primary_key=True)
-
-Where above, the ``address_id`` class-level callable is executed at the
-point at which the ``User`` class is constructed, and the declarative
-extension can use the resulting :class:`.Column` object as returned by
-the method without the need to copy it.
-
-Columns generated by :func:`~.declared_attr` can also be
-referenced by ``__mapper_args__`` to a limited degree, currently
-by ``polymorphic_on`` and ``version_id_col``, by specifying the
-classdecorator itself into the dictionary - the declarative extension
-will resolve them at class construction time::
-
- class MyMixin:
- @declared_attr
- def type_(cls):
- return Column(String(50))
-
- __mapper_args__= {'polymorphic_on':type_}
-
- class MyModel(Base,MyMixin):
- __tablename__='test'
- id = Column(Integer, primary_key=True)
-
-Mixing in Relationships
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Relationships created by :func:`~sqlalchemy.orm.relationship` are provided
-with declarative mixin classes exclusively using the
-:func:`.declared_attr` approach, eliminating any ambiguity
-which could arise when copying a relationship and its possibly column-bound
-contents. Below is an example which combines a foreign key column and a
-relationship so that two classes ``Foo`` and ``Bar`` can both be configured to
-reference a common target class via many-to-one::
-
- class RefTargetMixin(object):
- @declared_attr
- def target_id(cls):
- return Column('target_id', ForeignKey('target.id'))
-
- @declared_attr
- def target(cls):
- return relationship("Target")
-
- class Foo(Base, RefTargetMixin):
- __tablename__ = 'foo'
- id = Column(Integer, primary_key=True)
-
- class Bar(Base, RefTargetMixin):
- __tablename__ = 'bar'
- id = Column(Integer, primary_key=True)
-
- class Target(Base):
- __tablename__ = 'target'
- id = Column(Integer, primary_key=True)
-
-:func:`~sqlalchemy.orm.relationship` definitions which require explicit
-primaryjoin, order_by etc. expressions should use the string forms
-for these arguments, so that they are evaluated as late as possible.
-To reference the mixin class in these expressions, use the given ``cls``
-to get it's name::
-
- class RefTargetMixin(object):
- @declared_attr
- def target_id(cls):
- return Column('target_id', ForeignKey('target.id'))
-
- @declared_attr
- def target(cls):
- return relationship("Target",
- primaryjoin="Target.id==%s.target_id" % cls.__name__
- )
-
-Mixing in deferred(), column_property(), etc.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like :func:`~sqlalchemy.orm.relationship`, all
-:class:`~sqlalchemy.orm.interfaces.MapperProperty` subclasses such as
-:func:`~sqlalchemy.orm.deferred`, :func:`~sqlalchemy.orm.column_property`,
-etc. ultimately involve references to columns, and therefore, when
-used with declarative mixins, have the :func:`.declared_attr`
-requirement so that no reliance on copying is needed::
-
- class SomethingMixin(object):
-
- @declared_attr
- def dprop(cls):
- return deferred(Column(Integer))
-
- class Something(Base, SomethingMixin):
- __tablename__ = "something"
-
-
-Controlling table inheritance with mixins
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``__tablename__`` attribute in conjunction with the hierarchy of
-classes involved in a declarative mixin scenario controls what type of
-table inheritance, if any,
-is configured by the declarative extension.
-
-If the ``__tablename__`` is computed by a mixin, you may need to
-control which classes get the computed attribute in order to get the
-type of table inheritance you require.
-
-For example, if you had a mixin that computes ``__tablename__`` but
-where you wanted to use that mixin in a single table inheritance
-hierarchy, you can explicitly specify ``__tablename__`` as ``None`` to
-indicate that the class should not have a table mapped::
-
- from sqlalchemy.ext.declarative import declared_attr
-
- class Tablename:
- @declared_attr
- def __tablename__(cls):
- return cls.__name__.lower()
-
- class Person(Base,Tablename):
- id = Column(Integer, primary_key=True)
- discriminator = Column('type', String(50))
- __mapper_args__ = {'polymorphic_on': discriminator}
-
- class Engineer(Person):
- __tablename__ = None
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
- primary_language = Column(String(50))
-
-Alternatively, you can make the mixin intelligent enough to only
-return a ``__tablename__`` in the event that no table is already
-mapped in the inheritance hierarchy. To help with this, a
-:func:`~sqlalchemy.ext.declarative.has_inherited_table` helper
-function is provided that returns ``True`` if a parent class already
-has a mapped table.
-
-As an example, here's a mixin that will only allow single table
-inheritance::
-
- from sqlalchemy.ext.declarative import declared_attr
- from sqlalchemy.ext.declarative import has_inherited_table
-
- class Tablename:
- @declared_attr
- def __tablename__(cls):
- if has_inherited_table(cls):
- return None
- return cls.__name__.lower()
-
- class Person(Base,Tablename):
- id = Column(Integer, primary_key=True)
- discriminator = Column('type', String(50))
- __mapper_args__ = {'polymorphic_on': discriminator}
-
- class Engineer(Person):
- primary_language = Column(String(50))
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
-
-If you want to use a similar pattern with a mix of single and joined
-table inheritance, you would need a slightly different mixin and use
-it on any joined table child classes in addition to their parent
-classes::
-
- from sqlalchemy.ext.declarative import declared_attr
- from sqlalchemy.ext.declarative import has_inherited_table
-
- class Tablename:
- @declared_attr
- def __tablename__(cls):
- if (has_inherited_table(cls) and
- Tablename not in cls.__bases__):
- return None
- return cls.__name__.lower()
-
- class Person(Base,Tablename):
- id = Column(Integer, primary_key=True)
- discriminator = Column('type', String(50))
- __mapper_args__ = {'polymorphic_on': discriminator}
-
- # This is single table inheritance
- class Engineer(Person):
- primary_language = Column(String(50))
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
-
- # This is joined table inheritance
- class Manager(Person,Tablename):
- id = Column(Integer, ForeignKey('person.id'), primary_key=True)
- preferred_recreation = Column(String(50))
- __mapper_args__ = {'polymorphic_identity': 'engineer'}
-
-Combining Table/Mapper Arguments from Multiple Mixins
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In the case of ``__table_args__`` or ``__mapper_args__``
-specified with declarative mixins, you may want to combine
-some parameters from several mixins with those you wish to
-define on the class iteself. The
-:func:`.declared_attr` decorator can be used
-here to create user-defined collation routines that pull
-from multiple collections::
-
- from sqlalchemy.ext.declarative import declared_attr
-
- class MySQLSettings:
- __table_args__ = {'mysql_engine':'InnoDB'}
-
- class MyOtherMixin:
- __table_args__ = {'info':'foo'}
-
- class MyModel(Base,MySQLSettings,MyOtherMixin):
- __tablename__='my_model'
-
- @declared_attr
- def __table_args__(cls):
- args = dict()
- args.update(MySQLSettings.__table_args__)
- args.update(MyOtherMixin.__table_args__)
- return args
-
- id = Column(Integer, primary_key=True)
-
-Creating Indexes with Mixins
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To define a named, potentially multicolumn :class:`.Index` that applies to all
-tables derived from a mixin, use the "inline" form of :class:`.Index` and establish
-it as part of ``__table_args__``::
-
- class MyMixin(object):
- a = Column(Integer)
- b = Column(Integer)
-
- @declared_attr
- def __table_args__(cls):
- return (Index('test_idx_%s' % cls.__tablename__, 'a', 'b'),)
-
- class MyModel(Base,MyMixin):
- __tablename__ = 'atable'
- c = Column(Integer,primary_key=True)
-
-
-Class Constructor
-=================
-
-As a convenience feature, the :func:`declarative_base` sets a default
-constructor on classes which takes keyword arguments, and assigns them
-to the named attributes::
-
- e = Engineer(primary_language='python')
-
-Sessions
-========
-
-Note that ``declarative`` does nothing special with sessions, and is
-only intended as an easier way to configure mappers and
-:class:`~sqlalchemy.schema.Table` objects. A typical application
-setup using :func:`~sqlalchemy.orm.scoped_session` might look like::
-
- engine = create_engine('postgresql://scott:tiger@localhost/test')
- Session = scoped_session(sessionmaker(autocommit=False,
- autoflush=False,
- bind=engine))
- Base = declarative_base()
-
-Mapped instances then make usage of
-:class:`~sqlalchemy.orm.session.Session` in the usual way.
-
-"""
-
-from sqlalchemy.schema import Table, Column, MetaData, _get_table_key
-from sqlalchemy.orm import synonym as _orm_synonym, mapper,\
- comparable_property, class_mapper
-from sqlalchemy.orm.interfaces import MapperProperty
-from sqlalchemy.orm.properties import RelationshipProperty, ColumnProperty, CompositeProperty
-from sqlalchemy.orm.util import _is_mapped_class
-from sqlalchemy import util, exc
-from sqlalchemy.sql import util as sql_util, expression
-
-
-__all__ = 'declarative_base', 'synonym_for', \
- 'comparable_using', 'instrument_declarative'
-
-def instrument_declarative(cls, registry, metadata):
- """Given a class, configure the class declaratively,
- using the given registry, which can be any dictionary, and
- MetaData object.
-
- """
- if '_decl_class_registry' in cls.__dict__:
- raise exc.InvalidRequestError(
- "Class %r already has been "
- "instrumented declaratively" % cls)
- cls._decl_class_registry = registry
- cls.metadata = metadata
- _as_declarative(cls, cls.__name__, cls.__dict__)
-
-def has_inherited_table(cls):
- """Given a class, return True if any of the classes it inherits from has a
- mapped table, otherwise return False.
- """
- for class_ in cls.__mro__:
- if getattr(class_,'__table__',None) is not None:
- return True
- return False
-
-def _as_declarative(cls, classname, dict_):
-
- # dict_ will be a dictproxy, which we can't write to, and we need to!
- dict_ = dict(dict_)
-
- column_copies = {}
- potential_columns = {}
-
- mapper_args = {}
- table_args = inherited_table_args = None
- tablename = None
- parent_columns = ()
-
- declarative_props = (declared_attr, util.classproperty)
-
- for base in cls.__mro__:
- class_mapped = _is_mapped_class(base)
- if class_mapped:
- parent_columns = base.__table__.c.keys()
-
- for name,obj in vars(base).items():
- if name == '__mapper_args__':
- if not mapper_args and (
- not class_mapped or
- isinstance(obj, declarative_props)
- ):
- mapper_args = cls.__mapper_args__
- elif name == '__tablename__':
- if not tablename and (
- not class_mapped or
- isinstance(obj, declarative_props)
- ):
- tablename = cls.__tablename__
- elif name == '__table_args__':
- if not table_args and (
- not class_mapped or
- isinstance(obj, declarative_props)
- ):
- table_args = cls.__table_args__
- if not isinstance(table_args, (tuple, dict, type(None))):
- raise exc.ArgumentError(
- "__table_args__ value must be a tuple, "
- "dict, or None")
- if base is not cls:
- inherited_table_args = True
- elif class_mapped:
- continue
- elif base is not cls:
- # we're a mixin.
-
- if isinstance(obj, Column):
- if obj.foreign_keys:
- raise exc.InvalidRequestError(
- "Columns with foreign keys to other columns "
- "must be declared as @declared_attr callables "
- "on declarative mixin classes. ")
- if name not in dict_ and not (
- '__table__' in dict_ and
- (obj.name or name) in dict_['__table__'].c
- ) and name not in potential_columns:
- potential_columns[name] = \
- column_copies[obj] = \
- obj.copy()
- column_copies[obj]._creation_order = \
- obj._creation_order
- elif isinstance(obj, MapperProperty):
- raise exc.InvalidRequestError(
- "Mapper properties (i.e. deferred,"
- "column_property(), relationship(), etc.) must "
- "be declared as @declared_attr callables "
- "on declarative mixin classes.")
- elif isinstance(obj, declarative_props):
- dict_[name] = ret = \
- column_copies[obj] = getattr(cls, name)
- if isinstance(ret, (Column, MapperProperty)) and \
- ret.doc is None:
- ret.doc = obj.__doc__
-
- # apply inherited columns as we should
- for k, v in potential_columns.items():
- if tablename or (v.name or k) not in parent_columns:
- dict_[k] = v
-
- if inherited_table_args and not tablename:
- table_args = None
-
- # make sure that column copies are used rather
- # than the original columns from any mixins
- for k in ('version_id_col', 'polymorphic_on',):
- if k in mapper_args:
- v = mapper_args[k]
- mapper_args[k] = column_copies.get(v,v)
-
- if classname in cls._decl_class_registry:
- util.warn("The classname %r is already in the registry of this"
- " declarative base, mapped to %r" % (
- classname,
- cls._decl_class_registry[classname]
- ))
- cls._decl_class_registry[classname] = cls
- our_stuff = util.OrderedDict()
-
- for k in dict_:
- value = dict_[k]
- if isinstance(value, declarative_props):
- value = getattr(cls, k)
-
- if (isinstance(value, tuple) and len(value) == 1 and
- isinstance(value[0], (Column, MapperProperty))):
- util.warn("Ignoring declarative-like tuple value of attribute "
- "%s: possibly a copy-and-paste error with a comma "
- "left at the end of the line?" % k)
- continue
- if not isinstance(value, (Column, MapperProperty)):
- continue
- if k == 'metadata':
- raise exc.InvalidRequestError(
- "Attribute name 'metadata' is reserved "
- "for the MetaData instance when using a "
- "declarative base class."
- )
- prop = _deferred_relationship(cls, value)
- our_stuff[k] = prop
-
- # set up attributes in the order they were created
- our_stuff.sort(key=lambda key: our_stuff[key]._creation_order)
-
- # extract columns from the class dict
- cols = set()
- for key, c in our_stuff.iteritems():
- if isinstance(c, (ColumnProperty, CompositeProperty)):
- for col in c.columns:
- if isinstance(col, Column) and \
- col.table is None:
- _undefer_column_name(key, col)
- cols.add(col)
- elif isinstance(c, Column):
- _undefer_column_name(key, c)
- cols.add(c)
- # if the column is the same name as the key,
- # remove it from the explicit properties dict.
- # the normal rules for assigning column-based properties
- # will take over, including precedence of columns
- # in multi-column ColumnProperties.
- if key == c.key:
- del our_stuff[key]
- cols = sorted(cols, key=lambda c:c._creation_order)
-
- table = None
- if '__table__' not in dict_:
- if tablename is not None:
-
- if isinstance(table_args, dict):
- args, table_kw = (), table_args
- elif isinstance(table_args, tuple):
- if isinstance(table_args[-1], dict):
- args, table_kw = table_args[0:-1], table_args[-1]
- else:
- args, table_kw = table_args, {}
- else:
- args, table_kw = (), {}
-
- autoload = dict_.get('__autoload__')
- if autoload:
- table_kw['autoload'] = True
-
- cls.__table__ = table = Table(tablename, cls.metadata,
- *(tuple(cols) + tuple(args)),
- **table_kw)
- else:
- table = cls.__table__
- if cols:
- for c in cols:
- if not table.c.contains_column(c):
- raise exc.ArgumentError(
- "Can't add additional column %r when "
- "specifying __table__" % c.key
- )
-
- if 'inherits' not in mapper_args:
- for c in cls.__bases__:
- if _is_mapped_class(c):
- mapper_args['inherits'] = cls._decl_class_registry.get(
- c.__name__, None)
- break
-
- if hasattr(cls, '__mapper_cls__'):
- mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
- else:
- mapper_cls = mapper
-
- if table is None and 'inherits' not in mapper_args:
- raise exc.InvalidRequestError(
- "Class %r does not have a __table__ or __tablename__ "
- "specified and does not inherit from an existing "
- "table-mapped class." % cls
- )
-
- elif 'inherits' in mapper_args and not mapper_args.get('concrete', False):
- inherited_mapper = class_mapper(mapper_args['inherits'],
- compile=False)
- inherited_table = inherited_mapper.local_table
-
- if table is None:
- # single table inheritance.
- # ensure no table args
- if table_args:
- raise exc.ArgumentError(
- "Can't place __table_args__ on an inherited class "
- "with no table."
- )
-
- # add any columns declared here to the inherited table.
- for c in cols:
- if c.primary_key:
- raise exc.ArgumentError(
- "Can't place primary key columns on an inherited "
- "class with no table."
- )
- if c.name in inherited_table.c:
- raise exc.ArgumentError(
- "Column '%s' on class %s conflicts with "
- "existing column '%s'" %
- (c, cls, inherited_table.c[c.name])
- )
- inherited_table.append_column(c)
-
- # single or joined inheritance
- # exclude any cols on the inherited table which are not mapped on the
- # parent class, to avoid
- # mapping columns specific to sibling/nephew classes
- inherited_mapper = class_mapper(mapper_args['inherits'],
- compile=False)
- inherited_table = inherited_mapper.local_table
-
- if 'exclude_properties' not in mapper_args:
- mapper_args['exclude_properties'] = exclude_properties = \
- set([c.key for c in inherited_table.c
- if c not in inherited_mapper._columntoproperty])
- exclude_properties.difference_update([c.key for c in cols])
-
- # look through columns in the current mapper that
- # are keyed to a propname different than the colname
- # (if names were the same, we'd have popped it out above,
- # in which case the mapper makes this combination).
- # See if the superclass has a similar column property.
- # If so, join them together.
- for k, col in our_stuff.items():
- if not isinstance(col, expression.ColumnElement):
- continue
- if k in inherited_mapper._props:
- p = inherited_mapper._props[k]
- if isinstance(p, ColumnProperty):
- # note here we place the superclass column
- # first. this corresponds to the
- # append() in mapper._configure_property().
- # change this ordering when we do [ticket:1892]
- our_stuff[k] = p.columns + [col]
-
-
- cls.__mapper__ = mapper_cls(cls,
- table,
- properties=our_stuff,
- **mapper_args)
-
-class DeclarativeMeta(type):
- def __init__(cls, classname, bases, dict_):
- if '_decl_class_registry' in cls.__dict__:
- return type.__init__(cls, classname, bases, dict_)
-
- _as_declarative(cls, classname, cls.__dict__)
- return type.__init__(cls, classname, bases, dict_)
-
- def __setattr__(cls, key, value):
- if '__mapper__' in cls.__dict__:
- if isinstance(value, Column):
- _undefer_column_name(key, value)
- cls.__table__.append_column(value)
- cls.__mapper__.add_property(key, value)
- elif isinstance(value, ColumnProperty):
- for col in value.columns:
- if isinstance(col, Column) and col.table is None:
- _undefer_column_name(key, col)
- cls.__table__.append_column(col)
- cls.__mapper__.add_property(key, value)
- elif isinstance(value, MapperProperty):
- cls.__mapper__.add_property(
- key,
- _deferred_relationship(cls, value)
- )
- else:
- type.__setattr__(cls, key, value)
- else:
- type.__setattr__(cls, key, value)
-
-
-class _GetColumns(object):
- def __init__(self, cls):
- self.cls = cls
-
- def __getattr__(self, key):
- mapper = class_mapper(self.cls, compile=False)
- if mapper:
- if not mapper.has_property(key):
- raise exc.InvalidRequestError(
- "Class %r does not have a mapped column named %r"
- % (self.cls, key))
-
- prop = mapper.get_property(key)
- if not isinstance(prop, ColumnProperty):
- raise exc.InvalidRequestError(
- "Property %r is not an instance of"
- " ColumnProperty (i.e. does not correspond"
- " directly to a Column)." % key)
- return getattr(self.cls, key)
-
-class _GetTable(object):
- def __init__(self, key, metadata):
- self.key = key
- self.metadata = metadata
-
- def __getattr__(self, key):
- return self.metadata.tables[
- _get_table_key(key, self.key)
- ]
-
-def _deferred_relationship(cls, prop):
- def resolve_arg(arg):
- import sqlalchemy
-
- def access_cls(key):
- if key in cls._decl_class_registry:
- return _GetColumns(cls._decl_class_registry[key])
- elif key in cls.metadata.tables:
- return cls.metadata.tables[key]
- elif key in cls.metadata._schemas:
- return _GetTable(key, cls.metadata)
- else:
- return sqlalchemy.__dict__[key]
-
- d = util.PopulateDict(access_cls)
- def return_cls():
- try:
- x = eval(arg, globals(), d)
-
- if isinstance(x, _GetColumns):
- return x.cls
- else:
- return x
- except NameError, n:
- raise exc.InvalidRequestError(
- "When initializing mapper %s, expression %r failed to "
- "locate a name (%r). If this is a class name, consider "
- "adding this relationship() to the %r class after "
- "both dependent classes have been defined." %
- (prop.parent, arg, n.args[0], cls)
- )
- return return_cls
-
- if isinstance(prop, RelationshipProperty):
- for attr in ('argument', 'order_by', 'primaryjoin', 'secondaryjoin',
- 'secondary', '_user_defined_foreign_keys', 'remote_side'):
- v = getattr(prop, attr)
- if isinstance(v, basestring):
- setattr(prop, attr, resolve_arg(v))
-
- if prop.backref and isinstance(prop.backref, tuple):
- key, kwargs = prop.backref
- for attr in ('primaryjoin', 'secondaryjoin', 'secondary',
- 'foreign_keys', 'remote_side', 'order_by'):
- if attr in kwargs and isinstance(kwargs[attr], basestring):
- kwargs[attr] = resolve_arg(kwargs[attr])
-
-
- return prop
-
-def synonym_for(name, map_column=False):
- """Decorator, make a Python @property a query synonym for a column.
-
- A decorator version of :func:`~sqlalchemy.orm.synonym`. The function being
- decorated is the 'descriptor', otherwise passes its arguments through to
- synonym()::
-
- @synonym_for('col')
- @property
- def prop(self):
- return 'special sauce'
-
- The regular ``synonym()`` is also usable directly in a declarative setting
- and may be convenient for read/write properties::
-
- prop = synonym('col', descriptor=property(_read_prop, _write_prop))
-
- """
- def decorate(fn):
- return _orm_synonym(name, map_column=map_column, descriptor=fn)
- return decorate
-
-def comparable_using(comparator_factory):
- """Decorator, allow a Python @property to be used in query criteria.
-
- This is a decorator front end to
- :func:`~sqlalchemy.orm.comparable_property` that passes
- through the comparator_factory and the function being decorated::
-
- @comparable_using(MyComparatorType)
- @property
- def prop(self):
- return 'special sauce'
-
- The regular ``comparable_property()`` is also usable directly in a
- declarative setting and may be convenient for read/write properties::
-
- prop = comparable_property(MyComparatorType)
-
- """
- def decorate(fn):
- return comparable_property(comparator_factory, fn)
- return decorate
-
-class declared_attr(property):
- """Mark a class-level method as representing the definition of
- a mapped property or special declarative member name.
-
- .. note:: @declared_attr is available as
- ``sqlalchemy.util.classproperty`` for SQLAlchemy versions
- 0.6.2, 0.6.3, 0.6.4.
-
- @declared_attr turns the attribute into a scalar-like
- property that can be invoked from the uninstantiated class.
- Declarative treats attributes specifically marked with
- @declared_attr as returning a construct that is specific
- to mapping or declarative table configuration. The name
- of the attribute is that of what the non-dynamic version
- of the attribute would be.
-
- @declared_attr is more often than not applicable to mixins,
- to define relationships that are to be applied to different
- implementors of the class::
-
- class ProvidesUser(object):
- "A mixin that adds a 'user' relationship to classes."
-
- @declared_attr
- def user(self):
- return relationship("User")
-
- It also can be applied to mapped classes, such as to provide
- a "polymorphic" scheme for inheritance::
-
- class Employee(Base):
- id = Column(Integer, primary_key=True)
- type = Column(String(50), nullable=False)
-
- @declared_attr
- def __tablename__(cls):
- return cls.__name__.lower()
-
- @declared_attr
- def __mapper_args__(cls):
- if cls.__name__ == 'Employee':
- return {
- "polymorphic_on":cls.type,
- "polymorphic_identity":"Employee"
- }
- else:
- return {"polymorphic_identity":cls.__name__}
-
- """
-
- def __init__(self, fget, *arg, **kw):
- super(declared_attr, self).__init__(fget, *arg, **kw)
- self.__doc__ = fget.__doc__
-
- def __get__(desc, self, cls):
- return desc.fget(cls)
-
-def _declarative_constructor(self, **kwargs):
- """A simple constructor that allows initialization from kwargs.
-
- Sets attributes on the constructed instance using the names and
- values in ``kwargs``.
-
- Only keys that are present as
- attributes of the instance's class are allowed. These could be,
- for example, any mapped columns or relationships.
- """
- cls_ = type(self)
- for k in kwargs:
- if not hasattr(cls_, k):
- raise TypeError(
- "%r is an invalid keyword argument for %s" %
- (k, cls_.__name__))
- setattr(self, k, kwargs[k])
-_declarative_constructor.__name__ = '__init__'
-
-def declarative_base(bind=None, metadata=None, mapper=None, cls=object,
- name='Base', constructor=_declarative_constructor,
- metaclass=DeclarativeMeta):
- """Construct a base class for declarative class definitions.
-
- The new base class will be given a metaclass that produces
- appropriate :class:`~sqlalchemy.schema.Table` objects and makes
- the appropriate :func:`~sqlalchemy.orm.mapper` calls based on the
- information provided declaratively in the class and any subclasses
- of the class.
-
- :param bind: An optional
- :class:`~sqlalchemy.engine.base.Connectable`, will be assigned
- the ``bind`` attribute on the :class:`~sqlalchemy.MetaData`
- instance.
-
- :param metadata:
- An optional :class:`~sqlalchemy.MetaData` instance. All
- :class:`~sqlalchemy.schema.Table` objects implicitly declared by
- subclasses of the base will share this MetaData. A MetaData instance
- will be created if none is provided. The
- :class:`~sqlalchemy.MetaData` instance will be available via the
- `metadata` attribute of the generated declarative base class.
-
- :param mapper:
- An optional callable, defaults to :func:`~sqlalchemy.orm.mapper`. Will
- be used to map subclasses to their Tables.
-
- :param cls:
- Defaults to :class:`object`. A type to use as the base for the generated
- declarative base class. May be a class or tuple of classes.
-
- :param name:
- Defaults to ``Base``. The display name for the generated
- class. Customizing this is not required, but can improve clarity in
- tracebacks and debugging.
-
- :param constructor:
- Defaults to
- :func:`~sqlalchemy.ext.declarative._declarative_constructor`, an
- __init__ implementation that assigns \**kwargs for declared
- fields and relationships to an instance. If ``None`` is supplied,
- no __init__ will be provided and construction will fall back to
- cls.__init__ by way of the normal Python semantics.
-
- :param metaclass:
- Defaults to :class:`.DeclarativeMeta`. A metaclass or __metaclass__
- compatible callable to use as the meta type of the generated
- declarative base class.
-
- """
- lcl_metadata = metadata or MetaData()
- if bind:
- lcl_metadata.bind = bind
-
- bases = not isinstance(cls, tuple) and (cls,) or cls
- class_dict = dict(_decl_class_registry=dict(),
- metadata=lcl_metadata)
-
- if constructor:
- class_dict['__init__'] = constructor
- if mapper:
- class_dict['__mapper_cls__'] = mapper
-
- return metaclass(name, bases, class_dict)
-
-def _undefer_column_name(key, column):
- if column.key is None:
- column.key = key
- if column.name is None:
- column.name = key
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/horizontal_shard.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/horizontal_shard.py
deleted file mode 100755
index 6aafb227..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/horizontal_shard.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# ext/horizontal_shard.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Horizontal sharding support.
-
-Defines a rudimental 'horizontal sharding' system which allows a Session to
-distribute queries and persistence operations across multiple databases.
-
-For a usage example, see the :ref:`examples_sharding` example included in
-the source distrbution.
-
-"""
-
-from sqlalchemy import exc as sa_exc
-from sqlalchemy import util
-from sqlalchemy.orm.session import Session
-from sqlalchemy.orm.query import Query
-
-__all__ = ['ShardedSession', 'ShardedQuery']
-
-class ShardedQuery(Query):
- def __init__(self, *args, **kwargs):
- super(ShardedQuery, self).__init__(*args, **kwargs)
- self.id_chooser = self.session.id_chooser
- self.query_chooser = self.session.query_chooser
- self._shard_id = None
-
- def set_shard(self, shard_id):
- """return a new query, limited to a single shard ID.
-
- all subsequent operations with the returned query will
- be against the single shard regardless of other state.
- """
-
- q = self._clone()
- q._shard_id = shard_id
- return q
-
- def _execute_and_instances(self, context):
- def iter_for_shard(shard_id):
- context.attributes['shard_id'] = shard_id
- result = self._connection_from_session(
- mapper=self._mapper_zero(),
- shard_id=shard_id).execute(
- context.statement,
- self._params)
- return self.instances(result, context)
-
- if self._shard_id is not None:
- return iter_for_shard(self._shard_id)
- else:
- partial = []
- for shard_id in self.query_chooser(self):
- partial.extend(iter_for_shard(shard_id))
-
- # if some kind of in memory 'sorting'
- # were done, this is where it would happen
- return iter(partial)
-
- def get(self, ident, **kwargs):
- if self._shard_id is not None:
- return super(ShardedQuery, self).get(ident)
- else:
- ident = util.to_list(ident)
- for shard_id in self.id_chooser(self, ident):
- o = self.set_shard(shard_id).get(ident, **kwargs)
- if o is not None:
- return o
- else:
- return None
-
-class ShardedSession(Session):
- def __init__(self, shard_chooser, id_chooser, query_chooser, shards=None,
- query_cls=ShardedQuery, **kwargs):
- """Construct a ShardedSession.
-
- :param shard_chooser: A callable which, passed a Mapper, a mapped instance, and possibly a
- SQL clause, returns a shard ID. This id may be based off of the
- attributes present within the object, or on some round-robin
- scheme. If the scheme is based on a selection, it should set
- whatever state on the instance to mark it in the future as
- participating in that shard.
-
- :param id_chooser: A callable, passed a query and a tuple of identity values, which
- should return a list of shard ids where the ID might reside. The
- databases will be queried in the order of this listing.
-
- :param query_chooser: For a given Query, returns the list of shard_ids where the query
- should be issued. Results from all shards returned will be combined
- together into a single listing.
-
- :param shards: A dictionary of string shard names to :class:`~sqlalchemy.engine.base.Engine`
- objects.
-
- """
- super(ShardedSession, self).__init__(query_cls=query_cls, **kwargs)
- self.shard_chooser = shard_chooser
- self.id_chooser = id_chooser
- self.query_chooser = query_chooser
- self.__binds = {}
- self.connection_callable = self.connection
- if shards is not None:
- for k in shards:
- self.bind_shard(k, shards[k])
-
- def connection(self, mapper=None, instance=None, shard_id=None, **kwargs):
- if shard_id is None:
- shard_id = self.shard_chooser(mapper, instance)
-
- if self.transaction is not None:
- return self.transaction.connection(mapper, shard_id=shard_id)
- else:
- return self.get_bind(mapper,
- shard_id=shard_id,
- instance=instance).contextual_connect(**kwargs)
-
- def get_bind(self, mapper, shard_id=None, instance=None, clause=None, **kw):
- if shard_id is None:
- shard_id = self.shard_chooser(mapper, instance, clause=clause)
- return self.__binds[shard_id]
-
- def bind_shard(self, shard_id, bind):
- self.__binds[shard_id] = bind
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/hybrid.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/hybrid.py
deleted file mode 100755
index c16c38b2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/hybrid.py
+++ /dev/null
@@ -1,425 +0,0 @@
-# ext/hybrid.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Define attributes on ORM-mapped classes that have "hybrid" behavior.
-
-"hybrid" means the attribute has distinct behaviors defined at the
-class level and at the instance level.
-
-The :mod:`~sqlalchemy.ext.hybrid` extension provides a special form of method
-decorator, is around 50 lines of code and has almost no dependencies on the rest
-of SQLAlchemy. It can in theory work with any class-level expression generator.
-
-Consider a table ``interval`` as below::
-
- from sqlalchemy import MetaData, Table, Column, Integer
-
- metadata = MetaData()
-
- interval_table = Table('interval', metadata,
- Column('id', Integer, primary_key=True),
- Column('start', Integer, nullable=False),
- Column('end', Integer, nullable=False)
- )
-
-We can define higher level functions on mapped classes that produce SQL
-expressions at the class level, and Python expression evaluation at the
-instance level. Below, each function decorated with :func:`.hybrid_method`
-or :func:`.hybrid_property` may receive ``self`` as an instance of the class,
-or as the class itself::
-
- from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
- from sqlalchemy.orm import mapper, Session, aliased
-
- class Interval(object):
- def __init__(self, start, end):
- self.start = start
- self.end = end
-
- @hybrid_property
- def length(self):
- return self.end - self.start
-
- @hybrid_method
- def contains(self,point):
- return (self.start <= point) & (point < self.end)
-
- @hybrid_method
- def intersects(self, other):
- return self.contains(other.start) | self.contains(other.end)
-
- mapper(Interval, interval_table)
-
-Above, the ``length`` property returns the difference between the ``end`` and
-``start`` attributes. With an instance of ``Interval``, this subtraction occurs
-in Python, using normal Python descriptor mechanics::
-
- >>> i1 = Interval(5, 10)
- >>> i1.length
- 5
-
-At the class level, the usual descriptor behavior of returning the descriptor
-itself is modified by :class:`.hybrid_property`, to instead evaluate the function
-body given the ``Interval`` class as the argument::
-
- >>> print Interval.length
- interval."end" - interval.start
-
- >>> print Session().query(Interval).filter(Interval.length > 10)
- SELECT interval.id AS interval_id, interval.start AS interval_start,
- interval."end" AS interval_end
- FROM interval
- WHERE interval."end" - interval.start > :param_1
-
-ORM methods such as :meth:`~.Query.filter_by` generally use ``getattr()`` to
-locate attributes, so can also be used with hybrid attributes::
-
- >>> print Session().query(Interval).filter_by(length=5)
- SELECT interval.id AS interval_id, interval.start AS interval_start,
- interval."end" AS interval_end
- FROM interval
- WHERE interval."end" - interval.start = :param_1
-
-The ``contains()`` and ``intersects()`` methods are decorated with :class:`.hybrid_method`.
-This decorator applies the same idea to methods which accept
-zero or more arguments. The above methods return boolean values, and take advantage
-of the Python ``|`` and ``&`` bitwise operators to produce equivalent instance-level and
-SQL expression-level boolean behavior::
-
- >>> i1.contains(6)
- True
- >>> i1.contains(15)
- False
- >>> i1.intersects(Interval(7, 18))
- True
- >>> i1.intersects(Interval(25, 29))
- False
-
- >>> print Session().query(Interval).filter(Interval.contains(15))
- SELECT interval.id AS interval_id, interval.start AS interval_start,
- interval."end" AS interval_end
- FROM interval
- WHERE interval.start <= :start_1 AND interval."end" > :end_1
-
- >>> ia = aliased(Interval)
- >>> print Session().query(Interval, ia).filter(Interval.intersects(ia))
- SELECT interval.id AS interval_id, interval.start AS interval_start,
- interval."end" AS interval_end, interval_1.id AS interval_1_id,
- interval_1.start AS interval_1_start, interval_1."end" AS interval_1_end
- FROM interval, interval AS interval_1
- WHERE interval.start <= interval_1.start
- AND interval."end" > interval_1.start
- OR interval.start <= interval_1."end"
- AND interval."end" > interval_1."end"
-
-Defining Expression Behavior Distinct from Attribute Behavior
---------------------------------------------------------------
-
-Our usage of the ``&`` and ``|`` bitwise operators above was fortunate, considering
-our functions operated on two boolean values to return a new one. In many cases, the construction
-of an in-Python function and a SQLAlchemy SQL expression have enough differences that two
-separate Python expressions should be defined. The :mod:`~sqlalchemy.ext.hybrid` decorators
-define the :meth:`.hybrid_property.expression` modifier for this purpose. As an example we'll
-define the radius of the interval, which requires the usage of the absolute value function::
-
- from sqlalchemy import func
-
- class Interval(object):
- # ...
-
- @hybrid_property
- def radius(self):
- return abs(self.length) / 2
-
- @radius.expression
- def radius(cls):
- return func.abs(cls.length) / 2
-
-Above the Python function ``abs()`` is used for instance-level operations, the SQL function
-``ABS()`` is used via the :attr:`.func` object for class-level expressions::
-
- >>> i1.radius
- 2
-
- >>> print Session().query(Interval).filter(Interval.radius > 5)
- SELECT interval.id AS interval_id, interval.start AS interval_start,
- interval."end" AS interval_end
- FROM interval
- WHERE abs(interval."end" - interval.start) / :abs_1 > :param_1
-
-Defining Setters
-----------------
-
-Hybrid properties can also define setter methods. If we wanted ``length`` above, when
-set, to modify the endpoint value::
-
- class Interval(object):
- # ...
-
- @hybrid_property
- def length(self):
- return self.end - self.start
-
- @length.setter
- def length(self, value):
- self.end = self.start + value
-
-The ``length(self, value)`` method is now called upon set::
-
- >>> i1 = Interval(5, 10)
- >>> i1.length
- 5
- >>> i1.length = 12
- >>> i1.end
- 17
-
-Working with Relationships
---------------------------
-
-There's no essential difference when creating hybrids that work with related objects as
-opposed to column-based data. The need for distinct expressions tends to be greater.
-Consider the following declarative mapping which relates a ``User`` to a ``SavingsAccount``::
-
- from sqlalchemy import Column, Integer, ForeignKey, Numeric, String
- from sqlalchemy.orm import relationship
- from sqlalchemy.ext.declarative import declarative_base
- from sqlalchemy.ext.hybrid import hybrid_property
-
- Base = declarative_base()
-
- class SavingsAccount(Base):
- __tablename__ = 'account'
- id = Column(Integer, primary_key=True)
- user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
- balance = Column(Numeric(15, 5))
-
- class User(Base):
- __tablename__ = 'user'
- id = Column(Integer, primary_key=True)
- name = Column(String(100), nullable=False)
-
- accounts = relationship("SavingsAccount", backref="owner")
-
- @hybrid_property
- def balance(self):
- if self.accounts:
- return self.accounts[0].balance
- else:
- return None
-
- @balance.setter
- def balance(self, value):
- if not self.accounts:
- account = Account(owner=self)
- else:
- account = self.accounts[0]
- account.balance = balance
-
- @balance.expression
- def balance(cls):
- return SavingsAccount.balance
-
-The above hybrid property ``balance`` works with the first ``SavingsAccount`` entry in the list of
-accounts for this user. The in-Python getter/setter methods can treat ``accounts`` as a Python
-list available on ``self``.
-
-However, at the expression level, we can't travel along relationships to column attributes
-directly since SQLAlchemy is explicit about joins. So here, it's expected that the ``User`` class will be
-used in an appropriate context such that an appropriate join to ``SavingsAccount`` will be present::
-
- >>> print Session().query(User, User.balance).join(User.accounts).filter(User.balance > 5000)
- SELECT "user".id AS user_id, "user".name AS user_name, account.balance AS account_balance
- FROM "user" JOIN account ON "user".id = account.user_id
- WHERE account.balance > :balance_1
-
-Note however, that while the instance level accessors need to worry about whether ``self.accounts``
-is even present, this issue expresses itself differently at the SQL expression level, where we basically
-would use an outer join::
-
- >>> from sqlalchemy import or_
- >>> print (Session().query(User, User.balance).outerjoin(User.accounts).
- ... filter(or_(User.balance < 5000, User.balance == None)))
- SELECT "user".id AS user_id, "user".name AS user_name, account.balance AS account_balance
- FROM "user" LEFT OUTER JOIN account ON "user".id = account.user_id
- WHERE account.balance < :balance_1 OR account.balance IS NULL
-
-.. _hybrid_custom_comparators:
-
-Building Custom Comparators
----------------------------
-
-The hybrid property also includes a helper that allows construction of custom comparators.
-A comparator object allows one to customize the behavior of each SQLAlchemy expression
-operator individually. They are useful when creating custom types that have
-some highly idiosyncratic behavior on the SQL side.
-
-The example class below allows case-insensitive comparisons on the attribute
-named ``word_insensitive``::
-
- from sqlalchemy.ext.hybrid import Comparator
-
- class CaseInsensitiveComparator(Comparator):
- def __eq__(self, other):
- return func.lower(self.__clause_element__()) == func.lower(other)
-
- class SearchWord(Base):
- __tablename__ = 'searchword'
- id = Column(Integer, primary_key=True)
- word = Column(String(255), nullable=False)
-
- @hybrid_property
- def word_insensitive(self):
- return self.word.lower()
-
- @word_insensitive.comparator
- def word_insensitive(cls):
- return CaseInsensitiveComparator(cls.word)
-
-Above, SQL expressions against ``word_insensitive`` will apply the ``LOWER()``
-SQL function to both sides::
-
- >>> print Session().query(SearchWord).filter_by(word_insensitive="Trucks")
- SELECT searchword.id AS searchword_id, searchword.word AS searchword_word
- FROM searchword
- WHERE lower(searchword.word) = lower(:lower_1)
-
-"""
-from sqlalchemy import util
-from sqlalchemy.orm import attributes, interfaces
-
-class hybrid_method(object):
- """A decorator which allows definition of a Python object method with both
- instance-level and class-level behavior.
-
- """
-
-
- def __init__(self, func, expr=None):
- """Create a new :class:`.hybrid_method`.
-
- Usage is typically via decorator::
-
- from sqlalchemy.ext.hybrid import hybrid_method
-
- class SomeClass(object):
- @hybrid_method
- def value(self, x, y):
- return self._value + x + y
-
- @value.expression
- def value(self, x, y):
- return func.some_function(self._value, x, y)
-
- """
- self.func = func
- self.expr = expr or func
-
- def __get__(self, instance, owner):
- if instance is None:
- return self.expr.__get__(owner, owner.__class__)
- else:
- return self.func.__get__(instance, owner)
-
- def expression(self, expr):
- """Provide a modifying decorator that defines a SQL-expression producing method."""
-
- self.expr = expr
- return self
-
-class hybrid_property(object):
- """A decorator which allows definition of a Python descriptor with both
- instance-level and class-level behavior.
-
- """
-
- def __init__(self, fget, fset=None, fdel=None, expr=None):
- """Create a new :class:`.hybrid_property`.
-
- Usage is typically via decorator::
-
- from sqlalchemy.ext.hybrid import hybrid_property
-
- class SomeClass(object):
- @hybrid_property
- def value(self):
- return self._value
-
- @value.setter
- def value(self, value):
- self._value = value
-
- """
- self.fget = fget
- self.fset = fset
- self.fdel = fdel
- self.expr = expr or fget
- util.update_wrapper(self, fget)
-
- def __get__(self, instance, owner):
- if instance is None:
- return self.expr(owner)
- else:
- return self.fget(instance)
-
- def __set__(self, instance, value):
- self.fset(instance, value)
-
- def __delete__(self, instance):
- self.fdel(instance)
-
- def setter(self, fset):
- """Provide a modifying decorator that defines a value-setter method."""
-
- self.fset = fset
- return self
-
- def deleter(self, fdel):
- """Provide a modifying decorator that defines a value-deletion method."""
-
- self.fdel = fdel
- return self
-
- def expression(self, expr):
- """Provide a modifying decorator that defines a SQL-expression producing method."""
-
- self.expr = expr
- return self
-
- def comparator(self, comparator):
- """Provide a modifying decorator that defines a custom comparator producing method.
-
- The return value of the decorated method should be an instance of
- :class:`~.hybrid.Comparator`.
-
- """
-
- proxy_attr = attributes.\
- create_proxied_attribute(self)
- def expr(owner):
- return proxy_attr(owner, self.__name__, self, comparator(owner))
- self.expr = expr
- return self
-
-
-class Comparator(interfaces.PropComparator):
- """A helper class that allows easy construction of custom :class:`~.orm.interfaces.PropComparator`
- classes for usage with hybrids."""
-
-
- def __init__(self, expression):
- self.expression = expression
-
- def __clause_element__(self):
- expr = self.expression
- while hasattr(expr, '__clause_element__'):
- expr = expr.__clause_element__()
- return expr
-
- def adapted(self, adapter):
- # interesting....
- return self
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/mutable.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/mutable.py
deleted file mode 100755
index 078f9f3a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/mutable.py
+++ /dev/null
@@ -1,554 +0,0 @@
-# ext/mutable.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Provide support for tracking of in-place changes to scalar values,
-which are propagated into ORM change events on owning parent objects.
-
-The :mod:`sqlalchemy.ext.mutable` extension replaces SQLAlchemy's legacy approach to in-place
-mutations of scalar values, established by the :class:`.types.MutableType`
-class as well as the ``mutable=True`` type flag, with a system that allows
-change events to be propagated from the value to the owning parent, thereby
-removing the need for the ORM to maintain copies of values as well as the very
-expensive requirement of scanning through all "mutable" values on each flush
-call, looking for changes.
-
-.. _mutable_scalars:
-
-Establishing Mutability on Scalar Column Values
-===============================================
-
-A typical example of a "mutable" structure is a Python dictionary.
-Following the example introduced in :ref:`types_toplevel`, we
-begin with a custom type that marshals Python dictionaries into
-JSON strings before being persisted::
-
- from sqlalchemy.types import TypeDecorator, VARCHAR
- import json
-
- class JSONEncodedDict(TypeDecorator):
- "Represents an immutable structure as a json-encoded string."
-
- impl = VARCHAR
-
- def process_bind_param(self, value, dialect):
- if value is not None:
- value = json.dumps(value)
- return value
-
- def process_result_value(self, value, dialect):
- if value is not None:
- value = json.loads(value)
- return value
-
-The usage of ``json`` is only for the purposes of example. The :mod:`sqlalchemy.ext.mutable`
-extension can be used
-with any type whose target Python type may be mutable, including
-:class:`.PickleType`, :class:`.postgresql.ARRAY`, etc.
-
-When using the :mod:`sqlalchemy.ext.mutable` extension, the value itself
-tracks all parents which reference it. Here we will replace the usage
-of plain Python dictionaries with a dict subclass that implements
-the :class:`.Mutable` mixin::
-
- import collections
- from sqlalchemy.ext.mutable import Mutable
-
- class MutationDict(Mutable, dict):
- @classmethod
- def coerce(cls, key, value):
- "Convert plain dictionaries to MutationDict."
-
- if not isinstance(value, MutationDict):
- if isinstance(value, dict):
- return MutationDict(value)
-
- # this call will raise ValueError
- return Mutable.coerce(key, value)
- else:
- return value
-
- def __setitem__(self, key, value):
- "Detect dictionary set events and emit change events."
-
- dict.__setitem__(self, key, value)
- self.changed()
-
- def __delitem__(self, key):
- "Detect dictionary del events and emit change events."
-
- dict.__delitem__(self, key)
- self.changed()
-
-The above dictionary class takes the approach of subclassing the Python
-built-in ``dict`` to produce a dict
-subclass which routes all mutation events through ``__setitem__``. There are
-many variants on this approach, such as subclassing ``UserDict.UserDict``,
-the newer ``collections.MutableMapping``, etc. The part that's important to this
-example is that the :meth:`.Mutable.changed` method is called whenever an in-place change to the
-datastructure takes place.
-
-We also redefine the :meth:`.Mutable.coerce` method which will be used to
-convert any values that are not instances of ``MutationDict``, such
-as the plain dictionaries returned by the ``json`` module, into the
-appropriate type. Defining this method is optional; we could just as well created our
-``JSONEncodedDict`` such that it always returns an instance of ``MutationDict``,
-and additionally ensured that all calling code uses ``MutationDict``
-explicitly. When :meth:`.Mutable.coerce` is not overridden, any values
-applied to a parent object which are not instances of the mutable type
-will raise a ``ValueError``.
-
-Our new ``MutationDict`` type offers a class method
-:meth:`~.Mutable.as_mutable` which we can use within column metadata
-to associate with types. This method grabs the given type object or
-class and associates a listener that will detect all future mappings
-of this type, applying event listening instrumentation to the mapped
-attribute. Such as, with classical table metadata::
-
- from sqlalchemy import Table, Column, Integer
-
- my_data = Table('my_data', metadata,
- Column('id', Integer, primary_key=True),
- Column('data', MutationDict.as_mutable(JSONEncodedDict))
- )
-
-Above, :meth:`~.Mutable.as_mutable` returns an instance of ``JSONEncodedDict``
-(if the type object was not an instance already), which will intercept any
-attributes which are mapped against this type. Below we establish a simple
-mapping against the ``my_data`` table::
-
- from sqlalchemy import mapper
-
- class MyDataClass(object):
- pass
-
- # associates mutation listeners with MyDataClass.data
- mapper(MyDataClass, my_data)
-
-The ``MyDataClass.data`` member will now be notified of in place changes
-to its value.
-
-There's no difference in usage when using declarative::
-
- from sqlalchemy.ext.declarative import declarative_base
-
- Base = declarative_base()
-
- class MyDataClass(Base):
- __tablename__ = 'my_data'
- id = Column(Integer, primary_key=True)
- data = Column(MutationDict.as_mutable(JSONEncodedDict))
-
-Any in-place changes to the ``MyDataClass.data`` member
-will flag the attribute as "dirty" on the parent object::
-
- >>> from sqlalchemy.orm import Session
-
- >>> sess = Session()
- >>> m1 = MyDataClass(data={'value1':'foo'})
- >>> sess.add(m1)
- >>> sess.commit()
-
- >>> m1.data['value1'] = 'bar'
- >>> assert m1 in sess.dirty
- True
-
-The ``MutationDict`` can be associated with all future instances
-of ``JSONEncodedDict`` in one step, using :meth:`~.Mutable.associate_with`. This
-is similar to :meth:`~.Mutable.as_mutable` except it will intercept
-all occurrences of ``MutationDict`` in all mappings unconditionally, without
-the need to declare it individually::
-
- MutationDict.associate_with(JSONEncodedDict)
-
- class MyDataClass(Base):
- __tablename__ = 'my_data'
- id = Column(Integer, primary_key=True)
- data = Column(JSONEncodedDict)
-
-
-Supporting Pickling
---------------------
-
-The key to the :mod:`sqlalchemy.ext.mutable` extension relies upon the
-placement of a ``weakref.WeakKeyDictionary`` upon the value object, which
-stores a mapping of parent mapped objects keyed to the attribute name under
-which they are associated with this value. ``WeakKeyDictionary`` objects are
-not picklable, due to the fact that they contain weakrefs and function
-callbacks. In our case, this is a good thing, since if this dictionary were
-picklable, it could lead to an excessively large pickle size for our value
-objects that are pickled by themselves outside of the context of the parent.
-The developer responsiblity here is only to provide a ``__getstate__`` method
-that excludes the :meth:`~.MutableBase._parents` collection from the pickle
-stream::
-
- class MyMutableType(Mutable):
- def __getstate__(self):
- d = self.__dict__.copy()
- d.pop('_parents', None)
- return d
-
-With our dictionary example, we need to return the contents of the dict itself
-(and also restore them on __setstate__)::
-
- class MutationDict(Mutable, dict):
- # ....
-
- def __getstate__(self):
- return dict(self)
-
- def __setstate__(self, state):
- self.update(state)
-
-In the case that our mutable value object is pickled as it is attached to one
-or more parent objects that are also part of the pickle, the :class:`.Mutable`
-mixin will re-establish the :attr:`.Mutable._parents` collection on each value
-object as the owning parents themselves are unpickled.
-
-.. _mutable_composites:
-
-Establishing Mutability on Composites
-=====================================
-
-Composites are a special ORM feature which allow a single scalar attribute to
-be assigned an object value which represents information "composed" from one
-or more columns from the underlying mapped table. The usual example is that of
-a geometric "point", and is introduced in :ref:`mapper_composite`.
-
-As of SQLAlchemy 0.7, the internals of :func:`.orm.composite` have been
-greatly simplified and in-place mutation detection is no longer enabled by
-default; instead, the user-defined value must detect changes on its own and
-propagate them to all owning parents. The :mod:`sqlalchemy.ext.mutable`
-extension provides the helper class :class:`.MutableComposite`, which is a
-slight variant on the :class:`.Mutable` class.
-
-As is the case with :class:`.Mutable`, the user-defined composite class
-subclasses :class:`.MutableComposite` as a mixin, and detects and delivers
-change events to its parents via the :meth:`.MutableComposite.changed` method.
-In the case of a composite class, the detection is usually via the usage of
-Python descriptors (i.e. ``@property``), or alternatively via the special
-Python method ``__setattr__()``. Below we expand upon the ``Point`` class
-introduced in :ref:`mapper_composite` to subclass :class:`.MutableComposite`
-and to also route attribute set events via ``__setattr__`` to the
-:meth:`.MutableComposite.changed` method::
-
- from sqlalchemy.ext.mutable import MutableComposite
-
- class Point(MutableComposite):
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
- def __setattr__(self, key, value):
- "Intercept set events"
-
- # set the attribute
- object.__setattr__(self, key, value)
-
- # alert all parents to the change
- self.changed()
-
- def __composite_values__(self):
- return self.x, self.y
-
- def __eq__(self, other):
- return isinstance(other, Point) and \\
- other.x == self.x and \\
- other.y == self.y
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-The :class:`.MutableComposite` class uses a Python metaclass to automatically
-establish listeners for any usage of :func:`.orm.composite` that specifies our
-``Point`` type. Below, when ``Point`` is mapped to the ``Vertex`` class,
-listeners are established which will route change events from ``Point``
-objects to each of the ``Vertex.start`` and ``Vertex.end`` attributes::
-
- from sqlalchemy.orm import composite, mapper
- from sqlalchemy import Table, Column
-
- vertices = Table('vertices', metadata,
- Column('id', Integer, primary_key=True),
- Column('x1', Integer),
- Column('y1', Integer),
- Column('x2', Integer),
- Column('y2', Integer),
- )
-
- class Vertex(object):
- pass
-
- mapper(Vertex, vertices, properties={
- 'start': composite(Point, vertices.c.x1, vertices.c.y1),
- 'end': composite(Point, vertices.c.x2, vertices.c.y2)
- })
-
-Any in-place changes to the ``Vertex.start`` or ``Vertex.end`` members
-will flag the attribute as "dirty" on the parent object::
-
- >>> from sqlalchemy.orm import Session
-
- >>> sess = Session()
- >>> v1 = Vertex(start=Point(3, 4), end=Point(12, 15))
- >>> sess.add(v1)
- >>> sess.commit()
-
- >>> v1.end.x = 8
- >>> assert v1 in sess.dirty
- True
-
-Supporting Pickling
---------------------
-
-As is the case with :class:`.Mutable`, the :class:`.MutableComposite` helper
-class uses a ``weakref.WeakKeyDictionary`` available via the
-:meth:`.MutableBase._parents` attribute which isn't picklable. If we need to
-pickle instances of ``Point`` or its owning class ``Vertex``, we at least need
-to define a ``__getstate__`` that doesn't include the ``_parents`` dictionary.
-Below we define both a ``__getstate__`` and a ``__setstate__`` that package up
-the minimal form of our ``Point`` class::
-
- class Point(MutableComposite):
- # ...
-
- def __getstate__(self):
- return self.x, self.y
-
- def __setstate__(self, state):
- self.x, self.y = state
-
-As with :class:`.Mutable`, the :class:`.MutableComposite` augments the
-pickling process of the parent's object-relational state so that the
-:meth:`.MutableBase._parents` collection is restored to all ``Point`` objects.
-
-"""
-from sqlalchemy.orm.attributes import flag_modified
-from sqlalchemy import event, types
-from sqlalchemy.orm import mapper, object_mapper
-from sqlalchemy.util import memoized_property
-import weakref
-
-class MutableBase(object):
- """Common base class to :class:`.Mutable` and :class:`.MutableComposite`."""
-
- @memoized_property
- def _parents(self):
- """Dictionary of parent object->attribute name on the parent.
-
- This attribute is a so-called "memoized" property. It initializes
- itself with a new ``weakref.WeakKeyDictionary`` the first time
- it is accessed, returning the same object upon subsequent access.
-
- """
-
- return weakref.WeakKeyDictionary()
-
- @classmethod
- def _listen_on_attribute(cls, attribute, coerce):
- """Establish this type as a mutation listener for the given
- mapped descriptor.
-
- """
- key = attribute.key
- parent_cls = attribute.class_
-
- def load(state, *args):
- """Listen for objects loaded or refreshed.
-
- Wrap the target data member's value with
- ``Mutable``.
-
- """
- val = state.dict.get(key, None)
- if val is not None:
- if coerce:
- val = cls.coerce(key, val)
- state.dict[key] = val
- val._parents[state.obj()] = key
-
- def set(target, value, oldvalue, initiator):
- """Listen for set/replace events on the target
- data member.
-
- Establish a weak reference to the parent object
- on the incoming value, remove it for the one
- outgoing.
-
- """
- if not isinstance(value, cls):
- value = cls.coerce(key, value)
- if value is not None:
- value._parents[target.obj()] = key
- if isinstance(oldvalue, cls):
- oldvalue._parents.pop(target.obj(), None)
- return value
-
- def pickle(state, state_dict):
- val = state.dict.get(key, None)
- if val is not None:
- if 'ext.mutable.values' not in state_dict:
- state_dict['ext.mutable.values'] = []
- state_dict['ext.mutable.values'].append(val)
-
- def unpickle(state, state_dict):
- if 'ext.mutable.values' in state_dict:
- for val in state_dict['ext.mutable.values']:
- val._parents[state.obj()] = key
-
- event.listen(parent_cls, 'load', load, raw=True)
- event.listen(parent_cls, 'refresh', load, raw=True)
- event.listen(attribute, 'set', set, raw=True, retval=True)
- event.listen(parent_cls, 'pickle', pickle, raw=True)
- event.listen(parent_cls, 'unpickle', unpickle, raw=True)
-
-class Mutable(MutableBase):
- """Mixin that defines transparent propagation of change
- events to a parent object.
-
- See the example in :ref:`mutable_scalars` for usage information.
-
- """
-
- def changed(self):
- """Subclasses should call this method whenever change events occur."""
-
- for parent, key in self._parents.items():
- flag_modified(parent, key)
-
- @classmethod
- def coerce(cls, key, value):
- """Given a value, coerce it into this type.
-
- By default raises ValueError.
- """
- if value is None:
- return None
- raise ValueError("Attribute '%s' does not accept objects of type %s" % (key, type(value)))
-
- @classmethod
- def associate_with_attribute(cls, attribute):
- """Establish this type as a mutation listener for the given
- mapped descriptor.
-
- """
- cls._listen_on_attribute(attribute, True)
-
- @classmethod
- def associate_with(cls, sqltype):
- """Associate this wrapper with all future mapped columns
- of the given type.
-
- This is a convenience method that calls ``associate_with_attribute`` automatically.
-
- .. warning:: The listeners established by this method are *global*
- to all mappers, and are *not* garbage collected. Only use
- :meth:`.associate_with` for types that are permanent to an application,
- not with ad-hoc types else this will cause unbounded growth
- in memory usage.
-
- """
-
- def listen_for_type(mapper, class_):
- for prop in mapper.iterate_properties:
- if hasattr(prop, 'columns'):
- if isinstance(prop.columns[0].type, sqltype):
- cls.associate_with_attribute(getattr(class_, prop.key))
- break
-
- event.listen(mapper, 'mapper_configured', listen_for_type)
-
- @classmethod
- def as_mutable(cls, sqltype):
- """Associate a SQL type with this mutable Python type.
-
- This establishes listeners that will detect ORM mappings against
- the given type, adding mutation event trackers to those mappings.
-
- The type is returned, unconditionally as an instance, so that
- :meth:`.as_mutable` can be used inline::
-
- Table('mytable', metadata,
- Column('id', Integer, primary_key=True),
- Column('data', MyMutableType.as_mutable(PickleType))
- )
-
- Note that the returned type is always an instance, even if a class
- is given, and that only columns which are declared specifically with that
- type instance receive additional instrumentation.
-
- To associate a particular mutable type with all occurrences of a
- particular type, use the :meth:`.Mutable.associate_with` classmethod
- of the particular :meth:`.Mutable` subclass to establish a global
- association.
-
- .. warning:: The listeners established by this method are *global*
- to all mappers, and are *not* garbage collected. Only use
- :meth:`.as_mutable` for types that are permanent to an application,
- not with ad-hoc types else this will cause unbounded growth
- in memory usage.
-
- """
- sqltype = types.to_instance(sqltype)
-
- def listen_for_type(mapper, class_):
- for prop in mapper.iterate_properties:
- if hasattr(prop, 'columns'):
- if prop.columns[0].type is sqltype:
- cls.associate_with_attribute(getattr(class_, prop.key))
- break
-
- event.listen(mapper, 'mapper_configured', listen_for_type)
-
- return sqltype
-
-class _MutableCompositeMeta(type):
- def __init__(cls, classname, bases, dict_):
- cls._setup_listeners()
- return type.__init__(cls, classname, bases, dict_)
-
-class MutableComposite(MutableBase):
- """Mixin that defines transparent propagation of change
- events on a SQLAlchemy "composite" object to its
- owning parent or parents.
-
- See the example in :ref:`mutable_composites` for usage information.
-
- .. warning:: The listeners established by the :class:`.MutableComposite`
- class are *global* to all mappers, and are *not* garbage collected. Only use
- :class:`.MutableComposite` for types that are permanent to an application,
- not with ad-hoc types else this will cause unbounded growth
- in memory usage.
-
- """
- __metaclass__ = _MutableCompositeMeta
-
- def changed(self):
- """Subclasses should call this method whenever change events occur."""
-
- for parent, key in self._parents.items():
-
- prop = object_mapper(parent).get_property(key)
- for value, attr_name in zip(
- self.__composite_values__(),
- prop._attribute_keys):
- setattr(parent, attr_name, value)
-
- @classmethod
- def _setup_listeners(cls):
- """Associate this wrapper with all future mapped composites
- of the given type.
-
- This is a convenience method that calls ``associate_with_attribute`` automatically.
-
- """
-
- def listen_for_type(mapper, class_):
- for prop in mapper.iterate_properties:
- if hasattr(prop, 'composite_class') and issubclass(prop.composite_class, cls):
- cls._listen_on_attribute(getattr(class_, prop.key), False)
-
- event.listen(mapper, 'mapper_configured', listen_for_type)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/orderinglist.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/orderinglist.py
deleted file mode 100755
index ce63b88e..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/orderinglist.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# ext/orderinglist.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""A custom list that manages index/position information for its children.
-
-:author: Jason Kirtland
-
-``orderinglist`` is a helper for mutable ordered relationships. It will intercept
-list operations performed on a relationship collection and automatically
-synchronize changes in list position with an attribute on the related objects.
-(See :ref:`advdatamapping_entitycollections` for more information on the general pattern.)
-
-Example: Two tables that store slides in a presentation. Each slide
-has a number of bullet points, displayed in order by the 'position'
-column on the bullets table. These bullets can be inserted and re-ordered
-by your end users, and you need to update the 'position' column of all
-affected rows when changes are made.
-
-.. sourcecode:: python+sql
-
- slides_table = Table('Slides', metadata,
- Column('id', Integer, primary_key=True),
- Column('name', String))
-
- bullets_table = Table('Bullets', metadata,
- Column('id', Integer, primary_key=True),
- Column('slide_id', Integer, ForeignKey('Slides.id')),
- Column('position', Integer),
- Column('text', String))
-
- class Slide(object):
- pass
- class Bullet(object):
- pass
-
- mapper(Slide, slides_table, properties={
- 'bullets': relationship(Bullet, order_by=[bullets_table.c.position])
- })
- mapper(Bullet, bullets_table)
-
-The standard relationship mapping will produce a list-like attribute on each Slide
-containing all related Bullets, but coping with changes in ordering is totally
-your responsibility. If you insert a Bullet into that list, there is no
-magic- it won't have a position attribute unless you assign it it one, and
-you'll need to manually renumber all the subsequent Bullets in the list to
-accommodate the insert.
-
-An ``orderinglist`` can automate this and manage the 'position' attribute on all
-related bullets for you.
-
-.. sourcecode:: python+sql
-
- mapper(Slide, slides_table, properties={
- 'bullets': relationship(Bullet,
- collection_class=ordering_list('position'),
- order_by=[bullets_table.c.position])
- })
- mapper(Bullet, bullets_table)
-
- s = Slide()
- s.bullets.append(Bullet())
- s.bullets.append(Bullet())
- s.bullets[1].position
- >>> 1
- s.bullets.insert(1, Bullet())
- s.bullets[2].position
- >>> 2
-
-Use the ``ordering_list`` function to set up the ``collection_class`` on relationships
-(as in the mapper example above). This implementation depends on the list
-starting in the proper order, so be SURE to put an order_by on your relationship.
-
-.. warning:: ``ordering_list`` only provides limited functionality when a primary
- key column or unique column is the target of the sort. Since changing the order of
- entries often means that two rows must trade values, this is not possible when
- the value is constrained by a primary key or unique constraint, since one of the rows
- would temporarily have to point to a third available value so that the other row
- could take its old value. ``ordering_list`` doesn't do any of this for you,
- nor does SQLAlchemy itself.
-
-``ordering_list`` takes the name of the related object's ordering attribute as
-an argument. By default, the zero-based integer index of the object's
-position in the ``ordering_list`` is synchronized with the ordering attribute:
-index 0 will get position 0, index 1 position 1, etc. To start numbering at 1
-or some other integer, provide ``count_from=1``.
-
-Ordering values are not limited to incrementing integers. Almost any scheme
-can implemented by supplying a custom ``ordering_func`` that maps a Python list
-index to any value you require.
-
-
-
-
-"""
-from sqlalchemy.orm.collections import collection
-from sqlalchemy import util
-
-__all__ = [ 'ordering_list' ]
-
-
-def ordering_list(attr, count_from=None, **kw):
- """Prepares an OrderingList factory for use in mapper definitions.
-
- Returns an object suitable for use as an argument to a Mapper relationship's
- ``collection_class`` option. Arguments are:
-
- attr
- Name of the mapped attribute to use for storage and retrieval of
- ordering information
-
- count_from (optional)
- Set up an integer-based ordering, starting at ``count_from``. For
- example, ``ordering_list('pos', count_from=1)`` would create a 1-based
- list in SQL, storing the value in the 'pos' column. Ignored if
- ``ordering_func`` is supplied.
-
- Passes along any keyword arguments to ``OrderingList`` constructor.
- """
-
- kw = _unsugar_count_from(count_from=count_from, **kw)
- return lambda: OrderingList(attr, **kw)
-
-# Ordering utility functions
-def count_from_0(index, collection):
- """Numbering function: consecutive integers starting at 0."""
-
- return index
-
-def count_from_1(index, collection):
- """Numbering function: consecutive integers starting at 1."""
-
- return index + 1
-
-def count_from_n_factory(start):
- """Numbering function: consecutive integers starting at arbitrary start."""
-
- def f(index, collection):
- return index + start
- try:
- f.__name__ = 'count_from_%i' % start
- except TypeError:
- pass
- return f
-
-def _unsugar_count_from(**kw):
- """Builds counting functions from keywrod arguments.
-
- Keyword argument filter, prepares a simple ``ordering_func`` from a
- ``count_from`` argument, otherwise passes ``ordering_func`` on unchanged.
- """
-
- count_from = kw.pop('count_from', None)
- if kw.get('ordering_func', None) is None and count_from is not None:
- if count_from == 0:
- kw['ordering_func'] = count_from_0
- elif count_from == 1:
- kw['ordering_func'] = count_from_1
- else:
- kw['ordering_func'] = count_from_n_factory(count_from)
- return kw
-
-class OrderingList(list):
- """A custom list that manages position information for its children.
-
- See the module and __init__ documentation for more details. The
- ``ordering_list`` factory function is used to configure ``OrderingList``
- collections in ``mapper`` relationship definitions.
-
- """
-
- def __init__(self, ordering_attr=None, ordering_func=None,
- reorder_on_append=False):
- """A custom list that manages position information for its children.
-
- ``OrderingList`` is a ``collection_class`` list implementation that
- syncs position in a Python list with a position attribute on the
- mapped objects.
-
- This implementation relies on the list starting in the proper order,
- so be **sure** to put an ``order_by`` on your relationship.
-
- ordering_attr
- Name of the attribute that stores the object's order in the
- relationship.
-
- ordering_func
- Optional. A function that maps the position in the Python list to a
- value to store in the ``ordering_attr``. Values returned are
- usually (but need not be!) integers.
-
- An ``ordering_func`` is called with two positional parameters: the
- index of the element in the list, and the list itself.
-
- If omitted, Python list indexes are used for the attribute values.
- Two basic pre-built numbering functions are provided in this module:
- ``count_from_0`` and ``count_from_1``. For more exotic examples
- like stepped numbering, alphabetical and Fibonacci numbering, see
- the unit tests.
-
- reorder_on_append
- Default False. When appending an object with an existing (non-None)
- ordering value, that value will be left untouched unless
- ``reorder_on_append`` is true. This is an optimization to avoid a
- variety of dangerous unexpected database writes.
-
- SQLAlchemy will add instances to the list via append() when your
- object loads. If for some reason the result set from the database
- skips a step in the ordering (say, row '1' is missing but you get
- '2', '3', and '4'), reorder_on_append=True would immediately
- renumber the items to '1', '2', '3'. If you have multiple sessions
- making changes, any of whom happen to load this collection even in
- passing, all of the sessions would try to "clean up" the numbering
- in their commits, possibly causing all but one to fail with a
- concurrent modification error. Spooky action at a distance.
-
- Recommend leaving this with the default of False, and just call
- ``reorder()`` if you're doing ``append()`` operations with
- previously ordered instances or when doing some housekeeping after
- manual sql operations.
-
- """
- self.ordering_attr = ordering_attr
- if ordering_func is None:
- ordering_func = count_from_0
- self.ordering_func = ordering_func
- self.reorder_on_append = reorder_on_append
-
- # More complex serialization schemes (multi column, e.g.) are possible by
- # subclassing and reimplementing these two methods.
- def _get_order_value(self, entity):
- return getattr(entity, self.ordering_attr)
-
- def _set_order_value(self, entity, value):
- setattr(entity, self.ordering_attr, value)
-
- def reorder(self):
- """Synchronize ordering for the entire collection.
-
- Sweeps through the list and ensures that each object has accurate
- ordering information set.
-
- """
- for index, entity in enumerate(self):
- self._order_entity(index, entity, True)
-
- # As of 0.5, _reorder is no longer semi-private
- _reorder = reorder
-
- def _order_entity(self, index, entity, reorder=True):
- have = self._get_order_value(entity)
-
- # Don't disturb existing ordering if reorder is False
- if have is not None and not reorder:
- return
-
- should_be = self.ordering_func(index, self)
- if have != should_be:
- self._set_order_value(entity, should_be)
-
- def append(self, entity):
- super(OrderingList, self).append(entity)
- self._order_entity(len(self) - 1, entity, self.reorder_on_append)
-
- def _raw_append(self, entity):
- """Append without any ordering behavior."""
-
- super(OrderingList, self).append(entity)
- _raw_append = collection.adds(1)(_raw_append)
-
- def insert(self, index, entity):
- super(OrderingList, self).insert(index, entity)
- self._reorder()
-
- def remove(self, entity):
- super(OrderingList, self).remove(entity)
- self._reorder()
-
- def pop(self, index=-1):
- entity = super(OrderingList, self).pop(index)
- self._reorder()
- return entity
-
- def __setitem__(self, index, entity):
- if isinstance(index, slice):
- step = index.step or 1
- start = index.start or 0
- if start < 0:
- start += len(self)
- stop = index.stop or len(self)
- if stop < 0:
- stop += len(self)
-
- for i in xrange(start, stop, step):
- self.__setitem__(i, entity[i])
- else:
- self._order_entity(index, entity, True)
- super(OrderingList, self).__setitem__(index, entity)
-
- def __delitem__(self, index):
- super(OrderingList, self).__delitem__(index)
- self._reorder()
-
- # Py2K
- def __setslice__(self, start, end, values):
- super(OrderingList, self).__setslice__(start, end, values)
- self._reorder()
-
- def __delslice__(self, start, end):
- super(OrderingList, self).__delslice__(start, end)
- self._reorder()
- # end Py2K
-
- for func_name, func in locals().items():
- if (util.callable(func) and func.func_name == func_name and
- not func.__doc__ and hasattr(list, func_name)):
- func.__doc__ = getattr(list, func_name).__doc__
- del func_name, func
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/serializer.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/serializer.py
deleted file mode 100755
index 077a0fd9..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/serializer.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# ext/serializer.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Serializer/Deserializer objects for usage with SQLAlchemy query structures,
-allowing "contextual" deserialization.
-
-Any SQLAlchemy query structure, either based on sqlalchemy.sql.*
-or sqlalchemy.orm.* can be used. The mappers, Tables, Columns, Session
-etc. which are referenced by the structure are not persisted in serialized
-form, but are instead re-associated with the query structure
-when it is deserialized.
-
-Usage is nearly the same as that of the standard Python pickle module::
-
- from sqlalchemy.ext.serializer import loads, dumps
- metadata = MetaData(bind=some_engine)
- Session = scoped_session(sessionmaker())
-
- # ... define mappers
-
- query = Session.query(MyClass).filter(MyClass.somedata=='foo').order_by(MyClass.sortkey)
-
- # pickle the query
- serialized = dumps(query)
-
- # unpickle. Pass in metadata + scoped_session
- query2 = loads(serialized, metadata, Session)
-
- print query2.all()
-
-Similar restrictions as when using raw pickle apply; mapped classes must be
-themselves be pickleable, meaning they are importable from a module-level
-namespace.
-
-The serializer module is only appropriate for query structures. It is not
-needed for:
-
-* instances of user-defined classes. These contain no references to engines,
- sessions or expression constructs in the typical case and can be serialized directly.
-
-* Table metadata that is to be loaded entirely from the serialized structure (i.e. is
- not already declared in the application). Regular pickle.loads()/dumps() can
- be used to fully dump any ``MetaData`` object, typically one which was reflected
- from an existing database at some previous point in time. The serializer module
- is specifically for the opposite case, where the Table metadata is already present
- in memory.
-
-"""
-
-from sqlalchemy.orm import class_mapper, Query
-from sqlalchemy.orm.session import Session
-from sqlalchemy.orm.mapper import Mapper
-from sqlalchemy.orm.attributes import QueryableAttribute
-from sqlalchemy import Table, Column
-from sqlalchemy.engine import Engine
-from sqlalchemy.util import pickle
-import re
-import base64
-# Py3K
-#from io import BytesIO as byte_buffer
-# Py2K
-from cStringIO import StringIO as byte_buffer
-# end Py2K
-
-# Py3K
-#def b64encode(x):
-# return base64.b64encode(x).decode('ascii')
-#def b64decode(x):
-# return base64.b64decode(x.encode('ascii'))
-# Py2K
-b64encode = base64.b64encode
-b64decode = base64.b64decode
-# end Py2K
-
-__all__ = ['Serializer', 'Deserializer', 'dumps', 'loads']
-
-
-
-def Serializer(*args, **kw):
- pickler = pickle.Pickler(*args, **kw)
-
- def persistent_id(obj):
- #print "serializing:", repr(obj)
- if isinstance(obj, QueryableAttribute):
- cls = obj.impl.class_
- key = obj.impl.key
- id = "attribute:" + key + ":" + b64encode(pickle.dumps(cls))
- elif isinstance(obj, Mapper) and not obj.non_primary:
- id = "mapper:" + b64encode(pickle.dumps(obj.class_))
- elif isinstance(obj, Table):
- id = "table:" + str(obj)
- elif isinstance(obj, Column) and isinstance(obj.table, Table):
- id = "column:" + str(obj.table) + ":" + obj.key
- elif isinstance(obj, Session):
- id = "session:"
- elif isinstance(obj, Engine):
- id = "engine:"
- else:
- return None
- return id
-
- pickler.persistent_id = persistent_id
- return pickler
-
-our_ids = re.compile(r'(mapper|table|column|session|attribute|engine):(.*)')
-
-def Deserializer(file, metadata=None, scoped_session=None, engine=None):
- unpickler = pickle.Unpickler(file)
-
- def get_engine():
- if engine:
- return engine
- elif scoped_session and scoped_session().bind:
- return scoped_session().bind
- elif metadata and metadata.bind:
- return metadata.bind
- else:
- return None
-
- def persistent_load(id):
- m = our_ids.match(id)
- if not m:
- return None
- else:
- type_, args = m.group(1, 2)
- if type_ == 'attribute':
- key, clsarg = args.split(":")
- cls = pickle.loads(b64decode(clsarg))
- return getattr(cls, key)
- elif type_ == "mapper":
- cls = pickle.loads(b64decode(args))
- return class_mapper(cls)
- elif type_ == "table":
- return metadata.tables[args]
- elif type_ == "column":
- table, colname = args.split(':')
- return metadata.tables[table].c[colname]
- elif type_ == "session":
- return scoped_session()
- elif type_ == "engine":
- return get_engine()
- else:
- raise Exception("Unknown token: %s" % type_)
- unpickler.persistent_load = persistent_load
- return unpickler
-
-def dumps(obj, protocol=0):
- buf = byte_buffer()
- pickler = Serializer(buf, protocol)
- pickler.dump(obj)
- return buf.getvalue()
-
-def loads(data, metadata=None, scoped_session=None, engine=None):
- buf = byte_buffer(data)
- unpickler = Deserializer(buf, metadata, scoped_session, engine)
- return unpickler.load()
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/sqlsoup.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/sqlsoup.py
deleted file mode 100755
index f76a175a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/ext/sqlsoup.py
+++ /dev/null
@@ -1,797 +0,0 @@
-# ext/sqlsoup.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Introduction
-============
-
-SqlSoup provides a convenient way to access existing database
-tables without having to declare table or mapper classes ahead
-of time. It is built on top of the SQLAlchemy ORM and provides a
-super-minimalistic interface to an existing database.
-
-SqlSoup effectively provides a coarse grained, alternative
-interface to working with the SQLAlchemy ORM, providing a "self
-configuring" interface for extremely rudimental operations. It's
-somewhat akin to a "super novice mode" version of the ORM. While
-SqlSoup can be very handy, users are strongly encouraged to use
-the full ORM for non-trivial applications.
-
-Suppose we have a database with users, books, and loans tables
-(corresponding to the PyWebOff dataset, if you're curious).
-
-Creating a SqlSoup gateway is just like creating an SQLAlchemy
-engine::
-
- >>> from sqlalchemy.ext.sqlsoup import SqlSoup
- >>> db = SqlSoup('sqlite:///:memory:')
-
-or, you can re-use an existing engine::
-
- >>> db = SqlSoup(engine)
-
-You can optionally specify a schema within the database for your
-SqlSoup::
-
- >>> db.schema = myschemaname
-
-Loading objects
-===============
-
-Loading objects is as easy as this::
-
- >>> users = db.users.all()
- >>> users.sort()
- >>> users
- [
- MappedUsers(name=u'Joe Student',email=u'student@example.edu',
- password=u'student',classname=None,admin=0),
- MappedUsers(name=u'Bhargan Basepair',email=u'basepair@example.edu',
- password=u'basepair',classname=None,admin=1)
- ]
-
-Of course, letting the database do the sort is better::
-
- >>> db.users.order_by(db.users.name).all()
- [
- MappedUsers(name=u'Bhargan Basepair',email=u'basepair@example.edu',
- password=u'basepair',classname=None,admin=1),
- MappedUsers(name=u'Joe Student',email=u'student@example.edu',
- password=u'student',classname=None,admin=0)
- ]
-
-Field access is intuitive::
-
- >>> users[0].email
- u'student@example.edu'
-
-Of course, you don't want to load all users very often. Let's
-add a WHERE clause. Let's also switch the order_by to DESC while
-we're at it::
-
- >>> from sqlalchemy import or_, and_, desc
- >>> where = or_(db.users.name=='Bhargan Basepair', db.users.email=='student@example.edu')
- >>> db.users.filter(where).order_by(desc(db.users.name)).all()
- [
- MappedUsers(name=u'Joe Student',email=u'student@example.edu',
- password=u'student',classname=None,admin=0),
- MappedUsers(name=u'Bhargan Basepair',email=u'basepair@example.edu',
- password=u'basepair',classname=None,admin=1)
- ]
-
-You can also use .first() (to retrieve only the first object
-from a query) or .one() (like .first when you expect exactly one
-user -- it will raise an exception if more were returned)::
-
- >>> db.users.filter(db.users.name=='Bhargan Basepair').one()
- MappedUsers(name=u'Bhargan Basepair',email=u'basepair@example.edu',
- password=u'basepair',classname=None,admin=1)
-
-Since name is the primary key, this is equivalent to
-
- >>> db.users.get('Bhargan Basepair')
- MappedUsers(name=u'Bhargan Basepair',email=u'basepair@example.edu',
- password=u'basepair',classname=None,admin=1)
-
-This is also equivalent to
-
- >>> db.users.filter_by(name='Bhargan Basepair').one()
- MappedUsers(name=u'Bhargan Basepair',email=u'basepair@example.edu',
- password=u'basepair',classname=None,admin=1)
-
-filter_by is like filter, but takes kwargs instead of full
-clause expressions. This makes it more concise for simple
-queries like this, but you can't do complex queries like the
-or\_ above or non-equality based comparisons this way.
-
-Full query documentation
-------------------------
-
-Get, filter, filter_by, order_by, limit, and the rest of the
-query methods are explained in detail in
-:ref:`ormtutorial_querying`.
-
-Modifying objects
-=================
-
-Modifying objects is intuitive::
-
- >>> user = _
- >>> user.email = 'basepair+nospam@example.edu'
- >>> db.commit()
-
-(SqlSoup leverages the sophisticated SQLAlchemy unit-of-work
-code, so multiple updates to a single object will be turned into
-a single ``UPDATE`` statement when you commit.)
-
-To finish covering the basics, let's insert a new loan, then
-delete it::
-
- >>> book_id = db.books.filter_by(title='Regional Variation in Moss').first().id
- >>> db.loans.insert(book_id=book_id, user_name=user.name)
- MappedLoans(book_id=2,user_name=u'Bhargan Basepair',loan_date=None)
-
- >>> loan = db.loans.filter_by(book_id=2, user_name='Bhargan Basepair').one()
- >>> db.delete(loan)
- >>> db.commit()
-
-You can also delete rows that have not been loaded as objects.
-Let's do our insert/delete cycle once more, this time using the
-loans table's delete method. (For SQLAlchemy experts: note that
-no flush() call is required since this delete acts at the SQL
-level, not at the Mapper level.) The same where-clause
-construction rules apply here as to the select methods::
-
- >>> db.loans.insert(book_id=book_id, user_name=user.name)
- MappedLoans(book_id=2,user_name=u'Bhargan Basepair',loan_date=None)
- >>> db.loans.delete(db.loans.book_id==2)
-
-You can similarly update multiple rows at once. This will change the
-book_id to 1 in all loans whose book_id is 2::
-
- >>> db.loans.update(db.loans.book_id==2, book_id=1)
- >>> db.loans.filter_by(book_id=1).all()
- [MappedLoans(book_id=1,user_name=u'Joe Student',
- loan_date=datetime.datetime(2006, 7, 12, 0, 0))]
-
-
-Joins
-=====
-
-Occasionally, you will want to pull out a lot of data from related
-tables all at once. In this situation, it is far more efficient to
-have the database perform the necessary join. (Here we do not have *a
-lot of data* but hopefully the concept is still clear.) SQLAlchemy is
-smart enough to recognize that loans has a foreign key to users, and
-uses that as the join condition automatically::
-
- >>> join1 = db.join(db.users, db.loans, isouter=True)
- >>> join1.filter_by(name='Joe Student').all()
- [
- MappedJoin(name=u'Joe Student',email=u'student@example.edu',
- password=u'student',classname=None,admin=0,book_id=1,
- user_name=u'Joe Student',loan_date=datetime.datetime(2006, 7, 12, 0, 0))
- ]
-
-If you're unfortunate enough to be using MySQL with the default MyISAM
-storage engine, you'll have to specify the join condition manually,
-since MyISAM does not store foreign keys. Here's the same join again,
-with the join condition explicitly specified::
-
- >>> db.join(db.users, db.loans, db.users.name==db.loans.user_name, isouter=True)
- <class 'sqlalchemy.ext.sqlsoup.MappedJoin'>
-
-You can compose arbitrarily complex joins by combining Join objects
-with tables or other joins. Here we combine our first join with the
-books table::
-
- >>> join2 = db.join(join1, db.books)
- >>> join2.all()
- [
- MappedJoin(name=u'Joe Student',email=u'student@example.edu',
- password=u'student',classname=None,admin=0,book_id=1,
- user_name=u'Joe Student',loan_date=datetime.datetime(2006, 7, 12, 0, 0),
- id=1,title=u'Mustards I Have Known',published_year=u'1989',
- authors=u'Jones')
- ]
-
-If you join tables that have an identical column name, wrap your join
-with `with_labels`, to disambiguate columns with their table name
-(.c is short for .columns)::
-
- >>> db.with_labels(join1).c.keys()
- [u'users_name', u'users_email', u'users_password',
- u'users_classname', u'users_admin', u'loans_book_id',
- u'loans_user_name', u'loans_loan_date']
-
-You can also join directly to a labeled object::
-
- >>> labeled_loans = db.with_labels(db.loans)
- >>> db.join(db.users, labeled_loans, isouter=True).c.keys()
- [u'name', u'email', u'password', u'classname',
- u'admin', u'loans_book_id', u'loans_user_name', u'loans_loan_date']
-
-
-Relationships
-=============
-
-You can define relationships on SqlSoup classes:
-
- >>> db.users.relate('loans', db.loans)
-
-These can then be used like a normal SA property:
-
- >>> db.users.get('Joe Student').loans
- [MappedLoans(book_id=1,user_name=u'Joe Student',
- loan_date=datetime.datetime(2006, 7, 12, 0, 0))]
-
- >>> db.users.filter(~db.users.loans.any()).all()
- [MappedUsers(name=u'Bhargan Basepair',
- email='basepair+nospam@example.edu',
- password=u'basepair',classname=None,admin=1)]
-
-relate can take any options that the relationship function
-accepts in normal mapper definition:
-
- >>> del db._cache['users']
- >>> db.users.relate('loans', db.loans, order_by=db.loans.loan_date, cascade='all, delete-orphan')
-
-Advanced Use
-============
-
-Sessions, Transations and Application Integration
--------------------------------------------------
-
-**Note:** please read and understand this section thoroughly
-before using SqlSoup in any web application.
-
-SqlSoup uses a ScopedSession to provide thread-local sessions.
-You can get a reference to the current one like this::
-
- >>> session = db.session
-
-The default session is available at the module level in SQLSoup,
-via::
-
- >>> from sqlalchemy.ext.sqlsoup import Session
-
-The configuration of this session is ``autoflush=True``,
-``autocommit=False``. This means when you work with the SqlSoup
-object, you need to call ``db.commit()`` in order to have
-changes persisted. You may also call ``db.rollback()`` to roll
-things back.
-
-Since the SqlSoup object's Session automatically enters into a
-transaction as soon as it's used, it is *essential* that you
-call ``commit()`` or ``rollback()`` on it when the work within a
-thread completes. This means all the guidelines for web
-application integration at :ref:`session_lifespan` must be
-followed.
-
-The SqlSoup object can have any session or scoped session
-configured onto it. This is of key importance when integrating
-with existing code or frameworks such as Pylons. If your
-application already has a ``Session`` configured, pass it to
-your SqlSoup object::
-
- >>> from myapplication import Session
- >>> db = SqlSoup(session=Session)
-
-If the ``Session`` is configured with ``autocommit=True``, use
-``flush()`` instead of ``commit()`` to persist changes - in this
-case, the ``Session`` closes out its transaction immediately and
-no external management is needed. ``rollback()`` is also not
-available. Configuring a new SQLSoup object in "autocommit" mode
-looks like::
-
- >>> from sqlalchemy.orm import scoped_session, sessionmaker
- >>> db = SqlSoup('sqlite://', session=scoped_session(sessionmaker(autoflush=False, expire_on_commit=False, autocommit=True)))
-
-
-Mapping arbitrary Selectables
------------------------------
-
-SqlSoup can map any SQLAlchemy :class:`.Selectable` with the map
-method. Let's map an :func:`.expression.select` object that uses an aggregate
-function; we'll use the SQLAlchemy :class:`.Table` that SqlSoup
-introspected as the basis. (Since we're not mapping to a simple
-table or join, we need to tell SQLAlchemy how to find the
-*primary key* which just needs to be unique within the select,
-and not necessarily correspond to a *real* PK in the database.)::
-
- >>> from sqlalchemy import select, func
- >>> b = db.books._table
- >>> s = select([b.c.published_year, func.count('*').label('n')], from_obj=[b], group_by=[b.c.published_year])
- >>> s = s.alias('years_with_count')
- >>> years_with_count = db.map(s, primary_key=[s.c.published_year])
- >>> years_with_count.filter_by(published_year='1989').all()
- [MappedBooks(published_year=u'1989',n=1)]
-
-Obviously if we just wanted to get a list of counts associated with
-book years once, raw SQL is going to be less work. The advantage of
-mapping a Select is reusability, both standalone and in Joins. (And if
-you go to full SQLAlchemy, you can perform mappings like this directly
-to your object models.)
-
-An easy way to save mapped selectables like this is to just hang them on
-your db object::
-
- >>> db.years_with_count = years_with_count
-
-Python is flexible like that!
-
-Raw SQL
--------
-
-SqlSoup works fine with SQLAlchemy's text construct, described
-in :ref:`sqlexpression_text`. You can also execute textual SQL
-directly using the `execute()` method, which corresponds to the
-`execute()` method on the underlying `Session`. Expressions here
-are expressed like ``text()`` constructs, using named parameters
-with colons::
-
- >>> rp = db.execute('select name, email from users where name like :name order by name', name='%Bhargan%')
- >>> for name, email in rp.fetchall(): print name, email
- Bhargan Basepair basepair+nospam@example.edu
-
-Or you can get at the current transaction's connection using
-`connection()`. This is the raw connection object which can
-accept any sort of SQL expression or raw SQL string passed to
-the database::
-
- >>> conn = db.connection()
- >>> conn.execute("'select name, email from users where name like ? order by name'", '%Bhargan%')
-
-Dynamic table names
--------------------
-
-You can load a table whose name is specified at runtime with the
-entity() method:
-
- >>> tablename = 'loans'
- >>> db.entity(tablename) == db.loans
- True
-
-entity() also takes an optional schema argument. If none is
-specified, the default schema is used.
-
-"""
-
-from sqlalchemy import Table, MetaData, join
-from sqlalchemy import schema, sql, util
-from sqlalchemy.engine.base import Engine
-from sqlalchemy.orm import scoped_session, sessionmaker, mapper, \
- class_mapper, relationship, session,\
- object_session, attributes
-from sqlalchemy.orm.interfaces import MapperExtension, EXT_CONTINUE
-from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, ArgumentError
-from sqlalchemy.sql import expression
-
-
-__all__ = ['PKNotFoundError', 'SqlSoup']
-
-Session = scoped_session(sessionmaker(autoflush=True, autocommit=False))
-
-class AutoAdd(MapperExtension):
- def __init__(self, scoped_session):
- self.scoped_session = scoped_session
-
- def instrument_class(self, mapper, class_):
- class_.__init__ = self._default__init__(mapper)
-
- def _default__init__(ext, mapper):
- def __init__(self, **kwargs):
- for key, value in kwargs.iteritems():
- setattr(self, key, value)
- return __init__
-
- def init_instance(self, mapper, class_, oldinit, instance, args, kwargs):
- session = self.scoped_session()
- state = attributes.instance_state(instance)
- session._save_impl(state)
- return EXT_CONTINUE
-
- def init_failed(self, mapper, class_, oldinit, instance, args, kwargs):
- sess = object_session(instance)
- if sess:
- sess.expunge(instance)
- return EXT_CONTINUE
-
-class PKNotFoundError(SQLAlchemyError):
- pass
-
-def _ddl_error(cls):
- msg = 'SQLSoup can only modify mapped Tables (found: %s)' \
- % cls._table.__class__.__name__
- raise InvalidRequestError(msg)
-
-# metaclass is necessary to expose class methods with getattr, e.g.
-# we want to pass db.users.select through to users._mapper.select
-class SelectableClassType(type):
- def insert(cls, **kwargs):
- _ddl_error(cls)
-
- def __clause_element__(cls):
- return cls._table
-
- def __getattr__(cls, attr):
- if attr == '_query':
- # called during mapper init
- raise AttributeError()
- return getattr(cls._query, attr)
-
-class TableClassType(SelectableClassType):
- def insert(cls, **kwargs):
- o = cls()
- o.__dict__.update(kwargs)
- return o
-
- def relate(cls, propname, *args, **kwargs):
- class_mapper(cls)._configure_property(propname, relationship(*args, **kwargs))
-
-def _is_outer_join(selectable):
- if not isinstance(selectable, sql.Join):
- return False
- if selectable.isouter:
- return True
- return _is_outer_join(selectable.left) or _is_outer_join(selectable.right)
-
-def _selectable_name(selectable):
- if isinstance(selectable, sql.Alias):
- return _selectable_name(selectable.element)
- elif isinstance(selectable, sql.Select):
- return ''.join(_selectable_name(s) for s in selectable.froms)
- elif isinstance(selectable, schema.Table):
- return selectable.name.capitalize()
- else:
- x = selectable.__class__.__name__
- if x[0] == '_':
- x = x[1:]
- return x
-
-def _class_for_table(session, engine, selectable, base_cls, mapper_kwargs):
- selectable = expression._clause_element_as_expr(selectable)
- mapname = 'Mapped' + _selectable_name(selectable)
- # Py2K
- if isinstance(mapname, unicode):
- engine_encoding = engine.dialect.encoding
- mapname = mapname.encode(engine_encoding)
- # end Py2K
-
- if isinstance(selectable, Table):
- klass = TableClassType(mapname, (base_cls,), {})
- else:
- klass = SelectableClassType(mapname, (base_cls,), {})
-
- def _compare(self, o):
- L = list(self.__class__.c.keys())
- L.sort()
- t1 = [getattr(self, k) for k in L]
- try:
- t2 = [getattr(o, k) for k in L]
- except AttributeError:
- raise TypeError('unable to compare with %s' % o.__class__)
- return t1, t2
-
- # python2/python3 compatible system of
- # __cmp__ - __lt__ + __eq__
-
- def __lt__(self, o):
- t1, t2 = _compare(self, o)
- return t1 < t2
-
- def __eq__(self, o):
- t1, t2 = _compare(self, o)
- return t1 == t2
-
- def __repr__(self):
- L = ["%s=%r" % (key, getattr(self, key, ''))
- for key in self.__class__.c.keys()]
- return '%s(%s)' % (self.__class__.__name__, ','.join(L))
-
- for m in ['__eq__', '__repr__', '__lt__']:
- setattr(klass, m, eval(m))
- klass._table = selectable
- klass.c = expression.ColumnCollection()
- mappr = mapper(klass,
- selectable,
- extension=AutoAdd(session),
- **mapper_kwargs)
-
- for k in mappr.iterate_properties:
- klass.c[k.key] = k.columns[0]
-
- klass._query = session.query_property()
- return klass
-
-class SqlSoup(object):
- """Represent an ORM-wrapped database resource."""
-
- def __init__(self, engine_or_metadata, base=object, session=None):
- """Initialize a new :class:`.SqlSoup`.
-
- :param engine_or_metadata: a string database URL, :class:`.Engine`
- or :class:`.MetaData` object to associate with. If the
- argument is a :class:`.MetaData`, it should be *bound*
- to an :class:`.Engine`.
- :param base: a class which will serve as the default class for
- returned mapped classes. Defaults to ``object``.
- :param session: a :class:`.ScopedSession` or :class:`.Session` with
- which to associate ORM operations for this :class:`.SqlSoup` instance.
- If ``None``, a :class:`.ScopedSession` that's local to this
- module is used.
-
- """
-
- self.session = session or Session
- self.base=base
-
- if isinstance(engine_or_metadata, MetaData):
- self._metadata = engine_or_metadata
- elif isinstance(engine_or_metadata, (basestring, Engine)):
- self._metadata = MetaData(engine_or_metadata)
- else:
- raise ArgumentError("invalid engine or metadata argument %r" %
- engine_or_metadata)
-
- self._cache = {}
- self.schema = None
-
- @property
- def bind(self):
- """The :class:`.Engine` associated with this :class:`.SqlSoup`."""
- return self._metadata.bind
-
- engine = bind
-
- def delete(self, instance):
- """Mark an instance as deleted."""
-
- self.session.delete(instance)
-
- def execute(self, stmt, **params):
- """Execute a SQL statement.
-
- The statement may be a string SQL string,
- an :func:`.expression.select` construct, or an :func:`.expression.text`
- construct.
-
- """
- return self.session.execute(sql.text(stmt, bind=self.bind), **params)
-
- @property
- def _underlying_session(self):
- if isinstance(self.session, session.Session):
- return self.session
- else:
- return self.session()
-
- def connection(self):
- """Return the current :class:`.Connection` in use by the current transaction."""
-
- return self._underlying_session._connection_for_bind(self.bind)
-
- def flush(self):
- """Flush pending changes to the database.
-
- See :meth:`.Session.flush`.
-
- """
- self.session.flush()
-
- def rollback(self):
- """Rollback the current transction.
-
- See :meth:`.Session.rollback`.
-
- """
- self.session.rollback()
-
- def commit(self):
- """Commit the current transaction.
-
- See :meth:`.Session.commit`.
-
- """
- self.session.commit()
-
- def clear(self):
- """Synonym for :meth:`.SqlSoup.expunge_all`."""
-
- self.session.expunge_all()
-
- def expunge(self, instance):
- """Remove an instance from the :class:`.Session`.
-
- See :meth:`.Session.expunge`.
-
- """
- self.session.expunge(instance)
-
- def expunge_all(self):
- """Clear all objects from the current :class:`.Session`.
-
- See :meth:`.Session.expunge_all`.
-
- """
- self.session.expunge_all()
-
- def map_to(self, attrname, tablename=None, selectable=None,
- schema=None, base=None, mapper_args=util.immutabledict()):
- """Configure a mapping to the given attrname.
-
- This is the "master" method that can be used to create any
- configuration.
-
- (new in 0.6.6)
-
- :param attrname: String attribute name which will be
- established as an attribute on this :class:.`.SqlSoup`
- instance.
- :param base: a Python class which will be used as the
- base for the mapped class. If ``None``, the "base"
- argument specified by this :class:`.SqlSoup`
- instance's constructor will be used, which defaults to
- ``object``.
- :param mapper_args: Dictionary of arguments which will
- be passed directly to :func:`.orm.mapper`.
- :param tablename: String name of a :class:`.Table` to be
- reflected. If a :class:`.Table` is already available,
- use the ``selectable`` argument. This argument is
- mutually exclusive versus the ``selectable`` argument.
- :param selectable: a :class:`.Table`, :class:`.Join`, or
- :class:`.Select` object which will be mapped. This
- argument is mutually exclusive versus the ``tablename``
- argument.
- :param schema: String schema name to use if the
- ``tablename`` argument is present.
-
-
- """
- if attrname in self._cache:
- raise InvalidRequestError(
- "Attribute '%s' is already mapped to '%s'" % (
- attrname,
- class_mapper(self._cache[attrname]).mapped_table
- ))
-
- if tablename is not None:
- if not isinstance(tablename, basestring):
- raise ArgumentError("'tablename' argument must be a string."
- )
- if selectable is not None:
- raise ArgumentError("'tablename' and 'selectable' "
- "arguments are mutually exclusive")
-
- selectable = Table(tablename,
- self._metadata,
- autoload=True,
- autoload_with=self.bind,
- schema=schema or self.schema)
- elif schema:
- raise ArgumentError("'tablename' argument is required when "
- "using 'schema'.")
- elif selectable is not None:
- if not isinstance(selectable, expression.FromClause):
- raise ArgumentError("'selectable' argument must be a "
- "table, select, join, or other "
- "selectable construct.")
- else:
- raise ArgumentError("'tablename' or 'selectable' argument is "
- "required.")
-
- if not selectable.primary_key.columns:
- if tablename:
- raise PKNotFoundError(
- "table '%s' does not have a primary "
- "key defined" % tablename)
- else:
- raise PKNotFoundError(
- "selectable '%s' does not have a primary "
- "key defined" % selectable)
-
- mapped_cls = _class_for_table(
- self.session,
- self.engine,
- selectable,
- base or self.base,
- mapper_args
- )
- self._cache[attrname] = mapped_cls
- return mapped_cls
-
-
- def map(self, selectable, base=None, **mapper_args):
- """Map a selectable directly.
-
- The class and its mapping are not cached and will
- be discarded once dereferenced (as of 0.6.6).
-
- :param selectable: an :func:`.expression.select` construct.
- :param base: a Python class which will be used as the
- base for the mapped class. If ``None``, the "base"
- argument specified by this :class:`.SqlSoup`
- instance's constructor will be used, which defaults to
- ``object``.
- :param mapper_args: Dictionary of arguments which will
- be passed directly to :func:`.orm.mapper`.
-
- """
-
- return _class_for_table(
- self.session,
- self.engine,
- selectable,
- base or self.base,
- mapper_args
- )
-
- def with_labels(self, selectable, base=None, **mapper_args):
- """Map a selectable directly, wrapping the
- selectable in a subquery with labels.
-
- The class and its mapping are not cached and will
- be discarded once dereferenced (as of 0.6.6).
-
- :param selectable: an :func:`.expression.select` construct.
- :param base: a Python class which will be used as the
- base for the mapped class. If ``None``, the "base"
- argument specified by this :class:`.SqlSoup`
- instance's constructor will be used, which defaults to
- ``object``.
- :param mapper_args: Dictionary of arguments which will
- be passed directly to :func:`.orm.mapper`.
-
- """
-
- # TODO give meaningful aliases
- return self.map(
- expression._clause_element_as_expr(selectable).
- select(use_labels=True).
- alias('foo'), base=base, **mapper_args)
-
- def join(self, left, right, onclause=None, isouter=False,
- base=None, **mapper_args):
- """Create an :func:`.expression.join` and map to it.
-
- The class and its mapping are not cached and will
- be discarded once dereferenced (as of 0.6.6).
-
- :param left: a mapped class or table object.
- :param right: a mapped class or table object.
- :param onclause: optional "ON" clause construct..
- :param isouter: if True, the join will be an OUTER join.
- :param base: a Python class which will be used as the
- base for the mapped class. If ``None``, the "base"
- argument specified by this :class:`.SqlSoup`
- instance's constructor will be used, which defaults to
- ``object``.
- :param mapper_args: Dictionary of arguments which will
- be passed directly to :func:`.orm.mapper`.
-
- """
-
- j = join(left, right, onclause=onclause, isouter=isouter)
- return self.map(j, base=base, **mapper_args)
-
- def entity(self, attr, schema=None):
- """Return the named entity from this :class:`.SqlSoup`, or
- create if not present.
-
- For more generalized mapping, see :meth:`.map_to`.
-
- """
- try:
- return self._cache[attr]
- except KeyError, ke:
- return self.map_to(attr, tablename=attr, schema=schema)
-
- def __getattr__(self, attr):
- return self.entity(attr)
-
- def __repr__(self):
- return 'SqlSoup(%r)' % self._metadata
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/interfaces.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/interfaces.py
deleted file mode 100755
index d1e3fa6b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/interfaces.py
+++ /dev/null
@@ -1,305 +0,0 @@
-# sqlalchemy/interfaces.py
-# Copyright (C) 2007-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# Copyright (C) 2007 Jason Kirtland jek@discorporate.us
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Interfaces and abstract types.
-
-This module is **deprecated** and is superseded by the
-event system.
-
-"""
-
-from sqlalchemy import event, util
-
-class PoolListener(object):
- """Hooks into the lifecycle of connections in a :class:`.Pool`.
-
- .. note:: :class:`.PoolListener` is deprecated. Please
- refer to :class:`.PoolEvents`.
-
- Usage::
-
- class MyListener(PoolListener):
- def connect(self, dbapi_con, con_record):
- '''perform connect operations'''
- # etc.
-
- # create a new pool with a listener
- p = QueuePool(..., listeners=[MyListener()])
-
- # add a listener after the fact
- p.add_listener(MyListener())
-
- # usage with create_engine()
- e = create_engine("url://", listeners=[MyListener()])
-
- All of the standard connection :class:`~sqlalchemy.pool.Pool` types can
- accept event listeners for key connection lifecycle events:
- creation, pool check-out and check-in. There are no events fired
- when a connection closes.
-
- For any given DB-API connection, there will be one ``connect``
- event, `n` number of ``checkout`` events, and either `n` or `n - 1`
- ``checkin`` events. (If a ``Connection`` is detached from its
- pool via the ``detach()`` method, it won't be checked back in.)
-
- These are low-level events for low-level objects: raw Python
- DB-API connections, without the conveniences of the SQLAlchemy
- ``Connection`` wrapper, ``Dialect`` services or ``ClauseElement``
- execution. If you execute SQL through the connection, explicitly
- closing all cursors and other resources is recommended.
-
- Events also receive a ``_ConnectionRecord``, a long-lived internal
- ``Pool`` object that basically represents a "slot" in the
- connection pool. ``_ConnectionRecord`` objects have one public
- attribute of note: ``info``, a dictionary whose contents are
- scoped to the lifetime of the DB-API connection managed by the
- record. You can use this shared storage area however you like.
-
- There is no need to subclass ``PoolListener`` to handle events.
- Any class that implements one or more of these methods can be used
- as a pool listener. The ``Pool`` will inspect the methods
- provided by a listener object and add the listener to one or more
- internal event queues based on its capabilities. In terms of
- efficiency and function call overhead, you're much better off only
- providing implementations for the hooks you'll be using.
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- """Adapt a :class:`.PoolListener` to individual
- :class:`event.Dispatch` events.
-
- """
-
- listener = util.as_interface(listener, methods=('connect',
- 'first_connect', 'checkout', 'checkin'))
- if hasattr(listener, 'connect'):
- event.listen(self, 'connect', listener.connect)
- if hasattr(listener, 'first_connect'):
- event.listen(self, 'first_connect', listener.first_connect)
- if hasattr(listener, 'checkout'):
- event.listen(self, 'checkout', listener.checkout)
- if hasattr(listener, 'checkin'):
- event.listen(self, 'checkin', listener.checkin)
-
-
- def connect(self, dbapi_con, con_record):
- """Called once for each new DB-API connection or Pool's ``creator()``.
-
- dbapi_con
- A newly connected raw DB-API connection (not a SQLAlchemy
- ``Connection`` wrapper).
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
- def first_connect(self, dbapi_con, con_record):
- """Called exactly once for the first DB-API connection.
-
- dbapi_con
- A newly connected raw DB-API connection (not a SQLAlchemy
- ``Connection`` wrapper).
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
- def checkout(self, dbapi_con, con_record, con_proxy):
- """Called when a connection is retrieved from the Pool.
-
- dbapi_con
- A raw DB-API connection
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- con_proxy
- The ``_ConnectionFairy`` which manages the connection for the span of
- the current checkout.
-
- If you raise an ``exc.DisconnectionError``, the current
- connection will be disposed and a fresh connection retrieved.
- Processing of all checkout listeners will abort and restart
- using the new connection.
- """
-
- def checkin(self, dbapi_con, con_record):
- """Called when a connection returns to the pool.
-
- Note that the connection may be closed, and may be None if the
- connection has been invalidated. ``checkin`` will not be called
- for detached connections. (They do not return to the pool.)
-
- dbapi_con
- A raw DB-API connection
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
-class ConnectionProxy(object):
- """Allows interception of statement execution by Connections.
-
- .. note:: :class:`.ConnectionProxy` is deprecated. Please
- refer to :class:`.ConnectionEvents`.
-
- Either or both of the ``execute()`` and ``cursor_execute()``
- may be implemented to intercept compiled statement and
- cursor level executions, e.g.::
-
- class MyProxy(ConnectionProxy):
- def execute(self, conn, execute, clauseelement, *multiparams, **params):
- print "compiled statement:", clauseelement
- return execute(clauseelement, *multiparams, **params)
-
- def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
- print "raw statement:", statement
- return execute(cursor, statement, parameters, context)
-
- The ``execute`` argument is a function that will fulfill the default
- execution behavior for the operation. The signature illustrated
- in the example should be used.
-
- The proxy is installed into an :class:`~sqlalchemy.engine.Engine` via
- the ``proxy`` argument::
-
- e = create_engine('someurl://', proxy=MyProxy())
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
-
- def adapt_execute(conn, clauseelement, multiparams, params):
-
- def execute_wrapper(clauseelement, *multiparams, **params):
- return clauseelement, multiparams, params
-
- return listener.execute(conn, execute_wrapper,
- clauseelement, *multiparams,
- **params)
-
- event.listen(self, 'before_execute', adapt_execute)
-
- def adapt_cursor_execute(conn, cursor, statement,
- parameters,context, executemany, ):
-
- def execute_wrapper(
- cursor,
- statement,
- parameters,
- context,
- ):
- return statement, parameters
-
- return listener.cursor_execute(
- execute_wrapper,
- cursor,
- statement,
- parameters,
- context,
- executemany,
- )
-
- event.listen(self, 'before_cursor_execute', adapt_cursor_execute)
-
- def do_nothing_callback(*arg, **kw):
- pass
-
- def adapt_listener(fn):
-
- def go(conn, *arg, **kw):
- fn(conn, do_nothing_callback, *arg, **kw)
-
- return util.update_wrapper(go, fn)
-
- event.listen(self, 'begin', adapt_listener(listener.begin))
- event.listen(self, 'rollback',
- adapt_listener(listener.rollback))
- event.listen(self, 'commit', adapt_listener(listener.commit))
- event.listen(self, 'savepoint',
- adapt_listener(listener.savepoint))
- event.listen(self, 'rollback_savepoint',
- adapt_listener(listener.rollback_savepoint))
- event.listen(self, 'release_savepoint',
- adapt_listener(listener.release_savepoint))
- event.listen(self, 'begin_twophase',
- adapt_listener(listener.begin_twophase))
- event.listen(self, 'prepare_twophase',
- adapt_listener(listener.prepare_twophase))
- event.listen(self, 'rollback_twophase',
- adapt_listener(listener.rollback_twophase))
- event.listen(self, 'commit_twophase',
- adapt_listener(listener.commit_twophase))
-
-
- def execute(self, conn, execute, clauseelement, *multiparams, **params):
- """Intercept high level execute() events."""
-
-
- return execute(clauseelement, *multiparams, **params)
-
- def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
- """Intercept low-level cursor execute() events."""
-
- return execute(cursor, statement, parameters, context)
-
- def begin(self, conn, begin):
- """Intercept begin() events."""
-
- return begin()
-
- def rollback(self, conn, rollback):
- """Intercept rollback() events."""
-
- return rollback()
-
- def commit(self, conn, commit):
- """Intercept commit() events."""
-
- return commit()
-
- def savepoint(self, conn, savepoint, name=None):
- """Intercept savepoint() events."""
-
- return savepoint(name=name)
-
- def rollback_savepoint(self, conn, rollback_savepoint, name, context):
- """Intercept rollback_savepoint() events."""
-
- return rollback_savepoint(name, context)
-
- def release_savepoint(self, conn, release_savepoint, name, context):
- """Intercept release_savepoint() events."""
-
- return release_savepoint(name, context)
-
- def begin_twophase(self, conn, begin_twophase, xid):
- """Intercept begin_twophase() events."""
-
- return begin_twophase(xid)
-
- def prepare_twophase(self, conn, prepare_twophase, xid):
- """Intercept prepare_twophase() events."""
-
- return prepare_twophase(xid)
-
- def rollback_twophase(self, conn, rollback_twophase, xid, is_prepared):
- """Intercept rollback_twophase() events."""
-
- return rollback_twophase(xid, is_prepared)
-
- def commit_twophase(self, conn, commit_twophase, xid, is_prepared):
- """Intercept commit_twophase() events."""
-
- return commit_twophase(xid, is_prepared)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/log.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/log.py
deleted file mode 100755
index e77730a9..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/log.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# sqlalchemy/log.py
-# Copyright (C) 2006-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# Includes alterations by Vinay Sajip vinay_sajip@yahoo.co.uk
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Logging control and utilities.
-
-Control of logging for SA can be performed from the regular python logging
-module. The regular dotted module namespace is used, starting at
-'sqlalchemy'. For class-level logging, the class name is appended.
-
-The "echo" keyword parameter, available on SQLA :class:`.Engine`
-and :class:`.Pool` objects, corresponds to a logger specific to that
-instance only.
-
-"""
-
-import logging
-import sys
-from sqlalchemy import util
-
-# set initial level to WARN. This so that
-# log statements don't occur in the absense of explicit
-# logging being enabled for 'sqlalchemy'.
-rootlogger = logging.getLogger('sqlalchemy')
-if rootlogger.level == logging.NOTSET:
- rootlogger.setLevel(logging.WARN)
-
-def _add_default_handler(logger):
- handler = logging.StreamHandler(sys.stdout)
- handler.setFormatter(logging.Formatter(
- '%(asctime)s %(levelname)s %(name)s %(message)s'))
- logger.addHandler(handler)
-
-_logged_classes = set()
-def class_logger(cls, enable=False):
- logger = logging.getLogger(cls.__module__ + "." + cls.__name__)
- if enable == 'debug':
- logger.setLevel(logging.DEBUG)
- elif enable == 'info':
- logger.setLevel(logging.INFO)
- cls._should_log_debug = lambda self: logger.isEnabledFor(logging.DEBUG)
- cls._should_log_info = lambda self: logger.isEnabledFor(logging.INFO)
- cls.logger = logger
- _logged_classes.add(cls)
-
-
-class Identified(object):
- logging_name = None
-
- def _should_log_debug(self):
- return self.logger.isEnabledFor(logging.DEBUG)
-
- def _should_log_info(self):
- return self.logger.isEnabledFor(logging.INFO)
-
-class InstanceLogger(object):
- """A logger adapter (wrapper) for :class:`.Identified` subclasses.
-
- This allows multiple instances (e.g. Engine or Pool instances)
- to share a logger, but have its verbosity controlled on a
- per-instance basis.
-
- The basic functionality is to return a logging level
- which is based on an instance's echo setting.
-
- Default implementation is:
-
- 'debug' -> logging.DEBUG
- True -> logging.INFO
- False -> Effective level of underlying logger
- (logging.WARNING by default)
- None -> same as False
- """
-
- # Map echo settings to logger levels
- _echo_map = {
- None: logging.NOTSET,
- False: logging.NOTSET,
- True: logging.INFO,
- 'debug': logging.DEBUG,
- }
-
- def __init__(self, echo, name):
- self.echo = echo
- self.logger = logging.getLogger(name)
-
- # if echo flag is enabled and no handlers,
- # add a handler to the list
- if self._echo_map[echo] <= logging.INFO \
- and not self.logger.handlers:
- _add_default_handler(self.logger)
-
- #
- # Boilerplate convenience methods
- #
- def debug(self, msg, *args, **kwargs):
- """Delegate a debug call to the underlying logger."""
-
- self.log(logging.DEBUG, msg, *args, **kwargs)
-
- def info(self, msg, *args, **kwargs):
- """Delegate an info call to the underlying logger."""
-
- self.log(logging.INFO, msg, *args, **kwargs)
-
- def warning(self, msg, *args, **kwargs):
- """Delegate a warning call to the underlying logger."""
-
- self.log(logging.WARNING, msg, *args, **kwargs)
-
- warn = warning
-
- def error(self, msg, *args, **kwargs):
- """
- Delegate an error call to the underlying logger.
- """
- self.log(logging.ERROR, msg, *args, **kwargs)
-
- def exception(self, msg, *args, **kwargs):
- """Delegate an exception call to the underlying logger."""
-
- kwargs["exc_info"] = 1
- self.log(logging.ERROR, msg, *args, **kwargs)
-
- def critical(self, msg, *args, **kwargs):
- """Delegate a critical call to the underlying logger."""
-
- self.log(logging.CRITICAL, msg, *args, **kwargs)
-
- def log(self, level, msg, *args, **kwargs):
- """Delegate a log call to the underlying logger.
-
- The level here is determined by the echo
- flag as well as that of the underlying logger, and
- logger._log() is called directly.
-
- """
-
- # inline the logic from isEnabledFor(),
- # getEffectiveLevel(), to avoid overhead.
-
- if self.logger.manager.disable >= level:
- return
-
- selected_level = self._echo_map[self.echo]
- if selected_level == logging.NOTSET:
- selected_level = self.logger.getEffectiveLevel()
-
- if level >= selected_level:
- self.logger._log(level, msg, args, **kwargs)
-
- def isEnabledFor(self, level):
- """Is this logger enabled for level 'level'?"""
-
- if self.logger.manager.disable >= level:
- return False
- return level >= self.getEffectiveLevel()
-
- def getEffectiveLevel(self):
- """What's the effective level for this logger?"""
-
- level = self._echo_map[self.echo]
- if level == logging.NOTSET:
- level = self.logger.getEffectiveLevel()
- return level
-
-def instance_logger(instance, echoflag=None):
- """create a logger for an instance that implements :class:`.Identified`."""
-
- if instance.logging_name:
- name = "%s.%s.%s" % (instance.__class__.__module__,
- instance.__class__.__name__, instance.logging_name)
- else:
- name = "%s.%s" % (instance.__class__.__module__,
- instance.__class__.__name__)
-
- instance._echo = echoflag
-
- if echoflag in (False, None):
- # if no echo setting or False, return a Logger directly,
- # avoiding overhead of filtering
- logger = logging.getLogger(name)
- else:
- # if a specified echo flag, return an EchoLogger,
- # which checks the flag, overrides normal log
- # levels by calling logger._log()
- logger = InstanceLogger(echoflag, name)
-
- instance.logger = logger
-
-class echo_property(object):
- __doc__ = """\
- When ``True``, enable log output for this element.
-
- This has the effect of setting the Python logging level for the namespace
- of this element's class and object reference. A value of boolean ``True``
- indicates that the loglevel ``logging.INFO`` will be set for the logger,
- whereas the string value ``debug`` will set the loglevel to
- ``logging.DEBUG``.
- """
-
- def __get__(self, instance, owner):
- if instance is None:
- return self
- else:
- return instance._echo
-
- def __set__(self, instance, value):
- instance_logger(instance, echoflag=value)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/__init__.py
deleted file mode 100755
index 8a0312d5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/__init__.py
+++ /dev/null
@@ -1,1278 +0,0 @@
-# orm/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Functional constructs for ORM configuration.
-
-See the SQLAlchemy object relational tutorial and mapper configuration
-documentation for an overview of how this module is used.
-
-"""
-
-from sqlalchemy.orm import exc
-from sqlalchemy.orm.mapper import (
- Mapper,
- _mapper_registry,
- class_mapper,
- configure_mappers
- )
-from sqlalchemy.orm.interfaces import (
- EXT_CONTINUE,
- EXT_STOP,
- InstrumentationManager,
- MapperExtension,
- PropComparator,
- SessionExtension,
- AttributeExtension,
- )
-from sqlalchemy.orm.util import (
- aliased,
- join,
- object_mapper,
- outerjoin,
- polymorphic_union,
- with_parent,
- )
-from sqlalchemy.orm.properties import (
- ColumnProperty,
- ComparableProperty,
- CompositeProperty,
- RelationshipProperty,
- PropertyLoader,
- SynonymProperty,
- )
-from sqlalchemy.orm import mapper as mapperlib
-from sqlalchemy.orm.mapper import reconstructor, validates
-from sqlalchemy.orm import strategies
-from sqlalchemy.orm.query import AliasOption, Query
-from sqlalchemy.sql import util as sql_util
-from sqlalchemy.orm.session import Session
-from sqlalchemy.orm.session import object_session, sessionmaker, \
- make_transient
-from sqlalchemy.orm.scoping import ScopedSession
-from sqlalchemy import util as sa_util
-
-__all__ = (
- 'EXT_CONTINUE',
- 'EXT_STOP',
- 'InstrumentationManager',
- 'MapperExtension',
- 'AttributeExtension',
- 'PropComparator',
- 'Query',
- 'Session',
- 'aliased',
- 'backref',
- 'class_mapper',
- 'clear_mappers',
- 'column_property',
- 'comparable_property',
- 'compile_mappers',
- 'configure_mappers',
- 'composite',
- 'contains_alias',
- 'contains_eager',
- 'create_session',
- 'defer',
- 'deferred',
- 'dynamic_loader',
- 'eagerload',
- 'eagerload_all',
- 'immediateload',
- 'join',
- 'joinedload',
- 'joinedload_all',
- 'lazyload',
- 'mapper',
- 'make_transient',
- 'noload',
- 'object_mapper',
- 'object_session',
- 'outerjoin',
- 'polymorphic_union',
- 'reconstructor',
- 'relationship',
- 'relation',
- 'scoped_session',
- 'sessionmaker',
- 'subqueryload',
- 'subqueryload_all',
- 'synonym',
- 'undefer',
- 'undefer_group',
- 'validates'
- )
-
-
-def scoped_session(session_factory, scopefunc=None):
- """Provides thread-local or scoped management of :class:`.Session` objects.
-
- This is a front-end function to
- :class:`.ScopedSession`.
-
- :param session_factory: a callable function that produces
- :class:`.Session` instances, such as :func:`sessionmaker`.
-
- :param scopefunc: Optional "scope" function which would be
- passed to the :class:`.ScopedRegistry`. If None, the
- :class:`.ThreadLocalRegistry` is used by default.
-
- :returns: an :class:`.ScopedSession` instance
-
- Usage::
-
- Session = scoped_session(sessionmaker(autoflush=True))
-
- To instantiate a Session object which is part of the scoped context,
- instantiate normally::
-
- session = Session()
-
- Most session methods are available as classmethods from the scoped
- session::
-
- Session.commit()
- Session.close()
-
- """
- return ScopedSession(session_factory, scopefunc=scopefunc)
-
-def create_session(bind=None, **kwargs):
- """Create a new :class:`.Session`
- with no automation enabled by default.
-
- This function is used primarily for testing. The usual
- route to :class:`.Session` creation is via its constructor
- or the :func:`.sessionmaker` function.
-
- :param bind: optional, a single Connectable to use for all
- database access in the created
- :class:`~sqlalchemy.orm.session.Session`.
-
- :param \*\*kwargs: optional, passed through to the
- :class:`.Session` constructor.
-
- :returns: an :class:`~sqlalchemy.orm.session.Session` instance
-
- The defaults of create_session() are the opposite of that of
- :func:`sessionmaker`; ``autoflush`` and ``expire_on_commit`` are
- False, ``autocommit`` is True. In this sense the session acts
- more like the "classic" SQLAlchemy 0.3 session with these.
-
- Usage::
-
- >>> from sqlalchemy.orm import create_session
- >>> session = create_session()
-
- It is recommended to use :func:`sessionmaker` instead of
- create_session().
-
- """
- kwargs.setdefault('autoflush', False)
- kwargs.setdefault('autocommit', True)
- kwargs.setdefault('expire_on_commit', False)
- return Session(bind=bind, **kwargs)
-
-def relationship(argument, secondary=None, **kwargs):
- """Provide a relationship of a primary Mapper to a secondary Mapper.
-
- .. note:: :func:`relationship` is historically known as
- :func:`relation` prior to version 0.6.
-
- This corresponds to a parent-child or associative table relationship. The
- constructed class is an instance of :class:`.RelationshipProperty`.
-
- A typical :func:`relationship`::
-
- mapper(Parent, properties={
- 'children': relationship(Children)
- })
-
- :param argument:
- a class or :class:`.Mapper` instance, representing the target of
- the relationship.
-
- :param secondary:
- for a many-to-many relationship, specifies the intermediary
- table. The *secondary* keyword argument should generally only
- be used for a table that is not otherwise expressed in any class
- mapping. In particular, using the Association Object Pattern is
- generally mutually exclusive with the use of the *secondary*
- keyword argument.
-
- :param active_history=False:
- When ``True``, indicates that the "previous" value for a
- many-to-one reference should be loaded when replaced, if
- not already loaded. Normally, history tracking logic for
- simple many-to-ones only needs to be aware of the "new"
- value in order to perform a flush. This flag is available
- for applications that make use of
- :func:`.attributes.get_history` which also need to know
- the "previous" value of the attribute. (New in 0.6.6)
-
- :param backref:
- indicates the string name of a property to be placed on the related
- mapper's class that will handle this relationship in the other
- direction. The other property will be created automatically
- when the mappers are configured. Can also be passed as a
- :func:`backref` object to control the configuration of the
- new relationship.
-
- :param back_populates:
- Takes a string name and has the same meaning as ``backref``,
- except the complementing property is **not** created automatically,
- and instead must be configured explicitly on the other mapper. The
- complementing property should also indicate ``back_populates``
- to this relationship to ensure proper functioning.
-
- :param cascade:
- a comma-separated list of cascade rules which determines how
- Session operations should be "cascaded" from parent to child.
- This defaults to ``False``, which means the default cascade
- should be used. The default value is ``"save-update, merge"``.
-
- Available cascades are:
-
- * ``save-update`` - cascade the :meth:`.Session.add`
- operation. This cascade applies both to future and
- past calls to :meth:`~sqlalchemy.orm.session.Session.add`,
- meaning new items added to a collection or scalar relationship
- get placed into the same session as that of the parent, and
- also applies to items which have been removed from this
- relationship but are still part of unflushed history.
-
- * ``merge`` - cascade the :meth:`~sqlalchemy.orm.session.Session.merge`
- operation
-
- * ``expunge`` - cascade the :meth:`.Session.expunge`
- operation
-
- * ``delete`` - cascade the :meth:`.Session.delete`
- operation
-
- * ``delete-orphan`` - if an item of the child's type with no
- parent is detected, mark it for deletion. Note that this
- option prevents a pending item of the child's class from being
- persisted without a parent present.
-
- * ``refresh-expire`` - cascade the :meth:`.Session.expire`
- and :meth:`~sqlalchemy.orm.session.Session.refresh` operations
-
- * ``all`` - shorthand for "save-update,merge, refresh-expire,
- expunge, delete"
-
- :param cascade_backrefs=True:
- a boolean value indicating if the ``save-update`` cascade should
- operate along a backref event. When set to ``False`` on a
- one-to-many relationship that has a many-to-one backref, assigning
- a persistent object to the many-to-one attribute on a transient object
- will not add the transient to the session. Similarly, when
- set to ``False`` on a many-to-one relationship that has a one-to-many
- backref, appending a persistent object to the one-to-many collection
- on a transient object will not add the transient to the session.
-
- ``cascade_backrefs`` is new in 0.6.5.
-
- :param collection_class:
- a class or callable that returns a new list-holding object. will
- be used in place of a plain list for storing elements.
- Behavior of this attribute is described in detail at
- :ref:`custom_collections`.
-
- :param comparator_factory:
- a class which extends :class:`.RelationshipProperty.Comparator` which
- provides custom SQL clause generation for comparison operations.
-
- :param doc:
- docstring which will be applied to the resulting descriptor.
-
- :param extension:
- an :class:`.AttributeExtension` instance, or list of extensions,
- which will be prepended to the list of attribute listeners for
- the resulting descriptor placed on the class.
- **Deprecated.** Please see :class:`.AttributeEvents`.
-
- :param foreign_keys:
- a list of columns which are to be used as "foreign key" columns.
- Normally, :func:`relationship` uses the :class:`.ForeignKey`
- and :class:`.ForeignKeyConstraint` objects present within the
- mapped or secondary :class:`.Table` to determine the "foreign" side of
- the join condition. This is used to construct SQL clauses in order
- to load objects, as well as to "synchronize" values from
- primary key columns to referencing foreign key columns.
- The ``foreign_keys`` parameter overrides the notion of what's
- "foreign" in the table metadata, allowing the specification
- of a list of :class:`.Column` objects that should be considered
- part of the foreign key.
-
- There are only two use cases for ``foreign_keys`` - one, when it is not
- convenient for :class:`.Table` metadata to contain its own foreign key
- metadata (which should be almost never, unless reflecting a large amount of
- tables from a MySQL MyISAM schema, or a schema that doesn't actually
- have foreign keys on it). The other is for extremely
- rare and exotic composite foreign key setups where some columns
- should artificially not be considered as foreign.
-
- :param innerjoin=False:
- when ``True``, joined eager loads will use an inner join to join
- against related tables instead of an outer join. The purpose
- of this option is strictly one of performance, as inner joins
- generally perform better than outer joins. This flag can
- be set to ``True`` when the relationship references an object
- via many-to-one using local foreign keys that are not nullable,
- or when the reference is one-to-one or a collection that is
- guaranteed to have one or at least one entry.
-
- :param join_depth:
- when non-``None``, an integer value indicating how many levels
- deep "eager" loaders should join on a self-referring or cyclical
- relationship. The number counts how many times the same Mapper
- shall be present in the loading condition along a particular join
- branch. When left at its default of ``None``, eager loaders
- will stop chaining when they encounter a the same target mapper
- which is already higher up in the chain. This option applies
- both to joined- and subquery- eager loaders.
-
- :param lazy='select': specifies
- how the related items should be loaded. Default value is
- ``select``. Values include:
-
- * ``select`` - items should be loaded lazily when the property is first
- accessed, using a separate SELECT statement, or identity map
- fetch for simple many-to-one references.
-
- * ``immediate`` - items should be loaded as the parents are loaded,
- using a separate SELECT statement, or identity map fetch for
- simple many-to-one references. (new as of 0.6.5)
-
- * ``joined`` - items should be loaded "eagerly" in the same query as
- that of the parent, using a JOIN or LEFT OUTER JOIN. Whether
- the join is "outer" or not is determined by the ``innerjoin``
- parameter.
-
- * ``subquery`` - items should be loaded "eagerly" within the same
- query as that of the parent, using a second SQL statement
- which issues a JOIN to a subquery of the original
- statement.
-
- * ``noload`` - no loading should occur at any time. This is to
- support "write-only" attributes, or attributes which are
- populated in some manner specific to the application.
-
- * ``dynamic`` - the attribute will return a pre-configured
- :class:`~sqlalchemy.orm.query.Query` object for all read
- operations, onto which further filtering operations can be
- applied before iterating the results. The dynamic
- collection supports a limited set of mutation operations,
- allowing ``append()`` and ``remove()``. Changes to the
- collection will not be visible until flushed
- to the database, where it is then refetched upon iteration.
-
- * True - a synonym for 'select'
-
- * False - a synonyn for 'joined'
-
- * None - a synonym for 'noload'
-
- Detailed discussion of loader strategies is at :ref:`loading_toplevel`.
-
- :param load_on_pending=False:
- Indicates loading behavior for transient or pending parent objects.
-
- When set to ``True``, causes the lazy-loader to
- issue a query for a parent object that is not persistent, meaning it has
- never been flushed. This may take effect for a pending object when
- autoflush is disabled, or for a transient object that has been
- "attached" to a :class:`.Session` but is not part of its pending
- collection. Attachment of transient objects to the session without
- moving to the "pending" state is not a supported behavior at this time.
-
- Note that the load of related objects on a pending or transient object
- also does not trigger any attribute change events - no user-defined
- events will be emitted for these attributes, and if and when the
- object is ultimately flushed, only the user-specific foreign key
- attributes will be part of the modified state.
-
- The load_on_pending flag does not improve behavior
- when the ORM is used normally - object references should be constructed
- at the object level, not at the foreign key level, so that they
- are present in an ordinary way before flush() proceeds. This flag
- is not not intended for general use.
-
- New in 0.6.5.
-
- :param order_by:
- indicates the ordering that should be applied when loading these
- items.
-
- :param passive_deletes=False:
- Indicates loading behavior during delete operations.
-
- A value of True indicates that unloaded child items should not
- be loaded during a delete operation on the parent. Normally,
- when a parent item is deleted, all child items are loaded so
- that they can either be marked as deleted, or have their
- foreign key to the parent set to NULL. Marking this flag as
- True usually implies an ON DELETE <CASCADE|SET NULL> rule is in
- place which will handle updating/deleting child rows on the
- database side.
-
- Additionally, setting the flag to the string value 'all' will
- disable the "nulling out" of the child foreign keys, when there
- is no delete or delete-orphan cascade enabled. This is
- typically used when a triggering or error raise scenario is in
- place on the database side. Note that the foreign key
- attributes on in-session child objects will not be changed
- after a flush occurs so this is a very special use-case
- setting.
-
- :param passive_updates=True:
- Indicates loading and INSERT/UPDATE/DELETE behavior when the
- source of a foreign key value changes (i.e. an "on update"
- cascade), which are typically the primary key columns of the
- source row.
-
- When True, it is assumed that ON UPDATE CASCADE is configured on
- the foreign key in the database, and that the database will
- handle propagation of an UPDATE from a source column to
- dependent rows. Note that with databases which enforce
- referential integrity (i.e. PostgreSQL, MySQL with InnoDB tables),
- ON UPDATE CASCADE is required for this operation. The
- relationship() will update the value of the attribute on related
- items which are locally present in the session during a flush.
-
- When False, it is assumed that the database does not enforce
- referential integrity and will not be issuing its own CASCADE
- operation for an update. The relationship() will issue the
- appropriate UPDATE statements to the database in response to the
- change of a referenced key, and items locally present in the
- session during a flush will also be refreshed.
-
- This flag should probably be set to False if primary key changes
- are expected and the database in use doesn't support CASCADE
- (i.e. SQLite, MySQL MyISAM tables).
-
- Also see the passive_updates flag on ``mapper()``.
-
- A future SQLAlchemy release will provide a "detect" feature for
- this flag.
-
- :param post_update:
- this indicates that the relationship should be handled by a
- second UPDATE statement after an INSERT or before a
- DELETE. Currently, it also will issue an UPDATE after the
- instance was UPDATEd as well, although this technically should
- be improved. This flag is used to handle saving bi-directional
- dependencies between two individual rows (i.e. each row
- references the other), where it would otherwise be impossible to
- INSERT or DELETE both rows fully since one row exists before the
- other. Use this flag when a particular mapping arrangement will
- incur two rows that are dependent on each other, such as a table
- that has a one-to-many relationship to a set of child rows, and
- also has a column that references a single child row within that
- list (i.e. both tables contain a foreign key to each other). If
- a ``flush()`` operation returns an error that a "cyclical
- dependency" was detected, this is a cue that you might want to
- use ``post_update`` to "break" the cycle.
-
- :param primaryjoin:
- a ColumnElement (i.e. WHERE criterion) that will be used as the primary
- join of this child object against the parent object, or in a
- many-to-many relationship the join of the primary object to the
- association table. By default, this value is computed based on the
- foreign key relationships of the parent and child tables (or association
- table).
-
- :param remote_side:
- used for self-referential relationships, indicates the column or
- list of columns that form the "remote side" of the relationship.
-
- :param secondaryjoin:
- a ColumnElement (i.e. WHERE criterion) that will be used as the join of
- an association table to the child object. By default, this value is
- computed based on the foreign key relationships of the association and
- child tables.
-
- :param single_parent=(True|False):
- when True, installs a validator which will prevent objects
- from being associated with more than one parent at a time.
- This is used for many-to-one or many-to-many relationships that
- should be treated either as one-to-one or one-to-many. Its
- usage is optional unless delete-orphan cascade is also
- set on this relationship(), in which case its required (new in 0.5.2).
-
- :param uselist=(True|False):
- a boolean that indicates if this property should be loaded as a
- list or a scalar. In most cases, this value is determined
- automatically by ``relationship()``, based on the type and direction
- of the relationship - one to many forms a list, many to one
- forms a scalar, many to many is a list. If a scalar is desired
- where normally a list would be present, such as a bi-directional
- one-to-one relationship, set uselist to False.
-
- :param viewonly=False:
- when set to True, the relationship is used only for loading objects
- within the relationship, and has no effect on the unit-of-work
- flush process. Relationships with viewonly can specify any kind of
- join conditions to provide additional views of related objects
- onto a parent object. Note that the functionality of a viewonly
- relationship has its limits - complicated join conditions may
- not compile into eager or lazy loaders properly. If this is the
- case, use an alternative method.
-
- """
- return RelationshipProperty(argument, secondary=secondary, **kwargs)
-
-def relation(*arg, **kw):
- """A synonym for :func:`relationship`."""
-
- return relationship(*arg, **kw)
-
-def dynamic_loader(argument, **kw):
- """Construct a dynamically-loading mapper property.
-
- This is essentially the same as
- using the ``lazy='dynamic'`` argument with :func:`relationship`::
-
- dynamic_loader(SomeClass)
-
- # vs.
-
- relationship(SomeClass, lazy="dynamic")
-
- A :func:`relationship` that is "dynamic" features the behavior
- that read operations return an active :class:`.Query` object which
- reads from the database when accessed. Items may be appended to the
- attribute via ``append()``, or removed via ``remove()``; changes will be
- persisted to the database during a :meth:`Sesion.flush`. However, no other
- Python list or collection mutation operations are available.
-
- All arguments accepted by :func:`relationship` are
- accepted here, other than ``lazy`` which is fixed at ``dynamic``.
-
- """
- kw['lazy'] = 'dynamic'
- return relationship(argument, **kw)
-
-def column_property(*args, **kwargs):
- """Provide a column-level property for use with a Mapper.
-
- Column-based properties can normally be applied to the mapper's
- ``properties`` dictionary using the :class:`.Column` element directly.
- Use this function when the given column is not directly present within the
- mapper's selectable; examples include SQL expressions, functions, and
- scalar SELECT queries.
-
- Columns that aren't present in the mapper's selectable won't be persisted
- by the mapper and are effectively "read-only" attributes.
-
- :param \*cols:
- list of Column objects to be mapped.
-
- :param active_history=False:
- When ``True``, indicates that the "previous" value for a
- scalar attribute should be loaded when replaced, if not
- already loaded. Normally, history tracking logic for
- simple non-primary-key scalar values only needs to be
- aware of the "new" value in order to perform a flush. This
- flag is available for applications that make use of
- :func:`.attributes.get_history` which also need to know
- the "previous" value of the attribute. (new in 0.6.6)
-
- :param comparator_factory: a class which extends
- :class:`.ColumnProperty.Comparator` which provides custom SQL clause
- generation for comparison operations.
-
- :param group:
- a group name for this property when marked as deferred.
-
- :param deferred:
- when True, the column property is "deferred", meaning that
- it does not load immediately, and is instead loaded when the
- attribute is first accessed on an instance. See also
- :func:`~sqlalchemy.orm.deferred`.
-
- :param doc:
- optional string that will be applied as the doc on the
- class-bound descriptor.
-
- :param extension:
- an
- :class:`.AttributeExtension`
- instance, or list of extensions, which will be prepended
- to the list of attribute listeners for the resulting
- descriptor placed on the class.
- **Deprecated.** Please see :class:`.AttributeEvents`.
-
-
- """
-
- return ColumnProperty(*args, **kwargs)
-
-def composite(class_, *cols, **kwargs):
- """Return a composite column-based property for use with a Mapper.
-
- See the mapping documention section :ref:`mapper_composite` for a full
- usage example.
-
- :param class\_:
- The "composite type" class.
-
- :param \*cols:
- List of Column objects to be mapped.
-
- :param active_history=False:
- When ``True``, indicates that the "previous" value for a
- scalar attribute should be loaded when replaced, if not
- already loaded. See the same flag on :func:`.column_property`.
- (This flag becomes meaningful specifically for
- :func:`.composite` in 0.7 - previously it was a placeholder).
-
- :param group:
- A group name for this property when marked as deferred.
-
- :param deferred:
- When True, the column property is "deferred", meaning that it does not
- load immediately, and is instead loaded when the attribute is first
- accessed on an instance. See also :func:`~sqlalchemy.orm.deferred`.
-
- :param comparator_factory: a class which extends
- :class:`.CompositeProperty.Comparator` which provides custom SQL clause
- generation for comparison operations.
-
- :param doc:
- optional string that will be applied as the doc on the
- class-bound descriptor.
-
- :param extension:
- an :class:`.AttributeExtension` instance,
- or list of extensions, which will be prepended to the list of
- attribute listeners for the resulting descriptor placed on the class.
- **Deprecated.** Please see :class:`.AttributeEvents`.
-
- """
- return CompositeProperty(class_, *cols, **kwargs)
-
-
-def backref(name, **kwargs):
- """Create a back reference with explicit keyword arguments, which are the same
- arguments one can send to :func:`relationship`.
-
- Used with the ``backref`` keyword argument to :func:`relationship` in
- place of a string argument, e.g.::
-
- 'items':relationship(SomeItem, backref=backref('parent', lazy='subquery'))
-
- """
- return (name, kwargs)
-
-def deferred(*columns, **kwargs):
- """Return a :class:`.DeferredColumnProperty`, which indicates this
- object attributes should only be loaded from its corresponding
- table column when first accessed.
-
- Used with the `properties` dictionary sent to :func:`mapper`.
-
- """
- return ColumnProperty(deferred=True, *columns, **kwargs)
-
-def mapper(class_, local_table=None, *args, **params):
- """Return a new :class:`~.Mapper` object.
-
- :param class\_: The class to be mapped.
-
- :param local_table: The table to which the class is mapped, or None if
- this mapper inherits from another mapper using concrete table
- inheritance.
-
- :param always_refresh: If True, all query operations for this mapped
- class will overwrite all data within object instances that already
- exist within the session, erasing any in-memory changes with
- whatever information was loaded from the database. Usage of this
- flag is highly discouraged; as an alternative, see the method
- :meth:`.Query.populate_existing`.
-
- :param allow_null_pks: This flag is deprecated - this is stated as
- allow_partial_pks which defaults to True.
-
- :param allow_partial_pks: Defaults to True. Indicates that a
- composite primary key with some NULL values should be considered as
- possibly existing within the database. This affects whether a
- mapper will assign an incoming row to an existing identity, as well
- as if :meth:`.Session.merge` will check the database first for a
- particular primary key value. A "partial primary key" can occur if
- one has mapped to an OUTER JOIN, for example.
-
- :param batch: Indicates that save operations of multiple entities
- can be batched together for efficiency. setting to False indicates
- that an instance will be fully saved before saving the next
- instance, which includes inserting/updating all table rows
- corresponding to the entity as well as calling all
- :class:`.MapperExtension` methods corresponding to the save
- operation.
-
- :param column_prefix: A string which will be prepended to the `key`
- name of all :class:`.Column` objects when creating
- column-based properties from the
- given :class:`.Table`. Does not affect explicitly specified
- column-based properties
-
- :param concrete: If True, indicates this mapper should use concrete
- table inheritance with its parent mapper.
-
- :param exclude_properties: A list or set of string column names to
- be excluded from mapping. As of SQLAlchemy 0.6.4, this collection
- may also include :class:`.Column` objects. Columns named or present
- in this list will not be automatically mapped. Note that neither
- this option nor include_properties will allow one to circumvent plan
- Python inheritance - if mapped class ``B`` inherits from mapped
- class ``A``, no combination of includes or excludes will allow ``B``
- to have fewer properties than its superclass, ``A``.
-
- :param extension: A :class:`.MapperExtension` instance or
- list of :class:`.MapperExtension`
- instances which will be applied to all operations by this
- :class:`.Mapper`. **Deprecated.** Please see :class:`.MapperEvents`.
-
- :param include_properties: An inclusive list or set of string column
- names to map. As of SQLAlchemy 0.6.4, this collection may also
- include :class:`.Column` objects in order to disambiguate between
- same-named columns in a selectable (such as a
- :func:`~.expression.join()`). If this list is not ``None``, columns
- present in the mapped table but not named or present in this list
- will not be automatically mapped. See also "exclude_properties".
-
- :param inherits: Another :class:`.Mapper` for which
- this :class:`.Mapper` will have an inheritance
- relationship with.
-
- :param inherit_condition: For joined table inheritance, a SQL
- expression (constructed
- :class:`.ClauseElement`) which will
- define how the two tables are joined; defaults to a natural join
- between the two tables.
-
- :param inherit_foreign_keys: When inherit_condition is used and the
- condition contains no ForeignKey columns, specify the "foreign"
- columns of the join condition in this list. else leave as None.
-
- :param non_primary: Construct a :class:`.Mapper` that will define only
- the selection of instances, not their persistence. Any number of
- non_primary mappers may be created for a particular class.
-
- :param order_by: A single :class:`.Column` or list of :class:`.Column`
- objects for which selection operations should use as the default
- ordering for entities. Defaults to the OID/ROWID of the table if
- any, or the first primary key column of the table.
-
- :param passive_updates: Indicates UPDATE behavior of foreign keys
- when a primary key changes on a joined-table inheritance or other
- joined table mapping.
-
- When True, it is assumed that ON UPDATE CASCADE is configured on
- the foreign key in the database, and that the database will handle
- propagation of an UPDATE from a source column to dependent rows.
- Note that with databases which enforce referential integrity (i.e.
- PostgreSQL, MySQL with InnoDB tables), ON UPDATE CASCADE is
- required for this operation. The relationship() will update the
- value of the attribute on related items which are locally present
- in the session during a flush.
-
- When False, it is assumed that the database does not enforce
- referential integrity and will not be issuing its own CASCADE
- operation for an update. The relationship() will issue the
- appropriate UPDATE statements to the database in response to the
- change of a referenced key, and items locally present in the
- session during a flush will also be refreshed.
-
- This flag should probably be set to False if primary key changes
- are expected and the database in use doesn't support CASCADE (i.e.
- SQLite, MySQL MyISAM tables).
-
- Also see the passive_updates flag on :func:`relationship()`.
-
- A future SQLAlchemy release will provide a "detect" feature for
- this flag.
-
- :param polymorphic_on: Used with mappers in an inheritance
- relationship, a :class:`.Column` which will identify the class/mapper
- combination to be used with a particular row. Requires the
- ``polymorphic_identity`` value to be set for all mappers in the
- inheritance hierarchy. The column specified by ``polymorphic_on``
- is usually a column that resides directly within the base mapper's
- mapped table; alternatively, it may be a column that is only
- present within the <selectable> portion of the ``with_polymorphic``
- argument.
-
- :param polymorphic_identity: A value which will be stored in the
- Column denoted by polymorphic_on, corresponding to the class
- identity of this mapper.
-
- :param properties: A dictionary mapping the string names of object
- attributes to ``MapperProperty`` instances, which define the
- persistence behavior of that attribute. Note that the columns in
- the mapped table are automatically converted into
- ``ColumnProperty`` instances based on the ``key`` property of each
- :class:`.Column` (although they can be overridden using this dictionary).
-
- :param primary_key: A list of :class:`.Column` objects which define the
- primary key to be used against this mapper's selectable unit.
- This is normally simply the primary key of the ``local_table``, but
- can be overridden here.
-
- :param version_id_col: A :class:`.Column` which must have an integer type
- that will be used to keep a running version id of mapped entities
- in the database. this is used during save operations to ensure that
- no other thread or process has updated the instance during the
- lifetime of the entity, else a :class:`.StaleDataError` exception is
- thrown.
-
- :param version_id_generator: A callable which defines the algorithm
- used to generate new version ids. Defaults to an integer
- generator. Can be replaced with one that generates timestamps,
- uuids, etc. e.g.::
-
- import uuid
-
- mapper(Cls, table,
- version_id_col=table.c.version_uuid,
- version_id_generator=lambda version:uuid.uuid4().hex
- )
-
- The callable receives the current version identifier as its
- single argument.
-
- :param with_polymorphic: A tuple in the form ``(<classes>,
- <selectable>)`` indicating the default style of "polymorphic"
- loading, that is, which tables are queried at once. <classes> is
- any single or list of mappers and/or classes indicating the
- inherited classes that should be loaded at once. The special value
- ``'*'`` may be used to indicate all descending classes should be
- loaded immediately. The second tuple argument <selectable>
- indicates a selectable that will be used to query for multiple
- classes. Normally, it is left as None, in which case this mapper
- will form an outer join from the base mapper's table to that of
- all desired sub-mappers. When specified, it provides the
- selectable to be used for polymorphic loading. When
- with_polymorphic includes mappers which load from a "concrete"
- inheriting table, the <selectable> argument is required, since it
- usually requires more complex UNION queries.
-
- """
- return Mapper(class_, local_table, *args, **params)
-
-def synonym(name, map_column=False, descriptor=None,
- comparator_factory=None, doc=None):
- """Denote an attribute name as a synonym to a mapped property.
-
- .. note:: :func:`.synonym` is superseded as of 0.7 by
- the :mod:`~sqlalchemy.ext.hybrid` extension. See
- the documentation for hybrids at :ref:`hybrids_toplevel`.
-
- Used with the ``properties`` dictionary sent to
- :func:`~sqlalchemy.orm.mapper`::
-
- class MyClass(object):
- def _get_status(self):
- return self._status
- def _set_status(self, value):
- self._status = value
- status = property(_get_status, _set_status)
-
- mapper(MyClass, sometable, properties={
- "status":synonym("_status", map_column=True)
- })
-
- Above, the ``status`` attribute of MyClass will produce
- expression behavior against the table column named ``status``,
- using the Python attribute ``_status`` on the mapped class
- to represent the underlying value.
-
- :param name: the name of the existing mapped property, which can be
- any other ``MapperProperty`` including column-based properties and
- relationships.
-
- :param map_column: if ``True``, an additional ``ColumnProperty`` is created
- on the mapper automatically, using the synonym's name as the keyname of
- the property, and the keyname of this ``synonym()`` as the name of the
- column to map.
-
- """
- return SynonymProperty(name, map_column=map_column,
- descriptor=descriptor,
- comparator_factory=comparator_factory,
- doc=doc)
-
-def comparable_property(comparator_factory, descriptor=None):
- """Provides a method of applying a :class:`.PropComparator`
- to any Python descriptor attribute.
-
- .. note:: :func:`.comparable_property` is superseded as of 0.7 by
- the :mod:`~sqlalchemy.ext.hybrid` extension. See the example
- at :ref:`hybrid_custom_comparators`.
-
- Allows a regular Python @property (descriptor) to be used in queries and
- SQL constructs like a managed attribute. comparable_property wraps a
- descriptor with a proxy that directs operator overrides such as ==
- (__eq__) to the supplied comparator but proxies everything else through to
- the original descriptor. Used with the ``properties`` dictionary sent to
- :func:`~sqlalchemy.orm.mapper`::
-
- from sqlalchemy.orm import mapper, comparable_property
- from sqlalchemy.orm.interfaces import PropComparator
- from sqlalchemy.sql import func
- from sqlalchemy import Table, MetaData, Integer, String, Column
-
- metadata = MetaData()
-
- word_table = Table('word', metadata,
- Column('id', Integer, primary_key=True),
- Column('word', String(200), nullable=False)
- )
-
- class CaseInsensitiveComparator(PropComparator):
- def __clause_element__(self):
- return self.prop
-
- def __eq__(self, other):
- return func.lower(self.__clause_element__()) == func.lower(other)
-
- class SearchWord(object):
- pass
-
- mapper(SearchWord, word_table, properties={
- 'word_insensitive': comparable_property(CaseInsensitiveComparator)
- })
-
- A mapping like the above allows the ``word_insensitive`` attribute
- to render an expression like::
-
- >>> print SearchWord.word_insensitive == "Trucks"
- lower(:lower_1) = lower(:lower_2)
-
- :param comparator_factory:
- A PropComparator subclass or factory that defines operator behavior
- for this property.
-
- :param descriptor:
- Optional when used in a ``properties={}`` declaration. The Python
- descriptor or property to layer comparison behavior on top of.
-
- The like-named descriptor will be automatically retreived from the
- mapped class if left blank in a ``properties`` declaration.
-
- """
- return ComparableProperty(comparator_factory, descriptor)
-
-@sa_util.deprecated("0.7", message=":func:`.compile_mappers` "
- "is renamed to :func:`.configure_mappers`")
-def compile_mappers():
- """Initialize the inter-mapper relationships of all mappers that have been defined."""
-
- configure_mappers()
-
-def clear_mappers():
- """Remove all mappers from all classes.
-
- This function removes all instrumentation from classes and disposes
- of their associated mappers. Once called, the classes are unmapped
- and can be later re-mapped with new mappers.
-
- :func:`.clear_mappers` is *not* for normal use, as there is literally no
- valid usage for it outside of very specific testing scenarios. Normally,
- mappers are permanent structural components of user-defined classes, and
- are never discarded independently of their class. If a mapped class itself
- is garbage collected, its mapper is automatically disposed of as well. As
- such, :func:`.clear_mappers` is only for usage in test suites that re-use
- the same classes with different mappings, which is itself an extremely rare
- use case - the only such use case is in fact SQLAlchemy's own test suite,
- and possibly the test suites of other ORM extension libraries which
- intend to test various combinations of mapper construction upon a fixed
- set of classes.
-
- """
- mapperlib._COMPILE_MUTEX.acquire()
- try:
- while _mapper_registry:
- try:
- # can't even reliably call list(weakdict) in jython
- mapper, b = _mapper_registry.popitem()
- mapper.dispose()
- except KeyError:
- pass
- finally:
- mapperlib._COMPILE_MUTEX.release()
-
-def joinedload(*keys, **kw):
- """Return a ``MapperOption`` that will convert the property of the given
- name or series of mapped attributes into an joined eager load.
-
- .. note:: This function is known as :func:`eagerload` in all versions
- of SQLAlchemy prior to version 0.6beta3, including the 0.5 and 0.4
- series. :func:`eagerload` will remain available for the foreseeable
- future in order to enable cross-compatibility.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- examples::
-
- # joined-load the "orders" colleciton on "User"
- query(User).options(joinedload(User.orders))
-
- # joined-load the "keywords" collection on each "Item",
- # but not the "items" collection on "Order" - those
- # remain lazily loaded.
- query(Order).options(joinedload(Order.items, Item.keywords))
-
- # to joined-load across both, use joinedload_all()
- query(Order).options(joinedload_all(Order.items, Item.keywords))
-
- :func:`joinedload` also accepts a keyword argument `innerjoin=True` which
- indicates using an inner join instead of an outer::
-
- query(Order).options(joinedload(Order.user, innerjoin=True))
-
- Note that the join created by :func:`joinedload` is aliased such that no
- other aspects of the query will affect what it loads. To use joined eager
- loading with a join that is constructed manually using
- :meth:`~sqlalchemy.orm.query.Query.join` or :func:`~sqlalchemy.orm.join`,
- see :func:`contains_eager`.
-
- See also: :func:`subqueryload`, :func:`lazyload`
-
- """
- innerjoin = kw.pop('innerjoin', None)
- if innerjoin is not None:
- return (
- strategies.EagerLazyOption(keys, lazy='joined'),
- strategies.EagerJoinOption(keys, innerjoin)
- )
- else:
- return strategies.EagerLazyOption(keys, lazy='joined')
-
-def joinedload_all(*keys, **kw):
- """Return a ``MapperOption`` that will convert all properties along the
- given dot-separated path or series of mapped attributes
- into an joined eager load.
-
- .. note:: This function is known as :func:`eagerload_all` in all versions
- of SQLAlchemy prior to version 0.6beta3, including the 0.5 and 0.4
- series. :func:`eagerload_all` will remain available for the
- foreseeable future in order to enable cross-compatibility.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- For example::
-
- query.options(joinedload_all('orders.items.keywords'))...
-
- will set all of 'orders', 'orders.items', and 'orders.items.keywords' to
- load in one joined eager load.
-
- Individual descriptors are accepted as arguments as well::
-
- query.options(joinedload_all(User.orders, Order.items, Item.keywords))
-
- The keyword arguments accept a flag `innerjoin=True|False` which will
- override the value of the `innerjoin` flag specified on the
- relationship().
-
- See also: :func:`subqueryload_all`, :func:`lazyload`
-
- """
- innerjoin = kw.pop('innerjoin', None)
- if innerjoin is not None:
- return (
- strategies.EagerLazyOption(keys, lazy='joined', chained=True),
- strategies.EagerJoinOption(keys, innerjoin, chained=True)
- )
- else:
- return strategies.EagerLazyOption(keys, lazy='joined', chained=True)
-
-def eagerload(*args, **kwargs):
- """A synonym for :func:`joinedload()`."""
- return joinedload(*args, **kwargs)
-
-def eagerload_all(*args, **kwargs):
- """A synonym for :func:`joinedload_all()`"""
- return joinedload_all(*args, **kwargs)
-
-def subqueryload(*keys):
- """Return a ``MapperOption`` that will convert the property
- of the given name or series of mapped attributes
- into an subquery eager load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- examples::
-
- # subquery-load the "orders" colleciton on "User"
- query(User).options(subqueryload(User.orders))
-
- # subquery-load the "keywords" collection on each "Item",
- # but not the "items" collection on "Order" - those
- # remain lazily loaded.
- query(Order).options(subqueryload(Order.items, Item.keywords))
-
- # to subquery-load across both, use subqueryload_all()
- query(Order).options(subqueryload_all(Order.items, Item.keywords))
-
- See also: :func:`joinedload`, :func:`lazyload`
-
- """
- return strategies.EagerLazyOption(keys, lazy="subquery")
-
-def subqueryload_all(*keys):
- """Return a ``MapperOption`` that will convert all properties along the
- given dot-separated path or series of mapped attributes
- into a subquery eager load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- For example::
-
- query.options(subqueryload_all('orders.items.keywords'))...
-
- will set all of 'orders', 'orders.items', and 'orders.items.keywords' to
- load in one subquery eager load.
-
- Individual descriptors are accepted as arguments as well::
-
- query.options(subqueryload_all(User.orders, Order.items,
- Item.keywords))
-
- See also: :func:`joinedload_all`, :func:`lazyload`, :func:`immediateload`
-
- """
- return strategies.EagerLazyOption(keys, lazy="subquery", chained=True)
-
-def lazyload(*keys):
- """Return a ``MapperOption`` that will convert the property of the given
- name or series of mapped attributes into a lazy load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- See also: :func:`eagerload`, :func:`subqueryload`, :func:`immediateload`
-
- """
- return strategies.EagerLazyOption(keys, lazy=True)
-
-def lazyload_all(*keys):
- """Return a ``MapperOption`` that will convert all the properties
- along the given dot-separated path or series of mapped attributes
- into a lazy load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- See also: :func:`eagerload`, :func:`subqueryload`, :func:`immediateload`
-
- """
- return strategies.EagerLazyOption(keys, lazy=True, chained=True)
-
-def noload(*keys):
- """Return a ``MapperOption`` that will convert the property of the
- given name or series of mapped attributes into a non-load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- See also: :func:`lazyload`, :func:`eagerload`,
- :func:`subqueryload`, :func:`immediateload`
-
- """
- return strategies.EagerLazyOption(keys, lazy=None)
-
-def immediateload(*keys):
- """Return a ``MapperOption`` that will convert the property of the given
- name or series of mapped attributes into an immediate load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- See also: :func:`lazyload`, :func:`eagerload`, :func:`subqueryload`
-
- New as of verison 0.6.5.
-
- """
- return strategies.EagerLazyOption(keys, lazy='immediate')
-
-def contains_alias(alias):
- """Return a ``MapperOption`` that will indicate to the query that
- the main table has been aliased.
-
- `alias` is the string name or ``Alias`` object representing the
- alias.
-
- """
- return AliasOption(alias)
-
-def contains_eager(*keys, **kwargs):
- """Return a ``MapperOption`` that will indicate to the query that
- the given attribute should be eagerly loaded from columns currently
- in the query.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- The option is used in conjunction with an explicit join that loads
- the desired rows, i.e.::
-
- sess.query(Order).\\
- join(Order.user).\\
- options(contains_eager(Order.user))
-
- The above query would join from the ``Order`` entity to its related
- ``User`` entity, and the returned ``Order`` objects would have the
- ``Order.user`` attribute pre-populated.
-
- :func:`contains_eager` also accepts an `alias` argument, which is the
- string name of an alias, an :func:`~sqlalchemy.sql.expression.alias`
- construct, or an :func:`~sqlalchemy.orm.aliased` construct. Use this when
- the eagerly-loaded rows are to come from an aliased table::
-
- user_alias = aliased(User)
- sess.query(Order).\\
- join((user_alias, Order.user)).\\
- options(contains_eager(Order.user, alias=user_alias))
-
- See also :func:`eagerload` for the "automatic" version of this
- functionality.
-
- For additional examples of :func:`contains_eager` see
- :ref:`contains_eager`.
-
- """
- alias = kwargs.pop('alias', None)
- if kwargs:
- raise exceptions.ArgumentError('Invalid kwargs for contains_eag'
- 'er: %r' % kwargs.keys())
- return strategies.EagerLazyOption(keys, lazy='joined',
- propagate_to_loaders=False, chained=True), \
- strategies.LoadEagerFromAliasOption(keys, alias=alias, chained=True)
-
-def defer(*keys):
- """Return a ``MapperOption`` that will convert the column property of the
- given name into a deferred load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- """
- return strategies.DeferredOption(keys, defer=True)
-
-def undefer(*keys):
- """Return a ``MapperOption`` that will convert the column property of the
- given name into a non-deferred (regular column) load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- """
- return strategies.DeferredOption(keys, defer=False)
-
-def undefer_group(name):
- """Return a ``MapperOption`` that will convert the given group of deferred
- column properties into a non-deferred (regular column) load.
-
- Used with :meth:`~sqlalchemy.orm.query.Query.options`.
-
- """
- return strategies.UndeferGroupOption(name)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/attributes.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/attributes.py
deleted file mode 100755
index ba262266..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/attributes.py
+++ /dev/null
@@ -1,1335 +0,0 @@
-# orm/attributes.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Defines instrumentation for class attributes and their interaction
-with instances.
-
-This module is usually not directly visible to user applications, but
-defines a large part of the ORM's interactivity.
-
-
-"""
-
-import operator
-from operator import itemgetter
-
-from sqlalchemy import util, event, exc as sa_exc
-from sqlalchemy.orm import interfaces, collections, events
-
-
-mapperutil = util.importlater("sqlalchemy.orm", "util")
-
-PASSIVE_NO_RESULT = util.symbol('PASSIVE_NO_RESULT')
-ATTR_WAS_SET = util.symbol('ATTR_WAS_SET')
-ATTR_EMPTY = util.symbol('ATTR_EMPTY')
-NO_VALUE = util.symbol('NO_VALUE')
-NEVER_SET = util.symbol('NEVER_SET')
-
-PASSIVE_RETURN_NEVER_SET = util.symbol('PASSIVE_RETURN_NEVER_SET'
-"""Symbol indicating that a 'default' value, i.e. None or blank
-collection, should not be assigned to an attribute when a get()
-is performed and no value was present. NEVER_SET is returned
-instead.
-""")
-
-PASSIVE_NO_INITIALIZE = util.symbol('PASSIVE_NO_INITIALIZE',
-"""Symbol indicating that loader callables should
- not be fired off, and a non-initialized attribute
- should remain that way.
-""")
-
-PASSIVE_NO_FETCH = util.symbol('PASSIVE_NO_FETCH',
-"""Symbol indicating that loader callables should not emit SQL,
- but a value can be fetched from the current session.
-
- Non-initialized attributes should be initialized to an empty value.
-
-""")
-
-PASSIVE_NO_FETCH_RELATED = util.symbol('PASSIVE_NO_FETCH_RELATED',
-"""Symbol indicating that loader callables should not emit SQL for
- loading a related object, but can refresh the attributes of the local
- instance in order to locate a related object in the current session.
-
- Non-initialized attributes should be initialized to an empty value.
-
- The unit of work uses this mode to check if history is present
- on many-to-one attributes with minimal SQL emitted.
-
-""")
-
-PASSIVE_ONLY_PERSISTENT = util.symbol('PASSIVE_ONLY_PERSISTENT',
-"""Symbol indicating that loader callables should only fire off for
- parent objects which are persistent (i.e., have a database
- identity).
-
- Load operations for the "previous" value of an attribute make
- use of this flag during change events.
-
-""")
-
-PASSIVE_OFF = util.symbol('PASSIVE_OFF',
-"""Symbol indicating that loader callables should be executed
- normally.
-
-""")
-
-
-class QueryableAttribute(interfaces.PropComparator):
- """Base class for class-bound attributes. """
-
- def __init__(self, class_, key, impl=None,
- comparator=None, parententity=None):
- self.class_ = class_
- self.key = key
- self.impl = impl
- self.comparator = comparator
- self.parententity = parententity
-
- manager = manager_of_class(class_)
- # manager is None in the case of AliasedClass
- if manager:
- # propagate existing event listeners from
- # immediate superclass
- for base in manager._bases:
- if key in base:
- self.dispatch._update(base[key].dispatch)
-
- dispatch = event.dispatcher(events.AttributeEvents)
- dispatch.dispatch_cls._active_history = False
-
- @util.memoized_property
- def _supports_population(self):
- return self.impl.supports_population
-
- def get_history(self, instance, passive=PASSIVE_OFF):
- return self.impl.get_history(instance_state(instance),
- instance_dict(instance), passive)
-
- def __selectable__(self):
- # TODO: conditionally attach this method based on clause_element ?
- return self
-
- def __clause_element__(self):
- return self.comparator.__clause_element__()
-
- def label(self, name):
- return self.__clause_element__().label(name)
-
- def operate(self, op, *other, **kwargs):
- return op(self.comparator, *other, **kwargs)
-
- def reverse_operate(self, op, other, **kwargs):
- return op(other, self.comparator, **kwargs)
-
- def hasparent(self, state, optimistic=False):
- return self.impl.hasparent(state, optimistic=optimistic)
-
- def __getattr__(self, key):
- try:
- return getattr(self.comparator, key)
- except AttributeError:
- raise AttributeError(
- 'Neither %r object nor %r object has an attribute %r' % (
- type(self).__name__,
- type(self.comparator).__name__,
- key)
- )
-
- def __str__(self):
- return "%s.%s" % (self.class_.__name__, self.key)
-
- @util.memoized_property
- def property(self):
- return self.comparator.property
-
-
-class InstrumentedAttribute(QueryableAttribute):
- """Class bound instrumented attribute which adds descriptor methods."""
-
- def __set__(self, instance, value):
- self.impl.set(instance_state(instance),
- instance_dict(instance), value, None)
-
- def __delete__(self, instance):
- self.impl.delete(instance_state(instance), instance_dict(instance))
-
- def __get__(self, instance, owner):
- if instance is None:
- return self
-
- dict_ = instance_dict(instance)
- if self._supports_population and self.key in dict_:
- return dict_[self.key]
- else:
- return self.impl.get(instance_state(instance),dict_)
-
-def create_proxied_attribute(descriptor):
- """Create an QueryableAttribute / user descriptor hybrid.
-
- Returns a new QueryableAttribute type that delegates descriptor
- behavior and getattr() to the given descriptor.
- """
-
- # TODO: can move this to descriptor_props if the need for this
- # function is removed from ext/hybrid.py
-
- class Proxy(QueryableAttribute):
- """Presents the :class:`.QueryableAttribute` interface as a
- proxy on top of a Python descriptor / :class:`.PropComparator`
- combination.
-
- """
-
- def __init__(self, class_, key, descriptor, comparator,
- adapter=None, doc=None):
- self.class_ = class_
- self.key = key
- self.descriptor = descriptor
- self._comparator = comparator
- self.adapter = adapter
- self.__doc__ = doc
-
- @util.memoized_property
- def comparator(self):
- if util.callable(self._comparator):
- self._comparator = self._comparator()
- if self.adapter:
- self._comparator = self._comparator.adapted(self.adapter)
- return self._comparator
-
- def adapted(self, adapter):
- """Proxy adapted() for the use case of AliasedClass calling adapted."""
-
- return self.__class__(self.class_, self.key, self.descriptor,
- self._comparator,
- adapter)
-
- def __get__(self, instance, owner):
- if instance is None:
- return self
- else:
- return self.descriptor.__get__(instance, owner)
-
- def __str__(self):
- return self.key
-
- def __getattr__(self, attribute):
- """Delegate __getattr__ to the original descriptor and/or
- comparator."""
-
- try:
- return getattr(descriptor, attribute)
- except AttributeError:
- try:
- return getattr(self.comparator, attribute)
- except AttributeError:
- raise AttributeError(
- 'Neither %r object nor %r object has an attribute %r' % (
- type(descriptor).__name__,
- type(self.comparator).__name__,
- attribute)
- )
-
- Proxy.__name__ = type(descriptor).__name__ + 'Proxy'
-
- util.monkeypatch_proxied_specials(Proxy, type(descriptor),
- name='descriptor',
- from_instance=descriptor)
- return Proxy
-
-class AttributeImpl(object):
- """internal implementation for instrumented attributes."""
-
- def __init__(self, class_, key,
- callable_, dispatch, trackparent=False, extension=None,
- compare_function=None, active_history=False,
- parent_token=None, expire_missing=True,
- **kwargs):
- """Construct an AttributeImpl.
-
- \class_
- associated class
-
- key
- string name of the attribute
-
- \callable_
- optional function which generates a callable based on a parent
- instance, which produces the "default" values for a scalar or
- collection attribute when it's first accessed, if not present
- already.
-
- trackparent
- if True, attempt to track if an instance has a parent attached
- to it via this attribute.
-
- extension
- a single or list of AttributeExtension object(s) which will
- receive set/delete/append/remove/etc. events. Deprecated.
- The event package is now used.
-
- compare_function
- a function that compares two values which are normally
- assignable to this attribute.
-
- active_history
- indicates that get_history() should always return the "old" value,
- even if it means executing a lazy callable upon attribute change.
-
- parent_token
- Usually references the MapperProperty, used as a key for
- the hasparent() function to identify an "owning" attribute.
- Allows multiple AttributeImpls to all match a single
- owner attribute.
-
- expire_missing
- if False, don't add an "expiry" callable to this attribute
- during state.expire_attributes(None), if no value is present
- for this key.
-
- """
- self.class_ = class_
- self.key = key
- self.callable_ = callable_
- self.dispatch = dispatch
- self.trackparent = trackparent
- self.parent_token = parent_token or self
- if compare_function is None:
- self.is_equal = operator.eq
- else:
- self.is_equal = compare_function
-
- # TODO: pass in the manager here
- # instead of doing a lookup
- attr = manager_of_class(class_)[key]
-
- for ext in util.to_list(extension or []):
- ext._adapt_listener(attr, ext)
-
- if active_history:
- self.dispatch._active_history = True
-
- self.expire_missing = expire_missing
-
- def _get_active_history(self):
- """Backwards compat for impl.active_history"""
-
- return self.dispatch._active_history
-
- def _set_active_history(self, value):
- self.dispatch._active_history = value
-
- active_history = property(_get_active_history, _set_active_history)
-
-
- def hasparent(self, state, optimistic=False):
- """Return the boolean value of a `hasparent` flag attached to
- the given state.
-
- The `optimistic` flag determines what the default return value
- should be if no `hasparent` flag can be located.
-
- As this function is used to determine if an instance is an
- *orphan*, instances that were loaded from storage should be
- assumed to not be orphans, until a True/False value for this
- flag is set.
-
- An instance attribute that is loaded by a callable function
- will also not have a `hasparent` flag.
-
- """
- return state.parents.get(id(self.parent_token), optimistic)
-
- def sethasparent(self, state, value):
- """Set a boolean flag on the given item corresponding to
- whether or not it is attached to a parent object via the
- attribute represented by this ``InstrumentedAttribute``.
-
- """
- state.parents[id(self.parent_token)] = value
-
- def set_callable(self, state, callable_):
- """Set a callable function for this attribute on the given object.
-
- This callable will be executed when the attribute is next
- accessed, and is assumed to construct part of the instances
- previously stored state. When its value or values are loaded,
- they will be established as part of the instance's *committed
- state*. While *trackparent* information will be assembled for
- these instances, attribute-level event handlers will not be
- fired.
-
- The callable overrides the class level callable set in the
- ``InstrumentedAttribute`` constructor.
-
- """
- state.callables[self.key] = callable_
-
- def get_history(self, state, dict_, passive=PASSIVE_OFF):
- raise NotImplementedError()
-
- def get_all_pending(self, state, dict_):
- """Return a list of tuples of (state, obj)
- for all objects in this attribute's current state
- + history.
-
- Only applies to object-based attributes.
-
- This is an inlining of existing functionality
- which roughly correponds to:
-
- get_state_history(
- state,
- key,
- passive=PASSIVE_NO_INITIALIZE).sum()
-
- """
- raise NotImplementedError()
-
- def initialize(self, state, dict_):
- """Initialize the given state's attribute with an empty value."""
-
- dict_[self.key] = None
- return None
-
- def get(self, state, dict_, passive=PASSIVE_OFF):
- """Retrieve a value from the given object.
-
- If a callable is assembled on this object's attribute, and
- passive is False, the callable will be executed and the
- resulting value will be set as the new value for this attribute.
- """
- if self.key in dict_:
- return dict_[self.key]
- else:
- # if history present, don't load
- key = self.key
- if key not in state.committed_state or \
- state.committed_state[key] is NEVER_SET:
- if passive is PASSIVE_NO_INITIALIZE:
- return PASSIVE_NO_RESULT
-
- if key in state.callables:
- callable_ = state.callables[key]
- value = callable_(passive)
- elif self.callable_:
- value = self.callable_(state, passive)
- else:
- value = ATTR_EMPTY
-
- if value is PASSIVE_NO_RESULT:
- return value
- elif value is ATTR_WAS_SET:
- try:
- return dict_[key]
- except KeyError:
- # TODO: no test coverage here.
- raise KeyError(
- "Deferred loader for attribute "
- "%r failed to populate "
- "correctly" % key)
- elif value is not ATTR_EMPTY:
- return self.set_committed_value(state, dict_, value)
-
- if passive is PASSIVE_RETURN_NEVER_SET:
- return NEVER_SET
- else:
- # Return a new, empty value
- return self.initialize(state, dict_)
-
- def append(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- self.set(state, dict_, value, initiator, passive=passive)
-
- def remove(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- self.set(state, dict_, None, initiator, passive=passive)
-
- def set(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- raise NotImplementedError()
-
- def get_committed_value(self, state, dict_, passive=PASSIVE_OFF):
- """return the unchanged value of this attribute"""
-
- if self.key in state.committed_state:
- value = state.committed_state[self.key]
- if value is NO_VALUE:
- return None
- else:
- return value
- else:
- return self.get(state, dict_, passive=passive)
-
- def set_committed_value(self, state, dict_, value):
- """set an attribute value on the given instance and 'commit' it."""
-
- dict_[self.key] = value
- state.commit(dict_, [self.key])
- return value
-
-class ScalarAttributeImpl(AttributeImpl):
- """represents a scalar value-holding InstrumentedAttribute."""
-
- accepts_scalar_loader = True
- uses_objects = False
- supports_population = True
-
- def delete(self, state, dict_):
-
- # TODO: catch key errors, convert to attributeerror?
- if self.dispatch._active_history:
- old = self.get(state, dict_, PASSIVE_RETURN_NEVER_SET)
- else:
- old = dict_.get(self.key, NO_VALUE)
-
- if self.dispatch.remove:
- self.fire_remove_event(state, dict_, old, None)
- state.modified_event(dict_, self, old)
- del dict_[self.key]
-
- def get_history(self, state, dict_, passive=PASSIVE_OFF):
- return History.from_scalar_attribute(
- self, state, dict_.get(self.key, NO_VALUE))
-
- def set(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- if initiator and initiator.parent_token is self.parent_token:
- return
-
- if self.dispatch._active_history:
- old = self.get(state, dict_, PASSIVE_RETURN_NEVER_SET)
- else:
- old = dict_.get(self.key, NO_VALUE)
-
- if self.dispatch.set:
- value = self.fire_replace_event(state, dict_,
- value, old, initiator)
- state.modified_event(dict_, self, old)
- dict_[self.key] = value
-
- def fire_replace_event(self, state, dict_, value, previous, initiator):
- for fn in self.dispatch.set:
- value = fn(state, value, previous, initiator or self)
- return value
-
- def fire_remove_event(self, state, dict_, value, initiator):
- for fn in self.dispatch.remove:
- fn(state, value, initiator or self)
-
- @property
- def type(self):
- self.property.columns[0].type
-
-
-class MutableScalarAttributeImpl(ScalarAttributeImpl):
- """represents a scalar value-holding InstrumentedAttribute, which can
- detect changes within the value itself.
-
- """
-
- uses_objects = False
- supports_population = True
-
- def __init__(self, class_, key, callable_, dispatch,
- class_manager, copy_function=None,
- compare_function=None, **kwargs):
- super(ScalarAttributeImpl, self).__init__(
- class_,
- key,
- callable_, dispatch,
- compare_function=compare_function,
- **kwargs)
- class_manager.mutable_attributes.add(key)
- if copy_function is None:
- raise sa_exc.ArgumentError(
- "MutableScalarAttributeImpl requires a copy function")
- self.copy = copy_function
-
- def get_history(self, state, dict_, passive=PASSIVE_OFF):
- if not dict_:
- v = state.committed_state.get(self.key, NO_VALUE)
- else:
- v = dict_.get(self.key, NO_VALUE)
-
- return History.from_scalar_attribute(self, state, v)
-
- def check_mutable_modified(self, state, dict_):
- a, u, d = self.get_history(state, dict_)
- return bool(a or d)
-
- def get(self, state, dict_, passive=PASSIVE_OFF):
- if self.key not in state.mutable_dict:
- ret = ScalarAttributeImpl.get(self, state, dict_, passive=passive)
- if ret is not PASSIVE_NO_RESULT:
- state.mutable_dict[self.key] = ret
- return ret
- else:
- return state.mutable_dict[self.key]
-
- def delete(self, state, dict_):
- ScalarAttributeImpl.delete(self, state, dict_)
- state.mutable_dict.pop(self.key)
-
- def set(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- ScalarAttributeImpl.set(self, state, dict_, value, initiator, passive)
- state.mutable_dict[self.key] = value
-
-
-class ScalarObjectAttributeImpl(ScalarAttributeImpl):
- """represents a scalar-holding InstrumentedAttribute,
- where the target object is also instrumented.
-
- Adds events to delete/set operations.
-
- """
-
- accepts_scalar_loader = False
- uses_objects = True
- supports_population = True
-
- def __init__(self, class_, key, callable_, dispatch,
- trackparent=False, extension=None, copy_function=None,
- **kwargs):
- super(ScalarObjectAttributeImpl, self).__init__(
- class_,
- key,
- callable_, dispatch,
- trackparent=trackparent,
- extension=extension,
- **kwargs)
-
- def delete(self, state, dict_):
- old = self.get(state, dict_)
- self.fire_remove_event(state, dict_, old, self)
- del dict_[self.key]
-
- def get_history(self, state, dict_, passive=PASSIVE_OFF):
- if self.key in dict_:
- return History.from_object_attribute(self, state, dict_[self.key])
- else:
- if passive is PASSIVE_OFF:
- passive = PASSIVE_RETURN_NEVER_SET
- current = self.get(state, dict_, passive=passive)
- if current is PASSIVE_NO_RESULT:
- return HISTORY_BLANK
- else:
- return History.from_object_attribute(self, state, current)
-
- def get_all_pending(self, state, dict_):
- if self.key in dict_:
- current = dict_[self.key]
- if current is not None:
- ret = [(instance_state(current), current)]
- else:
- ret = []
-
- if self.key in state.committed_state:
- original = state.committed_state[self.key]
- if original not in (NEVER_SET, PASSIVE_NO_RESULT, None) and \
- original is not current:
-
- ret.append((instance_state(original), original))
- return ret
- else:
- return []
-
- def set(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- """Set a value on the given InstanceState.
-
- `initiator` is the ``InstrumentedAttribute`` that initiated the
- ``set()`` operation and is used to control the depth of a circular
- setter operation.
-
- """
- if initiator and initiator.parent_token is self.parent_token:
- return
-
- if self.dispatch._active_history:
- old = self.get(state, dict_, passive=PASSIVE_ONLY_PERSISTENT)
- else:
- old = self.get(state, dict_, passive=PASSIVE_NO_FETCH)
-
- value = self.fire_replace_event(state, dict_, value, old, initiator)
- dict_[self.key] = value
-
- def fire_remove_event(self, state, dict_, value, initiator):
- if self.trackparent and value is not None:
- self.sethasparent(instance_state(value), False)
-
- for fn in self.dispatch.remove:
- fn(state, value, initiator or self)
-
- state.modified_event(dict_, self, value)
-
- def fire_replace_event(self, state, dict_, value, previous, initiator):
- if self.trackparent:
- if (previous is not value and
- previous is not None and
- previous is not PASSIVE_NO_RESULT):
- self.sethasparent(instance_state(previous), False)
-
- for fn in self.dispatch.set:
- value = fn(state, value, previous, initiator or self)
-
- state.modified_event(dict_, self, previous)
-
- if self.trackparent:
- if value is not None:
- self.sethasparent(instance_state(value), True)
-
- return value
-
-
-class CollectionAttributeImpl(AttributeImpl):
- """A collection-holding attribute that instruments changes in membership.
-
- Only handles collections of instrumented objects.
-
- InstrumentedCollectionAttribute holds an arbitrary, user-specified
- container object (defaulting to a list) and brokers access to the
- CollectionAdapter, a "view" onto that object that presents consistent bag
- semantics to the orm layer independent of the user data implementation.
-
- """
- accepts_scalar_loader = False
- uses_objects = True
- supports_population = True
-
- def __init__(self, class_, key, callable_, dispatch,
- typecallable=None, trackparent=False, extension=None,
- copy_function=None, compare_function=None, **kwargs):
- super(CollectionAttributeImpl, self).__init__(
- class_,
- key,
- callable_, dispatch,
- trackparent=trackparent,
- extension=extension,
- compare_function=compare_function,
- **kwargs)
-
- if copy_function is None:
- copy_function = self.__copy
- self.copy = copy_function
- self.collection_factory = typecallable
-
- def __copy(self, item):
- return [y for y in list(collections.collection_adapter(item))]
-
- def get_history(self, state, dict_, passive=PASSIVE_OFF):
- current = self.get(state, dict_, passive=passive)
- if current is PASSIVE_NO_RESULT:
- return HISTORY_BLANK
- else:
- return History.from_collection(self, state, current)
-
- def get_all_pending(self, state, dict_):
- if self.key not in dict_:
- return []
-
- current = dict_[self.key]
- current = getattr(current, '_sa_adapter')
-
- if self.key in state.committed_state:
- original = state.committed_state[self.key]
- if original is not NO_VALUE:
- current_states = [(instance_state(c), c) for c in current]
- original_states = [(instance_state(c), c) for c in original]
-
- current_set = dict(current_states)
- original_set = dict(original_states)
-
- return \
- [(s, o) for s, o in current_states if s not in original_set] + \
- [(s, o) for s, o in current_states if s in original_set] + \
- [(s, o) for s, o in original_states if s not in current_set]
-
- return [(instance_state(o), o) for o in current]
-
-
- def fire_append_event(self, state, dict_, value, initiator):
- for fn in self.dispatch.append:
- value = fn(state, value, initiator or self)
-
- state.modified_event(dict_, self, NEVER_SET, True)
-
- if self.trackparent and value is not None:
- self.sethasparent(instance_state(value), True)
-
- return value
-
- def fire_pre_remove_event(self, state, dict_, initiator):
- state.modified_event(dict_, self, NEVER_SET, True)
-
- def fire_remove_event(self, state, dict_, value, initiator):
- if self.trackparent and value is not None:
- self.sethasparent(instance_state(value), False)
-
- for fn in self.dispatch.remove:
- fn(state, value, initiator or self)
-
- state.modified_event(dict_, self, NEVER_SET, True)
-
- def delete(self, state, dict_):
- if self.key not in dict_:
- return
-
- state.modified_event(dict_, self, NEVER_SET, True)
-
- collection = self.get_collection(state, state.dict)
- collection.clear_with_event()
- # TODO: catch key errors, convert to attributeerror?
- del dict_[self.key]
-
- def initialize(self, state, dict_):
- """Initialize this attribute with an empty collection."""
-
- _, user_data = self._initialize_collection(state)
- dict_[self.key] = user_data
- return user_data
-
- def _initialize_collection(self, state):
- return state.manager.initialize_collection(
- self.key, state, self.collection_factory)
-
- def append(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- if initiator and initiator.parent_token is self.parent_token:
- return
-
- collection = self.get_collection(state, dict_, passive=passive)
- if collection is PASSIVE_NO_RESULT:
- value = self.fire_append_event(state, dict_, value, initiator)
- assert self.key not in dict_, \
- "Collection was loaded during event handling."
- state.get_pending(self.key).append(value)
- else:
- collection.append_with_event(value, initiator)
-
- def remove(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- if initiator and initiator.parent_token is self.parent_token:
- return
-
- collection = self.get_collection(state, state.dict, passive=passive)
- if collection is PASSIVE_NO_RESULT:
- self.fire_remove_event(state, dict_, value, initiator)
- assert self.key not in dict_, \
- "Collection was loaded during event handling."
- state.get_pending(self.key).remove(value)
- else:
- collection.remove_with_event(value, initiator)
-
- def set(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
- """Set a value on the given object.
-
- `initiator` is the ``InstrumentedAttribute`` that initiated the
- ``set()`` operation and is used to control the depth of a circular
- setter operation.
- """
-
- if initiator and initiator.parent_token is self.parent_token:
- return
-
- self._set_iterable(
- state, dict_, value,
- lambda adapter, i: adapter.adapt_like_to_iterable(i))
-
- def _set_iterable(self, state, dict_, iterable, adapter=None):
- """Set a collection value from an iterable of state-bearers.
-
- ``adapter`` is an optional callable invoked with a CollectionAdapter
- and the iterable. Should return an iterable of state-bearing
- instances suitable for appending via a CollectionAdapter. Can be used
- for, e.g., adapting an incoming dictionary into an iterator of values
- rather than keys.
-
- """
- # pulling a new collection first so that an adaptation exception does
- # not trigger a lazy load of the old collection.
- new_collection, user_data = self._initialize_collection(state)
- if adapter:
- new_values = list(adapter(new_collection, iterable))
- else:
- new_values = list(iterable)
-
- old = self.get(state, dict_, passive=PASSIVE_ONLY_PERSISTENT)
- if old is PASSIVE_NO_RESULT:
- old = self.initialize(state, dict_)
- elif old is iterable:
- # ignore re-assignment of the current collection, as happens
- # implicitly with in-place operators (foo.collection |= other)
- return
-
- # place a copy of "old" in state.committed_state
- state.modified_event(dict_, self, old, True)
-
- old_collection = getattr(old, '_sa_adapter')
-
- dict_[self.key] = user_data
-
- collections.bulk_replace(new_values, old_collection, new_collection)
- old_collection.unlink(old)
-
- def set_committed_value(self, state, dict_, value):
- """Set an attribute value on the given instance and 'commit' it."""
-
- collection, user_data = self._initialize_collection(state)
-
- if value:
- collection.append_multiple_without_event(value)
-
- state.dict[self.key] = user_data
-
- state.commit(dict_, [self.key])
-
- if self.key in state.pending:
- # pending items exist. issue a modified event,
- # add/remove new items.
- state.modified_event(dict_, self, user_data, True)
-
- pending = state.pending.pop(self.key)
- added = pending.added_items
- removed = pending.deleted_items
- for item in added:
- collection.append_without_event(item)
- for item in removed:
- collection.remove_without_event(item)
-
- return user_data
-
- def get_collection(self, state, dict_,
- user_data=None, passive=PASSIVE_OFF):
- """Retrieve the CollectionAdapter associated with the given state.
-
- Creates a new CollectionAdapter if one does not exist.
-
- """
- if user_data is None:
- user_data = self.get(state, dict_, passive=passive)
- if user_data is PASSIVE_NO_RESULT:
- return user_data
-
- return getattr(user_data, '_sa_adapter')
-
-def backref_listeners(attribute, key, uselist):
- """Apply listeners to synchronize a two-way relationship."""
-
- # use easily recognizable names for stack traces
-
- def emit_backref_from_scalar_set_event(state, child, oldchild, initiator):
- if oldchild is child:
- return child
-
- if oldchild is not None and oldchild is not PASSIVE_NO_RESULT:
- # With lazy=None, there's no guarantee that the full collection is
- # present when updating via a backref.
- old_state, old_dict = instance_state(oldchild),\
- instance_dict(oldchild)
- impl = old_state.manager[key].impl
- try:
- impl.remove(old_state,
- old_dict,
- state.obj(),
- initiator, passive=PASSIVE_NO_FETCH)
- except (ValueError, KeyError, IndexError):
- pass
-
- if child is not None:
- child_state, child_dict = instance_state(child),\
- instance_dict(child)
- child_state.manager[key].impl.append(
- child_state,
- child_dict,
- state.obj(),
- initiator,
- passive=PASSIVE_NO_FETCH)
- return child
-
- def emit_backref_from_collection_append_event(state, child, initiator):
- child_state, child_dict = instance_state(child), \
- instance_dict(child)
- child_state.manager[key].impl.append(
- child_state,
- child_dict,
- state.obj(),
- initiator,
- passive=PASSIVE_NO_FETCH)
- return child
-
- def emit_backref_from_collection_remove_event(state, child, initiator):
- if child is not None:
- child_state, child_dict = instance_state(child),\
- instance_dict(child)
- child_state.manager[key].impl.remove(
- child_state,
- child_dict,
- state.obj(),
- initiator,
- passive=PASSIVE_NO_FETCH)
-
- if uselist:
- event.listen(attribute, "append",
- emit_backref_from_collection_append_event,
- retval=True, raw=True)
- else:
- event.listen(attribute, "set",
- emit_backref_from_scalar_set_event,
- retval=True, raw=True)
- # TODO: need coverage in test/orm/ of remove event
- event.listen(attribute, "remove",
- emit_backref_from_collection_remove_event,
- retval=True, raw=True)
-
-_NO_HISTORY = util.symbol('NO_HISTORY')
-_NO_STATE_SYMBOLS = frozenset([
- id(PASSIVE_NO_RESULT),
- id(NO_VALUE),
- id(NEVER_SET)])
-class History(tuple):
- """A 3-tuple of added, unchanged and deleted values,
- representing the changes which have occurred on an instrumented
- attribute.
-
- Each tuple member is an iterable sequence.
-
- """
-
- __slots__ = ()
-
- added = property(itemgetter(0))
- """Return the collection of items added to the attribute (the first tuple
- element)."""
-
- unchanged = property(itemgetter(1))
- """Return the collection of items that have not changed on the attribute
- (the second tuple element)."""
-
-
- deleted = property(itemgetter(2))
- """Return the collection of items that have been removed from the
- attribute (the third tuple element)."""
-
- def __new__(cls, added, unchanged, deleted):
- return tuple.__new__(cls, (added, unchanged, deleted))
-
- def __nonzero__(self):
- return self != HISTORY_BLANK
-
- def empty(self):
- """Return True if this :class:`.History` has no changes
- and no existing, unchanged state.
-
- """
-
- return not bool(
- (self.added or self.deleted)
- or self.unchanged and self.unchanged != [None]
- )
-
- def sum(self):
- """Return a collection of added + unchanged + deleted."""
-
- return (self.added or []) +\
- (self.unchanged or []) +\
- (self.deleted or [])
-
- def non_deleted(self):
- """Return a collection of added + unchanged."""
-
- return (self.added or []) +\
- (self.unchanged or [])
-
- def non_added(self):
- """Return a collection of unchanged + deleted."""
-
- return (self.unchanged or []) +\
- (self.deleted or [])
-
- def has_changes(self):
- """Return True if this :class:`.History` has changes."""
-
- return bool(self.added or self.deleted)
-
- def as_state(self):
- return History(
- [(c is not None)
- and instance_state(c) or None
- for c in self.added],
- [(c is not None)
- and instance_state(c) or None
- for c in self.unchanged],
- [(c is not None)
- and instance_state(c) or None
- for c in self.deleted],
- )
-
- @classmethod
- def from_scalar_attribute(cls, attribute, state, current):
- original = state.committed_state.get(attribute.key, _NO_HISTORY)
-
- if original is _NO_HISTORY:
- if current is NO_VALUE:
- return cls((), (), ())
- else:
- return cls((), [current], ())
- # dont let ClauseElement expressions here trip things up
- elif attribute.is_equal(current, original) is True:
- return cls((), [current], ())
- else:
- # current convention on native scalars is to not
- # include information
- # about missing previous value in "deleted", but
- # we do include None, which helps in some primary
- # key situations
- if id(original) in _NO_STATE_SYMBOLS:
- deleted = ()
- else:
- deleted = [original]
- if current is NO_VALUE:
- return cls((), (), deleted)
- else:
- return cls([current], (), deleted)
-
- @classmethod
- def from_object_attribute(cls, attribute, state, current):
- original = state.committed_state.get(attribute.key, _NO_HISTORY)
-
- if original is _NO_HISTORY:
- if current is NO_VALUE or current is NEVER_SET:
- return cls((), (), ())
- else:
- return cls((), [current], ())
- elif current is original:
- return cls((), [current], ())
- else:
- # current convention on related objects is to not
- # include information
- # about missing previous value in "deleted", and
- # to also not include None - the dependency.py rules
- # ignore the None in any case.
- if id(original) in _NO_STATE_SYMBOLS or original is None:
- deleted = ()
- else:
- deleted = [original]
- if current is NO_VALUE or current is NEVER_SET:
- return cls((), (), deleted)
- else:
- return cls([current], (), deleted)
-
- @classmethod
- def from_collection(cls, attribute, state, current):
- original = state.committed_state.get(attribute.key, _NO_HISTORY)
- current = getattr(current, '_sa_adapter')
-
- if original is NO_VALUE:
- return cls(list(current), (), ())
- elif original is _NO_HISTORY:
- return cls((), list(current), ())
- else:
- current_states = [(instance_state(c), c) for c in current]
- original_states = [(instance_state(c), c) for c in original]
-
- current_set = dict(current_states)
- original_set = dict(original_states)
-
- return cls(
- [o for s, o in current_states if s not in original_set],
- [o for s, o in current_states if s in original_set],
- [o for s, o in original_states if s not in current_set]
- )
-
-HISTORY_BLANK = History(None, None, None)
-
-def get_history(obj, key, passive=PASSIVE_OFF):
- """Return a :class:`.History` record for the given object
- and attribute key.
-
- :param obj: an object whose class is instrumented by the
- attributes package.
-
- :param key: string attribute name.
-
- :param passive: indicates if the attribute should be
- loaded from the database if not already present (:attr:`.PASSIVE_NO_FETCH`), and
- if the attribute should be not initialized to a blank value otherwise
- (:attr:`.PASSIVE_NO_INITIALIZE`). Default is :attr:`PASSIVE_OFF`.
-
- """
- if passive is True:
- util.warn_deprecated("Passing True for 'passive' is deprecated. "
- "Use attributes.PASSIVE_NO_INITIALIZE")
- passive = PASSIVE_NO_INITIALIZE
- elif passive is False:
- util.warn_deprecated("Passing False for 'passive' is "
- "deprecated. Use attributes.PASSIVE_OFF")
- passive = PASSIVE_OFF
-
- return get_state_history(instance_state(obj), key, passive)
-
-def get_state_history(state, key, passive=PASSIVE_OFF):
- return state.get_history(key, passive)
-
-
-def has_parent(cls, obj, key, optimistic=False):
- """TODO"""
- manager = manager_of_class(cls)
- state = instance_state(obj)
- return manager.has_parent(state, key, optimistic)
-
-def register_attribute(class_, key, **kw):
- comparator = kw.pop('comparator', None)
- parententity = kw.pop('parententity', None)
- doc = kw.pop('doc', None)
- desc = register_descriptor(class_, key,
- comparator, parententity, doc=doc)
- register_attribute_impl(class_, key, **kw)
- return desc
-
-def register_attribute_impl(class_, key,
- uselist=False, callable_=None,
- useobject=False, mutable_scalars=False,
- impl_class=None, backref=None, **kw):
-
- manager = manager_of_class(class_)
- if uselist:
- factory = kw.pop('typecallable', None)
- typecallable = manager.instrument_collection_class(
- key, factory or list)
- else:
- typecallable = kw.pop('typecallable', None)
-
- dispatch = manager[key].dispatch
-
- if impl_class:
- impl = impl_class(class_, key, typecallable, dispatch, **kw)
- elif uselist:
- impl = CollectionAttributeImpl(class_, key, callable_, dispatch,
- typecallable=typecallable, **kw)
- elif useobject:
- impl = ScalarObjectAttributeImpl(class_, key, callable_,
- dispatch,**kw)
- elif mutable_scalars:
- impl = MutableScalarAttributeImpl(class_, key, callable_, dispatch,
- class_manager=manager, **kw)
- else:
- impl = ScalarAttributeImpl(class_, key, callable_, dispatch, **kw)
-
- manager[key].impl = impl
-
- if backref:
- backref_listeners(manager[key], backref, uselist)
-
- manager.post_configure_attribute(key)
- return manager[key]
-
-def register_descriptor(class_, key, comparator=None,
- parententity=None, property_=None, doc=None):
- manager = manager_of_class(class_)
-
- descriptor = InstrumentedAttribute(class_, key, comparator=comparator,
- parententity=parententity)
-
- descriptor.__doc__ = doc
-
- manager.instrument_attribute(key, descriptor)
- return descriptor
-
-def unregister_attribute(class_, key):
- manager_of_class(class_).uninstrument_attribute(key)
-
-def init_collection(obj, key):
- """Initialize a collection attribute and return the collection adapter.
-
- This function is used to provide direct access to collection internals
- for a previously unloaded attribute. e.g.::
-
- collection_adapter = init_collection(someobject, 'elements')
- for elem in values:
- collection_adapter.append_without_event(elem)
-
- For an easier way to do the above, see
- :func:`~sqlalchemy.orm.attributes.set_committed_value`.
-
- obj is an instrumented object instance. An InstanceState
- is accepted directly for backwards compatibility but
- this usage is deprecated.
-
- """
- state = instance_state(obj)
- dict_ = state.dict
- return init_state_collection(state, dict_, key)
-
-def init_state_collection(state, dict_, key):
- """Initialize a collection attribute and return the collection adapter."""
-
- attr = state.manager[key].impl
- user_data = attr.initialize(state, dict_)
- return attr.get_collection(state, dict_, user_data)
-
-def set_committed_value(instance, key, value):
- """Set the value of an attribute with no history events.
-
- Cancels any previous history present. The value should be
- a scalar value for scalar-holding attributes, or
- an iterable for any collection-holding attribute.
-
- This is the same underlying method used when a lazy loader
- fires off and loads additional data from the database.
- In particular, this method can be used by application code
- which has loaded additional attributes or collections through
- separate queries, which can then be attached to an instance
- as though it were part of its original loaded state.
-
- """
- state, dict_ = instance_state(instance), instance_dict(instance)
- state.manager[key].impl.set_committed_value(state, dict_, value)
-
-def set_attribute(instance, key, value):
- """Set the value of an attribute, firing history events.
-
- This function may be used regardless of instrumentation
- applied directly to the class, i.e. no descriptors are required.
- Custom attribute management schemes will need to make usage
- of this method to establish attribute state as understood
- by SQLAlchemy.
-
- """
- state, dict_ = instance_state(instance), instance_dict(instance)
- state.manager[key].impl.set(state, dict_, value, None)
-
-def get_attribute(instance, key):
- """Get the value of an attribute, firing any callables required.
-
- This function may be used regardless of instrumentation
- applied directly to the class, i.e. no descriptors are required.
- Custom attribute management schemes will need to make usage
- of this method to make usage of attribute state as understood
- by SQLAlchemy.
-
- """
- state, dict_ = instance_state(instance), instance_dict(instance)
- return state.manager[key].impl.get(state, dict_)
-
-def del_attribute(instance, key):
- """Delete the value of an attribute, firing history events.
-
- This function may be used regardless of instrumentation
- applied directly to the class, i.e. no descriptors are required.
- Custom attribute management schemes will need to make usage
- of this method to establish attribute state as understood
- by SQLAlchemy.
-
- """
- state, dict_ = instance_state(instance), instance_dict(instance)
- state.manager[key].impl.delete(state, dict_)
-
-def flag_modified(instance, key):
- """Mark an attribute on an instance as 'modified'.
-
- This sets the 'modified' flag on the instance and
- establishes an unconditional change event for the given attribute.
-
- """
- state, dict_ = instance_state(instance), instance_dict(instance)
- impl = state.manager[key].impl
- state.modified_event(dict_, impl, NO_VALUE)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/collections.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/collections.py
deleted file mode 100755
index 14251920..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/collections.py
+++ /dev/null
@@ -1,1473 +0,0 @@
-# orm/collections.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Support for collections of mapped entities.
-
-The collections package supplies the machinery used to inform the ORM of
-collection membership changes. An instrumentation via decoration approach is
-used, allowing arbitrary types (including built-ins) to be used as entity
-collections without requiring inheritance from a base class.
-
-Instrumentation decoration relays membership change events to the
-``InstrumentedCollectionAttribute`` that is currently managing the collection.
-The decorators observe function call arguments and return values, tracking
-entities entering or leaving the collection. Two decorator approaches are
-provided. One is a bundle of generic decorators that map function arguments
-and return values to events::
-
- from sqlalchemy.orm.collections import collection
- class MyClass(object):
- # ...
-
- @collection.adds(1)
- def store(self, item):
- self.data.append(item)
-
- @collection.removes_return()
- def pop(self):
- return self.data.pop()
-
-
-The second approach is a bundle of targeted decorators that wrap appropriate
-append and remove notifiers around the mutation methods present in the
-standard Python ``list``, ``set`` and ``dict`` interfaces. These could be
-specified in terms of generic decorator recipes, but are instead hand-tooled
-for increased efficiency. The targeted decorators occasionally implement
-adapter-like behavior, such as mapping bulk-set methods (``extend``,
-``update``, ``__setslice__``, etc.) into the series of atomic mutation events
-that the ORM requires.
-
-The targeted decorators are used internally for automatic instrumentation of
-entity collection classes. Every collection class goes through a
-transformation process roughly like so:
-
-1. If the class is a built-in, substitute a trivial sub-class
-2. Is this class already instrumented?
-3. Add in generic decorators
-4. Sniff out the collection interface through duck-typing
-5. Add targeted decoration to any undecorated interface method
-
-This process modifies the class at runtime, decorating methods and adding some
-bookkeeping properties. This isn't possible (or desirable) for built-in
-classes like ``list``, so trivial sub-classes are substituted to hold
-decoration::
-
- class InstrumentedList(list):
- pass
-
-Collection classes can be specified in ``relationship(collection_class=)`` as
-types or a function that returns an instance. Collection classes are
-inspected and instrumented during the mapper compilation phase. The
-collection_class callable will be executed once to produce a specimen
-instance, and the type of that specimen will be instrumented. Functions that
-return built-in types like ``lists`` will be adapted to produce instrumented
-instances.
-
-When extending a known type like ``list``, additional decorations are not
-generally not needed. Odds are, the extension method will delegate to a
-method that's already instrumented. For example::
-
- class QueueIsh(list):
- def push(self, item):
- self.append(item)
- def shift(self):
- return self.pop(0)
-
-There's no need to decorate these methods. ``append`` and ``pop`` are already
-instrumented as part of the ``list`` interface. Decorating them would fire
-duplicate events, which should be avoided.
-
-The targeted decoration tries not to rely on other methods in the underlying
-collection class, but some are unavoidable. Many depend on 'read' methods
-being present to properly instrument a 'write', for example, ``__setitem__``
-needs ``__getitem__``. "Bulk" methods like ``update`` and ``extend`` may also
-reimplemented in terms of atomic appends and removes, so the ``extend``
-decoration will actually perform many ``append`` operations and not call the
-underlying method at all.
-
-Tight control over bulk operation and the firing of events is also possible by
-implementing the instrumentation internally in your methods. The basic
-instrumentation package works under the general assumption that collection
-mutation will not raise unusual exceptions. If you want to closely
-orchestrate append and remove events with exception management, internal
-instrumentation may be the answer. Within your method,
-``collection_adapter(self)`` will retrieve an object that you can use for
-explicit control over triggering append and remove events.
-
-The owning object and InstrumentedCollectionAttribute are also reachable
-through the adapter, allowing for some very sophisticated behavior.
-
-"""
-
-import copy
-import inspect
-import operator
-import sys
-import weakref
-
-from sqlalchemy.sql import expression
-from sqlalchemy import schema, util, exc as sa_exc
-
-
-__all__ = ['collection', 'collection_adapter',
- 'mapped_collection', 'column_mapped_collection',
- 'attribute_mapped_collection']
-
-__instrumentation_mutex = util.threading.Lock()
-
-
-def column_mapped_collection(mapping_spec):
- """A dictionary-based collection type with column-based keying.
-
- Returns a MappedCollection factory with a keying function generated
- from mapping_spec, which may be a Column or a sequence of Columns.
-
- The key value must be immutable for the lifetime of the object. You
- can not, for example, map on foreign key values if those key values will
- change during the session, i.e. from None to a database-assigned integer
- after a session flush.
-
- """
- from sqlalchemy.orm.util import _state_mapper
- from sqlalchemy.orm.attributes import instance_state
-
- cols = [expression._only_column_elements(q, "mapping_spec")
- for q in util.to_list(mapping_spec)]
- if len(cols) == 1:
- def keyfunc(value):
- state = instance_state(value)
- m = _state_mapper(state)
- return m._get_state_attr_by_column(state, state.dict, cols[0])
- else:
- mapping_spec = tuple(cols)
- def keyfunc(value):
- state = instance_state(value)
- m = _state_mapper(state)
- return tuple(m._get_state_attr_by_column(state, state.dict, c)
- for c in mapping_spec)
- return lambda: MappedCollection(keyfunc)
-
-def attribute_mapped_collection(attr_name):
- """A dictionary-based collection type with attribute-based keying.
-
- Returns a MappedCollection factory with a keying based on the
- 'attr_name' attribute of entities in the collection.
-
- The key value must be immutable for the lifetime of the object. You
- can not, for example, map on foreign key values if those key values will
- change during the session, i.e. from None to a database-assigned integer
- after a session flush.
-
- """
- return lambda: MappedCollection(operator.attrgetter(attr_name))
-
-
-def mapped_collection(keyfunc):
- """A dictionary-based collection type with arbitrary keying.
-
- Returns a MappedCollection factory with a keying function generated
- from keyfunc, a callable that takes an entity and returns a key value.
-
- The key value must be immutable for the lifetime of the object. You
- can not, for example, map on foreign key values if those key values will
- change during the session, i.e. from None to a database-assigned integer
- after a session flush.
-
- """
- return lambda: MappedCollection(keyfunc)
-
-class collection(object):
- """Decorators for entity collection classes.
-
- The decorators fall into two groups: annotations and interception recipes.
-
- The annotating decorators (appender, remover, iterator,
- internally_instrumented, link) indicate the method's purpose and take no
- arguments. They are not written with parens::
-
- @collection.appender
- def append(self, append): ...
-
- The recipe decorators all require parens, even those that take no
- arguments::
-
- @collection.adds('entity')
- def insert(self, position, entity): ...
-
- @collection.removes_return()
- def popitem(self): ...
-
- Decorators can be specified in long-hand for Python 2.3, or with
- the class-level dict attribute '__instrumentation__'- see the source
- for details.
-
- """
- # Bundled as a class solely for ease of use: packaging, doc strings,
- # importability.
-
- @staticmethod
- def appender(fn):
- """Tag the method as the collection appender.
-
- The appender method is called with one positional argument: the value
- to append. The method will be automatically decorated with 'adds(1)'
- if not already decorated::
-
- @collection.appender
- def add(self, append): ...
-
- # or, equivalently
- @collection.appender
- @collection.adds(1)
- def add(self, append): ...
-
- # for mapping type, an 'append' may kick out a previous value
- # that occupies that slot. consider d['a'] = 'foo'- any previous
- # value in d['a'] is discarded.
- @collection.appender
- @collection.replaces(1)
- def add(self, entity):
- key = some_key_func(entity)
- previous = None
- if key in self:
- previous = self[key]
- self[key] = entity
- return previous
-
- If the value to append is not allowed in the collection, you may
- raise an exception. Something to remember is that the appender
- will be called for each object mapped by a database query. If the
- database contains rows that violate your collection semantics, you
- will need to get creative to fix the problem, as access via the
- collection will not work.
-
- If the appender method is internally instrumented, you must also
- receive the keyword argument '_sa_initiator' and ensure its
- promulgation to collection events.
-
- """
- setattr(fn, '_sa_instrument_role', 'appender')
- return fn
-
- @staticmethod
- def remover(fn):
- """Tag the method as the collection remover.
-
- The remover method is called with one positional argument: the value
- to remove. The method will be automatically decorated with
- :meth:`removes_return` if not already decorated::
-
- @collection.remover
- def zap(self, entity): ...
-
- # or, equivalently
- @collection.remover
- @collection.removes_return()
- def zap(self, ): ...
-
- If the value to remove is not present in the collection, you may
- raise an exception or return None to ignore the error.
-
- If the remove method is internally instrumented, you must also
- receive the keyword argument '_sa_initiator' and ensure its
- promulgation to collection events.
-
- """
- setattr(fn, '_sa_instrument_role', 'remover')
- return fn
-
- @staticmethod
- def iterator(fn):
- """Tag the method as the collection remover.
-
- The iterator method is called with no arguments. It is expected to
- return an iterator over all collection members::
-
- @collection.iterator
- def __iter__(self): ...
-
- """
- setattr(fn, '_sa_instrument_role', 'iterator')
- return fn
-
- @staticmethod
- def internally_instrumented(fn):
- """Tag the method as instrumented.
-
- This tag will prevent any decoration from being applied to the method.
- Use this if you are orchestrating your own calls to :func:`.collection_adapter`
- in one of the basic SQLAlchemy interface methods, or to prevent
- an automatic ABC method decoration from wrapping your implementation::
-
- # normally an 'extend' method on a list-like class would be
- # automatically intercepted and re-implemented in terms of
- # SQLAlchemy events and append(). your implementation will
- # never be called, unless:
- @collection.internally_instrumented
- def extend(self, items): ...
-
- """
- setattr(fn, '_sa_instrumented', True)
- return fn
-
- @staticmethod
- def link(fn):
- """Tag the method as a the "linked to attribute" event handler.
-
- This optional event handler will be called when the collection class
- is linked to or unlinked from the InstrumentedAttribute. It is
- invoked immediately after the '_sa_adapter' property is set on
- the instance. A single argument is passed: the collection adapter
- that has been linked, or None if unlinking.
-
- """
- setattr(fn, '_sa_instrument_role', 'link')
- return fn
-
- @staticmethod
- def converter(fn):
- """Tag the method as the collection converter.
-
- This optional method will be called when a collection is being
- replaced entirely, as in::
-
- myobj.acollection = [newvalue1, newvalue2]
-
- The converter method will receive the object being assigned and should
- return an iterable of values suitable for use by the ``appender``
- method. A converter must not assign values or mutate the collection,
- it's sole job is to adapt the value the user provides into an iterable
- of values for the ORM's use.
-
- The default converter implementation will use duck-typing to do the
- conversion. A dict-like collection will be convert into an iterable
- of dictionary values, and other types will simply be iterated::
-
- @collection.converter
- def convert(self, other): ...
-
- If the duck-typing of the object does not match the type of this
- collection, a TypeError is raised.
-
- Supply an implementation of this method if you want to expand the
- range of possible types that can be assigned in bulk or perform
- validation on the values about to be assigned.
-
- """
- setattr(fn, '_sa_instrument_role', 'converter')
- return fn
-
- @staticmethod
- def adds(arg):
- """Mark the method as adding an entity to the collection.
-
- Adds "add to collection" handling to the method. The decorator
- argument indicates which method argument holds the SQLAlchemy-relevant
- value. Arguments can be specified positionally (i.e. integer) or by
- name::
-
- @collection.adds(1)
- def push(self, item): ...
-
- @collection.adds('entity')
- def do_stuff(self, thing, entity=None): ...
-
- """
- def decorator(fn):
- setattr(fn, '_sa_instrument_before', ('fire_append_event', arg))
- return fn
- return decorator
-
- @staticmethod
- def replaces(arg):
- """Mark the method as replacing an entity in the collection.
-
- Adds "add to collection" and "remove from collection" handling to
- the method. The decorator argument indicates which method argument
- holds the SQLAlchemy-relevant value to be added, and return value, if
- any will be considered the value to remove.
-
- Arguments can be specified positionally (i.e. integer) or by name::
-
- @collection.replaces(2)
- def __setitem__(self, index, item): ...
-
- """
- def decorator(fn):
- setattr(fn, '_sa_instrument_before', ('fire_append_event', arg))
- setattr(fn, '_sa_instrument_after', 'fire_remove_event')
- return fn
- return decorator
-
- @staticmethod
- def removes(arg):
- """Mark the method as removing an entity in the collection.
-
- Adds "remove from collection" handling to the method. The decorator
- argument indicates which method argument holds the SQLAlchemy-relevant
- value to be removed. Arguments can be specified positionally (i.e.
- integer) or by name::
-
- @collection.removes(1)
- def zap(self, item): ...
-
- For methods where the value to remove is not known at call-time, use
- collection.removes_return.
-
- """
- def decorator(fn):
- setattr(fn, '_sa_instrument_before', ('fire_remove_event', arg))
- return fn
- return decorator
-
- @staticmethod
- def removes_return():
- """Mark the method as removing an entity in the collection.
-
- Adds "remove from collection" handling to the method. The return value
- of the method, if any, is considered the value to remove. The method
- arguments are not inspected::
-
- @collection.removes_return()
- def pop(self): ...
-
- For methods where the value to remove is known at call-time, use
- collection.remove.
-
- """
- def decorator(fn):
- setattr(fn, '_sa_instrument_after', 'fire_remove_event')
- return fn
- return decorator
-
-
-# public instrumentation interface for 'internally instrumented'
-# implementations
-def collection_adapter(collection):
- """Fetch the :class:`.CollectionAdapter` for a collection."""
-
- return getattr(collection, '_sa_adapter', None)
-
-def collection_iter(collection):
- """Iterate over an object supporting the @iterator or __iter__ protocols.
-
- If the collection is an ORM collection, it need not be attached to an
- object to be iterable.
-
- """
- try:
- return getattr(collection, '_sa_iterator',
- getattr(collection, '__iter__'))()
- except AttributeError:
- raise TypeError("'%s' object is not iterable" %
- type(collection).__name__)
-
-
-class CollectionAdapter(object):
- """Bridges between the ORM and arbitrary Python collections.
-
- Proxies base-level collection operations (append, remove, iterate)
- to the underlying Python collection, and emits add/remove events for
- entities entering or leaving the collection.
-
- The ORM uses an CollectionAdapter exclusively for interaction with
- entity collections.
-
- The usage of getattr()/setattr() is currently to allow injection
- of custom methods, such as to unwrap Zope security proxies.
-
- """
- def __init__(self, attr, owner_state, data):
- self._key = attr.key
- self._data = weakref.ref(data)
- self.owner_state = owner_state
- self.link_to_self(data)
-
- @property
- def data(self):
- "The entity collection being adapted."
- return self._data()
-
- @util.memoized_property
- def attr(self):
- return self.owner_state.manager[self._key].impl
-
- def link_to_self(self, data):
- """Link a collection to this adapter, and fire a link event."""
- setattr(data, '_sa_adapter', self)
- if hasattr(data, '_sa_on_link'):
- getattr(data, '_sa_on_link')(self)
-
- def unlink(self, data):
- """Unlink a collection from any adapter, and fire a link event."""
- setattr(data, '_sa_adapter', None)
- if hasattr(data, '_sa_on_link'):
- getattr(data, '_sa_on_link')(None)
-
- def adapt_like_to_iterable(self, obj):
- """Converts collection-compatible objects to an iterable of values.
-
- Can be passed any type of object, and if the underlying collection
- determines that it can be adapted into a stream of values it can
- use, returns an iterable of values suitable for append()ing.
-
- This method may raise TypeError or any other suitable exception
- if adaptation fails.
-
- If a converter implementation is not supplied on the collection,
- a default duck-typing-based implementation is used.
-
- """
- converter = getattr(self._data(), '_sa_converter', None)
- if converter is not None:
- return converter(obj)
-
- setting_type = util.duck_type_collection(obj)
- receiving_type = util.duck_type_collection(self._data())
-
- if obj is None or setting_type != receiving_type:
- given = obj is None and 'None' or obj.__class__.__name__
- if receiving_type is None:
- wanted = self._data().__class__.__name__
- else:
- wanted = receiving_type.__name__
-
- raise TypeError(
- "Incompatible collection type: %s is not %s-like" % (
- given, wanted))
-
- # If the object is an adapted collection, return the (iterable)
- # adapter.
- if getattr(obj, '_sa_adapter', None) is not None:
- return getattr(obj, '_sa_adapter')
- elif setting_type == dict:
- # Py3K
- #return obj.values()
- # Py2K
- return getattr(obj, 'itervalues', getattr(obj, 'values'))()
- # end Py2K
- else:
- return iter(obj)
-
- def append_with_event(self, item, initiator=None):
- """Add an entity to the collection, firing mutation events."""
-
- getattr(self._data(), '_sa_appender')(item, _sa_initiator=initiator)
-
- def append_without_event(self, item):
- """Add or restore an entity to the collection, firing no events."""
- getattr(self._data(), '_sa_appender')(item, _sa_initiator=False)
-
- def append_multiple_without_event(self, items):
- """Add or restore an entity to the collection, firing no events."""
- appender = getattr(self._data(), '_sa_appender')
- for item in items:
- appender(item, _sa_initiator=False)
-
- def remove_with_event(self, item, initiator=None):
- """Remove an entity from the collection, firing mutation events."""
- getattr(self._data(), '_sa_remover')(item, _sa_initiator=initiator)
-
- def remove_without_event(self, item):
- """Remove an entity from the collection, firing no events."""
- getattr(self._data(), '_sa_remover')(item, _sa_initiator=False)
-
- def clear_with_event(self, initiator=None):
- """Empty the collection, firing a mutation event for each entity."""
-
- remover = getattr(self._data(), '_sa_remover')
- for item in list(self):
- remover(item, _sa_initiator=initiator)
-
- def clear_without_event(self):
- """Empty the collection, firing no events."""
-
- remover = getattr(self._data(), '_sa_remover')
- for item in list(self):
- remover(item, _sa_initiator=False)
-
- def __iter__(self):
- """Iterate over entities in the collection."""
-
- # Py3K requires iter() here
- return iter(getattr(self._data(), '_sa_iterator')())
-
- def __len__(self):
- """Count entities in the collection."""
- return len(list(getattr(self._data(), '_sa_iterator')()))
-
- def __nonzero__(self):
- return True
-
- def fire_append_event(self, item, initiator=None):
- """Notify that a entity has entered the collection.
-
- Initiator is a token owned by the InstrumentedAttribute that initiated the membership
- mutation, and should be left as None unless you are passing along
- an initiator value from a chained operation.
-
- """
- if initiator is not False and item is not None:
- return self.attr.fire_append_event(
- self.owner_state,
- self.owner_state.dict,
- item, initiator)
- else:
- return item
-
- def fire_remove_event(self, item, initiator=None):
- """Notify that a entity has been removed from the collection.
-
- Initiator is the InstrumentedAttribute that initiated the membership
- mutation, and should be left as None unless you are passing along
- an initiator value from a chained operation.
-
- """
- if initiator is not False and item is not None:
- self.attr.fire_remove_event(
- self.owner_state,
- self.owner_state.dict,
- item, initiator)
-
- def fire_pre_remove_event(self, initiator=None):
- """Notify that an entity is about to be removed from the collection.
-
- Only called if the entity cannot be removed after calling
- fire_remove_event().
-
- """
- self.attr.fire_pre_remove_event(
- self.owner_state,
- self.owner_state.dict,
- initiator=initiator)
-
- def __getstate__(self):
- return {'key': self._key,
- 'owner_state': self.owner_state,
- 'data': self.data}
-
- def __setstate__(self, d):
- self._key = d['key']
- self.owner_state = d['owner_state']
- self._data = weakref.ref(d['data'])
-
-
-def bulk_replace(values, existing_adapter, new_adapter):
- """Load a new collection, firing events based on prior like membership.
-
- Appends instances in ``values`` onto the ``new_adapter``. Events will be
- fired for any instance not present in the ``existing_adapter``. Any
- instances in ``existing_adapter`` not present in ``values`` will have
- remove events fired upon them.
-
- values
- An iterable of collection member instances
-
- existing_adapter
- A CollectionAdapter of instances to be replaced
-
- new_adapter
- An empty CollectionAdapter to load with ``values``
-
-
- """
- if not isinstance(values, list):
- values = list(values)
-
- idset = util.IdentitySet
- constants = idset(existing_adapter or ()).intersection(values or ())
- additions = idset(values or ()).difference(constants)
- removals = idset(existing_adapter or ()).difference(constants)
-
- for member in values or ():
- if member in additions:
- new_adapter.append_with_event(member)
- elif member in constants:
- new_adapter.append_without_event(member)
-
- if existing_adapter:
- for member in removals:
- existing_adapter.remove_with_event(member)
-
-def prepare_instrumentation(factory):
- """Prepare a callable for future use as a collection class factory.
-
- Given a collection class factory (either a type or no-arg callable),
- return another factory that will produce compatible instances when
- called.
-
- This function is responsible for converting collection_class=list
- into the run-time behavior of collection_class=InstrumentedList.
-
- """
- # Convert a builtin to 'Instrumented*'
- if factory in __canned_instrumentation:
- factory = __canned_instrumentation[factory]
-
- # Create a specimen
- cls = type(factory())
-
- # Did factory callable return a builtin?
- if cls in __canned_instrumentation:
- # Wrap it so that it returns our 'Instrumented*'
- factory = __converting_factory(factory)
- cls = factory()
-
- # Instrument the class if needed.
- if __instrumentation_mutex.acquire():
- try:
- if getattr(cls, '_sa_instrumented', None) != id(cls):
- _instrument_class(cls)
- finally:
- __instrumentation_mutex.release()
-
- return factory
-
-def __converting_factory(original_factory):
- """Convert the type returned by collection factories on the fly.
-
- Given a collection factory that returns a builtin type (e.g. a list),
- return a wrapped function that converts that type to one of our
- instrumented types.
-
- """
- def wrapper():
- collection = original_factory()
- type_ = type(collection)
- if type_ in __canned_instrumentation:
- # return an instrumented type initialized from the factory's
- # collection
- return __canned_instrumentation[type_](collection)
- else:
- raise sa_exc.InvalidRequestError(
- "Collection class factories must produce instances of a "
- "single class.")
- try:
- # often flawed but better than nothing
- wrapper.__name__ = "%sWrapper" % original_factory.__name__
- wrapper.__doc__ = original_factory.__doc__
- except:
- pass
- return wrapper
-
-def _instrument_class(cls):
- """Modify methods in a class and install instrumentation."""
-
- # TODO: more formally document this as a decoratorless/Python 2.3
- # option for specifying instrumentation. (likely doc'd here in code only,
- # not in online docs.) Useful for C types too.
- #
- # __instrumentation__ = {
- # 'rolename': 'methodname', # ...
- # 'methods': {
- # 'methodname': ('fire_{append,remove}_event', argspec,
- # 'fire_{append,remove}_event'),
- # 'append': ('fire_append_event', 1, None),
- # '__setitem__': ('fire_append_event', 1, 'fire_remove_event'),
- # 'pop': (None, None, 'fire_remove_event'),
- # }
- # }
-
- # In the normal call flow, a request for any of the 3 basic collection
- # types is transformed into one of our trivial subclasses
- # (e.g. InstrumentedList). Catch anything else that sneaks in here...
- if cls.__module__ == '__builtin__':
- raise sa_exc.ArgumentError(
- "Can not instrument a built-in type. Use a "
- "subclass, even a trivial one.")
-
- collection_type = util.duck_type_collection(cls)
- if collection_type in __interfaces:
- roles = __interfaces[collection_type].copy()
- decorators = roles.pop('_decorators', {})
- else:
- roles, decorators = {}, {}
-
- if hasattr(cls, '__instrumentation__'):
- roles.update(copy.deepcopy(getattr(cls, '__instrumentation__')))
-
- methods = roles.pop('methods', {})
-
- for name in dir(cls):
- method = getattr(cls, name, None)
- if not util.callable(method):
- continue
-
- # note role declarations
- if hasattr(method, '_sa_instrument_role'):
- role = method._sa_instrument_role
- assert role in ('appender', 'remover', 'iterator',
- 'link', 'converter')
- roles[role] = name
-
- # transfer instrumentation requests from decorated function
- # to the combined queue
- before, after = None, None
- if hasattr(method, '_sa_instrument_before'):
- op, argument = method._sa_instrument_before
- assert op in ('fire_append_event', 'fire_remove_event')
- before = op, argument
- if hasattr(method, '_sa_instrument_after'):
- op = method._sa_instrument_after
- assert op in ('fire_append_event', 'fire_remove_event')
- after = op
- if before:
- methods[name] = before[0], before[1], after
- elif after:
- methods[name] = None, None, after
-
- # apply ABC auto-decoration to methods that need it
- for method, decorator in decorators.items():
- fn = getattr(cls, method, None)
- if (fn and method not in methods and
- not hasattr(fn, '_sa_instrumented')):
- setattr(cls, method, decorator(fn))
-
- # ensure all roles are present, and apply implicit instrumentation if
- # needed
- if 'appender' not in roles or not hasattr(cls, roles['appender']):
- raise sa_exc.ArgumentError(
- "Type %s must elect an appender method to be "
- "a collection class" % cls.__name__)
- elif (roles['appender'] not in methods and
- not hasattr(getattr(cls, roles['appender']), '_sa_instrumented')):
- methods[roles['appender']] = ('fire_append_event', 1, None)
-
- if 'remover' not in roles or not hasattr(cls, roles['remover']):
- raise sa_exc.ArgumentError(
- "Type %s must elect a remover method to be "
- "a collection class" % cls.__name__)
- elif (roles['remover'] not in methods and
- not hasattr(getattr(cls, roles['remover']), '_sa_instrumented')):
- methods[roles['remover']] = ('fire_remove_event', 1, None)
-
- if 'iterator' not in roles or not hasattr(cls, roles['iterator']):
- raise sa_exc.ArgumentError(
- "Type %s must elect an iterator method to be "
- "a collection class" % cls.__name__)
-
- # apply ad-hoc instrumentation from decorators, class-level defaults
- # and implicit role declarations
- for method, (before, argument, after) in methods.items():
- setattr(cls, method,
- _instrument_membership_mutator(getattr(cls, method),
- before, argument, after))
- # intern the role map
- for role, method in roles.items():
- setattr(cls, '_sa_%s' % role, getattr(cls, method))
-
- setattr(cls, '_sa_instrumented', id(cls))
-
-def _instrument_membership_mutator(method, before, argument, after):
- """Route method args and/or return value through the collection adapter."""
- # This isn't smart enough to handle @adds(1) for 'def fn(self, (a, b))'
- if before:
- fn_args = list(util.flatten_iterator(inspect.getargspec(method)[0]))
- if type(argument) is int:
- pos_arg = argument
- named_arg = len(fn_args) > argument and fn_args[argument] or None
- else:
- if argument in fn_args:
- pos_arg = fn_args.index(argument)
- else:
- pos_arg = None
- named_arg = argument
- del fn_args
-
- def wrapper(*args, **kw):
- if before:
- if pos_arg is None:
- if named_arg not in kw:
- raise sa_exc.ArgumentError(
- "Missing argument %s" % argument)
- value = kw[named_arg]
- else:
- if len(args) > pos_arg:
- value = args[pos_arg]
- elif named_arg in kw:
- value = kw[named_arg]
- else:
- raise sa_exc.ArgumentError(
- "Missing argument %s" % argument)
-
- initiator = kw.pop('_sa_initiator', None)
- if initiator is False:
- executor = None
- else:
- executor = getattr(args[0], '_sa_adapter', None)
-
- if before and executor:
- getattr(executor, before)(value, initiator)
-
- if not after or not executor:
- return method(*args, **kw)
- else:
- res = method(*args, **kw)
- if res is not None:
- getattr(executor, after)(res, initiator)
- return res
- try:
- wrapper._sa_instrumented = True
- wrapper.__name__ = method.__name__
- wrapper.__doc__ = method.__doc__
- except:
- pass
- return wrapper
-
-def __set(collection, item, _sa_initiator=None):
- """Run set events, may eventually be inlined into decorators."""
-
- if _sa_initiator is not False and item is not None:
- executor = getattr(collection, '_sa_adapter', None)
- if executor:
- item = getattr(executor, 'fire_append_event')(item, _sa_initiator)
- return item
-
-def __del(collection, item, _sa_initiator=None):
- """Run del events, may eventually be inlined into decorators."""
- if _sa_initiator is not False and item is not None:
- executor = getattr(collection, '_sa_adapter', None)
- if executor:
- getattr(executor, 'fire_remove_event')(item, _sa_initiator)
-
-def __before_delete(collection, _sa_initiator=None):
- """Special method to run 'commit existing value' methods"""
- executor = getattr(collection, '_sa_adapter', None)
- if executor:
- getattr(executor, 'fire_pre_remove_event')(_sa_initiator)
-
-def _list_decorators():
- """Tailored instrumentation wrappers for any list-like class."""
-
- def _tidy(fn):
- setattr(fn, '_sa_instrumented', True)
- fn.__doc__ = getattr(getattr(list, fn.__name__), '__doc__')
-
- def append(fn):
- def append(self, item, _sa_initiator=None):
- item = __set(self, item, _sa_initiator)
- fn(self, item)
- _tidy(append)
- return append
-
- def remove(fn):
- def remove(self, value, _sa_initiator=None):
- __before_delete(self, _sa_initiator)
- # testlib.pragma exempt:__eq__
- fn(self, value)
- __del(self, value, _sa_initiator)
- _tidy(remove)
- return remove
-
- def insert(fn):
- def insert(self, index, value):
- value = __set(self, value)
- fn(self, index, value)
- _tidy(insert)
- return insert
-
- def __setitem__(fn):
- def __setitem__(self, index, value):
- if not isinstance(index, slice):
- existing = self[index]
- if existing is not None:
- __del(self, existing)
- value = __set(self, value)
- fn(self, index, value)
- else:
- # slice assignment requires __delitem__, insert, __len__
- step = index.step or 1
- start = index.start or 0
- if start < 0:
- start += len(self)
- stop = index.stop or len(self)
- if stop < 0:
- stop += len(self)
-
- if step == 1:
- for i in xrange(start, stop, step):
- if len(self) > start:
- del self[start]
-
- for i, item in enumerate(value):
- self.insert(i + start, item)
- else:
- rng = range(start, stop, step)
- if len(value) != len(rng):
- raise ValueError(
- "attempt to assign sequence of size %s to "
- "extended slice of size %s" % (len(value),
- len(rng)))
- for i, item in zip(rng, value):
- self.__setitem__(i, item)
- _tidy(__setitem__)
- return __setitem__
-
- def __delitem__(fn):
- def __delitem__(self, index):
- if not isinstance(index, slice):
- item = self[index]
- __del(self, item)
- fn(self, index)
- else:
- # slice deletion requires __getslice__ and a slice-groking
- # __getitem__ for stepped deletion
- # note: not breaking this into atomic dels
- for item in self[index]:
- __del(self, item)
- fn(self, index)
- _tidy(__delitem__)
- return __delitem__
-
- # Py2K
- def __setslice__(fn):
- def __setslice__(self, start, end, values):
- for value in self[start:end]:
- __del(self, value)
- values = [__set(self, value) for value in values]
- fn(self, start, end, values)
- _tidy(__setslice__)
- return __setslice__
-
- def __delslice__(fn):
- def __delslice__(self, start, end):
- for value in self[start:end]:
- __del(self, value)
- fn(self, start, end)
- _tidy(__delslice__)
- return __delslice__
- # end Py2K
-
- def extend(fn):
- def extend(self, iterable):
- for value in iterable:
- self.append(value)
- _tidy(extend)
- return extend
-
- def __iadd__(fn):
- def __iadd__(self, iterable):
- # list.__iadd__ takes any iterable and seems to let TypeError raise
- # as-is instead of returning NotImplemented
- for value in iterable:
- self.append(value)
- return self
- _tidy(__iadd__)
- return __iadd__
-
- def pop(fn):
- def pop(self, index=-1):
- __before_delete(self)
- item = fn(self, index)
- __del(self, item)
- return item
- _tidy(pop)
- return pop
-
- # __imul__ : not wrapping this. all members of the collection are already
- # present, so no need to fire appends... wrapping it with an explicit
- # decorator is still possible, so events on *= can be had if they're
- # desired. hard to imagine a use case for __imul__, though.
-
- l = locals().copy()
- l.pop('_tidy')
- return l
-
-def _dict_decorators():
- """Tailored instrumentation wrappers for any dict-like mapping class."""
-
- def _tidy(fn):
- setattr(fn, '_sa_instrumented', True)
- fn.__doc__ = getattr(getattr(dict, fn.__name__), '__doc__')
-
- Unspecified = util.symbol('Unspecified')
-
- def __setitem__(fn):
- def __setitem__(self, key, value, _sa_initiator=None):
- if key in self:
- __del(self, self[key], _sa_initiator)
- value = __set(self, value, _sa_initiator)
- fn(self, key, value)
- _tidy(__setitem__)
- return __setitem__
-
- def __delitem__(fn):
- def __delitem__(self, key, _sa_initiator=None):
- if key in self:
- __del(self, self[key], _sa_initiator)
- fn(self, key)
- _tidy(__delitem__)
- return __delitem__
-
- def clear(fn):
- def clear(self):
- for key in self:
- __del(self, self[key])
- fn(self)
- _tidy(clear)
- return clear
-
- def pop(fn):
- def pop(self, key, default=Unspecified):
- if key in self:
- __del(self, self[key])
- if default is Unspecified:
- return fn(self, key)
- else:
- return fn(self, key, default)
- _tidy(pop)
- return pop
-
- def popitem(fn):
- def popitem(self):
- __before_delete(self)
- item = fn(self)
- __del(self, item[1])
- return item
- _tidy(popitem)
- return popitem
-
- def setdefault(fn):
- def setdefault(self, key, default=None):
- if key not in self:
- self.__setitem__(key, default)
- return default
- else:
- return self.__getitem__(key)
- _tidy(setdefault)
- return setdefault
-
- if sys.version_info < (2, 4):
- def update(fn):
- def update(self, other):
- for key in other.keys():
- if key not in self or self[key] is not other[key]:
- self[key] = other[key]
- _tidy(update)
- return update
- else:
- def update(fn):
- def update(self, __other=Unspecified, **kw):
- if __other is not Unspecified:
- if hasattr(__other, 'keys'):
- for key in __other.keys():
- if (key not in self or
- self[key] is not __other[key]):
- self[key] = __other[key]
- else:
- for key, value in __other:
- if key not in self or self[key] is not value:
- self[key] = value
- for key in kw:
- if key not in self or self[key] is not kw[key]:
- self[key] = kw[key]
- _tidy(update)
- return update
-
- l = locals().copy()
- l.pop('_tidy')
- l.pop('Unspecified')
- return l
-
-if util.py3k:
- _set_binop_bases = (set, frozenset)
-else:
- import sets
- _set_binop_bases = (set, frozenset, sets.BaseSet)
-
-def _set_binops_check_strict(self, obj):
- """Allow only set, frozenset and self.__class__-derived objects in binops."""
- return isinstance(obj, _set_binop_bases + (self.__class__,))
-
-def _set_binops_check_loose(self, obj):
- """Allow anything set-like to participate in set binops."""
- return (isinstance(obj, _set_binop_bases + (self.__class__,)) or
- util.duck_type_collection(obj) == set)
-
-
-def _set_decorators():
- """Tailored instrumentation wrappers for any set-like class."""
-
- def _tidy(fn):
- setattr(fn, '_sa_instrumented', True)
- fn.__doc__ = getattr(getattr(set, fn.__name__), '__doc__')
-
- Unspecified = util.symbol('Unspecified')
-
- def add(fn):
- def add(self, value, _sa_initiator=None):
- if value not in self:
- value = __set(self, value, _sa_initiator)
- # testlib.pragma exempt:__hash__
- fn(self, value)
- _tidy(add)
- return add
-
- if sys.version_info < (2, 4):
- def discard(fn):
- def discard(self, value, _sa_initiator=None):
- if value in self:
- self.remove(value, _sa_initiator)
- _tidy(discard)
- return discard
- else:
- def discard(fn):
- def discard(self, value, _sa_initiator=None):
- # testlib.pragma exempt:__hash__
- if value in self:
- __del(self, value, _sa_initiator)
- # testlib.pragma exempt:__hash__
- fn(self, value)
- _tidy(discard)
- return discard
-
- def remove(fn):
- def remove(self, value, _sa_initiator=None):
- # testlib.pragma exempt:__hash__
- if value in self:
- __del(self, value, _sa_initiator)
- # testlib.pragma exempt:__hash__
- fn(self, value)
- _tidy(remove)
- return remove
-
- def pop(fn):
- def pop(self):
- __before_delete(self)
- item = fn(self)
- __del(self, item)
- return item
- _tidy(pop)
- return pop
-
- def clear(fn):
- def clear(self):
- for item in list(self):
- self.remove(item)
- _tidy(clear)
- return clear
-
- def update(fn):
- def update(self, value):
- for item in value:
- self.add(item)
- _tidy(update)
- return update
-
- def __ior__(fn):
- def __ior__(self, value):
- if not _set_binops_check_strict(self, value):
- return NotImplemented
- for item in value:
- self.add(item)
- return self
- _tidy(__ior__)
- return __ior__
-
- def difference_update(fn):
- def difference_update(self, value):
- for item in value:
- self.discard(item)
- _tidy(difference_update)
- return difference_update
-
- def __isub__(fn):
- def __isub__(self, value):
- if not _set_binops_check_strict(self, value):
- return NotImplemented
- for item in value:
- self.discard(item)
- return self
- _tidy(__isub__)
- return __isub__
-
- def intersection_update(fn):
- def intersection_update(self, other):
- want, have = self.intersection(other), set(self)
- remove, add = have - want, want - have
-
- for item in remove:
- self.remove(item)
- for item in add:
- self.add(item)
- _tidy(intersection_update)
- return intersection_update
-
- def __iand__(fn):
- def __iand__(self, other):
- if not _set_binops_check_strict(self, other):
- return NotImplemented
- want, have = self.intersection(other), set(self)
- remove, add = have - want, want - have
-
- for item in remove:
- self.remove(item)
- for item in add:
- self.add(item)
- return self
- _tidy(__iand__)
- return __iand__
-
- def symmetric_difference_update(fn):
- def symmetric_difference_update(self, other):
- want, have = self.symmetric_difference(other), set(self)
- remove, add = have - want, want - have
-
- for item in remove:
- self.remove(item)
- for item in add:
- self.add(item)
- _tidy(symmetric_difference_update)
- return symmetric_difference_update
-
- def __ixor__(fn):
- def __ixor__(self, other):
- if not _set_binops_check_strict(self, other):
- return NotImplemented
- want, have = self.symmetric_difference(other), set(self)
- remove, add = have - want, want - have
-
- for item in remove:
- self.remove(item)
- for item in add:
- self.add(item)
- return self
- _tidy(__ixor__)
- return __ixor__
-
- l = locals().copy()
- l.pop('_tidy')
- l.pop('Unspecified')
- return l
-
-
-class InstrumentedList(list):
- """An instrumented version of the built-in list."""
-
- __instrumentation__ = {
- 'appender': 'append',
- 'remover': 'remove',
- 'iterator': '__iter__', }
-
-class InstrumentedSet(set):
- """An instrumented version of the built-in set."""
-
- __instrumentation__ = {
- 'appender': 'add',
- 'remover': 'remove',
- 'iterator': '__iter__', }
-
-class InstrumentedDict(dict):
- """An instrumented version of the built-in dict."""
-
- # Py3K
- #__instrumentation__ = {
- # 'iterator': 'values', }
- # Py2K
- __instrumentation__ = {
- 'iterator': 'itervalues', }
- # end Py2K
-
-__canned_instrumentation = {
- list: InstrumentedList,
- set: InstrumentedSet,
- dict: InstrumentedDict,
- }
-
-__interfaces = {
- list: {'appender': 'append',
- 'remover': 'remove',
- 'iterator': '__iter__',
- '_decorators': _list_decorators(), },
- set: {'appender': 'add',
- 'remover': 'remove',
- 'iterator': '__iter__',
- '_decorators': _set_decorators(), },
- # decorators are required for dicts and object collections.
- # Py3K
- #dict: {'iterator': 'values',
- # '_decorators': _dict_decorators(), },
- # Py2K
- dict: {'iterator': 'itervalues',
- '_decorators': _dict_decorators(), },
- # end Py2K
- # < 0.4 compatible naming, deprecated- use decorators instead.
- None: {}
- }
-
-class MappedCollection(dict):
- """A basic dictionary-based collection class.
-
- Extends dict with the minimal bag semantics that collection classes require.
- ``set`` and ``remove`` are implemented in terms of a keying function: any
- callable that takes an object and returns an object for use as a dictionary
- key.
-
- """
-
- def __init__(self, keyfunc):
- """Create a new collection with keying provided by keyfunc.
-
- keyfunc may be any callable any callable that takes an object and
- returns an object for use as a dictionary key.
-
- The keyfunc will be called every time the ORM needs to add a member by
- value-only (such as when loading instances from the database) or
- remove a member. The usual cautions about dictionary keying apply-
- ``keyfunc(object)`` should return the same output for the life of the
- collection. Keying based on mutable properties can result in
- unreachable instances "lost" in the collection.
-
- """
- self.keyfunc = keyfunc
-
- def set(self, value, _sa_initiator=None):
- """Add an item by value, consulting the keyfunc for the key."""
-
- key = self.keyfunc(value)
- self.__setitem__(key, value, _sa_initiator)
- set = collection.internally_instrumented(set)
- set = collection.appender(set)
-
- def remove(self, value, _sa_initiator=None):
- """Remove an item by value, consulting the keyfunc for the key."""
-
- key = self.keyfunc(value)
- # Let self[key] raise if key is not in this collection
- # testlib.pragma exempt:__ne__
- if self[key] != value:
- raise sa_exc.InvalidRequestError(
- "Can not remove '%s': collection holds '%s' for key '%s'. "
- "Possible cause: is the MappedCollection key function "
- "based on mutable properties or properties that only obtain "
- "values after flush?" %
- (value, self[key], key))
- self.__delitem__(key, _sa_initiator)
- remove = collection.internally_instrumented(remove)
- remove = collection.remover(remove)
-
- def _convert(self, dictlike):
- """Validate and convert a dict-like object into values for set()ing.
-
- This is called behind the scenes when a MappedCollection is replaced
- entirely by another collection, as in::
-
- myobj.mappedcollection = {'a':obj1, 'b': obj2} # ...
-
- Raises a TypeError if the key in any (key, value) pair in the dictlike
- object does not match the key that this collection's keyfunc would
- have assigned for that value.
-
- """
- for incoming_key, value in util.dictlike_iteritems(dictlike):
- new_key = self.keyfunc(value)
- if incoming_key != new_key:
- raise TypeError(
- "Found incompatible key %r for value %r; this collection's "
- "keying function requires a key of %r for this value." % (
- incoming_key, value, new_key))
- yield value
- _convert = collection.converter(_convert)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dependency.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dependency.py
deleted file mode 100755
index 44858fb8..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dependency.py
+++ /dev/null
@@ -1,1161 +0,0 @@
-# orm/dependency.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Relationship dependencies.
-
-"""
-
-from sqlalchemy import sql, util, exc as sa_exc
-from sqlalchemy.orm import attributes, exc, sync, unitofwork, \
- util as mapperutil
-from sqlalchemy.orm.interfaces import ONETOMANY, MANYTOONE, MANYTOMANY
-
-class DependencyProcessor(object):
- def __init__(self, prop):
- self.prop = prop
- self.cascade = prop.cascade
- self.mapper = prop.mapper
- self.parent = prop.parent
- self.secondary = prop.secondary
- self.direction = prop.direction
- self.post_update = prop.post_update
- self.passive_deletes = prop.passive_deletes
- self.passive_updates = prop.passive_updates
- self.enable_typechecks = prop.enable_typechecks
- if self.passive_deletes:
- self._passive_delete_flag = attributes.PASSIVE_NO_INITIALIZE
- else:
- self._passive_delete_flag = attributes.PASSIVE_OFF
- if self.passive_updates:
- self._passive_update_flag = attributes.PASSIVE_NO_INITIALIZE
- else:
- self._passive_update_flag= attributes.PASSIVE_OFF
-
- self.key = prop.key
- if not self.prop.synchronize_pairs:
- raise sa_exc.ArgumentError(
- "Can't build a DependencyProcessor for relationship %s. "
- "No target attributes to populate between parent and "
- "child are present" %
- self.prop)
-
- @classmethod
- def from_relationship(cls, prop):
- return _direction_to_processor[prop.direction](prop)
-
- def hasparent(self, state):
- """return True if the given object instance has a parent,
- according to the ``InstrumentedAttribute`` handled by this
- ``DependencyProcessor``.
-
- """
- return self.parent.class_manager.get_impl(self.key).hasparent(state)
-
- def per_property_preprocessors(self, uow):
- """establish actions and dependencies related to a flush.
-
- These actions will operate on all relevant states in
- the aggregate.
-
- """
- uow.register_preprocessor(self, True)
-
-
- def per_property_flush_actions(self, uow):
- after_save = unitofwork.ProcessAll(uow, self, False, True)
- before_delete = unitofwork.ProcessAll(uow, self, True, True)
-
- parent_saves = unitofwork.SaveUpdateAll(
- uow,
- self.parent.primary_base_mapper
- )
- child_saves = unitofwork.SaveUpdateAll(
- uow,
- self.mapper.primary_base_mapper
- )
-
- parent_deletes = unitofwork.DeleteAll(
- uow,
- self.parent.primary_base_mapper
- )
- child_deletes = unitofwork.DeleteAll(
- uow,
- self.mapper.primary_base_mapper
- )
-
- self.per_property_dependencies(uow,
- parent_saves,
- child_saves,
- parent_deletes,
- child_deletes,
- after_save,
- before_delete
- )
-
-
- def per_state_flush_actions(self, uow, states, isdelete):
- """establish actions and dependencies related to a flush.
-
- These actions will operate on all relevant states
- individually. This occurs only if there are cycles
- in the 'aggregated' version of events.
-
- """
-
- parent_base_mapper = self.parent.primary_base_mapper
- child_base_mapper = self.mapper.primary_base_mapper
- child_saves = unitofwork.SaveUpdateAll(uow, child_base_mapper)
- child_deletes = unitofwork.DeleteAll(uow, child_base_mapper)
-
- # locate and disable the aggregate processors
- # for this dependency
-
- if isdelete:
- before_delete = unitofwork.ProcessAll(uow, self, True, True)
- before_delete.disabled = True
- else:
- after_save = unitofwork.ProcessAll(uow, self, False, True)
- after_save.disabled = True
-
- # check if the "child" side is part of the cycle
-
- if child_saves not in uow.cycles:
- # based on the current dependencies we use, the saves/
- # deletes should always be in the 'cycles' collection
- # together. if this changes, we will have to break up
- # this method a bit more.
- assert child_deletes not in uow.cycles
-
- # child side is not part of the cycle, so we will link per-state
- # actions to the aggregate "saves", "deletes" actions
- child_actions = [
- (child_saves, False), (child_deletes, True)
- ]
- child_in_cycles = False
- else:
- child_in_cycles = True
-
- # check if the "parent" side is part of the cycle
- if not isdelete:
- parent_saves = unitofwork.SaveUpdateAll(
- uow,
- self.parent.base_mapper)
- parent_deletes = before_delete = None
- if parent_saves in uow.cycles:
- parent_in_cycles = True
- else:
- parent_deletes = unitofwork.DeleteAll(
- uow,
- self.parent.base_mapper)
- parent_saves = after_save = None
- if parent_deletes in uow.cycles:
- parent_in_cycles = True
-
- # now create actions /dependencies for each state.
- for state in states:
- # detect if there's anything changed or loaded
- # by a preprocessor on this state/attribute. if not,
- # we should be able to skip it entirely.
- sum_ = state.manager[self.key].impl.get_all_pending(state, state.dict)
-
- if not sum_:
- continue
-
- if isdelete:
- before_delete = unitofwork.ProcessState(uow,
- self, True, state)
- if parent_in_cycles:
- parent_deletes = unitofwork.DeleteState(
- uow,
- state,
- parent_base_mapper)
- else:
- after_save = unitofwork.ProcessState(uow, self, False, state)
- if parent_in_cycles:
- parent_saves = unitofwork.SaveUpdateState(
- uow,
- state,
- parent_base_mapper)
-
- if child_in_cycles:
- child_actions = []
- for child_state, child in sum_:
- if child_state not in uow.states:
- child_action = (None, None)
- else:
- (deleted, listonly) = uow.states[child_state]
- if deleted:
- child_action = (
- unitofwork.DeleteState(
- uow, child_state,
- child_base_mapper),
- True)
- else:
- child_action = (
- unitofwork.SaveUpdateState(
- uow, child_state,
- child_base_mapper),
- False)
- child_actions.append(child_action)
-
- # establish dependencies between our possibly per-state
- # parent action and our possibly per-state child action.
- for child_action, childisdelete in child_actions:
- self.per_state_dependencies(uow, parent_saves,
- parent_deletes,
- child_action,
- after_save, before_delete,
- isdelete, childisdelete)
-
-
- def presort_deletes(self, uowcommit, states):
- return False
-
- def presort_saves(self, uowcommit, states):
- return False
-
- def process_deletes(self, uowcommit, states):
- pass
-
- def process_saves(self, uowcommit, states):
- pass
-
- def prop_has_changes(self, uowcommit, states, isdelete):
- if not isdelete or self.passive_deletes:
- passive = attributes.PASSIVE_NO_INITIALIZE
- elif self.direction is MANYTOONE:
- passive = attributes.PASSIVE_NO_FETCH_RELATED
- else:
- passive = attributes.PASSIVE_OFF
-
- for s in states:
- # TODO: add a high speed method
- # to InstanceState which returns: attribute
- # has a non-None value, or had one
- history = uowcommit.get_attribute_history(
- s,
- self.key,
- passive)
- if history and not history.empty():
- return True
- else:
- return states and \
- not self.prop._is_self_referential() and \
- self.mapper in uowcommit.mappers
-
- def _verify_canload(self, state):
- if state is not None and \
- not self.mapper._canload(state,
- allow_subtypes=not self.enable_typechecks):
- if self.mapper._canload(state, allow_subtypes=True):
- raise exc.FlushError('Attempting to flush an item of type '
- '%(x)s as a member of collection '
- '"%(y)s". Expected an object of type '
- '%(z)s or a polymorphic subclass of '
- 'this type. If %(x)s is a subclass of '
- '%(z)s, configure mapper "%(zm)s" to '
- 'load this subtype polymorphically, or '
- 'set enable_typechecks=False to allow '
- 'any subtype to be accepted for flush. '
- % {
- 'x': state.class_,
- 'y': self.prop,
- 'z': self.mapper.class_,
- 'zm': self.mapper,
- })
- else:
- raise exc.FlushError(
- 'Attempting to flush an item of type '
- '%(x)s as a member of collection '
- '"%(y)s". Expected an object of type '
- '%(z)s or a polymorphic subclass of '
- 'this type.' % {
- 'x': state.class_,
- 'y': self.prop,
- 'z': self.mapper.class_,
- })
-
- def _synchronize(self, state, child, associationrow,
- clearkeys, uowcommit):
- raise NotImplementedError()
-
- def _get_reversed_processed_set(self, uow):
- if not self.prop._reverse_property:
- return None
-
- process_key = tuple(sorted(
- [self.key] +
- [p.key for p in self.prop._reverse_property]
- ))
- return uow.memo(
- ('reverse_key', process_key),
- set
- )
-
- def _post_update(self, state, uowcommit, related):
- for x in related:
- if x is not None:
- uowcommit.issue_post_update(
- state,
- [r for l, r in self.prop.synchronize_pairs]
- )
- break
-
- def _pks_changed(self, uowcommit, state):
- raise NotImplementedError()
-
- def __repr__(self):
- return "%s(%s)" % (self.__class__.__name__, self.prop)
-
-class OneToManyDP(DependencyProcessor):
-
- def per_property_dependencies(self, uow, parent_saves,
- child_saves,
- parent_deletes,
- child_deletes,
- after_save,
- before_delete,
- ):
- if self.post_update:
- child_post_updates = unitofwork.IssuePostUpdate(
- uow,
- self.mapper.primary_base_mapper,
- False)
- child_pre_updates = unitofwork.IssuePostUpdate(
- uow,
- self.mapper.primary_base_mapper,
- True)
-
- uow.dependencies.update([
- (child_saves, after_save),
- (parent_saves, after_save),
- (after_save, child_post_updates),
-
- (before_delete, child_pre_updates),
- (child_pre_updates, parent_deletes),
- (child_pre_updates, child_deletes),
-
- ])
- else:
- uow.dependencies.update([
- (parent_saves, after_save),
- (after_save, child_saves),
- (after_save, child_deletes),
-
- (child_saves, parent_deletes),
- (child_deletes, parent_deletes),
-
- (before_delete, child_saves),
- (before_delete, child_deletes),
- ])
-
- def per_state_dependencies(self, uow,
- save_parent,
- delete_parent,
- child_action,
- after_save, before_delete,
- isdelete, childisdelete):
-
- if self.post_update:
-
- child_post_updates = unitofwork.IssuePostUpdate(
- uow,
- self.mapper.primary_base_mapper,
- False)
- child_pre_updates = unitofwork.IssuePostUpdate(
- uow,
- self.mapper.primary_base_mapper,
- True)
-
- # TODO: this whole block is not covered
- # by any tests
- if not isdelete:
- if childisdelete:
- uow.dependencies.update([
- (child_action, after_save),
- (after_save, child_post_updates),
- ])
- else:
- uow.dependencies.update([
- (save_parent, after_save),
- (child_action, after_save),
- (after_save, child_post_updates),
- ])
- else:
- if childisdelete:
- uow.dependencies.update([
- (before_delete, child_pre_updates),
- (child_pre_updates, delete_parent),
- ])
- else:
- uow.dependencies.update([
- (before_delete, child_pre_updates),
- (child_pre_updates, delete_parent),
- ])
- elif not isdelete:
- uow.dependencies.update([
- (save_parent, after_save),
- (after_save, child_action),
- (save_parent, child_action)
- ])
- else:
- uow.dependencies.update([
- (before_delete, child_action),
- (child_action, delete_parent)
- ])
-
- def presort_deletes(self, uowcommit, states):
- # head object is being deleted, and we manage its list of
- # child objects the child objects have to have their
- # foreign key to the parent set to NULL
- should_null_fks = not self.cascade.delete and \
- not self.passive_deletes == 'all'
-
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
- if history:
- for child in history.deleted:
- if child is not None and self.hasparent(child) is False:
- if self.cascade.delete_orphan:
- uowcommit.register_object(child, isdelete=True)
- else:
- uowcommit.register_object(child)
-
- if should_null_fks:
- for child in history.unchanged:
- if child is not None:
- uowcommit.register_object(child,
- operation="delete", prop=self.prop)
-
-
-
- def presort_saves(self, uowcommit, states):
- children_added = uowcommit.memo(('children_added', self), set)
-
- for state in states:
- pks_changed = self._pks_changed(uowcommit, state)
-
- if not pks_changed or self.passive_updates:
- passive = attributes.PASSIVE_NO_INITIALIZE
- else:
- passive = attributes.PASSIVE_OFF
-
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- passive)
- if history:
- for child in history.added:
- if child is not None:
- uowcommit.register_object(child, cancel_delete=True,
- operation="add",
- prop=self.prop)
-
- children_added.update(history.added)
-
- for child in history.deleted:
- if not self.cascade.delete_orphan:
- uowcommit.register_object(child, isdelete=False,
- operation='delete',
- prop=self.prop)
- elif self.hasparent(child) is False:
- uowcommit.register_object(child, isdelete=True,
- operation="delete", prop=self.prop)
- for c, m, st_, dct_ in self.mapper.cascade_iterator(
- 'delete', child):
- uowcommit.register_object(
- st_,
- isdelete=True)
-
- if pks_changed:
- if history:
- for child in history.unchanged:
- if child is not None:
- uowcommit.register_object(
- child,
- False,
- self.passive_updates,
- operation="pk change",
- prop=self.prop)
-
- def process_deletes(self, uowcommit, states):
- # head object is being deleted, and we manage its list of
- # child objects the child objects have to have their foreign
- # key to the parent set to NULL this phase can be called
- # safely for any cascade but is unnecessary if delete cascade
- # is on.
-
- if self.post_update or not self.passive_deletes == 'all':
- children_added = uowcommit.memo(('children_added', self), set)
-
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
- if history:
- for child in history.deleted:
- if child is not None and \
- self.hasparent(child) is False:
- self._synchronize(
- state,
- child,
- None, True,
- uowcommit, False)
- if self.post_update and child:
- self._post_update(child, uowcommit, [state])
-
- if self.post_update or not self.cascade.delete:
- for child in set(history.unchanged).\
- difference(children_added):
- if child is not None:
- self._synchronize(
- state,
- child,
- None, True,
- uowcommit, False)
- if self.post_update and child:
- self._post_update(child,
- uowcommit,
- [state])
-
- # technically, we can even remove each child from the
- # collection here too. but this would be a somewhat
- # inconsistent behavior since it wouldn't happen
- #if the old parent wasn't deleted but child was moved.
-
- def process_saves(self, uowcommit, states):
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- attributes.PASSIVE_NO_INITIALIZE)
- if history:
- for child in history.added:
- self._synchronize(state, child, None,
- False, uowcommit, False)
- if child is not None and self.post_update:
- self._post_update(child, uowcommit, [state])
-
- for child in history.deleted:
- if not self.cascade.delete_orphan and \
- not self.hasparent(child):
- self._synchronize(state, child, None, True,
- uowcommit, False)
-
- if self._pks_changed(uowcommit, state):
- for child in history.unchanged:
- self._synchronize(state, child, None,
- False, uowcommit, True)
-
- def _synchronize(self, state, child,
- associationrow, clearkeys, uowcommit,
- pks_changed):
- source = state
- dest = child
- if dest is None or \
- (not self.post_update and uowcommit.is_deleted(dest)):
- return
- self._verify_canload(child)
- if clearkeys:
- sync.clear(dest, self.mapper, self.prop.synchronize_pairs)
- else:
- sync.populate(source, self.parent, dest, self.mapper,
- self.prop.synchronize_pairs, uowcommit,
- self.passive_updates and pks_changed)
-
- def _pks_changed(self, uowcommit, state):
- return sync.source_modified(
- uowcommit,
- state,
- self.parent,
- self.prop.synchronize_pairs)
-
-class ManyToOneDP(DependencyProcessor):
- def __init__(self, prop):
- DependencyProcessor.__init__(self, prop)
- self.mapper._dependency_processors.append(DetectKeySwitch(prop))
-
- def per_property_dependencies(self, uow,
- parent_saves,
- child_saves,
- parent_deletes,
- child_deletes,
- after_save,
- before_delete):
-
- if self.post_update:
- parent_post_updates = unitofwork.IssuePostUpdate(
- uow,
- self.parent.primary_base_mapper,
- False)
- parent_pre_updates = unitofwork.IssuePostUpdate(
- uow,
- self.parent.primary_base_mapper,
- True)
-
- uow.dependencies.update([
- (child_saves, after_save),
- (parent_saves, after_save),
- (after_save, parent_post_updates),
-
- (after_save, parent_pre_updates),
- (before_delete, parent_pre_updates),
-
- (parent_pre_updates, child_deletes),
- ])
- else:
- uow.dependencies.update([
- (child_saves, after_save),
- (after_save, parent_saves),
- (parent_saves, child_deletes),
- (parent_deletes, child_deletes)
- ])
-
- def per_state_dependencies(self, uow,
- save_parent,
- delete_parent,
- child_action,
- after_save, before_delete,
- isdelete, childisdelete):
-
- if self.post_update:
-
- if not isdelete:
- parent_post_updates = unitofwork.IssuePostUpdate(
- uow,
- self.parent.primary_base_mapper,
- False)
- if childisdelete:
- uow.dependencies.update([
- (after_save, parent_post_updates),
- (parent_post_updates, child_action)
- ])
- else:
- uow.dependencies.update([
- (save_parent, after_save),
- (child_action, after_save),
-
- (after_save, parent_post_updates)
- ])
- else:
- parent_pre_updates = unitofwork.IssuePostUpdate(
- uow,
- self.parent.primary_base_mapper,
- True)
-
- uow.dependencies.update([
- (before_delete, parent_pre_updates),
- (parent_pre_updates, delete_parent),
- (parent_pre_updates, child_action)
- ])
-
- elif not isdelete:
- if not childisdelete:
- uow.dependencies.update([
- (child_action, after_save),
- (after_save, save_parent),
- ])
- else:
- uow.dependencies.update([
- (after_save, save_parent),
- ])
-
- else:
- if childisdelete:
- uow.dependencies.update([
- (delete_parent, child_action)
- ])
-
- def presort_deletes(self, uowcommit, states):
- if self.cascade.delete or self.cascade.delete_orphan:
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
- if history:
- if self.cascade.delete_orphan:
- todelete = history.sum()
- else:
- todelete = history.non_deleted()
- for child in todelete:
- if child is None:
- continue
- uowcommit.register_object(child, isdelete=True,
- operation="delete", prop=self.prop)
- for c, m, st_, dct_ in self.mapper.cascade_iterator(
- 'delete', child):
- uowcommit.register_object(
- st_, isdelete=True)
-
- def presort_saves(self, uowcommit, states):
- for state in states:
- uowcommit.register_object(state, operation="add", prop=self.prop)
- if self.cascade.delete_orphan:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
- if history:
- ret = True
- for child in history.deleted:
- if self.hasparent(child) is False:
- uowcommit.register_object(child, isdelete=True,
- operation="delete", prop=self.prop)
-
- for c, m, st_, dct_ in self.mapper.cascade_iterator(
- 'delete', child):
- uowcommit.register_object(
- st_,
- isdelete=True)
-
- def process_deletes(self, uowcommit, states):
- if self.post_update and \
- not self.cascade.delete_orphan and \
- not self.passive_deletes == 'all':
-
- # post_update means we have to update our
- # row to not reference the child object
- # before we can DELETE the row
- for state in states:
- self._synchronize(state, None, None, True, uowcommit)
- if state and self.post_update:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
- if history:
- self._post_update(state, uowcommit, history.sum())
-
- def process_saves(self, uowcommit, states):
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- attributes.PASSIVE_NO_INITIALIZE)
- if history:
- for child in history.added:
- self._synchronize(state, child, None, False,
- uowcommit, "add")
-
- if self.post_update:
- self._post_update(state, uowcommit, history.sum())
-
- def _synchronize(self, state, child, associationrow,
- clearkeys, uowcommit, operation=None):
- if state is None or \
- (not self.post_update and uowcommit.is_deleted(state)):
- return
-
- if operation is not None and \
- child is not None and \
- not uowcommit.session._contains_state(child):
- util.warn(
- "Object of type %s not in session, %s "
- "operation along '%s' won't proceed" %
- (mapperutil.state_class_str(child), operation, self.prop))
- return
-
- if clearkeys or child is None:
- sync.clear(state, self.parent, self.prop.synchronize_pairs)
- else:
- self._verify_canload(child)
- sync.populate(child, self.mapper, state,
- self.parent,
- self.prop.synchronize_pairs,
- uowcommit,
- False)
-
-class DetectKeySwitch(DependencyProcessor):
- """For many-to-one relationships with no one-to-many backref,
- searches for parents through the unit of work when a primary
- key has changed and updates them.
-
- Theoretically, this approach could be expanded to support transparent
- deletion of objects referenced via many-to-one as well, although
- the current attribute system doesn't do enough bookkeeping for this
- to be efficient.
-
- """
-
- def per_property_preprocessors(self, uow):
- if self.prop._reverse_property:
- if self.passive_updates:
- return
- else:
- if False in (prop.passive_updates for \
- prop in self.prop._reverse_property):
- return
-
- uow.register_preprocessor(self, False)
-
- def per_property_flush_actions(self, uow):
- parent_saves = unitofwork.SaveUpdateAll(
- uow,
- self.parent.base_mapper)
- after_save = unitofwork.ProcessAll(uow, self, False, False)
- uow.dependencies.update([
- (parent_saves, after_save)
- ])
-
- def per_state_flush_actions(self, uow, states, isdelete):
- pass
-
- def presort_deletes(self, uowcommit, states):
- pass
-
- def presort_saves(self, uow, states):
- if not self.passive_updates:
- # for non-passive updates, register in the preprocess stage
- # so that mapper save_obj() gets a hold of changes
- self._process_key_switches(states, uow)
-
- def prop_has_changes(self, uow, states, isdelete):
- if not isdelete and self.passive_updates:
- d = self._key_switchers(uow, states)
- return bool(d)
-
- return False
-
- def process_deletes(self, uowcommit, states):
- assert False
-
- def process_saves(self, uowcommit, states):
- # for passive updates, register objects in the process stage
- # so that we avoid ManyToOneDP's registering the object without
- # the listonly flag in its own preprocess stage (results in UPDATE)
- # statements being emitted
- assert self.passive_updates
- self._process_key_switches(states, uowcommit)
-
- def _key_switchers(self, uow, states):
- switched, notswitched = uow.memo(
- ('pk_switchers', self),
- lambda: (set(), set())
- )
-
- allstates = switched.union(notswitched)
- for s in states:
- if s not in allstates:
- if self._pks_changed(uow, s):
- switched.add(s)
- else:
- notswitched.add(s)
- return switched
-
- def _process_key_switches(self, deplist, uowcommit):
- switchers = self._key_switchers(uowcommit, deplist)
- if switchers:
- # if primary key values have actually changed somewhere, perform
- # a linear search through the UOW in search of a parent.
- for state in uowcommit.session.identity_map.all_states():
- if not issubclass(state.class_, self.parent.class_):
- continue
- dict_ = state.dict
- related = state.get_impl(self.key).get(state, dict_,
- passive=self._passive_update_flag)
- if related is not attributes.PASSIVE_NO_RESULT and \
- related is not None:
- related_state = attributes.instance_state(dict_[self.key])
- if related_state in switchers:
- uowcommit.register_object(state,
- False,
- self.passive_updates)
- sync.populate(
- related_state,
- self.mapper, state,
- self.parent, self.prop.synchronize_pairs,
- uowcommit, self.passive_updates)
-
- def _pks_changed(self, uowcommit, state):
- return bool(state.key) and sync.source_modified(uowcommit,
- state,
- self.mapper,
- self.prop.synchronize_pairs)
-
-
-class ManyToManyDP(DependencyProcessor):
-
- def per_property_dependencies(self, uow, parent_saves,
- child_saves,
- parent_deletes,
- child_deletes,
- after_save,
- before_delete
- ):
-
- uow.dependencies.update([
- (parent_saves, after_save),
- (child_saves, after_save),
- (after_save, child_deletes),
-
- # a rowswitch on the parent from deleted to saved
- # can make this one occur, as the "save" may remove
- # an element from the
- # "deleted" list before we have a chance to
- # process its child rows
- (before_delete, parent_saves),
-
- (before_delete, parent_deletes),
- (before_delete, child_deletes),
- (before_delete, child_saves),
- ])
-
- def per_state_dependencies(self, uow,
- save_parent,
- delete_parent,
- child_action,
- after_save, before_delete,
- isdelete, childisdelete):
- if not isdelete:
- if childisdelete:
- uow.dependencies.update([
- (save_parent, after_save),
- (after_save, child_action),
- ])
- else:
- uow.dependencies.update([
- (save_parent, after_save),
- (child_action, after_save),
- ])
- else:
- uow.dependencies.update([
- (before_delete, child_action),
- (before_delete, delete_parent)
- ])
-
- def presort_deletes(self, uowcommit, states):
- if not self.passive_deletes:
- # if no passive deletes, load history on
- # the collection, so that prop_has_changes()
- # returns True
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
-
- def presort_saves(self, uowcommit, states):
- if not self.passive_updates:
- # if no passive updates, load history on
- # each collection where parent has changed PK,
- # so that prop_has_changes() returns True
- for state in states:
- if self._pks_changed(uowcommit, state):
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- attributes.PASSIVE_OFF)
-
- if not self.cascade.delete_orphan:
- return
-
- # check for child items removed from the collection
- # if delete_orphan check is turned on.
- for state in states:
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- attributes.PASSIVE_NO_INITIALIZE)
- if history:
- for child in history.deleted:
- if self.hasparent(child) is False:
- uowcommit.register_object(child, isdelete=True,
- operation="delete", prop=self.prop)
- for c, m, st_, dct_ in self.mapper.cascade_iterator(
- 'delete',
- child):
- uowcommit.register_object(
- st_, isdelete=True)
-
- def process_deletes(self, uowcommit, states):
- secondary_delete = []
- secondary_insert = []
- secondary_update = []
-
- processed = self._get_reversed_processed_set(uowcommit)
- tmp = set()
- for state in states:
- # this history should be cached already, as
- # we loaded it in preprocess_deletes
- history = uowcommit.get_attribute_history(
- state,
- self.key,
- self._passive_delete_flag)
- if history:
- for child in history.non_added():
- if child is None or \
- (processed is not None and
- (state, child) in processed):
- continue
- associationrow = {}
- if not self._synchronize(
- state,
- child,
- associationrow,
- False, uowcommit, "delete"):
- continue
- secondary_delete.append(associationrow)
-
- tmp.update((c, state) for c in history.non_added())
-
- if processed is not None:
- processed.update(tmp)
-
- self._run_crud(uowcommit, secondary_insert,
- secondary_update, secondary_delete)
-
- def process_saves(self, uowcommit, states):
- secondary_delete = []
- secondary_insert = []
- secondary_update = []
-
- processed = self._get_reversed_processed_set(uowcommit)
- tmp = set()
-
- for state in states:
- need_cascade_pks = not self.passive_updates and \
- self._pks_changed(uowcommit, state)
- if need_cascade_pks:
- passive = attributes.PASSIVE_OFF
- else:
- passive = attributes.PASSIVE_NO_INITIALIZE
- history = uowcommit.get_attribute_history(state, self.key,
- passive)
- if history:
- for child in history.added:
- if child is None or \
- (processed is not None and
- (state, child) in processed):
- continue
- associationrow = {}
- if not self._synchronize(state,
- child,
- associationrow,
- False, uowcommit, "add"):
- continue
- secondary_insert.append(associationrow)
- for child in history.deleted:
- if child is None or \
- (processed is not None and
- (state, child) in processed):
- continue
- associationrow = {}
- if not self._synchronize(state,
- child,
- associationrow,
- False, uowcommit, "delete"):
- continue
- secondary_delete.append(associationrow)
-
- tmp.update((c, state)
- for c in history.added + history.deleted)
-
- if need_cascade_pks:
-
- for child in history.unchanged:
- associationrow = {}
- sync.update(state,
- self.parent,
- associationrow,
- "old_",
- self.prop.synchronize_pairs)
- sync.update(child,
- self.mapper,
- associationrow,
- "old_",
- self.prop.secondary_synchronize_pairs)
-
- secondary_update.append(associationrow)
-
- if processed is not None:
- processed.update(tmp)
-
- self._run_crud(uowcommit, secondary_insert,
- secondary_update, secondary_delete)
-
- def _run_crud(self, uowcommit, secondary_insert,
- secondary_update, secondary_delete):
- connection = uowcommit.transaction.connection(self.mapper)
-
- if secondary_delete:
- associationrow = secondary_delete[0]
- statement = self.secondary.delete(sql.and_(*[
- c == sql.bindparam(c.key, type_=c.type)
- for c in self.secondary.c
- if c.key in associationrow
- ]))
- result = connection.execute(statement, secondary_delete)
-
- if result.supports_sane_multi_rowcount() and \
- result.rowcount != len(secondary_delete):
- raise exc.StaleDataError(
- "DELETE statement on table '%s' expected to delete %d row(s); "
- "Only %d were matched." %
- (self.secondary.description, len(secondary_delete),
- result.rowcount)
- )
-
- if secondary_update:
- associationrow = secondary_update[0]
- statement = self.secondary.update(sql.and_(*[
- c == sql.bindparam("old_" + c.key, type_=c.type)
- for c in self.secondary.c
- if c.key in associationrow
- ]))
- result = connection.execute(statement, secondary_update)
- if result.supports_sane_multi_rowcount() and \
- result.rowcount != len(secondary_update):
- raise exc.StaleDataError(
- "UPDATE statement on table '%s' expected to update %d row(s); "
- "Only %d were matched." %
- (self.secondary.description, len(secondary_update),
- result.rowcount)
- )
-
- if secondary_insert:
- statement = self.secondary.insert()
- connection.execute(statement, secondary_insert)
-
- def _synchronize(self, state, child, associationrow,
- clearkeys, uowcommit, operation):
- if associationrow is None:
- return
-
- if child is not None and not uowcommit.session._contains_state(child):
- if not child.deleted:
- util.warn(
- "Object of type %s not in session, %s "
- "operation along '%s' won't proceed" %
- (mapperutil.state_class_str(child), operation, self.prop))
- return False
-
- self._verify_canload(child)
-
- sync.populate_dict(state, self.parent, associationrow,
- self.prop.synchronize_pairs)
- sync.populate_dict(child, self.mapper, associationrow,
- self.prop.secondary_synchronize_pairs)
-
- return True
-
- def _pks_changed(self, uowcommit, state):
- return sync.source_modified(
- uowcommit,
- state,
- self.parent,
- self.prop.synchronize_pairs)
-
-_direction_to_processor = {
- ONETOMANY : OneToManyDP,
- MANYTOONE: ManyToOneDP,
- MANYTOMANY : ManyToManyDP,
-}
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/deprecated_interfaces.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/deprecated_interfaces.py
deleted file mode 100755
index d5a9ab9c..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/deprecated_interfaces.py
+++ /dev/null
@@ -1,583 +0,0 @@
-# orm/deprecated_interfaces.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy import event, util
-from interfaces import EXT_CONTINUE
-
-
-class MapperExtension(object):
- """Base implementation for :class:`.Mapper` event hooks.
-
- .. note:: :class:`.MapperExtension` is deprecated. Please
- refer to :func:`.event.listen` as well as
- :class:`.MapperEvents`.
-
- New extension classes subclass :class:`.MapperExtension` and are specified
- using the ``extension`` mapper() argument, which is a single
- :class:`.MapperExtension` or a list of such::
-
- from sqlalchemy.orm.interfaces import MapperExtension
-
- class MyExtension(MapperExtension):
- def before_insert(self, mapper, connection, instance):
- print "instance %s before insert !" % instance
-
- m = mapper(User, users_table, extension=MyExtension())
-
- A single mapper can maintain a chain of ``MapperExtension``
- objects. When a particular mapping event occurs, the
- corresponding method on each ``MapperExtension`` is invoked
- serially, and each method has the ability to halt the chain
- from proceeding further::
-
- m = mapper(User, users_table, extension=[ext1, ext2, ext3])
-
- Each ``MapperExtension`` method returns the symbol
- EXT_CONTINUE by default. This symbol generally means "move
- to the next ``MapperExtension`` for processing". For methods
- that return objects like translated rows or new object
- instances, EXT_CONTINUE means the result of the method
- should be ignored. In some cases it's required for a
- default mapper activity to be performed, such as adding a
- new instance to a result list.
-
- The symbol EXT_STOP has significance within a chain
- of ``MapperExtension`` objects that the chain will be stopped
- when this symbol is returned. Like EXT_CONTINUE, it also
- has additional significance in some cases that a default
- mapper activity will not be performed.
-
- """
-
- @classmethod
- def _adapt_instrument_class(cls, self, listener):
- cls._adapt_listener_methods(self, listener, ('instrument_class',))
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- cls._adapt_listener_methods(
- self, listener,
- (
- 'init_instance',
- 'init_failed',
- 'translate_row',
- 'create_instance',
- 'append_result',
- 'populate_instance',
- 'reconstruct_instance',
- 'before_insert',
- 'after_insert',
- 'before_update',
- 'after_update',
- 'before_delete',
- 'after_delete'
- ))
-
- @classmethod
- def _adapt_listener_methods(cls, self, listener, methods):
-
- for meth in methods:
- me_meth = getattr(MapperExtension, meth)
- ls_meth = getattr(listener, meth)
-
- if not util.methods_equivalent(me_meth, ls_meth):
- if meth == 'reconstruct_instance':
- def go(ls_meth):
- def reconstruct(instance, ctx):
- ls_meth(self, instance)
- return reconstruct
- event.listen(self.class_manager, 'load',
- go(ls_meth), raw=False, propagate=True)
- elif meth == 'init_instance':
- def go(ls_meth):
- def init_instance(instance, args, kwargs):
- ls_meth(self, self.class_,
- self.class_manager.original_init,
- instance, args, kwargs)
- return init_instance
- event.listen(self.class_manager, 'init',
- go(ls_meth), raw=False, propagate=True)
- elif meth == 'init_failed':
- def go(ls_meth):
- def init_failed(instance, args, kwargs):
- util.warn_exception(ls_meth, self, self.class_,
- self.class_manager.original_init,
- instance, args, kwargs)
-
- return init_failed
- event.listen(self.class_manager, 'init_failure',
- go(ls_meth), raw=False, propagate=True)
- else:
- event.listen(self, "%s" % meth, ls_meth,
- raw=False, retval=True, propagate=True)
-
-
- def instrument_class(self, mapper, class_):
- """Receive a class when the mapper is first constructed, and has
- applied instrumentation to the mapped class.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def init_instance(self, mapper, class_, oldinit, instance, args, kwargs):
- """Receive an instance when it's constructor is called.
-
- This method is only called during a userland construction of
- an object. It is not called when an object is loaded from the
- database.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def init_failed(self, mapper, class_, oldinit, instance, args, kwargs):
- """Receive an instance when it's constructor has been called,
- and raised an exception.
-
- This method is only called during a userland construction of
- an object. It is not called when an object is loaded from the
- database.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def translate_row(self, mapper, context, row):
- """Perform pre-processing on the given result row and return a
- new row instance.
-
- This is called when the mapper first receives a row, before
- the object identity or the instance itself has been derived
- from that row. The given row may or may not be a
- ``RowProxy`` object - it will always be a dictionary-like
- object which contains mapped columns as keys. The
- returned object should also be a dictionary-like object
- which recognizes mapped columns as keys.
-
- If the ultimate return value is EXT_CONTINUE, the row
- is not translated.
-
- """
- return EXT_CONTINUE
-
- def create_instance(self, mapper, selectcontext, row, class_):
- """Receive a row when a new object instance is about to be
- created from that row.
-
- The method can choose to create the instance itself, or it can return
- EXT_CONTINUE to indicate normal object creation should take place.
-
- mapper
- The mapper doing the operation
-
- selectcontext
- The QueryContext generated from the Query.
-
- row
- The result row from the database
-
- class\_
- The class we are mapping.
-
- return value
- A new object instance, or EXT_CONTINUE
-
- """
- return EXT_CONTINUE
-
- def append_result(self, mapper, selectcontext, row, instance,
- result, **flags):
- """Receive an object instance before that instance is appended
- to a result list.
-
- If this method returns EXT_CONTINUE, result appending will proceed
- normally. if this method returns any other value or None,
- result appending will not proceed for this instance, giving
- this extension an opportunity to do the appending itself, if
- desired.
-
- mapper
- The mapper doing the operation.
-
- selectcontext
- The QueryContext generated from the Query.
-
- row
- The result row from the database.
-
- instance
- The object instance to be appended to the result.
-
- result
- List to which results are being appended.
-
- \**flags
- extra information about the row, same as criterion in
- ``create_row_processor()`` method of
- :class:`~sqlalchemy.orm.interfaces.MapperProperty`
- """
-
- return EXT_CONTINUE
-
- def populate_instance(self, mapper, selectcontext, row,
- instance, **flags):
- """Receive an instance before that instance has
- its attributes populated.
-
- This usually corresponds to a newly loaded instance but may
- also correspond to an already-loaded instance which has
- unloaded attributes to be populated. The method may be called
- many times for a single instance, as multiple result rows are
- used to populate eagerly loaded collections.
-
- If this method returns EXT_CONTINUE, instance population will
- proceed normally. If any other value or None is returned,
- instance population will not proceed, giving this extension an
- opportunity to populate the instance itself, if desired.
-
- As of 0.5, most usages of this hook are obsolete. For a
- generic "object has been newly created from a row" hook, use
- ``reconstruct_instance()``, or the ``@orm.reconstructor``
- decorator.
-
- """
- return EXT_CONTINUE
-
- def reconstruct_instance(self, mapper, instance):
- """Receive an object instance after it has been created via
- ``__new__``, and after initial attribute population has
- occurred.
-
- This typically occurs when the instance is created based on
- incoming result rows, and is only called once for that
- instance's lifetime.
-
- Note that during a result-row load, this method is called upon
- the first row received for this instance. Note that some
- attributes and collections may or may not be loaded or even
- initialized, depending on what's present in the result rows.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def before_insert(self, mapper, connection, instance):
- """Receive an object instance before that instance is inserted
- into its table.
-
- This is a good place to set up primary key values and such
- that aren't handled otherwise.
-
- Column-based attributes can be modified within this method
- which will result in the new value being inserted. However
- *no* changes to the overall flush plan can be made, and
- manipulation of the ``Session`` will not have the desired effect.
- To manipulate the ``Session`` within an extension, use
- ``SessionExtension``.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def after_insert(self, mapper, connection, instance):
- """Receive an object instance after that instance is inserted.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def before_update(self, mapper, connection, instance):
- """Receive an object instance before that instance is updated.
-
- Note that this method is called for all instances that are marked as
- "dirty", even those which have no net changes to their column-based
- attributes. An object is marked as dirty when any of its column-based
- attributes have a "set attribute" operation called or when any of its
- collections are modified. If, at update time, no column-based
- attributes have any net changes, no UPDATE statement will be issued.
- This means that an instance being sent to before_update is *not* a
- guarantee that an UPDATE statement will be issued (although you can
- affect the outcome here).
-
- To detect if the column-based attributes on the object have net
- changes, and will therefore generate an UPDATE statement, use
- ``object_session(instance).is_modified(instance,
- include_collections=False)``.
-
- Column-based attributes can be modified within this method
- which will result in the new value being updated. However
- *no* changes to the overall flush plan can be made, and
- manipulation of the ``Session`` will not have the desired effect.
- To manipulate the ``Session`` within an extension, use
- ``SessionExtension``.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def after_update(self, mapper, connection, instance):
- """Receive an object instance after that instance is updated.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def before_delete(self, mapper, connection, instance):
- """Receive an object instance before that instance is deleted.
-
- Note that *no* changes to the overall flush plan can be made
- here; and manipulation of the ``Session`` will not have the
- desired effect. To manipulate the ``Session`` within an
- extension, use ``SessionExtension``.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def after_delete(self, mapper, connection, instance):
- """Receive an object instance after that instance is deleted.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
-class SessionExtension(object):
-
- """Base implementation for :class:`.Session` event hooks.
-
- .. note:: :class:`.SessionExtension` is deprecated. Please
- refer to :func:`.event.listen` as well as
- :class:`.SessionEvents`.
-
- Subclasses may be installed into a :class:`.Session` (or
- :func:`.sessionmaker`) using the ``extension`` keyword
- argument::
-
- from sqlalchemy.orm.interfaces import SessionExtension
-
- class MySessionExtension(SessionExtension):
- def before_commit(self, session):
- print "before commit!"
-
- Session = sessionmaker(extension=MySessionExtension())
-
- The same :class:`.SessionExtension` instance can be used
- with any number of sessions.
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- for meth in [
- 'before_commit',
- 'after_commit',
- 'after_rollback',
- 'before_flush',
- 'after_flush',
- 'after_flush_postexec',
- 'after_begin',
- 'after_attach',
- 'after_bulk_update',
- 'after_bulk_delete',
- ]:
- me_meth = getattr(SessionExtension, meth)
- ls_meth = getattr(listener, meth)
-
- if not util.methods_equivalent(me_meth, ls_meth):
- event.listen(self, meth, getattr(listener, meth))
-
- def before_commit(self, session):
- """Execute right before commit is called.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def after_commit(self, session):
- """Execute after a commit has occurred.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def after_rollback(self, session):
- """Execute after a rollback has occurred.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def before_flush( self, session, flush_context, instances):
- """Execute before flush process has started.
-
- `instances` is an optional list of objects which were passed to
- the ``flush()`` method. """
-
- def after_flush(self, session, flush_context):
- """Execute after flush has completed, but before commit has been
- called.
-
- Note that the session's state is still in pre-flush, i.e. 'new',
- 'dirty', and 'deleted' lists still show pre-flush state as well
- as the history settings on instance attributes."""
-
- def after_flush_postexec(self, session, flush_context):
- """Execute after flush has completed, and after the post-exec
- state occurs.
-
- This will be when the 'new', 'dirty', and 'deleted' lists are in
- their final state. An actual commit() may or may not have
- occurred, depending on whether or not the flush started its own
- transaction or participated in a larger transaction. """
-
- def after_begin( self, session, transaction, connection):
- """Execute after a transaction is begun on a connection
-
- `transaction` is the SessionTransaction. This method is called
- after an engine level transaction is begun on a connection. """
-
- def after_attach(self, session, instance):
- """Execute after an instance is attached to a session.
-
- This is called after an add, delete or merge. """
-
- def after_bulk_update( self, session, query, query_context, result):
- """Execute after a bulk update operation to the session.
-
- This is called after a session.query(...).update()
-
- `query` is the query object that this update operation was
- called on. `query_context` was the query context object.
- `result` is the result object returned from the bulk operation.
- """
-
- def after_bulk_delete( self, session, query, query_context, result):
- """Execute after a bulk delete operation to the session.
-
- This is called after a session.query(...).delete()
-
- `query` is the query object that this delete operation was
- called on. `query_context` was the query context object.
- `result` is the result object returned from the bulk operation.
- """
-
-
-class AttributeExtension(object):
- """Base implementation for :class:`.AttributeImpl` event hooks, events
- that fire upon attribute mutations in user code.
-
- .. note:: :class:`.AttributeExtension` is deprecated. Please
- refer to :func:`.event.listen` as well as
- :class:`.AttributeEvents`.
-
- :class:`.AttributeExtension` is used to listen for set,
- remove, and append events on individual mapped attributes.
- It is established on an individual mapped attribute using
- the `extension` argument, available on
- :func:`.column_property`, :func:`.relationship`, and
- others::
-
- from sqlalchemy.orm.interfaces import AttributeExtension
- from sqlalchemy.orm import mapper, relationship, column_property
-
- class MyAttrExt(AttributeExtension):
- def append(self, state, value, initiator):
- print "append event !"
- return value
-
- def set(self, state, value, oldvalue, initiator):
- print "set event !"
- return value
-
- mapper(SomeClass, sometable, properties={
- 'foo':column_property(sometable.c.foo, extension=MyAttrExt()),
- 'bar':relationship(Bar, extension=MyAttrExt())
- })
-
- Note that the :class:`.AttributeExtension` methods
- :meth:`~.AttributeExtension.append` and
- :meth:`~.AttributeExtension.set` need to return the
- ``value`` parameter. The returned value is used as the
- effective value, and allows the extension to change what is
- ultimately persisted.
-
- AttributeExtension is assembled within the descriptors associated
- with a mapped class.
-
- """
-
- active_history = True
- """indicates that the set() method would like to receive the 'old' value,
- even if it means firing lazy callables.
-
- Note that ``active_history`` can also be set directly via
- :func:`.column_property` and :func:`.relationship`.
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- event.listen(self, 'append', listener.append,
- active_history=listener.active_history,
- raw=True, retval=True)
- event.listen(self, 'remove', listener.remove,
- active_history=listener.active_history,
- raw=True, retval=True)
- event.listen(self, 'set', listener.set,
- active_history=listener.active_history,
- raw=True, retval=True)
-
- def append(self, state, value, initiator):
- """Receive a collection append event.
-
- The returned value will be used as the actual value to be
- appended.
-
- """
- return value
-
- def remove(self, state, value, initiator):
- """Receive a remove event.
-
- No return value is defined.
-
- """
- pass
-
- def set(self, state, value, oldvalue, initiator):
- """Receive a set event.
-
- The returned value will be used as the actual value to be
- set.
-
- """
- return value
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/descriptor_props.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/descriptor_props.py
deleted file mode 100755
index 5ad148a7..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/descriptor_props.py
+++ /dev/null
@@ -1,405 +0,0 @@
-# orm/descriptor_props.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Descriptor properties are more "auxiliary" properties
-that exist as configurational elements, but don't participate
-as actively in the load/persist ORM loop.
-
-"""
-
-from sqlalchemy.orm.interfaces import \
- MapperProperty, PropComparator, StrategizedProperty
-from sqlalchemy.orm.mapper import _none_set
-from sqlalchemy.orm import attributes
-from sqlalchemy import util, sql, exc as sa_exc, event, schema
-from sqlalchemy.sql import expression
-properties = util.importlater('sqlalchemy.orm', 'properties')
-
-class DescriptorProperty(MapperProperty):
- """:class:`.MapperProperty` which proxies access to a
- user-defined descriptor."""
-
- doc = None
-
- def instrument_class(self, mapper):
- prop = self
-
- class _ProxyImpl(object):
- accepts_scalar_loader = False
- expire_missing = True
-
- def __init__(self, key):
- self.key = key
-
- if hasattr(prop, 'get_history'):
- def get_history(self, state, dict_,
- passive=attributes.PASSIVE_OFF):
- return prop.get_history(state, dict_, passive)
-
- if self.descriptor is None:
- desc = getattr(mapper.class_, self.key, None)
- if mapper._is_userland_descriptor(desc):
- self.descriptor = desc
-
- if self.descriptor is None:
- def fset(obj, value):
- setattr(obj, self.name, value)
- def fdel(obj):
- delattr(obj, self.name)
- def fget(obj):
- return getattr(obj, self.name)
-
- self.descriptor = property(
- fget=fget,
- fset=fset,
- fdel=fdel,
- )
-
- proxy_attr = attributes.\
- create_proxied_attribute(self.descriptor)\
- (
- self.parent.class_,
- self.key,
- self.descriptor,
- lambda: self._comparator_factory(mapper),
- doc=self.doc
- )
- proxy_attr.property = self
- proxy_attr.impl = _ProxyImpl(self.key)
- mapper.class_manager.instrument_attribute(self.key, proxy_attr)
-
-
-class CompositeProperty(DescriptorProperty):
-
- def __init__(self, class_, *attrs, **kwargs):
- self.attrs = attrs
- self.composite_class = class_
- self.active_history = kwargs.get('active_history', False)
- self.deferred = kwargs.get('deferred', False)
- self.group = kwargs.get('group', None)
- util.set_creation_order(self)
- self._create_descriptor()
-
- def instrument_class(self, mapper):
- super(CompositeProperty, self).instrument_class(mapper)
- self._setup_event_handlers()
-
- def do_init(self):
- """Initialization which occurs after the :class:`.CompositeProperty`
- has been associated with its parent mapper.
-
- """
- self._init_props()
- self._setup_arguments_on_columns()
-
- def _create_descriptor(self):
- """Create the Python descriptor that will serve as
- the access point on instances of the mapped class.
-
- """
-
- def fget(instance):
- dict_ = attributes.instance_dict(instance)
-
- if self.key not in dict_:
- # key not present. Iterate through related
- # attributes, retrieve their values. This
- # ensures they all load.
- values = [getattr(instance, key) for key in self._attribute_keys]
-
- # usually, the load() event will have loaded our key
- # at this point, unless we only loaded relationship()
- # attributes above. Populate here if that's the case.
- if self.key not in dict_ and not _none_set.issuperset(values):
- dict_[self.key] = self.composite_class(*values)
-
- return dict_.get(self.key, None)
-
- def fset(instance, value):
- dict_ = attributes.instance_dict(instance)
- state = attributes.instance_state(instance)
- attr = state.manager[self.key]
- previous = dict_.get(self.key, attributes.NO_VALUE)
- for fn in attr.dispatch.set:
- value = fn(state, value, previous, attr.impl)
- dict_[self.key] = value
- if value is None:
- for key in self._attribute_keys:
- setattr(instance, key, None)
- else:
- for key, value in zip(
- self._attribute_keys,
- value.__composite_values__()):
- setattr(instance, key, value)
-
- def fdel(instance):
- state = attributes.instance_state(instance)
- dict_ = attributes.instance_dict(instance)
- previous = dict_.pop(self.key, attributes.NO_VALUE)
- attr = state.manager[self.key]
- attr.dispatch.remove(state, previous, attr.impl)
- for key in self._attribute_keys:
- setattr(instance, key, None)
-
- self.descriptor = property(fget, fset, fdel)
-
- @util.memoized_property
- def _comparable_elements(self):
- return [
- getattr(self.parent.class_, prop.key)
- for prop in self.props
- ]
-
- def _init_props(self):
- self.props = props = []
- for attr in self.attrs:
- if isinstance(attr, basestring):
- prop = self.parent.get_property(attr)
- elif isinstance(attr, schema.Column):
- prop = self.parent._columntoproperty[attr]
- elif isinstance(attr, attributes.InstrumentedAttribute):
- prop = attr.property
- props.append(prop)
-
- @property
- def columns(self):
- return [a for a in self.attrs if isinstance(a, schema.Column)]
-
- def _setup_arguments_on_columns(self):
- """Propagate configuration arguments made on this composite
- to the target columns, for those that apply.
-
- """
- for prop in self.props:
- prop.active_history = self.active_history
- if self.deferred:
- prop.deferred = self.deferred
- prop.strategy_class = strategies.DeferredColumnLoader
- prop.group = self.group
-
- def _setup_event_handlers(self):
- """Establish events that populate/expire the composite attribute."""
-
- def load_handler(state, *args):
- dict_ = state.dict
-
- if self.key in dict_:
- return
-
- # if column elements aren't loaded, skip.
- # __get__() will initiate a load for those
- # columns
- for k in self._attribute_keys:
- if k not in dict_:
- return
-
- dict_[self.key] = self.composite_class(
- *[state.dict[key] for key in
- self._attribute_keys]
- )
-
- def expire_handler(state, keys):
- if keys is None or set(self._attribute_keys).intersection(keys):
- state.dict.pop(self.key, None)
-
- def insert_update_handler(mapper, connection, state):
- state.dict[self.key] = self.composite_class(
- *[state.dict.get(key, None) for key in
- self._attribute_keys]
- )
-
- event.listen(self.parent, 'after_insert',
- insert_update_handler, raw=True)
- event.listen(self.parent, 'after_update',
- insert_update_handler, raw=True)
- event.listen(self.parent, 'load', load_handler, raw=True)
- event.listen(self.parent, 'refresh', load_handler, raw=True)
- event.listen(self.parent, "expire", expire_handler, raw=True)
-
- # TODO: need a deserialize hook here
-
- @util.memoized_property
- def _attribute_keys(self):
- return [
- prop.key for prop in self.props
- ]
-
- def get_history(self, state, dict_, passive=attributes.PASSIVE_OFF):
- """Provided for userland code that uses attributes.get_history()."""
-
- added = []
- deleted = []
-
- has_history = False
- for prop in self.props:
- key = prop.key
- hist = state.manager[key].impl.get_history(state, dict_)
- if hist.has_changes():
- has_history = True
-
- added.extend(hist.non_deleted())
- if hist.deleted:
- deleted.extend(hist.deleted)
- else:
- deleted.append(None)
-
- if has_history:
- return attributes.History(
- [self.composite_class(*added)],
- (),
- [self.composite_class(*deleted)]
- )
- else:
- return attributes.History(
- (),[self.composite_class(*added)], ()
- )
-
- def _comparator_factory(self, mapper):
- return CompositeProperty.Comparator(self)
-
- class Comparator(PropComparator):
- def __init__(self, prop, adapter=None):
- self.prop = prop
- self.adapter = adapter
-
- def __clause_element__(self):
- if self.adapter:
- # TODO: test coverage for adapted composite comparison
- return expression.ClauseList(
- *[self.adapter(x) for x in self.prop._comparable_elements])
- else:
- return expression.ClauseList(*self.prop._comparable_elements)
-
- __hash__ = None
-
- def __eq__(self, other):
- if other is None:
- values = [None] * len(self.prop._comparable_elements)
- else:
- values = other.__composite_values__()
- return sql.and_(
- *[a==b for a, b in zip(self.prop._comparable_elements, values)])
-
- def __ne__(self, other):
- return sql.not_(self.__eq__(other))
-
- def __str__(self):
- return str(self.parent.class_.__name__) + "." + self.key
-
-class ConcreteInheritedProperty(DescriptorProperty):
- """A 'do nothing' :class:`.MapperProperty` that disables
- an attribute on a concrete subclass that is only present
- on the inherited mapper, not the concrete classes' mapper.
-
- Cases where this occurs include:
-
- * When the superclass mapper is mapped against a
- "polymorphic union", which includes all attributes from
- all subclasses.
- * When a relationship() is configured on an inherited mapper,
- but not on the subclass mapper. Concrete mappers require
- that relationship() is configured explicitly on each
- subclass.
-
- """
-
- def _comparator_factory(self, mapper):
- comparator_callable = None
-
- for m in self.parent.iterate_to_root():
- p = m._props[self.key]
- if not isinstance(p, ConcreteInheritedProperty):
- comparator_callable = p.comparator_factory
- break
- return comparator_callable
-
- def __init__(self):
- def warn():
- raise AttributeError("Concrete %s does not implement "
- "attribute %r at the instance level. Add this "
- "property explicitly to %s." %
- (self.parent, self.key, self.parent))
-
- class NoninheritedConcreteProp(object):
- def __set__(s, obj, value):
- warn()
- def __delete__(s, obj):
- warn()
- def __get__(s, obj, owner):
- if obj is None:
- return self.descriptor
- warn()
- self.descriptor = NoninheritedConcreteProp()
-
-
-class SynonymProperty(DescriptorProperty):
-
- def __init__(self, name, map_column=None,
- descriptor=None, comparator_factory=None,
- doc=None):
- self.name = name
- self.map_column = map_column
- self.descriptor = descriptor
- self.comparator_factory = comparator_factory
- self.doc = doc or (descriptor and descriptor.__doc__) or None
-
- util.set_creation_order(self)
-
- # TODO: when initialized, check _proxied_property,
- # emit a warning if its not a column-based property
-
- @util.memoized_property
- def _proxied_property(self):
- return getattr(self.parent.class_, self.name).property
-
- def _comparator_factory(self, mapper):
- prop = self._proxied_property
-
- if self.comparator_factory:
- comp = self.comparator_factory(prop, mapper)
- else:
- comp = prop.comparator_factory(prop, mapper)
- return comp
-
- def set_parent(self, parent, init):
- if self.map_column:
- # implement the 'map_column' option.
- if self.key not in parent.mapped_table.c:
- raise sa_exc.ArgumentError(
- "Can't compile synonym '%s': no column on table "
- "'%s' named '%s'"
- % (self.name, parent.mapped_table.description, self.key))
- elif parent.mapped_table.c[self.key] in \
- parent._columntoproperty and \
- parent._columntoproperty[
- parent.mapped_table.c[self.key]
- ].key == self.name:
- raise sa_exc.ArgumentError(
- "Can't call map_column=True for synonym %r=%r, "
- "a ColumnProperty already exists keyed to the name "
- "%r for column %r" %
- (self.key, self.name, self.name, self.key)
- )
- p = properties.ColumnProperty(parent.mapped_table.c[self.key])
- parent._configure_property(
- self.name, p,
- init=init,
- setparent=True)
- p._mapped_by_synonym = self.key
-
- self.parent = parent
-
-class ComparableProperty(DescriptorProperty):
- """Instruments a Python property for use in query expressions."""
-
- def __init__(self, comparator_factory, descriptor=None, doc=None):
- self.descriptor = descriptor
- self.comparator_factory = comparator_factory
- self.doc = doc or (descriptor and descriptor.__doc__) or None
- util.set_creation_order(self)
-
- def _comparator_factory(self, mapper):
- return self.comparator_factory(self, mapper)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dynamic.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dynamic.py
deleted file mode 100755
index d4a031d9..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/dynamic.py
+++ /dev/null
@@ -1,313 +0,0 @@
-# orm/dynamic.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Dynamic collection API.
-
-Dynamic collections act like Query() objects for read operations and support
-basic add/delete mutation.
-
-"""
-
-from sqlalchemy import log, util
-from sqlalchemy import exc as sa_exc
-from sqlalchemy.orm import exc as orm_exc
-from sqlalchemy.sql import operators
-from sqlalchemy.orm import (
- attributes, object_session, util as mapperutil, strategies, object_mapper
- )
-from sqlalchemy.orm.query import Query
-from sqlalchemy.orm.util import has_identity
-from sqlalchemy.orm import attributes, collections
-
-class DynaLoader(strategies.AbstractRelationshipLoader):
- def init_class_attribute(self, mapper):
- self.is_class_level = True
-
- strategies._register_attribute(self,
- mapper,
- useobject=True,
- impl_class=DynamicAttributeImpl,
- target_mapper=self.parent_property.mapper,
- order_by=self.parent_property.order_by,
- query_class=self.parent_property.query_class
- )
-
-log.class_logger(DynaLoader)
-
-class DynamicAttributeImpl(attributes.AttributeImpl):
- uses_objects = True
- accepts_scalar_loader = False
- supports_population = False
-
- def __init__(self, class_, key, typecallable,
- dispatch,
- target_mapper, order_by, query_class=None, **kw):
- super(DynamicAttributeImpl, self).\
- __init__(class_, key, typecallable, dispatch, **kw)
- self.target_mapper = target_mapper
- self.order_by = order_by
- if not query_class:
- self.query_class = AppenderQuery
- elif AppenderMixin in query_class.mro():
- self.query_class = query_class
- else:
- self.query_class = mixin_user_query(query_class)
-
- def get(self, state, dict_, passive=attributes.PASSIVE_OFF):
- if passive is not attributes.PASSIVE_OFF:
- return self._get_collection_history(state,
- attributes.PASSIVE_NO_INITIALIZE).added_items
- else:
- return self.query_class(self, state)
-
- def get_collection(self, state, dict_, user_data=None,
- passive=attributes.PASSIVE_NO_INITIALIZE):
- if passive is not attributes.PASSIVE_OFF:
- return self._get_collection_history(state,
- passive).added_items
- else:
- history = self._get_collection_history(state, passive)
- return history.added_items + history.unchanged_items
-
- def fire_append_event(self, state, dict_, value, initiator):
- collection_history = self._modified_event(state, dict_)
- collection_history.added_items.append(value)
-
- for fn in self.dispatch.append:
- value = fn(state, value, initiator or self)
-
- if self.trackparent and value is not None:
- self.sethasparent(attributes.instance_state(value), True)
-
- def fire_remove_event(self, state, dict_, value, initiator):
- collection_history = self._modified_event(state, dict_)
- collection_history.deleted_items.append(value)
-
- if self.trackparent and value is not None:
- self.sethasparent(attributes.instance_state(value), False)
-
- for fn in self.dispatch.remove:
- fn(state, value, initiator or self)
-
- def _modified_event(self, state, dict_):
-
- if self.key not in state.committed_state:
- state.committed_state[self.key] = CollectionHistory(self, state)
-
- state.modified_event(dict_,
- self,
- attributes.NEVER_SET)
-
- # this is a hack to allow the fixtures.ComparableEntity fixture
- # to work
- dict_[self.key] = True
- return state.committed_state[self.key]
-
- def set(self, state, dict_, value, initiator,
- passive=attributes.PASSIVE_OFF):
- if initiator and initiator.parent_token is self.parent_token:
- return
-
- self._set_iterable(state, dict_, value)
-
- def _set_iterable(self, state, dict_, iterable, adapter=None):
- collection_history = self._modified_event(state, dict_)
- new_values = list(iterable)
- if state.has_identity:
- old_collection = list(self.get(state, dict_))
- else:
- old_collection = []
- collections.bulk_replace(new_values, DynCollectionAdapter(self,
- state, old_collection),
- DynCollectionAdapter(self, state,
- new_values))
-
- def delete(self, *args, **kwargs):
- raise NotImplementedError()
-
- def set_committed_value(self, state, dict_, value):
- raise NotImplementedError("Dynamic attributes don't support "
- "collection population.")
-
- def get_history(self, state, dict_, passive=attributes.PASSIVE_OFF):
- c = self._get_collection_history(state, passive)
- return attributes.History(c.added_items, c.unchanged_items,
- c.deleted_items)
-
- def get_all_pending(self, state, dict_):
- c = self._get_collection_history(state, True)
- return [
- (attributes.instance_state(x), x)
- for x in
- c.added_items + c.unchanged_items + c.deleted_items
- ]
-
- def _get_collection_history(self, state, passive=attributes.PASSIVE_OFF):
- if self.key in state.committed_state:
- c = state.committed_state[self.key]
- else:
- c = CollectionHistory(self, state)
-
- if passive is attributes.PASSIVE_OFF:
- return CollectionHistory(self, state, apply_to=c)
- else:
- return c
-
- def append(self, state, dict_, value, initiator,
- passive=attributes.PASSIVE_OFF):
- if initiator is not self:
- self.fire_append_event(state, dict_, value, initiator)
-
- def remove(self, state, dict_, value, initiator,
- passive=attributes.PASSIVE_OFF):
- if initiator is not self:
- self.fire_remove_event(state, dict_, value, initiator)
-
-class DynCollectionAdapter(object):
- """the dynamic analogue to orm.collections.CollectionAdapter"""
-
- def __init__(self, attr, owner_state, data):
- self.attr = attr
- self.state = owner_state
- self.data = data
-
- def __iter__(self):
- return iter(self.data)
-
- def append_with_event(self, item, initiator=None):
- self.attr.append(self.state, self.state.dict, item, initiator)
-
- def remove_with_event(self, item, initiator=None):
- self.attr.remove(self.state, self.state.dict, item, initiator)
-
- def append_without_event(self, item):
- pass
-
- def remove_without_event(self, item):
- pass
-
-class AppenderMixin(object):
- query_class = None
-
- def __init__(self, attr, state):
- Query.__init__(self, attr.target_mapper, None)
- self.instance = instance = state.obj()
- self.attr = attr
-
- mapper = object_mapper(instance)
- prop = mapper._props[self.attr.key]
- self._criterion = prop.compare(
- operators.eq,
- instance,
- value_is_parent=True,
- alias_secondary=False)
-
- if self.attr.order_by:
- self._order_by = self.attr.order_by
-
- def __session(self):
- sess = object_session(self.instance)
- if sess is not None and self.autoflush and sess.autoflush \
- and self.instance in sess:
- sess.flush()
- if not has_identity(self.instance):
- return None
- else:
- return sess
-
- def session(self):
- return self.__session()
- session = property(session, lambda s, x:None)
-
- def __iter__(self):
- sess = self.__session()
- if sess is None:
- return iter(self.attr._get_collection_history(
- attributes.instance_state(self.instance),
- attributes.PASSIVE_NO_INITIALIZE).added_items)
- else:
- return iter(self._clone(sess))
-
- def __getitem__(self, index):
- sess = self.__session()
- if sess is None:
- return self.attr._get_collection_history(
- attributes.instance_state(self.instance),
- attributes.PASSIVE_NO_INITIALIZE).added_items.\
- __getitem__(index)
- else:
- return self._clone(sess).__getitem__(index)
-
- def count(self):
- sess = self.__session()
- if sess is None:
- return len(self.attr._get_collection_history(
- attributes.instance_state(self.instance),
- attributes.PASSIVE_NO_INITIALIZE).added_items)
- else:
- return self._clone(sess).count()
-
- def _clone(self, sess=None):
- # note we're returning an entirely new Query class instance
- # here without any assignment capabilities; the class of this
- # query is determined by the session.
- instance = self.instance
- if sess is None:
- sess = object_session(instance)
- if sess is None:
- raise orm_exc.DetachedInstanceError(
- "Parent instance %s is not bound to a Session, and no "
- "contextual session is established; lazy load operation "
- "of attribute '%s' cannot proceed" % (
- mapperutil.instance_str(instance), self.attr.key))
-
- if self.query_class:
- query = self.query_class(self.attr.target_mapper, session=sess)
- else:
- query = sess.query(self.attr.target_mapper)
-
- query._criterion = self._criterion
- query._order_by = self._order_by
-
- return query
-
- def append(self, item):
- self.attr.append(
- attributes.instance_state(self.instance),
- attributes.instance_dict(self.instance), item, None)
-
- def remove(self, item):
- self.attr.remove(
- attributes.instance_state(self.instance),
- attributes.instance_dict(self.instance), item, None)
-
-
-class AppenderQuery(AppenderMixin, Query):
- """A dynamic query that supports basic collection storage operations."""
-
-
-def mixin_user_query(cls):
- """Return a new class with AppenderQuery functionality layered over."""
- name = 'Appender' + cls.__name__
- return type(name, (AppenderMixin, cls), {'query_class': cls})
-
-class CollectionHistory(object):
- """Overrides AttributeHistory to receive append/remove events directly."""
-
- def __init__(self, attr, state, apply_to=None):
- if apply_to:
- deleted = util.IdentitySet(apply_to.deleted_items)
- added = apply_to.added_items
- coll = AppenderQuery(attr, state).autoflush(False)
- self.unchanged_items = [o for o in util.IdentitySet(coll)
- if o not in deleted]
- self.added_items = apply_to.added_items
- self.deleted_items = apply_to.deleted_items
- else:
- self.deleted_items = []
- self.added_items = []
- self.unchanged_items = []
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/evaluator.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/evaluator.py
deleted file mode 100755
index f05b92a5..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/evaluator.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# orm/evaluator.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-import operator
-from sqlalchemy.sql import operators, functions
-from sqlalchemy.sql import expression as sql
-
-
-class UnevaluatableError(Exception):
- pass
-
-_straight_ops = set(getattr(operators, op)
- for op in ('add', 'mul', 'sub',
- # Py2K
- 'div',
- # end Py2K
- 'mod', 'truediv',
- 'lt', 'le', 'ne', 'gt', 'ge', 'eq'))
-
-
-_notimplemented_ops = set(getattr(operators, op)
- for op in ('like_op', 'notlike_op', 'ilike_op',
- 'notilike_op', 'between_op', 'in_op',
- 'notin_op', 'endswith_op', 'concat_op'))
-
-class EvaluatorCompiler(object):
- def process(self, clause):
- meth = getattr(self, "visit_%s" % clause.__visit_name__, None)
- if not meth:
- raise UnevaluatableError("Cannot evaluate %s" % type(clause).__name__)
- return meth(clause)
-
- def visit_grouping(self, clause):
- return self.process(clause.element)
-
- def visit_null(self, clause):
- return lambda obj: None
-
- def visit_column(self, clause):
- if 'parentmapper' in clause._annotations:
- key = clause._annotations['parentmapper'].\
- _columntoproperty[clause].key
- else:
- key = clause.key
- get_corresponding_attr = operator.attrgetter(key)
- return lambda obj: get_corresponding_attr(obj)
-
- def visit_clauselist(self, clause):
- evaluators = map(self.process, clause.clauses)
- if clause.operator is operators.or_:
- def evaluate(obj):
- has_null = False
- for sub_evaluate in evaluators:
- value = sub_evaluate(obj)
- if value:
- return True
- has_null = has_null or value is None
- if has_null:
- return None
- return False
- elif clause.operator is operators.and_:
- def evaluate(obj):
- for sub_evaluate in evaluators:
- value = sub_evaluate(obj)
- if not value:
- if value is None:
- return None
- return False
- return True
- else:
- raise UnevaluatableError("Cannot evaluate clauselist with operator %s" % clause.operator)
-
- return evaluate
-
- def visit_binary(self, clause):
- eval_left,eval_right = map(self.process, [clause.left, clause.right])
- operator = clause.operator
- if operator is operators.is_:
- def evaluate(obj):
- return eval_left(obj) == eval_right(obj)
- elif operator is operators.isnot:
- def evaluate(obj):
- return eval_left(obj) != eval_right(obj)
- elif operator in _straight_ops:
- def evaluate(obj):
- left_val = eval_left(obj)
- right_val = eval_right(obj)
- if left_val is None or right_val is None:
- return None
- return operator(eval_left(obj), eval_right(obj))
- else:
- raise UnevaluatableError("Cannot evaluate %s with operator %s" % (type(clause).__name__, clause.operator))
- return evaluate
-
- def visit_unary(self, clause):
- eval_inner = self.process(clause.element)
- if clause.operator is operators.inv:
- def evaluate(obj):
- value = eval_inner(obj)
- if value is None:
- return None
- return not value
- return evaluate
- raise UnevaluatableError("Cannot evaluate %s with operator %s" % (type(clause).__name__, clause.operator))
-
- def visit_bindparam(self, clause):
- val = clause.value
- return lambda obj: val
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/events.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/events.py
deleted file mode 100755
index 8c12e72b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/events.py
+++ /dev/null
@@ -1,1046 +0,0 @@
-# orm/events.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""ORM event interfaces.
-
-"""
-from sqlalchemy import event, exc
-import inspect
-
-class InstrumentationEvents(event.Events):
- """Events related to class instrumentation events.
-
- The listeners here support being established against
- any new style class, that is any object that is a subclass
- of 'type'. Events will then be fired off for events
- against that class as well as all subclasses.
- 'type' itself is also accepted as a target
- in which case the events fire for all classes.
-
- """
-
- @classmethod
- def _accept_with(cls, target):
- from sqlalchemy.orm.instrumentation import instrumentation_registry
-
- if isinstance(target, type):
- return instrumentation_registry
- else:
- return None
-
- @classmethod
- def _listen(cls, target, identifier, fn, propagate=False):
- event.Events._listen(target, identifier, fn, propagate=propagate)
-
- @classmethod
- def _remove(cls, identifier, target, fn):
- raise NotImplementedError("Removal of instrumentation events not yet implemented")
-
- def class_instrument(self, cls):
- """Called after the given class is instrumented.
-
- To get at the :class:`.ClassManager`, use
- :func:`.manager_of_class`.
-
- """
-
- def class_uninstrument(self, cls):
- """Called before the given class is uninstrumented.
-
- To get at the :class:`.ClassManager`, use
- :func:`.manager_of_class`.
-
- """
-
-
- def attribute_instrument(self, cls, key, inst):
- """Called when an attribute is instrumented."""
-
-class InstanceEvents(event.Events):
- """Define events specific to object lifecycle.
-
- e.g.::
-
- from sqlalchemy import event
-
- def my_load_listener(target, context):
- print "on load!"
-
- event.listen(SomeMappedClass, 'load', my_load_listener)
-
- Available targets include mapped classes, instances of
- :class:`.Mapper` (i.e. returned by :func:`.mapper`,
- :func:`.class_mapper` and similar), as well as the
- :class:`.Mapper` class and :func:`.mapper` function itself
- for global event reception::
-
- from sqlalchemy.orm import mapper
-
- def some_listener(target, context):
- log.debug("Instance %s being loaded" % target)
-
- # attach to all mappers
- event.listen(mapper, 'load', some_listener)
-
- Instance events are closely related to mapper events, but
- are more specific to the instance and its instrumentation,
- rather than its system of persistence.
-
- When using :class:`.InstanceEvents`, several modifiers are
- available to the :func:`.event.listen` function.
-
- :param propagate=False: When True, the event listener should
- be applied to all inheriting mappers as well as the
- mapper which is the target of this listener.
- :param raw=False: When True, the "target" argument passed
- to applicable event listener functions will be the
- instance's :class:`.InstanceState` management
- object, rather than the mapped instance itself.
-
- """
- @classmethod
- def _accept_with(cls, target):
- from sqlalchemy.orm.instrumentation import ClassManager, manager_of_class
- from sqlalchemy.orm import Mapper, mapper
-
- if isinstance(target, ClassManager):
- return target
- elif isinstance(target, Mapper):
- return target.class_manager
- elif target is mapper:
- return ClassManager
- elif isinstance(target, type):
- if issubclass(target, Mapper):
- return ClassManager
- else:
- manager = manager_of_class(target)
- if manager:
- return manager
- return None
-
- @classmethod
- def _listen(cls, target, identifier, fn, raw=False, propagate=False):
- if not raw:
- orig_fn = fn
- def wrap(state, *arg, **kw):
- return orig_fn(state.obj(), *arg, **kw)
- fn = wrap
-
- event.Events._listen(target, identifier, fn, propagate=propagate)
- if propagate:
- for mgr in target.subclass_managers(True):
- event.Events._listen(mgr, identifier, fn, True)
-
- @classmethod
- def _remove(cls, identifier, target, fn):
- raise NotImplementedError("Removal of instance events not yet implemented")
-
- def first_init(self, manager, cls):
- """Called when the first instance of a particular mapping is called.
-
- """
-
- def init(self, target, args, kwargs):
- """Receive an instance when it's constructor is called.
-
- This method is only called during a userland construction of
- an object. It is not called when an object is loaded from the
- database.
-
- """
-
- def init_failure(self, target, args, kwargs):
- """Receive an instance when it's constructor has been called,
- and raised an exception.
-
- This method is only called during a userland construction of
- an object. It is not called when an object is loaded from the
- database.
-
- """
-
- def load(self, target, context):
- """Receive an object instance after it has been created via
- ``__new__``, and after initial attribute population has
- occurred.
-
- This typically occurs when the instance is created based on
- incoming result rows, and is only called once for that
- instance's lifetime.
-
- Note that during a result-row load, this method is called upon
- the first row received for this instance. Note that some
- attributes and collections may or may not be loaded or even
- initialized, depending on what's present in the result rows.
-
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :param context: the :class:`.QueryContext` corresponding to the
- current :class:`.Query` in progress. This argument may be
- ``None`` if the load does not correspond to a :class:`.Query`,
- such as during :meth:`.Session.merge`.
-
- """
-
- def refresh(self, target, context, attrs):
- """Receive an object instance after one or more attributes have
- been refreshed from a query.
-
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :param context: the :class:`.QueryContext` corresponding to the
- current :class:`.Query` in progress.
- :param attrs: iterable collection of attribute names which
- were populated, or None if all column-mapped, non-deferred
- attributes were populated.
-
- """
-
- def expire(self, target, attrs):
- """Receive an object instance after its attributes or some subset
- have been expired.
-
- 'keys' is a list of attribute names. If None, the entire
- state was expired.
-
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :param attrs: iterable collection of attribute
- names which were expired, or None if all attributes were
- expired.
-
- """
-
- def resurrect(self, target):
- """Receive an object instance as it is 'resurrected' from
- garbage collection, which occurs when a "dirty" state falls
- out of scope.
-
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
-
- """
-
- def pickle(self, target, state_dict):
- """Receive an object instance when its associated state is
- being pickled.
-
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :param state_dict: the dictionary returned by
- :class:`.InstanceState.__getstate__`, containing the state
- to be pickled.
-
- """
-
- def unpickle(self, target, state_dict):
- """Receive an object instance after it's associated state has
- been unpickled.
-
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :param state_dict: the dictionary sent to
- :class:`.InstanceState.__setstate__`, containing the state
- dictionary which was pickled.
-
- """
-
-class MapperEvents(event.Events):
- """Define events specific to mappings.
-
- e.g.::
-
- from sqlalchemy import event
-
- def my_before_insert_listener(mapper, connection, target):
- # execute a stored procedure upon INSERT,
- # apply the value to the row to be inserted
- target.calculated_value = connection.scalar(
- "select my_special_function(%d)"
- % target.special_number)
-
- # associate the listener function with SomeMappedClass,
- # to execute during the "before_insert" hook
- event.listen(SomeMappedClass, 'before_insert', my_before_insert_listener)
-
- Available targets include mapped classes, instances of
- :class:`.Mapper` (i.e. returned by :func:`.mapper`,
- :func:`.class_mapper` and similar), as well as the
- :class:`.Mapper` class and :func:`.mapper` function itself
- for global event reception::
-
- from sqlalchemy.orm import mapper
-
- def some_listener(mapper, connection, target):
- log.debug("Instance %s being inserted" % target)
-
- # attach to all mappers
- event.listen(mapper, 'before_insert', some_listener)
-
- Mapper events provide hooks into critical sections of the
- mapper, including those related to object instrumentation,
- object loading, and object persistence. In particular, the
- persistence methods :meth:`~.MapperEvents.before_insert`,
- and :meth:`~.MapperEvents.before_update` are popular
- places to augment the state being persisted - however, these
- methods operate with several significant restrictions. The
- user is encouraged to evaluate the
- :meth:`.SessionEvents.before_flush` and
- :meth:`.SessionEvents.after_flush` methods as more
- flexible and user-friendly hooks in which to apply
- additional database state during a flush.
-
- When using :class:`.MapperEvents`, several modifiers are
- available to the :func:`.event.listen` function.
-
- :param propagate=False: When True, the event listener should
- be applied to all inheriting mappers as well as the
- mapper which is the target of this listener.
- :param raw=False: When True, the "target" argument passed
- to applicable event listener functions will be the
- instance's :class:`.InstanceState` management
- object, rather than the mapped instance itself.
- :param retval=False: when True, the user-defined event function
- must have a return value, the purpose of which is either to
- control subsequent event propagation, or to otherwise alter
- the operation in progress by the mapper. Possible return
- values are:
-
- * ``sqlalchemy.orm.interfaces.EXT_CONTINUE`` - continue event
- processing normally.
- * ``sqlalchemy.orm.interfaces.EXT_STOP`` - cancel all subsequent
- event handlers in the chain.
- * other values - the return value specified by specific listeners,
- such as :meth:`~.MapperEvents.translate_row` or
- :meth:`~.MapperEvents.create_instance`.
-
- """
-
- @classmethod
- def _accept_with(cls, target):
- from sqlalchemy.orm import mapper, class_mapper, Mapper
- if target is mapper:
- return Mapper
- elif isinstance(target, type):
- if issubclass(target, Mapper):
- return target
- else:
- return class_mapper(target)
- else:
- return target
-
- @classmethod
- def _listen(cls, target, identifier, fn,
- raw=False, retval=False, propagate=False):
- from sqlalchemy.orm.interfaces import EXT_CONTINUE
-
- if not raw or not retval:
- if not raw:
- meth = getattr(cls, identifier)
- try:
- target_index = inspect.getargspec(meth)[0].index('target') - 1
- except ValueError:
- target_index = None
-
- wrapped_fn = fn
- def wrap(*arg, **kw):
- if not raw and target_index is not None:
- arg = list(arg)
- arg[target_index] = arg[target_index].obj()
- if not retval:
- wrapped_fn(*arg, **kw)
- return EXT_CONTINUE
- else:
- return wrapped_fn(*arg, **kw)
- fn = wrap
-
- if propagate:
- for mapper in target.self_and_descendants:
- event.Events._listen(mapper, identifier, fn, propagate=True)
- else:
- event.Events._listen(target, identifier, fn)
-
- def instrument_class(self, mapper, class_):
- """Receive a class when the mapper is first constructed,
- before instrumentation is applied to the mapped class.
-
- This event is the earliest phase of mapper construction.
- Most attributes of the mapper are not yet initialized.
-
- This listener can generally only be applied to the :class:`.Mapper`
- class overall.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param class\_: the mapped class.
-
- """
-
- def mapper_configured(self, mapper, class_):
- """Called when the mapper for the class is fully configured.
-
- This event is the latest phase of mapper construction.
- The mapper should be in its final state.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param class\_: the mapped class.
-
- """
- # TODO: need coverage for this event
-
- def translate_row(self, mapper, context, row):
- """Perform pre-processing on the given result row and return a
- new row instance.
-
- This listener is typically registered with ``retval=True``.
- It is called when the mapper first receives a row, before
- the object identity or the instance itself has been derived
- from that row. The given row may or may not be a
- :class:`.RowProxy` object - it will always be a dictionary-like
- object which contains mapped columns as keys. The
- returned object should also be a dictionary-like object
- which recognizes mapped columns as keys.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param context: the :class:`.QueryContext`, which includes
- a handle to the current :class:`.Query` in progress as well
- as additional state information.
- :param row: the result row being handled. This may be
- an actual :class:`.RowProxy` or may be a dictionary containing
- :class:`.Column` objects as keys.
- :return: When configured with ``retval=True``, the function
- should return a dictionary-like row object, or ``EXT_CONTINUE``,
- indicating the original row should be used.
-
-
- """
-
- def create_instance(self, mapper, context, row, class_):
- """Receive a row when a new object instance is about to be
- created from that row.
-
- The method can choose to create the instance itself, or it can return
- EXT_CONTINUE to indicate normal object creation should take place.
- This listener is typically registered with ``retval=True``.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param context: the :class:`.QueryContext`, which includes
- a handle to the current :class:`.Query` in progress as well
- as additional state information.
- :param row: the result row being handled. This may be
- an actual :class:`.RowProxy` or may be a dictionary containing
- :class:`.Column` objects as keys.
- :param class\_: the mapped class.
- :return: When configured with ``retval=True``, the return value
- should be a newly created instance of the mapped class,
- or ``EXT_CONTINUE`` indicating that default object construction
- should take place.
-
- """
-
- def append_result(self, mapper, context, row, target,
- result, **flags):
- """Receive an object instance before that instance is appended
- to a result list.
-
- This is a rarely used hook which can be used to alter
- the construction of a result list returned by :class:`.Query`.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param context: the :class:`.QueryContext`, which includes
- a handle to the current :class:`.Query` in progress as well
- as additional state information.
- :param row: the result row being handled. This may be
- an actual :class:`.RowProxy` or may be a dictionary containing
- :class:`.Column` objects as keys.
- :param target: the mapped instance being populated. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :param result: a list-like object where results are being
- appended.
- :param \**flags: Additional state information about the
- current handling of the row.
- :return: If this method is registered with ``retval=True``,
- a return value of ``EXT_STOP`` will prevent the instance
- from being appended to the given result list, whereas a
- return value of ``EXT_CONTINUE`` will result in the default
- behavior of appending the value to the result list.
-
- """
-
-
- def populate_instance(self, mapper, context, row,
- target, **flags):
- """Receive an instance before that instance has
- its attributes populated.
-
- This usually corresponds to a newly loaded instance but may
- also correspond to an already-loaded instance which has
- unloaded attributes to be populated. The method may be called
- many times for a single instance, as multiple result rows are
- used to populate eagerly loaded collections.
-
- Most usages of this hook are obsolete. For a
- generic "object has been newly created from a row" hook, use
- :meth:`.InstanceEvents.load`.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param context: the :class:`.QueryContext`, which includes
- a handle to the current :class:`.Query` in progress as well
- as additional state information.
- :param row: the result row being handled. This may be
- an actual :class:`.RowProxy` or may be a dictionary containing
- :class:`.Column` objects as keys.
- :param target: the mapped instance. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: When configured with ``retval=True``, a return
- value of ``EXT_STOP`` will bypass instance population by
- the mapper. A value of ``EXT_CONTINUE`` indicates that
- default instance population should take place.
-
- """
-
- def before_insert(self, mapper, connection, target):
- """Receive an object instance before an INSERT statement
- is emitted corresponding to that instance.
-
- This event is used to modify local, non-object related
- attributes on the instance before an INSERT occurs, as well
- as to emit additional SQL statements on the given
- connection.
-
- The event is often called for a batch of objects of the
- same class before their INSERT statements are emitted at
- once in a later step. In the extremely rare case that
- this is not desirable, the :func:`.mapper` can be
- configured with ``batch=False``, which will cause
- batches of instances to be broken up into individual
- (and more poorly performing) event->persist->event
- steps.
-
- Handlers should **not** modify any attributes which are
- mapped by :func:`.relationship`, nor should they attempt
- to make any modifications to the :class:`.Session` in
- this hook (including :meth:`.Session.add`,
- :meth:`.Session.delete`, etc.) - such changes will not
- take effect. For overall changes to the "flush plan",
- use :meth:`.SessionEvents.before_flush`.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param connection: the :class:`.Connection` being used to
- emit INSERT statements for this instance. This
- provides a handle into the current transaction on the
- target database specific to this instance.
- :param target: the mapped instance being persisted. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: No return value is supported by this event.
-
- """
-
- def after_insert(self, mapper, connection, target):
- """Receive an object instance after an INSERT statement
- is emitted corresponding to that instance.
-
- This event is used to modify in-Python-only
- state on the instance after an INSERT occurs, as well
- as to emit additional SQL statements on the given
- connection.
-
- The event is often called for a batch of objects of the
- same class after their INSERT statements have been
- emitted at once in a previous step. In the extremely
- rare case that this is not desirable, the
- :func:`.mapper` can be configured with ``batch=False``,
- which will cause batches of instances to be broken up
- into individual (and more poorly performing)
- event->persist->event steps.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param connection: the :class:`.Connection` being used to
- emit INSERT statements for this instance. This
- provides a handle into the current transaction on the
- target database specific to this instance.
- :param target: the mapped instance being persisted. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: No return value is supported by this event.
-
- """
-
- def before_update(self, mapper, connection, target):
- """Receive an object instance before an UPDATE statement
- is emitted corresponding to that instance.
-
- This event is used to modify local, non-object related
- attributes on the instance before an UPDATE occurs, as well
- as to emit additional SQL statements on the given
- connection.
-
- This method is called for all instances that are
- marked as "dirty", *even those which have no net changes
- to their column-based attributes*. An object is marked
- as dirty when any of its column-based attributes have a
- "set attribute" operation called or when any of its
- collections are modified. If, at update time, no
- column-based attributes have any net changes, no UPDATE
- statement will be issued. This means that an instance
- being sent to :meth:`~.MapperEvents.before_update` is
- *not* a guarantee that an UPDATE statement will be
- issued, although you can affect the outcome here by
- modifying attributes so that a net change in value does
- exist.
-
- To detect if the column-based attributes on the object have net
- changes, and will therefore generate an UPDATE statement, use
- ``object_session(instance).is_modified(instance,
- include_collections=False)``.
-
- The event is often called for a batch of objects of the
- same class before their UPDATE statements are emitted at
- once in a later step. In the extremely rare case that
- this is not desirable, the :func:`.mapper` can be
- configured with ``batch=False``, which will cause
- batches of instances to be broken up into individual
- (and more poorly performing) event->persist->event
- steps.
-
- Handlers should **not** modify any attributes which are
- mapped by :func:`.relationship`, nor should they attempt
- to make any modifications to the :class:`.Session` in
- this hook (including :meth:`.Session.add`,
- :meth:`.Session.delete`, etc.) - such changes will not
- take effect. For overall changes to the "flush plan",
- use :meth:`.SessionEvents.before_flush`.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param connection: the :class:`.Connection` being used to
- emit UPDATE statements for this instance. This
- provides a handle into the current transaction on the
- target database specific to this instance.
- :param target: the mapped instance being persisted. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: No return value is supported by this event.
- """
-
- def after_update(self, mapper, connection, target):
- """Receive an object instance after an UPDATE statement
- is emitted corresponding to that instance.
-
- This event is used to modify in-Python-only
- state on the instance after an UPDATE occurs, as well
- as to emit additional SQL statements on the given
- connection.
-
- This method is called for all instances that are
- marked as "dirty", *even those which have no net changes
- to their column-based attributes*, and for which
- no UPDATE statement has proceeded. An object is marked
- as dirty when any of its column-based attributes have a
- "set attribute" operation called or when any of its
- collections are modified. If, at update time, no
- column-based attributes have any net changes, no UPDATE
- statement will be issued. This means that an instance
- being sent to :meth:`~.MapperEvents.after_update` is
- *not* a guarantee that an UPDATE statement has been
- issued.
-
- To detect if the column-based attributes on the object have net
- changes, and therefore resulted in an UPDATE statement, use
- ``object_session(instance).is_modified(instance,
- include_collections=False)``.
-
- The event is often called for a batch of objects of the
- same class after their UPDATE statements have been emitted at
- once in a previous step. In the extremely rare case that
- this is not desirable, the :func:`.mapper` can be
- configured with ``batch=False``, which will cause
- batches of instances to be broken up into individual
- (and more poorly performing) event->persist->event
- steps.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param connection: the :class:`.Connection` being used to
- emit UPDATE statements for this instance. This
- provides a handle into the current transaction on the
- target database specific to this instance.
- :param target: the mapped instance being persisted. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: No return value is supported by this event.
-
- """
-
- def before_delete(self, mapper, connection, target):
- """Receive an object instance before a DELETE statement
- is emitted corresponding to that instance.
-
- This event is used to emit additional SQL statements on
- the given connection as well as to perform application
- specific bookkeeping related to a deletion event.
-
- The event is often called for a batch of objects of the
- same class before their DELETE statements are emitted at
- once in a later step.
-
- Handlers should **not** modify any attributes which are
- mapped by :func:`.relationship`, nor should they attempt
- to make any modifications to the :class:`.Session` in
- this hook (including :meth:`.Session.add`,
- :meth:`.Session.delete`, etc.) - such changes will not
- take effect. For overall changes to the "flush plan",
- use :meth:`.SessionEvents.before_flush`.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param connection: the :class:`.Connection` being used to
- emit DELETE statements for this instance. This
- provides a handle into the current transaction on the
- target database specific to this instance.
- :param target: the mapped instance being deleted. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: No return value is supported by this event.
-
- """
-
- def after_delete(self, mapper, connection, target):
- """Receive an object instance after a DELETE statement
- has been emitted corresponding to that instance.
-
- This event is used to emit additional SQL statements on
- the given connection as well as to perform application
- specific bookkeeping related to a deletion event.
-
- The event is often called for a batch of objects of the
- same class after their DELETE statements have been emitted at
- once in a previous step.
-
- :param mapper: the :class:`.Mapper` which is the target
- of this event.
- :param connection: the :class:`.Connection` being used to
- emit DELETE statements for this instance. This
- provides a handle into the current transaction on the
- target database specific to this instance.
- :param target: the mapped instance being deleted. If
- the event is configured with ``raw=True``, this will
- instead be the :class:`.InstanceState` state-management
- object associated with the instance.
- :return: No return value is supported by this event.
-
- """
-
- @classmethod
- def _remove(cls, identifier, target, fn):
- raise NotImplementedError("Removal of mapper events not yet implemented")
-
-class SessionEvents(event.Events):
- """Define events specific to :class:`.Session` lifecycle.
-
- e.g.::
-
- from sqlalchemy import event
- from sqlalchemy.orm import sessionmaker
-
- def my_before_commit(session):
- print "before commit!"
-
- Session = sessionmaker()
-
- event.listen(Session, "before_commit", my_before_commit)
-
- The :func:`~.event.listen` function will accept
- :class:`.Session` objects as well as the return result
- of :func:`.sessionmaker` and :func:`.scoped_session`.
-
- Additionally, it accepts the :class:`.Session` class which
- will apply listeners to all :class:`.Session` instances
- globally.
-
- """
-
- @classmethod
- def _accept_with(cls, target):
- from sqlalchemy.orm import ScopedSession, Session
- if isinstance(target, ScopedSession):
- if not isinstance(target.session_factory, type) or \
- not issubclass(target.session_factory, Session):
- raise exc.ArgumentError(
- "Session event listen on a ScopedSession "
- "requires that its creation callable "
- "is a Session subclass.")
- return target.session_factory
- elif isinstance(target, type):
- if issubclass(target, ScopedSession):
- return Session
- elif issubclass(target, Session):
- return target
- elif isinstance(target, Session):
- return target
- else:
- return None
-
- @classmethod
- def _remove(cls, identifier, target, fn):
- raise NotImplementedError("Removal of session events not yet implemented")
-
- def before_commit(self, session):
- """Execute before commit is called.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def after_commit(self, session):
- """Execute after a commit has occurred.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def after_rollback(self, session):
- """Execute after a rollback has occurred.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def before_flush( self, session, flush_context, instances):
- """Execute before flush process has started.
-
- `instances` is an optional list of objects which were passed to
- the ``flush()`` method. """
-
- def after_flush(self, session, flush_context):
- """Execute after flush has completed, but before commit has been
- called.
-
- Note that the session's state is still in pre-flush, i.e. 'new',
- 'dirty', and 'deleted' lists still show pre-flush state as well
- as the history settings on instance attributes."""
-
- def after_flush_postexec(self, session, flush_context):
- """Execute after flush has completed, and after the post-exec
- state occurs.
-
- This will be when the 'new', 'dirty', and 'deleted' lists are in
- their final state. An actual commit() may or may not have
- occurred, depending on whether or not the flush started its own
- transaction or participated in a larger transaction. """
-
- def after_begin( self, session, transaction, connection):
- """Execute after a transaction is begun on a connection
-
- `transaction` is the SessionTransaction. This method is called
- after an engine level transaction is begun on a connection. """
-
- def after_attach(self, session, instance):
- """Execute after an instance is attached to a session.
-
- This is called after an add, delete or merge. """
-
- def after_bulk_update( self, session, query, query_context, result):
- """Execute after a bulk update operation to the session.
-
- This is called after a session.query(...).update()
-
- `query` is the query object that this update operation was
- called on. `query_context` was the query context object.
- `result` is the result object returned from the bulk operation.
- """
-
- def after_bulk_delete( self, session, query, query_context, result):
- """Execute after a bulk delete operation to the session.
-
- This is called after a session.query(...).delete()
-
- `query` is the query object that this delete operation was
- called on. `query_context` was the query context object.
- `result` is the result object returned from the bulk operation.
- """
-
-
-class AttributeEvents(event.Events):
- """Define events for object attributes.
-
- These are typically defined on the class-bound descriptor for the
- target class.
-
- e.g.::
-
- from sqlalchemy import event
-
- def my_append_listener(target, value, initiator):
- print "received append event for target: %s" % target
-
- event.listen(MyClass.collection, 'append', my_append_listener)
-
- Listeners have the option to return a possibly modified version
- of the value, when the ``retval=True`` flag is passed
- to :func:`~.event.listen`::
-
- def validate_phone(target, value, oldvalue, initiator):
- "Strip non-numeric characters from a phone number"
-
- return re.sub(r'(?![0-9])', '', value)
-
- # setup listener on UserContact.phone attribute, instructing
- # it to use the return value
- listen(UserContact.phone, 'set', validate_phone, retval=True)
-
- A validation function like the above can also raise an exception
- such as :class:`.ValueError` to halt the operation.
-
- Several modifiers are available to the :func:`~.event.listen` function.
-
- :param active_history=False: When True, indicates that the
- "set" event would like to receive the "old" value being
- replaced unconditionally, even if this requires firing off
- database loads. Note that ``active_history`` can also be
- set directly via :func:`.column_property` and
- :func:`.relationship`.
-
- :param propagate=False: When True, the listener function will
- be established not just for the class attribute given, but
- for attributes of the same name on all current subclasses
- of that class, as well as all future subclasses of that
- class, using an additional listener that listens for
- instrumentation events.
- :param raw=False: When True, the "target" argument to the
- event will be the :class:`.InstanceState` management
- object, rather than the mapped instance itself.
- :param retval=False: when True, the user-defined event
- listening must return the "value" argument from the
- function. This gives the listening function the opportunity
- to change the value that is ultimately used for a "set"
- or "append" event.
-
- """
-
- @classmethod
- def _accept_with(cls, target):
- from sqlalchemy.orm import interfaces
- # TODO: coverage
- if isinstance(target, interfaces.MapperProperty):
- return getattr(target.parent.class_, target.key)
- else:
- return target
-
- @classmethod
- def _listen(cls, target, identifier, fn, active_history=False,
- raw=False, retval=False,
- propagate=False):
- if active_history:
- target.dispatch._active_history = True
-
- # TODO: for removal, need to package the identity
- # of the wrapper with the original function.
-
- if not raw or not retval:
- orig_fn = fn
- def wrap(target, value, *arg):
- if not raw:
- target = target.obj()
- if not retval:
- orig_fn(target, value, *arg)
- return value
- else:
- return orig_fn(target, value, *arg)
- fn = wrap
-
- event.Events._listen(target, identifier, fn, propagate)
-
- if propagate:
- from sqlalchemy.orm.instrumentation import manager_of_class
-
- manager = manager_of_class(target.class_)
-
- for mgr in manager.subclass_managers(True):
- event.Events._listen(mgr[target.key], identifier, fn, True)
-
- @classmethod
- def _remove(cls, identifier, target, fn):
- raise NotImplementedError("Removal of attribute events not yet implemented")
-
- def append(self, target, value, initiator):
- """Receive a collection append event.
-
- :param target: the object instance receiving the event.
- If the listener is registered with ``raw=True``, this will
- be the :class:`.InstanceState` object.
- :param value: the value being appended. If this listener
- is registered with ``retval=True``, the listener
- function must return this value, or a new value which
- replaces it.
- :param initiator: the attribute implementation object
- which initiated this event.
- :return: if the event was registered with ``retval=True``,
- the given value, or a new effective value, should be returned.
-
- """
-
- def remove(self, target, value, initiator):
- """Receive a collection remove event.
-
- :param target: the object instance receiving the event.
- If the listener is registered with ``raw=True``, this will
- be the :class:`.InstanceState` object.
- :param value: the value being removed.
- :param initiator: the attribute implementation object
- which initiated this event.
- :return: No return value is defined for this event.
- """
-
- def set(self, target, value, oldvalue, initiator):
- """Receive a scalar set event.
-
- :param target: the object instance receiving the event.
- If the listener is registered with ``raw=True``, this will
- be the :class:`.InstanceState` object.
- :param value: the value being set. If this listener
- is registered with ``retval=True``, the listener
- function must return this value, or a new value which
- replaces it.
- :param oldvalue: the previous value being replaced. This
- may also be the symbol ``NEVER_SET`` or ``NO_VALUE``.
- If the listener is registered with ``active_history=True``,
- the previous value of the attribute will be loaded from
- the database if the existing value is currently unloaded
- or expired.
- :param initiator: the attribute implementation object
- which initiated this event.
- :return: if the event was registered with ``retval=True``,
- the given value, or a new effective value, should be returned.
-
- """
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/exc.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/exc.py
deleted file mode 100755
index 3bfb2708..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/exc.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# orm/exc.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""SQLAlchemy ORM exceptions."""
-
-import sqlalchemy as sa
-
-
-NO_STATE = (AttributeError, KeyError)
-"""Exception types that may be raised by instrumentation implementations."""
-
-class StaleDataError(sa.exc.SQLAlchemyError):
- """An operation encountered database state that is unaccounted for.
-
- Two conditions cause this to happen:
-
- * A flush may have attempted to update or delete rows
- and an unexpected number of rows were matched during
- the UPDATE or DELETE statement. Note that when
- version_id_col is used, rows in UPDATE or DELETE statements
- are also matched against the current known version
- identifier.
-
- * A mapped object with version_id_col was refreshed,
- and the version number coming back from the database does
- not match that of the object itself.
-
- """
-
-ConcurrentModificationError = StaleDataError
-
-
-class FlushError(sa.exc.SQLAlchemyError):
- """A invalid condition was detected during flush()."""
-
-
-class UnmappedError(sa.exc.InvalidRequestError):
- """Base for exceptions that involve expected mappings not present."""
-
-class ObjectDereferencedError(sa.exc.SQLAlchemyError):
- """An operation cannot complete due to an object being garbage collected."""
-
-class DetachedInstanceError(sa.exc.SQLAlchemyError):
- """An attempt to access unloaded attributes on a
- mapped instance that is detached."""
-
-class UnmappedInstanceError(UnmappedError):
- """An mapping operation was requested for an unknown instance."""
-
- def __init__(self, obj, msg=None):
- if not msg:
- try:
- mapper = sa.orm.class_mapper(type(obj))
- name = _safe_cls_name(type(obj))
- msg = ("Class %r is mapped, but this instance lacks "
- "instrumentation. This occurs when the instance is created "
- "before sqlalchemy.orm.mapper(%s) was called." % (name, name))
- except UnmappedClassError:
- msg = _default_unmapped(type(obj))
- if isinstance(obj, type):
- msg += (
- '; was a class (%s) supplied where an instance was '
- 'required?' % _safe_cls_name(obj))
- UnmappedError.__init__(self, msg)
-
-
-class UnmappedClassError(UnmappedError):
- """An mapping operation was requested for an unknown class."""
-
- def __init__(self, cls, msg=None):
- if not msg:
- msg = _default_unmapped(cls)
- UnmappedError.__init__(self, msg)
-
-
-class ObjectDeletedError(sa.exc.InvalidRequestError):
- """An refresh() operation failed to re-retrieve an object's row."""
-
-
-class UnmappedColumnError(sa.exc.InvalidRequestError):
- """Mapping operation was requested on an unknown column."""
-
-
-class NoResultFound(sa.exc.InvalidRequestError):
- """A database result was required but none was found."""
-
-
-class MultipleResultsFound(sa.exc.InvalidRequestError):
- """A single database result was required but more than one were found."""
-
-
-# Legacy compat until 0.6.
-sa.exc.ConcurrentModificationError = ConcurrentModificationError
-sa.exc.FlushError = FlushError
-sa.exc.UnmappedColumnError
-
-def _safe_cls_name(cls):
- try:
- cls_name = '.'.join((cls.__module__, cls.__name__))
- except AttributeError:
- cls_name = getattr(cls, '__name__', None)
- if cls_name is None:
- cls_name = repr(cls)
- return cls_name
-
-def _default_unmapped(cls):
- try:
- mappers = sa.orm.attributes.manager_of_class(cls).mappers
- except NO_STATE:
- mappers = {}
- except TypeError:
- mappers = {}
- name = _safe_cls_name(cls)
-
- if not mappers:
- return "Class '%s' is not mapped" % name
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/identity.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/identity.py
deleted file mode 100755
index 8f000e41..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/identity.py
+++ /dev/null
@@ -1,254 +0,0 @@
-# orm/identity.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-import weakref
-from sqlalchemy.orm import attributes
-
-
-class IdentityMap(dict):
- def __init__(self):
- self._mutable_attrs = set()
- self._modified = set()
- self._wr = weakref.ref(self)
-
- def replace(self, state):
- raise NotImplementedError()
-
- def add(self, state):
- raise NotImplementedError()
-
- def update(self, dict):
- raise NotImplementedError("IdentityMap uses add() to insert data")
-
- def clear(self):
- raise NotImplementedError("IdentityMap uses remove() to remove data")
-
- def _manage_incoming_state(self, state):
- state._instance_dict = self._wr
-
- if state.modified:
- self._modified.add(state)
- if state.manager.mutable_attributes:
- self._mutable_attrs.add(state)
-
- def _manage_removed_state(self, state):
- del state._instance_dict
- self._mutable_attrs.discard(state)
- self._modified.discard(state)
-
- def _dirty_states(self):
- return self._modified.union(s for s in self._mutable_attrs.copy()
- if s.modified)
-
- def check_modified(self):
- """return True if any InstanceStates present have been marked as 'modified'."""
-
- if self._modified:
- return True
- else:
- for state in self._mutable_attrs.copy():
- if state.modified:
- return True
- return False
-
- def has_key(self, key):
- return key in self
-
- def popitem(self):
- raise NotImplementedError("IdentityMap uses remove() to remove data")
-
- def pop(self, key, *args):
- raise NotImplementedError("IdentityMap uses remove() to remove data")
-
- def setdefault(self, key, default=None):
- raise NotImplementedError("IdentityMap uses add() to insert data")
-
- def copy(self):
- raise NotImplementedError()
-
- def __setitem__(self, key, value):
- raise NotImplementedError("IdentityMap uses add() to insert data")
-
- def __delitem__(self, key):
- raise NotImplementedError("IdentityMap uses remove() to remove data")
-
-class WeakInstanceDict(IdentityMap):
- def __init__(self):
- IdentityMap.__init__(self)
-
- def __getitem__(self, key):
- state = dict.__getitem__(self, key)
- o = state.obj()
- if o is None:
- o = state._is_really_none()
- if o is None:
- raise KeyError, key
- return o
-
- def __contains__(self, key):
- try:
- if dict.__contains__(self, key):
- state = dict.__getitem__(self, key)
- o = state.obj()
- if o is None:
- o = state._is_really_none()
- else:
- return False
- except KeyError:
- return False
- else:
- return o is not None
-
- def contains_state(self, state):
- return dict.get(self, state.key) is state
-
- def replace(self, state):
- if dict.__contains__(self, state.key):
- existing = dict.__getitem__(self, state.key)
- if existing is not state:
- self._manage_removed_state(existing)
- else:
- return
-
- dict.__setitem__(self, state.key, state)
- self._manage_incoming_state(state)
-
- def add(self, state):
- key = state.key
- # inline of self.__contains__
- if dict.__contains__(self, key):
- try:
- existing_state = dict.__getitem__(self, key)
- if existing_state is not state:
- o = existing_state.obj()
- if o is None:
- o = existing_state._is_really_none()
- if o is not None:
- raise AssertionError("A conflicting state is already "
- "present in the identity map for key %r"
- % (key, ))
- else:
- return
- except KeyError:
- pass
- dict.__setitem__(self, key, state)
- self._manage_incoming_state(state)
-
- def get(self, key, default=None):
- state = dict.get(self, key, default)
- if state is default:
- return default
- o = state.obj()
- if o is None:
- o = state._is_really_none()
- if o is None:
- return default
- return o
-
- def _items(self):
- values = self.all_states()
- result = []
- for state in values:
- value = state.obj()
- if value is not None:
- result.append((state.key, value))
- return result
-
- def _values(self):
- values = self.all_states()
- result = []
- for state in values:
- value = state.obj()
- if value is not None:
- result.append(value)
-
- return result
-
- # Py3K
- #def items(self):
- # return iter(self._items())
- #
- #def values(self):
- # return iter(self._values())
- # Py2K
- items = _items
- def iteritems(self):
- return iter(self.items())
-
- values = _values
- def itervalues(self):
- return iter(self.values())
- # end Py2K
-
- def all_states(self):
- # Py3K
- # return list(dict.values(self))
- # Py2K
- return dict.values(self)
- # end Py2K
-
- def discard(self, state):
- st = dict.get(self, state.key, None)
- if st is state:
- dict.__delitem__(self, state.key)
- self._manage_removed_state(state)
-
- def prune(self):
- return 0
-
-class StrongInstanceDict(IdentityMap):
- def all_states(self):
- return [attributes.instance_state(o) for o in self.itervalues()]
-
- def contains_state(self, state):
- return state.key in self and attributes.instance_state(self[state.key]) is state
-
- def replace(self, state):
- if dict.__contains__(self, state.key):
- existing = dict.__getitem__(self, state.key)
- existing = attributes.instance_state(existing)
- if existing is not state:
- self._manage_removed_state(existing)
- else:
- return
-
- dict.__setitem__(self, state.key, state.obj())
- self._manage_incoming_state(state)
-
- def add(self, state):
- if state.key in self:
- if attributes.instance_state(dict.__getitem__(self,
- state.key)) is not state:
- raise AssertionError('A conflicting state is already '
- 'present in the identity map for key %r'
- % (state.key, ))
- else:
- dict.__setitem__(self, state.key, state.obj())
- self._manage_incoming_state(state)
-
- def discard(self, state):
- obj = dict.get(self, state.key, None)
- if obj is not None:
- st = attributes.instance_state(obj)
- if st is state:
- dict.__delitem__(self, state.key)
- self._manage_removed_state(state)
-
- def prune(self):
- """prune unreferenced, non-dirty states."""
-
- ref_count = len(self)
- dirty = [s.obj() for s in self.all_states() if s.modified]
-
- # work around http://bugs.python.org/issue6149
- keepers = weakref.WeakValueDictionary()
- keepers.update(self)
-
- dict.clear(self)
- dict.update(self, keepers)
- self.modified = bool(dirty)
- return ref_count - len(self)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/instrumentation.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/instrumentation.py
deleted file mode 100755
index aa051490..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/instrumentation.py
+++ /dev/null
@@ -1,691 +0,0 @@
-# orm/instrumentation.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Defines SQLAlchemy's system of class instrumentation.
-
-This module is usually not directly visible to user applications, but
-defines a large part of the ORM's interactivity.
-
-instrumentation.py deals with registration of end-user classes
-for state tracking. It interacts closely with state.py
-and attributes.py which establish per-instance and per-class-attribute
-instrumentation, respectively.
-
-SQLA's instrumentation system is completely customizable, in which
-case an understanding of the general mechanics of this module is helpful.
-An example of full customization is in /examples/custom_attributes.
-
-"""
-
-
-from sqlalchemy.orm import exc, collections, events
-from operator import attrgetter, itemgetter
-from sqlalchemy import event, util
-import weakref
-from sqlalchemy.orm import state, attributes
-
-
-INSTRUMENTATION_MANAGER = '__sa_instrumentation_manager__'
-"""Attribute, elects custom instrumentation when present on a mapped class.
-
-Allows a class to specify a slightly or wildly different technique for
-tracking changes made to mapped attributes and collections.
-
-Only one instrumentation implementation is allowed in a given object
-inheritance hierarchy.
-
-The value of this attribute must be a callable and will be passed a class
-object. The callable must return one of:
-
- - An instance of an interfaces.InstrumentationManager or subclass
- - An object implementing all or some of InstrumentationManager (TODO)
- - A dictionary of callables, implementing all or some of the above (TODO)
- - An instance of a ClassManager or subclass
-
-interfaces.InstrumentationManager is public API and will remain stable
-between releases. ClassManager is not public and no guarantees are made
-about stability. Caveat emptor.
-
-This attribute is consulted by the default SQLAlchemy instrumentation
-resolution code. If custom finders are installed in the global
-instrumentation_finders list, they may or may not choose to honor this
-attribute.
-
-"""
-
-instrumentation_finders = []
-"""An extensible sequence of instrumentation implementation finding callables.
-
-Finders callables will be passed a class object. If None is returned, the
-next finder in the sequence is consulted. Otherwise the return must be an
-instrumentation factory that follows the same guidelines as
-INSTRUMENTATION_MANAGER.
-
-By default, the only finder is find_native_user_instrumentation_hook, which
-searches for INSTRUMENTATION_MANAGER. If all finders return None, standard
-ClassManager instrumentation is used.
-
-"""
-
-
-class ClassManager(dict):
- """tracks state information at the class level."""
-
- MANAGER_ATTR = '_sa_class_manager'
- STATE_ATTR = '_sa_instance_state'
-
- deferred_scalar_loader = None
-
- original_init = object.__init__
-
- def __init__(self, class_):
- self.class_ = class_
- self.factory = None # where we came from, for inheritance bookkeeping
- self.info = {}
- self.new_init = None
- self.mutable_attributes = set()
- self.local_attrs = {}
- self.originals = {}
-
- self._bases = [mgr for mgr in [
- manager_of_class(base)
- for base in self.class_.__bases__
- if isinstance(base, type)
- ] if mgr is not None]
-
- for base in self._bases:
- self.update(base)
-
- self.manage()
- self._instrument_init()
-
- dispatch = event.dispatcher(events.InstanceEvents)
-
- @property
- def is_mapped(self):
- return 'mapper' in self.__dict__
-
- @util.memoized_property
- def mapper(self):
- raise exc.UnmappedClassError(self.class_)
-
- def _attr_has_impl(self, key):
- """Return True if the given attribute is fully initialized.
-
- i.e. has an impl.
- """
-
- return key in self and self[key].impl is not None
-
- def _configure_create_arguments(self,
- _source=None,
- deferred_scalar_loader=None):
- """Accept extra **kw arguments passed to create_manager_for_cls.
-
- The current contract of ClassManager and other managers is that they
- take a single "cls" argument in their constructor (as per
- test/orm/instrumentation.py InstrumentationCollisionTest). This
- is to provide consistency with the current API of "class manager"
- callables and such which may return various ClassManager and
- ClassManager-like instances. So create_manager_for_cls sends
- in ClassManager-specific arguments via this method once the
- non-proxied ClassManager is available.
-
- """
- if _source:
- deferred_scalar_loader = _source.deferred_scalar_loader
-
- if deferred_scalar_loader:
- self.deferred_scalar_loader = deferred_scalar_loader
-
- def _subclass_manager(self, cls):
- """Create a new ClassManager for a subclass of this ClassManager's
- class.
-
- This is called automatically when attributes are instrumented so that
- the attributes can be propagated to subclasses against their own
- class-local manager, without the need for mappers etc. to have already
- pre-configured managers for the full class hierarchy. Mappers
- can post-configure the auto-generated ClassManager when needed.
-
- """
- manager = manager_of_class(cls)
- if manager is None:
- manager = _create_manager_for_cls(cls, _source=self)
- return manager
-
- def _instrument_init(self):
- # TODO: self.class_.__init__ is often the already-instrumented
- # __init__ from an instrumented superclass. We still need to make
- # our own wrapper, but it would
- # be nice to wrap the original __init__ and not our existing wrapper
- # of such, since this adds method overhead.
- self.original_init = self.class_.__init__
- self.new_init = _generate_init(self.class_, self)
- self.install_member('__init__', self.new_init)
-
- def _uninstrument_init(self):
- if self.new_init:
- self.uninstall_member('__init__')
- self.new_init = None
-
- @util.memoized_property
- def _state_constructor(self):
- self.dispatch.first_init(self, self.class_)
- if self.mutable_attributes:
- return state.MutableAttrInstanceState
- else:
- return state.InstanceState
-
- def manage(self):
- """Mark this instance as the manager for its class."""
-
- setattr(self.class_, self.MANAGER_ATTR, self)
-
- def dispose(self):
- """Dissasociate this manager from its class."""
-
- delattr(self.class_, self.MANAGER_ATTR)
-
- def manager_getter(self):
- return attrgetter(self.MANAGER_ATTR)
-
- def instrument_attribute(self, key, inst, propagated=False):
- if propagated:
- if key in self.local_attrs:
- return # don't override local attr with inherited attr
- else:
- self.local_attrs[key] = inst
- self.install_descriptor(key, inst)
- self[key] = inst
-
- for cls in self.class_.__subclasses__():
- manager = self._subclass_manager(cls)
- manager.instrument_attribute(key, inst, True)
-
- def subclass_managers(self, recursive):
- for cls in self.class_.__subclasses__():
- mgr = manager_of_class(cls)
- if mgr is not None and mgr is not self:
- yield mgr
- if recursive:
- for m in mgr.subclass_managers(True):
- yield m
-
- def post_configure_attribute(self, key):
- instrumentation_registry.dispatch.\
- attribute_instrument(self.class_, key, self[key])
-
- def uninstrument_attribute(self, key, propagated=False):
- if key not in self:
- return
- if propagated:
- if key in self.local_attrs:
- return # don't get rid of local attr
- else:
- del self.local_attrs[key]
- self.uninstall_descriptor(key)
- del self[key]
- if key in self.mutable_attributes:
- self.mutable_attributes.remove(key)
- for cls in self.class_.__subclasses__():
- manager = manager_of_class(cls)
- if manager:
- manager.uninstrument_attribute(key, True)
-
- def unregister(self):
- """remove all instrumentation established by this ClassManager."""
-
- self._uninstrument_init()
-
- self.mapper = self.dispatch = None
- self.info.clear()
-
- for key in list(self):
- if key in self.local_attrs:
- self.uninstrument_attribute(key)
-
- def install_descriptor(self, key, inst):
- if key in (self.STATE_ATTR, self.MANAGER_ATTR):
- raise KeyError("%r: requested attribute name conflicts with "
- "instrumentation attribute of the same name." %
- key)
- setattr(self.class_, key, inst)
-
- def uninstall_descriptor(self, key):
- delattr(self.class_, key)
-
- def install_member(self, key, implementation):
- if key in (self.STATE_ATTR, self.MANAGER_ATTR):
- raise KeyError("%r: requested attribute name conflicts with "
- "instrumentation attribute of the same name." %
- key)
- self.originals.setdefault(key, getattr(self.class_, key, None))
- setattr(self.class_, key, implementation)
-
- def uninstall_member(self, key):
- original = self.originals.pop(key, None)
- if original is not None:
- setattr(self.class_, key, original)
-
- def instrument_collection_class(self, key, collection_class):
- return collections.prepare_instrumentation(collection_class)
-
- def initialize_collection(self, key, state, factory):
- user_data = factory()
- adapter = collections.CollectionAdapter(
- self.get_impl(key), state, user_data)
- return adapter, user_data
-
- def is_instrumented(self, key, search=False):
- if search:
- return key in self
- else:
- return key in self.local_attrs
-
- def get_impl(self, key):
- return self[key].impl
-
- @property
- def attributes(self):
- return self.itervalues()
-
- ## InstanceState management
-
- def new_instance(self, state=None):
- instance = self.class_.__new__(self.class_)
- setattr(instance, self.STATE_ATTR,
- state or self._state_constructor(instance, self))
- return instance
-
- def setup_instance(self, instance, state=None):
- setattr(instance, self.STATE_ATTR,
- state or self._state_constructor(instance, self))
-
- def teardown_instance(self, instance):
- delattr(instance, self.STATE_ATTR)
-
- def _new_state_if_none(self, instance):
- """Install a default InstanceState if none is present.
-
- A private convenience method used by the __init__ decorator.
-
- """
- if hasattr(instance, self.STATE_ATTR):
- return False
- elif self.class_ is not instance.__class__ and \
- self.is_mapped:
- # this will create a new ClassManager for the
- # subclass, without a mapper. This is likely a
- # user error situation but allow the object
- # to be constructed, so that it is usable
- # in a non-ORM context at least.
- return self._subclass_manager(instance.__class__).\
- _new_state_if_none(instance)
- else:
- state = self._state_constructor(instance, self)
- setattr(instance, self.STATE_ATTR, state)
- return state
-
- def state_getter(self):
- """Return a (instance) -> InstanceState callable.
-
- "state getter" callables should raise either KeyError or
- AttributeError if no InstanceState could be found for the
- instance.
- """
-
- return attrgetter(self.STATE_ATTR)
-
- def dict_getter(self):
- return attrgetter('__dict__')
-
- def has_state(self, instance):
- return hasattr(instance, self.STATE_ATTR)
-
- def has_parent(self, state, key, optimistic=False):
- """TODO"""
- return self.get_impl(key).hasparent(state, optimistic=optimistic)
-
- def __nonzero__(self):
- """All ClassManagers are non-zero regardless of attribute state."""
- return True
-
- def __repr__(self):
- return '<%s of %r at %x>' % (
- self.__class__.__name__, self.class_, id(self))
-
-class _ClassInstrumentationAdapter(ClassManager):
- """Adapts a user-defined InstrumentationManager to a ClassManager."""
-
- def __init__(self, class_, override, **kw):
- self._adapted = override
- self._get_state = self._adapted.state_getter(class_)
- self._get_dict = self._adapted.dict_getter(class_)
-
- ClassManager.__init__(self, class_, **kw)
-
- def manage(self):
- self._adapted.manage(self.class_, self)
-
- def dispose(self):
- self._adapted.dispose(self.class_)
-
- def manager_getter(self):
- return self._adapted.manager_getter(self.class_)
-
- def instrument_attribute(self, key, inst, propagated=False):
- ClassManager.instrument_attribute(self, key, inst, propagated)
- if not propagated:
- self._adapted.instrument_attribute(self.class_, key, inst)
-
- def post_configure_attribute(self, key):
- super(_ClassInstrumentationAdapter, self).post_configure_attribute(key)
- self._adapted.post_configure_attribute(self.class_, key, self[key])
-
- def install_descriptor(self, key, inst):
- self._adapted.install_descriptor(self.class_, key, inst)
-
- def uninstall_descriptor(self, key):
- self._adapted.uninstall_descriptor(self.class_, key)
-
- def install_member(self, key, implementation):
- self._adapted.install_member(self.class_, key, implementation)
-
- def uninstall_member(self, key):
- self._adapted.uninstall_member(self.class_, key)
-
- def instrument_collection_class(self, key, collection_class):
- return self._adapted.instrument_collection_class(
- self.class_, key, collection_class)
-
- def initialize_collection(self, key, state, factory):
- delegate = getattr(self._adapted, 'initialize_collection', None)
- if delegate:
- return delegate(key, state, factory)
- else:
- return ClassManager.initialize_collection(self, key,
- state, factory)
-
- def new_instance(self, state=None):
- instance = self.class_.__new__(self.class_)
- self.setup_instance(instance, state)
- return instance
-
- def _new_state_if_none(self, instance):
- """Install a default InstanceState if none is present.
-
- A private convenience method used by the __init__ decorator.
- """
- if self.has_state(instance):
- return False
- else:
- return self.setup_instance(instance)
-
- def setup_instance(self, instance, state=None):
- self._adapted.initialize_instance_dict(self.class_, instance)
-
- if state is None:
- state = self._state_constructor(instance, self)
-
- # the given instance is assumed to have no state
- self._adapted.install_state(self.class_, instance, state)
- return state
-
- def teardown_instance(self, instance):
- self._adapted.remove_state(self.class_, instance)
-
- def has_state(self, instance):
- try:
- state = self._get_state(instance)
- except exc.NO_STATE:
- return False
- else:
- return True
-
- def state_getter(self):
- return self._get_state
-
- def dict_getter(self):
- return self._get_dict
-
-def register_class(class_, **kw):
- """Register class instrumentation.
-
- Returns the existing or newly created class manager.
- """
-
- manager = manager_of_class(class_)
- if manager is None:
- manager = _create_manager_for_cls(class_, **kw)
- return manager
-
-def unregister_class(class_):
- """Unregister class instrumentation."""
-
- instrumentation_registry.unregister(class_)
-
-
-def is_instrumented(instance, key):
- """Return True if the given attribute on the given instance is
- instrumented by the attributes package.
-
- This function may be used regardless of instrumentation
- applied directly to the class, i.e. no descriptors are required.
-
- """
- return manager_of_class(instance.__class__).\
- is_instrumented(key, search=True)
-
-class InstrumentationRegistry(object):
- """Private instrumentation registration singleton.
-
- All classes are routed through this registry
- when first instrumented, however the InstrumentationRegistry
- is not actually needed unless custom ClassManagers are in use.
-
- """
-
- _manager_finders = weakref.WeakKeyDictionary()
- _state_finders = util.WeakIdentityMapping()
- _dict_finders = util.WeakIdentityMapping()
- _extended = False
-
- dispatch = event.dispatcher(events.InstrumentationEvents)
-
- def create_manager_for_cls(self, class_, **kw):
- assert class_ is not None
- assert manager_of_class(class_) is None
-
- for finder in instrumentation_finders:
- factory = finder(class_)
- if factory is not None:
- break
- else:
- factory = ClassManager
-
- existing_factories = self._collect_management_factories_for(class_).\
- difference([factory])
- if existing_factories:
- raise TypeError(
- "multiple instrumentation implementations specified "
- "in %s inheritance hierarchy: %r" % (
- class_.__name__, list(existing_factories)))
-
- manager = factory(class_)
- if not isinstance(manager, ClassManager):
- manager = _ClassInstrumentationAdapter(class_, manager)
-
- if factory != ClassManager and not self._extended:
- # somebody invoked a custom ClassManager.
- # reinstall global "getter" functions with the more
- # expensive ones.
- self._extended = True
- _install_lookup_strategy(self)
-
- manager._configure_create_arguments(**kw)
-
- manager.factory = factory
- self._manager_finders[class_] = manager.manager_getter()
- self._state_finders[class_] = manager.state_getter()
- self._dict_finders[class_] = manager.dict_getter()
-
- self.dispatch.class_instrument(class_)
-
- return manager
-
- def _collect_management_factories_for(self, cls):
- """Return a collection of factories in play or specified for a
- hierarchy.
-
- Traverses the entire inheritance graph of a cls and returns a
- collection of instrumentation factories for those classes. Factories
- are extracted from active ClassManagers, if available, otherwise
- instrumentation_finders is consulted.
-
- """
- hierarchy = util.class_hierarchy(cls)
- factories = set()
- for member in hierarchy:
- manager = manager_of_class(member)
- if manager is not None:
- factories.add(manager.factory)
- else:
- for finder in instrumentation_finders:
- factory = finder(member)
- if factory is not None:
- break
- else:
- factory = None
- factories.add(factory)
- factories.discard(None)
- return factories
-
- def manager_of_class(self, cls):
- # this is only called when alternate instrumentation
- # has been established
- if cls is None:
- return None
- try:
- finder = self._manager_finders[cls]
- except KeyError:
- return None
- else:
- return finder(cls)
-
- def state_of(self, instance):
- # this is only called when alternate instrumentation
- # has been established
- if instance is None:
- raise AttributeError("None has no persistent state.")
- try:
- return self._state_finders[instance.__class__](instance)
- except KeyError:
- raise AttributeError("%r is not instrumented" %
- instance.__class__)
-
- def dict_of(self, instance):
- # this is only called when alternate instrumentation
- # has been established
- if instance is None:
- raise AttributeError("None has no persistent state.")
- try:
- return self._dict_finders[instance.__class__](instance)
- except KeyError:
- raise AttributeError("%r is not instrumented" %
- instance.__class__)
-
- def unregister(self, class_):
- if class_ in self._manager_finders:
- manager = self.manager_of_class(class_)
- self.dispatch.class_uninstrument(class_)
- manager.unregister()
- manager.dispose()
- del self._manager_finders[class_]
- del self._state_finders[class_]
- del self._dict_finders[class_]
- if ClassManager.MANAGER_ATTR in class_.__dict__:
- delattr(class_, ClassManager.MANAGER_ATTR)
-
-instrumentation_registry = InstrumentationRegistry()
-
-
-def _install_lookup_strategy(implementation):
- """Replace global class/object management functions
- with either faster or more comprehensive implementations,
- based on whether or not extended class instrumentation
- has been detected.
-
- This function is called only by InstrumentationRegistry()
- and unit tests specific to this behavior.
-
- """
- global instance_state, instance_dict, manager_of_class
- if implementation is util.symbol('native'):
- instance_state = attrgetter(ClassManager.STATE_ATTR)
- instance_dict = attrgetter("__dict__")
- def manager_of_class(cls):
- return cls.__dict__.get(ClassManager.MANAGER_ATTR, None)
- else:
- instance_state = instrumentation_registry.state_of
- instance_dict = instrumentation_registry.dict_of
- manager_of_class = instrumentation_registry.manager_of_class
- attributes.instance_state = instance_state
- attributes.instance_dict = instance_dict
- attributes.manager_of_class = manager_of_class
-
-_create_manager_for_cls = instrumentation_registry.create_manager_for_cls
-
-# Install default "lookup" strategies. These are basically
-# very fast attrgetters for key attributes.
-# When a custom ClassManager is installed, more expensive per-class
-# strategies are copied over these.
-_install_lookup_strategy(util.symbol('native'))
-
-
-def find_native_user_instrumentation_hook(cls):
- """Find user-specified instrumentation management for a class."""
- return getattr(cls, INSTRUMENTATION_MANAGER, None)
-instrumentation_finders.append(find_native_user_instrumentation_hook)
-
-def _generate_init(class_, class_manager):
- """Build an __init__ decorator that triggers ClassManager events."""
-
- # TODO: we should use the ClassManager's notion of the
- # original '__init__' method, once ClassManager is fixed
- # to always reference that.
- original__init__ = class_.__init__
- assert original__init__
-
- # Go through some effort here and don't change the user's __init__
- # calling signature.
- # FIXME: need to juggle local names to avoid constructor argument
- # clashes.
- func_body = """\
-def __init__(%(apply_pos)s):
- new_state = class_manager._new_state_if_none(%(self_arg)s)
- if new_state:
- return new_state.initialize_instance(%(apply_kw)s)
- else:
- return original__init__(%(apply_kw)s)
-"""
- func_vars = util.format_argspec_init(original__init__, grouped=False)
- func_text = func_body % func_vars
-
- # Py3K
- #func_defaults = getattr(original__init__, '__defaults__', None)
- # Py2K
- func = getattr(original__init__, 'im_func', original__init__)
- func_defaults = getattr(func, 'func_defaults', None)
- # end Py2K
-
- env = locals().copy()
- exec func_text in env
- __init__ = env['__init__']
- __init__.__doc__ = original__init__.__doc__
- if func_defaults:
- __init__.func_defaults = func_defaults
- return __init__
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/interfaces.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/interfaces.py
deleted file mode 100755
index 7a874855..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/interfaces.py
+++ /dev/null
@@ -1,754 +0,0 @@
-# orm/interfaces.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""
-
-Contains various base classes used throughout the ORM.
-
-Defines the now deprecated ORM extension classes as well
-as ORM internals.
-
-Other than the deprecated extensions, this module and the
-classes within should be considered mostly private.
-
-"""
-
-from itertools import chain
-
-from sqlalchemy import exc as sa_exc
-from sqlalchemy import util
-from sqlalchemy.sql import expression
-deque = util.importlater('collections').deque
-
-mapperutil = util.importlater('sqlalchemy.orm', 'util')
-
-collections = None
-
-__all__ = (
- 'AttributeExtension',
- 'EXT_CONTINUE',
- 'EXT_STOP',
- 'ExtensionOption',
- 'InstrumentationManager',
- 'LoaderStrategy',
- 'MapperExtension',
- 'MapperOption',
- 'MapperProperty',
- 'PropComparator',
- 'PropertyOption',
- 'SessionExtension',
- 'StrategizedOption',
- 'StrategizedProperty',
- 'build_path',
- )
-
-EXT_CONTINUE = util.symbol('EXT_CONTINUE')
-EXT_STOP = util.symbol('EXT_STOP')
-
-ONETOMANY = util.symbol('ONETOMANY')
-MANYTOONE = util.symbol('MANYTOONE')
-MANYTOMANY = util.symbol('MANYTOMANY')
-
-from deprecated_interfaces import AttributeExtension, SessionExtension, \
- MapperExtension
-
-
-class MapperProperty(object):
- """Manage the relationship of a ``Mapper`` to a single class
- attribute, as well as that attribute as it appears on individual
- instances of the class, including attribute instrumentation,
- attribute access, loading behavior, and dependency calculations.
- """
-
- cascade = ()
- """The set of 'cascade' attribute names.
-
- This collection is checked before the 'cascade_iterator' method is called.
-
- """
-
- def setup(self, context, entity, path, reduced_path, adapter, **kwargs):
- """Called by Query for the purposes of constructing a SQL statement.
-
- Each MapperProperty associated with the target mapper processes the
- statement referenced by the query context, adding columns and/or
- criterion as appropriate.
- """
-
- pass
-
- def create_row_processor(self, selectcontext, path, reduced_path,
- mapper, row, adapter):
- """Return a 3-tuple consisting of three row processing functions.
-
- """
- return None, None, None
-
- def cascade_iterator(self, type_, state, visited_instances=None,
- halt_on=None):
- """Iterate through instances related to the given instance for
- a particular 'cascade', starting with this MapperProperty.
-
- Return an iterator3-tuples (instance, mapper, state).
-
- Note that the 'cascade' collection on this MapperProperty is
- checked first for the given type before cascade_iterator is called.
-
- See PropertyLoader for the related instance implementation.
- """
-
- return iter(())
-
- def set_parent(self, parent, init):
- self.parent = parent
-
- def instrument_class(self, mapper):
- raise NotImplementedError()
-
- _compile_started = False
- _compile_finished = False
-
- def init(self):
- """Called after all mappers are created to assemble
- relationships between mappers and perform other post-mapper-creation
- initialization steps.
-
- """
- self._compile_started = True
- self.do_init()
- self._compile_finished = True
-
- @property
- def class_attribute(self):
- """Return the class-bound descriptor corresponding to this
- MapperProperty."""
-
- return getattr(self.parent.class_, self.key)
-
- def do_init(self):
- """Perform subclass-specific initialization post-mapper-creation
- steps.
-
- This is a template method called by the ``MapperProperty``
- object's init() method.
-
- """
-
- pass
-
- def post_instrument_class(self, mapper):
- """Perform instrumentation adjustments that need to occur
- after init() has completed.
-
- """
- pass
-
- def per_property_preprocessors(self, uow):
- pass
-
- def is_primary(self):
- """Return True if this ``MapperProperty``'s mapper is the
- primary mapper for its class.
-
- This flag is used to indicate that the ``MapperProperty`` can
- define attribute instrumentation for the class at the class
- level (as opposed to the individual instance level).
- """
-
- return not self.parent.non_primary
-
- def merge(self, session, source_state, source_dict, dest_state,
- dest_dict, load, _recursive):
- """Merge the attribute represented by this ``MapperProperty``
- from source to destination object"""
-
- pass
-
- def compare(self, operator, value, **kw):
- """Return a compare operation for the columns represented by
- this ``MapperProperty`` to the given value, which may be a
- column value or an instance. 'operator' is an operator from
- the operators module, or from sql.Comparator.
-
- By default uses the PropComparator attached to this MapperProperty
- under the attribute name "comparator".
- """
-
- return operator(self.comparator, value)
-
-class PropComparator(expression.ColumnOperators):
- """Defines comparison operations for MapperProperty objects.
-
- User-defined subclasses of :class:`.PropComparator` may be created. The
- built-in Python comparison and math operator methods, such as
- ``__eq__()``, ``__lt__()``, ``__add__()``, can be overridden to provide
- new operator behaivor. The custom :class:`.PropComparator` is passed to
- the mapper property via the ``comparator_factory`` argument. In each case,
- the appropriate subclass of :class:`.PropComparator` should be used::
-
- from sqlalchemy.orm.properties import \\
- ColumnProperty,\\
- CompositeProperty,\\
- RelationshipProperty
-
- class MyColumnComparator(ColumnProperty.Comparator):
- pass
-
- class MyCompositeComparator(CompositeProperty.Comparator):
- pass
-
- class MyRelationshipComparator(RelationshipProperty.Comparator):
- pass
-
- """
-
- def __init__(self, prop, mapper, adapter=None):
- self.prop = self.property = prop
- self.mapper = mapper
- self.adapter = adapter
-
- def __clause_element__(self):
- raise NotImplementedError("%r" % self)
-
- def adapted(self, adapter):
- """Return a copy of this PropComparator which will use the given
- adaption function on the local side of generated expressions.
-
- """
-
- return self.__class__(self.prop, self.mapper, adapter)
-
- @staticmethod
- def any_op(a, b, **kwargs):
- return a.any(b, **kwargs)
-
- @staticmethod
- def has_op(a, b, **kwargs):
- return a.has(b, **kwargs)
-
- @staticmethod
- def of_type_op(a, class_):
- return a.of_type(class_)
-
- def of_type(self, class_):
- """Redefine this object in terms of a polymorphic subclass.
-
- Returns a new PropComparator from which further criterion can be
- evaluated.
-
- e.g.::
-
- query.join(Company.employees.of_type(Engineer)).\\
- filter(Engineer.name=='foo')
-
- \class_
- a class or mapper indicating that criterion will be against
- this specific subclass.
-
-
- """
-
- return self.operate(PropComparator.of_type_op, class_)
-
- def any(self, criterion=None, **kwargs):
- """Return true if this collection contains any member that meets the
- given criterion.
-
- criterion
- an optional ClauseElement formulated against the member class' table
- or attributes.
-
- \**kwargs
- key/value pairs corresponding to member class attribute names which
- will be compared via equality to the corresponding values.
- """
-
- return self.operate(PropComparator.any_op, criterion, **kwargs)
-
- def has(self, criterion=None, **kwargs):
- """Return true if this element references a member which meets the
- given criterion.
-
- criterion
- an optional ClauseElement formulated against the member class' table
- or attributes.
-
- \**kwargs
- key/value pairs corresponding to member class attribute names which
- will be compared via equality to the corresponding values.
- """
-
- return self.operate(PropComparator.has_op, criterion, **kwargs)
-
-
-class StrategizedProperty(MapperProperty):
- """A MapperProperty which uses selectable strategies to affect
- loading behavior.
-
- There is a single strategy selected by default. Alternate
- strategies can be selected at Query time through the usage of
- ``StrategizedOption`` objects via the Query.options() method.
-
- """
-
- def _get_context_strategy(self, context, reduced_path):
- key = ('loaderstrategy', reduced_path)
- if key in context.attributes:
- cls = context.attributes[key]
- try:
- return self._strategies[cls]
- except KeyError:
- return self.__init_strategy(cls)
- else:
- return self.strategy
-
- def _get_strategy(self, cls):
- try:
- return self._strategies[cls]
- except KeyError:
- return self.__init_strategy(cls)
-
- def __init_strategy(self, cls):
- self._strategies[cls] = strategy = cls(self)
- strategy.init()
- return strategy
-
- def setup(self, context, entity, path, reduced_path, adapter, **kwargs):
- self._get_context_strategy(context, reduced_path + (self.key,)).\
- setup_query(context, entity, path,
- reduced_path, adapter, **kwargs)
-
- def create_row_processor(self, context, path, reduced_path, mapper, row, adapter):
- return self._get_context_strategy(context, reduced_path + (self.key,)).\
- create_row_processor(context, path,
- reduced_path, mapper, row, adapter)
-
- def do_init(self):
- self._strategies = {}
- self.strategy = self.__init_strategy(self.strategy_class)
-
- def post_instrument_class(self, mapper):
- if self.is_primary() and \
- not mapper.class_manager._attr_has_impl(self.key):
- self.strategy.init_class_attribute(mapper)
-
-def build_path(entity, key, prev=None):
- if prev:
- return prev + (entity, key)
- else:
- return (entity, key)
-
-def serialize_path(path):
- if path is None:
- return None
-
- return zip(
- [m.class_ for m in [path[i] for i in range(0, len(path), 2)]],
- [path[i] for i in range(1, len(path), 2)] + [None]
- )
-
-def deserialize_path(path):
- if path is None:
- return None
-
- p = tuple(chain(*[(mapperutil.class_mapper(cls), key) for cls, key in path]))
- if p and p[-1] is None:
- p = p[0:-1]
- return p
-
-class MapperOption(object):
- """Describe a modification to a Query."""
-
- propagate_to_loaders = False
- """if True, indicate this option should be carried along
- Query object generated by scalar or object lazy loaders.
- """
-
- def process_query(self, query):
- pass
-
- def process_query_conditionally(self, query):
- """same as process_query(), except that this option may not
- apply to the given query.
-
- Used when secondary loaders resend existing options to a new
- Query."""
-
- self.process_query(query)
-
-class PropertyOption(MapperOption):
- """A MapperOption that is applied to a property off the mapper or
- one of its child mappers, identified by a dot-separated key. """
-
- def __init__(self, key, mapper=None):
- self.key = key
- self.mapper = mapper
-
- def process_query(self, query):
- self._process(query, True)
-
- def process_query_conditionally(self, query):
- self._process(query, False)
-
- def _process(self, query, raiseerr):
- paths, mappers = self._get_paths(query, raiseerr)
- if paths:
- self.process_query_property(query, paths, mappers)
-
- def process_query_property(self, query, paths, mappers):
- pass
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['key'] = ret = []
- for token in util.to_list(self.key):
- if isinstance(token, PropComparator):
- ret.append((token.mapper.class_, token.key))
- else:
- ret.append(token)
- return d
-
- def __setstate__(self, state):
- ret = []
- for key in state['key']:
- if isinstance(key, tuple):
- cls, propkey = key
- ret.append(getattr(cls, propkey))
- else:
- ret.append(key)
- state['key'] = tuple(ret)
- self.__dict__ = state
-
- def _find_entity_prop_comparator(self, query, token, mapper, raiseerr):
- if mapperutil._is_aliased_class(mapper):
- searchfor = mapper
- isa = False
- else:
- searchfor = mapperutil._class_to_mapper(mapper)
- isa = True
- for ent in query._mapper_entities:
- if searchfor is ent.path_entity or isa \
- and searchfor.common_parent(ent.path_entity):
- return ent
- else:
- if raiseerr:
- if not list(query._mapper_entities):
- raise sa_exc.ArgumentError(
- "Query has only expression-based entities - "
- "can't find property named '%s'."
- % (token, )
- )
- else:
- raise sa_exc.ArgumentError(
- "Can't find property '%s' on any entity "
- "specified in this Query. Note the full path "
- "from root (%s) to target entity must be specified."
- % (token, ",".join(str(x) for
- x in query._mapper_entities))
- )
- else:
- return None
-
- def _find_entity_basestring(self, query, token, raiseerr):
- for ent in query._mapper_entities:
- # return only the first _MapperEntity when searching
- # based on string prop name. Ideally object
- # attributes are used to specify more exactly.
- return ent
- else:
- if raiseerr:
- raise sa_exc.ArgumentError(
- "Query has only expression-based entities - "
- "can't find property named '%s'."
- % (token, )
- )
- else:
- return None
-
- def _get_paths(self, query, raiseerr):
- path = None
- entity = None
- l = []
- mappers = []
-
- # _current_path implies we're in a
- # secondary load with an existing path
- current_path = list(query._current_path)
-
- tokens = deque(self.key)
- while tokens:
- token = tokens.popleft()
- if isinstance(token, basestring):
- sub_tokens = token.split(".", 1)
- token = sub_tokens[0]
- tokens.extendleft(sub_tokens[1:])
-
- # exhaust current_path before
- # matching tokens to entities
- if current_path:
- if current_path[1] == token:
- current_path = current_path[2:]
- continue
- else:
- return [], []
-
- if not entity:
- entity = self._find_entity_basestring(
- query,
- token,
- raiseerr)
- if entity is None:
- return [], []
- path_element = entity.path_entity
- mapper = entity.mapper
- mappers.append(mapper)
- if mapper.has_property(token):
- prop = mapper.get_property(token)
- else:
- if raiseerr:
- raise sa_exc.ArgumentError(
- "Can't find property named '%s' on the "
- "mapped entity %s in this Query. " % (
- token, mapper)
- )
- else:
- return [], []
- elif isinstance(token, PropComparator):
- prop = token.property
-
- # exhaust current_path before
- # matching tokens to entities
- if current_path:
- if current_path[0:2] == \
- [token.parententity, prop.key]:
- current_path = current_path[2:]
- continue
- else:
- return [], []
-
- if not entity:
- entity = self._find_entity_prop_comparator(
- query,
- prop.key,
- token.parententity,
- raiseerr)
- if not entity:
- return [], []
- path_element = entity.path_entity
- mapper = entity.mapper
- mappers.append(prop.parent)
- else:
- raise sa_exc.ArgumentError(
- "mapper option expects "
- "string key or list of attributes")
- assert prop is not None
- path = build_path(path_element, prop.key, path)
- l.append(path)
- if getattr(token, '_of_type', None):
- path_element = mapper = token._of_type
- else:
- path_element = mapper = getattr(prop, 'mapper', None)
- if mapper is None and tokens:
- raise sa_exc.ArgumentError(
- "Attribute '%s' of entity '%s' does not "
- "refer to a mapped entity" %
- (token, entity)
- )
- if path_element:
- path_element = path_element
-
- if current_path:
- # ran out of tokens before
- # current_path was exhausted.
- assert not tokens
- return [], []
-
- return l, mappers
-
-class StrategizedOption(PropertyOption):
- """A MapperOption that affects which LoaderStrategy will be used
- for an operation by a StrategizedProperty.
- """
-
- chained = False
-
- def process_query_property(self, query, paths, mappers):
-
- # _get_context_strategy may receive the path in terms of a base
- # mapper - e.g. options(eagerload_all(Company.employees,
- # Engineer.machines)) in the polymorphic tests leads to
- # "(Person, 'machines')" in the path due to the mechanics of how
- # the eager strategy builds up the path
-
- if self.chained:
- for path in paths:
- query._attributes[('loaderstrategy',
- _reduce_path(path))] = \
- self.get_strategy_class()
- else:
- query._attributes[('loaderstrategy',
- _reduce_path(paths[-1]))] = \
- self.get_strategy_class()
-
- def get_strategy_class(self):
- raise NotImplementedError()
-
-def _reduce_path(path):
- """Convert a (mapper, path) path to use base mappers.
-
- This is used to allow more open ended selection of loader strategies, i.e.
- Mapper -> prop1 -> Subclass -> prop2, where Subclass is a sub-mapper
- of the mapper referenced by Mapper.prop1.
-
- """
- return tuple([i % 2 != 0 and
- element or
- getattr(element, 'base_mapper', element)
- for i, element in enumerate(path)])
-
-class LoaderStrategy(object):
- """Describe the loading behavior of a StrategizedProperty object.
-
- The ``LoaderStrategy`` interacts with the querying process in three
- ways:
-
- * it controls the configuration of the ``InstrumentedAttribute``
- placed on a class to handle the behavior of the attribute. this
- may involve setting up class-level callable functions to fire
- off a select operation when the attribute is first accessed
- (i.e. a lazy load)
-
- * it processes the ``QueryContext`` at statement construction time,
- where it can modify the SQL statement that is being produced.
- simple column attributes may add their represented column to the
- list of selected columns, *eager loading* properties may add
- ``LEFT OUTER JOIN`` clauses to the statement.
-
- * it processes the ``SelectionContext`` at row-processing time. This
- includes straight population of attributes corresponding to rows,
- setting instance-level lazyloader callables on newly
- constructed instances, and appending child items to scalar/collection
- attributes in response to eagerly-loaded relations.
- """
-
- def __init__(self, parent):
- self.parent_property = parent
- self.is_class_level = False
- self.parent = self.parent_property.parent
- self.key = self.parent_property.key
-
- def init(self):
- raise NotImplementedError("LoaderStrategy")
-
- def init_class_attribute(self, mapper):
- pass
-
- def setup_query(self, context, entity, path, reduced_path, adapter, **kwargs):
- pass
-
- def create_row_processor(self, selectcontext, path, reduced_path, mapper,
- row, adapter):
- """Return row processing functions which fulfill the contract
- specified by MapperProperty.create_row_processor.
-
- StrategizedProperty delegates its create_row_processor method
- directly to this method. """
-
- return None, None, None
-
- def __str__(self):
- return str(self.parent_property)
-
- def debug_callable(self, fn, logger, announcement, logfn):
- if announcement:
- logger.debug(announcement)
- if logfn:
- def call(*args, **kwargs):
- logger.debug(logfn(*args, **kwargs))
- return fn(*args, **kwargs)
- return call
- else:
- return fn
-
-class InstrumentationManager(object):
- """User-defined class instrumentation extension.
-
- :class:`.InstrumentationManager` can be subclassed in order
- to change
- how class instrumentation proceeds. This class exists for
- the purposes of integration with other object management
- frameworks which would like to entirely modify the
- instrumentation methodology of the ORM, and is not intended
- for regular usage. For interception of class instrumentation
- events, see :class:`.InstrumentationEvents`.
-
- For an example of :class:`.InstrumentationManager`, see the
- example :ref:`examples_instrumentation`.
-
- The API for this class should be considered as semi-stable,
- and may change slightly with new releases.
-
- """
-
- # r4361 added a mandatory (cls) constructor to this interface.
- # given that, perhaps class_ should be dropped from all of these
- # signatures.
-
- def __init__(self, class_):
- pass
-
- def manage(self, class_, manager):
- setattr(class_, '_default_class_manager', manager)
-
- def dispose(self, class_, manager):
- delattr(class_, '_default_class_manager')
-
- def manager_getter(self, class_):
- def get(cls):
- return cls._default_class_manager
- return get
-
- def instrument_attribute(self, class_, key, inst):
- pass
-
- def post_configure_attribute(self, class_, key, inst):
- pass
-
- def install_descriptor(self, class_, key, inst):
- setattr(class_, key, inst)
-
- def uninstall_descriptor(self, class_, key):
- delattr(class_, key)
-
- def install_member(self, class_, key, implementation):
- setattr(class_, key, implementation)
-
- def uninstall_member(self, class_, key):
- delattr(class_, key)
-
- def instrument_collection_class(self, class_, key, collection_class):
- global collections
- if collections is None:
- from sqlalchemy.orm import collections
- return collections.prepare_instrumentation(collection_class)
-
- def get_instance_dict(self, class_, instance):
- return instance.__dict__
-
- def initialize_instance_dict(self, class_, instance):
- pass
-
- def install_state(self, class_, instance, state):
- setattr(instance, '_default_state', state)
-
- def remove_state(self, class_, instance):
- delattr(instance, '_default_state')
-
- def state_getter(self, class_):
- return lambda instance: getattr(instance, '_default_state')
-
- def dict_getter(self, class_):
- return lambda inst: self.get_instance_dict(class_, inst)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py
deleted file mode 100755
index a426e28a..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py
+++ /dev/null
@@ -1,2825 +0,0 @@
-# orm/mapper.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Logic to map Python classes to and from selectables.
-
-Defines the :class:`~sqlalchemy.orm.mapper.Mapper` class, the central
-configurational unit which associates a class with a database table.
-
-This is a semi-private module; the main configurational API of the ORM is
-available in :class:`~sqlalchemy.orm.`.
-
-"""
-
-import types
-import weakref
-import operator
-from itertools import chain, groupby
-deque = __import__('collections').deque
-
-from sqlalchemy import sql, util, log, exc as sa_exc, event, schema
-from sqlalchemy.sql import expression, visitors, operators, util as sqlutil
-from sqlalchemy.orm import instrumentation, attributes, sync, \
- exc as orm_exc, unitofwork, events
-from sqlalchemy.orm.interfaces import MapperProperty, EXT_CONTINUE, \
- PropComparator
-
-from sqlalchemy.orm.util import _INSTRUMENTOR, _class_to_mapper, \
- _state_mapper, class_mapper, instance_str, state_str
-
-import sys
-sessionlib = util.importlater("sqlalchemy.orm", "session")
-properties = util.importlater("sqlalchemy.orm", "properties")
-
-__all__ = (
- 'Mapper',
- '_mapper_registry',
- 'class_mapper',
- 'object_mapper',
- )
-
-_mapper_registry = weakref.WeakKeyDictionary()
-_new_mappers = False
-_already_compiling = False
-_none_set = frozenset([None])
-
-_memoized_configured_property = util.group_expirable_memoized_property()
-
-# a constant returned by _get_attr_by_column to indicate
-# this mapper is not handling an attribute for a particular
-# column
-NO_ATTRIBUTE = util.symbol('NO_ATTRIBUTE')
-
-# lock used to synchronize the "mapper compile" step
-_COMPILE_MUTEX = util.threading.RLock()
-
-class Mapper(object):
- """Define the correlation of class attributes to database table
- columns.
-
- Instances of this class should be constructed via the
- :func:`~sqlalchemy.orm.mapper` function.
-
- """
- def __init__(self,
- class_,
- local_table,
- properties = None,
- primary_key = None,
- non_primary = False,
- inherits = None,
- inherit_condition = None,
- inherit_foreign_keys = None,
- extension = None,
- order_by = False,
- always_refresh = False,
- version_id_col = None,
- version_id_generator = None,
- polymorphic_on=None,
- _polymorphic_map=None,
- polymorphic_identity=None,
- concrete=False,
- with_polymorphic=None,
- allow_null_pks=None,
- allow_partial_pks=True,
- batch=True,
- column_prefix=None,
- include_properties=None,
- exclude_properties=None,
- passive_updates=True,
- eager_defaults=False,
- _compiled_cache_size=100,
- ):
- """Construct a new mapper.
-
- Mappers are normally constructed via the
- :func:`~sqlalchemy.orm.mapper` function. See for details.
-
- """
-
- self.class_ = util.assert_arg_type(class_, type, 'class_')
-
- self.class_manager = None
-
- self._primary_key_argument = util.to_list(primary_key)
- self.non_primary = non_primary
-
- if order_by is not False:
- self.order_by = util.to_list(order_by)
- else:
- self.order_by = order_by
-
- self.always_refresh = always_refresh
- self.version_id_col = version_id_col
- self.version_id_generator = version_id_generator or \
- (lambda x:(x or 0) + 1)
- self.concrete = concrete
- self.single = False
- self.inherits = inherits
- self.local_table = local_table
- self.inherit_condition = inherit_condition
- self.inherit_foreign_keys = inherit_foreign_keys
- self._init_properties = properties or {}
- self.delete_orphans = []
- self.batch = batch
- self.eager_defaults = eager_defaults
- self.column_prefix = column_prefix
- self.polymorphic_on = polymorphic_on
- self._dependency_processors = []
- self._validators = {}
- self.passive_updates = passive_updates
- self._clause_adapter = None
- self._requires_row_aliasing = False
- self._inherits_equated_pairs = None
- self._memoized_values = {}
- self._compiled_cache_size = _compiled_cache_size
- self._reconstructor = None
- self._deprecated_extensions = util.to_list(extension or [])
-
- if allow_null_pks:
- util.warn_deprecated(
- "the allow_null_pks option to Mapper() is "
- "deprecated. It is now allow_partial_pks=False|True, "
- "defaults to True.")
- allow_partial_pks = allow_null_pks
-
- self.allow_partial_pks = allow_partial_pks
-
- if with_polymorphic == '*':
- self.with_polymorphic = ('*', None)
- elif isinstance(with_polymorphic, (tuple, list)):
- if isinstance(with_polymorphic[0], (basestring, tuple, list)):
- self.with_polymorphic = with_polymorphic
- else:
- self.with_polymorphic = (with_polymorphic, None)
- elif with_polymorphic is not None:
- raise sa_exc.ArgumentError("Invalid setting for with_polymorphic")
- else:
- self.with_polymorphic = None
-
- if isinstance(self.local_table, expression._SelectBase):
- raise sa_exc.InvalidRequestError(
- "When mapping against a select() construct, map against "
- "an alias() of the construct instead."
- "This because several databases don't allow a "
- "SELECT from a subquery that does not have an alias."
- )
-
- if self.with_polymorphic and \
- isinstance(self.with_polymorphic[1],
- expression._SelectBase):
- self.with_polymorphic = (self.with_polymorphic[0],
- self.with_polymorphic[1].alias())
-
- # our 'polymorphic identity', a string name that when located in a
- # result set row indicates this Mapper should be used to construct
- # the object instance for that row.
- self.polymorphic_identity = polymorphic_identity
-
- # a dictionary of 'polymorphic identity' names, associating those
- # names with Mappers that will be used to construct object instances
- # upon a select operation.
- if _polymorphic_map is None:
- self.polymorphic_map = {}
- else:
- self.polymorphic_map = _polymorphic_map
-
- if include_properties is not None:
- self.include_properties = util.to_set(include_properties)
- else:
- self.include_properties = None
- if exclude_properties:
- self.exclude_properties = util.to_set(exclude_properties)
- else:
- self.exclude_properties = None
-
- self.configured = False
-
- # prevent this mapper from being constructed
- # while a configure_mappers() is occurring (and defer a configure_mappers()
- # until construction succeeds)
- _COMPILE_MUTEX.acquire()
- try:
- self._configure_inheritance()
- self._configure_legacy_instrument_class()
- self._configure_class_instrumentation()
- self._configure_listeners()
- self._configure_properties()
- self._configure_polymorphic_setter()
- self._configure_pks()
- global _new_mappers
- _new_mappers = True
- self._log("constructed")
- self._expire_memoizations()
- finally:
- _COMPILE_MUTEX.release()
-
- # major attributes initialized at the classlevel so that
- # they can be Sphinx-documented.
-
- local_table = None
- """The :class:`.Selectable` which this :class:`.Mapper` manages.
-
- Typically is an instance of :class:`.Table` or :class:`.Alias`.
- May also be ``None``.
-
- The "local" table is the
- selectable that the :class:`.Mapper` is directly responsible for
- managing from an attribute access and flush perspective. For
- non-inheriting mappers, the local table is the same as the
- "mapped" table. For joined-table inheritance mappers, local_table
- will be the particular sub-table of the overall "join" which
- this :class:`.Mapper` represents. If this mapper is a
- single-table inheriting mapper, local_table will be ``None``.
-
- See also :attr:`~.Mapper.mapped_table`.
-
- """
-
- mapped_table = None
- """The :class:`.Selectable` to which this :class:`.Mapper` is mapped.
-
- Typically an instance of :class:`.Table`, :class:`.Join`, or
- :class:`.Alias`.
-
- The "mapped" table is the selectable that
- the mapper selects from during queries. For non-inheriting
- mappers, the mapped table is the same as the "local" table.
- For joined-table inheritance mappers, mapped_table references the
- full :class:`.Join` representing full rows for this particular
- subclass. For single-table inheritance mappers, mapped_table
- references the base table.
-
- See also :attr:`~.Mapper.local_table`.
-
- """
-
- inherits = None
- """References the :class:`.Mapper` which this :class:`.Mapper`
- inherits from, if any.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- configured = None
- """Represent ``True`` if this :class:`.Mapper` has been configured.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- See also :func:`.configure_mappers`.
-
- """
-
- concrete = None
- """Represent ``True`` if this :class:`.Mapper` is a concrete
- inheritance mapper.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- tables = None
- """An iterable containing the collection of :class:`.Table` objects
- which this :class:`.Mapper` is aware of.
-
- If the mapper is mapped to a :class:`.Join`, or an :class:`.Alias`
- representing a :class:`.Select`, the individual :class:`.Table`
- objects that comprise the full construct will be represented here.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- primary_key = None
- """An iterable containing the collection of :class:`.Column` objects
- which comprise the 'primary key' of the mapped table, from the
- perspective of this :class:`.Mapper`.
-
- This list is against the selectable in :attr:`~.Mapper.mapped_table`. In the
- case of inheriting mappers, some columns may be managed by a superclass
- mapper. For example, in the case of a :class:`.Join`, the primary
- key is determined by all of the primary key columns across all tables
- referenced by the :class:`.Join`.
-
- The list is also not necessarily the same as the primary key column
- collection associated with the underlying tables; the :class:`.Mapper`
- features a ``primary_key`` argument that can override what the
- :class:`.Mapper` considers as primary key columns.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- class_ = None
- """The Python class which this :class:`.Mapper` maps.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- class_manager = None
- """The :class:`.ClassManager` which maintains event listeners
- and class-bound descriptors for this :class:`.Mapper`.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- single = None
- """Represent ``True`` if this :class:`.Mapper` is a single table
- inheritance mapper.
-
- :attr:`~.Mapper.local_table` will be ``None`` if this flag is set.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- non_primary = None
- """Represent ``True`` if this :class:`.Mapper` is a "non-primary"
- mapper, e.g. a mapper that is used only to selet rows but not for
- persistence management.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- polymorphic_on = None
- """The :class:`.Column` specified as the ``polymorphic_on`` column
- for this :class:`.Mapper`, within an inheritance scenario.
-
- This attribute may also be of other types besides :class:`.Column`
- in a future SQLAlchemy release.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- polymorphic_map = None
- """A mapping of "polymorphic identity" identifiers mapped to :class:`.Mapper`
- instances, within an inheritance scenario.
-
- The identifiers can be of any type which is comparable to the
- type of column represented by :attr:`~.Mapper.polymorphic_on`.
-
- An inheritance chain of mappers will all reference the same
- polymorphic map object. The object is used to correlate incoming
- result rows to target mappers.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- polymorphic_identity = None
- """Represent an identifier which is matched against the :attr:`~.Mapper.polymorphic_on`
- column during result row loading.
-
- Used only with inheritance, this object can be of any type which is
- comparable to the type of column represented by :attr:`~.Mapper.polymorphic_on`.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- base_mapper = None
- """The base-most :class:`.Mapper` in an inheritance chain.
-
- In a non-inheriting scenario, this attribute will always be this
- :class:`.Mapper`. In an inheritance scenario, it references
- the :class:`.Mapper` which is parent to all other :class:`.Mapper`
- objects in the inheritance chain.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- columns = None
- """A collection of :class:`.Column` or other scalar expression
- objects maintained by this :class:`.Mapper`.
-
- The collection behaves the same as that of the ``c`` attribute on
- any :class:`.Table` object, except that only those columns included in
- this mapping are present, and are keyed based on the attribute name
- defined in the mapping, not necessarily the ``key`` attribute of the
- :class:`.Column` itself. Additionally, scalar expressions mapped
- by :func:`.column_property` are also present here.
-
- This is a *read only* attribute determined during mapper construction.
- Behavior is undefined if directly modified.
-
- """
-
- c = None
- """A synonym for :attr:`~.Mapper.columns`."""
-
- dispatch = event.dispatcher(events.MapperEvents)
-
- def _configure_inheritance(self):
- """Configure settings related to inherting and/or inherited mappers
- being present."""
-
- # a set of all mappers which inherit from this one.
- self._inheriting_mappers = set()
-
- if self.inherits:
- if isinstance(self.inherits, type):
- self.inherits = class_mapper(self.inherits, compile=False)
- if not issubclass(self.class_, self.inherits.class_):
- raise sa_exc.ArgumentError(
- "Class '%s' does not inherit from '%s'" %
- (self.class_.__name__, self.inherits.class_.__name__))
- if self.non_primary != self.inherits.non_primary:
- np = not self.non_primary and "primary" or "non-primary"
- raise sa_exc.ArgumentError(
- "Inheritance of %s mapper for class '%s' is "
- "only allowed from a %s mapper" %
- (np, self.class_.__name__, np))
- # inherit_condition is optional.
- if self.local_table is None:
- self.local_table = self.inherits.local_table
- self.mapped_table = self.inherits.mapped_table
- self.single = True
- elif not self.local_table is self.inherits.local_table:
- if self.concrete:
- self.mapped_table = self.local_table
- for mapper in self.iterate_to_root():
- if mapper.polymorphic_on is not None:
- mapper._requires_row_aliasing = True
- else:
- if self.inherit_condition is None:
- # figure out inherit condition from our table to the
- # immediate table of the inherited mapper, not its
- # full table which could pull in other stuff we dont
- # want (allows test/inheritance.InheritTest4 to pass)
- self.inherit_condition = sqlutil.join_condition(
- self.inherits.local_table,
- self.local_table)
- self.mapped_table = sql.join(
- self.inherits.mapped_table,
- self.local_table,
- self.inherit_condition)
-
- fks = util.to_set(self.inherit_foreign_keys)
- self._inherits_equated_pairs = sqlutil.criterion_as_pairs(
- self.mapped_table.onclause,
- consider_as_foreign_keys=fks)
- else:
- self.mapped_table = self.local_table
-
- if self.polymorphic_identity is not None and not self.concrete:
- self._identity_class = self.inherits._identity_class
- else:
- self._identity_class = self.class_
-
- if self.version_id_col is None:
- self.version_id_col = self.inherits.version_id_col
- self.version_id_generator = self.inherits.version_id_generator
- elif self.inherits.version_id_col is not None and \
- self.version_id_col is not self.inherits.version_id_col:
- util.warn(
- "Inheriting version_id_col '%s' does not match inherited "
- "version_id_col '%s' and will not automatically populate "
- "the inherited versioning column. "
- "version_id_col should only be specified on "
- "the base-most mapper that includes versioning." %
- (self.version_id_col.description,
- self.inherits.version_id_col.description)
- )
-
- if self.order_by is False and \
- not self.concrete and \
- self.inherits.order_by is not False:
- self.order_by = self.inherits.order_by
-
- self.polymorphic_map = self.inherits.polymorphic_map
- self.batch = self.inherits.batch
- self.inherits._inheriting_mappers.add(self)
- self.base_mapper = self.inherits.base_mapper
- self.passive_updates = self.inherits.passive_updates
- self._all_tables = self.inherits._all_tables
-
- if self.polymorphic_identity is not None:
- self.polymorphic_map[self.polymorphic_identity] = self
-
- if self.polymorphic_on is None:
- for mapper in self.iterate_to_root():
- # try to set up polymorphic on using
- # correesponding_column(); else leave
- # as None
- if mapper.polymorphic_on is not None:
- self.polymorphic_on = \
- self.mapped_table.corresponding_column(
- mapper.polymorphic_on)
- break
- else:
- self._all_tables = set()
- self.base_mapper = self
- self.mapped_table = self.local_table
- if self.polymorphic_identity is not None:
- self.polymorphic_map[self.polymorphic_identity] = self
- self._identity_class = self.class_
-
- if self.mapped_table is None:
- raise sa_exc.ArgumentError(
- "Mapper '%s' does not have a mapped_table specified."
- % self)
-
- def _configure_legacy_instrument_class(self):
-
- if self.inherits:
- self.dispatch._update(self.inherits.dispatch)
- super_extensions = set(chain(*[m._deprecated_extensions
- for m in self.inherits.iterate_to_root()]))
- else:
- super_extensions = set()
-
- for ext in self._deprecated_extensions:
- if ext not in super_extensions:
- ext._adapt_instrument_class(self, ext)
-
- def _configure_listeners(self):
- if self.inherits:
- super_extensions = set(chain(*[m._deprecated_extensions
- for m in self.inherits.iterate_to_root()]))
- else:
- super_extensions = set()
-
- for ext in self._deprecated_extensions:
- if ext not in super_extensions:
- ext._adapt_listener(self, ext)
-
- if self.inherits:
- self.class_manager.dispatch._update(
- self.inherits.class_manager.dispatch)
-
- def _configure_class_instrumentation(self):
- """If this mapper is to be a primary mapper (i.e. the
- non_primary flag is not set), associate this Mapper with the
- given class_ and entity name.
-
- Subsequent calls to ``class_mapper()`` for the class_/entity
- name combination will return this mapper. Also decorate the
- `__init__` method on the mapped class to include optional
- auto-session attachment logic.
-
- """
- manager = attributes.manager_of_class(self.class_)
-
- if self.non_primary:
- if not manager or not manager.is_mapped:
- raise sa_exc.InvalidRequestError(
- "Class %s has no primary mapper configured. Configure "
- "a primary mapper first before setting up a non primary "
- "Mapper." % self.class_)
- self.class_manager = manager
- self._identity_class = manager.mapper._identity_class
- _mapper_registry[self] = True
- return
-
- if manager is not None:
- assert manager.class_ is self.class_
- if manager.is_mapped:
- raise sa_exc.ArgumentError(
- "Class '%s' already has a primary mapper defined. "
- "Use non_primary=True to "
- "create a non primary Mapper. clear_mappers() will "
- "remove *all* current mappers from all classes." %
- self.class_)
- #else:
- # a ClassManager may already exist as
- # ClassManager.instrument_attribute() creates
- # new managers for each subclass if they don't yet exist.
-
- _mapper_registry[self] = True
-
- self.dispatch.instrument_class(self, self.class_)
-
- if manager is None:
- manager = instrumentation.register_class(self.class_,
- deferred_scalar_loader = _load_scalar_attributes
- )
-
- self.class_manager = manager
-
- manager.mapper = self
-
- # The remaining members can be added by any mapper,
- # e_name None or not.
- if manager.info.get(_INSTRUMENTOR, False):
- return
-
- event.listen(manager, 'first_init', _event_on_first_init, raw=True)
- event.listen(manager, 'init', _event_on_init, raw=True)
- event.listen(manager, 'resurrect', _event_on_resurrect, raw=True)
-
- for key, method in util.iterate_attributes(self.class_):
- if isinstance(method, types.FunctionType):
- if hasattr(method, '__sa_reconstructor__'):
- self._reconstructor = method
- event.listen(manager, 'load', _event_on_load, raw=True)
- elif hasattr(method, '__sa_validators__'):
- for name in method.__sa_validators__:
- self._validators[name] = method
-
- manager.info[_INSTRUMENTOR] = self
-
- @util.deprecated("0.7", message=":meth:`.Mapper.compile` "
- "is replaced by :func:`.configure_mappers`")
- def compile(self):
- """Initialize the inter-mapper relationships of all mappers that
- have been constructed thus far.
-
- """
- configure_mappers()
- return self
-
-
- @property
- @util.deprecated("0.7", message=":attr:`.Mapper.compiled` "
- "is replaced by :attr:`.Mapper.configured`")
- def compiled(self):
- return self.configured
-
- def dispose(self):
- # Disable any attribute-based compilation.
- self.configured = True
-
- if hasattr(self, '_configure_failed'):
- del self._configure_failed
-
- if not self.non_primary and \
- self.class_manager.is_mapped and \
- self.class_manager.mapper is self:
- instrumentation.unregister_class(self.class_)
-
- def _configure_pks(self):
-
- self.tables = sqlutil.find_tables(self.mapped_table)
-
- self._pks_by_table = {}
- self._cols_by_table = {}
-
- all_cols = util.column_set(chain(*[
- col.proxy_set for col in
- self._columntoproperty]))
-
- pk_cols = util.column_set(c for c in all_cols if c.primary_key)
-
- # identify primary key columns which are also mapped by this mapper.
- tables = set(self.tables + [self.mapped_table])
- self._all_tables.update(tables)
- for t in tables:
- if t.primary_key and pk_cols.issuperset(t.primary_key):
- # ordering is important since it determines the ordering of
- # mapper.primary_key (and therefore query.get())
- self._pks_by_table[t] =\
- util.ordered_column_set(t.primary_key).\
- intersection(pk_cols)
- self._cols_by_table[t] = \
- util.ordered_column_set(t.c).\
- intersection(all_cols)
-
- # determine cols that aren't expressed within our tables; mark these
- # as "read only" properties which are refreshed upon INSERT/UPDATE
- self._readonly_props = set(
- self._columntoproperty[col]
- for col in self._columntoproperty
- if not hasattr(col, 'table') or
- col.table not in self._cols_by_table)
-
- # if explicit PK argument sent, add those columns to the
- # primary key mappings
- if self._primary_key_argument:
- for k in self._primary_key_argument:
- if k.table not in self._pks_by_table:
- self._pks_by_table[k.table] = util.OrderedSet()
- self._pks_by_table[k.table].add(k)
-
- # otherwise, see that we got a full PK for the mapped table
- elif self.mapped_table not in self._pks_by_table or \
- len(self._pks_by_table[self.mapped_table]) == 0:
- raise sa_exc.ArgumentError(
- "Mapper %s could not assemble any primary "
- "key columns for mapped table '%s'" %
- (self, self.mapped_table.description))
- elif self.local_table not in self._pks_by_table and \
- isinstance(self.local_table, schema.Table):
- util.warn("Could not assemble any primary "
- "keys for locally mapped table '%s' - "
- "no rows will be persisted in this Table."
- % self.local_table.description)
-
- if self.inherits and \
- not self.concrete and \
- not self._primary_key_argument:
- # if inheriting, the "primary key" for this mapper is
- # that of the inheriting (unless concrete or explicit)
- self.primary_key = self.inherits.primary_key
- else:
- # determine primary key from argument or mapped_table pks -
- # reduce to the minimal set of columns
- if self._primary_key_argument:
- primary_key = sqlutil.reduce_columns(
- [self.mapped_table.corresponding_column(c) for c in
- self._primary_key_argument],
- ignore_nonexistent_tables=True)
- else:
- primary_key = sqlutil.reduce_columns(
- self._pks_by_table[self.mapped_table],
- ignore_nonexistent_tables=True)
-
- if len(primary_key) == 0:
- raise sa_exc.ArgumentError(
- "Mapper %s could not assemble any primary "
- "key columns for mapped table '%s'" %
- (self, self.mapped_table.description))
-
- self.primary_key = tuple(primary_key)
- self._log("Identified primary key columns: %s", primary_key)
-
- def _configure_properties(self):
-
- # Column and other ClauseElement objects which are mapped
- self.columns = self.c = util.OrderedProperties()
-
- # object attribute names mapped to MapperProperty objects
- self._props = util.OrderedDict()
-
- # table columns mapped to lists of MapperProperty objects
- # using a list allows a single column to be defined as
- # populating multiple object attributes
- self._columntoproperty = _ColumnMapping(self)
-
- # load custom properties
- if self._init_properties:
- for key, prop in self._init_properties.iteritems():
- self._configure_property(key, prop, False)
-
- # pull properties from the inherited mapper if any.
- if self.inherits:
- for key, prop in self.inherits._props.iteritems():
- if key not in self._props and \
- not self._should_exclude(key, key, local=False, column=None):
- self._adapt_inherited_property(key, prop, False)
-
- # create properties for each column in the mapped table,
- # for those columns which don't already map to a property
- for column in self.mapped_table.columns:
- if column in self._columntoproperty:
- continue
-
- column_key = (self.column_prefix or '') + column.key
-
- if self._should_exclude(
- column.key, column_key,
- local=self.local_table.c.contains_column(column),
- column=column
- ):
- continue
-
- # adjust the "key" used for this column to that
- # of the inheriting mapper
- for mapper in self.iterate_to_root():
- if column in mapper._columntoproperty:
- column_key = mapper._columntoproperty[column].key
-
- self._configure_property(column_key,
- column,
- init=False,
- setparent=True)
-
- def _configure_polymorphic_setter(self):
- """Configure an attribute on the mapper representing the
- 'polymorphic_on' column, if applicable, and not
- already generated by _configure_properties (which is typical).
-
- Also create a setter function which will assign this
- attribute to the value of the 'polymorphic_identity'
- upon instance construction, also if applicable. This
- routine will run when an instance is created.
-
- """
- # do a special check for the "discriminiator" column, as it
- # may only be present in the 'with_polymorphic' selectable
- # but we need it for the base mapper
- setter = False
-
- if self.polymorphic_on is not None:
- setter = True
-
- if self.polymorphic_on not in self._columntoproperty:
- col = self.mapped_table.corresponding_column(self.polymorphic_on)
- if col is None:
- setter = False
- instrument = False
- col = self.polymorphic_on
- if self.with_polymorphic is None \
- or self.with_polymorphic[1].corresponding_column(col) \
- is None:
- raise sa_exc.InvalidRequestError("Could not map polymorphic_on column "
- "'%s' to the mapped table - polymorphic "
- "loads will not function properly"
- % col.description)
- else:
- instrument = True
-
- if self._should_exclude(col.key, col.key, False, col):
- raise sa_exc.InvalidRequestError(
- "Cannot exclude or override the discriminator column %r" %
- col.key)
-
- self._configure_property(
- col.key,
- properties.ColumnProperty(col, _instrument=instrument),
- init=False, setparent=True)
- polymorphic_key = col.key
- else:
- polymorphic_key = self._columntoproperty[self.polymorphic_on].key
-
- if setter:
- def _set_polymorphic_identity(state):
- dict_ = state.dict
- state.get_impl(polymorphic_key).set(state, dict_,
- self.polymorphic_identity, None)
-
- self._set_polymorphic_identity = _set_polymorphic_identity
- else:
- self._set_polymorphic_identity = None
-
-
-
- def _adapt_inherited_property(self, key, prop, init):
- if not self.concrete:
- self._configure_property(key, prop, init=False, setparent=False)
- elif key not in self._props:
- self._configure_property(
- key,
- properties.ConcreteInheritedProperty(),
- init=init, setparent=True)
-
- def _configure_property(self, key, prop, init=True, setparent=True):
- self._log("_configure_property(%s, %s)", key, prop.__class__.__name__)
-
- if not isinstance(prop, MapperProperty):
- # we were passed a Column or a list of Columns;
- # generate a properties.ColumnProperty
- columns = util.to_list(prop)
- column = columns[0]
- if not expression.is_column(column):
- raise sa_exc.ArgumentError(
- "%s=%r is not an instance of MapperProperty or Column"
- % (key, prop))
-
- prop = self._props.get(key, None)
-
- if isinstance(prop, properties.ColumnProperty):
- if prop.parent is self:
- raise sa_exc.InvalidRequestError(
- "Implicitly combining column %s with column "
- "%s under attribute '%s'. Please configure one "
- "or more attributes for these same-named columns "
- "explicitly."
- % (prop.columns[-1], column, key))
-
- # existing properties.ColumnProperty from an inheriting
- # mapper. make a copy and append our column to it
- prop = prop.copy()
- prop.columns.insert(0, column)
- self._log("inserting column to existing list "
- "in properties.ColumnProperty %s" % (key))
-
- elif prop is None or isinstance(prop, properties.ConcreteInheritedProperty):
- mapped_column = []
- for c in columns:
- mc = self.mapped_table.corresponding_column(c)
- if mc is None:
- mc = self.local_table.corresponding_column(c)
- if mc is not None:
- # if the column is in the local table but not the
- # mapped table, this corresponds to adding a
- # column after the fact to the local table.
- # [ticket:1523]
- self.mapped_table._reset_exported()
- mc = self.mapped_table.corresponding_column(c)
- if mc is None:
- raise sa_exc.ArgumentError(
- "When configuring property '%s' on %s, "
- "column '%s' is not represented in the mapper's "
- "table. Use the `column_property()` function to "
- "force this column to be mapped as a read-only "
- "attribute." % (key, self, c))
- mapped_column.append(mc)
- prop = properties.ColumnProperty(*mapped_column)
- else:
- raise sa_exc.ArgumentError(
- "WARNING: when configuring property '%s' on %s, "
- "column '%s' conflicts with property '%r'. "
- "To resolve this, map the column to the class under a "
- "different name in the 'properties' dictionary. Or, "
- "to remove all awareness of the column entirely "
- "(including its availability as a foreign key), "
- "use the 'include_properties' or 'exclude_properties' "
- "mapper arguments to control specifically which table "
- "columns get mapped." %
- (key, self, column.key, prop))
-
- if isinstance(prop, properties.ColumnProperty):
- col = self.mapped_table.corresponding_column(prop.columns[0])
-
- # if the column is not present in the mapped table,
- # test if a column has been added after the fact to the
- # parent table (or their parent, etc.) [ticket:1570]
- if col is None and self.inherits:
- path = [self]
- for m in self.inherits.iterate_to_root():
- col = m.local_table.corresponding_column(prop.columns[0])
- if col is not None:
- for m2 in path:
- m2.mapped_table._reset_exported()
- col = self.mapped_table.corresponding_column(
- prop.columns[0])
- break
- path.append(m)
-
- # subquery expression, column not present in the mapped
- # selectable.
- if col is None:
- col = prop.columns[0]
-
- # column is coming in after _readonly_props was
- # initialized; check for 'readonly'
- if hasattr(self, '_readonly_props') and \
- (not hasattr(col, 'table') or
- col.table not in self._cols_by_table):
- self._readonly_props.add(prop)
-
- else:
- # if column is coming in after _cols_by_table was
- # initialized, ensure the col is in the right set
- if hasattr(self, '_cols_by_table') and \
- col.table in self._cols_by_table and \
- col not in self._cols_by_table[col.table]:
- self._cols_by_table[col.table].add(col)
-
- # if this properties.ColumnProperty represents the "polymorphic
- # discriminator" column, mark it. We'll need this when rendering
- # columns in SELECT statements.
- if not hasattr(prop, '_is_polymorphic_discriminator'):
- prop._is_polymorphic_discriminator = \
- (col is self.polymorphic_on or
- prop.columns[0] is self.polymorphic_on)
-
- self.columns[key] = col
- for col in prop.columns:
- for col in col.proxy_set:
- self._columntoproperty[col] = prop
-
- prop.key = key
-
- if setparent:
- prop.set_parent(self, init)
-
- if key in self._props and \
- getattr(self._props[key], '_mapped_by_synonym', False):
- syn = self._props[key]._mapped_by_synonym
- raise sa_exc.ArgumentError(
- "Can't call map_column=True for synonym %r=%r, "
- "a ColumnProperty already exists keyed to the name "
- "%r for column %r" % (syn, key, key, syn)
- )
-
- self._props[key] = prop
-
- if not self.non_primary:
- prop.instrument_class(self)
-
- for mapper in self._inheriting_mappers:
- mapper._adapt_inherited_property(key, prop, init)
-
- if init:
- prop.init()
- prop.post_instrument_class(self)
-
-
- def _post_configure_properties(self):
- """Call the ``init()`` method on all ``MapperProperties``
- attached to this mapper.
-
- This is a deferred configuration step which is intended
- to execute once all mappers have been constructed.
-
- """
-
- self._log("_post_configure_properties() started")
- l = [(key, prop) for key, prop in self._props.iteritems()]
- for key, prop in l:
- self._log("initialize prop %s", key)
-
- if prop.parent is self and not prop._compile_started:
- prop.init()
-
- if prop._compile_finished:
- prop.post_instrument_class(self)
-
- self._log("_post_configure_properties() complete")
- self.configured = True
-
- def add_properties(self, dict_of_properties):
- """Add the given dictionary of properties to this mapper,
- using `add_property`.
-
- """
- for key, value in dict_of_properties.iteritems():
- self.add_property(key, value)
-
- def add_property(self, key, prop):
- """Add an individual MapperProperty to this mapper.
-
- If the mapper has not been configured yet, just adds the
- property to the initial properties dictionary sent to the
- constructor. If this Mapper has already been configured, then
- the given MapperProperty is configured immediately.
-
- """
- self._init_properties[key] = prop
- self._configure_property(key, prop, init=self.configured)
- self._expire_memoizations()
-
- def _expire_memoizations(self):
- for mapper in self.iterate_to_root():
- _memoized_configured_property.expire_instance(mapper)
-
- @property
- def _log_desc(self):
- return "(" + self.class_.__name__ + \
- "|" + \
- (self.local_table is not None and
- self.local_table.description or
- str(self.local_table)) +\
- (self.non_primary and
- "|non-primary" or "") + ")"
-
- def _log(self, msg, *args):
-
- self.logger.info(
- "%s " + msg, *((self._log_desc,) + args)
- )
-
- def _log_debug(self, msg, *args):
- self.logger.debug(
- "%s " + msg, *((self._log_desc,) + args)
- )
-
- def __repr__(self):
- return '<Mapper at 0x%x; %s>' % (
- id(self), self.class_.__name__)
-
- def __str__(self):
- return "Mapper|%s|%s%s" % (
- self.class_.__name__,
- self.local_table is not None and
- self.local_table.description or None,
- self.non_primary and "|non-primary" or ""
- )
-
- def _is_orphan(self, state):
- o = False
- for mapper in self.iterate_to_root():
- for (key, cls) in mapper.delete_orphans:
- if attributes.manager_of_class(cls).has_parent(
- state, key, optimistic=bool(state.key)):
- return False
- o = o or bool(mapper.delete_orphans)
- return o
-
- def has_property(self, key):
- return key in self._props
-
- def get_property(self, key, _compile_mappers=True):
- """return a MapperProperty associated with the given key.
- """
-
- if _compile_mappers and _new_mappers:
- configure_mappers()
-
- try:
- return self._props[key]
- except KeyError:
- raise sa_exc.InvalidRequestError(
- "Mapper '%s' has no property '%s'" % (self, key))
-
- @util.deprecated('0.6.4',
- 'Call to deprecated function mapper._get_col_to_pr'
- 'op(). Use mapper.get_property_by_column()')
- def _get_col_to_prop(self, col):
- return self._columntoproperty[col]
-
- def get_property_by_column(self, column):
- """Given a :class:`.Column` object, return the
- :class:`.MapperProperty` which maps this column."""
-
- return self._columntoproperty[column]
-
- @property
- def iterate_properties(self):
- """return an iterator of all MapperProperty objects."""
- if _new_mappers:
- configure_mappers()
- return self._props.itervalues()
-
- def _mappers_from_spec(self, spec, selectable):
- """given a with_polymorphic() argument, return the set of mappers it
- represents.
-
- Trims the list of mappers to just those represented within the given
- selectable, if present. This helps some more legacy-ish mappings.
-
- """
- if spec == '*':
- mappers = list(self.self_and_descendants)
- elif spec:
- mappers = [_class_to_mapper(m) for m in util.to_list(spec)]
- for m in mappers:
- if not m.isa(self):
- raise sa_exc.InvalidRequestError(
- "%r does not inherit from %r" %
- (m, self))
- else:
- mappers = []
-
- if selectable is not None:
- tables = set(sqlutil.find_tables(selectable,
- include_aliases=True))
- mappers = [m for m in mappers if m.local_table in tables]
-
- return mappers
-
- def _selectable_from_mappers(self, mappers):
- """given a list of mappers (assumed to be within this mapper's
- inheritance hierarchy), construct an outerjoin amongst those mapper's
- mapped tables.
-
- """
-
- from_obj = self.mapped_table
- for m in mappers:
- if m is self:
- continue
- if m.concrete:
- raise sa_exc.InvalidRequestError(
- "'with_polymorphic()' requires 'selectable' argument "
- "when concrete-inheriting mappers are used.")
- elif not m.single:
- from_obj = from_obj.outerjoin(m.local_table,
- m.inherit_condition)
-
- return from_obj
-
- @_memoized_configured_property
- def _single_table_criterion(self):
- if self.single and \
- self.inherits and \
- self.polymorphic_on is not None:
- return self.polymorphic_on.in_(
- m.polymorphic_identity
- for m in self.self_and_descendants)
- else:
- return None
-
- @_memoized_configured_property
- def _with_polymorphic_mappers(self):
- if not self.with_polymorphic:
- return [self]
- return self._mappers_from_spec(*self.with_polymorphic)
-
- @_memoized_configured_property
- def _with_polymorphic_selectable(self):
- if not self.with_polymorphic:
- return self.mapped_table
-
- spec, selectable = self.with_polymorphic
- if selectable is not None:
- return selectable
- else:
- return self._selectable_from_mappers(
- self._mappers_from_spec(spec, selectable))
-
- def _with_polymorphic_args(self, spec=None, selectable=False):
- if self.with_polymorphic:
- if not spec:
- spec = self.with_polymorphic[0]
- if selectable is False:
- selectable = self.with_polymorphic[1]
-
- mappers = self._mappers_from_spec(spec, selectable)
- if selectable is not None:
- return mappers, selectable
- else:
- return mappers, self._selectable_from_mappers(mappers)
-
- @_memoized_configured_property
- def _polymorphic_properties(self):
- return tuple(self._iterate_polymorphic_properties(
- self._with_polymorphic_mappers))
-
- def _iterate_polymorphic_properties(self, mappers=None):
- """Return an iterator of MapperProperty objects which will render into
- a SELECT."""
-
- if mappers is None:
- mappers = self._with_polymorphic_mappers
-
- if not mappers:
- for c in self.iterate_properties:
- yield c
- else:
- # in the polymorphic case, filter out discriminator columns
- # from other mappers, as these are sometimes dependent on that
- # mapper's polymorphic selectable (which we don't want rendered)
- for c in util.unique_list(
- chain(*[list(mapper.iterate_properties) for mapper in [self] +
- mappers])
- ):
- if getattr(c, '_is_polymorphic_discriminator', False) and \
- (self.polymorphic_on is None or
- c.columns[0] is not self.polymorphic_on):
- continue
- yield c
-
- @property
- def properties(self):
- raise NotImplementedError(
- "Public collection of MapperProperty objects is "
- "provided by the get_property() and iterate_properties "
- "accessors.")
-
- @_memoized_configured_property
- def _get_clause(self):
- """create a "get clause" based on the primary key. this is used
- by query.get() and many-to-one lazyloads to load this item
- by primary key.
-
- """
- params = [(primary_key, sql.bindparam(None, type_=primary_key.type))
- for primary_key in self.primary_key]
- return sql.and_(*[k==v for (k, v) in params]), \
- util.column_dict(params)
-
- @_memoized_configured_property
- def _equivalent_columns(self):
- """Create a map of all *equivalent* columns, based on
- the determination of column pairs that are equated to
- one another based on inherit condition. This is designed
- to work with the queries that util.polymorphic_union
- comes up with, which often don't include the columns from
- the base table directly (including the subclass table columns
- only).
-
- The resulting structure is a dictionary of columns mapped
- to lists of equivalent columns, i.e.
-
- {
- tablea.col1:
- set([tableb.col1, tablec.col1]),
- tablea.col2:
- set([tabled.col2])
- }
-
- """
- result = util.column_dict()
- def visit_binary(binary):
- if binary.operator == operators.eq:
- if binary.left in result:
- result[binary.left].add(binary.right)
- else:
- result[binary.left] = util.column_set((binary.right,))
- if binary.right in result:
- result[binary.right].add(binary.left)
- else:
- result[binary.right] = util.column_set((binary.left,))
- for mapper in self.base_mapper.self_and_descendants:
- if mapper.inherit_condition is not None:
- visitors.traverse(
- mapper.inherit_condition, {},
- {'binary':visit_binary})
-
- return result
-
- def _is_userland_descriptor(self, obj):
- return not isinstance(obj,
- (MapperProperty, attributes.QueryableAttribute)) and \
- hasattr(obj, '__get__') and not \
- isinstance(obj.__get__(None, obj),
- attributes.QueryableAttribute)
-
-
- def _should_exclude(self, name, assigned_name, local, column):
- """determine whether a particular property should be implicitly
- present on the class.
-
- This occurs when properties are propagated from an inherited class, or
- are applied from the columns present in the mapped table.
-
- """
-
- # check for descriptors, either local or from
- # an inherited class
- if local:
- if self.class_.__dict__.get(assigned_name, None) is not None \
- and self._is_userland_descriptor(
- self.class_.__dict__[assigned_name]):
- return True
- else:
- if getattr(self.class_, assigned_name, None) is not None \
- and self._is_userland_descriptor(
- getattr(self.class_, assigned_name)):
- return True
-
- if self.include_properties is not None and \
- name not in self.include_properties and \
- (column is None or column not in self.include_properties):
- self._log("not including property %s" % (name))
- return True
-
- if self.exclude_properties is not None and \
- (
- name in self.exclude_properties or \
- (column is not None and column in self.exclude_properties)
- ):
- self._log("excluding property %s" % (name))
- return True
-
- return False
-
- def common_parent(self, other):
- """Return true if the given mapper shares a common inherited parent as
- this mapper."""
-
- return self.base_mapper is other.base_mapper
-
- def _canload(self, state, allow_subtypes):
- s = self.primary_mapper()
- if self.polymorphic_on is not None or allow_subtypes:
- return _state_mapper(state).isa(s)
- else:
- return _state_mapper(state) is s
-
- def isa(self, other):
- """Return True if the this mapper inherits from the given mapper."""
-
- m = self
- while m and m is not other:
- m = m.inherits
- return bool(m)
-
- def iterate_to_root(self):
- m = self
- while m:
- yield m
- m = m.inherits
-
- @_memoized_configured_property
- def self_and_descendants(self):
- """The collection including this mapper and all descendant mappers.
-
- This includes not just the immediately inheriting mappers but
- all their inheriting mappers as well.
-
- """
- descendants = []
- stack = deque([self])
- while stack:
- item = stack.popleft()
- descendants.append(item)
- stack.extend(item._inheriting_mappers)
- return tuple(descendants)
-
- def polymorphic_iterator(self):
- """Iterate through the collection including this mapper and
- all descendant mappers.
-
- This includes not just the immediately inheriting mappers but
- all their inheriting mappers as well.
-
- To iterate through an entire hierarchy, use
- ``mapper.base_mapper.polymorphic_iterator()``.
-
- """
- return iter(self.self_and_descendants)
-
- def primary_mapper(self):
- """Return the primary mapper corresponding to this mapper's class key
- (class)."""
-
- return self.class_manager.mapper
-
- @property
- def primary_base_mapper(self):
- return self.class_manager.mapper.base_mapper
-
- def identity_key_from_row(self, row, adapter=None):
- """Return an identity-map key for use in storing/retrieving an
- item from the identity map.
-
- row
- A ``sqlalchemy.engine.base.RowProxy`` instance or a
- dictionary corresponding result-set ``ColumnElement``
- instances to their values within a row.
-
- """
- pk_cols = self.primary_key
- if adapter:
- pk_cols = [adapter.columns[c] for c in pk_cols]
-
- return self._identity_class, \
- tuple(row[column] for column in pk_cols)
-
- def identity_key_from_primary_key(self, primary_key):
- """Return an identity-map key for use in storing/retrieving an
- item from an identity map.
-
- primary_key
- A list of values indicating the identifier.
-
- """
- return self._identity_class, tuple(primary_key)
-
- def identity_key_from_instance(self, instance):
- """Return the identity key for the given instance, based on
- its primary key attributes.
-
- This value is typically also found on the instance state under the
- attribute name `key`.
-
- """
- return self.identity_key_from_primary_key(
- self.primary_key_from_instance(instance))
-
- def _identity_key_from_state(self, state):
- dict_ = state.dict
- manager = state.manager
- return self._identity_class, tuple([
- manager[self._columntoproperty[col].key].\
- impl.get(state, dict_, attributes.PASSIVE_OFF)
- for col in self.primary_key
- ])
-
- def primary_key_from_instance(self, instance):
- """Return the list of primary key values for the given
- instance.
-
- """
- state = attributes.instance_state(instance)
- return self._primary_key_from_state(state)
-
- def _primary_key_from_state(self, state):
- dict_ = state.dict
- manager = state.manager
- return [
- manager[self._columntoproperty[col].key].\
- impl.get(state, dict_, attributes.PASSIVE_OFF)
- for col in self.primary_key
- ]
-
- def _get_state_attr_by_column(self, state, dict_, column,
- passive=attributes.PASSIVE_OFF):
- prop = self._columntoproperty[column]
- return state.manager[prop.key].impl.get(state, dict_, passive=passive)
-
- def _set_state_attr_by_column(self, state, dict_, column, value):
- prop = self._columntoproperty[column]
- state.manager[prop.key].impl.set(state, dict_, value, None)
-
- def _get_committed_attr_by_column(self, obj, column):
- state = attributes.instance_state(obj)
- dict_ = attributes.instance_dict(obj)
- return self._get_committed_state_attr_by_column(state, dict_, column)
-
- def _get_committed_state_attr_by_column(self, state, dict_,
- column, passive=attributes.PASSIVE_OFF):
-
- prop = self._columntoproperty[column]
- return state.manager[prop.key].impl.\
- get_committed_value(state, dict_, passive=passive)
-
- def _optimized_get_statement(self, state, attribute_names):
- """assemble a WHERE clause which retrieves a given state by primary
- key, using a minimized set of tables.
-
- Applies to a joined-table inheritance mapper where the
- requested attribute names are only present on joined tables,
- not the base table. The WHERE clause attempts to include
- only those tables to minimize joins.
-
- """
- props = self._props
-
- tables = set(chain(
- *[sqlutil.find_tables(c, check_columns=True)
- for key in attribute_names
- for c in props[key].columns]
- ))
-
- if self.base_mapper.local_table in tables:
- return None
-
- class ColumnsNotAvailable(Exception):
- pass
-
- def visit_binary(binary):
- leftcol = binary.left
- rightcol = binary.right
- if leftcol is None or rightcol is None:
- return
-
- if leftcol.table not in tables:
- leftval = self._get_committed_state_attr_by_column(
- state, state.dict,
- leftcol,
- passive=attributes.PASSIVE_NO_INITIALIZE)
- if leftval is attributes.PASSIVE_NO_RESULT or leftval is None:
- raise ColumnsNotAvailable()
- binary.left = sql.bindparam(None, leftval,
- type_=binary.right.type)
- elif rightcol.table not in tables:
- rightval = self._get_committed_state_attr_by_column(
- state, state.dict,
- rightcol,
- passive=attributes.PASSIVE_NO_INITIALIZE)
- if rightval is attributes.PASSIVE_NO_RESULT or rightval is None:
- raise ColumnsNotAvailable()
- binary.right = sql.bindparam(None, rightval,
- type_=binary.right.type)
-
- allconds = []
-
- try:
- start = False
- for mapper in reversed(list(self.iterate_to_root())):
- if mapper.local_table in tables:
- start = True
- if start and not mapper.single:
- allconds.append(visitors.cloned_traverse(
- mapper.inherit_condition,
- {},
- {'binary':visit_binary}
- )
- )
- except ColumnsNotAvailable:
- return None
-
- cond = sql.and_(*allconds)
-
- cols = []
- for key in attribute_names:
- cols.extend(props[key].columns)
- return sql.select(cols, cond, use_labels=True)
-
- def cascade_iterator(self, type_, state, halt_on=None):
- """Iterate each element and its mapper in an object graph,
- for all relationships that meet the given cascade rule.
-
- :param type_:
- The name of the cascade rule (i.e. save-update, delete,
- etc.)
-
- :param state:
- The lead InstanceState. child items will be processed per
- the relationships defined for this object's mapper.
-
- the return value are object instances; this provides a strong
- reference so that they don't fall out of scope immediately.
-
- """
- visited_states = set()
- prp, mpp = object(), object()
-
- visitables = deque([(deque(self._props.values()), prp,
- state, state.dict)])
-
- while visitables:
- iterator, item_type, parent_state, parent_dict = visitables[-1]
- if not iterator:
- visitables.pop()
- continue
-
- if item_type is prp:
- prop = iterator.popleft()
- if type_ not in prop.cascade:
- continue
- queue = deque(prop.cascade_iterator(type_, parent_state,
- parent_dict, visited_states, halt_on))
- if queue:
- visitables.append((queue,mpp, None, None))
- elif item_type is mpp:
- instance, instance_mapper, corresponding_state, \
- corresponding_dict = iterator.popleft()
- yield instance, instance_mapper, \
- corresponding_state, corresponding_dict
- visitables.append((deque(instance_mapper._props.values()),
- prp, corresponding_state,
- corresponding_dict))
-
- @_memoized_configured_property
- def _compiled_cache(self):
- return util.LRUCache(self._compiled_cache_size)
-
- @_memoized_configured_property
- def _sorted_tables(self):
- table_to_mapper = {}
- for mapper in self.base_mapper.self_and_descendants:
- for t in mapper.tables:
- table_to_mapper[t] = mapper
-
- sorted_ = sqlutil.sort_tables(table_to_mapper.iterkeys())
- ret = util.OrderedDict()
- for t in sorted_:
- ret[t] = table_to_mapper[t]
- return ret
-
- def _per_mapper_flush_actions(self, uow):
- saves = unitofwork.SaveUpdateAll(uow, self.base_mapper)
- deletes = unitofwork.DeleteAll(uow, self.base_mapper)
- uow.dependencies.add((saves, deletes))
-
- for dep in self._dependency_processors:
- dep.per_property_preprocessors(uow)
-
- for prop in self._props.values():
- prop.per_property_preprocessors(uow)
-
- def _per_state_flush_actions(self, uow, states, isdelete):
-
- base_mapper = self.base_mapper
- save_all = unitofwork.SaveUpdateAll(uow, base_mapper)
- delete_all = unitofwork.DeleteAll(uow, base_mapper)
- for state in states:
- # keep saves before deletes -
- # this ensures 'row switch' operations work
- if isdelete:
- action = unitofwork.DeleteState(uow, state, base_mapper)
- uow.dependencies.add((save_all, action))
- else:
- action = unitofwork.SaveUpdateState(uow, state, base_mapper)
- uow.dependencies.add((action, delete_all))
-
- yield action
-
- def _memo(self, key, callable_):
- if key in self._memoized_values:
- return self._memoized_values[key]
- else:
- self._memoized_values[key] = value = callable_()
- return value
-
- def _post_update(self, states, uowtransaction, post_update_cols):
- """Issue UPDATE statements on behalf of a relationship() which
- specifies post_update.
-
- """
- cached_connections = util.PopulateDict(
- lambda conn:conn.execution_options(
- compiled_cache=self._compiled_cache
- ))
-
- # if session has a connection callable,
- # organize individual states with the connection
- # to use for update
- if uowtransaction.session.connection_callable:
- connection_callable = \
- uowtransaction.session.connection_callable
- else:
- connection = uowtransaction.transaction.connection(self)
- connection_callable = None
-
- tups = []
- for state in _sort_states(states):
- if connection_callable:
- conn = connection_callable(self, state.obj())
- else:
- conn = connection
-
- mapper = _state_mapper(state)
-
- tups.append((state, state.dict, mapper, conn))
-
- table_to_mapper = self._sorted_tables
-
- for table in table_to_mapper:
- update = []
-
- for state, state_dict, mapper, connection in tups:
- if table not in mapper._pks_by_table:
- continue
-
- pks = mapper._pks_by_table[table]
- params = {}
- hasdata = False
-
- for col in mapper._cols_by_table[table]:
- if col in pks:
- params[col._label] = \
- mapper._get_state_attr_by_column(
- state,
- state_dict, col)
- elif col in post_update_cols:
- prop = mapper._columntoproperty[col]
- history = attributes.get_state_history(
- state, prop.key,
- attributes.PASSIVE_NO_INITIALIZE)
- if history.added:
- value = history.added[0]
- params[col.key] = value
- hasdata = True
- if hasdata:
- update.append((state, state_dict, params, mapper,
- connection))
-
- if update:
- mapper = table_to_mapper[table]
-
- def update_stmt():
- clause = sql.and_()
-
- for col in mapper._pks_by_table[table]:
- clause.clauses.append(col == sql.bindparam(col._label,
- type_=col.type))
-
- return table.update(clause)
-
- statement = self._memo(('post_update', table), update_stmt)
-
- # execute each UPDATE in the order according to the original
- # list of states to guarantee row access order, but
- # also group them into common (connection, cols) sets
- # to support executemany().
- for key, grouper in groupby(
- update, lambda rec: (rec[4], rec[2].keys())
- ):
- multiparams = [params for state, state_dict,
- params, mapper, conn in grouper]
- cached_connections[connection].\
- execute(statement, multiparams)
-
- def _save_obj(self, states, uowtransaction, single=False):
- """Issue ``INSERT`` and/or ``UPDATE`` statements for a list
- of objects.
-
- This is called within the context of a UOWTransaction during a
- flush operation, given a list of states to be flushed. The
- base mapper in an inheritance hierarchy handles the inserts/
- updates for all descendant mappers.
-
- """
-
- # if batch=false, call _save_obj separately for each object
- if not single and not self.batch:
- for state in _sort_states(states):
- self._save_obj([state],
- uowtransaction,
- single=True)
- return
-
- # if session has a connection callable,
- # organize individual states with the connection
- # to use for insert/update
- if uowtransaction.session.connection_callable:
- connection_callable = \
- uowtransaction.session.connection_callable
- else:
- connection = uowtransaction.transaction.connection(self)
- connection_callable = None
-
- tups = []
-
- for state in _sort_states(states):
- if connection_callable:
- conn = connection_callable(self, state.obj())
- else:
- conn = connection
-
- has_identity = bool(state.key)
- mapper = _state_mapper(state)
- instance_key = state.key or mapper._identity_key_from_state(state)
-
- row_switch = None
-
- # call before_XXX extensions
- if not has_identity:
- mapper.dispatch.before_insert(mapper, conn, state)
- else:
- mapper.dispatch.before_update(mapper, conn, state)
-
- # detect if we have a "pending" instance (i.e. has
- # no instance_key attached to it), and another instance
- # with the same identity key already exists as persistent.
- # convert to an UPDATE if so.
- if not has_identity and \
- instance_key in uowtransaction.session.identity_map:
- instance = \
- uowtransaction.session.identity_map[instance_key]
- existing = attributes.instance_state(instance)
- if not uowtransaction.is_deleted(existing):
- raise orm_exc.FlushError(
- "New instance %s with identity key %s conflicts "
- "with persistent instance %s" %
- (state_str(state), instance_key,
- state_str(existing)))
-
- self._log_debug(
- "detected row switch for identity %s. "
- "will update %s, remove %s from "
- "transaction", instance_key,
- state_str(state), state_str(existing))
-
- # remove the "delete" flag from the existing element
- uowtransaction.remove_state_actions(existing)
- row_switch = existing
-
- tups.append(
- (state, state.dict, mapper, conn,
- has_identity, instance_key, row_switch)
- )
-
- # dictionary of connection->connection_with_cache_options.
- cached_connections = util.PopulateDict(
- lambda conn:conn.execution_options(
- compiled_cache=self._compiled_cache
- ))
-
- table_to_mapper = self._sorted_tables
-
- for table in table_to_mapper:
- insert = []
- update = []
-
- for state, state_dict, mapper, connection, has_identity, \
- instance_key, row_switch in tups:
- if table not in mapper._pks_by_table:
- continue
-
- pks = mapper._pks_by_table[table]
-
- isinsert = not has_identity and not row_switch
-
- params = {}
- value_params = {}
-
- if isinsert:
- has_all_pks = True
- for col in mapper._cols_by_table[table]:
- if col is mapper.version_id_col:
- params[col.key] = \
- mapper.version_id_generator(None)
- else:
- # pull straight from the dict for
- # pending objects
- prop = mapper._columntoproperty[col]
- value = state_dict.get(prop.key, None)
-
- if value is None:
- if col in pks:
- has_all_pks = False
- elif col.default is None and \
- col.server_default is None:
- params[col.key] = value
-
- elif isinstance(value, sql.ClauseElement):
- value_params[col] = value
- else:
- params[col.key] = value
-
- insert.append((state, state_dict, params, mapper,
- connection, value_params, has_all_pks))
- else:
- hasdata = False
- for col in mapper._cols_by_table[table]:
- if col is mapper.version_id_col:
- params[col._label] = \
- mapper._get_committed_state_attr_by_column(
- row_switch or state,
- row_switch and row_switch.dict
- or state_dict,
- col)
-
- prop = mapper._columntoproperty[col]
- history = attributes.get_state_history(
- state, prop.key,
- attributes.PASSIVE_NO_INITIALIZE
- )
- if history.added:
- params[col.key] = history.added[0]
- hasdata = True
- else:
- params[col.key] = \
- mapper.version_id_generator(
- params[col._label])
-
- # HACK: check for history, in case the
- # history is only
- # in a different table than the one
- # where the version_id_col is.
- for prop in mapper._columntoproperty.\
- itervalues():
- history = attributes.get_state_history(
- state, prop.key,
- attributes.PASSIVE_NO_INITIALIZE)
- if history.added:
- hasdata = True
- else:
- prop = mapper._columntoproperty[col]
- history = attributes.get_state_history(
- state, prop.key,
- attributes.PASSIVE_NO_INITIALIZE)
- if history.added:
- if isinstance(history.added[0],
- sql.ClauseElement):
- value_params[col] = history.added[0]
- else:
- value = history.added[0]
- params[col.key] = value
-
- if col in pks:
- if history.deleted and \
- not row_switch:
- # if passive_updates and sync detected
- # this was a pk->pk sync, use the new
- # value to locate the row, since the
- # DB would already have set this
- if ("pk_cascaded", state, col) in \
- uowtransaction.\
- attributes:
- value = history.added[0]
- params[col._label] = value
- else:
- # use the old value to
- # locate the row
- value = history.deleted[0]
- params[col._label] = value
- hasdata = True
- else:
- # row switch logic can reach us here
- # remove the pk from the update params
- # so the update doesn't
- # attempt to include the pk in the
- # update statement
- del params[col.key]
- value = history.added[0]
- params[col._label] = value
- if value is None and hasdata:
- raise sa_exc.FlushError(
- "Can't update table "
- "using NULL for primary key "
- "value")
- else:
- hasdata = True
- elif col in pks:
- value = state.manager[prop.key].\
- impl.get(state, state_dict)
- if value is None:
- raise sa_exc.FlushError(
- "Can't update table "
- "using NULL for primary "
- "key value")
- params[col._label] = value
- if hasdata:
- update.append((state, state_dict, params, mapper,
- connection, value_params))
-
- if update:
- mapper = table_to_mapper[table]
-
- needs_version_id = mapper.version_id_col is not None and \
- table.c.contains_column(mapper.version_id_col)
-
- def update_stmt():
- clause = sql.and_()
-
- for col in mapper._pks_by_table[table]:
- clause.clauses.append(col == sql.bindparam(col._label,
- type_=col.type))
-
- if needs_version_id:
- clause.clauses.append(mapper.version_id_col ==\
- sql.bindparam(mapper.version_id_col._label,
- type_=col.type))
-
- return table.update(clause)
-
- statement = self._memo(('update', table), update_stmt)
-
- rows = 0
- for state, state_dict, params, mapper, \
- connection, value_params in update:
-
- if value_params:
- c = connection.execute(
- statement.values(value_params),
- params)
- else:
- c = cached_connections[connection].\
- execute(statement, params)
-
- mapper._postfetch(
- uowtransaction,
- table,
- state,
- state_dict,
- c.context.prefetch_cols,
- c.context.postfetch_cols,
- c.context.compiled_parameters[0],
- value_params)
- rows += c.rowcount
-
- if connection.dialect.supports_sane_rowcount:
- if rows != len(update):
- raise orm_exc.StaleDataError(
- "UPDATE statement on table '%s' expected to update %d row(s); "
- "%d were matched." %
- (table.description, len(update), rows))
-
- elif needs_version_id:
- util.warn("Dialect %s does not support updated rowcount "
- "- versioning cannot be verified." %
- c.dialect.dialect_description,
- stacklevel=12)
-
- if insert:
- statement = self._memo(('insert', table), table.insert)
-
- for (connection, pkeys, hasvalue, has_all_pks), \
- records in groupby(insert,
- lambda rec: (rec[4],
- rec[2].keys(),
- bool(rec[5]),
- rec[6])
- ):
- if has_all_pks and not hasvalue:
- records = list(records)
- multiparams = [rec[2] for rec in records]
- c = cached_connections[connection].\
- execute(statement, multiparams)
-
- for (state, state_dict, params, mapper,
- conn, value_params, has_all_pks), \
- last_inserted_params in \
- zip(records, c.context.compiled_parameters):
- mapper._postfetch(
- uowtransaction,
- table,
- state,
- state_dict,
- c.context.prefetch_cols,
- c.context.postfetch_cols,
- last_inserted_params,
- value_params)
-
- else:
- for state, state_dict, params, mapper, \
- connection, value_params, \
- has_all_pks in records:
-
- if value_params:
- result = connection.execute(
- statement.values(value_params),
- params)
- else:
- result = cached_connections[connection].\
- execute(statement, params)
-
- primary_key = result.context.inserted_primary_key
-
- if primary_key is not None:
- # set primary key attributes
- for pk, col in zip(primary_key,
- mapper._pks_by_table[table]):
- prop = mapper._columntoproperty[col]
- if state_dict.get(prop.key) is None:
- # TODO: would rather say:
- #state_dict[prop.key] = pk
- mapper._set_state_attr_by_column(
- state,
- state_dict,
- col, pk)
-
- mapper._postfetch(
- uowtransaction,
- table,
- state,
- state_dict,
- result.context.prefetch_cols,
- result.context.postfetch_cols,
- result.context.compiled_parameters[0],
- value_params)
-
-
- for state, state_dict, mapper, connection, has_identity, \
- instance_key, row_switch in tups:
-
- if mapper._readonly_props:
- readonly = state.unmodified_intersection(
- [p.key for p in mapper._readonly_props]
- )
- if readonly:
- state.expire_attributes(state.dict, readonly)
-
- # if eager_defaults option is enabled,
- # refresh whatever has been expired.
- if self.eager_defaults and state.unloaded:
- state.key = self._identity_key_from_state(state)
- uowtransaction.session.query(self)._load_on_ident(
- state.key, refresh_state=state,
- only_load_props=state.unloaded)
-
- # call after_XXX extensions
- if not has_identity:
- mapper.dispatch.after_insert(mapper, connection, state)
- else:
- mapper.dispatch.after_update(mapper, connection, state)
-
- def _postfetch(self, uowtransaction, table,
- state, dict_, prefetch_cols, postfetch_cols,
- params, value_params):
- """During a flush, expire attributes in need of newly
- persisted database state."""
-
- if self.version_id_col is not None:
- prefetch_cols = list(prefetch_cols) + [self.version_id_col]
-
- for c in prefetch_cols:
- if c.key in params and c in self._columntoproperty:
- self._set_state_attr_by_column(state, dict_, c, params[c.key])
-
- if postfetch_cols:
- state.expire_attributes(state.dict,
- [self._columntoproperty[c].key
- for c in postfetch_cols if c in
- self._columntoproperty]
- )
-
- # synchronize newly inserted ids from one table to the next
- # TODO: this still goes a little too often. would be nice to
- # have definitive list of "columns that changed" here
- for m, equated_pairs in self._table_to_equated[table]:
- sync.populate(state, m, state, m,
- equated_pairs,
- uowtransaction,
- self.passive_updates)
-
- @util.memoized_property
- def _table_to_equated(self):
- """memoized map of tables to collections of columns to be
- synchronized upwards to the base mapper."""
-
- result = util.defaultdict(list)
-
- for table in self._sorted_tables:
- cols = set(table.c)
- for m in self.iterate_to_root():
- if m._inherits_equated_pairs and \
- cols.intersection(
- [l for l, r in m._inherits_equated_pairs]):
- result[table].append((m, m._inherits_equated_pairs))
-
- return result
-
- def _delete_obj(self, states, uowtransaction):
- """Issue ``DELETE`` statements for a list of objects.
-
- This is called within the context of a UOWTransaction during a
- flush operation.
-
- """
- if uowtransaction.session.connection_callable:
- connection_callable = \
- uowtransaction.session.connection_callable
- else:
- connection = uowtransaction.transaction.connection(self)
- connection_callable = None
-
- tups = []
- cached_connections = util.PopulateDict(
- lambda conn:conn.execution_options(
- compiled_cache=self._compiled_cache
- ))
-
- for state in _sort_states(states):
- mapper = _state_mapper(state)
-
- if connection_callable:
- conn = connection_callable(self, state.obj())
- else:
- conn = connection
-
- mapper.dispatch.before_delete(mapper, conn, state)
-
- tups.append((state,
- state.dict,
- _state_mapper(state),
- bool(state.key),
- conn))
-
- table_to_mapper = self._sorted_tables
-
- for table in reversed(table_to_mapper.keys()):
- delete = util.defaultdict(list)
- for state, state_dict, mapper, has_identity, connection in tups:
- if not has_identity or table not in mapper._pks_by_table:
- continue
-
- params = {}
- delete[connection].append(params)
- for col in mapper._pks_by_table[table]:
- params[col.key] = \
- value = \
- mapper._get_state_attr_by_column(
- state, state_dict, col)
- if value is None:
- raise sa_exc.FlushError(
- "Can't delete from table "
- "using NULL for primary "
- "key value")
-
- if mapper.version_id_col is not None and \
- table.c.contains_column(mapper.version_id_col):
- params[mapper.version_id_col.key] = \
- mapper._get_committed_state_attr_by_column(
- state, state_dict,
- mapper.version_id_col)
-
- mapper = table_to_mapper[table]
- need_version_id = mapper.version_id_col is not None and \
- table.c.contains_column(mapper.version_id_col)
-
- def delete_stmt():
- clause = sql.and_()
- for col in mapper._pks_by_table[table]:
- clause.clauses.append(
- col == sql.bindparam(col.key, type_=col.type))
-
- if need_version_id:
- clause.clauses.append(
- mapper.version_id_col ==
- sql.bindparam(
- mapper.version_id_col.key,
- type_=mapper.version_id_col.type
- )
- )
-
- return table.delete(clause)
-
- for connection, del_objects in delete.iteritems():
- statement = self._memo(('delete', table), delete_stmt)
- rows = -1
-
- connection = cached_connections[connection]
-
- if need_version_id and \
- not connection.dialect.supports_sane_multi_rowcount:
- # TODO: need test coverage for this [ticket:1761]
- if connection.dialect.supports_sane_rowcount:
- rows = 0
- # execute deletes individually so that versioned
- # rows can be verified
- for params in del_objects:
- c = connection.execute(statement, params)
- rows += c.rowcount
- else:
- util.warn(
- "Dialect %s does not support deleted rowcount "
- "- versioning cannot be verified." %
- connection.dialect.dialect_description,
- stacklevel=12)
- connection.execute(statement, del_objects)
- else:
- c = connection.execute(statement, del_objects)
- if connection.dialect.supports_sane_multi_rowcount:
- rows = c.rowcount
-
- if rows != -1 and rows != len(del_objects):
- raise orm_exc.StaleDataError(
- "DELETE statement on table '%s' expected to delete %d row(s); "
- "%d were matched." %
- (table.description, len(del_objects), c.rowcount)
- )
-
- for state, state_dict, mapper, has_identity, connection in tups:
- mapper.dispatch.after_delete(mapper, connection, state)
-
- def _instance_processor(self, context, path, reduced_path, adapter,
- polymorphic_from=None,
- only_load_props=None, refresh_state=None,
- polymorphic_discriminator=None):
-
- """Produce a mapper level row processor callable
- which processes rows into mapped instances."""
-
- pk_cols = self.primary_key
-
- if polymorphic_from or refresh_state:
- polymorphic_on = None
- else:
- if polymorphic_discriminator is not None:
- polymorphic_on = polymorphic_discriminator
- else:
- polymorphic_on = self.polymorphic_on
- polymorphic_instances = util.PopulateDict(
- self._configure_subclass_mapper(
- context, path, reduced_path, adapter)
- )
-
- version_id_col = self.version_id_col
-
- if adapter:
- pk_cols = [adapter.columns[c] for c in pk_cols]
- if polymorphic_on is not None:
- polymorphic_on = adapter.columns[polymorphic_on]
- if version_id_col is not None:
- version_id_col = adapter.columns[version_id_col]
-
- identity_class = self._identity_class
-
- new_populators = []
- existing_populators = []
- load_path = context.query._current_path + path
-
- def populate_state(state, dict_, row, isnew, only_load_props):
- if isnew:
- if context.propagate_options:
- state.load_options = context.propagate_options
- if state.load_options:
- state.load_path = load_path
-
- if not new_populators:
- self._populators(context, path, reduced_path, row, adapter,
- new_populators,
- existing_populators
- )
-
- if isnew:
- populators = new_populators
- else:
- populators = existing_populators
-
- if only_load_props:
- for key, populator in populators:
- if key in only_load_props:
- populator(state, dict_, row)
- else:
- for key, populator in populators:
- populator(state, dict_, row)
-
- session_identity_map = context.session.identity_map
-
- listeners = self.dispatch
-
- translate_row = listeners.translate_row or None
- create_instance = listeners.create_instance or None
- populate_instance = listeners.populate_instance or None
- append_result = listeners.append_result or None
- populate_existing = context.populate_existing or self.always_refresh
- if self.allow_partial_pks:
- is_not_primary_key = _none_set.issuperset
- else:
- is_not_primary_key = _none_set.issubset
-
- def _instance(row, result):
- if translate_row:
- for fn in translate_row:
- ret = fn(self, context, row)
- if ret is not EXT_CONTINUE:
- row = ret
- break
-
- if polymorphic_on is not None:
- discriminator = row[polymorphic_on]
- if discriminator is not None:
- _instance = polymorphic_instances[discriminator]
- if _instance:
- return _instance(row, result)
-
- # determine identity key
- if refresh_state:
- identitykey = refresh_state.key
- if identitykey is None:
- # super-rare condition; a refresh is being called
- # on a non-instance-key instance; this is meant to only
- # occur within a flush()
- identitykey = self._identity_key_from_state(refresh_state)
- else:
- identitykey = identity_class, tuple([row[column] for column in pk_cols])
-
- instance = session_identity_map.get(identitykey)
- if instance is not None:
- state = attributes.instance_state(instance)
- dict_ = attributes.instance_dict(instance)
-
- isnew = state.runid != context.runid
- currentload = not isnew
- loaded_instance = False
-
- if not currentload and \
- version_id_col is not None and \
- context.version_check and \
- self._get_state_attr_by_column(
- state,
- dict_,
- self.version_id_col) != \
- row[version_id_col]:
-
- raise orm_exc.StaleDataError(
- "Instance '%s' has version id '%s' which "
- "does not match database-loaded version id '%s'."
- % (state_str(state),
- self._get_state_attr_by_column(
- state, dict_,
- self.version_id_col),
- row[version_id_col]))
- elif refresh_state:
- # out of band refresh_state detected (i.e. its not in the
- # session.identity_map) honor it anyway. this can happen
- # if a _get() occurs within save_obj(), such as
- # when eager_defaults is True.
- state = refresh_state
- instance = state.obj()
- dict_ = attributes.instance_dict(instance)
- isnew = state.runid != context.runid
- currentload = True
- loaded_instance = False
- else:
- # check for non-NULL values in the primary key columns,
- # else no entity is returned for the row
- if is_not_primary_key(identitykey[1]):
- return None
-
- isnew = True
- currentload = True
- loaded_instance = True
-
- if create_instance:
- for fn in create_instance:
- instance = fn(self,
- context,
- row, self.class_)
- if instance is not EXT_CONTINUE:
- manager = attributes.manager_of_class(
- instance.__class__)
- # TODO: if manager is None, raise a friendly error
- # about returning instances of unmapped types
- manager.setup_instance(instance)
- break
- else:
- instance = self.class_manager.new_instance()
- else:
- instance = self.class_manager.new_instance()
-
- dict_ = attributes.instance_dict(instance)
- state = attributes.instance_state(instance)
- state.key = identitykey
-
- # manually adding instance to session. for a complete add,
- # session._finalize_loaded() must be called.
- state.session_id = context.session.hash_key
- session_identity_map.add(state)
-
- if currentload or populate_existing:
- if isnew:
- state.runid = context.runid
- context.progress[state] = dict_
-
- if populate_instance:
- for fn in populate_instance:
- ret = fn(self, context, row, state,
- only_load_props=only_load_props,
- instancekey=identitykey, isnew=isnew)
- if ret is not EXT_CONTINUE:
- break
- else:
- populate_state(state, dict_, row, isnew, only_load_props)
- else:
- populate_state(state, dict_, row, isnew, only_load_props)
-
- if loaded_instance:
- state.manager.dispatch.load(state, context)
- elif isnew:
- state.manager.dispatch.refresh(state, context, only_load_props)
-
- elif state in context.partials or state.unloaded:
- # populate attributes on non-loading instances which have
- # been expired
- # TODO: apply eager loads to un-lazy loaded collections ?
-
- if state in context.partials:
- isnew = False
- (d_, attrs) = context.partials[state]
- else:
- isnew = True
- attrs = state.unloaded
- # allow query.instances to commit the subset of attrs
- context.partials[state] = (dict_, attrs)
-
- if populate_instance:
- for fn in populate_instance:
- ret = fn(self, context, row, state,
- only_load_props=attrs,
- instancekey=identitykey, isnew=isnew)
- if ret is not EXT_CONTINUE:
- break
- else:
- populate_state(state, dict_, row, isnew, attrs)
- else:
- populate_state(state, dict_, row, isnew, attrs)
-
- if isnew:
- state.manager.dispatch.refresh(state, context, attrs)
-
-
- if result is not None:
- if append_result:
- for fn in append_result:
- if fn(self, context, row, state,
- result, instancekey=identitykey,
- isnew=isnew) is not EXT_CONTINUE:
- break
- else:
- result.append(instance)
- else:
- result.append(instance)
-
- return instance
- return _instance
-
- def _populators(self, context, path, reduced_path, row, adapter,
- new_populators, existing_populators):
- """Produce a collection of attribute level row processor callables."""
-
- delayed_populators = []
- for prop in self._props.itervalues():
- newpop, existingpop, delayedpop = prop.create_row_processor(
- context, path,
- reduced_path,
- self, row, adapter)
- if newpop:
- new_populators.append((prop.key, newpop))
- if existingpop:
- existing_populators.append((prop.key, existingpop))
- if delayedpop:
- delayed_populators.append((prop.key, delayedpop))
- if delayed_populators:
- new_populators.extend(delayed_populators)
-
- def _configure_subclass_mapper(self, context, path, reduced_path, adapter):
- """Produce a mapper level row processor callable factory for mappers
- inheriting this one."""
-
- def configure_subclass_mapper(discriminator):
- try:
- mapper = self.polymorphic_map[discriminator]
- except KeyError:
- raise AssertionError(
- "No such polymorphic_identity %r is defined" %
- discriminator)
- if mapper is self:
- return None
-
- # replace the tip of the path info with the subclass mapper
- # being used. that way accurate "load_path" info is available
- # for options invoked during deferred loads.
- # we lose AliasedClass path elements this way, but currently,
- # those are not needed at this stage.
-
- # this asserts to true
- #assert mapper.isa(_class_to_mapper(path[-1]))
-
- return mapper._instance_processor(context, path[0:-1] + (mapper,),
- reduced_path[0:-1] + (mapper.base_mapper,),
- adapter,
- polymorphic_from=self)
- return configure_subclass_mapper
-
-log.class_logger(Mapper)
-
-def configure_mappers():
- """Initialize the inter-mapper relationships of all mappers that
- have been constructed thus far.
-
- This function can be called any number of times, but in
- most cases is handled internally.
-
- """
-
- global _new_mappers
- if not _new_mappers:
- return
-
- _COMPILE_MUTEX.acquire()
- try:
- global _already_compiling
- if _already_compiling:
- return
- _already_compiling = True
- try:
-
- # double-check inside mutex
- if not _new_mappers:
- return
-
- # initialize properties on all mappers
- # note that _mapper_registry is unordered, which
- # may randomly conceal/reveal issues related to
- # the order of mapper compilation
- for mapper in list(_mapper_registry):
- if getattr(mapper, '_configure_failed', False):
- e = sa_exc.InvalidRequestError(
- "One or more mappers failed to initialize - "
- "can't proceed with initialization of other "
- "mappers. Original exception was: %s"
- % mapper._configure_failed)
- e._configure_failed = mapper._configure_failed
- raise e
- if not mapper.configured:
- try:
- mapper._post_configure_properties()
- mapper._expire_memoizations()
- mapper.dispatch.mapper_configured(mapper, mapper.class_)
- except:
- exc = sys.exc_info()[1]
- if not hasattr(exc, '_configure_failed'):
- mapper._configure_failed = exc
- raise
-
- _new_mappers = False
- finally:
- _already_compiling = False
- finally:
- _COMPILE_MUTEX.release()
-
-
-def reconstructor(fn):
- """Decorate a method as the 'reconstructor' hook.
-
- Designates a method as the "reconstructor", an ``__init__``-like
- method that will be called by the ORM after the instance has been
- loaded from the database or otherwise reconstituted.
-
- The reconstructor will be invoked with no arguments. Scalar
- (non-collection) database-mapped attributes of the instance will
- be available for use within the function. Eagerly-loaded
- collections are generally not yet available and will usually only
- contain the first element. ORM state changes made to objects at
- this stage will not be recorded for the next flush() operation, so
- the activity within a reconstructor should be conservative.
-
- """
- fn.__sa_reconstructor__ = True
- return fn
-
-def validates(*names):
- """Decorate a method as a 'validator' for one or more named properties.
-
- Designates a method as a validator, a method which receives the
- name of the attribute as well as a value to be assigned, or in the
- case of a collection, the value to be added to the collection. The function
- can then raise validation exceptions to halt the process from continuing
- (where Python's built-in ``ValueError`` and ``AssertionError`` exceptions are
- reasonable choices), or can modify or replace the value before proceeding.
- The function should otherwise return the given value.
-
- Note that a validator for a collection **cannot** issue a load of that
- collection within the validation routine - this usage raises
- an assertion to avoid recursion overflows. This is a reentrant
- condition which is not supported.
-
- """
- def wrap(fn):
- fn.__sa_validators__ = names
- return fn
- return wrap
-
-def _event_on_load(state, ctx):
- instrumenting_mapper = state.manager.info[_INSTRUMENTOR]
- if instrumenting_mapper._reconstructor:
- instrumenting_mapper._reconstructor(state.obj())
-
-def _event_on_first_init(manager, cls):
- """Trigger mapper compilation."""
-
- instrumenting_mapper = manager.info.get(_INSTRUMENTOR)
- if instrumenting_mapper:
- if _new_mappers:
- configure_mappers()
-
-def _event_on_init(state, args, kwargs):
- """Run init_instance hooks."""
-
- instrumenting_mapper = state.manager.info.get(_INSTRUMENTOR)
- if instrumenting_mapper and \
- instrumenting_mapper._set_polymorphic_identity:
- instrumenting_mapper._set_polymorphic_identity(state)
-
-def _event_on_resurrect(state):
- # re-populate the primary key elements
- # of the dict based on the mapping.
- instrumenting_mapper = state.manager.info.get(_INSTRUMENTOR)
- if instrumenting_mapper:
- for col, val in zip(instrumenting_mapper.primary_key, state.key[1]):
- instrumenting_mapper._set_state_attr_by_column(
- state, state.dict, col, val)
-
-
-def _sort_states(states):
- return sorted(states, key=operator.attrgetter('sort_key'))
-
-def _load_scalar_attributes(state, attribute_names):
- """initiate a column-based attribute refresh operation."""
-
- mapper = _state_mapper(state)
- session = sessionlib._state_session(state)
- if not session:
- raise orm_exc.DetachedInstanceError(
- "Instance %s is not bound to a Session; "
- "attribute refresh operation cannot proceed" %
- (state_str(state)))
-
- has_key = bool(state.key)
-
- result = False
-
- if mapper.inherits and not mapper.concrete:
- statement = mapper._optimized_get_statement(state, attribute_names)
- if statement is not None:
- result = session.query(mapper).from_statement(statement).\
- _load_on_ident(None,
- only_load_props=attribute_names,
- refresh_state=state)
-
- if result is False:
- if has_key:
- identity_key = state.key
- else:
- # this codepath is rare - only valid when inside a flush, and the
- # object is becoming persistent but hasn't yet been assigned an identity_key.
- # check here to ensure we have the attrs we need.
- pk_attrs = [mapper._columntoproperty[col].key
- for col in mapper.primary_key]
- if state.expired_attributes.intersection(pk_attrs):
- raise sa_exc.InvalidRequestError("Instance %s cannot be refreshed - it's not "
- " persistent and does not "
- "contain a full primary key." % state_str(state))
- identity_key = mapper._identity_key_from_state(state)
-
- if (_none_set.issubset(identity_key) and \
- not mapper.allow_partial_pks) or \
- _none_set.issuperset(identity_key):
- util.warn("Instance %s to be refreshed doesn't "
- "contain a full primary key - can't be refreshed "
- "(and shouldn't be expired, either)."
- % state_str(state))
- return
-
- result = session.query(mapper)._load_on_ident(
- identity_key,
- refresh_state=state,
- only_load_props=attribute_names)
-
- # if instance is pending, a refresh operation
- # may not complete (even if PK attributes are assigned)
- if has_key and result is None:
- raise orm_exc.ObjectDeletedError(
- "Instance '%s' has been deleted." %
- state_str(state))
-
-
-class _ColumnMapping(util.py25_dict):
- """Error reporting helper for mapper._columntoproperty."""
-
- def __init__(self, mapper):
- self.mapper = mapper
-
- def __missing__(self, column):
- prop = self.mapper._props.get(column)
- if prop:
- raise orm_exc.UnmappedColumnError(
- "Column '%s.%s' is not available, due to "
- "conflicting property '%s':%r" % (
- column.table.name, column.name, column.key, prop))
- raise orm_exc.UnmappedColumnError(
- "No column %s is configured on mapper %s..." %
- (column, self.mapper))
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/properties.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/properties.py
deleted file mode 100755
index cf059513..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/properties.py
+++ /dev/null
@@ -1,1250 +0,0 @@
-# orm/properties.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""MapperProperty implementations.
-
-This is a private module which defines the behavior of invidual ORM-
-mapped attributes.
-
-"""
-
-from sqlalchemy import sql, util, log, exc as sa_exc
-from sqlalchemy.sql.util import ClauseAdapter, criterion_as_pairs, \
- join_condition
-from sqlalchemy.sql import operators, expression
-from sqlalchemy.orm import attributes, dependency, mapper, \
- object_mapper, strategies, configure_mappers
-from sqlalchemy.orm.util import CascadeOptions, _class_to_mapper, \
- _orm_annotate, _orm_deannotate
-from sqlalchemy.orm.interfaces import MANYTOMANY, MANYTOONE, \
- MapperProperty, ONETOMANY, PropComparator, StrategizedProperty
-mapperlib = util.importlater("sqlalchemy.orm", "mapperlib")
-NoneType = type(None)
-
-__all__ = ('ColumnProperty', 'CompositeProperty', 'SynonymProperty',
- 'ComparableProperty', 'RelationshipProperty', 'RelationProperty')
-
-from descriptor_props import CompositeProperty, SynonymProperty, \
- ComparableProperty,ConcreteInheritedProperty
-
-class ColumnProperty(StrategizedProperty):
- """Describes an object attribute that corresponds to a table column."""
-
- def __init__(self, *columns, **kwargs):
- """Construct a ColumnProperty.
-
- :param \*columns: The list of `columns` describes a single
- object property. If there are multiple tables joined
- together for the mapper, this list represents the equivalent
- column as it appears across each table.
-
- :param group:
-
- :param deferred:
-
- :param comparator_factory:
-
- :param descriptor:
-
- :param extension:
-
- """
- self.columns = [expression._labeled(c) for c in columns]
- self.group = kwargs.pop('group', None)
- self.deferred = kwargs.pop('deferred', False)
- self.instrument = kwargs.pop('_instrument', True)
- self.comparator_factory = kwargs.pop('comparator_factory',
- self.__class__.Comparator)
- self.descriptor = kwargs.pop('descriptor', None)
- self.extension = kwargs.pop('extension', None)
- self.active_history = kwargs.pop('active_history', False)
-
- if 'doc' in kwargs:
- self.doc = kwargs.pop('doc')
- else:
- for col in reversed(self.columns):
- doc = getattr(col, 'doc', None)
- if doc is not None:
- self.doc = doc
- break
- else:
- self.doc = None
-
- if kwargs:
- raise TypeError(
- "%s received unexpected keyword argument(s): %s" % (
- self.__class__.__name__,
- ', '.join(sorted(kwargs.keys()))))
-
- util.set_creation_order(self)
- if not self.instrument:
- self.strategy_class = strategies.UninstrumentedColumnLoader
- elif self.deferred:
- self.strategy_class = strategies.DeferredColumnLoader
- else:
- self.strategy_class = strategies.ColumnLoader
-
- def instrument_class(self, mapper):
- if not self.instrument:
- return
-
- attributes.register_descriptor(
- mapper.class_,
- self.key,
- comparator=self.comparator_factory(self, mapper),
- parententity=mapper,
- property_=self,
- doc=self.doc
- )
-
- def do_init(self):
- super(ColumnProperty, self).do_init()
- if len(self.columns) > 1 and \
- set(self.parent.primary_key).issuperset(self.columns):
- util.warn(
- ("On mapper %s, primary key column '%s' is being combined "
- "with distinct primary key column '%s' in attribute '%s'. "
- "Use explicit properties to give each column its own mapped "
- "attribute name.") % (self.parent, self.columns[1],
- self.columns[0], self.key))
-
- def copy(self):
- return ColumnProperty(
- deferred=self.deferred,
- group=self.group,
- active_history=self.active_history,
- *self.columns)
-
- def _getcommitted(self, state, dict_, column,
- passive=attributes.PASSIVE_OFF):
- return state.get_impl(self.key).\
- get_committed_value(state, dict_, passive=passive)
-
- def merge(self, session, source_state, source_dict, dest_state,
- dest_dict, load, _recursive):
- if self.key in source_dict:
- value = source_dict[self.key]
-
- if not load:
- dest_dict[self.key] = value
- else:
- impl = dest_state.get_impl(self.key)
- impl.set(dest_state, dest_dict, value, None)
- else:
- if dest_state.has_identity and self.key not in dest_dict:
- dest_state.expire_attributes(dest_dict, [self.key])
-
- class Comparator(PropComparator):
- @util.memoized_instancemethod
- def __clause_element__(self):
- if self.adapter:
- return self.adapter(self.prop.columns[0])
- else:
- return self.prop.columns[0]._annotate({
- "parententity": self.mapper,
- "parentmapper":self.mapper})
-
- def operate(self, op, *other, **kwargs):
- return op(self.__clause_element__(), *other, **kwargs)
-
- def reverse_operate(self, op, other, **kwargs):
- col = self.__clause_element__()
- return op(col._bind_param(op, other), col, **kwargs)
-
- # TODO: legacy..do we need this ? (0.5)
- ColumnComparator = Comparator
-
- def __str__(self):
- return str(self.parent.class_.__name__) + "." + self.key
-
-log.class_logger(ColumnProperty)
-
-
-
-
-class RelationshipProperty(StrategizedProperty):
- """Describes an object property that holds a single item or list
- of items that correspond to a related database table.
- """
-
- def __init__(self, argument,
- secondary=None, primaryjoin=None,
- secondaryjoin=None,
- foreign_keys=None,
- uselist=None,
- order_by=False,
- backref=None,
- back_populates=None,
- post_update=False,
- cascade=False, extension=None,
- viewonly=False, lazy=True,
- collection_class=None, passive_deletes=False,
- passive_updates=True, remote_side=None,
- enable_typechecks=True, join_depth=None,
- comparator_factory=None,
- single_parent=False, innerjoin=False,
- doc=None,
- active_history=False,
- cascade_backrefs=True,
- load_on_pending=False,
- strategy_class=None, _local_remote_pairs=None,
- query_class=None):
-
- self.uselist = uselist
- self.argument = argument
- self.secondary = secondary
- self.primaryjoin = primaryjoin
- self.secondaryjoin = secondaryjoin
- self.post_update = post_update
- self.direction = None
- self.viewonly = viewonly
- self.lazy = lazy
- self.single_parent = single_parent
- self._user_defined_foreign_keys = foreign_keys
- self.collection_class = collection_class
- self.passive_deletes = passive_deletes
- self.cascade_backrefs = cascade_backrefs
- self.passive_updates = passive_updates
- self.remote_side = remote_side
- self.enable_typechecks = enable_typechecks
- self.query_class = query_class
- self.innerjoin = innerjoin
- self.doc = doc
- self.active_history = active_history
- self.join_depth = join_depth
- self.local_remote_pairs = _local_remote_pairs
- self.extension = extension
- self.load_on_pending = load_on_pending
- self.comparator_factory = comparator_factory or \
- RelationshipProperty.Comparator
- self.comparator = self.comparator_factory(self, None)
- util.set_creation_order(self)
-
- if strategy_class:
- self.strategy_class = strategy_class
- elif self.lazy== 'dynamic':
- from sqlalchemy.orm import dynamic
- self.strategy_class = dynamic.DynaLoader
- else:
- self.strategy_class = strategies.factory(self.lazy)
-
- self._reverse_property = set()
-
- if cascade is not False:
- self.cascade = CascadeOptions(cascade)
- else:
- self.cascade = CascadeOptions("save-update, merge")
-
- if self.passive_deletes == 'all' and \
- ("delete" in self.cascade or
- "delete-orphan" in self.cascade):
- raise sa_exc.ArgumentError(
- "Can't set passive_deletes='all' in conjunction "
- "with 'delete' or 'delete-orphan' cascade")
-
- self.order_by = order_by
-
- self.back_populates = back_populates
-
- if self.back_populates:
- if backref:
- raise sa_exc.ArgumentError(
- "backref and back_populates keyword arguments "
- "are mutually exclusive")
- self.backref = None
- else:
- self.backref = backref
-
- def instrument_class(self, mapper):
- attributes.register_descriptor(
- mapper.class_,
- self.key,
- comparator=self.comparator_factory(self, mapper),
- parententity=mapper,
- property_=self,
- doc=self.doc,
- )
-
- class Comparator(PropComparator):
- def __init__(self, prop, mapper, of_type=None, adapter=None):
- self.prop = prop
- self.mapper = mapper
- self.adapter = adapter
- if of_type:
- self._of_type = _class_to_mapper(of_type)
-
- def adapted(self, adapter):
- """Return a copy of this PropComparator which will use the
- given adaption function on the local side of generated
- expressions.
-
- """
-
- return self.__class__(self.property, self.mapper,
- getattr(self, '_of_type', None),
- adapter)
-
- @property
- def parententity(self):
- return self.property.parent
-
- def __clause_element__(self):
- elem = self.property.parent._with_polymorphic_selectable
- if self.adapter:
- return self.adapter(elem)
- else:
- return elem
-
- def operate(self, op, *other, **kwargs):
- return op(self, *other, **kwargs)
-
- def reverse_operate(self, op, other, **kwargs):
- return op(self, *other, **kwargs)
-
- def of_type(self, cls):
- return RelationshipProperty.Comparator(
- self.property,
- self.mapper,
- cls, adapter=self.adapter)
-
- def in_(self, other):
- raise NotImplementedError('in_() not yet supported for '
- 'relationships. For a simple many-to-one, use '
- 'in_() against the set of foreign key values.')
-
- __hash__ = None
-
- def __eq__(self, other):
- if isinstance(other, (NoneType, expression._Null)):
- if self.property.direction in [ONETOMANY, MANYTOMANY]:
- return ~self._criterion_exists()
- else:
- return _orm_annotate(self.property._optimized_compare(
- None, adapt_source=self.adapter))
- elif self.property.uselist:
- raise sa_exc.InvalidRequestError("Can't compare a colle"
- "ction to an object or collection; use "
- "contains() to test for membership.")
- else:
- return _orm_annotate(self.property._optimized_compare(other,
- adapt_source=self.adapter))
-
- def _criterion_exists(self, criterion=None, **kwargs):
- if getattr(self, '_of_type', None):
- target_mapper = self._of_type
- to_selectable = target_mapper._with_polymorphic_selectable
- if self.property._is_self_referential():
- to_selectable = to_selectable.alias()
-
- single_crit = target_mapper._single_table_criterion
- if single_crit is not None:
- if criterion is not None:
- criterion = single_crit & criterion
- else:
- criterion = single_crit
- else:
- to_selectable = None
-
- if self.adapter:
- source_selectable = self.__clause_element__()
- else:
- source_selectable = None
-
- pj, sj, source, dest, secondary, target_adapter = \
- self.property._create_joins(dest_polymorphic=True,
- dest_selectable=to_selectable,
- source_selectable=source_selectable)
-
- for k in kwargs:
- crit = self.property.mapper.class_manager[k] == kwargs[k]
- if criterion is None:
- criterion = crit
- else:
- criterion = criterion & crit
-
- # annotate the *local* side of the join condition, in the case
- # of pj + sj this is the full primaryjoin, in the case of just
- # pj its the local side of the primaryjoin.
- if sj is not None:
- j = _orm_annotate(pj) & sj
- else:
- j = _orm_annotate(pj, exclude=self.property.remote_side)
-
- if criterion is not None and target_adapter:
- # limit this adapter to annotated only?
- criterion = target_adapter.traverse(criterion)
-
- # only have the "joined left side" of what we
- # return be subject to Query adaption. The right
- # side of it is used for an exists() subquery and
- # should not correlate or otherwise reach out
- # to anything in the enclosing query.
- if criterion is not None:
- criterion = criterion._annotate({'_halt_adapt': True})
-
- crit = j & criterion
-
- return sql.exists([1], crit, from_obj=dest).correlate(source)
-
- def any(self, criterion=None, **kwargs):
- if not self.property.uselist:
- raise sa_exc.InvalidRequestError(
- "'any()' not implemented for scalar "
- "attributes. Use has()."
- )
-
- return self._criterion_exists(criterion, **kwargs)
-
- def has(self, criterion=None, **kwargs):
- if self.property.uselist:
- raise sa_exc.InvalidRequestError(
- "'has()' not implemented for collections. "
- "Use any().")
- return self._criterion_exists(criterion, **kwargs)
-
- def contains(self, other, **kwargs):
- if not self.property.uselist:
- raise sa_exc.InvalidRequestError(
- "'contains' not implemented for scalar "
- "attributes. Use ==")
- clause = self.property._optimized_compare(other,
- adapt_source=self.adapter)
-
- if self.property.secondaryjoin is not None:
- clause.negation_clause = \
- self.__negated_contains_or_equals(other)
-
- return clause
-
- def __negated_contains_or_equals(self, other):
- if self.property.direction == MANYTOONE:
- state = attributes.instance_state(other)
-
- def state_bindparam(x, state, col):
- o = state.obj() # strong ref
- return sql.bindparam(x, unique=True, callable_=lambda : \
- self.property.mapper._get_committed_attr_by_column(o,
- col))
-
- def adapt(col):
- if self.adapter:
- return self.adapter(col)
- else:
- return col
-
- if self.property._use_get:
- return sql.and_(*[
- sql.or_(
- adapt(x) != state_bindparam(adapt(x), state, y),
- adapt(x) == None)
- for (x, y) in self.property.local_remote_pairs])
-
- criterion = sql.and_(*[x==y for (x, y) in
- zip(
- self.property.mapper.primary_key,
- self.property.\
- mapper.\
- primary_key_from_instance(other))
- ])
- return ~self._criterion_exists(criterion)
-
- def __ne__(self, other):
- if isinstance(other, (NoneType, expression._Null)):
- if self.property.direction == MANYTOONE:
- return sql.or_(*[x != None for x in
- self.property._calculated_foreign_keys])
- else:
- return self._criterion_exists()
- elif self.property.uselist:
- raise sa_exc.InvalidRequestError("Can't compare a collection"
- " to an object or collection; use "
- "contains() to test for membership.")
- else:
- return self.__negated_contains_or_equals(other)
-
- @util.memoized_property
- def property(self):
- if mapperlib.module._new_mappers:
- configure_mappers()
- return self.prop
-
- def compare(self, op, value,
- value_is_parent=False,
- alias_secondary=True):
- if op == operators.eq:
- if value is None:
- if self.uselist:
- return ~sql.exists([1], self.primaryjoin)
- else:
- return self._optimized_compare(None,
- value_is_parent=value_is_parent,
- alias_secondary=alias_secondary)
- else:
- return self._optimized_compare(value,
- value_is_parent=value_is_parent,
- alias_secondary=alias_secondary)
- else:
- return op(self.comparator, value)
-
- def _optimized_compare(self, value, value_is_parent=False,
- adapt_source=None,
- alias_secondary=True):
- if value is not None:
- value = attributes.instance_state(value)
- return self._get_strategy(strategies.LazyLoader).lazy_clause(value,
- reverse_direction=not value_is_parent,
- alias_secondary=alias_secondary,
- adapt_source=adapt_source)
-
- def __str__(self):
- return str(self.parent.class_.__name__) + "." + self.key
-
- def merge(self,
- session,
- source_state,
- source_dict,
- dest_state,
- dest_dict,
- load, _recursive):
- if load:
- # TODO: no test coverage for recursive check
- for r in self._reverse_property:
- if (source_state, r) in _recursive:
- return
-
- if not "merge" in self.cascade:
- return
-
- if self.key not in source_dict:
- return
-
- if self.uselist:
- instances = source_state.get_impl(self.key).\
- get(source_state, source_dict)
- if hasattr(instances, '_sa_adapter'):
- # convert collections to adapters to get a true iterator
- instances = instances._sa_adapter
-
- if load:
- # for a full merge, pre-load the destination collection,
- # so that individual _merge of each item pulls from identity
- # map for those already present.
- # also assumes CollectionAttrbiuteImpl behavior of loading
- # "old" list in any case
- dest_state.get_impl(self.key).get(dest_state, dest_dict)
-
- dest_list = []
- for current in instances:
- current_state = attributes.instance_state(current)
- current_dict = attributes.instance_dict(current)
- _recursive[(current_state, self)] = True
- obj = session._merge(current_state, current_dict,
- load=load, _recursive=_recursive)
- if obj is not None:
- dest_list.append(obj)
-
- if not load:
- coll = attributes.init_state_collection(dest_state,
- dest_dict, self.key)
- for c in dest_list:
- coll.append_without_event(c)
- else:
- dest_state.get_impl(self.key)._set_iterable(dest_state,
- dest_dict, dest_list)
- else:
- current = source_dict[self.key]
- if current is not None:
- current_state = attributes.instance_state(current)
- current_dict = attributes.instance_dict(current)
- _recursive[(current_state, self)] = True
- obj = session._merge(current_state, current_dict,
- load=load, _recursive=_recursive)
- else:
- obj = None
- if not load:
- dest_dict[self.key] = obj
- else:
- dest_state.get_impl(self.key).set(dest_state,
- dest_dict, obj, None)
-
- def cascade_iterator(self, type_, state, dict_, visited_states, halt_on=None):
- #assert type_ in self.cascade
-
- # only actively lazy load on the 'delete' cascade
- if type_ != 'delete' or self.passive_deletes:
- passive = attributes.PASSIVE_NO_INITIALIZE
- else:
- passive = attributes.PASSIVE_OFF
-
- if type_ == 'save-update':
- tuples = state.manager[self.key].impl.\
- get_all_pending(state, dict_)
-
- else:
- tuples = state.value_as_iterable(dict_, self.key,
- passive=passive)
-
- skip_pending = type_ == 'refresh-expire' and 'delete-orphan' \
- not in self.cascade
-
- for instance_state, c in tuples:
- if instance_state in visited_states:
- continue
-
- instance_dict = attributes.instance_dict(c)
-
- if halt_on and halt_on(instance_state):
- continue
-
- if skip_pending and not instance_state.key:
- continue
-
- instance_mapper = instance_state.manager.mapper
-
- if not instance_mapper.isa(self.mapper.class_manager.mapper):
- raise AssertionError("Attribute '%s' on class '%s' "
- "doesn't handle objects "
- "of type '%s'" % (
- self.key,
- self.parent.class_,
- c.__class__
- ))
-
- visited_states.add(instance_state)
-
- yield c, instance_mapper, instance_state, instance_dict
-
-
- def _add_reverse_property(self, key):
- other = self.mapper.get_property(key, _compile_mappers=False)
- self._reverse_property.add(other)
- other._reverse_property.add(self)
-
- if not other._get_target().common_parent(self.parent):
- raise sa_exc.ArgumentError('reverse_property %r on '
- 'relationship %s references relationship %s, which '
- 'does not reference mapper %s' % (key, self, other,
- self.parent))
- if self.direction in (ONETOMANY, MANYTOONE) and self.direction \
- == other.direction:
- raise sa_exc.ArgumentError('%s and back-reference %s are '
- 'both of the same direction %r. Did you mean to '
- 'set remote_side on the many-to-one side ?'
- % (other, self, self.direction))
-
- def do_init(self):
- self._get_target()
- self._assert_is_primary()
- self._process_dependent_arguments()
- self._determine_joins()
- self._determine_synchronize_pairs()
- self._determine_direction()
- self._determine_local_remote_pairs()
- self._post_init()
- self._generate_backref()
- super(RelationshipProperty, self).do_init()
-
- def _get_target(self):
- if not hasattr(self, 'mapper'):
- if isinstance(self.argument, type):
- self.mapper = mapper.class_mapper(self.argument,
- compile=False)
- elif isinstance(self.argument, mapper.Mapper):
- self.mapper = self.argument
- elif util.callable(self.argument):
-
- # accept a callable to suit various deferred-
- # configurational schemes
-
- self.mapper = mapper.class_mapper(self.argument(),
- compile=False)
- else:
- raise sa_exc.ArgumentError("relationship '%s' expects "
- "a class or a mapper argument (received: %s)"
- % (self.key, type(self.argument)))
- assert isinstance(self.mapper, mapper.Mapper), self.mapper
- return self.mapper
-
- def _process_dependent_arguments(self):
-
- # accept callables for other attributes which may require
- # deferred initialization
-
- for attr in (
- 'order_by',
- 'primaryjoin',
- 'secondaryjoin',
- 'secondary',
- '_user_defined_foreign_keys',
- 'remote_side',
- ):
- if util.callable(getattr(self, attr)):
- setattr(self, attr, getattr(self, attr)())
-
- # in the case that InstrumentedAttributes were used to construct
- # primaryjoin or secondaryjoin, remove the "_orm_adapt"
- # annotation so these interact with Query in the same way as the
- # original Table-bound Column objects
-
- for attr in 'primaryjoin', 'secondaryjoin':
- val = getattr(self, attr)
- if val is not None:
- setattr(self, attr, _orm_deannotate(
- expression._only_column_elements(val, attr))
- )
- if self.order_by is not False and self.order_by is not None:
- self.order_by = [expression._only_column_elements(x, "order_by") for x in
- util.to_list(self.order_by)]
- self._user_defined_foreign_keys = \
- util.column_set(expression._only_column_elements(x, "foreign_keys") for x in
- util.to_column_set(self._user_defined_foreign_keys))
- self.remote_side = \
- util.column_set(expression._only_column_elements(x, "remote_side") for x in
- util.to_column_set(self.remote_side))
- if not self.parent.concrete:
- for inheriting in self.parent.iterate_to_root():
- if inheriting is not self.parent \
- and inheriting.has_property(self.key):
- util.warn("Warning: relationship '%s' on mapper "
- "'%s' supersedes the same relationship "
- "on inherited mapper '%s'; this can "
- "cause dependency issues during flush"
- % (self.key, self.parent, inheriting))
-
- # TODO: remove 'self.table'
-
- self.target = self.table = self.mapper.mapped_table
- if self.cascade.delete_orphan:
- if self.parent.class_ is self.mapper.class_:
- raise sa_exc.ArgumentError("In relationship '%s', "
- "can't establish 'delete-orphan' cascade rule "
- "on a self-referential relationship. You "
- "probably want cascade='all', which includes "
- "delete cascading but not orphan detection."
- % str(self))
- self.mapper.primary_mapper().delete_orphans.append((self.key,
- self.parent.class_))
-
- def _determine_joins(self):
- if self.secondaryjoin is not None and self.secondary is None:
- raise sa_exc.ArgumentError("Property '" + self.key
- + "' specified with secondary join condition but "
- "no secondary argument")
-
- # if join conditions were not specified, figure them out based
- # on foreign keys
-
- def _search_for_join(mapper, table):
-
- # find a join between the given mapper's mapped table and
- # the given table. will try the mapper's local table first
- # for more specificity, then if not found will try the more
- # general mapped table, which in the case of inheritance is
- # a join.
-
- try:
- return join_condition(mapper.local_table, table)
- except sa_exc.ArgumentError, e:
- return join_condition(mapper.mapped_table, table)
-
- try:
- if self.secondary is not None:
- if self.secondaryjoin is None:
- self.secondaryjoin = _search_for_join(self.mapper,
- self.secondary)
- if self.primaryjoin is None:
- self.primaryjoin = _search_for_join(self.parent,
- self.secondary)
- else:
- if self.primaryjoin is None:
- self.primaryjoin = _search_for_join(self.parent,
- self.target)
- except sa_exc.ArgumentError, e:
- raise sa_exc.ArgumentError("Could not determine join "
- "condition between parent/child tables on "
- "relationship %s. Specify a 'primaryjoin' "
- "expression. If 'secondary' is present, "
- "'secondaryjoin' is needed as well."
- % self)
-
- def _col_is_part_of_mappings(self, column):
- if self.secondary is None:
- return self.parent.mapped_table.c.contains_column(column) or \
- self.target.c.contains_column(column)
- else:
- return self.parent.mapped_table.c.contains_column(column) or \
- self.target.c.contains_column(column) or \
- self.secondary.c.contains_column(column) is not None
-
- def _sync_pairs_from_join(self, join_condition, primary):
- """Given a join condition, figure out what columns are foreign
- and are part of a binary "equated" condition to their referenced
- columns, and convert into a list of tuples of (primary col->foreign col).
-
- Make several attempts to determine if cols are compared using
- "=" or other comparators (in which case suggest viewonly),
- columns are present but not part of the expected mappings, columns
- don't have any :class:`.ForeignKey` information on them, or
- the ``foreign_keys`` attribute is being used incorrectly.
-
- """
- eq_pairs = criterion_as_pairs(join_condition,
- consider_as_foreign_keys=self._user_defined_foreign_keys,
- any_operator=self.viewonly)
-
- eq_pairs = [(l, r) for (l, r) in eq_pairs
- if self._col_is_part_of_mappings(l)
- and self._col_is_part_of_mappings(r)
- or self.viewonly and r in self._user_defined_foreign_keys]
-
- if not eq_pairs and \
- self.secondary is not None and \
- not self._user_defined_foreign_keys:
- fks = set(self.secondary.c)
- eq_pairs = criterion_as_pairs(join_condition,
- consider_as_foreign_keys=fks,
- any_operator=self.viewonly)
-
- eq_pairs = [(l, r) for (l, r) in eq_pairs
- if self._col_is_part_of_mappings(l)
- and self._col_is_part_of_mappings(r)
- or self.viewonly and r in fks]
- if eq_pairs:
- util.warn("No ForeignKey objects were present "
- "in secondary table '%s'. Assumed referenced "
- "foreign key columns %s for join condition '%s' "
- "on relationship %s" % (
- self.secondary.description,
- ", ".join(sorted(["'%s'" % col for col in fks])),
- join_condition,
- self
- ))
-
- if not eq_pairs:
- if not self.viewonly and criterion_as_pairs(join_condition,
- consider_as_foreign_keys=self._user_defined_foreign_keys,
- any_operator=True):
-
- err = "Could not locate any "\
- "foreign-key-equated, locally mapped column "\
- "pairs for %s "\
- "condition '%s' on relationship %s." % (
- primary and 'primaryjoin' or 'secondaryjoin',
- join_condition,
- self
- )
-
- if not self._user_defined_foreign_keys:
- err += " Ensure that the "\
- "referencing Column objects have a "\
- "ForeignKey present, or are otherwise part "\
- "of a ForeignKeyConstraint on their parent "\
- "Table, or specify the foreign_keys parameter "\
- "to this relationship."
-
- err += " For more "\
- "relaxed rules on join conditions, the "\
- "relationship may be marked as viewonly=True."
-
- raise sa_exc.ArgumentError(err)
- else:
- if self._user_defined_foreign_keys:
- raise sa_exc.ArgumentError("Could not determine "
- "relationship direction for %s condition "
- "'%s', on relationship %s, using manual "
- "'foreign_keys' setting. Do the columns "
- "in 'foreign_keys' represent all, and "
- "only, the 'foreign' columns in this join "
- "condition? Does the %s Table already "
- "have adequate ForeignKey and/or "
- "ForeignKeyConstraint objects established "
- "(in which case 'foreign_keys' is usually "
- "unnecessary)?"
- % (
- primary and 'primaryjoin' or 'secondaryjoin',
- join_condition,
- self,
- primary and 'mapped' or 'secondary'
- ))
- else:
- raise sa_exc.ArgumentError("Could not determine "
- "relationship direction for %s condition "
- "'%s', on relationship %s. Ensure that the "
- "referencing Column objects have a "
- "ForeignKey present, or are otherwise part "
- "of a ForeignKeyConstraint on their parent "
- "Table, or specify the foreign_keys parameter "
- "to this relationship."
- % (
- primary and 'primaryjoin' or 'secondaryjoin',
- join_condition,
- self
- ))
- return eq_pairs
-
- def _determine_synchronize_pairs(self):
- if self.local_remote_pairs:
- if not self._user_defined_foreign_keys:
- raise sa_exc.ArgumentError('foreign_keys argument is '
- 'required with _local_remote_pairs argument')
- self.synchronize_pairs = []
- for l, r in self.local_remote_pairs:
- if r in self._user_defined_foreign_keys:
- self.synchronize_pairs.append((l, r))
- elif l in self._user_defined_foreign_keys:
- self.synchronize_pairs.append((r, l))
- else:
- eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True)
- self.synchronize_pairs = eq_pairs
- if self.secondaryjoin is not None:
- sq_pairs = self._sync_pairs_from_join(self.secondaryjoin, False)
- self.secondary_synchronize_pairs = sq_pairs
- else:
- self.secondary_synchronize_pairs = None
- self._calculated_foreign_keys = util.column_set(r for (l, r) in
- self.synchronize_pairs)
- if self.secondary_synchronize_pairs:
- self._calculated_foreign_keys.update(r for (l, r) in
- self.secondary_synchronize_pairs)
-
- def _determine_direction(self):
- if self.secondaryjoin is not None:
- self.direction = MANYTOMANY
- elif self._refers_to_parent_table():
-
- # self referential defaults to ONETOMANY unless the "remote"
- # side is present and does not reference any foreign key
- # columns
-
- if self.local_remote_pairs:
- remote = [r for (l, r) in self.local_remote_pairs]
- elif self.remote_side:
- remote = self.remote_side
- else:
- remote = None
- if not remote or self._calculated_foreign_keys.difference(l for (l,
- r) in self.synchronize_pairs).intersection(remote):
- self.direction = ONETOMANY
- else:
- self.direction = MANYTOONE
- else:
- foreign_keys = [f for (c, f) in self.synchronize_pairs]
- parentcols = util.column_set(self.parent.mapped_table.c)
- targetcols = util.column_set(self.mapper.mapped_table.c)
-
- # fk collection which suggests ONETOMANY.
-
- onetomany_fk = targetcols.intersection(foreign_keys)
-
- # fk collection which suggests MANYTOONE.
-
- manytoone_fk = parentcols.intersection(foreign_keys)
- if not onetomany_fk and not manytoone_fk:
- raise sa_exc.ArgumentError("Can't determine relationshi"
- "p direction for relationship '%s' - foreign "
- "key columns are present in neither the parent "
- "nor the child's mapped tables" % self)
- elif onetomany_fk and manytoone_fk:
-
- # fks on both sides. do the same test only based on the
- # local side.
-
- referents = [c for (c, f) in self.synchronize_pairs]
- onetomany_local = parentcols.intersection(referents)
- manytoone_local = targetcols.intersection(referents)
- if onetomany_local and not manytoone_local:
- self.direction = ONETOMANY
- elif manytoone_local and not onetomany_local:
- self.direction = MANYTOONE
- elif onetomany_fk:
- self.direction = ONETOMANY
- elif manytoone_fk:
- self.direction = MANYTOONE
- if not self.direction:
- raise sa_exc.ArgumentError("Can't determine relationship"
- " direction for relationship '%s' - foreign "
- "key columns are present in both the parent "
- "and the child's mapped tables. Specify "
- "'foreign_keys' argument." % self)
- if self.cascade.delete_orphan and not self.single_parent \
- and (self.direction is MANYTOMANY or self.direction
- is MANYTOONE):
- util.warn('On %s, delete-orphan cascade is not supported '
- 'on a many-to-many or many-to-one relationship '
- 'when single_parent is not set. Set '
- 'single_parent=True on the relationship().'
- % self)
- if self.direction is MANYTOONE and self.passive_deletes:
- util.warn("On %s, 'passive_deletes' is normally configured "
- "on one-to-many, one-to-one, many-to-many "
- "relationships only."
- % self)
-
- def _determine_local_remote_pairs(self):
- if not self.local_remote_pairs:
- if self.remote_side:
- if self.direction is MANYTOONE:
- self.local_remote_pairs = [(r, l) for (l, r) in
- criterion_as_pairs(self.primaryjoin,
- consider_as_referenced_keys=self.remote_side,
- any_operator=True)]
- else:
- self.local_remote_pairs = \
- criterion_as_pairs(self.primaryjoin,
- consider_as_foreign_keys=self.remote_side,
- any_operator=True)
- if not self.local_remote_pairs:
- raise sa_exc.ArgumentError('Relationship %s could '
- 'not determine any local/remote column '
- 'pairs from remote side argument %r'
- % (self, self.remote_side))
- else:
- if self.viewonly:
- eq_pairs = self.synchronize_pairs
- if self.secondaryjoin is not None:
- eq_pairs += self.secondary_synchronize_pairs
- else:
- eq_pairs = criterion_as_pairs(self.primaryjoin,
- consider_as_foreign_keys=self._calculated_foreign_keys,
- any_operator=True)
- if self.secondaryjoin is not None:
- eq_pairs += \
- criterion_as_pairs(self.secondaryjoin,
- consider_as_foreign_keys=self._calculated_foreign_keys,
- any_operator=True)
- eq_pairs = [(l, r) for (l, r) in eq_pairs
- if self._col_is_part_of_mappings(l)
- and self._col_is_part_of_mappings(r)]
- if self.direction is MANYTOONE:
- self.local_remote_pairs = [(r, l) for (l, r) in
- eq_pairs]
- else:
- self.local_remote_pairs = eq_pairs
- elif self.remote_side:
- raise sa_exc.ArgumentError('remote_side argument is '
- 'redundant against more detailed '
- '_local_remote_side argument.')
- for l, r in self.local_remote_pairs:
- if self.direction is ONETOMANY \
- and not self._col_is_part_of_mappings(l):
- raise sa_exc.ArgumentError("Local column '%s' is not "
- "part of mapping %s. Specify remote_side "
- "argument to indicate which column lazy join "
- "condition should compare against." % (l,
- self.parent))
- elif self.direction is MANYTOONE \
- and not self._col_is_part_of_mappings(r):
- raise sa_exc.ArgumentError("Remote column '%s' is not "
- "part of mapping %s. Specify remote_side "
- "argument to indicate which column lazy join "
- "condition should bind." % (r, self.mapper))
- self.local_side, self.remote_side = [util.ordered_column_set(x)
- for x in zip(*list(self.local_remote_pairs))]
-
- def _assert_is_primary(self):
- if not self.is_primary() \
- and not mapper.class_mapper(self.parent.class_,
- compile=False).has_property(self.key):
- raise sa_exc.ArgumentError("Attempting to assign a new "
- "relationship '%s' to a non-primary mapper on "
- "class '%s'. New relationships can only be added "
- "to the primary mapper, i.e. the very first mapper "
- "created for class '%s' " % (self.key,
- self.parent.class_.__name__,
- self.parent.class_.__name__))
-
- def _generate_backref(self):
- if not self.is_primary():
- return
- if self.backref is not None and not self.back_populates:
- if isinstance(self.backref, basestring):
- backref_key, kwargs = self.backref, {}
- else:
- backref_key, kwargs = self.backref
- mapper = self.mapper.primary_mapper()
- if mapper.has_property(backref_key):
- raise sa_exc.ArgumentError("Error creating backref "
- "'%s' on relationship '%s': property of that "
- "name exists on mapper '%s'" % (backref_key,
- self, mapper))
- if self.secondary is not None:
- pj = kwargs.pop('primaryjoin', self.secondaryjoin)
- sj = kwargs.pop('secondaryjoin', self.primaryjoin)
- else:
- pj = kwargs.pop('primaryjoin', self.primaryjoin)
- sj = kwargs.pop('secondaryjoin', None)
- if sj:
- raise sa_exc.InvalidRequestError(
- "Can't assign 'secondaryjoin' on a backref against "
- "a non-secondary relationship."
- )
- foreign_keys = kwargs.pop('foreign_keys',
- self._user_defined_foreign_keys)
- parent = self.parent.primary_mapper()
- kwargs.setdefault('viewonly', self.viewonly)
- kwargs.setdefault('post_update', self.post_update)
- kwargs.setdefault('passive_updates', self.passive_updates)
- self.back_populates = backref_key
- relationship = RelationshipProperty(
- parent,
- self.secondary,
- pj,
- sj,
- foreign_keys=foreign_keys,
- back_populates=self.key,
- **kwargs
- )
- mapper._configure_property(backref_key, relationship)
- if self.back_populates:
- self._add_reverse_property(self.back_populates)
-
- def _post_init(self):
- self.logger.info('%s setup primary join %s', self,
- self.primaryjoin)
- self.logger.info('%s setup secondary join %s', self,
- self.secondaryjoin)
- self.logger.info('%s synchronize pairs [%s]', self,
- ','.join('(%s => %s)' % (l, r) for (l, r) in
- self.synchronize_pairs))
- self.logger.info('%s secondary synchronize pairs [%s]', self,
- ','.join('(%s => %s)' % (l, r) for (l, r) in
- self.secondary_synchronize_pairs or []))
- self.logger.info('%s local/remote pairs [%s]', self,
- ','.join('(%s / %s)' % (l, r) for (l, r) in
- self.local_remote_pairs))
- self.logger.info('%s relationship direction %s', self,
- self.direction)
- if self.uselist is None:
- self.uselist = self.direction is not MANYTOONE
- if not self.viewonly:
- self._dependency_processor = \
- dependency.DependencyProcessor.from_relationship(self)
-
- @util.memoized_property
- def _use_get(self):
- """memoize the 'use_get' attribute of this RelationshipLoader's
- lazyloader."""
-
- strategy = self._get_strategy(strategies.LazyLoader)
- return strategy.use_get
-
- def _refers_to_parent_table(self):
- pt = self.parent.mapped_table
- mt = self.mapper.mapped_table
- for c, f in self.synchronize_pairs:
- if (
- pt.is_derived_from(c.table) and \
- pt.is_derived_from(f.table) and \
- mt.is_derived_from(c.table) and \
- mt.is_derived_from(f.table)
- ):
- return True
- else:
- return False
-
- def _is_self_referential(self):
- return self.mapper.common_parent(self.parent)
-
- def per_property_preprocessors(self, uow):
- if not self.viewonly and self._dependency_processor:
- self._dependency_processor.per_property_preprocessors(uow)
-
- def _create_joins(self, source_polymorphic=False,
- source_selectable=None, dest_polymorphic=False,
- dest_selectable=None, of_type=None):
- if source_selectable is None:
- if source_polymorphic and self.parent.with_polymorphic:
- source_selectable = self.parent._with_polymorphic_selectable
-
- aliased = False
- if dest_selectable is None:
- if dest_polymorphic and self.mapper.with_polymorphic:
- dest_selectable = self.mapper._with_polymorphic_selectable
- aliased = True
- else:
- dest_selectable = self.mapper.mapped_table
-
- if self._is_self_referential() and source_selectable is None:
- dest_selectable = dest_selectable.alias()
- aliased = True
- else:
- aliased = True
-
- aliased = aliased or (source_selectable is not None)
-
- primaryjoin, secondaryjoin, secondary = self.primaryjoin, \
- self.secondaryjoin, self.secondary
-
- # adjust the join condition for single table inheritance,
- # in the case that the join is to a subclass
- # this is analogous to the "_adjust_for_single_table_inheritance()"
- # method in Query.
-
- dest_mapper = of_type or self.mapper
-
- single_crit = dest_mapper._single_table_criterion
- if single_crit is not None:
- if secondaryjoin is not None:
- secondaryjoin = secondaryjoin & single_crit
- else:
- primaryjoin = primaryjoin & single_crit
-
- if aliased:
- if secondary is not None:
- secondary = secondary.alias()
- primary_aliasizer = ClauseAdapter(secondary)
- if dest_selectable is not None:
- secondary_aliasizer = \
- ClauseAdapter(dest_selectable,
- equivalents=self.mapper._equivalent_columns).\
- chain(primary_aliasizer)
- else:
- secondary_aliasizer = primary_aliasizer
- if source_selectable is not None:
- primary_aliasizer = \
- ClauseAdapter(secondary).\
- chain(ClauseAdapter(source_selectable,
- equivalents=self.parent._equivalent_columns))
- secondaryjoin = \
- secondary_aliasizer.traverse(secondaryjoin)
- else:
- if dest_selectable is not None:
- primary_aliasizer = ClauseAdapter(dest_selectable,
- exclude=self.local_side,
- equivalents=self.mapper._equivalent_columns)
- if source_selectable is not None:
- primary_aliasizer.chain(
- ClauseAdapter(source_selectable,
- exclude=self.remote_side,
- equivalents=self.parent._equivalent_columns))
- elif source_selectable is not None:
- primary_aliasizer = \
- ClauseAdapter(source_selectable,
- exclude=self.remote_side,
- equivalents=self.parent._equivalent_columns)
- secondary_aliasizer = None
- primaryjoin = primary_aliasizer.traverse(primaryjoin)
- target_adapter = secondary_aliasizer or primary_aliasizer
- target_adapter.include = target_adapter.exclude = None
- else:
- target_adapter = None
- if source_selectable is None:
- source_selectable = self.parent.local_table
- if dest_selectable is None:
- dest_selectable = self.mapper.local_table
- return (
- primaryjoin,
- secondaryjoin,
- source_selectable,
- dest_selectable,
- secondary,
- target_adapter,
- )
-
-
-PropertyLoader = RelationProperty = RelationshipProperty
-log.class_logger(RelationshipProperty)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py
deleted file mode 100755
index 54e864ab..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py
+++ /dev/null
@@ -1,2936 +0,0 @@
-# orm/query.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""The Query class and support.
-
-Defines the :class:`.Query` class, the central
-construct used by the ORM to construct database queries.
-
-The :class:`.Query` class should not be confused with the
-:class:`.Select` class, which defines database
-SELECT operations at the SQL (non-ORM) level. ``Query`` differs from
-``Select`` in that it returns ORM-mapped objects and interacts with an
-ORM session, whereas the ``Select`` construct interacts directly with the
-database to return iterable result sets.
-
-"""
-
-from itertools import chain
-from operator import itemgetter
-
-from sqlalchemy import sql, util, log, schema
-from sqlalchemy import exc as sa_exc
-from sqlalchemy.orm import exc as orm_exc
-from sqlalchemy.sql import util as sql_util
-from sqlalchemy.sql import expression, visitors, operators
-from sqlalchemy.orm import (
- attributes, interfaces, mapper, object_mapper, evaluator,
- )
-from sqlalchemy.orm.util import (
- AliasedClass, ORMAdapter, _entity_descriptor, _entity_info,
- _is_aliased_class, _is_mapped_class, _orm_columns, _orm_selectable,
- join as orm_join,with_parent, _attr_as_key, aliased
- )
-
-
-__all__ = ['Query', 'QueryContext', 'aliased']
-
-
-def _generative(*assertions):
- """Mark a method as generative."""
-
- @util.decorator
- def generate(fn, *args, **kw):
- self = args[0]._clone()
- for assertion in assertions:
- assertion(self, fn.func_name)
- fn(self, *args[1:], **kw)
- return self
- return generate
-
-class Query(object):
- """ORM-level SQL construction object.
-
- :class:`.Query` is the source of all SELECT statements generated by the
- ORM, both those formulated by end-user query operations as well as by
- high level internal operations such as related collection loading. It
- features a generative interface whereby successive calls return a new
- :class:`.Query` object, a copy of the former with additional
- criteria and options associated with it.
-
- :class:`.Query` objects are normally initially generated using the
- :meth:`~.Session.query` method of :class:`.Session`. For a full walkthrough
- of :class:`.Query` usage, see the :ref:`ormtutorial_toplevel`.
-
- """
-
- _enable_eagerloads = True
- _enable_assertions = True
- _with_labels = False
- _criterion = None
- _yield_per = None
- _lockmode = None
- _order_by = False
- _group_by = False
- _having = None
- _distinct = False
- _offset = None
- _limit = None
- _statement = None
- _correlate = frozenset()
- _populate_existing = False
- _version_check = False
- _autoflush = True
- _current_path = ()
- _only_load_props = None
- _refresh_state = None
- _from_obj = ()
- _select_from_entity = None
- _filter_aliases = None
- _from_obj_alias = None
- _joinpath = _joinpoint = util.immutabledict()
- _execution_options = util.immutabledict()
- _params = util.immutabledict()
- _attributes = util.immutabledict()
- _with_options = ()
- _with_hints = ()
- _enable_single_crit = True
-
- def __init__(self, entities, session=None):
- self.session = session
- self._polymorphic_adapters = {}
- self._set_entities(entities)
-
- def _set_entities(self, entities, entity_wrapper=None):
- if entity_wrapper is None:
- entity_wrapper = _QueryEntity
- self._entities = []
- for ent in util.to_list(entities):
- entity_wrapper(self, ent)
-
- self._setup_aliasizers(self._entities)
-
- def _setup_aliasizers(self, entities):
- if hasattr(self, '_mapper_adapter_map'):
- # usually safe to share a single map, but copying to prevent
- # subtle leaks if end-user is reusing base query with arbitrary
- # number of aliased() objects
- self._mapper_adapter_map = d = self._mapper_adapter_map.copy()
- else:
- self._mapper_adapter_map = d = {}
-
- for ent in entities:
- for entity in ent.entities:
- if entity not in d:
- mapper, selectable, is_aliased_class = \
- _entity_info(entity)
- if not is_aliased_class and mapper.with_polymorphic:
- with_polymorphic = mapper._with_polymorphic_mappers
- if mapper.mapped_table not in \
- self._polymorphic_adapters:
- self.__mapper_loads_polymorphically_with(mapper,
- sql_util.ColumnAdapter(
- selectable,
- mapper._equivalent_columns))
- adapter = None
- elif is_aliased_class:
- adapter = sql_util.ColumnAdapter(
- selectable,
- mapper._equivalent_columns)
- with_polymorphic = None
- else:
- with_polymorphic = adapter = None
-
- d[entity] = (mapper, adapter, selectable,
- is_aliased_class, with_polymorphic)
- ent.setup_entity(entity, *d[entity])
-
- def __mapper_loads_polymorphically_with(self, mapper, adapter):
- for m2 in mapper._with_polymorphic_mappers:
- self._polymorphic_adapters[m2] = adapter
- for m in m2.iterate_to_root():
- self._polymorphic_adapters[m.mapped_table] = \
- self._polymorphic_adapters[m.local_table] = \
- adapter
-
- def _set_select_from(self, *obj):
-
- fa = []
- for from_obj in obj:
- if isinstance(from_obj, expression._SelectBase):
- from_obj = from_obj.alias()
- fa.append(from_obj)
-
- self._from_obj = tuple(fa)
-
- if len(self._from_obj) == 1 and \
- isinstance(self._from_obj[0], expression.Alias):
- equivs = self.__all_equivs()
- self._from_obj_alias = sql_util.ColumnAdapter(
- self._from_obj[0], equivs)
-
- def _get_polymorphic_adapter(self, entity, selectable):
- self.__mapper_loads_polymorphically_with(entity.mapper,
- sql_util.ColumnAdapter(selectable,
- entity.mapper._equivalent_columns))
-
- def _reset_polymorphic_adapter(self, mapper):
- for m2 in mapper._with_polymorphic_mappers:
- self._polymorphic_adapters.pop(m2, None)
- for m in m2.iterate_to_root():
- self._polymorphic_adapters.pop(m.mapped_table, None)
- self._polymorphic_adapters.pop(m.local_table, None)
-
- def __adapt_polymorphic_element(self, element):
- if isinstance(element, expression.FromClause):
- search = element
- elif hasattr(element, 'table'):
- search = element.table
- else:
- search = None
-
- if search is not None:
- alias = self._polymorphic_adapters.get(search, None)
- if alias:
- return alias.adapt_clause(element)
-
- def _adapt_col_list(self, cols):
- return [
- self._adapt_clause(
- expression._literal_as_text(o),
- True, True)
- for o in cols
- ]
-
- @_generative()
- def _adapt_all_clauses(self):
- self._orm_only_adapt = False
-
- def _adapt_clause(self, clause, as_filter, orm_only):
- """Adapt incoming clauses to transformations which have been applied
- within this query."""
-
- adapters = []
-
- # do we adapt all expression elements or only those
- # tagged as 'ORM' constructs ?
- orm_only = getattr(self, '_orm_only_adapt', orm_only)
-
- if as_filter and self._filter_aliases:
- for fa in self._filter_aliases._visitor_iterator:
- adapters.append(
- (
- orm_only, fa.replace
- )
- )
-
- if self._from_obj_alias:
- # for the "from obj" alias, apply extra rule to the
- # 'ORM only' check, if this query were generated from a
- # subquery of itself, i.e. _from_selectable(), apply adaption
- # to all SQL constructs.
- adapters.append(
- (
- getattr(self, '_orm_only_from_obj_alias', orm_only),
- self._from_obj_alias.replace
- )
- )
-
- if self._polymorphic_adapters:
- adapters.append(
- (
- orm_only, self.__adapt_polymorphic_element
- )
- )
-
- if not adapters:
- return clause
-
- def replace(elem):
- if '_halt_adapt' in elem._annotations:
- return elem
-
- for _orm_only, adapter in adapters:
- # if 'orm only', look for ORM annotations
- # in the element before adapting.
- if not _orm_only or \
- '_orm_adapt' in elem._annotations or \
- "parententity" in elem._annotations:
-
- e = adapter(elem)
- if e is not None:
- return e
-
- return visitors.replacement_traverse(
- clause,
- {'column_collections':False},
- replace
- )
-
- def _entity_zero(self):
- return self._entities[0]
-
- def _mapper_zero(self):
- return self._select_from_entity or \
- self._entity_zero().entity_zero
-
- @property
- def _mapper_entities(self):
- # TODO: this is wrong, its hardcoded to "primary entity" when
- # for the case of __all_equivs() it should not be
- # the name of this accessor is wrong too
- for ent in self._entities:
- if hasattr(ent, 'primary_entity'):
- yield ent
-
- def _joinpoint_zero(self):
- return self._joinpoint.get(
- '_joinpoint_entity',
- self._mapper_zero()
- )
-
- def _mapper_zero_or_none(self):
- if not getattr(self._entities[0], 'primary_entity', False):
- return None
- return self._entities[0].mapper
-
- def _only_mapper_zero(self, rationale=None):
- if len(self._entities) > 1:
- raise sa_exc.InvalidRequestError(
- rationale or
- "This operation requires a Query against a single mapper."
- )
- return self._mapper_zero()
-
- def _only_full_mapper_zero(self, methname):
- if len(self._entities) != 1:
- raise sa_exc.InvalidRequestError(
- "%s() can only be used against "
- "a single mapped class." % methname)
- entity = self._entity_zero()
- if not hasattr(entity, 'primary_entity'):
- raise sa_exc.InvalidRequestError(
- "%s() can only be used against "
- "a single mapped class." % methname)
- return entity.entity_zero
-
- def _only_entity_zero(self, rationale=None):
- if len(self._entities) > 1:
- raise sa_exc.InvalidRequestError(
- rationale or
- "This operation requires a Query against a single mapper."
- )
- return self._entity_zero()
-
- def _generate_mapper_zero(self):
- if not getattr(self._entities[0], 'primary_entity', False):
- raise sa_exc.InvalidRequestError(
- "No primary mapper set up for this Query.")
- entity = self._entities[0]._clone()
- self._entities = [entity] + self._entities[1:]
- return entity
-
- def __all_equivs(self):
- equivs = {}
- for ent in self._mapper_entities:
- equivs.update(ent.mapper._equivalent_columns)
- return equivs
-
- def _get_condition(self):
- self._order_by = self._distinct = False
- return self._no_criterion_condition("get")
-
- def _no_criterion_condition(self, meth):
- if not self._enable_assertions:
- return
- if self._criterion is not None or \
- self._statement is not None or self._from_obj or \
- self._limit is not None or self._offset is not None or \
- self._group_by or self._order_by or self._distinct:
- raise sa_exc.InvalidRequestError(
- "Query.%s() being called on a "
- "Query with existing criterion. " % meth)
-
- self._from_obj = ()
- self._statement = self._criterion = None
- self._order_by = self._group_by = self._distinct = False
-
- def _no_clauseelement_condition(self, meth):
- if not self._enable_assertions:
- return
- if self._order_by:
- raise sa_exc.InvalidRequestError(
- "Query.%s() being called on a "
- "Query with existing criterion. " % meth)
- self._no_criterion_condition(meth)
-
- def _no_statement_condition(self, meth):
- if not self._enable_assertions:
- return
- if self._statement:
- raise sa_exc.InvalidRequestError(
- ("Query.%s() being called on a Query with an existing full "
- "statement - can't apply criterion.") % meth)
-
- def _no_limit_offset(self, meth):
- if not self._enable_assertions:
- return
- if self._limit is not None or self._offset is not None:
- raise sa_exc.InvalidRequestError(
- "Query.%s() being called on a Query which already has LIMIT "
- "or OFFSET applied. To modify the row-limited results of a "
- " Query, call from_self() first. "
- "Otherwise, call %s() before limit() or offset() are applied."
- % (meth, meth)
- )
-
- def _no_select_modifiers(self, meth):
- if not self._enable_assertions:
- return
- for attr, methname, notset in (
- ('_limit', 'limit()', None),
- ('_offset', 'offset()', None),
- ('_order_by', 'order_by()', False),
- ('_group_by', 'group_by()', False),
- ('_distinct', 'distinct()', False),
- ):
- if getattr(self, attr) is not notset:
- raise sa_exc.InvalidRequestError(
- "Can't call Query.%s() when %s has been called" %
- (meth, methname)
- )
-
- def _get_options(self, populate_existing=None,
- version_check=None,
- only_load_props=None,
- refresh_state=None):
- if populate_existing:
- self._populate_existing = populate_existing
- if version_check:
- self._version_check = version_check
- if refresh_state:
- self._refresh_state = refresh_state
- if only_load_props:
- self._only_load_props = set(only_load_props)
- return self
-
- def _clone(self):
- cls = self.__class__
- q = cls.__new__(cls)
- q.__dict__ = self.__dict__.copy()
- return q
-
- @property
- def statement(self):
- """The full SELECT statement represented by this Query.
-
- The statement by default will not have disambiguating labels
- applied to the construct unless with_labels(True) is called
- first.
-
- """
-
- stmt = self._compile_context(labels=self._with_labels).\
- statement
- if self._params:
- stmt = stmt.params(self._params)
- return stmt._annotate({'_halt_adapt': True})
-
- def subquery(self, name=None):
- """return the full SELECT statement represented by this :class:`.Query`,
- embedded within an :class:`.Alias`.
-
- Eager JOIN generation within the query is disabled.
-
- The statement will not have disambiguating labels
- applied to the list of selected columns unless the
- :meth:`.Query.with_labels` method is used to generate a new
- :class:`.Query` with the option enabled.
-
- :param name: string name to be assigned as the alias;
- this is passed through to :meth:`.FromClause.alias`.
- If ``None``, a name will be deterministically generated
- at compile time.
-
-
- """
- return self.enable_eagerloads(False).statement.alias(name=name)
-
- def label(self, name):
- """Return the full SELECT statement represented by this :class:`.Query`, converted
- to a scalar subquery with a label of the given name.
-
- Analogous to :meth:`sqlalchemy.sql._SelectBaseMixin.label`.
-
- New in 0.6.5.
-
- """
-
- return self.enable_eagerloads(False).statement.label(name)
-
-
- def as_scalar(self):
- """Return the full SELECT statement represented by this :class:`.Query`, converted
- to a scalar subquery.
-
- Analogous to :meth:`sqlalchemy.sql._SelectBaseMixin.as_scalar`.
-
- New in 0.6.5.
-
- """
-
- return self.enable_eagerloads(False).statement.as_scalar()
-
-
- def __clause_element__(self):
- return self.enable_eagerloads(False).with_labels().statement
-
- @_generative()
- def enable_eagerloads(self, value):
- """Control whether or not eager joins and subqueries are
- rendered.
-
- When set to False, the returned Query will not render
- eager joins regardless of :func:`~sqlalchemy.orm.joinedload`,
- :func:`~sqlalchemy.orm.subqueryload` options
- or mapper-level ``lazy='joined'``/``lazy='subquery'``
- configurations.
-
- This is used primarily when nesting the Query's
- statement into a subquery or other
- selectable.
-
- """
- self._enable_eagerloads = value
-
- @_generative()
- def with_labels(self):
- """Apply column labels to the return value of Query.statement.
-
- Indicates that this Query's `statement` accessor should return
- a SELECT statement that applies labels to all columns in the
- form <tablename>_<columnname>; this is commonly used to
- disambiguate columns from multiple tables which have the same
- name.
-
- When the `Query` actually issues SQL to load rows, it always
- uses column labeling.
-
- """
- self._with_labels = True
-
- @_generative()
- def enable_assertions(self, value):
- """Control whether assertions are generated.
-
- When set to False, the returned Query will
- not assert its state before certain operations,
- including that LIMIT/OFFSET has not been applied
- when filter() is called, no criterion exists
- when get() is called, and no "from_statement()"
- exists when filter()/order_by()/group_by() etc.
- is called. This more permissive mode is used by
- custom Query subclasses to specify criterion or
- other modifiers outside of the usual usage patterns.
-
- Care should be taken to ensure that the usage
- pattern is even possible. A statement applied
- by from_statement() will override any criterion
- set by filter() or order_by(), for example.
-
- """
- self._enable_assertions = value
-
- @property
- def whereclause(self):
- """A readonly attribute which returns the current WHERE criterion for this Query.
-
- This returned value is a SQL expression construct, or ``None`` if no
- criterion has been established.
-
- """
- return self._criterion
-
- @_generative()
- def _with_current_path(self, path):
- """indicate that this query applies to objects loaded
- within a certain path.
-
- Used by deferred loaders (see strategies.py) which transfer
- query options from an originating query to a newly generated
- query intended for the deferred load.
-
- """
- self._current_path = path
-
- @_generative(_no_clauseelement_condition)
- def with_polymorphic(self,
- cls_or_mappers,
- selectable=None, discriminator=None):
- """Load columns for descendant mappers of this Query's mapper.
-
- Using this method will ensure that each descendant mapper's
- tables are included in the FROM clause, and will allow filter()
- criterion to be used against those tables. The resulting
- instances will also have those columns already loaded so that
- no "post fetch" of those columns will be required.
-
- :param cls_or_mappers: a single class or mapper, or list of
- class/mappers, which inherit from this Query's mapper.
- Alternatively, it may also be the string ``'*'``, in which case
- all descending mappers will be added to the FROM clause.
-
- :param selectable: a table or select() statement that will
- be used in place of the generated FROM clause. This argument is
- required if any of the desired mappers use concrete table
- inheritance, since SQLAlchemy currently cannot generate UNIONs
- among tables automatically. If used, the ``selectable`` argument
- must represent the full set of tables and columns mapped by every
- desired mapper. Otherwise, the unaccounted mapped columns will
- result in their table being appended directly to the FROM clause
- which will usually lead to incorrect results.
-
- :param discriminator: a column to be used as the "discriminator"
- column for the given selectable. If not given, the polymorphic_on
- attribute of the mapper will be used, if any. This is useful for
- mappers that don't have polymorphic loading behavior by default,
- such as concrete table mappers.
-
- """
- entity = self._generate_mapper_zero()
- entity.set_with_polymorphic(self,
- cls_or_mappers,
- selectable=selectable,
- discriminator=discriminator)
-
- @_generative()
- def yield_per(self, count):
- """Yield only ``count`` rows at a time.
-
- WARNING: use this method with caution; if the same instance is present
- in more than one batch of rows, end-user changes to attributes will be
- overwritten.
-
- In particular, it's usually impossible to use this setting with
- eagerly loaded collections (i.e. any lazy='joined' or 'subquery')
- since those collections will be cleared for a new load when
- encountered in a subsequent result batch. In the case of 'subquery'
- loading, the full result for all rows is fetched which generally
- defeats the purpose of :meth:`~sqlalchemy.orm.query.Query.yield_per`.
-
- Also note that many DBAPIs do not "stream" results, pre-buffering
- all rows before making them available, including mysql-python and
- psycopg2. :meth:`~sqlalchemy.orm.query.Query.yield_per` will also
- set the ``stream_results`` execution
- option to ``True``, which currently is only understood by psycopg2
- and causes server side cursors to be used.
-
- """
- self._yield_per = count
- self._execution_options = self._execution_options.copy()
- self._execution_options['stream_results'] = True
-
- def get(self, ident):
- """Return an instance of the object based on the
- given identifier, or ``None`` if not found.
-
- The ``ident`` argument is a scalar or tuple of
- primary key column values
- in the order of the mapper's "primary key" setting, which
- defaults to the list of primary key columns for the
- mapped :class:`.Table`.
-
- :meth:`get` returns only a single mapped instance, or
- ``None``. It is not intended to return rows or scalar
- column values, therefore the :class:`.Query` must be
- constructed only against a single mapper or mapped class,
- not a SQL expression or multiple entities.
- Other usages raise an error.
-
- """
-
- # convert composite types to individual args
- if hasattr(ident, '__composite_values__'):
- ident = ident.__composite_values__()
-
- ident = util.to_list(ident)
-
- mapper = self._only_full_mapper_zero("get")
-
- if len(ident) != len(mapper.primary_key):
- raise sa_exc.InvalidRequestError(
- "Incorrect number of values in identifier to formulate "
- "primary key for query.get(); primary key columns are %s" %
- ','.join("'%s'" % c for c in mapper.primary_key))
-
- key = mapper.identity_key_from_primary_key(ident)
-
- if not self._populate_existing and \
- not mapper.always_refresh and \
- self._lockmode is None:
-
- instance = self._get_from_identity(self.session, key, False)
- if instance is not None:
- # reject calls for id in identity map but class
- # mismatch.
- if not issubclass(instance.__class__, mapper.class_):
- return None
- return instance
-
- return self._load_on_ident(key)
-
- @_generative()
- def correlate(self, *args):
- """Return a :class:`.Query` construct which will correlate the given
- FROM clauses to that of an enclosing :class:`.Query` or
- :func:`~.expression.select`.
-
- The method here accepts mapped classes, :func:`.aliased` constructs,
- and :func:`.mapper` constructs as arguments, which are resolved into
- expression constructs, in addition to appropriate expression
- constructs.
-
- The correlation arguments are ultimately passed to
- :meth:`.Select.correlate` after coercion to expression constructs.
-
- The correlation arguments take effect in such cases
- as when :meth:`.Query.from_self` is used, or when
- a subquery as returned by :meth:`.Query.subquery` is
- embedded in another :func:`~.expression.select` construct.
-
- """
-
- self._correlate = self._correlate.union(
- _orm_selectable(s)
- for s in args)
-
- @_generative()
- def autoflush(self, setting):
- """Return a Query with a specific 'autoflush' setting.
-
- Note that a Session with autoflush=False will
- not autoflush, even if this flag is set to True at the
- Query level. Therefore this flag is usually used only
- to disable autoflush for a specific Query.
-
- """
- self._autoflush = setting
-
- @_generative()
- def populate_existing(self):
- """Return a :class:`.Query` that will expire and refresh all instances
- as they are loaded, or reused from the current :class:`.Session`.
-
- :meth:`.populate_existing` does not improve behavior when
- the ORM is used normally - the :class:`.Session` object's usual
- behavior of maintaining a transaction and expiring all attributes
- after rollback or commit handles object state automatically.
- This method is not intended for general use.
-
- """
- self._populate_existing = True
-
- def with_parent(self, instance, property=None):
- """Add filtering criterion that relates the given instance
- to a child object or collection, using its attribute state
- as well as an established :func:`.relationship()`
- configuration.
-
- The method uses the :func:`.with_parent` function to generate
- the clause, the result of which is passed to :meth:`.Query.filter`.
-
- Parameters are the same as :func:`.with_parent`, with the exception
- that the given property can be None, in which case a search is
- performed against this :class:`.Query` object's target mapper.
-
- """
-
- if property is None:
- from sqlalchemy.orm import properties
- mapper = object_mapper(instance)
-
- for prop in mapper.iterate_properties:
- if isinstance(prop, properties.PropertyLoader) and \
- prop.mapper is self._mapper_zero():
- property = prop
- break
- else:
- raise sa_exc.InvalidRequestError(
- "Could not locate a property which relates instances "
- "of class '%s' to instances of class '%s'" %
- (
- self._mapper_zero().class_.__name__,
- instance.__class__.__name__)
- )
-
- return self.filter(with_parent(instance, property))
-
- @_generative()
- def add_entity(self, entity, alias=None):
- """add a mapped entity to the list of result columns
- to be returned."""
-
- if alias is not None:
- entity = aliased(entity, alias)
-
- self._entities = list(self._entities)
- m = _MapperEntity(self, entity)
- self._setup_aliasizers([m])
-
- @_generative()
- def with_session(self, session):
- """Return a :class:`Query` that will use the given :class:`.Session`.
-
- """
-
- self.session = session
-
- def from_self(self, *entities):
- """return a Query that selects from this Query's
- SELECT statement.
-
- \*entities - optional list of entities which will replace
- those being selected.
-
- """
- fromclause = self.with_labels().enable_eagerloads(False).\
- _enable_single_crit(False).\
- statement.correlate(None)
- q = self._from_selectable(fromclause)
- if entities:
- q._set_entities(entities)
- return q
-
- @_generative()
- def _enable_single_crit(self, val):
- self._enable_single_crit = val
-
- @_generative()
- def _from_selectable(self, fromclause):
- for attr in (
- '_statement', '_criterion',
- '_order_by', '_group_by',
- '_limit', '_offset',
- '_joinpath', '_joinpoint',
- '_distinct', '_having'
- ):
- self.__dict__.pop(attr, None)
- self._set_select_from(fromclause)
-
- # this enables clause adaptation for non-ORM
- # expressions.
- self._orm_only_from_obj_alias = False
-
- old_entities = self._entities
- self._entities = []
- for e in old_entities:
- e.adapt_to_selectable(self, self._from_obj[0])
-
- def values(self, *columns):
- """Return an iterator yielding result tuples corresponding
- to the given list of columns"""
-
- if not columns:
- return iter(())
- q = self._clone()
- q._set_entities(columns, entity_wrapper=_ColumnEntity)
- if not q._yield_per:
- q._yield_per = 10
- return iter(q)
- _values = values
-
- def value(self, column):
- """Return a scalar result corresponding to the given
- column expression."""
- try:
- # Py3K
- #return self.values(column).__next__()[0]
- # Py2K
- return self.values(column).next()[0]
- # end Py2K
- except StopIteration:
- return None
-
- @_generative()
- def with_entities(self, *entities):
- """Return a new :class:`.Query` replacing the SELECT list with the given
- entities.
-
- e.g.::
-
- # Users, filtered on some arbitrary criterion
- # and then ordered by related email address
- q = session.query(User).\\
- join(User.address).\\
- filter(User.name.like('%ed%')).\\
- order_by(Address.email)
-
- # given *only* User.id==5, Address.email, and 'q', what
- # would the *next* User in the result be ?
- subq = q.with_entities(Address.email).\\
- order_by(None).\\
- filter(User.id==5).\\
- subquery()
- q = q.join((subq, subq.c.email < Address.email)).\\
- limit(1)
-
- New in 0.6.5.
-
- """
- self._set_entities(entities)
-
-
- @_generative()
- def add_columns(self, *column):
- """Add one or more column expressions to the list
- of result columns to be returned."""
-
- self._entities = list(self._entities)
- l = len(self._entities)
- for c in column:
- _ColumnEntity(self, c)
- # _ColumnEntity may add many entities if the
- # given arg is a FROM clause
- self._setup_aliasizers(self._entities[l:])
-
- @util.pending_deprecation("0.7",
- ":meth:`.add_column` is superseded by :meth:`.add_columns`",
- False)
- def add_column(self, column):
- """Add a column expression to the list of result columns to be returned.
-
- Pending deprecation: :meth:`.add_column` will be superseded by
- :meth:`.add_columns`.
-
- """
-
- return self.add_columns(column)
-
- def options(self, *args):
- """Return a new Query object, applying the given list of
- mapper options.
-
- Most supplied options regard changing how column- and
- relationship-mapped attributes are loaded. See the sections
- :ref:`deferred` and :ref:`loading_toplevel` for reference
- documentation.
-
- """
- return self._options(False, *args)
-
- def _conditional_options(self, *args):
- return self._options(True, *args)
-
- @_generative()
- def _options(self, conditional, *args):
- # most MapperOptions write to the '_attributes' dictionary,
- # so copy that as well
- self._attributes = self._attributes.copy()
- opts = tuple(util.flatten_iterator(args))
- self._with_options = self._with_options + opts
- if conditional:
- for opt in opts:
- opt.process_query_conditionally(self)
- else:
- for opt in opts:
- opt.process_query(self)
-
- @_generative()
- def with_hint(self, selectable, text, dialect_name='*'):
- """Add an indexing hint for the given entity or selectable to
- this :class:`.Query`.
-
- Functionality is passed straight through to
- :meth:`~sqlalchemy.sql.expression.Select.with_hint`,
- with the addition that ``selectable`` can be a
- :class:`.Table`, :class:`.Alias`, or ORM entity / mapped class
- /etc.
- """
- mapper, selectable, is_aliased_class = _entity_info(selectable)
-
- self._with_hints += ((selectable, text, dialect_name),)
-
- @_generative()
- def execution_options(self, **kwargs):
- """ Set non-SQL options which take effect during execution.
-
- The options are the same as those accepted by
- :meth:`.Connection.execution_options`.
-
- Note that the ``stream_results`` execution option is enabled
- automatically if the :meth:`~sqlalchemy.orm.query.Query.yield_per()`
- method is used.
-
- """
- self._execution_options = self._execution_options.union(kwargs)
-
- @_generative()
- def with_lockmode(self, mode):
- """Return a new Query object with the specified locking mode."""
-
- self._lockmode = mode
-
- @_generative()
- def params(self, *args, **kwargs):
- """add values for bind parameters which may have been
- specified in filter().
-
- parameters may be specified using \**kwargs, or optionally a single
- dictionary as the first positional argument. The reason for both is
- that \**kwargs is convenient, however some parameter dictionaries
- contain unicode keys in which case \**kwargs cannot be used.
-
- """
- if len(args) == 1:
- kwargs.update(args[0])
- elif len(args) > 0:
- raise sa_exc.ArgumentError(
- "params() takes zero or one positional argument, "
- "which is a dictionary.")
- self._params = self._params.copy()
- self._params.update(kwargs)
-
- @_generative(_no_statement_condition, _no_limit_offset)
- def filter(self, criterion):
- """apply the given filtering criterion to the query and return
- the newly resulting ``Query``
-
- the criterion is any sql.ClauseElement applicable to the WHERE clause
- of a select.
-
- """
- if isinstance(criterion, basestring):
- criterion = sql.text(criterion)
-
- if criterion is not None and \
- not isinstance(criterion, sql.ClauseElement):
- raise sa_exc.ArgumentError(
- "filter() argument must be of type "
- "sqlalchemy.sql.ClauseElement or string")
-
- criterion = self._adapt_clause(criterion, True, True)
-
- if self._criterion is not None:
- self._criterion = self._criterion & criterion
- else:
- self._criterion = criterion
-
- def filter_by(self, **kwargs):
- """apply the given filtering criterion to the query and return
- the newly resulting ``Query``."""
-
- clauses = [_entity_descriptor(self._joinpoint_zero(), key) == value
- for key, value in kwargs.iteritems()]
- return self.filter(sql.and_(*clauses))
-
- @_generative(_no_statement_condition, _no_limit_offset)
- def order_by(self, *criterion):
- """apply one or more ORDER BY criterion to the query and return
- the newly resulting ``Query``
-
- All existing ORDER BY settings can be suppressed by
- passing ``None`` - this will suppress any ORDER BY configured
- on mappers as well.
-
- Alternatively, an existing ORDER BY setting on the Query
- object can be entirely cancelled by passing ``False``
- as the value - use this before calling methods where
- an ORDER BY is invalid.
-
- """
-
- if len(criterion) == 1:
- if criterion[0] is False:
- if '_order_by' in self.__dict__:
- del self._order_by
- return
- if criterion[0] is None:
- self._order_by = None
- return
-
- criterion = self._adapt_col_list(criterion)
-
- if self._order_by is False or self._order_by is None:
- self._order_by = criterion
- else:
- self._order_by = self._order_by + criterion
-
- @_generative(_no_statement_condition, _no_limit_offset)
- def group_by(self, *criterion):
- """apply one or more GROUP BY criterion to the query and return
- the newly resulting ``Query``"""
-
- criterion = list(chain(*[_orm_columns(c) for c in criterion]))
-
- criterion = self._adapt_col_list(criterion)
-
- if self._group_by is False:
- self._group_by = criterion
- else:
- self._group_by = self._group_by + criterion
-
- @_generative(_no_statement_condition, _no_limit_offset)
- def having(self, criterion):
- """apply a HAVING criterion to the query and return the
- newly resulting ``Query``."""
-
- if isinstance(criterion, basestring):
- criterion = sql.text(criterion)
-
- if criterion is not None and \
- not isinstance(criterion, sql.ClauseElement):
- raise sa_exc.ArgumentError(
- "having() argument must be of type "
- "sqlalchemy.sql.ClauseElement or string")
-
- criterion = self._adapt_clause(criterion, True, True)
-
- if self._having is not None:
- self._having = self._having & criterion
- else:
- self._having = criterion
-
- def union(self, *q):
- """Produce a UNION of this Query against one or more queries.
-
- e.g.::
-
- q1 = sess.query(SomeClass).filter(SomeClass.foo=='bar')
- q2 = sess.query(SomeClass).filter(SomeClass.bar=='foo')
-
- q3 = q1.union(q2)
-
- The method accepts multiple Query objects so as to control
- the level of nesting. A series of ``union()`` calls such as::
-
- x.union(y).union(z).all()
-
- will nest on each ``union()``, and produces::
-
- SELECT * FROM (SELECT * FROM (SELECT * FROM X UNION
- SELECT * FROM y) UNION SELECT * FROM Z)
-
- Whereas::
-
- x.union(y, z).all()
-
- produces::
-
- SELECT * FROM (SELECT * FROM X UNION SELECT * FROM y UNION
- SELECT * FROM Z)
-
- Note that many database backends do not allow ORDER BY to
- be rendered on a query called within UNION, EXCEPT, etc.
- To disable all ORDER BY clauses including those configured
- on mappers, issue ``query.order_by(None)`` - the resulting
- :class:`.Query` object will not render ORDER BY within
- its SELECT statement.
-
- """
-
-
- return self._from_selectable(
- expression.union(*([self]+ list(q))))
-
- def union_all(self, *q):
- """Produce a UNION ALL of this Query against one or more queries.
-
- Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
- that method for usage examples.
-
- """
- return self._from_selectable(
- expression.union_all(*([self]+ list(q)))
- )
-
- def intersect(self, *q):
- """Produce an INTERSECT of this Query against one or more queries.
-
- Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
- that method for usage examples.
-
- """
- return self._from_selectable(
- expression.intersect(*([self]+ list(q)))
- )
-
- def intersect_all(self, *q):
- """Produce an INTERSECT ALL of this Query against one or more queries.
-
- Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
- that method for usage examples.
-
- """
- return self._from_selectable(
- expression.intersect_all(*([self]+ list(q)))
- )
-
- def except_(self, *q):
- """Produce an EXCEPT of this Query against one or more queries.
-
- Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
- that method for usage examples.
-
- """
- return self._from_selectable(
- expression.except_(*([self]+ list(q)))
- )
-
- def except_all(self, *q):
- """Produce an EXCEPT ALL of this Query against one or more queries.
-
- Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
- that method for usage examples.
-
- """
- return self._from_selectable(
- expression.except_all(*([self]+ list(q)))
- )
-
- def join(self, *props, **kwargs):
- """Create a join against this ``Query`` object's criterion
- and apply generatively, returning the newly resulting ``Query``.
-
- Each element in \*props may be:
-
- * a string property name, i.e. "rooms". This will join along the
- relationship of the same name from this Query's "primary" mapper,
- if one is present.
-
- * a class-mapped attribute, i.e. Houses.rooms. This will create a
- join from "Houses" table to that of the "rooms" relationship.
-
- A two-element form of \*props may also be passed. In this form,
- the first element is a target class or selectable, the second
- is a string property name, class-mapped attribute, or clause
- construct representing an "ON" clause. This supersedes the
- previous "tuple" calling form - multiple join() calls should
- be used for multiple (target, onclause) pairs.
-
- e.g.::
-
- # join along string attribute names
- session.query(Company).join('employees')
- session.query(Company).join('employees', 'tasks')
-
- # join the Person entity to an alias of itself,
- # along the "friends" relationship
- PAlias = aliased(Person)
- session.query(Person).join(Palias, Person.friends)
-
- # join from Houses to the "rooms" attribute on the
- # "Colonials" subclass of Houses, then join to the
- # "closets" relationship on Room
- session.query(Houses).join(Colonials.rooms, Room.closets)
-
- # join from Company entities to the "employees" collection,
- # using "people JOIN engineers" as the target. Then join
- # to the "computers" collection on the Engineer entity.
- session.query(Company).\
- join(people.join(engineers), 'employees').\\
- join(Engineer.computers)
-
- # join from Articles to Keywords, using the "keywords" attribute.
- # assume this is a many-to-many relationship.
- session.query(Article).join(Article.keywords)
-
- # same thing, but spelled out entirely explicitly
- # including the association table.
- session.query(Article).join(article_keywords,
- Articles.id==article_keywords.c.article_id).\\
- join(Keyword,
- Keyword.id==article_keywords.c.keyword_id)
-
- \**kwargs include:
-
- aliased - when joining, create anonymous aliases of each table.
- This is used for self-referential joins or multiple joins to the
- same table. Consider usage of the aliased(SomeClass) construct as
- a more explicit approach to this.
-
- from_joinpoint - the given join conditions will attempt
- to join from the right endpoint of the most recent join(),
- instead of from the query's root entity. I.e. any chain
- of joins, such as::
-
- query.join(a, b, c)
-
- is equivalent to::
-
- query.join(a).\\
- join(b, from_joinpoint=True).\\
- join(c, from_joinpoint=True)
-
- """
- aliased, from_joinpoint = kwargs.pop('aliased', False),\
- kwargs.pop('from_joinpoint', False)
- if kwargs:
- raise TypeError("unknown arguments: %s" %
- ','.join(kwargs.iterkeys()))
- return self._join(props,
- outerjoin=False, create_aliases=aliased,
- from_joinpoint=from_joinpoint)
-
- def outerjoin(self, *props, **kwargs):
- """Create a left outer join against this ``Query`` object's criterion
- and apply generatively, returning the newly resulting ``Query``.
-
- Usage is the same as the ``join()`` method.
-
- """
- aliased, from_joinpoint = kwargs.pop('aliased', False), \
- kwargs.pop('from_joinpoint', False)
- if kwargs:
- raise TypeError("unknown arguments: %s" %
- ','.join(kwargs.iterkeys()))
- return self._join(props,
- outerjoin=True, create_aliases=aliased,
- from_joinpoint=from_joinpoint)
-
- @_generative(_no_statement_condition, _no_limit_offset)
- def _join(self, keys, outerjoin, create_aliases, from_joinpoint):
- """consumes arguments from join() or outerjoin(), places them into a
- consistent format with which to form the actual JOIN constructs.
-
- """
- self._polymorphic_adapters = self._polymorphic_adapters.copy()
-
- if not from_joinpoint:
- self._reset_joinpoint()
-
- if len(keys) == 2 and \
- isinstance(keys[0], (expression.FromClause,
- type, AliasedClass)) and \
- isinstance(keys[1], (basestring, expression.ClauseElement,
- interfaces.PropComparator)):
- # detect 2-arg form of join and
- # convert to a tuple.
- keys = (keys,)
-
- for arg1 in util.to_list(keys):
- if isinstance(arg1, tuple):
- # "tuple" form of join, multiple
- # tuples are accepted as well. The simpler
- # "2-arg" form is preferred. May deprecate
- # the "tuple" usage.
- arg1, arg2 = arg1
- else:
- arg2 = None
-
- # determine onclause/right_entity. there
- # is a little bit of legacy behavior still at work here
- # which means they might be in either order. may possibly
- # lock this down to (right_entity, onclause) in 0.6.
- if isinstance(arg1, (interfaces.PropComparator, basestring)):
- right_entity, onclause = arg2, arg1
- else:
- right_entity, onclause = arg1, arg2
-
- left_entity = prop = None
-
- if isinstance(onclause, basestring):
- left_entity = self._joinpoint_zero()
-
- descriptor = _entity_descriptor(left_entity, onclause)
- onclause = descriptor
-
- # check for q.join(Class.propname, from_joinpoint=True)
- # and Class is that of the current joinpoint
- elif from_joinpoint and \
- isinstance(onclause, interfaces.PropComparator):
- left_entity = onclause.parententity
-
- left_mapper, left_selectable, left_is_aliased = \
- _entity_info(self._joinpoint_zero())
- if left_mapper is left_entity:
- left_entity = self._joinpoint_zero()
- descriptor = _entity_descriptor(left_entity,
- onclause.key)
- onclause = descriptor
-
- if isinstance(onclause, interfaces.PropComparator):
- if right_entity is None:
- right_entity = onclause.property.mapper
- of_type = getattr(onclause, '_of_type', None)
- if of_type:
- right_entity = of_type
- else:
- right_entity = onclause.property.mapper
-
- left_entity = onclause.parententity
-
- prop = onclause.property
- if not isinstance(onclause, attributes.QueryableAttribute):
- onclause = prop
-
- if not create_aliases:
- # check for this path already present.
- # don't render in that case.
- if (left_entity, right_entity, prop.key) in \
- self._joinpoint:
- self._joinpoint = \
- self._joinpoint[
- (left_entity, right_entity, prop.key)]
- continue
-
- elif onclause is not None and right_entity is None:
- # TODO: no coverage here
- raise NotImplementedError("query.join(a==b) not supported.")
-
- self._join_left_to_right(
- left_entity,
- right_entity, onclause,
- outerjoin, create_aliases, prop)
-
- def _join_left_to_right(self, left, right,
- onclause, outerjoin, create_aliases, prop):
- """append a JOIN to the query's from clause."""
-
- if left is None:
- left = self._joinpoint_zero()
-
- if left is right and \
- not create_aliases:
- raise sa_exc.InvalidRequestError(
- "Can't construct a join from %s to %s, they "
- "are the same entity" %
- (left, right))
-
- left_mapper, left_selectable, left_is_aliased = _entity_info(left)
- right_mapper, right_selectable, right_is_aliased = _entity_info(right)
-
- if right_mapper and prop and \
- not right_mapper.common_parent(prop.mapper):
- raise sa_exc.InvalidRequestError(
- "Join target %s does not correspond to "
- "the right side of join condition %s" % (right, onclause)
- )
-
- if not right_mapper and prop:
- right_mapper = prop.mapper
-
- need_adapter = False
-
- if right_mapper and right is right_selectable:
- if not right_selectable.is_derived_from(
- right_mapper.mapped_table):
- raise sa_exc.InvalidRequestError(
- "Selectable '%s' is not derived from '%s'" %
- (right_selectable.description,
- right_mapper.mapped_table.description))
-
- if not isinstance(right_selectable, expression.Alias):
- right_selectable = right_selectable.alias()
-
- right = aliased(right_mapper, right_selectable)
- need_adapter = True
-
- aliased_entity = right_mapper and \
- not right_is_aliased and \
- (
- right_mapper.with_polymorphic or
- isinstance(
- right_mapper.mapped_table,
- expression.Join)
- )
-
- if not need_adapter and (create_aliases or aliased_entity):
- right = aliased(right)
- need_adapter = True
-
- # if joining on a MapperProperty path,
- # track the path to prevent redundant joins
- if not create_aliases and prop:
-
- self._joinpoint = jp = {
- '_joinpoint_entity':right,
- 'prev':((left, right, prop.key), self._joinpoint)
- }
-
- # copy backwards to the root of the _joinpath
- # dict, so that no existing dict in the path is mutated
- while 'prev' in jp:
- f, prev = jp['prev']
- prev = prev.copy()
- prev[f] = jp
- jp['prev'] = (f, prev)
- jp = prev
-
- self._joinpath = jp
-
- else:
- self._joinpoint = {
- '_joinpoint_entity':right
- }
-
- # if an alias() of the right side was generated here,
- # apply an adapter to all subsequent filter() calls
- # until reset_joinpoint() is called.
- if need_adapter:
- self._filter_aliases = ORMAdapter(right,
- equivalents=right_mapper and right_mapper._equivalent_columns or {},
- chain_to=self._filter_aliases)
-
- # if the onclause is a ClauseElement, adapt it with any
- # adapters that are in place right now
- if isinstance(onclause, expression.ClauseElement):
- onclause = self._adapt_clause(onclause, True, True)
-
- # if an alias() on the right side was generated,
- # which is intended to wrap a the right side in a subquery,
- # ensure that columns retrieved from this target in the result
- # set are also adapted.
- if aliased_entity:
- self.__mapper_loads_polymorphically_with(
- right_mapper,
- ORMAdapter(
- right,
- equivalents=right_mapper._equivalent_columns
- )
- )
-
- # this is an overly broad assumption here, but there's a
- # very wide variety of situations where we rely upon orm.join's
- # adaption to glue clauses together, with joined-table inheritance's
- # wide array of variables taking up most of the space.
- # Setting the flag here is still a guess, so it is a bug
- # that we don't have definitive criterion to determine when
- # adaption should be enabled (or perhaps that we're even doing the
- # whole thing the way we are here).
- join_to_left = not right_is_aliased and not left_is_aliased
-
- if self._from_obj and left_selectable is not None:
- replace_clause_index, clause = sql_util.find_join_source(
- self._from_obj,
- left_selectable)
- if clause is not None:
- # the entire query's FROM clause is an alias of itself (i.e.
- # from_self(), similar). if the left clause is that one,
- # ensure it adapts to the left side.
- if self._from_obj_alias and clause is self._from_obj[0]:
- join_to_left = True
-
- # An exception case where adaption to the left edge is not
- # desirable. See above note on join_to_left.
- if join_to_left and isinstance(clause, expression.Join) and \
- sql_util.clause_is_present(left_selectable, clause):
- join_to_left = False
-
- clause = orm_join(clause,
- right,
- onclause, isouter=outerjoin,
- join_to_left=join_to_left)
-
- self._from_obj = \
- self._from_obj[:replace_clause_index] + \
- (clause, ) + \
- self._from_obj[replace_clause_index + 1:]
- return
-
- if left_mapper:
- for ent in self._entities:
- if ent.corresponds_to(left):
- clause = ent.selectable
- break
- else:
- clause = left
- else:
- clause = None
-
- if clause is None:
- raise sa_exc.InvalidRequestError(
- "Could not find a FROM clause to join from")
-
- clause = orm_join(clause, right, onclause,
- isouter=outerjoin, join_to_left=join_to_left)
-
- self._from_obj = self._from_obj + (clause,)
-
- def _reset_joinpoint(self):
- self._joinpoint = self._joinpath
- self._filter_aliases = None
-
- @_generative(_no_statement_condition)
- def reset_joinpoint(self):
- """return a new Query reset the 'joinpoint' of this Query reset
- back to the starting mapper. Subsequent generative calls will
- be constructed from the new joinpoint.
-
- Note that each call to join() or outerjoin() also starts from
- the root.
-
- """
- self._reset_joinpoint()
-
- @_generative(_no_clauseelement_condition)
- def select_from(self, *from_obj):
- """Set the FROM clause of this :class:`.Query` explicitly.
-
- Sending a mapped class or entity here effectively replaces the
- "left edge" of any calls to :meth:`.Query.join`, when no
- joinpoint is otherwise established - usually, the default "join
- point" is the leftmost entity in the :class:`.Query` object's
- list of entities to be selected.
-
- Mapped entities or plain :class:`.Table` or other selectables
- can be sent here which will form the default FROM clause.
-
- """
- obj = []
- for fo in from_obj:
- if _is_mapped_class(fo):
- mapper, selectable, is_aliased_class = _entity_info(fo)
- self._select_from_entity = fo
- obj.append(selectable)
- elif not isinstance(fo, expression.FromClause):
- raise sa_exc.ArgumentError(
- "select_from() accepts FromClause objects only.")
- else:
- obj.append(fo)
-
- self._set_select_from(*obj)
-
- def __getitem__(self, item):
- if isinstance(item, slice):
- start, stop, step = util.decode_slice(item)
-
- if isinstance(stop, int) and \
- isinstance(start, int) and \
- stop - start <= 0:
- return []
-
- # perhaps we should execute a count() here so that we
- # can still use LIMIT/OFFSET ?
- elif (isinstance(start, int) and start < 0) \
- or (isinstance(stop, int) and stop < 0):
- return list(self)[item]
-
- res = self.slice(start, stop)
- if step is not None:
- return list(res)[None:None:item.step]
- else:
- return list(res)
- else:
- if item == -1:
- return list(self)[-1]
- else:
- return list(self[item:item+1])[0]
-
- @_generative(_no_statement_condition)
- def slice(self, start, stop):
- """apply LIMIT/OFFSET to the ``Query`` based on a "
- "range and return the newly resulting ``Query``."""
-
- if start is not None and stop is not None:
- self._offset = (self._offset or 0) + start
- self._limit = stop - start
- elif start is None and stop is not None:
- self._limit = stop
- elif start is not None and stop is None:
- self._offset = (self._offset or 0) + start
-
- @_generative(_no_statement_condition)
- def limit(self, limit):
- """Apply a ``LIMIT`` to the query and return the newly resulting
-
- ``Query``.
-
- """
- self._limit = limit
-
- @_generative(_no_statement_condition)
- def offset(self, offset):
- """Apply an ``OFFSET`` to the query and return the newly resulting
- ``Query``.
-
- """
- self._offset = offset
-
- @_generative(_no_statement_condition)
- def distinct(self, *criterion):
- """Apply a ``DISTINCT`` to the query and return the newly resulting
- ``Query``.
-
- :param \*expr: optional column expressions. When present,
- the Postgresql dialect will render a ``DISTINCT ON (<expressions>>)``
- construct.
-
- """
- if not criterion:
- self._distinct = True
- else:
- criterion = self._adapt_col_list(criterion)
- if isinstance(self._distinct, list):
- self._distinct += criterion
- else:
- self._distinct = criterion
-
- def all(self):
- """Return the results represented by this ``Query`` as a list.
-
- This results in an execution of the underlying query.
-
- """
- return list(self)
-
- @_generative(_no_clauseelement_condition)
- def from_statement(self, statement):
- """Execute the given SELECT statement and return results.
-
- This method bypasses all internal statement compilation, and the
- statement is executed without modification.
-
- The statement argument is either a string, a ``select()`` construct,
- or a ``text()`` construct, and should return the set of columns
- appropriate to the entity class represented by this ``Query``.
-
- """
- if isinstance(statement, basestring):
- statement = sql.text(statement)
-
- if not isinstance(statement,
- (expression._TextClause,
- expression._SelectBase)):
- raise sa_exc.ArgumentError(
- "from_statement accepts text(), select(), "
- "and union() objects only.")
-
- self._statement = statement
-
- def first(self):
- """Return the first result of this ``Query`` or
- None if the result doesn't contain any row.
-
- first() applies a limit of one within the generated SQL, so that
- only one primary entity row is generated on the server side
- (note this may consist of multiple result rows if join-loaded
- collections are present).
-
- Calling ``first()`` results in an execution of the underlying query.
-
- """
- if self._statement is not None:
- ret = list(self)[0:1]
- else:
- ret = list(self[0:1])
- if len(ret) > 0:
- return ret[0]
- else:
- return None
-
- def one(self):
- """Return exactly one result or raise an exception.
-
- Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
- no rows. Raises ``sqlalchemy.orm.exc.MultipleResultsFound``
- if multiple object identities are returned, or if multiple
- rows are returned for a query that does not return object
- identities.
-
- Note that an entity query, that is, one which selects one or
- more mapped classes as opposed to individual column attributes,
- may ultimately represent many rows but only one row of
- unique entity or entities - this is a successful result for one().
-
- Calling ``one()`` results in an execution of the underlying query.
- As of 0.6, ``one()`` fully fetches all results instead of applying
- any kind of limit, so that the "unique"-ing of entities does not
- conceal multiple object identities.
-
- """
- ret = list(self)
-
- l = len(ret)
- if l == 1:
- return ret[0]
- elif l == 0:
- raise orm_exc.NoResultFound("No row was found for one()")
- else:
- raise orm_exc.MultipleResultsFound(
- "Multiple rows were found for one()")
-
- def scalar(self):
- """Return the first element of the first result or None
- if no rows present. If multiple rows are returned,
- raises MultipleResultsFound.
-
- >>> session.query(Item).scalar()
- <Item>
- >>> session.query(Item.id).scalar()
- 1
- >>> session.query(Item.id).filter(Item.id < 0).scalar()
- None
- >>> session.query(Item.id, Item.name).scalar()
- 1
- >>> session.query(func.count(Parent.id)).scalar()
- 20
-
- This results in an execution of the underlying query.
-
- """
- try:
- ret = self.one()
- if not isinstance(ret, tuple):
- return ret
- return ret[0]
- except orm_exc.NoResultFound:
- return None
-
- def __iter__(self):
- context = self._compile_context()
- context.statement.use_labels = True
- if self._autoflush and not self._populate_existing:
- self.session._autoflush()
- return self._execute_and_instances(context)
-
- def _connection_from_session(self, **kw):
- conn = self.session.connection(
- **kw)
- if self._execution_options:
- conn = conn.execution_options(**self._execution_options)
- return conn
-
- def _execute_and_instances(self, querycontext):
- conn = self._connection_from_session(
- mapper = self._mapper_zero_or_none(),
- clause = querycontext.statement,
- close_with_result=True)
-
- result = conn.execute(querycontext.statement, self._params)
- return self.instances(result, querycontext)
-
- @property
- def column_descriptions(self):
- """Return metadata about the columns which would be
- returned by this :class:`.Query`.
-
- Format is a list of dictionaries::
-
- user_alias = aliased(User, name='user2')
- q = sess.query(User, User.id, user_alias)
-
- # this expression:
- q.columns
-
- # would return:
- [
- {
- 'name':'User',
- 'type':User,
- 'aliased':False,
- 'expr':User,
- },
- {
- 'name':'id',
- 'type':Integer(),
- 'aliased':False,
- 'expr':User.id,
- },
- {
- 'name':'user2',
- 'type':User,
- 'aliased':True,
- 'expr':user_alias
- }
- ]
-
- """
- return [
- {
- 'name':ent._label_name,
- 'type':ent.type,
- 'aliased':getattr(ent, 'is_aliased_class', False),
- 'expr':ent.expr
- }
- for ent in self._entities
- ]
-
- def instances(self, cursor, __context=None):
- """Given a ResultProxy cursor as returned by connection.execute(),
- return an ORM result as an iterator.
-
- e.g.::
-
- result = engine.execute("select * from users")
- for u in session.query(User).instances(result):
- print u
- """
- session = self.session
-
- context = __context
- if context is None:
- context = QueryContext(self)
-
- context.runid = _new_runid()
-
- filtered = bool(list(self._mapper_entities))
- single_entity = filtered and len(self._entities) == 1
-
- if filtered:
- if single_entity:
- filter = lambda x: util.unique_list(x, id)
- else:
- filter = util.unique_list
- else:
- filter = None
-
- custom_rows = single_entity and \
- self._entities[0].mapper.dispatch.append_result
-
- (process, labels) = \
- zip(*[
- query_entity.row_processor(self, context, custom_rows)
- for query_entity in self._entities
- ])
-
-
- while True:
- context.progress = {}
- context.partials = {}
-
- if self._yield_per:
- fetch = cursor.fetchmany(self._yield_per)
- if not fetch:
- break
- else:
- fetch = cursor.fetchall()
-
- if custom_rows:
- rows = []
- for row in fetch:
- process[0](row, rows)
- elif single_entity:
- rows = [process[0](row, None) for row in fetch]
- else:
- rows = [util.NamedTuple([proc(row, None) for proc in process],
- labels) for row in fetch]
-
- if filter:
- rows = filter(rows)
-
- if context.refresh_state and self._only_load_props \
- and context.refresh_state in context.progress:
- context.refresh_state.commit(
- context.refresh_state.dict, self._only_load_props)
- context.progress.pop(context.refresh_state)
-
- session._finalize_loaded(context.progress)
-
- for ii, (dict_, attrs) in context.partials.iteritems():
- ii.commit(dict_, attrs)
-
- for row in rows:
- yield row
-
- if not self._yield_per:
- break
-
- def merge_result(self, iterator, load=True):
- """Merge a result into this Query's Session.
-
- Given an iterator returned by a Query of the same structure as this
- one, return an identical iterator of results, with all mapped
- instances merged into the session using Session.merge(). This is an
- optimized method which will merge all mapped instances, preserving the
- structure of the result rows and unmapped columns with less method
- overhead than that of calling Session.merge() explicitly for each
- value.
-
- The structure of the results is determined based on the column list of
- this Query - if these do not correspond, unchecked errors will occur.
-
- The 'load' argument is the same as that of Session.merge().
-
- """
-
- session = self.session
- if load:
- # flush current contents if we expect to load data
- session._autoflush()
-
- autoflush = session.autoflush
- try:
- session.autoflush = False
- single_entity = len(self._entities) == 1
- if single_entity:
- if isinstance(self._entities[0], _MapperEntity):
- result = [session._merge(
- attributes.instance_state(instance),
- attributes.instance_dict(instance),
- load=load, _recursive={})
- for instance in iterator]
- else:
- result = list(iterator)
- else:
- mapped_entities = [i for i, e in enumerate(self._entities)
- if isinstance(e, _MapperEntity)]
- result = []
- for row in iterator:
- newrow = list(row)
- for i in mapped_entities:
- newrow[i] = session._merge(
- attributes.instance_state(newrow[i]),
- attributes.instance_dict(newrow[i]),
- load=load, _recursive={})
- result.append(util.NamedTuple(newrow, row._labels))
-
- return iter(result)
- finally:
- session.autoflush = autoflush
-
- @classmethod
- def _get_from_identity(cls, session, key, passive):
- """Look up the given key in the given session's identity map,
- check the object for expired state if found.
-
- """
- instance = session.identity_map.get(key)
- if instance:
-
- state = attributes.instance_state(instance)
-
- # expired - ensure it still exists
- if state.expired:
- if passive is attributes.PASSIVE_NO_FETCH:
- # TODO: no coverage here
- return attributes.PASSIVE_NO_RESULT
- elif passive is attributes.PASSIVE_NO_FETCH_RELATED:
- # this mode is used within a flush and the instance's
- # expired state will be checked soon enough, if necessary
- return instance
- try:
- state(passive)
- except orm_exc.ObjectDeletedError:
- session._remove_newly_deleted(state)
- return None
- return instance
- else:
- return None
-
- def _load_on_ident(self, key, refresh_state=None, lockmode=None,
- only_load_props=None):
- """Load the given identity key from the database."""
-
- lockmode = lockmode or self._lockmode
-
- if key is not None:
- ident = key[1]
- else:
- ident = None
-
- if refresh_state is None:
- q = self._clone()
- q._get_condition()
- else:
- q = self._clone()
-
- if ident is not None:
- mapper = self._mapper_zero()
-
- (_get_clause, _get_params) = mapper._get_clause
-
- # None present in ident - turn those comparisons
- # into "IS NULL"
- if None in ident:
- nones = set([
- _get_params[col].key for col, value in
- zip(mapper.primary_key, ident) if value is None
- ])
- _get_clause = sql_util.adapt_criterion_to_null(
- _get_clause, nones)
-
- _get_clause = q._adapt_clause(_get_clause, True, False)
- q._criterion = _get_clause
-
- params = dict([
- (_get_params[primary_key].key, id_val)
- for id_val, primary_key in zip(ident, mapper.primary_key)
- ])
-
- q._params = params
-
- if lockmode is not None:
- q._lockmode = lockmode
- q._get_options(
- populate_existing=bool(refresh_state),
- version_check=(lockmode is not None),
- only_load_props=only_load_props,
- refresh_state=refresh_state)
- q._order_by = None
-
- try:
- return q.one()
- except orm_exc.NoResultFound:
- return None
-
- @property
- def _select_args(self):
- return {
- 'limit':self._limit,
- 'offset':self._offset,
- 'distinct':self._distinct,
- 'group_by':self._group_by or None,
- 'having':self._having
- }
-
- @property
- def _should_nest_selectable(self):
- kwargs = self._select_args
- return (kwargs.get('limit') is not None or
- kwargs.get('offset') is not None or
- kwargs.get('distinct', False))
-
- def count(self):
- """Return a count of rows this Query would return.
-
- This generates the SQL for this Query as follows::
-
- SELECT count(1) AS count_1 FROM (
- SELECT <rest of query follows...>
- ) AS anon_1
-
- Note the above scheme is newly refined in 0.7
- (as of 0.7b3).
-
- For fine grained control over specific columns
- to count, to skip the usage of a subquery or
- otherwise control of the FROM clause,
- or to use other aggregate functions,
- use :attr:`.func` expressions in conjunction
- with :meth:`~.Session.query`, i.e.::
-
- from sqlalchemy import func
-
- # count User records, without
- # using a subquery.
- session.query(func.count(User.id))
-
- # return count of user "id" grouped
- # by "name"
- session.query(func.count(User.id)).\\
- group_by(User.name)
-
- from sqlalchemy import distinct
-
- # count distinct "name" values
- session.query(func.count(distinct(User.name)))
-
- """
- col = sql.func.count(sql.literal_column('*'))
- return self.from_self(col).scalar()
-
- def delete(self, synchronize_session='evaluate'):
- """Perform a bulk delete query.
-
- Deletes rows matched by this query from the database.
-
- :param synchronize_session: chooses the strategy for the removal of
- matched objects from the session. Valid values are:
-
- False - don't synchronize the session. This option is the most
- efficient and is reliable once the session is expired, which
- typically occurs after a commit(), or explicitly using
- expire_all(). Before the expiration, objects may still remain in
- the session which were in fact deleted which can lead to confusing
- results if they are accessed via get() or already loaded
- collections.
-
- 'fetch' - performs a select query before the delete to find
- objects that are matched by the delete query and need to be
- removed from the session. Matched objects are removed from the
- session.
-
- 'evaluate' - Evaluate the query's criteria in Python straight on
- the objects in the session. If evaluation of the criteria isn't
- implemented, an error is raised. In that case you probably
- want to use the 'fetch' strategy as a fallback.
-
- The expression evaluator currently doesn't account for differing
- string collations between the database and Python.
-
- Returns the number of rows deleted, excluding any cascades.
-
- The method does *not* offer in-Python cascading of relationships - it
- is assumed that ON DELETE CASCADE is configured for any foreign key
- references which require it. The Session needs to be expired (occurs
- automatically after commit(), or call expire_all()) in order for the
- state of dependent objects subject to delete or delete-orphan cascade
- to be correctly represented.
-
- Also, the ``before_delete()`` and ``after_delete()``
- :class:`~sqlalchemy.orm.interfaces.MapperExtension` methods are not
- called from this method. For a delete hook here, use the
- :meth:`.SessionExtension.after_bulk_delete()` event hook.
-
- """
- #TODO: lots of duplication and ifs - probably needs to be
- # refactored to strategies
- #TODO: cascades need handling.
-
- if synchronize_session not in [False, 'evaluate', 'fetch']:
- raise sa_exc.ArgumentError(
- "Valid strategies for session "
- "synchronization are False, 'evaluate' and "
- "'fetch'")
- self._no_select_modifiers("delete")
-
- self = self.enable_eagerloads(False)
-
- context = self._compile_context()
- if len(context.statement.froms) != 1 or \
- not isinstance(context.statement.froms[0], schema.Table):
- raise sa_exc.ArgumentError("Only deletion via a single table "
- "query is currently supported")
- primary_table = context.statement.froms[0]
-
- session = self.session
-
- if self._autoflush:
- session._autoflush()
-
- if synchronize_session == 'evaluate':
- try:
- evaluator_compiler = evaluator.EvaluatorCompiler()
- if self.whereclause is not None:
- eval_condition = evaluator_compiler.process(
- self.whereclause)
- else:
- def eval_condition(obj):
- return True
-
- except evaluator.UnevaluatableError:
- raise sa_exc.InvalidRequestError(
- "Could not evaluate current criteria in Python. "
- "Specify 'fetch' or False for the synchronize_session "
- "parameter.")
-
- target_cls = self._mapper_zero().class_
-
- #TODO: detect when the where clause is a trivial primary key match
- objs_to_expunge = [
- obj for (cls, pk),obj in
- session.identity_map.iteritems()
- if issubclass(cls, target_cls) and
- eval_condition(obj)]
-
- elif synchronize_session == 'fetch':
- #TODO: use RETURNING when available
- select_stmt = context.statement.with_only_columns(
- primary_table.primary_key)
- matched_rows = session.execute(
- select_stmt,
- params=self._params).fetchall()
-
- delete_stmt = sql.delete(primary_table, context.whereclause)
-
- result = session.execute(delete_stmt, params=self._params)
-
- if synchronize_session == 'evaluate':
- for obj in objs_to_expunge:
- session._remove_newly_deleted(attributes.instance_state(obj))
- elif synchronize_session == 'fetch':
- target_mapper = self._mapper_zero()
- for primary_key in matched_rows:
- identity_key = target_mapper.identity_key_from_primary_key(
- list(primary_key))
- if identity_key in session.identity_map:
- session._remove_newly_deleted(
- attributes.instance_state(
- session.identity_map[identity_key]
- )
- )
-
- session.dispatch.after_bulk_delete(session, self, context, result)
-
- return result.rowcount
-
- def update(self, values, synchronize_session='evaluate'):
- """Perform a bulk update query.
-
- Updates rows matched by this query in the database.
-
- :param values: a dictionary with attributes names as keys and literal
- values or sql expressions as values.
-
- :param synchronize_session: chooses the strategy to update the
- attributes on objects in the session. Valid values are:
-
- False - don't synchronize the session. This option is the most
- efficient and is reliable once the session is expired, which
- typically occurs after a commit(), or explicitly using
- expire_all(). Before the expiration, updated objects may still
- remain in the session with stale values on their attributes, which
- can lead to confusing results.
-
- 'fetch' - performs a select query before the update to find
- objects that are matched by the update query. The updated
- attributes are expired on matched objects.
-
- 'evaluate' - Evaluate the Query's criteria in Python straight on
- the objects in the session. If evaluation of the criteria isn't
- implemented, an exception is raised.
-
- The expression evaluator currently doesn't account for differing
- string collations between the database and Python.
-
- Returns the number of rows matched by the update.
-
- The method does *not* offer in-Python cascading of relationships - it
- is assumed that ON UPDATE CASCADE is configured for any foreign key
- references which require it.
-
- The Session needs to be expired (occurs automatically after commit(),
- or call expire_all()) in order for the state of dependent objects
- subject foreign key cascade to be correctly represented.
-
- Also, the ``before_update()`` and ``after_update()``
- :class:`~sqlalchemy.orm.interfaces.MapperExtension` methods are not
- called from this method. For an update hook here, use the
- :meth:`.SessionExtension.after_bulk_update()` event hook.
-
- """
-
- #TODO: value keys need to be mapped to corresponding sql cols and
- # instr.attr.s to string keys
- #TODO: updates of manytoone relationships need to be converted to
- # fk assignments
- #TODO: cascades need handling.
-
- if synchronize_session == 'expire':
- util.warn_deprecated("The 'expire' value as applied to "
- "the synchronize_session argument of "
- "query.update() is now called 'fetch'")
- synchronize_session = 'fetch'
-
- if synchronize_session not in [False, 'evaluate', 'fetch']:
- raise sa_exc.ArgumentError(
- "Valid strategies for session synchronization "
- "are False, 'evaluate' and 'fetch'")
- self._no_select_modifiers("update")
-
- self = self.enable_eagerloads(False)
-
- context = self._compile_context()
- if len(context.statement.froms) != 1 or \
- not isinstance(context.statement.froms[0], schema.Table):
- raise sa_exc.ArgumentError(
- "Only update via a single table query is "
- "currently supported")
- primary_table = context.statement.froms[0]
-
- session = self.session
-
- if self._autoflush:
- session._autoflush()
-
- if synchronize_session == 'evaluate':
- try:
- evaluator_compiler = evaluator.EvaluatorCompiler()
- if self.whereclause is not None:
- eval_condition = evaluator_compiler.process(
- self.whereclause)
- else:
- def eval_condition(obj):
- return True
-
- value_evaluators = {}
- for key,value in values.iteritems():
- key = _attr_as_key(key)
- value_evaluators[key] = evaluator_compiler.process(
- expression._literal_as_binds(value))
- except evaluator.UnevaluatableError:
- raise sa_exc.InvalidRequestError(
- "Could not evaluate current criteria in Python. "
- "Specify 'fetch' or False for the "
- "synchronize_session parameter.")
- target_cls = self._mapper_zero().class_
- matched_objects = []
- for (cls, pk),obj in session.identity_map.iteritems():
- evaluated_keys = value_evaluators.keys()
-
- if issubclass(cls, target_cls) and eval_condition(obj):
- matched_objects.append(obj)
-
- elif synchronize_session == 'fetch':
- select_stmt = context.statement.with_only_columns(
- primary_table.primary_key)
- matched_rows = session.execute(
- select_stmt,
- params=self._params).fetchall()
-
- update_stmt = sql.update(primary_table, context.whereclause, values)
-
- result = session.execute(update_stmt, params=self._params)
-
- if synchronize_session == 'evaluate':
- target_cls = self._mapper_zero().class_
-
- for obj in matched_objects:
- state, dict_ = attributes.instance_state(obj),\
- attributes.instance_dict(obj)
-
- # only evaluate unmodified attributes
- to_evaluate = state.unmodified.intersection(
- evaluated_keys)
- for key in to_evaluate:
- dict_[key] = value_evaluators[key](obj)
-
- state.commit(dict_, list(to_evaluate))
-
- # expire attributes with pending changes
- # (there was no autoflush, so they are overwritten)
- state.expire_attributes(dict_,
- set(evaluated_keys).
- difference(to_evaluate))
-
- elif synchronize_session == 'fetch':
- target_mapper = self._mapper_zero()
-
- for primary_key in matched_rows:
- identity_key = target_mapper.identity_key_from_primary_key(
- list(primary_key))
- if identity_key in session.identity_map:
- session.expire(
- session.identity_map[identity_key],
- [_attr_as_key(k) for k in values]
- )
-
- session.dispatch.after_bulk_update(session, self, context, result)
-
- return result.rowcount
-
- def _compile_context(self, labels=True):
- context = QueryContext(self)
-
- if context.statement is not None:
- return context
-
- if self._lockmode:
- try:
- for_update = {'read': 'read',
- 'update': True,
- 'update_nowait': 'nowait',
- None: False}[self._lockmode]
- except KeyError:
- raise sa_exc.ArgumentError(
- "Unknown lockmode %r" % self._lockmode)
- else:
- for_update = False
-
- for entity in self._entities:
- entity.setup_context(self, context)
-
- for rec in context.create_eager_joins:
- strategy = rec[0]
- strategy(*rec[1:])
-
- eager_joins = context.eager_joins.values()
-
- if context.from_clause:
- # "load from explicit FROMs" mode,
- # i.e. when select_from() or join() is used
- froms = list(context.from_clause)
- else:
- # "load from discrete FROMs" mode,
- # i.e. when each _MappedEntity has its own FROM
- froms = context.froms
-
- if self._enable_single_crit:
- self._adjust_for_single_inheritance(context)
-
- if not context.primary_columns:
- if self._only_load_props:
- raise sa_exc.InvalidRequestError(
- "No column-based properties specified for "
- "refresh operation. Use session.expire() "
- "to reload collections and related items.")
- else:
- raise sa_exc.InvalidRequestError(
- "Query contains no columns with which to "
- "SELECT from.")
-
- if context.multi_row_eager_loaders and self._should_nest_selectable:
- # for eager joins present and LIMIT/OFFSET/DISTINCT,
- # wrap the query inside a select,
- # then append eager joins onto that
-
- if context.order_by:
- order_by_col_expr = list(
- chain(*[
- sql_util.find_columns(o)
- for o in context.order_by
- ])
- )
- else:
- context.order_by = None
- order_by_col_expr = []
-
- inner = sql.select(
- context.primary_columns + order_by_col_expr,
- context.whereclause,
- from_obj=froms,
- use_labels=labels,
- correlate=False,
- order_by=context.order_by,
- **self._select_args
- )
-
- for hint in self._with_hints:
- inner = inner.with_hint(*hint)
-
- if self._correlate:
- inner = inner.correlate(*self._correlate)
-
- inner = inner.alias()
-
- equivs = self.__all_equivs()
-
- context.adapter = sql_util.ColumnAdapter(inner, equivs)
-
- statement = sql.select(
- [inner] + context.secondary_columns,
- for_update=for_update,
- use_labels=labels)
-
- from_clause = inner
- for eager_join in eager_joins:
- # EagerLoader places a 'stop_on' attribute on the join,
- # giving us a marker as to where the "splice point" of
- # the join should be
- from_clause = sql_util.splice_joins(
- from_clause,
- eager_join, eager_join.stop_on)
-
- statement.append_from(from_clause)
-
- if context.order_by:
- statement.append_order_by(
- *context.adapter.copy_and_process(
- context.order_by
- )
- )
-
- statement.append_order_by(*context.eager_order_by)
- else:
- if not context.order_by:
- context.order_by = None
-
- if self._distinct and context.order_by:
- order_by_col_expr = list(
- chain(*[
- sql_util.find_columns(o)
- for o in context.order_by
- ])
- )
- context.primary_columns += order_by_col_expr
-
- froms += tuple(context.eager_joins.values())
-
- statement = sql.select(
- context.primary_columns +
- context.secondary_columns,
- context.whereclause,
- from_obj=froms,
- use_labels=labels,
- for_update=for_update,
- correlate=False,
- order_by=context.order_by,
- **self._select_args
- )
-
- for hint in self._with_hints:
- statement = statement.with_hint(*hint)
-
- if self._correlate:
- statement = statement.correlate(*self._correlate)
-
- if context.eager_order_by:
- statement.append_order_by(*context.eager_order_by)
-
- context.statement = statement
-
- return context
-
- def _adjust_for_single_inheritance(self, context):
- """Apply single-table-inheritance filtering.
-
- For all distinct single-table-inheritance mappers represented in the
- columns clause of this query, add criterion to the WHERE clause of the
- given QueryContext such that only the appropriate subtypes are
- selected from the total results.
-
- """
-
- for entity, (mapper, adapter, s, i, w) in \
- self._mapper_adapter_map.iteritems():
- single_crit = mapper._single_table_criterion
- if single_crit is not None:
- if adapter:
- single_crit = adapter.traverse(single_crit)
- single_crit = self._adapt_clause(single_crit, False, False)
- context.whereclause = sql.and_(
- context.whereclause, single_crit)
-
- def __str__(self):
- return str(self._compile_context().statement)
-
-
-class _QueryEntity(object):
- """represent an entity column returned within a Query result."""
-
- def __new__(cls, *args, **kwargs):
- if cls is _QueryEntity:
- entity = args[1]
- if not isinstance(entity, basestring) and \
- _is_mapped_class(entity):
- cls = _MapperEntity
- else:
- cls = _ColumnEntity
- return object.__new__(cls)
-
- def _clone(self):
- q = self.__class__.__new__(self.__class__)
- q.__dict__ = self.__dict__.copy()
- return q
-
-class _MapperEntity(_QueryEntity):
- """mapper/class/AliasedClass entity"""
-
- def __init__(self, query, entity):
- self.primary_entity = not query._entities
- query._entities.append(self)
-
- self.entities = [entity]
- self.entity_zero = self.expr = entity
-
- def setup_entity(self, entity, mapper, adapter,
- from_obj, is_aliased_class, with_polymorphic):
- self.mapper = mapper
- self.adapter = adapter
- self.selectable = from_obj
- self._with_polymorphic = with_polymorphic
- self._polymorphic_discriminator = None
- self.is_aliased_class = is_aliased_class
- if is_aliased_class:
- self.path_entity = self.entity_zero = entity
- self._path = (entity,)
- self._label_name = self.entity_zero._sa_label_name
- self._reduced_path = (self.path_entity, )
- else:
- self.path_entity = mapper
- self._path = (mapper,)
- self._reduced_path = (mapper.base_mapper, )
- self.entity_zero = mapper
- self._label_name = self.mapper.class_.__name__
-
-
- def set_with_polymorphic(self, query, cls_or_mappers,
- selectable, discriminator):
- if cls_or_mappers is None:
- query._reset_polymorphic_adapter(self.mapper)
- return
-
- mappers, from_obj = self.mapper._with_polymorphic_args(
- cls_or_mappers, selectable)
- self._with_polymorphic = mappers
- self._polymorphic_discriminator = discriminator
-
- # TODO: do the wrapped thing here too so that
- # with_polymorphic() can be applied to aliases
- if not self.is_aliased_class:
- self.selectable = from_obj
- self.adapter = query._get_polymorphic_adapter(self, from_obj)
-
- @property
- def type(self):
- return self.mapper.class_
-
- def corresponds_to(self, entity):
- if _is_aliased_class(entity) or self.is_aliased_class:
- return entity is self.path_entity
- else:
- return entity.common_parent(self.path_entity)
-
- def adapt_to_selectable(self, query, sel):
- query._entities.append(self)
-
- def _get_entity_clauses(self, query, context):
-
- adapter = None
- if not self.is_aliased_class and query._polymorphic_adapters:
- adapter = query._polymorphic_adapters.get(self.mapper, None)
-
- if not adapter and self.adapter:
- adapter = self.adapter
-
- if adapter:
- if query._from_obj_alias:
- ret = adapter.wrap(query._from_obj_alias)
- else:
- ret = adapter
- else:
- ret = query._from_obj_alias
-
- return ret
-
- def row_processor(self, query, context, custom_rows):
- adapter = self._get_entity_clauses(query, context)
-
- if context.adapter and adapter:
- adapter = adapter.wrap(context.adapter)
- elif not adapter:
- adapter = context.adapter
-
- # polymorphic mappers which have concrete tables in
- # their hierarchy usually
- # require row aliasing unconditionally.
- if not adapter and self.mapper._requires_row_aliasing:
- adapter = sql_util.ColumnAdapter(
- self.selectable,
- self.mapper._equivalent_columns)
-
- if self.primary_entity:
- _instance = self.mapper._instance_processor(
- context,
- self._path,
- self._reduced_path,
- adapter,
- only_load_props=query._only_load_props,
- refresh_state=context.refresh_state,
- polymorphic_discriminator=
- self._polymorphic_discriminator
- )
- else:
- _instance = self.mapper._instance_processor(
- context,
- self._path,
- self._reduced_path,
- adapter,
- polymorphic_discriminator=
- self._polymorphic_discriminator)
-
- return _instance, self._label_name
-
- def setup_context(self, query, context):
- adapter = self._get_entity_clauses(query, context)
-
- context.froms += (self.selectable,)
-
- if context.order_by is False and self.mapper.order_by:
- context.order_by = self.mapper.order_by
-
- # apply adaptation to the mapper's order_by if needed.
- if adapter:
- context.order_by = adapter.adapt_list(
- util.to_list(
- context.order_by
- )
- )
-
- if self._with_polymorphic:
- poly_properties = self.mapper._iterate_polymorphic_properties(
- self._with_polymorphic)
- else:
- poly_properties = self.mapper._polymorphic_properties
-
- for value in poly_properties:
- if query._only_load_props and \
- value.key not in query._only_load_props:
- continue
- value.setup(
- context,
- self,
- self._path,
- self._reduced_path,
- adapter,
- only_load_props=query._only_load_props,
- column_collection=context.primary_columns
- )
-
- if self._polymorphic_discriminator is not None:
- if adapter:
- pd = adapter.columns[self._polymorphic_discriminator]
- else:
- pd = self._polymorphic_discriminator
- context.primary_columns.append(pd)
-
- def __str__(self):
- return str(self.mapper)
-
-class _ColumnEntity(_QueryEntity):
- """Column/expression based entity."""
-
- def __init__(self, query, column):
- self.expr = column
-
- if isinstance(column, basestring):
- column = sql.literal_column(column)
- self._label_name = column.name
- elif isinstance(column, (
- attributes.QueryableAttribute,
- interfaces.PropComparator
- )):
- self._label_name = column.key
- column = column.__clause_element__()
- else:
- self._label_name = getattr(column, 'key', None)
-
- if not isinstance(column, expression.ColumnElement) and \
- hasattr(column, '_select_iterable'):
- for c in column._select_iterable:
- if c is column:
- break
- _ColumnEntity(query, c)
-
- if c is not column:
- return
-
- if not isinstance(column, sql.ColumnElement):
- raise sa_exc.InvalidRequestError(
- "SQL expression, column, or mapped entity "
- "expected - got '%r'" % column
- )
-
- # If the Column is unnamed, give it a
- # label() so that mutable column expressions
- # can be located in the result even
- # if the expression's identity has been changed
- # due to adaption.
- if not column._label:
- column = column.label(None)
-
- query._entities.append(self)
-
- self.column = column
- self.froms = set()
-
- # look for ORM entities represented within the
- # given expression. Try to count only entities
- # for columns whose FROM object is in the actual list
- # of FROMs for the overall expression - this helps
- # subqueries which were built from ORM constructs from
- # leaking out their entities into the main select construct
- actual_froms = set(column._from_objects)
-
- self.entities = util.OrderedSet(
- elem._annotations['parententity']
- for elem in visitors.iterate(column, {})
- if 'parententity' in elem._annotations
- and actual_froms.intersection(elem._from_objects)
- )
-
- if self.entities:
- self.entity_zero = list(self.entities)[0]
- else:
- self.entity_zero = None
-
- @property
- def type(self):
- return self.column.type
-
- def adapt_to_selectable(self, query, sel):
- c = _ColumnEntity(query, sel.corresponding_column(self.column))
- c._label_name = self._label_name
- c.entity_zero = self.entity_zero
- c.entities = self.entities
-
- def setup_entity(self, entity, mapper, adapter, from_obj,
- is_aliased_class, with_polymorphic):
- self.selectable = from_obj
- self.froms.add(from_obj)
-
- def corresponds_to(self, entity):
- if self.entity_zero is None:
- return False
- elif _is_aliased_class(entity):
- return entity is self.entity_zero
- else:
- return not _is_aliased_class(self.entity_zero) and \
- entity.common_parent(self.entity_zero)
-
- def _resolve_expr_against_query_aliases(self, query, expr, context):
- return query._adapt_clause(expr, False, True)
-
- def row_processor(self, query, context, custom_rows):
- column = self._resolve_expr_against_query_aliases(
- query, self.column, context)
-
- if context.adapter:
- column = context.adapter.columns[column]
-
- def proc(row, result):
- return row[column]
-
- return proc, self._label_name
-
- def setup_context(self, query, context):
- column = self._resolve_expr_against_query_aliases(
- query, self.column, context)
- context.froms += tuple(self.froms)
- context.primary_columns.append(column)
-
- def __str__(self):
- return str(self.column)
-
-log.class_logger(Query)
-
-class QueryContext(object):
- multi_row_eager_loaders = False
- adapter = None
- froms = ()
-
- def __init__(self, query):
-
- if query._statement is not None:
- if isinstance(query._statement, expression._SelectBase) and \
- not query._statement.use_labels:
- self.statement = query._statement.apply_labels()
- else:
- self.statement = query._statement
- else:
- self.statement = None
- self.from_clause = query._from_obj
- self.whereclause = query._criterion
- self.order_by = query._order_by
-
- self.query = query
- self.session = query.session
- self.populate_existing = query._populate_existing
- self.version_check = query._version_check
- self.refresh_state = query._refresh_state
- self.primary_columns = []
- self.secondary_columns = []
- self.eager_order_by = []
- self.eager_joins = {}
- self.create_eager_joins = []
- self.propagate_options = set(o for o in query._with_options if
- o.propagate_to_loaders)
- self.attributes = query._attributes.copy()
-
-class AliasOption(interfaces.MapperOption):
-
- def __init__(self, alias):
- self.alias = alias
-
- def process_query(self, query):
- if isinstance(self.alias, basestring):
- alias = query._mapper_zero().mapped_table.alias(self.alias)
- else:
- alias = self.alias
- query._from_obj_alias = sql_util.ColumnAdapter(alias)
-
-
-_runid = 1L
-_id_lock = util.threading.Lock()
-
-def _new_runid():
- global _runid
- _id_lock.acquire()
- try:
- _runid += 1
- return _runid
- finally:
- _id_lock.release()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/scoping.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/scoping.py
deleted file mode 100755
index 53e5e5d1..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/scoping.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# orm/scoping.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy import exc as sa_exc
-from sqlalchemy.util import ScopedRegistry, ThreadLocalRegistry, warn
-from sqlalchemy.orm import class_mapper
-from sqlalchemy.orm import exc as orm_exc
-from sqlalchemy.orm.session import Session
-
-
-__all__ = ['ScopedSession']
-
-
-class ScopedSession(object):
- """Provides thread-local management of Sessions.
-
- Usage::
-
- Session = scoped_session(sessionmaker())
-
- ... use Session normally.
-
- The internal registry is accessible as well,
- and by default is an instance of :class:`.ThreadLocalRegistry`.
-
-
- """
-
- def __init__(self, session_factory, scopefunc=None):
- self.session_factory = session_factory
- if scopefunc:
- self.registry = ScopedRegistry(session_factory, scopefunc)
- else:
- self.registry = ThreadLocalRegistry(session_factory)
-
- def __call__(self, **kwargs):
- if kwargs:
- scope = kwargs.pop('scope', False)
- if scope is not None:
- if self.registry.has():
- raise sa_exc.InvalidRequestError("Scoped session is already present; "
- "no new arguments may be specified.")
- else:
- sess = self.session_factory(**kwargs)
- self.registry.set(sess)
- return sess
- else:
- return self.session_factory(**kwargs)
- else:
- return self.registry()
-
- def remove(self):
- """Dispose of the current contextual session."""
-
- if self.registry.has():
- self.registry().close()
- self.registry.clear()
-
- def configure(self, **kwargs):
- """reconfigure the sessionmaker used by this ScopedSession."""
-
- if self.registry.has():
- warn('At least one scoped session is already present. '
- ' configure() can not affect sessions that have '
- 'already been created.')
-
- self.session_factory.configure(**kwargs)
-
- def query_property(self, query_cls=None):
- """return a class property which produces a `Query` object against the
- class when called.
-
- e.g.::
-
- Session = scoped_session(sessionmaker())
-
- class MyClass(object):
- query = Session.query_property()
-
- # after mappers are defined
- result = MyClass.query.filter(MyClass.name=='foo').all()
-
- Produces instances of the session's configured query class by
- default. To override and use a custom implementation, provide
- a ``query_cls`` callable. The callable will be invoked with
- the class's mapper as a positional argument and a session
- keyword argument.
-
- There is no limit to the number of query properties placed on
- a class.
-
- """
- class query(object):
- def __get__(s, instance, owner):
- try:
- mapper = class_mapper(owner)
- if mapper:
- if query_cls:
- # custom query class
- return query_cls(mapper, session=self.registry())
- else:
- # session's configured query class
- return self.registry().query(mapper)
- except orm_exc.UnmappedClassError:
- return None
- return query()
-
-def instrument(name):
- def do(self, *args, **kwargs):
- return getattr(self.registry(), name)(*args, **kwargs)
- return do
-for meth in Session.public_methods:
- setattr(ScopedSession, meth, instrument(meth))
-
-def makeprop(name):
- def set(self, attr):
- setattr(self.registry(), name, attr)
- def get(self):
- return getattr(self.registry(), name)
- return property(get, set)
-for prop in ('bind', 'dirty', 'deleted', 'new', 'identity_map', 'is_active', 'autoflush'):
- setattr(ScopedSession, prop, makeprop(prop))
-
-def clslevel(name):
- def do(cls, *args, **kwargs):
- return getattr(Session, name)(*args, **kwargs)
- return classmethod(do)
-for prop in ('close_all', 'object_session', 'identity_key'):
- setattr(ScopedSession, prop, clslevel(prop))
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py
deleted file mode 100755
index 8f8770a3..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py
+++ /dev/null
@@ -1,1725 +0,0 @@
-# orm/session.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Provides the Session class and related utilities."""
-
-import weakref
-from itertools import chain
-from sqlalchemy import util, sql, engine, log, exc as sa_exc
-from sqlalchemy.sql import util as sql_util, expression
-from sqlalchemy.orm import (
- SessionExtension, attributes, exc, query, unitofwork, util as mapperutil, state
- )
-from sqlalchemy.orm.util import object_mapper as _object_mapper
-from sqlalchemy.orm.util import class_mapper as _class_mapper
-from sqlalchemy.orm.util import (
- _class_to_mapper, _state_mapper,
- )
-from sqlalchemy.orm.mapper import Mapper, _none_set
-from sqlalchemy.orm.unitofwork import UOWTransaction
-from sqlalchemy.orm import identity
-from sqlalchemy import event
-from sqlalchemy.orm.events import SessionEvents
-
-import sys
-
-__all__ = ['Session', 'SessionTransaction', 'SessionExtension']
-
-
-def sessionmaker(bind=None, class_=None, autoflush=True, autocommit=False,
- expire_on_commit=True, **kwargs):
- """Generate a custom-configured :class:`~sqlalchemy.orm.session.Session` class.
-
- The returned object is a subclass of ``Session``, which, when instantiated
- with no arguments, uses the keyword arguments configured here as its
- constructor arguments.
-
- It is intended that the `sessionmaker()` function be called within the
- global scope of an application, and the returned class be made available
- to the rest of the application as the single class used to instantiate
- sessions.
-
- e.g.::
-
- # global scope
- Session = sessionmaker(autoflush=False)
-
- # later, in a local scope, create and use a session:
- sess = Session()
-
- Any keyword arguments sent to the constructor itself will override the
- "configured" keywords::
-
- Session = sessionmaker()
-
- # bind an individual session to a connection
- sess = Session(bind=connection)
-
- The class also includes a special classmethod ``configure()``, which
- allows additional configurational options to take place after the custom
- ``Session`` class has been generated. This is useful particularly for
- defining the specific ``Engine`` (or engines) to which new instances of
- ``Session`` should be bound::
-
- Session = sessionmaker()
- Session.configure(bind=create_engine('sqlite:///foo.db'))
-
- sess = Session()
-
- For options, see the constructor options for :class:`.Session`.
-
- """
- kwargs['bind'] = bind
- kwargs['autoflush'] = autoflush
- kwargs['autocommit'] = autocommit
- kwargs['expire_on_commit'] = expire_on_commit
-
- if class_ is None:
- class_ = Session
-
- class Sess(object):
- def __init__(self, **local_kwargs):
- for k in kwargs:
- local_kwargs.setdefault(k, kwargs[k])
- super(Sess, self).__init__(**local_kwargs)
-
- @classmethod
- def configure(self, **new_kwargs):
- """(Re)configure the arguments for this sessionmaker.
-
- e.g.::
-
- Session = sessionmaker()
-
- Session.configure(bind=create_engine('sqlite://'))
- """
- kwargs.update(new_kwargs)
-
-
- return type("Session", (Sess, class_), {})
-
-
-class SessionTransaction(object):
- """A Session-level transaction.
-
- This corresponds to one or more :class:`~sqlalchemy.engine.Transaction`
- instances behind the scenes, with one ``Transaction`` per ``Engine`` in
- use.
-
- Direct usage of ``SessionTransaction`` is not necessary as of SQLAlchemy
- 0.4; use the ``begin()`` and ``commit()`` methods on ``Session`` itself.
-
- The ``SessionTransaction`` object is **not** thread-safe.
-
- .. index::
- single: thread safety; SessionTransaction
-
- """
-
- _rollback_exception = None
-
- def __init__(self, session, parent=None, nested=False):
- self.session = session
- self._connections = {}
- self._parent = parent
- self.nested = nested
- self._active = True
- self._prepared = False
- if not parent and nested:
- raise sa_exc.InvalidRequestError(
- "Can't start a SAVEPOINT transaction when no existing "
- "transaction is in progress")
-
- if self.session._enable_transaction_accounting:
- self._take_snapshot()
-
- @property
- def is_active(self):
- return self.session is not None and self._active
-
- def _assert_is_active(self):
- self._assert_is_open()
- if not self._active:
- if self._rollback_exception:
- raise sa_exc.InvalidRequestError(
- "This Session's transaction has been rolled back "
- "due to a previous exception during flush."
- " To begin a new transaction with this Session, "
- "first issue Session.rollback()."
- " Original exception was: %s"
- % self._rollback_exception
- )
- else:
- raise sa_exc.InvalidRequestError(
- "This Session's transaction has been rolled back "
- "by a nested rollback() call. To begin a new "
- "transaction, issue Session.rollback() first."
- )
-
- def _assert_is_open(self, error_msg="The transaction is closed"):
- if self.session is None:
- raise sa_exc.ResourceClosedError(error_msg)
-
- @property
- def _is_transaction_boundary(self):
- return self.nested or not self._parent
-
- def connection(self, bindkey, **kwargs):
- self._assert_is_active()
- engine = self.session.get_bind(bindkey, **kwargs)
- return self._connection_for_bind(engine)
-
- def _begin(self, nested=False):
- self._assert_is_active()
- return SessionTransaction(
- self.session, self, nested=nested)
-
- def _iterate_parents(self, upto=None):
- if self._parent is upto:
- return (self,)
- else:
- if self._parent is None:
- raise sa_exc.InvalidRequestError(
- "Transaction %s is not on the active transaction list" % (
- upto))
- return (self,) + self._parent._iterate_parents(upto)
-
- def _take_snapshot(self):
- if not self._is_transaction_boundary:
- self._new = self._parent._new
- self._deleted = self._parent._deleted
- return
-
- if not self.session._flushing:
- self.session.flush()
-
- self._new = weakref.WeakKeyDictionary()
- self._deleted = weakref.WeakKeyDictionary()
-
- def _restore_snapshot(self):
- assert self._is_transaction_boundary
-
- for s in set(self._new).union(self.session._new):
- self.session._expunge_state(s)
- if s.key:
- del s.key
-
- for s in set(self._deleted).union(self.session._deleted):
- if s.deleted:
- #assert s in self._deleted
- del s.deleted
- self.session._update_impl(s)
-
- assert not self.session._deleted
-
- for s in self.session.identity_map.all_states():
- s.expire(s.dict, self.session.identity_map._modified)
-
- def _remove_snapshot(self):
- assert self._is_transaction_boundary
-
- if not self.nested and self.session.expire_on_commit:
- for s in self.session.identity_map.all_states():
- s.expire(s.dict, self.session.identity_map._modified)
-
- def _connection_for_bind(self, bind):
- self._assert_is_active()
-
- if bind in self._connections:
- return self._connections[bind][0]
-
- if self._parent:
- conn = self._parent._connection_for_bind(bind)
- if not self.nested:
- return conn
- else:
- if isinstance(bind, engine.Connection):
- conn = bind
- if conn.engine in self._connections:
- raise sa_exc.InvalidRequestError(
- "Session already has a Connection associated for the "
- "given Connection's Engine")
- else:
- conn = bind.contextual_connect()
-
- if self.session.twophase and self._parent is None:
- transaction = conn.begin_twophase()
- elif self.nested:
- transaction = conn.begin_nested()
- else:
- transaction = conn.begin()
-
- self._connections[conn] = self._connections[conn.engine] = \
- (conn, transaction, conn is not bind)
- self.session.dispatch.after_begin(self.session, self, conn)
- return conn
-
- def prepare(self):
- if self._parent is not None or not self.session.twophase:
- raise sa_exc.InvalidRequestError(
- "Only root two phase transactions of can be prepared")
- self._prepare_impl()
-
- def _prepare_impl(self):
- self._assert_is_active()
- if self._parent is None or self.nested:
- self.session.dispatch.before_commit(self.session)
-
- stx = self.session.transaction
- if stx is not self:
- for subtransaction in stx._iterate_parents(upto=self):
- subtransaction.commit()
-
- if not self.session._flushing:
- self.session.flush()
-
- if self._parent is None and self.session.twophase:
- try:
- for t in set(self._connections.values()):
- t[1].prepare()
- except:
- self.rollback()
- raise
-
- self._deactivate()
- self._prepared = True
-
- def commit(self):
- self._assert_is_open()
- if not self._prepared:
- self._prepare_impl()
-
- if self._parent is None or self.nested:
- for t in set(self._connections.values()):
- t[1].commit()
-
- self.session.dispatch.after_commit(self.session)
-
- if self.session._enable_transaction_accounting:
- self._remove_snapshot()
-
- self.close()
- return self._parent
-
- def rollback(self, _capture_exception=False):
- self._assert_is_open()
-
- stx = self.session.transaction
- if stx is not self:
- for subtransaction in stx._iterate_parents(upto=self):
- subtransaction.close()
-
- if self.is_active or self._prepared:
- for transaction in self._iterate_parents():
- if transaction._parent is None or transaction.nested:
- transaction._rollback_impl()
- transaction._deactivate()
- break
- else:
- transaction._deactivate()
-
- self.close()
- if self._parent and _capture_exception:
- self._parent._rollback_exception = sys.exc_info()[1]
- return self._parent
-
- def _rollback_impl(self):
- for t in set(self._connections.values()):
- t[1].rollback()
-
- if self.session._enable_transaction_accounting:
- self._restore_snapshot()
-
- self.session.dispatch.after_rollback(self.session)
-
- def _deactivate(self):
- self._active = False
-
- def close(self):
- self.session.transaction = self._parent
- if self._parent is None:
- for connection, transaction, autoclose in \
- set(self._connections.values()):
- if autoclose:
- connection.close()
- else:
- transaction.close()
- if not self.session.autocommit:
- self.session.begin()
- self._deactivate()
- self.session = None
- self._connections = None
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self._assert_is_open("Cannot end transaction context. The transaction "
- "was closed from within the context")
- if self.session.transaction is None:
- return
- if type is None:
- try:
- self.commit()
- except:
- self.rollback()
- raise
- else:
- self.rollback()
-
-class Session(object):
- """Manages persistence operations for ORM-mapped objects.
-
- The Session's usage paradigm is described at :ref:`session_toplevel`.
-
-
- """
-
- public_methods = (
- '__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
- 'close', 'commit', 'connection', 'delete', 'execute', 'expire',
- 'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
- 'is_modified',
- 'merge', 'query', 'refresh', 'rollback',
- 'scalar')
-
-
- def __init__(self, bind=None, autoflush=True, expire_on_commit=True,
- _enable_transaction_accounting=True,
- autocommit=False, twophase=False,
- weak_identity_map=True, binds=None, extension=None,
- query_cls=query.Query):
- """Construct a new Session.
-
- See also the :func:`.sessionmaker` function which is used to
- generate a :class:`.Session`-producing callable with a given
- set of arguments.
-
- :param autocommit: Defaults to ``False``. When ``True``, the ``Session``
- does not keep a persistent transaction running, and will acquire
- connections from the engine on an as-needed basis, returning them
- immediately after their use. Flushes will begin and commit (or possibly
- rollback) their own transaction if no transaction is present. When using
- this mode, the `session.begin()` method may be used to begin a
- transaction explicitly.
-
- Leaving it on its default value of ``False`` means that the ``Session``
- will acquire a connection and begin a transaction the first time it is
- used, which it will maintain persistently until ``rollback()``,
- ``commit()``, or ``close()`` is called. When the transaction is released
- by any of these methods, the ``Session`` is ready for the next usage,
- which will again acquire and maintain a new connection/transaction.
-
- :param autoflush: When ``True``, all query operations will issue a
- ``flush()`` call to this ``Session`` before proceeding. This is a
- convenience feature so that ``flush()`` need not be called repeatedly
- in order for database queries to retrieve results. It's typical that
- ``autoflush`` is used in conjunction with ``autocommit=False``. In this
- scenario, explicit calls to ``flush()`` are rarely needed; you usually
- only need to call ``commit()`` (which flushes) to finalize changes.
-
- :param bind: An optional ``Engine`` or ``Connection`` to which this
- ``Session`` should be bound. When specified, all SQL operations
- performed by this session will execute via this connectable.
-
- :param binds: An optional dictionary which contains more granular "bind"
- information than the ``bind`` parameter provides. This dictionary can
- map individual ``Table`` instances as well as ``Mapper`` instances to
- individual ``Engine`` or ``Connection`` objects. Operations which
- proceed relative to a particular ``Mapper`` will consult this
- dictionary for the direct ``Mapper`` instance as well as the mapper's
- ``mapped_table`` attribute in order to locate an connectable to use.
- The full resolution is described in the ``get_bind()`` method of
- ``Session``. Usage looks like::
-
- Session = sessionmaker(binds={
- SomeMappedClass: create_engine('postgresql://engine1'),
- somemapper: create_engine('postgresql://engine2'),
- some_table: create_engine('postgresql://engine3'),
- })
-
- Also see the :meth:`.Session.bind_mapper` and :meth:`.Session.bind_table` methods.
-
- :param \class_: Specify an alternate class other than
- ``sqlalchemy.orm.session.Session`` which should be used by the returned
- class. This is the only argument that is local to the
- ``sessionmaker()`` function, and is not sent directly to the
- constructor for ``Session``.
-
- :param _enable_transaction_accounting: Defaults to ``True``. A
- legacy-only flag which when ``False`` disables *all* 0.5-style object
- accounting on transaction boundaries, including auto-expiry of
- instances on rollback and commit, maintenance of the "new" and
- "deleted" lists upon rollback, and autoflush of pending changes upon
- begin(), all of which are interdependent.
-
- :param expire_on_commit: Defaults to ``True``. When ``True``, all
- instances will be fully expired after each ``commit()``, so that all
- attribute/object access subsequent to a completed transaction will load
- from the most recent database state.
-
- :param extension: An optional
- :class:`~.SessionExtension` instance, or a list
- of such instances, which will receive pre- and post- commit and flush
- events, as well as a post-rollback event. **Deprecated.**
- Please see :class:`.SessionEvents`.
-
- :param query_cls: Class which should be used to create new Query objects,
- as returned by the ``query()`` method. Defaults to
- :class:`~sqlalchemy.orm.query.Query`.
-
- :param twophase: When ``True``, all transactions will be started as
- a "two phase" transaction, i.e. using the "two phase" semantics
- of the database in use along with an XID. During a ``commit()``,
- after ``flush()`` has been issued for all attached databases, the
- ``prepare()`` method on each database's ``TwoPhaseTransaction`` will
- be called. This allows each database to roll back the entire
- transaction, before each transaction is committed.
-
- :param weak_identity_map: Defaults to ``True`` - when set to
- ``False``, objects placed in the :class:`.Session` will be
- strongly referenced until explicitly removed or the
- :class:`.Session` is closed. **Deprecated** - this option
- is obsolete.
-
- """
-
- if weak_identity_map:
- self._identity_cls = identity.WeakInstanceDict
- else:
- util.warn_deprecated("weak_identity_map=False is deprecated. "
- "This feature is not needed.")
- self._identity_cls = identity.StrongInstanceDict
- self.identity_map = self._identity_cls()
-
- self._new = {} # InstanceState->object, strong refs object
- self._deleted = {} # same
- self.bind = bind
- self.__binds = {}
- self._flushing = False
- self.transaction = None
- self.hash_key = id(self)
- self.autoflush = autoflush
- self.autocommit = autocommit
- self.expire_on_commit = expire_on_commit
- self._enable_transaction_accounting = _enable_transaction_accounting
- self.twophase = twophase
- self._query_cls = query_cls
-
- if extension:
- for ext in util.to_list(extension):
- SessionExtension._adapt_listener(self, ext)
-
- if binds is not None:
- for mapperortable, bind in binds.iteritems():
- if isinstance(mapperortable, (type, Mapper)):
- self.bind_mapper(mapperortable, bind)
- else:
- self.bind_table(mapperortable, bind)
-
- if not self.autocommit:
- self.begin()
- _sessions[self.hash_key] = self
-
- dispatch = event.dispatcher(SessionEvents)
-
- connection_callable = None
-
- def begin(self, subtransactions=False, nested=False):
- """Begin a transaction on this Session.
-
- If this Session is already within a transaction, either a plain
- transaction or nested transaction, an error is raised, unless
- ``subtransactions=True`` or ``nested=True`` is specified.
-
- The ``subtransactions=True`` flag indicates that this :meth:`~.Session.begin`
- can create a subtransaction if a transaction is already in progress.
- For documentation on subtransactions, please see :ref:`session_subtransactions`.
-
- The ``nested`` flag begins a SAVEPOINT transaction and is equivalent
- to calling :meth:`~.Session.begin_nested`. For documentation on SAVEPOINT
- transactions, please see :ref:`session_begin_nested`.
-
- """
- if self.transaction is not None:
- if subtransactions or nested:
- self.transaction = self.transaction._begin(
- nested=nested)
- else:
- raise sa_exc.InvalidRequestError(
- "A transaction is already begun. Use subtransactions=True "
- "to allow subtransactions.")
- else:
- self.transaction = SessionTransaction(
- self, nested=nested)
- return self.transaction # needed for __enter__/__exit__ hook
-
- def begin_nested(self):
- """Begin a `nested` transaction on this Session.
-
- The target database(s) must support SQL SAVEPOINTs or a
- SQLAlchemy-supported vendor implementation of the idea.
-
- For documentation on SAVEPOINT
- transactions, please see :ref:`session_begin_nested`.
-
- """
- return self.begin(nested=True)
-
- def rollback(self):
- """Rollback the current transaction in progress.
-
- If no transaction is in progress, this method is a pass-through.
-
- This method rolls back the current transaction or nested transaction
- regardless of subtransactions being in effect. All subtransactions up
- to the first real transaction are closed. Subtransactions occur when
- begin() is called multiple times.
-
- """
- if self.transaction is None:
- pass
- else:
- self.transaction.rollback()
-
- def commit(self):
- """Flush pending changes and commit the current transaction.
-
- If no transaction is in progress, this method raises an
- InvalidRequestError.
-
- By default, the :class:`.Session` also expires all database
- loaded state on all ORM-managed attributes after transaction commit.
- This so that subsequent operations load the most recent
- data from the database. This behavior can be disabled using
- the ``expire_on_commit=False`` option to :func:`.sessionmaker` or
- the :class:`.Session` constructor.
-
- If a subtransaction is in effect (which occurs when begin() is called
- multiple times), the subtransaction will be closed, and the next call
- to ``commit()`` will operate on the enclosing transaction.
-
- For a session configured with autocommit=False, a new transaction will
- be begun immediately after the commit, but note that the newly begun
- transaction does *not* use any connection resources until the first
- SQL is actually emitted.
-
- """
- if self.transaction is None:
- if not self.autocommit:
- self.begin()
- else:
- raise sa_exc.InvalidRequestError("No transaction is begun.")
-
- self.transaction.commit()
-
- def prepare(self):
- """Prepare the current transaction in progress for two phase commit.
-
- If no transaction is in progress, this method raises an
- InvalidRequestError.
-
- Only root transactions of two phase sessions can be prepared. If the
- current transaction is not such, an InvalidRequestError is raised.
-
- """
- if self.transaction is None:
- if not self.autocommit:
- self.begin()
- else:
- raise sa_exc.InvalidRequestError("No transaction is begun.")
-
- self.transaction.prepare()
-
- def connection(self, mapper=None, clause=None,
- bind=None,
- close_with_result=False,
- **kw):
- """Return a :class:`.Connection` object corresponding to this
- :class:`.Session` object's transactional state.
-
- If this :class:`.Session` is configured with ``autocommit=False``,
- either the :class:`.Connection` corresponding to the current transaction
- is returned, or if no transaction is in progress, a new one is begun
- and the :class:`.Connection` returned.
-
- Alternatively, if this :class:`.Session` is configured with ``autocommit=True``,
- an ad-hoc :class:`.Connection` is returned using :meth:`.Engine.contextual_connect`
- on the underlying :class:`.Engine`.
-
- Ambiguity in multi-bind or unbound :class:`.Session` objects can be resolved through
- any of the optional keyword arguments. This ultimately makes usage of the
- :meth:`.get_bind` method for resolution.
-
- :param bind:
- Optional :class:`.Engine` to be used as the bind. If
- this engine is already involved in an ongoing transaction,
- that connection will be used. This argument takes precedence
- over ``mapper``, ``clause``.
-
- :param mapper:
- Optional :func:`.mapper` mapped class, used to identify
- the appropriate bind. This argument takes precedence over
- ``clause``.
-
- :param clause:
- A :class:`.ClauseElement` (i.e. :func:`~.sql.expression.select`,
- :func:`~.sql.expression.text`,
- etc.) which will be used to locate a bind, if a bind
- cannot otherwise be identified.
-
- :param close_with_result: Passed to :meth:`Engine.connect`, indicating
- the :class:`.Connection` should be considered "single use", automatically
- closing when the first result set is closed. This flag only has
- an effect if this :class:`.Session` is configured with ``autocommit=True``
- and does not already have a transaction in progress.
-
- :param \**kw:
- Additional keyword arguments are sent to :meth:`get_bind()`,
- allowing additional arguments to be passed to custom
- implementations of :meth:`get_bind`.
-
- """
- if bind is None:
- bind = self.get_bind(mapper, clause=clause, **kw)
-
- return self._connection_for_bind(bind,
- close_with_result=close_with_result)
-
- def _connection_for_bind(self, engine, **kwargs):
- if self.transaction is not None:
- return self.transaction._connection_for_bind(engine)
- else:
- return engine.contextual_connect(**kwargs)
-
- def execute(self, clause, params=None, mapper=None, bind=None, **kw):
- """Execute a clause within the current transaction.
-
- Returns a :class:`.ResultProxy` representing
- results of the statement execution, in the same manner as that of an
- :class:`.Engine` or
- :class:`.Connection`.
-
- :meth:`~.Session.execute` accepts any executable clause construct, such
- as :func:`~.sql.expression.select`,
- :func:`~.sql.expression.insert`,
- :func:`~.sql.expression.update`,
- :func:`~.sql.expression.delete`, and
- :func:`~.sql.expression.text`, and additionally accepts
- plain strings that represent SQL statements. If a plain string is
- passed, it is first converted to a
- :func:`~.sql.expression.text` construct, which here means
- that bind parameters should be specified using the format ``:param``.
-
- The statement is executed within the current transactional context of
- this :class:`.Session`, using the same behavior as that of
- the :meth:`.Session.connection` method to determine the active
- :class:`.Connection`. The ``close_with_result`` flag is
- set to ``True`` so that an ``autocommit=True`` :class:`.Session`
- with no active transaction will produce a result that auto-closes
- the underlying :class:`.Connection`.
-
- :param clause:
- A :class:`.ClauseElement` (i.e. :func:`~.sql.expression.select`,
- :func:`~.sql.expression.text`, etc.) or string SQL statement to be executed. The clause
- will also be used to locate a bind, if this :class:`.Session`
- is not bound to a single engine already, and the ``mapper``
- and ``bind`` arguments are not passed.
-
- :param params:
- Optional dictionary of bind names mapped to values.
-
- :param mapper:
- Optional :func:`.mapper` or mapped class, used to identify
- the appropriate bind. This argument takes precedence over
- ``clause`` when locating a bind.
-
- :param bind:
- Optional :class:`.Engine` to be used as the bind. If
- this engine is already involved in an ongoing transaction,
- that connection will be used. This argument takes
- precedence over ``mapper`` and ``clause`` when locating
- a bind.
-
- :param \**kw:
- Additional keyword arguments are sent to :meth:`get_bind()`,
- allowing additional arguments to be passed to custom
- implementations of :meth:`get_bind`.
-
- """
- clause = expression._literal_as_text(clause)
-
- if bind is None:
- bind = self.get_bind(mapper, clause=clause, **kw)
-
- return self._connection_for_bind(bind, close_with_result=True).execute(
- clause, params or {})
-
- def scalar(self, clause, params=None, mapper=None, bind=None, **kw):
- """Like :meth:`~.Session.execute` but return a scalar result."""
-
- return self.execute(clause, params=params, mapper=mapper, bind=bind, **kw).scalar()
-
- def close(self):
- """Close this Session.
-
- This clears all items and ends any transaction in progress.
-
- If this session were created with ``autocommit=False``, a new
- transaction is immediately begun. Note that this new transaction does
- not use any connection resources until they are first needed.
-
- """
- self.expunge_all()
- if self.transaction is not None:
- for transaction in self.transaction._iterate_parents():
- transaction.close()
-
- @classmethod
- def close_all(cls):
- """Close *all* sessions in memory."""
-
- for sess in _sessions.values():
- sess.close()
-
- def expunge_all(self):
- """Remove all object instances from this ``Session``.
-
- This is equivalent to calling ``expunge(obj)`` on all objects in this
- ``Session``.
-
- """
- for state in self.identity_map.all_states() + list(self._new):
- state.detach()
-
- self.identity_map = self._identity_cls()
- self._new = {}
- self._deleted = {}
-
- # TODO: need much more test coverage for bind_mapper() and similar !
- # TODO: + crystalize + document resolution order vis. bind_mapper/bind_table
-
- def bind_mapper(self, mapper, bind):
- """Bind operations for a mapper to a Connectable.
-
- mapper
- A mapper instance or mapped class
-
- bind
- Any Connectable: a ``Engine`` or ``Connection``.
-
- All subsequent operations involving this mapper will use the given
- `bind`.
-
- """
- if isinstance(mapper, type):
- mapper = _class_mapper(mapper)
-
- self.__binds[mapper.base_mapper] = bind
- for t in mapper._all_tables:
- self.__binds[t] = bind
-
- def bind_table(self, table, bind):
- """Bind operations on a Table to a Connectable.
-
- table
- A ``Table`` instance
-
- bind
- Any Connectable: a ``Engine`` or ``Connection``.
-
- All subsequent operations involving this ``Table`` will use the
- given `bind`.
-
- """
- self.__binds[table] = bind
-
- def get_bind(self, mapper, clause=None):
- """Return an engine corresponding to the given arguments.
-
- All arguments are optional.
-
- mapper
- Optional, a ``Mapper`` or mapped class
-
- clause
- Optional, A ClauseElement (i.e. select(), text(), etc.)
-
- """
- if mapper is clause is None:
- if self.bind:
- return self.bind
- else:
- raise sa_exc.UnboundExecutionError(
- "This session is not bound to a single Engine or "
- "Connection, and no context was provided to locate "
- "a binding.")
-
- c_mapper = mapper is not None and _class_to_mapper(mapper) or None
-
- # manually bound?
- if self.__binds:
- if c_mapper:
- if c_mapper.base_mapper in self.__binds:
- return self.__binds[c_mapper.base_mapper]
- elif c_mapper.mapped_table in self.__binds:
- return self.__binds[c_mapper.mapped_table]
- if clause is not None:
- for t in sql_util.find_tables(clause, include_crud=True):
- if t in self.__binds:
- return self.__binds[t]
-
- if self.bind:
- return self.bind
-
- if isinstance(clause, sql.expression.ClauseElement) and clause.bind:
- return clause.bind
-
- if c_mapper and c_mapper.mapped_table.bind:
- return c_mapper.mapped_table.bind
-
- context = []
- if mapper is not None:
- context.append('mapper %s' % c_mapper)
- if clause is not None:
- context.append('SQL expression')
-
- raise sa_exc.UnboundExecutionError(
- "Could not locate a bind configured on %s or this Session" % (
- ', '.join(context)))
-
- def query(self, *entities, **kwargs):
- """Return a new ``Query`` object corresponding to this ``Session``."""
-
- return self._query_cls(entities, self, **kwargs)
-
- def _autoflush(self):
- if self.autoflush and not self._flushing:
- self.flush()
-
- def _finalize_loaded(self, states):
- for state, dict_ in states.items():
- state.commit_all(dict_, self.identity_map)
-
- def refresh(self, instance, attribute_names=None, lockmode=None):
- """Expire and refresh the attributes on the given instance.
-
- A query will be issued to the database and all attributes will be
- refreshed with their current database value.
-
- Lazy-loaded relational attributes will remain lazily loaded, so that
- the instance-wide refresh operation will be followed immediately by
- the lazy load of that attribute.
-
- Eagerly-loaded relational attributes will eagerly load within the
- single refresh operation.
-
- Note that a highly isolated transaction will return the same values as
- were previously read in that same transaction, regardless of changes
- in database state outside of that transaction - usage of
- :meth:`~Session.refresh` usually only makes sense if non-ORM SQL
- statement were emitted in the ongoing transaction, or if autocommit
- mode is turned on.
-
- :param attribute_names: optional. An iterable collection of
- string attribute names indicating a subset of attributes to
- be refreshed.
-
- :param lockmode: Passed to the :class:`~sqlalchemy.orm.query.Query`
- as used by :meth:`~sqlalchemy.orm.query.Query.with_lockmode`.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
-
- self._expire_state(state, attribute_names)
-
- if self.query(_object_mapper(instance))._load_on_ident(
- state.key, refresh_state=state,
- lockmode=lockmode,
- only_load_props=attribute_names) is None:
- raise sa_exc.InvalidRequestError(
- "Could not refresh instance '%s'" %
- mapperutil.instance_str(instance))
-
- def expire_all(self):
- """Expires all persistent instances within this Session.
-
- When any attributes on a persistent instance is next accessed,
- a query will be issued using the
- :class:`.Session` object's current transactional context in order to
- load all expired attributes for the given instance. Note that
- a highly isolated transaction will return the same values as were
- previously read in that same transaction, regardless of changes
- in database state outside of that transaction.
-
- To expire individual objects and individual attributes
- on those objects, use :meth:`Session.expire`.
-
- The :class:`.Session` object's default behavior is to
- expire all state whenever the :meth:`Session.rollback`
- or :meth:`Session.commit` methods are called, so that new
- state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire_all` should not be needed when
- autocommit is ``False``, assuming the transaction is isolated.
-
- """
- for state in self.identity_map.all_states():
- state.expire(state.dict, self.identity_map._modified)
-
- def expire(self, instance, attribute_names=None):
- """Expire the attributes on an instance.
-
- Marks the attributes of an instance as out of date. When an expired
- attribute is next accessed, a query will be issued to the
- :class:`.Session` object's current transactional context in order to
- load all expired attributes for the given instance. Note that
- a highly isolated transaction will return the same values as were
- previously read in that same transaction, regardless of changes
- in database state outside of that transaction.
-
- To expire all objects in the :class:`.Session` simultaneously,
- use :meth:`Session.expire_all`.
-
- The :class:`.Session` object's default behavior is to
- expire all state whenever the :meth:`Session.rollback`
- or :meth:`Session.commit` methods are called, so that new
- state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire` only makes sense for the specific
- case that a non-ORM SQL statement was emitted in the current
- transaction.
-
- :param instance: The instance to be refreshed.
- :param attribute_names: optional list of string attribute names
- indicating a subset of attributes to be expired.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
- self._expire_state(state, attribute_names)
-
- def _expire_state(self, state, attribute_names):
- self._validate_persistent(state)
- if attribute_names:
- state.expire_attributes(state.dict, attribute_names)
- else:
- # pre-fetch the full cascade since the expire is going to
- # remove associations
- cascaded = list(state.manager.mapper.cascade_iterator(
- 'refresh-expire', state))
- self._conditional_expire(state)
- for o, m, st_, dct_ in cascaded:
- self._conditional_expire(st_)
-
- def _conditional_expire(self, state):
- """Expire a state if persistent, else expunge if pending"""
-
- if state.key:
- state.expire(state.dict, self.identity_map._modified)
- elif state in self._new:
- self._new.pop(state)
- state.detach()
-
- @util.deprecated("0.7", "The non-weak-referencing identity map "
- "feature is no longer needed.")
- def prune(self):
- """Remove unreferenced instances cached in the identity map.
-
- Note that this method is only meaningful if "weak_identity_map" is set
- to False. The default weak identity map is self-pruning.
-
- Removes any object in this Session's identity map that is not
- referenced in user code, modified, new or scheduled for deletion.
- Returns the number of objects pruned.
-
- """
- return self.identity_map.prune()
-
- def expunge(self, instance):
- """Remove the `instance` from this ``Session``.
-
- This will free all internal references to the instance. Cascading
- will be applied according to the *expunge* cascade rule.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
- if state.session_id is not self.hash_key:
- raise sa_exc.InvalidRequestError(
- "Instance %s is not present in this Session" %
- mapperutil.state_str(state))
-
- cascaded = list(state.manager.mapper.cascade_iterator(
- 'expunge', state))
- self._expunge_state(state)
- for o, m, st_, dct_ in cascaded:
- self._expunge_state(st_)
-
- def _expunge_state(self, state):
- if state in self._new:
- self._new.pop(state)
- state.detach()
- elif self.identity_map.contains_state(state):
- self.identity_map.discard(state)
- self._deleted.pop(state, None)
- state.detach()
-
- def _register_newly_persistent(self, state):
- mapper = _state_mapper(state)
-
- # prevent against last minute dereferences of the object
- obj = state.obj()
- if obj is not None:
-
- instance_key = mapper._identity_key_from_state(state)
-
- if _none_set.issubset(instance_key[1]) and \
- not mapper.allow_partial_pks or \
- _none_set.issuperset(instance_key[1]):
- raise exc.FlushError('Instance %s has a NULL identity '
- 'key. Check if this flush is occurring at an '
- 'inappropriate time, such as during a load '
- 'operation.' % mapperutil.state_str(state))
-
- if state.key is None:
- state.key = instance_key
- elif state.key != instance_key:
- # primary key switch. use discard() in case another
- # state has already replaced this one in the identity
- # map (see test/orm/test_naturalpks.py ReversePKsTest)
- self.identity_map.discard(state)
- state.key = instance_key
-
- self.identity_map.replace(state)
- state.commit_all(state.dict, self.identity_map)
-
- # remove from new last, might be the last strong ref
- if state in self._new:
- if self._enable_transaction_accounting and self.transaction:
- self.transaction._new[state] = True
- self._new.pop(state)
-
- def _remove_newly_deleted(self, state):
- if self._enable_transaction_accounting and self.transaction:
- self.transaction._deleted[state] = True
-
- self.identity_map.discard(state)
- self._deleted.pop(state, None)
- state.deleted = True
-
- def add(self, instance):
- """Place an object in the ``Session``.
-
- Its state will be persisted to the database on the next flush
- operation.
-
- Repeated calls to ``add()`` will be ignored. The opposite of ``add()``
- is ``expunge()``.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
-
- self._save_or_update_state(state)
-
- def add_all(self, instances):
- """Add the given collection of instances to this ``Session``."""
-
- for instance in instances:
- self.add(instance)
-
- def _save_or_update_state(self, state):
- self._save_or_update_impl(state)
-
- mapper = _state_mapper(state)
- for o, m, st_, dct_ in mapper.cascade_iterator(
- 'save-update',
- state,
- halt_on=self._contains_state):
- self._save_or_update_impl(st_)
-
- def delete(self, instance):
- """Mark an instance as deleted.
-
- The database delete operation occurs upon ``flush()``.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
-
- if state.key is None:
- raise sa_exc.InvalidRequestError(
- "Instance '%s' is not persisted" %
- mapperutil.state_str(state))
-
- if state in self._deleted:
- return
-
- # ensure object is attached to allow the
- # cascade operation to load deferred attributes
- # and collections
- self._attach(state)
-
- # grab the cascades before adding the item to the deleted list
- # so that autoflush does not delete the item
- # the strong reference to the instance itself is significant here
- cascade_states = list(state.manager.mapper.cascade_iterator(
- 'delete', state))
-
- self._deleted[state] = state.obj()
- self.identity_map.add(state)
-
- for o, m, st_, dct_ in cascade_states:
- self._delete_impl(st_)
-
- def merge(self, instance, load=True, **kw):
- """Copy the state an instance onto the persistent instance with the
- same identifier.
-
- If there is no persistent instance currently associated with the
- session, it will be loaded. Return the persistent instance. If the
- given instance is unsaved, save a copy of and return it as a newly
- persistent instance. The given instance does not become associated
- with the session.
-
- This operation cascades to associated instances if the association is
- mapped with ``cascade="merge"``.
-
- See :ref:`unitofwork_merging` for a detailed discussion of merging.
-
- """
- if 'dont_load' in kw:
- load = not kw['dont_load']
- util.warn_deprecated('dont_load=True has been renamed to '
- 'load=False.')
-
- _recursive = {}
-
- if load:
- # flush current contents if we expect to load data
- self._autoflush()
-
- _object_mapper(instance) # verify mapped
- autoflush = self.autoflush
- try:
- self.autoflush = False
- return self._merge(
- attributes.instance_state(instance),
- attributes.instance_dict(instance),
- load=load, _recursive=_recursive)
- finally:
- self.autoflush = autoflush
-
- def _merge(self, state, state_dict, load=True, _recursive=None):
- mapper = _state_mapper(state)
- if state in _recursive:
- return _recursive[state]
-
- new_instance = False
- key = state.key
-
- if key is None:
- if not load:
- raise sa_exc.InvalidRequestError(
- "merge() with load=False option does not support "
- "objects transient (i.e. unpersisted) objects. flush() "
- "all changes on mapped instances before merging with "
- "load=False.")
- key = mapper._identity_key_from_state(state)
-
- if key in self.identity_map:
- merged = self.identity_map[key]
-
- elif not load:
- if state.modified:
- raise sa_exc.InvalidRequestError(
- "merge() with load=False option does not support "
- "objects marked as 'dirty'. flush() all changes on "
- "mapped instances before merging with load=False.")
- merged = mapper.class_manager.new_instance()
- merged_state = attributes.instance_state(merged)
- merged_state.key = key
- self._update_impl(merged_state)
- new_instance = True
-
- elif not _none_set.issubset(key[1]) or \
- (mapper.allow_partial_pks and
- not _none_set.issuperset(key[1])):
- merged = self.query(mapper.class_).get(key[1])
- else:
- merged = None
-
- if merged is None:
- merged = mapper.class_manager.new_instance()
- merged_state = attributes.instance_state(merged)
- merged_dict = attributes.instance_dict(merged)
- new_instance = True
- self._save_or_update_state(merged_state)
- else:
- merged_state = attributes.instance_state(merged)
- merged_dict = attributes.instance_dict(merged)
-
- _recursive[state] = merged
-
- # check that we didn't just pull the exact same
- # state out.
- if state is not merged_state:
- # version check if applicable
- if mapper.version_id_col is not None:
- existing_version = mapper._get_state_attr_by_column(
- state,
- state_dict,
- mapper.version_id_col,
- passive=attributes.PASSIVE_NO_INITIALIZE)
-
- merged_version = mapper._get_state_attr_by_column(
- merged_state,
- merged_dict,
- mapper.version_id_col,
- passive=attributes.PASSIVE_NO_INITIALIZE)
-
- if existing_version is not attributes.PASSIVE_NO_RESULT and \
- merged_version is not attributes.PASSIVE_NO_RESULT and \
- existing_version != merged_version:
- raise exc.StaleDataError(
- "Version id '%s' on merged state %s "
- "does not match existing version '%s'. "
- "Leave the version attribute unset when "
- "merging to update the most recent version."
- % (
- existing_version,
- mapperutil.state_str(merged_state),
- merged_version
- ))
-
- merged_state.load_path = state.load_path
- merged_state.load_options = state.load_options
-
- for prop in mapper.iterate_properties:
- prop.merge(self, state, state_dict,
- merged_state, merged_dict,
- load, _recursive)
-
- if not load:
- # remove any history
- merged_state.commit_all(merged_dict, self.identity_map)
-
- if new_instance:
- merged_state.manager.dispatch.load(merged_state, None)
- return merged
-
- @classmethod
- def identity_key(cls, *args, **kwargs):
- return mapperutil.identity_key(*args, **kwargs)
-
- @classmethod
- def object_session(cls, instance):
- """Return the ``Session`` to which an object belongs."""
-
- return object_session(instance)
-
- def _validate_persistent(self, state):
- if not self.identity_map.contains_state(state):
- raise sa_exc.InvalidRequestError(
- "Instance '%s' is not persistent within this Session" %
- mapperutil.state_str(state))
-
- def _save_impl(self, state):
- if state.key is not None:
- raise sa_exc.InvalidRequestError(
- "Object '%s' already has an identity - it can't be registered "
- "as pending" % mapperutil.state_str(state))
-
- self._attach(state)
- if state not in self._new:
- self._new[state] = state.obj()
- state.insert_order = len(self._new)
-
- def _update_impl(self, state):
- if (self.identity_map.contains_state(state) and
- state not in self._deleted):
- return
-
- if state.key is None:
- raise sa_exc.InvalidRequestError(
- "Instance '%s' is not persisted" %
- mapperutil.state_str(state))
-
- if state.deleted:
- raise sa_exc.InvalidRequestError(
- "Instance '%s' has been deleted. Use the make_transient() "
- "function to send this object back to the transient state." %
- mapperutil.state_str(state)
- )
- self._attach(state)
- self._deleted.pop(state, None)
- self.identity_map.add(state)
-
- def _save_or_update_impl(self, state):
- if state.key is None:
- self._save_impl(state)
- else:
- self._update_impl(state)
-
- def _delete_impl(self, state):
- if state in self._deleted:
- return
-
- if state.key is None:
- return
-
- self._attach(state)
- self._deleted[state] = state.obj()
- self.identity_map.add(state)
-
- def _attach(self, state):
- if state.key and \
- state.key in self.identity_map and \
- not self.identity_map.contains_state(state):
- raise sa_exc.InvalidRequestError("Can't attach instance "
- "%s; another instance with key %s is already "
- "present in this session."
- % (mapperutil.state_str(state), state.key))
-
- if state.session_id and state.session_id is not self.hash_key:
- raise sa_exc.InvalidRequestError(
- "Object '%s' is already attached to session '%s' "
- "(this is '%s')" % (mapperutil.state_str(state),
- state.session_id, self.hash_key))
-
- if state.session_id != self.hash_key:
- state.session_id = self.hash_key
- if self.dispatch.after_attach:
- self.dispatch.after_attach(self, state.obj())
-
- def __contains__(self, instance):
- """Return True if the instance is associated with this session.
-
- The instance may be pending or persistent within the Session for a
- result of True.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
- return self._contains_state(state)
-
- def __iter__(self):
- """Iterate over all pending or persistent instances within this Session."""
-
- return iter(list(self._new.values()) + self.identity_map.values())
-
- def _contains_state(self, state):
- return state in self._new or self.identity_map.contains_state(state)
-
- def flush(self, objects=None):
- """Flush all the object changes to the database.
-
- Writes out all pending object creations, deletions and modifications
- to the database as INSERTs, DELETEs, UPDATEs, etc. Operations are
- automatically ordered by the Session's unit of work dependency
- solver..
-
- Database operations will be issued in the current transactional
- context and do not affect the state of the transaction, unless an
- error occurs, in which case the entire transaction is rolled back.
- You may flush() as often as you like within a transaction to move
- changes from Python to the database's transaction buffer.
-
- For ``autocommit`` Sessions with no active manual transaction, flush()
- will create a transaction on the fly that surrounds the entire set of
- operations int the flush.
-
- objects
- Optional; a list or tuple collection. Restricts the flush operation
- to only these objects, rather than all pending changes.
- Deprecated - this flag prevents the session from properly maintaining
- accounting among inter-object relations and can cause invalid results.
-
- """
-
- if objects:
- util.warn_deprecated(
- "The 'objects' argument to session.flush() is deprecated; "
- "Please do not add objects to the session which should not "
- "yet be persisted.")
-
- if self._flushing:
- raise sa_exc.InvalidRequestError("Session is already flushing")
-
- try:
- self._flushing = True
- self._flush(objects)
- finally:
- self._flushing = False
-
- def _flush(self, objects=None):
- if (not self.identity_map.check_modified() and
- not self._deleted and not self._new):
- return
-
- dirty = self._dirty_states
- if not dirty and not self._deleted and not self._new:
- self.identity_map._modified.clear()
- return
-
- flush_context = UOWTransaction(self)
-
- if self.dispatch.before_flush:
- self.dispatch.before_flush(self, flush_context, objects)
- # re-establish "dirty states" in case the listeners
- # added
- dirty = self._dirty_states
-
- deleted = set(self._deleted)
- new = set(self._new)
-
- dirty = set(dirty).difference(deleted)
-
- # create the set of all objects we want to operate upon
- if objects:
- # specific list passed in
- objset = set()
- for o in objects:
- try:
- state = attributes.instance_state(o)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(o)
- objset.add(state)
- else:
- objset = None
-
- # store objects whose fate has been decided
- processed = set()
-
- # put all saves/updates into the flush context. detect top-level
- # orphans and throw them into deleted.
- if objset:
- proc = new.union(dirty).intersection(objset).difference(deleted)
- else:
- proc = new.union(dirty).difference(deleted)
-
- for state in proc:
- is_orphan = _state_mapper(state)._is_orphan(state) and state.has_identity
- flush_context.register_object(state, isdelete=is_orphan)
- processed.add(state)
-
- # put all remaining deletes into the flush context.
- if objset:
- proc = deleted.intersection(objset).difference(processed)
- else:
- proc = deleted.difference(processed)
- for state in proc:
- flush_context.register_object(state, isdelete=True)
-
- if not flush_context.has_work:
- return
-
- flush_context.transaction = transaction = self.begin(
- subtransactions=True)
- try:
- flush_context.execute()
-
- self.dispatch.after_flush(self, flush_context)
-
- flush_context.finalize_flush_changes()
-
- # useful assertions:
- #if not objects:
- # assert not self.identity_map._modified
- #else:
- # assert self.identity_map._modified == \
- # self.identity_map._modified.difference(objects)
-
- self.dispatch.after_flush_postexec(self, flush_context)
-
- transaction.commit()
-
- except:
- transaction.rollback(_capture_exception=True)
- raise
-
-
- def is_modified(self, instance, include_collections=True,
- passive=attributes.PASSIVE_OFF):
- """Return ``True`` if instance has modified attributes.
-
- This method retrieves a history instance for each instrumented
- attribute on the instance and performs a comparison of the current
- value to its previously committed value.
-
- ``include_collections`` indicates if multivalued collections should be
- included in the operation. Setting this to False is a way to detect
- only local-column based properties (i.e. scalar columns or many-to-one
- foreign keys) that would result in an UPDATE for this instance upon
- flush.
-
- The ``passive`` flag indicates if unloaded attributes and collections
- should not be loaded in the course of performing this test.
- Allowed values include :attr:`.PASSIVE_OFF`, :attr:`.PASSIVE_NO_INITIALIZE`.
-
- A few caveats to this method apply:
-
- * Instances present in the 'dirty' collection may result in a value
- of ``False`` when tested with this method. This because while
- the object may have received attribute set events, there may be
- no net changes on its state.
- * Scalar attributes may not have recorded the "previously" set
- value when a new value was applied, if the attribute was not loaded,
- or was expired, at the time the new value was received - in these
- cases, the attribute is assumed to have a change, even if there is
- ultimately no net change against its database value. SQLAlchemy in
- most cases does not need the "old" value when a set event occurs, so
- it skips the expense of a SQL call if the old value isn't present,
- based on the assumption that an UPDATE of the scalar value is
- usually needed, and in those few cases where it isn't, is less
- expensive on average than issuing a defensive SELECT.
-
- The "old" value is fetched unconditionally only if the attribute
- container has the "active_history" flag set to ``True``. This flag
- is set typically for primary key attributes and scalar references
- that are not a simple many-to-one.
-
- """
- try:
- state = attributes.instance_state(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
- dict_ = state.dict
- if passive is True:
- passive = attributes.PASSIVE_NO_INITIALIZE
- elif passive is False:
- passive = attributes.PASSIVE_OFF
- for attr in state.manager.attributes:
- if \
- (
- not include_collections and
- hasattr(attr.impl, 'get_collection')
- ) or not hasattr(attr.impl, 'get_history'):
- continue
-
- (added, unchanged, deleted) = \
- attr.impl.get_history(state, dict_, passive=passive)
-
- if added or deleted:
- return True
- return False
-
- @property
- def is_active(self):
- """True if this Session has an active transaction."""
-
- return self.transaction and self.transaction.is_active
-
- @property
- def _dirty_states(self):
- """The set of all persistent states considered dirty.
-
- This method returns all states that were modified including
- those that were possibly deleted.
-
- """
- return self.identity_map._dirty_states()
-
- @property
- def dirty(self):
- """The set of all persistent instances considered dirty.
-
- Instances are considered dirty when they were modified but not
- deleted.
-
- Note that this 'dirty' calculation is 'optimistic'; most
- attribute-setting or collection modification operations will
- mark an instance as 'dirty' and place it in this set, even if
- there is no net change to the attribute's value. At flush
- time, the value of each attribute is compared to its
- previously saved value, and if there's no net change, no SQL
- operation will occur (this is a more expensive operation so
- it's only done at flush time).
-
- To check if an instance has actionable net changes to its
- attributes, use the is_modified() method.
-
- """
- return util.IdentitySet(
- [state.obj()
- for state in self._dirty_states
- if state not in self._deleted])
-
- @property
- def deleted(self):
- "The set of all instances marked as 'deleted' within this ``Session``"
-
- return util.IdentitySet(self._deleted.values())
-
- @property
- def new(self):
- "The set of all instances marked as 'new' within this ``Session``."
-
- return util.IdentitySet(self._new.values())
-
-_sessions = weakref.WeakValueDictionary()
-
-def make_transient(instance):
- """Make the given instance 'transient'.
-
- This will remove its association with any
- session and additionally will remove its "identity key",
- such that it's as though the object were newly constructed,
- except retaining its values. It also resets the
- "deleted" flag on the state if this object
- had been explicitly deleted by its session.
-
- Attributes which were "expired" or deferred at the
- instance level are reverted to undefined, and
- will not trigger any loads.
-
- """
- state = attributes.instance_state(instance)
- s = _state_session(state)
- if s:
- s._expunge_state(state)
-
- # remove expired state and
- # deferred callables
- state.callables.clear()
- if state.key:
- del state.key
- if state.deleted:
- del state.deleted
-
-def object_session(instance):
- """Return the ``Session`` to which instance belongs.
-
- If the instance is not a mapped instance, an error is raised.
-
- """
-
- try:
- return _state_session(attributes.instance_state(instance))
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
-
-
-def _state_session(state):
- if state.session_id:
- try:
- return _sessions[state.session_id]
- except KeyError:
- pass
- return None
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/shard.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/shard.py
deleted file mode 100755
index 5d57472d..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/shard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# orm/shard.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy import util
-
-util.warn_deprecated(
- "Horizontal sharding is now importable via "
- "'import sqlalchemy.ext.horizontal_shard"
-)
-
-from sqlalchemy.ext.horizontal_shard import *
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/state.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/state.py
deleted file mode 100755
index 0963a526..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/state.py
+++ /dev/null
@@ -1,557 +0,0 @@
-# orm/state.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Defines instrumentation of instances.
-
-This module is usually not directly visible to user applications, but
-defines a large part of the ORM's interactivity.
-
-"""
-
-from sqlalchemy.util import EMPTY_SET
-import weakref
-from sqlalchemy import util
-
-from sqlalchemy.orm import exc as orm_exc, attributes, interfaces,\
- util as orm_util
-from sqlalchemy.orm.attributes import PASSIVE_OFF, PASSIVE_NO_RESULT, \
- PASSIVE_NO_FETCH, NEVER_SET, ATTR_WAS_SET, NO_VALUE
-
-mapperlib = util.importlater("sqlalchemy.orm", "mapperlib")
-
-import sys
-
-class InstanceState(object):
- """tracks state information at the instance level."""
-
- session_id = None
- key = None
- runid = None
- load_options = EMPTY_SET
- load_path = ()
- insert_order = None
- mutable_dict = None
- _strong_obj = None
- modified = False
- expired = False
- deleted = False
-
- def __init__(self, obj, manager):
- self.class_ = obj.__class__
- self.manager = manager
- self.obj = weakref.ref(obj, self._cleanup)
- self.callables = {}
- self.committed_state = {}
-
- @util.memoized_property
- def parents(self):
- return {}
-
- @util.memoized_property
- def pending(self):
- return {}
-
- @property
- def has_identity(self):
- return bool(self.key)
-
- def detach(self):
- self.session_id = None
-
- def dispose(self):
- self.detach()
- del self.obj
-
- def _cleanup(self, ref):
- instance_dict = self._instance_dict()
- if instance_dict:
- instance_dict.discard(self)
-
- self.callables = {}
- self.session_id = None
- del self.obj
-
- def obj(self):
- return None
-
- @property
- def dict(self):
- o = self.obj()
- if o is not None:
- return attributes.instance_dict(o)
- else:
- return {}
-
- @property
- def sort_key(self):
- return self.key and self.key[1] or (self.insert_order, )
-
- def initialize_instance(*mixed, **kwargs):
- self, instance, args = mixed[0], mixed[1], mixed[2:]
- manager = self.manager
-
- manager.dispatch.init(self, args, kwargs)
-
- #if manager.mutable_attributes:
- # assert self.__class__ is MutableAttrInstanceState
-
- try:
- return manager.original_init(*mixed[1:], **kwargs)
- except:
- manager.dispatch.init_failure(self, args, kwargs)
- raise
-
- def get_history(self, key, passive):
- return self.manager[key].impl.get_history(self, self.dict, passive)
-
- def get_impl(self, key):
- return self.manager[key].impl
-
- def get_pending(self, key):
- if key not in self.pending:
- self.pending[key] = PendingCollection()
- return self.pending[key]
-
- def value_as_iterable(self, dict_, key, passive=PASSIVE_OFF):
- """Return a list of tuples (state, obj) for the given
- key.
-
- returns an empty list if the value is None/empty/PASSIVE_NO_RESULT
- """
-
- impl = self.manager[key].impl
- x = impl.get(self, dict_, passive=passive)
- if x is PASSIVE_NO_RESULT or x is None:
- return []
- elif hasattr(impl, 'get_collection'):
- return [
- (attributes.instance_state(o), o) for o in
- impl.get_collection(self, dict_, x, passive=passive)
- ]
- else:
- return [(attributes.instance_state(x), x)]
-
- def __getstate__(self):
- d = {'instance':self.obj()}
-
- d.update(
- (k, self.__dict__[k]) for k in (
- 'committed_state', 'pending', 'parents', 'modified', 'expired',
- 'callables', 'key', 'load_options', 'mutable_dict'
- ) if k in self.__dict__
- )
- if self.load_path:
- d['load_path'] = interfaces.serialize_path(self.load_path)
-
- self.manager.dispatch.pickle(self, d)
-
- return d
-
- def __setstate__(self, state):
- from sqlalchemy.orm import instrumentation
- self.obj = weakref.ref(state['instance'], self._cleanup)
- self.class_ = state['instance'].__class__
- self.manager = manager = instrumentation.manager_of_class(self.class_)
- if manager is None:
- raise orm_exc.UnmappedInstanceError(
- state['instance'],
- "Cannot deserialize object of type %r - no mapper() has"
- " been configured for this class within the current Python process!" %
- self.class_)
- elif manager.is_mapped and not manager.mapper.configured:
- mapperlib.configure_mappers()
-
- self.committed_state = state.get('committed_state', {})
- self.pending = state.get('pending', {})
- self.parents = state.get('parents', {})
- self.modified = state.get('modified', False)
- self.expired = state.get('expired', False)
- self.callables = state.get('callables', {})
-
- if self.modified:
- self._strong_obj = state['instance']
-
- self.__dict__.update([
- (k, state[k]) for k in (
- 'key', 'load_options', 'mutable_dict'
- ) if k in state
- ])
-
- if 'load_path' in state:
- self.load_path = interfaces.deserialize_path(state['load_path'])
-
- manager.dispatch.unpickle(self, state)
-
- def initialize(self, key):
- """Set this attribute to an empty value or collection,
- based on the AttributeImpl in use."""
-
- self.manager.get_impl(key).initialize(self, self.dict)
-
- def reset(self, dict_, key):
- """Remove the given attribute and any
- callables associated with it."""
-
- dict_.pop(key, None)
- self.callables.pop(key, None)
-
- def expire_attribute_pre_commit(self, dict_, key):
- """a fast expire that can be called by column loaders during a load.
-
- The additional bookkeeping is finished up in commit_all().
-
- This method is actually called a lot with joined-table
- loading, when the second table isn't present in the result.
-
- """
- dict_.pop(key, None)
- self.callables[key] = self
-
- def set_callable(self, dict_, key, callable_):
- """Remove the given attribute and set the given callable
- as a loader."""
-
- dict_.pop(key, None)
- self.callables[key] = callable_
-
- def expire(self, dict_, modified_set):
- self.expired = True
- if self.modified:
- modified_set.discard(self)
-
- self.modified = False
-
- pending = self.__dict__.get('pending', None)
- mutable_dict = self.mutable_dict
- self.committed_state.clear()
- if mutable_dict:
- mutable_dict.clear()
- if pending:
- pending.clear()
-
- for key in self.manager:
- impl = self.manager[key].impl
- if impl.accepts_scalar_loader and \
- (impl.expire_missing or key in dict_):
- self.callables[key] = self
- dict_.pop(key, None)
-
- self.manager.dispatch.expire(self, None)
-
- def expire_attributes(self, dict_, attribute_names):
- pending = self.__dict__.get('pending', None)
- mutable_dict = self.mutable_dict
-
- for key in attribute_names:
- impl = self.manager[key].impl
- if impl.accepts_scalar_loader:
- self.callables[key] = self
- dict_.pop(key, None)
-
- self.committed_state.pop(key, None)
- if mutable_dict:
- mutable_dict.pop(key, None)
- if pending:
- pending.pop(key, None)
-
- self.manager.dispatch.expire(self, attribute_names)
-
- def __call__(self, passive):
- """__call__ allows the InstanceState to act as a deferred
- callable for loading expired attributes, which is also
- serializable (picklable).
-
- """
-
- if passive is PASSIVE_NO_FETCH:
- return PASSIVE_NO_RESULT
-
- toload = self.expired_attributes.\
- intersection(self.unmodified)
-
- self.manager.deferred_scalar_loader(self, toload)
-
- # if the loader failed, or this
- # instance state didn't have an identity,
- # the attributes still might be in the callables
- # dict. ensure they are removed.
- for k in toload.intersection(self.callables):
- del self.callables[k]
-
- return ATTR_WAS_SET
-
- @property
- def unmodified(self):
- """Return the set of keys which have no uncommitted changes"""
-
- return set(self.manager).difference(self.committed_state)
-
- def unmodified_intersection(self, keys):
- """Return self.unmodified.intersection(keys)."""
-
- return set(keys).intersection(self.manager).\
- difference(self.committed_state)
-
-
- @property
- def unloaded(self):
- """Return the set of keys which do not have a loaded value.
-
- This includes expired attributes and any other attribute that
- was never populated or modified.
-
- """
- return set(self.manager).\
- difference(self.committed_state).\
- difference(self.dict)
-
- @property
- def expired_attributes(self):
- """Return the set of keys which are 'expired' to be loaded by
- the manager's deferred scalar loader, assuming no pending
- changes.
-
- see also the ``unmodified`` collection which is intersected
- against this set when a refresh operation occurs.
-
- """
- return set([k for k, v in self.callables.items() if v is self])
-
- def _instance_dict(self):
- return None
-
- def _is_really_none(self):
- return self.obj()
-
- def modified_event(self, dict_, attr, previous, collection=False):
- if attr.key not in self.committed_state:
- if collection:
- if previous is NEVER_SET:
- if attr.key in dict_:
- previous = dict_[attr.key]
-
- if previous not in (None, NO_VALUE, NEVER_SET):
- previous = attr.copy(previous)
-
- self.committed_state[attr.key] = previous
-
- # the "or not self.modified" is defensive at
- # this point. The assertion below is expected
- # to be True:
- # assert self._strong_obj is None or self.modified
-
- if self._strong_obj is None or not self.modified:
- instance_dict = self._instance_dict()
- if instance_dict:
- instance_dict._modified.add(self)
-
- self._strong_obj = self.obj()
- if self._strong_obj is None:
- raise orm_exc.ObjectDereferencedError(
- "Can't emit change event for attribute '%s' - "
- "parent object of type %s has been garbage "
- "collected."
- % (
- self.manager[attr.key],
- orm_util.state_class_str(self)
- ))
- self.modified = True
-
- def commit(self, dict_, keys):
- """Commit attributes.
-
- This is used by a partial-attribute load operation to mark committed
- those attributes which were refreshed from the database.
-
- Attributes marked as "expired" can potentially remain "expired" after
- this step if a value was not populated in state.dict.
-
- """
- class_manager = self.manager
- if class_manager.mutable_attributes:
- for key in keys:
- if key in dict_ and key in class_manager.mutable_attributes:
- self.committed_state[key] = self.manager[key].impl.copy(dict_[key])
- else:
- self.committed_state.pop(key, None)
- else:
- for key in keys:
- self.committed_state.pop(key, None)
-
- self.expired = False
-
- for key in set(self.callables).\
- intersection(keys).\
- intersection(dict_):
- del self.callables[key]
-
- def commit_all(self, dict_, instance_dict=None):
- """commit all attributes unconditionally.
-
- This is used after a flush() or a full load/refresh
- to remove all pending state from the instance.
-
- - all attributes are marked as "committed"
- - the "strong dirty reference" is removed
- - the "modified" flag is set to False
- - any "expired" markers/callables for attributes loaded are removed.
-
- Attributes marked as "expired" can potentially remain "expired" after this step
- if a value was not populated in state.dict.
-
- """
-
- self.committed_state.clear()
- self.__dict__.pop('pending', None)
-
- callables = self.callables
- for key in list(callables):
- if key in dict_ and callables[key] is self:
- del callables[key]
-
- for key in self.manager.mutable_attributes:
- if key in dict_:
- self.committed_state[key] = self.manager[key].impl.copy(dict_[key])
-
- if instance_dict and self.modified:
- instance_dict._modified.discard(self)
-
- self.modified = self.expired = False
- self._strong_obj = None
-
-class MutableAttrInstanceState(InstanceState):
- """InstanceState implementation for objects that reference 'mutable'
- attributes.
-
- Has a more involved "cleanup" handler that checks mutable attributes
- for changes upon dereference, resurrecting if needed.
-
- """
-
- @util.memoized_property
- def mutable_dict(self):
- return {}
-
- def _get_modified(self, dict_=None):
- if self.__dict__.get('modified', False):
- return True
- else:
- if dict_ is None:
- dict_ = self.dict
- for key in self.manager.mutable_attributes:
- if self.manager[key].impl.check_mutable_modified(self, dict_):
- return True
- else:
- return False
-
- def _set_modified(self, value):
- self.__dict__['modified'] = value
-
- modified = property(_get_modified, _set_modified)
-
- @property
- def unmodified(self):
- """a set of keys which have no uncommitted changes"""
-
- dict_ = self.dict
-
- return set([
- key for key in self.manager
- if (key not in self.committed_state or
- (key in self.manager.mutable_attributes and
- not self.manager[key].impl.check_mutable_modified(self, dict_)))])
-
- def unmodified_intersection(self, keys):
- """Return self.unmodified.intersection(keys)."""
-
- dict_ = self.dict
-
- return set([
- key for key in keys
- if (key not in self.committed_state or
- (key in self.manager.mutable_attributes and
- not self.manager[key].impl.check_mutable_modified(self, dict_)))])
-
-
- def _is_really_none(self):
- """do a check modified/resurrect.
-
- This would be called in the extremely rare
- race condition that the weakref returned None but
- the cleanup handler had not yet established the
- __resurrect callable as its replacement.
-
- """
- if self.modified:
- self.obj = self.__resurrect
- return self.obj()
- else:
- return None
-
- def reset(self, dict_, key):
- self.mutable_dict.pop(key, None)
- InstanceState.reset(self, dict_, key)
-
- def _cleanup(self, ref):
- """weakref callback.
-
- This method may be called by an asynchronous
- gc.
-
- If the state shows pending changes, the weakref
- is replaced by the __resurrect callable which will
- re-establish an object reference on next access,
- else removes this InstanceState from the owning
- identity map, if any.
-
- """
- if self._get_modified(self.mutable_dict):
- self.obj = self.__resurrect
- else:
- instance_dict = self._instance_dict()
- if instance_dict:
- instance_dict.discard(self)
- self.dispose()
-
- def __resurrect(self):
- """A substitute for the obj() weakref function which resurrects."""
-
- # store strong ref'ed version of the object; will revert
- # to weakref when changes are persisted
- obj = self.manager.new_instance(state=self)
- self.obj = weakref.ref(obj, self._cleanup)
- self._strong_obj = obj
- obj.__dict__.update(self.mutable_dict)
-
- # re-establishes identity attributes from the key
- self.manager.dispatch.resurrect(self)
-
- return obj
-
-class PendingCollection(object):
- """A writable placeholder for an unloaded collection.
-
- Stores items appended to and removed from a collection that has not yet
- been loaded. When the collection is loaded, the changes stored in
- PendingCollection are applied to it to produce the final result.
-
- """
- def __init__(self):
- self.deleted_items = util.IdentitySet()
- self.added_items = util.OrderedIdentitySet()
-
- def append(self, value):
- if value in self.deleted_items:
- self.deleted_items.remove(value)
- else:
- self.added_items.add(value)
-
- def remove(self, value):
- if value in self.added_items:
- self.added_items.remove(value)
- else:
- self.deleted_items.add(value)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/strategies.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/strategies.py
deleted file mode 100755
index acdac998..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/strategies.py
+++ /dev/null
@@ -1,1300 +0,0 @@
-# orm/strategies.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""sqlalchemy.orm.interfaces.LoaderStrategy
- implementations, and related MapperOptions."""
-
-from sqlalchemy import exc as sa_exc
-from sqlalchemy import sql, util, log, event
-from sqlalchemy.sql import util as sql_util
-from sqlalchemy.sql import visitors, expression, operators
-from sqlalchemy.orm import mapper, attributes, interfaces, exc as orm_exc
-from sqlalchemy.orm.mapper import _none_set
-from sqlalchemy.orm.interfaces import (
- LoaderStrategy, StrategizedOption, MapperOption, PropertyOption,
- serialize_path, deserialize_path, StrategizedProperty
- )
-from sqlalchemy.orm import session as sessionlib, unitofwork
-from sqlalchemy.orm import util as mapperutil
-from sqlalchemy.orm.query import Query
-import itertools
-
-def _register_attribute(strategy, mapper, useobject,
- compare_function=None,
- typecallable=None,
- copy_function=None,
- mutable_scalars=False,
- uselist=False,
- callable_=None,
- proxy_property=None,
- active_history=False,
- impl_class=None,
- **kw
-):
-
- prop = strategy.parent_property
-
- attribute_ext = list(util.to_list(prop.extension, default=[]))
-
- listen_hooks = []
-
- if useobject and prop.single_parent:
- listen_hooks.append(single_parent_validator)
-
- if prop.key in prop.parent._validators:
- listen_hooks.append(
- lambda desc, prop: mapperutil._validator_events(desc,
- prop.key,
- prop.parent._validators[prop.key])
- )
-
- if useobject:
- listen_hooks.append(unitofwork.track_cascade_events)
-
- # need to assemble backref listeners
- # after the singleparentvalidator, mapper validator
- backref = kw.pop('backref', None)
- if backref:
- listen_hooks.append(
- lambda desc, prop: attributes.backref_listeners(desc,
- backref,
- uselist)
- )
-
- for m in mapper.self_and_descendants:
- if prop is m._props.get(prop.key):
-
- desc = attributes.register_attribute_impl(
- m.class_,
- prop.key,
- parent_token=prop,
- mutable_scalars=mutable_scalars,
- uselist=uselist,
- copy_function=copy_function,
- compare_function=compare_function,
- useobject=useobject,
- extension=attribute_ext,
- trackparent=useobject,
- typecallable=typecallable,
- callable_=callable_,
- active_history=active_history,
- impl_class=impl_class,
- doc=prop.doc,
- **kw
- )
-
- for hook in listen_hooks:
- hook(desc, prop)
-
-class UninstrumentedColumnLoader(LoaderStrategy):
- """Represent the a non-instrumented MapperProperty.
-
- The polymorphic_on argument of mapper() often results in this,
- if the argument is against the with_polymorphic selectable.
-
- """
- def init(self):
- self.columns = self.parent_property.columns
-
- def setup_query(self, context, entity, path, reduced_path, adapter,
- column_collection=None, **kwargs):
- for c in self.columns:
- if adapter:
- c = adapter.columns[c]
- column_collection.append(c)
-
- def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
- return None, None, None
-
-class ColumnLoader(LoaderStrategy):
- """Strategize the loading of a plain column-based MapperProperty."""
-
- def init(self):
- self.columns = self.parent_property.columns
- self.is_composite = hasattr(self.parent_property, 'composite_class')
-
- def setup_query(self, context, entity, path, reduced_path, adapter,
- column_collection=None, **kwargs):
- for c in self.columns:
- if adapter:
- c = adapter.columns[c]
- column_collection.append(c)
-
- def init_class_attribute(self, mapper):
- self.is_class_level = True
- coltype = self.columns[0].type
- # TODO: check all columns ? check for foreign key as well?
- active_history = self.parent_property.active_history or \
- self.columns[0].primary_key
-
- _register_attribute(self, mapper, useobject=False,
- compare_function=coltype.compare_values,
- copy_function=coltype.copy_value,
- mutable_scalars=self.columns[0].type.is_mutable(),
- active_history = active_history
- )
-
- def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
- key = self.key
- # look through list of columns represented here
- # to see which, if any, is present in the row.
- for col in self.columns:
- if adapter:
- col = adapter.columns[col]
- if col is not None and col in row:
- def new_execute(state, dict_, row):
- dict_[key] = row[col]
- return new_execute, None, None
- else:
- def new_execute(state, dict_, row):
- state.expire_attribute_pre_commit(dict_, key)
- return new_execute, None, None
-
-log.class_logger(ColumnLoader)
-
-class DeferredColumnLoader(LoaderStrategy):
- """Strategize the loading of a deferred column-based MapperProperty."""
-
- def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
- col = self.columns[0]
- if adapter:
- col = adapter.columns[col]
-
- key = self.key
- if col in row:
- return self.parent_property._get_strategy(ColumnLoader).\
- create_row_processor(
- selectcontext, path, reduced_path, mapper, row, adapter)
-
- elif not self.is_class_level:
- def new_execute(state, dict_, row):
- state.set_callable(dict_, key, LoadDeferredColumns(state, key))
- else:
- def new_execute(state, dict_, row):
- # reset state on the key so that deferred callables
- # fire off on next access.
- state.reset(dict_, key)
-
- return new_execute, None, None
-
- def init(self):
- if hasattr(self.parent_property, 'composite_class'):
- raise NotImplementedError("Deferred loading for composite "
- "types not implemented yet")
- self.columns = self.parent_property.columns
- self.group = self.parent_property.group
-
- def init_class_attribute(self, mapper):
- self.is_class_level = True
-
- _register_attribute(self, mapper, useobject=False,
- compare_function=self.columns[0].type.compare_values,
- copy_function=self.columns[0].type.copy_value,
- mutable_scalars=self.columns[0].type.is_mutable(),
- callable_=self._load_for_state,
- expire_missing=False
- )
-
- def setup_query(self, context, entity, path, reduced_path, adapter,
- only_load_props=None, **kwargs):
- if (
- self.group is not None and
- context.attributes.get(('undefer', self.group), False)
- ) or (only_load_props and self.key in only_load_props):
- self.parent_property._get_strategy(ColumnLoader).\
- setup_query(context, entity,
- path, reduced_path, adapter, **kwargs)
-
- def _load_for_state(self, state, passive):
- if not state.key:
- return attributes.ATTR_EMPTY
-
- if passive is attributes.PASSIVE_NO_FETCH:
- return attributes.PASSIVE_NO_RESULT
-
- prop = self.parent_property
- localparent = state.manager.mapper
-
- if self.group:
- toload = [
- p.key for p in
- localparent.iterate_properties
- if isinstance(p, StrategizedProperty) and
- isinstance(p.strategy, DeferredColumnLoader) and
- p.group==self.group
- ]
- else:
- toload = [self.key]
-
- # narrow the keys down to just those which have no history
- group = [k for k in toload if k in state.unmodified]
-
- session = sessionlib._state_session(state)
- if session is None:
- raise orm_exc.DetachedInstanceError(
- "Parent instance %s is not bound to a Session; "
- "deferred load operation of attribute '%s' cannot proceed" %
- (mapperutil.state_str(state), self.key)
- )
-
- query = session.query(localparent)
- query._load_on_ident(state.key,
- only_load_props=group, refresh_state=state)
- return attributes.ATTR_WAS_SET
-
-log.class_logger(DeferredColumnLoader)
-
-class LoadDeferredColumns(object):
- """serializable loader object used by DeferredColumnLoader"""
-
- def __init__(self, state, key):
- self.state = state
- self.key = key
-
- def __call__(self, passive=attributes.PASSIVE_OFF):
- state, key = self.state, self.key
-
- localparent = state.manager.mapper
- prop = localparent._props[key]
- strategy = prop._strategies[DeferredColumnLoader]
- return strategy._load_for_state(state, passive)
-
-class DeferredOption(StrategizedOption):
- propagate_to_loaders = True
-
- def __init__(self, key, defer=False):
- super(DeferredOption, self).__init__(key)
- self.defer = defer
-
- def get_strategy_class(self):
- if self.defer:
- return DeferredColumnLoader
- else:
- return ColumnLoader
-
-class UndeferGroupOption(MapperOption):
- propagate_to_loaders = True
-
- def __init__(self, group):
- self.group = group
-
- def process_query(self, query):
- query._attributes[('undefer', self.group)] = True
-
-class AbstractRelationshipLoader(LoaderStrategy):
- """LoaderStratgies which deal with related objects."""
-
- def init(self):
- self.mapper = self.parent_property.mapper
- self.target = self.parent_property.target
- self.table = self.parent_property.table
- self.uselist = self.parent_property.uselist
-
-class NoLoader(AbstractRelationshipLoader):
- """Strategize a relationship() that doesn't load data automatically."""
-
- def init_class_attribute(self, mapper):
- self.is_class_level = True
-
- _register_attribute(self, mapper,
- useobject=True,
- uselist=self.parent_property.uselist,
- typecallable = self.parent_property.collection_class,
- )
-
- def create_row_processor(self, selectcontext, path, reduced_path, mapper, row, adapter):
- def new_execute(state, dict_, row):
- state.initialize(self.key)
- return new_execute, None, None
-
-log.class_logger(NoLoader)
-
-class LazyLoader(AbstractRelationshipLoader):
- """Strategize a relationship() that loads when first accessed."""
-
- def init(self):
- super(LazyLoader, self).init()
- self.__lazywhere, \
- self.__bind_to_col, \
- self._equated_columns = self._create_lazy_clause(self.parent_property)
-
- self.logger.info("%s lazy loading clause %s", self, self.__lazywhere)
-
- # determine if our "lazywhere" clause is the same as the mapper's
- # get() clause. then we can just use mapper.get()
- #from sqlalchemy.orm import query
- self.use_get = not self.uselist and \
- self.mapper._get_clause[0].compare(
- self.__lazywhere,
- use_proxies=True,
- equivalents=self.mapper._equivalent_columns
- )
-
- if self.use_get:
- for col in self._equated_columns.keys():
- if col in self.mapper._equivalent_columns:
- for c in self.mapper._equivalent_columns[col]:
- self._equated_columns[c] = self._equated_columns[col]
-
- self.logger.info("%s will use query.get() to "
- "optimize instance loads" % self)
-
- def init_class_attribute(self, mapper):
- self.is_class_level = True
-
- # MANYTOONE currently only needs the
- # "old" value for delete-orphan
- # cascades. the required _SingleParentValidator
- # will enable active_history
- # in that case. otherwise we don't need the
- # "old" value during backref operations.
- _register_attribute(self,
- mapper,
- useobject=True,
- callable_=self._load_for_state,
- uselist = self.parent_property.uselist,
- backref = self.parent_property.back_populates,
- typecallable = self.parent_property.collection_class,
- active_history = \
- self.parent_property.active_history or \
- self.parent_property.direction is not \
- interfaces.MANYTOONE or \
- not self.use_get,
- )
-
- def lazy_clause(self, state, reverse_direction=False,
- alias_secondary=False,
- adapt_source=None):
- if state is None:
- return self._lazy_none_clause(
- reverse_direction,
- adapt_source=adapt_source)
-
- if not reverse_direction:
- criterion, bind_to_col, rev = \
- self.__lazywhere, \
- self.__bind_to_col, \
- self._equated_columns
- else:
- criterion, bind_to_col, rev = \
- LazyLoader._create_lazy_clause(
- self.parent_property,
- reverse_direction=reverse_direction)
-
- if reverse_direction:
- mapper = self.parent_property.mapper
- else:
- mapper = self.parent_property.parent
-
- o = state.obj() # strong ref
- dict_ = attributes.instance_dict(o)
-
- # use the "committed state" only if we're in a flush
- # for this state.
-
- sess = sessionlib._state_session(state)
- if sess is not None and sess._flushing:
- def visit_bindparam(bindparam):
- if bindparam.key in bind_to_col:
- bindparam.callable = \
- lambda: mapper._get_committed_state_attr_by_column(
- state, dict_, bind_to_col[bindparam.key])
- else:
- def visit_bindparam(bindparam):
- if bindparam.key in bind_to_col:
- bindparam.callable = lambda: mapper._get_state_attr_by_column(
- state, dict_, bind_to_col[bindparam.key])
-
-
- if self.parent_property.secondary is not None and alias_secondary:
- criterion = sql_util.ClauseAdapter(
- self.parent_property.secondary.alias()).\
- traverse(criterion)
-
- criterion = visitors.cloned_traverse(
- criterion, {}, {'bindparam':visit_bindparam})
-
- if adapt_source:
- criterion = adapt_source(criterion)
- return criterion
-
- def _lazy_none_clause(self, reverse_direction=False, adapt_source=None):
- if not reverse_direction:
- criterion, bind_to_col, rev = \
- self.__lazywhere, \
- self.__bind_to_col,\
- self._equated_columns
- else:
- criterion, bind_to_col, rev = \
- LazyLoader._create_lazy_clause(
- self.parent_property,
- reverse_direction=reverse_direction)
-
- criterion = sql_util.adapt_criterion_to_null(criterion, bind_to_col)
-
- if adapt_source:
- criterion = adapt_source(criterion)
- return criterion
-
- def _load_for_state(self, state, passive):
- if not state.key and \
- (not self.parent_property.load_on_pending or not state.session_id):
- return attributes.ATTR_EMPTY
-
- instance_mapper = state.manager.mapper
- prop = self.parent_property
- key = self.key
- prop_mapper = self.mapper
- pending = not state.key
-
- if (
- (passive is attributes.PASSIVE_NO_FETCH or \
- passive is attributes.PASSIVE_NO_FETCH_RELATED) and
- not self.use_get
- ) or (
- passive is attributes.PASSIVE_ONLY_PERSISTENT and
- pending
- ):
- return attributes.PASSIVE_NO_RESULT
-
- session = sessionlib._state_session(state)
- if not session:
- raise orm_exc.DetachedInstanceError(
- "Parent instance %s is not bound to a Session; "
- "lazy load operation of attribute '%s' cannot proceed" %
- (mapperutil.state_str(state), key)
- )
-
- # if we have a simple primary key load, check the
- # identity map without generating a Query at all
- if self.use_get:
- if session._flushing:
- get_attr = instance_mapper._get_committed_state_attr_by_column
- else:
- get_attr = instance_mapper._get_state_attr_by_column
-
- dict_ = state.dict
- if passive is attributes.PASSIVE_NO_FETCH_RELATED:
- attr_passive = attributes.PASSIVE_OFF
- else:
- attr_passive = passive
-
- ident = [
- get_attr(
- state,
- state.dict,
- self._equated_columns[pk],
- passive=attr_passive)
- for pk in prop_mapper.primary_key
- ]
- if attributes.PASSIVE_NO_RESULT in ident:
- return attributes.PASSIVE_NO_RESULT
-
- if _none_set.issuperset(ident):
- return None
-
- ident_key = prop_mapper.identity_key_from_primary_key(ident)
- instance = Query._get_from_identity(session, ident_key, passive)
- if instance is not None:
- return instance
- elif passive is attributes.PASSIVE_NO_FETCH or \
- passive is attributes.PASSIVE_NO_FETCH_RELATED:
- return attributes.PASSIVE_NO_RESULT
-
- q = session.query(prop_mapper)._adapt_all_clauses()
-
- # don't autoflush on pending
- if pending:
- q = q.autoflush(False)
-
- if state.load_path:
- q = q._with_current_path(state.load_path + (key,))
-
- if state.load_options:
- q = q._conditional_options(*state.load_options)
-
- if self.use_get:
- return q._load_on_ident(ident_key)
-
- if prop.order_by:
- q = q.order_by(*util.to_list(prop.order_by))
-
- for rev in prop._reverse_property:
- # reverse props that are MANYTOONE are loading *this*
- # object from get(), so don't need to eager out to those.
- if rev.direction is interfaces.MANYTOONE and \
- rev._use_get and \
- not isinstance(rev.strategy, LazyLoader):
- q = q.options(EagerLazyOption((rev.key,), lazy='select'))
-
- lazy_clause = self.lazy_clause(state)
-
- if pending:
- bind_values = sql_util.bind_values(lazy_clause)
- if None in bind_values:
- return None
-
- q = q.filter(lazy_clause)
-
- result = q.all()
- if self.uselist:
- return result
- else:
- l = len(result)
- if l:
- if l > 1:
- util.warn(
- "Multiple rows returned with "
- "uselist=False for lazily-loaded attribute '%s' "
- % prop)
-
- return result[0]
- else:
- return None
-
- def create_row_processor(self, selectcontext, path, reduced_path,
- mapper, row, adapter):
- key = self.key
- if not self.is_class_level:
- def new_execute(state, dict_, row):
- # we are not the primary manager for this attribute
- # on this class - set up a
- # per-instance lazyloader, which will override the
- # class-level behavior.
- # this currently only happens when using a
- # "lazyload" option on a "no load"
- # attribute - "eager" attributes always have a
- # class-level lazyloader installed.
- state.set_callable(dict_, key, LoadLazyAttribute(state, key))
- else:
- def new_execute(state, dict_, row):
- # we are the primary manager for this attribute on
- # this class - reset its
- # per-instance attribute state, so that the class-level
- # lazy loader is
- # executed when next referenced on this instance.
- # this is needed in
- # populate_existing() types of scenarios to reset
- # any existing state.
- state.reset(dict_, key)
-
- return new_execute, None, None
-
- @classmethod
- def _create_lazy_clause(cls, prop, reverse_direction=False):
- binds = util.column_dict()
- lookup = util.column_dict()
- equated_columns = util.column_dict()
-
- if reverse_direction and prop.secondaryjoin is None:
- for l, r in prop.local_remote_pairs:
- _list = lookup.setdefault(r, [])
- _list.append((r, l))
- equated_columns[l] = r
- else:
- for l, r in prop.local_remote_pairs:
- _list = lookup.setdefault(l, [])
- _list.append((l, r))
- equated_columns[r] = l
-
- def col_to_bind(col):
- if col in lookup:
- for tobind, equated in lookup[col]:
- if equated in binds:
- return None
- if col not in binds:
- binds[col] = sql.bindparam(None, None, type_=col.type)
- return binds[col]
- return None
-
- lazywhere = prop.primaryjoin
-
- if prop.secondaryjoin is None or not reverse_direction:
- lazywhere = visitors.replacement_traverse(
- lazywhere, {}, col_to_bind)
-
- if prop.secondaryjoin is not None:
- secondaryjoin = prop.secondaryjoin
- if reverse_direction:
- secondaryjoin = visitors.replacement_traverse(
- secondaryjoin, {}, col_to_bind)
- lazywhere = sql.and_(lazywhere, secondaryjoin)
-
- bind_to_col = dict((binds[col].key, col) for col in binds)
-
- return lazywhere, bind_to_col, equated_columns
-
-log.class_logger(LazyLoader)
-
-class LoadLazyAttribute(object):
- """serializable loader object used by LazyLoader"""
-
- def __init__(self, state, key):
- self.state = state
- self.key = key
-
- def __call__(self, passive=attributes.PASSIVE_OFF):
- state, key = self.state, self.key
- instance_mapper = state.manager.mapper
- prop = instance_mapper._props[key]
- strategy = prop._strategies[LazyLoader]
-
- return strategy._load_for_state(state, passive)
-
-
-class ImmediateLoader(AbstractRelationshipLoader):
- def init_class_attribute(self, mapper):
- self.parent_property.\
- _get_strategy(LazyLoader).\
- init_class_attribute(mapper)
-
- def setup_query(self, context, entity,
- path, reduced_path, adapter, column_collection=None,
- parentmapper=None, **kwargs):
- pass
-
- def create_row_processor(self, context, path, reduced_path, mapper, row, adapter):
- def execute(state, dict_, row):
- state.get_impl(self.key).get(state, dict_)
-
- return None, None, execute
-
-class SubqueryLoader(AbstractRelationshipLoader):
- def init(self):
- super(SubqueryLoader, self).init()
- self.join_depth = self.parent_property.join_depth
-
- def init_class_attribute(self, mapper):
- self.parent_property.\
- _get_strategy(LazyLoader).\
- init_class_attribute(mapper)
-
- def setup_query(self, context, entity,
- path, reduced_path, adapter, column_collection=None,
- parentmapper=None, **kwargs):
-
- if not context.query._enable_eagerloads:
- return
-
- path = path + (self.key, )
- reduced_path = reduced_path + (self.key, )
-
- # build up a path indicating the path from the leftmost
- # entity to the thing we're subquery loading.
- subq_path = context.attributes.get(('subquery_path', None), ())
-
- subq_path = subq_path + path
-
- # join-depth / recursion check
- if ("loaderstrategy", reduced_path) not in context.attributes:
- if self.join_depth:
- if len(path) / 2 > self.join_depth:
- return
- else:
- if self.mapper.base_mapper in interfaces._reduce_path(subq_path):
- return
-
- orig_query = context.attributes.get(
- ("orig_query", SubqueryLoader),
- context.query)
-
- subq_mapper = mapperutil._class_to_mapper(subq_path[0])
-
- # determine attributes of the leftmost mapper
- if self.parent.isa(subq_mapper) and self.key==subq_path[1]:
- leftmost_mapper, leftmost_prop = \
- self.parent, self.parent_property
- else:
- leftmost_mapper, leftmost_prop = \
- subq_mapper, \
- subq_mapper._props[subq_path[1]]
- leftmost_cols, remote_cols = self._local_remote_columns(leftmost_prop)
-
- leftmost_attr = [
- leftmost_mapper._columntoproperty[c].class_attribute
- for c in leftmost_cols
- ]
-
- # reformat the original query
- # to look only for significant columns
- q = orig_query._clone()
-
- # TODO: why does polymporphic etc. require hardcoding
- # into _adapt_col_list ? Does query.add_columns(...) work
- # with polymorphic loading ?
- q._set_entities(q._adapt_col_list(leftmost_attr))
-
- # don't need ORDER BY if no limit/offset
- if q._limit is None and q._offset is None:
- q._order_by = None
-
- # the original query now becomes a subquery
- # which we'll join onto.
- embed_q = q.with_labels().subquery()
- left_alias = mapperutil.AliasedClass(leftmost_mapper, embed_q)
-
- # q becomes a new query. basically doing a longhand
- # "from_self()". (from_self() itself not quite industrial
- # strength enough for all contingencies...but very close)
-
- q = q.session.query(self.mapper)
- q._attributes = {
- ("orig_query", SubqueryLoader): orig_query,
- ('subquery_path', None) : subq_path
- }
- q = q._enable_single_crit(False)
-
- # figure out what's being joined. a.k.a. the fun part
- to_join = [
- (subq_path[i], subq_path[i+1])
- for i in xrange(0, len(subq_path), 2)
- ]
-
- # determine the immediate parent class we are joining from,
- # which needs to be aliased.
-
- if len(to_join) < 2:
- # in the case of a one level eager load, this is the
- # leftmost "left_alias".
- parent_alias = left_alias
- elif subq_path[-2].isa(self.parent):
- # In the case of multiple levels, retrieve
- # it from subq_path[-2]. This is the same as self.parent
- # in the vast majority of cases, and [ticket:2014]
- # illustrates a case where sub_path[-2] is a subclass
- # of self.parent
- parent_alias = mapperutil.AliasedClass(subq_path[-2])
- else:
- # if of_type() were used leading to this relationship,
- # self.parent is more specific than subq_path[-2]
- parent_alias = mapperutil.AliasedClass(self.parent)
-
- local_cols, remote_cols = \
- self._local_remote_columns(self.parent_property)
-
- local_attr = [
- getattr(parent_alias, self.parent._columntoproperty[c].key)
- for c in local_cols
- ]
- q = q.order_by(*local_attr)
- q = q.add_columns(*local_attr)
-
- for i, (mapper, key) in enumerate(to_join):
-
- # we need to use query.join() as opposed to
- # orm.join() here because of the
- # rich behavior it brings when dealing with
- # "with_polymorphic" mappers. "aliased"
- # and "from_joinpoint" take care of most of
- # the chaining and aliasing for us.
-
- first = i == 0
- middle = i < len(to_join) - 1
- second_to_last = i == len(to_join) - 2
-
- if first:
- attr = getattr(left_alias, key)
- else:
- attr = key
-
- if second_to_last:
- q = q.join(parent_alias, attr, from_joinpoint=True)
- else:
- q = q.join(attr, aliased=middle, from_joinpoint=True)
-
- # propagate loader options etc. to the new query.
- # these will fire relative to subq_path.
- q = q._with_current_path(subq_path)
- q = q._conditional_options(*orig_query._with_options)
-
- if self.parent_property.order_by:
- # if there's an ORDER BY, alias it the same
- # way joinedloader does, but we have to pull out
- # the "eagerjoin" from the query.
- # this really only picks up the "secondary" table
- # right now.
- eagerjoin = q._from_obj[0]
- eager_order_by = \
- eagerjoin._target_adapter.\
- copy_and_process(
- util.to_list(
- self.parent_property.order_by
- )
- )
- q = q.order_by(*eager_order_by)
-
- # add new query to attributes to be picked up
- # by create_row_processor
- context.attributes[('subquery', reduced_path)] = q
-
- def _local_remote_columns(self, prop):
- if prop.secondary is None:
- return zip(*prop.local_remote_pairs)
- else:
- return \
- [p[0] for p in prop.synchronize_pairs],\
- [
- p[0] for p in prop.
- secondary_synchronize_pairs
- ]
-
- def create_row_processor(self, context, path, reduced_path,
- mapper, row, adapter):
- if not self.parent.class_manager[self.key].impl.supports_population:
- raise sa_exc.InvalidRequestError(
- "'%s' does not support object "
- "population - eager loading cannot be applied." %
- self)
-
- reduced_path = reduced_path + (self.key,)
-
- if ('subquery', reduced_path) not in context.attributes:
- return None, None, None
-
- local_cols, remote_cols = self._local_remote_columns(self.parent_property)
-
- remote_attr = [
- self.mapper._columntoproperty[c].key
- for c in remote_cols]
-
- q = context.attributes[('subquery', reduced_path)]
-
- collections = dict(
- (k, [v[0] for v in v])
- for k, v in itertools.groupby(
- q,
- lambda x:x[1:]
- ))
-
- if adapter:
- local_cols = [adapter.columns[c] for c in local_cols]
-
- if self.uselist:
- def execute(state, dict_, row):
- collection = collections.get(
- tuple([row[col] for col in local_cols]),
- ()
- )
- state.get_impl(self.key).\
- set_committed_value(state, dict_, collection)
- else:
- def execute(state, dict_, row):
- collection = collections.get(
- tuple([row[col] for col in local_cols]),
- (None,)
- )
- if len(collection) > 1:
- util.warn(
- "Multiple rows returned with "
- "uselist=False for eagerly-loaded attribute '%s' "
- % self)
-
- scalar = collection[0]
- state.get_impl(self.key).\
- set_committed_value(state, dict_, scalar)
-
- return execute, None, None
-
-log.class_logger(SubqueryLoader)
-
-class EagerLoader(AbstractRelationshipLoader):
- """Strategize a relationship() that loads within the process
- of the parent object being selected."""
-
- def init(self):
- super(EagerLoader, self).init()
- self.join_depth = self.parent_property.join_depth
-
- def init_class_attribute(self, mapper):
- self.parent_property.\
- _get_strategy(LazyLoader).init_class_attribute(mapper)
-
- def setup_query(self, context, entity, path, reduced_path, adapter, \
- column_collection=None, parentmapper=None,
- allow_innerjoin=True,
- **kwargs):
- """Add a left outer join to the statement thats being constructed."""
-
-
- if not context.query._enable_eagerloads:
- return
-
- path = path + (self.key,)
- reduced_path = reduced_path + (self.key,)
-
- # check for user-defined eager alias
- if ("user_defined_eager_row_processor", reduced_path) in\
- context.attributes:
- clauses = context.attributes[
- ("user_defined_eager_row_processor",
- reduced_path)]
-
- adapter = entity._get_entity_clauses(context.query, context)
- if adapter and clauses:
- context.attributes[
- ("user_defined_eager_row_processor",
- reduced_path)] = clauses = clauses.wrap(adapter)
- elif adapter:
- context.attributes[
- ("user_defined_eager_row_processor",
- reduced_path)] = clauses = adapter
-
- add_to_collection = context.primary_columns
-
- else:
- # check for join_depth or basic recursion,
- # if the current path was not explicitly stated as
- # a desired "loaderstrategy" (i.e. via query.options())
- if ("loaderstrategy", reduced_path) not in context.attributes:
- if self.join_depth:
- if len(path) / 2 > self.join_depth:
- return
- else:
- if self.mapper.base_mapper in reduced_path:
- return
-
- clauses = mapperutil.ORMAdapter(
- mapperutil.AliasedClass(self.mapper),
- equivalents=self.mapper._equivalent_columns,
- adapt_required=True)
-
- if self.parent_property.direction != interfaces.MANYTOONE:
- context.multi_row_eager_loaders = True
-
- innerjoin = allow_innerjoin and context.attributes.get(
- ("eager_join_type", path),
- self.parent_property.innerjoin)
- if not innerjoin:
- # if this is an outer join, all eager joins from
- # here must also be outer joins
- allow_innerjoin = False
-
- context.create_eager_joins.append(
- (self._create_eager_join, context,
- entity, path, adapter,
- parentmapper, clauses, innerjoin)
- )
-
- add_to_collection = context.secondary_columns
- context.attributes[
- ("eager_row_processor", reduced_path)
- ] = clauses
-
- path += (self.mapper,)
- reduced_path += (self.mapper.base_mapper,)
-
- for value in self.mapper._polymorphic_properties:
- value.setup(
- context,
- entity,
- path,
- reduced_path,
- clauses,
- parentmapper=self.mapper,
- column_collection=add_to_collection,
- allow_innerjoin=allow_innerjoin)
-
- def _create_eager_join(self, context, entity,
- path, adapter, parentmapper,
- clauses, innerjoin):
-
- if parentmapper is None:
- localparent = entity.mapper
- else:
- localparent = parentmapper
-
- # whether or not the Query will wrap the selectable in a subquery,
- # and then attach eager load joins to that (i.e., in the case of
- # LIMIT/OFFSET etc.)
- should_nest_selectable = context.multi_row_eager_loaders and \
- context.query._should_nest_selectable
-
- entity_key = None
- if entity not in context.eager_joins and \
- not should_nest_selectable and \
- context.from_clause:
- index, clause = \
- sql_util.find_join_source(
- context.from_clause, entity.selectable)
- if clause is not None:
- # join to an existing FROM clause on the query.
- # key it to its list index in the eager_joins dict.
- # Query._compile_context will adapt as needed and
- # append to the FROM clause of the select().
- entity_key, default_towrap = index, clause
-
- if entity_key is None:
- entity_key, default_towrap = entity, entity.selectable
-
- towrap = context.eager_joins.setdefault(entity_key, default_towrap)
-
- join_to_left = False
- if adapter:
- if getattr(adapter, 'aliased_class', None):
- onclause = getattr(
- adapter.aliased_class, self.key,
- self.parent_property)
- else:
- onclause = getattr(
- mapperutil.AliasedClass(
- self.parent,
- adapter.selectable
- ),
- self.key, self.parent_property
- )
-
- if onclause is self.parent_property:
- # TODO: this is a temporary hack to
- # account for polymorphic eager loads where
- # the eagerload is referencing via of_type().
- join_to_left = True
- else:
- onclause = self.parent_property
-
- context.eager_joins[entity_key] = eagerjoin = \
- mapperutil.join(
- towrap,
- clauses.aliased_class,
- onclause,
- join_to_left=join_to_left,
- isouter=not innerjoin
- )
-
- # send a hint to the Query as to where it may "splice" this join
- eagerjoin.stop_on = entity.selectable
-
- if self.parent_property.secondary is None and \
- not parentmapper:
- # for parentclause that is the non-eager end of the join,
- # ensure all the parent cols in the primaryjoin are actually
- # in the
- # columns clause (i.e. are not deferred), so that aliasing applied
- # by the Query propagates those columns outward.
- # This has the effect
- # of "undefering" those columns.
- for col in sql_util.find_columns(
- self.parent_property.primaryjoin):
- if localparent.mapped_table.c.contains_column(col):
- if adapter:
- col = adapter.columns[col]
- context.primary_columns.append(col)
-
- if self.parent_property.order_by:
- context.eager_order_by += \
- eagerjoin._target_adapter.\
- copy_and_process(
- util.to_list(
- self.parent_property.order_by
- )
- )
-
-
- def _create_eager_adapter(self, context, row, adapter, path, reduced_path):
- if ("user_defined_eager_row_processor", reduced_path) in \
- context.attributes:
- decorator = context.attributes[
- ("user_defined_eager_row_processor",
- reduced_path)]
- # user defined eagerloads are part of the "primary"
- # portion of the load.
- # the adapters applied to the Query should be honored.
- if context.adapter and decorator:
- decorator = decorator.wrap(context.adapter)
- elif context.adapter:
- decorator = context.adapter
- elif ("eager_row_processor", reduced_path) in context.attributes:
- decorator = context.attributes[
- ("eager_row_processor", reduced_path)]
- else:
- return False
-
- try:
- identity_key = self.mapper.identity_key_from_row(row, decorator)
- return decorator
- except KeyError, k:
- # no identity key - dont return a row
- # processor, will cause a degrade to lazy
- return False
-
- def create_row_processor(self, context, path, reduced_path, mapper, row, adapter):
- if not self.parent.class_manager[self.key].impl.supports_population:
- raise sa_exc.InvalidRequestError(
- "'%s' does not support object "
- "population - eager loading cannot be applied." %
- self)
-
- our_path = path + (self.key,)
- our_reduced_path = reduced_path + (self.key,)
-
- eager_adapter = self._create_eager_adapter(
- context,
- row,
- adapter, our_path,
- our_reduced_path)
-
- if eager_adapter is not False:
- key = self.key
- _instance = self.mapper._instance_processor(
- context,
- our_path + (self.mapper,),
- our_reduced_path + (self.mapper.base_mapper,),
- eager_adapter)
-
- if not self.uselist:
- def new_execute(state, dict_, row):
- # set a scalar object instance directly on the parent
- # object, bypassing InstrumentedAttribute event handlers.
- dict_[key] = _instance(row, None)
-
- def existing_execute(state, dict_, row):
- # call _instance on the row, even though the object has
- # been created, so that we further descend into properties
- existing = _instance(row, None)
- if existing is not None \
- and key in dict_ \
- and existing is not dict_[key]:
- util.warn(
- "Multiple rows returned with "
- "uselist=False for eagerly-loaded attribute '%s' "
- % self)
- return new_execute, existing_execute, None
- else:
- def new_execute(state, dict_, row):
- collection = attributes.init_state_collection(
- state, dict_, key)
- result_list = util.UniqueAppender(collection,
- 'append_without_event')
- context.attributes[(state, key)] = result_list
- _instance(row, result_list)
-
- def existing_execute(state, dict_, row):
- if (state, key) in context.attributes:
- result_list = context.attributes[(state, key)]
- else:
- # appender_key can be absent from context.attributes
- # with isnew=False when self-referential eager loading
- # is used; the same instance may be present in two
- # distinct sets of result columns
- collection = attributes.init_state_collection(state,
- dict_, key)
- result_list = util.UniqueAppender(
- collection,
- 'append_without_event')
- context.attributes[(state, key)] = result_list
- _instance(row, result_list)
- return new_execute, existing_execute, None
- else:
- return self.parent_property.\
- _get_strategy(LazyLoader).\
- create_row_processor(
- context, path,
- reduced_path,
- mapper, row, adapter)
-
-log.class_logger(EagerLoader)
-
-class EagerLazyOption(StrategizedOption):
- def __init__(self, key, lazy=True, chained=False,
- propagate_to_loaders=True
- ):
- super(EagerLazyOption, self).__init__(key)
- self.lazy = lazy
- self.chained = self.lazy in (False, 'joined', 'subquery') and chained
- self.propagate_to_loaders = propagate_to_loaders
- self.strategy_cls = factory(lazy)
-
- def get_strategy_class(self):
- return self.strategy_cls
-
-def factory(identifier):
- if identifier is False or identifier == 'joined':
- return EagerLoader
- elif identifier is None or identifier == 'noload':
- return NoLoader
- elif identifier is False or identifier == 'select':
- return LazyLoader
- elif identifier == 'subquery':
- return SubqueryLoader
- elif identifier == 'immediate':
- return ImmediateLoader
- else:
- return LazyLoader
-
-
-
-class EagerJoinOption(PropertyOption):
-
- def __init__(self, key, innerjoin, chained=False):
- super(EagerJoinOption, self).__init__(key)
- self.innerjoin = innerjoin
- self.chained = chained
-
- def process_query_property(self, query, paths, mappers):
- if self.chained:
- for path in paths:
- query._attributes[("eager_join_type", path)] = self.innerjoin
- else:
- query._attributes[("eager_join_type", paths[-1])] = self.innerjoin
-
-class LoadEagerFromAliasOption(PropertyOption):
-
- def __init__(self, key, alias=None, chained=False):
- super(LoadEagerFromAliasOption, self).__init__(key)
- if alias is not None:
- if not isinstance(alias, basestring):
- m, alias, is_aliased_class = mapperutil._entity_info(alias)
- self.alias = alias
- self.chained = chained
-
- def process_query_property(self, query, paths, mappers):
- if self.chained:
- for path in paths[0:-1]:
- (root_mapper, propname) = path[-2:]
- prop = root_mapper._props[propname]
- adapter = query._polymorphic_adapters.get(prop.mapper, None)
- query._attributes.setdefault(
- ("user_defined_eager_row_processor",
- interfaces._reduce_path(path)), adapter)
-
- if self.alias is not None:
- if isinstance(self.alias, basestring):
- (root_mapper, propname) = paths[-1][-2:]
- prop = root_mapper._props[propname]
- self.alias = prop.target.alias(self.alias)
- query._attributes[
- ("user_defined_eager_row_processor",
- interfaces._reduce_path(paths[-1]))
- ] = sql_util.ColumnAdapter(self.alias)
- else:
- (root_mapper, propname) = paths[-1][-2:]
- prop = root_mapper._props[propname]
- adapter = query._polymorphic_adapters.get(prop.mapper, None)
- query._attributes[
- ("user_defined_eager_row_processor",
- interfaces._reduce_path(paths[-1]))] = adapter
-
-def single_parent_validator(desc, prop):
- def _do_check(state, value, oldvalue, initiator):
- if value is not None:
- hasparent = initiator.hasparent(attributes.instance_state(value))
- if hasparent and oldvalue is not value:
- raise sa_exc.InvalidRequestError(
- "Instance %s is already associated with an instance "
- "of %s via its %s attribute, and is only allowed a "
- "single parent." %
- (mapperutil.instance_str(value), state.class_, prop)
- )
- return value
-
- def append(state, value, initiator):
- return _do_check(state, value, None, initiator)
-
- def set_(state, value, oldvalue, initiator):
- return _do_check(state, value, oldvalue, initiator)
-
- event.listen(desc, 'append', append, raw=True, retval=True, active_history=True)
- event.listen(desc, 'set', set_, raw=True, retval=True, active_history=True)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/sync.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/sync.py
deleted file mode 100755
index 5ebd44fb..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/sync.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# orm/sync.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""private module containing functions used for copying data
-between instances based on join conditions.
-"""
-
-from sqlalchemy.orm import exc, util as mapperutil, attributes
-
-def populate(source, source_mapper, dest, dest_mapper,
- synchronize_pairs, uowcommit, flag_cascaded_pks):
- source_dict = source.dict
- dest_dict = dest.dict
-
- for l, r in synchronize_pairs:
- try:
- # inline of source_mapper._get_state_attr_by_column
- prop = source_mapper._columntoproperty[l]
- value = source.manager[prop.key].impl.get(source, source_dict,
- attributes.PASSIVE_OFF)
- except exc.UnmappedColumnError:
- _raise_col_to_prop(False, source_mapper, l, dest_mapper, r)
-
- try:
- # inline of dest_mapper._set_state_attr_by_column
- prop = dest_mapper._columntoproperty[r]
- dest.manager[prop.key].impl.set(dest, dest_dict, value, None)
- except exc.UnmappedColumnError:
- _raise_col_to_prop(True, source_mapper, l, dest_mapper, r)
-
- # technically the "r.primary_key" check isn't
- # needed here, but we check for this condition to limit
- # how often this logic is invoked for memory/performance
- # reasons, since we only need this info for a primary key
- # destination.
- if flag_cascaded_pks and l.primary_key and \
- r.primary_key and \
- r.references(l):
- uowcommit.attributes[("pk_cascaded", dest, r)] = True
-
-def clear(dest, dest_mapper, synchronize_pairs):
- for l, r in synchronize_pairs:
- if r.primary_key:
- raise AssertionError(
- "Dependency rule tried to blank-out primary key "
- "column '%s' on instance '%s'" %
- (r, mapperutil.state_str(dest))
- )
- try:
- dest_mapper._set_state_attr_by_column(dest, dest.dict, r, None)
- except exc.UnmappedColumnError:
- _raise_col_to_prop(True, None, l, dest_mapper, r)
-
-def update(source, source_mapper, dest, old_prefix, synchronize_pairs):
- for l, r in synchronize_pairs:
- try:
- oldvalue = source_mapper._get_committed_attr_by_column(source.obj(), l)
- value = source_mapper._get_state_attr_by_column(source, source.dict, l)
- except exc.UnmappedColumnError:
- _raise_col_to_prop(False, source_mapper, l, None, r)
- dest[r.key] = value
- dest[old_prefix + r.key] = oldvalue
-
-def populate_dict(source, source_mapper, dict_, synchronize_pairs):
- for l, r in synchronize_pairs:
- try:
- value = source_mapper._get_state_attr_by_column(source, source.dict, l)
- except exc.UnmappedColumnError:
- _raise_col_to_prop(False, source_mapper, l, None, r)
-
- dict_[r.key] = value
-
-def source_modified(uowcommit, source, source_mapper, synchronize_pairs):
- """return true if the source object has changes from an old to a
- new value on the given synchronize pairs
-
- """
- for l, r in synchronize_pairs:
- try:
- prop = source_mapper._columntoproperty[l]
- except exc.UnmappedColumnError:
- _raise_col_to_prop(False, source_mapper, l, None, r)
- history = uowcommit.get_attribute_history(source, prop.key,
- attributes.PASSIVE_NO_INITIALIZE)
- return bool(history.deleted)
- else:
- return False
-
-def _raise_col_to_prop(isdest, source_mapper, source_column, dest_mapper, dest_column):
- if isdest:
- raise exc.UnmappedColumnError(
- "Can't execute sync rule for destination column '%s'; "
- "mapper '%s' does not map this column. Try using an explicit"
- " `foreign_keys` collection which does not include this column "
- "(or use a viewonly=True relation)." % (dest_column, dest_mapper)
- )
- else:
- raise exc.UnmappedColumnError(
- "Can't execute sync rule for source column '%s'; mapper '%s' "
- "does not map this column. Try using an explicit `foreign_keys`"
- " collection which does not include destination column '%s' (or "
- "use a viewonly=True relation)." %
- (source_column, source_mapper, dest_column)
- )
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py
deleted file mode 100755
index 5e0c9393..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py
+++ /dev/null
@@ -1,583 +0,0 @@
-# orm/unitofwork.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""The internals for the unit of work system.
-
-The session's flush() process passes objects to a contextual object
-here, which assembles flush tasks based on mappers and their properties,
-organizes them in order of dependency, and executes.
-
-"""
-
-from sqlalchemy import util, event
-from sqlalchemy.util import topological
-from sqlalchemy.orm import attributes, interfaces
-from sqlalchemy.orm import util as mapperutil
-session = util.importlater("sqlalchemy.orm", "session")
-
-def track_cascade_events(descriptor, prop):
- """Establish event listeners on object attributes which handle
- cascade-on-set/append.
-
- """
- key = prop.key
-
- def append(state, item, initiator):
- # process "save_update" cascade rules for when
- # an instance is appended to the list of another instance
-
- sess = session._state_session(state)
- if sess:
- prop = state.manager.mapper._props[key]
- item_state = attributes.instance_state(item)
- if prop.cascade.save_update and \
- (prop.cascade_backrefs or key == initiator.key) and \
- not sess._contains_state(item_state):
- sess._save_or_update_state(item_state)
- return item
-
- def remove(state, item, initiator):
- sess = session._state_session(state)
- if sess:
- prop = state.manager.mapper._props[key]
- # expunge pending orphans
- item_state = attributes.instance_state(item)
- if prop.cascade.delete_orphan and \
- item_state in sess._new and \
- prop.mapper._is_orphan(item_state):
- sess.expunge(item)
-
- def set_(state, newvalue, oldvalue, initiator):
- # process "save_update" cascade rules for when an instance
- # is attached to another instance
- if oldvalue is newvalue:
- return newvalue
-
- sess = session._state_session(state)
- if sess:
- prop = state.manager.mapper._props[key]
- if newvalue is not None:
- newvalue_state = attributes.instance_state(newvalue)
- if prop.cascade.save_update and \
- (prop.cascade_backrefs or key == initiator.key) and \
- not sess._contains_state(newvalue_state):
- sess._save_or_update_state(newvalue_state)
-
- if oldvalue is not None and prop.cascade.delete_orphan:
- oldvalue_state = attributes.instance_state(oldvalue)
-
- if oldvalue_state in sess._new and \
- prop.mapper._is_orphan(oldvalue_state):
- sess.expunge(oldvalue)
- return newvalue
-
- event.listen(descriptor, 'append', append, raw=True, retval=True)
- event.listen(descriptor, 'remove', remove, raw=True, retval=True)
- event.listen(descriptor, 'set', set_, raw=True, retval=True)
-
-
-class UOWTransaction(object):
- def __init__(self, session):
- self.session = session
-
- # dictionary used by external actors to
- # store arbitrary state information.
- self.attributes = {}
-
- # dictionary of mappers to sets of
- # DependencyProcessors, which are also
- # set to be part of the sorted flush actions,
- # which have that mapper as a parent.
- self.deps = util.defaultdict(set)
-
- # dictionary of mappers to sets of InstanceState
- # items pending for flush which have that mapper
- # as a parent.
- self.mappers = util.defaultdict(set)
-
- # a dictionary of Preprocess objects, which gather
- # additional states impacted by the flush
- # and determine if a flush action is needed
- self.presort_actions = {}
-
- # dictionary of PostSortRec objects, each
- # one issues work during the flush within
- # a certain ordering.
- self.postsort_actions = {}
-
- # a set of 2-tuples, each containing two
- # PostSortRec objects where the second
- # is dependent on the first being executed
- # first
- self.dependencies = set()
-
- # dictionary of InstanceState-> (isdelete, listonly)
- # tuples, indicating if this state is to be deleted
- # or insert/updated, or just refreshed
- self.states = {}
-
- # tracks InstanceStates which will be receiving
- # a "post update" call. Keys are mappers,
- # values are a set of states and a set of the
- # columns which should be included in the update.
- self.post_update_states = util.defaultdict(lambda: (set(), set()))
-
- @property
- def has_work(self):
- return bool(self.states)
-
- def is_deleted(self, state):
- """return true if the given state is marked as deleted
- within this uowtransaction."""
-
- return state in self.states and self.states[state][0]
-
- def memo(self, key, callable_):
- if key in self.attributes:
- return self.attributes[key]
- else:
- self.attributes[key] = ret = callable_()
- return ret
-
- def remove_state_actions(self, state):
- """remove pending actions for a state from the uowtransaction."""
-
- isdelete = self.states[state][0]
-
- self.states[state] = (isdelete, True)
-
- def get_attribute_history(self, state, key,
- passive=attributes.PASSIVE_NO_INITIALIZE):
- """facade to attributes.get_state_history(), including caching of results."""
-
- hashkey = ("history", state, key)
-
- # cache the objects, not the states; the strong reference here
- # prevents newly loaded objects from being dereferenced during the
- # flush process
-
- if hashkey in self.attributes:
- history, state_history, cached_passive = self.attributes[hashkey]
- # if the cached lookup was "passive" and now
- # we want non-passive, do a non-passive lookup and re-cache
- if cached_passive is not attributes.PASSIVE_OFF \
- and passive is attributes.PASSIVE_OFF:
- impl = state.manager[key].impl
- history = impl.get_history(state, state.dict,
- attributes.PASSIVE_OFF)
- if history and impl.uses_objects:
- state_history = history.as_state()
- else:
- state_history = history
- self.attributes[hashkey] = (history, state_history, passive)
- else:
- impl = state.manager[key].impl
- # TODO: store the history as (state, object) tuples
- # so we don't have to keep converting here
- history = impl.get_history(state, state.dict, passive)
- if history and impl.uses_objects:
- state_history = history.as_state()
- else:
- state_history = history
- self.attributes[hashkey] = (history, state_history, passive)
-
- return state_history
-
- def has_dep(self, processor):
- return (processor, True) in self.presort_actions
-
- def register_preprocessor(self, processor, fromparent):
- key = (processor, fromparent)
- if key not in self.presort_actions:
- self.presort_actions[key] = Preprocess(processor, fromparent)
-
- def register_object(self, state, isdelete=False,
- listonly=False, cancel_delete=False,
- operation=None, prop=None):
- if not self.session._contains_state(state):
- if not state.deleted and operation is not None:
- util.warn("Object of type %s not in session, %s operation "
- "along '%s' will not proceed" %
- (mapperutil.state_class_str(state), operation, prop))
- return False
-
- if state not in self.states:
- mapper = state.manager.mapper
-
- if mapper not in self.mappers:
- mapper._per_mapper_flush_actions(self)
-
- self.mappers[mapper].add(state)
- self.states[state] = (isdelete, listonly)
- else:
- if not listonly and (isdelete or cancel_delete):
- self.states[state] = (isdelete, False)
- return True
-
- def issue_post_update(self, state, post_update_cols):
- mapper = state.manager.mapper.base_mapper
- states, cols = self.post_update_states[mapper]
- states.add(state)
- cols.update(post_update_cols)
-
- @util.memoized_property
- def _mapper_for_dep(self):
- """return a dynamic mapping of (Mapper, DependencyProcessor) to
- True or False, indicating if the DependencyProcessor operates
- on objects of that Mapper.
-
- The result is stored in the dictionary persistently once
- calculated.
-
- """
- return util.PopulateDict(
- lambda tup:tup[0]._props.get(tup[1].key) is tup[1].prop
- )
-
- def filter_states_for_dep(self, dep, states):
- """Filter the given list of InstanceStates to those relevant to the
- given DependencyProcessor.
-
- """
- mapper_for_dep = self._mapper_for_dep
- return [s for s in states if mapper_for_dep[(s.manager.mapper, dep)]]
-
- def states_for_mapper_hierarchy(self, mapper, isdelete, listonly):
- checktup = (isdelete, listonly)
- for mapper in mapper.base_mapper.self_and_descendants:
- for state in self.mappers[mapper]:
- if self.states[state] == checktup:
- yield state
-
- def _generate_actions(self):
- """Generate the full, unsorted collection of PostSortRecs as
- well as dependency pairs for this UOWTransaction.
-
- """
- # execute presort_actions, until all states
- # have been processed. a presort_action might
- # add new states to the uow.
- while True:
- ret = False
- for action in list(self.presort_actions.values()):
- if action.execute(self):
- ret = True
- if not ret:
- break
-
- # see if the graph of mapper dependencies has cycles.
- self.cycles = cycles = topological.find_cycles(
- self.dependencies,
- self.postsort_actions.values())
-
- if cycles:
- # if yes, break the per-mapper actions into
- # per-state actions
- convert = dict(
- (rec, set(rec.per_state_flush_actions(self)))
- for rec in cycles
- )
-
- # rewrite the existing dependencies to point to
- # the per-state actions for those per-mapper actions
- # that were broken up.
- for edge in list(self.dependencies):
- if None in edge or \
- edge[0].disabled or edge[1].disabled or \
- cycles.issuperset(edge):
- self.dependencies.remove(edge)
- elif edge[0] in cycles:
- self.dependencies.remove(edge)
- for dep in convert[edge[0]]:
- self.dependencies.add((dep, edge[1]))
- elif edge[1] in cycles:
- self.dependencies.remove(edge)
- for dep in convert[edge[1]]:
- self.dependencies.add((edge[0], dep))
-
- return set([a for a in self.postsort_actions.values()
- if not a.disabled
- ]
- ).difference(cycles)
-
- def execute(self):
- postsort_actions = self._generate_actions()
-
- #sort = topological.sort(self.dependencies, postsort_actions)
- #print "--------------"
- #print self.dependencies
- #print list(sort)
- #print "COUNT OF POSTSORT ACTIONS", len(postsort_actions)
-
- # execute
- if self.cycles:
- for set_ in topological.sort_as_subsets(
- self.dependencies,
- postsort_actions):
- while set_:
- n = set_.pop()
- n.execute_aggregate(self, set_)
- else:
- for rec in topological.sort(
- self.dependencies,
- postsort_actions):
- rec.execute(self)
-
-
- def finalize_flush_changes(self):
- """mark processed objects as clean / deleted after a successful flush().
-
- this method is called within the flush() method after the
- execute() method has succeeded and the transaction has been committed.
-
- """
- for state, (isdelete, listonly) in self.states.iteritems():
- if isdelete:
- self.session._remove_newly_deleted(state)
- else:
- # if listonly:
- # debug... would like to see how many do this
- self.session._register_newly_persistent(state)
-
-class IterateMappersMixin(object):
- def _mappers(self, uow):
- if self.fromparent:
- return iter(
- m for m in self.dependency_processor.parent.self_and_descendants
- if uow._mapper_for_dep[(m, self.dependency_processor)]
- )
- else:
- return self.dependency_processor.mapper.self_and_descendants
-
-class Preprocess(IterateMappersMixin):
- def __init__(self, dependency_processor, fromparent):
- self.dependency_processor = dependency_processor
- self.fromparent = fromparent
- self.processed = set()
- self.setup_flush_actions = False
-
- def execute(self, uow):
- delete_states = set()
- save_states = set()
-
- for mapper in self._mappers(uow):
- for state in uow.mappers[mapper].difference(self.processed):
- (isdelete, listonly) = uow.states[state]
- if not listonly:
- if isdelete:
- delete_states.add(state)
- else:
- save_states.add(state)
-
- if delete_states:
- self.dependency_processor.presort_deletes(uow, delete_states)
- self.processed.update(delete_states)
- if save_states:
- self.dependency_processor.presort_saves(uow, save_states)
- self.processed.update(save_states)
-
- if (delete_states or save_states):
- if not self.setup_flush_actions and (
- self.dependency_processor.\
- prop_has_changes(uow, delete_states, True) or
- self.dependency_processor.\
- prop_has_changes(uow, save_states, False)
- ):
- self.dependency_processor.per_property_flush_actions(uow)
- self.setup_flush_actions = True
- return True
- else:
- return False
-
-class PostSortRec(object):
- disabled = False
-
- def __new__(cls, uow, *args):
- key = (cls, ) + args
- if key in uow.postsort_actions:
- return uow.postsort_actions[key]
- else:
- uow.postsort_actions[key] = \
- ret = \
- object.__new__(cls)
- return ret
-
- def execute_aggregate(self, uow, recs):
- self.execute(uow)
-
- def __repr__(self):
- return "%s(%s)" % (
- self.__class__.__name__,
- ",".join(str(x) for x in self.__dict__.values())
- )
-
-class ProcessAll(IterateMappersMixin, PostSortRec):
- def __init__(self, uow, dependency_processor, delete, fromparent):
- self.dependency_processor = dependency_processor
- self.delete = delete
- self.fromparent = fromparent
- uow.deps[dependency_processor.parent.base_mapper].add(dependency_processor)
-
- def execute(self, uow):
- states = self._elements(uow)
- if self.delete:
- self.dependency_processor.process_deletes(uow, states)
- else:
- self.dependency_processor.process_saves(uow, states)
-
- def per_state_flush_actions(self, uow):
- # this is handled by SaveUpdateAll and DeleteAll,
- # since a ProcessAll should unconditionally be pulled
- # into per-state if either the parent/child mappers
- # are part of a cycle
- return iter([])
-
- def __repr__(self):
- return "%s(%s, delete=%s)" % (
- self.__class__.__name__,
- self.dependency_processor,
- self.delete
- )
-
- def _elements(self, uow):
- for mapper in self._mappers(uow):
- for state in uow.mappers[mapper]:
- (isdelete, listonly) = uow.states[state]
- if isdelete == self.delete and not listonly:
- yield state
-
-class IssuePostUpdate(PostSortRec):
- def __init__(self, uow, mapper, isdelete):
- self.mapper = mapper
- self.isdelete = isdelete
-
- def execute(self, uow):
- states, cols = uow.post_update_states[self.mapper]
- states = [s for s in states if uow.states[s][0] == self.isdelete]
-
- self.mapper._post_update(states, uow, cols)
-
-class SaveUpdateAll(PostSortRec):
- def __init__(self, uow, mapper):
- self.mapper = mapper
- assert mapper is mapper.base_mapper
-
- def execute(self, uow):
- self.mapper._save_obj(
- uow.states_for_mapper_hierarchy(self.mapper, False, False),
- uow
- )
-
- def per_state_flush_actions(self, uow):
- states = list(uow.states_for_mapper_hierarchy(self.mapper, False, False))
- for rec in self.mapper._per_state_flush_actions(
- uow,
- states,
- False):
- yield rec
-
- for dep in uow.deps[self.mapper]:
- states_for_prop = uow.filter_states_for_dep(dep, states)
- dep.per_state_flush_actions(uow, states_for_prop, False)
-
-class DeleteAll(PostSortRec):
- def __init__(self, uow, mapper):
- self.mapper = mapper
- assert mapper is mapper.base_mapper
-
- def execute(self, uow):
- self.mapper._delete_obj(
- uow.states_for_mapper_hierarchy(self.mapper, True, False),
- uow
- )
-
- def per_state_flush_actions(self, uow):
- states = list(uow.states_for_mapper_hierarchy(self.mapper, True, False))
- for rec in self.mapper._per_state_flush_actions(
- uow,
- states,
- True):
- yield rec
-
- for dep in uow.deps[self.mapper]:
- states_for_prop = uow.filter_states_for_dep(dep, states)
- dep.per_state_flush_actions(uow, states_for_prop, True)
-
-class ProcessState(PostSortRec):
- def __init__(self, uow, dependency_processor, delete, state):
- self.dependency_processor = dependency_processor
- self.delete = delete
- self.state = state
-
- def execute_aggregate(self, uow, recs):
- cls_ = self.__class__
- dependency_processor = self.dependency_processor
- delete = self.delete
- our_recs = [r for r in recs
- if r.__class__ is cls_ and
- r.dependency_processor is dependency_processor and
- r.delete is delete]
- recs.difference_update(our_recs)
- states = [self.state] + [r.state for r in our_recs]
- if delete:
- dependency_processor.process_deletes(uow, states)
- else:
- dependency_processor.process_saves(uow, states)
-
- def __repr__(self):
- return "%s(%s, %s, delete=%s)" % (
- self.__class__.__name__,
- self.dependency_processor,
- mapperutil.state_str(self.state),
- self.delete
- )
-
-class SaveUpdateState(PostSortRec):
- def __init__(self, uow, state, mapper):
- self.state = state
- self.mapper = mapper
-
- def execute_aggregate(self, uow, recs):
- cls_ = self.__class__
- mapper = self.mapper
- our_recs = [r for r in recs
- if r.__class__ is cls_ and
- r.mapper is mapper]
- recs.difference_update(our_recs)
- mapper._save_obj(
- [self.state] +
- [r.state for r in our_recs],
- uow)
-
- def __repr__(self):
- return "%s(%s)" % (
- self.__class__.__name__,
- mapperutil.state_str(self.state)
- )
-
-class DeleteState(PostSortRec):
- def __init__(self, uow, state, mapper):
- self.state = state
- self.mapper = mapper
-
- def execute_aggregate(self, uow, recs):
- cls_ = self.__class__
- mapper = self.mapper
- our_recs = [r for r in recs
- if r.__class__ is cls_ and
- r.mapper is mapper]
- recs.difference_update(our_recs)
- states = [self.state] + [r.state for r in our_recs]
- mapper._delete_obj(
- [s for s in states if uow.states[s][0]],
- uow)
-
- def __repr__(self):
- return "%s(%s)" % (
- self.__class__.__name__,
- mapperutil.state_str(self.state)
- )
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py
deleted file mode 100755
index 8448b545..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/orm/util.py
+++ /dev/null
@@ -1,625 +0,0 @@
-# orm/util.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-
-from sqlalchemy import sql, util, event, exc as sa_exc
-from sqlalchemy.sql import expression, util as sql_util, operators
-from sqlalchemy.orm.interfaces import MapperExtension, EXT_CONTINUE,\
- PropComparator, MapperProperty
-from sqlalchemy.orm import attributes, exc
-import operator
-
-mapperlib = util.importlater("sqlalchemy.orm", "mapperlib")
-
-all_cascades = frozenset(("delete", "delete-orphan", "all", "merge",
- "expunge", "save-update", "refresh-expire",
- "none"))
-
-_INSTRUMENTOR = ('mapper', 'instrumentor')
-
-class CascadeOptions(dict):
- """Keeps track of the options sent to relationship().cascade"""
-
- def __init__(self, arg=""):
- if not arg:
- values = set()
- else:
- values = set(c.strip() for c in arg.split(','))
-
- for name in ['save-update', 'delete', 'refresh-expire',
- 'merge', 'expunge']:
- boolean = name in values or 'all' in values
- setattr(self, name.replace('-', '_'), boolean)
- if boolean:
- self[name] = True
- self.delete_orphan = "delete-orphan" in values
- if self.delete_orphan:
- self['delete-orphan'] = True
-
- if self.delete_orphan and not self.delete:
- util.warn("The 'delete-orphan' cascade option requires "
- "'delete'. This will raise an error in 0.6.")
-
- for x in values:
- if x not in all_cascades:
- raise sa_exc.ArgumentError("Invalid cascade option '%s'" % x)
-
- def __repr__(self):
- return "CascadeOptions(%s)" % repr(",".join(
- [x for x in ['delete', 'save_update', 'merge', 'expunge',
- 'delete_orphan', 'refresh-expire']
- if getattr(self, x, False) is True]))
-
-def _validator_events(desc, key, validator):
- """Runs a validation method on an attribute value to be set or appended."""
-
- def append(state, value, initiator):
- return validator(state.obj(), key, value)
-
- def set_(state, value, oldvalue, initiator):
- return validator(state.obj(), key, value)
-
- event.listen(desc, 'append', append, raw=True, retval=True)
- event.listen(desc, 'set', set_, raw=True, retval=True)
-
-def polymorphic_union(table_map, typecolname, aliasname='p_union', cast_nulls=True):
- """Create a ``UNION`` statement used by a polymorphic mapper.
-
- See :ref:`concrete_inheritance` for an example of how
- this is used.
-
- :param table_map: mapping of polymorphic identities to
- :class:`.Table` objects.
- :param typecolname: string name of a "discriminator" column, which will be
- derived from the query, producing the polymorphic identity for each row. If
- ``None``, no polymorphic discriminator is generated.
- :param aliasname: name of the :func:`~sqlalchemy.sql.expression.alias()`
- construct generated.
- :param cast_nulls: if True, non-existent columns, which are represented as labeled
- NULLs, will be passed into CAST. This is a legacy behavior that is problematic
- on some backends such as Oracle - in which case it can be set to False.
-
- """
-
- colnames = util.OrderedSet()
- colnamemaps = {}
- types = {}
- for key in table_map.keys():
- table = table_map[key]
-
- # mysql doesnt like selecting from a select;
- # make it an alias of the select
- if isinstance(table, sql.Select):
- table = table.alias()
- table_map[key] = table
-
- m = {}
- for c in table.c:
- colnames.add(c.key)
- m[c.key] = c
- types[c.key] = c.type
- colnamemaps[table] = m
-
- def col(name, table):
- try:
- return colnamemaps[table][name]
- except KeyError:
- if cast_nulls:
- return sql.cast(sql.null(), types[name]).label(name)
- else:
- return sql.type_coerce(sql.null(), types[name]).label(name)
-
- result = []
- for type, table in table_map.iteritems():
- if typecolname is not None:
- result.append(
- sql.select([col(name, table) for name in colnames] +
- [sql.literal_column(sql_util._quote_ddl_expr(type)).
- label(typecolname)],
- from_obj=[table]))
- else:
- result.append(sql.select([col(name, table) for name in colnames],
- from_obj=[table]))
- return sql.union_all(*result).alias(aliasname)
-
-def identity_key(*args, **kwargs):
- """Get an identity key.
-
- Valid call signatures:
-
- * ``identity_key(class, ident)``
-
- class
- mapped class (must be a positional argument)
-
- ident
- primary key, if the key is composite this is a tuple
-
-
- * ``identity_key(instance=instance)``
-
- instance
- object instance (must be given as a keyword arg)
-
- * ``identity_key(class, row=row)``
-
- class
- mapped class (must be a positional argument)
-
- row
- result proxy row (must be given as a keyword arg)
-
- """
- if args:
- if len(args) == 1:
- class_ = args[0]
- try:
- row = kwargs.pop("row")
- except KeyError:
- ident = kwargs.pop("ident")
- elif len(args) == 2:
- class_, ident = args
- elif len(args) == 3:
- class_, ident = args
- else:
- raise sa_exc.ArgumentError("expected up to three "
- "positional arguments, got %s" % len(args))
- if kwargs:
- raise sa_exc.ArgumentError("unknown keyword arguments: %s"
- % ", ".join(kwargs.keys()))
- mapper = class_mapper(class_)
- if "ident" in locals():
- return mapper.identity_key_from_primary_key(ident)
- return mapper.identity_key_from_row(row)
- instance = kwargs.pop("instance")
- if kwargs:
- raise sa_exc.ArgumentError("unknown keyword arguments: %s"
- % ", ".join(kwargs.keys()))
- mapper = object_mapper(instance)
- return mapper.identity_key_from_instance(instance)
-
-class ORMAdapter(sql_util.ColumnAdapter):
- """Extends ColumnAdapter to accept ORM entities.
-
- The selectable is extracted from the given entity,
- and the AliasedClass if any is referenced.
-
- """
- def __init__(self, entity, equivalents=None,
- chain_to=None, adapt_required=False):
- self.mapper, selectable, is_aliased_class = _entity_info(entity)
- if is_aliased_class:
- self.aliased_class = entity
- else:
- self.aliased_class = None
- sql_util.ColumnAdapter.__init__(self, selectable,
- equivalents, chain_to,
- adapt_required=adapt_required)
-
- def replace(self, elem):
- entity = elem._annotations.get('parentmapper', None)
- if not entity or entity.isa(self.mapper):
- return sql_util.ColumnAdapter.replace(self, elem)
- else:
- return None
-
-class AliasedClass(object):
- """Represents an "aliased" form of a mapped class for usage with Query.
-
- The ORM equivalent of a :func:`sqlalchemy.sql.expression.alias`
- construct, this object mimics the mapped class using a
- __getattr__ scheme and maintains a reference to a
- real :class:`~sqlalchemy.sql.expression.Alias` object.
-
- Usage is via the :class:`~sqlalchemy.orm.aliased()` synonym::
-
- # find all pairs of users with the same name
- user_alias = aliased(User)
- session.query(User, user_alias).\\
- join((user_alias, User.id > user_alias.id)).\\
- filter(User.name==user_alias.name)
-
- """
- def __init__(self, cls, alias=None, name=None):
- self.__mapper = _class_to_mapper(cls)
- self.__target = self.__mapper.class_
- if alias is None:
- alias = self.__mapper._with_polymorphic_selectable.alias(name=name)
- self.__adapter = sql_util.ClauseAdapter(alias,
- equivalents=self.__mapper._equivalent_columns)
- self.__alias = alias
- # used to assign a name to the RowTuple object
- # returned by Query.
- self._sa_label_name = name
- self.__name__ = 'AliasedClass_' + str(self.__target)
-
- def __getstate__(self):
- return {
- 'mapper':self.__mapper,
- 'alias':self.__alias,
- 'name':self._sa_label_name
- }
-
- def __setstate__(self, state):
- self.__mapper = state['mapper']
- self.__target = self.__mapper.class_
- alias = state['alias']
- self.__adapter = sql_util.ClauseAdapter(alias,
- equivalents=self.__mapper._equivalent_columns)
- self.__alias = alias
- name = state['name']
- self._sa_label_name = name
- self.__name__ = 'AliasedClass_' + str(self.__target)
-
- def __adapt_element(self, elem):
- return self.__adapter.traverse(elem).\
- _annotate({
- 'parententity': self,
- 'parentmapper':self.__mapper}
- )
-
- def __adapt_prop(self, existing, key):
- comparator = existing.comparator.adapted(self.__adapt_element)
-
- queryattr = attributes.QueryableAttribute(self, key,
- impl=existing.impl, parententity=self, comparator=comparator)
- setattr(self, key, queryattr)
- return queryattr
-
- def __getattr__(self, key):
- for base in self.__target.__mro__:
- try:
- attr = object.__getattribute__(base, key)
- except AttributeError:
- continue
- else:
- break
- else:
- raise AttributeError(key)
-
- if isinstance(attr, attributes.QueryableAttribute):
- return self.__adapt_prop(attr, key)
- elif hasattr(attr, 'func_code'):
- is_method = getattr(self.__target, key, None)
- if is_method and is_method.im_self is not None:
- return util.types.MethodType(attr.im_func, self, self)
- else:
- return None
- elif hasattr(attr, '__get__'):
- ret = attr.__get__(None, self)
- if isinstance(ret, PropComparator):
- return ret.adapted(self.__adapt_element)
- return ret
- else:
- return attr
-
- def __repr__(self):
- return '<AliasedClass at 0x%x; %s>' % (
- id(self), self.__target.__name__)
-
-def aliased(element, alias=None, name=None):
- if isinstance(element, expression.FromClause):
- return element.alias(name)
- else:
- return AliasedClass(element, alias=alias, name=name)
-
-def _orm_annotate(element, exclude=None):
- """Deep copy the given ClauseElement, annotating each element with the
- "_orm_adapt" flag.
-
- Elements within the exclude collection will be cloned but not annotated.
-
- """
- return sql_util._deep_annotate(element, {'_orm_adapt':True}, exclude)
-
-_orm_deannotate = sql_util._deep_deannotate
-
-class _ORMJoin(expression.Join):
- """Extend Join to support ORM constructs as input."""
-
- __visit_name__ = expression.Join.__visit_name__
-
- def __init__(self, left, right, onclause=None,
- isouter=False, join_to_left=True):
- adapt_from = None
-
- if hasattr(left, '_orm_mappers'):
- left_mapper = left._orm_mappers[1]
- if join_to_left:
- adapt_from = left.right
- else:
- left_mapper, left, left_is_aliased = _entity_info(left)
- if join_to_left and (left_is_aliased or not left_mapper):
- adapt_from = left
-
- right_mapper, right, right_is_aliased = _entity_info(right)
- if right_is_aliased:
- adapt_to = right
- else:
- adapt_to = None
-
- if left_mapper or right_mapper:
- self._orm_mappers = (left_mapper, right_mapper)
-
- if isinstance(onclause, basestring):
- prop = left_mapper.get_property(onclause)
- elif isinstance(onclause, attributes.QueryableAttribute):
- if adapt_from is None:
- adapt_from = onclause.__clause_element__()
- prop = onclause.property
- elif isinstance(onclause, MapperProperty):
- prop = onclause
- else:
- prop = None
-
- if prop:
- pj, sj, source, dest, \
- secondary, target_adapter = prop._create_joins(
- source_selectable=adapt_from,
- dest_selectable=adapt_to,
- source_polymorphic=True,
- dest_polymorphic=True,
- of_type=right_mapper)
-
- if sj is not None:
- left = sql.join(left, secondary, pj, isouter)
- onclause = sj
- else:
- onclause = pj
- self._target_adapter = target_adapter
-
- expression.Join.__init__(self, left, right, onclause, isouter)
-
- def join(self, right, onclause=None, isouter=False, join_to_left=True):
- return _ORMJoin(self, right, onclause, isouter, join_to_left)
-
- def outerjoin(self, right, onclause=None, join_to_left=True):
- return _ORMJoin(self, right, onclause, True, join_to_left)
-
-def join(left, right, onclause=None, isouter=False, join_to_left=True):
- """Produce an inner join between left and right clauses.
-
- In addition to the interface provided by
- :func:`~sqlalchemy.sql.expression.join()`, left and right may be mapped
- classes or AliasedClass instances. The onclause may be a
- string name of a relationship(), or a class-bound descriptor
- representing a relationship.
-
- join_to_left indicates to attempt aliasing the ON clause,
- in whatever form it is passed, to the selectable
- passed as the left side. If False, the onclause
- is used as is.
-
- """
- return _ORMJoin(left, right, onclause, isouter, join_to_left)
-
-def outerjoin(left, right, onclause=None, join_to_left=True):
- """Produce a left outer join between left and right clauses.
-
- In addition to the interface provided by
- :func:`~sqlalchemy.sql.expression.outerjoin()`, left and right may be
- mapped classes or AliasedClass instances. The onclause may be a string
- name of a relationship(), or a class-bound descriptor representing a
- relationship.
-
- """
- return _ORMJoin(left, right, onclause, True, join_to_left)
-
-def with_parent(instance, prop):
- """Create filtering criterion that relates this query's primary entity
- to the given related instance, using established :func:`.relationship()`
- configuration.
-
- The SQL rendered is the same as that rendered when a lazy loader
- would fire off from the given parent on that attribute, meaning
- that the appropriate state is taken from the parent object in
- Python without the need to render joins to the parent table
- in the rendered statement.
-
- As of 0.6.4, this method accepts parent instances in all
- persistence states, including transient, persistent, and detached.
- Only the requisite primary key/foreign key attributes need to
- be populated. Previous versions didn't work with transient
- instances.
-
- :param instance:
- An instance which has some :func:`.relationship`.
-
- :param property:
- String property name, or class-bound attribute, which indicates
- what relationship from the instance should be used to reconcile the
- parent/child relationship.
-
- """
- if isinstance(prop, basestring):
- mapper = object_mapper(instance)
- prop = mapper.get_property(prop)
- elif isinstance(prop, attributes.QueryableAttribute):
- prop = prop.property
-
- return prop.compare(operators.eq,
- instance,
- value_is_parent=True)
-
-
-def _entity_info(entity, compile=True):
- """Return mapping information given a class, mapper, or AliasedClass.
-
- Returns 3-tuple of: mapper, mapped selectable, boolean indicating if this
- is an aliased() construct.
-
- If the given entity is not a mapper, mapped class, or aliased construct,
- returns None, the entity, False. This is typically used to allow
- unmapped selectables through.
-
- """
- if isinstance(entity, AliasedClass):
- return entity._AliasedClass__mapper, entity._AliasedClass__alias, True
-
- if isinstance(entity, mapperlib.Mapper):
- mapper = entity
-
- elif isinstance(entity, type):
- class_manager = attributes.manager_of_class(entity)
-
- if class_manager is None:
- return None, entity, False
-
- mapper = class_manager.mapper
- else:
- return None, entity, False
-
- if compile and mapperlib.module._new_mappers:
- mapperlib.configure_mappers()
- return mapper, mapper._with_polymorphic_selectable, False
-
-def _entity_descriptor(entity, key):
- """Return a class attribute given an entity and string name.
-
- May return :class:`.InstrumentedAttribute` or user-defined
- attribute.
-
- """
- if not isinstance(entity, (AliasedClass, type)):
- entity = entity.class_
-
- try:
- return getattr(entity, key)
- except AttributeError:
- raise sa_exc.InvalidRequestError(
- "Entity '%s' has no property '%s'" %
- (entity, key)
- )
-
-def _orm_columns(entity):
- mapper, selectable, is_aliased_class = _entity_info(entity)
- if isinstance(selectable, expression.Selectable):
- return [c for c in selectable.c]
- else:
- return [selectable]
-
-def _orm_selectable(entity):
- mapper, selectable, is_aliased_class = _entity_info(entity)
- return selectable
-
-def _attr_as_key(attr):
- if hasattr(attr, 'key'):
- return attr.key
- else:
- return expression._column_as_key(attr)
-
-def _is_aliased_class(entity):
- return isinstance(entity, AliasedClass)
-
-_state_mapper = util.dottedgetter('manager.mapper')
-
-def object_mapper(instance):
- """Given an object, return the primary Mapper associated with the object
- instance.
-
- Raises UnmappedInstanceError if no mapping is configured.
-
- """
- try:
- state = attributes.instance_state(instance)
- return state.manager.mapper
- except exc.UnmappedClassError:
- raise exc.UnmappedInstanceError(instance)
- except exc.NO_STATE:
- raise exc.UnmappedInstanceError(instance)
-
-def class_mapper(class_, compile=True):
- """Given a class, return the primary Mapper associated with the key.
-
- Raises UnmappedClassError if no mapping is configured.
-
- """
-
- try:
- class_manager = attributes.manager_of_class(class_)
- mapper = class_manager.mapper
-
- except exc.NO_STATE:
- raise exc.UnmappedClassError(class_)
-
- if compile and mapperlib.module._new_mappers:
- mapperlib.configure_mappers()
- return mapper
-
-def _class_to_mapper(class_or_mapper, compile=True):
- if _is_aliased_class(class_or_mapper):
- return class_or_mapper._AliasedClass__mapper
-
- elif isinstance(class_or_mapper, type):
- try:
- class_manager = attributes.manager_of_class(class_or_mapper)
- mapper = class_manager.mapper
- except exc.NO_STATE:
- raise exc.UnmappedClassError(class_or_mapper)
- elif isinstance(class_or_mapper, mapperlib.Mapper):
- mapper = class_or_mapper
- else:
- raise exc.UnmappedClassError(class_or_mapper)
-
- if compile and mapperlib.module._new_mappers:
- mapperlib.configure_mappers()
- return mapper
-
-def has_identity(object):
- state = attributes.instance_state(object)
- return state.has_identity
-
-def _is_mapped_class(cls):
- if isinstance(cls, (AliasedClass, mapperlib.Mapper)):
- return True
- if isinstance(cls, expression.ClauseElement):
- return False
- if isinstance(cls, type):
- manager = attributes.manager_of_class(cls)
- return manager and _INSTRUMENTOR in manager.info
- return False
-
-def instance_str(instance):
- """Return a string describing an instance."""
-
- return state_str(attributes.instance_state(instance))
-
-def state_str(state):
- """Return a string describing an instance via its InstanceState."""
-
- if state is None:
- return "None"
- else:
- return '<%s at 0x%x>' % (state.class_.__name__, id(state.obj()))
-
-def state_class_str(state):
- """Return a string describing an instance's class via its InstanceState."""
-
- if state is None:
- return "None"
- else:
- return '<%s>' % (state.class_.__name__, )
-
-def attribute_str(instance, attribute):
- return instance_str(instance) + "." + attribute
-
-def state_attribute_str(state, attribute):
- return state_str(state) + "." + attribute
-
-def identity_equal(a, b):
- if a is b:
- return True
- if a is None or b is None:
- return False
- try:
- state_a = attributes.instance_state(a)
- state_b = attributes.instance_state(b)
- except exc.NO_STATE:
- return False
- if state_a.key is None or state_b.key is None:
- return False
- return state_a.key == state_b.key
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/pool.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/pool.py
deleted file mode 100755
index 2edafbf3..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/pool.py
+++ /dev/null
@@ -1,958 +0,0 @@
-# sqlalchemy/pool.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-
-"""Connection pooling for DB-API connections.
-
-Provides a number of connection pool implementations for a variety of
-usage scenarios and thread behavior requirements imposed by the
-application, DB-API or database itself.
-
-Also provides a DB-API 2.0 connection proxying mechanism allowing
-regular DB-API connect() methods to be transparently managed by a
-SQLAlchemy connection pool.
-"""
-
-import weakref, time, traceback
-
-from sqlalchemy import exc, log, event, events, interfaces, util
-from sqlalchemy.util import queue as sqla_queue
-from sqlalchemy.util import threading, memoized_property, \
- chop_traceback
-
-proxies = {}
-
-def manage(module, **params):
- """Return a proxy for a DB-API module that automatically
- pools connections.
-
- Given a DB-API 2.0 module and pool management parameters, returns
- a proxy for the module that will automatically pool connections,
- creating new connection pools for each distinct set of connection
- arguments sent to the decorated module's connect() function.
-
- :param module: a DB-API 2.0 database module
-
- :param poolclass: the class used by the pool module to provide
- pooling. Defaults to :class:`.QueuePool`.
-
- :param \*\*params: will be passed through to *poolclass*
-
- """
- try:
- return proxies[module]
- except KeyError:
- return proxies.setdefault(module, _DBProxy(module, **params))
-
-def clear_managers():
- """Remove all current DB-API 2.0 managers.
-
- All pools and connections are disposed.
- """
-
- for manager in proxies.itervalues():
- manager.close()
- proxies.clear()
-
-
-class Pool(log.Identified):
- """Abstract base class for connection pools."""
-
- def __init__(self,
- creator, recycle=-1, echo=None,
- use_threadlocal=False,
- logging_name=None,
- reset_on_return=True,
- listeners=None,
- events=None,
- _dispatch=None):
- """
- Construct a Pool.
-
- :param creator: a callable function that returns a DB-API
- connection object. The function will be called with
- parameters.
-
- :param recycle: If set to non -1, number of seconds between
- connection recycling, which means upon checkout, if this
- timeout is surpassed the connection will be closed and
- replaced with a newly opened connection. Defaults to -1.
-
- :param logging_name: String identifier which will be used within
- the "name" field of logging records generated within the
- "sqlalchemy.pool" logger. Defaults to a hexstring of the object's
- id.
-
- :param echo: If True, connections being pulled and retrieved
- from the pool will be logged to the standard output, as well
- as pool sizing information. Echoing can also be achieved by
- enabling logging for the "sqlalchemy.pool"
- namespace. Defaults to False.
-
- :param use_threadlocal: If set to True, repeated calls to
- :meth:`connect` within the same application thread will be
- guaranteed to return the same connection object, if one has
- already been retrieved from the pool and has not been
- returned yet. Offers a slight performance advantage at the
- cost of individual transactions by default. The
- :meth:`unique_connection` method is provided to bypass the
- threadlocal behavior installed into :meth:`connect`.
-
- :param reset_on_return: If true, reset the database state of
- connections returned to the pool. This is typically a
- ROLLBACK to release locks and transaction resources.
- Disable at your own peril. Defaults to True.
-
- :param events: a list of 2-tuples, each of the form
- ``(callable, target)`` which will be passed to event.listen()
- upon construction. Provided here so that event listeners
- can be assigned via ``create_engine`` before dialect-level
- listeners are applied.
-
- :param listeners: Deprecated. A list of
- :class:`~sqlalchemy.interfaces.PoolListener`-like objects or
- dictionaries of callables that receive events when DB-API
- connections are created, checked out and checked in to the
- pool. This has been superseded by
- :func:`~sqlalchemy.event.listen`.
-
- """
- if logging_name:
- self.logging_name = self._orig_logging_name = logging_name
- else:
- self._orig_logging_name = None
-
- log.instance_logger(self, echoflag=echo)
- self._threadconns = threading.local()
- self._creator = creator
- self._recycle = recycle
- self._use_threadlocal = use_threadlocal
- self._reset_on_return = reset_on_return
- self.echo = echo
- if _dispatch:
- self.dispatch._update(_dispatch, only_propagate=False)
- if events:
- for fn, target in events:
- event.listen(self, target, fn)
- if listeners:
- util.warn_deprecated(
- "The 'listeners' argument to Pool (and "
- "create_engine()) is deprecated. Use event.listen().")
- for l in listeners:
- self.add_listener(l)
-
- dispatch = event.dispatcher(events.PoolEvents)
-
- @util.deprecated(2.7, "Pool.add_listener is deprecated. Use event.listen()")
- def add_listener(self, listener):
- """Add a :class:`.PoolListener`-like object to this pool.
-
- ``listener`` may be an object that implements some or all of
- PoolListener, or a dictionary of callables containing implementations
- of some or all of the named methods in PoolListener.
-
- """
- interfaces.PoolListener._adapt_listener(self, listener)
-
- def unique_connection(self):
- """Produce a DBAPI connection that is not referenced by any
- thread-local context.
-
- This method is different from :meth:`.Pool.connect` only if the
- ``use_threadlocal`` flag has been set to ``True``.
-
- """
-
- return _ConnectionFairy(self).checkout()
-
- def _create_connection(self):
- """Called by subclasses to create a new ConnectionRecord."""
-
- return _ConnectionRecord(self)
-
- def recreate(self):
- """Return a new :class:`.Pool`, of the same class as this one
- and configured with identical creation arguments.
-
- This method is used in conjunection with :meth:`dispose`
- to close out an entire :class:`.Pool` and create a new one in
- its place.
-
- """
-
- raise NotImplementedError()
-
- def dispose(self):
- """Dispose of this pool.
-
- This method leaves the possibility of checked-out connections
- remaining open, It is advised to not reuse the pool once dispose()
- is called, and to instead use a new pool constructed by the
- recreate() method.
-
- """
-
- raise NotImplementedError()
-
- def connect(self):
- """Return a DBAPI connection from the pool.
-
- The connection is instrumented such that when its
- ``close()`` method is called, the connection will be returned to
- the pool.
-
- """
- if not self._use_threadlocal:
- return _ConnectionFairy(self).checkout()
-
- try:
- rec = self._threadconns.current()
- if rec:
- return rec.checkout()
- except AttributeError:
- pass
-
- agent = _ConnectionFairy(self)
- self._threadconns.current = weakref.ref(agent)
- return agent.checkout()
-
- def _return_conn(self, record):
- """Given a _ConnectionRecord, return it to the :class:`.Pool`.
-
- This method is called when an instrumented DBAPI connection
- has its ``close()`` method called.
-
- """
- if self._use_threadlocal:
- try:
- del self._threadconns.current
- except AttributeError:
- pass
- self._do_return_conn(record)
-
- def _do_get(self):
- """Implementation for :meth:`get`, supplied by subclasses."""
-
- raise NotImplementedError()
-
- def _do_return_conn(self, conn):
- """Implementation for :meth:`return_conn`, supplied by subclasses."""
-
- raise NotImplementedError()
-
- def status(self):
- raise NotImplementedError()
-
-
-class _ConnectionRecord(object):
- finalize_callback = None
-
- def __init__(self, pool):
- self.__pool = pool
- self.connection = self.__connect()
- self.info = {}
-
- pool.dispatch.first_connect.exec_once(self.connection, self)
- pool.dispatch.connect(self.connection, self)
-
- def close(self):
- if self.connection is not None:
- self.__pool.logger.debug("Closing connection %r", self.connection)
- try:
- self.connection.close()
- except (SystemExit, KeyboardInterrupt):
- raise
- except:
- self.__pool.logger.debug("Exception closing connection %r",
- self.connection)
-
- def invalidate(self, e=None):
- if e is not None:
- self.__pool.logger.info(
- "Invalidate connection %r (reason: %s:%s)",
- self.connection, e.__class__.__name__, e)
- else:
- self.__pool.logger.info(
- "Invalidate connection %r", self.connection)
- self.__close()
- self.connection = None
-
- def get_connection(self):
- if self.connection is None:
- self.connection = self.__connect()
- self.info.clear()
- if self.__pool.dispatch.connect:
- self.__pool.dispatch.connect(self.connection, self)
- elif self.__pool._recycle > -1 and \
- time.time() - self.starttime > self.__pool._recycle:
- self.__pool.logger.info(
- "Connection %r exceeded timeout; recycling",
- self.connection)
- self.__close()
- self.connection = self.__connect()
- self.info.clear()
- if self.__pool.dispatch.connect:
- self.__pool.dispatch.connect(self.connection, self)
- return self.connection
-
- def __close(self):
- try:
- self.__pool.logger.debug("Closing connection %r", self.connection)
- self.connection.close()
- except (SystemExit, KeyboardInterrupt):
- raise
- except Exception, e:
- self.__pool.logger.debug(
- "Connection %r threw an error on close: %s",
- self.connection, e)
-
- def __connect(self):
- try:
- self.starttime = time.time()
- connection = self.__pool._creator()
- self.__pool.logger.debug("Created new connection %r", connection)
- return connection
- except Exception, e:
- self.__pool.logger.debug("Error on connect(): %s", e)
- raise
-
-
-def _finalize_fairy(connection, connection_record, pool, ref, echo):
- _refs.discard(connection_record)
-
- if ref is not None and \
- connection_record.fairy is not ref:
- return
-
- if connection is not None:
- try:
- if pool._reset_on_return:
- connection.rollback()
- # Immediately close detached instances
- if connection_record is None:
- connection.close()
- except Exception, e:
- if connection_record is not None:
- connection_record.invalidate(e=e)
- if isinstance(e, (SystemExit, KeyboardInterrupt)):
- raise
-
- if connection_record is not None:
- connection_record.fairy = None
- if echo:
- pool.logger.debug("Connection %r being returned to pool",
- connection)
- if connection_record.finalize_callback:
- connection_record.finalize_callback(connection)
- del connection_record.finalize_callback
- if pool.dispatch.checkin:
- pool.dispatch.checkin(connection, connection_record)
- pool._return_conn(connection_record)
-
-_refs = set()
-
-class _ConnectionFairy(object):
- """Proxies a DB-API connection and provides return-on-dereference
- support."""
-
- __slots__ = '_pool', '__counter', 'connection', \
- '_connection_record', '__weakref__', \
- '_detached_info', '_echo'
-
- def __init__(self, pool):
- self._pool = pool
- self.__counter = 0
- self._echo = _echo = pool._should_log_debug()
- try:
- rec = self._connection_record = pool._do_get()
- conn = self.connection = self._connection_record.get_connection()
- rec.fairy = weakref.ref(
- self,
- lambda ref:_finalize_fairy(conn, rec, pool, ref, _echo)
- )
- _refs.add(rec)
- except:
- # helps with endless __getattr__ loops later on
- self.connection = None
- self._connection_record = None
- raise
- if self._echo:
- self._pool.logger.debug("Connection %r checked out from pool" %
- self.connection)
-
- @property
- def _logger(self):
- return self._pool.logger
-
- @property
- def is_valid(self):
- return self.connection is not None
-
- @property
- def info(self):
- """An info collection unique to this DB-API connection."""
-
- try:
- return self._connection_record.info
- except AttributeError:
- if self.connection is None:
- raise exc.InvalidRequestError("This connection is closed")
- try:
- return self._detached_info
- except AttributeError:
- self._detached_info = value = {}
- return value
-
- def invalidate(self, e=None):
- """Mark this connection as invalidated.
-
- The connection will be immediately closed. The containing
- ConnectionRecord will create a new connection when next used.
- """
-
- if self.connection is None:
- raise exc.InvalidRequestError("This connection is closed")
- if self._connection_record is not None:
- self._connection_record.invalidate(e=e)
- self.connection = None
- self._close()
-
- def cursor(self, *args, **kwargs):
- return self.connection.cursor(*args, **kwargs)
-
- def __getattr__(self, key):
- return getattr(self.connection, key)
-
- def checkout(self):
- if self.connection is None:
- raise exc.InvalidRequestError("This connection is closed")
- self.__counter += 1
-
- if not self._pool.dispatch.checkout or self.__counter != 1:
- return self
-
- # Pool listeners can trigger a reconnection on checkout
- attempts = 2
- while attempts > 0:
- try:
- self._pool.dispatch.checkout(self.connection,
- self._connection_record,
- self)
- return self
- except exc.DisconnectionError, e:
- self._pool.logger.info(
- "Disconnection detected on checkout: %s", e)
- self._connection_record.invalidate(e)
- self.connection = self._connection_record.get_connection()
- attempts -= 1
-
- self._pool.logger.info("Reconnection attempts exhausted on checkout")
- self.invalidate()
- raise exc.InvalidRequestError("This connection is closed")
-
- def detach(self):
- """Separate this connection from its Pool.
-
- This means that the connection will no longer be returned to the
- pool when closed, and will instead be literally closed. The
- containing ConnectionRecord is separated from the DB-API connection,
- and will create a new connection when next used.
-
- Note that any overall connection limiting constraints imposed by a
- Pool implementation may be violated after a detach, as the detached
- connection is removed from the pool's knowledge and control.
- """
-
- if self._connection_record is not None:
- _refs.remove(self._connection_record)
- self._connection_record.fairy = None
- self._connection_record.connection = None
- self._pool._do_return_conn(self._connection_record)
- self._detached_info = \
- self._connection_record.info.copy()
- self._connection_record = None
-
- def close(self):
- self.__counter -= 1
- if self.__counter == 0:
- self._close()
-
- def _close(self):
- _finalize_fairy(self.connection, self._connection_record,
- self._pool, None, self._echo)
- self.connection = None
- self._connection_record = None
-
-class SingletonThreadPool(Pool):
- """A Pool that maintains one connection per thread.
-
- Maintains one connection per each thread, never moving a connection to a
- thread other than the one which it was created in.
-
- Options are the same as those of :class:`.Pool`, as well as:
-
- :param pool_size: The number of threads in which to maintain connections
- at once. Defaults to five.
-
- :class:`.SingletonThreadPool` is used by the SQLite dialect
- automatically when a memory-based database is used.
- See :ref:`sqlite_toplevel`.
-
- """
-
- def __init__(self, creator, pool_size=5, **kw):
- kw['use_threadlocal'] = True
- Pool.__init__(self, creator, **kw)
- self._conn = threading.local()
- self._all_conns = set()
- self.size = pool_size
-
- def recreate(self):
- self.logger.info("Pool recreating")
- return SingletonThreadPool(self._creator,
- pool_size=self.size,
- recycle=self._recycle,
- echo=self.echo,
- logging_name=self._orig_logging_name,
- use_threadlocal=self._use_threadlocal,
- _dispatch=self.dispatch)
-
- def dispose(self):
- """Dispose of this pool."""
-
- for conn in self._all_conns:
- try:
- conn.close()
- except (SystemExit, KeyboardInterrupt):
- raise
- except:
- # pysqlite won't even let you close a conn from a thread
- # that didn't create it
- pass
-
- self._all_conns.clear()
-
- def _cleanup(self):
- while len(self._all_conns) > self.size:
- c = self._all_conns.pop()
- c.close()
-
- def status(self):
- return "SingletonThreadPool id:%d size: %d" % \
- (id(self), len(self._all_conns))
-
- def _do_return_conn(self, conn):
- pass
-
- def _do_get(self):
- try:
- c = self._conn.current()
- if c:
- return c
- except AttributeError:
- pass
- c = self._create_connection()
- self._conn.current = weakref.ref(c)
- self._all_conns.add(c)
- if len(self._all_conns) > self.size:
- self._cleanup()
- return c
-
-class QueuePool(Pool):
- """A :class:`.Pool` that imposes a limit on the number of open connections.
-
- :class:`.QueuePool` is the default pooling implementation used for
- all :class:`.Engine` objects, unless the SQLite dialect is in use.
-
- """
-
- def __init__(self, creator, pool_size=5, max_overflow=10, timeout=30,
- **kw):
- """
- Construct a QueuePool.
-
- :param creator: a callable function that returns a DB-API
- connection object. The function will be called with
- parameters.
-
- :param pool_size: The size of the pool to be maintained,
- defaults to 5. This is the largest number of connections that
- will be kept persistently in the pool. Note that the pool
- begins with no connections; once this number of connections
- is requested, that number of connections will remain.
- ``pool_size`` can be set to 0 to indicate no size limit; to
- disable pooling, use a :class:`~sqlalchemy.pool.NullPool`
- instead.
-
- :param max_overflow: The maximum overflow size of the
- pool. When the number of checked-out connections reaches the
- size set in pool_size, additional connections will be
- returned up to this limit. When those additional connections
- are returned to the pool, they are disconnected and
- discarded. It follows then that the total number of
- simultaneous connections the pool will allow is pool_size +
- `max_overflow`, and the total number of "sleeping"
- connections the pool will allow is pool_size. `max_overflow`
- can be set to -1 to indicate no overflow limit; no limit
- will be placed on the total number of concurrent
- connections. Defaults to 10.
-
- :param timeout: The number of seconds to wait before giving up
- on returning a connection. Defaults to 30.
-
- :param recycle: If set to non -1, number of seconds between
- connection recycling, which means upon checkout, if this
- timeout is surpassed the connection will be closed and
- replaced with a newly opened connection. Defaults to -1.
-
- :param echo: If True, connections being pulled and retrieved
- from the pool will be logged to the standard output, as well
- as pool sizing information. Echoing can also be achieved by
- enabling logging for the "sqlalchemy.pool"
- namespace. Defaults to False.
-
- :param use_threadlocal: If set to True, repeated calls to
- :meth:`connect` within the same application thread will be
- guaranteed to return the same connection object, if one has
- already been retrieved from the pool and has not been
- returned yet. Offers a slight performance advantage at the
- cost of individual transactions by default. The
- :meth:`unique_connection` method is provided to bypass the
- threadlocal behavior installed into :meth:`connect`.
-
- :param reset_on_return: If true, reset the database state of
- connections returned to the pool. This is typically a
- ROLLBACK to release locks and transaction resources.
- Disable at your own peril. Defaults to True.
-
- :param listeners: A list of
- :class:`~sqlalchemy.interfaces.PoolListener`-like objects or
- dictionaries of callables that receive events when DB-API
- connections are created, checked out and checked in to the
- pool.
-
- """
- Pool.__init__(self, creator, **kw)
- self._pool = sqla_queue.Queue(pool_size)
- self._overflow = 0 - pool_size
- self._max_overflow = max_overflow
- self._timeout = timeout
- self._overflow_lock = self._max_overflow > -1 and \
- threading.Lock() or None
-
- def recreate(self):
- self.logger.info("Pool recreating")
- return QueuePool(self._creator, pool_size=self._pool.maxsize,
- max_overflow=self._max_overflow,
- timeout=self._timeout,
- recycle=self._recycle, echo=self.echo,
- logging_name=self._orig_logging_name,
- use_threadlocal=self._use_threadlocal,
- _dispatch=self.dispatch)
-
- def _do_return_conn(self, conn):
- try:
- self._pool.put(conn, False)
- except sqla_queue.Full:
- conn.close()
- if self._overflow_lock is None:
- self._overflow -= 1
- else:
- self._overflow_lock.acquire()
- try:
- self._overflow -= 1
- finally:
- self._overflow_lock.release()
-
- def _do_get(self):
- try:
- wait = self._max_overflow > -1 and \
- self._overflow >= self._max_overflow
- return self._pool.get(wait, self._timeout)
- except sqla_queue.Empty:
- if self._max_overflow > -1 and \
- self._overflow >= self._max_overflow:
- if not wait:
- return self._do_get()
- else:
- raise exc.TimeoutError(
- "QueuePool limit of size %d overflow %d reached, "
- "connection timed out, timeout %d" %
- (self.size(), self.overflow(), self._timeout))
-
- if self._overflow_lock is not None:
- self._overflow_lock.acquire()
-
- if self._max_overflow > -1 and \
- self._overflow >= self._max_overflow:
- if self._overflow_lock is not None:
- self._overflow_lock.release()
- return self._do_get()
-
- try:
- con = self._create_connection()
- self._overflow += 1
- finally:
- if self._overflow_lock is not None:
- self._overflow_lock.release()
- return con
-
- def dispose(self):
- while True:
- try:
- conn = self._pool.get(False)
- conn.close()
- except sqla_queue.Empty:
- break
-
- self._overflow = 0 - self.size()
- self.logger.info("Pool disposed. %s", self.status())
-
- def status(self):
- return "Pool size: %d Connections in pool: %d "\
- "Current Overflow: %d Current Checked out "\
- "connections: %d" % (self.size(),
- self.checkedin(),
- self.overflow(),
- self.checkedout())
-
- def size(self):
- return self._pool.maxsize
-
- def checkedin(self):
- return self._pool.qsize()
-
- def overflow(self):
- return self._overflow
-
- def checkedout(self):
- return self._pool.maxsize - self._pool.qsize() + self._overflow
-
-class NullPool(Pool):
- """A Pool which does not pool connections.
-
- Instead it literally opens and closes the underlying DB-API connection
- per each connection open/close.
-
- Reconnect-related functions such as ``recycle`` and connection
- invalidation are not supported by this Pool implementation, since
- no connections are held persistently.
-
- :class:`.NullPool` is used by the SQlite dilalect automatically
- when a file-based database is used (as of SQLAlchemy 0.7).
- See :ref:`sqlite_toplevel`.
-
- """
-
- def status(self):
- return "NullPool"
-
- def _do_return_conn(self, conn):
- conn.close()
-
- def _do_get(self):
- return self._create_connection()
-
- def recreate(self):
- self.logger.info("Pool recreating")
-
- return NullPool(self._creator,
- recycle=self._recycle,
- echo=self.echo,
- logging_name=self._orig_logging_name,
- use_threadlocal=self._use_threadlocal,
- _dispatch=self.dispatch)
-
- def dispose(self):
- pass
-
-
-class StaticPool(Pool):
- """A Pool of exactly one connection, used for all requests.
-
- Reconnect-related functions such as ``recycle`` and connection
- invalidation (which is also used to support auto-reconnect) are not
- currently supported by this Pool implementation but may be implemented
- in a future release.
-
- """
-
- @memoized_property
- def _conn(self):
- return self._creator()
-
- @memoized_property
- def connection(self):
- return _ConnectionRecord(self)
-
- def status(self):
- return "StaticPool"
-
- def dispose(self):
- if '_conn' in self.__dict__:
- self._conn.close()
- self._conn = None
-
- def recreate(self):
- self.logger.info("Pool recreating")
- return self.__class__(creator=self._creator,
- recycle=self._recycle,
- use_threadlocal=self._use_threadlocal,
- reset_on_return=self._reset_on_return,
- echo=self.echo,
- logging_name=self._orig_logging_name,
- _dispatch=self.dispatch)
-
- def _create_connection(self):
- return self._conn
-
- def _do_return_conn(self, conn):
- pass
-
- def _do_get(self):
- return self.connection
-
-class AssertionPool(Pool):
- """A :class:`.Pool` that allows at most one checked out connection at any given
- time.
-
- This will raise an exception if more than one connection is checked out
- at a time. Useful for debugging code that is using more connections
- than desired.
-
- :class:`.AssertionPool` also logs a traceback of where
- the original connection was checked out, and reports
- this in the assertion error raised (new in 0.7).
-
- """
- def __init__(self, *args, **kw):
- self._conn = None
- self._checked_out = False
- self._store_traceback = kw.pop('store_traceback', True)
- self._checkout_traceback = None
- Pool.__init__(self, *args, **kw)
-
- def status(self):
- return "AssertionPool"
-
- def _do_return_conn(self, conn):
- if not self._checked_out:
- raise AssertionError("connection is not checked out")
- self._checked_out = False
- assert conn is self._conn
-
- def dispose(self):
- self._checked_out = False
- if self._conn:
- self._conn.close()
-
- def recreate(self):
- self.logger.info("Pool recreating")
- return AssertionPool(self._creator, echo=self.echo,
- logging_name=self._orig_logging_name,
- _dispatch=self.dispatch)
-
- def _do_get(self):
- if self._checked_out:
- if self._checkout_traceback:
- suffix = ' at:\n%s' % ''.join(
- chop_traceback(self._checkout_traceback))
- else:
- suffix = ''
- raise AssertionError("connection is already checked out" + suffix)
-
- if not self._conn:
- self._conn = self._create_connection()
-
- self._checked_out = True
- if self._store_traceback:
- self._checkout_traceback = traceback.format_stack()
- return self._conn
-
-class _DBProxy(object):
- """Layers connection pooling behavior on top of a standard DB-API module.
-
- Proxies a DB-API 2.0 connect() call to a connection pool keyed to the
- specific connect parameters. Other functions and attributes are delegated
- to the underlying DB-API module.
- """
-
- def __init__(self, module, poolclass=QueuePool, **kw):
- """Initializes a new proxy.
-
- module
- a DB-API 2.0 module
-
- poolclass
- a Pool class, defaulting to QueuePool
-
- Other parameters are sent to the Pool object's constructor.
-
- """
-
- self.module = module
- self.kw = kw
- self.poolclass = poolclass
- self.pools = {}
- self._create_pool_mutex = threading.Lock()
-
- def close(self):
- for key in self.pools.keys():
- del self.pools[key]
-
- def __del__(self):
- self.close()
-
- def __getattr__(self, key):
- return getattr(self.module, key)
-
- def get_pool(self, *args, **kw):
- key = self._serialize(*args, **kw)
- try:
- return self.pools[key]
- except KeyError:
- self._create_pool_mutex.acquire()
- try:
- if key not in self.pools:
- pool = self.poolclass(lambda:
- self.module.connect(*args, **kw), **self.kw)
- self.pools[key] = pool
- return pool
- else:
- return self.pools[key]
- finally:
- self._create_pool_mutex.release()
-
- def connect(self, *args, **kw):
- """Activate a connection to the database.
-
- Connect to the database using this DBProxy's module and the given
- connect arguments. If the arguments match an existing pool, the
- connection will be returned from the pool's current thread-local
- connection instance, or if there is no thread-local connection
- instance it will be checked out from the set of pooled connections.
-
- If the pool has no available connections and allows new connections
- to be created, a new database connection will be made.
-
- """
-
- return self.get_pool(*args, **kw).connect()
-
- def dispose(self, *args, **kw):
- """Dispose the pool referenced by the given connect arguments."""
-
- key = self._serialize(*args, **kw)
- try:
- del self.pools[key]
- except KeyError:
- pass
-
- def _serialize(self, *args, **kw):
- return tuple(
- list(args) +
- [(k, kw[k]) for k in sorted(kw)]
- )
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/processors.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/processors.py
deleted file mode 100755
index cb5f00bd..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/processors.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# sqlalchemy/processors.py
-# Copyright (C) 2010-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-# Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""defines generic type conversion functions, as used in bind and result
-processors.
-
-They all share one common characteristic: None is passed through unchanged.
-
-"""
-
-import codecs
-import re
-import datetime
-
-def str_to_datetime_processor_factory(regexp, type_):
- rmatch = regexp.match
- # Even on python2.6 datetime.strptime is both slower than this code
- # and it does not support microseconds.
- def process(value):
- if value is None:
- return None
- else:
- return type_(*map(int, rmatch(value).groups(0)))
- return process
-
-def boolean_to_int(value):
- if value is None:
- return None
- else:
- return int(value)
-
-try:
- from sqlalchemy.cprocessors import UnicodeResultProcessor, \
- DecimalResultProcessor, \
- to_float, to_str, int_to_boolean, \
- str_to_datetime, str_to_time, \
- str_to_date
-
- def to_unicode_processor_factory(encoding, errors=None):
- # this is cumbersome but it would be even more so on the C side
- if errors is not None:
- return UnicodeResultProcessor(encoding, errors).process
- else:
- return UnicodeResultProcessor(encoding).process
-
- def to_decimal_processor_factory(target_class, scale=10):
- # Note that the scale argument is not taken into account for integer
- # values in the C implementation while it is in the Python one.
- # For example, the Python implementation might return
- # Decimal('5.00000') whereas the C implementation will
- # return Decimal('5'). These are equivalent of course.
- return DecimalResultProcessor(target_class, "%%.%df" % scale).process
-
-except ImportError:
- def to_unicode_processor_factory(encoding, errors=None):
- decoder = codecs.getdecoder(encoding)
-
- def process(value):
- if value is None:
- return None
- else:
- # decoder returns a tuple: (value, len). Simply dropping the
- # len part is safe: it is done that way in the normal
- # 'xx'.decode(encoding) code path.
- return decoder(value, errors)[0]
- return process
-
- def to_decimal_processor_factory(target_class, scale=10):
- fstring = "%%.%df" % scale
-
- def process(value):
- if value is None:
- return None
- else:
- return target_class(fstring % value)
- return process
-
- def to_float(value):
- if value is None:
- return None
- else:
- return float(value)
-
- def to_str(value):
- if value is None:
- return None
- else:
- return str(value)
-
- def int_to_boolean(value):
- if value is None:
- return None
- else:
- return value and True or False
-
- DATETIME_RE = re.compile(
- "(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(?:\.(\d+))?")
- TIME_RE = re.compile("(\d+):(\d+):(\d+)(?:\.(\d+))?")
- DATE_RE = re.compile("(\d+)-(\d+)-(\d+)")
-
- str_to_datetime = str_to_datetime_processor_factory(DATETIME_RE,
- datetime.datetime)
- str_to_time = str_to_datetime_processor_factory(TIME_RE, datetime.time)
- str_to_date = str_to_datetime_processor_factory(DATE_RE, datetime.date)
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/schema.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/schema.py
deleted file mode 100755
index e85c82ad..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/schema.py
+++ /dev/null
@@ -1,2950 +0,0 @@
-# sqlalchemy/schema.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""The schema module provides the building blocks for database metadata.
-
-Each element within this module describes a database entity which can be
-created and dropped, or is otherwise part of such an entity. Examples include
-tables, columns, sequences, and indexes.
-
-All entities are subclasses of :class:`~sqlalchemy.schema.SchemaItem`, and as
-defined in this module they are intended to be agnostic of any vendor-specific
-constructs.
-
-A collection of entities are grouped into a unit called
-:class:`~sqlalchemy.schema.MetaData`. MetaData serves as a logical grouping of
-schema elements, and can also be associated with an actual database connection
-such that operations involving the contained elements can contact the database
-as needed.
-
-Two of the elements here also build upon their "syntactic" counterparts, which
-are defined in :class:`~sqlalchemy.sql.expression.`, specifically
-:class:`~sqlalchemy.schema.Table` and :class:`~sqlalchemy.schema.Column`.
-Since these objects are part of the SQL expression language, they are usable
-as components in SQL expressions.
-
-"""
-import re, inspect
-from sqlalchemy import exc, util, dialects
-from sqlalchemy.sql import expression, visitors
-from sqlalchemy import event, events
-
-sqlutil = util.importlater("sqlalchemy.sql", "util")
-url = util.importlater("sqlalchemy.engine", "url")
-sqltypes = util.importlater("sqlalchemy", "types")
-
-__all__ = ['SchemaItem', 'Table', 'Column', 'ForeignKey', 'Sequence', 'Index',
- 'ForeignKeyConstraint', 'PrimaryKeyConstraint', 'CheckConstraint',
- 'UniqueConstraint', 'DefaultGenerator', 'Constraint', 'MetaData',
- 'ThreadLocalMetaData', 'SchemaVisitor', 'PassiveDefault',
- 'DefaultClause', 'FetchedValue', 'ColumnDefault', 'DDL',
- 'CreateTable', 'DropTable', 'CreateSequence', 'DropSequence',
- 'AddConstraint', 'DropConstraint',
- ]
-__all__.sort()
-
-RETAIN_SCHEMA = util.symbol('retain_schema')
-
-class SchemaItem(events.SchemaEventTarget, visitors.Visitable):
- """Base class for items that define a database schema."""
-
- __visit_name__ = 'schema_item'
- quote = None
-
- def _init_items(self, *args):
- """Initialize the list of child items for this SchemaItem."""
-
- for item in args:
- if item is not None:
- item._set_parent_with_dispatch(self)
-
- def get_children(self, **kwargs):
- """used to allow SchemaVisitor access"""
- return []
-
- def __repr__(self):
- return "%s()" % self.__class__.__name__
-
- @util.memoized_property
- def info(self):
- return {}
-
-def _get_table_key(name, schema):
- if schema is None:
- return name
- else:
- return schema + "." + name
-
-
-class Table(SchemaItem, expression.TableClause):
- """Represent a table in a database.
-
- e.g.::
-
- mytable = Table("mytable", metadata,
- Column('mytable_id', Integer, primary_key=True),
- Column('value', String(50))
- )
-
- The :class:`.Table` object constructs a unique instance of itself based on its
- name and optionl schema name within the given :class:`.MetaData` object.
- Calling the :class:`.Table`
- constructor with the same name and same :class:`.MetaData` argument
- a second time will return the *same* :class:`.Table` object - in this way
- the :class:`.Table` constructor acts as a registry function.
-
- Constructor arguments are as follows:
-
- :param name: The name of this table as represented in the database.
-
- This property, along with the *schema*, indicates the *singleton
- identity* of this table in relation to its parent :class:`.MetaData`.
- Additional calls to :class:`.Table` with the same name, metadata,
- and schema name will return the same :class:`.Table` object.
-
- Names which contain no upper case characters
- will be treated as case insensitive names, and will not be quoted
- unless they are a reserved word. Names with any number of upper
- case characters will be quoted and sent exactly. Note that this
- behavior applies even for databases which standardize upper
- case names as case insensitive such as Oracle.
-
- :param metadata: a :class:`.MetaData` object which will contain this
- table. The metadata is used as a point of association of this table
- with other tables which are referenced via foreign key. It also
- may be used to associate this table with a particular
- :class:`~sqlalchemy.engine.base.Connectable`.
-
- :param \*args: Additional positional arguments are used primarily
- to add the list of :class:`.Column` objects contained within this
- table. Similar to the style of a CREATE TABLE statement, other
- :class:`.SchemaItem` constructs may be added here, including
- :class:`.PrimaryKeyConstraint`, and :class:`.ForeignKeyConstraint`.
-
- :param autoload: Defaults to False: the Columns for this table should
- be reflected from the database. Usually there will be no Column
- objects in the constructor if this property is set.
-
- :param autoload_with: If autoload==True, this is an optional Engine
- or Connection instance to be used for the table reflection. If
- ``None``, the underlying MetaData's bound connectable will be used.
-
- :param extend_existing: When ``True``, indicates that if this Table is already
- present in the given :class:`.MetaData`, apply further arguments within
- the constructor to the existing :class:`.Table`.
-
- If extend_existing or keep_existing are not set, an error is
- raised if additional table modifiers are specified when
- the given :class:`.Table` is already present in the :class:`.MetaData`.
-
- :param implicit_returning: True by default - indicates that
- RETURNING can be used by default to fetch newly inserted primary key
- values, for backends which support this. Note that
- create_engine() also provides an implicit_returning flag.
-
- :param include_columns: A list of strings indicating a subset of
- columns to be loaded via the ``autoload`` operation; table columns who
- aren't present in this list will not be represented on the resulting
- ``Table`` object. Defaults to ``None`` which indicates all columns
- should be reflected.
-
- :param info: A dictionary which defaults to ``{}``. A space to store
- application specific data. This must be a dictionary.
-
- :param keep_existing: When ``True``, indicates that if this Table
- is already present in the given :class:`.MetaData`, ignore
- further arguments within the constructor to the existing
- :class:`.Table`, and return the :class:`.Table` object as
- originally created. This is to allow a function that wishes
- to define a new :class:`.Table` on first call, but on
- subsequent calls will return the same :class:`.Table`,
- without any of the declarations (particularly constraints)
- being applied a second time. Also see extend_existing.
-
- If extend_existing or keep_existing are not set, an error is
- raised if additional table modifiers are specified when
- the given :class:`.Table` is already present in the :class:`.MetaData`.
-
- :param listeners: A list of tuples of the form ``(<eventname>, <fn>)``
- which will be passed to :func:`.event.listen` upon construction.
- This alternate hook to :func:`.event.listen` allows the establishment
- of a listener function specific to this :class:`.Table` before
- the "autoload" process begins. Particularly useful for
- the :meth:`.events.column_reflect` event::
-
- def listen_for_reflect(table, column_info):
- "handle the column reflection event"
- # ...
-
- t = Table(
- 'sometable',
- autoload=True,
- listeners=[
- ('column_reflect', listen_for_reflect)
- ])
-
- :param mustexist: When ``True``, indicates that this Table must already
- be present in the given :class:`.MetaData`` collection, else
- an exception is raised.
-
- :param prefixes:
- A list of strings to insert after CREATE in the CREATE TABLE
- statement. They will be separated by spaces.
-
- :param quote: Force quoting of this table's name on or off, corresponding
- to ``True`` or ``False``. When left at its default of ``None``,
- the column identifier will be quoted according to whether the name is
- case sensitive (identifiers with at least one upper case character are
- treated as case sensitive), or if it's a reserved word. This flag
- is only needed to force quoting of a reserved word which is not known
- by the SQLAlchemy dialect.
-
- :param quote_schema: same as 'quote' but applies to the schema identifier.
-
- :param schema: The *schema name* for this table, which is required if
- the table resides in a schema other than the default selected schema
- for the engine's database connection. Defaults to ``None``.
-
- :param useexisting: Deprecated. Use extend_existing.
-
- """
-
- __visit_name__ = 'table'
-
- def __new__(cls, *args, **kw):
- if not args:
- # python3k pickle seems to call this
- return object.__new__(cls)
-
- try:
- name, metadata, args = args[0], args[1], args[2:]
- except IndexError:
- raise TypeError("Table() takes at least two arguments")
-
- schema = kw.get('schema', None)
- keep_existing = kw.pop('keep_existing', False)
- extend_existing = kw.pop('extend_existing', False)
- if 'useexisting' in kw:
- util.warn_deprecated("useexisting is deprecated. Use extend_existing.")
- if extend_existing:
- raise exc.ArgumentError("useexisting is synonymous "
- "with extend_existing.")
- extend_existing = kw.pop('useexisting', False)
-
- if keep_existing and extend_existing:
- raise exc.ArgumentError("keep_existing and extend_existing "
- "are mutually exclusive.")
-
- mustexist = kw.pop('mustexist', False)
- key = _get_table_key(name, schema)
- if key in metadata.tables:
- if not keep_existing and not extend_existing and bool(args):
- raise exc.InvalidRequestError(
- "Table '%s' is already defined for this MetaData "
- "instance. Specify 'extend_existing=True' "
- "to redefine "
- "options and columns on an "
- "existing Table object." % key)
- table = metadata.tables[key]
- if extend_existing:
- table._init_existing(*args, **kw)
- return table
- else:
- if mustexist:
- raise exc.InvalidRequestError(
- "Table '%s' not defined" % (key))
- table = object.__new__(cls)
- table.dispatch.before_parent_attach(table, metadata)
- metadata._add_table(name, schema, table)
- try:
- table._init(name, metadata, *args, **kw)
- table.dispatch.after_parent_attach(table, metadata)
- return table
- except:
- metadata._remove_table(name, schema)
- raise
-
- def __init__(self, *args, **kw):
- """Constructor for :class:`~.schema.Table`.
-
- This method is a no-op. See the top-level
- documentation for :class:`~.schema.Table`
- for constructor arguments.
-
- """
- # __init__ is overridden to prevent __new__ from
- # calling the superclass constructor.
-
- def _init(self, name, metadata, *args, **kwargs):
- super(Table, self).__init__(name)
- self.metadata = metadata
- self.schema = kwargs.pop('schema', None)
- self.indexes = set()
- self.constraints = set()
- self._columns = expression.ColumnCollection()
- PrimaryKeyConstraint()._set_parent_with_dispatch(self)
- self.foreign_keys = set()
- self._extra_dependencies = set()
- self.kwargs = {}
- if self.schema is not None:
- self.fullname = "%s.%s" % (self.schema, self.name)
- else:
- self.fullname = self.name
-
- autoload = kwargs.pop('autoload', False)
- autoload_with = kwargs.pop('autoload_with', None)
- include_columns = kwargs.pop('include_columns', None)
-
- self.implicit_returning = kwargs.pop('implicit_returning', True)
- self.quote = kwargs.pop('quote', None)
- self.quote_schema = kwargs.pop('quote_schema', None)
- if 'info' in kwargs:
- self.info = kwargs.pop('info')
- if 'listeners' in kwargs:
- listeners = kwargs.pop('listeners')
- for evt, fn in listeners:
- event.listen(self, evt, fn)
-
- self._prefixes = kwargs.pop('prefixes', [])
-
- self._extra_kwargs(**kwargs)
-
- # load column definitions from the database if 'autoload' is defined
- # we do it after the table is in the singleton dictionary to support
- # circular foreign keys
- if autoload:
- if autoload_with:
- autoload_with.reflecttable(self,
- include_columns=include_columns)
- else:
- _bind_or_error(metadata,
- msg="No engine is bound to this Table's MetaData. "
- "Pass an engine to the Table via "
- "autoload_with=<someengine>, "
- "or associate the MetaData with an engine via "
- "metadata.bind=<someengine>").\
- reflecttable(self, include_columns=include_columns)
-
- # initialize all the column, etc. objects. done after reflection to
- # allow user-overrides
- self._init_items(*args)
-
- @property
- def _sorted_constraints(self):
- """Return the set of constraints as a list, sorted by creation order."""
-
- return sorted(self.constraints, key=lambda c:c._creation_order)
-
- def _init_existing(self, *args, **kwargs):
- autoload = kwargs.pop('autoload', False)
- autoload_with = kwargs.pop('autoload_with', None)
- schema = kwargs.pop('schema', None)
- if schema and schema != self.schema:
- raise exc.ArgumentError(
- "Can't change schema of existing table from '%s' to '%s'",
- (self.schema, schema))
-
- include_columns = kwargs.pop('include_columns', None)
- if include_columns:
- for c in self.c:
- if c.name not in include_columns:
- self._columns.remove(c)
-
- for key in ('quote', 'quote_schema'):
- if key in kwargs:
- setattr(self, key, kwargs.pop(key))
-
- if 'info' in kwargs:
- self.info = kwargs.pop('info')
-
- self._extra_kwargs(**kwargs)
- self._init_items(*args)
-
- def _extra_kwargs(self, **kwargs):
- # validate remaining kwargs that they all specify DB prefixes
- if len([k for k in kwargs
- if not re.match(
- r'^(?:%s)_' %
- '|'.join(dialects.__all__), k
- )
- ]):
- raise TypeError(
- "Invalid argument(s) for Table: %r" % kwargs.keys())
- self.kwargs.update(kwargs)
-
- def _init_collections(self):
- pass
-
-
- @util.memoized_property
- def _autoincrement_column(self):
- for col in self.primary_key:
- if col.autoincrement and \
- issubclass(col.type._type_affinity, sqltypes.Integer) and \
- not col.foreign_keys and \
- isinstance(col.default, (type(None), Sequence)) and \
- (col.server_default is None or col.server_default.reflected):
- return col
-
- @property
- def key(self):
- return _get_table_key(self.name, self.schema)
-
- def __repr__(self):
- return "Table(%s)" % ', '.join(
- [repr(self.name)] + [repr(self.metadata)] +
- [repr(x) for x in self.columns] +
- ["%s=%s" % (k, repr(getattr(self, k))) for k in ['schema']])
-
- def __str__(self):
- return _get_table_key(self.description, self.schema)
-
- @property
- def bind(self):
- """Return the connectable associated with this Table."""
-
- return self.metadata and self.metadata.bind or None
-
- def add_is_dependent_on(self, table):
- """Add a 'dependency' for this Table.
-
- This is another Table object which must be created
- first before this one can, or dropped after this one.
-
- Usually, dependencies between tables are determined via
- ForeignKey objects. However, for other situations that
- create dependencies outside of foreign keys (rules, inheriting),
- this method can manually establish such a link.
-
- """
- self._extra_dependencies.add(table)
-
- def append_column(self, column):
- """Append a :class:`~.schema.Column` to this :class:`~.schema.Table`.
-
- The "key" of the newly added :class:`~.schema.Column`, i.e. the
- value of its ``.key`` attribute, will then be available
- in the ``.c`` collection of this :class:`~.schema.Table`, and the
- column definition will be included in any CREATE TABLE, SELECT,
- UPDATE, etc. statements generated from this :class:`~.schema.Table`
- construct.
-
- Note that this does **not** change the definition of the table
- as it exists within any underlying database, assuming that
- table has already been created in the database. Relational
- databases support the addition of columns to existing tables
- using the SQL ALTER command, which would need to be
- emitted for an already-existing table that doesn't contain
- the newly added column.
-
- """
-
- column._set_parent_with_dispatch(self)
-
- def append_constraint(self, constraint):
- """Append a :class:`~.schema.Constraint` to this :class:`~.schema.Table`.
-
- This has the effect of the constraint being included in any
- future CREATE TABLE statement, assuming specific DDL creation
- events have not been associated with the given :class:`~.schema.Constraint`
- object.
-
- Note that this does **not** produce the constraint within the
- relational database automatically, for a table that already exists
- in the database. To add a constraint to an
- existing relational database table, the SQL ALTER command must
- be used. SQLAlchemy also provides the :class:`.AddConstraint` construct
- which can produce this SQL when invoked as an executable clause.
-
- """
-
- constraint._set_parent_with_dispatch(self)
-
- def append_ddl_listener(self, event_name, listener):
- """Append a DDL event listener to this ``Table``.
-
- Deprecated. See :class:`.DDLEvents`.
-
- """
-
- def adapt_listener(target, connection, **kw):
- listener(event_name, target, connection, **kw)
-
- event.listen(self, "" + event_name.replace('-', '_'), adapt_listener)
-
- def _set_parent(self, metadata):
- metadata._add_table(self.name, self.schema, self)
- self.metadata = metadata
-
- def get_children(self, column_collections=True,
- schema_visitor=False, **kw):
- if not schema_visitor:
- return expression.TableClause.get_children(
- self, column_collections=column_collections, **kw)
- else:
- if column_collections:
- return list(self.columns)
- else:
- return []
-
- def exists(self, bind=None):
- """Return True if this table exists."""
-
- if bind is None:
- bind = _bind_or_error(self)
-
- return bind.run_callable(bind.dialect.has_table,
- self.name, schema=self.schema)
-
- def create(self, bind=None, checkfirst=False):
- """Issue a ``CREATE`` statement for this table.
-
- See also ``metadata.create_all()``.
-
- """
-
- if bind is None:
- bind = _bind_or_error(self)
- bind.create(self, checkfirst=checkfirst)
-
- def drop(self, bind=None, checkfirst=False):
- """Issue a ``DROP`` statement for this table.
-
- See also ``metadata.drop_all()``.
-
- """
- if bind is None:
- bind = _bind_or_error(self)
- bind.drop(self, checkfirst=checkfirst)
-
-
- def tometadata(self, metadata, schema=RETAIN_SCHEMA):
- """Return a copy of this :class:`.Table` associated with a different
- :class:`.MetaData`.
-
- E.g.::
-
- # create two metadata
- meta1 = MetaData('sqlite:///querytest.db')
- meta2 = MetaData()
-
- # load 'users' from the sqlite engine
- users_table = Table('users', meta1, autoload=True)
-
- # create the same Table object for the plain metadata
- users_table_2 = users_table.tometadata(meta2)
-
- """
-
- if schema is RETAIN_SCHEMA:
- schema = self.schema
- key = _get_table_key(self.name, schema)
- if key in metadata.tables:
- util.warn("Table '%s' already exists within the given "
- "MetaData - not copying." % self.description)
- return metadata.tables[key]
-
- args = []
- for c in self.columns:
- args.append(c.copy(schema=schema))
- for c in self.constraints:
- args.append(c.copy(schema=schema))
- table = Table(
- self.name, metadata, schema=schema,
- *args, **self.kwargs
- )
- for index in self.indexes:
- # skip indexes that would be generated
- # by the 'index' flag on Column
- if len(index.columns) == 1 and \
- list(index.columns)[0].index:
- continue
- Index(index.name,
- unique=index.unique,
- *[table.c[col] for col in index.columns.keys()],
- **index.kwargs)
- table.dispatch._update(self.dispatch)
- return table
-
-class Column(SchemaItem, expression.ColumnClause):
- """Represents a column in a database table."""
-
- __visit_name__ = 'column'
-
- def __init__(self, *args, **kwargs):
- """
- Construct a new ``Column`` object.
-
- :param name: The name of this column as represented in the database.
- This argument may be the first positional argument, or specified
- via keyword.
-
- Names which contain no upper case characters
- will be treated as case insensitive names, and will not be quoted
- unless they are a reserved word. Names with any number of upper
- case characters will be quoted and sent exactly. Note that this
- behavior applies even for databases which standardize upper
- case names as case insensitive such as Oracle.
-
- The name field may be omitted at construction time and applied
- later, at any time before the Column is associated with a
- :class:`.Table`. This is to support convenient
- usage within the :mod:`~sqlalchemy.ext.declarative` extension.
-
- :param type\_: The column's type, indicated using an instance which
- subclasses :class:`~sqlalchemy.types.TypeEngine`. If no arguments
- are required for the type, the class of the type can be sent
- as well, e.g.::
-
- # use a type with arguments
- Column('data', String(50))
-
- # use no arguments
- Column('level', Integer)
-
- The ``type`` argument may be the second positional argument
- or specified by keyword.
-
- There is partial support for automatic detection of the
- type based on that of a :class:`.ForeignKey` associated
- with this column, if the type is specified as ``None``.
- However, this feature is not fully implemented and
- may not function in all cases.
-
- :param \*args: Additional positional arguments include various
- :class:`.SchemaItem` derived constructs which will be applied
- as options to the column. These include instances of
- :class:`.Constraint`, :class:`.ForeignKey`, :class:`.ColumnDefault`,
- and :class:`.Sequence`. In some cases an equivalent keyword
- argument is available such as ``server_default``, ``default``
- and ``unique``.
-
- :param autoincrement: This flag may be set to ``False`` to
- indicate an integer primary key column that should not be
- considered to be the "autoincrement" column, that is
- the integer primary key column which generates values
- implicitly upon INSERT and whose value is usually returned
- via the DBAPI cursor.lastrowid attribute. It defaults
- to ``True`` to satisfy the common use case of a table
- with a single integer primary key column. If the table
- has a composite primary key consisting of more than one
- integer column, set this flag to True only on the
- column that should be considered "autoincrement".
-
- The setting *only* has an effect for columns which are:
-
- * Integer derived (i.e. INT, SMALLINT, BIGINT).
-
- * Part of the primary key
-
- * Are not referenced by any foreign keys
-
- * have no server side or client side defaults (with the exception
- of Postgresql SERIAL).
-
- The setting has these two effects on columns that meet the
- above criteria:
-
- * DDL issued for the column will include database-specific
- keywords intended to signify this column as an
- "autoincrement" column, such as AUTO INCREMENT on MySQL,
- SERIAL on Postgresql, and IDENTITY on MS-SQL. It does
- *not* issue AUTOINCREMENT for SQLite since this is a
- special SQLite flag that is not required for autoincrementing
- behavior. See the SQLite dialect documentation for
- information on SQLite's AUTOINCREMENT.
-
- * The column will be considered to be available as
- cursor.lastrowid or equivalent, for those dialects which
- "post fetch" newly inserted identifiers after a row has
- been inserted (SQLite, MySQL, MS-SQL). It does not have
- any effect in this regard for databases that use sequences
- to generate primary key identifiers (i.e. Firebird, Postgresql,
- Oracle).
-
- :param default: A scalar, Python callable, or
- :class:`~sqlalchemy.sql.expression.ClauseElement` representing the
- *default value* for this column, which will be invoked upon insert
- if this column is otherwise not specified in the VALUES clause of
- the insert. This is a shortcut to using :class:`.ColumnDefault` as
- a positional argument.
-
- Contrast this argument to ``server_default`` which creates a
- default generator on the database side.
-
- :param doc: optional String that can be used by the ORM or similar
- to document attributes. This attribute does not render SQL
- comments (a future attribute 'comment' will achieve that).
-
- :param key: An optional string identifier which will identify this
- ``Column`` object on the :class:`.Table`. When a key is provided,
- this is the only identifier referencing the ``Column`` within the
- application, including ORM attribute mapping; the ``name`` field
- is used only when rendering SQL.
-
- :param index: When ``True``, indicates that the column is indexed.
- This is a shortcut for using a :class:`.Index` construct on the
- table. To specify indexes with explicit names or indexes that
- contain multiple columns, use the :class:`.Index` construct
- instead.
-
- :param info: A dictionary which defaults to ``{}``. A space to store
- application specific data. This must be a dictionary.
-
- :param nullable: If set to the default of ``True``, indicates the
- column will be rendered as allowing NULL, else it's rendered as
- NOT NULL. This parameter is only used when issuing CREATE TABLE
- statements.
-
- :param onupdate: A scalar, Python callable, or
- :class:`~sqlalchemy.sql.expression.ClauseElement` representing a
- default value to be applied to the column within UPDATE
- statements, which wil be invoked upon update if this column is not
- present in the SET clause of the update. This is a shortcut to
- using :class:`.ColumnDefault` as a positional argument with
- ``for_update=True``.
-
- :param primary_key: If ``True``, marks this column as a primary key
- column. Multiple columns can have this flag set to specify
- composite primary keys. As an alternative, the primary key of a
- :class:`.Table` can be specified via an explicit
- :class:`.PrimaryKeyConstraint` object.
-
- :param server_default: A :class:`.FetchedValue` instance, str, Unicode
- or :func:`~sqlalchemy.sql.expression.text` construct representing
- the DDL DEFAULT value for the column.
-
- String types will be emitted as-is, surrounded by single quotes::
-
- Column('x', Text, server_default="val")
-
- x TEXT DEFAULT 'val'
-
- A :func:`~sqlalchemy.sql.expression.text` expression will be
- rendered as-is, without quotes::
-
- Column('y', DateTime, server_default=text('NOW()'))0
-
- y DATETIME DEFAULT NOW()
-
- Strings and text() will be converted into a :class:`.DefaultClause`
- object upon initialization.
-
- Use :class:`.FetchedValue` to indicate that an already-existing
- column will generate a default value on the database side which
- will be available to SQLAlchemy for post-fetch after inserts. This
- construct does not specify any DDL and the implementation is left
- to the database, such as via a trigger.
-
- :param server_onupdate: A :class:`.FetchedValue` instance
- representing a database-side default generation function. This
- indicates to SQLAlchemy that a newly generated value will be
- available after updates. This construct does not specify any DDL
- and the implementation is left to the database, such as via a
- trigger.
-
- :param quote: Force quoting of this column's name on or off,
- corresponding to ``True`` or ``False``. When left at its default
- of ``None``, the column identifier will be quoted according to
- whether the name is case sensitive (identifiers with at least one
- upper case character are treated as case sensitive), or if it's a
- reserved word. This flag is only needed to force quoting of a
- reserved word which is not known by the SQLAlchemy dialect.
-
- :param unique: When ``True``, indicates that this column contains a
- unique constraint, or if ``index`` is ``True`` as well, indicates
- that the :class:`.Index` should be created with the unique flag.
- To specify multiple columns in the constraint/index or to specify
- an explicit name, use the :class:`.UniqueConstraint` or
- :class:`.Index` constructs explicitly.
-
- """
-
- name = kwargs.pop('name', None)
- type_ = kwargs.pop('type_', None)
- args = list(args)
- if args:
- if isinstance(args[0], basestring):
- if name is not None:
- raise exc.ArgumentError(
- "May not pass name positionally and as a keyword.")
- name = args.pop(0)
- if args:
- coltype = args[0]
-
- if (isinstance(coltype, sqltypes.TypeEngine) or
- (isinstance(coltype, type) and
- issubclass(coltype, sqltypes.TypeEngine))):
- if type_ is not None:
- raise exc.ArgumentError(
- "May not pass type_ positionally and as a keyword.")
- type_ = args.pop(0)
-
- no_type = type_ is None
-
- super(Column, self).__init__(name, None, type_)
- self.key = kwargs.pop('key', name)
- self.primary_key = kwargs.pop('primary_key', False)
- self.nullable = kwargs.pop('nullable', not self.primary_key)
- self.default = kwargs.pop('default', None)
- self.server_default = kwargs.pop('server_default', None)
- self.server_onupdate = kwargs.pop('server_onupdate', None)
- self.index = kwargs.pop('index', None)
- self.unique = kwargs.pop('unique', None)
- self.quote = kwargs.pop('quote', None)
- self.doc = kwargs.pop('doc', None)
- self.onupdate = kwargs.pop('onupdate', None)
- self.autoincrement = kwargs.pop('autoincrement', True)
- self.constraints = set()
- self.foreign_keys = set()
-
- # check if this Column is proxying another column
- if '_proxies' in kwargs:
- self.proxies = kwargs.pop('_proxies')
- # otherwise, add DDL-related events
- elif isinstance(self.type, sqltypes.SchemaType):
- self.type._set_parent_with_dispatch(self)
-
- if self.default is not None:
- if isinstance(self.default, (ColumnDefault, Sequence)):
- args.append(self.default)
- else:
- if getattr(self.type, '_warn_on_bytestring', False):
- # Py3K
- #if isinstance(self.default, bytes):
- # Py2K
- if isinstance(self.default, str):
- # end Py2K
- util.warn("Unicode column received non-unicode "
- "default value.")
- args.append(ColumnDefault(self.default))
-
- if self.server_default is not None:
- if isinstance(self.server_default, FetchedValue):
- args.append(self.server_default)
- else:
- args.append(DefaultClause(self.server_default))
-
- if self.onupdate is not None:
- if isinstance(self.onupdate, (ColumnDefault, Sequence)):
- args.append(self.onupdate)
- else:
- args.append(ColumnDefault(self.onupdate, for_update=True))
-
- if self.server_onupdate is not None:
- if isinstance(self.server_onupdate, FetchedValue):
- args.append(self.server_onupdate)
- else:
- args.append(DefaultClause(self.server_onupdate,
- for_update=True))
- self._init_items(*args)
-
- if not self.foreign_keys and no_type:
- raise exc.ArgumentError("'type' is required on Column objects "
- "which have no foreign keys.")
- util.set_creation_order(self)
-
- if 'info' in kwargs:
- self.info = kwargs.pop('info')
-
- if kwargs:
- raise exc.ArgumentError(
- "Unknown arguments passed to Column: " + repr(kwargs.keys()))
-
- def __str__(self):
- if self.name is None:
- return "(no name)"
- elif self.table is not None:
- if self.table.named_with_column:
- return (self.table.description + "." + self.description)
- else:
- return self.description
- else:
- return self.description
-
- def references(self, column):
- """Return True if this Column references the given column via foreign
- key."""
-
- for fk in self.foreign_keys:
- if fk.column.proxy_set.intersection(column.proxy_set):
- return True
- else:
- return False
-
- def append_foreign_key(self, fk):
- fk._set_parent_with_dispatch(self)
-
- def __repr__(self):
- kwarg = []
- if self.key != self.name:
- kwarg.append('key')
- if self.primary_key:
- kwarg.append('primary_key')
- if not self.nullable:
- kwarg.append('nullable')
- if self.onupdate:
- kwarg.append('onupdate')
- if self.default:
- kwarg.append('default')
- if self.server_default:
- kwarg.append('server_default')
- return "Column(%s)" % ', '.join(
- [repr(self.name)] + [repr(self.type)] +
- [repr(x) for x in self.foreign_keys if x is not None] +
- [repr(x) for x in self.constraints] +
- [(self.table is not None and "table=<%s>" %
- self.table.description or "")] +
- ["%s=%s" % (k, repr(getattr(self, k))) for k in kwarg])
-
- def _set_parent(self, table):
- if not self.name:
- raise exc.ArgumentError(
- "Column must be constructed with a non-blank name or "
- "assign a non-blank .name before adding to a Table.")
- if self.key is None:
- self.key = self.name
-
- if getattr(self, 'table', None) is not None:
- raise exc.ArgumentError(
- "Column object already assigned to Table '%s'" %
- self.table.description)
-
- if self.key in table._columns:
- col = table._columns.get(self.key)
- for fk in list(col.foreign_keys):
- col.foreign_keys.remove(fk)
- table.foreign_keys.remove(fk)
- if fk.constraint in table.constraints:
- # this might have been removed
- # already, if it's a composite constraint
- # and more than one col being replaced
- table.constraints.remove(fk.constraint)
-
- table._columns.replace(self)
-
- if self.primary_key:
- table.primary_key._replace(self)
- elif self.key in table.primary_key:
- raise exc.ArgumentError(
- "Trying to redefine primary-key column '%s' as a "
- "non-primary-key column on table '%s'" % (
- self.key, table.fullname))
- self.table = table
-
- if self.index:
- if isinstance(self.index, basestring):
- raise exc.ArgumentError(
- "The 'index' keyword argument on Column is boolean only. "
- "To create indexes with a specific name, create an "
- "explicit Index object external to the Table.")
- Index(expression._generated_label('ix_%s' % self._label), self, unique=self.unique)
- elif self.unique:
- if isinstance(self.unique, basestring):
- raise exc.ArgumentError(
- "The 'unique' keyword argument on Column is boolean "
- "only. To create unique constraints or indexes with a "
- "specific name, append an explicit UniqueConstraint to "
- "the Table's list of elements, or create an explicit "
- "Index object external to the Table.")
- table.append_constraint(UniqueConstraint(self.key))
-
- def _on_table_attach(self, fn):
- if self.table is not None:
- fn(self, self.table)
- event.listen(self, 'after_parent_attach', fn)
-
- def copy(self, **kw):
- """Create a copy of this ``Column``, unitialized.
-
- This is used in ``Table.tometadata``.
-
- """
-
- # Constraint objects plus non-constraint-bound ForeignKey objects
- args = \
- [c.copy(**kw) for c in self.constraints] + \
- [c.copy(**kw) for c in self.foreign_keys if not c.constraint]
-
- c = Column(
- name=self.name,
- type_=self.type,
- key = self.key,
- primary_key = self.primary_key,
- nullable = self.nullable,
- unique = self.unique,
- quote=self.quote,
- index=self.index,
- autoincrement=self.autoincrement,
- default=self.default,
- server_default=self.server_default,
- onupdate=self.onupdate,
- server_onupdate=self.server_onupdate,
- info=self.info,
- doc=self.doc,
- *args
- )
- c.dispatch._update(self.dispatch)
- return c
-
- def _make_proxy(self, selectable, name=None):
- """Create a *proxy* for this column.
-
- This is a copy of this ``Column`` referenced by a different parent
- (such as an alias or select statement). The column should
- be used only in select scenarios, as its full DDL/default
- information is not transferred.
-
- """
- fk = [ForeignKey(f.column) for f in self.foreign_keys]
- if name is None and self.name is None:
- raise exc.InvalidRequestError("Cannot initialize a sub-selectable"
- " with this Column object until it's 'name' has "
- "been assigned.")
- try:
- c = self._constructor(
- name or self.name,
- self.type,
- key = name or self.key,
- primary_key = self.primary_key,
- nullable = self.nullable,
- quote=self.quote, _proxies=[self], *fk)
- except TypeError, e:
- # Py3K
- #raise TypeError(
- # "Could not create a copy of this %r object. "
- # "Ensure the class includes a _constructor() "
- # "attribute or method which accepts the "
- # "standard Column constructor arguments, or "
- # "references the Column class itself." % self.__class__) from e
- # Py2K
- raise TypeError(
- "Could not create a copy of this %r object. "
- "Ensure the class includes a _constructor() "
- "attribute or method which accepts the "
- "standard Column constructor arguments, or "
- "references the Column class itself. "
- "Original error: %s" % (self.__class__, e))
- # end Py2K
-
- c.table = selectable
- selectable._columns.add(c)
- if self.primary_key:
- selectable.primary_key.add(c)
- c.dispatch.after_parent_attach(c, selectable)
- return c
-
- def get_children(self, schema_visitor=False, **kwargs):
- if schema_visitor:
- return [x for x in (self.default, self.onupdate)
- if x is not None] + \
- list(self.foreign_keys) + list(self.constraints)
- else:
- return expression.ColumnClause.get_children(self, **kwargs)
-
-
-class ForeignKey(SchemaItem):
- """Defines a dependency between two columns.
-
- ``ForeignKey`` is specified as an argument to a :class:`.Column` object,
- e.g.::
-
- t = Table("remote_table", metadata,
- Column("remote_id", ForeignKey("main_table.id"))
- )
-
- Note that ``ForeignKey`` is only a marker object that defines
- a dependency between two columns. The actual constraint
- is in all cases represented by the :class:`.ForeignKeyConstraint`
- object. This object will be generated automatically when
- a ``ForeignKey`` is associated with a :class:`.Column` which
- in turn is associated with a :class:`.Table`. Conversely,
- when :class:`.ForeignKeyConstraint` is applied to a :class:`.Table`,
- ``ForeignKey`` markers are automatically generated to be
- present on each associated :class:`.Column`, which are also
- associated with the constraint object.
-
- Note that you cannot define a "composite" foreign key constraint,
- that is a constraint between a grouping of multiple parent/child
- columns, using ``ForeignKey`` objects. To define this grouping,
- the :class:`.ForeignKeyConstraint` object must be used, and applied
- to the :class:`.Table`. The associated ``ForeignKey`` objects
- are created automatically.
-
- The ``ForeignKey`` objects associated with an individual
- :class:`.Column` object are available in the `foreign_keys` collection
- of that column.
-
- Further examples of foreign key configuration are in
- :ref:`metadata_foreignkeys`.
-
- """
-
- __visit_name__ = 'foreign_key'
-
- def __init__(self, column, _constraint=None, use_alter=False, name=None,
- onupdate=None, ondelete=None, deferrable=None,
- initially=None, link_to_name=False):
- """
- Construct a column-level FOREIGN KEY.
-
- The :class:`.ForeignKey` object when constructed generates a
- :class:`.ForeignKeyConstraint` which is associated with the parent
- :class:`.Table` object's collection of constraints.
-
- :param column: A single target column for the key relationship. A
- :class:`.Column` object or a column name as a string:
- ``tablename.columnkey`` or ``schema.tablename.columnkey``.
- ``columnkey`` is the ``key`` which has been assigned to the column
- (defaults to the column name itself), unless ``link_to_name`` is
- ``True`` in which case the rendered name of the column is used.
-
- :param name: Optional string. An in-database name for the key if
- `constraint` is not provided.
-
- :param onupdate: Optional string. If set, emit ON UPDATE <value> when
- issuing DDL for this constraint. Typical values include CASCADE,
- DELETE and RESTRICT.
-
- :param ondelete: Optional string. If set, emit ON DELETE <value> when
- issuing DDL for this constraint. Typical values include CASCADE,
- DELETE and RESTRICT.
-
- :param deferrable: Optional bool. If set, emit DEFERRABLE or NOT
- DEFERRABLE when issuing DDL for this constraint.
-
- :param initially: Optional string. If set, emit INITIALLY <value> when
- issuing DDL for this constraint.
-
- :param link_to_name: if True, the string name given in ``column`` is
- the rendered name of the referenced column, not its locally
- assigned ``key``.
-
- :param use_alter: passed to the underlying
- :class:`.ForeignKeyConstraint` to indicate the constraint should be
- generated/dropped externally from the CREATE TABLE/ DROP TABLE
- statement. See that classes' constructor for details.
-
- """
-
- self._colspec = column
-
- # the linked ForeignKeyConstraint.
- # ForeignKey will create this when parent Column
- # is attached to a Table, *or* ForeignKeyConstraint
- # object passes itself in when creating ForeignKey
- # markers.
- self.constraint = _constraint
-
-
- self.use_alter = use_alter
- self.name = name
- self.onupdate = onupdate
- self.ondelete = ondelete
- self.deferrable = deferrable
- self.initially = initially
- self.link_to_name = link_to_name
-
- def __repr__(self):
- return "ForeignKey(%r)" % self._get_colspec()
-
- def copy(self, schema=None):
- """Produce a copy of this :class:`.ForeignKey` object.
-
- The new :class:`.ForeignKey` will not be bound
- to any :class:`.Column`.
-
- This method is usually used by the internal
- copy procedures of :class:`.Column`, :class:`.Table`,
- and :class:`.MetaData`.
-
- :param schema: The returned :class:`.ForeignKey` will
- reference the original table and column name, qualified
- by the given string schema name.
-
- """
-
- fk = ForeignKey(
- self._get_colspec(schema=schema),
- use_alter=self.use_alter,
- name=self.name,
- onupdate=self.onupdate,
- ondelete=self.ondelete,
- deferrable=self.deferrable,
- initially=self.initially,
- link_to_name=self.link_to_name
- )
- fk.dispatch._update(self.dispatch)
- return fk
-
- def _get_colspec(self, schema=None):
- """Return a string based 'column specification' for this :class:`.ForeignKey`.
-
- This is usually the equivalent of the string-based "tablename.colname"
- argument first passed to the object's constructor.
-
- """
- if schema:
- return schema + "." + self.column.table.name + \
- "." + self.column.key
- elif isinstance(self._colspec, basestring):
- return self._colspec
- elif hasattr(self._colspec, '__clause_element__'):
- _column = self._colspec.__clause_element__()
- else:
- _column = self._colspec
-
- return "%s.%s" % (_column.table.fullname, _column.key)
-
- target_fullname = property(_get_colspec)
-
- def references(self, table):
- """Return True if the given :class:`.Table` is referenced by this :class:`.ForeignKey`."""
-
- return table.corresponding_column(self.column) is not None
-
- def get_referent(self, table):
- """Return the :class:`.Column` in the given :class:`.Table`
- referenced by this :class:`.ForeignKey`.
-
- Returns None if this :class:`.ForeignKey` does not reference the given
- :class:`.Table`.
-
- """
-
- return table.corresponding_column(self.column)
-
- @util.memoized_property
- def column(self):
- """Return the target :class:`.Column` referenced by this :class:`.ForeignKey`.
-
- If this :class:`.ForeignKey` was created using a
- string-based target column specification, this
- attribute will on first access initiate a resolution
- process to locate the referenced remote
- :class:`.Column`. The resolution process traverses
- to the parent :class:`.Column`, :class:`.Table`, and
- :class:`.MetaData` to proceed - if any of these aren't
- yet present, an error is raised.
-
- """
- # ForeignKey inits its remote column as late as possible, so tables
- # can be defined without dependencies
- if isinstance(self._colspec, basestring):
- # locate the parent table this foreign key is attached to. we
- # use the "original" column which our parent column represents
- # (its a list of columns/other ColumnElements if the parent
- # table is a UNION)
- for c in self.parent.base_columns:
- if isinstance(c, Column):
- parenttable = c.table
- break
- else:
- raise exc.ArgumentError(
- "Parent column '%s' does not descend from a "
- "table-attached Column" % str(self.parent))
-
- m = self._colspec.split('.')
-
- if m is None:
- raise exc.ArgumentError(
- "Invalid foreign key column specification: %s" %
- self._colspec)
-
- # A FK between column 'bar' and table 'foo' can be
- # specified as 'foo', 'foo.bar', 'dbo.foo.bar',
- # 'otherdb.dbo.foo.bar'. Once we have the column name and
- # the table name, treat everything else as the schema
- # name. Some databases (e.g. Sybase) support
- # inter-database foreign keys. See tickets#1341 and --
- # indirectly related -- Ticket #594. This assumes that '.'
- # will never appear *within* any component of the FK.
-
- (schema, tname, colname) = (None, None, None)
- if (len(m) == 1):
- tname = m.pop()
- else:
- colname = m.pop()
- tname = m.pop()
-
- if (len(m) > 0):
- schema = '.'.join(m)
-
- if _get_table_key(tname, schema) not in parenttable.metadata:
- raise exc.NoReferencedTableError(
- "Foreign key associated with column '%s' could not find "
- "table '%s' with which to generate a "
- "foreign key to target column '%s'" % (self.parent, tname, colname),
- tname)
- table = Table(tname, parenttable.metadata,
- mustexist=True, schema=schema)
-
- _column = None
- if colname is None:
- # colname is None in the case that ForeignKey argument
- # was specified as table name only, in which case we
- # match the column name to the same column on the
- # parent.
- key = self.parent
- _column = table.c.get(self.parent.key, None)
- elif self.link_to_name:
- key = colname
- for c in table.c:
- if c.name == colname:
- _column = c
- else:
- key = colname
- _column = table.c.get(colname, None)
-
- if _column is None:
- raise exc.NoReferencedColumnError(
- "Could not create ForeignKey '%s' on table '%s': "
- "table '%s' has no column named '%s'" % (
- self._colspec, parenttable.name, table.name, key),
- table.name, key)
-
- elif hasattr(self._colspec, '__clause_element__'):
- _column = self._colspec.__clause_element__()
- else:
- _column = self._colspec
-
- # propagate TypeEngine to parent if it didn't have one
- if isinstance(self.parent.type, sqltypes.NullType):
- self.parent.type = _column.type
- return _column
-
- def _set_parent(self, column):
- if hasattr(self, 'parent'):
- if self.parent is column:
- return
- raise exc.InvalidRequestError(
- "This ForeignKey already has a parent !")
- self.parent = column
- self.parent.foreign_keys.add(self)
- self.parent._on_table_attach(self._set_table)
-
- def _set_table(self, column, table):
- # standalone ForeignKey - create ForeignKeyConstraint
- # on the hosting Table when attached to the Table.
- if self.constraint is None and isinstance(table, Table):
- self.constraint = ForeignKeyConstraint(
- [], [], use_alter=self.use_alter, name=self.name,
- onupdate=self.onupdate, ondelete=self.ondelete,
- deferrable=self.deferrable, initially=self.initially,
- )
- self.constraint._elements[self.parent] = self
- self.constraint._set_parent_with_dispatch(table)
- table.foreign_keys.add(self)
-
-class _NotAColumnExpr(object):
- def _not_a_column_expr(self):
- raise exc.InvalidRequestError(
- "This %s cannot be used directly "
- "as a column expression." % self.__class__.__name__)
-
- __clause_element__ = self_group = lambda self: self._not_a_column_expr()
- _from_objects = property(lambda self: self._not_a_column_expr())
-
-class DefaultGenerator(_NotAColumnExpr, SchemaItem):
- """Base class for column *default* values."""
-
- __visit_name__ = 'default_generator'
-
- is_sequence = False
- is_server_default = False
- column = None
-
- def __init__(self, for_update=False):
- self.for_update = for_update
-
- def _set_parent(self, column):
- self.column = column
- if self.for_update:
- self.column.onupdate = self
- else:
- self.column.default = self
-
- def execute(self, bind=None, **kwargs):
- if bind is None:
- bind = _bind_or_error(self)
- return bind._execute_default(self, **kwargs)
-
- @property
- def bind(self):
- """Return the connectable associated with this default."""
- if getattr(self, 'column', None) is not None:
- return self.column.table.bind
- else:
- return None
-
- def __repr__(self):
- return "DefaultGenerator()"
-
-
-class ColumnDefault(DefaultGenerator):
- """A plain default value on a column.
-
- This could correspond to a constant, a callable function,
- or a SQL clause.
-
- :class:`.ColumnDefault` is generated automatically
- whenever the ``default``, ``onupdate`` arguments of
- :class:`.Column` are used. A :class:`.ColumnDefault`
- can be passed positionally as well.
-
- For example, the following::
-
- Column('foo', Integer, default=50)
-
- Is equivalent to::
-
- Column('foo', Integer, ColumnDefault(50))
-
-
- """
-
- def __init__(self, arg, **kwargs):
- super(ColumnDefault, self).__init__(**kwargs)
- if isinstance(arg, FetchedValue):
- raise exc.ArgumentError(
- "ColumnDefault may not be a server-side default type.")
- if util.callable(arg):
- arg = self._maybe_wrap_callable(arg)
- self.arg = arg
-
- @util.memoized_property
- def is_callable(self):
- return util.callable(self.arg)
-
- @util.memoized_property
- def is_clause_element(self):
- return isinstance(self.arg, expression.ClauseElement)
-
- @util.memoized_property
- def is_scalar(self):
- return not self.is_callable and \
- not self.is_clause_element and \
- not self.is_sequence
-
- def _maybe_wrap_callable(self, fn):
- """Backward compat: Wrap callables that don't accept a context."""
-
- if inspect.isfunction(fn):
- inspectable = fn
- elif inspect.isclass(fn):
- inspectable = fn.__init__
- elif hasattr(fn, '__call__'):
- inspectable = fn.__call__
- else:
- # probably not inspectable, try anyways.
- inspectable = fn
- try:
- argspec = inspect.getargspec(inspectable)
- except TypeError:
- return lambda ctx: fn()
-
- positionals = len(argspec[0])
-
- # Py3K compat - no unbound methods
- if inspect.ismethod(inspectable) or inspect.isclass(fn):
- positionals -= 1
-
- if positionals == 0:
- return lambda ctx: fn()
-
- defaulted = argspec[3] is not None and len(argspec[3]) or 0
- if positionals - defaulted > 1:
- raise exc.ArgumentError(
- "ColumnDefault Python function takes zero or one "
- "positional arguments")
- return fn
-
- def _visit_name(self):
- if self.for_update:
- return "column_onupdate"
- else:
- return "column_default"
- __visit_name__ = property(_visit_name)
-
- def __repr__(self):
- return "ColumnDefault(%r)" % self.arg
-
-class Sequence(DefaultGenerator):
- """Represents a named database sequence.
-
- The :class:`.Sequence` object represents the name and configurational
- parameters of a database sequence. It also represents
- a construct that can be "executed" by a SQLAlchemy :class:`.Engine`
- or :class:`.Connection`, rendering the appropriate "next value" function
- for the target database and returning a result.
-
- The :class:`.Sequence` is typically associated with a primary key column::
-
- some_table = Table('some_table', metadata,
- Column('id', Integer, Sequence('some_table_seq'), primary_key=True)
- )
-
- When CREATE TABLE is emitted for the above :class:`.Table`, if the
- target platform supports sequences, a CREATE SEQUENCE statement will
- be emitted as well. For platforms that don't support sequences,
- the :class:`.Sequence` construct is ignored.
-
- See also: :class:`.CreateSequence` :class:`.DropSequence`
-
- """
-
- __visit_name__ = 'sequence'
-
- is_sequence = True
-
- def __init__(self, name, start=None, increment=None, schema=None,
- optional=False, quote=None, metadata=None,
- for_update=False):
- """Construct a :class:`.Sequence` object.
-
- :param name: The name of the sequence.
- :param start: the starting index of the sequence. This value is
- used when the CREATE SEQUENCE command is emitted to the database
- as the value of the "START WITH" clause. If ``None``, the
- clause is omitted, which on most platforms indicates a starting
- value of 1.
- :param increment: the increment value of the sequence. This
- value is used when the CREATE SEQUENCE command is emitted to
- the database as the value of the "INCREMENT BY" clause. If ``None``,
- the clause is omitted, which on most platforms indicates an
- increment of 1.
- :param schema: Optional schema name for the sequence, if located
- in a schema other than the default.
- :param optional: boolean value, when ``True``, indicates that this
- :class:`.Sequence` object only needs to be explicitly generated
- on backends that don't provide another way to generate primary
- key identifiers. Currently, it essentially means, "don't create
- this sequence on the Postgresql backend, where the SERIAL keyword
- creates a sequence for us automatically".
- :param quote: boolean value, when ``True`` or ``False``, explicitly
- forces quoting of the schema name on or off. When left at its
- default of ``None``, normal quoting rules based on casing and reserved
- words take place.
- :param metadata: optional :class:`.MetaData` object which will be
- associated with this :class:`.Sequence`. A :class:`.Sequence`
- that is associated with a :class:`.MetaData` gains access to the
- ``bind`` of that :class:`.MetaData`, meaning the :meth:`.Sequence.create`
- and :meth:`.Sequence.drop` methods will make usage of that engine
- automatically. Additionally, the appropriate CREATE SEQUENCE/
- DROP SEQUENCE DDL commands will be emitted corresponding to this
- :class:`.Sequence` when :meth:`.MetaData.create_all` and
- :meth:`.MetaData.drop_all` are invoked (new in 0.7).
-
- Note that when a :class:`.Sequence` is applied to a :class:`.Column`,
- the :class:`.Sequence` is automatically associated with the
- :class:`.MetaData` object of that column's parent :class:`.Table`,
- when that association is made. The :class:`.Sequence` will then
- be subject to automatic CREATE SEQUENCE/DROP SEQUENCE corresponding
- to when the :class:`.Table` object itself is created or dropped,
- rather than that of the :class:`.MetaData` object overall.
- :param for_update: Indicates this :class:`.Sequence`, when associated
- with a :class:`.Column`, should be invoked for UPDATE statements
- on that column's table, rather than for INSERT statements, when
- no value is otherwise present for that column in the statement.
-
- """
- super(Sequence, self).__init__(for_update=for_update)
- self.name = name
- self.start = start
- self.increment = increment
- self.optional = optional
- self.quote = quote
- self.schema = schema
- self.metadata = metadata
- self._key = _get_table_key(name, schema)
- if metadata:
- self._set_metadata(metadata)
-
- @util.memoized_property
- def is_callable(self):
- return False
-
- @util.memoized_property
- def is_clause_element(self):
- return False
-
- def next_value(self):
- """Return a :class:`.next_value` function element
- which will render the appropriate increment function
- for this :class:`.Sequence` within any SQL expression.
-
- """
- return expression.func.next_value(self, bind=self.bind)
-
- def __repr__(self):
- return "Sequence(%s)" % ', '.join(
- [repr(self.name)] +
- ["%s=%s" % (k, repr(getattr(self, k)))
- for k in ['start', 'increment', 'optional']])
-
- def _set_parent(self, column):
- super(Sequence, self)._set_parent(column)
- column._on_table_attach(self._set_table)
-
- def _set_table(self, column, table):
- self._set_metadata(table.metadata)
-
- def _set_metadata(self, metadata):
- self.metadata = metadata
- self.metadata._sequences[self._key] = self
-
- @property
- def bind(self):
- if self.metadata:
- return self.metadata.bind
- else:
- return None
-
- def create(self, bind=None, checkfirst=True):
- """Creates this sequence in the database."""
-
- if bind is None:
- bind = _bind_or_error(self)
- bind.create(self, checkfirst=checkfirst)
-
- def drop(self, bind=None, checkfirst=True):
- """Drops this sequence from the database."""
-
- if bind is None:
- bind = _bind_or_error(self)
- bind.drop(self, checkfirst=checkfirst)
-
- def _not_a_column_expr(self):
- raise exc.InvalidRequestError(
- "This %s cannot be used directly "
- "as a column expression. Use func.next_value(sequence) "
- "to produce a 'next value' function that's usable "
- "as a column element."
- % self.__class__.__name__)
-
-
-class FetchedValue(_NotAColumnExpr, events.SchemaEventTarget):
- """A marker for a transparent database-side default.
-
- Use :class:`.FetchedValue` when the database is configured
- to provide some automatic default for a column.
-
- E.g.::
-
- Column('foo', Integer, FetchedValue())
-
- Would indicate that some trigger or default generator
- will create a new value for the ``foo`` column during an
- INSERT.
-
- """
- is_server_default = True
- reflected = False
- has_argument = False
-
- def __init__(self, for_update=False):
- self.for_update = for_update
-
- def _set_parent(self, column):
- self.column = column
- if self.for_update:
- self.column.server_onupdate = self
- else:
- self.column.server_default = self
-
- def __repr__(self):
- return 'FetchedValue(for_update=%r)' % self.for_update
-
-
-class DefaultClause(FetchedValue):
- """A DDL-specified DEFAULT column value.
-
- :class:`.DefaultClause` is a :class:`.FetchedValue`
- that also generates a "DEFAULT" clause when
- "CREATE TABLE" is emitted.
-
- :class:`.DefaultClause` is generated automatically
- whenever the ``server_default``, ``server_onupdate`` arguments of
- :class:`.Column` are used. A :class:`.DefaultClause`
- can be passed positionally as well.
-
- For example, the following::
-
- Column('foo', Integer, server_default="50")
-
- Is equivalent to::
-
- Column('foo', Integer, DefaultClause("50"))
-
- """
-
- has_argument = True
-
- def __init__(self, arg, for_update=False, _reflected=False):
- util.assert_arg_type(arg, (basestring,
- expression.ClauseElement,
- expression._TextClause), 'arg')
- super(DefaultClause, self).__init__(for_update)
- self.arg = arg
- self.reflected = _reflected
-
- def __repr__(self):
- return "DefaultClause(%r, for_update=%r)" % \
- (self.arg, self.for_update)
-
-class PassiveDefault(DefaultClause):
- """A DDL-specified DEFAULT column value.
-
- .. deprecated:: 0.6 :class:`.PassiveDefault` is deprecated.
- Use :class:`.DefaultClause`.
- """
- @util.deprecated("0.6",
- ":class:`.PassiveDefault` is deprecated. "
- "Use :class:`.DefaultClause`.",
- False)
- def __init__(self, *arg, **kw):
- DefaultClause.__init__(self, *arg, **kw)
-
-class Constraint(SchemaItem):
- """A table-level SQL constraint."""
-
- __visit_name__ = 'constraint'
-
- def __init__(self, name=None, deferrable=None, initially=None,
- _create_rule=None):
- """Create a SQL constraint.
-
- :param name:
- Optional, the in-database name of this ``Constraint``.
-
- :param deferrable:
- Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when
- issuing DDL for this constraint.
-
- :param initially:
- Optional string. If set, emit INITIALLY <value> when issuing DDL
- for this constraint.
-
- :param _create_rule:
- a callable which is passed the DDLCompiler object during
- compilation. Returns True or False to signal inline generation of
- this Constraint.
-
- The AddConstraint and DropConstraint DDL constructs provide
- DDLElement's more comprehensive "conditional DDL" approach that is
- passed a database connection when DDL is being issued. _create_rule
- is instead called during any CREATE TABLE compilation, where there
- may not be any transaction/connection in progress. However, it
- allows conditional compilation of the constraint even for backends
- which do not support addition of constraints through ALTER TABLE,
- which currently includes SQLite.
-
- _create_rule is used by some types to create constraints.
- Currently, its call signature is subject to change at any time.
-
- """
-
- self.name = name
- self.deferrable = deferrable
- self.initially = initially
- self._create_rule = _create_rule
- util.set_creation_order(self)
-
- @property
- def table(self):
- try:
- if isinstance(self.parent, Table):
- return self.parent
- except AttributeError:
- pass
- raise exc.InvalidRequestError(
- "This constraint is not bound to a table. Did you "
- "mean to call table.add_constraint(constraint) ?")
-
- def _set_parent(self, parent):
- self.parent = parent
- parent.constraints.add(self)
-
- def copy(self, **kw):
- raise NotImplementedError()
-
-class ColumnCollectionMixin(object):
- def __init__(self, *columns):
- self.columns = expression.ColumnCollection()
- self._pending_colargs = [_to_schema_column_or_string(c)
- for c in columns]
- if self._pending_colargs and \
- isinstance(self._pending_colargs[0], Column) and \
- self._pending_colargs[0].table is not None:
- self._set_parent_with_dispatch(self._pending_colargs[0].table)
-
- def _set_parent(self, table):
- for col in self._pending_colargs:
- if isinstance(col, basestring):
- col = table.c[col]
- self.columns.add(col)
-
-class ColumnCollectionConstraint(ColumnCollectionMixin, Constraint):
- """A constraint that proxies a ColumnCollection."""
-
- def __init__(self, *columns, **kw):
- """
- :param \*columns:
- A sequence of column names or Column objects.
-
- :param name:
- Optional, the in-database name of this constraint.
-
- :param deferrable:
- Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when
- issuing DDL for this constraint.
-
- :param initially:
- Optional string. If set, emit INITIALLY <value> when issuing DDL
- for this constraint.
-
- """
- ColumnCollectionMixin.__init__(self, *columns)
- Constraint.__init__(self, **kw)
-
- def _set_parent(self, table):
- ColumnCollectionMixin._set_parent(self, table)
- Constraint._set_parent(self, table)
-
- def __contains__(self, x):
- return x in self.columns
-
- def copy(self, **kw):
- c = self.__class__(name=self.name, deferrable=self.deferrable,
- initially=self.initially, *self.columns.keys())
- c.dispatch._update(self.dispatch)
- return c
-
- def contains_column(self, col):
- return self.columns.contains_column(col)
-
- def __iter__(self):
- # inlining of
- # return iter(self.columns)
- # ColumnCollection->OrderedProperties->OrderedDict
- ordered_dict = self.columns._data
- return (ordered_dict[key] for key in ordered_dict._list)
-
- def __len__(self):
- return len(self.columns._data)
-
-
-class CheckConstraint(Constraint):
- """A table- or column-level CHECK constraint.
-
- Can be included in the definition of a Table or Column.
- """
-
- def __init__(self, sqltext, name=None, deferrable=None,
- initially=None, table=None, _create_rule=None):
- """Construct a CHECK constraint.
-
- :param sqltext:
- A string containing the constraint definition, which will be used
- verbatim, or a SQL expression construct.
-
- :param name:
- Optional, the in-database name of the constraint.
-
- :param deferrable:
- Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when
- issuing DDL for this constraint.
-
- :param initially:
- Optional string. If set, emit INITIALLY <value> when issuing DDL
- for this constraint.
-
- """
-
- super(CheckConstraint, self).\
- __init__(name, deferrable, initially, _create_rule)
- self.sqltext = expression._literal_as_text(sqltext)
- if table is not None:
- self._set_parent_with_dispatch(table)
-
- def __visit_name__(self):
- if isinstance(self.parent, Table):
- return "check_constraint"
- else:
- return "column_check_constraint"
- __visit_name__ = property(__visit_name__)
-
- def copy(self, **kw):
- c = CheckConstraint(self.sqltext,
- name=self.name,
- initially=self.initially,
- deferrable=self.deferrable,
- _create_rule=self._create_rule)
- c.dispatch._update(self.dispatch)
- return c
-
-class ForeignKeyConstraint(Constraint):
- """A table-level FOREIGN KEY constraint.
-
- Defines a single column or composite FOREIGN KEY ... REFERENCES
- constraint. For a no-frills, single column foreign key, adding a
- :class:`.ForeignKey` to the definition of a :class:`.Column` is a shorthand
- equivalent for an unnamed, single column :class:`.ForeignKeyConstraint`.
-
- Examples of foreign key configuration are in :ref:`metadata_foreignkeys`.
-
- """
- __visit_name__ = 'foreign_key_constraint'
-
- def __init__(self, columns, refcolumns, name=None, onupdate=None,
- ondelete=None, deferrable=None, initially=None, use_alter=False,
- link_to_name=False, table=None):
- """Construct a composite-capable FOREIGN KEY.
-
- :param columns: A sequence of local column names. The named columns
- must be defined and present in the parent Table. The names should
- match the ``key`` given to each column (defaults to the name) unless
- ``link_to_name`` is True.
-
- :param refcolumns: A sequence of foreign column names or Column
- objects. The columns must all be located within the same Table.
-
- :param name: Optional, the in-database name of the key.
-
- :param onupdate: Optional string. If set, emit ON UPDATE <value> when
- issuing DDL for this constraint. Typical values include CASCADE,
- DELETE and RESTRICT.
-
- :param ondelete: Optional string. If set, emit ON DELETE <value> when
- issuing DDL for this constraint. Typical values include CASCADE,
- DELETE and RESTRICT.
-
- :param deferrable: Optional bool. If set, emit DEFERRABLE or NOT
- DEFERRABLE when issuing DDL for this constraint.
-
- :param initially: Optional string. If set, emit INITIALLY <value> when
- issuing DDL for this constraint.
-
- :param link_to_name: if True, the string name given in ``column`` is
- the rendered name of the referenced column, not its locally assigned
- ``key``.
-
- :param use_alter: If True, do not emit the DDL for this constraint as
- part of the CREATE TABLE definition. Instead, generate it via an
- ALTER TABLE statement issued after the full collection of tables
- have been created, and drop it via an ALTER TABLE statement before
- the full collection of tables are dropped. This is shorthand for the
- usage of :class:`.AddConstraint` and :class:`.DropConstraint` applied
- as "after-create" and "before-drop" events on the MetaData object.
- This is normally used to generate/drop constraints on objects that
- are mutually dependent on each other.
-
- """
- super(ForeignKeyConstraint, self).\
- __init__(name, deferrable, initially)
-
- self.onupdate = onupdate
- self.ondelete = ondelete
- self.link_to_name = link_to_name
- if self.name is None and use_alter:
- raise exc.ArgumentError("Alterable Constraint requires a name")
- self.use_alter = use_alter
-
- self._elements = util.OrderedDict()
-
- # standalone ForeignKeyConstraint - create
- # associated ForeignKey objects which will be applied to hosted
- # Column objects (in col.foreign_keys), either now or when attached
- # to the Table for string-specified names
- for col, refcol in zip(columns, refcolumns):
- self._elements[col] = ForeignKey(
- refcol,
- _constraint=self,
- name=self.name,
- onupdate=self.onupdate,
- ondelete=self.ondelete,
- use_alter=self.use_alter,
- link_to_name=self.link_to_name
- )
-
- if table is not None:
- self._set_parent_with_dispatch(table)
-
- @property
- def columns(self):
- return self._elements.keys()
-
- @property
- def elements(self):
- return self._elements.values()
-
- def _set_parent(self, table):
- super(ForeignKeyConstraint, self)._set_parent(table)
- for col, fk in self._elements.iteritems():
- # string-specified column names now get
- # resolved to Column objects
- if isinstance(col, basestring):
- col = table.c[col]
-
- if not hasattr(fk, 'parent') or \
- fk.parent is not col:
- fk._set_parent_with_dispatch(col)
-
- if self.use_alter:
- def supports_alter(ddl, event, schema_item, bind, **kw):
- return table in set(kw['tables']) and \
- bind.dialect.supports_alter
-
- event.listen(table.metadata, "after_create", AddConstraint(self, on=supports_alter))
- event.listen(table.metadata, "before_drop", DropConstraint(self, on=supports_alter))
-
-
- def copy(self, **kw):
- fkc = ForeignKeyConstraint(
- [x.parent.name for x in self._elements.values()],
- [x._get_colspec(**kw) for x in self._elements.values()],
- name=self.name,
- onupdate=self.onupdate,
- ondelete=self.ondelete,
- use_alter=self.use_alter,
- deferrable=self.deferrable,
- initially=self.initially,
- link_to_name=self.link_to_name
- )
- fkc.dispatch._update(self.dispatch)
- return fkc
-
-class PrimaryKeyConstraint(ColumnCollectionConstraint):
- """A table-level PRIMARY KEY constraint.
-
- Defines a single column or composite PRIMARY KEY constraint. For a
- no-frills primary key, adding ``primary_key=True`` to one or more
- ``Column`` definitions is a shorthand equivalent for an unnamed single- or
- multiple-column PrimaryKeyConstraint.
- """
-
- __visit_name__ = 'primary_key_constraint'
-
- def _set_parent(self, table):
- super(PrimaryKeyConstraint, self)._set_parent(table)
-
- if table.primary_key in table.constraints:
- table.constraints.remove(table.primary_key)
- table.primary_key = self
- table.constraints.add(self)
-
- for c in self.columns:
- c.primary_key = True
-
- def _replace(self, col):
- self.columns.replace(col)
-
-class UniqueConstraint(ColumnCollectionConstraint):
- """A table-level UNIQUE constraint.
-
- Defines a single column or composite UNIQUE constraint. For a no-frills,
- single column constraint, adding ``unique=True`` to the ``Column``
- definition is a shorthand equivalent for an unnamed, single column
- UniqueConstraint.
- """
-
- __visit_name__ = 'unique_constraint'
-
-class Index(ColumnCollectionMixin, SchemaItem):
- """A table-level INDEX.
-
- Defines a composite (one or more column) INDEX. For a no-frills, single
- column index, adding ``index=True`` to the ``Column`` definition is
- a shorthand equivalent for an unnamed, single column Index.
- """
-
- __visit_name__ = 'index'
-
- def __init__(self, name, *columns, **kw):
- """Construct an index object.
-
- :param name:
- The name of the index
-
- :param \*columns:
- Columns to include in the index. All columns must belong to the same
- table.
-
- :param unique:
- Defaults to False: create a unique index.
-
- :param \**kw:
- Other keyword arguments may be interpreted by specific dialects.
-
- """
- self.table = None
- # will call _set_parent() if table-bound column
- # objects are present
- ColumnCollectionMixin.__init__(self, *columns)
- self.name = name
- self.unique = kw.pop('unique', False)
- self.kwargs = kw
-
- def _set_parent(self, table):
- ColumnCollectionMixin._set_parent(self, table)
-
- if self.table is not None and table is not self.table:
- raise exc.ArgumentError(
- "Index '%s' is against table '%s', and "
- "cannot be associated with table '%s'." % (
- self.name,
- self.table.description,
- table.description
- )
- )
- self.table = table
- for c in self.columns:
- if c.table != self.table:
- raise exc.ArgumentError(
- "Column '%s' is not part of table '%s'." %
- (c, self.table.description)
- )
- table.indexes.add(self)
-
- @property
- def bind(self):
- """Return the connectable associated with this Index."""
-
- return self.table.bind
-
- def create(self, bind=None):
- if bind is None:
- bind = _bind_or_error(self)
- bind.create(self)
- return self
-
- def drop(self, bind=None):
- if bind is None:
- bind = _bind_or_error(self)
- bind.drop(self)
-
- def __repr__(self):
- return 'Index("%s", %s%s)' % (
- self.name,
- ', '.join(repr(c) for c in self.columns),
- (self.unique and ', unique=True') or '')
-
-class MetaData(SchemaItem):
- """A collection of Tables and their associated schema constructs.
-
- Holds a collection of Tables and an optional binding to an ``Engine`` or
- ``Connection``. If bound, the :class:`~sqlalchemy.schema.Table` objects
- in the collection and their columns may participate in implicit SQL
- execution.
-
- The `Table` objects themselves are stored in the `metadata.tables`
- dictionary.
-
- The ``bind`` property may be assigned to dynamically. A common pattern is
- to start unbound and then bind later when an engine is available::
-
- metadata = MetaData()
- # define tables
- Table('mytable', metadata, ...)
- # connect to an engine later, perhaps after loading a URL from a
- # configuration file
- metadata.bind = an_engine
-
- MetaData is a thread-safe object after tables have been explicitly defined
- or loaded via reflection.
-
- .. index::
- single: thread safety; MetaData
-
- """
-
- __visit_name__ = 'metadata'
-
- def __init__(self, bind=None, reflect=False):
- """Create a new MetaData object.
-
- :param bind:
- An Engine or Connection to bind to. May also be a string or URL
- instance, these are passed to create_engine() and this MetaData will
- be bound to the resulting engine.
-
- :param reflect:
- Optional, automatically load all tables from the bound database.
- Defaults to False. ``bind`` is required when this option is set.
- For finer control over loaded tables, use the ``reflect`` method of
- ``MetaData``.
-
- """
- self.tables = util.immutabledict()
- self._schemas = set()
- self._sequences = {}
- self.bind = bind
- if reflect:
- if not bind:
- raise exc.ArgumentError(
- "A bind must be supplied in conjunction "
- "with reflect=True")
- self.reflect()
-
- def __repr__(self):
- return 'MetaData(%r)' % self.bind
-
- def __contains__(self, table_or_key):
- if not isinstance(table_or_key, basestring):
- table_or_key = table_or_key.key
- return table_or_key in self.tables
-
- def _add_table(self, name, schema, table):
- key = _get_table_key(name, schema)
- dict.__setitem__(self.tables, key, table)
- if schema:
- self._schemas.add(schema)
-
- def _remove_table(self, name, schema):
- key = _get_table_key(name, schema)
- dict.pop(self.tables, key, None)
- if self._schemas:
- self._schemas = set([t.schema
- for t in self.tables.values()
- if t.schema is not None])
-
- def __getstate__(self):
- return {'tables': self.tables, 'schemas':self._schemas,
- 'sequences':self._sequences}
-
- def __setstate__(self, state):
- self.tables = state['tables']
- self._bind = None
- self._sequences = state['sequences']
- self._schemas = state['schemas']
-
- def is_bound(self):
- """True if this MetaData is bound to an Engine or Connection."""
-
- return self._bind is not None
-
- def bind(self):
- """An Engine or Connection to which this MetaData is bound.
-
- This property may be assigned an ``Engine`` or ``Connection``, or
- assigned a string or URL to automatically create a basic ``Engine``
- for this bind with ``create_engine()``.
-
- """
- return self._bind
-
- def _bind_to(self, bind):
- """Bind this MetaData to an Engine, Connection, string or URL."""
-
- if isinstance(bind, (basestring, url.URL)):
- from sqlalchemy import create_engine
- self._bind = create_engine(bind)
- else:
- self._bind = bind
- bind = property(bind, _bind_to)
-
- def clear(self):
- """Clear all Table objects from this MetaData."""
-
- dict.clear(self.tables)
- self._schemas.clear()
-
- def remove(self, table):
- """Remove the given Table object from this MetaData."""
-
- self._remove_table(table.name, table.schema)
-
- @property
- def sorted_tables(self):
- """Returns a list of ``Table`` objects sorted in order of
- dependency.
- """
- return sqlutil.sort_tables(self.tables.itervalues())
-
- def reflect(self, bind=None, schema=None, views=False, only=None):
- """Load all available table definitions from the database.
-
- Automatically creates ``Table`` entries in this ``MetaData`` for any
- table available in the database but not yet present in the
- ``MetaData``. May be called multiple times to pick up tables recently
- added to the database, however no special action is taken if a table
- in this ``MetaData`` no longer exists in the database.
-
- :param bind:
- A :class:`~sqlalchemy.engine.base.Connectable` used to access the
- database; if None, uses the existing bind on this ``MetaData``, if
- any.
-
- :param schema:
- Optional, query and reflect tables from an alterate schema.
-
- :param views:
- If True, also reflect views.
-
- :param only:
- Optional. Load only a sub-set of available named tables. May be
- specified as a sequence of names or a callable.
-
- If a sequence of names is provided, only those tables will be
- reflected. An error is raised if a table is requested but not
- available. Named tables already present in this ``MetaData`` are
- ignored.
-
- If a callable is provided, it will be used as a boolean predicate to
- filter the list of potential table names. The callable is called
- with a table name and this ``MetaData`` instance as positional
- arguments and should return a true value for any table to reflect.
-
- """
- reflect_opts = {'autoload': True}
- if bind is None:
- bind = _bind_or_error(self)
- conn = None
- else:
- reflect_opts['autoload_with'] = bind
- conn = bind.contextual_connect()
-
- if schema is not None:
- reflect_opts['schema'] = schema
-
- try:
- available = util.OrderedSet(bind.engine.table_names(schema,
- connection=conn))
- if views:
- available.update(
- bind.dialect.get_view_names(conn or bind, schema)
- )
-
- current = set(self.tables.iterkeys())
-
- if only is None:
- load = [name for name in available if name not in current]
- elif util.callable(only):
- load = [name for name in available
- if name not in current and only(name, self)]
- else:
- missing = [name for name in only if name not in available]
- if missing:
- s = schema and (" schema '%s'" % schema) or ''
- raise exc.InvalidRequestError(
- 'Could not reflect: requested table(s) not available '
- 'in %s%s: (%s)' %
- (bind.engine.url, s, ', '.join(missing)))
- load = [name for name in only if name not in current]
-
- for name in load:
- Table(name, self, **reflect_opts)
- finally:
- if conn is not None:
- conn.close()
-
- def append_ddl_listener(self, event_name, listener):
- """Append a DDL event listener to this ``MetaData``.
-
- Deprecated. See :class:`.DDLEvents`.
-
- """
- def adapt_listener(target, connection, **kw):
- listener(event, target, connection, **kw)
-
- event.listen(self, "" + event_name.replace('-', '_'), adapt_listener)
-
- def create_all(self, bind=None, tables=None, checkfirst=True):
- """Create all tables stored in this metadata.
-
- Conditional by default, will not attempt to recreate tables already
- present in the target database.
-
- :param bind:
- A :class:`~sqlalchemy.engine.base.Connectable` used to access the
- database; if None, uses the existing bind on this ``MetaData``, if
- any.
-
- :param tables:
- Optional list of ``Table`` objects, which is a subset of the total
- tables in the ``MetaData`` (others are ignored).
-
- :param checkfirst:
- Defaults to True, don't issue CREATEs for tables already present
- in the target database.
-
- """
- if bind is None:
- bind = _bind_or_error(self)
- bind.create(self, checkfirst=checkfirst, tables=tables)
-
- def drop_all(self, bind=None, tables=None, checkfirst=True):
- """Drop all tables stored in this metadata.
-
- Conditional by default, will not attempt to drop tables not present in
- the target database.
-
- :param bind:
- A :class:`~sqlalchemy.engine.base.Connectable` used to access the
- database; if None, uses the existing bind on this ``MetaData``, if
- any.
-
- :param tables:
- Optional list of ``Table`` objects, which is a subset of the
- total tables in the ``MetaData`` (others are ignored).
-
- :param checkfirst:
- Defaults to True, only issue DROPs for tables confirmed to be
- present in the target database.
-
- """
- if bind is None:
- bind = _bind_or_error(self)
- bind.drop(self, checkfirst=checkfirst, tables=tables)
-
-class ThreadLocalMetaData(MetaData):
- """A MetaData variant that presents a different ``bind`` in every thread.
-
- Makes the ``bind`` property of the MetaData a thread-local value, allowing
- this collection of tables to be bound to different ``Engine``
- implementations or connections in each thread.
-
- The ThreadLocalMetaData starts off bound to None in each thread. Binds
- must be made explicitly by assigning to the ``bind`` property or using
- ``connect()``. You can also re-bind dynamically multiple times per
- thread, just like a regular ``MetaData``.
-
- """
-
- __visit_name__ = 'metadata'
-
- def __init__(self):
- """Construct a ThreadLocalMetaData."""
-
- self.context = util.threading.local()
- self.__engines = {}
- super(ThreadLocalMetaData, self).__init__()
-
- def bind(self):
- """The bound Engine or Connection for this thread.
-
- This property may be assigned an Engine or Connection, or assigned a
- string or URL to automatically create a basic Engine for this bind
- with ``create_engine()``."""
-
- return getattr(self.context, '_engine', None)
-
- def _bind_to(self, bind):
- """Bind to a Connectable in the caller's thread."""
-
- if isinstance(bind, (basestring, url.URL)):
- try:
- self.context._engine = self.__engines[bind]
- except KeyError:
- from sqlalchemy import create_engine
- e = create_engine(bind)
- self.__engines[bind] = e
- self.context._engine = e
- else:
- # TODO: this is squirrely. we shouldnt have to hold onto engines
- # in a case like this
- if bind not in self.__engines:
- self.__engines[bind] = bind
- self.context._engine = bind
-
- bind = property(bind, _bind_to)
-
- def is_bound(self):
- """True if there is a bind for this thread."""
- return (hasattr(self.context, '_engine') and
- self.context._engine is not None)
-
- def dispose(self):
- """Dispose all bound engines, in all thread contexts."""
-
- for e in self.__engines.itervalues():
- if hasattr(e, 'dispose'):
- e.dispose()
-
-class SchemaVisitor(visitors.ClauseVisitor):
- """Define the visiting for ``SchemaItem`` objects."""
-
- __traverse_options__ = {'schema_visitor':True}
-
-
-class DDLElement(expression.Executable, expression.ClauseElement):
- """Base class for DDL expression constructs.
-
- This class is the base for the general purpose :class:`.DDL` class,
- as well as the various create/drop clause constructs such as
- :class:`.CreateTable`, :class:`.DropTable`, :class:`.AddConstraint`,
- etc.
-
- :class:`.DDLElement` integrates closely with SQLAlchemy events,
- introduced in :ref:`event_toplevel`. An instance of one is
- itself an event receiving callable::
-
- event.listen(
- users,
- 'after_create',
- AddConstraint(constraint).execute_if(dialect='postgresql')
- )
-
- See also:
-
- :class:`.DDL`
-
- :class:`.DDLEvents`
-
- :ref:`event_toplevel`
-
- :ref:`schema_ddl_sequences`
-
- """
-
- _execution_options = expression.Executable.\
- _execution_options.union({'autocommit':True})
-
- target = None
- on = None
- dialect = None
- callable_ = None
-
- def execute(self, bind=None, target=None):
- """Execute this DDL immediately.
-
- Executes the DDL statement in isolation using the supplied
- :class:`~sqlalchemy.engine.base.Connectable` or
- :class:`~sqlalchemy.engine.base.Connectable` assigned to the ``.bind``
- property, if not supplied. If the DDL has a conditional ``on``
- criteria, it will be invoked with None as the event.
-
- :param bind:
- Optional, an ``Engine`` or ``Connection``. If not supplied, a valid
- :class:`~sqlalchemy.engine.base.Connectable` must be present in the
- ``.bind`` property.
-
- :param target:
- Optional, defaults to None. The target SchemaItem for the
- execute call. Will be passed to the ``on`` callable if any,
- and may also provide string expansion data for the
- statement. See ``execute_at`` for more information.
-
- """
-
- if bind is None:
- bind = _bind_or_error(self)
-
- if self._should_execute(target, bind):
- return bind.execute(self.against(target))
- else:
- bind.engine.logger.info(
- "DDL execution skipped, criteria not met.")
-
- @util.deprecated("0.7", "See :class:`.DDLEvents`, as well as "
- ":meth:`.DDLElement.execute_if`.")
- def execute_at(self, event_name, target):
- """Link execution of this DDL to the DDL lifecycle of a SchemaItem.
-
- Links this ``DDLElement`` to a ``Table`` or ``MetaData`` instance,
- executing it when that schema item is created or dropped. The DDL
- statement will be executed using the same Connection and transactional
- context as the Table create/drop itself. The ``.bind`` property of
- this statement is ignored.
-
- :param event:
- One of the events defined in the schema item's ``.ddl_events``;
- e.g. 'before-create', 'after-create', 'before-drop' or 'after-drop'
-
- :param target:
- The Table or MetaData instance for which this DDLElement will
- be associated with.
-
- A DDLElement instance can be linked to any number of schema items.
-
- ``execute_at`` builds on the ``append_ddl_listener`` interface of
- :class:`.MetaData` and :class:`.Table` objects.
-
- Caveat: Creating or dropping a Table in isolation will also trigger
- any DDL set to ``execute_at`` that Table's MetaData. This may change
- in a future release.
-
- """
-
- def call_event(target, connection, **kw):
- if self._should_execute_deprecated(event_name,
- target, connection, **kw):
- return connection.execute(self.against(target))
-
- event.listen(target, "" + event_name.replace('-', '_'), call_event)
-
- @expression._generative
- def against(self, target):
- """Return a copy of this DDL against a specific schema item."""
-
- self.target = target
-
- @expression._generative
- def execute_if(self, dialect=None, callable_=None, state=None):
- """Return a callable that will execute this
- DDLElement conditionally.
-
- Used to provide a wrapper for event listening::
-
- event.listen(
- metadata,
- 'before_create',
- DDL("my_ddl").execute_if(dialect='postgresql')
- )
-
- :param dialect: May be a string, tuple or a callable
- predicate. If a string, it will be compared to the name of the
- executing database dialect::
-
- DDL('something').execute_if(dialect='postgresql')
-
- If a tuple, specifies multiple dialect names::
-
- DDL('something').execute_if(dialect=('postgresql', 'mysql'))
-
- :param callable_: A callable, which will be invoked with
- four positional arguments as well as optional keyword
- arguments:
-
- :ddl:
- This DDL element.
-
- :target:
- The :class:`.Table` or :class:`.MetaData` object which is the target of
- this event. May be None if the DDL is executed explicitly.
-
- :bind:
- The :class:`.Connection` being used for DDL execution
-
- :tables:
- Optional keyword argument - a list of Table objects which are to
- be created/ dropped within a MetaData.create_all() or drop_all()
- method call.
-
- :state:
- Optional keyword argument - will be the ``state`` argument
- passed to this function.
-
- :checkfirst:
- Keyword argument, will be True if the 'checkfirst' flag was
- set during the call to ``create()``, ``create_all()``,
- ``drop()``, ``drop_all()``.
-
- If the callable returns a true value, the DDL statement will be
- executed.
-
- :param state: any value which will be passed to the callable_
- as the ``state`` keyword argument.
-
- See also:
-
- :class:`.DDLEvents`
-
- :ref:`event_toplevel`
-
- """
- self.dialect = dialect
- self.callable_ = callable_
- self.state = state
-
- def _should_execute(self, target, bind, **kw):
- if self.on is not None and \
- not self._should_execute_deprecated(None, target, bind, **kw):
- return False
-
- if isinstance(self.dialect, basestring):
- if self.dialect != bind.engine.name:
- return False
- elif isinstance(self.dialect, (tuple, list, set)):
- if bind.engine.name not in self.dialect:
- return False
- if self.callable_ is not None and \
- not self.callable_(self, target, bind, state=self.state, **kw):
- return False
-
- return True
-
- def _should_execute_deprecated(self, event, target, bind, **kw):
- if self.on is None:
- return True
- elif isinstance(self.on, basestring):
- return self.on == bind.engine.name
- elif isinstance(self.on, (tuple, list, set)):
- return bind.engine.name in self.on
- else:
- return self.on(self, event, target, bind, **kw)
-
- def __call__(self, target, bind, **kw):
- """Execute the DDL as a ddl_listener."""
-
- if self._should_execute(target, bind, **kw):
- return bind.execute(self.against(target))
-
- def _check_ddl_on(self, on):
- if (on is not None and
- (not isinstance(on, (basestring, tuple, list, set)) and
- not util.callable(on))):
- raise exc.ArgumentError(
- "Expected the name of a database dialect, a tuple "
- "of names, or a callable for "
- "'on' criteria, got type '%s'." % type(on).__name__)
-
- def bind(self):
- if self._bind:
- return self._bind
- def _set_bind(self, bind):
- self._bind = bind
- bind = property(bind, _set_bind)
-
- def _generate(self):
- s = self.__class__.__new__(self.__class__)
- s.__dict__ = self.__dict__.copy()
- return s
-
- def _compiler(self, dialect, **kw):
- """Return a compiler appropriate for this ClauseElement, given a
- Dialect."""
-
- return dialect.ddl_compiler(dialect, self, **kw)
-
-class DDL(DDLElement):
- """A literal DDL statement.
-
- Specifies literal SQL DDL to be executed by the database. DDL objects
- function as DDL event listeners, and can be subscribed to those events
- listed in :class:`.DDLEvents`, using either :class:`.Table` or :class:`.MetaData`
- objects as targets. Basic templating support allows a single DDL instance
- to handle repetitive tasks for multiple tables.
-
- Examples::
-
- from sqlalchemy import event, DDL
-
- tbl = Table('users', metadata, Column('uid', Integer))
- event.listen(tbl, 'before_create', DDL('DROP TRIGGER users_trigger'))
-
- spow = DDL('ALTER TABLE %(table)s SET secretpowers TRUE')
- event.listen(tbl, 'after_create', spow.execute_if(dialect='somedb'))
-
- drop_spow = DDL('ALTER TABLE users SET secretpowers FALSE')
- connection.execute(drop_spow)
-
- When operating on Table events, the following ``statement``
- string substitions are available::
-
- %(table)s - the Table name, with any required quoting applied
- %(schema)s - the schema name, with any required quoting applied
- %(fullname)s - the Table name including schema, quoted if needed
-
- The DDL's "context", if any, will be combined with the standard
- substutions noted above. Keys present in the context will override
- the standard substitutions.
-
- """
-
- __visit_name__ = "ddl"
-
- def __init__(self, statement, on=None, context=None, bind=None):
- """Create a DDL statement.
-
- :param statement:
- A string or unicode string to be executed. Statements will be
- processed with Python's string formatting operator. See the
- ``context`` argument and the ``execute_at`` method.
-
- A literal '%' in a statement must be escaped as '%%'.
-
- SQL bind parameters are not available in DDL statements.
-
- :param on:
- Deprecated. See :meth:`.DDLElement.execute_if`.
-
- Optional filtering criteria. May be a string, tuple or a callable
- predicate. If a string, it will be compared to the name of the
- executing database dialect::
-
- DDL('something', on='postgresql')
-
- If a tuple, specifies multiple dialect names::
-
- DDL('something', on=('postgresql', 'mysql'))
-
- If a callable, it will be invoked with four positional arguments
- as well as optional keyword arguments:
-
- :ddl:
- This DDL element.
-
- :event:
- The name of the event that has triggered this DDL, such as
- 'after-create' Will be None if the DDL is executed explicitly.
-
- :target:
- The ``Table`` or ``MetaData`` object which is the target of
- this event. May be None if the DDL is executed explicitly.
-
- :connection:
- The ``Connection`` being used for DDL execution
-
- :tables:
- Optional keyword argument - a list of Table objects which are to
- be created/ dropped within a MetaData.create_all() or drop_all()
- method call.
-
-
- If the callable returns a true value, the DDL statement will be
- executed.
-
- :param context:
- Optional dictionary, defaults to None. These values will be
- available for use in string substitutions on the DDL statement.
-
- :param bind:
- Optional. A :class:`~sqlalchemy.engine.base.Connectable`, used by
- default when ``execute()`` is invoked without a bind argument.
-
-
- See also:
-
- :class:`.DDLEvents`
- :mod:`sqlalchemy.event`
-
- """
-
- if not isinstance(statement, basestring):
- raise exc.ArgumentError(
- "Expected a string or unicode SQL statement, got '%r'" %
- statement)
-
- self.statement = statement
- self.context = context or {}
-
- self._check_ddl_on(on)
- self.on = on
- self._bind = bind
-
-
- def __repr__(self):
- return '<%s@%s; %s>' % (
- type(self).__name__, id(self),
- ', '.join([repr(self.statement)] +
- ['%s=%r' % (key, getattr(self, key))
- for key in ('on', 'context')
- if getattr(self, key)]))
-
-def _to_schema_column(element):
- if hasattr(element, '__clause_element__'):
- element = element.__clause_element__()
- if not isinstance(element, Column):
- raise exc.ArgumentError("schema.Column object expected")
- return element
-
-def _to_schema_column_or_string(element):
- if hasattr(element, '__clause_element__'):
- element = element.__clause_element__()
- return element
-
-class _CreateDropBase(DDLElement):
- """Base class for DDL constucts that represent CREATE and DROP or
- equivalents.
-
- The common theme of _CreateDropBase is a single
- ``element`` attribute which refers to the element
- to be created or dropped.
-
- """
-
- def __init__(self, element, on=None, bind=None):
- self.element = element
- self._check_ddl_on(on)
- self.on = on
- self.bind = bind
-
- def _create_rule_disable(self, compiler):
- """Allow disable of _create_rule using a callable.
-
- Pass to _create_rule using
- util.portable_instancemethod(self._create_rule_disable)
- to retain serializability.
-
- """
- return False
-
-class CreateTable(_CreateDropBase):
- """Represent a CREATE TABLE statement."""
-
- __visit_name__ = "create_table"
-
-class DropTable(_CreateDropBase):
- """Represent a DROP TABLE statement."""
-
- __visit_name__ = "drop_table"
-
-class CreateSequence(_CreateDropBase):
- """Represent a CREATE SEQUENCE statement."""
-
- __visit_name__ = "create_sequence"
-
-class DropSequence(_CreateDropBase):
- """Represent a DROP SEQUENCE statement."""
-
- __visit_name__ = "drop_sequence"
-
-class CreateIndex(_CreateDropBase):
- """Represent a CREATE INDEX statement."""
-
- __visit_name__ = "create_index"
-
-class DropIndex(_CreateDropBase):
- """Represent a DROP INDEX statement."""
-
- __visit_name__ = "drop_index"
-
-class AddConstraint(_CreateDropBase):
- """Represent an ALTER TABLE ADD CONSTRAINT statement."""
-
- __visit_name__ = "add_constraint"
-
- def __init__(self, element, *args, **kw):
- super(AddConstraint, self).__init__(element, *args, **kw)
- element._create_rule = util.portable_instancemethod(
- self._create_rule_disable)
-
-class DropConstraint(_CreateDropBase):
- """Represent an ALTER TABLE DROP CONSTRAINT statement."""
-
- __visit_name__ = "drop_constraint"
-
- def __init__(self, element, cascade=False, **kw):
- self.cascade = cascade
- super(DropConstraint, self).__init__(element, **kw)
- element._create_rule = util.portable_instancemethod(
- self._create_rule_disable)
-
-def _bind_or_error(schemaitem, msg=None):
- bind = schemaitem.bind
- if not bind:
- name = schemaitem.__class__.__name__
- label = getattr(schemaitem, 'fullname',
- getattr(schemaitem, 'name', None))
- if label:
- item = '%s %r' % (name, label)
- else:
- item = name
- if isinstance(schemaitem, (MetaData, DDL)):
- bindable = "the %s's .bind" % name
- else:
- bindable = "this %s's .metadata.bind" % name
-
- if msg is None:
- msg = "The %s is not bound to an Engine or Connection. "\
- "Execution can not proceed without a database to execute "\
- "against. Either execute with an explicit connection or "\
- "assign %s to enable implicit execution." % \
- (item, bindable)
- raise exc.UnboundExecutionError(msg)
- return bind
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/__init__.py
deleted file mode 100755
index c591e680..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/__init__.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# sql/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy.sql.expression import (
- Alias,
- ClauseElement,
- ColumnCollection,
- ColumnElement,
- CompoundSelect,
- Delete,
- FromClause,
- Insert,
- Join,
- Select,
- Selectable,
- TableClause,
- Update,
- alias,
- and_,
- asc,
- between,
- bindparam,
- case,
- cast,
- collate,
- column,
- delete,
- desc,
- distinct,
- except_,
- except_all,
- exists,
- extract,
- func,
- insert,
- intersect,
- intersect_all,
- join,
- label,
- literal,
- literal_column,
- modifier,
- not_,
- null,
- or_,
- outerjoin,
- outparam,
- over,
- select,
- subquery,
- table,
- text,
- tuple_,
- type_coerce,
- union,
- union_all,
- update,
- )
-
-from sqlalchemy.sql.visitors import ClauseVisitor
-
-__tmp = locals().keys()
-__all__ = sorted([i for i in __tmp if not i.startswith('__')])
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py
deleted file mode 100755
index 829adeba..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py
+++ /dev/null
@@ -1,1793 +0,0 @@
-# sql/compiler.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Base SQL and DDL compiler implementations.
-
-Classes provided include:
-
-:class:`~sqlalchemy.sql.compiler.SQLCompiler` - renders SQL
-strings
-
-:class:`~sqlalchemy.sql.compiler.DDLCompiler` - renders DDL
-(data definition language) strings
-
-:class:`~sqlalchemy.sql.compiler.GenericTypeCompiler` - renders
-type specification strings.
-
-To generate user-defined SQL strings, see
-:module:`~sqlalchemy.ext.compiler`.
-
-"""
-
-import re
-from sqlalchemy import schema, engine, util, exc
-from sqlalchemy.sql import operators, functions, util as sql_util, \
- visitors
-from sqlalchemy.sql import expression as sql
-import decimal
-
-RESERVED_WORDS = set([
- 'all', 'analyse', 'analyze', 'and', 'any', 'array',
- 'as', 'asc', 'asymmetric', 'authorization', 'between',
- 'binary', 'both', 'case', 'cast', 'check', 'collate',
- 'column', 'constraint', 'create', 'cross', 'current_date',
- 'current_role', 'current_time', 'current_timestamp',
- 'current_user', 'default', 'deferrable', 'desc',
- 'distinct', 'do', 'else', 'end', 'except', 'false',
- 'for', 'foreign', 'freeze', 'from', 'full', 'grant',
- 'group', 'having', 'ilike', 'in', 'initially', 'inner',
- 'intersect', 'into', 'is', 'isnull', 'join', 'leading',
- 'left', 'like', 'limit', 'localtime', 'localtimestamp',
- 'natural', 'new', 'not', 'notnull', 'null', 'off', 'offset',
- 'old', 'on', 'only', 'or', 'order', 'outer', 'overlaps',
- 'placing', 'primary', 'references', 'right', 'select',
- 'session_user', 'set', 'similar', 'some', 'symmetric', 'table',
- 'then', 'to', 'trailing', 'true', 'union', 'unique', 'user',
- 'using', 'verbose', 'when', 'where'])
-
-LEGAL_CHARACTERS = re.compile(r'^[A-Z0-9_$]+$', re.I)
-ILLEGAL_INITIAL_CHARACTERS = set([str(x) for x in xrange(0, 10)]).union(['$'])
-
-BIND_PARAMS = re.compile(r'(?<![:\w\$\x5c]):([\w\$]+)(?![:\w\$])', re.UNICODE)
-BIND_PARAMS_ESC = re.compile(r'\x5c(:[\w\$]+)(?![:\w\$])', re.UNICODE)
-
-BIND_TEMPLATES = {
- 'pyformat':"%%(%(name)s)s",
- 'qmark':"?",
- 'format':"%%s",
- 'numeric':":%(position)s",
- 'named':":%(name)s"
-}
-
-
-OPERATORS = {
- # binary
- operators.and_ : ' AND ',
- operators.or_ : ' OR ',
- operators.add : ' + ',
- operators.mul : ' * ',
- operators.sub : ' - ',
- # Py2K
- operators.div : ' / ',
- # end Py2K
- operators.mod : ' % ',
- operators.truediv : ' / ',
- operators.neg : '-',
- operators.lt : ' < ',
- operators.le : ' <= ',
- operators.ne : ' != ',
- operators.gt : ' > ',
- operators.ge : ' >= ',
- operators.eq : ' = ',
- operators.concat_op : ' || ',
- operators.between_op : ' BETWEEN ',
- operators.match_op : ' MATCH ',
- operators.in_op : ' IN ',
- operators.notin_op : ' NOT IN ',
- operators.comma_op : ', ',
- operators.from_ : ' FROM ',
- operators.as_ : ' AS ',
- operators.is_ : ' IS ',
- operators.isnot : ' IS NOT ',
- operators.collate : ' COLLATE ',
-
- # unary
- operators.exists : 'EXISTS ',
- operators.distinct_op : 'DISTINCT ',
- operators.inv : 'NOT ',
-
- # modifiers
- operators.desc_op : ' DESC',
- operators.asc_op : ' ASC',
- operators.nullsfirst_op : ' NULLS FIRST',
- operators.nullslast_op : ' NULLS LAST',
-}
-
-FUNCTIONS = {
- functions.coalesce : 'coalesce%(expr)s',
- functions.current_date: 'CURRENT_DATE',
- functions.current_time: 'CURRENT_TIME',
- functions.current_timestamp: 'CURRENT_TIMESTAMP',
- functions.current_user: 'CURRENT_USER',
- functions.localtime: 'LOCALTIME',
- functions.localtimestamp: 'LOCALTIMESTAMP',
- functions.random: 'random%(expr)s',
- functions.sysdate: 'sysdate',
- functions.session_user :'SESSION_USER',
- functions.user: 'USER'
-}
-
-EXTRACT_MAP = {
- 'month': 'month',
- 'day': 'day',
- 'year': 'year',
- 'second': 'second',
- 'hour': 'hour',
- 'doy': 'doy',
- 'minute': 'minute',
- 'quarter': 'quarter',
- 'dow': 'dow',
- 'week': 'week',
- 'epoch': 'epoch',
- 'milliseconds': 'milliseconds',
- 'microseconds': 'microseconds',
- 'timezone_hour': 'timezone_hour',
- 'timezone_minute': 'timezone_minute'
-}
-
-COMPOUND_KEYWORDS = {
- sql.CompoundSelect.UNION : 'UNION',
- sql.CompoundSelect.UNION_ALL : 'UNION ALL',
- sql.CompoundSelect.EXCEPT : 'EXCEPT',
- sql.CompoundSelect.EXCEPT_ALL : 'EXCEPT ALL',
- sql.CompoundSelect.INTERSECT : 'INTERSECT',
- sql.CompoundSelect.INTERSECT_ALL : 'INTERSECT ALL'
-}
-
-class _CompileLabel(visitors.Visitable):
- """lightweight label object which acts as an expression._Label."""
-
- __visit_name__ = 'label'
- __slots__ = 'element', 'name'
-
- def __init__(self, col, name):
- self.element = col
- self.name = name
-
- @property
- def type(self):
- return self.element.type
-
- @property
- def quote(self):
- return self.element.quote
-
-class SQLCompiler(engine.Compiled):
- """Default implementation of Compiled.
-
- Compiles ClauseElements into SQL strings. Uses a similar visit
- paradigm as visitors.ClauseVisitor but implements its own traversal.
-
- """
-
- extract_map = EXTRACT_MAP
-
- compound_keywords = COMPOUND_KEYWORDS
-
- # class-level defaults which can be set at the instance
- # level to define if this Compiled instance represents
- # INSERT/UPDATE/DELETE
- isdelete = isinsert = isupdate = False
-
- # holds the "returning" collection of columns if
- # the statement is CRUD and defines returning columns
- # either implicitly or explicitly
- returning = None
-
- # set to True classwide to generate RETURNING
- # clauses before the VALUES or WHERE clause (i.e. MSSQL)
- returning_precedes_values = False
-
- # SQL 92 doesn't allow bind parameters to be used
- # in the columns clause of a SELECT, nor does it allow
- # ambiguous expressions like "? = ?". A compiler
- # subclass can set this flag to False if the target
- # driver/DB enforces this
- ansi_bind_rules = False
-
- def __init__(self, dialect, statement, column_keys=None,
- inline=False, **kwargs):
- """Construct a new ``DefaultCompiler`` object.
-
- dialect
- Dialect to be used
-
- statement
- ClauseElement to be compiled
-
- column_keys
- a list of column names to be compiled into an INSERT or UPDATE
- statement.
-
- """
- self.column_keys = column_keys
-
- # compile INSERT/UPDATE defaults/sequences inlined (no pre-
- # execute)
- self.inline = inline or getattr(statement, 'inline', False)
-
- # a dictionary of bind parameter keys to _BindParamClause
- # instances.
- self.binds = {}
-
- # a dictionary of _BindParamClause instances to "compiled" names
- # that are actually present in the generated SQL
- self.bind_names = util.column_dict()
-
- # stack which keeps track of nested SELECT statements
- self.stack = []
-
- # relates label names in the final SQL to a tuple of local
- # column/label name, ColumnElement object (if any) and
- # TypeEngine. ResultProxy uses this for type processing and
- # column targeting
- self.result_map = {}
-
- # true if the paramstyle is positional
- self.positional = dialect.positional
- if self.positional:
- self.positiontup = []
- self.bindtemplate = BIND_TEMPLATES[dialect.paramstyle]
-
- # an IdentifierPreparer that formats the quoting of identifiers
- self.preparer = dialect.identifier_preparer
- self.label_length = dialect.label_length \
- or dialect.max_identifier_length
-
- # a map which tracks "anonymous" identifiers that are created on
- # the fly here
- self.anon_map = util.PopulateDict(self._process_anon)
-
- # a map which tracks "truncated" names based on
- # dialect.label_length or dialect.max_identifier_length
- self.truncated_names = {}
- engine.Compiled.__init__(self, dialect, statement, **kwargs)
-
-
-
- @util.memoized_property
- def _bind_processors(self):
- return dict(
- (key, value) for key, value in
- ( (self.bind_names[bindparam],
- bindparam.type._cached_bind_processor(self.dialect))
- for bindparam in self.bind_names )
- if value is not None
- )
-
- def is_subquery(self):
- return len(self.stack) > 1
-
- @property
- def sql_compiler(self):
- return self
-
- def construct_params(self, params=None, _group_number=None):
- """return a dictionary of bind parameter keys and values"""
-
- if params:
- pd = {}
- for bindparam, name in self.bind_names.iteritems():
- if bindparam.key in params:
- pd[name] = params[bindparam.key]
- elif name in params:
- pd[name] = params[name]
- elif bindparam.required:
- if _group_number:
- raise exc.InvalidRequestError(
- "A value is required for bind parameter %r, "
- "in parameter group %d" %
- (bindparam.key, _group_number))
- else:
- raise exc.InvalidRequestError(
- "A value is required for bind parameter %r"
- % bindparam.key)
- elif bindparam.callable:
- pd[name] = bindparam.callable()
- else:
- pd[name] = bindparam.value
- return pd
- else:
- pd = {}
- for bindparam in self.bind_names:
- if bindparam.callable:
- pd[self.bind_names[bindparam]] = bindparam.callable()
- else:
- pd[self.bind_names[bindparam]] = bindparam.value
- return pd
-
- params = property(construct_params, doc="""
- Return the bind params for this compiled object.
-
- """)
-
- def default_from(self):
- """Called when a SELECT statement has no froms, and no FROM clause is
- to be appended.
-
- Gives Oracle a chance to tack on a ``FROM DUAL`` to the string output.
-
- """
- return ""
-
- def visit_grouping(self, grouping, asfrom=False, **kwargs):
- return "(" + grouping.element._compiler_dispatch(self, **kwargs) + ")"
-
- def visit_label(self, label, result_map=None,
- within_label_clause=False,
- within_columns_clause=False, **kw):
- # only render labels within the columns clause
- # or ORDER BY clause of a select. dialect-specific compilers
- # can modify this behavior.
- if within_columns_clause and not within_label_clause:
- if isinstance(label.name, sql._generated_label):
- labelname = self._truncated_identifier("colident", label.name)
- else:
- labelname = label.name
-
- if result_map is not None:
- result_map[labelname.lower()] = \
- (label.name, (label, label.element, labelname),\
- label.type)
-
- return label.element._compiler_dispatch(self,
- within_columns_clause=True,
- within_label_clause=True,
- **kw) + \
- OPERATORS[operators.as_] + \
- self.preparer.format_label(label, labelname)
- else:
- return label.element._compiler_dispatch(self,
- within_columns_clause=False,
- **kw)
-
- def visit_column(self, column, result_map=None, **kwargs):
- name = column.name
- if name is None:
- raise exc.CompileError("Cannot compile Column object until "
- "it's 'name' is assigned.")
-
- is_literal = column.is_literal
- if not is_literal and isinstance(name, sql._generated_label):
- name = self._truncated_identifier("colident", name)
-
- if result_map is not None:
- result_map[name.lower()] = (name, (column, ), column.type)
-
- if is_literal:
- name = self.escape_literal_column(name)
- else:
- name = self.preparer.quote(name, column.quote)
-
- table = column.table
- if table is None or not table.named_with_column:
- return name
- else:
- if table.schema:
- schema_prefix = self.preparer.quote_schema(
- table.schema,
- table.quote_schema) + '.'
- else:
- schema_prefix = ''
- tablename = table.name
- if isinstance(tablename, sql._generated_label):
- tablename = self._truncated_identifier("alias", tablename)
-
- return schema_prefix + \
- self.preparer.quote(tablename, table.quote) + \
- "." + name
-
- def escape_literal_column(self, text):
- """provide escaping for the literal_column() construct."""
-
- # TODO: some dialects might need different behavior here
- return text.replace('%', '%%')
-
- def visit_fromclause(self, fromclause, **kwargs):
- return fromclause.name
-
- def visit_index(self, index, **kwargs):
- return index.name
-
- def visit_typeclause(self, typeclause, **kwargs):
- return self.dialect.type_compiler.process(typeclause.type)
-
- def post_process_text(self, text):
- return text
-
- def visit_textclause(self, textclause, **kwargs):
- if textclause.typemap is not None:
- for colname, type_ in textclause.typemap.iteritems():
- self.result_map[colname.lower()] = (colname, None, type_)
-
- def do_bindparam(m):
- name = m.group(1)
- if name in textclause.bindparams:
- return self.process(textclause.bindparams[name])
- else:
- return self.bindparam_string(name)
-
- # un-escape any \:params
- return BIND_PARAMS_ESC.sub(lambda m: m.group(1),
- BIND_PARAMS.sub(do_bindparam,
- self.post_process_text(textclause.text))
- )
-
- def visit_null(self, expr, **kw):
- return 'NULL'
-
- def visit_true(self, expr, **kw):
- return 'true'
-
- def visit_false(self, expr, **kw):
- return 'false'
-
- def visit_clauselist(self, clauselist, **kwargs):
- sep = clauselist.operator
- if sep is None:
- sep = " "
- else:
- sep = OPERATORS[clauselist.operator]
- return sep.join(
- s for s in
- (c._compiler_dispatch(self, **kwargs)
- for c in clauselist.clauses)
- if s is not None)
-
- def visit_case(self, clause, **kwargs):
- x = "CASE "
- if clause.value is not None:
- x += clause.value._compiler_dispatch(self, **kwargs) + " "
- for cond, result in clause.whens:
- x += "WHEN " + cond._compiler_dispatch(
- self, **kwargs
- ) + " THEN " + result._compiler_dispatch(
- self, **kwargs) + " "
- if clause.else_ is not None:
- x += "ELSE " + clause.else_._compiler_dispatch(
- self, **kwargs
- ) + " "
- x += "END"
- return x
-
- def visit_cast(self, cast, **kwargs):
- return "CAST(%s AS %s)" % \
- (cast.clause._compiler_dispatch(self, **kwargs),
- cast.typeclause._compiler_dispatch(self, **kwargs))
-
- def visit_over(self, over, **kwargs):
- x ="%s OVER (" % over.func._compiler_dispatch(self, **kwargs)
- if over.partition_by is not None:
- x += "PARTITION BY %s" % \
- over.partition_by._compiler_dispatch(self, **kwargs)
- if over.order_by is not None:
- x += " "
- if over.order_by is not None:
- x += "ORDER BY %s" % \
- over.order_by._compiler_dispatch(self, **kwargs)
- x += ")"
- return x
-
- def visit_extract(self, extract, **kwargs):
- field = self.extract_map.get(extract.field, extract.field)
- return "EXTRACT(%s FROM %s)" % (field,
- extract.expr._compiler_dispatch(self, **kwargs))
-
- def visit_function(self, func, result_map=None, **kwargs):
- if result_map is not None:
- result_map[func.name.lower()] = (func.name, None, func.type)
-
- disp = getattr(self, "visit_%s_func" % func.name.lower(), None)
- if disp:
- return disp(func, **kwargs)
- else:
- name = FUNCTIONS.get(func.__class__, func.name + "%(expr)s")
- return ".".join(list(func.packagenames) + [name]) % \
- {'expr':self.function_argspec(func, **kwargs)}
-
- def visit_next_value_func(self, next_value, **kw):
- return self.visit_sequence(next_value.sequence)
-
- def visit_sequence(self, sequence):
- raise NotImplementedError(
- "Dialect '%s' does not support sequence increments." % self.dialect.name
- )
-
- def function_argspec(self, func, **kwargs):
- return func.clause_expr._compiler_dispatch(self, **kwargs)
-
- def visit_compound_select(self, cs, asfrom=False,
- parens=True, compound_index=1, **kwargs):
- entry = self.stack and self.stack[-1] or {}
- self.stack.append({'from':entry.get('from', None), 'iswrapper':True})
-
- keyword = self.compound_keywords.get(cs.keyword)
-
- text = (" " + keyword + " ").join(
- (c._compiler_dispatch(self,
- asfrom=asfrom, parens=False,
- compound_index=i, **kwargs)
- for i, c in enumerate(cs.selects))
- )
-
- group_by = cs._group_by_clause._compiler_dispatch(
- self, asfrom=asfrom, **kwargs)
- if group_by:
- text += " GROUP BY " + group_by
-
- text += self.order_by_clause(cs, **kwargs)
- text += (cs._limit is not None or cs._offset is not None) and \
- self.limit_clause(cs) or ""
-
- self.stack.pop(-1)
- if asfrom and parens:
- return "(" + text + ")"
- else:
- return text
-
- def visit_unary(self, unary, **kw):
- s = unary.element._compiler_dispatch(self, **kw)
- if unary.operator:
- s = OPERATORS[unary.operator] + s
- if unary.modifier:
- s = s + OPERATORS[unary.modifier]
- return s
-
- def visit_binary(self, binary, **kw):
- # don't allow "? = ?" to render
- if self.ansi_bind_rules and \
- isinstance(binary.left, sql._BindParamClause) and \
- isinstance(binary.right, sql._BindParamClause):
- kw['literal_binds'] = True
-
- return self._operator_dispatch(binary.operator,
- binary,
- lambda opstr: binary.left._compiler_dispatch(self, **kw) +
- opstr +
- binary.right._compiler_dispatch(
- self, **kw),
- **kw
- )
-
- def visit_like_op(self, binary, **kw):
- escape = binary.modifiers.get("escape", None)
- return '%s LIKE %s' % (
- binary.left._compiler_dispatch(self, **kw),
- binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
- (' ESCAPE ' + self.render_literal_value(escape, None))
- or '')
-
- def visit_notlike_op(self, binary, **kw):
- escape = binary.modifiers.get("escape", None)
- return '%s NOT LIKE %s' % (
- binary.left._compiler_dispatch(self, **kw),
- binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
- (' ESCAPE ' + self.render_literal_value(escape, None))
- or '')
-
- def visit_ilike_op(self, binary, **kw):
- escape = binary.modifiers.get("escape", None)
- return 'lower(%s) LIKE lower(%s)' % (
- binary.left._compiler_dispatch(self, **kw),
- binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
- (' ESCAPE ' + self.render_literal_value(escape, None))
- or '')
-
- def visit_notilike_op(self, binary, **kw):
- escape = binary.modifiers.get("escape", None)
- return 'lower(%s) NOT LIKE lower(%s)' % (
- binary.left._compiler_dispatch(self, **kw),
- binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
- (' ESCAPE ' + self.render_literal_value(escape, None))
- or '')
-
- def _operator_dispatch(self, operator, element, fn, **kw):
- if util.callable(operator):
- disp = getattr(self, "visit_%s" % operator.__name__, None)
- if disp:
- return disp(element, **kw)
- else:
- return fn(OPERATORS[operator])
- else:
- return fn(" " + operator + " ")
-
- def visit_bindparam(self, bindparam, within_columns_clause=False,
- literal_binds=False, **kwargs):
-
- if literal_binds or \
- (within_columns_clause and \
- self.ansi_bind_rules):
- if bindparam.value is None:
- raise exc.CompileError("Bind parameter without a "
- "renderable value not allowed here.")
- return self.render_literal_bindparam(bindparam,
- within_columns_clause=True, **kwargs)
-
- name = self._truncate_bindparam(bindparam)
-
- if name in self.binds:
- existing = self.binds[name]
- if existing is not bindparam:
- if existing.unique or bindparam.unique:
- raise exc.CompileError(
- "Bind parameter '%s' conflicts with "
- "unique bind parameter of the same name" %
- bindparam.key
- )
- elif getattr(existing, '_is_crud', False) or \
- getattr(bindparam, '_is_crud', False):
- raise exc.CompileError(
- "bindparam() name '%s' is reserved "
- "for automatic usage in the VALUES or SET "
- "clause of this "
- "insert/update statement. Please use a "
- "name other than column name when using bindparam() "
- "with insert() or update() (for example, 'b_%s')."
- % (bindparam.key, bindparam.key)
- )
-
- self.binds[bindparam.key] = self.binds[name] = bindparam
-
- return self.bindparam_string(name)
-
- def render_literal_bindparam(self, bindparam, **kw):
- value = bindparam.value
- processor = bindparam.type._cached_bind_processor(self.dialect)
- if processor:
- value = processor(value)
- return self.render_literal_value(value, bindparam.type)
-
- def render_literal_value(self, value, type_):
- """Render the value of a bind parameter as a quoted literal.
-
- This is used for statement sections that do not accept bind paramters
- on the target driver/database.
-
- This should be implemented by subclasses using the quoting services
- of the DBAPI.
-
- """
- if isinstance(value, basestring):
- value = value.replace("'", "''")
- return "'%s'" % value
- elif value is None:
- return "NULL"
- elif isinstance(value, (float, int, long)):
- return repr(value)
- elif isinstance(value, decimal.Decimal):
- return str(value)
- else:
- raise NotImplementedError(
- "Don't know how to literal-quote value %r" % value)
-
- def _truncate_bindparam(self, bindparam):
- if bindparam in self.bind_names:
- return self.bind_names[bindparam]
-
- bind_name = bindparam.key
- if isinstance(bind_name, sql._generated_label):
- bind_name = self._truncated_identifier("bindparam", bind_name)
-
- # add to bind_names for translation
- self.bind_names[bindparam] = bind_name
-
- return bind_name
-
- def _truncated_identifier(self, ident_class, name):
- if (ident_class, name) in self.truncated_names:
- return self.truncated_names[(ident_class, name)]
-
- anonname = name % self.anon_map
-
- if len(anonname) > self.label_length:
- counter = self.truncated_names.get(ident_class, 1)
- truncname = anonname[0:max(self.label_length - 6, 0)] + \
- "_" + hex(counter)[2:]
- self.truncated_names[ident_class] = counter + 1
- else:
- truncname = anonname
- self.truncated_names[(ident_class, name)] = truncname
- return truncname
-
- def _anonymize(self, name):
- return name % self.anon_map
-
- def _process_anon(self, key):
- (ident, derived) = key.split(' ', 1)
- anonymous_counter = self.anon_map.get(derived, 1)
- self.anon_map[derived] = anonymous_counter + 1
- return derived + "_" + str(anonymous_counter)
-
- def bindparam_string(self, name):
- if self.positional:
- self.positiontup.append(name)
- return self.bindtemplate % {
- 'name':name, 'position':len(self.positiontup)}
- else:
- return self.bindtemplate % {'name':name}
-
- def visit_alias(self, alias, asfrom=False, ashint=False,
- fromhints=None, **kwargs):
- if asfrom or ashint:
- if isinstance(alias.name, sql._generated_label):
- alias_name = self._truncated_identifier("alias", alias.name)
- else:
- alias_name = alias.name
-
- if ashint:
- return self.preparer.format_alias(alias, alias_name)
- elif asfrom:
- ret = alias.original._compiler_dispatch(self,
- asfrom=True, **kwargs) + \
- " AS " + \
- self.preparer.format_alias(alias, alias_name)
-
- if fromhints and alias in fromhints:
- hinttext = self.get_from_hint_text(alias, fromhints[alias])
- if hinttext:
- ret += " " + hinttext
-
- return ret
- else:
- return alias.original._compiler_dispatch(self, **kwargs)
-
- def label_select_column(self, select, column, asfrom):
- """label columns present in a select()."""
-
- if isinstance(column, sql._Label):
- return column
-
- elif select is not None and select.use_labels and column._label:
- return _CompileLabel(column, column._label)
-
- elif \
- asfrom and \
- isinstance(column, sql.ColumnClause) and \
- not column.is_literal and \
- column.table is not None and \
- not isinstance(column.table, sql.Select):
- return _CompileLabel(column, sql._generated_label(column.name))
- elif not isinstance(column,
- (sql._UnaryExpression, sql._TextClause)) \
- and (not hasattr(column, 'name') or \
- isinstance(column, sql.Function)):
- return _CompileLabel(column, column.anon_label)
- else:
- return column
-
- def get_select_hint_text(self, byfroms):
- return None
-
- def get_from_hint_text(self, table, text):
- return None
-
- def visit_select(self, select, asfrom=False, parens=True,
- iswrapper=False, fromhints=None,
- compound_index=1, **kwargs):
-
- entry = self.stack and self.stack[-1] or {}
-
- existingfroms = entry.get('from', None)
-
- froms = select._get_display_froms(existingfroms)
-
- correlate_froms = set(sql._from_objects(*froms))
-
- # TODO: might want to propagate existing froms for
- # select(select(select)) where innermost select should correlate
- # to outermost if existingfroms: correlate_froms =
- # correlate_froms.union(existingfroms)
-
- self.stack.append({'from': correlate_froms, 'iswrapper'
- : iswrapper})
-
- if compound_index==1 and not entry or entry.get('iswrapper', False):
- column_clause_args = {'result_map':self.result_map}
- else:
- column_clause_args = {}
-
- # the actual list of columns to print in the SELECT column list.
- inner_columns = [
- c for c in [
- self.label_select_column(select, co, asfrom=asfrom).\
- _compiler_dispatch(self,
- within_columns_clause=True,
- **column_clause_args)
- for co in util.unique_list(select.inner_columns)
- ]
- if c is not None
- ]
-
- text = "SELECT " # we're off to a good start !
-
- if select._hints:
- byfrom = dict([
- (from_, hinttext % {
- 'name':from_._compiler_dispatch(
- self, ashint=True)
- })
- for (from_, dialect), hinttext in
- select._hints.iteritems()
- if dialect in ('*', self.dialect.name)
- ])
- hint_text = self.get_select_hint_text(byfrom)
- if hint_text:
- text += hint_text + " "
-
- if select._prefixes:
- text += " ".join(
- x._compiler_dispatch(self, **kwargs)
- for x in select._prefixes) + " "
- text += self.get_select_precolumns(select)
- text += ', '.join(inner_columns)
-
- if froms:
- text += " \nFROM "
-
- if select._hints:
- text += ', '.join([f._compiler_dispatch(self,
- asfrom=True, fromhints=byfrom,
- **kwargs)
- for f in froms])
- else:
- text += ', '.join([f._compiler_dispatch(self,
- asfrom=True, **kwargs)
- for f in froms])
- else:
- text += self.default_from()
-
- if select._whereclause is not None:
- t = select._whereclause._compiler_dispatch(self, **kwargs)
- if t:
- text += " \nWHERE " + t
-
- if select._group_by_clause.clauses:
- group_by = select._group_by_clause._compiler_dispatch(
- self, **kwargs)
- if group_by:
- text += " GROUP BY " + group_by
-
- if select._having is not None:
- t = select._having._compiler_dispatch(self, **kwargs)
- if t:
- text += " \nHAVING " + t
-
- if select._order_by_clause.clauses:
- text += self.order_by_clause(select, **kwargs)
- if select._limit is not None or select._offset is not None:
- text += self.limit_clause(select)
- if select.for_update:
- text += self.for_update_clause(select)
-
- self.stack.pop(-1)
-
- if asfrom and parens:
- return "(" + text + ")"
- else:
- return text
-
- def get_select_precolumns(self, select):
- """Called when building a ``SELECT`` statement, position is just
- before column list.
-
- """
- return select._distinct and "DISTINCT " or ""
-
- def order_by_clause(self, select, **kw):
- order_by = select._order_by_clause._compiler_dispatch(self, **kw)
- if order_by:
- return " ORDER BY " + order_by
- else:
- return ""
-
- def for_update_clause(self, select):
- if select.for_update:
- return " FOR UPDATE"
- else:
- return ""
-
- def limit_clause(self, select):
- text = ""
- if select._limit is not None:
- text += "\n LIMIT " + self.process(sql.literal(select._limit))
- if select._offset is not None:
- if select._limit is None:
- text += "\n LIMIT -1"
- text += " OFFSET " + self.process(sql.literal(select._offset))
- return text
-
- def visit_table(self, table, asfrom=False, ashint=False,
- fromhints=None, **kwargs):
- if asfrom or ashint:
- if getattr(table, "schema", None):
- ret = self.preparer.quote_schema(table.schema,
- table.quote_schema) + \
- "." + self.preparer.quote(table.name,
- table.quote)
- else:
- ret = self.preparer.quote(table.name, table.quote)
- if fromhints and table in fromhints:
- hinttext = self.get_from_hint_text(table, fromhints[table])
- if hinttext:
- ret += " " + hinttext
- return ret
- else:
- return ""
-
- def visit_join(self, join, asfrom=False, **kwargs):
- return (
- join.left._compiler_dispatch(self, asfrom=True, **kwargs) +
- (join.isouter and " LEFT OUTER JOIN " or " JOIN ") +
- join.right._compiler_dispatch(self, asfrom=True, **kwargs) +
- " ON " +
- join.onclause._compiler_dispatch(self, **kwargs)
- )
-
- def visit_insert(self, insert_stmt):
- self.isinsert = True
- colparams = self._get_colparams(insert_stmt)
-
- if not colparams and \
- not self.dialect.supports_default_values and \
- not self.dialect.supports_empty_insert:
- raise exc.CompileError("The version of %s you are using does "
- "not support empty inserts." %
- self.dialect.name)
-
- preparer = self.preparer
- supports_default_values = self.dialect.supports_default_values
-
- text = "INSERT"
-
- prefixes = [self.process(x) for x in insert_stmt._prefixes]
- if prefixes:
- text += " " + " ".join(prefixes)
-
- text += " INTO " + preparer.format_table(insert_stmt.table)
-
- if colparams or not supports_default_values:
- text += " (%s)" % ', '.join([preparer.format_column(c[0])
- for c in colparams])
-
- if self.returning or insert_stmt._returning:
- self.returning = self.returning or insert_stmt._returning
- returning_clause = self.returning_clause(
- insert_stmt, self.returning)
-
- if self.returning_precedes_values:
- text += " " + returning_clause
-
- if not colparams and supports_default_values:
- text += " DEFAULT VALUES"
- else:
- text += " VALUES (%s)" % \
- ', '.join([c[1] for c in colparams])
-
- if self.returning and not self.returning_precedes_values:
- text += " " + returning_clause
-
- return text
-
- def visit_update(self, update_stmt):
- self.stack.append({'from': set([update_stmt.table])})
-
- self.isupdate = True
- colparams = self._get_colparams(update_stmt)
-
- text = "UPDATE " + self.preparer.format_table(update_stmt.table)
-
- text += ' SET ' + \
- ', '.join(
- self.preparer.quote(c[0].name, c[0].quote) +
- '=' + c[1]
- for c in colparams
- )
-
- if update_stmt._returning:
- self.returning = update_stmt._returning
- if self.returning_precedes_values:
- text += " " + self.returning_clause(
- update_stmt, update_stmt._returning)
-
- if update_stmt._whereclause is not None:
- text += " WHERE " + self.process(update_stmt._whereclause)
-
- if self.returning and not self.returning_precedes_values:
- text += " " + self.returning_clause(
- update_stmt, update_stmt._returning)
-
- self.stack.pop(-1)
-
- return text
-
- def _create_crud_bind_param(self, col, value, required=False):
- bindparam = sql.bindparam(col.key, value,
- type_=col.type, required=required)
- bindparam._is_crud = True
- return bindparam._compiler_dispatch(self)
-
-
- def _get_colparams(self, stmt):
- """create a set of tuples representing column/string pairs for use
- in an INSERT or UPDATE statement.
-
- Also generates the Compiled object's postfetch, prefetch, and
- returning column collections, used for default handling and ultimately
- populating the ResultProxy's prefetch_cols() and postfetch_cols()
- collections.
-
- """
-
- self.postfetch = []
- self.prefetch = []
- self.returning = []
-
- # no parameters in the statement, no parameters in the
- # compiled params - return binds for all columns
- if self.column_keys is None and stmt.parameters is None:
- return [
- (c, self._create_crud_bind_param(c,
- None, required=True))
- for c in stmt.table.columns
- ]
-
- required = object()
-
- # if we have statement parameters - set defaults in the
- # compiled params
- if self.column_keys is None:
- parameters = {}
- else:
- parameters = dict((sql._column_as_key(key), required)
- for key in self.column_keys
- if not stmt.parameters or
- key not in stmt.parameters)
-
- if stmt.parameters is not None:
- for k, v in stmt.parameters.iteritems():
- parameters.setdefault(sql._column_as_key(k), v)
-
- # create a list of column assignment clauses as tuples
- values = []
-
- need_pks = self.isinsert and \
- not self.inline and \
- not stmt._returning
-
- implicit_returning = need_pks and \
- self.dialect.implicit_returning and \
- stmt.table.implicit_returning
-
- postfetch_lastrowid = need_pks and self.dialect.postfetch_lastrowid
-
- # iterating through columns at the top to maintain ordering.
- # otherwise we might iterate through individual sets of
- # "defaults", "primary key cols", etc.
- for c in stmt.table.columns:
- if c.key in parameters:
- value = parameters[c.key]
- if sql._is_literal(value):
- value = self._create_crud_bind_param(
- c, value, required=value is required)
- elif c.primary_key and implicit_returning:
- self.returning.append(c)
- value = self.process(value.self_group())
- else:
- self.postfetch.append(c)
- value = self.process(value.self_group())
- values.append((c, value))
-
- elif self.isinsert:
- if c.primary_key and \
- need_pks and \
- (
- implicit_returning or
- not postfetch_lastrowid or
- c is not stmt.table._autoincrement_column
- ):
-
- if implicit_returning:
- if c.default is not None:
- if c.default.is_sequence:
- if self.dialect.supports_sequences and \
- (not c.default.optional or \
- not self.dialect.sequences_optional):
- proc = self.process(c.default)
- values.append((c, proc))
- self.returning.append(c)
- elif c.default.is_clause_element:
- values.append(
- (c,
- self.process(c.default.arg.self_group()))
- )
- self.returning.append(c)
- else:
- values.append(
- (c, self._create_crud_bind_param(c, None))
- )
- self.prefetch.append(c)
- else:
- self.returning.append(c)
- else:
- if c.default is not None or \
- c is stmt.table._autoincrement_column and (
- self.dialect.supports_sequences or
- self.dialect.preexecute_autoincrement_sequences
- ):
-
- values.append(
- (c, self._create_crud_bind_param(c, None))
- )
-
- self.prefetch.append(c)
-
- elif c.default is not None:
- if c.default.is_sequence:
- if self.dialect.supports_sequences and \
- (not c.default.optional or \
- not self.dialect.sequences_optional):
- proc = self.process(c.default)
- values.append((c, proc))
- if not c.primary_key:
- self.postfetch.append(c)
- elif c.default.is_clause_element:
- values.append(
- (c, self.process(c.default.arg.self_group()))
- )
-
- if not c.primary_key:
- # dont add primary key column to postfetch
- self.postfetch.append(c)
- else:
- values.append(
- (c, self._create_crud_bind_param(c, None))
- )
- self.prefetch.append(c)
- elif c.server_default is not None:
- if not c.primary_key:
- self.postfetch.append(c)
-
- elif self.isupdate:
- if c.onupdate is not None and not c.onupdate.is_sequence:
- if c.onupdate.is_clause_element:
- values.append(
- (c, self.process(c.onupdate.arg.self_group()))
- )
- self.postfetch.append(c)
- else:
- values.append(
- (c, self._create_crud_bind_param(c, None))
- )
- self.prefetch.append(c)
- elif c.server_onupdate is not None:
- self.postfetch.append(c)
- return values
-
- def visit_delete(self, delete_stmt):
- self.stack.append({'from': set([delete_stmt.table])})
- self.isdelete = True
-
- text = "DELETE FROM " + self.preparer.format_table(delete_stmt.table)
-
- if delete_stmt._returning:
- self.returning = delete_stmt._returning
- if self.returning_precedes_values:
- text += " " + self.returning_clause(
- delete_stmt, delete_stmt._returning)
-
- if delete_stmt._whereclause is not None:
- text += " WHERE " + self.process(delete_stmt._whereclause)
-
- if self.returning and not self.returning_precedes_values:
- text += " " + self.returning_clause(
- delete_stmt, delete_stmt._returning)
-
- self.stack.pop(-1)
-
- return text
-
- def visit_savepoint(self, savepoint_stmt):
- return "SAVEPOINT %s" % self.preparer.format_savepoint(savepoint_stmt)
-
- def visit_rollback_to_savepoint(self, savepoint_stmt):
- return "ROLLBACK TO SAVEPOINT %s" % \
- self.preparer.format_savepoint(savepoint_stmt)
-
- def visit_release_savepoint(self, savepoint_stmt):
- return "RELEASE SAVEPOINT %s" % \
- self.preparer.format_savepoint(savepoint_stmt)
-
-
-class DDLCompiler(engine.Compiled):
-
- @util.memoized_property
- def sql_compiler(self):
- return self.dialect.statement_compiler(self.dialect, None)
-
- @property
- def preparer(self):
- return self.dialect.identifier_preparer
-
- def construct_params(self, params=None):
- return None
-
- def visit_ddl(self, ddl, **kwargs):
- # table events can substitute table and schema name
- context = ddl.context
- if isinstance(ddl.target, schema.Table):
- context = context.copy()
-
- preparer = self.dialect.identifier_preparer
- path = preparer.format_table_seq(ddl.target)
- if len(path) == 1:
- table, sch = path[0], ''
- else:
- table, sch = path[-1], path[0]
-
- context.setdefault('table', table)
- context.setdefault('schema', sch)
- context.setdefault('fullname', preparer.format_table(ddl.target))
-
- return self.sql_compiler.post_process_text(ddl.statement % context)
-
- def visit_create_table(self, create):
- table = create.element
- preparer = self.dialect.identifier_preparer
-
- text = "\n" + " ".join(['CREATE'] + \
- table._prefixes + \
- ['TABLE',
- preparer.format_table(table),
- "("])
- separator = "\n"
-
- # if only one primary key, specify it along with the column
- first_pk = False
- for column in table.columns:
- text += separator
- separator = ", \n"
- text += "\t" + self.get_column_specification(
- column,
- first_pk=column.primary_key and \
- not first_pk
- )
- if column.primary_key:
- first_pk = True
- const = " ".join(self.process(constraint) \
- for constraint in column.constraints)
- if const:
- text += " " + const
-
- const = self.create_table_constraints(table)
- if const:
- text += ", \n\t" + const
-
- text += "\n)%s\n\n" % self.post_create_table(table)
- return text
-
- def create_table_constraints(self, table):
-
- # On some DB order is significant: visit PK first, then the
- # other constraints (engine.ReflectionTest.testbasic failed on FB2)
- constraints = []
- if table.primary_key:
- constraints.append(table.primary_key)
-
- constraints.extend([c for c in table._sorted_constraints
- if c is not table.primary_key])
-
- return ", \n\t".join(p for p in
- (self.process(constraint)
- for constraint in constraints
- if (
- constraint._create_rule is None or
- constraint._create_rule(self))
- and (
- not self.dialect.supports_alter or
- not getattr(constraint, 'use_alter', False)
- )) if p is not None
- )
-
- def visit_drop_table(self, drop):
- return "\nDROP TABLE " + self.preparer.format_table(drop.element)
-
- def _index_identifier(self, ident):
- if isinstance(ident, sql._generated_label):
- max = self.dialect.max_index_name_length or \
- self.dialect.max_identifier_length
- if len(ident) > max:
- return ident[0:max - 8] + \
- "_" + util.md5_hex(ident)[-4:]
- else:
- return ident
- else:
- self.dialect.validate_identifier(ident)
- return ident
-
- def visit_create_index(self, create):
- index = create.element
- preparer = self.preparer
- text = "CREATE "
- if index.unique:
- text += "UNIQUE "
- text += "INDEX %s ON %s (%s)" \
- % (preparer.quote(self._index_identifier(index.name),
- index.quote),
- preparer.format_table(index.table),
- ', '.join(preparer.quote(c.name, c.quote)
- for c in index.columns))
- return text
-
- def visit_drop_index(self, drop):
- index = drop.element
- return "\nDROP INDEX " + \
- self.preparer.quote(
- self._index_identifier(index.name), index.quote)
-
- def visit_add_constraint(self, create):
- preparer = self.preparer
- return "ALTER TABLE %s ADD %s" % (
- self.preparer.format_table(create.element.table),
- self.process(create.element)
- )
-
- def visit_create_sequence(self, create):
- text = "CREATE SEQUENCE %s" % \
- self.preparer.format_sequence(create.element)
- if create.element.increment is not None:
- text += " INCREMENT BY %d" % create.element.increment
- if create.element.start is not None:
- text += " START WITH %d" % create.element.start
- return text
-
- def visit_drop_sequence(self, drop):
- return "DROP SEQUENCE %s" % \
- self.preparer.format_sequence(drop.element)
-
- def visit_drop_constraint(self, drop):
- preparer = self.preparer
- return "ALTER TABLE %s DROP CONSTRAINT %s%s" % (
- self.preparer.format_table(drop.element.table),
- self.preparer.format_constraint(drop.element),
- drop.cascade and " CASCADE" or ""
- )
-
- def get_column_specification(self, column, **kwargs):
- colspec = self.preparer.format_column(column) + " " + \
- self.dialect.type_compiler.process(column.type)
- default = self.get_column_default_string(column)
- if default is not None:
- colspec += " DEFAULT " + default
-
- if not column.nullable:
- colspec += " NOT NULL"
- return colspec
-
- def post_create_table(self, table):
- return ''
-
- def get_column_default_string(self, column):
- if isinstance(column.server_default, schema.DefaultClause):
- if isinstance(column.server_default.arg, basestring):
- return "'%s'" % column.server_default.arg
- else:
- return self.sql_compiler.process(column.server_default.arg)
- else:
- return None
-
- def visit_check_constraint(self, constraint):
- text = ""
- if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
- sqltext = sql_util.expression_as_ddl(constraint.sqltext)
- text += "CHECK (%s)" % self.sql_compiler.process(sqltext)
- text += self.define_constraint_deferrability(constraint)
- return text
-
- def visit_column_check_constraint(self, constraint):
- text = "CHECK (%s)" % constraint.sqltext
- text += self.define_constraint_deferrability(constraint)
- return text
-
- def visit_primary_key_constraint(self, constraint):
- if len(constraint) == 0:
- return ''
- text = ""
- if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
- text += "PRIMARY KEY "
- text += "(%s)" % ', '.join(self.preparer.quote(c.name, c.quote)
- for c in constraint)
- text += self.define_constraint_deferrability(constraint)
- return text
-
- def visit_foreign_key_constraint(self, constraint):
- preparer = self.dialect.identifier_preparer
- text = ""
- if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- preparer.format_constraint(constraint)
- remote_table = list(constraint._elements.values())[0].column.table
- text += "FOREIGN KEY(%s) REFERENCES %s (%s)" % (
- ', '.join(preparer.quote(f.parent.name, f.parent.quote)
- for f in constraint._elements.values()),
- self.define_constraint_remote_table(
- constraint, remote_table, preparer),
- ', '.join(preparer.quote(f.column.name, f.column.quote)
- for f in constraint._elements.values())
- )
- text += self.define_constraint_cascades(constraint)
- text += self.define_constraint_deferrability(constraint)
- return text
-
- def define_constraint_remote_table(self, constraint, table, preparer):
- """Format the remote table clause of a CREATE CONSTRAINT clause."""
-
- return preparer.format_table(table)
-
- def visit_unique_constraint(self, constraint):
- text = ""
- if constraint.name is not None:
- text += "CONSTRAINT %s " % \
- self.preparer.format_constraint(constraint)
- text += "UNIQUE (%s)" % (
- ', '.join(self.preparer.quote(c.name, c.quote)
- for c in constraint))
- text += self.define_constraint_deferrability(constraint)
- return text
-
- def define_constraint_cascades(self, constraint):
- text = ""
- if constraint.ondelete is not None:
- text += " ON DELETE %s" % constraint.ondelete
- if constraint.onupdate is not None:
- text += " ON UPDATE %s" % constraint.onupdate
- return text
-
- def define_constraint_deferrability(self, constraint):
- text = ""
- if constraint.deferrable is not None:
- if constraint.deferrable:
- text += " DEFERRABLE"
- else:
- text += " NOT DEFERRABLE"
- if constraint.initially is not None:
- text += " INITIALLY %s" % constraint.initially
- return text
-
-
-class GenericTypeCompiler(engine.TypeCompiler):
- def visit_CHAR(self, type_):
- return "CHAR" + (type_.length and "(%d)" % type_.length or "")
-
- def visit_NCHAR(self, type_):
- return "NCHAR" + (type_.length and "(%d)" % type_.length or "")
-
- def visit_FLOAT(self, type_):
- return "FLOAT"
-
- def visit_REAL(self, type_):
- return "REAL"
-
- def visit_NUMERIC(self, type_):
- if type_.precision is None:
- return "NUMERIC"
- elif type_.scale is None:
- return "NUMERIC(%(precision)s)" % \
- {'precision': type_.precision}
- else:
- return "NUMERIC(%(precision)s, %(scale)s)" % \
- {'precision': type_.precision,
- 'scale' : type_.scale}
-
- def visit_DECIMAL(self, type_):
- return "DECIMAL"
-
- def visit_INTEGER(self, type_):
- return "INTEGER"
-
- def visit_SMALLINT(self, type_):
- return "SMALLINT"
-
- def visit_BIGINT(self, type_):
- return "BIGINT"
-
- def visit_TIMESTAMP(self, type_):
- return 'TIMESTAMP'
-
- def visit_DATETIME(self, type_):
- return "DATETIME"
-
- def visit_DATE(self, type_):
- return "DATE"
-
- def visit_TIME(self, type_):
- return "TIME"
-
- def visit_CLOB(self, type_):
- return "CLOB"
-
- def visit_NCLOB(self, type_):
- return "NCLOB"
-
- def visit_VARCHAR(self, type_):
- return "VARCHAR" + (type_.length and "(%d)" % type_.length or "")
-
- def visit_NVARCHAR(self, type_):
- return "NVARCHAR" + (type_.length and "(%d)" % type_.length or "")
-
- def visit_BLOB(self, type_):
- return "BLOB"
-
- def visit_BINARY(self, type_):
- return "BINARY" + (type_.length and "(%d)" % type_.length or "")
-
- def visit_VARBINARY(self, type_):
- return "VARBINARY" + (type_.length and "(%d)" % type_.length or "")
-
- def visit_BOOLEAN(self, type_):
- return "BOOLEAN"
-
- def visit_TEXT(self, type_):
- return "TEXT"
-
- def visit_large_binary(self, type_):
- return self.visit_BLOB(type_)
-
- def visit_boolean(self, type_):
- return self.visit_BOOLEAN(type_)
-
- def visit_time(self, type_):
- return self.visit_TIME(type_)
-
- def visit_datetime(self, type_):
- return self.visit_DATETIME(type_)
-
- def visit_date(self, type_):
- return self.visit_DATE(type_)
-
- def visit_big_integer(self, type_):
- return self.visit_BIGINT(type_)
-
- def visit_small_integer(self, type_):
- return self.visit_SMALLINT(type_)
-
- def visit_integer(self, type_):
- return self.visit_INTEGER(type_)
-
- def visit_real(self, type_):
- return self.visit_REAL(type_)
-
- def visit_float(self, type_):
- return self.visit_FLOAT(type_)
-
- def visit_numeric(self, type_):
- return self.visit_NUMERIC(type_)
-
- def visit_string(self, type_):
- return self.visit_VARCHAR(type_)
-
- def visit_unicode(self, type_):
- return self.visit_VARCHAR(type_)
-
- def visit_text(self, type_):
- return self.visit_TEXT(type_)
-
- def visit_unicode_text(self, type_):
- return self.visit_TEXT(type_)
-
- def visit_enum(self, type_):
- return self.visit_VARCHAR(type_)
-
- def visit_null(self, type_):
- raise NotImplementedError("Can't generate DDL for the null type")
-
- def visit_type_decorator(self, type_):
- return self.process(type_.type_engine(self.dialect))
-
- def visit_user_defined(self, type_):
- return type_.get_col_spec()
-
-class IdentifierPreparer(object):
- """Handle quoting and case-folding of identifiers based on options."""
-
- reserved_words = RESERVED_WORDS
-
- legal_characters = LEGAL_CHARACTERS
-
- illegal_initial_characters = ILLEGAL_INITIAL_CHARACTERS
-
- def __init__(self, dialect, initial_quote='"',
- final_quote=None, escape_quote='"', omit_schema=False):
- """Construct a new ``IdentifierPreparer`` object.
-
- initial_quote
- Character that begins a delimited identifier.
-
- final_quote
- Character that ends a delimited identifier. Defaults to
- `initial_quote`.
-
- omit_schema
- Prevent prepending schema name. Useful for databases that do
- not support schemae.
- """
-
- self.dialect = dialect
- self.initial_quote = initial_quote
- self.final_quote = final_quote or self.initial_quote
- self.escape_quote = escape_quote
- self.escape_to_quote = self.escape_quote * 2
- self.omit_schema = omit_schema
- self._strings = {}
-
- def _escape_identifier(self, value):
- """Escape an identifier.
-
- Subclasses should override this to provide database-dependent
- escaping behavior.
- """
-
- return value.replace(self.escape_quote, self.escape_to_quote)
-
- def _unescape_identifier(self, value):
- """Canonicalize an escaped identifier.
-
- Subclasses should override this to provide database-dependent
- unescaping behavior that reverses _escape_identifier.
- """
-
- return value.replace(self.escape_to_quote, self.escape_quote)
-
- def quote_identifier(self, value):
- """Quote an identifier.
-
- Subclasses should override this to provide database-dependent
- quoting behavior.
- """
-
- return self.initial_quote + \
- self._escape_identifier(value) + \
- self.final_quote
-
- def _requires_quotes(self, value):
- """Return True if the given identifier requires quoting."""
- lc_value = value.lower()
- return (lc_value in self.reserved_words
- or value[0] in self.illegal_initial_characters
- or not self.legal_characters.match(unicode(value))
- or (lc_value != value))
-
- def quote_schema(self, schema, force):
- """Quote a schema.
-
- Subclasses should override this to provide database-dependent
- quoting behavior.
- """
- return self.quote(schema, force)
-
- def quote(self, ident, force):
- if force is None:
- if ident in self._strings:
- return self._strings[ident]
- else:
- if self._requires_quotes(ident):
- self._strings[ident] = self.quote_identifier(ident)
- else:
- self._strings[ident] = ident
- return self._strings[ident]
- elif force:
- return self.quote_identifier(ident)
- else:
- return ident
-
- def format_sequence(self, sequence, use_schema=True):
- name = self.quote(sequence.name, sequence.quote)
- if not self.omit_schema and use_schema and \
- sequence.schema is not None:
- name = self.quote_schema(sequence.schema, sequence.quote) + \
- "." + name
- return name
-
- def format_label(self, label, name=None):
- return self.quote(name or label.name, label.quote)
-
- def format_alias(self, alias, name=None):
- return self.quote(name or alias.name, alias.quote)
-
- def format_savepoint(self, savepoint, name=None):
- return self.quote(name or savepoint.ident, savepoint.quote)
-
- def format_constraint(self, constraint):
- return self.quote(constraint.name, constraint.quote)
-
- def format_table(self, table, use_schema=True, name=None):
- """Prepare a quoted table and schema name."""
-
- if name is None:
- name = table.name
- result = self.quote(name, table.quote)
- if not self.omit_schema and use_schema \
- and getattr(table, "schema", None):
- result = self.quote_schema(table.schema, table.quote_schema) + \
- "." + result
- return result
-
- def format_column(self, column, use_table=False,
- name=None, table_name=None):
- """Prepare a quoted column name."""
-
- if name is None:
- name = column.name
- if not getattr(column, 'is_literal', False):
- if use_table:
- return self.format_table(
- column.table, use_schema=False,
- name=table_name) + "." + \
- self.quote(name, column.quote)
- else:
- return self.quote(name, column.quote)
- else:
- # literal textual elements get stuck into ColumnClause alot,
- # which shouldnt get quoted
-
- if use_table:
- return self.format_table(column.table,
- use_schema=False, name=table_name) + '.' + name
- else:
- return name
-
- def format_table_seq(self, table, use_schema=True):
- """Format table name and schema as a tuple."""
-
- # Dialects with more levels in their fully qualified references
- # ('database', 'owner', etc.) could override this and return
- # a longer sequence.
-
- if not self.omit_schema and use_schema and \
- getattr(table, 'schema', None):
- return (self.quote_schema(table.schema, table.quote_schema),
- self.format_table(table, use_schema=False))
- else:
- return (self.format_table(table, use_schema=False), )
-
- @util.memoized_property
- def _r_identifiers(self):
- initial, final, escaped_final = \
- [re.escape(s) for s in
- (self.initial_quote, self.final_quote,
- self._escape_identifier(self.final_quote))]
- r = re.compile(
- r'(?:'
- r'(?:%(initial)s((?:%(escaped)s|[^%(final)s])+)%(final)s'
- r'|([^\.]+))(?=\.|$))+' %
- { 'initial': initial,
- 'final': final,
- 'escaped': escaped_final })
- return r
-
- def unformat_identifiers(self, identifiers):
- """Unpack 'schema.table.column'-like strings into components."""
-
- r = self._r_identifiers
- return [self._unescape_identifier(i)
- for i in [a or b for a, b in r.findall(identifiers)]]
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/expression.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/expression.py
deleted file mode 100755
index e06eb61b..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/expression.py
+++ /dev/null
@@ -1,5127 +0,0 @@
-# sql/expression.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Defines the base components of SQL expression trees.
-
-All components are derived from a common base class
-:class:`.ClauseElement`. Common behaviors are organized
-based on class hierarchies, in some cases via mixins.
-
-All object construction from this package occurs via functions which
-in some cases will construct composite :class:`.ClauseElement` structures
-together, and in other cases simply return a single :class:`.ClauseElement`
-constructed directly. The function interface affords a more "DSL-ish"
-feel to constructing SQL expressions and also allows future class
-reorganizations.
-
-Even though classes are not constructed directly from the outside,
-most classes which have additional public methods are considered to be
-public (i.e. have no leading underscore). Other classes which are
-"semi-public" are marked with a single leading underscore; these
-classes usually have few or no public methods and are less guaranteed
-to stay the same in future releases.
-
-"""
-
-import itertools, re
-from operator import attrgetter
-
-from sqlalchemy import util, exc
-from sqlalchemy.sql import operators
-from sqlalchemy.sql.visitors import Visitable, cloned_traverse
-import operator
-
-functions = util.importlater("sqlalchemy.sql", "functions")
-sqlutil = util.importlater("sqlalchemy.sql", "util")
-sqltypes = util.importlater("sqlalchemy", "types")
-default = util.importlater("sqlalchemy.engine", "default")
-
-__all__ = [
- 'Alias', 'ClauseElement', 'ColumnCollection', 'ColumnElement',
- 'CompoundSelect', 'Delete', 'FromClause', 'Insert', 'Join', 'Select',
- 'Selectable', 'TableClause', 'Update', 'alias', 'and_', 'asc', 'between',
- 'bindparam', 'case', 'cast', 'column', 'delete', 'desc', 'distinct',
- 'except_', 'except_all', 'exists', 'extract', 'func', 'modifier',
- 'collate', 'insert', 'intersect', 'intersect_all', 'join', 'label',
- 'literal', 'literal_column', 'not_', 'null', 'nullsfirst', 'nullslast',
- 'or_', 'outparam', 'outerjoin', 'over', 'select', 'subquery', 'table', 'text',
- 'tuple_', 'type_coerce', 'union', 'union_all', 'update', ]
-
-PARSE_AUTOCOMMIT = util.symbol('PARSE_AUTOCOMMIT')
-
-def nullsfirst(column):
- """Return a NULLS FIRST ``ORDER BY`` clause element.
-
- e.g.::
-
- order_by = [desc(table1.mycol).nullsfirst()]
-
- """
- return _UnaryExpression(column, modifier=operators.nullsfirst_op)
-
-def nullslast(column):
- """Return a NULLS LAST ``ORDER BY`` clause element.
-
- e.g.::
-
- order_by = [desc(table1.mycol).nullslast()]
-
- """
- return _UnaryExpression(column, modifier=operators.nullslast_op)
-
-def desc(column):
- """Return a descending ``ORDER BY`` clause element.
-
- e.g.::
-
- order_by = [desc(table1.mycol)]
-
- """
- return _UnaryExpression(column, modifier=operators.desc_op)
-
-def asc(column):
- """Return an ascending ``ORDER BY`` clause element.
-
- e.g.::
-
- order_by = [asc(table1.mycol)]
-
- """
- return _UnaryExpression(column, modifier=operators.asc_op)
-
-def outerjoin(left, right, onclause=None):
- """Return an ``OUTER JOIN`` clause element.
-
- The returned object is an instance of :class:`.Join`.
-
- Similar functionality is also available via the :func:`outerjoin()`
- method on any :class:`.FromClause`.
-
- left
- The left side of the join.
-
- right
- The right side of the join.
-
- onclause
- Optional criterion for the ``ON`` clause, is derived from
- foreign key relationships established between left and right
- otherwise.
-
- To chain joins together, use the :func:`join()` or :func:`outerjoin()`
- methods on the resulting :class:`.Join` object.
-
- """
- return Join(left, right, onclause, isouter=True)
-
-def join(left, right, onclause=None, isouter=False):
- """Return a ``JOIN`` clause element (regular inner join).
-
- The returned object is an instance of :class:`.Join`.
-
- Similar functionality is also available via the :func:`join()` method
- on any :class:`.FromClause`.
-
- left
- The left side of the join.
-
- right
- The right side of the join.
-
- onclause
- Optional criterion for the ``ON`` clause, is derived from
- foreign key relationships established between left and right
- otherwise.
-
- To chain joins together, use the :func:`join()` or :func:`outerjoin()`
- methods on the resulting :class:`.Join` object.
-
- """
- return Join(left, right, onclause, isouter)
-
-def select(columns=None, whereclause=None, from_obj=[], **kwargs):
- """Returns a ``SELECT`` clause element.
-
- Similar functionality is also available via the :func:`select()`
- method on any :class:`.FromClause`.
-
- The returned object is an instance of :class:`.Select`.
-
- All arguments which accept :class:`.ClauseElement` arguments also accept
- string arguments, which will be converted as appropriate into
- either :func:`text()` or :func:`literal_column()` constructs.
-
- :param columns:
- A list of :class:`.ClauseElement` objects, typically
- :class:`.ColumnElement` objects or subclasses, which will form the
- columns clause of the resulting statement. For all members which are
- instances of :class:`.Selectable`, the individual :class:`.ColumnElement`
- members of the :class:`.Selectable` will be added individually to the
- columns clause. For example, specifying a
- :class:`~sqlalchemy.schema.Table` instance will result in all the
- contained :class:`~sqlalchemy.schema.Column` objects within to be added
- to the columns clause.
-
- This argument is not present on the form of :func:`select()`
- available on :class:`~sqlalchemy.schema.Table`.
-
- :param whereclause:
- A :class:`.ClauseElement` expression which will be used to form the
- ``WHERE`` clause.
-
- :param from_obj:
- A list of :class:`.ClauseElement` objects which will be added to the
- ``FROM`` clause of the resulting statement. Note that "from" objects are
- automatically located within the columns and whereclause ClauseElements.
- Use this parameter to explicitly specify "from" objects which are not
- automatically locatable. This could include
- :class:`~sqlalchemy.schema.Table` objects that aren't otherwise present,
- or :class:`.Join` objects whose presence will supercede that of the
- :class:`~sqlalchemy.schema.Table` objects already located in the other
- clauses.
-
- :param autocommit:
- Deprecated. Use .execution_options(autocommit=<True|False>)
- to set the autocommit option.
-
- :param bind=None:
- an :class:`~.base.Engine` or :class:`~.base.Connection` instance
- to which the
- resulting :class:`.Select` object will be bound. The :class:`.Select`
- object will otherwise automatically bind to whatever
- :class:`~.base.Connectable` instances can be located within its contained
- :class:`.ClauseElement` members.
-
- :param correlate=True:
- indicates that this :class:`.Select` object should have its
- contained :class:`.FromClause` elements "correlated" to an enclosing
- :class:`.Select` object. This means that any :class:`.ClauseElement`
- instance within the "froms" collection of this :class:`.Select`
- which is also present in the "froms" collection of an
- enclosing select will not be rendered in the ``FROM`` clause
- of this select statement.
-
- :param distinct=False:
- when ``True``, applies a ``DISTINCT`` qualifier to the columns
- clause of the resulting statement.
-
- The boolean argument may also be a column expression or list
- of column expressions - this is a special calling form which
- is understood by the Postgresql dialect to render the
- ``DISTINCT ON (<columns>)`` syntax.
-
- ``distinct`` is also available via the :meth:`~.Select.distinct`
- generative method.
-
- .. note:: The ``distinct`` keyword's acceptance of a string
- argument for usage with MySQL is deprecated. Use
- the ``prefixes`` argument or :meth:`~.Select.prefix_with`.
-
- :param for_update=False:
- when ``True``, applies ``FOR UPDATE`` to the end of the
- resulting statement. Certain database dialects also support
- alternate values for this parameter, for example mysql
- supports "read" which translates to ``LOCK IN SHARE MODE``,
- and oracle supports "nowait" which translates to ``FOR UPDATE
- NOWAIT``.
-
- :param group_by:
- a list of :class:`.ClauseElement` objects which will comprise the
- ``GROUP BY`` clause of the resulting select.
-
- :param having:
- a :class:`.ClauseElement` that will comprise the ``HAVING`` clause
- of the resulting select when ``GROUP BY`` is used.
-
- :param limit=None:
- a numerical value which usually compiles to a ``LIMIT``
- expression in the resulting select. Databases that don't
- support ``LIMIT`` will attempt to provide similar
- functionality.
-
- :param offset=None:
- a numeric value which usually compiles to an ``OFFSET``
- expression in the resulting select. Databases that don't
- support ``OFFSET`` will attempt to provide similar
- functionality.
-
- :param order_by:
- a scalar or list of :class:`.ClauseElement` objects which will
- comprise the ``ORDER BY`` clause of the resulting select.
-
- :param prefixes:
- a list of strings or :class:`.ClauseElement` objects to include
- directly after the SELECT keyword in the generated statement,
- for dialect-specific query features. ``prefixes`` is
- also available via the :meth:`~.Select.prefix_with`
- generative method.
-
- :param use_labels=False:
- when ``True``, the statement will be generated using labels
- for each column in the columns clause, which qualify each
- column with its parent table's (or aliases) name so that name
- conflicts between columns in different tables don't occur.
- The format of the label is <tablename>_<column>. The "c"
- collection of the resulting :class:`.Select` object will use these
- names as well for targeting column members.
-
- use_labels is also available via the :meth:`~._SelectBase.apply_labels`
- generative method.
-
- """
- return Select(columns, whereclause=whereclause, from_obj=from_obj,
- **kwargs)
-
-def subquery(alias, *args, **kwargs):
- """Return an :class:`.Alias` object derived
- from a :class:`.Select`.
-
- name
- alias name
-
- \*args, \**kwargs
-
- all other arguments are delivered to the
- :func:`select` function.
-
- """
- return Select(*args, **kwargs).alias(alias)
-
-def insert(table, values=None, inline=False, **kwargs):
- """Return an :class:`.Insert` clause element.
-
- Similar functionality is available via the :func:`insert()` method on
- :class:`~sqlalchemy.schema.Table`.
-
- :param table: The table to be inserted into.
-
- :param values: A dictionary which specifies the column specifications of
- the ``INSERT``, and is optional. If left as None, the column
- specifications are determined from the bind parameters used during the
- compile phase of the ``INSERT`` statement. If the bind parameters also
- are None during the compile phase, then the column specifications will be
- generated from the full list of table columns. Note that the
- :meth:`~Insert.values()` generative method may also be used for this.
-
- :param prefixes: A list of modifier keywords to be inserted between INSERT
- and INTO. Alternatively, the :meth:`~Insert.prefix_with` generative
- method may be used.
-
- :param inline: if True, SQL defaults will be compiled 'inline' into the
- statement and not pre-executed.
-
- If both `values` and compile-time bind parameters are present, the
- compile-time bind parameters override the information specified
- within `values` on a per-key basis.
-
- The keys within `values` can be either :class:`~sqlalchemy.schema.Column`
- objects or their string identifiers. Each key may reference one of:
-
- * a literal data value (i.e. string, number, etc.);
- * a Column object;
- * a SELECT statement.
-
- If a ``SELECT`` statement is specified which references this
- ``INSERT`` statement's table, the statement will be correlated
- against the ``INSERT`` statement.
-
- """
- return Insert(table, values, inline=inline, **kwargs)
-
-def update(table, whereclause=None, values=None, inline=False, **kwargs):
- """Return an :class:`.Update` clause element.
-
- Similar functionality is available via the :func:`update()` method on
- :class:`~sqlalchemy.schema.Table`.
-
- :param table: The table to be updated.
-
- :param whereclause: A :class:`.ClauseElement` describing the ``WHERE``
- condition of the ``UPDATE`` statement. Note that the
- :meth:`~Update.where()` generative method may also be used for this.
-
- :param values:
- A dictionary which specifies the ``SET`` conditions of the
- ``UPDATE``, and is optional. If left as None, the ``SET``
- conditions are determined from the bind parameters used during
- the compile phase of the ``UPDATE`` statement. If the bind
- parameters also are None during the compile phase, then the
- ``SET`` conditions will be generated from the full list of table
- columns. Note that the :meth:`~Update.values()` generative method may
- also be used for this.
-
- :param inline:
- if True, SQL defaults will be compiled 'inline' into the statement
- and not pre-executed.
-
- If both `values` and compile-time bind parameters are present, the
- compile-time bind parameters override the information specified
- within `values` on a per-key basis.
-
- The keys within `values` can be either :class:`~sqlalchemy.schema.Column`
- objects or their
- string identifiers. Each key may reference one of:
-
- * a literal data value (i.e. string, number, etc.);
- * a Column object;
- * a SELECT statement.
-
- If a ``SELECT`` statement is specified which references this
- ``UPDATE`` statement's table, the statement will be correlated
- against the ``UPDATE`` statement.
-
- """
- return Update(
- table,
- whereclause=whereclause,
- values=values,
- inline=inline,
- **kwargs)
-
-def delete(table, whereclause = None, **kwargs):
- """Return a :class:`.Delete` clause element.
-
- Similar functionality is available via the :func:`delete()` method on
- :class:`~sqlalchemy.schema.Table`.
-
- :param table: The table to be updated.
-
- :param whereclause: A :class:`.ClauseElement` describing the ``WHERE``
- condition of the ``UPDATE`` statement. Note that the
- :meth:`~Delete.where()` generative method may be used instead.
-
- """
- return Delete(table, whereclause, **kwargs)
-
-def and_(*clauses):
- """Join a list of clauses together using the ``AND`` operator.
-
- The ``&`` operator is also overloaded on all
- :class:`_CompareMixin` subclasses to produce the
- same result.
-
- """
- if len(clauses) == 1:
- return clauses[0]
- return BooleanClauseList(operator=operators.and_, *clauses)
-
-def or_(*clauses):
- """Join a list of clauses together using the ``OR`` operator.
-
- The ``|`` operator is also overloaded on all
- :class:`_CompareMixin` subclasses to produce the
- same result.
-
- """
- if len(clauses) == 1:
- return clauses[0]
- return BooleanClauseList(operator=operators.or_, *clauses)
-
-def not_(clause):
- """Return a negation of the given clause, i.e. ``NOT(clause)``.
-
- The ``~`` operator is also overloaded on all
- :class:`_CompareMixin` subclasses to produce the
- same result.
-
- """
- return operators.inv(_literal_as_binds(clause))
-
-def distinct(expr):
- """Return a ``DISTINCT`` clause."""
- expr = _literal_as_binds(expr)
- return _UnaryExpression(expr, operator=operators.distinct_op, type_=expr.type)
-
-def between(ctest, cleft, cright):
- """Return a ``BETWEEN`` predicate clause.
-
- Equivalent of SQL ``clausetest BETWEEN clauseleft AND clauseright``.
-
- The :func:`between()` method on all
- :class:`_CompareMixin` subclasses provides
- similar functionality.
-
- """
- ctest = _literal_as_binds(ctest)
- return ctest.between(cleft, cright)
-
-
-def case(whens, value=None, else_=None):
- """Produce a ``CASE`` statement.
-
- whens
- A sequence of pairs, or alternatively a dict,
- to be translated into "WHEN / THEN" clauses.
-
- value
- Optional for simple case statements, produces
- a column expression as in "CASE <expr> WHEN ..."
-
- else\_
- Optional as well, for case defaults produces
- the "ELSE" portion of the "CASE" statement.
-
- The expressions used for THEN and ELSE,
- when specified as strings, will be interpreted
- as bound values. To specify textual SQL expressions
- for these, use the :func:`literal_column`
- construct.
-
- The expressions used for the WHEN criterion
- may only be literal strings when "value" is
- present, i.e. CASE table.somecol WHEN "x" THEN "y".
- Otherwise, literal strings are not accepted
- in this position, and either the text(<string>)
- or literal(<string>) constructs must be used to
- interpret raw string values.
-
- Usage examples::
-
- case([(orderline.c.qty > 100, item.c.specialprice),
- (orderline.c.qty > 10, item.c.bulkprice)
- ], else_=item.c.regularprice)
- case(value=emp.c.type, whens={
- 'engineer': emp.c.salary * 1.1,
- 'manager': emp.c.salary * 3,
- })
-
- Using :func:`literal_column()`, to allow for databases that
- do not support bind parameters in the ``then`` clause. The type
- can be specified which determines the type of the :func:`case()` construct
- overall::
-
- case([(orderline.c.qty > 100,
- literal_column("'greaterthan100'", String)),
- (orderline.c.qty > 10, literal_column("'greaterthan10'",
- String))
- ], else_=literal_column("'lethan10'", String))
-
- """
-
- return _Case(whens, value=value, else_=else_)
-
-def cast(clause, totype, **kwargs):
- """Return a ``CAST`` function.
-
- Equivalent of SQL ``CAST(clause AS totype)``.
-
- Use with a :class:`~sqlalchemy.types.TypeEngine` subclass, i.e::
-
- cast(table.c.unit_price * table.c.qty, Numeric(10,4))
-
- or::
-
- cast(table.c.timestamp, DATE)
-
- """
- return _Cast(clause, totype, **kwargs)
-
-def extract(field, expr):
- """Return the clause ``extract(field FROM expr)``."""
-
- return _Extract(field, expr)
-
-def collate(expression, collation):
- """Return the clause ``expression COLLATE collation``."""
-
- expr = _literal_as_binds(expression)
- return _BinaryExpression(
- expr,
- _literal_as_text(collation),
- operators.collate, type_=expr.type)
-
-def exists(*args, **kwargs):
- """Return an ``EXISTS`` clause as applied to a :class:`.Select` object.
-
- Calling styles are of the following forms::
-
- # use on an existing select()
- s = select([table.c.col1]).where(table.c.col2==5)
- s = exists(s)
-
- # construct a select() at once
- exists(['*'], **select_arguments).where(criterion)
-
- # columns argument is optional, generates "EXISTS (SELECT *)"
- # by default.
- exists().where(table.c.col2==5)
-
- """
- return _Exists(*args, **kwargs)
-
-def union(*selects, **kwargs):
- """Return a ``UNION`` of multiple selectables.
-
- The returned object is an instance of
- :class:`.CompoundSelect`.
-
- A similar :func:`union()` method is available on all
- :class:`.FromClause` subclasses.
-
- \*selects
- a list of :class:`.Select` instances.
-
- \**kwargs
- available keyword arguments are the same as those of
- :func:`select`.
-
- """
- return CompoundSelect(CompoundSelect.UNION, *selects, **kwargs)
-
-def union_all(*selects, **kwargs):
- """Return a ``UNION ALL`` of multiple selectables.
-
- The returned object is an instance of
- :class:`.CompoundSelect`.
-
- A similar :func:`union_all()` method is available on all
- :class:`.FromClause` subclasses.
-
- \*selects
- a list of :class:`.Select` instances.
-
- \**kwargs
- available keyword arguments are the same as those of
- :func:`select`.
-
- """
- return CompoundSelect(CompoundSelect.UNION_ALL, *selects, **kwargs)
-
-def except_(*selects, **kwargs):
- """Return an ``EXCEPT`` of multiple selectables.
-
- The returned object is an instance of
- :class:`.CompoundSelect`.
-
- \*selects
- a list of :class:`.Select` instances.
-
- \**kwargs
- available keyword arguments are the same as those of
- :func:`select`.
-
- """
- return CompoundSelect(CompoundSelect.EXCEPT, *selects, **kwargs)
-
-def except_all(*selects, **kwargs):
- """Return an ``EXCEPT ALL`` of multiple selectables.
-
- The returned object is an instance of
- :class:`.CompoundSelect`.
-
- \*selects
- a list of :class:`.Select` instances.
-
- \**kwargs
- available keyword arguments are the same as those of
- :func:`select`.
-
- """
- return CompoundSelect(CompoundSelect.EXCEPT_ALL, *selects, **kwargs)
-
-def intersect(*selects, **kwargs):
- """Return an ``INTERSECT`` of multiple selectables.
-
- The returned object is an instance of
- :class:`.CompoundSelect`.
-
- \*selects
- a list of :class:`.Select` instances.
-
- \**kwargs
- available keyword arguments are the same as those of
- :func:`select`.
-
- """
- return CompoundSelect(CompoundSelect.INTERSECT, *selects, **kwargs)
-
-def intersect_all(*selects, **kwargs):
- """Return an ``INTERSECT ALL`` of multiple selectables.
-
- The returned object is an instance of
- :class:`.CompoundSelect`.
-
- \*selects
- a list of :class:`.Select` instances.
-
- \**kwargs
- available keyword arguments are the same as those of
- :func:`select`.
-
- """
- return CompoundSelect(CompoundSelect.INTERSECT_ALL, *selects, **kwargs)
-
-def alias(selectable, name=None):
- """Return an :class:`.Alias` object.
-
- An :class:`.Alias` represents any :class:`.FromClause`
- with an alternate name assigned within SQL, typically using the ``AS``
- clause when generated, e.g. ``SELECT * FROM table AS aliasname``.
-
- Similar functionality is available via the
- :meth:`~.FromClause.alias` method
- available on all :class:`.FromClause` subclasses.
-
- When an :class:`.Alias` is created from a :class:`.Table` object,
- this has the effect of the table being rendered
- as ``tablename AS aliasname`` in a SELECT statement.
-
- For :func:`.select` objects, the effect is that of creating a named
- subquery, i.e. ``(select ...) AS aliasname``.
-
- The ``name`` parameter is optional, and provides the name
- to use in the rendered SQL. If blank, an "anonymous" name
- will be deterministically generated at compile time.
- Deterministic means the name is guaranteed to be unique against
- other constructs used in the same statement, and will also be the
- same name for each successive compilation of the same statement
- object.
-
- :param selectable: any :class:`.FromClause` subclass,
- such as a table, select statement, etc.
-
- :param name: string name to be assigned as the alias.
- If ``None``, a name will be deterministically generated
- at compile time.
-
- """
- return Alias(selectable, name=name)
-
-
-def literal(value, type_=None):
- """Return a literal clause, bound to a bind parameter.
-
- Literal clauses are created automatically when non- :class:`.ClauseElement`
- objects (such as strings, ints, dates, etc.) are used in a comparison
- operation with a :class:`_CompareMixin`
- subclass, such as a :class:`~sqlalchemy.schema.Column` object. Use this function to force the
- generation of a literal clause, which will be created as a
- :class:`_BindParamClause` with a bound value.
-
- :param value: the value to be bound. Can be any Python object supported by
- the underlying DB-API, or is translatable via the given type argument.
-
- :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` which
- will provide bind-parameter translation for this literal.
-
- """
- return _BindParamClause(None, value, type_=type_, unique=True)
-
-def tuple_(*expr):
- """Return a SQL tuple.
-
- Main usage is to produce a composite IN construct::
-
- tuple_(table.c.col1, table.c.col2).in_(
- [(1, 2), (5, 12), (10, 19)]
- )
-
- """
- return _Tuple(*expr)
-
-def type_coerce(expr, type_):
- """Coerce the given expression into the given type, on the Python side only.
-
- :func:`.type_coerce` is roughly similar to :func:.`cast`, except no
- "CAST" expression is rendered - the given type is only applied towards
- expression typing and against received result values.
-
- e.g.::
-
- from sqlalchemy.types import TypeDecorator
- import uuid
-
- class AsGuid(TypeDecorator):
- impl = String
-
- def process_bind_param(self, value, dialect):
- if value is not None:
- return str(value)
- else:
- return None
-
- def process_result_value(self, value, dialect):
- if value is not None:
- return uuid.UUID(value)
- else:
- return None
-
- conn.execute(
- select([type_coerce(mytable.c.ident, AsGuid)]).\\
- where(
- type_coerce(mytable.c.ident, AsGuid) ==
- uuid.uuid3(uuid.NAMESPACE_URL, 'bar')
- )
- )
-
- """
- if hasattr(expr, '__clause_expr__'):
- return type_coerce(expr.__clause_expr__())
-
- elif not isinstance(expr, Visitable):
- if expr is None:
- return null()
- else:
- return literal(expr, type_=type_)
- else:
- return _Label(None, expr, type_=type_)
-
-
-def label(name, obj):
- """Return a :class:`_Label` object for the
- given :class:`.ColumnElement`.
-
- A label changes the name of an element in the columns clause of a
- ``SELECT`` statement, typically via the ``AS`` SQL keyword.
-
- This functionality is more conveniently available via the
- :func:`label()` method on :class:`.ColumnElement`.
-
- name
- label name
-
- obj
- a :class:`.ColumnElement`.
-
- """
- return _Label(name, obj)
-
-def column(text, type_=None):
- """Return a textual column clause, as would be in the columns clause of a
- ``SELECT`` statement.
-
- The object returned is an instance of :class:`.ColumnClause`, which
- represents the "syntactical" portion of the schema-level
- :class:`~sqlalchemy.schema.Column` object. It is often used directly
- within :func:`~.expression.select` constructs or with lightweight :func:`~.expression.table`
- constructs.
-
- Note that the :func:`~.expression.column` function is not part of
- the ``sqlalchemy`` namespace. It must be imported from the ``sql`` package::
-
- from sqlalchemy.sql import table, column
-
- :param text: the name of the column. Quoting rules will be applied
- to the clause like any other column name. For textual column constructs
- that are not to be quoted, use the :func:`literal_column` function.
-
- :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` object
- which will provide result-set translation for this column.
-
- See :class:`.ColumnClause` for further examples.
-
- """
- return ColumnClause(text, type_=type_)
-
-def literal_column(text, type_=None):
- """Return a textual column expression, as would be in the columns
- clause of a ``SELECT`` statement.
-
- The object returned supports further expressions in the same way as any
- other column object, including comparison, math and string operations.
- The type\_ parameter is important to determine proper expression behavior
- (such as, '+' means string concatenation or numerical addition based on
- the type).
-
- :param text: the text of the expression; can be any SQL expression.
- Quoting rules will not be applied. To specify a column-name expression
- which should be subject to quoting rules, use the :func:`column`
- function.
-
- :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` object which will
- provide result-set translation and additional expression semantics for
- this column. If left as None the type will be NullType.
-
- """
- return ColumnClause(text, type_=type_, is_literal=True)
-
-def table(name, *columns):
- """Represent a textual table clause.
-
- The object returned is an instance of :class:`.TableClause`, which represents the
- "syntactical" portion of the schema-level :class:`~.schema.Table` object.
- It may be used to construct lightweight table constructs.
-
- Note that the :func:`~.expression.table` function is not part of
- the ``sqlalchemy`` namespace. It must be imported from the ``sql`` package::
-
- from sqlalchemy.sql import table, column
-
- :param name: Name of the table.
-
- :param columns: A collection of :func:`~.expression.column` constructs.
-
- See :class:`.TableClause` for further examples.
-
- """
- return TableClause(name, *columns)
-
-def bindparam(key, value=None, type_=None, unique=False, required=False, callable_=None):
- """Create a bind parameter clause with the given key.
-
- :param key:
- the key for this bind param. Will be used in the generated
- SQL statement for dialects that use named parameters. This
- value may be modified when part of a compilation operation,
- if other :class:`_BindParamClause` objects exist with the same
- key, or if its length is too long and truncation is
- required.
-
- :param value:
- Initial value for this bind param. This value may be
- overridden by the dictionary of parameters sent to statement
- compilation/execution.
-
- :param callable\_:
- A callable function that takes the place of "value". The function
- will be called at statement execution time to determine the
- ultimate value. Used for scenarios where the actual bind
- value cannot be determined at the point at which the clause
- construct is created, but embedded bind values are still desirable.
-
- :param type\_:
- A ``TypeEngine`` object that will be used to pre-process the
- value corresponding to this :class:`_BindParamClause` at
- execution time.
-
- :param unique:
- if True, the key name of this BindParamClause will be
- modified if another :class:`_BindParamClause` of the same name
- already has been located within the containing
- :class:`.ClauseElement`.
-
- :param required:
- a value is required at execution time.
-
- """
- if isinstance(key, ColumnClause):
- return _BindParamClause(key.name, value, type_=key.type,
- callable_=callable_,
- unique=unique, required=required)
- else:
- return _BindParamClause(key, value, type_=type_,
- callable_=callable_,
- unique=unique, required=required)
-
-def outparam(key, type_=None):
- """Create an 'OUT' parameter for usage in functions (stored procedures),
- for databases which support them.
-
- The ``outparam`` can be used like a regular function parameter.
- The "output" value will be available from the
- :class:`~sqlalchemy.engine.ResultProxy` object via its ``out_parameters``
- attribute, which returns a dictionary containing the values.
-
- """
- return _BindParamClause(
- key, None, type_=type_, unique=False, isoutparam=True)
-
-def text(text, bind=None, *args, **kwargs):
- """Create a SQL construct that is represented by a literal string.
-
- E.g.::
-
- t = text("SELECT * FROM users")
- result = connection.execute(t)
-
- The advantages :func:`text` provides over a plain string are
- backend-neutral support for bind parameters, per-statement
- execution options, as well as
- bind parameter and result-column typing behavior, allowing
- SQLAlchemy type constructs to play a role when executing
- a statement that is specified literally.
-
- Bind parameters are specified by name, using the format ``:name``.
- E.g.::
-
- t = text("SELECT * FROM users WHERE id=:user_id")
- result = connection.execute(t, user_id=12)
-
- To invoke SQLAlchemy typing logic for bind parameters, the
- ``bindparams`` list allows specification of :func:`bindparam`
- constructs which specify the type for a given name::
-
- t = text("SELECT id FROM users WHERE updated_at>:updated",
- bindparams=[bindparam('updated', DateTime())]
- )
-
- Typing during result row processing is also an important concern.
- Result column types
- are specified using the ``typemap`` dictionary, where the keys
- match the names of columns. These names are taken from what
- the DBAPI returns as ``cursor.description``::
-
- t = text("SELECT id, name FROM users",
- typemap={
- 'id':Integer,
- 'name':Unicode
- }
- )
-
- The :func:`text` construct is used internally for most cases when
- a literal string is specified for part of a larger query, such as
- within :func:`select()`, :func:`update()`,
- :func:`insert()` or :func:`delete()`. In those cases, the same
- bind parameter syntax is applied::
-
- s = select([users.c.id, users.c.name]).where("id=:user_id")
- result = connection.execute(s, user_id=12)
-
- Using :func:`text` explicitly usually implies the construction
- of a full, standalone statement. As such, SQLAlchemy refers
- to it as an :class:`.Executable` object, and it supports
- the :meth:`Executable.execution_options` method. For example,
- a :func:`text` construct that should be subject to "autocommit"
- can be set explicitly so using the ``autocommit`` option::
-
- t = text("EXEC my_procedural_thing()").\\
- execution_options(autocommit=True)
-
- Note that SQLAlchemy's usual "autocommit" behavior applies to
- :func:`text` constructs - that is, statements which begin
- with a phrase such as ``INSERT``, ``UPDATE``, ``DELETE``,
- or a variety of other phrases specific to certain backends, will
- be eligible for autocommit if no transaction is in progress.
-
- :param text:
- the text of the SQL statement to be created. use ``:<param>``
- to specify bind parameters; they will be compiled to their
- engine-specific format.
-
- :param autocommit:
- Deprecated. Use .execution_options(autocommit=<True|False>)
- to set the autocommit option.
-
- :param bind:
- an optional connection or engine to be used for this text query.
-
- :param bindparams:
- a list of :func:`bindparam()` instances which can be used to define
- the types and/or initial values for the bind parameters within
- the textual statement; the keynames of the bindparams must match
- those within the text of the statement. The types will be used
- for pre-processing on bind values.
-
- :param typemap:
- a dictionary mapping the names of columns represented in the
- columns clause of a ``SELECT`` statement to type objects,
- which will be used to perform post-processing on columns within
- the result set. This argument applies to any expression
- that returns result sets.
-
- """
- return _TextClause(text, bind=bind, *args, **kwargs)
-
-def over(func, partition_by=None, order_by=None):
- """Produce an OVER clause against a function.
-
- Used against aggregate or so-called "window" functions,
- for database backends that support window functions.
-
- E.g.::
-
- from sqlalchemy import over
- over(func.row_number(), order_by='x')
-
- Would produce "ROW_NUMBER() OVER(ORDER BY x)".
-
- :param func: a :class:`.FunctionElement` construct, typically
- generated by :attr:`~.expression.func`.
- :param partition_by: a column element or string, or a list
- of such, that will be used as the PARTITION BY clause
- of the OVER construct.
- :param order_by: a column element or string, or a list
- of such, that will be used as the ORDER BY clause
- of the OVER construct.
-
- This function is also available from the :attr:`~.expression.func`
- construct itself via the :meth:`.FunctionElement.over` method.
-
- New in 0.7.
-
- """
- return _Over(func, partition_by=partition_by, order_by=order_by)
-
-def null():
- """Return a :class:`_Null` object, which compiles to ``NULL``.
-
- """
- return _Null()
-
-def true():
- """Return a :class:`_True` object, which compiles to ``true``, or the
- boolean equivalent for the target dialect.
-
- """
- return _True()
-
-def false():
- """Return a :class:`_False` object, which compiles to ``false``, or the
- boolean equivalent for the target dialect.
-
- """
- return _False()
-
-class _FunctionGenerator(object):
- """Generate :class:`.Function` objects based on getattr calls."""
-
- def __init__(self, **opts):
- self.__names = []
- self.opts = opts
-
- def __getattr__(self, name):
- # passthru __ attributes; fixes pydoc
- if name.startswith('__'):
- try:
- return self.__dict__[name]
- except KeyError:
- raise AttributeError(name)
-
- elif name.endswith('_'):
- name = name[0:-1]
- f = _FunctionGenerator(**self.opts)
- f.__names = list(self.__names) + [name]
- return f
-
- def __call__(self, *c, **kwargs):
- o = self.opts.copy()
- o.update(kwargs)
- if len(self.__names) == 1:
- func = getattr(functions, self.__names[-1].lower(), None)
- if func is not None and \
- isinstance(func, type) and \
- issubclass(func, Function):
- return func(*c, **o)
-
- return Function(self.__names[-1],
- packagenames=self.__names[0:-1], *c, **o)
-
-# "func" global - i.e. func.count()
-func = _FunctionGenerator()
-"""Generate SQL function expressions.
-
- ``func`` is a special object instance which generates SQL functions based on name-based attributes, e.g.::
-
- >>> print func.count(1)
- count(:param_1)
-
- Any name can be given to ``func``. If the function name is unknown to
- SQLAlchemy, it will be rendered exactly as is. For common SQL functions
- which SQLAlchemy is aware of, the name may be interpreted as a *generic
- function* which will be compiled appropriately to the target database::
-
- >>> print func.current_timestamp()
- CURRENT_TIMESTAMP
-
- To call functions which are present in dot-separated packages, specify them in the same manner::
-
- >>> print func.stats.yield_curve(5, 10)
- stats.yield_curve(:yield_curve_1, :yield_curve_2)
-
- SQLAlchemy can be made aware of the return type of functions to enable
- type-specific lexical and result-based behavior. For example, to ensure
- that a string-based function returns a Unicode value and is similarly
- treated as a string in expressions, specify
- :class:`~sqlalchemy.types.Unicode` as the type:
-
- >>> print func.my_string(u'hi', type_=Unicode) + ' ' + \
- ... func.my_string(u'there', type_=Unicode)
- my_string(:my_string_1) || :my_string_2 || my_string(:my_string_3)
-
- The object returned by a ``func`` call is an instance of :class:`.Function`.
- This object meets the "column" interface, including comparison and labeling
- functions. The object can also be passed the :meth:`~.Connectable.execute`
- method of a :class:`.Connection` or :class:`.Engine`, where it will be
- wrapped inside of a SELECT statement first.
-
- Functions which are interpreted as "generic" functions know how to
- calculate their return type automatically. For a listing of known generic
- functions, see :ref:`generic_functions`.
-
-"""
-
-# "modifier" global - i.e. modifier.distinct
-# TODO: use UnaryExpression for this instead ?
-modifier = _FunctionGenerator(group=False)
-
-class _generated_label(unicode):
- """A unicode subclass used to identify dynamically generated names."""
-
-def _escape_for_generated(x):
- if isinstance(x, _generated_label):
- return x
- else:
- return x.replace('%', '%%')
-
-def _clone(element):
- return element._clone()
-
-def _expand_cloned(elements):
- """expand the given set of ClauseElements to be the set of all 'cloned'
- predecessors.
-
- """
- return itertools.chain(*[x._cloned_set for x in elements])
-
-def _select_iterables(elements):
- """expand tables into individual columns in the
- given list of column expressions.
-
- """
- return itertools.chain(*[c._select_iterable for c in elements])
-
-def _cloned_intersection(a, b):
- """return the intersection of sets a and b, counting
- any overlap between 'cloned' predecessors.
-
- The returned set is in terms of the enties present within 'a'.
-
- """
- all_overlap = set(_expand_cloned(a)).intersection(_expand_cloned(b))
- return set(elem for elem in a
- if all_overlap.intersection(elem._cloned_set))
-
-
-def _is_literal(element):
- return not isinstance(element, Visitable) and \
- not hasattr(element, '__clause_element__')
-
-def _from_objects(*elements):
- return itertools.chain(*[element._from_objects for element in elements])
-
-def _labeled(element):
- if not hasattr(element, 'name'):
- return element.label(None)
- else:
- return element
-
-def _column_as_key(element):
- if isinstance(element, basestring):
- return element
- if hasattr(element, '__clause_element__'):
- element = element.__clause_element__()
- return element.key
-
-def _literal_as_text(element):
- if isinstance(element, Visitable):
- return element
- elif hasattr(element, '__clause_element__'):
- return element.__clause_element__()
- elif isinstance(element, basestring):
- return _TextClause(unicode(element))
- elif isinstance(element, (util.NoneType, bool)):
- return _const_expr(element)
- else:
- raise exc.ArgumentError(
- "SQL expression object or string expected."
- )
-
-def _const_expr(element):
- if element is None:
- return null()
- elif element is False:
- return false()
- elif element is True:
- return true()
- else:
- raise exc.ArgumentError(
- "Expected None, False, or True"
- )
-
-def _clause_element_as_expr(element):
- if hasattr(element, '__clause_element__'):
- return element.__clause_element__()
- else:
- return element
-
-def _literal_as_column(element):
- if isinstance(element, Visitable):
- return element
- elif hasattr(element, '__clause_element__'):
- return element.__clause_element__()
- else:
- return literal_column(str(element))
-
-def _literal_as_binds(element, name=None, type_=None):
- if hasattr(element, '__clause_element__'):
- return element.__clause_element__()
- elif not isinstance(element, Visitable):
- if element is None:
- return null()
- else:
- return _BindParamClause(name, element, type_=type_, unique=True)
- else:
- return element
-
-def _type_from_args(args):
- for a in args:
- if not isinstance(a.type, sqltypes.NullType):
- return a.type
- else:
- return sqltypes.NullType
-
-def _no_literals(element):
- if hasattr(element, '__clause_element__'):
- return element.__clause_element__()
- elif not isinstance(element, Visitable):
- raise exc.ArgumentError("Ambiguous literal: %r. Use the 'text()' "
- "function to indicate a SQL expression "
- "literal, or 'literal()' to indicate a "
- "bound value." % element)
- else:
- return element
-
-def _only_column_elements(element, name):
- if hasattr(element, '__clause_element__'):
- element = element.__clause_element__()
- if not isinstance(element, ColumnElement):
- raise exc.ArgumentError("Column-based expression object expected for argument '%s'; "
- "got: '%s', type %s" % (name, element, type(element)))
- return element
-
-def _corresponding_column_or_error(fromclause, column,
- require_embedded=False):
- c = fromclause.corresponding_column(column,
- require_embedded=require_embedded)
- if c is None:
- raise exc.InvalidRequestError(
- "Given column '%s', attached to table '%s', "
- "failed to locate a corresponding column from table '%s'"
- %
- (column,
- getattr(column, 'table', None),fromclause.description)
- )
- return c
-
-@util.decorator
-def _generative(fn, *args, **kw):
- """Mark a method as generative."""
-
- self = args[0]._generate()
- fn(self, *args[1:], **kw)
- return self
-
-
-def is_column(col):
- """True if ``col`` is an instance of :class:`.ColumnElement`."""
-
- return isinstance(col, ColumnElement)
-
-
-class ClauseElement(Visitable):
- """Base class for elements of a programmatically constructed SQL
- expression.
-
- """
- __visit_name__ = 'clause'
-
- _annotations = {}
- supports_execution = False
- _from_objects = []
- bind = None
-
- def _clone(self):
- """Create a shallow copy of this ClauseElement.
-
- This method may be used by a generative API. Its also used as
- part of the "deep" copy afforded by a traversal that combines
- the _copy_internals() method.
-
- """
- c = self.__class__.__new__(self.__class__)
- c.__dict__ = self.__dict__.copy()
- c.__dict__.pop('_cloned_set', None)
-
- # this is a marker that helps to "equate" clauses to each other
- # when a Select returns its list of FROM clauses. the cloning
- # process leaves around a lot of remnants of the previous clause
- # typically in the form of column expressions still attached to the
- # old table.
- c._is_clone_of = self
-
- return c
-
- @property
- def _constructor(self):
- """return the 'constructor' for this ClauseElement.
-
- This is for the purposes for creating a new object of
- this type. Usually, its just the element's __class__.
- However, the "Annotated" version of the object overrides
- to return the class of its proxied element.
-
- """
- return self.__class__
-
- @util.memoized_property
- def _cloned_set(self):
- """Return the set consisting all cloned anscestors of this
- ClauseElement.
-
- Includes this ClauseElement. This accessor tends to be used for
- FromClause objects to identify 'equivalent' FROM clauses, regardless
- of transformative operations.
-
- """
- s = util.column_set()
- f = self
- while f is not None:
- s.add(f)
- f = getattr(f, '_is_clone_of', None)
- return s
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d.pop('_is_clone_of', None)
- return d
-
- if util.jython:
- def __hash__(self):
- """Return a distinct hash code.
-
- ClauseElements may have special equality comparisons which
- makes us rely on them having unique hash codes for use in
- hash-based collections. Stock __hash__ doesn't guarantee
- unique values on platforms with moving GCs.
- """
- return id(self)
-
- def _annotate(self, values):
- """return a copy of this ClauseElement with the given annotations
- dictionary.
-
- """
- return sqlutil.Annotated(self, values)
-
- def _deannotate(self):
- """return a copy of this ClauseElement with an empty annotations
- dictionary.
-
- """
- return self._clone()
-
- def unique_params(self, *optionaldict, **kwargs):
- """Return a copy with :func:`bindparam()` elments replaced.
-
- Same functionality as ``params()``, except adds `unique=True`
- to affected bind parameters so that multiple statements can be
- used.
-
- """
- return self._params(True, optionaldict, kwargs)
-
- def params(self, *optionaldict, **kwargs):
- """Return a copy with :func:`bindparam()` elments replaced.
-
- Returns a copy of this ClauseElement with :func:`bindparam()`
- elements replaced with values taken from the given dictionary::
-
- >>> clause = column('x') + bindparam('foo')
- >>> print clause.compile().params
- {'foo':None}
- >>> print clause.params({'foo':7}).compile().params
- {'foo':7}
-
- """
- return self._params(False, optionaldict, kwargs)
-
- def _params(self, unique, optionaldict, kwargs):
- if len(optionaldict) == 1:
- kwargs.update(optionaldict[0])
- elif len(optionaldict) > 1:
- raise exc.ArgumentError(
- "params() takes zero or one positional dictionary argument")
-
- def visit_bindparam(bind):
- if bind.key in kwargs:
- bind.value = kwargs[bind.key]
- if unique:
- bind._convert_to_unique()
- return cloned_traverse(self, {}, {'bindparam':visit_bindparam})
-
- def compare(self, other, **kw):
- """Compare this ClauseElement to the given ClauseElement.
-
- Subclasses should override the default behavior, which is a
- straight identity comparison.
-
- \**kw are arguments consumed by subclass compare() methods and
- may be used to modify the criteria for comparison.
- (see :class:`.ColumnElement`)
-
- """
- return self is other
-
- def _copy_internals(self, clone=_clone):
- """Reassign internal elements to be clones of themselves.
-
- Called during a copy-and-traverse operation on newly
- shallow-copied elements to create a deep copy.
-
- """
- pass
-
- def get_children(self, **kwargs):
- """Return immediate child elements of this :class:`.ClauseElement`.
-
- This is used for visit traversal.
-
- \**kwargs may contain flags that change the collection that is
- returned, for example to return a subset of items in order to
- cut down on larger traversals, or to return child items from a
- different context (such as schema-level collections instead of
- clause-level).
-
- """
- return []
-
- def self_group(self, against=None):
- """Apply a 'grouping' to this :class:`.ClauseElement`.
-
- This method is overridden by subclasses to return a
- "grouping" construct, i.e. parenthesis. In particular
- it's used by "binary" expressions to provide a grouping
- around themselves when placed into a larger expression,
- as well as by :func:`.select` constructs when placed into
- the FROM clause of another :func:`.select`. (Note that
- subqueries should be normally created using the
- :func:`.Select.alias` method, as many platforms require
- nested SELECT statements to be named).
-
- As expressions are composed together, the application of
- :meth:`self_group` is automatic - end-user code should never
- need to use this method directly. Note that SQLAlchemy's
- clause constructs take operator precedence into account -
- so parenthesis might not be needed, for example, in
- an expression like ``x OR (y AND z)`` - AND takes precedence
- over OR.
-
- The base :meth:`self_group` method of :class:`.ClauseElement`
- just returns self.
- """
- return self
-
-
- @util.deprecated('0.7',
- 'Only SQL expressions which subclass '
- ':class:`.Executable` may provide the '
- ':func:`.execute` method.')
- def execute(self, *multiparams, **params):
- """Compile and execute this :class:`.ClauseElement`.
-
- """
- e = self.bind
- if e is None:
- label = getattr(self, 'description', self.__class__.__name__)
- msg = ('This %s does not support direct execution.' % label)
- raise exc.UnboundExecutionError(msg)
- return e._execute_clauseelement(self, multiparams, params)
-
- @util.deprecated('0.7',
- 'Only SQL expressions which subclass '
- ':class:`.Executable` may provide the '
- ':func:`.scalar` method.')
- def scalar(self, *multiparams, **params):
- """Compile and execute this :class:`.ClauseElement`, returning
- the result's scalar representation.
-
- """
- return self.execute(*multiparams, **params).scalar()
-
- def compile(self, bind=None, dialect=None, **kw):
- """Compile this SQL expression.
-
- The return value is a :class:`~sqlalchemy.engine.Compiled` object.
- Calling ``str()`` or ``unicode()`` on the returned value will yield a
- string representation of the result. The
- :class:`~sqlalchemy.engine.Compiled` object also can return a
- dictionary of bind parameter names and values
- using the ``params`` accessor.
-
- :param bind: An ``Engine`` or ``Connection`` from which a
- ``Compiled`` will be acquired. This argument takes precedence over
- this :class:`.ClauseElement`'s bound engine, if any.
-
- :param column_keys: Used for INSERT and UPDATE statements, a list of
- column names which should be present in the VALUES clause of the
- compiled statement. If ``None``, all columns from the target table
- object are rendered.
-
- :param dialect: A ``Dialect`` instance frmo which a ``Compiled``
- will be acquired. This argument takes precedence over the `bind`
- argument as well as this :class:`.ClauseElement`'s bound engine, if
- any.
-
- :param inline: Used for INSERT statements, for a dialect which does
- not support inline retrieval of newly generated primary key
- columns, will force the expression used to create the new primary
- key value to be rendered inline within the INSERT statement's
- VALUES clause. This typically refers to Sequence execution but may
- also refer to any server-side default generation function
- associated with a primary key `Column`.
-
- """
-
- if not dialect:
- if bind:
- dialect = bind.dialect
- elif self.bind:
- dialect = self.bind.dialect
- bind = self.bind
- else:
- dialect = default.DefaultDialect()
- return self._compiler(dialect, bind=bind, **kw)
-
- def _compiler(self, dialect, **kw):
- """Return a compiler appropriate for this ClauseElement, given a
- Dialect."""
-
- return dialect.statement_compiler(dialect, self, **kw)
-
- def __str__(self):
- # Py3K
- #return unicode(self.compile())
- # Py2K
- return unicode(self.compile()).encode('ascii', 'backslashreplace')
- # end Py2K
-
- def __and__(self, other):
- return and_(self, other)
-
- def __or__(self, other):
- return or_(self, other)
-
- def __invert__(self):
- return self._negate()
-
- def __nonzero__(self):
- raise TypeError("Boolean value of this clause is not defined")
-
- def _negate(self):
- if hasattr(self, 'negation_clause'):
- return self.negation_clause
- else:
- return _UnaryExpression(
- self.self_group(against=operators.inv),
- operator=operators.inv,
- negate=None)
-
- def __repr__(self):
- friendly = getattr(self, 'description', None)
- if friendly is None:
- return object.__repr__(self)
- else:
- return '<%s.%s at 0x%x; %s>' % (
- self.__module__, self.__class__.__name__, id(self), friendly)
-
-
-class _Immutable(object):
- """mark a ClauseElement as 'immutable' when expressions are cloned."""
-
- def unique_params(self, *optionaldict, **kwargs):
- raise NotImplementedError("Immutable objects do not support copying")
-
- def params(self, *optionaldict, **kwargs):
- raise NotImplementedError("Immutable objects do not support copying")
-
- def _clone(self):
- return self
-
-class Operators(object):
- def __and__(self, other):
- return self.operate(operators.and_, other)
-
- def __or__(self, other):
- return self.operate(operators.or_, other)
-
- def __invert__(self):
- return self.operate(operators.inv)
-
- def op(self, opstring):
- def op(b):
- return self.operate(operators.op, opstring, b)
- return op
-
- def operate(self, op, *other, **kwargs):
- raise NotImplementedError(str(op))
-
- def reverse_operate(self, op, other, **kwargs):
- raise NotImplementedError(str(op))
-
-class ColumnOperators(Operators):
- """Defines comparison and math operations."""
-
- timetuple = None
- """Hack, allows datetime objects to be compared on the LHS."""
-
- def __lt__(self, other):
- return self.operate(operators.lt, other)
-
- def __le__(self, other):
- return self.operate(operators.le, other)
-
- __hash__ = Operators.__hash__
-
- def __eq__(self, other):
- return self.operate(operators.eq, other)
-
- def __ne__(self, other):
- return self.operate(operators.ne, other)
-
- def __gt__(self, other):
- return self.operate(operators.gt, other)
-
- def __ge__(self, other):
- return self.operate(operators.ge, other)
-
- def __neg__(self):
- return self.operate(operators.neg)
-
- def concat(self, other):
- return self.operate(operators.concat_op, other)
-
- def like(self, other, escape=None):
- return self.operate(operators.like_op, other, escape=escape)
-
- def ilike(self, other, escape=None):
- return self.operate(operators.ilike_op, other, escape=escape)
-
- def in_(self, other):
- return self.operate(operators.in_op, other)
-
- def startswith(self, other, **kwargs):
- return self.operate(operators.startswith_op, other, **kwargs)
-
- def endswith(self, other, **kwargs):
- return self.operate(operators.endswith_op, other, **kwargs)
-
- def contains(self, other, **kwargs):
- return self.operate(operators.contains_op, other, **kwargs)
-
- def match(self, other, **kwargs):
- return self.operate(operators.match_op, other, **kwargs)
-
- def desc(self):
- return self.operate(operators.desc_op)
-
- def asc(self):
- return self.operate(operators.asc_op)
-
- def nullsfirst(self):
- return self.operate(operators.nullsfirst_op)
-
- def nullslast(self):
- return self.operate(operators.nullslast_op)
-
- def collate(self, collation):
- return self.operate(operators.collate, collation)
-
- def __radd__(self, other):
- return self.reverse_operate(operators.add, other)
-
- def __rsub__(self, other):
- return self.reverse_operate(operators.sub, other)
-
- def __rmul__(self, other):
- return self.reverse_operate(operators.mul, other)
-
- def __rdiv__(self, other):
- return self.reverse_operate(operators.div, other)
-
- def between(self, cleft, cright):
- return self.operate(operators.between_op, cleft, cright)
-
- def distinct(self):
- return self.operate(operators.distinct_op)
-
- def __add__(self, other):
- return self.operate(operators.add, other)
-
- def __sub__(self, other):
- return self.operate(operators.sub, other)
-
- def __mul__(self, other):
- return self.operate(operators.mul, other)
-
- def __div__(self, other):
- return self.operate(operators.div, other)
-
- def __mod__(self, other):
- return self.operate(operators.mod, other)
-
- def __truediv__(self, other):
- return self.operate(operators.truediv, other)
-
- def __rtruediv__(self, other):
- return self.reverse_operate(operators.truediv, other)
-
-class _CompareMixin(ColumnOperators):
- """Defines comparison and math operations for :class:`.ClauseElement`
- instances."""
-
- def __compare(self, op, obj, negate=None, reverse=False,
- **kwargs
- ):
- if obj is None or isinstance(obj, _Null):
- if op == operators.eq:
- return _BinaryExpression(self, null(), operators.is_,
- negate=operators.isnot)
- elif op == operators.ne:
- return _BinaryExpression(self, null(), operators.isnot,
- negate=operators.is_)
- else:
- raise exc.ArgumentError("Only '='/'!=' operators can "
- "be used with NULL")
- else:
- obj = self._check_literal(op, obj)
-
- if reverse:
- return _BinaryExpression(obj,
- self,
- op,
- type_=sqltypes.BOOLEANTYPE,
- negate=negate, modifiers=kwargs)
- else:
- return _BinaryExpression(self,
- obj,
- op,
- type_=sqltypes.BOOLEANTYPE,
- negate=negate, modifiers=kwargs)
-
- def __operate(self, op, obj, reverse=False):
- obj = self._check_literal(op, obj)
-
- if reverse:
- left, right = obj, self
- else:
- left, right = self, obj
-
- if left.type is None:
- op, result_type = sqltypes.NULLTYPE._adapt_expression(op,
- right.type)
- elif right.type is None:
- op, result_type = left.type._adapt_expression(op,
- sqltypes.NULLTYPE)
- else:
- op, result_type = left.type._adapt_expression(op,
- right.type)
- return _BinaryExpression(left, right, op, type_=result_type)
-
-
- # a mapping of operators with the method they use, along with their negated
- # operator for comparison operators
- operators = {
- operators.add : (__operate,),
- operators.mul : (__operate,),
- operators.sub : (__operate,),
- # Py2K
- operators.div : (__operate,),
- # end Py2K
- operators.mod : (__operate,),
- operators.truediv : (__operate,),
- operators.lt : (__compare, operators.ge),
- operators.le : (__compare, operators.gt),
- operators.ne : (__compare, operators.eq),
- operators.gt : (__compare, operators.le),
- operators.ge : (__compare, operators.lt),
- operators.eq : (__compare, operators.ne),
- operators.like_op : (__compare, operators.notlike_op),
- operators.ilike_op : (__compare, operators.notilike_op),
- }
-
- def operate(self, op, *other, **kwargs):
- o = _CompareMixin.operators[op]
- return o[0](self, op, other[0], *o[1:], **kwargs)
-
- def reverse_operate(self, op, other, **kwargs):
- o = _CompareMixin.operators[op]
- return o[0](self, op, other, reverse=True, *o[1:], **kwargs)
-
- def in_(self, other):
- """Compare this element to the given element or collection using IN."""
-
- return self._in_impl(operators.in_op, operators.notin_op, other)
-
- def _in_impl(self, op, negate_op, seq_or_selectable):
- seq_or_selectable = _clause_element_as_expr(seq_or_selectable)
-
- if isinstance(seq_or_selectable, _ScalarSelect):
- return self.__compare(op, seq_or_selectable,
- negate=negate_op)
- elif isinstance(seq_or_selectable, _SelectBase):
-
- # TODO: if we ever want to support (x, y, z) IN (select x,
- # y, z from table), we would need a multi-column version of
- # as_scalar() to produce a multi- column selectable that
- # does not export itself as a FROM clause
-
- return self.__compare(op, seq_or_selectable.as_scalar(),
- negate=negate_op)
- elif isinstance(seq_or_selectable, (Selectable, _TextClause)):
- return self.__compare(op, seq_or_selectable,
- negate=negate_op)
-
-
- # Handle non selectable arguments as sequences
-
- args = []
- for o in seq_or_selectable:
- if not _is_literal(o):
- if not isinstance(o, _CompareMixin):
- raise exc.InvalidRequestError('in() function accept'
- 's either a list of non-selectable values, '
- 'or a selectable: %r' % o)
- else:
- o = self._bind_param(op, o)
- args.append(o)
- if len(args) == 0:
-
- # Special case handling for empty IN's, behave like
- # comparison against zero row selectable. We use != to
- # build the contradiction as it handles NULL values
- # appropriately, i.e. "not (x IN ())" should not return NULL
- # values for x.
-
- util.warn('The IN-predicate on "%s" was invoked with an '
- 'empty sequence. This results in a '
- 'contradiction, which nonetheless can be '
- 'expensive to evaluate. Consider alternative '
- 'strategies for improved performance.' % self)
- return self != self
-
- return self.__compare(op,
- ClauseList(*args).self_group(against=op),
- negate=negate_op)
-
- def __neg__(self):
- return _UnaryExpression(self, operator=operators.neg)
-
- def startswith(self, other, escape=None):
- """Produce the clause ``LIKE '<other>%'``"""
-
- # use __radd__ to force string concat behavior
- return self.__compare(
- operators.like_op,
- literal_column("'%'", type_=sqltypes.String).__radd__(
- self._check_literal(operators.like_op, other)
- ),
- escape=escape)
-
- def endswith(self, other, escape=None):
- """Produce the clause ``LIKE '%<other>'``"""
-
- return self.__compare(
- operators.like_op,
- literal_column("'%'", type_=sqltypes.String) +
- self._check_literal(operators.like_op, other),
- escape=escape)
-
- def contains(self, other, escape=None):
- """Produce the clause ``LIKE '%<other>%'``"""
-
- return self.__compare(
- operators.like_op,
- literal_column("'%'", type_=sqltypes.String) +
- self._check_literal(operators.like_op, other) +
- literal_column("'%'", type_=sqltypes.String),
- escape=escape)
-
- def match(self, other):
- """Produce a MATCH clause, i.e. ``MATCH '<other>'``
-
- The allowed contents of ``other`` are database backend specific.
-
- """
- return self.__compare(operators.match_op,
- self._check_literal(operators.match_op,
- other))
-
- def label(self, name):
- """Produce a column label, i.e. ``<columnname> AS <name>``.
-
- This is a shortcut to the :func:`~.expression.label` function.
-
- if 'name' is None, an anonymous label name will be generated.
-
- """
- return _Label(name, self, self.type)
-
- def desc(self):
- """Produce a DESC clause, i.e. ``<columnname> DESC``"""
-
- return desc(self)
-
- def asc(self):
- """Produce a ASC clause, i.e. ``<columnname> ASC``"""
-
- return asc(self)
-
- def nullsfirst(self):
- """Produce a NULLS FIRST clause, i.e. ``NULLS FIRST``"""
-
- return nullsfirst(self)
-
- def nullslast(self):
- """Produce a NULLS LAST clause, i.e. ``NULLS LAST``"""
-
- return nullslast(self)
-
- def distinct(self):
- """Produce a DISTINCT clause, i.e. ``DISTINCT <columnname>``"""
-
- return _UnaryExpression(self, operator=operators.distinct_op,
- type_=self.type)
-
- def between(self, cleft, cright):
- """Produce a BETWEEN clause, i.e. ``<column> BETWEEN <cleft> AND
- <cright>``"""
-
- return _BinaryExpression(
- self,
- ClauseList(
- self._check_literal(operators.and_, cleft),
- self._check_literal(operators.and_, cright),
- operator=operators.and_,
- group=False),
- operators.between_op)
-
- def collate(self, collation):
- """Produce a COLLATE clause, i.e. ``<column> COLLATE utf8_bin``"""
-
- return collate(self, collation)
-
- def op(self, operator):
- """produce a generic operator function.
-
- e.g.::
-
- somecolumn.op("*")(5)
-
- produces::
-
- somecolumn * 5
-
- :param operator: a string which will be output as the infix operator
- between this :class:`.ClauseElement` and the expression passed to the
- generated function.
-
- This function can also be used to make bitwise operators explicit. For
- example::
-
- somecolumn.op('&')(0xff)
-
- is a bitwise AND of the value in somecolumn.
-
- """
- return lambda other: self.__operate(operator, other)
-
- def _bind_param(self, operator, obj):
- return _BindParamClause(None, obj,
- _compared_to_operator=operator,
- _compared_to_type=self.type, unique=True)
-
- def _check_literal(self, operator, other):
- if isinstance(other, _BindParamClause) and \
- isinstance(other.type, sqltypes.NullType):
- # TODO: perhaps we should not mutate the incoming bindparam()
- # here and instead make a copy of it. this might
- # be the only place that we're mutating an incoming construct.
- other.type = self.type
- return other
- elif hasattr(other, '__clause_element__'):
- return other.__clause_element__()
- elif not isinstance(other, ClauseElement):
- return self._bind_param(operator, other)
- elif isinstance(other, (_SelectBase, Alias)):
- return other.as_scalar()
- else:
- return other
-
-
-class ColumnElement(ClauseElement, _CompareMixin):
- """Represent an element that is usable within the "column clause" portion
- of a ``SELECT`` statement.
-
- This includes columns associated with tables, aliases, and
- subqueries, expressions, function calls, SQL keywords such as
- ``NULL``, literals, etc. :class:`.ColumnElement` is the ultimate base
- class for all such elements.
-
- :class:`.ColumnElement` supports the ability to be a *proxy* element,
- which indicates that the :class:`.ColumnElement` may be associated with
- a :class:`.Selectable` which was derived from another :class:`.Selectable`.
- An example of a "derived" :class:`.Selectable` is an :class:`.Alias` of a
- :class:`~sqlalchemy.schema.Table`.
-
- A :class:`.ColumnElement`, by subclassing the :class:`_CompareMixin` mixin
- class, provides the ability to generate new :class:`.ClauseElement`
- objects using Python expressions. See the :class:`_CompareMixin`
- docstring for more details.
-
- """
-
- __visit_name__ = 'column'
- primary_key = False
- foreign_keys = []
- quote = None
- _label = None
-
- @property
- def _select_iterable(self):
- return (self, )
-
- @util.memoized_property
- def base_columns(self):
- return util.column_set(c for c in self.proxy_set
- if not hasattr(c, 'proxies'))
-
- @util.memoized_property
- def proxy_set(self):
- s = util.column_set([self])
- if hasattr(self, 'proxies'):
- for c in self.proxies:
- s.update(c.proxy_set)
- return s
-
- def shares_lineage(self, othercolumn):
- """Return True if the given :class:`.ColumnElement`
- has a common ancestor to this :class:`.ColumnElement`."""
-
- return bool(self.proxy_set.intersection(othercolumn.proxy_set))
-
- def _make_proxy(self, selectable, name=None):
- """Create a new :class:`.ColumnElement` representing this
- :class:`.ColumnElement` as it appears in the select list of a
- descending selectable.
-
- """
- if name is None:
- name = self.anon_label
- # TODO: may want to change this to anon_label,
- # or some value that is more useful than the
- # compiled form of the expression
- key = str(self)
- else:
- key = name
-
- co = ColumnClause(name, selectable, type_=getattr(self,
- 'type', None))
- co.proxies = [self]
- selectable._columns[key] = co
- return co
-
- def compare(self, other, use_proxies=False, equivalents=None, **kw):
- """Compare this ColumnElement to another.
-
- Special arguments understood:
-
- :param use_proxies: when True, consider two columns that
- share a common base column as equivalent (i.e. shares_lineage())
-
- :param equivalents: a dictionary of columns as keys mapped to sets
- of columns. If the given "other" column is present in this
- dictionary, if any of the columns in the correponding set() pass the
- comparison test, the result is True. This is used to expand the
- comparison to other columns that may be known to be equivalent to
- this one via foreign key or other criterion.
-
- """
- to_compare = (other, )
- if equivalents and other in equivalents:
- to_compare = equivalents[other].union(to_compare)
-
- for oth in to_compare:
- if use_proxies and self.shares_lineage(oth):
- return True
- elif oth is self:
- return True
- else:
- return False
-
- @util.memoized_property
- def anon_label(self):
- """provides a constant 'anonymous label' for this ColumnElement.
-
- This is a label() expression which will be named at compile time.
- The same label() is returned each time anon_label is called so
- that expressions can reference anon_label multiple times, producing
- the same label name at compile time.
-
- the compiler uses this function automatically at compile time
- for expressions that are known to be 'unnamed' like binary
- expressions and function calls.
-
- """
- return _generated_label('%%(%d %s)s' % (id(self), getattr(self,
- 'name', 'anon')))
-
-class ColumnCollection(util.OrderedProperties):
- """An ordered dictionary that stores a list of ColumnElement
- instances.
-
- Overrides the ``__eq__()`` method to produce SQL clauses between
- sets of correlated columns.
-
- """
-
- def __init__(self, *cols):
- super(ColumnCollection, self).__init__()
- self._data.update((c.key, c) for c in cols)
- self.__dict__['_all_cols'] = util.column_set(self)
-
- def __str__(self):
- return repr([str(c) for c in self])
-
- def replace(self, column):
- """add the given column to this collection, removing unaliased
- versions of this column as well as existing columns with the
- same key.
-
- e.g.::
-
- t = Table('sometable', metadata, Column('col1', Integer))
- t.columns.replace(Column('col1', Integer, key='columnone'))
-
- will remove the original 'col1' from the collection, and add
- the new column under the name 'columnname'.
-
- Used by schema.Column to override columns during table reflection.
-
- """
- if column.name in self and column.key != column.name:
- other = self[column.name]
- if other.name == other.key:
- del self._data[other.name]
- self._all_cols.remove(other)
- if column.key in self._data:
- self._all_cols.remove(self._data[column.key])
- self._all_cols.add(column)
- self._data[column.key] = column
-
- def add(self, column):
- """Add a column to this collection.
-
- The key attribute of the column will be used as the hash key
- for this dictionary.
-
- """
- self[column.key] = column
-
- def __delitem__(self, key):
- raise NotImplementedError()
-
- def __setattr__(self, key, object):
- raise NotImplementedError()
-
- def __setitem__(self, key, value):
- if key in self:
-
- # this warning is primarily to catch select() statements
- # which have conflicting column names in their exported
- # columns collection
-
- existing = self[key]
- if not existing.shares_lineage(value):
- util.warn('Column %r on table %r being replaced by '
- 'another column with the same key. Consider '
- 'use_labels for select() statements.' % (key,
- getattr(existing, 'table', None)))
- self._all_cols.remove(existing)
- self._all_cols.add(value)
- self._data[key] = value
-
- def clear(self):
- self._data.clear()
- self._all_cols.clear()
-
- def remove(self, column):
- del self._data[column.key]
- self._all_cols.remove(column)
-
- def update(self, value):
- self._data.update(value)
- self._all_cols.clear()
- self._all_cols.update(self._data.values())
-
- def extend(self, iter):
- self.update((c.key, c) for c in iter)
-
- __hash__ = None
-
- def __eq__(self, other):
- l = []
- for c in other:
- for local in self:
- if c.shares_lineage(local):
- l.append(c==local)
- return and_(*l)
-
- def __contains__(self, other):
- if not isinstance(other, basestring):
- raise exc.ArgumentError("__contains__ requires a string argument")
- return util.OrderedProperties.__contains__(self, other)
-
- def __setstate__(self, state):
- self.__dict__['_data'] = state['_data']
- self.__dict__['_all_cols'] = util.column_set(self._data.values())
-
- def contains_column(self, col):
- # this has to be done via set() membership
- return col in self._all_cols
-
- def as_immutable(self):
- return ImmutableColumnCollection(self._data, self._all_cols)
-
-class ImmutableColumnCollection(util.ImmutableProperties, ColumnCollection):
- def __init__(self, data, colset):
- util.ImmutableProperties.__init__(self, data)
- self.__dict__['_all_cols'] = colset
-
- extend = remove = util.ImmutableProperties._immutable
-
-
-class ColumnSet(util.ordered_column_set):
- def contains_column(self, col):
- return col in self
-
- def extend(self, cols):
- for col in cols:
- self.add(col)
-
- def __add__(self, other):
- return list(self) + list(other)
-
- def __eq__(self, other):
- l = []
- for c in other:
- for local in self:
- if c.shares_lineage(local):
- l.append(c==local)
- return and_(*l)
-
- def __hash__(self):
- return hash(tuple(x for x in self))
-
-class Selectable(ClauseElement):
- """mark a class as being selectable"""
- __visit_name__ = 'selectable'
-
-class FromClause(Selectable):
- """Represent an element that can be used within the ``FROM``
- clause of a ``SELECT`` statement.
-
- """
- __visit_name__ = 'fromclause'
- named_with_column = False
- _hide_froms = []
- quote = None
- schema = None
-
- def count(self, whereclause=None, **params):
- """return a SELECT COUNT generated against this
- :class:`.FromClause`."""
-
- if self.primary_key:
- col = list(self.primary_key)[0]
- else:
- col = list(self.columns)[0]
- return select(
- [func.count(col).label('tbl_row_count')],
- whereclause,
- from_obj=[self],
- **params)
-
- def select(self, whereclause=None, **params):
- """return a SELECT of this :class:`.FromClause`."""
-
- return select([self], whereclause, **params)
-
- def join(self, right, onclause=None, isouter=False):
- """return a join of this :class:`.FromClause` against another
- :class:`.FromClause`."""
-
- return Join(self, right, onclause, isouter)
-
- def outerjoin(self, right, onclause=None):
- """return an outer join of this :class:`.FromClause` against another
- :class:`.FromClause`."""
-
- return Join(self, right, onclause, True)
-
- def alias(self, name=None):
- """return an alias of this :class:`.FromClause`.
-
- This is shorthand for calling::
-
- from sqlalchemy import alias
- a = alias(self, name=name)
-
- See :func:`~.expression.alias` for details.
-
- """
-
- return Alias(self, name)
-
- def is_derived_from(self, fromclause):
- """Return True if this FromClause is 'derived' from the given
- FromClause.
-
- An example would be an Alias of a Table is derived from that Table.
-
- """
- return fromclause in self._cloned_set
-
- def replace_selectable(self, old, alias):
- """replace all occurrences of FromClause 'old' with the given Alias
- object, returning a copy of this :class:`.FromClause`.
-
- """
-
- return sqlutil.ClauseAdapter(alias).traverse(self)
-
- def correspond_on_equivalents(self, column, equivalents):
- """Return corresponding_column for the given column, or if None
- search for a match in the given dictionary.
-
- """
- col = self.corresponding_column(column, require_embedded=True)
- if col is None and col in equivalents:
- for equiv in equivalents[col]:
- nc = self.corresponding_column(equiv, require_embedded=True)
- if nc:
- return nc
- return col
-
- def corresponding_column(self, column, require_embedded=False):
- """Given a :class:`.ColumnElement`, return the exported
- :class:`.ColumnElement` object from this :class:`.Selectable`
- which corresponds to that original
- :class:`~sqlalchemy.schema.Column` via a common anscestor
- column.
-
- :param column: the target :class:`.ColumnElement` to be matched
-
- :param require_embedded: only return corresponding columns for
- the given :class:`.ColumnElement`, if the given
- :class:`.ColumnElement` is actually present within a sub-element
- of this :class:`.FromClause`. Normally the column will match if
- it merely shares a common anscestor with one of the exported
- columns of this :class:`.FromClause`.
-
- """
-
- # dont dig around if the column is locally present
-
- if self.c.contains_column(column):
- return column
- col, intersect = None, None
- target_set = column.proxy_set
- cols = self.c
- for c in cols:
- i = target_set.intersection(itertools.chain(*[p._cloned_set
- for p in c.proxy_set]))
- if i and (not require_embedded
- or c.proxy_set.issuperset(target_set)):
- if col is None:
-
- # no corresponding column yet, pick this one.
-
- col, intersect = c, i
- elif len(i) > len(intersect):
-
- # 'c' has a larger field of correspondence than
- # 'col'. i.e. selectable.c.a1_x->a1.c.x->table.c.x
- # matches a1.c.x->table.c.x better than
- # selectable.c.x->table.c.x does.
-
- col, intersect = c, i
- elif i == intersect:
-
- # they have the same field of correspondence. see
- # which proxy_set has fewer columns in it, which
- # indicates a closer relationship with the root
- # column. Also take into account the "weight"
- # attribute which CompoundSelect() uses to give
- # higher precedence to columns based on vertical
- # position in the compound statement, and discard
- # columns that have no reference to the target
- # column (also occurs with CompoundSelect)
-
- col_distance = util.reduce(operator.add,
- [sc._annotations.get('weight', 1) for sc in
- col.proxy_set if sc.shares_lineage(column)])
- c_distance = util.reduce(operator.add,
- [sc._annotations.get('weight', 1) for sc in
- c.proxy_set if sc.shares_lineage(column)])
- if c_distance < col_distance:
- col, intersect = c, i
- return col
-
- @property
- def description(self):
- """a brief description of this FromClause.
-
- Used primarily for error message formatting.
-
- """
- return getattr(self, 'name', self.__class__.__name__ + " object")
-
- def _reset_exported(self):
- """delete memoized collections when a FromClause is cloned."""
-
- for name in 'primary_key', '_columns', 'columns', \
- 'foreign_keys', 'locate_all_froms':
- self.__dict__.pop(name, None)
-
- @util.memoized_property
- def columns(self):
- """Return the collection of Column objects contained by this
- FromClause."""
-
- if '_columns' not in self.__dict__:
- self._init_collections()
- self._populate_column_collection()
- return self._columns.as_immutable()
-
- @util.memoized_property
- def primary_key(self):
- """Return the collection of Column objects which comprise the
- primary key of this FromClause."""
-
- self._init_collections()
- self._populate_column_collection()
- return self.primary_key
-
- @util.memoized_property
- def foreign_keys(self):
- """Return the collection of ForeignKey objects which this
- FromClause references."""
-
- self._init_collections()
- self._populate_column_collection()
- return self.foreign_keys
-
- c = property(attrgetter('columns'))
- _select_iterable = property(attrgetter('columns'))
-
- def _init_collections(self):
- assert '_columns' not in self.__dict__
- assert 'primary_key' not in self.__dict__
- assert 'foreign_keys' not in self.__dict__
-
- self._columns = ColumnCollection()
- self.primary_key = ColumnSet()
- self.foreign_keys = set()
-
- def _populate_column_collection(self):
- pass
-
-class _BindParamClause(ColumnElement):
- """Represent a bind parameter.
-
- Public constructor is the :func:`bindparam()` function.
-
- """
-
- __visit_name__ = 'bindparam'
- quote = None
-
- def __init__(self, key, value, type_=None, unique=False,
- callable_=None,
- isoutparam=False, required=False,
- _compared_to_operator=None,
- _compared_to_type=None):
- """Construct a _BindParamClause.
-
- :param key:
- the key for this bind param. Will be used in the generated
- SQL statement for dialects that use named parameters. This
- value may be modified when part of a compilation operation,
- if other :class:`_BindParamClause` objects exist with the same
- key, or if its length is too long and truncation is
- required.
-
- :param value:
- Initial value for this bind param. This value may be
- overridden by the dictionary of parameters sent to statement
- compilation/execution.
-
- :param callable\_:
- A callable function that takes the place of "value". The function
- will be called at statement execution time to determine the
- ultimate value. Used for scenarios where the actual bind
- value cannot be determined at the point at which the clause
- construct is created, but embeded bind values are still desirable.
-
- :param type\_:
- A ``TypeEngine`` object that will be used to pre-process the
- value corresponding to this :class:`_BindParamClause` at
- execution time.
-
- :param unique:
- if True, the key name of this BindParamClause will be
- modified if another :class:`_BindParamClause` of the same name
- already has been located within the containing
- :class:`.ClauseElement`.
-
- :param required:
- a value is required at execution time.
-
- :param isoutparam:
- if True, the parameter should be treated like a stored procedure
- "OUT" parameter.
-
- """
- if unique:
- self.key = _generated_label('%%(%d %s)s' % (id(self), key
- or 'param'))
- else:
- self.key = key or _generated_label('%%(%d param)s'
- % id(self))
- self._orig_key = key or 'param'
- self.unique = unique
- self.value = value
- self.callable = callable_
- self.isoutparam = isoutparam
- self.required = required
- if type_ is None:
- if _compared_to_type is not None:
- self.type = \
- _compared_to_type._coerce_compared_value(
- _compared_to_operator, value)
- else:
- self.type = sqltypes._type_map.get(type(value),
- sqltypes.NULLTYPE)
- elif isinstance(type_, type):
- self.type = type_()
- else:
- self.type = type_
-
- def _clone(self):
- c = ClauseElement._clone(self)
- if self.unique:
- c.key = _generated_label('%%(%d %s)s' % (id(c), c._orig_key
- or 'param'))
- return c
-
- def _convert_to_unique(self):
- if not self.unique:
- self.unique = True
- self.key = _generated_label('%%(%d %s)s' % (id(self),
- self._orig_key or 'param'))
-
- def compare(self, other, **kw):
- """Compare this :class:`_BindParamClause` to the given
- clause."""
-
- return isinstance(other, _BindParamClause) \
- and self.type._compare_type_affinity(other.type) \
- and self.value == other.value
-
- def __getstate__(self):
- """execute a deferred value for serialization purposes."""
-
- d = self.__dict__.copy()
- v = self.value
- if self.callable:
- v = self.callable()
- d['callable'] = None
- d['value'] = v
- return d
-
- def __repr__(self):
- return '_BindParamClause(%r, %r, type_=%r)' % (self.key,
- self.value, self.type)
-
-class _TypeClause(ClauseElement):
- """Handle a type keyword in a SQL statement.
-
- Used by the ``Case`` statement.
-
- """
-
- __visit_name__ = 'typeclause'
-
- def __init__(self, type):
- self.type = type
-
-
-class _Generative(object):
- """Allow a ClauseElement to generate itself via the
- @_generative decorator.
-
- """
-
- def _generate(self):
- s = self.__class__.__new__(self.__class__)
- s.__dict__ = self.__dict__.copy()
- return s
-
-
-class Executable(_Generative):
- """Mark a ClauseElement as supporting execution.
-
- :class:`.Executable` is a superclass for all "statement" types
- of objects, including :func:`select`, :func:`delete`, :func:`update`,
- :func:`insert`, :func:`text`.
-
- """
-
- supports_execution = True
- _execution_options = util.immutabledict()
- _bind = None
-
- @_generative
- def execution_options(self, **kw):
- """ Set non-SQL options for the statement which take effect during
- execution.
-
- Execution options can be set on a per-statement or
- per :class:`.Connection` basis. Additionally, the
- :class:`.Engine` and ORM :class:`~.orm.query.Query` objects provide access
- to execution options which they in turn configure upon connections.
-
- The :meth:`execution_options` method is generative. A new
- instance of this statement is returned that contains the options::
-
- statement = select([table.c.x, table.c.y])
- statement = statement.execution_options(autocommit=True)
-
- Note that only a subset of possible execution options can be applied
- to a statement - these include "autocommit" and "stream_results",
- but not "isolation_level" or "compiled_cache".
- See :meth:`.Connection.execution_options` for a full list of
- possible options.
-
- See also:
-
- :meth:`.Connection.execution_options()`
-
- :meth:`.Query.execution_options()`
-
- """
- if 'isolation_level' in kw:
- raise exc.ArgumentError(
- "'isolation_level' execution option may only be specified "
- "on Connection.execution_options(), or "
- "per-engine using the isolation_level "
- "argument to create_engine()."
- )
- if 'compiled_cache' in kw:
- raise exc.ArgumentError(
- "'compiled_cache' execution option may only be specified "
- "on Connection.execution_options(), not per statement."
- )
- self._execution_options = self._execution_options.union(kw)
-
- def execute(self, *multiparams, **params):
- """Compile and execute this :class:`.Executable`."""
-
- e = self.bind
- if e is None:
- label = getattr(self, 'description', self.__class__.__name__)
- msg = ('This %s is not directly bound to a Connection or Engine.'
- 'Use the .execute() method of a Connection or Engine '
- 'to execute this construct.' % label)
- raise exc.UnboundExecutionError(msg)
- return e._execute_clauseelement(self, multiparams, params)
-
- def scalar(self, *multiparams, **params):
- """Compile and execute this :class:`.Executable`, returning the
- result's scalar representation.
-
- """
- return self.execute(*multiparams, **params).scalar()
-
- @property
- def bind(self):
- """Returns the :class:`.Engine` or :class:`.Connection` to
- which this :class:`.Executable` is bound, or None if none found.
-
- This is a traversal which checks locally, then
- checks among the "from" clauses of associated objects
- until a bound engine or connection is found.
-
- """
- if self._bind is not None:
- return self._bind
-
- for f in _from_objects(self):
- if f is self:
- continue
- engine = f.bind
- if engine is not None:
- return engine
- else:
- return None
-
-
-# legacy, some outside users may be calling this
-_Executable = Executable
-
-class _TextClause(Executable, ClauseElement):
- """Represent a literal SQL text fragment.
-
- Public constructor is the :func:`text()` function.
-
- """
-
- __visit_name__ = 'textclause'
-
- _bind_params_regex = re.compile(r'(?<![:\w\x5c]):(\w+)(?!:)', re.UNICODE)
- _execution_options = \
- Executable._execution_options.union({'autocommit'
- : PARSE_AUTOCOMMIT})
-
- @property
- def _select_iterable(self):
- return (self,)
-
- _hide_froms = []
-
- def __init__(
- self,
- text='',
- bind=None,
- bindparams=None,
- typemap=None,
- autocommit=None,
- ):
- self._bind = bind
- self.bindparams = {}
- self.typemap = typemap
- if autocommit is not None:
- util.warn_deprecated('autocommit on text() is deprecated. '
- 'Use .execution_options(autocommit=Tru'
- 'e)')
- self._execution_options = \
- self._execution_options.union({'autocommit'
- : autocommit})
- if typemap is not None:
- for key in typemap.keys():
- typemap[key] = sqltypes.to_instance(typemap[key])
-
- def repl(m):
- self.bindparams[m.group(1)] = bindparam(m.group(1))
- return ':%s' % m.group(1)
-
- # scan the string and search for bind parameter names, add them
- # to the list of bindparams
-
- self.text = self._bind_params_regex.sub(repl, text)
- if bindparams is not None:
- for b in bindparams:
- self.bindparams[b.key] = b
-
- @property
- def type(self):
- if self.typemap is not None and len(self.typemap) == 1:
- return list(self.typemap)[0]
- else:
- return sqltypes.NULLTYPE
-
- def self_group(self, against=None):
- if against is operators.in_op:
- return _Grouping(self)
- else:
- return self
-
- def _copy_internals(self, clone=_clone):
- self.bindparams = dict((b.key, clone(b))
- for b in self.bindparams.values())
-
- def get_children(self, **kwargs):
- return self.bindparams.values()
-
-
-class _Null(ColumnElement):
- """Represent the NULL keyword in a SQL statement.
-
- Public constructor is the :func:`null()` function.
-
- """
-
- __visit_name__ = 'null'
- def __init__(self):
- self.type = sqltypes.NULLTYPE
-
-class _False(ColumnElement):
- """Represent the ``false`` keyword in a SQL statement.
-
- Public constructor is the :func:`false()` function.
-
- """
-
- __visit_name__ = 'false'
- def __init__(self):
- self.type = sqltypes.BOOLEANTYPE
-
-class _True(ColumnElement):
- """Represent the ``true`` keyword in a SQL statement.
-
- Public constructor is the :func:`true()` function.
-
- """
-
- __visit_name__ = 'true'
- def __init__(self):
- self.type = sqltypes.BOOLEANTYPE
-
-
-class ClauseList(ClauseElement):
- """Describe a list of clauses, separated by an operator.
-
- By default, is comma-separated, such as a column listing.
-
- """
- __visit_name__ = 'clauselist'
-
- def __init__(self, *clauses, **kwargs):
- self.operator = kwargs.pop('operator', operators.comma_op)
- self.group = kwargs.pop('group', True)
- self.group_contents = kwargs.pop('group_contents', True)
- if self.group_contents:
- self.clauses = [
- _literal_as_text(clause).self_group(against=self.operator)
- for clause in clauses if clause is not None]
- else:
- self.clauses = [
- _literal_as_text(clause)
- for clause in clauses if clause is not None]
-
- @util.memoized_property
- def type(self):
- if self.clauses:
- return self.clauses[0].type
- else:
- return sqltypes.NULLTYPE
-
- def __iter__(self):
- return iter(self.clauses)
-
- def __len__(self):
- return len(self.clauses)
-
- @property
- def _select_iterable(self):
- return iter(self)
-
- def append(self, clause):
- # TODO: not sure if i like the 'group_contents' flag. need to
- # define the difference between a ClauseList of ClauseLists,
- # and a "flattened" ClauseList of ClauseLists. flatten()
- # method ?
- if self.group_contents:
- self.clauses.append(_literal_as_text(clause).\
- self_group(against=self.operator))
- else:
- self.clauses.append(_literal_as_text(clause))
-
- def _copy_internals(self, clone=_clone):
- self.clauses = [clone(clause) for clause in self.clauses]
-
- def get_children(self, **kwargs):
- return self.clauses
-
- @property
- def _from_objects(self):
- return list(itertools.chain(*[c._from_objects for c in self.clauses]))
-
- def self_group(self, against=None):
- if self.group and operators.is_precedent(self.operator, against):
- return _Grouping(self)
- else:
- return self
-
- def compare(self, other, **kw):
- """Compare this :class:`.ClauseList` to the given :class:`.ClauseList`,
- including a comparison of all the clause items.
-
- """
- if not isinstance(other, ClauseList) and len(self.clauses) == 1:
- return self.clauses[0].compare(other, **kw)
- elif isinstance(other, ClauseList) and \
- len(self.clauses) == len(other.clauses):
- for i in range(0, len(self.clauses)):
- if not self.clauses[i].compare(other.clauses[i], **kw):
- return False
- else:
- return self.operator == other.operator
- else:
- return False
-
-class BooleanClauseList(ClauseList, ColumnElement):
- __visit_name__ = 'clauselist'
-
- def __init__(self, *clauses, **kwargs):
- super(BooleanClauseList, self).__init__(*clauses, **kwargs)
- self.type = sqltypes.to_instance(kwargs.get('type_',
- sqltypes.Boolean))
-
- @property
- def _select_iterable(self):
- return (self, )
-
-class _Tuple(ClauseList, ColumnElement):
-
- def __init__(self, *clauses, **kw):
- clauses = [_literal_as_binds(c) for c in clauses]
- super(_Tuple, self).__init__(*clauses, **kw)
- self.type = _type_from_args(clauses)
-
- @property
- def _select_iterable(self):
- return (self, )
-
- def _bind_param(self, operator, obj):
- return _Tuple(*[
- _BindParamClause(None, o, _compared_to_operator=operator,
- _compared_to_type=self.type, unique=True)
- for o in obj
- ]).self_group()
-
-
-class _Case(ColumnElement):
- __visit_name__ = 'case'
-
- def __init__(self, whens, value=None, else_=None):
- try:
- whens = util.dictlike_iteritems(whens)
- except TypeError:
- pass
-
- if value is not None:
- whenlist = [
- (_literal_as_binds(c).self_group(),
- _literal_as_binds(r)) for (c, r) in whens
- ]
- else:
- whenlist = [
- (_no_literals(c).self_group(),
- _literal_as_binds(r)) for (c, r) in whens
- ]
-
- if whenlist:
- type_ = list(whenlist[-1])[-1].type
- else:
- type_ = None
-
- if value is None:
- self.value = None
- else:
- self.value = _literal_as_binds(value)
-
- self.type = type_
- self.whens = whenlist
- if else_ is not None:
- self.else_ = _literal_as_binds(else_)
- else:
- self.else_ = None
-
- def _copy_internals(self, clone=_clone):
- if self.value is not None:
- self.value = clone(self.value)
- self.whens = [(clone(x), clone(y)) for x, y in self.whens]
- if self.else_ is not None:
- self.else_ = clone(self.else_)
-
- def get_children(self, **kwargs):
- if self.value is not None:
- yield self.value
- for x, y in self.whens:
- yield x
- yield y
- if self.else_ is not None:
- yield self.else_
-
- @property
- def _from_objects(self):
- return list(itertools.chain(*[x._from_objects for x in
- self.get_children()]))
-
-class FunctionElement(Executable, ColumnElement, FromClause):
- """Base for SQL function-oriented constructs."""
-
- packagenames = ()
-
- def __init__(self, *clauses, **kwargs):
- """Construct a :class:`.FunctionElement`.
- """
- args = [_literal_as_binds(c, self.name) for c in clauses]
- self.clause_expr = ClauseList(
- operator=operators.comma_op,
- group_contents=True, *args).\
- self_group()
-
- @property
- def columns(self):
- """Fulfill the 'columns' contrct of :class:`.ColumnElement`.
-
- Returns a single-element list consisting of this object.
-
- """
- return [self]
-
- @util.memoized_property
- def clauses(self):
- """Return the underlying :class:`.ClauseList` which contains
- the arguments for this :class:`.FunctionElement`.
-
- """
- return self.clause_expr.element
-
- def over(self, partition_by=None, order_by=None):
- """Produce an OVER clause against this function.
-
- Used against aggregate or so-called "window" functions,
- for database backends that support window functions.
-
- The expression::
-
- func.row_number().over(order_by='x')
-
- is shorthand for::
-
- from sqlalchemy import over
- over(func.row_number(), order_by='x')
-
- See :func:`~.expression.over` for a full description.
-
- New in 0.7.
-
- """
- return over(self, partition_by=partition_by, order_by=order_by)
-
- @property
- def _from_objects(self):
- return self.clauses._from_objects
-
- def get_children(self, **kwargs):
- return self.clause_expr,
-
- def _copy_internals(self, clone=_clone):
- self.clause_expr = clone(self.clause_expr)
- self._reset_exported()
- util.reset_memoized(self, 'clauses')
-
- def select(self):
- """Produce a :func:`~.expression.select` construct
- against this :class:`.FunctionElement`.
-
- This is shorthand for::
-
- s = select([function_element])
-
- """
- s = select([self])
- if self._execution_options:
- s = s.execution_options(**self._execution_options)
- return s
-
- def scalar(self):
- """Execute this :class:`.FunctionElement` against an embedded
- 'bind' and return a scalar value.
-
- This first calls :meth:`~.FunctionElement.select` to
- produce a SELECT construct.
-
- Note that :class:`.FunctionElement` can be passed to
- the :meth:`.Connectable.scalar` method of :class:`.Connection`
- or :class:`.Engine`.
-
- """
- return self.select().execute().scalar()
-
- def execute(self):
- """Execute this :class:`.FunctionElement` against an embedded
- 'bind'.
-
- This first calls :meth:`~.FunctionElement.select` to
- produce a SELECT construct.
-
- Note that :class:`.FunctionElement` can be passed to
- the :meth:`.Connectable.execute` method of :class:`.Connection`
- or :class:`.Engine`.
-
- """
- return self.select().execute()
-
- def _bind_param(self, operator, obj):
- return _BindParamClause(None, obj, _compared_to_operator=operator,
- _compared_to_type=self.type, unique=True)
-
-
-class Function(FunctionElement):
- """Describe a named SQL function.
-
- See the superclass :class:`.FunctionElement` for a description
- of public methods.
-
- """
-
- __visit_name__ = 'function'
-
- def __init__(self, name, *clauses, **kw):
- """Construct a :class:`.Function`.
-
- The :attr:`.func` construct is normally used to construct
- new :class:`.Function` instances.
-
- """
- self.packagenames = kw.pop('packagenames', None) or []
- self.name = name
- self._bind = kw.get('bind', None)
- self.type = sqltypes.to_instance(kw.get('type_', None))
-
- FunctionElement.__init__(self, *clauses, **kw)
-
- def _bind_param(self, operator, obj):
- return _BindParamClause(self.name, obj,
- _compared_to_operator=operator,
- _compared_to_type=self.type,
- unique=True)
-
-
-class _Cast(ColumnElement):
-
- __visit_name__ = 'cast'
-
- def __init__(self, clause, totype, **kwargs):
- self.type = sqltypes.to_instance(totype)
- self.clause = _literal_as_binds(clause, None)
- self.typeclause = _TypeClause(self.type)
-
- def _copy_internals(self, clone=_clone):
- self.clause = clone(self.clause)
- self.typeclause = clone(self.typeclause)
-
- def get_children(self, **kwargs):
- return self.clause, self.typeclause
-
- @property
- def _from_objects(self):
- return self.clause._from_objects
-
-
-class _Extract(ColumnElement):
-
- __visit_name__ = 'extract'
-
- def __init__(self, field, expr, **kwargs):
- self.type = sqltypes.Integer()
- self.field = field
- self.expr = _literal_as_binds(expr, None)
-
- def _copy_internals(self, clone=_clone):
- self.expr = clone(self.expr)
-
- def get_children(self, **kwargs):
- return self.expr,
-
- @property
- def _from_objects(self):
- return self.expr._from_objects
-
-
-class _UnaryExpression(ColumnElement):
-
- __visit_name__ = 'unary'
-
- def __init__(self, element, operator=None, modifier=None,
- type_=None, negate=None):
- self.operator = operator
- self.modifier = modifier
-
- self.element = _literal_as_text(element).\
- self_group(against=self.operator or self.modifier)
- self.type = sqltypes.to_instance(type_)
- self.negate = negate
-
- @property
- def _from_objects(self):
- return self.element._from_objects
-
- def _copy_internals(self, clone=_clone):
- self.element = clone(self.element)
-
- def get_children(self, **kwargs):
- return self.element,
-
- def compare(self, other, **kw):
- """Compare this :class:`_UnaryExpression` against the given
- :class:`.ClauseElement`."""
-
- return (
- isinstance(other, _UnaryExpression) and
- self.operator == other.operator and
- self.modifier == other.modifier and
- self.element.compare(other.element, **kw)
- )
-
- def _negate(self):
- if self.negate is not None:
- return _UnaryExpression(
- self.element,
- operator=self.negate,
- negate=self.operator,
- modifier=self.modifier,
- type_=self.type)
- else:
- return super(_UnaryExpression, self)._negate()
-
- def self_group(self, against=None):
- if self.operator and operators.is_precedent(self.operator,
- against):
- return _Grouping(self)
- else:
- return self
-
-
-class _BinaryExpression(ColumnElement):
- """Represent an expression that is ``LEFT <operator> RIGHT``."""
-
- __visit_name__ = 'binary'
-
- def __init__(self, left, right, operator, type_=None,
- negate=None, modifiers=None):
- self.left = _literal_as_text(left).self_group(against=operator)
- self.right = _literal_as_text(right).self_group(against=operator)
- self.operator = operator
- self.type = sqltypes.to_instance(type_)
- self.negate = negate
- if modifiers is None:
- self.modifiers = {}
- else:
- self.modifiers = modifiers
-
- def __nonzero__(self):
- try:
- return self.operator(hash(self.left), hash(self.right))
- except:
- raise TypeError("Boolean value of this clause is not defined")
-
- @property
- def _from_objects(self):
- return self.left._from_objects + self.right._from_objects
-
- def _copy_internals(self, clone=_clone):
- self.left = clone(self.left)
- self.right = clone(self.right)
-
- def get_children(self, **kwargs):
- return self.left, self.right
-
- def compare(self, other, **kw):
- """Compare this :class:`_BinaryExpression` against the
- given :class:`_BinaryExpression`."""
-
- return (
- isinstance(other, _BinaryExpression) and
- self.operator == other.operator and
- (
- self.left.compare(other.left, **kw) and
- self.right.compare(other.right, **kw) or
- (
- operators.is_commutative(self.operator) and
- self.left.compare(other.right, **kw) and
- self.right.compare(other.left, **kw)
- )
- )
- )
-
- def self_group(self, against=None):
- if operators.is_precedent(self.operator, against):
- return _Grouping(self)
- else:
- return self
-
- def _negate(self):
- if self.negate is not None:
- return _BinaryExpression(
- self.left,
- self.right,
- self.negate,
- negate=self.operator,
- type_=sqltypes.BOOLEANTYPE,
- modifiers=self.modifiers)
- else:
- return super(_BinaryExpression, self)._negate()
-
-class _Exists(_UnaryExpression):
- __visit_name__ = _UnaryExpression.__visit_name__
- _from_objects = []
-
- def __init__(self, *args, **kwargs):
- if args and isinstance(args[0], (_SelectBase, _ScalarSelect)):
- s = args[0]
- else:
- if not args:
- args = ([literal_column('*')],)
- s = select(*args, **kwargs).as_scalar().self_group()
-
- _UnaryExpression.__init__(self, s, operator=operators.exists,
- type_=sqltypes.Boolean)
-
- def select(self, whereclause=None, **params):
- return select([self], whereclause, **params)
-
- def correlate(self, fromclause):
- e = self._clone()
- e.element = self.element.correlate(fromclause).self_group()
- return e
-
- def select_from(self, clause):
- """return a new exists() construct with the given expression set as
- its FROM clause.
-
- """
- e = self._clone()
- e.element = self.element.select_from(clause).self_group()
- return e
-
- def where(self, clause):
- """return a new exists() construct with the given expression added to
- its WHERE clause, joined to the existing clause via AND, if any.
-
- """
- e = self._clone()
- e.element = self.element.where(clause).self_group()
- return e
-
-class Join(FromClause):
- """represent a ``JOIN`` construct between two :class:`.FromClause`
- elements.
-
- The public constructor function for :class:`.Join` is the module-level
- :func:`join()` function, as well as the :func:`join()` method available
- off all :class:`.FromClause` subclasses.
-
- """
- __visit_name__ = 'join'
-
- def __init__(self, left, right, onclause=None, isouter=False):
- """Construct a new :class:`.Join`.
-
- The usual entrypoint here is the :func:`~.expression.join`
- function or the :meth:`.FromClause.join` method of any
- :class:`.FromClause` object.
-
- """
- self.left = _literal_as_text(left)
- self.right = _literal_as_text(right).self_group()
-
- if onclause is None:
- self.onclause = self._match_primaries(self.left, self.right)
- else:
- self.onclause = onclause
-
- self.isouter = isouter
- self.__folded_equivalents = None
-
- @property
- def description(self):
- return "Join object on %s(%d) and %s(%d)" % (
- self.left.description,
- id(self.left),
- self.right.description,
- id(self.right))
-
- def is_derived_from(self, fromclause):
- return fromclause is self or \
- self.left.is_derived_from(fromclause) or\
- self.right.is_derived_from(fromclause)
-
- def self_group(self, against=None):
- return _FromGrouping(self)
-
- def _populate_column_collection(self):
- columns = [c for c in self.left.columns] + \
- [c for c in self.right.columns]
-
- self.primary_key.extend(sqlutil.reduce_columns(
- (c for c in columns if c.primary_key), self.onclause))
- self._columns.update((col._label, col) for col in columns)
- self.foreign_keys.update(itertools.chain(
- *[col.foreign_keys for col in columns]))
-
- def _copy_internals(self, clone=_clone):
- self._reset_exported()
- self.left = clone(self.left)
- self.right = clone(self.right)
- self.onclause = clone(self.onclause)
- self.__folded_equivalents = None
-
- def get_children(self, **kwargs):
- return self.left, self.right, self.onclause
-
- def _match_primaries(self, left, right):
- if isinstance(left, Join):
- left_right = left.right
- else:
- left_right = None
- return sqlutil.join_condition(left, right, a_subset=left_right)
-
- def select(self, whereclause=None, fold_equivalents=False, **kwargs):
- """Create a :class:`.Select` from this :class:`.Join`.
-
- The equivalent long-hand form, given a :class:`.Join` object
- ``j``, is::
-
- from sqlalchemy import select
- j = select([j.left, j.right], **kw).\\
- where(whereclause).\\
- select_from(j)
-
- :param whereclause: the WHERE criterion that will be sent to
- the :func:`select()` function
-
- :param fold_equivalents: based on the join criterion of this
- :class:`.Join`, do not include
- repeat column names in the column list of the resulting
- select, for columns that are calculated to be "equivalent"
- based on the join criterion of this :class:`.Join`. This will
- recursively apply to any joins directly nested by this one
- as well.
-
- :param \**kwargs: all other kwargs are sent to the
- underlying :func:`select()` function.
-
- """
- if fold_equivalents:
- collist = sqlutil.folded_equivalents(self)
- else:
- collist = [self.left, self.right]
-
- return select(collist, whereclause, from_obj=[self], **kwargs)
-
- @property
- def bind(self):
- return self.left.bind or self.right.bind
-
- def alias(self, name=None):
- """return an alias of this :class:`.Join`.
-
- Used against a :class:`.Join` object,
- :meth:`~.Join.alias` calls the :meth:`~.Join.select`
- method first so that a subquery against a
- :func:`.select` construct is generated.
- the :func:`~expression.select` construct also has the
- ``correlate`` flag set to ``False`` and will not
- auto-correlate inside an enclosing :func:`~expression.select`
- construct.
-
- The equivalent long-hand form, given a :class:`.Join` object
- ``j``, is::
-
- from sqlalchemy import select, alias
- j = alias(
- select([j.left, j.right]).\\
- select_from(j).\\
- with_labels(True).\\
- correlate(False),
- name=name
- )
-
- See :func:`~.expression.alias` for further details on
- aliases.
-
- """
- return self.select(use_labels=True, correlate=False).alias(name)
-
- @property
- def _hide_froms(self):
- return itertools.chain(*[_from_objects(x.left, x.right)
- for x in self._cloned_set])
-
- @property
- def _from_objects(self):
- return [self] + \
- self.onclause._from_objects + \
- self.left._from_objects + \
- self.right._from_objects
-
-class Alias(FromClause):
- """Represents an table or selectable alias (AS).
-
- Represents an alias, as typically applied to any table or
- sub-select within a SQL statement using the ``AS`` keyword (or
- without the keyword on certain databases such as Oracle).
-
- This object is constructed from the :func:`~.expression.alias` module level
- function as well as the :meth:`.FromClause.alias` method available on all
- :class:`.FromClause` subclasses.
-
- """
-
- __visit_name__ = 'alias'
- named_with_column = True
-
- def __init__(self, selectable, name=None):
- baseselectable = selectable
- while isinstance(baseselectable, Alias):
- baseselectable = baseselectable.element
- self.original = baseselectable
- self.supports_execution = baseselectable.supports_execution
- if self.supports_execution:
- self._execution_options = baseselectable._execution_options
- self.element = selectable
- if name is None:
- if self.original.named_with_column:
- name = getattr(self.original, 'name', None)
- name = _generated_label('%%(%d %s)s' % (id(self), name
- or 'anon'))
- self.name = name
-
- @property
- def description(self):
- # Py3K
- #return self.name
- # Py2K
- return self.name.encode('ascii', 'backslashreplace')
- # end Py2K
-
- def as_scalar(self):
- try:
- return self.element.as_scalar()
- except AttributeError:
- raise AttributeError("Element %s does not support "
- "'as_scalar()'" % self.element)
-
- def is_derived_from(self, fromclause):
- if fromclause in self._cloned_set:
- return True
- return self.element.is_derived_from(fromclause)
-
- def _populate_column_collection(self):
- for col in self.element.columns:
- col._make_proxy(self)
-
- def _copy_internals(self, clone=_clone):
- self._reset_exported()
- self.element = _clone(self.element)
- baseselectable = self.element
- while isinstance(baseselectable, Alias):
- baseselectable = baseselectable.element
- self.original = baseselectable
-
- def get_children(self, column_collections=True,
- aliased_selectables=True, **kwargs):
- if column_collections:
- for c in self.c:
- yield c
- if aliased_selectables:
- yield self.element
-
- @property
- def _from_objects(self):
- return [self]
-
- @property
- def bind(self):
- return self.element.bind
-
-
-class _Grouping(ColumnElement):
- """Represent a grouping within a column expression"""
-
- __visit_name__ = 'grouping'
-
- def __init__(self, element):
- self.element = element
- self.type = getattr(element, 'type', None)
-
- @property
- def _label(self):
- return getattr(self.element, '_label', None) or self.anon_label
-
- def _copy_internals(self, clone=_clone):
- self.element = clone(self.element)
-
- def get_children(self, **kwargs):
- return self.element,
-
- @property
- def _from_objects(self):
- return self.element._from_objects
-
- def __getattr__(self, attr):
- return getattr(self.element, attr)
-
- def __getstate__(self):
- return {'element':self.element, 'type':self.type}
-
- def __setstate__(self, state):
- self.element = state['element']
- self.type = state['type']
-
-class _FromGrouping(FromClause):
- """Represent a grouping of a FROM clause"""
- __visit_name__ = 'grouping'
-
- def __init__(self, element):
- self.element = element
-
- def _init_collections(self):
- pass
-
- @property
- def columns(self):
- return self.element.columns
-
- @property
- def primary_key(self):
- return self.element.primary_key
-
- @property
- def foreign_keys(self):
- # this could be
- # self.element.foreign_keys
- # see SelectableTest.test_join_condition
- return set()
-
- @property
- def _hide_froms(self):
- return self.element._hide_froms
-
- def get_children(self, **kwargs):
- return self.element,
-
- def _copy_internals(self, clone=_clone):
- self.element = clone(self.element)
-
- @property
- def _from_objects(self):
- return self.element._from_objects
-
- def __getattr__(self, attr):
- return getattr(self.element, attr)
-
- def __getstate__(self):
- return {'element':self.element}
-
- def __setstate__(self, state):
- self.element = state['element']
-
-class _Over(ColumnElement):
- """Represent an OVER clause.
-
- This is a special operator against a so-called
- "window" function, as well as any aggregate function,
- which produces results relative to the result set
- itself. It's supported only by certain database
- backends.
-
- """
- __visit_name__ = 'over'
-
- order_by = None
- partition_by = None
-
- def __init__(self, func, partition_by=None, order_by=None):
- self.func = func
- if order_by is not None:
- self.order_by = ClauseList(*util.to_list(order_by))
- if partition_by is not None:
- self.partition_by = ClauseList(*util.to_list(partition_by))
-
- @util.memoized_property
- def type(self):
- return self.func.type
-
- def get_children(self, **kwargs):
- return [c for c in
- (self.func, self.partition_by, self.order_by)
- if c is not None]
-
- def _copy_internals(self, clone=_clone):
- self.func = clone(self.func)
- if self.partition_by is not None:
- self.partition_by = clone(self.partition_by)
- if self.order_by is not None:
- self.order_by = clone(self.order_by)
-
- @property
- def _from_objects(self):
- return list(itertools.chain(
- *[c._from_objects for c in
- (self.func, self.partition_by, self.order_by)
- if c is not None]
- ))
-
-class _Label(ColumnElement):
- """Represents a column label (AS).
-
- Represent a label, as typically applied to any column-level
- element using the ``AS`` sql keyword.
-
- This object is constructed from the :func:`label()` module level
- function as well as the :func:`label()` method available on all
- :class:`.ColumnElement` subclasses.
-
- """
-
- __visit_name__ = 'label'
-
- def __init__(self, name, element, type_=None):
- while isinstance(element, _Label):
- element = element.element
- self.name = self.key = self._label = name \
- or _generated_label('%%(%d %s)s' % (id(self),
- getattr(element, 'name', 'anon')))
- self._element = element
- self._type = type_
- self.quote = element.quote
- self.proxies = [element]
-
- @util.memoized_property
- def type(self):
- return sqltypes.to_instance(
- self._type or getattr(self._element, 'type', None)
- )
-
- @util.memoized_property
- def element(self):
- return self._element.self_group(against=operators.as_)
-
- def self_group(self, against=None):
- sub_element = self._element.self_group(against=against)
- if sub_element is not self._element:
- return _Label(self.name,
- sub_element,
- type_=self._type)
- else:
- return self._element
-
- @property
- def primary_key(self):
- return self.element.primary_key
-
- @property
- def foreign_keys(self):
- return self.element.foreign_keys
-
- def get_children(self, **kwargs):
- return self.element,
-
- def _copy_internals(self, clone=_clone):
- self.element = clone(self.element)
-
- @property
- def _from_objects(self):
- return self.element._from_objects
-
- def _make_proxy(self, selectable, name = None):
- e = self.element._make_proxy(selectable, name=name or self.name)
- e.proxies.append(self)
- return e
-
-class ColumnClause(_Immutable, ColumnElement):
- """Represents a generic column expression from any textual string.
-
- This includes columns associated with tables, aliases and select
- statements, but also any arbitrary text. May or may not be bound
- to an underlying :class:`.Selectable`.
-
- :class:`.ColumnClause` is constructed by itself typically via
- the :func:`~.expression.column` function. It may be placed directly
- into constructs such as :func:`.select` constructs::
-
- from sqlalchemy.sql import column, select
-
- c1, c2 = column("c1"), column("c2")
- s = select([c1, c2]).where(c1==5)
-
- There is also a variant on :func:`~.expression.column` known
- as :func:`~.expression.literal_column` - the difference is that
- in the latter case, the string value is assumed to be an exact
- expression, rather than a column name, so that no quoting rules
- or similar are applied::
-
- from sqlalchemy.sql import literal_column, select
-
- s = select([literal_column("5 + 7")])
-
- :class:`.ColumnClause` can also be used in a table-like
- fashion by combining the :func:`~.expression.column` function
- with the :func:`~.expression.table` function, to produce
- a "lightweight" form of table metadata::
-
- from sqlalchemy.sql import table, column
-
- user = table("user",
- column("id"),
- column("name"),
- column("description"),
- )
-
- The above construct can be created in an ad-hoc fashion and is
- not associated with any :class:`.schema.MetaData`, unlike it's
- more full fledged :class:`.schema.Table` counterpart.
-
- :param text: the text of the element.
-
- :param selectable: parent selectable.
-
- :param type: :class:`.types.TypeEngine` object which can associate
- this :class:`.ColumnClause` with a type.
-
- :param is_literal: if True, the :class:`.ColumnClause` is assumed to
- be an exact expression that will be delivered to the output with no
- quoting rules applied regardless of case sensitive settings. the
- :func:`literal_column()` function is usually used to create such a
- :class:`.ColumnClause`.
-
- """
- __visit_name__ = 'column'
-
- onupdate = default = server_default = server_onupdate = None
-
- def __init__(self, text, selectable=None, type_=None, is_literal=False):
- self.key = self.name = text
- self.table = selectable
- self.type = sqltypes.to_instance(type_)
- self.is_literal = is_literal
-
- @util.memoized_property
- def _from_objects(self):
- if self.table is not None:
- return [self.table]
- else:
- return []
-
- @util.memoized_property
- def description(self):
- # Py3K
- #return self.name
- # Py2K
- return self.name.encode('ascii', 'backslashreplace')
- # end Py2K
-
- @util.memoized_property
- def _label(self):
- if self.is_literal:
- return None
-
- elif self.table is not None and self.table.named_with_column:
- if getattr(self.table, 'schema', None):
- label = self.table.schema.replace('.', '_') + "_" + \
- _escape_for_generated(self.table.name) + "_" + \
- _escape_for_generated(self.name)
- else:
- label = _escape_for_generated(self.table.name) + "_" + \
- _escape_for_generated(self.name)
-
- # ensure the label name doesn't conflict with that
- # of an existing column
- if label in self.table.c:
- _label = label
- counter = 1
- while _label in self.table.c:
- _label = label + "_" + str(counter)
- counter += 1
- label = _label
-
- return _generated_label(label)
-
- else:
- return self.name
-
- def label(self, name):
- # currently, anonymous labels don't occur for
- # ColumnClause. The use at the moment
- # is that they do not generate nicely for
- # is_literal clauses. We would like to change
- # this so that label(None) acts as would be expected.
- # See [ticket:2168].
- if name is None:
- return self
- else:
- return super(ColumnClause, self).label(name)
-
-
- def _bind_param(self, operator, obj):
- return _BindParamClause(self.name, obj,
- _compared_to_operator=operator,
- _compared_to_type=self.type,
- unique=True)
-
- def _make_proxy(self, selectable, name=None, attach=True):
- # propagate the "is_literal" flag only if we are keeping our name,
- # otherwise its considered to be a label
- is_literal = self.is_literal and (name is None or name == self.name)
- c = self._constructor(
- name or self.name,
- selectable=selectable,
- type_=self.type,
- is_literal=is_literal
- )
- c.proxies = [self]
- if attach:
- selectable._columns[c.name] = c
- return c
-
-class TableClause(_Immutable, FromClause):
- """Represents a minimal "table" construct.
-
- The constructor for :class:`.TableClause` is the
- :func:`~.expression.table` function. This produces
- a lightweight table object that has only a name and a
- collection of columns, which are typically produced
- by the :func:`~.expression.column` function::
-
- from sqlalchemy.sql import table, column
-
- user = table("user",
- column("id"),
- column("name"),
- column("description"),
- )
-
- The :class:`.TableClause` construct serves as the base for
- the more commonly used :class:`~.schema.Table` object, providing
- the usual set of :class:`~.expression.FromClause` services including
- the ``.c.`` collection and statement generation methods.
-
- It does **not** provide all the additional schema-level services
- of :class:`~.schema.Table`, including constraints, references to other
- tables, or support for :class:`.MetaData`-level services. It's useful
- on its own as an ad-hoc construct used to generate quick SQL
- statements when a more fully fledged :class:`~.schema.Table` is not on hand.
-
- """
-
- __visit_name__ = 'table'
-
- named_with_column = True
-
- def __init__(self, name, *columns):
- super(TableClause, self).__init__()
- self.name = self.fullname = name
- self._columns = ColumnCollection()
- self.primary_key = ColumnSet()
- self.foreign_keys = set()
- for c in columns:
- self.append_column(c)
-
- def _init_collections(self):
- pass
-
- @util.memoized_property
- def description(self):
- # Py3K
- #return self.name
- # Py2K
- return self.name.encode('ascii', 'backslashreplace')
- # end Py2K
-
- def append_column(self, c):
- self._columns[c.name] = c
- c.table = self
-
- def get_children(self, column_collections=True, **kwargs):
- if column_collections:
- return [c for c in self.c]
- else:
- return []
-
- def count(self, whereclause=None, **params):
- """return a SELECT COUNT generated against this
- :class:`.TableClause`."""
-
- if self.primary_key:
- col = list(self.primary_key)[0]
- else:
- col = list(self.columns)[0]
- return select(
- [func.count(col).label('tbl_row_count')],
- whereclause,
- from_obj=[self],
- **params)
-
- def insert(self, values=None, inline=False, **kwargs):
- """Generate an :func:`insert()` construct."""
-
- return insert(self, values=values, inline=inline, **kwargs)
-
- def update(self, whereclause=None, values=None, inline=False, **kwargs):
- """Generate an :func:`update()` construct."""
-
- return update(self, whereclause=whereclause,
- values=values, inline=inline, **kwargs)
-
- def delete(self, whereclause=None, **kwargs):
- """Generate a :func:`delete()` construct."""
-
- return delete(self, whereclause, **kwargs)
-
- @property
- def _from_objects(self):
- return [self]
-
-class _SelectBase(Executable, FromClause):
- """Base class for :class:`.Select` and ``CompoundSelects``."""
-
- _order_by_clause = ClauseList()
- _group_by_clause = ClauseList()
- _limit = None
- _offset = None
-
- def __init__(self,
- use_labels=False,
- for_update=False,
- limit=None,
- offset=None,
- order_by=None,
- group_by=None,
- bind=None,
- autocommit=None):
- self.use_labels = use_labels
- self.for_update = for_update
- if autocommit is not None:
- util.warn_deprecated('autocommit on select() is '
- 'deprecated. Use .execution_options(a'
- 'utocommit=True)')
- self._execution_options = \
- self._execution_options.union({'autocommit'
- : autocommit})
- if limit is not None:
- self._limit = util.asint(limit)
- if offset is not None:
- self._offset = util.asint(offset)
- self._bind = bind
-
- if order_by is not None:
- self._order_by_clause = ClauseList(*util.to_list(order_by))
- if group_by is not None:
- self._group_by_clause = ClauseList(*util.to_list(group_by))
-
- def as_scalar(self):
- """return a 'scalar' representation of this selectable, which can be
- used as a column expression.
-
- Typically, a select statement which has only one column in its columns
- clause is eligible to be used as a scalar expression.
-
- The returned object is an instance of
- :class:`_ScalarSelect`.
-
- """
- return _ScalarSelect(self)
-
- @_generative
- def apply_labels(self):
- """return a new selectable with the 'use_labels' flag set to True.
-
- This will result in column expressions being generated using labels
- against their table name, such as "SELECT somecolumn AS
- tablename_somecolumn". This allows selectables which contain multiple
- FROM clauses to produce a unique set of column names regardless of
- name conflicts among the individual FROM clauses.
-
- """
- self.use_labels = True
-
- def label(self, name):
- """return a 'scalar' representation of this selectable, embedded as a
- subquery with a label.
-
- See also ``as_scalar()``.
-
- """
- return self.as_scalar().label(name)
-
- @_generative
- @util.deprecated('0.6',
- message=":func:`.autocommit` is deprecated. Use "
- ":func:`.Executable.execution_options` with the "
- "'autocommit' flag.")
- def autocommit(self):
- """return a new selectable with the 'autocommit' flag set to
- True."""
-
- self._execution_options = \
- self._execution_options.union({'autocommit': True})
-
- def _generate(self):
- """Override the default _generate() method to also clear out
- exported collections."""
-
- s = self.__class__.__new__(self.__class__)
- s.__dict__ = self.__dict__.copy()
- s._reset_exported()
- return s
-
- @_generative
- def limit(self, limit):
- """return a new selectable with the given LIMIT criterion
- applied."""
-
- self._limit = util.asint(limit)
-
- @_generative
- def offset(self, offset):
- """return a new selectable with the given OFFSET criterion
- applied."""
-
- self._offset = util.asint(offset)
-
- @_generative
- def order_by(self, *clauses):
- """return a new selectable with the given list of ORDER BY
- criterion applied.
-
- The criterion will be appended to any pre-existing ORDER BY
- criterion.
-
- """
-
- self.append_order_by(*clauses)
-
- @_generative
- def group_by(self, *clauses):
- """return a new selectable with the given list of GROUP BY
- criterion applied.
-
- The criterion will be appended to any pre-existing GROUP BY
- criterion.
-
- """
-
- self.append_group_by(*clauses)
-
- def append_order_by(self, *clauses):
- """Append the given ORDER BY criterion applied to this selectable.
-
- The criterion will be appended to any pre-existing ORDER BY criterion.
-
- """
- if len(clauses) == 1 and clauses[0] is None:
- self._order_by_clause = ClauseList()
- else:
- if getattr(self, '_order_by_clause', None) is not None:
- clauses = list(self._order_by_clause) + list(clauses)
- self._order_by_clause = ClauseList(*clauses)
-
- def append_group_by(self, *clauses):
- """Append the given GROUP BY criterion applied to this selectable.
-
- The criterion will be appended to any pre-existing GROUP BY criterion.
-
- """
- if len(clauses) == 1 and clauses[0] is None:
- self._group_by_clause = ClauseList()
- else:
- if getattr(self, '_group_by_clause', None) is not None:
- clauses = list(self._group_by_clause) + list(clauses)
- self._group_by_clause = ClauseList(*clauses)
-
- @property
- def _from_objects(self):
- return [self]
-
-
-class _ScalarSelect(_Grouping):
- _from_objects = []
-
- def __init__(self, element):
- self.element = element
- self.type = element._scalar_type()
-
- @property
- def columns(self):
- raise exc.InvalidRequestError('Scalar Select expression has no '
- 'columns; use this object directly within a '
- 'column-level expression.')
- c = columns
-
- def self_group(self, **kwargs):
- return self
-
- def _make_proxy(self, selectable, name):
- return list(self.inner_columns)[0]._make_proxy(selectable, name)
-
-class CompoundSelect(_SelectBase):
- """Forms the basis of ``UNION``, ``UNION ALL``, and other
- SELECT-based set operations."""
-
- __visit_name__ = 'compound_select'
-
- UNION = util.symbol('UNION')
- UNION_ALL = util.symbol('UNION ALL')
- EXCEPT = util.symbol('EXCEPT')
- EXCEPT_ALL = util.symbol('EXCEPT ALL')
- INTERSECT = util.symbol('INTERSECT')
- INTERSECT_ALL = util.symbol('INTERSECT ALL')
-
- def __init__(self, keyword, *selects, **kwargs):
- self._should_correlate = kwargs.pop('correlate', False)
- self.keyword = keyword
- self.selects = []
-
- numcols = None
-
- # some DBs do not like ORDER BY in the inner queries of a UNION, etc.
- for n, s in enumerate(selects):
- s = _clause_element_as_expr(s)
-
- if not numcols:
- numcols = len(s.c)
- elif len(s.c) != numcols:
- raise exc.ArgumentError('All selectables passed to '
- 'CompoundSelect must have identical numbers of '
- 'columns; select #%d has %d columns, select '
- '#%d has %d' % (1, len(self.selects[0].c), n
- + 1, len(s.c)))
-
- self.selects.append(s.self_group(self))
-
- _SelectBase.__init__(self, **kwargs)
-
- def _scalar_type(self):
- return self.selects[0]._scalar_type()
-
- def self_group(self, against=None):
- return _FromGrouping(self)
-
- def is_derived_from(self, fromclause):
- for s in self.selects:
- if s.is_derived_from(fromclause):
- return True
- return False
-
- def _populate_column_collection(self):
- for cols in zip(*[s.c for s in self.selects]):
-
- # this is a slightly hacky thing - the union exports a
- # column that resembles just that of the *first* selectable.
- # to get at a "composite" column, particularly foreign keys,
- # you have to dig through the proxies collection which we
- # generate below. We may want to improve upon this, such as
- # perhaps _make_proxy can accept a list of other columns
- # that are "shared" - schema.column can then copy all the
- # ForeignKeys in. this would allow the union() to have all
- # those fks too.
-
- proxy = cols[0]._make_proxy(self, name=self.use_labels
- and cols[0]._label or None)
-
- # hand-construct the "proxies" collection to include all
- # derived columns place a 'weight' annotation corresponding
- # to how low in the list of select()s the column occurs, so
- # that the corresponding_column() operation can resolve
- # conflicts
-
- proxy.proxies = [c._annotate({'weight': i + 1}) for (i,
- c) in enumerate(cols)]
-
- def _copy_internals(self, clone=_clone):
- self._reset_exported()
- self.selects = [clone(s) for s in self.selects]
- if hasattr(self, '_col_map'):
- del self._col_map
- for attr in ('_order_by_clause', '_group_by_clause'):
- if getattr(self, attr) is not None:
- setattr(self, attr, clone(getattr(self, attr)))
-
- def get_children(self, column_collections=True, **kwargs):
- return (column_collections and list(self.c) or []) \
- + [self._order_by_clause, self._group_by_clause] \
- + list(self.selects)
-
- def bind(self):
- if self._bind:
- return self._bind
- for s in self.selects:
- e = s.bind
- if e:
- return e
- else:
- return None
- def _set_bind(self, bind):
- self._bind = bind
- bind = property(bind, _set_bind)
-
-class Select(_SelectBase):
- """Represents a ``SELECT`` statement.
-
- Select statements support appendable clauses, as well as the
- ability to execute themselves and return a result set.
-
- """
-
- __visit_name__ = 'select'
-
- _prefixes = ()
- _hints = util.immutabledict()
- _distinct = False
-
- def __init__(self,
- columns,
- whereclause=None,
- from_obj=None,
- distinct=False,
- having=None,
- correlate=True,
- prefixes=None,
- **kwargs):
- """Construct a Select object.
-
- The public constructor for Select is the
- :func:`select` function; see that function for
- argument descriptions.
-
- Additional generative and mutator methods are available on the
- :class:`_SelectBase` superclass.
-
- """
- self._should_correlate = correlate
- if distinct is not False:
- if isinstance(distinct, basestring):
- util.warn_deprecated(
- "A string argument passed to the 'distinct' "
- "keyword argument of 'select()' is deprecated "
- "- please use 'prefixes' or 'prefix_with()' "
- "to specify additional prefixes")
- if prefixes:
- prefixes = util.to_list(prefixes) + [distinct]
- else:
- prefixes = [distinct]
- elif distinct is True:
- self._distinct = True
- else:
- self._distinct = [
- _literal_as_text(e)
- for e in util.to_list(distinct)
- ]
-
- self._correlate = set()
- self._froms = util.OrderedSet()
-
- try:
- cols_present = bool(columns)
- except TypeError:
- raise exc.ArgumentError("columns argument to select() must "
- "be a Python list or other iterable")
-
- if cols_present:
- self._raw_columns = []
- for c in columns:
- c = _literal_as_column(c)
- if isinstance(c, _ScalarSelect):
- c = c.self_group(against=operators.comma_op)
- self._raw_columns.append(c)
-
- self._froms.update(_from_objects(*self._raw_columns))
- else:
- self._raw_columns = []
-
- if whereclause is not None:
- self._whereclause = _literal_as_text(whereclause)
- self._froms.update(_from_objects(self._whereclause))
- else:
- self._whereclause = None
-
- if from_obj is not None:
- for f in util.to_list(from_obj):
- if _is_literal(f):
- self._froms.add(_TextClause(f))
- else:
- self._froms.add(f)
-
- if having is not None:
- self._having = _literal_as_text(having)
- else:
- self._having = None
-
- if prefixes:
- self._prefixes = tuple([_literal_as_text(p) for p in prefixes])
-
- _SelectBase.__init__(self, **kwargs)
-
- def _get_display_froms(self, existing_froms=None):
- """Return the full list of 'from' clauses to be displayed.
-
- Takes into account a set of existing froms which may be
- rendered in the FROM clause of enclosing selects; this Select
- may want to leave those absent if it is automatically
- correlating.
-
- """
- froms = self._froms
-
- toremove = itertools.chain(*[f._hide_froms for f in froms])
- if toremove:
- froms = froms.difference(toremove)
-
- if len(froms) > 1 or self._correlate:
- if self._correlate:
- froms = froms.difference(_cloned_intersection(froms,
- self._correlate))
- if self._should_correlate and existing_froms:
- froms = froms.difference(_cloned_intersection(froms,
- existing_froms))
-
- if not len(froms):
- raise exc.InvalidRequestError("Select statement '%s"
- "' returned no FROM clauses due to "
- "auto-correlation; specify "
- "correlate(<tables>) to control "
- "correlation manually." % self)
-
- return froms
-
- def _scalar_type(self):
- elem = self._raw_columns[0]
- cols = list(elem._select_iterable)
- return cols[0].type
-
- @property
- def froms(self):
- """Return the displayed list of FromClause elements."""
-
- return self._get_display_froms()
-
- @_generative
- def with_hint(self, selectable, text, dialect_name='*'):
- """Add an indexing hint for the given selectable to this
- :class:`.Select`.
-
- The text of the hint is rendered in the appropriate
- location for the database backend in use, relative
- to the given :class:`.Table` or :class:`.Alias` passed as the
- *selectable* argument. The dialect implementation
- typically uses Python string substitution syntax
- with the token ``%(name)s`` to render the name of
- the table or alias. E.g. when using Oracle, the
- following::
-
- select([mytable]).\\
- with_hint(mytable, "+ index(%(name)s ix_mytable)")
-
- Would render SQL as::
-
- select /*+ index(mytable ix_mytable) */ ... from mytable
-
- The ``dialect_name`` option will limit the rendering of a particular
- hint to a particular backend. Such as, to add hints for both Oracle
- and Sybase simultaneously::
-
- select([mytable]).\\
- with_hint(mytable, "+ index(%(name)s ix_mytable)", 'oracle').\\
- with_hint(mytable, "WITH INDEX ix_mytable", 'sybase')
-
- """
- self._hints = self._hints.union({(selectable, dialect_name):text})
-
- @property
- def type(self):
- raise exc.InvalidRequestError("Select objects don't have a type. "
- "Call as_scalar() on this Select object "
- "to return a 'scalar' version of this Select.")
-
- @util.memoized_instancemethod
- def locate_all_froms(self):
- """return a Set of all FromClause elements referenced by this Select.
-
- This set is a superset of that returned by the ``froms`` property,
- which is specifically for those FromClause elements that would
- actually be rendered.
-
- """
- return self._froms.union(_from_objects(*list(self._froms)))
-
- @property
- def inner_columns(self):
- """an iterator of all ColumnElement expressions which would
- be rendered into the columns clause of the resulting SELECT statement.
-
- """
- return _select_iterables(self._raw_columns)
-
- def is_derived_from(self, fromclause):
- if self in fromclause._cloned_set:
- return True
-
- for f in self.locate_all_froms():
- if f.is_derived_from(fromclause):
- return True
- return False
-
- def _copy_internals(self, clone=_clone):
- self._reset_exported()
- from_cloned = dict((f, clone(f))
- for f in self._froms.union(self._correlate))
- self._froms = util.OrderedSet(from_cloned[f] for f in self._froms)
- self._correlate = set(from_cloned[f] for f in self._correlate)
- self._raw_columns = [clone(c) for c in self._raw_columns]
- for attr in '_whereclause', '_having', '_order_by_clause', \
- '_group_by_clause':
- if getattr(self, attr) is not None:
- setattr(self, attr, clone(getattr(self, attr)))
-
- def get_children(self, column_collections=True, **kwargs):
- """return child elements as per the ClauseElement specification."""
-
- return (column_collections and list(self.columns) or []) + \
- self._raw_columns + list(self._froms) + \
- [x for x in
- (self._whereclause, self._having,
- self._order_by_clause, self._group_by_clause)
- if x is not None]
-
- @_generative
- def column(self, column):
- """return a new select() construct with the given column expression
- added to its columns clause.
-
- """
-
- column = _literal_as_column(column)
-
- if isinstance(column, _ScalarSelect):
- column = column.self_group(against=operators.comma_op)
-
- self._raw_columns = self._raw_columns + [column]
- self._froms = self._froms.union(_from_objects(column))
-
- @_generative
- def with_only_columns(self, columns):
- """return a new select() construct with its columns clause replaced
- with the given columns.
-
- """
-
- self._raw_columns = [
- isinstance(c, _ScalarSelect) and
- c.self_group(against=operators.comma_op) or c
- for c in [_literal_as_column(c) for c in columns]
- ]
-
- @_generative
- def where(self, whereclause):
- """return a new select() construct with the given expression added to
- its WHERE clause, joined to the existing clause via AND, if any.
-
- """
-
- self.append_whereclause(whereclause)
-
- @_generative
- def having(self, having):
- """return a new select() construct with the given expression added to
- its HAVING clause, joined to the existing clause via AND, if any.
-
- """
- self.append_having(having)
-
- @_generative
- def distinct(self, *expr):
- """Return a new select() construct which will apply DISTINCT to its
- columns clause.
-
- :param \*expr: optional column expressions. When present,
- the Postgresql dialect will render a ``DISTINCT ON (<expressions>>)``
- construct.
-
- """
- if expr:
- expr = [_literal_as_text(e) for e in expr]
- if isinstance(self._distinct, list):
- self._distinct = self._distinct + expr
- else:
- self._distinct = expr
- else:
- self._distinct = True
-
- @_generative
- def prefix_with(self, *expr):
- """return a new select() construct which will apply the given
- expressions, typically strings, to the start of its columns clause,
- not using any commas. In particular is useful for MySQL
- keywords.
-
- e.g.::
-
- select(['a', 'b']).prefix_with('HIGH_PRIORITY',
- 'SQL_SMALL_RESULT',
- 'ALL')
-
- Would render::
-
- SELECT HIGH_PRIORITY SQL_SMALL_RESULT ALL a, b
-
- """
- expr = tuple(_literal_as_text(e) for e in expr)
- self._prefixes = self._prefixes + expr
-
- @_generative
- def select_from(self, fromclause):
- """return a new select() construct with the given FROM expression
- applied to its list of FROM objects.
-
- """
- fromclause = _literal_as_text(fromclause)
- self._froms = self._froms.union([fromclause])
-
- @_generative
- def correlate(self, *fromclauses):
- """return a new select() construct which will correlate the given FROM
- clauses to that of an enclosing select(), if a match is found.
-
- By "match", the given fromclause must be present in this select's
- list of FROM objects and also present in an enclosing select's list of
- FROM objects.
-
- Calling this method turns off the select's default behavior of
- "auto-correlation". Normally, select() auto-correlates all of its FROM
- clauses to those of an embedded select when compiled.
-
- If the fromclause is None, correlation is disabled for the returned
- select().
-
- """
- self._should_correlate = False
- if fromclauses == (None,):
- self._correlate = set()
- else:
- self._correlate = self._correlate.union(fromclauses)
-
- def append_correlation(self, fromclause):
- """append the given correlation expression to this select()
- construct."""
-
- self._should_correlate = False
- self._correlate = self._correlate.union([fromclause])
-
- def append_column(self, column):
- """append the given column expression to the columns clause of this
- select() construct.
-
- """
- column = _literal_as_column(column)
-
- if isinstance(column, _ScalarSelect):
- column = column.self_group(against=operators.comma_op)
-
- self._raw_columns = self._raw_columns + [column]
- self._froms = self._froms.union(_from_objects(column))
- self._reset_exported()
-
- def append_prefix(self, clause):
- """append the given columns clause prefix expression to this select()
- construct.
-
- """
- clause = _literal_as_text(clause)
- self._prefixes = self._prefixes + (clause,)
-
- def append_whereclause(self, whereclause):
- """append the given expression to this select() construct's WHERE
- criterion.
-
- The expression will be joined to existing WHERE criterion via AND.
-
- """
- whereclause = _literal_as_text(whereclause)
- self._froms = self._froms.union(_from_objects(whereclause))
-
- if self._whereclause is not None:
- self._whereclause = and_(self._whereclause, whereclause)
- else:
- self._whereclause = whereclause
-
- def append_having(self, having):
- """append the given expression to this select() construct's HAVING
- criterion.
-
- The expression will be joined to existing HAVING criterion via AND.
-
- """
- if self._having is not None:
- self._having = and_(self._having, _literal_as_text(having))
- else:
- self._having = _literal_as_text(having)
-
- def append_from(self, fromclause):
- """append the given FromClause expression to this select() construct's
- FROM clause.
-
- """
- if _is_literal(fromclause):
- fromclause = _TextClause(fromclause)
-
- self._froms = self._froms.union([fromclause])
-
- def __exportable_columns(self):
- for column in self._raw_columns:
- if isinstance(column, Selectable):
- for co in column.columns:
- yield co
- elif isinstance(column, ColumnElement):
- yield column
- else:
- continue
-
- def _populate_column_collection(self):
- for c in self.__exportable_columns():
- c._make_proxy(self, name=self.use_labels and c._label or None)
-
- def self_group(self, against=None):
- """return a 'grouping' construct as per the ClauseElement
- specification.
-
- This produces an element that can be embedded in an expression. Note
- that this method is called automatically as needed when constructing
- expressions.
-
- """
- if isinstance(against, CompoundSelect):
- return self
- return _FromGrouping(self)
-
- def union(self, other, **kwargs):
- """return a SQL UNION of this select() construct against the given
- selectable."""
-
- return union(self, other, **kwargs)
-
- def union_all(self, other, **kwargs):
- """return a SQL UNION ALL of this select() construct against the given
- selectable.
-
- """
- return union_all(self, other, **kwargs)
-
- def except_(self, other, **kwargs):
- """return a SQL EXCEPT of this select() construct against the given
- selectable."""
-
- return except_(self, other, **kwargs)
-
- def except_all(self, other, **kwargs):
- """return a SQL EXCEPT ALL of this select() construct against the
- given selectable.
-
- """
- return except_all(self, other, **kwargs)
-
- def intersect(self, other, **kwargs):
- """return a SQL INTERSECT of this select() construct against the given
- selectable.
-
- """
- return intersect(self, other, **kwargs)
-
- def intersect_all(self, other, **kwargs):
- """return a SQL INTERSECT ALL of this select() construct against the
- given selectable.
-
- """
- return intersect_all(self, other, **kwargs)
-
- def bind(self):
- if self._bind:
- return self._bind
- if not self._froms:
- for c in self._raw_columns:
- e = c.bind
- if e:
- self._bind = e
- return e
- else:
- e = list(self._froms)[0].bind
- if e:
- self._bind = e
- return e
-
- return None
-
- def _set_bind(self, bind):
- self._bind = bind
- bind = property(bind, _set_bind)
-
-class UpdateBase(Executable, ClauseElement):
- """Form the base for ``INSERT``, ``UPDATE``, and ``DELETE`` statements."""
-
- __visit_name__ = 'update_base'
-
- _execution_options = \
- Executable._execution_options.union({'autocommit': True})
- kwargs = util.immutabledict()
-
- def _process_colparams(self, parameters):
- if isinstance(parameters, (list, tuple)):
- pp = {}
- for i, c in enumerate(self.table.c):
- pp[c.key] = parameters[i]
- return pp
- else:
- return parameters
-
- def params(self, *arg, **kw):
- raise NotImplementedError(
- "params() is not supported for INSERT/UPDATE/DELETE statements."
- " To set the values for an INSERT or UPDATE statement, use"
- " stmt.values(**parameters).")
-
- def bind(self):
- return self._bind or self.table.bind
-
- def _set_bind(self, bind):
- self._bind = bind
- bind = property(bind, _set_bind)
-
- _returning_re = re.compile(r'(?:firebird|postgres(?:ql)?)_returning')
- def _process_deprecated_kw(self, kwargs):
- for k in list(kwargs):
- m = self._returning_re.match(k)
- if m:
- self._returning = kwargs.pop(k)
- util.warn_deprecated(
- "The %r argument is deprecated. Please "
- "use statement.returning(col1, col2, ...)" % k
- )
- return kwargs
-
- @_generative
- def returning(self, *cols):
- """Add a RETURNING or equivalent clause to this statement.
-
- The given list of columns represent columns within the table that is
- the target of the INSERT, UPDATE, or DELETE. Each element can be any
- column expression. :class:`~sqlalchemy.schema.Table` objects will be
- expanded into their individual columns.
-
- Upon compilation, a RETURNING clause, or database equivalent,
- will be rendered within the statement. For INSERT and UPDATE,
- the values are the newly inserted/updated values. For DELETE,
- the values are those of the rows which were deleted.
-
- Upon execution, the values of the columns to be returned
- are made available via the result set and can be iterated
- using ``fetchone()`` and similar. For DBAPIs which do not
- natively support returning values (i.e. cx_oracle),
- SQLAlchemy will approximate this behavior at the result level
- so that a reasonable amount of behavioral neutrality is
- provided.
-
- Note that not all databases/DBAPIs
- support RETURNING. For those backends with no support,
- an exception is raised upon compilation and/or execution.
- For those who do support it, the functionality across backends
- varies greatly, including restrictions on executemany()
- and other statements which return multiple rows. Please
- read the documentation notes for the database in use in
- order to determine the availability of RETURNING.
-
- """
- self._returning = cols
-
-class ValuesBase(UpdateBase):
- """Supplies support for :meth:`.ValuesBase.values` to INSERT and UPDATE constructs."""
-
- __visit_name__ = 'values_base'
-
- def __init__(self, table, values):
- self.table = table
- self.parameters = self._process_colparams(values)
-
- @_generative
- def values(self, *args, **kwargs):
- """specify the VALUES clause for an INSERT statement, or the SET
- clause for an UPDATE.
-
- \**kwargs
- key=<somevalue> arguments
-
- \*args
- A single dictionary can be sent as the first positional
- argument. This allows non-string based keys, such as Column
- objects, to be used.
-
- """
- if args:
- v = args[0]
- else:
- v = {}
-
- if self.parameters is None:
- self.parameters = self._process_colparams(v)
- self.parameters.update(kwargs)
- else:
- self.parameters = self.parameters.copy()
- self.parameters.update(self._process_colparams(v))
- self.parameters.update(kwargs)
-
-class Insert(ValuesBase):
- """Represent an INSERT construct.
-
- The :class:`.Insert` object is created using the :func:`insert()` function.
-
- """
- __visit_name__ = 'insert'
-
- _prefixes = ()
-
- def __init__(self,
- table,
- values=None,
- inline=False,
- bind=None,
- prefixes=None,
- returning=None,
- **kwargs):
- ValuesBase.__init__(self, table, values)
- self._bind = bind
- self.select = None
- self.inline = inline
- self._returning = returning
- if prefixes:
- self._prefixes = tuple([_literal_as_text(p) for p in prefixes])
-
- if kwargs:
- self.kwargs = self._process_deprecated_kw(kwargs)
-
- def get_children(self, **kwargs):
- if self.select is not None:
- return self.select,
- else:
- return ()
-
- def _copy_internals(self, clone=_clone):
- # TODO: coverage
- self.parameters = self.parameters.copy()
-
- @_generative
- def prefix_with(self, clause):
- """Add a word or expression between INSERT and INTO. Generative.
-
- If multiple prefixes are supplied, they will be separated with
- spaces.
-
- """
- clause = _literal_as_text(clause)
- self._prefixes = self._prefixes + (clause,)
-
-class Update(ValuesBase):
- """Represent an Update construct.
-
- The :class:`.Update` object is created using the :func:`update()` function.
-
- """
- __visit_name__ = 'update'
-
- def __init__(self,
- table,
- whereclause,
- values=None,
- inline=False,
- bind=None,
- returning=None,
- **kwargs):
- ValuesBase.__init__(self, table, values)
- self._bind = bind
- self._returning = returning
- if whereclause is not None:
- self._whereclause = _literal_as_text(whereclause)
- else:
- self._whereclause = None
- self.inline = inline
-
- if kwargs:
- self.kwargs = self._process_deprecated_kw(kwargs)
-
- def get_children(self, **kwargs):
- if self._whereclause is not None:
- return self._whereclause,
- else:
- return ()
-
- def _copy_internals(self, clone=_clone):
- # TODO: coverage
- self._whereclause = clone(self._whereclause)
- self.parameters = self.parameters.copy()
-
- @_generative
- def where(self, whereclause):
- """return a new update() construct with the given expression added to
- its WHERE clause, joined to the existing clause via AND, if any.
-
- """
- if self._whereclause is not None:
- self._whereclause = and_(self._whereclause,
- _literal_as_text(whereclause))
- else:
- self._whereclause = _literal_as_text(whereclause)
-
-
-class Delete(UpdateBase):
- """Represent a DELETE construct.
-
- The :class:`.Delete` object is created using the :func:`delete()` function.
-
- """
-
- __visit_name__ = 'delete'
-
- def __init__(self,
- table,
- whereclause,
- bind=None,
- returning =None,
- **kwargs):
- self._bind = bind
- self.table = table
- self._returning = returning
-
- if whereclause is not None:
- self._whereclause = _literal_as_text(whereclause)
- else:
- self._whereclause = None
-
- if kwargs:
- self.kwargs = self._process_deprecated_kw(kwargs)
-
- def get_children(self, **kwargs):
- if self._whereclause is not None:
- return self._whereclause,
- else:
- return ()
-
- @_generative
- def where(self, whereclause):
- """Add the given WHERE clause to a newly returned delete construct."""
-
- if self._whereclause is not None:
- self._whereclause = and_(self._whereclause,
- _literal_as_text(whereclause))
- else:
- self._whereclause = _literal_as_text(whereclause)
-
- def _copy_internals(self, clone=_clone):
- # TODO: coverage
- self._whereclause = clone(self._whereclause)
-
-class _IdentifiedClause(Executable, ClauseElement):
-
- __visit_name__ = 'identified'
- _execution_options = \
- Executable._execution_options.union({'autocommit': False})
- quote = None
-
- def __init__(self, ident):
- self.ident = ident
-
-class SavepointClause(_IdentifiedClause):
- __visit_name__ = 'savepoint'
-
-class RollbackToSavepointClause(_IdentifiedClause):
- __visit_name__ = 'rollback_to_savepoint'
-
-class ReleaseSavepointClause(_IdentifiedClause):
- __visit_name__ = 'release_savepoint'
-
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/functions.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/functions.py
deleted file mode 100755
index 71781665..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/functions.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# sql/functions.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy import types as sqltypes, schema
-from sqlalchemy.sql.expression import (
- ClauseList, Function, _literal_as_binds, text, _type_from_args
- )
-from sqlalchemy.sql import operators
-from sqlalchemy.sql.visitors import VisitableType
-
-class _GenericMeta(VisitableType):
- def __call__(self, *args, **kwargs):
- args = [_literal_as_binds(c) for c in args]
- return type.__call__(self, *args, **kwargs)
-
-class GenericFunction(Function):
- __metaclass__ = _GenericMeta
-
- def __init__(self, type_=None, args=(), **kwargs):
- self.packagenames = []
- self.name = self.__class__.__name__
- self._bind = kwargs.get('bind', None)
- self.clause_expr = ClauseList(
- operator=operators.comma_op,
- group_contents=True, *args).self_group()
- self.type = sqltypes.to_instance(
- type_ or getattr(self, '__return_type__', None))
-
-
-class next_value(Function):
- """Represent the 'next value', given a :class:`.Sequence`
- as it's single argument.
-
- Compiles into the appropriate function on each backend,
- or will raise NotImplementedError if used on a backend
- that does not provide support for sequences.
-
- """
- type = sqltypes.Integer()
- name = "next_value"
-
- def __init__(self, seq, **kw):
- assert isinstance(seq, schema.Sequence), \
- "next_value() accepts a Sequence object as input."
- self._bind = kw.get('bind', None)
- self.sequence = seq
-
- @property
- def _from_objects(self):
- return []
-
-class AnsiFunction(GenericFunction):
- def __init__(self, **kwargs):
- GenericFunction.__init__(self, **kwargs)
-
-class ReturnTypeFromArgs(GenericFunction):
- """Define a function whose return type is the same as its arguments."""
-
- def __init__(self, *args, **kwargs):
- kwargs.setdefault('type_', _type_from_args(args))
- GenericFunction.__init__(self, args=args, **kwargs)
-
-class coalesce(ReturnTypeFromArgs):
- pass
-
-class max(ReturnTypeFromArgs):
- pass
-
-class min(ReturnTypeFromArgs):
- pass
-
-class sum(ReturnTypeFromArgs):
- pass
-
-
-class now(GenericFunction):
- __return_type__ = sqltypes.DateTime
-
-class concat(GenericFunction):
- __return_type__ = sqltypes.String
- def __init__(self, *args, **kwargs):
- GenericFunction.__init__(self, args=args, **kwargs)
-
-class char_length(GenericFunction):
- __return_type__ = sqltypes.Integer
-
- def __init__(self, arg, **kwargs):
- GenericFunction.__init__(self, args=[arg], **kwargs)
-
-class random(GenericFunction):
- def __init__(self, *args, **kwargs):
- kwargs.setdefault('type_', None)
- GenericFunction.__init__(self, args=args, **kwargs)
-
-class count(GenericFunction):
- """The ANSI COUNT aggregate function. With no arguments, emits COUNT \*."""
-
- __return_type__ = sqltypes.Integer
-
- def __init__(self, expression=None, **kwargs):
- if expression is None:
- expression = text('*')
- GenericFunction.__init__(self, args=(expression,), **kwargs)
-
-class current_date(AnsiFunction):
- __return_type__ = sqltypes.Date
-
-class current_time(AnsiFunction):
- __return_type__ = sqltypes.Time
-
-class current_timestamp(AnsiFunction):
- __return_type__ = sqltypes.DateTime
-
-class current_user(AnsiFunction):
- __return_type__ = sqltypes.String
-
-class localtime(AnsiFunction):
- __return_type__ = sqltypes.DateTime
-
-class localtimestamp(AnsiFunction):
- __return_type__ = sqltypes.DateTime
-
-class session_user(AnsiFunction):
- __return_type__ = sqltypes.String
-
-class sysdate(AnsiFunction):
- __return_type__ = sqltypes.DateTime
-
-class user(AnsiFunction):
- __return_type__ = sqltypes.String
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/operators.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/operators.py
deleted file mode 100755
index 494f76f1..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/operators.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# sql/operators.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Defines operators used in SQL expressions."""
-
-from operator import (
- and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg
- )
-
-# Py2K
-from operator import (div,)
-# end Py2K
-
-from sqlalchemy.util import symbol
-
-
-def from_():
- raise NotImplementedError()
-
-def as_():
- raise NotImplementedError()
-
-def exists():
- raise NotImplementedError()
-
-def is_():
- raise NotImplementedError()
-
-def isnot():
- raise NotImplementedError()
-
-def collate():
- raise NotImplementedError()
-
-def op(a, opstring, b):
- return a.op(opstring)(b)
-
-def like_op(a, b, escape=None):
- return a.like(b, escape=escape)
-
-def notlike_op(a, b, escape=None):
- raise NotImplementedError()
-
-def ilike_op(a, b, escape=None):
- return a.ilike(b, escape=escape)
-
-def notilike_op(a, b, escape=None):
- raise NotImplementedError()
-
-def between_op(a, b, c):
- return a.between(b, c)
-
-def in_op(a, b):
- return a.in_(b)
-
-def notin_op(a, b):
- raise NotImplementedError()
-
-def distinct_op(a):
- return a.distinct()
-
-def startswith_op(a, b, escape=None):
- return a.startswith(b, escape=escape)
-
-def endswith_op(a, b, escape=None):
- return a.endswith(b, escape=escape)
-
-def contains_op(a, b, escape=None):
- return a.contains(b, escape=escape)
-
-def match_op(a, b):
- return a.match(b)
-
-def comma_op(a, b):
- raise NotImplementedError()
-
-def concat_op(a, b):
- return a.concat(b)
-
-def desc_op(a):
- return a.desc()
-
-def asc_op(a):
- return a.asc()
-
-def nullsfirst_op(a):
- return a.nullsfirst()
-
-def nullslast_op(a):
- return a.nullslast()
-
-_commutative = set([eq, ne, add, mul])
-
-def is_commutative(op):
- return op in _commutative
-
-_associative = _commutative.union([concat_op, and_, or_])
-
-
-_smallest = symbol('_smallest')
-_largest = symbol('_largest')
-
-_PRECEDENCE = {
- from_: 15,
- mul: 7,
- truediv: 7,
- # Py2K
- div: 7,
- # end Py2K
- mod: 7,
- neg: 7,
- add: 6,
- sub: 6,
- concat_op: 6,
- match_op: 6,
- ilike_op: 5,
- notilike_op: 5,
- like_op: 5,
- notlike_op: 5,
- in_op: 5,
- notin_op: 5,
- is_: 5,
- isnot: 5,
- eq: 5,
- ne: 5,
- gt: 5,
- lt: 5,
- ge: 5,
- le: 5,
- between_op: 5,
- distinct_op: 5,
- inv: 5,
- and_: 3,
- or_: 2,
- comma_op: -1,
- collate: 7,
- as_: -1,
- exists: 0,
- _smallest: -1000,
- _largest: 1000
-}
-
-def is_precedent(operator, against):
- if operator is against and operator in _associative:
- return False
- else:
- return (_PRECEDENCE.get(operator, _PRECEDENCE[_smallest]) <=
- _PRECEDENCE.get(against, _PRECEDENCE[_largest]))
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/util.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/util.py
deleted file mode 100755
index 1a3f7d2f..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/util.py
+++ /dev/null
@@ -1,717 +0,0 @@
-# sql/util.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from sqlalchemy import exc, schema, util, sql, types as sqltypes
-from sqlalchemy.util import topological
-from sqlalchemy.sql import expression, operators, visitors
-from itertools import chain
-
-"""Utility functions that build upon SQL and Schema constructs."""
-
-def sort_tables(tables):
- """sort a collection of Table objects in order of their foreign-key dependency."""
-
- tables = list(tables)
- tuples = []
- def visit_foreign_key(fkey):
- if fkey.use_alter:
- return
- parent_table = fkey.column.table
- if parent_table in tables:
- child_table = fkey.parent.table
- if parent_table is not child_table:
- tuples.append((parent_table, child_table))
-
- for table in tables:
- visitors.traverse(table,
- {'schema_visitor':True},
- {'foreign_key':visit_foreign_key})
-
- tuples.extend(
- [parent, table] for parent in table._extra_dependencies
- )
-
- return list(topological.sort(tuples, tables))
-
-def find_join_source(clauses, join_to):
- """Given a list of FROM clauses and a selectable,
- return the first index and element from the list of
- clauses which can be joined against the selectable. returns
- None, None if no match is found.
-
- e.g.::
-
- clause1 = table1.join(table2)
- clause2 = table4.join(table5)
-
- join_to = table2.join(table3)
-
- find_join_source([clause1, clause2], join_to) == clause1
-
- """
-
- selectables = list(expression._from_objects(join_to))
- for i, f in enumerate(clauses):
- for s in selectables:
- if f.is_derived_from(s):
- return i, f
- else:
- return None, None
-
-def find_tables(clause, check_columns=False,
- include_aliases=False, include_joins=False,
- include_selects=False, include_crud=False):
- """locate Table objects within the given expression."""
-
- tables = []
- _visitors = {}
-
- if include_selects:
- _visitors['select'] = _visitors['compound_select'] = tables.append
-
- if include_joins:
- _visitors['join'] = tables.append
-
- if include_aliases:
- _visitors['alias'] = tables.append
-
- if include_crud:
- _visitors['insert'] = _visitors['update'] = \
- _visitors['delete'] = lambda ent: tables.append(ent.table)
-
- if check_columns:
- def visit_column(column):
- tables.append(column.table)
- _visitors['column'] = visit_column
-
- _visitors['table'] = tables.append
-
- visitors.traverse(clause, {'column_collections':False}, _visitors)
- return tables
-
-def find_columns(clause):
- """locate Column objects within the given expression."""
-
- cols = util.column_set()
- visitors.traverse(clause, {}, {'column':cols.add})
- return cols
-
-def clause_is_present(clause, search):
- """Given a target clause and a second to search within, return True
- if the target is plainly present in the search without any
- subqueries or aliases involved.
-
- Basically descends through Joins.
-
- """
-
- stack = [search]
- while stack:
- elem = stack.pop()
- if clause is elem:
- return True
- elif isinstance(elem, expression.Join):
- stack.extend((elem.left, elem.right))
- return False
-
-
-def bind_values(clause):
- """Return an ordered list of "bound" values in the given clause.
-
- E.g.::
-
- >>> expr = and_(
- ... table.c.foo==5, table.c.foo==7
- ... )
- >>> bind_values(expr)
- [5, 7]
- """
-
- v = []
- def visit_bindparam(bind):
- value = bind.value
-
- # evaluate callables
- if callable(value):
- value = value()
-
- v.append(value)
-
- visitors.traverse(clause, {}, {'bindparam':visit_bindparam})
- return v
-
-def _quote_ddl_expr(element):
- if isinstance(element, basestring):
- element = element.replace("'", "''")
- return "'%s'" % element
- else:
- return repr(element)
-
-def expression_as_ddl(clause):
- """Given a SQL expression, convert for usage in DDL, such as
- CREATE INDEX and CHECK CONSTRAINT.
-
- Converts bind params into quoted literals, column identifiers
- into detached column constructs so that the parent table
- identifier is not included.
-
- """
- def repl(element):
- if isinstance(element, expression._BindParamClause):
- return expression.literal_column(_quote_ddl_expr(element.value))
- elif isinstance(element, expression.ColumnClause) and \
- element.table is not None:
- return expression.column(element.name)
- else:
- return None
-
- return visitors.replacement_traverse(clause, {}, repl)
-
-def adapt_criterion_to_null(crit, nulls):
- """given criterion containing bind params, convert selected elements to IS NULL."""
-
- def visit_binary(binary):
- if isinstance(binary.left, expression._BindParamClause) and binary.left.key in nulls:
- # reverse order if the NULL is on the left side
- binary.left = binary.right
- binary.right = expression.null()
- binary.operator = operators.is_
- binary.negate = operators.isnot
- elif isinstance(binary.right, expression._BindParamClause) and binary.right.key in nulls:
- binary.right = expression.null()
- binary.operator = operators.is_
- binary.negate = operators.isnot
-
- return visitors.cloned_traverse(crit, {}, {'binary':visit_binary})
-
-def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None):
- """create a join condition between two tables or selectables.
-
- e.g.::
-
- join_condition(tablea, tableb)
-
- would produce an expression along the lines of::
-
- tablea.c.id==tableb.c.tablea_id
-
- The join is determined based on the foreign key relationships
- between the two selectables. If there are multiple ways
- to join, or no way to join, an error is raised.
-
- :param ignore_nonexistent_tables: Deprecated - this
- flag is no longer used. Only resolution errors regarding
- the two given tables are propagated.
-
- :param a_subset: An optional expression that is a sub-component
- of ``a``. An attempt will be made to join to just this sub-component
- first before looking at the full ``a`` construct, and if found
- will be successful even if there are other ways to join to ``a``.
- This allows the "right side" of a join to be passed thereby
- providing a "natural join".
-
- """
- crit = []
- constraints = set()
-
- for left in (a_subset, a):
- if left is None:
- continue
- for fk in sorted(
- b.foreign_keys,
- key=lambda fk:fk.parent._creation_order):
- try:
- col = fk.get_referent(left)
- except exc.NoReferenceError, nrte:
- if nrte.table_name == left.name:
- raise
- else:
- continue
-
- if col is not None:
- crit.append(col == fk.parent)
- constraints.add(fk.constraint)
- if left is not b:
- for fk in sorted(
- left.foreign_keys,
- key=lambda fk:fk.parent._creation_order):
- try:
- col = fk.get_referent(b)
- except exc.NoReferenceError, nrte:
- if nrte.table_name == b.name:
- raise
- else:
- # this is totally covered. can't get
- # coverage to mark it.
- continue
-
- if col is not None:
- crit.append(col == fk.parent)
- constraints.add(fk.constraint)
- if crit:
- break
-
- if len(crit) == 0:
- if isinstance(b, expression._FromGrouping):
- hint = " Perhaps you meant to convert the right side to a "\
- "subquery using alias()?"
- else:
- hint = ""
- raise exc.ArgumentError(
- "Can't find any foreign key relationships "
- "between '%s' and '%s'.%s" % (a.description, b.description, hint))
- elif len(constraints) > 1:
- raise exc.ArgumentError(
- "Can't determine join between '%s' and '%s'; "
- "tables have more than one foreign key "
- "constraint relationship between them. "
- "Please specify the 'onclause' of this "
- "join explicitly." % (a.description, b.description))
- elif len(crit) == 1:
- return (crit[0])
- else:
- return sql.and_(*crit)
-
-
-class Annotated(object):
- """clones a ClauseElement and applies an 'annotations' dictionary.
-
- Unlike regular clones, this clone also mimics __hash__() and
- __cmp__() of the original element so that it takes its place
- in hashed collections.
-
- A reference to the original element is maintained, for the important
- reason of keeping its hash value current. When GC'ed, the
- hash value may be reused, causing conflicts.
-
- """
-
- def __new__(cls, *args):
- if not args:
- # clone constructor
- return object.__new__(cls)
- else:
- element, values = args
- # pull appropriate subclass from registry of annotated
- # classes
- try:
- cls = annotated_classes[element.__class__]
- except KeyError:
- cls = annotated_classes[element.__class__] = type.__new__(type,
- "Annotated%s" % element.__class__.__name__,
- (Annotated, element.__class__), {})
- return object.__new__(cls)
-
- def __init__(self, element, values):
- # force FromClause to generate their internal
- # collections into __dict__
- if isinstance(element, expression.FromClause):
- element.c
-
- self.__dict__ = element.__dict__.copy()
- self.__element = element
- self._annotations = values
-
- def _annotate(self, values):
- _values = self._annotations.copy()
- _values.update(values)
- clone = self.__class__.__new__(self.__class__)
- clone.__dict__ = self.__dict__.copy()
- clone._annotations = _values
- return clone
-
- def _deannotate(self):
- return self.__element
-
- def _compiler_dispatch(self, visitor, **kw):
- return self.__element.__class__._compiler_dispatch(self, visitor, **kw)
-
- @property
- def _constructor(self):
- return self.__element._constructor
-
- def _clone(self):
- clone = self.__element._clone()
- if clone is self.__element:
- # detect immutable, don't change anything
- return self
- else:
- # update the clone with any changes that have occurred
- # to this object's __dict__.
- clone.__dict__.update(self.__dict__)
- return Annotated(clone, self._annotations)
-
- def __hash__(self):
- return hash(self.__element)
-
- def __cmp__(self, other):
- return cmp(hash(self.__element), hash(other))
-
-# hard-generate Annotated subclasses. this technique
-# is used instead of on-the-fly types (i.e. type.__new__())
-# so that the resulting objects are pickleable.
-annotated_classes = {}
-
-for cls in expression.__dict__.values() + [schema.Column, schema.Table]:
- if isinstance(cls, type) and issubclass(cls, expression.ClauseElement):
- exec "class Annotated%s(Annotated, cls):\n" \
- " pass" % (cls.__name__, ) in locals()
- exec "annotated_classes[cls] = Annotated%s" % (cls.__name__)
-
-def _deep_annotate(element, annotations, exclude=None):
- """Deep copy the given ClauseElement, annotating each element with the given annotations dictionary.
-
- Elements within the exclude collection will be cloned but not annotated.
-
- """
- def clone(elem):
- # check if element is present in the exclude list.
- # take into account proxying relationships.
- if exclude and \
- hasattr(elem, 'proxy_set') and \
- elem.proxy_set.intersection(exclude):
- elem = elem._clone()
- elif annotations != elem._annotations:
- elem = elem._annotate(annotations.copy())
- elem._copy_internals(clone=clone)
- return elem
-
- if element is not None:
- element = clone(element)
- return element
-
-def _deep_deannotate(element):
- """Deep copy the given element, removing all annotations."""
-
- def clone(elem):
- elem = elem._deannotate()
- elem._copy_internals(clone=clone)
- return elem
-
- if element is not None:
- element = clone(element)
- return element
-
-
-def splice_joins(left, right, stop_on=None):
- if left is None:
- return right
-
- stack = [(right, None)]
-
- adapter = ClauseAdapter(left)
- ret = None
- while stack:
- (right, prevright) = stack.pop()
- if isinstance(right, expression.Join) and right is not stop_on:
- right = right._clone()
- right._reset_exported()
- right.onclause = adapter.traverse(right.onclause)
- stack.append((right.left, right))
- else:
- right = adapter.traverse(right)
- if prevright is not None:
- prevright.left = right
- if ret is None:
- ret = right
-
- return ret
-
-def reduce_columns(columns, *clauses, **kw):
- """given a list of columns, return a 'reduced' set based on natural equivalents.
-
- the set is reduced to the smallest list of columns which have no natural
- equivalent present in the list. A "natural equivalent" means that two columns
- will ultimately represent the same value because they are related by a foreign key.
-
- \*clauses is an optional list of join clauses which will be traversed
- to further identify columns that are "equivalent".
-
- \**kw may specify 'ignore_nonexistent_tables' to ignore foreign keys
- whose tables are not yet configured.
-
- This function is primarily used to determine the most minimal "primary key"
- from a selectable, by reducing the set of primary key columns present
- in the the selectable to just those that are not repeated.
-
- """
- ignore_nonexistent_tables = kw.pop('ignore_nonexistent_tables', False)
-
- columns = util.ordered_column_set(columns)
-
- omit = util.column_set()
- for col in columns:
- for fk in chain(*[c.foreign_keys for c in col.proxy_set]):
- for c in columns:
- if c is col:
- continue
- try:
- fk_col = fk.column
- except exc.NoReferencedTableError:
- if ignore_nonexistent_tables:
- continue
- else:
- raise
- if fk_col.shares_lineage(c):
- omit.add(col)
- break
-
- if clauses:
- def visit_binary(binary):
- if binary.operator == operators.eq:
- cols = util.column_set(chain(*[c.proxy_set for c in columns.difference(omit)]))
- if binary.left in cols and binary.right in cols:
- for c in columns:
- if c.shares_lineage(binary.right):
- omit.add(c)
- break
- for clause in clauses:
- visitors.traverse(clause, {}, {'binary':visit_binary})
-
- return expression.ColumnSet(columns.difference(omit))
-
-def criterion_as_pairs(expression, consider_as_foreign_keys=None,
- consider_as_referenced_keys=None, any_operator=False):
- """traverse an expression and locate binary criterion pairs."""
-
- if consider_as_foreign_keys and consider_as_referenced_keys:
- raise exc.ArgumentError("Can only specify one of "
- "'consider_as_foreign_keys' or "
- "'consider_as_referenced_keys'")
-
- def visit_binary(binary):
- if not any_operator and binary.operator is not operators.eq:
- return
- if not isinstance(binary.left, sql.ColumnElement) or \
- not isinstance(binary.right, sql.ColumnElement):
- return
-
- if consider_as_foreign_keys:
- if binary.left in consider_as_foreign_keys and \
- (binary.right is binary.left or
- binary.right not in consider_as_foreign_keys):
- pairs.append((binary.right, binary.left))
- elif binary.right in consider_as_foreign_keys and \
- (binary.left is binary.right or
- binary.left not in consider_as_foreign_keys):
- pairs.append((binary.left, binary.right))
- elif consider_as_referenced_keys:
- if binary.left in consider_as_referenced_keys and \
- (binary.right is binary.left or
- binary.right not in consider_as_referenced_keys):
- pairs.append((binary.left, binary.right))
- elif binary.right in consider_as_referenced_keys and \
- (binary.left is binary.right or
- binary.left not in consider_as_referenced_keys):
- pairs.append((binary.right, binary.left))
- else:
- if isinstance(binary.left, schema.Column) and \
- isinstance(binary.right, schema.Column):
- if binary.left.references(binary.right):
- pairs.append((binary.right, binary.left))
- elif binary.right.references(binary.left):
- pairs.append((binary.left, binary.right))
- pairs = []
- visitors.traverse(expression, {}, {'binary':visit_binary})
- return pairs
-
-def folded_equivalents(join, equivs=None):
- """Return a list of uniquely named columns.
-
- The column list of the given Join will be narrowed
- down to a list of all equivalently-named,
- equated columns folded into one column, where 'equated' means they are
- equated to each other in the ON clause of this join.
-
- This function is used by Join.select(fold_equivalents=True).
-
- Deprecated. This function is used for a certain kind of
- "polymorphic_union" which is designed to achieve joined
- table inheritance where the base table has no "discriminator"
- column; [ticket:1131] will provide a better way to
- achieve this.
-
- """
- if equivs is None:
- equivs = set()
- def visit_binary(binary):
- if binary.operator == operators.eq and binary.left.name == binary.right.name:
- equivs.add(binary.right)
- equivs.add(binary.left)
- visitors.traverse(join.onclause, {}, {'binary':visit_binary})
- collist = []
- if isinstance(join.left, expression.Join):
- left = folded_equivalents(join.left, equivs)
- else:
- left = list(join.left.columns)
- if isinstance(join.right, expression.Join):
- right = folded_equivalents(join.right, equivs)
- else:
- right = list(join.right.columns)
- used = set()
- for c in left + right:
- if c in equivs:
- if c.name not in used:
- collist.append(c)
- used.add(c.name)
- else:
- collist.append(c)
- return collist
-
-class AliasedRow(object):
- """Wrap a RowProxy with a translation map.
-
- This object allows a set of keys to be translated
- to those present in a RowProxy.
-
- """
- def __init__(self, row, map):
- # AliasedRow objects don't nest, so un-nest
- # if another AliasedRow was passed
- if isinstance(row, AliasedRow):
- self.row = row.row
- else:
- self.row = row
- self.map = map
-
- def __contains__(self, key):
- return self.map[key] in self.row
-
- def has_key(self, key):
- return key in self
-
- def __getitem__(self, key):
- return self.row[self.map[key]]
-
- def keys(self):
- return self.row.keys()
-
-
-class ClauseAdapter(visitors.ReplacingCloningVisitor):
- """Clones and modifies clauses based on column correspondence.
-
- E.g.::
-
- table1 = Table('sometable', metadata,
- Column('col1', Integer),
- Column('col2', Integer)
- )
- table2 = Table('someothertable', metadata,
- Column('col1', Integer),
- Column('col2', Integer)
- )
-
- condition = table1.c.col1 == table2.c.col1
-
- make an alias of table1::
-
- s = table1.alias('foo')
-
- calling ``ClauseAdapter(s).traverse(condition)`` converts
- condition to read::
-
- s.c.col1 == table2.c.col1
-
- """
- def __init__(self, selectable, equivalents=None, include=None, exclude=None):
- self.__traverse_options__ = {'column_collections':False, 'stop_on':[selectable]}
- self.selectable = selectable
- self.include = include
- self.exclude = exclude
- self.equivalents = util.column_dict(equivalents or {})
-
- def _corresponding_column(self, col, require_embedded, _seen=util.EMPTY_SET):
- newcol = self.selectable.corresponding_column(col, require_embedded=require_embedded)
-
- if newcol is None and col in self.equivalents and col not in _seen:
- for equiv in self.equivalents[col]:
- newcol = self._corresponding_column(equiv, require_embedded=require_embedded, _seen=_seen.union([col]))
- if newcol is not None:
- return newcol
- return newcol
-
- def replace(self, col):
- if isinstance(col, expression.FromClause):
- if self.selectable.is_derived_from(col):
- return self.selectable
-
- if not isinstance(col, expression.ColumnElement):
- return None
-
- if self.include and col not in self.include:
- return None
- elif self.exclude and col in self.exclude:
- return None
-
- return self._corresponding_column(col, True)
-
-class ColumnAdapter(ClauseAdapter):
- """Extends ClauseAdapter with extra utility functions.
-
- Provides the ability to "wrap" this ClauseAdapter
- around another, a columns dictionary which returns
- adapted elements given an original, and an
- adapted_row() factory.
-
- """
- def __init__(self, selectable, equivalents=None,
- chain_to=None, include=None,
- exclude=None, adapt_required=False):
- ClauseAdapter.__init__(self, selectable, equivalents, include, exclude)
- if chain_to:
- self.chain(chain_to)
- self.columns = util.populate_column_dict(self._locate_col)
- self.adapt_required = adapt_required
-
- def wrap(self, adapter):
- ac = self.__class__.__new__(self.__class__)
- ac.__dict__ = self.__dict__.copy()
- ac._locate_col = ac._wrap(ac._locate_col, adapter._locate_col)
- ac.adapt_clause = ac._wrap(ac.adapt_clause, adapter.adapt_clause)
- ac.adapt_list = ac._wrap(ac.adapt_list, adapter.adapt_list)
- ac.columns = util.populate_column_dict(ac._locate_col)
- return ac
-
- adapt_clause = ClauseAdapter.traverse
- adapt_list = ClauseAdapter.copy_and_process
-
- def _wrap(self, local, wrapped):
- def locate(col):
- col = local(col)
- return wrapped(col)
- return locate
-
- def _locate_col(self, col):
- c = self._corresponding_column(col, True)
- if c is None:
- c = self.adapt_clause(col)
-
- # anonymize labels in case they have a hardcoded name
- if isinstance(c, expression._Label):
- c = c.label(None)
-
- # adapt_required indicates that if we got the same column
- # back which we put in (i.e. it passed through),
- # it's not correct. this is used by eagerloading which
- # knows that all columns and expressions need to be adapted
- # to a result row, and a "passthrough" is definitely targeting
- # the wrong column.
- if self.adapt_required and c is col:
- return None
-
- return c
-
- def adapted_row(self, row):
- return AliasedRow(row, self.columns)
-
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['columns']
- return d
-
- def __setstate__(self, state):
- self.__dict__.update(state)
- self.columns = util.PopulateDict(self._locate_col)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/visitors.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/visitors.py
deleted file mode 100755
index 0c6be97d..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/sql/visitors.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# sql/visitors.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Visitor/traversal interface and library functions.
-
-SQLAlchemy schema and expression constructs rely on a Python-centric
-version of the classic "visitor" pattern as the primary way in which
-they apply functionality. The most common use of this pattern
-is statement compilation, where individual expression classes match
-up to rendering methods that produce a string result. Beyond this,
-the visitor system is also used to inspect expressions for various
-information and patterns, as well as for usage in
-some kinds of expression transformation. Other kinds of transformation
-use a non-visitor traversal system.
-
-For many examples of how the visit system is used, see the
-sqlalchemy.sql.util and the sqlalchemy.sql.compiler modules.
-For an introduction to clause adaption, see
-http://techspot.zzzeek.org/?p=19 .
-
-"""
-
-from collections import deque
-import re
-from sqlalchemy import util
-import operator
-
-__all__ = ['VisitableType', 'Visitable', 'ClauseVisitor',
- 'CloningVisitor', 'ReplacingCloningVisitor', 'iterate',
- 'iterate_depthfirst', 'traverse_using', 'traverse',
- 'cloned_traverse', 'replacement_traverse']
-
-class VisitableType(type):
- """Metaclass which checks for a `__visit_name__` attribute and
- applies `_compiler_dispatch` method to classes.
-
- """
-
- def __init__(cls, clsname, bases, clsdict):
- if cls.__name__ == 'Visitable' or not hasattr(cls, '__visit_name__'):
- super(VisitableType, cls).__init__(clsname, bases, clsdict)
- return
-
- _generate_dispatch(cls)
-
- super(VisitableType, cls).__init__(clsname, bases, clsdict)
-
-def _generate_dispatch(cls):
- # set up an optimized visit dispatch function
- # for use by the compiler
- if '__visit_name__' in cls.__dict__:
- visit_name = cls.__visit_name__
- if isinstance(visit_name, str):
- getter = operator.attrgetter("visit_%s" % visit_name)
- def _compiler_dispatch(self, visitor, **kw):
- return getter(visitor)(self, **kw)
- else:
- def _compiler_dispatch(self, visitor, **kw):
- return getattr(visitor, 'visit_%s' % self.__visit_name__)(self, **kw)
-
- cls._compiler_dispatch = _compiler_dispatch
-
-class Visitable(object):
- """Base class for visitable objects, applies the
- ``VisitableType`` metaclass.
-
- """
-
- __metaclass__ = VisitableType
-
-class ClauseVisitor(object):
- """Base class for visitor objects which can traverse using
- the traverse() function.
-
- """
-
- __traverse_options__ = {}
-
- def traverse_single(self, obj, **kw):
- for v in self._visitor_iterator:
- meth = getattr(v, "visit_%s" % obj.__visit_name__, None)
- if meth:
- return meth(obj, **kw)
-
- def iterate(self, obj):
- """traverse the given expression structure, returning an iterator of all elements."""
-
- return iterate(obj, self.__traverse_options__)
-
- def traverse(self, obj):
- """traverse and visit the given expression structure."""
-
- return traverse(obj, self.__traverse_options__, self._visitor_dict)
-
- @util.memoized_property
- def _visitor_dict(self):
- visitors = {}
-
- for name in dir(self):
- if name.startswith('visit_'):
- visitors[name[6:]] = getattr(self, name)
- return visitors
-
- @property
- def _visitor_iterator(self):
- """iterate through this visitor and each 'chained' visitor."""
-
- v = self
- while v:
- yield v
- v = getattr(v, '_next', None)
-
- def chain(self, visitor):
- """'chain' an additional ClauseVisitor onto this ClauseVisitor.
-
- the chained visitor will receive all visit events after this one.
-
- """
- tail = list(self._visitor_iterator)[-1]
- tail._next = visitor
- return self
-
-class CloningVisitor(ClauseVisitor):
- """Base class for visitor objects which can traverse using
- the cloned_traverse() function.
-
- """
-
- def copy_and_process(self, list_):
- """Apply cloned traversal to the given list of elements, and return the new list."""
-
- return [self.traverse(x) for x in list_]
-
- def traverse(self, obj):
- """traverse and visit the given expression structure."""
-
- return cloned_traverse(obj, self.__traverse_options__, self._visitor_dict)
-
-class ReplacingCloningVisitor(CloningVisitor):
- """Base class for visitor objects which can traverse using
- the replacement_traverse() function.
-
- """
-
- def replace(self, elem):
- """receive pre-copied elements during a cloning traversal.
-
- If the method returns a new element, the element is used
- instead of creating a simple copy of the element. Traversal
- will halt on the newly returned element if it is re-encountered.
- """
- return None
-
- def traverse(self, obj):
- """traverse and visit the given expression structure."""
-
- def replace(elem):
- for v in self._visitor_iterator:
- e = v.replace(elem)
- if e is not None:
- return e
- return replacement_traverse(obj, self.__traverse_options__, replace)
-
-def iterate(obj, opts):
- """traverse the given expression structure, returning an iterator.
-
- traversal is configured to be breadth-first.
-
- """
- stack = deque([obj])
- while stack:
- t = stack.popleft()
- yield t
- for c in t.get_children(**opts):
- stack.append(c)
-
-def iterate_depthfirst(obj, opts):
- """traverse the given expression structure, returning an iterator.
-
- traversal is configured to be depth-first.
-
- """
- stack = deque([obj])
- traversal = deque()
- while stack:
- t = stack.pop()
- traversal.appendleft(t)
- for c in t.get_children(**opts):
- stack.append(c)
- return iter(traversal)
-
-def traverse_using(iterator, obj, visitors):
- """visit the given expression structure using the given iterator of objects."""
-
- for target in iterator:
- meth = visitors.get(target.__visit_name__, None)
- if meth:
- meth(target)
- return obj
-
-def traverse(obj, opts, visitors):
- """traverse and visit the given expression structure using the default iterator."""
-
- return traverse_using(iterate(obj, opts), obj, visitors)
-
-def traverse_depthfirst(obj, opts, visitors):
- """traverse and visit the given expression structure using the depth-first iterator."""
-
- return traverse_using(iterate_depthfirst(obj, opts), obj, visitors)
-
-def cloned_traverse(obj, opts, visitors):
- """clone the given expression structure, allowing modifications by visitors."""
-
- cloned = util.column_dict()
-
- def clone(element):
- if element not in cloned:
- cloned[element] = element._clone()
- return cloned[element]
-
- obj = clone(obj)
- stack = [obj]
-
- while stack:
- t = stack.pop()
- if t in cloned:
- continue
- t._copy_internals(clone=clone)
-
- meth = visitors.get(t.__visit_name__, None)
- if meth:
- meth(t)
-
- for c in t.get_children(**opts):
- stack.append(c)
- return obj
-
-def replacement_traverse(obj, opts, replace):
- """clone the given expression structure, allowing element replacement by a given replacement function."""
-
- cloned = util.column_dict()
- stop_on = util.column_set(opts.get('stop_on', []))
-
- def clone(element):
- newelem = replace(element)
- if newelem is not None:
- stop_on.add(newelem)
- return newelem
-
- if element not in cloned:
- cloned[element] = element._clone()
- return cloned[element]
-
- obj = clone(obj)
- stack = [obj]
- while stack:
- t = stack.pop()
- if t in stop_on:
- continue
- t._copy_internals(clone=clone)
- for c in t.get_children(**opts):
- stack.append(c)
- return obj
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/types.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/types.py
deleted file mode 100755
index e8d0b6f2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/types.py
+++ /dev/null
@@ -1,2140 +0,0 @@
-# sqlalchemy/types.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""defines genericized SQL types, each represented by a subclass of
-:class:`~sqlalchemy.types.AbstractType`. Dialects define further subclasses of these
-types.
-
-For more information see the SQLAlchemy documentation on types.
-
-"""
-__all__ = [ 'TypeEngine', 'TypeDecorator', 'AbstractType', 'UserDefinedType',
- 'INT', 'CHAR', 'VARCHAR', 'NCHAR', 'NVARCHAR','TEXT', 'Text',
- 'FLOAT', 'NUMERIC', 'REAL', 'DECIMAL', 'TIMESTAMP', 'DATETIME',
- 'CLOB', 'BLOB', 'BOOLEAN', 'SMALLINT', 'INTEGER', 'DATE', 'TIME',
- 'String', 'Integer', 'SmallInteger', 'BigInteger', 'Numeric',
- 'Float', 'DateTime', 'Date', 'Time', 'LargeBinary', 'Binary',
- 'Boolean', 'Unicode', 'MutableType', 'Concatenable',
- 'UnicodeText','PickleType', 'Interval', 'Enum' ]
-
-import inspect
-import datetime as dt
-import codecs
-
-from sqlalchemy import exc, schema
-from sqlalchemy.sql import expression, operators
-from sqlalchemy.util import pickle
-from sqlalchemy.util.compat import decimal
-from sqlalchemy.sql.visitors import Visitable
-from sqlalchemy import util
-from sqlalchemy import processors, events
-import collections
-default = util.importlater("sqlalchemy.engine", "default")
-
-NoneType = type(None)
-if util.jython:
- import array
-
-class AbstractType(Visitable):
- """Base for all types - not needed except for backwards
- compatibility."""
-
-class TypeEngine(AbstractType):
- """Base for built-in types."""
-
- def copy_value(self, value):
- return value
-
- def bind_processor(self, dialect):
- """Return a conversion function for processing bind values.
-
- Returns a callable which will receive a bind parameter value
- as the sole positional argument and will return a value to
- send to the DB-API.
-
- If processing is not necessary, the method should return ``None``.
-
- :param dialect: Dialect instance in use.
-
- """
- return None
-
- def result_processor(self, dialect, coltype):
- """Return a conversion function for processing result row values.
-
- Returns a callable which will receive a result row column
- value as the sole positional argument and will return a value
- to return to the user.
-
- If processing is not necessary, the method should return ``None``.
-
- :param dialect: Dialect instance in use.
-
- :param coltype: DBAPI coltype argument received in cursor.description.
-
- """
- return None
-
- def compare_values(self, x, y):
- """Compare two values for equality."""
-
- return x == y
-
- def is_mutable(self):
- """Return True if the target Python type is 'mutable'.
-
- This allows systems like the ORM to know if a column value can
- be considered 'not changed' by comparing the identity of
- objects alone. Values such as dicts, lists which
- are serialized into strings are examples of "mutable"
- column structures.
-
- .. note:: This functionality is now superseded by the
- ``sqlalchemy.ext.mutable`` extension described in
- :ref:`mutable_toplevel`.
-
- When this method is overridden, :meth:`copy_value` should
- also be supplied. The :class:`.MutableType` mixin
- is recommended as a helper.
-
- """
- return False
-
- def get_dbapi_type(self, dbapi):
- """Return the corresponding type object from the underlying DB-API, if
- any.
-
- This can be useful for calling ``setinputsizes()``, for example.
-
- """
- return None
-
- def _adapt_expression(self, op, othertype):
- """evaluate the return type of <self> <op> <othertype>,
- and apply any adaptations to the given operator.
-
- """
- return op, self
-
- @util.memoized_property
- def _type_affinity(self):
- """Return a rudimental 'affinity' value expressing the general class
- of type."""
-
- typ = None
- for t in self.__class__.__mro__:
- if t is TypeEngine or t is UserDefinedType:
- return typ
- elif issubclass(t, TypeEngine):
- typ = t
- else:
- return self.__class__
-
- def dialect_impl(self, dialect):
- """Return a dialect-specific implementation for this :class:`.TypeEngine`."""
-
- try:
- return dialect._type_memos[self]['impl']
- except KeyError:
- return self._dialect_info(dialect)['impl']
-
- def _cached_bind_processor(self, dialect):
- """Return a dialect-specific bind processor for this type."""
-
- try:
- return dialect._type_memos[self]['bind']
- except KeyError:
- d = self._dialect_info(dialect)
- d['bind'] = bp = d['impl'].bind_processor(dialect)
- return bp
-
- def _cached_result_processor(self, dialect, coltype):
- """Return a dialect-specific result processor for this type."""
-
- try:
- return dialect._type_memos[self][coltype]
- except KeyError:
- d = self._dialect_info(dialect)
- # key assumption: DBAPI type codes are
- # constants. Else this dictionary would
- # grow unbounded.
- d[coltype] = rp = d['impl'].result_processor(dialect, coltype)
- return rp
-
- def _dialect_info(self, dialect):
- """Return a dialect-specific registry which
- caches a dialect-specific implementation, bind processing
- function, and one or more result processing functions."""
-
- if self in dialect._type_memos:
- return dialect._type_memos[self]
- else:
- impl = self._gen_dialect_impl(dialect)
- if impl is self:
- impl = self.adapt(type(self))
- # this can't be self, else we create a cycle
- assert impl is not self
- dialect._type_memos[self] = d = {'impl':impl}
- return d
-
- def _gen_dialect_impl(self, dialect):
- return dialect.type_descriptor(self)
-
- def adapt(self, cls, **kw):
- """Produce an "adapted" form of this type, given an "impl" class
- to work with.
-
- This method is used internally to associate generic
- types with "implementation" types that are specific to a particular
- dialect.
- """
- return util.constructor_copy(self, cls, **kw)
-
- def _coerce_compared_value(self, op, value):
- """Suggest a type for a 'coerced' Python value in an expression.
-
- Given an operator and value, gives the type a chance
- to return a type which the value should be coerced into.
-
- The default behavior here is conservative; if the right-hand
- side is already coerced into a SQL type based on its
- Python type, it is usually left alone.
-
- End-user functionality extension here should generally be via
- :class:`.TypeDecorator`, which provides more liberal behavior in that
- it defaults to coercing the other side of the expression into this
- type, thus applying special Python conversions above and beyond those
- needed by the DBAPI to both ides. It also provides the public method
- :meth:`.TypeDecorator.coerce_compared_value` which is intended for
- end-user customization of this behavior.
-
- """
- _coerced_type = _type_map.get(type(value), NULLTYPE)
- if _coerced_type is NULLTYPE or _coerced_type._type_affinity \
- is self._type_affinity:
- return self
- else:
- return _coerced_type
-
- def _compare_type_affinity(self, other):
- return self._type_affinity is other._type_affinity
-
- def compile(self, dialect=None):
- """Produce a string-compiled form of this :class:`.TypeEngine`.
-
- When called with no arguments, uses a "default" dialect
- to produce a string result.
-
- :param dialect: a :class:`.Dialect` instance.
-
- """
- # arg, return value is inconsistent with
- # ClauseElement.compile()....this is a mistake.
-
- if not dialect:
- dialect = self._default_dialect
-
- return dialect.type_compiler.process(self)
-
- @property
- def _default_dialect(self):
- if self.__class__.__module__.startswith("sqlalchemy.dialects"):
- tokens = self.__class__.__module__.split(".")[0:3]
- mod = ".".join(tokens)
- return getattr(__import__(mod).dialects, tokens[-1]).dialect()
- else:
- return default.DefaultDialect()
-
- def __str__(self):
- # Py3K
- #return unicode(self.compile())
- # Py2K
- return unicode(self.compile()).\
- encode('ascii', 'backslashreplace')
- # end Py2K
-
- def __init__(self, *args, **kwargs):
- """Support implementations that were passing arguments"""
- if args or kwargs:
- util.warn_deprecated("Passing arguments to type object "
- "constructor %s is deprecated" % self.__class__)
-
- def __repr__(self):
- return "%s(%s)" % (
- self.__class__.__name__,
- ", ".join("%s=%r" % (k, getattr(self, k, None))
- for k in inspect.getargspec(self.__init__)[0][1:]))
-
-
-class UserDefinedType(TypeEngine):
- """Base for user defined types.
-
- This should be the base of new types. Note that
- for most cases, :class:`.TypeDecorator` is probably
- more appropriate::
-
- import sqlalchemy.types as types
-
- class MyType(types.UserDefinedType):
- def __init__(self, precision = 8):
- self.precision = precision
-
- def get_col_spec(self):
- return "MYTYPE(%s)" % self.precision
-
- def bind_processor(self, dialect):
- def process(value):
- return value
- return process
-
- def result_processor(self, dialect, coltype):
- def process(value):
- return value
- return process
-
- Once the type is made, it's immediately usable::
-
- table = Table('foo', meta,
- Column('id', Integer, primary_key=True),
- Column('data', MyType(16))
- )
-
- """
- __visit_name__ = "user_defined"
-
- def _adapt_expression(self, op, othertype):
- """evaluate the return type of <self> <op> <othertype>,
- and apply any adaptations to the given operator.
-
- """
- return self.adapt_operator(op), self
-
- def adapt_operator(self, op):
- """A hook which allows the given operator to be adapted
- to something new.
-
- See also UserDefinedType._adapt_expression(), an as-yet-
- semi-public method with greater capability in this regard.
-
- """
- return op
-
-class TypeDecorator(TypeEngine):
- """Allows the creation of types which add additional functionality
- to an existing type.
-
- This method is preferred to direct subclassing of SQLAlchemy's
- built-in types as it ensures that all required functionality of
- the underlying type is kept in place.
-
- Typical usage::
-
- import sqlalchemy.types as types
-
- class MyType(types.TypeDecorator):
- '''Prefixes Unicode values with "PREFIX:" on the way in and
- strips it off on the way out.
- '''
-
- impl = types.Unicode
-
- def process_bind_param(self, value, dialect):
- return "PREFIX:" + value
-
- def process_result_value(self, value, dialect):
- return value[7:]
-
- def copy(self):
- return MyType(self.impl.length)
-
- The class-level "impl" variable is required, and can reference any
- TypeEngine class. Alternatively, the load_dialect_impl() method
- can be used to provide different type classes based on the dialect
- given; in this case, the "impl" variable can reference
- ``TypeEngine`` as a placeholder.
-
- Types that receive a Python type that isn't similar to the ultimate type
- used may want to define the :meth:`TypeDecorator.coerce_compared_value`
- method. This is used to give the expression system a hint when coercing
- Python objects into bind parameters within expressions. Consider this
- expression::
-
- mytable.c.somecol + datetime.date(2009, 5, 15)
-
- Above, if "somecol" is an ``Integer`` variant, it makes sense that
- we're doing date arithmetic, where above is usually interpreted
- by databases as adding a number of days to the given date.
- The expression system does the right thing by not attempting to
- coerce the "date()" value into an integer-oriented bind parameter.
-
- However, in the case of ``TypeDecorator``, we are usually changing an
- incoming Python type to something new - ``TypeDecorator`` by default will
- "coerce" the non-typed side to be the same type as itself. Such as below,
- we define an "epoch" type that stores a date value as an integer::
-
- class MyEpochType(types.TypeDecorator):
- impl = types.Integer
-
- epoch = datetime.date(1970, 1, 1)
-
- def process_bind_param(self, value, dialect):
- return (value - self.epoch).days
-
- def process_result_value(self, value, dialect):
- return self.epoch + timedelta(days=value)
-
- Our expression of ``somecol + date`` with the above type will coerce the
- "date" on the right side to also be treated as ``MyEpochType``.
-
- This behavior can be overridden via the
- :meth:`~TypeDecorator.coerce_compared_value` method, which returns a type
- that should be used for the value of the expression. Below we set it such
- that an integer value will be treated as an ``Integer``, and any other
- value is assumed to be a date and will be treated as a ``MyEpochType``::
-
- def coerce_compared_value(self, op, value):
- if isinstance(value, int):
- return Integer()
- else:
- return self
-
- """
-
- __visit_name__ = "type_decorator"
-
- def __init__(self, *args, **kwargs):
- """Construct a :class:`.TypeDecorator`.
-
- Arguments sent here are passed to the constructor
- of the class assigned to the ``impl`` class level attribute,
- where the ``self.impl`` attribute is assigned an instance
- of the implementation type. If ``impl`` at the class level
- is already an instance, then it's assigned to ``self.impl``
- as is.
-
- Subclasses can override this to customize the generation
- of ``self.impl``.
-
- """
- if not hasattr(self.__class__, 'impl'):
- raise AssertionError("TypeDecorator implementations "
- "require a class-level variable "
- "'impl' which refers to the class of "
- "type being decorated")
- self.impl = to_instance(self.__class__.impl, *args, **kwargs)
-
-
- def _gen_dialect_impl(self, dialect):
- adapted = dialect.type_descriptor(self)
- if adapted is not self:
- return adapted
-
- # otherwise adapt the impl type, link
- # to a copy of this TypeDecorator and return
- # that.
- typedesc = self.load_dialect_impl(dialect).dialect_impl(dialect)
- tt = self.copy()
- if not isinstance(tt, self.__class__):
- raise AssertionError('Type object %s does not properly '
- 'implement the copy() method, it must '
- 'return an object of type %s' % (self,
- self.__class__))
- tt.impl = typedesc
- return tt
-
- @util.memoized_property
- def _type_affinity(self):
- return self.impl._type_affinity
-
- def type_engine(self, dialect):
- """Return a dialect-specific :class:`.TypeEngine` instance for this :class:`.TypeDecorator`.
-
- In most cases this returns a dialect-adapted form of
- the :class:`.TypeEngine` type represented by ``self.impl``.
- Makes usage of :meth:`dialect_impl` but also traverses
- into wrapped :class:`.TypeDecorator` instances.
- Behavior can be customized here by overriding :meth:`load_dialect_impl`.
-
- """
- adapted = dialect.type_descriptor(self)
- if type(adapted) is not type(self):
- return adapted
- elif isinstance(self.impl, TypeDecorator):
- return self.impl.type_engine(dialect)
- else:
- return self.load_dialect_impl(dialect)
-
- def load_dialect_impl(self, dialect):
- """Return a :class:`.TypeEngine` object corresponding to a dialect.
-
- This is an end-user override hook that can be used to provide
- differing types depending on the given dialect. It is used
- by the :class:`.TypeDecorator` implementation of :meth:`type_engine`
- to help determine what type should ultimately be returned
- for a given :class:`.TypeDecorator`.
-
- By default returns ``self.impl``.
-
- """
- return self.impl
-
- def __getattr__(self, key):
- """Proxy all other undefined accessors to the underlying
- implementation."""
-
- return getattr(self.impl, key)
-
- def process_bind_param(self, value, dialect):
- """Receive a bound parameter value to be converted.
-
- Subclasses override this method to return the
- value that should be passed along to the underlying
- :class:`.TypeEngine` object, and from there to the
- DBAPI ``execute()`` method.
-
- :param value: the value. Can be None.
- :param dialect: the :class:`.Dialect` in use.
-
- """
- raise NotImplementedError()
-
- def process_result_value(self, value, dialect):
- """Receive a result-row column value to be converted.
-
- Subclasses override this method to return the
- value that should be passed back to the application,
- given a value that is already processed by
- the underlying :class:`.TypeEngine` object, originally
- from the DBAPI cursor method ``fetchone()`` or similar.
-
- :param value: the value. Can be None.
- :param dialect: the :class:`.Dialect` in use.
-
- """
- raise NotImplementedError()
-
- def bind_processor(self, dialect):
- """Provide a bound value processing function for the given :class:`.Dialect`.
-
- This is the method that fulfills the :class:`.TypeEngine`
- contract for bound value conversion. :class:`.TypeDecorator`
- will wrap a user-defined implementation of
- :meth:`process_bind_param` here.
-
- User-defined code can override this method directly,
- though its likely best to use :meth:`process_bind_param` so that
- the processing provided by ``self.impl`` is maintained.
-
- """
- if self.__class__.process_bind_param.func_code \
- is not TypeDecorator.process_bind_param.func_code:
- process_param = self.process_bind_param
- impl_processor = self.impl.bind_processor(dialect)
- if impl_processor:
- def process(value):
- return impl_processor(process_param(value, dialect))
-
- else:
- def process(value):
- return process_param(value, dialect)
-
- return process
- else:
- return self.impl.bind_processor(dialect)
-
- def result_processor(self, dialect, coltype):
- """Provide a result value processing function for the given :class:`.Dialect`.
-
- This is the method that fulfills the :class:`.TypeEngine`
- contract for result value conversion. :class:`.TypeDecorator`
- will wrap a user-defined implementation of
- :meth:`process_result_value` here.
-
- User-defined code can override this method directly,
- though its likely best to use :meth:`process_result_value` so that
- the processing provided by ``self.impl`` is maintained.
-
- """
- if self.__class__.process_result_value.func_code \
- is not TypeDecorator.process_result_value.func_code:
- process_value = self.process_result_value
- impl_processor = self.impl.result_processor(dialect,
- coltype)
- if impl_processor:
- def process(value):
- return process_value(impl_processor(value), dialect)
-
- else:
- def process(value):
- return process_value(value, dialect)
-
- return process
- else:
- return self.impl.result_processor(dialect, coltype)
-
- def coerce_compared_value(self, op, value):
- """Suggest a type for a 'coerced' Python value in an expression.
-
- By default, returns self. This method is called by
- the expression system when an object using this type is
- on the left or right side of an expression against a plain Python
- object which does not yet have a SQLAlchemy type assigned::
-
- expr = table.c.somecolumn + 35
-
- Where above, if ``somecolumn`` uses this type, this method will
- be called with the value ``operator.add``
- and ``35``. The return value is whatever SQLAlchemy type should
- be used for ``35`` for this particular operation.
-
- """
- return self
-
- def _coerce_compared_value(self, op, value):
- """See :meth:`.TypeEngine._coerce_compared_value` for a description."""
-
- return self.coerce_compared_value(op, value)
-
- def copy(self):
- """Produce a copy of this :class:`.TypeDecorator` instance.
-
- This is a shallow copy and is provided to fulfill part of
- the :class:`.TypeEngine` contract. It usually does not
- need to be overridden unless the user-defined :class:`.TypeDecorator`
- has local state that should be deep-copied.
-
- """
- instance = self.__class__.__new__(self.__class__)
- instance.__dict__.update(self.__dict__)
- return instance
-
- def get_dbapi_type(self, dbapi):
- """Return the DBAPI type object represented by this :class:`.TypeDecorator`.
-
- By default this calls upon :meth:`.TypeEngine.get_dbapi_type` of the
- underlying "impl".
- """
- return self.impl.get_dbapi_type(dbapi)
-
- def copy_value(self, value):
- """Given a value, produce a copy of it.
-
- By default this calls upon :meth:`.TypeEngine.copy_value`
- of the underlying "impl".
-
- :meth:`.copy_value` will return the object
- itself, assuming "mutability" is not enabled.
- Only the :class:`.MutableType` mixin provides a copy
- function that actually produces a new object.
- The copying function is used by the ORM when
- "mutable" types are used, to memoize the original
- version of an object as loaded from the database,
- which is then compared to the possibly mutated
- version to check for changes.
-
- Modern implementations should use the
- ``sqlalchemy.ext.mutable`` extension described in
- :ref:`mutable_toplevel` for intercepting in-place
- changes to values.
-
- """
- return self.impl.copy_value(value)
-
- def compare_values(self, x, y):
- """Given two values, compare them for equality.
-
- By default this calls upon :meth:`.TypeEngine.compare_values`
- of the underlying "impl", which in turn usually
- uses the Python equals operator ``==``.
-
- This function is used by the ORM to compare
- an original-loaded value with an intercepted
- "changed" value, to determine if a net change
- has occurred.
-
- """
- return self.impl.compare_values(x, y)
-
- def is_mutable(self):
- """Return True if the target Python type is 'mutable'.
-
- This allows systems like the ORM to know if a column value can
- be considered 'not changed' by comparing the identity of
- objects alone. Values such as dicts, lists which
- are serialized into strings are examples of "mutable"
- column structures.
-
- .. note:: This functionality is now superseded by the
- ``sqlalchemy.ext.mutable`` extension described in
- :ref:`mutable_toplevel`.
-
- """
- return self.impl.is_mutable()
-
- def _adapt_expression(self, op, othertype):
- op, typ =self.impl._adapt_expression(op, othertype)
- if typ is self.impl:
- return op, self
- else:
- return op, typ
-
-class MutableType(object):
- """A mixin that marks a :class:`.TypeEngine` as representing
- a mutable Python object type. This functionality is used
- only by the ORM.
-
- .. note:: :class:`.MutableType` is superseded as of SQLAlchemy 0.7
- by the ``sqlalchemy.ext.mutable`` extension described in
- :ref:`mutable_toplevel`. This extension provides an event
- driven approach to in-place mutation detection that does not
- incur the severe performance penalty of the :class:`.MutableType`
- approach.
-
- "mutable" means that changes can occur in place to a value
- of this type. Examples includes Python lists, dictionaries,
- and sets, as well as user-defined objects. The primary
- need for identification of "mutable" types is by the ORM,
- which applies special rules to such values in order to guarantee
- that changes are detected. These rules may have a significant
- performance impact, described below.
-
- A :class:`.MutableType` usually allows a flag called
- ``mutable=False`` to enable/disable the "mutability" flag,
- represented on this class by :meth:`is_mutable`. Examples
- include :class:`.PickleType` and
- :class:`~sqlalchemy.dialects.postgresql.base.ARRAY`. Setting
- this flag to ``True`` enables mutability-specific behavior
- by the ORM.
-
- The :meth:`copy_value` and :meth:`compare_values` functions
- represent a copy and compare function for values of this
- type - implementing subclasses should override these
- appropriately.
-
- .. warning:: The usage of mutable types has significant performance
- implications when using the ORM. In order to detect changes, the
- ORM must create a copy of the value when it is first
- accessed, so that changes to the current value can be compared
- against the "clean" database-loaded value. Additionally, when the
- ORM checks to see if any data requires flushing, it must scan
- through all instances in the session which are known to have
- "mutable" attributes and compare the current value of each
- one to its "clean"
- value. So for example, if the Session contains 6000 objects (a
- fairly large amount) and autoflush is enabled, every individual
- execution of :class:`.Query` will require a full scan of that subset of
- the 6000 objects that have mutable attributes, possibly resulting
- in tens of thousands of additional method calls for every query.
-
- As of SQLAlchemy 0.7, the ``sqlalchemy.ext.mutable`` is provided which
- allows an event driven approach to in-place mutation detection. This
- approach should now be favored over the usage of :class:`.MutableType`
- with ``mutable=True``. ``sqlalchemy.ext.mutable`` is described in
- :ref:`mutable_toplevel`.
-
- """
-
- def is_mutable(self):
- """Return True if the target Python type is 'mutable'.
-
- For :class:`.MutableType`, this method is set to
- return ``True``.
-
- """
- return True
-
- def copy_value(self, value):
- """Unimplemented."""
- raise NotImplementedError()
-
- def compare_values(self, x, y):
- """Compare *x* == *y*."""
- return x == y
-
-def to_instance(typeobj, *arg, **kw):
- if typeobj is None:
- return NULLTYPE
-
- if util.callable(typeobj):
- return typeobj(*arg, **kw)
- else:
- return typeobj
-
-def adapt_type(typeobj, colspecs):
- if isinstance(typeobj, type):
- typeobj = typeobj()
- for t in typeobj.__class__.__mro__[0:-1]:
- try:
- impltype = colspecs[t]
- break
- except KeyError:
- pass
- else:
- # couldnt adapt - so just return the type itself
- # (it may be a user-defined type)
- return typeobj
- # if we adapted the given generic type to a database-specific type,
- # but it turns out the originally given "generic" type
- # is actually a subclass of our resulting type, then we were already
- # given a more specific type than that required; so use that.
- if (issubclass(typeobj.__class__, impltype)):
- return typeobj
- return typeobj.adapt(impltype)
-
-
-
-
-class NullType(TypeEngine):
- """An unknown type.
-
- NullTypes will stand in if :class:`~sqlalchemy.Table` reflection
- encounters a column data type unknown to SQLAlchemy. The
- resulting columns are nearly fully usable: the DB-API adapter will
- handle all translation to and from the database data type.
-
- NullType does not have sufficient information to particpate in a
- ``CREATE TABLE`` statement and will raise an exception if
- encountered during a :meth:`~sqlalchemy.Table.create` operation.
-
- """
- __visit_name__ = 'null'
-
- def _adapt_expression(self, op, othertype):
- if isinstance(othertype, NullType) or not operators.is_commutative(op):
- return op, self
- else:
- return othertype._adapt_expression(op, self)
-
-NullTypeEngine = NullType
-
-class Concatenable(object):
- """A mixin that marks a type as supporting 'concatenation',
- typically strings."""
-
- def _adapt_expression(self, op, othertype):
- if op is operators.add and issubclass(othertype._type_affinity,
- (Concatenable, NullType)):
- return operators.concat_op, self
- else:
- return op, self
-
-class _DateAffinity(object):
- """Mixin date/time specific expression adaptations.
-
- Rules are implemented within Date,Time,Interval,DateTime, Numeric,
- Integer. Based on http://www.postgresql.org/docs/current/static
- /functions-datetime.html.
-
- """
-
- @property
- def _expression_adaptations(self):
- raise NotImplementedError()
-
- _blank_dict = util.immutabledict()
- def _adapt_expression(self, op, othertype):
- othertype = othertype._type_affinity
- return op, \
- self._expression_adaptations.get(op, self._blank_dict).\
- get(othertype, NULLTYPE)
-
-class String(Concatenable, TypeEngine):
- """The base for all string and character types.
-
- In SQL, corresponds to VARCHAR. Can also take Python unicode objects
- and encode to the database's encoding in bind params (and the reverse for
- result sets.)
-
- The `length` field is usually required when the `String` type is
- used within a CREATE TABLE statement, as VARCHAR requires a length
- on most databases.
-
- """
-
- __visit_name__ = 'string'
-
- def __init__(self, length=None, convert_unicode=False,
- assert_unicode=None, unicode_error=None,
- _warn_on_bytestring=False
- ):
- """
- Create a string-holding type.
-
- :param length: optional, a length for the column for use in
- DDL statements. May be safely omitted if no ``CREATE
- TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued. Whether the value is
- interpreted as bytes or characters is database specific.
-
- :param convert_unicode: defaults to False. If True, the
- type will do what is necessary in order to accept
- Python Unicode objects as bind parameters, and to return
- Python Unicode objects in result rows. This may
- require SQLAlchemy to explicitly coerce incoming Python
- unicodes into an encoding, and from an encoding
- back to Unicode, or it may not require any interaction
- from SQLAlchemy at all, depending on the DBAPI in use.
-
- When SQLAlchemy performs the encoding/decoding,
- the encoding used is configured via
- :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which
- defaults to `utf-8`.
-
- The "convert_unicode" behavior can also be turned on
- for all String types by setting
- :attr:`sqlalchemy.engine.base.Dialect.convert_unicode`
- on create_engine().
-
- To instruct SQLAlchemy to perform Unicode encoding/decoding
- even on a platform that already handles Unicode natively,
- set convert_unicode='force'. This will incur significant
- performance overhead when fetching unicode result columns.
-
- :param assert_unicode: Deprecated. A warning is raised in all cases
- when a non-Unicode object is passed when SQLAlchemy would coerce
- into an encoding (note: but **not** when the DBAPI handles unicode
- objects natively). To suppress or raise this warning to an error,
- use the Python warnings filter documented at:
- http://docs.python.org/library/warnings.html
-
- :param unicode_error: Optional, a method to use to handle Unicode
- conversion errors. Behaves like the 'errors' keyword argument to
- the standard library's string.decode() functions. This flag
- requires that `convert_unicode` is set to `"force"` - otherwise,
- SQLAlchemy is not guaranteed to handle the task of unicode
- conversion. Note that this flag adds significant performance
- overhead to row-fetching operations for backends that already
- return unicode objects natively (which most DBAPIs do). This
- flag should only be used as an absolute last resort for reading
- strings from a column with varied or corrupted encodings,
- which only applies to databases that accept invalid encodings
- in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)
-
- """
- if unicode_error is not None and convert_unicode != 'force':
- raise exc.ArgumentError("convert_unicode must be 'force' "
- "when unicode_error is set.")
-
- if assert_unicode:
- util.warn_deprecated('assert_unicode is deprecated. '
- 'SQLAlchemy emits a warning in all '
- 'cases where it would otherwise like '
- 'to encode a Python unicode object '
- 'into a specific encoding but a plain '
- 'bytestring is received. This does '
- '*not* apply to DBAPIs that coerce '
- 'Unicode natively.')
- self.length = length
- self.convert_unicode = convert_unicode
- self.unicode_error = unicode_error
- self._warn_on_bytestring = _warn_on_bytestring
-
- def bind_processor(self, dialect):
- if self.convert_unicode or dialect.convert_unicode:
- if dialect.supports_unicode_binds and \
- self.convert_unicode != 'force':
- if self._warn_on_bytestring:
- def process(value):
- # Py3K
- #if isinstance(value, bytes):
- # Py2K
- if isinstance(value, str):
- # end Py2K
- util.warn("Unicode type received non-unicode bind "
- "param value.")
- return value
- return process
- else:
- return None
- else:
- encoder = codecs.getencoder(dialect.encoding)
- warn_on_bytestring = self._warn_on_bytestring
- def process(value):
- if isinstance(value, unicode):
- return encoder(value, self.unicode_error)[0]
- elif warn_on_bytestring and value is not None:
- util.warn("Unicode type received non-unicode bind "
- "param value")
- return value
- return process
- else:
- return None
-
- def result_processor(self, dialect, coltype):
- wants_unicode = self.convert_unicode or dialect.convert_unicode
- needs_convert = wants_unicode and \
- (dialect.returns_unicode_strings is not True or
- self.convert_unicode == 'force')
-
- if needs_convert:
- to_unicode = processors.to_unicode_processor_factory(
- dialect.encoding, self.unicode_error)
-
- if dialect.returns_unicode_strings:
- # we wouldn't be here unless convert_unicode='force'
- # was specified, or the driver has erratic unicode-returning
- # habits. since we will be getting back unicode
- # in most cases, we check for it (decode will fail).
- def process(value):
- if isinstance(value, unicode):
- return value
- else:
- return to_unicode(value)
- return process
- else:
- # here, we assume that the object is not unicode,
- # avoiding expensive isinstance() check.
- return to_unicode
- else:
- return None
-
- def get_dbapi_type(self, dbapi):
- return dbapi.STRING
-
-class Text(String):
- """A variably sized string type.
-
- In SQL, usually corresponds to CLOB or TEXT. Can also take Python
- unicode objects and encode to the database's encoding in bind
- params (and the reverse for result sets.)
-
- """
- __visit_name__ = 'text'
-
-class Unicode(String):
- """A variable length Unicode string.
-
- The ``Unicode`` type is a :class:`.String` which converts Python
- ``unicode`` objects (i.e., strings that are defined as
- ``u'somevalue'``) into encoded bytestrings when passing the value
- to the database driver, and similarly decodes values from the
- database back into Python ``unicode`` objects.
-
- It's roughly equivalent to using a ``String`` object with
- ``convert_unicode=True``, however
- the type has other significances in that it implies the usage
- of a unicode-capable type being used on the backend, such as NVARCHAR.
- This may affect what type is emitted when issuing CREATE TABLE
- and also may effect some DBAPI-specific details, such as type
- information passed along to ``setinputsizes()``.
-
- When using the ``Unicode`` type, it is only appropriate to pass
- Python ``unicode`` objects, and not plain ``str``. If a
- bytestring (``str``) is passed, a runtime warning is issued. If
- you notice your application raising these warnings but you're not
- sure where, the Python ``warnings`` filter can be used to turn
- these warnings into exceptions which will illustrate a stack
- trace::
-
- import warnings
- warnings.simplefilter('error')
-
- Bytestrings sent to and received from the database are encoded
- using the dialect's
- :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which defaults
- to `utf-8`.
-
- """
-
- __visit_name__ = 'unicode'
-
- def __init__(self, length=None, **kwargs):
- """
- Create a Unicode-converting String type.
-
- :param length: optional, a length for the column for use in
- DDL statements. May be safely omitted if no ``CREATE
- TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued. Whether the value is
- interpreted as bytes or characters is database specific.
-
- :param \**kwargs: passed through to the underlying ``String``
- type.
-
- """
- kwargs.setdefault('convert_unicode', True)
- kwargs.setdefault('_warn_on_bytestring', True)
- super(Unicode, self).__init__(length=length, **kwargs)
-
-class UnicodeText(Text):
- """An unbounded-length Unicode string.
-
- See :class:`.Unicode` for details on the unicode
- behavior of this object.
-
- Like ``Unicode``, usage the ``UnicodeText`` type implies a
- unicode-capable type being used on the backend, such as NCLOB.
-
- """
-
- __visit_name__ = 'unicode_text'
-
- def __init__(self, length=None, **kwargs):
- """
- Create a Unicode-converting Text type.
-
- :param length: optional, a length for the column for use in
- DDL statements. May be safely omitted if no ``CREATE
- TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued. Whether the value is
- interpreted as bytes or characters is database specific.
-
- """
- kwargs.setdefault('convert_unicode', True)
- kwargs.setdefault('_warn_on_bytestring', True)
- super(UnicodeText, self).__init__(length=length, **kwargs)
-
-
-class Integer(_DateAffinity, TypeEngine):
- """A type for ``int`` integers."""
-
- __visit_name__ = 'integer'
-
- def get_dbapi_type(self, dbapi):
- return dbapi.NUMBER
-
- @util.memoized_property
- def _expression_adaptations(self):
- # TODO: need a dictionary object that will
- # handle operators generically here, this is incomplete
- return {
- operators.add:{
- Date:Date,
- Integer:Integer,
- Numeric:Numeric,
- },
- operators.mul:{
- Interval:Interval,
- Integer:Integer,
- Numeric:Numeric,
- },
- # Py2K
- operators.div:{
- Integer:Integer,
- Numeric:Numeric,
- },
- # end Py2K
- operators.truediv:{
- Integer:Integer,
- Numeric:Numeric,
- },
- operators.sub:{
- Integer:Integer,
- Numeric:Numeric,
- },
- }
-
-class SmallInteger(Integer):
- """A type for smaller ``int`` integers.
-
- Typically generates a ``SMALLINT`` in DDL, and otherwise acts like
- a normal :class:`.Integer` on the Python side.
-
- """
-
- __visit_name__ = 'small_integer'
-
-
-class BigInteger(Integer):
- """A type for bigger ``int`` integers.
-
- Typically generates a ``BIGINT`` in DDL, and otherwise acts like
- a normal :class:`.Integer` on the Python side.
-
- """
-
- __visit_name__ = 'big_integer'
-
-
-class Numeric(_DateAffinity, TypeEngine):
- """A type for fixed precision numbers.
-
- Typically generates DECIMAL or NUMERIC. Returns
- ``decimal.Decimal`` objects by default, applying
- conversion as needed.
-
- .. note:: The `cdecimal <http://pypi.python.org/pypi/cdecimal/>`_ library
- is a high performing alternative to Python's built-in
- ``decimal.Decimal`` type, which performs very poorly in high volume
- situations. SQLAlchemy 0.7 is tested against ``cdecimal`` and supports
- it fully. The type is not necessarily supported by DBAPI
- implementations however, most of which contain an import for plain
- ``decimal`` in their source code, even though some such as psycopg2
- provide hooks for alternate adapters. SQLAlchemy imports ``decimal``
- globally as well. While the alternate ``Decimal`` class can be patched
- into SQLA's ``decimal`` module, overall the most straightforward and
- foolproof way to use "cdecimal" given current DBAPI and Python support
- is to patch it directly into sys.modules before anything else is
- imported::
-
- import sys
- import cdecimal
- sys.modules["decimal"] = cdecimal
-
- While the global patch is a little ugly, it's particularly
- important to use just one decimal library at a time since
- Python Decimal and cdecimal Decimal objects
- are not currently compatible *with each other*::
-
- >>> import cdecimal
- >>> import decimal
- >>> decimal.Decimal("10") == cdecimal.Decimal("10")
- False
-
- SQLAlchemy will provide more natural support of
- cdecimal if and when it becomes a standard part of Python
- installations and is supported by all DBAPIs.
-
- """
-
- __visit_name__ = 'numeric'
-
- def __init__(self, precision=None, scale=None, asdecimal=True):
- """
- Construct a Numeric.
-
- :param precision: the numeric precision for use in DDL ``CREATE
- TABLE``.
-
- :param scale: the numeric scale for use in DDL ``CREATE TABLE``.
-
- :param asdecimal: default True. Return whether or not
- values should be sent as Python Decimal objects, or
- as floats. Different DBAPIs send one or the other based on
- datatypes - the Numeric type will ensure that return values
- are one or the other across DBAPIs consistently.
-
- When using the ``Numeric`` type, care should be taken to ensure
- that the asdecimal setting is apppropriate for the DBAPI in use -
- when Numeric applies a conversion from Decimal->float or float->
- Decimal, this conversion incurs an additional performance overhead
- for all result columns received.
-
- DBAPIs that return Decimal natively (e.g. psycopg2) will have
- better accuracy and higher performance with a setting of ``True``,
- as the native translation to Decimal reduces the amount of floating-
- point issues at play, and the Numeric type itself doesn't need
- to apply any further conversions. However, another DBAPI which
- returns floats natively *will* incur an additional conversion
- overhead, and is still subject to floating point data loss - in
- which case ``asdecimal=False`` will at least remove the extra
- conversion overhead.
-
- """
- self.precision = precision
- self.scale = scale
- self.asdecimal = asdecimal
-
- def get_dbapi_type(self, dbapi):
- return dbapi.NUMBER
-
- def bind_processor(self, dialect):
- if dialect.supports_native_decimal:
- return None
- else:
- return processors.to_float
-
- def result_processor(self, dialect, coltype):
- if self.asdecimal:
- if dialect.supports_native_decimal:
- # we're a "numeric", DBAPI will give us Decimal directly
- return None
- else:
- util.warn('Dialect %s+%s does *not* support Decimal '
- 'objects natively, and SQLAlchemy must '
- 'convert from floating point - rounding '
- 'errors and other issues may occur. Please '
- 'consider storing Decimal numbers as strings '
- 'or integers on this platform for lossless '
- 'storage.' % (dialect.name, dialect.driver))
-
- # we're a "numeric", DBAPI returns floats, convert.
- if self.scale is not None:
- return processors.to_decimal_processor_factory(
- decimal.Decimal, self.scale)
- else:
- return processors.to_decimal_processor_factory(
- decimal.Decimal)
- else:
- if dialect.supports_native_decimal:
- return processors.to_float
- else:
- return None
-
- @util.memoized_property
- def _expression_adaptations(self):
- return {
- operators.mul:{
- Interval:Interval,
- Numeric:Numeric,
- Integer:Numeric,
- },
- # Py2K
- operators.div:{
- Numeric:Numeric,
- Integer:Numeric,
- },
- # end Py2K
- operators.truediv:{
- Numeric:Numeric,
- Integer:Numeric,
- },
- operators.add:{
- Numeric:Numeric,
- Integer:Numeric,
- },
- operators.sub:{
- Numeric:Numeric,
- Integer:Numeric,
- }
- }
-
-class Float(Numeric):
- """A type for ``float`` numbers.
-
- Returns Python ``float`` objects by default, applying
- conversion as needed.
-
- """
-
- __visit_name__ = 'float'
-
- scale = None
-
- def __init__(self, precision=None, asdecimal=False, **kwargs):
- """
- Construct a Float.
-
- :param precision: the numeric precision for use in DDL ``CREATE
- TABLE``.
-
- :param asdecimal: the same flag as that of :class:`.Numeric`, but
- defaults to ``False``. Note that setting this flag to ``True``
- results in floating point conversion.
-
- """
- self.precision = precision
- self.asdecimal = asdecimal
-
- def result_processor(self, dialect, coltype):
- if self.asdecimal:
- return processors.to_decimal_processor_factory(decimal.Decimal)
- else:
- return None
-
- @util.memoized_property
- def _expression_adaptations(self):
- return {
- operators.mul:{
- Interval:Interval,
- Numeric:Float,
- },
- # Py2K
- operators.div:{
- Numeric:Float,
- },
- # end Py2K
- operators.truediv:{
- Numeric:Float,
- },
- operators.add:{
- Numeric:Float,
- },
- operators.sub:{
- Numeric:Float,
- }
- }
-
-
-class DateTime(_DateAffinity, TypeEngine):
- """A type for ``datetime.datetime()`` objects.
-
- Date and time types return objects from the Python ``datetime``
- module. Most DBAPIs have built in support for the datetime
- module, with the noted exception of SQLite. In the case of
- SQLite, date and time types are stored as strings which are then
- converted back to datetime objects when rows are returned.
-
- """
-
- __visit_name__ = 'datetime'
-
- def __init__(self, timezone=False):
- self.timezone = timezone
-
- def get_dbapi_type(self, dbapi):
- return dbapi.DATETIME
-
- @util.memoized_property
- def _expression_adaptations(self):
- return {
- operators.add:{
- Interval:DateTime,
- },
- operators.sub:{
- Interval:DateTime,
- DateTime:Interval,
- },
- }
-
-
-class Date(_DateAffinity,TypeEngine):
- """A type for ``datetime.date()`` objects."""
-
- __visit_name__ = 'date'
-
- def get_dbapi_type(self, dbapi):
- return dbapi.DATETIME
-
- @util.memoized_property
- def _expression_adaptations(self):
- return {
- operators.add:{
- Integer:Date,
- Interval:DateTime,
- Time:DateTime,
- },
- operators.sub:{
- # date - integer = date
- Integer:Date,
-
- # date - date = integer.
- Date:Integer,
-
- Interval:DateTime,
-
- # date - datetime = interval,
- # this one is not in the PG docs
- # but works
- DateTime:Interval,
- },
- }
-
-
-class Time(_DateAffinity,TypeEngine):
- """A type for ``datetime.time()`` objects."""
-
- __visit_name__ = 'time'
-
- def __init__(self, timezone=False):
- self.timezone = timezone
-
- def get_dbapi_type(self, dbapi):
- return dbapi.DATETIME
-
- @util.memoized_property
- def _expression_adaptations(self):
- return {
- operators.add:{
- Date:DateTime,
- Interval:Time
- },
- operators.sub:{
- Time:Interval,
- Interval:Time,
- },
- }
-
-
-class _Binary(TypeEngine):
- """Define base behavior for binary types."""
-
- def __init__(self, length=None):
- self.length = length
-
- # Python 3 - sqlite3 doesn't need the `Binary` conversion
- # here, though pg8000 does to indicate "bytea"
- def bind_processor(self, dialect):
- DBAPIBinary = dialect.dbapi.Binary
- def process(value):
- x = self
- if value is not None:
- return DBAPIBinary(value)
- else:
- return None
- return process
-
- # Python 3 has native bytes() type
- # both sqlite3 and pg8000 seem to return it
- # (i.e. and not 'memoryview')
- # Py2K
- def result_processor(self, dialect, coltype):
- if util.jython:
- def process(value):
- if value is not None:
- if isinstance(value, array.array):
- return value.tostring()
- return str(value)
- else:
- return None
- else:
- process = processors.to_str
- return process
- # end Py2K
-
- def _coerce_compared_value(self, op, value):
- """See :meth:`.TypeEngine._coerce_compared_value` for a description."""
-
- if isinstance(value, basestring):
- return self
- else:
- return super(_Binary, self)._coerce_compared_value(op, value)
-
- def get_dbapi_type(self, dbapi):
- return dbapi.BINARY
-
-class LargeBinary(_Binary):
- """A type for large binary byte data.
-
- The Binary type generates BLOB or BYTEA when tables are created,
- and also converts incoming values using the ``Binary`` callable
- provided by each DB-API.
-
- """
-
- __visit_name__ = 'large_binary'
-
- def __init__(self, length=None):
- """
- Construct a LargeBinary type.
-
- :param length: optional, a length for the column for use in
- DDL statements, for those BLOB types that accept a length
- (i.e. MySQL). It does *not* produce a small BINARY/VARBINARY
- type - use the BINARY/VARBINARY types specifically for those.
- May be safely omitted if no ``CREATE
- TABLE`` will be issued. Certain databases may require a
- *length* for use in DDL, and will raise an exception when
- the ``CREATE TABLE`` DDL is issued.
-
- """
- _Binary.__init__(self, length=length)
-
-class Binary(LargeBinary):
- """Deprecated. Renamed to LargeBinary."""
-
- def __init__(self, *arg, **kw):
- util.warn_deprecated('The Binary type has been renamed to '
- 'LargeBinary.')
- LargeBinary.__init__(self, *arg, **kw)
-
-class SchemaType(events.SchemaEventTarget):
- """Mark a type as possibly requiring schema-level DDL for usage.
-
- Supports types that must be explicitly created/dropped (i.e. PG ENUM type)
- as well as types that are complimented by table or schema level
- constraints, triggers, and other rules.
-
- :class:`.SchemaType` classes can also be targets for the
- :meth:`.DDLEvents.before_parent_attach` and :meth:`.DDLEvents.after_parent_attach`
- events, where the events fire off surrounding the association of
- the type object with a parent :class:`.Column`.
-
- """
-
- def __init__(self, **kw):
- self.name = kw.pop('name', None)
- self.quote = kw.pop('quote', None)
- self.schema = kw.pop('schema', None)
- self.metadata = kw.pop('metadata', None)
- if self.metadata:
- self.metadata.append_ddl_listener('before-create',
- util.portable_instancemethod(self._on_metadata_create))
- self.metadata.append_ddl_listener('after-drop',
- util.portable_instancemethod(self._on_metadata_drop))
-
- def _set_parent(self, column):
- column._on_table_attach(util.portable_instancemethod(self._set_table))
-
- def _set_table(self, column, table):
- table.append_ddl_listener('before-create',
- util.portable_instancemethod(
- self._on_table_create))
- table.append_ddl_listener('after-drop',
- util.portable_instancemethod(
- self._on_table_drop))
- if self.metadata is None:
- table.metadata.append_ddl_listener('before-create',
- util.portable_instancemethod(self._on_metadata_create))
- table.metadata.append_ddl_listener('after-drop',
- util.portable_instancemethod(self._on_metadata_drop))
-
- @property
- def bind(self):
- return self.metadata and self.metadata.bind or None
-
- def create(self, bind=None, checkfirst=False):
- """Issue CREATE ddl for this type, if applicable."""
-
- if bind is None:
- bind = schema._bind_or_error(self)
- t = self.dialect_impl(bind.dialect)
- if t.__class__ is not self.__class__ and isinstance(t, SchemaType):
- t.create(bind=bind, checkfirst=checkfirst)
-
- def drop(self, bind=None, checkfirst=False):
- """Issue DROP ddl for this type, if applicable."""
-
- if bind is None:
- bind = schema._bind_or_error(self)
- t = self.dialect_impl(bind.dialect)
- if t.__class__ is not self.__class__ and isinstance(t, SchemaType):
- t.drop(bind=bind, checkfirst=checkfirst)
-
- def _on_table_create(self, event, target, bind, **kw):
- t = self.dialect_impl(bind.dialect)
- if t.__class__ is not self.__class__ and isinstance(t, SchemaType):
- t._on_table_create(event, target, bind, **kw)
-
- def _on_table_drop(self, event, target, bind, **kw):
- t = self.dialect_impl(bind.dialect)
- if t.__class__ is not self.__class__ and isinstance(t, SchemaType):
- t._on_table_drop(event, target, bind, **kw)
-
- def _on_metadata_create(self, event, target, bind, **kw):
- t = self.dialect_impl(bind.dialect)
- if t.__class__ is not self.__class__ and isinstance(t, SchemaType):
- t._on_metadata_create(event, target, bind, **kw)
-
- def _on_metadata_drop(self, event, target, bind, **kw):
- t = self.dialect_impl(bind.dialect)
- if t.__class__ is not self.__class__ and isinstance(t, SchemaType):
- t._on_metadata_drop(event, target, bind, **kw)
-
-class Enum(String, SchemaType):
- """Generic Enum Type.
-
- The Enum type provides a set of possible string values which the
- column is constrained towards.
-
- By default, uses the backend's native ENUM type if available,
- else uses VARCHAR + a CHECK constraint.
- """
-
- __visit_name__ = 'enum'
-
- def __init__(self, *enums, **kw):
- """Construct an enum.
-
- Keyword arguments which don't apply to a specific backend are ignored
- by that backend.
-
- :param \*enums: string or unicode enumeration labels. If unicode
- labels are present, the `convert_unicode` flag is auto-enabled.
-
- :param convert_unicode: Enable unicode-aware bind parameter and
- result-set processing for this Enum's data. This is set
- automatically based on the presence of unicode label strings.
-
- :param metadata: Associate this type directly with a ``MetaData``
- object. For types that exist on the target database as an
- independent schema construct (Postgresql), this type will be
- created and dropped within ``create_all()`` and ``drop_all()``
- operations. If the type is not associated with any ``MetaData``
- object, it will associate itself with each ``Table`` in which it is
- used, and will be created when any of those individual tables are
- created, after a check is performed for it's existence. The type is
- only dropped when ``drop_all()`` is called for that ``Table``
- object's metadata, however.
-
- :param name: The name of this type. This is required for Postgresql
- and any future supported database which requires an explicitly
- named type, or an explicitly named constraint in order to generate
- the type and/or a table that uses it.
-
- :param native_enum: Use the database's native ENUM type when
- available. Defaults to True. When False, uses VARCHAR + check
- constraint for all backends.
-
- :param schema: Schemaname of this type. For types that exist on the
- target database as an independent schema construct (Postgresql),
- this parameter specifies the named schema in which the type is
- present.
-
- :param quote: Force quoting to be on or off on the type's name. If
- left as the default of `None`, the usual schema-level "case
- sensitive"/"reserved name" rules are used to determine if this
- type's name should be quoted.
-
- """
- self.enums = enums
- self.native_enum = kw.pop('native_enum', True)
- convert_unicode= kw.pop('convert_unicode', None)
- if convert_unicode is None:
- for e in enums:
- if isinstance(e, unicode):
- convert_unicode = True
- break
- else:
- convert_unicode = False
-
- if self.enums:
- length =max(len(x) for x in self.enums)
- else:
- length = 0
- String.__init__(self,
- length =length,
- convert_unicode=convert_unicode,
- )
- SchemaType.__init__(self, **kw)
-
- def _should_create_constraint(self, compiler):
- return not self.native_enum or \
- not compiler.dialect.supports_native_enum
-
- def _set_table(self, column, table):
- if self.native_enum:
- SchemaType._set_table(self, column, table)
-
-
- e = schema.CheckConstraint(
- column.in_(self.enums),
- name=self.name,
- _create_rule=util.portable_instancemethod(
- self._should_create_constraint)
- )
- table.append_constraint(e)
-
- def adapt(self, impltype, **kw):
- if issubclass(impltype, Enum):
- return impltype(name=self.name,
- quote=self.quote,
- schema=self.schema,
- metadata=self.metadata,
- convert_unicode=self.convert_unicode,
- native_enum=self.native_enum,
- *self.enums,
- **kw
- )
- else:
- return super(Enum, self).adapt(impltype, **kw)
-
-class PickleType(MutableType, TypeDecorator):
- """Holds Python objects, which are serialized using pickle.
-
- PickleType builds upon the Binary type to apply Python's
- ``pickle.dumps()`` to incoming objects, and ``pickle.loads()`` on
- the way out, allowing any pickleable Python object to be stored as
- a serialized binary field.
-
- """
-
- impl = LargeBinary
-
- def __init__(self, protocol=pickle.HIGHEST_PROTOCOL,
- pickler=None, mutable=False, comparator=None):
- """
- Construct a PickleType.
-
- :param protocol: defaults to ``pickle.HIGHEST_PROTOCOL``.
-
- :param pickler: defaults to cPickle.pickle or pickle.pickle if
- cPickle is not available. May be any object with
- pickle-compatible ``dumps` and ``loads`` methods.
-
- :param mutable: defaults to False; implements
- :meth:`AbstractType.is_mutable`. When ``True``, incoming
- objects will be compared against copies of themselves
- using the Python "equals" operator, unless the
- ``comparator`` argument is present. See
- :class:`.MutableType` for details on "mutable" type
- behavior. (default changed from ``True`` in
- 0.7.0).
-
- .. note:: This functionality is now superseded by the
- ``sqlalchemy.ext.mutable`` extension described in
- :ref:`mutable_toplevel`.
-
- :param comparator: a 2-arg callable predicate used
- to compare values of this type. If left as ``None``,
- the Python "equals" operator is used to compare values.
-
- """
- self.protocol = protocol
- self.pickler = pickler or pickle
- self.mutable = mutable
- self.comparator = comparator
- super(PickleType, self).__init__()
-
- def __reduce__(self):
- return PickleType, (self.protocol,
- None,
- self.mutable,
- self.comparator)
-
- def bind_processor(self, dialect):
- impl_processor = self.impl.bind_processor(dialect)
- dumps = self.pickler.dumps
- protocol = self.protocol
- if impl_processor:
- def process(value):
- if value is not None:
- value = dumps(value, protocol)
- return impl_processor(value)
- else:
- def process(value):
- if value is not None:
- value = dumps(value, protocol)
- return value
- return process
-
- def result_processor(self, dialect, coltype):
- impl_processor = self.impl.result_processor(dialect, coltype)
- loads = self.pickler.loads
- if impl_processor:
- def process(value):
- value = impl_processor(value)
- if value is None:
- return None
- return loads(value)
- else:
- def process(value):
- if value is None:
- return None
- return loads(value)
- return process
-
- def copy_value(self, value):
- if self.mutable:
- return self.pickler.loads(
- self.pickler.dumps(value, self.protocol))
- else:
- return value
-
- def compare_values(self, x, y):
- if self.comparator:
- return self.comparator(x, y)
- else:
- return x == y
-
- def is_mutable(self):
- """Return True if the target Python type is 'mutable'.
-
- When this method is overridden, :meth:`copy_value` should
- also be supplied. The :class:`.MutableType` mixin
- is recommended as a helper.
-
- """
- return self.mutable
-
-
-class Boolean(TypeEngine, SchemaType):
- """A bool datatype.
-
- Boolean typically uses BOOLEAN or SMALLINT on the DDL side, and on
- the Python side deals in ``True`` or ``False``.
-
- """
-
- __visit_name__ = 'boolean'
-
- def __init__(self, create_constraint=True, name=None):
- """Construct a Boolean.
-
- :param create_constraint: defaults to True. If the boolean
- is generated as an int/smallint, also create a CHECK constraint
- on the table that ensures 1 or 0 as a value.
-
- :param name: if a CHECK constraint is generated, specify
- the name of the constraint.
-
- """
- self.create_constraint = create_constraint
- self.name = name
-
- def _should_create_constraint(self, compiler):
- return not compiler.dialect.supports_native_boolean
-
- def _set_table(self, column, table):
- if not self.create_constraint:
- return
-
- e = schema.CheckConstraint(
- column.in_([0, 1]),
- name=self.name,
- _create_rule=util.portable_instancemethod(
- self._should_create_constraint)
- )
- table.append_constraint(e)
-
- def bind_processor(self, dialect):
- if dialect.supports_native_boolean:
- return None
- else:
- return processors.boolean_to_int
-
- def result_processor(self, dialect, coltype):
- if dialect.supports_native_boolean:
- return None
- else:
- return processors.int_to_boolean
-
-class Interval(_DateAffinity, TypeDecorator):
- """A type for ``datetime.timedelta()`` objects.
-
- The Interval type deals with ``datetime.timedelta`` objects. In
- PostgreSQL, the native ``INTERVAL`` type is used; for others, the
- value is stored as a date which is relative to the "epoch"
- (Jan. 1, 1970).
-
- Note that the ``Interval`` type does not currently provide date arithmetic
- operations on platforms which do not support interval types natively. Such
- operations usually require transformation of both sides of the expression
- (such as, conversion of both sides into integer epoch values first) which
- currently is a manual procedure (such as via
- :attr:`~sqlalchemy.sql.expression.func`).
-
- """
-
- impl = DateTime
- epoch = dt.datetime.utcfromtimestamp(0)
-
- def __init__(self, native=True,
- second_precision=None,
- day_precision=None):
- """Construct an Interval object.
-
- :param native: when True, use the actual
- INTERVAL type provided by the database, if
- supported (currently Postgresql, Oracle).
- Otherwise, represent the interval data as
- an epoch value regardless.
-
- :param second_precision: For native interval types
- which support a "fractional seconds precision" parameter,
- i.e. Oracle and Postgresql
-
- :param day_precision: for native interval types which
- support a "day precision" parameter, i.e. Oracle.
-
- """
- super(Interval, self).__init__()
- self.native = native
- self.second_precision = second_precision
- self.day_precision = day_precision
-
- def adapt(self, cls, **kw):
- if self.native and hasattr(cls, '_adapt_from_generic_interval'):
- return cls._adapt_from_generic_interval(self, **kw)
- else:
- return self.__class__(
- native=self.native,
- second_precision=self.second_precision,
- day_precision=self.day_precision,
- **kw)
-
- def bind_processor(self, dialect):
- impl_processor = self.impl.bind_processor(dialect)
- epoch = self.epoch
- if impl_processor:
- def process(value):
- if value is not None:
- value = epoch + value
- return impl_processor(value)
- else:
- def process(value):
- if value is not None:
- value = epoch + value
- return value
- return process
-
- def result_processor(self, dialect, coltype):
- impl_processor = self.impl.result_processor(dialect, coltype)
- epoch = self.epoch
- if impl_processor:
- def process(value):
- value = impl_processor(value)
- if value is None:
- return None
- return value - epoch
- else:
- def process(value):
- if value is None:
- return None
- return value - epoch
- return process
-
- @util.memoized_property
- def _expression_adaptations(self):
- return {
- operators.add:{
- Date:DateTime,
- Interval:Interval,
- DateTime:DateTime,
- Time:Time,
- },
- operators.sub:{
- Interval:Interval
- },
- operators.mul:{
- Numeric:Interval
- },
- operators.truediv: {
- Numeric:Interval
- },
- # Py2K
- operators.div: {
- Numeric:Interval
- }
- # end Py2K
- }
-
- @property
- def _type_affinity(self):
- return Interval
-
- def _coerce_compared_value(self, op, value):
- """See :meth:`.TypeEngine._coerce_compared_value` for a description."""
-
- return self.impl._coerce_compared_value(op, value)
-
-
-class REAL(Float):
- """The SQL REAL type."""
-
- __visit_name__ = 'REAL'
-
-class FLOAT(Float):
- """The SQL FLOAT type."""
-
- __visit_name__ = 'FLOAT'
-
-class NUMERIC(Numeric):
- """The SQL NUMERIC type."""
-
- __visit_name__ = 'NUMERIC'
-
-
-class DECIMAL(Numeric):
- """The SQL DECIMAL type."""
-
- __visit_name__ = 'DECIMAL'
-
-
-class INTEGER(Integer):
- """The SQL INT or INTEGER type."""
-
- __visit_name__ = 'INTEGER'
-INT = INTEGER
-
-
-class SMALLINT(SmallInteger):
- """The SQL SMALLINT type."""
-
- __visit_name__ = 'SMALLINT'
-
-
-class BIGINT(BigInteger):
- """The SQL BIGINT type."""
-
- __visit_name__ = 'BIGINT'
-
-class TIMESTAMP(DateTime):
- """The SQL TIMESTAMP type."""
-
- __visit_name__ = 'TIMESTAMP'
-
- def get_dbapi_type(self, dbapi):
- return dbapi.TIMESTAMP
-
-class DATETIME(DateTime):
- """The SQL DATETIME type."""
-
- __visit_name__ = 'DATETIME'
-
-
-class DATE(Date):
- """The SQL DATE type."""
-
- __visit_name__ = 'DATE'
-
-
-class TIME(Time):
- """The SQL TIME type."""
-
- __visit_name__ = 'TIME'
-
-class TEXT(Text):
- """The SQL TEXT type."""
-
- __visit_name__ = 'TEXT'
-
-class CLOB(Text):
- """The CLOB type.
-
- This type is found in Oracle and Informix.
- """
-
- __visit_name__ = 'CLOB'
-
-class VARCHAR(String):
- """The SQL VARCHAR type."""
-
- __visit_name__ = 'VARCHAR'
-
-class NVARCHAR(Unicode):
- """The SQL NVARCHAR type."""
-
- __visit_name__ = 'NVARCHAR'
-
-class CHAR(String):
- """The SQL CHAR type."""
-
- __visit_name__ = 'CHAR'
-
-
-class NCHAR(Unicode):
- """The SQL NCHAR type."""
-
- __visit_name__ = 'NCHAR'
-
-
-class BLOB(LargeBinary):
- """The SQL BLOB type."""
-
- __visit_name__ = 'BLOB'
-
-class BINARY(_Binary):
- """The SQL BINARY type."""
-
- __visit_name__ = 'BINARY'
-
-class VARBINARY(_Binary):
- """The SQL VARBINARY type."""
-
- __visit_name__ = 'VARBINARY'
-
-
-class BOOLEAN(Boolean):
- """The SQL BOOLEAN type."""
-
- __visit_name__ = 'BOOLEAN'
-
-NULLTYPE = NullType()
-BOOLEANTYPE = Boolean()
-STRINGTYPE = String()
-
-_type_map = {
- str: String(),
- # Py3K
- #bytes : LargeBinary(),
- # Py2K
- unicode : Unicode(),
- # end Py2K
- int : Integer(),
- float : Numeric(),
- bool: BOOLEANTYPE,
- decimal.Decimal : Numeric(),
- dt.date : Date(),
- dt.datetime : DateTime(),
- dt.time : Time(),
- dt.timedelta : Interval(),
- NoneType: NULLTYPE
-}
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/__init__.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/__init__.py
deleted file mode 100755
index 93c418ed..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/__init__.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# util/__init__.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from compat import callable, cmp, reduce, defaultdict, py25_dict, \
- threading, py3k, jython, pypy, win32, set_types, buffer, pickle, \
- update_wrapper, partial, md5_hex, decode_slice, dottedgetter
-
-from _collections import NamedTuple, ImmutableContainer, immutabledict, \
- Properties, OrderedProperties, ImmutableProperties, OrderedDict, \
- OrderedSet, IdentitySet, OrderedIdentitySet, column_set, \
- column_dict, ordered_column_set, populate_column_dict, unique_list, \
- UniqueAppender, PopulateDict, EMPTY_SET, to_list, to_set, \
- to_column_set, update_copy, flatten_iterator, WeakIdentityMapping, \
- LRUCache, ScopedRegistry, ThreadLocalRegistry
-
-from langhelpers import iterate_attributes, class_hierarchy, \
- portable_instancemethod, unbound_method_to_callable, \
- getargspec_init, format_argspec_init, format_argspec_plus, \
- get_func_kwargs, get_cls_kwargs, decorator, as_interface, \
- memoized_property, memoized_instancemethod, \
- reset_memoized, group_expirable_memoized_property, importlater, \
- monkeypatch_proxied_specials, asbool, bool_or_str, coerce_kw_type,\
- duck_type_collection, assert_arg_type, symbol, dictlike_iteritems,\
- classproperty, set_creation_order, warn_exception, warn, NoneType,\
- constructor_copy, methods_equivalent, chop_traceback, asint
-
-from deprecations import warn_deprecated, warn_pending_deprecation, \
- deprecated, pending_deprecation
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/_collections.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/_collections.py
deleted file mode 100755
index 3adbf991..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/_collections.py
+++ /dev/null
@@ -1,897 +0,0 @@
-# util/_collections.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Collection classes and helpers."""
-
-import sys
-import itertools
-import weakref
-import operator
-from langhelpers import symbol
-from compat import time_func, threading
-
-EMPTY_SET = frozenset()
-
-
-class NamedTuple(tuple):
- """tuple() subclass that adds labeled names.
-
- Is also pickleable.
-
- """
-
- def __new__(cls, vals, labels=None):
- t = tuple.__new__(cls, vals)
- if labels:
- t.__dict__.update(zip(labels, vals))
- t._labels = labels
- return t
-
- def keys(self):
- return [l for l in self._labels if l is not None]
-
-class ImmutableContainer(object):
- def _immutable(self, *arg, **kw):
- raise TypeError("%s object is immutable" % self.__class__.__name__)
-
- __delitem__ = __setitem__ = __setattr__ = _immutable
-
-class immutabledict(ImmutableContainer, dict):
-
- clear = pop = popitem = setdefault = \
- update = ImmutableContainer._immutable
-
- def __new__(cls, *args):
- new = dict.__new__(cls)
- dict.__init__(new, *args)
- return new
-
- def __init__(self, *args):
- pass
-
- def __reduce__(self):
- return immutabledict, (dict(self), )
-
- def union(self, d):
- if not self:
- return immutabledict(d)
- else:
- d2 = immutabledict(self)
- dict.update(d2, d)
- return d2
-
- def __repr__(self):
- return "immutabledict(%s)" % dict.__repr__(self)
-
-class Properties(object):
- """Provide a __getattr__/__setattr__ interface over a dict."""
-
- def __init__(self, data):
- self.__dict__['_data'] = data
-
- def __len__(self):
- return len(self._data)
-
- def __iter__(self):
- return self._data.itervalues()
-
- def __add__(self, other):
- return list(self) + list(other)
-
- def __setitem__(self, key, object):
- self._data[key] = object
-
- def __getitem__(self, key):
- return self._data[key]
-
- def __delitem__(self, key):
- del self._data[key]
-
- def __setattr__(self, key, object):
- self._data[key] = object
-
- def __getstate__(self):
- return {'_data': self.__dict__['_data']}
-
- def __setstate__(self, state):
- self.__dict__['_data'] = state['_data']
-
- def __getattr__(self, key):
- try:
- return self._data[key]
- except KeyError:
- raise AttributeError(key)
-
- def __contains__(self, key):
- return key in self._data
-
- def as_immutable(self):
- """Return an immutable proxy for this :class:`.Properties`."""
-
- return ImmutableProperties(self._data)
-
- def update(self, value):
- self._data.update(value)
-
- def get(self, key, default=None):
- if key in self:
- return self[key]
- else:
- return default
-
- def keys(self):
- return self._data.keys()
-
- def has_key(self, key):
- return key in self._data
-
- def clear(self):
- self._data.clear()
-
-class OrderedProperties(Properties):
- """Provide a __getattr__/__setattr__ interface with an OrderedDict
- as backing store."""
- def __init__(self):
- Properties.__init__(self, OrderedDict())
-
-
-class ImmutableProperties(ImmutableContainer, Properties):
- """Provide immutable dict/object attribute to an underlying dictionary."""
-
-
-class OrderedDict(dict):
- """A dict that returns keys/values/items in the order they were added."""
-
- def __init__(self, ____sequence=None, **kwargs):
- self._list = []
- if ____sequence is None:
- if kwargs:
- self.update(**kwargs)
- else:
- self.update(____sequence, **kwargs)
-
- def clear(self):
- self._list = []
- dict.clear(self)
-
- def copy(self):
- return self.__copy__()
-
- def __copy__(self):
- return OrderedDict(self)
-
- def sort(self, *arg, **kw):
- self._list.sort(*arg, **kw)
-
- def update(self, ____sequence=None, **kwargs):
- if ____sequence is not None:
- if hasattr(____sequence, 'keys'):
- for key in ____sequence.keys():
- self.__setitem__(key, ____sequence[key])
- else:
- for key, value in ____sequence:
- self[key] = value
- if kwargs:
- self.update(kwargs)
-
- def setdefault(self, key, value):
- if key not in self:
- self.__setitem__(key, value)
- return value
- else:
- return self.__getitem__(key)
-
- def __iter__(self):
- return iter(self._list)
-
- def values(self):
- return [self[key] for key in self._list]
-
- def itervalues(self):
- return iter([self[key] for key in self._list])
-
- def keys(self):
- return list(self._list)
-
- def iterkeys(self):
- return iter(self.keys())
-
- def items(self):
- return [(key, self[key]) for key in self.keys()]
-
- def iteritems(self):
- return iter(self.items())
-
- def __setitem__(self, key, object):
- if key not in self:
- try:
- self._list.append(key)
- except AttributeError:
- # work around Python pickle loads() with
- # dict subclass (seems to ignore __setstate__?)
- self._list = [key]
- dict.__setitem__(self, key, object)
-
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- self._list.remove(key)
-
- def pop(self, key, *default):
- present = key in self
- value = dict.pop(self, key, *default)
- if present:
- self._list.remove(key)
- return value
-
- def popitem(self):
- item = dict.popitem(self)
- self._list.remove(item[0])
- return item
-
-class OrderedSet(set):
- def __init__(self, d=None):
- set.__init__(self)
- self._list = []
- if d is not None:
- self.update(d)
-
- def add(self, element):
- if element not in self:
- self._list.append(element)
- set.add(self, element)
-
- def remove(self, element):
- set.remove(self, element)
- self._list.remove(element)
-
- def insert(self, pos, element):
- if element not in self:
- self._list.insert(pos, element)
- set.add(self, element)
-
- def discard(self, element):
- if element in self:
- self._list.remove(element)
- set.remove(self, element)
-
- def clear(self):
- set.clear(self)
- self._list = []
-
- def __getitem__(self, key):
- return self._list[key]
-
- def __iter__(self):
- return iter(self._list)
-
- def __add__(self, other):
- return self.union(other)
-
- def __repr__(self):
- return '%s(%r)' % (self.__class__.__name__, self._list)
-
- __str__ = __repr__
-
- def update(self, iterable):
- for e in iterable:
- if e not in self:
- self._list.append(e)
- set.add(self, e)
- return self
-
- __ior__ = update
-
- def union(self, other):
- result = self.__class__(self)
- result.update(other)
- return result
-
- __or__ = union
-
- def intersection(self, other):
- other = set(other)
- return self.__class__(a for a in self if a in other)
-
- __and__ = intersection
-
- def symmetric_difference(self, other):
- other = set(other)
- result = self.__class__(a for a in self if a not in other)
- result.update(a for a in other if a not in self)
- return result
-
- __xor__ = symmetric_difference
-
- def difference(self, other):
- other = set(other)
- return self.__class__(a for a in self if a not in other)
-
- __sub__ = difference
-
- def intersection_update(self, other):
- other = set(other)
- set.intersection_update(self, other)
- self._list = [ a for a in self._list if a in other]
- return self
-
- __iand__ = intersection_update
-
- def symmetric_difference_update(self, other):
- set.symmetric_difference_update(self, other)
- self._list = [ a for a in self._list if a in self]
- self._list += [ a for a in other._list if a in self]
- return self
-
- __ixor__ = symmetric_difference_update
-
- def difference_update(self, other):
- set.difference_update(self, other)
- self._list = [ a for a in self._list if a in self]
- return self
-
- __isub__ = difference_update
-
-
-class IdentitySet(object):
- """A set that considers only object id() for uniqueness.
-
- This strategy has edge cases for builtin types- it's possible to have
- two 'foo' strings in one of these sets, for example. Use sparingly.
-
- """
-
- _working_set = set
-
- def __init__(self, iterable=None):
- self._members = dict()
- if iterable:
- for o in iterable:
- self.add(o)
-
- def add(self, value):
- self._members[id(value)] = value
-
- def __contains__(self, value):
- return id(value) in self._members
-
- def remove(self, value):
- del self._members[id(value)]
-
- def discard(self, value):
- try:
- self.remove(value)
- except KeyError:
- pass
-
- def pop(self):
- try:
- pair = self._members.popitem()
- return pair[1]
- except KeyError:
- raise KeyError('pop from an empty set')
-
- def clear(self):
- self._members.clear()
-
- def __cmp__(self, other):
- raise TypeError('cannot compare sets using cmp()')
-
- def __eq__(self, other):
- if isinstance(other, IdentitySet):
- return self._members == other._members
- else:
- return False
-
- def __ne__(self, other):
- if isinstance(other, IdentitySet):
- return self._members != other._members
- else:
- return True
-
- def issubset(self, iterable):
- other = type(self)(iterable)
-
- if len(self) > len(other):
- return False
- for m in itertools.ifilterfalse(other._members.__contains__,
- self._members.iterkeys()):
- return False
- return True
-
- def __le__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return self.issubset(other)
-
- def __lt__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return len(self) < len(other) and self.issubset(other)
-
- def issuperset(self, iterable):
- other = type(self)(iterable)
-
- if len(self) < len(other):
- return False
-
- for m in itertools.ifilterfalse(self._members.__contains__,
- other._members.iterkeys()):
- return False
- return True
-
- def __ge__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return self.issuperset(other)
-
- def __gt__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return len(self) > len(other) and self.issuperset(other)
-
- def union(self, iterable):
- result = type(self)()
- # testlib.pragma exempt:__hash__
- result._members.update(
- self._working_set(self._member_id_tuples()).union(_iter_id(iterable)))
- return result
-
- def __or__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return self.union(other)
-
- def update(self, iterable):
- self._members = self.union(iterable)._members
-
- def __ior__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- self.update(other)
- return self
-
- def difference(self, iterable):
- result = type(self)()
- # testlib.pragma exempt:__hash__
- result._members.update(
- self._working_set(self._member_id_tuples()).difference(_iter_id(iterable)))
- return result
-
- def __sub__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return self.difference(other)
-
- def difference_update(self, iterable):
- self._members = self.difference(iterable)._members
-
- def __isub__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- self.difference_update(other)
- return self
-
- def intersection(self, iterable):
- result = type(self)()
- # testlib.pragma exempt:__hash__
- result._members.update(
- self._working_set(self._member_id_tuples()).intersection(_iter_id(iterable)))
- return result
-
- def __and__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return self.intersection(other)
-
- def intersection_update(self, iterable):
- self._members = self.intersection(iterable)._members
-
- def __iand__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- self.intersection_update(other)
- return self
-
- def symmetric_difference(self, iterable):
- result = type(self)()
- # testlib.pragma exempt:__hash__
- result._members.update(
- self._working_set(self._member_id_tuples()).symmetric_difference(_iter_id(iterable)))
- return result
-
- def _member_id_tuples(self):
- return ((id(v), v) for v in self._members.itervalues())
-
- def __xor__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- return self.symmetric_difference(other)
-
- def symmetric_difference_update(self, iterable):
- self._members = self.symmetric_difference(iterable)._members
-
- def __ixor__(self, other):
- if not isinstance(other, IdentitySet):
- return NotImplemented
- self.symmetric_difference(other)
- return self
-
- def copy(self):
- return type(self)(self._members.itervalues())
-
- __copy__ = copy
-
- def __len__(self):
- return len(self._members)
-
- def __iter__(self):
- return self._members.itervalues()
-
- def __hash__(self):
- raise TypeError('set objects are unhashable')
-
- def __repr__(self):
- return '%s(%r)' % (type(self).__name__, self._members.values())
-
-
-class OrderedIdentitySet(IdentitySet):
- class _working_set(OrderedSet):
- # a testing pragma: exempt the OIDS working set from the test suite's
- # "never call the user's __hash__" assertions. this is a big hammer,
- # but it's safe here: IDS operates on (id, instance) tuples in the
- # working set.
- __sa_hash_exempt__ = True
-
- def __init__(self, iterable=None):
- IdentitySet.__init__(self)
- self._members = OrderedDict()
- if iterable:
- for o in iterable:
- self.add(o)
-
-
-if sys.version_info >= (2, 5):
- class PopulateDict(dict):
- """A dict which populates missing values via a creation function.
-
- Note the creation function takes a key, unlike
- collections.defaultdict.
-
- """
-
- def __init__(self, creator):
- self.creator = creator
-
- def __missing__(self, key):
- self[key] = val = self.creator(key)
- return val
-else:
- class PopulateDict(dict):
- """A dict which populates missing values via a creation function."""
-
- def __init__(self, creator):
- self.creator = creator
-
- def __getitem__(self, key):
- try:
- return dict.__getitem__(self, key)
- except KeyError:
- self[key] = value = self.creator(key)
- return value
-
-# define collections that are capable of storing
-# ColumnElement objects as hashable keys/elements.
-column_set = set
-column_dict = dict
-ordered_column_set = OrderedSet
-populate_column_dict = PopulateDict
-
-def unique_list(seq, hashfunc=None):
- seen = {}
- if not hashfunc:
- return [x for x in seq
- if x not in seen
- and not seen.__setitem__(x, True)]
- else:
- return [x for x in seq
- if hashfunc(x) not in seen
- and not seen.__setitem__(hashfunc(x), True)]
-
-class UniqueAppender(object):
- """Appends items to a collection ensuring uniqueness.
-
- Additional appends() of the same object are ignored. Membership is
- determined by identity (``is a``) not equality (``==``).
- """
-
- def __init__(self, data, via=None):
- self.data = data
- self._unique = {}
- if via:
- self._data_appender = getattr(data, via)
- elif hasattr(data, 'append'):
- self._data_appender = data.append
- elif hasattr(data, 'add'):
- self._data_appender = data.add
-
- def append(self, item):
- id_ = id(item)
- if id_ not in self._unique:
- self._data_appender(item)
- self._unique[id_] = True
-
- def __iter__(self):
- return iter(self.data)
-
-def to_list(x, default=None):
- if x is None:
- return default
- if not isinstance(x, (list, tuple)):
- return [x]
- else:
- return x
-
-def to_set(x):
- if x is None:
- return set()
- if not isinstance(x, set):
- return set(to_list(x))
- else:
- return x
-
-def to_column_set(x):
- if x is None:
- return column_set()
- if not isinstance(x, column_set):
- return column_set(to_list(x))
- else:
- return x
-
-def update_copy(d, _new=None, **kw):
- """Copy the given dict and update with the given values."""
-
- d = d.copy()
- if _new:
- d.update(_new)
- d.update(**kw)
- return d
-
-def flatten_iterator(x):
- """Given an iterator of which further sub-elements may also be
- iterators, flatten the sub-elements into a single iterator.
-
- """
- for elem in x:
- if not isinstance(elem, basestring) and hasattr(elem, '__iter__'):
- for y in flatten_iterator(elem):
- yield y
- else:
- yield elem
-
-class WeakIdentityMapping(weakref.WeakKeyDictionary):
- """A WeakKeyDictionary with an object identity index.
-
- Adds a .by_id dictionary to a regular WeakKeyDictionary. Trades
- performance during mutation operations for accelerated lookups by id().
-
- The usual cautions about weak dictionaries and iteration also apply to
- this subclass.
-
- """
- _none = symbol('none')
-
- def __init__(self):
- weakref.WeakKeyDictionary.__init__(self)
- self.by_id = {}
- self._weakrefs = {}
-
- def __setitem__(self, object, value):
- oid = id(object)
- self.by_id[oid] = value
- if oid not in self._weakrefs:
- self._weakrefs[oid] = self._ref(object)
- weakref.WeakKeyDictionary.__setitem__(self, object, value)
-
- def __delitem__(self, object):
- del self._weakrefs[id(object)]
- del self.by_id[id(object)]
- weakref.WeakKeyDictionary.__delitem__(self, object)
-
- def setdefault(self, object, default=None):
- value = weakref.WeakKeyDictionary.setdefault(self, object, default)
- oid = id(object)
- if value is default:
- self.by_id[oid] = default
- if oid not in self._weakrefs:
- self._weakrefs[oid] = self._ref(object)
- return value
-
- def pop(self, object, default=_none):
- if default is self._none:
- value = weakref.WeakKeyDictionary.pop(self, object)
- else:
- value = weakref.WeakKeyDictionary.pop(self, object, default)
- if id(object) in self.by_id:
- del self._weakrefs[id(object)]
- del self.by_id[id(object)]
- return value
-
- def popitem(self):
- item = weakref.WeakKeyDictionary.popitem(self)
- oid = id(item[0])
- del self._weakrefs[oid]
- del self.by_id[oid]
- return item
-
- def clear(self):
- # Py2K
- # in 3k, MutableMapping calls popitem()
- self._weakrefs.clear()
- self.by_id.clear()
- # end Py2K
- weakref.WeakKeyDictionary.clear(self)
-
- def update(self, *a, **kw):
- raise NotImplementedError
-
- def _cleanup(self, wr, key=None):
- if key is None:
- key = wr.key
- try:
- del self._weakrefs[key]
- except (KeyError, AttributeError): # pragma: no cover
- pass # pragma: no cover
- try:
- del self.by_id[key]
- except (KeyError, AttributeError): # pragma: no cover
- pass # pragma: no cover
-
- class _keyed_weakref(weakref.ref):
- def __init__(self, object, callback):
- weakref.ref.__init__(self, object, callback)
- self.key = id(object)
-
- def _ref(self, object):
- return self._keyed_weakref(object, self._cleanup)
-
-
-class LRUCache(dict):
- """Dictionary with 'squishy' removal of least
- recently used items.
-
- """
- def __init__(self, capacity=100, threshold=.5):
- self.capacity = capacity
- self.threshold = threshold
-
- def __getitem__(self, key):
- item = dict.__getitem__(self, key)
- item[2] = time_func()
- return item[1]
-
- def values(self):
- return [i[1] for i in dict.values(self)]
-
- def setdefault(self, key, value):
- if key in self:
- return self[key]
- else:
- self[key] = value
- return value
-
- def __setitem__(self, key, value):
- item = dict.get(self, key)
- if item is None:
- item = [key, value, time_func()]
- dict.__setitem__(self, key, item)
- else:
- item[1] = value
- self._manage_size()
-
- def _manage_size(self):
- while len(self) > self.capacity + self.capacity * self.threshold:
- bytime = sorted(dict.values(self),
- key=operator.itemgetter(2),
- reverse=True)
- for item in bytime[self.capacity:]:
- try:
- del self[item[0]]
- except KeyError:
- # if we couldnt find a key, most
- # likely some other thread broke in
- # on us. loop around and try again
- break
-
-
-class ScopedRegistry(object):
- """A Registry that can store one or multiple instances of a single
- class on the basis of a "scope" function.
-
- The object implements ``__call__`` as the "getter", so by
- calling ``myregistry()`` the contained object is returned
- for the current scope.
-
- :param createfunc:
- a callable that returns a new object to be placed in the registry
-
- :param scopefunc:
- a callable that will return a key to store/retrieve an object.
- """
-
- def __init__(self, createfunc, scopefunc):
- """Construct a new :class:`.ScopedRegistry`.
-
- :param createfunc: A creation function that will generate
- a new value for the current scope, if none is present.
-
- :param scopefunc: A function that returns a hashable
- token representing the current scope (such as, current
- thread identifier).
-
- """
- self.createfunc = createfunc
- self.scopefunc = scopefunc
- self.registry = {}
-
- def __call__(self):
- key = self.scopefunc()
- try:
- return self.registry[key]
- except KeyError:
- return self.registry.setdefault(key, self.createfunc())
-
- def has(self):
- """Return True if an object is present in the current scope."""
-
- return self.scopefunc() in self.registry
-
- def set(self, obj):
- """Set the value forthe current scope."""
-
- self.registry[self.scopefunc()] = obj
-
- def clear(self):
- """Clear the current scope, if any."""
-
- try:
- del self.registry[self.scopefunc()]
- except KeyError:
- pass
-
-class ThreadLocalRegistry(ScopedRegistry):
- """A :class:`.ScopedRegistry` that uses a ``threading.local()``
- variable for storage.
-
- """
- def __init__(self, createfunc):
- self.createfunc = createfunc
- self.registry = threading.local()
-
- def __call__(self):
- try:
- return self.registry.value
- except AttributeError:
- val = self.registry.value = self.createfunc()
- return val
-
- def has(self):
- return hasattr(self.registry, "value")
-
- def set(self, obj):
- self.registry.value = obj
-
- def clear(self):
- try:
- del self.registry.value
- except AttributeError:
- pass
-
-def _iter_id(iterable):
- """Generator: ((id(o), o) for o in iterable)."""
-
- for item in iterable:
- yield id(item), item
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/compat.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/compat.py
deleted file mode 100755
index 0fb00450..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/compat.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# util/compat.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Handle Python version/platform incompatibilities."""
-
-import sys
-
-# Py2K
-import __builtin__
-# end Py2K
-
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
-
-py32 = sys.version_info >= (3, 2)
-py3k = getattr(sys, 'py3kwarning', False) or sys.version_info >= (3, 0)
-jython = sys.platform.startswith('java')
-pypy = hasattr(sys, 'pypy_version_info')
-win32 = sys.platform.startswith('win')
-
-if py3k:
- set_types = set
-elif sys.version_info < (2, 6):
- import sets
- set_types = set, sets.Set
-else:
- # 2.6 deprecates sets.Set, but we still need to be able to detect them
- # in user code and as return values from DB-APIs
- ignore = ('ignore', None, DeprecationWarning, None, 0)
- import warnings
- try:
- warnings.filters.insert(0, ignore)
- except Exception:
- import sets
- else:
- import sets
- warnings.filters.remove(ignore)
-
- set_types = set, sets.Set
-
-if py3k:
- import pickle
-else:
- try:
- import cPickle as pickle
- except ImportError:
- import pickle
-
-# a controversial feature, required by MySQLdb currently
-def buffer(x):
- return x
-
-# Py2K
-buffer = getattr(__builtin__, 'buffer', buffer)
-# end Py2K
-
-try:
- from functools import update_wrapper
-except ImportError:
- def update_wrapper(wrapper, wrapped,
- assigned=('__doc__', '__module__', '__name__'),
- updated=('__dict__',)):
- for attr in assigned:
- setattr(wrapper, attr, getattr(wrapped, attr))
- for attr in updated:
- getattr(wrapper, attr).update(getattr(wrapped, attr, ()))
- return wrapper
-
-try:
- from functools import partial
-except ImportError:
- def partial(func, *args, **keywords):
- def newfunc(*fargs, **fkeywords):
- newkeywords = keywords.copy()
- newkeywords.update(fkeywords)
- return func(*(args + fargs), **newkeywords)
- return newfunc
-
-
-if py3k:
- # they're bringing it back in 3.2. brilliant !
- def callable(fn):
- return hasattr(fn, '__call__')
- def cmp(a, b):
- return (a > b) - (a < b)
-
- from functools import reduce
-else:
- callable = __builtin__.callable
- cmp = __builtin__.cmp
- reduce = __builtin__.reduce
-
-try:
- from collections import defaultdict
-except ImportError:
- class defaultdict(dict):
- def __init__(self, default_factory=None, *a, **kw):
- if (default_factory is not None and
- not hasattr(default_factory, '__call__')):
- raise TypeError('first argument must be callable')
- dict.__init__(self, *a, **kw)
- self.default_factory = default_factory
- def __getitem__(self, key):
- try:
- return dict.__getitem__(self, key)
- except KeyError:
- return self.__missing__(key)
- def __missing__(self, key):
- if self.default_factory is None:
- raise KeyError(key)
- self[key] = value = self.default_factory()
- return value
- def __reduce__(self):
- if self.default_factory is None:
- args = tuple()
- else:
- args = self.default_factory,
- return type(self), args, None, None, self.iteritems()
- def copy(self):
- return self.__copy__()
- def __copy__(self):
- return type(self)(self.default_factory, self)
- def __deepcopy__(self, memo):
- import copy
- return type(self)(self.default_factory,
- copy.deepcopy(self.items()))
- def __repr__(self):
- return 'defaultdict(%s, %s)' % (self.default_factory,
- dict.__repr__(self))
-
-
-# find or create a dict implementation that supports __missing__
-class _probe(dict):
- def __missing__(self, key):
- return 1
-
-try:
- try:
- _probe()['missing']
- py25_dict = dict
- except KeyError:
- class py25_dict(dict):
- def __getitem__(self, key):
- try:
- return dict.__getitem__(self, key)
- except KeyError:
- try:
- missing = self.__missing__
- except AttributeError:
- raise KeyError(key)
- else:
- return missing(key)
-finally:
- del _probe
-
-
-try:
- import hashlib
- _md5 = hashlib.md5
-except ImportError:
- import md5
- _md5 = md5.new
-
-def md5_hex(x):
- # Py3K
- #x = x.encode('utf-8')
- m = _md5()
- m.update(x)
- return m.hexdigest()
-
-import time
-if win32 or jython:
- time_func = time.clock
-else:
- time_func = time.time
-
-if sys.version_info >= (2, 5):
- def decode_slice(slc):
- """decode a slice object as sent to __getitem__.
-
- takes into account the 2.5 __index__() method, basically.
-
- """
- ret = []
- for x in slc.start, slc.stop, slc.step:
- if hasattr(x, '__index__'):
- x = x.__index__()
- ret.append(x)
- return tuple(ret)
-else:
- def decode_slice(slc):
- return (slc.start, slc.stop, slc.step)
-
-if sys.version_info >= (2, 6):
- from operator import attrgetter as dottedgetter
-else:
- def dottedgetter(attr):
- def g(obj):
- for name in attr.split("."):
- obj = getattr(obj, name)
- return obj
- return g
-
-
-import decimal
-
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/deprecations.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/deprecations.py
deleted file mode 100755
index d9018a26..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/deprecations.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# util/deprecations.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Helpers related to deprecation of functions, methods, classes, other
-functionality."""
-
-from sqlalchemy import exc
-import warnings
-import re
-from langhelpers import decorator
-
-def warn_deprecated(msg, stacklevel=3):
- warnings.warn(msg, exc.SADeprecationWarning, stacklevel=stacklevel)
-
-def warn_pending_deprecation(msg, stacklevel=3):
- warnings.warn(msg, exc.SAPendingDeprecationWarning, stacklevel=stacklevel)
-
-def deprecated(version, message=None, add_deprecation_to_docstring=True):
- """Decorates a function and issues a deprecation warning on use.
-
- :param message:
- If provided, issue message in the warning. A sensible default
- is used if not provided.
-
- :param add_deprecation_to_docstring:
- Default True. If False, the wrapped function's __doc__ is left
- as-is. If True, the 'message' is prepended to the docs if
- provided, or sensible default if message is omitted.
-
- """
-
- if add_deprecation_to_docstring:
- header = ".. deprecated:: %s %s" % \
- (version, (message or ''))
- else:
- header = None
-
- if message is None:
- message = "Call to deprecated function %(func)s"
-
- def decorate(fn):
- return _decorate_with_warning(
- fn, exc.SADeprecationWarning,
- message % dict(func=fn.__name__), header)
- return decorate
-
-def pending_deprecation(version, message=None,
- add_deprecation_to_docstring=True):
- """Decorates a function and issues a pending deprecation warning on use.
-
- :param version:
- An approximate future version at which point the pending deprecation
- will become deprecated. Not used in messaging.
-
- :param message:
- If provided, issue message in the warning. A sensible default
- is used if not provided.
-
- :param add_deprecation_to_docstring:
- Default True. If False, the wrapped function's __doc__ is left
- as-is. If True, the 'message' is prepended to the docs if
- provided, or sensible default if message is omitted.
- """
-
- if add_deprecation_to_docstring:
- header = ".. deprecated:: %s (pending) %s" % \
- (version, (message or ''))
- else:
- header = None
-
- if message is None:
- message = "Call to deprecated function %(func)s"
-
- def decorate(fn):
- return _decorate_with_warning(
- fn, exc.SAPendingDeprecationWarning,
- message % dict(func=fn.__name__), header)
- return decorate
-
-def _sanitize_restructured_text(text):
- def repl(m):
- type_, name = m.group(1, 2)
- if type_ in ("func", "meth"):
- name += "()"
- return name
- return re.sub(r'\:(\w+)\:`~?\.?(.+?)`', repl, text)
-
-
-def _decorate_with_warning(func, wtype, message, docstring_header=None):
- """Wrap a function with a warnings.warn and augmented docstring."""
-
- message = _sanitize_restructured_text(message)
-
- @decorator
- def warned(fn, *args, **kwargs):
- warnings.warn(wtype(message), stacklevel=3)
- return fn(*args, **kwargs)
-
- doc = func.__doc__ is not None and func.__doc__ or ''
- if docstring_header is not None:
- docstring_header %= dict(func=func.__name__)
- docs = doc and doc.expandtabs().split('\n') or []
- indent = ''
- for line in docs[1:]:
- text = line.lstrip()
- if text:
- indent = line[0:len(line) - len(text)]
- break
- point = min(len(docs), 1)
- docs.insert(point, '\n' + indent + docstring_header.rstrip())
- doc = '\n'.join(docs)
-
- decorated = warned(func)
- decorated.__doc__ = doc
- return decorated
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/langhelpers.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/langhelpers.py
deleted file mode 100755
index ba612bc2..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/langhelpers.py
+++ /dev/null
@@ -1,791 +0,0 @@
-# util/langhelpers.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Routines to help with the creation, loading and introspection of
-modules, classes, hierarchies, attributes, functions, and methods.
-
-"""
-import itertools
-import inspect
-import operator
-import re
-import sys
-import types
-import warnings
-from compat import update_wrapper, set_types, threading
-from sqlalchemy import exc
-
-def _unique_symbols(used, *bases):
- used = set(used)
- for base in bases:
- pool = itertools.chain((base,),
- itertools.imap(lambda i: base + str(i),
- xrange(1000)))
- for sym in pool:
- if sym not in used:
- used.add(sym)
- yield sym
- break
- else:
- raise NameError("exhausted namespace for symbol base %s" % base)
-
-def decorator(target):
- """A signature-matching decorator factory."""
-
- def decorate(fn):
- if not inspect.isfunction(fn):
- raise Exception("not a decoratable function")
- spec = inspect.getargspec(fn)
- names = tuple(spec[0]) + spec[1:3] + (fn.func_name,)
- targ_name, fn_name = _unique_symbols(names, 'target', 'fn')
-
- metadata = dict(target=targ_name, fn=fn_name)
- metadata.update(format_argspec_plus(spec, grouped=False))
-
- code = 'lambda %(args)s: %(target)s(%(fn)s, %(apply_kw)s)' % (
- metadata)
- decorated = eval(code, {targ_name:target, fn_name:fn})
- decorated.func_defaults = getattr(fn, 'im_func', fn).func_defaults
- return update_wrapper(decorated, fn)
- return update_wrapper(decorate, target)
-
-
-
-def get_cls_kwargs(cls):
- """Return the full set of inherited kwargs for the given `cls`.
-
- Probes a class's __init__ method, collecting all named arguments. If the
- __init__ defines a \**kwargs catch-all, then the constructor is presumed to
- pass along unrecognized keywords to it's base classes, and the collection
- process is repeated recursively on each of the bases.
-
- Uses a subset of inspect.getargspec() to cut down on method overhead.
- No anonymous tuple arguments please !
-
- """
-
- for c in cls.__mro__:
- if '__init__' in c.__dict__:
- stack = set([c])
- break
- else:
- return []
-
- args = set()
- while stack:
- class_ = stack.pop()
- ctr = class_.__dict__.get('__init__', False)
- if (not ctr or
- not isinstance(ctr, types.FunctionType) or
- not isinstance(ctr.func_code, types.CodeType)):
- stack.update(class_.__bases__)
- continue
-
- # this is shorthand for
- # names, _, has_kw, _ = inspect.getargspec(ctr)
-
- names, has_kw = inspect_func_args(ctr)
- args.update(names)
- if has_kw:
- stack.update(class_.__bases__)
- args.discard('self')
- return args
-
-try:
- from inspect import CO_VARKEYWORDS
- def inspect_func_args(fn):
- co = fn.func_code
- nargs = co.co_argcount
- names = co.co_varnames
- args = list(names[:nargs])
- has_kw = bool(co.co_flags & CO_VARKEYWORDS)
- return args, has_kw
-except ImportError:
- def inspect_func_args(fn):
- names, _, has_kw, _ = inspect.getargspec(fn)
- return names, bool(has_kw)
-
-def get_func_kwargs(func):
- """Return the set of legal kwargs for the given `func`.
-
- Uses getargspec so is safe to call for methods, functions,
- etc.
-
- """
-
- return inspect.getargspec(func)[0]
-
-def format_argspec_plus(fn, grouped=True):
- """Returns a dictionary of formatted, introspected function arguments.
-
- A enhanced variant of inspect.formatargspec to support code generation.
-
- fn
- An inspectable callable or tuple of inspect getargspec() results.
- grouped
- Defaults to True; include (parens, around, argument) lists
-
- Returns:
-
- args
- Full inspect.formatargspec for fn
- self_arg
- The name of the first positional argument, varargs[0], or None
- if the function defines no positional arguments.
- apply_pos
- args, re-written in calling rather than receiving syntax. Arguments are
- passed positionally.
- apply_kw
- Like apply_pos, except keyword-ish args are passed as keywords.
-
- Example::
-
- >>> format_argspec_plus(lambda self, a, b, c=3, **d: 123)
- {'args': '(self, a, b, c=3, **d)',
- 'self_arg': 'self',
- 'apply_kw': '(self, a, b, c=c, **d)',
- 'apply_pos': '(self, a, b, c, **d)'}
-
- """
- spec = callable(fn) and inspect.getargspec(fn) or fn
- args = inspect.formatargspec(*spec)
- if spec[0]:
- self_arg = spec[0][0]
- elif spec[1]:
- self_arg = '%s[0]' % spec[1]
- else:
- self_arg = None
- apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2])
- defaulted_vals = spec[3] is not None and spec[0][0-len(spec[3]):] or ()
- apply_kw = inspect.formatargspec(spec[0], spec[1], spec[2], defaulted_vals,
- formatvalue=lambda x: '=' + x)
- if grouped:
- return dict(args=args, self_arg=self_arg,
- apply_pos=apply_pos, apply_kw=apply_kw)
- else:
- return dict(args=args[1:-1], self_arg=self_arg,
- apply_pos=apply_pos[1:-1], apply_kw=apply_kw[1:-1])
-
-def format_argspec_init(method, grouped=True):
- """format_argspec_plus with considerations for typical __init__ methods
-
- Wraps format_argspec_plus with error handling strategies for typical
- __init__ cases::
-
- object.__init__ -> (self)
- other unreflectable (usually C) -> (self, *args, **kwargs)
-
- """
- try:
- return format_argspec_plus(method, grouped=grouped)
- except TypeError:
- self_arg = 'self'
- if method is object.__init__:
- args = grouped and '(self)' or 'self'
- else:
- args = (grouped and '(self, *args, **kwargs)'
- or 'self, *args, **kwargs')
- return dict(self_arg='self', args=args, apply_pos=args, apply_kw=args)
-
-def getargspec_init(method):
- """inspect.getargspec with considerations for typical __init__ methods
-
- Wraps inspect.getargspec with error handling for typical __init__ cases::
-
- object.__init__ -> (self)
- other unreflectable (usually C) -> (self, *args, **kwargs)
-
- """
- try:
- return inspect.getargspec(method)
- except TypeError:
- if method is object.__init__:
- return (['self'], None, None, None)
- else:
- return (['self'], 'args', 'kwargs', None)
-
-
-def unbound_method_to_callable(func_or_cls):
- """Adjust the incoming callable such that a 'self' argument is not required."""
-
- if isinstance(func_or_cls, types.MethodType) and not func_or_cls.im_self:
- return func_or_cls.im_func
- else:
- return func_or_cls
-
-class portable_instancemethod(object):
- """Turn an instancemethod into a (parent, name) pair
- to produce a serializable callable.
-
- """
- def __init__(self, meth):
- self.target = meth.im_self
- self.name = meth.__name__
-
- def __call__(self, *arg, **kw):
- return getattr(self.target, self.name)(*arg, **kw)
-
-def class_hierarchy(cls):
- """Return an unordered sequence of all classes related to cls.
-
- Traverses diamond hierarchies.
-
- Fibs slightly: subclasses of builtin types are not returned. Thus
- class_hierarchy(class A(object)) returns (A, object), not A plus every
- class systemwide that derives from object.
-
- Old-style classes are discarded and hierarchies rooted on them
- will not be descended.
-
- """
- # Py2K
- if isinstance(cls, types.ClassType):
- return list()
- # end Py2K
- hier = set([cls])
- process = list(cls.__mro__)
- while process:
- c = process.pop()
- # Py2K
- if isinstance(c, types.ClassType):
- continue
- for b in (_ for _ in c.__bases__
- if _ not in hier and not isinstance(_, types.ClassType)):
- # end Py2K
- # Py3K
- #for b in (_ for _ in c.__bases__
- # if _ not in hier):
- process.append(b)
- hier.add(b)
- # Py3K
- #if c.__module__ == 'builtins' or not hasattr(c, '__subclasses__'):
- # continue
- # Py2K
- if c.__module__ == '__builtin__' or not hasattr(c, '__subclasses__'):
- continue
- # end Py2K
- for s in [_ for _ in c.__subclasses__() if _ not in hier]:
- process.append(s)
- hier.add(s)
- return list(hier)
-
-def iterate_attributes(cls):
- """iterate all the keys and attributes associated
- with a class, without using getattr().
-
- Does not use getattr() so that class-sensitive
- descriptors (i.e. property.__get__()) are not called.
-
- """
- keys = dir(cls)
- for key in keys:
- for c in cls.__mro__:
- if key in c.__dict__:
- yield (key, c.__dict__[key])
- break
-
-def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None,
- name='self.proxy', from_instance=None):
- """Automates delegation of __specials__ for a proxying type."""
-
- if only:
- dunders = only
- else:
- if skip is None:
- skip = ('__slots__', '__del__', '__getattribute__',
- '__metaclass__', '__getstate__', '__setstate__')
- dunders = [m for m in dir(from_cls)
- if (m.startswith('__') and m.endswith('__') and
- not hasattr(into_cls, m) and m not in skip)]
- for method in dunders:
- try:
- fn = getattr(from_cls, method)
- if not hasattr(fn, '__call__'):
- continue
- fn = getattr(fn, 'im_func', fn)
- except AttributeError:
- continue
- try:
- spec = inspect.getargspec(fn)
- fn_args = inspect.formatargspec(spec[0])
- d_args = inspect.formatargspec(spec[0][1:])
- except TypeError:
- fn_args = '(self, *args, **kw)'
- d_args = '(*args, **kw)'
-
- py = ("def %(method)s%(fn_args)s: "
- "return %(name)s.%(method)s%(d_args)s" % locals())
-
- env = from_instance is not None and {name: from_instance} or {}
- exec py in env
- try:
- env[method].func_defaults = fn.func_defaults
- except AttributeError:
- pass
- setattr(into_cls, method, env[method])
-
-
-def methods_equivalent(meth1, meth2):
- """Return True if the two methods are the same implementation."""
-
- # Py3K
- #return getattr(meth1, '__func__', meth1) is getattr(meth2, '__func__', meth2)
- # Py2K
- return getattr(meth1, 'im_func', meth1) is getattr(meth2, 'im_func', meth2)
- # end Py2K
-
-def as_interface(obj, cls=None, methods=None, required=None):
- """Ensure basic interface compliance for an instance or dict of callables.
-
- Checks that ``obj`` implements public methods of ``cls`` or has members
- listed in ``methods``. If ``required`` is not supplied, implementing at
- least one interface method is sufficient. Methods present on ``obj`` that
- are not in the interface are ignored.
-
- If ``obj`` is a dict and ``dict`` does not meet the interface
- requirements, the keys of the dictionary are inspected. Keys present in
- ``obj`` that are not in the interface will raise TypeErrors.
-
- Raises TypeError if ``obj`` does not meet the interface criteria.
-
- In all passing cases, an object with callable members is returned. In the
- simple case, ``obj`` is returned as-is; if dict processing kicks in then
- an anonymous class is returned.
-
- obj
- A type, instance, or dictionary of callables.
- cls
- Optional, a type. All public methods of cls are considered the
- interface. An ``obj`` instance of cls will always pass, ignoring
- ``required``..
- methods
- Optional, a sequence of method names to consider as the interface.
- required
- Optional, a sequence of mandatory implementations. If omitted, an
- ``obj`` that provides at least one interface method is considered
- sufficient. As a convenience, required may be a type, in which case
- all public methods of the type are required.
-
- """
- if not cls and not methods:
- raise TypeError('a class or collection of method names are required')
-
- if isinstance(cls, type) and isinstance(obj, cls):
- return obj
-
- interface = set(methods or [m for m in dir(cls) if not m.startswith('_')])
- implemented = set(dir(obj))
-
- complies = operator.ge
- if isinstance(required, type):
- required = interface
- elif not required:
- required = set()
- complies = operator.gt
- else:
- required = set(required)
-
- if complies(implemented.intersection(interface), required):
- return obj
-
- # No dict duck typing here.
- if not type(obj) is dict:
- qualifier = complies is operator.gt and 'any of' or 'all of'
- raise TypeError("%r does not implement %s: %s" % (
- obj, qualifier, ', '.join(interface)))
-
- class AnonymousInterface(object):
- """A callable-holding shell."""
-
- if cls:
- AnonymousInterface.__name__ = 'Anonymous' + cls.__name__
- found = set()
-
- for method, impl in dictlike_iteritems(obj):
- if method not in interface:
- raise TypeError("%r: unknown in this interface" % method)
- if not callable(impl):
- raise TypeError("%r=%r is not callable" % (method, impl))
- setattr(AnonymousInterface, method, staticmethod(impl))
- found.add(method)
-
- if complies(found, required):
- return AnonymousInterface
-
- raise TypeError("dictionary does not contain required keys %s" %
- ', '.join(required - found))
-
-
-class memoized_property(object):
- """A read-only @property that is only evaluated once."""
- def __init__(self, fget, doc=None):
- self.fget = fget
- self.__doc__ = doc or fget.__doc__
- self.__name__ = fget.__name__
-
- def __get__(self, obj, cls):
- if obj is None:
- return self
- obj.__dict__[self.__name__] = result = self.fget(obj)
- return result
-
-
-class memoized_instancemethod(object):
- """Decorate a method memoize its return value.
-
- Best applied to no-arg methods: memoization is not sensitive to
- argument values, and will always return the same value even when
- called with different arguments.
-
- """
- def __init__(self, fget, doc=None):
- self.fget = fget
- self.__doc__ = doc or fget.__doc__
- self.__name__ = fget.__name__
-
- def __get__(self, obj, cls):
- if obj is None:
- return self
- def oneshot(*args, **kw):
- result = self.fget(obj, *args, **kw)
- memo = lambda *a, **kw: result
- memo.__name__ = self.__name__
- memo.__doc__ = self.__doc__
- obj.__dict__[self.__name__] = memo
- return result
- oneshot.__name__ = self.__name__
- oneshot.__doc__ = self.__doc__
- return oneshot
-
-def reset_memoized(instance, name):
- instance.__dict__.pop(name, None)
-
-
-class group_expirable_memoized_property(object):
- """A family of @memoized_properties that can be expired in tandem."""
-
- def __init__(self):
- self.attributes = []
-
- def expire_instance(self, instance):
- """Expire all memoized properties for *instance*."""
- stash = instance.__dict__
- for attribute in self.attributes:
- stash.pop(attribute, None)
-
- def __call__(self, fn):
- self.attributes.append(fn.__name__)
- return memoized_property(fn)
-
-class importlater(object):
- """Deferred import object.
-
- e.g.::
-
- somesubmod = importlater("mypackage.somemodule", "somesubmod")
-
- is equivalent to::
-
- from mypackage.somemodule import somesubmod
-
- except evaluted upon attribute access to "somesubmod".
-
- """
- def __init__(self, path, addtl=None):
- self._il_path = path
- self._il_addtl = addtl
-
- @memoized_property
- def module(self):
- if self._il_addtl:
- m = __import__(self._il_path, globals(), locals(),
- [self._il_addtl])
- try:
- return getattr(m, self._il_addtl)
- except AttributeError:
- raise ImportError(
- "Module %s has no attribute '%s'" %
- (self._il_path, self._il_addtl)
- )
- else:
- m = __import__(self._il_path)
- for token in self._il_path.split(".")[1:]:
- m = getattr(m, token)
- return m
-
- def __getattr__(self, key):
- try:
- attr = getattr(self.module, key)
- except AttributeError:
- raise AttributeError(
- "Module %s has no attribute '%s'" %
- (self._il_path, key)
- )
- self.__dict__[key] = attr
- return attr
-
-# from paste.deploy.converters
-def asbool(obj):
- if isinstance(obj, (str, unicode)):
- obj = obj.strip().lower()
- if obj in ['true', 'yes', 'on', 'y', 't', '1']:
- return True
- elif obj in ['false', 'no', 'off', 'n', 'f', '0']:
- return False
- else:
- raise ValueError("String is not true/false: %r" % obj)
- return bool(obj)
-
-def bool_or_str(*text):
- """Return a callable that will evaulate a string as
- boolean, or one of a set of "alternate" string values.
-
- """
- def bool_or_value(obj):
- if obj in text:
- return obj
- else:
- return asbool(obj)
- return bool_or_value
-
-def asint(value):
- """Coerce to integer."""
-
- if value is None:
- return value
- return int(value)
-
-
-def coerce_kw_type(kw, key, type_, flexi_bool=True):
- """If 'key' is present in dict 'kw', coerce its value to type 'type\_' if
- necessary. If 'flexi_bool' is True, the string '0' is considered false
- when coercing to boolean.
- """
-
- if key in kw and type(kw[key]) is not type_ and kw[key] is not None:
- if type_ is bool and flexi_bool:
- kw[key] = asbool(kw[key])
- else:
- kw[key] = type_(kw[key])
-
-
-def constructor_copy(obj, cls, **kw):
- """Instantiate cls using the __dict__ of obj as constructor arguments.
-
- Uses inspect to match the named arguments of ``cls``.
-
- """
-
- names = get_cls_kwargs(cls)
- kw.update((k, obj.__dict__[k]) for k in names if k in obj.__dict__)
- return cls(**kw)
-
-
-def duck_type_collection(specimen, default=None):
- """Given an instance or class, guess if it is or is acting as one of
- the basic collection types: list, set and dict. If the __emulates__
- property is present, return that preferentially.
- """
-
- if hasattr(specimen, '__emulates__'):
- # canonicalize set vs sets.Set to a standard: the builtin set
- if (specimen.__emulates__ is not None and
- issubclass(specimen.__emulates__, set_types)):
- return set
- else:
- return specimen.__emulates__
-
- isa = isinstance(specimen, type) and issubclass or isinstance
- if isa(specimen, list):
- return list
- elif isa(specimen, set_types):
- return set
- elif isa(specimen, dict):
- return dict
-
- if hasattr(specimen, 'append'):
- return list
- elif hasattr(specimen, 'add'):
- return set
- elif hasattr(specimen, 'set'):
- return dict
- else:
- return default
-
-def assert_arg_type(arg, argtype, name):
- if isinstance(arg, argtype):
- return arg
- else:
- if isinstance(argtype, tuple):
- raise exc.ArgumentError(
- "Argument '%s' is expected to be one of type %s, got '%s'" %
- (name, ' or '.join("'%s'" % a for a in argtype), type(arg)))
- else:
- raise exc.ArgumentError(
- "Argument '%s' is expected to be of type '%s', got '%s'" %
- (name, argtype, type(arg)))
-
-
-def dictlike_iteritems(dictlike):
- """Return a (key, value) iterator for almost any dict-like object."""
-
- # Py3K
- #if hasattr(dictlike, 'items'):
- # return dictlike.items()
- # Py2K
- if hasattr(dictlike, 'iteritems'):
- return dictlike.iteritems()
- elif hasattr(dictlike, 'items'):
- return iter(dictlike.items())
- # end Py2K
-
- getter = getattr(dictlike, '__getitem__', getattr(dictlike, 'get', None))
- if getter is None:
- raise TypeError(
- "Object '%r' is not dict-like" % dictlike)
-
- if hasattr(dictlike, 'iterkeys'):
- def iterator():
- for key in dictlike.iterkeys():
- yield key, getter(key)
- return iterator()
- elif hasattr(dictlike, 'keys'):
- return iter((key, getter(key)) for key in dictlike.keys())
- else:
- raise TypeError(
- "Object '%r' is not dict-like" % dictlike)
-
-
-class classproperty(property):
- """A decorator that behaves like @property except that operates
- on classes rather than instances.
-
- The decorator is currently special when using the declarative
- module, but note that the
- :class:`~.sqlalchemy.ext.declarative.declared_attr`
- decorator should be used for this purpose with declarative.
-
- """
-
- def __init__(self, fget, *arg, **kw):
- super(classproperty, self).__init__(fget, *arg, **kw)
- self.__doc__ = fget.__doc__
-
- def __get__(desc, self, cls):
- return desc.fget(cls)
-
-
-class _symbol(object):
- def __init__(self, name, doc=None):
- """Construct a new named symbol."""
- assert isinstance(name, str)
- self.name = name
- if doc:
- self.__doc__ = doc
- def __reduce__(self):
- return symbol, (self.name,)
- def __repr__(self):
- return "<symbol '%s>" % self.name
-
-_symbol.__name__ = 'symbol'
-
-
-class symbol(object):
- """A constant symbol.
-
- >>> symbol('foo') is symbol('foo')
- True
- >>> symbol('foo')
- <symbol 'foo>
-
- A slight refinement of the MAGICCOOKIE=object() pattern. The primary
- advantage of symbol() is its repr(). They are also singletons.
-
- Repeated calls of symbol('name') will all return the same instance.
-
- The optional ``doc`` argument assigns to ``__doc__``. This
- is strictly so that Sphinx autoattr picks up the docstring we want
- (it doesn't appear to pick up the in-module docstring if the datamember
- is in a different module - autoattribute also blows up completely).
- If Sphinx fixes/improves this then we would no longer need
- ``doc`` here.
-
- """
- symbols = {}
- _lock = threading.Lock()
-
- def __new__(cls, name, doc=None):
- cls._lock.acquire()
- try:
- sym = cls.symbols.get(name)
- if sym is None:
- cls.symbols[name] = sym = _symbol(name, doc)
- return sym
- finally:
- symbol._lock.release()
-
-
-_creation_order = 1
-def set_creation_order(instance):
- """Assign a '_creation_order' sequence to the given instance.
-
- This allows multiple instances to be sorted in order of creation
- (typically within a single thread; the counter is not particularly
- threadsafe).
-
- """
- global _creation_order
- instance._creation_order = _creation_order
- _creation_order +=1
-
-def warn_exception(func, *args, **kwargs):
- """executes the given function, catches all exceptions and converts to a warning."""
- try:
- return func(*args, **kwargs)
- except:
- warn("%s('%s') ignored" % sys.exc_info()[0:2])
-
-
-def warn(msg, stacklevel=3):
- """Issue a warning.
-
- If msg is a string, :class:`.exc.SAWarning` is used as
- the category.
-
- .. note:: This function is swapped out when the test suite
- runs, with a compatible version that uses
- warnings.warn_explicit, so that the warnings registry can
- be controlled.
-
- """
- if isinstance(msg, basestring):
- warnings.warn(msg, exc.SAWarning, stacklevel=stacklevel)
- else:
- warnings.warn(msg, stacklevel=stacklevel)
-
-_SQLA_RE = re.compile(r'sqlalchemy/([a-z_]+/){0,2}[a-z_]+\.py')
-_UNITTEST_RE = re.compile(r'unit(?:2|test2?/)')
-def chop_traceback(tb, exclude_prefix=_UNITTEST_RE, exclude_suffix=_SQLA_RE):
- """Chop extraneous lines off beginning and end of a traceback.
-
- :param tb:
- a list of traceback lines as returned by ``traceback.format_stack()``
-
- :param exclude_prefix:
- a regular expression object matching lines to skip at beginning of ``tb``
-
- :param exclude_suffix:
- a regular expression object matching lines to skip at end of ``tb``
- """
- start = 0
- end = len(tb) - 1
- while start <= end and exclude_prefix.search(tb[start]):
- start += 1
- while start <= end and exclude_suffix.search(tb[end]):
- end -= 1
- return tb[start:end+1]
-
-NoneType = type(None)
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/queue.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/queue.py
deleted file mode 100755
index db717595..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/queue.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# util/queue.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""An adaptation of Py2.3/2.4's Queue module which supports reentrant
-behavior, using RLock instead of Lock for its mutex object.
-
-This is to support the connection pool's usage of weakref callbacks to return
-connections to the underlying Queue, which can in extremely
-rare cases be invoked within the ``get()`` method of the Queue itself,
-producing a ``put()`` inside the ``get()`` and therefore a reentrant
-condition."""
-
-from collections import deque
-from time import time as _time
-from sqlalchemy.util import threading
-
-__all__ = ['Empty', 'Full', 'Queue']
-
-class Empty(Exception):
- "Exception raised by Queue.get(block=0)/get_nowait()."
-
- pass
-
-class Full(Exception):
- "Exception raised by Queue.put(block=0)/put_nowait()."
-
- pass
-
-class Queue:
- def __init__(self, maxsize=0):
- """Initialize a queue object with a given maximum size.
-
- If `maxsize` is <= 0, the queue size is infinite.
- """
-
- self._init(maxsize)
- # mutex must be held whenever the queue is mutating. All methods
- # that acquire mutex must release it before returning. mutex
- # is shared between the two conditions, so acquiring and
- # releasing the conditions also acquires and releases mutex.
- self.mutex = threading.RLock()
- # Notify not_empty whenever an item is added to the queue; a
- # thread waiting to get is notified then.
- self.not_empty = threading.Condition(self.mutex)
- # Notify not_full whenever an item is removed from the queue;
- # a thread waiting to put is notified then.
- self.not_full = threading.Condition(self.mutex)
-
- def qsize(self):
- """Return the approximate size of the queue (not reliable!)."""
-
- self.mutex.acquire()
- n = self._qsize()
- self.mutex.release()
- return n
-
- def empty(self):
- """Return True if the queue is empty, False otherwise (not
- reliable!)."""
-
- self.mutex.acquire()
- n = self._empty()
- self.mutex.release()
- return n
-
- def full(self):
- """Return True if the queue is full, False otherwise (not
- reliable!)."""
-
- self.mutex.acquire()
- n = self._full()
- self.mutex.release()
- return n
-
- def put(self, item, block=True, timeout=None):
- """Put an item into the queue.
-
- If optional args `block` is True and `timeout` is None (the
- default), block if necessary until a free slot is
- available. If `timeout` is a positive number, it blocks at
- most `timeout` seconds and raises the ``Full`` exception if no
- free slot was available within that time. Otherwise (`block`
- is false), put an item on the queue if a free slot is
- immediately available, else raise the ``Full`` exception
- (`timeout` is ignored in that case).
- """
-
- self.not_full.acquire()
- try:
- if not block:
- if self._full():
- raise Full
- elif timeout is None:
- while self._full():
- self.not_full.wait()
- else:
- if timeout < 0:
- raise ValueError("'timeout' must be a positive number")
- endtime = _time() + timeout
- while self._full():
- remaining = endtime - _time()
- if remaining <= 0.0:
- raise Full
- self.not_full.wait(remaining)
- self._put(item)
- self.not_empty.notify()
- finally:
- self.not_full.release()
-
- def put_nowait(self, item):
- """Put an item into the queue without blocking.
-
- Only enqueue the item if a free slot is immediately available.
- Otherwise raise the ``Full`` exception.
- """
- return self.put(item, False)
-
- def get(self, block=True, timeout=None):
- """Remove and return an item from the queue.
-
- If optional args `block` is True and `timeout` is None (the
- default), block if necessary until an item is available. If
- `timeout` is a positive number, it blocks at most `timeout`
- seconds and raises the ``Empty`` exception if no item was
- available within that time. Otherwise (`block` is false),
- return an item if one is immediately available, else raise the
- ``Empty`` exception (`timeout` is ignored in that case).
- """
-
- self.not_empty.acquire()
- try:
- if not block:
- if self._empty():
- raise Empty
- elif timeout is None:
- while self._empty():
- self.not_empty.wait()
- else:
- if timeout < 0:
- raise ValueError("'timeout' must be a positive number")
- endtime = _time() + timeout
- while self._empty():
- remaining = endtime - _time()
- if remaining <= 0.0:
- raise Empty
- self.not_empty.wait(remaining)
- item = self._get()
- self.not_full.notify()
- return item
- finally:
- self.not_empty.release()
-
- def get_nowait(self):
- """Remove and return an item from the queue without blocking.
-
- Only get an item if one is immediately available. Otherwise
- raise the ``Empty`` exception.
- """
-
- return self.get(False)
-
- # Override these methods to implement other queue organizations
- # (e.g. stack or priority queue).
- # These will only be called with appropriate locks held
-
- # Initialize the queue representation
- def _init(self, maxsize):
- self.maxsize = maxsize
- self.queue = deque()
-
- def _qsize(self):
- return len(self.queue)
-
- # Check whether the queue is empty
- def _empty(self):
- return not self.queue
-
- # Check whether the queue is full
- def _full(self):
- return self.maxsize > 0 and len(self.queue) == self.maxsize
-
- # Put a new item in the queue
- def _put(self, item):
- self.queue.append(item)
-
- # Get an item from the queue
- def _get(self):
- return self.queue.popleft()
diff --git a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/topological.py b/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/topological.py
deleted file mode 100755
index 8f340647..00000000
--- a/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg/sqlalchemy/util/topological.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# util/topological.py
-# Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Topological sorting algorithms."""
-
-from sqlalchemy.exc import CircularDependencyError
-from sqlalchemy import util
-
-
-__all__ = ['sort', 'sort_as_subsets', 'find_cycles']
-
-def sort_as_subsets(tuples, allitems):
-
- edges = util.defaultdict(set)
- for parent, child in tuples:
- edges[child].add(parent)
-
- todo = set(allitems)
-
- while todo:
- output = set()
- for node in list(todo):
- if not todo.intersection(edges[node]):
- output.add(node)
-
- if not output:
- raise CircularDependencyError(
- "Circular dependency detected",
- find_cycles(tuples, allitems),
- _gen_edges(edges)
- )
-
- todo.difference_update(output)
- yield output
-
-def sort(tuples, allitems):
- """sort the given list of items by dependency.
-
- 'tuples' is a list of tuples representing a partial ordering.
- """
-
- for set_ in sort_as_subsets(tuples, allitems):
- for s in set_:
- yield s
-
-def find_cycles(tuples, allitems):
- # straight from gvr with some mods
- todo = set(allitems)
-
- edges = util.defaultdict(set)
- for parent, child in tuples:
- edges[parent].add(child)
-
- output = set()
-
- while todo:
- node = todo.pop()
- stack = [node]
- while stack:
- top = stack[-1]
- for node in edges[top]:
- if node in stack:
- cyc = stack[stack.index(node):]
- todo.difference_update(cyc)
- output.update(cyc)
-
- if node in todo:
- stack.append(node)
- todo.remove(node)
- break
- else:
- node = stack.pop()
- return output
-
-def _gen_edges(edges):
- return set([
- (right, left)
- for left in edges
- for right in edges[left]
- ])
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 20d7f67d..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,32 +0,0 @@
-Metadata-Version: 1.1
-Name: Tempita
-Version: 0.5.1
-Summary: A very small text templating language
-Home-page: http://pythonpaste.org/tempita/
-Author: Ian Bicking
-Author-email: ianb@colorstudy.com
-License: MIT
-Description: Tempita is a small templating language for text substitution.
-
- This isn't meant to be the Next Big Thing in templating; it's just a
- handy little templating language for when your project outgrows
- ``string.Template`` or ``%`` substitution. It's small, it embeds
- Python in strings, and it doesn't do much else.
-
- You can read about the `language
- <http://pythonpaste.org/tempita/#the-language>`_, the `interface
- <http://pythonpaste.org/tempita/#the-interface>`_, and there's nothing
- more to learn about it.
-
- You can install from the `svn repository
- <http://svn.pythonpaste.org/Tempita/trunk#Tempita-dev>`__ with
- ``easy_install Tempita==dev``.
-
-Keywords: templating template language html
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Topic :: Text Processing
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 429a83c8..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-setup.cfg
-setup.py
-Tempita.egg-info/PKG-INFO
-Tempita.egg-info/SOURCES.txt
-Tempita.egg-info/dependency_links.txt
-Tempita.egg-info/top_level.txt
-Tempita.egg-info/zip-safe
-tempita/__init__.py
-tempita/_looper.py
-tempita/compat3.py \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index eddfc48a..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-tempita
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/zip-safe b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/EGG-INFO/zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/__init__.py b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/__init__.py
deleted file mode 100755
index 83528b3c..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/__init__.py
+++ /dev/null
@@ -1,1183 +0,0 @@
-"""
-A small templating language
-
-This implements a small templating language. This language implements
-if/elif/else, for/continue/break, expressions, and blocks of Python
-code. The syntax is::
-
- {{any expression (function calls etc)}}
- {{any expression | filter}}
- {{for x in y}}...{{endfor}}
- {{if x}}x{{elif y}}y{{else}}z{{endif}}
- {{py:x=1}}
- {{py:
- def foo(bar):
- return 'baz'
- }}
- {{default var = default_value}}
- {{# comment}}
-
-You use this with the ``Template`` class or the ``sub`` shortcut.
-The ``Template`` class takes the template string and the name of
-the template (for errors) and a default namespace. Then (like
-``string.Template``) you can call the ``tmpl.substitute(**kw)``
-method to make a substitution (or ``tmpl.substitute(a_dict)``).
-
-``sub(content, **kw)`` substitutes the template immediately. You
-can use ``__name='tmpl.html'`` to set the name of the template.
-
-If there are syntax errors ``TemplateError`` will be raised.
-"""
-
-import re
-import sys
-import cgi
-from urllib import quote as url_quote
-import os
-import tokenize
-from cStringIO import StringIO
-from tempita._looper import looper
-from tempita.compat3 import bytes, basestring_, next, is_unicode, coerce_text
-
-__all__ = ['TemplateError', 'Template', 'sub', 'HTMLTemplate',
- 'sub_html', 'html', 'bunch']
-
-in_re = re.compile(r'\s+in\s+')
-var_re = re.compile(r'^[a-z_][a-z0-9_]*$', re.I)
-
-
-class TemplateError(Exception):
- """Exception raised while parsing a template
- """
-
- def __init__(self, message, position, name=None):
- Exception.__init__(self, message)
- self.position = position
- self.name = name
-
- def __str__(self):
- msg = ' '.join(self.args)
- if self.position:
- msg = '%s at line %s column %s' % (
- msg, self.position[0], self.position[1])
- if self.name:
- msg += ' in %s' % self.name
- return msg
-
-
-class _TemplateContinue(Exception):
- pass
-
-
-class _TemplateBreak(Exception):
- pass
-
-
-def get_file_template(name, from_template):
- path = os.path.join(os.path.dirname(from_template.name), name)
- return from_template.__class__.from_filename(
- path, namespace=from_template.namespace,
- get_template=from_template.get_template)
-
-
-class Template(object):
-
- default_namespace = {
- 'start_braces': '{{',
- 'end_braces': '}}',
- 'looper': looper,
- }
-
- default_encoding = 'utf8'
- default_inherit = None
-
- def __init__(self, content, name=None, namespace=None, stacklevel=None,
- get_template=None, default_inherit=None, line_offset=0,
- delimeters=None):
- self.content = content
-
- # set delimeters
- if delimeters is None:
- delimeters = (self.default_namespace['start_braces'],
- self.default_namespace['end_braces'])
- else:
- assert len(delimeters) == 2 and all([isinstance(delimeter, basestring)
- for delimeter in delimeters])
- self.default_namespace = self.__class__.default_namespace.copy()
- self.default_namespace['start_braces'] = delimeters[0]
- self.default_namespace['end_braces'] = delimeters[1]
- self.delimeters = delimeters
-
- self._unicode = is_unicode(content)
- if name is None and stacklevel is not None:
- try:
- caller = sys._getframe(stacklevel)
- except ValueError:
- pass
- else:
- globals = caller.f_globals
- lineno = caller.f_lineno
- if '__file__' in globals:
- name = globals['__file__']
- if name.endswith('.pyc') or name.endswith('.pyo'):
- name = name[:-1]
- elif '__name__' in globals:
- name = globals['__name__']
- else:
- name = '<string>'
- if lineno:
- name += ':%s' % lineno
- self.name = name
- self._parsed = parse(content, name=name, line_offset=line_offset, delimeters=self.delimeters)
- if namespace is None:
- namespace = {}
- self.namespace = namespace
- self.get_template = get_template
- if default_inherit is not None:
- self.default_inherit = default_inherit
-
- def from_filename(cls, filename, namespace=None, encoding=None,
- default_inherit=None, get_template=get_file_template):
- f = open(filename, 'rb')
- c = f.read()
- f.close()
- if encoding:
- c = c.decode(encoding)
- return cls(content=c, name=filename, namespace=namespace,
- default_inherit=default_inherit, get_template=get_template)
-
- from_filename = classmethod(from_filename)
-
- def __repr__(self):
- return '<%s %s name=%r>' % (
- self.__class__.__name__,
- hex(id(self))[2:], self.name)
-
- def substitute(self, *args, **kw):
- if args:
- if kw:
- raise TypeError(
- "You can only give positional *or* keyword arguments")
- if len(args) > 1:
- raise TypeError(
- "You can only give one positional argument")
- if not hasattr(args[0], 'items'):
- raise TypeError(
- "If you pass in a single argument, you must pass in a dictionary-like object (with a .items() method); you gave %r"
- % (args[0],))
- kw = args[0]
- ns = kw
- ns['__template_name__'] = self.name
- if self.namespace:
- ns.update(self.namespace)
- result, defs, inherit = self._interpret(ns)
- if not inherit:
- inherit = self.default_inherit
- if inherit:
- result = self._interpret_inherit(result, defs, inherit, ns)
- return result
-
- def _interpret(self, ns):
- __traceback_hide__ = True
- parts = []
- defs = {}
- self._interpret_codes(self._parsed, ns, out=parts, defs=defs)
- if '__inherit__' in defs:
- inherit = defs.pop('__inherit__')
- else:
- inherit = None
- return ''.join(parts), defs, inherit
-
- def _interpret_inherit(self, body, defs, inherit_template, ns):
- __traceback_hide__ = True
- if not self.get_template:
- raise TemplateError(
- 'You cannot use inheritance without passing in get_template',
- position=None, name=self.name)
- templ = self.get_template(inherit_template, self)
- self_ = TemplateObject(self.name)
- for name, value in defs.iteritems():
- setattr(self_, name, value)
- self_.body = body
- ns = ns.copy()
- ns['self'] = self_
- return templ.substitute(ns)
-
- def _interpret_codes(self, codes, ns, out, defs):
- __traceback_hide__ = True
- for item in codes:
- if isinstance(item, basestring_):
- out.append(item)
- else:
- self._interpret_code(item, ns, out, defs)
-
- def _interpret_code(self, code, ns, out, defs):
- __traceback_hide__ = True
- name, pos = code[0], code[1]
- if name == 'py':
- self._exec(code[2], ns, pos)
- elif name == 'continue':
- raise _TemplateContinue()
- elif name == 'break':
- raise _TemplateBreak()
- elif name == 'for':
- vars, expr, content = code[2], code[3], code[4]
- expr = self._eval(expr, ns, pos)
- self._interpret_for(vars, expr, content, ns, out, defs)
- elif name == 'cond':
- parts = code[2:]
- self._interpret_if(parts, ns, out, defs)
- elif name == 'expr':
- parts = code[2].split('|')
- base = self._eval(parts[0], ns, pos)
- for part in parts[1:]:
- func = self._eval(part, ns, pos)
- base = func(base)
- out.append(self._repr(base, pos))
- elif name == 'default':
- var, expr = code[2], code[3]
- if var not in ns:
- result = self._eval(expr, ns, pos)
- ns[var] = result
- elif name == 'inherit':
- expr = code[2]
- value = self._eval(expr, ns, pos)
- defs['__inherit__'] = value
- elif name == 'def':
- name = code[2]
- signature = code[3]
- parts = code[4]
- ns[name] = defs[name] = TemplateDef(self, name, signature, body=parts, ns=ns,
- pos=pos)
- elif name == 'comment':
- return
- else:
- assert 0, "Unknown code: %r" % name
-
- def _interpret_for(self, vars, expr, content, ns, out, defs):
- __traceback_hide__ = True
- for item in expr:
- if len(vars) == 1:
- ns[vars[0]] = item
- else:
- if len(vars) != len(item):
- raise ValueError(
- 'Need %i items to unpack (got %i items)'
- % (len(vars), len(item)))
- for name, value in zip(vars, item):
- ns[name] = value
- try:
- self._interpret_codes(content, ns, out, defs)
- except _TemplateContinue:
- continue
- except _TemplateBreak:
- break
-
- def _interpret_if(self, parts, ns, out, defs):
- __traceback_hide__ = True
- # @@: if/else/else gets through
- for part in parts:
- assert not isinstance(part, basestring_)
- name, pos = part[0], part[1]
- if name == 'else':
- result = True
- else:
- result = self._eval(part[2], ns, pos)
- if result:
- self._interpret_codes(part[3], ns, out, defs)
- break
-
- def _eval(self, code, ns, pos):
- __traceback_hide__ = True
- try:
- try:
- value = eval(code, self.default_namespace, ns)
- except SyntaxError, e:
- raise SyntaxError(
- 'invalid syntax in expression: %s' % code)
- return value
- except:
- exc_info = sys.exc_info()
- e = exc_info[1]
- if getattr(e, 'args', None):
- arg0 = e.args[0]
- else:
- arg0 = coerce_text(e)
- e.args = (self._add_line_info(arg0, pos),)
- raise exc_info[0], e, exc_info[2]
-
- def _exec(self, code, ns, pos):
- __traceback_hide__ = True
- try:
- exec code in self.default_namespace, ns
- except:
- exc_info = sys.exc_info()
- e = exc_info[1]
- if e.args:
- e.args = (self._add_line_info(e.args[0], pos),)
- else:
- e.args = (self._add_line_info(None, pos),)
- raise exc_info[0], e, exc_info[2]
-
- def _repr(self, value, pos):
- __traceback_hide__ = True
- try:
- if value is None:
- return ''
- if self._unicode:
- try:
- value = unicode(value)
- except UnicodeDecodeError:
- value = bytes(value)
- else:
- if not isinstance(value, basestring_):
- value = coerce_text(value)
- if (is_unicode(value)
- and self.default_encoding):
- value = value.encode(self.default_encoding)
- except:
- exc_info = sys.exc_info()
- e = exc_info[1]
- e.args = (self._add_line_info(e.args[0], pos),)
- raise exc_info[0], e, exc_info[2]
- else:
- if self._unicode and isinstance(value, bytes):
- if not self.default_encoding:
- raise UnicodeDecodeError(
- 'Cannot decode bytes value %r into unicode '
- '(no default_encoding provided)' % value)
- try:
- value = value.decode(self.default_encoding)
- except UnicodeDecodeError, e:
- raise UnicodeDecodeError(
- e.encoding,
- e.object,
- e.start,
- e.end,
- e.reason + ' in string %r' % value)
- elif not self._unicode and is_unicode(value):
- if not self.default_encoding:
- raise UnicodeEncodeError(
- 'Cannot encode unicode value %r into bytes '
- '(no default_encoding provided)' % value)
- value = value.encode(self.default_encoding)
- return value
-
- def _add_line_info(self, msg, pos):
- msg = "%s at line %s column %s" % (
- msg, pos[0], pos[1])
- if self.name:
- msg += " in file %s" % self.name
- return msg
-
-
-def sub(content, delimeters=None, **kw):
- name = kw.get('__name')
- tmpl = Template(content, name=name, delimeters=delimeters)
- return tmpl.substitute(kw)
-
-
-def paste_script_template_renderer(content, vars, filename=None):
- tmpl = Template(content, name=filename)
- return tmpl.substitute(vars)
-
-
-class bunch(dict):
-
- def __init__(self, **kw):
- for name, value in kw.iteritems():
- setattr(self, name, value)
-
- def __setattr__(self, name, value):
- self[name] = value
-
- def __getattr__(self, name):
- try:
- return self[name]
- except KeyError:
- raise AttributeError(name)
-
- def __getitem__(self, key):
- if 'default' in self:
- try:
- return dict.__getitem__(self, key)
- except KeyError:
- return dict.__getitem__(self, 'default')
- else:
- return dict.__getitem__(self, key)
-
- def __repr__(self):
- items = [
- (k, v) for k, v in self.iteritems()]
- items.sort()
- return '<%s %s>' % (
- self.__class__.__name__,
- ' '.join(['%s=%r' % (k, v) for k, v in items]))
-
-############################################################
-## HTML Templating
-############################################################
-
-
-class html(object):
-
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return self.value
-
- def __html__(self):
- return self.value
-
- def __repr__(self):
- return '<%s %r>' % (
- self.__class__.__name__, self.value)
-
-
-def html_quote(value, force=True):
- if not force and hasattr(value, '__html__'):
- return value.__html__()
- if value is None:
- return ''
- if not isinstance(value, basestring_):
- value = coerce_text(value)
- if sys.version >= "3" and isinstance(value, bytes):
- value = cgi.escape(value.decode('latin1'), 1)
- value = value.encode('latin1')
- else:
- value = cgi.escape(value, 1)
- if sys.version < "3":
- if is_unicode(value):
- value = value.encode('ascii', 'xmlcharrefreplace')
- return value
-
-
-def url(v):
- v = coerce_text(v)
- if is_unicode(v):
- v = v.encode('utf8')
- return url_quote(v)
-
-
-def attr(**kw):
- kw = list(kw.iteritems())
- kw.sort()
- parts = []
- for name, value in kw:
- if value is None:
- continue
- if name.endswith('_'):
- name = name[:-1]
- parts.append('%s="%s"' % (html_quote(name), html_quote(value)))
- return html(' '.join(parts))
-
-
-class HTMLTemplate(Template):
-
- default_namespace = Template.default_namespace.copy()
- default_namespace.update(dict(
- html=html,
- attr=attr,
- url=url,
- html_quote=html_quote,
- ))
-
- def _repr(self, value, pos):
- if hasattr(value, '__html__'):
- value = value.__html__()
- quote = False
- else:
- quote = True
- plain = Template._repr(self, value, pos)
- if quote:
- return html_quote(plain)
- else:
- return plain
-
-
-def sub_html(content, **kw):
- name = kw.get('__name')
- tmpl = HTMLTemplate(content, name=name)
- return tmpl.substitute(kw)
-
-
-class TemplateDef(object):
- def __init__(self, template, func_name, func_signature,
- body, ns, pos, bound_self=None):
- self._template = template
- self._func_name = func_name
- self._func_signature = func_signature
- self._body = body
- self._ns = ns
- self._pos = pos
- self._bound_self = bound_self
-
- def __repr__(self):
- return '<tempita function %s(%s) at %s:%s>' % (
- self._func_name, self._func_signature,
- self._template.name, self._pos)
-
- def __str__(self):
- return self()
-
- def __call__(self, *args, **kw):
- values = self._parse_signature(args, kw)
- ns = self._ns.copy()
- ns.update(values)
- if self._bound_self is not None:
- ns['self'] = self._bound_self
- out = []
- subdefs = {}
- self._template._interpret_codes(self._body, ns, out, subdefs)
- return ''.join(out)
-
- def __get__(self, obj, type=None):
- if obj is None:
- return self
- return self.__class__(
- self._template, self._func_name, self._func_signature,
- self._body, self._ns, self._pos, bound_self=obj)
-
- def _parse_signature(self, args, kw):
- values = {}
- sig_args, var_args, var_kw, defaults = self._func_signature
- extra_kw = {}
- for name, value in kw.iteritems():
- if not var_kw and name not in sig_args:
- raise TypeError(
- 'Unexpected argument %s' % name)
- if name in sig_args:
- values[sig_args] = value
- else:
- extra_kw[name] = value
- args = list(args)
- sig_args = list(sig_args)
- while args:
- while sig_args and sig_args[0] in values:
- sig_args.pop(0)
- if sig_args:
- name = sig_args.pop(0)
- values[name] = args.pop(0)
- elif var_args:
- values[var_args] = tuple(args)
- break
- else:
- raise TypeError(
- 'Extra position arguments: %s'
- % ', '.join(repr(v) for v in args))
- for name, value_expr in defaults.iteritems():
- if name not in values:
- values[name] = self._template._eval(
- value_expr, self._ns, self._pos)
- for name in sig_args:
- if name not in values:
- raise TypeError(
- 'Missing argument: %s' % name)
- if var_kw:
- values[var_kw] = extra_kw
- return values
-
-
-class TemplateObject(object):
-
- def __init__(self, name):
- self.__name = name
- self.get = TemplateObjectGetter(self)
-
- def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, self.__name)
-
-
-class TemplateObjectGetter(object):
-
- def __init__(self, template_obj):
- self.__template_obj = template_obj
-
- def __getattr__(self, attr):
- return getattr(self.__template_obj, attr, Empty)
-
- def __repr__(self):
- return '<%s around %r>' % (self.__class__.__name__, self.__template_obj)
-
-
-class _Empty(object):
- def __call__(self, *args, **kw):
- return self
-
- def __str__(self):
- return ''
-
- def __repr__(self):
- return 'Empty'
-
- def __unicode__(self):
- return u''
-
- def __iter__(self):
- return iter(())
-
- def __bool__(self):
- return False
-
- if sys.version < "3":
- __nonzero__ = __bool__
-
-Empty = _Empty()
-del _Empty
-
-############################################################
-## Lexing and Parsing
-############################################################
-
-
-def lex(s, name=None, trim_whitespace=True, line_offset=0, delimeters=None):
- """
- Lex a string into chunks:
-
- >>> lex('hey')
- ['hey']
- >>> lex('hey {{you}}')
- ['hey ', ('you', (1, 7))]
- >>> lex('hey {{')
- Traceback (most recent call last):
- ...
- TemplateError: No }} to finish last expression at line 1 column 7
- >>> lex('hey }}')
- Traceback (most recent call last):
- ...
- TemplateError: }} outside expression at line 1 column 7
- >>> lex('hey {{ {{')
- Traceback (most recent call last):
- ...
- TemplateError: {{ inside expression at line 1 column 10
-
- """
- if delimeters is None:
- delimeters = ( Template.default_namespace['start_braces'],
- Template.default_namespace['end_braces'] )
- in_expr = False
- chunks = []
- last = 0
- last_pos = (1, 1)
- token_re = re.compile(r'%s|%s' % (re.escape(delimeters[0]),
- re.escape(delimeters[1])))
- for match in token_re.finditer(s):
- expr = match.group(0)
- pos = find_position(s, match.end(), line_offset)
- if expr == delimeters[0] and in_expr:
- raise TemplateError('%s inside expression' % delimeters[0],
- position=pos,
- name=name)
- elif expr == delimeters[1] and not in_expr:
- raise TemplateError('%s outside expression' % delimeters[1],
- position=pos,
- name=name)
- if expr == delimeters[0]:
- part = s[last:match.start()]
- if part:
- chunks.append(part)
- in_expr = True
- else:
- chunks.append((s[last:match.start()], last_pos))
- in_expr = False
- last = match.end()
- last_pos = pos
- if in_expr:
- raise TemplateError('No %s to finish last expression' % delimeters[1],
- name=name, position=last_pos)
- part = s[last:]
- if part:
- chunks.append(part)
- if trim_whitespace:
- chunks = trim_lex(chunks)
- return chunks
-
-statement_re = re.compile(r'^(?:if |elif |for |def |inherit |default |py:)')
-single_statements = ['else', 'endif', 'endfor', 'enddef', 'continue', 'break']
-trail_whitespace_re = re.compile(r'\n\r?[\t ]*$')
-lead_whitespace_re = re.compile(r'^[\t ]*\n')
-
-
-def trim_lex(tokens):
- r"""
- Takes a lexed set of tokens, and removes whitespace when there is
- a directive on a line by itself:
-
- >>> tokens = lex('{{if x}}\nx\n{{endif}}\ny', trim_whitespace=False)
- >>> tokens
- [('if x', (1, 3)), '\nx\n', ('endif', (3, 3)), '\ny']
- >>> trim_lex(tokens)
- [('if x', (1, 3)), 'x\n', ('endif', (3, 3)), 'y']
- """
- last_trim = None
- for i in range(len(tokens)):
- current = tokens[i]
- if isinstance(tokens[i], basestring_):
- # we don't trim this
- continue
- item = current[0]
- if not statement_re.search(item) and item not in single_statements:
- continue
- if not i:
- prev = ''
- else:
- prev = tokens[i - 1]
- if i + 1 >= len(tokens):
- next_chunk = ''
- else:
- next_chunk = tokens[i + 1]
- if (not isinstance(next_chunk, basestring_)
- or not isinstance(prev, basestring_)):
- continue
- prev_ok = not prev or trail_whitespace_re.search(prev)
- if i == 1 and not prev.strip():
- prev_ok = True
- if last_trim is not None and last_trim + 2 == i and not prev.strip():
- prev_ok = 'last'
- if (prev_ok
- and (not next_chunk or lead_whitespace_re.search(next_chunk)
- or (i == len(tokens) - 2 and not next_chunk.strip()))):
- if prev:
- if ((i == 1 and not prev.strip())
- or prev_ok == 'last'):
- tokens[i - 1] = ''
- else:
- m = trail_whitespace_re.search(prev)
- # +1 to leave the leading \n on:
- prev = prev[:m.start() + 1]
- tokens[i - 1] = prev
- if next_chunk:
- last_trim = i
- if i == len(tokens) - 2 and not next_chunk.strip():
- tokens[i + 1] = ''
- else:
- m = lead_whitespace_re.search(next_chunk)
- next_chunk = next_chunk[m.end():]
- tokens[i + 1] = next_chunk
- return tokens
-
-
-def find_position(string, index, line_offset):
- """Given a string and index, return (line, column)"""
- leading = string[:index].splitlines()
- return (len(leading) + line_offset, len(leading[-1]) + 1)
-
-
-def parse(s, name=None, line_offset=0, delimeters=None):
- r"""
- Parses a string into a kind of AST
-
- >>> parse('{{x}}')
- [('expr', (1, 3), 'x')]
- >>> parse('foo')
- ['foo']
- >>> parse('{{if x}}test{{endif}}')
- [('cond', (1, 3), ('if', (1, 3), 'x', ['test']))]
- >>> parse('series->{{for x in y}}x={{x}}{{endfor}}')
- ['series->', ('for', (1, 11), ('x',), 'y', ['x=', ('expr', (1, 27), 'x')])]
- >>> parse('{{for x, y in z:}}{{continue}}{{endfor}}')
- [('for', (1, 3), ('x', 'y'), 'z', [('continue', (1, 21))])]
- >>> parse('{{py:x=1}}')
- [('py', (1, 3), 'x=1')]
- >>> parse('{{if x}}a{{elif y}}b{{else}}c{{endif}}')
- [('cond', (1, 3), ('if', (1, 3), 'x', ['a']), ('elif', (1, 12), 'y', ['b']), ('else', (1, 23), None, ['c']))]
-
- Some exceptions::
-
- >>> parse('{{continue}}')
- Traceback (most recent call last):
- ...
- TemplateError: continue outside of for loop at line 1 column 3
- >>> parse('{{if x}}foo')
- Traceback (most recent call last):
- ...
- TemplateError: No {{endif}} at line 1 column 3
- >>> parse('{{else}}')
- Traceback (most recent call last):
- ...
- TemplateError: else outside of an if block at line 1 column 3
- >>> parse('{{if x}}{{for x in y}}{{endif}}{{endfor}}')
- Traceback (most recent call last):
- ...
- TemplateError: Unexpected endif at line 1 column 25
- >>> parse('{{if}}{{endif}}')
- Traceback (most recent call last):
- ...
- TemplateError: if with no expression at line 1 column 3
- >>> parse('{{for x y}}{{endfor}}')
- Traceback (most recent call last):
- ...
- TemplateError: Bad for (no "in") in 'x y' at line 1 column 3
- >>> parse('{{py:x=1\ny=2}}')
- Traceback (most recent call last):
- ...
- TemplateError: Multi-line py blocks must start with a newline at line 1 column 3
- """
- if delimeters is None:
- delimeters = ( Template.default_namespace['start_braces'],
- Template.default_namespace['end_braces'] )
- tokens = lex(s, name=name, line_offset=line_offset, delimeters=delimeters)
- result = []
- while tokens:
- next_chunk, tokens = parse_expr(tokens, name)
- result.append(next_chunk)
- return result
-
-
-def parse_expr(tokens, name, context=()):
- if isinstance(tokens[0], basestring_):
- return tokens[0], tokens[1:]
- expr, pos = tokens[0]
- expr = expr.strip()
- if expr.startswith('py:'):
- expr = expr[3:].lstrip(' \t')
- if expr.startswith('\n') or expr.startswith('\r'):
- expr = expr.lstrip('\r\n')
- if '\r' in expr:
- expr = expr.replace('\r\n', '\n')
- expr = expr.replace('\r', '')
- expr += '\n'
- else:
- if '\n' in expr:
- raise TemplateError(
- 'Multi-line py blocks must start with a newline',
- position=pos, name=name)
- return ('py', pos, expr), tokens[1:]
- elif expr in ('continue', 'break'):
- if 'for' not in context:
- raise TemplateError(
- 'continue outside of for loop',
- position=pos, name=name)
- return (expr, pos), tokens[1:]
- elif expr.startswith('if '):
- return parse_cond(tokens, name, context)
- elif (expr.startswith('elif ')
- or expr == 'else'):
- raise TemplateError(
- '%s outside of an if block' % expr.split()[0],
- position=pos, name=name)
- elif expr in ('if', 'elif', 'for'):
- raise TemplateError(
- '%s with no expression' % expr,
- position=pos, name=name)
- elif expr in ('endif', 'endfor', 'enddef'):
- raise TemplateError(
- 'Unexpected %s' % expr,
- position=pos, name=name)
- elif expr.startswith('for '):
- return parse_for(tokens, name, context)
- elif expr.startswith('default '):
- return parse_default(tokens, name, context)
- elif expr.startswith('inherit '):
- return parse_inherit(tokens, name, context)
- elif expr.startswith('def '):
- return parse_def(tokens, name, context)
- elif expr.startswith('#'):
- return ('comment', pos, tokens[0][0]), tokens[1:]
- return ('expr', pos, tokens[0][0]), tokens[1:]
-
-
-def parse_cond(tokens, name, context):
- start = tokens[0][1]
- pieces = []
- context = context + ('if',)
- while 1:
- if not tokens:
- raise TemplateError(
- 'Missing {{endif}}',
- position=start, name=name)
- if (isinstance(tokens[0], tuple)
- and tokens[0][0] == 'endif'):
- return ('cond', start) + tuple(pieces), tokens[1:]
- next_chunk, tokens = parse_one_cond(tokens, name, context)
- pieces.append(next_chunk)
-
-
-def parse_one_cond(tokens, name, context):
- (first, pos), tokens = tokens[0], tokens[1:]
- content = []
- if first.endswith(':'):
- first = first[:-1]
- if first.startswith('if '):
- part = ('if', pos, first[3:].lstrip(), content)
- elif first.startswith('elif '):
- part = ('elif', pos, first[5:].lstrip(), content)
- elif first == 'else':
- part = ('else', pos, None, content)
- else:
- assert 0, "Unexpected token %r at %s" % (first, pos)
- while 1:
- if not tokens:
- raise TemplateError(
- 'No {{endif}}',
- position=pos, name=name)
- if (isinstance(tokens[0], tuple)
- and (tokens[0][0] == 'endif'
- or tokens[0][0].startswith('elif ')
- or tokens[0][0] == 'else')):
- return part, tokens
- next_chunk, tokens = parse_expr(tokens, name, context)
- content.append(next_chunk)
-
-
-def parse_for(tokens, name, context):
- first, pos = tokens[0]
- tokens = tokens[1:]
- context = ('for',) + context
- content = []
- assert first.startswith('for ')
- if first.endswith(':'):
- first = first[:-1]
- first = first[3:].strip()
- match = in_re.search(first)
- if not match:
- raise TemplateError(
- 'Bad for (no "in") in %r' % first,
- position=pos, name=name)
- vars = first[:match.start()]
- if '(' in vars:
- raise TemplateError(
- 'You cannot have () in the variable section of a for loop (%r)'
- % vars, position=pos, name=name)
- vars = tuple([
- v.strip() for v in first[:match.start()].split(',')
- if v.strip()])
- expr = first[match.end():]
- while 1:
- if not tokens:
- raise TemplateError(
- 'No {{endfor}}',
- position=pos, name=name)
- if (isinstance(tokens[0], tuple)
- and tokens[0][0] == 'endfor'):
- return ('for', pos, vars, expr, content), tokens[1:]
- next_chunk, tokens = parse_expr(tokens, name, context)
- content.append(next_chunk)
-
-
-def parse_default(tokens, name, context):
- first, pos = tokens[0]
- assert first.startswith('default ')
- first = first.split(None, 1)[1]
- parts = first.split('=', 1)
- if len(parts) == 1:
- raise TemplateError(
- "Expression must be {{default var=value}}; no = found in %r" % first,
- position=pos, name=name)
- var = parts[0].strip()
- if ',' in var:
- raise TemplateError(
- "{{default x, y = ...}} is not supported",
- position=pos, name=name)
- if not var_re.search(var):
- raise TemplateError(
- "Not a valid variable name for {{default}}: %r"
- % var, position=pos, name=name)
- expr = parts[1].strip()
- return ('default', pos, var, expr), tokens[1:]
-
-
-def parse_inherit(tokens, name, context):
- first, pos = tokens[0]
- assert first.startswith('inherit ')
- expr = first.split(None, 1)[1]
- return ('inherit', pos, expr), tokens[1:]
-
-
-def parse_def(tokens, name, context):
- first, start = tokens[0]
- tokens = tokens[1:]
- assert first.startswith('def ')
- first = first.split(None, 1)[1]
- if first.endswith(':'):
- first = first[:-1]
- if '(' not in first:
- func_name = first
- sig = ((), None, None, {})
- elif not first.endswith(')'):
- raise TemplateError("Function definition doesn't end with ): %s" % first,
- position=start, name=name)
- else:
- first = first[:-1]
- func_name, sig_text = first.split('(', 1)
- sig = parse_signature(sig_text, name, start)
- context = context + ('def',)
- content = []
- while 1:
- if not tokens:
- raise TemplateError(
- 'Missing {{enddef}}',
- position=start, name=name)
- if (isinstance(tokens[0], tuple)
- and tokens[0][0] == 'enddef'):
- return ('def', start, func_name, sig, content), tokens[1:]
- next_chunk, tokens = parse_expr(tokens, name, context)
- content.append(next_chunk)
-
-
-def parse_signature(sig_text, name, pos):
- tokens = tokenize.generate_tokens(StringIO(sig_text).readline)
- sig_args = []
- var_arg = None
- var_kw = None
- defaults = {}
-
- def get_token(pos=False):
- try:
- tok_type, tok_string, (srow, scol), (erow, ecol), line = next(tokens)
- except StopIteration:
- return tokenize.ENDMARKER, ''
- if pos:
- return tok_type, tok_string, (srow, scol), (erow, ecol)
- else:
- return tok_type, tok_string
- while 1:
- var_arg_type = None
- tok_type, tok_string = get_token()
- if tok_type == tokenize.ENDMARKER:
- break
- if tok_type == tokenize.OP and (tok_string == '*' or tok_string == '**'):
- var_arg_type = tok_string
- tok_type, tok_string = get_token()
- if tok_type != tokenize.NAME:
- raise TemplateError('Invalid signature: (%s)' % sig_text,
- position=pos, name=name)
- var_name = tok_string
- tok_type, tok_string = get_token()
- if tok_type == tokenize.ENDMARKER or (tok_type == tokenize.OP and tok_string == ','):
- if var_arg_type == '*':
- var_arg = var_name
- elif var_arg_type == '**':
- var_kw = var_name
- else:
- sig_args.append(var_name)
- if tok_type == tokenize.ENDMARKER:
- break
- continue
- if var_arg_type is not None:
- raise TemplateError('Invalid signature: (%s)' % sig_text,
- position=pos, name=name)
- if tok_type == tokenize.OP and tok_string == '=':
- nest_type = None
- unnest_type = None
- nest_count = 0
- start_pos = end_pos = None
- parts = []
- while 1:
- tok_type, tok_string, s, e = get_token(True)
- if start_pos is None:
- start_pos = s
- end_pos = e
- if tok_type == tokenize.ENDMARKER and nest_count:
- raise TemplateError('Invalid signature: (%s)' % sig_text,
- position=pos, name=name)
- if (not nest_count and
- (tok_type == tokenize.ENDMARKER or (tok_type == tokenize.OP and tok_string == ','))):
- default_expr = isolate_expression(sig_text, start_pos, end_pos)
- defaults[var_name] = default_expr
- sig_args.append(var_name)
- break
- parts.append((tok_type, tok_string))
- if nest_count and tok_type == tokenize.OP and tok_string == nest_type:
- nest_count += 1
- elif nest_count and tok_type == tokenize.OP and tok_string == unnest_type:
- nest_count -= 1
- if not nest_count:
- nest_type = unnest_type = None
- elif not nest_count and tok_type == tokenize.OP and tok_string in ('(', '[', '{'):
- nest_type = tok_string
- nest_count = 1
- unnest_type = {'(': ')', '[': ']', '{': '}'}[nest_type]
- return sig_args, var_arg, var_kw, defaults
-
-
-def isolate_expression(string, start_pos, end_pos):
- srow, scol = start_pos
- srow -= 1
- erow, ecol = end_pos
- erow -= 1
- lines = string.splitlines(True)
- if srow == erow:
- return lines[srow][scol:ecol]
- parts = [lines[srow][scol:]]
- parts.extend(lines[srow+1:erow])
- if erow < len(lines):
- # It'll sometimes give (end_row_past_finish, 0)
- parts.append(lines[erow][:ecol])
- return ''.join(parts)
-
-_fill_command_usage = """\
-%prog [OPTIONS] TEMPLATE arg=value
-
-Use py:arg=value to set a Python value; otherwise all values are
-strings.
-"""
-
-
-def fill_command(args=None):
- import sys
- import optparse
- import pkg_resources
- import os
- if args is None:
- args = sys.argv[1:]
- dist = pkg_resources.get_distribution('Paste')
- parser = optparse.OptionParser(
- version=coerce_text(dist),
- usage=_fill_command_usage)
- parser.add_option(
- '-o', '--output',
- dest='output',
- metavar="FILENAME",
- help="File to write output to (default stdout)")
- parser.add_option(
- '--html',
- dest='use_html',
- action='store_true',
- help="Use HTML style filling (including automatic HTML quoting)")
- parser.add_option(
- '--env',
- dest='use_env',
- action='store_true',
- help="Put the environment in as top-level variables")
- options, args = parser.parse_args(args)
- if len(args) < 1:
- print('You must give a template filename')
- sys.exit(2)
- template_name = args[0]
- args = args[1:]
- vars = {}
- if options.use_env:
- vars.update(os.environ)
- for value in args:
- if '=' not in value:
- print('Bad argument: %r' % value)
- sys.exit(2)
- name, value = value.split('=', 1)
- if name.startswith('py:'):
- name = name[:3]
- value = eval(value)
- vars[name] = value
- if template_name == '-':
- template_content = sys.stdin.read()
- template_name = '<stdin>'
- else:
- f = open(template_name, 'rb')
- template_content = f.read()
- f.close()
- if options.use_html:
- TemplateClass = HTMLTemplate
- else:
- TemplateClass = Template
- template = TemplateClass(template_content, name=template_name)
- result = template.substitute(vars)
- if options.output:
- f = open(options.output, 'wb')
- f.write(result)
- f.close()
- else:
- sys.stdout.write(result)
-
-if __name__ == '__main__':
- fill_command()
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/_looper.py b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/_looper.py
deleted file mode 100755
index 6784c7cd..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/_looper.py
+++ /dev/null
@@ -1,163 +0,0 @@
-"""
-Helper for looping over sequences, particular in templates.
-
-Often in a loop in a template it's handy to know what's next up,
-previously up, if this is the first or last item in the sequence, etc.
-These can be awkward to manage in a normal Python loop, but using the
-looper you can get a better sense of the context. Use like::
-
- >>> for loop, item in looper(['a', 'b', 'c']):
- ... print loop.number, item
- ... if not loop.last:
- ... print '---'
- 1 a
- ---
- 2 b
- ---
- 3 c
-
-"""
-
-import sys
-from tempita.compat3 import basestring_
-
-__all__ = ['looper']
-
-
-class looper(object):
- """
- Helper for looping (particularly in templates)
-
- Use this like::
-
- for loop, item in looper(seq):
- if loop.first:
- ...
- """
-
- def __init__(self, seq):
- self.seq = seq
-
- def __iter__(self):
- return looper_iter(self.seq)
-
- def __repr__(self):
- return '<%s for %r>' % (
- self.__class__.__name__, self.seq)
-
-
-class looper_iter(object):
-
- def __init__(self, seq):
- self.seq = list(seq)
- self.pos = 0
-
- def __iter__(self):
- return self
-
- def __next__(self):
- if self.pos >= len(self.seq):
- raise StopIteration
- result = loop_pos(self.seq, self.pos), self.seq[self.pos]
- self.pos += 1
- return result
-
- if sys.version < "3":
- next = __next__
-
-
-class loop_pos(object):
-
- def __init__(self, seq, pos):
- self.seq = seq
- self.pos = pos
-
- def __repr__(self):
- return '<loop pos=%r at %r>' % (
- self.seq[self.pos], self.pos)
-
- def index(self):
- return self.pos
- index = property(index)
-
- def number(self):
- return self.pos + 1
- number = property(number)
-
- def item(self):
- return self.seq[self.pos]
- item = property(item)
-
- def __next__(self):
- try:
- return self.seq[self.pos + 1]
- except IndexError:
- return None
- __next__ = property(__next__)
-
- if sys.version < "3":
- next = __next__
-
- def previous(self):
- if self.pos == 0:
- return None
- return self.seq[self.pos - 1]
- previous = property(previous)
-
- def odd(self):
- return not self.pos % 2
- odd = property(odd)
-
- def even(self):
- return self.pos % 2
- even = property(even)
-
- def first(self):
- return self.pos == 0
- first = property(first)
-
- def last(self):
- return self.pos == len(self.seq) - 1
- last = property(last)
-
- def length(self):
- return len(self.seq)
- length = property(length)
-
- def first_group(self, getter=None):
- """
- Returns true if this item is the start of a new group,
- where groups mean that some attribute has changed. The getter
- can be None (the item itself changes), an attribute name like
- ``'.attr'``, a function, or a dict key or list index.
- """
- if self.first:
- return True
- return self._compare_group(self.item, self.previous, getter)
-
- def last_group(self, getter=None):
- """
- Returns true if this item is the end of a new group,
- where groups mean that some attribute has changed. The getter
- can be None (the item itself changes), an attribute name like
- ``'.attr'``, a function, or a dict key or list index.
- """
- if self.last:
- return True
- return self._compare_group(self.item, self.__next__, getter)
-
- def _compare_group(self, item, other, getter):
- if getter is None:
- return item != other
- elif (isinstance(getter, basestring_)
- and getter.startswith('.')):
- getter = getter[1:]
- if getter.endswith('()'):
- getter = getter[:-2]
- return getattr(item, getter)() != getattr(other, getter)()
- else:
- return getattr(item, getter) != getattr(other, getter)
- elif hasattr(getter, '__call__'):
- return getter(item) != getter(other)
- else:
- return item[getter] != other[getter]
diff --git a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/compat3.py b/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/compat3.py
deleted file mode 100755
index 5e18fa01..00000000
--- a/lib/python2.7/site-packages/Tempita-0.5.1-py2.7.egg/tempita/compat3.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import sys
-
-__all__ = ['b', 'basestring_', 'bytes', 'next', 'is_unicode']
-
-if sys.version < "3":
- b = bytes = str
- basestring_ = basestring
-else:
-
- def b(s):
- if isinstance(s, str):
- return s.encode('latin1')
- return bytes(s)
- basestring_ = (bytes, str)
- bytes = bytes
-text = str
-
-if sys.version < "3":
-
- def next(obj):
- return obj.next()
-else:
- next = next
-
-if sys.version < "3":
-
- def is_unicode(obj):
- return isinstance(obj, unicode)
-else:
-
- def is_unicode(obj):
- return isinstance(obj, str)
-
-
-def coerce_text(v):
- if not isinstance(v, basestring_):
- if sys.version < "3":
- attr = '__unicode__'
- else:
- attr = '__str__'
- if hasattr(v, attr):
- return unicode(v)
- else:
- return bytes(v)
- return v
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index ce2d4b8c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,14 +0,0 @@
-Metadata-Version: 1.1
-Name: Twisted
-Version: 12.2.0
-Summary: An asynchronous networking framework written in Python
-Home-page: http://twistedmatrix.com/
-Author: Glyph Lefkowitz
-Author-email: glyph@twistedmatrix.com
-License: MIT
-Description: An extensible framework for Python programming, with special focus
- on event-based network programming and multiprotocol integration.
-
-Platform: UNKNOWN
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 5a81b2ad..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,801 +0,0 @@
-README
-setup.py
-Twisted.egg-info/PKG-INFO
-Twisted.egg-info/SOURCES.txt
-Twisted.egg-info/dependency_links.txt
-Twisted.egg-info/not-zip-safe
-Twisted.egg-info/requires.txt
-Twisted.egg-info/top_level.txt
-bin/manhole
-bin/pyhtmlizer
-bin/tap2deb
-bin/tap2rpm
-bin/tapconvert
-bin/trial
-bin/twistd
-bin/conch/cftp
-bin/conch/ckeygen
-bin/conch/conch
-bin/conch/tkconch
-bin/lore/lore
-bin/mail/mailmail
-twisted/__init__.py
-twisted/_version.py
-twisted/copyright.py
-twisted/plugin.py
-twisted/application/__init__.py
-twisted/application/app.py
-twisted/application/internet.py
-twisted/application/reactors.py
-twisted/application/service.py
-twisted/application/strports.py
-twisted/application/test/__init__.py
-twisted/application/test/test_internet.py
-twisted/conch/__init__.py
-twisted/conch/_version.py
-twisted/conch/avatar.py
-twisted/conch/checkers.py
-twisted/conch/error.py
-twisted/conch/interfaces.py
-twisted/conch/ls.py
-twisted/conch/manhole.py
-twisted/conch/manhole_ssh.py
-twisted/conch/manhole_tap.py
-twisted/conch/mixin.py
-twisted/conch/recvline.py
-twisted/conch/stdio.py
-twisted/conch/tap.py
-twisted/conch/telnet.py
-twisted/conch/ttymodes.py
-twisted/conch/unix.py
-twisted/conch/client/__init__.py
-twisted/conch/client/agent.py
-twisted/conch/client/connect.py
-twisted/conch/client/default.py
-twisted/conch/client/direct.py
-twisted/conch/client/knownhosts.py
-twisted/conch/client/options.py
-twisted/conch/insults/__init__.py
-twisted/conch/insults/client.py
-twisted/conch/insults/colors.py
-twisted/conch/insults/helper.py
-twisted/conch/insults/insults.py
-twisted/conch/insults/text.py
-twisted/conch/insults/window.py
-twisted/conch/openssh_compat/__init__.py
-twisted/conch/openssh_compat/factory.py
-twisted/conch/openssh_compat/primes.py
-twisted/conch/scripts/__init__.py
-twisted/conch/scripts/cftp.py
-twisted/conch/scripts/ckeygen.py
-twisted/conch/scripts/conch.py
-twisted/conch/scripts/tkconch.py
-twisted/conch/ssh/__init__.py
-twisted/conch/ssh/address.py
-twisted/conch/ssh/agent.py
-twisted/conch/ssh/channel.py
-twisted/conch/ssh/common.py
-twisted/conch/ssh/connection.py
-twisted/conch/ssh/factory.py
-twisted/conch/ssh/filetransfer.py
-twisted/conch/ssh/forwarding.py
-twisted/conch/ssh/keys.py
-twisted/conch/ssh/service.py
-twisted/conch/ssh/session.py
-twisted/conch/ssh/sexpy.py
-twisted/conch/ssh/transport.py
-twisted/conch/ssh/userauth.py
-twisted/conch/test/__init__.py
-twisted/conch/test/keydata.py
-twisted/conch/test/test_address.py
-twisted/conch/test/test_agent.py
-twisted/conch/test/test_cftp.py
-twisted/conch/test/test_channel.py
-twisted/conch/test/test_checkers.py
-twisted/conch/test/test_ckeygen.py
-twisted/conch/test/test_conch.py
-twisted/conch/test/test_connection.py
-twisted/conch/test/test_default.py
-twisted/conch/test/test_filetransfer.py
-twisted/conch/test/test_helper.py
-twisted/conch/test/test_insults.py
-twisted/conch/test/test_keys.py
-twisted/conch/test/test_knownhosts.py
-twisted/conch/test/test_manhole.py
-twisted/conch/test/test_mixin.py
-twisted/conch/test/test_openssh_compat.py
-twisted/conch/test/test_recvline.py
-twisted/conch/test/test_scripts.py
-twisted/conch/test/test_session.py
-twisted/conch/test/test_ssh.py
-twisted/conch/test/test_tap.py
-twisted/conch/test/test_telnet.py
-twisted/conch/test/test_text.py
-twisted/conch/test/test_transport.py
-twisted/conch/test/test_userauth.py
-twisted/conch/test/test_window.py
-twisted/conch/ui/__init__.py
-twisted/conch/ui/ansi.py
-twisted/conch/ui/tkvt100.py
-twisted/cred/__init__.py
-twisted/cred/_digest.py
-twisted/cred/checkers.py
-twisted/cred/credentials.py
-twisted/cred/error.py
-twisted/cred/pamauth.py
-twisted/cred/portal.py
-twisted/cred/strcred.py
-twisted/enterprise/__init__.py
-twisted/enterprise/adbapi.py
-twisted/internet/__init__.py
-twisted/internet/_baseprocess.py
-twisted/internet/_dumbwin32proc.py
-twisted/internet/_glibbase.py
-twisted/internet/_newtls.py
-twisted/internet/_oldtls.py
-twisted/internet/_pollingfile.py
-twisted/internet/_posixserialport.py
-twisted/internet/_posixstdio.py
-twisted/internet/_sigchld.c
-twisted/internet/_signals.py
-twisted/internet/_ssl.py
-twisted/internet/_sslverify.py
-twisted/internet/_threadedselect.py
-twisted/internet/_win32serialport.py
-twisted/internet/_win32stdio.py
-twisted/internet/abstract.py
-twisted/internet/address.py
-twisted/internet/base.py
-twisted/internet/cfreactor.py
-twisted/internet/default.py
-twisted/internet/defer.py
-twisted/internet/endpoints.py
-twisted/internet/epollreactor.py
-twisted/internet/error.py
-twisted/internet/fdesc.py
-twisted/internet/gireactor.py
-twisted/internet/glib2reactor.py
-twisted/internet/gtk2reactor.py
-twisted/internet/gtk3reactor.py
-twisted/internet/gtkreactor.py
-twisted/internet/inotify.py
-twisted/internet/interfaces.py
-twisted/internet/kqreactor.py
-twisted/internet/main.py
-twisted/internet/pollreactor.py
-twisted/internet/posixbase.py
-twisted/internet/process.py
-twisted/internet/protocol.py
-twisted/internet/pyuisupport.py
-twisted/internet/qtreactor.py
-twisted/internet/reactor.py
-twisted/internet/selectreactor.py
-twisted/internet/serialport.py
-twisted/internet/ssl.py
-twisted/internet/stdio.py
-twisted/internet/task.py
-twisted/internet/tcp.py
-twisted/internet/threads.py
-twisted/internet/tksupport.py
-twisted/internet/udp.py
-twisted/internet/unix.py
-twisted/internet/utils.py
-twisted/internet/win32eventreactor.py
-twisted/internet/wxreactor.py
-twisted/internet/wxsupport.py
-twisted/internet/iocpreactor/__init__.py
-twisted/internet/iocpreactor/abstract.py
-twisted/internet/iocpreactor/const.py
-twisted/internet/iocpreactor/interfaces.py
-twisted/internet/iocpreactor/reactor.py
-twisted/internet/iocpreactor/setup.py
-twisted/internet/iocpreactor/tcp.py
-twisted/internet/iocpreactor/udp.py
-twisted/internet/iocpreactor/iocpsupport/iocpsupport.c
-twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c
-twisted/internet/test/__init__.py
-twisted/internet/test/_posixifaces.py
-twisted/internet/test/_win32ifaces.py
-twisted/internet/test/connectionmixins.py
-twisted/internet/test/fakeendpoint.py
-twisted/internet/test/inlinecb_tests.py
-twisted/internet/test/process_helper.py
-twisted/internet/test/reactormixins.py
-twisted/internet/test/test_abstract.py
-twisted/internet/test/test_address.py
-twisted/internet/test/test_base.py
-twisted/internet/test/test_baseprocess.py
-twisted/internet/test/test_core.py
-twisted/internet/test/test_default.py
-twisted/internet/test/test_endpoints.py
-twisted/internet/test/test_epollreactor.py
-twisted/internet/test/test_fdset.py
-twisted/internet/test/test_filedescriptor.py
-twisted/internet/test/test_glibbase.py
-twisted/internet/test/test_gtk3reactor.py
-twisted/internet/test/test_gtkreactor.py
-twisted/internet/test/test_inlinecb.py
-twisted/internet/test/test_inotify.py
-twisted/internet/test/test_interfaces.py
-twisted/internet/test/test_iocp.py
-twisted/internet/test/test_main.py
-twisted/internet/test/test_newtls.py
-twisted/internet/test/test_pollingfile.py
-twisted/internet/test/test_posixbase.py
-twisted/internet/test/test_posixprocess.py
-twisted/internet/test/test_process.py
-twisted/internet/test/test_protocol.py
-twisted/internet/test/test_qtreactor.py
-twisted/internet/test/test_serialport.py
-twisted/internet/test/test_sigchld.py
-twisted/internet/test/test_socket.py
-twisted/internet/test/test_stdio.py
-twisted/internet/test/test_tcp.py
-twisted/internet/test/test_threads.py
-twisted/internet/test/test_time.py
-twisted/internet/test/test_tls.py
-twisted/internet/test/test_udp.py
-twisted/internet/test/test_udp_internals.py
-twisted/internet/test/test_unix.py
-twisted/internet/test/test_win32events.py
-twisted/lore/__init__.py
-twisted/lore/_version.py
-twisted/lore/default.py
-twisted/lore/docbook.py
-twisted/lore/htmlbook.py
-twisted/lore/indexer.py
-twisted/lore/latex.py
-twisted/lore/lint.py
-twisted/lore/lmath.py
-twisted/lore/man2lore.py
-twisted/lore/numberer.py
-twisted/lore/process.py
-twisted/lore/slides.py
-twisted/lore/texi.py
-twisted/lore/tree.py
-twisted/lore/scripts/__init__.py
-twisted/lore/scripts/lore.py
-twisted/lore/test/__init__.py
-twisted/lore/test/test_docbook.py
-twisted/lore/test/test_latex.py
-twisted/lore/test/test_lint.py
-twisted/lore/test/test_lmath.py
-twisted/lore/test/test_lore.py
-twisted/lore/test/test_man2lore.py
-twisted/lore/test/test_scripts.py
-twisted/lore/test/test_slides.py
-twisted/mail/__init__.py
-twisted/mail/_version.py
-twisted/mail/alias.py
-twisted/mail/bounce.py
-twisted/mail/imap4.py
-twisted/mail/mail.py
-twisted/mail/maildir.py
-twisted/mail/pb.py
-twisted/mail/pop3.py
-twisted/mail/pop3client.py
-twisted/mail/protocols.py
-twisted/mail/relay.py
-twisted/mail/relaymanager.py
-twisted/mail/smtp.py
-twisted/mail/tap.py
-twisted/mail/scripts/__init__.py
-twisted/mail/scripts/mailmail.py
-twisted/mail/test/__init__.py
-twisted/mail/test/pop3testserver.py
-twisted/mail/test/test_bounce.py
-twisted/mail/test/test_imap.py
-twisted/mail/test/test_mail.py
-twisted/mail/test/test_mailmail.py
-twisted/mail/test/test_options.py
-twisted/mail/test/test_pop3.py
-twisted/mail/test/test_pop3client.py
-twisted/mail/test/test_scripts.py
-twisted/mail/test/test_smtp.py
-twisted/manhole/__init__.py
-twisted/manhole/_inspectro.py
-twisted/manhole/explorer.py
-twisted/manhole/gladereactor.py
-twisted/manhole/service.py
-twisted/manhole/telnet.py
-twisted/manhole/test/__init__.py
-twisted/manhole/test/test_explorer.py
-twisted/manhole/ui/__init__.py
-twisted/manhole/ui/gtk2manhole.py
-twisted/manhole/ui/test/__init__.py
-twisted/manhole/ui/test/test_gtk2manhole.py
-twisted/names/__init__.py
-twisted/names/_version.py
-twisted/names/authority.py
-twisted/names/cache.py
-twisted/names/client.py
-twisted/names/common.py
-twisted/names/dns.py
-twisted/names/error.py
-twisted/names/hosts.py
-twisted/names/resolve.py
-twisted/names/root.py
-twisted/names/secondary.py
-twisted/names/server.py
-twisted/names/srvconnect.py
-twisted/names/tap.py
-twisted/names/test/__init__.py
-twisted/names/test/test_cache.py
-twisted/names/test/test_client.py
-twisted/names/test/test_common.py
-twisted/names/test/test_dns.py
-twisted/names/test/test_hosts.py
-twisted/names/test/test_names.py
-twisted/names/test/test_rootresolve.py
-twisted/names/test/test_srvconnect.py
-twisted/names/test/test_tap.py
-twisted/news/__init__.py
-twisted/news/_version.py
-twisted/news/database.py
-twisted/news/news.py
-twisted/news/nntp.py
-twisted/news/tap.py
-twisted/news/test/__init__.py
-twisted/news/test/test_database.py
-twisted/news/test/test_news.py
-twisted/news/test/test_nntp.py
-twisted/pair/__init__.py
-twisted/pair/_version.py
-twisted/pair/ethernet.py
-twisted/pair/ip.py
-twisted/pair/raw.py
-twisted/pair/rawudp.py
-twisted/pair/tuntap.py
-twisted/pair/test/__init__.py
-twisted/pair/test/test_ethernet.py
-twisted/pair/test/test_ip.py
-twisted/pair/test/test_rawudp.py
-twisted/persisted/__init__.py
-twisted/persisted/aot.py
-twisted/persisted/crefutil.py
-twisted/persisted/dirdbm.py
-twisted/persisted/sob.py
-twisted/persisted/styles.py
-twisted/persisted/test/__init__.py
-twisted/persisted/test/test_styles.py
-twisted/plugins/__init__.py
-twisted/plugins/cred_anonymous.py
-twisted/plugins/cred_file.py
-twisted/plugins/cred_memory.py
-twisted/plugins/cred_sshkeys.py
-twisted/plugins/cred_unix.py
-twisted/plugins/twisted_conch.py
-twisted/plugins/twisted_core.py
-twisted/plugins/twisted_ftp.py
-twisted/plugins/twisted_inet.py
-twisted/plugins/twisted_lore.py
-twisted/plugins/twisted_mail.py
-twisted/plugins/twisted_manhole.py
-twisted/plugins/twisted_names.py
-twisted/plugins/twisted_news.py
-twisted/plugins/twisted_portforward.py
-twisted/plugins/twisted_qtstub.py
-twisted/plugins/twisted_reactors.py
-twisted/plugins/twisted_runner.py
-twisted/plugins/twisted_socks.py
-twisted/plugins/twisted_telnet.py
-twisted/plugins/twisted_trial.py
-twisted/plugins/twisted_web.py
-twisted/plugins/twisted_words.py
-twisted/protocols/__init__.py
-twisted/protocols/amp.py
-twisted/protocols/basic.py
-twisted/protocols/dict.py
-twisted/protocols/finger.py
-twisted/protocols/ftp.py
-twisted/protocols/htb.py
-twisted/protocols/ident.py
-twisted/protocols/loopback.py
-twisted/protocols/memcache.py
-twisted/protocols/pcp.py
-twisted/protocols/policies.py
-twisted/protocols/portforward.py
-twisted/protocols/postfix.py
-twisted/protocols/shoutcast.py
-twisted/protocols/sip.py
-twisted/protocols/socks.py
-twisted/protocols/stateful.py
-twisted/protocols/telnet.py
-twisted/protocols/tls.py
-twisted/protocols/wire.py
-twisted/protocols/gps/__init__.py
-twisted/protocols/gps/nmea.py
-twisted/protocols/gps/rockwell.py
-twisted/protocols/mice/__init__.py
-twisted/protocols/mice/mouseman.py
-twisted/protocols/test/__init__.py
-twisted/protocols/test/test_tls.py
-twisted/python/__init__.py
-twisted/python/_epoll.c
-twisted/python/_initgroups.c
-twisted/python/_inotify.py
-twisted/python/_release.py
-twisted/python/_shellcomp.py
-twisted/python/compat.py
-twisted/python/components.py
-twisted/python/constants.py
-twisted/python/context.py
-twisted/python/deprecate.py
-twisted/python/dist.py
-twisted/python/failure.py
-twisted/python/fakepwd.py
-twisted/python/filepath.py
-twisted/python/finalize.py
-twisted/python/formmethod.py
-twisted/python/hashlib.py
-twisted/python/hook.py
-twisted/python/htmlizer.py
-twisted/python/lockfile.py
-twisted/python/log.py
-twisted/python/logfile.py
-twisted/python/modules.py
-twisted/python/monkey.py
-twisted/python/procutils.py
-twisted/python/randbytes.py
-twisted/python/rebuild.py
-twisted/python/reflect.py
-twisted/python/release.py
-twisted/python/roots.py
-twisted/python/runtime.py
-twisted/python/sendmsg.c
-twisted/python/shortcut.py
-twisted/python/syslog.py
-twisted/python/systemd.py
-twisted/python/text.py
-twisted/python/threadable.py
-twisted/python/threadpool.py
-twisted/python/urlpath.py
-twisted/python/usage.py
-twisted/python/util.py
-twisted/python/versions.py
-twisted/python/win32.py
-twisted/python/zippath.py
-twisted/python/zipstream.py
-twisted/python/zshcomp.py
-twisted/python/test/__init__.py
-twisted/python/test/deprecatedattributes.py
-twisted/python/test/modules_helpers.py
-twisted/python/test/pullpipe.py
-twisted/python/test/test_components.py
-twisted/python/test/test_constants.py
-twisted/python/test/test_deprecate.py
-twisted/python/test/test_dist.py
-twisted/python/test/test_fakepwd.py
-twisted/python/test/test_hashlib.py
-twisted/python/test/test_htmlizer.py
-twisted/python/test/test_inotify.py
-twisted/python/test/test_release.py
-twisted/python/test/test_runtime.py
-twisted/python/test/test_sendmsg.py
-twisted/python/test/test_shellcomp.py
-twisted/python/test/test_syslog.py
-twisted/python/test/test_systemd.py
-twisted/python/test/test_util.py
-twisted/python/test/test_versions.py
-twisted/python/test/test_win32.py
-twisted/python/test/test_zipstream.py
-twisted/python/test/test_zshcomp.py
-twisted/runner/__init__.py
-twisted/runner/_version.py
-twisted/runner/inetd.py
-twisted/runner/inetdconf.py
-twisted/runner/inetdtap.py
-twisted/runner/portmap.c
-twisted/runner/procmon.py
-twisted/runner/procmontap.py
-twisted/runner/test/__init__.py
-twisted/runner/test/test_procmon.py
-twisted/runner/test/test_procmontap.py
-twisted/scripts/__init__.py
-twisted/scripts/_twistd_unix.py
-twisted/scripts/_twistw.py
-twisted/scripts/htmlizer.py
-twisted/scripts/manhole.py
-twisted/scripts/tap2deb.py
-twisted/scripts/tap2rpm.py
-twisted/scripts/tapconvert.py
-twisted/scripts/tkunzip.py
-twisted/scripts/trial.py
-twisted/scripts/twistd.py
-twisted/scripts/test/__init__.py
-twisted/scripts/test/test_scripts.py
-twisted/scripts/test/test_tap2rpm.py
-twisted/spread/__init__.py
-twisted/spread/banana.py
-twisted/spread/flavors.py
-twisted/spread/interfaces.py
-twisted/spread/jelly.py
-twisted/spread/pb.py
-twisted/spread/publish.py
-twisted/spread/util.py
-twisted/spread/ui/__init__.py
-twisted/spread/ui/gtk2util.py
-twisted/spread/ui/tktree.py
-twisted/spread/ui/tkutil.py
-twisted/tap/__init__.py
-twisted/tap/ftp.py
-twisted/tap/manhole.py
-twisted/tap/portforward.py
-twisted/tap/socks.py
-twisted/tap/telnet.py
-twisted/test/__init__.py
-twisted/test/_preamble.py
-twisted/test/crash_test_dummy.py
-twisted/test/generator_failure_tests.py
-twisted/test/iosim.py
-twisted/test/mock_win32process.py
-twisted/test/myrebuilder1.py
-twisted/test/myrebuilder2.py
-twisted/test/plugin_basic.py
-twisted/test/plugin_extra1.py
-twisted/test/plugin_extra2.py
-twisted/test/process_cmdline.py
-twisted/test/process_echoer.py
-twisted/test/process_fds.py
-twisted/test/process_linger.py
-twisted/test/process_reader.py
-twisted/test/process_signal.py
-twisted/test/process_stdinreader.py
-twisted/test/process_tester.py
-twisted/test/process_tty.py
-twisted/test/process_twisted.py
-twisted/test/proto_helpers.py
-twisted/test/raiser.c
-twisted/test/reflect_helper_IE.py
-twisted/test/reflect_helper_VE.py
-twisted/test/reflect_helper_ZDE.py
-twisted/test/ssl_helpers.py
-twisted/test/stdio_test_consumer.py
-twisted/test/stdio_test_halfclose.py
-twisted/test/stdio_test_hostpeer.py
-twisted/test/stdio_test_lastwrite.py
-twisted/test/stdio_test_loseconn.py
-twisted/test/stdio_test_producer.py
-twisted/test/stdio_test_write.py
-twisted/test/stdio_test_writeseq.py
-twisted/test/test_abstract.py
-twisted/test/test_adbapi.py
-twisted/test/test_amp.py
-twisted/test/test_application.py
-twisted/test/test_banana.py
-twisted/test/test_compat.py
-twisted/test/test_context.py
-twisted/test/test_cooperator.py
-twisted/test/test_defer.py
-twisted/test/test_defgen.py
-twisted/test/test_dict.py
-twisted/test/test_digestauth.py
-twisted/test/test_dirdbm.py
-twisted/test/test_doc.py
-twisted/test/test_epoll.py
-twisted/test/test_error.py
-twisted/test/test_explorer.py
-twisted/test/test_factories.py
-twisted/test/test_failure.py
-twisted/test/test_fdesc.py
-twisted/test/test_finger.py
-twisted/test/test_formmethod.py
-twisted/test/test_ftp.py
-twisted/test/test_ftp_options.py
-twisted/test/test_hook.py
-twisted/test/test_htb.py
-twisted/test/test_ident.py
-twisted/test/test_import.py
-twisted/test/test_internet.py
-twisted/test/test_iutils.py
-twisted/test/test_jelly.py
-twisted/test/test_lockfile.py
-twisted/test/test_log.py
-twisted/test/test_logfile.py
-twisted/test/test_loopback.py
-twisted/test/test_manhole.py
-twisted/test/test_memcache.py
-twisted/test/test_modules.py
-twisted/test/test_monkey.py
-twisted/test/test_newcred.py
-twisted/test/test_nmea.py
-twisted/test/test_paths.py
-twisted/test/test_pb.py
-twisted/test/test_pbfailure.py
-twisted/test/test_pcp.py
-twisted/test/test_persisted.py
-twisted/test/test_plugin.py
-twisted/test/test_policies.py
-twisted/test/test_postfix.py
-twisted/test/test_process.py
-twisted/test/test_protocols.py
-twisted/test/test_randbytes.py
-twisted/test/test_rebuild.py
-twisted/test/test_reflect.py
-twisted/test/test_roots.py
-twisted/test/test_shortcut.py
-twisted/test/test_sip.py
-twisted/test/test_sob.py
-twisted/test/test_socks.py
-twisted/test/test_ssl.py
-twisted/test/test_sslverify.py
-twisted/test/test_stateful.py
-twisted/test/test_stdio.py
-twisted/test/test_strcred.py
-twisted/test/test_strerror.py
-twisted/test/test_stringtransport.py
-twisted/test/test_strports.py
-twisted/test/test_task.py
-twisted/test/test_tcp.py
-twisted/test/test_tcp_internals.py
-twisted/test/test_text.py
-twisted/test/test_threadable.py
-twisted/test/test_threadpool.py
-twisted/test/test_threads.py
-twisted/test/test_tpfile.py
-twisted/test/test_twistd.py
-twisted/test/test_udp.py
-twisted/test/test_unix.py
-twisted/test/test_usage.py
-twisted/test/testutils.py
-twisted/trial/__init__.py
-twisted/trial/itrial.py
-twisted/trial/reporter.py
-twisted/trial/runner.py
-twisted/trial/unittest.py
-twisted/trial/util.py
-twisted/trial/test/__init__.py
-twisted/trial/test/detests.py
-twisted/trial/test/erroneous.py
-twisted/trial/test/mockcustomsuite.py
-twisted/trial/test/mockcustomsuite2.py
-twisted/trial/test/mockcustomsuite3.py
-twisted/trial/test/mockdoctest.py
-twisted/trial/test/moduleself.py
-twisted/trial/test/moduletest.py
-twisted/trial/test/novars.py
-twisted/trial/test/packages.py
-twisted/trial/test/sample.py
-twisted/trial/test/scripttest.py
-twisted/trial/test/skipping.py
-twisted/trial/test/suppression.py
-twisted/trial/test/test_assertions.py
-twisted/trial/test/test_deferred.py
-twisted/trial/test/test_doctest.py
-twisted/trial/test/test_keyboard.py
-twisted/trial/test/test_loader.py
-twisted/trial/test/test_log.py
-twisted/trial/test/test_output.py
-twisted/trial/test/test_plugins.py
-twisted/trial/test/test_pyunitcompat.py
-twisted/trial/test/test_reporter.py
-twisted/trial/test/test_runner.py
-twisted/trial/test/test_script.py
-twisted/trial/test/test_test_visitor.py
-twisted/trial/test/test_testcase.py
-twisted/trial/test/test_tests.py
-twisted/trial/test/test_util.py
-twisted/trial/test/test_warning.py
-twisted/trial/test/weird.py
-twisted/web/__init__.py
-twisted/web/_element.py
-twisted/web/_flatten.py
-twisted/web/_newclient.py
-twisted/web/_stan.py
-twisted/web/_version.py
-twisted/web/client.py
-twisted/web/demo.py
-twisted/web/distrib.py
-twisted/web/domhelpers.py
-twisted/web/error.py
-twisted/web/guard.py
-twisted/web/html.py
-twisted/web/http.py
-twisted/web/http_headers.py
-twisted/web/iweb.py
-twisted/web/microdom.py
-twisted/web/proxy.py
-twisted/web/resource.py
-twisted/web/rewrite.py
-twisted/web/script.py
-twisted/web/server.py
-twisted/web/soap.py
-twisted/web/static.py
-twisted/web/sux.py
-twisted/web/tap.py
-twisted/web/template.py
-twisted/web/twcgi.py
-twisted/web/util.py
-twisted/web/vhost.py
-twisted/web/wsgi.py
-twisted/web/xmlrpc.py
-twisted/web/_auth/__init__.py
-twisted/web/_auth/basic.py
-twisted/web/_auth/digest.py
-twisted/web/_auth/wrapper.py
-twisted/web/test/__init__.py
-twisted/web/test/_util.py
-twisted/web/test/test_cgi.py
-twisted/web/test/test_distrib.py
-twisted/web/test/test_domhelpers.py
-twisted/web/test/test_error.py
-twisted/web/test/test_flatten.py
-twisted/web/test/test_http.py
-twisted/web/test/test_http_headers.py
-twisted/web/test/test_httpauth.py
-twisted/web/test/test_newclient.py
-twisted/web/test/test_proxy.py
-twisted/web/test/test_resource.py
-twisted/web/test/test_script.py
-twisted/web/test/test_soap.py
-twisted/web/test/test_stan.py
-twisted/web/test/test_static.py
-twisted/web/test/test_tap.py
-twisted/web/test/test_template.py
-twisted/web/test/test_util.py
-twisted/web/test/test_vhost.py
-twisted/web/test/test_web.py
-twisted/web/test/test_webclient.py
-twisted/web/test/test_wsgi.py
-twisted/web/test/test_xml.py
-twisted/web/test/test_xmlrpc.py
-twisted/words/__init__.py
-twisted/words/_version.py
-twisted/words/ewords.py
-twisted/words/iwords.py
-twisted/words/service.py
-twisted/words/tap.py
-twisted/words/xmpproutertap.py
-twisted/words/im/__init__.py
-twisted/words/im/baseaccount.py
-twisted/words/im/basechat.py
-twisted/words/im/basesupport.py
-twisted/words/im/interfaces.py
-twisted/words/im/ircsupport.py
-twisted/words/im/locals.py
-twisted/words/im/pbsupport.py
-twisted/words/protocols/__init__.py
-twisted/words/protocols/irc.py
-twisted/words/protocols/msn.py
-twisted/words/protocols/oscar.py
-twisted/words/protocols/jabber/__init__.py
-twisted/words/protocols/jabber/client.py
-twisted/words/protocols/jabber/component.py
-twisted/words/protocols/jabber/error.py
-twisted/words/protocols/jabber/ijabber.py
-twisted/words/protocols/jabber/jid.py
-twisted/words/protocols/jabber/jstrports.py
-twisted/words/protocols/jabber/sasl.py
-twisted/words/protocols/jabber/sasl_mechanisms.py
-twisted/words/protocols/jabber/xmlstream.py
-twisted/words/protocols/jabber/xmpp_stringprep.py
-twisted/words/test/__init__.py
-twisted/words/test/test_basechat.py
-twisted/words/test/test_basesupport.py
-twisted/words/test/test_domish.py
-twisted/words/test/test_irc.py
-twisted/words/test/test_irc_service.py
-twisted/words/test/test_ircsupport.py
-twisted/words/test/test_jabberclient.py
-twisted/words/test/test_jabbercomponent.py
-twisted/words/test/test_jabbererror.py
-twisted/words/test/test_jabberjid.py
-twisted/words/test/test_jabberjstrports.py
-twisted/words/test/test_jabbersasl.py
-twisted/words/test/test_jabbersaslmechanisms.py
-twisted/words/test/test_jabberxmlstream.py
-twisted/words/test/test_jabberxmppstringprep.py
-twisted/words/test/test_msn.py
-twisted/words/test/test_oscar.py
-twisted/words/test/test_service.py
-twisted/words/test/test_tap.py
-twisted/words/test/test_xishutil.py
-twisted/words/test/test_xmlstream.py
-twisted/words/test/test_xmpproutertap.py
-twisted/words/test/test_xpath.py
-twisted/words/xish/__init__.py
-twisted/words/xish/domish.py
-twisted/words/xish/utility.py
-twisted/words/xish/xmlstream.py
-twisted/words/xish/xpath.py
-twisted/words/xish/xpathparser.py \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt
deleted file mode 100644
index 253fa5c4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-twisted/python/_initgroups.so
-twisted/python/sendmsg.so
-twisted/test/raiser.so
-twisted/internet/_sigchld.so
-twisted/runner/portmap.so
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt
deleted file mode 100644
index 2d7386e0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1 +0,0 @@
-zope.interface \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/cftp b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/cftp
deleted file mode 100644
index bd7f3db2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/cftp
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os
-extra = os.path.dirname(os.path.dirname(sys.argv[0]))
-sys.path.insert(0, extra)
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-sys.path.remove(extra)
-
-from twisted.conch.scripts.cftp import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/ckeygen b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/ckeygen
deleted file mode 100644
index bf12fe38..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/ckeygen
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os
-extra = os.path.dirname(os.path.dirname(sys.argv[0]))
-sys.path.insert(0, extra)
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-sys.path.remove(extra)
-
-from twisted.conch.scripts.ckeygen import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/conch b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/conch
deleted file mode 100644
index 304dd295..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/conch
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os
-extra = os.path.dirname(os.path.dirname(sys.argv[0]))
-sys.path.insert(0, extra)
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-sys.path.remove(extra)
-
-from twisted.conch.scripts.conch import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/lore b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/lore
deleted file mode 100644
index 0b497e36..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/lore
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os
-extra = os.path.dirname(os.path.dirname(sys.argv[0]))
-sys.path.insert(0, extra)
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-sys.path.remove(extra)
-
-from twisted.lore.scripts.lore import run
-run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/mailmail b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/mailmail
deleted file mode 100644
index 1fc026d6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/mailmail
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This script attempts to send some email.
-"""
-
-import sys, os
-extra = os.path.dirname(os.path.dirname(sys.argv[0]))
-sys.path.insert(0, extra)
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-sys.path.remove(extra)
-
-from twisted.mail.scripts import mailmail
-mailmail.run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/manhole b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/manhole
deleted file mode 100644
index ff662862..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/manhole
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This script runs GtkManhole, a client for Twisted.Manhole
-"""
-import sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-from twisted.scripts import manhole
-manhole.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/pyhtmlizer b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/pyhtmlizer
deleted file mode 100644
index 430f7889..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/pyhtmlizer
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-import sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-from twisted.scripts.htmlizer import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2deb b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2deb
deleted file mode 100644
index 3f90d25b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2deb
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-tap2deb
-"""
-import sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-from twisted.scripts import tap2deb
-tap2deb.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2rpm b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2rpm
deleted file mode 100644
index 36678585..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tap2rpm
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# based off the tap2deb code
-# tap2rpm built by Sean Reifschneider, <jafo@tummy.com>
-
-"""
-tap2rpm
-"""
-import sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-from twisted.scripts import tap2rpm
-tap2rpm.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tapconvert b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tapconvert
deleted file mode 100644
index fb7fe59f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tapconvert
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-import sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-from twisted.scripts.tapconvert import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tkconch b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tkconch
deleted file mode 100644
index 5b123a7a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tkconch
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os
-extra = os.path.dirname(os.path.dirname(sys.argv[0]))
-sys.path.insert(0, extra)
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-sys.path.remove(extra)
-
-from twisted.conch.scripts.tkconch import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/trial b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/trial
deleted file mode 100644
index 64a38cf4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/trial
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-import os, sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-# begin chdir armor
-sys.path[:] = map(os.path.abspath, sys.path)
-# end chdir armor
-
-sys.path.insert(0, os.path.abspath(os.getcwd()))
-
-from twisted.scripts.trial import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/twistd b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/twistd
deleted file mode 100644
index 8cf908df..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/scripts/twistd
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-import os, sys
-
-try:
- import _preamble
-except ImportError:
- sys.exc_clear()
-
-sys.path.insert(0, os.path.abspath(os.getcwd()))
-
-from twisted.scripts.twistd import run
-run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 3eb29f04..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-twisted
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/__init__.py
deleted file mode 100755
index 81922394..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- test-case-name: twisted -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted: The Framework Of Your Internet.
-"""
-
-# Ensure the user is running the version of python we require.
-import sys
-if not hasattr(sys, "version_info") or sys.version_info < (2, 6):
- raise RuntimeError("Twisted requires Python 2.6 or later.")
-del sys
-
-# Ensure compat gets imported
-from twisted.python import compat
-del compat
-
-# setup version
-from twisted._version import version
-__version__ = version.short()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/_version.py
deleted file mode 100755
index 28268181..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/__init__.py
deleted file mode 100755
index c155ca42..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""
-Configuration objects for Twisted Applications
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py
deleted file mode 100755
index 97f7a42f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py
+++ /dev/null
@@ -1,674 +0,0 @@
-# -*- test-case-name: twisted.test.test_application,twisted.test.test_twistd -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os, pdb, getpass, traceback, signal
-from operator import attrgetter
-
-from twisted.python import runtime, log, usage, failure, util, logfile
-from twisted.python.versions import Version
-from twisted.python.reflect import qual, namedAny
-from twisted.python.deprecate import deprecated
-from twisted.python.log import ILogObserver
-from twisted.persisted import sob
-from twisted.application import service, reactors
-from twisted.internet import defer
-from twisted import copyright, plugin
-
-# Expose the new implementation of installReactor at the old location.
-from twisted.application.reactors import installReactor
-from twisted.application.reactors import NoSuchReactor
-
-
-
-class _BasicProfiler(object):
- """
- @ivar saveStats: if C{True}, save the stats information instead of the
- human readable format
- @type saveStats: C{bool}
-
- @ivar profileOutput: the name of the file use to print profile data.
- @type profileOutput: C{str}
- """
-
- def __init__(self, profileOutput, saveStats):
- self.profileOutput = profileOutput
- self.saveStats = saveStats
-
-
- def _reportImportError(self, module, e):
- """
- Helper method to report an import error with a profile module. This
- has to be explicit because some of these modules are removed by
- distributions due to them being non-free.
- """
- s = "Failed to import module %s: %s" % (module, e)
- s += """
-This is most likely caused by your operating system not including
-the module due to it being non-free. Either do not use the option
---profile, or install the module; your operating system vendor
-may provide it in a separate package.
-"""
- raise SystemExit(s)
-
-
-
-class ProfileRunner(_BasicProfiler):
- """
- Runner for the standard profile module.
- """
-
- def run(self, reactor):
- """
- Run reactor under the standard profiler.
- """
- try:
- import profile
- except ImportError, e:
- self._reportImportError("profile", e)
-
- p = profile.Profile()
- p.runcall(reactor.run)
- if self.saveStats:
- p.dump_stats(self.profileOutput)
- else:
- tmp, sys.stdout = sys.stdout, open(self.profileOutput, 'a')
- try:
- p.print_stats()
- finally:
- sys.stdout, tmp = tmp, sys.stdout
- tmp.close()
-
-
-
-class HotshotRunner(_BasicProfiler):
- """
- Runner for the hotshot profile module.
- """
-
- def run(self, reactor):
- """
- Run reactor under the hotshot profiler.
- """
- try:
- import hotshot.stats
- except (ImportError, SystemExit), e:
- # Certain versions of Debian (and Debian derivatives) raise
- # SystemExit when importing hotshot if the "non-free" profiler
- # module is not installed. Someone eventually recognized this
- # as a bug and changed the Debian packaged Python to raise
- # ImportError instead. Handle both exception types here in
- # order to support the versions of Debian which have this
- # behavior. The bug report which prompted the introduction of
- # this highly undesirable behavior should be available online at
- # <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=334067>.
- # There seems to be no corresponding bug report which resulted
- # in the behavior being removed. -exarkun
- self._reportImportError("hotshot", e)
-
- # this writes stats straight out
- p = hotshot.Profile(self.profileOutput)
- p.runcall(reactor.run)
- if self.saveStats:
- # stats are automatically written to file, nothing to do
- return
- else:
- s = hotshot.stats.load(self.profileOutput)
- s.strip_dirs()
- s.sort_stats(-1)
- if getattr(s, 'stream', None) is not None:
- # Python 2.5 and above supports a stream attribute
- s.stream = open(self.profileOutput, 'w')
- s.print_stats()
- s.stream.close()
- else:
- # But we have to use a trick for Python < 2.5
- tmp, sys.stdout = sys.stdout, open(self.profileOutput, 'w')
- try:
- s.print_stats()
- finally:
- sys.stdout, tmp = tmp, sys.stdout
- tmp.close()
-
-
-
-class CProfileRunner(_BasicProfiler):
- """
- Runner for the cProfile module.
- """
-
- def run(self, reactor):
- """
- Run reactor under the cProfile profiler.
- """
- try:
- import cProfile, pstats
- except ImportError, e:
- self._reportImportError("cProfile", e)
-
- p = cProfile.Profile()
- p.runcall(reactor.run)
- if self.saveStats:
- p.dump_stats(self.profileOutput)
- else:
- stream = open(self.profileOutput, 'w')
- s = pstats.Stats(p, stream=stream)
- s.strip_dirs()
- s.sort_stats(-1)
- s.print_stats()
- stream.close()
-
-
-
-class AppProfiler(object):
- """
- Class which selects a specific profile runner based on configuration
- options.
-
- @ivar profiler: the name of the selected profiler.
- @type profiler: C{str}
- """
- profilers = {"profile": ProfileRunner, "hotshot": HotshotRunner,
- "cprofile": CProfileRunner}
-
- def __init__(self, options):
- saveStats = options.get("savestats", False)
- profileOutput = options.get("profile", None)
- self.profiler = options.get("profiler", "hotshot").lower()
- if self.profiler in self.profilers:
- profiler = self.profilers[self.profiler](profileOutput, saveStats)
- self.run = profiler.run
- else:
- raise SystemExit("Unsupported profiler name: %s" % (self.profiler,))
-
-
-
-class AppLogger(object):
- """
- Class managing logging faciliy of the application.
-
- @ivar _logfilename: The name of the file to which to log, if other than the
- default.
- @type _logfilename: C{str}
-
- @ivar _observerFactory: Callable object that will create a log observer, or
- None.
-
- @ivar _observer: log observer added at C{start} and removed at C{stop}.
- @type _observer: C{callable}
- """
- _observer = None
-
- def __init__(self, options):
- self._logfilename = options.get("logfile", "")
- self._observerFactory = options.get("logger") or None
-
-
- def start(self, application):
- """
- Initialize the logging system.
-
- If a customer logger was specified on the command line it will be
- used. If not, and an L{ILogObserver} component has been set on
- C{application}, then it will be used as the log observer. Otherwise a
- log observer will be created based on the command-line options for
- built-in loggers (e.g. C{--logfile}).
-
- @param application: The application on which to check for an
- L{ILogObserver}.
- """
- if self._observerFactory is not None:
- observer = self._observerFactory()
- else:
- observer = application.getComponent(ILogObserver, None)
-
- if observer is None:
- observer = self._getLogObserver()
- self._observer = observer
- log.startLoggingWithObserver(self._observer)
- self._initialLog()
-
-
- def _initialLog(self):
- """
- Print twistd start log message.
- """
- from twisted.internet import reactor
- log.msg("twistd %s (%s %s) starting up." % (copyright.version,
- sys.executable,
- runtime.shortPythonVersion()))
- log.msg('reactor class: %s.' % (qual(reactor.__class__),))
-
-
- def _getLogObserver(self):
- """
- Create a log observer to be added to the logging system before running
- this application.
- """
- if self._logfilename == '-' or not self._logfilename:
- logFile = sys.stdout
- else:
- logFile = logfile.LogFile.fromFullPath(self._logfilename)
- return log.FileLogObserver(logFile).emit
-
-
- def stop(self):
- """
- Print twistd stop log message.
- """
- log.msg("Server Shut Down.")
- if self._observer is not None:
- log.removeObserver(self._observer)
- self._observer = None
-
-
-
-def fixPdb():
- def do_stop(self, arg):
- self.clear_all_breaks()
- self.set_continue()
- from twisted.internet import reactor
- reactor.callLater(0, reactor.stop)
- return 1
-
-
- def help_stop(self):
- print """stop - Continue execution, then cleanly shutdown the twisted reactor."""
-
-
- def set_quit(self):
- os._exit(0)
-
- pdb.Pdb.set_quit = set_quit
- pdb.Pdb.do_stop = do_stop
- pdb.Pdb.help_stop = help_stop
-
-
-
-def runReactorWithLogging(config, oldstdout, oldstderr, profiler=None, reactor=None):
- """
- Start the reactor, using profiling if specified by the configuration, and
- log any error happening in the process.
-
- @param config: configuration of the twistd application.
- @type config: L{ServerOptions}
-
- @param oldstdout: initial value of C{sys.stdout}.
- @type oldstdout: C{file}
-
- @param oldstderr: initial value of C{sys.stderr}.
- @type oldstderr: C{file}
-
- @param profiler: object used to run the reactor with profiling.
- @type profiler: L{AppProfiler}
-
- @param reactor: The reactor to use. If C{None}, the global reactor will
- be used.
- """
- if reactor is None:
- from twisted.internet import reactor
- try:
- if config['profile']:
- if profiler is not None:
- profiler.run(reactor)
- elif config['debug']:
- sys.stdout = oldstdout
- sys.stderr = oldstderr
- if runtime.platformType == 'posix':
- signal.signal(signal.SIGUSR2, lambda *args: pdb.set_trace())
- signal.signal(signal.SIGINT, lambda *args: pdb.set_trace())
- fixPdb()
- pdb.runcall(reactor.run)
- else:
- reactor.run()
- except:
- if config['nodaemon']:
- file = oldstdout
- else:
- file = open("TWISTD-CRASH.log",'a')
- traceback.print_exc(file=file)
- file.flush()
-
-
-
-def getPassphrase(needed):
- if needed:
- return getpass.getpass('Passphrase: ')
- else:
- return None
-
-
-
-def getSavePassphrase(needed):
- if needed:
- passphrase = util.getPassword("Encryption passphrase: ")
- else:
- return None
-
-
-
-class ApplicationRunner(object):
- """
- An object which helps running an application based on a config object.
-
- Subclass me and implement preApplication and postApplication
- methods. postApplication generally will want to run the reactor
- after starting the application.
-
- @ivar config: The config object, which provides a dict-like interface.
-
- @ivar application: Available in postApplication, but not
- preApplication. This is the application object.
-
- @ivar profilerFactory: Factory for creating a profiler object, able to
- profile the application if options are set accordingly.
-
- @ivar profiler: Instance provided by C{profilerFactory}.
-
- @ivar loggerFactory: Factory for creating object responsible for logging.
-
- @ivar logger: Instance provided by C{loggerFactory}.
- """
- profilerFactory = AppProfiler
- loggerFactory = AppLogger
-
- def __init__(self, config):
- self.config = config
- self.profiler = self.profilerFactory(config)
- self.logger = self.loggerFactory(config)
-
-
- def run(self):
- """
- Run the application.
- """
- self.preApplication()
- self.application = self.createOrGetApplication()
-
- self.logger.start(self.application)
-
- self.postApplication()
- self.logger.stop()
-
-
- def startReactor(self, reactor, oldstdout, oldstderr):
- """
- Run the reactor with the given configuration. Subclasses should
- probably call this from C{postApplication}.
-
- @see: L{runReactorWithLogging}
- """
- runReactorWithLogging(
- self.config, oldstdout, oldstderr, self.profiler, reactor)
-
-
- def preApplication(self):
- """
- Override in subclass.
-
- This should set up any state necessary before loading and
- running the Application.
- """
- raise NotImplementedError()
-
-
- def postApplication(self):
- """
- Override in subclass.
-
- This will be called after the application has been loaded (so
- the C{application} attribute will be set). Generally this
- should start the application and run the reactor.
- """
- raise NotImplementedError()
-
-
- def createOrGetApplication(self):
- """
- Create or load an Application based on the parameters found in the
- given L{ServerOptions} instance.
-
- If a subcommand was used, the L{service.IServiceMaker} that it
- represents will be used to construct a service to be added to
- a newly-created Application.
-
- Otherwise, an application will be loaded based on parameters in
- the config.
- """
- if self.config.subCommand:
- # If a subcommand was given, it's our responsibility to create
- # the application, instead of load it from a file.
-
- # loadedPlugins is set up by the ServerOptions.subCommands
- # property, which is iterated somewhere in the bowels of
- # usage.Options.
- plg = self.config.loadedPlugins[self.config.subCommand]
- ser = plg.makeService(self.config.subOptions)
- application = service.Application(plg.tapname)
- ser.setServiceParent(application)
- else:
- passphrase = getPassphrase(self.config['encrypted'])
- application = getApplication(self.config, passphrase)
- return application
-
-
-
-def getApplication(config, passphrase):
- s = [(config[t], t)
- for t in ['python', 'source', 'file'] if config[t]][0]
- filename, style = s[0], {'file':'pickle'}.get(s[1],s[1])
- try:
- log.msg("Loading %s..." % filename)
- application = service.loadApplication(filename, style, passphrase)
- log.msg("Loaded.")
- except Exception, e:
- s = "Failed to load application: %s" % e
- if isinstance(e, KeyError) and e.args[0] == "application":
- s += """
-Could not find 'application' in the file. To use 'twistd -y', your .tac
-file must create a suitable object (e.g., by calling service.Application())
-and store it in a variable named 'application'. twistd loads your .tac file
-and scans the global variables for one of this name.
-
-Please read the 'Using Application' HOWTO for details.
-"""
- traceback.print_exc(file=log.logfile)
- log.msg(s)
- log.deferr()
- sys.exit('\n' + s + '\n')
- return application
-
-
-
-def _reactorAction():
- return usage.CompleteList([r.shortName for r in reactors.getReactorTypes()])
-
-
-class ReactorSelectionMixin:
- """
- Provides options for selecting a reactor to install.
-
- If a reactor is installed, the short name which was used to locate it is
- saved as the value for the C{"reactor"} key.
- """
- compData = usage.Completions(
- optActions={"reactor": _reactorAction})
-
- messageOutput = sys.stdout
- _getReactorTypes = staticmethod(reactors.getReactorTypes)
-
-
- def opt_help_reactors(self):
- """
- Display a list of possibly available reactor names.
- """
- rcts = sorted(self._getReactorTypes(), key=attrgetter('shortName'))
- for r in rcts:
- self.messageOutput.write(' %-4s\t%s\n' %
- (r.shortName, r.description))
- raise SystemExit(0)
-
-
- def opt_reactor(self, shortName):
- """
- Which reactor to use (see --help-reactors for a list of possibilities)
- """
- # Actually actually actually install the reactor right at this very
- # moment, before any other code (for example, a sub-command plugin)
- # runs and accidentally imports and installs the default reactor.
- #
- # This could probably be improved somehow.
- try:
- installReactor(shortName)
- except NoSuchReactor:
- msg = ("The specified reactor does not exist: '%s'.\n"
- "See the list of available reactors with "
- "--help-reactors" % (shortName,))
- raise usage.UsageError(msg)
- except Exception, e:
- msg = ("The specified reactor cannot be used, failed with error: "
- "%s.\nSee the list of available reactors with "
- "--help-reactors" % (e,))
- raise usage.UsageError(msg)
- else:
- self["reactor"] = shortName
- opt_r = opt_reactor
-
-
-
-
-class ServerOptions(usage.Options, ReactorSelectionMixin):
-
- longdesc = ("twistd reads a twisted.application.service.Application out "
- "of a file and runs it.")
-
- optFlags = [['savestats', None,
- "save the Stats object rather than the text output of "
- "the profiler."],
- ['no_save','o', "do not save state on shutdown"],
- ['encrypted', 'e',
- "The specified tap/aos file is encrypted."]]
-
- optParameters = [['logfile','l', None,
- "log to a specified file, - for stdout"],
- ['logger', None, None,
- "A fully-qualified name to a log observer factory to use "
- "for the initial log observer. Takes precedence over "
- "--logfile and --syslog (when available)."],
- ['profile', 'p', None,
- "Run in profile mode, dumping results to specified file"],
- ['profiler', None, "hotshot",
- "Name of the profiler to use (%s)." %
- ", ".join(AppProfiler.profilers)],
- ['file','f','twistd.tap',
- "read the given .tap file"],
- ['python','y', None,
- "read an application from within a Python file "
- "(implies -o)"],
- ['source', 's', None,
- "Read an application from a .tas file (AOT format)."],
- ['rundir','d','.',
- 'Change to a supplied directory before running']]
-
- compData = usage.Completions(
- mutuallyExclusive=[("file", "python", "source")],
- optActions={"file": usage.CompleteFiles("*.tap"),
- "python": usage.CompleteFiles("*.(tac|py)"),
- "source": usage.CompleteFiles("*.tas"),
- "rundir": usage.CompleteDirs()}
- )
-
- _getPlugins = staticmethod(plugin.getPlugins)
-
- def __init__(self, *a, **kw):
- self['debug'] = False
- usage.Options.__init__(self, *a, **kw)
-
-
- def opt_debug(self):
- """
- Run the application in the Python Debugger (implies nodaemon),
- sending SIGUSR2 will drop into debugger
- """
- defer.setDebugging(True)
- failure.startDebugMode()
- self['debug'] = True
- opt_b = opt_debug
-
-
- def opt_spew(self):
- """
- Print an insanely verbose log of everything that happens.
- Useful when debugging freezes or locks in complex code."""
- sys.settrace(util.spewer)
- try:
- import threading
- except ImportError:
- return
- threading.settrace(util.spewer)
-
-
- def parseOptions(self, options=None):
- if options is None:
- options = sys.argv[1:] or ["--help"]
- usage.Options.parseOptions(self, options)
-
-
- def postOptions(self):
- if self.subCommand or self['python']:
- self['no_save'] = True
- if self['logger'] is not None:
- try:
- self['logger'] = namedAny(self['logger'])
- except Exception, e:
- raise usage.UsageError("Logger '%s' could not be imported: %s"
- % (self['logger'], e))
-
-
- def subCommands(self):
- plugins = self._getPlugins(service.IServiceMaker)
- self.loadedPlugins = {}
- for plug in sorted(plugins, key=attrgetter('tapname')):
- self.loadedPlugins[plug.tapname] = plug
- yield (plug.tapname,
- None,
- # Avoid resolving the options attribute right away, in case
- # it's a property with a non-trivial getter (eg, one which
- # imports modules).
- lambda plug=plug: plug.options(),
- plug.description)
- subCommands = property(subCommands)
-
-
-
-def run(runApp, ServerOptions):
- config = ServerOptions()
- try:
- config.parseOptions()
- except usage.error, ue:
- print config
- print "%s: %s" % (sys.argv[0], ue)
- else:
- runApp(config)
-
-
-
-def convertStyle(filein, typein, passphrase, fileout, typeout, encrypt):
- application = service.loadApplication(filein, typein, passphrase)
- sob.IPersistable(application).setStyle(typeout)
- passphrase = getSavePassphrase(encrypt)
- if passphrase:
- fileout = None
- sob.IPersistable(application).save(filename=fileout, passphrase=passphrase)
-
-
-
-def startApplication(application, save):
- from twisted.internet import reactor
- service.IService(application).startService()
- if save:
- p = sob.IPersistable(application)
- reactor.addSystemEventTrigger('after', 'shutdown', p.save, 'shutdown')
- reactor.addSystemEventTrigger('before', 'shutdown',
- service.IService(application).stopService)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/internet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/internet.py
deleted file mode 100755
index c0fa4e91..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/internet.py
+++ /dev/null
@@ -1,408 +0,0 @@
-# -*- test-case-name: twisted.application.test.test_internet,twisted.test.test_application,twisted.test.test_cooperator -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Reactor-based Services
-
-Here are services to run clients, servers and periodic services using
-the reactor.
-
-If you want to run a server service, L{StreamServerEndpointService} defines a
-service that can wrap an arbitrary L{IStreamServerEndpoint
-<twisted.internet.interfaces.IStreamServerEndpoint>}
-as an L{IService}. See also L{twisted.application.strports.service} for
-constructing one of these directly from a descriptive string.
-
-Additionally, this module (dynamically) defines various Service subclasses that
-let you represent clients and servers in a Service hierarchy. Endpoints APIs
-should be preferred for stream server services, but since those APIs do not yet
-exist for clients or datagram services, many of these are still useful.
-
-They are as follows::
-
- TCPServer, TCPClient,
- UNIXServer, UNIXClient,
- SSLServer, SSLClient,
- UDPServer, UDPClient,
- UNIXDatagramServer, UNIXDatagramClient,
- MulticastServer
-
-These classes take arbitrary arguments in their constructors and pass
-them straight on to their respective reactor.listenXXX or
-reactor.connectXXX calls.
-
-For example, the following service starts a web server on port 8080:
-C{TCPServer(8080, server.Site(r))}. See the documentation for the
-reactor.listen/connect* methods for more information.
-"""
-
-import warnings
-
-from twisted.python import log
-from twisted.application import service
-from twisted.internet import task
-
-from twisted.internet.defer import CancelledError
-
-
-def _maybeGlobalReactor(maybeReactor):
- """
- @return: the argument, or the global reactor if the argument is C{None}.
- """
- if maybeReactor is None:
- from twisted.internet import reactor
- return reactor
- else:
- return maybeReactor
-
-
-class _VolatileDataService(service.Service):
-
- volatile = []
-
- def __getstate__(self):
- d = service.Service.__getstate__(self)
- for attr in self.volatile:
- if attr in d:
- del d[attr]
- return d
-
-
-
-class _AbstractServer(_VolatileDataService):
- """
- @cvar volatile: list of attribute to remove from pickling.
- @type volatile: C{list}
-
- @ivar method: the type of method to call on the reactor, one of B{TCP},
- B{UDP}, B{SSL} or B{UNIX}.
- @type method: C{str}
-
- @ivar reactor: the current running reactor.
- @type reactor: a provider of C{IReactorTCP}, C{IReactorUDP},
- C{IReactorSSL} or C{IReactorUnix}.
-
- @ivar _port: instance of port set when the service is started.
- @type _port: a provider of L{twisted.internet.interfaces.IListeningPort}.
- """
-
- volatile = ['_port']
- method = None
- reactor = None
-
- _port = None
-
- def __init__(self, *args, **kwargs):
- self.args = args
- if 'reactor' in kwargs:
- self.reactor = kwargs.pop("reactor")
- self.kwargs = kwargs
-
-
- def privilegedStartService(self):
- service.Service.privilegedStartService(self)
- self._port = self._getPort()
-
-
- def startService(self):
- service.Service.startService(self)
- if self._port is None:
- self._port = self._getPort()
-
-
- def stopService(self):
- service.Service.stopService(self)
- # TODO: if startup failed, should shutdown skip stopListening?
- # _port won't exist
- if self._port is not None:
- d = self._port.stopListening()
- del self._port
- return d
-
-
- def _getPort(self):
- """
- Wrapper around the appropriate listen method of the reactor.
-
- @return: the port object returned by the listen method.
- @rtype: an object providing
- L{twisted.internet.interfaces.IListeningPort}.
- """
- return getattr(_maybeGlobalReactor(self.reactor),
- 'listen%s' % (self.method,))(*self.args, **self.kwargs)
-
-
-
-class _AbstractClient(_VolatileDataService):
- """
- @cvar volatile: list of attribute to remove from pickling.
- @type volatile: C{list}
-
- @ivar method: the type of method to call on the reactor, one of B{TCP},
- B{UDP}, B{SSL} or B{UNIX}.
- @type method: C{str}
-
- @ivar reactor: the current running reactor.
- @type reactor: a provider of C{IReactorTCP}, C{IReactorUDP},
- C{IReactorSSL} or C{IReactorUnix}.
-
- @ivar _connection: instance of connection set when the service is started.
- @type _connection: a provider of L{twisted.internet.interfaces.IConnector}.
- """
- volatile = ['_connection']
- method = None
- reactor = None
-
- _connection = None
-
- def __init__(self, *args, **kwargs):
- self.args = args
- if 'reactor' in kwargs:
- self.reactor = kwargs.pop("reactor")
- self.kwargs = kwargs
-
-
- def startService(self):
- service.Service.startService(self)
- self._connection = self._getConnection()
-
-
- def stopService(self):
- service.Service.stopService(self)
- if self._connection is not None:
- self._connection.disconnect()
- del self._connection
-
-
- def _getConnection(self):
- """
- Wrapper around the appropriate connect method of the reactor.
-
- @return: the port object returned by the connect method.
- @rtype: an object providing L{twisted.internet.interfaces.IConnector}.
- """
- return getattr(_maybeGlobalReactor(self.reactor),
- 'connect%s' % (self.method,))(*self.args, **self.kwargs)
-
-
-
-_doc={
-'Client':
-"""Connect to %(tran)s
-
-Call reactor.connect%(method)s when the service starts, with the
-arguments given to the constructor.
-""",
-'Server':
-"""Serve %(tran)s clients
-
-Call reactor.listen%(method)s when the service starts, with the
-arguments given to the constructor. When the service stops,
-stop listening. See twisted.internet.interfaces for documentation
-on arguments to the reactor method.
-""",
-}
-
-import types
-for tran in 'TCP UNIX SSL UDP UNIXDatagram Multicast'.split():
- for side in 'Server Client'.split():
- if tran == "Multicast" and side == "Client":
- continue
- base = globals()['_Abstract'+side]
- method = {'Generic': 'With'}.get(tran, tran)
- doc = _doc[side]%vars()
- klass = types.ClassType(tran+side, (base,),
- {'method': method, '__doc__': doc})
- globals()[tran+side] = klass
-
-
-
-class GenericServer(_AbstractServer):
- """
- Serve Generic clients
-
- Call reactor.listenWith when the service starts, with the arguments given to
- the constructor. When the service stops, stop listening. See
- twisted.internet.interfaces for documentation on arguments to the reactor
- method.
-
- This service is deprecated (because reactor.listenWith is deprecated).
- """
- method = 'With'
-
- def __init__(self, *args, **kwargs):
- warnings.warn(
- 'GenericServer was deprecated in Twisted 10.1.',
- category=DeprecationWarning,
- stacklevel=2)
- _AbstractServer.__init__(self, *args, **kwargs)
-
-
-
-class GenericClient(_AbstractClient):
- """
- Connect to Generic.
-
- Call reactor.connectWith when the service starts, with the arguments given
- to the constructor.
-
- This service is deprecated (because reactor.connectWith is deprecated).
- """
- method = 'With'
-
- def __init__(self, *args, **kwargs):
- warnings.warn(
- 'GenericClient was deprecated in Twisted 10.1.',
- category=DeprecationWarning,
- stacklevel=2)
- _AbstractClient.__init__(self, *args, **kwargs)
-
-
-
-class TimerService(_VolatileDataService):
-
- """Service to periodically call a function
-
- Every C{step} seconds call the given function with the given arguments.
- The service starts the calls when it starts, and cancels them
- when it stops.
- """
-
- volatile = ['_loop']
-
- def __init__(self, step, callable, *args, **kwargs):
- self.step = step
- self.call = (callable, args, kwargs)
-
- def startService(self):
- service.Service.startService(self)
- callable, args, kwargs = self.call
- # we have to make a new LoopingCall each time we're started, because
- # an active LoopingCall remains active when serialized. If
- # LoopingCall were a _VolatileDataService, we wouldn't need to do
- # this.
- self._loop = task.LoopingCall(callable, *args, **kwargs)
- self._loop.start(self.step, now=True).addErrback(self._failed)
-
- def _failed(self, why):
- # make a note that the LoopingCall is no longer looping, so we don't
- # try to shut it down a second time in stopService. I think this
- # should be in LoopingCall. -warner
- self._loop.running = False
- log.err(why)
-
- def stopService(self):
- if self._loop.running:
- self._loop.stop()
- return service.Service.stopService(self)
-
-
-
-class CooperatorService(service.Service):
- """
- Simple L{service.IService} which starts and stops a L{twisted.internet.task.Cooperator}.
- """
- def __init__(self):
- self.coop = task.Cooperator(started=False)
-
-
- def coiterate(self, iterator):
- return self.coop.coiterate(iterator)
-
-
- def startService(self):
- self.coop.start()
-
-
- def stopService(self):
- self.coop.stop()
-
-
-
-class StreamServerEndpointService(service.Service, object):
- """
- A L{StreamServerEndpointService} is an L{IService} which runs a server on a
- listening port described by an L{IStreamServerEndpoint
- <twisted.internet.interfaces.IStreamServerEndpoint>}.
-
- @ivar factory: A server factory which will be used to listen on the
- endpoint.
-
- @ivar endpoint: An L{IStreamServerEndpoint
- <twisted.internet.interfaces.IStreamServerEndpoint>} provider
- which will be used to listen when the service starts.
-
- @ivar _waitingForPort: a Deferred, if C{listen} has yet been invoked on the
- endpoint, otherwise None.
-
- @ivar _raiseSynchronously: Defines error-handling behavior for the case
- where C{listen(...)} raises an exception before C{startService} or
- C{privilegedStartService} have completed.
-
- @type _raiseSynchronously: C{bool}
-
- @since: 10.2
- """
-
- _raiseSynchronously = None
-
- def __init__(self, endpoint, factory):
- self.endpoint = endpoint
- self.factory = factory
- self._waitingForPort = None
-
-
- def privilegedStartService(self):
- """
- Start listening on the endpoint.
- """
- service.Service.privilegedStartService(self)
- self._waitingForPort = self.endpoint.listen(self.factory)
- raisedNow = []
- def handleIt(err):
- if self._raiseSynchronously:
- raisedNow.append(err)
- elif not err.check(CancelledError):
- log.err(err)
- self._waitingForPort.addErrback(handleIt)
- if raisedNow:
- raisedNow[0].raiseException()
-
-
- def startService(self):
- """
- Start listening on the endpoint, unless L{privilegedStartService} got
- around to it already.
- """
- service.Service.startService(self)
- if self._waitingForPort is None:
- self.privilegedStartService()
-
-
- def stopService(self):
- """
- Stop listening on the port if it is already listening, otherwise,
- cancel the attempt to listen.
-
- @return: a L{Deferred<twisted.internet.defer.Deferred>} which fires
- with C{None} when the port has stopped listening.
- """
- self._waitingForPort.cancel()
- def stopIt(port):
- if port is not None:
- return port.stopListening()
- d = self._waitingForPort.addCallback(stopIt)
- def stop(passthrough):
- self.running = False
- return passthrough
- d.addBoth(stop)
- return d
-
-
-
-__all__ = (['TimerService', 'CooperatorService', 'MulticastServer',
- 'StreamServerEndpointService'] +
- [tran+side
- for tran in 'Generic TCP UNIX SSL UDP UNIXDatagram'.split()
- for side in 'Server Client'.split()])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/reactors.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/reactors.py
deleted file mode 100755
index 6bae985b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/reactors.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# -*- test-case-name: twisted.test.test_application -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Plugin-based system for enumerating available reactors and installing one of
-them.
-"""
-
-from zope.interface import Interface, Attribute, implements
-
-from twisted.plugin import IPlugin, getPlugins
-from twisted.python.reflect import namedAny
-
-
-class IReactorInstaller(Interface):
- """
- Definition of a reactor which can probably be installed.
- """
- shortName = Attribute("""
- A brief string giving the user-facing name of this reactor.
- """)
-
- description = Attribute("""
- A longer string giving a user-facing description of this reactor.
- """)
-
- def install():
- """
- Install this reactor.
- """
-
- # TODO - A method which provides a best-guess as to whether this reactor
- # can actually be used in the execution environment.
-
-
-
-class NoSuchReactor(KeyError):
- """
- Raised when an attempt is made to install a reactor which cannot be found.
- """
-
-
-class Reactor(object):
- """
- @ivar moduleName: The fully-qualified Python name of the module of which
- the install callable is an attribute.
- """
- implements(IPlugin, IReactorInstaller)
-
-
- def __init__(self, shortName, moduleName, description):
- self.shortName = shortName
- self.moduleName = moduleName
- self.description = description
-
-
- def install(self):
- namedAny(self.moduleName).install()
-
-
-
-def getReactorTypes():
- """
- Return an iterator of L{IReactorInstaller} plugins.
- """
- return getPlugins(IReactorInstaller)
-
-
-
-def installReactor(shortName):
- """
- Install the reactor with the given C{shortName} attribute.
-
- @raise NoSuchReactor: If no reactor is found with a matching C{shortName}.
-
- @raise: anything that the specified reactor can raise when installed.
- """
- for installer in getReactorTypes():
- if installer.shortName == shortName:
- return installer.install()
- raise NoSuchReactor(shortName)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/service.py
deleted file mode 100755
index 66fef85b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/service.py
+++ /dev/null
@@ -1,413 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Service architecture for Twisted.
-
-Services are arranged in a hierarchy. At the leafs of the hierarchy,
-the services which actually interact with the outside world are started.
-Services can be named or anonymous -- usually, they will be named if
-there is need to access them through the hierarchy (from a parent or
-a sibling).
-
-Maintainer: Moshe Zadka
-"""
-
-from zope.interface import implements, Interface, Attribute
-
-from twisted.python.reflect import namedAny
-from twisted.python import components
-from twisted.internet import defer
-from twisted.persisted import sob
-from twisted.plugin import IPlugin
-
-
-class IServiceMaker(Interface):
- """
- An object which can be used to construct services in a flexible
- way.
-
- This interface should most often be implemented along with
- L{twisted.plugin.IPlugin}, and will most often be used by the
- 'twistd' command.
- """
- tapname = Attribute(
- "A short string naming this Twisted plugin, for example 'web' or "
- "'pencil'. This name will be used as the subcommand of 'twistd'.")
-
- description = Attribute(
- "A brief summary of the features provided by this "
- "Twisted application plugin.")
-
- options = Attribute(
- "A C{twisted.python.usage.Options} subclass defining the "
- "configuration options for this application.")
-
-
- def makeService(options):
- """
- Create and return an object providing
- L{twisted.application.service.IService}.
-
- @param options: A mapping (typically a C{dict} or
- L{twisted.python.usage.Options} instance) of configuration
- options to desired configuration values.
- """
-
-
-
-class ServiceMaker(object):
- """
- Utility class to simplify the definition of L{IServiceMaker} plugins.
- """
- implements(IPlugin, IServiceMaker)
-
- def __init__(self, name, module, description, tapname):
- self.name = name
- self.module = module
- self.description = description
- self.tapname = tapname
-
-
- def options():
- def get(self):
- return namedAny(self.module).Options
- return get,
- options = property(*options())
-
-
- def makeService():
- def get(self):
- return namedAny(self.module).makeService
- return get,
- makeService = property(*makeService())
-
-
-
-class IService(Interface):
- """
- A service.
-
- Run start-up and shut-down code at the appropriate times.
-
- @type name: C{string}
- @ivar name: The name of the service (or None)
- @type running: C{boolean}
- @ivar running: Whether the service is running.
- """
-
- def setName(name):
- """
- Set the name of the service.
-
- @type name: C{str}
- @raise RuntimeError: Raised if the service already has a parent.
- """
-
- def setServiceParent(parent):
- """
- Set the parent of the service. This method is responsible for setting
- the C{parent} attribute on this service (the child service).
-
- @type parent: L{IServiceCollection}
- @raise RuntimeError: Raised if the service already has a parent
- or if the service has a name and the parent already has a child
- by that name.
- """
-
- def disownServiceParent():
- """
- Use this API to remove an L{IService} from an L{IServiceCollection}.
-
- This method is used symmetrically with L{setServiceParent} in that it
- sets the C{parent} attribute on the child.
-
- @rtype: L{Deferred<defer.Deferred>}
- @return: a L{Deferred<defer.Deferred>} which is triggered when the
- service has finished shutting down. If shutting down is immediate,
- a value can be returned (usually, C{None}).
- """
-
- def startService():
- """
- Start the service.
- """
-
- def stopService():
- """
- Stop the service.
-
- @rtype: L{Deferred<defer.Deferred>}
- @return: a L{Deferred<defer.Deferred>} which is triggered when the
- service has finished shutting down. If shutting down is immediate,
- a value can be returned (usually, C{None}).
- """
-
- def privilegedStartService():
- """
- Do preparation work for starting the service.
-
- Here things which should be done before changing directory,
- root or shedding privileges are done.
- """
-
-
-class Service:
- """
- Base class for services.
-
- Most services should inherit from this class. It handles the
- book-keeping reponsibilities of starting and stopping, as well
- as not serializing this book-keeping information.
- """
-
- implements(IService)
-
- running = 0
- name = None
- parent = None
-
- def __getstate__(self):
- dict = self.__dict__.copy()
- if "running" in dict:
- del dict['running']
- return dict
-
- def setName(self, name):
- if self.parent is not None:
- raise RuntimeError("cannot change name when parent exists")
- self.name = name
-
- def setServiceParent(self, parent):
- if self.parent is not None:
- self.disownServiceParent()
- parent = IServiceCollection(parent, parent)
- self.parent = parent
- self.parent.addService(self)
-
- def disownServiceParent(self):
- d = self.parent.removeService(self)
- self.parent = None
- return d
-
- def privilegedStartService(self):
- pass
-
- def startService(self):
- self.running = 1
-
- def stopService(self):
- self.running = 0
-
-
-
-class IServiceCollection(Interface):
- """
- Collection of services.
-
- Contain several services, and manage their start-up/shut-down.
- Services can be accessed by name if they have a name, and it
- is always possible to iterate over them.
- """
-
- def getServiceNamed(name):
- """
- Get the child service with a given name.
-
- @type name: C{str}
- @rtype: L{IService}
- @raise KeyError: Raised if the service has no child with the
- given name.
- """
-
- def __iter__():
- """
- Get an iterator over all child services.
- """
-
- def addService(service):
- """
- Add a child service.
-
- Only implementations of L{IService.setServiceParent} should use this
- method.
-
- @type service: L{IService}
- @raise RuntimeError: Raised if the service has a child with
- the given name.
- """
-
- def removeService(service):
- """
- Remove a child service.
-
- Only implementations of L{IService.disownServiceParent} should
- use this method.
-
- @type service: L{IService}
- @raise ValueError: Raised if the given service is not a child.
- @rtype: L{Deferred<defer.Deferred>}
- @return: a L{Deferred<defer.Deferred>} which is triggered when the
- service has finished shutting down. If shutting down is immediate,
- a value can be returned (usually, C{None}).
- """
-
-
-
-class MultiService(Service):
- """
- Straightforward Service Container.
-
- Hold a collection of services, and manage them in a simplistic
- way. No service will wait for another, but this object itself
- will not finish shutting down until all of its child services
- will finish.
- """
-
- implements(IServiceCollection)
-
- def __init__(self):
- self.services = []
- self.namedServices = {}
- self.parent = None
-
- def privilegedStartService(self):
- Service.privilegedStartService(self)
- for service in self:
- service.privilegedStartService()
-
- def startService(self):
- Service.startService(self)
- for service in self:
- service.startService()
-
- def stopService(self):
- Service.stopService(self)
- l = []
- services = list(self)
- services.reverse()
- for service in services:
- l.append(defer.maybeDeferred(service.stopService))
- return defer.DeferredList(l)
-
- def getServiceNamed(self, name):
- return self.namedServices[name]
-
- def __iter__(self):
- return iter(self.services)
-
- def addService(self, service):
- if service.name is not None:
- if service.name in self.namedServices:
- raise RuntimeError("cannot have two services with same name"
- " '%s'" % service.name)
- self.namedServices[service.name] = service
- self.services.append(service)
- if self.running:
- # It may be too late for that, but we will do our best
- service.privilegedStartService()
- service.startService()
-
- def removeService(self, service):
- if service.name:
- del self.namedServices[service.name]
- self.services.remove(service)
- if self.running:
- # Returning this so as not to lose information from the
- # MultiService.stopService deferred.
- return service.stopService()
- else:
- return None
-
-
-
-class IProcess(Interface):
- """
- Process running parameters.
-
- Represents parameters for how processes should be run.
- """
- processName = Attribute(
- """
- A C{str} giving the name the process should have in ps (or C{None}
- to leave the name alone).
- """)
-
- uid = Attribute(
- """
- An C{int} giving the user id as which the process should run (or
- C{None} to leave the UID alone).
- """)
-
- gid = Attribute(
- """
- An C{int} giving the group id as which the process should run (or
- C{None} to leave the GID alone).
- """)
-
-
-
-class Process:
- """
- Process running parameters.
-
- Sets up uid/gid in the constructor, and has a default
- of C{None} as C{processName}.
- """
- implements(IProcess)
- processName = None
-
- def __init__(self, uid=None, gid=None):
- """
- Set uid and gid.
-
- @param uid: The user ID as whom to execute the process. If
- this is C{None}, no attempt will be made to change the UID.
-
- @param gid: The group ID as whom to execute the process. If
- this is C{None}, no attempt will be made to change the GID.
- """
- self.uid = uid
- self.gid = gid
-
-
-def Application(name, uid=None, gid=None):
- """
- Return a compound class.
-
- Return an object supporting the L{IService}, L{IServiceCollection},
- L{IProcess} and L{sob.IPersistable} interfaces, with the given
- parameters. Always access the return value by explicit casting to
- one of the interfaces.
- """
- ret = components.Componentized()
- for comp in (MultiService(), sob.Persistent(ret, name), Process(uid, gid)):
- ret.addComponent(comp, ignoreClass=1)
- IService(ret).setName(name)
- return ret
-
-
-
-def loadApplication(filename, kind, passphrase=None):
- """
- Load Application from a given file.
-
- The serialization format it was saved in should be given as
- C{kind}, and is one of C{pickle}, C{source}, C{xml} or C{python}. If
- C{passphrase} is given, the application was encrypted with the
- given passphrase.
-
- @type filename: C{str}
- @type kind: C{str}
- @type passphrase: C{str}
- """
- if kind == 'python':
- application = sob.loadValueFromFile(filename, 'application', passphrase)
- else:
- application = sob.load(filename, kind, passphrase)
- return application
-
-
-__all__ = ['IServiceMaker', 'IService', 'Service',
- 'IServiceCollection', 'MultiService',
- 'IProcess', 'Process', 'Application', 'loadApplication']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/strports.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/strports.py
deleted file mode 100755
index 117d76fc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/strports.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# -*- test-case-name: twisted.test.test_strports -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Construct listening port services from a simple string description.
-
-@see: L{twisted.internet.endpoints.serverFromString}
-@see: L{twisted.internet.endpoints.clientFromString}
-"""
-
-import warnings
-
-from twisted.internet import endpoints
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-from twisted.application.internet import StreamServerEndpointService
-
-
-
-def parse(description, factory, default='tcp'):
- """
- This function is deprecated as of Twisted 10.2.
-
- @see: L{twisted.internet.endpoints.server}
- """
- return endpoints._parseServer(description, factory, default)
-
-deprecatedModuleAttribute(
- Version("Twisted", 10, 2, 0),
- "in favor of twisted.internet.endpoints.serverFromString",
- __name__, "parse")
-
-
-
-_DEFAULT = object()
-
-def service(description, factory, default=_DEFAULT, reactor=None):
- """
- Return the service corresponding to a description.
-
- @param description: The description of the listening port, in the syntax
- described by L{twisted.internet.endpoints.server}.
-
- @type description: C{str}
-
- @param factory: The protocol factory which will build protocols for
- connections to this service.
-
- @type factory: L{twisted.internet.interfaces.IProtocolFactory}
-
- @type default: C{str} or C{None}
-
- @param default: Do not use this parameter. It has been deprecated since
- Twisted 10.2.0.
-
- @rtype: C{twisted.application.service.IService}
-
- @return: the service corresponding to a description of a reliable
- stream server.
-
- @see: L{twisted.internet.endpoints.serverFromString}
- """
- if reactor is None:
- from twisted.internet import reactor
- if default is _DEFAULT:
- default = None
- else:
- message = "The 'default' parameter was deprecated in Twisted 10.2.0."
- if default is not None:
- message += (
- " Use qualified endpoint descriptions; for example, "
- "'tcp:%s'." % (description,))
- warnings.warn(
- message=message, category=DeprecationWarning, stacklevel=2)
- svc = StreamServerEndpointService(
- endpoints._serverFromStringLegacy(reactor, description, default),
- factory)
- svc._raiseSynchronously = True
- return svc
-
-
-
-def listen(description, factory, default=None):
- """Listen on a port corresponding to a description
-
- @type description: C{str}
- @type factory: L{twisted.internet.interfaces.IProtocolFactory}
- @type default: C{str} or C{None}
- @rtype: C{twisted.internet.interfaces.IListeningPort}
- @return: the port corresponding to a description of a reliable
- virtual circuit server.
-
- See the documentation of the C{parse} function for description
- of the semantics of the arguments.
- """
- from twisted.internet import reactor
- name, args, kw = parse(description, factory, default)
- return getattr(reactor, 'listen'+name)(*args, **kw)
-
-
-
-__all__ = ['parse', 'service', 'listen']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/__init__.py
deleted file mode 100755
index 3cb9635f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.application}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/test_internet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/test_internet.py
deleted file mode 100755
index 9e058d71..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/test/test_internet.py
+++ /dev/null
@@ -1,252 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for (new code in) L{twisted.application.internet}.
-"""
-
-
-from zope.interface import implements
-from zope.interface.verify import verifyClass
-
-from twisted.internet.protocol import Factory
-from twisted.trial.unittest import TestCase
-from twisted.application.internet import StreamServerEndpointService
-from twisted.internet.interfaces import IStreamServerEndpoint, IListeningPort
-from twisted.internet.defer import Deferred, CancelledError
-
-class FakeServer(object):
- """
- In-memory implementation of L{IStreamServerEndpoint}.
-
- @ivar result: The L{Deferred} resulting from the call to C{listen}, after
- C{listen} has been called.
-
- @ivar factory: The factory passed to C{listen}.
-
- @ivar cancelException: The exception to errback C{self.result} when it is
- cancelled.
-
- @ivar port: The L{IListeningPort} which C{listen}'s L{Deferred} will fire
- with.
-
- @ivar listenAttempts: The number of times C{listen} has been invoked.
-
- @ivar failImmediately: If set, the exception to fail the L{Deferred}
- returned from C{listen} before it is returned.
- """
-
- implements(IStreamServerEndpoint)
-
- result = None
- factory = None
- failImmediately = None
- cancelException = CancelledError()
- listenAttempts = 0
-
- def __init__(self):
- self.port = FakePort()
-
-
- def listen(self, factory):
- """
- Return a Deferred and store it for future use. (Implementation of
- L{IStreamServerEndpoint}).
- """
- self.listenAttempts += 1
- self.factory = factory
- self.result = Deferred(
- canceller=lambda d: d.errback(self.cancelException))
- if self.failImmediately is not None:
- self.result.errback(self.failImmediately)
- return self.result
-
-
- def startedListening(self):
- """
- Test code should invoke this method after causing C{listen} to be
- invoked in order to fire the L{Deferred} previously returned from
- C{listen}.
- """
- self.result.callback(self.port)
-
-
- def stoppedListening(self):
- """
- Test code should invoke this method after causing C{stopListening} to
- be invoked on the port fired from the L{Deferred} returned from
- C{listen} in order to cause the L{Deferred} returned from
- C{stopListening} to fire.
- """
- self.port.deferred.callback(None)
-
-verifyClass(IStreamServerEndpoint, FakeServer)
-
-
-
-class FakePort(object):
- """
- Fake L{IListeningPort} implementation.
-
- @ivar deferred: The L{Deferred} returned by C{stopListening}.
- """
-
- implements(IListeningPort)
-
- deferred = None
-
- def stopListening(self):
- self.deferred = Deferred()
- return self.deferred
-
-verifyClass(IStreamServerEndpoint, FakeServer)
-
-
-
-class TestEndpointService(TestCase):
- """
- Tests for L{twisted.application.internet}.
- """
-
- def setUp(self):
- """
- Construct a stub server, a stub factory, and a
- L{StreamServerEndpointService} to test.
- """
- self.fakeServer = FakeServer()
- self.factory = Factory()
- self.svc = StreamServerEndpointService(self.fakeServer, self.factory)
-
-
- def test_privilegedStartService(self):
- """
- L{StreamServerEndpointService.privilegedStartService} calls its
- endpoint's C{listen} method with its factory.
- """
- self.svc.privilegedStartService()
- self.assertIdentical(self.factory, self.fakeServer.factory)
-
-
- def test_synchronousRaiseRaisesSynchronously(self, thunk=None):
- """
- L{StreamServerEndpointService.startService} should raise synchronously
- if the L{Deferred} returned by its wrapped
- L{IStreamServerEndpoint.listen} has already fired with an errback and
- the L{StreamServerEndpointService}'s C{_raiseSynchronously} flag has
- been set. This feature is necessary to preserve compatibility with old
- behavior of L{twisted.internet.strports.service}, which is to return a
- service which synchronously raises an exception from C{startService}
- (so that, among other things, twistd will not start running). However,
- since L{IStreamServerEndpoint.listen} may fail asynchronously, it is
- a bad idea to rely on this behavior.
- """
- self.fakeServer.failImmediately = ZeroDivisionError()
- self.svc._raiseSynchronously = True
- self.assertRaises(ZeroDivisionError, thunk or self.svc.startService)
-
-
- def test_synchronousRaisePrivileged(self):
- """
- L{StreamServerEndpointService.privilegedStartService} should behave the
- same as C{startService} with respect to
- L{TestEndpointService.test_synchronousRaiseRaisesSynchronously}.
- """
- self.test_synchronousRaiseRaisesSynchronously(
- self.svc.privilegedStartService)
-
-
- def test_failReportsError(self):
- """
- L{StreamServerEndpointService.startService} and
- L{StreamServerEndpointService.privilegedStartService} should both log
- an exception when the L{Deferred} returned from their wrapped
- L{IStreamServerEndpoint.listen} fails.
- """
- self.svc.startService()
- self.fakeServer.result.errback(ZeroDivisionError())
- logged = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(logged), 1)
-
-
- def test_synchronousFailReportsError(self):
- """
- Without the C{_raiseSynchronously} compatibility flag, failing
- immediately has the same behavior as failing later; it logs the error.
- """
- self.fakeServer.failImmediately = ZeroDivisionError()
- self.svc.startService()
- logged = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(logged), 1)
-
-
- def test_startServiceUnstarted(self):
- """
- L{StreamServerEndpointService.startService} sets the C{running} flag,
- and calls its endpoint's C{listen} method with its factory, if it
- has not yet been started.
- """
- self.svc.startService()
- self.assertIdentical(self.factory, self.fakeServer.factory)
- self.assertEqual(self.svc.running, True)
-
-
- def test_startServiceStarted(self):
- """
- L{StreamServerEndpointService.startService} sets the C{running} flag,
- but nothing else, if the service has already been started.
- """
- self.test_privilegedStartService()
- self.svc.startService()
- self.assertEqual(self.fakeServer.listenAttempts, 1)
- self.assertEqual(self.svc.running, True)
-
-
- def test_stopService(self):
- """
- L{StreamServerEndpointService.stopService} calls C{stopListening} on
- the L{IListeningPort} returned from its endpoint, returns the
- C{Deferred} from stopService, and sets C{running} to C{False}.
- """
- self.svc.privilegedStartService()
- self.fakeServer.startedListening()
- # Ensure running gets set to true
- self.svc.startService()
- result = self.svc.stopService()
- l = []
- result.addCallback(l.append)
- self.assertEqual(len(l), 0)
- self.fakeServer.stoppedListening()
- self.assertEqual(len(l), 1)
- self.assertFalse(self.svc.running)
-
-
- def test_stopServiceBeforeStartFinished(self):
- """
- L{StreamServerEndpointService.stopService} cancels the L{Deferred}
- returned by C{listen} if it has not yet fired. No error will be logged
- about the cancellation of the listen attempt.
- """
- self.svc.privilegedStartService()
- result = self.svc.stopService()
- l = []
- result.addBoth(l.append)
- self.assertEqual(l, [None])
- self.assertEqual(self.flushLoggedErrors(CancelledError), [])
-
-
- def test_stopServiceCancelStartError(self):
- """
- L{StreamServerEndpointService.stopService} cancels the L{Deferred}
- returned by C{listen} if it has not fired yet. An error will be logged
- if the resulting exception is not L{CancelledError}.
- """
- self.fakeServer.cancelException = ZeroDivisionError()
- self.svc.privilegedStartService()
- result = self.svc.stopService()
- l = []
- result.addCallback(l.append)
- self.assertEqual(l, [None])
- stoppingErrors = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(stoppingErrors), 1)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py
deleted file mode 100755
index d7ce597c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- test-case-name: twisted.conch.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-
-"""
-Twisted.Conch: The Twisted Shell. Terminal emulation, SSHv2 and telnet.
-
-Currently this contains the SSHv2 implementation, but it may work over other
-protocols in the future. (i.e. Telnet)
-
-Maintainer: Paul Swartz
-"""
-
-from twisted.conch._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py
deleted file mode 100755
index 26337c3f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.conch', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py
deleted file mode 100755
index a914da3e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_conch -*-
-from interfaces import IConchUser
-from error import ConchError
-from ssh.connection import OPEN_UNKNOWN_CHANNEL_TYPE
-from twisted.python import log
-from zope import interface
-
-class ConchUser:
- interface.implements(IConchUser)
-
- def __init__(self):
- self.channelLookup = {}
- self.subsystemLookup = {}
-
- def lookupChannel(self, channelType, windowSize, maxPacket, data):
- klass = self.channelLookup.get(channelType, None)
- if not klass:
- raise ConchError(OPEN_UNKNOWN_CHANNEL_TYPE, "unknown channel")
- else:
- return klass(remoteWindow = windowSize,
- remoteMaxPacket = maxPacket,
- data=data, avatar=self)
-
- def lookupSubsystem(self, subsystem, data):
- log.msg(repr(self.subsystemLookup))
- klass = self.subsystemLookup.get(subsystem, None)
- if not klass:
- return False
- return klass(data, avatar=self)
-
- def gotGlobalRequest(self, requestType, data):
- # XXX should this use method dispatch?
- requestType = requestType.replace('-','_')
- f = getattr(self, "global_%s" % requestType, None)
- if not f:
- return 0
- return f(data)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py
deleted file mode 100755
index 3cd6a0ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_checkers -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Provide L{ICredentialsChecker} implementations to be used in Conch protocols.
-"""
-
-import os, base64, binascii, errno
-try:
- import pwd
-except ImportError:
- pwd = None
-else:
- import crypt
-
-try:
- # Python 2.5 got spwd to interface with shadow passwords
- import spwd
-except ImportError:
- spwd = None
- try:
- import shadow
- except ImportError:
- shadow = None
-else:
- shadow = None
-
-try:
- from twisted.cred import pamauth
-except ImportError:
- pamauth = None
-
-from zope.interface import implements, providedBy
-
-from twisted.conch import error
-from twisted.conch.ssh import keys
-from twisted.cred.checkers import ICredentialsChecker
-from twisted.cred.credentials import IUsernamePassword, ISSHPrivateKey
-from twisted.cred.error import UnauthorizedLogin, UnhandledCredentials
-from twisted.internet import defer
-from twisted.python import failure, reflect, log
-from twisted.python.util import runAsEffectiveUser
-from twisted.python.filepath import FilePath
-
-
-
-def verifyCryptedPassword(crypted, pw):
- return crypt.crypt(pw, crypted) == crypted
-
-
-
-def _pwdGetByName(username):
- """
- Look up a user in the /etc/passwd database using the pwd module. If the
- pwd module is not available, return None.
-
- @param username: the username of the user to return the passwd database
- information for.
- """
- if pwd is None:
- return None
- return pwd.getpwnam(username)
-
-
-
-def _shadowGetByName(username):
- """
- Look up a user in the /etc/shadow database using the spwd or shadow
- modules. If neither module is available, return None.
-
- @param username: the username of the user to return the shadow database
- information for.
- """
- if spwd is not None:
- f = spwd.getspnam
- elif shadow is not None:
- f = shadow.getspnam
- else:
- return None
- return runAsEffectiveUser(0, 0, f, username)
-
-
-
-class UNIXPasswordDatabase:
- """
- A checker which validates users out of the UNIX password databases, or
- databases of a compatible format.
-
- @ivar _getByNameFunctions: a C{list} of functions which are called in order
- to valid a user. The default value is such that the /etc/passwd
- database will be tried first, followed by the /etc/shadow database.
- """
- credentialInterfaces = IUsernamePassword,
- implements(ICredentialsChecker)
-
-
- def __init__(self, getByNameFunctions=None):
- if getByNameFunctions is None:
- getByNameFunctions = [_pwdGetByName, _shadowGetByName]
- self._getByNameFunctions = getByNameFunctions
-
-
- def requestAvatarId(self, credentials):
- for func in self._getByNameFunctions:
- try:
- pwnam = func(credentials.username)
- except KeyError:
- return defer.fail(UnauthorizedLogin("invalid username"))
- else:
- if pwnam is not None:
- crypted = pwnam[1]
- if crypted == '':
- continue
- if verifyCryptedPassword(crypted, credentials.password):
- return defer.succeed(credentials.username)
- # fallback
- return defer.fail(UnauthorizedLogin("unable to verify password"))
-
-
-
-class SSHPublicKeyDatabase:
- """
- Checker that authenticates SSH public keys, based on public keys listed in
- authorized_keys and authorized_keys2 files in user .ssh/ directories.
- """
- implements(ICredentialsChecker)
-
- credentialInterfaces = (ISSHPrivateKey,)
-
- _userdb = pwd
-
- def requestAvatarId(self, credentials):
- d = defer.maybeDeferred(self.checkKey, credentials)
- d.addCallback(self._cbRequestAvatarId, credentials)
- d.addErrback(self._ebRequestAvatarId)
- return d
-
- def _cbRequestAvatarId(self, validKey, credentials):
- """
- Check whether the credentials themselves are valid, now that we know
- if the key matches the user.
-
- @param validKey: A boolean indicating whether or not the public key
- matches a key in the user's authorized_keys file.
-
- @param credentials: The credentials offered by the user.
- @type credentials: L{ISSHPrivateKey} provider
-
- @raise UnauthorizedLogin: (as a failure) if the key does not match the
- user in C{credentials}. Also raised if the user provides an invalid
- signature.
-
- @raise ValidPublicKey: (as a failure) if the key matches the user but
- the credentials do not include a signature. See
- L{error.ValidPublicKey} for more information.
-
- @return: The user's username, if authentication was successful.
- """
- if not validKey:
- return failure.Failure(UnauthorizedLogin("invalid key"))
- if not credentials.signature:
- return failure.Failure(error.ValidPublicKey())
- else:
- try:
- pubKey = keys.Key.fromString(credentials.blob)
- if pubKey.verify(credentials.signature, credentials.sigData):
- return credentials.username
- except: # any error should be treated as a failed login
- log.err()
- return failure.Failure(UnauthorizedLogin('error while verifying key'))
- return failure.Failure(UnauthorizedLogin("unable to verify key"))
-
-
- def getAuthorizedKeysFiles(self, credentials):
- """
- Return a list of L{FilePath} instances for I{authorized_keys} files
- which might contain information about authorized keys for the given
- credentials.
-
- On OpenSSH servers, the default location of the file containing the
- list of authorized public keys is
- U{$HOME/.ssh/authorized_keys<http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config>}.
-
- I{$HOME/.ssh/authorized_keys2} is also returned, though it has been
- U{deprecated by OpenSSH since
- 2001<http://marc.info/?m=100508718416162>}.
-
- @return: A list of L{FilePath} instances to files with the authorized keys.
- """
- pwent = self._userdb.getpwnam(credentials.username)
- root = FilePath(pwent.pw_dir).child('.ssh')
- files = ['authorized_keys', 'authorized_keys2']
- return [root.child(f) for f in files]
-
-
- def checkKey(self, credentials):
- """
- Retrieve files containing authorized keys and check against user
- credentials.
- """
- uid, gid = os.geteuid(), os.getegid()
- ouid, ogid = self._userdb.getpwnam(credentials.username)[2:4]
- for filepath in self.getAuthorizedKeysFiles(credentials):
- if not filepath.exists():
- continue
- try:
- lines = filepath.open()
- except IOError, e:
- if e.errno == errno.EACCES:
- lines = runAsEffectiveUser(ouid, ogid, filepath.open)
- else:
- raise
- for l in lines:
- l2 = l.split()
- if len(l2) < 2:
- continue
- try:
- if base64.decodestring(l2[1]) == credentials.blob:
- return True
- except binascii.Error:
- continue
- return False
-
- def _ebRequestAvatarId(self, f):
- if not f.check(UnauthorizedLogin):
- log.msg(f)
- return failure.Failure(UnauthorizedLogin("unable to get avatar id"))
- return f
-
-
-class SSHProtocolChecker:
- """
- SSHProtocolChecker is a checker that requires multiple authentications
- to succeed. To add a checker, call my registerChecker method with
- the checker and the interface.
-
- After each successful authenticate, I call my areDone method with the
- avatar id. To get a list of the successful credentials for an avatar id,
- use C{SSHProcotolChecker.successfulCredentials[avatarId]}. If L{areDone}
- returns True, the authentication has succeeded.
- """
-
- implements(ICredentialsChecker)
-
- def __init__(self):
- self.checkers = {}
- self.successfulCredentials = {}
-
- def get_credentialInterfaces(self):
- return self.checkers.keys()
-
- credentialInterfaces = property(get_credentialInterfaces)
-
- def registerChecker(self, checker, *credentialInterfaces):
- if not credentialInterfaces:
- credentialInterfaces = checker.credentialInterfaces
- for credentialInterface in credentialInterfaces:
- self.checkers[credentialInterface] = checker
-
- def requestAvatarId(self, credentials):
- """
- Part of the L{ICredentialsChecker} interface. Called by a portal with
- some credentials to check if they'll authenticate a user. We check the
- interfaces that the credentials provide against our list of acceptable
- checkers. If one of them matches, we ask that checker to verify the
- credentials. If they're valid, we call our L{_cbGoodAuthentication}
- method to continue.
-
- @param credentials: the credentials the L{Portal} wants us to verify
- """
- ifac = providedBy(credentials)
- for i in ifac:
- c = self.checkers.get(i)
- if c is not None:
- d = defer.maybeDeferred(c.requestAvatarId, credentials)
- return d.addCallback(self._cbGoodAuthentication,
- credentials)
- return defer.fail(UnhandledCredentials("No checker for %s" % \
- ', '.join(map(reflect.qual, ifac))))
-
- def _cbGoodAuthentication(self, avatarId, credentials):
- """
- Called if a checker has verified the credentials. We call our
- L{areDone} method to see if the whole of the successful authentications
- are enough. If they are, we return the avatar ID returned by the first
- checker.
- """
- if avatarId not in self.successfulCredentials:
- self.successfulCredentials[avatarId] = []
- self.successfulCredentials[avatarId].append(credentials)
- if self.areDone(avatarId):
- del self.successfulCredentials[avatarId]
- return avatarId
- else:
- raise error.NotEnoughAuthentication()
-
- def areDone(self, avatarId):
- """
- Override to determine if the authentication is finished for a given
- avatarId.
-
- @param avatarId: the avatar returned by the first checker. For
- this checker to function correctly, all the checkers must
- return the same avatar ID.
- """
- return True
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py
deleted file mode 100755
index f55d474d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""
-Client support code for Conch.
-
-Maintainer: Paul Swartz
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py
deleted file mode 100755
index 50a8feaa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_default -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Accesses the key agent for user authentication.
-
-Maintainer: Paul Swartz
-"""
-
-import os
-
-from twisted.conch.ssh import agent, channel, keys
-from twisted.internet import protocol, reactor
-from twisted.python import log
-
-
-
-class SSHAgentClient(agent.SSHAgentClient):
-
- def __init__(self):
- agent.SSHAgentClient.__init__(self)
- self.blobs = []
-
-
- def getPublicKeys(self):
- return self.requestIdentities().addCallback(self._cbPublicKeys)
-
-
- def _cbPublicKeys(self, blobcomm):
- log.msg('got %i public keys' % len(blobcomm))
- self.blobs = [x[0] for x in blobcomm]
-
-
- def getPublicKey(self):
- """
- Return a L{Key} from the first blob in C{self.blobs}, if any, or
- return C{None}.
- """
- if self.blobs:
- return keys.Key.fromString(self.blobs.pop(0))
- return None
-
-
-
-class SSHAgentForwardingChannel(channel.SSHChannel):
-
- def channelOpen(self, specificData):
- cc = protocol.ClientCreator(reactor, SSHAgentForwardingLocal)
- d = cc.connectUNIX(os.environ['SSH_AUTH_SOCK'])
- d.addCallback(self._cbGotLocal)
- d.addErrback(lambda x:self.loseConnection())
- self.buf = ''
-
-
- def _cbGotLocal(self, local):
- self.local = local
- self.dataReceived = self.local.transport.write
- self.local.dataReceived = self.write
-
-
- def dataReceived(self, data):
- self.buf += data
-
-
- def closed(self):
- if self.local:
- self.local.loseConnection()
- self.local = None
-
-
-class SSHAgentForwardingLocal(protocol.Protocol):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py
deleted file mode 100755
index dc5fe22d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-import direct
-
-connectTypes = {"direct" : direct.connect}
-
-def connect(host, port, options, verifyHostKey, userAuthObject):
- useConnects = ['direct']
- return _ebConnect(None, useConnects, host, port, options, verifyHostKey,
- userAuthObject)
-
-def _ebConnect(f, useConnects, host, port, options, vhk, uao):
- if not useConnects:
- return f
- connectType = useConnects.pop(0)
- f = connectTypes[connectType]
- d = f(host, port, options, vhk, uao)
- d.addErrback(_ebConnect, useConnects, host, port, options, vhk, uao)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py
deleted file mode 100755
index 50fe97a1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_knownhosts,twisted.conch.test.test_default -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Various classes and functions for implementing user-interaction in the
-command-line conch client.
-
-You probably shouldn't use anything in this module directly, since it assumes
-you are sitting at an interactive terminal. For example, to programmatically
-interact with a known_hosts database, use L{twisted.conch.client.knownhosts}.
-"""
-
-from twisted.python import log
-from twisted.python.filepath import FilePath
-
-from twisted.conch.error import ConchError
-from twisted.conch.ssh import common, keys, userauth
-from twisted.internet import defer, protocol, reactor
-
-from twisted.conch.client.knownhosts import KnownHostsFile, ConsoleUI
-
-from twisted.conch.client import agent
-
-import os, sys, base64, getpass
-
-# This name is bound so that the unit tests can use 'patch' to override it.
-_open = open
-
-def verifyHostKey(transport, host, pubKey, fingerprint):
- """
- Verify a host's key.
-
- This function is a gross vestige of some bad factoring in the client
- internals. The actual implementation, and a better signature of this logic
- is in L{KnownHostsFile.verifyHostKey}. This function is not deprecated yet
- because the callers have not yet been rehabilitated, but they should
- eventually be changed to call that method instead.
-
- However, this function does perform two functions not implemented by
- L{KnownHostsFile.verifyHostKey}. It determines the path to the user's
- known_hosts file based on the options (which should really be the options
- object's job), and it provides an opener to L{ConsoleUI} which opens
- '/dev/tty' so that the user will be prompted on the tty of the process even
- if the input and output of the process has been redirected. This latter
- part is, somewhat obviously, not portable, but I don't know of a portable
- equivalent that could be used.
-
- @param host: Due to a bug in L{SSHClientTransport.verifyHostKey}, this is
- always the dotted-quad IP address of the host being connected to.
- @type host: L{str}
-
- @param transport: the client transport which is attempting to connect to
- the given host.
- @type transport: L{SSHClientTransport}
-
- @param fingerprint: the fingerprint of the given public key, in
- xx:xx:xx:... format. This is ignored in favor of getting the fingerprint
- from the key itself.
- @type fingerprint: L{str}
-
- @param pubKey: The public key of the server being connected to.
- @type pubKey: L{str}
-
- @return: a L{Deferred} which fires with C{1} if the key was successfully
- verified, or fails if the key could not be successfully verified. Failure
- types may include L{HostKeyChanged}, L{UserRejectedKey}, L{IOError} or
- L{KeyboardInterrupt}.
- """
- actualHost = transport.factory.options['host']
- actualKey = keys.Key.fromString(pubKey)
- kh = KnownHostsFile.fromPath(FilePath(
- transport.factory.options['known-hosts']
- or os.path.expanduser("~/.ssh/known_hosts")
- ))
- ui = ConsoleUI(lambda : _open("/dev/tty", "r+b"))
- return kh.verifyHostKey(ui, actualHost, host, actualKey)
-
-
-
-def isInKnownHosts(host, pubKey, options):
- """checks to see if host is in the known_hosts file for the user.
- returns 0 if it isn't, 1 if it is and is the same, 2 if it's changed.
- """
- keyType = common.getNS(pubKey)[0]
- retVal = 0
-
- if not options['known-hosts'] and not os.path.exists(os.path.expanduser('~/.ssh/')):
- print 'Creating ~/.ssh directory...'
- os.mkdir(os.path.expanduser('~/.ssh'))
- kh_file = options['known-hosts'] or '~/.ssh/known_hosts'
- try:
- known_hosts = open(os.path.expanduser(kh_file))
- except IOError:
- return 0
- for line in known_hosts.xreadlines():
- split = line.split()
- if len(split) < 3:
- continue
- hosts, hostKeyType, encodedKey = split[:3]
- if host not in hosts.split(','): # incorrect host
- continue
- if hostKeyType != keyType: # incorrect type of key
- continue
- try:
- decodedKey = base64.decodestring(encodedKey)
- except:
- continue
- if decodedKey == pubKey:
- return 1
- else:
- retVal = 2
- return retVal
-
-
-
-class SSHUserAuthClient(userauth.SSHUserAuthClient):
-
- def __init__(self, user, options, *args):
- userauth.SSHUserAuthClient.__init__(self, user, *args)
- self.keyAgent = None
- self.options = options
- self.usedFiles = []
- if not options.identitys:
- options.identitys = ['~/.ssh/id_rsa', '~/.ssh/id_dsa']
-
- def serviceStarted(self):
- if 'SSH_AUTH_SOCK' in os.environ and not self.options['noagent']:
- log.msg('using agent')
- cc = protocol.ClientCreator(reactor, agent.SSHAgentClient)
- d = cc.connectUNIX(os.environ['SSH_AUTH_SOCK'])
- d.addCallback(self._setAgent)
- d.addErrback(self._ebSetAgent)
- else:
- userauth.SSHUserAuthClient.serviceStarted(self)
-
- def serviceStopped(self):
- if self.keyAgent:
- self.keyAgent.transport.loseConnection()
- self.keyAgent = None
-
- def _setAgent(self, a):
- self.keyAgent = a
- d = self.keyAgent.getPublicKeys()
- d.addBoth(self._ebSetAgent)
- return d
-
- def _ebSetAgent(self, f):
- userauth.SSHUserAuthClient.serviceStarted(self)
-
- def _getPassword(self, prompt):
- try:
- oldout, oldin = sys.stdout, sys.stdin
- sys.stdin = sys.stdout = open('/dev/tty','r+')
- p=getpass.getpass(prompt)
- sys.stdout,sys.stdin=oldout,oldin
- return p
- except (KeyboardInterrupt, IOError):
- print
- raise ConchError('PEBKAC')
-
- def getPassword(self, prompt = None):
- if not prompt:
- prompt = "%s@%s's password: " % (self.user, self.transport.transport.getPeer().host)
- try:
- p = self._getPassword(prompt)
- return defer.succeed(p)
- except ConchError:
- return defer.fail()
-
-
- def getPublicKey(self):
- """
- Get a public key from the key agent if possible, otherwise look in
- the next configured identity file for one.
- """
- if self.keyAgent:
- key = self.keyAgent.getPublicKey()
- if key is not None:
- return key
- files = [x for x in self.options.identitys if x not in self.usedFiles]
- log.msg(str(self.options.identitys))
- log.msg(str(files))
- if not files:
- return None
- file = files[0]
- log.msg(file)
- self.usedFiles.append(file)
- file = os.path.expanduser(file)
- file += '.pub'
- if not os.path.exists(file):
- return self.getPublicKey() # try again
- try:
- return keys.Key.fromFile(file)
- except keys.BadKeyError:
- return self.getPublicKey() # try again
-
-
- def signData(self, publicKey, signData):
- """
- Extend the base signing behavior by using an SSH agent to sign the
- data, if one is available.
-
- @type publicKey: L{Key}
- @type signData: C{str}
- """
- if not self.usedFiles: # agent key
- return self.keyAgent.signData(publicKey.blob(), signData)
- else:
- return userauth.SSHUserAuthClient.signData(self, publicKey, signData)
-
-
- def getPrivateKey(self):
- """
- Try to load the private key from the last used file identified by
- C{getPublicKey}, potentially asking for the passphrase if the key is
- encrypted.
- """
- file = os.path.expanduser(self.usedFiles[-1])
- if not os.path.exists(file):
- return None
- try:
- return defer.succeed(keys.Key.fromFile(file))
- except keys.EncryptedKeyError:
- for i in range(3):
- prompt = "Enter passphrase for key '%s': " % \
- self.usedFiles[-1]
- try:
- p = self._getPassword(prompt)
- return defer.succeed(keys.Key.fromFile(file, passphrase=p))
- except (keys.BadKeyError, ConchError):
- pass
- return defer.fail(ConchError('bad password'))
- raise
- except KeyboardInterrupt:
- print
- reactor.stop()
-
-
- def getGenericAnswers(self, name, instruction, prompts):
- responses = []
- try:
- oldout, oldin = sys.stdout, sys.stdin
- sys.stdin = sys.stdout = open('/dev/tty','r+')
- if name:
- print name
- if instruction:
- print instruction
- for prompt, echo in prompts:
- if echo:
- responses.append(raw_input(prompt))
- else:
- responses.append(getpass.getpass(prompt))
- finally:
- sys.stdout,sys.stdin=oldout,oldin
- return defer.succeed(responses)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py
deleted file mode 100755
index f95a14ae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.internet import defer, protocol, reactor
-from twisted.conch import error
-from twisted.conch.ssh import transport
-from twisted.python import log
-
-
-
-class SSHClientFactory(protocol.ClientFactory):
-
- def __init__(self, d, options, verifyHostKey, userAuthObject):
- self.d = d
- self.options = options
- self.verifyHostKey = verifyHostKey
- self.userAuthObject = userAuthObject
-
-
- def clientConnectionLost(self, connector, reason):
- if self.options['reconnect']:
- connector.connect()
-
-
- def clientConnectionFailed(self, connector, reason):
- if self.d is None:
- return
- d, self.d = self.d, None
- d.errback(reason)
-
-
- def buildProtocol(self, addr):
- trans = SSHClientTransport(self)
- if self.options['ciphers']:
- trans.supportedCiphers = self.options['ciphers']
- if self.options['macs']:
- trans.supportedMACs = self.options['macs']
- if self.options['compress']:
- trans.supportedCompressions[0:1] = ['zlib']
- if self.options['host-key-algorithms']:
- trans.supportedPublicKeys = self.options['host-key-algorithms']
- return trans
-
-
-
-class SSHClientTransport(transport.SSHClientTransport):
-
- def __init__(self, factory):
- self.factory = factory
- self.unixServer = None
-
-
- def connectionLost(self, reason):
- if self.unixServer:
- d = self.unixServer.stopListening()
- self.unixServer = None
- else:
- d = defer.succeed(None)
- d.addCallback(lambda x:
- transport.SSHClientTransport.connectionLost(self, reason))
-
-
- def receiveError(self, code, desc):
- if self.factory.d is None:
- return
- d, self.factory.d = self.factory.d, None
- d.errback(error.ConchError(desc, code))
-
-
- def sendDisconnect(self, code, reason):
- if self.factory.d is None:
- return
- d, self.factory.d = self.factory.d, None
- transport.SSHClientTransport.sendDisconnect(self, code, reason)
- d.errback(error.ConchError(reason, code))
-
-
- def receiveDebug(self, alwaysDisplay, message, lang):
- log.msg('Received Debug Message: %s' % message)
- if alwaysDisplay: # XXX what should happen here?
- print message
-
-
- def verifyHostKey(self, pubKey, fingerprint):
- return self.factory.verifyHostKey(self, self.transport.getPeer().host, pubKey,
- fingerprint)
-
-
- def setService(self, service):
- log.msg('setting client server to %s' % service)
- transport.SSHClientTransport.setService(self, service)
- if service.name != 'ssh-userauth' and self.factory.d is not None:
- d, self.factory.d = self.factory.d, None
- d.callback(None)
-
-
- def connectionSecure(self):
- self.requestService(self.factory.userAuthObject)
-
-
-
-def connect(host, port, options, verifyHostKey, userAuthObject):
- d = defer.Deferred()
- factory = SSHClientFactory(d, options, verifyHostKey, userAuthObject)
- reactor.connectTCP(host, port, factory)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py
deleted file mode 100755
index 48cd89bf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py
+++ /dev/null
@@ -1,478 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_knownhosts -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An implementation of the OpenSSH known_hosts database.
-
-@since: 8.2
-"""
-
-from binascii import Error as DecodeError, b2a_base64
-import hmac
-import sys
-
-from zope.interface import implements
-
-from twisted.python.randbytes import secureRandom
-if sys.version_info >= (2, 5):
- from twisted.python.hashlib import sha1
-else:
- # We need to have an object with a method named 'new'.
- import sha as sha1
-
-from twisted.internet import defer
-
-from twisted.python import log
-from twisted.conch.interfaces import IKnownHostEntry
-from twisted.conch.error import HostKeyChanged, UserRejectedKey, InvalidEntry
-from twisted.conch.ssh.keys import Key, BadKeyError
-
-
-def _b64encode(s):
- """
- Encode a binary string as base64 with no trailing newline.
- """
- return b2a_base64(s).strip()
-
-
-
-def _extractCommon(string):
- """
- Extract common elements of base64 keys from an entry in a hosts file.
-
- @return: a 4-tuple of hostname data (L{str}), ssh key type (L{str}), key
- (L{Key}), and comment (L{str} or L{None}). The hostname data is simply the
- beginning of the line up to the first occurrence of whitespace.
- """
- elements = string.split(None, 2)
- if len(elements) != 3:
- raise InvalidEntry()
- hostnames, keyType, keyAndComment = elements
- splitkey = keyAndComment.split(None, 1)
- if len(splitkey) == 2:
- keyString, comment = splitkey
- comment = comment.rstrip("\n")
- else:
- keyString = splitkey[0]
- comment = None
- key = Key.fromString(keyString.decode('base64'))
- return hostnames, keyType, key, comment
-
-
-
-class _BaseEntry(object):
- """
- Abstract base of both hashed and non-hashed entry objects, since they
- represent keys and key types the same way.
-
- @ivar keyType: The type of the key; either ssh-dss or ssh-rsa.
- @type keyType: L{str}
-
- @ivar publicKey: The server public key indicated by this line.
- @type publicKey: L{twisted.conch.ssh.keys.Key}
-
- @ivar comment: Trailing garbage after the key line.
- @type comment: L{str}
- """
-
- def __init__(self, keyType, publicKey, comment):
- self.keyType = keyType
- self.publicKey = publicKey
- self.comment = comment
-
-
- def matchesKey(self, keyObject):
- """
- Check to see if this entry matches a given key object.
-
- @type keyObject: L{Key}
-
- @rtype: bool
- """
- return self.publicKey == keyObject
-
-
-
-class PlainEntry(_BaseEntry):
- """
- A L{PlainEntry} is a representation of a plain-text entry in a known_hosts
- file.
-
- @ivar _hostnames: the list of all host-names associated with this entry.
- @type _hostnames: L{list} of L{str}
- """
-
- implements(IKnownHostEntry)
-
- def __init__(self, hostnames, keyType, publicKey, comment):
- self._hostnames = hostnames
- super(PlainEntry, self).__init__(keyType, publicKey, comment)
-
-
- def fromString(cls, string):
- """
- Parse a plain-text entry in a known_hosts file, and return a
- corresponding L{PlainEntry}.
-
- @param string: a space-separated string formatted like "hostname
- key-type base64-key-data comment".
-
- @type string: L{str}
-
- @raise DecodeError: if the key is not valid encoded as valid base64.
-
- @raise InvalidEntry: if the entry does not have the right number of
- elements and is therefore invalid.
-
- @raise BadKeyError: if the key, once decoded from base64, is not
- actually an SSH key.
-
- @return: an IKnownHostEntry representing the hostname and key in the
- input line.
-
- @rtype: L{PlainEntry}
- """
- hostnames, keyType, key, comment = _extractCommon(string)
- self = cls(hostnames.split(","), keyType, key, comment)
- return self
-
- fromString = classmethod(fromString)
-
-
- def matchesHost(self, hostname):
- """
- Check to see if this entry matches a given hostname.
-
- @type hostname: L{str}
-
- @rtype: bool
- """
- return hostname in self._hostnames
-
-
- def toString(self):
- """
- Implement L{IKnownHostEntry.toString} by recording the comma-separated
- hostnames, key type, and base-64 encoded key.
- """
- fields = [','.join(self._hostnames),
- self.keyType,
- _b64encode(self.publicKey.blob())]
- if self.comment is not None:
- fields.append(self.comment)
- return ' '.join(fields)
-
-
-class UnparsedEntry(object):
- """
- L{UnparsedEntry} is an entry in a L{KnownHostsFile} which can't actually be
- parsed; therefore it matches no keys and no hosts.
- """
-
- implements(IKnownHostEntry)
-
- def __init__(self, string):
- """
- Create an unparsed entry from a line in a known_hosts file which cannot
- otherwise be parsed.
- """
- self._string = string
-
-
- def matchesHost(self, hostname):
- """
- Always returns False.
- """
- return False
-
-
- def matchesKey(self, key):
- """
- Always returns False.
- """
- return False
-
-
- def toString(self):
- """
- Returns the input line, without its newline if one was given.
- """
- return self._string.rstrip("\n")
-
-
-
-def _hmacedString(key, string):
- """
- Return the SHA-1 HMAC hash of the given key and string.
- """
- hash = hmac.HMAC(key, digestmod=sha1)
- hash.update(string)
- return hash.digest()
-
-
-
-class HashedEntry(_BaseEntry):
- """
- A L{HashedEntry} is a representation of an entry in a known_hosts file
- where the hostname has been hashed and salted.
-
- @ivar _hostSalt: the salt to combine with a hostname for hashing.
-
- @ivar _hostHash: the hashed representation of the hostname.
-
- @cvar MAGIC: the 'hash magic' string used to identify a hashed line in a
- known_hosts file as opposed to a plaintext one.
- """
-
- implements(IKnownHostEntry)
-
- MAGIC = '|1|'
-
- def __init__(self, hostSalt, hostHash, keyType, publicKey, comment):
- self._hostSalt = hostSalt
- self._hostHash = hostHash
- super(HashedEntry, self).__init__(keyType, publicKey, comment)
-
-
- def fromString(cls, string):
- """
- Load a hashed entry from a string representing a line in a known_hosts
- file.
-
- @raise DecodeError: if the key, the hostname, or the is not valid
- encoded as valid base64
-
- @raise InvalidEntry: if the entry does not have the right number of
- elements and is therefore invalid, or the host/hash portion contains
- more items than just the host and hash.
-
- @raise BadKeyError: if the key, once decoded from base64, is not
- actually an SSH key.
- """
- stuff, keyType, key, comment = _extractCommon(string)
- saltAndHash = stuff[len(cls.MAGIC):].split("|")
- if len(saltAndHash) != 2:
- raise InvalidEntry()
- hostSalt, hostHash = saltAndHash
- self = cls(hostSalt.decode("base64"), hostHash.decode("base64"),
- keyType, key, comment)
- return self
-
- fromString = classmethod(fromString)
-
-
- def matchesHost(self, hostname):
- """
- Implement L{IKnownHostEntry.matchesHost} to compare the hash of the
- input to the stored hash.
- """
- return (_hmacedString(self._hostSalt, hostname) == self._hostHash)
-
-
- def toString(self):
- """
- Implement L{IKnownHostEntry.toString} by base64-encoding the salt, host
- hash, and key.
- """
- fields = [self.MAGIC + '|'.join([_b64encode(self._hostSalt),
- _b64encode(self._hostHash)]),
- self.keyType,
- _b64encode(self.publicKey.blob())]
- if self.comment is not None:
- fields.append(self.comment)
- return ' '.join(fields)
-
-
-
-class KnownHostsFile(object):
- """
- A structured representation of an OpenSSH-format ~/.ssh/known_hosts file.
-
- @ivar _entries: a list of L{IKnownHostEntry} providers.
-
- @ivar _savePath: the L{FilePath} to save new entries to.
- """
-
- def __init__(self, savePath):
- """
- Create a new, empty KnownHostsFile.
-
- You want to use L{KnownHostsFile.fromPath} to parse one of these.
- """
- self._entries = []
- self._savePath = savePath
-
-
- def hasHostKey(self, hostname, key):
- """
- @return: True if the given hostname and key are present in this file,
- False if they are not.
-
- @rtype: L{bool}
-
- @raise HostKeyChanged: if the host key found for the given hostname
- does not match the given key.
- """
- for lineidx, entry in enumerate(self._entries):
- if entry.matchesHost(hostname):
- if entry.matchesKey(key):
- return True
- else:
- raise HostKeyChanged(entry, self._savePath, lineidx + 1)
- return False
-
-
- def verifyHostKey(self, ui, hostname, ip, key):
- """
- Verify the given host key for the given IP and host, asking for
- confirmation from, and notifying, the given UI about changes to this
- file.
-
- @param ui: The user interface to request an IP address from.
-
- @param hostname: The hostname that the user requested to connect to.
-
- @param ip: The string representation of the IP address that is actually
- being connected to.
-
- @param key: The public key of the server.
-
- @return: a L{Deferred} that fires with True when the key has been
- verified, or fires with an errback when the key either cannot be
- verified or has changed.
-
- @rtype: L{Deferred}
- """
- hhk = defer.maybeDeferred(self.hasHostKey, hostname, key)
- def gotHasKey(result):
- if result:
- if not self.hasHostKey(ip, key):
- ui.warn("Warning: Permanently added the %s host key for "
- "IP address '%s' to the list of known hosts." %
- (key.type(), ip))
- self.addHostKey(ip, key)
- self.save()
- return result
- else:
- def promptResponse(response):
- if response:
- self.addHostKey(hostname, key)
- self.addHostKey(ip, key)
- self.save()
- return response
- else:
- raise UserRejectedKey()
- return ui.prompt(
- "The authenticity of host '%s (%s)' "
- "can't be established.\n"
- "RSA key fingerprint is %s.\n"
- "Are you sure you want to continue connecting (yes/no)? " %
- (hostname, ip, key.fingerprint())).addCallback(promptResponse)
- return hhk.addCallback(gotHasKey)
-
-
- def addHostKey(self, hostname, key):
- """
- Add a new L{HashedEntry} to the key database.
-
- Note that you still need to call L{KnownHostsFile.save} if you wish
- these changes to be persisted.
-
- @return: the L{HashedEntry} that was added.
- """
- salt = secureRandom(20)
- keyType = "ssh-" + key.type().lower()
- entry = HashedEntry(salt, _hmacedString(salt, hostname),
- keyType, key, None)
- self._entries.append(entry)
- return entry
-
-
- def save(self):
- """
- Save this L{KnownHostsFile} to the path it was loaded from.
- """
- p = self._savePath.parent()
- if not p.isdir():
- p.makedirs()
- self._savePath.setContent('\n'.join(
- [entry.toString() for entry in self._entries]) + "\n")
-
-
- def fromPath(cls, path):
- """
- @param path: A path object to use for both reading contents from and
- later saving to.
-
- @type path: L{FilePath}
- """
- self = cls(path)
- try:
- fp = path.open()
- except IOError:
- return self
- for line in fp:
- try:
- if line.startswith(HashedEntry.MAGIC):
- entry = HashedEntry.fromString(line)
- else:
- entry = PlainEntry.fromString(line)
- except (DecodeError, InvalidEntry, BadKeyError):
- entry = UnparsedEntry(line)
- self._entries.append(entry)
- return self
-
- fromPath = classmethod(fromPath)
-
-
-class ConsoleUI(object):
- """
- A UI object that can ask true/false questions and post notifications on the
- console, to be used during key verification.
-
- @ivar opener: a no-argument callable which should open a console file-like
- object to be used for reading and writing.
- """
-
- def __init__(self, opener):
- self.opener = opener
-
-
- def prompt(self, text):
- """
- Write the given text as a prompt to the console output, then read a
- result from the console input.
-
- @return: a L{Deferred} which fires with L{True} when the user answers
- 'yes' and L{False} when the user answers 'no'. It may errback if there
- were any I/O errors.
- """
- d = defer.succeed(None)
- def body(ignored):
- f = self.opener()
- f.write(text)
- while True:
- answer = f.readline().strip().lower()
- if answer == 'yes':
- f.close()
- return True
- elif answer == 'no':
- f.close()
- return False
- else:
- f.write("Please type 'yes' or 'no': ")
- return d.addCallback(body)
-
-
- def warn(self, text):
- """
- Notify the user (non-interactively) of the provided text, by writing it
- to the console.
- """
- try:
- f = self.opener()
- f.write(text)
- f.close()
- except:
- log.err()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py
deleted file mode 100755
index 8550573d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-from twisted.conch.ssh.transport import SSHClientTransport, SSHCiphers
-from twisted.python import usage
-
-import sys
-
-class ConchOptions(usage.Options):
-
- optParameters = [['user', 'l', None, 'Log in using this user name.'],
- ['identity', 'i', None],
- ['ciphers', 'c', None],
- ['macs', 'm', None],
- ['port', 'p', None, 'Connect to this port. Server must be on the same port.'],
- ['option', 'o', None, 'Ignored OpenSSH options'],
- ['host-key-algorithms', '', None],
- ['known-hosts', '', None, 'File to check for host keys'],
- ['user-authentications', '', None, 'Types of user authentications to use.'],
- ['logfile', '', None, 'File to log to, or - for stdout'],
- ]
-
- optFlags = [['version', 'V', 'Display version number only.'],
- ['compress', 'C', 'Enable compression.'],
- ['log', 'v', 'Enable logging (defaults to stderr)'],
- ['nox11', 'x', 'Disable X11 connection forwarding (default)'],
- ['agent', 'A', 'Enable authentication agent forwarding'],
- ['noagent', 'a', 'Disable authentication agent forwarding (default)'],
- ['reconnect', 'r', 'Reconnect to the server if the connection is lost.'],
- ]
-
- compData = usage.Completions(
- mutuallyExclusive=[("agent", "noagent")],
- optActions={
- "user": usage.CompleteUsernames(),
- "ciphers": usage.CompleteMultiList(
- SSHCiphers.cipherMap.keys(),
- descr='ciphers to choose from'),
- "macs": usage.CompleteMultiList(
- SSHCiphers.macMap.keys(),
- descr='macs to choose from'),
- "host-key-algorithms": usage.CompleteMultiList(
- SSHClientTransport.supportedPublicKeys,
- descr='host key algorithms to choose from'),
- #"user-authentications": usage.CompleteMultiList(?
- # descr='user authentication types' ),
- },
- extraActions=[usage.CompleteUserAtHost(),
- usage.Completer(descr="command"),
- usage.Completer(descr='argument',
- repeat=True)]
- )
-
- def __init__(self, *args, **kw):
- usage.Options.__init__(self, *args, **kw)
- self.identitys = []
- self.conns = None
-
- def opt_identity(self, i):
- """Identity for public-key authentication"""
- self.identitys.append(i)
-
- def opt_ciphers(self, ciphers):
- "Select encryption algorithms"
- ciphers = ciphers.split(',')
- for cipher in ciphers:
- if not SSHCiphers.cipherMap.has_key(cipher):
- sys.exit("Unknown cipher type '%s'" % cipher)
- self['ciphers'] = ciphers
-
-
- def opt_macs(self, macs):
- "Specify MAC algorithms"
- macs = macs.split(',')
- for mac in macs:
- if not SSHCiphers.macMap.has_key(mac):
- sys.exit("Unknown mac type '%s'" % mac)
- self['macs'] = macs
-
- def opt_host_key_algorithms(self, hkas):
- "Select host key algorithms"
- hkas = hkas.split(',')
- for hka in hkas:
- if hka not in SSHClientTransport.supportedPublicKeys:
- sys.exit("Unknown host key type '%s'" % hka)
- self['host-key-algorithms'] = hkas
-
- def opt_user_authentications(self, uas):
- "Choose how to authenticate to the remote server"
- self['user-authentications'] = uas.split(',')
-
-# def opt_compress(self):
-# "Enable compression"
-# self.enableCompression = 1
-# SSHClientTransport.supportedCompressions[0:1] = ['zlib']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py
deleted file mode 100755
index a3bcc65e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An error to represent bad things happening in Conch.
-
-Maintainer: Paul Swartz
-"""
-
-from twisted.cred.error import UnauthorizedLogin
-
-
-
-class ConchError(Exception):
- def __init__(self, value, data = None):
- Exception.__init__(self, value, data)
- self.value = value
- self.data = data
-
-
-
-class NotEnoughAuthentication(Exception):
- """
- This is thrown if the authentication is valid, but is not enough to
- successfully verify the user. i.e. don't retry this type of
- authentication, try another one.
- """
-
-
-
-class ValidPublicKey(UnauthorizedLogin):
- """
- Raised by public key checkers when they receive public key credentials
- that don't contain a signature at all, but are valid in every other way.
- (e.g. the public key matches one in the user's authorized_keys file).
-
- Protocol code (eg
- L{SSHUserAuthServer<twisted.conch.ssh.userauth.SSHUserAuthServer>}) which
- attempts to log in using
- L{ISSHPrivateKey<twisted.cred.credentials.ISSHPrivateKey>} credentials
- should be prepared to handle a failure of this type by telling the user to
- re-authenticate using the same key and to include a signature with the new
- attempt.
-
- See U{http://www.ietf.org/rfc/rfc4252.txt} section 7 for more details.
- """
-
-
-
-class IgnoreAuthentication(Exception):
- """
- This is thrown to let the UserAuthServer know it doesn't need to handle the
- authentication anymore.
- """
-
-
-
-class MissingKeyStoreError(Exception):
- """
- Raised if an SSHAgentServer starts receiving data without its factory
- providing a keys dict on which to read/write key data.
- """
-
-
-
-class UserRejectedKey(Exception):
- """
- The user interactively rejected a key.
- """
-
-
-
-class InvalidEntry(Exception):
- """
- An entry in a known_hosts file could not be interpreted as a valid entry.
- """
-
-
-
-class HostKeyChanged(Exception):
- """
- The host key of a remote host has changed.
-
- @ivar offendingEntry: The entry which contains the persistent host key that
- disagrees with the given host key.
-
- @type offendingEntry: L{twisted.conch.interfaces.IKnownHostEntry}
-
- @ivar path: a reference to the known_hosts file that the offending entry
- was loaded from
-
- @type path: L{twisted.python.filepath.FilePath}
-
- @ivar lineno: The line number of the offending entry in the given path.
-
- @type lineno: L{int}
- """
- def __init__(self, offendingEntry, path, lineno):
- Exception.__init__(self)
- self.offendingEntry = offendingEntry
- self.path = path
- self.lineno = lineno
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py
deleted file mode 100755
index c070d4f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Insults: a replacement for Curses/S-Lang.
-
-Very basic at the moment."""
-
-from twisted.python import deprecate, versions
-
-deprecate.deprecatedModuleAttribute(
- versions.Version("Twisted", 10, 1, 0),
- "Please use twisted.conch.insults.helper instead.",
- __name__, "colors")
-
-deprecate.deprecatedModuleAttribute(
- versions.Version("Twisted", 10, 1, 0),
- "Please use twisted.conch.insults.insults instead.",
- __name__, "client")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py
deleted file mode 100755
index 89c79cda..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py
+++ /dev/null
@@ -1,138 +0,0 @@
-"""
-You don't really want to use this module. Try insults.py instead.
-"""
-
-from twisted.internet import protocol
-
-class InsultsClient(protocol.Protocol):
-
- escapeTimeout = 0.2
-
- def __init__(self):
- self.width = self.height = None
- self.xpos = self.ypos = 0
- self.commandQueue = []
- self.inEscape = ''
-
- def setSize(self, width, height):
- call = 0
- if self.width:
- call = 1
- self.width = width
- self.height = height
- if call:
- self.windowSizeChanged()
-
- def dataReceived(self, data):
- from twisted.internet import reactor
- for ch in data:
- if ch == '\x1b':
- if self.inEscape:
- self.keyReceived(ch)
- self.inEscape = ''
- else:
- self.inEscape = ch
- self.escapeCall = reactor.callLater(self.escapeTimeout,
- self.endEscape)
- elif ch in 'ABCD' and self.inEscape:
- self.inEscape = ''
- self.escapeCall.cancel()
- if ch == 'A':
- self.keyReceived('<Up>')
- elif ch == 'B':
- self.keyReceived('<Down>')
- elif ch == 'C':
- self.keyReceived('<Right>')
- elif ch == 'D':
- self.keyReceived('<Left>')
- elif self.inEscape:
- self.inEscape += ch
- else:
- self.keyReceived(ch)
-
- def endEscape(self):
- ch = self.inEscape
- self.inEscape = ''
- self.keyReceived(ch)
-
- def initScreen(self):
- self.transport.write('\x1b=\x1b[?1h')
-
- def gotoXY(self, x, y):
- """Go to a position on the screen.
- """
- self.xpos = x
- self.ypos = y
- self.commandQueue.append(('gotoxy', x, y))
-
- def writeCh(self, ch):
- """Write a character to the screen. If we're at the end of the row,
- ignore the write.
- """
- if self.xpos < self.width - 1:
- self.commandQueue.append(('write', ch))
- self.xpos += 1
-
- def writeStr(self, s):
- """Write a string to the screen. This does not wrap a the edge of the
- screen, and stops at \\r and \\n.
- """
- s = s[:self.width-self.xpos]
- if '\n' in s:
- s=s[:s.find('\n')]
- if '\r' in s:
- s=s[:s.find('\r')]
- self.commandQueue.append(('write', s))
- self.xpos += len(s)
-
- def eraseToLine(self):
- """Erase from the current position to the end of the line.
- """
- self.commandQueue.append(('eraseeol',))
-
- def eraseToScreen(self):
- """Erase from the current position to the end of the screen.
- """
- self.commandQueue.append(('eraseeos',))
-
- def clearScreen(self):
- """Clear the screen, and return the cursor to 0, 0.
- """
- self.commandQueue = [('cls',)]
- self.xpos = self.ypos = 0
-
- def setAttributes(self, *attrs):
- """Set the attributes for drawing on the screen.
- """
- self.commandQueue.append(('attributes', attrs))
-
- def refresh(self):
- """Redraw the screen.
- """
- redraw = ''
- for command in self.commandQueue:
- if command[0] == 'gotoxy':
- redraw += '\x1b[%i;%iH' % (command[2]+1, command[1]+1)
- elif command[0] == 'write':
- redraw += command[1]
- elif command[0] == 'eraseeol':
- redraw += '\x1b[0K'
- elif command[0] == 'eraseeos':
- redraw += '\x1b[OJ'
- elif command[0] == 'cls':
- redraw += '\x1b[H\x1b[J'
- elif command[0] == 'attributes':
- redraw += '\x1b[%sm' % ';'.join(map(str, command[1]))
- else:
- print command
- self.commandQueue = []
- self.transport.write(redraw)
-
- def windowSizeChanged(self):
- """Called when the size of the window changes.
- Might want to redraw the screen here, or something.
- """
-
- def keyReceived(self, key):
- """Called when the user hits a key.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py
deleted file mode 100755
index c12ab16f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py
+++ /dev/null
@@ -1,29 +0,0 @@
-"""
-You don't really want to use this module. Try helper.py instead.
-"""
-
-CLEAR = 0
-BOLD = 1
-DIM = 2
-ITALIC = 3
-UNDERSCORE = 4
-BLINK_SLOW = 5
-BLINK_FAST = 6
-REVERSE = 7
-CONCEALED = 8
-FG_BLACK = 30
-FG_RED = 31
-FG_GREEN = 32
-FG_YELLOW = 33
-FG_BLUE = 34
-FG_MAGENTA = 35
-FG_CYAN = 36
-FG_WHITE = 37
-BG_BLACK = 40
-BG_RED = 41
-BG_GREEN = 42
-BG_YELLOW = 43
-BG_BLUE = 44
-BG_MAGENTA = 45
-BG_CYAN = 46
-BG_WHITE = 47
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py
deleted file mode 100755
index ed645c48..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py
+++ /dev/null
@@ -1,450 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_helper -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Partial in-memory terminal emulator
-
-@author: Jp Calderone
-"""
-
-import re, string
-
-from zope.interface import implements
-
-from twisted.internet import defer, protocol, reactor
-from twisted.python import log
-
-from twisted.conch.insults import insults
-
-FOREGROUND = 30
-BACKGROUND = 40
-BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, N_COLORS = range(9)
-
-class CharacterAttribute:
- """Represents the attributes of a single character.
-
- Character set, intensity, underlinedness, blinkitude, video
- reversal, as well as foreground and background colors made up a
- character's attributes.
- """
- def __init__(self, charset=insults.G0,
- bold=False, underline=False,
- blink=False, reverseVideo=False,
- foreground=WHITE, background=BLACK,
-
- _subtracting=False):
- self.charset = charset
- self.bold = bold
- self.underline = underline
- self.blink = blink
- self.reverseVideo = reverseVideo
- self.foreground = foreground
- self.background = background
-
- self._subtracting = _subtracting
-
- def __eq__(self, other):
- return vars(self) == vars(other)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def copy(self):
- c = self.__class__()
- c.__dict__.update(vars(self))
- return c
-
- def wantOne(self, **kw):
- k, v = kw.popitem()
- if getattr(self, k) != v:
- attr = self.copy()
- attr._subtracting = not v
- setattr(attr, k, v)
- return attr
- else:
- return self.copy()
-
- def toVT102(self):
- # Spit out a vt102 control sequence that will set up
- # all the attributes set here. Except charset.
- attrs = []
- if self._subtracting:
- attrs.append(0)
- if self.bold:
- attrs.append(insults.BOLD)
- if self.underline:
- attrs.append(insults.UNDERLINE)
- if self.blink:
- attrs.append(insults.BLINK)
- if self.reverseVideo:
- attrs.append(insults.REVERSE_VIDEO)
- if self.foreground != WHITE:
- attrs.append(FOREGROUND + self.foreground)
- if self.background != BLACK:
- attrs.append(BACKGROUND + self.background)
- if attrs:
- return '\x1b[' + ';'.join(map(str, attrs)) + 'm'
- return ''
-
-# XXX - need to support scroll regions and scroll history
-class TerminalBuffer(protocol.Protocol):
- """
- An in-memory terminal emulator.
- """
- implements(insults.ITerminalTransport)
-
- for keyID in ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW',
- 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN',
- 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
- 'F10', 'F11', 'F12'):
- exec '%s = object()' % (keyID,)
-
- TAB = '\t'
- BACKSPACE = '\x7f'
-
- width = 80
- height = 24
-
- fill = ' '
- void = object()
-
- def getCharacter(self, x, y):
- return self.lines[y][x]
-
- def connectionMade(self):
- self.reset()
-
- def write(self, bytes):
- """
- Add the given printable bytes to the terminal.
-
- Line feeds in C{bytes} will be replaced with carriage return / line
- feed pairs.
- """
- for b in bytes.replace('\n', '\r\n'):
- self.insertAtCursor(b)
-
- def _currentCharacterAttributes(self):
- return CharacterAttribute(self.activeCharset, **self.graphicRendition)
-
- def insertAtCursor(self, b):
- """
- Add one byte to the terminal at the cursor and make consequent state
- updates.
-
- If b is a carriage return, move the cursor to the beginning of the
- current row.
-
- If b is a line feed, move the cursor to the next row or scroll down if
- the cursor is already in the last row.
-
- Otherwise, if b is printable, put it at the cursor position (inserting
- or overwriting as dictated by the current mode) and move the cursor.
- """
- if b == '\r':
- self.x = 0
- elif b == '\n':
- self._scrollDown()
- elif b in string.printable:
- if self.x >= self.width:
- self.nextLine()
- ch = (b, self._currentCharacterAttributes())
- if self.modes.get(insults.modes.IRM):
- self.lines[self.y][self.x:self.x] = [ch]
- self.lines[self.y].pop()
- else:
- self.lines[self.y][self.x] = ch
- self.x += 1
-
- def _emptyLine(self, width):
- return [(self.void, self._currentCharacterAttributes()) for i in xrange(width)]
-
- def _scrollDown(self):
- self.y += 1
- if self.y >= self.height:
- self.y -= 1
- del self.lines[0]
- self.lines.append(self._emptyLine(self.width))
-
- def _scrollUp(self):
- self.y -= 1
- if self.y < 0:
- self.y = 0
- del self.lines[-1]
- self.lines.insert(0, self._emptyLine(self.width))
-
- def cursorUp(self, n=1):
- self.y = max(0, self.y - n)
-
- def cursorDown(self, n=1):
- self.y = min(self.height - 1, self.y + n)
-
- def cursorBackward(self, n=1):
- self.x = max(0, self.x - n)
-
- def cursorForward(self, n=1):
- self.x = min(self.width, self.x + n)
-
- def cursorPosition(self, column, line):
- self.x = column
- self.y = line
-
- def cursorHome(self):
- self.x = self.home.x
- self.y = self.home.y
-
- def index(self):
- self._scrollDown()
-
- def reverseIndex(self):
- self._scrollUp()
-
- def nextLine(self):
- """
- Update the cursor position attributes and scroll down if appropriate.
- """
- self.x = 0
- self._scrollDown()
-
- def saveCursor(self):
- self._savedCursor = (self.x, self.y)
-
- def restoreCursor(self):
- self.x, self.y = self._savedCursor
- del self._savedCursor
-
- def setModes(self, modes):
- for m in modes:
- self.modes[m] = True
-
- def resetModes(self, modes):
- for m in modes:
- try:
- del self.modes[m]
- except KeyError:
- pass
-
-
- def setPrivateModes(self, modes):
- """
- Enable the given modes.
-
- Track which modes have been enabled so that the implementations of
- other L{insults.ITerminalTransport} methods can be properly implemented
- to respect these settings.
-
- @see: L{resetPrivateModes}
- @see: L{insults.ITerminalTransport.setPrivateModes}
- """
- for m in modes:
- self.privateModes[m] = True
-
-
- def resetPrivateModes(self, modes):
- """
- Disable the given modes.
-
- @see: L{setPrivateModes}
- @see: L{insults.ITerminalTransport.resetPrivateModes}
- """
- for m in modes:
- try:
- del self.privateModes[m]
- except KeyError:
- pass
-
-
- def applicationKeypadMode(self):
- self.keypadMode = 'app'
-
- def numericKeypadMode(self):
- self.keypadMode = 'num'
-
- def selectCharacterSet(self, charSet, which):
- self.charsets[which] = charSet
-
- def shiftIn(self):
- self.activeCharset = insults.G0
-
- def shiftOut(self):
- self.activeCharset = insults.G1
-
- def singleShift2(self):
- oldActiveCharset = self.activeCharset
- self.activeCharset = insults.G2
- f = self.insertAtCursor
- def insertAtCursor(b):
- f(b)
- del self.insertAtCursor
- self.activeCharset = oldActiveCharset
- self.insertAtCursor = insertAtCursor
-
- def singleShift3(self):
- oldActiveCharset = self.activeCharset
- self.activeCharset = insults.G3
- f = self.insertAtCursor
- def insertAtCursor(b):
- f(b)
- del self.insertAtCursor
- self.activeCharset = oldActiveCharset
- self.insertAtCursor = insertAtCursor
-
- def selectGraphicRendition(self, *attributes):
- for a in attributes:
- if a == insults.NORMAL:
- self.graphicRendition = {
- 'bold': False,
- 'underline': False,
- 'blink': False,
- 'reverseVideo': False,
- 'foreground': WHITE,
- 'background': BLACK}
- elif a == insults.BOLD:
- self.graphicRendition['bold'] = True
- elif a == insults.UNDERLINE:
- self.graphicRendition['underline'] = True
- elif a == insults.BLINK:
- self.graphicRendition['blink'] = True
- elif a == insults.REVERSE_VIDEO:
- self.graphicRendition['reverseVideo'] = True
- else:
- try:
- v = int(a)
- except ValueError:
- log.msg("Unknown graphic rendition attribute: " + repr(a))
- else:
- if FOREGROUND <= v <= FOREGROUND + N_COLORS:
- self.graphicRendition['foreground'] = v - FOREGROUND
- elif BACKGROUND <= v <= BACKGROUND + N_COLORS:
- self.graphicRendition['background'] = v - BACKGROUND
- else:
- log.msg("Unknown graphic rendition attribute: " + repr(a))
-
- def eraseLine(self):
- self.lines[self.y] = self._emptyLine(self.width)
-
- def eraseToLineEnd(self):
- width = self.width - self.x
- self.lines[self.y][self.x:] = self._emptyLine(width)
-
- def eraseToLineBeginning(self):
- self.lines[self.y][:self.x + 1] = self._emptyLine(self.x + 1)
-
- def eraseDisplay(self):
- self.lines = [self._emptyLine(self.width) for i in xrange(self.height)]
-
- def eraseToDisplayEnd(self):
- self.eraseToLineEnd()
- height = self.height - self.y - 1
- self.lines[self.y + 1:] = [self._emptyLine(self.width) for i in range(height)]
-
- def eraseToDisplayBeginning(self):
- self.eraseToLineBeginning()
- self.lines[:self.y] = [self._emptyLine(self.width) for i in range(self.y)]
-
- def deleteCharacter(self, n=1):
- del self.lines[self.y][self.x:self.x+n]
- self.lines[self.y].extend(self._emptyLine(min(self.width - self.x, n)))
-
- def insertLine(self, n=1):
- self.lines[self.y:self.y] = [self._emptyLine(self.width) for i in range(n)]
- del self.lines[self.height:]
-
- def deleteLine(self, n=1):
- del self.lines[self.y:self.y+n]
- self.lines.extend([self._emptyLine(self.width) for i in range(n)])
-
- def reportCursorPosition(self):
- return (self.x, self.y)
-
- def reset(self):
- self.home = insults.Vector(0, 0)
- self.x = self.y = 0
- self.modes = {}
- self.privateModes = {}
- self.setPrivateModes([insults.privateModes.AUTO_WRAP,
- insults.privateModes.CURSOR_MODE])
- self.numericKeypad = 'app'
- self.activeCharset = insults.G0
- self.graphicRendition = {
- 'bold': False,
- 'underline': False,
- 'blink': False,
- 'reverseVideo': False,
- 'foreground': WHITE,
- 'background': BLACK}
- self.charsets = {
- insults.G0: insults.CS_US,
- insults.G1: insults.CS_US,
- insults.G2: insults.CS_ALTERNATE,
- insults.G3: insults.CS_ALTERNATE_SPECIAL}
- self.eraseDisplay()
-
- def unhandledControlSequence(self, buf):
- print 'Could not handle', repr(buf)
-
- def __str__(self):
- lines = []
- for L in self.lines:
- buf = []
- length = 0
- for (ch, attr) in L:
- if ch is not self.void:
- buf.append(ch)
- length = len(buf)
- else:
- buf.append(self.fill)
- lines.append(''.join(buf[:length]))
- return '\n'.join(lines)
-
-class ExpectationTimeout(Exception):
- pass
-
-class ExpectableBuffer(TerminalBuffer):
- _mark = 0
-
- def connectionMade(self):
- TerminalBuffer.connectionMade(self)
- self._expecting = []
-
- def write(self, bytes):
- TerminalBuffer.write(self, bytes)
- self._checkExpected()
-
- def cursorHome(self):
- TerminalBuffer.cursorHome(self)
- self._mark = 0
-
- def _timeoutExpected(self, d):
- d.errback(ExpectationTimeout())
- self._checkExpected()
-
- def _checkExpected(self):
- s = str(self)[self._mark:]
- while self._expecting:
- expr, timer, deferred = self._expecting[0]
- if timer and not timer.active():
- del self._expecting[0]
- continue
- for match in expr.finditer(s):
- if timer:
- timer.cancel()
- del self._expecting[0]
- self._mark += match.end()
- s = s[match.end():]
- deferred.callback(match)
- break
- else:
- return
-
- def expect(self, expression, timeout=None, scheduler=reactor):
- d = defer.Deferred()
- timer = None
- if timeout:
- timer = scheduler.callLater(timeout, self._timeoutExpected, d)
- self._expecting.append((re.compile(expression), timer, d))
- self._checkExpected()
- return d
-
-__all__ = ['CharacterAttribute', 'TerminalBuffer', 'ExpectableBuffer']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py
deleted file mode 100755
index 721551de..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py
+++ /dev/null
@@ -1,1087 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_insults -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-VT102 and VT220 terminal manipulation.
-
-@author: Jp Calderone
-"""
-
-from zope.interface import implements, Interface
-
-from twisted.internet import protocol, defer, interfaces as iinternet
-
-class ITerminalProtocol(Interface):
- def makeConnection(transport):
- """Called with an L{ITerminalTransport} when a connection is established.
- """
-
- def keystrokeReceived(keyID, modifier):
- """A keystroke was received.
-
- Each keystroke corresponds to one invocation of this method.
- keyID is a string identifier for that key. Printable characters
- are represented by themselves. Control keys, such as arrows and
- function keys, are represented with symbolic constants on
- L{ServerProtocol}.
- """
-
- def terminalSize(width, height):
- """Called to indicate the size of the terminal.
-
- A terminal of 80x24 should be assumed if this method is not
- called. This method might not be called for real terminals.
- """
-
- def unhandledControlSequence(seq):
- """Called when an unsupported control sequence is received.
-
- @type seq: C{str}
- @param seq: The whole control sequence which could not be interpreted.
- """
-
- def connectionLost(reason):
- """Called when the connection has been lost.
-
- reason is a Failure describing why.
- """
-
-class TerminalProtocol(object):
- implements(ITerminalProtocol)
-
- def makeConnection(self, terminal):
- # assert ITerminalTransport.providedBy(transport), "TerminalProtocol.makeConnection must be passed an ITerminalTransport implementor"
- self.terminal = terminal
- self.connectionMade()
-
- def connectionMade(self):
- """Called after a connection has been established.
- """
-
- def keystrokeReceived(self, keyID, modifier):
- pass
-
- def terminalSize(self, width, height):
- pass
-
- def unhandledControlSequence(self, seq):
- pass
-
- def connectionLost(self, reason):
- pass
-
-class ITerminalTransport(iinternet.ITransport):
- def cursorUp(n=1):
- """Move the cursor up n lines.
- """
-
- def cursorDown(n=1):
- """Move the cursor down n lines.
- """
-
- def cursorForward(n=1):
- """Move the cursor right n columns.
- """
-
- def cursorBackward(n=1):
- """Move the cursor left n columns.
- """
-
- def cursorPosition(column, line):
- """Move the cursor to the given line and column.
- """
-
- def cursorHome():
- """Move the cursor home.
- """
-
- def index():
- """Move the cursor down one line, performing scrolling if necessary.
- """
-
- def reverseIndex():
- """Move the cursor up one line, performing scrolling if necessary.
- """
-
- def nextLine():
- """Move the cursor to the first position on the next line, performing scrolling if necessary.
- """
-
- def saveCursor():
- """Save the cursor position, character attribute, character set, and origin mode selection.
- """
-
- def restoreCursor():
- """Restore the previously saved cursor position, character attribute, character set, and origin mode selection.
-
- If no cursor state was previously saved, move the cursor to the home position.
- """
-
- def setModes(modes):
- """Set the given modes on the terminal.
- """
-
- def resetModes(mode):
- """Reset the given modes on the terminal.
- """
-
-
- def setPrivateModes(modes):
- """
- Set the given DEC private modes on the terminal.
- """
-
-
- def resetPrivateModes(modes):
- """
- Reset the given DEC private modes on the terminal.
- """
-
-
- def applicationKeypadMode():
- """Cause keypad to generate control functions.
-
- Cursor key mode selects the type of characters generated by cursor keys.
- """
-
- def numericKeypadMode():
- """Cause keypad to generate normal characters.
- """
-
- def selectCharacterSet(charSet, which):
- """Select a character set.
-
- charSet should be one of CS_US, CS_UK, CS_DRAWING, CS_ALTERNATE, or
- CS_ALTERNATE_SPECIAL.
-
- which should be one of G0 or G1.
- """
-
- def shiftIn():
- """Activate the G0 character set.
- """
-
- def shiftOut():
- """Activate the G1 character set.
- """
-
- def singleShift2():
- """Shift to the G2 character set for a single character.
- """
-
- def singleShift3():
- """Shift to the G3 character set for a single character.
- """
-
- def selectGraphicRendition(*attributes):
- """Enabled one or more character attributes.
-
- Arguments should be one or more of UNDERLINE, REVERSE_VIDEO, BLINK, or BOLD.
- NORMAL may also be specified to disable all character attributes.
- """
-
- def horizontalTabulationSet():
- """Set a tab stop at the current cursor position.
- """
-
- def tabulationClear():
- """Clear the tab stop at the current cursor position.
- """
-
- def tabulationClearAll():
- """Clear all tab stops.
- """
-
- def doubleHeightLine(top=True):
- """Make the current line the top or bottom half of a double-height, double-width line.
-
- If top is True, the current line is the top half. Otherwise, it is the bottom half.
- """
-
- def singleWidthLine():
- """Make the current line a single-width, single-height line.
- """
-
- def doubleWidthLine():
- """Make the current line a double-width line.
- """
-
- def eraseToLineEnd():
- """Erase from the cursor to the end of line, including cursor position.
- """
-
- def eraseToLineBeginning():
- """Erase from the cursor to the beginning of the line, including the cursor position.
- """
-
- def eraseLine():
- """Erase the entire cursor line.
- """
-
- def eraseToDisplayEnd():
- """Erase from the cursor to the end of the display, including the cursor position.
- """
-
- def eraseToDisplayBeginning():
- """Erase from the cursor to the beginning of the display, including the cursor position.
- """
-
- def eraseDisplay():
- """Erase the entire display.
- """
-
- def deleteCharacter(n=1):
- """Delete n characters starting at the cursor position.
-
- Characters to the right of deleted characters are shifted to the left.
- """
-
- def insertLine(n=1):
- """Insert n lines at the cursor position.
-
- Lines below the cursor are shifted down. Lines moved past the bottom margin are lost.
- This command is ignored when the cursor is outside the scroll region.
- """
-
- def deleteLine(n=1):
- """Delete n lines starting at the cursor position.
-
- Lines below the cursor are shifted up. This command is ignored when the cursor is outside
- the scroll region.
- """
-
- def reportCursorPosition():
- """Return a Deferred that fires with a two-tuple of (x, y) indicating the cursor position.
- """
-
- def reset():
- """Reset the terminal to its initial state.
- """
-
- def unhandledControlSequence(seq):
- """Called when an unsupported control sequence is received.
-
- @type seq: C{str}
- @param seq: The whole control sequence which could not be interpreted.
- """
-
-
-CSI = '\x1b'
-CST = {'~': 'tilde'}
-
-class modes:
- """ECMA 48 standardized modes
- """
-
- # BREAKS YOPUR KEYBOARD MOFO
- KEYBOARD_ACTION = KAM = 2
-
- # When set, enables character insertion. New display characters
- # move old display characters to the right. Characters moved past
- # the right margin are lost.
-
- # When reset, enables replacement mode (disables character
- # insertion). New display characters replace old display
- # characters at cursor position. The old character is erased.
- INSERTION_REPLACEMENT = IRM = 4
-
- # Set causes a received linefeed, form feed, or vertical tab to
- # move cursor to first column of next line. RETURN transmits both
- # a carriage return and linefeed. This selection is also called
- # new line option.
-
- # Reset causes a received linefeed, form feed, or vertical tab to
- # move cursor to next line in current column. RETURN transmits a
- # carriage return.
- LINEFEED_NEWLINE = LNM = 20
-
-
-class privateModes:
- """ANSI-Compatible Private Modes
- """
- ERROR = 0
- CURSOR_KEY = 1
- ANSI_VT52 = 2
- COLUMN = 3
- SCROLL = 4
- SCREEN = 5
- ORIGIN = 6
- AUTO_WRAP = 7
- AUTO_REPEAT = 8
- PRINTER_FORM_FEED = 18
- PRINTER_EXTENT = 19
-
- # Toggle cursor visibility (reset hides it)
- CURSOR_MODE = 25
-
-
-# Character sets
-CS_US = 'CS_US'
-CS_UK = 'CS_UK'
-CS_DRAWING = 'CS_DRAWING'
-CS_ALTERNATE = 'CS_ALTERNATE'
-CS_ALTERNATE_SPECIAL = 'CS_ALTERNATE_SPECIAL'
-
-# Groupings (or something?? These are like variables that can be bound to character sets)
-G0 = 'G0'
-G1 = 'G1'
-
-# G2 and G3 cannot be changed, but they can be shifted to.
-G2 = 'G2'
-G3 = 'G3'
-
-# Character attributes
-
-NORMAL = 0
-BOLD = 1
-UNDERLINE = 4
-BLINK = 5
-REVERSE_VIDEO = 7
-
-class Vector:
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
-def log(s):
- file('log', 'a').write(str(s) + '\n')
-
-# XXX TODO - These attributes are really part of the
-# ITerminalTransport interface, I think.
-_KEY_NAMES = ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW',
- 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN', 'NUMPAD_MIDDLE',
- 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
- 'F10', 'F11', 'F12',
-
- 'ALT', 'SHIFT', 'CONTROL')
-
-class _const(object):
- """
- @ivar name: A string naming this constant
- """
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return '[' + self.name + ']'
-
-
-FUNCTION_KEYS = [
- _const(_name) for _name in _KEY_NAMES]
-
-class ServerProtocol(protocol.Protocol):
- implements(ITerminalTransport)
-
- protocolFactory = None
- terminalProtocol = None
-
- TAB = '\t'
- BACKSPACE = '\x7f'
- ##
-
- lastWrite = ''
-
- state = 'data'
-
- termSize = Vector(80, 24)
- cursorPos = Vector(0, 0)
- scrollRegion = None
-
- # Factory who instantiated me
- factory = None
-
- def __init__(self, protocolFactory=None, *a, **kw):
- """
- @param protocolFactory: A callable which will be invoked with
- *a, **kw and should return an ITerminalProtocol implementor.
- This will be invoked when a connection to this ServerProtocol
- is established.
-
- @param a: Any positional arguments to pass to protocolFactory.
- @param kw: Any keyword arguments to pass to protocolFactory.
- """
- # assert protocolFactory is None or ITerminalProtocol.implementedBy(protocolFactory), "ServerProtocol.__init__ must be passed an ITerminalProtocol implementor"
- if protocolFactory is not None:
- self.protocolFactory = protocolFactory
- self.protocolArgs = a
- self.protocolKwArgs = kw
-
- self._cursorReports = []
-
- def connectionMade(self):
- if self.protocolFactory is not None:
- self.terminalProtocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs)
-
- try:
- factory = self.factory
- except AttributeError:
- pass
- else:
- self.terminalProtocol.factory = factory
-
- self.terminalProtocol.makeConnection(self)
-
- def dataReceived(self, data):
- for ch in data:
- if self.state == 'data':
- if ch == '\x1b':
- self.state = 'escaped'
- else:
- self.terminalProtocol.keystrokeReceived(ch, None)
- elif self.state == 'escaped':
- if ch == '[':
- self.state = 'bracket-escaped'
- self.escBuf = []
- elif ch == 'O':
- self.state = 'low-function-escaped'
- else:
- self.state = 'data'
- self._handleShortControlSequence(ch)
- elif self.state == 'bracket-escaped':
- if ch == 'O':
- self.state = 'low-function-escaped'
- elif ch.isalpha() or ch == '~':
- self._handleControlSequence(''.join(self.escBuf) + ch)
- del self.escBuf
- self.state = 'data'
- else:
- self.escBuf.append(ch)
- elif self.state == 'low-function-escaped':
- self._handleLowFunctionControlSequence(ch)
- self.state = 'data'
- else:
- raise ValueError("Illegal state")
-
- def _handleShortControlSequence(self, ch):
- self.terminalProtocol.keystrokeReceived(ch, self.ALT)
-
- def _handleControlSequence(self, buf):
- buf = '\x1b[' + buf
- f = getattr(self.controlSequenceParser, CST.get(buf[-1], buf[-1]), None)
- if f is None:
- self.unhandledControlSequence(buf)
- else:
- f(self, self.terminalProtocol, buf[:-1])
-
- def unhandledControlSequence(self, buf):
- self.terminalProtocol.unhandledControlSequence(buf)
-
- def _handleLowFunctionControlSequence(self, ch):
- map = {'P': self.F1, 'Q': self.F2, 'R': self.F3, 'S': self.F4}
- keyID = map.get(ch)
- if keyID is not None:
- self.terminalProtocol.keystrokeReceived(keyID, None)
- else:
- self.terminalProtocol.unhandledControlSequence('\x1b[O' + ch)
-
- class ControlSequenceParser:
- def A(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.UP_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'A')
-
- def B(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.DOWN_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'B')
-
- def C(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.RIGHT_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'C')
-
- def D(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.LEFT_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'D')
-
- def E(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.NUMPAD_MIDDLE, None)
- else:
- handler.unhandledControlSequence(buf + 'E')
-
- def F(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.END, None)
- else:
- handler.unhandledControlSequence(buf + 'F')
-
- def H(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.HOME, None)
- else:
- handler.unhandledControlSequence(buf + 'H')
-
- def R(self, proto, handler, buf):
- if not proto._cursorReports:
- handler.unhandledControlSequence(buf + 'R')
- elif buf.startswith('\x1b['):
- report = buf[2:]
- parts = report.split(';')
- if len(parts) != 2:
- handler.unhandledControlSequence(buf + 'R')
- else:
- Pl, Pc = parts
- try:
- Pl, Pc = int(Pl), int(Pc)
- except ValueError:
- handler.unhandledControlSequence(buf + 'R')
- else:
- d = proto._cursorReports.pop(0)
- d.callback((Pc - 1, Pl - 1))
- else:
- handler.unhandledControlSequence(buf + 'R')
-
- def Z(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.TAB, proto.SHIFT)
- else:
- handler.unhandledControlSequence(buf + 'Z')
-
- def tilde(self, proto, handler, buf):
- map = {1: proto.HOME, 2: proto.INSERT, 3: proto.DELETE,
- 4: proto.END, 5: proto.PGUP, 6: proto.PGDN,
-
- 15: proto.F5, 17: proto.F6, 18: proto.F7,
- 19: proto.F8, 20: proto.F9, 21: proto.F10,
- 23: proto.F11, 24: proto.F12}
-
- if buf.startswith('\x1b['):
- ch = buf[2:]
- try:
- v = int(ch)
- except ValueError:
- handler.unhandledControlSequence(buf + '~')
- else:
- symbolic = map.get(v)
- if symbolic is not None:
- handler.keystrokeReceived(map[v], None)
- else:
- handler.unhandledControlSequence(buf + '~')
- else:
- handler.unhandledControlSequence(buf + '~')
-
- controlSequenceParser = ControlSequenceParser()
-
- # ITerminalTransport
- def cursorUp(self, n=1):
- assert n >= 1
- self.cursorPos.y = max(self.cursorPos.y - n, 0)
- self.write('\x1b[%dA' % (n,))
-
- def cursorDown(self, n=1):
- assert n >= 1
- self.cursorPos.y = min(self.cursorPos.y + n, self.termSize.y - 1)
- self.write('\x1b[%dB' % (n,))
-
- def cursorForward(self, n=1):
- assert n >= 1
- self.cursorPos.x = min(self.cursorPos.x + n, self.termSize.x - 1)
- self.write('\x1b[%dC' % (n,))
-
- def cursorBackward(self, n=1):
- assert n >= 1
- self.cursorPos.x = max(self.cursorPos.x - n, 0)
- self.write('\x1b[%dD' % (n,))
-
- def cursorPosition(self, column, line):
- self.write('\x1b[%d;%dH' % (line + 1, column + 1))
-
- def cursorHome(self):
- self.cursorPos.x = self.cursorPos.y = 0
- self.write('\x1b[H')
-
- def index(self):
- self.cursorPos.y = min(self.cursorPos.y + 1, self.termSize.y - 1)
- self.write('\x1bD')
-
- def reverseIndex(self):
- self.cursorPos.y = max(self.cursorPos.y - 1, 0)
- self.write('\x1bM')
-
- def nextLine(self):
- self.cursorPos.x = 0
- self.cursorPos.y = min(self.cursorPos.y + 1, self.termSize.y - 1)
- self.write('\n')
-
- def saveCursor(self):
- self._savedCursorPos = Vector(self.cursorPos.x, self.cursorPos.y)
- self.write('\x1b7')
-
- def restoreCursor(self):
- self.cursorPos = self._savedCursorPos
- del self._savedCursorPos
- self.write('\x1b8')
-
- def setModes(self, modes):
- # XXX Support ANSI-Compatible private modes
- self.write('\x1b[%sh' % (';'.join(map(str, modes)),))
-
- def setPrivateModes(self, modes):
- self.write('\x1b[?%sh' % (';'.join(map(str, modes)),))
-
- def resetModes(self, modes):
- # XXX Support ANSI-Compatible private modes
- self.write('\x1b[%sl' % (';'.join(map(str, modes)),))
-
- def resetPrivateModes(self, modes):
- self.write('\x1b[?%sl' % (';'.join(map(str, modes)),))
-
- def applicationKeypadMode(self):
- self.write('\x1b=')
-
- def numericKeypadMode(self):
- self.write('\x1b>')
-
- def selectCharacterSet(self, charSet, which):
- # XXX Rewrite these as dict lookups
- if which == G0:
- which = '('
- elif which == G1:
- which = ')'
- else:
- raise ValueError("`which' argument to selectCharacterSet must be G0 or G1")
- if charSet == CS_UK:
- charSet = 'A'
- elif charSet == CS_US:
- charSet = 'B'
- elif charSet == CS_DRAWING:
- charSet = '0'
- elif charSet == CS_ALTERNATE:
- charSet = '1'
- elif charSet == CS_ALTERNATE_SPECIAL:
- charSet = '2'
- else:
- raise ValueError("Invalid `charSet' argument to selectCharacterSet")
- self.write('\x1b' + which + charSet)
-
- def shiftIn(self):
- self.write('\x15')
-
- def shiftOut(self):
- self.write('\x14')
-
- def singleShift2(self):
- self.write('\x1bN')
-
- def singleShift3(self):
- self.write('\x1bO')
-
- def selectGraphicRendition(self, *attributes):
- attrs = []
- for a in attributes:
- attrs.append(a)
- self.write('\x1b[%sm' % (';'.join(attrs),))
-
- def horizontalTabulationSet(self):
- self.write('\x1bH')
-
- def tabulationClear(self):
- self.write('\x1b[q')
-
- def tabulationClearAll(self):
- self.write('\x1b[3q')
-
- def doubleHeightLine(self, top=True):
- if top:
- self.write('\x1b#3')
- else:
- self.write('\x1b#4')
-
- def singleWidthLine(self):
- self.write('\x1b#5')
-
- def doubleWidthLine(self):
- self.write('\x1b#6')
-
- def eraseToLineEnd(self):
- self.write('\x1b[K')
-
- def eraseToLineBeginning(self):
- self.write('\x1b[1K')
-
- def eraseLine(self):
- self.write('\x1b[2K')
-
- def eraseToDisplayEnd(self):
- self.write('\x1b[J')
-
- def eraseToDisplayBeginning(self):
- self.write('\x1b[1J')
-
- def eraseDisplay(self):
- self.write('\x1b[2J')
-
- def deleteCharacter(self, n=1):
- self.write('\x1b[%dP' % (n,))
-
- def insertLine(self, n=1):
- self.write('\x1b[%dL' % (n,))
-
- def deleteLine(self, n=1):
- self.write('\x1b[%dM' % (n,))
-
- def setScrollRegion(self, first=None, last=None):
- if first is not None:
- first = '%d' % (first,)
- else:
- first = ''
- if last is not None:
- last = '%d' % (last,)
- else:
- last = ''
- self.write('\x1b[%s;%sr' % (first, last))
-
- def resetScrollRegion(self):
- self.setScrollRegion()
-
- def reportCursorPosition(self):
- d = defer.Deferred()
- self._cursorReports.append(d)
- self.write('\x1b[6n')
- return d
-
- def reset(self):
- self.cursorPos.x = self.cursorPos.y = 0
- try:
- del self._savedCursorPos
- except AttributeError:
- pass
- self.write('\x1bc')
-
- # ITransport
- def write(self, bytes):
- if bytes:
- self.lastWrite = bytes
- self.transport.write('\r\n'.join(bytes.split('\n')))
-
- def writeSequence(self, bytes):
- self.write(''.join(bytes))
-
- def loseConnection(self):
- self.reset()
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- if self.terminalProtocol is not None:
- try:
- self.terminalProtocol.connectionLost(reason)
- finally:
- self.terminalProtocol = None
-# Add symbolic names for function keys
-for name, const in zip(_KEY_NAMES, FUNCTION_KEYS):
- setattr(ServerProtocol, name, const)
-
-
-
-class ClientProtocol(protocol.Protocol):
-
- terminalFactory = None
- terminal = None
-
- state = 'data'
-
- _escBuf = None
-
- _shorts = {
- 'D': 'index',
- 'M': 'reverseIndex',
- 'E': 'nextLine',
- '7': 'saveCursor',
- '8': 'restoreCursor',
- '=': 'applicationKeypadMode',
- '>': 'numericKeypadMode',
- 'N': 'singleShift2',
- 'O': 'singleShift3',
- 'H': 'horizontalTabulationSet',
- 'c': 'reset'}
-
- _longs = {
- '[': 'bracket-escape',
- '(': 'select-g0',
- ')': 'select-g1',
- '#': 'select-height-width'}
-
- _charsets = {
- 'A': CS_UK,
- 'B': CS_US,
- '0': CS_DRAWING,
- '1': CS_ALTERNATE,
- '2': CS_ALTERNATE_SPECIAL}
-
- # Factory who instantiated me
- factory = None
-
- def __init__(self, terminalFactory=None, *a, **kw):
- """
- @param terminalFactory: A callable which will be invoked with
- *a, **kw and should return an ITerminalTransport provider.
- This will be invoked when this ClientProtocol establishes a
- connection.
-
- @param a: Any positional arguments to pass to terminalFactory.
- @param kw: Any keyword arguments to pass to terminalFactory.
- """
- # assert terminalFactory is None or ITerminalTransport.implementedBy(terminalFactory), "ClientProtocol.__init__ must be passed an ITerminalTransport implementor"
- if terminalFactory is not None:
- self.terminalFactory = terminalFactory
- self.terminalArgs = a
- self.terminalKwArgs = kw
-
- def connectionMade(self):
- if self.terminalFactory is not None:
- self.terminal = self.terminalFactory(*self.terminalArgs, **self.terminalKwArgs)
- self.terminal.factory = self.factory
- self.terminal.makeConnection(self)
-
- def connectionLost(self, reason):
- if self.terminal is not None:
- try:
- self.terminal.connectionLost(reason)
- finally:
- del self.terminal
-
- def dataReceived(self, bytes):
- """
- Parse the given data from a terminal server, dispatching to event
- handlers defined by C{self.terminal}.
- """
- toWrite = []
- for b in bytes:
- if self.state == 'data':
- if b == '\x1b':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.state = 'escaped'
- elif b == '\x14':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.terminal.shiftOut()
- elif b == '\x15':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.terminal.shiftIn()
- elif b == '\x08':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.terminal.cursorBackward()
- else:
- toWrite.append(b)
- elif self.state == 'escaped':
- fName = self._shorts.get(b)
- if fName is not None:
- self.state = 'data'
- getattr(self.terminal, fName)()
- else:
- state = self._longs.get(b)
- if state is not None:
- self.state = state
- else:
- self.terminal.unhandledControlSequence('\x1b' + b)
- self.state = 'data'
- elif self.state == 'bracket-escape':
- if self._escBuf is None:
- self._escBuf = []
- if b.isalpha() or b == '~':
- self._handleControlSequence(''.join(self._escBuf), b)
- del self._escBuf
- self.state = 'data'
- else:
- self._escBuf.append(b)
- elif self.state == 'select-g0':
- self.terminal.selectCharacterSet(self._charsets.get(b, b), G0)
- self.state = 'data'
- elif self.state == 'select-g1':
- self.terminal.selectCharacterSet(self._charsets.get(b, b), G1)
- self.state = 'data'
- elif self.state == 'select-height-width':
- self._handleHeightWidth(b)
- self.state = 'data'
- else:
- raise ValueError("Illegal state")
- if toWrite:
- self.terminal.write(''.join(toWrite))
-
-
- def _handleControlSequence(self, buf, terminal):
- f = getattr(self.controlSequenceParser, CST.get(terminal, terminal), None)
- if f is None:
- self.terminal.unhandledControlSequence('\x1b[' + buf + terminal)
- else:
- f(self, self.terminal, buf)
-
- class ControlSequenceParser:
- def _makeSimple(ch, fName):
- n = 'cursor' + fName
- def simple(self, proto, handler, buf):
- if not buf:
- getattr(handler, n)(1)
- else:
- try:
- m = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + ch)
- else:
- getattr(handler, n)(m)
- return simple
- for (ch, fName) in (('A', 'Up'),
- ('B', 'Down'),
- ('C', 'Forward'),
- ('D', 'Backward')):
- exec ch + " = _makeSimple(ch, fName)"
- del _makeSimple
-
- def h(self, proto, handler, buf):
- # XXX - Handle '?' to introduce ANSI-Compatible private modes.
- try:
- modes = map(int, buf.split(';'))
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'h')
- else:
- handler.setModes(modes)
-
- def l(self, proto, handler, buf):
- # XXX - Handle '?' to introduce ANSI-Compatible private modes.
- try:
- modes = map(int, buf.split(';'))
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'l')
- else:
- handler.resetModes(modes)
-
- def r(self, proto, handler, buf):
- parts = buf.split(';')
- if len(parts) == 1:
- handler.setScrollRegion(None, None)
- elif len(parts) == 2:
- try:
- if parts[0]:
- pt = int(parts[0])
- else:
- pt = None
- if parts[1]:
- pb = int(parts[1])
- else:
- pb = None
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'r')
- else:
- handler.setScrollRegion(pt, pb)
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'r')
-
- def K(self, proto, handler, buf):
- if not buf:
- handler.eraseToLineEnd()
- elif buf == '1':
- handler.eraseToLineBeginning()
- elif buf == '2':
- handler.eraseLine()
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'K')
-
- def H(self, proto, handler, buf):
- handler.cursorHome()
-
- def J(self, proto, handler, buf):
- if not buf:
- handler.eraseToDisplayEnd()
- elif buf == '1':
- handler.eraseToDisplayBeginning()
- elif buf == '2':
- handler.eraseDisplay()
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'J')
-
- def P(self, proto, handler, buf):
- if not buf:
- handler.deleteCharacter(1)
- else:
- try:
- n = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'P')
- else:
- handler.deleteCharacter(n)
-
- def L(self, proto, handler, buf):
- if not buf:
- handler.insertLine(1)
- else:
- try:
- n = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'L')
- else:
- handler.insertLine(n)
-
- def M(self, proto, handler, buf):
- if not buf:
- handler.deleteLine(1)
- else:
- try:
- n = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'M')
- else:
- handler.deleteLine(n)
-
- def n(self, proto, handler, buf):
- if buf == '6':
- x, y = handler.reportCursorPosition()
- proto.transport.write('\x1b[%d;%dR' % (x + 1, y + 1))
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'n')
-
- def m(self, proto, handler, buf):
- if not buf:
- handler.selectGraphicRendition(NORMAL)
- else:
- attrs = []
- for a in buf.split(';'):
- try:
- a = int(a)
- except ValueError:
- pass
- attrs.append(a)
- handler.selectGraphicRendition(*attrs)
-
- controlSequenceParser = ControlSequenceParser()
-
- def _handleHeightWidth(self, b):
- if b == '3':
- self.terminal.doubleHeightLine(True)
- elif b == '4':
- self.terminal.doubleHeightLine(False)
- elif b == '5':
- self.terminal.singleWidthLine()
- elif b == '6':
- self.terminal.doubleWidthLine()
- else:
- self.terminal.unhandledControlSequence('\x1b#' + b)
-
-
-__all__ = [
- # Interfaces
- 'ITerminalProtocol', 'ITerminalTransport',
-
- # Symbolic constants
- 'modes', 'privateModes', 'FUNCTION_KEYS',
-
- 'CS_US', 'CS_UK', 'CS_DRAWING', 'CS_ALTERNATE', 'CS_ALTERNATE_SPECIAL',
- 'G0', 'G1', 'G2', 'G3',
-
- 'UNDERLINE', 'REVERSE_VIDEO', 'BLINK', 'BOLD', 'NORMAL',
-
- # Protocol classes
- 'ServerProtocol', 'ClientProtocol']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py
deleted file mode 100755
index e5c8fd12..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_text -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Character attribute manipulation API
-
-This module provides a domain-specific language (using Python syntax)
-for the creation of text with additional display attributes associated
-with it. It is intended as an alternative to manually building up
-strings containing ECMA 48 character attribute control codes. It
-currently supports foreground and background colors (black, red,
-green, yellow, blue, magenta, cyan, and white), intensity selection,
-underlining, blinking and reverse video. Character set selection
-support is planned.
-
-Character attributes are specified by using two Python operations:
-attribute lookup and indexing. For example, the string \"Hello
-world\" with red foreground and all other attributes set to their
-defaults, assuming the name twisted.conch.insults.text.attributes has
-been imported and bound to the name \"A\" (with the statement C{from
-twisted.conch.insults.text import attributes as A}, for example) one
-uses this expression::
-
- | A.fg.red[\"Hello world\"]
-
-Other foreground colors are set by substituting their name for
-\"red\". To set both a foreground and a background color, this
-expression is used::
-
- | A.fg.red[A.bg.green[\"Hello world\"]]
-
-Note that either A.bg.green can be nested within A.fg.red or vice
-versa. Also note that multiple items can be nested within a single
-index operation by separating them with commas::
-
- | A.bg.green[A.fg.red[\"Hello\"], " ", A.fg.blue[\"world\"]]
-
-Other character attributes are set in a similar fashion. To specify a
-blinking version of the previous expression::
-
- | A.blink[A.bg.green[A.fg.red[\"Hello\"], " ", A.fg.blue[\"world\"]]]
-
-C{A.reverseVideo}, C{A.underline}, and C{A.bold} are also valid.
-
-A third operation is actually supported: unary negation. This turns
-off an attribute when an enclosing expression would otherwise have
-caused it to be on. For example::
-
- | A.underline[A.fg.red[\"Hello\", -A.underline[\" world\"]]]
-
-@author: Jp Calderone
-"""
-
-from twisted.conch.insults import helper, insults
-
-class _Attribute(object):
- def __init__(self):
- self.children = []
-
- def __getitem__(self, item):
- assert isinstance(item, (list, tuple, _Attribute, str))
- if isinstance(item, (list, tuple)):
- self.children.extend(item)
- else:
- self.children.append(item)
- return self
-
- def serialize(self, write, attrs=None):
- if attrs is None:
- attrs = helper.CharacterAttribute()
- for ch in self.children:
- if isinstance(ch, _Attribute):
- ch.serialize(write, attrs.copy())
- else:
- write(attrs.toVT102())
- write(ch)
-
-class _NormalAttr(_Attribute):
- def serialize(self, write, attrs):
- attrs.__init__()
- super(_NormalAttr, self).serialize(write, attrs)
-
-class _OtherAttr(_Attribute):
- def __init__(self, attrname, attrvalue):
- self.attrname = attrname
- self.attrvalue = attrvalue
- self.children = []
-
- def __neg__(self):
- result = _OtherAttr(self.attrname, not self.attrvalue)
- result.children.extend(self.children)
- return result
-
- def serialize(self, write, attrs):
- attrs = attrs.wantOne(**{self.attrname: self.attrvalue})
- super(_OtherAttr, self).serialize(write, attrs)
-
-class _ColorAttr(_Attribute):
- def __init__(self, color, ground):
- self.color = color
- self.ground = ground
- self.children = []
-
- def serialize(self, write, attrs):
- attrs = attrs.wantOne(**{self.ground: self.color})
- super(_ColorAttr, self).serialize(write, attrs)
-
-class _ForegroundColorAttr(_ColorAttr):
- def __init__(self, color):
- super(_ForegroundColorAttr, self).__init__(color, 'foreground')
-
-class _BackgroundColorAttr(_ColorAttr):
- def __init__(self, color):
- super(_BackgroundColorAttr, self).__init__(color, 'background')
-
-class CharacterAttributes(object):
- class _ColorAttribute(object):
- def __init__(self, ground):
- self.ground = ground
-
- attrs = {
- 'black': helper.BLACK,
- 'red': helper.RED,
- 'green': helper.GREEN,
- 'yellow': helper.YELLOW,
- 'blue': helper.BLUE,
- 'magenta': helper.MAGENTA,
- 'cyan': helper.CYAN,
- 'white': helper.WHITE}
-
- def __getattr__(self, name):
- try:
- return self.ground(self.attrs[name])
- except KeyError:
- raise AttributeError(name)
-
- fg = _ColorAttribute(_ForegroundColorAttr)
- bg = _ColorAttribute(_BackgroundColorAttr)
-
- attrs = {
- 'bold': insults.BOLD,
- 'blink': insults.BLINK,
- 'underline': insults.UNDERLINE,
- 'reverseVideo': insults.REVERSE_VIDEO}
-
- def __getattr__(self, name):
- if name == 'normal':
- return _NormalAttr()
- if name in self.attrs:
- return _OtherAttr(name, True)
- raise AttributeError(name)
-
-def flatten(output, attrs):
- """Serialize a sequence of characters with attribute information
-
- The resulting string can be interpreted by VT102-compatible
- terminals so that the contained characters are displayed and, for
- those attributes which the terminal supports, have the attributes
- specified in the input.
-
- For example, if your terminal is VT102 compatible, you might run
- this for a colorful variation on the \"hello world\" theme::
-
- | from twisted.conch.insults.text import flatten, attributes as A
- | from twisted.conch.insults.helper import CharacterAttribute
- | print flatten(
- | A.normal[A.bold[A.fg.red['He'], A.fg.green['ll'], A.fg.magenta['o'], ' ',
- | A.fg.yellow['Wo'], A.fg.blue['rl'], A.fg.cyan['d!']]],
- | CharacterAttribute())
-
- @param output: Object returned by accessing attributes of the
- module-level attributes object.
-
- @param attrs: A L{twisted.conch.insults.helper.CharacterAttribute}
- instance
-
- @return: A VT102-friendly string
- """
- L = []
- output.serialize(L.append, attrs)
- return ''.join(L)
-
-attributes = CharacterAttributes()
-
-__all__ = ['attributes', 'flatten']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py
deleted file mode 100755
index 99013273..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py
+++ /dev/null
@@ -1,868 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_window -*-
-
-"""
-Simple insults-based widget library
-
-@author: Jp Calderone
-"""
-
-import array
-
-from twisted.conch.insults import insults, helper
-from twisted.python import text as tptext
-
-class YieldFocus(Exception):
- """Input focus manipulation exception
- """
-
-class BoundedTerminalWrapper(object):
- def __init__(self, terminal, width, height, xoff, yoff):
- self.width = width
- self.height = height
- self.xoff = xoff
- self.yoff = yoff
- self.terminal = terminal
- self.cursorForward = terminal.cursorForward
- self.selectCharacterSet = terminal.selectCharacterSet
- self.selectGraphicRendition = terminal.selectGraphicRendition
- self.saveCursor = terminal.saveCursor
- self.restoreCursor = terminal.restoreCursor
-
- def cursorPosition(self, x, y):
- return self.terminal.cursorPosition(
- self.xoff + min(self.width, x),
- self.yoff + min(self.height, y)
- )
-
- def cursorHome(self):
- return self.terminal.cursorPosition(
- self.xoff, self.yoff)
-
- def write(self, bytes):
- return self.terminal.write(bytes)
-
-class Widget(object):
- focused = False
- parent = None
- dirty = False
- width = height = None
-
- def repaint(self):
- if not self.dirty:
- self.dirty = True
- if self.parent is not None and not self.parent.dirty:
- self.parent.repaint()
-
- def filthy(self):
- self.dirty = True
-
- def redraw(self, width, height, terminal):
- self.filthy()
- self.draw(width, height, terminal)
-
- def draw(self, width, height, terminal):
- if width != self.width or height != self.height or self.dirty:
- self.width = width
- self.height = height
- self.dirty = False
- self.render(width, height, terminal)
-
- def render(self, width, height, terminal):
- pass
-
- def sizeHint(self):
- return None
-
- def keystrokeReceived(self, keyID, modifier):
- if keyID == '\t':
- self.tabReceived(modifier)
- elif keyID == '\x7f':
- self.backspaceReceived()
- elif keyID in insults.FUNCTION_KEYS:
- self.functionKeyReceived(keyID, modifier)
- else:
- self.characterReceived(keyID, modifier)
-
- def tabReceived(self, modifier):
- # XXX TODO - Handle shift+tab
- raise YieldFocus()
-
- def focusReceived(self):
- """Called when focus is being given to this widget.
-
- May raise YieldFocus is this widget does not want focus.
- """
- self.focused = True
- self.repaint()
-
- def focusLost(self):
- self.focused = False
- self.repaint()
-
- def backspaceReceived(self):
- pass
-
- def functionKeyReceived(self, keyID, modifier):
- func = getattr(self, 'func_' + keyID.name, None)
- if func is not None:
- func(modifier)
-
- def characterReceived(self, keyID, modifier):
- pass
-
-class ContainerWidget(Widget):
- """
- @ivar focusedChild: The contained widget which currently has
- focus, or None.
- """
- focusedChild = None
- focused = False
-
- def __init__(self):
- Widget.__init__(self)
- self.children = []
-
- def addChild(self, child):
- assert child.parent is None
- child.parent = self
- self.children.append(child)
- if self.focusedChild is None and self.focused:
- try:
- child.focusReceived()
- except YieldFocus:
- pass
- else:
- self.focusedChild = child
- self.repaint()
-
- def remChild(self, child):
- assert child.parent is self
- child.parent = None
- self.children.remove(child)
- self.repaint()
-
- def filthy(self):
- for ch in self.children:
- ch.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- for ch in self.children:
- ch.draw(width, height, terminal)
-
- def changeFocus(self):
- self.repaint()
-
- if self.focusedChild is not None:
- self.focusedChild.focusLost()
- focusedChild = self.focusedChild
- self.focusedChild = None
- try:
- curFocus = self.children.index(focusedChild) + 1
- except ValueError:
- raise YieldFocus()
- else:
- curFocus = 0
- while curFocus < len(self.children):
- try:
- self.children[curFocus].focusReceived()
- except YieldFocus:
- curFocus += 1
- else:
- self.focusedChild = self.children[curFocus]
- return
- # None of our children wanted focus
- raise YieldFocus()
-
-
- def focusReceived(self):
- self.changeFocus()
- self.focused = True
-
-
- def keystrokeReceived(self, keyID, modifier):
- if self.focusedChild is not None:
- try:
- self.focusedChild.keystrokeReceived(keyID, modifier)
- except YieldFocus:
- self.changeFocus()
- self.repaint()
- else:
- Widget.keystrokeReceived(self, keyID, modifier)
-
-
-class TopWindow(ContainerWidget):
- """
- A top-level container object which provides focus wrap-around and paint
- scheduling.
-
- @ivar painter: A no-argument callable which will be invoked when this
- widget needs to be redrawn.
-
- @ivar scheduler: A one-argument callable which will be invoked with a
- no-argument callable and should arrange for it to invoked at some point in
- the near future. The no-argument callable will cause this widget and all
- its children to be redrawn. It is typically beneficial for the no-argument
- callable to be invoked at the end of handling for whatever event is
- currently active; for example, it might make sense to call it at the end of
- L{twisted.conch.insults.insults.ITerminalProtocol.keystrokeReceived}.
- Note, however, that since calls to this may also be made in response to no
- apparent event, arrangements should be made for the function to be called
- even if an event handler such as C{keystrokeReceived} is not on the call
- stack (eg, using C{reactor.callLater} with a short timeout).
- """
- focused = True
-
- def __init__(self, painter, scheduler):
- ContainerWidget.__init__(self)
- self.painter = painter
- self.scheduler = scheduler
-
- _paintCall = None
- def repaint(self):
- if self._paintCall is None:
- self._paintCall = object()
- self.scheduler(self._paint)
- ContainerWidget.repaint(self)
-
- def _paint(self):
- self._paintCall = None
- self.painter()
-
- def changeFocus(self):
- try:
- ContainerWidget.changeFocus(self)
- except YieldFocus:
- try:
- ContainerWidget.changeFocus(self)
- except YieldFocus:
- pass
-
- def keystrokeReceived(self, keyID, modifier):
- try:
- ContainerWidget.keystrokeReceived(self, keyID, modifier)
- except YieldFocus:
- self.changeFocus()
-
-
-class AbsoluteBox(ContainerWidget):
- def moveChild(self, child, x, y):
- for n in range(len(self.children)):
- if self.children[n][0] is child:
- self.children[n] = (child, x, y)
- break
- else:
- raise ValueError("No such child", child)
-
- def render(self, width, height, terminal):
- for (ch, x, y) in self.children:
- wrap = BoundedTerminalWrapper(terminal, width - x, height - y, x, y)
- ch.draw(width, height, wrap)
-
-
-class _Box(ContainerWidget):
- TOP, CENTER, BOTTOM = range(3)
-
- def __init__(self, gravity=CENTER):
- ContainerWidget.__init__(self)
- self.gravity = gravity
-
- def sizeHint(self):
- height = 0
- width = 0
- for ch in self.children:
- hint = ch.sizeHint()
- if hint is None:
- hint = (None, None)
-
- if self.variableDimension == 0:
- if hint[0] is None:
- width = None
- elif width is not None:
- width += hint[0]
- if hint[1] is None:
- height = None
- elif height is not None:
- height = max(height, hint[1])
- else:
- if hint[0] is None:
- width = None
- elif width is not None:
- width = max(width, hint[0])
- if hint[1] is None:
- height = None
- elif height is not None:
- height += hint[1]
-
- return width, height
-
-
- def render(self, width, height, terminal):
- if not self.children:
- return
-
- greedy = 0
- wants = []
- for ch in self.children:
- hint = ch.sizeHint()
- if hint is None:
- hint = (None, None)
- if hint[self.variableDimension] is None:
- greedy += 1
- wants.append(hint[self.variableDimension])
-
- length = (width, height)[self.variableDimension]
- totalWant = sum([w for w in wants if w is not None])
- if greedy:
- leftForGreedy = int((length - totalWant) / greedy)
-
- widthOffset = heightOffset = 0
-
- for want, ch in zip(wants, self.children):
- if want is None:
- want = leftForGreedy
-
- subWidth, subHeight = width, height
- if self.variableDimension == 0:
- subWidth = want
- else:
- subHeight = want
-
- wrap = BoundedTerminalWrapper(
- terminal,
- subWidth,
- subHeight,
- widthOffset,
- heightOffset,
- )
- ch.draw(subWidth, subHeight, wrap)
- if self.variableDimension == 0:
- widthOffset += want
- else:
- heightOffset += want
-
-
-class HBox(_Box):
- variableDimension = 0
-
-class VBox(_Box):
- variableDimension = 1
-
-
-class Packer(ContainerWidget):
- def render(self, width, height, terminal):
- if not self.children:
- return
-
- root = int(len(self.children) ** 0.5 + 0.5)
- boxes = [VBox() for n in range(root)]
- for n, ch in enumerate(self.children):
- boxes[n % len(boxes)].addChild(ch)
- h = HBox()
- map(h.addChild, boxes)
- h.render(width, height, terminal)
-
-
-class Canvas(Widget):
- focused = False
-
- contents = None
-
- def __init__(self):
- Widget.__init__(self)
- self.resize(1, 1)
-
- def resize(self, width, height):
- contents = array.array('c', ' ' * width * height)
- if self.contents is not None:
- for x in range(min(width, self._width)):
- for y in range(min(height, self._height)):
- contents[width * y + x] = self[x, y]
- self.contents = contents
- self._width = width
- self._height = height
- if self.x >= width:
- self.x = width - 1
- if self.y >= height:
- self.y = height - 1
-
- def __getitem__(self, (x, y)):
- return self.contents[(self._width * y) + x]
-
- def __setitem__(self, (x, y), value):
- self.contents[(self._width * y) + x] = value
-
- def clear(self):
- self.contents = array.array('c', ' ' * len(self.contents))
-
- def render(self, width, height, terminal):
- if not width or not height:
- return
-
- if width != self._width or height != self._height:
- self.resize(width, height)
- for i in range(height):
- terminal.cursorPosition(0, i)
- terminal.write(''.join(self.contents[self._width * i:self._width * i + self._width])[:width])
-
-
-def horizontalLine(terminal, y, left, right):
- terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0)
- terminal.cursorPosition(left, y)
- terminal.write(chr(0161) * (right - left))
- terminal.selectCharacterSet(insults.CS_US, insults.G0)
-
-def verticalLine(terminal, x, top, bottom):
- terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0)
- for n in xrange(top, bottom):
- terminal.cursorPosition(x, n)
- terminal.write(chr(0170))
- terminal.selectCharacterSet(insults.CS_US, insults.G0)
-
-
-def rectangle(terminal, (top, left), (width, height)):
- terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0)
-
- terminal.cursorPosition(top, left)
- terminal.write(chr(0154))
- terminal.write(chr(0161) * (width - 2))
- terminal.write(chr(0153))
- for n in range(height - 2):
- terminal.cursorPosition(left, top + n + 1)
- terminal.write(chr(0170))
- terminal.cursorForward(width - 2)
- terminal.write(chr(0170))
- terminal.cursorPosition(0, top + height - 1)
- terminal.write(chr(0155))
- terminal.write(chr(0161) * (width - 2))
- terminal.write(chr(0152))
-
- terminal.selectCharacterSet(insults.CS_US, insults.G0)
-
-class Border(Widget):
- def __init__(self, containee):
- Widget.__init__(self)
- self.containee = containee
- self.containee.parent = self
-
- def focusReceived(self):
- return self.containee.focusReceived()
-
- def focusLost(self):
- return self.containee.focusLost()
-
- def keystrokeReceived(self, keyID, modifier):
- return self.containee.keystrokeReceived(keyID, modifier)
-
- def sizeHint(self):
- hint = self.containee.sizeHint()
- if hint is None:
- hint = (None, None)
- if hint[0] is None:
- x = None
- else:
- x = hint[0] + 2
- if hint[1] is None:
- y = None
- else:
- y = hint[1] + 2
- return x, y
-
- def filthy(self):
- self.containee.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- if self.containee.focused:
- terminal.write('\x1b[31m')
- rectangle(terminal, (0, 0), (width, height))
- terminal.write('\x1b[0m')
- wrap = BoundedTerminalWrapper(terminal, width - 2, height - 2, 1, 1)
- self.containee.draw(width - 2, height - 2, wrap)
-
-
-class Button(Widget):
- def __init__(self, label, onPress):
- Widget.__init__(self)
- self.label = label
- self.onPress = onPress
-
- def sizeHint(self):
- return len(self.label), 1
-
- def characterReceived(self, keyID, modifier):
- if keyID == '\r':
- self.onPress()
-
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- if self.focused:
- terminal.write('\x1b[1m' + self.label + '\x1b[0m')
- else:
- terminal.write(self.label)
-
-class TextInput(Widget):
- def __init__(self, maxwidth, onSubmit):
- Widget.__init__(self)
- self.onSubmit = onSubmit
- self.maxwidth = maxwidth
- self.buffer = ''
- self.cursor = 0
-
- def setText(self, text):
- self.buffer = text[:self.maxwidth]
- self.cursor = len(self.buffer)
- self.repaint()
-
- def func_LEFT_ARROW(self, modifier):
- if self.cursor > 0:
- self.cursor -= 1
- self.repaint()
-
- def func_RIGHT_ARROW(self, modifier):
- if self.cursor < len(self.buffer):
- self.cursor += 1
- self.repaint()
-
- def backspaceReceived(self):
- if self.cursor > 0:
- self.buffer = self.buffer[:self.cursor - 1] + self.buffer[self.cursor:]
- self.cursor -= 1
- self.repaint()
-
- def characterReceived(self, keyID, modifier):
- if keyID == '\r':
- self.onSubmit(self.buffer)
- else:
- if len(self.buffer) < self.maxwidth:
- self.buffer = self.buffer[:self.cursor] + keyID + self.buffer[self.cursor:]
- self.cursor += 1
- self.repaint()
-
- def sizeHint(self):
- return self.maxwidth + 1, 1
-
- def render(self, width, height, terminal):
- currentText = self._renderText()
- terminal.cursorPosition(0, 0)
- if self.focused:
- terminal.write(currentText[:self.cursor])
- cursor(terminal, currentText[self.cursor:self.cursor+1] or ' ')
- terminal.write(currentText[self.cursor+1:])
- terminal.write(' ' * (self.maxwidth - len(currentText) + 1))
- else:
- more = self.maxwidth - len(currentText)
- terminal.write(currentText + '_' * more)
-
- def _renderText(self):
- return self.buffer
-
-class PasswordInput(TextInput):
- def _renderText(self):
- return '*' * len(self.buffer)
-
-class TextOutput(Widget):
- text = ''
-
- def __init__(self, size=None):
- Widget.__init__(self)
- self.size = size
-
- def sizeHint(self):
- return self.size
-
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- text = self.text[:width]
- terminal.write(text + ' ' * (width - len(text)))
-
- def setText(self, text):
- self.text = text
- self.repaint()
-
- def focusReceived(self):
- raise YieldFocus()
-
-class TextOutputArea(TextOutput):
- WRAP, TRUNCATE = range(2)
-
- def __init__(self, size=None, longLines=WRAP):
- TextOutput.__init__(self, size)
- self.longLines = longLines
-
- def render(self, width, height, terminal):
- n = 0
- inputLines = self.text.splitlines()
- outputLines = []
- while inputLines:
- if self.longLines == self.WRAP:
- wrappedLines = tptext.greedyWrap(inputLines.pop(0), width)
- outputLines.extend(wrappedLines or [''])
- else:
- outputLines.append(inputLines.pop(0)[:width])
- if len(outputLines) >= height:
- break
- for n, L in enumerate(outputLines[:height]):
- terminal.cursorPosition(0, n)
- terminal.write(L)
-
-class Viewport(Widget):
- _xOffset = 0
- _yOffset = 0
-
- def xOffset():
- def get(self):
- return self._xOffset
- def set(self, value):
- if self._xOffset != value:
- self._xOffset = value
- self.repaint()
- return get, set
- xOffset = property(*xOffset())
-
- def yOffset():
- def get(self):
- return self._yOffset
- def set(self, value):
- if self._yOffset != value:
- self._yOffset = value
- self.repaint()
- return get, set
- yOffset = property(*yOffset())
-
- _width = 160
- _height = 24
-
- def __init__(self, containee):
- Widget.__init__(self)
- self.containee = containee
- self.containee.parent = self
-
- self._buf = helper.TerminalBuffer()
- self._buf.width = self._width
- self._buf.height = self._height
- self._buf.connectionMade()
-
- def filthy(self):
- self.containee.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- self.containee.draw(self._width, self._height, self._buf)
-
- # XXX /Lame/
- for y, line in enumerate(self._buf.lines[self._yOffset:self._yOffset + height]):
- terminal.cursorPosition(0, y)
- n = 0
- for n, (ch, attr) in enumerate(line[self._xOffset:self._xOffset + width]):
- if ch is self._buf.void:
- ch = ' '
- terminal.write(ch)
- if n < width:
- terminal.write(' ' * (width - n - 1))
-
-
-class _Scrollbar(Widget):
- def __init__(self, onScroll):
- Widget.__init__(self)
- self.onScroll = onScroll
- self.percent = 0.0
-
- def smaller(self):
- self.percent = min(1.0, max(0.0, self.onScroll(-1)))
- self.repaint()
-
- def bigger(self):
- self.percent = min(1.0, max(0.0, self.onScroll(+1)))
- self.repaint()
-
-
-class HorizontalScrollbar(_Scrollbar):
- def sizeHint(self):
- return (None, 1)
-
- def func_LEFT_ARROW(self, modifier):
- self.smaller()
-
- def func_RIGHT_ARROW(self, modifier):
- self.bigger()
-
- _left = u'\N{BLACK LEFT-POINTING TRIANGLE}'
- _right = u'\N{BLACK RIGHT-POINTING TRIANGLE}'
- _bar = u'\N{LIGHT SHADE}'
- _slider = u'\N{DARK SHADE}'
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- n = width - 3
- before = int(n * self.percent)
- after = n - before
- me = self._left + (self._bar * before) + self._slider + (self._bar * after) + self._right
- terminal.write(me.encode('utf-8'))
-
-
-class VerticalScrollbar(_Scrollbar):
- def sizeHint(self):
- return (1, None)
-
- def func_UP_ARROW(self, modifier):
- self.smaller()
-
- def func_DOWN_ARROW(self, modifier):
- self.bigger()
-
- _up = u'\N{BLACK UP-POINTING TRIANGLE}'
- _down = u'\N{BLACK DOWN-POINTING TRIANGLE}'
- _bar = u'\N{LIGHT SHADE}'
- _slider = u'\N{DARK SHADE}'
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- knob = int(self.percent * (height - 2))
- terminal.write(self._up.encode('utf-8'))
- for i in xrange(1, height - 1):
- terminal.cursorPosition(0, i)
- if i != (knob + 1):
- terminal.write(self._bar.encode('utf-8'))
- else:
- terminal.write(self._slider.encode('utf-8'))
- terminal.cursorPosition(0, height - 1)
- terminal.write(self._down.encode('utf-8'))
-
-
-class ScrolledArea(Widget):
- """
- A L{ScrolledArea} contains another widget wrapped in a viewport and
- vertical and horizontal scrollbars for moving the viewport around.
- """
- def __init__(self, containee):
- Widget.__init__(self)
- self._viewport = Viewport(containee)
- self._horiz = HorizontalScrollbar(self._horizScroll)
- self._vert = VerticalScrollbar(self._vertScroll)
-
- for w in self._viewport, self._horiz, self._vert:
- w.parent = self
-
- def _horizScroll(self, n):
- self._viewport.xOffset += n
- self._viewport.xOffset = max(0, self._viewport.xOffset)
- return self._viewport.xOffset / 25.0
-
- def _vertScroll(self, n):
- self._viewport.yOffset += n
- self._viewport.yOffset = max(0, self._viewport.yOffset)
- return self._viewport.yOffset / 25.0
-
- def func_UP_ARROW(self, modifier):
- self._vert.smaller()
-
- def func_DOWN_ARROW(self, modifier):
- self._vert.bigger()
-
- def func_LEFT_ARROW(self, modifier):
- self._horiz.smaller()
-
- def func_RIGHT_ARROW(self, modifier):
- self._horiz.bigger()
-
- def filthy(self):
- self._viewport.filthy()
- self._horiz.filthy()
- self._vert.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- wrapper = BoundedTerminalWrapper(terminal, width - 2, height - 2, 1, 1)
- self._viewport.draw(width - 2, height - 2, wrapper)
- if self.focused:
- terminal.write('\x1b[31m')
- horizontalLine(terminal, 0, 1, width - 1)
- verticalLine(terminal, 0, 1, height - 1)
- self._vert.draw(1, height - 1, BoundedTerminalWrapper(terminal, 1, height - 1, width - 1, 0))
- self._horiz.draw(width, 1, BoundedTerminalWrapper(terminal, width, 1, 0, height - 1))
- terminal.write('\x1b[0m')
-
-def cursor(terminal, ch):
- terminal.saveCursor()
- terminal.selectGraphicRendition(str(insults.REVERSE_VIDEO))
- terminal.write(ch)
- terminal.restoreCursor()
- terminal.cursorForward()
-
-class Selection(Widget):
- # Index into the sequence
- focusedIndex = 0
-
- # Offset into the displayed subset of the sequence
- renderOffset = 0
-
- def __init__(self, sequence, onSelect, minVisible=None):
- Widget.__init__(self)
- self.sequence = sequence
- self.onSelect = onSelect
- self.minVisible = minVisible
- if minVisible is not None:
- self._width = max(map(len, self.sequence))
-
- def sizeHint(self):
- if self.minVisible is not None:
- return self._width, self.minVisible
-
- def func_UP_ARROW(self, modifier):
- if self.focusedIndex > 0:
- self.focusedIndex -= 1
- if self.renderOffset > 0:
- self.renderOffset -= 1
- self.repaint()
-
- def func_PGUP(self, modifier):
- if self.renderOffset != 0:
- self.focusedIndex -= self.renderOffset
- self.renderOffset = 0
- else:
- self.focusedIndex = max(0, self.focusedIndex - self.height)
- self.repaint()
-
- def func_DOWN_ARROW(self, modifier):
- if self.focusedIndex < len(self.sequence) - 1:
- self.focusedIndex += 1
- if self.renderOffset < self.height - 1:
- self.renderOffset += 1
- self.repaint()
-
-
- def func_PGDN(self, modifier):
- if self.renderOffset != self.height - 1:
- change = self.height - self.renderOffset - 1
- if change + self.focusedIndex >= len(self.sequence):
- change = len(self.sequence) - self.focusedIndex - 1
- self.focusedIndex += change
- self.renderOffset = self.height - 1
- else:
- self.focusedIndex = min(len(self.sequence) - 1, self.focusedIndex + self.height)
- self.repaint()
-
- def characterReceived(self, keyID, modifier):
- if keyID == '\r':
- self.onSelect(self.sequence[self.focusedIndex])
-
- def render(self, width, height, terminal):
- self.height = height
- start = self.focusedIndex - self.renderOffset
- if start > len(self.sequence) - height:
- start = max(0, len(self.sequence) - height)
-
- elements = self.sequence[start:start+height]
-
- for n, ele in enumerate(elements):
- terminal.cursorPosition(0, n)
- if n == self.renderOffset:
- terminal.saveCursor()
- if self.focused:
- modes = str(insults.REVERSE_VIDEO), str(insults.BOLD)
- else:
- modes = str(insults.REVERSE_VIDEO),
- terminal.selectGraphicRendition(*modes)
- text = ele[:width]
- terminal.write(text + (' ' * (width - len(text))))
- if n == self.renderOffset:
- terminal.restoreCursor()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py
deleted file mode 100755
index d42811a8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py
+++ /dev/null
@@ -1,402 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module contains interfaces defined for the L{twisted.conch} package.
-"""
-
-from zope.interface import Interface, Attribute
-
-class IConchUser(Interface):
- """
- A user who has been authenticated to Cred through Conch. This is
- the interface between the SSH connection and the user.
- """
-
- conn = Attribute('The SSHConnection object for this user.')
-
- def lookupChannel(channelType, windowSize, maxPacket, data):
- """
- The other side requested a channel of some sort.
- channelType is the type of channel being requested,
- windowSize is the initial size of the remote window,
- maxPacket is the largest packet we should send,
- data is any other packet data (often nothing).
-
- We return a subclass of L{SSHChannel<ssh.channel.SSHChannel>}. If
- an appropriate channel can not be found, an exception will be
- raised. If a L{ConchError<error.ConchError>} is raised, the .value
- will be the message, and the .data will be the error code.
-
- @type channelType: C{str}
- @type windowSize: C{int}
- @type maxPacket: C{int}
- @type data: C{str}
- @rtype: subclass of L{SSHChannel}/C{tuple}
- """
-
- def lookupSubsystem(subsystem, data):
- """
- The other side requested a subsystem.
- subsystem is the name of the subsystem being requested.
- data is any other packet data (often nothing).
-
- We return a L{Protocol}.
- """
-
- def gotGlobalRequest(requestType, data):
- """
- A global request was sent from the other side.
-
- By default, this dispatches to a method 'channel_channelType' with any
- non-alphanumerics in the channelType replace with _'s. If it cannot
- find a suitable method, it returns an OPEN_UNKNOWN_CHANNEL_TYPE error.
- The method is called with arguments of windowSize, maxPacket, data.
- """
-
-class ISession(Interface):
-
- def getPty(term, windowSize, modes):
- """
- Get a psuedo-terminal for use by a shell or command.
-
- If a psuedo-terminal is not available, or the request otherwise
- fails, raise an exception.
- """
-
- def openShell(proto):
- """
- Open a shell and connect it to proto.
-
- @param proto: a L{ProcessProtocol} instance.
- """
-
- def execCommand(proto, command):
- """
- Execute a command.
-
- @param proto: a L{ProcessProtocol} instance.
- """
-
- def windowChanged(newWindowSize):
- """
- Called when the size of the remote screen has changed.
- """
-
- def eofReceived():
- """
- Called when the other side has indicated no more data will be sent.
- """
-
- def closed():
- """
- Called when the session is closed.
- """
-
-
-class ISFTPServer(Interface):
- """
- The only attribute of this class is "avatar". It is the avatar
- returned by the Realm that we are authenticated with, and
- represents the logged-in user. Each method should check to verify
- that the user has permission for their actions.
- """
-
- def gotVersion(otherVersion, extData):
- """
- Called when the client sends their version info.
-
- otherVersion is an integer representing the version of the SFTP
- protocol they are claiming.
- extData is a dictionary of extended_name : extended_data items.
- These items are sent by the client to indicate additional features.
-
- This method should return a dictionary of extended_name : extended_data
- items. These items are the additional features (if any) supported
- by the server.
- """
- return {}
-
- def openFile(filename, flags, attrs):
- """
- Called when the clients asks to open a file.
-
- @param filename: a string representing the file to open.
-
- @param flags: an integer of the flags to open the file with, ORed together.
- The flags and their values are listed at the bottom of this file.
-
- @param attrs: a list of attributes to open the file with. It is a
- dictionary, consisting of 0 or more keys. The possible keys are::
-
- size: the size of the file in bytes
- uid: the user ID of the file as an integer
- gid: the group ID of the file as an integer
- permissions: the permissions of the file with as an integer.
- the bit representation of this field is defined by POSIX.
- atime: the access time of the file as seconds since the epoch.
- mtime: the modification time of the file as seconds since the epoch.
- ext_*: extended attributes. The server is not required to
- understand this, but it may.
-
- NOTE: there is no way to indicate text or binary files. it is up
- to the SFTP client to deal with this.
-
- This method returns an object that meets the ISFTPFile interface.
- Alternatively, it can return a L{Deferred} that will be called back
- with the object.
- """
-
- def removeFile(filename):
- """
- Remove the given file.
-
- This method returns when the remove succeeds, or a Deferred that is
- called back when it succeeds.
-
- @param filename: the name of the file as a string.
- """
-
- def renameFile(oldpath, newpath):
- """
- Rename the given file.
-
- This method returns when the rename succeeds, or a L{Deferred} that is
- called back when it succeeds. If the rename fails, C{renameFile} will
- raise an implementation-dependent exception.
-
- @param oldpath: the current location of the file.
- @param newpath: the new file name.
- """
-
- def makeDirectory(path, attrs):
- """
- Make a directory.
-
- This method returns when the directory is created, or a Deferred that
- is called back when it is created.
-
- @param path: the name of the directory to create as a string.
- @param attrs: a dictionary of attributes to create the directory with.
- Its meaning is the same as the attrs in the L{openFile} method.
- """
-
- def removeDirectory(path):
- """
- Remove a directory (non-recursively)
-
- It is an error to remove a directory that has files or directories in
- it.
-
- This method returns when the directory is removed, or a Deferred that
- is called back when it is removed.
-
- @param path: the directory to remove.
- """
-
- def openDirectory(path):
- """
- Open a directory for scanning.
-
- This method returns an iterable object that has a close() method,
- or a Deferred that is called back with same.
-
- The close() method is called when the client is finished reading
- from the directory. At this point, the iterable will no longer
- be used.
-
- The iterable should return triples of the form (filename,
- longname, attrs) or Deferreds that return the same. The
- sequence must support __getitem__, but otherwise may be any
- 'sequence-like' object.
-
- filename is the name of the file relative to the directory.
- logname is an expanded format of the filename. The recommended format
- is:
- -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
- 1234567890 123 12345678 12345678 12345678 123456789012
-
- The first line is sample output, the second is the length of the field.
- The fields are: permissions, link count, user owner, group owner,
- size in bytes, modification time.
-
- attrs is a dictionary in the format of the attrs argument to openFile.
-
- @param path: the directory to open.
- """
-
- def getAttrs(path, followLinks):
- """
- Return the attributes for the given path.
-
- This method returns a dictionary in the same format as the attrs
- argument to openFile or a Deferred that is called back with same.
-
- @param path: the path to return attributes for as a string.
- @param followLinks: a boolean. If it is True, follow symbolic links
- and return attributes for the real path at the base. If it is False,
- return attributes for the specified path.
- """
-
- def setAttrs(path, attrs):
- """
- Set the attributes for the path.
-
- This method returns when the attributes are set or a Deferred that is
- called back when they are.
-
- @param path: the path to set attributes for as a string.
- @param attrs: a dictionary in the same format as the attrs argument to
- L{openFile}.
- """
-
- def readLink(path):
- """
- Find the root of a set of symbolic links.
-
- This method returns the target of the link, or a Deferred that
- returns the same.
-
- @param path: the path of the symlink to read.
- """
-
- def makeLink(linkPath, targetPath):
- """
- Create a symbolic link.
-
- This method returns when the link is made, or a Deferred that
- returns the same.
-
- @param linkPath: the pathname of the symlink as a string.
- @param targetPath: the path of the target of the link as a string.
- """
-
- def realPath(path):
- """
- Convert any path to an absolute path.
-
- This method returns the absolute path as a string, or a Deferred
- that returns the same.
-
- @param path: the path to convert as a string.
- """
-
- def extendedRequest(extendedName, extendedData):
- """
- This is the extension mechanism for SFTP. The other side can send us
- arbitrary requests.
-
- If we don't implement the request given by extendedName, raise
- NotImplementedError.
-
- The return value is a string, or a Deferred that will be called
- back with a string.
-
- @param extendedName: the name of the request as a string.
- @param extendedData: the data the other side sent with the request,
- as a string.
- """
-
-
-
-class IKnownHostEntry(Interface):
- """
- A L{IKnownHostEntry} is an entry in an OpenSSH-formatted C{known_hosts}
- file.
-
- @since: 8.2
- """
-
- def matchesKey(key):
- """
- Return True if this entry matches the given Key object, False
- otherwise.
-
- @param key: The key object to match against.
- @type key: L{twisted.conch.ssh.Key}
- """
-
-
- def matchesHost(hostname):
- """
- Return True if this entry matches the given hostname, False otherwise.
-
- Note that this does no name resolution; if you want to match an IP
- address, you have to resolve it yourself, and pass it in as a dotted
- quad string.
-
- @param key: The hostname to match against.
- @type key: L{str}
- """
-
-
- def toString():
- """
- @return: a serialized string representation of this entry, suitable for
- inclusion in a known_hosts file. (Newline not included.)
-
- @rtype: L{str}
- """
-
-
-
-class ISFTPFile(Interface):
- """
- This represents an open file on the server. An object adhering to this
- interface should be returned from L{openFile}().
- """
-
- def close():
- """
- Close the file.
-
- This method returns nothing if the close succeeds immediately, or a
- Deferred that is called back when the close succeeds.
- """
-
- def readChunk(offset, length):
- """
- Read from the file.
-
- If EOF is reached before any data is read, raise EOFError.
-
- This method returns the data as a string, or a Deferred that is
- called back with same.
-
- @param offset: an integer that is the index to start from in the file.
- @param length: the maximum length of data to return. The actual amount
- returned may less than this. For normal disk files, however,
- this should read the requested number (up to the end of the file).
- """
-
- def writeChunk(offset, data):
- """
- Write to the file.
-
- This method returns when the write completes, or a Deferred that is
- called when it completes.
-
- @param offset: an integer that is the index to start from in the file.
- @param data: a string that is the data to write.
- """
-
- def getAttrs():
- """
- Return the attributes for the file.
-
- This method returns a dictionary in the same format as the attrs
- argument to L{openFile} or a L{Deferred} that is called back with same.
- """
-
- def setAttrs(attrs):
- """
- Set the attributes for the file.
-
- This method returns when the attributes are set or a Deferred that is
- called back when they are.
-
- @param attrs: a dictionary in the same format as the attrs argument to
- L{openFile}.
- """
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py
deleted file mode 100755
index ab44f855..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_cftp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import array
-import stat
-
-from time import time, strftime, localtime
-
-# locale-independent month names to use instead of strftime's
-_MONTH_NAMES = dict(zip(
- range(1, 13),
- "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split()))
-
-
-def lsLine(name, s):
- """
- Build an 'ls' line for a file ('file' in its generic sense, it
- can be of any type).
- """
- mode = s.st_mode
- perms = array.array('c', '-'*10)
- ft = stat.S_IFMT(mode)
- if stat.S_ISDIR(ft): perms[0] = 'd'
- elif stat.S_ISCHR(ft): perms[0] = 'c'
- elif stat.S_ISBLK(ft): perms[0] = 'b'
- elif stat.S_ISREG(ft): perms[0] = '-'
- elif stat.S_ISFIFO(ft): perms[0] = 'f'
- elif stat.S_ISLNK(ft): perms[0] = 'l'
- elif stat.S_ISSOCK(ft): perms[0] = 's'
- else: perms[0] = '!'
- # user
- if mode&stat.S_IRUSR:perms[1] = 'r'
- if mode&stat.S_IWUSR:perms[2] = 'w'
- if mode&stat.S_IXUSR:perms[3] = 'x'
- # group
- if mode&stat.S_IRGRP:perms[4] = 'r'
- if mode&stat.S_IWGRP:perms[5] = 'w'
- if mode&stat.S_IXGRP:perms[6] = 'x'
- # other
- if mode&stat.S_IROTH:perms[7] = 'r'
- if mode&stat.S_IWOTH:perms[8] = 'w'
- if mode&stat.S_IXOTH:perms[9] = 'x'
- # suid/sgid
- if mode&stat.S_ISUID:
- if perms[3] == 'x': perms[3] = 's'
- else: perms[3] = 'S'
- if mode&stat.S_ISGID:
- if perms[6] == 'x': perms[6] = 's'
- else: perms[6] = 'S'
-
- lsresult = [
- perms.tostring(),
- str(s.st_nlink).rjust(5),
- ' ',
- str(s.st_uid).ljust(9),
- str(s.st_gid).ljust(9),
- str(s.st_size).rjust(8),
- ' ',
- ]
-
- # need to specify the month manually, as strftime depends on locale
- ttup = localtime(s.st_mtime)
- sixmonths = 60 * 60 * 24 * 7 * 26
- if s.st_mtime + sixmonths < time(): # last edited more than 6mo ago
- strtime = strftime("%%s %d %Y ", ttup)
- else:
- strtime = strftime("%%s %d %H:%M ", ttup)
- lsresult.append(strtime % (_MONTH_NAMES[ttup[1]],))
-
- lsresult.append(name)
- return ''.join(lsresult)
-
-
-__all__ = ['lsLine']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py
deleted file mode 100755
index dee6a024..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py
+++ /dev/null
@@ -1,340 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_manhole -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Line-input oriented interactive interpreter loop.
-
-Provides classes for handling Python source input and arbitrary output
-interactively from a Twisted application. Also included is syntax coloring
-code with support for VT102 terminals, control code handling (^C, ^D, ^Q),
-and reasonable handling of Deferreds.
-
-@author: Jp Calderone
-"""
-
-import code, sys, StringIO, tokenize
-
-from twisted.conch import recvline
-
-from twisted.internet import defer
-from twisted.python.htmlizer import TokenPrinter
-
-class FileWrapper:
- """Minimal write-file-like object.
-
- Writes are translated into addOutput calls on an object passed to
- __init__. Newlines are also converted from network to local style.
- """
-
- softspace = 0
- state = 'normal'
-
- def __init__(self, o):
- self.o = o
-
- def flush(self):
- pass
-
- def write(self, data):
- self.o.addOutput(data.replace('\r\n', '\n'))
-
- def writelines(self, lines):
- self.write(''.join(lines))
-
-class ManholeInterpreter(code.InteractiveInterpreter):
- """Interactive Interpreter with special output and Deferred support.
-
- Aside from the features provided by L{code.InteractiveInterpreter}, this
- class captures sys.stdout output and redirects it to the appropriate
- location (the Manhole protocol instance). It also treats Deferreds
- which reach the top-level specially: each is formatted to the user with
- a unique identifier and a new callback and errback added to it, each of
- which will format the unique identifier and the result with which the
- Deferred fires and then pass it on to the next participant in the
- callback chain.
- """
-
- numDeferreds = 0
- def __init__(self, handler, locals=None, filename="<console>"):
- code.InteractiveInterpreter.__init__(self, locals)
- self._pendingDeferreds = {}
- self.handler = handler
- self.filename = filename
- self.resetBuffer()
-
- def resetBuffer(self):
- """Reset the input buffer."""
- self.buffer = []
-
- def push(self, line):
- """Push a line to the interpreter.
-
- The line should not have a trailing newline; it may have
- internal newlines. The line is appended to a buffer and the
- interpreter's runsource() method is called with the
- concatenated contents of the buffer as source. If this
- indicates that the command was executed or invalid, the buffer
- is reset; otherwise, the command is incomplete, and the buffer
- is left as it was after the line was appended. The return
- value is 1 if more input is required, 0 if the line was dealt
- with in some way (this is the same as runsource()).
-
- """
- self.buffer.append(line)
- source = "\n".join(self.buffer)
- more = self.runsource(source, self.filename)
- if not more:
- self.resetBuffer()
- return more
-
- def runcode(self, *a, **kw):
- orighook, sys.displayhook = sys.displayhook, self.displayhook
- try:
- origout, sys.stdout = sys.stdout, FileWrapper(self.handler)
- try:
- code.InteractiveInterpreter.runcode(self, *a, **kw)
- finally:
- sys.stdout = origout
- finally:
- sys.displayhook = orighook
-
- def displayhook(self, obj):
- self.locals['_'] = obj
- if isinstance(obj, defer.Deferred):
- # XXX Ick, where is my "hasFired()" interface?
- if hasattr(obj, "result"):
- self.write(repr(obj))
- elif id(obj) in self._pendingDeferreds:
- self.write("<Deferred #%d>" % (self._pendingDeferreds[id(obj)][0],))
- else:
- d = self._pendingDeferreds
- k = self.numDeferreds
- d[id(obj)] = (k, obj)
- self.numDeferreds += 1
- obj.addCallbacks(self._cbDisplayDeferred, self._ebDisplayDeferred,
- callbackArgs=(k, obj), errbackArgs=(k, obj))
- self.write("<Deferred #%d>" % (k,))
- elif obj is not None:
- self.write(repr(obj))
-
- def _cbDisplayDeferred(self, result, k, obj):
- self.write("Deferred #%d called back: %r" % (k, result), True)
- del self._pendingDeferreds[id(obj)]
- return result
-
- def _ebDisplayDeferred(self, failure, k, obj):
- self.write("Deferred #%d failed: %r" % (k, failure.getErrorMessage()), True)
- del self._pendingDeferreds[id(obj)]
- return failure
-
- def write(self, data, async=False):
- self.handler.addOutput(data, async)
-
-CTRL_C = '\x03'
-CTRL_D = '\x04'
-CTRL_BACKSLASH = '\x1c'
-CTRL_L = '\x0c'
-CTRL_A = '\x01'
-CTRL_E = '\x05'
-
-class Manhole(recvline.HistoricRecvLine):
- """Mediator between a fancy line source and an interactive interpreter.
-
- This accepts lines from its transport and passes them on to a
- L{ManholeInterpreter}. Control commands (^C, ^D, ^\) are also handled
- with something approximating their normal terminal-mode behavior. It
- can optionally be constructed with a dict which will be used as the
- local namespace for any code executed.
- """
-
- namespace = None
-
- def __init__(self, namespace=None):
- recvline.HistoricRecvLine.__init__(self)
- if namespace is not None:
- self.namespace = namespace.copy()
-
- def connectionMade(self):
- recvline.HistoricRecvLine.connectionMade(self)
- self.interpreter = ManholeInterpreter(self, self.namespace)
- self.keyHandlers[CTRL_C] = self.handle_INT
- self.keyHandlers[CTRL_D] = self.handle_EOF
- self.keyHandlers[CTRL_L] = self.handle_FF
- self.keyHandlers[CTRL_A] = self.handle_HOME
- self.keyHandlers[CTRL_E] = self.handle_END
- self.keyHandlers[CTRL_BACKSLASH] = self.handle_QUIT
-
-
- def handle_INT(self):
- """
- Handle ^C as an interrupt keystroke by resetting the current input
- variables to their initial state.
- """
- self.pn = 0
- self.lineBuffer = []
- self.lineBufferIndex = 0
- self.interpreter.resetBuffer()
-
- self.terminal.nextLine()
- self.terminal.write("KeyboardInterrupt")
- self.terminal.nextLine()
- self.terminal.write(self.ps[self.pn])
-
-
- def handle_EOF(self):
- if self.lineBuffer:
- self.terminal.write('\a')
- else:
- self.handle_QUIT()
-
-
- def handle_FF(self):
- """
- Handle a 'form feed' byte - generally used to request a screen
- refresh/redraw.
- """
- self.terminal.eraseDisplay()
- self.terminal.cursorHome()
- self.drawInputLine()
-
-
- def handle_QUIT(self):
- self.terminal.loseConnection()
-
-
- def _needsNewline(self):
- w = self.terminal.lastWrite
- return not w.endswith('\n') and not w.endswith('\x1bE')
-
- def addOutput(self, bytes, async=False):
- if async:
- self.terminal.eraseLine()
- self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]))
-
- self.terminal.write(bytes)
-
- if async:
- if self._needsNewline():
- self.terminal.nextLine()
-
- self.terminal.write(self.ps[self.pn])
-
- if self.lineBuffer:
- oldBuffer = self.lineBuffer
- self.lineBuffer = []
- self.lineBufferIndex = 0
-
- self._deliverBuffer(oldBuffer)
-
- def lineReceived(self, line):
- more = self.interpreter.push(line)
- self.pn = bool(more)
- if self._needsNewline():
- self.terminal.nextLine()
- self.terminal.write(self.ps[self.pn])
-
-class VT102Writer:
- """Colorizer for Python tokens.
-
- A series of tokens are written to instances of this object. Each is
- colored in a particular way. The final line of the result of this is
- generally added to the output.
- """
-
- typeToColor = {
- 'identifier': '\x1b[31m',
- 'keyword': '\x1b[32m',
- 'parameter': '\x1b[33m',
- 'variable': '\x1b[1;33m',
- 'string': '\x1b[35m',
- 'number': '\x1b[36m',
- 'op': '\x1b[37m'}
-
- normalColor = '\x1b[0m'
-
- def __init__(self):
- self.written = []
-
- def color(self, type):
- r = self.typeToColor.get(type, '')
- return r
-
- def write(self, token, type=None):
- if token and token != '\r':
- c = self.color(type)
- if c:
- self.written.append(c)
- self.written.append(token)
- if c:
- self.written.append(self.normalColor)
-
- def __str__(self):
- s = ''.join(self.written)
- return s.strip('\n').splitlines()[-1]
-
-def lastColorizedLine(source):
- """Tokenize and colorize the given Python source.
-
- Returns a VT102-format colorized version of the last line of C{source}.
- """
- w = VT102Writer()
- p = TokenPrinter(w.write).printtoken
- s = StringIO.StringIO(source)
-
- tokenize.tokenize(s.readline, p)
-
- return str(w)
-
-class ColoredManhole(Manhole):
- """A REPL which syntax colors input as users type it.
- """
-
- def getSource(self):
- """Return a string containing the currently entered source.
-
- This is only the code which will be considered for execution
- next.
- """
- return ('\n'.join(self.interpreter.buffer) +
- '\n' +
- ''.join(self.lineBuffer))
-
-
- def characterReceived(self, ch, moreCharactersComing):
- if self.mode == 'insert':
- self.lineBuffer.insert(self.lineBufferIndex, ch)
- else:
- self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex+1] = [ch]
- self.lineBufferIndex += 1
-
- if moreCharactersComing:
- # Skip it all, we'll get called with another character in
- # like 2 femtoseconds.
- return
-
- if ch == ' ':
- # Don't bother to try to color whitespace
- self.terminal.write(ch)
- return
-
- source = self.getSource()
-
- # Try to write some junk
- try:
- coloredLine = lastColorizedLine(source)
- except tokenize.TokenError:
- # We couldn't do it. Strange. Oh well, just add the character.
- self.terminal.write(ch)
- else:
- # Success! Clear the source on this line.
- self.terminal.eraseLine()
- self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]) - 1)
-
- # And write a new, colorized one.
- self.terminal.write(self.ps[self.pn] + coloredLine)
-
- # And move the cursor to where it belongs
- n = len(self.lineBuffer) - self.lineBufferIndex
- if n:
- self.terminal.cursorBackward(n)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py
deleted file mode 100755
index a2297ef6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_manhole -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-insults/SSH integration support.
-
-@author: Jp Calderone
-"""
-
-from zope.interface import implements
-
-from twisted.conch import avatar, interfaces as iconch, error as econch
-from twisted.conch.ssh import factory, keys, session
-from twisted.cred import credentials, checkers, portal
-from twisted.python import components
-
-from twisted.conch.insults import insults
-
-class _Glue:
- """A feeble class for making one attribute look like another.
-
- This should be replaced with a real class at some point, probably.
- Try not to write new code that uses it.
- """
- def __init__(self, **kw):
- self.__dict__.update(kw)
-
- def __getattr__(self, name):
- raise AttributeError(self.name, "has no attribute", name)
-
-class TerminalSessionTransport:
- def __init__(self, proto, chainedProtocol, avatar, width, height):
- self.proto = proto
- self.avatar = avatar
- self.chainedProtocol = chainedProtocol
-
- session = self.proto.session
-
- self.proto.makeConnection(
- _Glue(write=self.chainedProtocol.dataReceived,
- loseConnection=lambda: avatar.conn.sendClose(session),
- name="SSH Proto Transport"))
-
- def loseConnection():
- self.proto.loseConnection()
-
- self.chainedProtocol.makeConnection(
- _Glue(write=self.proto.write,
- loseConnection=loseConnection,
- name="Chained Proto Transport"))
-
- # XXX TODO
- # chainedProtocol is supposed to be an ITerminalTransport,
- # maybe. That means perhaps its terminalProtocol attribute is
- # an ITerminalProtocol, it could be. So calling terminalSize
- # on that should do the right thing But it'd be nice to clean
- # this bit up.
- self.chainedProtocol.terminalProtocol.terminalSize(width, height)
-
-class TerminalSession(components.Adapter):
- implements(iconch.ISession)
-
- transportFactory = TerminalSessionTransport
- chainedProtocolFactory = insults.ServerProtocol
-
- def getPty(self, term, windowSize, attrs):
- self.height, self.width = windowSize[:2]
-
- def openShell(self, proto):
- self.transportFactory(
- proto, self.chainedProtocolFactory(),
- iconch.IConchUser(self.original),
- self.width, self.height)
-
- def execCommand(self, proto, cmd):
- raise econch.ConchError("Cannot execute commands")
-
- def closed(self):
- pass
-
-class TerminalUser(avatar.ConchUser, components.Adapter):
- def __init__(self, original, avatarId):
- components.Adapter.__init__(self, original)
- avatar.ConchUser.__init__(self)
- self.channelLookup['session'] = session.SSHSession
-
-class TerminalRealm:
- userFactory = TerminalUser
- sessionFactory = TerminalSession
-
- transportFactory = TerminalSessionTransport
- chainedProtocolFactory = insults.ServerProtocol
-
- def _getAvatar(self, avatarId):
- comp = components.Componentized()
- user = self.userFactory(comp, avatarId)
- sess = self.sessionFactory(comp)
-
- sess.transportFactory = self.transportFactory
- sess.chainedProtocolFactory = self.chainedProtocolFactory
-
- comp.setComponent(iconch.IConchUser, user)
- comp.setComponent(iconch.ISession, sess)
-
- return user
-
- def __init__(self, transportFactory=None):
- if transportFactory is not None:
- self.transportFactory = transportFactory
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- for i in interfaces:
- if i is iconch.IConchUser:
- return (iconch.IConchUser,
- self._getAvatar(avatarId),
- lambda: None)
- raise NotImplementedError()
-
-class ConchFactory(factory.SSHFactory):
- publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV'
-
- publicKeys = {
- 'ssh-rsa' : keys.Key.fromString(publicKey)
- }
- del publicKey
-
- privateKey = """-----BEGIN RSA PRIVATE KEY-----
-MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
-4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
-vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
-Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
-xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
-PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
-gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
-DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
-pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
-EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
------END RSA PRIVATE KEY-----"""
- privateKeys = {
- 'ssh-rsa' : keys.Key.fromString(privateKey)
- }
- del privateKey
-
- def __init__(self, portal):
- self.portal = portal
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py
deleted file mode 100755
index 4df7c839..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-TAP plugin for creating telnet- and ssh-accessible manhole servers.
-
-@author: Jp Calderone
-"""
-
-from zope.interface import implements
-
-from twisted.internet import protocol
-from twisted.application import service, strports
-from twisted.conch.ssh import session
-from twisted.conch import interfaces as iconch
-from twisted.cred import portal, checkers
-from twisted.python import usage
-
-from twisted.conch.insults import insults
-from twisted.conch import manhole, manhole_ssh, telnet
-
-class makeTelnetProtocol:
- def __init__(self, portal):
- self.portal = portal
-
- def __call__(self):
- auth = telnet.AuthenticatingTelnetProtocol
- args = (self.portal,)
- return telnet.TelnetTransport(auth, *args)
-
-class chainedProtocolFactory:
- def __init__(self, namespace):
- self.namespace = namespace
-
- def __call__(self):
- return insults.ServerProtocol(manhole.ColoredManhole, self.namespace)
-
-class _StupidRealm:
- implements(portal.IRealm)
-
- def __init__(self, proto, *a, **kw):
- self.protocolFactory = proto
- self.protocolArgs = a
- self.protocolKwArgs = kw
-
- def requestAvatar(self, avatarId, *interfaces):
- if telnet.ITelnetProtocol in interfaces:
- return (telnet.ITelnetProtocol,
- self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs),
- lambda: None)
- raise NotImplementedError()
-
-class Options(usage.Options):
- optParameters = [
- ["telnetPort", "t", None, "strports description of the address on which to listen for telnet connections"],
- ["sshPort", "s", None, "strports description of the address on which to listen for ssh connections"],
- ["passwd", "p", "/etc/passwd", "name of a passwd(5)-format username/password file"]]
-
- def __init__(self):
- usage.Options.__init__(self)
- self['namespace'] = None
-
- def postOptions(self):
- if self['telnetPort'] is None and self['sshPort'] is None:
- raise usage.UsageError("At least one of --telnetPort and --sshPort must be specified")
-
-def makeService(options):
- """Create a manhole server service.
-
- @type options: C{dict}
- @param options: A mapping describing the configuration of
- the desired service. Recognized key/value pairs are::
-
- "telnetPort": strports description of the address on which
- to listen for telnet connections. If None,
- no telnet service will be started.
-
- "sshPort": strports description of the address on which to
- listen for ssh connections. If None, no ssh
- service will be started.
-
- "namespace": dictionary containing desired initial locals
- for manhole connections. If None, an empty
- dictionary will be used.
-
- "passwd": Name of a passwd(5)-format username/password file.
-
- @rtype: L{twisted.application.service.IService}
- @return: A manhole service.
- """
-
- svc = service.MultiService()
-
- namespace = options['namespace']
- if namespace is None:
- namespace = {}
-
- checker = checkers.FilePasswordDB(options['passwd'])
-
- if options['telnetPort']:
- telnetRealm = _StupidRealm(telnet.TelnetBootstrapProtocol,
- insults.ServerProtocol,
- manhole.ColoredManhole,
- namespace)
-
- telnetPortal = portal.Portal(telnetRealm, [checker])
-
- telnetFactory = protocol.ServerFactory()
- telnetFactory.protocol = makeTelnetProtocol(telnetPortal)
- telnetService = strports.service(options['telnetPort'],
- telnetFactory)
- telnetService.setServiceParent(svc)
-
- if options['sshPort']:
- sshRealm = manhole_ssh.TerminalRealm()
- sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)
-
- sshPortal = portal.Portal(sshRealm, [checker])
- sshFactory = manhole_ssh.ConchFactory(sshPortal)
- sshService = strports.service(options['sshPort'],
- sshFactory)
- sshService.setServiceParent(svc)
-
- return svc
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py
deleted file mode 100755
index 581e2ff0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_mixin -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Experimental optimization
-
-This module provides a single mixin class which allows protocols to
-collapse numerous small writes into a single larger one.
-
-@author: Jp Calderone
-"""
-
-from twisted.internet import reactor
-
-class BufferingMixin:
- """Mixin which adds write buffering.
- """
- _delayedWriteCall = None
- bytes = None
-
- DELAY = 0.0
-
- def schedule(self):
- return reactor.callLater(self.DELAY, self.flush)
-
- def reschedule(self, token):
- token.reset(self.DELAY)
-
- def write(self, bytes):
- """Buffer some bytes to be written soon.
-
- Every call to this function delays the real write by C{self.DELAY}
- seconds. When the delay expires, all collected bytes are written
- to the underlying transport using L{ITransport.writeSequence}.
- """
- if self._delayedWriteCall is None:
- self.bytes = []
- self._delayedWriteCall = self.schedule()
- else:
- self.reschedule(self._delayedWriteCall)
- self.bytes.append(bytes)
-
- def flush(self):
- """Flush the buffer immediately.
- """
- self._delayedWriteCall = None
- self.transport.writeSequence(self.bytes)
- self.bytes = None
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py
deleted file mode 100755
index 69d5927d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-Support for OpenSSH configuration files.
-
-Maintainer: Paul Swartz
-"""
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py
deleted file mode 100755
index f0ad8f79..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_openssh_compat -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Factory for reading openssh configuration files: public keys, private keys, and
-moduli file.
-"""
-
-import os, errno
-
-from twisted.python import log
-from twisted.python.util import runAsEffectiveUser
-
-from twisted.conch.ssh import keys, factory, common
-from twisted.conch.openssh_compat import primes
-
-
-
-class OpenSSHFactory(factory.SSHFactory):
- dataRoot = '/usr/local/etc'
- moduliRoot = '/usr/local/etc' # for openbsd which puts moduli in a different
- # directory from keys
-
-
- def getPublicKeys(self):
- """
- Return the server public keys.
- """
- ks = {}
- for filename in os.listdir(self.dataRoot):
- if filename[:9] == 'ssh_host_' and filename[-8:]=='_key.pub':
- try:
- k = keys.Key.fromFile(
- os.path.join(self.dataRoot, filename))
- t = common.getNS(k.blob())[0]
- ks[t] = k
- except Exception, e:
- log.msg('bad public key file %s: %s' % (filename, e))
- return ks
-
-
- def getPrivateKeys(self):
- """
- Return the server private keys.
- """
- privateKeys = {}
- for filename in os.listdir(self.dataRoot):
- if filename[:9] == 'ssh_host_' and filename[-4:]=='_key':
- fullPath = os.path.join(self.dataRoot, filename)
- try:
- key = keys.Key.fromFile(fullPath)
- except IOError, e:
- if e.errno == errno.EACCES:
- # Not allowed, let's switch to root
- key = runAsEffectiveUser(0, 0, keys.Key.fromFile, fullPath)
- keyType = keys.objectType(key.keyObject)
- privateKeys[keyType] = key
- else:
- raise
- except Exception, e:
- log.msg('bad private key file %s: %s' % (filename, e))
- else:
- keyType = keys.objectType(key.keyObject)
- privateKeys[keyType] = key
- return privateKeys
-
-
- def getPrimes(self):
- try:
- return primes.parseModuliFile(self.moduliRoot+'/moduli')
- except IOError:
- return None
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py
deleted file mode 100755
index 5d939e6d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-Parsing for the moduli file, which contains Diffie-Hellman prime groups.
-
-Maintainer: Paul Swartz
-"""
-
-def parseModuliFile(filename):
- lines = open(filename).readlines()
- primes = {}
- for l in lines:
- l = l.strip()
- if not l or l[0]=='#':
- continue
- tim, typ, tst, tri, size, gen, mod = l.split()
- size = int(size) + 1
- gen = long(gen)
- mod = long(mod, 16)
- if not primes.has_key(size):
- primes[size] = []
- primes[size].append((gen, mod))
- return primes
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py
deleted file mode 100755
index 6c8416ae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_recvline -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Basic line editing support.
-
-@author: Jp Calderone
-"""
-
-import string
-
-from zope.interface import implements
-
-from twisted.conch.insults import insults, helper
-
-from twisted.python import log, reflect
-
-_counters = {}
-class Logging(object):
- """Wrapper which logs attribute lookups.
-
- This was useful in debugging something, I guess. I forget what.
- It can probably be deleted or moved somewhere more appropriate.
- Nothing special going on here, really.
- """
- def __init__(self, original):
- self.original = original
- key = reflect.qual(original.__class__)
- count = _counters.get(key, 0)
- _counters[key] = count + 1
- self._logFile = file(key + '-' + str(count), 'w')
-
- def __str__(self):
- return str(super(Logging, self).__getattribute__('original'))
-
- def __repr__(self):
- return repr(super(Logging, self).__getattribute__('original'))
-
- def __getattribute__(self, name):
- original = super(Logging, self).__getattribute__('original')
- logFile = super(Logging, self).__getattribute__('_logFile')
- logFile.write(name + '\n')
- return getattr(original, name)
-
-class TransportSequence(object):
- """An L{ITerminalTransport} implementation which forwards calls to
- one or more other L{ITerminalTransport}s.
-
- This is a cheap way for servers to keep track of the state they
- expect the client to see, since all terminal manipulations can be
- send to the real client and to a terminal emulator that lives in
- the server process.
- """
- implements(insults.ITerminalTransport)
-
- for keyID in ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW',
- 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN',
- 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
- 'F10', 'F11', 'F12'):
- exec '%s = object()' % (keyID,)
-
- TAB = '\t'
- BACKSPACE = '\x7f'
-
- def __init__(self, *transports):
- assert transports, "Cannot construct a TransportSequence with no transports"
- self.transports = transports
-
- for method in insults.ITerminalTransport:
- exec """\
-def %s(self, *a, **kw):
- for tpt in self.transports:
- result = tpt.%s(*a, **kw)
- return result
-""" % (method, method)
-
-class LocalTerminalBufferMixin(object):
- """A mixin for RecvLine subclasses which records the state of the terminal.
-
- This is accomplished by performing all L{ITerminalTransport} operations on both
- the transport passed to makeConnection and an instance of helper.TerminalBuffer.
-
- @ivar terminalCopy: A L{helper.TerminalBuffer} instance which efforts
- will be made to keep up to date with the actual terminal
- associated with this protocol instance.
- """
-
- def makeConnection(self, transport):
- self.terminalCopy = helper.TerminalBuffer()
- self.terminalCopy.connectionMade()
- return super(LocalTerminalBufferMixin, self).makeConnection(
- TransportSequence(transport, self.terminalCopy))
-
- def __str__(self):
- return str(self.terminalCopy)
-
-class RecvLine(insults.TerminalProtocol):
- """L{TerminalProtocol} which adds line editing features.
-
- Clients will be prompted for lines of input with all the usual
- features: character echoing, left and right arrow support for
- moving the cursor to different areas of the line buffer, backspace
- and delete for removing characters, and insert for toggling
- between typeover and insert mode. Tabs will be expanded to enough
- spaces to move the cursor to the next tabstop (every four
- characters by default). Enter causes the line buffer to be
- cleared and the line to be passed to the lineReceived() method
- which, by default, does nothing. Subclasses are responsible for
- redrawing the input prompt (this will probably change).
- """
- width = 80
- height = 24
-
- TABSTOP = 4
-
- ps = ('>>> ', '... ')
- pn = 0
- _printableChars = set(string.printable)
-
- def connectionMade(self):
- # A list containing the characters making up the current line
- self.lineBuffer = []
-
- # A zero-based (wtf else?) index into self.lineBuffer.
- # Indicates the current cursor position.
- self.lineBufferIndex = 0
-
- t = self.terminal
- # A map of keyIDs to bound instance methods.
- self.keyHandlers = {
- t.LEFT_ARROW: self.handle_LEFT,
- t.RIGHT_ARROW: self.handle_RIGHT,
- t.TAB: self.handle_TAB,
-
- # Both of these should not be necessary, but figuring out
- # which is necessary is a huge hassle.
- '\r': self.handle_RETURN,
- '\n': self.handle_RETURN,
-
- t.BACKSPACE: self.handle_BACKSPACE,
- t.DELETE: self.handle_DELETE,
- t.INSERT: self.handle_INSERT,
- t.HOME: self.handle_HOME,
- t.END: self.handle_END}
-
- self.initializeScreen()
-
- def initializeScreen(self):
- # Hmm, state sucks. Oh well.
- # For now we will just take over the whole terminal.
- self.terminal.reset()
- self.terminal.write(self.ps[self.pn])
- # XXX Note: I would prefer to default to starting in insert
- # mode, however this does not seem to actually work! I do not
- # know why. This is probably of interest to implementors
- # subclassing RecvLine.
-
- # XXX XXX Note: But the unit tests all expect the initial mode
- # to be insert right now. Fuck, there needs to be a way to
- # query the current mode or something.
- # self.setTypeoverMode()
- self.setInsertMode()
-
- def currentLineBuffer(self):
- s = ''.join(self.lineBuffer)
- return s[:self.lineBufferIndex], s[self.lineBufferIndex:]
-
- def setInsertMode(self):
- self.mode = 'insert'
- self.terminal.setModes([insults.modes.IRM])
-
- def setTypeoverMode(self):
- self.mode = 'typeover'
- self.terminal.resetModes([insults.modes.IRM])
-
- def drawInputLine(self):
- """
- Write a line containing the current input prompt and the current line
- buffer at the current cursor position.
- """
- self.terminal.write(self.ps[self.pn] + ''.join(self.lineBuffer))
-
- def terminalSize(self, width, height):
- # XXX - Clear the previous input line, redraw it at the new
- # cursor position
- self.terminal.eraseDisplay()
- self.terminal.cursorHome()
- self.width = width
- self.height = height
- self.drawInputLine()
-
- def unhandledControlSequence(self, seq):
- pass
-
- def keystrokeReceived(self, keyID, modifier):
- m = self.keyHandlers.get(keyID)
- if m is not None:
- m()
- elif keyID in self._printableChars:
- self.characterReceived(keyID, False)
- else:
- log.msg("Received unhandled keyID: %r" % (keyID,))
-
- def characterReceived(self, ch, moreCharactersComing):
- if self.mode == 'insert':
- self.lineBuffer.insert(self.lineBufferIndex, ch)
- else:
- self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex+1] = [ch]
- self.lineBufferIndex += 1
- self.terminal.write(ch)
-
- def handle_TAB(self):
- n = self.TABSTOP - (len(self.lineBuffer) % self.TABSTOP)
- self.terminal.cursorForward(n)
- self.lineBufferIndex += n
- self.lineBuffer.extend(' ' * n)
-
- def handle_LEFT(self):
- if self.lineBufferIndex > 0:
- self.lineBufferIndex -= 1
- self.terminal.cursorBackward()
-
- def handle_RIGHT(self):
- if self.lineBufferIndex < len(self.lineBuffer):
- self.lineBufferIndex += 1
- self.terminal.cursorForward()
-
- def handle_HOME(self):
- if self.lineBufferIndex:
- self.terminal.cursorBackward(self.lineBufferIndex)
- self.lineBufferIndex = 0
-
- def handle_END(self):
- offset = len(self.lineBuffer) - self.lineBufferIndex
- if offset:
- self.terminal.cursorForward(offset)
- self.lineBufferIndex = len(self.lineBuffer)
-
- def handle_BACKSPACE(self):
- if self.lineBufferIndex > 0:
- self.lineBufferIndex -= 1
- del self.lineBuffer[self.lineBufferIndex]
- self.terminal.cursorBackward()
- self.terminal.deleteCharacter()
-
- def handle_DELETE(self):
- if self.lineBufferIndex < len(self.lineBuffer):
- del self.lineBuffer[self.lineBufferIndex]
- self.terminal.deleteCharacter()
-
- def handle_RETURN(self):
- line = ''.join(self.lineBuffer)
- self.lineBuffer = []
- self.lineBufferIndex = 0
- self.terminal.nextLine()
- self.lineReceived(line)
-
- def handle_INSERT(self):
- assert self.mode in ('typeover', 'insert')
- if self.mode == 'typeover':
- self.setInsertMode()
- else:
- self.setTypeoverMode()
-
- def lineReceived(self, line):
- pass
-
-class HistoricRecvLine(RecvLine):
- """L{TerminalProtocol} which adds both basic line-editing features and input history.
-
- Everything supported by L{RecvLine} is also supported by this class. In addition, the
- up and down arrows traverse the input history. Each received line is automatically
- added to the end of the input history.
- """
- def connectionMade(self):
- RecvLine.connectionMade(self)
-
- self.historyLines = []
- self.historyPosition = 0
-
- t = self.terminal
- self.keyHandlers.update({t.UP_ARROW: self.handle_UP,
- t.DOWN_ARROW: self.handle_DOWN})
-
- def currentHistoryBuffer(self):
- b = tuple(self.historyLines)
- return b[:self.historyPosition], b[self.historyPosition:]
-
- def _deliverBuffer(self, buf):
- if buf:
- for ch in buf[:-1]:
- self.characterReceived(ch, True)
- self.characterReceived(buf[-1], False)
-
- def handle_UP(self):
- if self.lineBuffer and self.historyPosition == len(self.historyLines):
- self.historyLines.append(self.lineBuffer)
- if self.historyPosition > 0:
- self.handle_HOME()
- self.terminal.eraseToLineEnd()
-
- self.historyPosition -= 1
- self.lineBuffer = []
-
- self._deliverBuffer(self.historyLines[self.historyPosition])
-
- def handle_DOWN(self):
- if self.historyPosition < len(self.historyLines) - 1:
- self.handle_HOME()
- self.terminal.eraseToLineEnd()
-
- self.historyPosition += 1
- self.lineBuffer = []
-
- self._deliverBuffer(self.historyLines[self.historyPosition])
- else:
- self.handle_HOME()
- self.terminal.eraseToLineEnd()
-
- self.historyPosition = len(self.historyLines)
- self.lineBuffer = []
- self.lineBufferIndex = 0
-
- def handle_RETURN(self):
- if self.lineBuffer:
- self.historyLines.append(''.join(self.lineBuffer))
- self.historyPosition = len(self.historyLines)
- return RecvLine.handle_RETURN(self)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py
deleted file mode 100755
index 63fdb3d2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-'conch scripts'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py
deleted file mode 100755
index e6db67f0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py
+++ /dev/null
@@ -1,832 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_cftp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation module for the I{cftp} command.
-"""
-
-import os, sys, getpass, struct, tty, fcntl, stat
-import fnmatch, pwd, glob
-
-from twisted.conch.client import connect, default, options
-from twisted.conch.ssh import connection, common
-from twisted.conch.ssh import channel, filetransfer
-from twisted.protocols import basic
-from twisted.internet import reactor, stdio, defer, utils
-from twisted.python import log, usage, failure
-
-class ClientOptions(options.ConchOptions):
-
- synopsis = """Usage: cftp [options] [user@]host
- cftp [options] [user@]host[:dir[/]]
- cftp [options] [user@]host[:file [localfile]]
-"""
- longdesc = ("cftp is a client for logging into a remote machine and "
- "executing commands to send and receive file information")
-
- optParameters = [
- ['buffersize', 'B', 32768, 'Size of the buffer to use for sending/receiving.'],
- ['batchfile', 'b', None, 'File to read commands from, or \'-\' for stdin.'],
- ['requests', 'R', 5, 'Number of requests to make before waiting for a reply.'],
- ['subsystem', 's', 'sftp', 'Subsystem/server program to connect to.']]
-
- compData = usage.Completions(
- descriptions={
- "buffersize": "Size of send/receive buffer (default: 32768)"},
- extraActions=[usage.CompleteUserAtHost(),
- usage.CompleteFiles(descr="local file")])
-
- def parseArgs(self, host, localPath=None):
- self['remotePath'] = ''
- if ':' in host:
- host, self['remotePath'] = host.split(':', 1)
- self['remotePath'].rstrip('/')
- self['host'] = host
- self['localPath'] = localPath
-
-def run():
-# import hotshot
-# prof = hotshot.Profile('cftp.prof')
-# prof.start()
- args = sys.argv[1:]
- if '-l' in args: # cvs is an idiot
- i = args.index('-l')
- args = args[i:i+2]+args
- del args[i+2:i+4]
- options = ClientOptions()
- try:
- options.parseOptions(args)
- except usage.UsageError, u:
- print 'ERROR: %s' % u
- sys.exit(1)
- if options['log']:
- realout = sys.stdout
- log.startLogging(sys.stderr)
- sys.stdout = realout
- else:
- log.discardLogs()
- doConnect(options)
- reactor.run()
-# prof.stop()
-# prof.close()
-
-def handleError():
- global exitStatus
- exitStatus = 2
- try:
- reactor.stop()
- except: pass
- log.err(failure.Failure())
- raise
-
-def doConnect(options):
-# log.deferr = handleError # HACK
- if '@' in options['host']:
- options['user'], options['host'] = options['host'].split('@',1)
- host = options['host']
- if not options['user']:
- options['user'] = getpass.getuser()
- if not options['port']:
- options['port'] = 22
- else:
- options['port'] = int(options['port'])
- host = options['host']
- port = options['port']
- conn = SSHConnection()
- conn.options = options
- vhk = default.verifyHostKey
- uao = default.SSHUserAuthClient(options['user'], options, conn)
- connect.connect(host, port, options, vhk, uao).addErrback(_ebExit)
-
-def _ebExit(f):
- #global exitStatus
- if hasattr(f.value, 'value'):
- s = f.value.value
- else:
- s = str(f)
- print s
- #exitStatus = "conch: exiting with error %s" % f
- try:
- reactor.stop()
- except: pass
-
-def _ignore(*args): pass
-
-class FileWrapper:
-
- def __init__(self, f):
- self.f = f
- self.total = 0.0
- f.seek(0, 2) # seek to the end
- self.size = f.tell()
-
- def __getattr__(self, attr):
- return getattr(self.f, attr)
-
-class StdioClient(basic.LineReceiver):
-
- _pwd = pwd
-
- ps = 'cftp> '
- delimiter = '\n'
-
- reactor = reactor
-
- def __init__(self, client, f = None):
- self.client = client
- self.currentDirectory = ''
- self.file = f
- self.useProgressBar = (not f and 1) or 0
-
- def connectionMade(self):
- self.client.realPath('').addCallback(self._cbSetCurDir)
-
- def _cbSetCurDir(self, path):
- self.currentDirectory = path
- self._newLine()
-
- def lineReceived(self, line):
- if self.client.transport.localClosed:
- return
- log.msg('got line %s' % repr(line))
- line = line.lstrip()
- if not line:
- self._newLine()
- return
- if self.file and line.startswith('-'):
- self.ignoreErrors = 1
- line = line[1:]
- else:
- self.ignoreErrors = 0
- d = self._dispatchCommand(line)
- if d is not None:
- d.addCallback(self._cbCommand)
- d.addErrback(self._ebCommand)
-
-
- def _dispatchCommand(self, line):
- if ' ' in line:
- command, rest = line.split(' ', 1)
- rest = rest.lstrip()
- else:
- command, rest = line, ''
- if command.startswith('!'): # command
- f = self.cmd_EXEC
- rest = (command[1:] + ' ' + rest).strip()
- else:
- command = command.upper()
- log.msg('looking up cmd %s' % command)
- f = getattr(self, 'cmd_%s' % command, None)
- if f is not None:
- return defer.maybeDeferred(f, rest)
- else:
- self._ebCommand(failure.Failure(NotImplementedError(
- "No command called `%s'" % command)))
- self._newLine()
-
- def _printFailure(self, f):
- log.msg(f)
- e = f.trap(NotImplementedError, filetransfer.SFTPError, OSError, IOError)
- if e == NotImplementedError:
- self.transport.write(self.cmd_HELP(''))
- elif e == filetransfer.SFTPError:
- self.transport.write("remote error %i: %s\n" %
- (f.value.code, f.value.message))
- elif e in (OSError, IOError):
- self.transport.write("local error %i: %s\n" %
- (f.value.errno, f.value.strerror))
-
- def _newLine(self):
- if self.client.transport.localClosed:
- return
- self.transport.write(self.ps)
- self.ignoreErrors = 0
- if self.file:
- l = self.file.readline()
- if not l:
- self.client.transport.loseConnection()
- else:
- self.transport.write(l)
- self.lineReceived(l.strip())
-
- def _cbCommand(self, result):
- if result is not None:
- self.transport.write(result)
- if not result.endswith('\n'):
- self.transport.write('\n')
- self._newLine()
-
- def _ebCommand(self, f):
- self._printFailure(f)
- if self.file and not self.ignoreErrors:
- self.client.transport.loseConnection()
- self._newLine()
-
- def cmd_CD(self, path):
- path, rest = self._getFilename(path)
- if not path.endswith('/'):
- path += '/'
- newPath = path and os.path.join(self.currentDirectory, path) or ''
- d = self.client.openDirectory(newPath)
- d.addCallback(self._cbCd)
- d.addErrback(self._ebCommand)
- return d
-
- def _cbCd(self, directory):
- directory.close()
- d = self.client.realPath(directory.name)
- d.addCallback(self._cbCurDir)
- return d
-
- def _cbCurDir(self, path):
- self.currentDirectory = path
-
- def cmd_CHGRP(self, rest):
- grp, rest = rest.split(None, 1)
- path, rest = self._getFilename(rest)
- grp = int(grp)
- d = self.client.getAttrs(path)
- d.addCallback(self._cbSetUsrGrp, path, grp=grp)
- return d
-
- def cmd_CHMOD(self, rest):
- mod, rest = rest.split(None, 1)
- path, rest = self._getFilename(rest)
- mod = int(mod, 8)
- d = self.client.setAttrs(path, {'permissions':mod})
- d.addCallback(_ignore)
- return d
-
- def cmd_CHOWN(self, rest):
- usr, rest = rest.split(None, 1)
- path, rest = self._getFilename(rest)
- usr = int(usr)
- d = self.client.getAttrs(path)
- d.addCallback(self._cbSetUsrGrp, path, usr=usr)
- return d
-
- def _cbSetUsrGrp(self, attrs, path, usr=None, grp=None):
- new = {}
- new['uid'] = (usr is not None) and usr or attrs['uid']
- new['gid'] = (grp is not None) and grp or attrs['gid']
- d = self.client.setAttrs(path, new)
- d.addCallback(_ignore)
- return d
-
- def cmd_GET(self, rest):
- remote, rest = self._getFilename(rest)
- if '*' in remote or '?' in remote: # wildcard
- if rest:
- local, rest = self._getFilename(rest)
- if not os.path.isdir(local):
- return "Wildcard get with non-directory target."
- else:
- local = ''
- d = self._remoteGlob(remote)
- d.addCallback(self._cbGetMultiple, local)
- return d
- if rest:
- local, rest = self._getFilename(rest)
- else:
- local = os.path.split(remote)[1]
- log.msg((remote, local))
- lf = file(local, 'w', 0)
- path = os.path.join(self.currentDirectory, remote)
- d = self.client.openFile(path, filetransfer.FXF_READ, {})
- d.addCallback(self._cbGetOpenFile, lf)
- d.addErrback(self._ebCloseLf, lf)
- return d
-
- def _cbGetMultiple(self, files, local):
- #if self._useProgressBar: # one at a time
- # XXX this can be optimized for times w/o progress bar
- return self._cbGetMultipleNext(None, files, local)
-
- def _cbGetMultipleNext(self, res, files, local):
- if isinstance(res, failure.Failure):
- self._printFailure(res)
- elif res:
- self.transport.write(res)
- if not res.endswith('\n'):
- self.transport.write('\n')
- if not files:
- return
- f = files.pop(0)[0]
- lf = file(os.path.join(local, os.path.split(f)[1]), 'w', 0)
- path = os.path.join(self.currentDirectory, f)
- d = self.client.openFile(path, filetransfer.FXF_READ, {})
- d.addCallback(self._cbGetOpenFile, lf)
- d.addErrback(self._ebCloseLf, lf)
- d.addBoth(self._cbGetMultipleNext, files, local)
- return d
-
- def _ebCloseLf(self, f, lf):
- lf.close()
- return f
-
- def _cbGetOpenFile(self, rf, lf):
- return rf.getAttrs().addCallback(self._cbGetFileSize, rf, lf)
-
- def _cbGetFileSize(self, attrs, rf, lf):
- if not stat.S_ISREG(attrs['permissions']):
- rf.close()
- lf.close()
- return "Can't get non-regular file: %s" % rf.name
- rf.size = attrs['size']
- bufferSize = self.client.transport.conn.options['buffersize']
- numRequests = self.client.transport.conn.options['requests']
- rf.total = 0.0
- dList = []
- chunks = []
- startTime = self.reactor.seconds()
- for i in range(numRequests):
- d = self._cbGetRead('', rf, lf, chunks, 0, bufferSize, startTime)
- dList.append(d)
- dl = defer.DeferredList(dList, fireOnOneErrback=1)
- dl.addCallback(self._cbGetDone, rf, lf)
- return dl
-
- def _getNextChunk(self, chunks):
- end = 0
- for chunk in chunks:
- if end == 'eof':
- return # nothing more to get
- if end != chunk[0]:
- i = chunks.index(chunk)
- chunks.insert(i, (end, chunk[0]))
- return (end, chunk[0] - end)
- end = chunk[1]
- bufSize = int(self.client.transport.conn.options['buffersize'])
- chunks.append((end, end + bufSize))
- return (end, bufSize)
-
- def _cbGetRead(self, data, rf, lf, chunks, start, size, startTime):
- if data and isinstance(data, failure.Failure):
- log.msg('get read err: %s' % data)
- reason = data
- reason.trap(EOFError)
- i = chunks.index((start, start + size))
- del chunks[i]
- chunks.insert(i, (start, 'eof'))
- elif data:
- log.msg('get read data: %i' % len(data))
- lf.seek(start)
- lf.write(data)
- if len(data) != size:
- log.msg('got less than we asked for: %i < %i' %
- (len(data), size))
- i = chunks.index((start, start + size))
- del chunks[i]
- chunks.insert(i, (start, start + len(data)))
- rf.total += len(data)
- if self.useProgressBar:
- self._printProgressBar(rf, startTime)
- chunk = self._getNextChunk(chunks)
- if not chunk:
- return
- else:
- start, length = chunk
- log.msg('asking for %i -> %i' % (start, start+length))
- d = rf.readChunk(start, length)
- d.addBoth(self._cbGetRead, rf, lf, chunks, start, length, startTime)
- return d
-
- def _cbGetDone(self, ignored, rf, lf):
- log.msg('get done')
- rf.close()
- lf.close()
- if self.useProgressBar:
- self.transport.write('\n')
- return "Transferred %s to %s" % (rf.name, lf.name)
-
- def cmd_PUT(self, rest):
- local, rest = self._getFilename(rest)
- if '*' in local or '?' in local: # wildcard
- if rest:
- remote, rest = self._getFilename(rest)
- path = os.path.join(self.currentDirectory, remote)
- d = self.client.getAttrs(path)
- d.addCallback(self._cbPutTargetAttrs, remote, local)
- return d
- else:
- remote = ''
- files = glob.glob(local)
- return self._cbPutMultipleNext(None, files, remote)
- if rest:
- remote, rest = self._getFilename(rest)
- else:
- remote = os.path.split(local)[1]
- lf = file(local, 'r')
- path = os.path.join(self.currentDirectory, remote)
- flags = filetransfer.FXF_WRITE|filetransfer.FXF_CREAT|filetransfer.FXF_TRUNC
- d = self.client.openFile(path, flags, {})
- d.addCallback(self._cbPutOpenFile, lf)
- d.addErrback(self._ebCloseLf, lf)
- return d
-
- def _cbPutTargetAttrs(self, attrs, path, local):
- if not stat.S_ISDIR(attrs['permissions']):
- return "Wildcard put with non-directory target."
- return self._cbPutMultipleNext(None, files, path)
-
- def _cbPutMultipleNext(self, res, files, path):
- if isinstance(res, failure.Failure):
- self._printFailure(res)
- elif res:
- self.transport.write(res)
- if not res.endswith('\n'):
- self.transport.write('\n')
- f = None
- while files and not f:
- try:
- f = files.pop(0)
- lf = file(f, 'r')
- except:
- self._printFailure(failure.Failure())
- f = None
- if not f:
- return
- name = os.path.split(f)[1]
- remote = os.path.join(self.currentDirectory, path, name)
- log.msg((name, remote, path))
- flags = filetransfer.FXF_WRITE|filetransfer.FXF_CREAT|filetransfer.FXF_TRUNC
- d = self.client.openFile(remote, flags, {})
- d.addCallback(self._cbPutOpenFile, lf)
- d.addErrback(self._ebCloseLf, lf)
- d.addBoth(self._cbPutMultipleNext, files, path)
- return d
-
- def _cbPutOpenFile(self, rf, lf):
- numRequests = self.client.transport.conn.options['requests']
- if self.useProgressBar:
- lf = FileWrapper(lf)
- dList = []
- chunks = []
- startTime = self.reactor.seconds()
- for i in range(numRequests):
- d = self._cbPutWrite(None, rf, lf, chunks, startTime)
- if d:
- dList.append(d)
- dl = defer.DeferredList(dList, fireOnOneErrback=1)
- dl.addCallback(self._cbPutDone, rf, lf)
- return dl
-
- def _cbPutWrite(self, ignored, rf, lf, chunks, startTime):
- chunk = self._getNextChunk(chunks)
- start, size = chunk
- lf.seek(start)
- data = lf.read(size)
- if self.useProgressBar:
- lf.total += len(data)
- self._printProgressBar(lf, startTime)
- if data:
- d = rf.writeChunk(start, data)
- d.addCallback(self._cbPutWrite, rf, lf, chunks, startTime)
- return d
- else:
- return
-
- def _cbPutDone(self, ignored, rf, lf):
- lf.close()
- rf.close()
- if self.useProgressBar:
- self.transport.write('\n')
- return 'Transferred %s to %s' % (lf.name, rf.name)
-
- def cmd_LCD(self, path):
- os.chdir(path)
-
- def cmd_LN(self, rest):
- linkpath, rest = self._getFilename(rest)
- targetpath, rest = self._getFilename(rest)
- linkpath, targetpath = map(
- lambda x: os.path.join(self.currentDirectory, x),
- (linkpath, targetpath))
- return self.client.makeLink(linkpath, targetpath).addCallback(_ignore)
-
- def cmd_LS(self, rest):
- # possible lines:
- # ls current directory
- # ls name_of_file that file
- # ls name_of_directory that directory
- # ls some_glob_string current directory, globbed for that string
- options = []
- rest = rest.split()
- while rest and rest[0] and rest[0][0] == '-':
- opts = rest.pop(0)[1:]
- for o in opts:
- if o == 'l':
- options.append('verbose')
- elif o == 'a':
- options.append('all')
- rest = ' '.join(rest)
- path, rest = self._getFilename(rest)
- if not path:
- fullPath = self.currentDirectory + '/'
- else:
- fullPath = os.path.join(self.currentDirectory, path)
- d = self._remoteGlob(fullPath)
- d.addCallback(self._cbDisplayFiles, options)
- return d
-
- def _cbDisplayFiles(self, files, options):
- files.sort()
- if 'all' not in options:
- files = [f for f in files if not f[0].startswith('.')]
- if 'verbose' in options:
- lines = [f[1] for f in files]
- else:
- lines = [f[0] for f in files]
- if not lines:
- return None
- else:
- return '\n'.join(lines)
-
- def cmd_MKDIR(self, path):
- path, rest = self._getFilename(path)
- path = os.path.join(self.currentDirectory, path)
- return self.client.makeDirectory(path, {}).addCallback(_ignore)
-
- def cmd_RMDIR(self, path):
- path, rest = self._getFilename(path)
- path = os.path.join(self.currentDirectory, path)
- return self.client.removeDirectory(path).addCallback(_ignore)
-
- def cmd_LMKDIR(self, path):
- os.system("mkdir %s" % path)
-
- def cmd_RM(self, path):
- path, rest = self._getFilename(path)
- path = os.path.join(self.currentDirectory, path)
- return self.client.removeFile(path).addCallback(_ignore)
-
- def cmd_LLS(self, rest):
- os.system("ls %s" % rest)
-
- def cmd_RENAME(self, rest):
- oldpath, rest = self._getFilename(rest)
- newpath, rest = self._getFilename(rest)
- oldpath, newpath = map (
- lambda x: os.path.join(self.currentDirectory, x),
- (oldpath, newpath))
- return self.client.renameFile(oldpath, newpath).addCallback(_ignore)
-
- def cmd_EXIT(self, ignored):
- self.client.transport.loseConnection()
-
- cmd_QUIT = cmd_EXIT
-
- def cmd_VERSION(self, ignored):
- return "SFTP version %i" % self.client.version
-
- def cmd_HELP(self, ignored):
- return """Available commands:
-cd path Change remote directory to 'path'.
-chgrp gid path Change gid of 'path' to 'gid'.
-chmod mode path Change mode of 'path' to 'mode'.
-chown uid path Change uid of 'path' to 'uid'.
-exit Disconnect from the server.
-get remote-path [local-path] Get remote file.
-help Get a list of available commands.
-lcd path Change local directory to 'path'.
-lls [ls-options] [path] Display local directory listing.
-lmkdir path Create local directory.
-ln linkpath targetpath Symlink remote file.
-lpwd Print the local working directory.
-ls [-l] [path] Display remote directory listing.
-mkdir path Create remote directory.
-progress Toggle progress bar.
-put local-path [remote-path] Put local file.
-pwd Print the remote working directory.
-quit Disconnect from the server.
-rename oldpath newpath Rename remote file.
-rmdir path Remove remote directory.
-rm path Remove remote file.
-version Print the SFTP version.
-? Synonym for 'help'.
-"""
-
- def cmd_PWD(self, ignored):
- return self.currentDirectory
-
- def cmd_LPWD(self, ignored):
- return os.getcwd()
-
- def cmd_PROGRESS(self, ignored):
- self.useProgressBar = not self.useProgressBar
- return "%ssing progess bar." % (self.useProgressBar and "U" or "Not u")
-
- def cmd_EXEC(self, rest):
- """
- Run C{rest} using the user's shell (or /bin/sh if they do not have
- one).
- """
- shell = self._pwd.getpwnam(getpass.getuser())[6]
- if not shell:
- shell = '/bin/sh'
- if rest:
- cmds = ['-c', rest]
- return utils.getProcessOutput(shell, cmds, errortoo=1)
- else:
- os.system(shell)
-
- # accessory functions
-
- def _remoteGlob(self, fullPath):
- log.msg('looking up %s' % fullPath)
- head, tail = os.path.split(fullPath)
- if '*' in tail or '?' in tail:
- glob = 1
- else:
- glob = 0
- if tail and not glob: # could be file or directory
- # try directory first
- d = self.client.openDirectory(fullPath)
- d.addCallback(self._cbOpenList, '')
- d.addErrback(self._ebNotADirectory, head, tail)
- else:
- d = self.client.openDirectory(head)
- d.addCallback(self._cbOpenList, tail)
- return d
-
- def _cbOpenList(self, directory, glob):
- files = []
- d = directory.read()
- d.addBoth(self._cbReadFile, files, directory, glob)
- return d
-
- def _ebNotADirectory(self, reason, path, glob):
- d = self.client.openDirectory(path)
- d.addCallback(self._cbOpenList, glob)
- return d
-
- def _cbReadFile(self, files, l, directory, glob):
- if not isinstance(files, failure.Failure):
- if glob:
- l.extend([f for f in files if fnmatch.fnmatch(f[0], glob)])
- else:
- l.extend(files)
- d = directory.read()
- d.addBoth(self._cbReadFile, l, directory, glob)
- return d
- else:
- reason = files
- reason.trap(EOFError)
- directory.close()
- return l
-
- def _abbrevSize(self, size):
- # from http://mail.python.org/pipermail/python-list/1999-December/018395.html
- _abbrevs = [
- (1<<50L, 'PB'),
- (1<<40L, 'TB'),
- (1<<30L, 'GB'),
- (1<<20L, 'MB'),
- (1<<10L, 'kB'),
- (1, 'B')
- ]
-
- for factor, suffix in _abbrevs:
- if size > factor:
- break
- return '%.1f' % (size/factor) + suffix
-
- def _abbrevTime(self, t):
- if t > 3600: # 1 hour
- hours = int(t / 3600)
- t -= (3600 * hours)
- mins = int(t / 60)
- t -= (60 * mins)
- return "%i:%02i:%02i" % (hours, mins, t)
- else:
- mins = int(t/60)
- t -= (60 * mins)
- return "%02i:%02i" % (mins, t)
-
-
- def _printProgressBar(self, f, startTime):
- """
- Update a console progress bar on this L{StdioClient}'s transport, based
- on the difference between the start time of the operation and the
- current time according to the reactor, and appropriate to the size of
- the console window.
-
- @param f: a wrapper around the file which is being written or read
- @type f: L{FileWrapper}
-
- @param startTime: The time at which the operation being tracked began.
- @type startTime: C{float}
- """
- diff = self.reactor.seconds() - startTime
- total = f.total
- try:
- winSize = struct.unpack('4H',
- fcntl.ioctl(0, tty.TIOCGWINSZ, '12345679'))
- except IOError:
- winSize = [None, 80]
- if diff == 0.0:
- speed = 0.0
- else:
- speed = total / diff
- if speed:
- timeLeft = (f.size - total) / speed
- else:
- timeLeft = 0
- front = f.name
- back = '%3i%% %s %sps %s ' % ((total / f.size) * 100,
- self._abbrevSize(total),
- self._abbrevSize(speed),
- self._abbrevTime(timeLeft))
- spaces = (winSize[1] - (len(front) + len(back) + 1)) * ' '
- self.transport.write('\r%s%s%s' % (front, spaces, back))
-
-
- def _getFilename(self, line):
- line.lstrip()
- if not line:
- return None, ''
- if line[0] in '\'"':
- ret = []
- line = list(line)
- try:
- for i in range(1,len(line)):
- c = line[i]
- if c == line[0]:
- return ''.join(ret), ''.join(line[i+1:]).lstrip()
- elif c == '\\': # quoted character
- del line[i]
- if line[i] not in '\'"\\':
- raise IndexError, "bad quote: \\%s" % line[i]
- ret.append(line[i])
- else:
- ret.append(line[i])
- except IndexError:
- raise IndexError, "unterminated quote"
- ret = line.split(None, 1)
- if len(ret) == 1:
- return ret[0], ''
- else:
- return ret
-
-StdioClient.__dict__['cmd_?'] = StdioClient.cmd_HELP
-
-class SSHConnection(connection.SSHConnection):
- def serviceStarted(self):
- self.openChannel(SSHSession())
-
-class SSHSession(channel.SSHChannel):
-
- name = 'session'
-
- def channelOpen(self, foo):
- log.msg('session %s open' % self.id)
- if self.conn.options['subsystem'].startswith('/'):
- request = 'exec'
- else:
- request = 'subsystem'
- d = self.conn.sendRequest(self, request, \
- common.NS(self.conn.options['subsystem']), wantReply=1)
- d.addCallback(self._cbSubsystem)
- d.addErrback(_ebExit)
-
- def _cbSubsystem(self, result):
- self.client = filetransfer.FileTransferClient()
- self.client.makeConnection(self)
- self.dataReceived = self.client.dataReceived
- f = None
- if self.conn.options['batchfile']:
- fn = self.conn.options['batchfile']
- if fn != '-':
- f = file(fn)
- self.stdio = stdio.StandardIO(StdioClient(self.client, f))
-
- def extReceived(self, t, data):
- if t==connection.EXTENDED_DATA_STDERR:
- log.msg('got %s stderr data' % len(data))
- sys.stderr.write(data)
- sys.stderr.flush()
-
- def eofReceived(self):
- log.msg('got eof')
- self.stdio.closeStdin()
-
- def closeReceived(self):
- log.msg('remote side closed %s' % self)
- self.conn.sendClose(self)
-
- def closed(self):
- try:
- reactor.stop()
- except:
- pass
-
- def stopWriting(self):
- self.stdio.pauseProducing()
-
- def startWriting(self):
- self.stdio.resumeProducing()
-
-if __name__ == '__main__':
- run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py
deleted file mode 100755
index ab51fc19..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_ckeygen -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation module for the `ckeygen` command.
-"""
-
-import sys, os, getpass, socket
-if getpass.getpass == getpass.unix_getpass:
- try:
- import termios # hack around broken termios
- termios.tcgetattr, termios.tcsetattr
- except (ImportError, AttributeError):
- sys.modules['termios'] = None
- reload(getpass)
-
-from twisted.conch.ssh import keys
-from twisted.python import filepath, log, usage, randbytes
-
-
-class GeneralOptions(usage.Options):
- synopsis = """Usage: ckeygen [options]
- """
-
- longdesc = "ckeygen manipulates public/private keys in various ways."
-
- optParameters = [['bits', 'b', 1024, 'Number of bits in the key to create.'],
- ['filename', 'f', None, 'Filename of the key file.'],
- ['type', 't', None, 'Specify type of key to create.'],
- ['comment', 'C', None, 'Provide new comment.'],
- ['newpass', 'N', None, 'Provide new passphrase.'],
- ['pass', 'P', None, 'Provide old passphrase']]
-
- optFlags = [['fingerprint', 'l', 'Show fingerprint of key file.'],
- ['changepass', 'p', 'Change passphrase of private key file.'],
- ['quiet', 'q', 'Quiet.'],
- ['showpub', 'y', 'Read private key file and print public key.']]
-
- compData = usage.Completions(
- optActions={"type": usage.CompleteList(["rsa", "dsa"])})
-
-def run():
- options = GeneralOptions()
- try:
- options.parseOptions(sys.argv[1:])
- except usage.UsageError, u:
- print 'ERROR: %s' % u
- options.opt_help()
- sys.exit(1)
- log.discardLogs()
- log.deferr = handleError # HACK
- if options['type']:
- if options['type'] == 'rsa':
- generateRSAkey(options)
- elif options['type'] == 'dsa':
- generateDSAkey(options)
- else:
- sys.exit('Key type was %s, must be one of: rsa, dsa' % options['type'])
- elif options['fingerprint']:
- printFingerprint(options)
- elif options['changepass']:
- changePassPhrase(options)
- elif options['showpub']:
- displayPublicKey(options)
- else:
- options.opt_help()
- sys.exit(1)
-
-def handleError():
- from twisted.python import failure
- global exitStatus
- exitStatus = 2
- log.err(failure.Failure())
- reactor.stop()
- raise
-
-def generateRSAkey(options):
- from Crypto.PublicKey import RSA
- print 'Generating public/private rsa key pair.'
- key = RSA.generate(int(options['bits']), randbytes.secureRandom)
- _saveKey(key, options)
-
-def generateDSAkey(options):
- from Crypto.PublicKey import DSA
- print 'Generating public/private dsa key pair.'
- key = DSA.generate(int(options['bits']), randbytes.secureRandom)
- _saveKey(key, options)
-
-
-def printFingerprint(options):
- if not options['filename']:
- filename = os.path.expanduser('~/.ssh/id_rsa')
- options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename)
- if os.path.exists(options['filename']+'.pub'):
- options['filename'] += '.pub'
- try:
- key = keys.Key.fromFile(options['filename'])
- obj = key.keyObject
- string = key.blob()
- print '%s %s %s' % (
- obj.size() + 1,
- key.fingerprint(),
- os.path.basename(options['filename']))
- except:
- sys.exit('bad key')
-
-
-def changePassPhrase(options):
- if not options['filename']:
- filename = os.path.expanduser('~/.ssh/id_rsa')
- options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename)
- try:
- key = keys.Key.fromFile(options['filename']).keyObject
- except keys.BadKeyError, e:
- if e.args[0] != 'encrypted key with no passphrase':
- raise
- else:
- if not options['pass']:
- options['pass'] = getpass.getpass('Enter old passphrase: ')
- key = keys.Key.fromFile(
- options['filename'], passphrase = options['pass']).keyObject
- if not options['newpass']:
- while 1:
- p1 = getpass.getpass('Enter new passphrase (empty for no passphrase): ')
- p2 = getpass.getpass('Enter same passphrase again: ')
- if p1 == p2:
- break
- print 'Passphrases do not match. Try again.'
- options['newpass'] = p1
- open(options['filename'], 'w').write(
- keys.Key(key).toString(passphrase=options['newpass']))
- print 'Your identification has been saved with the new passphrase.'
-
-
-def displayPublicKey(options):
- if not options['filename']:
- filename = os.path.expanduser('~/.ssh/id_rsa')
- options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename)
- try:
- key = keys.Key.fromFile(options['filename']).keyObject
- except keys.BadKeyError, e:
- if e.args[0] != 'encrypted key with no passphrase':
- raise
- else:
- if not options['pass']:
- options['pass'] = getpass.getpass('Enter passphrase: ')
- key = keys.Key.fromFile(
- options['filename'], passphrase = options['pass']).keyObject
- print keys.Key(key).public().toString()
-
-
-def _saveKey(key, options):
- if not options['filename']:
- kind = keys.objectType(key)
- kind = {'ssh-rsa':'rsa','ssh-dss':'dsa'}[kind]
- filename = os.path.expanduser('~/.ssh/id_%s'%kind)
- options['filename'] = raw_input('Enter file in which to save the key (%s): '%filename).strip() or filename
- if os.path.exists(options['filename']):
- print '%s already exists.' % options['filename']
- yn = raw_input('Overwrite (y/n)? ')
- if yn[0].lower() != 'y':
- sys.exit()
- if not options['pass']:
- while 1:
- p1 = getpass.getpass('Enter passphrase (empty for no passphrase): ')
- p2 = getpass.getpass('Enter same passphrase again: ')
- if p1 == p2:
- break
- print 'Passphrases do not match. Try again.'
- options['pass'] = p1
-
- keyObj = keys.Key(key)
- comment = '%s@%s' % (getpass.getuser(), socket.gethostname())
-
- filepath.FilePath(options['filename']).setContent(
- keyObj.toString('openssh', options['pass']))
- os.chmod(options['filename'], 33152)
-
- filepath.FilePath(options['filename'] + '.pub').setContent(
- keyObj.public().toString('openssh', comment))
-
- print 'Your identification has been saved in %s' % options['filename']
- print 'Your public key has been saved in %s.pub' % options['filename']
- print 'The key fingerprint is:'
- print keyObj.fingerprint()
-
-if __name__ == '__main__':
- run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py
deleted file mode 100755
index 8c495441..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py
+++ /dev/null
@@ -1,512 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_conch -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-# $Id: conch.py,v 1.65 2004/03/11 00:29:14 z3p Exp $
-
-#""" Implementation module for the `conch` command.
-#"""
-from twisted.conch.client import connect, default, options
-from twisted.conch.error import ConchError
-from twisted.conch.ssh import connection, common
-from twisted.conch.ssh import session, forwarding, channel
-from twisted.internet import reactor, stdio, task
-from twisted.python import log, usage
-
-import os, sys, getpass, struct, tty, fcntl, signal
-
-class ClientOptions(options.ConchOptions):
-
- synopsis = """Usage: conch [options] host [command]
-"""
- longdesc = ("conch is a SSHv2 client that allows logging into a remote "
- "machine and executing commands.")
-
- optParameters = [['escape', 'e', '~'],
- ['localforward', 'L', None, 'listen-port:host:port Forward local port to remote address'],
- ['remoteforward', 'R', None, 'listen-port:host:port Forward remote port to local address'],
- ]
-
- optFlags = [['null', 'n', 'Redirect input from /dev/null.'],
- ['fork', 'f', 'Fork to background after authentication.'],
- ['tty', 't', 'Tty; allocate a tty even if command is given.'],
- ['notty', 'T', 'Do not allocate a tty.'],
- ['noshell', 'N', 'Do not execute a shell or command.'],
- ['subsystem', 's', 'Invoke command (mandatory) as SSH2 subsystem.'],
- ]
-
- compData = usage.Completions(
- mutuallyExclusive=[("tty", "notty")],
- optActions={
- "localforward": usage.Completer(descr="listen-port:host:port"),
- "remoteforward": usage.Completer(descr="listen-port:host:port")},
- extraActions=[usage.CompleteUserAtHost(),
- usage.Completer(descr="command"),
- usage.Completer(descr="argument", repeat=True)]
- )
-
- localForwards = []
- remoteForwards = []
-
- def opt_escape(self, esc):
- "Set escape character; ``none'' = disable"
- if esc == 'none':
- self['escape'] = None
- elif esc[0] == '^' and len(esc) == 2:
- self['escape'] = chr(ord(esc[1])-64)
- elif len(esc) == 1:
- self['escape'] = esc
- else:
- sys.exit("Bad escape character '%s'." % esc)
-
- def opt_localforward(self, f):
- "Forward local port to remote address (lport:host:port)"
- localPort, remoteHost, remotePort = f.split(':') # doesn't do v6 yet
- localPort = int(localPort)
- remotePort = int(remotePort)
- self.localForwards.append((localPort, (remoteHost, remotePort)))
-
- def opt_remoteforward(self, f):
- """Forward remote port to local address (rport:host:port)"""
- remotePort, connHost, connPort = f.split(':') # doesn't do v6 yet
- remotePort = int(remotePort)
- connPort = int(connPort)
- self.remoteForwards.append((remotePort, (connHost, connPort)))
-
- def parseArgs(self, host, *command):
- self['host'] = host
- self['command'] = ' '.join(command)
-
-# Rest of code in "run"
-options = None
-conn = None
-exitStatus = 0
-old = None
-_inRawMode = 0
-_savedRawMode = None
-
-def run():
- global options, old
- args = sys.argv[1:]
- if '-l' in args: # cvs is an idiot
- i = args.index('-l')
- args = args[i:i+2]+args
- del args[i+2:i+4]
- for arg in args[:]:
- try:
- i = args.index(arg)
- if arg[:2] == '-o' and args[i+1][0]!='-':
- args[i:i+2] = [] # suck on it scp
- except ValueError:
- pass
- options = ClientOptions()
- try:
- options.parseOptions(args)
- except usage.UsageError, u:
- print 'ERROR: %s' % u
- options.opt_help()
- sys.exit(1)
- if options['log']:
- if options['logfile']:
- if options['logfile'] == '-':
- f = sys.stdout
- else:
- f = file(options['logfile'], 'a+')
- else:
- f = sys.stderr
- realout = sys.stdout
- log.startLogging(f)
- sys.stdout = realout
- else:
- log.discardLogs()
- doConnect()
- fd = sys.stdin.fileno()
- try:
- old = tty.tcgetattr(fd)
- except:
- old = None
- try:
- oldUSR1 = signal.signal(signal.SIGUSR1, lambda *a: reactor.callLater(0, reConnect))
- except:
- oldUSR1 = None
- try:
- reactor.run()
- finally:
- if old:
- tty.tcsetattr(fd, tty.TCSANOW, old)
- if oldUSR1:
- signal.signal(signal.SIGUSR1, oldUSR1)
- if (options['command'] and options['tty']) or not options['notty']:
- signal.signal(signal.SIGWINCH, signal.SIG_DFL)
- if sys.stdout.isatty() and not options['command']:
- print 'Connection to %s closed.' % options['host']
- sys.exit(exitStatus)
-
-def handleError():
- from twisted.python import failure
- global exitStatus
- exitStatus = 2
- reactor.callLater(0.01, _stopReactor)
- log.err(failure.Failure())
- raise
-
-def _stopReactor():
- try:
- reactor.stop()
- except: pass
-
-def doConnect():
-# log.deferr = handleError # HACK
- if '@' in options['host']:
- options['user'], options['host'] = options['host'].split('@',1)
- if not options.identitys:
- options.identitys = ['~/.ssh/id_rsa', '~/.ssh/id_dsa']
- host = options['host']
- if not options['user']:
- options['user'] = getpass.getuser()
- if not options['port']:
- options['port'] = 22
- else:
- options['port'] = int(options['port'])
- host = options['host']
- port = options['port']
- vhk = default.verifyHostKey
- uao = default.SSHUserAuthClient(options['user'], options, SSHConnection())
- connect.connect(host, port, options, vhk, uao).addErrback(_ebExit)
-
-def _ebExit(f):
- global exitStatus
- if hasattr(f.value, 'value'):
- s = f.value.value
- else:
- s = str(f)
- exitStatus = "conch: exiting with error %s" % f
- reactor.callLater(0.1, _stopReactor)
-
-def onConnect():
-# if keyAgent and options['agent']:
-# cc = protocol.ClientCreator(reactor, SSHAgentForwardingLocal, conn)
-# cc.connectUNIX(os.environ['SSH_AUTH_SOCK'])
- if hasattr(conn.transport, 'sendIgnore'):
- _KeepAlive(conn)
- if options.localForwards:
- for localPort, hostport in options.localForwards:
- s = reactor.listenTCP(localPort,
- forwarding.SSHListenForwardingFactory(conn,
- hostport,
- SSHListenClientForwardingChannel))
- conn.localForwards.append(s)
- if options.remoteForwards:
- for remotePort, hostport in options.remoteForwards:
- log.msg('asking for remote forwarding for %s:%s' %
- (remotePort, hostport))
- conn.requestRemoteForwarding(remotePort, hostport)
- reactor.addSystemEventTrigger('before', 'shutdown', beforeShutdown)
- if not options['noshell'] or options['agent']:
- conn.openChannel(SSHSession())
- if options['fork']:
- if os.fork():
- os._exit(0)
- os.setsid()
- for i in range(3):
- try:
- os.close(i)
- except OSError, e:
- import errno
- if e.errno != errno.EBADF:
- raise
-
-def reConnect():
- beforeShutdown()
- conn.transport.transport.loseConnection()
-
-def beforeShutdown():
- remoteForwards = options.remoteForwards
- for remotePort, hostport in remoteForwards:
- log.msg('cancelling %s:%s' % (remotePort, hostport))
- conn.cancelRemoteForwarding(remotePort)
-
-def stopConnection():
- if not options['reconnect']:
- reactor.callLater(0.1, _stopReactor)
-
-class _KeepAlive:
-
- def __init__(self, conn):
- self.conn = conn
- self.globalTimeout = None
- self.lc = task.LoopingCall(self.sendGlobal)
- self.lc.start(300)
-
- def sendGlobal(self):
- d = self.conn.sendGlobalRequest("conch-keep-alive@twistedmatrix.com",
- "", wantReply = 1)
- d.addBoth(self._cbGlobal)
- self.globalTimeout = reactor.callLater(30, self._ebGlobal)
-
- def _cbGlobal(self, res):
- if self.globalTimeout:
- self.globalTimeout.cancel()
- self.globalTimeout = None
-
- def _ebGlobal(self):
- if self.globalTimeout:
- self.globalTimeout = None
- self.conn.transport.loseConnection()
-
-class SSHConnection(connection.SSHConnection):
- def serviceStarted(self):
- global conn
- conn = self
- self.localForwards = []
- self.remoteForwards = {}
- if not isinstance(self, connection.SSHConnection):
- # make these fall through
- del self.__class__.requestRemoteForwarding
- del self.__class__.cancelRemoteForwarding
- onConnect()
-
- def serviceStopped(self):
- lf = self.localForwards
- self.localForwards = []
- for s in lf:
- s.loseConnection()
- stopConnection()
-
- def requestRemoteForwarding(self, remotePort, hostport):
- data = forwarding.packGlobal_tcpip_forward(('0.0.0.0', remotePort))
- d = self.sendGlobalRequest('tcpip-forward', data,
- wantReply=1)
- log.msg('requesting remote forwarding %s:%s' %(remotePort, hostport))
- d.addCallback(self._cbRemoteForwarding, remotePort, hostport)
- d.addErrback(self._ebRemoteForwarding, remotePort, hostport)
-
- def _cbRemoteForwarding(self, result, remotePort, hostport):
- log.msg('accepted remote forwarding %s:%s' % (remotePort, hostport))
- self.remoteForwards[remotePort] = hostport
- log.msg(repr(self.remoteForwards))
-
- def _ebRemoteForwarding(self, f, remotePort, hostport):
- log.msg('remote forwarding %s:%s failed' % (remotePort, hostport))
- log.msg(f)
-
- def cancelRemoteForwarding(self, remotePort):
- data = forwarding.packGlobal_tcpip_forward(('0.0.0.0', remotePort))
- self.sendGlobalRequest('cancel-tcpip-forward', data)
- log.msg('cancelling remote forwarding %s' % remotePort)
- try:
- del self.remoteForwards[remotePort]
- except:
- pass
- log.msg(repr(self.remoteForwards))
-
- def channel_forwarded_tcpip(self, windowSize, maxPacket, data):
- log.msg('%s %s' % ('FTCP', repr(data)))
- remoteHP, origHP = forwarding.unpackOpen_forwarded_tcpip(data)
- log.msg(self.remoteForwards)
- log.msg(remoteHP)
- if self.remoteForwards.has_key(remoteHP[1]):
- connectHP = self.remoteForwards[remoteHP[1]]
- log.msg('connect forwarding %s' % (connectHP,))
- return SSHConnectForwardingChannel(connectHP,
- remoteWindow = windowSize,
- remoteMaxPacket = maxPacket,
- conn = self)
- else:
- raise ConchError(connection.OPEN_CONNECT_FAILED, "don't know about that port")
-
-# def channel_auth_agent_openssh_com(self, windowSize, maxPacket, data):
-# if options['agent'] and keyAgent:
-# return agent.SSHAgentForwardingChannel(remoteWindow = windowSize,
-# remoteMaxPacket = maxPacket,
-# conn = self)
-# else:
-# return connection.OPEN_CONNECT_FAILED, "don't have an agent"
-
- def channelClosed(self, channel):
- log.msg('connection closing %s' % channel)
- log.msg(self.channels)
- if len(self.channels) == 1: # just us left
- log.msg('stopping connection')
- stopConnection()
- else:
- # because of the unix thing
- self.__class__.__bases__[0].channelClosed(self, channel)
-
-class SSHSession(channel.SSHChannel):
-
- name = 'session'
-
- def channelOpen(self, foo):
- log.msg('session %s open' % self.id)
- if options['agent']:
- d = self.conn.sendRequest(self, 'auth-agent-req@openssh.com', '', wantReply=1)
- d.addBoth(lambda x:log.msg(x))
- if options['noshell']: return
- if (options['command'] and options['tty']) or not options['notty']:
- _enterRawMode()
- c = session.SSHSessionClient()
- if options['escape'] and not options['notty']:
- self.escapeMode = 1
- c.dataReceived = self.handleInput
- else:
- c.dataReceived = self.write
- c.connectionLost = lambda x=None,s=self:s.sendEOF()
- self.stdio = stdio.StandardIO(c)
- fd = 0
- if options['subsystem']:
- self.conn.sendRequest(self, 'subsystem', \
- common.NS(options['command']))
- elif options['command']:
- if options['tty']:
- term = os.environ['TERM']
- winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678')
- winSize = struct.unpack('4H', winsz)
- ptyReqData = session.packRequest_pty_req(term, winSize, '')
- self.conn.sendRequest(self, 'pty-req', ptyReqData)
- signal.signal(signal.SIGWINCH, self._windowResized)
- self.conn.sendRequest(self, 'exec', \
- common.NS(options['command']))
- else:
- if not options['notty']:
- term = os.environ['TERM']
- winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678')
- winSize = struct.unpack('4H', winsz)
- ptyReqData = session.packRequest_pty_req(term, winSize, '')
- self.conn.sendRequest(self, 'pty-req', ptyReqData)
- signal.signal(signal.SIGWINCH, self._windowResized)
- self.conn.sendRequest(self, 'shell', '')
- #if hasattr(conn.transport, 'transport'):
- # conn.transport.transport.setTcpNoDelay(1)
-
- def handleInput(self, char):
- #log.msg('handling %s' % repr(char))
- if char in ('\n', '\r'):
- self.escapeMode = 1
- self.write(char)
- elif self.escapeMode == 1 and char == options['escape']:
- self.escapeMode = 2
- elif self.escapeMode == 2:
- self.escapeMode = 1 # so we can chain escapes together
- if char == '.': # disconnect
- log.msg('disconnecting from escape')
- stopConnection()
- return
- elif char == '\x1a': # ^Z, suspend
- def _():
- _leaveRawMode()
- sys.stdout.flush()
- sys.stdin.flush()
- os.kill(os.getpid(), signal.SIGTSTP)
- _enterRawMode()
- reactor.callLater(0, _)
- return
- elif char == 'R': # rekey connection
- log.msg('rekeying connection')
- self.conn.transport.sendKexInit()
- return
- elif char == '#': # display connections
- self.stdio.write('\r\nThe following connections are open:\r\n')
- channels = self.conn.channels.keys()
- channels.sort()
- for channelId in channels:
- self.stdio.write(' #%i %s\r\n' % (channelId, str(self.conn.channels[channelId])))
- return
- self.write('~' + char)
- else:
- self.escapeMode = 0
- self.write(char)
-
- def dataReceived(self, data):
- self.stdio.write(data)
-
- def extReceived(self, t, data):
- if t==connection.EXTENDED_DATA_STDERR:
- log.msg('got %s stderr data' % len(data))
- sys.stderr.write(data)
-
- def eofReceived(self):
- log.msg('got eof')
- self.stdio.loseWriteConnection()
-
- def closeReceived(self):
- log.msg('remote side closed %s' % self)
- self.conn.sendClose(self)
-
- def closed(self):
- global old
- log.msg('closed %s' % self)
- log.msg(repr(self.conn.channels))
-
- def request_exit_status(self, data):
- global exitStatus
- exitStatus = int(struct.unpack('>L', data)[0])
- log.msg('exit status: %s' % exitStatus)
-
- def sendEOF(self):
- self.conn.sendEOF(self)
-
- def stopWriting(self):
- self.stdio.pauseProducing()
-
- def startWriting(self):
- self.stdio.resumeProducing()
-
- def _windowResized(self, *args):
- winsz = fcntl.ioctl(0, tty.TIOCGWINSZ, '12345678')
- winSize = struct.unpack('4H', winsz)
- newSize = winSize[1], winSize[0], winSize[2], winSize[3]
- self.conn.sendRequest(self, 'window-change', struct.pack('!4L', *newSize))
-
-
-class SSHListenClientForwardingChannel(forwarding.SSHListenClientForwardingChannel): pass
-class SSHConnectForwardingChannel(forwarding.SSHConnectForwardingChannel): pass
-
-def _leaveRawMode():
- global _inRawMode
- if not _inRawMode:
- return
- fd = sys.stdin.fileno()
- tty.tcsetattr(fd, tty.TCSANOW, _savedMode)
- _inRawMode = 0
-
-def _enterRawMode():
- global _inRawMode, _savedMode
- if _inRawMode:
- return
- fd = sys.stdin.fileno()
- try:
- old = tty.tcgetattr(fd)
- new = old[:]
- except:
- log.msg('not a typewriter!')
- else:
- # iflage
- new[0] = new[0] | tty.IGNPAR
- new[0] = new[0] & ~(tty.ISTRIP | tty.INLCR | tty.IGNCR | tty.ICRNL |
- tty.IXON | tty.IXANY | tty.IXOFF)
- if hasattr(tty, 'IUCLC'):
- new[0] = new[0] & ~tty.IUCLC
-
- # lflag
- new[3] = new[3] & ~(tty.ISIG | tty.ICANON | tty.ECHO | tty.ECHO |
- tty.ECHOE | tty.ECHOK | tty.ECHONL)
- if hasattr(tty, 'IEXTEN'):
- new[3] = new[3] & ~tty.IEXTEN
-
- #oflag
- new[1] = new[1] & ~tty.OPOST
-
- new[6][tty.VMIN] = 1
- new[6][tty.VTIME] = 0
-
- _savedMode = old
- tty.tcsetattr(fd, tty.TCSANOW, new)
- #tty.setraw(fd)
- _inRawMode = 1
-
-if __name__ == '__main__':
- run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py
deleted file mode 100755
index eb001869..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py
+++ /dev/null
@@ -1,572 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_scripts -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation module for the `tkconch` command.
-"""
-
-import Tkinter, tkFileDialog, tkFont, tkMessageBox, string
-from twisted.conch.ui import tkvt100
-from twisted.conch.ssh import transport, userauth, connection, common, keys
-from twisted.conch.ssh import session, forwarding, channel
-from twisted.conch.client.default import isInKnownHosts
-from twisted.internet import reactor, defer, protocol, tksupport
-from twisted.python import usage, log
-
-import os, sys, getpass, struct, base64, signal
-
-class TkConchMenu(Tkinter.Frame):
- def __init__(self, *args, **params):
- ## Standard heading: initialization
- apply(Tkinter.Frame.__init__, (self,) + args, params)
-
- self.master.title('TkConch')
- self.localRemoteVar = Tkinter.StringVar()
- self.localRemoteVar.set('local')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Hostname').grid(column=1, row=1, sticky='w')
- self.host = Tkinter.Entry(self)
- self.host.grid(column=2, columnspan=2, row=1, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Port').grid(column=1, row=2, sticky='w')
- self.port = Tkinter.Entry(self)
- self.port.grid(column=2, columnspan=2, row=2, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Username').grid(column=1, row=3, sticky='w')
- self.user = Tkinter.Entry(self)
- self.user.grid(column=2, columnspan=2, row=3, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Command').grid(column=1, row=4, sticky='w')
- self.command = Tkinter.Entry(self)
- self.command.grid(column=2, columnspan=2, row=4, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Identity').grid(column=1, row=5, sticky='w')
- self.identity = Tkinter.Entry(self)
- self.identity.grid(column=2, row=5, sticky='nesw')
- Tkinter.Button(self, command=self.getIdentityFile, text='Browse').grid(column=3, row=5, sticky='nesw')
-
- Tkinter.Label(self, text='Port Forwarding').grid(column=1, row=6, sticky='w')
- self.forwards = Tkinter.Listbox(self, height=0, width=0)
- self.forwards.grid(column=2, columnspan=2, row=6, sticky='nesw')
- Tkinter.Button(self, text='Add', command=self.addForward).grid(column=1, row=7)
- Tkinter.Button(self, text='Remove', command=self.removeForward).grid(column=1, row=8)
- self.forwardPort = Tkinter.Entry(self)
- self.forwardPort.grid(column=2, row=7, sticky='nesw')
- Tkinter.Label(self, text='Port').grid(column=3, row=7, sticky='nesw')
- self.forwardHost = Tkinter.Entry(self)
- self.forwardHost.grid(column=2, row=8, sticky='nesw')
- Tkinter.Label(self, text='Host').grid(column=3, row=8, sticky='nesw')
- self.localForward = Tkinter.Radiobutton(self, text='Local', variable=self.localRemoteVar, value='local')
- self.localForward.grid(column=2, row=9)
- self.remoteForward = Tkinter.Radiobutton(self, text='Remote', variable=self.localRemoteVar, value='remote')
- self.remoteForward.grid(column=3, row=9)
-
- Tkinter.Label(self, text='Advanced Options').grid(column=1, columnspan=3, row=10, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Cipher').grid(column=1, row=11, sticky='w')
- self.cipher = Tkinter.Entry(self, name='cipher')
- self.cipher.grid(column=2, columnspan=2, row=11, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='MAC').grid(column=1, row=12, sticky='w')
- self.mac = Tkinter.Entry(self, name='mac')
- self.mac.grid(column=2, columnspan=2, row=12, sticky='nesw')
-
- Tkinter.Label(self, anchor='w', justify='left', text='Escape Char').grid(column=1, row=13, sticky='w')
- self.escape = Tkinter.Entry(self, name='escape')
- self.escape.grid(column=2, columnspan=2, row=13, sticky='nesw')
- Tkinter.Button(self, text='Connect!', command=self.doConnect).grid(column=1, columnspan=3, row=14, sticky='nesw')
-
- # Resize behavior(s)
- self.grid_rowconfigure(6, weight=1, minsize=64)
- self.grid_columnconfigure(2, weight=1, minsize=2)
-
- self.master.protocol("WM_DELETE_WINDOW", sys.exit)
-
-
- def getIdentityFile(self):
- r = tkFileDialog.askopenfilename()
- if r:
- self.identity.delete(0, Tkinter.END)
- self.identity.insert(Tkinter.END, r)
-
- def addForward(self):
- port = self.forwardPort.get()
- self.forwardPort.delete(0, Tkinter.END)
- host = self.forwardHost.get()
- self.forwardHost.delete(0, Tkinter.END)
- if self.localRemoteVar.get() == 'local':
- self.forwards.insert(Tkinter.END, 'L:%s:%s' % (port, host))
- else:
- self.forwards.insert(Tkinter.END, 'R:%s:%s' % (port, host))
-
- def removeForward(self):
- cur = self.forwards.curselection()
- if cur:
- self.forwards.remove(cur[0])
-
- def doConnect(self):
- finished = 1
- options['host'] = self.host.get()
- options['port'] = self.port.get()
- options['user'] = self.user.get()
- options['command'] = self.command.get()
- cipher = self.cipher.get()
- mac = self.mac.get()
- escape = self.escape.get()
- if cipher:
- if cipher in SSHClientTransport.supportedCiphers:
- SSHClientTransport.supportedCiphers = [cipher]
- else:
- tkMessageBox.showerror('TkConch', 'Bad cipher.')
- finished = 0
-
- if mac:
- if mac in SSHClientTransport.supportedMACs:
- SSHClientTransport.supportedMACs = [mac]
- elif finished:
- tkMessageBox.showerror('TkConch', 'Bad MAC.')
- finished = 0
-
- if escape:
- if escape == 'none':
- options['escape'] = None
- elif escape[0] == '^' and len(escape) == 2:
- options['escape'] = chr(ord(escape[1])-64)
- elif len(escape) == 1:
- options['escape'] = escape
- elif finished:
- tkMessageBox.showerror('TkConch', "Bad escape character '%s'." % escape)
- finished = 0
-
- if self.identity.get():
- options.identitys.append(self.identity.get())
-
- for line in self.forwards.get(0,Tkinter.END):
- if line[0]=='L':
- options.opt_localforward(line[2:])
- else:
- options.opt_remoteforward(line[2:])
-
- if '@' in options['host']:
- options['user'], options['host'] = options['host'].split('@',1)
-
- if (not options['host'] or not options['user']) and finished:
- tkMessageBox.showerror('TkConch', 'Missing host or username.')
- finished = 0
- if finished:
- self.master.quit()
- self.master.destroy()
- if options['log']:
- realout = sys.stdout
- log.startLogging(sys.stderr)
- sys.stdout = realout
- else:
- log.discardLogs()
- log.deferr = handleError # HACK
- if not options.identitys:
- options.identitys = ['~/.ssh/id_rsa', '~/.ssh/id_dsa']
- host = options['host']
- port = int(options['port'] or 22)
- log.msg((host,port))
- reactor.connectTCP(host, port, SSHClientFactory())
- frame.master.deiconify()
- frame.master.title('%s@%s - TkConch' % (options['user'], options['host']))
- else:
- self.focus()
-
-class GeneralOptions(usage.Options):
- synopsis = """Usage: tkconch [options] host [command]
- """
-
- optParameters = [['user', 'l', None, 'Log in using this user name.'],
- ['identity', 'i', '~/.ssh/identity', 'Identity for public key authentication'],
- ['escape', 'e', '~', "Set escape character; ``none'' = disable"],
- ['cipher', 'c', None, 'Select encryption algorithm.'],
- ['macs', 'm', None, 'Specify MAC algorithms for protocol version 2.'],
- ['port', 'p', None, 'Connect to this port. Server must be on the same port.'],
- ['localforward', 'L', None, 'listen-port:host:port Forward local port to remote address'],
- ['remoteforward', 'R', None, 'listen-port:host:port Forward remote port to local address'],
- ]
-
- optFlags = [['tty', 't', 'Tty; allocate a tty even if command is given.'],
- ['notty', 'T', 'Do not allocate a tty.'],
- ['version', 'V', 'Display version number only.'],
- ['compress', 'C', 'Enable compression.'],
- ['noshell', 'N', 'Do not execute a shell or command.'],
- ['subsystem', 's', 'Invoke command (mandatory) as SSH2 subsystem.'],
- ['log', 'v', 'Log to stderr'],
- ['ansilog', 'a', 'Print the receieved data to stdout']]
-
- _ciphers = transport.SSHClientTransport.supportedCiphers
- _macs = transport.SSHClientTransport.supportedMACs
-
- compData = usage.Completions(
- mutuallyExclusive=[("tty", "notty")],
- optActions={
- "cipher": usage.CompleteList(_ciphers),
- "macs": usage.CompleteList(_macs),
- "localforward": usage.Completer(descr="listen-port:host:port"),
- "remoteforward": usage.Completer(descr="listen-port:host:port")},
- extraActions=[usage.CompleteUserAtHost(),
- usage.Completer(descr="command"),
- usage.Completer(descr="argument", repeat=True)]
- )
-
- identitys = []
- localForwards = []
- remoteForwards = []
-
- def opt_identity(self, i):
- self.identitys.append(i)
-
- def opt_localforward(self, f):
- localPort, remoteHost, remotePort = f.split(':') # doesn't do v6 yet
- localPort = int(localPort)
- remotePort = int(remotePort)
- self.localForwards.append((localPort, (remoteHost, remotePort)))
-
- def opt_remoteforward(self, f):
- remotePort, connHost, connPort = f.split(':') # doesn't do v6 yet
- remotePort = int(remotePort)
- connPort = int(connPort)
- self.remoteForwards.append((remotePort, (connHost, connPort)))
-
- def opt_compress(self):
- SSHClientTransport.supportedCompressions[0:1] = ['zlib']
-
- def parseArgs(self, *args):
- if args:
- self['host'] = args[0]
- self['command'] = ' '.join(args[1:])
- else:
- self['host'] = ''
- self['command'] = ''
-
-# Rest of code in "run"
-options = None
-menu = None
-exitStatus = 0
-frame = None
-
-def deferredAskFrame(question, echo):
- if frame.callback:
- raise ValueError("can't ask 2 questions at once!")
- d = defer.Deferred()
- resp = []
- def gotChar(ch, resp=resp):
- if not ch: return
- if ch=='\x03': # C-c
- reactor.stop()
- if ch=='\r':
- frame.write('\r\n')
- stresp = ''.join(resp)
- del resp
- frame.callback = None
- d.callback(stresp)
- return
- elif 32 <= ord(ch) < 127:
- resp.append(ch)
- if echo:
- frame.write(ch)
- elif ord(ch) == 8 and resp: # BS
- if echo: frame.write('\x08 \x08')
- resp.pop()
- frame.callback = gotChar
- frame.write(question)
- frame.canvas.focus_force()
- return d
-
-def run():
- global menu, options, frame
- args = sys.argv[1:]
- if '-l' in args: # cvs is an idiot
- i = args.index('-l')
- args = args[i:i+2]+args
- del args[i+2:i+4]
- for arg in args[:]:
- try:
- i = args.index(arg)
- if arg[:2] == '-o' and args[i+1][0]!='-':
- args[i:i+2] = [] # suck on it scp
- except ValueError:
- pass
- root = Tkinter.Tk()
- root.withdraw()
- top = Tkinter.Toplevel()
- menu = TkConchMenu(top)
- menu.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
- options = GeneralOptions()
- try:
- options.parseOptions(args)
- except usage.UsageError, u:
- print 'ERROR: %s' % u
- options.opt_help()
- sys.exit(1)
- for k,v in options.items():
- if v and hasattr(menu, k):
- getattr(menu,k).insert(Tkinter.END, v)
- for (p, (rh, rp)) in options.localForwards:
- menu.forwards.insert(Tkinter.END, 'L:%s:%s:%s' % (p, rh, rp))
- options.localForwards = []
- for (p, (rh, rp)) in options.remoteForwards:
- menu.forwards.insert(Tkinter.END, 'R:%s:%s:%s' % (p, rh, rp))
- options.remoteForwards = []
- frame = tkvt100.VT100Frame(root, callback=None)
- root.geometry('%dx%d'%(tkvt100.fontWidth*frame.width+3, tkvt100.fontHeight*frame.height+3))
- frame.pack(side = Tkinter.TOP)
- tksupport.install(root)
- root.withdraw()
- if (options['host'] and options['user']) or '@' in options['host']:
- menu.doConnect()
- else:
- top.mainloop()
- reactor.run()
- sys.exit(exitStatus)
-
-def handleError():
- from twisted.python import failure
- global exitStatus
- exitStatus = 2
- log.err(failure.Failure())
- reactor.stop()
- raise
-
-class SSHClientFactory(protocol.ClientFactory):
- noisy = 1
-
- def stopFactory(self):
- reactor.stop()
-
- def buildProtocol(self, addr):
- return SSHClientTransport()
-
- def clientConnectionFailed(self, connector, reason):
- tkMessageBox.showwarning('TkConch','Connection Failed, Reason:\n %s: %s' % (reason.type, reason.value))
-
-class SSHClientTransport(transport.SSHClientTransport):
-
- def receiveError(self, code, desc):
- global exitStatus
- exitStatus = 'conch:\tRemote side disconnected with error code %i\nconch:\treason: %s' % (code, desc)
-
- def sendDisconnect(self, code, reason):
- global exitStatus
- exitStatus = 'conch:\tSending disconnect with error code %i\nconch:\treason: %s' % (code, reason)
- transport.SSHClientTransport.sendDisconnect(self, code, reason)
-
- def receiveDebug(self, alwaysDisplay, message, lang):
- global options
- if alwaysDisplay or options['log']:
- log.msg('Received Debug Message: %s' % message)
-
- def verifyHostKey(self, pubKey, fingerprint):
- #d = defer.Deferred()
- #d.addCallback(lambda x:defer.succeed(1))
- #d.callback(2)
- #return d
- goodKey = isInKnownHosts(options['host'], pubKey, {'known-hosts': None})
- if goodKey == 1: # good key
- return defer.succeed(1)
- elif goodKey == 2: # AAHHHHH changed
- return defer.fail(error.ConchError('bad host key'))
- else:
- if options['host'] == self.transport.getPeer()[1]:
- host = options['host']
- khHost = options['host']
- else:
- host = '%s (%s)' % (options['host'],
- self.transport.getPeer()[1])
- khHost = '%s,%s' % (options['host'],
- self.transport.getPeer()[1])
- keyType = common.getNS(pubKey)[0]
- ques = """The authenticity of host '%s' can't be established.\r
-%s key fingerprint is %s.""" % (host,
- {'ssh-dss':'DSA', 'ssh-rsa':'RSA'}[keyType],
- fingerprint)
- ques+='\r\nAre you sure you want to continue connecting (yes/no)? '
- return deferredAskFrame(ques, 1).addCallback(self._cbVerifyHostKey, pubKey, khHost, keyType)
-
- def _cbVerifyHostKey(self, ans, pubKey, khHost, keyType):
- if ans.lower() not in ('yes', 'no'):
- return deferredAskFrame("Please type 'yes' or 'no': ",1).addCallback(self._cbVerifyHostKey, pubKey, khHost, keyType)
- if ans.lower() == 'no':
- frame.write('Host key verification failed.\r\n')
- raise error.ConchError('bad host key')
- try:
- frame.write("Warning: Permanently added '%s' (%s) to the list of known hosts.\r\n" % (khHost, {'ssh-dss':'DSA', 'ssh-rsa':'RSA'}[keyType]))
- known_hosts = open(os.path.expanduser('~/.ssh/known_hosts'), 'a')
- encodedKey = base64.encodestring(pubKey).replace('\n', '')
- known_hosts.write('\n%s %s %s' % (khHost, keyType, encodedKey))
- known_hosts.close()
- except:
- log.deferr()
- raise error.ConchError
-
- def connectionSecure(self):
- if options['user']:
- user = options['user']
- else:
- user = getpass.getuser()
- self.requestService(SSHUserAuthClient(user, SSHConnection()))
-
-class SSHUserAuthClient(userauth.SSHUserAuthClient):
- usedFiles = []
-
- def getPassword(self, prompt = None):
- if not prompt:
- prompt = "%s@%s's password: " % (self.user, options['host'])
- return deferredAskFrame(prompt,0)
-
- def getPublicKey(self):
- files = [x for x in options.identitys if x not in self.usedFiles]
- if not files:
- return None
- file = files[0]
- log.msg(file)
- self.usedFiles.append(file)
- file = os.path.expanduser(file)
- file += '.pub'
- if not os.path.exists(file):
- return
- try:
- return keys.Key.fromFile(file).blob()
- except:
- return self.getPublicKey() # try again
-
- def getPrivateKey(self):
- file = os.path.expanduser(self.usedFiles[-1])
- if not os.path.exists(file):
- return None
- try:
- return defer.succeed(keys.Key.fromFile(file).keyObject)
- except keys.BadKeyError, e:
- if e.args[0] == 'encrypted key with no password':
- prompt = "Enter passphrase for key '%s': " % \
- self.usedFiles[-1]
- return deferredAskFrame(prompt, 0).addCallback(self._cbGetPrivateKey, 0)
- def _cbGetPrivateKey(self, ans, count):
- file = os.path.expanduser(self.usedFiles[-1])
- try:
- return keys.Key.fromFile(file, password = ans).keyObject
- except keys.BadKeyError:
- if count == 2:
- raise
- prompt = "Enter passphrase for key '%s': " % \
- self.usedFiles[-1]
- return deferredAskFrame(prompt, 0).addCallback(self._cbGetPrivateKey, count+1)
-
-class SSHConnection(connection.SSHConnection):
- def serviceStarted(self):
- if not options['noshell']:
- self.openChannel(SSHSession())
- if options.localForwards:
- for localPort, hostport in options.localForwards:
- reactor.listenTCP(localPort,
- forwarding.SSHListenForwardingFactory(self,
- hostport,
- forwarding.SSHListenClientForwardingChannel))
- if options.remoteForwards:
- for remotePort, hostport in options.remoteForwards:
- log.msg('asking for remote forwarding for %s:%s' %
- (remotePort, hostport))
- data = forwarding.packGlobal_tcpip_forward(
- ('0.0.0.0', remotePort))
- d = self.sendGlobalRequest('tcpip-forward', data)
- self.remoteForwards[remotePort] = hostport
-
-class SSHSession(channel.SSHChannel):
-
- name = 'session'
-
- def channelOpen(self, foo):
- #global globalSession
- #globalSession = self
- # turn off local echo
- self.escapeMode = 1
- c = session.SSHSessionClient()
- if options['escape']:
- c.dataReceived = self.handleInput
- else:
- c.dataReceived = self.write
- c.connectionLost = self.sendEOF
- frame.callback = c.dataReceived
- frame.canvas.focus_force()
- if options['subsystem']:
- self.conn.sendRequest(self, 'subsystem', \
- common.NS(options['command']))
- elif options['command']:
- if options['tty']:
- term = os.environ.get('TERM', 'xterm')
- #winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678')
- winSize = (25,80,0,0) #struct.unpack('4H', winsz)
- ptyReqData = session.packRequest_pty_req(term, winSize, '')
- self.conn.sendRequest(self, 'pty-req', ptyReqData)
- self.conn.sendRequest(self, 'exec', \
- common.NS(options['command']))
- else:
- if not options['notty']:
- term = os.environ.get('TERM', 'xterm')
- #winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678')
- winSize = (25,80,0,0) #struct.unpack('4H', winsz)
- ptyReqData = session.packRequest_pty_req(term, winSize, '')
- self.conn.sendRequest(self, 'pty-req', ptyReqData)
- self.conn.sendRequest(self, 'shell', '')
- self.conn.transport.transport.setTcpNoDelay(1)
-
- def handleInput(self, char):
- #log.msg('handling %s' % repr(char))
- if char in ('\n', '\r'):
- self.escapeMode = 1
- self.write(char)
- elif self.escapeMode == 1 and char == options['escape']:
- self.escapeMode = 2
- elif self.escapeMode == 2:
- self.escapeMode = 1 # so we can chain escapes together
- if char == '.': # disconnect
- log.msg('disconnecting from escape')
- reactor.stop()
- return
- elif char == '\x1a': # ^Z, suspend
- # following line courtesy of Erwin@freenode
- os.kill(os.getpid(), signal.SIGSTOP)
- return
- elif char == 'R': # rekey connection
- log.msg('rekeying connection')
- self.conn.transport.sendKexInit()
- return
- self.write('~' + char)
- else:
- self.escapeMode = 0
- self.write(char)
-
- def dataReceived(self, data):
- if options['ansilog']:
- print repr(data)
- frame.write(data)
-
- def extReceived(self, t, data):
- if t==connection.EXTENDED_DATA_STDERR:
- log.msg('got %s stderr data' % len(data))
- sys.stderr.write(data)
- sys.stderr.flush()
-
- def eofReceived(self):
- log.msg('got eof')
- sys.stdin.close()
-
- def closed(self):
- log.msg('closed %s' % self)
- if len(self.conn.channels) == 1: # just us left
- reactor.stop()
-
- def request_exit_status(self, data):
- global exitStatus
- exitStatus = int(struct.unpack('>L', data)[0])
- log.msg('exit status: %s' % exitStatus)
-
- def sendEOF(self):
- self.conn.sendEOF(self)
-
-if __name__=="__main__":
- run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py
deleted file mode 100755
index 4b7f024b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-An SSHv2 implementation for Twisted. Part of the Twisted.Conch package.
-
-Maintainer: Paul Swartz
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py
deleted file mode 100755
index c06f2bfa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_address -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Address object for SSH network connections.
-
-Maintainer: Paul Swartz
-
-@since: 12.1
-"""
-from zope.interface import implements
-from twisted.internet.interfaces import IAddress
-from twisted.python import util
-
-
-
-class SSHTransportAddress(object, util.FancyEqMixin):
- """
- Object representing an SSH Transport endpoint.
-
- @ivar address: A instance of an object which implements I{IAddress} to
- which this transport address is connected.
- """
-
- implements(IAddress)
-
- compareAttributes = ('address',)
-
- def __init__(self, address):
- self.address = address
-
- def __repr__(self):
- return 'SSHTransportAddress(%r)' % (self.address,)
-
- def __hash__(self):
- return hash(('SSH', self.address))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py
deleted file mode 100755
index c1bf1a09..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implements the SSH v2 key agent protocol. This protocol is documented in the
-SSH source code, in the file
-U{PROTOCOL.agent<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent>}.
-
-Maintainer: Paul Swartz
-"""
-
-import struct
-
-from twisted.conch.ssh.common import NS, getNS, getMP
-from twisted.conch.error import ConchError, MissingKeyStoreError
-from twisted.conch.ssh import keys
-from twisted.internet import defer, protocol
-
-
-
-class SSHAgentClient(protocol.Protocol):
- """
- The client side of the SSH agent protocol. This is equivalent to
- ssh-add(1) and can be used with either ssh-agent(1) or the SSHAgentServer
- protocol, also in this package.
- """
-
- def __init__(self):
- self.buf = ''
- self.deferreds = []
-
-
- def dataReceived(self, data):
- self.buf += data
- while 1:
- if len(self.buf) <= 4:
- return
- packLen = struct.unpack('!L', self.buf[:4])[0]
- if len(self.buf) < 4 + packLen:
- return
- packet, self.buf = self.buf[4:4 + packLen], self.buf[4 + packLen:]
- reqType = ord(packet[0])
- d = self.deferreds.pop(0)
- if reqType == AGENT_FAILURE:
- d.errback(ConchError('agent failure'))
- elif reqType == AGENT_SUCCESS:
- d.callback('')
- else:
- d.callback(packet)
-
-
- def sendRequest(self, reqType, data):
- pack = struct.pack('!LB',len(data) + 1, reqType) + data
- self.transport.write(pack)
- d = defer.Deferred()
- self.deferreds.append(d)
- return d
-
-
- def requestIdentities(self):
- """
- @return: A L{Deferred} which will fire with a list of all keys found in
- the SSH agent. The list of keys is comprised of (public key blob,
- comment) tuples.
- """
- d = self.sendRequest(AGENTC_REQUEST_IDENTITIES, '')
- d.addCallback(self._cbRequestIdentities)
- return d
-
-
- def _cbRequestIdentities(self, data):
- """
- Unpack a collection of identities into a list of tuples comprised of
- public key blobs and comments.
- """
- if ord(data[0]) != AGENT_IDENTITIES_ANSWER:
- raise ConchError('unexpected response: %i' % ord(data[0]))
- numKeys = struct.unpack('!L', data[1:5])[0]
- keys = []
- data = data[5:]
- for i in range(numKeys):
- blob, data = getNS(data)
- comment, data = getNS(data)
- keys.append((blob, comment))
- return keys
-
-
- def addIdentity(self, blob, comment = ''):
- """
- Add a private key blob to the agent's collection of keys.
- """
- req = blob
- req += NS(comment)
- return self.sendRequest(AGENTC_ADD_IDENTITY, req)
-
-
- def signData(self, blob, data):
- """
- Request that the agent sign the given C{data} with the private key
- which corresponds to the public key given by C{blob}. The private
- key should have been added to the agent already.
-
- @type blob: C{str}
- @type data: C{str}
- @return: A L{Deferred} which fires with a signature for given data
- created with the given key.
- """
- req = NS(blob)
- req += NS(data)
- req += '\000\000\000\000' # flags
- return self.sendRequest(AGENTC_SIGN_REQUEST, req).addCallback(self._cbSignData)
-
-
- def _cbSignData(self, data):
- if ord(data[0]) != AGENT_SIGN_RESPONSE:
- raise ConchError('unexpected data: %i' % ord(data[0]))
- signature = getNS(data[1:])[0]
- return signature
-
-
- def removeIdentity(self, blob):
- """
- Remove the private key corresponding to the public key in blob from the
- running agent.
- """
- req = NS(blob)
- return self.sendRequest(AGENTC_REMOVE_IDENTITY, req)
-
-
- def removeAllIdentities(self):
- """
- Remove all keys from the running agent.
- """
- return self.sendRequest(AGENTC_REMOVE_ALL_IDENTITIES, '')
-
-
-
-class SSHAgentServer(protocol.Protocol):
- """
- The server side of the SSH agent protocol. This is equivalent to
- ssh-agent(1) and can be used with either ssh-add(1) or the SSHAgentClient
- protocol, also in this package.
- """
-
- def __init__(self):
- self.buf = ''
-
-
- def dataReceived(self, data):
- self.buf += data
- while 1:
- if len(self.buf) <= 4:
- return
- packLen = struct.unpack('!L', self.buf[:4])[0]
- if len(self.buf) < 4 + packLen:
- return
- packet, self.buf = self.buf[4:4 + packLen], self.buf[4 + packLen:]
- reqType = ord(packet[0])
- reqName = messages.get(reqType, None)
- if not reqName:
- self.sendResponse(AGENT_FAILURE, '')
- else:
- f = getattr(self, 'agentc_%s' % reqName)
- if getattr(self.factory, 'keys', None) is None:
- self.sendResponse(AGENT_FAILURE, '')
- raise MissingKeyStoreError()
- f(packet[1:])
-
-
- def sendResponse(self, reqType, data):
- pack = struct.pack('!LB', len(data) + 1, reqType) + data
- self.transport.write(pack)
-
-
- def agentc_REQUEST_IDENTITIES(self, data):
- """
- Return all of the identities that have been added to the server
- """
- assert data == ''
- numKeys = len(self.factory.keys)
- resp = []
-
- resp.append(struct.pack('!L', numKeys))
- for key, comment in self.factory.keys.itervalues():
- resp.append(NS(key.blob())) # yes, wrapped in an NS
- resp.append(NS(comment))
- self.sendResponse(AGENT_IDENTITIES_ANSWER, ''.join(resp))
-
-
- def agentc_SIGN_REQUEST(self, data):
- """
- Data is a structure with a reference to an already added key object and
- some data that the clients wants signed with that key. If the key
- object wasn't loaded, return AGENT_FAILURE, else return the signature.
- """
- blob, data = getNS(data)
- if blob not in self.factory.keys:
- return self.sendResponse(AGENT_FAILURE, '')
- signData, data = getNS(data)
- assert data == '\000\000\000\000'
- self.sendResponse(AGENT_SIGN_RESPONSE, NS(self.factory.keys[blob][0].sign(signData)))
-
-
- def agentc_ADD_IDENTITY(self, data):
- """
- Adds a private key to the agent's collection of identities. On
- subsequent interactions, the private key can be accessed using only the
- corresponding public key.
- """
-
- # need to pre-read the key data so we can get past it to the comment string
- keyType, rest = getNS(data)
- if keyType == 'ssh-rsa':
- nmp = 6
- elif keyType == 'ssh-dss':
- nmp = 5
- else:
- raise keys.BadKeyError('unknown blob type: %s' % keyType)
-
- rest = getMP(rest, nmp)[-1] # ignore the key data for now, we just want the comment
- comment, rest = getNS(rest) # the comment, tacked onto the end of the key blob
-
- k = keys.Key.fromString(data, type='private_blob') # not wrapped in NS here
- self.factory.keys[k.blob()] = (k, comment)
- self.sendResponse(AGENT_SUCCESS, '')
-
-
- def agentc_REMOVE_IDENTITY(self, data):
- """
- Remove a specific key from the agent's collection of identities.
- """
- blob, _ = getNS(data)
- k = keys.Key.fromString(blob, type='blob')
- del self.factory.keys[k.blob()]
- self.sendResponse(AGENT_SUCCESS, '')
-
-
- def agentc_REMOVE_ALL_IDENTITIES(self, data):
- """
- Remove all keys from the agent's collection of identities.
- """
- assert data == ''
- self.factory.keys = {}
- self.sendResponse(AGENT_SUCCESS, '')
-
- # v1 messages that we ignore because we don't keep v1 keys
- # open-ssh sends both v1 and v2 commands, so we have to
- # do no-ops for v1 commands or we'll get "bad request" errors
-
- def agentc_REQUEST_RSA_IDENTITIES(self, data):
- """
- v1 message for listing RSA1 keys; superseded by
- agentc_REQUEST_IDENTITIES, which handles different key types.
- """
- self.sendResponse(AGENT_RSA_IDENTITIES_ANSWER, struct.pack('!L', 0))
-
-
- def agentc_REMOVE_RSA_IDENTITY(self, data):
- """
- v1 message for removing RSA1 keys; superseded by
- agentc_REMOVE_IDENTITY, which handles different key types.
- """
- self.sendResponse(AGENT_SUCCESS, '')
-
-
- def agentc_REMOVE_ALL_RSA_IDENTITIES(self, data):
- """
- v1 message for removing all RSA1 keys; superseded by
- agentc_REMOVE_ALL_IDENTITIES, which handles different key types.
- """
- self.sendResponse(AGENT_SUCCESS, '')
-
-
-AGENTC_REQUEST_RSA_IDENTITIES = 1
-AGENT_RSA_IDENTITIES_ANSWER = 2
-AGENT_FAILURE = 5
-AGENT_SUCCESS = 6
-
-AGENTC_REMOVE_RSA_IDENTITY = 8
-AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9
-
-AGENTC_REQUEST_IDENTITIES = 11
-AGENT_IDENTITIES_ANSWER = 12
-AGENTC_SIGN_REQUEST = 13
-AGENT_SIGN_RESPONSE = 14
-AGENTC_ADD_IDENTITY = 17
-AGENTC_REMOVE_IDENTITY = 18
-AGENTC_REMOVE_ALL_IDENTITIES = 19
-
-messages = {}
-for name, value in locals().copy().items():
- if name[:7] == 'AGENTC_':
- messages[value] = name[7:] # doesn't handle doubles
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py
deleted file mode 100755
index f498aec0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_channel -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""
-The parent class for all the SSH Channels. Currently implemented channels
-are session. direct-tcp, and forwarded-tcp.
-
-Maintainer: Paul Swartz
-"""
-
-from twisted.python import log
-from twisted.internet import interfaces
-from zope.interface import implements
-
-
-class SSHChannel(log.Logger):
- """
- A class that represents a multiplexed channel over an SSH connection.
- The channel has a local window which is the maximum amount of data it will
- receive, and a remote which is the maximum amount of data the remote side
- will accept. There is also a maximum packet size for any individual data
- packet going each way.
-
- @ivar name: the name of the channel.
- @type name: C{str}
- @ivar localWindowSize: the maximum size of the local window in bytes.
- @type localWindowSize: C{int}
- @ivar localWindowLeft: how many bytes are left in the local window.
- @type localWindowLeft: C{int}
- @ivar localMaxPacket: the maximum size of packet we will accept in bytes.
- @type localMaxPacket: C{int}
- @ivar remoteWindowLeft: how many bytes are left in the remote window.
- @type remoteWindowLeft: C{int}
- @ivar remoteMaxPacket: the maximum size of a packet the remote side will
- accept in bytes.
- @type remoteMaxPacket: C{int}
- @ivar conn: the connection this channel is multiplexed through.
- @type conn: L{SSHConnection}
- @ivar data: any data to send to the other size when the channel is
- requested.
- @type data: C{str}
- @ivar avatar: an avatar for the logged-in user (if a server channel)
- @ivar localClosed: True if we aren't accepting more data.
- @type localClosed: C{bool}
- @ivar remoteClosed: True if the other size isn't accepting more data.
- @type remoteClosed: C{bool}
- """
-
- implements(interfaces.ITransport)
-
- name = None # only needed for client channels
-
- def __init__(self, localWindow = 0, localMaxPacket = 0,
- remoteWindow = 0, remoteMaxPacket = 0,
- conn = None, data=None, avatar = None):
- self.localWindowSize = localWindow or 131072
- self.localWindowLeft = self.localWindowSize
- self.localMaxPacket = localMaxPacket or 32768
- self.remoteWindowLeft = remoteWindow
- self.remoteMaxPacket = remoteMaxPacket
- self.areWriting = 1
- self.conn = conn
- self.data = data
- self.avatar = avatar
- self.specificData = ''
- self.buf = ''
- self.extBuf = []
- self.closing = 0
- self.localClosed = 0
- self.remoteClosed = 0
- self.id = None # gets set later by SSHConnection
-
- def __str__(self):
- return '<SSHChannel %s (lw %i rw %i)>' % (self.name,
- self.localWindowLeft, self.remoteWindowLeft)
-
- def logPrefix(self):
- id = (self.id is not None and str(self.id)) or "unknown"
- return "SSHChannel %s (%s) on %s" % (self.name, id,
- self.conn.logPrefix())
-
- def channelOpen(self, specificData):
- """
- Called when the channel is opened. specificData is any data that the
- other side sent us when opening the channel.
-
- @type specificData: C{str}
- """
- log.msg('channel open')
-
- def openFailed(self, reason):
- """
- Called when the the open failed for some reason.
- reason.desc is a string descrption, reason.code the the SSH error code.
-
- @type reason: L{error.ConchError}
- """
- log.msg('other side refused open\nreason: %s'% reason)
-
- def addWindowBytes(self, bytes):
- """
- Called when bytes are added to the remote window. By default it clears
- the data buffers.
-
- @type bytes: C{int}
- """
- self.remoteWindowLeft = self.remoteWindowLeft+bytes
- if not self.areWriting and not self.closing:
- self.areWriting = True
- self.startWriting()
- if self.buf:
- b = self.buf
- self.buf = ''
- self.write(b)
- if self.extBuf:
- b = self.extBuf
- self.extBuf = []
- for (type, data) in b:
- self.writeExtended(type, data)
-
- def requestReceived(self, requestType, data):
- """
- Called when a request is sent to this channel. By default it delegates
- to self.request_<requestType>.
- If this function returns true, the request succeeded, otherwise it
- failed.
-
- @type requestType: C{str}
- @type data: C{str}
- @rtype: C{bool}
- """
- foo = requestType.replace('-', '_')
- f = getattr(self, 'request_%s'%foo, None)
- if f:
- return f(data)
- log.msg('unhandled request for %s'%requestType)
- return 0
-
- def dataReceived(self, data):
- """
- Called when we receive data.
-
- @type data: C{str}
- """
- log.msg('got data %s'%repr(data))
-
- def extReceived(self, dataType, data):
- """
- Called when we receive extended data (usually standard error).
-
- @type dataType: C{int}
- @type data: C{str}
- """
- log.msg('got extended data %s %s'%(dataType, repr(data)))
-
- def eofReceived(self):
- """
- Called when the other side will send no more data.
- """
- log.msg('remote eof')
-
- def closeReceived(self):
- """
- Called when the other side has closed the channel.
- """
- log.msg('remote close')
- self.loseConnection()
-
- def closed(self):
- """
- Called when the channel is closed. This means that both our side and
- the remote side have closed the channel.
- """
- log.msg('closed')
-
- # transport stuff
- def write(self, data):
- """
- Write some data to the channel. If there is not enough remote window
- available, buffer until it is. Otherwise, split the data into
- packets of length remoteMaxPacket and send them.
-
- @type data: C{str}
- """
- if self.buf:
- self.buf += data
- return
- top = len(data)
- if top > self.remoteWindowLeft:
- data, self.buf = (data[:self.remoteWindowLeft],
- data[self.remoteWindowLeft:])
- self.areWriting = 0
- self.stopWriting()
- top = self.remoteWindowLeft
- rmp = self.remoteMaxPacket
- write = self.conn.sendData
- r = range(0, top, rmp)
- for offset in r:
- write(self, data[offset: offset+rmp])
- self.remoteWindowLeft -= top
- if self.closing and not self.buf:
- self.loseConnection() # try again
-
- def writeExtended(self, dataType, data):
- """
- Send extended data to this channel. If there is not enough remote
- window available, buffer until there is. Otherwise, split the data
- into packets of length remoteMaxPacket and send them.
-
- @type dataType: C{int}
- @type data: C{str}
- """
- if self.extBuf:
- if self.extBuf[-1][0] == dataType:
- self.extBuf[-1][1] += data
- else:
- self.extBuf.append([dataType, data])
- return
- if len(data) > self.remoteWindowLeft:
- data, self.extBuf = (data[:self.remoteWindowLeft],
- [[dataType, data[self.remoteWindowLeft:]]])
- self.areWriting = 0
- self.stopWriting()
- while len(data) > self.remoteMaxPacket:
- self.conn.sendExtendedData(self, dataType,
- data[:self.remoteMaxPacket])
- data = data[self.remoteMaxPacket:]
- self.remoteWindowLeft -= self.remoteMaxPacket
- if data:
- self.conn.sendExtendedData(self, dataType, data)
- self.remoteWindowLeft -= len(data)
- if self.closing:
- self.loseConnection() # try again
-
- def writeSequence(self, data):
- """
- Part of the Transport interface. Write a list of strings to the
- channel.
-
- @type data: C{list} of C{str}
- """
- self.write(''.join(data))
-
- def loseConnection(self):
- """
- Close the channel if there is no buferred data. Otherwise, note the
- request and return.
- """
- self.closing = 1
- if not self.buf and not self.extBuf:
- self.conn.sendClose(self)
-
- def getPeer(self):
- """
- Return a tuple describing the other side of the connection.
-
- @rtype: C{tuple}
- """
- return('SSH', )+self.conn.transport.getPeer()
-
- def getHost(self):
- """
- Return a tuple describing our side of the connection.
-
- @rtype: C{tuple}
- """
- return('SSH', )+self.conn.transport.getHost()
-
- def stopWriting(self):
- """
- Called when the remote buffer is full, as a hint to stop writing.
- This can be ignored, but it can be helpful.
- """
-
- def startWriting(self):
- """
- Called when the remote buffer has more room, as a hint to continue
- writing.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py
deleted file mode 100755
index 3afa3413..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_ssh -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Common functions for the SSH classes.
-
-Maintainer: Paul Swartz
-"""
-
-import struct, warnings, __builtin__
-
-try:
- from Crypto import Util
-except ImportError:
- warnings.warn("PyCrypto not installed, but continuing anyways!",
- RuntimeWarning)
-
-from twisted.python import randbytes
-
-
-def NS(t):
- """
- net string
- """
- return struct.pack('!L',len(t)) + t
-
-def getNS(s, count=1):
- """
- get net string
- """
- ns = []
- c = 0
- for i in range(count):
- l, = struct.unpack('!L',s[c:c+4])
- ns.append(s[c+4:4+l+c])
- c += 4 + l
- return tuple(ns) + (s[c:],)
-
-def MP(number):
- if number==0: return '\000'*4
- assert number>0
- bn = Util.number.long_to_bytes(number)
- if ord(bn[0])&128:
- bn = '\000' + bn
- return struct.pack('>L',len(bn)) + bn
-
-def getMP(data, count=1):
- """
- Get multiple precision integer out of the string. A multiple precision
- integer is stored as a 4-byte length followed by length bytes of the
- integer. If count is specified, get count integers out of the string.
- The return value is a tuple of count integers followed by the rest of
- the data.
- """
- mp = []
- c = 0
- for i in range(count):
- length, = struct.unpack('>L',data[c:c+4])
- mp.append(Util.number.bytes_to_long(data[c+4:c+4+length]))
- c += 4 + length
- return tuple(mp) + (data[c:],)
-
-def _MPpow(x, y, z):
- """return the MP version of (x**y)%z
- """
- return MP(pow(x,y,z))
-
-def ffs(c, s):
- """
- first from second
- goes through the first list, looking for items in the second, returns the first one
- """
- for i in c:
- if i in s: return i
-
-getMP_py = getMP
-MP_py = MP
-_MPpow_py = _MPpow
-pyPow = pow
-
-def _fastgetMP(data, count=1):
- mp = []
- c = 0
- for i in range(count):
- length = struct.unpack('!L', data[c:c+4])[0]
- mp.append(long(gmpy.mpz(data[c + 4:c + 4 + length][::-1] + '\x00', 256)))
- c += length + 4
- return tuple(mp) + (data[c:],)
-
-def _fastMP(i):
- i2 = gmpy.mpz(i).binary()[::-1]
- return struct.pack('!L', len(i2)) + i2
-
-def _fastMPpow(x, y, z=None):
- r = pyPow(gmpy.mpz(x),y,z).binary()[::-1]
- return struct.pack('!L', len(r)) + r
-
-def install():
- global getMP, MP, _MPpow
- getMP = _fastgetMP
- MP = _fastMP
- _MPpow = _fastMPpow
- # XXX: We override builtin pow so that PyCrypto can benefit from gmpy too.
- def _fastpow(x, y, z=None, mpz=gmpy.mpz):
- if type(x) in (long, int):
- x = mpz(x)
- return pyPow(x, y, z)
- __builtin__.pow = _fastpow # evil evil
-
-try:
- import gmpy
- install()
-except ImportError:
- pass
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py
deleted file mode 100755
index 25271995..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py
+++ /dev/null
@@ -1,637 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_connection -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module contains the implementation of the ssh-connection service, which
-allows access to the shell and port-forwarding.
-
-Maintainer: Paul Swartz
-"""
-
-import struct
-
-from twisted.conch.ssh import service, common
-from twisted.conch import error
-from twisted.internet import defer
-from twisted.python import log
-
-class SSHConnection(service.SSHService):
- """
- An implementation of the 'ssh-connection' service. It is used to
- multiplex multiple channels over the single SSH connection.
-
- @ivar localChannelID: the next number to use as a local channel ID.
- @type localChannelID: C{int}
- @ivar channels: a C{dict} mapping a local channel ID to C{SSHChannel}
- subclasses.
- @type channels: C{dict}
- @ivar localToRemoteChannel: a C{dict} mapping a local channel ID to a
- remote channel ID.
- @type localToRemoteChannel: C{dict}
- @ivar channelsToRemoteChannel: a C{dict} mapping a C{SSHChannel} subclass
- to remote channel ID.
- @type channelsToRemoteChannel: C{dict}
- @ivar deferreds: a C{dict} mapping a local channel ID to a C{list} of
- C{Deferreds} for outstanding channel requests. Also, the 'global'
- key stores the C{list} of pending global request C{Deferred}s.
- """
- name = 'ssh-connection'
-
- def __init__(self):
- self.localChannelID = 0 # this is the current # to use for channel ID
- self.localToRemoteChannel = {} # local channel ID -> remote channel ID
- self.channels = {} # local channel ID -> subclass of SSHChannel
- self.channelsToRemoteChannel = {} # subclass of SSHChannel ->
- # remote channel ID
- self.deferreds = {"global": []} # local channel -> list of deferreds
- # for pending requests or 'global' -> list of
- # deferreds for global requests
- self.transport = None # gets set later
-
-
- def serviceStarted(self):
- if hasattr(self.transport, 'avatar'):
- self.transport.avatar.conn = self
-
-
- def serviceStopped(self):
- """
- Called when the connection is stopped.
- """
- map(self.channelClosed, self.channels.values())
- self._cleanupGlobalDeferreds()
-
-
- def _cleanupGlobalDeferreds(self):
- """
- All pending requests that have returned a deferred must be errbacked
- when this service is stopped, otherwise they might be left uncalled and
- uncallable.
- """
- for d in self.deferreds["global"]:
- d.errback(error.ConchError("Connection stopped."))
- del self.deferreds["global"][:]
-
-
- # packet methods
- def ssh_GLOBAL_REQUEST(self, packet):
- """
- The other side has made a global request. Payload::
- string request type
- bool want reply
- <request specific data>
-
- This dispatches to self.gotGlobalRequest.
- """
- requestType, rest = common.getNS(packet)
- wantReply, rest = ord(rest[0]), rest[1:]
- ret = self.gotGlobalRequest(requestType, rest)
- if wantReply:
- reply = MSG_REQUEST_FAILURE
- data = ''
- if ret:
- reply = MSG_REQUEST_SUCCESS
- if isinstance(ret, (tuple, list)):
- data = ret[1]
- self.transport.sendPacket(reply, data)
-
- def ssh_REQUEST_SUCCESS(self, packet):
- """
- Our global request succeeded. Get the appropriate Deferred and call
- it back with the packet we received.
- """
- log.msg('RS')
- self.deferreds['global'].pop(0).callback(packet)
-
- def ssh_REQUEST_FAILURE(self, packet):
- """
- Our global request failed. Get the appropriate Deferred and errback
- it with the packet we received.
- """
- log.msg('RF')
- self.deferreds['global'].pop(0).errback(
- error.ConchError('global request failed', packet))
-
- def ssh_CHANNEL_OPEN(self, packet):
- """
- The other side wants to get a channel. Payload::
- string channel name
- uint32 remote channel number
- uint32 remote window size
- uint32 remote maximum packet size
- <channel specific data>
-
- We get a channel from self.getChannel(), give it a local channel number
- and notify the other side. Then notify the channel by calling its
- channelOpen method.
- """
- channelType, rest = common.getNS(packet)
- senderChannel, windowSize, maxPacket = struct.unpack('>3L', rest[:12])
- packet = rest[12:]
- try:
- channel = self.getChannel(channelType, windowSize, maxPacket,
- packet)
- localChannel = self.localChannelID
- self.localChannelID += 1
- channel.id = localChannel
- self.channels[localChannel] = channel
- self.channelsToRemoteChannel[channel] = senderChannel
- self.localToRemoteChannel[localChannel] = senderChannel
- self.transport.sendPacket(MSG_CHANNEL_OPEN_CONFIRMATION,
- struct.pack('>4L', senderChannel, localChannel,
- channel.localWindowSize,
- channel.localMaxPacket)+channel.specificData)
- log.callWithLogger(channel, channel.channelOpen, packet)
- except Exception, e:
- log.msg('channel open failed')
- log.err(e)
- if isinstance(e, error.ConchError):
- textualInfo, reason = e.args
- if isinstance(textualInfo, (int, long)):
- # See #3657 and #3071
- textualInfo, reason = reason, textualInfo
- else:
- reason = OPEN_CONNECT_FAILED
- textualInfo = "unknown failure"
- self.transport.sendPacket(
- MSG_CHANNEL_OPEN_FAILURE,
- struct.pack('>2L', senderChannel, reason) +
- common.NS(textualInfo) + common.NS(''))
-
- def ssh_CHANNEL_OPEN_CONFIRMATION(self, packet):
- """
- The other side accepted our MSG_CHANNEL_OPEN request. Payload::
- uint32 local channel number
- uint32 remote channel number
- uint32 remote window size
- uint32 remote maximum packet size
- <channel specific data>
-
- Find the channel using the local channel number and notify its
- channelOpen method.
- """
- (localChannel, remoteChannel, windowSize,
- maxPacket) = struct.unpack('>4L', packet[: 16])
- specificData = packet[16:]
- channel = self.channels[localChannel]
- channel.conn = self
- self.localToRemoteChannel[localChannel] = remoteChannel
- self.channelsToRemoteChannel[channel] = remoteChannel
- channel.remoteWindowLeft = windowSize
- channel.remoteMaxPacket = maxPacket
- log.callWithLogger(channel, channel.channelOpen, specificData)
-
- def ssh_CHANNEL_OPEN_FAILURE(self, packet):
- """
- The other side did not accept our MSG_CHANNEL_OPEN request. Payload::
- uint32 local channel number
- uint32 reason code
- string reason description
-
- Find the channel using the local channel number and notify it by
- calling its openFailed() method.
- """
- localChannel, reasonCode = struct.unpack('>2L', packet[:8])
- reasonDesc = common.getNS(packet[8:])[0]
- channel = self.channels[localChannel]
- del self.channels[localChannel]
- channel.conn = self
- reason = error.ConchError(reasonDesc, reasonCode)
- log.callWithLogger(channel, channel.openFailed, reason)
-
- def ssh_CHANNEL_WINDOW_ADJUST(self, packet):
- """
- The other side is adding bytes to its window. Payload::
- uint32 local channel number
- uint32 bytes to add
-
- Call the channel's addWindowBytes() method to add new bytes to the
- remote window.
- """
- localChannel, bytesToAdd = struct.unpack('>2L', packet[:8])
- channel = self.channels[localChannel]
- log.callWithLogger(channel, channel.addWindowBytes, bytesToAdd)
-
- def ssh_CHANNEL_DATA(self, packet):
- """
- The other side is sending us data. Payload::
- uint32 local channel number
- string data
-
- Check to make sure the other side hasn't sent too much data (more
- than what's in the window, or more than the maximum packet size). If
- they have, close the channel. Otherwise, decrease the available
- window and pass the data to the channel's dataReceived().
- """
- localChannel, dataLength = struct.unpack('>2L', packet[:8])
- channel = self.channels[localChannel]
- # XXX should this move to dataReceived to put client in charge?
- if (dataLength > channel.localWindowLeft or
- dataLength > channel.localMaxPacket): # more data than we want
- log.callWithLogger(channel, log.msg, 'too much data')
- self.sendClose(channel)
- return
- #packet = packet[:channel.localWindowLeft+4]
- data = common.getNS(packet[4:])[0]
- channel.localWindowLeft -= dataLength
- if channel.localWindowLeft < channel.localWindowSize // 2:
- self.adjustWindow(channel, channel.localWindowSize - \
- channel.localWindowLeft)
- #log.msg('local window left: %s/%s' % (channel.localWindowLeft,
- # channel.localWindowSize))
- log.callWithLogger(channel, channel.dataReceived, data)
-
- def ssh_CHANNEL_EXTENDED_DATA(self, packet):
- """
- The other side is sending us exteneded data. Payload::
- uint32 local channel number
- uint32 type code
- string data
-
- Check to make sure the other side hasn't sent too much data (more
- than what's in the window, or or than the maximum packet size). If
- they have, close the channel. Otherwise, decrease the available
- window and pass the data and type code to the channel's
- extReceived().
- """
- localChannel, typeCode, dataLength = struct.unpack('>3L', packet[:12])
- channel = self.channels[localChannel]
- if (dataLength > channel.localWindowLeft or
- dataLength > channel.localMaxPacket):
- log.callWithLogger(channel, log.msg, 'too much extdata')
- self.sendClose(channel)
- return
- data = common.getNS(packet[8:])[0]
- channel.localWindowLeft -= dataLength
- if channel.localWindowLeft < channel.localWindowSize // 2:
- self.adjustWindow(channel, channel.localWindowSize -
- channel.localWindowLeft)
- log.callWithLogger(channel, channel.extReceived, typeCode, data)
-
- def ssh_CHANNEL_EOF(self, packet):
- """
- The other side is not sending any more data. Payload::
- uint32 local channel number
-
- Notify the channel by calling its eofReceived() method.
- """
- localChannel = struct.unpack('>L', packet[:4])[0]
- channel = self.channels[localChannel]
- log.callWithLogger(channel, channel.eofReceived)
-
- def ssh_CHANNEL_CLOSE(self, packet):
- """
- The other side is closing its end; it does not want to receive any
- more data. Payload::
- uint32 local channel number
-
- Notify the channnel by calling its closeReceived() method. If
- the channel has also sent a close message, call self.channelClosed().
- """
- localChannel = struct.unpack('>L', packet[:4])[0]
- channel = self.channels[localChannel]
- log.callWithLogger(channel, channel.closeReceived)
- channel.remoteClosed = True
- if channel.localClosed and channel.remoteClosed:
- self.channelClosed(channel)
-
- def ssh_CHANNEL_REQUEST(self, packet):
- """
- The other side is sending a request to a channel. Payload::
- uint32 local channel number
- string request name
- bool want reply
- <request specific data>
-
- Pass the message to the channel's requestReceived method. If the
- other side wants a reply, add callbacks which will send the
- reply.
- """
- localChannel = struct.unpack('>L', packet[: 4])[0]
- requestType, rest = common.getNS(packet[4:])
- wantReply = ord(rest[0])
- channel = self.channels[localChannel]
- d = defer.maybeDeferred(log.callWithLogger, channel,
- channel.requestReceived, requestType, rest[1:])
- if wantReply:
- d.addCallback(self._cbChannelRequest, localChannel)
- d.addErrback(self._ebChannelRequest, localChannel)
- return d
-
- def _cbChannelRequest(self, result, localChannel):
- """
- Called back if the other side wanted a reply to a channel request. If
- the result is true, send a MSG_CHANNEL_SUCCESS. Otherwise, raise
- a C{error.ConchError}
-
- @param result: the value returned from the channel's requestReceived()
- method. If it's False, the request failed.
- @type result: C{bool}
- @param localChannel: the local channel ID of the channel to which the
- request was made.
- @type localChannel: C{int}
- @raises ConchError: if the result is False.
- """
- if not result:
- raise error.ConchError('failed request')
- self.transport.sendPacket(MSG_CHANNEL_SUCCESS, struct.pack('>L',
- self.localToRemoteChannel[localChannel]))
-
- def _ebChannelRequest(self, result, localChannel):
- """
- Called if the other wisde wanted a reply to the channel requeset and
- the channel request failed.
-
- @param result: a Failure, but it's not used.
- @param localChannel: the local channel ID of the channel to which the
- request was made.
- @type localChannel: C{int}
- """
- self.transport.sendPacket(MSG_CHANNEL_FAILURE, struct.pack('>L',
- self.localToRemoteChannel[localChannel]))
-
- def ssh_CHANNEL_SUCCESS(self, packet):
- """
- Our channel request to the other other side succeeded. Payload::
- uint32 local channel number
-
- Get the C{Deferred} out of self.deferreds and call it back.
- """
- localChannel = struct.unpack('>L', packet[:4])[0]
- if self.deferreds.get(localChannel):
- d = self.deferreds[localChannel].pop(0)
- log.callWithLogger(self.channels[localChannel],
- d.callback, '')
-
- def ssh_CHANNEL_FAILURE(self, packet):
- """
- Our channel request to the other side failed. Payload::
- uint32 local channel number
-
- Get the C{Deferred} out of self.deferreds and errback it with a
- C{error.ConchError}.
- """
- localChannel = struct.unpack('>L', packet[:4])[0]
- if self.deferreds.get(localChannel):
- d = self.deferreds[localChannel].pop(0)
- log.callWithLogger(self.channels[localChannel],
- d.errback,
- error.ConchError('channel request failed'))
-
- # methods for users of the connection to call
-
- def sendGlobalRequest(self, request, data, wantReply=0):
- """
- Send a global request for this connection. Current this is only used
- for remote->local TCP forwarding.
-
- @type request: C{str}
- @type data: C{str}
- @type wantReply: C{bool}
- @rtype C{Deferred}/C{None}
- """
- self.transport.sendPacket(MSG_GLOBAL_REQUEST,
- common.NS(request)
- + (wantReply and '\xff' or '\x00')
- + data)
- if wantReply:
- d = defer.Deferred()
- self.deferreds['global'].append(d)
- return d
-
- def openChannel(self, channel, extra=''):
- """
- Open a new channel on this connection.
-
- @type channel: subclass of C{SSHChannel}
- @type extra: C{str}
- """
- log.msg('opening channel %s with %s %s'%(self.localChannelID,
- channel.localWindowSize, channel.localMaxPacket))
- self.transport.sendPacket(MSG_CHANNEL_OPEN, common.NS(channel.name)
- + struct.pack('>3L', self.localChannelID,
- channel.localWindowSize, channel.localMaxPacket)
- + extra)
- channel.id = self.localChannelID
- self.channels[self.localChannelID] = channel
- self.localChannelID += 1
-
- def sendRequest(self, channel, requestType, data, wantReply=0):
- """
- Send a request to a channel.
-
- @type channel: subclass of C{SSHChannel}
- @type requestType: C{str}
- @type data: C{str}
- @type wantReply: C{bool}
- @rtype C{Deferred}/C{None}
- """
- if channel.localClosed:
- return
- log.msg('sending request %s' % requestType)
- self.transport.sendPacket(MSG_CHANNEL_REQUEST, struct.pack('>L',
- self.channelsToRemoteChannel[channel])
- + common.NS(requestType)+chr(wantReply)
- + data)
- if wantReply:
- d = defer.Deferred()
- self.deferreds.setdefault(channel.id, []).append(d)
- return d
-
- def adjustWindow(self, channel, bytesToAdd):
- """
- Tell the other side that we will receive more data. This should not
- normally need to be called as it is managed automatically.
-
- @type channel: subclass of L{SSHChannel}
- @type bytesToAdd: C{int}
- """
- if channel.localClosed:
- return # we're already closed
- self.transport.sendPacket(MSG_CHANNEL_WINDOW_ADJUST, struct.pack('>2L',
- self.channelsToRemoteChannel[channel],
- bytesToAdd))
- log.msg('adding %i to %i in channel %i' % (bytesToAdd,
- channel.localWindowLeft, channel.id))
- channel.localWindowLeft += bytesToAdd
-
- def sendData(self, channel, data):
- """
- Send data to a channel. This should not normally be used: instead use
- channel.write(data) as it manages the window automatically.
-
- @type channel: subclass of L{SSHChannel}
- @type data: C{str}
- """
- if channel.localClosed:
- return # we're already closed
- self.transport.sendPacket(MSG_CHANNEL_DATA, struct.pack('>L',
- self.channelsToRemoteChannel[channel]) +
- common.NS(data))
-
- def sendExtendedData(self, channel, dataType, data):
- """
- Send extended data to a channel. This should not normally be used:
- instead use channel.writeExtendedData(data, dataType) as it manages
- the window automatically.
-
- @type channel: subclass of L{SSHChannel}
- @type dataType: C{int}
- @type data: C{str}
- """
- if channel.localClosed:
- return # we're already closed
- self.transport.sendPacket(MSG_CHANNEL_EXTENDED_DATA, struct.pack('>2L',
- self.channelsToRemoteChannel[channel],dataType) \
- + common.NS(data))
-
- def sendEOF(self, channel):
- """
- Send an EOF (End of File) for a channel.
-
- @type channel: subclass of L{SSHChannel}
- """
- if channel.localClosed:
- return # we're already closed
- log.msg('sending eof')
- self.transport.sendPacket(MSG_CHANNEL_EOF, struct.pack('>L',
- self.channelsToRemoteChannel[channel]))
-
- def sendClose(self, channel):
- """
- Close a channel.
-
- @type channel: subclass of L{SSHChannel}
- """
- if channel.localClosed:
- return # we're already closed
- log.msg('sending close %i' % channel.id)
- self.transport.sendPacket(MSG_CHANNEL_CLOSE, struct.pack('>L',
- self.channelsToRemoteChannel[channel]))
- channel.localClosed = True
- if channel.localClosed and channel.remoteClosed:
- self.channelClosed(channel)
-
- # methods to override
- def getChannel(self, channelType, windowSize, maxPacket, data):
- """
- The other side requested a channel of some sort.
- channelType is the type of channel being requested,
- windowSize is the initial size of the remote window,
- maxPacket is the largest packet we should send,
- data is any other packet data (often nothing).
-
- We return a subclass of L{SSHChannel}.
-
- By default, this dispatches to a method 'channel_channelType' with any
- non-alphanumerics in the channelType replace with _'s. If it cannot
- find a suitable method, it returns an OPEN_UNKNOWN_CHANNEL_TYPE error.
- The method is called with arguments of windowSize, maxPacket, data.
-
- @type channelType: C{str}
- @type windowSize: C{int}
- @type maxPacket: C{int}
- @type data: C{str}
- @rtype: subclass of L{SSHChannel}/C{tuple}
- """
- log.msg('got channel %s request' % channelType)
- if hasattr(self.transport, "avatar"): # this is a server!
- chan = self.transport.avatar.lookupChannel(channelType,
- windowSize,
- maxPacket,
- data)
- else:
- channelType = channelType.translate(TRANSLATE_TABLE)
- f = getattr(self, 'channel_%s' % channelType, None)
- if f is not None:
- chan = f(windowSize, maxPacket, data)
- else:
- chan = None
- if chan is None:
- raise error.ConchError('unknown channel',
- OPEN_UNKNOWN_CHANNEL_TYPE)
- else:
- chan.conn = self
- return chan
-
- def gotGlobalRequest(self, requestType, data):
- """
- We got a global request. pretty much, this is just used by the client
- to request that we forward a port from the server to the client.
- Returns either:
- - 1: request accepted
- - 1, <data>: request accepted with request specific data
- - 0: request denied
-
- By default, this dispatches to a method 'global_requestType' with
- -'s in requestType replaced with _'s. The found method is passed data.
- If this method cannot be found, this method returns 0. Otherwise, it
- returns the return value of that method.
-
- @type requestType: C{str}
- @type data: C{str}
- @rtype: C{int}/C{tuple}
- """
- log.msg('got global %s request' % requestType)
- if hasattr(self.transport, 'avatar'): # this is a server!
- return self.transport.avatar.gotGlobalRequest(requestType, data)
-
- requestType = requestType.replace('-','_')
- f = getattr(self, 'global_%s' % requestType, None)
- if not f:
- return 0
- return f(data)
-
- def channelClosed(self, channel):
- """
- Called when a channel is closed.
- It clears the local state related to the channel, and calls
- channel.closed().
- MAKE SURE YOU CALL THIS METHOD, even if you subclass L{SSHConnection}.
- If you don't, things will break mysteriously.
-
- @type channel: L{SSHChannel}
- """
- if channel in self.channelsToRemoteChannel: # actually open
- channel.localClosed = channel.remoteClosed = True
- del self.localToRemoteChannel[channel.id]
- del self.channels[channel.id]
- del self.channelsToRemoteChannel[channel]
- for d in self.deferreds.setdefault(channel.id, []):
- d.errback(error.ConchError("Channel closed."))
- del self.deferreds[channel.id][:]
- log.callWithLogger(channel, channel.closed)
-
-MSG_GLOBAL_REQUEST = 80
-MSG_REQUEST_SUCCESS = 81
-MSG_REQUEST_FAILURE = 82
-MSG_CHANNEL_OPEN = 90
-MSG_CHANNEL_OPEN_CONFIRMATION = 91
-MSG_CHANNEL_OPEN_FAILURE = 92
-MSG_CHANNEL_WINDOW_ADJUST = 93
-MSG_CHANNEL_DATA = 94
-MSG_CHANNEL_EXTENDED_DATA = 95
-MSG_CHANNEL_EOF = 96
-MSG_CHANNEL_CLOSE = 97
-MSG_CHANNEL_REQUEST = 98
-MSG_CHANNEL_SUCCESS = 99
-MSG_CHANNEL_FAILURE = 100
-
-OPEN_ADMINISTRATIVELY_PROHIBITED = 1
-OPEN_CONNECT_FAILED = 2
-OPEN_UNKNOWN_CHANNEL_TYPE = 3
-OPEN_RESOURCE_SHORTAGE = 4
-
-EXTENDED_DATA_STDERR = 1
-
-messages = {}
-for name, value in locals().copy().items():
- if name[:4] == 'MSG_':
- messages[value] = name # doesn't handle doubles
-
-import string
-alphanums = string.letters + string.digits
-TRANSLATE_TABLE = ''.join([chr(i) in alphanums and chr(i) or '_'
- for i in range(256)])
-SSHConnection.protocolMessages = messages
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py
deleted file mode 100755
index 3c50932f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A Factory for SSH servers, along with an OpenSSHFactory to use the same
-data sources as OpenSSH.
-
-Maintainer: Paul Swartz
-"""
-
-from twisted.internet import protocol
-from twisted.python import log
-from twisted.python.reflect import qual
-
-from twisted.conch import error
-from twisted.conch.ssh import keys
-import transport, userauth, connection
-
-import random
-import warnings
-
-class SSHFactory(protocol.Factory):
- """
- A Factory for SSH servers.
- """
- protocol = transport.SSHServerTransport
-
- services = {
- 'ssh-userauth':userauth.SSHUserAuthServer,
- 'ssh-connection':connection.SSHConnection
- }
- def startFactory(self):
- """
- Check for public and private keys.
- """
- if not hasattr(self,'publicKeys'):
- self.publicKeys = self.getPublicKeys()
- for keyType, value in self.publicKeys.items():
- if isinstance(value, str):
- warnings.warn("Returning a mapping from strings to "
- "strings from getPublicKeys()/publicKeys (in %s) "
- "is deprecated. Return a mapping from "
- "strings to Key objects instead." %
- (qual(self.__class__)),
- DeprecationWarning, stacklevel=1)
- self.publicKeys[keyType] = keys.Key.fromString(value)
- if not hasattr(self,'privateKeys'):
- self.privateKeys = self.getPrivateKeys()
- for keyType, value in self.privateKeys.items():
- if not isinstance(value, keys.Key):
- warnings.warn("Returning a mapping from strings to "
- "PyCrypto key objects from "
- "getPrivateKeys()/privateKeys (in %s) "
- "is deprecated. Return a mapping from "
- "strings to Key objects instead." %
- (qual(self.__class__),),
- DeprecationWarning, stacklevel=1)
- self.privateKeys[keyType] = keys.Key(value)
- if not self.publicKeys or not self.privateKeys:
- raise error.ConchError('no host keys, failing')
- if not hasattr(self,'primes'):
- self.primes = self.getPrimes()
-
-
- def buildProtocol(self, addr):
- """
- Create an instance of the server side of the SSH protocol.
-
- @type addr: L{twisted.internet.interfaces.IAddress} provider
- @param addr: The address at which the server will listen.
-
- @rtype: L{twisted.conch.ssh.SSHServerTransport}
- @return: The built transport.
- """
- t = protocol.Factory.buildProtocol(self, addr)
- t.supportedPublicKeys = self.privateKeys.keys()
- if not self.primes:
- log.msg('disabling diffie-hellman-group-exchange because we '
- 'cannot find moduli file')
- ske = t.supportedKeyExchanges[:]
- ske.remove('diffie-hellman-group-exchange-sha1')
- t.supportedKeyExchanges = ske
- return t
-
-
- def getPublicKeys(self):
- """
- Called when the factory is started to get the public portions of the
- servers host keys. Returns a dictionary mapping SSH key types to
- public key strings.
-
- @rtype: C{dict}
- """
- raise NotImplementedError('getPublicKeys unimplemented')
-
-
- def getPrivateKeys(self):
- """
- Called when the factory is started to get the private portions of the
- servers host keys. Returns a dictionary mapping SSH key types to
- C{Crypto.PublicKey.pubkey.pubkey} objects.
-
- @rtype: C{dict}
- """
- raise NotImplementedError('getPrivateKeys unimplemented')
-
-
- def getPrimes(self):
- """
- Called when the factory is started to get Diffie-Hellman generators and
- primes to use. Returns a dictionary mapping number of bits to lists
- of tuple of (generator, prime).
-
- @rtype: C{dict}
- """
-
-
- def getDHPrime(self, bits):
- """
- Return a tuple of (g, p) for a Diffe-Hellman process, with p being as
- close to bits bits as possible.
-
- @type bits: C{int}
- @rtype: C{tuple}
- """
- primesKeys = self.primes.keys()
- primesKeys.sort(lambda x, y: cmp(abs(x - bits), abs(y - bits)))
- realBits = primesKeys[0]
- return random.choice(self.primes[realBits])
-
-
- def getService(self, transport, service):
- """
- Return a class to use as a service for the given transport.
-
- @type transport: L{transport.SSHServerTransport}
- @type service: C{str}
- @rtype: subclass of L{service.SSHService}
- """
- if service == 'ssh-userauth' or hasattr(transport, 'avatar'):
- return self.services[service]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py
deleted file mode 100755
index 9b11db0d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py
+++ /dev/null
@@ -1,934 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_filetransfer -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-import struct, errno
-
-from twisted.internet import defer, protocol
-from twisted.python import failure, log
-
-from common import NS, getNS
-from twisted.conch.interfaces import ISFTPServer, ISFTPFile
-
-from zope import interface
-
-
-
-class FileTransferBase(protocol.Protocol):
-
- versions = (3, )
-
- packetTypes = {}
-
- def __init__(self):
- self.buf = ''
- self.otherVersion = None # this gets set
-
- def sendPacket(self, kind, data):
- self.transport.write(struct.pack('!LB', len(data)+1, kind) + data)
-
- def dataReceived(self, data):
- self.buf += data
- while len(self.buf) > 5:
- length, kind = struct.unpack('!LB', self.buf[:5])
- if len(self.buf) < 4 + length:
- return
- data, self.buf = self.buf[5:4+length], self.buf[4+length:]
- packetType = self.packetTypes.get(kind, None)
- if not packetType:
- log.msg('no packet type for', kind)
- continue
- f = getattr(self, 'packet_%s' % packetType, None)
- if not f:
- log.msg('not implemented: %s' % packetType)
- log.msg(repr(data[4:]))
- reqId, = struct.unpack('!L', data[:4])
- self._sendStatus(reqId, FX_OP_UNSUPPORTED,
- "don't understand %s" % packetType)
- #XXX not implemented
- continue
- try:
- f(data)
- except:
- log.err()
- continue
- reqId ,= struct.unpack('!L', data[:4])
- self._ebStatus(failure.Failure(e), reqId)
-
- def _parseAttributes(self, data):
- flags ,= struct.unpack('!L', data[:4])
- attrs = {}
- data = data[4:]
- if flags & FILEXFER_ATTR_SIZE == FILEXFER_ATTR_SIZE:
- size ,= struct.unpack('!Q', data[:8])
- attrs['size'] = size
- data = data[8:]
- if flags & FILEXFER_ATTR_OWNERGROUP == FILEXFER_ATTR_OWNERGROUP:
- uid, gid = struct.unpack('!2L', data[:8])
- attrs['uid'] = uid
- attrs['gid'] = gid
- data = data[8:]
- if flags & FILEXFER_ATTR_PERMISSIONS == FILEXFER_ATTR_PERMISSIONS:
- perms ,= struct.unpack('!L', data[:4])
- attrs['permissions'] = perms
- data = data[4:]
- if flags & FILEXFER_ATTR_ACMODTIME == FILEXFER_ATTR_ACMODTIME:
- atime, mtime = struct.unpack('!2L', data[:8])
- attrs['atime'] = atime
- attrs['mtime'] = mtime
- data = data[8:]
- if flags & FILEXFER_ATTR_EXTENDED == FILEXFER_ATTR_EXTENDED:
- extended_count ,= struct.unpack('!L', data[:4])
- data = data[4:]
- for i in xrange(extended_count):
- extended_type, data = getNS(data)
- extended_data, data = getNS(data)
- attrs['ext_%s' % extended_type] = extended_data
- return attrs, data
-
- def _packAttributes(self, attrs):
- flags = 0
- data = ''
- if 'size' in attrs:
- data += struct.pack('!Q', attrs['size'])
- flags |= FILEXFER_ATTR_SIZE
- if 'uid' in attrs and 'gid' in attrs:
- data += struct.pack('!2L', attrs['uid'], attrs['gid'])
- flags |= FILEXFER_ATTR_OWNERGROUP
- if 'permissions' in attrs:
- data += struct.pack('!L', attrs['permissions'])
- flags |= FILEXFER_ATTR_PERMISSIONS
- if 'atime' in attrs and 'mtime' in attrs:
- data += struct.pack('!2L', attrs['atime'], attrs['mtime'])
- flags |= FILEXFER_ATTR_ACMODTIME
- extended = []
- for k in attrs:
- if k.startswith('ext_'):
- ext_type = NS(k[4:])
- ext_data = NS(attrs[k])
- extended.append(ext_type+ext_data)
- if extended:
- data += struct.pack('!L', len(extended))
- data += ''.join(extended)
- flags |= FILEXFER_ATTR_EXTENDED
- return struct.pack('!L', flags) + data
-
-class FileTransferServer(FileTransferBase):
-
- def __init__(self, data=None, avatar=None):
- FileTransferBase.__init__(self)
- self.client = ISFTPServer(avatar) # yay interfaces
- self.openFiles = {}
- self.openDirs = {}
-
- def packet_INIT(self, data):
- version ,= struct.unpack('!L', data[:4])
- self.version = min(list(self.versions) + [version])
- data = data[4:]
- ext = {}
- while data:
- ext_name, data = getNS(data)
- ext_data, data = getNS(data)
- ext[ext_name] = ext_data
- our_ext = self.client.gotVersion(version, ext)
- our_ext_data = ""
- for (k,v) in our_ext.items():
- our_ext_data += NS(k) + NS(v)
- self.sendPacket(FXP_VERSION, struct.pack('!L', self.version) + \
- our_ext_data)
-
- def packet_OPEN(self, data):
- requestId = data[:4]
- data = data[4:]
- filename, data = getNS(data)
- flags ,= struct.unpack('!L', data[:4])
- data = data[4:]
- attrs, data = self._parseAttributes(data)
- assert data == '', 'still have data in OPEN: %s' % repr(data)
- d = defer.maybeDeferred(self.client.openFile, filename, flags, attrs)
- d.addCallback(self._cbOpenFile, requestId)
- d.addErrback(self._ebStatus, requestId, "open failed")
-
- def _cbOpenFile(self, fileObj, requestId):
- fileId = str(hash(fileObj))
- if fileId in self.openFiles:
- raise KeyError, 'id already open'
- self.openFiles[fileId] = fileObj
- self.sendPacket(FXP_HANDLE, requestId + NS(fileId))
-
- def packet_CLOSE(self, data):
- requestId = data[:4]
- data = data[4:]
- handle, data = getNS(data)
- assert data == '', 'still have data in CLOSE: %s' % repr(data)
- if handle in self.openFiles:
- fileObj = self.openFiles[handle]
- d = defer.maybeDeferred(fileObj.close)
- d.addCallback(self._cbClose, handle, requestId)
- d.addErrback(self._ebStatus, requestId, "close failed")
- elif handle in self.openDirs:
- dirObj = self.openDirs[handle][0]
- d = defer.maybeDeferred(dirObj.close)
- d.addCallback(self._cbClose, handle, requestId, 1)
- d.addErrback(self._ebStatus, requestId, "close failed")
- else:
- self._ebClose(failure.Failure(KeyError()), requestId)
-
- def _cbClose(self, result, handle, requestId, isDir = 0):
- if isDir:
- del self.openDirs[handle]
- else:
- del self.openFiles[handle]
- self._sendStatus(requestId, FX_OK, 'file closed')
-
- def packet_READ(self, data):
- requestId = data[:4]
- data = data[4:]
- handle, data = getNS(data)
- (offset, length), data = struct.unpack('!QL', data[:12]), data[12:]
- assert data == '', 'still have data in READ: %s' % repr(data)
- if handle not in self.openFiles:
- self._ebRead(failure.Failure(KeyError()), requestId)
- else:
- fileObj = self.openFiles[handle]
- d = defer.maybeDeferred(fileObj.readChunk, offset, length)
- d.addCallback(self._cbRead, requestId)
- d.addErrback(self._ebStatus, requestId, "read failed")
-
- def _cbRead(self, result, requestId):
- if result == '': # python's read will return this for EOF
- raise EOFError()
- self.sendPacket(FXP_DATA, requestId + NS(result))
-
- def packet_WRITE(self, data):
- requestId = data[:4]
- data = data[4:]
- handle, data = getNS(data)
- offset, = struct.unpack('!Q', data[:8])
- data = data[8:]
- writeData, data = getNS(data)
- assert data == '', 'still have data in WRITE: %s' % repr(data)
- if handle not in self.openFiles:
- self._ebWrite(failure.Failure(KeyError()), requestId)
- else:
- fileObj = self.openFiles[handle]
- d = defer.maybeDeferred(fileObj.writeChunk, offset, writeData)
- d.addCallback(self._cbStatus, requestId, "write succeeded")
- d.addErrback(self._ebStatus, requestId, "write failed")
-
- def packet_REMOVE(self, data):
- requestId = data[:4]
- data = data[4:]
- filename, data = getNS(data)
- assert data == '', 'still have data in REMOVE: %s' % repr(data)
- d = defer.maybeDeferred(self.client.removeFile, filename)
- d.addCallback(self._cbStatus, requestId, "remove succeeded")
- d.addErrback(self._ebStatus, requestId, "remove failed")
-
- def packet_RENAME(self, data):
- requestId = data[:4]
- data = data[4:]
- oldPath, data = getNS(data)
- newPath, data = getNS(data)
- assert data == '', 'still have data in RENAME: %s' % repr(data)
- d = defer.maybeDeferred(self.client.renameFile, oldPath, newPath)
- d.addCallback(self._cbStatus, requestId, "rename succeeded")
- d.addErrback(self._ebStatus, requestId, "rename failed")
-
- def packet_MKDIR(self, data):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- attrs, data = self._parseAttributes(data)
- assert data == '', 'still have data in MKDIR: %s' % repr(data)
- d = defer.maybeDeferred(self.client.makeDirectory, path, attrs)
- d.addCallback(self._cbStatus, requestId, "mkdir succeeded")
- d.addErrback(self._ebStatus, requestId, "mkdir failed")
-
- def packet_RMDIR(self, data):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- assert data == '', 'still have data in RMDIR: %s' % repr(data)
- d = defer.maybeDeferred(self.client.removeDirectory, path)
- d.addCallback(self._cbStatus, requestId, "rmdir succeeded")
- d.addErrback(self._ebStatus, requestId, "rmdir failed")
-
- def packet_OPENDIR(self, data):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- assert data == '', 'still have data in OPENDIR: %s' % repr(data)
- d = defer.maybeDeferred(self.client.openDirectory, path)
- d.addCallback(self._cbOpenDirectory, requestId)
- d.addErrback(self._ebStatus, requestId, "opendir failed")
-
- def _cbOpenDirectory(self, dirObj, requestId):
- handle = str(hash(dirObj))
- if handle in self.openDirs:
- raise KeyError, "already opened this directory"
- self.openDirs[handle] = [dirObj, iter(dirObj)]
- self.sendPacket(FXP_HANDLE, requestId + NS(handle))
-
- def packet_READDIR(self, data):
- requestId = data[:4]
- data = data[4:]
- handle, data = getNS(data)
- assert data == '', 'still have data in READDIR: %s' % repr(data)
- if handle not in self.openDirs:
- self._ebStatus(failure.Failure(KeyError()), requestId)
- else:
- dirObj, dirIter = self.openDirs[handle]
- d = defer.maybeDeferred(self._scanDirectory, dirIter, [])
- d.addCallback(self._cbSendDirectory, requestId)
- d.addErrback(self._ebStatus, requestId, "scan directory failed")
-
- def _scanDirectory(self, dirIter, f):
- while len(f) < 250:
- try:
- info = dirIter.next()
- except StopIteration:
- if not f:
- raise EOFError
- return f
- if isinstance(info, defer.Deferred):
- info.addCallback(self._cbScanDirectory, dirIter, f)
- return
- else:
- f.append(info)
- return f
-
- def _cbScanDirectory(self, result, dirIter, f):
- f.append(result)
- return self._scanDirectory(dirIter, f)
-
- def _cbSendDirectory(self, result, requestId):
- data = ''
- for (filename, longname, attrs) in result:
- data += NS(filename)
- data += NS(longname)
- data += self._packAttributes(attrs)
- self.sendPacket(FXP_NAME, requestId +
- struct.pack('!L', len(result))+data)
-
- def packet_STAT(self, data, followLinks = 1):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- assert data == '', 'still have data in STAT/LSTAT: %s' % repr(data)
- d = defer.maybeDeferred(self.client.getAttrs, path, followLinks)
- d.addCallback(self._cbStat, requestId)
- d.addErrback(self._ebStatus, requestId, 'stat/lstat failed')
-
- def packet_LSTAT(self, data):
- self.packet_STAT(data, 0)
-
- def packet_FSTAT(self, data):
- requestId = data[:4]
- data = data[4:]
- handle, data = getNS(data)
- assert data == '', 'still have data in FSTAT: %s' % repr(data)
- if handle not in self.openFiles:
- self._ebStatus(failure.Failure(KeyError('%s not in self.openFiles'
- % handle)), requestId)
- else:
- fileObj = self.openFiles[handle]
- d = defer.maybeDeferred(fileObj.getAttrs)
- d.addCallback(self._cbStat, requestId)
- d.addErrback(self._ebStatus, requestId, 'fstat failed')
-
- def _cbStat(self, result, requestId):
- data = requestId + self._packAttributes(result)
- self.sendPacket(FXP_ATTRS, data)
-
- def packet_SETSTAT(self, data):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- attrs, data = self._parseAttributes(data)
- if data != '':
- log.msg('WARN: still have data in SETSTAT: %s' % repr(data))
- d = defer.maybeDeferred(self.client.setAttrs, path, attrs)
- d.addCallback(self._cbStatus, requestId, 'setstat succeeded')
- d.addErrback(self._ebStatus, requestId, 'setstat failed')
-
- def packet_FSETSTAT(self, data):
- requestId = data[:4]
- data = data[4:]
- handle, data = getNS(data)
- attrs, data = self._parseAttributes(data)
- assert data == '', 'still have data in FSETSTAT: %s' % repr(data)
- if handle not in self.openFiles:
- self._ebStatus(failure.Failure(KeyError()), requestId)
- else:
- fileObj = self.openFiles[handle]
- d = defer.maybeDeferred(fileObj.setAttrs, attrs)
- d.addCallback(self._cbStatus, requestId, 'fsetstat succeeded')
- d.addErrback(self._ebStatus, requestId, 'fsetstat failed')
-
- def packet_READLINK(self, data):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- assert data == '', 'still have data in READLINK: %s' % repr(data)
- d = defer.maybeDeferred(self.client.readLink, path)
- d.addCallback(self._cbReadLink, requestId)
- d.addErrback(self._ebStatus, requestId, 'readlink failed')
-
- def _cbReadLink(self, result, requestId):
- self._cbSendDirectory([(result, '', {})], requestId)
-
- def packet_SYMLINK(self, data):
- requestId = data[:4]
- data = data[4:]
- linkPath, data = getNS(data)
- targetPath, data = getNS(data)
- d = defer.maybeDeferred(self.client.makeLink, linkPath, targetPath)
- d.addCallback(self._cbStatus, requestId, 'symlink succeeded')
- d.addErrback(self._ebStatus, requestId, 'symlink failed')
-
- def packet_REALPATH(self, data):
- requestId = data[:4]
- data = data[4:]
- path, data = getNS(data)
- assert data == '', 'still have data in REALPATH: %s' % repr(data)
- d = defer.maybeDeferred(self.client.realPath, path)
- d.addCallback(self._cbReadLink, requestId) # same return format
- d.addErrback(self._ebStatus, requestId, 'realpath failed')
-
- def packet_EXTENDED(self, data):
- requestId = data[:4]
- data = data[4:]
- extName, extData = getNS(data)
- d = defer.maybeDeferred(self.client.extendedRequest, extName, extData)
- d.addCallback(self._cbExtended, requestId)
- d.addErrback(self._ebStatus, requestId, 'extended %s failed' % extName)
-
- def _cbExtended(self, data, requestId):
- self.sendPacket(FXP_EXTENDED_REPLY, requestId + data)
-
- def _cbStatus(self, result, requestId, msg = "request succeeded"):
- self._sendStatus(requestId, FX_OK, msg)
-
- def _ebStatus(self, reason, requestId, msg = "request failed"):
- code = FX_FAILURE
- message = msg
- if reason.type in (IOError, OSError):
- if reason.value.errno == errno.ENOENT: # no such file
- code = FX_NO_SUCH_FILE
- message = reason.value.strerror
- elif reason.value.errno == errno.EACCES: # permission denied
- code = FX_PERMISSION_DENIED
- message = reason.value.strerror
- elif reason.value.errno == errno.EEXIST:
- code = FX_FILE_ALREADY_EXISTS
- else:
- log.err(reason)
- elif reason.type == EOFError: # EOF
- code = FX_EOF
- if reason.value.args:
- message = reason.value.args[0]
- elif reason.type == NotImplementedError:
- code = FX_OP_UNSUPPORTED
- if reason.value.args:
- message = reason.value.args[0]
- elif reason.type == SFTPError:
- code = reason.value.code
- message = reason.value.message
- else:
- log.err(reason)
- self._sendStatus(requestId, code, message)
-
- def _sendStatus(self, requestId, code, message, lang = ''):
- """
- Helper method to send a FXP_STATUS message.
- """
- data = requestId + struct.pack('!L', code)
- data += NS(message)
- data += NS(lang)
- self.sendPacket(FXP_STATUS, data)
-
-
- def connectionLost(self, reason):
- """
- Clean all opened files and directories.
- """
- for fileObj in self.openFiles.values():
- fileObj.close()
- self.openFiles = {}
- for (dirObj, dirIter) in self.openDirs.values():
- dirObj.close()
- self.openDirs = {}
-
-
-
-class FileTransferClient(FileTransferBase):
-
- def __init__(self, extData = {}):
- """
- @param extData: a dict of extended_name : extended_data items
- to be sent to the server.
- """
- FileTransferBase.__init__(self)
- self.extData = {}
- self.counter = 0
- self.openRequests = {} # id -> Deferred
- self.wasAFile = {} # Deferred -> 1 TERRIBLE HACK
-
- def connectionMade(self):
- data = struct.pack('!L', max(self.versions))
- for k,v in self.extData.itervalues():
- data += NS(k) + NS(v)
- self.sendPacket(FXP_INIT, data)
-
- def _sendRequest(self, msg, data):
- data = struct.pack('!L', self.counter) + data
- d = defer.Deferred()
- self.openRequests[self.counter] = d
- self.counter += 1
- self.sendPacket(msg, data)
- return d
-
- def _parseRequest(self, data):
- (id,) = struct.unpack('!L', data[:4])
- d = self.openRequests[id]
- del self.openRequests[id]
- return d, data[4:]
-
- def openFile(self, filename, flags, attrs):
- """
- Open a file.
-
- This method returns a L{Deferred} that is called back with an object
- that provides the L{ISFTPFile} interface.
-
- @param filename: a string representing the file to open.
-
- @param flags: a integer of the flags to open the file with, ORed together.
- The flags and their values are listed at the bottom of this file.
-
- @param attrs: a list of attributes to open the file with. It is a
- dictionary, consisting of 0 or more keys. The possible keys are::
-
- size: the size of the file in bytes
- uid: the user ID of the file as an integer
- gid: the group ID of the file as an integer
- permissions: the permissions of the file with as an integer.
- the bit representation of this field is defined by POSIX.
- atime: the access time of the file as seconds since the epoch.
- mtime: the modification time of the file as seconds since the epoch.
- ext_*: extended attributes. The server is not required to
- understand this, but it may.
-
- NOTE: there is no way to indicate text or binary files. it is up
- to the SFTP client to deal with this.
- """
- data = NS(filename) + struct.pack('!L', flags) + self._packAttributes(attrs)
- d = self._sendRequest(FXP_OPEN, data)
- self.wasAFile[d] = (1, filename) # HACK
- return d
-
- def removeFile(self, filename):
- """
- Remove the given file.
-
- This method returns a Deferred that is called back when it succeeds.
-
- @param filename: the name of the file as a string.
- """
- return self._sendRequest(FXP_REMOVE, NS(filename))
-
- def renameFile(self, oldpath, newpath):
- """
- Rename the given file.
-
- This method returns a Deferred that is called back when it succeeds.
-
- @param oldpath: the current location of the file.
- @param newpath: the new file name.
- """
- return self._sendRequest(FXP_RENAME, NS(oldpath)+NS(newpath))
-
- def makeDirectory(self, path, attrs):
- """
- Make a directory.
-
- This method returns a Deferred that is called back when it is
- created.
-
- @param path: the name of the directory to create as a string.
-
- @param attrs: a dictionary of attributes to create the directory
- with. Its meaning is the same as the attrs in the openFile method.
- """
- return self._sendRequest(FXP_MKDIR, NS(path)+self._packAttributes(attrs))
-
- def removeDirectory(self, path):
- """
- Remove a directory (non-recursively)
-
- It is an error to remove a directory that has files or directories in
- it.
-
- This method returns a Deferred that is called back when it is removed.
-
- @param path: the directory to remove.
- """
- return self._sendRequest(FXP_RMDIR, NS(path))
-
- def openDirectory(self, path):
- """
- Open a directory for scanning.
-
- This method returns a Deferred that is called back with an iterable
- object that has a close() method.
-
- The close() method is called when the client is finished reading
- from the directory. At this point, the iterable will no longer
- be used.
-
- The iterable returns triples of the form (filename, longname, attrs)
- or a Deferred that returns the same. The sequence must support
- __getitem__, but otherwise may be any 'sequence-like' object.
-
- filename is the name of the file relative to the directory.
- logname is an expanded format of the filename. The recommended format
- is:
- -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
- 1234567890 123 12345678 12345678 12345678 123456789012
-
- The first line is sample output, the second is the length of the field.
- The fields are: permissions, link count, user owner, group owner,
- size in bytes, modification time.
-
- attrs is a dictionary in the format of the attrs argument to openFile.
-
- @param path: the directory to open.
- """
- d = self._sendRequest(FXP_OPENDIR, NS(path))
- self.wasAFile[d] = (0, path)
- return d
-
- def getAttrs(self, path, followLinks=0):
- """
- Return the attributes for the given path.
-
- This method returns a dictionary in the same format as the attrs
- argument to openFile or a Deferred that is called back with same.
-
- @param path: the path to return attributes for as a string.
- @param followLinks: a boolean. if it is True, follow symbolic links
- and return attributes for the real path at the base. if it is False,
- return attributes for the specified path.
- """
- if followLinks: m = FXP_STAT
- else: m = FXP_LSTAT
- return self._sendRequest(m, NS(path))
-
- def setAttrs(self, path, attrs):
- """
- Set the attributes for the path.
-
- This method returns when the attributes are set or a Deferred that is
- called back when they are.
-
- @param path: the path to set attributes for as a string.
- @param attrs: a dictionary in the same format as the attrs argument to
- openFile.
- """
- data = NS(path) + self._packAttributes(attrs)
- return self._sendRequest(FXP_SETSTAT, data)
-
- def readLink(self, path):
- """
- Find the root of a set of symbolic links.
-
- This method returns the target of the link, or a Deferred that
- returns the same.
-
- @param path: the path of the symlink to read.
- """
- d = self._sendRequest(FXP_READLINK, NS(path))
- return d.addCallback(self._cbRealPath)
-
- def makeLink(self, linkPath, targetPath):
- """
- Create a symbolic link.
-
- This method returns when the link is made, or a Deferred that
- returns the same.
-
- @param linkPath: the pathname of the symlink as a string
- @param targetPath: the path of the target of the link as a string.
- """
- return self._sendRequest(FXP_SYMLINK, NS(linkPath)+NS(targetPath))
-
- def realPath(self, path):
- """
- Convert any path to an absolute path.
-
- This method returns the absolute path as a string, or a Deferred
- that returns the same.
-
- @param path: the path to convert as a string.
- """
- d = self._sendRequest(FXP_REALPATH, NS(path))
- return d.addCallback(self._cbRealPath)
-
- def _cbRealPath(self, result):
- name, longname, attrs = result[0]
- return name
-
- def extendedRequest(self, request, data):
- """
- Make an extended request of the server.
-
- The method returns a Deferred that is called back with
- the result of the extended request.
-
- @param request: the name of the extended request to make.
- @param data: any other data that goes along with the request.
- """
- return self._sendRequest(FXP_EXTENDED, NS(request) + data)
-
- def packet_VERSION(self, data):
- version, = struct.unpack('!L', data[:4])
- data = data[4:]
- d = {}
- while data:
- k, data = getNS(data)
- v, data = getNS(data)
- d[k]=v
- self.version = version
- self.gotServerVersion(version, d)
-
- def packet_STATUS(self, data):
- d, data = self._parseRequest(data)
- code, = struct.unpack('!L', data[:4])
- data = data[4:]
- if len(data) >= 4:
- msg, data = getNS(data)
- if len(data) >= 4:
- lang, data = getNS(data)
- else:
- lang = ''
- else:
- msg = ''
- lang = ''
- if code == FX_OK:
- d.callback((msg, lang))
- elif code == FX_EOF:
- d.errback(EOFError(msg))
- elif code == FX_OP_UNSUPPORTED:
- d.errback(NotImplementedError(msg))
- else:
- d.errback(SFTPError(code, msg, lang))
-
- def packet_HANDLE(self, data):
- d, data = self._parseRequest(data)
- isFile, name = self.wasAFile.pop(d)
- if isFile:
- cb = ClientFile(self, getNS(data)[0])
- else:
- cb = ClientDirectory(self, getNS(data)[0])
- cb.name = name
- d.callback(cb)
-
- def packet_DATA(self, data):
- d, data = self._parseRequest(data)
- d.callback(getNS(data)[0])
-
- def packet_NAME(self, data):
- d, data = self._parseRequest(data)
- count, = struct.unpack('!L', data[:4])
- data = data[4:]
- files = []
- for i in range(count):
- filename, data = getNS(data)
- longname, data = getNS(data)
- attrs, data = self._parseAttributes(data)
- files.append((filename, longname, attrs))
- d.callback(files)
-
- def packet_ATTRS(self, data):
- d, data = self._parseRequest(data)
- d.callback(self._parseAttributes(data)[0])
-
- def packet_EXTENDED_REPLY(self, data):
- d, data = self._parseRequest(data)
- d.callback(data)
-
- def gotServerVersion(self, serverVersion, extData):
- """
- Called when the client sends their version info.
-
- @param otherVersion: an integer representing the version of the SFTP
- protocol they are claiming.
- @param extData: a dictionary of extended_name : extended_data items.
- These items are sent by the client to indicate additional features.
- """
-
-class ClientFile:
-
- interface.implements(ISFTPFile)
-
- def __init__(self, parent, handle):
- self.parent = parent
- self.handle = NS(handle)
-
- def close(self):
- return self.parent._sendRequest(FXP_CLOSE, self.handle)
-
- def readChunk(self, offset, length):
- data = self.handle + struct.pack("!QL", offset, length)
- return self.parent._sendRequest(FXP_READ, data)
-
- def writeChunk(self, offset, chunk):
- data = self.handle + struct.pack("!Q", offset) + NS(chunk)
- return self.parent._sendRequest(FXP_WRITE, data)
-
- def getAttrs(self):
- return self.parent._sendRequest(FXP_FSTAT, self.handle)
-
- def setAttrs(self, attrs):
- data = self.handle + self.parent._packAttributes(attrs)
- return self.parent._sendRequest(FXP_FSTAT, data)
-
-class ClientDirectory:
-
- def __init__(self, parent, handle):
- self.parent = parent
- self.handle = NS(handle)
- self.filesCache = []
-
- def read(self):
- d = self.parent._sendRequest(FXP_READDIR, self.handle)
- return d
-
- def close(self):
- return self.parent._sendRequest(FXP_CLOSE, self.handle)
-
- def __iter__(self):
- return self
-
- def next(self):
- if self.filesCache:
- return self.filesCache.pop(0)
- d = self.read()
- d.addCallback(self._cbReadDir)
- d.addErrback(self._ebReadDir)
- return d
-
- def _cbReadDir(self, names):
- self.filesCache = names[1:]
- return names[0]
-
- def _ebReadDir(self, reason):
- reason.trap(EOFError)
- def _():
- raise StopIteration
- self.next = _
- return reason
-
-
-class SFTPError(Exception):
-
- def __init__(self, errorCode, errorMessage, lang = ''):
- Exception.__init__(self)
- self.code = errorCode
- self._message = errorMessage
- self.lang = lang
-
-
- def message(self):
- """
- A string received over the network that explains the error to a human.
- """
- # Python 2.6 deprecates assigning to the 'message' attribute of an
- # exception. We define this read-only property here in order to
- # prevent the warning about deprecation while maintaining backwards
- # compatibility with object clients that rely on the 'message'
- # attribute being set correctly. See bug #3897.
- return self._message
- message = property(message)
-
-
- def __str__(self):
- return 'SFTPError %s: %s' % (self.code, self.message)
-
-FXP_INIT = 1
-FXP_VERSION = 2
-FXP_OPEN = 3
-FXP_CLOSE = 4
-FXP_READ = 5
-FXP_WRITE = 6
-FXP_LSTAT = 7
-FXP_FSTAT = 8
-FXP_SETSTAT = 9
-FXP_FSETSTAT = 10
-FXP_OPENDIR = 11
-FXP_READDIR = 12
-FXP_REMOVE = 13
-FXP_MKDIR = 14
-FXP_RMDIR = 15
-FXP_REALPATH = 16
-FXP_STAT = 17
-FXP_RENAME = 18
-FXP_READLINK = 19
-FXP_SYMLINK = 20
-FXP_STATUS = 101
-FXP_HANDLE = 102
-FXP_DATA = 103
-FXP_NAME = 104
-FXP_ATTRS = 105
-FXP_EXTENDED = 200
-FXP_EXTENDED_REPLY = 201
-
-FILEXFER_ATTR_SIZE = 0x00000001
-FILEXFER_ATTR_UIDGID = 0x00000002
-FILEXFER_ATTR_OWNERGROUP = FILEXFER_ATTR_UIDGID
-FILEXFER_ATTR_PERMISSIONS = 0x00000004
-FILEXFER_ATTR_ACMODTIME = 0x00000008
-FILEXFER_ATTR_EXTENDED = 0x80000000L
-
-FILEXFER_TYPE_REGULAR = 1
-FILEXFER_TYPE_DIRECTORY = 2
-FILEXFER_TYPE_SYMLINK = 3
-FILEXFER_TYPE_SPECIAL = 4
-FILEXFER_TYPE_UNKNOWN = 5
-
-FXF_READ = 0x00000001
-FXF_WRITE = 0x00000002
-FXF_APPEND = 0x00000004
-FXF_CREAT = 0x00000008
-FXF_TRUNC = 0x00000010
-FXF_EXCL = 0x00000020
-FXF_TEXT = 0x00000040
-
-FX_OK = 0
-FX_EOF = 1
-FX_NO_SUCH_FILE = 2
-FX_PERMISSION_DENIED = 3
-FX_FAILURE = 4
-FX_BAD_MESSAGE = 5
-FX_NO_CONNECTION = 6
-FX_CONNECTION_LOST = 7
-FX_OP_UNSUPPORTED = 8
-FX_FILE_ALREADY_EXISTS = 11
-# http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/ defines more
-# useful error codes, but so far OpenSSH doesn't implement them. We use them
-# internally for clarity, but for now define them all as FX_FAILURE to be
-# compatible with existing software.
-FX_NOT_A_DIRECTORY = FX_FAILURE
-FX_FILE_IS_A_DIRECTORY = FX_FAILURE
-
-
-# initialize FileTransferBase.packetTypes:
-g = globals()
-for name in g.keys():
- if name.startswith('FXP_'):
- value = g[name]
- FileTransferBase.packetTypes[value] = name[4:]
-del g, name, value
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py
deleted file mode 100755
index 753f9946..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-This module contains the implementation of the TCP forwarding, which allows
-clients and servers to forward arbitrary TCP data across the connection.
-
-Maintainer: Paul Swartz
-"""
-
-import struct
-
-from twisted.internet import protocol, reactor
-from twisted.python import log
-
-import common, channel
-
-class SSHListenForwardingFactory(protocol.Factory):
- def __init__(self, connection, hostport, klass):
- self.conn = connection
- self.hostport = hostport # tuple
- self.klass = klass
-
- def buildProtocol(self, addr):
- channel = self.klass(conn = self.conn)
- client = SSHForwardingClient(channel)
- channel.client = client
- addrTuple = (addr.host, addr.port)
- channelOpenData = packOpen_direct_tcpip(self.hostport, addrTuple)
- self.conn.openChannel(channel, channelOpenData)
- return client
-
-class SSHListenForwardingChannel(channel.SSHChannel):
-
- def channelOpen(self, specificData):
- log.msg('opened forwarding channel %s' % self.id)
- if len(self.client.buf)>1:
- b = self.client.buf[1:]
- self.write(b)
- self.client.buf = ''
-
- def openFailed(self, reason):
- self.closed()
-
- def dataReceived(self, data):
- self.client.transport.write(data)
-
- def eofReceived(self):
- self.client.transport.loseConnection()
-
- def closed(self):
- if hasattr(self, 'client'):
- log.msg('closing local forwarding channel %s' % self.id)
- self.client.transport.loseConnection()
- del self.client
-
-class SSHListenClientForwardingChannel(SSHListenForwardingChannel):
-
- name = 'direct-tcpip'
-
-class SSHListenServerForwardingChannel(SSHListenForwardingChannel):
-
- name = 'forwarded-tcpip'
-
-class SSHConnectForwardingChannel(channel.SSHChannel):
-
- def __init__(self, hostport, *args, **kw):
- channel.SSHChannel.__init__(self, *args, **kw)
- self.hostport = hostport
- self.client = None
- self.clientBuf = ''
-
- def channelOpen(self, specificData):
- cc = protocol.ClientCreator(reactor, SSHForwardingClient, self)
- log.msg("connecting to %s:%i" % self.hostport)
- cc.connectTCP(*self.hostport).addCallbacks(self._setClient, self._close)
-
- def _setClient(self, client):
- self.client = client
- log.msg("connected to %s:%i" % self.hostport)
- if self.clientBuf:
- self.client.transport.write(self.clientBuf)
- self.clientBuf = None
- if self.client.buf[1:]:
- self.write(self.client.buf[1:])
- self.client.buf = ''
-
- def _close(self, reason):
- log.msg("failed to connect: %s" % reason)
- self.loseConnection()
-
- def dataReceived(self, data):
- if self.client:
- self.client.transport.write(data)
- else:
- self.clientBuf += data
-
- def closed(self):
- if self.client:
- log.msg('closed remote forwarding channel %s' % self.id)
- if self.client.channel:
- self.loseConnection()
- self.client.transport.loseConnection()
- del self.client
-
-def openConnectForwardingClient(remoteWindow, remoteMaxPacket, data, avatar):
- remoteHP, origHP = unpackOpen_direct_tcpip(data)
- return SSHConnectForwardingChannel(remoteHP,
- remoteWindow=remoteWindow,
- remoteMaxPacket=remoteMaxPacket,
- avatar=avatar)
-
-class SSHForwardingClient(protocol.Protocol):
-
- def __init__(self, channel):
- self.channel = channel
- self.buf = '\000'
-
- def dataReceived(self, data):
- if self.buf:
- self.buf += data
- else:
- self.channel.write(data)
-
- def connectionLost(self, reason):
- if self.channel:
- self.channel.loseConnection()
- self.channel = None
-
-
-def packOpen_direct_tcpip((connHost, connPort), (origHost, origPort)):
- """Pack the data suitable for sending in a CHANNEL_OPEN packet.
- """
- conn = common.NS(connHost) + struct.pack('>L', connPort)
- orig = common.NS(origHost) + struct.pack('>L', origPort)
- return conn + orig
-
-packOpen_forwarded_tcpip = packOpen_direct_tcpip
-
-def unpackOpen_direct_tcpip(data):
- """Unpack the data to a usable format.
- """
- connHost, rest = common.getNS(data)
- connPort = int(struct.unpack('>L', rest[:4])[0])
- origHost, rest = common.getNS(rest[4:])
- origPort = int(struct.unpack('>L', rest[:4])[0])
- return (connHost, connPort), (origHost, origPort)
-
-unpackOpen_forwarded_tcpip = unpackOpen_direct_tcpip
-
-def packGlobal_tcpip_forward((host, port)):
- return common.NS(host) + struct.pack('>L', port)
-
-def unpackGlobal_tcpip_forward(data):
- host, rest = common.getNS(data)
- port = int(struct.unpack('>L', rest[:4])[0])
- return host, port
-
-"""This is how the data -> eof -> close stuff /should/ work.
-
-debug3: channel 1: waiting for connection
-debug1: channel 1: connected
-debug1: channel 1: read<=0 rfd 7 len 0
-debug1: channel 1: read failed
-debug1: channel 1: close_read
-debug1: channel 1: input open -> drain
-debug1: channel 1: ibuf empty
-debug1: channel 1: send eof
-debug1: channel 1: input drain -> closed
-debug1: channel 1: rcvd eof
-debug1: channel 1: output open -> drain
-debug1: channel 1: obuf empty
-debug1: channel 1: close_write
-debug1: channel 1: output drain -> closed
-debug1: channel 1: rcvd close
-debug3: channel 1: will not send data after close
-debug1: channel 1: send close
-debug1: channel 1: is dead
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py
deleted file mode 100755
index 1c223517..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py
+++ /dev/null
@@ -1,809 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_keys -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Handling of RSA and DSA keys.
-
-Maintainer: U{Paul Swartz}
-"""
-
-# base library imports
-import base64
-import itertools
-
-# external library imports
-from Crypto.Cipher import DES3, AES
-from Crypto.PublicKey import RSA, DSA
-from Crypto import Util
-from pyasn1.type import univ
-from pyasn1.codec.ber import decoder as berDecoder
-from pyasn1.codec.ber import encoder as berEncoder
-
-# twisted
-from twisted.python import randbytes
-from twisted.python.hashlib import md5, sha1
-
-# sibling imports
-from twisted.conch.ssh import common, sexpy
-
-
-class BadKeyError(Exception):
- """
- Raised when a key isn't what we expected from it.
-
- XXX: we really need to check for bad keys
- """
-
-
-class EncryptedKeyError(Exception):
- """
- Raised when an encrypted key is presented to fromString/fromFile without
- a password.
- """
-
-
-class Key(object):
- """
- An object representing a key. A key can be either a public or
- private key. A public key can verify a signature; a private key can
- create or verify a signature. To generate a string that can be stored
- on disk, use the toString method. If you have a private key, but want
- the string representation of the public key, use Key.public().toString().
-
- @ivar keyObject: The C{Crypto.PublicKey.pubkey.pubkey} object that
- operations are performed with.
- """
-
- def fromFile(Class, filename, type=None, passphrase=None):
- """
- Return a Key object corresponding to the data in filename. type
- and passphrase function as they do in fromString.
- """
- return Class.fromString(file(filename, 'rb').read(), type, passphrase)
- fromFile = classmethod(fromFile)
-
- def fromString(Class, data, type=None, passphrase=None):
- """
- Return a Key object corresponding to the string data.
- type is optionally the type of string, matching a _fromString_*
- method. Otherwise, the _guessStringType() classmethod will be used
- to guess a type. If the key is encrypted, passphrase is used as
- the decryption key.
-
- @type data: C{str}
- @type type: C{None}/C{str}
- @type passphrase: C{None}/C{str}
- @rtype: C{Key}
- """
- if type is None:
- type = Class._guessStringType(data)
- if type is None:
- raise BadKeyError('cannot guess the type of %r' % data)
- method = getattr(Class, '_fromString_%s' % type.upper(), None)
- if method is None:
- raise BadKeyError('no _fromString method for %s' % type)
- if method.func_code.co_argcount == 2: # no passphrase
- if passphrase:
- raise BadKeyError('key not encrypted')
- return method(data)
- else:
- return method(data, passphrase)
- fromString = classmethod(fromString)
-
- def _fromString_BLOB(Class, blob):
- """
- Return a public key object corresponding to this public key blob.
- The format of a RSA public key blob is::
- string 'ssh-rsa'
- integer e
- integer n
-
- The format of a DSA public key blob is::
- string 'ssh-dss'
- integer p
- integer q
- integer g
- integer y
-
- @type blob: C{str}
- @return: a C{Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if the key type (the first string) is unknown.
- """
- keyType, rest = common.getNS(blob)
- if keyType == 'ssh-rsa':
- e, n, rest = common.getMP(rest, 2)
- return Class(RSA.construct((n, e)))
- elif keyType == 'ssh-dss':
- p, q, g, y, rest = common.getMP(rest, 4)
- return Class(DSA.construct((y, g, p, q)))
- else:
- raise BadKeyError('unknown blob type: %s' % keyType)
- _fromString_BLOB = classmethod(_fromString_BLOB)
-
- def _fromString_PRIVATE_BLOB(Class, blob):
- """
- Return a private key object corresponding to this private key blob.
- The blob formats are as follows:
-
- RSA keys::
- string 'ssh-rsa'
- integer n
- integer e
- integer d
- integer u
- integer p
- integer q
-
- DSA keys::
- string 'ssh-dss'
- integer p
- integer q
- integer g
- integer y
- integer x
-
- @type blob: C{str}
- @return: a C{Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if the key type (the first string) is unknown.
- """
- keyType, rest = common.getNS(blob)
-
- if keyType == 'ssh-rsa':
- n, e, d, u, p, q, rest = common.getMP(rest, 6)
- rsakey = Class(RSA.construct((n, e, d, p, q, u)))
- return rsakey
- elif keyType == 'ssh-dss':
- p, q, g, y, x, rest = common.getMP(rest, 5)
- dsakey = Class(DSA.construct((y, g, p, q, x)))
- return dsakey
- else:
- raise BadKeyError('unknown blob type: %s' % keyType)
- _fromString_PRIVATE_BLOB = classmethod(_fromString_PRIVATE_BLOB)
-
- def _fromString_PUBLIC_OPENSSH(Class, data):
- """
- Return a public key object corresponding to this OpenSSH public key
- string. The format of an OpenSSH public key string is::
- <key type> <base64-encoded public key blob>
-
- @type data: C{str}
- @return: A {Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if the blob type is unknown.
- """
- blob = base64.decodestring(data.split()[1])
- return Class._fromString_BLOB(blob)
- _fromString_PUBLIC_OPENSSH = classmethod(_fromString_PUBLIC_OPENSSH)
-
- def _fromString_PRIVATE_OPENSSH(Class, data, passphrase):
- """
- Return a private key object corresponding to this OpenSSH private key
- string. If the key is encrypted, passphrase MUST be provided.
- Providing a passphrase for an unencrypted key is an error.
-
- The format of an OpenSSH private key string is::
- -----BEGIN <key type> PRIVATE KEY-----
- [Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-EDE3-CBC,<initialization value>]
- <base64-encoded ASN.1 structure>
- ------END <key type> PRIVATE KEY------
-
- The ASN.1 structure of a RSA key is::
- (0, n, e, d, p, q)
-
- The ASN.1 structure of a DSA key is::
- (0, p, q, g, y, x)
-
- @type data: C{str}
- @type passphrase: C{str}
- @return: a C{Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if
- * a passphrase is provided for an unencrypted key
- * a passphrase is not provided for an encrypted key
- * the ASN.1 encoding is incorrect
- """
- lines = data.strip().split('\n')
- kind = lines[0][11:14]
- if lines[1].startswith('Proc-Type: 4,ENCRYPTED'): # encrypted key
- try:
- _, cipher_iv_info = lines[2].split(' ', 1)
- cipher, ivdata = cipher_iv_info.rstrip().split(',', 1)
- except ValueError:
- raise BadKeyError('invalid DEK-info %r' % lines[2])
- if cipher == 'AES-128-CBC':
- CipherClass = AES
- keySize = 16
- if len(ivdata) != 32:
- raise BadKeyError('AES encrypted key with a bad IV')
- elif cipher == 'DES-EDE3-CBC':
- CipherClass = DES3
- keySize = 24
- if len(ivdata) != 16:
- raise BadKeyError('DES encrypted key with a bad IV')
- else:
- raise BadKeyError('unknown encryption type %r' % cipher)
- iv = ''.join([chr(int(ivdata[i:i + 2], 16))
- for i in range(0, len(ivdata), 2)])
- if not passphrase:
- raise EncryptedKeyError('encrypted key with no passphrase')
- ba = md5(passphrase + iv[:8]).digest()
- bb = md5(ba + passphrase + iv[:8]).digest()
- decKey = (ba + bb)[:keySize]
- b64Data = base64.decodestring(''.join(lines[3:-1]))
- keyData = CipherClass.new(decKey,
- CipherClass.MODE_CBC,
- iv).decrypt(b64Data)
- removeLen = ord(keyData[-1])
- keyData = keyData[:-removeLen]
- else:
- b64Data = ''.join(lines[1:-1])
- keyData = base64.decodestring(b64Data)
- try:
- decodedKey = berDecoder.decode(keyData)[0]
- except Exception:
- raise BadKeyError('something wrong with decode')
- if kind == 'RSA':
- if len(decodedKey) == 2: # alternate RSA key
- decodedKey = decodedKey[0]
- if len(decodedKey) < 6:
- raise BadKeyError('RSA key failed to decode properly')
- n, e, d, p, q = [long(value) for value in decodedKey[1:6]]
- if p > q: # make p smaller than q
- p, q = q, p
- return Class(RSA.construct((n, e, d, p, q)))
- elif kind == 'DSA':
- p, q, g, y, x = [long(value) for value in decodedKey[1: 6]]
- if len(decodedKey) < 6:
- raise BadKeyError('DSA key failed to decode properly')
- return Class(DSA.construct((y, g, p, q, x)))
- _fromString_PRIVATE_OPENSSH = classmethod(_fromString_PRIVATE_OPENSSH)
-
- def _fromString_PUBLIC_LSH(Class, data):
- """
- Return a public key corresponding to this LSH public key string.
- The LSH public key string format is::
- <s-expression: ('public-key', (<key type>, (<name, <value>)+))>
-
- The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e.
- The names for a DSA (key type 'dsa') key are: y, g, p, q.
-
- @type data: C{str}
- @return: a C{Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if the key type is unknown
- """
- sexp = sexpy.parse(base64.decodestring(data[1:-1]))
- assert sexp[0] == 'public-key'
- kd = {}
- for name, data in sexp[1][1:]:
- kd[name] = common.getMP(common.NS(data))[0]
- if sexp[1][0] == 'dsa':
- return Class(DSA.construct((kd['y'], kd['g'], kd['p'], kd['q'])))
- elif sexp[1][0] == 'rsa-pkcs1-sha1':
- return Class(RSA.construct((kd['n'], kd['e'])))
- else:
- raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
- _fromString_PUBLIC_LSH = classmethod(_fromString_PUBLIC_LSH)
-
- def _fromString_PRIVATE_LSH(Class, data):
- """
- Return a private key corresponding to this LSH private key string.
- The LSH private key string format is::
- <s-expression: ('private-key', (<key type>, (<name>, <value>)+))>
-
- The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e, d, p, q.
- The names for a DSA (key type 'dsa') key are: y, g, p, q, x.
-
- @type data: C{str}
- @return: a {Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if the key type is unknown
- """
- sexp = sexpy.parse(data)
- assert sexp[0] == 'private-key'
- kd = {}
- for name, data in sexp[1][1:]:
- kd[name] = common.getMP(common.NS(data))[0]
- if sexp[1][0] == 'dsa':
- assert len(kd) == 5, len(kd)
- return Class(DSA.construct((kd['y'], kd['g'], kd['p'],
- kd['q'], kd['x'])))
- elif sexp[1][0] == 'rsa-pkcs1':
- assert len(kd) == 8, len(kd)
- if kd['p'] > kd['q']: # make p smaller than q
- kd['p'], kd['q'] = kd['q'], kd['p']
- return Class(RSA.construct((kd['n'], kd['e'], kd['d'],
- kd['p'], kd['q'])))
- else:
- raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
- _fromString_PRIVATE_LSH = classmethod(_fromString_PRIVATE_LSH)
-
- def _fromString_AGENTV3(Class, data):
- """
- Return a private key object corresponsing to the Secure Shell Key
- Agent v3 format.
-
- The SSH Key Agent v3 format for a RSA key is::
- string 'ssh-rsa'
- integer e
- integer d
- integer n
- integer u
- integer p
- integer q
-
- The SSH Key Agent v3 format for a DSA key is::
- string 'ssh-dss'
- integer p
- integer q
- integer g
- integer y
- integer x
-
- @type data: C{str}
- @return: a C{Crypto.PublicKey.pubkey.pubkey} object
- @raises BadKeyError: if the key type (the first string) is unknown
- """
- keyType, data = common.getNS(data)
- if keyType == 'ssh-dss':
- p, data = common.getMP(data)
- q, data = common.getMP(data)
- g, data = common.getMP(data)
- y, data = common.getMP(data)
- x, data = common.getMP(data)
- return Class(DSA.construct((y, g, p, q, x)))
- elif keyType == 'ssh-rsa':
- e, data = common.getMP(data)
- d, data = common.getMP(data)
- n, data = common.getMP(data)
- u, data = common.getMP(data)
- p, data = common.getMP(data)
- q, data = common.getMP(data)
- return Class(RSA.construct((n, e, d, p, q, u)))
- else:
- raise BadKeyError("unknown key type %s" % keyType)
- _fromString_AGENTV3 = classmethod(_fromString_AGENTV3)
-
- def _guessStringType(Class, data):
- """
- Guess the type of key in data. The types map to _fromString_*
- methods.
- """
- if data.startswith('ssh-'):
- return 'public_openssh'
- elif data.startswith('-----BEGIN'):
- return 'private_openssh'
- elif data.startswith('{'):
- return 'public_lsh'
- elif data.startswith('('):
- return 'private_lsh'
- elif data.startswith('\x00\x00\x00\x07ssh-'):
- ignored, rest = common.getNS(data)
- count = 0
- while rest:
- count += 1
- ignored, rest = common.getMP(rest)
- if count > 4:
- return 'agentv3'
- else:
- return 'blob'
- _guessStringType = classmethod(_guessStringType)
-
- def __init__(self, keyObject):
- """
- Initialize a PublicKey with a C{Crypto.PublicKey.pubkey.pubkey}
- object.
-
- @type keyObject: C{Crypto.PublicKey.pubkey.pubkey}
- """
- self.keyObject = keyObject
-
- def __eq__(self, other):
- """
- Return True if other represents an object with the same key.
- """
- if type(self) == type(other):
- return self.type() == other.type() and self.data() == other.data()
- else:
- return NotImplemented
-
- def __ne__(self, other):
- """
- Return True if other represents anything other than this key.
- """
- result = self.__eq__(other)
- if result == NotImplemented:
- return result
- return not result
-
- def __repr__(self):
- """
- Return a pretty representation of this object.
- """
- lines = [
- '<%s %s (%s bits)' % (
- self.type(),
- self.isPublic() and 'Public Key' or 'Private Key',
- self.keyObject.size())]
- for k, v in sorted(self.data().items()):
- lines.append('attr %s:' % k)
- by = common.MP(v)[4:]
- while by:
- m = by[:15]
- by = by[15:]
- o = ''
- for c in m:
- o = o + '%02x:' % ord(c)
- if len(m) < 15:
- o = o[:-1]
- lines.append('\t' + o)
- lines[-1] = lines[-1] + '>'
- return '\n'.join(lines)
-
- def isPublic(self):
- """
- Returns True if this Key is a public key.
- """
- return not self.keyObject.has_private()
-
- def public(self):
- """
- Returns a version of this key containing only the public key data.
- If this is a public key, this may or may not be the same object
- as self.
- """
- return Key(self.keyObject.publickey())
-
- def fingerprint(self):
- """
- Get the user presentation of the fingerprint of this L{Key}. As
- described by U{RFC 4716 section
- 4<http://tools.ietf.org/html/rfc4716#section-4>}::
-
- The fingerprint of a public key consists of the output of the MD5
- message-digest algorithm [RFC1321]. The input to the algorithm is
- the public key data as specified by [RFC4253]. (...) The output
- of the (MD5) algorithm is presented to the user as a sequence of 16
- octets printed as hexadecimal with lowercase letters and separated
- by colons.
-
- @since: 8.2
-
- @return: the user presentation of this L{Key}'s fingerprint, as a
- string.
-
- @rtype: L{str}
- """
- return ':'.join([x.encode('hex') for x in md5(self.blob()).digest()])
-
- def type(self):
- """
- Return the type of the object we wrap. Currently this can only be
- 'RSA' or 'DSA'.
- """
- # the class is Crypto.PublicKey.<type>.<stuff we don't care about>
- mod = self.keyObject.__class__.__module__
- if mod.startswith('Crypto.PublicKey'):
- type = mod.split('.')[2]
- else:
- raise RuntimeError('unknown type of object: %r' % self.keyObject)
- if type in ('RSA', 'DSA'):
- return type
- else:
- raise RuntimeError('unknown type of key: %s' % type)
-
- def sshType(self):
- """
- Return the type of the object we wrap as defined in the ssh protocol.
- Currently this can only be 'ssh-rsa' or 'ssh-dss'.
- """
- return {'RSA': 'ssh-rsa', 'DSA': 'ssh-dss'}[self.type()]
-
- def data(self):
- """
- Return the values of the public key as a dictionary.
-
- @rtype: C{dict}
- """
- keyData = {}
- for name in self.keyObject.keydata:
- value = getattr(self.keyObject, name, None)
- if value is not None:
- keyData[name] = value
- return keyData
-
- def blob(self):
- """
- Return the public key blob for this key. The blob is the
- over-the-wire format for public keys:
-
- RSA keys::
- string 'ssh-rsa'
- integer e
- integer n
-
- DSA keys::
- string 'ssh-dss'
- integer p
- integer q
- integer g
- integer y
-
- @rtype: C{str}
- """
- type = self.type()
- data = self.data()
- if type == 'RSA':
- return (common.NS('ssh-rsa') + common.MP(data['e']) +
- common.MP(data['n']))
- elif type == 'DSA':
- return (common.NS('ssh-dss') + common.MP(data['p']) +
- common.MP(data['q']) + common.MP(data['g']) +
- common.MP(data['y']))
-
- def privateBlob(self):
- """
- Return the private key blob for this key. The blob is the
- over-the-wire format for private keys:
-
- RSA keys::
- string 'ssh-rsa'
- integer n
- integer e
- integer d
- integer u
- integer p
- integer q
-
- DSA keys::
- string 'ssh-dss'
- integer p
- integer q
- integer g
- integer y
- integer x
- """
- type = self.type()
- data = self.data()
- if type == 'RSA':
- return (common.NS('ssh-rsa') + common.MP(data['n']) +
- common.MP(data['e']) + common.MP(data['d']) +
- common.MP(data['u']) + common.MP(data['p']) +
- common.MP(data['q']))
- elif type == 'DSA':
- return (common.NS('ssh-dss') + common.MP(data['p']) +
- common.MP(data['q']) + common.MP(data['g']) +
- common.MP(data['y']) + common.MP(data['x']))
-
- def toString(self, type, extra=None):
- """
- Create a string representation of this key. If the key is a private
- key and you want the represenation of its public key, use
- C{key.public().toString()}. type maps to a _toString_* method.
-
- @param type: The type of string to emit. Currently supported values
- are C{'OPENSSH'}, C{'LSH'}, and C{'AGENTV3'}.
- @type type: L{str}
-
- @param extra: Any extra data supported by the selected format which
- is not part of the key itself. For public OpenSSH keys, this is
- a comment. For private OpenSSH keys, this is a passphrase to
- encrypt with.
- @type extra: L{str} or L{NoneType}
-
- @rtype: L{str}
- """
- method = getattr(self, '_toString_%s' % type.upper(), None)
- if method is None:
- raise BadKeyError('unknown type: %s' % type)
- if method.func_code.co_argcount == 2:
- return method(extra)
- else:
- return method()
-
- def _toString_OPENSSH(self, extra):
- """
- Return a public or private OpenSSH string. See
- _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the
- string formats. If extra is present, it represents a comment for a
- public key, or a passphrase for a private key.
-
- @type extra: C{str}
- @rtype: C{str}
- """
- data = self.data()
- if self.isPublic():
- b64Data = base64.encodestring(self.blob()).replace('\n', '')
- if not extra:
- extra = ''
- return ('%s %s %s' % (self.sshType(), b64Data, extra)).strip()
- else:
- lines = ['-----BEGIN %s PRIVATE KEY-----' % self.type()]
- if self.type() == 'RSA':
- p, q = data['p'], data['q']
- objData = (0, data['n'], data['e'], data['d'], q, p,
- data['d'] % (q - 1), data['d'] % (p - 1),
- data['u'])
- else:
- objData = (0, data['p'], data['q'], data['g'], data['y'],
- data['x'])
- asn1Sequence = univ.Sequence()
- for index, value in itertools.izip(itertools.count(), objData):
- asn1Sequence.setComponentByPosition(index, univ.Integer(value))
- asn1Data = berEncoder.encode(asn1Sequence)
- if extra:
- iv = randbytes.secureRandom(8)
- hexiv = ''.join(['%02X' % ord(x) for x in iv])
- lines.append('Proc-Type: 4,ENCRYPTED')
- lines.append('DEK-Info: DES-EDE3-CBC,%s\n' % hexiv)
- ba = md5(extra + iv).digest()
- bb = md5(ba + extra + iv).digest()
- encKey = (ba + bb)[:24]
- padLen = 8 - (len(asn1Data) % 8)
- asn1Data += (chr(padLen) * padLen)
- asn1Data = DES3.new(encKey, DES3.MODE_CBC,
- iv).encrypt(asn1Data)
- b64Data = base64.encodestring(asn1Data).replace('\n', '')
- lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)]
- lines.append('-----END %s PRIVATE KEY-----' % self.type())
- return '\n'.join(lines)
-
- def _toString_LSH(self):
- """
- Return a public or private LSH key. See _fromString_PUBLIC_LSH and
- _fromString_PRIVATE_LSH for the key formats.
-
- @rtype: C{str}
- """
- data = self.data()
- if self.isPublic():
- if self.type() == 'RSA':
- keyData = sexpy.pack([['public-key',
- ['rsa-pkcs1-sha1',
- ['n', common.MP(data['n'])[4:]],
- ['e', common.MP(data['e'])[4:]]]]])
- elif self.type() == 'DSA':
- keyData = sexpy.pack([['public-key',
- ['dsa',
- ['p', common.MP(data['p'])[4:]],
- ['q', common.MP(data['q'])[4:]],
- ['g', common.MP(data['g'])[4:]],
- ['y', common.MP(data['y'])[4:]]]]])
- return '{' + base64.encodestring(keyData).replace('\n', '') + '}'
- else:
- if self.type() == 'RSA':
- p, q = data['p'], data['q']
- return sexpy.pack([['private-key',
- ['rsa-pkcs1',
- ['n', common.MP(data['n'])[4:]],
- ['e', common.MP(data['e'])[4:]],
- ['d', common.MP(data['d'])[4:]],
- ['p', common.MP(q)[4:]],
- ['q', common.MP(p)[4:]],
- ['a', common.MP(data['d'] % (q - 1))[4:]],
- ['b', common.MP(data['d'] % (p - 1))[4:]],
- ['c', common.MP(data['u'])[4:]]]]])
- elif self.type() == 'DSA':
- return sexpy.pack([['private-key',
- ['dsa',
- ['p', common.MP(data['p'])[4:]],
- ['q', common.MP(data['q'])[4:]],
- ['g', common.MP(data['g'])[4:]],
- ['y', common.MP(data['y'])[4:]],
- ['x', common.MP(data['x'])[4:]]]]])
-
- def _toString_AGENTV3(self):
- """
- Return a private Secure Shell Agent v3 key. See
- _fromString_AGENTV3 for the key format.
-
- @rtype: C{str}
- """
- data = self.data()
- if not self.isPublic():
- if self.type() == 'RSA':
- values = (data['e'], data['d'], data['n'], data['u'],
- data['p'], data['q'])
- elif self.type() == 'DSA':
- values = (data['p'], data['q'], data['g'], data['y'],
- data['x'])
- return common.NS(self.sshType()) + ''.join(map(common.MP, values))
-
- def sign(self, data):
- """
- Returns a signature with this Key.
-
- @type data: C{str}
- @rtype: C{str}
- """
- if self.type() == 'RSA':
- digest = pkcs1Digest(data, self.keyObject.size() / 8)
- signature = self.keyObject.sign(digest, '')[0]
- ret = common.NS(Util.number.long_to_bytes(signature))
- elif self.type() == 'DSA':
- digest = sha1(data).digest()
- randomBytes = randbytes.secureRandom(19)
- sig = self.keyObject.sign(digest, randomBytes)
- # SSH insists that the DSS signature blob be two 160-bit integers
- # concatenated together. The sig[0], [1] numbers from obj.sign
- # are just numbers, and could be any length from 0 to 160 bits.
- # Make sure they are padded out to 160 bits (20 bytes each)
- ret = common.NS(Util.number.long_to_bytes(sig[0], 20) +
- Util.number.long_to_bytes(sig[1], 20))
- return common.NS(self.sshType()) + ret
-
- def verify(self, signature, data):
- """
- Returns true if the signature for data is valid for this Key.
-
- @type signature: C{str}
- @type data: C{str}
- @rtype: C{bool}
- """
- if len(signature) == 40:
- # DSA key with no padding
- signatureType, signature = 'ssh-dss', common.NS(signature)
- else:
- signatureType, signature = common.getNS(signature)
- if signatureType != self.sshType():
- return False
- if self.type() == 'RSA':
- numbers = common.getMP(signature)
- digest = pkcs1Digest(data, self.keyObject.size() / 8)
- elif self.type() == 'DSA':
- signature = common.getNS(signature)[0]
- numbers = [Util.number.bytes_to_long(n) for n in signature[:20],
- signature[20:]]
- digest = sha1(data).digest()
- return self.keyObject.verify(digest, numbers)
-
-
-def objectType(obj):
- """
- Return the SSH key type corresponding to a
- C{Crypto.PublicKey.pubkey.pubkey} object.
-
- @type obj: C{Crypto.PublicKey.pubkey.pubkey}
- @rtype: C{str}
- """
- keyDataMapping = {
- ('n', 'e', 'd', 'p', 'q'): 'ssh-rsa',
- ('n', 'e', 'd', 'p', 'q', 'u'): 'ssh-rsa',
- ('y', 'g', 'p', 'q', 'x'): 'ssh-dss'
- }
- try:
- return keyDataMapping[tuple(obj.keydata)]
- except (KeyError, AttributeError):
- raise BadKeyError("invalid key object", obj)
-
-
-def pkcs1Pad(data, messageLength):
- """
- Pad out data to messageLength according to the PKCS#1 standard.
- @type data: C{str}
- @type messageLength: C{int}
- """
- lenPad = messageLength - 2 - len(data)
- return '\x01' + ('\xff' * lenPad) + '\x00' + data
-
-
-def pkcs1Digest(data, messageLength):
- """
- Create a message digest using the SHA1 hash algorithm according to the
- PKCS#1 standard.
- @type data: C{str}
- @type messageLength: C{str}
- """
- digest = sha1(data).digest()
- return pkcs1Pad(ID_SHA1 + digest, messageLength)
-
-
-def lenSig(obj):
- """
- Return the length of the signature in bytes for a key object.
-
- @type obj: C{Crypto.PublicKey.pubkey.pubkey}
- @rtype: C{long}
- """
- return obj.size() / 8
-
-
-ID_SHA1 = '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py
deleted file mode 100755
index b5477c4f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The parent class for all the SSH services. Currently implemented services
-are ssh-userauth and ssh-connection.
-
-Maintainer: Paul Swartz
-"""
-
-
-from twisted.python import log
-
-class SSHService(log.Logger):
- name = None # this is the ssh name for the service
- protocolMessages = {} # these map #'s -> protocol names
- transport = None # gets set later
-
- def serviceStarted(self):
- """
- called when the service is active on the transport.
- """
-
- def serviceStopped(self):
- """
- called when the service is stopped, either by the connection ending
- or by another service being started
- """
-
- def logPrefix(self):
- return "SSHService %s on %s" % (self.name,
- self.transport.transport.logPrefix())
-
- def packetReceived(self, messageNum, packet):
- """
- called when we receive a packet on the transport
- """
- #print self.protocolMessages
- if messageNum in self.protocolMessages:
- messageType = self.protocolMessages[messageNum]
- f = getattr(self,'ssh_%s' % messageType[4:],
- None)
- if f is not None:
- return f(packet)
- log.msg("couldn't handle %r" % messageNum)
- log.msg(repr(packet))
- self.transport.sendUnimplemented()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py
deleted file mode 100755
index e9eca3eb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_session -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module contains the implementation of SSHSession, which (by default)
-allows access to a shell and a python interpreter over SSH.
-
-Maintainer: Paul Swartz
-"""
-
-import struct
-import signal
-import sys
-import os
-from zope.interface import implements
-
-from twisted.internet import interfaces, protocol
-from twisted.python import log
-from twisted.conch.interfaces import ISession
-from twisted.conch.ssh import common, channel
-
-class SSHSession(channel.SSHChannel):
-
- name = 'session'
- def __init__(self, *args, **kw):
- channel.SSHChannel.__init__(self, *args, **kw)
- self.buf = ''
- self.client = None
- self.session = None
-
- def request_subsystem(self, data):
- subsystem, ignored= common.getNS(data)
- log.msg('asking for subsystem "%s"' % subsystem)
- client = self.avatar.lookupSubsystem(subsystem, data)
- if client:
- pp = SSHSessionProcessProtocol(self)
- proto = wrapProcessProtocol(pp)
- client.makeConnection(proto)
- pp.makeConnection(wrapProtocol(client))
- self.client = pp
- return 1
- else:
- log.msg('failed to get subsystem')
- return 0
-
- def request_shell(self, data):
- log.msg('getting shell')
- if not self.session:
- self.session = ISession(self.avatar)
- try:
- pp = SSHSessionProcessProtocol(self)
- self.session.openShell(pp)
- except:
- log.deferr()
- return 0
- else:
- self.client = pp
- return 1
-
- def request_exec(self, data):
- if not self.session:
- self.session = ISession(self.avatar)
- f,data = common.getNS(data)
- log.msg('executing command "%s"' % f)
- try:
- pp = SSHSessionProcessProtocol(self)
- self.session.execCommand(pp, f)
- except:
- log.deferr()
- return 0
- else:
- self.client = pp
- return 1
-
- def request_pty_req(self, data):
- if not self.session:
- self.session = ISession(self.avatar)
- term, windowSize, modes = parseRequest_pty_req(data)
- log.msg('pty request: %s %s' % (term, windowSize))
- try:
- self.session.getPty(term, windowSize, modes)
- except:
- log.err()
- return 0
- else:
- return 1
-
- def request_window_change(self, data):
- if not self.session:
- self.session = ISession(self.avatar)
- winSize = parseRequest_window_change(data)
- try:
- self.session.windowChanged(winSize)
- except:
- log.msg('error changing window size')
- log.err()
- return 0
- else:
- return 1
-
- def dataReceived(self, data):
- if not self.client:
- #self.conn.sendClose(self)
- self.buf += data
- return
- self.client.transport.write(data)
-
- def extReceived(self, dataType, data):
- if dataType == connection.EXTENDED_DATA_STDERR:
- if self.client and hasattr(self.client.transport, 'writeErr'):
- self.client.transport.writeErr(data)
- else:
- log.msg('weird extended data: %s'%dataType)
-
- def eofReceived(self):
- if self.session:
- self.session.eofReceived()
- elif self.client:
- self.conn.sendClose(self)
-
- def closed(self):
- if self.session:
- self.session.closed()
- elif self.client:
- self.client.transport.loseConnection()
-
- #def closeReceived(self):
- # self.loseConnection() # don't know what to do with this
-
- def loseConnection(self):
- if self.client:
- self.client.transport.loseConnection()
- channel.SSHChannel.loseConnection(self)
-
-class _ProtocolWrapper(protocol.ProcessProtocol):
- """
- This class wraps a L{Protocol} instance in a L{ProcessProtocol} instance.
- """
- def __init__(self, proto):
- self.proto = proto
-
- def connectionMade(self): self.proto.connectionMade()
-
- def outReceived(self, data): self.proto.dataReceived(data)
-
- def processEnded(self, reason): self.proto.connectionLost(reason)
-
-class _DummyTransport:
-
- def __init__(self, proto):
- self.proto = proto
-
- def dataReceived(self, data):
- self.proto.transport.write(data)
-
- def write(self, data):
- self.proto.dataReceived(data)
-
- def writeSequence(self, seq):
- self.write(''.join(seq))
-
- def loseConnection(self):
- self.proto.connectionLost(protocol.connectionDone)
-
-def wrapProcessProtocol(inst):
- if isinstance(inst, protocol.Protocol):
- return _ProtocolWrapper(inst)
- else:
- return inst
-
-def wrapProtocol(proto):
- return _DummyTransport(proto)
-
-
-
-# SUPPORTED_SIGNALS is a list of signals that every session channel is supposed
-# to accept. See RFC 4254
-SUPPORTED_SIGNALS = ["ABRT", "ALRM", "FPE", "HUP", "ILL", "INT", "KILL",
- "PIPE", "QUIT", "SEGV", "TERM", "USR1", "USR2"]
-
-
-
-class SSHSessionProcessProtocol(protocol.ProcessProtocol):
- """I am both an L{IProcessProtocol} and an L{ITransport}.
-
- I am a transport to the remote endpoint and a process protocol to the
- local subsystem.
- """
-
- implements(interfaces.ITransport)
-
- # once initialized, a dictionary mapping signal values to strings
- # that follow RFC 4254.
- _signalValuesToNames = None
-
- def __init__(self, session):
- self.session = session
- self.lostOutOrErrFlag = False
-
- def connectionMade(self):
- if self.session.buf:
- self.transport.write(self.session.buf)
- self.session.buf = None
-
- def outReceived(self, data):
- self.session.write(data)
-
- def errReceived(self, err):
- self.session.writeExtended(connection.EXTENDED_DATA_STDERR, err)
-
- def outConnectionLost(self):
- """
- EOF should only be sent when both STDOUT and STDERR have been closed.
- """
- if self.lostOutOrErrFlag:
- self.session.conn.sendEOF(self.session)
- else:
- self.lostOutOrErrFlag = True
-
- def errConnectionLost(self):
- """
- See outConnectionLost().
- """
- self.outConnectionLost()
-
- def connectionLost(self, reason = None):
- self.session.loseConnection()
-
-
- def _getSignalName(self, signum):
- """
- Get a signal name given a signal number.
- """
- if self._signalValuesToNames is None:
- self._signalValuesToNames = {}
- # make sure that the POSIX ones are the defaults
- for signame in SUPPORTED_SIGNALS:
- signame = 'SIG' + signame
- sigvalue = getattr(signal, signame, None)
- if sigvalue is not None:
- self._signalValuesToNames[sigvalue] = signame
- for k, v in signal.__dict__.items():
- # Check for platform specific signals, ignoring Python specific
- # SIG_DFL and SIG_IGN
- if k.startswith('SIG') and not k.startswith('SIG_'):
- if v not in self._signalValuesToNames:
- self._signalValuesToNames[v] = k + '@' + sys.platform
- return self._signalValuesToNames[signum]
-
-
- def processEnded(self, reason=None):
- """
- When we are told the process ended, try to notify the other side about
- how the process ended using the exit-signal or exit-status requests.
- Also, close the channel.
- """
- if reason is not None:
- err = reason.value
- if err.signal is not None:
- signame = self._getSignalName(err.signal)
- if (getattr(os, 'WCOREDUMP', None) is not None and
- os.WCOREDUMP(err.status)):
- log.msg('exitSignal: %s (core dumped)' % (signame,))
- coreDumped = 1
- else:
- log.msg('exitSignal: %s' % (signame,))
- coreDumped = 0
- self.session.conn.sendRequest(self.session, 'exit-signal',
- common.NS(signame[3:]) + chr(coreDumped) +
- common.NS('') + common.NS(''))
- elif err.exitCode is not None:
- log.msg('exitCode: %r' % (err.exitCode,))
- self.session.conn.sendRequest(self.session, 'exit-status',
- struct.pack('>L', err.exitCode))
- self.session.loseConnection()
-
-
- def getHost(self):
- """
- Return the host from my session's transport.
- """
- return self.session.conn.transport.getHost()
-
-
- def getPeer(self):
- """
- Return the peer from my session's transport.
- """
- return self.session.conn.transport.getPeer()
-
-
- def write(self, data):
- self.session.write(data)
-
-
- def writeSequence(self, seq):
- self.session.write(''.join(seq))
-
-
- def loseConnection(self):
- self.session.loseConnection()
-
-
-
-class SSHSessionClient(protocol.Protocol):
-
- def dataReceived(self, data):
- if self.transport:
- self.transport.write(data)
-
-# methods factored out to make live easier on server writers
-def parseRequest_pty_req(data):
- """Parse the data from a pty-req request into usable data.
-
- @returns: a tuple of (terminal type, (rows, cols, xpixel, ypixel), modes)
- """
- term, rest = common.getNS(data)
- cols, rows, xpixel, ypixel = struct.unpack('>4L', rest[: 16])
- modes, ignored= common.getNS(rest[16:])
- winSize = (rows, cols, xpixel, ypixel)
- modes = [(ord(modes[i]), struct.unpack('>L', modes[i+1: i+5])[0]) for i in range(0, len(modes)-1, 5)]
- return term, winSize, modes
-
-def packRequest_pty_req(term, (rows, cols, xpixel, ypixel), modes):
- """Pack a pty-req request so that it is suitable for sending.
-
- NOTE: modes must be packed before being sent here.
- """
- termPacked = common.NS(term)
- winSizePacked = struct.pack('>4L', cols, rows, xpixel, ypixel)
- modesPacked = common.NS(modes) # depend on the client packing modes
- return termPacked + winSizePacked + modesPacked
-
-def parseRequest_window_change(data):
- """Parse the data from a window-change request into usuable data.
-
- @returns: a tuple of (rows, cols, xpixel, ypixel)
- """
- cols, rows, xpixel, ypixel = struct.unpack('>4L', data)
- return rows, cols, xpixel, ypixel
-
-def packRequest_window_change((rows, cols, xpixel, ypixel)):
- """Pack a window-change request so that it is suitable for sending.
- """
- return struct.pack('>4L', cols, rows, xpixel, ypixel)
-
-import connection
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py
deleted file mode 100755
index 60c43289..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-def parse(s):
- s = s.strip()
- expr = []
- while s:
- if s[0] == '(':
- newSexp = []
- if expr:
- expr[-1].append(newSexp)
- expr.append(newSexp)
- s = s[1:]
- continue
- if s[0] == ')':
- aList = expr.pop()
- s=s[1:]
- if not expr:
- assert not s
- return aList
- continue
- i = 0
- while s[i].isdigit(): i+=1
- assert i
- length = int(s[:i])
- data = s[i+1:i+1+length]
- expr[-1].append(data)
- s=s[i+1+length:]
- assert 0, "this should not happen"
-
-def pack(sexp):
- s = ""
- for o in sexp:
- if type(o) in (type(()), type([])):
- s+='('
- s+=pack(o)
- s+=')'
- else:
- s+='%i:%s' % (len(o), o)
- return s
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py
deleted file mode 100755
index 9e0c753f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py
+++ /dev/null
@@ -1,1617 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_transport -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The lowest level SSH protocol. This handles the key negotiation, the
-encryption and the compression. The transport layer is described in
-RFC 4253.
-
-Maintainer: Paul Swartz
-"""
-
-# base library imports
-import struct
-import zlib
-import array
-
-# external library imports
-from Crypto import Util
-from Crypto.Cipher import XOR
-
-# twisted imports
-from twisted.internet import protocol, defer
-
-from twisted.conch import error
-from twisted.python import log, randbytes
-from twisted.python.hashlib import md5, sha1
-
-
-# sibling imports
-from twisted.conch.ssh import address, keys
-from twisted.conch.ssh.common import NS, getNS, MP, getMP, _MPpow, ffs
-
-
-def _getRandomNumber(random, bits):
- """
- Generate a random number in the range [0, 2 ** bits).
-
- @param bits: The number of bits in the result.
- @type bits: C{int}
-
- @rtype: C{int} or C{long}
- @return: The newly generated random number.
-
- @raise ValueError: if C{bits} is not a multiple of 8.
- """
- if bits % 8:
- raise ValueError("bits (%d) must be a multiple of 8" % (bits,))
- bytes = random(bits / 8)
- result = Util.number.bytes_to_long(bytes)
- return result
-
-
-
-def _generateX(random, bits):
- """
- Generate a new value for the private key x.
-
- From RFC 2631, section 2.2::
-
- X9.42 requires that the private key x be in the interval
- [2, (q - 2)]. x should be randomly generated in this interval.
- """
- while True:
- x = _getRandomNumber(random, bits)
- if 2 <= x <= (2 ** bits) - 2:
- return x
-
-class SSHTransportBase(protocol.Protocol):
- """
- Protocol supporting basic SSH functionality: sending/receiving packets
- and message dispatch. To connect to or run a server, you must use
- SSHClientTransport or SSHServerTransport.
-
- @ivar protocolVersion: A string representing the version of the SSH
- protocol we support. Currently defaults to '2.0'.
-
- @ivar version: A string representing the version of the server or client.
- Currently defaults to 'Twisted'.
-
- @ivar comment: An optional string giving more information about the
- server or client.
-
- @ivar supportedCiphers: A list of strings representing the encryption
- algorithms supported, in order from most-preferred to least.
-
- @ivar supportedMACs: A list of strings representing the message
- authentication codes (hashes) supported, in order from most-preferred
- to least. Both this and supportedCiphers can include 'none' to use
- no encryption or authentication, but that must be done manually,
-
- @ivar supportedKeyExchanges: A list of strings representing the
- key exchanges supported, in order from most-preferred to least.
-
- @ivar supportedPublicKeys: A list of strings representing the
- public key types supported, in order from most-preferred to least.
-
- @ivar supportedCompressions: A list of strings representing compression
- types supported, from most-preferred to least.
-
- @ivar supportedLanguages: A list of strings representing languages
- supported, from most-preferred to least.
-
- @ivar supportedVersions: A container of strings representing supported ssh
- protocol version numbers.
-
- @ivar isClient: A boolean indicating whether this is a client or server.
-
- @ivar gotVersion: A boolean indicating whether we have receieved the
- version string from the other side.
-
- @ivar buf: Data we've received but hasn't been parsed into a packet.
-
- @ivar outgoingPacketSequence: the sequence number of the next packet we
- will send.
-
- @ivar incomingPacketSequence: the sequence number of the next packet we
- are expecting from the other side.
-
- @ivar outgoingCompression: an object supporting the .compress(str) and
- .flush() methods, or None if there is no outgoing compression. Used to
- compress outgoing data.
-
- @ivar outgoingCompressionType: A string representing the outgoing
- compression type.
-
- @ivar incomingCompression: an object supporting the .decompress(str)
- method, or None if there is no incoming compression. Used to
- decompress incoming data.
-
- @ivar incomingCompressionType: A string representing the incoming
- compression type.
-
- @ivar ourVersionString: the version string that we sent to the other side.
- Used in the key exchange.
-
- @ivar otherVersionString: the version string sent by the other side. Used
- in the key exchange.
-
- @ivar ourKexInitPayload: the MSG_KEXINIT payload we sent. Used in the key
- exchange.
-
- @ivar otherKexInitPayload: the MSG_KEXINIT payload we received. Used in
- the key exchange
-
- @ivar sessionID: a string that is unique to this SSH session. Created as
- part of the key exchange, sessionID is used to generate the various
- encryption and authentication keys.
-
- @ivar service: an SSHService instance, or None. If it's set to an object,
- it's the currently running service.
-
- @ivar kexAlg: the agreed-upon key exchange algorithm.
-
- @ivar keyAlg: the agreed-upon public key type for the key exchange.
-
- @ivar currentEncryptions: an SSHCiphers instance. It represents the
- current encryption and authentication options for the transport.
-
- @ivar nextEncryptions: an SSHCiphers instance. Held here until the
- MSG_NEWKEYS messages are exchanged, when nextEncryptions is
- transitioned to currentEncryptions.
-
- @ivar first: the first bytes of the next packet. In order to avoid
- decrypting data twice, the first bytes are decrypted and stored until
- the whole packet is available.
-
- @ivar _keyExchangeState: The current protocol state with respect to key
- exchange. This is either C{_KEY_EXCHANGE_NONE} if no key exchange is
- in progress (and returns to this value after any key exchange
- completqes), C{_KEY_EXCHANGE_REQUESTED} if this side of the connection
- initiated a key exchange, and C{_KEY_EXCHANGE_PROGRESSING} if the other
- side of the connection initiated a key exchange. C{_KEY_EXCHANGE_NONE}
- is the initial value (however SSH connections begin with key exchange,
- so it will quickly change to another state).
-
- @ivar _blockedByKeyExchange: Whenever C{_keyExchangeState} is not
- C{_KEY_EXCHANGE_NONE}, this is a C{list} of pending messages which were
- passed to L{sendPacket} but could not be sent because it is not legal
- to send them while a key exchange is in progress. When the key
- exchange completes, another attempt is made to send these messages.
- """
-
-
- protocolVersion = '2.0'
- version = 'Twisted'
- comment = ''
- ourVersionString = ('SSH-' + protocolVersion + '-' + version + ' '
- + comment).strip()
- supportedCiphers = ['aes256-ctr', 'aes256-cbc', 'aes192-ctr', 'aes192-cbc',
- 'aes128-ctr', 'aes128-cbc', 'cast128-ctr',
- 'cast128-cbc', 'blowfish-ctr', 'blowfish-cbc',
- '3des-ctr', '3des-cbc'] # ,'none']
- supportedMACs = ['hmac-sha1', 'hmac-md5'] # , 'none']
- # both of the above support 'none', but for security are disabled by
- # default. to enable them, subclass this class and add it, or do:
- # SSHTransportBase.supportedCiphers.append('none')
- supportedKeyExchanges = ['diffie-hellman-group-exchange-sha1',
- 'diffie-hellman-group1-sha1']
- supportedPublicKeys = ['ssh-rsa', 'ssh-dss']
- supportedCompressions = ['none', 'zlib']
- supportedLanguages = ()
- supportedVersions = ('1.99', '2.0')
- isClient = False
- gotVersion = False
- buf = ''
- outgoingPacketSequence = 0
- incomingPacketSequence = 0
- outgoingCompression = None
- incomingCompression = None
- sessionID = None
- service = None
-
- # There is no key exchange activity in progress.
- _KEY_EXCHANGE_NONE = '_KEY_EXCHANGE_NONE'
-
- # Key exchange is in progress and we started it.
- _KEY_EXCHANGE_REQUESTED = '_KEY_EXCHANGE_REQUESTED'
-
- # Key exchange is in progress and both sides have sent KEXINIT messages.
- _KEY_EXCHANGE_PROGRESSING = '_KEY_EXCHANGE_PROGRESSING'
-
- # There is a fourth conceptual state not represented here: KEXINIT received
- # but not sent. Since we always send a KEXINIT as soon as we get it, we
- # can't ever be in that state.
-
- # The current key exchange state.
- _keyExchangeState = _KEY_EXCHANGE_NONE
- _blockedByKeyExchange = None
-
- def connectionLost(self, reason):
- if self.service:
- self.service.serviceStopped()
- if hasattr(self, 'avatar'):
- self.logoutFunction()
- log.msg('connection lost')
-
-
- def connectionMade(self):
- """
- Called when the connection is made to the other side. We sent our
- version and the MSG_KEXINIT packet.
- """
- self.transport.write('%s\r\n' % (self.ourVersionString,))
- self.currentEncryptions = SSHCiphers('none', 'none', 'none', 'none')
- self.currentEncryptions.setKeys('', '', '', '', '', '')
- self.sendKexInit()
-
-
- def sendKexInit(self):
- """
- Send a I{KEXINIT} message to initiate key exchange or to respond to a
- key exchange initiated by the peer.
-
- @raise RuntimeError: If a key exchange has already been started and it
- is not appropriate to send a I{KEXINIT} message at this time.
-
- @return: C{None}
- """
- if self._keyExchangeState != self._KEY_EXCHANGE_NONE:
- raise RuntimeError(
- "Cannot send KEXINIT while key exchange state is %r" % (
- self._keyExchangeState,))
-
- self.ourKexInitPayload = (chr(MSG_KEXINIT) +
- randbytes.secureRandom(16) +
- NS(','.join(self.supportedKeyExchanges)) +
- NS(','.join(self.supportedPublicKeys)) +
- NS(','.join(self.supportedCiphers)) +
- NS(','.join(self.supportedCiphers)) +
- NS(','.join(self.supportedMACs)) +
- NS(','.join(self.supportedMACs)) +
- NS(','.join(self.supportedCompressions)) +
- NS(','.join(self.supportedCompressions)) +
- NS(','.join(self.supportedLanguages)) +
- NS(','.join(self.supportedLanguages)) +
- '\000' + '\000\000\000\000')
- self.sendPacket(MSG_KEXINIT, self.ourKexInitPayload[1:])
- self._keyExchangeState = self._KEY_EXCHANGE_REQUESTED
- self._blockedByKeyExchange = []
-
-
- def _allowedKeyExchangeMessageType(self, messageType):
- """
- Determine if the given message type may be sent while key exchange is
- in progress.
-
- @param messageType: The type of message
- @type messageType: C{int}
-
- @return: C{True} if the given type of message may be sent while key
- exchange is in progress, C{False} if it may not.
- @rtype: C{bool}
-
- @see: U{http://tools.ietf.org/html/rfc4253#section-7.1}
- """
- # Written somewhat peculularly to reflect the way the specification
- # defines the allowed message types.
- if 1 <= messageType <= 19:
- return messageType not in (MSG_SERVICE_REQUEST, MSG_SERVICE_ACCEPT)
- if 20 <= messageType <= 29:
- return messageType not in (MSG_KEXINIT,)
- return 30 <= messageType <= 49
-
-
- def sendPacket(self, messageType, payload):
- """
- Sends a packet. If it's been set up, compress the data, encrypt it,
- and authenticate it before sending. If key exchange is in progress and
- the message is not part of key exchange, queue it to be sent later.
-
- @param messageType: The type of the packet; generally one of the
- MSG_* values.
- @type messageType: C{int}
- @param payload: The payload for the message.
- @type payload: C{str}
- """
- if self._keyExchangeState != self._KEY_EXCHANGE_NONE:
- if not self._allowedKeyExchangeMessageType(messageType):
- self._blockedByKeyExchange.append((messageType, payload))
- return
-
- payload = chr(messageType) + payload
- if self.outgoingCompression:
- payload = (self.outgoingCompression.compress(payload)
- + self.outgoingCompression.flush(2))
- bs = self.currentEncryptions.encBlockSize
- # 4 for the packet length and 1 for the padding length
- totalSize = 5 + len(payload)
- lenPad = bs - (totalSize % bs)
- if lenPad < 4:
- lenPad = lenPad + bs
- packet = (struct.pack('!LB',
- totalSize + lenPad - 4, lenPad) +
- payload + randbytes.secureRandom(lenPad))
- encPacket = (
- self.currentEncryptions.encrypt(packet) +
- self.currentEncryptions.makeMAC(
- self.outgoingPacketSequence, packet))
- self.transport.write(encPacket)
- self.outgoingPacketSequence += 1
-
-
- def getPacket(self):
- """
- Try to return a decrypted, authenticated, and decompressed packet
- out of the buffer. If there is not enough data, return None.
-
- @rtype: C{str}/C{None}
- """
- bs = self.currentEncryptions.decBlockSize
- ms = self.currentEncryptions.verifyDigestSize
- if len(self.buf) < bs: return # not enough data
- if not hasattr(self, 'first'):
- first = self.currentEncryptions.decrypt(self.buf[:bs])
- else:
- first = self.first
- del self.first
- packetLen, paddingLen = struct.unpack('!LB', first[:5])
- if packetLen > 1048576: # 1024 ** 2
- self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR,
- 'bad packet length %s' % packetLen)
- return
- if len(self.buf) < packetLen + 4 + ms:
- self.first = first
- return # not enough packet
- if(packetLen + 4) % bs != 0:
- self.sendDisconnect(
- DISCONNECT_PROTOCOL_ERROR,
- 'bad packet mod (%i%%%i == %i)' % (packetLen + 4, bs,
- (packetLen + 4) % bs))
- return
- encData, self.buf = self.buf[:4 + packetLen], self.buf[4 + packetLen:]
- packet = first + self.currentEncryptions.decrypt(encData[bs:])
- if len(packet) != 4 + packetLen:
- self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR,
- 'bad decryption')
- return
- if ms:
- macData, self.buf = self.buf[:ms], self.buf[ms:]
- if not self.currentEncryptions.verify(self.incomingPacketSequence,
- packet, macData):
- self.sendDisconnect(DISCONNECT_MAC_ERROR, 'bad MAC')
- return
- payload = packet[5:-paddingLen]
- if self.incomingCompression:
- try:
- payload = self.incomingCompression.decompress(payload)
- except: # bare except, because who knows what kind of errors
- # decompression can raise
- log.err()
- self.sendDisconnect(DISCONNECT_COMPRESSION_ERROR,
- 'compression error')
- return
- self.incomingPacketSequence += 1
- return payload
-
-
- def _unsupportedVersionReceived(self, remoteVersion):
- """
- Called when an unsupported version of the ssh protocol is received from
- the remote endpoint.
-
- @param remoteVersion: remote ssh protocol version which is unsupported
- by us.
- @type remoteVersion: C{str}
- """
- self.sendDisconnect(DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
- 'bad version ' + remoteVersion)
-
-
- def dataReceived(self, data):
- """
- First, check for the version string (SSH-2.0-*). After that has been
- received, this method adds data to the buffer, and pulls out any
- packets.
-
- @type data: C{str}
- """
- self.buf = self.buf + data
- if not self.gotVersion:
- if self.buf.find('\n', self.buf.find('SSH-')) == -1:
- return
- lines = self.buf.split('\n')
- for p in lines:
- if p.startswith('SSH-'):
- self.gotVersion = True
- self.otherVersionString = p.strip()
- remoteVersion = p.split('-')[1]
- if remoteVersion not in self.supportedVersions:
- self._unsupportedVersionReceived(remoteVersion)
- return
- i = lines.index(p)
- self.buf = '\n'.join(lines[i + 1:])
- packet = self.getPacket()
- while packet:
- messageNum = ord(packet[0])
- self.dispatchMessage(messageNum, packet[1:])
- packet = self.getPacket()
-
-
- def dispatchMessage(self, messageNum, payload):
- """
- Send a received message to the appropriate method.
-
- @type messageNum: C{int}
- @type payload: c{str}
- """
- if messageNum < 50 and messageNum in messages:
- messageType = messages[messageNum][4:]
- f = getattr(self, 'ssh_%s' % messageType, None)
- if f is not None:
- f(payload)
- else:
- log.msg("couldn't handle %s" % messageType)
- log.msg(repr(payload))
- self.sendUnimplemented()
- elif self.service:
- log.callWithLogger(self.service, self.service.packetReceived,
- messageNum, payload)
- else:
- log.msg("couldn't handle %s" % messageNum)
- log.msg(repr(payload))
- self.sendUnimplemented()
-
- def getPeer(self):
- """
- Returns an L{SSHTransportAddress} corresponding to the other (peer)
- side of this transport.
-
- @return: L{SSHTransportAddress} for the peer
- @rtype: L{SSHTransportAddress}
- @since: 12.1
- """
- return address.SSHTransportAddress(self.transport.getPeer())
-
- def getHost(self):
- """
- Returns an L{SSHTransportAddress} corresponding to the this side of
- transport.
-
- @return: L{SSHTransportAddress} for the peer
- @rtype: L{SSHTransportAddress}
- @since: 12.1
- """
- return address.SSHTransportAddress(self.transport.getHost())
-
-
- # Client-initiated rekeying looks like this:
- #
- # C> MSG_KEXINIT
- # S> MSG_KEXINIT
- # C> MSG_KEX_DH_GEX_REQUEST or MSG_KEXDH_INIT
- # S> MSG_KEX_DH_GEX_GROUP or MSG_KEXDH_REPLY
- # C> MSG_KEX_DH_GEX_INIT or --
- # S> MSG_KEX_DH_GEX_REPLY or --
- # C> MSG_NEWKEYS
- # S> MSG_NEWKEYS
- #
- # Server-initiated rekeying is the same, only the first two messages are
- # switched.
-
- def ssh_KEXINIT(self, packet):
- """
- Called when we receive a MSG_KEXINIT message. Payload::
- bytes[16] cookie
- string keyExchangeAlgorithms
- string keyAlgorithms
- string incomingEncryptions
- string outgoingEncryptions
- string incomingAuthentications
- string outgoingAuthentications
- string incomingCompressions
- string outgoingCompressions
- string incomingLanguages
- string outgoingLanguages
- bool firstPacketFollows
- unit32 0 (reserved)
-
- Starts setting up the key exchange, keys, encryptions, and
- authentications. Extended by ssh_KEXINIT in SSHServerTransport and
- SSHClientTransport.
- """
- self.otherKexInitPayload = chr(MSG_KEXINIT) + packet
- #cookie = packet[: 16] # taking this is useless
- k = getNS(packet[16:], 10)
- strings, rest = k[:-1], k[-1]
- (kexAlgs, keyAlgs, encCS, encSC, macCS, macSC, compCS, compSC, langCS,
- langSC) = [s.split(',') for s in strings]
- # these are the server directions
- outs = [encSC, macSC, compSC]
- ins = [encCS, macSC, compCS]
- if self.isClient:
- outs, ins = ins, outs # switch directions
- server = (self.supportedKeyExchanges, self.supportedPublicKeys,
- self.supportedCiphers, self.supportedCiphers,
- self.supportedMACs, self.supportedMACs,
- self.supportedCompressions, self.supportedCompressions)
- client = (kexAlgs, keyAlgs, outs[0], ins[0], outs[1], ins[1],
- outs[2], ins[2])
- if self.isClient:
- server, client = client, server
- self.kexAlg = ffs(client[0], server[0])
- self.keyAlg = ffs(client[1], server[1])
- self.nextEncryptions = SSHCiphers(
- ffs(client[2], server[2]),
- ffs(client[3], server[3]),
- ffs(client[4], server[4]),
- ffs(client[5], server[5]))
- self.outgoingCompressionType = ffs(client[6], server[6])
- self.incomingCompressionType = ffs(client[7], server[7])
- if None in (self.kexAlg, self.keyAlg, self.outgoingCompressionType,
- self.incomingCompressionType):
- self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
- "couldn't match all kex parts")
- return
- if None in self.nextEncryptions.__dict__.values():
- self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
- "couldn't match all kex parts")
- return
- log.msg('kex alg, key alg: %s %s' % (self.kexAlg, self.keyAlg))
- log.msg('outgoing: %s %s %s' % (self.nextEncryptions.outCipType,
- self.nextEncryptions.outMACType,
- self.outgoingCompressionType))
- log.msg('incoming: %s %s %s' % (self.nextEncryptions.inCipType,
- self.nextEncryptions.inMACType,
- self.incomingCompressionType))
-
- if self._keyExchangeState == self._KEY_EXCHANGE_REQUESTED:
- self._keyExchangeState = self._KEY_EXCHANGE_PROGRESSING
- else:
- self.sendKexInit()
-
- return kexAlgs, keyAlgs, rest # for SSHServerTransport to use
-
-
- def ssh_DISCONNECT(self, packet):
- """
- Called when we receive a MSG_DISCONNECT message. Payload::
- long code
- string description
-
- This means that the other side has disconnected. Pass the message up
- and disconnect ourselves.
- """
- reasonCode = struct.unpack('>L', packet[: 4])[0]
- description, foo = getNS(packet[4:])
- self.receiveError(reasonCode, description)
- self.transport.loseConnection()
-
-
- def ssh_IGNORE(self, packet):
- """
- Called when we receieve a MSG_IGNORE message. No payload.
- This means nothing; we simply return.
- """
-
-
- def ssh_UNIMPLEMENTED(self, packet):
- """
- Called when we receieve a MSG_UNIMPLEMENTED message. Payload::
- long packet
-
- This means that the other side did not implement one of our packets.
- """
- seqnum, = struct.unpack('>L', packet)
- self.receiveUnimplemented(seqnum)
-
-
- def ssh_DEBUG(self, packet):
- """
- Called when we receieve a MSG_DEBUG message. Payload::
- bool alwaysDisplay
- string message
- string language
-
- This means the other side has passed along some debugging info.
- """
- alwaysDisplay = bool(packet[0])
- message, lang, foo = getNS(packet[1:], 2)
- self.receiveDebug(alwaysDisplay, message, lang)
-
-
- def setService(self, service):
- """
- Set our service to service and start it running. If we were
- running a service previously, stop it first.
-
- @type service: C{SSHService}
- """
- log.msg('starting service %s' % service.name)
- if self.service:
- self.service.serviceStopped()
- self.service = service
- service.transport = self
- self.service.serviceStarted()
-
-
- def sendDebug(self, message, alwaysDisplay=False, language=''):
- """
- Send a debug message to the other side.
-
- @param message: the message to send.
- @type message: C{str}
- @param alwaysDisplay: if True, tell the other side to always
- display this message.
- @type alwaysDisplay: C{bool}
- @param language: optionally, the language the message is in.
- @type language: C{str}
- """
- self.sendPacket(MSG_DEBUG, chr(alwaysDisplay) + NS(message) +
- NS(language))
-
-
- def sendIgnore(self, message):
- """
- Send a message that will be ignored by the other side. This is
- useful to fool attacks based on guessing packet sizes in the
- encrypted stream.
-
- @param message: data to send with the message
- @type message: C{str}
- """
- self.sendPacket(MSG_IGNORE, NS(message))
-
-
- def sendUnimplemented(self):
- """
- Send a message to the other side that the last packet was not
- understood.
- """
- seqnum = self.incomingPacketSequence
- self.sendPacket(MSG_UNIMPLEMENTED, struct.pack('!L', seqnum))
-
-
- def sendDisconnect(self, reason, desc):
- """
- Send a disconnect message to the other side and then disconnect.
-
- @param reason: the reason for the disconnect. Should be one of the
- DISCONNECT_* values.
- @type reason: C{int}
- @param desc: a descrption of the reason for the disconnection.
- @type desc: C{str}
- """
- self.sendPacket(
- MSG_DISCONNECT, struct.pack('>L', reason) + NS(desc) + NS(''))
- log.msg('Disconnecting with error, code %s\nreason: %s' % (reason,
- desc))
- self.transport.loseConnection()
-
-
- def _getKey(self, c, sharedSecret, exchangeHash):
- """
- Get one of the keys for authentication/encryption.
-
- @type c: C{str}
- @type sharedSecret: C{str}
- @type exchangeHash: C{str}
- """
- k1 = sha1(sharedSecret + exchangeHash + c + self.sessionID)
- k1 = k1.digest()
- k2 = sha1(sharedSecret + exchangeHash + k1).digest()
- return k1 + k2
-
-
- def _keySetup(self, sharedSecret, exchangeHash):
- """
- Set up the keys for the connection and sends MSG_NEWKEYS when
- finished,
-
- @param sharedSecret: a secret string agreed upon using a Diffie-
- Hellman exchange, so it is only shared between
- the server and the client.
- @type sharedSecret: C{str}
- @param exchangeHash: A hash of various data known by both sides.
- @type exchangeHash: C{str}
- """
- if not self.sessionID:
- self.sessionID = exchangeHash
- initIVCS = self._getKey('A', sharedSecret, exchangeHash)
- initIVSC = self._getKey('B', sharedSecret, exchangeHash)
- encKeyCS = self._getKey('C', sharedSecret, exchangeHash)
- encKeySC = self._getKey('D', sharedSecret, exchangeHash)
- integKeyCS = self._getKey('E', sharedSecret, exchangeHash)
- integKeySC = self._getKey('F', sharedSecret, exchangeHash)
- outs = [initIVSC, encKeySC, integKeySC]
- ins = [initIVCS, encKeyCS, integKeyCS]
- if self.isClient: # reverse for the client
- log.msg('REVERSE')
- outs, ins = ins, outs
- self.nextEncryptions.setKeys(outs[0], outs[1], ins[0], ins[1],
- outs[2], ins[2])
- self.sendPacket(MSG_NEWKEYS, '')
-
-
- def _newKeys(self):
- """
- Called back by a subclass once a I{MSG_NEWKEYS} message has been
- received. This indicates key exchange has completed and new encryption
- and compression parameters should be adopted. Any messages which were
- queued during key exchange will also be flushed.
- """
- log.msg('NEW KEYS')
- self.currentEncryptions = self.nextEncryptions
- if self.outgoingCompressionType == 'zlib':
- self.outgoingCompression = zlib.compressobj(6)
- if self.incomingCompressionType == 'zlib':
- self.incomingCompression = zlib.decompressobj()
-
- self._keyExchangeState = self._KEY_EXCHANGE_NONE
- messages = self._blockedByKeyExchange
- self._blockedByKeyExchange = None
- for (messageType, payload) in messages:
- self.sendPacket(messageType, payload)
-
-
- def isEncrypted(self, direction="out"):
- """
- Return True if the connection is encrypted in the given direction.
- Direction must be one of ["out", "in", "both"].
- """
- if direction == "out":
- return self.currentEncryptions.outCipType != 'none'
- elif direction == "in":
- return self.currentEncryptions.inCipType != 'none'
- elif direction == "both":
- return self.isEncrypted("in") and self.isEncrypted("out")
- else:
- raise TypeError('direction must be "out", "in", or "both"')
-
-
- def isVerified(self, direction="out"):
- """
- Return True if the connecction is verified/authenticated in the
- given direction. Direction must be one of ["out", "in", "both"].
- """
- if direction == "out":
- return self.currentEncryptions.outMACType != 'none'
- elif direction == "in":
- return self.currentEncryptions.inMACType != 'none'
- elif direction == "both":
- return self.isVerified("in")and self.isVerified("out")
- else:
- raise TypeError('direction must be "out", "in", or "both"')
-
-
- def loseConnection(self):
- """
- Lose the connection to the other side, sending a
- DISCONNECT_CONNECTION_LOST message.
- """
- self.sendDisconnect(DISCONNECT_CONNECTION_LOST,
- "user closed connection")
-
-
- # client methods
- def receiveError(self, reasonCode, description):
- """
- Called when we receive a disconnect error message from the other
- side.
-
- @param reasonCode: the reason for the disconnect, one of the
- DISCONNECT_ values.
- @type reasonCode: C{int}
- @param description: a human-readable description of the
- disconnection.
- @type description: C{str}
- """
- log.msg('Got remote error, code %s\nreason: %s' % (reasonCode,
- description))
-
-
- def receiveUnimplemented(self, seqnum):
- """
- Called when we receive an unimplemented packet message from the other
- side.
-
- @param seqnum: the sequence number that was not understood.
- @type seqnum: C{int}
- """
- log.msg('other side unimplemented packet #%s' % seqnum)
-
-
- def receiveDebug(self, alwaysDisplay, message, lang):
- """
- Called when we receive a debug message from the other side.
-
- @param alwaysDisplay: if True, this message should always be
- displayed.
- @type alwaysDisplay: C{bool}
- @param message: the debug message
- @type message: C{str}
- @param lang: optionally the language the message is in.
- @type lang: C{str}
- """
- if alwaysDisplay:
- log.msg('Remote Debug Message: %s' % message)
-
-
-
-class SSHServerTransport(SSHTransportBase):
- """
- SSHServerTransport implements the server side of the SSH protocol.
-
- @ivar isClient: since we are never the client, this is always False.
-
- @ivar ignoreNextPacket: if True, ignore the next key exchange packet. This
- is set when the client sends a guessed key exchange packet but with
- an incorrect guess.
-
- @ivar dhGexRequest: the KEX_DH_GEX_REQUEST(_OLD) that the client sent.
- The key generation needs this to be stored.
-
- @ivar g: the Diffie-Hellman group generator.
-
- @ivar p: the Diffie-Hellman group prime.
- """
- isClient = False
- ignoreNextPacket = 0
-
-
- def ssh_KEXINIT(self, packet):
- """
- Called when we receive a MSG_KEXINIT message. For a description
- of the packet, see SSHTransportBase.ssh_KEXINIT(). Additionally,
- this method checks if a guessed key exchange packet was sent. If
- it was sent, and it guessed incorrectly, the next key exchange
- packet MUST be ignored.
- """
- retval = SSHTransportBase.ssh_KEXINIT(self, packet)
- if not retval: # disconnected
- return
- else:
- kexAlgs, keyAlgs, rest = retval
- if ord(rest[0]): # first_kex_packet_follows
- if (kexAlgs[0] != self.supportedKeyExchanges[0] or
- keyAlgs[0] != self.supportedPublicKeys[0]):
- self.ignoreNextPacket = True # guess was wrong
-
-
- def _ssh_KEXDH_INIT(self, packet):
- """
- Called to handle the beginning of a diffie-hellman-group1-sha1 key
- exchange.
-
- Unlike other message types, this is not dispatched automatically. It
- is called from C{ssh_KEX_DH_GEX_REQUEST_OLD} because an extra check is
- required to determine if this is really a KEXDH_INIT message or if it
- is a KEX_DH_GEX_REQUEST_OLD message.
-
- The KEXDH_INIT (for diffie-hellman-group1-sha1 exchanges) payload::
-
- integer e (the client's Diffie-Hellman public key)
-
- We send the KEXDH_REPLY with our host key and signature.
- """
- clientDHpublicKey, foo = getMP(packet)
- y = _getRandomNumber(randbytes.secureRandom, 512)
- serverDHpublicKey = _MPpow(DH_GENERATOR, y, DH_PRIME)
- sharedSecret = _MPpow(clientDHpublicKey, y, DH_PRIME)
- h = sha1()
- h.update(NS(self.otherVersionString))
- h.update(NS(self.ourVersionString))
- h.update(NS(self.otherKexInitPayload))
- h.update(NS(self.ourKexInitPayload))
- h.update(NS(self.factory.publicKeys[self.keyAlg].blob()))
- h.update(MP(clientDHpublicKey))
- h.update(serverDHpublicKey)
- h.update(sharedSecret)
- exchangeHash = h.digest()
- self.sendPacket(
- MSG_KEXDH_REPLY,
- NS(self.factory.publicKeys[self.keyAlg].blob()) +
- serverDHpublicKey +
- NS(self.factory.privateKeys[self.keyAlg].sign(exchangeHash)))
- self._keySetup(sharedSecret, exchangeHash)
-
-
- def ssh_KEX_DH_GEX_REQUEST_OLD(self, packet):
- """
- This represents two different key exchange methods that share the same
- integer value. If the message is determined to be a KEXDH_INIT,
- C{_ssh_KEXDH_INIT} is called to handle it. Otherwise, for
- KEX_DH_GEX_REQUEST_OLD (for diffie-hellman-group-exchange-sha1)
- payload::
-
- integer ideal (ideal size for the Diffie-Hellman prime)
-
- We send the KEX_DH_GEX_GROUP message with the group that is
- closest in size to ideal.
-
- If we were told to ignore the next key exchange packet by ssh_KEXINIT,
- drop it on the floor and return.
- """
- if self.ignoreNextPacket:
- self.ignoreNextPacket = 0
- return
-
- # KEXDH_INIT and KEX_DH_GEX_REQUEST_OLD have the same value, so use
- # another cue to decide what kind of message the peer sent us.
- if self.kexAlg == 'diffie-hellman-group1-sha1':
- return self._ssh_KEXDH_INIT(packet)
- elif self.kexAlg == 'diffie-hellman-group-exchange-sha1':
- self.dhGexRequest = packet
- ideal = struct.unpack('>L', packet)[0]
- self.g, self.p = self.factory.getDHPrime(ideal)
- self.sendPacket(MSG_KEX_DH_GEX_GROUP, MP(self.p) + MP(self.g))
- else:
- raise error.ConchError('bad kexalg: %s' % self.kexAlg)
-
-
- def ssh_KEX_DH_GEX_REQUEST(self, packet):
- """
- Called when we receive a MSG_KEX_DH_GEX_REQUEST message. Payload::
- integer minimum
- integer ideal
- integer maximum
-
- The client is asking for a Diffie-Hellman group between minimum and
- maximum size, and close to ideal if possible. We reply with a
- MSG_KEX_DH_GEX_GROUP message.
-
- If we were told to ignore the next key exchange packet by ssh_KEXINIT,
- drop it on the floor and return.
- """
- if self.ignoreNextPacket:
- self.ignoreNextPacket = 0
- return
- self.dhGexRequest = packet
- min, ideal, max = struct.unpack('>3L', packet)
- self.g, self.p = self.factory.getDHPrime(ideal)
- self.sendPacket(MSG_KEX_DH_GEX_GROUP, MP(self.p) + MP(self.g))
-
-
- def ssh_KEX_DH_GEX_INIT(self, packet):
- """
- Called when we get a MSG_KEX_DH_GEX_INIT message. Payload::
- integer e (client DH public key)
-
- We send the MSG_KEX_DH_GEX_REPLY message with our host key and
- signature.
- """
- clientDHpublicKey, foo = getMP(packet)
- # TODO: we should also look at the value they send to us and reject
- # insecure values of f (if g==2 and f has a single '1' bit while the
- # rest are '0's, then they must have used a small y also).
-
- # TODO: This could be computed when self.p is set up
- # or do as openssh does and scan f for a single '1' bit instead
-
- pSize = Util.number.size(self.p)
- y = _getRandomNumber(randbytes.secureRandom, pSize)
-
- serverDHpublicKey = _MPpow(self.g, y, self.p)
- sharedSecret = _MPpow(clientDHpublicKey, y, self.p)
- h = sha1()
- h.update(NS(self.otherVersionString))
- h.update(NS(self.ourVersionString))
- h.update(NS(self.otherKexInitPayload))
- h.update(NS(self.ourKexInitPayload))
- h.update(NS(self.factory.publicKeys[self.keyAlg].blob()))
- h.update(self.dhGexRequest)
- h.update(MP(self.p))
- h.update(MP(self.g))
- h.update(MP(clientDHpublicKey))
- h.update(serverDHpublicKey)
- h.update(sharedSecret)
- exchangeHash = h.digest()
- self.sendPacket(
- MSG_KEX_DH_GEX_REPLY,
- NS(self.factory.publicKeys[self.keyAlg].blob()) +
- serverDHpublicKey +
- NS(self.factory.privateKeys[self.keyAlg].sign(exchangeHash)))
- self._keySetup(sharedSecret, exchangeHash)
-
-
- def ssh_NEWKEYS(self, packet):
- """
- Called when we get a MSG_NEWKEYS message. No payload.
- When we get this, the keys have been set on both sides, and we
- start using them to encrypt and authenticate the connection.
- """
- if packet != '':
- self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR,
- "NEWKEYS takes no data")
- return
- self._newKeys()
-
-
- def ssh_SERVICE_REQUEST(self, packet):
- """
- Called when we get a MSG_SERVICE_REQUEST message. Payload::
- string serviceName
-
- The client has requested a service. If we can start the service,
- start it; otherwise, disconnect with
- DISCONNECT_SERVICE_NOT_AVAILABLE.
- """
- service, rest = getNS(packet)
- cls = self.factory.getService(self, service)
- if not cls:
- self.sendDisconnect(DISCONNECT_SERVICE_NOT_AVAILABLE,
- "don't have service %s" % service)
- return
- else:
- self.sendPacket(MSG_SERVICE_ACCEPT, NS(service))
- self.setService(cls())
-
-
-
-class SSHClientTransport(SSHTransportBase):
- """
- SSHClientTransport implements the client side of the SSH protocol.
-
- @ivar isClient: since we are always the client, this is always True.
-
- @ivar _gotNewKeys: if we receive a MSG_NEWKEYS message before we are
- ready to transition to the new keys, this is set to True so we
- can transition when the keys are ready locally.
-
- @ivar x: our Diffie-Hellman private key.
-
- @ivar e: our Diffie-Hellman public key.
-
- @ivar g: the Diffie-Hellman group generator.
-
- @ivar p: the Diffie-Hellman group prime
-
- @ivar instance: the SSHService object we are requesting.
- """
- isClient = True
-
- def connectionMade(self):
- """
- Called when the connection is started with the server. Just sets
- up a private instance variable.
- """
- SSHTransportBase.connectionMade(self)
- self._gotNewKeys = 0
-
-
- def ssh_KEXINIT(self, packet):
- """
- Called when we receive a MSG_KEXINIT message. For a description
- of the packet, see SSHTransportBase.ssh_KEXINIT(). Additionally,
- this method sends the first key exchange packet. If the agreed-upon
- exchange is diffie-hellman-group1-sha1, generate a public key
- and send it in a MSG_KEXDH_INIT message. If the exchange is
- diffie-hellman-group-exchange-sha1, ask for a 2048 bit group with a
- MSG_KEX_DH_GEX_REQUEST_OLD message.
- """
- if SSHTransportBase.ssh_KEXINIT(self, packet) is None:
- return # we disconnected
- if self.kexAlg == 'diffie-hellman-group1-sha1':
- self.x = _generateX(randbytes.secureRandom, 512)
- self.e = _MPpow(DH_GENERATOR, self.x, DH_PRIME)
- self.sendPacket(MSG_KEXDH_INIT, self.e)
- elif self.kexAlg == 'diffie-hellman-group-exchange-sha1':
- self.sendPacket(MSG_KEX_DH_GEX_REQUEST_OLD, '\x00\x00\x08\x00')
- else:
- raise error.ConchError("somehow, the kexAlg has been set "
- "to something we don't support")
-
-
- def _ssh_KEXDH_REPLY(self, packet):
- """
- Called to handle a reply to a diffie-hellman-group1-sha1 key exchange
- message (KEXDH_INIT).
-
- Like the handler for I{KEXDH_INIT}, this message type has an
- overlapping value. This method is called from C{ssh_KEX_DH_GEX_GROUP}
- if that method detects a diffie-hellman-group1-sha1 key exchange is in
- progress.
-
- Payload::
-
- string serverHostKey
- integer f (server Diffie-Hellman public key)
- string signature
-
- We verify the host key by calling verifyHostKey, then continue in
- _continueKEXDH_REPLY.
- """
- pubKey, packet = getNS(packet)
- f, packet = getMP(packet)
- signature, packet = getNS(packet)
- fingerprint = ':'.join([ch.encode('hex') for ch in
- md5(pubKey).digest()])
- d = self.verifyHostKey(pubKey, fingerprint)
- d.addCallback(self._continueKEXDH_REPLY, pubKey, f, signature)
- d.addErrback(
- lambda unused: self.sendDisconnect(
- DISCONNECT_HOST_KEY_NOT_VERIFIABLE, 'bad host key'))
- return d
-
-
- def ssh_KEX_DH_GEX_GROUP(self, packet):
- """
- This handles two different message which share an integer value.
-
- If the key exchange is diffie-hellman-group-exchange-sha1, this is
- MSG_KEX_DH_GEX_GROUP. Payload::
- string g (group generator)
- string p (group prime)
-
- We generate a Diffie-Hellman public key and send it in a
- MSG_KEX_DH_GEX_INIT message.
- """
- if self.kexAlg == 'diffie-hellman-group1-sha1':
- return self._ssh_KEXDH_REPLY(packet)
- else:
- self.p, rest = getMP(packet)
- self.g, rest = getMP(rest)
- self.x = _generateX(randbytes.secureRandom, 320)
- self.e = _MPpow(self.g, self.x, self.p)
- self.sendPacket(MSG_KEX_DH_GEX_INIT, self.e)
-
-
- def _continueKEXDH_REPLY(self, ignored, pubKey, f, signature):
- """
- The host key has been verified, so we generate the keys.
-
- @param pubKey: the public key blob for the server's public key.
- @type pubKey: C{str}
- @param f: the server's Diffie-Hellman public key.
- @type f: C{long}
- @param signature: the server's signature, verifying that it has the
- correct private key.
- @type signature: C{str}
- """
- serverKey = keys.Key.fromString(pubKey)
- sharedSecret = _MPpow(f, self.x, DH_PRIME)
- h = sha1()
- h.update(NS(self.ourVersionString))
- h.update(NS(self.otherVersionString))
- h.update(NS(self.ourKexInitPayload))
- h.update(NS(self.otherKexInitPayload))
- h.update(NS(pubKey))
- h.update(self.e)
- h.update(MP(f))
- h.update(sharedSecret)
- exchangeHash = h.digest()
- if not serverKey.verify(signature, exchangeHash):
- self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
- 'bad signature')
- return
- self._keySetup(sharedSecret, exchangeHash)
-
-
- def ssh_KEX_DH_GEX_REPLY(self, packet):
- """
- Called when we receieve a MSG_KEX_DH_GEX_REPLY message. Payload::
- string server host key
- integer f (server DH public key)
-
- We verify the host key by calling verifyHostKey, then continue in
- _continueGEX_REPLY.
- """
- pubKey, packet = getNS(packet)
- f, packet = getMP(packet)
- signature, packet = getNS(packet)
- fingerprint = ':'.join(map(lambda c: '%02x'%ord(c),
- md5(pubKey).digest()))
- d = self.verifyHostKey(pubKey, fingerprint)
- d.addCallback(self._continueGEX_REPLY, pubKey, f, signature)
- d.addErrback(
- lambda unused: self.sendDisconnect(
- DISCONNECT_HOST_KEY_NOT_VERIFIABLE, 'bad host key'))
- return d
-
-
- def _continueGEX_REPLY(self, ignored, pubKey, f, signature):
- """
- The host key has been verified, so we generate the keys.
-
- @param pubKey: the public key blob for the server's public key.
- @type pubKey: C{str}
- @param f: the server's Diffie-Hellman public key.
- @type f: C{long}
- @param signature: the server's signature, verifying that it has the
- correct private key.
- @type signature: C{str}
- """
- serverKey = keys.Key.fromString(pubKey)
- sharedSecret = _MPpow(f, self.x, self.p)
- h = sha1()
- h.update(NS(self.ourVersionString))
- h.update(NS(self.otherVersionString))
- h.update(NS(self.ourKexInitPayload))
- h.update(NS(self.otherKexInitPayload))
- h.update(NS(pubKey))
- h.update('\x00\x00\x08\x00')
- h.update(MP(self.p))
- h.update(MP(self.g))
- h.update(self.e)
- h.update(MP(f))
- h.update(sharedSecret)
- exchangeHash = h.digest()
- if not serverKey.verify(signature, exchangeHash):
- self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
- 'bad signature')
- return
- self._keySetup(sharedSecret, exchangeHash)
-
-
- def _keySetup(self, sharedSecret, exchangeHash):
- """
- See SSHTransportBase._keySetup().
- """
- SSHTransportBase._keySetup(self, sharedSecret, exchangeHash)
- if self._gotNewKeys:
- self.ssh_NEWKEYS('')
-
-
- def ssh_NEWKEYS(self, packet):
- """
- Called when we receieve a MSG_NEWKEYS message. No payload.
- If we've finished setting up our own keys, start using them.
- Otherwise, remeber that we've receieved this message.
- """
- if packet != '':
- self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR,
- "NEWKEYS takes no data")
- return
- if not self.nextEncryptions.encBlockSize:
- self._gotNewKeys = 1
- return
- self._newKeys()
- self.connectionSecure()
-
-
- def ssh_SERVICE_ACCEPT(self, packet):
- """
- Called when we receieve a MSG_SERVICE_ACCEPT message. Payload::
- string service name
-
- Start the service we requested.
- """
- if packet == '':
- log.msg('got SERVICE_ACCEPT without payload')
- else:
- name = getNS(packet)[0]
- if name != self.instance.name:
- self.sendDisconnect(
- DISCONNECT_PROTOCOL_ERROR,
- "received accept for service we did not request")
- self.setService(self.instance)
-
-
- def requestService(self, instance):
- """
- Request that a service be run over this transport.
-
- @type instance: subclass of L{twisted.conch.ssh.service.SSHService}
- """
- self.sendPacket(MSG_SERVICE_REQUEST, NS(instance.name))
- self.instance = instance
-
-
- # client methods
- def verifyHostKey(self, hostKey, fingerprint):
- """
- Returns a Deferred that gets a callback if it is a valid key, or
- an errback if not.
-
- @type hostKey: C{str}
- @type fingerprint: C{str}
- @rtype: L{twisted.internet.defer.Deferred}
- """
- # return if it's good
- return defer.fail(NotImplementedError())
-
-
- def connectionSecure(self):
- """
- Called when the encryption has been set up. Generally,
- requestService() is called to run another service over the transport.
- """
- raise NotImplementedError()
-
-
-
-class _DummyCipher:
- """
- A cipher for the none encryption method.
-
- @ivar block_size: the block size of the encryption. In the case of the
- none cipher, this is 8 bytes.
- """
- block_size = 8
-
-
- def encrypt(self, x):
- return x
-
-
- decrypt = encrypt
-
-
-class SSHCiphers:
- """
- SSHCiphers represents all the encryption operations that need to occur
- to encrypt and authenticate the SSH connection.
-
- @cvar cipherMap: A dictionary mapping SSH encryption names to 3-tuples of
- (<Crypto.Cipher.* name>, <block size>, <counter mode>)
- @cvar macMap: A dictionary mapping SSH MAC names to hash modules.
-
- @ivar outCipType: the string type of the outgoing cipher.
- @ivar inCipType: the string type of the incoming cipher.
- @ivar outMACType: the string type of the incoming MAC.
- @ivar inMACType: the string type of the incoming MAC.
- @ivar encBlockSize: the block size of the outgoing cipher.
- @ivar decBlockSize: the block size of the incoming cipher.
- @ivar verifyDigestSize: the size of the incoming MAC.
- @ivar outMAC: a tuple of (<hash module>, <inner key>, <outer key>,
- <digest size>) representing the outgoing MAC.
- @ivar inMAc: see outMAC, but for the incoming MAC.
- """
-
-
- cipherMap = {
- '3des-cbc':('DES3', 24, 0),
- 'blowfish-cbc':('Blowfish', 16,0 ),
- 'aes256-cbc':('AES', 32, 0),
- 'aes192-cbc':('AES', 24, 0),
- 'aes128-cbc':('AES', 16, 0),
- 'cast128-cbc':('CAST', 16, 0),
- 'aes128-ctr':('AES', 16, 1),
- 'aes192-ctr':('AES', 24, 1),
- 'aes256-ctr':('AES', 32, 1),
- '3des-ctr':('DES3', 24, 1),
- 'blowfish-ctr':('Blowfish', 16, 1),
- 'cast128-ctr':('CAST', 16, 1),
- 'none':(None, 0, 0),
- }
- macMap = {
- 'hmac-sha1': sha1,
- 'hmac-md5': md5,
- 'none': None
- }
-
-
- def __init__(self, outCip, inCip, outMac, inMac):
- self.outCipType = outCip
- self.inCipType = inCip
- self.outMACType = outMac
- self.inMACType = inMac
- self.encBlockSize = 0
- self.decBlockSize = 0
- self.verifyDigestSize = 0
- self.outMAC = (None, '', '', 0)
- self.inMAC = (None, '', '', 0)
-
-
- def setKeys(self, outIV, outKey, inIV, inKey, outInteg, inInteg):
- """
- Set up the ciphers and hashes using the given keys,
-
- @param outIV: the outgoing initialization vector
- @param outKey: the outgoing encryption key
- @param inIV: the incoming initialization vector
- @param inKey: the incoming encryption key
- @param outInteg: the outgoing integrity key
- @param inInteg: the incoming integrity key.
- """
- o = self._getCipher(self.outCipType, outIV, outKey)
- self.encrypt = o.encrypt
- self.encBlockSize = o.block_size
- o = self._getCipher(self.inCipType, inIV, inKey)
- self.decrypt = o.decrypt
- self.decBlockSize = o.block_size
- self.outMAC = self._getMAC(self.outMACType, outInteg)
- self.inMAC = self._getMAC(self.inMACType, inInteg)
- if self.inMAC:
- self.verifyDigestSize = self.inMAC[3]
-
-
- def _getCipher(self, cip, iv, key):
- """
- Creates an initialized cipher object.
-
- @param cip: the name of the cipher: maps into Crypto.Cipher.*
- @param iv: the initialzation vector
- @param key: the encryption key
- """
- modName, keySize, counterMode = self.cipherMap[cip]
- if not modName: # no cipher
- return _DummyCipher()
- mod = __import__('Crypto.Cipher.%s'%modName, {}, {}, 'x')
- if counterMode:
- return mod.new(key[:keySize], mod.MODE_CTR, iv[:mod.block_size],
- counter=_Counter(iv, mod.block_size))
- else:
- return mod.new(key[:keySize], mod.MODE_CBC, iv[:mod.block_size])
-
-
- def _getMAC(self, mac, key):
- """
- Gets a 4-tuple representing the message authentication code.
- (<hash module>, <inner hash value>, <outer hash value>,
- <digest size>)
-
- @param mac: a key mapping into macMap
- @type mac: C{str}
- @param key: the MAC key.
- @type key: C{str}
- """
- mod = self.macMap[mac]
- if not mod:
- return (None, '', '', 0)
- ds = mod().digest_size
- key = key[:ds] + '\x00' * (64 - ds)
- i = XOR.new('\x36').encrypt(key)
- o = XOR.new('\x5c').encrypt(key)
- return mod, i, o, ds
-
-
- def encrypt(self, blocks):
- """
- Encrypt blocks. Overridden by the encrypt method of a
- Crypto.Cipher.* object in setKeys().
-
- @type blocks: C{str}
- """
- raise NotImplementedError()
-
-
- def decrypt(self, blocks):
- """
- Decrypt blocks. See encrypt().
-
- @type blocks: C{str}
- """
- raise NotImplementedError()
-
-
- def makeMAC(self, seqid, data):
- """
- Create a message authentication code (MAC) for the given packet using
- the outgoing MAC values.
-
- @param seqid: the sequence ID of the outgoing packet
- @type seqid: C{int}
- @param data: the data to create a MAC for
- @type data: C{str}
- @rtype: C{str}
- """
- if not self.outMAC[0]:
- return ''
- data = struct.pack('>L', seqid) + data
- mod, i, o, ds = self.outMAC
- inner = mod(i + data)
- outer = mod(o + inner.digest())
- return outer.digest()
-
-
- def verify(self, seqid, data, mac):
- """
- Verify an incoming MAC using the incoming MAC values. Return True
- if the MAC is valid.
-
- @param seqid: the sequence ID of the incoming packet
- @type seqid: C{int}
- @param data: the packet data to verify
- @type data: C{str}
- @param mac: the MAC sent with the packet
- @type mac: C{str}
- @rtype: C{bool}
- """
- if not self.inMAC[0]:
- return mac == ''
- data = struct.pack('>L', seqid) + data
- mod, i, o, ds = self.inMAC
- inner = mod(i + data)
- outer = mod(o + inner.digest())
- return mac == outer.digest()
-
-
-
-class _Counter:
- """
- Stateful counter which returns results packed in a byte string
- """
-
-
- def __init__(self, initialVector, blockSize):
- """
- @type initialVector: C{str}
- @param initialVector: A byte string representing the initial counter
- value.
- @type blockSize: C{int}
- @param blockSize: The length of the output buffer, as well as the
- number of bytes at the beginning of C{initialVector} to consider.
- """
- initialVector = initialVector[:blockSize]
- self.count = getMP('\xff\xff\xff\xff' + initialVector)[0]
- self.blockSize = blockSize
- self.count = Util.number.long_to_bytes(self.count - 1)
- self.count = '\x00' * (self.blockSize - len(self.count)) + self.count
- self.count = array.array('c', self.count)
- self.len = len(self.count) - 1
-
-
- def __call__(self):
- """
- Increment the counter and return the new value.
- """
- i = self.len
- while i > -1:
- self.count[i] = n = chr((ord(self.count[i]) + 1) % 256)
- if n == '\x00':
- i -= 1
- else:
- return self.count.tostring()
-
- self.count = array.array('c', '\x00' * self.blockSize)
- return self.count.tostring()
-
-
-
-# Diffie-Hellman primes from Oakley Group 2 [RFC 2409]
-DH_PRIME = long('17976931348623159077083915679378745319786029604875601170644'
-'442368419718021615851936894783379586492554150218056548598050364644054819923'
-'910005079287700335581663922955313623907650873575991482257486257500742530207'
-'744771258955095793777842444242661733472762929938766870920560605027081084290'
-'7692932019128194467627007L')
-DH_GENERATOR = 2L
-
-
-
-MSG_DISCONNECT = 1
-MSG_IGNORE = 2
-MSG_UNIMPLEMENTED = 3
-MSG_DEBUG = 4
-MSG_SERVICE_REQUEST = 5
-MSG_SERVICE_ACCEPT = 6
-MSG_KEXINIT = 20
-MSG_NEWKEYS = 21
-MSG_KEXDH_INIT = 30
-MSG_KEXDH_REPLY = 31
-MSG_KEX_DH_GEX_REQUEST_OLD = 30
-MSG_KEX_DH_GEX_REQUEST = 34
-MSG_KEX_DH_GEX_GROUP = 31
-MSG_KEX_DH_GEX_INIT = 32
-MSG_KEX_DH_GEX_REPLY = 33
-
-
-
-DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1
-DISCONNECT_PROTOCOL_ERROR = 2
-DISCONNECT_KEY_EXCHANGE_FAILED = 3
-DISCONNECT_RESERVED = 4
-DISCONNECT_MAC_ERROR = 5
-DISCONNECT_COMPRESSION_ERROR = 6
-DISCONNECT_SERVICE_NOT_AVAILABLE = 7
-DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8
-DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9
-DISCONNECT_CONNECTION_LOST = 10
-DISCONNECT_BY_APPLICATION = 11
-DISCONNECT_TOO_MANY_CONNECTIONS = 12
-DISCONNECT_AUTH_CANCELLED_BY_USER = 13
-DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14
-DISCONNECT_ILLEGAL_USER_NAME = 15
-
-
-
-messages = {}
-for name, value in globals().items():
- # Avoid legacy messages which overlap with never ones
- if name.startswith('MSG_') and not name.startswith('MSG_KEXDH_'):
- messages[value] = name
-# Check for regressions (#5352)
-if 'MSG_KEXDH_INIT' in messages or 'MSG_KEXDH_REPLY' in messages:
- raise RuntimeError(
- "legacy SSH mnemonics should not end up in messages dict")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py
deleted file mode 100755
index 65c0ef07..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py
+++ /dev/null
@@ -1,848 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_userauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation of the ssh-userauth service.
-Currently implemented authentication types are public-key and password.
-
-Maintainer: Paul Swartz
-"""
-
-import struct, warnings
-from twisted.conch import error, interfaces
-from twisted.conch.ssh import keys, transport, service
-from twisted.conch.ssh.common import NS, getNS
-from twisted.cred import credentials
-from twisted.cred.error import UnauthorizedLogin
-from twisted.internet import defer, reactor
-from twisted.python import failure, log
-
-
-
-class SSHUserAuthServer(service.SSHService):
- """
- A service implementing the server side of the 'ssh-userauth' service. It
- is used to authenticate the user on the other side as being able to access
- this server.
-
- @ivar name: the name of this service: 'ssh-userauth'
- @type name: C{str}
- @ivar authenticatedWith: a list of authentication methods that have
- already been used.
- @type authenticatedWith: C{list}
- @ivar loginTimeout: the number of seconds we wait before disconnecting
- the user for taking too long to authenticate
- @type loginTimeout: C{int}
- @ivar attemptsBeforeDisconnect: the number of failed login attempts we
- allow before disconnecting.
- @type attemptsBeforeDisconnect: C{int}
- @ivar loginAttempts: the number of login attempts that have been made
- @type loginAttempts: C{int}
- @ivar passwordDelay: the number of seconds to delay when the user gives
- an incorrect password
- @type passwordDelay: C{int}
- @ivar interfaceToMethod: a C{dict} mapping credential interfaces to
- authentication methods. The server checks to see which of the
- cred interfaces have checkers and tells the client that those methods
- are valid for authentication.
- @type interfaceToMethod: C{dict}
- @ivar supportedAuthentications: A list of the supported authentication
- methods.
- @type supportedAuthentications: C{list} of C{str}
- @ivar user: the last username the client tried to authenticate with
- @type user: C{str}
- @ivar method: the current authentication method
- @type method: C{str}
- @ivar nextService: the service the user wants started after authentication
- has been completed.
- @type nextService: C{str}
- @ivar portal: the L{twisted.cred.portal.Portal} we are using for
- authentication
- @type portal: L{twisted.cred.portal.Portal}
- @ivar clock: an object with a callLater method. Stubbed out for testing.
- """
-
-
- name = 'ssh-userauth'
- loginTimeout = 10 * 60 * 60
- # 10 minutes before we disconnect them
- attemptsBeforeDisconnect = 20
- # 20 login attempts before a disconnect
- passwordDelay = 1 # number of seconds to delay on a failed password
- clock = reactor
- interfaceToMethod = {
- credentials.ISSHPrivateKey : 'publickey',
- credentials.IUsernamePassword : 'password',
- credentials.IPluggableAuthenticationModules : 'keyboard-interactive',
- }
-
-
- def serviceStarted(self):
- """
- Called when the userauth service is started. Set up instance
- variables, check if we should allow password/keyboard-interactive
- authentication (only allow if the outgoing connection is encrypted) and
- set up a login timeout.
- """
- self.authenticatedWith = []
- self.loginAttempts = 0
- self.user = None
- self.nextService = None
- self._pamDeferred = None
- self.portal = self.transport.factory.portal
-
- self.supportedAuthentications = []
- for i in self.portal.listCredentialsInterfaces():
- if i in self.interfaceToMethod:
- self.supportedAuthentications.append(self.interfaceToMethod[i])
-
- if not self.transport.isEncrypted('in'):
- # don't let us transport password in plaintext
- if 'password' in self.supportedAuthentications:
- self.supportedAuthentications.remove('password')
- if 'keyboard-interactive' in self.supportedAuthentications:
- self.supportedAuthentications.remove('keyboard-interactive')
- self._cancelLoginTimeout = self.clock.callLater(
- self.loginTimeout,
- self.timeoutAuthentication)
-
-
- def serviceStopped(self):
- """
- Called when the userauth service is stopped. Cancel the login timeout
- if it's still going.
- """
- if self._cancelLoginTimeout:
- self._cancelLoginTimeout.cancel()
- self._cancelLoginTimeout = None
-
-
- def timeoutAuthentication(self):
- """
- Called when the user has timed out on authentication. Disconnect
- with a DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE message.
- """
- self._cancelLoginTimeout = None
- self.transport.sendDisconnect(
- transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
- 'you took too long')
-
-
- def tryAuth(self, kind, user, data):
- """
- Try to authenticate the user with the given method. Dispatches to a
- auth_* method.
-
- @param kind: the authentication method to try.
- @type kind: C{str}
- @param user: the username the client is authenticating with.
- @type user: C{str}
- @param data: authentication specific data sent by the client.
- @type data: C{str}
- @return: A Deferred called back if the method succeeded, or erred back
- if it failed.
- @rtype: C{defer.Deferred}
- """
- log.msg('%s trying auth %s' % (user, kind))
- if kind not in self.supportedAuthentications:
- return defer.fail(
- error.ConchError('unsupported authentication, failing'))
- kind = kind.replace('-', '_')
- f = getattr(self,'auth_%s'%kind, None)
- if f:
- ret = f(data)
- if not ret:
- return defer.fail(
- error.ConchError('%s return None instead of a Deferred'
- % kind))
- else:
- return ret
- return defer.fail(error.ConchError('bad auth type: %s' % kind))
-
-
- def ssh_USERAUTH_REQUEST(self, packet):
- """
- The client has requested authentication. Payload::
- string user
- string next service
- string method
- <authentication specific data>
-
- @type packet: C{str}
- """
- user, nextService, method, rest = getNS(packet, 3)
- if user != self.user or nextService != self.nextService:
- self.authenticatedWith = [] # clear auth state
- self.user = user
- self.nextService = nextService
- self.method = method
- d = self.tryAuth(method, user, rest)
- if not d:
- self._ebBadAuth(
- failure.Failure(error.ConchError('auth returned none')))
- return
- d.addCallback(self._cbFinishedAuth)
- d.addErrback(self._ebMaybeBadAuth)
- d.addErrback(self._ebBadAuth)
- return d
-
-
- def _cbFinishedAuth(self, (interface, avatar, logout)):
- """
- The callback when user has successfully been authenticated. For a
- description of the arguments, see L{twisted.cred.portal.Portal.login}.
- We start the service requested by the user.
- """
- self.transport.avatar = avatar
- self.transport.logoutFunction = logout
- service = self.transport.factory.getService(self.transport,
- self.nextService)
- if not service:
- raise error.ConchError('could not get next service: %s'
- % self.nextService)
- log.msg('%s authenticated with %s' % (self.user, self.method))
- self.transport.sendPacket(MSG_USERAUTH_SUCCESS, '')
- self.transport.setService(service())
-
-
- def _ebMaybeBadAuth(self, reason):
- """
- An intermediate errback. If the reason is
- error.NotEnoughAuthentication, we send a MSG_USERAUTH_FAILURE, but
- with the partial success indicator set.
-
- @type reason: L{twisted.python.failure.Failure}
- """
- reason.trap(error.NotEnoughAuthentication)
- self.transport.sendPacket(MSG_USERAUTH_FAILURE,
- NS(','.join(self.supportedAuthentications)) + '\xff')
-
-
- def _ebBadAuth(self, reason):
- """
- The final errback in the authentication chain. If the reason is
- error.IgnoreAuthentication, we simply return; the authentication
- method has sent its own response. Otherwise, send a failure message
- and (if the method is not 'none') increment the number of login
- attempts.
-
- @type reason: L{twisted.python.failure.Failure}
- """
- if reason.check(error.IgnoreAuthentication):
- return
- if self.method != 'none':
- log.msg('%s failed auth %s' % (self.user, self.method))
- if reason.check(UnauthorizedLogin):
- log.msg('unauthorized login: %s' % reason.getErrorMessage())
- elif reason.check(error.ConchError):
- log.msg('reason: %s' % reason.getErrorMessage())
- else:
- log.msg(reason.getTraceback())
- self.loginAttempts += 1
- if self.loginAttempts > self.attemptsBeforeDisconnect:
- self.transport.sendDisconnect(
- transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
- 'too many bad auths')
- return
- self.transport.sendPacket(
- MSG_USERAUTH_FAILURE,
- NS(','.join(self.supportedAuthentications)) + '\x00')
-
-
- def auth_publickey(self, packet):
- """
- Public key authentication. Payload::
- byte has signature
- string algorithm name
- string key blob
- [string signature] (if has signature is True)
-
- Create a SSHPublicKey credential and verify it using our portal.
- """
- hasSig = ord(packet[0])
- algName, blob, rest = getNS(packet[1:], 2)
- pubKey = keys.Key.fromString(blob)
- signature = hasSig and getNS(rest)[0] or None
- if hasSig:
- b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) +
- NS(self.user) + NS(self.nextService) + NS('publickey') +
- chr(hasSig) + NS(pubKey.sshType()) + NS(blob))
- c = credentials.SSHPrivateKey(self.user, algName, blob, b,
- signature)
- return self.portal.login(c, None, interfaces.IConchUser)
- else:
- c = credentials.SSHPrivateKey(self.user, algName, blob, None, None)
- return self.portal.login(c, None,
- interfaces.IConchUser).addErrback(self._ebCheckKey,
- packet[1:])
-
-
- def _ebCheckKey(self, reason, packet):
- """
- Called back if the user did not sent a signature. If reason is
- error.ValidPublicKey then this key is valid for the user to
- authenticate with. Send MSG_USERAUTH_PK_OK.
- """
- reason.trap(error.ValidPublicKey)
- # if we make it here, it means that the publickey is valid
- self.transport.sendPacket(MSG_USERAUTH_PK_OK, packet)
- return failure.Failure(error.IgnoreAuthentication())
-
-
- def auth_password(self, packet):
- """
- Password authentication. Payload::
- string password
-
- Make a UsernamePassword credential and verify it with our portal.
- """
- password = getNS(packet[1:])[0]
- c = credentials.UsernamePassword(self.user, password)
- return self.portal.login(c, None, interfaces.IConchUser).addErrback(
- self._ebPassword)
-
-
- def _ebPassword(self, f):
- """
- If the password is invalid, wait before sending the failure in order
- to delay brute-force password guessing.
- """
- d = defer.Deferred()
- self.clock.callLater(self.passwordDelay, d.callback, f)
- return d
-
-
- def auth_keyboard_interactive(self, packet):
- """
- Keyboard interactive authentication. No payload. We create a
- PluggableAuthenticationModules credential and authenticate with our
- portal.
- """
- if self._pamDeferred is not None:
- self.transport.sendDisconnect(
- transport.DISCONNECT_PROTOCOL_ERROR,
- "only one keyboard interactive attempt at a time")
- return defer.fail(error.IgnoreAuthentication())
- c = credentials.PluggableAuthenticationModules(self.user,
- self._pamConv)
- return self.portal.login(c, None, interfaces.IConchUser)
-
-
- def _pamConv(self, items):
- """
- Convert a list of PAM authentication questions into a
- MSG_USERAUTH_INFO_REQUEST. Returns a Deferred that will be called
- back when the user has responses to the questions.
-
- @param items: a list of 2-tuples (message, kind). We only care about
- kinds 1 (password) and 2 (text).
- @type items: C{list}
- @rtype: L{defer.Deferred}
- """
- resp = []
- for message, kind in items:
- if kind == 1: # password
- resp.append((message, 0))
- elif kind == 2: # text
- resp.append((message, 1))
- elif kind in (3, 4):
- return defer.fail(error.ConchError(
- 'cannot handle PAM 3 or 4 messages'))
- else:
- return defer.fail(error.ConchError(
- 'bad PAM auth kind %i' % kind))
- packet = NS('') + NS('') + NS('')
- packet += struct.pack('>L', len(resp))
- for prompt, echo in resp:
- packet += NS(prompt)
- packet += chr(echo)
- self.transport.sendPacket(MSG_USERAUTH_INFO_REQUEST, packet)
- self._pamDeferred = defer.Deferred()
- return self._pamDeferred
-
-
- def ssh_USERAUTH_INFO_RESPONSE(self, packet):
- """
- The user has responded with answers to PAMs authentication questions.
- Parse the packet into a PAM response and callback self._pamDeferred.
- Payload::
- uint32 numer of responses
- string response 1
- ...
- string response n
- """
- d, self._pamDeferred = self._pamDeferred, None
-
- try:
- resp = []
- numResps = struct.unpack('>L', packet[:4])[0]
- packet = packet[4:]
- while len(resp) < numResps:
- response, packet = getNS(packet)
- resp.append((response, 0))
- if packet:
- raise error.ConchError("%i bytes of extra data" % len(packet))
- except:
- d.errback(failure.Failure())
- else:
- d.callback(resp)
-
-
-
-class SSHUserAuthClient(service.SSHService):
- """
- A service implementing the client side of 'ssh-userauth'.
-
- @ivar name: the name of this service: 'ssh-userauth'
- @type name: C{str}
- @ivar preferredOrder: a list of authentication methods we support, in
- order of preference. The client will try authentication methods in
- this order, making callbacks for information when necessary.
- @type preferredOrder: C{list}
- @ivar user: the name of the user to authenticate as
- @type user: C{str}
- @ivar instance: the service to start after authentication has finished
- @type instance: L{service.SSHService}
- @ivar authenticatedWith: a list of strings of authentication methods we've tried
- @type authenticatedWith: C{list} of C{str}
- @ivar triedPublicKeys: a list of public key objects that we've tried to
- authenticate with
- @type triedPublicKeys: C{list} of L{Key}
- @ivar lastPublicKey: the last public key object we've tried to authenticate
- with
- @type lastPublicKey: L{Key}
- """
-
-
- name = 'ssh-userauth'
- preferredOrder = ['publickey', 'password', 'keyboard-interactive']
-
-
- def __init__(self, user, instance):
- self.user = user
- self.instance = instance
-
-
- def serviceStarted(self):
- self.authenticatedWith = []
- self.triedPublicKeys = []
- self.lastPublicKey = None
- self.askForAuth('none', '')
-
-
- def askForAuth(self, kind, extraData):
- """
- Send a MSG_USERAUTH_REQUEST.
-
- @param kind: the authentication method to try.
- @type kind: C{str}
- @param extraData: method-specific data to go in the packet
- @type extraData: C{str}
- """
- self.lastAuth = kind
- self.transport.sendPacket(MSG_USERAUTH_REQUEST, NS(self.user) +
- NS(self.instance.name) + NS(kind) + extraData)
-
-
- def tryAuth(self, kind):
- """
- Dispatch to an authentication method.
-
- @param kind: the authentication method
- @type kind: C{str}
- """
- kind = kind.replace('-', '_')
- log.msg('trying to auth with %s' % (kind,))
- f = getattr(self,'auth_%s' % (kind,), None)
- if f:
- return f()
-
-
- def _ebAuth(self, ignored, *args):
- """
- Generic callback for a failed authentication attempt. Respond by
- asking for the list of accepted methods (the 'none' method)
- """
- self.askForAuth('none', '')
-
-
- def ssh_USERAUTH_SUCCESS(self, packet):
- """
- We received a MSG_USERAUTH_SUCCESS. The server has accepted our
- authentication, so start the next service.
- """
- self.transport.setService(self.instance)
-
-
- def ssh_USERAUTH_FAILURE(self, packet):
- """
- We received a MSG_USERAUTH_FAILURE. Payload::
- string methods
- byte partial success
-
- If partial success is C{True}, then the previous method succeeded but is
- not sufficent for authentication. C{methods} is a comma-separated list
- of accepted authentication methods.
-
- We sort the list of methods by their position in C{self.preferredOrder},
- removing methods that have already succeeded. We then call
- C{self.tryAuth} with the most preferred method.
-
- @param packet: the L{MSG_USERAUTH_FAILURE} payload.
- @type packet: C{str}
-
- @return: a L{defer.Deferred} that will be callbacked with C{None} as
- soon as all authentication methods have been tried, or C{None} if no
- more authentication methods are available.
- @rtype: C{defer.Deferred} or C{None}
- """
- canContinue, partial = getNS(packet)
- partial = ord(partial)
- if partial:
- self.authenticatedWith.append(self.lastAuth)
-
- def orderByPreference(meth):
- """
- Invoked once per authentication method in order to extract a
- comparison key which is then used for sorting.
-
- @param meth: the authentication method.
- @type meth: C{str}
-
- @return: the comparison key for C{meth}.
- @rtype: C{int}
- """
- if meth in self.preferredOrder:
- return self.preferredOrder.index(meth)
- else:
- # put the element at the end of the list.
- return len(self.preferredOrder)
-
- canContinue = sorted([meth for meth in canContinue.split(',')
- if meth not in self.authenticatedWith],
- key=orderByPreference)
-
- log.msg('can continue with: %s' % canContinue)
- return self._cbUserauthFailure(None, iter(canContinue))
-
-
- def _cbUserauthFailure(self, result, iterator):
- if result:
- return
- try:
- method = iterator.next()
- except StopIteration:
- self.transport.sendDisconnect(
- transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
- 'no more authentication methods available')
- else:
- d = defer.maybeDeferred(self.tryAuth, method)
- d.addCallback(self._cbUserauthFailure, iterator)
- return d
-
-
- def ssh_USERAUTH_PK_OK(self, packet):
- """
- This message (number 60) can mean several different messages depending
- on the current authentication type. We dispatch to individual methods
- in order to handle this request.
- """
- func = getattr(self, 'ssh_USERAUTH_PK_OK_%s' %
- self.lastAuth.replace('-', '_'), None)
- if func is not None:
- return func(packet)
- else:
- self.askForAuth('none', '')
-
-
- def ssh_USERAUTH_PK_OK_publickey(self, packet):
- """
- This is MSG_USERAUTH_PK. Our public key is valid, so we create a
- signature and try to authenticate with it.
- """
- publicKey = self.lastPublicKey
- b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) +
- NS(self.user) + NS(self.instance.name) + NS('publickey') +
- '\x01' + NS(publicKey.sshType()) + NS(publicKey.blob()))
- d = self.signData(publicKey, b)
- if not d:
- self.askForAuth('none', '')
- # this will fail, we'll move on
- return
- d.addCallback(self._cbSignedData)
- d.addErrback(self._ebAuth)
-
-
- def ssh_USERAUTH_PK_OK_password(self, packet):
- """
- This is MSG_USERAUTH_PASSWD_CHANGEREQ. The password given has expired.
- We ask for an old password and a new password, then send both back to
- the server.
- """
- prompt, language, rest = getNS(packet, 2)
- self._oldPass = self._newPass = None
- d = self.getPassword('Old Password: ')
- d = d.addCallbacks(self._setOldPass, self._ebAuth)
- d.addCallback(lambda ignored: self.getPassword(prompt))
- d.addCallbacks(self._setNewPass, self._ebAuth)
-
-
- def ssh_USERAUTH_PK_OK_keyboard_interactive(self, packet):
- """
- This is MSG_USERAUTH_INFO_RESPONSE. The server has sent us the
- questions it wants us to answer, so we ask the user and sent the
- responses.
- """
- name, instruction, lang, data = getNS(packet, 3)
- numPrompts = struct.unpack('!L', data[:4])[0]
- data = data[4:]
- prompts = []
- for i in range(numPrompts):
- prompt, data = getNS(data)
- echo = bool(ord(data[0]))
- data = data[1:]
- prompts.append((prompt, echo))
- d = self.getGenericAnswers(name, instruction, prompts)
- d.addCallback(self._cbGenericAnswers)
- d.addErrback(self._ebAuth)
-
-
- def _cbSignedData(self, signedData):
- """
- Called back out of self.signData with the signed data. Send the
- authentication request with the signature.
-
- @param signedData: the data signed by the user's private key.
- @type signedData: C{str}
- """
- publicKey = self.lastPublicKey
- self.askForAuth('publickey', '\x01' + NS(publicKey.sshType()) +
- NS(publicKey.blob()) + NS(signedData))
-
-
- def _setOldPass(self, op):
- """
- Called back when we are choosing a new password. Simply store the old
- password for now.
-
- @param op: the old password as entered by the user
- @type op: C{str}
- """
- self._oldPass = op
-
-
- def _setNewPass(self, np):
- """
- Called back when we are choosing a new password. Get the old password
- and send the authentication message with both.
-
- @param np: the new password as entered by the user
- @type np: C{str}
- """
- op = self._oldPass
- self._oldPass = None
- self.askForAuth('password', '\xff' + NS(op) + NS(np))
-
-
- def _cbGenericAnswers(self, responses):
- """
- Called back when we are finished answering keyboard-interactive
- questions. Send the info back to the server in a
- MSG_USERAUTH_INFO_RESPONSE.
-
- @param responses: a list of C{str} responses
- @type responses: C{list}
- """
- data = struct.pack('!L', len(responses))
- for r in responses:
- data += NS(r.encode('UTF8'))
- self.transport.sendPacket(MSG_USERAUTH_INFO_RESPONSE, data)
-
-
- def auth_publickey(self):
- """
- Try to authenticate with a public key. Ask the user for a public key;
- if the user has one, send the request to the server and return True.
- Otherwise, return False.
-
- @rtype: C{bool}
- """
- d = defer.maybeDeferred(self.getPublicKey)
- d.addBoth(self._cbGetPublicKey)
- return d
-
-
- def _cbGetPublicKey(self, publicKey):
- if isinstance(publicKey, str):
- warnings.warn("Returning a string from "
- "SSHUserAuthClient.getPublicKey() is deprecated "
- "since Twisted 9.0. Return a keys.Key() instead.",
- DeprecationWarning)
- publicKey = keys.Key.fromString(publicKey)
- if not isinstance(publicKey, keys.Key): # failure or None
- publicKey = None
- if publicKey is not None:
- self.lastPublicKey = publicKey
- self.triedPublicKeys.append(publicKey)
- log.msg('using key of type %s' % publicKey.type())
- self.askForAuth('publickey', '\x00' + NS(publicKey.sshType()) +
- NS(publicKey.blob()))
- return True
- else:
- return False
-
-
- def auth_password(self):
- """
- Try to authenticate with a password. Ask the user for a password.
- If the user will return a password, return True. Otherwise, return
- False.
-
- @rtype: C{bool}
- """
- d = self.getPassword()
- if d:
- d.addCallbacks(self._cbPassword, self._ebAuth)
- return True
- else: # returned None, don't do password auth
- return False
-
-
- def auth_keyboard_interactive(self):
- """
- Try to authenticate with keyboard-interactive authentication. Send
- the request to the server and return True.
-
- @rtype: C{bool}
- """
- log.msg('authing with keyboard-interactive')
- self.askForAuth('keyboard-interactive', NS('') + NS(''))
- return True
-
-
- def _cbPassword(self, password):
- """
- Called back when the user gives a password. Send the request to the
- server.
-
- @param password: the password the user entered
- @type password: C{str}
- """
- self.askForAuth('password', '\x00' + NS(password))
-
-
- def signData(self, publicKey, signData):
- """
- Sign the given data with the given public key.
-
- By default, this will call getPrivateKey to get the private key,
- then sign the data using Key.sign().
-
- This method is factored out so that it can be overridden to use
- alternate methods, such as a key agent.
-
- @param publicKey: The public key object returned from L{getPublicKey}
- @type publicKey: L{keys.Key}
-
- @param signData: the data to be signed by the private key.
- @type signData: C{str}
- @return: a Deferred that's called back with the signature
- @rtype: L{defer.Deferred}
- """
- key = self.getPrivateKey()
- if not key:
- return
- return key.addCallback(self._cbSignData, signData)
-
-
- def _cbSignData(self, privateKey, signData):
- """
- Called back when the private key is returned. Sign the data and
- return the signature.
-
- @param privateKey: the private key object
- @type publicKey: L{keys.Key}
- @param signData: the data to be signed by the private key.
- @type signData: C{str}
- @return: the signature
- @rtype: C{str}
- """
- if not isinstance(privateKey, keys.Key):
- warnings.warn("Returning a PyCrypto key object from "
- "SSHUserAuthClient.getPrivateKey() is deprecated "
- "since Twisted 9.0. Return a keys.Key() instead.",
- DeprecationWarning)
- privateKey = keys.Key(privateKey)
- return privateKey.sign(signData)
-
-
- def getPublicKey(self):
- """
- Return a public key for the user. If no more public keys are
- available, return C{None}.
-
- This implementation always returns C{None}. Override it in a
- subclass to actually find and return a public key object.
-
- @rtype: L{Key} or L{NoneType}
- """
- return None
-
-
- def getPrivateKey(self):
- """
- Return a L{Deferred} that will be called back with the private key
- object corresponding to the last public key from getPublicKey().
- If the private key is not available, errback on the Deferred.
-
- @rtype: L{Deferred} called back with L{Key}
- """
- return defer.fail(NotImplementedError())
-
-
- def getPassword(self, prompt = None):
- """
- Return a L{Deferred} that will be called back with a password.
- prompt is a string to display for the password, or None for a generic
- 'user@hostname's password: '.
-
- @type prompt: C{str}/C{None}
- @rtype: L{defer.Deferred}
- """
- return defer.fail(NotImplementedError())
-
-
- def getGenericAnswers(self, name, instruction, prompts):
- """
- Returns a L{Deferred} with the responses to the promopts.
-
- @param name: The name of the authentication currently in progress.
- @param instruction: Describes what the authentication wants.
- @param prompts: A list of (prompt, echo) pairs, where prompt is a
- string to display and echo is a boolean indicating whether the
- user's response should be echoed as they type it.
- """
- return defer.fail(NotImplementedError())
-
-
-MSG_USERAUTH_REQUEST = 50
-MSG_USERAUTH_FAILURE = 51
-MSG_USERAUTH_SUCCESS = 52
-MSG_USERAUTH_BANNER = 53
-MSG_USERAUTH_INFO_RESPONSE = 61
-MSG_USERAUTH_PK_OK = 60
-
-messages = {}
-for k, v in locals().items():
- if k[:4]=='MSG_':
- messages[v] = k
-
-SSHUserAuthServer.protocolMessages = messages
-SSHUserAuthClient.protocolMessages = messages
-del messages
-del v
-
-# Doubles, not included in the protocols' mappings
-MSG_USERAUTH_PASSWD_CHANGEREQ = 60
-MSG_USERAUTH_INFO_REQUEST = 60
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py
deleted file mode 100755
index c45fc3bf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_manhole -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Asynchronous local terminal input handling
-
-@author: Jp Calderone
-"""
-
-import os, tty, sys, termios
-
-from twisted.internet import reactor, stdio, protocol, defer
-from twisted.python import failure, reflect, log
-
-from twisted.conch.insults.insults import ServerProtocol
-from twisted.conch.manhole import ColoredManhole
-
-class UnexpectedOutputError(Exception):
- pass
-
-class TerminalProcessProtocol(protocol.ProcessProtocol):
- def __init__(self, proto):
- self.proto = proto
- self.onConnection = defer.Deferred()
-
- def connectionMade(self):
- self.proto.makeConnection(self)
- self.onConnection.callback(None)
- self.onConnection = None
-
- def write(self, bytes):
- self.transport.write(bytes)
-
- def outReceived(self, bytes):
- self.proto.dataReceived(bytes)
-
- def errReceived(self, bytes):
- self.transport.loseConnection()
- if self.proto is not None:
- self.proto.connectionLost(failure.Failure(UnexpectedOutputError(bytes)))
- self.proto = None
-
- def childConnectionLost(self, childFD):
- if self.proto is not None:
- self.proto.childConnectionLost(childFD)
-
- def processEnded(self, reason):
- if self.proto is not None:
- self.proto.connectionLost(reason)
- self.proto = None
-
-
-
-class ConsoleManhole(ColoredManhole):
- """
- A manhole protocol specifically for use with L{stdio.StandardIO}.
- """
- def connectionLost(self, reason):
- """
- When the connection is lost, there is nothing more to do. Stop the
- reactor so that the process can exit.
- """
- reactor.stop()
-
-
-
-def runWithProtocol(klass):
- fd = sys.__stdin__.fileno()
- oldSettings = termios.tcgetattr(fd)
- tty.setraw(fd)
- try:
- p = ServerProtocol(klass)
- stdio.StandardIO(p)
- reactor.run()
- finally:
- termios.tcsetattr(fd, termios.TCSANOW, oldSettings)
- os.write(fd, "\r\x1bc\r")
-
-
-
-def main(argv=None):
- log.startLogging(file('child.log', 'w'))
-
- if argv is None:
- argv = sys.argv[1:]
- if argv:
- klass = reflect.namedClass(argv[0])
- else:
- klass = ConsoleManhole
- runWithProtocol(klass)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py
deleted file mode 100755
index 7488cc02..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_tap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support module for making SSH servers with twistd.
-"""
-
-from twisted.conch import unix
-from twisted.conch import checkers as conch_checkers
-from twisted.conch.openssh_compat import factory
-from twisted.cred import portal, checkers, strcred
-from twisted.python import usage
-from twisted.application import strports
-try:
- from twisted.cred import pamauth
-except ImportError:
- pamauth = None
-
-
-
-class Options(usage.Options, strcred.AuthOptionMixin):
- synopsis = "[-i <interface>] [-p <port>] [-d <dir>] "
- longdesc = ("Makes a Conch SSH server. If no authentication methods are "
- "specified, the default authentication methods are UNIX passwords, "
- "SSH public keys, and PAM if it is available. If --auth options are "
- "passed, only the measures specified will be used.")
- optParameters = [
- ["interface", "i", "", "local interface to which we listen"],
- ["port", "p", "tcp:22", "Port on which to listen"],
- ["data", "d", "/etc", "directory to look for host keys in"],
- ["moduli", "", None, "directory to look for moduli in "
- "(if different from --data)"]
- ]
- compData = usage.Completions(
- optActions={"data": usage.CompleteDirs(descr="data directory"),
- "moduli": usage.CompleteDirs(descr="moduli directory"),
- "interface": usage.CompleteNetInterfaces()}
- )
-
-
- def __init__(self, *a, **kw):
- usage.Options.__init__(self, *a, **kw)
-
- # call the default addCheckers (for backwards compatibility) that will
- # be used if no --auth option is provided - note that conch's
- # UNIXPasswordDatabase is used, instead of twisted.plugins.cred_unix's
- # checker
- super(Options, self).addChecker(conch_checkers.UNIXPasswordDatabase())
- super(Options, self).addChecker(conch_checkers.SSHPublicKeyDatabase())
- if pamauth is not None:
- super(Options, self).addChecker(
- checkers.PluggableAuthenticationModulesChecker())
-
-
- def addChecker(self, checker):
- """
- If addChecker is called, clear out the default checkers first
- """
- self['credCheckers'] = []
- self['credInterfaces'] = {}
- super(Options, self).addChecker(checker)
-
-
-
-def makeService(config):
- """
- Construct a service for operating a SSH server.
-
- @param config: An L{Options} instance specifying server options, including
- where server keys are stored and what authentication methods to use.
-
- @return: An L{IService} provider which contains the requested SSH server.
- """
-
- t = factory.OpenSSHFactory()
-
- r = unix.UnixSSHRealm()
- t.portal = portal.Portal(r, config.get('credCheckers', []))
- t.dataRoot = config['data']
- t.moduliRoot = config['moduli'] or config['data']
-
- port = config['port']
- if config['interface']:
- # Add warning here
- port += ':interface=' + config['interface']
- return strports.service(port, t)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py
deleted file mode 100755
index c90fe1a2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py
+++ /dev/null
@@ -1,1086 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_telnet -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Telnet protocol implementation.
-
-@author: Jean-Paul Calderone
-"""
-
-import struct
-
-from zope.interface import implements
-
-from twisted.internet import protocol, interfaces as iinternet, defer
-from twisted.python import log
-
-MODE = chr(1)
-EDIT = 1
-TRAPSIG = 2
-MODE_ACK = 4
-SOFT_TAB = 8
-LIT_ECHO = 16
-
-# Characters gleaned from the various (and conflicting) RFCs. Not all of these are correct.
-
-NULL = chr(0) # No operation.
-BEL = chr(7) # Produces an audible or
- # visible signal (which does
- # NOT move the print head).
-BS = chr(8) # Moves the print head one
- # character position towards
- # the left margin.
-HT = chr(9) # Moves the printer to the
- # next horizontal tab stop.
- # It remains unspecified how
- # either party determines or
- # establishes where such tab
- # stops are located.
-LF = chr(10) # Moves the printer to the
- # next print line, keeping the
- # same horizontal position.
-VT = chr(11) # Moves the printer to the
- # next vertical tab stop. It
- # remains unspecified how
- # either party determines or
- # establishes where such tab
- # stops are located.
-FF = chr(12) # Moves the printer to the top
- # of the next page, keeping
- # the same horizontal position.
-CR = chr(13) # Moves the printer to the left
- # margin of the current line.
-
-ECHO = chr(1) # User-to-Server: Asks the server to send
- # Echos of the transmitted data.
-SGA = chr(3) # Suppress Go Ahead. Go Ahead is silly
- # and most modern servers should suppress
- # it.
-NAWS = chr(31) # Negotiate About Window Size. Indicate that
- # information about the size of the terminal
- # can be communicated.
-LINEMODE = chr(34) # Allow line buffering to be
- # negotiated about.
-
-SE = chr(240) # End of subnegotiation parameters.
-NOP = chr(241) # No operation.
-DM = chr(242) # "Data Mark": The data stream portion
- # of a Synch. This should always be
- # accompanied by a TCP Urgent
- # notification.
-BRK = chr(243) # NVT character Break.
-IP = chr(244) # The function Interrupt Process.
-AO = chr(245) # The function Abort Output
-AYT = chr(246) # The function Are You There.
-EC = chr(247) # The function Erase Character.
-EL = chr(248) # The function Erase Line
-GA = chr(249) # The Go Ahead signal.
-SB = chr(250) # Indicates that what follows is
- # subnegotiation of the indicated
- # option.
-WILL = chr(251) # Indicates the desire to begin
- # performing, or confirmation that
- # you are now performing, the
- # indicated option.
-WONT = chr(252) # Indicates the refusal to perform,
- # or continue performing, the
- # indicated option.
-DO = chr(253) # Indicates the request that the
- # other party perform, or
- # confirmation that you are expecting
- # the other party to perform, the
- # indicated option.
-DONT = chr(254) # Indicates the demand that the
- # other party stop performing,
- # or confirmation that you are no
- # longer expecting the other party
- # to perform, the indicated option.
-IAC = chr(255) # Data Byte 255. Introduces a
- # telnet command.
-
-LINEMODE_MODE = chr(1)
-LINEMODE_EDIT = chr(1)
-LINEMODE_TRAPSIG = chr(2)
-LINEMODE_MODE_ACK = chr(4)
-LINEMODE_SOFT_TAB = chr(8)
-LINEMODE_LIT_ECHO = chr(16)
-LINEMODE_FORWARDMASK = chr(2)
-LINEMODE_SLC = chr(3)
-LINEMODE_SLC_SYNCH = chr(1)
-LINEMODE_SLC_BRK = chr(2)
-LINEMODE_SLC_IP = chr(3)
-LINEMODE_SLC_AO = chr(4)
-LINEMODE_SLC_AYT = chr(5)
-LINEMODE_SLC_EOR = chr(6)
-LINEMODE_SLC_ABORT = chr(7)
-LINEMODE_SLC_EOF = chr(8)
-LINEMODE_SLC_SUSP = chr(9)
-LINEMODE_SLC_EC = chr(10)
-LINEMODE_SLC_EL = chr(11)
-
-LINEMODE_SLC_EW = chr(12)
-LINEMODE_SLC_RP = chr(13)
-LINEMODE_SLC_LNEXT = chr(14)
-LINEMODE_SLC_XON = chr(15)
-LINEMODE_SLC_XOFF = chr(16)
-LINEMODE_SLC_FORW1 = chr(17)
-LINEMODE_SLC_FORW2 = chr(18)
-LINEMODE_SLC_MCL = chr(19)
-LINEMODE_SLC_MCR = chr(20)
-LINEMODE_SLC_MCWL = chr(21)
-LINEMODE_SLC_MCWR = chr(22)
-LINEMODE_SLC_MCBOL = chr(23)
-LINEMODE_SLC_MCEOL = chr(24)
-LINEMODE_SLC_INSRT = chr(25)
-LINEMODE_SLC_OVER = chr(26)
-LINEMODE_SLC_ECR = chr(27)
-LINEMODE_SLC_EWR = chr(28)
-LINEMODE_SLC_EBOL = chr(29)
-LINEMODE_SLC_EEOL = chr(30)
-
-LINEMODE_SLC_DEFAULT = chr(3)
-LINEMODE_SLC_VALUE = chr(2)
-LINEMODE_SLC_CANTCHANGE = chr(1)
-LINEMODE_SLC_NOSUPPORT = chr(0)
-LINEMODE_SLC_LEVELBITS = chr(3)
-
-LINEMODE_SLC_ACK = chr(128)
-LINEMODE_SLC_FLUSHIN = chr(64)
-LINEMODE_SLC_FLUSHOUT = chr(32)
-LINEMODE_EOF = chr(236)
-LINEMODE_SUSP = chr(237)
-LINEMODE_ABORT = chr(238)
-
-class ITelnetProtocol(iinternet.IProtocol):
- def unhandledCommand(command, argument):
- """A command was received but not understood.
-
- @param command: the command received.
- @type command: C{str}, a single character.
- @param argument: the argument to the received command.
- @type argument: C{str}, a single character, or None if the command that
- was unhandled does not provide an argument.
- """
-
- def unhandledSubnegotiation(command, bytes):
- """A subnegotiation command was received but not understood.
-
- @param command: the command being subnegotiated. That is, the first
- byte after the SB command.
- @type command: C{str}, a single character.
- @param bytes: all other bytes of the subneogation. That is, all but the
- first bytes between SB and SE, with IAC un-escaping applied.
- @type bytes: C{list} of C{str}, each a single character
- """
-
- def enableLocal(option):
- """Enable the given option locally.
-
- This should enable the given option on this side of the
- telnet connection and return True. If False is returned,
- the option will be treated as still disabled and the peer
- will be notified.
-
- @param option: the option to be enabled.
- @type option: C{str}, a single character.
- """
-
- def enableRemote(option):
- """Indicate whether the peer should be allowed to enable this option.
-
- Returns True if the peer should be allowed to enable this option,
- False otherwise.
-
- @param option: the option to be enabled.
- @type option: C{str}, a single character.
- """
-
- def disableLocal(option):
- """Disable the given option locally.
-
- Unlike enableLocal, this method cannot fail. The option must be
- disabled.
-
- @param option: the option to be disabled.
- @type option: C{str}, a single character.
- """
-
- def disableRemote(option):
- """Indicate that the peer has disabled this option.
-
- @param option: the option to be disabled.
- @type option: C{str}, a single character.
- """
-
-
-
-class ITelnetTransport(iinternet.ITransport):
- def do(option):
- """
- Indicate a desire for the peer to begin performing the given option.
-
- Returns a Deferred that fires with True when the peer begins performing
- the option, or fails with L{OptionRefused} when the peer refuses to
- perform it. If the peer is already performing the given option, the
- Deferred will fail with L{AlreadyEnabled}. If a negotiation regarding
- this option is already in progress, the Deferred will fail with
- L{AlreadyNegotiating}.
-
- Note: It is currently possible that this Deferred will never fire,
- if the peer never responds, or if the peer believes the option to
- already be enabled.
- """
-
-
- def dont(option):
- """
- Indicate a desire for the peer to cease performing the given option.
-
- Returns a Deferred that fires with True when the peer ceases performing
- the option. If the peer is not performing the given option, the
- Deferred will fail with L{AlreadyDisabled}. If negotiation regarding
- this option is already in progress, the Deferred will fail with
- L{AlreadyNegotiating}.
-
- Note: It is currently possible that this Deferred will never fire,
- if the peer never responds, or if the peer believes the option to
- already be disabled.
- """
-
-
- def will(option):
- """
- Indicate our willingness to begin performing this option locally.
-
- Returns a Deferred that fires with True when the peer agrees to allow us
- to begin performing this option, or fails with L{OptionRefused} if the
- peer refuses to allow us to begin performing it. If the option is
- already enabled locally, the Deferred will fail with L{AlreadyEnabled}.
- If negotiation regarding this option is already in progress, the
- Deferred will fail with L{AlreadyNegotiating}.
-
- Note: It is currently possible that this Deferred will never fire,
- if the peer never responds, or if the peer believes the option to
- already be enabled.
- """
-
-
- def wont(option):
- """
- Indicate that we will stop performing the given option.
-
- Returns a Deferred that fires with True when the peer acknowledges
- we have stopped performing this option. If the option is already
- disabled locally, the Deferred will fail with L{AlreadyDisabled}.
- If negotiation regarding this option is already in progress,
- the Deferred will fail with L{AlreadyNegotiating}.
-
- Note: It is currently possible that this Deferred will never fire,
- if the peer never responds, or if the peer believes the option to
- already be disabled.
- """
-
-
- def requestNegotiation(about, bytes):
- """
- Send a subnegotiation request.
-
- @param about: A byte indicating the feature being negotiated.
- @param bytes: Any number of bytes containing specific information
- about the negotiation being requested. No values in this string
- need to be escaped, as this function will escape any value which
- requires it.
- """
-
-
-
-class TelnetError(Exception):
- pass
-
-class NegotiationError(TelnetError):
- def __str__(self):
- return self.__class__.__module__ + '.' + self.__class__.__name__ + ':' + repr(self.args[0])
-
-class OptionRefused(NegotiationError):
- pass
-
-class AlreadyEnabled(NegotiationError):
- pass
-
-class AlreadyDisabled(NegotiationError):
- pass
-
-class AlreadyNegotiating(NegotiationError):
- pass
-
-class TelnetProtocol(protocol.Protocol):
- implements(ITelnetProtocol)
-
- def unhandledCommand(self, command, argument):
- pass
-
- def unhandledSubnegotiation(self, command, bytes):
- pass
-
- def enableLocal(self, option):
- pass
-
- def enableRemote(self, option):
- pass
-
- def disableLocal(self, option):
- pass
-
- def disableRemote(self, option):
- pass
-
-
-class Telnet(protocol.Protocol):
- """
- @ivar commandMap: A mapping of bytes to callables. When a
- telnet command is received, the command byte (the first byte
- after IAC) is looked up in this dictionary. If a callable is
- found, it is invoked with the argument of the command, or None
- if the command takes no argument. Values should be added to
- this dictionary if commands wish to be handled. By default,
- only WILL, WONT, DO, and DONT are handled. These should not
- be overridden, as this class handles them correctly and
- provides an API for interacting with them.
-
- @ivar negotiationMap: A mapping of bytes to callables. When
- a subnegotiation command is received, the command byte (the
- first byte after SB) is looked up in this dictionary. If
- a callable is found, it is invoked with the argument of the
- subnegotiation. Values should be added to this dictionary if
- subnegotiations are to be handled. By default, no values are
- handled.
-
- @ivar options: A mapping of option bytes to their current
- state. This state is likely of little use to user code.
- Changes should not be made to it.
-
- @ivar state: A string indicating the current parse state. It
- can take on the values "data", "escaped", "command", "newline",
- "subnegotiation", and "subnegotiation-escaped". Changes
- should not be made to it.
-
- @ivar transport: This protocol's transport object.
- """
-
- # One of a lot of things
- state = 'data'
-
- def __init__(self):
- self.options = {}
- self.negotiationMap = {}
- self.commandMap = {
- WILL: self.telnet_WILL,
- WONT: self.telnet_WONT,
- DO: self.telnet_DO,
- DONT: self.telnet_DONT}
-
- def _write(self, bytes):
- self.transport.write(bytes)
-
- class _OptionState:
- """
- Represents the state of an option on both sides of a telnet
- connection.
-
- @ivar us: The state of the option on this side of the connection.
-
- @ivar him: The state of the option on the other side of the
- connection.
- """
- class _Perspective:
- """
- Represents the state of an option on side of the telnet
- connection. Some options can be enabled on a particular side of
- the connection (RFC 1073 for example: only the client can have
- NAWS enabled). Other options can be enabled on either or both
- sides (such as RFC 1372: each side can have its own flow control
- state).
-
- @ivar state: C{'yes'} or C{'no'} indicating whether or not this
- option is enabled on one side of the connection.
-
- @ivar negotiating: A boolean tracking whether negotiation about
- this option is in progress.
-
- @ivar onResult: When negotiation about this option has been
- initiated by this side of the connection, a L{Deferred}
- which will fire with the result of the negotiation. C{None}
- at other times.
- """
- state = 'no'
- negotiating = False
- onResult = None
-
- def __str__(self):
- return self.state + ('*' * self.negotiating)
-
- def __init__(self):
- self.us = self._Perspective()
- self.him = self._Perspective()
-
- def __repr__(self):
- return '<_OptionState us=%s him=%s>' % (self.us, self.him)
-
- def getOptionState(self, opt):
- return self.options.setdefault(opt, self._OptionState())
-
- def _do(self, option):
- self._write(IAC + DO + option)
-
- def _dont(self, option):
- self._write(IAC + DONT + option)
-
- def _will(self, option):
- self._write(IAC + WILL + option)
-
- def _wont(self, option):
- self._write(IAC + WONT + option)
-
- def will(self, option):
- """Indicate our willingness to enable an option.
- """
- s = self.getOptionState(option)
- if s.us.negotiating or s.him.negotiating:
- return defer.fail(AlreadyNegotiating(option))
- elif s.us.state == 'yes':
- return defer.fail(AlreadyEnabled(option))
- else:
- s.us.negotiating = True
- s.us.onResult = d = defer.Deferred()
- self._will(option)
- return d
-
- def wont(self, option):
- """Indicate we are not willing to enable an option.
- """
- s = self.getOptionState(option)
- if s.us.negotiating or s.him.negotiating:
- return defer.fail(AlreadyNegotiating(option))
- elif s.us.state == 'no':
- return defer.fail(AlreadyDisabled(option))
- else:
- s.us.negotiating = True
- s.us.onResult = d = defer.Deferred()
- self._wont(option)
- return d
-
- def do(self, option):
- s = self.getOptionState(option)
- if s.us.negotiating or s.him.negotiating:
- return defer.fail(AlreadyNegotiating(option))
- elif s.him.state == 'yes':
- return defer.fail(AlreadyEnabled(option))
- else:
- s.him.negotiating = True
- s.him.onResult = d = defer.Deferred()
- self._do(option)
- return d
-
- def dont(self, option):
- s = self.getOptionState(option)
- if s.us.negotiating or s.him.negotiating:
- return defer.fail(AlreadyNegotiating(option))
- elif s.him.state == 'no':
- return defer.fail(AlreadyDisabled(option))
- else:
- s.him.negotiating = True
- s.him.onResult = d = defer.Deferred()
- self._dont(option)
- return d
-
-
- def requestNegotiation(self, about, bytes):
- """
- Send a negotiation message for the option C{about} with C{bytes} as the
- payload.
-
- @see: L{ITelnetTransport.requestNegotiation}
- """
- bytes = bytes.replace(IAC, IAC * 2)
- self._write(IAC + SB + about + bytes + IAC + SE)
-
-
- def dataReceived(self, data):
- appDataBuffer = []
-
- for b in data:
- if self.state == 'data':
- if b == IAC:
- self.state = 'escaped'
- elif b == '\r':
- self.state = 'newline'
- else:
- appDataBuffer.append(b)
- elif self.state == 'escaped':
- if b == IAC:
- appDataBuffer.append(b)
- self.state = 'data'
- elif b == SB:
- self.state = 'subnegotiation'
- self.commands = []
- elif b in (NOP, DM, BRK, IP, AO, AYT, EC, EL, GA):
- self.state = 'data'
- if appDataBuffer:
- self.applicationDataReceived(''.join(appDataBuffer))
- del appDataBuffer[:]
- self.commandReceived(b, None)
- elif b in (WILL, WONT, DO, DONT):
- self.state = 'command'
- self.command = b
- else:
- raise ValueError("Stumped", b)
- elif self.state == 'command':
- self.state = 'data'
- command = self.command
- del self.command
- if appDataBuffer:
- self.applicationDataReceived(''.join(appDataBuffer))
- del appDataBuffer[:]
- self.commandReceived(command, b)
- elif self.state == 'newline':
- self.state = 'data'
- if b == '\n':
- appDataBuffer.append('\n')
- elif b == '\0':
- appDataBuffer.append('\r')
- elif b == IAC:
- # IAC isn't really allowed after \r, according to the
- # RFC, but handling it this way is less surprising than
- # delivering the IAC to the app as application data.
- # The purpose of the restriction is to allow terminals
- # to unambiguously interpret the behavior of the CR
- # after reading only one more byte. CR LF is supposed
- # to mean one thing (cursor to next line, first column),
- # CR NUL another (cursor to first column). Absent the
- # NUL, it still makes sense to interpret this as CR and
- # then apply all the usual interpretation to the IAC.
- appDataBuffer.append('\r')
- self.state = 'escaped'
- else:
- appDataBuffer.append('\r' + b)
- elif self.state == 'subnegotiation':
- if b == IAC:
- self.state = 'subnegotiation-escaped'
- else:
- self.commands.append(b)
- elif self.state == 'subnegotiation-escaped':
- if b == SE:
- self.state = 'data'
- commands = self.commands
- del self.commands
- if appDataBuffer:
- self.applicationDataReceived(''.join(appDataBuffer))
- del appDataBuffer[:]
- self.negotiate(commands)
- else:
- self.state = 'subnegotiation'
- self.commands.append(b)
- else:
- raise ValueError("How'd you do this?")
-
- if appDataBuffer:
- self.applicationDataReceived(''.join(appDataBuffer))
-
-
- def connectionLost(self, reason):
- for state in self.options.values():
- if state.us.onResult is not None:
- d = state.us.onResult
- state.us.onResult = None
- d.errback(reason)
- if state.him.onResult is not None:
- d = state.him.onResult
- state.him.onResult = None
- d.errback(reason)
-
- def applicationDataReceived(self, bytes):
- """Called with application-level data.
- """
-
- def unhandledCommand(self, command, argument):
- """Called for commands for which no handler is installed.
- """
-
- def commandReceived(self, command, argument):
- cmdFunc = self.commandMap.get(command)
- if cmdFunc is None:
- self.unhandledCommand(command, argument)
- else:
- cmdFunc(argument)
-
- def unhandledSubnegotiation(self, command, bytes):
- """Called for subnegotiations for which no handler is installed.
- """
-
- def negotiate(self, bytes):
- command, bytes = bytes[0], bytes[1:]
- cmdFunc = self.negotiationMap.get(command)
- if cmdFunc is None:
- self.unhandledSubnegotiation(command, bytes)
- else:
- cmdFunc(bytes)
-
- def telnet_WILL(self, option):
- s = self.getOptionState(option)
- self.willMap[s.him.state, s.him.negotiating](self, s, option)
-
- def will_no_false(self, state, option):
- # He is unilaterally offering to enable an option.
- if self.enableRemote(option):
- state.him.state = 'yes'
- self._do(option)
- else:
- self._dont(option)
-
- def will_no_true(self, state, option):
- # Peer agreed to enable an option in response to our request.
- state.him.state = 'yes'
- state.him.negotiating = False
- d = state.him.onResult
- state.him.onResult = None
- d.callback(True)
- assert self.enableRemote(option), "enableRemote must return True in this context (for option %r)" % (option,)
-
- def will_yes_false(self, state, option):
- # He is unilaterally offering to enable an already-enabled option.
- # Ignore this.
- pass
-
- def will_yes_true(self, state, option):
- # This is a bogus state. It is here for completeness. It will
- # never be entered.
- assert False, "will_yes_true can never be entered, but was called with %r, %r" % (state, option)
-
- willMap = {('no', False): will_no_false, ('no', True): will_no_true,
- ('yes', False): will_yes_false, ('yes', True): will_yes_true}
-
- def telnet_WONT(self, option):
- s = self.getOptionState(option)
- self.wontMap[s.him.state, s.him.negotiating](self, s, option)
-
- def wont_no_false(self, state, option):
- # He is unilaterally demanding that an already-disabled option be/remain disabled.
- # Ignore this (although we could record it and refuse subsequent enable attempts
- # from our side - he can always refuse them again though, so we won't)
- pass
-
- def wont_no_true(self, state, option):
- # Peer refused to enable an option in response to our request.
- state.him.negotiating = False
- d = state.him.onResult
- state.him.onResult = None
- d.errback(OptionRefused(option))
-
- def wont_yes_false(self, state, option):
- # Peer is unilaterally demanding that an option be disabled.
- state.him.state = 'no'
- self.disableRemote(option)
- self._dont(option)
-
- def wont_yes_true(self, state, option):
- # Peer agreed to disable an option at our request.
- state.him.state = 'no'
- state.him.negotiating = False
- d = state.him.onResult
- state.him.onResult = None
- d.callback(True)
- self.disableRemote(option)
-
- wontMap = {('no', False): wont_no_false, ('no', True): wont_no_true,
- ('yes', False): wont_yes_false, ('yes', True): wont_yes_true}
-
- def telnet_DO(self, option):
- s = self.getOptionState(option)
- self.doMap[s.us.state, s.us.negotiating](self, s, option)
-
- def do_no_false(self, state, option):
- # Peer is unilaterally requesting that we enable an option.
- if self.enableLocal(option):
- state.us.state = 'yes'
- self._will(option)
- else:
- self._wont(option)
-
- def do_no_true(self, state, option):
- # Peer agreed to allow us to enable an option at our request.
- state.us.state = 'yes'
- state.us.negotiating = False
- d = state.us.onResult
- state.us.onResult = None
- d.callback(True)
- self.enableLocal(option)
-
- def do_yes_false(self, state, option):
- # Peer is unilaterally requesting us to enable an already-enabled option.
- # Ignore this.
- pass
-
- def do_yes_true(self, state, option):
- # This is a bogus state. It is here for completeness. It will never be
- # entered.
- assert False, "do_yes_true can never be entered, but was called with %r, %r" % (state, option)
-
- doMap = {('no', False): do_no_false, ('no', True): do_no_true,
- ('yes', False): do_yes_false, ('yes', True): do_yes_true}
-
- def telnet_DONT(self, option):
- s = self.getOptionState(option)
- self.dontMap[s.us.state, s.us.negotiating](self, s, option)
-
- def dont_no_false(self, state, option):
- # Peer is unilaterally demanding us to disable an already-disabled option.
- # Ignore this.
- pass
-
- def dont_no_true(self, state, option):
- # Offered option was refused. Fail the Deferred returned by the
- # previous will() call.
- state.us.negotiating = False
- d = state.us.onResult
- state.us.onResult = None
- d.errback(OptionRefused(option))
-
- def dont_yes_false(self, state, option):
- # Peer is unilaterally demanding we disable an option.
- state.us.state = 'no'
- self.disableLocal(option)
- self._wont(option)
-
- def dont_yes_true(self, state, option):
- # Peer acknowledged our notice that we will disable an option.
- state.us.state = 'no'
- state.us.negotiating = False
- d = state.us.onResult
- state.us.onResult = None
- d.callback(True)
- self.disableLocal(option)
-
- dontMap = {('no', False): dont_no_false, ('no', True): dont_no_true,
- ('yes', False): dont_yes_false, ('yes', True): dont_yes_true}
-
- def enableLocal(self, option):
- """
- Reject all attempts to enable options.
- """
- return False
-
-
- def enableRemote(self, option):
- """
- Reject all attempts to enable options.
- """
- return False
-
-
- def disableLocal(self, option):
- """
- Signal a programming error by raising an exception.
-
- L{enableLocal} must return true for the given value of C{option} in
- order for this method to be called. If a subclass of L{Telnet}
- overrides enableLocal to allow certain options to be enabled, it must
- also override disableLocal to disable those options.
-
- @raise NotImplementedError: Always raised.
- """
- raise NotImplementedError(
- "Don't know how to disable local telnet option %r" % (option,))
-
-
- def disableRemote(self, option):
- """
- Signal a programming error by raising an exception.
-
- L{enableRemote} must return true for the given value of C{option} in
- order for this method to be called. If a subclass of L{Telnet}
- overrides enableRemote to allow certain options to be enabled, it must
- also override disableRemote tto disable those options.
-
- @raise NotImplementedError: Always raised.
- """
- raise NotImplementedError(
- "Don't know how to disable remote telnet option %r" % (option,))
-
-
-
-class ProtocolTransportMixin:
- def write(self, bytes):
- self.transport.write(bytes.replace('\n', '\r\n'))
-
- def writeSequence(self, seq):
- self.transport.writeSequence(seq)
-
- def loseConnection(self):
- self.transport.loseConnection()
-
- def getHost(self):
- return self.transport.getHost()
-
- def getPeer(self):
- return self.transport.getPeer()
-
-class TelnetTransport(Telnet, ProtocolTransportMixin):
- """
- @ivar protocol: An instance of the protocol to which this
- transport is connected, or None before the connection is
- established and after it is lost.
-
- @ivar protocolFactory: A callable which returns protocol instances
- which provide L{ITelnetProtocol}. This will be invoked when a
- connection is established. It is passed *protocolArgs and
- **protocolKwArgs.
-
- @ivar protocolArgs: A tuple of additional arguments to
- pass to protocolFactory.
-
- @ivar protocolKwArgs: A dictionary of additional arguments
- to pass to protocolFactory.
- """
-
- disconnecting = False
-
- protocolFactory = None
- protocol = None
-
- def __init__(self, protocolFactory=None, *a, **kw):
- Telnet.__init__(self)
- if protocolFactory is not None:
- self.protocolFactory = protocolFactory
- self.protocolArgs = a
- self.protocolKwArgs = kw
-
- def connectionMade(self):
- if self.protocolFactory is not None:
- self.protocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs)
- assert ITelnetProtocol.providedBy(self.protocol)
- try:
- factory = self.factory
- except AttributeError:
- pass
- else:
- self.protocol.factory = factory
- self.protocol.makeConnection(self)
-
- def connectionLost(self, reason):
- Telnet.connectionLost(self, reason)
- if self.protocol is not None:
- try:
- self.protocol.connectionLost(reason)
- finally:
- del self.protocol
-
- def enableLocal(self, option):
- return self.protocol.enableLocal(option)
-
- def enableRemote(self, option):
- return self.protocol.enableRemote(option)
-
- def disableLocal(self, option):
- return self.protocol.disableLocal(option)
-
- def disableRemote(self, option):
- return self.protocol.disableRemote(option)
-
- def unhandledSubnegotiation(self, command, bytes):
- self.protocol.unhandledSubnegotiation(command, bytes)
-
- def unhandledCommand(self, command, argument):
- self.protocol.unhandledCommand(command, argument)
-
- def applicationDataReceived(self, bytes):
- self.protocol.dataReceived(bytes)
-
- def write(self, data):
- ProtocolTransportMixin.write(self, data.replace('\xff','\xff\xff'))
-
-
-class TelnetBootstrapProtocol(TelnetProtocol, ProtocolTransportMixin):
- implements()
-
- protocol = None
-
- def __init__(self, protocolFactory, *args, **kw):
- self.protocolFactory = protocolFactory
- self.protocolArgs = args
- self.protocolKwArgs = kw
-
- def connectionMade(self):
- self.transport.negotiationMap[NAWS] = self.telnet_NAWS
- self.transport.negotiationMap[LINEMODE] = self.telnet_LINEMODE
-
- for opt in (LINEMODE, NAWS, SGA):
- self.transport.do(opt).addErrback(log.err)
- for opt in (ECHO,):
- self.transport.will(opt).addErrback(log.err)
-
- self.protocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs)
-
- try:
- factory = self.factory
- except AttributeError:
- pass
- else:
- self.protocol.factory = factory
-
- self.protocol.makeConnection(self)
-
- def connectionLost(self, reason):
- if self.protocol is not None:
- try:
- self.protocol.connectionLost(reason)
- finally:
- del self.protocol
-
- def dataReceived(self, data):
- self.protocol.dataReceived(data)
-
- def enableLocal(self, opt):
- if opt == ECHO:
- return True
- elif opt == SGA:
- return True
- else:
- return False
-
- def enableRemote(self, opt):
- if opt == LINEMODE:
- self.transport.requestNegotiation(LINEMODE, MODE + chr(TRAPSIG))
- return True
- elif opt == NAWS:
- return True
- elif opt == SGA:
- return True
- else:
- return False
-
- def telnet_NAWS(self, bytes):
- # NAWS is client -> server *only*. self.protocol will
- # therefore be an ITerminalTransport, the `.protocol'
- # attribute of which will be an ITerminalProtocol. Maybe.
- # You know what, XXX TODO clean this up.
- if len(bytes) == 4:
- width, height = struct.unpack('!HH', ''.join(bytes))
- self.protocol.terminalProtocol.terminalSize(width, height)
- else:
- log.msg("Wrong number of NAWS bytes")
-
-
- linemodeSubcommands = {
- LINEMODE_SLC: 'SLC'}
- def telnet_LINEMODE(self, bytes):
- revmap = {}
- linemodeSubcommand = bytes[0]
- if 0:
- # XXX TODO: This should be enabled to parse linemode subnegotiation.
- getattr(self, 'linemode_' + self.linemodeSubcommands[linemodeSubcommand])(bytes[1:])
-
- def linemode_SLC(self, bytes):
- chunks = zip(*[iter(bytes)]*3)
- for slcFunction, slcValue, slcWhat in chunks:
- # Later, we should parse stuff.
- 'SLC', ord(slcFunction), ord(slcValue), ord(slcWhat)
-
-from twisted.protocols import basic
-
-class StatefulTelnetProtocol(basic.LineReceiver, TelnetProtocol):
- delimiter = '\n'
-
- state = 'Discard'
-
- def connectionLost(self, reason):
- basic.LineReceiver.connectionLost(self, reason)
- TelnetProtocol.connectionLost(self, reason)
-
- def lineReceived(self, line):
- oldState = self.state
- newState = getattr(self, "telnet_" + oldState)(line)
- if newState is not None:
- if self.state == oldState:
- self.state = newState
- else:
- log.msg("Warning: state changed and new state returned")
-
- def telnet_Discard(self, line):
- pass
-
-from twisted.cred import credentials
-
-class AuthenticatingTelnetProtocol(StatefulTelnetProtocol):
- """A protocol which prompts for credentials and attempts to authenticate them.
-
- Username and password prompts are given (the password is obscured). When the
- information is collected, it is passed to a portal and an avatar implementing
- L{ITelnetProtocol} is requested. If an avatar is returned, it connected to this
- protocol's transport, and this protocol's transport is connected to it.
- Otherwise, the user is re-prompted for credentials.
- """
-
- state = "User"
- protocol = None
-
- def __init__(self, portal):
- self.portal = portal
-
- def connectionMade(self):
- self.transport.write("Username: ")
-
- def connectionLost(self, reason):
- StatefulTelnetProtocol.connectionLost(self, reason)
- if self.protocol is not None:
- try:
- self.protocol.connectionLost(reason)
- self.logout()
- finally:
- del self.protocol, self.logout
-
- def telnet_User(self, line):
- self.username = line
- self.transport.will(ECHO)
- self.transport.write("Password: ")
- return 'Password'
-
- def telnet_Password(self, line):
- username, password = self.username, line
- del self.username
- def login(ignored):
- creds = credentials.UsernamePassword(username, password)
- d = self.portal.login(creds, None, ITelnetProtocol)
- d.addCallback(self._cbLogin)
- d.addErrback(self._ebLogin)
- self.transport.wont(ECHO).addCallback(login)
- return 'Discard'
-
- def _cbLogin(self, ial):
- interface, protocol, logout = ial
- assert interface is ITelnetProtocol
- self.protocol = protocol
- self.logout = logout
- self.state = 'Command'
-
- protocol.makeConnection(self.transport)
- self.transport.protocol = protocol
-
- def _ebLogin(self, failure):
- self.transport.write("\nAuthentication failed\n")
- self.transport.write("Username: ")
- self.state = "User"
-
-__all__ = [
- # Exceptions
- 'TelnetError', 'NegotiationError', 'OptionRefused',
- 'AlreadyNegotiating', 'AlreadyEnabled', 'AlreadyDisabled',
-
- # Interfaces
- 'ITelnetProtocol', 'ITelnetTransport',
-
- # Other stuff, protocols, etc.
- 'Telnet', 'TelnetProtocol', 'TelnetTransport',
- 'TelnetBootstrapProtocol',
-
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py
deleted file mode 100755
index d09b4122..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-'conch tests'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py
deleted file mode 100755
index 9417ec57..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_keys -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Data used by test_keys as well as others.
-"""
-RSAData = {
- 'n':long('1062486685755247411169438309495398947372127791189432809481'
- '382072971106157632182084539383569281493520117634129557550415277'
- '516685881326038852354459895734875625093273594925884531272867425'
- '864910490065695876046999646807138717162833156501L'),
- 'e':35L,
- 'd':long('6678487739032983727350755088256793383481946116047863373882'
- '973030104095847973715959961839578340816412167985957218887914482'
- '713602371850869127033494910375212470664166001439410214474266799'
- '85974425203903884190893469297150446322896587555L'),
- 'q':long('3395694744258061291019136154000709371890447462086362702627'
- '9704149412726577280741108645721676968699696898960891593323L'),
- 'p':long('3128922844292337321766351031842562691837301298995834258844'
- '4720539204069737532863831050930719431498338835415515173887L')}
-
-DSAData = {
- 'y':long('2300663509295750360093768159135720439490120577534296730713'
- '348508834878775464483169644934425336771277908527130096489120714'
- '610188630979820723924744291603865L'),
- 'g':long('4451569990409370769930903934104221766858515498655655091803'
- '866645719060300558655677517139568505649468378587802312867198352'
- '1161998270001677664063945776405L'),
- 'p':long('7067311773048598659694590252855127633397024017439939353776'
- '608320410518694001356789646664502838652272205440894335303988504'
- '978724817717069039110940675621677L'),
- 'q':1184501645189849666738820838619601267690550087703L,
- 'x':863951293559205482820041244219051653999559962819L}
-
-publicRSA_openssh = ("ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBE"
-"vLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYL"
-"h5KmRpslkYHRivcJSkbh/C+BR3utDS555mV comment")
-
-privateRSA_openssh = """-----BEGIN RSA PRIVATE KEY-----
-MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
-4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
-vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
-Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
-xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
-PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
-gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
-DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
-pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
-EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
------END RSA PRIVATE KEY-----"""
-
-# some versions of OpenSSH generate these (slightly different keys)
-privateRSA_openssh_alternate = """-----BEGIN RSA PRIVATE KEY-----
-MIIBzjCCAcgCAQACYQCvMnHw5g6cmbN/i18ES8uLwNU+snf9z2TYj8DPrh/GMd/2
-KbJEluLG1CGUf2V82NQjH7guaskflA1GwWmitwcMo5PBNNguHkqZGmyWRgdGK9wl
-KRuH8L4FHe60NLnnmZUCASMCYG4ftVWX6+1n7SuZbuzB7ahNUtbz1mUGBN/lVJ/M
-iQA8m2eH7GWgq81vZZCKl5BNxiGPqI3YWYZDtYGxtNdfLCIKYcElikcStJr4ehEc
-SqiLdcSRCTu+BMpF2VeKDSfLIwIxANyfa9mYIVYRjelfA50K05NuE3dBPIVPAHD9
-BVT/vD0Jv4P2l39kEJEE/qJnR1RCawIxAMtKS9BAR+hFUvfHrwwgbUMNtjmU+dql
-5QMGdoMk64ihVaKo3hI7d0mSiqlx0gKT/wIwS6Rffc3CSWUatmm4GJX/Zb9XIZK1
-qgx1Lg2bbZmCXhH4hQQWr1WCBdXTpWU9BvIzAjAXO7DkmaHRZwIq8j/kIPaLUgYy
-d20DC6Uk6su3N2tgEnAv2MjsJA2iAh55w918ozMCMQC0c5dLUBCjF7OoR/E6FHZS
-0TgqzxIUNMGoVEwpNYCgOLjw+kzEwoWr24eCutzr2yowAA==
-------END RSA PRIVATE KEY------"""
-
-# encrypted with the passphrase 'encrypted'
-privateRSA_openssh_encrypted = """-----BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,FFFFFFFFFFFFFFFF
-
-30qUR7DYY/rpVJu159paRM1mUqt/IMibfEMTKWSjNhCVD21hskftZCJROw/WgIFt
-ncusHpJMkjgwEpho0KyKilcC7zxjpunTex24Meb5pCdXCrYft8AyUkRdq3dugMqT
-4nuWuWxziluBhKQ2M9tPGcEOeulU4vVjceZt2pZhZQVBf08o3XUv5/7RYd24M9md
-WIo+5zdj2YQkI6xMFTP954O/X32ME1KQt98wgNEy6mxhItbvf00mH3woALwEKP3v
-PSMxxtx3VKeDKd9YTOm1giKkXZUf91vZWs0378tUBrU4U5qJxgryTjvvVKOtofj6
-4qQy6+r6M6wtwVlXBgeRm2gBPvL3nv6MsROp3E6ztBd/e7A8fSec+UTq3ko/EbGP
-0QG+IG5tg8FsdITxQ9WAIITZL3Rc6hA5Ymx1VNhySp3iSiso8Jof27lku4pyuvRV
-ko/B3N2H7LnQrGV0GyrjeYocW/qZh/PCsY48JBFhlNQexn2mn44AJW3y5xgbhvKA
-3mrmMD1hD17ZvZxi4fPHjbuAyM1vFqhQx63eT9ijbwJ91svKJl5O5MIv41mCRonm
-hxvOXw8S0mjSasyofptzzQCtXxFLQigXbpQBltII+Ys=
------END RSA PRIVATE KEY-----"""
-
-# encrypted with the passphrase 'testxp'. NB: this key was generated by
-# OpenSSH, so it doesn't use the same key data as the other keys here.
-privateRSA_openssh_encrypted_aes = """-----BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-128-CBC,0673309A6ACCAB4B77DEE1C1E536AC26
-
-4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n
-T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H
-g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB
-sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5
-9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV
-gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW
-0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE
-vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS
-hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk
-2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf
-qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk
-4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY
-EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n
-8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0
-fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P
-V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+
-0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5
-xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI
-dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup
-VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk
-gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c
-8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw
-SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7
-CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE
-xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P
------END RSA PRIVATE KEY-----"""
-
-publicRSA_lsh = ("{KDEwOnB1YmxpYy1rZXkoMTQ6cnNhLXBrY3MxLXNoYTEoMTpuOTc6AK8yc"
-"fDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW4sbUIZR/ZXzY1CMfuC5qyR+UDUbB"
-"aaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fwvgUd7rQ0ueeZlSkoMTplMTojKSkp}")
-
-privateRSA_lsh = ("(11:private-key(9:rsa-pkcs1(1:n97:\x00\xaf2q\xf0\xe6\x0e"
-"\x9c\x99\xb3\x7f\x8b_\x04K\xcb\x8b\xc0\xd5>\xb2w\xfd\xcfd\xd8\x8f\xc0\xcf"
-"\xae\x1f\xc61\xdf\xf6)\xb2D\x96\xe2\xc6\xd4!\x94\x7fe|\xd8\xd4#\x1f\xb8.j"
-"\xc9\x1f\x94\rF\xc1i\xa2\xb7\x07\x0c\xa3\x93\xc14\xd8.\x1eJ\x99\x1al\x96F"
-"\x07F+\xdc%)\x1b\x87\xf0\xbe\x05\x1d\xee\xb44\xb9\xe7\x99\x95)(1:e1:#)(1:d9"
-"6:n\x1f\xb5U\x97\xeb\xedg\xed+\x99n\xec\xc1\xed\xa8MR\xd6\xf3\xd6e\x06\x04"
-"\xdf\xe5T\x9f\xcc\x89\x00<\x9bg\x87\xece\xa0\xab\xcdoe\x90\x8a\x97\x90M\xc6"
-'!\x8f\xa8\x8d\xd8Y\x86C\xb5\x81\xb1\xb4\xd7_,"\na\xc1%\x8aG\x12\xb4\x9a\xf8'
-"z\x11\x1cJ\xa8\x8bu\xc4\x91\t;\xbe\x04\xcaE\xd9W\x8a\r\'\xcb#)(1:p49:\x00"
-"\xdc\x9fk\xd9\x98!V\x11\x8d\xe9_\x03\x9d\n\xd3\x93n\x13wA<\x85O\x00p\xfd"
-"\x05T\xff\xbc=\t\xbf\x83\xf6\x97\x7fd\x10\x91\x04\xfe\xa2gGTBk)(1:q49:\x00"
-"\xcbJK\xd0@G\xe8ER\xf7\xc7\xaf\x0c mC\r\xb69\x94\xf9\xda\xa5\xe5\x03\x06v"
-"\x83$\xeb\x88\xa1U\xa2\xa8\xde\x12;wI\x92\x8a\xa9q\xd2\x02\x93\xff)(1:a48:K"
-"\xa4_}\xcd\xc2Ie\x1a\xb6i\xb8\x18\x95\xffe\xbfW!\x92\xb5\xaa\x0cu.\r\x9bm"
-"\x99\x82^\x11\xf8\x85\x04\x16\xafU\x82\x05\xd5\xd3\xa5e=\x06\xf23)(1:b48:"
-"\x17;\xb0\xe4\x99\xa1\xd1g\x02*\xf2?\xe4 \xf6\x8bR\x062wm\x03\x0b\xa5$\xea"
-"\xcb\xb77k`\x12p/\xd8\xc8\xec$\r\xa2\x02\x1ey\xc3\xdd|\xa33)(1:c49:\x00\xb4"
-"s\x97KP\x10\xa3\x17\xb3\xa8G\xf1:\x14vR\xd18*\xcf\x12\x144\xc1\xa8TL)5\x80"
-"\xa08\xb8\xf0\xfaL\xc4\xc2\x85\xab\xdb\x87\x82\xba\xdc\xeb\xdb*)))")
-
-privateRSA_agentv3 = ("\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00`"
-"n\x1f\xb5U\x97\xeb\xedg\xed+\x99n\xec\xc1\xed\xa8MR\xd6\xf3\xd6e\x06\x04"
-"\xdf\xe5T\x9f\xcc\x89\x00<\x9bg\x87\xece\xa0\xab\xcdoe\x90\x8a\x97\x90M\xc6"
-'!\x8f\xa8\x8d\xd8Y\x86C\xb5\x81\xb1\xb4\xd7_,"\na\xc1%\x8aG\x12\xb4\x9a\xf8'
-"z\x11\x1cJ\xa8\x8bu\xc4\x91\t;\xbe\x04\xcaE\xd9W\x8a\r\'\xcb#\x00\x00\x00a"
-"\x00\xaf2q\xf0\xe6\x0e\x9c\x99\xb3\x7f\x8b_\x04K\xcb\x8b\xc0\xd5>\xb2w\xfd"
-"\xcfd\xd8\x8f\xc0\xcf\xae\x1f\xc61\xdf\xf6)\xb2D\x96\xe2\xc6\xd4!\x94\x7fe|"
-"\xd8\xd4#\x1f\xb8.j\xc9\x1f\x94\rF\xc1i\xa2\xb7\x07\x0c\xa3\x93\xc14\xd8."
-"\x1eJ\x99\x1al\x96F\x07F+\xdc%)\x1b\x87\xf0\xbe\x05\x1d\xee\xb44\xb9\xe7"
-"\x99\x95\x00\x00\x001\x00\xb4s\x97KP\x10\xa3\x17\xb3\xa8G\xf1:\x14vR\xd18*"
-"\xcf\x12\x144\xc1\xa8TL)5\x80\xa08\xb8\xf0\xfaL\xc4\xc2\x85\xab\xdb\x87\x82"
-"\xba\xdc\xeb\xdb*\x00\x00\x001\x00\xcbJK\xd0@G\xe8ER\xf7\xc7\xaf\x0c mC\r"
-"\xb69\x94\xf9\xda\xa5\xe5\x03\x06v\x83$\xeb\x88\xa1U\xa2\xa8\xde\x12;wI\x92"
-"\x8a\xa9q\xd2\x02\x93\xff\x00\x00\x001\x00\xdc\x9fk\xd9\x98!V\x11\x8d\xe9_"
-"\x03\x9d\n\xd3\x93n\x13wA<\x85O\x00p\xfd\x05T\xff\xbc=\t\xbf\x83\xf6\x97"
-"\x7fd\x10\x91\x04\xfe\xa2gGTBk")
-
-publicDSA_openssh = ("ssh-dss AAAAB3NzaC1kc3MAAABBAIbwTOSsZ7Bl7U1KyMNqV13Tu7"
-"yRAtTr70PVI3QnfrPumf2UzCgpL1ljbKxSfAi05XvrE/1vfCFAsFYXRZLhQy0AAAAVAM965Akmo"
-"6eAi7K+k9qDR4TotFAXAAAAQADZlpTW964haQWS4vC063NGdldT6xpUGDcDRqbm90CoPEa2RmNO"
-"uOqi8lnbhYraEzypYH3K4Gzv/bxCBnKtHRUAAABAK+1osyWBS0+P90u/rAuko6chZ98thUSY2kL"
-"SHp6hLKyy2bjnT29h7haELE+XHfq2bM9fckDx2FLOSIJzy83VmQ== comment")
-
-privateDSA_openssh = """-----BEGIN DSA PRIVATE KEY-----
-MIH4AgEAAkEAhvBM5KxnsGXtTUrIw2pXXdO7vJEC1OvvQ9UjdCd+s+6Z/ZTMKCkv
-WWNsrFJ8CLTle+sT/W98IUCwVhdFkuFDLQIVAM965Akmo6eAi7K+k9qDR4TotFAX
-AkAA2ZaU1veuIWkFkuLwtOtzRnZXU+saVBg3A0am5vdAqDxGtkZjTrjqovJZ24WK
-2hM8qWB9yuBs7/28QgZyrR0VAkAr7WizJYFLT4/3S7+sC6SjpyFn3y2FRJjaQtIe
-nqEsrLLZuOdPb2HuFoQsT5cd+rZsz19yQPHYUs5IgnPLzdWZAhUAl1TqdmlAG/b4
-nnVchGiO9sML8MM=
------END DSA PRIVATE KEY-----"""
-
-publicDSA_lsh = ("{KDEwOnB1YmxpYy1rZXkoMzpkc2EoMTpwNjU6AIbwTOSsZ7Bl7U1KyMNqV"
-"13Tu7yRAtTr70PVI3QnfrPumf2UzCgpL1ljbKxSfAi05XvrE/1vfCFAsFYXRZLhQy0pKDE6cTIx"
-"OgDPeuQJJqOngIuyvpPag0eE6LRQFykoMTpnNjQ6ANmWlNb3riFpBZLi8LTrc0Z2V1PrGlQYNwN"
-"Gpub3QKg8RrZGY0646qLyWduFitoTPKlgfcrgbO/9vEIGcq0dFSkoMTp5NjQ6K+1osyWBS0+P90"
-"u/rAuko6chZ98thUSY2kLSHp6hLKyy2bjnT29h7haELE+XHfq2bM9fckDx2FLOSIJzy83VmSkpK"
-"Q==}")
-
-privateDSA_lsh = ("(11:private-key(3:dsa(1:p65:\x00\x86\xf0L\xe4\xacg\xb0e"
-"\xedMJ\xc8\xc3jW]\xd3\xbb\xbc\x91\x02\xd4\xeb\xefC\xd5#t'~\xb3\xee\x99\xfd"
-"\x94\xcc()/Ycl\xacR|\x08\xb4\xe5{\xeb\x13\xfdo|!@\xb0V\x17E\x92\xe1C-)(1:q2"
-"1:\x00\xcfz\xe4\t&\xa3\xa7\x80\x8b\xb2\xbe\x93\xda\x83G\x84\xe8\xb4P\x17)(1"
-":g64:\x00\xd9\x96\x94\xd6\xf7\xae!i\x05\x92\xe2\xf0\xb4\xebsFvWS\xeb\x1aT"
-"\x187\x03F\xa6\xe6\xf7@\xa8<F\xb6FcN\xb8\xea\xa2\xf2Y\xdb\x85\x8a\xda\x13<"
-"\xa9`}\xca\xe0l\xef\xfd\xbcB\x06r\xad\x1d\x15)(1:y64:+\xedh\xb3%\x81KO\x8f"
-"\xf7K\xbf\xac\x0b\xa4\xa3\xa7!g\xdf-\x85D\x98\xdaB\xd2\x1e\x9e\xa1,\xac\xb2"
-"\xd9\xb8\xe7Ooa\xee\x16\x84,O\x97\x1d\xfa\xb6l\xcf_r@\xf1\xd8R\xceH\x82s"
-"\xcb\xcd\xd5\x99)(1:x21:\x00\x97T\xeavi@\x1b\xf6\xf8\x9eu\\\x84h\x8e\xf6"
-"\xc3\x0b\xf0\xc3)))")
-
-privateDSA_agentv3 = ("\x00\x00\x00\x07ssh-dss\x00\x00\x00A\x00\x86\xf0L\xe4"
-"\xacg\xb0e\xedMJ\xc8\xc3jW]\xd3\xbb\xbc\x91\x02\xd4\xeb\xefC\xd5#t'~\xb3"
-"\xee\x99\xfd\x94\xcc()/Ycl\xacR|\x08\xb4\xe5{\xeb\x13\xfdo|!@\xb0V\x17E\x92"
-"\xe1C-\x00\x00\x00\x15\x00\xcfz\xe4\t&\xa3\xa7\x80\x8b\xb2\xbe\x93\xda\x83G"
-"\x84\xe8\xb4P\x17\x00\x00\x00@\x00\xd9\x96\x94\xd6\xf7\xae!i\x05\x92\xe2"
-"\xf0\xb4\xebsFvWS\xeb\x1aT\x187\x03F\xa6\xe6\xf7@\xa8<F\xb6FcN\xb8\xea\xa2"
-"\xf2Y\xdb\x85\x8a\xda\x13<\xa9`}\xca\xe0l\xef\xfd\xbcB\x06r\xad\x1d\x15\x00"
-"\x00\x00@+\xedh\xb3%\x81KO\x8f\xf7K\xbf\xac\x0b\xa4\xa3\xa7!g\xdf-\x85D\x98"
-"\xdaB\xd2\x1e\x9e\xa1,\xac\xb2\xd9\xb8\xe7Ooa\xee\x16\x84,O\x97\x1d\xfa\xb6"
-"l\xcf_r@\xf1\xd8R\xceH\x82s\xcb\xcd\xd5\x99\x00\x00\x00\x15\x00\x97T\xeavi@"
-"\x1b\xf6\xf8\x9eu\\\x84h\x8e\xf6\xc3\x0b\xf0\xc3")
-
-__all__ = ['DSAData', 'RSAData', 'privateDSA_agentv3', 'privateDSA_lsh',
- 'privateDSA_openssh', 'privateRSA_agentv3', 'privateRSA_lsh',
- 'privateRSA_openssh', 'publicDSA_lsh', 'publicDSA_openssh',
- 'publicRSA_lsh', 'publicRSA_openssh', 'privateRSA_openssh_alternate']
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py
deleted file mode 100755
index cf02275b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{SSHTransportAddrress} in ssh/address.py
-"""
-
-from twisted.trial import unittest
-from twisted.internet.address import IPv4Address
-from twisted.internet.test.test_address import AddressTestCaseMixin
-
-from twisted.conch.ssh.address import SSHTransportAddress
-
-
-
-class SSHTransportAddressTestCase(unittest.TestCase, AddressTestCaseMixin):
- """
- L{twisted.conch.ssh.address.SSHTransportAddress} is what Conch transports
- use to represent the other side of the SSH connection. This tests the
- basic functionality of that class (string representation, comparison, &c).
- """
-
-
- def _stringRepresentation(self, stringFunction):
- """
- The string representation of C{SSHTransportAddress} should be
- "SSHTransportAddress(<stringFunction on address>)".
- """
- addr = self.buildAddress()
- stringValue = stringFunction(addr)
- addressValue = stringFunction(addr.address)
- self.assertEqual(stringValue,
- "SSHTransportAddress(%s)" % addressValue)
-
-
- def buildAddress(self):
- """
- Create an arbitrary new C{SSHTransportAddress}. A new instance is
- created for each call, but always for the same address.
- """
- return SSHTransportAddress(IPv4Address("TCP", "127.0.0.1", 22))
-
-
- def buildDifferentAddress(self):
- """
- Like C{buildAddress}, but with a different fixed address.
- """
- return SSHTransportAddress(IPv4Address("TCP", "127.0.0.2", 22))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py
deleted file mode 100755
index 532a0e51..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py
+++ /dev/null
@@ -1,399 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.ssh.agent}.
-"""
-
-import struct
-
-from twisted.trial import unittest
-
-try:
- import OpenSSL
-except ImportError:
- iosim = None
-else:
- from twisted.test import iosim
-
-try:
- import Crypto.Cipher.DES3
-except ImportError:
- Crypto = None
-
-try:
- import pyasn1
-except ImportError:
- pyasn1 = None
-
-if Crypto and pyasn1:
- from twisted.conch.ssh import keys, agent
-else:
- keys = agent = None
-
-from twisted.conch.test import keydata
-from twisted.conch.error import ConchError, MissingKeyStoreError
-
-
-class StubFactory(object):
- """
- Mock factory that provides the keys attribute required by the
- SSHAgentServerProtocol
- """
- def __init__(self):
- self.keys = {}
-
-
-
-class AgentTestBase(unittest.TestCase):
- """
- Tests for SSHAgentServer/Client.
- """
- if iosim is None:
- skip = "iosim requires SSL, but SSL is not available"
- elif agent is None or keys is None:
- skip = "Cannot run without PyCrypto or PyASN1"
-
- def setUp(self):
- # wire up our client <-> server
- self.client, self.server, self.pump = iosim.connectedServerAndClient(
- agent.SSHAgentServer, agent.SSHAgentClient)
-
- # the server's end of the protocol is stateful and we store it on the
- # factory, for which we only need a mock
- self.server.factory = StubFactory()
-
- # pub/priv keys of each kind
- self.rsaPrivate = keys.Key.fromString(keydata.privateRSA_openssh)
- self.dsaPrivate = keys.Key.fromString(keydata.privateDSA_openssh)
-
- self.rsaPublic = keys.Key.fromString(keydata.publicRSA_openssh)
- self.dsaPublic = keys.Key.fromString(keydata.publicDSA_openssh)
-
-
-
-class TestServerProtocolContractWithFactory(AgentTestBase):
- """
- The server protocol is stateful and so uses its factory to track state
- across requests. This test asserts that the protocol raises if its factory
- doesn't provide the necessary storage for that state.
- """
- def test_factorySuppliesKeyStorageForServerProtocol(self):
- # need a message to send into the server
- msg = struct.pack('!LB',1, agent.AGENTC_REQUEST_IDENTITIES)
- del self.server.factory.__dict__['keys']
- self.assertRaises(MissingKeyStoreError,
- self.server.dataReceived, msg)
-
-
-
-class TestUnimplementedVersionOneServer(AgentTestBase):
- """
- Tests for methods with no-op implementations on the server. We need these
- for clients, such as openssh, that try v1 methods before going to v2.
-
- Because the client doesn't expose these operations with nice method names,
- we invoke sendRequest directly with an op code.
- """
-
- def test_agentc_REQUEST_RSA_IDENTITIES(self):
- """
- assert that we get the correct op code for an RSA identities request
- """
- d = self.client.sendRequest(agent.AGENTC_REQUEST_RSA_IDENTITIES, '')
- self.pump.flush()
- def _cb(packet):
- self.assertEqual(
- agent.AGENT_RSA_IDENTITIES_ANSWER, ord(packet[0]))
- return d.addCallback(_cb)
-
-
- def test_agentc_REMOVE_RSA_IDENTITY(self):
- """
- assert that we get the correct op code for an RSA remove identity request
- """
- d = self.client.sendRequest(agent.AGENTC_REMOVE_RSA_IDENTITY, '')
- self.pump.flush()
- return d.addCallback(self.assertEqual, '')
-
-
- def test_agentc_REMOVE_ALL_RSA_IDENTITIES(self):
- """
- assert that we get the correct op code for an RSA remove all identities
- request.
- """
- d = self.client.sendRequest(agent.AGENTC_REMOVE_ALL_RSA_IDENTITIES, '')
- self.pump.flush()
- return d.addCallback(self.assertEqual, '')
-
-
-
-if agent is not None:
- class CorruptServer(agent.SSHAgentServer):
- """
- A misbehaving server that returns bogus response op codes so that we can
- verify that our callbacks that deal with these op codes handle such
- miscreants.
- """
- def agentc_REQUEST_IDENTITIES(self, data):
- self.sendResponse(254, '')
-
-
- def agentc_SIGN_REQUEST(self, data):
- self.sendResponse(254, '')
-
-
-
-class TestClientWithBrokenServer(AgentTestBase):
- """
- verify error handling code in the client using a misbehaving server
- """
-
- def setUp(self):
- AgentTestBase.setUp(self)
- self.client, self.server, self.pump = iosim.connectedServerAndClient(
- CorruptServer, agent.SSHAgentClient)
- # the server's end of the protocol is stateful and we store it on the
- # factory, for which we only need a mock
- self.server.factory = StubFactory()
-
-
- def test_signDataCallbackErrorHandling(self):
- """
- Assert that L{SSHAgentClient.signData} raises a ConchError
- if we get a response from the server whose opcode doesn't match
- the protocol for data signing requests.
- """
- d = self.client.signData(self.rsaPublic.blob(), "John Hancock")
- self.pump.flush()
- return self.assertFailure(d, ConchError)
-
-
- def test_requestIdentitiesCallbackErrorHandling(self):
- """
- Assert that L{SSHAgentClient.requestIdentities} raises a ConchError
- if we get a response from the server whose opcode doesn't match
- the protocol for identity requests.
- """
- d = self.client.requestIdentities()
- self.pump.flush()
- return self.assertFailure(d, ConchError)
-
-
-
-class TestAgentKeyAddition(AgentTestBase):
- """
- Test adding different flavors of keys to an agent.
- """
-
- def test_addRSAIdentityNoComment(self):
- """
- L{SSHAgentClient.addIdentity} adds the private key it is called
- with to the SSH agent server to which it is connected, associating
- it with the comment it is called with.
-
- This test asserts that ommitting the comment produces an
- empty string for the comment on the server.
- """
- d = self.client.addIdentity(self.rsaPrivate.privateBlob())
- self.pump.flush()
- def _check(ignored):
- serverKey = self.server.factory.keys[self.rsaPrivate.blob()]
- self.assertEqual(self.rsaPrivate, serverKey[0])
- self.assertEqual('', serverKey[1])
- return d.addCallback(_check)
-
-
- def test_addDSAIdentityNoComment(self):
- """
- L{SSHAgentClient.addIdentity} adds the private key it is called
- with to the SSH agent server to which it is connected, associating
- it with the comment it is called with.
-
- This test asserts that ommitting the comment produces an
- empty string for the comment on the server.
- """
- d = self.client.addIdentity(self.dsaPrivate.privateBlob())
- self.pump.flush()
- def _check(ignored):
- serverKey = self.server.factory.keys[self.dsaPrivate.blob()]
- self.assertEqual(self.dsaPrivate, serverKey[0])
- self.assertEqual('', serverKey[1])
- return d.addCallback(_check)
-
-
- def test_addRSAIdentityWithComment(self):
- """
- L{SSHAgentClient.addIdentity} adds the private key it is called
- with to the SSH agent server to which it is connected, associating
- it with the comment it is called with.
-
- This test asserts that the server receives/stores the comment
- as sent by the client.
- """
- d = self.client.addIdentity(
- self.rsaPrivate.privateBlob(), comment='My special key')
- self.pump.flush()
- def _check(ignored):
- serverKey = self.server.factory.keys[self.rsaPrivate.blob()]
- self.assertEqual(self.rsaPrivate, serverKey[0])
- self.assertEqual('My special key', serverKey[1])
- return d.addCallback(_check)
-
-
- def test_addDSAIdentityWithComment(self):
- """
- L{SSHAgentClient.addIdentity} adds the private key it is called
- with to the SSH agent server to which it is connected, associating
- it with the comment it is called with.
-
- This test asserts that the server receives/stores the comment
- as sent by the client.
- """
- d = self.client.addIdentity(
- self.dsaPrivate.privateBlob(), comment='My special key')
- self.pump.flush()
- def _check(ignored):
- serverKey = self.server.factory.keys[self.dsaPrivate.blob()]
- self.assertEqual(self.dsaPrivate, serverKey[0])
- self.assertEqual('My special key', serverKey[1])
- return d.addCallback(_check)
-
-
-
-class TestAgentClientFailure(AgentTestBase):
- def test_agentFailure(self):
- """
- verify that the client raises ConchError on AGENT_FAILURE
- """
- d = self.client.sendRequest(254, '')
- self.pump.flush()
- return self.assertFailure(d, ConchError)
-
-
-
-class TestAgentIdentityRequests(AgentTestBase):
- """
- Test operations against a server with identities already loaded.
- """
-
- def setUp(self):
- AgentTestBase.setUp(self)
- self.server.factory.keys[self.dsaPrivate.blob()] = (
- self.dsaPrivate, 'a comment')
- self.server.factory.keys[self.rsaPrivate.blob()] = (
- self.rsaPrivate, 'another comment')
-
-
- def test_signDataRSA(self):
- """
- Sign data with an RSA private key and then verify it with the public
- key.
- """
- d = self.client.signData(self.rsaPublic.blob(), "John Hancock")
- self.pump.flush()
- def _check(sig):
- expected = self.rsaPrivate.sign("John Hancock")
- self.assertEqual(expected, sig)
- self.assertTrue(self.rsaPublic.verify(sig, "John Hancock"))
- return d.addCallback(_check)
-
-
- def test_signDataDSA(self):
- """
- Sign data with a DSA private key and then verify it with the public
- key.
- """
- d = self.client.signData(self.dsaPublic.blob(), "John Hancock")
- self.pump.flush()
- def _check(sig):
- # Cannot do this b/c DSA uses random numbers when signing
- # expected = self.dsaPrivate.sign("John Hancock")
- # self.assertEqual(expected, sig)
- self.assertTrue(self.dsaPublic.verify(sig, "John Hancock"))
- return d.addCallback(_check)
-
-
- def test_signDataRSAErrbackOnUnknownBlob(self):
- """
- Assert that we get an errback if we try to sign data using a key that
- wasn't added.
- """
- del self.server.factory.keys[self.rsaPublic.blob()]
- d = self.client.signData(self.rsaPublic.blob(), "John Hancock")
- self.pump.flush()
- return self.assertFailure(d, ConchError)
-
-
- def test_requestIdentities(self):
- """
- Assert that we get all of the keys/comments that we add when we issue a
- request for all identities.
- """
- d = self.client.requestIdentities()
- self.pump.flush()
- def _check(keyt):
- expected = {}
- expected[self.dsaPublic.blob()] = 'a comment'
- expected[self.rsaPublic.blob()] = 'another comment'
-
- received = {}
- for k in keyt:
- received[keys.Key.fromString(k[0], type='blob').blob()] = k[1]
- self.assertEqual(expected, received)
- return d.addCallback(_check)
-
-
-
-class TestAgentKeyRemoval(AgentTestBase):
- """
- Test support for removing keys in a remote server.
- """
-
- def setUp(self):
- AgentTestBase.setUp(self)
- self.server.factory.keys[self.dsaPrivate.blob()] = (
- self.dsaPrivate, 'a comment')
- self.server.factory.keys[self.rsaPrivate.blob()] = (
- self.rsaPrivate, 'another comment')
-
-
- def test_removeRSAIdentity(self):
- """
- Assert that we can remove an RSA identity.
- """
- # only need public key for this
- d = self.client.removeIdentity(self.rsaPrivate.blob())
- self.pump.flush()
-
- def _check(ignored):
- self.assertEqual(1, len(self.server.factory.keys))
- self.assertIn(self.dsaPrivate.blob(), self.server.factory.keys)
- self.assertNotIn(self.rsaPrivate.blob(), self.server.factory.keys)
- return d.addCallback(_check)
-
-
- def test_removeDSAIdentity(self):
- """
- Assert that we can remove a DSA identity.
- """
- # only need public key for this
- d = self.client.removeIdentity(self.dsaPrivate.blob())
- self.pump.flush()
-
- def _check(ignored):
- self.assertEqual(1, len(self.server.factory.keys))
- self.assertIn(self.rsaPrivate.blob(), self.server.factory.keys)
- return d.addCallback(_check)
-
-
- def test_removeAllIdentities(self):
- """
- Assert that we can remove all identities.
- """
- d = self.client.removeAllIdentities()
- self.pump.flush()
-
- def _check(ignored):
- self.assertEqual(0, len(self.server.factory.keys))
- return d.addCallback(_check)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py
deleted file mode 100755
index 03e327a6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py
+++ /dev/null
@@ -1,975 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_cftp -*-
-# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
-# See LICENSE file for details.
-
-"""
-Tests for L{twisted.conch.scripts.cftp}.
-"""
-
-import locale
-import time, sys, os, operator, getpass, struct
-from StringIO import StringIO
-
-from twisted.conch.test.test_ssh import Crypto, pyasn1
-
-_reason = None
-if Crypto and pyasn1:
- try:
- from twisted.conch import unix
- from twisted.conch.scripts import cftp
- from twisted.conch.test.test_filetransfer import FileTransferForTestAvatar
- except ImportError, e:
- # Python 2.3 compatibility fix
- sys.modules.pop("twisted.conch.unix", None)
- unix = None
- _reason = str(e)
- del e
-else:
- unix = None
-
-
-from twisted.python.fakepwd import UserDatabase
-from twisted.trial.unittest import TestCase
-from twisted.cred import portal
-from twisted.internet import reactor, protocol, interfaces, defer, error
-from twisted.internet.utils import getProcessOutputAndValue
-from twisted.python import log
-from twisted.conch import ls
-from twisted.test.proto_helpers import StringTransport
-from twisted.internet.task import Clock
-
-from twisted.conch.test import test_ssh, test_conch
-from twisted.conch.test.test_filetransfer import SFTPTestBase
-from twisted.conch.test.test_filetransfer import FileTransferTestAvatar
-
-
-
-class ListingTests(TestCase):
- """
- Tests for L{lsLine}, the function which generates an entry for a file or
- directory in an SFTP I{ls} command's output.
- """
- if getattr(time, 'tzset', None) is None:
- skip = "Cannot test timestamp formatting code without time.tzset"
-
- def setUp(self):
- """
- Patch the L{ls} module's time function so the results of L{lsLine} are
- deterministic.
- """
- self.now = 123456789
- def fakeTime():
- return self.now
- self.patch(ls, 'time', fakeTime)
-
- # Make sure that the timezone ends up the same after these tests as
- # it was before.
- if 'TZ' in os.environ:
- self.addCleanup(operator.setitem, os.environ, 'TZ', os.environ['TZ'])
- self.addCleanup(time.tzset)
- else:
- def cleanup():
- # os.environ.pop is broken! Don't use it! Ever! Or die!
- try:
- del os.environ['TZ']
- except KeyError:
- pass
- time.tzset()
- self.addCleanup(cleanup)
-
-
- def _lsInTimezone(self, timezone, stat):
- """
- Call L{ls.lsLine} after setting the timezone to C{timezone} and return
- the result.
- """
- # Set the timezone to a well-known value so the timestamps are
- # predictable.
- os.environ['TZ'] = timezone
- time.tzset()
- return ls.lsLine('foo', stat)
-
-
- def test_oldFile(self):
- """
- A file with an mtime six months (approximately) or more in the past has
- a listing including a low-resolution timestamp.
- """
- # Go with 7 months. That's more than 6 months.
- then = self.now - (60 * 60 * 24 * 31 * 7)
- stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0))
-
- self.assertEqual(
- self._lsInTimezone('America/New_York', stat),
- '!--------- 0 0 0 0 Apr 26 1973 foo')
- self.assertEqual(
- self._lsInTimezone('Pacific/Auckland', stat),
- '!--------- 0 0 0 0 Apr 27 1973 foo')
-
-
- def test_oldSingleDigitDayOfMonth(self):
- """
- A file with a high-resolution timestamp which falls on a day of the
- month which can be represented by one decimal digit is formatted with
- one padding 0 to preserve the columns which come after it.
- """
- # A point about 7 months in the past, tweaked to fall on the first of a
- # month so we test the case we want to test.
- then = self.now - (60 * 60 * 24 * 31 * 7) + (60 * 60 * 24 * 5)
- stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0))
-
- self.assertEqual(
- self._lsInTimezone('America/New_York', stat),
- '!--------- 0 0 0 0 May 01 1973 foo')
- self.assertEqual(
- self._lsInTimezone('Pacific/Auckland', stat),
- '!--------- 0 0 0 0 May 02 1973 foo')
-
-
- def test_newFile(self):
- """
- A file with an mtime fewer than six months (approximately) in the past
- has a listing including a high-resolution timestamp excluding the year.
- """
- # A point about three months in the past.
- then = self.now - (60 * 60 * 24 * 31 * 3)
- stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0))
-
- self.assertEqual(
- self._lsInTimezone('America/New_York', stat),
- '!--------- 0 0 0 0 Aug 28 17:33 foo')
- self.assertEqual(
- self._lsInTimezone('Pacific/Auckland', stat),
- '!--------- 0 0 0 0 Aug 29 09:33 foo')
-
-
- def test_localeIndependent(self):
- """
- The month name in the date is locale independent.
- """
- # A point about three months in the past.
- then = self.now - (60 * 60 * 24 * 31 * 3)
- stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0))
-
- # Fake that we're in a language where August is not Aug (e.g.: Spanish)
- currentLocale = locale.getlocale()
- locale.setlocale(locale.LC_ALL, "es_AR.UTF8")
- self.addCleanup(locale.setlocale, locale.LC_ALL, currentLocale)
-
- self.assertEqual(
- self._lsInTimezone('America/New_York', stat),
- '!--------- 0 0 0 0 Aug 28 17:33 foo')
- self.assertEqual(
- self._lsInTimezone('Pacific/Auckland', stat),
- '!--------- 0 0 0 0 Aug 29 09:33 foo')
-
- # if alternate locale is not available, the previous test will be
- # skipped, please install this locale for it to run
- currentLocale = locale.getlocale()
- try:
- try:
- locale.setlocale(locale.LC_ALL, "es_AR.UTF8")
- except locale.Error:
- test_localeIndependent.skip = "The es_AR.UTF8 locale is not installed."
- finally:
- locale.setlocale(locale.LC_ALL, currentLocale)
-
-
- def test_newSingleDigitDayOfMonth(self):
- """
- A file with a high-resolution timestamp which falls on a day of the
- month which can be represented by one decimal digit is formatted with
- one padding 0 to preserve the columns which come after it.
- """
- # A point about three months in the past, tweaked to fall on the first
- # of a month so we test the case we want to test.
- then = self.now - (60 * 60 * 24 * 31 * 3) + (60 * 60 * 24 * 4)
- stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0))
-
- self.assertEqual(
- self._lsInTimezone('America/New_York', stat),
- '!--------- 0 0 0 0 Sep 01 17:33 foo')
- self.assertEqual(
- self._lsInTimezone('Pacific/Auckland', stat),
- '!--------- 0 0 0 0 Sep 02 09:33 foo')
-
-
-
-class StdioClientTests(TestCase):
- """
- Tests for L{cftp.StdioClient}.
- """
- def setUp(self):
- """
- Create a L{cftp.StdioClient} hooked up to dummy transport and a fake
- user database.
- """
- class Connection:
- pass
-
- conn = Connection()
- conn.transport = StringTransport()
- conn.transport.localClosed = False
-
- self.client = cftp.StdioClient(conn)
- self.database = self.client._pwd = UserDatabase()
-
- # Intentionally bypassing makeConnection - that triggers some code
- # which uses features not provided by our dumb Connection fake.
- self.client.transport = StringTransport()
-
-
- def test_exec(self):
- """
- The I{exec} command runs its arguments locally in a child process
- using the user's shell.
- """
- self.database.addUser(
- getpass.getuser(), 'secret', os.getuid(), 1234, 'foo', 'bar',
- sys.executable)
-
- d = self.client._dispatchCommand("exec print 1 + 2")
- d.addCallback(self.assertEqual, "3\n")
- return d
-
-
- def test_execWithoutShell(self):
- """
- If the local user has no shell, the I{exec} command runs its arguments
- using I{/bin/sh}.
- """
- self.database.addUser(
- getpass.getuser(), 'secret', os.getuid(), 1234, 'foo', 'bar', '')
-
- d = self.client._dispatchCommand("exec echo hello")
- d.addCallback(self.assertEqual, "hello\n")
- return d
-
-
- def test_bang(self):
- """
- The I{exec} command is run for lines which start with C{"!"}.
- """
- self.database.addUser(
- getpass.getuser(), 'secret', os.getuid(), 1234, 'foo', 'bar',
- '/bin/sh')
-
- d = self.client._dispatchCommand("!echo hello")
- d.addCallback(self.assertEqual, "hello\n")
- return d
-
-
- def setKnownConsoleSize(self, width, height):
- """
- For the duration of this test, patch C{cftp}'s C{fcntl} module to return
- a fixed width and height.
-
- @param width: the width in characters
- @type width: C{int}
- @param height: the height in characters
- @type height: C{int}
- """
- import tty # local import to avoid win32 issues
- class FakeFcntl(object):
- def ioctl(self, fd, opt, mutate):
- if opt != tty.TIOCGWINSZ:
- self.fail("Only window-size queries supported.")
- return struct.pack("4H", height, width, 0, 0)
- self.patch(cftp, "fcntl", FakeFcntl())
-
-
- def test_progressReporting(self):
- """
- L{StdioClient._printProgressBar} prints a progress description,
- including percent done, amount transferred, transfer rate, and time
- remaining, all based the given start time, the given L{FileWrapper}'s
- progress information and the reactor's current time.
- """
- # Use a short, known console width because this simple test doesn't need
- # to test the console padding.
- self.setKnownConsoleSize(10, 34)
- clock = self.client.reactor = Clock()
- wrapped = StringIO("x")
- wrapped.name = "sample"
- wrapper = cftp.FileWrapper(wrapped)
- wrapper.size = 1024 * 10
- startTime = clock.seconds()
- clock.advance(2.0)
- wrapper.total += 4096
- self.client._printProgressBar(wrapper, startTime)
- self.assertEqual(self.client.transport.value(),
- "\rsample 40% 4.0kB 2.0kBps 00:03 ")
-
-
- def test_reportNoProgress(self):
- """
- L{StdioClient._printProgressBar} prints a progress description that
- indicates 0 bytes transferred if no bytes have been transferred and no
- time has passed.
- """
- self.setKnownConsoleSize(10, 34)
- clock = self.client.reactor = Clock()
- wrapped = StringIO("x")
- wrapped.name = "sample"
- wrapper = cftp.FileWrapper(wrapped)
- startTime = clock.seconds()
- self.client._printProgressBar(wrapper, startTime)
- self.assertEqual(self.client.transport.value(),
- "\rsample 0% 0.0B 0.0Bps 00:00 ")
-
-
-
-class FileTransferTestRealm:
- def __init__(self, testDir):
- self.testDir = testDir
-
- def requestAvatar(self, avatarID, mind, *interfaces):
- a = FileTransferTestAvatar(self.testDir)
- return interfaces[0], a, lambda: None
-
-
-class SFTPTestProcess(protocol.ProcessProtocol):
- """
- Protocol for testing cftp. Provides an interface between Python (where all
- the tests are) and the cftp client process (which does the work that is
- being tested).
- """
-
- def __init__(self, onOutReceived):
- """
- @param onOutReceived: A L{Deferred} to be fired as soon as data is
- received from stdout.
- """
- self.clearBuffer()
- self.onOutReceived = onOutReceived
- self.onProcessEnd = None
- self._expectingCommand = None
- self._processEnded = False
-
- def clearBuffer(self):
- """
- Clear any buffered data received from stdout. Should be private.
- """
- self.buffer = ''
- self._linesReceived = []
- self._lineBuffer = ''
-
- def outReceived(self, data):
- """
- Called by Twisted when the cftp client prints data to stdout.
- """
- log.msg('got %s' % data)
- lines = (self._lineBuffer + data).split('\n')
- self._lineBuffer = lines.pop(-1)
- self._linesReceived.extend(lines)
- # XXX - not strictly correct.
- # We really want onOutReceived to fire after the first 'cftp>' prompt
- # has been received. (See use in TestOurServerCmdLineClient.setUp)
- if self.onOutReceived is not None:
- d, self.onOutReceived = self.onOutReceived, None
- d.callback(data)
- self.buffer += data
- self._checkForCommand()
-
- def _checkForCommand(self):
- prompt = 'cftp> '
- if self._expectingCommand and self._lineBuffer == prompt:
- buf = '\n'.join(self._linesReceived)
- if buf.startswith(prompt):
- buf = buf[len(prompt):]
- self.clearBuffer()
- d, self._expectingCommand = self._expectingCommand, None
- d.callback(buf)
-
- def errReceived(self, data):
- """
- Called by Twisted when the cftp client prints data to stderr.
- """
- log.msg('err: %s' % data)
-
- def getBuffer(self):
- """
- Return the contents of the buffer of data received from stdout.
- """
- return self.buffer
-
- def runCommand(self, command):
- """
- Issue the given command via the cftp client. Return a C{Deferred} that
- fires when the server returns a result. Note that the C{Deferred} will
- callback even if the server returns some kind of error.
-
- @param command: A string containing an sftp command.
-
- @return: A C{Deferred} that fires when the sftp server returns a
- result. The payload is the server's response string.
- """
- self._expectingCommand = defer.Deferred()
- self.clearBuffer()
- self.transport.write(command + '\n')
- return self._expectingCommand
-
- def runScript(self, commands):
- """
- Run each command in sequence and return a Deferred that fires when all
- commands are completed.
-
- @param commands: A list of strings containing sftp commands.
-
- @return: A C{Deferred} that fires when all commands are completed. The
- payload is a list of response strings from the server, in the same
- order as the commands.
- """
- sem = defer.DeferredSemaphore(1)
- dl = [sem.run(self.runCommand, command) for command in commands]
- return defer.gatherResults(dl)
-
- def killProcess(self):
- """
- Kill the process if it is still running.
-
- If the process is still running, sends a KILL signal to the transport
- and returns a C{Deferred} which fires when L{processEnded} is called.
-
- @return: a C{Deferred}.
- """
- if self._processEnded:
- return defer.succeed(None)
- self.onProcessEnd = defer.Deferred()
- self.transport.signalProcess('KILL')
- return self.onProcessEnd
-
- def processEnded(self, reason):
- """
- Called by Twisted when the cftp client process ends.
- """
- self._processEnded = True
- if self.onProcessEnd:
- d, self.onProcessEnd = self.onProcessEnd, None
- d.callback(None)
-
-
-class CFTPClientTestBase(SFTPTestBase):
- def setUp(self):
- f = open('dsa_test.pub','w')
- f.write(test_ssh.publicDSA_openssh)
- f.close()
- f = open('dsa_test','w')
- f.write(test_ssh.privateDSA_openssh)
- f.close()
- os.chmod('dsa_test', 33152)
- f = open('kh_test','w')
- f.write('127.0.0.1 ' + test_ssh.publicRSA_openssh)
- f.close()
- return SFTPTestBase.setUp(self)
-
- def startServer(self):
- realm = FileTransferTestRealm(self.testDir)
- p = portal.Portal(realm)
- p.registerChecker(test_ssh.ConchTestPublicKeyChecker())
- fac = test_ssh.ConchTestServerFactory()
- fac.portal = p
- self.server = reactor.listenTCP(0, fac, interface="127.0.0.1")
-
- def stopServer(self):
- if not hasattr(self.server.factory, 'proto'):
- return self._cbStopServer(None)
- self.server.factory.proto.expectedLoseConnection = 1
- d = defer.maybeDeferred(
- self.server.factory.proto.transport.loseConnection)
- d.addCallback(self._cbStopServer)
- return d
-
- def _cbStopServer(self, ignored):
- return defer.maybeDeferred(self.server.stopListening)
-
- def tearDown(self):
- for f in ['dsa_test.pub', 'dsa_test', 'kh_test']:
- try:
- os.remove(f)
- except:
- pass
- return SFTPTestBase.tearDown(self)
-
-
-
-class TestOurServerCmdLineClient(CFTPClientTestBase):
-
- def setUp(self):
- CFTPClientTestBase.setUp(self)
-
- self.startServer()
- cmds = ('-p %i -l testuser '
- '--known-hosts kh_test '
- '--user-authentications publickey '
- '--host-key-algorithms ssh-rsa '
- '-i dsa_test '
- '-a '
- '-v '
- '127.0.0.1')
- port = self.server.getHost().port
- cmds = test_conch._makeArgs((cmds % port).split(), mod='cftp')
- log.msg('running %s %s' % (sys.executable, cmds))
- d = defer.Deferred()
- self.processProtocol = SFTPTestProcess(d)
- d.addCallback(lambda _: self.processProtocol.clearBuffer())
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
- reactor.spawnProcess(self.processProtocol, sys.executable, cmds,
- env=env)
- return d
-
- def tearDown(self):
- d = self.stopServer()
- d.addCallback(lambda _: self.processProtocol.killProcess())
- return d
-
- def _killProcess(self, ignored):
- try:
- self.processProtocol.transport.signalProcess('KILL')
- except error.ProcessExitedAlready:
- pass
-
- def runCommand(self, command):
- """
- Run the given command with the cftp client. Return a C{Deferred} that
- fires when the command is complete. Payload is the server's output for
- that command.
- """
- return self.processProtocol.runCommand(command)
-
- def runScript(self, *commands):
- """
- Run the given commands with the cftp client. Returns a C{Deferred}
- that fires when the commands are all complete. The C{Deferred}'s
- payload is a list of output for each command.
- """
- return self.processProtocol.runScript(commands)
-
- def testCdPwd(self):
- """
- Test that 'pwd' reports the current remote directory, that 'lpwd'
- reports the current local directory, and that changing to a
- subdirectory then changing to its parent leaves you in the original
- remote directory.
- """
- # XXX - not actually a unit test, see docstring.
- homeDir = os.path.join(os.getcwd(), self.testDir)
- d = self.runScript('pwd', 'lpwd', 'cd testDirectory', 'cd ..', 'pwd')
- d.addCallback(lambda xs: xs[:3] + xs[4:])
- d.addCallback(self.assertEqual,
- [homeDir, os.getcwd(), '', homeDir])
- return d
-
- def testChAttrs(self):
- """
- Check that 'ls -l' output includes the access permissions and that
- this output changes appropriately with 'chmod'.
- """
- def _check(results):
- self.flushLoggedErrors()
- self.assertTrue(results[0].startswith('-rw-r--r--'))
- self.assertEqual(results[1], '')
- self.assertTrue(results[2].startswith('----------'), results[2])
- self.assertEqual(results[3], '')
-
- d = self.runScript('ls -l testfile1', 'chmod 0 testfile1',
- 'ls -l testfile1', 'chmod 644 testfile1')
- return d.addCallback(_check)
- # XXX test chgrp/own
-
-
- def testList(self):
- """
- Check 'ls' works as expected. Checks for wildcards, hidden files,
- listing directories and listing empty directories.
- """
- def _check(results):
- self.assertEqual(results[0], ['testDirectory', 'testRemoveFile',
- 'testRenameFile', 'testfile1'])
- self.assertEqual(results[1], ['testDirectory', 'testRemoveFile',
- 'testRenameFile', 'testfile1'])
- self.assertEqual(results[2], ['testRemoveFile', 'testRenameFile'])
- self.assertEqual(results[3], ['.testHiddenFile', 'testRemoveFile',
- 'testRenameFile'])
- self.assertEqual(results[4], [''])
- d = self.runScript('ls', 'ls ../' + os.path.basename(self.testDir),
- 'ls *File', 'ls -a *File', 'ls -l testDirectory')
- d.addCallback(lambda xs: [x.split('\n') for x in xs])
- return d.addCallback(_check)
-
-
- def testHelp(self):
- """
- Check that running the '?' command returns help.
- """
- d = self.runCommand('?')
- d.addCallback(self.assertEqual,
- cftp.StdioClient(None).cmd_HELP('').strip())
- return d
-
- def assertFilesEqual(self, name1, name2, msg=None):
- """
- Assert that the files at C{name1} and C{name2} contain exactly the
- same data.
- """
- f1 = file(name1).read()
- f2 = file(name2).read()
- self.assertEqual(f1, f2, msg)
-
-
- def testGet(self):
- """
- Test that 'get' saves the remote file to the correct local location,
- that the output of 'get' is correct and that 'rm' actually removes
- the file.
- """
- # XXX - not actually a unit test
- expectedOutput = ("Transferred %s/%s/testfile1 to %s/test file2"
- % (os.getcwd(), self.testDir, self.testDir))
- def _checkGet(result):
- self.assertTrue(result.endswith(expectedOutput))
- self.assertFilesEqual(self.testDir + '/testfile1',
- self.testDir + '/test file2',
- "get failed")
- return self.runCommand('rm "test file2"')
-
- d = self.runCommand('get testfile1 "%s/test file2"' % (self.testDir,))
- d.addCallback(_checkGet)
- d.addCallback(lambda _: self.failIf(
- os.path.exists(self.testDir + '/test file2')))
- return d
-
-
- def testWildcardGet(self):
- """
- Test that 'get' works correctly when given wildcard parameters.
- """
- def _check(ignored):
- self.assertFilesEqual(self.testDir + '/testRemoveFile',
- 'testRemoveFile',
- 'testRemoveFile get failed')
- self.assertFilesEqual(self.testDir + '/testRenameFile',
- 'testRenameFile',
- 'testRenameFile get failed')
-
- d = self.runCommand('get testR*')
- return d.addCallback(_check)
-
-
- def testPut(self):
- """
- Check that 'put' uploads files correctly and that they can be
- successfully removed. Also check the output of the put command.
- """
- # XXX - not actually a unit test
- expectedOutput = ('Transferred %s/testfile1 to %s/%s/test"file2'
- % (self.testDir, os.getcwd(), self.testDir))
- def _checkPut(result):
- self.assertFilesEqual(self.testDir + '/testfile1',
- self.testDir + '/test"file2')
- self.failUnless(result.endswith(expectedOutput))
- return self.runCommand('rm "test\\"file2"')
-
- d = self.runCommand('put %s/testfile1 "test\\"file2"'
- % (self.testDir,))
- d.addCallback(_checkPut)
- d.addCallback(lambda _: self.failIf(
- os.path.exists(self.testDir + '/test"file2')))
- return d
-
-
- def test_putOverLongerFile(self):
- """
- Check that 'put' uploads files correctly when overwriting a longer
- file.
- """
- # XXX - not actually a unit test
- f = file(os.path.join(self.testDir, 'shorterFile'), 'w')
- f.write("a")
- f.close()
- f = file(os.path.join(self.testDir, 'longerFile'), 'w')
- f.write("bb")
- f.close()
- def _checkPut(result):
- self.assertFilesEqual(self.testDir + '/shorterFile',
- self.testDir + '/longerFile')
-
- d = self.runCommand('put %s/shorterFile longerFile'
- % (self.testDir,))
- d.addCallback(_checkPut)
- return d
-
-
- def test_putMultipleOverLongerFile(self):
- """
- Check that 'put' uploads files correctly when overwriting a longer
- file and you use a wildcard to specify the files to upload.
- """
- # XXX - not actually a unit test
- os.mkdir(os.path.join(self.testDir, 'dir'))
- f = file(os.path.join(self.testDir, 'dir', 'file'), 'w')
- f.write("a")
- f.close()
- f = file(os.path.join(self.testDir, 'file'), 'w')
- f.write("bb")
- f.close()
- def _checkPut(result):
- self.assertFilesEqual(self.testDir + '/dir/file',
- self.testDir + '/file')
-
- d = self.runCommand('put %s/dir/*'
- % (self.testDir,))
- d.addCallback(_checkPut)
- return d
-
-
- def testWildcardPut(self):
- """
- What happens if you issue a 'put' command and include a wildcard (i.e.
- '*') in parameter? Check that all files matching the wildcard are
- uploaded to the correct directory.
- """
- def check(results):
- self.assertEqual(results[0], '')
- self.assertEqual(results[2], '')
- self.assertFilesEqual(self.testDir + '/testRemoveFile',
- self.testDir + '/../testRemoveFile',
- 'testRemoveFile get failed')
- self.assertFilesEqual(self.testDir + '/testRenameFile',
- self.testDir + '/../testRenameFile',
- 'testRenameFile get failed')
-
- d = self.runScript('cd ..',
- 'put %s/testR*' % (self.testDir,),
- 'cd %s' % os.path.basename(self.testDir))
- d.addCallback(check)
- return d
-
-
- def testLink(self):
- """
- Test that 'ln' creates a file which appears as a link in the output of
- 'ls'. Check that removing the new file succeeds without output.
- """
- def _check(results):
- self.flushLoggedErrors()
- self.assertEqual(results[0], '')
- self.assertTrue(results[1].startswith('l'), 'link failed')
- return self.runCommand('rm testLink')
-
- d = self.runScript('ln testLink testfile1', 'ls -l testLink')
- d.addCallback(_check)
- d.addCallback(self.assertEqual, '')
- return d
-
-
- def testRemoteDirectory(self):
- """
- Test that we can create and remove directories with the cftp client.
- """
- def _check(results):
- self.assertEqual(results[0], '')
- self.assertTrue(results[1].startswith('d'))
- return self.runCommand('rmdir testMakeDirectory')
-
- d = self.runScript('mkdir testMakeDirectory',
- 'ls -l testMakeDirector?')
- d.addCallback(_check)
- d.addCallback(self.assertEqual, '')
- return d
-
-
- def test_existingRemoteDirectory(self):
- """
- Test that a C{mkdir} on an existing directory fails with the
- appropriate error, and doesn't log an useless error server side.
- """
- def _check(results):
- self.assertEqual(results[0], '')
- self.assertEqual(results[1],
- 'remote error 11: mkdir failed')
-
- d = self.runScript('mkdir testMakeDirectory',
- 'mkdir testMakeDirectory')
- d.addCallback(_check)
- return d
-
-
- def testLocalDirectory(self):
- """
- Test that we can create a directory locally and remove it with the
- cftp client. This test works because the 'remote' server is running
- out of a local directory.
- """
- d = self.runCommand('lmkdir %s/testLocalDirectory' % (self.testDir,))
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: self.runCommand('rmdir testLocalDirectory'))
- d.addCallback(self.assertEqual, '')
- return d
-
-
- def testRename(self):
- """
- Test that we can rename a file.
- """
- def _check(results):
- self.assertEqual(results[0], '')
- self.assertEqual(results[1], 'testfile2')
- return self.runCommand('rename testfile2 testfile1')
-
- d = self.runScript('rename testfile1 testfile2', 'ls testfile?')
- d.addCallback(_check)
- d.addCallback(self.assertEqual, '')
- return d
-
-
-
-class TestOurServerBatchFile(CFTPClientTestBase):
- def setUp(self):
- CFTPClientTestBase.setUp(self)
- self.startServer()
-
- def tearDown(self):
- CFTPClientTestBase.tearDown(self)
- return self.stopServer()
-
- def _getBatchOutput(self, f):
- fn = self.mktemp()
- open(fn, 'w').write(f)
- port = self.server.getHost().port
- cmds = ('-p %i -l testuser '
- '--known-hosts kh_test '
- '--user-authentications publickey '
- '--host-key-algorithms ssh-rsa '
- '-i dsa_test '
- '-a '
- '-v -b %s 127.0.0.1') % (port, fn)
- cmds = test_conch._makeArgs(cmds.split(), mod='cftp')[1:]
- log.msg('running %s %s' % (sys.executable, cmds))
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
-
- self.server.factory.expectedLoseConnection = 1
-
- d = getProcessOutputAndValue(sys.executable, cmds, env=env)
-
- def _cleanup(res):
- os.remove(fn)
- return res
-
- d.addCallback(lambda res: res[0])
- d.addBoth(_cleanup)
-
- return d
-
- def testBatchFile(self):
- """Test whether batch file function of cftp ('cftp -b batchfile').
- This works by treating the file as a list of commands to be run.
- """
- cmds = """pwd
-ls
-exit
-"""
- def _cbCheckResult(res):
- res = res.split('\n')
- log.msg('RES %s' % str(res))
- self.failUnless(res[1].find(self.testDir) != -1, repr(res))
- self.assertEqual(res[3:-2], ['testDirectory', 'testRemoveFile',
- 'testRenameFile', 'testfile1'])
-
- d = self._getBatchOutput(cmds)
- d.addCallback(_cbCheckResult)
- return d
-
- def testError(self):
- """Test that an error in the batch file stops running the batch.
- """
- cmds = """chown 0 missingFile
-pwd
-exit
-"""
- def _cbCheckResult(res):
- self.failIf(res.find(self.testDir) != -1)
-
- d = self._getBatchOutput(cmds)
- d.addCallback(_cbCheckResult)
- return d
-
- def testIgnoredError(self):
- """Test that a minus sign '-' at the front of a line ignores
- any errors.
- """
- cmds = """-chown 0 missingFile
-pwd
-exit
-"""
- def _cbCheckResult(res):
- self.failIf(res.find(self.testDir) == -1)
-
- d = self._getBatchOutput(cmds)
- d.addCallback(_cbCheckResult)
- return d
-
-
-
-class TestOurServerSftpClient(CFTPClientTestBase):
- """
- Test the sftp server against sftp command line client.
- """
-
- def setUp(self):
- CFTPClientTestBase.setUp(self)
- return self.startServer()
-
-
- def tearDown(self):
- return self.stopServer()
-
-
- def test_extendedAttributes(self):
- """
- Test the return of extended attributes by the server: the sftp client
- should ignore them, but still be able to parse the response correctly.
-
- This test is mainly here to check that
- L{filetransfer.FILEXFER_ATTR_EXTENDED} has the correct value.
- """
- fn = self.mktemp()
- open(fn, 'w').write("ls .\nexit")
- port = self.server.getHost().port
-
- oldGetAttr = FileTransferForTestAvatar._getAttrs
- def _getAttrs(self, s):
- attrs = oldGetAttr(self, s)
- attrs["ext_foo"] = "bar"
- return attrs
-
- self.patch(FileTransferForTestAvatar, "_getAttrs", _getAttrs)
-
- self.server.factory.expectedLoseConnection = True
- cmds = ('-o', 'IdentityFile=dsa_test',
- '-o', 'UserKnownHostsFile=kh_test',
- '-o', 'HostKeyAlgorithms=ssh-rsa',
- '-o', 'Port=%i' % (port,), '-b', fn, 'testuser@127.0.0.1')
- d = getProcessOutputAndValue("sftp", cmds)
- def check(result):
- self.assertEqual(result[2], 0)
- for i in ['testDirectory', 'testRemoveFile',
- 'testRenameFile', 'testfile1']:
- self.assertIn(i, result[0])
- return d.addCallback(check)
-
-
-
-if unix is None or Crypto is None or pyasn1 is None or interfaces.IReactorProcess(reactor, None) is None:
- if _reason is None:
- _reason = "don't run w/o spawnProcess or PyCrypto or pyasn1"
- TestOurServerCmdLineClient.skip = _reason
- TestOurServerBatchFile.skip = _reason
- TestOurServerSftpClient.skip = _reason
- StdioClientTests.skip = _reason
-else:
- from twisted.python.procutils import which
- if not which('sftp'):
- TestOurServerSftpClient.skip = "no sftp command-line client available"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py
deleted file mode 100755
index a46596dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright (C) 2007-2008 Twisted Matrix Laboratories
-# See LICENSE for details
-
-"""
-Test ssh/channel.py.
-"""
-from twisted.conch.ssh import channel
-from twisted.trial import unittest
-
-
-class MockTransport(object):
- """
- A mock Transport. All we use is the getPeer() and getHost() methods.
- Channels implement the ITransport interface, and their getPeer() and
- getHost() methods return ('SSH', <transport's getPeer/Host value>) so
- we need to implement these methods so they have something to draw
- from.
- """
- def getPeer(self):
- return ('MockPeer',)
-
- def getHost(self):
- return ('MockHost',)
-
-
-class MockConnection(object):
- """
- A mock for twisted.conch.ssh.connection.SSHConnection. Record the data
- that channels send, and when they try to close the connection.
-
- @ivar data: a C{dict} mapping channel id #s to lists of data sent by that
- channel.
- @ivar extData: a C{dict} mapping channel id #s to lists of 2-tuples
- (extended data type, data) sent by that channel.
- @ivar closes: a C{dict} mapping channel id #s to True if that channel sent
- a close message.
- """
- transport = MockTransport()
-
- def __init__(self):
- self.data = {}
- self.extData = {}
- self.closes = {}
-
- def logPrefix(self):
- """
- Return our logging prefix.
- """
- return "MockConnection"
-
- def sendData(self, channel, data):
- """
- Record the sent data.
- """
- self.data.setdefault(channel, []).append(data)
-
- def sendExtendedData(self, channel, type, data):
- """
- Record the sent extended data.
- """
- self.extData.setdefault(channel, []).append((type, data))
-
- def sendClose(self, channel):
- """
- Record that the channel sent a close message.
- """
- self.closes[channel] = True
-
-
-class ChannelTestCase(unittest.TestCase):
-
- def setUp(self):
- """
- Initialize the channel. remoteMaxPacket is 10 so that data is able
- to be sent (the default of 0 means no data is sent because no packets
- are made).
- """
- self.conn = MockConnection()
- self.channel = channel.SSHChannel(conn=self.conn,
- remoteMaxPacket=10)
- self.channel.name = 'channel'
-
- def test_init(self):
- """
- Test that SSHChannel initializes correctly. localWindowSize defaults
- to 131072 (2**17) and localMaxPacket to 32768 (2**15) as reasonable
- defaults (what OpenSSH uses for those variables).
-
- The values in the second set of assertions are meaningless; they serve
- only to verify that the instance variables are assigned in the correct
- order.
- """
- c = channel.SSHChannel(conn=self.conn)
- self.assertEqual(c.localWindowSize, 131072)
- self.assertEqual(c.localWindowLeft, 131072)
- self.assertEqual(c.localMaxPacket, 32768)
- self.assertEqual(c.remoteWindowLeft, 0)
- self.assertEqual(c.remoteMaxPacket, 0)
- self.assertEqual(c.conn, self.conn)
- self.assertEqual(c.data, None)
- self.assertEqual(c.avatar, None)
-
- c2 = channel.SSHChannel(1, 2, 3, 4, 5, 6, 7)
- self.assertEqual(c2.localWindowSize, 1)
- self.assertEqual(c2.localWindowLeft, 1)
- self.assertEqual(c2.localMaxPacket, 2)
- self.assertEqual(c2.remoteWindowLeft, 3)
- self.assertEqual(c2.remoteMaxPacket, 4)
- self.assertEqual(c2.conn, 5)
- self.assertEqual(c2.data, 6)
- self.assertEqual(c2.avatar, 7)
-
- def test_str(self):
- """
- Test that str(SSHChannel) works gives the channel name and local and
- remote windows at a glance..
- """
- self.assertEqual(str(self.channel), '<SSHChannel channel (lw 131072 '
- 'rw 0)>')
-
- def test_logPrefix(self):
- """
- Test that SSHChannel.logPrefix gives the name of the channel, the
- local channel ID and the underlying connection.
- """
- self.assertEqual(self.channel.logPrefix(), 'SSHChannel channel '
- '(unknown) on MockConnection')
-
- def test_addWindowBytes(self):
- """
- Test that addWindowBytes adds bytes to the window and resumes writing
- if it was paused.
- """
- cb = [False]
- def stubStartWriting():
- cb[0] = True
- self.channel.startWriting = stubStartWriting
- self.channel.write('test')
- self.channel.writeExtended(1, 'test')
- self.channel.addWindowBytes(50)
- self.assertEqual(self.channel.remoteWindowLeft, 50 - 4 - 4)
- self.assertTrue(self.channel.areWriting)
- self.assertTrue(cb[0])
- self.assertEqual(self.channel.buf, '')
- self.assertEqual(self.conn.data[self.channel], ['test'])
- self.assertEqual(self.channel.extBuf, [])
- self.assertEqual(self.conn.extData[self.channel], [(1, 'test')])
-
- cb[0] = False
- self.channel.addWindowBytes(20)
- self.assertFalse(cb[0])
-
- self.channel.write('a'*80)
- self.channel.loseConnection()
- self.channel.addWindowBytes(20)
- self.assertFalse(cb[0])
-
- def test_requestReceived(self):
- """
- Test that requestReceived handles requests by dispatching them to
- request_* methods.
- """
- self.channel.request_test_method = lambda data: data == ''
- self.assertTrue(self.channel.requestReceived('test-method', ''))
- self.assertFalse(self.channel.requestReceived('test-method', 'a'))
- self.assertFalse(self.channel.requestReceived('bad-method', ''))
-
- def test_closeReceieved(self):
- """
- Test that the default closeReceieved closes the connection.
- """
- self.assertFalse(self.channel.closing)
- self.channel.closeReceived()
- self.assertTrue(self.channel.closing)
-
- def test_write(self):
- """
- Test that write handles data correctly. Send data up to the size
- of the remote window, splitting the data into packets of length
- remoteMaxPacket.
- """
- cb = [False]
- def stubStopWriting():
- cb[0] = True
- # no window to start with
- self.channel.stopWriting = stubStopWriting
- self.channel.write('d')
- self.channel.write('a')
- self.assertFalse(self.channel.areWriting)
- self.assertTrue(cb[0])
- # regular write
- self.channel.addWindowBytes(20)
- self.channel.write('ta')
- data = self.conn.data[self.channel]
- self.assertEqual(data, ['da', 'ta'])
- self.assertEqual(self.channel.remoteWindowLeft, 16)
- # larger than max packet
- self.channel.write('12345678901')
- self.assertEqual(data, ['da', 'ta', '1234567890', '1'])
- self.assertEqual(self.channel.remoteWindowLeft, 5)
- # running out of window
- cb[0] = False
- self.channel.write('123456')
- self.assertFalse(self.channel.areWriting)
- self.assertTrue(cb[0])
- self.assertEqual(data, ['da', 'ta', '1234567890', '1', '12345'])
- self.assertEqual(self.channel.buf, '6')
- self.assertEqual(self.channel.remoteWindowLeft, 0)
-
- def test_writeExtended(self):
- """
- Test that writeExtended handles data correctly. Send extended data
- up to the size of the window, splitting the extended data into packets
- of length remoteMaxPacket.
- """
- cb = [False]
- def stubStopWriting():
- cb[0] = True
- # no window to start with
- self.channel.stopWriting = stubStopWriting
- self.channel.writeExtended(1, 'd')
- self.channel.writeExtended(1, 'a')
- self.channel.writeExtended(2, 't')
- self.assertFalse(self.channel.areWriting)
- self.assertTrue(cb[0])
- # regular write
- self.channel.addWindowBytes(20)
- self.channel.writeExtended(2, 'a')
- data = self.conn.extData[self.channel]
- self.assertEqual(data, [(1, 'da'), (2, 't'), (2, 'a')])
- self.assertEqual(self.channel.remoteWindowLeft, 16)
- # larger than max packet
- self.channel.writeExtended(3, '12345678901')
- self.assertEqual(data, [(1, 'da'), (2, 't'), (2, 'a'),
- (3, '1234567890'), (3, '1')])
- self.assertEqual(self.channel.remoteWindowLeft, 5)
- # running out of window
- cb[0] = False
- self.channel.writeExtended(4, '123456')
- self.assertFalse(self.channel.areWriting)
- self.assertTrue(cb[0])
- self.assertEqual(data, [(1, 'da'), (2, 't'), (2, 'a'),
- (3, '1234567890'), (3, '1'), (4, '12345')])
- self.assertEqual(self.channel.extBuf, [[4, '6']])
- self.assertEqual(self.channel.remoteWindowLeft, 0)
-
- def test_writeSequence(self):
- """
- Test that writeSequence is equivalent to write(''.join(sequece)).
- """
- self.channel.addWindowBytes(20)
- self.channel.writeSequence(map(str, range(10)))
- self.assertEqual(self.conn.data[self.channel], ['0123456789'])
-
- def test_loseConnection(self):
- """
- Tesyt that loseConnection() doesn't close the channel until all
- the data is sent.
- """
- self.channel.write('data')
- self.channel.writeExtended(1, 'datadata')
- self.channel.loseConnection()
- self.assertEqual(self.conn.closes.get(self.channel), None)
- self.channel.addWindowBytes(4) # send regular data
- self.assertEqual(self.conn.closes.get(self.channel), None)
- self.channel.addWindowBytes(8) # send extended data
- self.assertTrue(self.conn.closes.get(self.channel))
-
- def test_getPeer(self):
- """
- Test that getPeer() returns ('SSH', <connection transport peer>).
- """
- self.assertEqual(self.channel.getPeer(), ('SSH', 'MockPeer'))
-
- def test_getHost(self):
- """
- Test that getHost() returns ('SSH', <connection transport host>).
- """
- self.assertEqual(self.channel.getHost(), ('SSH', 'MockHost'))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py
deleted file mode 100755
index 9c85050b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py
+++ /dev/null
@@ -1,609 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.checkers}.
-"""
-
-try:
- import crypt
-except ImportError:
- cryptSkip = 'cannot run without crypt module'
-else:
- cryptSkip = None
-
-import os, base64
-
-from twisted.python import util
-from twisted.python.failure import Failure
-from twisted.trial.unittest import TestCase
-from twisted.python.filepath import FilePath
-from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
-from twisted.cred.credentials import UsernamePassword, IUsernamePassword, \
- SSHPrivateKey, ISSHPrivateKey
-from twisted.cred.error import UnhandledCredentials, UnauthorizedLogin
-from twisted.python.fakepwd import UserDatabase, ShadowDatabase
-from twisted.test.test_process import MockOS
-
-try:
- import Crypto.Cipher.DES3
- import pyasn1
-except ImportError:
- dependencySkip = "can't run without Crypto and PyASN1"
-else:
- dependencySkip = None
- from twisted.conch.ssh import keys
- from twisted.conch import checkers
- from twisted.conch.error import NotEnoughAuthentication, ValidPublicKey
- from twisted.conch.test import keydata
-
-if getattr(os, 'geteuid', None) is None:
- euidSkip = "Cannot run without effective UIDs (questionable)"
-else:
- euidSkip = None
-
-
-class HelperTests(TestCase):
- """
- Tests for helper functions L{verifyCryptedPassword}, L{_pwdGetByName} and
- L{_shadowGetByName}.
- """
- skip = cryptSkip or dependencySkip
-
- def setUp(self):
- self.mockos = MockOS()
-
-
- def test_verifyCryptedPassword(self):
- """
- L{verifyCryptedPassword} returns C{True} if the plaintext password
- passed to it matches the encrypted password passed to it.
- """
- password = 'secret string'
- salt = 'salty'
- crypted = crypt.crypt(password, salt)
- self.assertTrue(
- checkers.verifyCryptedPassword(crypted, password),
- '%r supposed to be valid encrypted password for %r' % (
- crypted, password))
-
-
- def test_verifyCryptedPasswordMD5(self):
- """
- L{verifyCryptedPassword} returns True if the provided cleartext password
- matches the provided MD5 password hash.
- """
- password = 'password'
- salt = '$1$salt'
- crypted = crypt.crypt(password, salt)
- self.assertTrue(
- checkers.verifyCryptedPassword(crypted, password),
- '%r supposed to be valid encrypted password for %s' % (
- crypted, password))
-
-
- def test_refuteCryptedPassword(self):
- """
- L{verifyCryptedPassword} returns C{False} if the plaintext password
- passed to it does not match the encrypted password passed to it.
- """
- password = 'string secret'
- wrong = 'secret string'
- crypted = crypt.crypt(password, password)
- self.assertFalse(
- checkers.verifyCryptedPassword(crypted, wrong),
- '%r not supposed to be valid encrypted password for %s' % (
- crypted, wrong))
-
-
- def test_pwdGetByName(self):
- """
- L{_pwdGetByName} returns a tuple of items from the UNIX /etc/passwd
- database if the L{pwd} module is present.
- """
- userdb = UserDatabase()
- userdb.addUser(
- 'alice', 'secrit', 1, 2, 'first last', '/foo', '/bin/sh')
- self.patch(checkers, 'pwd', userdb)
- self.assertEquals(
- checkers._pwdGetByName('alice'), userdb.getpwnam('alice'))
-
-
- def test_pwdGetByNameWithoutPwd(self):
- """
- If the C{pwd} module isn't present, L{_pwdGetByName} returns C{None}.
- """
- self.patch(checkers, 'pwd', None)
- self.assertIdentical(checkers._pwdGetByName('alice'), None)
-
-
- def test_shadowGetByName(self):
- """
- L{_shadowGetByName} returns a tuple of items from the UNIX /etc/shadow
- database if the L{spwd} is present.
- """
- userdb = ShadowDatabase()
- userdb.addUser('bob', 'passphrase', 1, 2, 3, 4, 5, 6, 7)
- self.patch(checkers, 'spwd', userdb)
-
- self.mockos.euid = 2345
- self.mockos.egid = 1234
- self.patch(checkers, 'os', self.mockos)
- self.patch(util, 'os', self.mockos)
-
- self.assertEquals(
- checkers._shadowGetByName('bob'), userdb.getspnam('bob'))
- self.assertEquals(self.mockos.seteuidCalls, [0, 2345])
- self.assertEquals(self.mockos.setegidCalls, [0, 1234])
-
-
- def test_shadowGetByNameWithoutSpwd(self):
- """
- L{_shadowGetByName} uses the C{shadow} module to return a tuple of items
- from the UNIX /etc/shadow database if the C{spwd} module is not present
- and the C{shadow} module is.
- """
- userdb = ShadowDatabase()
- userdb.addUser('bob', 'passphrase', 1, 2, 3, 4, 5, 6, 7)
- self.patch(checkers, 'spwd', None)
- self.patch(checkers, 'shadow', userdb)
- self.patch(checkers, 'os', self.mockos)
- self.patch(util, 'os', self.mockos)
-
- self.mockos.euid = 2345
- self.mockos.egid = 1234
-
- self.assertEquals(
- checkers._shadowGetByName('bob'), userdb.getspnam('bob'))
- self.assertEquals(self.mockos.seteuidCalls, [0, 2345])
- self.assertEquals(self.mockos.setegidCalls, [0, 1234])
-
-
- def test_shadowGetByNameWithoutEither(self):
- """
- L{_shadowGetByName} returns C{None} if neither C{spwd} nor C{shadow} is
- present.
- """
- self.patch(checkers, 'spwd', None)
- self.patch(checkers, 'shadow', None)
- self.patch(checkers, 'os', self.mockos)
-
- self.assertIdentical(checkers._shadowGetByName('bob'), None)
- self.assertEquals(self.mockos.seteuidCalls, [])
- self.assertEquals(self.mockos.setegidCalls, [])
-
-
-
-class SSHPublicKeyDatabaseTestCase(TestCase):
- """
- Tests for L{SSHPublicKeyDatabase}.
- """
- skip = euidSkip or dependencySkip
-
- def setUp(self):
- self.checker = checkers.SSHPublicKeyDatabase()
- self.key1 = base64.encodestring("foobar")
- self.key2 = base64.encodestring("eggspam")
- self.content = "t1 %s foo\nt2 %s egg\n" % (self.key1, self.key2)
-
- self.mockos = MockOS()
- self.mockos.path = FilePath(self.mktemp())
- self.mockos.path.makedirs()
- self.patch(checkers, 'os', self.mockos)
- self.patch(util, 'os', self.mockos)
- self.sshDir = self.mockos.path.child('.ssh')
- self.sshDir.makedirs()
-
- userdb = UserDatabase()
- userdb.addUser(
- 'user', 'password', 1, 2, 'first last',
- self.mockos.path.path, '/bin/shell')
- self.checker._userdb = userdb
-
-
- def _testCheckKey(self, filename):
- self.sshDir.child(filename).setContent(self.content)
- user = UsernamePassword("user", "password")
- user.blob = "foobar"
- self.assertTrue(self.checker.checkKey(user))
- user.blob = "eggspam"
- self.assertTrue(self.checker.checkKey(user))
- user.blob = "notallowed"
- self.assertFalse(self.checker.checkKey(user))
-
-
- def test_checkKey(self):
- """
- L{SSHPublicKeyDatabase.checkKey} should retrieve the content of the
- authorized_keys file and check the keys against that file.
- """
- self._testCheckKey("authorized_keys")
- self.assertEqual(self.mockos.seteuidCalls, [])
- self.assertEqual(self.mockos.setegidCalls, [])
-
-
- def test_checkKey2(self):
- """
- L{SSHPublicKeyDatabase.checkKey} should retrieve the content of the
- authorized_keys2 file and check the keys against that file.
- """
- self._testCheckKey("authorized_keys2")
- self.assertEqual(self.mockos.seteuidCalls, [])
- self.assertEqual(self.mockos.setegidCalls, [])
-
-
- def test_checkKeyAsRoot(self):
- """
- If the key file is readable, L{SSHPublicKeyDatabase.checkKey} should
- switch its uid/gid to the ones of the authenticated user.
- """
- keyFile = self.sshDir.child("authorized_keys")
- keyFile.setContent(self.content)
- # Fake permission error by changing the mode
- keyFile.chmod(0000)
- self.addCleanup(keyFile.chmod, 0777)
- # And restore the right mode when seteuid is called
- savedSeteuid = self.mockos.seteuid
- def seteuid(euid):
- keyFile.chmod(0777)
- return savedSeteuid(euid)
- self.mockos.euid = 2345
- self.mockos.egid = 1234
- self.patch(self.mockos, "seteuid", seteuid)
- self.patch(checkers, 'os', self.mockos)
- self.patch(util, 'os', self.mockos)
- user = UsernamePassword("user", "password")
- user.blob = "foobar"
- self.assertTrue(self.checker.checkKey(user))
- self.assertEqual(self.mockos.seteuidCalls, [0, 1, 0, 2345])
- self.assertEqual(self.mockos.setegidCalls, [2, 1234])
-
-
- def test_requestAvatarId(self):
- """
- L{SSHPublicKeyDatabase.requestAvatarId} should return the avatar id
- passed in if its C{_checkKey} method returns True.
- """
- def _checkKey(ignored):
- return True
- self.patch(self.checker, 'checkKey', _checkKey)
- credentials = SSHPrivateKey(
- 'test', 'ssh-rsa', keydata.publicRSA_openssh, 'foo',
- keys.Key.fromString(keydata.privateRSA_openssh).sign('foo'))
- d = self.checker.requestAvatarId(credentials)
- def _verify(avatarId):
- self.assertEqual(avatarId, 'test')
- return d.addCallback(_verify)
-
-
- def test_requestAvatarIdWithoutSignature(self):
- """
- L{SSHPublicKeyDatabase.requestAvatarId} should raise L{ValidPublicKey}
- if the credentials represent a valid key without a signature. This
- tells the user that the key is valid for login, but does not actually
- allow that user to do so without a signature.
- """
- def _checkKey(ignored):
- return True
- self.patch(self.checker, 'checkKey', _checkKey)
- credentials = SSHPrivateKey(
- 'test', 'ssh-rsa', keydata.publicRSA_openssh, None, None)
- d = self.checker.requestAvatarId(credentials)
- return self.assertFailure(d, ValidPublicKey)
-
-
- def test_requestAvatarIdInvalidKey(self):
- """
- If L{SSHPublicKeyDatabase.checkKey} returns False,
- C{_cbRequestAvatarId} should raise L{UnauthorizedLogin}.
- """
- def _checkKey(ignored):
- return False
- self.patch(self.checker, 'checkKey', _checkKey)
- d = self.checker.requestAvatarId(None);
- return self.assertFailure(d, UnauthorizedLogin)
-
-
- def test_requestAvatarIdInvalidSignature(self):
- """
- Valid keys with invalid signatures should cause
- L{SSHPublicKeyDatabase.requestAvatarId} to return a {UnauthorizedLogin}
- failure
- """
- def _checkKey(ignored):
- return True
- self.patch(self.checker, 'checkKey', _checkKey)
- credentials = SSHPrivateKey(
- 'test', 'ssh-rsa', keydata.publicRSA_openssh, 'foo',
- keys.Key.fromString(keydata.privateDSA_openssh).sign('foo'))
- d = self.checker.requestAvatarId(credentials)
- return self.assertFailure(d, UnauthorizedLogin)
-
-
- def test_requestAvatarIdNormalizeException(self):
- """
- Exceptions raised while verifying the key should be normalized into an
- C{UnauthorizedLogin} failure.
- """
- def _checkKey(ignored):
- return True
- self.patch(self.checker, 'checkKey', _checkKey)
- credentials = SSHPrivateKey('test', None, 'blob', 'sigData', 'sig')
- d = self.checker.requestAvatarId(credentials)
- def _verifyLoggedException(failure):
- errors = self.flushLoggedErrors(keys.BadKeyError)
- self.assertEqual(len(errors), 1)
- return failure
- d.addErrback(_verifyLoggedException)
- return self.assertFailure(d, UnauthorizedLogin)
-
-
-
-class SSHProtocolCheckerTestCase(TestCase):
- """
- Tests for L{SSHProtocolChecker}.
- """
-
- skip = dependencySkip
-
- def test_registerChecker(self):
- """
- L{SSHProcotolChecker.registerChecker} should add the given checker to
- the list of registered checkers.
- """
- checker = checkers.SSHProtocolChecker()
- self.assertEqual(checker.credentialInterfaces, [])
- checker.registerChecker(checkers.SSHPublicKeyDatabase(), )
- self.assertEqual(checker.credentialInterfaces, [ISSHPrivateKey])
- self.assertIsInstance(checker.checkers[ISSHPrivateKey],
- checkers.SSHPublicKeyDatabase)
-
-
- def test_registerCheckerWithInterface(self):
- """
- If a apecific interface is passed into
- L{SSHProtocolChecker.registerChecker}, that interface should be
- registered instead of what the checker specifies in
- credentialIntefaces.
- """
- checker = checkers.SSHProtocolChecker()
- self.assertEqual(checker.credentialInterfaces, [])
- checker.registerChecker(checkers.SSHPublicKeyDatabase(),
- IUsernamePassword)
- self.assertEqual(checker.credentialInterfaces, [IUsernamePassword])
- self.assertIsInstance(checker.checkers[IUsernamePassword],
- checkers.SSHPublicKeyDatabase)
-
-
- def test_requestAvatarId(self):
- """
- L{SSHProtocolChecker.requestAvatarId} should defer to one if its
- registered checkers to authenticate a user.
- """
- checker = checkers.SSHProtocolChecker()
- passwordDatabase = InMemoryUsernamePasswordDatabaseDontUse()
- passwordDatabase.addUser('test', 'test')
- checker.registerChecker(passwordDatabase)
- d = checker.requestAvatarId(UsernamePassword('test', 'test'))
- def _callback(avatarId):
- self.assertEqual(avatarId, 'test')
- return d.addCallback(_callback)
-
-
- def test_requestAvatarIdWithNotEnoughAuthentication(self):
- """
- If the client indicates that it is never satisfied, by always returning
- False from _areDone, then L{SSHProtocolChecker} should raise
- L{NotEnoughAuthentication}.
- """
- checker = checkers.SSHProtocolChecker()
- def _areDone(avatarId):
- return False
- self.patch(checker, 'areDone', _areDone)
-
- passwordDatabase = InMemoryUsernamePasswordDatabaseDontUse()
- passwordDatabase.addUser('test', 'test')
- checker.registerChecker(passwordDatabase)
- d = checker.requestAvatarId(UsernamePassword('test', 'test'))
- return self.assertFailure(d, NotEnoughAuthentication)
-
-
- def test_requestAvatarIdInvalidCredential(self):
- """
- If the passed credentials aren't handled by any registered checker,
- L{SSHProtocolChecker} should raise L{UnhandledCredentials}.
- """
- checker = checkers.SSHProtocolChecker()
- d = checker.requestAvatarId(UsernamePassword('test', 'test'))
- return self.assertFailure(d, UnhandledCredentials)
-
-
- def test_areDone(self):
- """
- The default L{SSHProcotolChecker.areDone} should simply return True.
- """
- self.assertEquals(checkers.SSHProtocolChecker().areDone(None), True)
-
-
-
-class UNIXPasswordDatabaseTests(TestCase):
- """
- Tests for L{UNIXPasswordDatabase}.
- """
- skip = cryptSkip or dependencySkip
-
- def assertLoggedIn(self, d, username):
- """
- Assert that the L{Deferred} passed in is called back with the value
- 'username'. This represents a valid login for this TestCase.
-
- NOTE: To work, this method's return value must be returned from the
- test method, or otherwise hooked up to the test machinery.
-
- @param d: a L{Deferred} from an L{IChecker.requestAvatarId} method.
- @type d: L{Deferred}
- @rtype: L{Deferred}
- """
- result = []
- d.addBoth(result.append)
- self.assertEquals(len(result), 1, "login incomplete")
- if isinstance(result[0], Failure):
- result[0].raiseException()
- self.assertEquals(result[0], username)
-
-
- def test_defaultCheckers(self):
- """
- L{UNIXPasswordDatabase} with no arguments has checks the C{pwd} database
- and then the C{spwd} database.
- """
- checker = checkers.UNIXPasswordDatabase()
-
- def crypted(username, password):
- salt = crypt.crypt(password, username)
- crypted = crypt.crypt(password, '$1$' + salt)
- return crypted
-
- pwd = UserDatabase()
- pwd.addUser('alice', crypted('alice', 'password'),
- 1, 2, 'foo', '/foo', '/bin/sh')
- # x and * are convention for "look elsewhere for the password"
- pwd.addUser('bob', 'x', 1, 2, 'bar', '/bar', '/bin/sh')
- spwd = ShadowDatabase()
- spwd.addUser('alice', 'wrong', 1, 2, 3, 4, 5, 6, 7)
- spwd.addUser('bob', crypted('bob', 'password'),
- 8, 9, 10, 11, 12, 13, 14)
-
- self.patch(checkers, 'pwd', pwd)
- self.patch(checkers, 'spwd', spwd)
-
- mockos = MockOS()
- self.patch(checkers, 'os', mockos)
- self.patch(util, 'os', mockos)
-
- mockos.euid = 2345
- mockos.egid = 1234
-
- cred = UsernamePassword("alice", "password")
- self.assertLoggedIn(checker.requestAvatarId(cred), 'alice')
- self.assertEquals(mockos.seteuidCalls, [])
- self.assertEquals(mockos.setegidCalls, [])
- cred.username = "bob"
- self.assertLoggedIn(checker.requestAvatarId(cred), 'bob')
- self.assertEquals(mockos.seteuidCalls, [0, 2345])
- self.assertEquals(mockos.setegidCalls, [0, 1234])
-
-
- def assertUnauthorizedLogin(self, d):
- """
- Asserts that the L{Deferred} passed in is erred back with an
- L{UnauthorizedLogin} L{Failure}. This reprsents an invalid login for
- this TestCase.
-
- NOTE: To work, this method's return value must be returned from the
- test method, or otherwise hooked up to the test machinery.
-
- @param d: a L{Deferred} from an L{IChecker.requestAvatarId} method.
- @type d: L{Deferred}
- @rtype: L{None}
- """
- self.assertRaises(
- checkers.UnauthorizedLogin, self.assertLoggedIn, d, 'bogus value')
-
-
- def test_passInCheckers(self):
- """
- L{UNIXPasswordDatabase} takes a list of functions to check for UNIX
- user information.
- """
- password = crypt.crypt('secret', 'secret')
- userdb = UserDatabase()
- userdb.addUser('anybody', password, 1, 2, 'foo', '/bar', '/bin/sh')
- checker = checkers.UNIXPasswordDatabase([userdb.getpwnam])
- self.assertLoggedIn(
- checker.requestAvatarId(UsernamePassword('anybody', 'secret')),
- 'anybody')
-
-
- def test_verifyPassword(self):
- """
- If the encrypted password provided by the getpwnam function is valid
- (verified by the L{verifyCryptedPassword} function), we callback the
- C{requestAvatarId} L{Deferred} with the username.
- """
- def verifyCryptedPassword(crypted, pw):
- return crypted == pw
- def getpwnam(username):
- return [username, username]
- self.patch(checkers, 'verifyCryptedPassword', verifyCryptedPassword)
- checker = checkers.UNIXPasswordDatabase([getpwnam])
- credential = UsernamePassword('username', 'username')
- self.assertLoggedIn(checker.requestAvatarId(credential), 'username')
-
-
- def test_failOnKeyError(self):
- """
- If the getpwnam function raises a KeyError, the login fails with an
- L{UnauthorizedLogin} exception.
- """
- def getpwnam(username):
- raise KeyError(username)
- checker = checkers.UNIXPasswordDatabase([getpwnam])
- credential = UsernamePassword('username', 'username')
- self.assertUnauthorizedLogin(checker.requestAvatarId(credential))
-
-
- def test_failOnBadPassword(self):
- """
- If the verifyCryptedPassword function doesn't verify the password, the
- login fails with an L{UnauthorizedLogin} exception.
- """
- def verifyCryptedPassword(crypted, pw):
- return False
- def getpwnam(username):
- return [username, username]
- self.patch(checkers, 'verifyCryptedPassword', verifyCryptedPassword)
- checker = checkers.UNIXPasswordDatabase([getpwnam])
- credential = UsernamePassword('username', 'username')
- self.assertUnauthorizedLogin(checker.requestAvatarId(credential))
-
-
- def test_loopThroughFunctions(self):
- """
- UNIXPasswordDatabase.requestAvatarId loops through each getpwnam
- function associated with it and returns a L{Deferred} which fires with
- the result of the first one which returns a value other than None.
- ones do not verify the password.
- """
- def verifyCryptedPassword(crypted, pw):
- return crypted == pw
- def getpwnam1(username):
- return [username, 'not the password']
- def getpwnam2(username):
- return [username, username]
- self.patch(checkers, 'verifyCryptedPassword', verifyCryptedPassword)
- checker = checkers.UNIXPasswordDatabase([getpwnam1, getpwnam2])
- credential = UsernamePassword('username', 'username')
- self.assertLoggedIn(checker.requestAvatarId(credential), 'username')
-
-
- def test_failOnSpecial(self):
- """
- If the password returned by any function is C{""}, C{"x"}, or C{"*"} it
- is not compared against the supplied password. Instead it is skipped.
- """
- pwd = UserDatabase()
- pwd.addUser('alice', '', 1, 2, '', 'foo', 'bar')
- pwd.addUser('bob', 'x', 1, 2, '', 'foo', 'bar')
- pwd.addUser('carol', '*', 1, 2, '', 'foo', 'bar')
- self.patch(checkers, 'pwd', pwd)
-
- checker = checkers.UNIXPasswordDatabase([checkers._pwdGetByName])
- cred = UsernamePassword('alice', '')
- self.assertUnauthorizedLogin(checker.requestAvatarId(cred))
-
- cred = UsernamePassword('bob', 'x')
- self.assertUnauthorizedLogin(checker.requestAvatarId(cred))
-
- cred = UsernamePassword('carol', '*')
- self.assertUnauthorizedLogin(checker.requestAvatarId(cred))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py
deleted file mode 100755
index df437e2d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.scripts.ckeygen}.
-"""
-
-import sys
-from StringIO import StringIO
-
-try:
- import Crypto
- import pyasn1
-except ImportError:
- skip = "PyCrypto and pyasn1 required for twisted.conch.scripts.ckeygen."
-else:
- from twisted.conch.ssh.keys import Key
- from twisted.conch.scripts.ckeygen import printFingerprint, _saveKey
-
-from twisted.python.filepath import FilePath
-from twisted.trial.unittest import TestCase
-from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh
-
-
-
-class KeyGenTests(TestCase):
- """
- Tests for various functions used to implement the I{ckeygen} script.
- """
- def setUp(self):
- """
- Patch C{sys.stdout} with a L{StringIO} instance to tests can make
- assertions about what's printed.
- """
- self.stdout = StringIO()
- self.patch(sys, 'stdout', self.stdout)
-
-
- def test_printFingerprint(self):
- """
- L{printFingerprint} writes a line to standard out giving the number of
- bits of the key, its fingerprint, and the basename of the file from it
- was read.
- """
- filename = self.mktemp()
- FilePath(filename).setContent(publicRSA_openssh)
- printFingerprint({'filename': filename})
- self.assertEqual(
- self.stdout.getvalue(),
- '768 3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af temp\n')
-
-
- def test_saveKey(self):
- """
- L{_saveKey} writes the private and public parts of a key to two
- different files and writes a report of this to standard out.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- filename = base.child('id_rsa').path
- key = Key.fromString(privateRSA_openssh)
- _saveKey(
- key.keyObject,
- {'filename': filename, 'pass': 'passphrase'})
- self.assertEqual(
- self.stdout.getvalue(),
- "Your identification has been saved in %s\n"
- "Your public key has been saved in %s.pub\n"
- "The key fingerprint is:\n"
- "3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af\n" % (
- filename,
- filename))
- self.assertEqual(
- key.fromString(
- base.child('id_rsa').getContent(), None, 'passphrase'),
- key)
- self.assertEqual(
- Key.fromString(base.child('id_rsa.pub').getContent()),
- key.public())
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py
deleted file mode 100755
index 95219d4d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py
+++ /dev/null
@@ -1,552 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_conch -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import os, sys, socket
-from itertools import count
-
-from zope.interface import implements
-
-from twisted.cred import portal
-from twisted.internet import reactor, defer, protocol
-from twisted.internet.error import ProcessExitedAlready
-from twisted.internet.task import LoopingCall
-from twisted.python import log, runtime
-from twisted.trial import unittest
-from twisted.conch.error import ConchError
-from twisted.conch.avatar import ConchUser
-from twisted.conch.ssh.session import ISession, SSHSession, wrapProtocol
-
-try:
- from twisted.conch.scripts.conch import SSHSession as StdioInteractingSession
-except ImportError, e:
- StdioInteractingSession = None
- _reason = str(e)
- del e
-
-from twisted.conch.test.test_ssh import ConchTestRealm
-from twisted.python.procutils import which
-
-from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh
-from twisted.conch.test.keydata import publicDSA_openssh, privateDSA_openssh
-
-from twisted.conch.test.test_ssh import Crypto, pyasn1
-try:
- from twisted.conch.test.test_ssh import ConchTestServerFactory, \
- ConchTestPublicKeyChecker
-except ImportError:
- pass
-
-
-
-class StdioInteractingSessionTests(unittest.TestCase):
- """
- Tests for L{twisted.conch.scripts.conch.SSHSession}.
- """
- if StdioInteractingSession is None:
- skip = _reason
-
- def test_eofReceived(self):
- """
- L{twisted.conch.scripts.conch.SSHSession.eofReceived} loses the
- write half of its stdio connection.
- """
- class FakeStdio:
- writeConnLost = False
-
- def loseWriteConnection(self):
- self.writeConnLost = True
-
- stdio = FakeStdio()
- channel = StdioInteractingSession()
- channel.stdio = stdio
- channel.eofReceived()
- self.assertTrue(stdio.writeConnLost)
-
-
-
-class Echo(protocol.Protocol):
- def connectionMade(self):
- log.msg('ECHO CONNECTION MADE')
-
-
- def connectionLost(self, reason):
- log.msg('ECHO CONNECTION DONE')
-
-
- def dataReceived(self, data):
- self.transport.write(data)
- if '\n' in data:
- self.transport.loseConnection()
-
-
-
-class EchoFactory(protocol.Factory):
- protocol = Echo
-
-
-
-class ConchTestOpenSSHProcess(protocol.ProcessProtocol):
- """
- Test protocol for launching an OpenSSH client process.
-
- @ivar deferred: Set by whatever uses this object. Accessed using
- L{_getDeferred}, which destroys the value so the Deferred is not
- fired twice. Fires when the process is terminated.
- """
-
- deferred = None
- buf = ''
-
- def _getDeferred(self):
- d, self.deferred = self.deferred, None
- return d
-
-
- def outReceived(self, data):
- self.buf += data
-
-
- def processEnded(self, reason):
- """
- Called when the process has ended.
-
- @param reason: a Failure giving the reason for the process' end.
- """
- if reason.value.exitCode != 0:
- self._getDeferred().errback(
- ConchError("exit code was not 0: %s" %
- reason.value.exitCode))
- else:
- buf = self.buf.replace('\r\n', '\n')
- self._getDeferred().callback(buf)
-
-
-
-class ConchTestForwardingProcess(protocol.ProcessProtocol):
- """
- Manages a third-party process which launches a server.
-
- Uses L{ConchTestForwardingPort} to connect to the third-party server.
- Once L{ConchTestForwardingPort} has disconnected, kill the process and fire
- a Deferred with the data received by the L{ConchTestForwardingPort}.
-
- @ivar deferred: Set by whatever uses this object. Accessed using
- L{_getDeferred}, which destroys the value so the Deferred is not
- fired twice. Fires when the process is terminated.
- """
-
- deferred = None
-
- def __init__(self, port, data):
- """
- @type port: C{int}
- @param port: The port on which the third-party server is listening.
- (it is assumed that the server is running on localhost).
-
- @type data: C{str}
- @param data: This is sent to the third-party server. Must end with '\n'
- in order to trigger a disconnect.
- """
- self.port = port
- self.buffer = None
- self.data = data
-
-
- def _getDeferred(self):
- d, self.deferred = self.deferred, None
- return d
-
-
- def connectionMade(self):
- self._connect()
-
-
- def _connect(self):
- """
- Connect to the server, which is often a third-party process.
- Tries to reconnect if it fails because we have no way of determining
- exactly when the port becomes available for listening -- we can only
- know when the process starts.
- """
- cc = protocol.ClientCreator(reactor, ConchTestForwardingPort, self,
- self.data)
- d = cc.connectTCP('127.0.0.1', self.port)
- d.addErrback(self._ebConnect)
- return d
-
-
- def _ebConnect(self, f):
- reactor.callLater(.1, self._connect)
-
-
- def forwardingPortDisconnected(self, buffer):
- """
- The network connection has died; save the buffer of output
- from the network and attempt to quit the process gracefully,
- and then (after the reactor has spun) send it a KILL signal.
- """
- self.buffer = buffer
- self.transport.write('\x03')
- self.transport.loseConnection()
- reactor.callLater(0, self._reallyDie)
-
-
- def _reallyDie(self):
- try:
- self.transport.signalProcess('KILL')
- except ProcessExitedAlready:
- pass
-
-
- def processEnded(self, reason):
- """
- Fire the Deferred at self.deferred with the data collected
- from the L{ConchTestForwardingPort} connection, if any.
- """
- self._getDeferred().callback(self.buffer)
-
-
-
-class ConchTestForwardingPort(protocol.Protocol):
- """
- Connects to server launched by a third-party process (managed by
- L{ConchTestForwardingProcess}) sends data, then reports whatever it
- received back to the L{ConchTestForwardingProcess} once the connection
- is ended.
- """
-
-
- def __init__(self, protocol, data):
- """
- @type protocol: L{ConchTestForwardingProcess}
- @param protocol: The L{ProcessProtocol} which made this connection.
-
- @type data: str
- @param data: The data to be sent to the third-party server.
- """
- self.protocol = protocol
- self.data = data
-
-
- def connectionMade(self):
- self.buffer = ''
- self.transport.write(self.data)
-
-
- def dataReceived(self, data):
- self.buffer += data
-
-
- def connectionLost(self, reason):
- self.protocol.forwardingPortDisconnected(self.buffer)
-
-
-
-def _makeArgs(args, mod="conch"):
- start = [sys.executable, '-c'
-"""
-### Twisted Preamble
-import sys, os
-path = os.path.abspath(sys.argv[0])
-while os.path.dirname(path) != path:
- if os.path.basename(path).startswith('Twisted'):
- sys.path.insert(0, path)
- break
- path = os.path.dirname(path)
-
-from twisted.conch.scripts.%s import run
-run()""" % mod]
- return start + list(args)
-
-
-
-class ConchServerSetupMixin:
- if not Crypto:
- skip = "can't run w/o PyCrypto"
-
- if not pyasn1:
- skip = "Cannot run without PyASN1"
-
- realmFactory = staticmethod(lambda: ConchTestRealm('testuser'))
-
- def _createFiles(self):
- for f in ['rsa_test','rsa_test.pub','dsa_test','dsa_test.pub',
- 'kh_test']:
- if os.path.exists(f):
- os.remove(f)
- open('rsa_test','w').write(privateRSA_openssh)
- open('rsa_test.pub','w').write(publicRSA_openssh)
- open('dsa_test.pub','w').write(publicDSA_openssh)
- open('dsa_test','w').write(privateDSA_openssh)
- os.chmod('dsa_test', 33152)
- os.chmod('rsa_test', 33152)
- open('kh_test','w').write('127.0.0.1 '+publicRSA_openssh)
-
-
- def _getFreePort(self):
- s = socket.socket()
- s.bind(('', 0))
- port = s.getsockname()[1]
- s.close()
- return port
-
-
- def _makeConchFactory(self):
- """
- Make a L{ConchTestServerFactory}, which allows us to start a
- L{ConchTestServer} -- i.e. an actually listening conch.
- """
- realm = self.realmFactory()
- p = portal.Portal(realm)
- p.registerChecker(ConchTestPublicKeyChecker())
- factory = ConchTestServerFactory()
- factory.portal = p
- return factory
-
-
- def setUp(self):
- self._createFiles()
- self.conchFactory = self._makeConchFactory()
- self.conchFactory.expectedLoseConnection = 1
- self.conchServer = reactor.listenTCP(0, self.conchFactory,
- interface="127.0.0.1")
- self.echoServer = reactor.listenTCP(0, EchoFactory())
- self.echoPort = self.echoServer.getHost().port
-
-
- def tearDown(self):
- try:
- self.conchFactory.proto.done = 1
- except AttributeError:
- pass
- else:
- self.conchFactory.proto.transport.loseConnection()
- return defer.gatherResults([
- defer.maybeDeferred(self.conchServer.stopListening),
- defer.maybeDeferred(self.echoServer.stopListening)])
-
-
-
-class ForwardingMixin(ConchServerSetupMixin):
- """
- Template class for tests of the Conch server's ability to forward arbitrary
- protocols over SSH.
-
- These tests are integration tests, not unit tests. They launch a Conch
- server, a custom TCP server (just an L{EchoProtocol}) and then call
- L{execute}.
-
- L{execute} is implemented by subclasses of L{ForwardingMixin}. It should
- cause an SSH client to connect to the Conch server, asking it to forward
- data to the custom TCP server.
- """
-
- def test_exec(self):
- """
- Test that we can use whatever client to send the command "echo goodbye"
- to the Conch server. Make sure we receive "goodbye" back from the
- server.
- """
- d = self.execute('echo goodbye', ConchTestOpenSSHProcess())
- return d.addCallback(self.assertEqual, 'goodbye\n')
-
-
- def test_localToRemoteForwarding(self):
- """
- Test that we can use whatever client to forward a local port to a
- specified port on the server.
- """
- localPort = self._getFreePort()
- process = ConchTestForwardingProcess(localPort, 'test\n')
- d = self.execute('', process,
- sshArgs='-N -L%i:127.0.0.1:%i'
- % (localPort, self.echoPort))
- d.addCallback(self.assertEqual, 'test\n')
- return d
-
-
- def test_remoteToLocalForwarding(self):
- """
- Test that we can use whatever client to forward a port from the server
- to a port locally.
- """
- localPort = self._getFreePort()
- process = ConchTestForwardingProcess(localPort, 'test\n')
- d = self.execute('', process,
- sshArgs='-N -R %i:127.0.0.1:%i'
- % (localPort, self.echoPort))
- d.addCallback(self.assertEqual, 'test\n')
- return d
-
-
-
-class RekeyAvatar(ConchUser):
- """
- This avatar implements a shell which sends 60 numbered lines to whatever
- connects to it, then closes the session with a 0 exit status.
-
- 60 lines is selected as being enough to send more than 2kB of traffic, the
- amount the client is configured to initiate a rekey after.
- """
- # Conventionally there is a separate adapter object which provides ISession
- # for the user, but making the user provide ISession directly works too.
- # This isn't a full implementation of ISession though, just enough to make
- # these tests pass.
- implements(ISession)
-
- def __init__(self):
- ConchUser.__init__(self)
- self.channelLookup['session'] = SSHSession
-
-
- def openShell(self, transport):
- """
- Write 60 lines of data to the transport, then exit.
- """
- proto = protocol.Protocol()
- proto.makeConnection(transport)
- transport.makeConnection(wrapProtocol(proto))
-
- # Send enough bytes to the connection so that a rekey is triggered in
- # the client.
- def write(counter):
- i = counter()
- if i == 60:
- call.stop()
- transport.session.conn.sendRequest(
- transport.session, 'exit-status', '\x00\x00\x00\x00')
- transport.loseConnection()
- else:
- transport.write("line #%02d\n" % (i,))
-
- # The timing for this loop is an educated guess (and/or the result of
- # experimentation) to exercise the case where a packet is generated
- # mid-rekey. Since the other side of the connection is (so far) the
- # OpenSSH command line client, there's no easy way to determine when the
- # rekey has been initiated. If there were, then generating a packet
- # immediately at that time would be a better way to test the
- # functionality being tested here.
- call = LoopingCall(write, count().next)
- call.start(0.01)
-
-
- def closed(self):
- """
- Ignore the close of the session.
- """
-
-
-
-class RekeyRealm:
- """
- This realm gives out new L{RekeyAvatar} instances for any avatar request.
- """
- def requestAvatar(self, avatarID, mind, *interfaces):
- return interfaces[0], RekeyAvatar(), lambda: None
-
-
-
-class RekeyTestsMixin(ConchServerSetupMixin):
- """
- TestCase mixin which defines tests exercising L{SSHTransportBase}'s handling
- of rekeying messages.
- """
- realmFactory = RekeyRealm
-
- def test_clientRekey(self):
- """
- After a client-initiated rekey is completed, application data continues
- to be passed over the SSH connection.
- """
- process = ConchTestOpenSSHProcess()
- d = self.execute("", process, '-o RekeyLimit=2K')
- def finished(result):
- self.assertEqual(
- result,
- '\n'.join(['line #%02d' % (i,) for i in range(60)]) + '\n')
- d.addCallback(finished)
- return d
-
-
-
-class OpenSSHClientMixin:
- if not which('ssh'):
- skip = "no ssh command-line client available"
-
- def execute(self, remoteCommand, process, sshArgs=''):
- """
- Connects to the SSH server started in L{ConchServerSetupMixin.setUp} by
- running the 'ssh' command line tool.
-
- @type remoteCommand: str
- @param remoteCommand: The command (with arguments) to run on the
- remote end.
-
- @type process: L{ConchTestOpenSSHProcess}
-
- @type sshArgs: str
- @param sshArgs: Arguments to pass to the 'ssh' process.
-
- @return: L{defer.Deferred}
- """
- process.deferred = defer.Deferred()
- cmdline = ('ssh -2 -l testuser -p %i '
- '-oUserKnownHostsFile=kh_test '
- '-oPasswordAuthentication=no '
- # Always use the RSA key, since that's the one in kh_test.
- '-oHostKeyAlgorithms=ssh-rsa '
- '-a '
- '-i dsa_test ') + sshArgs + \
- ' 127.0.0.1 ' + remoteCommand
- port = self.conchServer.getHost().port
- cmds = (cmdline % port).split()
- reactor.spawnProcess(process, "ssh", cmds)
- return process.deferred
-
-
-
-class OpenSSHClientForwardingTestCase(ForwardingMixin, OpenSSHClientMixin,
- unittest.TestCase):
- """
- Connection forwarding tests run against the OpenSSL command line client.
- """
-
-
-
-class OpenSSHClientRekeyTestCase(RekeyTestsMixin, OpenSSHClientMixin,
- unittest.TestCase):
- """
- Rekeying tests run against the OpenSSL command line client.
- """
-
-
-
-class CmdLineClientTestCase(ForwardingMixin, unittest.TestCase):
- """
- Connection forwarding tests run against the Conch command line client.
- """
- if runtime.platformType == 'win32':
- skip = "can't run cmdline client on win32"
-
- def execute(self, remoteCommand, process, sshArgs=''):
- """
- As for L{OpenSSHClientTestCase.execute}, except it runs the 'conch'
- command line tool, not 'ssh'.
- """
- process.deferred = defer.Deferred()
- port = self.conchServer.getHost().port
- cmd = ('-p %i -l testuser '
- '--known-hosts kh_test '
- '--user-authentications publickey '
- '--host-key-algorithms ssh-rsa '
- '-a '
- '-i dsa_test '
- '-v ') % port + sshArgs + \
- ' 127.0.0.1 ' + remoteCommand
- cmds = _makeArgs(cmd.split())
- log.msg(str(cmds))
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
- reactor.spawnProcess(process, sys.executable, cmds, env=env)
- return process.deferred
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py
deleted file mode 100755
index 85a8e6a7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py
+++ /dev/null
@@ -1,730 +0,0 @@
-# Copyright (c) 2007-2010 Twisted Matrix Laboratories.
-# See LICENSE for details
-
-"""
-This module tests twisted.conch.ssh.connection.
-"""
-
-import struct
-
-from twisted.conch import error
-from twisted.conch.ssh import channel, common, connection
-from twisted.trial import unittest
-from twisted.conch.test import test_userauth
-
-
-class TestChannel(channel.SSHChannel):
- """
- A mocked-up version of twisted.conch.ssh.channel.SSHChannel.
-
- @ivar gotOpen: True if channelOpen has been called.
- @type gotOpen: C{bool}
- @ivar specificData: the specific channel open data passed to channelOpen.
- @type specificData: C{str}
- @ivar openFailureReason: the reason passed to openFailed.
- @type openFailed: C{error.ConchError}
- @ivar inBuffer: a C{list} of strings received by the channel.
- @type inBuffer: C{list}
- @ivar extBuffer: a C{list} of 2-tuples (type, extended data) of received by
- the channel.
- @type extBuffer: C{list}
- @ivar numberRequests: the number of requests that have been made to this
- channel.
- @type numberRequests: C{int}
- @ivar gotEOF: True if the other side sent EOF.
- @type gotEOF: C{bool}
- @ivar gotOneClose: True if the other side closed the connection.
- @type gotOneClose: C{bool}
- @ivar gotClosed: True if the channel is closed.
- @type gotClosed: C{bool}
- """
- name = "TestChannel"
- gotOpen = False
-
- def logPrefix(self):
- return "TestChannel %i" % self.id
-
- def channelOpen(self, specificData):
- """
- The channel is open. Set up the instance variables.
- """
- self.gotOpen = True
- self.specificData = specificData
- self.inBuffer = []
- self.extBuffer = []
- self.numberRequests = 0
- self.gotEOF = False
- self.gotOneClose = False
- self.gotClosed = False
-
- def openFailed(self, reason):
- """
- Opening the channel failed. Store the reason why.
- """
- self.openFailureReason = reason
-
- def request_test(self, data):
- """
- A test request. Return True if data is 'data'.
-
- @type data: C{str}
- """
- self.numberRequests += 1
- return data == 'data'
-
- def dataReceived(self, data):
- """
- Data was received. Store it in the buffer.
- """
- self.inBuffer.append(data)
-
- def extReceived(self, code, data):
- """
- Extended data was received. Store it in the buffer.
- """
- self.extBuffer.append((code, data))
-
- def eofReceived(self):
- """
- EOF was received. Remember it.
- """
- self.gotEOF = True
-
- def closeReceived(self):
- """
- Close was received. Remember it.
- """
- self.gotOneClose = True
-
- def closed(self):
- """
- The channel is closed. Rembember it.
- """
- self.gotClosed = True
-
-class TestAvatar:
- """
- A mocked-up version of twisted.conch.avatar.ConchUser
- """
- _ARGS_ERROR_CODE = 123
-
- def lookupChannel(self, channelType, windowSize, maxPacket, data):
- """
- The server wants us to return a channel. If the requested channel is
- our TestChannel, return it, otherwise return None.
- """
- if channelType == TestChannel.name:
- return TestChannel(remoteWindow=windowSize,
- remoteMaxPacket=maxPacket,
- data=data, avatar=self)
- elif channelType == "conch-error-args":
- # Raise a ConchError with backwards arguments to make sure the
- # connection fixes it for us. This case should be deprecated and
- # deleted eventually, but only after all of Conch gets the argument
- # order right.
- raise error.ConchError(
- self._ARGS_ERROR_CODE, "error args in wrong order")
-
-
- def gotGlobalRequest(self, requestType, data):
- """
- The client has made a global request. If the global request is
- 'TestGlobal', return True. If the global request is 'TestData',
- return True and the request-specific data we received. Otherwise,
- return False.
- """
- if requestType == 'TestGlobal':
- return True
- elif requestType == 'TestData':
- return True, data
- else:
- return False
-
-
-
-class TestConnection(connection.SSHConnection):
- """
- A subclass of SSHConnection for testing.
-
- @ivar channel: the current channel.
- @type channel. C{TestChannel}
- """
-
- def logPrefix(self):
- return "TestConnection"
-
- def global_TestGlobal(self, data):
- """
- The other side made the 'TestGlobal' global request. Return True.
- """
- return True
-
- def global_Test_Data(self, data):
- """
- The other side made the 'Test-Data' global request. Return True and
- the data we received.
- """
- return True, data
-
- def channel_TestChannel(self, windowSize, maxPacket, data):
- """
- The other side is requesting the TestChannel. Create a C{TestChannel}
- instance, store it, and return it.
- """
- self.channel = TestChannel(remoteWindow=windowSize,
- remoteMaxPacket=maxPacket, data=data)
- return self.channel
-
- def channel_ErrorChannel(self, windowSize, maxPacket, data):
- """
- The other side is requesting the ErrorChannel. Raise an exception.
- """
- raise AssertionError('no such thing')
-
-
-
-class ConnectionTestCase(unittest.TestCase):
-
- if test_userauth.transport is None:
- skip = "Cannot run without both PyCrypto and pyasn1"
-
- def setUp(self):
- self.transport = test_userauth.FakeTransport(None)
- self.transport.avatar = TestAvatar()
- self.conn = TestConnection()
- self.conn.transport = self.transport
- self.conn.serviceStarted()
-
- def _openChannel(self, channel):
- """
- Open the channel with the default connection.
- """
- self.conn.openChannel(channel)
- self.transport.packets = self.transport.packets[:-1]
- self.conn.ssh_CHANNEL_OPEN_CONFIRMATION(struct.pack('>2L',
- channel.id, 255) + '\x00\x02\x00\x00\x00\x00\x80\x00')
-
- def tearDown(self):
- self.conn.serviceStopped()
-
- def test_linkAvatar(self):
- """
- Test that the connection links itself to the avatar in the
- transport.
- """
- self.assertIdentical(self.transport.avatar.conn, self.conn)
-
- def test_serviceStopped(self):
- """
- Test that serviceStopped() closes any open channels.
- """
- channel1 = TestChannel()
- channel2 = TestChannel()
- self.conn.openChannel(channel1)
- self.conn.openChannel(channel2)
- self.conn.ssh_CHANNEL_OPEN_CONFIRMATION('\x00\x00\x00\x00' * 4)
- self.assertTrue(channel1.gotOpen)
- self.assertFalse(channel2.gotOpen)
- self.conn.serviceStopped()
- self.assertTrue(channel1.gotClosed)
-
- def test_GLOBAL_REQUEST(self):
- """
- Test that global request packets are dispatched to the global_*
- methods and the return values are translated into success or failure
- messages.
- """
- self.conn.ssh_GLOBAL_REQUEST(common.NS('TestGlobal') + '\xff')
- self.assertEqual(self.transport.packets,
- [(connection.MSG_REQUEST_SUCCESS, '')])
- self.transport.packets = []
- self.conn.ssh_GLOBAL_REQUEST(common.NS('TestData') + '\xff' +
- 'test data')
- self.assertEqual(self.transport.packets,
- [(connection.MSG_REQUEST_SUCCESS, 'test data')])
- self.transport.packets = []
- self.conn.ssh_GLOBAL_REQUEST(common.NS('TestBad') + '\xff')
- self.assertEqual(self.transport.packets,
- [(connection.MSG_REQUEST_FAILURE, '')])
- self.transport.packets = []
- self.conn.ssh_GLOBAL_REQUEST(common.NS('TestGlobal') + '\x00')
- self.assertEqual(self.transport.packets, [])
-
- def test_REQUEST_SUCCESS(self):
- """
- Test that global request success packets cause the Deferred to be
- called back.
- """
- d = self.conn.sendGlobalRequest('request', 'data', True)
- self.conn.ssh_REQUEST_SUCCESS('data')
- def check(data):
- self.assertEqual(data, 'data')
- d.addCallback(check)
- d.addErrback(self.fail)
- return d
-
- def test_REQUEST_FAILURE(self):
- """
- Test that global request failure packets cause the Deferred to be
- erred back.
- """
- d = self.conn.sendGlobalRequest('request', 'data', True)
- self.conn.ssh_REQUEST_FAILURE('data')
- def check(f):
- self.assertEqual(f.value.data, 'data')
- d.addCallback(self.fail)
- d.addErrback(check)
- return d
-
- def test_CHANNEL_OPEN(self):
- """
- Test that open channel packets cause a channel to be created and
- opened or a failure message to be returned.
- """
- del self.transport.avatar
- self.conn.ssh_CHANNEL_OPEN(common.NS('TestChannel') +
- '\x00\x00\x00\x01' * 4)
- self.assertTrue(self.conn.channel.gotOpen)
- self.assertEqual(self.conn.channel.conn, self.conn)
- self.assertEqual(self.conn.channel.data, '\x00\x00\x00\x01')
- self.assertEqual(self.conn.channel.specificData, '\x00\x00\x00\x01')
- self.assertEqual(self.conn.channel.remoteWindowLeft, 1)
- self.assertEqual(self.conn.channel.remoteMaxPacket, 1)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_OPEN_CONFIRMATION,
- '\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00'
- '\x00\x00\x80\x00')])
- self.transport.packets = []
- self.conn.ssh_CHANNEL_OPEN(common.NS('BadChannel') +
- '\x00\x00\x00\x02' * 4)
- self.flushLoggedErrors()
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_OPEN_FAILURE,
- '\x00\x00\x00\x02\x00\x00\x00\x03' + common.NS(
- 'unknown channel') + common.NS(''))])
- self.transport.packets = []
- self.conn.ssh_CHANNEL_OPEN(common.NS('ErrorChannel') +
- '\x00\x00\x00\x02' * 4)
- self.flushLoggedErrors()
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_OPEN_FAILURE,
- '\x00\x00\x00\x02\x00\x00\x00\x02' + common.NS(
- 'unknown failure') + common.NS(''))])
-
-
- def _lookupChannelErrorTest(self, code):
- """
- Deliver a request for a channel open which will result in an exception
- being raised during channel lookup. Assert that an error response is
- delivered as a result.
- """
- self.transport.avatar._ARGS_ERROR_CODE = code
- self.conn.ssh_CHANNEL_OPEN(
- common.NS('conch-error-args') + '\x00\x00\x00\x01' * 4)
- errors = self.flushLoggedErrors(error.ConchError)
- self.assertEqual(
- len(errors), 1, "Expected one error, got: %r" % (errors,))
- self.assertEqual(errors[0].value.args, (123, "error args in wrong order"))
- self.assertEqual(
- self.transport.packets,
- [(connection.MSG_CHANNEL_OPEN_FAILURE,
- # The response includes some bytes which identifying the
- # associated request, as well as the error code (7b in hex) and
- # the error message.
- '\x00\x00\x00\x01\x00\x00\x00\x7b' + common.NS(
- 'error args in wrong order') + common.NS(''))])
-
-
- def test_lookupChannelError(self):
- """
- If a C{lookupChannel} implementation raises L{error.ConchError} with the
- arguments in the wrong order, a C{MSG_CHANNEL_OPEN} failure is still
- sent in response to the message.
-
- This is a temporary work-around until L{error.ConchError} is given
- better attributes and all of the Conch code starts constructing
- instances of it properly. Eventually this functionality should be
- deprecated and then removed.
- """
- self._lookupChannelErrorTest(123)
-
-
- def test_lookupChannelErrorLongCode(self):
- """
- Like L{test_lookupChannelError}, but for the case where the failure code
- is represented as a C{long} instead of a C{int}.
- """
- self._lookupChannelErrorTest(123L)
-
-
- def test_CHANNEL_OPEN_CONFIRMATION(self):
- """
- Test that channel open confirmation packets cause the channel to be
- notified that it's open.
- """
- channel = TestChannel()
- self.conn.openChannel(channel)
- self.conn.ssh_CHANNEL_OPEN_CONFIRMATION('\x00\x00\x00\x00'*5)
- self.assertEqual(channel.remoteWindowLeft, 0)
- self.assertEqual(channel.remoteMaxPacket, 0)
- self.assertEqual(channel.specificData, '\x00\x00\x00\x00')
- self.assertEqual(self.conn.channelsToRemoteChannel[channel],
- 0)
- self.assertEqual(self.conn.localToRemoteChannel[0], 0)
-
- def test_CHANNEL_OPEN_FAILURE(self):
- """
- Test that channel open failure packets cause the channel to be
- notified that its opening failed.
- """
- channel = TestChannel()
- self.conn.openChannel(channel)
- self.conn.ssh_CHANNEL_OPEN_FAILURE('\x00\x00\x00\x00\x00\x00\x00'
- '\x01' + common.NS('failure!'))
- self.assertEqual(channel.openFailureReason.args, ('failure!', 1))
- self.assertEqual(self.conn.channels.get(channel), None)
-
-
- def test_CHANNEL_WINDOW_ADJUST(self):
- """
- Test that channel window adjust messages add bytes to the channel
- window.
- """
- channel = TestChannel()
- self._openChannel(channel)
- oldWindowSize = channel.remoteWindowLeft
- self.conn.ssh_CHANNEL_WINDOW_ADJUST('\x00\x00\x00\x00\x00\x00\x00'
- '\x01')
- self.assertEqual(channel.remoteWindowLeft, oldWindowSize + 1)
-
- def test_CHANNEL_DATA(self):
- """
- Test that channel data messages are passed up to the channel, or
- cause the channel to be closed if the data is too large.
- """
- channel = TestChannel(localWindow=6, localMaxPacket=5)
- self._openChannel(channel)
- self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x00' + common.NS('data'))
- self.assertEqual(channel.inBuffer, ['data'])
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff'
- '\x00\x00\x00\x04')])
- self.transport.packets = []
- longData = 'a' * (channel.localWindowLeft + 1)
- self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x00' + common.NS(longData))
- self.assertEqual(channel.inBuffer, ['data'])
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
- channel = TestChannel()
- self._openChannel(channel)
- bigData = 'a' * (channel.localMaxPacket + 1)
- self.transport.packets = []
- self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x01' + common.NS(bigData))
- self.assertEqual(channel.inBuffer, [])
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
-
- def test_CHANNEL_EXTENDED_DATA(self):
- """
- Test that channel extended data messages are passed up to the channel,
- or cause the channel to be closed if they're too big.
- """
- channel = TestChannel(localWindow=6, localMaxPacket=5)
- self._openChannel(channel)
- self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x00\x00\x00\x00'
- '\x00' + common.NS('data'))
- self.assertEqual(channel.extBuffer, [(0, 'data')])
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff'
- '\x00\x00\x00\x04')])
- self.transport.packets = []
- longData = 'a' * (channel.localWindowLeft + 1)
- self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x00\x00\x00\x00'
- '\x00' + common.NS(longData))
- self.assertEqual(channel.extBuffer, [(0, 'data')])
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
- channel = TestChannel()
- self._openChannel(channel)
- bigData = 'a' * (channel.localMaxPacket + 1)
- self.transport.packets = []
- self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x01\x00\x00\x00'
- '\x00' + common.NS(bigData))
- self.assertEqual(channel.extBuffer, [])
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
-
- def test_CHANNEL_EOF(self):
- """
- Test that channel eof messages are passed up to the channel.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.ssh_CHANNEL_EOF('\x00\x00\x00\x00')
- self.assertTrue(channel.gotEOF)
-
- def test_CHANNEL_CLOSE(self):
- """
- Test that channel close messages are passed up to the channel. Also,
- test that channel.close() is called if both sides are closed when this
- message is received.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.sendClose(channel)
- self.conn.ssh_CHANNEL_CLOSE('\x00\x00\x00\x00')
- self.assertTrue(channel.gotOneClose)
- self.assertTrue(channel.gotClosed)
-
- def test_CHANNEL_REQUEST_success(self):
- """
- Test that channel requests that succeed send MSG_CHANNEL_SUCCESS.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS('test')
- + '\x00')
- self.assertEqual(channel.numberRequests, 1)
- d = self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS(
- 'test') + '\xff' + 'data')
- def check(result):
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_SUCCESS, '\x00\x00\x00\xff')])
- d.addCallback(check)
- return d
-
- def test_CHANNEL_REQUEST_failure(self):
- """
- Test that channel requests that fail send MSG_CHANNEL_FAILURE.
- """
- channel = TestChannel()
- self._openChannel(channel)
- d = self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS(
- 'test') + '\xff')
- def check(result):
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_FAILURE, '\x00\x00\x00\xff'
- )])
- d.addCallback(self.fail)
- d.addErrback(check)
- return d
-
- def test_CHANNEL_REQUEST_SUCCESS(self):
- """
- Test that channel request success messages cause the Deferred to be
- called back.
- """
- channel = TestChannel()
- self._openChannel(channel)
- d = self.conn.sendRequest(channel, 'test', 'data', True)
- self.conn.ssh_CHANNEL_SUCCESS('\x00\x00\x00\x00')
- def check(result):
- self.assertTrue(result)
- return d
-
- def test_CHANNEL_REQUEST_FAILURE(self):
- """
- Test that channel request failure messages cause the Deferred to be
- erred back.
- """
- channel = TestChannel()
- self._openChannel(channel)
- d = self.conn.sendRequest(channel, 'test', '', True)
- self.conn.ssh_CHANNEL_FAILURE('\x00\x00\x00\x00')
- def check(result):
- self.assertEqual(result.value.value, 'channel request failed')
- d.addCallback(self.fail)
- d.addErrback(check)
- return d
-
- def test_sendGlobalRequest(self):
- """
- Test that global request messages are sent in the right format.
- """
- d = self.conn.sendGlobalRequest('wantReply', 'data', True)
- # must be added to prevent errbacking during teardown
- d.addErrback(lambda failure: None)
- self.conn.sendGlobalRequest('noReply', '', False)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_GLOBAL_REQUEST, common.NS('wantReply') +
- '\xffdata'),
- (connection.MSG_GLOBAL_REQUEST, common.NS('noReply') +
- '\x00')])
- self.assertEqual(self.conn.deferreds, {'global':[d]})
-
- def test_openChannel(self):
- """
- Test that open channel messages are sent in the right format.
- """
- channel = TestChannel()
- self.conn.openChannel(channel, 'aaaa')
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_OPEN, common.NS('TestChannel') +
- '\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x80\x00aaaa')])
- self.assertEqual(channel.id, 0)
- self.assertEqual(self.conn.localChannelID, 1)
-
- def test_sendRequest(self):
- """
- Test that channel request messages are sent in the right format.
- """
- channel = TestChannel()
- self._openChannel(channel)
- d = self.conn.sendRequest(channel, 'test', 'test', True)
- # needed to prevent errbacks during teardown.
- d.addErrback(lambda failure: None)
- self.conn.sendRequest(channel, 'test2', '', False)
- channel.localClosed = True # emulate sending a close message
- self.conn.sendRequest(channel, 'test3', '', True)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_REQUEST, '\x00\x00\x00\xff' +
- common.NS('test') + '\x01test'),
- (connection.MSG_CHANNEL_REQUEST, '\x00\x00\x00\xff' +
- common.NS('test2') + '\x00')])
- self.assertEqual(self.conn.deferreds[0], [d])
-
- def test_adjustWindow(self):
- """
- Test that channel window adjust messages cause bytes to be added
- to the window.
- """
- channel = TestChannel(localWindow=5)
- self._openChannel(channel)
- channel.localWindowLeft = 0
- self.conn.adjustWindow(channel, 1)
- self.assertEqual(channel.localWindowLeft, 1)
- channel.localClosed = True
- self.conn.adjustWindow(channel, 2)
- self.assertEqual(channel.localWindowLeft, 1)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff'
- '\x00\x00\x00\x01')])
-
- def test_sendData(self):
- """
- Test that channel data messages are sent in the right format.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.sendData(channel, 'a')
- channel.localClosed = True
- self.conn.sendData(channel, 'b')
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_DATA, '\x00\x00\x00\xff' +
- common.NS('a'))])
-
- def test_sendExtendedData(self):
- """
- Test that channel extended data messages are sent in the right format.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.sendExtendedData(channel, 1, 'test')
- channel.localClosed = True
- self.conn.sendExtendedData(channel, 2, 'test2')
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_EXTENDED_DATA, '\x00\x00\x00\xff' +
- '\x00\x00\x00\x01' + common.NS('test'))])
-
- def test_sendEOF(self):
- """
- Test that channel EOF messages are sent in the right format.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.sendEOF(channel)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_EOF, '\x00\x00\x00\xff')])
- channel.localClosed = True
- self.conn.sendEOF(channel)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_EOF, '\x00\x00\x00\xff')])
-
- def test_sendClose(self):
- """
- Test that channel close messages are sent in the right format.
- """
- channel = TestChannel()
- self._openChannel(channel)
- self.conn.sendClose(channel)
- self.assertTrue(channel.localClosed)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
- self.conn.sendClose(channel)
- self.assertEqual(self.transport.packets,
- [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
-
- channel2 = TestChannel()
- self._openChannel(channel2)
- channel2.remoteClosed = True
- self.conn.sendClose(channel2)
- self.assertTrue(channel2.gotClosed)
-
- def test_getChannelWithAvatar(self):
- """
- Test that getChannel dispatches to the avatar when an avatar is
- present. Correct functioning without the avatar is verified in
- test_CHANNEL_OPEN.
- """
- channel = self.conn.getChannel('TestChannel', 50, 30, 'data')
- self.assertEqual(channel.data, 'data')
- self.assertEqual(channel.remoteWindowLeft, 50)
- self.assertEqual(channel.remoteMaxPacket, 30)
- self.assertRaises(error.ConchError, self.conn.getChannel,
- 'BadChannel', 50, 30, 'data')
-
- def test_gotGlobalRequestWithoutAvatar(self):
- """
- Test that gotGlobalRequests dispatches to global_* without an avatar.
- """
- del self.transport.avatar
- self.assertTrue(self.conn.gotGlobalRequest('TestGlobal', 'data'))
- self.assertEqual(self.conn.gotGlobalRequest('Test-Data', 'data'),
- (True, 'data'))
- self.assertFalse(self.conn.gotGlobalRequest('BadGlobal', 'data'))
-
-
- def test_channelClosedCausesLeftoverChannelDeferredsToErrback(self):
- """
- Whenever an SSH channel gets closed any Deferred that was returned by a
- sendRequest() on its parent connection must be errbacked.
- """
- channel = TestChannel()
- self._openChannel(channel)
-
- d = self.conn.sendRequest(
- channel, "dummyrequest", "dummydata", wantReply=1)
- d = self.assertFailure(d, error.ConchError)
- self.conn.channelClosed(channel)
- return d
-
-
-
-class TestCleanConnectionShutdown(unittest.TestCase):
- """
- Check whether correct cleanup is performed on connection shutdown.
- """
- if test_userauth.transport is None:
- skip = "Cannot run without both PyCrypto and pyasn1"
-
- def setUp(self):
- self.transport = test_userauth.FakeTransport(None)
- self.transport.avatar = TestAvatar()
- self.conn = TestConnection()
- self.conn.transport = self.transport
-
-
- def test_serviceStoppedCausesLeftoverGlobalDeferredsToErrback(self):
- """
- Once the service is stopped any leftover global deferred returned by
- a sendGlobalRequest() call must be errbacked.
- """
- self.conn.serviceStarted()
-
- d = self.conn.sendGlobalRequest(
- "dummyrequest", "dummydata", wantReply=1)
- d = self.assertFailure(d, error.ConchError)
- self.conn.serviceStopped()
- return d
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py
deleted file mode 100755
index 109f23d2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.client.default}.
-"""
-try:
- import Crypto.Cipher.DES3
- import pyasn1
-except ImportError:
- skip = "PyCrypto and PyASN1 required for twisted.conch.client.default."
-else:
- from twisted.conch.client.agent import SSHAgentClient
- from twisted.conch.client.default import SSHUserAuthClient
- from twisted.conch.client.options import ConchOptions
- from twisted.conch.ssh.keys import Key
-
-
-from twisted.trial.unittest import TestCase
-from twisted.python.filepath import FilePath
-from twisted.conch.test import keydata
-from twisted.test.proto_helpers import StringTransport
-
-
-
-class SSHUserAuthClientTest(TestCase):
- """
- Tests for L{SSHUserAuthClient}.
-
- @type rsaPublic: L{Key}
- @ivar rsaPublic: A public RSA key.
- """
-
- def setUp(self):
- self.rsaPublic = Key.fromString(keydata.publicRSA_openssh)
- self.tmpdir = FilePath(self.mktemp())
- self.tmpdir.makedirs()
- self.rsaFile = self.tmpdir.child('id_rsa')
- self.rsaFile.setContent(keydata.privateRSA_openssh)
- self.tmpdir.child('id_rsa.pub').setContent(keydata.publicRSA_openssh)
-
-
- def test_signDataWithAgent(self):
- """
- When connected to an agent, L{SSHUserAuthClient} can use it to
- request signatures of particular data with a particular L{Key}.
- """
- client = SSHUserAuthClient("user", ConchOptions(), None)
- agent = SSHAgentClient()
- transport = StringTransport()
- agent.makeConnection(transport)
- client.keyAgent = agent
- cleartext = "Sign here"
- client.signData(self.rsaPublic, cleartext)
- self.assertEqual(
- transport.value(),
- "\x00\x00\x00\x8b\r\x00\x00\x00u" + self.rsaPublic.blob() +
- "\x00\x00\x00\t" + cleartext +
- "\x00\x00\x00\x00")
-
-
- def test_agentGetPublicKey(self):
- """
- L{SSHUserAuthClient} looks up public keys from the agent using the
- L{SSHAgentClient} class. That L{SSHAgentClient.getPublicKey} returns a
- L{Key} object with one of the public keys in the agent. If no more
- keys are present, it returns C{None}.
- """
- agent = SSHAgentClient()
- agent.blobs = [self.rsaPublic.blob()]
- key = agent.getPublicKey()
- self.assertEqual(key.isPublic(), True)
- self.assertEqual(key, self.rsaPublic)
- self.assertEqual(agent.getPublicKey(), None)
-
-
- def test_getPublicKeyFromFile(self):
- """
- L{SSHUserAuthClient.getPublicKey()} is able to get a public key from
- the first file described by its options' C{identitys} list, and return
- the corresponding public L{Key} object.
- """
- options = ConchOptions()
- options.identitys = [self.rsaFile.path]
- client = SSHUserAuthClient("user", options, None)
- key = client.getPublicKey()
- self.assertEqual(key.isPublic(), True)
- self.assertEqual(key, self.rsaPublic)
-
-
- def test_getPublicKeyAgentFallback(self):
- """
- If an agent is present, but doesn't return a key,
- L{SSHUserAuthClient.getPublicKey} continue with the normal key lookup.
- """
- options = ConchOptions()
- options.identitys = [self.rsaFile.path]
- agent = SSHAgentClient()
- client = SSHUserAuthClient("user", options, None)
- client.keyAgent = agent
- key = client.getPublicKey()
- self.assertEqual(key.isPublic(), True)
- self.assertEqual(key, self.rsaPublic)
-
-
- def test_getPublicKeyBadKeyError(self):
- """
- If L{keys.Key.fromFile} raises a L{keys.BadKeyError}, the
- L{SSHUserAuthClient.getPublicKey} tries again to get a public key by
- calling itself recursively.
- """
- options = ConchOptions()
- self.tmpdir.child('id_dsa.pub').setContent(keydata.publicDSA_openssh)
- dsaFile = self.tmpdir.child('id_dsa')
- dsaFile.setContent(keydata.privateDSA_openssh)
- options.identitys = [self.rsaFile.path, dsaFile.path]
- self.tmpdir.child('id_rsa.pub').setContent('not a key!')
- client = SSHUserAuthClient("user", options, None)
- key = client.getPublicKey()
- self.assertEqual(key.isPublic(), True)
- self.assertEqual(key, Key.fromString(keydata.publicDSA_openssh))
- self.assertEqual(client.usedFiles, [self.rsaFile.path, dsaFile.path])
-
-
- def test_getPrivateKey(self):
- """
- L{SSHUserAuthClient.getPrivateKey} will load a private key from the
- last used file populated by L{SSHUserAuthClient.getPublicKey}, and
- return a L{Deferred} which fires with the corresponding private L{Key}.
- """
- rsaPrivate = Key.fromString(keydata.privateRSA_openssh)
- options = ConchOptions()
- options.identitys = [self.rsaFile.path]
- client = SSHUserAuthClient("user", options, None)
- # Populate the list of used files
- client.getPublicKey()
-
- def _cbGetPrivateKey(key):
- self.assertEqual(key.isPublic(), False)
- self.assertEqual(key, rsaPrivate)
-
- return client.getPrivateKey().addCallback(_cbGetPrivateKey)
-
-
- def test_getPrivateKeyPassphrase(self):
- """
- L{SSHUserAuthClient} can get a private key from a file, and return a
- Deferred called back with a private L{Key} object, even if the key is
- encrypted.
- """
- rsaPrivate = Key.fromString(keydata.privateRSA_openssh)
- passphrase = 'this is the passphrase'
- self.rsaFile.setContent(rsaPrivate.toString('openssh', passphrase))
- options = ConchOptions()
- options.identitys = [self.rsaFile.path]
- client = SSHUserAuthClient("user", options, None)
- # Populate the list of used files
- client.getPublicKey()
-
- def _getPassword(prompt):
- self.assertEqual(prompt,
- "Enter passphrase for key '%s': " % (
- self.rsaFile.path,))
- return passphrase
-
- def _cbGetPrivateKey(key):
- self.assertEqual(key.isPublic(), False)
- self.assertEqual(key, rsaPrivate)
-
- self.patch(client, '_getPassword', _getPassword)
- return client.getPrivateKey().addCallback(_cbGetPrivateKey)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py
deleted file mode 100755
index 38493317..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py
+++ /dev/null
@@ -1,765 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_filetransfer -*-
-# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
-# See LICENSE file for details.
-
-
-import os
-import re
-import struct
-import sys
-
-from twisted.trial import unittest
-try:
- from twisted.conch import unix
- unix # shut up pyflakes
-except ImportError:
- unix = None
- try:
- del sys.modules['twisted.conch.unix'] # remove the bad import
- except KeyError:
- # In Python 2.4, the bad import has already been cleaned up for us.
- # Hooray.
- pass
-
-from twisted.conch import avatar
-from twisted.conch.ssh import common, connection, filetransfer, session
-from twisted.internet import defer
-from twisted.protocols import loopback
-from twisted.python import components
-
-
-class TestAvatar(avatar.ConchUser):
- def __init__(self):
- avatar.ConchUser.__init__(self)
- self.channelLookup['session'] = session.SSHSession
- self.subsystemLookup['sftp'] = filetransfer.FileTransferServer
-
- def _runAsUser(self, f, *args, **kw):
- try:
- f = iter(f)
- except TypeError:
- f = [(f, args, kw)]
- for i in f:
- func = i[0]
- args = len(i)>1 and i[1] or ()
- kw = len(i)>2 and i[2] or {}
- r = func(*args, **kw)
- return r
-
-
-class FileTransferTestAvatar(TestAvatar):
-
- def __init__(self, homeDir):
- TestAvatar.__init__(self)
- self.homeDir = homeDir
-
- def getHomeDir(self):
- return os.path.join(os.getcwd(), self.homeDir)
-
-
-class ConchSessionForTestAvatar:
-
- def __init__(self, avatar):
- self.avatar = avatar
-
-if unix:
- if not hasattr(unix, 'SFTPServerForUnixConchUser'):
- # unix should either be a fully working module, or None. I'm not sure
- # how this happens, but on win32 it does. Try to cope. --spiv.
- import warnings
- warnings.warn(("twisted.conch.unix imported %r, "
- "but doesn't define SFTPServerForUnixConchUser'")
- % (unix,))
- unix = None
- else:
- class FileTransferForTestAvatar(unix.SFTPServerForUnixConchUser):
-
- def gotVersion(self, version, otherExt):
- return {'conchTest' : 'ext data'}
-
- def extendedRequest(self, extName, extData):
- if extName == 'testExtendedRequest':
- return 'bar'
- raise NotImplementedError
-
- components.registerAdapter(FileTransferForTestAvatar,
- TestAvatar,
- filetransfer.ISFTPServer)
-
-class SFTPTestBase(unittest.TestCase):
-
- def setUp(self):
- self.testDir = self.mktemp()
- # Give the testDir another level so we can safely "cd .." from it in
- # tests.
- self.testDir = os.path.join(self.testDir, 'extra')
- os.makedirs(os.path.join(self.testDir, 'testDirectory'))
-
- f = file(os.path.join(self.testDir, 'testfile1'),'w')
- f.write('a'*10+'b'*10)
- f.write(file('/dev/urandom').read(1024*64)) # random data
- os.chmod(os.path.join(self.testDir, 'testfile1'), 0644)
- file(os.path.join(self.testDir, 'testRemoveFile'), 'w').write('a')
- file(os.path.join(self.testDir, 'testRenameFile'), 'w').write('a')
- file(os.path.join(self.testDir, '.testHiddenFile'), 'w').write('a')
-
-
-class TestOurServerOurClient(SFTPTestBase):
-
- if not unix:
- skip = "can't run on non-posix computers"
-
- def setUp(self):
- SFTPTestBase.setUp(self)
-
- self.avatar = FileTransferTestAvatar(self.testDir)
- self.server = filetransfer.FileTransferServer(avatar=self.avatar)
- clientTransport = loopback.LoopbackRelay(self.server)
-
- self.client = filetransfer.FileTransferClient()
- self._serverVersion = None
- self._extData = None
- def _(serverVersion, extData):
- self._serverVersion = serverVersion
- self._extData = extData
- self.client.gotServerVersion = _
- serverTransport = loopback.LoopbackRelay(self.client)
- self.client.makeConnection(clientTransport)
- self.server.makeConnection(serverTransport)
-
- self.clientTransport = clientTransport
- self.serverTransport = serverTransport
-
- self._emptyBuffers()
-
-
- def _emptyBuffers(self):
- while self.serverTransport.buffer or self.clientTransport.buffer:
- self.serverTransport.clearBuffer()
- self.clientTransport.clearBuffer()
-
-
- def tearDown(self):
- self.serverTransport.loseConnection()
- self.clientTransport.loseConnection()
- self.serverTransport.clearBuffer()
- self.clientTransport.clearBuffer()
-
-
- def testServerVersion(self):
- self.assertEqual(self._serverVersion, 3)
- self.assertEqual(self._extData, {'conchTest' : 'ext data'})
-
-
- def test_openedFileClosedWithConnection(self):
- """
- A file opened with C{openFile} is close when the connection is lost.
- """
- d = self.client.openFile("testfile1", filetransfer.FXF_READ |
- filetransfer.FXF_WRITE, {})
- self._emptyBuffers()
-
- oldClose = os.close
- closed = []
- def close(fd):
- closed.append(fd)
- oldClose(fd)
-
- self.patch(os, "close", close)
-
- def _fileOpened(openFile):
- fd = self.server.openFiles[openFile.handle[4:]].fd
- self.serverTransport.loseConnection()
- self.clientTransport.loseConnection()
- self.serverTransport.clearBuffer()
- self.clientTransport.clearBuffer()
- self.assertEqual(self.server.openFiles, {})
- self.assertIn(fd, closed)
-
- d.addCallback(_fileOpened)
- return d
-
-
- def test_openedDirectoryClosedWithConnection(self):
- """
- A directory opened with C{openDirectory} is close when the connection
- is lost.
- """
- d = self.client.openDirectory('')
- self._emptyBuffers()
-
- def _getFiles(openDir):
- self.serverTransport.loseConnection()
- self.clientTransport.loseConnection()
- self.serverTransport.clearBuffer()
- self.clientTransport.clearBuffer()
- self.assertEqual(self.server.openDirs, {})
-
- d.addCallback(_getFiles)
- return d
-
-
- def testOpenFileIO(self):
- d = self.client.openFile("testfile1", filetransfer.FXF_READ |
- filetransfer.FXF_WRITE, {})
- self._emptyBuffers()
-
- def _fileOpened(openFile):
- self.assertEqual(openFile, filetransfer.ISFTPFile(openFile))
- d = _readChunk(openFile)
- d.addCallback(_writeChunk, openFile)
- return d
-
- def _readChunk(openFile):
- d = openFile.readChunk(0, 20)
- self._emptyBuffers()
- d.addCallback(self.assertEqual, 'a'*10 + 'b'*10)
- return d
-
- def _writeChunk(_, openFile):
- d = openFile.writeChunk(20, 'c'*10)
- self._emptyBuffers()
- d.addCallback(_readChunk2, openFile)
- return d
-
- def _readChunk2(_, openFile):
- d = openFile.readChunk(0, 30)
- self._emptyBuffers()
- d.addCallback(self.assertEqual, 'a'*10 + 'b'*10 + 'c'*10)
- return d
-
- d.addCallback(_fileOpened)
- return d
-
- def testClosedFileGetAttrs(self):
- d = self.client.openFile("testfile1", filetransfer.FXF_READ |
- filetransfer.FXF_WRITE, {})
- self._emptyBuffers()
-
- def _getAttrs(_, openFile):
- d = openFile.getAttrs()
- self._emptyBuffers()
- return d
-
- def _err(f):
- self.flushLoggedErrors()
- return f
-
- def _close(openFile):
- d = openFile.close()
- self._emptyBuffers()
- d.addCallback(_getAttrs, openFile)
- d.addErrback(_err)
- return self.assertFailure(d, filetransfer.SFTPError)
-
- d.addCallback(_close)
- return d
-
- def testOpenFileAttributes(self):
- d = self.client.openFile("testfile1", filetransfer.FXF_READ |
- filetransfer.FXF_WRITE, {})
- self._emptyBuffers()
-
- def _getAttrs(openFile):
- d = openFile.getAttrs()
- self._emptyBuffers()
- d.addCallback(_getAttrs2)
- return d
-
- def _getAttrs2(attrs1):
- d = self.client.getAttrs('testfile1')
- self._emptyBuffers()
- d.addCallback(self.assertEqual, attrs1)
- return d
-
- return d.addCallback(_getAttrs)
-
-
- def testOpenFileSetAttrs(self):
- # XXX test setAttrs
- # Ok, how about this for a start? It caught a bug :) -- spiv.
- d = self.client.openFile("testfile1", filetransfer.FXF_READ |
- filetransfer.FXF_WRITE, {})
- self._emptyBuffers()
-
- def _getAttrs(openFile):
- d = openFile.getAttrs()
- self._emptyBuffers()
- d.addCallback(_setAttrs)
- return d
-
- def _setAttrs(attrs):
- attrs['atime'] = 0
- d = self.client.setAttrs('testfile1', attrs)
- self._emptyBuffers()
- d.addCallback(_getAttrs2)
- d.addCallback(self.assertEqual, attrs)
- return d
-
- def _getAttrs2(_):
- d = self.client.getAttrs('testfile1')
- self._emptyBuffers()
- return d
-
- d.addCallback(_getAttrs)
- return d
-
-
- def test_openFileExtendedAttributes(self):
- """
- Check that L{filetransfer.FileTransferClient.openFile} can send
- extended attributes, that should be extracted server side. By default,
- they are ignored, so we just verify they are correctly parsed.
- """
- savedAttributes = {}
- oldOpenFile = self.server.client.openFile
- def openFile(filename, flags, attrs):
- savedAttributes.update(attrs)
- return oldOpenFile(filename, flags, attrs)
- self.server.client.openFile = openFile
-
- d = self.client.openFile("testfile1", filetransfer.FXF_READ |
- filetransfer.FXF_WRITE, {"ext_foo": "bar"})
- self._emptyBuffers()
-
- def check(ign):
- self.assertEqual(savedAttributes, {"ext_foo": "bar"})
-
- return d.addCallback(check)
-
-
- def testRemoveFile(self):
- d = self.client.getAttrs("testRemoveFile")
- self._emptyBuffers()
- def _removeFile(ignored):
- d = self.client.removeFile("testRemoveFile")
- self._emptyBuffers()
- return d
- d.addCallback(_removeFile)
- d.addCallback(_removeFile)
- return self.assertFailure(d, filetransfer.SFTPError)
-
- def testRenameFile(self):
- d = self.client.getAttrs("testRenameFile")
- self._emptyBuffers()
- def _rename(attrs):
- d = self.client.renameFile("testRenameFile", "testRenamedFile")
- self._emptyBuffers()
- d.addCallback(_testRenamed, attrs)
- return d
- def _testRenamed(_, attrs):
- d = self.client.getAttrs("testRenamedFile")
- self._emptyBuffers()
- d.addCallback(self.assertEqual, attrs)
- return d.addCallback(_rename)
-
- def testDirectoryBad(self):
- d = self.client.getAttrs("testMakeDirectory")
- self._emptyBuffers()
- return self.assertFailure(d, filetransfer.SFTPError)
-
- def testDirectoryCreation(self):
- d = self.client.makeDirectory("testMakeDirectory", {})
- self._emptyBuffers()
-
- def _getAttrs(_):
- d = self.client.getAttrs("testMakeDirectory")
- self._emptyBuffers()
- return d
-
- # XXX not until version 4/5
- # self.assertEqual(filetransfer.FILEXFER_TYPE_DIRECTORY&attrs['type'],
- # filetransfer.FILEXFER_TYPE_DIRECTORY)
-
- def _removeDirectory(_):
- d = self.client.removeDirectory("testMakeDirectory")
- self._emptyBuffers()
- return d
-
- d.addCallback(_getAttrs)
- d.addCallback(_removeDirectory)
- d.addCallback(_getAttrs)
- return self.assertFailure(d, filetransfer.SFTPError)
-
- def testOpenDirectory(self):
- d = self.client.openDirectory('')
- self._emptyBuffers()
- files = []
-
- def _getFiles(openDir):
- def append(f):
- files.append(f)
- return openDir
- d = defer.maybeDeferred(openDir.next)
- self._emptyBuffers()
- d.addCallback(append)
- d.addCallback(_getFiles)
- d.addErrback(_close, openDir)
- return d
-
- def _checkFiles(ignored):
- fs = list(zip(*files)[0])
- fs.sort()
- self.assertEqual(fs,
- ['.testHiddenFile', 'testDirectory',
- 'testRemoveFile', 'testRenameFile',
- 'testfile1'])
-
- def _close(_, openDir):
- d = openDir.close()
- self._emptyBuffers()
- return d
-
- d.addCallback(_getFiles)
- d.addCallback(_checkFiles)
- return d
-
- def testLinkDoesntExist(self):
- d = self.client.getAttrs('testLink')
- self._emptyBuffers()
- return self.assertFailure(d, filetransfer.SFTPError)
-
- def testLinkSharesAttrs(self):
- d = self.client.makeLink('testLink', 'testfile1')
- self._emptyBuffers()
- def _getFirstAttrs(_):
- d = self.client.getAttrs('testLink', 1)
- self._emptyBuffers()
- return d
- def _getSecondAttrs(firstAttrs):
- d = self.client.getAttrs('testfile1')
- self._emptyBuffers()
- d.addCallback(self.assertEqual, firstAttrs)
- return d
- d.addCallback(_getFirstAttrs)
- return d.addCallback(_getSecondAttrs)
-
- def testLinkPath(self):
- d = self.client.makeLink('testLink', 'testfile1')
- self._emptyBuffers()
- def _readLink(_):
- d = self.client.readLink('testLink')
- self._emptyBuffers()
- d.addCallback(self.assertEqual,
- os.path.join(os.getcwd(), self.testDir, 'testfile1'))
- return d
- def _realPath(_):
- d = self.client.realPath('testLink')
- self._emptyBuffers()
- d.addCallback(self.assertEqual,
- os.path.join(os.getcwd(), self.testDir, 'testfile1'))
- return d
- d.addCallback(_readLink)
- d.addCallback(_realPath)
- return d
-
- def testExtendedRequest(self):
- d = self.client.extendedRequest('testExtendedRequest', 'foo')
- self._emptyBuffers()
- d.addCallback(self.assertEqual, 'bar')
- d.addCallback(self._cbTestExtendedRequest)
- return d
-
- def _cbTestExtendedRequest(self, ignored):
- d = self.client.extendedRequest('testBadRequest', '')
- self._emptyBuffers()
- return self.assertFailure(d, NotImplementedError)
-
-
-class FakeConn:
- def sendClose(self, channel):
- pass
-
-
-class TestFileTransferClose(unittest.TestCase):
-
- if not unix:
- skip = "can't run on non-posix computers"
-
- def setUp(self):
- self.avatar = TestAvatar()
-
- def buildServerConnection(self):
- # make a server connection
- conn = connection.SSHConnection()
- # server connections have a 'self.transport.avatar'.
- class DummyTransport:
- def __init__(self):
- self.transport = self
- def sendPacket(self, kind, data):
- pass
- def logPrefix(self):
- return 'dummy transport'
- conn.transport = DummyTransport()
- conn.transport.avatar = self.avatar
- return conn
-
- def interceptConnectionLost(self, sftpServer):
- self.connectionLostFired = False
- origConnectionLost = sftpServer.connectionLost
- def connectionLost(reason):
- self.connectionLostFired = True
- origConnectionLost(reason)
- sftpServer.connectionLost = connectionLost
-
- def assertSFTPConnectionLost(self):
- self.assertTrue(self.connectionLostFired,
- "sftpServer's connectionLost was not called")
-
- def test_sessionClose(self):
- """
- Closing a session should notify an SFTP subsystem launched by that
- session.
- """
- # make a session
- testSession = session.SSHSession(conn=FakeConn(), avatar=self.avatar)
-
- # start an SFTP subsystem on the session
- testSession.request_subsystem(common.NS('sftp'))
- sftpServer = testSession.client.transport.proto
-
- # intercept connectionLost so we can check that it's called
- self.interceptConnectionLost(sftpServer)
-
- # close session
- testSession.closeReceived()
-
- self.assertSFTPConnectionLost()
-
- def test_clientClosesChannelOnConnnection(self):
- """
- A client sending CHANNEL_CLOSE should trigger closeReceived on the
- associated channel instance.
- """
- conn = self.buildServerConnection()
-
- # somehow get a session
- packet = common.NS('session') + struct.pack('>L', 0) * 3
- conn.ssh_CHANNEL_OPEN(packet)
- sessionChannel = conn.channels[0]
-
- sessionChannel.request_subsystem(common.NS('sftp'))
- sftpServer = sessionChannel.client.transport.proto
- self.interceptConnectionLost(sftpServer)
-
- # intercept closeReceived
- self.interceptConnectionLost(sftpServer)
-
- # close the connection
- conn.ssh_CHANNEL_CLOSE(struct.pack('>L', 0))
-
- self.assertSFTPConnectionLost()
-
-
- def test_stopConnectionServiceClosesChannel(self):
- """
- Closing an SSH connection should close all sessions within it.
- """
- conn = self.buildServerConnection()
-
- # somehow get a session
- packet = common.NS('session') + struct.pack('>L', 0) * 3
- conn.ssh_CHANNEL_OPEN(packet)
- sessionChannel = conn.channels[0]
-
- sessionChannel.request_subsystem(common.NS('sftp'))
- sftpServer = sessionChannel.client.transport.proto
- self.interceptConnectionLost(sftpServer)
-
- # close the connection
- conn.serviceStopped()
-
- self.assertSFTPConnectionLost()
-
-
-
-class TestConstants(unittest.TestCase):
- """
- Tests for the constants used by the SFTP protocol implementation.
-
- @ivar filexferSpecExcerpts: Excerpts from the
- draft-ietf-secsh-filexfer-02.txt (draft) specification of the SFTP
- protocol. There are more recent drafts of the specification, but this
- one describes version 3, which is what conch (and OpenSSH) implements.
- """
-
-
- filexferSpecExcerpts = [
- """
- The following values are defined for packet types.
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
- """,
- """
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_UIDGID 0x00000002
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
- """,
- """
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- """,
- """
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- """]
-
-
- def test_constantsAgainstSpec(self):
- """
- The constants used by the SFTP protocol implementation match those
- found by searching through the spec.
- """
- constants = {}
- for excerpt in self.filexferSpecExcerpts:
- for line in excerpt.splitlines():
- m = re.match('^\s*#define SSH_([A-Z_]+)\s+([0-9x]*)\s*$', line)
- if m:
- constants[m.group(1)] = long(m.group(2), 0)
- self.assertTrue(
- len(constants) > 0, "No constants found (the test must be buggy).")
- for k, v in constants.items():
- self.assertEqual(v, getattr(filetransfer, k))
-
-
-
-class TestRawPacketData(unittest.TestCase):
- """
- Tests for L{filetransfer.FileTransferClient} which explicitly craft certain
- less common protocol messages to exercise their handling.
- """
- def setUp(self):
- self.ftc = filetransfer.FileTransferClient()
-
-
- def test_packetSTATUS(self):
- """
- A STATUS packet containing a result code, a message, and a language is
- parsed to produce the result of an outstanding request L{Deferred}.
-
- @see: U{section 9.1<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>}
- of the SFTP Internet-Draft.
- """
- d = defer.Deferred()
- d.addCallback(self._cbTestPacketSTATUS)
- self.ftc.openRequests[1] = d
- data = struct.pack('!LL', 1, filetransfer.FX_OK) + common.NS('msg') + common.NS('lang')
- self.ftc.packet_STATUS(data)
- return d
-
-
- def _cbTestPacketSTATUS(self, result):
- """
- Assert that the result is a two-tuple containing the message and
- language from the STATUS packet.
- """
- self.assertEqual(result[0], 'msg')
- self.assertEqual(result[1], 'lang')
-
-
- def test_packetSTATUSShort(self):
- """
- A STATUS packet containing only a result code can also be parsed to
- produce the result of an outstanding request L{Deferred}. Such packets
- are sent by some SFTP implementations, though not strictly legal.
-
- @see: U{section 9.1<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>}
- of the SFTP Internet-Draft.
- """
- d = defer.Deferred()
- d.addCallback(self._cbTestPacketSTATUSShort)
- self.ftc.openRequests[1] = d
- data = struct.pack('!LL', 1, filetransfer.FX_OK)
- self.ftc.packet_STATUS(data)
- return d
-
-
- def _cbTestPacketSTATUSShort(self, result):
- """
- Assert that the result is a two-tuple containing empty strings, since
- the STATUS packet had neither a message nor a language.
- """
- self.assertEqual(result[0], '')
- self.assertEqual(result[1], '')
-
-
- def test_packetSTATUSWithoutLang(self):
- """
- A STATUS packet containing a result code and a message but no language
- can also be parsed to produce the result of an outstanding request
- L{Deferred}. Such packets are sent by some SFTP implementations, though
- not strictly legal.
-
- @see: U{section 9.1<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>}
- of the SFTP Internet-Draft.
- """
- d = defer.Deferred()
- d.addCallback(self._cbTestPacketSTATUSWithoutLang)
- self.ftc.openRequests[1] = d
- data = struct.pack('!LL', 1, filetransfer.FX_OK) + common.NS('msg')
- self.ftc.packet_STATUS(data)
- return d
-
-
- def _cbTestPacketSTATUSWithoutLang(self, result):
- """
- Assert that the result is a two-tuple containing the message from the
- STATUS packet and an empty string, since the language was missing.
- """
- self.assertEqual(result[0], 'msg')
- self.assertEqual(result[1], '')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py
deleted file mode 100755
index 7064d03b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py
+++ /dev/null
@@ -1,560 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_helper -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.conch.insults import helper
-from twisted.conch.insults.insults import G0, G1, G2, G3
-from twisted.conch.insults.insults import modes, privateModes
-from twisted.conch.insults.insults import NORMAL, BOLD, UNDERLINE, BLINK, REVERSE_VIDEO
-
-from twisted.trial import unittest
-
-WIDTH = 80
-HEIGHT = 24
-
-class BufferTestCase(unittest.TestCase):
- def setUp(self):
- self.term = helper.TerminalBuffer()
- self.term.connectionMade()
-
- def testInitialState(self):
- self.assertEqual(self.term.width, WIDTH)
- self.assertEqual(self.term.height, HEIGHT)
- self.assertEqual(str(self.term),
- '\n' * (HEIGHT - 1))
- self.assertEqual(self.term.reportCursorPosition(), (0, 0))
-
-
- def test_initialPrivateModes(self):
- """
- Verify that only DEC Auto Wrap Mode (DECAWM) and DEC Text Cursor Enable
- Mode (DECTCEM) are initially in the Set Mode (SM) state.
- """
- self.assertEqual(
- {privateModes.AUTO_WRAP: True,
- privateModes.CURSOR_MODE: True},
- self.term.privateModes)
-
-
- def test_carriageReturn(self):
- """
- C{"\r"} moves the cursor to the first column in the current row.
- """
- self.term.cursorForward(5)
- self.term.cursorDown(3)
- self.assertEqual(self.term.reportCursorPosition(), (5, 3))
- self.term.insertAtCursor("\r")
- self.assertEqual(self.term.reportCursorPosition(), (0, 3))
-
-
- def test_linefeed(self):
- """
- C{"\n"} moves the cursor to the next row without changing the column.
- """
- self.term.cursorForward(5)
- self.assertEqual(self.term.reportCursorPosition(), (5, 0))
- self.term.insertAtCursor("\n")
- self.assertEqual(self.term.reportCursorPosition(), (5, 1))
-
-
- def test_newline(self):
- """
- C{write} transforms C{"\n"} into C{"\r\n"}.
- """
- self.term.cursorForward(5)
- self.term.cursorDown(3)
- self.assertEqual(self.term.reportCursorPosition(), (5, 3))
- self.term.write("\n")
- self.assertEqual(self.term.reportCursorPosition(), (0, 4))
-
-
- def test_setPrivateModes(self):
- """
- Verify that L{helper.TerminalBuffer.setPrivateModes} changes the Set
- Mode (SM) state to "set" for the private modes it is passed.
- """
- expected = self.term.privateModes.copy()
- self.term.setPrivateModes([privateModes.SCROLL, privateModes.SCREEN])
- expected[privateModes.SCROLL] = True
- expected[privateModes.SCREEN] = True
- self.assertEqual(expected, self.term.privateModes)
-
-
- def test_resetPrivateModes(self):
- """
- Verify that L{helper.TerminalBuffer.resetPrivateModes} changes the Set
- Mode (SM) state to "reset" for the private modes it is passed.
- """
- expected = self.term.privateModes.copy()
- self.term.resetPrivateModes([privateModes.AUTO_WRAP, privateModes.CURSOR_MODE])
- del expected[privateModes.AUTO_WRAP]
- del expected[privateModes.CURSOR_MODE]
- self.assertEqual(expected, self.term.privateModes)
-
-
- def testCursorDown(self):
- self.term.cursorDown(3)
- self.assertEqual(self.term.reportCursorPosition(), (0, 3))
- self.term.cursorDown()
- self.assertEqual(self.term.reportCursorPosition(), (0, 4))
- self.term.cursorDown(HEIGHT)
- self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1))
-
- def testCursorUp(self):
- self.term.cursorUp(5)
- self.assertEqual(self.term.reportCursorPosition(), (0, 0))
-
- self.term.cursorDown(20)
- self.term.cursorUp(1)
- self.assertEqual(self.term.reportCursorPosition(), (0, 19))
-
- self.term.cursorUp(19)
- self.assertEqual(self.term.reportCursorPosition(), (0, 0))
-
- def testCursorForward(self):
- self.term.cursorForward(2)
- self.assertEqual(self.term.reportCursorPosition(), (2, 0))
- self.term.cursorForward(2)
- self.assertEqual(self.term.reportCursorPosition(), (4, 0))
- self.term.cursorForward(WIDTH)
- self.assertEqual(self.term.reportCursorPosition(), (WIDTH, 0))
-
- def testCursorBackward(self):
- self.term.cursorForward(10)
- self.term.cursorBackward(2)
- self.assertEqual(self.term.reportCursorPosition(), (8, 0))
- self.term.cursorBackward(7)
- self.assertEqual(self.term.reportCursorPosition(), (1, 0))
- self.term.cursorBackward(1)
- self.assertEqual(self.term.reportCursorPosition(), (0, 0))
- self.term.cursorBackward(1)
- self.assertEqual(self.term.reportCursorPosition(), (0, 0))
-
- def testCursorPositioning(self):
- self.term.cursorPosition(3, 9)
- self.assertEqual(self.term.reportCursorPosition(), (3, 9))
-
- def testSimpleWriting(self):
- s = "Hello, world."
- self.term.write(s)
- self.assertEqual(
- str(self.term),
- s + '\n' +
- '\n' * (HEIGHT - 2))
-
- def testOvertype(self):
- s = "hello, world."
- self.term.write(s)
- self.term.cursorBackward(len(s))
- self.term.resetModes([modes.IRM])
- self.term.write("H")
- self.assertEqual(
- str(self.term),
- ("H" + s[1:]) + '\n' +
- '\n' * (HEIGHT - 2))
-
- def testInsert(self):
- s = "ello, world."
- self.term.write(s)
- self.term.cursorBackward(len(s))
- self.term.setModes([modes.IRM])
- self.term.write("H")
- self.assertEqual(
- str(self.term),
- ("H" + s) + '\n' +
- '\n' * (HEIGHT - 2))
-
- def testWritingInTheMiddle(self):
- s = "Hello, world."
- self.term.cursorDown(5)
- self.term.cursorForward(5)
- self.term.write(s)
- self.assertEqual(
- str(self.term),
- '\n' * 5 +
- (self.term.fill * 5) + s + '\n' +
- '\n' * (HEIGHT - 7))
-
- def testWritingWrappedAtEndOfLine(self):
- s = "Hello, world."
- self.term.cursorForward(WIDTH - 5)
- self.term.write(s)
- self.assertEqual(
- str(self.term),
- s[:5].rjust(WIDTH) + '\n' +
- s[5:] + '\n' +
- '\n' * (HEIGHT - 3))
-
- def testIndex(self):
- self.term.index()
- self.assertEqual(self.term.reportCursorPosition(), (0, 1))
- self.term.cursorDown(HEIGHT)
- self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1))
- self.term.index()
- self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1))
-
- def testReverseIndex(self):
- self.term.reverseIndex()
- self.assertEqual(self.term.reportCursorPosition(), (0, 0))
- self.term.cursorDown(2)
- self.assertEqual(self.term.reportCursorPosition(), (0, 2))
- self.term.reverseIndex()
- self.assertEqual(self.term.reportCursorPosition(), (0, 1))
-
- def test_nextLine(self):
- """
- C{nextLine} positions the cursor at the beginning of the row below the
- current row.
- """
- self.term.nextLine()
- self.assertEqual(self.term.reportCursorPosition(), (0, 1))
- self.term.cursorForward(5)
- self.assertEqual(self.term.reportCursorPosition(), (5, 1))
- self.term.nextLine()
- self.assertEqual(self.term.reportCursorPosition(), (0, 2))
-
- def testSaveCursor(self):
- self.term.cursorDown(5)
- self.term.cursorForward(7)
- self.assertEqual(self.term.reportCursorPosition(), (7, 5))
- self.term.saveCursor()
- self.term.cursorDown(7)
- self.term.cursorBackward(3)
- self.assertEqual(self.term.reportCursorPosition(), (4, 12))
- self.term.restoreCursor()
- self.assertEqual(self.term.reportCursorPosition(), (7, 5))
-
- def testSingleShifts(self):
- self.term.singleShift2()
- self.term.write('Hi')
-
- ch = self.term.getCharacter(0, 0)
- self.assertEqual(ch[0], 'H')
- self.assertEqual(ch[1].charset, G2)
-
- ch = self.term.getCharacter(1, 0)
- self.assertEqual(ch[0], 'i')
- self.assertEqual(ch[1].charset, G0)
-
- self.term.singleShift3()
- self.term.write('!!')
-
- ch = self.term.getCharacter(2, 0)
- self.assertEqual(ch[0], '!')
- self.assertEqual(ch[1].charset, G3)
-
- ch = self.term.getCharacter(3, 0)
- self.assertEqual(ch[0], '!')
- self.assertEqual(ch[1].charset, G0)
-
- def testShifting(self):
- s1 = "Hello"
- s2 = "World"
- s3 = "Bye!"
- self.term.write("Hello\n")
- self.term.shiftOut()
- self.term.write("World\n")
- self.term.shiftIn()
- self.term.write("Bye!\n")
-
- g = G0
- h = 0
- for s in (s1, s2, s3):
- for i in range(len(s)):
- ch = self.term.getCharacter(i, h)
- self.assertEqual(ch[0], s[i])
- self.assertEqual(ch[1].charset, g)
- g = g == G0 and G1 or G0
- h += 1
-
- def testGraphicRendition(self):
- self.term.selectGraphicRendition(BOLD, UNDERLINE, BLINK, REVERSE_VIDEO)
- self.term.write('W')
- self.term.selectGraphicRendition(NORMAL)
- self.term.write('X')
- self.term.selectGraphicRendition(BLINK)
- self.term.write('Y')
- self.term.selectGraphicRendition(BOLD)
- self.term.write('Z')
-
- ch = self.term.getCharacter(0, 0)
- self.assertEqual(ch[0], 'W')
- self.failUnless(ch[1].bold)
- self.failUnless(ch[1].underline)
- self.failUnless(ch[1].blink)
- self.failUnless(ch[1].reverseVideo)
-
- ch = self.term.getCharacter(1, 0)
- self.assertEqual(ch[0], 'X')
- self.failIf(ch[1].bold)
- self.failIf(ch[1].underline)
- self.failIf(ch[1].blink)
- self.failIf(ch[1].reverseVideo)
-
- ch = self.term.getCharacter(2, 0)
- self.assertEqual(ch[0], 'Y')
- self.failUnless(ch[1].blink)
- self.failIf(ch[1].bold)
- self.failIf(ch[1].underline)
- self.failIf(ch[1].reverseVideo)
-
- ch = self.term.getCharacter(3, 0)
- self.assertEqual(ch[0], 'Z')
- self.failUnless(ch[1].blink)
- self.failUnless(ch[1].bold)
- self.failIf(ch[1].underline)
- self.failIf(ch[1].reverseVideo)
-
- def testColorAttributes(self):
- s1 = "Merry xmas"
- s2 = "Just kidding"
- self.term.selectGraphicRendition(helper.FOREGROUND + helper.RED,
- helper.BACKGROUND + helper.GREEN)
- self.term.write(s1 + "\n")
- self.term.selectGraphicRendition(NORMAL)
- self.term.write(s2 + "\n")
-
- for i in range(len(s1)):
- ch = self.term.getCharacter(i, 0)
- self.assertEqual(ch[0], s1[i])
- self.assertEqual(ch[1].charset, G0)
- self.assertEqual(ch[1].bold, False)
- self.assertEqual(ch[1].underline, False)
- self.assertEqual(ch[1].blink, False)
- self.assertEqual(ch[1].reverseVideo, False)
- self.assertEqual(ch[1].foreground, helper.RED)
- self.assertEqual(ch[1].background, helper.GREEN)
-
- for i in range(len(s2)):
- ch = self.term.getCharacter(i, 1)
- self.assertEqual(ch[0], s2[i])
- self.assertEqual(ch[1].charset, G0)
- self.assertEqual(ch[1].bold, False)
- self.assertEqual(ch[1].underline, False)
- self.assertEqual(ch[1].blink, False)
- self.assertEqual(ch[1].reverseVideo, False)
- self.assertEqual(ch[1].foreground, helper.WHITE)
- self.assertEqual(ch[1].background, helper.BLACK)
-
- def testEraseLine(self):
- s1 = 'line 1'
- s2 = 'line 2'
- s3 = 'line 3'
- self.term.write('\n'.join((s1, s2, s3)) + '\n')
- self.term.cursorPosition(1, 1)
- self.term.eraseLine()
-
- self.assertEqual(
- str(self.term),
- s1 + '\n' +
- '\n' +
- s3 + '\n' +
- '\n' * (HEIGHT - 4))
-
- def testEraseToLineEnd(self):
- s = 'Hello, world.'
- self.term.write(s)
- self.term.cursorBackward(5)
- self.term.eraseToLineEnd()
- self.assertEqual(
- str(self.term),
- s[:-5] + '\n' +
- '\n' * (HEIGHT - 2))
-
- def testEraseToLineBeginning(self):
- s = 'Hello, world.'
- self.term.write(s)
- self.term.cursorBackward(5)
- self.term.eraseToLineBeginning()
- self.assertEqual(
- str(self.term),
- s[-4:].rjust(len(s)) + '\n' +
- '\n' * (HEIGHT - 2))
-
- def testEraseDisplay(self):
- self.term.write('Hello world\n')
- self.term.write('Goodbye world\n')
- self.term.eraseDisplay()
-
- self.assertEqual(
- str(self.term),
- '\n' * (HEIGHT - 1))
-
- def testEraseToDisplayEnd(self):
- s1 = "Hello world"
- s2 = "Goodbye world"
- self.term.write('\n'.join((s1, s2, '')))
- self.term.cursorPosition(5, 1)
- self.term.eraseToDisplayEnd()
-
- self.assertEqual(
- str(self.term),
- s1 + '\n' +
- s2[:5] + '\n' +
- '\n' * (HEIGHT - 3))
-
- def testEraseToDisplayBeginning(self):
- s1 = "Hello world"
- s2 = "Goodbye world"
- self.term.write('\n'.join((s1, s2)))
- self.term.cursorPosition(5, 1)
- self.term.eraseToDisplayBeginning()
-
- self.assertEqual(
- str(self.term),
- '\n' +
- s2[6:].rjust(len(s2)) + '\n' +
- '\n' * (HEIGHT - 3))
-
- def testLineInsertion(self):
- s1 = "Hello world"
- s2 = "Goodbye world"
- self.term.write('\n'.join((s1, s2)))
- self.term.cursorPosition(7, 1)
- self.term.insertLine()
-
- self.assertEqual(
- str(self.term),
- s1 + '\n' +
- '\n' +
- s2 + '\n' +
- '\n' * (HEIGHT - 4))
-
- def testLineDeletion(self):
- s1 = "Hello world"
- s2 = "Middle words"
- s3 = "Goodbye world"
- self.term.write('\n'.join((s1, s2, s3)))
- self.term.cursorPosition(9, 1)
- self.term.deleteLine()
-
- self.assertEqual(
- str(self.term),
- s1 + '\n' +
- s3 + '\n' +
- '\n' * (HEIGHT - 3))
-
-class FakeDelayedCall:
- called = False
- cancelled = False
- def __init__(self, fs, timeout, f, a, kw):
- self.fs = fs
- self.timeout = timeout
- self.f = f
- self.a = a
- self.kw = kw
-
- def active(self):
- return not (self.cancelled or self.called)
-
- def cancel(self):
- self.cancelled = True
-# self.fs.calls.remove(self)
-
- def call(self):
- self.called = True
- self.f(*self.a, **self.kw)
-
-class FakeScheduler:
- def __init__(self):
- self.calls = []
-
- def callLater(self, timeout, f, *a, **kw):
- self.calls.append(FakeDelayedCall(self, timeout, f, a, kw))
- return self.calls[-1]
-
-class ExpectTestCase(unittest.TestCase):
- def setUp(self):
- self.term = helper.ExpectableBuffer()
- self.term.connectionMade()
- self.fs = FakeScheduler()
-
- def testSimpleString(self):
- result = []
- d = self.term.expect("hello world", timeout=1, scheduler=self.fs)
- d.addCallback(result.append)
-
- self.term.write("greeting puny earthlings\n")
- self.failIf(result)
- self.term.write("hello world\n")
- self.failUnless(result)
- self.assertEqual(result[0].group(), "hello world")
- self.assertEqual(len(self.fs.calls), 1)
- self.failIf(self.fs.calls[0].active())
-
- def testBrokenUpString(self):
- result = []
- d = self.term.expect("hello world")
- d.addCallback(result.append)
-
- self.failIf(result)
- self.term.write("hello ")
- self.failIf(result)
- self.term.write("worl")
- self.failIf(result)
- self.term.write("d")
- self.failUnless(result)
- self.assertEqual(result[0].group(), "hello world")
-
-
- def testMultiple(self):
- result = []
- d1 = self.term.expect("hello ")
- d1.addCallback(result.append)
- d2 = self.term.expect("world")
- d2.addCallback(result.append)
-
- self.failIf(result)
- self.term.write("hello")
- self.failIf(result)
- self.term.write(" ")
- self.assertEqual(len(result), 1)
- self.term.write("world")
- self.assertEqual(len(result), 2)
- self.assertEqual(result[0].group(), "hello ")
- self.assertEqual(result[1].group(), "world")
-
- def testSynchronous(self):
- self.term.write("hello world")
-
- result = []
- d = self.term.expect("hello world")
- d.addCallback(result.append)
- self.failUnless(result)
- self.assertEqual(result[0].group(), "hello world")
-
- def testMultipleSynchronous(self):
- self.term.write("goodbye world")
-
- result = []
- d1 = self.term.expect("bye")
- d1.addCallback(result.append)
- d2 = self.term.expect("world")
- d2.addCallback(result.append)
-
- self.assertEqual(len(result), 2)
- self.assertEqual(result[0].group(), "bye")
- self.assertEqual(result[1].group(), "world")
-
- def _cbTestTimeoutFailure(self, res):
- self.assert_(hasattr(res, 'type'))
- self.assertEqual(res.type, helper.ExpectationTimeout)
-
- def testTimeoutFailure(self):
- d = self.term.expect("hello world", timeout=1, scheduler=self.fs)
- d.addBoth(self._cbTestTimeoutFailure)
- self.fs.calls[0].call()
-
- def testOverlappingTimeout(self):
- self.term.write("not zoomtastic")
-
- result = []
- d1 = self.term.expect("hello world", timeout=1, scheduler=self.fs)
- d1.addBoth(self._cbTestTimeoutFailure)
- d2 = self.term.expect("zoom")
- d2.addCallback(result.append)
-
- self.fs.calls[0].call()
-
- self.assertEqual(len(result), 1)
- self.assertEqual(result[0].group(), "zoom")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py
deleted file mode 100755
index f313b5ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py
+++ /dev/null
@@ -1,496 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_insults -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport
-
-from twisted.conch.insults.insults import ServerProtocol, ClientProtocol
-from twisted.conch.insults.insults import CS_UK, CS_US, CS_DRAWING, CS_ALTERNATE, CS_ALTERNATE_SPECIAL
-from twisted.conch.insults.insults import G0, G1
-from twisted.conch.insults.insults import modes
-
-def _getattr(mock, name):
- return super(Mock, mock).__getattribute__(name)
-
-def occurrences(mock):
- return _getattr(mock, 'occurrences')
-
-def methods(mock):
- return _getattr(mock, 'methods')
-
-def _append(mock, obj):
- occurrences(mock).append(obj)
-
-default = object()
-
-class Mock(object):
- callReturnValue = default
-
- def __init__(self, methods=None, callReturnValue=default):
- """
- @param methods: Mapping of names to return values
- @param callReturnValue: object __call__ should return
- """
- self.occurrences = []
- if methods is None:
- methods = {}
- self.methods = methods
- if callReturnValue is not default:
- self.callReturnValue = callReturnValue
-
- def __call__(self, *a, **kw):
- returnValue = _getattr(self, 'callReturnValue')
- if returnValue is default:
- returnValue = Mock()
- # _getattr(self, 'occurrences').append(('__call__', returnValue, a, kw))
- _append(self, ('__call__', returnValue, a, kw))
- return returnValue
-
- def __getattribute__(self, name):
- methods = _getattr(self, 'methods')
- if name in methods:
- attrValue = Mock(callReturnValue=methods[name])
- else:
- attrValue = Mock()
- # _getattr(self, 'occurrences').append((name, attrValue))
- _append(self, (name, attrValue))
- return attrValue
-
-class MockMixin:
- def assertCall(self, occurrence, methodName, expectedPositionalArgs=(),
- expectedKeywordArgs={}):
- attr, mock = occurrence
- self.assertEqual(attr, methodName)
- self.assertEqual(len(occurrences(mock)), 1)
- [(call, result, args, kw)] = occurrences(mock)
- self.assertEqual(call, "__call__")
- self.assertEqual(args, expectedPositionalArgs)
- self.assertEqual(kw, expectedKeywordArgs)
- return result
-
-
-_byteGroupingTestTemplate = """\
-def testByte%(groupName)s(self):
- transport = StringTransport()
- proto = Mock()
- parser = self.protocolFactory(lambda: proto)
- parser.factory = self
- parser.makeConnection(transport)
-
- bytes = self.TEST_BYTES
- while bytes:
- chunk = bytes[:%(bytesPer)d]
- bytes = bytes[%(bytesPer)d:]
- parser.dataReceived(chunk)
-
- self.verifyResults(transport, proto, parser)
-"""
-class ByteGroupingsMixin(MockMixin):
- protocolFactory = None
-
- for word, n in [('Pairs', 2), ('Triples', 3), ('Quads', 4), ('Quints', 5), ('Sexes', 6)]:
- exec _byteGroupingTestTemplate % {'groupName': word, 'bytesPer': n}
- del word, n
-
- def verifyResults(self, transport, proto, parser):
- result = self.assertCall(occurrences(proto).pop(0), "makeConnection", (parser,))
- self.assertEqual(occurrences(result), [])
-
-del _byteGroupingTestTemplate
-
-class ServerArrowKeys(ByteGroupingsMixin, unittest.TestCase):
- protocolFactory = ServerProtocol
-
- # All the arrow keys once
- TEST_BYTES = '\x1b[A\x1b[B\x1b[C\x1b[D'
-
- def verifyResults(self, transport, proto, parser):
- ByteGroupingsMixin.verifyResults(self, transport, proto, parser)
-
- for arrow in (parser.UP_ARROW, parser.DOWN_ARROW,
- parser.RIGHT_ARROW, parser.LEFT_ARROW):
- result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (arrow, None))
- self.assertEqual(occurrences(result), [])
- self.failIf(occurrences(proto))
-
-
-class PrintableCharacters(ByteGroupingsMixin, unittest.TestCase):
- protocolFactory = ServerProtocol
-
- # Some letters and digits, first on their own, then capitalized,
- # then modified with alt
-
- TEST_BYTES = 'abc123ABC!@#\x1ba\x1bb\x1bc\x1b1\x1b2\x1b3'
-
- def verifyResults(self, transport, proto, parser):
- ByteGroupingsMixin.verifyResults(self, transport, proto, parser)
-
- for char in 'abc123ABC!@#':
- result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (char, None))
- self.assertEqual(occurrences(result), [])
-
- for char in 'abc123':
- result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (char, parser.ALT))
- self.assertEqual(occurrences(result), [])
-
- occs = occurrences(proto)
- self.failIf(occs, "%r should have been []" % (occs,))
-
-class ServerFunctionKeys(ByteGroupingsMixin, unittest.TestCase):
- """Test for parsing and dispatching function keys (F1 - F12)
- """
- protocolFactory = ServerProtocol
-
- byteList = []
- for bytes in ('OP', 'OQ', 'OR', 'OS', # F1 - F4
- '15~', '17~', '18~', '19~', # F5 - F8
- '20~', '21~', '23~', '24~'): # F9 - F12
- byteList.append('\x1b[' + bytes)
- TEST_BYTES = ''.join(byteList)
- del byteList, bytes
-
- def verifyResults(self, transport, proto, parser):
- ByteGroupingsMixin.verifyResults(self, transport, proto, parser)
- for funcNum in range(1, 13):
- funcArg = getattr(parser, 'F%d' % (funcNum,))
- result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (funcArg, None))
- self.assertEqual(occurrences(result), [])
- self.failIf(occurrences(proto))
-
-class ClientCursorMovement(ByteGroupingsMixin, unittest.TestCase):
- protocolFactory = ClientProtocol
-
- d2 = "\x1b[2B"
- r4 = "\x1b[4C"
- u1 = "\x1b[A"
- l2 = "\x1b[2D"
- # Move the cursor down two, right four, up one, left two, up one, left two
- TEST_BYTES = d2 + r4 + u1 + l2 + u1 + l2
- del d2, r4, u1, l2
-
- def verifyResults(self, transport, proto, parser):
- ByteGroupingsMixin.verifyResults(self, transport, proto, parser)
-
- for (method, count) in [('Down', 2), ('Forward', 4), ('Up', 1),
- ('Backward', 2), ('Up', 1), ('Backward', 2)]:
- result = self.assertCall(occurrences(proto).pop(0), "cursor" + method, (count,))
- self.assertEqual(occurrences(result), [])
- self.failIf(occurrences(proto))
-
-class ClientControlSequences(unittest.TestCase, MockMixin):
- def setUp(self):
- self.transport = StringTransport()
- self.proto = Mock()
- self.parser = ClientProtocol(lambda: self.proto)
- self.parser.factory = self
- self.parser.makeConnection(self.transport)
- result = self.assertCall(occurrences(self.proto).pop(0), "makeConnection", (self.parser,))
- self.failIf(occurrences(result))
-
- def testSimpleCardinals(self):
- self.parser.dataReceived(
- ''.join([''.join(['\x1b[' + str(n) + ch for n in ('', 2, 20, 200)]) for ch in 'BACD']))
- occs = occurrences(self.proto)
-
- for meth in ("Down", "Up", "Forward", "Backward"):
- for count in (1, 2, 20, 200):
- result = self.assertCall(occs.pop(0), "cursor" + meth, (count,))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testScrollRegion(self):
- self.parser.dataReceived('\x1b[5;22r\x1b[r')
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "setScrollRegion", (5, 22))
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "setScrollRegion", (None, None))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testHeightAndWidth(self):
- self.parser.dataReceived("\x1b#3\x1b#4\x1b#5\x1b#6")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "doubleHeightLine", (True,))
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "doubleHeightLine", (False,))
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "singleWidthLine")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "doubleWidthLine")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testCharacterSet(self):
- self.parser.dataReceived(
- ''.join([''.join(['\x1b' + g + n for n in 'AB012']) for g in '()']))
- occs = occurrences(self.proto)
-
- for which in (G0, G1):
- for charset in (CS_UK, CS_US, CS_DRAWING, CS_ALTERNATE, CS_ALTERNATE_SPECIAL):
- result = self.assertCall(occs.pop(0), "selectCharacterSet", (charset, which))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testShifting(self):
- self.parser.dataReceived("\x15\x14")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "shiftIn")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "shiftOut")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testSingleShifts(self):
- self.parser.dataReceived("\x1bN\x1bO")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "singleShift2")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "singleShift3")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testKeypadMode(self):
- self.parser.dataReceived("\x1b=\x1b>")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "applicationKeypadMode")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "numericKeypadMode")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testCursor(self):
- self.parser.dataReceived("\x1b7\x1b8")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "saveCursor")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "restoreCursor")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testReset(self):
- self.parser.dataReceived("\x1bc")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "reset")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testIndex(self):
- self.parser.dataReceived("\x1bD\x1bM\x1bE")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "index")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "reverseIndex")
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "nextLine")
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testModes(self):
- self.parser.dataReceived(
- "\x1b[" + ';'.join(map(str, [modes.KAM, modes.IRM, modes.LNM])) + "h")
- self.parser.dataReceived(
- "\x1b[" + ';'.join(map(str, [modes.KAM, modes.IRM, modes.LNM])) + "l")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "setModes", ([modes.KAM, modes.IRM, modes.LNM],))
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "resetModes", ([modes.KAM, modes.IRM, modes.LNM],))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testErasure(self):
- self.parser.dataReceived(
- "\x1b[K\x1b[1K\x1b[2K\x1b[J\x1b[1J\x1b[2J\x1b[3P")
- occs = occurrences(self.proto)
-
- for meth in ("eraseToLineEnd", "eraseToLineBeginning", "eraseLine",
- "eraseToDisplayEnd", "eraseToDisplayBeginning",
- "eraseDisplay"):
- result = self.assertCall(occs.pop(0), meth)
- self.failIf(occurrences(result))
-
- result = self.assertCall(occs.pop(0), "deleteCharacter", (3,))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testLineDeletion(self):
- self.parser.dataReceived("\x1b[M\x1b[3M")
- occs = occurrences(self.proto)
-
- for arg in (1, 3):
- result = self.assertCall(occs.pop(0), "deleteLine", (arg,))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testLineInsertion(self):
- self.parser.dataReceived("\x1b[L\x1b[3L")
- occs = occurrences(self.proto)
-
- for arg in (1, 3):
- result = self.assertCall(occs.pop(0), "insertLine", (arg,))
- self.failIf(occurrences(result))
- self.failIf(occs)
-
- def testCursorPosition(self):
- methods(self.proto)['reportCursorPosition'] = (6, 7)
- self.parser.dataReceived("\x1b[6n")
- self.assertEqual(self.transport.value(), "\x1b[7;8R")
- occs = occurrences(self.proto)
-
- result = self.assertCall(occs.pop(0), "reportCursorPosition")
- # This isn't really an interesting assert, since it only tests that
- # our mock setup is working right, but I'll include it anyway.
- self.assertEqual(result, (6, 7))
-
-
- def test_applicationDataBytes(self):
- """
- Contiguous non-control bytes are passed to a single call to the
- C{write} method of the terminal to which the L{ClientProtocol} is
- connected.
- """
- occs = occurrences(self.proto)
- self.parser.dataReceived('a')
- self.assertCall(occs.pop(0), "write", ("a",))
- self.parser.dataReceived('bc')
- self.assertCall(occs.pop(0), "write", ("bc",))
-
-
- def _applicationDataTest(self, data, calls):
- occs = occurrences(self.proto)
- self.parser.dataReceived(data)
- while calls:
- self.assertCall(occs.pop(0), *calls.pop(0))
- self.assertFalse(occs, "No other calls should happen: %r" % (occs,))
-
-
- def test_shiftInAfterApplicationData(self):
- """
- Application data bytes followed by a shift-in command are passed to a
- call to C{write} before the terminal's C{shiftIn} method is called.
- """
- self._applicationDataTest(
- 'ab\x15', [
- ("write", ("ab",)),
- ("shiftIn",)])
-
-
- def test_shiftOutAfterApplicationData(self):
- """
- Application data bytes followed by a shift-out command are passed to a
- call to C{write} before the terminal's C{shiftOut} method is called.
- """
- self._applicationDataTest(
- 'ab\x14', [
- ("write", ("ab",)),
- ("shiftOut",)])
-
-
- def test_cursorBackwardAfterApplicationData(self):
- """
- Application data bytes followed by a cursor-backward command are passed
- to a call to C{write} before the terminal's C{cursorBackward} method is
- called.
- """
- self._applicationDataTest(
- 'ab\x08', [
- ("write", ("ab",)),
- ("cursorBackward",)])
-
-
- def test_escapeAfterApplicationData(self):
- """
- Application data bytes followed by an escape character are passed to a
- call to C{write} before the terminal's handler method for the escape is
- called.
- """
- # Test a short escape
- self._applicationDataTest(
- 'ab\x1bD', [
- ("write", ("ab",)),
- ("index",)])
-
- # And a long escape
- self._applicationDataTest(
- 'ab\x1b[4h', [
- ("write", ("ab",)),
- ("setModes", ([4],))])
-
- # There's some other cases too, but they're all handled by the same
- # codepaths as above.
-
-
-
-class ServerProtocolOutputTests(unittest.TestCase):
- """
- Tests for the bytes L{ServerProtocol} writes to its transport when its
- methods are called.
- """
- def test_nextLine(self):
- """
- L{ServerProtocol.nextLine} writes C{"\r\n"} to its transport.
- """
- # Why doesn't it write ESC E? Because ESC E is poorly supported. For
- # example, gnome-terminal (many different versions) fails to scroll if
- # it receives ESC E and the cursor is already on the last row.
- protocol = ServerProtocol()
- transport = StringTransport()
- protocol.makeConnection(transport)
- protocol.nextLine()
- self.assertEqual(transport.value(), "\r\n")
-
-
-
-class Deprecations(unittest.TestCase):
- """
- Tests to ensure deprecation of L{insults.colors} and L{insults.client}
- """
-
- def ensureDeprecated(self, message):
- """
- Ensures that the correct deprecation warning was issued.
- """
- warnings = self.flushWarnings()
- self.assertIdentical(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(warnings[0]['message'], message)
- self.assertEqual(len(warnings), 1)
-
-
- def test_colors(self):
- """
- The L{insults.colors} module is deprecated
- """
- from twisted.conch.insults import colors
- self.ensureDeprecated("twisted.conch.insults.colors was deprecated "
- "in Twisted 10.1.0: Please use "
- "twisted.conch.insults.helper instead.")
-
-
- def test_client(self):
- """
- The L{insults.client} module is deprecated
- """
- from twisted.conch.insults import client
- self.ensureDeprecated("twisted.conch.insults.client was deprecated "
- "in Twisted 10.1.0: Please use "
- "twisted.conch.insults.insults instead.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py
deleted file mode 100755
index 8403e1e5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py
+++ /dev/null
@@ -1,644 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.ssh.keys}.
-"""
-
-try:
- import Crypto.Cipher.DES3
-except ImportError:
- # we'll have to skip these tests without PyCypto and pyasn1
- Crypto = None
-
-try:
- import pyasn1
-except ImportError:
- pyasn1 = None
-
-if Crypto and pyasn1:
- from twisted.conch.ssh import keys, common, sexpy
-
-import os, base64
-from twisted.conch.test import keydata
-from twisted.python import randbytes
-from twisted.python.hashlib import sha1
-from twisted.trial import unittest
-
-
-class HelpersTestCase(unittest.TestCase):
-
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
- def setUp(self):
- self._secureRandom = randbytes.secureRandom
- randbytes.secureRandom = lambda x: '\x55' * x
-
- def tearDown(self):
- randbytes.secureRandom = self._secureRandom
- self._secureRandom = None
-
- def test_pkcs1(self):
- """
- Test Public Key Cryptographic Standard #1 functions.
- """
- data = 'ABC'
- messageSize = 6
- self.assertEqual(keys.pkcs1Pad(data, messageSize),
- '\x01\xff\x00ABC')
- hash = sha1().digest()
- messageSize = 40
- self.assertEqual(keys.pkcs1Digest('', messageSize),
- '\x01\xff\xff\xff\x00' + keys.ID_SHA1 + hash)
-
- def _signRSA(self, data):
- key = keys.Key.fromString(keydata.privateRSA_openssh)
- sig = key.sign(data)
- return key.keyObject, sig
-
- def _signDSA(self, data):
- key = keys.Key.fromString(keydata.privateDSA_openssh)
- sig = key.sign(data)
- return key.keyObject, sig
-
- def test_signRSA(self):
- """
- Test that RSA keys return appropriate signatures.
- """
- data = 'data'
- key, sig = self._signRSA(data)
- sigData = keys.pkcs1Digest(data, keys.lenSig(key))
- v = key.sign(sigData, '')[0]
- self.assertEqual(sig, common.NS('ssh-rsa') + common.MP(v))
- return key, sig
-
- def test_signDSA(self):
- """
- Test that DSA keys return appropriate signatures.
- """
- data = 'data'
- key, sig = self._signDSA(data)
- sigData = sha1(data).digest()
- v = key.sign(sigData, '\x55' * 19)
- self.assertEqual(sig, common.NS('ssh-dss') + common.NS(
- Crypto.Util.number.long_to_bytes(v[0], 20) +
- Crypto.Util.number.long_to_bytes(v[1], 20)))
- return key, sig
-
-
- def test_objectType(self):
- """
- Test that objectType, returns the correct type for objects.
- """
- self.assertEqual(keys.objectType(keys.Key.fromString(
- keydata.privateRSA_openssh).keyObject), 'ssh-rsa')
- self.assertEqual(keys.objectType(keys.Key.fromString(
- keydata.privateDSA_openssh).keyObject), 'ssh-dss')
- self.assertRaises(keys.BadKeyError, keys.objectType, None)
-
-
-class KeyTestCase(unittest.TestCase):
-
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
- def setUp(self):
- self.rsaObj = Crypto.PublicKey.RSA.construct((1L, 2L, 3L, 4L, 5L))
- self.dsaObj = Crypto.PublicKey.DSA.construct((1L, 2L, 3L, 4L, 5L))
- self.rsaSignature = ('\x00\x00\x00\x07ssh-rsa\x00'
- '\x00\x00`N\xac\xb4@qK\xa0(\xc3\xf2h \xd3\xdd\xee6Np\x9d_'
- '\xb0>\xe3\x0c(L\x9d{\txUd|!\xf6m\x9c\xd3\x93\x842\x7fU'
- '\x05\xf4\xf7\xfaD\xda\xce\x81\x8ea\x7f=Y\xed*\xb7\xba\x81'
- '\xf2\xad\xda\xeb(\x97\x03S\x08\x81\xc7\xb1\xb7\xe6\xe3'
- '\xcd*\xd4\xbd\xc0wt\xf7y\xcd\xf0\xb7\x7f\xfb\x1e>\xf9r'
- '\x8c\xba')
- self.dsaSignature = ('\x00\x00\x00\x07ssh-dss\x00\x00'
- '\x00(\x18z)H\x8a\x1b\xc6\r\xbbq\xa2\xd7f\x7f$\xa7\xbf'
- '\xe8\x87\x8c\x88\xef\xd9k\x1a\x98\xdd{=\xdec\x18\t\xe3'
- '\x87\xa9\xc72h\x95')
- self.oldSecureRandom = randbytes.secureRandom
- randbytes.secureRandom = lambda x: '\xff' * x
- self.keyFile = self.mktemp()
- file(self.keyFile, 'wb').write(keydata.privateRSA_lsh)
-
- def tearDown(self):
- randbytes.secureRandom = self.oldSecureRandom
- del self.oldSecureRandom
- os.unlink(self.keyFile)
-
- def test__guessStringType(self):
- """
- Test that the _guessStringType method guesses string types
- correctly.
- """
- self.assertEqual(keys.Key._guessStringType(keydata.publicRSA_openssh),
- 'public_openssh')
- self.assertEqual(keys.Key._guessStringType(keydata.publicDSA_openssh),
- 'public_openssh')
- self.assertEqual(keys.Key._guessStringType(
- keydata.privateRSA_openssh), 'private_openssh')
- self.assertEqual(keys.Key._guessStringType(
- keydata.privateDSA_openssh), 'private_openssh')
- self.assertEqual(keys.Key._guessStringType(keydata.publicRSA_lsh),
- 'public_lsh')
- self.assertEqual(keys.Key._guessStringType(keydata.publicDSA_lsh),
- 'public_lsh')
- self.assertEqual(keys.Key._guessStringType(keydata.privateRSA_lsh),
- 'private_lsh')
- self.assertEqual(keys.Key._guessStringType(keydata.privateDSA_lsh),
- 'private_lsh')
- self.assertEqual(keys.Key._guessStringType(
- keydata.privateRSA_agentv3), 'agentv3')
- self.assertEqual(keys.Key._guessStringType(
- keydata.privateDSA_agentv3), 'agentv3')
- self.assertEqual(keys.Key._guessStringType(
- '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x01'),
- 'blob')
- self.assertEqual(keys.Key._guessStringType(
- '\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x01'),
- 'blob')
- self.assertEqual(keys.Key._guessStringType('not a key'),
- None)
-
- def _testPublicPrivateFromString(self, public, private, type, data):
- self._testPublicFromString(public, type, data)
- self._testPrivateFromString(private, type, data)
-
- def _testPublicFromString(self, public, type, data):
- publicKey = keys.Key.fromString(public)
- self.assertTrue(publicKey.isPublic())
- self.assertEqual(publicKey.type(), type)
- for k, v in publicKey.data().items():
- self.assertEqual(data[k], v)
-
- def _testPrivateFromString(self, private, type, data):
- privateKey = keys.Key.fromString(private)
- self.assertFalse(privateKey.isPublic())
- self.assertEqual(privateKey.type(), type)
- for k, v in data.items():
- self.assertEqual(privateKey.data()[k], v)
-
- def test_fromOpenSSH(self):
- """
- Test that keys are correctly generated from OpenSSH strings.
- """
- self._testPublicPrivateFromString(keydata.publicRSA_openssh,
- keydata.privateRSA_openssh, 'RSA', keydata.RSAData)
- self.assertEqual(keys.Key.fromString(
- keydata.privateRSA_openssh_encrypted,
- passphrase='encrypted'),
- keys.Key.fromString(keydata.privateRSA_openssh))
- self.assertEqual(keys.Key.fromString(
- keydata.privateRSA_openssh_alternate),
- keys.Key.fromString(keydata.privateRSA_openssh))
- self._testPublicPrivateFromString(keydata.publicDSA_openssh,
- keydata.privateDSA_openssh, 'DSA', keydata.DSAData)
-
- def test_fromOpenSSH_with_whitespace(self):
- """
- If key strings have trailing whitespace, it should be ignored.
- """
- # from bug #3391, since our test key data doesn't have
- # an issue with appended newlines
- privateDSAData = """-----BEGIN DSA PRIVATE KEY-----
-MIIBuwIBAAKBgQDylESNuc61jq2yatCzZbenlr9llG+p9LhIpOLUbXhhHcwC6hrh
-EZIdCKqTO0USLrGoP5uS9UHAUoeN62Z0KXXWTwOWGEQn/syyPzNJtnBorHpNUT9D
-Qzwl1yUa53NNgEctpo4NoEFOx8PuU6iFLyvgHCjNn2MsuGuzkZm7sI9ZpQIVAJiR
-9dPc08KLdpJyRxz8T74b4FQRAoGAGBc4Z5Y6R/HZi7AYM/iNOM8su6hrk8ypkBwR
-a3Dbhzk97fuV3SF1SDrcQu4zF7c4CtH609N5nfZs2SUjLLGPWln83Ysb8qhh55Em
-AcHXuROrHS/sDsnqu8FQp86MaudrqMExCOYyVPE7jaBWW+/JWFbKCxmgOCSdViUJ
-esJpBFsCgYEA7+jtVvSt9yrwsS/YU1QGP5wRAiDYB+T5cK4HytzAqJKRdC5qS4zf
-C7R0eKcDHHLMYO39aPnCwXjscisnInEhYGNblTDyPyiyNxAOXuC8x7luTmwzMbNJ
-/ow0IqSj0VF72VJN9uSoPpFd4lLT0zN8v42RWja0M8ohWNf+YNJluPgCFE0PT4Vm
-SUrCyZXsNh6VXwjs3gKQ
------END DSA PRIVATE KEY-----"""
- self.assertEqual(keys.Key.fromString(privateDSAData),
- keys.Key.fromString(privateDSAData + '\n'))
-
- def test_fromNewerOpenSSH(self):
- """
- Newer versions of OpenSSH generate encrypted keys which have a longer
- IV than the older versions. These newer keys are also loaded.
- """
- key = keys.Key.fromString(keydata.privateRSA_openssh_encrypted_aes,
- passphrase='testxp')
- self.assertEqual(key.type(), 'RSA')
- key2 = keys.Key.fromString(
- keydata.privateRSA_openssh_encrypted_aes + '\n',
- passphrase='testxp')
- self.assertEqual(key, key2)
-
-
- def test_fromLSH(self):
- """
- Test that keys are correctly generated from LSH strings.
- """
- self._testPublicPrivateFromString(keydata.publicRSA_lsh,
- keydata.privateRSA_lsh, 'RSA', keydata.RSAData)
- self._testPublicPrivateFromString(keydata.publicDSA_lsh,
- keydata.privateDSA_lsh, 'DSA', keydata.DSAData)
- sexp = sexpy.pack([['public-key', ['bad-key', ['p', '2']]]])
- self.assertRaises(keys.BadKeyError, keys.Key.fromString,
- data='{'+base64.encodestring(sexp)+'}')
- sexp = sexpy.pack([['private-key', ['bad-key', ['p', '2']]]])
- self.assertRaises(keys.BadKeyError, keys.Key.fromString,
- sexp)
-
- def test_fromAgentv3(self):
- """
- Test that keys are correctly generated from Agent v3 strings.
- """
- self._testPrivateFromString(keydata.privateRSA_agentv3, 'RSA',
- keydata.RSAData)
- self._testPrivateFromString(keydata.privateDSA_agentv3, 'DSA',
- keydata.DSAData)
- self.assertRaises(keys.BadKeyError, keys.Key.fromString,
- '\x00\x00\x00\x07ssh-foo'+'\x00\x00\x00\x01\x01'*5)
-
- def test_fromStringErrors(self):
- """
- keys.Key.fromString should raise BadKeyError when the key is invalid.
- """
- self.assertRaises(keys.BadKeyError, keys.Key.fromString, '')
- # no key data with a bad key type
- self.assertRaises(keys.BadKeyError, keys.Key.fromString, '',
- 'bad_type')
- # trying to decrypt a key which doesn't support encryption
- self.assertRaises(keys.BadKeyError, keys.Key.fromString,
- keydata.publicRSA_lsh, passphrase = 'unencrypted')
- # trying to decrypt an unencrypted key
- self.assertRaises(keys.EncryptedKeyError, keys.Key.fromString,
- keys.Key(self.rsaObj).toString('openssh', 'encrypted'))
- # key with no key data
- self.assertRaises(keys.BadKeyError, keys.Key.fromString,
- '-----BEGIN RSA KEY-----\nwA==\n')
- # key with invalid DEK Info
- self.assertRaises(
- keys.BadKeyError, keys.Key.fromString,
- """-----BEGIN ENCRYPTED RSA KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: weird type
-
-4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n
-T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H
-g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB
-sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5
-9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV
-gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW
-0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE
-vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS
-hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk
-2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf
-qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk
-4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY
-EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n
-8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0
-fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P
-V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+
-0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5
-xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI
-dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup
-VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk
-gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c
-8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw
-SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7
-CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE
-xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P
------END RSA PRIVATE KEY-----""")
- # key with invalid encryption type
- self.assertRaises(
- keys.BadKeyError, keys.Key.fromString,
- """-----BEGIN ENCRYPTED RSA KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: FOO-123-BAR,01234567
-
-4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n
-T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H
-g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB
-sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5
-9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV
-gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW
-0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE
-vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS
-hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk
-2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf
-qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk
-4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY
-EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n
-8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0
-fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P
-V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+
-0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5
-xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI
-dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup
-VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk
-gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c
-8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw
-SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7
-CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE
-xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P
------END RSA PRIVATE KEY-----""")
- # key with bad IV (AES)
- self.assertRaises(
- keys.BadKeyError, keys.Key.fromString,
- """-----BEGIN ENCRYPTED RSA KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-128-CBC,01234
-
-4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n
-T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H
-g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB
-sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5
-9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV
-gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW
-0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE
-vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS
-hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk
-2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf
-qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk
-4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY
-EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n
-8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0
-fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P
-V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+
-0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5
-xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI
-dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup
-VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk
-gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c
-8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw
-SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7
-CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE
-xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P
------END RSA PRIVATE KEY-----""")
- # key with bad IV (DES3)
- self.assertRaises(
- keys.BadKeyError, keys.Key.fromString,
- """-----BEGIN ENCRYPTED RSA KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,01234
-
-4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n
-T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H
-g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB
-sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5
-9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV
-gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW
-0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE
-vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS
-hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk
-2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf
-qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk
-4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY
-EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n
-8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0
-fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P
-V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+
-0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5
-xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI
-dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup
-VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk
-gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c
-8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw
-SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7
-CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE
-xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P
------END RSA PRIVATE KEY-----""")
-
- def test_fromFile(self):
- """
- Test that fromFile works correctly.
- """
- self.assertEqual(keys.Key.fromFile(self.keyFile),
- keys.Key.fromString(keydata.privateRSA_lsh))
- self.assertRaises(keys.BadKeyError, keys.Key.fromFile,
- self.keyFile, 'bad_type')
- self.assertRaises(keys.BadKeyError, keys.Key.fromFile,
- self.keyFile, passphrase='unencrypted')
-
- def test_init(self):
- """
- Test that the PublicKey object is initialized correctly.
- """
- obj = Crypto.PublicKey.RSA.construct((1L, 2L))
- key = keys.Key(obj)
- self.assertEqual(key.keyObject, obj)
-
- def test_equal(self):
- """
- Test that Key objects are compared correctly.
- """
- rsa1 = keys.Key(self.rsaObj)
- rsa2 = keys.Key(self.rsaObj)
- rsa3 = keys.Key(Crypto.PublicKey.RSA.construct((1L, 2L)))
- dsa = keys.Key(self.dsaObj)
- self.assertTrue(rsa1 == rsa2)
- self.assertFalse(rsa1 == rsa3)
- self.assertFalse(rsa1 == dsa)
- self.assertFalse(rsa1 == object)
- self.assertFalse(rsa1 == None)
-
- def test_notEqual(self):
- """
- Test that Key objects are not-compared correctly.
- """
- rsa1 = keys.Key(self.rsaObj)
- rsa2 = keys.Key(self.rsaObj)
- rsa3 = keys.Key(Crypto.PublicKey.RSA.construct((1L, 2L)))
- dsa = keys.Key(self.dsaObj)
- self.assertFalse(rsa1 != rsa2)
- self.assertTrue(rsa1 != rsa3)
- self.assertTrue(rsa1 != dsa)
- self.assertTrue(rsa1 != object)
- self.assertTrue(rsa1 != None)
-
- def test_type(self):
- """
- Test that the type method returns the correct type for an object.
- """
- self.assertEqual(keys.Key(self.rsaObj).type(), 'RSA')
- self.assertEqual(keys.Key(self.rsaObj).sshType(), 'ssh-rsa')
- self.assertEqual(keys.Key(self.dsaObj).type(), 'DSA')
- self.assertEqual(keys.Key(self.dsaObj).sshType(), 'ssh-dss')
- self.assertRaises(RuntimeError, keys.Key(None).type)
- self.assertRaises(RuntimeError, keys.Key(None).sshType)
- self.assertRaises(RuntimeError, keys.Key(self).type)
- self.assertRaises(RuntimeError, keys.Key(self).sshType)
-
- def test_fromBlob(self):
- """
- Test that a public key is correctly generated from a public key blob.
- """
- rsaBlob = common.NS('ssh-rsa') + common.MP(2) + common.MP(3)
- rsaKey = keys.Key.fromString(rsaBlob)
- dsaBlob = (common.NS('ssh-dss') + common.MP(2) + common.MP(3) +
- common.MP(4) + common.MP(5))
- dsaKey = keys.Key.fromString(dsaBlob)
- badBlob = common.NS('ssh-bad')
- self.assertTrue(rsaKey.isPublic())
- self.assertEqual(rsaKey.data(), {'e':2L, 'n':3L})
- self.assertTrue(dsaKey.isPublic())
- self.assertEqual(dsaKey.data(), {'p':2L, 'q':3L, 'g':4L, 'y':5L})
- self.assertRaises(keys.BadKeyError,
- keys.Key.fromString, badBlob)
-
-
- def test_fromPrivateBlob(self):
- """
- Test that a private key is correctly generated from a private key blob.
- """
- rsaBlob = (common.NS('ssh-rsa') + common.MP(2) + common.MP(3) +
- common.MP(4) + common.MP(5) + common.MP(6) + common.MP(7))
- rsaKey = keys.Key._fromString_PRIVATE_BLOB(rsaBlob)
- dsaBlob = (common.NS('ssh-dss') + common.MP(2) + common.MP(3) +
- common.MP(4) + common.MP(5) + common.MP(6))
- dsaKey = keys.Key._fromString_PRIVATE_BLOB(dsaBlob)
- badBlob = common.NS('ssh-bad')
- self.assertFalse(rsaKey.isPublic())
- self.assertEqual(
- rsaKey.data(), {'n':2L, 'e':3L, 'd':4L, 'u':5L, 'p':6L, 'q':7L})
- self.assertFalse(dsaKey.isPublic())
- self.assertEqual(dsaKey.data(), {'p':2L, 'q':3L, 'g':4L, 'y':5L, 'x':6L})
- self.assertRaises(
- keys.BadKeyError, keys.Key._fromString_PRIVATE_BLOB, badBlob)
-
-
- def test_blob(self):
- """
- Test that the Key object generates blobs correctly.
- """
- self.assertEqual(keys.Key(self.rsaObj).blob(),
- '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x02'
- '\x00\x00\x00\x01\x01')
- self.assertEqual(keys.Key(self.dsaObj).blob(),
- '\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x03'
- '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x02'
- '\x00\x00\x00\x01\x01')
-
- badKey = keys.Key(None)
- self.assertRaises(RuntimeError, badKey.blob)
-
-
- def test_privateBlob(self):
- """
- L{Key.privateBlob} returns the SSH protocol-level format of the private
- key and raises L{RuntimeError} if the underlying key object is invalid.
- """
- self.assertEqual(keys.Key(self.rsaObj).privateBlob(),
- '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x01'
- '\x00\x00\x00\x01\x02\x00\x00\x00\x01\x03\x00'
- '\x00\x00\x01\x04\x00\x00\x00\x01\x04\x00\x00'
- '\x00\x01\x05')
- self.assertEqual(keys.Key(self.dsaObj).privateBlob(),
- '\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x03'
- '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x02\x00'
- '\x00\x00\x01\x01\x00\x00\x00\x01\x05')
-
- badKey = keys.Key(None)
- self.assertRaises(RuntimeError, badKey.privateBlob)
-
-
- def test_toOpenSSH(self):
- """
- Test that the Key object generates OpenSSH keys correctly.
- """
- key = keys.Key.fromString(keydata.privateRSA_lsh)
- self.assertEqual(key.toString('openssh'), keydata.privateRSA_openssh)
- self.assertEqual(key.toString('openssh', 'encrypted'),
- keydata.privateRSA_openssh_encrypted)
- self.assertEqual(key.public().toString('openssh'),
- keydata.publicRSA_openssh[:-8]) # no comment
- self.assertEqual(key.public().toString('openssh', 'comment'),
- keydata.publicRSA_openssh)
- key = keys.Key.fromString(keydata.privateDSA_lsh)
- self.assertEqual(key.toString('openssh'), keydata.privateDSA_openssh)
- self.assertEqual(key.public().toString('openssh', 'comment'),
- keydata.publicDSA_openssh)
- self.assertEqual(key.public().toString('openssh'),
- keydata.publicDSA_openssh[:-8]) # no comment
-
- def test_toLSH(self):
- """
- Test that the Key object generates LSH keys correctly.
- """
- key = keys.Key.fromString(keydata.privateRSA_openssh)
- self.assertEqual(key.toString('lsh'), keydata.privateRSA_lsh)
- self.assertEqual(key.public().toString('lsh'),
- keydata.publicRSA_lsh)
- key = keys.Key.fromString(keydata.privateDSA_openssh)
- self.assertEqual(key.toString('lsh'), keydata.privateDSA_lsh)
- self.assertEqual(key.public().toString('lsh'),
- keydata.publicDSA_lsh)
-
- def test_toAgentv3(self):
- """
- Test that the Key object generates Agent v3 keys correctly.
- """
- key = keys.Key.fromString(keydata.privateRSA_openssh)
- self.assertEqual(key.toString('agentv3'), keydata.privateRSA_agentv3)
- key = keys.Key.fromString(keydata.privateDSA_openssh)
- self.assertEqual(key.toString('agentv3'), keydata.privateDSA_agentv3)
-
- def test_toStringErrors(self):
- """
- Test that toString raises errors appropriately.
- """
- self.assertRaises(keys.BadKeyError, keys.Key(self.rsaObj).toString,
- 'bad_type')
-
- def test_sign(self):
- """
- Test that the Key object generates correct signatures.
- """
- key = keys.Key.fromString(keydata.privateRSA_openssh)
- self.assertEqual(key.sign(''), self.rsaSignature)
- key = keys.Key.fromString(keydata.privateDSA_openssh)
- self.assertEqual(key.sign(''), self.dsaSignature)
-
-
- def test_verify(self):
- """
- Test that the Key object correctly verifies signatures.
- """
- key = keys.Key.fromString(keydata.publicRSA_openssh)
- self.assertTrue(key.verify(self.rsaSignature, ''))
- self.assertFalse(key.verify(self.rsaSignature, 'a'))
- self.assertFalse(key.verify(self.dsaSignature, ''))
- key = keys.Key.fromString(keydata.publicDSA_openssh)
- self.assertTrue(key.verify(self.dsaSignature, ''))
- self.assertFalse(key.verify(self.dsaSignature, 'a'))
- self.assertFalse(key.verify(self.rsaSignature, ''))
-
-
- def test_verifyDSANoPrefix(self):
- """
- Some commercial SSH servers send DSA keys as 2 20-byte numbers;
- they are still verified as valid keys.
- """
- key = keys.Key.fromString(keydata.publicDSA_openssh)
- self.assertTrue(key.verify(self.dsaSignature[-40:], ''))
-
-
- def test_repr(self):
- """
- Test the pretty representation of Key.
- """
- self.assertEqual(repr(keys.Key(self.rsaObj)),
-"""<RSA Private Key (0 bits)
-attr d:
-\t03
-attr e:
-\t02
-attr n:
-\t01
-attr p:
-\t04
-attr q:
-\t05
-attr u:
-\t04>""")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py
deleted file mode 100755
index d7fdacf0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py
+++ /dev/null
@@ -1,1037 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.client.knownhosts}.
-"""
-
-import os
-from binascii import Error as BinasciiError, b2a_base64, a2b_base64
-
-try:
- import Crypto
- import pyasn1
-except ImportError:
- skip = "PyCrypto and PyASN1 required for twisted.conch.knownhosts."
-else:
- from twisted.conch.ssh.keys import Key, BadKeyError
- from twisted.conch.client.knownhosts import \
- PlainEntry, HashedEntry, KnownHostsFile, UnparsedEntry, ConsoleUI
- from twisted.conch.client import default
-
-from zope.interface.verify import verifyObject
-
-from twisted.python.filepath import FilePath
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import Deferred
-from twisted.conch.interfaces import IKnownHostEntry
-from twisted.conch.error import HostKeyChanged, UserRejectedKey, InvalidEntry
-
-
-sampleEncodedKey = (
- 'AAAAB3NzaC1yc2EAAAABIwAAAQEAsV0VMRbGmzhqxxayLRHmvnFvtyNqgbNKV46dU1bVFB+3y'
- 'tNvue4Riqv/SVkPRNwMb7eWH29SviXaBxUhYyzKkDoNUq3rTNnH1Vnif6d6X4JCrUb5d3W+Dm'
- 'YClyJrZ5HgD/hUpdSkTRqdbQ2TrvSAxRacj+vHHT4F4dm1bJSewm3B2D8HVOoi/CbVh3dsIiC'
- 'dp8VltdZx4qYVfYe2LwVINCbAa3d3tj9ma7RVfw3OH2Mfb+toLd1N5tBQFb7oqTt2nC6I/6Bd'
- '4JwPUld+IEitw/suElq/AIJVQXXujeyiZlea90HE65U2mF1ytr17HTAIT2ySokJWyuBANGACk'
- '6iIaw==')
-
-otherSampleEncodedKey = (
- 'AAAAB3NzaC1yc2EAAAABIwAAAIEAwaeCZd3UCuPXhX39+/p9qO028jTF76DMVd9mPvYVDVXuf'
- 'WckKZauF7+0b7qm+ChT7kan6BzRVo4++gCVNfAlMzLysSt3ylmOR48tFpAfygg9UCX3DjHz0E'
- 'lOOUKh3iifc9aUShD0OPaK3pR5JJ8jfiBfzSYWt/hDi/iZ4igsSs8=')
-
-thirdSampleEncodedKey = (
- 'AAAAB3NzaC1yc2EAAAABIwAAAQEAl/TQakPkePlnwCBRPitIVUTg6Z8VzN1en+DGkyo/evkmLw'
- '7o4NWR5qbysk9A9jXW332nxnEuAnbcCam9SHe1su1liVfyIK0+3bdn0YRB0sXIbNEtMs2LtCho'
- '/aV3cXPS+Cf1yut3wvIpaRnAzXxuKPCTXQ7/y0IXa8TwkRBH58OJa3RqfQ/NsSp5SAfdsrHyH2'
- 'aitiVKm2jfbTKzSEqOQG/zq4J9GXTkq61gZugory/Tvl5/yPgSnOR6C9jVOMHf27ZPoRtyj9SY'
- '343Hd2QHiIE0KPZJEgCynKeWoKz8v6eTSK8n4rBnaqWdp8MnGZK1WGy05MguXbyCDuTC8AmJXQ'
- '==')
-
-sampleKey = a2b_base64(sampleEncodedKey)
-otherSampleKey = a2b_base64(otherSampleEncodedKey)
-thirdSampleKey = a2b_base64(thirdSampleEncodedKey)
-
-samplePlaintextLine = (
- "www.twistedmatrix.com ssh-rsa " + sampleEncodedKey + "\n")
-
-otherSamplePlaintextLine = (
- "divmod.com ssh-rsa " + otherSampleEncodedKey + "\n")
-
-sampleHostIPLine = (
- "www.twistedmatrix.com,198.49.126.131 ssh-rsa " + sampleEncodedKey + "\n")
-
-sampleHashedLine = (
- "|1|gJbSEPBG9ZSBoZpHNtZBD1bHKBA=|bQv+0Xa0dByrwkA1EB0E7Xop/Fo= ssh-rsa " +
- sampleEncodedKey + "\n")
-
-
-
-class EntryTestsMixin:
- """
- Tests for implementations of L{IKnownHostEntry}. Subclasses must set the
- 'entry' attribute to a provider of that interface, the implementation of
- that interface under test.
-
- @ivar entry: a provider of L{IKnownHostEntry} with a hostname of
- www.twistedmatrix.com and an RSA key of sampleKey.
- """
-
- def test_providesInterface(self):
- """
- The given entry should provide IKnownHostEntry.
- """
- verifyObject(IKnownHostEntry, self.entry)
-
-
- def test_fromString(self):
- """
- Constructing a plain text entry from an unhashed known_hosts entry will
- result in an L{IKnownHostEntry} provider with 'keyString', 'hostname',
- and 'keyType' attributes. While outside the interface in question,
- these attributes are held in common by L{PlainEntry} and L{HashedEntry}
- implementations; other implementations should override this method in
- subclasses.
- """
- entry = self.entry
- self.assertEqual(entry.publicKey, Key.fromString(sampleKey))
- self.assertEqual(entry.keyType, "ssh-rsa")
-
-
- def test_matchesKey(self):
- """
- L{IKnownHostEntry.matchesKey} checks to see if an entry matches a given
- SSH key.
- """
- twistedmatrixDotCom = Key.fromString(sampleKey)
- divmodDotCom = Key.fromString(otherSampleKey)
- self.assertEqual(
- True,
- self.entry.matchesKey(twistedmatrixDotCom))
- self.assertEqual(
- False,
- self.entry.matchesKey(divmodDotCom))
-
-
- def test_matchesHost(self):
- """
- L{IKnownHostEntry.matchesHost} checks to see if an entry matches a
- given hostname.
- """
- self.assertEqual(True, self.entry.matchesHost(
- "www.twistedmatrix.com"))
- self.assertEqual(False, self.entry.matchesHost(
- "www.divmod.com"))
-
-
-
-class PlainEntryTests(EntryTestsMixin, TestCase):
- """
- Test cases for L{PlainEntry}.
- """
- plaintextLine = samplePlaintextLine
- hostIPLine = sampleHostIPLine
-
- def setUp(self):
- """
- Set 'entry' to a sample plain-text entry with sampleKey as its key.
- """
- self.entry = PlainEntry.fromString(self.plaintextLine)
-
-
- def test_matchesHostIP(self):
- """
- A "hostname,ip" formatted line will match both the host and the IP.
- """
- self.entry = PlainEntry.fromString(self.hostIPLine)
- self.assertEqual(True, self.entry.matchesHost("198.49.126.131"))
- self.test_matchesHost()
-
-
- def test_toString(self):
- """
- L{PlainEntry.toString} generates the serialized OpenSSL format string
- for the entry, sans newline.
- """
- self.assertEqual(self.entry.toString(), self.plaintextLine.rstrip("\n"))
- multiHostEntry = PlainEntry.fromString(self.hostIPLine)
- self.assertEqual(multiHostEntry.toString(),
- self.hostIPLine.rstrip("\n"))
-
-
-
-class PlainTextWithCommentTests(PlainEntryTests):
- """
- Test cases for L{PlainEntry} when parsed from a line with a comment.
- """
-
- plaintextLine = samplePlaintextLine[:-1] + " plain text comment.\n"
- hostIPLine = sampleHostIPLine[:-1] + " text following host/IP line\n"
-
-
-
-class HashedEntryTests(EntryTestsMixin, TestCase):
- """
- Tests for L{HashedEntry}.
-
- This suite doesn't include any tests for host/IP pairs because hashed
- entries store IP addresses the same way as hostnames and does not support
- comma-separated lists. (If you hash the IP and host together you can't
- tell if you've got the key already for one or the other.)
- """
- hashedLine = sampleHashedLine
-
- def setUp(self):
- """
- Set 'entry' to a sample hashed entry for twistedmatrix.com with
- sampleKey as its key.
- """
- self.entry = HashedEntry.fromString(self.hashedLine)
-
-
- def test_toString(self):
- """
- L{HashedEntry.toString} generates the serialized OpenSSL format string
- for the entry, sans the newline.
- """
- self.assertEqual(self.entry.toString(), self.hashedLine.rstrip("\n"))
-
-
-
-class HashedEntryWithCommentTests(HashedEntryTests):
- """
- Test cases for L{PlainEntry} when parsed from a line with a comment.
- """
-
- hashedLine = sampleHashedLine[:-1] + " plain text comment.\n"
-
-
-
-class UnparsedEntryTests(TestCase, EntryTestsMixin):
- """
- Tests for L{UnparsedEntry}
- """
- def setUp(self):
- """
- Set up the 'entry' to be an unparsed entry for some random text.
- """
- self.entry = UnparsedEntry(" This is a bogus entry. \n")
-
-
- def test_fromString(self):
- """
- Creating an L{UnparsedEntry} should simply record the string it was
- passed.
- """
- self.assertEqual(" This is a bogus entry. \n",
- self.entry._string)
-
-
- def test_matchesHost(self):
- """
- An unparsed entry can't match any hosts.
- """
- self.assertEqual(False, self.entry.matchesHost("www.twistedmatrix.com"))
-
-
- def test_matchesKey(self):
- """
- An unparsed entry can't match any keys.
- """
- self.assertEqual(False, self.entry.matchesKey(Key.fromString(sampleKey)))
-
-
- def test_toString(self):
- """
- L{UnparsedEntry.toString} returns its input string, sans trailing
- newline.
- """
- self.assertEqual(" This is a bogus entry. ", self.entry.toString())
-
-
-
-class ParseErrorTests(TestCase):
- """
- L{HashedEntry.fromString} and L{PlainEntry.fromString} can raise a variety
- of errors depending on misformattings of certain strings. These tests make
- sure those errors are caught. Since many of the ways that this can go
- wrong are in the lower-level APIs being invoked by the parsing logic,
- several of these are integration tests with the C{base64} and
- L{twisted.conch.ssh.keys} modules.
- """
-
- def invalidEntryTest(self, cls):
- """
- If there are fewer than three elements, C{fromString} should raise
- L{InvalidEntry}.
- """
- self.assertRaises(InvalidEntry, cls.fromString, "invalid")
-
-
- def notBase64Test(self, cls):
- """
- If the key is not base64, C{fromString} should raise L{BinasciiError}.
- """
- self.assertRaises(BinasciiError, cls.fromString, "x x x")
-
-
- def badKeyTest(self, cls, prefix):
- """
- If the key portion of the entry is valid base64, but is not actually an
- SSH key, C{fromString} should raise L{BadKeyError}.
- """
- self.assertRaises(BadKeyError, cls.fromString, ' '.join(
- [prefix, "ssh-rsa", b2a_base64(
- "Hey, this isn't an SSH key!").strip()]))
-
-
- def test_invalidPlainEntry(self):
- """
- If there are fewer than three whitespace-separated elements in an
- entry, L{PlainEntry.fromString} should raise L{InvalidEntry}.
- """
- self.invalidEntryTest(PlainEntry)
-
-
- def test_invalidHashedEntry(self):
- """
- If there are fewer than three whitespace-separated elements in an
- entry, or the hostname salt/hash portion has more than two elements,
- L{HashedEntry.fromString} should raise L{InvalidEntry}.
- """
- self.invalidEntryTest(HashedEntry)
- a, b, c = sampleHashedLine.split()
- self.assertRaises(InvalidEntry, HashedEntry.fromString, ' '.join(
- [a + "||", b, c]))
-
-
- def test_plainNotBase64(self):
- """
- If the key portion of a plain entry is not decodable as base64,
- C{fromString} should raise L{BinasciiError}.
- """
- self.notBase64Test(PlainEntry)
-
-
- def test_hashedNotBase64(self):
- """
- If the key, host salt, or host hash portion of a hashed entry is not
- encoded, it will raise L{BinasciiError}.
- """
- self.notBase64Test(HashedEntry)
- a, b, c = sampleHashedLine.split()
- # Salt not valid base64.
- self.assertRaises(
- BinasciiError, HashedEntry.fromString,
- ' '.join(["|1|x|" + b2a_base64("stuff").strip(), b, c]))
- # Host hash not valid base64.
- self.assertRaises(
- BinasciiError, HashedEntry.fromString,
- ' '.join([HashedEntry.MAGIC + b2a_base64("stuff").strip() + "|x",
- b, c]))
- # Neither salt nor hash valid base64.
- self.assertRaises(
- BinasciiError, HashedEntry.fromString,
- ' '.join(["|1|x|x", b, c]))
-
-
- def test_hashedBadKey(self):
- """
- If the key portion of the entry is valid base64, but is not actually an
- SSH key, C{HashedEntry.fromString} should raise L{BadKeyError}.
- """
- a, b, c = sampleHashedLine.split()
- self.badKeyTest(HashedEntry, a)
-
-
- def test_plainBadKey(self):
- """
- If the key portion of the entry is valid base64, but is not actually an
- SSH key, C{PlainEntry.fromString} should raise L{BadKeyError}.
- """
- self.badKeyTest(PlainEntry, "hostname")
-
-
-
-class KnownHostsDatabaseTests(TestCase):
- """
- Tests for L{KnownHostsFile}.
- """
-
- def pathWithContent(self, content):
- """
- Return a FilePath with the given initial content.
- """
- fp = FilePath(self.mktemp())
- fp.setContent(content)
- return fp
-
-
- def loadSampleHostsFile(self, content=(
- sampleHashedLine + otherSamplePlaintextLine +
- "\n# That was a blank line.\n"
- "This is just unparseable.\n"
- "|1|This also unparseable.\n")):
- """
- Return a sample hosts file, with keys for www.twistedmatrix.com and
- divmod.com present.
- """
- return KnownHostsFile.fromPath(self.pathWithContent(content))
-
-
- def test_loadFromPath(self):
- """
- Loading a L{KnownHostsFile} from a path with six entries in it will
- result in a L{KnownHostsFile} object with six L{IKnownHostEntry}
- providers in it.
- """
- hostsFile = self.loadSampleHostsFile()
- self.assertEqual(len(hostsFile._entries), 6)
-
-
- def test_verifyHashedEntry(self):
- """
- Loading a L{KnownHostsFile} from a path containing a single valid
- L{HashedEntry} entry will result in a L{KnownHostsFile} object
- with one L{IKnownHostEntry} provider.
- """
- hostsFile = self.loadSampleHostsFile((sampleHashedLine))
- self.assertIsInstance(hostsFile._entries[0], HashedEntry)
- self.assertEqual(True, hostsFile._entries[0].matchesHost(
- "www.twistedmatrix.com"))
-
-
- def test_verifyPlainEntry(self):
- """
- Loading a L{KnownHostsFile} from a path containing a single valid
- L{PlainEntry} entry will result in a L{KnownHostsFile} object
- with one L{IKnownHostEntry} provider.
- """
- hostsFile = self.loadSampleHostsFile((otherSamplePlaintextLine))
- self.assertIsInstance(hostsFile._entries[0], PlainEntry)
- self.assertEqual(True, hostsFile._entries[0].matchesHost(
- "divmod.com"))
-
-
- def test_verifyUnparsedEntry(self):
- """
- Loading a L{KnownHostsFile} from a path that only contains '\n' will
- result in a L{KnownHostsFile} object containing a L{UnparsedEntry}
- object.
- """
- hostsFile = self.loadSampleHostsFile(("\n"))
- self.assertIsInstance(hostsFile._entries[0], UnparsedEntry)
- self.assertEqual(hostsFile._entries[0].toString(), "")
-
-
- def test_verifyUnparsedComment(self):
- """
- Loading a L{KnownHostsFile} from a path that contains a comment will
- result in a L{KnownHostsFile} object containing a L{UnparsedEntry}
- object.
- """
- hostsFile = self.loadSampleHostsFile(("# That was a blank line.\n"))
- self.assertIsInstance(hostsFile._entries[0], UnparsedEntry)
- self.assertEqual(hostsFile._entries[0].toString(),
- "# That was a blank line.")
-
-
- def test_verifyUnparsableLine(self):
- """
- Loading a L{KnownHostsFile} from a path that contains an unparseable
- line will be represented as an L{UnparsedEntry} instance.
- """
- hostsFile = self.loadSampleHostsFile(("This is just unparseable.\n"))
- self.assertIsInstance(hostsFile._entries[0], UnparsedEntry)
- self.assertEqual(hostsFile._entries[0].toString(),
- "This is just unparseable.")
-
-
- def test_verifyUnparsableEncryptionMarker(self):
- """
- Loading a L{KnownHostsFile} from a path containing an unparseable line
- that starts with an encryption marker will be represented as an
- L{UnparsedEntry} instance.
- """
- hostsFile = self.loadSampleHostsFile(("|1|This is unparseable.\n"))
- self.assertIsInstance(hostsFile._entries[0], UnparsedEntry)
- self.assertEqual(hostsFile._entries[0].toString(),
- "|1|This is unparseable.")
-
-
- def test_loadNonExistent(self):
- """
- Loading a L{KnownHostsFile} from a path that does not exist should
- result in an empty L{KnownHostsFile} that will save back to that path.
- """
- pn = self.mktemp()
- knownHostsFile = KnownHostsFile.fromPath(FilePath(pn))
- self.assertEqual([], list(knownHostsFile._entries))
- self.assertEqual(False, FilePath(pn).exists())
- knownHostsFile.save()
- self.assertEqual(True, FilePath(pn).exists())
-
-
- def test_loadNonExistentParent(self):
- """
- Loading a L{KnownHostsFile} from a path whose parent directory does not
- exist should result in an empty L{KnownHostsFile} that will save back
- to that path, creating its parent directory(ies) in the process.
- """
- thePath = FilePath(self.mktemp())
- knownHostsPath = thePath.child("foo").child("known_hosts")
- knownHostsFile = KnownHostsFile.fromPath(knownHostsPath)
- knownHostsFile.save()
- knownHostsPath.restat(False)
- self.assertEqual(True, knownHostsPath.exists())
-
-
- def test_savingAddsEntry(self):
- """
- L{KnownHostsFile.save()} will write out a new file with any entries
- that have been added.
- """
- path = self.pathWithContent(sampleHashedLine +
- otherSamplePlaintextLine)
- knownHostsFile = KnownHostsFile.fromPath(path)
- newEntry = knownHostsFile.addHostKey("some.example.com",
- Key.fromString(thirdSampleKey))
- expectedContent = (
- sampleHashedLine +
- otherSamplePlaintextLine + HashedEntry.MAGIC +
- b2a_base64(newEntry._hostSalt).strip() + "|" +
- b2a_base64(newEntry._hostHash).strip() + " ssh-rsa " +
- thirdSampleEncodedKey + "\n")
-
- # Sanity check, let's make sure the base64 API being used for the test
- # isn't inserting spurious newlines.
- self.assertEqual(3, expectedContent.count("\n"))
- knownHostsFile.save()
- self.assertEqual(expectedContent, path.getContent())
-
-
- def test_hasPresentKey(self):
- """
- L{KnownHostsFile.hasHostKey} returns C{True} when a key for the given
- hostname is present and matches the expected key.
- """
- hostsFile = self.loadSampleHostsFile()
- self.assertEqual(True, hostsFile.hasHostKey(
- "www.twistedmatrix.com", Key.fromString(sampleKey)))
-
-
- def test_hasNonPresentKey(self):
- """
- L{KnownHostsFile.hasHostKey} returns C{False} when a key for the given
- hostname is not present.
- """
- hostsFile = self.loadSampleHostsFile()
- self.assertEqual(False, hostsFile.hasHostKey(
- "non-existent.example.com", Key.fromString(sampleKey)))
-
-
- def test_hasKeyMismatch(self):
- """
- L{KnownHostsFile.hasHostKey} raises L{HostKeyChanged} if the host key
- is present, but different from the expected one. The resulting
- exception should have an C{offendingEntry} indicating the given entry.
- """
- hostsFile = self.loadSampleHostsFile()
- exception = self.assertRaises(
- HostKeyChanged, hostsFile.hasHostKey,
- "www.twistedmatrix.com", Key.fromString(otherSampleKey))
- self.assertEqual(exception.offendingEntry, hostsFile._entries[0])
- self.assertEqual(exception.lineno, 1)
- self.assertEqual(exception.path, hostsFile._savePath)
-
-
- def test_addHostKey(self):
- """
- L{KnownHostsFile.addHostKey} adds a new L{HashedEntry} to the host
- file, and returns it.
- """
- hostsFile = self.loadSampleHostsFile()
- aKey = Key.fromString(thirdSampleKey)
- self.assertEqual(False,
- hostsFile.hasHostKey("somewhere.example.com", aKey))
- newEntry = hostsFile.addHostKey("somewhere.example.com", aKey)
-
- # The code in OpenSSH requires host salts to be 20 characters long.
- # This is the required length of a SHA-1 HMAC hash, so it's just a
- # sanity check.
- self.assertEqual(20, len(newEntry._hostSalt))
- self.assertEqual(True,
- newEntry.matchesHost("somewhere.example.com"))
- self.assertEqual(newEntry.keyType, "ssh-rsa")
- self.assertEqual(aKey, newEntry.publicKey)
- self.assertEqual(True,
- hostsFile.hasHostKey("somewhere.example.com", aKey))
-
-
- def test_randomSalts(self):
- """
- L{KnownHostsFile.addHostKey} generates a random salt for each new key,
- so subsequent salts will be different.
- """
- hostsFile = self.loadSampleHostsFile()
- aKey = Key.fromString(thirdSampleKey)
- self.assertNotEqual(
- hostsFile.addHostKey("somewhere.example.com", aKey)._hostSalt,
- hostsFile.addHostKey("somewhere-else.example.com", aKey)._hostSalt)
-
-
- def test_verifyValidKey(self):
- """
- Verifying a valid key should return a L{Deferred} which fires with
- True.
- """
- hostsFile = self.loadSampleHostsFile()
- hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey))
- ui = FakeUI()
- d = hostsFile.verifyHostKey(ui, "www.twistedmatrix.com", "1.2.3.4",
- Key.fromString(sampleKey))
- l = []
- d.addCallback(l.append)
- self.assertEqual(l, [True])
-
-
- def test_verifyInvalidKey(self):
- """
- Verfying an invalid key should return a L{Deferred} which fires with a
- L{HostKeyChanged} failure.
- """
- hostsFile = self.loadSampleHostsFile()
- wrongKey = Key.fromString(thirdSampleKey)
- ui = FakeUI()
- hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey))
- d = hostsFile.verifyHostKey(
- ui, "www.twistedmatrix.com", "1.2.3.4", wrongKey)
- return self.assertFailure(d, HostKeyChanged)
-
-
- def verifyNonPresentKey(self):
- """
- Set up a test to verify a key that isn't present. Return a 3-tuple of
- the UI, a list set up to collect the result of the verifyHostKey call,
- and the sample L{KnownHostsFile} being used.
-
- This utility method avoids returning a L{Deferred}, and records results
- in the returned list instead, because the events which get generated
- here are pre-recorded in the 'ui' object. If the L{Deferred} in
- question does not fire, the it will fail quickly with an empty list.
- """
- hostsFile = self.loadSampleHostsFile()
- absentKey = Key.fromString(thirdSampleKey)
- ui = FakeUI()
- l = []
- d = hostsFile.verifyHostKey(
- ui, "sample-host.example.com", "4.3.2.1", absentKey)
- d.addBoth(l.append)
- self.assertEqual([], l)
- self.assertEqual(
- ui.promptText,
- "The authenticity of host 'sample-host.example.com (4.3.2.1)' "
- "can't be established.\n"
- "RSA key fingerprint is "
- "89:4e:cc:8c:57:83:96:48:ef:63:ad:ee:99:00:4c:8f.\n"
- "Are you sure you want to continue connecting (yes/no)? ")
- return ui, l, hostsFile
-
-
- def test_verifyNonPresentKey_Yes(self):
- """
- Verifying a key where neither the hostname nor the IP are present
- should result in the UI being prompted with a message explaining as
- much. If the UI says yes, the Deferred should fire with True.
- """
- ui, l, knownHostsFile = self.verifyNonPresentKey()
- ui.promptDeferred.callback(True)
- self.assertEqual([True], l)
- reloaded = KnownHostsFile.fromPath(knownHostsFile._savePath)
- self.assertEqual(
- True,
- reloaded.hasHostKey("4.3.2.1", Key.fromString(thirdSampleKey)))
- self.assertEqual(
- True,
- reloaded.hasHostKey("sample-host.example.com",
- Key.fromString(thirdSampleKey)))
-
-
- def test_verifyNonPresentKey_No(self):
- """
- Verifying a key where neither the hostname nor the IP are present
- should result in the UI being prompted with a message explaining as
- much. If the UI says no, the Deferred should fail with
- UserRejectedKey.
- """
- ui, l, knownHostsFile = self.verifyNonPresentKey()
- ui.promptDeferred.callback(False)
- l[0].trap(UserRejectedKey)
-
-
- def test_verifyHostIPMismatch(self):
- """
- Verifying a key where the host is present (and correct), but the IP is
- present and different, should result the deferred firing in a
- HostKeyChanged failure.
- """
- hostsFile = self.loadSampleHostsFile()
- wrongKey = Key.fromString(thirdSampleKey)
- ui = FakeUI()
- d = hostsFile.verifyHostKey(
- ui, "www.twistedmatrix.com", "4.3.2.1", wrongKey)
- return self.assertFailure(d, HostKeyChanged)
-
-
- def test_verifyKeyForHostAndIP(self):
- """
- Verifying a key where the hostname is present but the IP is not should
- result in the key being added for the IP and the user being warned
- about the change.
- """
- ui = FakeUI()
- hostsFile = self.loadSampleHostsFile()
- expectedKey = Key.fromString(sampleKey)
- hostsFile.verifyHostKey(
- ui, "www.twistedmatrix.com", "5.4.3.2", expectedKey)
- self.assertEqual(
- True, KnownHostsFile.fromPath(hostsFile._savePath).hasHostKey(
- "5.4.3.2", expectedKey))
- self.assertEqual(
- ["Warning: Permanently added the RSA host key for IP address "
- "'5.4.3.2' to the list of known hosts."],
- ui.userWarnings)
-
-
-class FakeFile(object):
- """
- A fake file-like object that acts enough like a file for
- L{ConsoleUI.prompt}.
- """
-
- def __init__(self):
- self.inlines = []
- self.outchunks = []
- self.closed = False
-
-
- def readline(self):
- """
- Return a line from the 'inlines' list.
- """
- return self.inlines.pop(0)
-
-
- def write(self, chunk):
- """
- Append the given item to the 'outchunks' list.
- """
- if self.closed:
- raise IOError("the file was closed")
- self.outchunks.append(chunk)
-
-
- def close(self):
- """
- Set the 'closed' flag to True, explicitly marking that it has been
- closed.
- """
- self.closed = True
-
-
-
-class ConsoleUITests(TestCase):
- """
- Test cases for L{ConsoleUI}.
- """
-
- def setUp(self):
- """
- Create a L{ConsoleUI} pointed at a L{FakeFile}.
- """
- self.fakeFile = FakeFile()
- self.ui = ConsoleUI(self.openFile)
-
-
- def openFile(self):
- """
- Return the current fake file.
- """
- return self.fakeFile
-
-
- def newFile(self, lines):
- """
- Create a new fake file (the next file that self.ui will open) with the
- given list of lines to be returned from readline().
- """
- self.fakeFile = FakeFile()
- self.fakeFile.inlines = lines
-
-
- def test_promptYes(self):
- """
- L{ConsoleUI.prompt} writes a message to the console, then reads a line.
- If that line is 'yes', then it returns a L{Deferred} that fires with
- True.
- """
- for okYes in ['yes', 'Yes', 'yes\n']:
- self.newFile([okYes])
- l = []
- self.ui.prompt("Hello, world!").addCallback(l.append)
- self.assertEqual(["Hello, world!"], self.fakeFile.outchunks)
- self.assertEqual([True], l)
- self.assertEqual(True, self.fakeFile.closed)
-
-
- def test_promptNo(self):
- """
- L{ConsoleUI.prompt} writes a message to the console, then reads a line.
- If that line is 'no', then it returns a L{Deferred} that fires with
- False.
- """
- for okNo in ['no', 'No', 'no\n']:
- self.newFile([okNo])
- l = []
- self.ui.prompt("Goodbye, world!").addCallback(l.append)
- self.assertEqual(["Goodbye, world!"], self.fakeFile.outchunks)
- self.assertEqual([False], l)
- self.assertEqual(True, self.fakeFile.closed)
-
-
- def test_promptRepeatedly(self):
- """
- L{ConsoleUI.prompt} writes a message to the console, then reads a line.
- If that line is neither 'yes' nor 'no', then it says "Please enter
- 'yes' or 'no'" until it gets a 'yes' or a 'no', at which point it
- returns a Deferred that answers either True or False.
- """
- self.newFile(['what', 'uh', 'okay', 'yes'])
- l = []
- self.ui.prompt("Please say something useful.").addCallback(l.append)
- self.assertEqual([True], l)
- self.assertEqual(self.fakeFile.outchunks,
- ["Please say something useful."] +
- ["Please type 'yes' or 'no': "] * 3)
- self.assertEqual(True, self.fakeFile.closed)
- self.newFile(['blah', 'stuff', 'feh', 'no'])
- l = []
- self.ui.prompt("Please say something negative.").addCallback(l.append)
- self.assertEqual([False], l)
- self.assertEqual(self.fakeFile.outchunks,
- ["Please say something negative."] +
- ["Please type 'yes' or 'no': "] * 3)
- self.assertEqual(True, self.fakeFile.closed)
-
-
- def test_promptOpenFailed(self):
- """
- If the C{opener} passed to L{ConsoleUI} raises an exception, that
- exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}.
- """
- def raiseIt():
- raise IOError()
- ui = ConsoleUI(raiseIt)
- d = ui.prompt("This is a test.")
- return self.assertFailure(d, IOError)
-
-
- def test_warn(self):
- """
- L{ConsoleUI.warn} should output a message to the console object.
- """
- self.ui.warn("Test message.")
- self.assertEqual(["Test message."], self.fakeFile.outchunks)
- self.assertEqual(True, self.fakeFile.closed)
-
-
- def test_warnOpenFailed(self):
- """
- L{ConsoleUI.warn} should log a traceback if the output can't be opened.
- """
- def raiseIt():
- 1 / 0
- ui = ConsoleUI(raiseIt)
- ui.warn("This message never makes it.")
- self.assertEqual(len(self.flushLoggedErrors(ZeroDivisionError)), 1)
-
-
-
-class FakeUI(object):
- """
- A fake UI object, adhering to the interface expected by
- L{KnownHostsFile.verifyHostKey}
-
- @ivar userWarnings: inputs provided to 'warn'.
-
- @ivar promptDeferred: last result returned from 'prompt'.
-
- @ivar promptText: the last input provided to 'prompt'.
- """
-
- def __init__(self):
- self.userWarnings = []
- self.promptDeferred = None
- self.promptText = None
-
-
- def prompt(self, text):
- """
- Issue the user an interactive prompt, which they can accept or deny.
- """
- self.promptText = text
- self.promptDeferred = Deferred()
- return self.promptDeferred
-
-
- def warn(self, text):
- """
- Issue a non-interactive warning to the user.
- """
- self.userWarnings.append(text)
-
-
-
-class FakeObject(object):
- """
- A fake object that can have some attributes. Used to fake
- L{SSHClientTransport} and L{SSHClientFactory}.
- """
-
-
-class DefaultAPITests(TestCase):
- """
- The API in L{twisted.conch.client.default.verifyHostKey} is the integration
- point between the code in the rest of conch and L{KnownHostsFile}.
- """
-
- def patchedOpen(self, fname, mode):
- """
- The patched version of 'open'; this returns a L{FakeFile} that the
- instantiated L{ConsoleUI} can use.
- """
- self.assertEqual(fname, "/dev/tty")
- self.assertEqual(mode, "r+b")
- return self.fakeFile
-
-
- def setUp(self):
- """
- Patch 'open' in verifyHostKey.
- """
- self.fakeFile = FakeFile()
- self.patch(default, "_open", self.patchedOpen)
- self.hostsOption = self.mktemp()
- knownHostsFile = KnownHostsFile(FilePath(self.hostsOption))
- knownHostsFile.addHostKey("exists.example.com",
- Key.fromString(sampleKey))
- knownHostsFile.addHostKey("4.3.2.1", Key.fromString(sampleKey))
- knownHostsFile.save()
- self.fakeTransport = FakeObject()
- self.fakeTransport.factory = FakeObject()
- self.options = self.fakeTransport.factory.options = {
- 'host': "exists.example.com",
- 'known-hosts': self.hostsOption
- }
-
-
- def test_verifyOKKey(self):
- """
- L{default.verifyHostKey} should return a L{Deferred} which fires with
- C{1} when passed a host, IP, and key which already match the
- known_hosts file it is supposed to check.
- """
- l = []
- default.verifyHostKey(self.fakeTransport, "4.3.2.1", sampleKey,
- "I don't care.").addCallback(l.append)
- self.assertEqual([1], l)
-
-
- def replaceHome(self, tempHome):
- """
- Replace the HOME environment variable until the end of the current
- test, with the given new home-directory, so that L{os.path.expanduser}
- will yield controllable, predictable results.
-
- @param tempHome: the pathname to replace the HOME variable with.
-
- @type tempHome: L{str}
- """
- oldHome = os.environ.get('HOME')
- def cleanupHome():
- if oldHome is None:
- del os.environ['HOME']
- else:
- os.environ['HOME'] = oldHome
- self.addCleanup(cleanupHome)
- os.environ['HOME'] = tempHome
-
-
- def test_noKnownHostsOption(self):
- """
- L{default.verifyHostKey} should find your known_hosts file in
- ~/.ssh/known_hosts if you don't specify one explicitly on the command
- line.
- """
- l = []
- tmpdir = self.mktemp()
- oldHostsOption = self.hostsOption
- hostsNonOption = FilePath(tmpdir).child(".ssh").child("known_hosts")
- hostsNonOption.parent().makedirs()
- FilePath(oldHostsOption).moveTo(hostsNonOption)
- self.replaceHome(tmpdir)
- self.options['known-hosts'] = None
- default.verifyHostKey(self.fakeTransport, "4.3.2.1", sampleKey,
- "I don't care.").addCallback(l.append)
- self.assertEqual([1], l)
-
-
- def test_verifyHostButNotIP(self):
- """
- L{default.verifyHostKey} should return a L{Deferred} which fires with
- C{1} when passed a host which matches with an IP is not present in its
- known_hosts file, and should also warn the user that it has added the
- IP address.
- """
- l = []
- default.verifyHostKey(self.fakeTransport, "8.7.6.5", sampleKey,
- "Fingerprint not required.").addCallback(l.append)
- self.assertEqual(
- ["Warning: Permanently added the RSA host key for IP address "
- "'8.7.6.5' to the list of known hosts."],
- self.fakeFile.outchunks)
- self.assertEqual([1], l)
- knownHostsFile = KnownHostsFile.fromPath(FilePath(self.hostsOption))
- self.assertEqual(True, knownHostsFile.hasHostKey("8.7.6.5",
- Key.fromString(sampleKey)))
-
-
- def test_verifyQuestion(self):
- """
- L{default.verifyHostKey} should return a L{Default} which fires with
- C{0} when passed a unknown host that the user refuses to acknowledge.
- """
- self.fakeTransport.factory.options['host'] = 'fake.example.com'
- self.fakeFile.inlines.append("no")
- d = default.verifyHostKey(
- self.fakeTransport, "9.8.7.6", otherSampleKey, "No fingerprint!")
- self.assertEqual(
- ["The authenticity of host 'fake.example.com (9.8.7.6)' "
- "can't be established.\n"
- "RSA key fingerprint is "
- "57:a1:c2:a1:07:a0:2b:f4:ce:b5:e5:b7:ae:cc:e1:99.\n"
- "Are you sure you want to continue connecting (yes/no)? "],
- self.fakeFile.outchunks)
- return self.assertFailure(d, UserRejectedKey)
-
-
- def test_verifyBadKey(self):
- """
- L{default.verifyHostKey} should return a L{Deferred} which fails with
- L{HostKeyChanged} if the host key is incorrect.
- """
- d = default.verifyHostKey(
- self.fakeTransport, "4.3.2.1", otherSampleKey,
- "Again, not required.")
- return self.assertFailure(d, HostKeyChanged)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py
deleted file mode 100755
index 09dd52c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_manhole -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.manhole}.
-"""
-
-import traceback
-
-from twisted.trial import unittest
-from twisted.internet import error, defer
-from twisted.test.proto_helpers import StringTransport
-from twisted.conch.test.test_recvline import _TelnetMixin, _SSHMixin, _StdioMixin, stdio, ssh
-from twisted.conch import manhole
-from twisted.conch.insults import insults
-
-
-def determineDefaultFunctionName():
- """
- Return the string used by Python as the name for code objects which are
- compiled from interactive input or at the top-level of modules.
- """
- try:
- 1 // 0
- except:
- # The last frame is this function. The second to last frame is this
- # function's caller, which is module-scope, which is what we want,
- # so -2.
- return traceback.extract_stack()[-2][2]
-defaultFunctionName = determineDefaultFunctionName()
-
-
-
-class ManholeInterpreterTests(unittest.TestCase):
- """
- Tests for L{manhole.ManholeInterpreter}.
- """
- def test_resetBuffer(self):
- """
- L{ManholeInterpreter.resetBuffer} should empty the input buffer.
- """
- interpreter = manhole.ManholeInterpreter(None)
- interpreter.buffer.extend(["1", "2"])
- interpreter.resetBuffer()
- self.assertFalse(interpreter.buffer)
-
-
-
-class ManholeProtocolTests(unittest.TestCase):
- """
- Tests for L{manhole.Manhole}.
- """
- def test_interruptResetsInterpreterBuffer(self):
- """
- L{manhole.Manhole.handle_INT} should cause the interpreter input buffer
- to be reset.
- """
- transport = StringTransport()
- terminal = insults.ServerProtocol(manhole.Manhole)
- terminal.makeConnection(transport)
- protocol = terminal.terminalProtocol
- interpreter = protocol.interpreter
- interpreter.buffer.extend(["1", "2"])
- protocol.handle_INT()
- self.assertFalse(interpreter.buffer)
-
-
-
-class WriterTestCase(unittest.TestCase):
- def testInteger(self):
- manhole.lastColorizedLine("1")
-
-
- def testDoubleQuoteString(self):
- manhole.lastColorizedLine('"1"')
-
-
- def testSingleQuoteString(self):
- manhole.lastColorizedLine("'1'")
-
-
- def testTripleSingleQuotedString(self):
- manhole.lastColorizedLine("'''1'''")
-
-
- def testTripleDoubleQuotedString(self):
- manhole.lastColorizedLine('"""1"""')
-
-
- def testFunctionDefinition(self):
- manhole.lastColorizedLine("def foo():")
-
-
- def testClassDefinition(self):
- manhole.lastColorizedLine("class foo:")
-
-
-class ManholeLoopbackMixin:
- serverProtocol = manhole.ColoredManhole
-
- def wfd(self, d):
- return defer.waitForDeferred(d)
-
- def testSimpleExpression(self):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(
- "1 + 1\n"
- "done")
-
- def finished(ign):
- self._assertBuffer(
- [">>> 1 + 1",
- "2",
- ">>> done"])
-
- return done.addCallback(finished)
-
- def testTripleQuoteLineContinuation(self):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(
- "'''\n'''\n"
- "done")
-
- def finished(ign):
- self._assertBuffer(
- [">>> '''",
- "... '''",
- "'\\n'",
- ">>> done"])
-
- return done.addCallback(finished)
-
- def testFunctionDefinition(self):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(
- "def foo(bar):\n"
- "\tprint bar\n\n"
- "foo(42)\n"
- "done")
-
- def finished(ign):
- self._assertBuffer(
- [">>> def foo(bar):",
- "... print bar",
- "... ",
- ">>> foo(42)",
- "42",
- ">>> done"])
-
- return done.addCallback(finished)
-
- def testClassDefinition(self):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(
- "class Foo:\n"
- "\tdef bar(self):\n"
- "\t\tprint 'Hello, world!'\n\n"
- "Foo().bar()\n"
- "done")
-
- def finished(ign):
- self._assertBuffer(
- [">>> class Foo:",
- "... def bar(self):",
- "... print 'Hello, world!'",
- "... ",
- ">>> Foo().bar()",
- "Hello, world!",
- ">>> done"])
-
- return done.addCallback(finished)
-
- def testException(self):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(
- "raise Exception('foo bar baz')\n"
- "done")
-
- def finished(ign):
- self._assertBuffer(
- [">>> raise Exception('foo bar baz')",
- "Traceback (most recent call last):",
- ' File "<console>", line 1, in ' + defaultFunctionName,
- "Exception: foo bar baz",
- ">>> done"])
-
- return done.addCallback(finished)
-
- def testControlC(self):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(
- "cancelled line" + manhole.CTRL_C +
- "done")
-
- def finished(ign):
- self._assertBuffer(
- [">>> cancelled line",
- "KeyboardInterrupt",
- ">>> done"])
-
- return done.addCallback(finished)
-
-
- def test_interruptDuringContinuation(self):
- """
- Sending ^C to Manhole while in a state where more input is required to
- complete a statement should discard the entire ongoing statement and
- reset the input prompt to the non-continuation prompt.
- """
- continuing = self.recvlineClient.expect("things")
-
- self._testwrite("(\nthings")
-
- def gotContinuation(ignored):
- self._assertBuffer(
- [">>> (",
- "... things"])
- interrupted = self.recvlineClient.expect(">>> ")
- self._testwrite(manhole.CTRL_C)
- return interrupted
- continuing.addCallback(gotContinuation)
-
- def gotInterruption(ignored):
- self._assertBuffer(
- [">>> (",
- "... things",
- "KeyboardInterrupt",
- ">>> "])
- continuing.addCallback(gotInterruption)
- return continuing
-
-
- def testControlBackslash(self):
- self._testwrite("cancelled line")
- partialLine = self.recvlineClient.expect("cancelled line")
-
- def gotPartialLine(ign):
- self._assertBuffer(
- [">>> cancelled line"])
- self._testwrite(manhole.CTRL_BACKSLASH)
-
- d = self.recvlineClient.onDisconnection
- return self.assertFailure(d, error.ConnectionDone)
-
- def gotClearedLine(ign):
- self._assertBuffer(
- [""])
-
- return partialLine.addCallback(gotPartialLine).addCallback(gotClearedLine)
-
- def testControlD(self):
- self._testwrite("1 + 1")
- helloWorld = self.wfd(self.recvlineClient.expect(r"\+ 1"))
- yield helloWorld
- helloWorld.getResult()
- self._assertBuffer([">>> 1 + 1"])
-
- self._testwrite(manhole.CTRL_D + " + 1")
- cleared = self.wfd(self.recvlineClient.expect(r"\+ 1"))
- yield cleared
- cleared.getResult()
- self._assertBuffer([">>> 1 + 1 + 1"])
-
- self._testwrite("\n")
- printed = self.wfd(self.recvlineClient.expect("3\n>>> "))
- yield printed
- printed.getResult()
-
- self._testwrite(manhole.CTRL_D)
- d = self.recvlineClient.onDisconnection
- disconnected = self.wfd(self.assertFailure(d, error.ConnectionDone))
- yield disconnected
- disconnected.getResult()
- testControlD = defer.deferredGenerator(testControlD)
-
-
- def testControlL(self):
- """
- CTRL+L is generally used as a redraw-screen command in terminal
- applications. Manhole doesn't currently respect this usage of it,
- but it should at least do something reasonable in response to this
- event (rather than, say, eating your face).
- """
- # Start off with a newline so that when we clear the display we can
- # tell by looking for the missing first empty prompt line.
- self._testwrite("\n1 + 1")
- helloWorld = self.wfd(self.recvlineClient.expect(r"\+ 1"))
- yield helloWorld
- helloWorld.getResult()
- self._assertBuffer([">>> ", ">>> 1 + 1"])
-
- self._testwrite(manhole.CTRL_L + " + 1")
- redrew = self.wfd(self.recvlineClient.expect(r"1 \+ 1 \+ 1"))
- yield redrew
- redrew.getResult()
- self._assertBuffer([">>> 1 + 1 + 1"])
- testControlL = defer.deferredGenerator(testControlL)
-
-
- def test_controlA(self):
- """
- CTRL-A can be used as HOME - returning cursor to beginning of
- current line buffer.
- """
- self._testwrite('rint "hello"' + '\x01' + 'p')
- d = self.recvlineClient.expect('print "hello"')
- def cb(ignore):
- self._assertBuffer(['>>> print "hello"'])
- return d.addCallback(cb)
-
-
- def test_controlE(self):
- """
- CTRL-E can be used as END - setting cursor to end of current
- line buffer.
- """
- self._testwrite('rint "hello' + '\x01' + 'p' + '\x05' + '"')
- d = self.recvlineClient.expect('print "hello"')
- def cb(ignore):
- self._assertBuffer(['>>> print "hello"'])
- return d.addCallback(cb)
-
-
- def testDeferred(self):
- self._testwrite(
- "from twisted.internet import defer, reactor\n"
- "d = defer.Deferred()\n"
- "d\n")
-
- deferred = self.wfd(self.recvlineClient.expect("<Deferred #0>"))
- yield deferred
- deferred.getResult()
-
- self._testwrite(
- "c = reactor.callLater(0.1, d.callback, 'Hi!')\n")
- delayed = self.wfd(self.recvlineClient.expect(">>> "))
- yield delayed
- delayed.getResult()
-
- called = self.wfd(self.recvlineClient.expect("Deferred #0 called back: 'Hi!'\n>>> "))
- yield called
- called.getResult()
- self._assertBuffer(
- [">>> from twisted.internet import defer, reactor",
- ">>> d = defer.Deferred()",
- ">>> d",
- "<Deferred #0>",
- ">>> c = reactor.callLater(0.1, d.callback, 'Hi!')",
- "Deferred #0 called back: 'Hi!'",
- ">>> "])
-
- testDeferred = defer.deferredGenerator(testDeferred)
-
-class ManholeLoopbackTelnet(_TelnetMixin, unittest.TestCase, ManholeLoopbackMixin):
- pass
-
-class ManholeLoopbackSSH(_SSHMixin, unittest.TestCase, ManholeLoopbackMixin):
- if ssh is None:
- skip = "Crypto requirements missing, can't run manhole tests over ssh"
-
-class ManholeLoopbackStdio(_StdioMixin, unittest.TestCase, ManholeLoopbackMixin):
- if stdio is None:
- skip = "Terminal requirements missing, can't run manhole tests over stdio"
- else:
- serverProtocol = stdio.ConsoleManhole
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py
deleted file mode 100755
index 74d60eaa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- twisted.conch.test.test_mixin -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import time
-
-from twisted.internet import reactor, protocol
-
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport
-
-from twisted.conch import mixin
-
-
-class TestBufferingProto(mixin.BufferingMixin):
- scheduled = False
- rescheduled = 0
- def schedule(self):
- self.scheduled = True
- return object()
-
- def reschedule(self, token):
- self.rescheduled += 1
-
-
-
-class BufferingTest(unittest.TestCase):
- def testBuffering(self):
- p = TestBufferingProto()
- t = p.transport = StringTransport()
-
- self.failIf(p.scheduled)
-
- L = ['foo', 'bar', 'baz', 'quux']
-
- p.write('foo')
- self.failUnless(p.scheduled)
- self.failIf(p.rescheduled)
-
- for s in L:
- n = p.rescheduled
- p.write(s)
- self.assertEqual(p.rescheduled, n + 1)
- self.assertEqual(t.value(), '')
-
- p.flush()
- self.assertEqual(t.value(), 'foo' + ''.join(L))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py
deleted file mode 100755
index 8b4e1a6f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.openssh_compat}.
-"""
-
-import os
-
-from twisted.trial.unittest import TestCase
-from twisted.python.filepath import FilePath
-from twisted.python.compat import set
-
-try:
- import Crypto.Cipher.DES3
- import pyasn1
-except ImportError:
- OpenSSHFactory = None
-else:
- from twisted.conch.openssh_compat.factory import OpenSSHFactory
-
-from twisted.conch.test import keydata
-from twisted.test.test_process import MockOS
-
-
-class OpenSSHFactoryTests(TestCase):
- """
- Tests for L{OpenSSHFactory}.
- """
- if getattr(os, "geteuid", None) is None:
- skip = "geteuid/seteuid not available"
- elif OpenSSHFactory is None:
- skip = "Cannot run without PyCrypto or PyASN1"
-
- def setUp(self):
- self.factory = OpenSSHFactory()
- self.keysDir = FilePath(self.mktemp())
- self.keysDir.makedirs()
- self.factory.dataRoot = self.keysDir.path
-
- self.keysDir.child("ssh_host_foo").setContent("foo")
- self.keysDir.child("bar_key").setContent("foo")
- self.keysDir.child("ssh_host_one_key").setContent(
- keydata.privateRSA_openssh)
- self.keysDir.child("ssh_host_two_key").setContent(
- keydata.privateDSA_openssh)
- self.keysDir.child("ssh_host_three_key").setContent(
- "not a key content")
-
- self.keysDir.child("ssh_host_one_key.pub").setContent(
- keydata.publicRSA_openssh)
-
- self.mockos = MockOS()
- self.patch(os, "seteuid", self.mockos.seteuid)
- self.patch(os, "setegid", self.mockos.setegid)
-
-
- def test_getPublicKeys(self):
- """
- L{OpenSSHFactory.getPublicKeys} should return the available public keys
- in the data directory
- """
- keys = self.factory.getPublicKeys()
- self.assertEqual(len(keys), 1)
- keyTypes = keys.keys()
- self.assertEqual(keyTypes, ['ssh-rsa'])
-
-
- def test_getPrivateKeys(self):
- """
- L{OpenSSHFactory.getPrivateKeys} should return the available private
- keys in the data directory.
- """
- keys = self.factory.getPrivateKeys()
- self.assertEqual(len(keys), 2)
- keyTypes = keys.keys()
- self.assertEqual(set(keyTypes), set(['ssh-rsa', 'ssh-dss']))
- self.assertEqual(self.mockos.seteuidCalls, [])
- self.assertEqual(self.mockos.setegidCalls, [])
-
-
- def test_getPrivateKeysAsRoot(self):
- """
- L{OpenSSHFactory.getPrivateKeys} should switch to root if the keys
- aren't readable by the current user.
- """
- keyFile = self.keysDir.child("ssh_host_two_key")
- # Fake permission error by changing the mode
- keyFile.chmod(0000)
- self.addCleanup(keyFile.chmod, 0777)
- # And restore the right mode when seteuid is called
- savedSeteuid = os.seteuid
- def seteuid(euid):
- keyFile.chmod(0777)
- return savedSeteuid(euid)
- self.patch(os, "seteuid", seteuid)
- keys = self.factory.getPrivateKeys()
- self.assertEqual(len(keys), 2)
- keyTypes = keys.keys()
- self.assertEqual(set(keyTypes), set(['ssh-rsa', 'ssh-dss']))
- self.assertEqual(self.mockos.seteuidCalls, [0, os.geteuid()])
- self.assertEqual(self.mockos.setegidCalls, [0, os.getegid()])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py
deleted file mode 100755
index 3d535646..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py
+++ /dev/null
@@ -1,706 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_recvline -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.recvline} and fixtures for testing related
-functionality.
-"""
-
-import sys, os
-
-from twisted.conch.insults import insults
-from twisted.conch import recvline
-
-from twisted.python import reflect, components
-from twisted.internet import defer, error
-from twisted.trial import unittest
-from twisted.cred import portal
-from twisted.test.proto_helpers import StringTransport
-
-class Arrows(unittest.TestCase):
- def setUp(self):
- self.underlyingTransport = StringTransport()
- self.pt = insults.ServerProtocol()
- self.p = recvline.HistoricRecvLine()
- self.pt.protocolFactory = lambda: self.p
- self.pt.factory = self
- self.pt.makeConnection(self.underlyingTransport)
- # self.p.makeConnection(self.pt)
-
- def test_printableCharacters(self):
- """
- When L{HistoricRecvLine} receives a printable character,
- it adds it to the current line buffer.
- """
- self.p.keystrokeReceived('x', None)
- self.p.keystrokeReceived('y', None)
- self.p.keystrokeReceived('z', None)
-
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- def test_horizontalArrows(self):
- """
- When L{HistoricRecvLine} receives an LEFT_ARROW or
- RIGHT_ARROW keystroke it moves the cursor left or right
- in the current line buffer, respectively.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
- for ch in 'xyz':
- kR(ch)
-
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.RIGHT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.LEFT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('xy', 'z'))
-
- kR(self.pt.LEFT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('x', 'yz'))
-
- kR(self.pt.LEFT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('', 'xyz'))
-
- kR(self.pt.LEFT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('', 'xyz'))
-
- kR(self.pt.RIGHT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('x', 'yz'))
-
- kR(self.pt.RIGHT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('xy', 'z'))
-
- kR(self.pt.RIGHT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.RIGHT_ARROW)
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- def test_newline(self):
- """
- When {HistoricRecvLine} receives a newline, it adds the current
- line buffer to the end of its history buffer.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'xyz\nabc\n123\n':
- kR(ch)
-
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz', 'abc', '123'), ()))
-
- kR('c')
- kR('b')
- kR('a')
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz', 'abc', '123'), ()))
-
- kR('\n')
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz', 'abc', '123', 'cba'), ()))
-
- def test_verticalArrows(self):
- """
- When L{HistoricRecvLine} receives UP_ARROW or DOWN_ARROW
- keystrokes it move the current index in the current history
- buffer up or down, and resets the current line buffer to the
- previous or next line in history, respectively for each.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'xyz\nabc\n123\n':
- kR(ch)
-
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz', 'abc', '123'), ()))
- self.assertEqual(self.p.currentLineBuffer(), ('', ''))
-
- kR(self.pt.UP_ARROW)
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz', 'abc'), ('123',)))
- self.assertEqual(self.p.currentLineBuffer(), ('123', ''))
-
- kR(self.pt.UP_ARROW)
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz',), ('abc', '123')))
- self.assertEqual(self.p.currentLineBuffer(), ('abc', ''))
-
- kR(self.pt.UP_ARROW)
- self.assertEqual(self.p.currentHistoryBuffer(),
- ((), ('xyz', 'abc', '123')))
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.UP_ARROW)
- self.assertEqual(self.p.currentHistoryBuffer(),
- ((), ('xyz', 'abc', '123')))
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- for i in range(4):
- kR(self.pt.DOWN_ARROW)
- self.assertEqual(self.p.currentHistoryBuffer(),
- (('xyz', 'abc', '123'), ()))
-
- def test_home(self):
- """
- When L{HistoricRecvLine} receives a HOME keystroke it moves the
- cursor to the beginning of the current line buffer.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'hello, world':
- kR(ch)
- self.assertEqual(self.p.currentLineBuffer(), ('hello, world', ''))
-
- kR(self.pt.HOME)
- self.assertEqual(self.p.currentLineBuffer(), ('', 'hello, world'))
-
- def test_end(self):
- """
- When L{HistoricRecvLine} receives a END keystroke it moves the cursor
- to the end of the current line buffer.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'hello, world':
- kR(ch)
- self.assertEqual(self.p.currentLineBuffer(), ('hello, world', ''))
-
- kR(self.pt.HOME)
- kR(self.pt.END)
- self.assertEqual(self.p.currentLineBuffer(), ('hello, world', ''))
-
- def test_backspace(self):
- """
- When L{HistoricRecvLine} receives a BACKSPACE keystroke it deletes
- the character immediately before the cursor.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'xyz':
- kR(ch)
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.BACKSPACE)
- self.assertEqual(self.p.currentLineBuffer(), ('xy', ''))
-
- kR(self.pt.LEFT_ARROW)
- kR(self.pt.BACKSPACE)
- self.assertEqual(self.p.currentLineBuffer(), ('', 'y'))
-
- kR(self.pt.BACKSPACE)
- self.assertEqual(self.p.currentLineBuffer(), ('', 'y'))
-
- def test_delete(self):
- """
- When L{HistoricRecvLine} receives a DELETE keystroke, it
- delets the character immediately after the cursor.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'xyz':
- kR(ch)
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.DELETE)
- self.assertEqual(self.p.currentLineBuffer(), ('xyz', ''))
-
- kR(self.pt.LEFT_ARROW)
- kR(self.pt.DELETE)
- self.assertEqual(self.p.currentLineBuffer(), ('xy', ''))
-
- kR(self.pt.LEFT_ARROW)
- kR(self.pt.DELETE)
- self.assertEqual(self.p.currentLineBuffer(), ('x', ''))
-
- kR(self.pt.LEFT_ARROW)
- kR(self.pt.DELETE)
- self.assertEqual(self.p.currentLineBuffer(), ('', ''))
-
- kR(self.pt.DELETE)
- self.assertEqual(self.p.currentLineBuffer(), ('', ''))
-
- def test_insert(self):
- """
- When not in INSERT mode, L{HistoricRecvLine} inserts the typed
- character at the cursor before the next character.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'xyz':
- kR(ch)
-
- kR(self.pt.LEFT_ARROW)
- kR('A')
- self.assertEqual(self.p.currentLineBuffer(), ('xyA', 'z'))
-
- kR(self.pt.LEFT_ARROW)
- kR('B')
- self.assertEqual(self.p.currentLineBuffer(), ('xyB', 'Az'))
-
- def test_typeover(self):
- """
- When in INSERT mode and upon receiving a keystroke with a printable
- character, L{HistoricRecvLine} replaces the character at
- the cursor with the typed character rather than inserting before.
- Ah, the ironies of INSERT mode.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
-
- for ch in 'xyz':
- kR(ch)
-
- kR(self.pt.INSERT)
-
- kR(self.pt.LEFT_ARROW)
- kR('A')
- self.assertEqual(self.p.currentLineBuffer(), ('xyA', ''))
-
- kR(self.pt.LEFT_ARROW)
- kR('B')
- self.assertEqual(self.p.currentLineBuffer(), ('xyB', ''))
-
-
- def test_unprintableCharacters(self):
- """
- When L{HistoricRecvLine} receives a keystroke for an unprintable
- function key with no assigned behavior, the line buffer is unmodified.
- """
- kR = lambda ch: self.p.keystrokeReceived(ch, None)
- pt = self.pt
-
- for ch in (pt.F1, pt.F2, pt.F3, pt.F4, pt.F5, pt.F6, pt.F7, pt.F8,
- pt.F9, pt.F10, pt.F11, pt.F12, pt.PGUP, pt.PGDN):
- kR(ch)
- self.assertEqual(self.p.currentLineBuffer(), ('', ''))
-
-
-from twisted.conch import telnet
-from twisted.conch.insults import helper
-from twisted.protocols import loopback
-
-class EchoServer(recvline.HistoricRecvLine):
- def lineReceived(self, line):
- self.terminal.write(line + '\n' + self.ps[self.pn])
-
-# An insults API for this would be nice.
-left = "\x1b[D"
-right = "\x1b[C"
-up = "\x1b[A"
-down = "\x1b[B"
-insert = "\x1b[2~"
-home = "\x1b[1~"
-delete = "\x1b[3~"
-end = "\x1b[4~"
-backspace = "\x7f"
-
-from twisted.cred import checkers
-
-try:
- from twisted.conch.ssh import userauth, transport, channel, connection, session
- from twisted.conch.manhole_ssh import TerminalUser, TerminalSession, TerminalRealm, TerminalSessionTransport, ConchFactory
-except ImportError:
- ssh = False
-else:
- ssh = True
- class SessionChannel(channel.SSHChannel):
- name = 'session'
-
- def __init__(self, protocolFactory, protocolArgs, protocolKwArgs, width, height, *a, **kw):
- channel.SSHChannel.__init__(self, *a, **kw)
-
- self.protocolFactory = protocolFactory
- self.protocolArgs = protocolArgs
- self.protocolKwArgs = protocolKwArgs
-
- self.width = width
- self.height = height
-
- def channelOpen(self, data):
- term = session.packRequest_pty_req("vt102", (self.height, self.width, 0, 0), '')
- self.conn.sendRequest(self, 'pty-req', term)
- self.conn.sendRequest(self, 'shell', '')
-
- self._protocolInstance = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs)
- self._protocolInstance.factory = self
- self._protocolInstance.makeConnection(self)
-
- def closed(self):
- self._protocolInstance.connectionLost(error.ConnectionDone())
-
- def dataReceived(self, data):
- self._protocolInstance.dataReceived(data)
-
- class TestConnection(connection.SSHConnection):
- def __init__(self, protocolFactory, protocolArgs, protocolKwArgs, width, height, *a, **kw):
- connection.SSHConnection.__init__(self, *a, **kw)
-
- self.protocolFactory = protocolFactory
- self.protocolArgs = protocolArgs
- self.protocolKwArgs = protocolKwArgs
-
- self.width = width
- self.height = height
-
- def serviceStarted(self):
- self.__channel = SessionChannel(self.protocolFactory, self.protocolArgs, self.protocolKwArgs, self.width, self.height)
- self.openChannel(self.__channel)
-
- def write(self, bytes):
- return self.__channel.write(bytes)
-
- class TestAuth(userauth.SSHUserAuthClient):
- def __init__(self, username, password, *a, **kw):
- userauth.SSHUserAuthClient.__init__(self, username, *a, **kw)
- self.password = password
-
- def getPassword(self):
- return defer.succeed(self.password)
-
- class TestTransport(transport.SSHClientTransport):
- def __init__(self, protocolFactory, protocolArgs, protocolKwArgs, username, password, width, height, *a, **kw):
- # transport.SSHClientTransport.__init__(self, *a, **kw)
- self.protocolFactory = protocolFactory
- self.protocolArgs = protocolArgs
- self.protocolKwArgs = protocolKwArgs
- self.username = username
- self.password = password
- self.width = width
- self.height = height
-
- def verifyHostKey(self, hostKey, fingerprint):
- return defer.succeed(True)
-
- def connectionSecure(self):
- self.__connection = TestConnection(self.protocolFactory, self.protocolArgs, self.protocolKwArgs, self.width, self.height)
- self.requestService(
- TestAuth(self.username, self.password, self.__connection))
-
- def write(self, bytes):
- return self.__connection.write(bytes)
-
- class TestSessionTransport(TerminalSessionTransport):
- def protocolFactory(self):
- return self.avatar.conn.transport.factory.serverProtocol()
-
- class TestSession(TerminalSession):
- transportFactory = TestSessionTransport
-
- class TestUser(TerminalUser):
- pass
-
- components.registerAdapter(TestSession, TestUser, session.ISession)
-
-
-class LoopbackRelay(loopback.LoopbackRelay):
- clearCall = None
-
- def logPrefix(self):
- return "LoopbackRelay(%r)" % (self.target.__class__.__name__,)
-
- def write(self, bytes):
- loopback.LoopbackRelay.write(self, bytes)
- if self.clearCall is not None:
- self.clearCall.cancel()
-
- from twisted.internet import reactor
- self.clearCall = reactor.callLater(0, self._clearBuffer)
-
- def _clearBuffer(self):
- self.clearCall = None
- loopback.LoopbackRelay.clearBuffer(self)
-
-
-class NotifyingExpectableBuffer(helper.ExpectableBuffer):
- def __init__(self):
- self.onConnection = defer.Deferred()
- self.onDisconnection = defer.Deferred()
-
- def connectionMade(self):
- helper.ExpectableBuffer.connectionMade(self)
- self.onConnection.callback(self)
-
- def connectionLost(self, reason):
- self.onDisconnection.errback(reason)
-
-
-class _BaseMixin:
- WIDTH = 80
- HEIGHT = 24
-
- def _assertBuffer(self, lines):
- receivedLines = str(self.recvlineClient).splitlines()
- expectedLines = lines + ([''] * (self.HEIGHT - len(lines) - 1))
- self.assertEqual(len(receivedLines), len(expectedLines))
- for i in range(len(receivedLines)):
- self.assertEqual(
- receivedLines[i], expectedLines[i],
- str(receivedLines[max(0, i-1):i+1]) +
- " != " +
- str(expectedLines[max(0, i-1):i+1]))
-
- def _trivialTest(self, input, output):
- done = self.recvlineClient.expect("done")
-
- self._testwrite(input)
-
- def finished(ign):
- self._assertBuffer(output)
-
- return done.addCallback(finished)
-
-
-class _SSHMixin(_BaseMixin):
- def setUp(self):
- if not ssh:
- raise unittest.SkipTest("Crypto requirements missing, can't run historic recvline tests over ssh")
-
- u, p = 'testuser', 'testpass'
- rlm = TerminalRealm()
- rlm.userFactory = TestUser
- rlm.chainedProtocolFactory = lambda: insultsServer
-
- ptl = portal.Portal(
- rlm,
- [checkers.InMemoryUsernamePasswordDatabaseDontUse(**{u: p})])
- sshFactory = ConchFactory(ptl)
- sshFactory.serverProtocol = self.serverProtocol
- sshFactory.startFactory()
-
- recvlineServer = self.serverProtocol()
- insultsServer = insults.ServerProtocol(lambda: recvlineServer)
- sshServer = sshFactory.buildProtocol(None)
- clientTransport = LoopbackRelay(sshServer)
-
- recvlineClient = NotifyingExpectableBuffer()
- insultsClient = insults.ClientProtocol(lambda: recvlineClient)
- sshClient = TestTransport(lambda: insultsClient, (), {}, u, p, self.WIDTH, self.HEIGHT)
- serverTransport = LoopbackRelay(sshClient)
-
- sshClient.makeConnection(clientTransport)
- sshServer.makeConnection(serverTransport)
-
- self.recvlineClient = recvlineClient
- self.sshClient = sshClient
- self.sshServer = sshServer
- self.clientTransport = clientTransport
- self.serverTransport = serverTransport
-
- return recvlineClient.onConnection
-
- def _testwrite(self, bytes):
- self.sshClient.write(bytes)
-
-from twisted.conch.test import test_telnet
-
-class TestInsultsClientProtocol(insults.ClientProtocol,
- test_telnet.TestProtocol):
- pass
-
-
-class TestInsultsServerProtocol(insults.ServerProtocol,
- test_telnet.TestProtocol):
- pass
-
-class _TelnetMixin(_BaseMixin):
- def setUp(self):
- recvlineServer = self.serverProtocol()
- insultsServer = TestInsultsServerProtocol(lambda: recvlineServer)
- telnetServer = telnet.TelnetTransport(lambda: insultsServer)
- clientTransport = LoopbackRelay(telnetServer)
-
- recvlineClient = NotifyingExpectableBuffer()
- insultsClient = TestInsultsClientProtocol(lambda: recvlineClient)
- telnetClient = telnet.TelnetTransport(lambda: insultsClient)
- serverTransport = LoopbackRelay(telnetClient)
-
- telnetClient.makeConnection(clientTransport)
- telnetServer.makeConnection(serverTransport)
-
- serverTransport.clearBuffer()
- clientTransport.clearBuffer()
-
- self.recvlineClient = recvlineClient
- self.telnetClient = telnetClient
- self.clientTransport = clientTransport
- self.serverTransport = serverTransport
-
- return recvlineClient.onConnection
-
- def _testwrite(self, bytes):
- self.telnetClient.write(bytes)
-
-try:
- from twisted.conch import stdio
-except ImportError:
- stdio = None
-
-class _StdioMixin(_BaseMixin):
- def setUp(self):
- # A memory-only terminal emulator, into which the server will
- # write things and make other state changes. What ends up
- # here is basically what a user would have seen on their
- # screen.
- testTerminal = NotifyingExpectableBuffer()
-
- # An insults client protocol which will translate bytes
- # received from the child process into keystroke commands for
- # an ITerminalProtocol.
- insultsClient = insults.ClientProtocol(lambda: testTerminal)
-
- # A process protocol which will translate stdout and stderr
- # received from the child process to dataReceived calls and
- # error reporting on an insults client protocol.
- processClient = stdio.TerminalProcessProtocol(insultsClient)
-
- # Run twisted/conch/stdio.py with the name of a class
- # implementing ITerminalProtocol. This class will be used to
- # handle bytes we send to the child process.
- exe = sys.executable
- module = stdio.__file__
- if module.endswith('.pyc') or module.endswith('.pyo'):
- module = module[:-1]
- args = [exe, module, reflect.qual(self.serverProtocol)]
- env = os.environ.copy()
- env["PYTHONPATH"] = os.pathsep.join(sys.path)
-
- from twisted.internet import reactor
- clientTransport = reactor.spawnProcess(processClient, exe, args,
- env=env, usePTY=True)
-
- self.recvlineClient = self.testTerminal = testTerminal
- self.processClient = processClient
- self.clientTransport = clientTransport
-
- # Wait for the process protocol and test terminal to become
- # connected before proceeding. The former should always
- # happen first, but it doesn't hurt to be safe.
- return defer.gatherResults(filter(None, [
- processClient.onConnection,
- testTerminal.expect(">>> ")]))
-
- def tearDown(self):
- # Kill the child process. We're done with it.
- try:
- self.clientTransport.signalProcess("KILL")
- except (error.ProcessExitedAlready, OSError):
- pass
- def trap(failure):
- failure.trap(error.ProcessTerminated)
- self.assertEqual(failure.value.exitCode, None)
- self.assertEqual(failure.value.status, 9)
- return self.testTerminal.onDisconnection.addErrback(trap)
-
- def _testwrite(self, bytes):
- self.clientTransport.write(bytes)
-
-class RecvlineLoopbackMixin:
- serverProtocol = EchoServer
-
- def testSimple(self):
- return self._trivialTest(
- "first line\ndone",
- [">>> first line",
- "first line",
- ">>> done"])
-
- def testLeftArrow(self):
- return self._trivialTest(
- insert + 'first line' + left * 4 + "xxxx\ndone",
- [">>> first xxxx",
- "first xxxx",
- ">>> done"])
-
- def testRightArrow(self):
- return self._trivialTest(
- insert + 'right line' + left * 4 + right * 2 + "xx\ndone",
- [">>> right lixx",
- "right lixx",
- ">>> done"])
-
- def testBackspace(self):
- return self._trivialTest(
- "second line" + backspace * 4 + "xxxx\ndone",
- [">>> second xxxx",
- "second xxxx",
- ">>> done"])
-
- def testDelete(self):
- return self._trivialTest(
- "delete xxxx" + left * 4 + delete * 4 + "line\ndone",
- [">>> delete line",
- "delete line",
- ">>> done"])
-
- def testInsert(self):
- return self._trivialTest(
- "third ine" + left * 3 + "l\ndone",
- [">>> third line",
- "third line",
- ">>> done"])
-
- def testTypeover(self):
- return self._trivialTest(
- "fourth xine" + left * 4 + insert + "l\ndone",
- [">>> fourth line",
- "fourth line",
- ">>> done"])
-
- def testHome(self):
- return self._trivialTest(
- insert + "blah line" + home + "home\ndone",
- [">>> home line",
- "home line",
- ">>> done"])
-
- def testEnd(self):
- return self._trivialTest(
- "end " + left * 4 + end + "line\ndone",
- [">>> end line",
- "end line",
- ">>> done"])
-
-class RecvlineLoopbackTelnet(_TelnetMixin, unittest.TestCase, RecvlineLoopbackMixin):
- pass
-
-class RecvlineLoopbackSSH(_SSHMixin, unittest.TestCase, RecvlineLoopbackMixin):
- pass
-
-class RecvlineLoopbackStdio(_StdioMixin, unittest.TestCase, RecvlineLoopbackMixin):
- if stdio is None:
- skip = "Terminal requirements missing, can't run recvline tests over stdio"
-
-
-class HistoricRecvlineLoopbackMixin:
- serverProtocol = EchoServer
-
- def testUpArrow(self):
- return self._trivialTest(
- "first line\n" + up + "\ndone",
- [">>> first line",
- "first line",
- ">>> first line",
- "first line",
- ">>> done"])
-
- def testDownArrow(self):
- return self._trivialTest(
- "first line\nsecond line\n" + up * 2 + down + "\ndone",
- [">>> first line",
- "first line",
- ">>> second line",
- "second line",
- ">>> second line",
- "second line",
- ">>> done"])
-
-class HistoricRecvlineLoopbackTelnet(_TelnetMixin, unittest.TestCase, HistoricRecvlineLoopbackMixin):
- pass
-
-class HistoricRecvlineLoopbackSSH(_SSHMixin, unittest.TestCase, HistoricRecvlineLoopbackMixin):
- pass
-
-class HistoricRecvlineLoopbackStdio(_StdioMixin, unittest.TestCase, HistoricRecvlineLoopbackMixin):
- if stdio is None:
- skip = "Terminal requirements missing, can't run historic recvline tests over stdio"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py
deleted file mode 100755
index ae90e828..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the command-line interfaces to conch.
-"""
-
-try:
- import pyasn1
-except ImportError:
- pyasn1Skip = "Cannot run without PyASN1"
-else:
- pyasn1Skip = None
-
-try:
- import Crypto
-except ImportError:
- cryptoSkip = "can't run w/o PyCrypto"
-else:
- cryptoSkip = None
-
-try:
- import tty
-except ImportError:
- ttySkip = "can't run w/o tty"
-else:
- ttySkip = None
-
-try:
- import Tkinter
-except ImportError:
- tkskip = "can't run w/o Tkinter"
-else:
- try:
- Tkinter.Tk().destroy()
- except Tkinter.TclError, e:
- tkskip = "Can't test Tkinter: " + str(e)
- else:
- tkskip = None
-
-from twisted.trial.unittest import TestCase
-from twisted.scripts.test.test_scripts import ScriptTestsMixin
-from twisted.python.test.test_shellcomp import ZshScriptTestMixin
-
-
-
-class ScriptTests(TestCase, ScriptTestsMixin):
- """
- Tests for the Conch scripts.
- """
- skip = pyasn1Skip or cryptoSkip
-
-
- def test_conch(self):
- self.scriptTest("conch/conch")
- test_conch.skip = ttySkip or skip
-
-
- def test_cftp(self):
- self.scriptTest("conch/cftp")
- test_cftp.skip = ttySkip or skip
-
-
- def test_ckeygen(self):
- self.scriptTest("conch/ckeygen")
-
-
- def test_tkconch(self):
- self.scriptTest("conch/tkconch")
- test_tkconch.skip = tkskip or skip
-
-
-
-class ZshIntegrationTestCase(TestCase, ZshScriptTestMixin):
- """
- Test that zsh completion functions are generated without error
- """
- generateFor = [('conch', 'twisted.conch.scripts.conch.ClientOptions'),
- ('cftp', 'twisted.conch.scripts.cftp.ClientOptions'),
- ('ckeygen', 'twisted.conch.scripts.ckeygen.GeneralOptions'),
- ('tkconch', 'twisted.conch.scripts.tkconch.GeneralOptions'),
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py
deleted file mode 100755
index 4db16298..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py
+++ /dev/null
@@ -1,1256 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the 'session' channel implementation in twisted.conch.ssh.session.
-
-See also RFC 4254.
-"""
-
-import os, signal, sys, struct
-
-from zope.interface import implements
-
-from twisted.internet.address import IPv4Address
-from twisted.internet.error import ProcessTerminated, ProcessDone
-from twisted.python.failure import Failure
-from twisted.conch.ssh import common, session, connection
-from twisted.internet import defer, protocol, error
-from twisted.python import components, failure
-from twisted.trial import unittest
-
-
-
-class SubsystemOnlyAvatar(object):
- """
- A stub class representing an avatar that is only useful for
- getting a subsystem.
- """
-
-
- def lookupSubsystem(self, name, data):
- """
- If the other side requests the 'subsystem' subsystem, allow it by
- returning a MockProtocol to implement it. Otherwise, return
- None which is interpreted by SSHSession as a failure.
- """
- if name == 'subsystem':
- return MockProtocol()
-
-
-
-class StubAvatar:
- """
- A stub class representing the avatar representing the authenticated user.
- It implements the I{ISession} interface.
- """
-
-
- def lookupSubsystem(self, name, data):
- """
- If the user requests the TestSubsystem subsystem, connect them to a
- MockProtocol. If they request neither, then None is returned which is
- interpreted by SSHSession as a failure.
- """
- if name == 'TestSubsystem':
- self.subsystem = MockProtocol()
- self.subsystem.packetData = data
- return self.subsystem
-
-
-
-class StubSessionForStubAvatar(object):
- """
- A stub ISession implementation for our StubAvatar. The instance
- variables generally keep track of method invocations so that we can test
- that the methods were called.
-
- @ivar avatar: the L{StubAvatar} we are adapting.
- @ivar ptyRequest: if present, the terminal, window size, and modes passed
- to the getPty method.
- @ivar windowChange: if present, the window size passed to the
- windowChangned method.
- @ivar shellProtocol: if present, the L{SSHSessionProcessProtocol} passed
- to the openShell method.
- @ivar shellTransport: if present, the L{EchoTransport} connected to
- shellProtocol.
- @ivar execProtocol: if present, the L{SSHSessionProcessProtocol} passed
- to the execCommand method.
- @ivar execTransport: if present, the L{EchoTransport} connected to
- execProtocol.
- @ivar execCommandLine: if present, the command line passed to the
- execCommand method.
- @ivar gotEOF: if present, an EOF message was received.
- @ivar gotClosed: if present, a closed message was received.
- """
-
-
- implements(session.ISession)
-
-
- def __init__(self, avatar):
- """
- Store the avatar we're adapting.
- """
- self.avatar = avatar
- self.shellProtocol = None
-
-
- def getPty(self, terminal, window, modes):
- """
- If the terminal is 'bad', fail. Otherwise, store the information in
- the ptyRequest variable.
- """
- if terminal != 'bad':
- self.ptyRequest = (terminal, window, modes)
- else:
- raise RuntimeError('not getting a pty')
-
-
- def windowChanged(self, window):
- """
- If all the window sizes are 0, fail. Otherwise, store the size in the
- windowChange variable.
- """
- if window == (0, 0, 0, 0):
- raise RuntimeError('not changing the window size')
- else:
- self.windowChange = window
-
-
- def openShell(self, pp):
- """
- If we have gotten a shell request before, fail. Otherwise, store the
- process protocol in the shellProtocol variable, connect it to the
- EchoTransport and store that as shellTransport.
- """
- if self.shellProtocol is not None:
- raise RuntimeError('not getting a shell this time')
- else:
- self.shellProtocol = pp
- self.shellTransport = EchoTransport(pp)
-
-
- def execCommand(self, pp, command):
- """
- If the command is 'true', store the command, the process protocol, and
- the transport we connect to the process protocol. Otherwise, just
- store the command and raise an error.
- """
- self.execCommandLine = command
- if command == 'success':
- self.execProtocol = pp
- elif command[:6] == 'repeat':
- self.execProtocol = pp
- self.execTransport = EchoTransport(pp)
- pp.outReceived(command[7:])
- else:
- raise RuntimeError('not getting a command')
-
-
- def eofReceived(self):
- """
- Note that EOF has been received.
- """
- self.gotEOF = True
-
-
- def closed(self):
- """
- Note that close has been received.
- """
- self.gotClosed = True
-
-
-
-components.registerAdapter(StubSessionForStubAvatar, StubAvatar,
- session.ISession)
-
-
-
-
-class MockProcessProtocol(protocol.ProcessProtocol):
- """
- A mock ProcessProtocol which echoes back data sent to it and
- appends a tilde. The tilde is appended so the tests can verify that
- we received and processed the data.
-
- @ivar packetData: C{str} of data to be sent when the connection is made.
- @ivar data: a C{str} of data received.
- @ivar err: a C{str} of error data received.
- @ivar inConnectionOpen: True if the input side is open.
- @ivar outConnectionOpen: True if the output side is open.
- @ivar errConnectionOpen: True if the error side is open.
- @ivar ended: False if the protocol has not ended, a C{Failure} if the
- process has ended.
- """
- packetData = ''
-
-
- def connectionMade(self):
- """
- Set up variables.
- """
- self.data = ''
- self.err = ''
- self.inConnectionOpen = True
- self.outConnectionOpen = True
- self.errConnectionOpen = True
- self.ended = False
- if self.packetData:
- self.outReceived(self.packetData)
-
-
- def outReceived(self, data):
- """
- Data was received. Store it and echo it back with a tilde.
- """
- self.data += data
- if self.transport is not None:
- self.transport.write(data + '~')
-
-
- def errReceived(self, data):
- """
- Error data was received. Store it and echo it back backwards.
- """
- self.err += data
- self.transport.write(data[::-1])
-
-
- def inConnectionLost(self):
- """
- Close the input side.
- """
- self.inConnectionOpen = False
-
-
- def outConnectionLost(self):
- """
- Close the output side.
- """
- self.outConnectionOpen = False
-
-
- def errConnectionLost(self):
- """
- Close the error side.
- """
- self.errConnectionOpen = False
-
-
- def processEnded(self, reason):
- """
- End the process and store the reason.
- """
- self.ended = reason
-
-
-
-class EchoTransport:
- """
- A transport for a ProcessProtocol which echos data that is sent to it with
- a Window newline (CR LF) appended to it. If a null byte is in the data,
- disconnect. When we are asked to disconnect, disconnect the
- C{ProcessProtocol} with a 0 exit code.
-
- @ivar proto: the C{ProcessProtocol} connected to us.
- @ivar data: a C{str} of data written to us.
- """
-
-
- def __init__(self, processProtocol):
- """
- Initialize our instance variables.
-
- @param processProtocol: a C{ProcessProtocol} to connect to ourself.
- """
- self.proto = processProtocol
- self.closed = False
- self.data = ''
- processProtocol.makeConnection(self)
-
-
- def write(self, data):
- """
- We got some data. Give it back to our C{ProcessProtocol} with
- a newline attached. Disconnect if there's a null byte.
- """
- self.data += data
- self.proto.outReceived(data)
- self.proto.outReceived('\r\n')
- if '\x00' in data: # mimic 'exit' for the shell test
- self.loseConnection()
-
-
- def loseConnection(self):
- """
- If we're asked to disconnect (and we haven't already) shut down
- the C{ProcessProtocol} with a 0 exit code.
- """
- if self.closed:
- return
- self.closed = 1
- self.proto.inConnectionLost()
- self.proto.outConnectionLost()
- self.proto.errConnectionLost()
- self.proto.processEnded(failure.Failure(
- error.ProcessTerminated(0, None, None)))
-
-
-
-class MockProtocol(protocol.Protocol):
- """
- A sample Protocol which stores the data passed to it.
-
- @ivar packetData: a C{str} of data to be sent when the connection is made.
- @ivar data: a C{str} of the data passed to us.
- @ivar open: True if the channel is open.
- @ivar reason: if not None, the reason the protocol was closed.
- """
- packetData = ''
-
-
- def connectionMade(self):
- """
- Set up the instance variables. If we have any packetData, send it
- along.
- """
-
- self.data = ''
- self.open = True
- self.reason = None
- if self.packetData:
- self.dataReceived(self.packetData)
-
-
- def dataReceived(self, data):
- """
- Store the received data and write it back with a tilde appended.
- The tilde is appended so that the tests can verify that we processed
- the data.
- """
- self.data += data
- if self.transport is not None:
- self.transport.write(data + '~')
-
-
- def connectionLost(self, reason):
- """
- Close the protocol and store the reason.
- """
- self.open = False
- self.reason = reason
-
-
-
-class StubConnection(object):
- """
- A stub for twisted.conch.ssh.connection.SSHConnection. Record the data
- that channels send, and when they try to close the connection.
-
- @ivar data: a C{dict} mapping C{SSHChannel}s to a C{list} of C{str} of data
- they sent.
- @ivar extData: a C{dict} mapping L{SSHChannel}s to a C{list} of C{tuple} of
- (C{int}, C{str}) of extended data they sent.
- @ivar requests: a C{dict} mapping L{SSHChannel}s to a C{list} of C{tuple}
- of (C{str}, C{str}) of channel requests they made.
- @ivar eofs: a C{dict} mapping L{SSHChannel}s to C{true} if they have sent
- an EOF.
- @ivar closes: a C{dict} mapping L{SSHChannel}s to C{true} if they have sent
- a close.
- """
-
-
- def __init__(self, transport=None):
- """
- Initialize our instance variables.
- """
- self.data = {}
- self.extData = {}
- self.requests = {}
- self.eofs = {}
- self.closes = {}
- self.transport = transport
-
-
- def logPrefix(self):
- """
- Return our logging prefix.
- """
- return "MockConnection"
-
-
- def sendData(self, channel, data):
- """
- Record the sent data.
- """
- self.data.setdefault(channel, []).append(data)
-
-
- def sendExtendedData(self, channel, type, data):
- """
- Record the sent extended data.
- """
- self.extData.setdefault(channel, []).append((type, data))
-
-
- def sendRequest(self, channel, request, data, wantReply=False):
- """
- Record the sent channel request.
- """
- self.requests.setdefault(channel, []).append((request, data,
- wantReply))
- if wantReply:
- return defer.succeed(None)
-
-
- def sendEOF(self, channel):
- """
- Record the sent EOF.
- """
- self.eofs[channel] = True
-
-
- def sendClose(self, channel):
- """
- Record the sent close.
- """
- self.closes[channel] = True
-
-
-
-class StubTransport:
- """
- A stub transport which records the data written.
-
- @ivar buf: the data sent to the transport.
- @type buf: C{str}
-
- @ivar close: flags indicating if the transport has been closed.
- @type close: C{bool}
- """
-
- buf = ''
- close = False
-
-
- def getPeer(self):
- """
- Return an arbitrary L{IAddress}.
- """
- return IPv4Address('TCP', 'remotehost', 8888)
-
-
- def getHost(self):
- """
- Return an arbitrary L{IAddress}.
- """
- return IPv4Address('TCP', 'localhost', 9999)
-
-
- def write(self, data):
- """
- Record data in the buffer.
- """
- self.buf += data
-
-
- def loseConnection(self):
- """
- Note that the connection was closed.
- """
- self.close = True
-
-
-class StubTransportWithWriteErr(StubTransport):
- """
- A version of StubTransport which records the error data sent to it.
-
- @ivar err: the extended data sent to the transport.
- @type err: C{str}
- """
-
- err = ''
-
-
- def writeErr(self, data):
- """
- Record the extended data in the buffer. This was an old interface
- that allowed the Transports from ISession.openShell() or
- ISession.execCommand() to receive extended data from the client.
- """
- self.err += data
-
-
-
-class StubClient(object):
- """
- A stub class representing the client to a SSHSession.
-
- @ivar transport: A L{StubTransport} object which keeps track of the data
- passed to it.
- """
-
-
- def __init__(self):
- self.transport = StubTransportWithWriteErr()
-
-
-
-class SessionInterfaceTestCase(unittest.TestCase):
- """
- Tests for the SSHSession class interface. This interface is not ideal, but
- it is tested in order to maintain backwards compatibility.
- """
-
-
- def setUp(self):
- """
- Make an SSHSession object to test. Give the channel some window
- so that it's allowed to send packets. 500 and 100 are arbitrary
- values.
- """
- self.session = session.SSHSession(remoteWindow=500,
- remoteMaxPacket=100, conn=StubConnection(),
- avatar=StubAvatar())
-
-
- def assertSessionIsStubSession(self):
- """
- Asserts that self.session.session is an instance of
- StubSessionForStubOldAvatar.
- """
- self.assertIsInstance(self.session.session,
- StubSessionForStubAvatar)
-
-
- def test_init(self):
- """
- SSHSession initializes its buffer (buf), client, and ISession adapter.
- The avatar should not need to be adaptable to an ISession immediately.
- """
- s = session.SSHSession(avatar=object) # use object because it doesn't
- # have an adapter
- self.assertEqual(s.buf, '')
- self.assertIdentical(s.client, None)
- self.assertIdentical(s.session, None)
-
-
- def test_client_dataReceived(self):
- """
- SSHSession.dataReceived() passes data along to a client. If the data
- comes before there is a client, the data should be discarded.
- """
- self.session.dataReceived('1')
- self.session.client = StubClient()
- self.session.dataReceived('2')
- self.assertEqual(self.session.client.transport.buf, '2')
-
- def test_client_extReceived(self):
- """
- SSHSession.extReceived() passed data of type EXTENDED_DATA_STDERR along
- to the client. If the data comes before there is a client, or if the
- data is not of type EXTENDED_DATA_STDERR, it is discared.
- """
- self.session.extReceived(connection.EXTENDED_DATA_STDERR, '1')
- self.session.extReceived(255, '2') # 255 is arbitrary
- self.session.client = StubClient()
- self.session.extReceived(connection.EXTENDED_DATA_STDERR, '3')
- self.assertEqual(self.session.client.transport.err, '3')
-
-
- def test_client_extReceivedWithoutWriteErr(self):
- """
- SSHSession.extReceived() should handle the case where the transport
- on the client doesn't have a writeErr method.
- """
- client = self.session.client = StubClient()
- client.transport = StubTransport() # doesn't have writeErr
-
- # should not raise an error
- self.session.extReceived(connection.EXTENDED_DATA_STDERR, 'ignored')
-
-
-
- def test_client_closed(self):
- """
- SSHSession.closed() should tell the transport connected to the client
- that the connection was lost.
- """
- self.session.client = StubClient()
- self.session.closed()
- self.assertTrue(self.session.client.transport.close)
- self.session.client.transport.close = False
-
-
- def test_badSubsystemDoesNotCreateClient(self):
- """
- When a subsystem request fails, SSHSession.client should not be set.
- """
- ret = self.session.requestReceived(
- 'subsystem', common.NS('BadSubsystem'))
- self.assertFalse(ret)
- self.assertIdentical(self.session.client, None)
-
-
- def test_lookupSubsystem(self):
- """
- When a client requests a subsystem, the SSHSession object should get
- the subsystem by calling avatar.lookupSubsystem, and attach it as
- the client.
- """
- ret = self.session.requestReceived(
- 'subsystem', common.NS('TestSubsystem') + 'data')
- self.assertTrue(ret)
- self.assertIsInstance(self.session.client, protocol.ProcessProtocol)
- self.assertIdentical(self.session.client.transport.proto,
- self.session.avatar.subsystem)
-
-
-
- def test_lookupSubsystemDoesNotNeedISession(self):
- """
- Previously, if one only wanted to implement a subsystem, an ISession
- adapter wasn't needed because subsystems were looked up using the
- lookupSubsystem method on the avatar.
- """
- s = session.SSHSession(avatar=SubsystemOnlyAvatar(),
- conn=StubConnection())
- ret = s.request_subsystem(
- common.NS('subsystem') + 'data')
- self.assertTrue(ret)
- self.assertNotIdentical(s.client, None)
- self.assertIdentical(s.conn.closes.get(s), None)
- s.eofReceived()
- self.assertTrue(s.conn.closes.get(s))
- # these should not raise errors
- s.loseConnection()
- s.closed()
-
-
- def test_lookupSubsystem_data(self):
- """
- After having looked up a subsystem, data should be passed along to the
- client. Additionally, subsystems were passed the entire request packet
- as data, instead of just the additional data.
-
- We check for the additional tidle to verify that the data passed
- through the client.
- """
- #self.session.dataReceived('1')
- # subsystems didn't get extended data
- #self.session.extReceived(connection.EXTENDED_DATA_STDERR, '2')
-
- self.session.requestReceived('subsystem',
- common.NS('TestSubsystem') + 'data')
-
- self.assertEqual(self.session.conn.data[self.session],
- ['\x00\x00\x00\x0dTestSubsystemdata~'])
- self.session.dataReceived('more data')
- self.assertEqual(self.session.conn.data[self.session][-1],
- 'more data~')
-
-
- def test_lookupSubsystem_closeReceived(self):
- """
- SSHSession.closeReceived() should sent a close message to the remote
- side.
- """
- self.session.requestReceived('subsystem',
- common.NS('TestSubsystem') + 'data')
-
- self.session.closeReceived()
- self.assertTrue(self.session.conn.closes[self.session])
-
-
- def assertRequestRaisedRuntimeError(self):
- """
- Assert that the request we just made raised a RuntimeError (and only a
- RuntimeError).
- """
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1, "Multiple RuntimeErrors raised: %s" %
- '\n'.join([repr(error) for error in errors]))
- errors[0].trap(RuntimeError)
-
-
- def test_requestShell(self):
- """
- When a client requests a shell, the SSHSession object should get
- the shell by getting an ISession adapter for the avatar, then
- calling openShell() with a ProcessProtocol to attach.
- """
- # gets a shell the first time
- ret = self.session.requestReceived('shell', '')
- self.assertTrue(ret)
- self.assertSessionIsStubSession()
- self.assertIsInstance(self.session.client,
- session.SSHSessionProcessProtocol)
- self.assertIdentical(self.session.session.shellProtocol,
- self.session.client)
- # doesn't get a shell the second time
- self.assertFalse(self.session.requestReceived('shell', ''))
- self.assertRequestRaisedRuntimeError()
-
-
- def test_requestShellWithData(self):
- """
- When a client executes a shell, it should be able to give pass data
- back and forth between the local and the remote side.
- """
- ret = self.session.requestReceived('shell', '')
- self.assertTrue(ret)
- self.assertSessionIsStubSession()
- self.session.dataReceived('some data\x00')
- self.assertEqual(self.session.session.shellTransport.data,
- 'some data\x00')
- self.assertEqual(self.session.conn.data[self.session],
- ['some data\x00', '\r\n'])
- self.assertTrue(self.session.session.shellTransport.closed)
- self.assertEqual(self.session.conn.requests[self.session],
- [('exit-status', '\x00\x00\x00\x00', False)])
-
-
- def test_requestExec(self):
- """
- When a client requests a command, the SSHSession object should get
- the command by getting an ISession adapter for the avatar, then
- calling execCommand with a ProcessProtocol to attach and the
- command line.
- """
- ret = self.session.requestReceived('exec',
- common.NS('failure'))
- self.assertFalse(ret)
- self.assertRequestRaisedRuntimeError()
- self.assertIdentical(self.session.client, None)
-
- self.assertTrue(self.session.requestReceived('exec',
- common.NS('success')))
- self.assertSessionIsStubSession()
- self.assertIsInstance(self.session.client,
- session.SSHSessionProcessProtocol)
- self.assertIdentical(self.session.session.execProtocol,
- self.session.client)
- self.assertEqual(self.session.session.execCommandLine,
- 'success')
-
-
- def test_requestExecWithData(self):
- """
- When a client executes a command, it should be able to give pass data
- back and forth.
- """
- ret = self.session.requestReceived('exec',
- common.NS('repeat hello'))
- self.assertTrue(ret)
- self.assertSessionIsStubSession()
- self.session.dataReceived('some data')
- self.assertEqual(self.session.session.execTransport.data, 'some data')
- self.assertEqual(self.session.conn.data[self.session],
- ['hello', 'some data', '\r\n'])
- self.session.eofReceived()
- self.session.closeReceived()
- self.session.closed()
- self.assertTrue(self.session.session.execTransport.closed)
- self.assertEqual(self.session.conn.requests[self.session],
- [('exit-status', '\x00\x00\x00\x00', False)])
-
-
- def test_requestPty(self):
- """
- When a client requests a PTY, the SSHSession object should make
- the request by getting an ISession adapter for the avatar, then
- calling getPty with the terminal type, the window size, and any modes
- the client gave us.
- """
- # 'bad' terminal type fails
- ret = self.session.requestReceived(
- 'pty_req', session.packRequest_pty_req(
- 'bad', (1, 2, 3, 4), ''))
- self.assertFalse(ret)
- self.assertSessionIsStubSession()
- self.assertRequestRaisedRuntimeError()
- # 'good' terminal type succeeds
- self.assertTrue(self.session.requestReceived('pty_req',
- session.packRequest_pty_req('good', (1, 2, 3, 4), '')))
- self.assertEqual(self.session.session.ptyRequest,
- ('good', (1, 2, 3, 4), []))
-
-
- def test_requestWindowChange(self):
- """
- When the client requests to change the window size, the SSHSession
- object should make the request by getting an ISession adapter for the
- avatar, then calling windowChanged with the new window size.
- """
- ret = self.session.requestReceived(
- 'window_change',
- session.packRequest_window_change((0, 0, 0, 0)))
- self.assertFalse(ret)
- self.assertRequestRaisedRuntimeError()
- self.assertSessionIsStubSession()
- self.assertTrue(self.session.requestReceived('window_change',
- session.packRequest_window_change((1, 2, 3, 4))))
- self.assertEqual(self.session.session.windowChange,
- (1, 2, 3, 4))
-
-
- def test_eofReceived(self):
- """
- When an EOF is received and a ISession adapter is present, it should
- be notified of the EOF message.
- """
- self.session.session = session.ISession(self.session.avatar)
- self.session.eofReceived()
- self.assertTrue(self.session.session.gotEOF)
-
-
- def test_closeReceived(self):
- """
- When a close is received, the session should send a close message.
- """
- ret = self.session.closeReceived()
- self.assertIdentical(ret, None)
- self.assertTrue(self.session.conn.closes[self.session])
-
-
- def test_closed(self):
- """
- When a close is received and a ISession adapter is present, it should
- be notified of the close message.
- """
- self.session.session = session.ISession(self.session.avatar)
- self.session.closed()
- self.assertTrue(self.session.session.gotClosed)
-
-
-
-class SessionWithNoAvatarTestCase(unittest.TestCase):
- """
- Test for the SSHSession interface. Several of the methods (request_shell,
- request_exec, request_pty_req, request_window_change) would create a
- 'session' instance variable from the avatar if one didn't exist when they
- were called.
- """
-
-
- def setUp(self):
- self.session = session.SSHSession()
- self.session.avatar = StubAvatar()
- self.assertIdentical(self.session.session, None)
-
-
- def assertSessionProvidesISession(self):
- """
- self.session.session should provide I{ISession}.
- """
- self.assertTrue(session.ISession.providedBy(self.session.session),
- "ISession not provided by %r" % self.session.session)
-
-
- def test_requestShellGetsSession(self):
- """
- If an ISession adapter isn't already present, request_shell should get
- one.
- """
- self.session.requestReceived('shell', '')
- self.assertSessionProvidesISession()
-
-
- def test_requestExecGetsSession(self):
- """
- If an ISession adapter isn't already present, request_exec should get
- one.
- """
- self.session.requestReceived('exec',
- common.NS('success'))
- self.assertSessionProvidesISession()
-
-
- def test_requestPtyReqGetsSession(self):
- """
- If an ISession adapter isn't already present, request_pty_req should
- get one.
- """
- self.session.requestReceived('pty_req',
- session.packRequest_pty_req(
- 'term', (0, 0, 0, 0), ''))
- self.assertSessionProvidesISession()
-
-
- def test_requestWindowChangeGetsSession(self):
- """
- If an ISession adapter isn't already present, request_window_change
- should get one.
- """
- self.session.requestReceived(
- 'window_change',
- session.packRequest_window_change(
- (1, 1, 1, 1)))
- self.assertSessionProvidesISession()
-
-
-
-class WrappersTestCase(unittest.TestCase):
- """
- A test for the wrapProtocol and wrapProcessProtocol functions.
- """
-
- def test_wrapProtocol(self):
- """
- L{wrapProtocol}, when passed a L{Protocol} should return something that
- has write(), writeSequence(), loseConnection() methods which call the
- Protocol's dataReceived() and connectionLost() methods, respectively.
- """
- protocol = MockProtocol()
- protocol.transport = StubTransport()
- protocol.connectionMade()
- wrapped = session.wrapProtocol(protocol)
- wrapped.dataReceived('dataReceived')
- self.assertEqual(protocol.transport.buf, 'dataReceived')
- wrapped.write('data')
- wrapped.writeSequence(['1', '2'])
- wrapped.loseConnection()
- self.assertEqual(protocol.data, 'data12')
- protocol.reason.trap(error.ConnectionDone)
-
- def test_wrapProcessProtocol_Protocol(self):
- """
- L{wrapPRocessProtocol}, when passed a L{Protocol} should return
- something that follows the L{IProcessProtocol} interface, with
- connectionMade() mapping to connectionMade(), outReceived() mapping to
- dataReceived() and processEnded() mapping to connectionLost().
- """
- protocol = MockProtocol()
- protocol.transport = StubTransport()
- process_protocol = session.wrapProcessProtocol(protocol)
- process_protocol.connectionMade()
- process_protocol.outReceived('data')
- self.assertEqual(protocol.transport.buf, 'data~')
- process_protocol.processEnded(failure.Failure(
- error.ProcessTerminated(0, None, None)))
- protocol.reason.trap(error.ProcessTerminated)
-
-
-
-class TestHelpers(unittest.TestCase):
- """
- Tests for the 4 helper functions: parseRequest_* and packRequest_*.
- """
-
-
- def test_parseRequest_pty_req(self):
- """
- The payload of a pty-req message is::
- string terminal
- uint32 columns
- uint32 rows
- uint32 x pixels
- uint32 y pixels
- string modes
-
- Modes are::
- byte mode number
- uint32 mode value
- """
- self.assertEqual(session.parseRequest_pty_req(common.NS('xterm') +
- struct.pack('>4L',
- 1, 2, 3, 4)
- + common.NS(
- struct.pack('>BL', 5, 6))),
- ('xterm', (2, 1, 3, 4), [(5, 6)]))
-
-
- def test_packRequest_pty_req_old(self):
- """
- See test_parseRequest_pty_req for the payload format.
- """
- packed = session.packRequest_pty_req('xterm', (2, 1, 3, 4),
- '\x05\x00\x00\x00\x06')
-
- self.assertEqual(packed,
- common.NS('xterm') + struct.pack('>4L', 1, 2, 3, 4) +
- common.NS(struct.pack('>BL', 5, 6)))
-
-
- def test_packRequest_pty_req(self):
- """
- See test_parseRequest_pty_req for the payload format.
- """
- packed = session.packRequest_pty_req('xterm', (2, 1, 3, 4),
- '\x05\x00\x00\x00\x06')
- self.assertEqual(packed,
- common.NS('xterm') + struct.pack('>4L', 1, 2, 3, 4) +
- common.NS(struct.pack('>BL', 5, 6)))
-
-
- def test_parseRequest_window_change(self):
- """
- The payload of a window_change request is::
- uint32 columns
- uint32 rows
- uint32 x pixels
- uint32 y pixels
-
- parseRequest_window_change() returns (rows, columns, x pixels,
- y pixels).
- """
- self.assertEqual(session.parseRequest_window_change(
- struct.pack('>4L', 1, 2, 3, 4)), (2, 1, 3, 4))
-
-
- def test_packRequest_window_change(self):
- """
- See test_parseRequest_window_change for the payload format.
- """
- self.assertEqual(session.packRequest_window_change((2, 1, 3, 4)),
- struct.pack('>4L', 1, 2, 3, 4))
-
-
-
-class SSHSessionProcessProtocolTestCase(unittest.TestCase):
- """
- Tests for L{SSHSessionProcessProtocol}.
- """
-
- def setUp(self):
- self.transport = StubTransport()
- self.session = session.SSHSession(
- conn=StubConnection(self.transport), remoteWindow=500,
- remoteMaxPacket=100)
- self.pp = session.SSHSessionProcessProtocol(self.session)
- self.pp.makeConnection(self.transport)
-
-
- def assertSessionClosed(self):
- """
- Assert that C{self.session} is closed.
- """
- self.assertTrue(self.session.conn.closes[self.session])
-
-
- def assertRequestsEqual(self, expectedRequests):
- """
- Assert that C{self.session} has sent the C{expectedRequests}.
- """
- self.assertEqual(
- self.session.conn.requests[self.session],
- expectedRequests)
-
-
- def test_init(self):
- """
- SSHSessionProcessProtocol should set self.session to the session passed
- to the __init__ method.
- """
- self.assertEqual(self.pp.session, self.session)
-
-
- def test_getHost(self):
- """
- SSHSessionProcessProtocol.getHost() just delegates to its
- session.conn.transport.getHost().
- """
- self.assertEqual(
- self.session.conn.transport.getHost(), self.pp.getHost())
-
-
- def test_getPeer(self):
- """
- SSHSessionProcessProtocol.getPeer() just delegates to its
- session.conn.transport.getPeer().
- """
- self.assertEqual(
- self.session.conn.transport.getPeer(), self.pp.getPeer())
-
-
- def test_connectionMade(self):
- """
- SSHSessionProcessProtocol.connectionMade() should check if there's a
- 'buf' attribute on its session and write it to the transport if so.
- """
- self.session.buf = 'buffer'
- self.pp.connectionMade()
- self.assertEqual(self.transport.buf, 'buffer')
-
-
- def test_getSignalName(self):
- """
- _getSignalName should return the name of a signal when given the
- signal number.
- """
- for signalName in session.SUPPORTED_SIGNALS:
- signalName = 'SIG' + signalName
- signalValue = getattr(signal, signalName)
- sshName = self.pp._getSignalName(signalValue)
- self.assertEqual(sshName, signalName,
- "%i: %s != %s" % (signalValue, sshName,
- signalName))
-
-
- def test_getSignalNameWithLocalSignal(self):
- """
- If there are signals in the signal module which aren't in the SSH RFC,
- we map their name to [signal name]@[platform].
- """
- signal.SIGTwistedTest = signal.NSIG + 1 # value can't exist normally
- # Force reinitialization of signals
- self.pp._signalValuesToNames = None
- self.assertEqual(self.pp._getSignalName(signal.SIGTwistedTest),
- 'SIGTwistedTest@' + sys.platform)
-
-
- if getattr(signal, 'SIGALRM', None) is None:
- test_getSignalName.skip = test_getSignalNameWithLocalSignal.skip = \
- "Not all signals available"
-
-
- def test_outReceived(self):
- """
- When data is passed to the outReceived method, it should be sent to
- the session's write method.
- """
- self.pp.outReceived('test data')
- self.assertEqual(self.session.conn.data[self.session],
- ['test data'])
-
-
- def test_write(self):
- """
- When data is passed to the write method, it should be sent to the
- session channel's write method.
- """
- self.pp.write('test data')
- self.assertEqual(self.session.conn.data[self.session],
- ['test data'])
-
- def test_writeSequence(self):
- """
- When a sequence is passed to the writeSequence method, it should be
- joined together and sent to the session channel's write method.
- """
- self.pp.writeSequence(['test ', 'data'])
- self.assertEqual(self.session.conn.data[self.session],
- ['test data'])
-
-
- def test_errReceived(self):
- """
- When data is passed to the errReceived method, it should be sent to
- the session's writeExtended method.
- """
- self.pp.errReceived('test data')
- self.assertEqual(self.session.conn.extData[self.session],
- [(1, 'test data')])
-
-
- def test_outConnectionLost(self):
- """
- When outConnectionLost and errConnectionLost are both called, we should
- send an EOF message.
- """
- self.pp.outConnectionLost()
- self.assertFalse(self.session in self.session.conn.eofs)
- self.pp.errConnectionLost()
- self.assertTrue(self.session.conn.eofs[self.session])
-
-
- def test_errConnectionLost(self):
- """
- Make sure reverse ordering of events in test_outConnectionLost also
- sends EOF.
- """
- self.pp.errConnectionLost()
- self.assertFalse(self.session in self.session.conn.eofs)
- self.pp.outConnectionLost()
- self.assertTrue(self.session.conn.eofs[self.session])
-
-
- def test_loseConnection(self):
- """
- When loseConnection() is called, it should call loseConnection
- on the session channel.
- """
- self.pp.loseConnection()
- self.assertTrue(self.session.conn.closes[self.session])
-
-
- def test_connectionLost(self):
- """
- When connectionLost() is called, it should call loseConnection()
- on the session channel.
- """
- self.pp.connectionLost(failure.Failure(
- ProcessDone(0)))
-
-
- def test_processEndedWithExitCode(self):
- """
- When processEnded is called, if there is an exit code in the reason
- it should be sent in an exit-status method. The connection should be
- closed.
- """
- self.pp.processEnded(Failure(ProcessDone(None)))
- self.assertRequestsEqual(
- [('exit-status', struct.pack('>I', 0) , False)])
- self.assertSessionClosed()
-
-
- def test_processEndedWithExitSignalCoreDump(self):
- """
- When processEnded is called, if there is an exit signal in the reason
- it should be sent in an exit-signal message. The connection should be
- closed.
- """
- self.pp.processEnded(
- Failure(ProcessTerminated(1,
- signal.SIGTERM, 1 << 7))) # 7th bit means core dumped
- self.assertRequestsEqual(
- [('exit-signal',
- common.NS('TERM') # signal name
- + '\x01' # core dumped is true
- + common.NS('') # error message
- + common.NS(''), # language tag
- False)])
- self.assertSessionClosed()
-
-
- def test_processEndedWithExitSignalNoCoreDump(self):
- """
- When processEnded is called, if there is an exit signal in the
- reason it should be sent in an exit-signal message. If no
- core was dumped, don't set the core-dump bit.
- """
- self.pp.processEnded(
- Failure(ProcessTerminated(1, signal.SIGTERM, 0)))
- # see comments in test_processEndedWithExitSignalCoreDump for the
- # meaning of the parts in the request
- self.assertRequestsEqual(
- [('exit-signal', common.NS('TERM') + '\x00' + common.NS('') +
- common.NS(''), False)])
- self.assertSessionClosed()
-
-
- if getattr(os, 'WCOREDUMP', None) is None:
- skipMsg = "can't run this w/o os.WCOREDUMP"
- test_processEndedWithExitSignalCoreDump.skip = skipMsg
- test_processEndedWithExitSignalNoCoreDump.skip = skipMsg
-
-
-
-class SSHSessionClientTestCase(unittest.TestCase):
- """
- SSHSessionClient is an obsolete class used to connect standard IO to
- an SSHSession.
- """
-
-
- def test_dataReceived(self):
- """
- When data is received, it should be sent to the transport.
- """
- client = session.SSHSessionClient()
- client.transport = StubTransport()
- client.dataReceived('test data')
- self.assertEqual(client.transport.buf, 'test data')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py
deleted file mode 100755
index 6cf1a1ab..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py
+++ /dev/null
@@ -1,995 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.ssh}.
-"""
-
-import struct
-
-try:
- import Crypto.Cipher.DES3
-except ImportError:
- Crypto = None
-
-try:
- import pyasn1
-except ImportError:
- pyasn1 = None
-
-from twisted.conch.ssh import common, session, forwarding
-from twisted.conch import avatar, error
-from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh
-from twisted.conch.test.keydata import publicDSA_openssh, privateDSA_openssh
-from twisted.cred import portal
-from twisted.cred.error import UnauthorizedLogin
-from twisted.internet import defer, protocol, reactor
-from twisted.internet.error import ProcessTerminated
-from twisted.python import failure, log
-from twisted.trial import unittest
-
-from twisted.conch.test.test_recvline import LoopbackRelay
-
-
-
-class ConchTestRealm(object):
- """
- A realm which expects a particular avatarId to log in once and creates a
- L{ConchTestAvatar} for that request.
-
- @ivar expectedAvatarID: The only avatarID that this realm will produce an
- avatar for.
-
- @ivar avatar: A reference to the avatar after it is requested.
- """
- avatar = None
-
- def __init__(self, expectedAvatarID):
- self.expectedAvatarID = expectedAvatarID
-
-
- def requestAvatar(self, avatarID, mind, *interfaces):
- """
- Return a new L{ConchTestAvatar} if the avatarID matches the expected one
- and this is the first avatar request.
- """
- if avatarID == self.expectedAvatarID:
- if self.avatar is not None:
- raise UnauthorizedLogin("Only one login allowed")
- self.avatar = ConchTestAvatar()
- return interfaces[0], self.avatar, self.avatar.logout
- raise UnauthorizedLogin(
- "Only %r may log in, not %r" % (self.expectedAvatarID, avatarID))
-
-
-
-class ConchTestAvatar(avatar.ConchUser):
- """
- An avatar against which various SSH features can be tested.
-
- @ivar loggedOut: A flag indicating whether the avatar logout method has been
- called.
- """
- loggedOut = False
-
- def __init__(self):
- avatar.ConchUser.__init__(self)
- self.listeners = {}
- self.globalRequests = {}
- self.channelLookup.update({'session': session.SSHSession,
- 'direct-tcpip':forwarding.openConnectForwardingClient})
- self.subsystemLookup.update({'crazy': CrazySubsystem})
-
-
- def global_foo(self, data):
- self.globalRequests['foo'] = data
- return 1
-
-
- def global_foo_2(self, data):
- self.globalRequests['foo_2'] = data
- return 1, 'data'
-
-
- def global_tcpip_forward(self, data):
- host, port = forwarding.unpackGlobal_tcpip_forward(data)
- try:
- listener = reactor.listenTCP(
- port, forwarding.SSHListenForwardingFactory(
- self.conn, (host, port),
- forwarding.SSHListenServerForwardingChannel),
- interface=host)
- except:
- log.err(None, "something went wrong with remote->local forwarding")
- return 0
- else:
- self.listeners[(host, port)] = listener
- return 1
-
-
- def global_cancel_tcpip_forward(self, data):
- host, port = forwarding.unpackGlobal_tcpip_forward(data)
- listener = self.listeners.get((host, port), None)
- if not listener:
- return 0
- del self.listeners[(host, port)]
- listener.stopListening()
- return 1
-
-
- def logout(self):
- self.loggedOut = True
- for listener in self.listeners.values():
- log.msg('stopListening %s' % listener)
- listener.stopListening()
-
-
-
-class ConchSessionForTestAvatar(object):
- """
- An ISession adapter for ConchTestAvatar.
- """
- def __init__(self, avatar):
- """
- Initialize the session and create a reference to it on the avatar for
- later inspection.
- """
- self.avatar = avatar
- self.avatar._testSession = self
- self.cmd = None
- self.proto = None
- self.ptyReq = False
- self.eof = 0
- self.onClose = defer.Deferred()
-
-
- def getPty(self, term, windowSize, attrs):
- log.msg('pty req')
- self._terminalType = term
- self._windowSize = windowSize
- self.ptyReq = True
-
-
- def openShell(self, proto):
- log.msg('opening shell')
- self.proto = proto
- EchoTransport(proto)
- self.cmd = 'shell'
-
-
- def execCommand(self, proto, cmd):
- self.cmd = cmd
- self.proto = proto
- f = cmd.split()[0]
- if f == 'false':
- t = FalseTransport(proto)
- # Avoid disconnecting this immediately. If the channel is closed
- # before execCommand even returns the caller gets confused.
- reactor.callLater(0, t.loseConnection)
- elif f == 'echo':
- t = EchoTransport(proto)
- t.write(cmd[5:])
- t.loseConnection()
- elif f == 'secho':
- t = SuperEchoTransport(proto)
- t.write(cmd[6:])
- t.loseConnection()
- elif f == 'eecho':
- t = ErrEchoTransport(proto)
- t.write(cmd[6:])
- t.loseConnection()
- else:
- raise error.ConchError('bad exec')
- self.avatar.conn.transport.expectedLoseConnection = 1
-
-
- def eofReceived(self):
- self.eof = 1
-
-
- def closed(self):
- log.msg('closed cmd "%s"' % self.cmd)
- self.remoteWindowLeftAtClose = self.proto.session.remoteWindowLeft
- self.onClose.callback(None)
-
-from twisted.python import components
-components.registerAdapter(ConchSessionForTestAvatar, ConchTestAvatar, session.ISession)
-
-class CrazySubsystem(protocol.Protocol):
-
- def __init__(self, *args, **kw):
- pass
-
- def connectionMade(self):
- """
- good ... good
- """
-
-
-
-class FalseTransport:
- """
- False transport should act like a /bin/false execution, i.e. just exit with
- nonzero status, writing nothing to the terminal.
-
- @ivar proto: The protocol associated with this transport.
- @ivar closed: A flag tracking whether C{loseConnection} has been called yet.
- """
-
- def __init__(self, p):
- """
- @type p L{twisted.conch.ssh.session.SSHSessionProcessProtocol} instance
- """
- self.proto = p
- p.makeConnection(self)
- self.closed = 0
-
-
- def loseConnection(self):
- """
- Disconnect the protocol associated with this transport.
- """
- if self.closed:
- return
- self.closed = 1
- self.proto.inConnectionLost()
- self.proto.outConnectionLost()
- self.proto.errConnectionLost()
- self.proto.processEnded(failure.Failure(ProcessTerminated(255, None, None)))
-
-
-
-class EchoTransport:
-
- def __init__(self, p):
- self.proto = p
- p.makeConnection(self)
- self.closed = 0
-
- def write(self, data):
- log.msg(repr(data))
- self.proto.outReceived(data)
- self.proto.outReceived('\r\n')
- if '\x00' in data: # mimic 'exit' for the shell test
- self.loseConnection()
-
- def loseConnection(self):
- if self.closed: return
- self.closed = 1
- self.proto.inConnectionLost()
- self.proto.outConnectionLost()
- self.proto.errConnectionLost()
- self.proto.processEnded(failure.Failure(ProcessTerminated(0, None, None)))
-
-class ErrEchoTransport:
-
- def __init__(self, p):
- self.proto = p
- p.makeConnection(self)
- self.closed = 0
-
- def write(self, data):
- self.proto.errReceived(data)
- self.proto.errReceived('\r\n')
-
- def loseConnection(self):
- if self.closed: return
- self.closed = 1
- self.proto.inConnectionLost()
- self.proto.outConnectionLost()
- self.proto.errConnectionLost()
- self.proto.processEnded(failure.Failure(ProcessTerminated(0, None, None)))
-
-class SuperEchoTransport:
-
- def __init__(self, p):
- self.proto = p
- p.makeConnection(self)
- self.closed = 0
-
- def write(self, data):
- self.proto.outReceived(data)
- self.proto.outReceived('\r\n')
- self.proto.errReceived(data)
- self.proto.errReceived('\r\n')
-
- def loseConnection(self):
- if self.closed: return
- self.closed = 1
- self.proto.inConnectionLost()
- self.proto.outConnectionLost()
- self.proto.errConnectionLost()
- self.proto.processEnded(failure.Failure(ProcessTerminated(0, None, None)))
-
-
-if Crypto is not None and pyasn1 is not None:
- from twisted.conch import checkers
- from twisted.conch.ssh import channel, connection, factory, keys
- from twisted.conch.ssh import transport, userauth
-
- class UtilityTestCase(unittest.TestCase):
- def testCounter(self):
- c = transport._Counter('\x00\x00', 2)
- for i in xrange(256 * 256):
- self.assertEqual(c(), struct.pack('!H', (i + 1) % (2 ** 16)))
- # It should wrap around, too.
- for i in xrange(256 * 256):
- self.assertEqual(c(), struct.pack('!H', (i + 1) % (2 ** 16)))
-
-
- class ConchTestPublicKeyChecker(checkers.SSHPublicKeyDatabase):
- def checkKey(self, credentials):
- blob = keys.Key.fromString(publicDSA_openssh).blob()
- if credentials.username == 'testuser' and credentials.blob == blob:
- return True
- return False
-
-
- class ConchTestPasswordChecker:
- credentialInterfaces = checkers.IUsernamePassword,
-
- def requestAvatarId(self, credentials):
- if credentials.username == 'testuser' and credentials.password == 'testpass':
- return defer.succeed(credentials.username)
- return defer.fail(Exception("Bad credentials"))
-
-
- class ConchTestSSHChecker(checkers.SSHProtocolChecker):
-
- def areDone(self, avatarId):
- if avatarId != 'testuser' or len(self.successfulCredentials[avatarId]) < 2:
- return False
- return True
-
- class ConchTestServerFactory(factory.SSHFactory):
- noisy = 0
-
- services = {
- 'ssh-userauth':userauth.SSHUserAuthServer,
- 'ssh-connection':connection.SSHConnection
- }
-
- def buildProtocol(self, addr):
- proto = ConchTestServer()
- proto.supportedPublicKeys = self.privateKeys.keys()
- proto.factory = self
-
- if hasattr(self, 'expectedLoseConnection'):
- proto.expectedLoseConnection = self.expectedLoseConnection
-
- self.proto = proto
- return proto
-
- def getPublicKeys(self):
- return {
- 'ssh-rsa': keys.Key.fromString(publicRSA_openssh),
- 'ssh-dss': keys.Key.fromString(publicDSA_openssh)
- }
-
- def getPrivateKeys(self):
- return {
- 'ssh-rsa': keys.Key.fromString(privateRSA_openssh),
- 'ssh-dss': keys.Key.fromString(privateDSA_openssh)
- }
-
- def getPrimes(self):
- return {
- 2048:[(transport.DH_GENERATOR, transport.DH_PRIME)]
- }
-
- def getService(self, trans, name):
- return factory.SSHFactory.getService(self, trans, name)
-
- class ConchTestBase:
-
- done = 0
-
- def connectionLost(self, reason):
- if self.done:
- return
- if not hasattr(self,'expectedLoseConnection'):
- unittest.fail('unexpectedly lost connection %s\n%s' % (self, reason))
- self.done = 1
-
- def receiveError(self, reasonCode, desc):
- self.expectedLoseConnection = 1
- # Some versions of OpenSSH (for example, OpenSSH_5.3p1) will
- # send a DISCONNECT_BY_APPLICATION error before closing the
- # connection. Other, older versions (for example,
- # OpenSSH_5.1p1), won't. So accept this particular error here,
- # but no others.
- if reasonCode != transport.DISCONNECT_BY_APPLICATION:
- log.err(
- Exception(
- 'got disconnect for %s: reason %s, desc: %s' % (
- self, reasonCode, desc)))
- self.loseConnection()
-
- def receiveUnimplemented(self, seqID):
- unittest.fail('got unimplemented: seqid %s' % seqID)
- self.expectedLoseConnection = 1
- self.loseConnection()
-
- class ConchTestServer(ConchTestBase, transport.SSHServerTransport):
-
- def connectionLost(self, reason):
- ConchTestBase.connectionLost(self, reason)
- transport.SSHServerTransport.connectionLost(self, reason)
-
-
- class ConchTestClient(ConchTestBase, transport.SSHClientTransport):
- """
- @ivar _channelFactory: A callable which accepts an SSH connection and
- returns a channel which will be attached to a new channel on that
- connection.
- """
- def __init__(self, channelFactory):
- self._channelFactory = channelFactory
-
- def connectionLost(self, reason):
- ConchTestBase.connectionLost(self, reason)
- transport.SSHClientTransport.connectionLost(self, reason)
-
- def verifyHostKey(self, key, fp):
- keyMatch = key == keys.Key.fromString(publicRSA_openssh).blob()
- fingerprintMatch = (
- fp == '3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af')
- if keyMatch and fingerprintMatch:
- return defer.succeed(1)
- return defer.fail(Exception("Key or fingerprint mismatch"))
-
- def connectionSecure(self):
- self.requestService(ConchTestClientAuth('testuser',
- ConchTestClientConnection(self._channelFactory)))
-
-
- class ConchTestClientAuth(userauth.SSHUserAuthClient):
-
- hasTriedNone = 0 # have we tried the 'none' auth yet?
- canSucceedPublicKey = 0 # can we succed with this yet?
- canSucceedPassword = 0
-
- def ssh_USERAUTH_SUCCESS(self, packet):
- if not self.canSucceedPassword and self.canSucceedPublicKey:
- unittest.fail('got USERAUTH_SUCESS before password and publickey')
- userauth.SSHUserAuthClient.ssh_USERAUTH_SUCCESS(self, packet)
-
- def getPassword(self):
- self.canSucceedPassword = 1
- return defer.succeed('testpass')
-
- def getPrivateKey(self):
- self.canSucceedPublicKey = 1
- return defer.succeed(keys.Key.fromString(privateDSA_openssh))
-
- def getPublicKey(self):
- return keys.Key.fromString(publicDSA_openssh)
-
-
- class ConchTestClientConnection(connection.SSHConnection):
- """
- @ivar _completed: A L{Deferred} which will be fired when the number of
- results collected reaches C{totalResults}.
- """
- name = 'ssh-connection'
- results = 0
- totalResults = 8
-
- def __init__(self, channelFactory):
- connection.SSHConnection.__init__(self)
- self._channelFactory = channelFactory
-
- def serviceStarted(self):
- self.openChannel(self._channelFactory(conn=self))
-
-
- class SSHTestChannel(channel.SSHChannel):
-
- def __init__(self, name, opened, *args, **kwargs):
- self.name = name
- self._opened = opened
- self.received = []
- self.receivedExt = []
- self.onClose = defer.Deferred()
- channel.SSHChannel.__init__(self, *args, **kwargs)
-
-
- def openFailed(self, reason):
- self._opened.errback(reason)
-
-
- def channelOpen(self, ignore):
- self._opened.callback(self)
-
-
- def dataReceived(self, data):
- self.received.append(data)
-
-
- def extReceived(self, dataType, data):
- if dataType == connection.EXTENDED_DATA_STDERR:
- self.receivedExt.append(data)
- else:
- log.msg("Unrecognized extended data: %r" % (dataType,))
-
-
- def request_exit_status(self, status):
- [self.status] = struct.unpack('>L', status)
-
-
- def eofReceived(self):
- self.eofCalled = True
-
-
- def closed(self):
- self.onClose.callback(None)
-
-
-
-class SSHProtocolTestCase(unittest.TestCase):
- """
- Tests for communication between L{SSHServerTransport} and
- L{SSHClientTransport}.
- """
-
- if not Crypto:
- skip = "can't run w/o PyCrypto"
-
- if not pyasn1:
- skip = "Cannot run without PyASN1"
-
- def _ourServerOurClientTest(self, name='session', **kwargs):
- """
- Create a connected SSH client and server protocol pair and return a
- L{Deferred} which fires with an L{SSHTestChannel} instance connected to
- a channel on that SSH connection.
- """
- result = defer.Deferred()
- self.realm = ConchTestRealm('testuser')
- p = portal.Portal(self.realm)
- sshpc = ConchTestSSHChecker()
- sshpc.registerChecker(ConchTestPasswordChecker())
- sshpc.registerChecker(ConchTestPublicKeyChecker())
- p.registerChecker(sshpc)
- fac = ConchTestServerFactory()
- fac.portal = p
- fac.startFactory()
- self.server = fac.buildProtocol(None)
- self.clientTransport = LoopbackRelay(self.server)
- self.client = ConchTestClient(
- lambda conn: SSHTestChannel(name, result, conn=conn, **kwargs))
-
- self.serverTransport = LoopbackRelay(self.client)
-
- self.server.makeConnection(self.serverTransport)
- self.client.makeConnection(self.clientTransport)
- return result
-
-
- def test_subsystemsAndGlobalRequests(self):
- """
- Run the Conch server against the Conch client. Set up several different
- channels which exercise different behaviors and wait for them to
- complete. Verify that the channels with errors log them.
- """
- channel = self._ourServerOurClientTest()
-
- def cbSubsystem(channel):
- self.channel = channel
- return self.assertFailure(
- channel.conn.sendRequest(
- channel, 'subsystem', common.NS('not-crazy'), 1),
- Exception)
- channel.addCallback(cbSubsystem)
-
- def cbNotCrazyFailed(ignored):
- channel = self.channel
- return channel.conn.sendRequest(
- channel, 'subsystem', common.NS('crazy'), 1)
- channel.addCallback(cbNotCrazyFailed)
-
- def cbGlobalRequests(ignored):
- channel = self.channel
- d1 = channel.conn.sendGlobalRequest('foo', 'bar', 1)
-
- d2 = channel.conn.sendGlobalRequest('foo-2', 'bar2', 1)
- d2.addCallback(self.assertEqual, 'data')
-
- d3 = self.assertFailure(
- channel.conn.sendGlobalRequest('bar', 'foo', 1),
- Exception)
-
- return defer.gatherResults([d1, d2, d3])
- channel.addCallback(cbGlobalRequests)
-
- def disconnect(ignored):
- self.assertEqual(
- self.realm.avatar.globalRequests,
- {"foo": "bar", "foo_2": "bar2"})
- channel = self.channel
- channel.conn.transport.expectedLoseConnection = True
- channel.conn.serviceStopped()
- channel.loseConnection()
- channel.addCallback(disconnect)
-
- return channel
-
-
- def test_shell(self):
- """
- L{SSHChannel.sendRequest} can open a shell with a I{pty-req} request,
- specifying a terminal type and window size.
- """
- channel = self._ourServerOurClientTest()
-
- data = session.packRequest_pty_req('conch-test-term', (24, 80, 0, 0), '')
- def cbChannel(channel):
- self.channel = channel
- return channel.conn.sendRequest(channel, 'pty-req', data, 1)
- channel.addCallback(cbChannel)
-
- def cbPty(ignored):
- # The server-side object corresponding to our client side channel.
- session = self.realm.avatar.conn.channels[0].session
- self.assertIdentical(session.avatar, self.realm.avatar)
- self.assertEqual(session._terminalType, 'conch-test-term')
- self.assertEqual(session._windowSize, (24, 80, 0, 0))
- self.assertTrue(session.ptyReq)
- channel = self.channel
- return channel.conn.sendRequest(channel, 'shell', '', 1)
- channel.addCallback(cbPty)
-
- def cbShell(ignored):
- self.channel.write('testing the shell!\x00')
- self.channel.conn.sendEOF(self.channel)
- return defer.gatherResults([
- self.channel.onClose,
- self.realm.avatar._testSession.onClose])
- channel.addCallback(cbShell)
-
- def cbExited(ignored):
- if self.channel.status != 0:
- log.msg(
- 'shell exit status was not 0: %i' % (self.channel.status,))
- self.assertEqual(
- "".join(self.channel.received),
- 'testing the shell!\x00\r\n')
- self.assertTrue(self.channel.eofCalled)
- self.assertTrue(
- self.realm.avatar._testSession.eof)
- channel.addCallback(cbExited)
- return channel
-
-
- def test_failedExec(self):
- """
- If L{SSHChannel.sendRequest} issues an exec which the server responds to
- with an error, the L{Deferred} it returns fires its errback.
- """
- channel = self._ourServerOurClientTest()
-
- def cbChannel(channel):
- self.channel = channel
- return self.assertFailure(
- channel.conn.sendRequest(
- channel, 'exec', common.NS('jumboliah'), 1),
- Exception)
- channel.addCallback(cbChannel)
-
- def cbFailed(ignored):
- # The server logs this exception when it cannot perform the
- # requested exec.
- errors = self.flushLoggedErrors(error.ConchError)
- self.assertEqual(errors[0].value.args, ('bad exec', None))
- channel.addCallback(cbFailed)
- return channel
-
-
- def test_falseChannel(self):
- """
- When the process started by a L{SSHChannel.sendRequest} exec request
- exits, the exit status is reported to the channel.
- """
- channel = self._ourServerOurClientTest()
-
- def cbChannel(channel):
- self.channel = channel
- return channel.conn.sendRequest(
- channel, 'exec', common.NS('false'), 1)
- channel.addCallback(cbChannel)
-
- def cbExec(ignored):
- return self.channel.onClose
- channel.addCallback(cbExec)
-
- def cbClosed(ignored):
- # No data is expected
- self.assertEqual(self.channel.received, [])
- self.assertNotEquals(self.channel.status, 0)
- channel.addCallback(cbClosed)
- return channel
-
-
- def test_errorChannel(self):
- """
- Bytes sent over the extended channel for stderr data are delivered to
- the channel's C{extReceived} method.
- """
- channel = self._ourServerOurClientTest(localWindow=4, localMaxPacket=5)
-
- def cbChannel(channel):
- self.channel = channel
- return channel.conn.sendRequest(
- channel, 'exec', common.NS('eecho hello'), 1)
- channel.addCallback(cbChannel)
-
- def cbExec(ignored):
- return defer.gatherResults([
- self.channel.onClose,
- self.realm.avatar._testSession.onClose])
- channel.addCallback(cbExec)
-
- def cbClosed(ignored):
- self.assertEqual(self.channel.received, [])
- self.assertEqual("".join(self.channel.receivedExt), "hello\r\n")
- self.assertEqual(self.channel.status, 0)
- self.assertTrue(self.channel.eofCalled)
- self.assertEqual(self.channel.localWindowLeft, 4)
- self.assertEqual(
- self.channel.localWindowLeft,
- self.realm.avatar._testSession.remoteWindowLeftAtClose)
- channel.addCallback(cbClosed)
- return channel
-
-
- def test_unknownChannel(self):
- """
- When an attempt is made to open an unknown channel type, the L{Deferred}
- returned by L{SSHChannel.sendRequest} fires its errback.
- """
- d = self.assertFailure(
- self._ourServerOurClientTest('crazy-unknown-channel'), Exception)
- def cbFailed(ignored):
- errors = self.flushLoggedErrors(error.ConchError)
- self.assertEqual(errors[0].value.args, (3, 'unknown channel'))
- self.assertEqual(len(errors), 1)
- d.addCallback(cbFailed)
- return d
-
-
- def test_maxPacket(self):
- """
- An L{SSHChannel} can be configured with a maximum packet size to
- receive.
- """
- # localWindow needs to be at least 11 otherwise the assertion about it
- # in cbClosed is invalid.
- channel = self._ourServerOurClientTest(
- localWindow=11, localMaxPacket=1)
-
- def cbChannel(channel):
- self.channel = channel
- return channel.conn.sendRequest(
- channel, 'exec', common.NS('secho hello'), 1)
- channel.addCallback(cbChannel)
-
- def cbExec(ignored):
- return self.channel.onClose
- channel.addCallback(cbExec)
-
- def cbClosed(ignored):
- self.assertEqual(self.channel.status, 0)
- self.assertEqual("".join(self.channel.received), "hello\r\n")
- self.assertEqual("".join(self.channel.receivedExt), "hello\r\n")
- self.assertEqual(self.channel.localWindowLeft, 11)
- self.assertTrue(self.channel.eofCalled)
- channel.addCallback(cbClosed)
- return channel
-
-
- def test_echo(self):
- """
- Normal standard out bytes are sent to the channel's C{dataReceived}
- method.
- """
- channel = self._ourServerOurClientTest(localWindow=4, localMaxPacket=5)
-
- def cbChannel(channel):
- self.channel = channel
- return channel.conn.sendRequest(
- channel, 'exec', common.NS('echo hello'), 1)
- channel.addCallback(cbChannel)
-
- def cbEcho(ignored):
- return defer.gatherResults([
- self.channel.onClose,
- self.realm.avatar._testSession.onClose])
- channel.addCallback(cbEcho)
-
- def cbClosed(ignored):
- self.assertEqual(self.channel.status, 0)
- self.assertEqual("".join(self.channel.received), "hello\r\n")
- self.assertEqual(self.channel.localWindowLeft, 4)
- self.assertTrue(self.channel.eofCalled)
- self.assertEqual(
- self.channel.localWindowLeft,
- self.realm.avatar._testSession.remoteWindowLeftAtClose)
- channel.addCallback(cbClosed)
- return channel
-
-
-
-class TestSSHFactory(unittest.TestCase):
-
- if not Crypto:
- skip = "can't run w/o PyCrypto"
-
- if not pyasn1:
- skip = "Cannot run without PyASN1"
-
- def makeSSHFactory(self, primes=None):
- sshFactory = factory.SSHFactory()
- gpk = lambda: {'ssh-rsa' : keys.Key(None)}
- sshFactory.getPrimes = lambda: primes
- sshFactory.getPublicKeys = sshFactory.getPrivateKeys = gpk
- sshFactory.startFactory()
- return sshFactory
-
-
- def test_buildProtocol(self):
- """
- By default, buildProtocol() constructs an instance of
- SSHServerTransport.
- """
- factory = self.makeSSHFactory()
- protocol = factory.buildProtocol(None)
- self.assertIsInstance(protocol, transport.SSHServerTransport)
-
-
- def test_buildProtocolRespectsProtocol(self):
- """
- buildProtocol() calls 'self.protocol()' to construct a protocol
- instance.
- """
- calls = []
- def makeProtocol(*args):
- calls.append(args)
- return transport.SSHServerTransport()
- factory = self.makeSSHFactory()
- factory.protocol = makeProtocol
- factory.buildProtocol(None)
- self.assertEqual([()], calls)
-
-
- def test_multipleFactories(self):
- f1 = self.makeSSHFactory(primes=None)
- f2 = self.makeSSHFactory(primes={1:(2,3)})
- p1 = f1.buildProtocol(None)
- p2 = f2.buildProtocol(None)
- self.failIf('diffie-hellman-group-exchange-sha1' in p1.supportedKeyExchanges,
- p1.supportedKeyExchanges)
- self.failUnless('diffie-hellman-group-exchange-sha1' in p2.supportedKeyExchanges,
- p2.supportedKeyExchanges)
-
-
-
-class MPTestCase(unittest.TestCase):
- """
- Tests for L{common.getMP}.
-
- @cvar getMP: a method providing a MP parser.
- @type getMP: C{callable}
- """
- getMP = staticmethod(common.getMP)
-
- if not Crypto:
- skip = "can't run w/o PyCrypto"
-
- if not pyasn1:
- skip = "Cannot run without PyASN1"
-
-
- def test_getMP(self):
- """
- L{common.getMP} should parse the a multiple precision integer from a
- string: a 4-byte length followed by length bytes of the integer.
- """
- self.assertEqual(
- self.getMP('\x00\x00\x00\x04\x00\x00\x00\x01'),
- (1, ''))
-
-
- def test_getMPBigInteger(self):
- """
- L{common.getMP} should be able to parse a big enough integer
- (that doesn't fit on one byte).
- """
- self.assertEqual(
- self.getMP('\x00\x00\x00\x04\x01\x02\x03\x04'),
- (16909060, ''))
-
-
- def test_multipleGetMP(self):
- """
- L{common.getMP} has the ability to parse multiple integer in the same
- string.
- """
- self.assertEqual(
- self.getMP('\x00\x00\x00\x04\x00\x00\x00\x01'
- '\x00\x00\x00\x04\x00\x00\x00\x02', 2),
- (1, 2, ''))
-
-
- def test_getMPRemainingData(self):
- """
- When more data than needed is sent to L{common.getMP}, it should return
- the remaining data.
- """
- self.assertEqual(
- self.getMP('\x00\x00\x00\x04\x00\x00\x00\x01foo'),
- (1, 'foo'))
-
-
- def test_notEnoughData(self):
- """
- When the string passed to L{common.getMP} doesn't even make 5 bytes,
- it should raise a L{struct.error}.
- """
- self.assertRaises(struct.error, self.getMP, '\x02\x00')
-
-
-
-class PyMPTestCase(MPTestCase):
- """
- Tests for the python implementation of L{common.getMP}.
- """
- getMP = staticmethod(common.getMP_py)
-
-
-
-class GMPYMPTestCase(MPTestCase):
- """
- Tests for the gmpy implementation of L{common.getMP}.
- """
- getMP = staticmethod(common._fastgetMP)
-
-
-class BuiltinPowHackTestCase(unittest.TestCase):
- """
- Tests that the builtin pow method is still correct after
- L{twisted.conch.ssh.common} monkeypatches it to use gmpy.
- """
-
- def test_floatBase(self):
- """
- pow gives the correct result when passed a base of type float with a
- non-integer value.
- """
- self.assertEqual(6.25, pow(2.5, 2))
-
- def test_intBase(self):
- """
- pow gives the correct result when passed a base of type int.
- """
- self.assertEqual(81, pow(3, 4))
-
- def test_longBase(self):
- """
- pow gives the correct result when passed a base of type long.
- """
- self.assertEqual(81, pow(3, 4))
-
- def test_mpzBase(self):
- """
- pow gives the correct result when passed a base of type gmpy.mpz.
- """
- if gmpy is None:
- raise unittest.SkipTest('gmpy not available')
- self.assertEqual(81, pow(gmpy.mpz(3), 4))
-
-
-try:
- import gmpy
-except ImportError:
- GMPYMPTestCase.skip = "gmpy not available"
- gmpy = None
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py
deleted file mode 100755
index 44acecd3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.tap}.
-"""
-
-try:
- import Crypto.Cipher.DES3
-except:
- Crypto = None
-
-try:
- import pyasn1
-except ImportError:
- pyasn1 = None
-
-try:
- from twisted.conch import unix
-except ImportError:
- unix = None
-
-if Crypto and pyasn1 and unix:
- from twisted.conch import tap
- from twisted.conch.openssh_compat.factory import OpenSSHFactory
-
-from twisted.python.compat import set
-from twisted.application.internet import StreamServerEndpointService
-from twisted.cred import error
-from twisted.cred.credentials import IPluggableAuthenticationModules
-from twisted.cred.credentials import ISSHPrivateKey
-from twisted.cred.credentials import IUsernamePassword, UsernamePassword
-
-from twisted.trial.unittest import TestCase
-
-
-
-class MakeServiceTest(TestCase):
- """
- Tests for L{tap.makeService}.
- """
-
- if not Crypto:
- skip = "can't run w/o PyCrypto"
-
- if not pyasn1:
- skip = "Cannot run without PyASN1"
-
- if not unix:
- skip = "can't run on non-posix computers"
-
- usernamePassword = ('iamuser', 'thisispassword')
-
- def setUp(self):
- """
- Create a file with two users.
- """
- self.filename = self.mktemp()
- f = open(self.filename, 'wb+')
- f.write(':'.join(self.usernamePassword))
- f.close()
- self.options = tap.Options()
-
-
- def test_basic(self):
- """
- L{tap.makeService} returns a L{StreamServerEndpointService} instance
- running on TCP port 22, and the linked protocol factory is an instance
- of L{OpenSSHFactory}.
- """
- config = tap.Options()
- service = tap.makeService(config)
- self.assertIsInstance(service, StreamServerEndpointService)
- self.assertEqual(service.endpoint._port, 22)
- self.assertIsInstance(service.factory, OpenSSHFactory)
-
-
- def test_defaultAuths(self):
- """
- Make sure that if the C{--auth} command-line option is not passed,
- the default checkers are (for backwards compatibility): SSH, UNIX, and
- PAM if available
- """
- numCheckers = 2
- try:
- from twisted.cred import pamauth
- self.assertIn(IPluggableAuthenticationModules,
- self.options['credInterfaces'],
- "PAM should be one of the modules")
- numCheckers += 1
- except ImportError:
- pass
-
- self.assertIn(ISSHPrivateKey, self.options['credInterfaces'],
- "SSH should be one of the default checkers")
- self.assertIn(IUsernamePassword, self.options['credInterfaces'],
- "UNIX should be one of the default checkers")
- self.assertEqual(numCheckers, len(self.options['credCheckers']),
- "There should be %d checkers by default" % (numCheckers,))
-
-
- def test_authAdded(self):
- """
- The C{--auth} command-line option will add a checker to the list of
- checkers, and it should be the only auth checker
- """
- self.options.parseOptions(['--auth', 'file:' + self.filename])
- self.assertEqual(len(self.options['credCheckers']), 1)
-
-
- def test_authFailure(self):
- """
- The checker created by the C{--auth} command-line option returns a
- L{Deferred} that fails with L{UnauthorizedLogin} when
- presented with credentials that are unknown to that checker.
- """
- self.options.parseOptions(['--auth', 'file:' + self.filename])
- checker = self.options['credCheckers'][-1]
- invalid = UsernamePassword(self.usernamePassword[0], 'fake')
- # Wrong password should raise error
- return self.assertFailure(
- checker.requestAvatarId(invalid), error.UnauthorizedLogin)
-
-
- def test_authSuccess(self):
- """
- The checker created by the C{--auth} command-line option returns a
- L{Deferred} that returns the avatar id when presented with credentials
- that are known to that checker.
- """
- self.options.parseOptions(['--auth', 'file:' + self.filename])
- checker = self.options['credCheckers'][-1]
- correct = UsernamePassword(*self.usernamePassword)
- d = checker.requestAvatarId(correct)
-
- def checkSuccess(username):
- self.assertEqual(username, correct.username)
-
- return d.addCallback(checkSuccess)
-
-
- def test_checkersPamAuth(self):
- """
- The L{OpenSSHFactory} built by L{tap.makeService} has a portal with
- L{IPluggableAuthenticationModules}, L{ISSHPrivateKey} and
- L{IUsernamePassword} interfaces registered as checkers if C{pamauth} is
- available.
- """
- # Fake the presence of pamauth, even if PyPAM is not installed
- self.patch(tap, "pamauth", object())
- config = tap.Options()
- service = tap.makeService(config)
- portal = service.factory.portal
- self.assertEqual(
- set(portal.checkers.keys()),
- set([IPluggableAuthenticationModules, ISSHPrivateKey,
- IUsernamePassword]))
-
-
- def test_checkersWithoutPamAuth(self):
- """
- The L{OpenSSHFactory} built by L{tap.makeService} has a portal with
- L{ISSHPrivateKey} and L{IUsernamePassword} interfaces registered as
- checkers if C{pamauth} is not available.
- """
- # Fake the absence of pamauth, even if PyPAM is installed
- self.patch(tap, "pamauth", None)
- config = tap.Options()
- service = tap.makeService(config)
- portal = service.factory.portal
- self.assertEqual(
- set(portal.checkers.keys()),
- set([ISSHPrivateKey, IUsernamePassword]))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py
deleted file mode 100755
index 9b5bf76a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py
+++ /dev/null
@@ -1,767 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_telnet -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.conch.telnet}.
-"""
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.internet import defer
-
-from twisted.conch import telnet
-
-from twisted.trial import unittest
-from twisted.test import proto_helpers
-
-
-class TestProtocol:
- implements(telnet.ITelnetProtocol)
-
- localEnableable = ()
- remoteEnableable = ()
-
- def __init__(self):
- self.bytes = ''
- self.subcmd = ''
- self.calls = []
-
- self.enabledLocal = []
- self.enabledRemote = []
- self.disabledLocal = []
- self.disabledRemote = []
-
- def makeConnection(self, transport):
- d = transport.negotiationMap = {}
- d['\x12'] = self.neg_TEST_COMMAND
-
- d = transport.commandMap = transport.commandMap.copy()
- for cmd in ('NOP', 'DM', 'BRK', 'IP', 'AO', 'AYT', 'EC', 'EL', 'GA'):
- d[getattr(telnet, cmd)] = lambda arg, cmd=cmd: self.calls.append(cmd)
-
- def dataReceived(self, bytes):
- self.bytes += bytes
-
- def connectionLost(self, reason):
- pass
-
- def neg_TEST_COMMAND(self, payload):
- self.subcmd = payload
-
- def enableLocal(self, option):
- if option in self.localEnableable:
- self.enabledLocal.append(option)
- return True
- return False
-
- def disableLocal(self, option):
- self.disabledLocal.append(option)
-
- def enableRemote(self, option):
- if option in self.remoteEnableable:
- self.enabledRemote.append(option)
- return True
- return False
-
- def disableRemote(self, option):
- self.disabledRemote.append(option)
-
-
-
-class TestInterfaces(unittest.TestCase):
- def test_interface(self):
- """
- L{telnet.TelnetProtocol} implements L{telnet.ITelnetProtocol}
- """
- p = telnet.TelnetProtocol()
- verifyObject(telnet.ITelnetProtocol, p)
-
-
-
-class TelnetTransportTestCase(unittest.TestCase):
- """
- Tests for L{telnet.TelnetTransport}.
- """
- def setUp(self):
- self.p = telnet.TelnetTransport(TestProtocol)
- self.t = proto_helpers.StringTransport()
- self.p.makeConnection(self.t)
-
- def testRegularBytes(self):
- # Just send a bunch of bytes. None of these do anything
- # with telnet. They should pass right through to the
- # application layer.
- h = self.p.protocol
-
- L = ["here are some bytes la la la",
- "some more arrive here",
- "lots of bytes to play with",
- "la la la",
- "ta de da",
- "dum"]
- for b in L:
- self.p.dataReceived(b)
-
- self.assertEqual(h.bytes, ''.join(L))
-
- def testNewlineHandling(self):
- # Send various kinds of newlines and make sure they get translated
- # into \n.
- h = self.p.protocol
-
- L = ["here is the first line\r\n",
- "here is the second line\r\0",
- "here is the third line\r\n",
- "here is the last line\r\0"]
-
- for b in L:
- self.p.dataReceived(b)
-
- self.assertEqual(h.bytes, L[0][:-2] + '\n' +
- L[1][:-2] + '\r' +
- L[2][:-2] + '\n' +
- L[3][:-2] + '\r')
-
- def testIACEscape(self):
- # Send a bunch of bytes and a couple quoted \xFFs. Unquoted,
- # \xFF is a telnet command. Quoted, one of them from each pair
- # should be passed through to the application layer.
- h = self.p.protocol
-
- L = ["here are some bytes\xff\xff with an embedded IAC",
- "and here is a test of a border escape\xff",
- "\xff did you get that IAC?"]
-
- for b in L:
- self.p.dataReceived(b)
-
- self.assertEqual(h.bytes, ''.join(L).replace('\xff\xff', '\xff'))
-
- def _simpleCommandTest(self, cmdName):
- # Send a single simple telnet command and make sure
- # it gets noticed and the appropriate method gets
- # called.
- h = self.p.protocol
-
- cmd = telnet.IAC + getattr(telnet, cmdName)
- L = ["Here's some bytes, tra la la",
- "But ono!" + cmd + " an interrupt"]
-
- for b in L:
- self.p.dataReceived(b)
-
- self.assertEqual(h.calls, [cmdName])
- self.assertEqual(h.bytes, ''.join(L).replace(cmd, ''))
-
- def testInterrupt(self):
- self._simpleCommandTest("IP")
-
- def testNoOperation(self):
- self._simpleCommandTest("NOP")
-
- def testDataMark(self):
- self._simpleCommandTest("DM")
-
- def testBreak(self):
- self._simpleCommandTest("BRK")
-
- def testAbortOutput(self):
- self._simpleCommandTest("AO")
-
- def testAreYouThere(self):
- self._simpleCommandTest("AYT")
-
- def testEraseCharacter(self):
- self._simpleCommandTest("EC")
-
- def testEraseLine(self):
- self._simpleCommandTest("EL")
-
- def testGoAhead(self):
- self._simpleCommandTest("GA")
-
- def testSubnegotiation(self):
- # Send a subnegotiation command and make sure it gets
- # parsed and that the correct method is called.
- h = self.p.protocol
-
- cmd = telnet.IAC + telnet.SB + '\x12hello world' + telnet.IAC + telnet.SE
- L = ["These are some bytes but soon" + cmd,
- "there will be some more"]
-
- for b in L:
- self.p.dataReceived(b)
-
- self.assertEqual(h.bytes, ''.join(L).replace(cmd, ''))
- self.assertEqual(h.subcmd, list("hello world"))
-
- def testSubnegotiationWithEmbeddedSE(self):
- # Send a subnegotiation command with an embedded SE. Make sure
- # that SE gets passed to the correct method.
- h = self.p.protocol
-
- cmd = (telnet.IAC + telnet.SB +
- '\x12' + telnet.SE +
- telnet.IAC + telnet.SE)
-
- L = ["Some bytes are here" + cmd + "and here",
- "and here"]
-
- for b in L:
- self.p.dataReceived(b)
-
- self.assertEqual(h.bytes, ''.join(L).replace(cmd, ''))
- self.assertEqual(h.subcmd, [telnet.SE])
-
- def testBoundarySubnegotiation(self):
- # Send a subnegotiation command. Split it at every possible byte boundary
- # and make sure it always gets parsed and that it is passed to the correct
- # method.
- cmd = (telnet.IAC + telnet.SB +
- '\x12' + telnet.SE + 'hello' +
- telnet.IAC + telnet.SE)
-
- for i in range(len(cmd)):
- h = self.p.protocol = TestProtocol()
- h.makeConnection(self.p)
-
- a, b = cmd[:i], cmd[i:]
- L = ["first part" + a,
- b + "last part"]
-
- for bytes in L:
- self.p.dataReceived(bytes)
-
- self.assertEqual(h.bytes, ''.join(L).replace(cmd, ''))
- self.assertEqual(h.subcmd, [telnet.SE] + list('hello'))
-
- def _enabledHelper(self, o, eL=[], eR=[], dL=[], dR=[]):
- self.assertEqual(o.enabledLocal, eL)
- self.assertEqual(o.enabledRemote, eR)
- self.assertEqual(o.disabledLocal, dL)
- self.assertEqual(o.disabledRemote, dR)
-
- def testRefuseWill(self):
- # Try to enable an option. The server should refuse to enable it.
- cmd = telnet.IAC + telnet.WILL + '\x12'
-
- bytes = "surrounding bytes" + cmd + "to spice things up"
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), telnet.IAC + telnet.DONT + '\x12')
- self._enabledHelper(self.p.protocol)
-
- def testRefuseDo(self):
- # Try to enable an option. The server should refuse to enable it.
- cmd = telnet.IAC + telnet.DO + '\x12'
-
- bytes = "surrounding bytes" + cmd + "to spice things up"
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), telnet.IAC + telnet.WONT + '\x12')
- self._enabledHelper(self.p.protocol)
-
- def testAcceptDo(self):
- # Try to enable an option. The option is in our allowEnable
- # list, so we will allow it to be enabled.
- cmd = telnet.IAC + telnet.DO + '\x19'
- bytes = 'padding' + cmd + 'trailer'
-
- h = self.p.protocol
- h.localEnableable = ('\x19',)
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.t.value(), telnet.IAC + telnet.WILL + '\x19')
- self._enabledHelper(h, eL=['\x19'])
-
- def testAcceptWill(self):
- # Same as testAcceptDo, but reversed.
- cmd = telnet.IAC + telnet.WILL + '\x91'
- bytes = 'header' + cmd + 'padding'
-
- h = self.p.protocol
- h.remoteEnableable = ('\x91',)
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.t.value(), telnet.IAC + telnet.DO + '\x91')
- self._enabledHelper(h, eR=['\x91'])
-
- def testAcceptWont(self):
- # Try to disable an option. The server must allow any option to
- # be disabled at any time. Make sure it disables it and sends
- # back an acknowledgement of this.
- cmd = telnet.IAC + telnet.WONT + '\x29'
-
- # Jimmy it - after these two lines, the server will be in a state
- # such that it believes the option to have been previously enabled
- # via normal negotiation.
- s = self.p.getOptionState('\x29')
- s.him.state = 'yes'
-
- bytes = "fiddle dee" + cmd
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), telnet.IAC + telnet.DONT + '\x29')
- self.assertEqual(s.him.state, 'no')
- self._enabledHelper(self.p.protocol, dR=['\x29'])
-
- def testAcceptDont(self):
- # Try to disable an option. The server must allow any option to
- # be disabled at any time. Make sure it disables it and sends
- # back an acknowledgement of this.
- cmd = telnet.IAC + telnet.DONT + '\x29'
-
- # Jimmy it - after these two lines, the server will be in a state
- # such that it believes the option to have beenp previously enabled
- # via normal negotiation.
- s = self.p.getOptionState('\x29')
- s.us.state = 'yes'
-
- bytes = "fiddle dum " + cmd
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), telnet.IAC + telnet.WONT + '\x29')
- self.assertEqual(s.us.state, 'no')
- self._enabledHelper(self.p.protocol, dL=['\x29'])
-
- def testIgnoreWont(self):
- # Try to disable an option. The option is already disabled. The
- # server should send nothing in response to this.
- cmd = telnet.IAC + telnet.WONT + '\x47'
-
- bytes = "dum de dum" + cmd + "tra la la"
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), '')
- self._enabledHelper(self.p.protocol)
-
- def testIgnoreDont(self):
- # Try to disable an option. The option is already disabled. The
- # server should send nothing in response to this. Doing so could
- # lead to a negotiation loop.
- cmd = telnet.IAC + telnet.DONT + '\x47'
-
- bytes = "dum de dum" + cmd + "tra la la"
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), '')
- self._enabledHelper(self.p.protocol)
-
- def testIgnoreWill(self):
- # Try to enable an option. The option is already enabled. The
- # server should send nothing in response to this. Doing so could
- # lead to a negotiation loop.
- cmd = telnet.IAC + telnet.WILL + '\x56'
-
- # Jimmy it - after these two lines, the server will be in a state
- # such that it believes the option to have been previously enabled
- # via normal negotiation.
- s = self.p.getOptionState('\x56')
- s.him.state = 'yes'
-
- bytes = "tra la la" + cmd + "dum de dum"
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), '')
- self._enabledHelper(self.p.protocol)
-
- def testIgnoreDo(self):
- # Try to enable an option. The option is already enabled. The
- # server should send nothing in response to this. Doing so could
- # lead to a negotiation loop.
- cmd = telnet.IAC + telnet.DO + '\x56'
-
- # Jimmy it - after these two lines, the server will be in a state
- # such that it believes the option to have been previously enabled
- # via normal negotiation.
- s = self.p.getOptionState('\x56')
- s.us.state = 'yes'
-
- bytes = "tra la la" + cmd + "dum de dum"
- self.p.dataReceived(bytes)
-
- self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, ''))
- self.assertEqual(self.t.value(), '')
- self._enabledHelper(self.p.protocol)
-
- def testAcceptedEnableRequest(self):
- # Try to enable an option through the user-level API. This
- # returns a Deferred that fires when negotiation about the option
- # finishes. Make sure it fires, make sure state gets updated
- # properly, make sure the result indicates the option was enabled.
- d = self.p.do('\x42')
-
- h = self.p.protocol
- h.remoteEnableable = ('\x42',)
-
- self.assertEqual(self.t.value(), telnet.IAC + telnet.DO + '\x42')
-
- self.p.dataReceived(telnet.IAC + telnet.WILL + '\x42')
-
- d.addCallback(self.assertEqual, True)
- d.addCallback(lambda _: self._enabledHelper(h, eR=['\x42']))
- return d
-
-
- def test_refusedEnableRequest(self):
- """
- If the peer refuses to enable an option we request it to enable, the
- L{Deferred} returned by L{TelnetProtocol.do} fires with an
- L{OptionRefused} L{Failure}.
- """
- # Try to enable an option through the user-level API. This returns a
- # Deferred that fires when negotiation about the option finishes. Make
- # sure it fires, make sure state gets updated properly, make sure the
- # result indicates the option was enabled.
- self.p.protocol.remoteEnableable = ('\x42',)
- d = self.p.do('\x42')
-
- self.assertEqual(self.t.value(), telnet.IAC + telnet.DO + '\x42')
-
- s = self.p.getOptionState('\x42')
- self.assertEqual(s.him.state, 'no')
- self.assertEqual(s.us.state, 'no')
- self.assertEqual(s.him.negotiating, True)
- self.assertEqual(s.us.negotiating, False)
-
- self.p.dataReceived(telnet.IAC + telnet.WONT + '\x42')
-
- d = self.assertFailure(d, telnet.OptionRefused)
- d.addCallback(lambda ignored: self._enabledHelper(self.p.protocol))
- d.addCallback(
- lambda ignored: self.assertEqual(s.him.negotiating, False))
- return d
-
-
- def test_refusedEnableOffer(self):
- """
- If the peer refuses to allow us to enable an option, the L{Deferred}
- returned by L{TelnetProtocol.will} fires with an L{OptionRefused}
- L{Failure}.
- """
- # Try to offer an option through the user-level API. This returns a
- # Deferred that fires when negotiation about the option finishes. Make
- # sure it fires, make sure state gets updated properly, make sure the
- # result indicates the option was enabled.
- self.p.protocol.localEnableable = ('\x42',)
- d = self.p.will('\x42')
-
- self.assertEqual(self.t.value(), telnet.IAC + telnet.WILL + '\x42')
-
- s = self.p.getOptionState('\x42')
- self.assertEqual(s.him.state, 'no')
- self.assertEqual(s.us.state, 'no')
- self.assertEqual(s.him.negotiating, False)
- self.assertEqual(s.us.negotiating, True)
-
- self.p.dataReceived(telnet.IAC + telnet.DONT + '\x42')
-
- d = self.assertFailure(d, telnet.OptionRefused)
- d.addCallback(lambda ignored: self._enabledHelper(self.p.protocol))
- d.addCallback(
- lambda ignored: self.assertEqual(s.us.negotiating, False))
- return d
-
-
- def testAcceptedDisableRequest(self):
- # Try to disable an option through the user-level API. This
- # returns a Deferred that fires when negotiation about the option
- # finishes. Make sure it fires, make sure state gets updated
- # properly, make sure the result indicates the option was enabled.
- s = self.p.getOptionState('\x42')
- s.him.state = 'yes'
-
- d = self.p.dont('\x42')
-
- self.assertEqual(self.t.value(), telnet.IAC + telnet.DONT + '\x42')
-
- self.p.dataReceived(telnet.IAC + telnet.WONT + '\x42')
-
- d.addCallback(self.assertEqual, True)
- d.addCallback(lambda _: self._enabledHelper(self.p.protocol,
- dR=['\x42']))
- return d
-
- def testNegotiationBlocksFurtherNegotiation(self):
- # Try to disable an option, then immediately try to enable it, then
- # immediately try to disable it. Ensure that the 2nd and 3rd calls
- # fail quickly with the right exception.
- s = self.p.getOptionState('\x24')
- s.him.state = 'yes'
- d2 = self.p.dont('\x24') # fires after the first line of _final
-
- def _do(x):
- d = self.p.do('\x24')
- return self.assertFailure(d, telnet.AlreadyNegotiating)
-
- def _dont(x):
- d = self.p.dont('\x24')
- return self.assertFailure(d, telnet.AlreadyNegotiating)
-
- def _final(x):
- self.p.dataReceived(telnet.IAC + telnet.WONT + '\x24')
- # an assertion that only passes if d2 has fired
- self._enabledHelper(self.p.protocol, dR=['\x24'])
- # Make sure we allow this
- self.p.protocol.remoteEnableable = ('\x24',)
- d = self.p.do('\x24')
- self.p.dataReceived(telnet.IAC + telnet.WILL + '\x24')
- d.addCallback(self.assertEqual, True)
- d.addCallback(lambda _: self._enabledHelper(self.p.protocol,
- eR=['\x24'],
- dR=['\x24']))
- return d
-
- d = _do(None)
- d.addCallback(_dont)
- d.addCallback(_final)
- return d
-
- def testSuperfluousDisableRequestRaises(self):
- # Try to disable a disabled option. Make sure it fails properly.
- d = self.p.dont('\xab')
- return self.assertFailure(d, telnet.AlreadyDisabled)
-
- def testSuperfluousEnableRequestRaises(self):
- # Try to disable a disabled option. Make sure it fails properly.
- s = self.p.getOptionState('\xab')
- s.him.state = 'yes'
- d = self.p.do('\xab')
- return self.assertFailure(d, telnet.AlreadyEnabled)
-
- def testLostConnectionFailsDeferreds(self):
- d1 = self.p.do('\x12')
- d2 = self.p.do('\x23')
- d3 = self.p.do('\x34')
-
- class TestException(Exception):
- pass
-
- self.p.connectionLost(TestException("Total failure!"))
-
- d1 = self.assertFailure(d1, TestException)
- d2 = self.assertFailure(d2, TestException)
- d3 = self.assertFailure(d3, TestException)
- return defer.gatherResults([d1, d2, d3])
-
-
-class TestTelnet(telnet.Telnet):
- """
- A trivial extension of the telnet protocol class useful to unit tests.
- """
- def __init__(self):
- telnet.Telnet.__init__(self)
- self.events = []
-
-
- def applicationDataReceived(self, bytes):
- """
- Record the given data in C{self.events}.
- """
- self.events.append(('bytes', bytes))
-
-
- def unhandledCommand(self, command, bytes):
- """
- Record the given command in C{self.events}.
- """
- self.events.append(('command', command, bytes))
-
-
- def unhandledSubnegotiation(self, command, bytes):
- """
- Record the given subnegotiation command in C{self.events}.
- """
- self.events.append(('negotiate', command, bytes))
-
-
-
-class TelnetTests(unittest.TestCase):
- """
- Tests for L{telnet.Telnet}.
-
- L{telnet.Telnet} implements the TELNET protocol (RFC 854), including option
- and suboption negotiation, and option state tracking.
- """
- def setUp(self):
- """
- Create an unconnected L{telnet.Telnet} to be used by tests.
- """
- self.protocol = TestTelnet()
-
-
- def test_enableLocal(self):
- """
- L{telnet.Telnet.enableLocal} should reject all options, since
- L{telnet.Telnet} does not know how to implement any options.
- """
- self.assertFalse(self.protocol.enableLocal('\0'))
-
-
- def test_enableRemote(self):
- """
- L{telnet.Telnet.enableRemote} should reject all options, since
- L{telnet.Telnet} does not know how to implement any options.
- """
- self.assertFalse(self.protocol.enableRemote('\0'))
-
-
- def test_disableLocal(self):
- """
- It is an error for L{telnet.Telnet.disableLocal} to be called, since
- L{telnet.Telnet.enableLocal} will never allow any options to be enabled
- locally. If a subclass overrides enableLocal, it must also override
- disableLocal.
- """
- self.assertRaises(NotImplementedError, self.protocol.disableLocal, '\0')
-
-
- def test_disableRemote(self):
- """
- It is an error for L{telnet.Telnet.disableRemote} to be called, since
- L{telnet.Telnet.enableRemote} will never allow any options to be
- enabled remotely. If a subclass overrides enableRemote, it must also
- override disableRemote.
- """
- self.assertRaises(NotImplementedError, self.protocol.disableRemote, '\0')
-
-
- def test_requestNegotiation(self):
- """
- L{telnet.Telnet.requestNegotiation} formats the feature byte and the
- payload bytes into the subnegotiation format and sends them.
-
- See RFC 855.
- """
- transport = proto_helpers.StringTransport()
- self.protocol.makeConnection(transport)
- self.protocol.requestNegotiation('\x01', '\x02\x03')
- self.assertEqual(
- transport.value(),
- # IAC SB feature bytes IAC SE
- '\xff\xfa\x01\x02\x03\xff\xf0')
-
-
- def test_requestNegotiationEscapesIAC(self):
- """
- If the payload for a subnegotiation includes I{IAC}, it is escaped by
- L{telnet.Telnet.requestNegotiation} with another I{IAC}.
-
- See RFC 855.
- """
- transport = proto_helpers.StringTransport()
- self.protocol.makeConnection(transport)
- self.protocol.requestNegotiation('\x01', '\xff')
- self.assertEqual(
- transport.value(),
- '\xff\xfa\x01\xff\xff\xff\xf0')
-
-
- def _deliver(self, bytes, *expected):
- """
- Pass the given bytes to the protocol's C{dataReceived} method and
- assert that the given events occur.
- """
- received = self.protocol.events = []
- self.protocol.dataReceived(bytes)
- self.assertEqual(received, list(expected))
-
-
- def test_oneApplicationDataByte(self):
- """
- One application-data byte in the default state gets delivered right
- away.
- """
- self._deliver('a', ('bytes', 'a'))
-
-
- def test_twoApplicationDataBytes(self):
- """
- Two application-data bytes in the default state get delivered
- together.
- """
- self._deliver('bc', ('bytes', 'bc'))
-
-
- def test_threeApplicationDataBytes(self):
- """
- Three application-data bytes followed by a control byte get
- delivered, but the control byte doesn't.
- """
- self._deliver('def' + telnet.IAC, ('bytes', 'def'))
-
-
- def test_escapedControl(self):
- """
- IAC in the escaped state gets delivered and so does another
- application-data byte following it.
- """
- self._deliver(telnet.IAC)
- self._deliver(telnet.IAC + 'g', ('bytes', telnet.IAC + 'g'))
-
-
- def test_carriageReturn(self):
- """
- A carriage return only puts the protocol into the newline state. A
- linefeed in the newline state causes just the newline to be
- delivered. A nul in the newline state causes a carriage return to
- be delivered. An IAC in the newline state causes a carriage return
- to be delivered and puts the protocol into the escaped state.
- Anything else causes a carriage return and that thing to be
- delivered.
- """
- self._deliver('\r')
- self._deliver('\n', ('bytes', '\n'))
- self._deliver('\r\n', ('bytes', '\n'))
-
- self._deliver('\r')
- self._deliver('\0', ('bytes', '\r'))
- self._deliver('\r\0', ('bytes', '\r'))
-
- self._deliver('\r')
- self._deliver('a', ('bytes', '\ra'))
- self._deliver('\ra', ('bytes', '\ra'))
-
- self._deliver('\r')
- self._deliver(
- telnet.IAC + telnet.IAC + 'x', ('bytes', '\r' + telnet.IAC + 'x'))
-
-
- def test_applicationDataBeforeSimpleCommand(self):
- """
- Application bytes received before a command are delivered before the
- command is processed.
- """
- self._deliver(
- 'x' + telnet.IAC + telnet.NOP,
- ('bytes', 'x'), ('command', telnet.NOP, None))
-
-
- def test_applicationDataBeforeCommand(self):
- """
- Application bytes received before a WILL/WONT/DO/DONT are delivered
- before the command is processed.
- """
- self.protocol.commandMap = {}
- self._deliver(
- 'y' + telnet.IAC + telnet.WILL + '\x00',
- ('bytes', 'y'), ('command', telnet.WILL, '\x00'))
-
-
- def test_applicationDataBeforeSubnegotiation(self):
- """
- Application bytes received before a subnegotiation command are
- delivered before the negotiation is processed.
- """
- self._deliver(
- 'z' + telnet.IAC + telnet.SB + 'Qx' + telnet.IAC + telnet.SE,
- ('bytes', 'z'), ('negotiate', 'Q', ['x']))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py
deleted file mode 100755
index 1d688703..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_text -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-
-from twisted.conch.insults import helper, text
-
-A = text.attributes
-
-class Serialization(unittest.TestCase):
- def setUp(self):
- self.attrs = helper.CharacterAttribute()
-
- def testTrivial(self):
- self.assertEqual(
- text.flatten(A.normal['Hello, world.'], self.attrs),
- 'Hello, world.')
-
- def testBold(self):
- self.assertEqual(
- text.flatten(A.bold['Hello, world.'], self.attrs),
- '\x1b[1mHello, world.')
-
- def testUnderline(self):
- self.assertEqual(
- text.flatten(A.underline['Hello, world.'], self.attrs),
- '\x1b[4mHello, world.')
-
- def testBlink(self):
- self.assertEqual(
- text.flatten(A.blink['Hello, world.'], self.attrs),
- '\x1b[5mHello, world.')
-
- def testReverseVideo(self):
- self.assertEqual(
- text.flatten(A.reverseVideo['Hello, world.'], self.attrs),
- '\x1b[7mHello, world.')
-
- def testMinus(self):
- self.assertEqual(
- text.flatten(
- A.bold[A.blink['Hello', -A.bold[' world'], '.']],
- self.attrs),
- '\x1b[1;5mHello\x1b[0;5m world\x1b[1;5m.')
-
- def testForeground(self):
- self.assertEqual(
- text.flatten(
- A.normal[A.fg.red['Hello, '], A.fg.green['world!']],
- self.attrs),
- '\x1b[31mHello, \x1b[32mworld!')
-
- def testBackground(self):
- self.assertEqual(
- text.flatten(
- A.normal[A.bg.red['Hello, '], A.bg.green['world!']],
- self.attrs),
- '\x1b[41mHello, \x1b[42mworld!')
-
-
-class EfficiencyTestCase(unittest.TestCase):
- todo = ("flatten() isn't quite stateful enough to avoid emitting a few extra bytes in "
- "certain circumstances, so these tests fail. The failures take the form of "
- "additional elements in the ;-delimited character attribute lists. For example, "
- "\\x1b[0;31;46m might be emitted instead of \\x[46m, even if 31 has already been "
- "activated and no conflicting attributes are set which need to be cleared.")
-
- def setUp(self):
- self.attrs = helper.CharacterAttribute()
-
- def testComplexStructure(self):
- output = A.normal[
- A.bold[
- A.bg.cyan[
- A.fg.red[
- "Foreground Red, Background Cyan, Bold",
- A.blink[
- "Blinking"],
- -A.bold[
- "Foreground Red, Background Cyan, normal"]],
- A.fg.green[
- "Foreground Green, Background Cyan, Bold"]]]]
-
- self.assertEqual(
- text.flatten(output, self.attrs),
- "\x1b[1;31;46mForeground Red, Background Cyan, Bold"
- "\x1b[5mBlinking"
- "\x1b[0;31;46mForeground Red, Background Cyan, normal"
- "\x1b[1;32;46mForeground Green, Background Cyan, Bold")
-
- def testNesting(self):
- self.assertEqual(
- text.flatten(A.bold['Hello, ', A.underline['world.']], self.attrs),
- '\x1b[1mHello, \x1b[4mworld.')
-
- self.assertEqual(
- text.flatten(
- A.bold[A.reverseVideo['Hello, ', A.normal['world'], '.']],
- self.attrs),
- '\x1b[1;7mHello, \x1b[0mworld\x1b[1;7m.')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py
deleted file mode 100755
index 8b801b0b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py
+++ /dev/null
@@ -1,2225 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for ssh/transport.py and the classes therein.
-"""
-
-try:
- import pyasn1
-except ImportError:
- pyasn1 = None
-
-try:
- import Crypto.Cipher.DES3
-except ImportError:
- Crypto = None
-
-if pyasn1 is not None and Crypto is not None:
- dependencySkip = None
- from twisted.conch.ssh import transport, keys, factory
- from twisted.conch.test import keydata
-else:
- if pyasn1 is None:
- dependencySkip = "Cannot run without PyASN1"
- elif Crypto is None:
- dependencySkip = "can't run w/o PyCrypto"
-
- class transport: # fictional modules to make classes work
- class SSHTransportBase: pass
- class SSHServerTransport: pass
- class SSHClientTransport: pass
- class factory:
- class SSHFactory:
- pass
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.protocols import loopback
-from twisted.python import randbytes
-from twisted.python.reflect import qual, getClass
-from twisted.python.hashlib import md5, sha1
-from twisted.conch.ssh import address, service, common
-from twisted.test import proto_helpers
-
-from twisted.conch.error import ConchError
-
-class MockTransportBase(transport.SSHTransportBase):
- """
- A base class for the client and server protocols. Stores the messages
- it receieves instead of ignoring them.
-
- @ivar errors: a list of tuples: (reasonCode, description)
- @ivar unimplementeds: a list of integers: sequence number
- @ivar debugs: a list of tuples: (alwaysDisplay, message, lang)
- @ivar ignoreds: a list of strings: ignored data
- """
-
- def connectionMade(self):
- """
- Set up instance variables.
- """
- transport.SSHTransportBase.connectionMade(self)
- self.errors = []
- self.unimplementeds = []
- self.debugs = []
- self.ignoreds = []
- self.gotUnsupportedVersion = None
-
-
- def _unsupportedVersionReceived(self, remoteVersion):
- """
- Intercept unsupported version call.
-
- @type remoteVersion: C{str}
- """
- self.gotUnsupportedVersion = remoteVersion
- return transport.SSHTransportBase._unsupportedVersionReceived(
- self, remoteVersion)
-
-
- def receiveError(self, reasonCode, description):
- """
- Store any errors received.
-
- @type reasonCode: C{int}
- @type description: C{str}
- """
- self.errors.append((reasonCode, description))
-
-
- def receiveUnimplemented(self, seqnum):
- """
- Store any unimplemented packet messages.
-
- @type seqnum: C{int}
- """
- self.unimplementeds.append(seqnum)
-
-
- def receiveDebug(self, alwaysDisplay, message, lang):
- """
- Store any debug messages.
-
- @type alwaysDisplay: C{bool}
- @type message: C{str}
- @type lang: C{str}
- """
- self.debugs.append((alwaysDisplay, message, lang))
-
-
- def ssh_IGNORE(self, packet):
- """
- Store any ignored data.
-
- @type packet: C{str}
- """
- self.ignoreds.append(packet)
-
-
-class MockCipher(object):
- """
- A mocked-up version of twisted.conch.ssh.transport.SSHCiphers.
- """
- outCipType = 'test'
- encBlockSize = 6
- inCipType = 'test'
- decBlockSize = 6
- inMACType = 'test'
- outMACType = 'test'
- verifyDigestSize = 1
- usedEncrypt = False
- usedDecrypt = False
- outMAC = (None, '', '', 1)
- inMAC = (None, '', '', 1)
- keys = ()
-
-
- def encrypt(self, x):
- """
- Called to encrypt the packet. Simply record that encryption was used
- and return the data unchanged.
- """
- self.usedEncrypt = True
- if (len(x) % self.encBlockSize) != 0:
- raise RuntimeError("length %i modulo blocksize %i is not 0: %i" %
- (len(x), self.encBlockSize, len(x) % self.encBlockSize))
- return x
-
-
- def decrypt(self, x):
- """
- Called to decrypt the packet. Simply record that decryption was used
- and return the data unchanged.
- """
- self.usedDecrypt = True
- if (len(x) % self.encBlockSize) != 0:
- raise RuntimeError("length %i modulo blocksize %i is not 0: %i" %
- (len(x), self.decBlockSize, len(x) % self.decBlockSize))
- return x
-
-
- def makeMAC(self, outgoingPacketSequence, payload):
- """
- Make a Message Authentication Code by sending the character value of
- the outgoing packet.
- """
- return chr(outgoingPacketSequence)
-
-
- def verify(self, incomingPacketSequence, packet, macData):
- """
- Verify the Message Authentication Code by checking that the packet
- sequence number is the same.
- """
- return chr(incomingPacketSequence) == macData
-
-
- def setKeys(self, ivOut, keyOut, ivIn, keyIn, macIn, macOut):
- """
- Record the keys.
- """
- self.keys = (ivOut, keyOut, ivIn, keyIn, macIn, macOut)
-
-
-
-class MockCompression:
- """
- A mocked-up compression, based on the zlib interface. Instead of
- compressing, it reverses the data and adds a 0x66 byte to the end.
- """
-
-
- def compress(self, payload):
- return payload[::-1] # reversed
-
-
- def decompress(self, payload):
- return payload[:-1][::-1]
-
-
- def flush(self, kind):
- return '\x66'
-
-
-
-class MockService(service.SSHService):
- """
- A mocked-up service, based on twisted.conch.ssh.service.SSHService.
-
- @ivar started: True if this service has been started.
- @ivar stopped: True if this service has been stopped.
- """
- name = "MockService"
- started = False
- stopped = False
- protocolMessages = {0xff: "MSG_TEST", 71: "MSG_fiction"}
-
-
- def logPrefix(self):
- return "MockService"
-
-
- def serviceStarted(self):
- """
- Record that the service was started.
- """
- self.started = True
-
-
- def serviceStopped(self):
- """
- Record that the service was stopped.
- """
- self.stopped = True
-
-
- def ssh_TEST(self, packet):
- """
- A message that this service responds to.
- """
- self.transport.sendPacket(0xff, packet)
-
-
-class MockFactory(factory.SSHFactory):
- """
- A mocked-up factory based on twisted.conch.ssh.factory.SSHFactory.
- """
- services = {
- 'ssh-userauth': MockService}
-
-
- def getPublicKeys(self):
- """
- Return the public keys that authenticate this server.
- """
- return {
- 'ssh-rsa': keys.Key.fromString(keydata.publicRSA_openssh),
- 'ssh-dsa': keys.Key.fromString(keydata.publicDSA_openssh)}
-
-
- def getPrivateKeys(self):
- """
- Return the private keys that authenticate this server.
- """
- return {
- 'ssh-rsa': keys.Key.fromString(keydata.privateRSA_openssh),
- 'ssh-dsa': keys.Key.fromString(keydata.privateDSA_openssh)}
-
-
- def getPrimes(self):
- """
- Return the Diffie-Hellman primes that can be used for the
- diffie-hellman-group-exchange-sha1 key exchange.
- """
- return {
- 1024: ((2, transport.DH_PRIME),),
- 2048: ((3, transport.DH_PRIME),),
- 4096: ((5, 7),)}
-
-
-
-class MockOldFactoryPublicKeys(MockFactory):
- """
- The old SSHFactory returned mappings from key names to strings from
- getPublicKeys(). We return those here for testing.
- """
-
-
- def getPublicKeys(self):
- """
- We used to map key types to public key blobs as strings.
- """
- keys = MockFactory.getPublicKeys(self)
- for name, key in keys.items()[:]:
- keys[name] = key.blob()
- return keys
-
-
-
-class MockOldFactoryPrivateKeys(MockFactory):
- """
- The old SSHFactory returned mappings from key names to PyCrypto key
- objects from getPrivateKeys(). We return those here for testing.
- """
-
-
- def getPrivateKeys(self):
- """
- We used to map key types to PyCrypto key objects.
- """
- keys = MockFactory.getPrivateKeys(self)
- for name, key in keys.items()[:]:
- keys[name] = key.keyObject
- return keys
-
-
-class TransportTestCase(unittest.TestCase):
- """
- Base class for transport test cases.
- """
- klass = None
-
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
-
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
-
- def setUp(self):
- self.transport = proto_helpers.StringTransport()
- self.proto = self.klass()
- self.packets = []
- def secureRandom(len):
- """
- Return a consistent entropy value
- """
- return '\x99' * len
- self.oldSecureRandom = randbytes.secureRandom
- randbytes.secureRandom = secureRandom
- def stubSendPacket(messageType, payload):
- self.packets.append((messageType, payload))
- self.proto.makeConnection(self.transport)
- # we just let the kex packet go into the transport
- self.proto.sendPacket = stubSendPacket
-
-
- def finishKeyExchange(self, proto):
- """
- Deliver enough additional messages to C{proto} so that the key exchange
- which is started in L{SSHTransportBase.connectionMade} completes and
- non-key exchange messages can be sent and received.
- """
- proto.dataReceived("SSH-2.0-BogoClient-1.2i\r\n")
- proto.dispatchMessage(
- transport.MSG_KEXINIT, self._A_KEXINIT_MESSAGE)
- proto._keySetup("foo", "bar")
- # SSHTransportBase can't handle MSG_NEWKEYS, or it would be the right
- # thing to deliver next. _newKeys won't work either, because
- # sendKexInit (probably) hasn't been called. sendKexInit is
- # responsible for setting up certain state _newKeys relies on. So,
- # just change the key exchange state to what it would be when key
- # exchange is finished.
- proto._keyExchangeState = proto._KEY_EXCHANGE_NONE
-
-
- def tearDown(self):
- randbytes.secureRandom = self.oldSecureRandom
- self.oldSecureRandom = None
-
-
- def simulateKeyExchange(self, sharedSecret, exchangeHash):
- """
- Finish a key exchange by calling C{_keySetup} with the given arguments.
- Also do extra whitebox stuff to satisfy that method's assumption that
- some kind of key exchange has actually taken place.
- """
- self.proto._keyExchangeState = self.proto._KEY_EXCHANGE_REQUESTED
- self.proto._blockedByKeyExchange = []
- self.proto._keySetup(sharedSecret, exchangeHash)
-
-
-
-class BaseSSHTransportTestCase(TransportTestCase):
- """
- Test TransportBase. It implements the non-server/client specific
- parts of the SSH transport protocol.
- """
-
- klass = MockTransportBase
-
- _A_KEXINIT_MESSAGE = (
- "\xAA" * 16 +
- common.NS('diffie-hellman-group1-sha1') +
- common.NS('ssh-rsa') +
- common.NS('aes256-ctr') +
- common.NS('aes256-ctr') +
- common.NS('hmac-sha1') +
- common.NS('hmac-sha1') +
- common.NS('none') +
- common.NS('none') +
- common.NS('') +
- common.NS('') +
- '\x00' + '\x00\x00\x00\x00')
-
- def test_sendVersion(self):
- """
- Test that the first thing sent over the connection is the version
- string.
- """
- # the other setup was done in the setup method
- self.assertEqual(self.transport.value().split('\r\n', 1)[0],
- "SSH-2.0-Twisted")
-
-
- def test_sendPacketPlain(self):
- """
- Test that plain (unencrypted, uncompressed) packets are sent
- correctly. The format is::
- uint32 length (including type and padding length)
- byte padding length
- byte type
- bytes[length-padding length-2] data
- bytes[padding length] padding
- """
- proto = MockTransportBase()
- proto.makeConnection(self.transport)
- self.finishKeyExchange(proto)
- self.transport.clear()
- message = ord('A')
- payload = 'BCDEFG'
- proto.sendPacket(message, payload)
- value = self.transport.value()
- self.assertEqual(value, '\x00\x00\x00\x0c\x04ABCDEFG\x99\x99\x99\x99')
-
-
- def test_sendPacketEncrypted(self):
- """
- Test that packets sent while encryption is enabled are sent
- correctly. The whole packet should be encrypted.
- """
- proto = MockTransportBase()
- proto.makeConnection(self.transport)
- self.finishKeyExchange(proto)
- proto.currentEncryptions = testCipher = MockCipher()
- message = ord('A')
- payload = 'BC'
- self.transport.clear()
- proto.sendPacket(message, payload)
- self.assertTrue(testCipher.usedEncrypt)
- value = self.transport.value()
- self.assertEqual(
- value,
- # Four byte length prefix
- '\x00\x00\x00\x08'
- # One byte padding length
- '\x04'
- # The actual application data
- 'ABC'
- # "Random" padding - see the secureRandom monkeypatch in setUp
- '\x99\x99\x99\x99'
- # The MAC
- '\x02')
-
-
- def test_sendPacketCompressed(self):
- """
- Test that packets sent while compression is enabled are sent
- correctly. The packet type and data should be encrypted.
- """
- proto = MockTransportBase()
- proto.makeConnection(self.transport)
- self.finishKeyExchange(proto)
- proto.outgoingCompression = MockCompression()
- self.transport.clear()
- proto.sendPacket(ord('A'), 'B')
- value = self.transport.value()
- self.assertEqual(
- value,
- '\x00\x00\x00\x0c\x08BA\x66\x99\x99\x99\x99\x99\x99\x99\x99')
-
-
- def test_sendPacketBoth(self):
- """
- Test that packets sent while compression and encryption are
- enabled are sent correctly. The packet type and data should be
- compressed and then the whole packet should be encrypted.
- """
- proto = MockTransportBase()
- proto.makeConnection(self.transport)
- self.finishKeyExchange(proto)
- proto.currentEncryptions = testCipher = MockCipher()
- proto.outgoingCompression = MockCompression()
- message = ord('A')
- payload = 'BC'
- self.transport.clear()
- proto.sendPacket(message, payload)
- self.assertTrue(testCipher.usedEncrypt)
- value = self.transport.value()
- self.assertEqual(
- value,
- # Four byte length prefix
- '\x00\x00\x00\x0e'
- # One byte padding length
- '\x09'
- # Compressed application data
- 'CBA\x66'
- # "Random" padding - see the secureRandom monkeypatch in setUp
- '\x99\x99\x99\x99\x99\x99\x99\x99\x99'
- # The MAC
- '\x02')
-
-
- def test_getPacketPlain(self):
- """
- Test that packets are retrieved correctly out of the buffer when
- no encryption is enabled.
- """
- proto = MockTransportBase()
- proto.makeConnection(self.transport)
- self.finishKeyExchange(proto)
- self.transport.clear()
- proto.sendPacket(ord('A'), 'BC')
- proto.buf = self.transport.value() + 'extra'
- self.assertEqual(proto.getPacket(), 'ABC')
- self.assertEqual(proto.buf, 'extra')
-
-
- def test_getPacketEncrypted(self):
- """
- Test that encrypted packets are retrieved correctly.
- See test_sendPacketEncrypted.
- """
- proto = MockTransportBase()
- proto.sendKexInit = lambda: None # don't send packets
- proto.makeConnection(self.transport)
- self.transport.clear()
- proto.currentEncryptions = testCipher = MockCipher()
- proto.sendPacket(ord('A'), 'BCD')
- value = self.transport.value()
- proto.buf = value[:MockCipher.decBlockSize]
- self.assertEqual(proto.getPacket(), None)
- self.assertTrue(testCipher.usedDecrypt)
- self.assertEqual(proto.first, '\x00\x00\x00\x0e\x09A')
- proto.buf += value[MockCipher.decBlockSize:]
- self.assertEqual(proto.getPacket(), 'ABCD')
- self.assertEqual(proto.buf, '')
-
-
- def test_getPacketCompressed(self):
- """
- Test that compressed packets are retrieved correctly. See
- test_sendPacketCompressed.
- """
- proto = MockTransportBase()
- proto.makeConnection(self.transport)
- self.finishKeyExchange(proto)
- self.transport.clear()
- proto.outgoingCompression = MockCompression()
- proto.incomingCompression = proto.outgoingCompression
- proto.sendPacket(ord('A'), 'BCD')
- proto.buf = self.transport.value()
- self.assertEqual(proto.getPacket(), 'ABCD')
-
-
- def test_getPacketBoth(self):
- """
- Test that compressed and encrypted packets are retrieved correctly.
- See test_sendPacketBoth.
- """
- proto = MockTransportBase()
- proto.sendKexInit = lambda: None
- proto.makeConnection(self.transport)
- self.transport.clear()
- proto.currentEncryptions = MockCipher()
- proto.outgoingCompression = MockCompression()
- proto.incomingCompression = proto.outgoingCompression
- proto.sendPacket(ord('A'), 'BCDEFG')
- proto.buf = self.transport.value()
- self.assertEqual(proto.getPacket(), 'ABCDEFG')
-
-
- def test_ciphersAreValid(self):
- """
- Test that all the supportedCiphers are valid.
- """
- ciphers = transport.SSHCiphers('A', 'B', 'C', 'D')
- iv = key = '\x00' * 16
- for cipName in self.proto.supportedCiphers:
- self.assertTrue(ciphers._getCipher(cipName, iv, key))
-
-
- def test_sendKexInit(self):
- """
- Test that the KEXINIT (key exchange initiation) message is sent
- correctly. Payload::
- bytes[16] cookie
- string key exchange algorithms
- string public key algorithms
- string outgoing ciphers
- string incoming ciphers
- string outgoing MACs
- string incoming MACs
- string outgoing compressions
- string incoming compressions
- bool first packet follows
- uint32 0
- """
- value = self.transport.value().split('\r\n', 1)[1]
- self.proto.buf = value
- packet = self.proto.getPacket()
- self.assertEqual(packet[0], chr(transport.MSG_KEXINIT))
- self.assertEqual(packet[1:17], '\x99' * 16)
- (kex, pubkeys, ciphers1, ciphers2, macs1, macs2, compressions1,
- compressions2, languages1, languages2,
- buf) = common.getNS(packet[17:], 10)
-
- self.assertEqual(kex, ','.join(self.proto.supportedKeyExchanges))
- self.assertEqual(pubkeys, ','.join(self.proto.supportedPublicKeys))
- self.assertEqual(ciphers1, ','.join(self.proto.supportedCiphers))
- self.assertEqual(ciphers2, ','.join(self.proto.supportedCiphers))
- self.assertEqual(macs1, ','.join(self.proto.supportedMACs))
- self.assertEqual(macs2, ','.join(self.proto.supportedMACs))
- self.assertEqual(compressions1,
- ','.join(self.proto.supportedCompressions))
- self.assertEqual(compressions2,
- ','.join(self.proto.supportedCompressions))
- self.assertEqual(languages1, ','.join(self.proto.supportedLanguages))
- self.assertEqual(languages2, ','.join(self.proto.supportedLanguages))
- self.assertEqual(buf, '\x00' * 5)
-
-
- def test_receiveKEXINITReply(self):
- """
- Immediately after connecting, the transport expects a KEXINIT message
- and does not reply to it.
- """
- self.transport.clear()
- self.proto.dispatchMessage(
- transport.MSG_KEXINIT, self._A_KEXINIT_MESSAGE)
- self.assertEqual(self.packets, [])
-
-
- def test_sendKEXINITReply(self):
- """
- When a KEXINIT message is received which is not a reply to an earlier
- KEXINIT message which was sent, a KEXINIT reply is sent.
- """
- self.finishKeyExchange(self.proto)
- del self.packets[:]
-
- self.proto.dispatchMessage(
- transport.MSG_KEXINIT, self._A_KEXINIT_MESSAGE)
- self.assertEqual(len(self.packets), 1)
- self.assertEqual(self.packets[0][0], transport.MSG_KEXINIT)
-
-
- def test_sendKexInitTwiceFails(self):
- """
- A new key exchange cannot be started while a key exchange is already in
- progress. If an attempt is made to send a I{KEXINIT} message using
- L{SSHTransportBase.sendKexInit} while a key exchange is in progress
- causes that method to raise a L{RuntimeError}.
- """
- self.assertRaises(RuntimeError, self.proto.sendKexInit)
-
-
- def test_sendKexInitBlocksOthers(self):
- """
- After L{SSHTransportBase.sendKexInit} has been called, messages types
- other than the following are queued and not sent until after I{NEWKEYS}
- is sent by L{SSHTransportBase._keySetup}.
-
- RFC 4253, section 7.1.
- """
- # sendKexInit is called by connectionMade, which is called in setUp.
- # So we're in the state already.
- disallowedMessageTypes = [
- transport.MSG_SERVICE_REQUEST,
- transport.MSG_KEXINIT,
- ]
-
- # Drop all the bytes sent by setUp, they're not relevant to this test.
- self.transport.clear()
-
- # Get rid of the sendPacket monkey patch, we are testing the behavior
- # of sendPacket.
- del self.proto.sendPacket
-
- for messageType in disallowedMessageTypes:
- self.proto.sendPacket(messageType, 'foo')
- self.assertEqual(self.transport.value(), "")
-
- self.finishKeyExchange(self.proto)
- # Make the bytes written to the transport cleartext so it's easier to
- # make an assertion about them.
- self.proto.nextEncryptions = MockCipher()
-
- # Pseudo-deliver the peer's NEWKEYS message, which should flush the
- # messages which were queued above.
- self.proto._newKeys()
- self.assertEqual(self.transport.value().count("foo"), 2)
-
-
- def test_sendDebug(self):
- """
- Test that debug messages are sent correctly. Payload::
- bool always display
- string debug message
- string language
- """
- self.proto.sendDebug("test", True, 'en')
- self.assertEqual(
- self.packets,
- [(transport.MSG_DEBUG,
- "\x01\x00\x00\x00\x04test\x00\x00\x00\x02en")])
-
-
- def test_receiveDebug(self):
- """
- Test that debug messages are received correctly. See test_sendDebug.
- """
- self.proto.dispatchMessage(
- transport.MSG_DEBUG,
- '\x01\x00\x00\x00\x04test\x00\x00\x00\x02en')
- self.assertEqual(self.proto.debugs, [(True, 'test', 'en')])
-
-
- def test_sendIgnore(self):
- """
- Test that ignored messages are sent correctly. Payload::
- string ignored data
- """
- self.proto.sendIgnore("test")
- self.assertEqual(
- self.packets, [(transport.MSG_IGNORE,
- '\x00\x00\x00\x04test')])
-
-
- def test_receiveIgnore(self):
- """
- Test that ignored messages are received correctly. See
- test_sendIgnore.
- """
- self.proto.dispatchMessage(transport.MSG_IGNORE, 'test')
- self.assertEqual(self.proto.ignoreds, ['test'])
-
-
- def test_sendUnimplemented(self):
- """
- Test that unimplemented messages are sent correctly. Payload::
- uint32 sequence number
- """
- self.proto.sendUnimplemented()
- self.assertEqual(
- self.packets, [(transport.MSG_UNIMPLEMENTED,
- '\x00\x00\x00\x00')])
-
-
- def test_receiveUnimplemented(self):
- """
- Test that unimplemented messages are received correctly. See
- test_sendUnimplemented.
- """
- self.proto.dispatchMessage(transport.MSG_UNIMPLEMENTED,
- '\x00\x00\x00\xff')
- self.assertEqual(self.proto.unimplementeds, [255])
-
-
- def test_sendDisconnect(self):
- """
- Test that disconnection messages are sent correctly. Payload::
- uint32 reason code
- string reason description
- string language
- """
- disconnected = [False]
- def stubLoseConnection():
- disconnected[0] = True
- self.transport.loseConnection = stubLoseConnection
- self.proto.sendDisconnect(0xff, "test")
- self.assertEqual(
- self.packets,
- [(transport.MSG_DISCONNECT,
- "\x00\x00\x00\xff\x00\x00\x00\x04test\x00\x00\x00\x00")])
- self.assertTrue(disconnected[0])
-
-
- def test_receiveDisconnect(self):
- """
- Test that disconnection messages are received correctly. See
- test_sendDisconnect.
- """
- disconnected = [False]
- def stubLoseConnection():
- disconnected[0] = True
- self.transport.loseConnection = stubLoseConnection
- self.proto.dispatchMessage(transport.MSG_DISCONNECT,
- '\x00\x00\x00\xff\x00\x00\x00\x04test')
- self.assertEqual(self.proto.errors, [(255, 'test')])
- self.assertTrue(disconnected[0])
-
-
- def test_dataReceived(self):
- """
- Test that dataReceived parses packets and dispatches them to
- ssh_* methods.
- """
- kexInit = [False]
- def stubKEXINIT(packet):
- kexInit[0] = True
- self.proto.ssh_KEXINIT = stubKEXINIT
- self.proto.dataReceived(self.transport.value())
- self.assertTrue(self.proto.gotVersion)
- self.assertEqual(self.proto.ourVersionString,
- self.proto.otherVersionString)
- self.assertTrue(kexInit[0])
-
-
- def test_service(self):
- """
- Test that the transport can set the running service and dispatches
- packets to the service's packetReceived method.
- """
- service = MockService()
- self.proto.setService(service)
- self.assertEqual(self.proto.service, service)
- self.assertTrue(service.started)
- self.proto.dispatchMessage(0xff, "test")
- self.assertEqual(self.packets, [(0xff, "test")])
-
- service2 = MockService()
- self.proto.setService(service2)
- self.assertTrue(service2.started)
- self.assertTrue(service.stopped)
-
- self.proto.connectionLost(None)
- self.assertTrue(service2.stopped)
-
-
- def test_avatar(self):
- """
- Test that the transport notifies the avatar of disconnections.
- """
- disconnected = [False]
- def logout():
- disconnected[0] = True
- self.proto.logoutFunction = logout
- self.proto.avatar = True
-
- self.proto.connectionLost(None)
- self.assertTrue(disconnected[0])
-
-
- def test_isEncrypted(self):
- """
- Test that the transport accurately reflects its encrypted status.
- """
- self.assertFalse(self.proto.isEncrypted('in'))
- self.assertFalse(self.proto.isEncrypted('out'))
- self.assertFalse(self.proto.isEncrypted('both'))
- self.proto.currentEncryptions = MockCipher()
- self.assertTrue(self.proto.isEncrypted('in'))
- self.assertTrue(self.proto.isEncrypted('out'))
- self.assertTrue(self.proto.isEncrypted('both'))
- self.proto.currentEncryptions = transport.SSHCiphers('none', 'none',
- 'none', 'none')
- self.assertFalse(self.proto.isEncrypted('in'))
- self.assertFalse(self.proto.isEncrypted('out'))
- self.assertFalse(self.proto.isEncrypted('both'))
-
- self.assertRaises(TypeError, self.proto.isEncrypted, 'bad')
-
-
- def test_isVerified(self):
- """
- Test that the transport accurately reflects its verified status.
- """
- self.assertFalse(self.proto.isVerified('in'))
- self.assertFalse(self.proto.isVerified('out'))
- self.assertFalse(self.proto.isVerified('both'))
- self.proto.currentEncryptions = MockCipher()
- self.assertTrue(self.proto.isVerified('in'))
- self.assertTrue(self.proto.isVerified('out'))
- self.assertTrue(self.proto.isVerified('both'))
- self.proto.currentEncryptions = transport.SSHCiphers('none', 'none',
- 'none', 'none')
- self.assertFalse(self.proto.isVerified('in'))
- self.assertFalse(self.proto.isVerified('out'))
- self.assertFalse(self.proto.isVerified('both'))
-
- self.assertRaises(TypeError, self.proto.isVerified, 'bad')
-
-
- def test_loseConnection(self):
- """
- Test that loseConnection sends a disconnect message and closes the
- connection.
- """
- disconnected = [False]
- def stubLoseConnection():
- disconnected[0] = True
- self.transport.loseConnection = stubLoseConnection
- self.proto.loseConnection()
- self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT)
- self.assertEqual(self.packets[0][1][3],
- chr(transport.DISCONNECT_CONNECTION_LOST))
-
-
- def test_badVersion(self):
- """
- Test that the transport disconnects when it receives a bad version.
- """
- def testBad(version):
- self.packets = []
- self.proto.gotVersion = False
- disconnected = [False]
- def stubLoseConnection():
- disconnected[0] = True
- self.transport.loseConnection = stubLoseConnection
- for c in version + '\r\n':
- self.proto.dataReceived(c)
- self.assertTrue(disconnected[0])
- self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT)
- self.assertEqual(
- self.packets[0][1][3],
- chr(transport.DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED))
- testBad('SSH-1.5-OpenSSH')
- testBad('SSH-3.0-Twisted')
- testBad('GET / HTTP/1.1')
-
-
- def test_dataBeforeVersion(self):
- """
- Test that the transport ignores data sent before the version string.
- """
- proto = MockTransportBase()
- proto.makeConnection(proto_helpers.StringTransport())
- data = ("""here's some stuff beforehand
-here's some other stuff
-""" + proto.ourVersionString + "\r\n")
- [proto.dataReceived(c) for c in data]
- self.assertTrue(proto.gotVersion)
- self.assertEqual(proto.otherVersionString, proto.ourVersionString)
-
-
- def test_compatabilityVersion(self):
- """
- Test that the transport treats the compatbility version (1.99)
- as equivalent to version 2.0.
- """
- proto = MockTransportBase()
- proto.makeConnection(proto_helpers.StringTransport())
- proto.dataReceived("SSH-1.99-OpenSSH\n")
- self.assertTrue(proto.gotVersion)
- self.assertEqual(proto.otherVersionString, "SSH-1.99-OpenSSH")
-
-
- def test_supportedVersionsAreAllowed(self):
- """
- If an unusual SSH version is received and is included in
- C{supportedVersions}, an unsupported version error is not emitted.
- """
- proto = MockTransportBase()
- proto.supportedVersions = ("9.99", )
- proto.makeConnection(proto_helpers.StringTransport())
- proto.dataReceived("SSH-9.99-OpenSSH\n")
- self.assertFalse(proto.gotUnsupportedVersion)
-
-
- def test_unsupportedVersionsCallUnsupportedVersionReceived(self):
- """
- If an unusual SSH version is received and is not included in
- C{supportedVersions}, an unsupported version error is emitted.
- """
- proto = MockTransportBase()
- proto.supportedVersions = ("2.0", )
- proto.makeConnection(proto_helpers.StringTransport())
- proto.dataReceived("SSH-9.99-OpenSSH\n")
- self.assertEqual("9.99", proto.gotUnsupportedVersion)
-
-
- def test_badPackets(self):
- """
- Test that the transport disconnects with an error when it receives
- bad packets.
- """
- def testBad(packet, error=transport.DISCONNECT_PROTOCOL_ERROR):
- self.packets = []
- self.proto.buf = packet
- self.assertEqual(self.proto.getPacket(), None)
- self.assertEqual(len(self.packets), 1)
- self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT)
- self.assertEqual(self.packets[0][1][3], chr(error))
-
- testBad('\xff' * 8) # big packet
- testBad('\x00\x00\x00\x05\x00BCDE') # length not modulo blocksize
- oldEncryptions = self.proto.currentEncryptions
- self.proto.currentEncryptions = MockCipher()
- testBad('\x00\x00\x00\x08\x06AB123456', # bad MAC
- transport.DISCONNECT_MAC_ERROR)
- self.proto.currentEncryptions.decrypt = lambda x: x[:-1]
- testBad('\x00\x00\x00\x08\x06BCDEFGHIJK') # bad decryption
- self.proto.currentEncryptions = oldEncryptions
- self.proto.incomingCompression = MockCompression()
- def stubDecompress(payload):
- raise Exception('bad compression')
- self.proto.incomingCompression.decompress = stubDecompress
- testBad('\x00\x00\x00\x04\x00BCDE', # bad decompression
- transport.DISCONNECT_COMPRESSION_ERROR)
- self.flushLoggedErrors()
-
-
- def test_unimplementedPackets(self):
- """
- Test that unimplemented packet types cause MSG_UNIMPLEMENTED packets
- to be sent.
- """
- seqnum = self.proto.incomingPacketSequence
- def checkUnimplemented(seqnum=seqnum):
- self.assertEqual(self.packets[0][0],
- transport.MSG_UNIMPLEMENTED)
- self.assertEqual(self.packets[0][1][3], chr(seqnum))
- self.proto.packets = []
- seqnum += 1
-
- self.proto.dispatchMessage(40, '')
- checkUnimplemented()
- transport.messages[41] = 'MSG_fiction'
- self.proto.dispatchMessage(41, '')
- checkUnimplemented()
- self.proto.dispatchMessage(60, '')
- checkUnimplemented()
- self.proto.setService(MockService())
- self.proto.dispatchMessage(70, '')
- checkUnimplemented()
- self.proto.dispatchMessage(71, '')
- checkUnimplemented()
-
-
- def test_getKey(self):
- """
- Test that _getKey generates the correct keys.
- """
- self.proto.sessionID = 'EF'
-
- k1 = sha1('AB' + 'CD' + 'K' + self.proto.sessionID).digest()
- k2 = sha1('ABCD' + k1).digest()
- self.assertEqual(self.proto._getKey('K', 'AB', 'CD'), k1 + k2)
-
-
- def test_multipleClasses(self):
- """
- Test that multiple instances have distinct states.
- """
- proto = self.proto
- proto.dataReceived(self.transport.value())
- proto.currentEncryptions = MockCipher()
- proto.outgoingCompression = MockCompression()
- proto.incomingCompression = MockCompression()
- proto.setService(MockService())
- proto2 = MockTransportBase()
- proto2.makeConnection(proto_helpers.StringTransport())
- proto2.sendIgnore('')
- self.failIfEquals(proto.gotVersion, proto2.gotVersion)
- self.failIfEquals(proto.transport, proto2.transport)
- self.failIfEquals(proto.outgoingPacketSequence,
- proto2.outgoingPacketSequence)
- self.failIfEquals(proto.incomingPacketSequence,
- proto2.incomingPacketSequence)
- self.failIfEquals(proto.currentEncryptions,
- proto2.currentEncryptions)
- self.failIfEquals(proto.service, proto2.service)
-
-
-
-class ServerAndClientSSHTransportBaseCase:
- """
- Tests that need to be run on both the server and the client.
- """
-
-
- def checkDisconnected(self, kind=None):
- """
- Helper function to check if the transport disconnected.
- """
- if kind is None:
- kind = transport.DISCONNECT_PROTOCOL_ERROR
- self.assertEqual(self.packets[-1][0], transport.MSG_DISCONNECT)
- self.assertEqual(self.packets[-1][1][3], chr(kind))
-
-
- def connectModifiedProtocol(self, protoModification,
- kind=None):
- """
- Helper function to connect a modified protocol to the test protocol
- and test for disconnection.
- """
- if kind is None:
- kind = transport.DISCONNECT_KEY_EXCHANGE_FAILED
- proto2 = self.klass()
- protoModification(proto2)
- proto2.makeConnection(proto_helpers.StringTransport())
- self.proto.dataReceived(proto2.transport.value())
- if kind:
- self.checkDisconnected(kind)
- return proto2
-
-
- def test_disconnectIfCantMatchKex(self):
- """
- Test that the transport disconnects if it can't match the key
- exchange
- """
- def blankKeyExchanges(proto2):
- proto2.supportedKeyExchanges = []
- self.connectModifiedProtocol(blankKeyExchanges)
-
-
- def test_disconnectIfCantMatchKeyAlg(self):
- """
- Like test_disconnectIfCantMatchKex, but for the key algorithm.
- """
- def blankPublicKeys(proto2):
- proto2.supportedPublicKeys = []
- self.connectModifiedProtocol(blankPublicKeys)
-
-
- def test_disconnectIfCantMatchCompression(self):
- """
- Like test_disconnectIfCantMatchKex, but for the compression.
- """
- def blankCompressions(proto2):
- proto2.supportedCompressions = []
- self.connectModifiedProtocol(blankCompressions)
-
-
- def test_disconnectIfCantMatchCipher(self):
- """
- Like test_disconnectIfCantMatchKex, but for the encryption.
- """
- def blankCiphers(proto2):
- proto2.supportedCiphers = []
- self.connectModifiedProtocol(blankCiphers)
-
-
- def test_disconnectIfCantMatchMAC(self):
- """
- Like test_disconnectIfCantMatchKex, but for the MAC.
- """
- def blankMACs(proto2):
- proto2.supportedMACs = []
- self.connectModifiedProtocol(blankMACs)
-
- def test_getPeer(self):
- """
- Test that the transport's L{getPeer} method returns an
- L{SSHTransportAddress} with the L{IAddress} of the peer.
- """
- self.assertEqual(self.proto.getPeer(),
- address.SSHTransportAddress(
- self.proto.transport.getPeer()))
-
- def test_getHost(self):
- """
- Test that the transport's L{getHost} method returns an
- L{SSHTransportAddress} with the L{IAddress} of the host.
- """
- self.assertEqual(self.proto.getHost(),
- address.SSHTransportAddress(
- self.proto.transport.getHost()))
-
-
-
-class ServerSSHTransportTestCase(ServerAndClientSSHTransportBaseCase,
- TransportTestCase):
- """
- Tests for the SSHServerTransport.
- """
-
- klass = transport.SSHServerTransport
-
-
- def setUp(self):
- TransportTestCase.setUp(self)
- self.proto.factory = MockFactory()
- self.proto.factory.startFactory()
-
-
- def tearDown(self):
- TransportTestCase.tearDown(self)
- self.proto.factory.stopFactory()
- del self.proto.factory
-
-
- def test_KEXINIT(self):
- """
- Test that receiving a KEXINIT packet sets up the correct values on the
- server.
- """
- self.proto.dataReceived( 'SSH-2.0-Twisted\r\n\x00\x00\x01\xd4\t\x14'
- '\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99'
- '\x99\x00\x00\x00=diffie-hellman-group1-sha1,diffie-hellman-g'
- 'roup-exchange-sha1\x00\x00\x00\x0fssh-dss,ssh-rsa\x00\x00\x00'
- '\x85aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,ae'
- 's256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3d'
- 'es-ctr,3des-cbc\x00\x00\x00\x85aes128-ctr,aes128-cbc,aes192-c'
- 'tr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,b'
- 'lowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc\x00\x00\x00\x12hma'
- 'c-md5,hmac-sha1\x00\x00\x00\x12hmac-md5,hmac-sha1\x00\x00\x00'
- '\tnone,zlib\x00\x00\x00\tnone,zlib\x00\x00\x00\x00\x00\x00'
- '\x00\x00\x00\x00\x00\x00\x00\x99\x99\x99\x99\x99\x99\x99\x99'
- '\x99')
- self.assertEqual(self.proto.kexAlg,
- 'diffie-hellman-group1-sha1')
- self.assertEqual(self.proto.keyAlg,
- 'ssh-dss')
- self.assertEqual(self.proto.outgoingCompressionType,
- 'none')
- self.assertEqual(self.proto.incomingCompressionType,
- 'none')
- ne = self.proto.nextEncryptions
- self.assertEqual(ne.outCipType, 'aes128-ctr')
- self.assertEqual(ne.inCipType, 'aes128-ctr')
- self.assertEqual(ne.outMACType, 'hmac-md5')
- self.assertEqual(ne.inMACType, 'hmac-md5')
-
-
- def test_ignoreGuessPacketKex(self):
- """
- The client is allowed to send a guessed key exchange packet
- after it sends the KEXINIT packet. However, if the key exchanges
- do not match, that guess packet must be ignored. This tests that
- the packet is ignored in the case of the key exchange method not
- matching.
- """
- kexInitPacket = '\x00' * 16 + (
- ''.join([common.NS(x) for x in
- [','.join(y) for y in
- [self.proto.supportedKeyExchanges[::-1],
- self.proto.supportedPublicKeys,
- self.proto.supportedCiphers,
- self.proto.supportedCiphers,
- self.proto.supportedMACs,
- self.proto.supportedMACs,
- self.proto.supportedCompressions,
- self.proto.supportedCompressions,
- self.proto.supportedLanguages,
- self.proto.supportedLanguages]]])) + (
- '\xff\x00\x00\x00\x00')
- self.proto.ssh_KEXINIT(kexInitPacket)
- self.assertTrue(self.proto.ignoreNextPacket)
- self.proto.ssh_DEBUG("\x01\x00\x00\x00\x04test\x00\x00\x00\x00")
- self.assertTrue(self.proto.ignoreNextPacket)
-
-
- self.proto.ssh_KEX_DH_GEX_REQUEST_OLD('\x00\x00\x08\x00')
- self.assertFalse(self.proto.ignoreNextPacket)
- self.assertEqual(self.packets, [])
- self.proto.ignoreNextPacket = True
-
- self.proto.ssh_KEX_DH_GEX_REQUEST('\x00\x00\x08\x00' * 3)
- self.assertFalse(self.proto.ignoreNextPacket)
- self.assertEqual(self.packets, [])
-
-
- def test_ignoreGuessPacketKey(self):
- """
- Like test_ignoreGuessPacketKex, but for an incorrectly guessed
- public key format.
- """
- kexInitPacket = '\x00' * 16 + (
- ''.join([common.NS(x) for x in
- [','.join(y) for y in
- [self.proto.supportedKeyExchanges,
- self.proto.supportedPublicKeys[::-1],
- self.proto.supportedCiphers,
- self.proto.supportedCiphers,
- self.proto.supportedMACs,
- self.proto.supportedMACs,
- self.proto.supportedCompressions,
- self.proto.supportedCompressions,
- self.proto.supportedLanguages,
- self.proto.supportedLanguages]]])) + (
- '\xff\x00\x00\x00\x00')
- self.proto.ssh_KEXINIT(kexInitPacket)
- self.assertTrue(self.proto.ignoreNextPacket)
- self.proto.ssh_DEBUG("\x01\x00\x00\x00\x04test\x00\x00\x00\x00")
- self.assertTrue(self.proto.ignoreNextPacket)
-
- self.proto.ssh_KEX_DH_GEX_REQUEST_OLD('\x00\x00\x08\x00')
- self.assertFalse(self.proto.ignoreNextPacket)
- self.assertEqual(self.packets, [])
- self.proto.ignoreNextPacket = True
-
- self.proto.ssh_KEX_DH_GEX_REQUEST('\x00\x00\x08\x00' * 3)
- self.assertFalse(self.proto.ignoreNextPacket)
- self.assertEqual(self.packets, [])
-
-
- def test_KEXDH_INIT(self):
- """
- Test that the KEXDH_INIT packet causes the server to send a
- KEXDH_REPLY with the server's public key and a signature.
- """
- self.proto.supportedKeyExchanges = ['diffie-hellman-group1-sha1']
- self.proto.supportedPublicKeys = ['ssh-rsa']
- self.proto.dataReceived(self.transport.value())
- e = pow(transport.DH_GENERATOR, 5000,
- transport.DH_PRIME)
-
- self.proto.ssh_KEX_DH_GEX_REQUEST_OLD(common.MP(e))
- y = common.getMP('\x00\x00\x00\x40' + '\x99' * 64)[0]
- f = common._MPpow(transport.DH_GENERATOR, y, transport.DH_PRIME)
- sharedSecret = common._MPpow(e, y, transport.DH_PRIME)
-
- h = sha1()
- h.update(common.NS(self.proto.ourVersionString) * 2)
- h.update(common.NS(self.proto.ourKexInitPayload) * 2)
- h.update(common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()))
- h.update(common.MP(e))
- h.update(f)
- h.update(sharedSecret)
- exchangeHash = h.digest()
-
- signature = self.proto.factory.privateKeys['ssh-rsa'].sign(
- exchangeHash)
-
- self.assertEqual(
- self.packets,
- [(transport.MSG_KEXDH_REPLY,
- common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob())
- + f + common.NS(signature)),
- (transport.MSG_NEWKEYS, '')])
-
-
- def test_KEX_DH_GEX_REQUEST_OLD(self):
- """
- Test that the KEX_DH_GEX_REQUEST_OLD message causes the server
- to reply with a KEX_DH_GEX_GROUP message with the correct
- Diffie-Hellman group.
- """
- self.proto.supportedKeyExchanges = [
- 'diffie-hellman-group-exchange-sha1']
- self.proto.supportedPublicKeys = ['ssh-rsa']
- self.proto.dataReceived(self.transport.value())
- self.proto.ssh_KEX_DH_GEX_REQUEST_OLD('\x00\x00\x04\x00')
- self.assertEqual(
- self.packets,
- [(transport.MSG_KEX_DH_GEX_GROUP,
- common.MP(transport.DH_PRIME) + '\x00\x00\x00\x01\x02')])
- self.assertEqual(self.proto.g, 2)
- self.assertEqual(self.proto.p, transport.DH_PRIME)
-
-
- def test_KEX_DH_GEX_REQUEST_OLD_badKexAlg(self):
- """
- Test that if the server recieves a KEX_DH_GEX_REQUEST_OLD message
- and the key exchange algorithm is not 'diffie-hellman-group1-sha1' or
- 'diffie-hellman-group-exchange-sha1', we raise a ConchError.
- """
- self.proto.kexAlg = None
- self.assertRaises(ConchError, self.proto.ssh_KEX_DH_GEX_REQUEST_OLD,
- None)
-
-
- def test_KEX_DH_GEX_REQUEST(self):
- """
- Test that the KEX_DH_GEX_REQUEST message causes the server to reply
- with a KEX_DH_GEX_GROUP message with the correct Diffie-Hellman
- group.
- """
- self.proto.supportedKeyExchanges = [
- 'diffie-hellman-group-exchange-sha1']
- self.proto.supportedPublicKeys = ['ssh-rsa']
- self.proto.dataReceived(self.transport.value())
- self.proto.ssh_KEX_DH_GEX_REQUEST('\x00\x00\x04\x00\x00\x00\x08\x00' +
- '\x00\x00\x0c\x00')
- self.assertEqual(
- self.packets,
- [(transport.MSG_KEX_DH_GEX_GROUP,
- common.MP(transport.DH_PRIME) + '\x00\x00\x00\x01\x03')])
- self.assertEqual(self.proto.g, 3)
- self.assertEqual(self.proto.p, transport.DH_PRIME)
-
-
- def test_KEX_DH_GEX_INIT_after_REQUEST(self):
- """
- Test that the KEX_DH_GEX_INIT message after the client sends
- KEX_DH_GEX_REQUEST causes the server to send a KEX_DH_GEX_INIT message
- with a public key and signature.
- """
- self.test_KEX_DH_GEX_REQUEST()
- e = pow(self.proto.g, 3, self.proto.p)
- y = common.getMP('\x00\x00\x00\x80' + '\x99' * 128)[0]
- f = common._MPpow(self.proto.g, y, self.proto.p)
- sharedSecret = common._MPpow(e, y, self.proto.p)
- h = sha1()
- h.update(common.NS(self.proto.ourVersionString) * 2)
- h.update(common.NS(self.proto.ourKexInitPayload) * 2)
- h.update(common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()))
- h.update('\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x0c\x00')
- h.update(common.MP(self.proto.p))
- h.update(common.MP(self.proto.g))
- h.update(common.MP(e))
- h.update(f)
- h.update(sharedSecret)
- exchangeHash = h.digest()
- self.proto.ssh_KEX_DH_GEX_INIT(common.MP(e))
- self.assertEqual(
- self.packets[1],
- (transport.MSG_KEX_DH_GEX_REPLY,
- common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()) +
- f + common.NS(self.proto.factory.privateKeys['ssh-rsa'].sign(
- exchangeHash))))
-
-
- def test_KEX_DH_GEX_INIT_after_REQUEST_OLD(self):
- """
- Test that the KEX_DH_GEX_INIT message after the client sends
- KEX_DH_GEX_REQUEST_OLD causes the server to sent a KEX_DH_GEX_INIT
- message with a public key and signature.
- """
- self.test_KEX_DH_GEX_REQUEST_OLD()
- e = pow(self.proto.g, 3, self.proto.p)
- y = common.getMP('\x00\x00\x00\x80' + '\x99' * 128)[0]
- f = common._MPpow(self.proto.g, y, self.proto.p)
- sharedSecret = common._MPpow(e, y, self.proto.p)
- h = sha1()
- h.update(common.NS(self.proto.ourVersionString) * 2)
- h.update(common.NS(self.proto.ourKexInitPayload) * 2)
- h.update(common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()))
- h.update('\x00\x00\x04\x00')
- h.update(common.MP(self.proto.p))
- h.update(common.MP(self.proto.g))
- h.update(common.MP(e))
- h.update(f)
- h.update(sharedSecret)
- exchangeHash = h.digest()
- self.proto.ssh_KEX_DH_GEX_INIT(common.MP(e))
- self.assertEqual(
- self.packets[1:],
- [(transport.MSG_KEX_DH_GEX_REPLY,
- common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()) +
- f + common.NS(self.proto.factory.privateKeys['ssh-rsa'].sign(
- exchangeHash))),
- (transport.MSG_NEWKEYS, '')])
-
-
- def test_keySetup(self):
- """
- Test that _keySetup sets up the next encryption keys.
- """
- self.proto.nextEncryptions = MockCipher()
- self.simulateKeyExchange('AB', 'CD')
- self.assertEqual(self.proto.sessionID, 'CD')
- self.simulateKeyExchange('AB', 'EF')
- self.assertEqual(self.proto.sessionID, 'CD')
- self.assertEqual(self.packets[-1], (transport.MSG_NEWKEYS, ''))
- newKeys = [self.proto._getKey(c, 'AB', 'EF') for c in 'ABCDEF']
- self.assertEqual(
- self.proto.nextEncryptions.keys,
- (newKeys[1], newKeys[3], newKeys[0], newKeys[2], newKeys[5],
- newKeys[4]))
-
-
- def test_NEWKEYS(self):
- """
- Test that NEWKEYS transitions the keys in nextEncryptions to
- currentEncryptions.
- """
- self.test_KEXINIT()
-
- self.proto.nextEncryptions = transport.SSHCiphers('none', 'none',
- 'none', 'none')
- self.proto.ssh_NEWKEYS('')
- self.assertIdentical(self.proto.currentEncryptions,
- self.proto.nextEncryptions)
- self.assertIdentical(self.proto.outgoingCompression, None)
- self.assertIdentical(self.proto.incomingCompression, None)
- self.proto.outgoingCompressionType = 'zlib'
- self.simulateKeyExchange('AB', 'CD')
- self.proto.ssh_NEWKEYS('')
- self.failIfIdentical(self.proto.outgoingCompression, None)
- self.proto.incomingCompressionType = 'zlib'
- self.simulateKeyExchange('AB', 'EF')
- self.proto.ssh_NEWKEYS('')
- self.failIfIdentical(self.proto.incomingCompression, None)
-
-
- def test_SERVICE_REQUEST(self):
- """
- Test that the SERVICE_REQUEST message requests and starts a
- service.
- """
- self.proto.ssh_SERVICE_REQUEST(common.NS('ssh-userauth'))
- self.assertEqual(self.packets, [(transport.MSG_SERVICE_ACCEPT,
- common.NS('ssh-userauth'))])
- self.assertEqual(self.proto.service.name, 'MockService')
-
-
- def test_disconnectNEWKEYSData(self):
- """
- Test that NEWKEYS disconnects if it receives data.
- """
- self.proto.ssh_NEWKEYS("bad packet")
- self.checkDisconnected()
-
-
- def test_disconnectSERVICE_REQUESTBadService(self):
- """
- Test that SERVICE_REQUESTS disconnects if an unknown service is
- requested.
- """
- self.proto.ssh_SERVICE_REQUEST(common.NS('no service'))
- self.checkDisconnected(transport.DISCONNECT_SERVICE_NOT_AVAILABLE)
-
-
-
-class ClientSSHTransportTestCase(ServerAndClientSSHTransportBaseCase,
- TransportTestCase):
- """
- Tests for SSHClientTransport.
- """
-
- klass = transport.SSHClientTransport
-
-
- def test_KEXINIT(self):
- """
- Test that receiving a KEXINIT packet sets up the correct values on the
- client. The way algorithms are picks is that the first item in the
- client's list that is also in the server's list is chosen.
- """
- self.proto.dataReceived( 'SSH-2.0-Twisted\r\n\x00\x00\x01\xd4\t\x14'
- '\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99'
- '\x99\x00\x00\x00=diffie-hellman-group1-sha1,diffie-hellman-g'
- 'roup-exchange-sha1\x00\x00\x00\x0fssh-dss,ssh-rsa\x00\x00\x00'
- '\x85aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,ae'
- 's256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3d'
- 'es-ctr,3des-cbc\x00\x00\x00\x85aes128-ctr,aes128-cbc,aes192-c'
- 'tr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,b'
- 'lowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc\x00\x00\x00\x12hma'
- 'c-md5,hmac-sha1\x00\x00\x00\x12hmac-md5,hmac-sha1\x00\x00\x00'
- '\tzlib,none\x00\x00\x00\tzlib,none\x00\x00\x00\x00\x00\x00'
- '\x00\x00\x00\x00\x00\x00\x00\x99\x99\x99\x99\x99\x99\x99\x99'
- '\x99')
- self.assertEqual(self.proto.kexAlg,
- 'diffie-hellman-group-exchange-sha1')
- self.assertEqual(self.proto.keyAlg,
- 'ssh-rsa')
- self.assertEqual(self.proto.outgoingCompressionType,
- 'none')
- self.assertEqual(self.proto.incomingCompressionType,
- 'none')
- ne = self.proto.nextEncryptions
- self.assertEqual(ne.outCipType, 'aes256-ctr')
- self.assertEqual(ne.inCipType, 'aes256-ctr')
- self.assertEqual(ne.outMACType, 'hmac-sha1')
- self.assertEqual(ne.inMACType, 'hmac-sha1')
-
-
- def verifyHostKey(self, pubKey, fingerprint):
- """
- Mock version of SSHClientTransport.verifyHostKey.
- """
- self.calledVerifyHostKey = True
- self.assertEqual(pubKey, self.blob)
- self.assertEqual(fingerprint.replace(':', ''),
- md5(pubKey).hexdigest())
- return defer.succeed(True)
-
-
- def setUp(self):
- TransportTestCase.setUp(self)
- self.blob = keys.Key.fromString(keydata.publicRSA_openssh).blob()
- self.privObj = keys.Key.fromString(keydata.privateRSA_openssh)
- self.calledVerifyHostKey = False
- self.proto.verifyHostKey = self.verifyHostKey
-
-
- def test_notImplementedClientMethods(self):
- """
- verifyHostKey() should return a Deferred which fails with a
- NotImplementedError exception. connectionSecure() should raise
- NotImplementedError().
- """
- self.assertRaises(NotImplementedError, self.klass().connectionSecure)
- def _checkRaises(f):
- f.trap(NotImplementedError)
- d = self.klass().verifyHostKey(None, None)
- return d.addCallback(self.fail).addErrback(_checkRaises)
-
-
- def test_KEXINIT_groupexchange(self):
- """
- Test that a KEXINIT packet with a group-exchange key exchange results
- in a KEX_DH_GEX_REQUEST_OLD message..
- """
- self.proto.supportedKeyExchanges = [
- 'diffie-hellman-group-exchange-sha1']
- self.proto.dataReceived(self.transport.value())
- self.assertEqual(self.packets, [(transport.MSG_KEX_DH_GEX_REQUEST_OLD,
- '\x00\x00\x08\x00')])
-
-
- def test_KEXINIT_group1(self):
- """
- Like test_KEXINIT_groupexchange, but for the group-1 key exchange.
- """
- self.proto.supportedKeyExchanges = ['diffie-hellman-group1-sha1']
- self.proto.dataReceived(self.transport.value())
- self.assertEqual(common.MP(self.proto.x)[5:], '\x99' * 64)
- self.assertEqual(self.packets,
- [(transport.MSG_KEXDH_INIT, self.proto.e)])
-
-
- def test_KEXINIT_badKexAlg(self):
- """
- Test that the client raises a ConchError if it receives a
- KEXINIT message bug doesn't have a key exchange algorithm that we
- understand.
- """
- self.proto.supportedKeyExchanges = ['diffie-hellman-group2-sha1']
- data = self.transport.value().replace('group1', 'group2')
- self.assertRaises(ConchError, self.proto.dataReceived, data)
-
-
- def test_KEXDH_REPLY(self):
- """
- Test that the KEXDH_REPLY message verifies the server.
- """
- self.test_KEXINIT_group1()
-
- sharedSecret = common._MPpow(transport.DH_GENERATOR,
- self.proto.x, transport.DH_PRIME)
- h = sha1()
- h.update(common.NS(self.proto.ourVersionString) * 2)
- h.update(common.NS(self.proto.ourKexInitPayload) * 2)
- h.update(common.NS(self.blob))
- h.update(self.proto.e)
- h.update('\x00\x00\x00\x01\x02') # f
- h.update(sharedSecret)
- exchangeHash = h.digest()
-
- def _cbTestKEXDH_REPLY(value):
- self.assertIdentical(value, None)
- self.assertEqual(self.calledVerifyHostKey, True)
- self.assertEqual(self.proto.sessionID, exchangeHash)
-
- signature = self.privObj.sign(exchangeHash)
-
- d = self.proto.ssh_KEX_DH_GEX_GROUP(
- (common.NS(self.blob) + '\x00\x00\x00\x01\x02' +
- common.NS(signature)))
- d.addCallback(_cbTestKEXDH_REPLY)
-
- return d
-
-
- def test_KEX_DH_GEX_GROUP(self):
- """
- Test that the KEX_DH_GEX_GROUP message results in a
- KEX_DH_GEX_INIT message with the client's Diffie-Hellman public key.
- """
- self.test_KEXINIT_groupexchange()
- self.proto.ssh_KEX_DH_GEX_GROUP(
- '\x00\x00\x00\x01\x0f\x00\x00\x00\x01\x02')
- self.assertEqual(self.proto.p, 15)
- self.assertEqual(self.proto.g, 2)
- self.assertEqual(common.MP(self.proto.x)[5:], '\x99' * 40)
- self.assertEqual(self.proto.e,
- common.MP(pow(2, self.proto.x, 15)))
- self.assertEqual(self.packets[1:], [(transport.MSG_KEX_DH_GEX_INIT,
- self.proto.e)])
-
-
- def test_KEX_DH_GEX_REPLY(self):
- """
- Test that the KEX_DH_GEX_REPLY message results in a verified
- server.
- """
-
- self.test_KEX_DH_GEX_GROUP()
- sharedSecret = common._MPpow(3, self.proto.x, self.proto.p)
- h = sha1()
- h.update(common.NS(self.proto.ourVersionString) * 2)
- h.update(common.NS(self.proto.ourKexInitPayload) * 2)
- h.update(common.NS(self.blob))
- h.update('\x00\x00\x08\x00\x00\x00\x00\x01\x0f\x00\x00\x00\x01\x02')
- h.update(self.proto.e)
- h.update('\x00\x00\x00\x01\x03') # f
- h.update(sharedSecret)
- exchangeHash = h.digest()
-
- def _cbTestKEX_DH_GEX_REPLY(value):
- self.assertIdentical(value, None)
- self.assertEqual(self.calledVerifyHostKey, True)
- self.assertEqual(self.proto.sessionID, exchangeHash)
-
- signature = self.privObj.sign(exchangeHash)
-
- d = self.proto.ssh_KEX_DH_GEX_REPLY(
- common.NS(self.blob) +
- '\x00\x00\x00\x01\x03' +
- common.NS(signature))
- d.addCallback(_cbTestKEX_DH_GEX_REPLY)
- return d
-
-
- def test_keySetup(self):
- """
- Test that _keySetup sets up the next encryption keys.
- """
- self.proto.nextEncryptions = MockCipher()
- self.simulateKeyExchange('AB', 'CD')
- self.assertEqual(self.proto.sessionID, 'CD')
- self.simulateKeyExchange('AB', 'EF')
- self.assertEqual(self.proto.sessionID, 'CD')
- self.assertEqual(self.packets[-1], (transport.MSG_NEWKEYS, ''))
- newKeys = [self.proto._getKey(c, 'AB', 'EF') for c in 'ABCDEF']
- self.assertEqual(self.proto.nextEncryptions.keys,
- (newKeys[0], newKeys[2], newKeys[1], newKeys[3],
- newKeys[4], newKeys[5]))
-
-
- def test_NEWKEYS(self):
- """
- Test that NEWKEYS transitions the keys from nextEncryptions to
- currentEncryptions.
- """
- self.test_KEXINIT()
- secure = [False]
- def stubConnectionSecure():
- secure[0] = True
- self.proto.connectionSecure = stubConnectionSecure
-
- self.proto.nextEncryptions = transport.SSHCiphers(
- 'none', 'none', 'none', 'none')
- self.simulateKeyExchange('AB', 'CD')
- self.assertNotIdentical(
- self.proto.currentEncryptions, self.proto.nextEncryptions)
-
- self.proto.nextEncryptions = MockCipher()
- self.proto.ssh_NEWKEYS('')
- self.assertIdentical(self.proto.outgoingCompression, None)
- self.assertIdentical(self.proto.incomingCompression, None)
- self.assertIdentical(self.proto.currentEncryptions,
- self.proto.nextEncryptions)
- self.assertTrue(secure[0])
- self.proto.outgoingCompressionType = 'zlib'
- self.simulateKeyExchange('AB', 'GH')
- self.proto.ssh_NEWKEYS('')
- self.failIfIdentical(self.proto.outgoingCompression, None)
- self.proto.incomingCompressionType = 'zlib'
- self.simulateKeyExchange('AB', 'IJ')
- self.proto.ssh_NEWKEYS('')
- self.failIfIdentical(self.proto.incomingCompression, None)
-
-
- def test_SERVICE_ACCEPT(self):
- """
- Test that the SERVICE_ACCEPT packet starts the requested service.
- """
- self.proto.instance = MockService()
- self.proto.ssh_SERVICE_ACCEPT('\x00\x00\x00\x0bMockService')
- self.assertTrue(self.proto.instance.started)
-
-
- def test_requestService(self):
- """
- Test that requesting a service sends a SERVICE_REQUEST packet.
- """
- self.proto.requestService(MockService())
- self.assertEqual(self.packets, [(transport.MSG_SERVICE_REQUEST,
- '\x00\x00\x00\x0bMockService')])
-
-
- def test_disconnectKEXDH_REPLYBadSignature(self):
- """
- Test that KEXDH_REPLY disconnects if the signature is bad.
- """
- self.test_KEXDH_REPLY()
- self.proto._continueKEXDH_REPLY(None, self.blob, 3, "bad signature")
- self.checkDisconnected(transport.DISCONNECT_KEY_EXCHANGE_FAILED)
-
-
- def test_disconnectGEX_REPLYBadSignature(self):
- """
- Like test_disconnectKEXDH_REPLYBadSignature, but for DH_GEX_REPLY.
- """
- self.test_KEX_DH_GEX_REPLY()
- self.proto._continueGEX_REPLY(None, self.blob, 3, "bad signature")
- self.checkDisconnected(transport.DISCONNECT_KEY_EXCHANGE_FAILED)
-
-
- def test_disconnectNEWKEYSData(self):
- """
- Test that NEWKEYS disconnects if it receives data.
- """
- self.proto.ssh_NEWKEYS("bad packet")
- self.checkDisconnected()
-
-
- def test_disconnectSERVICE_ACCEPT(self):
- """
- Test that SERVICE_ACCEPT disconnects if the accepted protocol is
- differet from the asked-for protocol.
- """
- self.proto.instance = MockService()
- self.proto.ssh_SERVICE_ACCEPT('\x00\x00\x00\x03bad')
- self.checkDisconnected()
-
-
- def test_noPayloadSERVICE_ACCEPT(self):
- """
- Some commercial SSH servers don't send a payload with the
- SERVICE_ACCEPT message. Conch pretends that it got the correct
- name of the service.
- """
- self.proto.instance = MockService()
- self.proto.ssh_SERVICE_ACCEPT('') # no payload
- self.assertTrue(self.proto.instance.started)
- self.assertEquals(len(self.packets), 0) # not disconnected
-
-
-
-class SSHCiphersTestCase(unittest.TestCase):
- """
- Tests for the SSHCiphers helper class.
- """
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
-
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
-
- def test_init(self):
- """
- Test that the initializer sets up the SSHCiphers object.
- """
- ciphers = transport.SSHCiphers('A', 'B', 'C', 'D')
- self.assertEqual(ciphers.outCipType, 'A')
- self.assertEqual(ciphers.inCipType, 'B')
- self.assertEqual(ciphers.outMACType, 'C')
- self.assertEqual(ciphers.inMACType, 'D')
-
-
- def test_getCipher(self):
- """
- Test that the _getCipher method returns the correct cipher.
- """
- ciphers = transport.SSHCiphers('A', 'B', 'C', 'D')
- iv = key = '\x00' * 16
- for cipName, (modName, keySize, counter) in ciphers.cipherMap.items():
- cip = ciphers._getCipher(cipName, iv, key)
- if cipName == 'none':
- self.assertIsInstance(cip, transport._DummyCipher)
- else:
- self.assertTrue(getClass(cip).__name__.startswith(modName))
-
-
- def test_getMAC(self):
- """
- Test that the _getMAC method returns the correct MAC.
- """
- ciphers = transport.SSHCiphers('A', 'B', 'C', 'D')
- key = '\x00' * 64
- for macName, mac in ciphers.macMap.items():
- mod = ciphers._getMAC(macName, key)
- if macName == 'none':
- self.assertIdentical(mac, None)
- else:
- self.assertEqual(mod[0], mac)
- self.assertEqual(mod[1],
- Crypto.Cipher.XOR.new('\x36').encrypt(key))
- self.assertEqual(mod[2],
- Crypto.Cipher.XOR.new('\x5c').encrypt(key))
- self.assertEqual(mod[3], len(mod[0]().digest()))
-
-
- def test_setKeysCiphers(self):
- """
- Test that setKeys sets up the ciphers.
- """
- key = '\x00' * 64
- cipherItems = transport.SSHCiphers.cipherMap.items()
- for cipName, (modName, keySize, counter) in cipherItems:
- encCipher = transport.SSHCiphers(cipName, 'none', 'none', 'none')
- decCipher = transport.SSHCiphers('none', cipName, 'none', 'none')
- cip = encCipher._getCipher(cipName, key, key)
- bs = cip.block_size
- encCipher.setKeys(key, key, '', '', '', '')
- decCipher.setKeys('', '', key, key, '', '')
- self.assertEqual(encCipher.encBlockSize, bs)
- self.assertEqual(decCipher.decBlockSize, bs)
- enc = cip.encrypt(key[:bs])
- enc2 = cip.encrypt(key[:bs])
- if counter:
- self.failIfEquals(enc, enc2)
- self.assertEqual(encCipher.encrypt(key[:bs]), enc)
- self.assertEqual(encCipher.encrypt(key[:bs]), enc2)
- self.assertEqual(decCipher.decrypt(enc), key[:bs])
- self.assertEqual(decCipher.decrypt(enc2), key[:bs])
-
-
- def test_setKeysMACs(self):
- """
- Test that setKeys sets up the MACs.
- """
- key = '\x00' * 64
- for macName, mod in transport.SSHCiphers.macMap.items():
- outMac = transport.SSHCiphers('none', 'none', macName, 'none')
- inMac = transport.SSHCiphers('none', 'none', 'none', macName)
- outMac.setKeys('', '', '', '', key, '')
- inMac.setKeys('', '', '', '', '', key)
- if mod:
- ds = mod().digest_size
- else:
- ds = 0
- self.assertEqual(inMac.verifyDigestSize, ds)
- if mod:
- mod, i, o, ds = outMac._getMAC(macName, key)
- seqid = 0
- data = key
- packet = '\x00' * 4 + key
- if mod:
- mac = mod(o + mod(i + packet).digest()).digest()
- else:
- mac = ''
- self.assertEqual(outMac.makeMAC(seqid, data), mac)
- self.assertTrue(inMac.verify(seqid, data, mac))
-
-
-
-class CounterTestCase(unittest.TestCase):
- """
- Tests for the _Counter helper class.
- """
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
-
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
-
- def test_init(self):
- """
- Test that the counter is initialized correctly.
- """
- counter = transport._Counter('\x00' * 8 + '\xff' * 8, 8)
- self.assertEqual(counter.blockSize, 8)
- self.assertEqual(counter.count.tostring(), '\x00' * 8)
-
-
- def test_count(self):
- """
- Test that the counter counts incrementally and wraps at the top.
- """
- counter = transport._Counter('\x00', 1)
- self.assertEqual(counter(), '\x01')
- self.assertEqual(counter(), '\x02')
- [counter() for i in range(252)]
- self.assertEqual(counter(), '\xff')
- self.assertEqual(counter(), '\x00')
-
-
-
-class TransportLoopbackTestCase(unittest.TestCase):
- """
- Test the server transport and client transport against each other,
- """
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
-
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
-
- def _runClientServer(self, mod):
- """
- Run an async client and server, modifying each using the mod function
- provided. Returns a Deferred called back when both Protocols have
- disconnected.
-
- @type mod: C{func}
- @rtype: C{defer.Deferred}
- """
- factory = MockFactory()
- server = transport.SSHServerTransport()
- server.factory = factory
- factory.startFactory()
- server.errors = []
- server.receiveError = lambda code, desc: server.errors.append((
- code, desc))
- client = transport.SSHClientTransport()
- client.verifyHostKey = lambda x, y: defer.succeed(None)
- client.errors = []
- client.receiveError = lambda code, desc: client.errors.append((
- code, desc))
- client.connectionSecure = lambda: client.loseConnection()
- server = mod(server)
- client = mod(client)
- def check(ignored, server, client):
- name = repr([server.supportedCiphers[0],
- server.supportedMACs[0],
- server.supportedKeyExchanges[0],
- server.supportedCompressions[0]])
- self.assertEqual(client.errors, [])
- self.assertEqual(server.errors, [(
- transport.DISCONNECT_CONNECTION_LOST,
- "user closed connection")])
- if server.supportedCiphers[0] == 'none':
- self.assertFalse(server.isEncrypted(), name)
- self.assertFalse(client.isEncrypted(), name)
- else:
- self.assertTrue(server.isEncrypted(), name)
- self.assertTrue(client.isEncrypted(), name)
- if server.supportedMACs[0] == 'none':
- self.assertFalse(server.isVerified(), name)
- self.assertFalse(client.isVerified(), name)
- else:
- self.assertTrue(server.isVerified(), name)
- self.assertTrue(client.isVerified(), name)
-
- d = loopback.loopbackAsync(server, client)
- d.addCallback(check, server, client)
- return d
-
-
- def test_ciphers(self):
- """
- Test that the client and server play nicely together, in all
- the various combinations of ciphers.
- """
- deferreds = []
- for cipher in transport.SSHTransportBase.supportedCiphers + ['none']:
- def setCipher(proto):
- proto.supportedCiphers = [cipher]
- return proto
- deferreds.append(self._runClientServer(setCipher))
- return defer.DeferredList(deferreds, fireOnOneErrback=True)
-
-
- def test_macs(self):
- """
- Like test_ciphers, but for the various MACs.
- """
- deferreds = []
- for mac in transport.SSHTransportBase.supportedMACs + ['none']:
- def setMAC(proto):
- proto.supportedMACs = [mac]
- return proto
- deferreds.append(self._runClientServer(setMAC))
- return defer.DeferredList(deferreds, fireOnOneErrback=True)
-
-
- def test_keyexchanges(self):
- """
- Like test_ciphers, but for the various key exchanges.
- """
- deferreds = []
- for kex in transport.SSHTransportBase.supportedKeyExchanges:
- def setKeyExchange(proto):
- proto.supportedKeyExchanges = [kex]
- return proto
- deferreds.append(self._runClientServer(setKeyExchange))
- return defer.DeferredList(deferreds, fireOnOneErrback=True)
-
-
- def test_compressions(self):
- """
- Like test_ciphers, but for the various compressions.
- """
- deferreds = []
- for compression in transport.SSHTransportBase.supportedCompressions:
- def setCompression(proto):
- proto.supportedCompressions = [compression]
- return proto
- deferreds.append(self._runClientServer(setCompression))
- return defer.DeferredList(deferreds, fireOnOneErrback=True)
-
-
-class RandomNumberTestCase(unittest.TestCase):
- """
- Tests for the random number generator L{_getRandomNumber} and private
- key generator L{_generateX}.
- """
- skip = dependencySkip
-
- def test_usesSuppliedRandomFunction(self):
- """
- L{_getRandomNumber} returns an integer constructed directly from the
- bytes returned by the random byte generator passed to it.
- """
- def random(bytes):
- # The number of bytes requested will be the value of each byte
- # we return.
- return chr(bytes) * bytes
- self.assertEqual(
- transport._getRandomNumber(random, 32),
- 4 << 24 | 4 << 16 | 4 << 8 | 4)
-
-
- def test_rejectsNonByteMultiples(self):
- """
- L{_getRandomNumber} raises L{ValueError} if the number of bits
- passed to L{_getRandomNumber} is not a multiple of 8.
- """
- self.assertRaises(
- ValueError,
- transport._getRandomNumber, None, 9)
-
-
- def test_excludesSmall(self):
- """
- If the random byte generator passed to L{_generateX} produces bytes
- which would result in 0 or 1 being returned, these bytes are
- discarded and another attempt is made to produce a larger value.
- """
- results = [chr(0), chr(1), chr(127)]
- def random(bytes):
- return results.pop(0) * bytes
- self.assertEqual(
- transport._generateX(random, 8),
- 127)
-
-
- def test_excludesLarge(self):
- """
- If the random byte generator passed to L{_generateX} produces bytes
- which would result in C{(2 ** bits) - 1} being returned, these bytes
- are discarded and another attempt is made to produce a smaller
- value.
- """
- results = [chr(255), chr(64)]
- def random(bytes):
- return results.pop(0) * bytes
- self.assertEqual(
- transport._generateX(random, 8),
- 64)
-
-
-
-class OldFactoryTestCase(unittest.TestCase):
- """
- The old C{SSHFactory.getPublicKeys}() returned mappings of key names to
- strings of key blobs and mappings of key names to PyCrypto key objects from
- C{SSHFactory.getPrivateKeys}() (they could also be specified with the
- C{publicKeys} and C{privateKeys} attributes). This is no longer supported
- by the C{SSHServerTransport}, so we warn the user if they create an old
- factory.
- """
-
- if Crypto is None:
- skip = "cannot run w/o PyCrypto"
-
- if pyasn1 is None:
- skip = "Cannot run without PyASN1"
-
-
- def test_getPublicKeysWarning(self):
- """
- If the return value of C{getPublicKeys}() isn't a mapping from key
- names to C{Key} objects, then warn the user and convert the mapping.
- """
- sshFactory = MockOldFactoryPublicKeys()
- self.assertWarns(DeprecationWarning,
- "Returning a mapping from strings to strings from"
- " getPublicKeys()/publicKeys (in %s) is deprecated. Return "
- "a mapping from strings to Key objects instead." %
- (qual(MockOldFactoryPublicKeys),),
- factory.__file__, sshFactory.startFactory)
- self.assertEqual(sshFactory.publicKeys, MockFactory().getPublicKeys())
-
-
- def test_getPrivateKeysWarning(self):
- """
- If the return value of C{getPrivateKeys}() isn't a mapping from key
- names to C{Key} objects, then warn the user and convert the mapping.
- """
- sshFactory = MockOldFactoryPrivateKeys()
- self.assertWarns(DeprecationWarning,
- "Returning a mapping from strings to PyCrypto key objects from"
- " getPrivateKeys()/privateKeys (in %s) is deprecated. Return"
- " a mapping from strings to Key objects instead." %
- (qual(MockOldFactoryPrivateKeys),),
- factory.__file__, sshFactory.startFactory)
- self.assertEqual(sshFactory.privateKeys,
- MockFactory().getPrivateKeys())
-
-
- def test_publicKeysWarning(self):
- """
- If the value of the C{publicKeys} attribute isn't a mapping from key
- names to C{Key} objects, then warn the user and convert the mapping.
- """
- sshFactory = MockOldFactoryPublicKeys()
- sshFactory.publicKeys = sshFactory.getPublicKeys()
- self.assertWarns(DeprecationWarning,
- "Returning a mapping from strings to strings from"
- " getPublicKeys()/publicKeys (in %s) is deprecated. Return "
- "a mapping from strings to Key objects instead." %
- (qual(MockOldFactoryPublicKeys),),
- factory.__file__, sshFactory.startFactory)
- self.assertEqual(sshFactory.publicKeys, MockFactory().getPublicKeys())
-
-
- def test_privateKeysWarning(self):
- """
- If the return value of C{privateKeys} attribute isn't a mapping from
- key names to C{Key} objects, then warn the user and convert the
- mapping.
- """
- sshFactory = MockOldFactoryPrivateKeys()
- sshFactory.privateKeys = sshFactory.getPrivateKeys()
- self.assertWarns(DeprecationWarning,
- "Returning a mapping from strings to PyCrypto key objects from"
- " getPrivateKeys()/privateKeys (in %s) is deprecated. Return"
- " a mapping from strings to Key objects instead." %
- (qual(MockOldFactoryPrivateKeys),),
- factory.__file__, sshFactory.startFactory)
- self.assertEqual(sshFactory.privateKeys,
- MockFactory().getPrivateKeys())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py
deleted file mode 100755
index d027faad..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py
+++ /dev/null
@@ -1,1077 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_userauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the implementation of the ssh-userauth service.
-
-Maintainer: Paul Swartz
-"""
-
-from zope.interface import implements
-
-from twisted.cred.checkers import ICredentialsChecker
-from twisted.cred.credentials import IUsernamePassword, ISSHPrivateKey
-from twisted.cred.credentials import IPluggableAuthenticationModules
-from twisted.cred.credentials import IAnonymous
-from twisted.cred.error import UnauthorizedLogin
-from twisted.cred.portal import IRealm, Portal
-from twisted.conch.error import ConchError, ValidPublicKey
-from twisted.internet import defer, task
-from twisted.protocols import loopback
-from twisted.trial import unittest
-
-try:
- import Crypto.Cipher.DES3, Crypto.Cipher.XOR
- import pyasn1
-except ImportError:
- keys = None
-
-
- class transport:
- class SSHTransportBase:
- """
- A stub class so that later class definitions won't die.
- """
-
- class userauth:
- class SSHUserAuthClient:
- """
- A stub class so that later class definitions won't die.
- """
-else:
- from twisted.conch.ssh.common import NS
- from twisted.conch.checkers import SSHProtocolChecker
- from twisted.conch.ssh import keys, userauth, transport
- from twisted.conch.test import keydata
-
-
-
-class ClientUserAuth(userauth.SSHUserAuthClient):
- """
- A mock user auth client.
- """
-
-
- def getPublicKey(self):
- """
- If this is the first time we've been called, return a blob for
- the DSA key. Otherwise, return a blob
- for the RSA key.
- """
- if self.lastPublicKey:
- return keys.Key.fromString(keydata.publicRSA_openssh)
- else:
- return defer.succeed(keys.Key.fromString(keydata.publicDSA_openssh))
-
-
- def getPrivateKey(self):
- """
- Return the private key object for the RSA key.
- """
- return defer.succeed(keys.Key.fromString(keydata.privateRSA_openssh))
-
-
- def getPassword(self, prompt=None):
- """
- Return 'foo' as the password.
- """
- return defer.succeed('foo')
-
-
- def getGenericAnswers(self, name, information, answers):
- """
- Return 'foo' as the answer to two questions.
- """
- return defer.succeed(('foo', 'foo'))
-
-
-
-class OldClientAuth(userauth.SSHUserAuthClient):
- """
- The old SSHUserAuthClient returned a PyCrypto key object from
- getPrivateKey() and a string from getPublicKey
- """
-
-
- def getPrivateKey(self):
- return defer.succeed(keys.Key.fromString(
- keydata.privateRSA_openssh).keyObject)
-
-
- def getPublicKey(self):
- return keys.Key.fromString(keydata.publicRSA_openssh).blob()
-
-class ClientAuthWithoutPrivateKey(userauth.SSHUserAuthClient):
- """
- This client doesn't have a private key, but it does have a public key.
- """
-
-
- def getPrivateKey(self):
- return
-
-
- def getPublicKey(self):
- return keys.Key.fromString(keydata.publicRSA_openssh)
-
-
-
-class FakeTransport(transport.SSHTransportBase):
- """
- L{userauth.SSHUserAuthServer} expects an SSH transport which has a factory
- attribute which has a portal attribute. Because the portal is important for
- testing authentication, we need to be able to provide an interesting portal
- object to the L{SSHUserAuthServer}.
-
- In addition, we want to be able to capture any packets sent over the
- transport.
-
- @ivar packets: a list of 2-tuples: (messageType, data). Each 2-tuple is
- a sent packet.
- @type packets: C{list}
- @param lostConnecion: True if loseConnection has been called on us.
- @type lostConnection: C{bool}
- """
-
-
- class Service(object):
- """
- A mock service, representing the other service offered by the server.
- """
- name = 'nancy'
-
-
- def serviceStarted(self):
- pass
-
-
-
- class Factory(object):
- """
- A mock factory, representing the factory that spawned this user auth
- service.
- """
-
-
- def getService(self, transport, service):
- """
- Return our fake service.
- """
- if service == 'none':
- return FakeTransport.Service
-
-
-
- def __init__(self, portal):
- self.factory = self.Factory()
- self.factory.portal = portal
- self.lostConnection = False
- self.transport = self
- self.packets = []
-
-
-
- def sendPacket(self, messageType, message):
- """
- Record the packet sent by the service.
- """
- self.packets.append((messageType, message))
-
-
- def isEncrypted(self, direction):
- """
- Pretend that this transport encrypts traffic in both directions. The
- SSHUserAuthServer disables password authentication if the transport
- isn't encrypted.
- """
- return True
-
-
- def loseConnection(self):
- self.lostConnection = True
-
-
-
-class Realm(object):
- """
- A mock realm for testing L{userauth.SSHUserAuthServer}.
-
- This realm is not actually used in the course of testing, so it returns the
- simplest thing that could possibly work.
- """
- implements(IRealm)
-
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- return defer.succeed((interfaces[0], None, lambda: None))
-
-
-
-class PasswordChecker(object):
- """
- A very simple username/password checker which authenticates anyone whose
- password matches their username and rejects all others.
- """
- credentialInterfaces = (IUsernamePassword,)
- implements(ICredentialsChecker)
-
-
- def requestAvatarId(self, creds):
- if creds.username == creds.password:
- return defer.succeed(creds.username)
- return defer.fail(UnauthorizedLogin("Invalid username/password pair"))
-
-
-
-class PrivateKeyChecker(object):
- """
- A very simple public key checker which authenticates anyone whose
- public/private keypair is the same keydata.public/privateRSA_openssh.
- """
- credentialInterfaces = (ISSHPrivateKey,)
- implements(ICredentialsChecker)
-
-
-
- def requestAvatarId(self, creds):
- if creds.blob == keys.Key.fromString(keydata.publicRSA_openssh).blob():
- if creds.signature is not None:
- obj = keys.Key.fromString(creds.blob)
- if obj.verify(creds.signature, creds.sigData):
- return creds.username
- else:
- raise ValidPublicKey()
- raise UnauthorizedLogin()
-
-
-
-class PAMChecker(object):
- """
- A simple PAM checker which asks the user for a password, verifying them
- if the password is the same as their username.
- """
- credentialInterfaces = (IPluggableAuthenticationModules,)
- implements(ICredentialsChecker)
-
-
- def requestAvatarId(self, creds):
- d = creds.pamConversion([('Name: ', 2), ("Password: ", 1)])
- def check(values):
- if values == [(creds.username, 0), (creds.username, 0)]:
- return creds.username
- raise UnauthorizedLogin()
- return d.addCallback(check)
-
-
-
-class AnonymousChecker(object):
- """
- A simple checker which isn't supported by L{SSHUserAuthServer}.
- """
- credentialInterfaces = (IAnonymous,)
- implements(ICredentialsChecker)
-
-
-
-class SSHUserAuthServerTestCase(unittest.TestCase):
- """
- Tests for SSHUserAuthServer.
- """
-
-
- if keys is None:
- skip = "cannot run w/o PyCrypto"
-
-
- def setUp(self):
- self.realm = Realm()
- self.portal = Portal(self.realm)
- self.portal.registerChecker(PasswordChecker())
- self.portal.registerChecker(PrivateKeyChecker())
- self.portal.registerChecker(PAMChecker())
- self.authServer = userauth.SSHUserAuthServer()
- self.authServer.transport = FakeTransport(self.portal)
- self.authServer.serviceStarted()
- self.authServer.supportedAuthentications.sort() # give a consistent
- # order
-
-
- def tearDown(self):
- self.authServer.serviceStopped()
- self.authServer = None
-
-
- def _checkFailed(self, ignored):
- """
- Check that the authentication has failed.
- """
- self.assertEqual(self.authServer.transport.packets[-1],
- (userauth.MSG_USERAUTH_FAILURE,
- NS('keyboard-interactive,password,publickey') + '\x00'))
-
-
- def test_noneAuthentication(self):
- """
- A client may request a list of authentication 'method name' values
- that may continue by using the "none" authentication 'method name'.
-
- See RFC 4252 Section 5.2.
- """
- d = self.authServer.ssh_USERAUTH_REQUEST(NS('foo') + NS('service') +
- NS('none'))
- return d.addCallback(self._checkFailed)
-
-
- def test_successfulPasswordAuthentication(self):
- """
- When provided with correct password authentication information, the
- server should respond by sending a MSG_USERAUTH_SUCCESS message with
- no other data.
-
- See RFC 4252, Section 5.1.
- """
- packet = NS('foo') + NS('none') + NS('password') + chr(0) + NS('foo')
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- def check(ignored):
- self.assertEqual(
- self.authServer.transport.packets,
- [(userauth.MSG_USERAUTH_SUCCESS, '')])
- return d.addCallback(check)
-
-
- def test_failedPasswordAuthentication(self):
- """
- When provided with invalid authentication details, the server should
- respond by sending a MSG_USERAUTH_FAILURE message which states whether
- the authentication was partially successful, and provides other, open
- options for authentication.
-
- See RFC 4252, Section 5.1.
- """
- # packet = username, next_service, authentication type, FALSE, password
- packet = NS('foo') + NS('none') + NS('password') + chr(0) + NS('bar')
- self.authServer.clock = task.Clock()
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.assertEqual(self.authServer.transport.packets, [])
- self.authServer.clock.advance(2)
- return d.addCallback(self._checkFailed)
-
-
- def test_successfulPrivateKeyAuthentication(self):
- """
- Test that private key authentication completes sucessfully,
- """
- blob = keys.Key.fromString(keydata.publicRSA_openssh).blob()
- obj = keys.Key.fromString(keydata.privateRSA_openssh)
- packet = (NS('foo') + NS('none') + NS('publickey') + '\xff'
- + NS(obj.sshType()) + NS(blob))
- self.authServer.transport.sessionID = 'test'
- signature = obj.sign(NS('test') + chr(userauth.MSG_USERAUTH_REQUEST)
- + packet)
- packet += NS(signature)
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- def check(ignored):
- self.assertEqual(self.authServer.transport.packets,
- [(userauth.MSG_USERAUTH_SUCCESS, '')])
- return d.addCallback(check)
-
-
- def test_requestRaisesConchError(self):
- """
- ssh_USERAUTH_REQUEST should raise a ConchError if tryAuth returns
- None. Added to catch a bug noticed by pyflakes.
- """
- d = defer.Deferred()
-
- def mockCbFinishedAuth(self, ignored):
- self.fail('request should have raised ConochError')
-
- def mockTryAuth(kind, user, data):
- return None
-
- def mockEbBadAuth(reason):
- d.errback(reason.value)
-
- self.patch(self.authServer, 'tryAuth', mockTryAuth)
- self.patch(self.authServer, '_cbFinishedAuth', mockCbFinishedAuth)
- self.patch(self.authServer, '_ebBadAuth', mockEbBadAuth)
-
- packet = NS('user') + NS('none') + NS('public-key') + NS('data')
- # If an error other than ConchError is raised, this will trigger an
- # exception.
- self.authServer.ssh_USERAUTH_REQUEST(packet)
- return self.assertFailure(d, ConchError)
-
-
- def test_verifyValidPrivateKey(self):
- """
- Test that verifying a valid private key works.
- """
- blob = keys.Key.fromString(keydata.publicRSA_openssh).blob()
- packet = (NS('foo') + NS('none') + NS('publickey') + '\x00'
- + NS('ssh-rsa') + NS(blob))
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- def check(ignored):
- self.assertEqual(self.authServer.transport.packets,
- [(userauth.MSG_USERAUTH_PK_OK, NS('ssh-rsa') + NS(blob))])
- return d.addCallback(check)
-
-
- def test_failedPrivateKeyAuthenticationWithoutSignature(self):
- """
- Test that private key authentication fails when the public key
- is invalid.
- """
- blob = keys.Key.fromString(keydata.publicDSA_openssh).blob()
- packet = (NS('foo') + NS('none') + NS('publickey') + '\x00'
- + NS('ssh-dsa') + NS(blob))
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- return d.addCallback(self._checkFailed)
-
-
- def test_failedPrivateKeyAuthenticationWithSignature(self):
- """
- Test that private key authentication fails when the public key
- is invalid.
- """
- blob = keys.Key.fromString(keydata.publicRSA_openssh).blob()
- obj = keys.Key.fromString(keydata.privateRSA_openssh)
- packet = (NS('foo') + NS('none') + NS('publickey') + '\xff'
- + NS('ssh-rsa') + NS(blob) + NS(obj.sign(blob)))
- self.authServer.transport.sessionID = 'test'
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- return d.addCallback(self._checkFailed)
-
-
- def test_successfulPAMAuthentication(self):
- """
- Test that keyboard-interactive authentication succeeds.
- """
- packet = (NS('foo') + NS('none') + NS('keyboard-interactive')
- + NS('') + NS(''))
- response = '\x00\x00\x00\x02' + NS('foo') + NS('foo')
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.authServer.ssh_USERAUTH_INFO_RESPONSE(response)
- def check(ignored):
- self.assertEqual(self.authServer.transport.packets,
- [(userauth.MSG_USERAUTH_INFO_REQUEST, (NS('') + NS('')
- + NS('') + '\x00\x00\x00\x02' + NS('Name: ') + '\x01'
- + NS('Password: ') + '\x00')),
- (userauth.MSG_USERAUTH_SUCCESS, '')])
-
- return d.addCallback(check)
-
-
- def test_failedPAMAuthentication(self):
- """
- Test that keyboard-interactive authentication fails.
- """
- packet = (NS('foo') + NS('none') + NS('keyboard-interactive')
- + NS('') + NS(''))
- response = '\x00\x00\x00\x02' + NS('bar') + NS('bar')
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.authServer.ssh_USERAUTH_INFO_RESPONSE(response)
- def check(ignored):
- self.assertEqual(self.authServer.transport.packets[0],
- (userauth.MSG_USERAUTH_INFO_REQUEST, (NS('') + NS('')
- + NS('') + '\x00\x00\x00\x02' + NS('Name: ') + '\x01'
- + NS('Password: ') + '\x00')))
- return d.addCallback(check).addCallback(self._checkFailed)
-
-
- def test_invalid_USERAUTH_INFO_RESPONSE_not_enough_data(self):
- """
- If ssh_USERAUTH_INFO_RESPONSE gets an invalid packet,
- the user authentication should fail.
- """
- packet = (NS('foo') + NS('none') + NS('keyboard-interactive')
- + NS('') + NS(''))
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.authServer.ssh_USERAUTH_INFO_RESPONSE(NS('\x00\x00\x00\x00' +
- NS('hi')))
- return d.addCallback(self._checkFailed)
-
-
- def test_invalid_USERAUTH_INFO_RESPONSE_too_much_data(self):
- """
- If ssh_USERAUTH_INFO_RESPONSE gets too much data, the user
- authentication should fail.
- """
- packet = (NS('foo') + NS('none') + NS('keyboard-interactive')
- + NS('') + NS(''))
- response = '\x00\x00\x00\x02' + NS('foo') + NS('foo') + NS('foo')
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.authServer.ssh_USERAUTH_INFO_RESPONSE(response)
- return d.addCallback(self._checkFailed)
-
-
- def test_onlyOnePAMAuthentication(self):
- """
- Because it requires an intermediate message, one can't send a second
- keyboard-interactive request while the first is still pending.
- """
- packet = (NS('foo') + NS('none') + NS('keyboard-interactive')
- + NS('') + NS(''))
- self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.assertEqual(self.authServer.transport.packets[-1][0],
- transport.MSG_DISCONNECT)
- self.assertEqual(self.authServer.transport.packets[-1][1][3],
- chr(transport.DISCONNECT_PROTOCOL_ERROR))
-
-
- def test_ignoreUnknownCredInterfaces(self):
- """
- L{SSHUserAuthServer} sets up
- C{SSHUserAuthServer.supportedAuthentications} by checking the portal's
- credentials interfaces and mapping them to SSH authentication method
- strings. If the Portal advertises an interface that
- L{SSHUserAuthServer} can't map, it should be ignored. This is a white
- box test.
- """
- server = userauth.SSHUserAuthServer()
- server.transport = FakeTransport(self.portal)
- self.portal.registerChecker(AnonymousChecker())
- server.serviceStarted()
- server.serviceStopped()
- server.supportedAuthentications.sort() # give a consistent order
- self.assertEqual(server.supportedAuthentications,
- ['keyboard-interactive', 'password', 'publickey'])
-
-
- def test_removePasswordIfUnencrypted(self):
- """
- Test that the userauth service does not advertise password
- authentication if the password would be send in cleartext.
- """
- self.assertIn('password', self.authServer.supportedAuthentications)
- # no encryption
- clearAuthServer = userauth.SSHUserAuthServer()
- clearAuthServer.transport = FakeTransport(self.portal)
- clearAuthServer.transport.isEncrypted = lambda x: False
- clearAuthServer.serviceStarted()
- clearAuthServer.serviceStopped()
- self.failIfIn('password', clearAuthServer.supportedAuthentications)
- # only encrypt incoming (the direction the password is sent)
- halfAuthServer = userauth.SSHUserAuthServer()
- halfAuthServer.transport = FakeTransport(self.portal)
- halfAuthServer.transport.isEncrypted = lambda x: x == 'in'
- halfAuthServer.serviceStarted()
- halfAuthServer.serviceStopped()
- self.assertIn('password', halfAuthServer.supportedAuthentications)
-
-
- def test_removeKeyboardInteractiveIfUnencrypted(self):
- """
- Test that the userauth service does not advertise keyboard-interactive
- authentication if the password would be send in cleartext.
- """
- self.assertIn('keyboard-interactive',
- self.authServer.supportedAuthentications)
- # no encryption
- clearAuthServer = userauth.SSHUserAuthServer()
- clearAuthServer.transport = FakeTransport(self.portal)
- clearAuthServer.transport.isEncrypted = lambda x: False
- clearAuthServer.serviceStarted()
- clearAuthServer.serviceStopped()
- self.failIfIn('keyboard-interactive',
- clearAuthServer.supportedAuthentications)
- # only encrypt incoming (the direction the password is sent)
- halfAuthServer = userauth.SSHUserAuthServer()
- halfAuthServer.transport = FakeTransport(self.portal)
- halfAuthServer.transport.isEncrypted = lambda x: x == 'in'
- halfAuthServer.serviceStarted()
- halfAuthServer.serviceStopped()
- self.assertIn('keyboard-interactive',
- halfAuthServer.supportedAuthentications)
-
-
- def test_unencryptedConnectionWithoutPasswords(self):
- """
- If the L{SSHUserAuthServer} is not advertising passwords, then an
- unencrypted connection should not cause any warnings or exceptions.
- This is a white box test.
- """
- # create a Portal without password authentication
- portal = Portal(self.realm)
- portal.registerChecker(PrivateKeyChecker())
-
- # no encryption
- clearAuthServer = userauth.SSHUserAuthServer()
- clearAuthServer.transport = FakeTransport(portal)
- clearAuthServer.transport.isEncrypted = lambda x: False
- clearAuthServer.serviceStarted()
- clearAuthServer.serviceStopped()
- self.assertEqual(clearAuthServer.supportedAuthentications,
- ['publickey'])
-
- # only encrypt incoming (the direction the password is sent)
- halfAuthServer = userauth.SSHUserAuthServer()
- halfAuthServer.transport = FakeTransport(portal)
- halfAuthServer.transport.isEncrypted = lambda x: x == 'in'
- halfAuthServer.serviceStarted()
- halfAuthServer.serviceStopped()
- self.assertEqual(clearAuthServer.supportedAuthentications,
- ['publickey'])
-
-
- def test_loginTimeout(self):
- """
- Test that the login times out.
- """
- timeoutAuthServer = userauth.SSHUserAuthServer()
- timeoutAuthServer.clock = task.Clock()
- timeoutAuthServer.transport = FakeTransport(self.portal)
- timeoutAuthServer.serviceStarted()
- timeoutAuthServer.clock.advance(11 * 60 * 60)
- timeoutAuthServer.serviceStopped()
- self.assertEqual(timeoutAuthServer.transport.packets,
- [(transport.MSG_DISCONNECT,
- '\x00' * 3 +
- chr(transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) +
- NS("you took too long") + NS(''))])
- self.assertTrue(timeoutAuthServer.transport.lostConnection)
-
-
- def test_cancelLoginTimeout(self):
- """
- Test that stopping the service also stops the login timeout.
- """
- timeoutAuthServer = userauth.SSHUserAuthServer()
- timeoutAuthServer.clock = task.Clock()
- timeoutAuthServer.transport = FakeTransport(self.portal)
- timeoutAuthServer.serviceStarted()
- timeoutAuthServer.serviceStopped()
- timeoutAuthServer.clock.advance(11 * 60 * 60)
- self.assertEqual(timeoutAuthServer.transport.packets, [])
- self.assertFalse(timeoutAuthServer.transport.lostConnection)
-
-
- def test_tooManyAttempts(self):
- """
- Test that the server disconnects if the client fails authentication
- too many times.
- """
- packet = NS('foo') + NS('none') + NS('password') + chr(0) + NS('bar')
- self.authServer.clock = task.Clock()
- for i in range(21):
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- self.authServer.clock.advance(2)
- def check(ignored):
- self.assertEqual(self.authServer.transport.packets[-1],
- (transport.MSG_DISCONNECT,
- '\x00' * 3 +
- chr(transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) +
- NS("too many bad auths") + NS('')))
- return d.addCallback(check)
-
-
- def test_failIfUnknownService(self):
- """
- If the user requests a service that we don't support, the
- authentication should fail.
- """
- packet = NS('foo') + NS('') + NS('password') + chr(0) + NS('foo')
- self.authServer.clock = task.Clock()
- d = self.authServer.ssh_USERAUTH_REQUEST(packet)
- return d.addCallback(self._checkFailed)
-
-
- def test__pamConvErrors(self):
- """
- _pamConv should fail if it gets a message that's not 1 or 2.
- """
- def secondTest(ignored):
- d2 = self.authServer._pamConv([('', 90)])
- return self.assertFailure(d2, ConchError)
-
- d = self.authServer._pamConv([('', 3)])
- return self.assertFailure(d, ConchError).addCallback(secondTest)
-
-
- def test_tryAuthEdgeCases(self):
- """
- tryAuth() has two edge cases that are difficult to reach.
-
- 1) an authentication method auth_* returns None instead of a Deferred.
- 2) an authentication type that is defined does not have a matching
- auth_* method.
-
- Both these cases should return a Deferred which fails with a
- ConchError.
- """
- def mockAuth(packet):
- return None
-
- self.patch(self.authServer, 'auth_publickey', mockAuth) # first case
- self.patch(self.authServer, 'auth_password', None) # second case
-
- def secondTest(ignored):
- d2 = self.authServer.tryAuth('password', None, None)
- return self.assertFailure(d2, ConchError)
-
- d1 = self.authServer.tryAuth('publickey', None, None)
- return self.assertFailure(d1, ConchError).addCallback(secondTest)
-
-
-
-
-class SSHUserAuthClientTestCase(unittest.TestCase):
- """
- Tests for SSHUserAuthClient.
- """
-
-
- if keys is None:
- skip = "cannot run w/o PyCrypto"
-
-
- def setUp(self):
- self.authClient = ClientUserAuth('foo', FakeTransport.Service())
- self.authClient.transport = FakeTransport(None)
- self.authClient.transport.sessionID = 'test'
- self.authClient.serviceStarted()
-
-
- def tearDown(self):
- self.authClient.serviceStopped()
- self.authClient = None
-
-
- def test_init(self):
- """
- Test that client is initialized properly.
- """
- self.assertEqual(self.authClient.user, 'foo')
- self.assertEqual(self.authClient.instance.name, 'nancy')
- self.assertEqual(self.authClient.transport.packets,
- [(userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('none'))])
-
-
- def test_USERAUTH_SUCCESS(self):
- """
- Test that the client succeeds properly.
- """
- instance = [None]
- def stubSetService(service):
- instance[0] = service
- self.authClient.transport.setService = stubSetService
- self.authClient.ssh_USERAUTH_SUCCESS('')
- self.assertEqual(instance[0], self.authClient.instance)
-
-
- def test_publickey(self):
- """
- Test that the client can authenticate with a public key.
- """
- self.authClient.ssh_USERAUTH_FAILURE(NS('publickey') + '\x00')
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('publickey') + '\x00' + NS('ssh-dss')
- + NS(keys.Key.fromString(
- keydata.publicDSA_openssh).blob())))
- # that key isn't good
- self.authClient.ssh_USERAUTH_FAILURE(NS('publickey') + '\x00')
- blob = NS(keys.Key.fromString(keydata.publicRSA_openssh).blob())
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, (NS('foo') + NS('nancy')
- + NS('publickey') + '\x00'+ NS('ssh-rsa') + blob)))
- self.authClient.ssh_USERAUTH_PK_OK(NS('ssh-rsa')
- + NS(keys.Key.fromString(keydata.publicRSA_openssh).blob()))
- sigData = (NS(self.authClient.transport.sessionID)
- + chr(userauth.MSG_USERAUTH_REQUEST) + NS('foo')
- + NS('nancy') + NS('publickey') + '\x01' + NS('ssh-rsa')
- + blob)
- obj = keys.Key.fromString(keydata.privateRSA_openssh)
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('publickey') + '\x01' + NS('ssh-rsa') + blob
- + NS(obj.sign(sigData))))
-
-
- def test_publickey_without_privatekey(self):
- """
- If the SSHUserAuthClient doesn't return anything from signData,
- the client should start the authentication over again by requesting
- 'none' authentication.
- """
- authClient = ClientAuthWithoutPrivateKey('foo',
- FakeTransport.Service())
-
- authClient.transport = FakeTransport(None)
- authClient.transport.sessionID = 'test'
- authClient.serviceStarted()
- authClient.tryAuth('publickey')
- authClient.transport.packets = []
- self.assertIdentical(authClient.ssh_USERAUTH_PK_OK(''), None)
- self.assertEqual(authClient.transport.packets, [
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') +
- NS('none'))])
-
-
- def test_old_publickey_getPublicKey(self):
- """
- Old SSHUserAuthClients returned strings of public key blobs from
- getPublicKey(). Test that a Deprecation warning is raised but the key is
- verified correctly.
- """
- oldAuth = OldClientAuth('foo', FakeTransport.Service())
- oldAuth.transport = FakeTransport(None)
- oldAuth.transport.sessionID = 'test'
- oldAuth.serviceStarted()
- oldAuth.transport.packets = []
- self.assertWarns(DeprecationWarning, "Returning a string from "
- "SSHUserAuthClient.getPublicKey() is deprecated since "
- "Twisted 9.0. Return a keys.Key() instead.",
- userauth.__file__, oldAuth.tryAuth, 'publickey')
- self.assertEqual(oldAuth.transport.packets, [
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') +
- NS('publickey') + '\x00' + NS('ssh-rsa') +
- NS(keys.Key.fromString(keydata.publicRSA_openssh).blob()))])
-
-
- def test_old_publickey_getPrivateKey(self):
- """
- Old SSHUserAuthClients returned a PyCrypto key object from
- getPrivateKey(). Test that _cbSignData signs the data warns the
- user about the deprecation, but signs the data correctly.
- """
- oldAuth = OldClientAuth('foo', FakeTransport.Service())
- d = self.assertWarns(DeprecationWarning, "Returning a PyCrypto key "
- "object from SSHUserAuthClient.getPrivateKey() is "
- "deprecated since Twisted 9.0. "
- "Return a keys.Key() instead.", userauth.__file__,
- oldAuth.signData, None, 'data')
- def _checkSignedData(sig):
- self.assertEqual(sig,
- keys.Key.fromString(keydata.privateRSA_openssh).sign(
- 'data'))
- d.addCallback(_checkSignedData)
- return d
-
-
- def test_no_publickey(self):
- """
- If there's no public key, auth_publickey should return a Deferred
- called back with a False value.
- """
- self.authClient.getPublicKey = lambda x: None
- d = self.authClient.tryAuth('publickey')
- def check(result):
- self.assertFalse(result)
- return d.addCallback(check)
-
- def test_password(self):
- """
- Test that the client can authentication with a password. This
- includes changing the password.
- """
- self.authClient.ssh_USERAUTH_FAILURE(NS('password') + '\x00')
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('password') + '\x00' + NS('foo')))
- self.authClient.ssh_USERAUTH_PK_OK(NS('') + NS(''))
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('password') + '\xff' + NS('foo') * 2))
-
-
- def test_no_password(self):
- """
- If getPassword returns None, tryAuth should return False.
- """
- self.authClient.getPassword = lambda: None
- self.assertFalse(self.authClient.tryAuth('password'))
-
-
- def test_keyboardInteractive(self):
- """
- Test that the client can authenticate using keyboard-interactive
- authentication.
- """
- self.authClient.ssh_USERAUTH_FAILURE(NS('keyboard-interactive')
- + '\x00')
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('keyboard-interactive') + NS('')*2))
- self.authClient.ssh_USERAUTH_PK_OK(NS('')*3 + '\x00\x00\x00\x02'
- + NS('Name: ') + '\xff' + NS('Password: ') + '\x00')
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_INFO_RESPONSE, '\x00\x00\x00\x02'
- + NS('foo')*2))
-
-
- def test_USERAUTH_PK_OK_unknown_method(self):
- """
- If C{SSHUserAuthClient} gets a MSG_USERAUTH_PK_OK packet when it's not
- expecting it, it should fail the current authentication and move on to
- the next type.
- """
- self.authClient.lastAuth = 'unknown'
- self.authClient.transport.packets = []
- self.authClient.ssh_USERAUTH_PK_OK('')
- self.assertEqual(self.authClient.transport.packets,
- [(userauth.MSG_USERAUTH_REQUEST, NS('foo') +
- NS('nancy') + NS('none'))])
-
-
- def test_USERAUTH_FAILURE_sorting(self):
- """
- ssh_USERAUTH_FAILURE should sort the methods by their position
- in SSHUserAuthClient.preferredOrder. Methods that are not in
- preferredOrder should be sorted at the end of that list.
- """
- def auth_firstmethod():
- self.authClient.transport.sendPacket(255, 'here is data')
- def auth_anothermethod():
- self.authClient.transport.sendPacket(254, 'other data')
- return True
- self.authClient.auth_firstmethod = auth_firstmethod
- self.authClient.auth_anothermethod = auth_anothermethod
-
- # although they shouldn't get called, method callbacks auth_* MUST
- # exist in order for the test to work properly.
- self.authClient.ssh_USERAUTH_FAILURE(NS('anothermethod,password') +
- '\x00')
- # should send password packet
- self.assertEqual(self.authClient.transport.packets[-1],
- (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('password') + '\x00' + NS('foo')))
- self.authClient.ssh_USERAUTH_FAILURE(
- NS('firstmethod,anothermethod,password') + '\xff')
- self.assertEqual(self.authClient.transport.packets[-2:],
- [(255, 'here is data'), (254, 'other data')])
-
-
- def test_disconnectIfNoMoreAuthentication(self):
- """
- If there are no more available user authentication messages,
- the SSHUserAuthClient should disconnect with code
- DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE.
- """
- self.authClient.ssh_USERAUTH_FAILURE(NS('password') + '\x00')
- self.authClient.ssh_USERAUTH_FAILURE(NS('password') + '\xff')
- self.assertEqual(self.authClient.transport.packets[-1],
- (transport.MSG_DISCONNECT, '\x00\x00\x00\x0e' +
- NS('no more authentication methods available') +
- '\x00\x00\x00\x00'))
-
-
- def test_ebAuth(self):
- """
- _ebAuth (the generic authentication error handler) should send
- a request for the 'none' authentication method.
- """
- self.authClient.transport.packets = []
- self.authClient._ebAuth(None)
- self.assertEqual(self.authClient.transport.packets,
- [(userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy')
- + NS('none'))])
-
-
- def test_defaults(self):
- """
- getPublicKey() should return None. getPrivateKey() should return a
- failed Deferred. getPassword() should return a failed Deferred.
- getGenericAnswers() should return a failed Deferred.
- """
- authClient = userauth.SSHUserAuthClient('foo', FakeTransport.Service())
- self.assertIdentical(authClient.getPublicKey(), None)
- def check(result):
- result.trap(NotImplementedError)
- d = authClient.getPassword()
- return d.addCallback(self.fail).addErrback(check2)
- def check2(result):
- result.trap(NotImplementedError)
- d = authClient.getGenericAnswers(None, None, None)
- return d.addCallback(self.fail).addErrback(check3)
- def check3(result):
- result.trap(NotImplementedError)
- d = authClient.getPrivateKey()
- return d.addCallback(self.fail).addErrback(check)
-
-
-
-class LoopbackTestCase(unittest.TestCase):
-
-
- if keys is None:
- skip = "cannot run w/o PyCrypto or PyASN1"
-
-
- class Factory:
- class Service:
- name = 'TestService'
-
-
- def serviceStarted(self):
- self.transport.loseConnection()
-
-
- def serviceStopped(self):
- pass
-
-
- def getService(self, avatar, name):
- return self.Service
-
-
- def test_loopback(self):
- """
- Test that the userauth server and client play nicely with each other.
- """
- server = userauth.SSHUserAuthServer()
- client = ClientUserAuth('foo', self.Factory.Service())
-
- # set up transports
- server.transport = transport.SSHTransportBase()
- server.transport.service = server
- server.transport.isEncrypted = lambda x: True
- client.transport = transport.SSHTransportBase()
- client.transport.service = client
- server.transport.sessionID = client.transport.sessionID = ''
- # don't send key exchange packet
- server.transport.sendKexInit = client.transport.sendKexInit = \
- lambda: None
-
- # set up server authentication
- server.transport.factory = self.Factory()
- server.passwordDelay = 0 # remove bad password delay
- realm = Realm()
- portal = Portal(realm)
- checker = SSHProtocolChecker()
- checker.registerChecker(PasswordChecker())
- checker.registerChecker(PrivateKeyChecker())
- checker.registerChecker(PAMChecker())
- checker.areDone = lambda aId: (
- len(checker.successfulCredentials[aId]) == 3)
- portal.registerChecker(checker)
- server.transport.factory.portal = portal
-
- d = loopback.loopbackAsync(server.transport, client.transport)
- server.transport.transport.logPrefix = lambda: '_ServerLoopback'
- client.transport.transport.logPrefix = lambda: '_ClientLoopback'
-
- server.serviceStarted()
- client.serviceStarted()
-
- def check(ignored):
- self.assertEqual(server.transport.service.name, 'TestService')
- return d.addCallback(check)
-
-
-
-class ModuleInitializationTestCase(unittest.TestCase):
- if keys is None:
- skip = "cannot run w/o PyCrypto or PyASN1"
-
-
- def test_messages(self):
- # Several message types have value 60, check that MSG_USERAUTH_PK_OK
- # is always the one which is mapped.
- self.assertEqual(userauth.SSHUserAuthServer.protocolMessages[60],
- 'MSG_USERAUTH_PK_OK')
- self.assertEqual(userauth.SSHUserAuthClient.protocolMessages[60],
- 'MSG_USERAUTH_PK_OK')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py
deleted file mode 100755
index 6d7d9d28..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py
+++ /dev/null
@@ -1,67 +0,0 @@
-
-"""
-Tests for the insults windowing module, L{twisted.conch.insults.window}.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.conch.insults.window import TopWindow, ScrolledArea, TextOutput
-
-
-class TopWindowTests(TestCase):
- """
- Tests for L{TopWindow}, the root window container class.
- """
-
- def test_paintScheduling(self):
- """
- Verify that L{TopWindow.repaint} schedules an actual paint to occur
- using the scheduling object passed to its initializer.
- """
- paints = []
- scheduled = []
- root = TopWindow(lambda: paints.append(None), scheduled.append)
-
- # Nothing should have happened yet.
- self.assertEqual(paints, [])
- self.assertEqual(scheduled, [])
-
- # Cause a paint to be scheduled.
- root.repaint()
- self.assertEqual(paints, [])
- self.assertEqual(len(scheduled), 1)
-
- # Do another one to verify nothing else happens as long as the previous
- # one is still pending.
- root.repaint()
- self.assertEqual(paints, [])
- self.assertEqual(len(scheduled), 1)
-
- # Run the actual paint call.
- scheduled.pop()()
- self.assertEqual(len(paints), 1)
- self.assertEqual(scheduled, [])
-
- # Do one more to verify that now that the previous one is finished
- # future paints will succeed.
- root.repaint()
- self.assertEqual(len(paints), 1)
- self.assertEqual(len(scheduled), 1)
-
-
-
-class ScrolledAreaTests(TestCase):
- """
- Tests for L{ScrolledArea}, a widget which creates a viewport containing
- another widget and can reposition that viewport using scrollbars.
- """
- def test_parent(self):
- """
- The parent of the widget passed to L{ScrolledArea} is set to a new
- L{Viewport} created by the L{ScrolledArea} which itself has the
- L{ScrolledArea} instance as its parent.
- """
- widget = TextOutput()
- scrolled = ScrolledArea(widget)
- self.assertIdentical(widget.parent, scrolled._viewport)
- self.assertIdentical(scrolled._viewport.parent, scrolled)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS
deleted file mode 100644
index e3a12638..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS
+++ /dev/null
@@ -1,414 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Conch 12.2.0 (2012-08-26)
-=================================
-
-Features
---------
- - twisted.conch.ssh.transport.SSHTransport now returns an
- SSHTransportAddress from the getPeer() and getHost() methods.
- (#2997)
-
-Bugfixes
---------
- - twisted.conch now supports commercial SSH implementations which
- don't comply with the IETF standard (#1902)
- - twisted.conch.ssh.userauth now works correctly with hash
- randomization enabled. (#5776)
- - twisted.conch no longer relies on __builtins__ being a dict, which
- is a purely CPython implementation detail (#5779)
-
-Other
------
- - #5496, #5617, #5700, #5748, #5777
-
-
-Twisted Conch 12.1.0 (2012-06-02)
-=================================
-
-Features
---------
- - twisted.conch.tap now supports cred plugins (#4753)
-
-Bugfixes
---------
- - twisted.conch.client.knownhosts now handles errors encountered
- parsing hashed entries in a known hosts file. (#5616)
-
-Improved Documentation
-----------------------
- - Conch examples window.tac and telnet_echo.tac now have better
- explanations. (#5590)
-
-Other
------
- - #5580
-
-
-Twisted Conch 12.0.0 (2012-02-10)
-=================================
-
-Features
---------
- - use Python shadow module for authentication if it's available
- (#3242)
-
-Bugfixes
---------
- - twisted.conch.ssh.transport.messages no longer ends with with old
- message IDs on platforms with differing dict() orderings (#5352)
-
-Other
------
- - #5225
-
-
-Twisted Conch 11.1.0 (2011-11-15)
-=================================
-
-Features
---------
- - twisted.conch.ssh.filetransfer.FileTransferClient now handles short
- status messages, not strictly allowed by the RFC, but sent by some
- SSH implementations. (#3009)
- - twisted.conch.manhole now supports CTRL-A and CTRL-E to trigger
- HOME and END functions respectively. (#5252)
-
-Bugfixes
---------
- - When run from an unpacked source tarball or a VCS checkout, the
- bin/conch/ scripts will now use the version of Twisted they are
- part of. (#3526)
- - twisted.conch.insults.window.ScrolledArea now passes no extra
- arguments to object.__init__ (which works on more versions of
- Python). (#4197)
- - twisted.conch.telnet.ITelnetProtocol now has the correct signature
- for its unhandledSubnegotiation() method. (#4751)
- - twisted.conch.ssh.userauth.SSHUserAuthClient now more closely
- follows the RFC 4251 definition of boolean values when negotiating
- for key-based authentication, allowing better interoperability with
- other SSH implementations. (#5241)
- - twisted.conch.recvline.RecvLine now ignores certain function keys
- in its keystrokeReceived method instead of raising an exception.
- (#5246)
-
-Deprecations and Removals
--------------------------
- - The --user option to `twistd manhole' has been removed as it was
- dead code with no functionality associated with it. (#5283)
-
-Other
------
- - #5107, #5256, #5349
-
-
-Twisted Conch 11.0.0 (2011-04-01)
-=================================
-
-Bugfixes
---------
- - The transport for subsystem protocols now declares that it
- implements ITransport and implements the getHost and getPeer
- methods. (#2453)
- - twisted.conch.ssh.transport.SSHTransportBase now responds to key
- exchange messages at any time during a connection (instead of only
- at connection setup). It also queues non-key exchange messages
- sent during key exchange to avoid corrupting the connection state.
- (#4395)
- - Importing twisted.conch.ssh.common no longer breaks pow(base, exp[,
- modulus]) when the gmpy package is installed and base is not an
- integer. (#4803)
- - twisted.conch.ls.lsLine now returns a time string which does not
- consider the locale. (#4937)
-
-Improved Documentation
-----------------------
- - Changed the man page for ckeygen to accurately reflect what it
- does, and corrected its synposis so that a second "ckeygen" is not
- a required part of the ckeygen command line. (#4738)
-
-Other
------
- - #2112
-
-
-Twisted Conch 10.2.0 (2010-11-29)
-=================================
-
-Bugfixes
---------
- - twisted.conch.ssh.factory.SSHFactory no longer disables coredumps.
- (#2715)
- - The Deferred returned by twisted.conch.telnet.TelnetTransport.will
- now fires with an OptionRefused failure if the peer responds with a
- refusal for the option negotiation. (#4231)
- - SSHServerTransport and SSHClientTransport in
- twisted.conch.ssh.transport no longer use PyCrypto to generate
- random numbers for DH KEX. They also now generate values from the
- full valid range, rather than only half of it. (#4469)
- - twisted.conch.ssh.connection.SSHConnection now errbacks leftover
- request deferreds on connection shutdown. (#4483)
-
-Other
------
- - #4677
-
-
-Twisted Conch 10.1.0 (2010-06-27)
-=================================
-
-Features
---------
- - twisted.conch.ssh.transport.SSHTransportBase now allows supported
- ssh protocol versions to be overriden. (#4428)
-
-Bugfixes
---------
- - SSHSessionProcessProtocol now doesn't close the session when stdin
- is closed, but instead when both stdout and stderr are. (#4350)
- - The 'cftp' command-line tool will no longer encounter an
- intermittent error, crashing at startup with a ZeroDivisionError
- while trying to report progress. (#4463)
- - twisted.conch.ssh.connection.SSHConnection now replies to requests
- to open an unknown channel with a OPEN_UNKNOWN_CHANNEL_TYPE message
- instead of closing the connection. (#4490)
-
-Deprecations and Removals
--------------------------
- - twisted.conch.insults.client was deprecated. (#4095)
- - twisted.conch.insults.colors has been deprecated. Please use
- twisted.conch.insults.helper instead. (#4096)
- - Removed twisted.conch.ssh.asn1, which has been deprecated since
- Twisted 9.0. (#4097)
- - Removed twisted.conch.ssh.common.Entropy, as Entropy.get_bytes has
- been deprecated since 2007 and Entropy.get_bytes was the only
- attribute of Entropy. (#4098)
- - Removed twisted.conch.ssh.keys.getPublicKeyString, which has been
- deprecated since 2007. Also updated the conch examples
- sshsimpleserver.py and sshsimpleclient.py to reflect this removal.
- (#4099)
- - Removed twisted.conch.ssh.keys.makePublicKeyString, which has been
- deprecated since 2007. (#4100)
- - Removed twisted.conch.ssh.keys.getPublicKeyObject, which has been
- deprecated since 2007. (#4101)
- - Removed twisted.conch.ssh.keys.getPrivateKeyObject, which has been
- deprecated since 2007. Also updated the conch examples to reflect
- this removal. (#4102)
- - Removed twisted.conch.ssh.keys.makePrivateKeyString, which has been
- deprecated since 2007. (#4103)
- - Removed twisted.conch.ssh.keys.makePublicKeyBlob, which has been
- deprecated since 2007. (#4104)
- - Removed twisted.conch.ssh.keys.signData,
- twisted.conch.ssh.keys.verifySignature, and
- twisted.conch.ssh.keys.printKey, which have been deprecated since
- 2007. (#4105)
-
-Other
------
- - #3849, #4408, #4454
-
-
-Twisted Conch 10.0.0 (2010-03-01)
-=================================
-
-Bugfixes
---------
- - twisted.conch.checkers.SSHPublicKeyDatabase now looks in the
- correct user directory for authorized_keys files. (#3984)
-
- - twisted.conch.ssh.SSHUserAuthClient now honors preferredOrder when
- authenticating. (#4266)
-
-Other
------
- - #2391, #4203, #4265
-
-
-Twisted Conch 9.0.0 (2009-11-24)
-================================
-
-Fixes
------
- - The SSH key parser has been removed and conch now uses pyASN1 to parse keys.
- This should fix a number of cases where parsing a key would fail, but it now
- requires users to have pyASN1 installed (#3391)
- - The time field on SFTP file listings should now be correct (#3503)
- - The day field on SFTP file listings should now be correct on Windows (#3503)
- - The "cftp" sftp client now truncates files it is uploading over (#2519)
- - The telnet server protocol can now properly respond to subnegotiation
- requests (#3655)
- - Tests and factoring of the SSHv2 server implementation are now much better
- (#2682)
- - The SSHv2 server now sends "exit-signal" messages to the client, instead of
- raising an exception, when a process dies due to a signal (#2687)
- - cftp's client-side "exec" command now uses /bin/sh if the current user has
- no shell (#3914)
-
-Deprecations and Removals
--------------------------
- - The buggy SSH connection sharing feature of the SSHv2 client was removed
- (#3498)
- - Use of strings and PyCrypto objects to represent keys is deprecated in favor
- of using Conch Key objects (#2682)
-
-Other
------
- - #3548, #3537, #3551, #3220, #3568, #3689, #3709, #3809, #2763, #3540, #3750,
- #3897, #3813, #3871, #3916, #4047, #3940, #4050
-
-
-Conch 8.2.0 (2008-12-16)
-========================
-
-Features
---------
- - The type of the protocols instantiated by SSHFactory is now parameterized
- (#3443)
-
-Fixes
------
- - A file descriptor leak has been fixed (#3213, #1789)
- - "File Already Exists" errors are now handled more correctly (#3033)
- - Handling of CR IAC in TelnetClient is now improved (#3305)
- - SSHAgent is no longer completely unusable (#3332)
- - The performance of insults.ClientProtocol is now greatly increased by
- delivering more than one byte at a time to application code (#3386)
- - Manhole and the conch server no longer need to be run as root when not
- necessary (#2607)
- - The value of FILEXFER_ATTR_ACMODTIME has been corrected (#2902)
- - The management of known_hosts and host key verification has been overhauled
- (#1376, #1301, #3494, #3496, #1292, #3499)
-
-Other
------
- - #3193, #1633
-
-
-8.1.0 (2008-05-18)
-==================
-
-Fixes
------
- - A regression was fixed whereby the publicKeys and privateKeys attributes of
- SSHFactory would not be interpreted as strings (#3141)
- - The sshsimpleserver.py example had a minor bug fix (#3135)
- - The deprecated mktap API is no longer used (#3127)
- - An infelicity was fixed whereby a NameError would be raised in certain
- circumstances during authentication when a ConchError should have been
- (#3154)
- - A workaround was added to conch.insults for a bug in gnome-terminal whereby
- it would not scroll correctly (#3189)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Features
---------
- - Add DEC private mode manipulation methods to ITerminalTransport. (#2403)
-
-Fixes
------
- - Parameterize the scheduler function used by the insults TopWindow widget.
- This change breaks backwards compatibility in the TopWindow initializer.
- (#2413)
- - Notify subsystems, like SFTP, of connection close. (#2421)
- - Change the process file descriptor "connection lost" code to reverse the
- setNonBlocking operation done during initialization. (#2371)
- - Change ConsoleManhole to wait for connectionLost notification before
- stopping the reactor. (#2123, #2371)
- - Make SSHUserAuthServer.ssh_USERAUTH_REQUEST return a Deferred. (#2528)
- - Manhole's initializer calls its parent class's initializer with its
- namespace argument. (#2587)
- - Handle ^C during input line continuation in manhole by updating the prompt
- and line buffer correctly. (#2663)
- - Make twisted.conch.telnet.Telnet by default reject all attempts to enable
- options. (#1967)
- - Reduce the number of calls into application code to deliver application-level
- data in twisted.conch.telnet.Telnet.dataReceived (#2107)
- - Fix definition and management of extended attributes in conch file transfer.
- (#3010)
- - Fix parsing of OpenSSH-generated RSA keys with differing ASN.1 packing style.
- (#3008)
- - Fix handling of missing $HOME in twisted.conch.client.unix. (#3061)
-
-Misc
-----
- - #2267, #2378, #2604, #2707, #2341, #2685, #2679, #2912, #2977, #2678, #2709
- #2063, #2847
-
-
-0.8.0 (2007-01-06)
-==================
-
-Features
---------
- - Manhole now supports Ctrl-l to emulate the same behavior in the
- Python interactive interpreter (#1565)
- - Python 2.5 is now supported (#1867)
-
-Misc
-----
- - #1673, #1636, #1892, #1943, #2057, #1180, #1185, #2148, #2159, #2291,
-
-Deprecations and Removals
--------------------------
-
- - The old twisted.cred API (Identities, Authorizers, etc) is no
- longer supported (#1440)
-
-
-0.7.0 (2006-05-21)
-==================
-
-Features
---------
- - Timeout support for ExpectableBuffer.expect()
-
-Fixes
------
- - ~5x speedup for bulk data transfer (#1325)
- - Misc: #1428
-
-0.6.0:
-
- Bugfixes and improvements in SSH support and Insults:
- - PAM authenticator support factored out into twisted.cred
- - Poorly supported next-line terminal operation replaced with simple \r\n
-
- New functionality:
- - An ITerminalTransport implementation with expect-like features
- - Support for the "none" SSH cipher
- - Insults support for handling more keystrokes and more methods for
- terminal manipulation
- - New, simple insults-based widget library added
-
- Better test coverage:
- - Dependence on `localhost' name removed
- - Some timing-sensitive tests changed to be more reliable
- - Process spawning tests initialize environment more robustly
-
-0.5.0:
-
- Many improvements to SSH support. Here's some in particular:
- - Add --reconnect option to conch binary
- - utmp/wtmp logging
- - Unix login improvements, PAM support
- - Add "cftp" -- Conch SFTP.
- - Deferred retrieval of public keys is supported
- - PAM support for client and server
- - Bugfixes:
- - fix conch failing to exit, and hangs.
- - Remote->Local forwarding
- - Channel closing
- - Invalid known_host writing
- - Many others
-
- New functionality:
- - twisted.conch.telnet: new, much improved telnet implementation.
- - twisted.conch.insults: Basic curses-like terminal support (server-side).
- - twisted.conch.manhole: new interactive python interactive interpreter,
- can be used with conch's telnet, ssh, or on the console.
- - Main features: Syntax coloring, line editing, and useful interactive
- handling of Deferreds.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README
deleted file mode 100644
index aa25bb65..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Twisted Conch 12.2.0
-
-Twisted Conch depends on Twisted Core and on Python Crypto extensions
-(<http://www.pycrypto.org>).
-
-The pyasn1 module (<http://pyasn1.sourceforge.net/>) is also required.
-
-gmpy (<http://code.google.com/p/gmpy/>) is strongly recommended to improve
-performance.
-
-Twisted Conch includes a couple simple GUI applications which depend on Tkinter.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py
deleted file mode 100755
index 00b4495f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-import tty
-# this module was autogenerated.
-
-VINTR = 1
-VQUIT = 2
-VERASE = 3
-VKILL = 4
-VEOF = 5
-VEOL = 6
-VEOL2 = 7
-VSTART = 8
-VSTOP = 9
-VSUSP = 10
-VDSUSP = 11
-VREPRINT = 12
-VWERASE = 13
-VLNEXT = 14
-VFLUSH = 15
-VSWTCH = 16
-VSTATUS = 17
-VDISCARD = 18
-IGNPAR = 30
-PARMRK = 31
-INPCK = 32
-ISTRIP = 33
-INLCR = 34
-IGNCR = 35
-ICRNL = 36
-IUCLC = 37
-IXON = 38
-IXANY = 39
-IXOFF = 40
-IMAXBEL = 41
-ISIG = 50
-ICANON = 51
-XCASE = 52
-ECHO = 53
-ECHOE = 54
-ECHOK = 55
-ECHONL = 56
-NOFLSH = 57
-TOSTOP = 58
-IEXTEN = 59
-ECHOCTL = 60
-ECHOKE = 61
-PENDIN = 62
-OPOST = 70
-OLCUC = 71
-ONLCR = 72
-OCRNL = 73
-ONOCR = 74
-ONLRET = 75
-CS7 = 90
-CS8 = 91
-PARENB = 92
-PARODD = 93
-TTY_OP_ISPEED = 128
-TTY_OP_OSPEED = 129
-
-TTYMODES = {
- 1 : 'VINTR',
- 2 : 'VQUIT',
- 3 : 'VERASE',
- 4 : 'VKILL',
- 5 : 'VEOF',
- 6 : 'VEOL',
- 7 : 'VEOL2',
- 8 : 'VSTART',
- 9 : 'VSTOP',
- 10 : 'VSUSP',
- 11 : 'VDSUSP',
- 12 : 'VREPRINT',
- 13 : 'VWERASE',
- 14 : 'VLNEXT',
- 15 : 'VFLUSH',
- 16 : 'VSWTCH',
- 17 : 'VSTATUS',
- 18 : 'VDISCARD',
- 30 : (tty.IFLAG, 'IGNPAR'),
- 31 : (tty.IFLAG, 'PARMRK'),
- 32 : (tty.IFLAG, 'INPCK'),
- 33 : (tty.IFLAG, 'ISTRIP'),
- 34 : (tty.IFLAG, 'INLCR'),
- 35 : (tty.IFLAG, 'IGNCR'),
- 36 : (tty.IFLAG, 'ICRNL'),
- 37 : (tty.IFLAG, 'IUCLC'),
- 38 : (tty.IFLAG, 'IXON'),
- 39 : (tty.IFLAG, 'IXANY'),
- 40 : (tty.IFLAG, 'IXOFF'),
- 41 : (tty.IFLAG, 'IMAXBEL'),
- 50 : (tty.LFLAG, 'ISIG'),
- 51 : (tty.LFLAG, 'ICANON'),
- 52 : (tty.LFLAG, 'XCASE'),
- 53 : (tty.LFLAG, 'ECHO'),
- 54 : (tty.LFLAG, 'ECHOE'),
- 55 : (tty.LFLAG, 'ECHOK'),
- 56 : (tty.LFLAG, 'ECHONL'),
- 57 : (tty.LFLAG, 'NOFLSH'),
- 58 : (tty.LFLAG, 'TOSTOP'),
- 59 : (tty.LFLAG, 'IEXTEN'),
- 60 : (tty.LFLAG, 'ECHOCTL'),
- 61 : (tty.LFLAG, 'ECHOKE'),
- 62 : (tty.LFLAG, 'PENDIN'),
- 70 : (tty.OFLAG, 'OPOST'),
- 71 : (tty.OFLAG, 'OLCUC'),
- 72 : (tty.OFLAG, 'ONLCR'),
- 73 : (tty.OFLAG, 'OCRNL'),
- 74 : (tty.OFLAG, 'ONOCR'),
- 75 : (tty.OFLAG, 'ONLRET'),
-# 90 : (tty.CFLAG, 'CS7'),
-# 91 : (tty.CFLAG, 'CS8'),
- 92 : (tty.CFLAG, 'PARENB'),
- 93 : (tty.CFLAG, 'PARODD'),
- 128 : 'ISPEED',
- 129 : 'OSPEED'
-}
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py
deleted file mode 100755
index ea0eea83..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-
-"""
-twisted.conch.ui is home to the UI elements for tkconch.
-
-Maintainer: Paul Swartz
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py
deleted file mode 100755
index 9d5e616a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""Module to parse ANSI escape sequences
-
-Maintainer: Jean-Paul Calderone
-"""
-
-import string
-
-# Twisted imports
-from twisted.python import log
-
-class ColorText:
- """
- Represents an element of text along with the texts colors and
- additional attributes.
- """
-
- # The colors to use
- COLORS = ('b', 'r', 'g', 'y', 'l', 'm', 'c', 'w')
- BOLD_COLORS = tuple([x.upper() for x in COLORS])
- BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(len(COLORS))
-
- # Color names
- COLOR_NAMES = (
- 'Black', 'Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan', 'White'
- )
-
- def __init__(self, text, fg, bg, display, bold, underline, flash, reverse):
- self.text, self.fg, self.bg = text, fg, bg
- self.display = display
- self.bold = bold
- self.underline = underline
- self.flash = flash
- self.reverse = reverse
- if self.reverse:
- self.fg, self.bg = self.bg, self.fg
-
-
-class AnsiParser:
- """
- Parser class for ANSI codes.
- """
-
- # Terminators for cursor movement ansi controls - unsupported
- CURSOR_SET = ('H', 'f', 'A', 'B', 'C', 'D', 'R', 's', 'u', 'd','G')
-
- # Terminators for erasure ansi controls - unsupported
- ERASE_SET = ('J', 'K', 'P')
-
- # Terminators for mode change ansi controls - unsupported
- MODE_SET = ('h', 'l')
-
- # Terminators for keyboard assignment ansi controls - unsupported
- ASSIGN_SET = ('p',)
-
- # Terminators for color change ansi controls - supported
- COLOR_SET = ('m',)
-
- SETS = (CURSOR_SET, ERASE_SET, MODE_SET, ASSIGN_SET, COLOR_SET)
-
- def __init__(self, defaultFG, defaultBG):
- self.defaultFG, self.defaultBG = defaultFG, defaultBG
- self.currentFG, self.currentBG = self.defaultFG, self.defaultBG
- self.bold, self.flash, self.underline, self.reverse = 0, 0, 0, 0
- self.display = 1
- self.prepend = ''
-
-
- def stripEscapes(self, string):
- """
- Remove all ANSI color escapes from the given string.
- """
- result = ''
- show = 1
- i = 0
- L = len(string)
- while i < L:
- if show == 0 and string[i] in _sets:
- show = 1
- elif show:
- n = string.find('\x1B', i)
- if n == -1:
- return result + string[i:]
- else:
- result = result + string[i:n]
- i = n
- show = 0
- i = i + 1
- return result
-
- def writeString(self, colorstr):
- pass
-
- def parseString(self, str):
- """
- Turn a string input into a list of L{ColorText} elements.
- """
-
- if self.prepend:
- str = self.prepend + str
- self.prepend = ''
- parts = str.split('\x1B')
-
- if len(parts) == 1:
- self.writeString(self.formatText(parts[0]))
- else:
- self.writeString(self.formatText(parts[0]))
- for s in parts[1:]:
- L = len(s)
- i = 0
- type = None
- while i < L:
- if s[i] not in string.digits+'[;?':
- break
- i+=1
- if not s:
- self.prepend = '\x1b'
- return
- if s[0]!='[':
- self.writeString(self.formatText(s[i+1:]))
- continue
- else:
- s=s[1:]
- i-=1
- if i==L-1:
- self.prepend = '\x1b['
- return
- type = _setmap.get(s[i], None)
- if type is None:
- continue
-
- if type == AnsiParser.COLOR_SET:
- self.parseColor(s[:i + 1])
- s = s[i + 1:]
- self.writeString(self.formatText(s))
- elif type == AnsiParser.CURSOR_SET:
- cursor, s = s[:i+1], s[i+1:]
- self.parseCursor(cursor)
- self.writeString(self.formatText(s))
- elif type == AnsiParser.ERASE_SET:
- erase, s = s[:i+1], s[i+1:]
- self.parseErase(erase)
- self.writeString(self.formatText(s))
- elif type == AnsiParser.MODE_SET:
- mode, s = s[:i+1], s[i+1:]
- #self.parseErase('2J')
- self.writeString(self.formatText(s))
- elif i == L:
- self.prepend = '\x1B[' + s
- else:
- log.msg('Unhandled ANSI control type: %c' % (s[i],))
- s = s[i + 1:]
- self.writeString(self.formatText(s))
-
- def parseColor(self, str):
- """
- Handle a single ANSI color sequence
- """
- # Drop the trailing 'm'
- str = str[:-1]
-
- if not str:
- str = '0'
-
- try:
- parts = map(int, str.split(';'))
- except ValueError:
- log.msg('Invalid ANSI color sequence (%d): %s' % (len(str), str))
- self.currentFG, self.currentBG = self.defaultFG, self.defaultBG
- return
-
- for x in parts:
- if x == 0:
- self.currentFG, self.currentBG = self.defaultFG, self.defaultBG
- self.bold, self.flash, self.underline, self.reverse = 0, 0, 0, 0
- self.display = 1
- elif x == 1:
- self.bold = 1
- elif 30 <= x <= 37:
- self.currentFG = x - 30
- elif 40 <= x <= 47:
- self.currentBG = x - 40
- elif x == 39:
- self.currentFG = self.defaultFG
- elif x == 49:
- self.currentBG = self.defaultBG
- elif x == 4:
- self.underline = 1
- elif x == 5:
- self.flash = 1
- elif x == 7:
- self.reverse = 1
- elif x == 8:
- self.display = 0
- elif x == 22:
- self.bold = 0
- elif x == 24:
- self.underline = 0
- elif x == 25:
- self.blink = 0
- elif x == 27:
- self.reverse = 0
- elif x == 28:
- self.display = 1
- else:
- log.msg('Unrecognised ANSI color command: %d' % (x,))
-
- def parseCursor(self, cursor):
- pass
-
- def parseErase(self, erase):
- pass
-
-
- def pickColor(self, value, mode, BOLD = ColorText.BOLD_COLORS):
- if mode:
- return ColorText.COLORS[value]
- else:
- return self.bold and BOLD[value] or ColorText.COLORS[value]
-
-
- def formatText(self, text):
- return ColorText(
- text,
- self.pickColor(self.currentFG, 0),
- self.pickColor(self.currentBG, 1),
- self.display, self.bold, self.underline, self.flash, self.reverse
- )
-
-
-_sets = ''.join(map(''.join, AnsiParser.SETS))
-
-_setmap = {}
-for s in AnsiParser.SETS:
- for r in s:
- _setmap[r] = s
-del s
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py
deleted file mode 100755
index cd7581da..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""Module to emulate a VT100 terminal in Tkinter.
-
-Maintainer: Paul Swartz
-"""
-
-import Tkinter, tkFont
-import ansi
-import string
-
-ttyFont = None#tkFont.Font(family = 'Courier', size = 10)
-fontWidth, fontHeight = None,None#max(map(ttyFont.measure, string.letters+string.digits)), int(ttyFont.metrics()['linespace'])
-
-colorKeys = (
- 'b', 'r', 'g', 'y', 'l', 'm', 'c', 'w',
- 'B', 'R', 'G', 'Y', 'L', 'M', 'C', 'W'
-)
-
-colorMap = {
- 'b': '#000000', 'r': '#c40000', 'g': '#00c400', 'y': '#c4c400',
- 'l': '#000080', 'm': '#c400c4', 'c': '#00c4c4', 'w': '#c4c4c4',
- 'B': '#626262', 'R': '#ff0000', 'G': '#00ff00', 'Y': '#ffff00',
- 'L': '#0000ff', 'M': '#ff00ff', 'C': '#00ffff', 'W': '#ffffff',
-}
-
-class VT100Frame(Tkinter.Frame):
- def __init__(self, *args, **kw):
- global ttyFont, fontHeight, fontWidth
- ttyFont = tkFont.Font(family = 'Courier', size = 10)
- fontWidth, fontHeight = max(map(ttyFont.measure, string.letters+string.digits)), int(ttyFont.metrics()['linespace'])
- self.width = kw.get('width', 80)
- self.height = kw.get('height', 25)
- self.callback = kw['callback']
- del kw['callback']
- kw['width'] = w = fontWidth * self.width
- kw['height'] = h = fontHeight * self.height
- Tkinter.Frame.__init__(self, *args, **kw)
- self.canvas = Tkinter.Canvas(bg='#000000', width=w, height=h)
- self.canvas.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
- self.canvas.bind('<Key>', self.keyPressed)
- self.canvas.bind('<1>', lambda x: 'break')
- self.canvas.bind('<Up>', self.upPressed)
- self.canvas.bind('<Down>', self.downPressed)
- self.canvas.bind('<Left>', self.leftPressed)
- self.canvas.bind('<Right>', self.rightPressed)
- self.canvas.focus()
-
- self.ansiParser = ansi.AnsiParser(ansi.ColorText.WHITE, ansi.ColorText.BLACK)
- self.ansiParser.writeString = self.writeString
- self.ansiParser.parseCursor = self.parseCursor
- self.ansiParser.parseErase = self.parseErase
- #for (a, b) in colorMap.items():
- # self.canvas.tag_config(a, foreground=b)
- # self.canvas.tag_config('b'+a, background=b)
- #self.canvas.tag_config('underline', underline=1)
-
- self.x = 0
- self.y = 0
- self.cursor = self.canvas.create_rectangle(0,0,fontWidth-1,fontHeight-1,fill='green',outline='green')
-
- def _delete(self, sx, sy, ex, ey):
- csx = sx*fontWidth + 1
- csy = sy*fontHeight + 1
- cex = ex*fontWidth + 3
- cey = ey*fontHeight + 3
- items = self.canvas.find_overlapping(csx,csy, cex,cey)
- for item in items:
- self.canvas.delete(item)
-
- def _write(self, ch, fg, bg):
- if self.x == self.width:
- self.x = 0
- self.y+=1
- if self.y == self.height:
- [self.canvas.move(x,0,-fontHeight) for x in self.canvas.find_all()]
- self.y-=1
- canvasX = self.x*fontWidth + 1
- canvasY = self.y*fontHeight + 1
- items = self.canvas.find_overlapping(canvasX, canvasY, canvasX+2, canvasY+2)
- if items:
- [self.canvas.delete(item) for item in items]
- if bg:
- self.canvas.create_rectangle(canvasX, canvasY, canvasX+fontWidth-1, canvasY+fontHeight-1, fill=bg, outline=bg)
- self.canvas.create_text(canvasX, canvasY, anchor=Tkinter.NW, font=ttyFont, text=ch, fill=fg)
- self.x+=1
-
- def write(self, data):
- #print self.x,self.y,repr(data)
- #if len(data)>5: raw_input()
- self.ansiParser.parseString(data)
- self.canvas.delete(self.cursor)
- canvasX = self.x*fontWidth + 1
- canvasY = self.y*fontHeight + 1
- self.cursor = self.canvas.create_rectangle(canvasX,canvasY,canvasX+fontWidth-1,canvasY+fontHeight-1, fill='green', outline='green')
- self.canvas.lower(self.cursor)
-
- def writeString(self, i):
- if not i.display:
- return
- fg = colorMap[i.fg]
- bg = i.bg != 'b' and colorMap[i.bg]
- for ch in i.text:
- b = ord(ch)
- if b == 7: # bell
- self.bell()
- elif b == 8: # BS
- if self.x:
- self.x-=1
- elif b == 9: # TAB
- [self._write(' ',fg,bg) for i in range(8)]
- elif b == 10:
- if self.y == self.height-1:
- self._delete(0,0,self.width,0)
- [self.canvas.move(x,0,-fontHeight) for x in self.canvas.find_all()]
- else:
- self.y+=1
- elif b == 13:
- self.x = 0
- elif 32 <= b < 127:
- self._write(ch, fg, bg)
-
- def parseErase(self, erase):
- if ';' in erase:
- end = erase[-1]
- parts = erase[:-1].split(';')
- [self.parseErase(x+end) for x in parts]
- return
- start = 0
- x,y = self.x, self.y
- if len(erase) > 1:
- start = int(erase[:-1])
- if erase[-1] == 'J':
- if start == 0:
- self._delete(x,y,self.width,self.height)
- else:
- self._delete(0,0,self.width,self.height)
- self.x = 0
- self.y = 0
- elif erase[-1] == 'K':
- if start == 0:
- self._delete(x,y,self.width,y)
- elif start == 1:
- self._delete(0,y,x,y)
- self.x = 0
- else:
- self._delete(0,y,self.width,y)
- self.x = 0
- elif erase[-1] == 'P':
- self._delete(x,y,x+start,y)
-
- def parseCursor(self, cursor):
- #if ';' in cursor and cursor[-1]!='H':
- # end = cursor[-1]
- # parts = cursor[:-1].split(';')
- # [self.parseCursor(x+end) for x in parts]
- # return
- start = 1
- if len(cursor) > 1 and cursor[-1]!='H':
- start = int(cursor[:-1])
- if cursor[-1] == 'C':
- self.x+=start
- elif cursor[-1] == 'D':
- self.x-=start
- elif cursor[-1]=='d':
- self.y=start-1
- elif cursor[-1]=='G':
- self.x=start-1
- elif cursor[-1]=='H':
- if len(cursor)>1:
- y,x = map(int, cursor[:-1].split(';'))
- y-=1
- x-=1
- else:
- x,y=0,0
- self.x = x
- self.y = y
-
- def keyPressed(self, event):
- if self.callback and event.char:
- self.callback(event.char)
- return 'break'
-
- def upPressed(self, event):
- self.callback('\x1bOA')
-
- def downPressed(self, event):
- self.callback('\x1bOB')
-
- def rightPressed(self, event):
- self.callback('\x1bOC')
-
- def leftPressed(self, event):
- self.callback('\x1bOD')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py
deleted file mode 100755
index 3a44be07..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py
+++ /dev/null
@@ -1,457 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.cred import portal
-from twisted.python import components, log
-from twisted.internet.error import ProcessExitedAlready
-from zope import interface
-from ssh import session, forwarding, filetransfer
-from ssh.filetransfer import FXF_READ, FXF_WRITE, FXF_APPEND, FXF_CREAT, FXF_TRUNC, FXF_EXCL
-from twisted.conch.ls import lsLine
-
-from avatar import ConchUser
-from error import ConchError
-from interfaces import ISession, ISFTPServer, ISFTPFile
-
-import struct, os, time, socket
-import fcntl, tty
-import pwd, grp
-import pty
-import ttymodes
-
-try:
- import utmp
-except ImportError:
- utmp = None
-
-class UnixSSHRealm:
- interface.implements(portal.IRealm)
-
- def requestAvatar(self, username, mind, *interfaces):
- user = UnixConchUser(username)
- return interfaces[0], user, user.logout
-
-
-class UnixConchUser(ConchUser):
-
- def __init__(self, username):
- ConchUser.__init__(self)
- self.username = username
- self.pwdData = pwd.getpwnam(self.username)
- l = [self.pwdData[3]]
- for groupname, password, gid, userlist in grp.getgrall():
- if username in userlist:
- l.append(gid)
- self.otherGroups = l
- self.listeners = {} # dict mapping (interface, port) -> listener
- self.channelLookup.update(
- {"session": session.SSHSession,
- "direct-tcpip": forwarding.openConnectForwardingClient})
-
- self.subsystemLookup.update(
- {"sftp": filetransfer.FileTransferServer})
-
- def getUserGroupId(self):
- return self.pwdData[2:4]
-
- def getOtherGroups(self):
- return self.otherGroups
-
- def getHomeDir(self):
- return self.pwdData[5]
-
- def getShell(self):
- return self.pwdData[6]
-
- def global_tcpip_forward(self, data):
- hostToBind, portToBind = forwarding.unpackGlobal_tcpip_forward(data)
- from twisted.internet import reactor
- try: listener = self._runAsUser(
- reactor.listenTCP, portToBind,
- forwarding.SSHListenForwardingFactory(self.conn,
- (hostToBind, portToBind),
- forwarding.SSHListenServerForwardingChannel),
- interface = hostToBind)
- except:
- return 0
- else:
- self.listeners[(hostToBind, portToBind)] = listener
- if portToBind == 0:
- portToBind = listener.getHost()[2] # the port
- return 1, struct.pack('>L', portToBind)
- else:
- return 1
-
- def global_cancel_tcpip_forward(self, data):
- hostToBind, portToBind = forwarding.unpackGlobal_tcpip_forward(data)
- listener = self.listeners.get((hostToBind, portToBind), None)
- if not listener:
- return 0
- del self.listeners[(hostToBind, portToBind)]
- self._runAsUser(listener.stopListening)
- return 1
-
- def logout(self):
- # remove all listeners
- for listener in self.listeners.itervalues():
- self._runAsUser(listener.stopListening)
- log.msg('avatar %s logging out (%i)' % (self.username, len(self.listeners)))
-
- def _runAsUser(self, f, *args, **kw):
- euid = os.geteuid()
- egid = os.getegid()
- groups = os.getgroups()
- uid, gid = self.getUserGroupId()
- os.setegid(0)
- os.seteuid(0)
- os.setgroups(self.getOtherGroups())
- os.setegid(gid)
- os.seteuid(uid)
- try:
- f = iter(f)
- except TypeError:
- f = [(f, args, kw)]
- try:
- for i in f:
- func = i[0]
- args = len(i)>1 and i[1] or ()
- kw = len(i)>2 and i[2] or {}
- r = func(*args, **kw)
- finally:
- os.setegid(0)
- os.seteuid(0)
- os.setgroups(groups)
- os.setegid(egid)
- os.seteuid(euid)
- return r
-
-class SSHSessionForUnixConchUser:
-
- interface.implements(ISession)
-
- def __init__(self, avatar):
- self.avatar = avatar
- self. environ = {'PATH':'/bin:/usr/bin:/usr/local/bin'}
- self.pty = None
- self.ptyTuple = 0
-
- def addUTMPEntry(self, loggedIn=1):
- if not utmp:
- return
- ipAddress = self.avatar.conn.transport.transport.getPeer().host
- packedIp ,= struct.unpack('L', socket.inet_aton(ipAddress))
- ttyName = self.ptyTuple[2][5:]
- t = time.time()
- t1 = int(t)
- t2 = int((t-t1) * 1e6)
- entry = utmp.UtmpEntry()
- entry.ut_type = loggedIn and utmp.USER_PROCESS or utmp.DEAD_PROCESS
- entry.ut_pid = self.pty.pid
- entry.ut_line = ttyName
- entry.ut_id = ttyName[-4:]
- entry.ut_tv = (t1,t2)
- if loggedIn:
- entry.ut_user = self.avatar.username
- entry.ut_host = socket.gethostbyaddr(ipAddress)[0]
- entry.ut_addr_v6 = (packedIp, 0, 0, 0)
- a = utmp.UtmpRecord(utmp.UTMP_FILE)
- a.pututline(entry)
- a.endutent()
- b = utmp.UtmpRecord(utmp.WTMP_FILE)
- b.pututline(entry)
- b.endutent()
-
-
- def getPty(self, term, windowSize, modes):
- self.environ['TERM'] = term
- self.winSize = windowSize
- self.modes = modes
- master, slave = pty.openpty()
- ttyname = os.ttyname(slave)
- self.environ['SSH_TTY'] = ttyname
- self.ptyTuple = (master, slave, ttyname)
-
- def openShell(self, proto):
- from twisted.internet import reactor
- if not self.ptyTuple: # we didn't get a pty-req
- log.msg('tried to get shell without pty, failing')
- raise ConchError("no pty")
- uid, gid = self.avatar.getUserGroupId()
- homeDir = self.avatar.getHomeDir()
- shell = self.avatar.getShell()
- self.environ['USER'] = self.avatar.username
- self.environ['HOME'] = homeDir
- self.environ['SHELL'] = shell
- shellExec = os.path.basename(shell)
- peer = self.avatar.conn.transport.transport.getPeer()
- host = self.avatar.conn.transport.transport.getHost()
- self.environ['SSH_CLIENT'] = '%s %s %s' % (peer.host, peer.port, host.port)
- self.getPtyOwnership()
- self.pty = reactor.spawnProcess(proto, \
- shell, ['-%s' % shellExec], self.environ, homeDir, uid, gid,
- usePTY = self.ptyTuple)
- self.addUTMPEntry()
- fcntl.ioctl(self.pty.fileno(), tty.TIOCSWINSZ,
- struct.pack('4H', *self.winSize))
- if self.modes:
- self.setModes()
- self.oldWrite = proto.transport.write
- proto.transport.write = self._writeHack
- self.avatar.conn.transport.transport.setTcpNoDelay(1)
-
- def execCommand(self, proto, cmd):
- from twisted.internet import reactor
- uid, gid = self.avatar.getUserGroupId()
- homeDir = self.avatar.getHomeDir()
- shell = self.avatar.getShell() or '/bin/sh'
- command = (shell, '-c', cmd)
- peer = self.avatar.conn.transport.transport.getPeer()
- host = self.avatar.conn.transport.transport.getHost()
- self.environ['SSH_CLIENT'] = '%s %s %s' % (peer.host, peer.port, host.port)
- if self.ptyTuple:
- self.getPtyOwnership()
- self.pty = reactor.spawnProcess(proto, \
- shell, command, self.environ, homeDir,
- uid, gid, usePTY = self.ptyTuple or 0)
- if self.ptyTuple:
- self.addUTMPEntry()
- if self.modes:
- self.setModes()
-# else:
-# tty.setraw(self.pty.pipes[0].fileno(), tty.TCSANOW)
- self.avatar.conn.transport.transport.setTcpNoDelay(1)
-
- def getPtyOwnership(self):
- ttyGid = os.stat(self.ptyTuple[2])[5]
- uid, gid = self.avatar.getUserGroupId()
- euid, egid = os.geteuid(), os.getegid()
- os.setegid(0)
- os.seteuid(0)
- try:
- os.chown(self.ptyTuple[2], uid, ttyGid)
- finally:
- os.setegid(egid)
- os.seteuid(euid)
-
- def setModes(self):
- pty = self.pty
- attr = tty.tcgetattr(pty.fileno())
- for mode, modeValue in self.modes:
- if not ttymodes.TTYMODES.has_key(mode): continue
- ttyMode = ttymodes.TTYMODES[mode]
- if len(ttyMode) == 2: # flag
- flag, ttyAttr = ttyMode
- if not hasattr(tty, ttyAttr): continue
- ttyval = getattr(tty, ttyAttr)
- if modeValue:
- attr[flag] = attr[flag]|ttyval
- else:
- attr[flag] = attr[flag]&~ttyval
- elif ttyMode == 'OSPEED':
- attr[tty.OSPEED] = getattr(tty, 'B%s'%modeValue)
- elif ttyMode == 'ISPEED':
- attr[tty.ISPEED] = getattr(tty, 'B%s'%modeValue)
- else:
- if not hasattr(tty, ttyMode): continue
- ttyval = getattr(tty, ttyMode)
- attr[tty.CC][ttyval] = chr(modeValue)
- tty.tcsetattr(pty.fileno(), tty.TCSANOW, attr)
-
- def eofReceived(self):
- if self.pty:
- self.pty.closeStdin()
-
- def closed(self):
- if self.ptyTuple and os.path.exists(self.ptyTuple[2]):
- ttyGID = os.stat(self.ptyTuple[2])[5]
- os.chown(self.ptyTuple[2], 0, ttyGID)
- if self.pty:
- try:
- self.pty.signalProcess('HUP')
- except (OSError,ProcessExitedAlready):
- pass
- self.pty.loseConnection()
- self.addUTMPEntry(0)
- log.msg('shell closed')
-
- def windowChanged(self, winSize):
- self.winSize = winSize
- fcntl.ioctl(self.pty.fileno(), tty.TIOCSWINSZ,
- struct.pack('4H', *self.winSize))
-
- def _writeHack(self, data):
- """
- Hack to send ignore messages when we aren't echoing.
- """
- if self.pty is not None:
- attr = tty.tcgetattr(self.pty.fileno())[3]
- if not attr & tty.ECHO and attr & tty.ICANON: # no echo
- self.avatar.conn.transport.sendIgnore('\x00'*(8+len(data)))
- self.oldWrite(data)
-
-
-class SFTPServerForUnixConchUser:
-
- interface.implements(ISFTPServer)
-
- def __init__(self, avatar):
- self.avatar = avatar
-
-
- def _setAttrs(self, path, attrs):
- """
- NOTE: this function assumes it runs as the logged-in user:
- i.e. under _runAsUser()
- """
- if "uid" in attrs and "gid" in attrs:
- os.chown(path, attrs["uid"], attrs["gid"])
- if "permissions" in attrs:
- os.chmod(path, attrs["permissions"])
- if "atime" in attrs and "mtime" in attrs:
- os.utime(path, (attrs["atime"], attrs["mtime"]))
-
- def _getAttrs(self, s):
- return {
- "size" : s.st_size,
- "uid" : s.st_uid,
- "gid" : s.st_gid,
- "permissions" : s.st_mode,
- "atime" : int(s.st_atime),
- "mtime" : int(s.st_mtime)
- }
-
- def _absPath(self, path):
- home = self.avatar.getHomeDir()
- return os.path.abspath(os.path.join(home, path))
-
- def gotVersion(self, otherVersion, extData):
- return {}
-
- def openFile(self, filename, flags, attrs):
- return UnixSFTPFile(self, self._absPath(filename), flags, attrs)
-
- def removeFile(self, filename):
- filename = self._absPath(filename)
- return self.avatar._runAsUser(os.remove, filename)
-
- def renameFile(self, oldpath, newpath):
- oldpath = self._absPath(oldpath)
- newpath = self._absPath(newpath)
- return self.avatar._runAsUser(os.rename, oldpath, newpath)
-
- def makeDirectory(self, path, attrs):
- path = self._absPath(path)
- return self.avatar._runAsUser([(os.mkdir, (path,)),
- (self._setAttrs, (path, attrs))])
-
- def removeDirectory(self, path):
- path = self._absPath(path)
- self.avatar._runAsUser(os.rmdir, path)
-
- def openDirectory(self, path):
- return UnixSFTPDirectory(self, self._absPath(path))
-
- def getAttrs(self, path, followLinks):
- path = self._absPath(path)
- if followLinks:
- s = self.avatar._runAsUser(os.stat, path)
- else:
- s = self.avatar._runAsUser(os.lstat, path)
- return self._getAttrs(s)
-
- def setAttrs(self, path, attrs):
- path = self._absPath(path)
- self.avatar._runAsUser(self._setAttrs, path, attrs)
-
- def readLink(self, path):
- path = self._absPath(path)
- return self.avatar._runAsUser(os.readlink, path)
-
- def makeLink(self, linkPath, targetPath):
- linkPath = self._absPath(linkPath)
- targetPath = self._absPath(targetPath)
- return self.avatar._runAsUser(os.symlink, targetPath, linkPath)
-
- def realPath(self, path):
- return os.path.realpath(self._absPath(path))
-
- def extendedRequest(self, extName, extData):
- raise NotImplementedError
-
-class UnixSFTPFile:
-
- interface.implements(ISFTPFile)
-
- def __init__(self, server, filename, flags, attrs):
- self.server = server
- openFlags = 0
- if flags & FXF_READ == FXF_READ and flags & FXF_WRITE == 0:
- openFlags = os.O_RDONLY
- if flags & FXF_WRITE == FXF_WRITE and flags & FXF_READ == 0:
- openFlags = os.O_WRONLY
- if flags & FXF_WRITE == FXF_WRITE and flags & FXF_READ == FXF_READ:
- openFlags = os.O_RDWR
- if flags & FXF_APPEND == FXF_APPEND:
- openFlags |= os.O_APPEND
- if flags & FXF_CREAT == FXF_CREAT:
- openFlags |= os.O_CREAT
- if flags & FXF_TRUNC == FXF_TRUNC:
- openFlags |= os.O_TRUNC
- if flags & FXF_EXCL == FXF_EXCL:
- openFlags |= os.O_EXCL
- if "permissions" in attrs:
- mode = attrs["permissions"]
- del attrs["permissions"]
- else:
- mode = 0777
- fd = server.avatar._runAsUser(os.open, filename, openFlags, mode)
- if attrs:
- server.avatar._runAsUser(server._setAttrs, filename, attrs)
- self.fd = fd
-
- def close(self):
- return self.server.avatar._runAsUser(os.close, self.fd)
-
- def readChunk(self, offset, length):
- return self.server.avatar._runAsUser([ (os.lseek, (self.fd, offset, 0)),
- (os.read, (self.fd, length)) ])
-
- def writeChunk(self, offset, data):
- return self.server.avatar._runAsUser([(os.lseek, (self.fd, offset, 0)),
- (os.write, (self.fd, data))])
-
- def getAttrs(self):
- s = self.server.avatar._runAsUser(os.fstat, self.fd)
- return self.server._getAttrs(s)
-
- def setAttrs(self, attrs):
- raise NotImplementedError
-
-
-class UnixSFTPDirectory:
-
- def __init__(self, server, directory):
- self.server = server
- self.files = server.avatar._runAsUser(os.listdir, directory)
- self.dir = directory
-
- def __iter__(self):
- return self
-
- def next(self):
- try:
- f = self.files.pop(0)
- except IndexError:
- raise StopIteration
- else:
- s = self.server.avatar._runAsUser(os.lstat, os.path.join(self.dir, f))
- longname = lsLine(f, s)
- attrs = self.server._getAttrs(s)
- return (f, longname, attrs)
-
- def close(self):
- self.files = []
-
-
-components.registerAdapter(SFTPServerForUnixConchUser, UnixConchUser, filetransfer.ISFTPServer)
-components.registerAdapter(SSHSessionForUnixConchUser, UnixConchUser, session.ISession)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/copyright.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/copyright.py
deleted file mode 100755
index 01165e0d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/copyright.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Copyright information for Twisted.
-"""
-
-from twisted import __version__ as version, version as longversion
-
-longversion = str(longversion)
-
-copyright="""\
-Copyright (c) 2001-2012 Twisted Matrix Laboratories.
-See LICENSE for details."""
-
-disclaimer='''
-Twisted, the Framework of Your Internet
-%s
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-''' % copyright
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/__init__.py
deleted file mode 100755
index 06e287f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Cred
-
-Support for verifying credentials, and providing services to users based on
-those credentials.
-
-(This package was previously known as the module twisted.internet.passport.)
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/_digest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/_digest.py
deleted file mode 100755
index 4640a1d1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/_digest.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# -*- test-case-name: twisted.test.test_digestauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Calculations for HTTP Digest authentication.
-
-@see: U{http://www.faqs.org/rfcs/rfc2617.html}
-"""
-
-from twisted.python.hashlib import md5, sha1
-
-
-
-# The digest math
-
-algorithms = {
- 'md5': md5,
-
- # md5-sess is more complicated than just another algorithm. It requires
- # H(A1) state to be remembered from the first WWW-Authenticate challenge
- # issued and re-used to process any Authorization header in response to
- # that WWW-Authenticate challenge. It is *not* correct to simply
- # recalculate H(A1) each time an Authorization header is received. Read
- # RFC 2617, section 3.2.2.2 and do not try to make DigestCredentialFactory
- # support this unless you completely understand it. -exarkun
- 'md5-sess': md5,
-
- 'sha': sha1,
-}
-
-# DigestCalcHA1
-def calcHA1(pszAlg, pszUserName, pszRealm, pszPassword, pszNonce, pszCNonce,
- preHA1=None):
- """
- Compute H(A1) from RFC 2617.
-
- @param pszAlg: The name of the algorithm to use to calculate the digest.
- Currently supported are md5, md5-sess, and sha.
- @param pszUserName: The username
- @param pszRealm: The realm
- @param pszPassword: The password
- @param pszNonce: The nonce
- @param pszCNonce: The cnonce
-
- @param preHA1: If available this is a str containing a previously
- calculated H(A1) as a hex string. If this is given then the values for
- pszUserName, pszRealm, and pszPassword must be C{None} and are ignored.
- """
-
- if (preHA1 and (pszUserName or pszRealm or pszPassword)):
- raise TypeError(("preHA1 is incompatible with the pszUserName, "
- "pszRealm, and pszPassword arguments"))
-
- if preHA1 is None:
- # We need to calculate the HA1 from the username:realm:password
- m = algorithms[pszAlg]()
- m.update(pszUserName)
- m.update(":")
- m.update(pszRealm)
- m.update(":")
- m.update(pszPassword)
- HA1 = m.digest()
- else:
- # We were given a username:realm:password
- HA1 = preHA1.decode('hex')
-
- if pszAlg == "md5-sess":
- m = algorithms[pszAlg]()
- m.update(HA1)
- m.update(":")
- m.update(pszNonce)
- m.update(":")
- m.update(pszCNonce)
- HA1 = m.digest()
-
- return HA1.encode('hex')
-
-
-def calcHA2(algo, pszMethod, pszDigestUri, pszQop, pszHEntity):
- """
- Compute H(A2) from RFC 2617.
-
- @param pszAlg: The name of the algorithm to use to calculate the digest.
- Currently supported are md5, md5-sess, and sha.
- @param pszMethod: The request method.
- @param pszDigestUri: The request URI.
- @param pszQop: The Quality-of-Protection value.
- @param pszHEntity: The hash of the entity body or C{None} if C{pszQop} is
- not C{'auth-int'}.
- @return: The hash of the A2 value for the calculation of the response
- digest.
- """
- m = algorithms[algo]()
- m.update(pszMethod)
- m.update(":")
- m.update(pszDigestUri)
- if pszQop == "auth-int":
- m.update(":")
- m.update(pszHEntity)
- return m.digest().encode('hex')
-
-
-def calcResponse(HA1, HA2, algo, pszNonce, pszNonceCount, pszCNonce, pszQop):
- """
- Compute the digest for the given parameters.
-
- @param HA1: The H(A1) value, as computed by L{calcHA1}.
- @param HA2: The H(A2) value, as computed by L{calcHA2}.
- @param pszNonce: The challenge nonce.
- @param pszNonceCount: The (client) nonce count value for this response.
- @param pszCNonce: The client nonce.
- @param pszQop: The Quality-of-Protection value.
- """
- m = algorithms[algo]()
- m.update(HA1)
- m.update(":")
- m.update(pszNonce)
- m.update(":")
- if pszNonceCount and pszCNonce:
- m.update(pszNonceCount)
- m.update(":")
- m.update(pszCNonce)
- m.update(":")
- m.update(pszQop)
- m.update(":")
- m.update(HA2)
- respHash = m.digest().encode('hex')
- return respHash
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/checkers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/checkers.py
deleted file mode 100755
index 523a94da..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/checkers.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# -*- test-case-name: twisted.test.test_newcred -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import os
-
-from zope.interface import implements, Interface, Attribute
-
-from twisted.internet import defer
-from twisted.python import failure, log
-from twisted.cred import error, credentials
-
-
-
-class ICredentialsChecker(Interface):
- """
- An object that can check sub-interfaces of ICredentials.
- """
-
- credentialInterfaces = Attribute(
- 'A list of sub-interfaces of ICredentials which specifies which I may check.')
-
-
- def requestAvatarId(credentials):
- """
- @param credentials: something which implements one of the interfaces in
- self.credentialInterfaces.
-
- @return: a Deferred which will fire a string which identifies an
- avatar, an empty tuple to specify an authenticated anonymous user
- (provided as checkers.ANONYMOUS) or fire a Failure(UnauthorizedLogin).
- Alternatively, return the result itself.
-
- @see: L{twisted.cred.credentials}
- """
-
-
-
-# A note on anonymity - We do not want None as the value for anonymous
-# because it is too easy to accidentally return it. We do not want the
-# empty string, because it is too easy to mistype a password file. For
-# example, an .htpasswd file may contain the lines: ['hello:asdf',
-# 'world:asdf', 'goodbye', ':world']. This misconfiguration will have an
-# ill effect in any case, but accidentally granting anonymous access is a
-# worse failure mode than simply granting access to an untypeable
-# username. We do not want an instance of 'object', because that would
-# create potential problems with persistence.
-
-ANONYMOUS = ()
-
-
-class AllowAnonymousAccess:
- implements(ICredentialsChecker)
- credentialInterfaces = credentials.IAnonymous,
-
- def requestAvatarId(self, credentials):
- return defer.succeed(ANONYMOUS)
-
-
-class InMemoryUsernamePasswordDatabaseDontUse:
- """
- An extremely simple credentials checker.
-
- This is only of use in one-off test programs or examples which don't
- want to focus too much on how credentials are verified.
-
- You really don't want to use this for anything else. It is, at best, a
- toy. If you need a simple credentials checker for a real application,
- see L{FilePasswordDB}.
- """
-
- implements(ICredentialsChecker)
-
- credentialInterfaces = (credentials.IUsernamePassword,
- credentials.IUsernameHashedPassword)
-
- def __init__(self, **users):
- self.users = users
-
- def addUser(self, username, password):
- self.users[username] = password
-
- def _cbPasswordMatch(self, matched, username):
- if matched:
- return username
- else:
- return failure.Failure(error.UnauthorizedLogin())
-
- def requestAvatarId(self, credentials):
- if credentials.username in self.users:
- return defer.maybeDeferred(
- credentials.checkPassword,
- self.users[credentials.username]).addCallback(
- self._cbPasswordMatch, str(credentials.username))
- else:
- return defer.fail(error.UnauthorizedLogin())
-
-
-class FilePasswordDB:
- """A file-based, text-based username/password database.
-
- Records in the datafile for this class are delimited by a particular
- string. The username appears in a fixed field of the columns delimited
- by this string, as does the password. Both fields are specifiable. If
- the passwords are not stored plaintext, a hash function must be supplied
- to convert plaintext passwords to the form stored on disk and this
- CredentialsChecker will only be able to check IUsernamePassword
- credentials. If the passwords are stored plaintext,
- IUsernameHashedPassword credentials will be checkable as well.
- """
-
- implements(ICredentialsChecker)
-
- cache = False
- _credCache = None
- _cacheTimestamp = 0
-
- def __init__(self, filename, delim=':', usernameField=0, passwordField=1,
- caseSensitive=True, hash=None, cache=False):
- """
- @type filename: C{str}
- @param filename: The name of the file from which to read username and
- password information.
-
- @type delim: C{str}
- @param delim: The field delimiter used in the file.
-
- @type usernameField: C{int}
- @param usernameField: The index of the username after splitting a
- line on the delimiter.
-
- @type passwordField: C{int}
- @param passwordField: The index of the password after splitting a
- line on the delimiter.
-
- @type caseSensitive: C{bool}
- @param caseSensitive: If true, consider the case of the username when
- performing a lookup. Ignore it otherwise.
-
- @type hash: Three-argument callable or C{None}
- @param hash: A function used to transform the plaintext password
- received over the network to a format suitable for comparison
- against the version stored on disk. The arguments to the callable
- are the username, the network-supplied password, and the in-file
- version of the password. If the return value compares equal to the
- version stored on disk, the credentials are accepted.
-
- @type cache: C{bool}
- @param cache: If true, maintain an in-memory cache of the
- contents of the password file. On lookups, the mtime of the
- file will be checked, and the file will only be re-parsed if
- the mtime is newer than when the cache was generated.
- """
- self.filename = filename
- self.delim = delim
- self.ufield = usernameField
- self.pfield = passwordField
- self.caseSensitive = caseSensitive
- self.hash = hash
- self.cache = cache
-
- if self.hash is None:
- # The passwords are stored plaintext. We can support both
- # plaintext and hashed passwords received over the network.
- self.credentialInterfaces = (
- credentials.IUsernamePassword,
- credentials.IUsernameHashedPassword
- )
- else:
- # The passwords are hashed on disk. We can support only
- # plaintext passwords received over the network.
- self.credentialInterfaces = (
- credentials.IUsernamePassword,
- )
-
-
- def __getstate__(self):
- d = dict(vars(self))
- for k in '_credCache', '_cacheTimestamp':
- try:
- del d[k]
- except KeyError:
- pass
- return d
-
-
- def _cbPasswordMatch(self, matched, username):
- if matched:
- return username
- else:
- return failure.Failure(error.UnauthorizedLogin())
-
-
- def _loadCredentials(self):
- try:
- f = file(self.filename)
- except:
- log.err()
- raise error.UnauthorizedLogin()
- else:
- for line in f:
- line = line.rstrip()
- parts = line.split(self.delim)
-
- if self.ufield >= len(parts) or self.pfield >= len(parts):
- continue
- if self.caseSensitive:
- yield parts[self.ufield], parts[self.pfield]
- else:
- yield parts[self.ufield].lower(), parts[self.pfield]
-
-
- def getUser(self, username):
- if not self.caseSensitive:
- username = username.lower()
-
- if self.cache:
- if self._credCache is None or os.path.getmtime(self.filename) > self._cacheTimestamp:
- self._cacheTimestamp = os.path.getmtime(self.filename)
- self._credCache = dict(self._loadCredentials())
- return username, self._credCache[username]
- else:
- for u, p in self._loadCredentials():
- if u == username:
- return u, p
- raise KeyError(username)
-
-
- def requestAvatarId(self, c):
- try:
- u, p = self.getUser(c.username)
- except KeyError:
- return defer.fail(error.UnauthorizedLogin())
- else:
- up = credentials.IUsernamePassword(c, None)
- if self.hash:
- if up is not None:
- h = self.hash(up.username, up.password, p)
- if h == p:
- return defer.succeed(u)
- return defer.fail(error.UnauthorizedLogin())
- else:
- return defer.maybeDeferred(c.checkPassword, p
- ).addCallback(self._cbPasswordMatch, u)
-
-
-
-class PluggableAuthenticationModulesChecker:
- implements(ICredentialsChecker)
- credentialInterfaces = credentials.IPluggableAuthenticationModules,
- service = 'Twisted'
-
- def requestAvatarId(self, credentials):
- try:
- from twisted.cred import pamauth
- except ImportError: # PyPAM is missing
- return defer.fail(error.UnauthorizedLogin())
- else:
- d = pamauth.pamAuthenticate(self.service, credentials.username,
- credentials.pamConversion)
- d.addCallback(lambda x: credentials.username)
- return d
-
-
-
-# For backwards compatibility
-# Allow access as the old name.
-OnDiskUsernamePasswordDatabase = FilePasswordDB
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/credentials.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/credentials.py
deleted file mode 100755
index 63fb44ea..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/credentials.py
+++ /dev/null
@@ -1,483 +0,0 @@
-# -*- test-case-name: twisted.test.test_newcred-*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from zope.interface import implements, Interface
-
-import hmac, time, random
-from twisted.python.hashlib import md5
-from twisted.python.randbytes import secureRandom
-from twisted.cred._digest import calcResponse, calcHA1, calcHA2
-from twisted.cred import error
-
-class ICredentials(Interface):
- """
- I check credentials.
-
- Implementors _must_ specify which sub-interfaces of ICredentials
- to which it conforms, using zope.interface.implements().
- """
-
-
-
-class IUsernameDigestHash(ICredentials):
- """
- This credential is used when a CredentialChecker has access to the hash
- of the username:realm:password as in an Apache .htdigest file.
- """
- def checkHash(digestHash):
- """
- @param digestHash: The hashed username:realm:password to check against.
-
- @return: C{True} if the credentials represented by this object match
- the given hash, C{False} if they do not, or a L{Deferred} which
- will be called back with one of these values.
- """
-
-
-
-class IUsernameHashedPassword(ICredentials):
- """
- I encapsulate a username and a hashed password.
-
- This credential is used when a hashed password is received from the
- party requesting authentication. CredentialCheckers which check this
- kind of credential must store the passwords in plaintext (or as
- password-equivalent hashes) form so that they can be hashed in a manner
- appropriate for the particular credentials class.
-
- @type username: C{str}
- @ivar username: The username associated with these credentials.
- """
-
- def checkPassword(password):
- """
- Validate these credentials against the correct password.
-
- @type password: C{str}
- @param password: The correct, plaintext password against which to
- check.
-
- @rtype: C{bool} or L{Deferred}
- @return: C{True} if the credentials represented by this object match the
- given password, C{False} if they do not, or a L{Deferred} which will
- be called back with one of these values.
- """
-
-
-
-class IUsernamePassword(ICredentials):
- """
- I encapsulate a username and a plaintext password.
-
- This encapsulates the case where the password received over the network
- has been hashed with the identity function (That is, not at all). The
- CredentialsChecker may store the password in whatever format it desires,
- it need only transform the stored password in a similar way before
- performing the comparison.
-
- @type username: C{str}
- @ivar username: The username associated with these credentials.
-
- @type password: C{str}
- @ivar password: The password associated with these credentials.
- """
-
- def checkPassword(password):
- """
- Validate these credentials against the correct password.
-
- @type password: C{str}
- @param password: The correct, plaintext password against which to
- check.
-
- @rtype: C{bool} or L{Deferred}
- @return: C{True} if the credentials represented by this object match the
- given password, C{False} if they do not, or a L{Deferred} which will
- be called back with one of these values.
- """
-
-
-
-class IAnonymous(ICredentials):
- """
- I am an explicitly anonymous request for access.
- """
-
-
-
-class DigestedCredentials(object):
- """
- Yet Another Simple HTTP Digest authentication scheme.
- """
- implements(IUsernameHashedPassword, IUsernameDigestHash)
-
- def __init__(self, username, method, realm, fields):
- self.username = username
- self.method = method
- self.realm = realm
- self.fields = fields
-
-
- def checkPassword(self, password):
- """
- Verify that the credentials represented by this object agree with the
- given plaintext C{password} by hashing C{password} in the same way the
- response hash represented by this object was generated and comparing
- the results.
- """
- response = self.fields.get('response')
- uri = self.fields.get('uri')
- nonce = self.fields.get('nonce')
- cnonce = self.fields.get('cnonce')
- nc = self.fields.get('nc')
- algo = self.fields.get('algorithm', 'md5').lower()
- qop = self.fields.get('qop', 'auth')
-
- expected = calcResponse(
- calcHA1(algo, self.username, self.realm, password, nonce, cnonce),
- calcHA2(algo, self.method, uri, qop, None),
- algo, nonce, nc, cnonce, qop)
-
- return expected == response
-
-
- def checkHash(self, digestHash):
- """
- Verify that the credentials represented by this object agree with the
- credentials represented by the I{H(A1)} given in C{digestHash}.
-
- @param digestHash: A precomputed H(A1) value based on the username,
- realm, and password associate with this credentials object.
- """
- response = self.fields.get('response')
- uri = self.fields.get('uri')
- nonce = self.fields.get('nonce')
- cnonce = self.fields.get('cnonce')
- nc = self.fields.get('nc')
- algo = self.fields.get('algorithm', 'md5').lower()
- qop = self.fields.get('qop', 'auth')
-
- expected = calcResponse(
- calcHA1(algo, None, None, None, nonce, cnonce, preHA1=digestHash),
- calcHA2(algo, self.method, uri, qop, None),
- algo, nonce, nc, cnonce, qop)
-
- return expected == response
-
-
-
-class DigestCredentialFactory(object):
- """
- Support for RFC2617 HTTP Digest Authentication
-
- @cvar CHALLENGE_LIFETIME_SECS: The number of seconds for which an
- opaque should be valid.
-
- @type privateKey: C{str}
- @ivar privateKey: A random string used for generating the secure opaque.
-
- @type algorithm: C{str}
- @param algorithm: Case insensitive string specifying the hash algorithm to
- use. Must be either C{'md5'} or C{'sha'}. C{'md5-sess'} is B{not}
- supported.
-
- @type authenticationRealm: C{str}
- @param authenticationRealm: case sensitive string that specifies the realm
- portion of the challenge
- """
-
- CHALLENGE_LIFETIME_SECS = 15 * 60 # 15 minutes
-
- scheme = "digest"
-
- def __init__(self, algorithm, authenticationRealm):
- self.algorithm = algorithm
- self.authenticationRealm = authenticationRealm
- self.privateKey = secureRandom(12)
-
-
- def getChallenge(self, address):
- """
- Generate the challenge for use in the WWW-Authenticate header.
-
- @param address: The client address to which this challenge is being
- sent.
-
- @return: The C{dict} that can be used to generate a WWW-Authenticate
- header.
- """
- c = self._generateNonce()
- o = self._generateOpaque(c, address)
-
- return {'nonce': c,
- 'opaque': o,
- 'qop': 'auth',
- 'algorithm': self.algorithm,
- 'realm': self.authenticationRealm}
-
-
- def _generateNonce(self):
- """
- Create a random value suitable for use as the nonce parameter of a
- WWW-Authenticate challenge.
-
- @rtype: C{str}
- """
- return secureRandom(12).encode('hex')
-
-
- def _getTime(self):
- """
- Parameterize the time based seed used in C{_generateOpaque}
- so we can deterministically unittest it's behavior.
- """
- return time.time()
-
-
- def _generateOpaque(self, nonce, clientip):
- """
- Generate an opaque to be returned to the client. This is a unique
- string that can be returned to us and verified.
- """
- # Now, what we do is encode the nonce, client ip and a timestamp in the
- # opaque value with a suitable digest.
- now = str(int(self._getTime()))
- if clientip is None:
- clientip = ''
- key = "%s,%s,%s" % (nonce, clientip, now)
- digest = md5(key + self.privateKey).hexdigest()
- ekey = key.encode('base64')
- return "%s-%s" % (digest, ekey.replace('\n', ''))
-
-
- def _verifyOpaque(self, opaque, nonce, clientip):
- """
- Given the opaque and nonce from the request, as well as the client IP
- that made the request, verify that the opaque was generated by us.
- And that it's not too old.
-
- @param opaque: The opaque value from the Digest response
- @param nonce: The nonce value from the Digest response
- @param clientip: The remote IP address of the client making the request
- or C{None} if the request was submitted over a channel where this
- does not make sense.
-
- @return: C{True} if the opaque was successfully verified.
-
- @raise error.LoginFailed: if C{opaque} could not be parsed or
- contained the wrong values.
- """
- # First split the digest from the key
- opaqueParts = opaque.split('-')
- if len(opaqueParts) != 2:
- raise error.LoginFailed('Invalid response, invalid opaque value')
-
- if clientip is None:
- clientip = ''
-
- # Verify the key
- key = opaqueParts[1].decode('base64')
- keyParts = key.split(',')
-
- if len(keyParts) != 3:
- raise error.LoginFailed('Invalid response, invalid opaque value')
-
- if keyParts[0] != nonce:
- raise error.LoginFailed(
- 'Invalid response, incompatible opaque/nonce values')
-
- if keyParts[1] != clientip:
- raise error.LoginFailed(
- 'Invalid response, incompatible opaque/client values')
-
- try:
- when = int(keyParts[2])
- except ValueError:
- raise error.LoginFailed(
- 'Invalid response, invalid opaque/time values')
-
- if (int(self._getTime()) - when >
- DigestCredentialFactory.CHALLENGE_LIFETIME_SECS):
-
- raise error.LoginFailed(
- 'Invalid response, incompatible opaque/nonce too old')
-
- # Verify the digest
- digest = md5(key + self.privateKey).hexdigest()
- if digest != opaqueParts[0]:
- raise error.LoginFailed('Invalid response, invalid opaque value')
-
- return True
-
-
- def decode(self, response, method, host):
- """
- Decode the given response and attempt to generate a
- L{DigestedCredentials} from it.
-
- @type response: C{str}
- @param response: A string of comma seperated key=value pairs
-
- @type method: C{str}
- @param method: The action requested to which this response is addressed
- (GET, POST, INVITE, OPTIONS, etc).
-
- @type host: C{str}
- @param host: The address the request was sent from.
-
- @raise error.LoginFailed: If the response does not contain a username,
- a nonce, an opaque, or if the opaque is invalid.
-
- @return: L{DigestedCredentials}
- """
- def unq(s):
- if s[0] == s[-1] == '"':
- return s[1:-1]
- return s
- response = ' '.join(response.splitlines())
- parts = response.split(',')
-
- auth = {}
-
- for (k, v) in [p.split('=', 1) for p in parts]:
- auth[k.strip()] = unq(v.strip())
-
- username = auth.get('username')
- if not username:
- raise error.LoginFailed('Invalid response, no username given.')
-
- if 'opaque' not in auth:
- raise error.LoginFailed('Invalid response, no opaque given.')
-
- if 'nonce' not in auth:
- raise error.LoginFailed('Invalid response, no nonce given.')
-
- # Now verify the nonce/opaque values for this client
- if self._verifyOpaque(auth.get('opaque'), auth.get('nonce'), host):
- return DigestedCredentials(username,
- method,
- self.authenticationRealm,
- auth)
-
-
-
-class CramMD5Credentials:
- implements(IUsernameHashedPassword)
-
- challenge = ''
- response = ''
-
- def __init__(self, host=None):
- self.host = host
-
- def getChallenge(self):
- if self.challenge:
- return self.challenge
- # The data encoded in the first ready response contains an
- # presumptively arbitrary string of random digits, a timestamp, and
- # the fully-qualified primary host name of the server. The syntax of
- # the unencoded form must correspond to that of an RFC 822 'msg-id'
- # [RFC822] as described in [POP3].
- # -- RFC 2195
- r = random.randrange(0x7fffffff)
- t = time.time()
- self.challenge = '<%d.%d@%s>' % (r, t, self.host)
- return self.challenge
-
- def setResponse(self, response):
- self.username, self.response = response.split(None, 1)
-
- def moreChallenges(self):
- return False
-
- def checkPassword(self, password):
- verify = hmac.HMAC(password, self.challenge).hexdigest()
- return verify == self.response
-
-
-class UsernameHashedPassword:
- implements(IUsernameHashedPassword)
-
- def __init__(self, username, hashed):
- self.username = username
- self.hashed = hashed
-
- def checkPassword(self, password):
- return self.hashed == password
-
-
-class UsernamePassword:
- implements(IUsernamePassword)
-
- def __init__(self, username, password):
- self.username = username
- self.password = password
-
- def checkPassword(self, password):
- return self.password == password
-
-
-class Anonymous:
- implements(IAnonymous)
-
-
-
-class ISSHPrivateKey(ICredentials):
- """
- L{ISSHPrivateKey} credentials encapsulate an SSH public key to be checked
- against a user's private key.
-
- @ivar username: The username associated with these credentials.
- @type username: C{str}
-
- @ivar algName: The algorithm name for the blob.
- @type algName: C{str}
-
- @ivar blob: The public key blob as sent by the client.
- @type blob: C{str}
-
- @ivar sigData: The data the signature was made from.
- @type sigData: C{str}
-
- @ivar signature: The signed data. This is checked to verify that the user
- owns the private key.
- @type signature: C{str} or C{NoneType}
- """
-
-
-
-class SSHPrivateKey:
- implements(ISSHPrivateKey)
- def __init__(self, username, algName, blob, sigData, signature):
- self.username = username
- self.algName = algName
- self.blob = blob
- self.sigData = sigData
- self.signature = signature
-
-
-class IPluggableAuthenticationModules(ICredentials):
- """I encapsulate the authentication of a user via PAM (Pluggable
- Authentication Modules. I use PyPAM (available from
- http://www.tummy.com/Software/PyPam/index.html).
-
- @ivar username: The username for the user being logged in.
-
- @ivar pamConversion: A function that is called with a list of tuples
- (message, messageType). See the PAM documentation
- for the meaning of messageType. The function
- returns a Deferred which will fire with a list
- of (response, 0), one for each message. The 0 is
- currently unused, but is required by the PAM library.
- """
-
-class PluggableAuthenticationModules:
- implements(IPluggableAuthenticationModules)
-
- def __init__(self, username, pamConversion):
- self.username = username
- self.pamConversion = pamConversion
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/error.py
deleted file mode 100755
index cce682b5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/error.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Cred errors."""
-
-class Unauthorized(Exception):
- """Standard unauthorized error."""
-
-
-
-class LoginFailed(Exception):
- """
- The user's request to log in failed for some reason.
- """
-
-
-
-class UnauthorizedLogin(LoginFailed, Unauthorized):
- """The user was not authorized to log in.
- """
-
-
-
-class UnhandledCredentials(LoginFailed):
- """A type of credentials were passed in with no knowledge of how to check
- them. This is a server configuration error - it means that a protocol was
- connected to a Portal without a CredentialChecker that can check all of its
- potential authentication strategies.
- """
-
-
-
-class LoginDenied(LoginFailed):
- """
- The realm rejected this login for some reason.
-
- Examples of reasons this might be raised include an avatar logging in
- too frequently, a quota having been fully used, or the overall server
- load being too high.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/pamauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/pamauth.py
deleted file mode 100755
index 12357dfb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/pamauth.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support for asynchronously authenticating using PAM.
-"""
-
-
-import PAM
-
-import getpass, threading, os
-
-from twisted.internet import threads, defer
-
-def pamAuthenticateThread(service, user, conv):
- def _conv(items):
- from twisted.internet import reactor
- try:
- d = conv(items)
- except:
- import traceback
- traceback.print_exc()
- return
- ev = threading.Event()
- def cb(r):
- ev.r = (1, r)
- ev.set()
- def eb(e):
- ev.r = (0, e)
- ev.set()
- reactor.callFromThread(d.addCallbacks, cb, eb)
- ev.wait()
- done = ev.r
- if done[0]:
- return done[1]
- else:
- raise done[1].type, done[1].value
-
- return callIntoPAM(service, user, _conv)
-
-def callIntoPAM(service, user, conv):
- """A testing hook.
- """
- pam = PAM.pam()
- pam.start(service)
- pam.set_item(PAM.PAM_USER, user)
- pam.set_item(PAM.PAM_CONV, conv)
- gid = os.getegid()
- uid = os.geteuid()
- os.setegid(0)
- os.seteuid(0)
- try:
- pam.authenticate() # these will raise
- pam.acct_mgmt()
- return 1
- finally:
- os.setegid(gid)
- os.seteuid(uid)
-
-def defConv(items):
- resp = []
- for i in range(len(items)):
- message, kind = items[i]
- if kind == 1: # password
- p = getpass.getpass(message)
- resp.append((p, 0))
- elif kind == 2: # text
- p = raw_input(message)
- resp.append((p, 0))
- elif kind in (3,4):
- print message
- resp.append(("", 0))
- else:
- return defer.fail('foo')
- d = defer.succeed(resp)
- return d
-
-def pamAuthenticate(service, user, conv):
- return threads.deferToThread(pamAuthenticateThread, service, user, conv)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/portal.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/portal.py
deleted file mode 100755
index bbb0af8e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/portal.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# -*- test-case-name: twisted.test.test_newcred -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The point of integration of application and authentication.
-"""
-
-
-from twisted.internet import defer
-from twisted.internet.defer import maybeDeferred
-from twisted.python import failure, reflect
-from twisted.cred import error
-from zope.interface import providedBy, Interface
-
-
-class IRealm(Interface):
- """
- The realm connects application-specific objects to the
- authentication system.
- """
- def requestAvatar(avatarId, mind, *interfaces):
- """
- Return avatar which provides one of the given interfaces.
-
- @param avatarId: a string that identifies an avatar, as returned by
- L{ICredentialsChecker.requestAvatarId<twisted.cred.checkers.ICredentialsChecker.requestAvatarId>}
- (via a Deferred). Alternatively, it may be
- C{twisted.cred.checkers.ANONYMOUS}.
- @param mind: usually None. See the description of mind in
- L{Portal.login}.
- @param interfaces: the interface(s) the returned avatar should
- implement, e.g. C{IMailAccount}. See the description of
- L{Portal.login}.
-
- @returns: a deferred which will fire a tuple of (interface,
- avatarAspect, logout), or the tuple itself. The interface will be
- one of the interfaces passed in the 'interfaces' argument. The
- 'avatarAspect' will implement that interface. The 'logout' object
- is a callable which will detach the mind from the avatar.
- """
-
-
-class Portal:
- """
- A mediator between clients and a realm.
-
- A portal is associated with one Realm and zero or more credentials checkers.
- When a login is attempted, the portal finds the appropriate credentials
- checker for the credentials given, invokes it, and if the credentials are
- valid, retrieves the appropriate avatar from the Realm.
-
- This class is not intended to be subclassed. Customization should be done
- in the realm object and in the credentials checker objects.
- """
- def __init__(self, realm, checkers=()):
- """
- Create a Portal to a L{IRealm}.
- """
- self.realm = realm
- self.checkers = {}
- for checker in checkers:
- self.registerChecker(checker)
-
- def listCredentialsInterfaces(self):
- """
- Return list of credentials interfaces that can be used to login.
- """
- return self.checkers.keys()
-
- def registerChecker(self, checker, *credentialInterfaces):
- if not credentialInterfaces:
- credentialInterfaces = checker.credentialInterfaces
- for credentialInterface in credentialInterfaces:
- self.checkers[credentialInterface] = checker
-
- def login(self, credentials, mind, *interfaces):
- """
- @param credentials: an implementor of
- L{twisted.cred.credentials.ICredentials}
-
- @param mind: an object which implements a client-side interface for
- your particular realm. In many cases, this may be None, so if the
- word 'mind' confuses you, just ignore it.
-
- @param interfaces: list of interfaces for the perspective that the mind
- wishes to attach to. Usually, this will be only one interface, for
- example IMailAccount. For highly dynamic protocols, however, this
- may be a list like (IMailAccount, IUserChooser, IServiceInfo). To
- expand: if we are speaking to the system over IMAP, any information
- that will be relayed to the user MUST be returned as an
- IMailAccount implementor; IMAP clients would not be able to
- understand anything else. Any information about unusual status
- would have to be relayed as a single mail message in an
- otherwise-empty mailbox. However, in a web-based mail system, or a
- PB-based client, the ``mind'' object inside the web server
- (implemented with a dynamic page-viewing mechanism such as a
- Twisted Web Resource) or on the user's client program may be
- intelligent enough to respond to several ``server''-side
- interfaces.
-
- @return: A deferred which will fire a tuple of (interface,
- avatarAspect, logout). The interface will be one of the interfaces
- passed in the 'interfaces' argument. The 'avatarAspect' will
- implement that interface. The 'logout' object is a callable which
- will detach the mind from the avatar. It must be called when the
- user has conceptually disconnected from the service. Although in
- some cases this will not be in connectionLost (such as in a
- web-based session), it will always be at the end of a user's
- interactive session.
- """
- for i in self.checkers:
- if i.providedBy(credentials):
- return maybeDeferred(self.checkers[i].requestAvatarId, credentials
- ).addCallback(self.realm.requestAvatar, mind, *interfaces
- )
- ifac = providedBy(credentials)
- return defer.fail(failure.Failure(error.UnhandledCredentials(
- "No checker for %s" % ', '.join(map(reflect.qual, ifac)))))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/strcred.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/strcred.py
deleted file mode 100755
index 5f99a16c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/cred/strcred.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# -*- test-case-name: twisted.test.test_strcred -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-
-"""
-Support for resolving command-line strings that represent different
-checkers available to cred.
-
-Examples:
- - passwd:/etc/passwd
- - memory:admin:asdf:user:lkj
- - unix
-"""
-
-import sys
-
-from zope.interface import Interface, Attribute
-
-from twisted.plugin import getPlugins
-from twisted.python import usage
-
-
-
-class ICheckerFactory(Interface):
- """
- A factory for objects which provide
- L{twisted.cred.checkers.ICredentialsChecker}.
-
- It's implemented by twistd plugins creating checkers.
- """
-
- authType = Attribute(
- 'A tag that identifies the authentication method.')
-
-
- authHelp = Attribute(
- 'A detailed (potentially multi-line) description of precisely '
- 'what functionality this CheckerFactory provides.')
-
-
- argStringFormat = Attribute(
- 'A short (one-line) description of the argument string format.')
-
-
- credentialInterfaces = Attribute(
- 'A list of credentials interfaces that this factory will support.')
-
-
- def generateChecker(argstring):
- """
- Return an L{ICredentialChecker} provider using the supplied
- argument string.
- """
-
-
-
-class StrcredException(Exception):
- """
- Base exception class for strcred.
- """
-
-
-
-class InvalidAuthType(StrcredException):
- """
- Raised when a user provides an invalid identifier for the
- authentication plugin (known as the authType).
- """
-
-
-
-class InvalidAuthArgumentString(StrcredException):
- """
- Raised by an authentication plugin when the argument string
- provided is formatted incorrectly.
- """
-
-
-
-class UnsupportedInterfaces(StrcredException):
- """
- Raised when an application is given a checker to use that does not
- provide any of the application's supported credentials interfaces.
- """
-
-
-
-# This will be used to warn the users whenever they view help for an
-# authType that is not supported by the application.
-notSupportedWarning = ("WARNING: This authType is not supported by "
- "this application.")
-
-
-
-def findCheckerFactories():
- """
- Find all objects that implement L{ICheckerFactory}.
- """
- return getPlugins(ICheckerFactory)
-
-
-
-def findCheckerFactory(authType):
- """
- Find the first checker factory that supports the given authType.
- """
- for factory in findCheckerFactories():
- if factory.authType == authType:
- return factory
- raise InvalidAuthType(authType)
-
-
-
-def makeChecker(description):
- """
- Returns an L{twisted.cred.checkers.ICredentialsChecker} based on the
- contents of a descriptive string. Similar to
- L{twisted.application.strports}.
- """
- if ':' in description:
- authType, argstring = description.split(':', 1)
- else:
- authType = description
- argstring = ''
- return findCheckerFactory(authType).generateChecker(argstring)
-
-
-
-class AuthOptionMixin:
- """
- Defines helper methods that can be added on to any
- L{usage.Options} subclass that needs authentication.
-
- This mixin implements three new options methods:
-
- The opt_auth method (--auth) will write two new values to the
- 'self' dictionary: C{credInterfaces} (a dict of lists) and
- C{credCheckers} (a list).
-
- The opt_help_auth method (--help-auth) will search for all
- available checker plugins and list them for the user; it will exit
- when finished.
-
- The opt_help_auth_type method (--help-auth-type) will display
- detailed help for a particular checker plugin.
-
- @cvar supportedInterfaces: An iterable object that returns
- credential interfaces which this application is able to support.
-
- @cvar authOutput: A writeable object to which this options class
- will send all help-related output. Default: L{sys.stdout}
- """
-
- supportedInterfaces = None
- authOutput = sys.stdout
-
-
- def supportsInterface(self, interface):
- """
- Returns whether a particular credentials interface is supported.
- """
- return (self.supportedInterfaces is None
- or interface in self.supportedInterfaces)
-
-
- def supportsCheckerFactory(self, factory):
- """
- Returns whether a checker factory will provide at least one of
- the credentials interfaces that we care about.
- """
- for interface in factory.credentialInterfaces:
- if self.supportsInterface(interface):
- return True
- return False
-
-
- def addChecker(self, checker):
- """
- Supply a supplied credentials checker to the Options class.
- """
- # First figure out which interfaces we're willing to support.
- supported = []
- if self.supportedInterfaces is None:
- supported = checker.credentialInterfaces
- else:
- for interface in checker.credentialInterfaces:
- if self.supportsInterface(interface):
- supported.append(interface)
- if not supported:
- raise UnsupportedInterfaces(checker.credentialInterfaces)
- # If we get this far, then we know we can use this checker.
- if 'credInterfaces' not in self:
- self['credInterfaces'] = {}
- if 'credCheckers' not in self:
- self['credCheckers'] = []
- self['credCheckers'].append(checker)
- for interface in supported:
- self['credInterfaces'].setdefault(interface, []).append(checker)
-
-
- def opt_auth(self, description):
- """
- Specify an authentication method for the server.
- """
- try:
- self.addChecker(makeChecker(description))
- except UnsupportedInterfaces, e:
- raise usage.UsageError(
- 'Auth plugin not supported: %s' % e.args[0])
- except InvalidAuthType, e:
- raise usage.UsageError(
- 'Auth plugin not recognized: %s' % e.args[0])
- except Exception, e:
- raise usage.UsageError('Unexpected error: %s' % e)
-
-
- def _checkerFactoriesForOptHelpAuth(self):
- """
- Return a list of which authTypes will be displayed by --help-auth.
- This makes it a lot easier to test this module.
- """
- for factory in findCheckerFactories():
- for interface in factory.credentialInterfaces:
- if self.supportsInterface(interface):
- yield factory
- break
-
-
- def opt_help_auth(self):
- """
- Show all authentication methods available.
- """
- self.authOutput.write("Usage: --auth AuthType[:ArgString]\n")
- self.authOutput.write("For detailed help: --help-auth-type AuthType\n")
- self.authOutput.write('\n')
- # Figure out the right width for our columns
- firstLength = 0
- for factory in self._checkerFactoriesForOptHelpAuth():
- if len(factory.authType) > firstLength:
- firstLength = len(factory.authType)
- formatString = ' %%-%is\t%%s\n' % firstLength
- self.authOutput.write(formatString % ('AuthType', 'ArgString format'))
- self.authOutput.write(formatString % ('========', '================'))
- for factory in self._checkerFactoriesForOptHelpAuth():
- self.authOutput.write(
- formatString % (factory.authType, factory.argStringFormat))
- self.authOutput.write('\n')
- raise SystemExit(0)
-
-
- def opt_help_auth_type(self, authType):
- """
- Show help for a particular authentication type.
- """
- try:
- cf = findCheckerFactory(authType)
- except InvalidAuthType:
- raise usage.UsageError("Invalid auth type: %s" % authType)
- self.authOutput.write("Usage: --auth %s[:ArgString]\n" % authType)
- self.authOutput.write("ArgString format: %s\n" % cf.argStringFormat)
- self.authOutput.write('\n')
- for line in cf.authHelp.strip().splitlines():
- self.authOutput.write(' %s\n' % line.rstrip())
- self.authOutput.write('\n')
- if not self.supportsCheckerFactory(cf):
- self.authOutput.write(' %s\n' % notSupportedWarning)
- self.authOutput.write('\n')
- raise SystemExit(0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/__init__.py
deleted file mode 100755
index 06c6a61e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Enterprise: database support for Twisted services.
-"""
-
-__all__ = ['adbapi']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/adbapi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/adbapi.py
deleted file mode 100755
index 0531d2da..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/enterprise/adbapi.py
+++ /dev/null
@@ -1,483 +0,0 @@
-# -*- test-case-name: twisted.test.test_adbapi -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An asynchronous mapping to U{DB-API 2.0<http://www.python.org/topics/database/DatabaseAPI-2.0.html>}.
-"""
-
-import sys
-
-from twisted.internet import threads
-from twisted.python import reflect, log
-from twisted.python.deprecate import deprecated
-from twisted.python.versions import Version
-
-
-
-class ConnectionLost(Exception):
- """
- This exception means that a db connection has been lost. Client code may
- try again.
- """
-
-
-
-class Connection(object):
- """
- A wrapper for a DB-API connection instance.
-
- The wrapper passes almost everything to the wrapped connection and so has
- the same API. However, the Connection knows about its pool and also
- handle reconnecting should when the real connection dies.
- """
-
- def __init__(self, pool):
- self._pool = pool
- self._connection = None
- self.reconnect()
-
- def close(self):
- # The way adbapi works right now means that closing a connection is
- # a really bad thing as it leaves a dead connection associated with
- # a thread in the thread pool.
- # Really, I think closing a pooled connection should return it to the
- # pool but that's handled by the runWithConnection method already so,
- # rather than upsetting anyone by raising an exception, let's ignore
- # the request
- pass
-
- def rollback(self):
- if not self._pool.reconnect:
- self._connection.rollback()
- return
-
- try:
- self._connection.rollback()
- curs = self._connection.cursor()
- curs.execute(self._pool.good_sql)
- curs.close()
- self._connection.commit()
- return
- except:
- log.err(None, "Rollback failed")
-
- self._pool.disconnect(self._connection)
-
- if self._pool.noisy:
- log.msg("Connection lost.")
-
- raise ConnectionLost()
-
- def reconnect(self):
- if self._connection is not None:
- self._pool.disconnect(self._connection)
- self._connection = self._pool.connect()
-
- def __getattr__(self, name):
- return getattr(self._connection, name)
-
-
-class Transaction:
- """A lightweight wrapper for a DB-API 'cursor' object.
-
- Relays attribute access to the DB cursor. That is, you can call
- execute(), fetchall(), etc., and they will be called on the
- underlying DB-API cursor object. Attributes will also be
- retrieved from there.
- """
- _cursor = None
-
- def __init__(self, pool, connection):
- self._pool = pool
- self._connection = connection
- self.reopen()
-
- def close(self):
- _cursor = self._cursor
- self._cursor = None
- _cursor.close()
-
- def reopen(self):
- if self._cursor is not None:
- self.close()
-
- try:
- self._cursor = self._connection.cursor()
- return
- except:
- if not self._pool.reconnect:
- raise
- else:
- log.err(None, "Cursor creation failed")
-
- if self._pool.noisy:
- log.msg('Connection lost, reconnecting')
-
- self.reconnect()
- self._cursor = self._connection.cursor()
-
- def reconnect(self):
- self._connection.reconnect()
- self._cursor = None
-
- def __getattr__(self, name):
- return getattr(self._cursor, name)
-
-
-class ConnectionPool:
- """
- Represent a pool of connections to a DB-API 2.0 compliant database.
-
- @ivar connectionFactory: factory for connections, default to L{Connection}.
- @type connectionFactory: any callable.
-
- @ivar transactionFactory: factory for transactions, default to
- L{Transaction}.
- @type transactionFactory: any callable
-
- @ivar shutdownID: C{None} or a handle on the shutdown event trigger
- which will be used to stop the connection pool workers when the
- reactor stops.
-
- @ivar _reactor: The reactor which will be used to schedule startup and
- shutdown events.
- @type _reactor: L{IReactorCore} provider
- """
-
- CP_ARGS = "min max name noisy openfun reconnect good_sql".split()
-
- noisy = False # if true, generate informational log messages
- min = 3 # minimum number of connections in pool
- max = 5 # maximum number of connections in pool
- name = None # Name to assign to thread pool for debugging
- openfun = None # A function to call on new connections
- reconnect = False # reconnect when connections fail
- good_sql = 'select 1' # a query which should always succeed
-
- running = False # true when the pool is operating
- connectionFactory = Connection
- transactionFactory = Transaction
-
- # Initialize this to None so it's available in close() even if start()
- # never runs.
- shutdownID = None
-
- def __init__(self, dbapiName, *connargs, **connkw):
- """Create a new ConnectionPool.
-
- Any positional or keyword arguments other than those documented here
- are passed to the DB-API object when connecting. Use these arguments to
- pass database names, usernames, passwords, etc.
-
- @param dbapiName: an import string to use to obtain a DB-API compatible
- module (e.g. 'pyPgSQL.PgSQL')
-
- @param cp_min: the minimum number of connections in pool (default 3)
-
- @param cp_max: the maximum number of connections in pool (default 5)
-
- @param cp_noisy: generate informational log messages during operation
- (default False)
-
- @param cp_openfun: a callback invoked after every connect() on the
- underlying DB-API object. The callback is passed a
- new DB-API connection object. This callback can
- setup per-connection state such as charset,
- timezone, etc.
-
- @param cp_reconnect: detect connections which have failed and reconnect
- (default False). Failed connections may result in
- ConnectionLost exceptions, which indicate the
- query may need to be re-sent.
-
- @param cp_good_sql: an sql query which should always succeed and change
- no state (default 'select 1')
-
- @param cp_reactor: use this reactor instead of the global reactor
- (added in Twisted 10.2).
- @type cp_reactor: L{IReactorCore} provider
- """
-
- self.dbapiName = dbapiName
- self.dbapi = reflect.namedModule(dbapiName)
-
- if getattr(self.dbapi, 'apilevel', None) != '2.0':
- log.msg('DB API module not DB API 2.0 compliant.')
-
- if getattr(self.dbapi, 'threadsafety', 0) < 1:
- log.msg('DB API module not sufficiently thread-safe.')
-
- reactor = connkw.pop('cp_reactor', None)
- if reactor is None:
- from twisted.internet import reactor
- self._reactor = reactor
-
- self.connargs = connargs
- self.connkw = connkw
-
- for arg in self.CP_ARGS:
- cp_arg = 'cp_%s' % arg
- if cp_arg in connkw:
- setattr(self, arg, connkw[cp_arg])
- del connkw[cp_arg]
-
- self.min = min(self.min, self.max)
- self.max = max(self.min, self.max)
-
- self.connections = {} # all connections, hashed on thread id
-
- # these are optional so import them here
- from twisted.python import threadpool
- import thread
-
- self.threadID = thread.get_ident
- self.threadpool = threadpool.ThreadPool(self.min, self.max)
- self.startID = self._reactor.callWhenRunning(self._start)
-
-
- def _start(self):
- self.startID = None
- return self.start()
-
-
- def start(self):
- """
- Start the connection pool.
-
- If you are using the reactor normally, this function does *not*
- need to be called.
- """
- if not self.running:
- self.threadpool.start()
- self.shutdownID = self._reactor.addSystemEventTrigger(
- 'during', 'shutdown', self.finalClose)
- self.running = True
-
-
- def runWithConnection(self, func, *args, **kw):
- """
- Execute a function with a database connection and return the result.
-
- @param func: A callable object of one argument which will be executed
- in a thread with a connection from the pool. It will be passed as
- its first argument a L{Connection} instance (whose interface is
- mostly identical to that of a connection object for your DB-API
- module of choice), and its results will be returned as a Deferred.
- If the method raises an exception the transaction will be rolled
- back. Otherwise, the transaction will be committed. B{Note} that
- this function is B{not} run in the main thread: it must be
- threadsafe.
-
- @param *args: positional arguments to be passed to func
-
- @param **kw: keyword arguments to be passed to func
-
- @return: a Deferred which will fire the return value of
- C{func(Transaction(...), *args, **kw)}, or a Failure.
- """
- from twisted.internet import reactor
- return threads.deferToThreadPool(reactor, self.threadpool,
- self._runWithConnection,
- func, *args, **kw)
-
-
- def _runWithConnection(self, func, *args, **kw):
- conn = self.connectionFactory(self)
- try:
- result = func(conn, *args, **kw)
- conn.commit()
- return result
- except:
- excType, excValue, excTraceback = sys.exc_info()
- try:
- conn.rollback()
- except:
- log.err(None, "Rollback failed")
- raise excType, excValue, excTraceback
-
-
- def runInteraction(self, interaction, *args, **kw):
- """
- Interact with the database and return the result.
-
- The 'interaction' is a callable object which will be executed
- in a thread using a pooled connection. It will be passed an
- L{Transaction} object as an argument (whose interface is
- identical to that of the database cursor for your DB-API
- module of choice), and its results will be returned as a
- Deferred. If running the method raises an exception, the
- transaction will be rolled back. If the method returns a
- value, the transaction will be committed.
-
- NOTE that the function you pass is *not* run in the main
- thread: you may have to worry about thread-safety in the
- function you pass to this if it tries to use non-local
- objects.
-
- @param interaction: a callable object whose first argument
- is an L{adbapi.Transaction}.
-
- @param *args: additional positional arguments to be passed
- to interaction
-
- @param **kw: keyword arguments to be passed to interaction
-
- @return: a Deferred which will fire the return value of
- 'interaction(Transaction(...), *args, **kw)', or a Failure.
- """
- from twisted.internet import reactor
- return threads.deferToThreadPool(reactor, self.threadpool,
- self._runInteraction,
- interaction, *args, **kw)
-
-
- def runQuery(self, *args, **kw):
- """Execute an SQL query and return the result.
-
- A DB-API cursor will will be invoked with cursor.execute(*args, **kw).
- The exact nature of the arguments will depend on the specific flavor
- of DB-API being used, but the first argument in *args be an SQL
- statement. The result of a subsequent cursor.fetchall() will be
- fired to the Deferred which is returned. If either the 'execute' or
- 'fetchall' methods raise an exception, the transaction will be rolled
- back and a Failure returned.
-
- The *args and **kw arguments will be passed to the DB-API cursor's
- 'execute' method.
-
- @return: a Deferred which will fire the return value of a DB-API
- cursor's 'fetchall' method, or a Failure.
- """
- return self.runInteraction(self._runQuery, *args, **kw)
-
-
- def runOperation(self, *args, **kw):
- """Execute an SQL query and return None.
-
- A DB-API cursor will will be invoked with cursor.execute(*args, **kw).
- The exact nature of the arguments will depend on the specific flavor
- of DB-API being used, but the first argument in *args will be an SQL
- statement. This method will not attempt to fetch any results from the
- query and is thus suitable for INSERT, DELETE, and other SQL statements
- which do not return values. If the 'execute' method raises an
- exception, the transaction will be rolled back and a Failure returned.
-
- The args and kw arguments will be passed to the DB-API cursor's
- 'execute' method.
-
- return: a Deferred which will fire None or a Failure.
- """
- return self.runInteraction(self._runOperation, *args, **kw)
-
-
- def close(self):
- """
- Close all pool connections and shutdown the pool.
- """
- if self.shutdownID:
- self._reactor.removeSystemEventTrigger(self.shutdownID)
- self.shutdownID = None
- if self.startID:
- self._reactor.removeSystemEventTrigger(self.startID)
- self.startID = None
- self.finalClose()
-
- def finalClose(self):
- """This should only be called by the shutdown trigger."""
-
- self.shutdownID = None
- self.threadpool.stop()
- self.running = False
- for conn in self.connections.values():
- self._close(conn)
- self.connections.clear()
-
- def connect(self):
- """Return a database connection when one becomes available.
-
- This method blocks and should be run in a thread from the internal
- threadpool. Don't call this method directly from non-threaded code.
- Using this method outside the external threadpool may exceed the
- maximum number of connections in the pool.
-
- @return: a database connection from the pool.
- """
-
- tid = self.threadID()
- conn = self.connections.get(tid)
- if conn is None:
- if self.noisy:
- log.msg('adbapi connecting: %s %s%s' % (self.dbapiName,
- self.connargs or '',
- self.connkw or ''))
- conn = self.dbapi.connect(*self.connargs, **self.connkw)
- if self.openfun != None:
- self.openfun(conn)
- self.connections[tid] = conn
- return conn
-
- def disconnect(self, conn):
- """Disconnect a database connection associated with this pool.
-
- Note: This function should only be used by the same thread which
- called connect(). As with connect(), this function is not used
- in normal non-threaded twisted code.
- """
- tid = self.threadID()
- if conn is not self.connections.get(tid):
- raise Exception("wrong connection for thread")
- if conn is not None:
- self._close(conn)
- del self.connections[tid]
-
-
- def _close(self, conn):
- if self.noisy:
- log.msg('adbapi closing: %s' % (self.dbapiName,))
- try:
- conn.close()
- except:
- log.err(None, "Connection close failed")
-
-
- def _runInteraction(self, interaction, *args, **kw):
- conn = self.connectionFactory(self)
- trans = self.transactionFactory(self, conn)
- try:
- result = interaction(trans, *args, **kw)
- trans.close()
- conn.commit()
- return result
- except:
- excType, excValue, excTraceback = sys.exc_info()
- try:
- conn.rollback()
- except:
- log.err(None, "Rollback failed")
- raise excType, excValue, excTraceback
-
-
- def _runQuery(self, trans, *args, **kw):
- trans.execute(*args, **kw)
- return trans.fetchall()
-
- def _runOperation(self, trans, *args, **kw):
- trans.execute(*args, **kw)
-
- def __getstate__(self):
- return {'dbapiName': self.dbapiName,
- 'min': self.min,
- 'max': self.max,
- 'noisy': self.noisy,
- 'reconnect': self.reconnect,
- 'good_sql': self.good_sql,
- 'connargs': self.connargs,
- 'connkw': self.connkw}
-
- def __setstate__(self, state):
- self.__dict__ = state
- self.__init__(self.dbapiName, *self.connargs, **self.connkw)
-
-
-__all__ = ['Transaction', 'ConnectionPool']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/__init__.py
deleted file mode 100755
index a3d851d1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Twisted Internet: Asynchronous I/O and Events.
-
-Twisted Internet is a collection of compatible event-loops for Python. It contains
-the code to dispatch events to interested observers and a portable API so that
-observers need not care about which event loop is running. Thus, it is possible
-to use the same code for different loops, from Twisted's basic, yet portable,
-select-based loop to the loops of various GUI toolkits like GTK+ or Tk.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_baseprocess.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_baseprocess.py
deleted file mode 100755
index 0a06259b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_baseprocess.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- test-case-name: twisted.test.test_process -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cross-platform process-related functionality used by different
-L{IReactorProcess} implementations.
-"""
-
-from twisted.python.reflect import qual
-from twisted.python.deprecate import getWarningMethod
-from twisted.python.failure import Failure
-from twisted.python.log import err
-from twisted.persisted.styles import Ephemeral
-
-_missingProcessExited = ("Since Twisted 8.2, IProcessProtocol.processExited "
- "is required. %s must implement it.")
-
-class BaseProcess(Ephemeral):
- pid = None
- status = None
- lostProcess = 0
- proto = None
-
- def __init__(self, protocol):
- self.proto = protocol
-
-
- def _callProcessExited(self, reason):
- default = object()
- processExited = getattr(self.proto, 'processExited', default)
- if processExited is default:
- getWarningMethod()(
- _missingProcessExited % (qual(self.proto.__class__),),
- DeprecationWarning, stacklevel=0)
- else:
- processExited(Failure(reason))
-
-
- def processEnded(self, status):
- """
- This is called when the child terminates.
- """
- self.status = status
- self.lostProcess += 1
- self.pid = None
- self._callProcessExited(self._getReason(status))
- self.maybeCallProcessEnded()
-
-
- def maybeCallProcessEnded(self):
- """
- Call processEnded on protocol after final cleanup.
- """
- if self.proto is not None:
- reason = self._getReason(self.status)
- proto = self.proto
- self.proto = None
- try:
- proto.processEnded(Failure(reason))
- except:
- err(None, "unexpected error in processEnded")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_dumbwin32proc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_dumbwin32proc.py
deleted file mode 100755
index 0df82ae1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_dumbwin32proc.py
+++ /dev/null
@@ -1,388 +0,0 @@
-# -*- test-case-name: twisted.test.test_process -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-http://isometric.sixsided.org/_/gates_in_the_head/
-"""
-
-import os
-
-# Win32 imports
-import win32api
-import win32con
-import win32event
-import win32file
-import win32pipe
-import win32process
-import win32security
-
-import pywintypes
-
-# security attributes for pipes
-PIPE_ATTRS_INHERITABLE = win32security.SECURITY_ATTRIBUTES()
-PIPE_ATTRS_INHERITABLE.bInheritHandle = 1
-
-from zope.interface import implements
-from twisted.internet.interfaces import IProcessTransport, IConsumer, IProducer
-
-from twisted.python.win32 import quoteArguments
-
-from twisted.internet import error
-
-from twisted.internet import _pollingfile
-from twisted.internet._baseprocess import BaseProcess
-
-def debug(msg):
- import sys
- print msg
- sys.stdout.flush()
-
-class _Reaper(_pollingfile._PollableResource):
-
- def __init__(self, proc):
- self.proc = proc
-
- def checkWork(self):
- if win32event.WaitForSingleObject(self.proc.hProcess, 0) != win32event.WAIT_OBJECT_0:
- return 0
- exitCode = win32process.GetExitCodeProcess(self.proc.hProcess)
- self.deactivate()
- self.proc.processEnded(exitCode)
- return 0
-
-
-def _findShebang(filename):
- """
- Look for a #! line, and return the value following the #! if one exists, or
- None if this file is not a script.
-
- I don't know if there are any conventions for quoting in Windows shebang
- lines, so this doesn't support any; therefore, you may not pass any
- arguments to scripts invoked as filters. That's probably wrong, so if
- somebody knows more about the cultural expectations on Windows, please feel
- free to fix.
-
- This shebang line support was added in support of the CGI tests;
- appropriately enough, I determined that shebang lines are culturally
- accepted in the Windows world through this page::
-
- http://www.cgi101.com/learn/connect/winxp.html
-
- @param filename: str representing a filename
-
- @return: a str representing another filename.
- """
- f = file(filename, 'rU')
- if f.read(2) == '#!':
- exe = f.readline(1024).strip('\n')
- return exe
-
-def _invalidWin32App(pywinerr):
- """
- Determine if a pywintypes.error is telling us that the given process is
- 'not a valid win32 application', i.e. not a PE format executable.
-
- @param pywinerr: a pywintypes.error instance raised by CreateProcess
-
- @return: a boolean
- """
-
- # Let's do this better in the future, but I have no idea what this error
- # is; MSDN doesn't mention it, and there is no symbolic constant in
- # win32process module that represents 193.
-
- return pywinerr.args[0] == 193
-
-class Process(_pollingfile._PollingTimer, BaseProcess):
- """A process that integrates with the Twisted event loop.
-
- If your subprocess is a python program, you need to:
-
- - Run python.exe with the '-u' command line option - this turns on
- unbuffered I/O. Buffering stdout/err/in can cause problems, see e.g.
- http://support.microsoft.com/default.aspx?scid=kb;EN-US;q1903
-
- - If you don't want Windows messing with data passed over
- stdin/out/err, set the pipes to be in binary mode::
-
- import os, sys, mscvrt
- msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
- msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
- msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
-
- """
- implements(IProcessTransport, IConsumer, IProducer)
-
- closedNotifies = 0
-
- def __init__(self, reactor, protocol, command, args, environment, path):
- """
- Create a new child process.
- """
- _pollingfile._PollingTimer.__init__(self, reactor)
- BaseProcess.__init__(self, protocol)
-
- # security attributes for pipes
- sAttrs = win32security.SECURITY_ATTRIBUTES()
- sAttrs.bInheritHandle = 1
-
- # create the pipes which will connect to the secondary process
- self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
- self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
- hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0)
-
- win32pipe.SetNamedPipeHandleState(self.hStdinW,
- win32pipe.PIPE_NOWAIT,
- None,
- None)
-
- # set the info structure for the new process.
- StartupInfo = win32process.STARTUPINFO()
- StartupInfo.hStdOutput = hStdoutW
- StartupInfo.hStdError = hStderrW
- StartupInfo.hStdInput = hStdinR
- StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES
-
- # Create new handles whose inheritance property is false
- currentPid = win32api.GetCurrentProcess()
-
- tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0,
- win32con.DUPLICATE_SAME_ACCESS)
- win32file.CloseHandle(self.hStdoutR)
- self.hStdoutR = tmp
-
- tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0,
- win32con.DUPLICATE_SAME_ACCESS)
- win32file.CloseHandle(self.hStderrR)
- self.hStderrR = tmp
-
- tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0,
- win32con.DUPLICATE_SAME_ACCESS)
- win32file.CloseHandle(self.hStdinW)
- self.hStdinW = tmp
-
- # Add the specified environment to the current environment - this is
- # necessary because certain operations are only supported on Windows
- # if certain environment variables are present.
-
- env = os.environ.copy()
- env.update(environment or {})
-
- cmdline = quoteArguments(args)
- # TODO: error detection here. See #2787 and #4184.
- def doCreate():
- self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess(
- command, cmdline, None, None, 1, 0, env, path, StartupInfo)
- try:
- try:
- doCreate()
- except TypeError, e:
- # win32process.CreateProcess cannot deal with mixed
- # str/unicode environment, so we make it all Unicode
- if e.args != ('All dictionary items must be strings, or '
- 'all must be unicode',):
- raise
- newenv = {}
- for key, value in env.items():
- newenv[unicode(key)] = unicode(value)
- env = newenv
- doCreate()
- except pywintypes.error, pwte:
- if not _invalidWin32App(pwte):
- # This behavior isn't _really_ documented, but let's make it
- # consistent with the behavior that is documented.
- raise OSError(pwte)
- else:
- # look for a shebang line. Insert the original 'command'
- # (actually a script) into the new arguments list.
- sheb = _findShebang(command)
- if sheb is None:
- raise OSError(
- "%r is neither a Windows executable, "
- "nor a script with a shebang line" % command)
- else:
- args = list(args)
- args.insert(0, command)
- cmdline = quoteArguments(args)
- origcmd = command
- command = sheb
- try:
- # Let's try again.
- doCreate()
- except pywintypes.error, pwte2:
- # d'oh, failed again!
- if _invalidWin32App(pwte2):
- raise OSError(
- "%r has an invalid shebang line: "
- "%r is not a valid executable" % (
- origcmd, sheb))
- raise OSError(pwte2)
-
- # close handles which only the child will use
- win32file.CloseHandle(hStderrW)
- win32file.CloseHandle(hStdoutW)
- win32file.CloseHandle(hStdinR)
-
- # set up everything
- self.stdout = _pollingfile._PollableReadPipe(
- self.hStdoutR,
- lambda data: self.proto.childDataReceived(1, data),
- self.outConnectionLost)
-
- self.stderr = _pollingfile._PollableReadPipe(
- self.hStderrR,
- lambda data: self.proto.childDataReceived(2, data),
- self.errConnectionLost)
-
- self.stdin = _pollingfile._PollableWritePipe(
- self.hStdinW, self.inConnectionLost)
-
- for pipewatcher in self.stdout, self.stderr, self.stdin:
- self._addPollableResource(pipewatcher)
-
-
- # notify protocol
- self.proto.makeConnection(self)
-
- self._addPollableResource(_Reaper(self))
-
-
- def signalProcess(self, signalID):
- if self.pid is None:
- raise error.ProcessExitedAlready()
- if signalID in ("INT", "TERM", "KILL"):
- win32process.TerminateProcess(self.hProcess, 1)
-
-
- def _getReason(self, status):
- if status == 0:
- return error.ProcessDone(status)
- return error.ProcessTerminated(status)
-
-
- def write(self, data):
- """
- Write data to the process' stdin.
-
- @type data: C{str}
- """
- self.stdin.write(data)
-
-
- def writeSequence(self, seq):
- """
- Write data to the process' stdin.
-
- @type data: C{list} of C{str}
- """
- self.stdin.writeSequence(seq)
-
-
- def writeToChild(self, fd, data):
- """
- Similar to L{ITransport.write} but also allows the file descriptor in
- the child process which will receive the bytes to be specified.
-
- This implementation is limited to writing to the child's standard input.
-
- @param fd: The file descriptor to which to write. Only stdin (C{0}) is
- supported.
- @type fd: C{int}
-
- @param data: The bytes to write.
- @type data: C{str}
-
- @return: C{None}
-
- @raise KeyError: If C{fd} is anything other than the stdin file
- descriptor (C{0}).
- """
- if fd == 0:
- self.stdin.write(data)
- else:
- raise KeyError(fd)
-
-
- def closeChildFD(self, fd):
- if fd == 0:
- self.closeStdin()
- elif fd == 1:
- self.closeStdout()
- elif fd == 2:
- self.closeStderr()
- else:
- raise NotImplementedError("Only standard-IO file descriptors available on win32")
-
- def closeStdin(self):
- """Close the process' stdin.
- """
- self.stdin.close()
-
- def closeStderr(self):
- self.stderr.close()
-
- def closeStdout(self):
- self.stdout.close()
-
- def loseConnection(self):
- """Close the process' stdout, in and err."""
- self.closeStdin()
- self.closeStdout()
- self.closeStderr()
-
-
- def outConnectionLost(self):
- self.proto.childConnectionLost(1)
- self.connectionLostNotify()
-
-
- def errConnectionLost(self):
- self.proto.childConnectionLost(2)
- self.connectionLostNotify()
-
-
- def inConnectionLost(self):
- self.proto.childConnectionLost(0)
- self.connectionLostNotify()
-
-
- def connectionLostNotify(self):
- """
- Will be called 3 times, by stdout/err threads and process handle.
- """
- self.closedNotifies += 1
- self.maybeCallProcessEnded()
-
-
- def maybeCallProcessEnded(self):
- if self.closedNotifies == 3 and self.lostProcess:
- win32file.CloseHandle(self.hProcess)
- win32file.CloseHandle(self.hThread)
- self.hProcess = None
- self.hThread = None
- BaseProcess.maybeCallProcessEnded(self)
-
-
- # IConsumer
- def registerProducer(self, producer, streaming):
- self.stdin.registerProducer(producer, streaming)
-
- def unregisterProducer(self):
- self.stdin.unregisterProducer()
-
- # IProducer
- def pauseProducing(self):
- self._pause()
-
- def resumeProducing(self):
- self._unpause()
-
- def stopProducing(self):
- self.loseConnection()
-
- def __repr__(self):
- """
- Return a string representation of the process.
- """
- return "<%s pid=%s>" % (self.__class__.__name__, self.pid)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_glibbase.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_glibbase.py
deleted file mode 100755
index bfb84ca2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_glibbase.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# -*- test-case-name: twisted.internet.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides base support for Twisted to interact with the glib/gtk
-mainloops.
-
-The classes in this module should not be used directly, but rather you should
-import gireactor or gtk3reactor for GObject Introspection based applications,
-or glib2reactor or gtk2reactor for applications using legacy static bindings.
-"""
-
-import sys
-
-from twisted.internet import base, posixbase, selectreactor
-from twisted.internet.interfaces import IReactorFDSet
-from twisted.python import log
-from twisted.python.compat import set
-from zope.interface import implements
-
-
-def ensureNotImported(moduleNames, errorMessage, preventImports=[]):
- """
- Check whether the given modules were imported, and if requested, ensure
- they will not be importable in the future.
-
- @param moduleNames: A list of module names we make sure aren't imported.
- @type moduleNames: C{list} of C{str}
-
- @param preventImports: A list of module name whose future imports should
- be prevented.
- @type preventImports: C{list} of C{str}
-
- @param errorMessage: Message to use when raising an C{ImportError}.
- @type errorMessage: C{str}
-
- @raises: C{ImportError} with given error message if a given module name
- has already been imported.
- """
- for name in moduleNames:
- if sys.modules.get(name) is not None:
- raise ImportError(errorMessage)
-
- # Disable module imports to avoid potential problems.
- for name in preventImports:
- sys.modules[name] = None
-
-
-
-class GlibWaker(posixbase._UnixWaker):
- """
- Run scheduled events after waking up.
- """
-
- def doRead(self):
- posixbase._UnixWaker.doRead(self)
- self.reactor._simulate()
-
-
-
-class GlibReactorBase(posixbase.PosixReactorBase, posixbase._PollLikeMixin):
- """
- Base class for GObject event loop reactors.
-
- Notification for I/O events (reads and writes on file descriptors) is done
- by the the gobject-based event loop. File descriptors are registered with
- gobject with the appropriate flags for read/write/disconnect notification.
-
- Time-based events, the results of C{callLater} and C{callFromThread}, are
- handled differently. Rather than registering each event with gobject, a
- single gobject timeout is registered for the earliest scheduled event, the
- output of C{reactor.timeout()}. For example, if there are timeouts in 1, 2
- and 3.4 seconds, a single timeout is registered for 1 second in the
- future. When this timeout is hit, C{_simulate} is called, which calls the
- appropriate Twisted-level handlers, and a new timeout is added to gobject
- by the C{_reschedule} method.
-
- To handle C{callFromThread} events, we use a custom waker that calls
- C{_simulate} whenever it wakes up.
-
- @ivar _sources: A dictionary mapping L{FileDescriptor} instances to
- GSource handles.
-
- @ivar _reads: A set of L{FileDescriptor} instances currently monitored for
- reading.
-
- @ivar _writes: A set of L{FileDescriptor} instances currently monitored for
- writing.
-
- @ivar _simtag: A GSource handle for the next L{simulate} call.
- """
- implements(IReactorFDSet)
-
- # Install a waker that knows it needs to call C{_simulate} in order to run
- # callbacks queued from a thread:
- _wakerFactory = GlibWaker
-
- def __init__(self, glib_module, gtk_module, useGtk=False):
- self._simtag = None
- self._reads = set()
- self._writes = set()
- self._sources = {}
- self._glib = glib_module
- self._gtk = gtk_module
- posixbase.PosixReactorBase.__init__(self)
-
- self._source_remove = self._glib.source_remove
- self._timeout_add = self._glib.timeout_add
-
- def _mainquit():
- if self._gtk.main_level():
- self._gtk.main_quit()
-
- if useGtk:
- self._pending = self._gtk.events_pending
- self._iteration = self._gtk.main_iteration_do
- self._crash = _mainquit
- self._run = self._gtk.main
- else:
- self.context = self._glib.main_context_default()
- self._pending = self.context.pending
- self._iteration = self.context.iteration
- self.loop = self._glib.MainLoop()
- self._crash = lambda: self._glib.idle_add(self.loop.quit)
- self._run = self.loop.run
-
-
- def _handleSignals(self):
- # First, install SIGINT and friends:
- base._SignalReactorMixin._handleSignals(self)
- # Next, since certain versions of gtk will clobber our signal handler,
- # set all signal handlers again after the event loop has started to
- # ensure they're *really* set. We don't call this twice so we don't
- # leak file descriptors created in the SIGCHLD initialization:
- self.callLater(0, posixbase.PosixReactorBase._handleSignals, self)
-
-
- # The input_add function in pygtk1 checks for objects with a
- # 'fileno' method and, if present, uses the result of that method
- # as the input source. The pygtk2 input_add does not do this. The
- # function below replicates the pygtk1 functionality.
-
- # In addition, pygtk maps gtk.input_add to _gobject.io_add_watch, and
- # g_io_add_watch() takes different condition bitfields than
- # gtk_input_add(). We use g_io_add_watch() here in case pygtk fixes this
- # bug.
- def input_add(self, source, condition, callback):
- if hasattr(source, 'fileno'):
- # handle python objects
- def wrapper(ignored, condition):
- return callback(source, condition)
- fileno = source.fileno()
- else:
- fileno = source
- wrapper = callback
- return self._glib.io_add_watch(
- fileno, condition, wrapper,
- priority=self._glib.PRIORITY_DEFAULT_IDLE)
-
-
- def _ioEventCallback(self, source, condition):
- """
- Called by event loop when an I/O event occurs.
- """
- log.callWithLogger(
- source, self._doReadOrWrite, source, source, condition)
- return True # True = don't auto-remove the source
-
-
- def _add(self, source, primary, other, primaryFlag, otherFlag):
- """
- Add the given L{FileDescriptor} for monitoring either for reading or
- writing. If the file is already monitored for the other operation, we
- delete the previous registration and re-register it for both reading
- and writing.
- """
- if source in primary:
- return
- flags = primaryFlag
- if source in other:
- self._source_remove(self._sources[source])
- flags |= otherFlag
- self._sources[source] = self.input_add(
- source, flags, self._ioEventCallback)
- primary.add(source)
-
-
- def addReader(self, reader):
- """
- Add a L{FileDescriptor} for monitoring of data available to read.
- """
- self._add(reader, self._reads, self._writes,
- self.INFLAGS, self.OUTFLAGS)
-
-
- def addWriter(self, writer):
- """
- Add a L{FileDescriptor} for monitoring ability to write data.
- """
- self._add(writer, self._writes, self._reads,
- self.OUTFLAGS, self.INFLAGS)
-
-
- def getReaders(self):
- """
- Retrieve the list of current L{FileDescriptor} monitored for reading.
- """
- return list(self._reads)
-
-
- def getWriters(self):
- """
- Retrieve the list of current L{FileDescriptor} monitored for writing.
- """
- return list(self._writes)
-
-
- def removeAll(self):
- """
- Remove monitoring for all registered L{FileDescriptor}s.
- """
- return self._removeAll(self._reads, self._writes)
-
-
- def _remove(self, source, primary, other, flags):
- """
- Remove monitoring the given L{FileDescriptor} for either reading or
- writing. If it's still monitored for the other operation, we
- re-register the L{FileDescriptor} for only that operation.
- """
- if source not in primary:
- return
- self._source_remove(self._sources[source])
- primary.remove(source)
- if source in other:
- self._sources[source] = self.input_add(
- source, flags, self._ioEventCallback)
- else:
- self._sources.pop(source)
-
-
- def removeReader(self, reader):
- """
- Stop monitoring the given L{FileDescriptor} for reading.
- """
- self._remove(reader, self._reads, self._writes, self.OUTFLAGS)
-
-
- def removeWriter(self, writer):
- """
- Stop monitoring the given L{FileDescriptor} for writing.
- """
- self._remove(writer, self._writes, self._reads, self.INFLAGS)
-
-
- def iterate(self, delay=0):
- """
- One iteration of the event loop, for trial's use.
-
- This is not used for actual reactor runs.
- """
- self.runUntilCurrent()
- while self._pending():
- self._iteration(0)
-
-
- def crash(self):
- """
- Crash the reactor.
- """
- posixbase.PosixReactorBase.crash(self)
- self._crash()
-
-
- def stop(self):
- """
- Stop the reactor.
- """
- posixbase.PosixReactorBase.stop(self)
- # The base implementation only sets a flag, to ensure shutting down is
- # not reentrant. Unfortunately, this flag is not meaningful to the
- # gobject event loop. We therefore call wakeUp() to ensure the event
- # loop will call back into Twisted once this iteration is done. This
- # will result in self.runUntilCurrent() being called, where the stop
- # flag will trigger the actual shutdown process, eventually calling
- # crash() which will do the actual gobject event loop shutdown.
- self.wakeUp()
-
-
- def run(self, installSignalHandlers=True):
- """
- Run the reactor.
- """
- self.callWhenRunning(self._reschedule)
- self.startRunning(installSignalHandlers=installSignalHandlers)
- if self._started:
- self._run()
-
-
- def callLater(self, *args, **kwargs):
- """
- Schedule a C{DelayedCall}.
- """
- result = posixbase.PosixReactorBase.callLater(self, *args, **kwargs)
- # Make sure we'll get woken up at correct time to handle this new
- # scheduled call:
- self._reschedule()
- return result
-
-
- def _reschedule(self):
- """
- Schedule a glib timeout for C{_simulate}.
- """
- if self._simtag is not None:
- self._source_remove(self._simtag)
- self._simtag = None
- timeout = self.timeout()
- if timeout is not None:
- self._simtag = self._timeout_add(
- int(timeout * 1000), self._simulate,
- priority=self._glib.PRIORITY_DEFAULT_IDLE)
-
-
- def _simulate(self):
- """
- Run timers, and then reschedule glib timeout for next scheduled event.
- """
- self.runUntilCurrent()
- self._reschedule()
-
-
-
-class PortableGlibReactorBase(selectreactor.SelectReactor):
- """
- Base class for GObject event loop reactors that works on Windows.
-
- Sockets aren't supported by GObject's input_add on Win32.
- """
- def __init__(self, glib_module, gtk_module, useGtk=False):
- self._simtag = None
- self._glib = glib_module
- self._gtk = gtk_module
- selectreactor.SelectReactor.__init__(self)
-
- self._source_remove = self._glib.source_remove
- self._timeout_add = self._glib.timeout_add
-
- def _mainquit():
- if self._gtk.main_level():
- self._gtk.main_quit()
-
- if useGtk:
- self._crash = _mainquit
- self._run = self._gtk.main
- else:
- self.loop = self._glib.MainLoop()
- self._crash = lambda: self._glib.idle_add(self.loop.quit)
- self._run = self.loop.run
-
-
- def crash(self):
- selectreactor.SelectReactor.crash(self)
- self._crash()
-
-
- def run(self, installSignalHandlers=True):
- self.startRunning(installSignalHandlers=installSignalHandlers)
- self._timeout_add(0, self.simulate)
- if self._started:
- self._run()
-
-
- def simulate(self):
- """
- Run simulation loops and reschedule callbacks.
- """
- if self._simtag is not None:
- self._source_remove(self._simtag)
- self.iterate()
- timeout = min(self.timeout(), 0.01)
- if timeout is None:
- timeout = 0.01
- self._simtag = self._timeout_add(
- int(timeout * 1000), self.simulate,
- priority=self._glib.PRIORITY_DEFAULT_IDLE)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_newtls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_newtls.py
deleted file mode 100755
index a8c34793..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_newtls.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# -*- test-case-name: twisted.test.test_ssl -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module implements memory BIO based TLS support. It is the preferred
-implementation and will be used whenever pyOpenSSL 0.10 or newer is installed
-(whenever L{twisted.protocols.tls} is importable).
-
-@since: 11.1
-"""
-
-from zope.interface import implements
-from zope.interface import directlyProvides
-
-from twisted.internet.interfaces import ITLSTransport, ISSLTransport
-from twisted.internet.abstract import FileDescriptor
-from twisted.internet._ssl import _TLSDelayed
-
-from twisted.protocols.tls import TLSMemoryBIOFactory, TLSMemoryBIOProtocol
-
-
-class _BypassTLS(object):
- """
- L{_BypassTLS} is used as the transport object for the TLS protocol object
- used to implement C{startTLS}. Its methods skip any TLS logic which
- C{startTLS} enables.
-
- @ivar _base: A transport class L{_BypassTLS} has been mixed in with to which
- methods will be forwarded. This class is only responsible for sending
- bytes over the connection, not doing TLS.
-
- @ivar _connection: A L{Connection} which TLS has been started on which will
- be proxied to by this object. Any method which has its behavior
- altered after C{startTLS} will be skipped in favor of the base class's
- implementation. This allows the TLS protocol object to have direct
- access to the transport, necessary to actually implement TLS.
- """
- def __init__(self, base, connection):
- self._base = base
- self._connection = connection
-
-
- def __getattr__(self, name):
- """
- Forward any extra attribute access to the original transport object.
- For example, this exposes C{getHost}, the behavior of which does not
- change after TLS is enabled.
- """
- return getattr(self._connection, name)
-
-
- def write(self, data):
- """
- Write some bytes directly to the connection.
- """
- return self._base.write(self._connection, data)
-
-
- def writeSequence(self, iovec):
- """
- Write a some bytes directly to the connection.
- """
- return self._base.writeSequence(self._connection, iovec)
-
-
- def loseConnection(self, *args, **kwargs):
- """
- Close the underlying connection.
- """
- return self._base.loseConnection(self._connection, *args, **kwargs)
-
-
- def registerProducer(self, producer, streaming):
- """
- Register a producer with the underlying connection.
- """
- return self._base.registerProducer(self._connection, producer, streaming)
-
-
- def unregisterProducer(self):
- """
- Unregister a producer with the underlying connection.
- """
- return self._base.unregisterProducer(self._connection)
-
-
-
-def startTLS(transport, contextFactory, normal, bypass):
- """
- Add a layer of SSL to a transport.
-
- @param transport: The transport which will be modified. This can either by
- a L{FileDescriptor<twisted.internet.abstract.FileDescriptor>} or a
- L{FileHandle<twisted.internet.iocpreactor.abstract.FileHandle>}. The
- actual requirements of this instance are that it have:
-
- - a C{_tlsClientDefault} attribute indicating whether the transport is
- a client (C{True}) or a server (C{False})
- - a settable C{TLS} attribute which can be used to mark the fact
- that SSL has been started
- - settable C{getHandle} and C{getPeerCertificate} attributes so
- these L{ISSLTransport} methods can be added to it
- - a C{protocol} attribute referring to the L{IProtocol} currently
- connected to the transport, which can also be set to a new
- L{IProtocol} for the transport to deliver data to
-
- @param contextFactory: An SSL context factory defining SSL parameters for
- the new SSL layer.
- @type contextFactory: L{twisted.internet.ssl.ContextFactory}
-
- @param normal: A flag indicating whether SSL will go in the same direction
- as the underlying transport goes. That is, if the SSL client will be
- the underlying client and the SSL server will be the underlying server.
- C{True} means it is the same, C{False} means they are switched.
- @type param: L{bool}
-
- @param bypass: A transport base class to call methods on to bypass the new
- SSL layer (so that the SSL layer itself can send its bytes).
- @type bypass: L{type}
- """
- # Figure out which direction the SSL goes in. If normal is True,
- # we'll go in the direction indicated by the subclass. Otherwise,
- # we'll go the other way (client = not normal ^ _tlsClientDefault,
- # in other words).
- if normal:
- client = transport._tlsClientDefault
- else:
- client = not transport._tlsClientDefault
-
- # If we have a producer, unregister it, and then re-register it below once
- # we've switched to TLS mode, so it gets hooked up correctly:
- producer, streaming = None, None
- if transport.producer is not None:
- producer, streaming = transport.producer, transport.streamingProducer
- transport.unregisterProducer()
-
- tlsFactory = TLSMemoryBIOFactory(contextFactory, client, None)
- tlsProtocol = TLSMemoryBIOProtocol(tlsFactory, transport.protocol, False)
- transport.protocol = tlsProtocol
-
- transport.getHandle = tlsProtocol.getHandle
- transport.getPeerCertificate = tlsProtocol.getPeerCertificate
-
- # Mark the transport as secure.
- directlyProvides(transport, ISSLTransport)
-
- # Remember we did this so that write and writeSequence can send the
- # data to the right place.
- transport.TLS = True
-
- # Hook it up
- transport.protocol.makeConnection(_BypassTLS(bypass, transport))
-
- # Restore producer if necessary:
- if producer:
- transport.registerProducer(producer, streaming)
-
-
-
-class ConnectionMixin(object):
- """
- A mixin for L{twisted.internet.abstract.FileDescriptor} which adds an
- L{ITLSTransport} implementation.
-
- @ivar TLS: A flag indicating whether TLS is currently in use on this
- transport. This is not a good way for applications to check for TLS,
- instead use L{ISSLTransport.providedBy}.
- """
- implements(ITLSTransport)
-
- TLS = False
-
- def startTLS(self, ctx, normal=True):
- """
- @see: L{ITLSTransport.startTLS}
- """
- startTLS(self, ctx, normal, FileDescriptor)
-
-
- def write(self, bytes):
- """
- Write some bytes to this connection, passing them through a TLS layer if
- necessary, or discarding them if the connection has already been lost.
- """
- if self.TLS:
- if self.connected:
- self.protocol.write(bytes)
- else:
- FileDescriptor.write(self, bytes)
-
-
- def writeSequence(self, iovec):
- """
- Write some bytes to this connection, scatter/gather-style, passing them
- through a TLS layer if necessary, or discarding them if the connection
- has already been lost.
- """
- if self.TLS:
- if self.connected:
- self.protocol.writeSequence(iovec)
- else:
- FileDescriptor.writeSequence(self, iovec)
-
-
- def loseConnection(self):
- """
- Close this connection after writing all pending data.
-
- If TLS has been negotiated, perform a TLS shutdown.
- """
- if self.TLS:
- if self.connected and not self.disconnecting:
- self.protocol.loseConnection()
- else:
- FileDescriptor.loseConnection(self)
-
-
- def registerProducer(self, producer, streaming):
- """
- Register a producer.
-
- If TLS is enabled, the TLS connection handles this.
- """
- if self.TLS:
- # Registering a producer before we're connected shouldn't be a
- # problem. If we end up with a write(), that's already handled in
- # the write() code above, and there are no other potential
- # side-effects.
- self.protocol.registerProducer(producer, streaming)
- else:
- FileDescriptor.registerProducer(self, producer, streaming)
-
-
- def unregisterProducer(self):
- """
- Unregister a producer.
-
- If TLS is enabled, the TLS connection handles this.
- """
- if self.TLS:
- self.protocol.unregisterProducer()
- else:
- FileDescriptor.unregisterProducer(self)
-
-
-
-class ClientMixin(object):
- """
- A mixin for L{twisted.internet.tcp.Client} which just marks it as a client
- for the purposes of the default TLS handshake.
-
- @ivar _tlsClientDefault: Always C{True}, indicating that this is a client
- connection, and by default when TLS is negotiated this class will act as
- a TLS client.
- """
- _tlsClientDefault = True
-
-
-
-class ServerMixin(object):
- """
- A mixin for L{twisted.internet.tcp.Server} which just marks it as a server
- for the purposes of the default TLS handshake.
-
- @ivar _tlsClientDefault: Always C{False}, indicating that this is a server
- connection, and by default when TLS is negotiated this class will act as
- a TLS server.
- """
- _tlsClientDefault = False
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_oldtls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_oldtls.py
deleted file mode 100755
index e0d2cadb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_oldtls.py
+++ /dev/null
@@ -1,381 +0,0 @@
-# -*- test-case-name: twisted.test.test_ssl -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module implements OpenSSL socket BIO based TLS support. It is only used if
-memory BIO APIs are not available, which is when the version of pyOpenSSL
-installed is older than 0.10 (when L{twisted.protocols.tls} is not importable).
-This implementation is undesirable because of the complexity of working with
-OpenSSL's non-blocking socket-based APIs (which this module probably does about
-99% correctly, but see #4455 for an example of a problem with it).
-
-Support for older versions of pyOpenSSL is now deprecated and will be removed
-(see #5014).
-
-@see: L{twisted.internet._newtls}
-@since: 11.1
-"""
-
-import os, warnings
-
-from twisted.python.runtime import platformType
-if platformType == 'win32':
- from errno import WSAEINTR as EINTR
- from errno import WSAEWOULDBLOCK as EWOULDBLOCK
- from errno import WSAENOBUFS as ENOBUFS
-else:
- from errno import EINTR
- from errno import EWOULDBLOCK
- from errno import ENOBUFS
-
-from OpenSSL import SSL, __version__ as _sslversion
-
-from zope.interface import implements
-
-from twisted.python import log
-from twisted.internet.interfaces import ITLSTransport, ISSLTransport
-from twisted.internet.abstract import FileDescriptor
-from twisted.internet.main import CONNECTION_DONE, CONNECTION_LOST
-from twisted.internet._ssl import _TLSDelayed
-
-warnings.warn(
- "Support for pyOpenSSL %s is deprecated. "
- "Upgrade to pyOpenSSL 0.10 or newer." % (_sslversion,),
- category=DeprecationWarning,
- stacklevel=100)
-
-class _TLSMixin:
- _socketShutdownMethod = 'sock_shutdown'
-
- writeBlockedOnRead = 0
- readBlockedOnWrite = 0
- _userWantRead = _userWantWrite = True
-
- def getPeerCertificate(self):
- return self.socket.get_peer_certificate()
-
- def doRead(self):
- if self.disconnected:
- # See the comment in the similar check in doWrite below.
- # Additionally, in order for anything other than returning
- # CONNECTION_DONE here to make sense, it will probably be necessary
- # to implement a way to switch back to TCP from TLS (actually, if
- # we did something other than return CONNECTION_DONE, that would be
- # a big part of implementing that feature). In other words, the
- # expectation is that doRead will be called when self.disconnected
- # is True only when the connection has been lost. It's possible
- # that the other end could stop speaking TLS and then send us some
- # non-TLS data. We'll end up ignoring that data and dropping the
- # connection. There's no unit tests for this check in the cases
- # where it makes a difference. The test suite only hits this
- # codepath when it would have otherwise hit the SSL.ZeroReturnError
- # exception handler below, which has exactly the same behavior as
- # this conditional. Maybe that's the only case that can ever be
- # triggered, I'm not sure. -exarkun
- return CONNECTION_DONE
- if self.writeBlockedOnRead:
- self.writeBlockedOnRead = 0
- self._resetReadWrite()
- try:
- return self._base.doRead(self)
- except SSL.ZeroReturnError:
- return CONNECTION_DONE
- except SSL.WantReadError:
- return
- except SSL.WantWriteError:
- self.readBlockedOnWrite = 1
- self._base.startWriting(self)
- self._base.stopReading(self)
- return
- except SSL.SysCallError, (retval, desc):
- if ((retval == -1 and desc == 'Unexpected EOF')
- or retval > 0):
- return CONNECTION_LOST
- log.err()
- return CONNECTION_LOST
- except SSL.Error, e:
- return e
-
- def doWrite(self):
- # Retry disconnecting
- if self.disconnected:
- # This case is triggered when "disconnected" is set to True by a
- # call to _postLoseConnection from FileDescriptor.doWrite (to which
- # we upcall at the end of this overridden version of that API). It
- # means that while, as far as any protocol connected to this
- # transport is concerned, the connection no longer exists, the
- # connection *does* actually still exist. Instead of closing the
- # connection in the overridden _postLoseConnection, we probably
- # tried (and failed) to send a TLS close alert. The TCP connection
- # is still up and we're waiting for the socket to become writeable
- # enough for the TLS close alert to actually be sendable. Only
- # then will the connection actually be torn down. -exarkun
- return self._postLoseConnection()
- if self._writeDisconnected:
- return self._closeWriteConnection()
-
- if self.readBlockedOnWrite:
- self.readBlockedOnWrite = 0
- self._resetReadWrite()
- return self._base.doWrite(self)
-
- def writeSomeData(self, data):
- try:
- return self._base.writeSomeData(self, data)
- except SSL.WantWriteError:
- return 0
- except SSL.WantReadError:
- self.writeBlockedOnRead = 1
- self._base.stopWriting(self)
- self._base.startReading(self)
- return 0
- except SSL.ZeroReturnError:
- return CONNECTION_LOST
- except SSL.SysCallError, e:
- if e[0] == -1 and data == "":
- # errors when writing empty strings are expected
- # and can be ignored
- return 0
- else:
- return CONNECTION_LOST
- except SSL.Error, e:
- return e
-
-
- def _postLoseConnection(self):
- """
- Gets called after loseConnection(), after buffered data is sent.
-
- We try to send an SSL shutdown alert, but if it doesn't work, retry
- when the socket is writable.
- """
- # Here, set "disconnected" to True to trick higher levels into thinking
- # the connection is really gone. It's not, and we're not going to
- # close it yet. Instead, we'll try to send a TLS close alert to shut
- # down the TLS connection cleanly. Only after we actually get the
- # close alert into the socket will we disconnect the underlying TCP
- # connection.
- self.disconnected = True
- if hasattr(self.socket, 'set_shutdown'):
- # If possible, mark the state of the TLS connection as having
- # already received a TLS close alert from the peer. Why do
- # this???
- self.socket.set_shutdown(SSL.RECEIVED_SHUTDOWN)
- return self._sendCloseAlert()
-
-
- def _sendCloseAlert(self):
- # Okay, *THIS* is a bit complicated.
-
- # Basically, the issue is, OpenSSL seems to not actually return
- # errors from SSL_shutdown. Therefore, the only way to
- # determine if the close notification has been sent is by
- # SSL_shutdown returning "done". However, it will not claim it's
- # done until it's both sent *and* received a shutdown notification.
-
- # I don't actually want to wait for a received shutdown
- # notification, though, so, I have to set RECEIVED_SHUTDOWN
- # before calling shutdown. Then, it'll return True once it's
- # *SENT* the shutdown.
-
- # However, RECEIVED_SHUTDOWN can't be left set, because then
- # reads will fail, breaking half close.
-
- # Also, since shutdown doesn't report errors, an empty write call is
- # done first, to try to detect if the connection has gone away.
- # (*NOT* an SSL_write call, because that fails once you've called
- # shutdown)
- try:
- os.write(self.socket.fileno(), '')
- except OSError, se:
- if se.args[0] in (EINTR, EWOULDBLOCK, ENOBUFS):
- return 0
- # Write error, socket gone
- return CONNECTION_LOST
-
- try:
- if hasattr(self.socket, 'set_shutdown'):
- laststate = self.socket.get_shutdown()
- self.socket.set_shutdown(laststate | SSL.RECEIVED_SHUTDOWN)
- done = self.socket.shutdown()
- if not (laststate & SSL.RECEIVED_SHUTDOWN):
- self.socket.set_shutdown(SSL.SENT_SHUTDOWN)
- else:
- #warnings.warn("SSL connection shutdown possibly unreliable, "
- # "please upgrade to ver 0.XX", category=UserWarning)
- self.socket.shutdown()
- done = True
- except SSL.Error, e:
- return e
-
- if done:
- self.stopWriting()
- # Note that this is tested for by identity below.
- return CONNECTION_DONE
- else:
- # For some reason, the close alert wasn't sent. Start writing
- # again so that we'll get another chance to send it.
- self.startWriting()
- # On Linux, select will sometimes not report a closed file
- # descriptor in the write set (in particular, it seems that if a
- # send() fails with EPIPE, the socket will not appear in the write
- # set). The shutdown call above (which calls down to SSL_shutdown)
- # may have swallowed a write error. Therefore, also start reading
- # so that if the socket is closed we will notice. This doesn't
- # seem to be a problem for poll (because poll reports errors
- # separately) or with select on BSD (presumably because, unlike
- # Linux, it doesn't implement select in terms of poll and then map
- # POLLHUP to select's in fd_set).
- self.startReading()
- return None
-
- def _closeWriteConnection(self):
- result = self._sendCloseAlert()
-
- if result is CONNECTION_DONE:
- return self._base._closeWriteConnection(self)
-
- return result
-
- def startReading(self):
- self._userWantRead = True
- if not self.readBlockedOnWrite:
- return self._base.startReading(self)
-
-
- def stopReading(self):
- self._userWantRead = False
- # If we've disconnected, preventing stopReading() from happening
- # because we are blocked on a read is silly; the read will never
- # happen.
- if self.disconnected or not self.writeBlockedOnRead:
- return self._base.stopReading(self)
-
-
- def startWriting(self):
- self._userWantWrite = True
- if not self.writeBlockedOnRead:
- return self._base.startWriting(self)
-
-
- def stopWriting(self):
- self._userWantWrite = False
- # If we've disconnected, preventing stopWriting() from happening
- # because we are blocked on a write is silly; the write will never
- # happen.
- if self.disconnected or not self.readBlockedOnWrite:
- return self._base.stopWriting(self)
-
-
- def _resetReadWrite(self):
- # After changing readBlockedOnWrite or writeBlockedOnRead,
- # call this to reset the state to what the user requested.
- if self._userWantWrite:
- self.startWriting()
- else:
- self.stopWriting()
-
- if self._userWantRead:
- self.startReading()
- else:
- self.stopReading()
-
-
-
-def _getTLSClass(klass, _existing={}):
- if klass not in _existing:
- class TLSConnection(_TLSMixin, klass):
- implements(ISSLTransport)
- _base = klass
- _existing[klass] = TLSConnection
- return _existing[klass]
-
-
-class ConnectionMixin(object):
- """
- Mixin for L{twisted.internet.tcp.Connection} to help implement
- L{ITLSTransport} using pyOpenSSL to do crypto and I/O.
- """
- TLS = 0
-
- _tlsWaiting = None
- def startTLS(self, ctx, extra=True):
- assert not self.TLS
- if self.dataBuffer or self._tempDataBuffer:
- # pre-TLS bytes are still being written. Starting TLS now
- # will do the wrong thing. Instead, mark that we're trying
- # to go into the TLS state.
- self._tlsWaiting = _TLSDelayed([], ctx, extra)
- return False
-
- self.stopReading()
- self.stopWriting()
- self._startTLS()
- self.socket = SSL.Connection(ctx.getContext(), self.socket)
- self.fileno = self.socket.fileno
- self.startReading()
- return True
-
-
- def _startTLS(self):
- self.TLS = 1
- self.__class__ = _getTLSClass(self.__class__)
-
-
- def write(self, bytes):
- if self._tlsWaiting is not None:
- self._tlsWaiting.bufferedData.append(bytes)
- else:
- FileDescriptor.write(self, bytes)
-
-
- def writeSequence(self, iovec):
- if self._tlsWaiting is not None:
- self._tlsWaiting.bufferedData.extend(iovec)
- else:
- FileDescriptor.writeSequence(self, iovec)
-
-
- def doWrite(self):
- result = FileDescriptor.doWrite(self)
- if self._tlsWaiting is not None:
- if not self.dataBuffer and not self._tempDataBuffer:
- waiting = self._tlsWaiting
- self._tlsWaiting = None
- self.startTLS(waiting.context, waiting.extra)
- self.writeSequence(waiting.bufferedData)
- return result
-
-
-
-class ClientMixin(object):
- """
- Mixin for L{twisted.internet.tcp.Client} to implement the client part of
- L{ITLSTransport}.
- """
- implements(ITLSTransport)
-
- def startTLS(self, ctx, client=1):
- if self._base.startTLS(self, ctx, client):
- if client:
- self.socket.set_connect_state()
- else:
- self.socket.set_accept_state()
-
-
-
-class ServerMixin(object):
- """
- Mixin for L{twisted.internet.tcp.Client} to implement the server part of
- L{ITLSTransport}.
- """
- implements(ITLSTransport)
-
- def startTLS(self, ctx, server=1):
- if self._base.startTLS(self, ctx, server):
- if server:
- self.socket.set_accept_state()
- else:
- self.socket.set_connect_state()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_pollingfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_pollingfile.py
deleted file mode 100755
index 5d00ace2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_pollingfile.py
+++ /dev/null
@@ -1,300 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_pollingfile -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implements a simple polling interface for file descriptors that don't work with
-select() - this is pretty much only useful on Windows.
-"""
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IConsumer, IPushProducer
-
-
-MIN_TIMEOUT = 0.000000001
-MAX_TIMEOUT = 0.1
-
-
-
-class _PollableResource:
- active = True
-
- def activate(self):
- self.active = True
-
-
- def deactivate(self):
- self.active = False
-
-
-
-class _PollingTimer:
- # Everything is private here because it is really an implementation detail.
-
- def __init__(self, reactor):
- self.reactor = reactor
- self._resources = []
- self._pollTimer = None
- self._currentTimeout = MAX_TIMEOUT
- self._paused = False
-
- def _addPollableResource(self, res):
- self._resources.append(res)
- self._checkPollingState()
-
- def _checkPollingState(self):
- for resource in self._resources:
- if resource.active:
- self._startPolling()
- break
- else:
- self._stopPolling()
-
- def _startPolling(self):
- if self._pollTimer is None:
- self._pollTimer = self._reschedule()
-
- def _stopPolling(self):
- if self._pollTimer is not None:
- self._pollTimer.cancel()
- self._pollTimer = None
-
- def _pause(self):
- self._paused = True
-
- def _unpause(self):
- self._paused = False
- self._checkPollingState()
-
- def _reschedule(self):
- if not self._paused:
- return self.reactor.callLater(self._currentTimeout, self._pollEvent)
-
- def _pollEvent(self):
- workUnits = 0.
- anyActive = []
- for resource in self._resources:
- if resource.active:
- workUnits += resource.checkWork()
- # Check AFTER work has been done
- if resource.active:
- anyActive.append(resource)
-
- newTimeout = self._currentTimeout
- if workUnits:
- newTimeout = self._currentTimeout / (workUnits + 1.)
- if newTimeout < MIN_TIMEOUT:
- newTimeout = MIN_TIMEOUT
- else:
- newTimeout = self._currentTimeout * 2.
- if newTimeout > MAX_TIMEOUT:
- newTimeout = MAX_TIMEOUT
- self._currentTimeout = newTimeout
- if anyActive:
- self._pollTimer = self._reschedule()
-
-
-# If we ever (let's hope not) need the above functionality on UNIX, this could
-# be factored into a different module.
-
-import win32pipe
-import win32file
-import win32api
-import pywintypes
-
-class _PollableReadPipe(_PollableResource):
-
- implements(IPushProducer)
-
- def __init__(self, pipe, receivedCallback, lostCallback):
- # security attributes for pipes
- self.pipe = pipe
- self.receivedCallback = receivedCallback
- self.lostCallback = lostCallback
-
- def checkWork(self):
- finished = 0
- fullDataRead = []
-
- while 1:
- try:
- buffer, bytesToRead, result = win32pipe.PeekNamedPipe(self.pipe, 1)
- # finished = (result == -1)
- if not bytesToRead:
- break
- hr, data = win32file.ReadFile(self.pipe, bytesToRead, None)
- fullDataRead.append(data)
- except win32api.error:
- finished = 1
- break
-
- dataBuf = ''.join(fullDataRead)
- if dataBuf:
- self.receivedCallback(dataBuf)
- if finished:
- self.cleanup()
- return len(dataBuf)
-
- def cleanup(self):
- self.deactivate()
- self.lostCallback()
-
- def close(self):
- try:
- win32api.CloseHandle(self.pipe)
- except pywintypes.error:
- # You can't close std handles...?
- pass
-
- def stopProducing(self):
- self.close()
-
- def pauseProducing(self):
- self.deactivate()
-
- def resumeProducing(self):
- self.activate()
-
-
-FULL_BUFFER_SIZE = 64 * 1024
-
-class _PollableWritePipe(_PollableResource):
-
- implements(IConsumer)
-
- def __init__(self, writePipe, lostCallback):
- self.disconnecting = False
- self.producer = None
- self.producerPaused = 0
- self.streamingProducer = 0
- self.outQueue = []
- self.writePipe = writePipe
- self.lostCallback = lostCallback
- try:
- win32pipe.SetNamedPipeHandleState(writePipe,
- win32pipe.PIPE_NOWAIT,
- None,
- None)
- except pywintypes.error:
- # Maybe it's an invalid handle. Who knows.
- pass
-
- def close(self):
- self.disconnecting = True
-
- def bufferFull(self):
- if self.producer is not None:
- self.producerPaused = 1
- self.producer.pauseProducing()
-
- def bufferEmpty(self):
- if self.producer is not None and ((not self.streamingProducer) or
- self.producerPaused):
- self.producer.producerPaused = 0
- self.producer.resumeProducing()
- return True
- return False
-
- # almost-but-not-quite-exact copy-paste from abstract.FileDescriptor... ugh
-
- def registerProducer(self, producer, streaming):
- """Register to receive data from a producer.
-
- This sets this selectable to be a consumer for a producer. When this
- selectable runs out of data on a write() call, it will ask the producer
- to resumeProducing(). A producer should implement the IProducer
- interface.
-
- FileDescriptor provides some infrastructure for producer methods.
- """
- if self.producer is not None:
- raise RuntimeError(
- "Cannot register producer %s, because producer %s was never "
- "unregistered." % (producer, self.producer))
- if not self.active:
- producer.stopProducing()
- else:
- self.producer = producer
- self.streamingProducer = streaming
- if not streaming:
- producer.resumeProducing()
-
- def unregisterProducer(self):
- """Stop consuming data from a producer, without disconnecting.
- """
- self.producer = None
-
- def writeConnectionLost(self):
- self.deactivate()
- try:
- win32api.CloseHandle(self.writePipe)
- except pywintypes.error:
- # OMG what
- pass
- self.lostCallback()
-
-
- def writeSequence(self, seq):
- """
- Append a C{list} or C{tuple} of bytes to the output buffer.
-
- @param seq: C{list} or C{tuple} of C{str} instances to be appended to
- the output buffer.
-
- @raise TypeError: If C{seq} contains C{unicode}.
- """
- if unicode in map(type, seq):
- raise TypeError("Unicode not allowed in output buffer.")
- self.outQueue.extend(seq)
-
-
- def write(self, data):
- """
- Append some bytes to the output buffer.
-
- @param data: C{str} to be appended to the output buffer.
- @type data: C{str}.
-
- @raise TypeError: If C{data} is C{unicode} instead of C{str}.
- """
- if isinstance(data, unicode):
- raise TypeError("Unicode not allowed in output buffer.")
- if self.disconnecting:
- return
- self.outQueue.append(data)
- if sum(map(len, self.outQueue)) > FULL_BUFFER_SIZE:
- self.bufferFull()
-
-
- def checkWork(self):
- numBytesWritten = 0
- if not self.outQueue:
- if self.disconnecting:
- self.writeConnectionLost()
- return 0
- try:
- win32file.WriteFile(self.writePipe, '', None)
- except pywintypes.error:
- self.writeConnectionLost()
- return numBytesWritten
- while self.outQueue:
- data = self.outQueue.pop(0)
- errCode = 0
- try:
- errCode, nBytesWritten = win32file.WriteFile(self.writePipe,
- data, None)
- except win32api.error:
- self.writeConnectionLost()
- break
- else:
- # assert not errCode, "wtf an error code???"
- numBytesWritten += nBytesWritten
- if len(data) > nBytesWritten:
- self.outQueue.insert(0, data[nBytesWritten:])
- break
- else:
- resumed = self.bufferEmpty()
- if not resumed and self.disconnecting:
- self.writeConnectionLost()
- return numBytesWritten
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixserialport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixserialport.py
deleted file mode 100755
index cc165a3f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixserialport.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Serial Port Protocol
-"""
-
-# system imports
-import os, errno
-
-# dependent on pyserial ( http://pyserial.sf.net/ )
-# only tested w/ 1.18 (5 Dec 2002)
-import serial
-from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD
-from serial import STOPBITS_ONE, STOPBITS_TWO
-from serial import FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS
-
-from serialport import BaseSerialPort
-
-# twisted imports
-from twisted.internet import abstract, fdesc, main
-
-class SerialPort(BaseSerialPort, abstract.FileDescriptor):
- """
- A select()able serial device, acting as a transport.
- """
-
- connected = 1
-
- def __init__(self, protocol, deviceNameOrPortNumber, reactor,
- baudrate = 9600, bytesize = EIGHTBITS, parity = PARITY_NONE,
- stopbits = STOPBITS_ONE, timeout = 0, xonxoff = 0, rtscts = 0):
- abstract.FileDescriptor.__init__(self, reactor)
- self._serial = self._serialFactory(
- deviceNameOrPortNumber, baudrate=baudrate, bytesize=bytesize,
- parity=parity, stopbits=stopbits, timeout=timeout,
- xonxoff=xonxoff, rtscts=rtscts)
- self.reactor = reactor
- self.flushInput()
- self.flushOutput()
- self.protocol = protocol
- self.protocol.makeConnection(self)
- self.startReading()
-
-
- def fileno(self):
- return self._serial.fd
-
-
- def writeSomeData(self, data):
- """
- Write some data to the serial device.
- """
- return fdesc.writeToFD(self.fileno(), data)
-
-
- def doRead(self):
- """
- Some data's readable from serial device.
- """
- return fdesc.readFromFD(self.fileno(), self.protocol.dataReceived)
-
-
- def connectionLost(self, reason):
- """
- Called when the serial port disconnects.
-
- Will call C{connectionLost} on the protocol that is handling the
- serial data.
- """
- abstract.FileDescriptor.connectionLost(self, reason)
- self._serial.close()
- self.protocol.connectionLost(reason)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixstdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixstdio.py
deleted file mode 100755
index 11b3205e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_posixstdio.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio -*-
-
-"""Standard input/out/err support.
-
-Future Plans::
-
- support for stderr, perhaps
- Rewrite to use the reactor instead of an ad-hoc mechanism for connecting
- protocols to transport.
-
-Maintainer: James Y Knight
-"""
-
-import warnings
-from zope.interface import implements
-
-from twisted.internet import process, error, interfaces
-from twisted.python import log, failure
-
-
-class PipeAddress(object):
- implements(interfaces.IAddress)
-
-
-class StandardIO(object):
- implements(interfaces.ITransport, interfaces.IProducer,
- interfaces.IConsumer, interfaces.IHalfCloseableDescriptor)
-
- _reader = None
- _writer = None
- disconnected = False
- disconnecting = False
-
- def __init__(self, proto, stdin=0, stdout=1, reactor=None):
- if reactor is None:
- from twisted.internet import reactor
- self.protocol = proto
-
- self._writer = process.ProcessWriter(reactor, self, 'write', stdout)
- self._reader = process.ProcessReader(reactor, self, 'read', stdin)
- self._reader.startReading()
- self.protocol.makeConnection(self)
-
- # ITransport
-
- # XXX Actually, see #3597.
- def loseWriteConnection(self):
- if self._writer is not None:
- self._writer.loseConnection()
-
- def write(self, data):
- if self._writer is not None:
- self._writer.write(data)
-
- def writeSequence(self, data):
- if self._writer is not None:
- self._writer.writeSequence(data)
-
- def loseConnection(self):
- self.disconnecting = True
-
- if self._writer is not None:
- self._writer.loseConnection()
- if self._reader is not None:
- # Don't loseConnection, because we don't want to SIGPIPE it.
- self._reader.stopReading()
-
- def getPeer(self):
- return PipeAddress()
-
- def getHost(self):
- return PipeAddress()
-
-
- # Callbacks from process.ProcessReader/ProcessWriter
- def childDataReceived(self, fd, data):
- self.protocol.dataReceived(data)
-
- def childConnectionLost(self, fd, reason):
- if self.disconnected:
- return
-
- if reason.value.__class__ == error.ConnectionDone:
- # Normal close
- if fd == 'read':
- self._readConnectionLost(reason)
- else:
- self._writeConnectionLost(reason)
- else:
- self.connectionLost(reason)
-
- def connectionLost(self, reason):
- self.disconnected = True
-
- # Make sure to cleanup the other half
- _reader = self._reader
- _writer = self._writer
- protocol = self.protocol
- self._reader = self._writer = None
- self.protocol = None
-
- if _writer is not None and not _writer.disconnected:
- _writer.connectionLost(reason)
-
- if _reader is not None and not _reader.disconnected:
- _reader.connectionLost(reason)
-
- try:
- protocol.connectionLost(reason)
- except:
- log.err()
-
- def _writeConnectionLost(self, reason):
- self._writer=None
- if self.disconnecting:
- self.connectionLost(reason)
- return
-
- p = interfaces.IHalfCloseableProtocol(self.protocol, None)
- if p:
- try:
- p.writeConnectionLost()
- except:
- log.err()
- self.connectionLost(failure.Failure())
-
- def _readConnectionLost(self, reason):
- self._reader=None
- p = interfaces.IHalfCloseableProtocol(self.protocol, None)
- if p:
- try:
- p.readConnectionLost()
- except:
- log.err()
- self.connectionLost(failure.Failure())
- else:
- self.connectionLost(reason)
-
- # IConsumer
- def registerProducer(self, producer, streaming):
- if self._writer is None:
- producer.stopProducing()
- else:
- self._writer.registerProducer(producer, streaming)
-
- def unregisterProducer(self):
- if self._writer is not None:
- self._writer.unregisterProducer()
-
- # IProducer
- def stopProducing(self):
- self.loseConnection()
-
- def pauseProducing(self):
- if self._reader is not None:
- self._reader.pauseProducing()
-
- def resumeProducing(self):
- if self._reader is not None:
- self._reader.resumeProducing()
-
- # Stupid compatibility:
- def closeStdin(self):
- """Compatibility only, don't use. Same as loseWriteConnection."""
- warnings.warn("This function is deprecated, use loseWriteConnection instead.",
- category=DeprecationWarning, stacklevel=2)
- self.loseWriteConnection()
-
- def stopReading(self):
- """Compatibility only, don't use. Call pauseProducing."""
- self.pauseProducing()
-
- def startReading(self):
- """Compatibility only, don't use. Call resumeProducing."""
- self.resumeProducing()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.c
deleted file mode 100644
index f6880dac..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2010 Twisted Matrix Laboratories.
- * See LICENSE for details.
- */
-
-#include <signal.h>
-#include <errno.h>
-
-#include "Python.h"
-
-static int sigchld_pipe_fd = -1;
-
-static void got_signal(int sig) {
- int saved_errno = errno;
- ssize_t ignored_result;
-
- /* write() errors are unhandled. If the buffer is full, we don't
- * care. What about other errors? */
- ignored_result = write(sigchld_pipe_fd, "x", 1);
-
- errno = saved_errno;
-}
-
-PyDoc_STRVAR(install_sigchld_handler_doc, "\
-install_sigchld_handler(fd)\n\
-\n\
-Installs a SIGCHLD handler which will write a byte to the given fd\n\
-whenever a SIGCHLD occurs. This is done in C code because the python\n\
-signal handling system is not reliable, and additionally cannot\n\
-specify SA_RESTART.\n\
-\n\
-Please ensure fd is in non-blocking mode.\n\
-");
-
-static PyObject *
-install_sigchld_handler(PyObject *self, PyObject *args) {
- int fd, old_fd;
- struct sigaction sa;
-
- if (!PyArg_ParseTuple(args, "i:install_sigchld_handler", &fd)) {
- return NULL;
- }
- old_fd = sigchld_pipe_fd;
- sigchld_pipe_fd = fd;
-
- if (fd == -1) {
- sa.sa_handler = SIG_DFL;
- } else {
- sa.sa_handler = got_signal;
- sa.sa_flags = SA_RESTART;
- /* mask all signals so I don't worry about EINTR from the write. */
- sigfillset(&sa.sa_mask);
- }
- if (sigaction(SIGCHLD, &sa, 0) != 0) {
- sigchld_pipe_fd = old_fd;
- return PyErr_SetFromErrno(PyExc_OSError);
- }
- return PyLong_FromLong(old_fd);
-}
-
-PyDoc_STRVAR(is_default_handler_doc, "\
-Return 1 if the SIGCHLD handler is SIG_DFL, 0 otherwise.\n\
-");
-
-static PyObject *
-is_default_handler(PyObject *self, PyObject *args) {
- /*
- * This implementation is necessary since the install_sigchld_handler
- * function above bypasses the Python signal handler installation API, so
- * CPython doesn't notice that the handler has changed and signal.getsignal
- * won't return an accurate result.
- */
- struct sigaction sa;
-
- if (sigaction(SIGCHLD, NULL, &sa) != 0) {
- return PyErr_SetFromErrno(PyExc_OSError);
- }
-
- return PyLong_FromLong(sa.sa_handler == SIG_DFL);
-}
-
-static PyMethodDef sigchld_methods[] = {
- {"installHandler", install_sigchld_handler, METH_VARARGS,
- install_sigchld_handler_doc},
- {"isDefaultHandler", is_default_handler, METH_NOARGS,
- is_default_handler_doc},
- /* sentinel */
- {NULL, NULL, 0, NULL}
-};
-
-
-static const char _sigchld_doc[] = "\n\
-This module contains an API for receiving SIGCHLD via a file descriptor.\n\
-";
-
-PyMODINIT_FUNC
-init_sigchld(void) {
- /* Create the module and add the functions */
- Py_InitModule3(
- "twisted.internet._sigchld", sigchld_methods, _sigchld_doc);
-}
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.py
deleted file mode 100755
index 85792f0d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'_sigchld.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.so b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.so
deleted file mode 100755
index 52efadcd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sigchld.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_signals.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_signals.py
deleted file mode 100755
index 4cc82b89..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_signals.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# -*- test-case-name: twisted.test.test_process,twisted.internet.test.test_process -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides a uniform interface to the several mechanisms which are
-possibly available for dealing with signals.
-
-This module is used to integrate child process termination into a
-reactor event loop. This is a challenging feature to provide because
-most platforms indicate process termination via SIGCHLD and do not
-provide a way to wait for that signal and arbitrary I/O events at the
-same time. The naive implementation involves installing a Python
-SIGCHLD handler; unfortunately this leads to other syscalls being
-interrupted (whenever SIGCHLD is received) and failing with EINTR
-(which almost no one is prepared to handle). This interruption can be
-disabled via siginterrupt(2) (or one of the equivalent mechanisms);
-however, if the SIGCHLD is delivered by the platform to a non-main
-thread (not a common occurrence, but difficult to prove impossible),
-the main thread (waiting on select() or another event notification
-API) may not wake up leading to an arbitrary delay before the child
-termination is noticed.
-
-The basic solution to all these issues involves enabling SA_RESTART
-(ie, disabling system call interruption) and registering a C signal
-handler which writes a byte to a pipe. The other end of the pipe is
-registered with the event loop, allowing it to wake up shortly after
-SIGCHLD is received. See L{twisted.internet.posixbase._SIGCHLDWaker}
-for the implementation of the event loop side of this solution. The
-use of a pipe this way is known as the U{self-pipe
-trick<http://cr.yp.to/docs/selfpipe.html>}.
-
-The actual solution implemented in this module depends on the version
-of Python. From version 2.6, C{signal.siginterrupt} and
-C{signal.set_wakeup_fd} allow the necessary C signal handler which
-writes to the pipe to be registered with C{SA_RESTART}. Prior to 2.6,
-the L{twisted.internet._sigchld} extension module provides similar
-functionality.
-
-If neither of these is available, a Python signal handler is used
-instead. This is essentially the naive solution mentioned above and
-has the problems described there.
-"""
-
-import os
-
-try:
- from signal import set_wakeup_fd, siginterrupt
-except ImportError:
- set_wakeup_fd = siginterrupt = None
-
-try:
- import signal
-except ImportError:
- signal = None
-
-from twisted.python.log import msg
-
-try:
- from twisted.internet._sigchld import installHandler as _extInstallHandler, \
- isDefaultHandler as _extIsDefaultHandler
-except ImportError:
- _extInstallHandler = _extIsDefaultHandler = None
-
-
-class _Handler(object):
- """
- L{_Handler} is a signal handler which writes a byte to a file descriptor
- whenever it is invoked.
-
- @ivar fd: The file descriptor to which to write. If this is C{None},
- nothing will be written.
- """
- def __init__(self, fd):
- self.fd = fd
-
-
- def __call__(self, *args):
- """
- L{_Handler.__call__} is the signal handler. It will write a byte to
- the wrapped file descriptor, if there is one.
- """
- if self.fd is not None:
- try:
- os.write(self.fd, '\0')
- except:
- pass
-
-
-
-def _installHandlerUsingSignal(fd):
- """
- Install a signal handler which will write a byte to C{fd} when
- I{SIGCHLD} is received.
-
- This is implemented by creating an instance of L{_Handler} with C{fd}
- and installing it as the signal handler.
-
- @param fd: The file descriptor to which to write when I{SIGCHLD} is
- received.
- @type fd: C{int}
- """
- if fd == -1:
- previous = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- else:
- previous = signal.signal(signal.SIGCHLD, _Handler(fd))
- if isinstance(previous, _Handler):
- return previous.fd
- return -1
-
-
-
-def _installHandlerUsingSetWakeup(fd):
- """
- Install a signal handler which will write a byte to C{fd} when
- I{SIGCHLD} is received.
-
- This is implemented by installing an instance of L{_Handler} wrapped
- around C{None}, setting the I{SIGCHLD} handler as not allowed to
- interrupt system calls, and using L{signal.set_wakeup_fd} to do the
- actual writing.
-
- @param fd: The file descriptor to which to write when I{SIGCHLD} is
- received.
- @type fd: C{int}
- """
- if fd == -1:
- signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- else:
- signal.signal(signal.SIGCHLD, _Handler(None))
- siginterrupt(signal.SIGCHLD, False)
- return set_wakeup_fd(fd)
-
-
-
-def _isDefaultHandler():
- """
- Determine whether the I{SIGCHLD} handler is the default or not.
- """
- return signal.getsignal(signal.SIGCHLD) == signal.SIG_DFL
-
-
-
-def _cannotInstallHandler(fd):
- """
- Fail to install a signal handler for I{SIGCHLD}.
-
- This implementation is used when the supporting code for the other
- implementations is unavailable (on Python versions 2.5 and older where
- neither the L{twisted.internet._sigchld} extension nor the standard
- L{signal} module is available).
-
- @param fd: Ignored; only for compatibility with the other
- implementations of this interface.
-
- @raise RuntimeError: Always raised to indicate no I{SIGCHLD} handler can
- be installed.
- """
- raise RuntimeError("Cannot install a SIGCHLD handler")
-
-
-
-def _cannotDetermineDefault():
- raise RuntimeError("No usable signal API available")
-
-
-
-if set_wakeup_fd is not None:
- msg('using set_wakeup_fd')
- installHandler = _installHandlerUsingSetWakeup
- isDefaultHandler = _isDefaultHandler
-elif _extInstallHandler is not None:
- msg('using _sigchld')
- installHandler = _extInstallHandler
- isDefaultHandler = _extIsDefaultHandler
-elif signal is not None:
- msg('using signal module')
- installHandler = _installHandlerUsingSignal
- isDefaultHandler = _isDefaultHandler
-else:
- msg('nothing unavailable')
- installHandler = _cannotInstallHandler
- isDefaultHandler = _cannotDetermineDefault
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_ssl.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_ssl.py
deleted file mode 100755
index 318ee357..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_ssl.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- test-case-name: twisted.test.test_ssl -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module implements helpers for switching to TLS on an existing transport.
-
-@since: 11.1
-"""
-
-class _TLSDelayed(object):
- """
- State tracking record for TLS startup parameters. Used to remember how
- TLS should be started when starting it is delayed to wait for the output
- buffer to be flushed.
-
- @ivar bufferedData: A C{list} which contains all the data which was
- written to the transport after an attempt to start TLS was made but
- before the buffers outstanding at that time could be flushed and TLS
- could really be started. This is appended to by the transport's
- write and writeSequence methods until it is possible to actually
- start TLS, then it is written to the TLS-enabled transport.
-
- @ivar context: An SSL context factory object to use to start TLS.
-
- @ivar extra: An extra argument to pass to the transport's C{startTLS}
- method.
- """
- def __init__(self, bufferedData, context, extra):
- self.bufferedData = bufferedData
- self.context = context
- self.extra = extra
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sslverify.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sslverify.py
deleted file mode 100755
index 59015439..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_sslverify.py
+++ /dev/null
@@ -1,749 +0,0 @@
-# -*- test-case-name: twisted.test.test_sslverify -*-
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-# Copyright (c) 2005-2008 Twisted Matrix Laboratories.
-
-import itertools
-from OpenSSL import SSL, crypto
-
-from twisted.python import reflect, util
-from twisted.python.hashlib import md5
-from twisted.internet.defer import Deferred
-from twisted.internet.error import VerifyError, CertificateError
-
-# Private - shared between all OpenSSLCertificateOptions, counts up to provide
-# a unique session id for each context
-_sessionCounter = itertools.count().next
-
-_x509names = {
- 'CN': 'commonName',
- 'commonName': 'commonName',
-
- 'O': 'organizationName',
- 'organizationName': 'organizationName',
-
- 'OU': 'organizationalUnitName',
- 'organizationalUnitName': 'organizationalUnitName',
-
- 'L': 'localityName',
- 'localityName': 'localityName',
-
- 'ST': 'stateOrProvinceName',
- 'stateOrProvinceName': 'stateOrProvinceName',
-
- 'C': 'countryName',
- 'countryName': 'countryName',
-
- 'emailAddress': 'emailAddress'}
-
-
-class DistinguishedName(dict):
- """
- Identify and describe an entity.
-
- Distinguished names are used to provide a minimal amount of identifying
- information about a certificate issuer or subject. They are commonly
- created with one or more of the following fields::
-
- commonName (CN)
- organizationName (O)
- organizationalUnitName (OU)
- localityName (L)
- stateOrProvinceName (ST)
- countryName (C)
- emailAddress
- """
- __slots__ = ()
-
- def __init__(self, **kw):
- for k, v in kw.iteritems():
- setattr(self, k, v)
-
-
- def _copyFrom(self, x509name):
- d = {}
- for name in _x509names:
- value = getattr(x509name, name, None)
- if value is not None:
- setattr(self, name, value)
-
-
- def _copyInto(self, x509name):
- for k, v in self.iteritems():
- setattr(x509name, k, v)
-
-
- def __repr__(self):
- return '<DN %s>' % (dict.__repr__(self)[1:-1])
-
-
- def __getattr__(self, attr):
- try:
- return self[_x509names[attr]]
- except KeyError:
- raise AttributeError(attr)
-
-
- def __setattr__(self, attr, value):
- assert type(attr) is str
- if not attr in _x509names:
- raise AttributeError("%s is not a valid OpenSSL X509 name field" % (attr,))
- realAttr = _x509names[attr]
- value = value.encode('ascii')
- assert type(value) is str
- self[realAttr] = value
-
-
- def inspect(self):
- """
- Return a multi-line, human-readable representation of this DN.
- """
- l = []
- lablen = 0
- def uniqueValues(mapping):
- return set(mapping.itervalues())
- for k in sorted(uniqueValues(_x509names)):
- label = util.nameToLabel(k)
- lablen = max(len(label), lablen)
- v = getattr(self, k, None)
- if v is not None:
- l.append((label, v))
- lablen += 2
- for n, (label, attr) in enumerate(l):
- l[n] = (label.rjust(lablen)+': '+ attr)
- return '\n'.join(l)
-
-DN = DistinguishedName
-
-
-class CertBase:
- def __init__(self, original):
- self.original = original
-
- def _copyName(self, suffix):
- dn = DistinguishedName()
- dn._copyFrom(getattr(self.original, 'get_'+suffix)())
- return dn
-
- def getSubject(self):
- """
- Retrieve the subject of this certificate.
-
- @rtype: L{DistinguishedName}
- @return: A copy of the subject of this certificate.
- """
- return self._copyName('subject')
-
-
-
-def _handleattrhelper(Class, transport, methodName):
- """
- (private) Helper for L{Certificate.peerFromTransport} and
- L{Certificate.hostFromTransport} which checks for incompatible handle types
- and null certificates and raises the appropriate exception or returns the
- appropriate certificate object.
- """
- method = getattr(transport.getHandle(),
- "get_%s_certificate" % (methodName,), None)
- if method is None:
- raise CertificateError(
- "non-TLS transport %r did not have %s certificate" % (transport, methodName))
- cert = method()
- if cert is None:
- raise CertificateError(
- "TLS transport %r did not have %s certificate" % (transport, methodName))
- return Class(cert)
-
-
-class Certificate(CertBase):
- """
- An x509 certificate.
- """
- def __repr__(self):
- return '<%s Subject=%s Issuer=%s>' % (self.__class__.__name__,
- self.getSubject().commonName,
- self.getIssuer().commonName)
-
- def __eq__(self, other):
- if isinstance(other, Certificate):
- return self.dump() == other.dump()
- return False
-
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-
- def load(Class, requestData, format=crypto.FILETYPE_ASN1, args=()):
- """
- Load a certificate from an ASN.1- or PEM-format string.
-
- @rtype: C{Class}
- """
- return Class(crypto.load_certificate(format, requestData), *args)
- load = classmethod(load)
- _load = load
-
-
- def dumpPEM(self):
- """
- Dump this certificate to a PEM-format data string.
-
- @rtype: C{str}
- """
- return self.dump(crypto.FILETYPE_PEM)
-
-
- def loadPEM(Class, data):
- """
- Load a certificate from a PEM-format data string.
-
- @rtype: C{Class}
- """
- return Class.load(data, crypto.FILETYPE_PEM)
- loadPEM = classmethod(loadPEM)
-
-
- def peerFromTransport(Class, transport):
- """
- Get the certificate for the remote end of the given transport.
-
- @type: L{ISystemHandle}
- @rtype: C{Class}
-
- @raise: L{CertificateError}, if the given transport does not have a peer
- certificate.
- """
- return _handleattrhelper(Class, transport, 'peer')
- peerFromTransport = classmethod(peerFromTransport)
-
-
- def hostFromTransport(Class, transport):
- """
- Get the certificate for the local end of the given transport.
-
- @param transport: an L{ISystemHandle} provider; the transport we will
-
- @rtype: C{Class}
-
- @raise: L{CertificateError}, if the given transport does not have a host
- certificate.
- """
- return _handleattrhelper(Class, transport, 'host')
- hostFromTransport = classmethod(hostFromTransport)
-
-
- def getPublicKey(self):
- """
- Get the public key for this certificate.
-
- @rtype: L{PublicKey}
- """
- return PublicKey(self.original.get_pubkey())
-
-
- def dump(self, format=crypto.FILETYPE_ASN1):
- return crypto.dump_certificate(format, self.original)
-
-
- def serialNumber(self):
- """
- Retrieve the serial number of this certificate.
-
- @rtype: C{int}
- """
- return self.original.get_serial_number()
-
-
- def digest(self, method='md5'):
- """
- Return a digest hash of this certificate using the specified hash
- algorithm.
-
- @param method: One of C{'md5'} or C{'sha'}.
- @rtype: C{str}
- """
- return self.original.digest(method)
-
-
- def _inspect(self):
- return '\n'.join(['Certificate For Subject:',
- self.getSubject().inspect(),
- '\nIssuer:',
- self.getIssuer().inspect(),
- '\nSerial Number: %d' % self.serialNumber(),
- 'Digest: %s' % self.digest()])
-
-
- def inspect(self):
- """
- Return a multi-line, human-readable representation of this
- Certificate, including information about the subject, issuer, and
- public key.
- """
- return '\n'.join((self._inspect(), self.getPublicKey().inspect()))
-
-
- def getIssuer(self):
- """
- Retrieve the issuer of this certificate.
-
- @rtype: L{DistinguishedName}
- @return: A copy of the issuer of this certificate.
- """
- return self._copyName('issuer')
-
-
- def options(self, *authorities):
- raise NotImplementedError('Possible, but doubtful we need this yet')
-
-
-
-class CertificateRequest(CertBase):
- """
- An x509 certificate request.
-
- Certificate requests are given to certificate authorities to be signed and
- returned resulting in an actual certificate.
- """
- def load(Class, requestData, requestFormat=crypto.FILETYPE_ASN1):
- req = crypto.load_certificate_request(requestFormat, requestData)
- dn = DistinguishedName()
- dn._copyFrom(req.get_subject())
- if not req.verify(req.get_pubkey()):
- raise VerifyError("Can't verify that request for %r is self-signed." % (dn,))
- return Class(req)
- load = classmethod(load)
-
-
- def dump(self, format=crypto.FILETYPE_ASN1):
- return crypto.dump_certificate_request(format, self.original)
-
-
-
-class PrivateCertificate(Certificate):
- """
- An x509 certificate and private key.
- """
- def __repr__(self):
- return Certificate.__repr__(self) + ' with ' + repr(self.privateKey)
-
-
- def _setPrivateKey(self, privateKey):
- if not privateKey.matches(self.getPublicKey()):
- raise VerifyError(
- "Certificate public and private keys do not match.")
- self.privateKey = privateKey
- return self
-
-
- def newCertificate(self, newCertData, format=crypto.FILETYPE_ASN1):
- """
- Create a new L{PrivateCertificate} from the given certificate data and
- this instance's private key.
- """
- return self.load(newCertData, self.privateKey, format)
-
-
- def load(Class, data, privateKey, format=crypto.FILETYPE_ASN1):
- return Class._load(data, format)._setPrivateKey(privateKey)
- load = classmethod(load)
-
-
- def inspect(self):
- return '\n'.join([Certificate._inspect(self),
- self.privateKey.inspect()])
-
-
- def dumpPEM(self):
- """
- Dump both public and private parts of a private certificate to
- PEM-format data.
- """
- return self.dump(crypto.FILETYPE_PEM) + self.privateKey.dump(crypto.FILETYPE_PEM)
-
-
- def loadPEM(Class, data):
- """
- Load both private and public parts of a private certificate from a
- chunk of PEM-format data.
- """
- return Class.load(data, KeyPair.load(data, crypto.FILETYPE_PEM),
- crypto.FILETYPE_PEM)
- loadPEM = classmethod(loadPEM)
-
-
- def fromCertificateAndKeyPair(Class, certificateInstance, privateKey):
- privcert = Class(certificateInstance.original)
- return privcert._setPrivateKey(privateKey)
- fromCertificateAndKeyPair = classmethod(fromCertificateAndKeyPair)
-
-
- def options(self, *authorities):
- options = dict(privateKey=self.privateKey.original,
- certificate=self.original)
- if authorities:
- options.update(dict(verify=True,
- requireCertificate=True,
- caCerts=[auth.original for auth in authorities]))
- return OpenSSLCertificateOptions(**options)
-
-
- def certificateRequest(self, format=crypto.FILETYPE_ASN1,
- digestAlgorithm='md5'):
- return self.privateKey.certificateRequest(
- self.getSubject(),
- format,
- digestAlgorithm)
-
-
- def signCertificateRequest(self,
- requestData,
- verifyDNCallback,
- serialNumber,
- requestFormat=crypto.FILETYPE_ASN1,
- certificateFormat=crypto.FILETYPE_ASN1):
- issuer = self.getSubject()
- return self.privateKey.signCertificateRequest(
- issuer,
- requestData,
- verifyDNCallback,
- serialNumber,
- requestFormat,
- certificateFormat)
-
-
- def signRequestObject(self, certificateRequest, serialNumber,
- secondsToExpiry=60 * 60 * 24 * 365, # One year
- digestAlgorithm='md5'):
- return self.privateKey.signRequestObject(self.getSubject(),
- certificateRequest,
- serialNumber,
- secondsToExpiry,
- digestAlgorithm)
-
-
-class PublicKey:
- def __init__(self, osslpkey):
- self.original = osslpkey
- req1 = crypto.X509Req()
- req1.set_pubkey(osslpkey)
- self._emptyReq = crypto.dump_certificate_request(crypto.FILETYPE_ASN1, req1)
-
-
- def matches(self, otherKey):
- return self._emptyReq == otherKey._emptyReq
-
-
- # XXX This could be a useful method, but sometimes it triggers a segfault,
- # so we'll steer clear for now.
-# def verifyCertificate(self, certificate):
-# """
-# returns None, or raises a VerifyError exception if the certificate
-# could not be verified.
-# """
-# if not certificate.original.verify(self.original):
-# raise VerifyError("We didn't sign that certificate.")
-
- def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, self.keyHash())
-
-
- def keyHash(self):
- """
- MD5 hex digest of signature on an empty certificate request with this
- key.
- """
- return md5(self._emptyReq).hexdigest()
-
-
- def inspect(self):
- return 'Public Key with Hash: %s' % (self.keyHash(),)
-
-
-
-class KeyPair(PublicKey):
-
- def load(Class, data, format=crypto.FILETYPE_ASN1):
- return Class(crypto.load_privatekey(format, data))
- load = classmethod(load)
-
-
- def dump(self, format=crypto.FILETYPE_ASN1):
- return crypto.dump_privatekey(format, self.original)
-
-
- def __getstate__(self):
- return self.dump()
-
-
- def __setstate__(self, state):
- self.__init__(crypto.load_privatekey(crypto.FILETYPE_ASN1, state))
-
-
- def inspect(self):
- t = self.original.type()
- if t == crypto.TYPE_RSA:
- ts = 'RSA'
- elif t == crypto.TYPE_DSA:
- ts = 'DSA'
- else:
- ts = '(Unknown Type!)'
- L = (self.original.bits(), ts, self.keyHash())
- return '%s-bit %s Key Pair with Hash: %s' % L
-
-
- def generate(Class, kind=crypto.TYPE_RSA, size=1024):
- pkey = crypto.PKey()
- pkey.generate_key(kind, size)
- return Class(pkey)
-
-
- def newCertificate(self, newCertData, format=crypto.FILETYPE_ASN1):
- return PrivateCertificate.load(newCertData, self, format)
- generate = classmethod(generate)
-
-
- def requestObject(self, distinguishedName, digestAlgorithm='md5'):
- req = crypto.X509Req()
- req.set_pubkey(self.original)
- distinguishedName._copyInto(req.get_subject())
- req.sign(self.original, digestAlgorithm)
- return CertificateRequest(req)
-
-
- def certificateRequest(self, distinguishedName,
- format=crypto.FILETYPE_ASN1,
- digestAlgorithm='md5'):
- """Create a certificate request signed with this key.
-
- @return: a string, formatted according to the 'format' argument.
- """
- return self.requestObject(distinguishedName, digestAlgorithm).dump(format)
-
-
- def signCertificateRequest(self,
- issuerDistinguishedName,
- requestData,
- verifyDNCallback,
- serialNumber,
- requestFormat=crypto.FILETYPE_ASN1,
- certificateFormat=crypto.FILETYPE_ASN1,
- secondsToExpiry=60 * 60 * 24 * 365, # One year
- digestAlgorithm='md5'):
- """
- Given a blob of certificate request data and a certificate authority's
- DistinguishedName, return a blob of signed certificate data.
-
- If verifyDNCallback returns a Deferred, I will return a Deferred which
- fires the data when that Deferred has completed.
- """
- hlreq = CertificateRequest.load(requestData, requestFormat)
-
- dn = hlreq.getSubject()
- vval = verifyDNCallback(dn)
-
- def verified(value):
- if not value:
- raise VerifyError("DN callback %r rejected request DN %r" % (verifyDNCallback, dn))
- return self.signRequestObject(issuerDistinguishedName, hlreq,
- serialNumber, secondsToExpiry, digestAlgorithm).dump(certificateFormat)
-
- if isinstance(vval, Deferred):
- return vval.addCallback(verified)
- else:
- return verified(vval)
-
-
- def signRequestObject(self,
- issuerDistinguishedName,
- requestObject,
- serialNumber,
- secondsToExpiry=60 * 60 * 24 * 365, # One year
- digestAlgorithm='md5'):
- """
- Sign a CertificateRequest instance, returning a Certificate instance.
- """
- req = requestObject.original
- dn = requestObject.getSubject()
- cert = crypto.X509()
- issuerDistinguishedName._copyInto(cert.get_issuer())
- cert.set_subject(req.get_subject())
- cert.set_pubkey(req.get_pubkey())
- cert.gmtime_adj_notBefore(0)
- cert.gmtime_adj_notAfter(secondsToExpiry)
- cert.set_serial_number(serialNumber)
- cert.sign(self.original, digestAlgorithm)
- return Certificate(cert)
-
-
- def selfSignedCert(self, serialNumber, **kw):
- dn = DN(**kw)
- return PrivateCertificate.fromCertificateAndKeyPair(
- self.signRequestObject(dn, self.requestObject(dn), serialNumber),
- self)
-
-
-
-class OpenSSLCertificateOptions(object):
- """
- A factory for SSL context objects for both SSL servers and clients.
- """
-
- _context = None
- # Older versions of PyOpenSSL didn't provide OP_ALL. Fudge it here, just in case.
- _OP_ALL = getattr(SSL, 'OP_ALL', 0x0000FFFF)
- # OP_NO_TICKET is not (yet) exposed by PyOpenSSL
- _OP_NO_TICKET = 0x00004000
-
- method = SSL.TLSv1_METHOD
-
- def __init__(self,
- privateKey=None,
- certificate=None,
- method=None,
- verify=False,
- caCerts=None,
- verifyDepth=9,
- requireCertificate=True,
- verifyOnce=True,
- enableSingleUseKeys=True,
- enableSessions=True,
- fixBrokenPeers=False,
- enableSessionTickets=False):
- """
- Create an OpenSSL context SSL connection context factory.
-
- @param privateKey: A PKey object holding the private key.
-
- @param certificate: An X509 object holding the certificate.
-
- @param method: The SSL protocol to use, one of SSLv23_METHOD,
- SSLv2_METHOD, SSLv3_METHOD, TLSv1_METHOD. Defaults to TLSv1_METHOD.
-
- @param verify: If True, verify certificates received from the peer and
- fail the handshake if verification fails. Otherwise, allow anonymous
- sessions and sessions with certificates which fail validation. By
- default this is False.
-
- @param caCerts: List of certificate authority certificate objects to
- use to verify the peer's certificate. Only used if verify is
- C{True}, and if verify is C{True}, this must be specified. Since
- verify is C{False} by default, this is C{None} by default.
-
- @type caCerts: C{list} of L{OpenSSL.crypto.X509}
-
- @param verifyDepth: Depth in certificate chain down to which to verify.
- If unspecified, use the underlying default (9).
-
- @param requireCertificate: If True, do not allow anonymous sessions.
-
- @param verifyOnce: If True, do not re-verify the certificate
- on session resumption.
-
- @param enableSingleUseKeys: If True, generate a new key whenever
- ephemeral DH parameters are used to prevent small subgroup attacks.
-
- @param enableSessions: If True, set a session ID on each context. This
- allows a shortened handshake to be used when a known client reconnects.
-
- @param fixBrokenPeers: If True, enable various non-spec protocol fixes
- for broken SSL implementations. This should be entirely safe,
- according to the OpenSSL documentation, but YMMV. This option is now
- off by default, because it causes problems with connections between
- peers using OpenSSL 0.9.8a.
-
- @param enableSessionTickets: If True, enable session ticket extension
- for session resumption per RFC 5077. Note there is no support for
- controlling session tickets. This option is off by default, as some
- server implementations don't correctly process incoming empty session
- ticket extensions in the hello.
- """
-
- assert (privateKey is None) == (certificate is None), "Specify neither or both of privateKey and certificate"
- self.privateKey = privateKey
- self.certificate = certificate
- if method is not None:
- self.method = method
-
- self.verify = verify
- assert ((verify and caCerts) or
- (not verify)), "Specify client CA certificate information if and only if enabling certificate verification"
-
- self.caCerts = caCerts
- self.verifyDepth = verifyDepth
- self.requireCertificate = requireCertificate
- self.verifyOnce = verifyOnce
- self.enableSingleUseKeys = enableSingleUseKeys
- self.enableSessions = enableSessions
- self.fixBrokenPeers = fixBrokenPeers
- self.enableSessionTickets = enableSessionTickets
-
-
- def __getstate__(self):
- d = self.__dict__.copy()
- try:
- del d['_context']
- except KeyError:
- pass
- return d
-
-
- def __setstate__(self, state):
- self.__dict__ = state
-
-
- def getContext(self):
- """Return a SSL.Context object.
- """
- if self._context is None:
- self._context = self._makeContext()
- return self._context
-
-
- def _makeContext(self):
- ctx = SSL.Context(self.method)
-
- if self.certificate is not None and self.privateKey is not None:
- ctx.use_certificate(self.certificate)
- ctx.use_privatekey(self.privateKey)
- # Sanity check
- ctx.check_privatekey()
-
- verifyFlags = SSL.VERIFY_NONE
- if self.verify:
- verifyFlags = SSL.VERIFY_PEER
- if self.requireCertificate:
- verifyFlags |= SSL.VERIFY_FAIL_IF_NO_PEER_CERT
- if self.verifyOnce:
- verifyFlags |= SSL.VERIFY_CLIENT_ONCE
- if self.caCerts:
- store = ctx.get_cert_store()
- for cert in self.caCerts:
- store.add_cert(cert)
-
- # It'd be nice if pyOpenSSL let us pass None here for this behavior (as
- # the underlying OpenSSL API call allows NULL to be passed). It
- # doesn't, so we'll supply a function which does the same thing.
- def _verifyCallback(conn, cert, errno, depth, preverify_ok):
- return preverify_ok
- ctx.set_verify(verifyFlags, _verifyCallback)
-
- if self.verifyDepth is not None:
- ctx.set_verify_depth(self.verifyDepth)
-
- if self.enableSingleUseKeys:
- ctx.set_options(SSL.OP_SINGLE_DH_USE)
-
- if self.fixBrokenPeers:
- ctx.set_options(self._OP_ALL)
-
- if self.enableSessions:
- sessionName = md5("%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest()
- ctx.set_session_id(sessionName)
-
- if not self.enableSessionTickets:
- ctx.set_options(self._OP_NO_TICKET)
-
- return ctx
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_threadedselect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_threadedselect.py
deleted file mode 100755
index 8a1b722b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_threadedselect.py
+++ /dev/null
@@ -1,361 +0,0 @@
-# -*- test-case-name: twisted.test.test_internet -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Threaded select reactor
-
-The threadedselectreactor is a specialized reactor for integrating with
-arbitrary foreign event loop, such as those you find in GUI toolkits.
-
-There are three things you'll need to do to use this reactor.
-
-Install the reactor at the beginning of your program, before importing
-the rest of Twisted::
-
- | from twisted.internet import _threadedselect
- | _threadedselect.install()
-
-Interleave this reactor with your foreign event loop, at some point after
-your event loop is initialized::
-
- | from twisted.internet import reactor
- | reactor.interleave(foreignEventLoopWakerFunction)
- | self.addSystemEventTrigger('after', 'shutdown', foreignEventLoopStop)
-
-Instead of shutting down the foreign event loop directly, shut down the
-reactor::
-
- | from twisted.internet import reactor
- | reactor.stop()
-
-In order for Twisted to do its work in the main thread (the thread that
-interleave is called from), a waker function is necessary. The waker function
-will be called from a "background" thread with one argument: func.
-The waker function's purpose is to call func() from the main thread.
-Many GUI toolkits ship with appropriate waker functions.
-Some examples of this are wxPython's wx.callAfter (may be wxCallAfter in
-older versions of wxPython) or PyObjC's PyObjCTools.AppHelper.callAfter.
-These would be used in place of "foreignEventLoopWakerFunction" in the above
-example.
-
-The other integration point at which the foreign event loop and this reactor
-must integrate is shutdown. In order to ensure clean shutdown of Twisted,
-you must allow for Twisted to come to a complete stop before quitting the
-application. Typically, you will do this by setting up an after shutdown
-trigger to stop your foreign event loop, and call reactor.stop() where you
-would normally have initiated the shutdown procedure for the foreign event
-loop. Shutdown functions that could be used in place of
-"foreignEventloopStop" would be the ExitMainLoop method of the wxApp instance
-with wxPython, or the PyObjCTools.AppHelper.stopEventLoop function.
-"""
-
-from threading import Thread
-from Queue import Queue, Empty
-from time import sleep
-import sys
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IReactorFDSet
-from twisted.internet import error
-from twisted.internet import posixbase
-from twisted.internet.posixbase import _NO_FILENO, _NO_FILEDESC
-from twisted.python import log, failure, threadable
-from twisted.persisted import styles
-from twisted.python.runtime import platformType
-
-import select
-from errno import EINTR, EBADF
-
-from twisted.internet.selectreactor import _select
-
-def dictRemove(dct, value):
- try:
- del dct[value]
- except KeyError:
- pass
-
-def raiseException(e):
- raise e
-
-class ThreadedSelectReactor(posixbase.PosixReactorBase):
- """A threaded select() based reactor - runs on all POSIX platforms and on
- Win32.
- """
- implements(IReactorFDSet)
-
- def __init__(self):
- threadable.init(1)
- self.reads = {}
- self.writes = {}
- self.toThreadQueue = Queue()
- self.toMainThread = Queue()
- self.workerThread = None
- self.mainWaker = None
- posixbase.PosixReactorBase.__init__(self)
- self.addSystemEventTrigger('after', 'shutdown', self._mainLoopShutdown)
-
- def wakeUp(self):
- # we want to wake up from any thread
- self.waker.wakeUp()
-
- def callLater(self, *args, **kw):
- tple = posixbase.PosixReactorBase.callLater(self, *args, **kw)
- self.wakeUp()
- return tple
-
- def _sendToMain(self, msg, *args):
- #print >>sys.stderr, 'sendToMain', msg, args
- self.toMainThread.put((msg, args))
- if self.mainWaker is not None:
- self.mainWaker()
-
- def _sendToThread(self, fn, *args):
- #print >>sys.stderr, 'sendToThread', fn, args
- self.toThreadQueue.put((fn, args))
-
- def _preenDescriptorsInThread(self):
- log.msg("Malformed file descriptor found. Preening lists.")
- readers = self.reads.keys()
- writers = self.writes.keys()
- self.reads.clear()
- self.writes.clear()
- for selDict, selList in ((self.reads, readers), (self.writes, writers)):
- for selectable in selList:
- try:
- select.select([selectable], [selectable], [selectable], 0)
- except:
- log.msg("bad descriptor %s" % selectable)
- else:
- selDict[selectable] = 1
-
- def _workerInThread(self):
- try:
- while 1:
- fn, args = self.toThreadQueue.get()
- #print >>sys.stderr, "worker got", fn, args
- fn(*args)
- except SystemExit:
- pass # exception indicates this thread should exit
- except:
- f = failure.Failure()
- self._sendToMain('Failure', f)
- #print >>sys.stderr, "worker finished"
-
- def _doSelectInThread(self, timeout):
- """Run one iteration of the I/O monitor loop.
-
- This will run all selectables who had input or output readiness
- waiting for them.
- """
- reads = self.reads
- writes = self.writes
- while 1:
- try:
- r, w, ignored = _select(reads.keys(),
- writes.keys(),
- [], timeout)
- break
- except ValueError, ve:
- # Possibly a file descriptor has gone negative?
- log.err()
- self._preenDescriptorsInThread()
- except TypeError, te:
- # Something *totally* invalid (object w/o fileno, non-integral
- # result) was passed
- log.err()
- self._preenDescriptorsInThread()
- except (select.error, IOError), se:
- # select(2) encountered an error
- if se.args[0] in (0, 2):
- # windows does this if it got an empty list
- if (not reads) and (not writes):
- return
- else:
- raise
- elif se.args[0] == EINTR:
- return
- elif se.args[0] == EBADF:
- self._preenDescriptorsInThread()
- else:
- # OK, I really don't know what's going on. Blow up.
- raise
- self._sendToMain('Notify', r, w)
-
- def _process_Notify(self, r, w):
- #print >>sys.stderr, "_process_Notify"
- reads = self.reads
- writes = self.writes
-
- _drdw = self._doReadOrWrite
- _logrun = log.callWithLogger
- for selectables, method, dct in ((r, "doRead", reads), (w, "doWrite", writes)):
- for selectable in selectables:
- # if this was disconnected in another thread, kill it.
- if selectable not in dct:
- continue
- # This for pausing input when we're not ready for more.
- _logrun(selectable, _drdw, selectable, method, dct)
- #print >>sys.stderr, "done _process_Notify"
-
- def _process_Failure(self, f):
- f.raiseException()
-
- _doIterationInThread = _doSelectInThread
-
- def ensureWorkerThread(self):
- if self.workerThread is None or not self.workerThread.isAlive():
- self.workerThread = Thread(target=self._workerInThread)
- self.workerThread.start()
-
- def doThreadIteration(self, timeout):
- self._sendToThread(self._doIterationInThread, timeout)
- self.ensureWorkerThread()
- #print >>sys.stderr, 'getting...'
- msg, args = self.toMainThread.get()
- #print >>sys.stderr, 'got', msg, args
- getattr(self, '_process_' + msg)(*args)
-
- doIteration = doThreadIteration
-
- def _interleave(self):
- while self.running:
- #print >>sys.stderr, "runUntilCurrent"
- self.runUntilCurrent()
- t2 = self.timeout()
- t = self.running and t2
- self._sendToThread(self._doIterationInThread, t)
- #print >>sys.stderr, "yielding"
- yield None
- #print >>sys.stderr, "fetching"
- msg, args = self.toMainThread.get_nowait()
- getattr(self, '_process_' + msg)(*args)
-
- def interleave(self, waker, *args, **kw):
- """
- interleave(waker) interleaves this reactor with the
- current application by moving the blocking parts of
- the reactor (select() in this case) to a separate
- thread. This is typically useful for integration with
- GUI applications which have their own event loop
- already running.
-
- See the module docstring for more information.
- """
- self.startRunning(*args, **kw)
- loop = self._interleave()
- def mainWaker(waker=waker, loop=loop):
- #print >>sys.stderr, "mainWaker()"
- waker(loop.next)
- self.mainWaker = mainWaker
- loop.next()
- self.ensureWorkerThread()
-
- def _mainLoopShutdown(self):
- self.mainWaker = None
- if self.workerThread is not None:
- #print >>sys.stderr, 'getting...'
- self._sendToThread(raiseException, SystemExit)
- self.wakeUp()
- try:
- while 1:
- msg, args = self.toMainThread.get_nowait()
- #print >>sys.stderr, "ignored:", (msg, args)
- except Empty:
- pass
- self.workerThread.join()
- self.workerThread = None
- try:
- while 1:
- fn, args = self.toThreadQueue.get_nowait()
- if fn is self._doIterationInThread:
- log.msg('Iteration is still in the thread queue!')
- elif fn is raiseException and args[0] is SystemExit:
- pass
- else:
- fn(*args)
- except Empty:
- pass
-
- def _doReadOrWrite(self, selectable, method, dict):
- try:
- why = getattr(selectable, method)()
- handfn = getattr(selectable, 'fileno', None)
- if not handfn:
- why = _NO_FILENO
- elif handfn() == -1:
- why = _NO_FILEDESC
- except:
- why = sys.exc_info()[1]
- log.err()
- if why:
- self._disconnectSelectable(selectable, why, method == "doRead")
-
- def addReader(self, reader):
- """Add a FileDescriptor for notification of data available to read.
- """
- self._sendToThread(self.reads.__setitem__, reader, 1)
- self.wakeUp()
-
- def addWriter(self, writer):
- """Add a FileDescriptor for notification of data available to write.
- """
- self._sendToThread(self.writes.__setitem__, writer, 1)
- self.wakeUp()
-
- def removeReader(self, reader):
- """Remove a Selectable for notification of data available to read.
- """
- self._sendToThread(dictRemove, self.reads, reader)
-
- def removeWriter(self, writer):
- """Remove a Selectable for notification of data available to write.
- """
- self._sendToThread(dictRemove, self.writes, writer)
-
- def removeAll(self):
- return self._removeAll(self.reads, self.writes)
-
-
- def getReaders(self):
- return self.reads.keys()
-
-
- def getWriters(self):
- return self.writes.keys()
-
-
- def stop(self):
- """
- Extend the base stop implementation to also wake up the select thread so
- that C{runUntilCurrent} notices the reactor should stop.
- """
- posixbase.PosixReactorBase.stop(self)
- self.wakeUp()
-
-
- def run(self, installSignalHandlers=1):
- self.startRunning(installSignalHandlers=installSignalHandlers)
- self.mainLoop()
-
- def mainLoop(self):
- q = Queue()
- self.interleave(q.put)
- while self.running:
- try:
- q.get()()
- except StopIteration:
- break
-
-
-
-def install():
- """Configure the twisted mainloop to be run using the select() reactor.
- """
- reactor = ThreadedSelectReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32serialport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32serialport.py
deleted file mode 100755
index 1a77236e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32serialport.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Serial port support for Windows.
-
-Requires PySerial and pywin32.
-"""
-
-# system imports
-import serial
-from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD
-from serial import STOPBITS_ONE, STOPBITS_TWO
-from serial import FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS
-import win32file, win32event
-
-# twisted imports
-from twisted.internet import abstract
-
-# sibling imports
-from serialport import BaseSerialPort
-
-
-class SerialPort(BaseSerialPort, abstract.FileDescriptor):
- """A serial device, acting as a transport, that uses a win32 event."""
-
- connected = 1
-
- def __init__(self, protocol, deviceNameOrPortNumber, reactor,
- baudrate = 9600, bytesize = EIGHTBITS, parity = PARITY_NONE,
- stopbits = STOPBITS_ONE, xonxoff = 0, rtscts = 0):
- self._serial = self._serialFactory(
- deviceNameOrPortNumber, baudrate=baudrate, bytesize=bytesize,
- parity=parity, stopbits=stopbits, timeout=None,
- xonxoff=xonxoff, rtscts=rtscts)
- self.flushInput()
- self.flushOutput()
- self.reactor = reactor
- self.protocol = protocol
- self.outQueue = []
- self.closed = 0
- self.closedNotifies = 0
- self.writeInProgress = 0
-
- self.protocol = protocol
- self._overlappedRead = win32file.OVERLAPPED()
- self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
- self._overlappedWrite = win32file.OVERLAPPED()
- self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
-
- self.reactor.addEvent(self._overlappedRead.hEvent, self, 'serialReadEvent')
- self.reactor.addEvent(self._overlappedWrite.hEvent, self, 'serialWriteEvent')
-
- self.protocol.makeConnection(self)
- self._finishPortSetup()
-
-
- def _finishPortSetup(self):
- """
- Finish setting up the serial port.
-
- This is a separate method to facilitate testing.
- """
- flags, comstat = win32file.ClearCommError(self._serial.hComPort)
- rc, self.read_buf = win32file.ReadFile(self._serial.hComPort,
- win32file.AllocateReadBuffer(1),
- self._overlappedRead)
-
-
- def serialReadEvent(self):
- #get that character we set up
- n = win32file.GetOverlappedResult(self._serial.hComPort, self._overlappedRead, 0)
- if n:
- first = str(self.read_buf[:n])
- #now we should get everything that is already in the buffer
- flags, comstat = win32file.ClearCommError(self._serial.hComPort)
- if comstat.cbInQue:
- win32event.ResetEvent(self._overlappedRead.hEvent)
- rc, buf = win32file.ReadFile(self._serial.hComPort,
- win32file.AllocateReadBuffer(comstat.cbInQue),
- self._overlappedRead)
- n = win32file.GetOverlappedResult(self._serial.hComPort, self._overlappedRead, 1)
- #handle all the received data:
- self.protocol.dataReceived(first + str(buf[:n]))
- else:
- #handle all the received data:
- self.protocol.dataReceived(first)
-
- #set up next one
- win32event.ResetEvent(self._overlappedRead.hEvent)
- rc, self.read_buf = win32file.ReadFile(self._serial.hComPort,
- win32file.AllocateReadBuffer(1),
- self._overlappedRead)
-
-
- def write(self, data):
- if data:
- if self.writeInProgress:
- self.outQueue.append(data)
- else:
- self.writeInProgress = 1
- win32file.WriteFile(self._serial.hComPort, data, self._overlappedWrite)
-
-
- def serialWriteEvent(self):
- try:
- dataToWrite = self.outQueue.pop(0)
- except IndexError:
- self.writeInProgress = 0
- return
- else:
- win32file.WriteFile(self._serial.hComPort, dataToWrite, self._overlappedWrite)
-
-
- def connectionLost(self, reason):
- """
- Called when the serial port disconnects.
-
- Will call C{connectionLost} on the protocol that is handling the
- serial data.
- """
- self.reactor.removeEvent(self._overlappedRead.hEvent)
- self.reactor.removeEvent(self._overlappedWrite.hEvent)
- abstract.FileDescriptor.connectionLost(self, reason)
- self._serial.close()
- self.protocol.connectionLost(reason)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32stdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32stdio.py
deleted file mode 100755
index c4c56440..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/_win32stdio.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio -*-
-
-"""
-Windows-specific implementation of the L{twisted.internet.stdio} interface.
-"""
-
-import win32api
-import os, msvcrt
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IHalfCloseableProtocol, ITransport, IAddress
-from twisted.internet.interfaces import IConsumer, IPushProducer
-
-from twisted.internet import _pollingfile, main
-from twisted.python.failure import Failure
-
-
-class Win32PipeAddress(object):
- implements(IAddress)
-
-
-
-class StandardIO(_pollingfile._PollingTimer):
-
- implements(ITransport,
- IConsumer,
- IPushProducer)
-
- disconnecting = False
- disconnected = False
-
- def __init__(self, proto):
- """
- Start talking to standard IO with the given protocol.
-
- Also, put it stdin/stdout/stderr into binary mode.
- """
- from twisted.internet import reactor
-
- for stdfd in range(0, 1, 2):
- msvcrt.setmode(stdfd, os.O_BINARY)
-
- _pollingfile._PollingTimer.__init__(self, reactor)
- self.proto = proto
-
- hstdin = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)
- hstdout = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE)
-
- self.stdin = _pollingfile._PollableReadPipe(
- hstdin, self.dataReceived, self.readConnectionLost)
-
- self.stdout = _pollingfile._PollableWritePipe(
- hstdout, self.writeConnectionLost)
-
- self._addPollableResource(self.stdin)
- self._addPollableResource(self.stdout)
-
- self.proto.makeConnection(self)
-
- def dataReceived(self, data):
- self.proto.dataReceived(data)
-
- def readConnectionLost(self):
- if IHalfCloseableProtocol.providedBy(self.proto):
- self.proto.readConnectionLost()
- self.checkConnLost()
-
- def writeConnectionLost(self):
- if IHalfCloseableProtocol.providedBy(self.proto):
- self.proto.writeConnectionLost()
- self.checkConnLost()
-
- connsLost = 0
-
- def checkConnLost(self):
- self.connsLost += 1
- if self.connsLost >= 2:
- self.disconnecting = True
- self.disconnected = True
- self.proto.connectionLost(Failure(main.CONNECTION_DONE))
-
- # ITransport
-
- def write(self, data):
- self.stdout.write(data)
-
- def writeSequence(self, seq):
- self.stdout.write(''.join(seq))
-
- def loseConnection(self):
- self.disconnecting = True
- self.stdin.close()
- self.stdout.close()
-
- def getPeer(self):
- return Win32PipeAddress()
-
- def getHost(self):
- return Win32PipeAddress()
-
- # IConsumer
-
- def registerProducer(self, producer, streaming):
- return self.stdout.registerProducer(producer, streaming)
-
- def unregisterProducer(self):
- return self.stdout.unregisterProducer()
-
- # def write() above
-
- # IProducer
-
- def stopProducing(self):
- self.stdin.stopProducing()
-
- # IPushProducer
-
- def pauseProducing(self):
- self.stdin.pauseProducing()
-
- def resumeProducing(self):
- self.stdin.resumeProducing()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/abstract.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/abstract.py
deleted file mode 100755
index 08dd4d5d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/abstract.py
+++ /dev/null
@@ -1,517 +0,0 @@
-# -*- test-case-name: twisted.test.test_abstract -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Support for generic select()able objects.
-"""
-
-from socket import AF_INET6, inet_pton, error
-
-from zope.interface import implements
-
-# Twisted Imports
-from twisted.python import reflect, failure
-from twisted.internet import interfaces, main
-
-
-class _ConsumerMixin(object):
- """
- L{IConsumer} implementations can mix this in to get C{registerProducer} and
- C{unregisterProducer} methods which take care of keeping track of a
- producer's state.
-
- Subclasses must provide three attributes which L{_ConsumerMixin} will read
- but not write:
-
- - connected: A C{bool} which is C{True} as long as the the consumer has
- someplace to send bytes (for example, a TCP connection), and then
- C{False} when it no longer does.
-
- - disconnecting: A C{bool} which is C{False} until something like
- L{ITransport.loseConnection} is called, indicating that the send buffer
- should be flushed and the connection lost afterwards. Afterwards,
- C{True}.
-
- - disconnected: A C{bool} which is C{False} until the consumer no longer
- has a place to send bytes, then C{True}.
-
- Subclasses must also override the C{startWriting} method.
-
- @ivar producer: C{None} if no producer is registered, otherwise the
- registered producer.
-
- @ivar producerPaused: A flag indicating whether the producer is currently
- paused.
- @type producerPaused: C{bool} or C{int}
-
- @ivar streamingProducer: A flag indicating whether the producer was
- registered as a streaming (ie push) producer or not (ie a pull
- producer). This will determine whether the consumer may ever need to
- pause and resume it, or if it can merely call C{resumeProducing} on it
- when buffer space is available.
- @ivar streamingProducer: C{bool} or C{int}
-
- """
- producer = None
- producerPaused = False
- streamingProducer = False
-
- def startWriting(self):
- """
- Override in a subclass to cause the reactor to monitor this selectable
- for write events. This will be called once in C{unregisterProducer} if
- C{loseConnection} has previously been called, so that the connection can
- actually close.
- """
- raise NotImplementedError("%r did not implement startWriting")
-
-
- def registerProducer(self, producer, streaming):
- """
- Register to receive data from a producer.
-
- This sets this selectable to be a consumer for a producer. When this
- selectable runs out of data on a write() call, it will ask the producer
- to resumeProducing(). When the FileDescriptor's internal data buffer is
- filled, it will ask the producer to pauseProducing(). If the connection
- is lost, FileDescriptor calls producer's stopProducing() method.
-
- If streaming is true, the producer should provide the IPushProducer
- interface. Otherwise, it is assumed that producer provides the
- IPullProducer interface. In this case, the producer won't be asked to
- pauseProducing(), but it has to be careful to write() data only when its
- resumeProducing() method is called.
- """
- if self.producer is not None:
- raise RuntimeError(
- "Cannot register producer %s, because producer %s was never "
- "unregistered." % (producer, self.producer))
- if self.disconnected:
- producer.stopProducing()
- else:
- self.producer = producer
- self.streamingProducer = streaming
- if not streaming:
- producer.resumeProducing()
-
-
- def unregisterProducer(self):
- """
- Stop consuming data from a producer, without disconnecting.
- """
- self.producer = None
- if self.connected and self.disconnecting:
- self.startWriting()
-
-
-
-class _LogOwner(object):
- """
- Mixin to help implement L{interfaces.ILoggingContext} for transports which
- have a protocol, the log prefix of which should also appear in the
- transport's log prefix.
- """
- implements(interfaces.ILoggingContext)
-
- def _getLogPrefix(self, applicationObject):
- """
- Determine the log prefix to use for messages related to
- C{applicationObject}, which may or may not be an
- L{interfaces.ILoggingContext} provider.
-
- @return: A C{str} giving the log prefix to use.
- """
- if interfaces.ILoggingContext.providedBy(applicationObject):
- return applicationObject.logPrefix()
- return applicationObject.__class__.__name__
-
-
- def logPrefix(self):
- """
- Override this method to insert custom logging behavior. Its
- return value will be inserted in front of every line. It may
- be called more times than the number of output lines.
- """
- return "-"
-
-
-
-class FileDescriptor(_ConsumerMixin, _LogOwner):
- """An object which can be operated on by select().
-
- This is an abstract superclass of all objects which may be notified when
- they are readable or writable; e.g. they have a file-descriptor that is
- valid to be passed to select(2).
- """
- connected = 0
- disconnected = 0
- disconnecting = 0
- _writeDisconnecting = False
- _writeDisconnected = False
- dataBuffer = ""
- offset = 0
-
- SEND_LIMIT = 128*1024
-
- implements(interfaces.IPushProducer, interfaces.IReadWriteDescriptor,
- interfaces.IConsumer, interfaces.ITransport, interfaces.IHalfCloseableDescriptor)
-
- def __init__(self, reactor=None):
- if not reactor:
- from twisted.internet import reactor
- self.reactor = reactor
- self._tempDataBuffer = [] # will be added to dataBuffer in doWrite
- self._tempDataLen = 0
-
-
- def connectionLost(self, reason):
- """The connection was lost.
-
- This is called when the connection on a selectable object has been
- lost. It will be called whether the connection was closed explicitly,
- an exception occurred in an event handler, or the other end of the
- connection closed it first.
-
- Clean up state here, but make sure to call back up to FileDescriptor.
- """
- self.disconnected = 1
- self.connected = 0
- if self.producer is not None:
- self.producer.stopProducing()
- self.producer = None
- self.stopReading()
- self.stopWriting()
-
-
- def writeSomeData(self, data):
- """
- Write as much as possible of the given data, immediately.
-
- This is called to invoke the lower-level writing functionality, such
- as a socket's send() method, or a file's write(); this method
- returns an integer or an exception. If an integer, it is the number
- of bytes written (possibly zero); if an exception, it indicates the
- connection was lost.
- """
- raise NotImplementedError("%s does not implement writeSomeData" %
- reflect.qual(self.__class__))
-
-
- def doRead(self):
- """
- Called when data is available for reading.
-
- Subclasses must override this method. The result will be interpreted
- in the same way as a result of doWrite().
- """
- raise NotImplementedError("%s does not implement doRead" %
- reflect.qual(self.__class__))
-
- def doWrite(self):
- """
- Called when data can be written.
-
- A result that is true (which will be a negative number or an
- exception instance) indicates that the connection was lost. A false
- result implies the connection is still there; a result of 0
- indicates no write was done, and a result of None indicates that a
- write was done.
- """
- if len(self.dataBuffer) - self.offset < self.SEND_LIMIT:
- # If there is currently less than SEND_LIMIT bytes left to send
- # in the string, extend it with the array data.
- self.dataBuffer = buffer(self.dataBuffer, self.offset) + "".join(self._tempDataBuffer)
- self.offset = 0
- self._tempDataBuffer = []
- self._tempDataLen = 0
-
- # Send as much data as you can.
- if self.offset:
- l = self.writeSomeData(buffer(self.dataBuffer, self.offset))
- else:
- l = self.writeSomeData(self.dataBuffer)
-
- # There is no writeSomeData implementation in Twisted which returns
- # < 0, but the documentation for writeSomeData used to claim negative
- # integers meant connection lost. Keep supporting this here,
- # although it may be worth deprecating and removing at some point.
- if l < 0 or isinstance(l, Exception):
- return l
- if l == 0 and self.dataBuffer:
- result = 0
- else:
- result = None
- self.offset += l
- # If there is nothing left to send,
- if self.offset == len(self.dataBuffer) and not self._tempDataLen:
- self.dataBuffer = ""
- self.offset = 0
- # stop writing.
- self.stopWriting()
- # If I've got a producer who is supposed to supply me with data,
- if self.producer is not None and ((not self.streamingProducer)
- or self.producerPaused):
- # tell them to supply some more.
- self.producerPaused = 0
- self.producer.resumeProducing()
- elif self.disconnecting:
- # But if I was previously asked to let the connection die, do
- # so.
- return self._postLoseConnection()
- elif self._writeDisconnecting:
- # I was previously asked to half-close the connection. We
- # set _writeDisconnected before calling handler, in case the
- # handler calls loseConnection(), which will want to check for
- # this attribute.
- self._writeDisconnected = True
- result = self._closeWriteConnection()
- return result
- return result
-
- def _postLoseConnection(self):
- """Called after a loseConnection(), when all data has been written.
-
- Whatever this returns is then returned by doWrite.
- """
- # default implementation, telling reactor we're finished
- return main.CONNECTION_DONE
-
- def _closeWriteConnection(self):
- # override in subclasses
- pass
-
- def writeConnectionLost(self, reason):
- # in current code should never be called
- self.connectionLost(reason)
-
- def readConnectionLost(self, reason):
- # override in subclasses
- self.connectionLost(reason)
-
-
- def _isSendBufferFull(self):
- """
- Determine whether the user-space send buffer for this transport is full
- or not.
-
- When the buffer contains more than C{self.bufferSize} bytes, it is
- considered full. This might be improved by considering the size of the
- kernel send buffer and how much of it is free.
-
- @return: C{True} if it is full, C{False} otherwise.
- """
- return len(self.dataBuffer) + self._tempDataLen > self.bufferSize
-
-
- def _maybePauseProducer(self):
- """
- Possibly pause a producer, if there is one and the send buffer is full.
- """
- # If we are responsible for pausing our producer,
- if self.producer is not None and self.streamingProducer:
- # and our buffer is full,
- if self._isSendBufferFull():
- # pause it.
- self.producerPaused = 1
- self.producer.pauseProducing()
-
-
- def write(self, data):
- """Reliably write some data.
-
- The data is buffered until the underlying file descriptor is ready
- for writing. If there is more than C{self.bufferSize} data in the
- buffer and this descriptor has a registered streaming producer, its
- C{pauseProducing()} method will be called.
- """
- if isinstance(data, unicode): # no, really, I mean it
- raise TypeError("Data must not be unicode")
- if not self.connected or self._writeDisconnected:
- return
- if data:
- self._tempDataBuffer.append(data)
- self._tempDataLen += len(data)
- self._maybePauseProducer()
- self.startWriting()
-
-
- def writeSequence(self, iovec):
- """
- Reliably write a sequence of data.
-
- Currently, this is a convenience method roughly equivalent to::
-
- for chunk in iovec:
- fd.write(chunk)
-
- It may have a more efficient implementation at a later time or in a
- different reactor.
-
- As with the C{write()} method, if a buffer size limit is reached and a
- streaming producer is registered, it will be paused until the buffered
- data is written to the underlying file descriptor.
- """
- for i in iovec:
- if isinstance(i, unicode): # no, really, I mean it
- raise TypeError("Data must not be unicode")
- if not self.connected or not iovec or self._writeDisconnected:
- return
- self._tempDataBuffer.extend(iovec)
- for i in iovec:
- self._tempDataLen += len(i)
- self._maybePauseProducer()
- self.startWriting()
-
-
- def loseConnection(self, _connDone=failure.Failure(main.CONNECTION_DONE)):
- """Close the connection at the next available opportunity.
-
- Call this to cause this FileDescriptor to lose its connection. It will
- first write any data that it has buffered.
-
- If there is data buffered yet to be written, this method will cause the
- transport to lose its connection as soon as it's done flushing its
- write buffer. If you have a producer registered, the connection won't
- be closed until the producer is finished. Therefore, make sure you
- unregister your producer when it's finished, or the connection will
- never close.
- """
-
- if self.connected and not self.disconnecting:
- if self._writeDisconnected:
- # doWrite won't trigger the connection close anymore
- self.stopReading()
- self.stopWriting()
- self.connectionLost(_connDone)
- else:
- self.stopReading()
- self.startWriting()
- self.disconnecting = 1
-
- def loseWriteConnection(self):
- self._writeDisconnecting = True
- self.startWriting()
-
- def stopReading(self):
- """Stop waiting for read availability.
-
- Call this to remove this selectable from being notified when it is
- ready for reading.
- """
- self.reactor.removeReader(self)
-
- def stopWriting(self):
- """Stop waiting for write availability.
-
- Call this to remove this selectable from being notified when it is ready
- for writing.
- """
- self.reactor.removeWriter(self)
-
- def startReading(self):
- """Start waiting for read availability.
- """
- self.reactor.addReader(self)
-
- def startWriting(self):
- """Start waiting for write availability.
-
- Call this to have this FileDescriptor be notified whenever it is ready for
- writing.
- """
- self.reactor.addWriter(self)
-
- # Producer/consumer implementation
-
- # first, the consumer stuff. This requires no additional work, as
- # any object you can write to can be a consumer, really.
-
- producer = None
- bufferSize = 2**2**2**2
-
- def stopConsuming(self):
- """Stop consuming data.
-
- This is called when a producer has lost its connection, to tell the
- consumer to go lose its connection (and break potential circular
- references).
- """
- self.unregisterProducer()
- self.loseConnection()
-
- # producer interface implementation
-
- def resumeProducing(self):
- assert self.connected and not self.disconnecting
- self.startReading()
-
- def pauseProducing(self):
- self.stopReading()
-
- def stopProducing(self):
- self.loseConnection()
-
-
- def fileno(self):
- """File Descriptor number for select().
-
- This method must be overridden or assigned in subclasses to
- indicate a valid file descriptor for the operating system.
- """
- return -1
-
-
-def isIPAddress(addr):
- """
- Determine whether the given string represents an IPv4 address.
-
- @type addr: C{str}
- @param addr: A string which may or may not be the decimal dotted
- representation of an IPv4 address.
-
- @rtype: C{bool}
- @return: C{True} if C{addr} represents an IPv4 address, C{False}
- otherwise.
- """
- dottedParts = addr.split('.')
- if len(dottedParts) == 4:
- for octet in dottedParts:
- try:
- value = int(octet)
- except ValueError:
- return False
- else:
- if value < 0 or value > 255:
- return False
- return True
- return False
-
-
-def isIPv6Address(addr):
- """
- Determine whether the given string represents an IPv6 address.
-
- @param addr: A string which may or may not be the hex
- representation of an IPv6 address.
- @type addr: C{str}
-
- @return: C{True} if C{addr} represents an IPv6 address, C{False}
- otherwise.
- @rtype: C{bool}
- """
- if '%' in addr:
- addr = addr.split('%', 1)[0]
- if not addr:
- return False
- try:
- # This might be a native implementation or the one from
- # twisted.python.compat.
- inet_pton(AF_INET6, addr)
- except (ValueError, error):
- return False
- return True
-
-
-__all__ = ["FileDescriptor", "isIPAddress", "isIPv6Address"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/address.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/address.py
deleted file mode 100755
index 14ecf748..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/address.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Address objects for network connections.
-"""
-
-import warnings, os
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IAddress
-from twisted.python import util
-
-
-class _IPAddress(object, util.FancyEqMixin):
- """
- An L{_IPAddress} represents the address of an IP socket endpoint, providing
- common behavior for IPv4 and IPv6.
-
- @ivar type: A string describing the type of transport, either 'TCP' or
- 'UDP'.
-
- @ivar host: A string containing the presentation format of the IP address;
- for example, "127.0.0.1" or "::1".
- @type host: C{str}
-
- @ivar port: An integer representing the port number.
- @type port: C{int}
- """
-
- implements(IAddress)
-
- compareAttributes = ('type', 'host', 'port')
-
- def __init__(self, type, host, port):
- assert type in ('TCP', 'UDP')
- self.type = type
- self.host = host
- self.port = port
-
-
- def __repr__(self):
- return '%s(%s, %r, %d)' % (
- self.__class__.__name__, self.type, self.host, self.port)
-
-
- def __hash__(self):
- return hash((self.type, self.host, self.port))
-
-
-
-class IPv4Address(_IPAddress):
- """
- An L{IPv4Address} represents the address of an IPv4 socket endpoint.
-
- @ivar host: A string containing a dotted-quad IPv4 address; for example,
- "127.0.0.1".
- @type host: C{str}
- """
-
- def __init__(self, type, host, port, _bwHack=None):
- _IPAddress.__init__(self, type, host, port)
- if _bwHack is not None:
- warnings.warn("twisted.internet.address.IPv4Address._bwHack "
- "is deprecated since Twisted 11.0",
- DeprecationWarning, stacklevel=2)
-
-
-
-class IPv6Address(_IPAddress):
- """
- An L{IPv6Address} represents the address of an IPv6 socket endpoint.
-
- @ivar host: A string containing a colon-separated, hexadecimal formatted
- IPv6 address; for example, "::1".
- @type host: C{str}
- """
-
-
-
-class UNIXAddress(object, util.FancyEqMixin):
- """
- Object representing a UNIX socket endpoint.
-
- @ivar name: The filename associated with this socket.
- @type name: C{str}
- """
-
- implements(IAddress)
-
- compareAttributes = ('name', )
-
- def __init__(self, name, _bwHack = None):
- self.name = name
- if _bwHack is not None:
- warnings.warn("twisted.internet.address.UNIXAddress._bwHack is deprecated since Twisted 11.0",
- DeprecationWarning, stacklevel=2)
-
-
- if getattr(os.path, 'samefile', None) is not None:
- def __eq__(self, other):
- """
- overriding L{util.FancyEqMixin} to ensure the os level samefile
- check is done if the name attributes do not match.
- """
- res = super(UNIXAddress, self).__eq__(other)
- if not res and self.name and other.name:
- try:
- return os.path.samefile(self.name, other.name)
- except OSError:
- pass
- return res
-
-
- def __repr__(self):
- return 'UNIXAddress(%r)' % (self.name,)
-
-
- def __hash__(self):
- if self.name is None:
- return hash((self.__class__, None))
- try:
- s1 = os.stat(self.name)
- return hash((s1.st_ino, s1.st_dev))
- except OSError:
- return hash(self.name)
-
-
-
-# These are for buildFactory backwards compatability due to
-# stupidity-induced inconsistency.
-
-class _ServerFactoryIPv4Address(IPv4Address):
- """Backwards compatability hack. Just like IPv4Address in practice."""
-
- def __eq__(self, other):
- if isinstance(other, tuple):
- warnings.warn("IPv4Address.__getitem__ is deprecated. Use attributes instead.",
- category=DeprecationWarning, stacklevel=2)
- return (self.host, self.port) == other
- elif isinstance(other, IPv4Address):
- a = (self.type, self.host, self.port)
- b = (other.type, other.host, other.port)
- return a == b
- return False
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/base.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/base.py
deleted file mode 100755
index 2c7cfb6a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/base.py
+++ /dev/null
@@ -1,1190 +0,0 @@
-# -*- test-case-name: twisted.test.test_internet -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Very basic functionality for a Reactor implementation.
-"""
-
-import socket # needed only for sync-dns
-from zope.interface import implements, classImplements
-
-import sys
-import warnings
-from heapq import heappush, heappop, heapify
-
-import traceback
-
-from twisted.python.compat import set
-from twisted.python.util import unsignedID
-from twisted.internet.interfaces import IReactorCore, IReactorTime, IReactorThreads
-from twisted.internet.interfaces import IResolverSimple, IReactorPluggableResolver
-from twisted.internet.interfaces import IConnector, IDelayedCall
-from twisted.internet import fdesc, main, error, abstract, defer, threads
-from twisted.python import log, failure, reflect
-from twisted.python.runtime import seconds as runtimeSeconds, platform
-from twisted.internet.defer import Deferred, DeferredList
-from twisted.persisted import styles
-
-# This import is for side-effects! Even if you don't see any code using it
-# in this module, don't delete it.
-from twisted.python import threadable
-
-
-class DelayedCall(styles.Ephemeral):
-
- implements(IDelayedCall)
- # enable .debug to record creator call stack, and it will be logged if
- # an exception occurs while the function is being run
- debug = False
- _str = None
-
- def __init__(self, time, func, args, kw, cancel, reset,
- seconds=runtimeSeconds):
- """
- @param time: Seconds from the epoch at which to call C{func}.
- @param func: The callable to call.
- @param args: The positional arguments to pass to the callable.
- @param kw: The keyword arguments to pass to the callable.
- @param cancel: A callable which will be called with this
- DelayedCall before cancellation.
- @param reset: A callable which will be called with this
- DelayedCall after changing this DelayedCall's scheduled
- execution time. The callable should adjust any necessary
- scheduling details to ensure this DelayedCall is invoked
- at the new appropriate time.
- @param seconds: If provided, a no-argument callable which will be
- used to determine the current time any time that information is
- needed.
- """
- self.time, self.func, self.args, self.kw = time, func, args, kw
- self.resetter = reset
- self.canceller = cancel
- self.seconds = seconds
- self.cancelled = self.called = 0
- self.delayed_time = 0
- if self.debug:
- self.creator = traceback.format_stack()[:-2]
-
- def getTime(self):
- """Return the time at which this call will fire
-
- @rtype: C{float}
- @return: The number of seconds after the epoch at which this call is
- scheduled to be made.
- """
- return self.time + self.delayed_time
-
- def cancel(self):
- """Unschedule this call
-
- @raise AlreadyCancelled: Raised if this call has already been
- unscheduled.
-
- @raise AlreadyCalled: Raised if this call has already been made.
- """
- if self.cancelled:
- raise error.AlreadyCancelled
- elif self.called:
- raise error.AlreadyCalled
- else:
- self.canceller(self)
- self.cancelled = 1
- if self.debug:
- self._str = str(self)
- del self.func, self.args, self.kw
-
- def reset(self, secondsFromNow):
- """Reschedule this call for a different time
-
- @type secondsFromNow: C{float}
- @param secondsFromNow: The number of seconds from the time of the
- C{reset} call at which this call will be scheduled.
-
- @raise AlreadyCancelled: Raised if this call has been cancelled.
- @raise AlreadyCalled: Raised if this call has already been made.
- """
- if self.cancelled:
- raise error.AlreadyCancelled
- elif self.called:
- raise error.AlreadyCalled
- else:
- newTime = self.seconds() + secondsFromNow
- if newTime < self.time:
- self.delayed_time = 0
- self.time = newTime
- self.resetter(self)
- else:
- self.delayed_time = newTime - self.time
-
- def delay(self, secondsLater):
- """Reschedule this call for a later time
-
- @type secondsLater: C{float}
- @param secondsLater: The number of seconds after the originally
- scheduled time for which to reschedule this call.
-
- @raise AlreadyCancelled: Raised if this call has been cancelled.
- @raise AlreadyCalled: Raised if this call has already been made.
- """
- if self.cancelled:
- raise error.AlreadyCancelled
- elif self.called:
- raise error.AlreadyCalled
- else:
- self.delayed_time += secondsLater
- if self.delayed_time < 0:
- self.activate_delay()
- self.resetter(self)
-
- def activate_delay(self):
- self.time += self.delayed_time
- self.delayed_time = 0
-
- def active(self):
- """Determine whether this call is still pending
-
- @rtype: C{bool}
- @return: True if this call has not yet been made or cancelled,
- False otherwise.
- """
- return not (self.cancelled or self.called)
-
-
- def __le__(self, other):
- """
- Implement C{<=} operator between two L{DelayedCall} instances.
-
- Comparison is based on the C{time} attribute (unadjusted by the
- delayed time).
- """
- return self.time <= other.time
-
-
- def __lt__(self, other):
- """
- Implement C{<} operator between two L{DelayedCall} instances.
-
- Comparison is based on the C{time} attribute (unadjusted by the
- delayed time).
- """
- return self.time < other.time
-
-
- def __str__(self):
- if self._str is not None:
- return self._str
- if hasattr(self, 'func'):
- if hasattr(self.func, 'func_name'):
- func = self.func.func_name
- if hasattr(self.func, 'im_class'):
- func = self.func.im_class.__name__ + '.' + func
- else:
- func = reflect.safe_repr(self.func)
- else:
- func = None
-
- now = self.seconds()
- L = ["<DelayedCall 0x%x [%ss] called=%s cancelled=%s" % (
- unsignedID(self), self.time - now, self.called,
- self.cancelled)]
- if func is not None:
- L.extend((" ", func, "("))
- if self.args:
- L.append(", ".join([reflect.safe_repr(e) for e in self.args]))
- if self.kw:
- L.append(", ")
- if self.kw:
- L.append(", ".join(['%s=%s' % (k, reflect.safe_repr(v)) for (k, v) in self.kw.iteritems()]))
- L.append(")")
-
- if self.debug:
- L.append("\n\ntraceback at creation: \n\n%s" % (' '.join(self.creator)))
- L.append('>')
-
- return "".join(L)
-
-
-
-class ThreadedResolver(object):
- """
- L{ThreadedResolver} uses a reactor, a threadpool, and
- L{socket.gethostbyname} to perform name lookups without blocking the
- reactor thread. It also supports timeouts indepedently from whatever
- timeout logic L{socket.gethostbyname} might have.
-
- @ivar reactor: The reactor the threadpool of which will be used to call
- L{socket.gethostbyname} and the I/O thread of which the result will be
- delivered.
- """
- implements(IResolverSimple)
-
- def __init__(self, reactor):
- self.reactor = reactor
- self._runningQueries = {}
-
-
- def _fail(self, name, err):
- err = error.DNSLookupError("address %r not found: %s" % (name, err))
- return failure.Failure(err)
-
-
- def _cleanup(self, name, lookupDeferred):
- userDeferred, cancelCall = self._runningQueries[lookupDeferred]
- del self._runningQueries[lookupDeferred]
- userDeferred.errback(self._fail(name, "timeout error"))
-
-
- def _checkTimeout(self, result, name, lookupDeferred):
- try:
- userDeferred, cancelCall = self._runningQueries[lookupDeferred]
- except KeyError:
- pass
- else:
- del self._runningQueries[lookupDeferred]
- cancelCall.cancel()
-
- if isinstance(result, failure.Failure):
- userDeferred.errback(self._fail(name, result.getErrorMessage()))
- else:
- userDeferred.callback(result)
-
-
- def getHostByName(self, name, timeout = (1, 3, 11, 45)):
- """
- See L{twisted.internet.interfaces.IResolverSimple.getHostByName}.
-
- Note that the elements of C{timeout} are summed and the result is used
- as a timeout for the lookup. Any intermediate timeout or retry logic
- is left up to the platform via L{socket.gethostbyname}.
- """
- if timeout:
- timeoutDelay = sum(timeout)
- else:
- timeoutDelay = 60
- userDeferred = defer.Deferred()
- lookupDeferred = threads.deferToThreadPool(
- self.reactor, self.reactor.getThreadPool(),
- socket.gethostbyname, name)
- cancelCall = self.reactor.callLater(
- timeoutDelay, self._cleanup, name, lookupDeferred)
- self._runningQueries[lookupDeferred] = (userDeferred, cancelCall)
- lookupDeferred.addBoth(self._checkTimeout, name, lookupDeferred)
- return userDeferred
-
-
-
-class BlockingResolver:
- implements(IResolverSimple)
-
- def getHostByName(self, name, timeout = (1, 3, 11, 45)):
- try:
- address = socket.gethostbyname(name)
- except socket.error:
- msg = "address %r not found" % (name,)
- err = error.DNSLookupError(msg)
- return defer.fail(err)
- else:
- return defer.succeed(address)
-
-
-class _ThreePhaseEvent(object):
- """
- Collection of callables (with arguments) which can be invoked as a group in
- a particular order.
-
- This provides the underlying implementation for the reactor's system event
- triggers. An instance of this class tracks triggers for all phases of a
- single type of event.
-
- @ivar before: A list of the before-phase triggers containing three-tuples
- of a callable, a tuple of positional arguments, and a dict of keyword
- arguments
-
- @ivar finishedBefore: A list of the before-phase triggers which have
- already been executed. This is only populated in the C{'BEFORE'} state.
-
- @ivar during: A list of the during-phase triggers containing three-tuples
- of a callable, a tuple of positional arguments, and a dict of keyword
- arguments
-
- @ivar after: A list of the after-phase triggers containing three-tuples
- of a callable, a tuple of positional arguments, and a dict of keyword
- arguments
-
- @ivar state: A string indicating what is currently going on with this
- object. One of C{'BASE'} (for when nothing in particular is happening;
- this is the initial value), C{'BEFORE'} (when the before-phase triggers
- are in the process of being executed).
- """
- def __init__(self):
- self.before = []
- self.during = []
- self.after = []
- self.state = 'BASE'
-
-
- def addTrigger(self, phase, callable, *args, **kwargs):
- """
- Add a trigger to the indicate phase.
-
- @param phase: One of C{'before'}, C{'during'}, or C{'after'}.
-
- @param callable: An object to be called when this event is triggered.
- @param *args: Positional arguments to pass to C{callable}.
- @param **kwargs: Keyword arguments to pass to C{callable}.
-
- @return: An opaque handle which may be passed to L{removeTrigger} to
- reverse the effects of calling this method.
- """
- if phase not in ('before', 'during', 'after'):
- raise KeyError("invalid phase")
- getattr(self, phase).append((callable, args, kwargs))
- return phase, callable, args, kwargs
-
-
- def removeTrigger(self, handle):
- """
- Remove a previously added trigger callable.
-
- @param handle: An object previously returned by L{addTrigger}. The
- trigger added by that call will be removed.
-
- @raise ValueError: If the trigger associated with C{handle} has already
- been removed or if C{handle} is not a valid handle.
- """
- return getattr(self, 'removeTrigger_' + self.state)(handle)
-
-
- def removeTrigger_BASE(self, handle):
- """
- Just try to remove the trigger.
-
- @see: removeTrigger
- """
- try:
- phase, callable, args, kwargs = handle
- except (TypeError, ValueError):
- raise ValueError("invalid trigger handle")
- else:
- if phase not in ('before', 'during', 'after'):
- raise KeyError("invalid phase")
- getattr(self, phase).remove((callable, args, kwargs))
-
-
- def removeTrigger_BEFORE(self, handle):
- """
- Remove the trigger if it has yet to be executed, otherwise emit a
- warning that in the future an exception will be raised when removing an
- already-executed trigger.
-
- @see: removeTrigger
- """
- phase, callable, args, kwargs = handle
- if phase != 'before':
- return self.removeTrigger_BASE(handle)
- if (callable, args, kwargs) in self.finishedBefore:
- warnings.warn(
- "Removing already-fired system event triggers will raise an "
- "exception in a future version of Twisted.",
- category=DeprecationWarning,
- stacklevel=3)
- else:
- self.removeTrigger_BASE(handle)
-
-
- def fireEvent(self):
- """
- Call the triggers added to this event.
- """
- self.state = 'BEFORE'
- self.finishedBefore = []
- beforeResults = []
- while self.before:
- callable, args, kwargs = self.before.pop(0)
- self.finishedBefore.append((callable, args, kwargs))
- try:
- result = callable(*args, **kwargs)
- except:
- log.err()
- else:
- if isinstance(result, Deferred):
- beforeResults.append(result)
- DeferredList(beforeResults).addCallback(self._continueFiring)
-
-
- def _continueFiring(self, ignored):
- """
- Call the during and after phase triggers for this event.
- """
- self.state = 'BASE'
- self.finishedBefore = []
- for phase in self.during, self.after:
- while phase:
- callable, args, kwargs = phase.pop(0)
- try:
- callable(*args, **kwargs)
- except:
- log.err()
-
-
-
-class ReactorBase(object):
- """
- Default base class for Reactors.
-
- @type _stopped: C{bool}
- @ivar _stopped: A flag which is true between paired calls to C{reactor.run}
- and C{reactor.stop}. This should be replaced with an explicit state
- machine.
-
- @type _justStopped: C{bool}
- @ivar _justStopped: A flag which is true between the time C{reactor.stop}
- is called and the time the shutdown system event is fired. This is
- used to determine whether that event should be fired after each
- iteration through the mainloop. This should be replaced with an
- explicit state machine.
-
- @type _started: C{bool}
- @ivar _started: A flag which is true from the time C{reactor.run} is called
- until the time C{reactor.run} returns. This is used to prevent calls
- to C{reactor.run} on a running reactor. This should be replaced with
- an explicit state machine.
-
- @ivar running: See L{IReactorCore.running}
-
- @ivar _registerAsIOThread: A flag controlling whether the reactor will
- register the thread it is running in as the I/O thread when it starts.
- If C{True}, registration will be done, otherwise it will not be.
- """
- implements(IReactorCore, IReactorTime, IReactorPluggableResolver)
-
- _registerAsIOThread = True
-
- _stopped = True
- installed = False
- usingThreads = False
- resolver = BlockingResolver()
-
- __name__ = "twisted.internet.reactor"
-
- def __init__(self):
- self.threadCallQueue = []
- self._eventTriggers = {}
- self._pendingTimedCalls = []
- self._newTimedCalls = []
- self._cancellations = 0
- self.running = False
- self._started = False
- self._justStopped = False
- self._startedBefore = False
- # reactor internal readers, e.g. the waker.
- self._internalReaders = set()
- self.waker = None
-
- # Arrange for the running attribute to change to True at the right time
- # and let a subclass possibly do other things at that time (eg install
- # signal handlers).
- self.addSystemEventTrigger(
- 'during', 'startup', self._reallyStartRunning)
- self.addSystemEventTrigger('during', 'shutdown', self.crash)
- self.addSystemEventTrigger('during', 'shutdown', self.disconnectAll)
-
- if platform.supportsThreads():
- self._initThreads()
- self.installWaker()
-
- # override in subclasses
-
- _lock = None
-
- def installWaker(self):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement installWaker")
-
- def installResolver(self, resolver):
- assert IResolverSimple.providedBy(resolver)
- oldResolver = self.resolver
- self.resolver = resolver
- return oldResolver
-
- def wakeUp(self):
- """
- Wake up the event loop.
- """
- if self.waker:
- self.waker.wakeUp()
- # if the waker isn't installed, the reactor isn't running, and
- # therefore doesn't need to be woken up
-
- def doIteration(self, delay):
- """
- Do one iteration over the readers and writers which have been added.
- """
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement doIteration")
-
- def addReader(self, reader):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement addReader")
-
- def addWriter(self, writer):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement addWriter")
-
- def removeReader(self, reader):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement removeReader")
-
- def removeWriter(self, writer):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement removeWriter")
-
- def removeAll(self):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement removeAll")
-
-
- def getReaders(self):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement getReaders")
-
-
- def getWriters(self):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement getWriters")
-
-
- def resolve(self, name, timeout = (1, 3, 11, 45)):
- """Return a Deferred that will resolve a hostname.
- """
- if not name:
- # XXX - This is *less than* '::', and will screw up IPv6 servers
- return defer.succeed('0.0.0.0')
- if abstract.isIPAddress(name):
- return defer.succeed(name)
- return self.resolver.getHostByName(name, timeout)
-
- # Installation.
-
- # IReactorCore
- def stop(self):
- """
- See twisted.internet.interfaces.IReactorCore.stop.
- """
- if self._stopped:
- raise error.ReactorNotRunning(
- "Can't stop reactor that isn't running.")
- self._stopped = True
- self._justStopped = True
- self._startedBefore = True
-
-
- def crash(self):
- """
- See twisted.internet.interfaces.IReactorCore.crash.
-
- Reset reactor state tracking attributes and re-initialize certain
- state-transition helpers which were set up in C{__init__} but later
- destroyed (through use).
- """
- self._started = False
- self.running = False
- self.addSystemEventTrigger(
- 'during', 'startup', self._reallyStartRunning)
-
- def sigInt(self, *args):
- """Handle a SIGINT interrupt.
- """
- log.msg("Received SIGINT, shutting down.")
- self.callFromThread(self.stop)
-
- def sigBreak(self, *args):
- """Handle a SIGBREAK interrupt.
- """
- log.msg("Received SIGBREAK, shutting down.")
- self.callFromThread(self.stop)
-
- def sigTerm(self, *args):
- """Handle a SIGTERM interrupt.
- """
- log.msg("Received SIGTERM, shutting down.")
- self.callFromThread(self.stop)
-
- def disconnectAll(self):
- """Disconnect every reader, and writer in the system.
- """
- selectables = self.removeAll()
- for reader in selectables:
- log.callWithLogger(reader,
- reader.connectionLost,
- failure.Failure(main.CONNECTION_LOST))
-
-
- def iterate(self, delay=0):
- """See twisted.internet.interfaces.IReactorCore.iterate.
- """
- self.runUntilCurrent()
- self.doIteration(delay)
-
-
- def fireSystemEvent(self, eventType):
- """See twisted.internet.interfaces.IReactorCore.fireSystemEvent.
- """
- event = self._eventTriggers.get(eventType)
- if event is not None:
- event.fireEvent()
-
-
- def addSystemEventTrigger(self, _phase, _eventType, _f, *args, **kw):
- """See twisted.internet.interfaces.IReactorCore.addSystemEventTrigger.
- """
- assert callable(_f), "%s is not callable" % _f
- if _eventType not in self._eventTriggers:
- self._eventTriggers[_eventType] = _ThreePhaseEvent()
- return (_eventType, self._eventTriggers[_eventType].addTrigger(
- _phase, _f, *args, **kw))
-
-
- def removeSystemEventTrigger(self, triggerID):
- """See twisted.internet.interfaces.IReactorCore.removeSystemEventTrigger.
- """
- eventType, handle = triggerID
- self._eventTriggers[eventType].removeTrigger(handle)
-
-
- def callWhenRunning(self, _callable, *args, **kw):
- """See twisted.internet.interfaces.IReactorCore.callWhenRunning.
- """
- if self.running:
- _callable(*args, **kw)
- else:
- return self.addSystemEventTrigger('after', 'startup',
- _callable, *args, **kw)
-
- def startRunning(self):
- """
- Method called when reactor starts: do some initialization and fire
- startup events.
-
- Don't call this directly, call reactor.run() instead: it should take
- care of calling this.
-
- This method is somewhat misnamed. The reactor will not necessarily be
- in the running state by the time this method returns. The only
- guarantee is that it will be on its way to the running state.
- """
- if self._started:
- raise error.ReactorAlreadyRunning()
- if self._startedBefore:
- raise error.ReactorNotRestartable()
- self._started = True
- self._stopped = False
- if self._registerAsIOThread:
- threadable.registerAsIOThread()
- self.fireSystemEvent('startup')
-
-
- def _reallyStartRunning(self):
- """
- Method called to transition to the running state. This should happen
- in the I{during startup} event trigger phase.
- """
- self.running = True
-
- # IReactorTime
-
- seconds = staticmethod(runtimeSeconds)
-
- def callLater(self, _seconds, _f, *args, **kw):
- """See twisted.internet.interfaces.IReactorTime.callLater.
- """
- assert callable(_f), "%s is not callable" % _f
- assert sys.maxint >= _seconds >= 0, \
- "%s is not greater than or equal to 0 seconds" % (_seconds,)
- tple = DelayedCall(self.seconds() + _seconds, _f, args, kw,
- self._cancelCallLater,
- self._moveCallLaterSooner,
- seconds=self.seconds)
- self._newTimedCalls.append(tple)
- return tple
-
- def _moveCallLaterSooner(self, tple):
- # Linear time find: slow.
- heap = self._pendingTimedCalls
- try:
- pos = heap.index(tple)
-
- # Move elt up the heap until it rests at the right place.
- elt = heap[pos]
- while pos != 0:
- parent = (pos-1) // 2
- if heap[parent] <= elt:
- break
- # move parent down
- heap[pos] = heap[parent]
- pos = parent
- heap[pos] = elt
- except ValueError:
- # element was not found in heap - oh well...
- pass
-
- def _cancelCallLater(self, tple):
- self._cancellations+=1
-
-
- def getDelayedCalls(self):
- """Return all the outstanding delayed calls in the system.
- They are returned in no particular order.
- This method is not efficient -- it is really only meant for
- test cases."""
- return [x for x in (self._pendingTimedCalls + self._newTimedCalls) if not x.cancelled]
-
- def _insertNewDelayedCalls(self):
- for call in self._newTimedCalls:
- if call.cancelled:
- self._cancellations-=1
- else:
- call.activate_delay()
- heappush(self._pendingTimedCalls, call)
- self._newTimedCalls = []
-
- def timeout(self):
- # insert new delayed calls to make sure to include them in timeout value
- self._insertNewDelayedCalls()
-
- if not self._pendingTimedCalls:
- return None
-
- return max(0, self._pendingTimedCalls[0].time - self.seconds())
-
-
- def runUntilCurrent(self):
- """Run all pending timed calls.
- """
- if self.threadCallQueue:
- # Keep track of how many calls we actually make, as we're
- # making them, in case another call is added to the queue
- # while we're in this loop.
- count = 0
- total = len(self.threadCallQueue)
- for (f, a, kw) in self.threadCallQueue:
- try:
- f(*a, **kw)
- except:
- log.err()
- count += 1
- if count == total:
- break
- del self.threadCallQueue[:count]
- if self.threadCallQueue:
- self.wakeUp()
-
- # insert new delayed calls now
- self._insertNewDelayedCalls()
-
- now = self.seconds()
- while self._pendingTimedCalls and (self._pendingTimedCalls[0].time <= now):
- call = heappop(self._pendingTimedCalls)
- if call.cancelled:
- self._cancellations-=1
- continue
-
- if call.delayed_time > 0:
- call.activate_delay()
- heappush(self._pendingTimedCalls, call)
- continue
-
- try:
- call.called = 1
- call.func(*call.args, **call.kw)
- except:
- log.deferr()
- if hasattr(call, "creator"):
- e = "\n"
- e += " C: previous exception occurred in " + \
- "a DelayedCall created here:\n"
- e += " C:"
- e += "".join(call.creator).rstrip().replace("\n","\n C:")
- e += "\n"
- log.msg(e)
-
-
- if (self._cancellations > 50 and
- self._cancellations > len(self._pendingTimedCalls) >> 1):
- self._cancellations = 0
- self._pendingTimedCalls = [x for x in self._pendingTimedCalls
- if not x.cancelled]
- heapify(self._pendingTimedCalls)
-
- if self._justStopped:
- self._justStopped = False
- self.fireSystemEvent("shutdown")
-
- # IReactorProcess
-
- def _checkProcessArgs(self, args, env):
- """
- Check for valid arguments and environment to spawnProcess.
-
- @return: A two element tuple giving values to use when creating the
- process. The first element of the tuple is a C{list} of C{str}
- giving the values for argv of the child process. The second element
- of the tuple is either C{None} if C{env} was C{None} or a C{dict}
- mapping C{str} environment keys to C{str} environment values.
- """
- # Any unicode string which Python would successfully implicitly
- # encode to a byte string would have worked before these explicit
- # checks were added. Anything which would have failed with a
- # UnicodeEncodeError during that implicit encoding step would have
- # raised an exception in the child process and that would have been
- # a pain in the butt to debug.
- #
- # So, we will explicitly attempt the same encoding which Python
- # would implicitly do later. If it fails, we will report an error
- # without ever spawning a child process. If it succeeds, we'll save
- # the result so that Python doesn't need to do it implicitly later.
- #
- # For any unicode which we can actually encode, we'll also issue a
- # deprecation warning, because no one should be passing unicode here
- # anyway.
- #
- # -exarkun
- defaultEncoding = sys.getdefaultencoding()
-
- # Common check function
- def argChecker(arg):
- """
- Return either a str or None. If the given value is not
- allowable for some reason, None is returned. Otherwise, a
- possibly different object which should be used in place of arg
- is returned. This forces unicode encoding to happen now, rather
- than implicitly later.
- """
- if isinstance(arg, unicode):
- try:
- arg = arg.encode(defaultEncoding)
- except UnicodeEncodeError:
- return None
- warnings.warn(
- "Argument strings and environment keys/values passed to "
- "reactor.spawnProcess should be str, not unicode.",
- category=DeprecationWarning,
- stacklevel=4)
- if isinstance(arg, str) and '\0' not in arg:
- return arg
- return None
-
- # Make a few tests to check input validity
- if not isinstance(args, (tuple, list)):
- raise TypeError("Arguments must be a tuple or list")
-
- outputArgs = []
- for arg in args:
- arg = argChecker(arg)
- if arg is None:
- raise TypeError("Arguments contain a non-string value")
- else:
- outputArgs.append(arg)
-
- outputEnv = None
- if env is not None:
- outputEnv = {}
- for key, val in env.iteritems():
- key = argChecker(key)
- if key is None:
- raise TypeError("Environment contains a non-string key")
- val = argChecker(val)
- if val is None:
- raise TypeError("Environment contains a non-string value")
- outputEnv[key] = val
- return outputArgs, outputEnv
-
- # IReactorThreads
- if platform.supportsThreads():
- threadpool = None
- # ID of the trigger starting the threadpool
- _threadpoolStartupID = None
- # ID of the trigger stopping the threadpool
- threadpoolShutdownID = None
-
- def _initThreads(self):
- self.usingThreads = True
- self.resolver = ThreadedResolver(self)
-
- def callFromThread(self, f, *args, **kw):
- """
- See L{twisted.internet.interfaces.IReactorThreads.callFromThread}.
- """
- assert callable(f), "%s is not callable" % (f,)
- # lists are thread-safe in CPython, but not in Jython
- # this is probably a bug in Jython, but until fixed this code
- # won't work in Jython.
- self.threadCallQueue.append((f, args, kw))
- self.wakeUp()
-
- def _initThreadPool(self):
- """
- Create the threadpool accessible with callFromThread.
- """
- from twisted.python import threadpool
- self.threadpool = threadpool.ThreadPool(
- 0, 10, 'twisted.internet.reactor')
- self._threadpoolStartupID = self.callWhenRunning(
- self.threadpool.start)
- self.threadpoolShutdownID = self.addSystemEventTrigger(
- 'during', 'shutdown', self._stopThreadPool)
-
- def _uninstallHandler(self):
- pass
-
- def _stopThreadPool(self):
- """
- Stop the reactor threadpool. This method is only valid if there
- is currently a threadpool (created by L{_initThreadPool}). It
- is not intended to be called directly; instead, it will be
- called by a shutdown trigger created in L{_initThreadPool}.
- """
- triggers = [self._threadpoolStartupID, self.threadpoolShutdownID]
- for trigger in filter(None, triggers):
- try:
- self.removeSystemEventTrigger(trigger)
- except ValueError:
- pass
- self._threadpoolStartupID = None
- self.threadpoolShutdownID = None
- self.threadpool.stop()
- self.threadpool = None
-
-
- def getThreadPool(self):
- """
- See L{twisted.internet.interfaces.IReactorThreads.getThreadPool}.
- """
- if self.threadpool is None:
- self._initThreadPool()
- return self.threadpool
-
-
- def callInThread(self, _callable, *args, **kwargs):
- """
- See L{twisted.internet.interfaces.IReactorThreads.callInThread}.
- """
- self.getThreadPool().callInThread(_callable, *args, **kwargs)
-
- def suggestThreadPoolSize(self, size):
- """
- See L{twisted.internet.interfaces.IReactorThreads.suggestThreadPoolSize}.
- """
- self.getThreadPool().adjustPoolsize(maxthreads=size)
- else:
- # This is for signal handlers.
- def callFromThread(self, f, *args, **kw):
- assert callable(f), "%s is not callable" % (f,)
- # See comment in the other callFromThread implementation.
- self.threadCallQueue.append((f, args, kw))
-
-if platform.supportsThreads():
- classImplements(ReactorBase, IReactorThreads)
-
-
-class BaseConnector(styles.Ephemeral):
- """Basic implementation of connector.
-
- State can be: "connecting", "connected", "disconnected"
- """
-
- implements(IConnector)
-
- timeoutID = None
- factoryStarted = 0
-
- def __init__(self, factory, timeout, reactor):
- self.state = "disconnected"
- self.reactor = reactor
- self.factory = factory
- self.timeout = timeout
-
- def disconnect(self):
- """Disconnect whatever our state is."""
- if self.state == 'connecting':
- self.stopConnecting()
- elif self.state == 'connected':
- self.transport.loseConnection()
-
- def connect(self):
- """Start connection to remote server."""
- if self.state != "disconnected":
- raise RuntimeError, "can't connect in this state"
-
- self.state = "connecting"
- if not self.factoryStarted:
- self.factory.doStart()
- self.factoryStarted = 1
- self.transport = transport = self._makeTransport()
- if self.timeout is not None:
- self.timeoutID = self.reactor.callLater(self.timeout, transport.failIfNotConnected, error.TimeoutError())
- self.factory.startedConnecting(self)
-
- def stopConnecting(self):
- """Stop attempting to connect."""
- if self.state != "connecting":
- raise error.NotConnectingError, "we're not trying to connect"
-
- self.state = "disconnected"
- self.transport.failIfNotConnected(error.UserError())
- del self.transport
-
- def cancelTimeout(self):
- if self.timeoutID is not None:
- try:
- self.timeoutID.cancel()
- except ValueError:
- pass
- del self.timeoutID
-
- def buildProtocol(self, addr):
- self.state = "connected"
- self.cancelTimeout()
- return self.factory.buildProtocol(addr)
-
- def connectionFailed(self, reason):
- self.cancelTimeout()
- self.transport = None
- self.state = "disconnected"
- self.factory.clientConnectionFailed(self, reason)
- if self.state == "disconnected":
- # factory hasn't called our connect() method
- self.factory.doStop()
- self.factoryStarted = 0
-
- def connectionLost(self, reason):
- self.state = "disconnected"
- self.factory.clientConnectionLost(self, reason)
- if self.state == "disconnected":
- # factory hasn't called our connect() method
- self.factory.doStop()
- self.factoryStarted = 0
-
- def getDestination(self):
- raise NotImplementedError(
- reflect.qual(self.__class__) + " did not implement "
- "getDestination")
-
-
-
-class BasePort(abstract.FileDescriptor):
- """Basic implementation of a ListeningPort.
-
- Note: This does not actually implement IListeningPort.
- """
-
- addressFamily = None
- socketType = None
-
- def createInternetSocket(self):
- s = socket.socket(self.addressFamily, self.socketType)
- s.setblocking(0)
- fdesc._setCloseOnExec(s.fileno())
- return s
-
-
- def doWrite(self):
- """Raises a RuntimeError"""
- raise RuntimeError, "doWrite called on a %s" % reflect.qual(self.__class__)
-
-
-
-class _SignalReactorMixin(object):
- """
- Private mixin to manage signals: it installs signal handlers at start time,
- and define run method.
-
- It can only be used mixed in with L{ReactorBase}, and has to be defined
- first in the inheritance (so that method resolution order finds
- startRunning first).
-
- @type _installSignalHandlers: C{bool}
- @ivar _installSignalHandlers: A flag which indicates whether any signal
- handlers will be installed during startup. This includes handlers for
- SIGCHLD to monitor child processes, and SIGINT, SIGTERM, and SIGBREAK
- to stop the reactor.
- """
-
- _installSignalHandlers = False
-
- def _handleSignals(self):
- """
- Install the signal handlers for the Twisted event loop.
- """
- try:
- import signal
- except ImportError:
- log.msg("Warning: signal module unavailable -- "
- "not installing signal handlers.")
- return
-
- if signal.getsignal(signal.SIGINT) == signal.default_int_handler:
- # only handle if there isn't already a handler, e.g. for Pdb.
- signal.signal(signal.SIGINT, self.sigInt)
- signal.signal(signal.SIGTERM, self.sigTerm)
-
- # Catch Ctrl-Break in windows
- if hasattr(signal, "SIGBREAK"):
- signal.signal(signal.SIGBREAK, self.sigBreak)
-
-
- def startRunning(self, installSignalHandlers=True):
- """
- Extend the base implementation in order to remember whether signal
- handlers should be installed later.
-
- @type installSignalHandlers: C{bool}
- @param installSignalHandlers: A flag which, if set, indicates that
- handlers for a number of (implementation-defined) signals should be
- installed during startup.
- """
- self._installSignalHandlers = installSignalHandlers
- ReactorBase.startRunning(self)
-
-
- def _reallyStartRunning(self):
- """
- Extend the base implementation by also installing signal handlers, if
- C{self._installSignalHandlers} is true.
- """
- ReactorBase._reallyStartRunning(self)
- if self._installSignalHandlers:
- # Make sure this happens before after-startup events, since the
- # expectation of after-startup is that the reactor is fully
- # initialized. Don't do it right away for historical reasons
- # (perhaps some before-startup triggers don't want there to be a
- # custom SIGCHLD handler so that they can run child processes with
- # some blocking api).
- self._handleSignals()
-
-
- def run(self, installSignalHandlers=True):
- self.startRunning(installSignalHandlers=installSignalHandlers)
- self.mainLoop()
-
-
- def mainLoop(self):
- while self._started:
- try:
- while self._started:
- # Advance simulation time in delayed event
- # processors.
- self.runUntilCurrent()
- t2 = self.timeout()
- t = self.running and t2
- self.doIteration(t)
- except:
- log.msg("Unexpected error in main loop.")
- log.err()
- else:
- log.msg('Main loop terminated.')
-
-
-
-__all__ = []
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/cfreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/cfreactor.py
deleted file mode 100755
index ef6bf7d3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/cfreactor.py
+++ /dev/null
@@ -1,501 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_core -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A reactor for integrating with U{CFRunLoop<http://bit.ly/cfrunloop>}, the
-CoreFoundation main loop used by MacOS X.
-
-This is useful for integrating Twisted with U{PyObjC<http://pyobjc.sf.net/>}
-applications.
-"""
-
-__all__ = [
- 'install',
- 'CFReactor'
-]
-
-import sys
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IReactorFDSet
-from twisted.internet.posixbase import PosixReactorBase, _Waker
-from twisted.internet.posixbase import _NO_FILEDESC
-
-from twisted.python import log
-
-from CoreFoundation import (
- CFRunLoopAddSource, CFRunLoopRemoveSource, CFRunLoopGetMain, CFRunLoopRun,
- CFRunLoopStop, CFRunLoopTimerCreate, CFRunLoopAddTimer,
- CFRunLoopTimerInvalidate, kCFAllocatorDefault, kCFRunLoopCommonModes,
- CFAbsoluteTimeGetCurrent)
-
-from CFNetwork import (
- CFSocketCreateWithNative, CFSocketSetSocketFlags, CFSocketEnableCallBacks,
- CFSocketCreateRunLoopSource, CFSocketDisableCallBacks, CFSocketInvalidate,
- kCFSocketWriteCallBack, kCFSocketReadCallBack, kCFSocketConnectCallBack,
- kCFSocketAutomaticallyReenableReadCallBack,
- kCFSocketAutomaticallyReenableWriteCallBack)
-
-
-_READ = 0
-_WRITE = 1
-_preserveSOError = 1 << 6
-
-
-class _WakerPlus(_Waker):
- """
- The normal Twisted waker will simply wake up the main loop, which causes an
- iteration to run, which in turn causes L{PosixReactorBase.runUntilCurrent}
- to get invoked.
-
- L{CFReactor} has a slightly different model of iteration, though: rather
- than have each iteration process the thread queue, then timed calls, then
- file descriptors, each callback is run as it is dispatched by the CFRunLoop
- observer which triggered it.
-
- So this waker needs to not only unblock the loop, but also make sure the
- work gets done; so, it reschedules the invocation of C{runUntilCurrent} to
- be immediate (0 seconds from now) even if there is no timed call work to
- do.
- """
-
- def doRead(self):
- """
- Wake up the loop and force C{runUntilCurrent} to run immediately in the
- next timed iteration.
- """
- result = _Waker.doRead(self)
- self.reactor._scheduleSimulate(True)
- return result
-
-
-
-class CFReactor(PosixReactorBase):
- """
- The CoreFoundation reactor.
-
- You probably want to use this via the L{install} API.
-
- @ivar _fdmap: a dictionary, mapping an integer (a file descriptor) to a
- 4-tuple of:
-
- - source: a C{CFRunLoopSource}; the source associated with this
- socket.
- - socket: a C{CFSocket} wrapping the file descriptor.
- - descriptor: an L{IReadDescriptor} and/or L{IWriteDescriptor}
- provider.
- - read-write: a 2-C{list} of booleans: respectively, whether this
- descriptor is currently registered for reading or registered for
- writing.
-
- @ivar _idmap: a dictionary, mapping the id() of an L{IReadDescriptor} or
- L{IWriteDescriptor} to a C{fd} in L{_fdmap}. Implemented in this
- manner so that we don't have to rely (even more) on the hashability of
- L{IReadDescriptor} providers, and we know that they won't be collected
- since these are kept in sync with C{_fdmap}. Necessary because the
- .fileno() of a file descriptor may change at will, so we need to be
- able to look up what its file descriptor I{used} to be, so that we can
- look it up in C{_fdmap}
-
- @ivar _cfrunloop: the L{CFRunLoop} pyobjc object wrapped by this reactor.
-
- @ivar _inCFLoop: Is L{CFRunLoopRun} currently running?
-
- @type _inCFLoop: C{bool}
-
- @ivar _currentSimulator: if a CFTimer is currently scheduled with the CF
- run loop to run Twisted callLater calls, this is a reference to it.
- Otherwise, it is C{None}
- """
-
- implements(IReactorFDSet)
-
- def __init__(self, runLoop=None, runner=None):
- self._fdmap = {}
- self._idmap = {}
- if runner is None:
- runner = CFRunLoopRun
- self._runner = runner
-
- if runLoop is None:
- runLoop = CFRunLoopGetMain()
- self._cfrunloop = runLoop
- PosixReactorBase.__init__(self)
-
-
- def installWaker(self):
- """
- Override C{installWaker} in order to use L{_WakerPlus}; otherwise this
- should be exactly the same as the parent implementation.
- """
- if not self.waker:
- self.waker = _WakerPlus(self)
- self._internalReaders.add(self.waker)
- self.addReader(self.waker)
-
-
- def _socketCallback(self, cfSocket, callbackType,
- ignoredAddress, ignoredData, context):
- """
- The socket callback issued by CFRunLoop. This will issue C{doRead} or
- C{doWrite} calls to the L{IReadDescriptor} and L{IWriteDescriptor}
- registered with the file descriptor that we are being notified of.
-
- @param cfSocket: The L{CFSocket} which has got some activity.
-
- @param callbackType: The type of activity that we are being notified
- of. Either L{kCFSocketReadCallBack} or L{kCFSocketWriteCallBack}.
-
- @param ignoredAddress: Unused, because this is not used for either of
- the callback types we register for.
-
- @param ignoredData: Unused, because this is not used for either of the
- callback types we register for.
-
- @param context: The data associated with this callback by
- L{CFSocketCreateWithNative} (in L{CFReactor._watchFD}). A 2-tuple
- of C{(int, CFRunLoopSource)}.
- """
- (fd, smugglesrc) = context
- if fd not in self._fdmap:
- # Spurious notifications seem to be generated sometimes if you
- # CFSocketDisableCallBacks in the middle of an event. I don't know
- # about this FD, any more, so let's get rid of it.
- CFRunLoopRemoveSource(
- self._cfrunloop, smugglesrc, kCFRunLoopCommonModes
- )
- return
-
- why = None
- isRead = False
- src, skt, readWriteDescriptor, rw = self._fdmap[fd]
- try:
- if readWriteDescriptor.fileno() == -1:
- why = _NO_FILEDESC
- else:
- isRead = callbackType == kCFSocketReadCallBack
- # CFSocket seems to deliver duplicate read/write notifications
- # sometimes, especially a duplicate writability notification
- # when first registering the socket. This bears further
- # investigation, since I may have been mis-interpreting the
- # behavior I was seeing. (Running the full Twisted test suite,
- # while thorough, is not always entirely clear.) Until this has
- # been more thoroughly investigated , we consult our own
- # reading/writing state flags to determine whether we should
- # actually attempt a doRead/doWrite first. -glyph
- if isRead:
- if rw[_READ]:
- why = log.callWithLogger(
- readWriteDescriptor, readWriteDescriptor.doRead)
- else:
- if rw[_WRITE]:
- why = log.callWithLogger(
- readWriteDescriptor, readWriteDescriptor.doWrite)
- except:
- why = sys.exc_info()[1]
- log.err()
- if why:
- self._disconnectSelectable(readWriteDescriptor, why, isRead)
-
-
- def _watchFD(self, fd, descr, flag):
- """
- Register a file descriptor with the L{CFRunLoop}, or modify its state
- so that it's listening for both notifications (read and write) rather
- than just one; used to implement C{addReader} and C{addWriter}.
-
- @param fd: The file descriptor.
-
- @type fd: C{int}
-
- @param descr: the L{IReadDescriptor} or L{IWriteDescriptor}
-
- @param flag: the flag to register for callbacks on, either
- L{kCFSocketReadCallBack} or L{kCFSocketWriteCallBack}
- """
- if fd == -1:
- raise RuntimeError("Invalid file descriptor.")
- if fd in self._fdmap:
- src, cfs, gotdescr, rw = self._fdmap[fd]
- # do I need to verify that it's the same descr?
- else:
- ctx = []
- ctx.append(fd)
- cfs = CFSocketCreateWithNative(
- kCFAllocatorDefault, fd,
- kCFSocketReadCallBack | kCFSocketWriteCallBack |
- kCFSocketConnectCallBack,
- self._socketCallback, ctx
- )
- CFSocketSetSocketFlags(
- cfs,
- kCFSocketAutomaticallyReenableReadCallBack |
- kCFSocketAutomaticallyReenableWriteCallBack |
-
- # This extra flag is to ensure that CF doesn't (destructively,
- # because destructively is the only way to do it) retrieve
- # SO_ERROR and thereby break twisted.internet.tcp.BaseClient,
- # which needs SO_ERROR to tell it whether or not it needs to
- # call connect_ex a second time.
- _preserveSOError
- )
- src = CFSocketCreateRunLoopSource(kCFAllocatorDefault, cfs, 0)
- ctx.append(src)
- CFRunLoopAddSource(self._cfrunloop, src, kCFRunLoopCommonModes)
- CFSocketDisableCallBacks(
- cfs,
- kCFSocketReadCallBack | kCFSocketWriteCallBack |
- kCFSocketConnectCallBack
- )
- rw = [False, False]
- self._idmap[id(descr)] = fd
- self._fdmap[fd] = src, cfs, descr, rw
- rw[self._flag2idx(flag)] = True
- CFSocketEnableCallBacks(cfs, flag)
-
-
- def _flag2idx(self, flag):
- """
- Convert a C{kCFSocket...} constant to an index into the read/write
- state list (C{_READ} or C{_WRITE}) (the 4th element of the value of
- C{self._fdmap}).
-
- @param flag: C{kCFSocketReadCallBack} or C{kCFSocketWriteCallBack}
-
- @return: C{_READ} or C{_WRITE}
- """
- return {kCFSocketReadCallBack: _READ,
- kCFSocketWriteCallBack: _WRITE}[flag]
-
-
- def _unwatchFD(self, fd, descr, flag):
- """
- Unregister a file descriptor with the L{CFRunLoop}, or modify its state
- so that it's listening for only one notification (read or write) as
- opposed to both; used to implement C{removeReader} and C{removeWriter}.
-
- @param fd: a file descriptor
-
- @type fd: C{int}
-
- @param descr: an L{IReadDescriptor} or L{IWriteDescriptor}
-
- @param flag: L{kCFSocketWriteCallBack} L{kCFSocketReadCallBack}
- """
- if id(descr) not in self._idmap:
- return
- if fd == -1:
- # need to deal with it in this case, I think.
- realfd = self._idmap[id(descr)]
- else:
- realfd = fd
- src, cfs, descr, rw = self._fdmap[realfd]
- CFSocketDisableCallBacks(cfs, flag)
- rw[self._flag2idx(flag)] = False
- if not rw[_READ] and not rw[_WRITE]:
- del self._idmap[id(descr)]
- del self._fdmap[realfd]
- CFRunLoopRemoveSource(self._cfrunloop, src, kCFRunLoopCommonModes)
- CFSocketInvalidate(cfs)
-
-
- def addReader(self, reader):
- """
- Implement L{IReactorFDSet.addReader}.
- """
- self._watchFD(reader.fileno(), reader, kCFSocketReadCallBack)
-
-
- def addWriter(self, writer):
- """
- Implement L{IReactorFDSet.addWriter}.
- """
- self._watchFD(writer.fileno(), writer, kCFSocketWriteCallBack)
-
-
- def removeReader(self, reader):
- """
- Implement L{IReactorFDSet.removeReader}.
- """
- self._unwatchFD(reader.fileno(), reader, kCFSocketReadCallBack)
-
-
- def removeWriter(self, writer):
- """
- Implement L{IReactorFDSet.removeWriter}.
- """
- self._unwatchFD(writer.fileno(), writer, kCFSocketWriteCallBack)
-
-
- def removeAll(self):
- """
- Implement L{IReactorFDSet.removeAll}.
- """
- allDesc = set([descr for src, cfs, descr, rw in self._fdmap.values()])
- allDesc -= set(self._internalReaders)
- for desc in allDesc:
- self.removeReader(desc)
- self.removeWriter(desc)
- return list(allDesc)
-
-
- def getReaders(self):
- """
- Implement L{IReactorFDSet.getReaders}.
- """
- return [descr for src, cfs, descr, rw in self._fdmap.values()
- if rw[_READ]]
-
-
- def getWriters(self):
- """
- Implement L{IReactorFDSet.getWriters}.
- """
- return [descr for src, cfs, descr, rw in self._fdmap.values()
- if rw[_WRITE]]
-
-
- def _moveCallLaterSooner(self, tple):
- """
- Override L{PosixReactorBase}'s implementation of L{IDelayedCall.reset}
- so that it will immediately reschedule. Normally
- C{_moveCallLaterSooner} depends on the fact that C{runUntilCurrent} is
- always run before the mainloop goes back to sleep, so this forces it to
- immediately recompute how long the loop needs to stay asleep.
- """
- result = PosixReactorBase._moveCallLaterSooner(self, tple)
- self._scheduleSimulate()
- return result
-
-
- _inCFLoop = False
-
- def mainLoop(self):
- """
- Run the runner (L{CFRunLoopRun} or something that calls it), which runs
- the run loop until C{crash()} is called.
- """
- self._inCFLoop = True
- try:
- self._runner()
- finally:
- self._inCFLoop = False
-
-
- _currentSimulator = None
-
- def _scheduleSimulate(self, force=False):
- """
- Schedule a call to C{self.runUntilCurrent}. This will cancel the
- currently scheduled call if it is already scheduled.
-
- @param force: Even if there are no timed calls, make sure that
- C{runUntilCurrent} runs immediately (in a 0-seconds-from-now
- {CFRunLoopTimer}). This is necessary for calls which need to
- trigger behavior of C{runUntilCurrent} other than running timed
- calls, such as draining the thread call queue or calling C{crash()}
- when the appropriate flags are set.
-
- @type force: C{bool}
- """
- if self._currentSimulator is not None:
- CFRunLoopTimerInvalidate(self._currentSimulator)
- self._currentSimulator = None
- timeout = self.timeout()
- if force:
- timeout = 0.0
- if timeout is not None:
- fireDate = (CFAbsoluteTimeGetCurrent() + timeout)
- def simulate(cftimer, extra):
- self._currentSimulator = None
- self.runUntilCurrent()
- self._scheduleSimulate()
- c = self._currentSimulator = CFRunLoopTimerCreate(
- kCFAllocatorDefault, fireDate,
- 0, 0, 0, simulate, None
- )
- CFRunLoopAddTimer(self._cfrunloop, c, kCFRunLoopCommonModes)
-
-
- def callLater(self, _seconds, _f, *args, **kw):
- """
- Implement L{IReactorTime.callLater}.
- """
- delayedCall = PosixReactorBase.callLater(
- self, _seconds, _f, *args, **kw
- )
- self._scheduleSimulate()
- return delayedCall
-
-
- def stop(self):
- """
- Implement L{IReactorCore.stop}.
- """
- PosixReactorBase.stop(self)
- self._scheduleSimulate(True)
-
-
- def crash(self):
- """
- Implement L{IReactorCore.crash}
- """
- wasStarted = self._started
- PosixReactorBase.crash(self)
- if self._inCFLoop:
- self._stopNow()
- else:
- if wasStarted:
- self.callLater(0, self._stopNow)
-
-
- def _stopNow(self):
- """
- Immediately stop the CFRunLoop (which must be running!).
- """
- CFRunLoopStop(self._cfrunloop)
-
-
- def iterate(self, delay=0):
- """
- Emulate the behavior of C{iterate()} for things that want to call it,
- by letting the loop run for a little while and then scheduling a timed
- call to exit it.
- """
- self.callLater(delay, self._stopNow)
- self.mainLoop()
-
-
-
-def install(runLoop=None, runner=None):
- """
- Configure the twisted mainloop to be run inside CFRunLoop.
-
- @param runLoop: the run loop to use.
-
- @param runner: the function to call in order to actually invoke the main
- loop. This will default to L{CFRunLoopRun} if not specified. However,
- this is not an appropriate choice for GUI applications, as you need to
- run NSApplicationMain (or something like it). For example, to run the
- Twisted mainloop in a PyObjC application, your C{main.py} should look
- something like this::
-
- from PyObjCTools import AppHelper
- from twisted.internet.cfreactor import install
- install(runner=AppHelper.runEventLoop)
- # initialize your application
- reactor.run()
-
- @return: The installed reactor.
-
- @rtype: L{CFReactor}
- """
-
- reactor = CFReactor(runLoop=runLoop, runner=runner)
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/default.py
deleted file mode 100755
index b9aa1999..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/default.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_default -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The most suitable default reactor for the current platform.
-
-Depending on a specific application's needs, some other reactor may in
-fact be better.
-"""
-
-__all__ = ["install"]
-
-from twisted.python.runtime import platform
-
-
-def _getInstallFunction(platform):
- """
- Return a function to install the reactor most suited for the given platform.
-
- @param platform: The platform for which to select a reactor.
- @type platform: L{twisted.python.runtime.Platform}
-
- @return: A zero-argument callable which will install the selected
- reactor.
- """
- # Linux: epoll(7) is the fault, since it scales well.
- #
- # OS X: poll(2) is not exposed by Python because it doesn't
- # support all file descriptors (in particular, lack of PTY support
- # is a problem) -- see <http://bugs.python.org/issue5154>. kqueue
- # reactor is being rewritten (see
- # <http://twistedmatrix.com/trac/ticket/1918>), and also has same
- # restriction as poll(2) as far PTY support goes.
- #
- # Windows: IOCP should eventually be default, but still has some serious
- # bugs, e.g. <http://twistedmatrix.com/trac/ticket/4667>.
- #
- # We therefore choose epoll(7) on Linux, poll(2) on other non-OS X POSIX
- # platforms, and select(2) everywhere else.
- try:
- if platform.isLinux():
- try:
- from twisted.internet.epollreactor import install
- except ImportError:
- from twisted.internet.pollreactor import install
- elif platform.getType() == 'posix' and not platform.isMacOSX():
- from twisted.internet.pollreactor import install
- else:
- from twisted.internet.selectreactor import install
- except ImportError:
- from twisted.internet.selectreactor import install
- return install
-
-
-install = _getInstallFunction(platform)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/defer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/defer.py
deleted file mode 100755
index f1f05a42..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/defer.py
+++ /dev/null
@@ -1,1561 +0,0 @@
-# -*- test-case-name: twisted.test.test_defer,twisted.test.test_defgen,twisted.internet.test.test_inlinecb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support for results that aren't immediately available.
-
-Maintainer: Glyph Lefkowitz
-
-@var _NO_RESULT: The result used to represent the fact that there is no
- result. B{Never ever ever use this as an actual result for a Deferred}. You
- have been warned.
-
-@var _CONTINUE: A marker left in L{Deferred.callbacks} to indicate a Deferred
- chain. Always accompanied by a Deferred instance in the args tuple pointing
- at the Deferred which is chained to the Deferred which has this marker.
-"""
-
-import traceback
-import types
-import warnings
-from sys import exc_info
-
-# Twisted imports
-from twisted.python import log, failure, lockfile
-from twisted.python.util import unsignedID, mergeFunctionMetadata
-
-
-
-class AlreadyCalledError(Exception):
- pass
-
-
-class CancelledError(Exception):
- """
- This error is raised by default when a L{Deferred} is cancelled.
- """
-
-
-class TimeoutError(Exception):
- """
- This exception is deprecated. It is used only by the deprecated
- L{Deferred.setTimeout} method.
- """
-
-
-
-def logError(err):
- log.err(err)
- return err
-
-
-
-def succeed(result):
- """
- Return a L{Deferred} that has already had C{.callback(result)} called.
-
- This is useful when you're writing synchronous code to an
- asynchronous interface: i.e., some code is calling you expecting a
- L{Deferred} result, but you don't actually need to do anything
- asynchronous. Just return C{defer.succeed(theResult)}.
-
- See L{fail} for a version of this function that uses a failing
- L{Deferred} rather than a successful one.
-
- @param result: The result to give to the Deferred's 'callback'
- method.
-
- @rtype: L{Deferred}
- """
- d = Deferred()
- d.callback(result)
- return d
-
-
-
-def fail(result=None):
- """
- Return a L{Deferred} that has already had C{.errback(result)} called.
-
- See L{succeed}'s docstring for rationale.
-
- @param result: The same argument that L{Deferred.errback} takes.
-
- @raise NoCurrentExceptionError: If C{result} is C{None} but there is no
- current exception state.
-
- @rtype: L{Deferred}
- """
- d = Deferred()
- d.errback(result)
- return d
-
-
-
-def execute(callable, *args, **kw):
- """
- Create a L{Deferred} from a callable and arguments.
-
- Call the given function with the given arguments. Return a L{Deferred}
- which has been fired with its callback as the result of that invocation
- or its C{errback} with a L{Failure} for the exception thrown.
- """
- try:
- result = callable(*args, **kw)
- except:
- return fail()
- else:
- return succeed(result)
-
-
-
-def maybeDeferred(f, *args, **kw):
- """
- Invoke a function that may or may not return a L{Deferred}.
-
- Call the given function with the given arguments. If the returned
- object is a L{Deferred}, return it. If the returned object is a L{Failure},
- wrap it with L{fail} and return it. Otherwise, wrap it in L{succeed} and
- return it. If an exception is raised, convert it to a L{Failure}, wrap it
- in L{fail}, and then return it.
-
- @type f: Any callable
- @param f: The callable to invoke
-
- @param args: The arguments to pass to C{f}
- @param kw: The keyword arguments to pass to C{f}
-
- @rtype: L{Deferred}
- @return: The result of the function call, wrapped in a L{Deferred} if
- necessary.
- """
- try:
- result = f(*args, **kw)
- except:
- return fail(failure.Failure(captureVars=Deferred.debug))
-
- if isinstance(result, Deferred):
- return result
- elif isinstance(result, failure.Failure):
- return fail(result)
- else:
- return succeed(result)
-
-
-
-def timeout(deferred):
- deferred.errback(failure.Failure(TimeoutError("Callback timed out")))
-
-
-
-def passthru(arg):
- return arg
-
-
-
-def setDebugging(on):
- """
- Enable or disable L{Deferred} debugging.
-
- When debugging is on, the call stacks from creation and invocation are
- recorded, and added to any L{AlreadyCalledErrors} we raise.
- """
- Deferred.debug=bool(on)
-
-
-
-def getDebugging():
- """
- Determine whether L{Deferred} debugging is enabled.
- """
- return Deferred.debug
-
-
-# See module docstring.
-_NO_RESULT = object()
-_CONTINUE = object()
-
-
-
-class Deferred:
- """
- This is a callback which will be put off until later.
-
- Why do we want this? Well, in cases where a function in a threaded
- program would block until it gets a result, for Twisted it should
- not block. Instead, it should return a L{Deferred}.
-
- This can be implemented for protocols that run over the network by
- writing an asynchronous protocol for L{twisted.internet}. For methods
- that come from outside packages that are not under our control, we use
- threads (see for example L{twisted.enterprise.adbapi}).
-
- For more information about Deferreds, see doc/core/howto/defer.html or
- U{http://twistedmatrix.com/documents/current/core/howto/defer.html}
-
- When creating a Deferred, you may provide a canceller function, which
- will be called by d.cancel() to let you do any clean-up necessary if the
- user decides not to wait for the deferred to complete.
-
- @ivar called: A flag which is C{False} until either C{callback} or
- C{errback} is called and afterwards always C{True}.
- @type called: C{bool}
-
- @ivar paused: A counter of how many unmatched C{pause} calls have been made
- on this instance.
- @type paused: C{int}
-
- @ivar _suppressAlreadyCalled: A flag used by the cancellation mechanism
- which is C{True} if the Deferred has no canceller and has been
- cancelled, C{False} otherwise. If C{True}, it can be expected that
- C{callback} or C{errback} will eventually be called and the result
- should be silently discarded.
- @type _suppressAlreadyCalled: C{bool}
-
- @ivar _runningCallbacks: A flag which is C{True} while this instance is
- executing its callback chain, used to stop recursive execution of
- L{_runCallbacks}
- @type _runningCallbacks: C{bool}
-
- @ivar _chainedTo: If this Deferred is waiting for the result of another
- Deferred, this is a reference to the other Deferred. Otherwise, C{None}.
- """
-
- called = False
- paused = 0
- _debugInfo = None
- _suppressAlreadyCalled = False
-
- # Are we currently running a user-installed callback? Meant to prevent
- # recursive running of callbacks when a reentrant call to add a callback is
- # used.
- _runningCallbacks = False
-
- # Keep this class attribute for now, for compatibility with code that
- # sets it directly.
- debug = False
-
- _chainedTo = None
-
- def __init__(self, canceller=None):
- """
- Initialize a L{Deferred}.
-
- @param canceller: a callable used to stop the pending operation
- scheduled by this L{Deferred} when L{Deferred.cancel} is
- invoked. The canceller will be passed the deferred whose
- cancelation is requested (i.e., self).
-
- If a canceller is not given, or does not invoke its argument's
- C{callback} or C{errback} method, L{Deferred.cancel} will
- invoke L{Deferred.errback} with a L{CancelledError}.
-
- Note that if a canceller is not given, C{callback} or
- C{errback} may still be invoked exactly once, even though
- defer.py will have already invoked C{errback}, as described
- above. This allows clients of code which returns a L{Deferred}
- to cancel it without requiring the L{Deferred} instantiator to
- provide any specific implementation support for cancellation.
- New in 10.1.
-
- @type canceller: a 1-argument callable which takes a L{Deferred}. The
- return result is ignored.
- """
- self.callbacks = []
- self._canceller = canceller
- if self.debug:
- self._debugInfo = DebugInfo()
- self._debugInfo.creator = traceback.format_stack()[:-1]
-
-
- def addCallbacks(self, callback, errback=None,
- callbackArgs=None, callbackKeywords=None,
- errbackArgs=None, errbackKeywords=None):
- """
- Add a pair of callbacks (success and error) to this L{Deferred}.
-
- These will be executed when the 'master' callback is run.
-
- @return: C{self}.
- @rtype: a L{Deferred}
- """
- assert callable(callback)
- assert errback == None or callable(errback)
- cbs = ((callback, callbackArgs, callbackKeywords),
- (errback or (passthru), errbackArgs, errbackKeywords))
- self.callbacks.append(cbs)
-
- if self.called:
- self._runCallbacks()
- return self
-
-
- def addCallback(self, callback, *args, **kw):
- """
- Convenience method for adding just a callback.
-
- See L{addCallbacks}.
- """
- return self.addCallbacks(callback, callbackArgs=args,
- callbackKeywords=kw)
-
-
- def addErrback(self, errback, *args, **kw):
- """
- Convenience method for adding just an errback.
-
- See L{addCallbacks}.
- """
- return self.addCallbacks(passthru, errback,
- errbackArgs=args,
- errbackKeywords=kw)
-
-
- def addBoth(self, callback, *args, **kw):
- """
- Convenience method for adding a single callable as both a callback
- and an errback.
-
- See L{addCallbacks}.
- """
- return self.addCallbacks(callback, callback,
- callbackArgs=args, errbackArgs=args,
- callbackKeywords=kw, errbackKeywords=kw)
-
-
- def chainDeferred(self, d):
- """
- Chain another L{Deferred} to this L{Deferred}.
-
- This method adds callbacks to this L{Deferred} to call C{d}'s callback
- or errback, as appropriate. It is merely a shorthand way of performing
- the following::
-
- self.addCallbacks(d.callback, d.errback)
-
- When you chain a deferred d2 to another deferred d1 with
- d1.chainDeferred(d2), you are making d2 participate in the callback
- chain of d1. Thus any event that fires d1 will also fire d2.
- However, the converse is B{not} true; if d2 is fired d1 will not be
- affected.
-
- Note that unlike the case where chaining is caused by a L{Deferred}
- being returned from a callback, it is possible to cause the call
- stack size limit to be exceeded by chaining many L{Deferred}s
- together with C{chainDeferred}.
-
- @return: C{self}.
- @rtype: a L{Deferred}
- """
- d._chainedTo = self
- return self.addCallbacks(d.callback, d.errback)
-
-
- def callback(self, result):
- """
- Run all success callbacks that have been added to this L{Deferred}.
-
- Each callback will have its result passed as the first argument to
- the next; this way, the callbacks act as a 'processing chain'. If
- the success-callback returns a L{Failure} or raises an L{Exception},
- processing will continue on the *error* callback chain. If a
- callback (or errback) returns another L{Deferred}, this L{Deferred}
- will be chained to it (and further callbacks will not run until that
- L{Deferred} has a result).
- """
- assert not isinstance(result, Deferred)
- self._startRunCallbacks(result)
-
-
- def errback(self, fail=None):
- """
- Run all error callbacks that have been added to this L{Deferred}.
-
- Each callback will have its result passed as the first
- argument to the next; this way, the callbacks act as a
- 'processing chain'. Also, if the error-callback returns a non-Failure
- or doesn't raise an L{Exception}, processing will continue on the
- *success*-callback chain.
-
- If the argument that's passed to me is not a L{failure.Failure} instance,
- it will be embedded in one. If no argument is passed, a
- L{failure.Failure} instance will be created based on the current
- traceback stack.
-
- Passing a string as `fail' is deprecated, and will be punished with
- a warning message.
-
- @raise NoCurrentExceptionError: If C{fail} is C{None} but there is
- no current exception state.
- """
- if fail is None:
- fail = failure.Failure(captureVars=self.debug)
- elif not isinstance(fail, failure.Failure):
- fail = failure.Failure(fail)
-
- self._startRunCallbacks(fail)
-
-
- def pause(self):
- """
- Stop processing on a L{Deferred} until L{unpause}() is called.
- """
- self.paused = self.paused + 1
-
-
- def unpause(self):
- """
- Process all callbacks made since L{pause}() was called.
- """
- self.paused = self.paused - 1
- if self.paused:
- return
- if self.called:
- self._runCallbacks()
-
-
- def cancel(self):
- """
- Cancel this L{Deferred}.
-
- If the L{Deferred} has not yet had its C{errback} or C{callback} method
- invoked, call the canceller function provided to the constructor. If
- that function does not invoke C{callback} or C{errback}, or if no
- canceller function was provided, errback with L{CancelledError}.
-
- If this L{Deferred} is waiting on another L{Deferred}, forward the
- cancellation to the other L{Deferred}.
- """
- if not self.called:
- canceller = self._canceller
- if canceller:
- canceller(self)
- else:
- # Arrange to eat the callback that will eventually be fired
- # since there was no real canceller.
- self._suppressAlreadyCalled = True
- if not self.called:
- # There was no canceller, or the canceller didn't call
- # callback or errback.
- self.errback(failure.Failure(CancelledError()))
- elif isinstance(self.result, Deferred):
- # Waiting for another deferred -- cancel it instead.
- self.result.cancel()
-
-
- def _startRunCallbacks(self, result):
- if self.called:
- if self._suppressAlreadyCalled:
- self._suppressAlreadyCalled = False
- return
- if self.debug:
- if self._debugInfo is None:
- self._debugInfo = DebugInfo()
- extra = "\n" + self._debugInfo._getDebugTracebacks()
- raise AlreadyCalledError(extra)
- raise AlreadyCalledError
- if self.debug:
- if self._debugInfo is None:
- self._debugInfo = DebugInfo()
- self._debugInfo.invoker = traceback.format_stack()[:-2]
- self.called = True
- self.result = result
- self._runCallbacks()
-
-
- def _continuation(self):
- """
- Build a tuple of callback and errback with L{_continue} to be used by
- L{_addContinue} and L{_removeContinue} on another Deferred.
- """
- return ((_CONTINUE, (self,), None),
- (_CONTINUE, (self,), None))
-
-
- def _runCallbacks(self):
- """
- Run the chain of callbacks once a result is available.
-
- This consists of a simple loop over all of the callbacks, calling each
- with the current result and making the current result equal to the
- return value (or raised exception) of that call.
-
- If C{self._runningCallbacks} is true, this loop won't run at all, since
- it is already running above us on the call stack. If C{self.paused} is
- true, the loop also won't run, because that's what it means to be
- paused.
-
- The loop will terminate before processing all of the callbacks if a
- C{Deferred} without a result is encountered.
-
- If a C{Deferred} I{with} a result is encountered, that result is taken
- and the loop proceeds.
-
- @note: The implementation is complicated slightly by the fact that
- chaining (associating two Deferreds with each other such that one
- will wait for the result of the other, as happens when a Deferred is
- returned from a callback on another Deferred) is supported
- iteratively rather than recursively, to avoid running out of stack
- frames when processing long chains.
- """
- if self._runningCallbacks:
- # Don't recursively run callbacks
- return
-
- # Keep track of all the Deferreds encountered while propagating results
- # up a chain. The way a Deferred gets onto this stack is by having
- # added its _continuation() to the callbacks list of a second Deferred
- # and then that second Deferred being fired. ie, if ever had _chainedTo
- # set to something other than None, you might end up on this stack.
- chain = [self]
-
- while chain:
- current = chain[-1]
-
- if current.paused:
- # This Deferred isn't going to produce a result at all. All the
- # Deferreds up the chain waiting on it will just have to...
- # wait.
- return
-
- finished = True
- current._chainedTo = None
- while current.callbacks:
- item = current.callbacks.pop(0)
- callback, args, kw = item[
- isinstance(current.result, failure.Failure)]
- args = args or ()
- kw = kw or {}
-
- # Avoid recursion if we can.
- if callback is _CONTINUE:
- # Give the waiting Deferred our current result and then
- # forget about that result ourselves.
- chainee = args[0]
- chainee.result = current.result
- current.result = None
- # Making sure to update _debugInfo
- if current._debugInfo is not None:
- current._debugInfo.failResult = None
- chainee.paused -= 1
- chain.append(chainee)
- # Delay cleaning this Deferred and popping it from the chain
- # until after we've dealt with chainee.
- finished = False
- break
-
- try:
- current._runningCallbacks = True
- try:
- current.result = callback(current.result, *args, **kw)
- finally:
- current._runningCallbacks = False
- except:
- # Including full frame information in the Failure is quite
- # expensive, so we avoid it unless self.debug is set.
- current.result = failure.Failure(captureVars=self.debug)
- else:
- if isinstance(current.result, Deferred):
- # The result is another Deferred. If it has a result,
- # we can take it and keep going.
- resultResult = getattr(current.result, 'result', _NO_RESULT)
- if resultResult is _NO_RESULT or isinstance(resultResult, Deferred) or current.result.paused:
- # Nope, it didn't. Pause and chain.
- current.pause()
- current._chainedTo = current.result
- # Note: current.result has no result, so it's not
- # running its callbacks right now. Therefore we can
- # append to the callbacks list directly instead of
- # using addCallbacks.
- current.result.callbacks.append(current._continuation())
- break
- else:
- # Yep, it did. Steal it.
- current.result.result = None
- # Make sure _debugInfo's failure state is updated.
- if current.result._debugInfo is not None:
- current.result._debugInfo.failResult = None
- current.result = resultResult
-
- if finished:
- # As much of the callback chain - perhaps all of it - as can be
- # processed right now has been. The current Deferred is waiting on
- # another Deferred or for more callbacks. Before finishing with it,
- # make sure its _debugInfo is in the proper state.
- if isinstance(current.result, failure.Failure):
- # Stash the Failure in the _debugInfo for unhandled error
- # reporting.
- current.result.cleanFailure()
- if current._debugInfo is None:
- current._debugInfo = DebugInfo()
- current._debugInfo.failResult = current.result
- else:
- # Clear out any Failure in the _debugInfo, since the result
- # is no longer a Failure.
- if current._debugInfo is not None:
- current._debugInfo.failResult = None
-
- # This Deferred is done, pop it from the chain and move back up
- # to the Deferred which supplied us with our result.
- chain.pop()
-
-
- def __str__(self):
- """
- Return a string representation of this C{Deferred}.
- """
- cname = self.__class__.__name__
- result = getattr(self, 'result', _NO_RESULT)
- myID = hex(unsignedID(self))
- if self._chainedTo is not None:
- result = ' waiting on Deferred at %s' % (hex(unsignedID(self._chainedTo)),)
- elif result is _NO_RESULT:
- result = ''
- else:
- result = ' current result: %r' % (result,)
- return "<%s at %s%s>" % (cname, myID, result)
- __repr__ = __str__
-
-
-
-class DebugInfo:
- """
- Deferred debug helper.
- """
-
- failResult = None
-
- def _getDebugTracebacks(self):
- info = ''
- if hasattr(self, "creator"):
- info += " C: Deferred was created:\n C:"
- info += "".join(self.creator).rstrip().replace("\n","\n C:")
- info += "\n"
- if hasattr(self, "invoker"):
- info += " I: First Invoker was:\n I:"
- info += "".join(self.invoker).rstrip().replace("\n","\n I:")
- info += "\n"
- return info
-
-
- def __del__(self):
- """
- Print tracebacks and die.
-
- If the *last* (and I do mean *last*) callback leaves me in an error
- state, print a traceback (if said errback is a L{Failure}).
- """
- if self.failResult is not None:
- log.msg("Unhandled error in Deferred:", isError=True)
- debugInfo = self._getDebugTracebacks()
- if debugInfo != '':
- log.msg("(debug: " + debugInfo + ")", isError=True)
- log.err(self.failResult)
-
-
-
-class FirstError(Exception):
- """
- First error to occur in a L{DeferredList} if C{fireOnOneErrback} is set.
-
- @ivar subFailure: The L{Failure} that occurred.
- @type subFailure: L{Failure}
-
- @ivar index: The index of the L{Deferred} in the L{DeferredList} where
- it happened.
- @type index: C{int}
- """
- def __init__(self, failure, index):
- Exception.__init__(self, failure, index)
- self.subFailure = failure
- self.index = index
-
-
- def __repr__(self):
- """
- The I{repr} of L{FirstError} instances includes the repr of the
- wrapped failure's exception and the index of the L{FirstError}.
- """
- return 'FirstError[#%d, %r]' % (self.index, self.subFailure.value)
-
-
- def __str__(self):
- """
- The I{str} of L{FirstError} instances includes the I{str} of the
- entire wrapped failure (including its traceback and exception) and
- the index of the L{FirstError}.
- """
- return 'FirstError[#%d, %s]' % (self.index, self.subFailure)
-
-
- def __cmp__(self, other):
- """
- Comparison between L{FirstError} and other L{FirstError} instances
- is defined as the comparison of the index and sub-failure of each
- instance. L{FirstError} instances don't compare equal to anything
- that isn't a L{FirstError} instance.
-
- @since: 8.2
- """
- if isinstance(other, FirstError):
- return cmp(
- (self.index, self.subFailure),
- (other.index, other.subFailure))
- return -1
-
-
-
-class DeferredList(Deferred):
- """
- L{DeferredList} is a tool for collecting the results of several Deferreds.
-
- This tracks a list of L{Deferred}s for their results, and makes a single
- callback when they have all completed. By default, the ultimate result is a
- list of (success, result) tuples, 'success' being a boolean.
- L{DeferredList} exposes the same API that L{Deferred} does, so callbacks and
- errbacks can be added to it in the same way.
-
- L{DeferredList} is implemented by adding callbacks and errbacks to each
- L{Deferred} in the list passed to it. This means callbacks and errbacks
- added to the Deferreds before they are passed to L{DeferredList} will change
- the result that L{DeferredList} sees (i.e., L{DeferredList} is not special).
- Callbacks and errbacks can also be added to the Deferreds after they are
- passed to L{DeferredList} and L{DeferredList} may change the result that
- they see.
-
- See the documentation for the C{__init__} arguments for more information.
- """
-
- fireOnOneCallback = False
- fireOnOneErrback = False
-
- def __init__(self, deferredList, fireOnOneCallback=False,
- fireOnOneErrback=False, consumeErrors=False):
- """
- Initialize a DeferredList.
-
- @param deferredList: The list of deferreds to track.
- @type deferredList: C{list} of L{Deferred}s
-
- @param fireOnOneCallback: (keyword param) a flag indicating that this
- L{DeferredList} will fire when the first L{Deferred} in
- C{deferredList} fires with a non-failure result without waiting for
- any of the other Deferreds. When this flag is set, the DeferredList
- will fire with a two-tuple: the first element is the result of the
- Deferred which fired; the second element is the index in
- C{deferredList} of that Deferred.
- @type fireOnOneCallback: C{bool}
-
- @param fireOnOneErrback: (keyword param) a flag indicating that this
- L{DeferredList} will fire when the first L{Deferred} in
- C{deferredList} fires with a failure result without waiting for any
- of the other Deferreds. When this flag is set, if a Deferred in the
- list errbacks, the DeferredList will errback with a L{FirstError}
- failure wrapping the failure of that Deferred.
- @type fireOnOneErrback: C{bool}
-
- @param consumeErrors: (keyword param) a flag indicating that failures in
- any of the included L{Deferreds} should not be propagated to
- errbacks added to the individual L{Deferreds} after this
- L{DeferredList} is constructed. After constructing the
- L{DeferredList}, any errors in the individual L{Deferred}s will be
- converted to a callback result of C{None}. This is useful to
- prevent spurious 'Unhandled error in Deferred' messages from being
- logged. This does not prevent C{fireOnOneErrback} from working.
- @type consumeErrors: C{bool}
- """
- self.resultList = [None] * len(deferredList)
- Deferred.__init__(self)
- if len(deferredList) == 0 and not fireOnOneCallback:
- self.callback(self.resultList)
-
- # These flags need to be set *before* attaching callbacks to the
- # deferreds, because the callbacks use these flags, and will run
- # synchronously if any of the deferreds are already fired.
- self.fireOnOneCallback = fireOnOneCallback
- self.fireOnOneErrback = fireOnOneErrback
- self.consumeErrors = consumeErrors
- self.finishedCount = 0
-
- index = 0
- for deferred in deferredList:
- deferred.addCallbacks(self._cbDeferred, self._cbDeferred,
- callbackArgs=(index,SUCCESS),
- errbackArgs=(index,FAILURE))
- index = index + 1
-
-
- def _cbDeferred(self, result, index, succeeded):
- """
- (internal) Callback for when one of my deferreds fires.
- """
- self.resultList[index] = (succeeded, result)
-
- self.finishedCount += 1
- if not self.called:
- if succeeded == SUCCESS and self.fireOnOneCallback:
- self.callback((result, index))
- elif succeeded == FAILURE and self.fireOnOneErrback:
- self.errback(failure.Failure(FirstError(result, index)))
- elif self.finishedCount == len(self.resultList):
- self.callback(self.resultList)
-
- if succeeded == FAILURE and self.consumeErrors:
- result = None
-
- return result
-
-
-
-def _parseDListResult(l, fireOnOneErrback=False):
- if __debug__:
- for success, value in l:
- assert success
- return [x[1] for x in l]
-
-
-
-def gatherResults(deferredList, consumeErrors=False):
- """
- Returns, via a L{Deferred}, a list with the results of the given
- L{Deferred}s - in effect, a "join" of multiple deferred operations.
-
- The returned L{Deferred} will fire when I{all} of the provided L{Deferred}s
- have fired, or when any one of them has failed.
-
- This differs from L{DeferredList} in that you don't need to parse
- the result for success/failure.
-
- @type deferredList: C{list} of L{Deferred}s
-
- @param consumeErrors: (keyword param) a flag, defaulting to False,
- indicating that failures in any of the given L{Deferreds} should not be
- propagated to errbacks added to the individual L{Deferreds} after this
- L{gatherResults} invocation. Any such errors in the individual
- L{Deferred}s will be converted to a callback result of C{None}. This
- is useful to prevent spurious 'Unhandled error in Deferred' messages
- from being logged. This parameter is available since 11.1.0.
- @type consumeErrors: C{bool}
- """
- d = DeferredList(deferredList, fireOnOneErrback=True,
- consumeErrors=consumeErrors)
- d.addCallback(_parseDListResult)
- return d
-
-
-
-# Constants for use with DeferredList
-
-SUCCESS = True
-FAILURE = False
-
-
-
-## deferredGenerator
-
-class waitForDeferred:
- """
- See L{deferredGenerator}.
- """
-
- def __init__(self, d):
- if not isinstance(d, Deferred):
- raise TypeError("You must give waitForDeferred a Deferred. You gave it %r." % (d,))
- self.d = d
-
-
- def getResult(self):
- if isinstance(self.result, failure.Failure):
- self.result.raiseException()
- return self.result
-
-
-
-def _deferGenerator(g, deferred):
- """
- See L{deferredGenerator}.
- """
- result = None
-
- # This function is complicated by the need to prevent unbounded recursion
- # arising from repeatedly yielding immediately ready deferreds. This while
- # loop and the waiting variable solve that by manually unfolding the
- # recursion.
-
- waiting = [True, # defgen is waiting for result?
- None] # result
-
- while 1:
- try:
- result = g.next()
- except StopIteration:
- deferred.callback(result)
- return deferred
- except:
- deferred.errback()
- return deferred
-
- # Deferred.callback(Deferred) raises an error; we catch this case
- # early here and give a nicer error message to the user in case
- # they yield a Deferred.
- if isinstance(result, Deferred):
- return fail(TypeError("Yield waitForDeferred(d), not d!"))
-
- if isinstance(result, waitForDeferred):
- # a waitForDeferred was yielded, get the result.
- # Pass result in so it don't get changed going around the loop
- # This isn't a problem for waiting, as it's only reused if
- # gotResult has already been executed.
- def gotResult(r, result=result):
- result.result = r
- if waiting[0]:
- waiting[0] = False
- waiting[1] = r
- else:
- _deferGenerator(g, deferred)
- result.d.addBoth(gotResult)
- if waiting[0]:
- # Haven't called back yet, set flag so that we get reinvoked
- # and return from the loop
- waiting[0] = False
- return deferred
- # Reset waiting to initial values for next loop
- waiting[0] = True
- waiting[1] = None
-
- result = None
-
-
-
-def deferredGenerator(f):
- """
- deferredGenerator and waitForDeferred help you write L{Deferred}-using code
- that looks like a regular sequential function. If your code has a minimum
- requirement of Python 2.5, consider the use of L{inlineCallbacks} instead,
- which can accomplish the same thing in a more concise manner.
-
- There are two important functions involved: L{waitForDeferred}, and
- L{deferredGenerator}. They are used together, like this::
-
- @deferredGenerator
- def thingummy():
- thing = waitForDeferred(makeSomeRequestResultingInDeferred())
- yield thing
- thing = thing.getResult()
- print thing #the result! hoorj!
-
- L{waitForDeferred} returns something that you should immediately yield; when
- your generator is resumed, calling C{thing.getResult()} will either give you
- the result of the L{Deferred} if it was a success, or raise an exception if it
- was a failure. Calling C{getResult} is B{absolutely mandatory}. If you do
- not call it, I{your program will not work}.
-
- L{deferredGenerator} takes one of these waitForDeferred-using generator
- functions and converts it into a function that returns a L{Deferred}. The
- result of the L{Deferred} will be the last value that your generator yielded
- unless the last value is a L{waitForDeferred} instance, in which case the
- result will be C{None}. If the function raises an unhandled exception, the
- L{Deferred} will errback instead. Remember that C{return result} won't work;
- use C{yield result; return} in place of that.
-
- Note that not yielding anything from your generator will make the L{Deferred}
- result in C{None}. Yielding a L{Deferred} from your generator is also an error
- condition; always yield C{waitForDeferred(d)} instead.
-
- The L{Deferred} returned from your deferred generator may also errback if your
- generator raised an exception. For example::
-
- @deferredGenerator
- def thingummy():
- thing = waitForDeferred(makeSomeRequestResultingInDeferred())
- yield thing
- thing = thing.getResult()
- if thing == 'I love Twisted':
- # will become the result of the Deferred
- yield 'TWISTED IS GREAT!'
- return
- else:
- # will trigger an errback
- raise Exception('DESTROY ALL LIFE')
-
- Put succinctly, these functions connect deferred-using code with this 'fake
- blocking' style in both directions: L{waitForDeferred} converts from a
- L{Deferred} to the 'blocking' style, and L{deferredGenerator} converts from the
- 'blocking' style to a L{Deferred}.
- """
-
- def unwindGenerator(*args, **kwargs):
- return _deferGenerator(f(*args, **kwargs), Deferred())
- return mergeFunctionMetadata(f, unwindGenerator)
-
-
-## inlineCallbacks
-
-# BaseException is only in Py 2.5.
-try:
- BaseException
-except NameError:
- BaseException=Exception
-
-
-
-class _DefGen_Return(BaseException):
- def __init__(self, value):
- self.value = value
-
-
-
-def returnValue(val):
- """
- Return val from a L{inlineCallbacks} generator.
-
- Note: this is currently implemented by raising an exception
- derived from L{BaseException}. You might want to change any
- 'except:' clauses to an 'except Exception:' clause so as not to
- catch this exception.
-
- Also: while this function currently will work when called from
- within arbitrary functions called from within the generator, do
- not rely upon this behavior.
- """
- raise _DefGen_Return(val)
-
-
-
-def _inlineCallbacks(result, g, deferred):
- """
- See L{inlineCallbacks}.
- """
- # This function is complicated by the need to prevent unbounded recursion
- # arising from repeatedly yielding immediately ready deferreds. This while
- # loop and the waiting variable solve that by manually unfolding the
- # recursion.
-
- waiting = [True, # waiting for result?
- None] # result
-
- while 1:
- try:
- # Send the last result back as the result of the yield expression.
- isFailure = isinstance(result, failure.Failure)
- if isFailure:
- result = result.throwExceptionIntoGenerator(g)
- else:
- result = g.send(result)
- except StopIteration:
- # fell off the end, or "return" statement
- deferred.callback(None)
- return deferred
- except _DefGen_Return, e:
- # returnValue() was called; time to give a result to the original
- # Deferred. First though, let's try to identify the potentially
- # confusing situation which results when returnValue() is
- # accidentally invoked from a different function, one that wasn't
- # decorated with @inlineCallbacks.
-
- # The traceback starts in this frame (the one for
- # _inlineCallbacks); the next one down should be the application
- # code.
- appCodeTrace = exc_info()[2].tb_next
- if isFailure:
- # If we invoked this generator frame by throwing an exception
- # into it, then throwExceptionIntoGenerator will consume an
- # additional stack frame itself, so we need to skip that too.
- appCodeTrace = appCodeTrace.tb_next
- # Now that we've identified the frame being exited by the
- # exception, let's figure out if returnValue was called from it
- # directly. returnValue itself consumes a stack frame, so the
- # application code will have a tb_next, but it will *not* have a
- # second tb_next.
- if appCodeTrace.tb_next.tb_next:
- # If returnValue was invoked non-local to the frame which it is
- # exiting, identify the frame that ultimately invoked
- # returnValue so that we can warn the user, as this behavior is
- # confusing.
- ultimateTrace = appCodeTrace
- while ultimateTrace.tb_next.tb_next:
- ultimateTrace = ultimateTrace.tb_next
- filename = ultimateTrace.tb_frame.f_code.co_filename
- lineno = ultimateTrace.tb_lineno
- warnings.warn_explicit(
- "returnValue() in %r causing %r to exit: "
- "returnValue should only be invoked by functions decorated "
- "with inlineCallbacks" % (
- ultimateTrace.tb_frame.f_code.co_name,
- appCodeTrace.tb_frame.f_code.co_name),
- DeprecationWarning, filename, lineno)
- deferred.callback(e.value)
- return deferred
- except:
- deferred.errback()
- return deferred
-
- if isinstance(result, Deferred):
- # a deferred was yielded, get the result.
- def gotResult(r):
- if waiting[0]:
- waiting[0] = False
- waiting[1] = r
- else:
- _inlineCallbacks(r, g, deferred)
-
- result.addBoth(gotResult)
- if waiting[0]:
- # Haven't called back yet, set flag so that we get reinvoked
- # and return from the loop
- waiting[0] = False
- return deferred
-
- result = waiting[1]
- # Reset waiting to initial values for next loop. gotResult uses
- # waiting, but this isn't a problem because gotResult is only
- # executed once, and if it hasn't been executed yet, the return
- # branch above would have been taken.
-
-
- waiting[0] = True
- waiting[1] = None
-
-
- return deferred
-
-
-
-def inlineCallbacks(f):
- """
- WARNING: this function will not work in Python 2.4 and earlier!
-
- inlineCallbacks helps you write Deferred-using code that looks like a
- regular sequential function. This function uses features of Python 2.5
- generators. If you need to be compatible with Python 2.4 or before, use
- the L{deferredGenerator} function instead, which accomplishes the same
- thing, but with somewhat more boilerplate. For example::
-
- @inlineCallBacks
- def thingummy():
- thing = yield makeSomeRequestResultingInDeferred()
- print thing #the result! hoorj!
-
- When you call anything that results in a L{Deferred}, you can simply yield it;
- your generator will automatically be resumed when the Deferred's result is
- available. The generator will be sent the result of the L{Deferred} with the
- 'send' method on generators, or if the result was a failure, 'throw'.
-
- Things that are not L{Deferred}s may also be yielded, and your generator
- will be resumed with the same object sent back. This means C{yield}
- performs an operation roughly equivalent to L{maybeDeferred}.
-
- Your inlineCallbacks-enabled generator will return a L{Deferred} object, which
- will result in the return value of the generator (or will fail with a
- failure object if your generator raises an unhandled exception). Note that
- you can't use C{return result} to return a value; use C{returnValue(result)}
- instead. Falling off the end of the generator, or simply using C{return}
- will cause the L{Deferred} to have a result of C{None}.
-
- Be aware that L{returnValue} will not accept a L{Deferred} as a parameter.
- If you believe the thing you'd like to return could be a L{Deferred}, do
- this::
-
- result = yield result
- returnValue(result)
-
- The L{Deferred} returned from your deferred generator may errback if your
- generator raised an exception::
-
- @inlineCallbacks
- def thingummy():
- thing = yield makeSomeRequestResultingInDeferred()
- if thing == 'I love Twisted':
- # will become the result of the Deferred
- returnValue('TWISTED IS GREAT!')
- else:
- # will trigger an errback
- raise Exception('DESTROY ALL LIFE')
- """
- def unwindGenerator(*args, **kwargs):
- try:
- gen = f(*args, **kwargs)
- except _DefGen_Return:
- raise TypeError(
- "inlineCallbacks requires %r to produce a generator; instead"
- "caught returnValue being used in a non-generator" % (f,))
- if not isinstance(gen, types.GeneratorType):
- raise TypeError(
- "inlineCallbacks requires %r to produce a generator; "
- "instead got %r" % (f, gen))
- return _inlineCallbacks(None, gen, Deferred())
- return mergeFunctionMetadata(f, unwindGenerator)
-
-
-## DeferredLock/DeferredQueue
-
-class _ConcurrencyPrimitive(object):
- def __init__(self):
- self.waiting = []
-
-
- def _releaseAndReturn(self, r):
- self.release()
- return r
-
-
- def run(*args, **kwargs):
- """
- Acquire, run, release.
-
- This function takes a callable as its first argument and any
- number of other positional and keyword arguments. When the
- lock or semaphore is acquired, the callable will be invoked
- with those arguments.
-
- The callable may return a L{Deferred}; if it does, the lock or
- semaphore won't be released until that L{Deferred} fires.
-
- @return: L{Deferred} of function result.
- """
- if len(args) < 2:
- if not args:
- raise TypeError("run() takes at least 2 arguments, none given.")
- raise TypeError("%s.run() takes at least 2 arguments, 1 given" % (
- args[0].__class__.__name__,))
- self, f = args[:2]
- args = args[2:]
-
- def execute(ignoredResult):
- d = maybeDeferred(f, *args, **kwargs)
- d.addBoth(self._releaseAndReturn)
- return d
-
- d = self.acquire()
- d.addCallback(execute)
- return d
-
-
-
-class DeferredLock(_ConcurrencyPrimitive):
- """
- A lock for event driven systems.
-
- @ivar locked: C{True} when this Lock has been acquired, false at all other
- times. Do not change this value, but it is useful to examine for the
- equivalent of a "non-blocking" acquisition.
- """
-
- locked = False
-
-
- def _cancelAcquire(self, d):
- """
- Remove a deferred d from our waiting list, as the deferred has been
- canceled.
-
- Note: We do not need to wrap this in a try/except to catch d not
- being in self.waiting because this canceller will not be called if
- d has fired. release() pops a deferred out of self.waiting and
- calls it, so the canceller will no longer be called.
-
- @param d: The deferred that has been canceled.
- """
- self.waiting.remove(d)
-
-
- def acquire(self):
- """
- Attempt to acquire the lock. Returns a L{Deferred} that fires on
- lock acquisition with the L{DeferredLock} as the value. If the lock
- is locked, then the Deferred is placed at the end of a waiting list.
-
- @return: a L{Deferred} which fires on lock acquisition.
- @rtype: a L{Deferred}
- """
- d = Deferred(canceller=self._cancelAcquire)
- if self.locked:
- self.waiting.append(d)
- else:
- self.locked = True
- d.callback(self)
- return d
-
-
- def release(self):
- """
- Release the lock. If there is a waiting list, then the first
- L{Deferred} in that waiting list will be called back.
-
- Should be called by whomever did the L{acquire}() when the shared
- resource is free.
- """
- assert self.locked, "Tried to release an unlocked lock"
- self.locked = False
- if self.waiting:
- # someone is waiting to acquire lock
- self.locked = True
- d = self.waiting.pop(0)
- d.callback(self)
-
-
-
-class DeferredSemaphore(_ConcurrencyPrimitive):
- """
- A semaphore for event driven systems.
-
- @ivar tokens: At most this many users may acquire this semaphore at
- once.
- @type tokens: C{int}
-
- @ivar limit: The difference between C{tokens} and the number of users
- which have currently acquired this semaphore.
- @type limit: C{int}
- """
-
- def __init__(self, tokens):
- _ConcurrencyPrimitive.__init__(self)
- if tokens < 1:
- raise ValueError("DeferredSemaphore requires tokens >= 1")
- self.tokens = tokens
- self.limit = tokens
-
-
- def _cancelAcquire(self, d):
- """
- Remove a deferred d from our waiting list, as the deferred has been
- canceled.
-
- Note: We do not need to wrap this in a try/except to catch d not
- being in self.waiting because this canceller will not be called if
- d has fired. release() pops a deferred out of self.waiting and
- calls it, so the canceller will no longer be called.
-
- @param d: The deferred that has been canceled.
- """
- self.waiting.remove(d)
-
-
- def acquire(self):
- """
- Attempt to acquire the token.
-
- @return: a L{Deferred} which fires on token acquisition.
- """
- assert self.tokens >= 0, "Internal inconsistency?? tokens should never be negative"
- d = Deferred(canceller=self._cancelAcquire)
- if not self.tokens:
- self.waiting.append(d)
- else:
- self.tokens = self.tokens - 1
- d.callback(self)
- return d
-
-
- def release(self):
- """
- Release the token.
-
- Should be called by whoever did the L{acquire}() when the shared
- resource is free.
- """
- assert self.tokens < self.limit, "Someone released me too many times: too many tokens!"
- self.tokens = self.tokens + 1
- if self.waiting:
- # someone is waiting to acquire token
- self.tokens = self.tokens - 1
- d = self.waiting.pop(0)
- d.callback(self)
-
-
-
-class QueueOverflow(Exception):
- pass
-
-
-
-class QueueUnderflow(Exception):
- pass
-
-
-
-class DeferredQueue(object):
- """
- An event driven queue.
-
- Objects may be added as usual to this queue. When an attempt is
- made to retrieve an object when the queue is empty, a L{Deferred} is
- returned which will fire when an object becomes available.
-
- @ivar size: The maximum number of objects to allow into the queue
- at a time. When an attempt to add a new object would exceed this
- limit, L{QueueOverflow} is raised synchronously. C{None} for no limit.
-
- @ivar backlog: The maximum number of L{Deferred} gets to allow at
- one time. When an attempt is made to get an object which would
- exceed this limit, L{QueueUnderflow} is raised synchronously. C{None}
- for no limit.
- """
-
- def __init__(self, size=None, backlog=None):
- self.waiting = []
- self.pending = []
- self.size = size
- self.backlog = backlog
-
-
- def _cancelGet(self, d):
- """
- Remove a deferred d from our waiting list, as the deferred has been
- canceled.
-
- Note: We do not need to wrap this in a try/except to catch d not
- being in self.waiting because this canceller will not be called if
- d has fired. put() pops a deferred out of self.waiting and calls
- it, so the canceller will no longer be called.
-
- @param d: The deferred that has been canceled.
- """
- self.waiting.remove(d)
-
-
- def put(self, obj):
- """
- Add an object to this queue.
-
- @raise QueueOverflow: Too many objects are in this queue.
- """
- if self.waiting:
- self.waiting.pop(0).callback(obj)
- elif self.size is None or len(self.pending) < self.size:
- self.pending.append(obj)
- else:
- raise QueueOverflow()
-
-
- def get(self):
- """
- Attempt to retrieve and remove an object from the queue.
-
- @return: a L{Deferred} which fires with the next object available in
- the queue.
-
- @raise QueueUnderflow: Too many (more than C{backlog})
- L{Deferred}s are already waiting for an object from this queue.
- """
- if self.pending:
- return succeed(self.pending.pop(0))
- elif self.backlog is None or len(self.waiting) < self.backlog:
- d = Deferred(canceller=self._cancelGet)
- self.waiting.append(d)
- return d
- else:
- raise QueueUnderflow()
-
-
-
-class AlreadyTryingToLockError(Exception):
- """
- Raised when L{DeferredFilesystemLock.deferUntilLocked} is called twice on a
- single L{DeferredFilesystemLock}.
- """
-
-
-
-class DeferredFilesystemLock(lockfile.FilesystemLock):
- """
- A L{FilesystemLock} that allows for a L{Deferred} to be fired when the lock is
- acquired.
-
- @ivar _scheduler: The object in charge of scheduling retries. In this
- implementation this is parameterized for testing.
-
- @ivar _interval: The retry interval for an L{IReactorTime} based scheduler.
-
- @ivar _tryLockCall: A L{DelayedCall} based on C{_interval} that will manage
- the next retry for aquiring the lock.
-
- @ivar _timeoutCall: A L{DelayedCall} based on C{deferUntilLocked}'s timeout
- argument. This is in charge of timing out our attempt to acquire the
- lock.
- """
- _interval = 1
- _tryLockCall = None
- _timeoutCall = None
-
-
- def __init__(self, name, scheduler=None):
- """
- @param name: The name of the lock to acquire
- @param scheduler: An object which provides L{IReactorTime}
- """
- lockfile.FilesystemLock.__init__(self, name)
-
- if scheduler is None:
- from twisted.internet import reactor
- scheduler = reactor
-
- self._scheduler = scheduler
-
-
- def deferUntilLocked(self, timeout=None):
- """
- Wait until we acquire this lock. This method is not safe for
- concurrent use.
-
- @type timeout: C{float} or C{int}
- @param timeout: the number of seconds after which to time out if the
- lock has not been acquired.
-
- @return: a L{Deferred} which will callback when the lock is acquired, or
- errback with a L{TimeoutError} after timing out or an
- L{AlreadyTryingToLockError} if the L{deferUntilLocked} has already
- been called and not successfully locked the file.
- """
- if self._tryLockCall is not None:
- return fail(
- AlreadyTryingToLockError(
- "deferUntilLocked isn't safe for concurrent use."))
-
- d = Deferred()
-
- def _cancelLock():
- self._tryLockCall.cancel()
- self._tryLockCall = None
- self._timeoutCall = None
-
- if self.lock():
- d.callback(None)
- else:
- d.errback(failure.Failure(
- TimeoutError("Timed out aquiring lock: %s after %fs" % (
- self.name,
- timeout))))
-
- def _tryLock():
- if self.lock():
- if self._timeoutCall is not None:
- self._timeoutCall.cancel()
- self._timeoutCall = None
-
- self._tryLockCall = None
-
- d.callback(None)
- else:
- if timeout is not None and self._timeoutCall is None:
- self._timeoutCall = self._scheduler.callLater(
- timeout, _cancelLock)
-
- self._tryLockCall = self._scheduler.callLater(
- self._interval, _tryLock)
-
- _tryLock()
-
- return d
-
-
-
-__all__ = ["Deferred", "DeferredList", "succeed", "fail", "FAILURE", "SUCCESS",
- "AlreadyCalledError", "TimeoutError", "gatherResults",
- "maybeDeferred",
- "waitForDeferred", "deferredGenerator", "inlineCallbacks",
- "returnValue",
- "DeferredLock", "DeferredSemaphore", "DeferredQueue",
- "DeferredFilesystemLock", "AlreadyTryingToLockError",
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/endpoints.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/endpoints.py
deleted file mode 100755
index 4e2f6e9b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/endpoints.py
+++ /dev/null
@@ -1,1347 +0,0 @@
-
-# -*- test-case-name: twisted.internet.test.test_endpoints -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-"""
-Implementations of L{IStreamServerEndpoint} and L{IStreamClientEndpoint} that
-wrap the L{IReactorTCP}, L{IReactorSSL}, and L{IReactorUNIX} interfaces.
-
-This also implements an extensible mini-language for describing endpoints,
-parsed by the L{clientFromString} and L{serverFromString} functions.
-
-@since: 10.1
-"""
-
-import os, socket
-
-from zope.interface import implements, directlyProvides
-import warnings
-
-from twisted.internet import interfaces, defer, error, fdesc, threads
-from twisted.internet.protocol import ClientFactory, Protocol
-from twisted.plugin import IPlugin, getPlugins
-from twisted.internet.interfaces import IStreamServerEndpointStringParser
-from twisted.internet.interfaces import IStreamClientEndpointStringParser
-from twisted.python.filepath import FilePath
-from twisted.python.systemd import ListenFDs
-from twisted.internet.abstract import isIPv6Address
-from twisted.internet import stdio
-from twisted.internet.stdio import PipeAddress
-
-
-__all__ = ["clientFromString", "serverFromString",
- "TCP4ServerEndpoint", "TCP6ServerEndpoint",
- "TCP4ClientEndpoint", "TCP6ClientEndpoint",
- "UNIXServerEndpoint", "UNIXClientEndpoint",
- "SSL4ServerEndpoint", "SSL4ClientEndpoint",
- "AdoptedStreamServerEndpoint", "StandardIOEndpoint"]
-
-
-class _WrappingProtocol(Protocol):
- """
- Wrap another protocol in order to notify my user when a connection has
- been made.
- """
-
- def __init__(self, connectedDeferred, wrappedProtocol):
- """
- @param connectedDeferred: The L{Deferred} that will callback
- with the C{wrappedProtocol} when it is connected.
-
- @param wrappedProtocol: An L{IProtocol} provider that will be
- connected.
- """
- self._connectedDeferred = connectedDeferred
- self._wrappedProtocol = wrappedProtocol
-
- for iface in [interfaces.IHalfCloseableProtocol,
- interfaces.IFileDescriptorReceiver]:
- if iface.providedBy(self._wrappedProtocol):
- directlyProvides(self, iface)
-
-
- def logPrefix(self):
- """
- Transparently pass through the wrapped protocol's log prefix.
- """
- if interfaces.ILoggingContext.providedBy(self._wrappedProtocol):
- return self._wrappedProtocol.logPrefix()
- return self._wrappedProtocol.__class__.__name__
-
-
- def connectionMade(self):
- """
- Connect the C{self._wrappedProtocol} to our C{self.transport} and
- callback C{self._connectedDeferred} with the C{self._wrappedProtocol}
- """
- self._wrappedProtocol.makeConnection(self.transport)
- self._connectedDeferred.callback(self._wrappedProtocol)
-
-
- def dataReceived(self, data):
- """
- Proxy C{dataReceived} calls to our C{self._wrappedProtocol}
- """
- return self._wrappedProtocol.dataReceived(data)
-
-
- def fileDescriptorReceived(self, descriptor):
- """
- Proxy C{fileDescriptorReceived} calls to our C{self._wrappedProtocol}
- """
- return self._wrappedProtocol.fileDescriptorReceived(descriptor)
-
-
- def connectionLost(self, reason):
- """
- Proxy C{connectionLost} calls to our C{self._wrappedProtocol}
- """
- return self._wrappedProtocol.connectionLost(reason)
-
-
- def readConnectionLost(self):
- """
- Proxy L{IHalfCloseableProtocol.readConnectionLost} to our
- C{self._wrappedProtocol}
- """
- self._wrappedProtocol.readConnectionLost()
-
-
- def writeConnectionLost(self):
- """
- Proxy L{IHalfCloseableProtocol.writeConnectionLost} to our
- C{self._wrappedProtocol}
- """
- self._wrappedProtocol.writeConnectionLost()
-
-
-
-class _WrappingFactory(ClientFactory):
- """
- Wrap a factory in order to wrap the protocols it builds.
-
- @ivar _wrappedFactory: A provider of I{IProtocolFactory} whose buildProtocol
- method will be called and whose resulting protocol will be wrapped.
-
- @ivar _onConnection: A L{Deferred} that fires when the protocol is
- connected
-
- @ivar _connector: A L{connector <twisted.internet.interfaces.IConnector>}
- that is managing the current or previous connection attempt.
- """
- protocol = _WrappingProtocol
-
- def __init__(self, wrappedFactory):
- """
- @param wrappedFactory: A provider of I{IProtocolFactory} whose
- buildProtocol method will be called and whose resulting protocol
- will be wrapped.
- """
- self._wrappedFactory = wrappedFactory
- self._onConnection = defer.Deferred(canceller=self._canceller)
-
-
- def startedConnecting(self, connector):
- """
- A connection attempt was started. Remember the connector which started
- said attempt, for use later.
- """
- self._connector = connector
-
-
- def _canceller(self, deferred):
- """
- The outgoing connection attempt was cancelled. Fail that L{Deferred}
- with an L{error.ConnectingCancelledError}.
-
- @param deferred: The L{Deferred <defer.Deferred>} that was cancelled;
- should be the same as C{self._onConnection}.
- @type deferred: L{Deferred <defer.Deferred>}
-
- @note: This relies on startedConnecting having been called, so it may
- seem as though there's a race condition where C{_connector} may not
- have been set. However, using public APIs, this condition is
- impossible to catch, because a connection API
- (C{connectTCP}/C{SSL}/C{UNIX}) is always invoked before a
- L{_WrappingFactory}'s L{Deferred <defer.Deferred>} is returned to
- C{connect()}'s caller.
-
- @return: C{None}
- """
- deferred.errback(
- error.ConnectingCancelledError(
- self._connector.getDestination()))
- self._connector.stopConnecting()
-
-
- def doStart(self):
- """
- Start notifications are passed straight through to the wrapped factory.
- """
- self._wrappedFactory.doStart()
-
-
- def doStop(self):
- """
- Stop notifications are passed straight through to the wrapped factory.
- """
- self._wrappedFactory.doStop()
-
-
- def buildProtocol(self, addr):
- """
- Proxy C{buildProtocol} to our C{self._wrappedFactory} or errback
- the C{self._onConnection} L{Deferred}.
-
- @return: An instance of L{_WrappingProtocol} or C{None}
- """
- try:
- proto = self._wrappedFactory.buildProtocol(addr)
- except:
- self._onConnection.errback()
- else:
- return self.protocol(self._onConnection, proto)
-
-
- def clientConnectionFailed(self, connector, reason):
- """
- Errback the C{self._onConnection} L{Deferred} when the
- client connection fails.
- """
- if not self._onConnection.called:
- self._onConnection.errback(reason)
-
-
-
-class StandardIOEndpoint(object):
- """
- A Standard Input/Output endpoint
- """
- implements(interfaces.IStreamServerEndpoint)
-
- def __init__(self, reactor):
- """
- @param reactor: The reactor for the endpoint
- """
- self._reactor = reactor
-
-
- def listen(self, stdioProtocolFactory):
- """
- Implement L{IStreamServerEndpoint.listen} to listen on stdin/stdout
- """
- return defer.execute(stdio.StandardIO,
- stdioProtocolFactory.buildProtocol(PipeAddress()))
-
-
-
-class _TCPServerEndpoint(object):
- """
- A TCP server endpoint interface
- """
- implements(interfaces.IStreamServerEndpoint)
-
- def __init__(self, reactor, port, backlog, interface):
- """
- @param reactor: An L{IReactorTCP} provider.
-
- @param port: The port number used for listening
- @type port: int
-
- @param backlog: Size of the listen queue
- @type backlog: int
-
- @param interface: The hostname to bind to
- @type interface: str
- """
- self._reactor = reactor
- self._port = port
- self._backlog = backlog
- self._interface = interface
-
-
- def listen(self, protocolFactory):
- """
- Implement L{IStreamServerEndpoint.listen} to listen on a TCP socket
- """
- return defer.execute(self._reactor.listenTCP,
- self._port,
- protocolFactory,
- backlog=self._backlog,
- interface=self._interface)
-
-
-
-class TCP4ServerEndpoint(_TCPServerEndpoint):
- """
- Implements TCP server endpoint with an IPv4 configuration
- """
- def __init__(self, reactor, port, backlog=50, interface=''):
- """
- @param reactor: An L{IReactorTCP} provider.
-
- @param port: The port number used for listening
- @type port: int
-
- @param backlog: Size of the listen queue
- @type backlog: int
-
- @param interface: The hostname to bind to, defaults to '' (all)
- @type interface: str
- """
- _TCPServerEndpoint.__init__(self, reactor, port, backlog, interface)
-
-
-
-class TCP6ServerEndpoint(_TCPServerEndpoint):
- """
- Implements TCP server endpoint with an IPv6 configuration
- """
- def __init__(self, reactor, port, backlog=50, interface='::'):
- """
- @param reactor: An L{IReactorTCP} provider.
-
- @param port: The port number used for listening
- @type port: int
-
- @param backlog: Size of the listen queue
- @type backlog: int
-
- @param interface: The hostname to bind to, defaults to '' (all)
- @type interface: str
- """
- _TCPServerEndpoint.__init__(self, reactor, port, backlog, interface)
-
-
-
-class TCP4ClientEndpoint(object):
- """
- TCP client endpoint with an IPv4 configuration.
- """
- implements(interfaces.IStreamClientEndpoint)
-
- def __init__(self, reactor, host, port, timeout=30, bindAddress=None):
- """
- @param reactor: An L{IReactorTCP} provider
-
- @param host: A hostname, used when connecting
- @type host: str
-
- @param port: The port number, used when connecting
- @type port: int
-
- @param timeout: The number of seconds to wait before assuming the
- connection has failed.
- @type timeout: int
-
- @param bindAddress: A (host, port) tuple of local address to bind to,
- or None.
- @type bindAddress: tuple
- """
- self._reactor = reactor
- self._host = host
- self._port = port
- self._timeout = timeout
- self._bindAddress = bindAddress
-
-
- def connect(self, protocolFactory):
- """
- Implement L{IStreamClientEndpoint.connect} to connect via TCP.
- """
- try:
- wf = _WrappingFactory(protocolFactory)
- self._reactor.connectTCP(
- self._host, self._port, wf,
- timeout=self._timeout, bindAddress=self._bindAddress)
- return wf._onConnection
- except:
- return defer.fail()
-
-
-
-class TCP6ClientEndpoint(object):
- """
- TCP client endpoint with an IPv6 configuration.
-
- @ivar _getaddrinfo: A hook used for testing name resolution.
-
- @ivar _deferToThread: A hook used for testing deferToThread.
-
- @ivar _GAI_ADDRESS: Index of the address portion in result of
- getaddrinfo to be used.
-
- @ivar _GAI_ADDRESS_HOST: Index of the actual host-address in the
- 5-tuple L{_GAI_ADDRESS}.
- """
- _getaddrinfo = socket.getaddrinfo
- _deferToThread = threads.deferToThread
- _GAI_ADDRESS = 4
- _GAI_ADDRESS_HOST = 0
-
- def __init__(self, reactor, host, port, timeout=30, bindAddress=None):
- """
- @param host: An IPv6 address literal or a hostname with an
- IPv6 address
-
- @see: L{twisted.internet.interfaces.IReactorTCP.connectTCP}
- """
- self._reactor = reactor
- self._host = host
- self._port = port
- self._timeout = timeout
- self._bindAddress = bindAddress
-
-
- def connect(self, protocolFactory):
- """
- Implement L{IStreamClientEndpoint.connect} to connect via TCP,
- once the hostname resolution is done.
- """
- if isIPv6Address(self._host):
- d = self._resolvedHostConnect(self._host, protocolFactory)
- else:
- d = self._nameResolution(self._host)
- d.addCallback(lambda result: result[0][self._GAI_ADDRESS]
- [self._GAI_ADDRESS_HOST])
- d.addCallback(self._resolvedHostConnect, protocolFactory)
- return d
-
-
- def _nameResolution(self, host):
- """
- Resolve the hostname string into a tuple containig the host
- IPv6 address.
- """
- return self._deferToThread(
- self._getaddrinfo, host, 0, socket.AF_INET6)
-
-
- def _resolvedHostConnect(self, resolvedHost, protocolFactory):
- """
- Connect to the server using the resolved hostname.
- """
- try:
- wf = _WrappingFactory(protocolFactory)
- self._reactor.connectTCP(resolvedHost, self._port, wf,
- timeout=self._timeout, bindAddress=self._bindAddress)
- return wf._onConnection
- except:
- return defer.fail()
-
-
-
-class SSL4ServerEndpoint(object):
- """
- SSL secured TCP server endpoint with an IPv4 configuration.
- """
- implements(interfaces.IStreamServerEndpoint)
-
- def __init__(self, reactor, port, sslContextFactory,
- backlog=50, interface=''):
- """
- @param reactor: An L{IReactorSSL} provider.
-
- @param port: The port number used for listening
- @type port: int
-
- @param sslContextFactory: An instance of
- L{twisted.internet._sslverify.OpenSSLCertificateOptions}.
-
- @param backlog: Size of the listen queue
- @type backlog: int
-
- @param interface: The hostname to bind to, defaults to '' (all)
- @type interface: str
- """
- self._reactor = reactor
- self._port = port
- self._sslContextFactory = sslContextFactory
- self._backlog = backlog
- self._interface = interface
-
-
- def listen(self, protocolFactory):
- """
- Implement L{IStreamServerEndpoint.listen} to listen for SSL on a
- TCP socket.
- """
- return defer.execute(self._reactor.listenSSL, self._port,
- protocolFactory,
- contextFactory=self._sslContextFactory,
- backlog=self._backlog,
- interface=self._interface)
-
-
-
-class SSL4ClientEndpoint(object):
- """
- SSL secured TCP client endpoint with an IPv4 configuration
- """
- implements(interfaces.IStreamClientEndpoint)
-
- def __init__(self, reactor, host, port, sslContextFactory,
- timeout=30, bindAddress=None):
- """
- @param reactor: An L{IReactorSSL} provider.
-
- @param host: A hostname, used when connecting
- @type host: str
-
- @param port: The port number, used when connecting
- @type port: int
-
- @param sslContextFactory: SSL Configuration information as an instance
- of L{OpenSSLCertificateOptions}.
-
- @param timeout: Number of seconds to wait before assuming the
- connection has failed.
- @type timeout: int
-
- @param bindAddress: A (host, port) tuple of local address to bind to,
- or None.
- @type bindAddress: tuple
- """
- self._reactor = reactor
- self._host = host
- self._port = port
- self._sslContextFactory = sslContextFactory
- self._timeout = timeout
- self._bindAddress = bindAddress
-
-
- def connect(self, protocolFactory):
- """
- Implement L{IStreamClientEndpoint.connect} to connect with SSL over
- TCP.
- """
- try:
- wf = _WrappingFactory(protocolFactory)
- self._reactor.connectSSL(
- self._host, self._port, wf, self._sslContextFactory,
- timeout=self._timeout, bindAddress=self._bindAddress)
- return wf._onConnection
- except:
- return defer.fail()
-
-
-
-class UNIXServerEndpoint(object):
- """
- UnixSocket server endpoint.
- """
- implements(interfaces.IStreamServerEndpoint)
-
- def __init__(self, reactor, address, backlog=50, mode=0666, wantPID=0):
- """
- @param reactor: An L{IReactorUNIX} provider.
- @param address: The path to the Unix socket file, used when listening
- @param backlog: number of connections to allow in backlog.
- @param mode: mode to set on the unix socket. This parameter is
- deprecated. Permissions should be set on the directory which
- contains the UNIX socket.
- @param wantPID: If True, create a pidfile for the socket.
- """
- self._reactor = reactor
- self._address = address
- self._backlog = backlog
- self._mode = mode
- self._wantPID = wantPID
-
-
- def listen(self, protocolFactory):
- """
- Implement L{IStreamServerEndpoint.listen} to listen on a UNIX socket.
- """
- return defer.execute(self._reactor.listenUNIX, self._address,
- protocolFactory,
- backlog=self._backlog,
- mode=self._mode,
- wantPID=self._wantPID)
-
-
-
-class UNIXClientEndpoint(object):
- """
- UnixSocket client endpoint.
- """
- implements(interfaces.IStreamClientEndpoint)
-
- def __init__(self, reactor, path, timeout=30, checkPID=0):
- """
- @param reactor: An L{IReactorUNIX} provider.
-
- @param path: The path to the Unix socket file, used when connecting
- @type path: str
-
- @param timeout: Number of seconds to wait before assuming the
- connection has failed.
- @type timeout: int
-
- @param checkPID: If True, check for a pid file to verify that a server
- is listening.
- @type checkPID: bool
- """
- self._reactor = reactor
- self._path = path
- self._timeout = timeout
- self._checkPID = checkPID
-
-
- def connect(self, protocolFactory):
- """
- Implement L{IStreamClientEndpoint.connect} to connect via a
- UNIX Socket
- """
- try:
- wf = _WrappingFactory(protocolFactory)
- self._reactor.connectUNIX(
- self._path, wf,
- timeout=self._timeout,
- checkPID=self._checkPID)
- return wf._onConnection
- except:
- return defer.fail()
-
-
-
-class AdoptedStreamServerEndpoint(object):
- """
- An endpoint for listening on a file descriptor initialized outside of
- Twisted.
-
- @ivar _used: A C{bool} indicating whether this endpoint has been used to
- listen with a factory yet. C{True} if so.
- """
- _close = os.close
- _setNonBlocking = staticmethod(fdesc.setNonBlocking)
-
- def __init__(self, reactor, fileno, addressFamily):
- """
- @param reactor: An L{IReactorSocket} provider.
-
- @param fileno: An integer file descriptor corresponding to a listening
- I{SOCK_STREAM} socket.
-
- @param addressFamily: The address family of the socket given by
- C{fileno}.
- """
- self.reactor = reactor
- self.fileno = fileno
- self.addressFamily = addressFamily
- self._used = False
-
-
- def listen(self, factory):
- """
- Implement L{IStreamServerEndpoint.listen} to start listening on, and
- then close, C{self._fileno}.
- """
- if self._used:
- return defer.fail(error.AlreadyListened())
- self._used = True
-
- try:
- self._setNonBlocking(self.fileno)
- port = self.reactor.adoptStreamPort(
- self.fileno, self.addressFamily, factory)
- self._close(self.fileno)
- except:
- return defer.fail()
- return defer.succeed(port)
-
-
-
-def _parseTCP(factory, port, interface="", backlog=50):
- """
- Internal parser function for L{_parseServer} to convert the string
- arguments for a TCP(IPv4) stream endpoint into the structured arguments.
-
- @param factory: the protocol factory being parsed, or C{None}. (This was a
- leftover argument from when this code was in C{strports}, and is now
- mostly None and unused.)
-
- @type factory: L{IProtocolFactory} or C{NoneType}
-
- @param port: the integer port number to bind
- @type port: C{str}
-
- @param interface: the interface IP to listen on
- @param backlog: the length of the listen queue
- @type backlog: C{str}
-
- @return: a 2-tuple of (args, kwargs), describing the parameters to
- L{IReactorTCP.listenTCP} (or, modulo argument 2, the factory, arguments
- to L{TCP4ServerEndpoint}.
- """
- return (int(port), factory), {'interface': interface,
- 'backlog': int(backlog)}
-
-
-
-def _parseUNIX(factory, address, mode='666', backlog=50, lockfile=True):
- """
- Internal parser function for L{_parseServer} to convert the string
- arguments for a UNIX (AF_UNIX/SOCK_STREAM) stream endpoint into the
- structured arguments.
-
- @param factory: the protocol factory being parsed, or C{None}. (This was a
- leftover argument from when this code was in C{strports}, and is now
- mostly None and unused.)
-
- @type factory: L{IProtocolFactory} or C{NoneType}
-
- @param address: the pathname of the unix socket
- @type address: C{str}
-
- @param backlog: the length of the listen queue
- @type backlog: C{str}
-
- @param lockfile: A string '0' or '1', mapping to True and False
- respectively. See the C{wantPID} argument to C{listenUNIX}
-
- @return: a 2-tuple of (args, kwargs), describing the parameters to
- L{IReactorTCP.listenUNIX} (or, modulo argument 2, the factory,
- arguments to L{UNIXServerEndpoint}.
- """
- return (
- (address, factory),
- {'mode': int(mode, 8), 'backlog': int(backlog),
- 'wantPID': bool(int(lockfile))})
-
-
-
-def _parseSSL(factory, port, privateKey="server.pem", certKey=None,
- sslmethod=None, interface='', backlog=50):
- """
- Internal parser function for L{_parseServer} to convert the string
- arguments for an SSL (over TCP/IPv4) stream endpoint into the structured
- arguments.
-
- @param factory: the protocol factory being parsed, or C{None}. (This was a
- leftover argument from when this code was in C{strports}, and is now
- mostly None and unused.)
- @type factory: L{IProtocolFactory} or C{NoneType}
-
- @param port: the integer port number to bind
- @type port: C{str}
-
- @param interface: the interface IP to listen on
- @param backlog: the length of the listen queue
- @type backlog: C{str}
-
- @param privateKey: The file name of a PEM format private key file.
- @type privateKey: C{str}
-
- @param certKey: The file name of a PEM format certificate file.
- @type certKey: C{str}
-
- @param sslmethod: The string name of an SSL method, based on the name of a
- constant in C{OpenSSL.SSL}. Must be one of: "SSLv23_METHOD",
- "SSLv2_METHOD", "SSLv3_METHOD", "TLSv1_METHOD".
- @type sslmethod: C{str}
-
- @return: a 2-tuple of (args, kwargs), describing the parameters to
- L{IReactorSSL.listenSSL} (or, modulo argument 2, the factory, arguments
- to L{SSL4ServerEndpoint}.
- """
- from twisted.internet import ssl
- if certKey is None:
- certKey = privateKey
- kw = {}
- if sslmethod is not None:
- kw['sslmethod'] = getattr(ssl.SSL, sslmethod)
- cf = ssl.DefaultOpenSSLContextFactory(privateKey, certKey, **kw)
- return ((int(port), factory, cf),
- {'interface': interface, 'backlog': int(backlog)})
-
-
-
-class _StandardIOParser(object):
- """
- Stream server endpoint string parser for the Standard I/O type.
-
- @ivar prefix: See L{IStreamClientEndpointStringParser.prefix}.
- """
- implements(IPlugin, IStreamServerEndpointStringParser)
-
- prefix = "stdio"
-
- def _parseServer(self, reactor):
- """
- Internal parser function for L{_parseServer} to convert the string
- arguments into structured arguments for the L{StandardIOEndpoint}
-
- @param reactor: Reactor for the endpoint
- """
- return StandardIOEndpoint(reactor)
-
-
- def parseStreamServer(self, reactor, *args, **kwargs):
- # Redirects to another function (self._parseServer), tricks zope.interface
- # into believing the interface is correctly implemented.
- return self._parseServer(reactor)
-
-
-
-class _SystemdParser(object):
- """
- Stream server endpoint string parser for the I{systemd} endpoint type.
-
- @ivar prefix: See L{IStreamClientEndpointStringParser.prefix}.
-
- @ivar _sddaemon: A L{ListenFDs} instance used to translate an index into an
- actual file descriptor.
- """
- implements(IPlugin, IStreamServerEndpointStringParser)
-
- _sddaemon = ListenFDs.fromEnvironment()
-
- prefix = "systemd"
-
- def _parseServer(self, reactor, domain, index):
- """
- Internal parser function for L{_parseServer} to convert the string
- arguments for a systemd server endpoint into structured arguments for
- L{AdoptedStreamServerEndpoint}.
-
- @param reactor: An L{IReactorSocket} provider.
-
- @param domain: The domain (or address family) of the socket inherited
- from systemd. This is a string like C{"INET"} or C{"UNIX"}, ie the
- name of an address family from the L{socket} module, without the
- C{"AF_"} prefix.
- @type domain: C{str}
-
- @param index: An offset into the list of file descriptors inherited from
- systemd.
- @type index: C{str}
-
- @return: A two-tuple of parsed positional arguments and parsed keyword
- arguments (a tuple and a dictionary). These can be used to
- construct an L{AdoptedStreamServerEndpoint}.
- """
- index = int(index)
- fileno = self._sddaemon.inheritedDescriptors()[index]
- addressFamily = getattr(socket, 'AF_' + domain)
- return AdoptedStreamServerEndpoint(reactor, fileno, addressFamily)
-
-
- def parseStreamServer(self, reactor, *args, **kwargs):
- # Delegate to another function with a sane signature. This function has
- # an insane signature to trick zope.interface into believing the
- # interface is correctly implemented.
- return self._parseServer(reactor, *args, **kwargs)
-
-
-
-class _TCP6ServerParser(object):
- """
- Stream server endpoint string parser for the TCP6ServerEndpoint type.
-
- @ivar prefix: See L{IStreamClientEndpointStringParser.prefix}.
- """
- implements(IPlugin, IStreamServerEndpointStringParser)
-
- prefix = "tcp6" # Used in _parseServer to identify the plugin with the endpoint type
-
- def _parseServer(self, reactor, port, backlog=50, interface='::'):
- """
- Internal parser function for L{_parseServer} to convert the string
- arguments into structured arguments for the L{TCP6ServerEndpoint}
-
- @param reactor: An L{IReactorTCP} provider.
-
- @param port: The port number used for listening
- @type port: int
-
- @param backlog: Size of the listen queue
- @type backlog: int
-
- @param interface: The hostname to bind to
- @type interface: str
- """
- port = int(port)
- backlog = int(backlog)
- return TCP6ServerEndpoint(reactor, port, backlog, interface)
-
-
- def parseStreamServer(self, reactor, *args, **kwargs):
- # Redirects to another function (self._parseServer), tricks zope.interface
- # into believing the interface is correctly implemented.
- return self._parseServer(reactor, *args, **kwargs)
-
-
-
-_serverParsers = {"tcp": _parseTCP,
- "unix": _parseUNIX,
- "ssl": _parseSSL,
- }
-
-_OP, _STRING = range(2)
-
-def _tokenize(description):
- """
- Tokenize a strports string and yield each token.
-
- @param description: a string as described by L{serverFromString} or
- L{clientFromString}.
-
- @return: an iterable of 2-tuples of (L{_OP} or L{_STRING}, string). Tuples
- starting with L{_OP} will contain a second element of either ':' (i.e.
- 'next parameter') or '=' (i.e. 'assign parameter value'). For example,
- the string 'hello:greet\=ing=world' would result in a generator
- yielding these values::
-
- _STRING, 'hello'
- _OP, ':'
- _STRING, 'greet=ing'
- _OP, '='
- _STRING, 'world'
- """
- current = ''
- ops = ':='
- nextOps = {':': ':=', '=': ':'}
- description = iter(description)
- for n in description:
- if n in ops:
- yield _STRING, current
- yield _OP, n
- current = ''
- ops = nextOps[n]
- elif n == '\\':
- current += description.next()
- else:
- current += n
- yield _STRING, current
-
-
-
-def _parse(description):
- """
- Convert a description string into a list of positional and keyword
- parameters, using logic vaguely like what Python does.
-
- @param description: a string as described by L{serverFromString} or
- L{clientFromString}.
-
- @return: a 2-tuple of C{(args, kwargs)}, where 'args' is a list of all
- ':'-separated C{str}s not containing an '=' and 'kwargs' is a map of
- all C{str}s which do contain an '='. For example, the result of
- C{_parse('a:b:d=1:c')} would be C{(['a', 'b', 'c'], {'d': '1'})}.
- """
- args, kw = [], {}
- def add(sofar):
- if len(sofar) == 1:
- args.append(sofar[0])
- else:
- kw[sofar[0]] = sofar[1]
- sofar = ()
- for (type, value) in _tokenize(description):
- if type is _STRING:
- sofar += (value,)
- elif value == ':':
- add(sofar)
- sofar = ()
- add(sofar)
- return args, kw
-
-
-# Mappings from description "names" to endpoint constructors.
-_endpointServerFactories = {
- 'TCP': TCP4ServerEndpoint,
- 'SSL': SSL4ServerEndpoint,
- 'UNIX': UNIXServerEndpoint,
- }
-
-_endpointClientFactories = {
- 'TCP': TCP4ClientEndpoint,
- 'SSL': SSL4ClientEndpoint,
- 'UNIX': UNIXClientEndpoint,
- }
-
-
-_NO_DEFAULT = object()
-
-def _parseServer(description, factory, default=None):
- """
- Parse a stports description into a 2-tuple of arguments and keyword values.
-
- @param description: A description in the format explained by
- L{serverFromString}.
- @type description: C{str}
-
- @param factory: A 'factory' argument; this is left-over from
- twisted.application.strports, it's not really used.
- @type factory: L{IProtocolFactory} or L{None}
-
- @param default: Deprecated argument, specifying the default parser mode to
- use for unqualified description strings (those which do not have a ':'
- and prefix).
- @type default: C{str} or C{NoneType}
-
- @return: a 3-tuple of (plugin or name, arguments, keyword arguments)
- """
- args, kw = _parse(description)
- if not args or (len(args) == 1 and not kw):
- deprecationMessage = (
- "Unqualified strport description passed to 'service'."
- "Use qualified endpoint descriptions; for example, 'tcp:%s'."
- % (description,))
- if default is None:
- default = 'tcp'
- warnings.warn(
- deprecationMessage, category=DeprecationWarning, stacklevel=4)
- elif default is _NO_DEFAULT:
- raise ValueError(deprecationMessage)
- # If the default has been otherwise specified, the user has already
- # been warned.
- args[0:0] = [default]
- endpointType = args[0]
- parser = _serverParsers.get(endpointType)
- if parser is None:
- # If the required parser is not found in _server, check if
- # a plugin exists for the endpointType
- for plugin in getPlugins(IStreamServerEndpointStringParser):
- if plugin.prefix == endpointType:
- return (plugin, args[1:], kw)
- raise ValueError("Unknown endpoint type: '%s'" % (endpointType,))
- return (endpointType.upper(),) + parser(factory, *args[1:], **kw)
-
-
-
-def _serverFromStringLegacy(reactor, description, default):
- """
- Underlying implementation of L{serverFromString} which avoids exposing the
- deprecated 'default' argument to anything but L{strports.service}.
- """
- nameOrPlugin, args, kw = _parseServer(description, None, default)
- if type(nameOrPlugin) is not str:
- plugin = nameOrPlugin
- return plugin.parseStreamServer(reactor, *args, **kw)
- else:
- name = nameOrPlugin
- # Chop out the factory.
- args = args[:1] + args[2:]
- return _endpointServerFactories[name](reactor, *args, **kw)
-
-
-
-def serverFromString(reactor, description):
- """
- Construct a stream server endpoint from an endpoint description string.
-
- The format for server endpoint descriptions is a simple string. It is a
- prefix naming the type of endpoint, then a colon, then the arguments for
- that endpoint.
-
- For example, you can call it like this to create an endpoint that will
- listen on TCP port 80::
-
- serverFromString(reactor, "tcp:80")
-
- Additional arguments may be specified as keywords, separated with colons.
- For example, you can specify the interface for a TCP server endpoint to
- bind to like this::
-
- serverFromString(reactor, "tcp:80:interface=127.0.0.1")
-
- SSL server endpoints may be specified with the 'ssl' prefix, and the
- private key and certificate files may be specified by the C{privateKey} and
- C{certKey} arguments::
-
- serverFromString(reactor, "ssl:443:privateKey=key.pem:certKey=crt.pem")
-
- If a private key file name (C{privateKey}) isn't provided, a "server.pem"
- file is assumed to exist which contains the private key. If the certificate
- file name (C{certKey}) isn't provided, the private key file is assumed to
- contain the certificate as well.
-
- You may escape colons in arguments with a backslash, which you will need to
- use if you want to specify a full pathname argument on Windows::
-
- serverFromString(reactor,
- "ssl:443:privateKey=C\\:/key.pem:certKey=C\\:/cert.pem")
-
- finally, the 'unix' prefix may be used to specify a filesystem UNIX socket,
- optionally with a 'mode' argument to specify the mode of the socket file
- created by C{listen}::
-
- serverFromString(reactor, "unix:/var/run/finger")
- serverFromString(reactor, "unix:/var/run/finger:mode=660")
-
- This function is also extensible; new endpoint types may be registered as
- L{IStreamServerEndpointStringParser} plugins. See that interface for more
- information.
-
- @param reactor: The server endpoint will be constructed with this reactor.
-
- @param description: The strports description to parse.
-
- @return: A new endpoint which can be used to listen with the parameters
- given by by C{description}.
-
- @rtype: L{IStreamServerEndpoint<twisted.internet.interfaces.IStreamServerEndpoint>}
-
- @raise ValueError: when the 'description' string cannot be parsed.
-
- @since: 10.2
- """
- return _serverFromStringLegacy(reactor, description, _NO_DEFAULT)
-
-
-
-def quoteStringArgument(argument):
- """
- Quote an argument to L{serverFromString} and L{clientFromString}. Since
- arguments are separated with colons and colons are escaped with
- backslashes, some care is necessary if, for example, you have a pathname,
- you may be tempted to interpolate into a string like this::
-
- serverFromString("ssl:443:privateKey=%s" % (myPathName,))
-
- This may appear to work, but will have portability issues (Windows
- pathnames, for example). Usually you should just construct the appropriate
- endpoint type rather than interpolating strings, which in this case would
- be L{SSL4ServerEndpoint}. There are some use-cases where you may need to
- generate such a string, though; for example, a tool to manipulate a
- configuration file which has strports descriptions in it. To be correct in
- those cases, do this instead::
-
- serverFromString("ssl:443:privateKey=%s" %
- (quoteStringArgument(myPathName),))
-
- @param argument: The part of the endpoint description string you want to
- pass through.
-
- @type argument: C{str}
-
- @return: The quoted argument.
-
- @rtype: C{str}
- """
- return argument.replace('\\', '\\\\').replace(':', '\\:')
-
-
-
-def _parseClientTCP(*args, **kwargs):
- """
- Perform any argument value coercion necessary for TCP client parameters.
-
- Valid positional arguments to this function are host and port.
-
- Valid keyword arguments to this function are all L{IReactorTCP.connectTCP}
- arguments.
-
- @return: The coerced values as a C{dict}.
- """
-
- if len(args) == 2:
- kwargs['port'] = int(args[1])
- kwargs['host'] = args[0]
- elif len(args) == 1:
- if 'host' in kwargs:
- kwargs['port'] = int(args[0])
- else:
- kwargs['host'] = args[0]
-
- try:
- kwargs['port'] = int(kwargs['port'])
- except KeyError:
- pass
-
- try:
- kwargs['timeout'] = int(kwargs['timeout'])
- except KeyError:
- pass
- return kwargs
-
-
-
-def _loadCAsFromDir(directoryPath):
- """
- Load certificate-authority certificate objects in a given directory.
-
- @param directoryPath: a L{FilePath} pointing at a directory to load .pem
- files from.
-
- @return: a C{list} of L{OpenSSL.crypto.X509} objects.
- """
- from twisted.internet import ssl
-
- caCerts = {}
- for child in directoryPath.children():
- if not child.basename().split('.')[-1].lower() == 'pem':
- continue
- try:
- data = child.getContent()
- except IOError:
- # Permission denied, corrupt disk, we don't care.
- continue
- try:
- theCert = ssl.Certificate.loadPEM(data)
- except ssl.SSL.Error:
- # Duplicate certificate, invalid certificate, etc. We don't care.
- pass
- else:
- caCerts[theCert.digest()] = theCert.original
- return caCerts.values()
-
-
-
-def _parseClientSSL(*args, **kwargs):
- """
- Perform any argument value coercion necessary for SSL client parameters.
-
- Valid keyword arguments to this function are all L{IReactorSSL.connectSSL}
- arguments except for C{contextFactory}. Instead, C{certKey} (the path name
- of the certificate file) C{privateKey} (the path name of the private key
- associated with the certificate) are accepted and used to construct a
- context factory.
-
- Valid positional arguments to this function are host and port.
-
- @param caCertsDir: The one parameter which is not part of
- L{IReactorSSL.connectSSL}'s signature, this is a path name used to
- construct a list of certificate authority certificates. The directory
- will be scanned for files ending in C{.pem}, all of which will be
- considered valid certificate authorities for this connection.
-
- @type caCertsDir: C{str}
-
- @return: The coerced values as a C{dict}.
- """
- from twisted.internet import ssl
- kwargs = _parseClientTCP(*args, **kwargs)
- certKey = kwargs.pop('certKey', None)
- privateKey = kwargs.pop('privateKey', None)
- caCertsDir = kwargs.pop('caCertsDir', None)
- if certKey is not None:
- certx509 = ssl.Certificate.loadPEM(
- FilePath(certKey).getContent()).original
- else:
- certx509 = None
- if privateKey is not None:
- privateKey = ssl.PrivateCertificate.loadPEM(
- FilePath(privateKey).getContent()).privateKey.original
- else:
- privateKey = None
- if caCertsDir is not None:
- verify = True
- caCerts = _loadCAsFromDir(FilePath(caCertsDir))
- else:
- verify = False
- caCerts = None
- kwargs['sslContextFactory'] = ssl.CertificateOptions(
- method=ssl.SSL.SSLv23_METHOD,
- certificate=certx509,
- privateKey=privateKey,
- verify=verify,
- caCerts=caCerts
- )
- return kwargs
-
-
-
-def _parseClientUNIX(*args, **kwargs):
- """
- Perform any argument value coercion necessary for UNIX client parameters.
-
- Valid keyword arguments to this function are all L{IReactorUNIX.connectUNIX}
- keyword arguments except for C{checkPID}. Instead, C{lockfile} is accepted
- and has the same meaning. Also C{path} is used instead of C{address}.
-
- Valid positional arguments to this function are C{path}.
-
- @return: The coerced values as a C{dict}.
- """
- if len(args) == 1:
- kwargs['path'] = args[0]
-
- try:
- kwargs['checkPID'] = bool(int(kwargs.pop('lockfile')))
- except KeyError:
- pass
- try:
- kwargs['timeout'] = int(kwargs['timeout'])
- except KeyError:
- pass
- return kwargs
-
-_clientParsers = {
- 'TCP': _parseClientTCP,
- 'SSL': _parseClientSSL,
- 'UNIX': _parseClientUNIX,
- }
-
-
-
-def clientFromString(reactor, description):
- """
- Construct a client endpoint from a description string.
-
- Client description strings are much like server description strings,
- although they take all of their arguments as keywords, aside from host and
- port.
-
- You can create a TCP client endpoint with the 'host' and 'port' arguments,
- like so::
-
- clientFromString(reactor, "tcp:host=www.example.com:port=80")
-
- or, without specifying host and port keywords::
-
- clientFromString(reactor, "tcp:www.example.com:80")
-
- Or you can specify only one or the other, as in the following 2 examples::
-
- clientFromString(reactor, "tcp:host=www.example.com:80")
- clientFromString(reactor, "tcp:www.example.com:port=80")
-
- or an SSL client endpoint with those arguments, plus the arguments used by
- the server SSL, for a client certificate::
-
- clientFromString(reactor, "ssl:web.example.com:443:"
- "privateKey=foo.pem:certKey=foo.pem")
-
- to specify your certificate trust roots, you can identify a directory with
- PEM files in it with the C{caCertsDir} argument::
-
- clientFromString(reactor, "ssl:host=web.example.com:port=443:"
- "caCertsDir=/etc/ssl/certs")
-
- You can create a UNIX client endpoint with the 'path' argument and optional
- 'lockfile' and 'timeout' arguments::
-
- clientFromString(reactor, "unix:path=/var/foo/bar:lockfile=1:timeout=9")
-
- or, with the path as a positional argument with or without optional
- arguments as in the following 2 examples::
-
- clientFromString(reactor, "unix:/var/foo/bar")
- clientFromString(reactor, "unix:/var/foo/bar:lockfile=1:timeout=9")
-
- This function is also extensible; new endpoint types may be registered as
- L{IStreamClientEndpointStringParser} plugins. See that interface for more
- information.
-
- @param reactor: The client endpoint will be constructed with this reactor.
-
- @param description: The strports description to parse.
-
- @return: A new endpoint which can be used to connect with the parameters
- given by by C{description}.
- @rtype: L{IStreamClientEndpoint<twisted.internet.interfaces.IStreamClientEndpoint>}
-
- @since: 10.2
- """
- args, kwargs = _parse(description)
- aname = args.pop(0)
- name = aname.upper()
- for plugin in getPlugins(IStreamClientEndpointStringParser):
- if plugin.prefix.upper() == name:
- return plugin.parseStreamClient(*args, **kwargs)
- if name not in _clientParsers:
- raise ValueError("Unknown endpoint type: %r" % (aname,))
- kwargs = _clientParsers[name](*args, **kwargs)
- return _endpointClientFactories[name](reactor, **kwargs)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py
deleted file mode 100755
index f892d6bd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py
+++ /dev/null
@@ -1,394 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An epoll() based implementation of the twisted main loop.
-
-To install the event loop (and you should do this before any connections,
-listeners or connectors are added)::
-
- from twisted.internet import epollreactor
- epollreactor.install()
-"""
-
-import errno
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IReactorFDSet
-
-from twisted.python import log
-from twisted.internet import posixbase
-
-try:
- # In Python 2.6+, select.epoll provides epoll functionality. Try to import
- # it, and fall back to Twisted's own epoll wrapper if it isn't available
- # for any reason.
- from select import epoll
-except ImportError:
- from twisted.python import _epoll
-else:
- del epoll
- import select as _epoll
-
-
-
-class _ContinuousPolling(posixbase._PollLikeMixin,
- posixbase._DisconnectSelectableMixin):
- """
- Schedule reads and writes based on the passage of time, rather than
- notification.
-
- This is useful for supporting polling filesystem files, which C{epoll(7)}
- does not support.
-
- The implementation uses L{posixbase._PollLikeMixin}, which is a bit hacky,
- but re-implementing and testing the relevant code yet again is
- unappealing.
-
- @ivar _reactor: The L{EPollReactor} that is using this instance.
-
- @ivar _loop: A C{LoopingCall} that drives the polling, or C{None}.
-
- @ivar _readers: A C{set} of C{FileDescriptor} objects that should be read
- from.
-
- @ivar _writers: A C{set} of C{FileDescriptor} objects that should be
- written to.
- """
- implements(IReactorFDSet)
-
- # Attributes for _PollLikeMixin
- _POLL_DISCONNECTED = 1
- _POLL_IN = 2
- _POLL_OUT = 4
-
-
- def __init__(self, reactor):
- self._reactor = reactor
- self._loop = None
- self._readers = set()
- self._writers = set()
- self.isReading = self._readers.__contains__
- self.isWriting = self._writers.__contains__
-
-
- def _checkLoop(self):
- """
- Start or stop a C{LoopingCall} based on whether there are readers and
- writers.
- """
- if self._readers or self._writers:
- if self._loop is None:
- from twisted.internet.task import LoopingCall, _EPSILON
- self._loop = LoopingCall(self.iterate)
- self._loop.clock = self._reactor
- # LoopingCall seems unhappy with timeout of 0, so use very
- # small number:
- self._loop.start(_EPSILON, now=False)
- elif self._loop:
- self._loop.stop()
- self._loop = None
-
-
- def iterate(self):
- """
- Call C{doRead} and C{doWrite} on all readers and writers respectively.
- """
- for reader in list(self._readers):
- self._doReadOrWrite(reader, reader, self._POLL_IN)
- for reader in list(self._writers):
- self._doReadOrWrite(reader, reader, self._POLL_OUT)
-
-
- def addReader(self, reader):
- """
- Add a C{FileDescriptor} for notification of data available to read.
- """
- self._readers.add(reader)
- self._checkLoop()
-
-
- def addWriter(self, writer):
- """
- Add a C{FileDescriptor} for notification of data available to write.
- """
- self._writers.add(writer)
- self._checkLoop()
-
-
- def removeReader(self, reader):
- """
- Remove a C{FileDescriptor} from notification of data available to read.
- """
- try:
- self._readers.remove(reader)
- except KeyError:
- return
- self._checkLoop()
-
-
- def removeWriter(self, writer):
- """
- Remove a C{FileDescriptor} from notification of data available to write.
- """
- try:
- self._writers.remove(writer)
- except KeyError:
- return
- self._checkLoop()
-
-
- def removeAll(self):
- """
- Remove all readers and writers.
- """
- result = list(self._readers | self._writers)
- # Don't reset to new value, since self.isWriting and .isReading refer
- # to the existing instance:
- self._readers.clear()
- self._writers.clear()
- return result
-
-
- def getReaders(self):
- """
- Return a list of the readers.
- """
- return list(self._readers)
-
-
- def getWriters(self):
- """
- Return a list of the writers.
- """
- return list(self._writers)
-
-
-
-class EPollReactor(posixbase.PosixReactorBase, posixbase._PollLikeMixin):
- """
- A reactor that uses epoll(7).
-
- @ivar _poller: A C{epoll} which will be used to check for I/O
- readiness.
-
- @ivar _selectables: A dictionary mapping integer file descriptors to
- instances of C{FileDescriptor} which have been registered with the
- reactor. All C{FileDescriptors} which are currently receiving read or
- write readiness notifications will be present as values in this
- dictionary.
-
- @ivar _reads: A dictionary mapping integer file descriptors to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- registered with C{_poller} for read readiness notifications which will
- be dispatched to the corresponding C{FileDescriptor} instances in
- C{_selectables}.
-
- @ivar _writes: A dictionary mapping integer file descriptors to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- registered with C{_poller} for write readiness notifications which will
- be dispatched to the corresponding C{FileDescriptor} instances in
- C{_selectables}.
-
- @ivar _continuousPolling: A L{_ContinuousPolling} instance, used to handle
- file descriptors (e.g. filesytem files) that are not supported by
- C{epoll(7)}.
- """
- implements(IReactorFDSet)
-
- # Attributes for _PollLikeMixin
- _POLL_DISCONNECTED = (_epoll.EPOLLHUP | _epoll.EPOLLERR)
- _POLL_IN = _epoll.EPOLLIN
- _POLL_OUT = _epoll.EPOLLOUT
-
- def __init__(self):
- """
- Initialize epoll object, file descriptor tracking dictionaries, and the
- base class.
- """
- # Create the poller we're going to use. The 1024 here is just a hint to
- # the kernel, it is not a hard maximum. After Linux 2.6.8, the size
- # argument is completely ignored.
- self._poller = _epoll.epoll(1024)
- self._reads = {}
- self._writes = {}
- self._selectables = {}
- self._continuousPolling = _ContinuousPolling(self)
- posixbase.PosixReactorBase.__init__(self)
-
-
- def _add(self, xer, primary, other, selectables, event, antievent):
- """
- Private method for adding a descriptor from the event loop.
-
- It takes care of adding it if new or modifying it if already added
- for another state (read -> read/write for example).
- """
- fd = xer.fileno()
- if fd not in primary:
- flags = event
- # epoll_ctl can raise all kinds of IOErrors, and every one
- # indicates a bug either in the reactor or application-code.
- # Let them all through so someone sees a traceback and fixes
- # something. We'll do the same thing for every other call to
- # this method in this file.
- if fd in other:
- flags |= antievent
- self._poller.modify(fd, flags)
- else:
- self._poller.register(fd, flags)
-
- # Update our own tracking state *only* after the epoll call has
- # succeeded. Otherwise we may get out of sync.
- primary[fd] = 1
- selectables[fd] = xer
-
-
- def addReader(self, reader):
- """
- Add a FileDescriptor for notification of data available to read.
- """
- try:
- self._add(reader, self._reads, self._writes, self._selectables,
- _epoll.EPOLLIN, _epoll.EPOLLOUT)
- except IOError, e:
- if e.errno == errno.EPERM:
- # epoll(7) doesn't support certain file descriptors,
- # e.g. filesystem files, so for those we just poll
- # continuously:
- self._continuousPolling.addReader(reader)
- else:
- raise
-
-
- def addWriter(self, writer):
- """
- Add a FileDescriptor for notification of data available to write.
- """
- try:
- self._add(writer, self._writes, self._reads, self._selectables,
- _epoll.EPOLLOUT, _epoll.EPOLLIN)
- except IOError, e:
- if e.errno == errno.EPERM:
- # epoll(7) doesn't support certain file descriptors,
- # e.g. filesystem files, so for those we just poll
- # continuously:
- self._continuousPolling.addWriter(writer)
- else:
- raise
-
-
- def _remove(self, xer, primary, other, selectables, event, antievent):
- """
- Private method for removing a descriptor from the event loop.
-
- It does the inverse job of _add, and also add a check in case of the fd
- has gone away.
- """
- fd = xer.fileno()
- if fd == -1:
- for fd, fdes in selectables.items():
- if xer is fdes:
- break
- else:
- return
- if fd in primary:
- if fd in other:
- flags = antievent
- # See comment above modify call in _add.
- self._poller.modify(fd, flags)
- else:
- del selectables[fd]
- # See comment above _control call in _add.
- self._poller.unregister(fd)
- del primary[fd]
-
-
- def removeReader(self, reader):
- """
- Remove a Selectable for notification of data available to read.
- """
- if self._continuousPolling.isReading(reader):
- self._continuousPolling.removeReader(reader)
- return
- self._remove(reader, self._reads, self._writes, self._selectables,
- _epoll.EPOLLIN, _epoll.EPOLLOUT)
-
-
- def removeWriter(self, writer):
- """
- Remove a Selectable for notification of data available to write.
- """
- if self._continuousPolling.isWriting(writer):
- self._continuousPolling.removeWriter(writer)
- return
- self._remove(writer, self._writes, self._reads, self._selectables,
- _epoll.EPOLLOUT, _epoll.EPOLLIN)
-
-
- def removeAll(self):
- """
- Remove all selectables, and return a list of them.
- """
- return (self._removeAll(
- [self._selectables[fd] for fd in self._reads],
- [self._selectables[fd] for fd in self._writes]) +
- self._continuousPolling.removeAll())
-
-
- def getReaders(self):
- return ([self._selectables[fd] for fd in self._reads] +
- self._continuousPolling.getReaders())
-
-
- def getWriters(self):
- return ([self._selectables[fd] for fd in self._writes] +
- self._continuousPolling.getWriters())
-
-
- def doPoll(self, timeout):
- """
- Poll the poller for new events.
- """
- if timeout is None:
- timeout = -1 # Wait indefinitely.
-
- try:
- # Limit the number of events to the number of io objects we're
- # currently tracking (because that's maybe a good heuristic) and
- # the amount of time we block to the value specified by our
- # caller.
- l = self._poller.poll(timeout, len(self._selectables))
- except IOError, err:
- if err.errno == errno.EINTR:
- return
- # See epoll_wait(2) for documentation on the other conditions
- # under which this can fail. They can only be due to a serious
- # programming error on our part, so let's just announce them
- # loudly.
- raise
-
- _drdw = self._doReadOrWrite
- for fd, event in l:
- try:
- selectable = self._selectables[fd]
- except KeyError:
- pass
- else:
- log.callWithLogger(selectable, _drdw, selectable, fd, event)
-
- doIteration = doPoll
-
-
-def install():
- """
- Install the epoll() reactor.
- """
- p = EPollReactor()
- from twisted.internet.main import installReactor
- installReactor(p)
-
-
-__all__ = ["EPollReactor", "install"]
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/error.py
deleted file mode 100755
index 51b0ad82..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/error.py
+++ /dev/null
@@ -1,448 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Exceptions and errors for use in twisted.internet modules.
-"""
-
-import socket
-
-from twisted.python import deprecate
-from twisted.python.versions import Version
-
-
-
-class BindError(Exception):
- """An error occurred binding to an interface"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class CannotListenError(BindError):
- """
- This gets raised by a call to startListening, when the object cannotstart
- listening.
-
- @ivar interface: the interface I tried to listen on
- @ivar port: the port I tried to listen on
- @ivar socketError: the exception I got when I tried to listen
- @type socketError: L{socket.error}
- """
- def __init__(self, interface, port, socketError):
- BindError.__init__(self, interface, port, socketError)
- self.interface = interface
- self.port = port
- self.socketError = socketError
-
- def __str__(self):
- iface = self.interface or 'any'
- return "Couldn't listen on %s:%s: %s." % (iface, self.port,
- self.socketError)
-
-
-
-class MulticastJoinError(Exception):
- """
- An attempt to join a multicast group failed.
- """
-
-
-
-class MessageLengthError(Exception):
- """Message is too long to send"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class DNSLookupError(IOError):
- """DNS lookup failed"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class ConnectInProgressError(Exception):
- """A connect operation was started and isn't done yet."""
-
-
-# connection errors
-
-class ConnectError(Exception):
- """An error occurred while connecting"""
-
- def __init__(self, osError=None, string=""):
- self.osError = osError
- Exception.__init__(self, string)
-
- def __str__(self):
- s = self.__doc__ or self.__class__.__name__
- if self.osError:
- s = '%s: %s' % (s, self.osError)
- if self.args[0]:
- s = '%s: %s' % (s, self.args[0])
- s = '%s.' % s
- return s
-
-
-
-class ConnectBindError(ConnectError):
- """Couldn't bind"""
-
-
-
-class UnknownHostError(ConnectError):
- """Hostname couldn't be looked up"""
-
-
-
-class NoRouteError(ConnectError):
- """No route to host"""
-
-
-
-class ConnectionRefusedError(ConnectError):
- """Connection was refused by other side"""
-
-
-
-class TCPTimedOutError(ConnectError):
- """TCP connection timed out"""
-
-
-
-class BadFileError(ConnectError):
- """File used for UNIX socket is no good"""
-
-
-
-class ServiceNameUnknownError(ConnectError):
- """Service name given as port is unknown"""
-
-
-
-class UserError(ConnectError):
- """User aborted connection"""
-
-
-
-class TimeoutError(UserError):
- """User timeout caused connection failure"""
-
-
-
-class SSLError(ConnectError):
- """An SSL error occurred"""
-
-
-
-class VerifyError(Exception):
- """Could not verify something that was supposed to be signed.
- """
-
-
-
-class PeerVerifyError(VerifyError):
- """The peer rejected our verify error.
- """
-
-
-
-class CertificateError(Exception):
- """
- We did not find a certificate where we expected to find one.
- """
-
-
-
-try:
- import errno
- errnoMapping = {
- errno.ENETUNREACH: NoRouteError,
- errno.ECONNREFUSED: ConnectionRefusedError,
- errno.ETIMEDOUT: TCPTimedOutError,
- }
- if hasattr(errno, "WSAECONNREFUSED"):
- errnoMapping[errno.WSAECONNREFUSED] = ConnectionRefusedError
- errnoMapping[errno.WSAENETUNREACH] = NoRouteError
-except ImportError:
- errnoMapping = {}
-
-
-
-def getConnectError(e):
- """Given a socket exception, return connection error."""
- try:
- number, string = e
- except ValueError:
- return ConnectError(string=e)
-
- if hasattr(socket, 'gaierror') and isinstance(e, socket.gaierror):
- # only works in 2.2
- klass = UnknownHostError
- else:
- klass = errnoMapping.get(number, ConnectError)
- return klass(number, string)
-
-
-
-class ConnectionClosed(Exception):
- """
- Connection was closed, whether cleanly or non-cleanly.
- """
-
-
-
-class ConnectionLost(ConnectionClosed):
- """Connection to the other side was lost in a non-clean fashion"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class ConnectionAborted(ConnectionLost):
- """
- Connection was aborted locally, using
- L{twisted.internet.interfaces.ITCPTransport.abortConnection}.
-
- @since: 11.1
- """
-
-
-
-class ConnectionDone(ConnectionClosed):
- """Connection was closed cleanly"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class FileDescriptorOverrun(ConnectionLost):
- """
- A mis-use of L{IUNIXTransport.sendFileDescriptor} caused the connection to
- be closed.
-
- Each file descriptor sent using C{sendFileDescriptor} must be associated
- with at least one byte sent using L{ITransport.write}. If at any point
- fewer bytes have been written than file descriptors have been sent, the
- connection is closed with this exception.
- """
-
-
-
-class ConnectionFdescWentAway(ConnectionLost):
- """Uh""" #TODO
-
-
-
-class AlreadyCalled(ValueError):
- """Tried to cancel an already-called event"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class AlreadyCancelled(ValueError):
- """Tried to cancel an already-cancelled event"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class PotentialZombieWarning(Warning):
- """
- Emitted when L{IReactorProcess.spawnProcess} is called in a way which may
- result in termination of the created child process not being reported.
-
- Deprecated in Twisted 10.0.
- """
- MESSAGE = (
- "spawnProcess called, but the SIGCHLD handler is not "
- "installed. This probably means you have not yet "
- "called reactor.run, or called "
- "reactor.run(installSignalHandler=0). You will probably "
- "never see this process finish, and it may become a "
- "zombie process.")
-
-deprecate.deprecatedModuleAttribute(
- Version("Twisted", 10, 0, 0),
- "There is no longer any potential for zombie process.",
- __name__,
- "PotentialZombieWarning")
-
-
-
-class ProcessDone(ConnectionDone):
- """A process has ended without apparent errors"""
-
- def __init__(self, status):
- Exception.__init__(self, "process finished with exit code 0")
- self.exitCode = 0
- self.signal = None
- self.status = status
-
-
-
-class ProcessTerminated(ConnectionLost):
- """A process has ended with a probable error condition"""
-
- def __init__(self, exitCode=None, signal=None, status=None):
- self.exitCode = exitCode
- self.signal = signal
- self.status = status
- s = "process ended"
- if exitCode is not None: s = s + " with exit code %s" % exitCode
- if signal is not None: s = s + " by signal %s" % signal
- Exception.__init__(self, s)
-
-
-
-class ProcessExitedAlready(Exception):
- """
- The process has already exited and the operation requested can no longer
- be performed.
- """
-
-
-
-class NotConnectingError(RuntimeError):
- """The Connector was not connecting when it was asked to stop connecting"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class NotListeningError(RuntimeError):
- """The Port was not listening when it was asked to stop listening"""
-
- def __str__(self):
- s = self.__doc__
- if self.args:
- s = '%s: %s' % (s, ' '.join(self.args))
- s = '%s.' % s
- return s
-
-
-
-class ReactorNotRunning(RuntimeError):
- """
- Error raised when trying to stop a reactor which is not running.
- """
-
-
-class ReactorNotRestartable(RuntimeError):
- """
- Error raised when trying to run a reactor which was stopped.
- """
-
-
-
-class ReactorAlreadyRunning(RuntimeError):
- """
- Error raised when trying to start the reactor multiple times.
- """
-
-
-class ReactorAlreadyInstalledError(AssertionError):
- """
- Could not install reactor because one is already installed.
- """
-
-
-
-class ConnectingCancelledError(Exception):
- """
- An C{Exception} that will be raised when an L{IStreamClientEndpoint} is
- cancelled before it connects.
-
- @ivar address: The L{IAddress} that is the destination of the
- cancelled L{IStreamClientEndpoint}.
- """
-
- def __init__(self, address):
- """
- @param address: The L{IAddress} that is the destination of the
- L{IStreamClientEndpoint} that was cancelled.
- """
- Exception.__init__(self, address)
- self.address = address
-
-
-
-class UnsupportedAddressFamily(Exception):
- """
- An attempt was made to use a socket with an address family (eg I{AF_INET},
- I{AF_INET6}, etc) which is not supported by the reactor.
- """
-
-
-
-class UnsupportedSocketType(Exception):
- """
- An attempt was made to use a socket of a type (eg I{SOCK_STREAM},
- I{SOCK_DGRAM}, etc) which is not supported by the reactor.
- """
-
-
-class AlreadyListened(Exception):
- """
- An attempt was made to listen on a file descriptor which can only be
- listened on once.
- """
-
-
-__all__ = [
- 'BindError', 'CannotListenError', 'MulticastJoinError',
- 'MessageLengthError', 'DNSLookupError', 'ConnectInProgressError',
- 'ConnectError', 'ConnectBindError', 'UnknownHostError', 'NoRouteError',
- 'ConnectionRefusedError', 'TCPTimedOutError', 'BadFileError',
- 'ServiceNameUnknownError', 'UserError', 'TimeoutError', 'SSLError',
- 'VerifyError', 'PeerVerifyError', 'CertificateError',
- 'getConnectError', 'ConnectionClosed', 'ConnectionLost',
- 'ConnectionDone', 'ConnectionFdescWentAway', 'AlreadyCalled',
- 'AlreadyCancelled', 'PotentialZombieWarning', 'ProcessDone',
- 'ProcessTerminated', 'ProcessExitedAlready', 'NotConnectingError',
- 'NotListeningError', 'ReactorNotRunning', 'ReactorAlreadyRunning',
- 'ReactorAlreadyInstalledError', 'ConnectingCancelledError',
- 'UnsupportedAddressFamily', 'UnsupportedSocketType']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/fdesc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/fdesc.py
deleted file mode 100755
index f4b0cdf6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/fdesc.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# -*- test-case-name: twisted.test.test_fdesc -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Utility functions for dealing with POSIX file descriptors.
-"""
-
-import os
-import errno
-try:
- import fcntl
-except ImportError:
- fcntl = None
-
-# twisted imports
-from twisted.internet.main import CONNECTION_LOST, CONNECTION_DONE
-from twisted.python.runtime import platformType
-
-def setNonBlocking(fd):
- """
- Make a file descriptor non-blocking.
- """
- flags = fcntl.fcntl(fd, fcntl.F_GETFL)
- flags = flags | os.O_NONBLOCK
- fcntl.fcntl(fd, fcntl.F_SETFL, flags)
-
-
-def setBlocking(fd):
- """
- Make a file descriptor blocking.
- """
- flags = fcntl.fcntl(fd, fcntl.F_GETFL)
- flags = flags & ~os.O_NONBLOCK
- fcntl.fcntl(fd, fcntl.F_SETFL, flags)
-
-
-if fcntl is None:
- # fcntl isn't available on Windows. By default, handles aren't
- # inherited on Windows, so we can do nothing here.
- _setCloseOnExec = _unsetCloseOnExec = lambda fd: None
-else:
- def _setCloseOnExec(fd):
- """
- Make a file descriptor close-on-exec.
- """
- flags = fcntl.fcntl(fd, fcntl.F_GETFD)
- flags = flags | fcntl.FD_CLOEXEC
- fcntl.fcntl(fd, fcntl.F_SETFD, flags)
-
-
- def _unsetCloseOnExec(fd):
- """
- Make a file descriptor close-on-exec.
- """
- flags = fcntl.fcntl(fd, fcntl.F_GETFD)
- flags = flags & ~fcntl.FD_CLOEXEC
- fcntl.fcntl(fd, fcntl.F_SETFD, flags)
-
-
-def readFromFD(fd, callback):
- """
- Read from file descriptor, calling callback with resulting data.
-
- If successful, call 'callback' with a single argument: the
- resulting data.
-
- Returns same thing FileDescriptor.doRead would: CONNECTION_LOST,
- CONNECTION_DONE, or None.
-
- @type fd: C{int}
- @param fd: non-blocking file descriptor to be read from.
- @param callback: a callable which accepts a single argument. If
- data is read from the file descriptor it will be called with this
- data. Handling exceptions from calling the callback is up to the
- caller.
-
- Note that if the descriptor is still connected but no data is read,
- None will be returned but callback will not be called.
-
- @return: CONNECTION_LOST on error, CONNECTION_DONE when fd is
- closed, otherwise None.
- """
- try:
- output = os.read(fd, 8192)
- except (OSError, IOError), ioe:
- if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
- return
- else:
- return CONNECTION_LOST
- if not output:
- return CONNECTION_DONE
- callback(output)
-
-
-def writeToFD(fd, data):
- """
- Write data to file descriptor.
-
- Returns same thing FileDescriptor.writeSomeData would.
-
- @type fd: C{int}
- @param fd: non-blocking file descriptor to be written to.
- @type data: C{str} or C{buffer}
- @param data: bytes to write to fd.
-
- @return: number of bytes written, or CONNECTION_LOST.
- """
- try:
- return os.write(fd, data)
- except (OSError, IOError), io:
- if io.errno in (errno.EAGAIN, errno.EINTR):
- return 0
- return CONNECTION_LOST
-
-
-__all__ = ["setNonBlocking", "setBlocking", "readFromFD", "writeToFD"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gireactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gireactor.py
deleted file mode 100755
index bf71bb50..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gireactor.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides support for Twisted to interact with the glib
-mainloop via GObject Introspection.
-
-In order to use this support, simply do the following::
-
- from twisted.internet import gireactor
- gireactor.install()
-
-If you wish to use a GApplication, register it with the reactor::
-
- from twisted.internet import reactor
- reactor.registerGApplication(app)
-
-Then use twisted.internet APIs as usual.
-"""
-
-import sys
-from twisted.internet.error import ReactorAlreadyRunning
-from twisted.internet import _glibbase
-from twisted.python import runtime
-
-# We can't immediately prevent imports, because that confuses some buggy code
-# in gi:
-_glibbase.ensureNotImported(
- ['gobject' 'glib', 'gio', 'gtk'],
- "Introspected and static glib/gtk bindings must not be mixed; can't "
- "import gireactor since pygtk2 module is already imported.")
-
-from gi.repository import GLib
-GLib.threads_init()
-
-_glibbase.ensureNotImported([], "",
- preventImports=['gobject' 'glib', 'gio', 'gtk'])
-
-
-
-class GIReactor(_glibbase.GlibReactorBase):
- """
- GObject-introspection event loop reactor.
-
- @ivar _gapplication: A C{Gio.Application} instance that was registered
- with C{registerGApplication}.
- """
- _POLL_DISCONNECTED = (GLib.IOCondition.HUP | GLib.IOCondition.ERR |
- GLib.IOCondition.NVAL)
- _POLL_IN = GLib.IOCondition.IN
- _POLL_OUT = GLib.IOCondition.OUT
-
- # glib's iochannel sources won't tell us about any events that we haven't
- # asked for, even if those events aren't sensible inputs to the poll()
- # call.
- INFLAGS = _POLL_IN | _POLL_DISCONNECTED
- OUTFLAGS = _POLL_OUT | _POLL_DISCONNECTED
-
- # By default no Application is registered:
- _gapplication = None
-
-
- def __init__(self, useGtk=False):
- _gtk = None
- if useGtk is True:
- from gi.repository import Gtk as _gtk
-
- _glibbase.GlibReactorBase.__init__(self, GLib, _gtk, useGtk=useGtk)
-
-
- def registerGApplication(self, app):
- """
- Register a C{Gio.Application} or C{Gtk.Application}, whose main loop
- will be used instead of the default one.
-
- We will C{hold} the application so it doesn't exit on its own. In
- versions of C{python-gi} 3.2 and later, we exit the event loop using
- the C{app.quit} method which overrides any holds. Older versions are
- not supported.
- """
- if self._gapplication is not None:
- raise RuntimeError(
- "Can't register more than one application instance.")
- if self._started:
- raise ReactorAlreadyRunning(
- "Can't register application after reactor was started.")
- if not hasattr(app, "quit"):
- raise RuntimeError("Application registration is not supported in"
- " versions of PyGObject prior to 3.2.")
- self._gapplication = app
- def run():
- app.hold()
- app.run(None)
- self._run = run
-
- self._crash = app.quit
-
-
-
-class PortableGIReactor(_glibbase.PortableGlibReactorBase):
- """
- Portable GObject Introspection event loop reactor.
- """
- def __init__(self, useGtk=False):
- _gtk = None
- if useGtk is True:
- from gi.repository import Gtk as _gtk
-
- _glibbase.PortableGlibReactorBase.__init__(self, GLib, _gtk,
- useGtk=useGtk)
-
-
- def registerGApplication(self, app):
- """
- Register a C{Gio.Application} or C{Gtk.Application}, whose main loop
- will be used instead of the default one.
- """
- raise NotImplementedError("GApplication is not currently supported on Windows.")
-
-
-
-def install(useGtk=False):
- """
- Configure the twisted mainloop to be run inside the glib mainloop.
-
- @param useGtk: should GTK+ rather than glib event loop be
- used (this will be slightly slower but does support GUI).
- """
- if runtime.platform.getType() == 'posix':
- reactor = GIReactor(useGtk=useGtk)
- else:
- reactor = PortableGIReactor(useGtk=useGtk)
-
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/glib2reactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/glib2reactor.py
deleted file mode 100755
index 5275efd8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/glib2reactor.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides support for Twisted to interact with the glib mainloop.
-This is like gtk2, but slightly faster and does not require a working
-$DISPLAY. However, you cannot run GUIs under this reactor: for that you must
-use the gtk2reactor instead.
-
-In order to use this support, simply do the following::
-
- from twisted.internet import glib2reactor
- glib2reactor.install()
-
-Then use twisted.internet APIs as usual. The other methods here are not
-intended to be called directly.
-"""
-
-from twisted.internet import gtk2reactor
-
-
-class Glib2Reactor(gtk2reactor.Gtk2Reactor):
- """
- The reactor using the glib mainloop.
- """
-
- def __init__(self):
- """
- Override init to set the C{useGtk} flag.
- """
- gtk2reactor.Gtk2Reactor.__init__(self, useGtk=False)
-
-
-
-def install():
- """
- Configure the twisted mainloop to be run inside the glib mainloop.
- """
- reactor = Glib2Reactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
-
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk2reactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk2reactor.py
deleted file mode 100755
index 65e6693d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk2reactor.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# -*- test-case-name: twisted.internet.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-This module provides support for Twisted to interact with the glib/gtk2
-mainloop.
-
-In order to use this support, simply do the following::
-
- from twisted.internet import gtk2reactor
- gtk2reactor.install()
-
-Then use twisted.internet APIs as usual. The other methods here are not
-intended to be called directly.
-"""
-
-# System Imports
-import sys
-
-# Twisted Imports
-from twisted.internet import _glibbase
-from twisted.python import runtime
-
-_glibbase.ensureNotImported(
- ["gi"],
- "Introspected and static glib/gtk bindings must not be mixed; can't "
- "import gtk2reactor since gi module is already imported.",
- preventImports=["gi"])
-
-try:
- if not hasattr(sys, 'frozen'):
- # Don't want to check this for py2exe
- import pygtk
- pygtk.require('2.0')
-except (ImportError, AttributeError):
- pass # maybe we're using pygtk before this hack existed.
-
-import gobject
-if hasattr(gobject, "threads_init"):
- # recent versions of python-gtk expose this. python-gtk=2.4.1
- # (wrapping glib-2.4.7) does. python-gtk=2.0.0 (wrapping
- # glib-2.2.3) does not.
- gobject.threads_init()
-
-
-
-class Gtk2Reactor(_glibbase.GlibReactorBase):
- """
- PyGTK+ 2 event loop reactor.
- """
- _POLL_DISCONNECTED = gobject.IO_HUP | gobject.IO_ERR | gobject.IO_NVAL
- _POLL_IN = gobject.IO_IN
- _POLL_OUT = gobject.IO_OUT
-
- # glib's iochannel sources won't tell us about any events that we haven't
- # asked for, even if those events aren't sensible inputs to the poll()
- # call.
- INFLAGS = _POLL_IN | _POLL_DISCONNECTED
- OUTFLAGS = _POLL_OUT | _POLL_DISCONNECTED
-
- def __init__(self, useGtk=True):
- _gtk = None
- if useGtk is True:
- import gtk as _gtk
-
- _glibbase.GlibReactorBase.__init__(self, gobject, _gtk, useGtk=useGtk)
-
-
-
-class PortableGtkReactor(_glibbase.PortableGlibReactorBase):
- """
- Reactor that works on Windows.
-
- Sockets aren't supported by GTK+'s input_add on Win32.
- """
- def __init__(self, useGtk=True):
- _gtk = None
- if useGtk is True:
- import gtk as _gtk
-
- _glibbase.PortableGlibReactorBase.__init__(self, gobject, _gtk,
- useGtk=useGtk)
-
-
-def install(useGtk=True):
- """
- Configure the twisted mainloop to be run inside the gtk mainloop.
-
- @param useGtk: should glib rather than GTK+ event loop be
- used (this will be slightly faster but does not support GUI).
- """
- reactor = Gtk2Reactor(useGtk)
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-
-def portableInstall(useGtk=True):
- """
- Configure the twisted mainloop to be run inside the gtk mainloop.
- """
- reactor = PortableGtkReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-
-if runtime.platform.getType() != 'posix':
- install = portableInstall
-
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk3reactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk3reactor.py
deleted file mode 100755
index d3a5864f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtk3reactor.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides support for Twisted to interact with the gtk3 mainloop
-via Gobject introspection. This is like gi, but slightly slower and requires a
-working $DISPLAY.
-
-In order to use this support, simply do the following::
-
- from twisted.internet import gtk3reactor
- gtk3reactor.install()
-
-If you wish to use a GApplication, register it with the reactor::
-
- from twisted.internet import reactor
- reactor.registerGApplication(app)
-
-Then use twisted.internet APIs as usual.
-"""
-
-from twisted.internet import gireactor
-from twisted.python import runtime
-
-
-class Gtk3Reactor(gireactor.GIReactor):
- """
- A reactor using the gtk3+ event loop.
- """
-
- def __init__(self):
- """
- Override init to set the C{useGtk} flag.
- """
- gireactor.GIReactor.__init__(self, useGtk=True)
-
-
-
-class PortableGtk3Reactor(gireactor.PortableGIReactor):
- """
- Portable GTK+ 3.x reactor.
- """
- def __init__(self):
- """
- Override init to set the C{useGtk} flag.
- """
- gireactor.PortableGIReactor.__init__(self, useGtk=True)
-
-
-
-def install():
- """
- Configure the Twisted mainloop to be run inside the gtk3+ mainloop.
- """
- if runtime.platform.getType() == 'posix':
- reactor = Gtk3Reactor()
- else:
- reactor = PortableGtk3Reactor()
-
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtkreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtkreactor.py
deleted file mode 100755
index 6b1855e9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/gtkreactor.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides support for Twisted to interact with the PyGTK mainloop.
-
-In order to use this support, simply do the following::
-
- | from twisted.internet import gtkreactor
- | gtkreactor.install()
-
-Then use twisted.internet APIs as usual. The other methods here are not
-intended to be called directly.
-"""
-
-import sys
-
-# System Imports
-try:
- import pygtk
- pygtk.require('1.2')
-except ImportError, AttributeError:
- pass # maybe we're using pygtk before this hack existed.
-import gtk
-
-from zope.interface import implements
-
-# Twisted Imports
-from twisted.python import log, runtime, deprecate, versions
-from twisted.internet.interfaces import IReactorFDSet
-
-# Sibling Imports
-from twisted.internet import posixbase, selectreactor
-
-
-deprecatedSince = versions.Version("Twisted", 10, 1, 0)
-deprecationMessage = ("All new applications should be written with gtk 2.x, "
- "which is supported by twisted.internet.gtk2reactor.")
-
-
-class GtkReactor(posixbase.PosixReactorBase):
- """
- GTK+ event loop reactor.
-
- @ivar _reads: A dictionary mapping L{FileDescriptor} instances to gtk INPUT_READ
- watch handles.
-
- @ivar _writes: A dictionary mapping L{FileDescriptor} instances to gtk
- INTPUT_WRITE watch handles.
-
- @ivar _simtag: A gtk timeout handle for the next L{simulate} call.
- """
- implements(IReactorFDSet)
-
- deprecate.deprecatedModuleAttribute(deprecatedSince, deprecationMessage,
- __name__, "GtkReactor")
-
- def __init__(self):
- """
- Initialize the file descriptor tracking dictionaries and the base
- class.
- """
- self._simtag = None
- self._reads = {}
- self._writes = {}
- posixbase.PosixReactorBase.__init__(self)
-
-
- def addReader(self, reader):
- if reader not in self._reads:
- self._reads[reader] = gtk.input_add(reader, gtk.GDK.INPUT_READ, self.callback)
-
- def addWriter(self, writer):
- if writer not in self._writes:
- self._writes[writer] = gtk.input_add(writer, gtk.GDK.INPUT_WRITE, self.callback)
-
-
- def getReaders(self):
- return self._reads.keys()
-
-
- def getWriters(self):
- return self._writes.keys()
-
-
- def removeAll(self):
- return self._removeAll(self._reads, self._writes)
-
-
- def removeReader(self, reader):
- if reader in self._reads:
- gtk.input_remove(self._reads[reader])
- del self._reads[reader]
-
- def removeWriter(self, writer):
- if writer in self._writes:
- gtk.input_remove(self._writes[writer])
- del self._writes[writer]
-
- doIterationTimer = None
-
- def doIterationTimeout(self, *args):
- self.doIterationTimer = None
- return 0 # auto-remove
- def doIteration(self, delay):
- # flush some pending events, return if there was something to do
- # don't use the usual "while gtk.events_pending(): mainiteration()"
- # idiom because lots of IO (in particular test_tcp's
- # ProperlyCloseFilesTestCase) can keep us from ever exiting.
- log.msg(channel='system', event='iteration', reactor=self)
- if gtk.events_pending():
- gtk.mainiteration(0)
- return
- # nothing to do, must delay
- if delay == 0:
- return # shouldn't delay, so just return
- self.doIterationTimer = gtk.timeout_add(int(delay * 1000),
- self.doIterationTimeout)
- # This will either wake up from IO or from a timeout.
- gtk.mainiteration(1) # block
- # note: with the .simulate timer below, delays > 0.1 will always be
- # woken up by the .simulate timer
- if self.doIterationTimer:
- # if woken by IO, need to cancel the timer
- gtk.timeout_remove(self.doIterationTimer)
- self.doIterationTimer = None
-
- def crash(self):
- posixbase.PosixReactorBase.crash(self)
- gtk.mainquit()
-
- def run(self, installSignalHandlers=1):
- self.startRunning(installSignalHandlers=installSignalHandlers)
- gtk.timeout_add(0, self.simulate)
- gtk.mainloop()
-
- def _readAndWrite(self, source, condition):
- # note: gtk-1.2's gtk_input_add presents an API in terms of gdk
- # constants like INPUT_READ and INPUT_WRITE. Internally, it will add
- # POLL_HUP and POLL_ERR to the poll() events, but if they happen it
- # will turn them back into INPUT_READ and INPUT_WRITE. gdkevents.c
- # maps IN/HUP/ERR to INPUT_READ, and OUT/ERR to INPUT_WRITE. This
- # means there is no immediate way to detect a disconnected socket.
-
- # The g_io_add_watch() API is more suited to this task. I don't think
- # pygtk exposes it, though.
- why = None
- didRead = None
- try:
- if condition & gtk.GDK.INPUT_READ:
- why = source.doRead()
- didRead = source.doRead
- if not why and condition & gtk.GDK.INPUT_WRITE:
- # if doRead caused connectionLost, don't call doWrite
- # if doRead is doWrite, don't call it again.
- if not source.disconnected and source.doWrite != didRead:
- why = source.doWrite()
- didRead = source.doWrite # if failed it was in write
- except:
- why = sys.exc_info()[1]
- log.msg('Error In %s' % source)
- log.deferr()
-
- if why:
- self._disconnectSelectable(source, why, didRead == source.doRead)
-
- def callback(self, source, condition):
- log.callWithLogger(source, self._readAndWrite, source, condition)
- self.simulate() # fire Twisted timers
- return 1 # 1=don't auto-remove the source
-
- def simulate(self):
- """Run simulation loops and reschedule callbacks.
- """
- if self._simtag is not None:
- gtk.timeout_remove(self._simtag)
- self.runUntilCurrent()
- timeout = min(self.timeout(), 0.1)
- if timeout is None:
- timeout = 0.1
- # Quoth someone other than me, "grumble", yet I know not why. Try to be
- # more specific in your complaints, guys. -exarkun
- self._simtag = gtk.timeout_add(int(timeout * 1010), self.simulate)
-
-
-
-class PortableGtkReactor(selectreactor.SelectReactor):
- """Reactor that works on Windows.
-
- input_add is not supported on GTK+ for Win32, apparently.
-
- @ivar _simtag: A gtk timeout handle for the next L{simulate} call.
- """
- _simtag = None
-
- deprecate.deprecatedModuleAttribute(deprecatedSince, deprecationMessage,
- __name__, "PortableGtkReactor")
-
- def crash(self):
- selectreactor.SelectReactor.crash(self)
- gtk.mainquit()
-
- def run(self, installSignalHandlers=1):
- self.startRunning(installSignalHandlers=installSignalHandlers)
- self.simulate()
- gtk.mainloop()
-
- def simulate(self):
- """Run simulation loops and reschedule callbacks.
- """
- if self._simtag is not None:
- gtk.timeout_remove(self._simtag)
- self.iterate()
- timeout = min(self.timeout(), 0.1)
- if timeout is None:
- timeout = 0.1
-
- # See comment for identical line in GtkReactor.simulate.
- self._simtag = gtk.timeout_add((timeout * 1010), self.simulate)
-
-
-
-def install():
- """Configure the twisted mainloop to be run inside the gtk mainloop.
- """
- reactor = GtkReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-deprecate.deprecatedModuleAttribute(deprecatedSince, deprecationMessage,
- __name__, "install")
-
-
-def portableInstall():
- """Configure the twisted mainloop to be run inside the gtk mainloop.
- """
- reactor = PortableGtkReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-deprecate.deprecatedModuleAttribute(deprecatedSince, deprecationMessage,
- __name__, "portableInstall")
-
-
-if runtime.platform.getType() != 'posix':
- install = portableInstall
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/inotify.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/inotify.py
deleted file mode 100755
index 85305dcb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/inotify.py
+++ /dev/null
@@ -1,405 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_inotify -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides support for Twisted to linux inotify API.
-
-In order to use this support, simply do the following (and start a reactor
-at some point)::
-
- from twisted.internet import inotify
- from twisted.python import filepath
-
- def notify(ignored, filepath, mask):
- \"""
- For historical reasons, an opaque handle is passed as first
- parameter. This object should never be used.
-
- @param filepath: FilePath on which the event happened.
- @param mask: inotify event as hexadecimal masks
- \"""
- print "event %s on %s" % (
- ', '.join(inotify.humanReadableMask(mask)), filepath)
-
- notifier = inotify.INotify()
- notifier.startReading()
- notifier.watch(filepath.FilePath("/some/directory"), callbacks=[notify])
-
-@since: 10.1
-"""
-
-import os
-import struct
-
-from twisted.internet import fdesc
-from twisted.internet.abstract import FileDescriptor
-from twisted.python import log, _inotify
-
-
-# from /usr/src/linux/include/linux/inotify.h
-
-IN_ACCESS = 0x00000001L # File was accessed
-IN_MODIFY = 0x00000002L # File was modified
-IN_ATTRIB = 0x00000004L # Metadata changed
-IN_CLOSE_WRITE = 0x00000008L # Writeable file was closed
-IN_CLOSE_NOWRITE = 0x00000010L # Unwriteable file closed
-IN_OPEN = 0x00000020L # File was opened
-IN_MOVED_FROM = 0x00000040L # File was moved from X
-IN_MOVED_TO = 0x00000080L # File was moved to Y
-IN_CREATE = 0x00000100L # Subfile was created
-IN_DELETE = 0x00000200L # Subfile was delete
-IN_DELETE_SELF = 0x00000400L # Self was deleted
-IN_MOVE_SELF = 0x00000800L # Self was moved
-IN_UNMOUNT = 0x00002000L # Backing fs was unmounted
-IN_Q_OVERFLOW = 0x00004000L # Event queued overflowed
-IN_IGNORED = 0x00008000L # File was ignored
-
-IN_ONLYDIR = 0x01000000 # only watch the path if it is a directory
-IN_DONT_FOLLOW = 0x02000000 # don't follow a sym link
-IN_MASK_ADD = 0x20000000 # add to the mask of an already existing watch
-IN_ISDIR = 0x40000000 # event occurred against dir
-IN_ONESHOT = 0x80000000 # only send event once
-
-IN_CLOSE = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE # closes
-IN_MOVED = IN_MOVED_FROM | IN_MOVED_TO # moves
-IN_CHANGED = IN_MODIFY | IN_ATTRIB # changes
-
-IN_WATCH_MASK = (IN_MODIFY | IN_ATTRIB |
- IN_CREATE | IN_DELETE |
- IN_DELETE_SELF | IN_MOVE_SELF |
- IN_UNMOUNT | IN_MOVED_FROM | IN_MOVED_TO)
-
-
-_FLAG_TO_HUMAN = [
- (IN_ACCESS, 'access'),
- (IN_MODIFY, 'modify'),
- (IN_ATTRIB, 'attrib'),
- (IN_CLOSE_WRITE, 'close_write'),
- (IN_CLOSE_NOWRITE, 'close_nowrite'),
- (IN_OPEN, 'open'),
- (IN_MOVED_FROM, 'moved_from'),
- (IN_MOVED_TO, 'moved_to'),
- (IN_CREATE, 'create'),
- (IN_DELETE, 'delete'),
- (IN_DELETE_SELF, 'delete_self'),
- (IN_MOVE_SELF, 'move_self'),
- (IN_UNMOUNT, 'unmount'),
- (IN_Q_OVERFLOW, 'queue_overflow'),
- (IN_IGNORED, 'ignored'),
- (IN_ONLYDIR, 'only_dir'),
- (IN_DONT_FOLLOW, 'dont_follow'),
- (IN_MASK_ADD, 'mask_add'),
- (IN_ISDIR, 'is_dir'),
- (IN_ONESHOT, 'one_shot')
-]
-
-
-
-def humanReadableMask(mask):
- """
- Auxiliary function that converts an hexadecimal mask into a series
- of human readable flags.
- """
- s = []
- for k, v in _FLAG_TO_HUMAN:
- if k & mask:
- s.append(v)
- return s
-
-
-
-class _Watch(object):
- """
- Watch object that represents a Watch point in the filesystem. The
- user should let INotify to create these objects
-
- @ivar path: The path over which this watch point is monitoring
- @ivar mask: The events monitored by this watchpoint
- @ivar autoAdd: Flag that determines whether this watch point
- should automatically add created subdirectories
- @ivar callbacks: C{list} of callback functions that will be called
- when an event occurs on this watch.
- """
- def __init__(self, path, mask=IN_WATCH_MASK, autoAdd=False,
- callbacks=None):
- self.path = path
- self.mask = mask
- self.autoAdd = autoAdd
- if callbacks is None:
- callbacks = []
- self.callbacks = callbacks
-
-
- def _notify(self, filepath, events):
- """
- Callback function used by L{INotify} to dispatch an event.
- """
- for callback in self.callbacks:
- callback(self, filepath, events)
-
-
-
-class INotify(FileDescriptor, object):
- """
- The INotify file descriptor, it basically does everything related
- to INotify, from reading to notifying watch points.
-
- @ivar _buffer: a C{str} containing the data read from the inotify fd.
-
- @ivar _watchpoints: a C{dict} that maps from inotify watch ids to
- watchpoints objects
-
- @ivar _watchpaths: a C{dict} that maps from watched paths to the
- inotify watch ids
- """
- _inotify = _inotify
-
- def __init__(self, reactor=None):
- FileDescriptor.__init__(self, reactor=reactor)
-
- # Smart way to allow parametrization of libc so I can override
- # it and test for the system errors.
- self._fd = self._inotify.init()
-
- fdesc.setNonBlocking(self._fd)
- fdesc._setCloseOnExec(self._fd)
-
- # The next 2 lines are needed to have self.loseConnection()
- # to call connectionLost() on us. Since we already created the
- # fd that talks to inotify we want to be notified even if we
- # haven't yet started reading.
- self.connected = 1
- self._writeDisconnected = True
-
- self._buffer = ''
- self._watchpoints = {}
- self._watchpaths = {}
-
-
- def _addWatch(self, path, mask, autoAdd, callbacks):
- """
- Private helper that abstracts the use of ctypes.
-
- Calls the internal inotify API and checks for any errors after the
- call. If there's an error L{INotify._addWatch} can raise an
- INotifyError. If there's no error it proceeds creating a watchpoint and
- adding a watchpath for inverse lookup of the file descriptor from the
- path.
- """
- wd = self._inotify.add(self._fd, path.path, mask)
-
- iwp = _Watch(path, mask, autoAdd, callbacks)
-
- self._watchpoints[wd] = iwp
- self._watchpaths[path] = wd
-
- return wd
-
-
- def _rmWatch(self, wd):
- """
- Private helper that abstracts the use of ctypes.
-
- Calls the internal inotify API to remove an fd from inotify then
- removes the corresponding watchpoint from the internal mapping together
- with the file descriptor from the watchpath.
- """
- self._inotify.remove(self._fd, wd)
- iwp = self._watchpoints.pop(wd)
- self._watchpaths.pop(iwp.path)
-
-
- def connectionLost(self, reason):
- """
- Release the inotify file descriptor and do the necessary cleanup
- """
- FileDescriptor.connectionLost(self, reason)
- if self._fd >= 0:
- try:
- os.close(self._fd)
- except OSError, e:
- log.err(e, "Couldn't close INotify file descriptor.")
-
-
- def fileno(self):
- """
- Get the underlying file descriptor from this inotify observer.
- Required by L{abstract.FileDescriptor} subclasses.
- """
- return self._fd
-
-
- def doRead(self):
- """
- Read some data from the observed file descriptors
- """
- fdesc.readFromFD(self._fd, self._doRead)
-
-
- def _doRead(self, in_):
- """
- Work on the data just read from the file descriptor.
- """
- self._buffer += in_
- while len(self._buffer) >= 16:
-
- wd, mask, cookie, size = struct.unpack("=LLLL", self._buffer[0:16])
-
- if size:
- name = self._buffer[16:16 + size].rstrip('\0')
- else:
- name = None
-
- self._buffer = self._buffer[16 + size:]
-
- try:
- iwp = self._watchpoints[wd]
- except KeyError:
- continue
-
- path = iwp.path
- if name:
- path = path.child(name)
- iwp._notify(path, mask)
-
- if (iwp.autoAdd and mask & IN_ISDIR and mask & IN_CREATE):
- # mask & IN_ISDIR already guarantees that the path is a
- # directory. There's no way you can get here without a
- # directory anyway, so no point in checking for that again.
- new_wd = self.watch(
- path, mask=iwp.mask, autoAdd=True,
- callbacks=iwp.callbacks
- )
- # This is very very very hacky and I'd rather not do this but
- # we have no other alternative that is less hacky other than
- # surrender. We use callLater because we don't want to have
- # too many events waiting while we process these subdirs, we
- # must always answer events as fast as possible or the overflow
- # might come.
- self.reactor.callLater(0,
- self._addChildren, self._watchpoints[new_wd])
- if mask & IN_DELETE_SELF:
- self._rmWatch(wd)
-
-
- def _addChildren(self, iwp):
- """
- This is a very private method, please don't even think about using it.
-
- Note that this is a fricking hack... it's because we cannot be fast
- enough in adding a watch to a directory and so we basically end up
- getting here too late if some operations have already been going on in
- the subdir, we basically need to catchup. This eventually ends up
- meaning that we generate double events, your app must be resistant.
- """
- try:
- listdir = iwp.path.children()
- except OSError:
- # Somebody or something (like a test) removed this directory while
- # we were in the callLater(0...) waiting. It doesn't make sense to
- # process it anymore
- return
-
- # note that it's true that listdir will only see the subdirs inside
- # path at the moment of the call but path is monitored already so if
- # something is created we will receive an event.
- for f in listdir:
- # It's a directory, watch it and then add its children
- if f.isdir():
- wd = self.watch(
- f, mask=iwp.mask, autoAdd=True,
- callbacks=iwp.callbacks
- )
- iwp._notify(f, IN_ISDIR|IN_CREATE)
- # now f is watched, we can add its children the callLater is to
- # avoid recursion
- self.reactor.callLater(0,
- self._addChildren, self._watchpoints[wd])
-
- # It's a file and we notify it.
- if f.isfile():
- iwp._notify(f, IN_CREATE|IN_CLOSE_WRITE)
-
-
- def watch(self, path, mask=IN_WATCH_MASK, autoAdd=False,
- callbacks=None, recursive=False):
- """
- Watch the 'mask' events in given path. Can raise C{INotifyError} when
- there's a problem while adding a directory.
-
- @param path: The path needing monitoring
- @type path: L{FilePath}
-
- @param mask: The events that should be watched
- @type mask: C{int}
-
- @param autoAdd: if True automatically add newly created
- subdirectories
- @type autoAdd: C{boolean}
-
- @param callbacks: A list of callbacks that should be called
- when an event happens in the given path.
- The callback should accept 3 arguments:
- (ignored, filepath, mask)
- @type callbacks: C{list} of callables
-
- @param recursive: Also add all the subdirectories in this path
- @type recursive: C{boolean}
- """
- if recursive:
- # This behavior is needed to be compatible with the windows
- # interface for filesystem changes:
- # http://msdn.microsoft.com/en-us/library/aa365465(VS.85).aspx
- # ReadDirectoryChangesW can do bWatchSubtree so it doesn't
- # make sense to implement this at an higher abstraction
- # level when other platforms support it already
- for child in path.walk():
- if child.isdir():
- self.watch(child, mask, autoAdd, callbacks,
- recursive=False)
- else:
- wd = self._isWatched(path)
- if wd:
- return wd
-
- mask = mask | IN_DELETE_SELF # need this to remove the watch
-
- return self._addWatch(path, mask, autoAdd, callbacks)
-
-
- def ignore(self, path):
- """
- Remove the watch point monitoring the given path
-
- @param path: The path that should be ignored
- @type path: L{FilePath}
- """
- wd = self._isWatched(path)
- if wd is None:
- raise KeyError("%r is not watched" % (path,))
- else:
- self._rmWatch(wd)
-
-
- def _isWatched(self, path):
- """
- Helper function that checks if the path is already monitored
- and returns its watchdescriptor if so or None otherwise.
-
- @param path: The path that should be checked
- @type path: L{FilePath}
- """
- return self._watchpaths.get(path, None)
-
-
-INotifyError = _inotify.INotifyError
-
-
-__all__ = ["INotify", "humanReadableMask", "IN_WATCH_MASK", "IN_ACCESS",
- "IN_MODIFY", "IN_ATTRIB", "IN_CLOSE_NOWRITE", "IN_CLOSE_WRITE",
- "IN_OPEN", "IN_MOVED_FROM", "IN_MOVED_TO", "IN_CREATE",
- "IN_DELETE", "IN_DELETE_SELF", "IN_MOVE_SELF", "IN_UNMOUNT",
- "IN_Q_OVERFLOW", "IN_IGNORED", "IN_ONLYDIR", "IN_DONT_FOLLOW",
- "IN_MASK_ADD", "IN_ISDIR", "IN_ONESHOT", "IN_CLOSE",
- "IN_MOVED", "IN_CHANGED"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/interfaces.py
deleted file mode 100755
index bcd5c50b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/interfaces.py
+++ /dev/null
@@ -1,2083 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Interface documentation.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-from zope.interface import Interface, Attribute
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-
-class IAddress(Interface):
- """
- An address, e.g. a TCP C{(host, port)}.
-
- Default implementations are in L{twisted.internet.address}.
- """
-
-### Reactor Interfaces
-
-class IConnector(Interface):
- """
- Object used to interface between connections and protocols.
-
- Each L{IConnector} manages one connection.
- """
-
- def stopConnecting():
- """
- Stop attempting to connect.
- """
-
- def disconnect():
- """
- Disconnect regardless of the connection state.
-
- If we are connected, disconnect, if we are trying to connect,
- stop trying.
- """
-
- def connect():
- """
- Try to connect to remote address.
- """
-
- def getDestination():
- """
- Return destination this will try to connect to.
-
- @return: An object which provides L{IAddress}.
- """
-
-
-class IResolverSimple(Interface):
-
- def getHostByName(name, timeout = (1, 3, 11, 45)):
- """
- Resolve the domain name C{name} into an IP address.
-
- @type name: C{str}
- @type timeout: C{tuple}
- @rtype: L{twisted.internet.defer.Deferred}
- @return: The callback of the Deferred that is returned will be
- passed a string that represents the IP address of the specified
- name, or the errback will be called if the lookup times out. If
- multiple types of address records are associated with the name,
- A6 records will be returned in preference to AAAA records, which
- will be returned in preference to A records. If there are multiple
- records of the type to be returned, one will be selected at random.
-
- @raise twisted.internet.defer.TimeoutError: Raised (asynchronously)
- if the name cannot be resolved within the specified timeout period.
- """
-
-class IResolver(IResolverSimple):
- def lookupRecord(name, cls, type, timeout = 10):
- """
- Lookup the records associated with the given name
- that are of the given type and in the given class.
- """
-
- def query(query, timeout = 10):
- """
- Interpret and dispatch a query object to the appropriate
- lookup* method.
- """
-
- def lookupAddress(name, timeout = 10):
- """
- Lookup the A records associated with C{name}.
- """
-
- def lookupAddress6(name, timeout = 10):
- """
- Lookup all the A6 records associated with C{name}.
- """
-
- def lookupIPV6Address(name, timeout = 10):
- """
- Lookup all the AAAA records associated with C{name}.
- """
-
- def lookupMailExchange(name, timeout = 10):
- """
- Lookup the MX records associated with C{name}.
- """
-
- def lookupNameservers(name, timeout = 10):
- """
- Lookup the the NS records associated with C{name}.
- """
-
- def lookupCanonicalName(name, timeout = 10):
- """
- Lookup the CNAME records associated with C{name}.
- """
-
- def lookupMailBox(name, timeout = 10):
- """
- Lookup the MB records associated with C{name}.
- """
-
- def lookupMailGroup(name, timeout = 10):
- """
- Lookup the MG records associated with C{name}.
- """
-
- def lookupMailRename(name, timeout = 10):
- """
- Lookup the MR records associated with C{name}.
- """
-
- def lookupPointer(name, timeout = 10):
- """
- Lookup the PTR records associated with C{name}.
- """
-
- def lookupAuthority(name, timeout = 10):
- """
- Lookup the SOA records associated with C{name}.
- """
-
- def lookupNull(name, timeout = 10):
- """
- Lookup the NULL records associated with C{name}.
- """
-
- def lookupWellKnownServices(name, timeout = 10):
- """
- Lookup the WKS records associated with C{name}.
- """
-
- def lookupHostInfo(name, timeout = 10):
- """
- Lookup the HINFO records associated with C{name}.
- """
-
- def lookupMailboxInfo(name, timeout = 10):
- """
- Lookup the MINFO records associated with C{name}.
- """
-
- def lookupText(name, timeout = 10):
- """
- Lookup the TXT records associated with C{name}.
- """
-
- def lookupResponsibility(name, timeout = 10):
- """
- Lookup the RP records associated with C{name}.
- """
-
- def lookupAFSDatabase(name, timeout = 10):
- """
- Lookup the AFSDB records associated with C{name}.
- """
-
- def lookupService(name, timeout = 10):
- """
- Lookup the SRV records associated with C{name}.
- """
-
- def lookupAllRecords(name, timeout = 10):
- """
- Lookup all records associated with C{name}.
- """
-
- def lookupZone(name, timeout = 10):
- """
- Perform a zone transfer for the given C{name}.
- """
-
-
-
-class IReactorArbitrary(Interface):
- """
- This interface is redundant with L{IReactorFDSet} and is deprecated.
- """
- deprecatedModuleAttribute(
- Version("Twisted", 10, 1, 0),
- "See IReactorFDSet.",
- __name__,
- "IReactorArbitrary")
-
-
- def listenWith(portType, *args, **kw):
- """
- Start an instance of the given C{portType} listening.
-
- @type portType: type which implements L{IListeningPort}
-
- @param portType: The object given by C{portType(*args, **kw)} will be
- started listening.
-
- @return: an object which provides L{IListeningPort}.
- """
-
-
- def connectWith(connectorType, *args, **kw):
- """
- Start an instance of the given C{connectorType} connecting.
-
- @type connectorType: type which implements L{IConnector}
-
- @param connectorType: The object given by C{connectorType(*args, **kw)}
- will be started connecting.
-
- @return: An object which provides L{IConnector}.
- """
-
-# Alias for IReactorArbitrary so that internal Twisted code can continue to
-# provide the interface without emitting a deprecation warning. This can be
-# removed when IReactorArbitrary is removed.
-_IReactorArbitrary = IReactorArbitrary
-
-
-
-class IReactorTCP(Interface):
-
- def listenTCP(port, factory, backlog=50, interface=''):
- """
- Connects a given protocol factory to the given numeric TCP/IP port.
-
- @param port: a port number on which to listen
-
- @param factory: a L{twisted.internet.protocol.ServerFactory} instance
-
- @param backlog: size of the listen queue
-
- @param interface: The local IPv4 or IPv6 address to which to bind;
- defaults to '', ie all IPv4 addresses. To bind to all IPv4 and IPv6
- addresses, you must call this method twice.
-
- @return: an object that provides L{IListeningPort}.
-
- @raise CannotListenError: as defined here
- L{twisted.internet.error.CannotListenError},
- if it cannot listen on this port (e.g., it
- cannot bind to the required port number)
- """
-
- def connectTCP(host, port, factory, timeout=30, bindAddress=None):
- """
- Connect a TCP client.
-
- @param host: a host name
-
- @param port: a port number
-
- @param factory: a L{twisted.internet.protocol.ClientFactory} instance
-
- @param timeout: number of seconds to wait before assuming the
- connection has failed.
-
- @param bindAddress: a (host, port) tuple of local address to bind
- to, or None.
-
- @return: An object which provides L{IConnector}. This connector will
- call various callbacks on the factory when a connection is
- made, failed, or lost - see
- L{ClientFactory<twisted.internet.protocol.ClientFactory>}
- docs for details.
- """
-
-class IReactorSSL(Interface):
-
- def connectSSL(host, port, factory, contextFactory, timeout=30, bindAddress=None):
- """
- Connect a client Protocol to a remote SSL socket.
-
- @param host: a host name
-
- @param port: a port number
-
- @param factory: a L{twisted.internet.protocol.ClientFactory} instance
-
- @param contextFactory: a L{twisted.internet.ssl.ClientContextFactory} object.
-
- @param timeout: number of seconds to wait before assuming the
- connection has failed.
-
- @param bindAddress: a (host, port) tuple of local address to bind to,
- or C{None}.
-
- @return: An object which provides L{IConnector}.
- """
-
- def listenSSL(port, factory, contextFactory, backlog=50, interface=''):
- """
- Connects a given protocol factory to the given numeric TCP/IP port.
- The connection is a SSL one, using contexts created by the context
- factory.
-
- @param port: a port number on which to listen
-
- @param factory: a L{twisted.internet.protocol.ServerFactory} instance
-
- @param contextFactory: a L{twisted.internet.ssl.ContextFactory} instance
-
- @param backlog: size of the listen queue
-
- @param interface: the hostname to bind to, defaults to '' (all)
- """
-
-
-
-class IReactorUNIX(Interface):
- """
- UNIX socket methods.
- """
-
- def connectUNIX(address, factory, timeout=30, checkPID=0):
- """
- Connect a client protocol to a UNIX socket.
-
- @param address: a path to a unix socket on the filesystem.
-
- @param factory: a L{twisted.internet.protocol.ClientFactory} instance
-
- @param timeout: number of seconds to wait before assuming the connection
- has failed.
-
- @param checkPID: if True, check for a pid file to verify that a server
- is listening. If C{address} is a Linux abstract namespace path,
- this must be C{False}.
-
- @return: An object which provides L{IConnector}.
- """
-
-
- def listenUNIX(address, factory, backlog=50, mode=0666, wantPID=0):
- """
- Listen on a UNIX socket.
-
- @param address: a path to a unix socket on the filesystem.
-
- @param factory: a L{twisted.internet.protocol.Factory} instance.
-
- @param backlog: number of connections to allow in backlog.
-
- @param mode: The mode (B{not} umask) to set on the unix socket. See
- platform specific documentation for information about how this
- might affect connection attempts.
- @type mode: C{int}
-
- @param wantPID: if True, create a pidfile for the socket. If C{address}
- is a Linux abstract namespace path, this must be C{False}.
-
- @return: An object which provides L{IListeningPort}.
- """
-
-
-
-class IReactorUNIXDatagram(Interface):
- """
- Datagram UNIX socket methods.
- """
-
- def connectUNIXDatagram(address, protocol, maxPacketSize=8192, mode=0666, bindAddress=None):
- """
- Connect a client protocol to a datagram UNIX socket.
-
- @param address: a path to a unix socket on the filesystem.
-
- @param protocol: a L{twisted.internet.protocol.ConnectedDatagramProtocol} instance
-
- @param maxPacketSize: maximum packet size to accept
-
- @param mode: The mode (B{not} umask) to set on the unix socket. See
- platform specific documentation for information about how this
- might affect connection attempts.
- @type mode: C{int}
-
- @param bindAddress: address to bind to
-
- @return: An object which provides L{IConnector}.
- """
-
-
- def listenUNIXDatagram(address, protocol, maxPacketSize=8192, mode=0666):
- """
- Listen on a datagram UNIX socket.
-
- @param address: a path to a unix socket on the filesystem.
-
- @param protocol: a L{twisted.internet.protocol.DatagramProtocol} instance.
-
- @param maxPacketSize: maximum packet size to accept
-
- @param mode: The mode (B{not} umask) to set on the unix socket. See
- platform specific documentation for information about how this
- might affect connection attempts.
- @type mode: C{int}
-
- @return: An object which provides L{IListeningPort}.
- """
-
-
-
-class IReactorWin32Events(Interface):
- """
- Win32 Event API methods
-
- @since: 10.2
- """
-
- def addEvent(event, fd, action):
- """
- Add a new win32 event to the event loop.
-
- @param event: a Win32 event object created using win32event.CreateEvent()
-
- @param fd: an instance of L{twisted.internet.abstract.FileDescriptor}
-
- @param action: a string that is a method name of the fd instance.
- This method is called in response to the event.
-
- @return: None
- """
-
-
- def removeEvent(event):
- """
- Remove an event.
-
- @param event: a Win32 event object added using L{IReactorWin32Events.addEvent}
-
- @return: None
- """
-
-
-
-class IReactorUDP(Interface):
- """
- UDP socket methods.
- """
-
- def listenUDP(port, protocol, interface='', maxPacketSize=8192):
- """
- Connects a given DatagramProtocol to the given numeric UDP port.
-
- @return: object which provides L{IListeningPort}.
- """
-
-
-
-class IReactorMulticast(Interface):
- """
- UDP socket methods that support multicast.
-
- IMPORTANT: This is an experimental new interface. It may change
- without backwards compatability. Suggestions are welcome.
- """
-
- def listenMulticast(port, protocol, interface='', maxPacketSize=8192,
- listenMultiple=False):
- """
- Connects a given
- L{DatagramProtocol<twisted.internet.protocol.DatagramProtocol>} to the
- given numeric UDP port.
-
- @param listenMultiple: If set to True, allows multiple sockets to
- bind to the same address and port number at the same time.
- @type listenMultiple: C{bool}
-
- @returns: An object which provides L{IListeningPort}.
-
- @see: L{twisted.internet.interfaces.IMulticastTransport}
- @see: U{http://twistedmatrix.com/documents/current/core/howto/udp.html}
- """
-
-
-
-class IReactorSocket(Interface):
- """
- Methods which allow a reactor to use externally created sockets.
-
- For example, to use C{adoptStreamPort} to implement behavior equivalent
- to that of L{IReactorTCP.listenTCP}, you might write code like this::
-
- from socket import SOMAXCONN, AF_INET, SOCK_STREAM, socket
- portSocket = socket(AF_INET, SOCK_STREAM)
- # Set FD_CLOEXEC on port, left as an exercise. Then make it into a
- # non-blocking listening port:
- portSocket.setblocking(False)
- portSocket.bind(('192.168.1.2', 12345))
- portSocket.listen(SOMAXCONN)
-
- # Now have the reactor use it as a TCP port
- port = reactor.adoptStreamPort(
- portSocket.fileno(), AF_INET, YourFactory())
-
- # portSocket itself is no longer necessary, and needs to be cleaned
- # up by us.
- portSocket.close()
-
- # Whenever the server is no longer needed, stop it as usual.
- stoppedDeferred = port.stopListening()
-
- Another potential use is to inherit a listening descriptor from a parent
- process (for example, systemd or launchd), or to receive one over a UNIX
- domain socket.
-
- Some plans for extending this interface exist. See:
-
- - U{http://twistedmatrix.com/trac/ticket/5570}: established connections
- - U{http://twistedmatrix.com/trac/ticket/5573}: AF_UNIX ports
- - U{http://twistedmatrix.com/trac/ticket/5574}: SOCK_DGRAM sockets
- """
-
- def adoptStreamPort(fileDescriptor, addressFamily, factory):
- """
- Add an existing listening I{SOCK_STREAM} socket to the reactor to
- monitor for new connections to accept and handle.
-
- @param fileDescriptor: A file descriptor associated with a socket which
- is already bound to an address and marked as listening. The socket
- must be set non-blocking. Any additional flags (for example,
- close-on-exec) must also be set by application code. Application
- code is responsible for closing the file descriptor, which may be
- done as soon as C{adoptStreamPort} returns.
- @type fileDescriptor: C{int}
-
- @param addressFamily: The address family (or I{domain}) of the socket.
- For example, L{socket.AF_INET6}.
-
- @param factory: A L{ServerFactory} instance to use to create new
- protocols to handle connections accepted via this socket.
-
- @return: An object providing L{IListeningPort}.
-
- @raise UnsupportedAddressFamily: If the given address family is not
- supported by this reactor, or not supported with the given socket
- type.
-
- @raise UnsupportedSocketType: If the given socket type is not supported
- by this reactor, or not supported with the given socket type.
- """
-
- def adoptStreamConnection(fileDescriptor, addressFamily, factory):
- """
- Add an existing connected I{SOCK_STREAM} socket to the reactor to
- monitor for data.
-
- Note that the given factory won't have its C{startFactory} and
- C{stopFactory} methods called, as there is no sensible time to call
- them in this situation.
-
- @param fileDescriptor: A file descriptor associated with a socket which
- is already connected. The socket must be set non-blocking. Any
- additional flags (for example, close-on-exec) must also be set by
- application code. Application code is responsible for closing the
- file descriptor, which may be done as soon as
- C{adoptStreamConnection} returns.
- @type fileDescriptor: C{int}
-
- @param addressFamily: The address family (or I{domain}) of the socket.
- For example, L{socket.AF_INET6}.
-
- @param factory: A L{ServerFactory} instance to use to create a new
- protocol to handle the connection via this socket.
-
- @raise UnsupportedAddressFamily: If the given address family is not
- supported by this reactor, or not supported with the given socket
- type.
-
- @raise UnsupportedSocketType: If the given socket type is not supported
- by this reactor, or not supported with the given socket type.
- """
-
-
-
-class IReactorProcess(Interface):
-
- def spawnProcess(processProtocol, executable, args=(), env={}, path=None,
- uid=None, gid=None, usePTY=0, childFDs=None):
- """
- Spawn a process, with a process protocol.
-
- @type processProtocol: L{IProcessProtocol} provider
- @param processProtocol: An object which will be notified of all
- events related to the created process.
-
- @param executable: the file name to spawn - the full path should be
- used.
-
- @param args: the command line arguments to pass to the process; a
- sequence of strings. The first string should be the
- executable's name.
-
- @type env: a C{dict} mapping C{str} to C{str}, or C{None}.
- @param env: the environment variables to pass to the child process. The
- resulting behavior varies between platforms. If
- - C{env} is not set:
- - On POSIX: pass an empty environment.
- - On Windows: pass C{os.environ}.
- - C{env} is C{None}:
- - On POSIX: pass C{os.environ}.
- - On Windows: pass C{os.environ}.
- - C{env} is a C{dict}:
- - On POSIX: pass the key/value pairs in C{env} as the
- complete environment.
- - On Windows: update C{os.environ} with the key/value
- pairs in the C{dict} before passing it. As a
- consequence of U{bug #1640
- <http://twistedmatrix.com/trac/ticket/1640>}, passing
- keys with empty values in an effort to unset
- environment variables I{won't} unset them.
-
- @param path: the path to run the subprocess in - defaults to the
- current directory.
-
- @param uid: user ID to run the subprocess as. (Only available on
- POSIX systems.)
-
- @param gid: group ID to run the subprocess as. (Only available on
- POSIX systems.)
-
- @param usePTY: if true, run this process in a pseudo-terminal.
- optionally a tuple of C{(masterfd, slavefd, ttyname)},
- in which case use those file descriptors.
- (Not available on all systems.)
-
- @param childFDs: A dictionary mapping file descriptors in the new child
- process to an integer or to the string 'r' or 'w'.
-
- If the value is an integer, it specifies a file
- descriptor in the parent process which will be mapped
- to a file descriptor (specified by the key) in the
- child process. This is useful for things like inetd
- and shell-like file redirection.
-
- If it is the string 'r', a pipe will be created and
- attached to the child at that file descriptor: the
- child will be able to write to that file descriptor
- and the parent will receive read notification via the
- L{IProcessProtocol.childDataReceived} callback. This
- is useful for the child's stdout and stderr.
-
- If it is the string 'w', similar setup to the previous
- case will occur, with the pipe being readable by the
- child instead of writeable. The parent process can
- write to that file descriptor using
- L{IProcessTransport.writeToChild}. This is useful for
- the child's stdin.
-
- If childFDs is not passed, the default behaviour is to
- use a mapping that opens the usual stdin/stdout/stderr
- pipes.
-
- @see: L{twisted.internet.protocol.ProcessProtocol}
-
- @return: An object which provides L{IProcessTransport}.
-
- @raise OSError: Raised with errno C{EAGAIN} or C{ENOMEM} if there are
- insufficient system resources to create a new process.
- """
-
-class IReactorTime(Interface):
- """
- Time methods that a Reactor should implement.
- """
-
- def seconds():
- """
- Get the current time in seconds.
-
- @return: A number-like object of some sort.
- """
-
-
- def callLater(delay, callable, *args, **kw):
- """
- Call a function later.
-
- @type delay: C{float}
- @param delay: the number of seconds to wait.
-
- @param callable: the callable object to call later.
-
- @param args: the arguments to call it with.
-
- @param kw: the keyword arguments to call it with.
-
- @return: An object which provides L{IDelayedCall} and can be used to
- cancel the scheduled call, by calling its C{cancel()} method.
- It also may be rescheduled by calling its C{delay()} or
- C{reset()} methods.
- """
-
-
- def getDelayedCalls():
- """
- Retrieve all currently scheduled delayed calls.
-
- @return: A tuple of all L{IDelayedCall} providers representing all
- currently scheduled calls. This is everything that has been
- returned by C{callLater} but not yet called or canceled.
- """
-
-
-class IDelayedCall(Interface):
- """
- A scheduled call.
-
- There are probably other useful methods we can add to this interface;
- suggestions are welcome.
- """
-
- def getTime():
- """
- Get time when delayed call will happen.
-
- @return: time in seconds since epoch (a float).
- """
-
- def cancel():
- """
- Cancel the scheduled call.
-
- @raises twisted.internet.error.AlreadyCalled: if the call has already
- happened.
- @raises twisted.internet.error.AlreadyCancelled: if the call has already
- been cancelled.
- """
-
- def delay(secondsLater):
- """
- Delay the scheduled call.
-
- @param secondsLater: how many seconds from its current firing time to delay
-
- @raises twisted.internet.error.AlreadyCalled: if the call has already
- happened.
- @raises twisted.internet.error.AlreadyCancelled: if the call has already
- been cancelled.
- """
-
- def reset(secondsFromNow):
- """
- Reset the scheduled call's timer.
-
- @param secondsFromNow: how many seconds from now it should fire,
- equivalent to C{.cancel()} and then doing another
- C{reactor.callLater(secondsLater, ...)}
-
- @raises twisted.internet.error.AlreadyCalled: if the call has already
- happened.
- @raises twisted.internet.error.AlreadyCancelled: if the call has already
- been cancelled.
- """
-
- def active():
- """
- @return: True if this call is still active, False if it has been
- called or cancelled.
- """
-
-class IReactorThreads(Interface):
- """
- Dispatch methods to be run in threads.
-
- Internally, this should use a thread pool and dispatch methods to them.
- """
-
- def getThreadPool():
- """
- Return the threadpool used by L{callInThread}. Create it first if
- necessary.
-
- @rtype: L{twisted.python.threadpool.ThreadPool}
- """
-
-
- def callInThread(callable, *args, **kwargs):
- """
- Run the callable object in a separate thread.
- """
-
-
- def callFromThread(callable, *args, **kw):
- """
- Cause a function to be executed by the reactor thread.
-
- Use this method when you want to run a function in the reactor's thread
- from another thread. Calling L{callFromThread} should wake up the main
- thread (where L{reactor.run()<reactor.run>} is executing) and run the
- given callable in that thread.
-
- If you're writing a multi-threaded application the C{callable} may need
- to be thread safe, but this method doesn't require it as such. If you
- want to call a function in the next mainloop iteration, but you're in
- the same thread, use L{callLater} with a delay of 0.
- """
-
-
- def suggestThreadPoolSize(size):
- """
- Suggest the size of the internal threadpool used to dispatch functions
- passed to L{callInThread}.
- """
-
-
-class IReactorCore(Interface):
- """
- Core methods that a Reactor must implement.
- """
-
- running = Attribute(
- "A C{bool} which is C{True} from I{during startup} to "
- "I{during shutdown} and C{False} the rest of the time.")
-
-
- def resolve(name, timeout=10):
- """
- Return a L{twisted.internet.defer.Deferred} that will resolve a hostname.
- """
-
- def run():
- """
- Fire 'startup' System Events, move the reactor to the 'running'
- state, then run the main loop until it is stopped with C{stop()} or
- C{crash()}.
- """
-
- def stop():
- """
- Fire 'shutdown' System Events, which will move the reactor to the
- 'stopped' state and cause C{reactor.run()} to exit.
- """
-
- def crash():
- """
- Stop the main loop *immediately*, without firing any system events.
-
- This is named as it is because this is an extremely "rude" thing to do;
- it is possible to lose data and put your system in an inconsistent
- state by calling this. However, it is necessary, as sometimes a system
- can become wedged in a pre-shutdown call.
- """
-
- def iterate(delay=0):
- """
- Run the main loop's I/O polling function for a period of time.
-
- This is most useful in applications where the UI is being drawn "as
- fast as possible", such as games. All pending L{IDelayedCall}s will
- be called.
-
- The reactor must have been started (via the C{run()} method) prior to
- any invocations of this method. It must also be stopped manually
- after the last call to this method (via the C{stop()} method). This
- method is not re-entrant: you must not call it recursively; in
- particular, you must not call it while the reactor is running.
- """
-
- def fireSystemEvent(eventType):
- """
- Fire a system-wide event.
-
- System-wide events are things like 'startup', 'shutdown', and
- 'persist'.
- """
-
- def addSystemEventTrigger(phase, eventType, callable, *args, **kw):
- """
- Add a function to be called when a system event occurs.
-
- Each "system event" in Twisted, such as 'startup', 'shutdown', and
- 'persist', has 3 phases: 'before', 'during', and 'after' (in that
- order, of course). These events will be fired internally by the
- Reactor.
-
- An implementor of this interface must only implement those events
- described here.
-
- Callbacks registered for the "before" phase may return either None or a
- Deferred. The "during" phase will not execute until all of the
- Deferreds from the "before" phase have fired.
-
- Once the "during" phase is running, all of the remaining triggers must
- execute; their return values must be ignored.
-
- @param phase: a time to call the event -- either the string 'before',
- 'after', or 'during', describing when to call it
- relative to the event's execution.
-
- @param eventType: this is a string describing the type of event.
-
- @param callable: the object to call before shutdown.
-
- @param args: the arguments to call it with.
-
- @param kw: the keyword arguments to call it with.
-
- @return: an ID that can be used to remove this call with
- removeSystemEventTrigger.
- """
-
- def removeSystemEventTrigger(triggerID):
- """
- Removes a trigger added with addSystemEventTrigger.
-
- @param triggerID: a value returned from addSystemEventTrigger.
-
- @raise KeyError: If there is no system event trigger for the given
- C{triggerID}.
-
- @raise ValueError: If there is no system event trigger for the given
- C{triggerID}.
-
- @raise TypeError: If there is no system event trigger for the given
- C{triggerID}.
- """
-
- def callWhenRunning(callable, *args, **kw):
- """
- Call a function when the reactor is running.
-
- If the reactor has not started, the callable will be scheduled
- to run when it does start. Otherwise, the callable will be invoked
- immediately.
-
- @param callable: the callable object to call later.
-
- @param args: the arguments to call it with.
-
- @param kw: the keyword arguments to call it with.
-
- @return: None if the callable was invoked, otherwise a system
- event id for the scheduled call.
- """
-
-
-class IReactorPluggableResolver(Interface):
- """
- A reactor with a pluggable name resolver interface.
- """
-
- def installResolver(resolver):
- """
- Set the internal resolver to use to for name lookups.
-
- @type resolver: An object implementing the L{IResolverSimple} interface
- @param resolver: The new resolver to use.
-
- @return: The previously installed resolver.
- """
-
-
-class IReactorDaemonize(Interface):
- """
- A reactor which provides hooks that need to be called before and after
- daemonization.
-
- Notes:
- - This interface SHOULD NOT be called by applications.
- - This interface should only be implemented by reactors as a workaround
- (in particular, it's implemented currently only by kqueue()).
- For details please see the comments on ticket #1918.
- """
-
- def beforeDaemonize():
- """
- Hook to be called immediately before daemonization. No reactor methods
- may be called until L{afterDaemonize} is called.
-
- @return: C{None}.
- """
-
-
- def afterDaemonize():
- """
- Hook to be called immediately after daemonization. This may only be
- called after L{beforeDaemonize} had been called previously.
-
- @return: C{None}.
- """
-
-
-
-class IReactorFDSet(Interface):
- """
- Implement me to be able to use L{IFileDescriptor} type resources.
-
- This assumes that your main-loop uses UNIX-style numeric file descriptors
- (or at least similarly opaque IDs returned from a .fileno() method)
- """
-
- def addReader(reader):
- """
- I add reader to the set of file descriptors to get read events for.
-
- @param reader: An L{IReadDescriptor} provider that will be checked for
- read events until it is removed from the reactor with
- L{removeReader}.
-
- @return: C{None}.
- """
-
- def addWriter(writer):
- """
- I add writer to the set of file descriptors to get write events for.
-
- @param writer: An L{IWriteDescriptor} provider that will be checked for
- write events until it is removed from the reactor with
- L{removeWriter}.
-
- @return: C{None}.
- """
-
- def removeReader(reader):
- """
- Removes an object previously added with L{addReader}.
-
- @return: C{None}.
- """
-
- def removeWriter(writer):
- """
- Removes an object previously added with L{addWriter}.
-
- @return: C{None}.
- """
-
- def removeAll():
- """
- Remove all readers and writers.
-
- Should not remove reactor internal reactor connections (like a waker).
-
- @return: A list of L{IReadDescriptor} and L{IWriteDescriptor} providers
- which were removed.
- """
-
- def getReaders():
- """
- Return the list of file descriptors currently monitored for input
- events by the reactor.
-
- @return: the list of file descriptors monitored for input events.
- @rtype: C{list} of C{IReadDescriptor}
- """
-
- def getWriters():
- """
- Return the list file descriptors currently monitored for output events
- by the reactor.
-
- @return: the list of file descriptors monitored for output events.
- @rtype: C{list} of C{IWriteDescriptor}
- """
-
-
-class IListeningPort(Interface):
- """
- A listening port.
- """
-
- def startListening():
- """
- Start listening on this port.
-
- @raise CannotListenError: If it cannot listen on this port (e.g., it is
- a TCP port and it cannot bind to the required
- port number).
- """
-
- def stopListening():
- """
- Stop listening on this port.
-
- If it does not complete immediately, will return Deferred that fires
- upon completion.
- """
-
- def getHost():
- """
- Get the host that this port is listening for.
-
- @return: An L{IAddress} provider.
- """
-
-
-class ILoggingContext(Interface):
- """
- Give context information that will be used to log events generated by
- this item.
- """
-
- def logPrefix():
- """
- @return: Prefix used during log formatting to indicate context.
- @rtype: C{str}
- """
-
-
-
-class IFileDescriptor(ILoggingContext):
- """
- An interface representing a UNIX-style numeric file descriptor.
- """
-
- def fileno():
- """
- @raise: If the descriptor no longer has a valid file descriptor
- number associated with it.
-
- @return: The platform-specified representation of a file descriptor
- number. Or C{-1} if the descriptor no longer has a valid file
- descriptor number associated with it. As long as the descriptor
- is valid, calls to this method on a particular instance must
- return the same value.
- """
-
-
- def connectionLost(reason):
- """
- Called when the connection was lost.
-
- This is called when the connection on a selectable object has been
- lost. It will be called whether the connection was closed explicitly,
- an exception occurred in an event handler, or the other end of the
- connection closed it first.
-
- See also L{IHalfCloseableDescriptor} if your descriptor wants to be
- notified separately of the two halves of the connection being closed.
-
- @param reason: A failure instance indicating the reason why the
- connection was lost. L{error.ConnectionLost} and
- L{error.ConnectionDone} are of special note, but the
- failure may be of other classes as well.
- """
-
-
-
-class IReadDescriptor(IFileDescriptor):
- """
- An L{IFileDescriptor} that can read.
-
- This interface is generally used in conjunction with L{IReactorFDSet}.
- """
-
- def doRead():
- """
- Some data is available for reading on your descriptor.
-
- @return: If an error is encountered which causes the descriptor to
- no longer be valid, a L{Failure} should be returned. Otherwise,
- C{None}.
- """
-
-
-class IWriteDescriptor(IFileDescriptor):
- """
- An L{IFileDescriptor} that can write.
-
- This interface is generally used in conjunction with L{IReactorFDSet}.
- """
-
- def doWrite():
- """
- Some data can be written to your descriptor.
-
- @return: If an error is encountered which causes the descriptor to
- no longer be valid, a L{Failure} should be returned. Otherwise,
- C{None}.
- """
-
-
-class IReadWriteDescriptor(IReadDescriptor, IWriteDescriptor):
- """
- An L{IFileDescriptor} that can both read and write.
- """
-
-
-class IHalfCloseableDescriptor(Interface):
- """
- A descriptor that can be half-closed.
- """
-
- def writeConnectionLost(reason):
- """
- Indicates write connection was lost.
- """
-
- def readConnectionLost(reason):
- """
- Indicates read connection was lost.
- """
-
-
-class ISystemHandle(Interface):
- """
- An object that wraps a networking OS-specific handle.
- """
-
- def getHandle():
- """
- Return a system- and reactor-specific handle.
-
- This might be a socket.socket() object, or some other type of
- object, depending on which reactor is being used. Use and
- manipulate at your own risk.
-
- This might be used in cases where you want to set specific
- options not exposed by the Twisted APIs.
- """
-
-
-class IConsumer(Interface):
- """
- A consumer consumes data from a producer.
- """
-
- def registerProducer(producer, streaming):
- """
- Register to receive data from a producer.
-
- This sets self to be a consumer for a producer. When this object runs
- out of data (as when a send(2) call on a socket succeeds in moving the
- last data from a userspace buffer into a kernelspace buffer), it will
- ask the producer to resumeProducing().
-
- For L{IPullProducer} providers, C{resumeProducing} will be called once
- each time data is required.
-
- For L{IPushProducer} providers, C{pauseProducing} will be called
- whenever the write buffer fills up and C{resumeProducing} will only be
- called when it empties.
-
- @type producer: L{IProducer} provider
-
- @type streaming: C{bool}
- @param streaming: C{True} if C{producer} provides L{IPushProducer},
- C{False} if C{producer} provides L{IPullProducer}.
-
- @raise RuntimeError: If a producer is already registered.
-
- @return: C{None}
- """
-
-
- def unregisterProducer():
- """
- Stop consuming data from a producer, without disconnecting.
- """
-
-
- def write(data):
- """
- The producer will write data by calling this method.
-
- The implementation must be non-blocking and perform whatever
- buffering is necessary. If the producer has provided enough data
- for now and it is a L{IPushProducer}, the consumer may call its
- C{pauseProducing} method.
- """
-
-
-
-deprecatedModuleAttribute(Version("Twisted", 11, 1, 0),
- "Please use IConsumer (and IConsumer.unregisterProducer) instead.",
- __name__, "IFinishableConsumer")
-
-class IFinishableConsumer(IConsumer):
- """
- A Consumer for producers that finish. This interface offers no advantages
- over L{IConsumer} and is deprecated. Please use
- L{IConsumer.unregisterProducer} instead of L{IFinishableConsumer.finish}.
- """
-
- def finish():
- """
- The producer has finished producing. This method is deprecated.
- Please use L{IConsumer.unregisterProducer} instead.
- """
-
-
-
-class IProducer(Interface):
- """
- A producer produces data for a consumer.
-
- Typically producing is done by calling the write method of an class
- implementing L{IConsumer}.
- """
-
- def stopProducing():
- """
- Stop producing data.
-
- This tells a producer that its consumer has died, so it must stop
- producing data for good.
- """
-
-
-class IPushProducer(IProducer):
- """
- A push producer, also known as a streaming producer is expected to
- produce (write to this consumer) data on a continuous basis, unless
- it has been paused. A paused push producer will resume producing
- after its resumeProducing() method is called. For a push producer
- which is not pauseable, these functions may be noops.
- """
-
- def pauseProducing():
- """
- Pause producing data.
-
- Tells a producer that it has produced too much data to process for
- the time being, and to stop until resumeProducing() is called.
- """
- def resumeProducing():
- """
- Resume producing data.
-
- This tells a producer to re-add itself to the main loop and produce
- more data for its consumer.
- """
-
-class IPullProducer(IProducer):
- """
- A pull producer, also known as a non-streaming producer, is
- expected to produce data each time resumeProducing() is called.
- """
-
- def resumeProducing():
- """
- Produce data for the consumer a single time.
-
- This tells a producer to produce data for the consumer once
- (not repeatedly, once only). Typically this will be done
- by calling the consumer's write() method a single time with
- produced data.
- """
-
-class IProtocol(Interface):
-
- def dataReceived(data):
- """
- Called whenever data is received.
-
- Use this method to translate to a higher-level message. Usually, some
- callback will be made upon the receipt of each complete protocol
- message.
-
- @param data: a string of indeterminate length. Please keep in mind
- that you will probably need to buffer some data, as partial
- (or multiple) protocol messages may be received! I recommend
- that unit tests for protocols call through to this method with
- differing chunk sizes, down to one byte at a time.
- """
-
- def connectionLost(reason):
- """
- Called when the connection is shut down.
-
- Clear any circular references here, and any external references
- to this Protocol. The connection has been closed. The C{reason}
- Failure wraps a L{twisted.internet.error.ConnectionDone} or
- L{twisted.internet.error.ConnectionLost} instance (or a subclass
- of one of those).
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
- def makeConnection(transport):
- """
- Make a connection to a transport and a server.
- """
-
- def connectionMade():
- """
- Called when a connection is made.
-
- This may be considered the initializer of the protocol, because
- it is called when the connection is completed. For clients,
- this is called once the connection to the server has been
- established; for servers, this is called after an accept() call
- stops blocking and a socket has been received. If you need to
- send any greeting or initial message, do it here.
- """
-
-
-class IProcessProtocol(Interface):
- """
- Interface for process-related event handlers.
- """
-
- def makeConnection(process):
- """
- Called when the process has been created.
-
- @type process: L{IProcessTransport} provider
- @param process: An object representing the process which has been
- created and associated with this protocol.
- """
-
-
- def childDataReceived(childFD, data):
- """
- Called when data arrives from the child process.
-
- @type childFD: C{int}
- @param childFD: The file descriptor from which the data was
- received.
-
- @type data: C{str}
- @param data: The data read from the child's file descriptor.
- """
-
-
- def childConnectionLost(childFD):
- """
- Called when a file descriptor associated with the child process is
- closed.
-
- @type childFD: C{int}
- @param childFD: The file descriptor which was closed.
- """
-
-
- def processExited(reason):
- """
- Called when the child process exits.
-
- @type reason: L{twisted.python.failure.Failure}
- @param reason: A failure giving the reason the child process
- terminated. The type of exception for this failure is either
- L{twisted.internet.error.ProcessDone} or
- L{twisted.internet.error.ProcessTerminated}.
-
- @since: 8.2
- """
-
-
- def processEnded(reason):
- """
- Called when the child process exits and all file descriptors associated
- with it have been closed.
-
- @type reason: L{twisted.python.failure.Failure}
- @param reason: A failure giving the reason the child process
- terminated. The type of exception for this failure is either
- L{twisted.internet.error.ProcessDone} or
- L{twisted.internet.error.ProcessTerminated}.
- """
-
-
-
-class IHalfCloseableProtocol(Interface):
- """
- Implemented to indicate they want notification of half-closes.
-
- TCP supports the notion of half-closing the connection, e.g.
- closing the write side but still not stopping reading. A protocol
- that implements this interface will be notified of such events,
- instead of having connectionLost called.
- """
-
- def readConnectionLost():
- """
- Notification of the read connection being closed.
-
- This indicates peer did half-close of write side. It is now
- the responsibility of the this protocol to call
- loseConnection(). In addition, the protocol MUST make sure a
- reference to it still exists (i.e. by doing a callLater with
- one of its methods, etc.) as the reactor will only have a
- reference to it if it is writing.
-
- If the protocol does not do so, it might get garbage collected
- without the connectionLost method ever being called.
- """
-
- def writeConnectionLost():
- """
- Notification of the write connection being closed.
-
- This will never be called for TCP connections as TCP does not
- support notification of this type of half-close.
- """
-
-
-
-class IFileDescriptorReceiver(Interface):
- """
- Protocols may implement L{IFileDescriptorReceiver} to receive file
- descriptors sent to them. This is useful in conjunction with
- L{IUNIXTransport}, which allows file descriptors to be sent between
- processes on a single host.
- """
- def fileDescriptorReceived(descriptor):
- """
- Called when a file descriptor is received over the connection.
-
- @param descriptor: The descriptor which was received.
- @type descriptor: C{int}
-
- @return: C{None}
- """
-
-
-
-class IProtocolFactory(Interface):
- """
- Interface for protocol factories.
- """
-
- def buildProtocol(addr):
- """
- Called when a connection has been established to addr.
-
- If None is returned, the connection is assumed to have been refused,
- and the Port will close the connection.
-
- @type addr: (host, port)
- @param addr: The address of the newly-established connection
-
- @return: None if the connection was refused, otherwise an object
- providing L{IProtocol}.
- """
-
- def doStart():
- """
- Called every time this is connected to a Port or Connector.
- """
-
- def doStop():
- """
- Called every time this is unconnected from a Port or Connector.
- """
-
-
-class ITransport(Interface):
- """
- I am a transport for bytes.
-
- I represent (and wrap) the physical connection and synchronicity
- of the framework which is talking to the network. I make no
- representations about whether calls to me will happen immediately
- or require returning to a control loop, or whether they will happen
- in the same or another thread. Consider methods of this class
- (aside from getPeer) to be 'thrown over the wall', to happen at some
- indeterminate time.
- """
-
- def write(data):
- """
- Write some data to the physical connection, in sequence, in a
- non-blocking fashion.
-
- If possible, make sure that it is all written. No data will
- ever be lost, although (obviously) the connection may be closed
- before it all gets through.
- """
-
- def writeSequence(data):
- """
- Write a list of strings to the physical connection.
-
- If possible, make sure that all of the data is written to
- the socket at once, without first copying it all into a
- single string.
- """
-
- def loseConnection():
- """
- Close my connection, after writing all pending data.
-
- Note that if there is a registered producer on a transport it
- will not be closed until the producer has been unregistered.
- """
-
- def getPeer():
- """
- Get the remote address of this connection.
-
- Treat this method with caution. It is the unfortunate result of the
- CGI and Jabber standards, but should not be considered reliable for
- the usual host of reasons; port forwarding, proxying, firewalls, IP
- masquerading, etc.
-
- @return: An L{IAddress} provider.
- """
-
- def getHost():
- """
- Similar to getPeer, but returns an address describing this side of the
- connection.
-
- @return: An L{IAddress} provider.
- """
-
-
-class ITCPTransport(ITransport):
- """
- A TCP based transport.
- """
-
- def loseWriteConnection():
- """
- Half-close the write side of a TCP connection.
-
- If the protocol instance this is attached to provides
- IHalfCloseableProtocol, it will get notified when the operation is
- done. When closing write connection, as with loseConnection this will
- only happen when buffer has emptied and there is no registered
- producer.
- """
-
-
- def abortConnection():
- """
- Close the connection abruptly.
-
- Discards any buffered data, stops any registered producer,
- and, if possible, notifies the other end of the unclean
- closure.
-
- @since: 11.1
- """
-
-
- def getTcpNoDelay():
- """
- Return if C{TCP_NODELAY} is enabled.
- """
-
- def setTcpNoDelay(enabled):
- """
- Enable/disable C{TCP_NODELAY}.
-
- Enabling C{TCP_NODELAY} turns off Nagle's algorithm. Small packets are
- sent sooner, possibly at the expense of overall throughput.
- """
-
- def getTcpKeepAlive():
- """
- Return if C{SO_KEEPALIVE} is enabled.
- """
-
- def setTcpKeepAlive(enabled):
- """
- Enable/disable C{SO_KEEPALIVE}.
-
- Enabling C{SO_KEEPALIVE} sends packets periodically when the connection
- is otherwise idle, usually once every two hours. They are intended
- to allow detection of lost peers in a non-infinite amount of time.
- """
-
- def getHost():
- """
- Returns L{IPv4Address} or L{IPv6Address}.
- """
-
- def getPeer():
- """
- Returns L{IPv4Address} or L{IPv6Address}.
- """
-
-
-
-class IUNIXTransport(ITransport):
- """
- Transport for stream-oriented unix domain connections.
- """
- def sendFileDescriptor(descriptor):
- """
- Send a duplicate of this (file, socket, pipe, etc) descriptor to the
- other end of this connection.
-
- The send is non-blocking and will be queued if it cannot be performed
- immediately. The send will be processed in order with respect to other
- C{sendFileDescriptor} calls on this transport, but not necessarily with
- respect to C{write} calls on this transport. The send can only be
- processed if there are also bytes in the normal connection-oriented send
- buffer (ie, you must call C{write} at least as many times as you call
- C{sendFileDescriptor}).
-
- @param descriptor: An C{int} giving a valid file descriptor in this
- process. Note that a I{file descriptor} may actually refer to a
- socket, a pipe, or anything else POSIX tries to treat in the same
- way as a file.
-
- @return: C{None}
- """
-
-
-
-class ITLSTransport(ITCPTransport):
- """
- A TCP transport that supports switching to TLS midstream.
-
- Once TLS mode is started the transport will implement L{ISSLTransport}.
- """
-
- def startTLS(contextFactory):
- """
- Initiate TLS negotiation.
-
- @param contextFactory: A context factory (see L{ssl.py<twisted.internet.ssl>})
- """
-
-class ISSLTransport(ITCPTransport):
- """
- A SSL/TLS based transport.
- """
-
- def getPeerCertificate():
- """
- Return an object with the peer's certificate info.
- """
-
-
-class IProcessTransport(ITransport):
- """
- A process transport.
- """
-
- pid = Attribute(
- "From before L{IProcessProtocol.makeConnection} is called to before "
- "L{IProcessProtocol.processEnded} is called, C{pid} is an L{int} "
- "giving the platform process ID of this process. C{pid} is L{None} "
- "at all other times.")
-
- def closeStdin():
- """
- Close stdin after all data has been written out.
- """
-
- def closeStdout():
- """
- Close stdout.
- """
-
- def closeStderr():
- """
- Close stderr.
- """
-
- def closeChildFD(descriptor):
- """
- Close a file descriptor which is connected to the child process, identified
- by its FD in the child process.
- """
-
- def writeToChild(childFD, data):
- """
- Similar to L{ITransport.write} but also allows the file descriptor in
- the child process which will receive the bytes to be specified.
-
- @type childFD: C{int}
- @param childFD: The file descriptor to which to write.
-
- @type data: C{str}
- @param data: The bytes to write.
-
- @return: C{None}
-
- @raise KeyError: If C{childFD} is not a file descriptor that was mapped
- in the child when L{IReactorProcess.spawnProcess} was used to create
- it.
- """
-
- def loseConnection():
- """
- Close stdin, stderr and stdout.
- """
-
- def signalProcess(signalID):
- """
- Send a signal to the process.
-
- @param signalID: can be
- - one of C{"KILL"}, C{"TERM"}, or C{"INT"}.
- These will be implemented in a
- cross-platform manner, and so should be used
- if possible.
- - an integer, where it represents a POSIX
- signal ID.
-
- @raise twisted.internet.error.ProcessExitedAlready: If the process has
- already exited.
- @raise OSError: If the C{os.kill} call fails with an errno different
- from C{ESRCH}.
- """
-
-
-class IServiceCollection(Interface):
- """
- An object which provides access to a collection of services.
- """
-
- def getServiceNamed(serviceName):
- """
- Retrieve the named service from this application.
-
- Raise a C{KeyError} if there is no such service name.
- """
-
- def addService(service):
- """
- Add a service to this collection.
- """
-
- def removeService(service):
- """
- Remove a service from this collection.
- """
-
-
-class IUDPTransport(Interface):
- """
- Transport for UDP DatagramProtocols.
- """
-
- def write(packet, addr=None):
- """
- Write packet to given address.
-
- @param addr: a tuple of (ip, port). For connected transports must
- be the address the transport is connected to, or None.
- In non-connected mode this is mandatory.
-
- @raise twisted.internet.error.MessageLengthError: C{packet} was too
- long.
- """
-
- def connect(host, port):
- """
- Connect the transport to an address.
-
- This changes it to connected mode. Datagrams can only be sent to
- this address, and will only be received from this address. In addition
- the protocol's connectionRefused method might get called if destination
- is not receiving datagrams.
-
- @param host: an IP address, not a domain name ('127.0.0.1', not 'localhost')
- @param port: port to connect to.
- """
-
- def getHost():
- """
- Returns L{IPv4Address}.
- """
-
- def stopListening():
- """
- Stop listening on this port.
-
- If it does not complete immediately, will return L{Deferred} that fires
- upon completion.
- """
-
-
-
-class IUNIXDatagramTransport(Interface):
- """
- Transport for UDP PacketProtocols.
- """
-
- def write(packet, address):
- """
- Write packet to given address.
- """
-
- def getHost():
- """
- Returns L{UNIXAddress}.
- """
-
-
-class IUNIXDatagramConnectedTransport(Interface):
- """
- Transport for UDP ConnectedPacketProtocols.
- """
-
- def write(packet):
- """
- Write packet to address we are connected to.
- """
-
- def getHost():
- """
- Returns L{UNIXAddress}.
- """
-
- def getPeer():
- """
- Returns L{UNIXAddress}.
- """
-
-
-class IMulticastTransport(Interface):
- """
- Additional functionality for multicast UDP.
- """
-
- def getOutgoingInterface():
- """
- Return interface of outgoing multicast packets.
- """
-
- def setOutgoingInterface(addr):
- """
- Set interface for outgoing multicast packets.
-
- Returns Deferred of success.
- """
-
- def getLoopbackMode():
- """
- Return if loopback mode is enabled.
- """
-
- def setLoopbackMode(mode):
- """
- Set if loopback mode is enabled.
- """
-
- def getTTL():
- """
- Get time to live for multicast packets.
- """
-
- def setTTL(ttl):
- """
- Set time to live on multicast packets.
- """
-
- def joinGroup(addr, interface=""):
- """
- Join a multicast group. Returns L{Deferred} of success or failure.
-
- If an error occurs, the returned L{Deferred} will fail with
- L{error.MulticastJoinError}.
- """
-
- def leaveGroup(addr, interface=""):
- """
- Leave multicast group, return L{Deferred} of success.
- """
-
-
-class IStreamClientEndpoint(Interface):
- """
- A stream client endpoint is a place that L{ClientFactory} can connect to.
- For example, a remote TCP host/port pair would be a TCP client endpoint.
-
- @since: 10.1
- """
-
- def connect(protocolFactory):
- """
- Connect the C{protocolFactory} to the location specified by this
- L{IStreamClientEndpoint} provider.
-
- @param protocolFactory: A provider of L{IProtocolFactory}
- @return: A L{Deferred} that results in an L{IProtocol} upon successful
- connection otherwise a L{ConnectError}
- """
-
-
-
-class IStreamServerEndpoint(Interface):
- """
- A stream server endpoint is a place that a L{Factory} can listen for
- incoming connections.
-
- @since: 10.1
- """
-
- def listen(protocolFactory):
- """
- Listen with C{protocolFactory} at the location specified by this
- L{IStreamServerEndpoint} provider.
-
- @param protocolFactory: A provider of L{IProtocolFactory}
- @return: A L{Deferred} that results in an L{IListeningPort} or an
- L{CannotListenError}
- """
-
-
-
-class IStreamServerEndpointStringParser(Interface):
- """
- An L{IStreamServerEndpointStringParser} is like an
- L{IStreamClientEndpointStringParser}, except for L{IStreamServerEndpoint}s
- instead of clients. It integrates with L{endpoints.serverFromString} in
- much the same way.
- """
-
- prefix = Attribute(
- """
- @see: L{IStreamClientEndpointStringParser.prefix}
- """
- )
-
-
- def parseStreamServer(reactor, *args, **kwargs):
- """
- Parse a stream server endpoint from a reactor and string-only arguments
- and keyword arguments.
-
- @see: L{IStreamClientEndpointStringParser.parseStreamClient}
-
- @return: a stream server endpoint
- @rtype: L{IStreamServerEndpoint}
- """
-
-
-
-class IStreamClientEndpointStringParser(Interface):
- """
- An L{IStreamClientEndpointStringParser} is a parser which can convert
- a set of string C{*args} and C{**kwargs} into an L{IStreamClientEndpoint}
- provider.
-
- This interface is really only useful in the context of the plugin system
- for L{endpoints.clientFromString}. See the document entitled "I{The
- Twisted Plugin System}" for more details on how to write a plugin.
-
- If you place an L{IStreamClientEndpointStringParser} plugin in the
- C{twisted.plugins} package, that plugin's C{parseStreamClient} method will
- be used to produce endpoints for any description string that begins with
- the result of that L{IStreamClientEndpointStringParser}'s prefix attribute.
- """
-
- prefix = Attribute(
- """
- A C{str}, the description prefix to respond to. For example, an
- L{IStreamClientEndpointStringParser} plugin which had C{"foo"} for its
- C{prefix} attribute would be called for endpoint descriptions like
- C{"foo:bar:baz"} or C{"foo:"}.
- """
- )
-
-
- def parseStreamClient(*args, **kwargs):
- """
- This method is invoked by L{endpoints.clientFromString}, if the type of
- endpoint matches the return value from this
- L{IStreamClientEndpointStringParser}'s C{prefix} method.
-
- @param args: The string arguments, minus the endpoint type, in the
- endpoint description string, parsed according to the rules
- described in L{endpoints.quoteStringArgument}. For example, if the
- description were C{"my-type:foo:bar:baz=qux"}, C{args} would be
- C{('foo','bar')}
-
- @param kwargs: The string arguments from the endpoint description
- passed as keyword arguments. For example, if the description were
- C{"my-type:foo:bar:baz=qux"}, C{kwargs} would be
- C{dict(baz='qux')}.
-
- @return: a client endpoint
- @rtype: L{IStreamClientEndpoint}
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/__init__.py
deleted file mode 100755
index c403e517..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-I/O Completion Ports reactor
-"""
-
-from twisted.internet.iocpreactor.reactor import install
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/abstract.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/abstract.py
deleted file mode 100755
index ee3c51f3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/abstract.py
+++ /dev/null
@@ -1,400 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Abstract file handle class
-"""
-
-from twisted.internet import main, error, interfaces
-from twisted.internet.abstract import _ConsumerMixin, _LogOwner
-from twisted.python import failure
-
-from zope.interface import implements
-import errno
-
-from twisted.internet.iocpreactor.const import ERROR_HANDLE_EOF
-from twisted.internet.iocpreactor.const import ERROR_IO_PENDING
-from twisted.internet.iocpreactor import iocpsupport as _iocp
-
-
-
-class FileHandle(_ConsumerMixin, _LogOwner):
- """
- File handle that can read and write asynchronously
- """
- implements(interfaces.IPushProducer, interfaces.IConsumer,
- interfaces.ITransport, interfaces.IHalfCloseableDescriptor)
- # read stuff
- maxReadBuffers = 16
- readBufferSize = 4096
- reading = False
- dynamicReadBuffers = True # set this to false if subclass doesn't do iovecs
- _readNextBuffer = 0
- _readSize = 0 # how much data we have in the read buffer
- _readScheduled = None
- _readScheduledInOS = False
-
-
- def startReading(self):
- self.reactor.addActiveHandle(self)
- if not self._readScheduled and not self.reading:
- self.reading = True
- self._readScheduled = self.reactor.callLater(0,
- self._resumeReading)
-
-
- def stopReading(self):
- if self._readScheduled:
- self._readScheduled.cancel()
- self._readScheduled = None
- self.reading = False
-
-
- def _resumeReading(self):
- self._readScheduled = None
- if self._dispatchData() and not self._readScheduledInOS:
- self.doRead()
-
-
- def _dispatchData(self):
- """
- Dispatch previously read data. Return True if self.reading and we don't
- have any more data
- """
- if not self._readSize:
- return self.reading
- size = self._readSize
- full_buffers = size // self.readBufferSize
- while self._readNextBuffer < full_buffers:
- self.dataReceived(self._readBuffers[self._readNextBuffer])
- self._readNextBuffer += 1
- if not self.reading:
- return False
- remainder = size % self.readBufferSize
- if remainder:
- self.dataReceived(buffer(self._readBuffers[full_buffers],
- 0, remainder))
- if self.dynamicReadBuffers:
- total_buffer_size = self.readBufferSize * len(self._readBuffers)
- # we have one buffer too many
- if size < total_buffer_size - self.readBufferSize:
- del self._readBuffers[-1]
- # we filled all buffers, so allocate one more
- elif (size == total_buffer_size and
- len(self._readBuffers) < self.maxReadBuffers):
- self._readBuffers.append(_iocp.AllocateReadBuffer(
- self.readBufferSize))
- self._readNextBuffer = 0
- self._readSize = 0
- return self.reading
-
-
- def _cbRead(self, rc, bytes, evt):
- self._readScheduledInOS = False
- if self._handleRead(rc, bytes, evt):
- self.doRead()
-
-
- def _handleRead(self, rc, bytes, evt):
- """
- Returns False if we should stop reading for now
- """
- if self.disconnected:
- return False
- # graceful disconnection
- if (not (rc or bytes)) or rc in (errno.WSAEDISCON, ERROR_HANDLE_EOF):
- self.reactor.removeActiveHandle(self)
- self.readConnectionLost(failure.Failure(main.CONNECTION_DONE))
- return False
- # XXX: not handling WSAEWOULDBLOCK
- # ("too many outstanding overlapped I/O requests")
- elif rc:
- self.connectionLost(failure.Failure(
- error.ConnectionLost("read error -- %s (%s)" %
- (errno.errorcode.get(rc, 'unknown'), rc))))
- return False
- else:
- assert self._readSize == 0
- assert self._readNextBuffer == 0
- self._readSize = bytes
- return self._dispatchData()
-
-
- def doRead(self):
- evt = _iocp.Event(self._cbRead, self)
-
- evt.buff = buff = self._readBuffers
- rc, bytes = self.readFromHandle(buff, evt)
-
- if not rc or rc == ERROR_IO_PENDING:
- self._readScheduledInOS = True
- else:
- self._handleRead(rc, bytes, evt)
-
-
- def readFromHandle(self, bufflist, evt):
- raise NotImplementedError() # TODO: this should default to ReadFile
-
-
- def dataReceived(self, data):
- raise NotImplementedError
-
-
- def readConnectionLost(self, reason):
- self.connectionLost(reason)
-
-
- # write stuff
- dataBuffer = ''
- offset = 0
- writing = False
- _writeScheduled = None
- _writeDisconnecting = False
- _writeDisconnected = False
- writeBufferSize = 2**2**2**2
-
-
- def loseWriteConnection(self):
- self._writeDisconnecting = True
- self.startWriting()
-
-
- def _closeWriteConnection(self):
- # override in subclasses
- pass
-
-
- def writeConnectionLost(self, reason):
- # in current code should never be called
- self.connectionLost(reason)
-
-
- def startWriting(self):
- self.reactor.addActiveHandle(self)
- self.writing = True
- if not self._writeScheduled:
- self._writeScheduled = self.reactor.callLater(0,
- self._resumeWriting)
-
-
- def stopWriting(self):
- if self._writeScheduled:
- self._writeScheduled.cancel()
- self._writeScheduled = None
- self.writing = False
-
-
- def _resumeWriting(self):
- self._writeScheduled = None
- self.doWrite()
-
-
- def _cbWrite(self, rc, bytes, evt):
- if self._handleWrite(rc, bytes, evt):
- self.doWrite()
-
-
- def _handleWrite(self, rc, bytes, evt):
- """
- Returns false if we should stop writing for now
- """
- if self.disconnected or self._writeDisconnected:
- return False
- # XXX: not handling WSAEWOULDBLOCK
- # ("too many outstanding overlapped I/O requests")
- if rc:
- self.connectionLost(failure.Failure(
- error.ConnectionLost("write error -- %s (%s)" %
- (errno.errorcode.get(rc, 'unknown'), rc))))
- return False
- else:
- self.offset += bytes
- # If there is nothing left to send,
- if self.offset == len(self.dataBuffer) and not self._tempDataLen:
- self.dataBuffer = ""
- self.offset = 0
- # stop writing
- self.stopWriting()
- # If I've got a producer who is supposed to supply me with data
- if self.producer is not None and ((not self.streamingProducer)
- or self.producerPaused):
- # tell them to supply some more.
- self.producerPaused = True
- self.producer.resumeProducing()
- elif self.disconnecting:
- # But if I was previously asked to let the connection die,
- # do so.
- self.connectionLost(failure.Failure(main.CONNECTION_DONE))
- elif self._writeDisconnecting:
- # I was previously asked to to half-close the connection.
- self._writeDisconnected = True
- self._closeWriteConnection()
- return False
- else:
- return True
-
-
- def doWrite(self):
- if len(self.dataBuffer) - self.offset < self.SEND_LIMIT:
- # If there is currently less than SEND_LIMIT bytes left to send
- # in the string, extend it with the array data.
- self.dataBuffer = (buffer(self.dataBuffer, self.offset) +
- "".join(self._tempDataBuffer))
- self.offset = 0
- self._tempDataBuffer = []
- self._tempDataLen = 0
-
- evt = _iocp.Event(self._cbWrite, self)
-
- # Send as much data as you can.
- if self.offset:
- evt.buff = buff = buffer(self.dataBuffer, self.offset)
- else:
- evt.buff = buff = self.dataBuffer
- rc, bytes = self.writeToHandle(buff, evt)
- if rc and rc != ERROR_IO_PENDING:
- self._handleWrite(rc, bytes, evt)
-
-
- def writeToHandle(self, buff, evt):
- raise NotImplementedError() # TODO: this should default to WriteFile
-
-
- def write(self, data):
- """Reliably write some data.
-
- The data is buffered until his file descriptor is ready for writing.
- """
- if isinstance(data, unicode): # no, really, I mean it
- raise TypeError("Data must not be unicode")
- if not self.connected or self._writeDisconnected:
- return
- if data:
- self._tempDataBuffer.append(data)
- self._tempDataLen += len(data)
- if self.producer is not None and self.streamingProducer:
- if (len(self.dataBuffer) + self._tempDataLen
- > self.writeBufferSize):
- self.producerPaused = True
- self.producer.pauseProducing()
- self.startWriting()
-
-
- def writeSequence(self, iovec):
- for i in iovec:
- if isinstance(i, unicode): # no, really, I mean it
- raise TypeError("Data must not be unicode")
- if not self.connected or not iovec or self._writeDisconnected:
- return
- self._tempDataBuffer.extend(iovec)
- for i in iovec:
- self._tempDataLen += len(i)
- if self.producer is not None and self.streamingProducer:
- if len(self.dataBuffer) + self._tempDataLen > self.writeBufferSize:
- self.producerPaused = True
- self.producer.pauseProducing()
- self.startWriting()
-
-
- # general stuff
- connected = False
- disconnected = False
- disconnecting = False
- logstr = "Uninitialized"
-
- SEND_LIMIT = 128*1024
-
-
- def __init__(self, reactor = None):
- if not reactor:
- from twisted.internet import reactor
- self.reactor = reactor
- self._tempDataBuffer = [] # will be added to dataBuffer in doWrite
- self._tempDataLen = 0
- self._readBuffers = [_iocp.AllocateReadBuffer(self.readBufferSize)]
-
-
- def connectionLost(self, reason):
- """
- The connection was lost.
-
- This is called when the connection on a selectable object has been
- lost. It will be called whether the connection was closed explicitly,
- an exception occurred in an event handler, or the other end of the
- connection closed it first.
-
- Clean up state here, but make sure to call back up to FileDescriptor.
- """
-
- self.disconnected = True
- self.connected = False
- if self.producer is not None:
- self.producer.stopProducing()
- self.producer = None
- self.stopReading()
- self.stopWriting()
- self.reactor.removeActiveHandle(self)
-
-
- def getFileHandle(self):
- return -1
-
-
- def loseConnection(self, _connDone=failure.Failure(main.CONNECTION_DONE)):
- """
- Close the connection at the next available opportunity.
-
- Call this to cause this FileDescriptor to lose its connection. It will
- first write any data that it has buffered.
-
- If there is data buffered yet to be written, this method will cause the
- transport to lose its connection as soon as it's done flushing its
- write buffer. If you have a producer registered, the connection won't
- be closed until the producer is finished. Therefore, make sure you
- unregister your producer when it's finished, or the connection will
- never close.
- """
-
- if self.connected and not self.disconnecting:
- if self._writeDisconnected:
- # doWrite won't trigger the connection close anymore
- self.stopReading()
- self.stopWriting
- self.connectionLost(_connDone)
- else:
- self.stopReading()
- self.startWriting()
- self.disconnecting = 1
-
-
- # Producer/consumer implementation
-
- def stopConsuming(self):
- """
- Stop consuming data.
-
- This is called when a producer has lost its connection, to tell the
- consumer to go lose its connection (and break potential circular
- references).
- """
- self.unregisterProducer()
- self.loseConnection()
-
-
- # producer interface implementation
-
- def resumeProducing(self):
- assert self.connected and not self.disconnecting
- self.startReading()
-
-
- def pauseProducing(self):
- self.stopReading()
-
-
- def stopProducing(self):
- self.loseConnection()
-
-
-__all__ = ['FileHandle']
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/build.bat b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/build.bat
deleted file mode 100644
index 25f361be..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/build.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-del iocpsupport\iocpsupport.c iocpsupport.pyd
-del /f /s /q build
-python setup.py build_ext -i -c mingw32
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/const.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/const.py
deleted file mode 100755
index dbeb094b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/const.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Windows constants for IOCP
-"""
-
-
-# this stuff should really be gotten from Windows headers via pyrex, but it
-# probably is not going to change
-
-ERROR_PORT_UNREACHABLE = 1234
-ERROR_NETWORK_UNREACHABLE = 1231
-ERROR_CONNECTION_REFUSED = 1225
-ERROR_IO_PENDING = 997
-ERROR_OPERATION_ABORTED = 995
-WAIT_TIMEOUT = 258
-ERROR_NETNAME_DELETED = 64
-ERROR_HANDLE_EOF = 38
-
-INFINITE = -1
-
-SO_UPDATE_CONNECT_CONTEXT = 0x7010
-SO_UPDATE_ACCEPT_CONTEXT = 0x700B
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/interfaces.py
deleted file mode 100755
index 9e4d3ca4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/interfaces.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Interfaces for iocpreactor
-"""
-
-
-from zope.interface import Interface
-
-
-
-class IReadHandle(Interface):
- def readFromHandle(bufflist, evt):
- """
- Read into the given buffers from this handle.
-
- @param buff: the buffers to read into
- @type buff: list of objects implementing the read/write buffer protocol
-
- @param evt: an IOCP Event object
-
- @return: tuple (return code, number of bytes read)
- """
-
-
-
-class IWriteHandle(Interface):
- def writeToHandle(buff, evt):
- """
- Write the given buffer to this handle.
-
- @param buff: the buffer to write
- @type buff: any object implementing the buffer protocol
-
- @param evt: an IOCP Event object
-
- @return: tuple (return code, number of bytes written)
- """
-
-
-
-class IReadWriteHandle(IReadHandle, IWriteHandle):
- pass
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/acceptex.pxi b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/acceptex.pxi
deleted file mode 100644
index 867736d7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/acceptex.pxi
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-def accept(long listening, long accepting, object buff, object obj):
- """
- CAUTION: unlike system AcceptEx(), this function returns 0 on success
- """
- cdef unsigned long bytes
- cdef int rc
- cdef Py_ssize_t size
- cdef void *mem_buffer
- cdef myOVERLAPPED *ov
-
- PyObject_AsWriteBuffer(buff, &mem_buffer, &size)
-
- ov = makeOV()
- if obj is not None:
- ov.obj = <PyObject *>obj
-
- rc = lpAcceptEx(listening, accepting, mem_buffer, 0,
- <DWORD>size / 2, <DWORD>size / 2,
- &bytes, <OVERLAPPED *>ov)
- if not rc:
- rc = WSAGetLastError()
- if rc != ERROR_IO_PENDING:
- PyMem_Free(ov)
- return rc
-
- # operation is in progress
- Py_XINCREF(obj)
- return 0
-
-def get_accept_addrs(long s, object buff):
- cdef WSAPROTOCOL_INFO wsa_pi
- cdef int locallen, remotelen
- cdef Py_ssize_t size
- cdef void *mem_buffer
- cdef sockaddr *localaddr, *remoteaddr
-
- PyObject_AsReadBuffer(buff, &mem_buffer, &size)
-
- lpGetAcceptExSockaddrs(mem_buffer, 0, <DWORD>size / 2, <DWORD>size / 2,
- &localaddr, &locallen, &remoteaddr, &remotelen)
- return remoteaddr.sa_family, _makesockaddr(localaddr, locallen), _makesockaddr(remoteaddr, remotelen)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/connectex.pxi b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/connectex.pxi
deleted file mode 100644
index 276638a3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/connectex.pxi
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-def connect(long s, object addr, object obj):
- """
- CAUTION: unlike system ConnectEx(), this function returns 0 on success
- """
- cdef int family, rc
- cdef myOVERLAPPED *ov
- cdef sockaddr_in ipv4_name
- cdef sockaddr_in6 ipv6_name
- cdef sockaddr *name
- cdef int namelen
-
- if not have_connectex:
- raise ValueError, 'ConnectEx is not available on this system'
-
- family = getAddrFamily(s)
- if family == AF_INET:
- name = <sockaddr *>&ipv4_name
- namelen = sizeof(ipv4_name)
- fillinetaddr(&ipv4_name, addr)
- elif family == AF_INET6:
- name = <sockaddr *>&ipv6_name
- namelen = sizeof(ipv6_name)
- fillinet6addr(&ipv6_name, addr)
- else:
- raise ValueError, 'unsupported address family'
- name.sa_family = family
-
- ov = makeOV()
- if obj is not None:
- ov.obj = <PyObject *>obj
-
- rc = lpConnectEx(s, name, namelen, NULL, 0, NULL, <OVERLAPPED *>ov)
-
- if not rc:
- rc = WSAGetLastError()
- if rc != ERROR_IO_PENDING:
- PyMem_Free(ov)
- return rc
-
- # operation is in progress
- Py_XINCREF(obj)
- return 0
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.c
deleted file mode 100644
index deb4b22b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.c
+++ /dev/null
@@ -1,6376 +0,0 @@
-/* Generated by Cython 0.15.1 on Tue Mar 27 07:16:06 2012 */
-
-#define PY_SSIZE_T_CLEAN
-#include "Python.h"
-#ifndef Py_PYTHON_H
- #error Python headers needed to compile C extensions, please install development version of Python.
-#else
-
-#include <stddef.h> /* For offsetof */
-#ifndef offsetof
-#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
-#endif
-
-#if !defined(WIN32) && !defined(MS_WINDOWS)
- #ifndef __stdcall
- #define __stdcall
- #endif
- #ifndef __cdecl
- #define __cdecl
- #endif
- #ifndef __fastcall
- #define __fastcall
- #endif
-#endif
-
-#ifndef DL_IMPORT
- #define DL_IMPORT(t) t
-#endif
-#ifndef DL_EXPORT
- #define DL_EXPORT(t) t
-#endif
-
-#ifndef PY_LONG_LONG
- #define PY_LONG_LONG LONG_LONG
-#endif
-
-#if PY_VERSION_HEX < 0x02040000
- #define METH_COEXIST 0
- #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
- #define PyDict_Contains(d,o) PySequence_Contains(d,o)
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- typedef int Py_ssize_t;
- #define PY_SSIZE_T_MAX INT_MAX
- #define PY_SSIZE_T_MIN INT_MIN
- #define PY_FORMAT_SIZE_T ""
- #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
- #define PyInt_AsSsize_t(o) __Pyx_PyInt_AsInt(o)
- #define PyNumber_Index(o) PyNumber_Int(o)
- #define PyIndex_Check(o) PyNumber_Check(o)
- #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
- #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
- #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
- #define PyVarObject_HEAD_INIT(type, size) \
- PyObject_HEAD_INIT(type) size,
- #define PyType_Modified(t)
-
- typedef struct {
- void *buf;
- PyObject *obj;
- Py_ssize_t len;
- Py_ssize_t itemsize;
- int readonly;
- int ndim;
- char *format;
- Py_ssize_t *shape;
- Py_ssize_t *strides;
- Py_ssize_t *suboffsets;
- void *internal;
- } Py_buffer;
-
- #define PyBUF_SIMPLE 0
- #define PyBUF_WRITABLE 0x0001
- #define PyBUF_FORMAT 0x0004
- #define PyBUF_ND 0x0008
- #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
- #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
- #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
- #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
- #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
-
-#endif
-
-#if PY_MAJOR_VERSION < 3
- #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-#else
- #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define Py_TPFLAGS_CHECKTYPES 0
- #define Py_TPFLAGS_HAVE_INDEX 0
-#endif
-
-#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
- #define Py_TPFLAGS_HAVE_NEWBUFFER 0
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyBaseString_Type PyUnicode_Type
- #define PyStringObject PyUnicodeObject
- #define PyString_Type PyUnicode_Type
- #define PyString_Check PyUnicode_Check
- #define PyString_CheckExact PyUnicode_CheckExact
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define PyBytesObject PyStringObject
- #define PyBytes_Type PyString_Type
- #define PyBytes_Check PyString_Check
- #define PyBytes_CheckExact PyString_CheckExact
- #define PyBytes_FromString PyString_FromString
- #define PyBytes_FromStringAndSize PyString_FromStringAndSize
- #define PyBytes_FromFormat PyString_FromFormat
- #define PyBytes_DecodeEscape PyString_DecodeEscape
- #define PyBytes_AsString PyString_AsString
- #define PyBytes_AsStringAndSize PyString_AsStringAndSize
- #define PyBytes_Size PyString_Size
- #define PyBytes_AS_STRING PyString_AS_STRING
- #define PyBytes_GET_SIZE PyString_GET_SIZE
- #define PyBytes_Repr PyString_Repr
- #define PyBytes_Concat PyString_Concat
- #define PyBytes_ConcatAndDel PyString_ConcatAndDel
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
- #define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
-#endif
-#ifndef PySet_CheckExact
- #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
-#endif
-
-#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
-
-#if PY_MAJOR_VERSION >= 3
- #define PyIntObject PyLongObject
- #define PyInt_Type PyLong_Type
- #define PyInt_Check(op) PyLong_Check(op)
- #define PyInt_CheckExact(op) PyLong_CheckExact(op)
- #define PyInt_FromString PyLong_FromString
- #define PyInt_FromUnicode PyLong_FromUnicode
- #define PyInt_FromLong PyLong_FromLong
- #define PyInt_FromSize_t PyLong_FromSize_t
- #define PyInt_FromSsize_t PyLong_FromSsize_t
- #define PyInt_AsLong PyLong_AsLong
- #define PyInt_AS_LONG PyLong_AS_LONG
- #define PyInt_AsSsize_t PyLong_AsSsize_t
- #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
- #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyBoolObject PyLongObject
-#endif
-
-#if PY_VERSION_HEX < 0x03020000
- typedef long Py_hash_t;
- #define __Pyx_PyInt_FromHash_t PyInt_FromLong
- #define __Pyx_PyInt_AsHash_t PyInt_AsLong
-#else
- #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
- #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
- #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
- #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
-#else
- #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
- #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
-#endif
-
-#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
- #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
- #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
- #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
-#else
- #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
- #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
- #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
- #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
- #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
-#else
- #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
- #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
- #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- #define __Pyx_NAMESTR(n) ((char *)(n))
- #define __Pyx_DOCSTR(n) ((char *)(n))
-#else
- #define __Pyx_NAMESTR(n) (n)
- #define __Pyx_DOCSTR(n) (n)
-#endif
-
-#ifndef __PYX_EXTERN_C
- #ifdef __cplusplus
- #define __PYX_EXTERN_C extern "C"
- #else
- #define __PYX_EXTERN_C extern
- #endif
-#endif
-
-#if defined(WIN32) || defined(MS_WINDOWS)
-#define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-#define __PYX_HAVE__iocpsupport
-#define __PYX_HAVE_API__iocpsupport
-#include "io.h"
-#include "errno.h"
-#include "winsock2.h"
-#include "ws2tcpip.h"
-#include "windows.h"
-#include "python.h"
-#include "string.h"
-#include "winsock_pointers.h"
-#ifdef _OPENMP
-#include <omp.h>
-#endif /* _OPENMP */
-
-#ifdef PYREX_WITHOUT_ASSERTIONS
-#define CYTHON_WITHOUT_ASSERTIONS
-#endif
-
-
-/* inline attribute */
-#ifndef CYTHON_INLINE
- #if defined(__GNUC__)
- #define CYTHON_INLINE __inline__
- #elif defined(_MSC_VER)
- #define CYTHON_INLINE __inline
- #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- #define CYTHON_INLINE inline
- #else
- #define CYTHON_INLINE
- #endif
-#endif
-
-/* unused attribute */
-#ifndef CYTHON_UNUSED
-# if defined(__GNUC__)
-# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-# define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-# define CYTHON_UNUSED
-# endif
-# elif defined(__ICC) || defined(__INTEL_COMPILER)
-# define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-# define CYTHON_UNUSED
-# endif
-#endif
-
-typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
-
-
-/* Type Conversion Predeclarations */
-
-#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
-#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) PyBytes_AsString(s))
-
-#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
-#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
-
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
-
-#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
-
-
-#ifdef __GNUC__
- /* Test for GCC > 2.95 */
- #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
- #define likely(x) __builtin_expect(!!(x), 1)
- #define unlikely(x) __builtin_expect(!!(x), 0)
- #else /* __GNUC__ > 2 ... */
- #define likely(x) (x)
- #define unlikely(x) (x)
- #endif /* __GNUC__ > 2 ... */
-#else /* __GNUC__ */
- #define likely(x) (x)
- #define unlikely(x) (x)
-#endif /* __GNUC__ */
-
-static PyObject *__pyx_m;
-static PyObject *__pyx_b;
-static PyObject *__pyx_empty_tuple;
-static PyObject *__pyx_empty_bytes;
-static int __pyx_lineno;
-static int __pyx_clineno = 0;
-static const char * __pyx_cfilenm= __FILE__;
-static const char *__pyx_filename;
-
-
-static const char *__pyx_f[] = {
- "iocpsupport.pyx",
- "acceptex.pxi",
- "connectex.pxi",
- "wsarecv.pxi",
- "wsasend.pxi",
-};
-
-/* "iocpsupport.pyx":6
- *
- * # HANDLE and SOCKET are pointer-sized (they are 64 bit wide in 64-bit builds)
- * ctypedef size_t HANDLE # <<<<<<<<<<<<<<
- * ctypedef size_t SOCKET
- * ctypedef unsigned long DWORD
- */
-typedef size_t __pyx_t_11iocpsupport_HANDLE;
-
-/* "iocpsupport.pyx":7
- * # HANDLE and SOCKET are pointer-sized (they are 64 bit wide in 64-bit builds)
- * ctypedef size_t HANDLE
- * ctypedef size_t SOCKET # <<<<<<<<<<<<<<
- * ctypedef unsigned long DWORD
- * # it's really a pointer, but we use it as an integer
- */
-typedef size_t __pyx_t_11iocpsupport_SOCKET;
-
-/* "iocpsupport.pyx":8
- * ctypedef size_t HANDLE
- * ctypedef size_t SOCKET
- * ctypedef unsigned long DWORD # <<<<<<<<<<<<<<
- * # it's really a pointer, but we use it as an integer
- * ctypedef size_t ULONG_PTR
- */
-typedef unsigned long __pyx_t_11iocpsupport_DWORD;
-
-/* "iocpsupport.pyx":10
- * ctypedef unsigned long DWORD
- * # it's really a pointer, but we use it as an integer
- * ctypedef size_t ULONG_PTR # <<<<<<<<<<<<<<
- * ctypedef int BOOL
- *
- */
-typedef size_t __pyx_t_11iocpsupport_ULONG_PTR;
-
-/* "iocpsupport.pyx":11
- * # it's really a pointer, but we use it as an integer
- * ctypedef size_t ULONG_PTR
- * ctypedef int BOOL # <<<<<<<<<<<<<<
- *
- * cdef extern from 'io.h':
- */
-typedef int __pyx_t_11iocpsupport_BOOL;
-
-/*--- Type declarations ---*/
-struct __pyx_obj_11iocpsupport_CompletionPort;
-struct __pyx_t_11iocpsupport_myOVERLAPPED;
-
-/* "iocpsupport.pyx":124
- * # BOOL (*lpTransmitFile)(SOCKET s, HANDLE hFile, DWORD size, DWORD buffer_size, OVERLAPPED *ov, TRANSMIT_FILE_BUFFERS *buff, DWORD flags)
- *
- * cdef struct myOVERLAPPED: # <<<<<<<<<<<<<<
- * OVERLAPPED ov
- * PyObject *obj
- */
-struct __pyx_t_11iocpsupport_myOVERLAPPED {
- OVERLAPPED ov;
- struct PyObject *obj;
-};
-
-/* "iocpsupport.pyx":148
- * setattr(self, k, v)
- *
- * cdef class CompletionPort: # <<<<<<<<<<<<<<
- * cdef HANDLE port
- * def __init__(self):
- */
-struct __pyx_obj_11iocpsupport_CompletionPort {
- PyObject_HEAD
- __pyx_t_11iocpsupport_HANDLE port;
-};
-
-
-#ifndef CYTHON_REFNANNY
- #define CYTHON_REFNANNY 0
-#endif
-
-#if CYTHON_REFNANNY
- typedef struct {
- void (*INCREF)(void*, PyObject*, int);
- void (*DECREF)(void*, PyObject*, int);
- void (*GOTREF)(void*, PyObject*, int);
- void (*GIVEREF)(void*, PyObject*, int);
- void* (*SetupContext)(const char*, int, const char*);
- void (*FinishContext)(void**);
- } __Pyx_RefNannyAPIStruct;
- static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
- static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
- #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
- #define __Pyx_RefNannySetupContext(name) __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
- #define __Pyx_RefNannyFinishContext() __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
- #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
- #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
- #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
- #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
-#else
- #define __Pyx_RefNannyDeclarations
- #define __Pyx_RefNannySetupContext(name)
- #define __Pyx_RefNannyFinishContext()
- #define __Pyx_INCREF(r) Py_INCREF(r)
- #define __Pyx_DECREF(r) Py_DECREF(r)
- #define __Pyx_GOTREF(r)
- #define __Pyx_GIVEREF(r)
- #define __Pyx_XINCREF(r) Py_XINCREF(r)
- #define __Pyx_XDECREF(r) Py_XDECREF(r)
- #define __Pyx_XGOTREF(r)
- #define __Pyx_XGIVEREF(r)
-#endif /* CYTHON_REFNANNY */
-
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
-
-static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
- Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
-
-static void __Pyx_RaiseDoubleKeywordsError(
- const char* func_name, PyObject* kw_name); /*proto*/
-
-static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/
-
-static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
-
-static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
-
-static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); /*proto*/
-
-static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
- const char* function_name, int kw_allowed); /*proto*/
-
-
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
- PyObject *r;
- if (!j) return NULL;
- r = PyObject_GetItem(o, j);
- Py_DECREF(j);
- return r;
-}
-
-
-#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
- __Pyx_GetItemInt_List_Fast(o, i) : \
- __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
- if (likely(o != Py_None)) {
- if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
- PyObject *r = PyList_GET_ITEM(o, i);
- Py_INCREF(r);
- return r;
- }
- else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
- PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
- Py_INCREF(r);
- return r;
- }
- }
- return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-}
-
-#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
- __Pyx_GetItemInt_Tuple_Fast(o, i) : \
- __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
- if (likely(o != Py_None)) {
- if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
- PyObject *r = PyTuple_GET_ITEM(o, i);
- Py_INCREF(r);
- return r;
- }
- else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
- PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
- Py_INCREF(r);
- return r;
- }
- }
- return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-}
-
-
-#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
- __Pyx_GetItemInt_Fast(o, i) : \
- __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
- PyObject *r;
- if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
- r = PyList_GET_ITEM(o, i);
- Py_INCREF(r);
- }
- else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
- r = PyTuple_GET_ITEM(o, i);
- Py_INCREF(r);
- }
- else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
- r = PySequence_GetItem(o, i);
- }
- else {
- r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
- }
- return r;
-}
-
-static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
-
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
- PyObject *modname); /*proto*/
-
-#define __pyx_binding_PyCFunctionType_USED 1
-
-typedef struct {
- PyCFunctionObject func;
-} __pyx_binding_PyCFunctionType_object;
-
-static PyTypeObject __pyx_binding_PyCFunctionType_type;
-static PyTypeObject *__pyx_binding_PyCFunctionType = NULL;
-
-static PyObject *__pyx_binding_PyCFunctionType_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
-#define __pyx_binding_PyCFunctionType_New(ml, self) __pyx_binding_PyCFunctionType_NewEx(ml, self, NULL)
-
-static int __pyx_binding_PyCFunctionType_init(void); /* proto */
-
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level); /*proto*/
-
-#include <string.h>
-
-static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
-
-static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
-
-#if PY_MAJOR_VERSION >= 3
-#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
-#else
-#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
-#endif
-
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
-
-static int __Pyx_check_binary_version(void);
-
-static void __Pyx_AddTraceback(const char *funcname, int __pyx_clineno,
- int __pyx_lineno, const char *__pyx_filename); /*proto*/
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
-
-/* Module declarations from 'iocpsupport' */
-static PyTypeObject *__pyx_ptype_11iocpsupport_CompletionPort = 0;
-static struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_f_11iocpsupport_makeOV(void); /*proto*/
-static void __pyx_f_11iocpsupport_raise_error(int, PyObject *); /*proto*/
-static PyObject *__pyx_f_11iocpsupport__makesockaddr(struct sockaddr *, Py_ssize_t); /*proto*/
-static PyObject *__pyx_f_11iocpsupport_fillinetaddr(struct sockaddr_in *, PyObject *); /*proto*/
-static PyObject *__pyx_f_11iocpsupport_fillinet6addr(struct sockaddr_in6 *, PyObject *); /*proto*/
-static int __pyx_f_11iocpsupport_getAddrFamily(__pyx_t_11iocpsupport_SOCKET); /*proto*/
-#define __Pyx_MODULE_NAME "iocpsupport"
-int __pyx_module_is_main_iocpsupport = 0;
-
-/* Implementation of 'iocpsupport' */
-static PyObject *__pyx_builtin_ValueError;
-static PyObject *__pyx_builtin_MemoryError;
-static PyObject *__pyx_builtin_RuntimeError;
-static char __pyx_k_1[] = "CreateIoCompletionPort";
-static char __pyx_k_2[] = "PostQueuedCompletionStatus";
-static char __pyx_k_3[] = ":";
-static char __pyx_k_5[] = "[";
-static char __pyx_k_6[] = "]";
-static char __pyx_k_7[] = "invalid IP address";
-static char __pyx_k_8[] = "%";
-static char __pyx_k_10[] = "invalid IPv6 address %r";
-static char __pyx_k_11[] = "undefined error occurred during address parsing";
-static char __pyx_k_12[] = "ConnectEx is not available on this system";
-static char __pyx_k_13[] = "unsupported address family";
-static char __pyx_k_14[] = "second argument needs to be a list";
-static char __pyx_k_15[] = "length of address length buffer needs to be sizeof(int)";
-static char __pyx_k_16[] = "Failed to initialize Winsock function vectors";
-static char __pyx_k__s[] = "s";
-static char __pyx_k__key[] = "key";
-static char __pyx_k__obj[] = "obj";
-static char __pyx_k__addr[] = "addr";
-static char __pyx_k__buff[] = "buff";
-static char __pyx_k__recv[] = "recv";
-static char __pyx_k__self[] = "self";
-static char __pyx_k__send[] = "send";
-static char __pyx_k__Event[] = "Event";
-static char __pyx_k__bytes[] = "bytes";
-static char __pyx_k__flags[] = "flags";
-static char __pyx_k__owner[] = "owner";
-static char __pyx_k__split[] = "split";
-static char __pyx_k__accept[] = "accept";
-static char __pyx_k__handle[] = "handle";
-static char __pyx_k__rsplit[] = "rsplit";
-static char __pyx_k__socket[] = "socket";
-static char __pyx_k__connect[] = "connect";
-static char __pyx_k____init__[] = "__init__";
-static char __pyx_k____main__[] = "__main__";
-static char __pyx_k____test__[] = "__test__";
-static char __pyx_k__bufflist[] = "bufflist";
-static char __pyx_k__callback[] = "callback";
-static char __pyx_k__recvfrom[] = "recvfrom";
-static char __pyx_k__accepting[] = "accepting";
-static char __pyx_k__addr_buff[] = "addr_buff";
-static char __pyx_k__listening[] = "listening";
-static char __pyx_k__ValueError[] = "ValueError";
-static char __pyx_k__getsockopt[] = "getsockopt";
-static char __pyx_k__maxAddrLen[] = "maxAddrLen";
-static char __pyx_k__MemoryError[] = "MemoryError";
-static char __pyx_k__iocpsupport[] = "iocpsupport";
-static char __pyx_k__RuntimeError[] = "RuntimeError";
-static char __pyx_k__WindowsError[] = "WindowsError";
-static char __pyx_k__makesockaddr[] = "makesockaddr";
-static char __pyx_k__addr_len_buff[] = "addr_len_buff";
-static char __pyx_k__have_connectex[] = "have_connectex";
-static char __pyx_k__get_accept_addrs[] = "get_accept_addrs";
-static char __pyx_k__AllocateReadBuffer[] = "AllocateReadBuffer";
-static char __pyx_k__WSAAddressToString[] = "WSAAddressToString";
-static PyObject *__pyx_n_s_1;
-static PyObject *__pyx_kp_s_10;
-static PyObject *__pyx_kp_s_11;
-static PyObject *__pyx_kp_s_12;
-static PyObject *__pyx_kp_s_13;
-static PyObject *__pyx_kp_s_15;
-static PyObject *__pyx_kp_s_16;
-static PyObject *__pyx_n_s_2;
-static PyObject *__pyx_kp_s_3;
-static PyObject *__pyx_kp_s_5;
-static PyObject *__pyx_kp_s_6;
-static PyObject *__pyx_kp_s_7;
-static PyObject *__pyx_kp_s_8;
-static PyObject *__pyx_n_s__AllocateReadBuffer;
-static PyObject *__pyx_n_s__Event;
-static PyObject *__pyx_n_s__MemoryError;
-static PyObject *__pyx_n_s__RuntimeError;
-static PyObject *__pyx_n_s__ValueError;
-static PyObject *__pyx_n_s__WSAAddressToString;
-static PyObject *__pyx_n_s__WindowsError;
-static PyObject *__pyx_n_s____init__;
-static PyObject *__pyx_n_s____main__;
-static PyObject *__pyx_n_s____test__;
-static PyObject *__pyx_n_s__accept;
-static PyObject *__pyx_n_s__accepting;
-static PyObject *__pyx_n_s__addr;
-static PyObject *__pyx_n_s__addr_buff;
-static PyObject *__pyx_n_s__addr_len_buff;
-static PyObject *__pyx_n_s__buff;
-static PyObject *__pyx_n_s__bufflist;
-static PyObject *__pyx_n_s__bytes;
-static PyObject *__pyx_n_s__callback;
-static PyObject *__pyx_n_s__connect;
-static PyObject *__pyx_n_s__flags;
-static PyObject *__pyx_n_s__get_accept_addrs;
-static PyObject *__pyx_n_s__getsockopt;
-static PyObject *__pyx_n_s__handle;
-static PyObject *__pyx_n_s__have_connectex;
-static PyObject *__pyx_n_s__iocpsupport;
-static PyObject *__pyx_n_s__key;
-static PyObject *__pyx_n_s__listening;
-static PyObject *__pyx_n_s__makesockaddr;
-static PyObject *__pyx_n_s__maxAddrLen;
-static PyObject *__pyx_n_s__obj;
-static PyObject *__pyx_n_s__owner;
-static PyObject *__pyx_n_s__recv;
-static PyObject *__pyx_n_s__recvfrom;
-static PyObject *__pyx_n_s__rsplit;
-static PyObject *__pyx_n_s__s;
-static PyObject *__pyx_n_s__self;
-static PyObject *__pyx_n_s__send;
-static PyObject *__pyx_n_s__socket;
-static PyObject *__pyx_n_s__split;
-static PyObject *__pyx_int_0;
-static PyObject *__pyx_int_1;
-static PyObject *__pyx_k_tuple_4;
-static PyObject *__pyx_k_tuple_9;
-
-/* "iocpsupport.pyx":128
- * PyObject *obj
- *
- * cdef myOVERLAPPED *makeOV() except NULL: # <<<<<<<<<<<<<<
- * cdef myOVERLAPPED *res
- * res = <myOVERLAPPED *>PyMem_Malloc(sizeof(myOVERLAPPED))
- */
-
-static struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_f_11iocpsupport_makeOV(void) {
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_res;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_r;
- __Pyx_RefNannyDeclarations
- void *__pyx_t_1;
- int __pyx_t_2;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("makeOV");
-
- /* "iocpsupport.pyx":130
- * cdef myOVERLAPPED *makeOV() except NULL:
- * cdef myOVERLAPPED *res
- * res = <myOVERLAPPED *>PyMem_Malloc(sizeof(myOVERLAPPED)) # <<<<<<<<<<<<<<
- * if not res:
- * raise MemoryError
- */
- __pyx_t_1 = PyMem_Malloc((sizeof(struct __pyx_t_11iocpsupport_myOVERLAPPED))); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_res = ((struct __pyx_t_11iocpsupport_myOVERLAPPED *)__pyx_t_1);
-
- /* "iocpsupport.pyx":131
- * cdef myOVERLAPPED *res
- * res = <myOVERLAPPED *>PyMem_Malloc(sizeof(myOVERLAPPED))
- * if not res: # <<<<<<<<<<<<<<
- * raise MemoryError
- * memset(res, 0, sizeof(myOVERLAPPED))
- */
- __pyx_t_2 = (!(__pyx_v_res != 0));
- if (__pyx_t_2) {
-
- /* "iocpsupport.pyx":132
- * res = <myOVERLAPPED *>PyMem_Malloc(sizeof(myOVERLAPPED))
- * if not res:
- * raise MemoryError # <<<<<<<<<<<<<<
- * memset(res, 0, sizeof(myOVERLAPPED))
- * return res
- */
- PyErr_NoMemory(); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L3;
- }
- __pyx_L3:;
-
- /* "iocpsupport.pyx":133
- * if not res:
- * raise MemoryError
- * memset(res, 0, sizeof(myOVERLAPPED)) # <<<<<<<<<<<<<<
- * return res
- *
- */
- memset(__pyx_v_res, 0, (sizeof(struct __pyx_t_11iocpsupport_myOVERLAPPED)));
-
- /* "iocpsupport.pyx":134
- * raise MemoryError
- * memset(res, 0, sizeof(myOVERLAPPED))
- * return res # <<<<<<<<<<<<<<
- *
- * cdef void raise_error(int err, object message) except *:
- */
- __pyx_r = __pyx_v_res;
- goto __pyx_L0;
-
- __pyx_r = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_AddTraceback("iocpsupport.makeOV", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":136
- * return res
- *
- * cdef void raise_error(int err, object message) except *: # <<<<<<<<<<<<<<
- * if not err:
- * err = GetLastError()
- */
-
-static void __pyx_f_11iocpsupport_raise_error(int __pyx_v_err, PyObject *__pyx_v_message) {
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("raise_error");
-
- /* "iocpsupport.pyx":137
- *
- * cdef void raise_error(int err, object message) except *:
- * if not err: # <<<<<<<<<<<<<<
- * err = GetLastError()
- * raise WindowsError(message, err)
- */
- __pyx_t_1 = (!__pyx_v_err);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":138
- * cdef void raise_error(int err, object message) except *:
- * if not err:
- * err = GetLastError() # <<<<<<<<<<<<<<
- * raise WindowsError(message, err)
- *
- */
- __pyx_v_err = GetLastError();
- goto __pyx_L3;
- }
- __pyx_L3:;
-
- /* "iocpsupport.pyx":139
- * if not err:
- * err = GetLastError()
- * raise WindowsError(message, err) # <<<<<<<<<<<<<<
- *
- * class Event:
- */
- __pyx_t_2 = __Pyx_GetName(__pyx_b, __pyx_n_s__WindowsError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyInt_FromLong(__pyx_v_err); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- __Pyx_INCREF(__pyx_v_message);
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_message);
- __Pyx_GIVEREF(__pyx_v_message);
- PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- __pyx_t_3 = 0;
- __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
- __Pyx_Raise(__pyx_t_3, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_AddTraceback("iocpsupport.raise_error", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
-}
-
-/* "iocpsupport.pyx":142
- *
- * class Event:
- * def __init__(self, callback, owner, **kw): # <<<<<<<<<<<<<<
- * self.callback = callback
- * self.owner = owner
- */
-
-static PyObject *__pyx_pf_11iocpsupport_5Event___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_5Event___init__ = {__Pyx_NAMESTR("__init__"), (PyCFunction)__pyx_pf_11iocpsupport_5Event___init__, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_5Event___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- PyObject *__pyx_v_self = 0;
- PyObject *__pyx_v_callback = 0;
- PyObject *__pyx_v_owner = 0;
- PyObject *__pyx_v_kw = 0;
- PyObject *__pyx_v_k = NULL;
- PyObject *__pyx_v_v = NULL;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- PyObject *__pyx_t_2 = NULL;
- Py_ssize_t __pyx_t_3;
- PyObject *(*__pyx_t_4)(PyObject *);
- PyObject *__pyx_t_5 = NULL;
- PyObject *__pyx_t_6 = NULL;
- PyObject *__pyx_t_7 = NULL;
- PyObject *(*__pyx_t_8)(PyObject *);
- int __pyx_t_9;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__self,&__pyx_n_s__callback,&__pyx_n_s__owner,0};
- __Pyx_RefNannySetupContext("__init__");
- __pyx_self = __pyx_self;
- __pyx_v_kw = PyDict_New(); if (unlikely(!__pyx_v_kw)) return NULL;
- __Pyx_GOTREF(__pyx_v_kw);
- {
- PyObject* values[3] = {0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__self);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__callback);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__owner);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kw, values, PyTuple_GET_SIZE(__pyx_args), "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- }
- __pyx_v_self = values[0];
- __pyx_v_callback = values[1];
- __pyx_v_owner = values[2];
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_DECREF(__pyx_v_kw); __pyx_v_kw = 0;
- __Pyx_AddTraceback("iocpsupport.Event.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "iocpsupport.pyx":143
- * class Event:
- * def __init__(self, callback, owner, **kw):
- * self.callback = callback # <<<<<<<<<<<<<<
- * self.owner = owner
- * for k, v in kw.items():
- */
- if (PyObject_SetAttr(__pyx_v_self, __pyx_n_s__callback, __pyx_v_callback) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "iocpsupport.pyx":144
- * def __init__(self, callback, owner, **kw):
- * self.callback = callback
- * self.owner = owner # <<<<<<<<<<<<<<
- * for k, v in kw.items():
- * setattr(self, k, v)
- */
- if (PyObject_SetAttr(__pyx_v_self, __pyx_n_s__owner, __pyx_v_owner) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "iocpsupport.pyx":145
- * self.callback = callback
- * self.owner = owner
- * for k, v in kw.items(): # <<<<<<<<<<<<<<
- * setattr(self, k, v)
- *
- */
- if (unlikely(((PyObject *)__pyx_v_kw) == Py_None)) {
- PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "items"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_1 = PyDict_Items(__pyx_v_kw); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyList_CheckExact(__pyx_t_1) || PyTuple_CheckExact(__pyx_t_1)) {
- __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
- __pyx_t_4 = NULL;
- } else {
- __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext;
- }
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- for (;;) {
- if (PyList_CheckExact(__pyx_t_2)) {
- if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
- __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++;
- } else if (PyTuple_CheckExact(__pyx_t_2)) {
- if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
- __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++;
- } else {
- __pyx_t_1 = __pyx_t_4(__pyx_t_2);
- if (unlikely(!__pyx_t_1)) {
- if (PyErr_Occurred()) {
- if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
- else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- break;
- }
- __Pyx_GOTREF(__pyx_t_1);
- }
- if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
- PyObject* sequence = __pyx_t_1;
- if (likely(PyTuple_CheckExact(sequence))) {
- if (unlikely(PyTuple_GET_SIZE(sequence) != 2)) {
- if (PyTuple_GET_SIZE(sequence) > 2) __Pyx_RaiseTooManyValuesError(2);
- else __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0);
- __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1);
- } else {
- if (unlikely(PyList_GET_SIZE(sequence) != 2)) {
- if (PyList_GET_SIZE(sequence) > 2) __Pyx_RaiseTooManyValuesError(2);
- else __Pyx_RaiseNeedMoreValuesError(PyList_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_5 = PyList_GET_ITEM(sequence, 0);
- __pyx_t_6 = PyList_GET_ITEM(sequence, 1);
- }
- __Pyx_INCREF(__pyx_t_5);
- __Pyx_INCREF(__pyx_t_6);
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- } else {
- Py_ssize_t index = -1;
- __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_7);
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
- index = 0; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L8_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_5);
- index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L8_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_6);
- if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
- goto __pyx_L9_unpacking_done;
- __pyx_L8_unpacking_failed:;
- __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
- if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear();
- if (!PyErr_Occurred()) __Pyx_RaiseNeedMoreValuesError(index);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_L9_unpacking_done:;
- }
- __Pyx_XDECREF(__pyx_v_k);
- __pyx_v_k = __pyx_t_5;
- __pyx_t_5 = 0;
- __Pyx_XDECREF(__pyx_v_v);
- __pyx_v_v = __pyx_t_6;
- __pyx_t_6 = 0;
-
- /* "iocpsupport.pyx":146
- * self.owner = owner
- * for k, v in kw.items():
- * setattr(self, k, v) # <<<<<<<<<<<<<<
- *
- * cdef class CompletionPort:
- */
- __pyx_t_9 = PyObject_SetAttr(__pyx_v_self, __pyx_v_k, __pyx_v_v); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_XDECREF(__pyx_t_6);
- __Pyx_XDECREF(__pyx_t_7);
- __Pyx_AddTraceback("iocpsupport.Event.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_kw);
- __Pyx_XDECREF(__pyx_v_k);
- __Pyx_XDECREF(__pyx_v_v);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":150
- * cdef class CompletionPort:
- * cdef HANDLE port
- * def __init__(self): # <<<<<<<<<<<<<<
- * cdef HANDLE res
- * res = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0)
- */
-
-static int __pyx_pf_11iocpsupport_14CompletionPort___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pf_11iocpsupport_14CompletionPort___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- __pyx_t_11iocpsupport_HANDLE __pyx_v_res;
- int __pyx_r;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("__init__");
- if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) {
- __Pyx_RaiseArgtupleInvalid("__init__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;}
- if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__init__", 0))) return -1;
-
- /* "iocpsupport.pyx":152
- * def __init__(self):
- * cdef HANDLE res
- * res = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0) # <<<<<<<<<<<<<<
- * if not res:
- * raise_error(0, 'CreateIoCompletionPort')
- */
- __pyx_v_res = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
-
- /* "iocpsupport.pyx":153
- * cdef HANDLE res
- * res = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0)
- * if not res: # <<<<<<<<<<<<<<
- * raise_error(0, 'CreateIoCompletionPort')
- * self.port = res
- */
- __pyx_t_1 = (!__pyx_v_res);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":154
- * res = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0)
- * if not res:
- * raise_error(0, 'CreateIoCompletionPort') # <<<<<<<<<<<<<<
- * self.port = res
- *
- */
- __pyx_t_2 = ((PyObject *)__pyx_n_s_1);
- __Pyx_INCREF(__pyx_t_2);
- __pyx_f_11iocpsupport_raise_error(0, __pyx_t_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- /* "iocpsupport.pyx":155
- * if not res:
- * raise_error(0, 'CreateIoCompletionPort')
- * self.port = res # <<<<<<<<<<<<<<
- *
- * def addHandle(self, HANDLE handle, size_t key=0):
- */
- ((struct __pyx_obj_11iocpsupport_CompletionPort *)__pyx_v_self)->port = __pyx_v_res;
-
- __pyx_r = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_AddTraceback("iocpsupport.CompletionPort.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = -1;
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":157
- * self.port = res
- *
- * def addHandle(self, HANDLE handle, size_t key=0): # <<<<<<<<<<<<<<
- * cdef HANDLE res
- * res = CreateIoCompletionPort(handle, self.port, key, 0)
- */
-
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_1addHandle(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_1addHandle(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- __pyx_t_11iocpsupport_HANDLE __pyx_v_handle;
- size_t __pyx_v_key;
- __pyx_t_11iocpsupport_HANDLE __pyx_v_res;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__handle,&__pyx_n_s__key,0};
- __Pyx_RefNannySetupContext("addHandle");
- {
- PyObject* values[2] = {0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__handle);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__key);
- if (value) { values[1] = value; kw_args--; }
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "addHandle") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else {
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- break;
- default: goto __pyx_L5_argtuple_error;
- }
- }
- __pyx_v_handle = __Pyx_PyInt_AsSize_t(values[0]); if (unlikely((__pyx_v_handle == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- if (values[1]) {
- __pyx_v_key = __Pyx_PyInt_AsSize_t(values[1]); if (unlikely((__pyx_v_key == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_key = ((size_t)0);
- }
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("addHandle", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.CompletionPort.addHandle", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "iocpsupport.pyx":159
- * def addHandle(self, HANDLE handle, size_t key=0):
- * cdef HANDLE res
- * res = CreateIoCompletionPort(handle, self.port, key, 0) # <<<<<<<<<<<<<<
- * if not res:
- * raise_error(0, 'CreateIoCompletionPort')
- */
- __pyx_v_res = CreateIoCompletionPort(__pyx_v_handle, ((struct __pyx_obj_11iocpsupport_CompletionPort *)__pyx_v_self)->port, __pyx_v_key, 0);
-
- /* "iocpsupport.pyx":160
- * cdef HANDLE res
- * res = CreateIoCompletionPort(handle, self.port, key, 0)
- * if not res: # <<<<<<<<<<<<<<
- * raise_error(0, 'CreateIoCompletionPort')
- *
- */
- __pyx_t_1 = (!__pyx_v_res);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":161
- * res = CreateIoCompletionPort(handle, self.port, key, 0)
- * if not res:
- * raise_error(0, 'CreateIoCompletionPort') # <<<<<<<<<<<<<<
- *
- * def getEvent(self, long timeout):
- */
- __pyx_t_2 = ((PyObject *)__pyx_n_s_1);
- __Pyx_INCREF(__pyx_t_2);
- __pyx_f_11iocpsupport_raise_error(0, __pyx_t_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_AddTraceback("iocpsupport.CompletionPort.addHandle", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":163
- * raise_error(0, 'CreateIoCompletionPort')
- *
- * def getEvent(self, long timeout): # <<<<<<<<<<<<<<
- * cdef PyThreadState *_save
- * cdef unsigned long bytes, rc
- */
-
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_2getEvent(PyObject *__pyx_v_self, PyObject *__pyx_arg_timeout); /*proto*/
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_2getEvent(PyObject *__pyx_v_self, PyObject *__pyx_arg_timeout) {
- long __pyx_v_timeout;
- struct PyThreadState *__pyx_v__save;
- unsigned long __pyx_v_bytes;
- unsigned long __pyx_v_rc;
- size_t __pyx_v_key;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- PyObject *__pyx_v_obj = NULL;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("getEvent");
- assert(__pyx_arg_timeout); {
- __pyx_v_timeout = __Pyx_PyInt_AsLong(__pyx_arg_timeout); if (unlikely((__pyx_v_timeout == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.CompletionPort.getEvent", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "iocpsupport.pyx":169
- * cdef myOVERLAPPED *ov
- *
- * _save = PyEval_SaveThread() # <<<<<<<<<<<<<<
- * rc = GetQueuedCompletionStatus(self.port, &bytes, &key, <OVERLAPPED **>&ov, timeout)
- * PyEval_RestoreThread(_save)
- */
- __pyx_v__save = PyEval_SaveThread();
-
- /* "iocpsupport.pyx":170
- *
- * _save = PyEval_SaveThread()
- * rc = GetQueuedCompletionStatus(self.port, &bytes, &key, <OVERLAPPED **>&ov, timeout) # <<<<<<<<<<<<<<
- * PyEval_RestoreThread(_save)
- *
- */
- __pyx_v_rc = GetQueuedCompletionStatus(((struct __pyx_obj_11iocpsupport_CompletionPort *)__pyx_v_self)->port, (&__pyx_v_bytes), (&__pyx_v_key), ((OVERLAPPED **)(&__pyx_v_ov)), __pyx_v_timeout);
-
- /* "iocpsupport.pyx":171
- * _save = PyEval_SaveThread()
- * rc = GetQueuedCompletionStatus(self.port, &bytes, &key, <OVERLAPPED **>&ov, timeout)
- * PyEval_RestoreThread(_save) # <<<<<<<<<<<<<<
- *
- * if not rc:
- */
- PyEval_RestoreThread(__pyx_v__save);
-
- /* "iocpsupport.pyx":173
- * PyEval_RestoreThread(_save)
- *
- * if not rc: # <<<<<<<<<<<<<<
- * rc = GetLastError()
- * else:
- */
- __pyx_t_1 = (!__pyx_v_rc);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":174
- *
- * if not rc:
- * rc = GetLastError() # <<<<<<<<<<<<<<
- * else:
- * rc = 0
- */
- __pyx_v_rc = GetLastError();
- goto __pyx_L5;
- }
- /*else*/ {
-
- /* "iocpsupport.pyx":176
- * rc = GetLastError()
- * else:
- * rc = 0 # <<<<<<<<<<<<<<
- *
- * obj = None
- */
- __pyx_v_rc = 0;
- }
- __pyx_L5:;
-
- /* "iocpsupport.pyx":178
- * rc = 0
- *
- * obj = None # <<<<<<<<<<<<<<
- * if ov:
- * if ov.obj:
- */
- __Pyx_INCREF(Py_None);
- __pyx_v_obj = Py_None;
-
- /* "iocpsupport.pyx":179
- *
- * obj = None
- * if ov: # <<<<<<<<<<<<<<
- * if ov.obj:
- * obj = <object>ov.obj
- */
- __pyx_t_1 = (__pyx_v_ov != 0);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":180
- * obj = None
- * if ov:
- * if ov.obj: # <<<<<<<<<<<<<<
- * obj = <object>ov.obj
- * Py_DECREF(obj) # we are stealing a reference here
- */
- __pyx_t_1 = (__pyx_v_ov->obj != 0);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":181
- * if ov:
- * if ov.obj:
- * obj = <object>ov.obj # <<<<<<<<<<<<<<
- * Py_DECREF(obj) # we are stealing a reference here
- * PyMem_Free(ov)
- */
- __Pyx_INCREF(((PyObject *)__pyx_v_ov->obj));
- __Pyx_DECREF(__pyx_v_obj);
- __pyx_v_obj = ((PyObject *)__pyx_v_ov->obj);
-
- /* "iocpsupport.pyx":182
- * if ov.obj:
- * obj = <object>ov.obj
- * Py_DECREF(obj) # we are stealing a reference here # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- *
- */
- Py_DECREF(__pyx_v_obj);
- goto __pyx_L7;
- }
- __pyx_L7:;
-
- /* "iocpsupport.pyx":183
- * obj = <object>ov.obj
- * Py_DECREF(obj) # we are stealing a reference here
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- *
- * return (rc, bytes, key, obj)
- */
- PyMem_Free(__pyx_v_ov);
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "iocpsupport.pyx":185
- * PyMem_Free(ov)
- *
- * return (rc, bytes, key, obj) # <<<<<<<<<<<<<<
- *
- * def postEvent(self, unsigned long bytes, size_t key, obj):
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_2 = PyLong_FromUnsignedLong(__pyx_v_rc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyLong_FromUnsignedLong(__pyx_v_bytes); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_4 = __Pyx_PyInt_FromSize_t(__pyx_v_key); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_5));
- PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4);
- __Pyx_GIVEREF(__pyx_t_4);
- __Pyx_INCREF(__pyx_v_obj);
- PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_obj);
- __Pyx_GIVEREF(__pyx_v_obj);
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_t_4 = 0;
- __pyx_r = ((PyObject *)__pyx_t_5);
- __pyx_t_5 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_AddTraceback("iocpsupport.CompletionPort.getEvent", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_obj);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":187
- * return (rc, bytes, key, obj)
- *
- * def postEvent(self, unsigned long bytes, size_t key, obj): # <<<<<<<<<<<<<<
- * cdef myOVERLAPPED *ov
- * cdef unsigned long rc
- */
-
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_3postEvent(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_3postEvent(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- unsigned long __pyx_v_bytes;
- size_t __pyx_v_key;
- PyObject *__pyx_v_obj = 0;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- unsigned long __pyx_v_rc;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_t_2;
- PyObject *__pyx_t_3 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__bytes,&__pyx_n_s__key,&__pyx_n_s__obj,0};
- __Pyx_RefNannySetupContext("postEvent");
- {
- PyObject* values[3] = {0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__bytes);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__key);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("postEvent", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("postEvent", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "postEvent") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- }
- __pyx_v_bytes = __Pyx_PyInt_AsUnsignedLong(values[0]); if (unlikely((__pyx_v_bytes == (unsigned long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_key = __Pyx_PyInt_AsSize_t(values[1]); if (unlikely((__pyx_v_key == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_obj = values[2];
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("postEvent", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.CompletionPort.postEvent", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "iocpsupport.pyx":191
- * cdef unsigned long rc
- *
- * if obj is not None: # <<<<<<<<<<<<<<
- * ov = makeOV()
- * Py_INCREF(obj) # give ov its own reference to obj
- */
- __pyx_t_1 = (__pyx_v_obj != Py_None);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":192
- *
- * if obj is not None:
- * ov = makeOV() # <<<<<<<<<<<<<<
- * Py_INCREF(obj) # give ov its own reference to obj
- * ov.obj = <PyObject *>obj
- */
- __pyx_t_2 = __pyx_f_11iocpsupport_makeOV(); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_ov = __pyx_t_2;
-
- /* "iocpsupport.pyx":193
- * if obj is not None:
- * ov = makeOV()
- * Py_INCREF(obj) # give ov its own reference to obj # <<<<<<<<<<<<<<
- * ov.obj = <PyObject *>obj
- * else:
- */
- Py_INCREF(__pyx_v_obj);
-
- /* "iocpsupport.pyx":194
- * ov = makeOV()
- * Py_INCREF(obj) # give ov its own reference to obj
- * ov.obj = <PyObject *>obj # <<<<<<<<<<<<<<
- * else:
- * ov = NULL
- */
- __pyx_v_ov->obj = ((struct PyObject *)__pyx_v_obj);
- goto __pyx_L6;
- }
- /*else*/ {
-
- /* "iocpsupport.pyx":196
- * ov.obj = <PyObject *>obj
- * else:
- * ov = NULL # <<<<<<<<<<<<<<
- *
- * rc = PostQueuedCompletionStatus(self.port, bytes, key, <OVERLAPPED *>ov)
- */
- __pyx_v_ov = NULL;
- }
- __pyx_L6:;
-
- /* "iocpsupport.pyx":198
- * ov = NULL
- *
- * rc = PostQueuedCompletionStatus(self.port, bytes, key, <OVERLAPPED *>ov) # <<<<<<<<<<<<<<
- * if not rc:
- * if ov:
- */
- __pyx_v_rc = PostQueuedCompletionStatus(((struct __pyx_obj_11iocpsupport_CompletionPort *)__pyx_v_self)->port, __pyx_v_bytes, __pyx_v_key, ((OVERLAPPED *)__pyx_v_ov));
-
- /* "iocpsupport.pyx":199
- *
- * rc = PostQueuedCompletionStatus(self.port, bytes, key, <OVERLAPPED *>ov)
- * if not rc: # <<<<<<<<<<<<<<
- * if ov:
- * Py_DECREF(obj)
- */
- __pyx_t_1 = (!__pyx_v_rc);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":200
- * rc = PostQueuedCompletionStatus(self.port, bytes, key, <OVERLAPPED *>ov)
- * if not rc:
- * if ov: # <<<<<<<<<<<<<<
- * Py_DECREF(obj)
- * PyMem_Free(ov)
- */
- __pyx_t_1 = (__pyx_v_ov != 0);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":201
- * if not rc:
- * if ov:
- * Py_DECREF(obj) # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- * raise_error(0, 'PostQueuedCompletionStatus')
- */
- Py_DECREF(__pyx_v_obj);
-
- /* "iocpsupport.pyx":202
- * if ov:
- * Py_DECREF(obj)
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- * raise_error(0, 'PostQueuedCompletionStatus')
- *
- */
- PyMem_Free(__pyx_v_ov);
- goto __pyx_L8;
- }
- __pyx_L8:;
-
- /* "iocpsupport.pyx":203
- * Py_DECREF(obj)
- * PyMem_Free(ov)
- * raise_error(0, 'PostQueuedCompletionStatus') # <<<<<<<<<<<<<<
- *
- * def __del__(self):
- */
- __pyx_t_3 = ((PyObject *)__pyx_n_s_2);
- __Pyx_INCREF(__pyx_t_3);
- __pyx_f_11iocpsupport_raise_error(0, __pyx_t_3); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- goto __pyx_L7;
- }
- __pyx_L7:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_AddTraceback("iocpsupport.CompletionPort.postEvent", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":205
- * raise_error(0, 'PostQueuedCompletionStatus')
- *
- * def __del__(self): # <<<<<<<<<<<<<<
- * CloseHandle(self.port)
- *
- */
-
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_4__del__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pf_11iocpsupport_14CompletionPort_4__del__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- __Pyx_RefNannySetupContext("__del__");
-
- /* "iocpsupport.pyx":206
- *
- * def __del__(self):
- * CloseHandle(self.port) # <<<<<<<<<<<<<<
- *
- * def makesockaddr(object buff):
- */
- CloseHandle(((struct __pyx_obj_11iocpsupport_CompletionPort *)__pyx_v_self)->port);
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":208
- * CloseHandle(self.port)
- *
- * def makesockaddr(object buff): # <<<<<<<<<<<<<<
- * cdef void *mem_buffer
- * cdef Py_ssize_t size
- */
-
-static PyObject *__pyx_pf_11iocpsupport_makesockaddr(PyObject *__pyx_self, PyObject *__pyx_v_buff); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_makesockaddr = {__Pyx_NAMESTR("makesockaddr"), (PyCFunction)__pyx_pf_11iocpsupport_makesockaddr, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_makesockaddr(PyObject *__pyx_self, PyObject *__pyx_v_buff) {
- void *__pyx_v_mem_buffer;
- Py_ssize_t __pyx_v_size;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("makesockaddr");
- __pyx_self = __pyx_self;
-
- /* "iocpsupport.pyx":212
- * cdef Py_ssize_t size
- *
- * PyObject_AsReadBuffer(buff, &mem_buffer, &size) # <<<<<<<<<<<<<<
- * # XXX: this should really return the address family as well
- * return _makesockaddr(<sockaddr *>mem_buffer, size)
- */
- __pyx_t_1 = PyObject_AsReadBuffer(__pyx_v_buff, (&__pyx_v_mem_buffer), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "iocpsupport.pyx":214
- * PyObject_AsReadBuffer(buff, &mem_buffer, &size)
- * # XXX: this should really return the address family as well
- * return _makesockaddr(<sockaddr *>mem_buffer, size) # <<<<<<<<<<<<<<
- *
- * cdef object _makesockaddr(sockaddr *addr, Py_ssize_t len):
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_2 = __pyx_f_11iocpsupport__makesockaddr(((struct sockaddr *)__pyx_v_mem_buffer), __pyx_v_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_r = __pyx_t_2;
- __pyx_t_2 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_AddTraceback("iocpsupport.makesockaddr", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":216
- * return _makesockaddr(<sockaddr *>mem_buffer, size)
- *
- * cdef object _makesockaddr(sockaddr *addr, Py_ssize_t len): # <<<<<<<<<<<<<<
- * cdef sockaddr_in *sin
- * cdef sockaddr_in6 *sin6
- */
-
-static PyObject *__pyx_f_11iocpsupport__makesockaddr(struct sockaddr *__pyx_v_addr, Py_ssize_t __pyx_v_len) {
- struct sockaddr_in *__pyx_v_sin;
- struct sockaddr_in6 *__pyx_v_sin6;
- char __pyx_v_buff[256];
- int __pyx_v_rc;
- __pyx_t_11iocpsupport_DWORD __pyx_v_buff_size;
- PyObject *__pyx_v_host = NULL;
- unsigned short __pyx_v_sa_port;
- PyObject *__pyx_v_port = NULL;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- unsigned short __pyx_t_5;
- PyObject *__pyx_t_6 = NULL;
- PyObject *(*__pyx_t_7)(PyObject *);
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("_makesockaddr");
-
- /* "iocpsupport.pyx":221
- * cdef char buff[256]
- * cdef int rc
- * cdef DWORD buff_size = sizeof(buff) # <<<<<<<<<<<<<<
- * if not len:
- * return None
- */
- __pyx_v_buff_size = (sizeof(__pyx_v_buff));
-
- /* "iocpsupport.pyx":222
- * cdef int rc
- * cdef DWORD buff_size = sizeof(buff)
- * if not len: # <<<<<<<<<<<<<<
- * return None
- * if addr.sa_family == AF_INET:
- */
- __pyx_t_1 = (!__pyx_v_len);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":223
- * cdef DWORD buff_size = sizeof(buff)
- * if not len:
- * return None # <<<<<<<<<<<<<<
- * if addr.sa_family == AF_INET:
- * sin = <sockaddr_in *>addr
- */
- __Pyx_XDECREF(__pyx_r);
- __Pyx_INCREF(Py_None);
- __pyx_r = Py_None;
- goto __pyx_L0;
- goto __pyx_L3;
- }
- __pyx_L3:;
-
- /* "iocpsupport.pyx":227
- * sin = <sockaddr_in *>addr
- * return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port)
- * elif addr.sa_family == AF_INET6: # <<<<<<<<<<<<<<
- * sin6 = <sockaddr_in6 *>addr
- * rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size)
- */
- switch (__pyx_v_addr->sa_family) {
-
- /* "iocpsupport.pyx":224
- * if not len:
- * return None
- * if addr.sa_family == AF_INET: # <<<<<<<<<<<<<<
- * sin = <sockaddr_in *>addr
- * return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port)
- */
- case AF_INET:
-
- /* "iocpsupport.pyx":225
- * return None
- * if addr.sa_family == AF_INET:
- * sin = <sockaddr_in *>addr # <<<<<<<<<<<<<<
- * return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port)
- * elif addr.sa_family == AF_INET6:
- */
- __pyx_v_sin = ((struct sockaddr_in *)__pyx_v_addr);
-
- /* "iocpsupport.pyx":226
- * if addr.sa_family == AF_INET:
- * sin = <sockaddr_in *>addr
- * return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port) # <<<<<<<<<<<<<<
- * elif addr.sa_family == AF_INET6:
- * sin6 = <sockaddr_in6 *>addr
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_2 = PyString_FromString(inet_ntoa(__pyx_v_sin->sin_addr)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyInt_FromLong(ntohs(__pyx_v_sin->sin_port)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_r = ((PyObject *)__pyx_t_4);
- __pyx_t_4 = 0;
- goto __pyx_L0;
- break;
-
- /* "iocpsupport.pyx":227
- * sin = <sockaddr_in *>addr
- * return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port)
- * elif addr.sa_family == AF_INET6: # <<<<<<<<<<<<<<
- * sin6 = <sockaddr_in6 *>addr
- * rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size)
- */
- case AF_INET6:
-
- /* "iocpsupport.pyx":228
- * return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port)
- * elif addr.sa_family == AF_INET6:
- * sin6 = <sockaddr_in6 *>addr # <<<<<<<<<<<<<<
- * rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size)
- * if rc == SOCKET_ERROR:
- */
- __pyx_v_sin6 = ((struct sockaddr_in6 *)__pyx_v_addr);
-
- /* "iocpsupport.pyx":229
- * elif addr.sa_family == AF_INET6:
- * sin6 = <sockaddr_in6 *>addr
- * rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size) # <<<<<<<<<<<<<<
- * if rc == SOCKET_ERROR:
- * raise_error(0, 'WSAAddressToString')
- */
- __pyx_v_rc = WSAAddressToStringA(__pyx_v_addr, (sizeof(struct sockaddr_in6)), NULL, __pyx_v_buff, (&__pyx_v_buff_size));
-
- /* "iocpsupport.pyx":230
- * sin6 = <sockaddr_in6 *>addr
- * rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size)
- * if rc == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * raise_error(0, 'WSAAddressToString')
- * host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port)
- */
- __pyx_t_1 = (__pyx_v_rc == SOCKET_ERROR);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":231
- * rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size)
- * if rc == SOCKET_ERROR:
- * raise_error(0, 'WSAAddressToString') # <<<<<<<<<<<<<<
- * host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port)
- * host, port = host.rsplit(':', 1)
- */
- __pyx_t_4 = ((PyObject *)__pyx_n_s__WSAAddressToString);
- __Pyx_INCREF(__pyx_t_4);
- __pyx_f_11iocpsupport_raise_error(0, __pyx_t_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- goto __pyx_L4;
- }
- __pyx_L4:;
-
- /* "iocpsupport.pyx":232
- * if rc == SOCKET_ERROR:
- * raise_error(0, 'WSAAddressToString')
- * host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port) # <<<<<<<<<<<<<<
- * host, port = host.rsplit(':', 1)
- * port = int(port)
- */
- __pyx_t_4 = PyString_FromString(__pyx_v_buff); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_5 = ntohs(__pyx_v_sin6->sin6_port);
- __pyx_v_host = __pyx_t_4;
- __pyx_t_4 = 0;
- __pyx_v_sa_port = __pyx_t_5;
-
- /* "iocpsupport.pyx":233
- * raise_error(0, 'WSAAddressToString')
- * host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port)
- * host, port = host.rsplit(':', 1) # <<<<<<<<<<<<<<
- * port = int(port)
- * assert host[0] == '['
- */
- __pyx_t_4 = PyObject_GetAttr(__pyx_v_host, __pyx_n_s__rsplit); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) {
- PyObject* sequence = __pyx_t_3;
- if (likely(PyTuple_CheckExact(sequence))) {
- if (unlikely(PyTuple_GET_SIZE(sequence) != 2)) {
- if (PyTuple_GET_SIZE(sequence) > 2) __Pyx_RaiseTooManyValuesError(2);
- else __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
- __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1);
- } else {
- if (unlikely(PyList_GET_SIZE(sequence) != 2)) {
- if (PyList_GET_SIZE(sequence) > 2) __Pyx_RaiseTooManyValuesError(2);
- else __Pyx_RaiseNeedMoreValuesError(PyList_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_4 = PyList_GET_ITEM(sequence, 0);
- __pyx_t_2 = PyList_GET_ITEM(sequence, 1);
- }
- __Pyx_INCREF(__pyx_t_4);
- __Pyx_INCREF(__pyx_t_2);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- } else {
- Py_ssize_t index = -1;
- __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_6);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext;
- index = 0; __pyx_t_4 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_4);
- index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_2);
- if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
- goto __pyx_L6_unpacking_done;
- __pyx_L5_unpacking_failed:;
- __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
- if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear();
- if (!PyErr_Occurred()) __Pyx_RaiseNeedMoreValuesError(index);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_L6_unpacking_done:;
- }
- __Pyx_DECREF(__pyx_v_host);
- __pyx_v_host = __pyx_t_4;
- __pyx_t_4 = 0;
- __pyx_v_port = __pyx_t_2;
- __pyx_t_2 = 0;
-
- /* "iocpsupport.pyx":234
- * host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port)
- * host, port = host.rsplit(':', 1)
- * port = int(port) # <<<<<<<<<<<<<<
- * assert host[0] == '['
- * assert host[-1] == ']'
- */
- __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __Pyx_INCREF(__pyx_v_port);
- PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_port);
- __Pyx_GIVEREF(__pyx_v_port);
- __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
- __Pyx_DECREF(__pyx_v_port);
- __pyx_v_port = __pyx_t_2;
- __pyx_t_2 = 0;
-
- /* "iocpsupport.pyx":235
- * host, port = host.rsplit(':', 1)
- * port = int(port)
- * assert host[0] == '[' # <<<<<<<<<<<<<<
- * assert host[-1] == ']'
- * assert port == sa_port
- */
- #ifndef CYTHON_WITHOUT_ASSERTIONS
- __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_host, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_1 = __Pyx_PyString_Equals(__pyx_t_2, ((PyObject *)__pyx_kp_s_5), Py_EQ); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- if (unlikely(!__pyx_t_1)) {
- PyErr_SetNone(PyExc_AssertionError);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- #endif
-
- /* "iocpsupport.pyx":236
- * port = int(port)
- * assert host[0] == '['
- * assert host[-1] == ']' # <<<<<<<<<<<<<<
- * assert port == sa_port
- * return host[1:-1], port
- */
- #ifndef CYTHON_WITHOUT_ASSERTIONS
- __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_host, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_1 = __Pyx_PyString_Equals(__pyx_t_2, ((PyObject *)__pyx_kp_s_6), Py_EQ); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- if (unlikely(!__pyx_t_1)) {
- PyErr_SetNone(PyExc_AssertionError);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- #endif
-
- /* "iocpsupport.pyx":237
- * assert host[0] == '['
- * assert host[-1] == ']'
- * assert port == sa_port # <<<<<<<<<<<<<<
- * return host[1:-1], port
- * else:
- */
- #ifndef CYTHON_WITHOUT_ASSERTIONS
- __pyx_t_2 = PyInt_FromLong(__pyx_v_sa_port); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyObject_RichCompare(__pyx_v_port, __pyx_t_2, Py_EQ); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- if (unlikely(!__pyx_t_1)) {
- PyErr_SetNone(PyExc_AssertionError);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- #endif
-
- /* "iocpsupport.pyx":238
- * assert host[-1] == ']'
- * assert port == sa_port
- * return host[1:-1], port # <<<<<<<<<<<<<<
- * else:
- * return PyString_FromStringAndSize(addr.sa_data, sizeof(addr.sa_data))
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_host, 1, -1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_2));
- PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- __Pyx_INCREF(__pyx_v_port);
- PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_port);
- __Pyx_GIVEREF(__pyx_v_port);
- __pyx_t_3 = 0;
- __pyx_r = ((PyObject *)__pyx_t_2);
- __pyx_t_2 = 0;
- goto __pyx_L0;
- break;
- default:
-
- /* "iocpsupport.pyx":240
- * return host[1:-1], port
- * else:
- * return PyString_FromStringAndSize(addr.sa_data, sizeof(addr.sa_data)) # <<<<<<<<<<<<<<
- *
- *
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_2 = PyString_FromStringAndSize(__pyx_v_addr->sa_data, (sizeof(__pyx_v_addr->sa_data))); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_r = __pyx_t_2;
- __pyx_t_2 = 0;
- goto __pyx_L0;
- break;
- }
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_6);
- __Pyx_AddTraceback("iocpsupport._makesockaddr", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = 0;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_host);
- __Pyx_XDECREF(__pyx_v_port);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":243
- *
- *
- * cdef object fillinetaddr(sockaddr_in *dest, object addr): # <<<<<<<<<<<<<<
- * cdef unsigned short port
- * cdef unsigned long res
- */
-
-static PyObject *__pyx_f_11iocpsupport_fillinetaddr(struct sockaddr_in *__pyx_v_dest, PyObject *__pyx_v_addr) {
- unsigned short __pyx_v_port;
- unsigned long __pyx_v_res;
- char *__pyx_v_hoststr;
- PyObject *__pyx_v_host = NULL;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *(*__pyx_t_4)(PyObject *);
- unsigned short __pyx_t_5;
- char *__pyx_t_6;
- int __pyx_t_7;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("fillinetaddr");
-
- /* "iocpsupport.pyx":247
- * cdef unsigned long res
- * cdef char *hoststr
- * host, port = addr # <<<<<<<<<<<<<<
- *
- * hoststr = PyString_AsString(host)
- */
- if ((likely(PyTuple_CheckExact(__pyx_v_addr))) || (PyList_CheckExact(__pyx_v_addr))) {
- PyObject* sequence = __pyx_v_addr;
- if (likely(PyTuple_CheckExact(sequence))) {
- if (unlikely(PyTuple_GET_SIZE(sequence) != 2)) {
- if (PyTuple_GET_SIZE(sequence) > 2) __Pyx_RaiseTooManyValuesError(2);
- else __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0);
- __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1);
- } else {
- if (unlikely(PyList_GET_SIZE(sequence) != 2)) {
- if (PyList_GET_SIZE(sequence) > 2) __Pyx_RaiseTooManyValuesError(2);
- else __Pyx_RaiseNeedMoreValuesError(PyList_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_1 = PyList_GET_ITEM(sequence, 0);
- __pyx_t_2 = PyList_GET_ITEM(sequence, 1);
- }
- __Pyx_INCREF(__pyx_t_1);
- __Pyx_INCREF(__pyx_t_2);
- } else {
- Py_ssize_t index = -1;
- __pyx_t_3 = PyObject_GetIter(__pyx_v_addr); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_4 = Py_TYPE(__pyx_t_3)->tp_iternext;
- index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_1);
- index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_2);
- if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- goto __pyx_L4_unpacking_done;
- __pyx_L3_unpacking_failed:;
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear();
- if (!PyErr_Occurred()) __Pyx_RaiseNeedMoreValuesError(index);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_L4_unpacking_done:;
- }
- __pyx_t_5 = __Pyx_PyInt_AsUnsignedShort(__pyx_t_2); if (unlikely((__pyx_t_5 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- __pyx_v_host = __pyx_t_1;
- __pyx_t_1 = 0;
- __pyx_v_port = __pyx_t_5;
-
- /* "iocpsupport.pyx":249
- * host, port = addr
- *
- * hoststr = PyString_AsString(host) # <<<<<<<<<<<<<<
- * res = inet_addr(hoststr)
- * if res == INADDR_ANY:
- */
- __pyx_t_6 = PyString_AsString(__pyx_v_host); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_hoststr = __pyx_t_6;
-
- /* "iocpsupport.pyx":250
- *
- * hoststr = PyString_AsString(host)
- * res = inet_addr(hoststr) # <<<<<<<<<<<<<<
- * if res == INADDR_ANY:
- * raise ValueError, 'invalid IP address'
- */
- __pyx_v_res = inet_addr(__pyx_v_hoststr);
-
- /* "iocpsupport.pyx":251
- * hoststr = PyString_AsString(host)
- * res = inet_addr(hoststr)
- * if res == INADDR_ANY: # <<<<<<<<<<<<<<
- * raise ValueError, 'invalid IP address'
- * dest.sin_addr.s_addr = res
- */
- __pyx_t_7 = (__pyx_v_res == INADDR_ANY);
- if (__pyx_t_7) {
-
- /* "iocpsupport.pyx":252
- * res = inet_addr(hoststr)
- * if res == INADDR_ANY:
- * raise ValueError, 'invalid IP address' # <<<<<<<<<<<<<<
- * dest.sin_addr.s_addr = res
- *
- */
- __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_kp_s_7), 0, 0);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- /* "iocpsupport.pyx":253
- * if res == INADDR_ANY:
- * raise ValueError, 'invalid IP address'
- * dest.sin_addr.s_addr = res # <<<<<<<<<<<<<<
- *
- * dest.sin_port = htons(port)
- */
- __pyx_v_dest->sin_addr.s_addr = __pyx_v_res;
-
- /* "iocpsupport.pyx":255
- * dest.sin_addr.s_addr = res
- *
- * dest.sin_port = htons(port) # <<<<<<<<<<<<<<
- *
- *
- */
- __pyx_v_dest->sin_port = htons(__pyx_v_port);
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_AddTraceback("iocpsupport.fillinetaddr", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = 0;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_host);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":258
- *
- *
- * cdef object fillinet6addr(sockaddr_in6 *dest, object addr): # <<<<<<<<<<<<<<
- * cdef unsigned short port
- * cdef unsigned long res
- */
-
-static PyObject *__pyx_f_11iocpsupport_fillinet6addr(struct sockaddr_in6 *__pyx_v_dest, PyObject *__pyx_v_addr) {
- unsigned short __pyx_v_port;
- char *__pyx_v_hoststr;
- int __pyx_v_addrlen;
- PyObject *__pyx_v_host = NULL;
- PyObject *__pyx_v_flow = NULL;
- PyObject *__pyx_v_scope = NULL;
- int __pyx_v_parseresult;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- PyObject *(*__pyx_t_6)(PyObject *);
- unsigned short __pyx_t_7;
- char *__pyx_t_8;
- int __pyx_t_9;
- unsigned long __pyx_t_10;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("fillinet6addr");
-
- /* "iocpsupport.pyx":262
- * cdef unsigned long res
- * cdef char *hoststr
- * cdef int addrlen = sizeof(sockaddr_in6) # <<<<<<<<<<<<<<
- * host, port, flow, scope = addr
- * host = host.split("%")[0] # remove scope ID, if any
- */
- __pyx_v_addrlen = (sizeof(struct sockaddr_in6));
-
- /* "iocpsupport.pyx":263
- * cdef char *hoststr
- * cdef int addrlen = sizeof(sockaddr_in6)
- * host, port, flow, scope = addr # <<<<<<<<<<<<<<
- * host = host.split("%")[0] # remove scope ID, if any
- *
- */
- if ((likely(PyTuple_CheckExact(__pyx_v_addr))) || (PyList_CheckExact(__pyx_v_addr))) {
- PyObject* sequence = __pyx_v_addr;
- if (likely(PyTuple_CheckExact(sequence))) {
- if (unlikely(PyTuple_GET_SIZE(sequence) != 4)) {
- if (PyTuple_GET_SIZE(sequence) > 4) __Pyx_RaiseTooManyValuesError(4);
- else __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0);
- __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1);
- __pyx_t_3 = PyTuple_GET_ITEM(sequence, 2);
- __pyx_t_4 = PyTuple_GET_ITEM(sequence, 3);
- } else {
- if (unlikely(PyList_GET_SIZE(sequence) != 4)) {
- if (PyList_GET_SIZE(sequence) > 4) __Pyx_RaiseTooManyValuesError(4);
- else __Pyx_RaiseNeedMoreValuesError(PyList_GET_SIZE(sequence));
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- }
- __pyx_t_1 = PyList_GET_ITEM(sequence, 0);
- __pyx_t_2 = PyList_GET_ITEM(sequence, 1);
- __pyx_t_3 = PyList_GET_ITEM(sequence, 2);
- __pyx_t_4 = PyList_GET_ITEM(sequence, 3);
- }
- __Pyx_INCREF(__pyx_t_1);
- __Pyx_INCREF(__pyx_t_2);
- __Pyx_INCREF(__pyx_t_3);
- __Pyx_INCREF(__pyx_t_4);
- } else {
- Py_ssize_t index = -1;
- __pyx_t_5 = PyObject_GetIter(__pyx_v_addr); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_5);
- __pyx_t_6 = Py_TYPE(__pyx_t_5)->tp_iternext;
- index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_1);
- index = 1; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_2);
- index = 2; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_3);
- index = 3; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L3_unpacking_failed;
- __Pyx_GOTREF(__pyx_t_4);
- if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
- goto __pyx_L4_unpacking_done;
- __pyx_L3_unpacking_failed:;
- __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
- if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear();
- if (!PyErr_Occurred()) __Pyx_RaiseNeedMoreValuesError(index);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_L4_unpacking_done:;
- }
- __pyx_t_7 = __Pyx_PyInt_AsUnsignedShort(__pyx_t_2); if (unlikely((__pyx_t_7 == (unsigned short)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- __pyx_v_host = __pyx_t_1;
- __pyx_t_1 = 0;
- __pyx_v_port = __pyx_t_7;
- __pyx_v_flow = __pyx_t_3;
- __pyx_t_3 = 0;
- __pyx_v_scope = __pyx_t_4;
- __pyx_t_4 = 0;
-
- /* "iocpsupport.pyx":264
- * cdef int addrlen = sizeof(sockaddr_in6)
- * host, port, flow, scope = addr
- * host = host.split("%")[0] # remove scope ID, if any # <<<<<<<<<<<<<<
- *
- * hoststr = PyString_AsString(host)
- */
- __pyx_t_4 = PyObject_GetAttr(__pyx_v_host, __pyx_n_s__split); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_9), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- __Pyx_DECREF(__pyx_v_host);
- __pyx_v_host = __pyx_t_4;
- __pyx_t_4 = 0;
-
- /* "iocpsupport.pyx":266
- * host = host.split("%")[0] # remove scope ID, if any
- *
- * hoststr = PyString_AsString(host) # <<<<<<<<<<<<<<
- * cdef int parseresult = WSAStringToAddressA(hoststr, AF_INET6, NULL,
- * <sockaddr *>dest, &addrlen)
- */
- __pyx_t_8 = PyString_AsString(__pyx_v_host); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_hoststr = __pyx_t_8;
-
- /* "iocpsupport.pyx":268
- * hoststr = PyString_AsString(host)
- * cdef int parseresult = WSAStringToAddressA(hoststr, AF_INET6, NULL,
- * <sockaddr *>dest, &addrlen) # <<<<<<<<<<<<<<
- * if parseresult == SOCKET_ERROR:
- * raise ValueError, 'invalid IPv6 address %r' % (host,)
- */
- __pyx_v_parseresult = WSAStringToAddressA(__pyx_v_hoststr, AF_INET6, NULL, ((struct sockaddr *)__pyx_v_dest), (&__pyx_v_addrlen));
-
- /* "iocpsupport.pyx":269
- * cdef int parseresult = WSAStringToAddressA(hoststr, AF_INET6, NULL,
- * <sockaddr *>dest, &addrlen)
- * if parseresult == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * raise ValueError, 'invalid IPv6 address %r' % (host,)
- * if parseresult != 0:
- */
- __pyx_t_9 = (__pyx_v_parseresult == SOCKET_ERROR);
- if (__pyx_t_9) {
-
- /* "iocpsupport.pyx":270
- * <sockaddr *>dest, &addrlen)
- * if parseresult == SOCKET_ERROR:
- * raise ValueError, 'invalid IPv6 address %r' % (host,) # <<<<<<<<<<<<<<
- * if parseresult != 0:
- * raise RuntimeError, 'undefined error occurred during address parsing'
- */
- __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- __Pyx_INCREF(__pyx_v_host);
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_host);
- __Pyx_GIVEREF(__pyx_v_host);
- __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_10), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
- __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_3), 0, 0);
- __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- /* "iocpsupport.pyx":271
- * if parseresult == SOCKET_ERROR:
- * raise ValueError, 'invalid IPv6 address %r' % (host,)
- * if parseresult != 0: # <<<<<<<<<<<<<<
- * raise RuntimeError, 'undefined error occurred during address parsing'
- * # sin6_host field was handled by WSAStringToAddress
- */
- __pyx_t_9 = (__pyx_v_parseresult != 0);
- if (__pyx_t_9) {
-
- /* "iocpsupport.pyx":272
- * raise ValueError, 'invalid IPv6 address %r' % (host,)
- * if parseresult != 0:
- * raise RuntimeError, 'undefined error occurred during address parsing' # <<<<<<<<<<<<<<
- * # sin6_host field was handled by WSAStringToAddress
- * dest.sin6_port = htons(port)
- */
- __Pyx_Raise(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_kp_s_11), 0, 0);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "iocpsupport.pyx":274
- * raise RuntimeError, 'undefined error occurred during address parsing'
- * # sin6_host field was handled by WSAStringToAddress
- * dest.sin6_port = htons(port) # <<<<<<<<<<<<<<
- * dest.sin6_flowinfo = flow
- * dest.sin6_scope_id = scope
- */
- __pyx_v_dest->sin6_port = htons(__pyx_v_port);
-
- /* "iocpsupport.pyx":275
- * # sin6_host field was handled by WSAStringToAddress
- * dest.sin6_port = htons(port)
- * dest.sin6_flowinfo = flow # <<<<<<<<<<<<<<
- * dest.sin6_scope_id = scope
- *
- */
- __pyx_t_10 = __Pyx_PyInt_AsUnsignedLong(__pyx_v_flow); if (unlikely((__pyx_t_10 == (unsigned long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_dest->sin6_flowinfo = __pyx_t_10;
-
- /* "iocpsupport.pyx":276
- * dest.sin6_port = htons(port)
- * dest.sin6_flowinfo = flow
- * dest.sin6_scope_id = scope # <<<<<<<<<<<<<<
- *
- *
- */
- __pyx_t_10 = __Pyx_PyInt_AsUnsignedLong(__pyx_v_scope); if (unlikely((__pyx_t_10 == (unsigned long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_dest->sin6_scope_id = __pyx_t_10;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_AddTraceback("iocpsupport.fillinet6addr", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = 0;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_host);
- __Pyx_XDECREF(__pyx_v_flow);
- __Pyx_XDECREF(__pyx_v_scope);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":279
- *
- *
- * def AllocateReadBuffer(int size): # <<<<<<<<<<<<<<
- * return PyBuffer_New(size)
- *
- */
-
-static PyObject *__pyx_pf_11iocpsupport_1AllocateReadBuffer(PyObject *__pyx_self, PyObject *__pyx_arg_size); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_1AllocateReadBuffer = {__Pyx_NAMESTR("AllocateReadBuffer"), (PyCFunction)__pyx_pf_11iocpsupport_1AllocateReadBuffer, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_1AllocateReadBuffer(PyObject *__pyx_self, PyObject *__pyx_arg_size) {
- int __pyx_v_size;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("AllocateReadBuffer");
- __pyx_self = __pyx_self;
- assert(__pyx_arg_size); {
- __pyx_v_size = __Pyx_PyInt_AsInt(__pyx_arg_size); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.AllocateReadBuffer", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "iocpsupport.pyx":280
- *
- * def AllocateReadBuffer(int size):
- * return PyBuffer_New(size) # <<<<<<<<<<<<<<
- *
- * def maxAddrLen(long s):
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_1 = PyBuffer_New(__pyx_v_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_r = __pyx_t_1;
- __pyx_t_1 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_AddTraceback("iocpsupport.AllocateReadBuffer", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":282
- * return PyBuffer_New(size)
- *
- * def maxAddrLen(long s): # <<<<<<<<<<<<<<
- * cdef WSAPROTOCOL_INFO wsa_pi
- * cdef int size, rc
- */
-
-static PyObject *__pyx_pf_11iocpsupport_2maxAddrLen(PyObject *__pyx_self, PyObject *__pyx_arg_s); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_2maxAddrLen = {__Pyx_NAMESTR("maxAddrLen"), (PyCFunction)__pyx_pf_11iocpsupport_2maxAddrLen, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_2maxAddrLen(PyObject *__pyx_self, PyObject *__pyx_arg_s) {
- long __pyx_v_s;
- WSAPROTOCOL_INFO __pyx_v_wsa_pi;
- int __pyx_v_size;
- int __pyx_v_rc;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("maxAddrLen");
- __pyx_self = __pyx_self;
- assert(__pyx_arg_s); {
- __pyx_v_s = __Pyx_PyInt_AsLong(__pyx_arg_s); if (unlikely((__pyx_v_s == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.maxAddrLen", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "iocpsupport.pyx":286
- * cdef int size, rc
- *
- * size = sizeof(wsa_pi) # <<<<<<<<<<<<<<
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- * if rc == SOCKET_ERROR:
- */
- __pyx_v_size = (sizeof(__pyx_v_wsa_pi));
-
- /* "iocpsupport.pyx":287
- *
- * size = sizeof(wsa_pi)
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size) # <<<<<<<<<<<<<<
- * if rc == SOCKET_ERROR:
- * raise_error(WSAGetLastError(), 'getsockopt')
- */
- __pyx_v_rc = getsockopt(__pyx_v_s, SOL_SOCKET, SO_PROTOCOL_INFO, ((char *)(&__pyx_v_wsa_pi)), (&__pyx_v_size));
-
- /* "iocpsupport.pyx":288
- * size = sizeof(wsa_pi)
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- * if rc == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * raise_error(WSAGetLastError(), 'getsockopt')
- * return wsa_pi.iMaxSockAddr
- */
- __pyx_t_1 = (__pyx_v_rc == SOCKET_ERROR);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":289
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- * if rc == SOCKET_ERROR:
- * raise_error(WSAGetLastError(), 'getsockopt') # <<<<<<<<<<<<<<
- * return wsa_pi.iMaxSockAddr
- *
- */
- __pyx_t_2 = ((PyObject *)__pyx_n_s__getsockopt);
- __Pyx_INCREF(__pyx_t_2);
- __pyx_f_11iocpsupport_raise_error(WSAGetLastError(), __pyx_t_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- /* "iocpsupport.pyx":290
- * if rc == SOCKET_ERROR:
- * raise_error(WSAGetLastError(), 'getsockopt')
- * return wsa_pi.iMaxSockAddr # <<<<<<<<<<<<<<
- *
- * cdef int getAddrFamily(SOCKET s) except *:
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_2 = PyInt_FromLong(__pyx_v_wsa_pi.iMaxSockAddr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_r = __pyx_t_2;
- __pyx_t_2 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_AddTraceback("iocpsupport.maxAddrLen", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "iocpsupport.pyx":292
- * return wsa_pi.iMaxSockAddr
- *
- * cdef int getAddrFamily(SOCKET s) except *: # <<<<<<<<<<<<<<
- * cdef WSAPROTOCOL_INFO wsa_pi
- * cdef int size, rc
- */
-
-static int __pyx_f_11iocpsupport_getAddrFamily(__pyx_t_11iocpsupport_SOCKET __pyx_v_s) {
- WSAPROTOCOL_INFO __pyx_v_wsa_pi;
- int __pyx_v_size;
- int __pyx_v_rc;
- int __pyx_r;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("getAddrFamily");
-
- /* "iocpsupport.pyx":296
- * cdef int size, rc
- *
- * size = sizeof(wsa_pi) # <<<<<<<<<<<<<<
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- * if rc == SOCKET_ERROR:
- */
- __pyx_v_size = (sizeof(__pyx_v_wsa_pi));
-
- /* "iocpsupport.pyx":297
- *
- * size = sizeof(wsa_pi)
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size) # <<<<<<<<<<<<<<
- * if rc == SOCKET_ERROR:
- * raise_error(WSAGetLastError(), 'getsockopt')
- */
- __pyx_v_rc = getsockopt(__pyx_v_s, SOL_SOCKET, SO_PROTOCOL_INFO, ((char *)(&__pyx_v_wsa_pi)), (&__pyx_v_size));
-
- /* "iocpsupport.pyx":298
- * size = sizeof(wsa_pi)
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- * if rc == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * raise_error(WSAGetLastError(), 'getsockopt')
- * return wsa_pi.iAddressFamily
- */
- __pyx_t_1 = (__pyx_v_rc == SOCKET_ERROR);
- if (__pyx_t_1) {
-
- /* "iocpsupport.pyx":299
- * rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- * if rc == SOCKET_ERROR:
- * raise_error(WSAGetLastError(), 'getsockopt') # <<<<<<<<<<<<<<
- * return wsa_pi.iAddressFamily
- *
- */
- __pyx_t_2 = ((PyObject *)__pyx_n_s__getsockopt);
- __Pyx_INCREF(__pyx_t_2);
- __pyx_f_11iocpsupport_raise_error(WSAGetLastError(), __pyx_t_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- goto __pyx_L3;
- }
- __pyx_L3:;
-
- /* "iocpsupport.pyx":300
- * if rc == SOCKET_ERROR:
- * raise_error(WSAGetLastError(), 'getsockopt')
- * return wsa_pi.iAddressFamily # <<<<<<<<<<<<<<
- *
- * import socket # for WSAStartup
- */
- __pyx_r = __pyx_v_wsa_pi.iAddressFamily;
- goto __pyx_L0;
-
- __pyx_r = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_AddTraceback("iocpsupport.getAddrFamily", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = 0;
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":5
- *
- *
- * def accept(long listening, long accepting, object buff, object obj): # <<<<<<<<<<<<<<
- * """
- * CAUTION: unlike system AcceptEx(), this function returns 0 on success
- */
-
-static PyObject *__pyx_pf_11iocpsupport_3accept(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_11iocpsupport_3accept[] = "\n CAUTION: unlike system AcceptEx(), this function returns 0 on success\n ";
-static PyMethodDef __pyx_mdef_11iocpsupport_3accept = {__Pyx_NAMESTR("accept"), (PyCFunction)__pyx_pf_11iocpsupport_3accept, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_11iocpsupport_3accept)};
-static PyObject *__pyx_pf_11iocpsupport_3accept(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- long __pyx_v_listening;
- long __pyx_v_accepting;
- PyObject *__pyx_v_buff = 0;
- PyObject *__pyx_v_obj = 0;
- unsigned long __pyx_v_bytes;
- int __pyx_v_rc;
- Py_ssize_t __pyx_v_size;
- void *__pyx_v_mem_buffer;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_t_2;
- int __pyx_t_3;
- PyObject *__pyx_t_4 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__listening,&__pyx_n_s__accepting,&__pyx_n_s__buff,&__pyx_n_s__obj,0};
- __Pyx_RefNannySetupContext("accept");
- __pyx_self = __pyx_self;
- {
- PyObject* values[4] = {0,0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__listening);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__accepting);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("accept", 1, 4, 4, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__buff);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("accept", 1, 4, 4, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 3:
- values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj);
- if (likely(values[3])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("accept", 1, 4, 4, 3); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "accept") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- }
- __pyx_v_listening = __Pyx_PyInt_AsLong(values[0]); if (unlikely((__pyx_v_listening == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_accepting = __Pyx_PyInt_AsLong(values[1]); if (unlikely((__pyx_v_accepting == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_buff = values[2];
- __pyx_v_obj = values[3];
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("accept", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.accept", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":15
- * cdef myOVERLAPPED *ov
- *
- * PyObject_AsWriteBuffer(buff, &mem_buffer, &size) # <<<<<<<<<<<<<<
- *
- * ov = makeOV()
- */
- __pyx_t_1 = PyObject_AsWriteBuffer(__pyx_v_buff, (&__pyx_v_mem_buffer), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":17
- * PyObject_AsWriteBuffer(buff, &mem_buffer, &size)
- *
- * ov = makeOV() # <<<<<<<<<<<<<<
- * if obj is not None:
- * ov.obj = <PyObject *>obj
- */
- __pyx_t_2 = __pyx_f_11iocpsupport_makeOV(); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_ov = __pyx_t_2;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":18
- *
- * ov = makeOV()
- * if obj is not None: # <<<<<<<<<<<<<<
- * ov.obj = <PyObject *>obj
- *
- */
- __pyx_t_3 = (__pyx_v_obj != Py_None);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":19
- * ov = makeOV()
- * if obj is not None:
- * ov.obj = <PyObject *>obj # <<<<<<<<<<<<<<
- *
- * rc = lpAcceptEx(listening, accepting, mem_buffer, 0,
- */
- __pyx_v_ov->obj = ((struct PyObject *)__pyx_v_obj);
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":23
- * rc = lpAcceptEx(listening, accepting, mem_buffer, 0,
- * <DWORD>size / 2, <DWORD>size / 2,
- * &bytes, <OVERLAPPED *>ov) # <<<<<<<<<<<<<<
- * if not rc:
- * rc = WSAGetLastError()
- */
- __pyx_v_rc = lpAcceptEx(__pyx_v_listening, __pyx_v_accepting, __pyx_v_mem_buffer, 0, (((__pyx_t_11iocpsupport_DWORD)__pyx_v_size) / 2), (((__pyx_t_11iocpsupport_DWORD)__pyx_v_size) / 2), (&__pyx_v_bytes), ((OVERLAPPED *)__pyx_v_ov));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":24
- * <DWORD>size / 2, <DWORD>size / 2,
- * &bytes, <OVERLAPPED *>ov)
- * if not rc: # <<<<<<<<<<<<<<
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- */
- __pyx_t_3 = (!__pyx_v_rc);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":25
- * &bytes, <OVERLAPPED *>ov)
- * if not rc:
- * rc = WSAGetLastError() # <<<<<<<<<<<<<<
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- */
- __pyx_v_rc = WSAGetLastError();
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":26
- * if not rc:
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING: # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- * return rc
- */
- __pyx_t_3 = (__pyx_v_rc != ERROR_IO_PENDING);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":27
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- * return rc
- *
- */
- PyMem_Free(__pyx_v_ov);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":28
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- * return rc # <<<<<<<<<<<<<<
- *
- * # operation is in progress
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_4 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_r = __pyx_t_4;
- __pyx_t_4 = 0;
- goto __pyx_L0;
- goto __pyx_L8;
- }
- __pyx_L8:;
- goto __pyx_L7;
- }
- __pyx_L7:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":31
- *
- * # operation is in progress
- * Py_XINCREF(obj) # <<<<<<<<<<<<<<
- * return 0
- *
- */
- Py_XINCREF(__pyx_v_obj);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":32
- * # operation is in progress
- * Py_XINCREF(obj)
- * return 0 # <<<<<<<<<<<<<<
- *
- * def get_accept_addrs(long s, object buff):
- */
- __Pyx_XDECREF(__pyx_r);
- __Pyx_INCREF(__pyx_int_0);
- __pyx_r = __pyx_int_0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_AddTraceback("iocpsupport.accept", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":34
- * return 0
- *
- * def get_accept_addrs(long s, object buff): # <<<<<<<<<<<<<<
- * cdef WSAPROTOCOL_INFO wsa_pi
- * cdef int locallen, remotelen
- */
-
-static PyObject *__pyx_pf_11iocpsupport_4get_accept_addrs(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_4get_accept_addrs = {__Pyx_NAMESTR("get_accept_addrs"), (PyCFunction)__pyx_pf_11iocpsupport_4get_accept_addrs, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_4get_accept_addrs(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- long __pyx_v_s;
- PyObject *__pyx_v_buff = 0;
- int __pyx_v_locallen;
- int __pyx_v_remotelen;
- Py_ssize_t __pyx_v_size;
- void *__pyx_v_mem_buffer;
- struct sockaddr *__pyx_v_localaddr;
- struct sockaddr *__pyx_v_remoteaddr;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__buff,0};
- __Pyx_RefNannySetupContext("get_accept_addrs");
- __pyx_self = __pyx_self;
- {
- PyObject* values[2] = {0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__buff);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("get_accept_addrs", 1, 2, 2, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "get_accept_addrs") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- }
- __pyx_v_s = __Pyx_PyInt_AsLong(values[0]); if (unlikely((__pyx_v_s == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_buff = values[1];
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("get_accept_addrs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.get_accept_addrs", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":41
- * cdef sockaddr *localaddr, *remoteaddr
- *
- * PyObject_AsReadBuffer(buff, &mem_buffer, &size) # <<<<<<<<<<<<<<
- *
- * lpGetAcceptExSockaddrs(mem_buffer, 0, <DWORD>size / 2, <DWORD>size / 2,
- */
- __pyx_t_1 = PyObject_AsReadBuffer(__pyx_v_buff, (&__pyx_v_mem_buffer), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":44
- *
- * lpGetAcceptExSockaddrs(mem_buffer, 0, <DWORD>size / 2, <DWORD>size / 2,
- * &localaddr, &locallen, &remoteaddr, &remotelen) # <<<<<<<<<<<<<<
- * return remoteaddr.sa_family, _makesockaddr(localaddr, locallen), _makesockaddr(remoteaddr, remotelen)
- *
- */
- lpGetAcceptExSockaddrs(__pyx_v_mem_buffer, 0, (((__pyx_t_11iocpsupport_DWORD)__pyx_v_size) / 2), (((__pyx_t_11iocpsupport_DWORD)__pyx_v_size) / 2), (&__pyx_v_localaddr), (&__pyx_v_locallen), (&__pyx_v_remoteaddr), (&__pyx_v_remotelen));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":45
- * lpGetAcceptExSockaddrs(mem_buffer, 0, <DWORD>size / 2, <DWORD>size / 2,
- * &localaddr, &locallen, &remoteaddr, &remotelen)
- * return remoteaddr.sa_family, _makesockaddr(localaddr, locallen), _makesockaddr(remoteaddr, remotelen) # <<<<<<<<<<<<<<
- *
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_2 = PyInt_FromLong(__pyx_v_remoteaddr->sa_family); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = __pyx_f_11iocpsupport__makesockaddr(__pyx_v_localaddr, __pyx_v_locallen); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_4 = __pyx_f_11iocpsupport__makesockaddr(__pyx_v_remoteaddr, __pyx_v_remotelen); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_5));
- PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4);
- __Pyx_GIVEREF(__pyx_t_4);
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_t_4 = 0;
- __pyx_r = ((PyObject *)__pyx_t_5);
- __pyx_t_5 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_AddTraceback("iocpsupport.get_accept_addrs", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":5
- *
- *
- * def connect(long s, object addr, object obj): # <<<<<<<<<<<<<<
- * """
- * CAUTION: unlike system ConnectEx(), this function returns 0 on success
- */
-
-static PyObject *__pyx_pf_11iocpsupport_5connect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_11iocpsupport_5connect[] = "\n CAUTION: unlike system ConnectEx(), this function returns 0 on success\n ";
-static PyMethodDef __pyx_mdef_11iocpsupport_5connect = {__Pyx_NAMESTR("connect"), (PyCFunction)__pyx_pf_11iocpsupport_5connect, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_11iocpsupport_5connect)};
-static PyObject *__pyx_pf_11iocpsupport_5connect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- long __pyx_v_s;
- PyObject *__pyx_v_addr = 0;
- PyObject *__pyx_v_obj = 0;
- int __pyx_v_family;
- int __pyx_v_rc;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- struct sockaddr_in __pyx_v_ipv4_name;
- struct sockaddr_in6 __pyx_v_ipv6_name;
- struct sockaddr *__pyx_v_name;
- int __pyx_v_namelen;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_t_2;
- int __pyx_t_3;
- int __pyx_t_4;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_t_5;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__addr,&__pyx_n_s__obj,0};
- __Pyx_RefNannySetupContext("connect");
- __pyx_self = __pyx_self;
- {
- PyObject* values[3] = {0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__addr);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("connect", 1, 3, 3, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("connect", 1, 3, 3, 2); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "connect") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- }
- __pyx_v_s = __Pyx_PyInt_AsLong(values[0]); if (unlikely((__pyx_v_s == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_addr = values[1];
- __pyx_v_obj = values[2];
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("connect", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.connect", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":16
- * cdef int namelen
- *
- * if not have_connectex: # <<<<<<<<<<<<<<
- * raise ValueError, 'ConnectEx is not available on this system'
- *
- */
- __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__have_connectex); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_3 = (!__pyx_t_2);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":17
- *
- * if not have_connectex:
- * raise ValueError, 'ConnectEx is not available on this system' # <<<<<<<<<<<<<<
- *
- * family = getAddrFamily(s)
- */
- __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_kp_s_12), 0, 0);
- {__pyx_filename = __pyx_f[2]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":19
- * raise ValueError, 'ConnectEx is not available on this system'
- *
- * family = getAddrFamily(s) # <<<<<<<<<<<<<<
- * if family == AF_INET:
- * name = <sockaddr *>&ipv4_name
- */
- __pyx_t_4 = __pyx_f_11iocpsupport_getAddrFamily(__pyx_v_s); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_family = __pyx_t_4;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":24
- * namelen = sizeof(ipv4_name)
- * fillinetaddr(&ipv4_name, addr)
- * elif family == AF_INET6: # <<<<<<<<<<<<<<
- * name = <sockaddr *>&ipv6_name
- * namelen = sizeof(ipv6_name)
- */
- switch (__pyx_v_family) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":20
- *
- * family = getAddrFamily(s)
- * if family == AF_INET: # <<<<<<<<<<<<<<
- * name = <sockaddr *>&ipv4_name
- * namelen = sizeof(ipv4_name)
- */
- case AF_INET:
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":21
- * family = getAddrFamily(s)
- * if family == AF_INET:
- * name = <sockaddr *>&ipv4_name # <<<<<<<<<<<<<<
- * namelen = sizeof(ipv4_name)
- * fillinetaddr(&ipv4_name, addr)
- */
- __pyx_v_name = ((struct sockaddr *)(&__pyx_v_ipv4_name));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":22
- * if family == AF_INET:
- * name = <sockaddr *>&ipv4_name
- * namelen = sizeof(ipv4_name) # <<<<<<<<<<<<<<
- * fillinetaddr(&ipv4_name, addr)
- * elif family == AF_INET6:
- */
- __pyx_v_namelen = (sizeof(__pyx_v_ipv4_name));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":23
- * name = <sockaddr *>&ipv4_name
- * namelen = sizeof(ipv4_name)
- * fillinetaddr(&ipv4_name, addr) # <<<<<<<<<<<<<<
- * elif family == AF_INET6:
- * name = <sockaddr *>&ipv6_name
- */
- __pyx_t_1 = __pyx_f_11iocpsupport_fillinetaddr((&__pyx_v_ipv4_name), __pyx_v_addr); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- break;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":24
- * namelen = sizeof(ipv4_name)
- * fillinetaddr(&ipv4_name, addr)
- * elif family == AF_INET6: # <<<<<<<<<<<<<<
- * name = <sockaddr *>&ipv6_name
- * namelen = sizeof(ipv6_name)
- */
- case AF_INET6:
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":25
- * fillinetaddr(&ipv4_name, addr)
- * elif family == AF_INET6:
- * name = <sockaddr *>&ipv6_name # <<<<<<<<<<<<<<
- * namelen = sizeof(ipv6_name)
- * fillinet6addr(&ipv6_name, addr)
- */
- __pyx_v_name = ((struct sockaddr *)(&__pyx_v_ipv6_name));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":26
- * elif family == AF_INET6:
- * name = <sockaddr *>&ipv6_name
- * namelen = sizeof(ipv6_name) # <<<<<<<<<<<<<<
- * fillinet6addr(&ipv6_name, addr)
- * else:
- */
- __pyx_v_namelen = (sizeof(__pyx_v_ipv6_name));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":27
- * name = <sockaddr *>&ipv6_name
- * namelen = sizeof(ipv6_name)
- * fillinet6addr(&ipv6_name, addr) # <<<<<<<<<<<<<<
- * else:
- * raise ValueError, 'unsupported address family'
- */
- __pyx_t_1 = __pyx_f_11iocpsupport_fillinet6addr((&__pyx_v_ipv6_name), __pyx_v_addr); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- break;
- default:
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":29
- * fillinet6addr(&ipv6_name, addr)
- * else:
- * raise ValueError, 'unsupported address family' # <<<<<<<<<<<<<<
- * name.sa_family = family
- *
- */
- __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_kp_s_13), 0, 0);
- {__pyx_filename = __pyx_f[2]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- break;
- }
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":30
- * else:
- * raise ValueError, 'unsupported address family'
- * name.sa_family = family # <<<<<<<<<<<<<<
- *
- * ov = makeOV()
- */
- __pyx_v_name->sa_family = __pyx_v_family;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":32
- * name.sa_family = family
- *
- * ov = makeOV() # <<<<<<<<<<<<<<
- * if obj is not None:
- * ov.obj = <PyObject *>obj
- */
- __pyx_t_5 = __pyx_f_11iocpsupport_makeOV(); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_ov = __pyx_t_5;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":33
- *
- * ov = makeOV()
- * if obj is not None: # <<<<<<<<<<<<<<
- * ov.obj = <PyObject *>obj
- *
- */
- __pyx_t_3 = (__pyx_v_obj != Py_None);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":34
- * ov = makeOV()
- * if obj is not None:
- * ov.obj = <PyObject *>obj # <<<<<<<<<<<<<<
- *
- * rc = lpConnectEx(s, name, namelen, NULL, 0, NULL, <OVERLAPPED *>ov)
- */
- __pyx_v_ov->obj = ((struct PyObject *)__pyx_v_obj);
- goto __pyx_L7;
- }
- __pyx_L7:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":36
- * ov.obj = <PyObject *>obj
- *
- * rc = lpConnectEx(s, name, namelen, NULL, 0, NULL, <OVERLAPPED *>ov) # <<<<<<<<<<<<<<
- *
- * if not rc:
- */
- __pyx_v_rc = lpConnectEx(__pyx_v_s, __pyx_v_name, __pyx_v_namelen, NULL, 0, NULL, ((OVERLAPPED *)__pyx_v_ov));
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":38
- * rc = lpConnectEx(s, name, namelen, NULL, 0, NULL, <OVERLAPPED *>ov)
- *
- * if not rc: # <<<<<<<<<<<<<<
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- */
- __pyx_t_3 = (!__pyx_v_rc);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":39
- *
- * if not rc:
- * rc = WSAGetLastError() # <<<<<<<<<<<<<<
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- */
- __pyx_v_rc = WSAGetLastError();
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":40
- * if not rc:
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING: # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- * return rc
- */
- __pyx_t_3 = (__pyx_v_rc != ERROR_IO_PENDING);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":41
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- * return rc
- *
- */
- PyMem_Free(__pyx_v_ov);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":42
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- * return rc # <<<<<<<<<<<<<<
- *
- * # operation is in progress
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_1 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_r = __pyx_t_1;
- __pyx_t_1 = 0;
- goto __pyx_L0;
- goto __pyx_L9;
- }
- __pyx_L9:;
- goto __pyx_L8;
- }
- __pyx_L8:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":45
- *
- * # operation is in progress
- * Py_XINCREF(obj) # <<<<<<<<<<<<<<
- * return 0
- *
- */
- Py_XINCREF(__pyx_v_obj);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":46
- * # operation is in progress
- * Py_XINCREF(obj)
- * return 0 # <<<<<<<<<<<<<<
- *
- */
- __Pyx_XDECREF(__pyx_r);
- __Pyx_INCREF(__pyx_int_0);
- __pyx_r = __pyx_int_0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_AddTraceback("iocpsupport.connect", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":5
- *
- *
- * def recv(long s, object bufflist, object obj, unsigned long flags = 0): # <<<<<<<<<<<<<<
- * cdef int rc, res
- * cdef myOVERLAPPED *ov
- */
-
-static PyObject *__pyx_pf_11iocpsupport_6recv(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_6recv = {__Pyx_NAMESTR("recv"), (PyCFunction)__pyx_pf_11iocpsupport_6recv, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_6recv(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- long __pyx_v_s;
- PyObject *__pyx_v_bufflist = 0;
- PyObject *__pyx_v_obj = 0;
- unsigned long __pyx_v_flags;
- int __pyx_v_rc;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- WSABUF *__pyx_v_ws_buf;
- unsigned long __pyx_v_bytes;
- struct PyObject **__pyx_v_buffers;
- Py_ssize_t __pyx_v_i;
- Py_ssize_t __pyx_v_size;
- Py_ssize_t __pyx_v_buffcount;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- void *__pyx_t_2;
- Py_ssize_t __pyx_t_3;
- int __pyx_t_4;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_t_5;
- int __pyx_t_6;
- PyObject *__pyx_t_7 = NULL;
- PyObject *__pyx_t_8 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__bufflist,&__pyx_n_s__obj,&__pyx_n_s__flags,0};
- __Pyx_RefNannySetupContext("recv");
- __pyx_self = __pyx_self;
- {
- PyObject* values[4] = {0,0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__bufflist);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("recv", 0, 3, 4, 1); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("recv", 0, 3, 4, 2); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 3:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__flags);
- if (value) { values[3] = value; kw_args--; }
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "recv") < 0)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else {
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- break;
- default: goto __pyx_L5_argtuple_error;
- }
- }
- __pyx_v_s = __Pyx_PyInt_AsLong(values[0]); if (unlikely((__pyx_v_s == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_bufflist = values[1];
- __pyx_v_obj = values[2];
- if (values[3]) {
- __pyx_v_flags = __Pyx_PyInt_AsUnsignedLong(values[3]); if (unlikely((__pyx_v_flags == (unsigned long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_flags = ((unsigned long)0);
- }
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("recv", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.recv", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
- __Pyx_INCREF(__pyx_v_bufflist);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":13
- * cdef Py_ssize_t i, size, buffcount
- *
- * bufflist = PySequence_Fast(bufflist, 'second argument needs to be a list') # <<<<<<<<<<<<<<
- * buffcount = PySequence_Fast_GET_SIZE(bufflist)
- * buffers = PySequence_Fast_ITEMS(bufflist)
- */
- __pyx_t_1 = PySequence_Fast(__pyx_v_bufflist, __pyx_k_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __Pyx_DECREF(__pyx_v_bufflist);
- __pyx_v_bufflist = __pyx_t_1;
- __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":14
- *
- * bufflist = PySequence_Fast(bufflist, 'second argument needs to be a list')
- * buffcount = PySequence_Fast_GET_SIZE(bufflist) # <<<<<<<<<<<<<<
- * buffers = PySequence_Fast_ITEMS(bufflist)
- *
- */
- __pyx_v_buffcount = PySequence_Fast_GET_SIZE(__pyx_v_bufflist);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":15
- * bufflist = PySequence_Fast(bufflist, 'second argument needs to be a list')
- * buffcount = PySequence_Fast_GET_SIZE(bufflist)
- * buffers = PySequence_Fast_ITEMS(bufflist) # <<<<<<<<<<<<<<
- *
- * ws_buf = <WSABUF *>PyMem_Malloc(buffcount*sizeof(WSABUF))
- */
- __pyx_v_buffers = PySequence_Fast_ITEMS(__pyx_v_bufflist);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":17
- * buffers = PySequence_Fast_ITEMS(bufflist)
- *
- * ws_buf = <WSABUF *>PyMem_Malloc(buffcount*sizeof(WSABUF)) # <<<<<<<<<<<<<<
- *
- * try:
- */
- __pyx_t_2 = PyMem_Malloc((__pyx_v_buffcount * (sizeof(WSABUF)))); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_ws_buf = ((WSABUF *)__pyx_t_2);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":19
- * ws_buf = <WSABUF *>PyMem_Malloc(buffcount*sizeof(WSABUF))
- *
- * try: # <<<<<<<<<<<<<<
- * for i from 0 <= i < buffcount:
- * PyObject_AsWriteBuffer(<object>buffers[i], <void **>&ws_buf[i].buf, &size)
- */
- /*try:*/ {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":20
- *
- * try:
- * for i from 0 <= i < buffcount: # <<<<<<<<<<<<<<
- * PyObject_AsWriteBuffer(<object>buffers[i], <void **>&ws_buf[i].buf, &size)
- * ws_buf[i].len = <DWORD>size
- */
- __pyx_t_3 = __pyx_v_buffcount;
- for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":21
- * try:
- * for i from 0 <= i < buffcount:
- * PyObject_AsWriteBuffer(<object>buffers[i], <void **>&ws_buf[i].buf, &size) # <<<<<<<<<<<<<<
- * ws_buf[i].len = <DWORD>size
- *
- */
- __pyx_t_1 = ((PyObject *)(__pyx_v_buffers[__pyx_v_i]));
- __Pyx_INCREF(__pyx_t_1);
- __pyx_t_4 = PyObject_AsWriteBuffer(__pyx_t_1, ((void **)(&(__pyx_v_ws_buf[__pyx_v_i]).buf)), (&__pyx_v_size)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":22
- * for i from 0 <= i < buffcount:
- * PyObject_AsWriteBuffer(<object>buffers[i], <void **>&ws_buf[i].buf, &size)
- * ws_buf[i].len = <DWORD>size # <<<<<<<<<<<<<<
- *
- * ov = makeOV()
- */
- (__pyx_v_ws_buf[__pyx_v_i]).len = ((__pyx_t_11iocpsupport_DWORD)__pyx_v_size);
- }
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":24
- * ws_buf[i].len = <DWORD>size
- *
- * ov = makeOV() # <<<<<<<<<<<<<<
- * if obj is not None:
- * ov.obj = <PyObject *>obj
- */
- __pyx_t_5 = __pyx_f_11iocpsupport_makeOV(); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __pyx_v_ov = __pyx_t_5;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":25
- *
- * ov = makeOV()
- * if obj is not None: # <<<<<<<<<<<<<<
- * ov.obj = <PyObject *>obj
- *
- */
- __pyx_t_6 = (__pyx_v_obj != Py_None);
- if (__pyx_t_6) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":26
- * ov = makeOV()
- * if obj is not None:
- * ov.obj = <PyObject *>obj # <<<<<<<<<<<<<<
- *
- * rc = WSARecv(s, ws_buf, <DWORD>buffcount, &bytes, &flags, <OVERLAPPED *>ov, NULL)
- */
- __pyx_v_ov->obj = ((struct PyObject *)__pyx_v_obj);
- goto __pyx_L11;
- }
- __pyx_L11:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":28
- * ov.obj = <PyObject *>obj
- *
- * rc = WSARecv(s, ws_buf, <DWORD>buffcount, &bytes, &flags, <OVERLAPPED *>ov, NULL) # <<<<<<<<<<<<<<
- *
- * if rc == SOCKET_ERROR:
- */
- __pyx_v_rc = WSARecv(__pyx_v_s, __pyx_v_ws_buf, ((__pyx_t_11iocpsupport_DWORD)__pyx_v_buffcount), (&__pyx_v_bytes), (&__pyx_v_flags), ((OVERLAPPED *)__pyx_v_ov), NULL);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":30
- * rc = WSARecv(s, ws_buf, <DWORD>buffcount, &bytes, &flags, <OVERLAPPED *>ov, NULL)
- *
- * if rc == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- */
- __pyx_t_6 = (__pyx_v_rc == SOCKET_ERROR);
- if (__pyx_t_6) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":31
- *
- * if rc == SOCKET_ERROR:
- * rc = WSAGetLastError() # <<<<<<<<<<<<<<
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- */
- __pyx_v_rc = WSAGetLastError();
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":32
- * if rc == SOCKET_ERROR:
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING: # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- * return rc, 0
- */
- __pyx_t_6 = (__pyx_v_rc != ERROR_IO_PENDING);
- if (__pyx_t_6) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":33
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- * return rc, 0
- *
- */
- PyMem_Free(__pyx_v_ov);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":34
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- * return rc, 0 # <<<<<<<<<<<<<<
- *
- * Py_XINCREF(obj)
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_1 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_7));
- PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
- __Pyx_GIVEREF(__pyx_t_1);
- __Pyx_INCREF(__pyx_int_0);
- PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_int_0);
- __Pyx_GIVEREF(__pyx_int_0);
- __pyx_t_1 = 0;
- __pyx_r = ((PyObject *)__pyx_t_7);
- __pyx_t_7 = 0;
- goto __pyx_L6;
- goto __pyx_L13;
- }
- __pyx_L13:;
- goto __pyx_L12;
- }
- __pyx_L12:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":36
- * return rc, 0
- *
- * Py_XINCREF(obj) # <<<<<<<<<<<<<<
- * return rc, bytes
- * finally:
- */
- Py_XINCREF(__pyx_v_obj);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":37
- *
- * Py_XINCREF(obj)
- * return rc, bytes # <<<<<<<<<<<<<<
- * finally:
- * PyMem_Free(ws_buf)
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_7 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __Pyx_GOTREF(__pyx_t_7);
- __pyx_t_1 = PyLong_FromUnsignedLong(__pyx_v_bytes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_8));
- PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7);
- __Pyx_GIVEREF(__pyx_t_7);
- PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
- __Pyx_GIVEREF(__pyx_t_1);
- __pyx_t_7 = 0;
- __pyx_t_1 = 0;
- __pyx_r = ((PyObject *)__pyx_t_8);
- __pyx_t_8 = 0;
- goto __pyx_L6;
- }
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":39
- * return rc, bytes
- * finally:
- * PyMem_Free(ws_buf) # <<<<<<<<<<<<<<
- *
- * def recvfrom(long s, object buff, object addr_buff, object addr_len_buff, object obj, unsigned long flags = 0):
- */
- /*finally:*/ {
- int __pyx_why;
- PyObject *__pyx_exc_type, *__pyx_exc_value, *__pyx_exc_tb;
- int __pyx_exc_lineno;
- __pyx_exc_type = 0; __pyx_exc_value = 0; __pyx_exc_tb = 0; __pyx_exc_lineno = 0;
- __pyx_why = 0; goto __pyx_L8;
- __pyx_L6: __pyx_exc_type = 0; __pyx_exc_value = 0; __pyx_exc_tb = 0; __pyx_exc_lineno = 0;
- __pyx_why = 3; goto __pyx_L8;
- __pyx_L7: {
- __pyx_why = 4;
- __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
- __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
- __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
- __Pyx_ErrFetch(&__pyx_exc_type, &__pyx_exc_value, &__pyx_exc_tb);
- __pyx_exc_lineno = __pyx_lineno;
- goto __pyx_L8;
- }
- __pyx_L8:;
- PyMem_Free(__pyx_v_ws_buf);
- switch (__pyx_why) {
- case 3: goto __pyx_L0;
- case 4: {
- __Pyx_ErrRestore(__pyx_exc_type, __pyx_exc_value, __pyx_exc_tb);
- __pyx_lineno = __pyx_exc_lineno;
- __pyx_exc_type = 0;
- __pyx_exc_value = 0;
- __pyx_exc_tb = 0;
- goto __pyx_L1_error;
- }
- }
- }
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_7);
- __Pyx_XDECREF(__pyx_t_8);
- __Pyx_AddTraceback("iocpsupport.recv", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_bufflist);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":41
- * PyMem_Free(ws_buf)
- *
- * def recvfrom(long s, object buff, object addr_buff, object addr_len_buff, object obj, unsigned long flags = 0): # <<<<<<<<<<<<<<
- * cdef int rc, c_addr_buff_len, c_addr_len_buff_len
- * cdef myOVERLAPPED *ov
- */
-
-static PyObject *__pyx_pf_11iocpsupport_7recvfrom(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_7recvfrom = {__Pyx_NAMESTR("recvfrom"), (PyCFunction)__pyx_pf_11iocpsupport_7recvfrom, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_7recvfrom(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- long __pyx_v_s;
- PyObject *__pyx_v_buff = 0;
- PyObject *__pyx_v_addr_buff = 0;
- PyObject *__pyx_v_addr_len_buff = 0;
- PyObject *__pyx_v_obj = 0;
- unsigned long __pyx_v_flags;
- int __pyx_v_rc;
- int __pyx_v_c_addr_buff_len;
- int __pyx_v_c_addr_len_buff_len;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- WSABUF __pyx_v_ws_buf;
- unsigned long __pyx_v_bytes;
- struct sockaddr *__pyx_v_c_addr_buff;
- int *__pyx_v_c_addr_len_buff;
- Py_ssize_t __pyx_v_size;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- int __pyx_t_2;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_t_3;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- PyObject *__pyx_t_6 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__buff,&__pyx_n_s__addr_buff,&__pyx_n_s__addr_len_buff,&__pyx_n_s__obj,&__pyx_n_s__flags,0};
- __Pyx_RefNannySetupContext("recvfrom");
- __pyx_self = __pyx_self;
- {
- PyObject* values[6] = {0,0,0,0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
- case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
- case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__buff);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("recvfrom", 0, 5, 6, 1); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__addr_buff);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("recvfrom", 0, 5, 6, 2); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 3:
- values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__addr_len_buff);
- if (likely(values[3])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("recvfrom", 0, 5, 6, 3); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 4:
- values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj);
- if (likely(values[4])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("recvfrom", 0, 5, 6, 4); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 5:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__flags);
- if (value) { values[5] = value; kw_args--; }
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "recvfrom") < 0)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else {
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
- case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
- values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- break;
- default: goto __pyx_L5_argtuple_error;
- }
- }
- __pyx_v_s = __Pyx_PyInt_AsLong(values[0]); if (unlikely((__pyx_v_s == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_buff = values[1];
- __pyx_v_addr_buff = values[2];
- __pyx_v_addr_len_buff = values[3];
- __pyx_v_obj = values[4];
- if (values[5]) {
- __pyx_v_flags = __Pyx_PyInt_AsUnsignedLong(values[5]); if (unlikely((__pyx_v_flags == (unsigned long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_flags = ((unsigned long)0);
- }
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("recvfrom", 0, 5, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.recvfrom", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":50
- * cdef Py_ssize_t size
- *
- * PyObject_AsWriteBuffer(buff, <void **>&ws_buf.buf, &size) # <<<<<<<<<<<<<<
- * ws_buf.len = <DWORD>size
- * PyObject_AsWriteBuffer(addr_buff, <void **>&c_addr_buff, &size)
- */
- __pyx_t_1 = PyObject_AsWriteBuffer(__pyx_v_buff, ((void **)(&__pyx_v_ws_buf.buf)), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":51
- *
- * PyObject_AsWriteBuffer(buff, <void **>&ws_buf.buf, &size)
- * ws_buf.len = <DWORD>size # <<<<<<<<<<<<<<
- * PyObject_AsWriteBuffer(addr_buff, <void **>&c_addr_buff, &size)
- * c_addr_buff_len = <int>size
- */
- __pyx_v_ws_buf.len = ((__pyx_t_11iocpsupport_DWORD)__pyx_v_size);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":52
- * PyObject_AsWriteBuffer(buff, <void **>&ws_buf.buf, &size)
- * ws_buf.len = <DWORD>size
- * PyObject_AsWriteBuffer(addr_buff, <void **>&c_addr_buff, &size) # <<<<<<<<<<<<<<
- * c_addr_buff_len = <int>size
- * PyObject_AsWriteBuffer(addr_len_buff, <void **>&c_addr_len_buff, &size)
- */
- __pyx_t_1 = PyObject_AsWriteBuffer(__pyx_v_addr_buff, ((void **)(&__pyx_v_c_addr_buff)), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":53
- * ws_buf.len = <DWORD>size
- * PyObject_AsWriteBuffer(addr_buff, <void **>&c_addr_buff, &size)
- * c_addr_buff_len = <int>size # <<<<<<<<<<<<<<
- * PyObject_AsWriteBuffer(addr_len_buff, <void **>&c_addr_len_buff, &size)
- * c_addr_len_buff_len = <int>size
- */
- __pyx_v_c_addr_buff_len = ((int)__pyx_v_size);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":54
- * PyObject_AsWriteBuffer(addr_buff, <void **>&c_addr_buff, &size)
- * c_addr_buff_len = <int>size
- * PyObject_AsWriteBuffer(addr_len_buff, <void **>&c_addr_len_buff, &size) # <<<<<<<<<<<<<<
- * c_addr_len_buff_len = <int>size
- *
- */
- __pyx_t_1 = PyObject_AsWriteBuffer(__pyx_v_addr_len_buff, ((void **)(&__pyx_v_c_addr_len_buff)), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":55
- * c_addr_buff_len = <int>size
- * PyObject_AsWriteBuffer(addr_len_buff, <void **>&c_addr_len_buff, &size)
- * c_addr_len_buff_len = <int>size # <<<<<<<<<<<<<<
- *
- * if c_addr_len_buff_len != sizeof(int):
- */
- __pyx_v_c_addr_len_buff_len = ((int)__pyx_v_size);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":57
- * c_addr_len_buff_len = <int>size
- *
- * if c_addr_len_buff_len != sizeof(int): # <<<<<<<<<<<<<<
- * raise ValueError, 'length of address length buffer needs to be sizeof(int)'
- *
- */
- __pyx_t_2 = (__pyx_v_c_addr_len_buff_len != (sizeof(int)));
- if (__pyx_t_2) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":58
- *
- * if c_addr_len_buff_len != sizeof(int):
- * raise ValueError, 'length of address length buffer needs to be sizeof(int)' # <<<<<<<<<<<<<<
- *
- * c_addr_len_buff[0] = c_addr_buff_len
- */
- __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_kp_s_15), 0, 0);
- {__pyx_filename = __pyx_f[3]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":60
- * raise ValueError, 'length of address length buffer needs to be sizeof(int)'
- *
- * c_addr_len_buff[0] = c_addr_buff_len # <<<<<<<<<<<<<<
- *
- * ov = makeOV()
- */
- (__pyx_v_c_addr_len_buff[0]) = __pyx_v_c_addr_buff_len;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":62
- * c_addr_len_buff[0] = c_addr_buff_len
- *
- * ov = makeOV() # <<<<<<<<<<<<<<
- * if obj is not None:
- * ov.obj = <PyObject *>obj
- */
- __pyx_t_3 = __pyx_f_11iocpsupport_makeOV(); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_ov = __pyx_t_3;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":63
- *
- * ov = makeOV()
- * if obj is not None: # <<<<<<<<<<<<<<
- * ov.obj = <PyObject *>obj
- *
- */
- __pyx_t_2 = (__pyx_v_obj != Py_None);
- if (__pyx_t_2) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":64
- * ov = makeOV()
- * if obj is not None:
- * ov.obj = <PyObject *>obj # <<<<<<<<<<<<<<
- *
- * rc = WSARecvFrom(s, &ws_buf, 1, &bytes, &flags, c_addr_buff, c_addr_len_buff, <OVERLAPPED *>ov, NULL)
- */
- __pyx_v_ov->obj = ((struct PyObject *)__pyx_v_obj);
- goto __pyx_L7;
- }
- __pyx_L7:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":66
- * ov.obj = <PyObject *>obj
- *
- * rc = WSARecvFrom(s, &ws_buf, 1, &bytes, &flags, c_addr_buff, c_addr_len_buff, <OVERLAPPED *>ov, NULL) # <<<<<<<<<<<<<<
- *
- * if rc == SOCKET_ERROR:
- */
- __pyx_v_rc = WSARecvFrom(__pyx_v_s, (&__pyx_v_ws_buf), 1, (&__pyx_v_bytes), (&__pyx_v_flags), __pyx_v_c_addr_buff, __pyx_v_c_addr_len_buff, ((OVERLAPPED *)__pyx_v_ov), NULL);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":68
- * rc = WSARecvFrom(s, &ws_buf, 1, &bytes, &flags, c_addr_buff, c_addr_len_buff, <OVERLAPPED *>ov, NULL)
- *
- * if rc == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- */
- __pyx_t_2 = (__pyx_v_rc == SOCKET_ERROR);
- if (__pyx_t_2) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":69
- *
- * if rc == SOCKET_ERROR:
- * rc = WSAGetLastError() # <<<<<<<<<<<<<<
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- */
- __pyx_v_rc = WSAGetLastError();
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":70
- * if rc == SOCKET_ERROR:
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING: # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- * return rc, 0
- */
- __pyx_t_2 = (__pyx_v_rc != ERROR_IO_PENDING);
- if (__pyx_t_2) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":71
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- * return rc, 0
- *
- */
- PyMem_Free(__pyx_v_ov);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":72
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- * return rc, 0 # <<<<<<<<<<<<<<
- *
- * Py_XINCREF(obj)
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_4 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_5));
- PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
- __Pyx_GIVEREF(__pyx_t_4);
- __Pyx_INCREF(__pyx_int_0);
- PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_0);
- __Pyx_GIVEREF(__pyx_int_0);
- __pyx_t_4 = 0;
- __pyx_r = ((PyObject *)__pyx_t_5);
- __pyx_t_5 = 0;
- goto __pyx_L0;
- goto __pyx_L9;
- }
- __pyx_L9:;
- goto __pyx_L8;
- }
- __pyx_L8:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":74
- * return rc, 0
- *
- * Py_XINCREF(obj) # <<<<<<<<<<<<<<
- * return rc, bytes
- *
- */
- Py_XINCREF(__pyx_v_obj);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":75
- *
- * Py_XINCREF(obj)
- * return rc, bytes # <<<<<<<<<<<<<<
- *
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_5 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_5);
- __pyx_t_4 = PyLong_FromUnsignedLong(__pyx_v_bytes); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_6));
- PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
- __Pyx_GIVEREF(__pyx_t_5);
- PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4);
- __Pyx_GIVEREF(__pyx_t_4);
- __pyx_t_5 = 0;
- __pyx_t_4 = 0;
- __pyx_r = ((PyObject *)__pyx_t_6);
- __pyx_t_6 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_XDECREF(__pyx_t_6);
- __Pyx_AddTraceback("iocpsupport.recvfrom", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":5
- *
- *
- * def send(long s, object buff, object obj, unsigned long flags = 0): # <<<<<<<<<<<<<<
- * cdef int rc
- * cdef myOVERLAPPED *ov
- */
-
-static PyObject *__pyx_pf_11iocpsupport_8send(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_11iocpsupport_8send = {__Pyx_NAMESTR("send"), (PyCFunction)__pyx_pf_11iocpsupport_8send, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pf_11iocpsupport_8send(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- long __pyx_v_s;
- PyObject *__pyx_v_buff = 0;
- PyObject *__pyx_v_obj = 0;
- unsigned long __pyx_v_flags;
- int __pyx_v_rc;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_v_ov;
- WSABUF __pyx_v_ws_buf;
- unsigned long __pyx_v_bytes;
- Py_ssize_t __pyx_v_size;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- struct __pyx_t_11iocpsupport_myOVERLAPPED *__pyx_t_2;
- int __pyx_t_3;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- PyObject *__pyx_t_6 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__s,&__pyx_n_s__buff,&__pyx_n_s__obj,&__pyx_n_s__flags,0};
- __Pyx_RefNannySetupContext("send");
- __pyx_self = __pyx_self;
- {
- PyObject* values[4] = {0,0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__s);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__buff);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("send", 0, 3, 4, 1); {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("send", 0, 3, 4, 2); {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 3:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__flags);
- if (value) { values[3] = value; kw_args--; }
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "send") < 0)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else {
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- break;
- default: goto __pyx_L5_argtuple_error;
- }
- }
- __pyx_v_s = __Pyx_PyInt_AsLong(values[0]); if (unlikely((__pyx_v_s == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_buff = values[1];
- __pyx_v_obj = values[2];
- if (values[3]) {
- __pyx_v_flags = __Pyx_PyInt_AsUnsignedLong(values[3]); if (unlikely((__pyx_v_flags == (unsigned long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_flags = ((unsigned long)0);
- }
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("send", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("iocpsupport.send", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":12
- * cdef Py_ssize_t size
- *
- * PyObject_AsReadBuffer(buff, <void **>&ws_buf.buf, &size) # <<<<<<<<<<<<<<
- * ws_buf.len = <DWORD>size
- *
- */
- __pyx_t_1 = PyObject_AsReadBuffer(__pyx_v_buff, ((void **)(&__pyx_v_ws_buf.buf)), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":13
- *
- * PyObject_AsReadBuffer(buff, <void **>&ws_buf.buf, &size)
- * ws_buf.len = <DWORD>size # <<<<<<<<<<<<<<
- *
- * ov = makeOV()
- */
- __pyx_v_ws_buf.len = ((__pyx_t_11iocpsupport_DWORD)__pyx_v_size);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":15
- * ws_buf.len = <DWORD>size
- *
- * ov = makeOV() # <<<<<<<<<<<<<<
- * if obj is not None:
- * ov.obj = <PyObject *>obj
- */
- __pyx_t_2 = __pyx_f_11iocpsupport_makeOV(); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_v_ov = __pyx_t_2;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":16
- *
- * ov = makeOV()
- * if obj is not None: # <<<<<<<<<<<<<<
- * ov.obj = <PyObject *>obj
- *
- */
- __pyx_t_3 = (__pyx_v_obj != Py_None);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":17
- * ov = makeOV()
- * if obj is not None:
- * ov.obj = <PyObject *>obj # <<<<<<<<<<<<<<
- *
- * rc = WSASend(s, &ws_buf, 1, &bytes, flags, <OVERLAPPED *>ov, NULL)
- */
- __pyx_v_ov->obj = ((struct PyObject *)__pyx_v_obj);
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":19
- * ov.obj = <PyObject *>obj
- *
- * rc = WSASend(s, &ws_buf, 1, &bytes, flags, <OVERLAPPED *>ov, NULL) # <<<<<<<<<<<<<<
- *
- * if rc == SOCKET_ERROR:
- */
- __pyx_v_rc = WSASend(__pyx_v_s, (&__pyx_v_ws_buf), 1, (&__pyx_v_bytes), __pyx_v_flags, ((OVERLAPPED *)__pyx_v_ov), NULL);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":21
- * rc = WSASend(s, &ws_buf, 1, &bytes, flags, <OVERLAPPED *>ov, NULL)
- *
- * if rc == SOCKET_ERROR: # <<<<<<<<<<<<<<
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- */
- __pyx_t_3 = (__pyx_v_rc == SOCKET_ERROR);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":22
- *
- * if rc == SOCKET_ERROR:
- * rc = WSAGetLastError() # <<<<<<<<<<<<<<
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- */
- __pyx_v_rc = WSAGetLastError();
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":23
- * if rc == SOCKET_ERROR:
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING: # <<<<<<<<<<<<<<
- * PyMem_Free(ov)
- * return rc, bytes
- */
- __pyx_t_3 = (__pyx_v_rc != ERROR_IO_PENDING);
- if (__pyx_t_3) {
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":24
- * rc = WSAGetLastError()
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov) # <<<<<<<<<<<<<<
- * return rc, bytes
- *
- */
- PyMem_Free(__pyx_v_ov);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":25
- * if rc != ERROR_IO_PENDING:
- * PyMem_Free(ov)
- * return rc, bytes # <<<<<<<<<<<<<<
- *
- * Py_XINCREF(obj)
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_4 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_5 = PyLong_FromUnsignedLong(__pyx_v_bytes); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_5);
- __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_6));
- PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
- __Pyx_GIVEREF(__pyx_t_4);
- PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5);
- __Pyx_GIVEREF(__pyx_t_5);
- __pyx_t_4 = 0;
- __pyx_t_5 = 0;
- __pyx_r = ((PyObject *)__pyx_t_6);
- __pyx_t_6 = 0;
- goto __pyx_L0;
- goto __pyx_L8;
- }
- __pyx_L8:;
- goto __pyx_L7;
- }
- __pyx_L7:;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":27
- * return rc, bytes
- *
- * Py_XINCREF(obj) # <<<<<<<<<<<<<<
- * return rc, bytes
- *
- */
- Py_XINCREF(__pyx_v_obj);
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":28
- *
- * Py_XINCREF(obj)
- * return rc, bytes # <<<<<<<<<<<<<<
- *
- *
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_6 = PyInt_FromLong(__pyx_v_rc); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_6);
- __pyx_t_5 = PyLong_FromUnsignedLong(__pyx_v_bytes); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_5);
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
- __Pyx_GIVEREF(__pyx_t_6);
- PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_5);
- __Pyx_GIVEREF(__pyx_t_5);
- __pyx_t_6 = 0;
- __pyx_t_5 = 0;
- __pyx_r = ((PyObject *)__pyx_t_4);
- __pyx_t_4 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_XDECREF(__pyx_t_6);
- __Pyx_AddTraceback("iocpsupport.send", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-static PyObject *__pyx_tp_new_11iocpsupport_CompletionPort(PyTypeObject *t, PyObject *a, PyObject *k) {
- PyObject *o = (*t->tp_alloc)(t, 0);
- if (!o) return 0;
- return o;
-}
-
-static void __pyx_tp_dealloc_11iocpsupport_CompletionPort(PyObject *o) {
- (*Py_TYPE(o)->tp_free)(o);
-}
-
-static PyMethodDef __pyx_methods_11iocpsupport_CompletionPort[] = {
- {__Pyx_NAMESTR("addHandle"), (PyCFunction)__pyx_pf_11iocpsupport_14CompletionPort_1addHandle, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
- {__Pyx_NAMESTR("getEvent"), (PyCFunction)__pyx_pf_11iocpsupport_14CompletionPort_2getEvent, METH_O, __Pyx_DOCSTR(0)},
- {__Pyx_NAMESTR("postEvent"), (PyCFunction)__pyx_pf_11iocpsupport_14CompletionPort_3postEvent, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
- {__Pyx_NAMESTR("__del__"), (PyCFunction)__pyx_pf_11iocpsupport_14CompletionPort_4__del__, METH_NOARGS, __Pyx_DOCSTR(0)},
- {0, 0, 0, 0}
-};
-
-static PyNumberMethods __pyx_tp_as_number_CompletionPort = {
- 0, /*nb_add*/
- 0, /*nb_subtract*/
- 0, /*nb_multiply*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_divide*/
- #endif
- 0, /*nb_remainder*/
- 0, /*nb_divmod*/
- 0, /*nb_power*/
- 0, /*nb_negative*/
- 0, /*nb_positive*/
- 0, /*nb_absolute*/
- 0, /*nb_nonzero*/
- 0, /*nb_invert*/
- 0, /*nb_lshift*/
- 0, /*nb_rshift*/
- 0, /*nb_and*/
- 0, /*nb_xor*/
- 0, /*nb_or*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_coerce*/
- #endif
- 0, /*nb_int*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_long*/
- #else
- 0, /*reserved*/
- #endif
- 0, /*nb_float*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_oct*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_hex*/
- #endif
- 0, /*nb_inplace_add*/
- 0, /*nb_inplace_subtract*/
- 0, /*nb_inplace_multiply*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_inplace_divide*/
- #endif
- 0, /*nb_inplace_remainder*/
- 0, /*nb_inplace_power*/
- 0, /*nb_inplace_lshift*/
- 0, /*nb_inplace_rshift*/
- 0, /*nb_inplace_and*/
- 0, /*nb_inplace_xor*/
- 0, /*nb_inplace_or*/
- 0, /*nb_floor_divide*/
- 0, /*nb_true_divide*/
- 0, /*nb_inplace_floor_divide*/
- 0, /*nb_inplace_true_divide*/
- #if PY_VERSION_HEX >= 0x02050000
- 0, /*nb_index*/
- #endif
-};
-
-static PySequenceMethods __pyx_tp_as_sequence_CompletionPort = {
- 0, /*sq_length*/
- 0, /*sq_concat*/
- 0, /*sq_repeat*/
- 0, /*sq_item*/
- 0, /*sq_slice*/
- 0, /*sq_ass_item*/
- 0, /*sq_ass_slice*/
- 0, /*sq_contains*/
- 0, /*sq_inplace_concat*/
- 0, /*sq_inplace_repeat*/
-};
-
-static PyMappingMethods __pyx_tp_as_mapping_CompletionPort = {
- 0, /*mp_length*/
- 0, /*mp_subscript*/
- 0, /*mp_ass_subscript*/
-};
-
-static PyBufferProcs __pyx_tp_as_buffer_CompletionPort = {
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getreadbuffer*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getwritebuffer*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getsegcount*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getcharbuffer*/
- #endif
- #if PY_VERSION_HEX >= 0x02060000
- 0, /*bf_getbuffer*/
- #endif
- #if PY_VERSION_HEX >= 0x02060000
- 0, /*bf_releasebuffer*/
- #endif
-};
-
-static PyTypeObject __pyx_type_11iocpsupport_CompletionPort = {
- PyVarObject_HEAD_INIT(0, 0)
- __Pyx_NAMESTR("iocpsupport.CompletionPort"), /*tp_name*/
- sizeof(struct __pyx_obj_11iocpsupport_CompletionPort), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- __pyx_tp_dealloc_11iocpsupport_CompletionPort, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- #if PY_MAJOR_VERSION < 3
- 0, /*tp_compare*/
- #else
- 0, /*reserved*/
- #endif
- 0, /*tp_repr*/
- &__pyx_tp_as_number_CompletionPort, /*tp_as_number*/
- &__pyx_tp_as_sequence_CompletionPort, /*tp_as_sequence*/
- &__pyx_tp_as_mapping_CompletionPort, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- &__pyx_tp_as_buffer_CompletionPort, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- __pyx_methods_11iocpsupport_CompletionPort, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- __pyx_pf_11iocpsupport_14CompletionPort___init__, /*tp_init*/
- 0, /*tp_alloc*/
- __pyx_tp_new_11iocpsupport_CompletionPort, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
- 0, /*tp_bases*/
- 0, /*tp_mro*/
- 0, /*tp_cache*/
- 0, /*tp_subclasses*/
- 0, /*tp_weaklist*/
- 0, /*tp_del*/
- #if PY_VERSION_HEX >= 0x02060000
- 0, /*tp_version_tag*/
- #endif
-};
-
-static PyMethodDef __pyx_methods[] = {
- {0, 0, 0, 0}
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef __pyx_moduledef = {
- PyModuleDef_HEAD_INIT,
- __Pyx_NAMESTR("iocpsupport"),
- 0, /* m_doc */
- -1, /* m_size */
- __pyx_methods /* m_methods */,
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL /* m_free */
-};
-#endif
-
-static __Pyx_StringTabEntry __pyx_string_tab[] = {
- {&__pyx_n_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 1},
- {&__pyx_kp_s_10, __pyx_k_10, sizeof(__pyx_k_10), 0, 0, 1, 0},
- {&__pyx_kp_s_11, __pyx_k_11, sizeof(__pyx_k_11), 0, 0, 1, 0},
- {&__pyx_kp_s_12, __pyx_k_12, sizeof(__pyx_k_12), 0, 0, 1, 0},
- {&__pyx_kp_s_13, __pyx_k_13, sizeof(__pyx_k_13), 0, 0, 1, 0},
- {&__pyx_kp_s_15, __pyx_k_15, sizeof(__pyx_k_15), 0, 0, 1, 0},
- {&__pyx_kp_s_16, __pyx_k_16, sizeof(__pyx_k_16), 0, 0, 1, 0},
- {&__pyx_n_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 1},
- {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
- {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0},
- {&__pyx_kp_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 0},
- {&__pyx_kp_s_7, __pyx_k_7, sizeof(__pyx_k_7), 0, 0, 1, 0},
- {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
- {&__pyx_n_s__AllocateReadBuffer, __pyx_k__AllocateReadBuffer, sizeof(__pyx_k__AllocateReadBuffer), 0, 0, 1, 1},
- {&__pyx_n_s__Event, __pyx_k__Event, sizeof(__pyx_k__Event), 0, 0, 1, 1},
- {&__pyx_n_s__MemoryError, __pyx_k__MemoryError, sizeof(__pyx_k__MemoryError), 0, 0, 1, 1},
- {&__pyx_n_s__RuntimeError, __pyx_k__RuntimeError, sizeof(__pyx_k__RuntimeError), 0, 0, 1, 1},
- {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
- {&__pyx_n_s__WSAAddressToString, __pyx_k__WSAAddressToString, sizeof(__pyx_k__WSAAddressToString), 0, 0, 1, 1},
- {&__pyx_n_s__WindowsError, __pyx_k__WindowsError, sizeof(__pyx_k__WindowsError), 0, 0, 1, 1},
- {&__pyx_n_s____init__, __pyx_k____init__, sizeof(__pyx_k____init__), 0, 0, 1, 1},
- {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
- {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
- {&__pyx_n_s__accept, __pyx_k__accept, sizeof(__pyx_k__accept), 0, 0, 1, 1},
- {&__pyx_n_s__accepting, __pyx_k__accepting, sizeof(__pyx_k__accepting), 0, 0, 1, 1},
- {&__pyx_n_s__addr, __pyx_k__addr, sizeof(__pyx_k__addr), 0, 0, 1, 1},
- {&__pyx_n_s__addr_buff, __pyx_k__addr_buff, sizeof(__pyx_k__addr_buff), 0, 0, 1, 1},
- {&__pyx_n_s__addr_len_buff, __pyx_k__addr_len_buff, sizeof(__pyx_k__addr_len_buff), 0, 0, 1, 1},
- {&__pyx_n_s__buff, __pyx_k__buff, sizeof(__pyx_k__buff), 0, 0, 1, 1},
- {&__pyx_n_s__bufflist, __pyx_k__bufflist, sizeof(__pyx_k__bufflist), 0, 0, 1, 1},
- {&__pyx_n_s__bytes, __pyx_k__bytes, sizeof(__pyx_k__bytes), 0, 0, 1, 1},
- {&__pyx_n_s__callback, __pyx_k__callback, sizeof(__pyx_k__callback), 0, 0, 1, 1},
- {&__pyx_n_s__connect, __pyx_k__connect, sizeof(__pyx_k__connect), 0, 0, 1, 1},
- {&__pyx_n_s__flags, __pyx_k__flags, sizeof(__pyx_k__flags), 0, 0, 1, 1},
- {&__pyx_n_s__get_accept_addrs, __pyx_k__get_accept_addrs, sizeof(__pyx_k__get_accept_addrs), 0, 0, 1, 1},
- {&__pyx_n_s__getsockopt, __pyx_k__getsockopt, sizeof(__pyx_k__getsockopt), 0, 0, 1, 1},
- {&__pyx_n_s__handle, __pyx_k__handle, sizeof(__pyx_k__handle), 0, 0, 1, 1},
- {&__pyx_n_s__have_connectex, __pyx_k__have_connectex, sizeof(__pyx_k__have_connectex), 0, 0, 1, 1},
- {&__pyx_n_s__iocpsupport, __pyx_k__iocpsupport, sizeof(__pyx_k__iocpsupport), 0, 0, 1, 1},
- {&__pyx_n_s__key, __pyx_k__key, sizeof(__pyx_k__key), 0, 0, 1, 1},
- {&__pyx_n_s__listening, __pyx_k__listening, sizeof(__pyx_k__listening), 0, 0, 1, 1},
- {&__pyx_n_s__makesockaddr, __pyx_k__makesockaddr, sizeof(__pyx_k__makesockaddr), 0, 0, 1, 1},
- {&__pyx_n_s__maxAddrLen, __pyx_k__maxAddrLen, sizeof(__pyx_k__maxAddrLen), 0, 0, 1, 1},
- {&__pyx_n_s__obj, __pyx_k__obj, sizeof(__pyx_k__obj), 0, 0, 1, 1},
- {&__pyx_n_s__owner, __pyx_k__owner, sizeof(__pyx_k__owner), 0, 0, 1, 1},
- {&__pyx_n_s__recv, __pyx_k__recv, sizeof(__pyx_k__recv), 0, 0, 1, 1},
- {&__pyx_n_s__recvfrom, __pyx_k__recvfrom, sizeof(__pyx_k__recvfrom), 0, 0, 1, 1},
- {&__pyx_n_s__rsplit, __pyx_k__rsplit, sizeof(__pyx_k__rsplit), 0, 0, 1, 1},
- {&__pyx_n_s__s, __pyx_k__s, sizeof(__pyx_k__s), 0, 0, 1, 1},
- {&__pyx_n_s__self, __pyx_k__self, sizeof(__pyx_k__self), 0, 0, 1, 1},
- {&__pyx_n_s__send, __pyx_k__send, sizeof(__pyx_k__send), 0, 0, 1, 1},
- {&__pyx_n_s__socket, __pyx_k__socket, sizeof(__pyx_k__socket), 0, 0, 1, 1},
- {&__pyx_n_s__split, __pyx_k__split, sizeof(__pyx_k__split), 0, 0, 1, 1},
- {0, 0, 0, 0, 0, 0, 0}
-};
-static int __Pyx_InitCachedBuiltins(void) {
- __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_builtin_MemoryError = __Pyx_GetName(__pyx_b, __pyx_n_s__MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_n_s__RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- return 0;
- __pyx_L1_error:;
- return -1;
-}
-
-static int __Pyx_InitCachedConstants(void) {
- __Pyx_RefNannyDeclarations
- __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants");
-
- /* "iocpsupport.pyx":233
- * raise_error(0, 'WSAAddressToString')
- * host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port)
- * host, port = host.rsplit(':', 1) # <<<<<<<<<<<<<<
- * port = int(port)
- * assert host[0] == '['
- */
- __pyx_k_tuple_4 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_4));
- __Pyx_INCREF(((PyObject *)__pyx_kp_s_3));
- PyTuple_SET_ITEM(__pyx_k_tuple_4, 0, ((PyObject *)__pyx_kp_s_3));
- __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_3));
- __Pyx_INCREF(__pyx_int_1);
- PyTuple_SET_ITEM(__pyx_k_tuple_4, 1, __pyx_int_1);
- __Pyx_GIVEREF(__pyx_int_1);
- __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_4));
-
- /* "iocpsupport.pyx":264
- * cdef int addrlen = sizeof(sockaddr_in6)
- * host, port, flow, scope = addr
- * host = host.split("%")[0] # remove scope ID, if any # <<<<<<<<<<<<<<
- *
- * hoststr = PyString_AsString(host)
- */
- __pyx_k_tuple_9 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_9));
- __Pyx_INCREF(((PyObject *)__pyx_kp_s_8));
- PyTuple_SET_ITEM(__pyx_k_tuple_9, 0, ((PyObject *)__pyx_kp_s_8));
- __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_8));
- __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_9));
- __Pyx_RefNannyFinishContext();
- return 0;
- __pyx_L1_error:;
- __Pyx_RefNannyFinishContext();
- return -1;
-}
-
-static int __Pyx_InitGlobals(void) {
- if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- return 0;
- __pyx_L1_error:;
- return -1;
-}
-
-#if PY_MAJOR_VERSION < 3
-PyMODINIT_FUNC initiocpsupport(void); /*proto*/
-PyMODINIT_FUNC initiocpsupport(void)
-#else
-PyMODINIT_FUNC PyInit_iocpsupport(void); /*proto*/
-PyMODINIT_FUNC PyInit_iocpsupport(void)
-#endif
-{
- PyObject *__pyx_t_1 = NULL;
- PyObject *__pyx_t_2 = NULL;
- int __pyx_t_3;
- __Pyx_RefNannyDeclarations
- #if CYTHON_REFNANNY
- __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
- if (!__Pyx_RefNanny) {
- PyErr_Clear();
- __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
- if (!__Pyx_RefNanny)
- Py_FatalError("failed to import 'refnanny' module");
- }
- #endif
- __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_iocpsupport(void)");
- if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- #ifdef __pyx_binding_PyCFunctionType_USED
- if (__pyx_binding_PyCFunctionType_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- #endif
- /*--- Library function declarations ---*/
- /*--- Threads initialization code ---*/
- #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
- #ifdef WITH_THREAD /* Python build with threading support? */
- PyEval_InitThreads();
- #endif
- #endif
- /*--- Module creation code ---*/
- #if PY_MAJOR_VERSION < 3
- __pyx_m = Py_InitModule4(__Pyx_NAMESTR("iocpsupport"), __pyx_methods, 0, 0, PYTHON_API_VERSION);
- #else
- __pyx_m = PyModule_Create(&__pyx_moduledef);
- #endif
- if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- #if PY_MAJOR_VERSION < 3
- Py_INCREF(__pyx_m);
- #endif
- __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));
- if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- /*--- Initialize various global constants etc. ---*/
- if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- if (__pyx_module_is_main_iocpsupport) {
- if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- }
- /*--- Builtin init code ---*/
- if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- /*--- Constants init code ---*/
- if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- /*--- Global init code ---*/
- /*--- Variable export code ---*/
- /*--- Function export code ---*/
- /*--- Type init code ---*/
- if (PyType_Ready(&__pyx_type_11iocpsupport_CompletionPort) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- if (__Pyx_SetAttrString(__pyx_m, "CompletionPort", (PyObject *)&__pyx_type_11iocpsupport_CompletionPort) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_ptype_11iocpsupport_CompletionPort = &__pyx_type_11iocpsupport_CompletionPort;
- /*--- Type import code ---*/
- /*--- Variable import code ---*/
- /*--- Function import code ---*/
- /*--- Execution code ---*/
-
- /* "iocpsupport.pyx":141
- * raise WindowsError(message, err)
- *
- * class Event: # <<<<<<<<<<<<<<
- * def __init__(self, callback, owner, **kw):
- * self.callback = callback
- */
- __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-
- /* "iocpsupport.pyx":142
- *
- * class Event:
- * def __init__(self, callback, owner, **kw): # <<<<<<<<<<<<<<
- * self.callback = callback
- * self.owner = owner
- */
- __pyx_t_2 = __pyx_binding_PyCFunctionType_NewEx(&__pyx_mdef_11iocpsupport_5Event___init__, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- if (PyObject_SetItem(__pyx_t_1, __pyx_n_s____init__, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
- /* "iocpsupport.pyx":141
- * raise WindowsError(message, err)
- *
- * class Event: # <<<<<<<<<<<<<<
- * def __init__(self, callback, owner, **kw):
- * self.callback = callback
- */
- __pyx_t_2 = __Pyx_CreateClass(((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1), __pyx_n_s__Event, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__Event, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-
- /* "iocpsupport.pyx":208
- * CloseHandle(self.port)
- *
- * def makesockaddr(object buff): # <<<<<<<<<<<<<<
- * cdef void *mem_buffer
- * cdef Py_ssize_t size
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_makesockaddr, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__makesockaddr, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "iocpsupport.pyx":279
- *
- *
- * def AllocateReadBuffer(int size): # <<<<<<<<<<<<<<
- * return PyBuffer_New(size)
- *
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_1AllocateReadBuffer, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__AllocateReadBuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "iocpsupport.pyx":282
- * return PyBuffer_New(size)
- *
- * def maxAddrLen(long s): # <<<<<<<<<<<<<<
- * cdef WSAPROTOCOL_INFO wsa_pi
- * cdef int size, rc
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_2maxAddrLen, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__maxAddrLen, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "iocpsupport.pyx":302
- * return wsa_pi.iAddressFamily
- *
- * import socket # for WSAStartup # <<<<<<<<<<<<<<
- * if not initWinsockPointers():
- * raise ValueError, 'Failed to initialize Winsock function vectors'
- */
- __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__socket), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__socket, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "iocpsupport.pyx":303
- *
- * import socket # for WSAStartup
- * if not initWinsockPointers(): # <<<<<<<<<<<<<<
- * raise ValueError, 'Failed to initialize Winsock function vectors'
- *
- */
- __pyx_t_3 = (!initWinsockPointers());
- if (__pyx_t_3) {
-
- /* "iocpsupport.pyx":304
- * import socket # for WSAStartup
- * if not initWinsockPointers():
- * raise ValueError, 'Failed to initialize Winsock function vectors' # <<<<<<<<<<<<<<
- *
- * have_connectex = (lpConnectEx != NULL)
- */
- __Pyx_Raise(__pyx_builtin_ValueError, ((PyObject *)__pyx_kp_s_16), 0, 0);
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L2;
- }
- __pyx_L2:;
-
- /* "iocpsupport.pyx":306
- * raise ValueError, 'Failed to initialize Winsock function vectors'
- *
- * have_connectex = (lpConnectEx != NULL) # <<<<<<<<<<<<<<
- *
- * include 'acceptex.pxi'
- */
- __pyx_t_1 = __Pyx_PyBool_FromLong((lpConnectEx != NULL)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__have_connectex, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":5
- *
- *
- * def accept(long listening, long accepting, object buff, object obj): # <<<<<<<<<<<<<<
- * """
- * CAUTION: unlike system AcceptEx(), this function returns 0 on success
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_3accept, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__accept, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\acceptex.pxi":34
- * return 0
- *
- * def get_accept_addrs(long s, object buff): # <<<<<<<<<<<<<<
- * cdef WSAPROTOCOL_INFO wsa_pi
- * cdef int locallen, remotelen
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_4get_accept_addrs, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__get_accept_addrs, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\connectex.pxi":5
- *
- *
- * def connect(long s, object addr, object obj): # <<<<<<<<<<<<<<
- * """
- * CAUTION: unlike system ConnectEx(), this function returns 0 on success
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_5connect, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__connect, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_6recv, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__recv, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsarecv.pxi":41
- * PyMem_Free(ws_buf)
- *
- * def recvfrom(long s, object buff, object addr_buff, object addr_len_buff, object obj, unsigned long flags = 0): # <<<<<<<<<<<<<<
- * cdef int rc, c_addr_buff_len, c_addr_len_buff_len
- * cdef myOVERLAPPED *ov
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_7recvfrom, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__recvfrom, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "C:\t\twisted\twisted\internet\iocpreactor\iocpsupport\wsasend.pxi":5
- *
- *
- * def send(long s, object buff, object obj, unsigned long flags = 0): # <<<<<<<<<<<<<<
- * cdef int rc
- * cdef myOVERLAPPED *ov
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11iocpsupport_8send, NULL, __pyx_n_s__iocpsupport); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__send, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "iocpsupport.pyx":1
- * # Copyright (c) Twisted Matrix Laboratories. # <<<<<<<<<<<<<<
- * # See LICENSE for details.
- *
- */
- __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_1));
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_2);
- if (__pyx_m) {
- __Pyx_AddTraceback("init iocpsupport", __pyx_clineno, __pyx_lineno, __pyx_filename);
- Py_DECREF(__pyx_m); __pyx_m = 0;
- } else if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_ImportError, "init iocpsupport");
- }
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- #if PY_MAJOR_VERSION < 3
- return;
- #else
- return __pyx_m;
- #endif
-}
-
-/* Runtime support code */
-
-#if CYTHON_REFNANNY
-static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
- PyObject *m = NULL, *p = NULL;
- void *r = NULL;
- m = PyImport_ImportModule((char *)modname);
- if (!m) goto end;
- p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
- if (!p) goto end;
- r = PyLong_AsVoidPtr(p);
-end:
- Py_XDECREF(p);
- Py_XDECREF(m);
- return (__Pyx_RefNannyAPIStruct *)r;
-}
-#endif /* CYTHON_REFNANNY */
-
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
- PyObject *result;
- result = PyObject_GetAttr(dict, name);
- if (!result) {
- if (dict != __pyx_b) {
- PyErr_Clear();
- result = PyObject_GetAttr(__pyx_b, name);
- }
- if (!result) {
- PyErr_SetObject(PyExc_NameError, name);
- }
- }
- return result;
-}
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
- PyObject *tmp_type, *tmp_value, *tmp_tb;
- PyThreadState *tstate = PyThreadState_GET();
-
- tmp_type = tstate->curexc_type;
- tmp_value = tstate->curexc_value;
- tmp_tb = tstate->curexc_traceback;
- tstate->curexc_type = type;
- tstate->curexc_value = value;
- tstate->curexc_traceback = tb;
- Py_XDECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
-}
-
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
- PyThreadState *tstate = PyThreadState_GET();
- *type = tstate->curexc_type;
- *value = tstate->curexc_value;
- *tb = tstate->curexc_traceback;
-
- tstate->curexc_type = 0;
- tstate->curexc_value = 0;
- tstate->curexc_traceback = 0;
-}
-
-
-#if PY_MAJOR_VERSION < 3
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
- /* cause is unused */
- Py_XINCREF(type);
- Py_XINCREF(value);
- Py_XINCREF(tb);
- /* First, check the traceback argument, replacing None with NULL. */
- if (tb == Py_None) {
- Py_DECREF(tb);
- tb = 0;
- }
- else if (tb != NULL && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto raise_error;
- }
- /* Next, replace a missing value with None */
- if (value == NULL) {
- value = Py_None;
- Py_INCREF(value);
- }
- #if PY_VERSION_HEX < 0x02050000
- if (!PyClass_Check(type))
- #else
- if (!PyType_Check(type))
- #endif
- {
- /* Raising an instance. The value should be a dummy. */
- if (value != Py_None) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto raise_error;
- }
- /* Normalize to raise <class>, <instance> */
- Py_DECREF(value);
- value = type;
- #if PY_VERSION_HEX < 0x02050000
- if (PyInstance_Check(type)) {
- type = (PyObject*) ((PyInstanceObject*)type)->in_class;
- Py_INCREF(type);
- }
- else {
- type = 0;
- PyErr_SetString(PyExc_TypeError,
- "raise: exception must be an old-style class or instance");
- goto raise_error;
- }
- #else
- type = (PyObject*) Py_TYPE(type);
- Py_INCREF(type);
- if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto raise_error;
- }
- #endif
- }
-
- __Pyx_ErrRestore(type, value, tb);
- return;
-raise_error:
- Py_XDECREF(value);
- Py_XDECREF(type);
- Py_XDECREF(tb);
- return;
-}
-
-#else /* Python 3+ */
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
- if (tb == Py_None) {
- tb = 0;
- } else if (tb && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto bad;
- }
- if (value == Py_None)
- value = 0;
-
- if (PyExceptionInstance_Check(type)) {
- if (value) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto bad;
- }
- value = type;
- type = (PyObject*) Py_TYPE(value);
- } else if (!PyExceptionClass_Check(type)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto bad;
- }
-
- if (cause) {
- PyObject *fixed_cause;
- if (PyExceptionClass_Check(cause)) {
- fixed_cause = PyObject_CallObject(cause, NULL);
- if (fixed_cause == NULL)
- goto bad;
- }
- else if (PyExceptionInstance_Check(cause)) {
- fixed_cause = cause;
- Py_INCREF(fixed_cause);
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "exception causes must derive from "
- "BaseException");
- goto bad;
- }
- if (!value) {
- value = PyObject_CallObject(type, NULL);
- }
- PyException_SetCause(value, fixed_cause);
- }
-
- PyErr_SetObject(type, value);
-
- if (tb) {
- PyThreadState *tstate = PyThreadState_GET();
- PyObject* tmp_tb = tstate->curexc_traceback;
- if (tb != tmp_tb) {
- Py_INCREF(tb);
- tstate->curexc_traceback = tb;
- Py_XDECREF(tmp_tb);
- }
- }
-
-bad:
- return;
-}
-#endif
-
-static void __Pyx_RaiseArgtupleInvalid(
- const char* func_name,
- int exact,
- Py_ssize_t num_min,
- Py_ssize_t num_max,
- Py_ssize_t num_found)
-{
- Py_ssize_t num_expected;
- const char *more_or_less;
-
- if (num_found < num_min) {
- num_expected = num_min;
- more_or_less = "at least";
- } else {
- num_expected = num_max;
- more_or_less = "at most";
- }
- if (exact) {
- more_or_less = "exactly";
- }
- PyErr_Format(PyExc_TypeError,
- "%s() takes %s %"PY_FORMAT_SIZE_T"d positional argument%s (%"PY_FORMAT_SIZE_T"d given)",
- func_name, more_or_less, num_expected,
- (num_expected == 1) ? "" : "s", num_found);
-}
-
-static void __Pyx_RaiseDoubleKeywordsError(
- const char* func_name,
- PyObject* kw_name)
-{
- PyErr_Format(PyExc_TypeError,
- #if PY_MAJOR_VERSION >= 3
- "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
- #else
- "%s() got multiple values for keyword argument '%s'", func_name,
- PyString_AS_STRING(kw_name));
- #endif
-}
-
-static int __Pyx_ParseOptionalKeywords(
- PyObject *kwds,
- PyObject **argnames[],
- PyObject *kwds2,
- PyObject *values[],
- Py_ssize_t num_pos_args,
- const char* function_name)
-{
- PyObject *key = 0, *value = 0;
- Py_ssize_t pos = 0;
- PyObject*** name;
- PyObject*** first_kw_arg = argnames + num_pos_args;
-
- while (PyDict_Next(kwds, &pos, &key, &value)) {
- name = first_kw_arg;
- while (*name && (**name != key)) name++;
- if (*name) {
- values[name-argnames] = value;
- } else {
- #if PY_MAJOR_VERSION < 3
- if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
- #else
- if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
- #endif
- goto invalid_keyword_type;
- } else {
- for (name = first_kw_arg; *name; name++) {
- #if PY_MAJOR_VERSION >= 3
- if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
- PyUnicode_Compare(**name, key) == 0) break;
- #else
- if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
- _PyString_Eq(**name, key)) break;
- #endif
- }
- if (*name) {
- values[name-argnames] = value;
- } else {
- /* unexpected keyword found */
- for (name=argnames; name != first_kw_arg; name++) {
- if (**name == key) goto arg_passed_twice;
- #if PY_MAJOR_VERSION >= 3
- if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
- PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
- #else
- if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
- _PyString_Eq(**name, key)) goto arg_passed_twice;
- #endif
- }
- if (kwds2) {
- if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
- } else {
- goto invalid_keyword;
- }
- }
- }
- }
- }
- return 0;
-arg_passed_twice:
- __Pyx_RaiseDoubleKeywordsError(function_name, **name);
- goto bad;
-invalid_keyword_type:
- PyErr_Format(PyExc_TypeError,
- "%s() keywords must be strings", function_name);
- goto bad;
-invalid_keyword:
- PyErr_Format(PyExc_TypeError,
- #if PY_MAJOR_VERSION < 3
- "%s() got an unexpected keyword argument '%s'",
- function_name, PyString_AsString(key));
- #else
- "%s() got an unexpected keyword argument '%U'",
- function_name, key);
- #endif
-bad:
- return -1;
-}
-
-static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
- PyErr_Format(PyExc_ValueError,
- "need more than %"PY_FORMAT_SIZE_T"d value%s to unpack",
- index, (index == 1) ? "" : "s");
-}
-
-static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
- PyErr_Format(PyExc_ValueError,
- "too many values to unpack (expected %"PY_FORMAT_SIZE_T"d)", expected);
-}
-
-static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
- if (unlikely(retval)) {
- Py_DECREF(retval);
- __Pyx_RaiseTooManyValuesError(expected);
- return -1;
- } else if (PyErr_Occurred()) {
- if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
- PyErr_Clear();
- return 0;
- } else {
- return -1;
- }
- }
- return 0;
-}
-
-static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
- PyObject *kwdict,
- const char* function_name,
- int kw_allowed)
-{
- PyObject* key = 0;
- Py_ssize_t pos = 0;
- while (PyDict_Next(kwdict, &pos, &key, 0)) {
- #if PY_MAJOR_VERSION < 3
- if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
- #else
- if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
- #endif
- goto invalid_keyword_type;
- }
- if ((!kw_allowed) && unlikely(key))
- goto invalid_keyword;
- return 1;
-invalid_keyword_type:
- PyErr_Format(PyExc_TypeError,
- "%s() keywords must be strings", function_name);
- return 0;
-invalid_keyword:
- PyErr_Format(PyExc_TypeError,
- #if PY_MAJOR_VERSION < 3
- "%s() got an unexpected keyword argument '%s'",
- function_name, PyString_AsString(key));
- #else
- "%s() got an unexpected keyword argument '%U'",
- function_name, key);
- #endif
- return 0;
-}
-
-
-static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
- PyObject *metaclass;
- /* Default metaclass */
-#if PY_MAJOR_VERSION < 3
- if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
- PyObject *base = PyTuple_GET_ITEM(bases, 0);
- metaclass = PyObject_GetAttrString(base, (char *)"__class__");
- if (!metaclass) {
- PyErr_Clear();
- metaclass = (PyObject*) Py_TYPE(base);
- }
- } else {
- metaclass = (PyObject *) &PyClass_Type;
- }
-#else
- if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
- PyObject *base = PyTuple_GET_ITEM(bases, 0);
- metaclass = (PyObject*) Py_TYPE(base);
- } else {
- metaclass = (PyObject *) &PyType_Type;
- }
-#endif
- Py_INCREF(metaclass);
- return metaclass;
-}
-
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
- PyObject *modname) {
- PyObject *result;
- PyObject *metaclass;
-
- if (PyDict_SetItemString(dict, "__module__", modname) < 0)
- return NULL;
-
- /* Python2 __metaclass__ */
- metaclass = PyDict_GetItemString(dict, "__metaclass__");
- if (metaclass) {
- Py_INCREF(metaclass);
- } else {
- metaclass = __Pyx_FindPy2Metaclass(bases);
- }
- result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
- Py_DECREF(metaclass);
- return result;
-}
-
-
-static PyObject *__pyx_binding_PyCFunctionType_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
- __pyx_binding_PyCFunctionType_object *op = PyObject_GC_New(__pyx_binding_PyCFunctionType_object, __pyx_binding_PyCFunctionType);
- if (op == NULL)
- return NULL;
- op->func.m_ml = ml;
- Py_XINCREF(self);
- op->func.m_self = self;
- Py_XINCREF(module);
- op->func.m_module = module;
- PyObject_GC_Track(op);
- return (PyObject *)op;
-}
-
-static void __pyx_binding_PyCFunctionType_dealloc(__pyx_binding_PyCFunctionType_object *m) {
- PyObject_GC_UnTrack(m);
- Py_XDECREF(m->func.m_self);
- Py_XDECREF(m->func.m_module);
- PyObject_GC_Del(m);
-}
-
-static PyObject *__pyx_binding_PyCFunctionType_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
- if (obj == Py_None)
- obj = NULL;
- return PyMethod_New(func, obj, type);
-}
-
-static int __pyx_binding_PyCFunctionType_init(void) {
- __pyx_binding_PyCFunctionType_type = PyCFunction_Type;
- __pyx_binding_PyCFunctionType_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
- __pyx_binding_PyCFunctionType_type.tp_dealloc = (destructor)__pyx_binding_PyCFunctionType_dealloc;
- __pyx_binding_PyCFunctionType_type.tp_descr_get = __pyx_binding_PyCFunctionType_descr_get;
- if (PyType_Ready(&__pyx_binding_PyCFunctionType_type) < 0) {
- return -1;
- }
- __pyx_binding_PyCFunctionType = &__pyx_binding_PyCFunctionType_type;
- return 0;
-
-}
-
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level) {
- PyObject *py_import = 0;
- PyObject *empty_list = 0;
- PyObject *module = 0;
- PyObject *global_dict = 0;
- PyObject *empty_dict = 0;
- PyObject *list;
- py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
- if (!py_import)
- goto bad;
- if (from_list)
- list = from_list;
- else {
- empty_list = PyList_New(0);
- if (!empty_list)
- goto bad;
- list = empty_list;
- }
- global_dict = PyModule_GetDict(__pyx_m);
- if (!global_dict)
- goto bad;
- empty_dict = PyDict_New();
- if (!empty_dict)
- goto bad;
- #if PY_VERSION_HEX >= 0x02050000
- {
- PyObject *py_level = PyInt_FromLong(level);
- if (!py_level)
- goto bad;
- module = PyObject_CallFunctionObjArgs(py_import,
- name, global_dict, empty_dict, list, py_level, NULL);
- Py_DECREF(py_level);
- }
- #else
- if (level>0) {
- PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
- goto bad;
- }
- module = PyObject_CallFunctionObjArgs(py_import,
- name, global_dict, empty_dict, list, NULL);
- #endif
-bad:
- Py_XDECREF(empty_list);
- Py_XDECREF(py_import);
- Py_XDECREF(empty_dict);
- return module;
-}
-
-static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
- if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
- return (equals == Py_EQ);
- } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
- if (PyBytes_GET_SIZE(s1) != PyBytes_GET_SIZE(s2)) {
- return (equals == Py_NE);
- } else if (PyBytes_GET_SIZE(s1) == 1) {
- if (equals == Py_EQ)
- return (PyBytes_AS_STRING(s1)[0] == PyBytes_AS_STRING(s2)[0]);
- else
- return (PyBytes_AS_STRING(s1)[0] != PyBytes_AS_STRING(s2)[0]);
- } else {
- int result = memcmp(PyBytes_AS_STRING(s1), PyBytes_AS_STRING(s2), (size_t)PyBytes_GET_SIZE(s1));
- return (equals == Py_EQ) ? (result == 0) : (result != 0);
- }
- } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
- return (equals == Py_NE);
- } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
- return (equals == Py_NE);
- } else {
- int result;
- PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
- if (!py_result)
- return -1;
- result = __Pyx_PyObject_IsTrue(py_result);
- Py_DECREF(py_result);
- return result;
- }
-}
-
-static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
- if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
- return (equals == Py_EQ);
- } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
- if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
- return (equals == Py_NE);
- } else if (PyUnicode_GET_SIZE(s1) == 1) {
- if (equals == Py_EQ)
- return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
- else
- return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
- } else {
- int result = PyUnicode_Compare(s1, s2);
- if ((result == -1) && unlikely(PyErr_Occurred()))
- return -1;
- return (equals == Py_EQ) ? (result == 0) : (result != 0);
- }
- } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
- return (equals == Py_NE);
- } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
- return (equals == Py_NE);
- } else {
- int result;
- PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
- if (!py_result)
- return -1;
- result = __Pyx_PyObject_IsTrue(py_result);
- Py_DECREF(py_result);
- return result;
- }
-}
-
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
- const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned char" :
- "value too large to convert to unsigned char");
- }
- return (unsigned char)-1;
- }
- return (unsigned char)val;
- }
- return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
- const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned short" :
- "value too large to convert to unsigned short");
- }
- return (unsigned short)-1;
- }
- return (unsigned short)val;
- }
- return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
- const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned int" :
- "value too large to convert to unsigned int");
- }
- return (unsigned int)-1;
- }
- return (unsigned int)val;
- }
- return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
- const char neg_one = (char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to char" :
- "value too large to convert to char");
- }
- return (char)-1;
- }
- return (char)val;
- }
- return (char)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
- const short neg_one = (short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to short" :
- "value too large to convert to short");
- }
- return (short)-1;
- }
- return (short)val;
- }
- return (short)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
- const int neg_one = (int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to int" :
- "value too large to convert to int");
- }
- return (int)-1;
- }
- return (int)val;
- }
- return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
- const signed char neg_one = (signed char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed char" :
- "value too large to convert to signed char");
- }
- return (signed char)-1;
- }
- return (signed char)val;
- }
- return (signed char)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
- const signed short neg_one = (signed short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed short" :
- "value too large to convert to signed short");
- }
- return (signed short)-1;
- }
- return (signed short)val;
- }
- return (signed short)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
- const signed int neg_one = (signed int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed int" :
- "value too large to convert to signed int");
- }
- return (signed int)-1;
- }
- return (signed int)val;
- }
- return (signed int)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
- const int neg_one = (int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to int" :
- "value too large to convert to int");
- }
- return (int)-1;
- }
- return (int)val;
- }
- return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
- const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
- return (unsigned long)-1;
- }
- return (unsigned long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
- return (unsigned long)-1;
- }
- return (unsigned long)PyLong_AsUnsignedLong(x);
- } else {
- return (unsigned long)PyLong_AsLong(x);
- }
- } else {
- unsigned long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (unsigned long)-1;
- val = __Pyx_PyInt_AsUnsignedLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
- const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned PY_LONG_LONG");
- return (unsigned PY_LONG_LONG)-1;
- }
- return (unsigned PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned PY_LONG_LONG");
- return (unsigned PY_LONG_LONG)-1;
- }
- return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
- } else {
- return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
- }
- } else {
- unsigned PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (unsigned PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
- const long neg_one = (long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to long");
- return (long)-1;
- }
- return (long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to long");
- return (long)-1;
- }
- return (long)PyLong_AsUnsignedLong(x);
- } else {
- return (long)PyLong_AsLong(x);
- }
- } else {
- long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (long)-1;
- val = __Pyx_PyInt_AsLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
- const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to PY_LONG_LONG");
- return (PY_LONG_LONG)-1;
- }
- return (PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to PY_LONG_LONG");
- return (PY_LONG_LONG)-1;
- }
- return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
- } else {
- return (PY_LONG_LONG)PyLong_AsLongLong(x);
- }
- } else {
- PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
- const signed long neg_one = (signed long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed long");
- return (signed long)-1;
- }
- return (signed long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed long");
- return (signed long)-1;
- }
- return (signed long)PyLong_AsUnsignedLong(x);
- } else {
- return (signed long)PyLong_AsLong(x);
- }
- } else {
- signed long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (signed long)-1;
- val = __Pyx_PyInt_AsSignedLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
- const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed PY_LONG_LONG");
- return (signed PY_LONG_LONG)-1;
- }
- return (signed PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed PY_LONG_LONG");
- return (signed PY_LONG_LONG)-1;
- }
- return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
- } else {
- return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
- }
- } else {
- signed PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (signed PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsSignedLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static int __Pyx_check_binary_version(void) {
- char ctversion[4], rtversion[4];
- PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
- PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
- if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
- char message[200];
- PyOS_snprintf(message, sizeof(message),
- "compiletime version %s of module '%.100s' "
- "does not match runtime version %s",
- ctversion, __Pyx_MODULE_NAME, rtversion);
- #if PY_VERSION_HEX < 0x02050000
- return PyErr_Warn(NULL, message);
- #else
- return PyErr_WarnEx(NULL, message, 1);
- #endif
- }
- return 0;
-}
-
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-
-static void __Pyx_AddTraceback(const char *funcname, int __pyx_clineno,
- int __pyx_lineno, const char *__pyx_filename) {
- PyObject *py_srcfile = 0;
- PyObject *py_funcname = 0;
- PyObject *py_globals = 0;
- PyCodeObject *py_code = 0;
- PyFrameObject *py_frame = 0;
-
- #if PY_MAJOR_VERSION < 3
- py_srcfile = PyString_FromString(__pyx_filename);
- #else
- py_srcfile = PyUnicode_FromString(__pyx_filename);
- #endif
- if (!py_srcfile) goto bad;
- if (__pyx_clineno) {
- #if PY_MAJOR_VERSION < 3
- py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
- #else
- py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
- #endif
- }
- else {
- #if PY_MAJOR_VERSION < 3
- py_funcname = PyString_FromString(funcname);
- #else
- py_funcname = PyUnicode_FromString(funcname);
- #endif
- }
- if (!py_funcname) goto bad;
- py_globals = PyModule_GetDict(__pyx_m);
- if (!py_globals) goto bad;
- py_code = PyCode_New(
- 0, /*int argcount,*/
- #if PY_MAJOR_VERSION >= 3
- 0, /*int kwonlyargcount,*/
- #endif
- 0, /*int nlocals,*/
- 0, /*int stacksize,*/
- 0, /*int flags,*/
- __pyx_empty_bytes, /*PyObject *code,*/
- __pyx_empty_tuple, /*PyObject *consts,*/
- __pyx_empty_tuple, /*PyObject *names,*/
- __pyx_empty_tuple, /*PyObject *varnames,*/
- __pyx_empty_tuple, /*PyObject *freevars,*/
- __pyx_empty_tuple, /*PyObject *cellvars,*/
- py_srcfile, /*PyObject *filename,*/
- py_funcname, /*PyObject *name,*/
- __pyx_lineno, /*int firstlineno,*/
- __pyx_empty_bytes /*PyObject *lnotab*/
- );
- if (!py_code) goto bad;
- py_frame = PyFrame_New(
- PyThreadState_GET(), /*PyThreadState *tstate,*/
- py_code, /*PyCodeObject *code,*/
- py_globals, /*PyObject *globals,*/
- 0 /*PyObject *locals*/
- );
- if (!py_frame) goto bad;
- py_frame->f_lineno = __pyx_lineno;
- PyTraceBack_Here(py_frame);
-bad:
- Py_XDECREF(py_srcfile);
- Py_XDECREF(py_funcname);
- Py_XDECREF(py_code);
- Py_XDECREF(py_frame);
-}
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
- while (t->p) {
- #if PY_MAJOR_VERSION < 3
- if (t->is_unicode) {
- *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
- } else if (t->intern) {
- *t->p = PyString_InternFromString(t->s);
- } else {
- *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
- }
- #else /* Python 3+ has unicode identifiers */
- if (t->is_unicode | t->is_str) {
- if (t->intern) {
- *t->p = PyUnicode_InternFromString(t->s);
- } else if (t->encoding) {
- *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
- } else {
- *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
- }
- } else {
- *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
- }
- #endif
- if (!*t->p)
- return -1;
- ++t;
- }
- return 0;
-}
-
-/* Type Conversion Functions */
-
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
- int is_true = x == Py_True;
- if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
- else return PyObject_IsTrue(x);
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
- PyNumberMethods *m;
- const char *name = NULL;
- PyObject *res = NULL;
-#if PY_VERSION_HEX < 0x03000000
- if (PyInt_Check(x) || PyLong_Check(x))
-#else
- if (PyLong_Check(x))
-#endif
- return Py_INCREF(x), x;
- m = Py_TYPE(x)->tp_as_number;
-#if PY_VERSION_HEX < 0x03000000
- if (m && m->nb_int) {
- name = "int";
- res = PyNumber_Int(x);
- }
- else if (m && m->nb_long) {
- name = "long";
- res = PyNumber_Long(x);
- }
-#else
- if (m && m->nb_int) {
- name = "int";
- res = PyNumber_Long(x);
- }
-#endif
- if (res) {
-#if PY_VERSION_HEX < 0x03000000
- if (!PyInt_Check(res) && !PyLong_Check(res)) {
-#else
- if (!PyLong_Check(res)) {
-#endif
- PyErr_Format(PyExc_TypeError,
- "__%s__ returned non-%s (type %.200s)",
- name, name, Py_TYPE(res)->tp_name);
- Py_DECREF(res);
- return NULL;
- }
- }
- else if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "an integer is required");
- }
- return res;
-}
-
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
- Py_ssize_t ival;
- PyObject* x = PyNumber_Index(b);
- if (!x) return -1;
- ival = PyInt_AsSsize_t(x);
- Py_DECREF(x);
- return ival;
-}
-
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
-#if PY_VERSION_HEX < 0x02050000
- if (ival <= LONG_MAX)
- return PyInt_FromLong((long)ival);
- else {
- unsigned char *bytes = (unsigned char *) &ival;
- int one = 1; int little = (int)*(unsigned char*)&one;
- return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
- }
-#else
- return PyInt_FromSize_t(ival);
-#endif
-}
-
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
- unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
- if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
- return (size_t)-1;
- } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
- PyErr_SetString(PyExc_OverflowError,
- "value too large to convert to size_t");
- return (size_t)-1;
- }
- return (size_t)val;
-}
-
-
-#endif /* Py_PYTHON_H */
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.pyx b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.pyx
deleted file mode 100644
index 97cf6348..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/iocpsupport.pyx
+++ /dev/null
@@ -1,312 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-# HANDLE and SOCKET are pointer-sized (they are 64 bit wide in 64-bit builds)
-ctypedef size_t HANDLE
-ctypedef size_t SOCKET
-ctypedef unsigned long DWORD
-# it's really a pointer, but we use it as an integer
-ctypedef size_t ULONG_PTR
-ctypedef int BOOL
-
-cdef extern from 'io.h':
- long _get_osfhandle(int filehandle)
-
-cdef extern from 'errno.h':
- int errno
- enum:
- EBADF
-
-cdef extern from 'winsock2.h':
- pass
-
-cdef extern from 'ws2tcpip.h':
- pass
-
-cdef extern from 'windows.h':
- ctypedef struct OVERLAPPED:
- pass
- HANDLE CreateIoCompletionPort(HANDLE fileHandle, HANDLE existing, ULONG_PTR key, DWORD numThreads)
- BOOL GetQueuedCompletionStatus(HANDLE port, DWORD *bytes, ULONG_PTR *key, OVERLAPPED **ov, DWORD timeout)
- BOOL PostQueuedCompletionStatus(HANDLE port, DWORD bytes, ULONG_PTR key, OVERLAPPED *ov)
- DWORD GetLastError()
- BOOL CloseHandle(HANDLE h)
- enum:
- INVALID_HANDLE_VALUE
- void DebugBreak()
-
-cdef extern from 'python.h':
- struct PyObject:
- pass
- void *PyMem_Malloc(size_t n) except NULL
- void PyMem_Free(void *p)
- struct PyThreadState:
- pass
- PyThreadState *PyEval_SaveThread()
- void PyEval_RestoreThread(PyThreadState *tstate)
- void Py_INCREF(object o)
- void Py_XINCREF(object o)
- void Py_DECREF(object o)
- void Py_XDECREF(object o)
- int PyObject_AsWriteBuffer(object obj, void **buffer, Py_ssize_t *buffer_len) except -1
- int PyObject_AsReadBuffer(object obj, void **buffer, Py_ssize_t *buffer_len) except -1
- object PyString_FromString(char *v)
- object PyString_FromStringAndSize(char *v, Py_ssize_t len)
- object PyBuffer_New(Py_ssize_t size)
- char *PyString_AsString(object obj) except NULL
- object PySequence_Fast(object o, char *m)
-# object PySequence_Fast_GET_ITEM(object o, Py_ssize_t i)
- PyObject** PySequence_Fast_ITEMS(object o)
- PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)
- Py_ssize_t PySequence_Fast_GET_SIZE(object o)
-
-cdef extern from '':
- struct sockaddr:
- unsigned short int sa_family
- char sa_data[0]
- cdef struct in_addr:
- unsigned long s_addr
- struct sockaddr_in:
- int sin_port
- in_addr sin_addr
- cdef struct in6_addr:
- char s6_addr[16]
- struct sockaddr_in6:
- short int sin6_family
- unsigned short int sin6_port
- unsigned long int sin6_flowinfo
- in6_addr sin6_addr
- unsigned long int sin6_scope_id
- int getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
- enum:
- SOL_SOCKET
- SO_PROTOCOL_INFO
- SOCKET_ERROR
- ERROR_IO_PENDING
- AF_INET
- AF_INET6
- INADDR_ANY
- ctypedef struct WSAPROTOCOL_INFO:
- int iMaxSockAddr
- int iAddressFamily
- int WSAGetLastError()
- char *inet_ntoa(in_addr ina)
- unsigned long inet_addr(char *cp)
- unsigned short ntohs(unsigned short netshort)
- unsigned short htons(unsigned short hostshort)
- ctypedef struct WSABUF:
- long len
- char *buf
-# cdef struct TRANSMIT_FILE_BUFFERS:
-# pass
- int WSARecv(SOCKET s, WSABUF *buffs, DWORD buffcount, DWORD *bytes, DWORD *flags, OVERLAPPED *ov, void *crud)
- int WSARecvFrom(SOCKET s, WSABUF *buffs, DWORD buffcount, DWORD *bytes, DWORD *flags, sockaddr *fromaddr, int *fromlen, OVERLAPPED *ov, void *crud)
- int WSASend(SOCKET s, WSABUF *buffs, DWORD buffcount, DWORD *bytes, DWORD flags, OVERLAPPED *ov, void *crud)
- int WSAAddressToStringA(sockaddr *lpsaAddress, DWORD dwAddressLength,
- WSAPROTOCOL_INFO *lpProtocolInfo,
- char *lpszAddressString,
- DWORD *lpdwAddressStringLength)
- int WSAStringToAddressA(char *AddressString, int AddressFamily,
- WSAPROTOCOL_INFO *lpProtocolInfo,
- sockaddr *lpAddress, int *lpAddressLength)
-
-cdef extern from 'string.h':
- void *memset(void *s, int c, size_t n)
-
-cdef extern from 'winsock_pointers.h':
- int initWinsockPointers()
- BOOL (*lpAcceptEx)(SOCKET listening, SOCKET accepting, void *buffer, DWORD recvlen, DWORD locallen, DWORD remotelen, DWORD *bytes, OVERLAPPED *ov)
- void (*lpGetAcceptExSockaddrs)(void *buffer, DWORD recvlen, DWORD locallen, DWORD remotelen, sockaddr **localaddr, int *locallen, sockaddr **remoteaddr, int *remotelen)
- BOOL (*lpConnectEx)(SOCKET s, sockaddr *name, int namelen, void *buff, DWORD sendlen, DWORD *sentlen, OVERLAPPED *ov)
-# BOOL (*lpTransmitFile)(SOCKET s, HANDLE hFile, DWORD size, DWORD buffer_size, OVERLAPPED *ov, TRANSMIT_FILE_BUFFERS *buff, DWORD flags)
-
-cdef struct myOVERLAPPED:
- OVERLAPPED ov
- PyObject *obj
-
-cdef myOVERLAPPED *makeOV() except NULL:
- cdef myOVERLAPPED *res
- res = <myOVERLAPPED *>PyMem_Malloc(sizeof(myOVERLAPPED))
- if not res:
- raise MemoryError
- memset(res, 0, sizeof(myOVERLAPPED))
- return res
-
-cdef void raise_error(int err, object message) except *:
- if not err:
- err = GetLastError()
- raise WindowsError(message, err)
-
-class Event:
- def __init__(self, callback, owner, **kw):
- self.callback = callback
- self.owner = owner
- for k, v in kw.items():
- setattr(self, k, v)
-
-cdef class CompletionPort:
- cdef HANDLE port
- def __init__(self):
- cdef HANDLE res
- res = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0)
- if not res:
- raise_error(0, 'CreateIoCompletionPort')
- self.port = res
-
- def addHandle(self, HANDLE handle, size_t key=0):
- cdef HANDLE res
- res = CreateIoCompletionPort(handle, self.port, key, 0)
- if not res:
- raise_error(0, 'CreateIoCompletionPort')
-
- def getEvent(self, long timeout):
- cdef PyThreadState *_save
- cdef unsigned long bytes, rc
- cdef size_t key
- cdef myOVERLAPPED *ov
-
- _save = PyEval_SaveThread()
- rc = GetQueuedCompletionStatus(self.port, &bytes, &key, <OVERLAPPED **>&ov, timeout)
- PyEval_RestoreThread(_save)
-
- if not rc:
- rc = GetLastError()
- else:
- rc = 0
-
- obj = None
- if ov:
- if ov.obj:
- obj = <object>ov.obj
- Py_DECREF(obj) # we are stealing a reference here
- PyMem_Free(ov)
-
- return (rc, bytes, key, obj)
-
- def postEvent(self, unsigned long bytes, size_t key, obj):
- cdef myOVERLAPPED *ov
- cdef unsigned long rc
-
- if obj is not None:
- ov = makeOV()
- Py_INCREF(obj) # give ov its own reference to obj
- ov.obj = <PyObject *>obj
- else:
- ov = NULL
-
- rc = PostQueuedCompletionStatus(self.port, bytes, key, <OVERLAPPED *>ov)
- if not rc:
- if ov:
- Py_DECREF(obj)
- PyMem_Free(ov)
- raise_error(0, 'PostQueuedCompletionStatus')
-
- def __del__(self):
- CloseHandle(self.port)
-
-def makesockaddr(object buff):
- cdef void *mem_buffer
- cdef Py_ssize_t size
-
- PyObject_AsReadBuffer(buff, &mem_buffer, &size)
- # XXX: this should really return the address family as well
- return _makesockaddr(<sockaddr *>mem_buffer, size)
-
-cdef object _makesockaddr(sockaddr *addr, Py_ssize_t len):
- cdef sockaddr_in *sin
- cdef sockaddr_in6 *sin6
- cdef char buff[256]
- cdef int rc
- cdef DWORD buff_size = sizeof(buff)
- if not len:
- return None
- if addr.sa_family == AF_INET:
- sin = <sockaddr_in *>addr
- return PyString_FromString(inet_ntoa(sin.sin_addr)), ntohs(sin.sin_port)
- elif addr.sa_family == AF_INET6:
- sin6 = <sockaddr_in6 *>addr
- rc = WSAAddressToStringA(addr, sizeof(sockaddr_in6), NULL, buff, &buff_size)
- if rc == SOCKET_ERROR:
- raise_error(0, 'WSAAddressToString')
- host, sa_port = PyString_FromString(buff), ntohs(sin6.sin6_port)
- host, port = host.rsplit(':', 1)
- port = int(port)
- assert host[0] == '['
- assert host[-1] == ']'
- assert port == sa_port
- return host[1:-1], port
- else:
- return PyString_FromStringAndSize(addr.sa_data, sizeof(addr.sa_data))
-
-
-cdef object fillinetaddr(sockaddr_in *dest, object addr):
- cdef unsigned short port
- cdef unsigned long res
- cdef char *hoststr
- host, port = addr
-
- hoststr = PyString_AsString(host)
- res = inet_addr(hoststr)
- if res == INADDR_ANY:
- raise ValueError, 'invalid IP address'
- dest.sin_addr.s_addr = res
-
- dest.sin_port = htons(port)
-
-
-cdef object fillinet6addr(sockaddr_in6 *dest, object addr):
- cdef unsigned short port
- cdef unsigned long res
- cdef char *hoststr
- cdef int addrlen = sizeof(sockaddr_in6)
- host, port, flow, scope = addr
- host = host.split("%")[0] # remove scope ID, if any
-
- hoststr = PyString_AsString(host)
- cdef int parseresult = WSAStringToAddressA(hoststr, AF_INET6, NULL,
- <sockaddr *>dest, &addrlen)
- if parseresult == SOCKET_ERROR:
- raise ValueError, 'invalid IPv6 address %r' % (host,)
- if parseresult != 0:
- raise RuntimeError, 'undefined error occurred during address parsing'
- # sin6_host field was handled by WSAStringToAddress
- dest.sin6_port = htons(port)
- dest.sin6_flowinfo = flow
- dest.sin6_scope_id = scope
-
-
-def AllocateReadBuffer(int size):
- return PyBuffer_New(size)
-
-def maxAddrLen(long s):
- cdef WSAPROTOCOL_INFO wsa_pi
- cdef int size, rc
-
- size = sizeof(wsa_pi)
- rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- if rc == SOCKET_ERROR:
- raise_error(WSAGetLastError(), 'getsockopt')
- return wsa_pi.iMaxSockAddr
-
-cdef int getAddrFamily(SOCKET s) except *:
- cdef WSAPROTOCOL_INFO wsa_pi
- cdef int size, rc
-
- size = sizeof(wsa_pi)
- rc = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, <char *>&wsa_pi, &size)
- if rc == SOCKET_ERROR:
- raise_error(WSAGetLastError(), 'getsockopt')
- return wsa_pi.iAddressFamily
-
-import socket # for WSAStartup
-if not initWinsockPointers():
- raise ValueError, 'Failed to initialize Winsock function vectors'
-
-have_connectex = (lpConnectEx != NULL)
-
-include 'acceptex.pxi'
-include 'connectex.pxi'
-include 'wsarecv.pxi'
-include 'wsasend.pxi'
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c
deleted file mode 100644
index 9bd115af..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright (c) 2008 Twisted Matrix Laboratories.
- * See LICENSE for details.
- */
-
-
-#include<winsock2.h>
-#include<assert.h>
-#include<stdio.h>
-#include<stdlib.h>
-
-#ifndef WSAID_CONNECTEX
-#define WSAID_CONNECTEX {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
-#endif
-#ifndef WSAID_GETACCEPTEXSOCKADDRS
-#define WSAID_GETACCEPTEXSOCKADDRS {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
-#endif
-#ifndef WSAID_ACCEPTEX
-#define WSAID_ACCEPTEX {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
-#endif
-/*#ifndef WSAID_TRANSMITFILE
-#define WSAID_TRANSMITFILE {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
-#endif*/
-
-
-void *lpAcceptEx, *lpGetAcceptExSockaddrs, *lpConnectEx, *lpTransmitFile;
-
-int initPointer(SOCKET s, void **fun, GUID guid) {
- int res;
- DWORD bytes;
-
- *fun = NULL;
- res = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
- &guid, sizeof(guid),
- fun, sizeof(fun),
- &bytes, NULL, NULL);
- return !res;
-}
-
-int initWinsockPointers() {
- SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
- /* I hate C */
- GUID guid1 = WSAID_ACCEPTEX;
- GUID guid2 = WSAID_GETACCEPTEXSOCKADDRS;
- GUID guid3 = WSAID_CONNECTEX;
- /*GUID guid4 = WSAID_TRANSMITFILE;*/
- if (!s) {
- return 0;
- }
- if (!initPointer(s, &lpAcceptEx, guid1))
- {
- return 0;
- }
- if (!initPointer(s, &lpGetAcceptExSockaddrs, guid2)) {
- return 0;
- }
- if (!initPointer(s, &lpConnectEx, guid3)) {
- return 0;
- };
- /*initPointer(s, &lpTransmitFile, guid4);*/
- return 1;
-}
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.h b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.h
deleted file mode 100644
index 83e9ba83..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (c) 2008 Twisted Matrix Laboratories.
- * See LICENSE for details.
- */
-
-
-#include<windows.h>
-
-int initWinsockPointers();
-BOOL
-(PASCAL FAR * lpAcceptEx)(
- IN SOCKET sListenSocket,
- IN SOCKET sAcceptSocket,
- IN PVOID lpOutputBuffer,
- IN DWORD dwReceiveDataLength,
- IN DWORD dwLocalAddressLength,
- IN DWORD dwRemoteAddressLength,
- OUT LPDWORD lpdwBytesReceived,
- IN LPOVERLAPPED lpOverlapped
- );
-VOID
-(PASCAL FAR * lpGetAcceptExSockaddrs)(
- IN PVOID lpOutputBuffer,
- IN DWORD dwReceiveDataLength,
- IN DWORD dwLocalAddressLength,
- IN DWORD dwRemoteAddressLength,
- OUT struct sockaddr **LocalSockaddr,
- OUT LPINT LocalSockaddrLength,
- OUT struct sockaddr **RemoteSockaddr,
- OUT LPINT RemoteSockaddrLength
- );
-BOOL
-(PASCAL FAR * lpConnectEx) (
- IN SOCKET s,
- IN const struct sockaddr FAR *name,
- IN int namelen,
- IN PVOID lpSendBuffer OPTIONAL,
- IN DWORD dwSendDataLength,
- OUT LPDWORD lpdwBytesSent,
- IN LPOVERLAPPED lpOverlapped
- );
-/*BOOL
-(PASCAL FAR * lpTransmitFile)(
- IN SOCKET hSocket,
- IN HANDLE hFile,
- IN DWORD nNumberOfBytesToWrite,
- IN DWORD nNumberOfBytesPerSend,
- IN LPOVERLAPPED lpOverlapped,
- IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
- IN DWORD dwReserved
- );*/
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsarecv.pxi b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsarecv.pxi
deleted file mode 100644
index 58c391ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsarecv.pxi
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-def recv(long s, object bufflist, object obj, unsigned long flags = 0):
- cdef int rc, res
- cdef myOVERLAPPED *ov
- cdef WSABUF *ws_buf
- cdef unsigned long bytes
- cdef PyObject **buffers
- cdef Py_ssize_t i, size, buffcount
-
- bufflist = PySequence_Fast(bufflist, 'second argument needs to be a list')
- buffcount = PySequence_Fast_GET_SIZE(bufflist)
- buffers = PySequence_Fast_ITEMS(bufflist)
-
- ws_buf = <WSABUF *>PyMem_Malloc(buffcount*sizeof(WSABUF))
-
- try:
- for i from 0 <= i < buffcount:
- PyObject_AsWriteBuffer(<object>buffers[i], <void **>&ws_buf[i].buf, &size)
- ws_buf[i].len = <DWORD>size
-
- ov = makeOV()
- if obj is not None:
- ov.obj = <PyObject *>obj
-
- rc = WSARecv(s, ws_buf, <DWORD>buffcount, &bytes, &flags, <OVERLAPPED *>ov, NULL)
-
- if rc == SOCKET_ERROR:
- rc = WSAGetLastError()
- if rc != ERROR_IO_PENDING:
- PyMem_Free(ov)
- return rc, 0
-
- Py_XINCREF(obj)
- return rc, bytes
- finally:
- PyMem_Free(ws_buf)
-
-def recvfrom(long s, object buff, object addr_buff, object addr_len_buff, object obj, unsigned long flags = 0):
- cdef int rc, c_addr_buff_len, c_addr_len_buff_len
- cdef myOVERLAPPED *ov
- cdef WSABUF ws_buf
- cdef unsigned long bytes
- cdef sockaddr *c_addr_buff
- cdef int *c_addr_len_buff
- cdef Py_ssize_t size
-
- PyObject_AsWriteBuffer(buff, <void **>&ws_buf.buf, &size)
- ws_buf.len = <DWORD>size
- PyObject_AsWriteBuffer(addr_buff, <void **>&c_addr_buff, &size)
- c_addr_buff_len = <int>size
- PyObject_AsWriteBuffer(addr_len_buff, <void **>&c_addr_len_buff, &size)
- c_addr_len_buff_len = <int>size
-
- if c_addr_len_buff_len != sizeof(int):
- raise ValueError, 'length of address length buffer needs to be sizeof(int)'
-
- c_addr_len_buff[0] = c_addr_buff_len
-
- ov = makeOV()
- if obj is not None:
- ov.obj = <PyObject *>obj
-
- rc = WSARecvFrom(s, &ws_buf, 1, &bytes, &flags, c_addr_buff, c_addr_len_buff, <OVERLAPPED *>ov, NULL)
-
- if rc == SOCKET_ERROR:
- rc = WSAGetLastError()
- if rc != ERROR_IO_PENDING:
- PyMem_Free(ov)
- return rc, 0
-
- Py_XINCREF(obj)
- return rc, bytes
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsasend.pxi b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsasend.pxi
deleted file mode 100644
index 4ad59ca8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/iocpsupport/wsasend.pxi
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-def send(long s, object buff, object obj, unsigned long flags = 0):
- cdef int rc
- cdef myOVERLAPPED *ov
- cdef WSABUF ws_buf
- cdef unsigned long bytes
- cdef Py_ssize_t size
-
- PyObject_AsReadBuffer(buff, <void **>&ws_buf.buf, &size)
- ws_buf.len = <DWORD>size
-
- ov = makeOV()
- if obj is not None:
- ov.obj = <PyObject *>obj
-
- rc = WSASend(s, &ws_buf, 1, &bytes, flags, <OVERLAPPED *>ov, NULL)
-
- if rc == SOCKET_ERROR:
- rc = WSAGetLastError()
- if rc != ERROR_IO_PENDING:
- PyMem_Free(ov)
- return rc, bytes
-
- Py_XINCREF(obj)
- return rc, bytes
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/notes.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/notes.txt
deleted file mode 100644
index 4caffb88..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/notes.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-test specifically:
-failed accept error message -- similar to test_tcp_internals
-immediate success on accept/connect/recv, including Event.ignore
-parametrize iocpsupport somehow -- via reactor?
-
-do:
-break handling -- WaitForSingleObject on the IOCP handle?
-iovecs for write buffer
-do not wait for a mainloop iteration if resumeProducing (in _handleWrite) does startWriting
-don't addActiveHandle in every call to startWriting/startReading
-iocpified process support
- win32er-in-a-thread (or run GQCS in a thread -- it can't receive SIGBREAK)
-blocking in sendto() -- I think Windows can do that, especially with local UDP
-
-buildbot:
-run in vmware
-start from a persistent snapshot
-
-use a stub inside the vm to svnup/run tests/collect stdio
-lift logs through SMB? or ship them via tcp beams to the VM host
-
-have a timeout on the test run
-if we time out, take a screenshot, save it, kill the VM
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/reactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/reactor.py
deleted file mode 100755
index 0c565aba..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/reactor.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_iocp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Reactor that uses IO completion ports
-"""
-
-import warnings, socket, sys
-
-from zope.interface import implements
-
-from twisted.internet import base, interfaces, main, error
-from twisted.python import log, failure
-from twisted.internet._dumbwin32proc import Process
-from twisted.internet.win32eventreactor import _ThreadedWin32EventsMixin
-
-from twisted.internet.iocpreactor import iocpsupport as _iocp
-from twisted.internet.iocpreactor.const import WAIT_TIMEOUT
-from twisted.internet.iocpreactor import tcp, udp
-
-try:
- from twisted.protocols.tls import TLSMemoryBIOFactory
-except ImportError:
- # Either pyOpenSSL isn't installed, or it is too old for this code to work.
- # The reactor won't provide IReactorSSL.
- TLSMemoryBIOFactory = None
- _extraInterfaces = ()
- warnings.warn(
- "pyOpenSSL 0.10 or newer is required for SSL support in iocpreactor. "
- "It is missing, so the reactor will not support SSL APIs.")
-else:
- _extraInterfaces = (interfaces.IReactorSSL,)
-
-from twisted.python.compat import set
-
-MAX_TIMEOUT = 2000 # 2 seconds, see doIteration for explanation
-
-EVENTS_PER_LOOP = 1000 # XXX: what's a good value here?
-
-# keys to associate with normal and waker events
-KEY_NORMAL, KEY_WAKEUP = range(2)
-
-_NO_GETHANDLE = error.ConnectionFdescWentAway(
- 'Handler has no getFileHandle method')
-_NO_FILEDESC = error.ConnectionFdescWentAway('Filedescriptor went away')
-
-
-
-class IOCPReactor(base._SignalReactorMixin, base.ReactorBase,
- _ThreadedWin32EventsMixin):
- implements(interfaces.IReactorTCP, interfaces.IReactorUDP,
- interfaces.IReactorMulticast, interfaces.IReactorProcess,
- *_extraInterfaces)
-
- port = None
-
- def __init__(self):
- base.ReactorBase.__init__(self)
- self.port = _iocp.CompletionPort()
- self.handles = set()
-
-
- def addActiveHandle(self, handle):
- self.handles.add(handle)
-
-
- def removeActiveHandle(self, handle):
- self.handles.discard(handle)
-
-
- def doIteration(self, timeout):
- """
- Poll the IO completion port for new events.
- """
- # This function sits and waits for an IO completion event.
- #
- # There are two requirements: process IO events as soon as they arrive
- # and process ctrl-break from the user in a reasonable amount of time.
- #
- # There are three kinds of waiting.
- # 1) GetQueuedCompletionStatus (self.port.getEvent) to wait for IO
- # events only.
- # 2) Msg* family of wait functions that can stop waiting when
- # ctrl-break is detected (then, I think, Python converts it into a
- # KeyboardInterrupt)
- # 3) *Ex family of wait functions that put the thread into an
- # "alertable" wait state which is supposedly triggered by IO completion
- #
- # 2) and 3) can be combined. Trouble is, my IO completion is not
- # causing 3) to trigger, possibly because I do not use an IO completion
- # callback. Windows is weird.
- # There are two ways to handle this. I could use MsgWaitForSingleObject
- # here and GetQueuedCompletionStatus in a thread. Or I could poll with
- # a reasonable interval. Guess what! Threads are hard.
-
- processed_events = 0
- if timeout is None:
- timeout = MAX_TIMEOUT
- else:
- timeout = min(MAX_TIMEOUT, int(1000*timeout))
- rc, bytes, key, evt = self.port.getEvent(timeout)
- while 1:
- if rc == WAIT_TIMEOUT:
- break
- if key != KEY_WAKEUP:
- assert key == KEY_NORMAL
- log.callWithLogger(evt.owner, self._callEventCallback,
- rc, bytes, evt)
- processed_events += 1
- if processed_events >= EVENTS_PER_LOOP:
- break
- rc, bytes, key, evt = self.port.getEvent(0)
-
-
- def _callEventCallback(self, rc, bytes, evt):
- owner = evt.owner
- why = None
- try:
- evt.callback(rc, bytes, evt)
- handfn = getattr(owner, 'getFileHandle', None)
- if not handfn:
- why = _NO_GETHANDLE
- elif handfn() == -1:
- why = _NO_FILEDESC
- if why:
- return # ignore handles that were closed
- except:
- why = sys.exc_info()[1]
- log.err()
- if why:
- owner.loseConnection(failure.Failure(why))
-
-
- def installWaker(self):
- pass
-
-
- def wakeUp(self):
- self.port.postEvent(0, KEY_WAKEUP, None)
-
-
- def registerHandle(self, handle):
- self.port.addHandle(handle, KEY_NORMAL)
-
-
- def createSocket(self, af, stype):
- skt = socket.socket(af, stype)
- self.registerHandle(skt.fileno())
- return skt
-
-
- def listenTCP(self, port, factory, backlog=50, interface=''):
- """
- @see: twisted.internet.interfaces.IReactorTCP.listenTCP
- """
- p = tcp.Port(port, factory, backlog, interface, self)
- p.startListening()
- return p
-
-
- def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):
- """
- @see: twisted.internet.interfaces.IReactorTCP.connectTCP
- """
- c = tcp.Connector(host, port, factory, timeout, bindAddress, self)
- c.connect()
- return c
-
-
- if TLSMemoryBIOFactory is not None:
- def listenSSL(self, port, factory, contextFactory, backlog=50, interface=''):
- """
- @see: twisted.internet.interfaces.IReactorSSL.listenSSL
- """
- port = self.listenTCP(
- port,
- TLSMemoryBIOFactory(contextFactory, False, factory),
- backlog, interface)
- port._type = 'TLS'
- return port
-
-
- def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None):
- """
- @see: twisted.internet.interfaces.IReactorSSL.connectSSL
- """
- return self.connectTCP(
- host, port,
- TLSMemoryBIOFactory(contextFactory, True, factory),
- timeout, bindAddress)
- else:
- def listenSSL(self, port, factory, contextFactory, backlog=50, interface=''):
- """
- Non-implementation of L{IReactorSSL.listenSSL}. Some dependency
- is not satisfied. This implementation always raises
- L{NotImplementedError}.
- """
- raise NotImplementedError(
- "pyOpenSSL 0.10 or newer is required for SSL support in "
- "iocpreactor. It is missing, so the reactor does not support "
- "SSL APIs.")
-
-
- def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None):
- """
- Non-implementation of L{IReactorSSL.connectSSL}. Some dependency
- is not satisfied. This implementation always raises
- L{NotImplementedError}.
- """
- raise NotImplementedError(
- "pyOpenSSL 0.10 or newer is required for SSL support in "
- "iocpreactor. It is missing, so the reactor does not support "
- "SSL APIs.")
-
-
- def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):
- """
- Connects a given L{DatagramProtocol} to the given numeric UDP port.
-
- @returns: object conforming to L{IListeningPort}.
- """
- p = udp.Port(port, protocol, interface, maxPacketSize, self)
- p.startListening()
- return p
-
-
- def listenMulticast(self, port, protocol, interface='', maxPacketSize=8192,
- listenMultiple=False):
- """
- Connects a given DatagramProtocol to the given numeric UDP port.
-
- EXPERIMENTAL.
-
- @returns: object conforming to IListeningPort.
- """
- p = udp.MulticastPort(port, protocol, interface, maxPacketSize, self,
- listenMultiple)
- p.startListening()
- return p
-
-
- def spawnProcess(self, processProtocol, executable, args=(), env={},
- path=None, uid=None, gid=None, usePTY=0, childFDs=None):
- """
- Spawn a process.
- """
- if uid is not None:
- raise ValueError("Setting UID is unsupported on this platform.")
- if gid is not None:
- raise ValueError("Setting GID is unsupported on this platform.")
- if usePTY:
- raise ValueError("PTYs are unsupported on this platform.")
- if childFDs is not None:
- raise ValueError(
- "Custom child file descriptor mappings are unsupported on "
- "this platform.")
- args, env = self._checkProcessArgs(args, env)
- return Process(self, processProtocol, executable, args, env, path)
-
-
- def removeAll(self):
- res = list(self.handles)
- self.handles.clear()
- return res
-
-
-
-def install():
- r = IOCPReactor()
- main.installReactor(r)
-
-
-__all__ = ['IOCPReactor', 'install']
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/setup.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/setup.py
deleted file mode 100755
index b110fc53..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/setup.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Distutils file for building low-level IOCP bindings from their Pyrex source
-"""
-
-
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Distutils import build_ext
-
-setup(name='iocpsupport',
- ext_modules=[Extension('iocpsupport',
- ['iocpsupport/iocpsupport.pyx',
- 'iocpsupport/winsock_pointers.c'],
- libraries = ['ws2_32'],
- )
- ],
- cmdclass = {'build_ext': build_ext},
- )
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/tcp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/tcp.py
deleted file mode 100755
index d34f698d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/tcp.py
+++ /dev/null
@@ -1,578 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-TCP support for IOCP reactor
-"""
-
-import socket, operator, errno, struct
-
-from zope.interface import implements, classImplements
-
-from twisted.internet import interfaces, error, address, main, defer
-from twisted.internet.abstract import _LogOwner, isIPAddress, isIPv6Address
-from twisted.internet.tcp import _SocketCloser, Connector as TCPConnector
-from twisted.internet.tcp import _AbortingMixin, _BaseBaseClient, _BaseTCPClient
-from twisted.python import log, failure, reflect, util
-
-from twisted.internet.iocpreactor import iocpsupport as _iocp, abstract
-from twisted.internet.iocpreactor.interfaces import IReadWriteHandle
-from twisted.internet.iocpreactor.const import ERROR_IO_PENDING
-from twisted.internet.iocpreactor.const import SO_UPDATE_CONNECT_CONTEXT
-from twisted.internet.iocpreactor.const import SO_UPDATE_ACCEPT_CONTEXT
-from twisted.internet.iocpreactor.const import ERROR_CONNECTION_REFUSED
-from twisted.internet.iocpreactor.const import ERROR_NETWORK_UNREACHABLE
-
-try:
- from twisted.internet._newtls import startTLS as _startTLS
-except ImportError:
- _startTLS = None
-
-# ConnectEx returns these. XXX: find out what it does for timeout
-connectExErrors = {
- ERROR_CONNECTION_REFUSED: errno.WSAECONNREFUSED,
- ERROR_NETWORK_UNREACHABLE: errno.WSAENETUNREACH,
- }
-
-class Connection(abstract.FileHandle, _SocketCloser, _AbortingMixin):
- """
- @ivar TLS: C{False} to indicate the connection is in normal TCP mode,
- C{True} to indicate that TLS has been started and that operations must
- be routed through the L{TLSMemoryBIOProtocol} instance.
- """
- implements(IReadWriteHandle, interfaces.ITCPTransport,
- interfaces.ISystemHandle)
-
- TLS = False
-
-
- def __init__(self, sock, proto, reactor=None):
- abstract.FileHandle.__init__(self, reactor)
- self.socket = sock
- self.getFileHandle = sock.fileno
- self.protocol = proto
-
-
- def getHandle(self):
- return self.socket
-
-
- def dataReceived(self, rbuffer):
- # XXX: some day, we'll have protocols that can handle raw buffers
- self.protocol.dataReceived(str(rbuffer))
-
-
- def readFromHandle(self, bufflist, evt):
- return _iocp.recv(self.getFileHandle(), bufflist, evt)
-
-
- def writeToHandle(self, buff, evt):
- """
- Send C{buff} to current file handle using C{_iocp.send}. The buffer
- sent is limited to a size of C{self.SEND_LIMIT}.
- """
- return _iocp.send(self.getFileHandle(),
- buffer(buff, 0, self.SEND_LIMIT), evt)
-
-
- def _closeWriteConnection(self):
- try:
- getattr(self.socket, self._socketShutdownMethod)(1)
- except socket.error:
- pass
- p = interfaces.IHalfCloseableProtocol(self.protocol, None)
- if p:
- try:
- p.writeConnectionLost()
- except:
- f = failure.Failure()
- log.err()
- self.connectionLost(f)
-
-
- def readConnectionLost(self, reason):
- p = interfaces.IHalfCloseableProtocol(self.protocol, None)
- if p:
- try:
- p.readConnectionLost()
- except:
- log.err()
- self.connectionLost(failure.Failure())
- else:
- self.connectionLost(reason)
-
-
- def connectionLost(self, reason):
- if self.disconnected:
- return
- abstract.FileHandle.connectionLost(self, reason)
- isClean = (reason is None or
- not reason.check(error.ConnectionAborted))
- self._closeSocket(isClean)
- protocol = self.protocol
- del self.protocol
- del self.socket
- del self.getFileHandle
- protocol.connectionLost(reason)
-
-
- def logPrefix(self):
- """
- Return the prefix to log with when I own the logging thread.
- """
- return self.logstr
-
-
- def getTcpNoDelay(self):
- return operator.truth(self.socket.getsockopt(socket.IPPROTO_TCP,
- socket.TCP_NODELAY))
-
-
- def setTcpNoDelay(self, enabled):
- self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, enabled)
-
-
- def getTcpKeepAlive(self):
- return operator.truth(self.socket.getsockopt(socket.SOL_SOCKET,
- socket.SO_KEEPALIVE))
-
-
- def setTcpKeepAlive(self, enabled):
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, enabled)
-
-
- if _startTLS is not None:
- def startTLS(self, contextFactory, normal=True):
- """
- @see: L{ITLSTransport.startTLS}
- """
- _startTLS(self, contextFactory, normal, abstract.FileHandle)
-
-
- def write(self, data):
- """
- Write some data, either directly to the underlying handle or, if TLS
- has been started, to the L{TLSMemoryBIOProtocol} for it to encrypt and
- send.
-
- @see: L{ITCPTransport.write}
- """
- if self.disconnected:
- return
- if self.TLS:
- self.protocol.write(data)
- else:
- abstract.FileHandle.write(self, data)
-
-
- def writeSequence(self, iovec):
- """
- Write some data, either directly to the underlying handle or, if TLS
- has been started, to the L{TLSMemoryBIOProtocol} for it to encrypt and
- send.
-
- @see: L{ITCPTransport.writeSequence}
- """
- if self.disconnected:
- return
- if self.TLS:
- self.protocol.writeSequence(iovec)
- else:
- abstract.FileHandle.writeSequence(self, iovec)
-
-
- def loseConnection(self, reason=None):
- """
- Close the underlying handle or, if TLS has been started, first shut it
- down.
-
- @see: L{ITCPTransport.loseConnection}
- """
- if self.TLS:
- if self.connected and not self.disconnecting:
- self.protocol.loseConnection()
- else:
- abstract.FileHandle.loseConnection(self, reason)
-
-
- def registerProducer(self, producer, streaming):
- """
- Register a producer.
-
- If TLS is enabled, the TLS connection handles this.
- """
- if self.TLS:
- # Registering a producer before we're connected shouldn't be a
- # problem. If we end up with a write(), that's already handled in
- # the write() code above, and there are no other potential
- # side-effects.
- self.protocol.registerProducer(producer, streaming)
- else:
- abstract.FileHandle.registerProducer(self, producer, streaming)
-
-
- def unregisterProducer(self):
- """
- Unregister a producer.
-
- If TLS is enabled, the TLS connection handles this.
- """
- if self.TLS:
- self.protocol.unregisterProducer()
- else:
- abstract.FileHandle.unregisterProducer(self)
-
-if _startTLS is not None:
- classImplements(Connection, interfaces.ITLSTransport)
-
-
-
-class Client(_BaseBaseClient, _BaseTCPClient, Connection):
- """
- @ivar _tlsClientDefault: Always C{True}, indicating that this is a client
- connection, and by default when TLS is negotiated this class will act as
- a TLS client.
- """
- addressFamily = socket.AF_INET
- socketType = socket.SOCK_STREAM
-
- _tlsClientDefault = True
- _commonConnection = Connection
-
- def __init__(self, host, port, bindAddress, connector, reactor):
- # ConnectEx documentation says socket _has_ to be bound
- if bindAddress is None:
- bindAddress = ('', 0)
- self.reactor = reactor # createInternetSocket needs this
- _BaseTCPClient.__init__(self, host, port, bindAddress, connector,
- reactor)
-
-
- def createInternetSocket(self):
- """
- Create a socket registered with the IOCP reactor.
-
- @see: L{_BaseTCPClient}
- """
- return self.reactor.createSocket(self.addressFamily, self.socketType)
-
-
- def _collectSocketDetails(self):
- """
- Clean up potentially circular references to the socket and to its
- C{getFileHandle} method.
-
- @see: L{_BaseBaseClient}
- """
- del self.socket, self.getFileHandle
-
-
- def _stopReadingAndWriting(self):
- """
- Remove the active handle from the reactor.
-
- @see: L{_BaseBaseClient}
- """
- self.reactor.removeActiveHandle(self)
-
-
- def cbConnect(self, rc, bytes, evt):
- if rc:
- rc = connectExErrors.get(rc, rc)
- self.failIfNotConnected(error.getConnectError((rc,
- errno.errorcode.get(rc, 'Unknown error'))))
- else:
- self.socket.setsockopt(
- socket.SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT,
- struct.pack('P', self.socket.fileno()))
- self.protocol = self.connector.buildProtocol(self.getPeer())
- self.connected = True
- logPrefix = self._getLogPrefix(self.protocol)
- self.logstr = logPrefix + ",client"
- self.protocol.makeConnection(self)
- self.startReading()
-
-
- def doConnect(self):
- if not hasattr(self, "connector"):
- # this happens if we connector.stopConnecting in
- # factory.startedConnecting
- return
- assert _iocp.have_connectex
- self.reactor.addActiveHandle(self)
- evt = _iocp.Event(self.cbConnect, self)
-
- rc = _iocp.connect(self.socket.fileno(), self.realAddress, evt)
- if rc and rc != ERROR_IO_PENDING:
- self.cbConnect(rc, 0, evt)
-
-
-
-class Server(Connection):
- """
- Serverside socket-stream connection class.
-
- I am a serverside network connection transport; a socket which came from an
- accept() on a server.
-
- @ivar _tlsClientDefault: Always C{False}, indicating that this is a server
- connection, and by default when TLS is negotiated this class will act as
- a TLS server.
- """
-
- _tlsClientDefault = False
-
-
- def __init__(self, sock, protocol, clientAddr, serverAddr, sessionno, reactor):
- """
- Server(sock, protocol, client, server, sessionno)
-
- Initialize me with a socket, a protocol, a descriptor for my peer (a
- tuple of host, port describing the other end of the connection), an
- instance of Port, and a session number.
- """
- Connection.__init__(self, sock, protocol, reactor)
- self.serverAddr = serverAddr
- self.clientAddr = clientAddr
- self.sessionno = sessionno
- logPrefix = self._getLogPrefix(self.protocol)
- self.logstr = "%s,%s,%s" % (logPrefix, sessionno, self.clientAddr.host)
- self.repstr = "<%s #%s on %s>" % (self.protocol.__class__.__name__,
- self.sessionno, self.serverAddr.port)
- self.connected = True
- self.startReading()
-
-
- def __repr__(self):
- """
- A string representation of this connection.
- """
- return self.repstr
-
-
- def getHost(self):
- """
- Returns an IPv4Address.
-
- This indicates the server's address.
- """
- return self.serverAddr
-
-
- def getPeer(self):
- """
- Returns an IPv4Address.
-
- This indicates the client's address.
- """
- return self.clientAddr
-
-
-
-class Connector(TCPConnector):
- def _makeTransport(self):
- return Client(self.host, self.port, self.bindAddress, self,
- self.reactor)
-
-
-
-class Port(_SocketCloser, _LogOwner):
- implements(interfaces.IListeningPort)
-
- connected = False
- disconnected = False
- disconnecting = False
- addressFamily = socket.AF_INET
- socketType = socket.SOCK_STREAM
- _addressType = address.IPv4Address
- sessionno = 0
-
- # Actual port number being listened on, only set to a non-None
- # value when we are actually listening.
- _realPortNumber = None
-
- # A string describing the connections which will be created by this port.
- # Normally this is C{"TCP"}, since this is a TCP port, but when the TLS
- # implementation re-uses this class it overrides the value with C{"TLS"}.
- # Only used for logging.
- _type = 'TCP'
-
- def __init__(self, port, factory, backlog=50, interface='', reactor=None):
- self.port = port
- self.factory = factory
- self.backlog = backlog
- self.interface = interface
- self.reactor = reactor
- if isIPv6Address(interface):
- self.addressFamily = socket.AF_INET6
- self._addressType = address.IPv6Address
-
-
- def __repr__(self):
- if self._realPortNumber is not None:
- return "<%s of %s on %s>" % (self.__class__,
- self.factory.__class__,
- self._realPortNumber)
- else:
- return "<%s of %s (not listening)>" % (self.__class__,
- self.factory.__class__)
-
-
- def startListening(self):
- try:
- skt = self.reactor.createSocket(self.addressFamily,
- self.socketType)
- # TODO: resolve self.interface if necessary
- if self.addressFamily == socket.AF_INET6:
- addr = socket.getaddrinfo(self.interface, self.port)[0][4]
- else:
- addr = (self.interface, self.port)
- skt.bind(addr)
- except socket.error, le:
- raise error.CannotListenError, (self.interface, self.port, le)
-
- self.addrLen = _iocp.maxAddrLen(skt.fileno())
-
- # Make sure that if we listened on port 0, we update that to
- # reflect what the OS actually assigned us.
- self._realPortNumber = skt.getsockname()[1]
-
- log.msg("%s starting on %s" % (self._getLogPrefix(self.factory),
- self._realPortNumber))
-
- self.factory.doStart()
- skt.listen(self.backlog)
- self.connected = True
- self.disconnected = False
- self.reactor.addActiveHandle(self)
- self.socket = skt
- self.getFileHandle = self.socket.fileno
- self.doAccept()
-
-
- def loseConnection(self, connDone=failure.Failure(main.CONNECTION_DONE)):
- """
- Stop accepting connections on this port.
-
- This will shut down my socket and call self.connectionLost().
- It returns a deferred which will fire successfully when the
- port is actually closed.
- """
- self.disconnecting = True
- if self.connected:
- self.deferred = defer.Deferred()
- self.reactor.callLater(0, self.connectionLost, connDone)
- return self.deferred
-
- stopListening = loseConnection
-
-
- def _logConnectionLostMsg(self):
- """
- Log message for closing port
- """
- log.msg('(%s Port %s Closed)' % (self._type, self._realPortNumber))
-
-
- def connectionLost(self, reason):
- """
- Cleans up the socket.
- """
- self._logConnectionLostMsg()
- self._realPortNumber = None
- d = None
- if hasattr(self, "deferred"):
- d = self.deferred
- del self.deferred
-
- self.disconnected = True
- self.reactor.removeActiveHandle(self)
- self.connected = False
- self._closeSocket(True)
- del self.socket
- del self.getFileHandle
-
- try:
- self.factory.doStop()
- except:
- self.disconnecting = False
- if d is not None:
- d.errback(failure.Failure())
- else:
- raise
- else:
- self.disconnecting = False
- if d is not None:
- d.callback(None)
-
-
- def logPrefix(self):
- """
- Returns the name of my class, to prefix log entries with.
- """
- return reflect.qual(self.factory.__class__)
-
-
- def getHost(self):
- """
- Returns an IPv4Address.
-
- This indicates the server's address.
- """
- host, port = self.socket.getsockname()[:2]
- return self._addressType('TCP', host, port)
-
-
- def cbAccept(self, rc, bytes, evt):
- self.handleAccept(rc, evt)
- if not (self.disconnecting or self.disconnected):
- self.doAccept()
-
-
- def handleAccept(self, rc, evt):
- if self.disconnecting or self.disconnected:
- return False
-
- # possible errors:
- # (WSAEMFILE, WSAENOBUFS, WSAENFILE, WSAENOMEM, WSAECONNABORTED)
- if rc:
- log.msg("Could not accept new connection -- %s (%s)" %
- (errno.errorcode.get(rc, 'unknown error'), rc))
- return False
- else:
- evt.newskt.setsockopt(
- socket.SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
- struct.pack('P', self.socket.fileno()))
- family, lAddr, rAddr = _iocp.get_accept_addrs(evt.newskt.fileno(),
- evt.buff)
- assert family == self.addressFamily
-
- protocol = self.factory.buildProtocol(
- self._addressType('TCP', rAddr[0], rAddr[1]))
- if protocol is None:
- evt.newskt.close()
- else:
- s = self.sessionno
- self.sessionno = s+1
- transport = Server(evt.newskt, protocol,
- self._addressType('TCP', rAddr[0], rAddr[1]),
- self._addressType('TCP', lAddr[0], lAddr[1]),
- s, self.reactor)
- protocol.makeConnection(transport)
- return True
-
-
- def doAccept(self):
- evt = _iocp.Event(self.cbAccept, self)
-
- # see AcceptEx documentation
- evt.buff = buff = _iocp.AllocateReadBuffer(2 * (self.addrLen + 16))
-
- evt.newskt = newskt = self.reactor.createSocket(self.addressFamily,
- self.socketType)
- rc = _iocp.accept(self.socket.fileno(), newskt.fileno(), buff, evt)
-
- if rc and rc != ERROR_IO_PENDING:
- self.handleAccept(rc, evt)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/udp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/udp.py
deleted file mode 100755
index 4dec51f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/iocpreactor/udp.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-UDP support for IOCP reactor
-"""
-
-import socket, operator, struct, warnings, errno
-
-from zope.interface import implements
-
-from twisted.internet import defer, address, error, interfaces
-from twisted.internet.abstract import isIPAddress
-from twisted.python import log, failure
-
-from twisted.internet.iocpreactor.const import ERROR_IO_PENDING
-from twisted.internet.iocpreactor.const import ERROR_CONNECTION_REFUSED
-from twisted.internet.iocpreactor.const import ERROR_PORT_UNREACHABLE
-from twisted.internet.iocpreactor.interfaces import IReadWriteHandle
-from twisted.internet.iocpreactor import iocpsupport as _iocp, abstract
-
-
-
-class Port(abstract.FileHandle):
- """
- UDP port, listening for packets.
- """
- implements(
- IReadWriteHandle, interfaces.IListeningPort, interfaces.IUDPTransport,
- interfaces.ISystemHandle)
-
- addressFamily = socket.AF_INET
- socketType = socket.SOCK_DGRAM
- dynamicReadBuffers = False
-
- # Actual port number being listened on, only set to a non-None
- # value when we are actually listening.
- _realPortNumber = None
-
-
- def __init__(self, port, proto, interface='', maxPacketSize=8192,
- reactor=None):
- """
- Initialize with a numeric port to listen on.
- """
- self.port = port
- self.protocol = proto
- self.readBufferSize = maxPacketSize
- self.interface = interface
- self.setLogStr()
- self._connectedAddr = None
-
- abstract.FileHandle.__init__(self, reactor)
-
- skt = socket.socket(self.addressFamily, self.socketType)
- addrLen = _iocp.maxAddrLen(skt.fileno())
- self.addressBuffer = _iocp.AllocateReadBuffer(addrLen)
- # WSARecvFrom takes an int
- self.addressLengthBuffer = _iocp.AllocateReadBuffer(
- struct.calcsize('i'))
-
-
- def __repr__(self):
- if self._realPortNumber is not None:
- return ("<%s on %s>" %
- (self.protocol.__class__, self._realPortNumber))
- else:
- return "<%s not connected>" % (self.protocol.__class__,)
-
-
- def getHandle(self):
- """
- Return a socket object.
- """
- return self.socket
-
-
- def startListening(self):
- """
- Create and bind my socket, and begin listening on it.
-
- This is called on unserialization, and must be called after creating a
- server to begin listening on the specified port.
- """
- self._bindSocket()
- self._connectToProtocol()
-
-
- def createSocket(self):
- return self.reactor.createSocket(self.addressFamily, self.socketType)
-
-
- def _bindSocket(self):
- try:
- skt = self.createSocket()
- skt.bind((self.interface, self.port))
- except socket.error, le:
- raise error.CannotListenError, (self.interface, self.port, le)
-
- # Make sure that if we listened on port 0, we update that to
- # reflect what the OS actually assigned us.
- self._realPortNumber = skt.getsockname()[1]
-
- log.msg("%s starting on %s" % (
- self._getLogPrefix(self.protocol), self._realPortNumber))
-
- self.connected = True
- self.socket = skt
- self.getFileHandle = self.socket.fileno
-
-
- def _connectToProtocol(self):
- self.protocol.makeConnection(self)
- self.startReading()
- self.reactor.addActiveHandle(self)
-
-
- def cbRead(self, rc, bytes, evt):
- if self.reading:
- self.handleRead(rc, bytes, evt)
- self.doRead()
-
-
- def handleRead(self, rc, bytes, evt):
- if rc in (errno.WSAECONNREFUSED, errno.WSAECONNRESET,
- ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE):
- if self._connectedAddr:
- self.protocol.connectionRefused()
- elif rc:
- log.msg("error in recvfrom -- %s (%s)" %
- (errno.errorcode.get(rc, 'unknown error'), rc))
- else:
- try:
- self.protocol.datagramReceived(str(evt.buff[:bytes]),
- _iocp.makesockaddr(evt.addr_buff))
- except:
- log.err()
-
-
- def doRead(self):
- evt = _iocp.Event(self.cbRead, self)
-
- evt.buff = buff = self._readBuffers[0]
- evt.addr_buff = addr_buff = self.addressBuffer
- evt.addr_len_buff = addr_len_buff = self.addressLengthBuffer
- rc, bytes = _iocp.recvfrom(self.getFileHandle(), buff,
- addr_buff, addr_len_buff, evt)
-
- if rc and rc != ERROR_IO_PENDING:
- self.handleRead(rc, bytes, evt)
-
-
- def write(self, datagram, addr=None):
- """
- Write a datagram.
-
- @param addr: should be a tuple (ip, port), can be None in connected
- mode.
- """
- if self._connectedAddr:
- assert addr in (None, self._connectedAddr)
- try:
- return self.socket.send(datagram)
- except socket.error, se:
- no = se.args[0]
- if no == errno.WSAEINTR:
- return self.write(datagram)
- elif no == errno.WSAEMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif no in (errno.WSAECONNREFUSED, errno.WSAECONNRESET,
- ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE):
- self.protocol.connectionRefused()
- else:
- raise
- else:
- assert addr != None
- if not addr[0].replace(".", "").isdigit():
- warnings.warn("Please only pass IPs to write(), not hostnames",
- DeprecationWarning, stacklevel=2)
- try:
- return self.socket.sendto(datagram, addr)
- except socket.error, se:
- no = se.args[0]
- if no == errno.WSAEINTR:
- return self.write(datagram, addr)
- elif no == errno.WSAEMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif no in (errno.WSAECONNREFUSED, errno.WSAECONNRESET,
- ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE):
- # in non-connected UDP ECONNREFUSED is platform dependent,
- # I think and the info is not necessarily useful.
- # Nevertheless maybe we should call connectionRefused? XXX
- return
- else:
- raise
-
-
- def writeSequence(self, seq, addr):
- self.write("".join(seq), addr)
-
-
- def connect(self, host, port):
- """
- 'Connect' to remote server.
- """
- if self._connectedAddr:
- raise RuntimeError(
- "already connected, reconnecting is not currently supported "
- "(talk to itamar if you want this)")
- if not isIPAddress(host):
- raise ValueError, "please pass only IP addresses, not domain names"
- self._connectedAddr = (host, port)
- self.socket.connect((host, port))
-
-
- def _loseConnection(self):
- self.stopReading()
- self.reactor.removeActiveHandle(self)
- if self.connected: # actually means if we are *listening*
- self.reactor.callLater(0, self.connectionLost)
-
-
- def stopListening(self):
- if self.connected:
- result = self.d = defer.Deferred()
- else:
- result = None
- self._loseConnection()
- return result
-
-
- def loseConnection(self):
- warnings.warn("Please use stopListening() to disconnect port",
- DeprecationWarning, stacklevel=2)
- self.stopListening()
-
-
- def connectionLost(self, reason=None):
- """
- Cleans up my socket.
- """
- log.msg('(UDP Port %s Closed)' % self._realPortNumber)
- self._realPortNumber = None
- abstract.FileHandle.connectionLost(self, reason)
- self.protocol.doStop()
- self.socket.close()
- del self.socket
- del self.getFileHandle
- if hasattr(self, "d"):
- self.d.callback(None)
- del self.d
-
-
- def setLogStr(self):
- """
- Initialize the C{logstr} attribute to be used by C{logPrefix}.
- """
- logPrefix = self._getLogPrefix(self.protocol)
- self.logstr = "%s (UDP)" % logPrefix
-
-
- def logPrefix(self):
- """
- Returns the name of my class, to prefix log entries with.
- """
- return self.logstr
-
-
- def getHost(self):
- """
- Returns an IPv4Address.
-
- This indicates the address from which I am connecting.
- """
- return address.IPv4Address('UDP', *self.socket.getsockname())
-
-
-
-class MulticastMixin:
- """
- Implement multicast functionality.
- """
-
-
- def getOutgoingInterface(self):
- i = self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF)
- return socket.inet_ntoa(struct.pack("@i", i))
-
-
- def setOutgoingInterface(self, addr):
- """
- Returns Deferred of success.
- """
- return self.reactor.resolve(addr).addCallback(self._setInterface)
-
-
- def _setInterface(self, addr):
- i = socket.inet_aton(addr)
- self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, i)
- return 1
-
-
- def getLoopbackMode(self):
- return self.socket.getsockopt(socket.IPPROTO_IP,
- socket.IP_MULTICAST_LOOP)
-
-
- def setLoopbackMode(self, mode):
- mode = struct.pack("b", operator.truth(mode))
- self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP,
- mode)
-
-
- def getTTL(self):
- return self.socket.getsockopt(socket.IPPROTO_IP,
- socket.IP_MULTICAST_TTL)
-
-
- def setTTL(self, ttl):
- ttl = struct.pack("B", ttl)
- self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
-
-
- def joinGroup(self, addr, interface=""):
- """
- Join a multicast group. Returns Deferred of success.
- """
- return self.reactor.resolve(addr).addCallback(self._joinAddr1,
- interface, 1)
-
-
- def _joinAddr1(self, addr, interface, join):
- return self.reactor.resolve(interface).addCallback(self._joinAddr2,
- addr, join)
-
-
- def _joinAddr2(self, interface, addr, join):
- addr = socket.inet_aton(addr)
- interface = socket.inet_aton(interface)
- if join:
- cmd = socket.IP_ADD_MEMBERSHIP
- else:
- cmd = socket.IP_DROP_MEMBERSHIP
- try:
- self.socket.setsockopt(socket.IPPROTO_IP, cmd, addr + interface)
- except socket.error, e:
- return failure.Failure(error.MulticastJoinError(addr, interface,
- *e.args))
-
-
- def leaveGroup(self, addr, interface=""):
- """
- Leave multicast group, return Deferred of success.
- """
- return self.reactor.resolve(addr).addCallback(self._joinAddr1,
- interface, 0)
-
-
-
-class MulticastPort(MulticastMixin, Port):
- """
- UDP Port that supports multicasting.
- """
-
- implements(interfaces.IMulticastTransport)
-
-
- def __init__(self, port, proto, interface='', maxPacketSize=8192,
- reactor=None, listenMultiple=False):
- Port.__init__(self, port, proto, interface, maxPacketSize, reactor)
- self.listenMultiple = listenMultiple
-
-
- def createSocket(self):
- skt = Port.createSocket(self)
- if self.listenMultiple:
- skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- if hasattr(socket, "SO_REUSEPORT"):
- skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
- return skt
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/kqreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/kqreactor.py
deleted file mode 100755
index bb1b6a3e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/kqreactor.py
+++ /dev/null
@@ -1,305 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A kqueue()/kevent() based implementation of the Twisted main loop.
-
-To use this reactor, start your application specifying the kqueue reactor::
-
- twistd --reactor kqueue ...
-
-To install the event loop from code (and you should do this before any
-connections, listeners or connectors are added)::
-
- from twisted.internet import kqreactor
- kqreactor.install()
-
-This implementation depends on Python 2.6 or higher which has kqueue support
-built in the select module.
-
-Note, that you should use Python 2.6.5 or higher, since previous implementations
-of select.kqueue had U{http://bugs.python.org/issue5910} not yet fixed.
-"""
-
-import errno
-
-from zope.interface import implements
-
-from select import kqueue, kevent
-from select import KQ_FILTER_READ, KQ_FILTER_WRITE
-from select import KQ_EV_DELETE, KQ_EV_ADD, KQ_EV_EOF
-
-from twisted.internet.interfaces import IReactorFDSet, IReactorDaemonize
-
-from twisted.python import log, failure
-from twisted.internet import main, posixbase
-
-
-class KQueueReactor(posixbase.PosixReactorBase):
- """
- A reactor that uses kqueue(2)/kevent(2) and relies on Python 2.6 or higher
- which has built in support for kqueue in the select module.
-
- @ivar _kq: A L{kqueue} which will be used to check for I/O readiness.
-
- @ivar _selectables: A dictionary mapping integer file descriptors to
- instances of L{FileDescriptor} which have been registered with the
- reactor. All L{FileDescriptors} which are currently receiving read or
- write readiness notifications will be present as values in this
- dictionary.
-
- @ivar _reads: A dictionary mapping integer file descriptors to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- registered with C{_kq} for read readiness notifications which will be
- dispatched to the corresponding L{FileDescriptor} instances in
- C{_selectables}.
-
- @ivar _writes: A dictionary mapping integer file descriptors to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- registered with C{_kq} for write readiness notifications which will be
- dispatched to the corresponding L{FileDescriptor} instances in
- C{_selectables}.
- """
- implements(IReactorFDSet, IReactorDaemonize)
-
-
- def __init__(self):
- """
- Initialize kqueue object, file descriptor tracking dictionaries, and the
- base class.
-
- See:
- - http://docs.python.org/library/select.html
- - www.freebsd.org/cgi/man.cgi?query=kqueue
- - people.freebsd.org/~jlemon/papers/kqueue.pdf
- """
- self._kq = kqueue()
- self._reads = {}
- self._writes = {}
- self._selectables = {}
- posixbase.PosixReactorBase.__init__(self)
-
-
- def _updateRegistration(self, fd, filter, op):
- """
- Private method for changing kqueue registration on a given FD
- filtering for events given filter/op. This will never block and
- returns nothing.
- """
- self._kq.control([kevent(fd, filter, op)], 0, 0)
-
-
- def beforeDaemonize(self):
- """
- Implement L{IReactorDaemonize.beforeDaemonize}.
- """
- # Twisted-internal method called during daemonization (when application
- # is started via twistd). This is called right before the magic double
- # forking done for daemonization. We cleanly close the kqueue() and later
- # recreate it. This is needed since a) kqueue() are not inherited across
- # forks and b) twistd will create the reactor already before daemonization
- # (and will also add at least 1 reader to the reactor, an instance of
- # twisted.internet.posixbase._UnixWaker).
- #
- # See: twisted.scripts._twistd_unix.daemonize()
- self._kq.close()
- self._kq = None
-
-
- def afterDaemonize(self):
- """
- Implement L{IReactorDaemonize.afterDaemonize}.
- """
- # Twisted-internal method called during daemonization. This is called right
- # after daemonization and recreates the kqueue() and any readers/writers
- # that were added before. Note that you MUST NOT call any reactor methods
- # in between beforeDaemonize() and afterDaemonize()!
- self._kq = kqueue()
- for fd in self._reads:
- self._updateRegistration(fd, KQ_FILTER_READ, KQ_EV_ADD)
- for fd in self._writes:
- self._updateRegistration(fd, KQ_FILTER_WRITE, KQ_EV_ADD)
-
-
- def addReader(self, reader):
- """
- Implement L{IReactorFDSet.addReader}.
- """
- fd = reader.fileno()
- if fd not in self._reads:
- try:
- self._updateRegistration(fd, KQ_FILTER_READ, KQ_EV_ADD)
- except OSError:
- pass
- finally:
- self._selectables[fd] = reader
- self._reads[fd] = 1
-
-
- def addWriter(self, writer):
- """
- Implement L{IReactorFDSet.addWriter}.
- """
- fd = writer.fileno()
- if fd not in self._writes:
- try:
- self._updateRegistration(fd, KQ_FILTER_WRITE, KQ_EV_ADD)
- except OSError:
- pass
- finally:
- self._selectables[fd] = writer
- self._writes[fd] = 1
-
-
- def removeReader(self, reader):
- """
- Implement L{IReactorFDSet.removeReader}.
- """
- wasLost = False
- try:
- fd = reader.fileno()
- except:
- fd = -1
- if fd == -1:
- for fd, fdes in self._selectables.items():
- if reader is fdes:
- wasLost = True
- break
- else:
- return
- if fd in self._reads:
- del self._reads[fd]
- if fd not in self._writes:
- del self._selectables[fd]
- if not wasLost:
- try:
- self._updateRegistration(fd, KQ_FILTER_READ, KQ_EV_DELETE)
- except OSError:
- pass
-
-
- def removeWriter(self, writer):
- """
- Implement L{IReactorFDSet.removeWriter}.
- """
- wasLost = False
- try:
- fd = writer.fileno()
- except:
- fd = -1
- if fd == -1:
- for fd, fdes in self._selectables.items():
- if writer is fdes:
- wasLost = True
- break
- else:
- return
- if fd in self._writes:
- del self._writes[fd]
- if fd not in self._reads:
- del self._selectables[fd]
- if not wasLost:
- try:
- self._updateRegistration(fd, KQ_FILTER_WRITE, KQ_EV_DELETE)
- except OSError:
- pass
-
-
- def removeAll(self):
- """
- Implement L{IReactorFDSet.removeAll}.
- """
- return self._removeAll(
- [self._selectables[fd] for fd in self._reads],
- [self._selectables[fd] for fd in self._writes])
-
-
- def getReaders(self):
- """
- Implement L{IReactorFDSet.getReaders}.
- """
- return [self._selectables[fd] for fd in self._reads]
-
-
- def getWriters(self):
- """
- Implement L{IReactorFDSet.getWriters}.
- """
- return [self._selectables[fd] for fd in self._writes]
-
-
- def doKEvent(self, timeout):
- """
- Poll the kqueue for new events.
- """
- if timeout is None:
- timeout = 1
-
- try:
- l = self._kq.control([], len(self._selectables), timeout)
- except OSError, e:
- if e[0] == errno.EINTR:
- return
- else:
- raise
-
- _drdw = self._doWriteOrRead
- for event in l:
- fd = event.ident
- try:
- selectable = self._selectables[fd]
- except KeyError:
- # Handles the infrequent case where one selectable's
- # handler disconnects another.
- continue
- else:
- log.callWithLogger(selectable, _drdw, selectable, fd, event)
-
-
- def _doWriteOrRead(self, selectable, fd, event):
- """
- Private method called when a FD is ready for reading, writing or was
- lost. Do the work and raise errors where necessary.
- """
- why = None
- inRead = False
- (filter, flags, data, fflags) = (
- event.filter, event.flags, event.data, event.fflags)
-
- if flags & KQ_EV_EOF and data and fflags:
- why = main.CONNECTION_LOST
- else:
- try:
- if selectable.fileno() == -1:
- inRead = False
- why = posixbase._NO_FILEDESC
- else:
- if filter == KQ_FILTER_READ:
- inRead = True
- why = selectable.doRead()
- if filter == KQ_FILTER_WRITE:
- inRead = False
- why = selectable.doWrite()
- except:
- # Any exception from application code gets logged and will
- # cause us to disconnect the selectable.
- why = failure.Failure()
- log.err(why, "An exception was raised from application code" \
- " while processing a reactor selectable")
-
- if why:
- self._disconnectSelectable(selectable, why, inRead)
-
- doIteration = doKEvent
-
-
-def install():
- """
- Install the kqueue() reactor.
- """
- p = KQueueReactor()
- from twisted.internet.main import installReactor
- installReactor(p)
-
-
-__all__ = ["KQueueReactor", "install"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/main.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/main.py
deleted file mode 100755
index 0c6c2ff4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/main.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_main -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Backwards compatibility, and utility functions.
-
-In general, this module should not be used, other than by reactor authors
-who need to use the 'installReactor' method.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-import error
-
-CONNECTION_DONE = error.ConnectionDone('Connection done')
-CONNECTION_LOST = error.ConnectionLost('Connection lost')
-
-def installReactor(reactor):
- """
- Install reactor C{reactor}.
-
- @param reactor: An object that provides one or more IReactor* interfaces.
- """
- # this stuff should be common to all reactors.
- import twisted.internet
- import sys
- if 'twisted.internet.reactor' in sys.modules:
- raise error.ReactorAlreadyInstalledError("reactor already installed")
- twisted.internet.reactor = reactor
- sys.modules['twisted.internet.reactor'] = reactor
-
-
-__all__ = ["CONNECTION_LOST", "CONNECTION_DONE", "installReactor"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pollreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pollreactor.py
deleted file mode 100755
index 57691676..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pollreactor.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A poll() based implementation of the twisted main loop.
-
-To install the event loop (and you should do this before any connections,
-listeners or connectors are added)::
-
- from twisted.internet import pollreactor
- pollreactor.install()
-"""
-
-# System imports
-import errno
-from select import error as SelectError, poll
-from select import POLLIN, POLLOUT, POLLHUP, POLLERR, POLLNVAL
-
-from zope.interface import implements
-
-# Twisted imports
-from twisted.python import log
-from twisted.internet import posixbase
-from twisted.internet.interfaces import IReactorFDSet
-
-
-
-class PollReactor(posixbase.PosixReactorBase, posixbase._PollLikeMixin):
- """
- A reactor that uses poll(2).
-
- @ivar _poller: A L{poll} which will be used to check for I/O
- readiness.
-
- @ivar _selectables: A dictionary mapping integer file descriptors to
- instances of L{FileDescriptor} which have been registered with the
- reactor. All L{FileDescriptors} which are currently receiving read or
- write readiness notifications will be present as values in this
- dictionary.
-
- @ivar _reads: A dictionary mapping integer file descriptors to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- registered with C{_poller} for read readiness notifications which will
- be dispatched to the corresponding L{FileDescriptor} instances in
- C{_selectables}.
-
- @ivar _writes: A dictionary mapping integer file descriptors to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- registered with C{_poller} for write readiness notifications which will
- be dispatched to the corresponding L{FileDescriptor} instances in
- C{_selectables}.
- """
- implements(IReactorFDSet)
-
- _POLL_DISCONNECTED = (POLLHUP | POLLERR | POLLNVAL)
- _POLL_IN = POLLIN
- _POLL_OUT = POLLOUT
-
- def __init__(self):
- """
- Initialize polling object, file descriptor tracking dictionaries, and
- the base class.
- """
- self._poller = poll()
- self._selectables = {}
- self._reads = {}
- self._writes = {}
- posixbase.PosixReactorBase.__init__(self)
-
-
- def _updateRegistration(self, fd):
- """Register/unregister an fd with the poller."""
- try:
- self._poller.unregister(fd)
- except KeyError:
- pass
-
- mask = 0
- if fd in self._reads:
- mask = mask | POLLIN
- if fd in self._writes:
- mask = mask | POLLOUT
- if mask != 0:
- self._poller.register(fd, mask)
- else:
- if fd in self._selectables:
- del self._selectables[fd]
-
- def _dictRemove(self, selectable, mdict):
- try:
- # the easy way
- fd = selectable.fileno()
- # make sure the fd is actually real. In some situations we can get
- # -1 here.
- mdict[fd]
- except:
- # the hard way: necessary because fileno() may disappear at any
- # moment, thanks to python's underlying sockets impl
- for fd, fdes in self._selectables.items():
- if selectable is fdes:
- break
- else:
- # Hmm, maybe not the right course of action? This method can't
- # fail, because it happens inside error detection...
- return
- if fd in mdict:
- del mdict[fd]
- self._updateRegistration(fd)
-
- def addReader(self, reader):
- """Add a FileDescriptor for notification of data available to read.
- """
- fd = reader.fileno()
- if fd not in self._reads:
- self._selectables[fd] = reader
- self._reads[fd] = 1
- self._updateRegistration(fd)
-
- def addWriter(self, writer):
- """Add a FileDescriptor for notification of data available to write.
- """
- fd = writer.fileno()
- if fd not in self._writes:
- self._selectables[fd] = writer
- self._writes[fd] = 1
- self._updateRegistration(fd)
-
- def removeReader(self, reader):
- """Remove a Selectable for notification of data available to read.
- """
- return self._dictRemove(reader, self._reads)
-
- def removeWriter(self, writer):
- """Remove a Selectable for notification of data available to write.
- """
- return self._dictRemove(writer, self._writes)
-
- def removeAll(self):
- """
- Remove all selectables, and return a list of them.
- """
- return self._removeAll(
- [self._selectables[fd] for fd in self._reads],
- [self._selectables[fd] for fd in self._writes])
-
-
- def doPoll(self, timeout):
- """Poll the poller for new events."""
- if timeout is not None:
- timeout = int(timeout * 1000) # convert seconds to milliseconds
-
- try:
- l = self._poller.poll(timeout)
- except SelectError, e:
- if e.args[0] == errno.EINTR:
- return
- else:
- raise
- _drdw = self._doReadOrWrite
- for fd, event in l:
- try:
- selectable = self._selectables[fd]
- except KeyError:
- # Handles the infrequent case where one selectable's
- # handler disconnects another.
- continue
- log.callWithLogger(selectable, _drdw, selectable, fd, event)
-
- doIteration = doPoll
-
- def getReaders(self):
- return [self._selectables[fd] for fd in self._reads]
-
-
- def getWriters(self):
- return [self._selectables[fd] for fd in self._writes]
-
-
-
-def install():
- """Install the poll() reactor."""
- p = PollReactor()
- from twisted.internet.main import installReactor
- installReactor(p)
-
-
-__all__ = ["PollReactor", "install"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py
deleted file mode 100755
index bc6590ce..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py
+++ /dev/null
@@ -1,652 +0,0 @@
-# -*- test-case-name: twisted.test.test_internet,twisted.internet.test.test_posixbase -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Posix reactor base class
-"""
-
-import warnings
-import socket
-import errno
-import os
-import sys
-
-from zope.interface import implements, classImplements
-
-from twisted.python.compat import set
-from twisted.internet.interfaces import IReactorUNIX, IReactorUNIXDatagram
-from twisted.internet.interfaces import (
- IReactorTCP, IReactorUDP, IReactorSSL, _IReactorArbitrary, IReactorSocket)
-from twisted.internet.interfaces import IReactorProcess, IReactorMulticast
-from twisted.internet.interfaces import IHalfCloseableDescriptor
-from twisted.internet import error
-from twisted.internet import tcp, udp
-
-from twisted.python import log, failure, util
-from twisted.persisted import styles
-from twisted.python.runtime import platformType, platform
-
-from twisted.internet.base import ReactorBase, _SignalReactorMixin
-from twisted.internet.main import CONNECTION_DONE, CONNECTION_LOST
-
-# Exceptions that doSelect might return frequently
-_NO_FILENO = error.ConnectionFdescWentAway('Handler has no fileno method')
-_NO_FILEDESC = error.ConnectionFdescWentAway('File descriptor lost')
-
-
-try:
- from twisted.protocols import tls
-except ImportError:
- tls = None
- try:
- from twisted.internet import ssl
- except ImportError:
- ssl = None
-
-try:
- from twisted.internet import unix
- unixEnabled = True
-except ImportError:
- unixEnabled = False
-
-processEnabled = False
-if platformType == 'posix':
- from twisted.internet import fdesc, process, _signals
- processEnabled = True
-
-if platform.isWindows():
- try:
- import win32process
- processEnabled = True
- except ImportError:
- win32process = None
-
-
-class _SocketWaker(log.Logger, styles.Ephemeral):
- """
- The I{self-pipe trick<http://cr.yp.to/docs/selfpipe.html>}, implemented
- using a pair of sockets rather than pipes (due to the lack of support in
- select() on Windows for pipes), used to wake up the main loop from
- another thread.
- """
- disconnected = 0
-
- def __init__(self, reactor):
- """Initialize.
- """
- self.reactor = reactor
- # Following select_trigger (from asyncore)'s example;
- server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- client.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
- server.bind(('127.0.0.1', 0))
- server.listen(1)
- client.connect(server.getsockname())
- reader, clientaddr = server.accept()
- client.setblocking(0)
- reader.setblocking(0)
- self.r = reader
- self.w = client
- self.fileno = self.r.fileno
-
- def wakeUp(self):
- """Send a byte to my connection.
- """
- try:
- util.untilConcludes(self.w.send, 'x')
- except socket.error, (err, msg):
- if err != errno.WSAEWOULDBLOCK:
- raise
-
- def doRead(self):
- """Read some data from my connection.
- """
- try:
- self.r.recv(8192)
- except socket.error:
- pass
-
- def connectionLost(self, reason):
- self.r.close()
- self.w.close()
-
-
-
-class _FDWaker(object, log.Logger, styles.Ephemeral):
- """
- The I{self-pipe trick<http://cr.yp.to/docs/selfpipe.html>}, used to wake
- up the main loop from another thread or a signal handler.
-
- L{_FDWaker} is a base class for waker implementations based on
- writing to a pipe being monitored by the reactor.
-
- @ivar o: The file descriptor for the end of the pipe which can be
- written to to wake up a reactor monitoring this waker.
-
- @ivar i: The file descriptor which should be monitored in order to
- be awoken by this waker.
- """
- disconnected = 0
-
- i = None
- o = None
-
- def __init__(self, reactor):
- """Initialize.
- """
- self.reactor = reactor
- self.i, self.o = os.pipe()
- fdesc.setNonBlocking(self.i)
- fdesc._setCloseOnExec(self.i)
- fdesc.setNonBlocking(self.o)
- fdesc._setCloseOnExec(self.o)
- self.fileno = lambda: self.i
-
-
- def doRead(self):
- """
- Read some bytes from the pipe and discard them.
- """
- fdesc.readFromFD(self.fileno(), lambda data: None)
-
-
- def connectionLost(self, reason):
- """Close both ends of my pipe.
- """
- if not hasattr(self, "o"):
- return
- for fd in self.i, self.o:
- try:
- os.close(fd)
- except IOError:
- pass
- del self.i, self.o
-
-
-
-class _UnixWaker(_FDWaker):
- """
- This class provides a simple interface to wake up the event loop.
-
- This is used by threads or signals to wake up the event loop.
- """
-
- def wakeUp(self):
- """Write one byte to the pipe, and flush it.
- """
- # We don't use fdesc.writeToFD since we need to distinguish
- # between EINTR (try again) and EAGAIN (do nothing).
- if self.o is not None:
- try:
- util.untilConcludes(os.write, self.o, 'x')
- except OSError, e:
- # XXX There is no unit test for raising the exception
- # for other errnos. See #4285.
- if e.errno != errno.EAGAIN:
- raise
-
-
-
-if platformType == 'posix':
- _Waker = _UnixWaker
-else:
- # Primarily Windows and Jython.
- _Waker = _SocketWaker
-
-
-class _SIGCHLDWaker(_FDWaker):
- """
- L{_SIGCHLDWaker} can wake up a reactor whenever C{SIGCHLD} is
- received.
-
- @see: L{twisted.internet._signals}
- """
- def __init__(self, reactor):
- _FDWaker.__init__(self, reactor)
-
-
- def install(self):
- """
- Install the handler necessary to make this waker active.
- """
- _signals.installHandler(self.o)
-
-
- def uninstall(self):
- """
- Remove the handler which makes this waker active.
- """
- _signals.installHandler(-1)
-
-
- def doRead(self):
- """
- Having woken up the reactor in response to receipt of
- C{SIGCHLD}, reap the process which exited.
-
- This is called whenever the reactor notices the waker pipe is
- writeable, which happens soon after any call to the C{wakeUp}
- method.
- """
- _FDWaker.doRead(self)
- process.reapAllProcesses()
-
-
-
-
-class _DisconnectSelectableMixin(object):
- """
- Mixin providing the C{_disconnectSelectable} method.
- """
-
- def _disconnectSelectable(self, selectable, why, isRead, faildict={
- error.ConnectionDone: failure.Failure(error.ConnectionDone()),
- error.ConnectionLost: failure.Failure(error.ConnectionLost())
- }):
- """
- Utility function for disconnecting a selectable.
-
- Supports half-close notification, isRead should be boolean indicating
- whether error resulted from doRead().
- """
- self.removeReader(selectable)
- f = faildict.get(why.__class__)
- if f:
- if (isRead and why.__class__ == error.ConnectionDone
- and IHalfCloseableDescriptor.providedBy(selectable)):
- selectable.readConnectionLost(f)
- else:
- self.removeWriter(selectable)
- selectable.connectionLost(f)
- else:
- self.removeWriter(selectable)
- selectable.connectionLost(failure.Failure(why))
-
-
-
-class PosixReactorBase(_SignalReactorMixin, _DisconnectSelectableMixin,
- ReactorBase):
- """
- A basis for reactors that use file descriptors.
-
- @ivar _childWaker: C{None} or a reference to the L{_SIGCHLDWaker}
- which is used to properly notice child process termination.
- """
- implements(_IReactorArbitrary, IReactorTCP, IReactorUDP, IReactorMulticast)
-
- # Callable that creates a waker, overrideable so that subclasses can
- # substitute their own implementation:
- _wakerFactory = _Waker
-
- def installWaker(self):
- """
- Install a `waker' to allow threads and signals to wake up the IO thread.
-
- We use the self-pipe trick (http://cr.yp.to/docs/selfpipe.html) to wake
- the reactor. On Windows we use a pair of sockets.
- """
- if not self.waker:
- self.waker = self._wakerFactory(self)
- self._internalReaders.add(self.waker)
- self.addReader(self.waker)
-
-
- _childWaker = None
- def _handleSignals(self):
- """
- Extend the basic signal handling logic to also support
- handling SIGCHLD to know when to try to reap child processes.
- """
- _SignalReactorMixin._handleSignals(self)
- if platformType == 'posix':
- if not self._childWaker:
- self._childWaker = _SIGCHLDWaker(self)
- self._internalReaders.add(self._childWaker)
- self.addReader(self._childWaker)
- self._childWaker.install()
- # Also reap all processes right now, in case we missed any
- # signals before we installed the SIGCHLD waker/handler.
- # This should only happen if someone used spawnProcess
- # before calling reactor.run (and the process also exited
- # already).
- process.reapAllProcesses()
-
- def _uninstallHandler(self):
- """
- If a child waker was created and installed, uninstall it now.
-
- Since this disables reactor functionality and is only called
- when the reactor is stopping, it doesn't provide any directly
- useful functionality, but the cleanup of reactor-related
- process-global state that it does helps in unit tests
- involving multiple reactors and is generally just a nice
- thing.
- """
- # XXX This would probably be an alright place to put all of
- # the cleanup code for all internal readers (here and in the
- # base class, anyway). See #3063 for that cleanup task.
- if self._childWaker:
- self._childWaker.uninstall()
-
- # IReactorProcess
-
- def spawnProcess(self, processProtocol, executable, args=(),
- env={}, path=None,
- uid=None, gid=None, usePTY=0, childFDs=None):
- args, env = self._checkProcessArgs(args, env)
- if platformType == 'posix':
- if usePTY:
- if childFDs is not None:
- raise ValueError("Using childFDs is not supported with usePTY=True.")
- return process.PTYProcess(self, executable, args, env, path,
- processProtocol, uid, gid, usePTY)
- else:
- return process.Process(self, executable, args, env, path,
- processProtocol, uid, gid, childFDs)
- elif platformType == "win32":
- if uid is not None:
- raise ValueError("Setting UID is unsupported on this platform.")
- if gid is not None:
- raise ValueError("Setting GID is unsupported on this platform.")
- if usePTY:
- raise ValueError("The usePTY parameter is not supported on Windows.")
- if childFDs:
- raise ValueError("Customizing childFDs is not supported on Windows.")
-
- if win32process:
- from twisted.internet._dumbwin32proc import Process
- return Process(self, processProtocol, executable, args, env, path)
- else:
- raise NotImplementedError, "spawnProcess not available since pywin32 is not installed."
- else:
- raise NotImplementedError, "spawnProcess only available on Windows or POSIX."
-
- # IReactorUDP
-
- def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):
- """Connects a given L{DatagramProtocol} to the given numeric UDP port.
-
- @returns: object conforming to L{IListeningPort}.
- """
- p = udp.Port(port, protocol, interface, maxPacketSize, self)
- p.startListening()
- return p
-
- # IReactorMulticast
-
- def listenMulticast(self, port, protocol, interface='', maxPacketSize=8192, listenMultiple=False):
- """Connects a given DatagramProtocol to the given numeric UDP port.
-
- EXPERIMENTAL.
-
- @returns: object conforming to IListeningPort.
- """
- p = udp.MulticastPort(port, protocol, interface, maxPacketSize, self, listenMultiple)
- p.startListening()
- return p
-
-
- # IReactorUNIX
-
- def connectUNIX(self, address, factory, timeout=30, checkPID=0):
- """@see: twisted.internet.interfaces.IReactorUNIX.connectUNIX
- """
- assert unixEnabled, "UNIX support is not present"
- c = unix.Connector(address, factory, timeout, self, checkPID)
- c.connect()
- return c
-
- def listenUNIX(self, address, factory, backlog=50, mode=0666, wantPID=0):
- """
- @see: twisted.internet.interfaces.IReactorUNIX.listenUNIX
- """
- assert unixEnabled, "UNIX support is not present"
- p = unix.Port(address, factory, backlog, mode, self, wantPID)
- p.startListening()
- return p
-
-
- # IReactorUNIXDatagram
-
- def listenUNIXDatagram(self, address, protocol, maxPacketSize=8192,
- mode=0666):
- """
- Connects a given L{DatagramProtocol} to the given path.
-
- EXPERIMENTAL.
-
- @returns: object conforming to L{IListeningPort}.
- """
- assert unixEnabled, "UNIX support is not present"
- p = unix.DatagramPort(address, protocol, maxPacketSize, mode, self)
- p.startListening()
- return p
-
- def connectUNIXDatagram(self, address, protocol, maxPacketSize=8192,
- mode=0666, bindAddress=None):
- """
- Connects a L{ConnectedDatagramProtocol} instance to a path.
-
- EXPERIMENTAL.
- """
- assert unixEnabled, "UNIX support is not present"
- p = unix.ConnectedDatagramPort(address, protocol, maxPacketSize, mode, bindAddress, self)
- p.startListening()
- return p
-
-
- # IReactorSocket (but not on Windows)
-
- def adoptStreamPort(self, fileDescriptor, addressFamily, factory):
- """
- Create a new L{IListeningPort} from an already-initialized socket.
-
- This just dispatches to a suitable port implementation (eg from
- L{IReactorTCP}, etc) based on the specified C{addressFamily}.
-
- @see: L{twisted.internet.interfaces.IReactorSocket.adoptStreamPort}
- """
- if addressFamily not in (socket.AF_INET, socket.AF_INET6):
- raise error.UnsupportedAddressFamily(addressFamily)
-
- p = tcp.Port._fromListeningDescriptor(
- self, fileDescriptor, addressFamily, factory)
- p.startListening()
- return p
-
- def adoptStreamConnection(self, fileDescriptor, addressFamily, factory):
- """
- @see:
- L{twisted.internet.interfaces.IReactorSocket.adoptStreamConnection}
- """
- if addressFamily not in (socket.AF_INET, socket.AF_INET6):
- raise error.UnsupportedAddressFamily(addressFamily)
-
- return tcp.Server._fromConnectedSocket(
- fileDescriptor, addressFamily, factory, self)
-
-
- # IReactorTCP
-
- def listenTCP(self, port, factory, backlog=50, interface=''):
- """@see: twisted.internet.interfaces.IReactorTCP.listenTCP
- """
- p = tcp.Port(port, factory, backlog, interface, self)
- p.startListening()
- return p
-
- def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):
- """@see: twisted.internet.interfaces.IReactorTCP.connectTCP
- """
- c = tcp.Connector(host, port, factory, timeout, bindAddress, self)
- c.connect()
- return c
-
- # IReactorSSL (sometimes, not implemented)
-
- def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None):
- """@see: twisted.internet.interfaces.IReactorSSL.connectSSL
- """
- if tls is not None:
- tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, True, factory)
- return self.connectTCP(host, port, tlsFactory, timeout, bindAddress)
- elif ssl is not None:
- c = ssl.Connector(
- host, port, factory, contextFactory, timeout, bindAddress, self)
- c.connect()
- return c
- else:
- assert False, "SSL support is not present"
-
-
-
- def listenSSL(self, port, factory, contextFactory, backlog=50, interface=''):
- """@see: twisted.internet.interfaces.IReactorSSL.listenSSL
- """
- if tls is not None:
- tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, False, factory)
- port = self.listenTCP(port, tlsFactory, backlog, interface)
- port._type = 'TLS'
- return port
- elif ssl is not None:
- p = ssl.Port(
- port, factory, contextFactory, backlog, interface, self)
- p.startListening()
- return p
- else:
- assert False, "SSL support is not present"
-
-
- # IReactorArbitrary
- def listenWith(self, portType, *args, **kw):
- warnings.warn(
- "listenWith is deprecated since Twisted 10.1. "
- "See IReactorFDSet.",
- category=DeprecationWarning,
- stacklevel=2)
- kw['reactor'] = self
- p = portType(*args, **kw)
- p.startListening()
- return p
-
-
- def connectWith(self, connectorType, *args, **kw):
- warnings.warn(
- "connectWith is deprecated since Twisted 10.1. "
- "See IReactorFDSet.",
- category=DeprecationWarning,
- stacklevel=2)
- kw['reactor'] = self
- c = connectorType(*args, **kw)
- c.connect()
- return c
-
-
- def _removeAll(self, readers, writers):
- """
- Remove all readers and writers, and list of removed L{IReadDescriptor}s
- and L{IWriteDescriptor}s.
-
- Meant for calling from subclasses, to implement removeAll, like::
-
- def removeAll(self):
- return self._removeAll(self._reads, self._writes)
-
- where C{self._reads} and C{self._writes} are iterables.
- """
- removedReaders = set(readers) - self._internalReaders
- for reader in removedReaders:
- self.removeReader(reader)
-
- removedWriters = set(writers)
- for writer in removedWriters:
- self.removeWriter(writer)
-
- return list(removedReaders | removedWriters)
-
-
-class _PollLikeMixin(object):
- """
- Mixin for poll-like reactors.
-
- Subclasses must define the following attributes::
-
- - _POLL_DISCONNECTED - Bitmask for events indicating a connection was
- lost.
- - _POLL_IN - Bitmask for events indicating there is input to read.
- - _POLL_OUT - Bitmask for events indicating output can be written.
-
- Must be mixed in to a subclass of PosixReactorBase (for
- _disconnectSelectable).
- """
-
- def _doReadOrWrite(self, selectable, fd, event):
- """
- fd is available for read or write, do the work and raise errors if
- necessary.
- """
- why = None
- inRead = False
- if event & self._POLL_DISCONNECTED and not (event & self._POLL_IN):
- # Handle disconnection. But only if we finished processing all
- # the pending input.
- if fd in self._reads:
- # If we were reading from the descriptor then this is a
- # clean shutdown. We know there are no read events pending
- # because we just checked above. It also might be a
- # half-close (which is why we have to keep track of inRead).
- inRead = True
- why = CONNECTION_DONE
- else:
- # If we weren't reading, this is an error shutdown of some
- # sort.
- why = CONNECTION_LOST
- else:
- # Any non-disconnect event turns into a doRead or a doWrite.
- try:
- # First check to see if the descriptor is still valid. This
- # gives fileno() a chance to raise an exception, too.
- # Ideally, disconnection would always be indicated by the
- # return value of doRead or doWrite (or an exception from
- # one of those methods), but calling fileno here helps make
- # buggy applications more transparent.
- if selectable.fileno() == -1:
- # -1 is sort of a historical Python artifact. Python
- # files and sockets used to change their file descriptor
- # to -1 when they closed. For the time being, we'll
- # continue to support this anyway in case applications
- # replicated it, plus abstract.FileDescriptor.fileno
- # returns -1. Eventually it'd be good to deprecate this
- # case.
- why = _NO_FILEDESC
- else:
- if event & self._POLL_IN:
- # Handle a read event.
- why = selectable.doRead()
- inRead = True
- if not why and event & self._POLL_OUT:
- # Handle a write event, as long as doRead didn't
- # disconnect us.
- why = selectable.doWrite()
- inRead = False
- except:
- # Any exception from application code gets logged and will
- # cause us to disconnect the selectable.
- why = sys.exc_info()[1]
- log.err()
- if why:
- self._disconnectSelectable(selectable, why, inRead)
-
-
-
-if tls is not None or ssl is not None:
- classImplements(PosixReactorBase, IReactorSSL)
-if unixEnabled:
- classImplements(PosixReactorBase, IReactorUNIX, IReactorUNIXDatagram)
-if processEnabled:
- classImplements(PosixReactorBase, IReactorProcess)
-if getattr(socket, 'fromfd', None) is not None:
- classImplements(PosixReactorBase, IReactorSocket)
-
-__all__ = ["PosixReactorBase"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/process.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/process.py
deleted file mode 100755
index ee61f743..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/process.py
+++ /dev/null
@@ -1,1074 +0,0 @@
-# -*- test-case-name: twisted.test.test_process -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-UNIX Process management.
-
-Do NOT use this module directly - use reactor.spawnProcess() instead.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-# System Imports
-import gc, os, sys, stat, traceback, select, signal, errno
-
-try:
- import pty
-except ImportError:
- pty = None
-
-try:
- import fcntl, termios
-except ImportError:
- fcntl = None
-
-from zope.interface import implements
-
-from twisted.python import log, failure
-from twisted.python.util import switchUID
-from twisted.internet import fdesc, abstract, error
-from twisted.internet.main import CONNECTION_LOST, CONNECTION_DONE
-from twisted.internet._baseprocess import BaseProcess
-from twisted.internet.interfaces import IProcessTransport
-
-# Some people were importing this, which is incorrect, just keeping it
-# here for backwards compatibility:
-ProcessExitedAlready = error.ProcessExitedAlready
-
-reapProcessHandlers = {}
-
-def reapAllProcesses():
- """
- Reap all registered processes.
- """
- for process in reapProcessHandlers.values():
- process.reapProcess()
-
-
-def registerReapProcessHandler(pid, process):
- """
- Register a process handler for the given pid, in case L{reapAllProcesses}
- is called.
-
- @param pid: the pid of the process.
- @param process: a process handler.
- """
- if pid in reapProcessHandlers:
- raise RuntimeError("Try to register an already registered process.")
- try:
- auxPID, status = os.waitpid(pid, os.WNOHANG)
- except:
- log.msg('Failed to reap %d:' % pid)
- log.err()
- auxPID = None
- if auxPID:
- process.processEnded(status)
- else:
- # if auxPID is 0, there are children but none have exited
- reapProcessHandlers[pid] = process
-
-
-def unregisterReapProcessHandler(pid, process):
- """
- Unregister a process handler previously registered with
- L{registerReapProcessHandler}.
- """
- if not (pid in reapProcessHandlers
- and reapProcessHandlers[pid] == process):
- raise RuntimeError("Try to unregister a process not registered.")
- del reapProcessHandlers[pid]
-
-
-def detectLinuxBrokenPipeBehavior():
- """
- On some Linux version, write-only pipe are detected as readable. This
- function is here to check if this bug is present or not.
-
- See L{ProcessWriter.doRead} for a more detailed explanation.
- """
- global brokenLinuxPipeBehavior
- r, w = os.pipe()
- os.write(w, 'a')
- reads, writes, exes = select.select([w], [], [], 0)
- if reads:
- # Linux < 2.6.11 says a write-only pipe is readable.
- brokenLinuxPipeBehavior = True
- else:
- brokenLinuxPipeBehavior = False
- os.close(r)
- os.close(w)
-
-# Call at import time
-detectLinuxBrokenPipeBehavior()
-
-
-class ProcessWriter(abstract.FileDescriptor):
- """
- (Internal) Helper class to write into a Process's input pipe.
-
- I am a helper which describes a selectable asynchronous writer to a
- process's input pipe, including stdin.
-
- @ivar enableReadHack: A flag which determines how readability on this
- write descriptor will be handled. If C{True}, then readability may
- indicate the reader for this write descriptor has been closed (ie,
- the connection has been lost). If C{False}, then readability events
- are ignored.
- """
- connected = 1
- ic = 0
- enableReadHack = False
-
- def __init__(self, reactor, proc, name, fileno, forceReadHack=False):
- """
- Initialize, specifying a Process instance to connect to.
- """
- abstract.FileDescriptor.__init__(self, reactor)
- fdesc.setNonBlocking(fileno)
- self.proc = proc
- self.name = name
- self.fd = fileno
-
- if not stat.S_ISFIFO(os.fstat(self.fileno()).st_mode):
- # If the fd is not a pipe, then the read hack is never
- # applicable. This case arises when ProcessWriter is used by
- # StandardIO and stdout is redirected to a normal file.
- self.enableReadHack = False
- elif forceReadHack:
- self.enableReadHack = True
- else:
- # Detect if this fd is actually a write-only fd. If it's
- # valid to read, don't try to detect closing via read.
- # This really only means that we cannot detect a TTY's write
- # pipe being closed.
- try:
- os.read(self.fileno(), 0)
- except OSError:
- # It's a write-only pipe end, enable hack
- self.enableReadHack = True
-
- if self.enableReadHack:
- self.startReading()
-
- def fileno(self):
- """
- Return the fileno() of my process's stdin.
- """
- return self.fd
-
- def writeSomeData(self, data):
- """
- Write some data to the open process.
- """
- rv = fdesc.writeToFD(self.fd, data)
- if rv == len(data) and self.enableReadHack:
- # If the send buffer is now empty and it is necessary to monitor
- # this descriptor for readability to detect close, try detecting
- # readability now.
- self.startReading()
- return rv
-
- def write(self, data):
- self.stopReading()
- abstract.FileDescriptor.write(self, data)
-
- def doRead(self):
- """
- The only way a write pipe can become "readable" is at EOF, because the
- child has closed it, and we're using a reactor which doesn't
- distinguish between readable and closed (such as the select reactor).
-
- Except that's not true on linux < 2.6.11. It has the following
- characteristics: write pipe is completely empty => POLLOUT (writable in
- select), write pipe is not completely empty => POLLIN (readable in
- select), write pipe's reader closed => POLLIN|POLLERR (readable and
- writable in select)
-
- That's what this funky code is for. If linux was not broken, this
- function could be simply "return CONNECTION_LOST".
-
- BUG: We call select no matter what the reactor.
- If the reactor is pollreactor, and the fd is > 1024, this will fail.
- (only occurs on broken versions of linux, though).
- """
- if self.enableReadHack:
- if brokenLinuxPipeBehavior:
- fd = self.fd
- r, w, x = select.select([fd], [fd], [], 0)
- if r and w:
- return CONNECTION_LOST
- else:
- return CONNECTION_LOST
- else:
- self.stopReading()
-
- def connectionLost(self, reason):
- """
- See abstract.FileDescriptor.connectionLost.
- """
- # At least on OS X 10.4, exiting while stdout is non-blocking can
- # result in data loss. For some reason putting the file descriptor
- # back into blocking mode seems to resolve this issue.
- fdesc.setBlocking(self.fd)
-
- abstract.FileDescriptor.connectionLost(self, reason)
- self.proc.childConnectionLost(self.name, reason)
-
-
-
-class ProcessReader(abstract.FileDescriptor):
- """
- ProcessReader
-
- I am a selectable representation of a process's output pipe, such as
- stdout and stderr.
- """
- connected = 1
-
- def __init__(self, reactor, proc, name, fileno):
- """
- Initialize, specifying a process to connect to.
- """
- abstract.FileDescriptor.__init__(self, reactor)
- fdesc.setNonBlocking(fileno)
- self.proc = proc
- self.name = name
- self.fd = fileno
- self.startReading()
-
- def fileno(self):
- """
- Return the fileno() of my process's stderr.
- """
- return self.fd
-
- def writeSomeData(self, data):
- # the only time this is actually called is after .loseConnection Any
- # actual write attempt would fail, so we must avoid that. This hack
- # allows us to use .loseConnection on both readers and writers.
- assert data == ""
- return CONNECTION_LOST
-
- def doRead(self):
- """
- This is called when the pipe becomes readable.
- """
- return fdesc.readFromFD(self.fd, self.dataReceived)
-
- def dataReceived(self, data):
- self.proc.childDataReceived(self.name, data)
-
- def loseConnection(self):
- if self.connected and not self.disconnecting:
- self.disconnecting = 1
- self.stopReading()
- self.reactor.callLater(0, self.connectionLost,
- failure.Failure(CONNECTION_DONE))
-
- def connectionLost(self, reason):
- """
- Close my end of the pipe, signal the Process (which signals the
- ProcessProtocol).
- """
- abstract.FileDescriptor.connectionLost(self, reason)
- self.proc.childConnectionLost(self.name, reason)
-
-
-class _BaseProcess(BaseProcess, object):
- """
- Base class for Process and PTYProcess.
- """
- status = None
- pid = None
-
- def reapProcess(self):
- """
- Try to reap a process (without blocking) via waitpid.
-
- This is called when sigchild is caught or a Process object loses its
- "connection" (stdout is closed) This ought to result in reaping all
- zombie processes, since it will be called twice as often as it needs
- to be.
-
- (Unfortunately, this is a slightly experimental approach, since
- UNIX has no way to be really sure that your process is going to
- go away w/o blocking. I don't want to block.)
- """
- try:
- try:
- pid, status = os.waitpid(self.pid, os.WNOHANG)
- except OSError, e:
- if e.errno == errno.ECHILD:
- # no child process
- pid = None
- else:
- raise
- except:
- log.msg('Failed to reap %d:' % self.pid)
- log.err()
- pid = None
- if pid:
- self.processEnded(status)
- unregisterReapProcessHandler(pid, self)
-
-
- def _getReason(self, status):
- exitCode = sig = None
- if os.WIFEXITED(status):
- exitCode = os.WEXITSTATUS(status)
- else:
- sig = os.WTERMSIG(status)
- if exitCode or sig:
- return error.ProcessTerminated(exitCode, sig, status)
- return error.ProcessDone(status)
-
-
- def signalProcess(self, signalID):
- """
- Send the given signal C{signalID} to the process. It'll translate a
- few signals ('HUP', 'STOP', 'INT', 'KILL', 'TERM') from a string
- representation to its int value, otherwise it'll pass directly the
- value provided
-
- @type signalID: C{str} or C{int}
- """
- if signalID in ('HUP', 'STOP', 'INT', 'KILL', 'TERM'):
- signalID = getattr(signal, 'SIG%s' % (signalID,))
- if self.pid is None:
- raise ProcessExitedAlready()
- try:
- os.kill(self.pid, signalID)
- except OSError, e:
- if e.errno == errno.ESRCH:
- raise ProcessExitedAlready()
- else:
- raise
-
-
- def _resetSignalDisposition(self):
- # The Python interpreter ignores some signals, and our child
- # process will inherit that behaviour. To have a child process
- # that responds to signals normally, we need to reset our
- # child process's signal handling (just) after we fork and
- # before we execvpe.
- for signalnum in range(1, signal.NSIG):
- if signal.getsignal(signalnum) == signal.SIG_IGN:
- # Reset signal handling to the default
- signal.signal(signalnum, signal.SIG_DFL)
-
-
- def _fork(self, path, uid, gid, executable, args, environment, **kwargs):
- """
- Fork and then exec sub-process.
-
- @param path: the path where to run the new process.
- @type path: C{str}
- @param uid: if defined, the uid used to run the new process.
- @type uid: C{int}
- @param gid: if defined, the gid used to run the new process.
- @type gid: C{int}
- @param executable: the executable to run in a new process.
- @type executable: C{str}
- @param args: arguments used to create the new process.
- @type args: C{list}.
- @param environment: environment used for the new process.
- @type environment: C{dict}.
- @param kwargs: keyword arguments to L{_setupChild} method.
- """
- settingUID = (uid is not None) or (gid is not None)
- if settingUID:
- curegid = os.getegid()
- currgid = os.getgid()
- cureuid = os.geteuid()
- curruid = os.getuid()
- if uid is None:
- uid = cureuid
- if gid is None:
- gid = curegid
- # prepare to change UID in subprocess
- os.setuid(0)
- os.setgid(0)
-
- collectorEnabled = gc.isenabled()
- gc.disable()
- try:
- self.pid = os.fork()
- except:
- # Still in the parent process
- if settingUID:
- os.setregid(currgid, curegid)
- os.setreuid(curruid, cureuid)
- if collectorEnabled:
- gc.enable()
- raise
- else:
- if self.pid == 0: # pid is 0 in the child process
- # do not put *ANY* code outside the try block. The child process
- # must either exec or _exit. If it gets outside this block (due
- # to an exception that is not handled here, but which might be
- # handled higher up), there will be two copies of the parent
- # running in parallel, doing all kinds of damage.
-
- # After each change to this code, review it to make sure there
- # are no exit paths.
- try:
- # Stop debugging. If I am, I don't care anymore.
- sys.settrace(None)
- self._setupChild(**kwargs)
- self._execChild(path, settingUID, uid, gid,
- executable, args, environment)
- except:
- # If there are errors, bail and try to write something
- # descriptive to stderr.
- # XXX: The parent's stderr isn't necessarily fd 2 anymore, or
- # even still available
- # XXXX: however even libc assumes write(2, err) is a useful
- # thing to attempt
- try:
- stderr = os.fdopen(2, 'w')
- stderr.write("Upon execvpe %s %s in environment %s\n:" %
- (executable, str(args),
- "id %s" % id(environment)))
- traceback.print_exc(file=stderr)
- stderr.flush()
- for fd in range(3):
- os.close(fd)
- except:
- pass # make *sure* the child terminates
- # Did you read the comment about not adding code here?
- os._exit(1)
-
- # we are now in parent process
- if settingUID:
- os.setregid(currgid, curegid)
- os.setreuid(curruid, cureuid)
- if collectorEnabled:
- gc.enable()
- self.status = -1 # this records the exit status of the child
-
- def _setupChild(self, *args, **kwargs):
- """
- Setup the child process. Override in subclasses.
- """
- raise NotImplementedError()
-
- def _execChild(self, path, settingUID, uid, gid,
- executable, args, environment):
- """
- The exec() which is done in the forked child.
- """
- if path:
- os.chdir(path)
- # set the UID before I actually exec the process
- if settingUID:
- switchUID(uid, gid)
- os.execvpe(executable, args, environment)
-
- def __repr__(self):
- """
- String representation of a process.
- """
- return "<%s pid=%s status=%s>" % (self.__class__.__name__,
- self.pid, self.status)
-
-
-class _FDDetector(object):
- """
- This class contains the logic necessary to decide which of the available
- system techniques should be used to detect the open file descriptors for
- the current process. The chosen technique gets monkey-patched into the
- _listOpenFDs method of this class so that the detection only needs to occur
- once.
-
- @ivars listdir: The implementation of listdir to use. This gets overwritten
- by the test cases.
- @ivars getpid: The implementation of getpid to use, returns the PID of the
- running process.
- @ivars openfile: The implementation of open() to use, by default the Python
- builtin.
- """
- # So that we can unit test this
- listdir = os.listdir
- getpid = os.getpid
- openfile = open
-
- def __init__(self):
- self._implementations = [
- self._procFDImplementation, self._devFDImplementation,
- self._fallbackFDImplementation]
-
-
- def _listOpenFDs(self):
- """
- Return an iterable of file descriptors which I{may} be open in this
- process.
-
- This will try to return the fewest possible descriptors without missing
- any.
- """
- self._listOpenFDs = self._getImplementation()
- return self._listOpenFDs()
-
-
- def _getImplementation(self):
- """
- Pick a method which gives correct results for C{_listOpenFDs} in this
- runtime environment.
-
- This involves a lot of very platform-specific checks, some of which may
- be relatively expensive. Therefore the returned method should be saved
- and re-used, rather than always calling this method to determine what it
- is.
-
- See the implementation for the details of how a method is selected.
- """
- for impl in self._implementations:
- try:
- before = impl()
- except:
- continue
- try:
- fp = self.openfile("/dev/null", "r")
- after = impl()
- finally:
- fp.close()
- if before != after:
- return impl
- # If no implementation can detect the newly opened file above, then just
- # return the last one. The last one should therefore always be one
- # which makes a simple static guess which includes all possible open
- # file descriptors, but perhaps also many other values which do not
- # correspond to file descriptors. For example, the scheme implemented
- # by _fallbackFDImplementation is suitable to be the last entry.
- return impl
-
-
- def _devFDImplementation(self):
- """
- Simple implementation for systems where /dev/fd actually works.
- See: http://www.freebsd.org/cgi/man.cgi?fdescfs
- """
- dname = "/dev/fd"
- result = [int(fd) for fd in self.listdir(dname)]
- return result
-
-
- def _procFDImplementation(self):
- """
- Simple implementation for systems where /proc/pid/fd exists (we assume
- it works).
- """
- dname = "/proc/%d/fd" % (self.getpid(),)
- return [int(fd) for fd in self.listdir(dname)]
-
-
- def _fallbackFDImplementation(self):
- """
- Fallback implementation where either the resource module can inform us
- about the upper bound of how many FDs to expect, or where we just guess
- a constant maximum if there is no resource module.
-
- All possible file descriptors from 0 to that upper bound are returned
- with no attempt to exclude invalid file descriptor values.
- """
- try:
- import resource
- except ImportError:
- maxfds = 1024
- else:
- # OS-X reports 9223372036854775808. That's a lot of fds to close.
- # OS-X should get the /dev/fd implementation instead, so mostly
- # this check probably isn't necessary.
- maxfds = min(1024, resource.getrlimit(resource.RLIMIT_NOFILE)[1])
- return range(maxfds)
-
-
-
-detector = _FDDetector()
-
-def _listOpenFDs():
- """
- Use the global detector object to figure out which FD implementation to
- use.
- """
- return detector._listOpenFDs()
-
-
-class Process(_BaseProcess):
- """
- An operating-system Process.
-
- This represents an operating-system process with arbitrary input/output
- pipes connected to it. Those pipes may represent standard input,
- standard output, and standard error, or any other file descriptor.
-
- On UNIX, this is implemented using fork(), exec(), pipe()
- and fcntl(). These calls may not exist elsewhere so this
- code is not cross-platform. (also, windows can only select
- on sockets...)
- """
- implements(IProcessTransport)
-
- debug = False
- debug_child = False
-
- status = -1
- pid = None
-
- processWriterFactory = ProcessWriter
- processReaderFactory = ProcessReader
-
- def __init__(self,
- reactor, executable, args, environment, path, proto,
- uid=None, gid=None, childFDs=None):
- """
- Spawn an operating-system process.
-
- This is where the hard work of disconnecting all currently open
- files / forking / executing the new process happens. (This is
- executed automatically when a Process is instantiated.)
-
- This will also run the subprocess as a given user ID and group ID, if
- specified. (Implementation Note: this doesn't support all the arcane
- nuances of setXXuid on UNIX: it will assume that either your effective
- or real UID is 0.)
- """
- if not proto:
- assert 'r' not in childFDs.values()
- assert 'w' not in childFDs.values()
- _BaseProcess.__init__(self, proto)
-
- self.pipes = {}
- # keys are childFDs, we can sense them closing
- # values are ProcessReader/ProcessWriters
-
- helpers = {}
- # keys are childFDs
- # values are parentFDs
-
- if childFDs is None:
- childFDs = {0: "w", # we write to the child's stdin
- 1: "r", # we read from their stdout
- 2: "r", # and we read from their stderr
- }
-
- debug = self.debug
- if debug: print "childFDs", childFDs
-
- _openedPipes = []
- def pipe():
- r, w = os.pipe()
- _openedPipes.extend([r, w])
- return r, w
-
- # fdmap.keys() are filenos of pipes that are used by the child.
- fdmap = {} # maps childFD to parentFD
- try:
- for childFD, target in childFDs.items():
- if debug: print "[%d]" % childFD, target
- if target == "r":
- # we need a pipe that the parent can read from
- readFD, writeFD = pipe()
- if debug: print "readFD=%d, writeFD=%d" % (readFD, writeFD)
- fdmap[childFD] = writeFD # child writes to this
- helpers[childFD] = readFD # parent reads from this
- elif target == "w":
- # we need a pipe that the parent can write to
- readFD, writeFD = pipe()
- if debug: print "readFD=%d, writeFD=%d" % (readFD, writeFD)
- fdmap[childFD] = readFD # child reads from this
- helpers[childFD] = writeFD # parent writes to this
- else:
- assert type(target) == int, '%r should be an int' % (target,)
- fdmap[childFD] = target # parent ignores this
- if debug: print "fdmap", fdmap
- if debug: print "helpers", helpers
- # the child only cares about fdmap.values()
-
- self._fork(path, uid, gid, executable, args, environment, fdmap=fdmap)
- except:
- map(os.close, _openedPipes)
- raise
-
- # we are the parent process:
- self.proto = proto
-
- # arrange for the parent-side pipes to be read and written
- for childFD, parentFD in helpers.items():
- os.close(fdmap[childFD])
-
- if childFDs[childFD] == "r":
- reader = self.processReaderFactory(reactor, self, childFD,
- parentFD)
- self.pipes[childFD] = reader
-
- if childFDs[childFD] == "w":
- writer = self.processWriterFactory(reactor, self, childFD,
- parentFD, forceReadHack=True)
- self.pipes[childFD] = writer
-
- try:
- # the 'transport' is used for some compatibility methods
- if self.proto is not None:
- self.proto.makeConnection(self)
- except:
- log.err()
-
- # The reactor might not be running yet. This might call back into
- # processEnded synchronously, triggering an application-visible
- # callback. That's probably not ideal. The replacement API for
- # spawnProcess should improve upon this situation.
- registerReapProcessHandler(self.pid, self)
-
-
- def _setupChild(self, fdmap):
- """
- fdmap[childFD] = parentFD
-
- The child wants to end up with 'childFD' attached to what used to be
- the parent's parentFD. As an example, a bash command run like
- 'command 2>&1' would correspond to an fdmap of {0:0, 1:1, 2:1}.
- 'command >foo.txt' would be {0:0, 1:os.open('foo.txt'), 2:2}.
-
- This is accomplished in two steps::
-
- 1. close all file descriptors that aren't values of fdmap. This
- means 0 .. maxfds (or just the open fds within that range, if
- the platform supports '/proc/<pid>/fd').
-
- 2. for each childFD::
-
- - if fdmap[childFD] == childFD, the descriptor is already in
- place. Make sure the CLOEXEC flag is not set, then delete
- the entry from fdmap.
-
- - if childFD is in fdmap.values(), then the target descriptor
- is busy. Use os.dup() to move it elsewhere, update all
- fdmap[childFD] items that point to it, then close the
- original. Then fall through to the next case.
-
- - now fdmap[childFD] is not in fdmap.values(), and is free.
- Use os.dup2() to move it to the right place, then close the
- original.
- """
-
- debug = self.debug_child
- if debug:
- errfd = sys.stderr
- errfd.write("starting _setupChild\n")
-
- destList = fdmap.values()
- for fd in _listOpenFDs():
- if fd in destList:
- continue
- if debug and fd == errfd.fileno():
- continue
- try:
- os.close(fd)
- except:
- pass
-
- # at this point, the only fds still open are the ones that need to
- # be moved to their appropriate positions in the child (the targets
- # of fdmap, i.e. fdmap.values() )
-
- if debug: print >>errfd, "fdmap", fdmap
- childlist = fdmap.keys()
- childlist.sort()
-
- for child in childlist:
- target = fdmap[child]
- if target == child:
- # fd is already in place
- if debug: print >>errfd, "%d already in place" % target
- fdesc._unsetCloseOnExec(child)
- else:
- if child in fdmap.values():
- # we can't replace child-fd yet, as some other mapping
- # still needs the fd it wants to target. We must preserve
- # that old fd by duping it to a new home.
- newtarget = os.dup(child) # give it a safe home
- if debug: print >>errfd, "os.dup(%d) -> %d" % (child,
- newtarget)
- os.close(child) # close the original
- for c, p in fdmap.items():
- if p == child:
- fdmap[c] = newtarget # update all pointers
- # now it should be available
- if debug: print >>errfd, "os.dup2(%d,%d)" % (target, child)
- os.dup2(target, child)
-
- # At this point, the child has everything it needs. We want to close
- # everything that isn't going to be used by the child, i.e.
- # everything not in fdmap.keys(). The only remaining fds open are
- # those in fdmap.values().
-
- # Any given fd may appear in fdmap.values() multiple times, so we
- # need to remove duplicates first.
-
- old = []
- for fd in fdmap.values():
- if not fd in old:
- if not fd in fdmap.keys():
- old.append(fd)
- if debug: print >>errfd, "old", old
- for fd in old:
- os.close(fd)
-
- self._resetSignalDisposition()
-
-
- def writeToChild(self, childFD, data):
- self.pipes[childFD].write(data)
-
- def closeChildFD(self, childFD):
- # for writer pipes, loseConnection tries to write the remaining data
- # out to the pipe before closing it
- # if childFD is not in the list of pipes, assume that it is already
- # closed
- if childFD in self.pipes:
- self.pipes[childFD].loseConnection()
-
- def pauseProducing(self):
- for p in self.pipes.itervalues():
- if isinstance(p, ProcessReader):
- p.stopReading()
-
- def resumeProducing(self):
- for p in self.pipes.itervalues():
- if isinstance(p, ProcessReader):
- p.startReading()
-
- # compatibility
- def closeStdin(self):
- """
- Call this to close standard input on this process.
- """
- self.closeChildFD(0)
-
- def closeStdout(self):
- self.closeChildFD(1)
-
- def closeStderr(self):
- self.closeChildFD(2)
-
- def loseConnection(self):
- self.closeStdin()
- self.closeStderr()
- self.closeStdout()
-
- def write(self, data):
- """
- Call this to write to standard input on this process.
-
- NOTE: This will silently lose data if there is no standard input.
- """
- if 0 in self.pipes:
- self.pipes[0].write(data)
-
- def registerProducer(self, producer, streaming):
- """
- Call this to register producer for standard input.
-
- If there is no standard input producer.stopProducing() will
- be called immediately.
- """
- if 0 in self.pipes:
- self.pipes[0].registerProducer(producer, streaming)
- else:
- producer.stopProducing()
-
- def unregisterProducer(self):
- """
- Call this to unregister producer for standard input."""
- if 0 in self.pipes:
- self.pipes[0].unregisterProducer()
-
- def writeSequence(self, seq):
- """
- Call this to write to standard input on this process.
-
- NOTE: This will silently lose data if there is no standard input.
- """
- if 0 in self.pipes:
- self.pipes[0].writeSequence(seq)
-
-
- def childDataReceived(self, name, data):
- self.proto.childDataReceived(name, data)
-
-
- def childConnectionLost(self, childFD, reason):
- # this is called when one of the helpers (ProcessReader or
- # ProcessWriter) notices their pipe has been closed
- os.close(self.pipes[childFD].fileno())
- del self.pipes[childFD]
- try:
- self.proto.childConnectionLost(childFD)
- except:
- log.err()
- self.maybeCallProcessEnded()
-
- def maybeCallProcessEnded(self):
- # we don't call ProcessProtocol.processEnded until:
- # the child has terminated, AND
- # all writers have indicated an error status, AND
- # all readers have indicated EOF
- # This insures that we've gathered all output from the process.
- if self.pipes:
- return
- if not self.lostProcess:
- self.reapProcess()
- return
- _BaseProcess.maybeCallProcessEnded(self)
-
-
-
-class PTYProcess(abstract.FileDescriptor, _BaseProcess):
- """
- An operating-system Process that uses PTY support.
- """
- implements(IProcessTransport)
-
- status = -1
- pid = None
-
- def __init__(self, reactor, executable, args, environment, path, proto,
- uid=None, gid=None, usePTY=None):
- """
- Spawn an operating-system process.
-
- This is where the hard work of disconnecting all currently open
- files / forking / executing the new process happens. (This is
- executed automatically when a Process is instantiated.)
-
- This will also run the subprocess as a given user ID and group ID, if
- specified. (Implementation Note: this doesn't support all the arcane
- nuances of setXXuid on UNIX: it will assume that either your effective
- or real UID is 0.)
- """
- if pty is None and not isinstance(usePTY, (tuple, list)):
- # no pty module and we didn't get a pty to use
- raise NotImplementedError(
- "cannot use PTYProcess on platforms without the pty module.")
- abstract.FileDescriptor.__init__(self, reactor)
- _BaseProcess.__init__(self, proto)
-
- if isinstance(usePTY, (tuple, list)):
- masterfd, slavefd, ttyname = usePTY
- else:
- masterfd, slavefd = pty.openpty()
- ttyname = os.ttyname(slavefd)
-
- try:
- self._fork(path, uid, gid, executable, args, environment,
- masterfd=masterfd, slavefd=slavefd)
- except:
- if not isinstance(usePTY, (tuple, list)):
- os.close(masterfd)
- os.close(slavefd)
- raise
-
- # we are now in parent process:
- os.close(slavefd)
- fdesc.setNonBlocking(masterfd)
- self.fd = masterfd
- self.startReading()
- self.connected = 1
- self.status = -1
- try:
- self.proto.makeConnection(self)
- except:
- log.err()
- registerReapProcessHandler(self.pid, self)
-
- def _setupChild(self, masterfd, slavefd):
- """
- Setup child process after fork() but before exec().
- """
- os.close(masterfd)
- if hasattr(termios, 'TIOCNOTTY'):
- try:
- fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
- except OSError:
- pass
- else:
- try:
- fcntl.ioctl(fd, termios.TIOCNOTTY, '')
- except:
- pass
- os.close(fd)
-
- os.setsid()
-
- if hasattr(termios, 'TIOCSCTTY'):
- fcntl.ioctl(slavefd, termios.TIOCSCTTY, '')
-
- for fd in range(3):
- if fd != slavefd:
- os.close(fd)
-
- os.dup2(slavefd, 0) # stdin
- os.dup2(slavefd, 1) # stdout
- os.dup2(slavefd, 2) # stderr
-
- for fd in _listOpenFDs():
- if fd > 2:
- try:
- os.close(fd)
- except:
- pass
-
- self._resetSignalDisposition()
-
-
- # PTYs do not have stdin/stdout/stderr. They only have in and out, just
- # like sockets. You cannot close one without closing off the entire PTY.
- def closeStdin(self):
- pass
-
- def closeStdout(self):
- pass
-
- def closeStderr(self):
- pass
-
- def doRead(self):
- """
- Called when my standard output stream is ready for reading.
- """
- return fdesc.readFromFD(
- self.fd,
- lambda data: self.proto.childDataReceived(1, data))
-
- def fileno(self):
- """
- This returns the file number of standard output on this process.
- """
- return self.fd
-
- def maybeCallProcessEnded(self):
- # two things must happen before we call the ProcessProtocol's
- # processEnded method. 1: the child process must die and be reaped
- # (which calls our own processEnded method). 2: the child must close
- # their stdin/stdout/stderr fds, causing the pty to close, causing
- # our connectionLost method to be called. #2 can also be triggered
- # by calling .loseConnection().
- if self.lostProcess == 2:
- _BaseProcess.maybeCallProcessEnded(self)
-
- def connectionLost(self, reason):
- """
- I call this to clean up when one or all of my connections has died.
- """
- abstract.FileDescriptor.connectionLost(self, reason)
- os.close(self.fd)
- self.lostProcess += 1
- self.maybeCallProcessEnded()
-
- def writeSomeData(self, data):
- """
- Write some data to the open process.
- """
- return fdesc.writeToFD(self.fd, data)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/protocol.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/protocol.py
deleted file mode 100755
index 094a535a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/protocol.py
+++ /dev/null
@@ -1,830 +0,0 @@
-# -*- test-case-name: twisted.test.test_factories,twisted.internet.test.test_protocol -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Standard implementations of Twisted protocol-related interfaces.
-
-Start here if you are looking to write a new protocol implementation for
-Twisted. The Protocol class contains some introductory material.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-import random
-from zope.interface import implements
-
-# Twisted Imports
-from twisted.python import log, failure, components
-from twisted.internet import interfaces, error, defer
-
-
-class Factory:
- """
- This is a factory which produces protocols.
-
- By default, buildProtocol will create a protocol of the class given in
- self.protocol.
- """
-
- implements(interfaces.IProtocolFactory, interfaces.ILoggingContext)
-
- # put a subclass of Protocol here:
- protocol = None
-
- numPorts = 0
- noisy = True
-
- def logPrefix(self):
- """
- Describe this factory for log messages.
- """
- return self.__class__.__name__
-
-
- def doStart(self):
- """Make sure startFactory is called.
-
- Users should not call this function themselves!
- """
- if not self.numPorts:
- if self.noisy:
- log.msg("Starting factory %r" % self)
- self.startFactory()
- self.numPorts = self.numPorts + 1
-
- def doStop(self):
- """Make sure stopFactory is called.
-
- Users should not call this function themselves!
- """
- if self.numPorts == 0:
- # this shouldn't happen, but does sometimes and this is better
- # than blowing up in assert as we did previously.
- return
- self.numPorts = self.numPorts - 1
- if not self.numPorts:
- if self.noisy:
- log.msg("Stopping factory %r" % self)
- self.stopFactory()
-
- def startFactory(self):
- """This will be called before I begin listening on a Port or Connector.
-
- It will only be called once, even if the factory is connected
- to multiple ports.
-
- This can be used to perform 'unserialization' tasks that
- are best put off until things are actually running, such
- as connecting to a database, opening files, etcetera.
- """
-
- def stopFactory(self):
- """This will be called before I stop listening on all Ports/Connectors.
-
- This can be overridden to perform 'shutdown' tasks such as disconnecting
- database connections, closing files, etc.
-
- It will be called, for example, before an application shuts down,
- if it was connected to a port. User code should not call this function
- directly.
- """
-
- def buildProtocol(self, addr):
- """Create an instance of a subclass of Protocol.
-
- The returned instance will handle input on an incoming server
- connection, and an attribute \"factory\" pointing to the creating
- factory.
-
- Override this method to alter how Protocol instances get created.
-
- @param addr: an object implementing L{twisted.internet.interfaces.IAddress}
- """
- p = self.protocol()
- p.factory = self
- return p
-
-
-class ClientFactory(Factory):
- """A Protocol factory for clients.
-
- This can be used together with the various connectXXX methods in
- reactors.
- """
-
- def startedConnecting(self, connector):
- """Called when a connection has been started.
-
- You can call connector.stopConnecting() to stop the connection attempt.
-
- @param connector: a Connector object.
- """
-
- def clientConnectionFailed(self, connector, reason):
- """Called when a connection has failed to connect.
-
- It may be useful to call connector.connect() - this will reconnect.
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
- def clientConnectionLost(self, connector, reason):
- """Called when an established connection is lost.
-
- It may be useful to call connector.connect() - this will reconnect.
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
-
-class _InstanceFactory(ClientFactory):
- """
- Factory used by ClientCreator.
-
- @ivar deferred: The L{Deferred} which represents this connection attempt and
- which will be fired when it succeeds or fails.
-
- @ivar pending: After a connection attempt succeeds or fails, a delayed call
- which will fire the L{Deferred} representing this connection attempt.
- """
-
- noisy = False
- pending = None
-
- def __init__(self, reactor, instance, deferred):
- self.reactor = reactor
- self.instance = instance
- self.deferred = deferred
-
-
- def __repr__(self):
- return "<ClientCreator factory: %r>" % (self.instance, )
-
-
- def buildProtocol(self, addr):
- """
- Return the pre-constructed protocol instance and arrange to fire the
- waiting L{Deferred} to indicate success establishing the connection.
- """
- self.pending = self.reactor.callLater(
- 0, self.fire, self.deferred.callback, self.instance)
- self.deferred = None
- return self.instance
-
-
- def clientConnectionFailed(self, connector, reason):
- """
- Arrange to fire the waiting L{Deferred} with the given failure to
- indicate the connection could not be established.
- """
- self.pending = self.reactor.callLater(
- 0, self.fire, self.deferred.errback, reason)
- self.deferred = None
-
-
- def fire(self, func, value):
- """
- Clear C{self.pending} to avoid a reference cycle and then invoke func
- with the value.
- """
- self.pending = None
- func(value)
-
-
-
-class ClientCreator:
- """
- Client connections that do not require a factory.
-
- The various connect* methods create a protocol instance using the given
- protocol class and arguments, and connect it, returning a Deferred of the
- resulting protocol instance.
-
- Useful for cases when we don't really need a factory. Mainly this
- is when there is no shared state between protocol instances, and no need
- to reconnect.
-
- The C{connectTCP}, C{connectUNIX}, and C{connectSSL} methods each return a
- L{Deferred} which will fire with an instance of the protocol class passed to
- L{ClientCreator.__init__}. These Deferred can be cancelled to abort the
- connection attempt (in a very unlikely case, cancelling the Deferred may not
- prevent the protocol from being instantiated and connected to a transport;
- if this happens, it will be disconnected immediately afterwards and the
- Deferred will still errback with L{CancelledError}).
- """
-
- def __init__(self, reactor, protocolClass, *args, **kwargs):
- self.reactor = reactor
- self.protocolClass = protocolClass
- self.args = args
- self.kwargs = kwargs
-
-
- def _connect(self, method, *args, **kwargs):
- """
- Initiate a connection attempt.
-
- @param method: A callable which will actually start the connection
- attempt. For example, C{reactor.connectTCP}.
-
- @param *args: Positional arguments to pass to C{method}, excluding the
- factory.
-
- @param **kwargs: Keyword arguments to pass to C{method}.
-
- @return: A L{Deferred} which fires with an instance of the protocol
- class passed to this L{ClientCreator}'s initializer or fails if the
- connection cannot be set up for some reason.
- """
- def cancelConnect(deferred):
- connector.disconnect()
- if f.pending is not None:
- f.pending.cancel()
- d = defer.Deferred(cancelConnect)
- f = _InstanceFactory(
- self.reactor, self.protocolClass(*self.args, **self.kwargs), d)
- connector = method(factory=f, *args, **kwargs)
- return d
-
-
- def connectTCP(self, host, port, timeout=30, bindAddress=None):
- """
- Connect to a TCP server.
-
- The parameters are all the same as to L{IReactorTCP.connectTCP} except
- that the factory parameter is omitted.
-
- @return: A L{Deferred} which fires with an instance of the protocol
- class passed to this L{ClientCreator}'s initializer or fails if the
- connection cannot be set up for some reason.
- """
- return self._connect(
- self.reactor.connectTCP, host, port, timeout=timeout,
- bindAddress=bindAddress)
-
-
- def connectUNIX(self, address, timeout=30, checkPID=False):
- """
- Connect to a Unix socket.
-
- The parameters are all the same as to L{IReactorUNIX.connectUNIX} except
- that the factory parameter is omitted.
-
- @return: A L{Deferred} which fires with an instance of the protocol
- class passed to this L{ClientCreator}'s initializer or fails if the
- connection cannot be set up for some reason.
- """
- return self._connect(
- self.reactor.connectUNIX, address, timeout=timeout,
- checkPID=checkPID)
-
-
- def connectSSL(self, host, port, contextFactory, timeout=30, bindAddress=None):
- """
- Connect to an SSL server.
-
- The parameters are all the same as to L{IReactorSSL.connectSSL} except
- that the factory parameter is omitted.
-
- @return: A L{Deferred} which fires with an instance of the protocol
- class passed to this L{ClientCreator}'s initializer or fails if the
- connection cannot be set up for some reason.
- """
- return self._connect(
- self.reactor.connectSSL, host, port,
- contextFactory=contextFactory, timeout=timeout,
- bindAddress=bindAddress)
-
-
-
-class ReconnectingClientFactory(ClientFactory):
- """
- Factory which auto-reconnects clients with an exponential back-off.
-
- Note that clients should call my resetDelay method after they have
- connected successfully.
-
- @ivar maxDelay: Maximum number of seconds between connection attempts.
- @ivar initialDelay: Delay for the first reconnection attempt.
- @ivar factor: A multiplicitive factor by which the delay grows
- @ivar jitter: Percentage of randomness to introduce into the delay length
- to prevent stampeding.
- @ivar clock: The clock used to schedule reconnection. It's mainly useful to
- be parametrized in tests. If the factory is serialized, this attribute
- will not be serialized, and the default value (the reactor) will be
- restored when deserialized.
- @type clock: L{IReactorTime}
- @ivar maxRetries: Maximum number of consecutive unsuccessful connection
- attempts, after which no further connection attempts will be made. If
- this is not explicitly set, no maximum is applied.
- """
- maxDelay = 3600
- initialDelay = 1.0
- # Note: These highly sensitive factors have been precisely measured by
- # the National Institute of Science and Technology. Take extreme care
- # in altering them, or you may damage your Internet!
- # (Seriously: <http://physics.nist.gov/cuu/Constants/index.html>)
- factor = 2.7182818284590451 # (math.e)
- # Phi = 1.6180339887498948 # (Phi is acceptable for use as a
- # factor if e is too large for your application.)
- jitter = 0.11962656472 # molar Planck constant times c, joule meter/mole
-
- delay = initialDelay
- retries = 0
- maxRetries = None
- _callID = None
- connector = None
- clock = None
-
- continueTrying = 1
-
-
- def clientConnectionFailed(self, connector, reason):
- if self.continueTrying:
- self.connector = connector
- self.retry()
-
-
- def clientConnectionLost(self, connector, unused_reason):
- if self.continueTrying:
- self.connector = connector
- self.retry()
-
-
- def retry(self, connector=None):
- """
- Have this connector connect again, after a suitable delay.
- """
- if not self.continueTrying:
- if self.noisy:
- log.msg("Abandoning %s on explicit request" % (connector,))
- return
-
- if connector is None:
- if self.connector is None:
- raise ValueError("no connector to retry")
- else:
- connector = self.connector
-
- self.retries += 1
- if self.maxRetries is not None and (self.retries > self.maxRetries):
- if self.noisy:
- log.msg("Abandoning %s after %d retries." %
- (connector, self.retries))
- return
-
- self.delay = min(self.delay * self.factor, self.maxDelay)
- if self.jitter:
- self.delay = random.normalvariate(self.delay,
- self.delay * self.jitter)
-
- if self.noisy:
- log.msg("%s will retry in %d seconds" % (connector, self.delay,))
-
- def reconnector():
- self._callID = None
- connector.connect()
- if self.clock is None:
- from twisted.internet import reactor
- self.clock = reactor
- self._callID = self.clock.callLater(self.delay, reconnector)
-
-
- def stopTrying(self):
- """
- Put a stop to any attempt to reconnect in progress.
- """
- # ??? Is this function really stopFactory?
- if self._callID:
- self._callID.cancel()
- self._callID = None
- self.continueTrying = 0
- if self.connector:
- try:
- self.connector.stopConnecting()
- except error.NotConnectingError:
- pass
-
-
- def resetDelay(self):
- """
- Call this method after a successful connection: it resets the delay and
- the retry counter.
- """
- self.delay = self.initialDelay
- self.retries = 0
- self._callID = None
- self.continueTrying = 1
-
-
- def __getstate__(self):
- """
- Remove all of the state which is mutated by connection attempts and
- failures, returning just the state which describes how reconnections
- should be attempted. This will make the unserialized instance
- behave just as this one did when it was first instantiated.
- """
- state = self.__dict__.copy()
- for key in ['connector', 'retries', 'delay',
- 'continueTrying', '_callID', 'clock']:
- if key in state:
- del state[key]
- return state
-
-
-
-class ServerFactory(Factory):
- """Subclass this to indicate that your protocol.Factory is only usable for servers.
- """
-
-
-
-class BaseProtocol:
- """
- This is the abstract superclass of all protocols.
-
- Some methods have helpful default implementations here so that they can
- easily be shared, but otherwise the direct subclasses of this class are more
- interesting, L{Protocol} and L{ProcessProtocol}.
- """
- connected = 0
- transport = None
-
- def makeConnection(self, transport):
- """Make a connection to a transport and a server.
-
- This sets the 'transport' attribute of this Protocol, and calls the
- connectionMade() callback.
- """
- self.connected = 1
- self.transport = transport
- self.connectionMade()
-
- def connectionMade(self):
- """Called when a connection is made.
-
- This may be considered the initializer of the protocol, because
- it is called when the connection is completed. For clients,
- this is called once the connection to the server has been
- established; for servers, this is called after an accept() call
- stops blocking and a socket has been received. If you need to
- send any greeting or initial message, do it here.
- """
-
-connectionDone=failure.Failure(error.ConnectionDone())
-connectionDone.cleanFailure()
-
-
-class Protocol(BaseProtocol):
- """
- This is the base class for streaming connection-oriented protocols.
-
- If you are going to write a new connection-oriented protocol for Twisted,
- start here. Any protocol implementation, either client or server, should
- be a subclass of this class.
-
- The API is quite simple. Implement L{dataReceived} to handle both
- event-based and synchronous input; output can be sent through the
- 'transport' attribute, which is to be an instance that implements
- L{twisted.internet.interfaces.ITransport}. Override C{connectionLost} to be
- notified when the connection ends.
-
- Some subclasses exist already to help you write common types of protocols:
- see the L{twisted.protocols.basic} module for a few of them.
- """
- implements(interfaces.IProtocol, interfaces.ILoggingContext)
-
- def logPrefix(self):
- """
- Return a prefix matching the class name, to identify log messages
- related to this protocol instance.
- """
- return self.__class__.__name__
-
-
- def dataReceived(self, data):
- """Called whenever data is received.
-
- Use this method to translate to a higher-level message. Usually, some
- callback will be made upon the receipt of each complete protocol
- message.
-
- @param data: a string of indeterminate length. Please keep in mind
- that you will probably need to buffer some data, as partial
- (or multiple) protocol messages may be received! I recommend
- that unit tests for protocols call through to this method with
- differing chunk sizes, down to one byte at a time.
- """
-
- def connectionLost(self, reason=connectionDone):
- """Called when the connection is shut down.
-
- Clear any circular references here, and any external references
- to this Protocol. The connection has been closed.
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
-
-class ProtocolToConsumerAdapter(components.Adapter):
- implements(interfaces.IConsumer)
-
- def write(self, data):
- self.original.dataReceived(data)
-
- def registerProducer(self, producer, streaming):
- pass
-
- def unregisterProducer(self):
- pass
-
-components.registerAdapter(ProtocolToConsumerAdapter, interfaces.IProtocol,
- interfaces.IConsumer)
-
-class ConsumerToProtocolAdapter(components.Adapter):
- implements(interfaces.IProtocol)
-
- def dataReceived(self, data):
- self.original.write(data)
-
- def connectionLost(self, reason):
- pass
-
- def makeConnection(self, transport):
- pass
-
- def connectionMade(self):
- pass
-
-components.registerAdapter(ConsumerToProtocolAdapter, interfaces.IConsumer,
- interfaces.IProtocol)
-
-class ProcessProtocol(BaseProtocol):
- """
- Base process protocol implementation which does simple dispatching for
- stdin, stdout, and stderr file descriptors.
- """
- implements(interfaces.IProcessProtocol)
-
- def childDataReceived(self, childFD, data):
- if childFD == 1:
- self.outReceived(data)
- elif childFD == 2:
- self.errReceived(data)
-
-
- def outReceived(self, data):
- """
- Some data was received from stdout.
- """
-
-
- def errReceived(self, data):
- """
- Some data was received from stderr.
- """
-
-
- def childConnectionLost(self, childFD):
- if childFD == 0:
- self.inConnectionLost()
- elif childFD == 1:
- self.outConnectionLost()
- elif childFD == 2:
- self.errConnectionLost()
-
-
- def inConnectionLost(self):
- """
- This will be called when stdin is closed.
- """
-
-
- def outConnectionLost(self):
- """
- This will be called when stdout is closed.
- """
-
-
- def errConnectionLost(self):
- """
- This will be called when stderr is closed.
- """
-
-
- def processExited(self, reason):
- """
- This will be called when the subprocess exits.
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
-
- def processEnded(self, reason):
- """
- Called when the child process exits and all file descriptors
- associated with it have been closed.
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
-
-
-class AbstractDatagramProtocol:
- """
- Abstract protocol for datagram-oriented transports, e.g. IP, ICMP, ARP, UDP.
- """
-
- transport = None
- numPorts = 0
- noisy = True
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['transport'] = None
- return d
-
- def doStart(self):
- """Make sure startProtocol is called.
-
- This will be called by makeConnection(), users should not call it.
- """
- if not self.numPorts:
- if self.noisy:
- log.msg("Starting protocol %s" % self)
- self.startProtocol()
- self.numPorts = self.numPorts + 1
-
- def doStop(self):
- """Make sure stopProtocol is called.
-
- This will be called by the port, users should not call it.
- """
- assert self.numPorts > 0
- self.numPorts = self.numPorts - 1
- self.transport = None
- if not self.numPorts:
- if self.noisy:
- log.msg("Stopping protocol %s" % self)
- self.stopProtocol()
-
- def startProtocol(self):
- """Called when a transport is connected to this protocol.
-
- Will only be called once, even if multiple ports are connected.
- """
-
- def stopProtocol(self):
- """Called when the transport is disconnected.
-
- Will only be called once, after all ports are disconnected.
- """
-
- def makeConnection(self, transport):
- """Make a connection to a transport and a server.
-
- This sets the 'transport' attribute of this DatagramProtocol, and calls the
- doStart() callback.
- """
- assert self.transport == None
- self.transport = transport
- self.doStart()
-
- def datagramReceived(self, datagram, addr):
- """Called when a datagram is received.
-
- @param datagram: the string received from the transport.
- @param addr: tuple of source of datagram.
- """
-
-
-class DatagramProtocol(AbstractDatagramProtocol):
- """
- Protocol for datagram-oriented transport, e.g. UDP.
-
- @type transport: C{NoneType} or
- L{IUDPTransport<twisted.internet.interfaces.IUDPTransport>} provider
- @ivar transport: The transport with which this protocol is associated,
- if it is associated with one.
- """
- implements(interfaces.ILoggingContext)
-
- def logPrefix(self):
- """
- Return a prefix matching the class name, to identify log messages
- related to this protocol instance.
- """
- return self.__class__.__name__
-
-
- def connectionRefused(self):
- """Called due to error from write in connected mode.
-
- Note this is a result of ICMP message generated by *previous*
- write.
- """
-
-
-class ConnectedDatagramProtocol(DatagramProtocol):
- """Protocol for connected datagram-oriented transport.
-
- No longer necessary for UDP.
- """
-
- def datagramReceived(self, datagram):
- """Called when a datagram is received.
-
- @param datagram: the string received from the transport.
- """
-
- def connectionFailed(self, failure):
- """Called if connecting failed.
-
- Usually this will be due to a DNS lookup failure.
- """
-
-
-
-class FileWrapper:
- """A wrapper around a file-like object to make it behave as a Transport.
-
- This doesn't actually stream the file to the attached protocol,
- and is thus useful mainly as a utility for debugging protocols.
- """
-
- implements(interfaces.ITransport)
-
- closed = 0
- disconnecting = 0
- producer = None
- streamingProducer = 0
-
- def __init__(self, file):
- self.file = file
-
- def write(self, data):
- try:
- self.file.write(data)
- except:
- self.handleException()
- # self._checkProducer()
-
- def _checkProducer(self):
- # Cheating; this is called at "idle" times to allow producers to be
- # found and dealt with
- if self.producer:
- self.producer.resumeProducing()
-
- def registerProducer(self, producer, streaming):
- """From abstract.FileDescriptor
- """
- self.producer = producer
- self.streamingProducer = streaming
- if not streaming:
- producer.resumeProducing()
-
- def unregisterProducer(self):
- self.producer = None
-
- def stopConsuming(self):
- self.unregisterProducer()
- self.loseConnection()
-
- def writeSequence(self, iovec):
- self.write("".join(iovec))
-
- def loseConnection(self):
- self.closed = 1
- try:
- self.file.close()
- except (IOError, OSError):
- self.handleException()
-
- def getPeer(self):
- # XXX: According to ITransport, this should return an IAddress!
- return 'file', 'file'
-
- def getHost(self):
- # XXX: According to ITransport, this should return an IAddress!
- return 'file'
-
- def handleException(self):
- pass
-
- def resumeProducing(self):
- # Never sends data anyways
- pass
-
- def pauseProducing(self):
- # Never sends data anyways
- pass
-
- def stopProducing(self):
- self.loseConnection()
-
-
-__all__ = ["Factory", "ClientFactory", "ReconnectingClientFactory", "connectionDone",
- "Protocol", "ProcessProtocol", "FileWrapper", "ServerFactory",
- "AbstractDatagramProtocol", "DatagramProtocol", "ConnectedDatagramProtocol",
- "ClientCreator"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pyuisupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pyuisupport.py
deleted file mode 100755
index 1e7def59..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/pyuisupport.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-This module integrates PyUI with twisted.internet's mainloop.
-
-Maintainer: Jp Calderone
-
-See doc/examples/pyuidemo.py for example usage.
-"""
-
-# System imports
-import pyui
-
-def _guiUpdate(reactor, delay):
- pyui.draw()
- if pyui.update() == 0:
- pyui.quit()
- reactor.stop()
- else:
- reactor.callLater(delay, _guiUpdate, reactor, delay)
-
-
-def install(ms=10, reactor=None, args=(), kw={}):
- """
- Schedule PyUI's display to be updated approximately every C{ms}
- milliseconds, and initialize PyUI with the specified arguments.
- """
- d = pyui.init(*args, **kw)
-
- if reactor is None:
- from twisted.internet import reactor
- _guiUpdate(reactor, ms / 1000.0)
- return d
-
-__all__ = ["install"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/qtreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/qtreactor.py
deleted file mode 100755
index a5480083..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/qtreactor.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_qtreactor -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-try:
- # 'import qtreactor' would have imported this file instead of the
- # top-level qtreactor. __import__ does the right thing
- # (kids, don't repeat this at home)
- install = __import__('qtreactor').install
-except ImportError:
- from twisted.plugins.twisted_qtstub import errorMessage
- raise ImportError(errorMessage)
-else:
- import warnings
- warnings.warn("Please use qtreactor instead of twisted.internet.qtreactor",
- category=DeprecationWarning)
-
-__all__ = ['install']
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/reactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/reactor.py
deleted file mode 100755
index 54e2ceba..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/reactor.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The reactor is the Twisted event loop within Twisted, the loop which drives
-applications using Twisted. The reactor provides APIs for networking,
-threading, dispatching events, and more.
-
-The default reactor depends on the platform and will be installed if this
-module is imported without another reactor being explicitly installed
-beforehand. Regardless of which reactor is installed, importing this module is
-the correct way to get a reference to it.
-
-New application code should prefer to pass and accept the reactor as a
-parameter where it is needed, rather than relying on being able to import this
-module to get a reference. This simplifies unit testing and may make it easier
-to one day support multiple reactors (as a performance enhancement), though
-this is not currently possible.
-
-@see: L{IReactorCore<twisted.internet.interfaces.IReactorCore>}
-@see: L{IReactorTime<twisted.internet.interfaces.IReactorTime>}
-@see: L{IReactorProcess<twisted.internet.interfaces.IReactorProcess>}
-@see: L{IReactorTCP<twisted.internet.interfaces.IReactorTCP>}
-@see: L{IReactorSSL<twisted.internet.interfaces.IReactorSSL>}
-@see: L{IReactorUDP<twisted.internet.interfaces.IReactorUDP>}
-@see: L{IReactorMulticast<twisted.internet.interfaces.IReactorMulticast>}
-@see: L{IReactorUNIX<twisted.internet.interfaces.IReactorUNIX>}
-@see: L{IReactorUNIXDatagram<twisted.internet.interfaces.IReactorUNIXDatagram>}
-@see: L{IReactorFDSet<twisted.internet.interfaces.IReactorFDSet>}
-@see: L{IReactorThreads<twisted.internet.interfaces.IReactorThreads>}
-@see: L{IReactorArbitrary<twisted.internet.interfaces.IReactorArbitrary>}
-@see: L{IReactorPluggableResolver<twisted.internet.interfaces.IReactorPluggableResolver>}
-"""
-
-import sys
-del sys.modules['twisted.internet.reactor']
-from twisted.internet import default
-default.install()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/selectreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/selectreactor.py
deleted file mode 100755
index 01ac28cf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/selectreactor.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# -*- test-case-name: twisted.test.test_internet -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Select reactor
-"""
-
-from time import sleep
-import sys, select, socket
-from errno import EINTR, EBADF
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IReactorFDSet
-from twisted.internet import posixbase
-from twisted.python import log
-from twisted.python.runtime import platformType
-
-
-def win32select(r, w, e, timeout=None):
- """Win32 select wrapper."""
- if not (r or w):
- # windows select() exits immediately when no sockets
- if timeout is None:
- timeout = 0.01
- else:
- timeout = min(timeout, 0.001)
- sleep(timeout)
- return [], [], []
- # windows doesn't process 'signals' inside select(), so we set a max
- # time or ctrl-c will never be recognized
- if timeout is None or timeout > 0.5:
- timeout = 0.5
- r, w, e = select.select(r, w, w, timeout)
- return r, w + e, []
-
-if platformType == "win32":
- _select = win32select
-else:
- _select = select.select
-
-
-try:
- from twisted.internet.win32eventreactor import _ThreadedWin32EventsMixin
-except ImportError:
- _extraBase = object
-else:
- _extraBase = _ThreadedWin32EventsMixin
-
-
-class SelectReactor(posixbase.PosixReactorBase, _extraBase):
- """
- A select() based reactor - runs on all POSIX platforms and on Win32.
-
- @ivar _reads: A dictionary mapping L{FileDescriptor} instances to arbitrary
- values (this is essentially a set). Keys in this dictionary will be
- checked for read events.
-
- @ivar _writes: A dictionary mapping L{FileDescriptor} instances to
- arbitrary values (this is essentially a set). Keys in this dictionary
- will be checked for writability.
- """
- implements(IReactorFDSet)
-
- def __init__(self):
- """
- Initialize file descriptor tracking dictionaries and the base class.
- """
- self._reads = {}
- self._writes = {}
- posixbase.PosixReactorBase.__init__(self)
-
-
- def _preenDescriptors(self):
- log.msg("Malformed file descriptor found. Preening lists.")
- readers = self._reads.keys()
- writers = self._writes.keys()
- self._reads.clear()
- self._writes.clear()
- for selDict, selList in ((self._reads, readers),
- (self._writes, writers)):
- for selectable in selList:
- try:
- select.select([selectable], [selectable], [selectable], 0)
- except Exception, e:
- log.msg("bad descriptor %s" % selectable)
- self._disconnectSelectable(selectable, e, False)
- else:
- selDict[selectable] = 1
-
-
- def doSelect(self, timeout):
- """
- Run one iteration of the I/O monitor loop.
-
- This will run all selectables who had input or output readiness
- waiting for them.
- """
- try:
- r, w, ignored = _select(self._reads.keys(),
- self._writes.keys(),
- [], timeout)
- except ValueError:
- # Possibly a file descriptor has gone negative?
- self._preenDescriptors()
- return
- except TypeError:
- # Something *totally* invalid (object w/o fileno, non-integral
- # result) was passed
- log.err()
- self._preenDescriptors()
- return
- except (select.error, socket.error, IOError), se:
- # select(2) encountered an error, perhaps while calling the fileno()
- # method of a socket. (Python 2.6 socket.error is an IOError
- # subclass, but on Python 2.5 and earlier it is not.)
- if se.args[0] in (0, 2):
- # windows does this if it got an empty list
- if (not self._reads) and (not self._writes):
- return
- else:
- raise
- elif se.args[0] == EINTR:
- return
- elif se.args[0] == EBADF:
- self._preenDescriptors()
- return
- else:
- # OK, I really don't know what's going on. Blow up.
- raise
-
- _drdw = self._doReadOrWrite
- _logrun = log.callWithLogger
- for selectables, method, fdset in ((r, "doRead", self._reads),
- (w,"doWrite", self._writes)):
- for selectable in selectables:
- # if this was disconnected in another thread, kill it.
- # ^^^^ --- what the !@#*? serious! -exarkun
- if selectable not in fdset:
- continue
- # This for pausing input when we're not ready for more.
- _logrun(selectable, _drdw, selectable, method, dict)
-
- doIteration = doSelect
-
- def _doReadOrWrite(self, selectable, method, dict):
- try:
- why = getattr(selectable, method)()
- except:
- why = sys.exc_info()[1]
- log.err()
- if why:
- self._disconnectSelectable(selectable, why, method=="doRead")
-
- def addReader(self, reader):
- """
- Add a FileDescriptor for notification of data available to read.
- """
- self._reads[reader] = 1
-
- def addWriter(self, writer):
- """
- Add a FileDescriptor for notification of data available to write.
- """
- self._writes[writer] = 1
-
- def removeReader(self, reader):
- """
- Remove a Selectable for notification of data available to read.
- """
- if reader in self._reads:
- del self._reads[reader]
-
- def removeWriter(self, writer):
- """
- Remove a Selectable for notification of data available to write.
- """
- if writer in self._writes:
- del self._writes[writer]
-
- def removeAll(self):
- return self._removeAll(self._reads, self._writes)
-
-
- def getReaders(self):
- return self._reads.keys()
-
-
- def getWriters(self):
- return self._writes.keys()
-
-
-
-def install():
- """Configure the twisted mainloop to be run using the select() reactor.
- """
- reactor = SelectReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/serialport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/serialport.py
deleted file mode 100755
index 500d8baf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/serialport.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Serial Port Protocol
-"""
-
-# http://twistedmatrix.com/trac/ticket/3725#comment:24
-# Apparently applications use these names even though they should
-# be imported from pyserial
-__all__ = ["serial", "PARITY_ODD", "PARITY_EVEN", "PARITY_NONE",
- "STOPBITS_TWO", "STOPBITS_ONE", "FIVEBITS",
- "EIGHTBITS", "SEVENBITS", "SIXBITS",
-# Name this module is actually trying to export
- "SerialPort"]
-
-# system imports
-import os, sys
-
-# all of them require pyserial at the moment, so check that first
-import serial
-from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD
-from serial import STOPBITS_ONE, STOPBITS_TWO
-from serial import FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS
-
-
-
-class BaseSerialPort:
- """
- Base class for Windows and POSIX serial ports.
-
- @ivar _serialFactory: a pyserial C{serial.Serial} factory, used to create
- the instance stored in C{self._serial}. Overrideable to enable easier
- testing.
-
- @ivar _serial: a pyserial C{serial.Serial} instance used to manage the
- options on the serial port.
- """
-
- _serialFactory = serial.Serial
-
-
- def setBaudRate(self, baudrate):
- if hasattr(self._serial, "setBaudrate"):
- self._serial.setBaudrate(baudrate)
- else:
- self._serial.setBaudRate(baudrate)
-
- def inWaiting(self):
- return self._serial.inWaiting()
-
- def flushInput(self):
- self._serial.flushInput()
-
- def flushOutput(self):
- self._serial.flushOutput()
-
- def sendBreak(self):
- self._serial.sendBreak()
-
- def getDSR(self):
- return self._serial.getDSR()
-
- def getCD(self):
- return self._serial.getCD()
-
- def getRI(self):
- return self._serial.getRI()
-
- def getCTS(self):
- return self._serial.getCTS()
-
- def setDTR(self, on = 1):
- self._serial.setDTR(on)
-
- def setRTS(self, on = 1):
- self._serial.setRTS(on)
-
-class SerialPort(BaseSerialPort):
- pass
-
-# replace SerialPort with appropriate serial port
-if os.name == 'posix':
- from twisted.internet._posixserialport import SerialPort
-elif sys.platform == 'win32':
- from twisted.internet._win32serialport import SerialPort
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/ssl.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/ssl.py
deleted file mode 100755
index 2141f204..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/ssl.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# -*- test-case-name: twisted.test.test_ssl -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-SSL transport. Requires PyOpenSSL (http://pyopenssl.sf.net).
-
-SSL connections require a ContextFactory so they can create SSL contexts.
-End users should only use the ContextFactory classes directly - for SSL
-connections use the reactor.connectSSL/listenSSL and so on, as documented
-in IReactorSSL.
-
-All server context factories should inherit from ContextFactory, and all
-client context factories should inherit from ClientContextFactory. At the
-moment this is not enforced, but in the future it might be.
-
-Future Plans:
- - split module so reactor-specific classes are in a separate module
-"""
-
-# System imports
-from OpenSSL import SSL
-supported = True
-
-from zope.interface import implements, implementsOnly, implementedBy
-
-# Twisted imports
-from twisted.internet import tcp, interfaces
-
-
-class ContextFactory:
- """A factory for SSL context objects, for server SSL connections."""
-
- isClient = 0
-
- def getContext(self):
- """Return a SSL.Context object. override in subclasses."""
- raise NotImplementedError
-
-
-class DefaultOpenSSLContextFactory(ContextFactory):
- """
- L{DefaultOpenSSLContextFactory} is a factory for server-side SSL context
- objects. These objects define certain parameters related to SSL
- handshakes and the subsequent connection.
-
- @ivar _contextFactory: A callable which will be used to create new
- context objects. This is typically L{SSL.Context}.
- """
- _context = None
-
- def __init__(self, privateKeyFileName, certificateFileName,
- sslmethod=SSL.SSLv23_METHOD, _contextFactory=SSL.Context):
- """
- @param privateKeyFileName: Name of a file containing a private key
- @param certificateFileName: Name of a file containing a certificate
- @param sslmethod: The SSL method to use
- """
- self.privateKeyFileName = privateKeyFileName
- self.certificateFileName = certificateFileName
- self.sslmethod = sslmethod
- self._contextFactory = _contextFactory
-
- # Create a context object right now. This is to force validation of
- # the given parameters so that errors are detected earlier rather
- # than later.
- self.cacheContext()
-
-
- def cacheContext(self):
- if self._context is None:
- ctx = self._contextFactory(self.sslmethod)
- # Disallow SSLv2! It's insecure! SSLv3 has been around since
- # 1996. It's time to move on.
- ctx.set_options(SSL.OP_NO_SSLv2)
- ctx.use_certificate_file(self.certificateFileName)
- ctx.use_privatekey_file(self.privateKeyFileName)
- self._context = ctx
-
-
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['_context']
- return d
-
-
- def __setstate__(self, state):
- self.__dict__ = state
-
-
- def getContext(self):
- """
- Return an SSL context.
- """
- return self._context
-
-
-class ClientContextFactory:
- """A context factory for SSL clients."""
-
- isClient = 1
-
- # SSLv23_METHOD allows SSLv2, SSLv3, and TLSv1. We disable SSLv2 below,
- # though.
- method = SSL.SSLv23_METHOD
-
- _contextFactory = SSL.Context
-
- def getContext(self):
- ctx = self._contextFactory(self.method)
- # See comment in DefaultOpenSSLContextFactory about SSLv2.
- ctx.set_options(SSL.OP_NO_SSLv2)
- return ctx
-
-
-
-class Client(tcp.Client):
- """
- I am an SSL client.
- """
-
- implementsOnly(interfaces.ISSLTransport,
- *[i for i in implementedBy(tcp.Client) if i != interfaces.ITLSTransport])
-
- def __init__(self, host, port, bindAddress, ctxFactory, connector, reactor=None):
- # tcp.Client.__init__ depends on self.ctxFactory being set
- self.ctxFactory = ctxFactory
- tcp.Client.__init__(self, host, port, bindAddress, connector, reactor)
-
- def _connectDone(self):
- self.startTLS(self.ctxFactory)
- self.startWriting()
- tcp.Client._connectDone(self)
-
-
-
-class Server(tcp.Server):
- """
- I am an SSL server.
- """
- implements(interfaces.ISSLTransport)
-
- def __init__(self, *args, **kwargs):
- tcp.Server.__init__(self, *args, **kwargs)
- self.startTLS(self.server.ctxFactory)
-
-
-
-class Port(tcp.Port):
- """
- I am an SSL port.
- """
- transport = Server
-
- _type = 'TLS'
-
- def __init__(self, port, factory, ctxFactory, backlog=50, interface='', reactor=None):
- tcp.Port.__init__(self, port, factory, backlog, interface, reactor)
- self.ctxFactory = ctxFactory
-
- # Force some parameter checking in pyOpenSSL. It's better to fail now
- # than after we've set up the transport.
- ctxFactory.getContext()
-
-
- def _getLogPrefix(self, factory):
- """
- Override the normal prefix to include an annotation indicating this is a
- port for TLS connections.
- """
- return tcp.Port._getLogPrefix(self, factory) + ' (TLS)'
-
-
-
-class Connector(tcp.Connector):
- def __init__(self, host, port, factory, contextFactory, timeout, bindAddress, reactor=None):
- self.contextFactory = contextFactory
- tcp.Connector.__init__(self, host, port, factory, timeout, bindAddress, reactor)
-
- # Force some parameter checking in pyOpenSSL. It's better to fail now
- # than after we've set up the transport.
- contextFactory.getContext()
-
-
- def _makeTransport(self):
- return Client(self.host, self.port, self.bindAddress, self.contextFactory, self, self.reactor)
-
-
-
-from twisted.internet._sslverify import DistinguishedName, DN, Certificate
-from twisted.internet._sslverify import CertificateRequest, PrivateCertificate
-from twisted.internet._sslverify import KeyPair
-from twisted.internet._sslverify import OpenSSLCertificateOptions as CertificateOptions
-
-__all__ = [
- "ContextFactory", "DefaultOpenSSLContextFactory", "ClientContextFactory",
-
- 'DistinguishedName', 'DN',
- 'Certificate', 'CertificateRequest', 'PrivateCertificate',
- 'KeyPair',
- 'CertificateOptions',
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/stdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/stdio.py
deleted file mode 100755
index 201e5f16..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/stdio.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Standard input/out/err support.
-
-This module exposes one name, StandardIO, which is a factory that takes an
-IProtocol provider as an argument. It connects that protocol to standard input
-and output on the current process.
-
-It should work on any UNIX and also on Win32 (with some caveats: due to
-platform limitations, it will perform very poorly on Win32).
-
-Future Plans::
-
- support for stderr, perhaps
- Rewrite to use the reactor instead of an ad-hoc mechanism for connecting
- protocols to transport.
-
-
-Maintainer: James Y Knight
-"""
-
-from twisted.python.runtime import platform
-
-if platform.isWindows():
- from twisted.internet import _win32stdio
- StandardIO = _win32stdio.StandardIO
- PipeAddress = _win32stdio.Win32PipeAddress
-
-else:
- from twisted.internet._posixstdio import StandardIO, PipeAddress
-
-__all__ = ['StandardIO', 'PipeAddress']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/task.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/task.py
deleted file mode 100755
index 0c7c32d2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/task.py
+++ /dev/null
@@ -1,793 +0,0 @@
-# -*- test-case-name: twisted.test.test_task,twisted.test.test_cooperator -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Scheduling utility methods and classes.
-
-@author: Jp Calderone
-"""
-
-__metaclass__ = type
-
-import time
-
-from zope.interface import implements
-
-from twisted.python import reflect
-from twisted.python.failure import Failure
-
-from twisted.internet import base, defer
-from twisted.internet.interfaces import IReactorTime
-
-
-class LoopingCall:
- """Call a function repeatedly.
-
- If C{f} returns a deferred, rescheduling will not take place until the
- deferred has fired. The result value is ignored.
-
- @ivar f: The function to call.
- @ivar a: A tuple of arguments to pass the function.
- @ivar kw: A dictionary of keyword arguments to pass to the function.
- @ivar clock: A provider of
- L{twisted.internet.interfaces.IReactorTime}. The default is
- L{twisted.internet.reactor}. Feel free to set this to
- something else, but it probably ought to be set *before*
- calling L{start}.
-
- @type running: C{bool}
- @ivar running: A flag which is C{True} while C{f} is scheduled to be called
- (or is currently being called). It is set to C{True} when L{start} is
- called and set to C{False} when L{stop} is called or if C{f} raises an
- exception. In either case, it will be C{False} by the time the
- C{Deferred} returned by L{start} fires its callback or errback.
-
- @type _expectNextCallAt: C{float}
- @ivar _expectNextCallAt: The time at which this instance most recently
- scheduled itself to run.
-
- @type _realLastTime: C{float}
- @ivar _realLastTime: When counting skips, the time at which the skip
- counter was last invoked.
-
- @type _runAtStart: C{bool}
- @ivar _runAtStart: A flag indicating whether the 'now' argument was passed
- to L{LoopingCall.start}.
- """
-
- call = None
- running = False
- deferred = None
- interval = None
- _expectNextCallAt = 0.0
- _runAtStart = False
- starttime = None
-
- def __init__(self, f, *a, **kw):
- self.f = f
- self.a = a
- self.kw = kw
- from twisted.internet import reactor
- self.clock = reactor
-
-
- def withCount(cls, countCallable):
- """
- An alternate constructor for L{LoopingCall} that makes available the
- number of calls which should have occurred since it was last invoked.
-
- Note that this number is an C{int} value; It represents the discrete
- number of calls that should have been made. For example, if you are
- using a looping call to display an animation with discrete frames, this
- number would be the number of frames to advance.
-
- The count is normally 1, but can be higher. For example, if the reactor
- is blocked and takes too long to invoke the L{LoopingCall}, a Deferred
- returned from a previous call is not fired before an interval has
- elapsed, or if the callable itself blocks for longer than an interval,
- preventing I{itself} from being called.
-
- @param countCallable: A callable that will be invoked each time the
- resulting LoopingCall is run, with an integer specifying the number
- of calls that should have been invoked.
-
- @type countCallable: 1-argument callable which takes an C{int}
-
- @return: An instance of L{LoopingCall} with call counting enabled,
- which provides the count as the first positional argument.
-
- @rtype: L{LoopingCall}
-
- @since: 9.0
- """
-
- def counter():
- now = self.clock.seconds()
- lastTime = self._realLastTime
- if lastTime is None:
- lastTime = self.starttime
- if self._runAtStart:
- lastTime -= self.interval
- self._realLastTime = now
- lastInterval = self._intervalOf(lastTime)
- thisInterval = self._intervalOf(now)
- count = thisInterval - lastInterval
- return countCallable(count)
-
- self = cls(counter)
-
- self._realLastTime = None
-
- return self
-
- withCount = classmethod(withCount)
-
-
- def _intervalOf(self, t):
- """
- Determine the number of intervals passed as of the given point in
- time.
-
- @param t: The specified time (from the start of the L{LoopingCall}) to
- be measured in intervals
-
- @return: The C{int} number of intervals which have passed as of the
- given point in time.
- """
- elapsedTime = t - self.starttime
- intervalNum = int(elapsedTime / self.interval)
- return intervalNum
-
-
- def start(self, interval, now=True):
- """
- Start running function every interval seconds.
-
- @param interval: The number of seconds between calls. May be
- less than one. Precision will depend on the underlying
- platform, the available hardware, and the load on the system.
-
- @param now: If True, run this call right now. Otherwise, wait
- until the interval has elapsed before beginning.
-
- @return: A Deferred whose callback will be invoked with
- C{self} when C{self.stop} is called, or whose errback will be
- invoked when the function raises an exception or returned a
- deferred that has its errback invoked.
- """
- assert not self.running, ("Tried to start an already running "
- "LoopingCall.")
- if interval < 0:
- raise ValueError, "interval must be >= 0"
- self.running = True
- d = self.deferred = defer.Deferred()
- self.starttime = self.clock.seconds()
- self._expectNextCallAt = self.starttime
- self.interval = interval
- self._runAtStart = now
- if now:
- self()
- else:
- self._reschedule()
- return d
-
- def stop(self):
- """Stop running function.
- """
- assert self.running, ("Tried to stop a LoopingCall that was "
- "not running.")
- self.running = False
- if self.call is not None:
- self.call.cancel()
- self.call = None
- d, self.deferred = self.deferred, None
- d.callback(self)
-
- def reset(self):
- """
- Skip the next iteration and reset the timer.
-
- @since: 11.1
- """
- assert self.running, ("Tried to reset a LoopingCall that was "
- "not running.")
- if self.call is not None:
- self.call.cancel()
- self.call = None
- self._expectNextCallAt = self.clock.seconds()
- self._reschedule()
-
- def __call__(self):
- def cb(result):
- if self.running:
- self._reschedule()
- else:
- d, self.deferred = self.deferred, None
- d.callback(self)
-
- def eb(failure):
- self.running = False
- d, self.deferred = self.deferred, None
- d.errback(failure)
-
- self.call = None
- d = defer.maybeDeferred(self.f, *self.a, **self.kw)
- d.addCallback(cb)
- d.addErrback(eb)
-
-
- def _reschedule(self):
- """
- Schedule the next iteration of this looping call.
- """
- if self.interval == 0:
- self.call = self.clock.callLater(0, self)
- return
-
- currentTime = self.clock.seconds()
- # Find how long is left until the interval comes around again.
- untilNextTime = (self._expectNextCallAt - currentTime) % self.interval
- # Make sure it is in the future, in case more than one interval worth
- # of time passed since the previous call was made.
- nextTime = max(
- self._expectNextCallAt + self.interval, currentTime + untilNextTime)
- # If the interval falls on the current time exactly, skip it and
- # schedule the call for the next interval.
- if nextTime == currentTime:
- nextTime += self.interval
- self._expectNextCallAt = nextTime
- self.call = self.clock.callLater(nextTime - currentTime, self)
-
-
- def __repr__(self):
- if hasattr(self.f, 'func_name'):
- func = self.f.func_name
- if hasattr(self.f, 'im_class'):
- func = self.f.im_class.__name__ + '.' + func
- else:
- func = reflect.safe_repr(self.f)
-
- return 'LoopingCall<%r>(%s, *%s, **%s)' % (
- self.interval, func, reflect.safe_repr(self.a),
- reflect.safe_repr(self.kw))
-
-
-
-class SchedulerError(Exception):
- """
- The operation could not be completed because the scheduler or one of its
- tasks was in an invalid state. This exception should not be raised
- directly, but is a superclass of various scheduler-state-related
- exceptions.
- """
-
-
-
-class SchedulerStopped(SchedulerError):
- """
- The operation could not complete because the scheduler was stopped in
- progress or was already stopped.
- """
-
-
-
-class TaskFinished(SchedulerError):
- """
- The operation could not complete because the task was already completed,
- stopped, encountered an error or otherwise permanently stopped running.
- """
-
-
-
-class TaskDone(TaskFinished):
- """
- The operation could not complete because the task was already completed.
- """
-
-
-
-class TaskStopped(TaskFinished):
- """
- The operation could not complete because the task was stopped.
- """
-
-
-
-class TaskFailed(TaskFinished):
- """
- The operation could not complete because the task died with an unhandled
- error.
- """
-
-
-
-class NotPaused(SchedulerError):
- """
- This exception is raised when a task is resumed which was not previously
- paused.
- """
-
-
-
-class _Timer(object):
- MAX_SLICE = 0.01
- def __init__(self):
- self.end = time.time() + self.MAX_SLICE
-
-
- def __call__(self):
- return time.time() >= self.end
-
-
-
-_EPSILON = 0.00000001
-def _defaultScheduler(x):
- from twisted.internet import reactor
- return reactor.callLater(_EPSILON, x)
-
-
-class CooperativeTask(object):
- """
- A L{CooperativeTask} is a task object inside a L{Cooperator}, which can be
- paused, resumed, and stopped. It can also have its completion (or
- termination) monitored.
-
- @see: L{CooperativeTask.cooperate}
-
- @ivar _iterator: the iterator to iterate when this L{CooperativeTask} is
- asked to do work.
-
- @ivar _cooperator: the L{Cooperator} that this L{CooperativeTask}
- participates in, which is used to re-insert it upon resume.
-
- @ivar _deferreds: the list of L{defer.Deferred}s to fire when this task
- completes, fails, or finishes.
-
- @type _deferreds: L{list}
-
- @type _cooperator: L{Cooperator}
-
- @ivar _pauseCount: the number of times that this L{CooperativeTask} has
- been paused; if 0, it is running.
-
- @type _pauseCount: L{int}
-
- @ivar _completionState: The completion-state of this L{CooperativeTask}.
- C{None} if the task is not yet completed, an instance of L{TaskStopped}
- if C{stop} was called to stop this task early, of L{TaskFailed} if the
- application code in the iterator raised an exception which caused it to
- terminate, and of L{TaskDone} if it terminated normally via raising
- L{StopIteration}.
-
- @type _completionState: L{TaskFinished}
- """
-
- def __init__(self, iterator, cooperator):
- """
- A private constructor: to create a new L{CooperativeTask}, see
- L{Cooperator.cooperate}.
- """
- self._iterator = iterator
- self._cooperator = cooperator
- self._deferreds = []
- self._pauseCount = 0
- self._completionState = None
- self._completionResult = None
- cooperator._addTask(self)
-
-
- def whenDone(self):
- """
- Get a L{defer.Deferred} notification of when this task is complete.
-
- @return: a L{defer.Deferred} that fires with the C{iterator} that this
- L{CooperativeTask} was created with when the iterator has been
- exhausted (i.e. its C{next} method has raised L{StopIteration}), or
- fails with the exception raised by C{next} if it raises some other
- exception.
-
- @rtype: L{defer.Deferred}
- """
- d = defer.Deferred()
- if self._completionState is None:
- self._deferreds.append(d)
- else:
- d.callback(self._completionResult)
- return d
-
-
- def pause(self):
- """
- Pause this L{CooperativeTask}. Stop doing work until
- L{CooperativeTask.resume} is called. If C{pause} is called more than
- once, C{resume} must be called an equal number of times to resume this
- task.
-
- @raise TaskFinished: if this task has already finished or completed.
- """
- self._checkFinish()
- self._pauseCount += 1
- if self._pauseCount == 1:
- self._cooperator._removeTask(self)
-
-
- def resume(self):
- """
- Resume processing of a paused L{CooperativeTask}.
-
- @raise NotPaused: if this L{CooperativeTask} is not paused.
- """
- if self._pauseCount == 0:
- raise NotPaused()
- self._pauseCount -= 1
- if self._pauseCount == 0 and self._completionState is None:
- self._cooperator._addTask(self)
-
-
- def _completeWith(self, completionState, deferredResult):
- """
- @param completionState: a L{TaskFinished} exception or a subclass
- thereof, indicating what exception should be raised when subsequent
- operations are performed.
-
- @param deferredResult: the result to fire all the deferreds with.
- """
- self._completionState = completionState
- self._completionResult = deferredResult
- if not self._pauseCount:
- self._cooperator._removeTask(self)
-
- # The Deferreds need to be invoked after all this is completed, because
- # a Deferred may want to manipulate other tasks in a Cooperator. For
- # example, if you call "stop()" on a cooperator in a callback on a
- # Deferred returned from whenDone(), this CooperativeTask must be gone
- # from the Cooperator by that point so that _completeWith is not
- # invoked reentrantly; that would cause these Deferreds to blow up with
- # an AlreadyCalledError, or the _removeTask to fail with a ValueError.
- for d in self._deferreds:
- d.callback(deferredResult)
-
-
- def stop(self):
- """
- Stop further processing of this task.
-
- @raise TaskFinished: if this L{CooperativeTask} has previously
- completed, via C{stop}, completion, or failure.
- """
- self._checkFinish()
- self._completeWith(TaskStopped(), Failure(TaskStopped()))
-
-
- def _checkFinish(self):
- """
- If this task has been stopped, raise the appropriate subclass of
- L{TaskFinished}.
- """
- if self._completionState is not None:
- raise self._completionState
-
-
- def _oneWorkUnit(self):
- """
- Perform one unit of work for this task, retrieving one item from its
- iterator, stopping if there are no further items in the iterator, and
- pausing if the result was a L{defer.Deferred}.
- """
- try:
- result = self._iterator.next()
- except StopIteration:
- self._completeWith(TaskDone(), self._iterator)
- except:
- self._completeWith(TaskFailed(), Failure())
- else:
- if isinstance(result, defer.Deferred):
- self.pause()
- def failLater(f):
- self._completeWith(TaskFailed(), f)
- result.addCallbacks(lambda result: self.resume(),
- failLater)
-
-
-
-class Cooperator(object):
- """
- Cooperative task scheduler.
- """
-
- def __init__(self,
- terminationPredicateFactory=_Timer,
- scheduler=_defaultScheduler,
- started=True):
- """
- Create a scheduler-like object to which iterators may be added.
-
- @param terminationPredicateFactory: A no-argument callable which will
- be invoked at the beginning of each step and should return a
- no-argument callable which will return True when the step should be
- terminated. The default factory is time-based and allows iterators to
- run for 1/100th of a second at a time.
-
- @param scheduler: A one-argument callable which takes a no-argument
- callable and should invoke it at some future point. This will be used
- to schedule each step of this Cooperator.
-
- @param started: A boolean which indicates whether iterators should be
- stepped as soon as they are added, or if they will be queued up until
- L{Cooperator.start} is called.
- """
- self._tasks = []
- self._metarator = iter(())
- self._terminationPredicateFactory = terminationPredicateFactory
- self._scheduler = scheduler
- self._delayedCall = None
- self._stopped = False
- self._started = started
-
-
- def coiterate(self, iterator, doneDeferred=None):
- """
- Add an iterator to the list of iterators this L{Cooperator} is
- currently running.
-
- @param doneDeferred: If specified, this will be the Deferred used as
- the completion deferred. It is suggested that you use the default,
- which creates a new Deferred for you.
-
- @return: a Deferred that will fire when the iterator finishes.
- """
- if doneDeferred is None:
- doneDeferred = defer.Deferred()
- CooperativeTask(iterator, self).whenDone().chainDeferred(doneDeferred)
- return doneDeferred
-
-
- def cooperate(self, iterator):
- """
- Start running the given iterator as a long-running cooperative task, by
- calling next() on it as a periodic timed event.
-
- @param iterator: the iterator to invoke.
-
- @return: a L{CooperativeTask} object representing this task.
- """
- return CooperativeTask(iterator, self)
-
-
- def _addTask(self, task):
- """
- Add a L{CooperativeTask} object to this L{Cooperator}.
- """
- if self._stopped:
- self._tasks.append(task) # XXX silly, I know, but _completeWith
- # does the inverse
- task._completeWith(SchedulerStopped(), Failure(SchedulerStopped()))
- else:
- self._tasks.append(task)
- self._reschedule()
-
-
- def _removeTask(self, task):
- """
- Remove a L{CooperativeTask} from this L{Cooperator}.
- """
- self._tasks.remove(task)
- # If no work left to do, cancel the delayed call:
- if not self._tasks and self._delayedCall:
- self._delayedCall.cancel()
- self._delayedCall = None
-
-
- def _tasksWhileNotStopped(self):
- """
- Yield all L{CooperativeTask} objects in a loop as long as this
- L{Cooperator}'s termination condition has not been met.
- """
- terminator = self._terminationPredicateFactory()
- while self._tasks:
- for t in self._metarator:
- yield t
- if terminator():
- return
- self._metarator = iter(self._tasks)
-
-
- def _tick(self):
- """
- Run one scheduler tick.
- """
- self._delayedCall = None
- for taskObj in self._tasksWhileNotStopped():
- taskObj._oneWorkUnit()
- self._reschedule()
-
-
- _mustScheduleOnStart = False
- def _reschedule(self):
- if not self._started:
- self._mustScheduleOnStart = True
- return
- if self._delayedCall is None and self._tasks:
- self._delayedCall = self._scheduler(self._tick)
-
-
- def start(self):
- """
- Begin scheduling steps.
- """
- self._stopped = False
- self._started = True
- if self._mustScheduleOnStart:
- del self._mustScheduleOnStart
- self._reschedule()
-
-
- def stop(self):
- """
- Stop scheduling steps. Errback the completion Deferreds of all
- iterators which have been added and forget about them.
- """
- self._stopped = True
- for taskObj in self._tasks:
- taskObj._completeWith(SchedulerStopped(),
- Failure(SchedulerStopped()))
- self._tasks = []
- if self._delayedCall is not None:
- self._delayedCall.cancel()
- self._delayedCall = None
-
-
-
-_theCooperator = Cooperator()
-
-def coiterate(iterator):
- """
- Cooperatively iterate over the given iterator, dividing runtime between it
- and all other iterators which have been passed to this function and not yet
- exhausted.
-
- @param iterator: the iterator to invoke.
-
- @return: a Deferred that will fire when the iterator finishes.
- """
- return _theCooperator.coiterate(iterator)
-
-
-
-def cooperate(iterator):
- """
- Start running the given iterator as a long-running cooperative task, by
- calling next() on it as a periodic timed event.
-
- @param iterator: the iterator to invoke.
-
- @return: a L{CooperativeTask} object representing this task.
- """
- return _theCooperator.cooperate(iterator)
-
-
-
-class Clock:
- """
- Provide a deterministic, easily-controlled implementation of
- L{IReactorTime.callLater}. This is commonly useful for writing
- deterministic unit tests for code which schedules events using this API.
- """
- implements(IReactorTime)
-
- rightNow = 0.0
-
- def __init__(self):
- self.calls = []
-
-
- def seconds(self):
- """
- Pretend to be time.time(). This is used internally when an operation
- such as L{IDelayedCall.reset} needs to determine a a time value
- relative to the current time.
-
- @rtype: C{float}
- @return: The time which should be considered the current time.
- """
- return self.rightNow
-
-
- def _sortCalls(self):
- """
- Sort the pending calls according to the time they are scheduled.
- """
- self.calls.sort(lambda a, b: cmp(a.getTime(), b.getTime()))
-
-
- def callLater(self, when, what, *a, **kw):
- """
- See L{twisted.internet.interfaces.IReactorTime.callLater}.
- """
- dc = base.DelayedCall(self.seconds() + when,
- what, a, kw,
- self.calls.remove,
- lambda c: None,
- self.seconds)
- self.calls.append(dc)
- self._sortCalls()
- return dc
-
-
- def getDelayedCalls(self):
- """
- See L{twisted.internet.interfaces.IReactorTime.getDelayedCalls}
- """
- return self.calls
-
-
- def advance(self, amount):
- """
- Move time on this clock forward by the given amount and run whatever
- pending calls should be run.
-
- @type amount: C{float}
- @param amount: The number of seconds which to advance this clock's
- time.
- """
- self.rightNow += amount
- self._sortCalls()
- while self.calls and self.calls[0].getTime() <= self.seconds():
- call = self.calls.pop(0)
- call.called = 1
- call.func(*call.args, **call.kw)
- self._sortCalls()
-
-
- def pump(self, timings):
- """
- Advance incrementally by the given set of times.
-
- @type timings: iterable of C{float}
- """
- for amount in timings:
- self.advance(amount)
-
-
-
-def deferLater(clock, delay, callable, *args, **kw):
- """
- Call the given function after a certain period of time has passed.
-
- @type clock: L{IReactorTime} provider
- @param clock: The object which will be used to schedule the delayed
- call.
-
- @type delay: C{float} or C{int}
- @param delay: The number of seconds to wait before calling the function.
-
- @param callable: The object to call after the delay.
-
- @param *args: The positional arguments to pass to C{callable}.
-
- @param **kw: The keyword arguments to pass to C{callable}.
-
- @rtype: L{defer.Deferred}
-
- @return: A deferred that fires with the result of the callable when the
- specified time has elapsed.
- """
- def deferLaterCancel(deferred):
- delayedCall.cancel()
- d = defer.Deferred(deferLaterCancel)
- d.addCallback(lambda ignored: callable(*args, **kw))
- delayedCall = clock.callLater(delay, d.callback, None)
- return d
-
-
-
-__all__ = [
- 'LoopingCall',
-
- 'Clock',
-
- 'SchedulerStopped', 'Cooperator', 'coiterate',
-
- 'deferLater',
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tcp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tcp.py
deleted file mode 100755
index d1f89c38..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tcp.py
+++ /dev/null
@@ -1,1172 +0,0 @@
-# -*- test-case-name: twisted.test.test_tcp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Various asynchronous TCP/IP classes.
-
-End users shouldn't use this module directly - use the reactor APIs instead.
-"""
-
-
-# System Imports
-import types
-import socket
-import sys
-import operator
-import struct
-
-from zope.interface import implements
-
-from twisted.python.runtime import platformType
-from twisted.python import versions, deprecate
-
-try:
- # Try to get the memory BIO based startTLS implementation, available since
- # pyOpenSSL 0.10
- from twisted.internet._newtls import (
- ConnectionMixin as _TLSConnectionMixin,
- ClientMixin as _TLSClientMixin,
- ServerMixin as _TLSServerMixin)
-except ImportError:
- try:
- # Try to get the socket BIO based startTLS implementation, available in
- # all pyOpenSSL versions
- from twisted.internet._oldtls import (
- ConnectionMixin as _TLSConnectionMixin,
- ClientMixin as _TLSClientMixin,
- ServerMixin as _TLSServerMixin)
- except ImportError:
- # There is no version of startTLS available
- class _TLSConnectionMixin(object):
- TLS = False
- class _TLSClientMixin(object):
- pass
- class _TLSServerMixin(object):
- pass
-
-if platformType == 'win32':
- # no such thing as WSAEPERM or error code 10001 according to winsock.h or MSDN
- EPERM = object()
- from errno import WSAEINVAL as EINVAL
- from errno import WSAEWOULDBLOCK as EWOULDBLOCK
- from errno import WSAEINPROGRESS as EINPROGRESS
- from errno import WSAEALREADY as EALREADY
- from errno import WSAECONNRESET as ECONNRESET
- from errno import WSAEISCONN as EISCONN
- from errno import WSAENOTCONN as ENOTCONN
- from errno import WSAEINTR as EINTR
- from errno import WSAENOBUFS as ENOBUFS
- from errno import WSAEMFILE as EMFILE
- # No such thing as WSAENFILE, either.
- ENFILE = object()
- # Nor ENOMEM
- ENOMEM = object()
- EAGAIN = EWOULDBLOCK
- from errno import WSAECONNRESET as ECONNABORTED
-
- from twisted.python.win32 import formatError as strerror
-else:
- from errno import EPERM
- from errno import EINVAL
- from errno import EWOULDBLOCK
- from errno import EINPROGRESS
- from errno import EALREADY
- from errno import ECONNRESET
- from errno import EISCONN
- from errno import ENOTCONN
- from errno import EINTR
- from errno import ENOBUFS
- from errno import EMFILE
- from errno import ENFILE
- from errno import ENOMEM
- from errno import EAGAIN
- from errno import ECONNABORTED
-
- from os import strerror
-
-
-from errno import errorcode
-
-# Twisted Imports
-from twisted.internet import base, address, fdesc
-from twisted.internet.task import deferLater
-from twisted.python import log, failure, reflect
-from twisted.python.util import unsignedID, untilConcludes
-from twisted.internet.error import CannotListenError
-from twisted.internet import abstract, main, interfaces, error
-
-# Not all platforms have, or support, this flag.
-_AI_NUMERICSERV = getattr(socket, "AI_NUMERICSERV", 0)
-
-
-
-class _SocketCloser(object):
- _socketShutdownMethod = 'shutdown'
-
- def _closeSocket(self, orderly):
- # The call to shutdown() before close() isn't really necessary, because
- # we set FD_CLOEXEC now, which will ensure this is the only process
- # holding the FD, thus ensuring close() really will shutdown the TCP
- # socket. However, do it anyways, just to be safe.
- skt = self.socket
- try:
- if orderly:
- if self._socketShutdownMethod is not None:
- getattr(skt, self._socketShutdownMethod)(2)
- else:
- # Set SO_LINGER to 1,0 which, by convention, causes a
- # connection reset to be sent when close is called,
- # instead of the standard FIN shutdown sequence.
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
- struct.pack("ii", 1, 0))
-
- except socket.error:
- pass
- try:
- skt.close()
- except socket.error:
- pass
-
-
-
-class _AbortingMixin(object):
- """
- Common implementation of C{abortConnection}.
-
- @ivar _aborting: Set to C{True} when C{abortConnection} is called.
- @type _aborting: C{bool}
- """
- _aborting = False
-
- def abortConnection(self):
- """
- Aborts the connection immediately, dropping any buffered data.
-
- @since: 11.1
- """
- if self.disconnected or self._aborting:
- return
- self._aborting = True
- self.stopReading()
- self.stopWriting()
- self.doRead = lambda *args, **kwargs: None
- self.doWrite = lambda *args, **kwargs: None
- self.reactor.callLater(0, self.connectionLost,
- failure.Failure(error.ConnectionAborted()))
-
-
-
-class Connection(_TLSConnectionMixin, abstract.FileDescriptor, _SocketCloser,
- _AbortingMixin):
- """
- Superclass of all socket-based FileDescriptors.
-
- This is an abstract superclass of all objects which represent a TCP/IP
- connection based socket.
-
- @ivar logstr: prefix used when logging events related to this connection.
- @type logstr: C{str}
- """
- implements(interfaces.ITCPTransport, interfaces.ISystemHandle)
-
-
- def __init__(self, skt, protocol, reactor=None):
- abstract.FileDescriptor.__init__(self, reactor=reactor)
- self.socket = skt
- self.socket.setblocking(0)
- self.fileno = skt.fileno
- self.protocol = protocol
-
-
- def getHandle(self):
- """Return the socket for this connection."""
- return self.socket
-
-
- def doRead(self):
- """Calls self.protocol.dataReceived with all available data.
-
- This reads up to self.bufferSize bytes of data from its socket, then
- calls self.dataReceived(data) to process it. If the connection is not
- lost through an error in the physical recv(), this function will return
- the result of the dataReceived call.
- """
- try:
- data = self.socket.recv(self.bufferSize)
- except socket.error, se:
- if se.args[0] == EWOULDBLOCK:
- return
- else:
- return main.CONNECTION_LOST
-
- return self._dataReceived(data)
-
-
- def _dataReceived(self, data):
- if not data:
- return main.CONNECTION_DONE
- rval = self.protocol.dataReceived(data)
- if rval is not None:
- offender = self.protocol.dataReceived
- warningFormat = (
- 'Returning a value other than None from %(fqpn)s is '
- 'deprecated since %(version)s.')
- warningString = deprecate.getDeprecationWarningString(
- offender, versions.Version('Twisted', 11, 0, 0),
- format=warningFormat)
- deprecate.warnAboutFunction(offender, warningString)
- return rval
-
-
- def writeSomeData(self, data):
- """
- Write as much as possible of the given data to this TCP connection.
-
- This sends up to C{self.SEND_LIMIT} bytes from C{data}. If the
- connection is lost, an exception is returned. Otherwise, the number
- of bytes successfully written is returned.
- """
- # Limit length of buffer to try to send, because some OSes are too
- # stupid to do so themselves (ahem windows)
- limitedData = buffer(data, 0, self.SEND_LIMIT)
-
- try:
- return untilConcludes(self.socket.send, limitedData)
- except socket.error, se:
- if se.args[0] in (EWOULDBLOCK, ENOBUFS):
- return 0
- else:
- return main.CONNECTION_LOST
-
-
- def _closeWriteConnection(self):
- try:
- getattr(self.socket, self._socketShutdownMethod)(1)
- except socket.error:
- pass
- p = interfaces.IHalfCloseableProtocol(self.protocol, None)
- if p:
- try:
- p.writeConnectionLost()
- except:
- f = failure.Failure()
- log.err()
- self.connectionLost(f)
-
-
- def readConnectionLost(self, reason):
- p = interfaces.IHalfCloseableProtocol(self.protocol, None)
- if p:
- try:
- p.readConnectionLost()
- except:
- log.err()
- self.connectionLost(failure.Failure())
- else:
- self.connectionLost(reason)
-
-
-
- def connectionLost(self, reason):
- """See abstract.FileDescriptor.connectionLost().
- """
- # Make sure we're not called twice, which can happen e.g. if
- # abortConnection() is called from protocol's dataReceived and then
- # code immediately after throws an exception that reaches the
- # reactor. We can't rely on "disconnected" attribute for this check
- # since twisted.internet._oldtls does evil things to it:
- if not hasattr(self, "socket"):
- return
- abstract.FileDescriptor.connectionLost(self, reason)
- self._closeSocket(not reason.check(error.ConnectionAborted))
- protocol = self.protocol
- del self.protocol
- del self.socket
- del self.fileno
- protocol.connectionLost(reason)
-
-
- logstr = "Uninitialized"
-
- def logPrefix(self):
- """Return the prefix to log with when I own the logging thread.
- """
- return self.logstr
-
- def getTcpNoDelay(self):
- return operator.truth(self.socket.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY))
-
- def setTcpNoDelay(self, enabled):
- self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, enabled)
-
- def getTcpKeepAlive(self):
- return operator.truth(self.socket.getsockopt(socket.SOL_SOCKET,
- socket.SO_KEEPALIVE))
-
- def setTcpKeepAlive(self, enabled):
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, enabled)
-
-
-
-
-class _BaseBaseClient(object):
- """
- Code shared with other (non-POSIX) reactors for management of general
- outgoing connections.
-
- Requirements upon subclasses are documented as instance variables rather
- than abstract methods, in order to avoid MRO confusion, since this base is
- mixed in to unfortunately weird and distinctive multiple-inheritance
- hierarchies and many of these attributes are provided by peer classes
- rather than descendant classes in those hierarchies.
-
- @ivar addressFamily: The address family constant (C{socket.AF_INET},
- C{socket.AF_INET6}, C{socket.AF_UNIX}) of the underlying socket of this
- client connection.
- @type addressFamily: C{int}
-
- @ivar socketType: The socket type constant (C{socket.SOCK_STREAM} or
- C{socket.SOCK_DGRAM}) of the underlying socket.
- @type socketType: C{int}
-
- @ivar _requiresResolution: A flag indicating whether the address of this
- client will require name resolution. C{True} if the hostname of said
- address indicates a name that must be resolved by hostname lookup,
- C{False} if it indicates an IP address literal.
- @type _requiresResolution: C{bool}
-
- @cvar _commonConnection: Subclasses must provide this attribute, which
- indicates the L{Connection}-alike class to invoke C{__init__} and
- C{connectionLost} on.
- @type _commonConnection: C{type}
-
- @ivar _stopReadingAndWriting: Subclasses must implement in order to remove
- this transport from its reactor's notifications in response to a
- terminated connection attempt.
- @type _stopReadingAndWriting: 0-argument callable returning C{None}
-
- @ivar _closeSocket: Subclasses must implement in order to close the socket
- in response to a terminated connection attempt.
- @type _closeSocket: 1-argument callable; see L{_SocketCloser._closeSocket}
-
- @ivar _collectSocketDetails: Clean up references to the attached socket in
- its underlying OS resource (such as a file descriptor or file handle),
- as part of post connection-failure cleanup.
- @type _collectSocketDetails: 0-argument callable returning C{None}.
-
- @ivar reactor: The class pointed to by C{_commonConnection} should set this
- attribute in its constructor.
- @type reactor: L{twisted.internet.interfaces.IReactorTime},
- L{twisted.internet.interfaces.IReactorCore},
- L{twisted.internet.interfaces.IReactorFDSet}
- """
-
- addressFamily = socket.AF_INET
- socketType = socket.SOCK_STREAM
-
- def _finishInit(self, whenDone, skt, error, reactor):
- """
- Called by subclasses to continue to the stage of initialization where
- the socket connect attempt is made.
-
- @param whenDone: A 0-argument callable to invoke once the connection is
- set up. This is C{None} if the connection could not be prepared
- due to a previous error.
-
- @param skt: The socket object to use to perform the connection.
- @type skt: C{socket._socketobject}
-
- @param error: The error to fail the connection with.
-
- @param reactor: The reactor to use for this client.
- @type reactor: L{twisted.internet.interfaces.IReactorTime}
- """
- if whenDone:
- self._commonConnection.__init__(self, skt, None, reactor)
- reactor.callLater(0, whenDone)
- else:
- reactor.callLater(0, self.failIfNotConnected, error)
-
-
- def resolveAddress(self):
- """
- Resolve the name that was passed to this L{_BaseBaseClient}, if
- necessary, and then move on to attempting the connection once an
- address has been determined. (The connection will be attempted
- immediately within this function if either name resolution can be
- synchronous or the address was an IP address literal.)
-
- @note: You don't want to call this method from outside, as it won't do
- anything useful; it's just part of the connection bootstrapping
- process. Also, although this method is on L{_BaseBaseClient} for
- historical reasons, it's not used anywhere except for L{Client}
- itself.
-
- @return: C{None}
- """
- if self._requiresResolution:
- d = self.reactor.resolve(self.addr[0])
- d.addCallback(lambda n: (n,) + self.addr[1:])
- d.addCallbacks(self._setRealAddress, self.failIfNotConnected)
- else:
- self._setRealAddress(self.addr)
-
-
- def _setRealAddress(self, address):
- """
- Set the resolved address of this L{_BaseBaseClient} and initiate the
- connection attempt.
-
- @param address: Depending on whether this is an IPv4 or IPv6 connection
- attempt, a 2-tuple of C{(host, port)} or a 4-tuple of C{(host,
- port, flow, scope)}. At this point it is a fully resolved address,
- and the 'host' portion will always be an IP address, not a DNS
- name.
- """
- self.realAddress = address
- self.doConnect()
-
-
- def failIfNotConnected(self, err):
- """
- Generic method called when the attemps to connect failed. It basically
- cleans everything it can: call connectionFailed, stop read and write,
- delete socket related members.
- """
- if (self.connected or self.disconnected or
- not hasattr(self, "connector")):
- return
-
- self._stopReadingAndWriting()
- try:
- self._closeSocket(True)
- except AttributeError:
- pass
- else:
- self._collectSocketDetails()
- self.connector.connectionFailed(failure.Failure(err))
- del self.connector
-
-
- def stopConnecting(self):
- """
- If a connection attempt is still outstanding (i.e. no connection is
- yet established), immediately stop attempting to connect.
- """
- self.failIfNotConnected(error.UserError())
-
-
- def connectionLost(self, reason):
- """
- Invoked by lower-level logic when it's time to clean the socket up.
- Depending on the state of the connection, either inform the attached
- L{Connector} that the connection attempt has failed, or inform the
- connected L{IProtocol} that the established connection has been lost.
-
- @param reason: the reason that the connection was terminated
- @type reason: L{Failure}
- """
- if not self.connected:
- self.failIfNotConnected(error.ConnectError(string=reason))
- else:
- self._commonConnection.connectionLost(self, reason)
- self.connector.connectionLost(reason)
-
-
-
-class BaseClient(_BaseBaseClient, _TLSClientMixin, Connection):
- """
- A base class for client TCP (and similiar) sockets.
-
- @ivar realAddress: The address object that will be used for socket.connect;
- this address is an address tuple (the number of elements dependent upon
- the address family) which does not contain any names which need to be
- resolved.
- @type realAddress: C{tuple}
-
- @ivar _base: L{Connection}, which is the base class of this class which has
- all of the useful file descriptor methods. This is used by
- L{_TLSServerMixin} to call the right methods to directly manipulate the
- transport, as is necessary for writing TLS-encrypted bytes (whereas
- those methods on L{Server} will go through another layer of TLS if it
- has been enabled).
- """
-
- _base = Connection
- _commonConnection = Connection
-
- def _stopReadingAndWriting(self):
- """
- Implement the POSIX-ish (i.e.
- L{twisted.internet.interfaces.IReactorFDSet}) method of detaching this
- socket from the reactor for L{_BaseBaseClient}.
- """
- if hasattr(self, "reactor"):
- # this doesn't happen if we failed in __init__
- self.stopReading()
- self.stopWriting()
-
-
- def _collectSocketDetails(self):
- """
- Clean up references to the socket and its file descriptor.
-
- @see: L{_BaseBaseClient}
- """
- del self.socket, self.fileno
-
-
- def createInternetSocket(self):
- """(internal) Create a non-blocking socket using
- self.addressFamily, self.socketType.
- """
- s = socket.socket(self.addressFamily, self.socketType)
- s.setblocking(0)
- fdesc._setCloseOnExec(s.fileno())
- return s
-
-
- def doConnect(self):
- """
- Initiate the outgoing connection attempt.
-
- @note: Applications do not need to call this method; it will be invoked
- internally as part of L{IReactorTCP.connectTCP}.
- """
- self.doWrite = self.doConnect
- self.doRead = self.doConnect
- if not hasattr(self, "connector"):
- # this happens when connection failed but doConnect
- # was scheduled via a callLater in self._finishInit
- return
-
- err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
- if err:
- self.failIfNotConnected(error.getConnectError((err, strerror(err))))
- return
-
- # doConnect gets called twice. The first time we actually need to
- # start the connection attempt. The second time we don't really
- # want to (SO_ERROR above will have taken care of any errors, and if
- # it reported none, the mere fact that doConnect was called again is
- # sufficient to indicate that the connection has succeeded), but it
- # is not /particularly/ detrimental to do so. This should get
- # cleaned up some day, though.
- try:
- connectResult = self.socket.connect_ex(self.realAddress)
- except socket.error, se:
- connectResult = se.args[0]
- if connectResult:
- if connectResult == EISCONN:
- pass
- # on Windows EINVAL means sometimes that we should keep trying:
- # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/connect_2.asp
- elif ((connectResult in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or
- (connectResult == EINVAL and platformType == "win32")):
- self.startReading()
- self.startWriting()
- return
- else:
- self.failIfNotConnected(error.getConnectError((connectResult, strerror(connectResult))))
- return
-
- # If I have reached this point without raising or returning, that means
- # that the socket is connected.
- del self.doWrite
- del self.doRead
- # we first stop and then start, to reset any references to the old doRead
- self.stopReading()
- self.stopWriting()
- self._connectDone()
-
-
- def _connectDone(self):
- """
- This is a hook for when a connection attempt has succeeded.
-
- Here, we build the protocol from the
- L{twisted.internet.protocol.ClientFactory} that was passed in, compute
- a log string, begin reading so as to send traffic to the newly built
- protocol, and finally hook up the protocol itself.
-
- This hook is overridden by L{ssl.Client} to initiate the TLS protocol.
- """
- self.protocol = self.connector.buildProtocol(self.getPeer())
- self.connected = 1
- logPrefix = self._getLogPrefix(self.protocol)
- self.logstr = "%s,client" % logPrefix
- self.startReading()
- self.protocol.makeConnection(self)
-
-
-
-_NUMERIC_ONLY = socket.AI_NUMERICHOST | _AI_NUMERICSERV
-
-def _resolveIPv6(ip, port):
- """
- Resolve an IPv6 literal into an IPv6 address.
-
- This is necessary to resolve any embedded scope identifiers to the relevant
- C{sin6_scope_id} for use with C{socket.connect()}, C{socket.listen()}, or
- C{socket.bind()}; see U{RFC 3493 <https://tools.ietf.org/html/rfc3493>} for
- more information.
-
- @param ip: An IPv6 address literal.
- @type ip: C{str}
-
- @param port: A port number.
- @type port: C{int}
-
- @return: a 4-tuple of C{(host, port, flow, scope)}, suitable for use as an
- IPv6 address.
-
- @raise socket.gaierror: if either the IP or port is not numeric as it
- should be.
- """
- return socket.getaddrinfo(ip, port, 0, 0, 0, _NUMERIC_ONLY)[0][4]
-
-
-
-class _BaseTCPClient(object):
- """
- Code shared with other (non-POSIX) reactors for management of outgoing TCP
- connections (both TCPv4 and TCPv6).
-
- @note: In order to be functional, this class must be mixed into the same
- hierarchy as L{_BaseBaseClient}. It would subclass L{_BaseBaseClient}
- directly, but the class hierarchy here is divided in strange ways out
- of the need to share code along multiple axes; specifically, with the
- IOCP reactor and also with UNIX clients in other reactors.
-
- @ivar _addressType: The Twisted _IPAddress implementation for this client
- @type _addressType: L{IPv4Address} or L{IPv6Address}
-
- @ivar connector: The L{Connector} which is driving this L{_BaseTCPClient}'s
- connection attempt.
-
- @ivar addr: The address that this socket will be connecting to.
- @type addr: If IPv4, a 2-C{tuple} of C{(str host, int port)}. If IPv6, a
- 4-C{tuple} of (C{str host, int port, int ignored, int scope}).
-
- @ivar createInternetSocket: Subclasses must implement this as a method to
- create a python socket object of the appropriate address family and
- socket type.
- @type createInternetSocket: 0-argument callable returning
- C{socket._socketobject}.
- """
-
- _addressType = address.IPv4Address
-
- def __init__(self, host, port, bindAddress, connector, reactor=None):
- # BaseClient.__init__ is invoked later
- self.connector = connector
- self.addr = (host, port)
-
- whenDone = self.resolveAddress
- err = None
- skt = None
-
- if abstract.isIPAddress(host):
- self._requiresResolution = False
- elif abstract.isIPv6Address(host):
- self._requiresResolution = False
- self.addr = _resolveIPv6(host, port)
- self.addressFamily = socket.AF_INET6
- self._addressType = address.IPv6Address
- else:
- self._requiresResolution = True
- try:
- skt = self.createInternetSocket()
- except socket.error, se:
- err = error.ConnectBindError(se.args[0], se.args[1])
- whenDone = None
- if whenDone and bindAddress is not None:
- try:
- if abstract.isIPv6Address(bindAddress[0]):
- bindinfo = _resolveIPv6(*bindAddress)
- else:
- bindinfo = bindAddress
- skt.bind(bindinfo)
- except socket.error, se:
- err = error.ConnectBindError(se.args[0], se.args[1])
- whenDone = None
- self._finishInit(whenDone, skt, err, reactor)
-
-
- def getHost(self):
- """
- Returns an L{IPv4Address} or L{IPv6Address}.
-
- This indicates the address from which I am connecting.
- """
- return self._addressType('TCP', *self.socket.getsockname()[:2])
-
-
- def getPeer(self):
- """
- Returns an L{IPv4Address} or L{IPv6Address}.
-
- This indicates the address that I am connected to.
- """
- # an ipv6 realAddress has more than two elements, but the IPv6Address
- # constructor still only takes two.
- return self._addressType('TCP', *self.realAddress[:2])
-
-
- def __repr__(self):
- s = '<%s to %s at %x>' % (self.__class__, self.addr, unsignedID(self))
- return s
-
-
-
-class Client(_BaseTCPClient, BaseClient):
- """
- A transport for a TCP protocol; either TCPv4 or TCPv6.
-
- Do not create these directly; use L{IReactorTCP.connectTCP}.
- """
-
-
-
-class Server(_TLSServerMixin, Connection):
- """
- Serverside socket-stream connection class.
-
- This is a serverside network connection transport; a socket which came from
- an accept() on a server.
-
- @ivar _base: L{Connection}, which is the base class of this class which has
- all of the useful file descriptor methods. This is used by
- L{_TLSServerMixin} to call the right methods to directly manipulate the
- transport, as is necessary for writing TLS-encrypted bytes (whereas
- those methods on L{Server} will go through another layer of TLS if it
- has been enabled).
- """
- _base = Connection
-
- _addressType = address.IPv4Address
-
- def __init__(self, sock, protocol, client, server, sessionno, reactor):
- """
- Server(sock, protocol, client, server, sessionno)
-
- Initialize it with a socket, a protocol, a descriptor for my peer (a
- tuple of host, port describing the other end of the connection), an
- instance of Port, and a session number.
- """
- Connection.__init__(self, sock, protocol, reactor)
- if len(client) != 2:
- self._addressType = address.IPv6Address
- self.server = server
- self.client = client
- self.sessionno = sessionno
- self.hostname = client[0]
-
- logPrefix = self._getLogPrefix(self.protocol)
- self.logstr = "%s,%s,%s" % (logPrefix,
- sessionno,
- self.hostname)
- if self.server is not None:
- self.repstr = "<%s #%s on %s>" % (self.protocol.__class__.__name__,
- self.sessionno,
- self.server._realPortNumber)
- self.startReading()
- self.connected = 1
-
- def __repr__(self):
- """
- A string representation of this connection.
- """
- return self.repstr
-
-
- @classmethod
- def _fromConnectedSocket(cls, fileDescriptor, addressFamily, factory,
- reactor):
- """
- Create a new L{Server} based on an existing connected I{SOCK_STREAM}
- socket.
-
- Arguments are the same as to L{Server.__init__}, except where noted.
-
- @param fileDescriptor: An integer file descriptor associated with a
- connected socket. The socket must be in non-blocking mode. Any
- additional attributes desired, such as I{FD_CLOEXEC}, must also be
- set already.
-
- @param addressFamily: The address family (sometimes called I{domain})
- of the existing socket. For example, L{socket.AF_INET}.
-
- @return: A new instance of C{cls} wrapping the socket given by
- C{fileDescriptor}.
- """
- addressType = address.IPv4Address
- if addressFamily == socket.AF_INET6:
- addressType = address.IPv6Address
- skt = socket.fromfd(fileDescriptor, addressFamily, socket.SOCK_STREAM)
- addr = skt.getpeername()
- protocolAddr = addressType('TCP', addr[0], addr[1])
- localPort = skt.getsockname()[1]
-
- protocol = factory.buildProtocol(protocolAddr)
- if protocol is None:
- skt.close()
- return
-
- self = cls(skt, protocol, addr, None, addr[1], reactor)
- self.repstr = "<%s #%s on %s>" % (
- self.protocol.__class__.__name__, self.sessionno, localPort)
- protocol.makeConnection(self)
- return self
-
-
- def getHost(self):
- """
- Returns an L{IPv4Address} or L{IPv6Address}.
-
- This indicates the server's address.
- """
- host, port = self.socket.getsockname()[:2]
- return self._addressType('TCP', host, port)
-
-
- def getPeer(self):
- """
- Returns an L{IPv4Address} or L{IPv6Address}.
-
- This indicates the client's address.
- """
- return self._addressType('TCP', *self.client[:2])
-
-
-
-class Port(base.BasePort, _SocketCloser):
- """
- A TCP server port, listening for connections.
-
- When a connection is accepted, this will call a factory's buildProtocol
- with the incoming address as an argument, according to the specification
- described in L{twisted.internet.interfaces.IProtocolFactory}.
-
- If you wish to change the sort of transport that will be used, the
- C{transport} attribute will be called with the signature expected for
- C{Server.__init__}, so it can be replaced.
-
- @ivar deferred: a deferred created when L{stopListening} is called, and
- that will fire when connection is lost. This is not to be used it
- directly: prefer the deferred returned by L{stopListening} instead.
- @type deferred: L{defer.Deferred}
-
- @ivar disconnecting: flag indicating that the L{stopListening} method has
- been called and that no connections should be accepted anymore.
- @type disconnecting: C{bool}
-
- @ivar connected: flag set once the listen has successfully been called on
- the socket.
- @type connected: C{bool}
-
- @ivar _type: A string describing the connections which will be created by
- this port. Normally this is C{"TCP"}, since this is a TCP port, but
- when the TLS implementation re-uses this class it overrides the value
- with C{"TLS"}. Only used for logging.
-
- @ivar _preexistingSocket: If not C{None}, a L{socket.socket} instance which
- was created and initialized outside of the reactor and will be used to
- listen for connections (instead of a new socket being created by this
- L{Port}).
- """
-
- implements(interfaces.IListeningPort)
-
- socketType = socket.SOCK_STREAM
-
- transport = Server
- sessionno = 0
- interface = ''
- backlog = 50
-
- _type = 'TCP'
-
- # Actual port number being listened on, only set to a non-None
- # value when we are actually listening.
- _realPortNumber = None
-
- # An externally initialized socket that we will use, rather than creating
- # our own.
- _preexistingSocket = None
-
- addressFamily = socket.AF_INET
- _addressType = address.IPv4Address
-
- def __init__(self, port, factory, backlog=50, interface='', reactor=None):
- """Initialize with a numeric port to listen on.
- """
- base.BasePort.__init__(self, reactor=reactor)
- self.port = port
- self.factory = factory
- self.backlog = backlog
- if abstract.isIPv6Address(interface):
- self.addressFamily = socket.AF_INET6
- self._addressType = address.IPv6Address
- self.interface = interface
-
-
- @classmethod
- def _fromListeningDescriptor(cls, reactor, fd, addressFamily, factory):
- """
- Create a new L{Port} based on an existing listening I{SOCK_STREAM}
- socket.
-
- Arguments are the same as to L{Port.__init__}, except where noted.
-
- @param fd: An integer file descriptor associated with a listening
- socket. The socket must be in non-blocking mode. Any additional
- attributes desired, such as I{FD_CLOEXEC}, must also be set already.
-
- @param addressFamily: The address family (sometimes called I{domain}) of
- the existing socket. For example, L{socket.AF_INET}.
-
- @return: A new instance of C{cls} wrapping the socket given by C{fd}.
- """
- port = socket.fromfd(fd, addressFamily, cls.socketType)
- interface = port.getsockname()[0]
- self = cls(None, factory, None, interface, reactor)
- self._preexistingSocket = port
- return self
-
-
- def __repr__(self):
- if self._realPortNumber is not None:
- return "<%s of %s on %s>" % (self.__class__,
- self.factory.__class__, self._realPortNumber)
- else:
- return "<%s of %s (not listening)>" % (self.__class__, self.factory.__class__)
-
- def createInternetSocket(self):
- s = base.BasePort.createInternetSocket(self)
- if platformType == "posix" and sys.platform != "cygwin":
- s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- return s
-
-
- def startListening(self):
- """Create and bind my socket, and begin listening on it.
-
- This is called on unserialization, and must be called after creating a
- server to begin listening on the specified port.
- """
- if self._preexistingSocket is None:
- # Create a new socket and make it listen
- try:
- skt = self.createInternetSocket()
- if self.addressFamily == socket.AF_INET6:
- addr = _resolveIPv6(self.interface, self.port)
- else:
- addr = (self.interface, self.port)
- skt.bind(addr)
- except socket.error, le:
- raise CannotListenError, (self.interface, self.port, le)
- skt.listen(self.backlog)
- else:
- # Re-use the externally specified socket
- skt = self._preexistingSocket
- self._preexistingSocket = None
- # Avoid shutting it down at the end.
- self._socketShutdownMethod = None
-
- # Make sure that if we listened on port 0, we update that to
- # reflect what the OS actually assigned us.
- self._realPortNumber = skt.getsockname()[1]
-
- log.msg("%s starting on %s" % (
- self._getLogPrefix(self.factory), self._realPortNumber))
-
- # The order of the next 5 lines is kind of bizarre. If no one
- # can explain it, perhaps we should re-arrange them.
- self.factory.doStart()
- self.connected = True
- self.socket = skt
- self.fileno = self.socket.fileno
- self.numberAccepts = 100
-
- self.startReading()
-
-
- def _buildAddr(self, address):
- host, port = address[:2]
- return self._addressType('TCP', host, port)
-
-
- def doRead(self):
- """Called when my socket is ready for reading.
-
- This accepts a connection and calls self.protocol() to handle the
- wire-level protocol.
- """
- try:
- if platformType == "posix":
- numAccepts = self.numberAccepts
- else:
- # win32 event loop breaks if we do more than one accept()
- # in an iteration of the event loop.
- numAccepts = 1
- for i in range(numAccepts):
- # we need this so we can deal with a factory's buildProtocol
- # calling our loseConnection
- if self.disconnecting:
- return
- try:
- skt, addr = self.socket.accept()
- except socket.error, e:
- if e.args[0] in (EWOULDBLOCK, EAGAIN):
- self.numberAccepts = i
- break
- elif e.args[0] == EPERM:
- # Netfilter on Linux may have rejected the
- # connection, but we get told to try to accept()
- # anyway.
- continue
- elif e.args[0] in (EMFILE, ENOBUFS, ENFILE, ENOMEM, ECONNABORTED):
-
- # Linux gives EMFILE when a process is not allowed
- # to allocate any more file descriptors. *BSD and
- # Win32 give (WSA)ENOBUFS. Linux can also give
- # ENFILE if the system is out of inodes, or ENOMEM
- # if there is insufficient memory to allocate a new
- # dentry. ECONNABORTED is documented as possible on
- # both Linux and Windows, but it is not clear
- # whether there are actually any circumstances under
- # which it can happen (one might expect it to be
- # possible if a client sends a FIN or RST after the
- # server sends a SYN|ACK but before application code
- # calls accept(2), however at least on Linux this
- # _seems_ to be short-circuited by syncookies.
-
- log.msg("Could not accept new connection (%s)" % (
- errorcode[e.args[0]],))
- break
- raise
-
- fdesc._setCloseOnExec(skt.fileno())
- protocol = self.factory.buildProtocol(self._buildAddr(addr))
- if protocol is None:
- skt.close()
- continue
- s = self.sessionno
- self.sessionno = s+1
- transport = self.transport(skt, protocol, addr, self, s, self.reactor)
- protocol.makeConnection(transport)
- else:
- self.numberAccepts = self.numberAccepts+20
- except:
- # Note that in TLS mode, this will possibly catch SSL.Errors
- # raised by self.socket.accept()
- #
- # There is no "except SSL.Error:" above because SSL may be
- # None if there is no SSL support. In any case, all the
- # "except SSL.Error:" suite would probably do is log.deferr()
- # and return, so handling it here works just as well.
- log.deferr()
-
- def loseConnection(self, connDone=failure.Failure(main.CONNECTION_DONE)):
- """
- Stop accepting connections on this port.
-
- This will shut down the socket and call self.connectionLost(). It
- returns a deferred which will fire successfully when the port is
- actually closed, or with a failure if an error occurs shutting down.
- """
- self.disconnecting = True
- self.stopReading()
- if self.connected:
- self.deferred = deferLater(
- self.reactor, 0, self.connectionLost, connDone)
- return self.deferred
-
- stopListening = loseConnection
-
- def _logConnectionLostMsg(self):
- """
- Log message for closing port
- """
- log.msg('(%s Port %s Closed)' % (self._type, self._realPortNumber))
-
-
- def connectionLost(self, reason):
- """
- Cleans up the socket.
- """
- self._logConnectionLostMsg()
- self._realPortNumber = None
-
- base.BasePort.connectionLost(self, reason)
- self.connected = False
- self._closeSocket(True)
- del self.socket
- del self.fileno
-
- try:
- self.factory.doStop()
- finally:
- self.disconnecting = False
-
-
- def logPrefix(self):
- """Returns the name of my class, to prefix log entries with.
- """
- return reflect.qual(self.factory.__class__)
-
-
- def getHost(self):
- """
- Return an L{IPv4Address} or L{IPv6Address} indicating the listening
- address of this port.
- """
- host, port = self.socket.getsockname()[:2]
- return self._addressType('TCP', host, port)
-
-
-
-class Connector(base.BaseConnector):
- """
- A L{Connector} provides of L{twisted.internet.interfaces.IConnector} for
- all POSIX-style reactors.
-
- @ivar _addressType: the type returned by L{Connector.getDestination}.
- Either L{IPv4Address} or L{IPv6Address}, depending on the type of
- address.
- @type _addressType: C{type}
- """
- _addressType = address.IPv4Address
-
- def __init__(self, host, port, factory, timeout, bindAddress, reactor=None):
- if isinstance(port, types.StringTypes):
- try:
- port = socket.getservbyname(port, 'tcp')
- except socket.error, e:
- raise error.ServiceNameUnknownError(string="%s (%r)" % (e, port))
- self.host, self.port = host, port
- if abstract.isIPv6Address(host):
- self._addressType = address.IPv6Address
- self.bindAddress = bindAddress
- base.BaseConnector.__init__(self, factory, timeout, reactor)
-
-
- def _makeTransport(self):
- """
- Create a L{Client} bound to this L{Connector}.
-
- @return: a new L{Client}
- @rtype: L{Client}
- """
- return Client(self.host, self.port, self.bindAddress, self, self.reactor)
-
-
- def getDestination(self):
- """
- @see: L{twisted.internet.interfaces.IConnector.getDestination}.
- """
- return self._addressType('TCP', self.host, self.port)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/__init__.py
deleted file mode 100755
index cf1de2ac..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_posixifaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_posixifaces.py
deleted file mode 100755
index 3dcbc272..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_posixifaces.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-POSIX implementation of local network interface enumeration.
-"""
-
-import sys, socket
-
-from socket import AF_INET, AF_INET6, inet_ntop
-from ctypes import (
- CDLL, POINTER, Structure, c_char_p, c_ushort, c_int,
- c_uint32, c_uint8, c_void_p, c_ubyte, pointer, cast)
-from ctypes.util import find_library
-
-libc = CDLL(find_library("c"))
-
-if sys.platform == 'darwin':
- _sockaddrCommon = [
- ("sin_len", c_uint8),
- ("sin_family", c_uint8),
- ]
-else:
- _sockaddrCommon = [
- ("sin_family", c_ushort),
- ]
-
-
-
-class in_addr(Structure):
- _fields_ = [
- ("in_addr", c_ubyte * 4),
- ]
-
-
-
-class in6_addr(Structure):
- _fields_ = [
- ("in_addr", c_ubyte * 16),
- ]
-
-
-
-class sockaddr(Structure):
- _fields_ = _sockaddrCommon + [
- ("sin_port", c_ushort),
- ]
-
-
-
-class sockaddr_in(Structure):
- _fields_ = _sockaddrCommon + [
- ("sin_port", c_ushort),
- ("sin_addr", in_addr),
- ]
-
-
-
-class sockaddr_in6(Structure):
- _fields_ = _sockaddrCommon + [
- ("sin_port", c_ushort),
- ("sin_flowinfo", c_uint32),
- ("sin_addr", in6_addr),
- ]
-
-
-
-class ifaddrs(Structure):
- pass
-
-ifaddrs_p = POINTER(ifaddrs)
-ifaddrs._fields_ = [
- ('ifa_next', ifaddrs_p),
- ('ifa_name', c_char_p),
- ('ifa_flags', c_uint32),
- ('ifa_addr', POINTER(sockaddr)),
- ('ifa_netmask', POINTER(sockaddr)),
- ('ifa_dstaddr', POINTER(sockaddr)),
- ('ifa_data', c_void_p)]
-
-getifaddrs = libc.getifaddrs
-getifaddrs.argtypes = [POINTER(ifaddrs_p)]
-getifaddrs.restype = c_int
-
-freeifaddrs = libc.freeifaddrs
-freeifaddrs.argtypes = [ifaddrs_p]
-
-def _interfaces():
- """
- Call C{getifaddrs(3)} and return a list of tuples of interface name, address
- family, and human-readable address representing its results.
- """
- ifaddrs = ifaddrs_p()
- if getifaddrs(pointer(ifaddrs)) < 0:
- raise OSError()
- results = []
- try:
- while ifaddrs:
- if ifaddrs[0].ifa_addr:
- family = ifaddrs[0].ifa_addr[0].sin_family
- if family == AF_INET:
- addr = cast(ifaddrs[0].ifa_addr, POINTER(sockaddr_in))
- elif family == AF_INET6:
- addr = cast(ifaddrs[0].ifa_addr, POINTER(sockaddr_in6))
- else:
- addr = None
-
- if addr:
- packed = ''.join(map(chr, addr[0].sin_addr.in_addr[:]))
- results.append((
- ifaddrs[0].ifa_name,
- family,
- inet_ntop(family, packed)))
-
- ifaddrs = ifaddrs[0].ifa_next
- finally:
- freeifaddrs(ifaddrs)
- return results
-
-
-
-def posixGetLinkLocalIPv6Addresses():
- """
- Return a list of strings in colon-hex format representing all the link local
- IPv6 addresses available on the system, as reported by I{getifaddrs(3)}.
- """
- retList = []
- for (interface, family, address) in _interfaces():
- if family == socket.AF_INET6 and address.startswith('fe80:'):
- retList.append('%s%%%s' % (address, interface))
- return retList
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_win32ifaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_win32ifaces.py
deleted file mode 100755
index 4a1e82b1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/_win32ifaces.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Windows implementation of local network interface enumeration.
-"""
-
-from socket import socket, AF_INET6, SOCK_STREAM
-from ctypes import (
- WinDLL, byref, create_string_buffer, c_int, c_void_p,
- POINTER, Structure, cast, string_at)
-
-WS2_32 = WinDLL('ws2_32')
-
-SOCKET = c_int
-DWORD = c_int
-LPVOID = c_void_p
-LPSOCKADDR = c_void_p
-LPWSAPROTOCOL_INFO = c_void_p
-LPTSTR = c_void_p
-LPDWORD = c_void_p
-LPWSAOVERLAPPED = c_void_p
-LPWSAOVERLAPPED_COMPLETION_ROUTINE = c_void_p
-
-# http://msdn.microsoft.com/en-us/library/ms741621(v=VS.85).aspx
-# int WSAIoctl(
-# __in SOCKET s,
-# __in DWORD dwIoControlCode,
-# __in LPVOID lpvInBuffer,
-# __in DWORD cbInBuffer,
-# __out LPVOID lpvOutBuffer,
-# __in DWORD cbOutBuffer,
-# __out LPDWORD lpcbBytesReturned,
-# __in LPWSAOVERLAPPED lpOverlapped,
-# __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
-# );
-WSAIoctl = WS2_32.WSAIoctl
-WSAIoctl.argtypes = [
- SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD,
- LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE]
-WSAIoctl.restype = c_int
-
-# http://msdn.microsoft.com/en-us/library/ms741516(VS.85).aspx
-# INT WSAAPI WSAAddressToString(
-# __in LPSOCKADDR lpsaAddress,
-# __in DWORD dwAddressLength,
-# __in_opt LPWSAPROTOCOL_INFO lpProtocolInfo,
-# __inout LPTSTR lpszAddressString,
-# __inout LPDWORD lpdwAddressStringLength
-# );
-WSAAddressToString = WS2_32.WSAAddressToStringA
-WSAAddressToString.argtypes = [
- LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO, LPTSTR, LPDWORD]
-WSAAddressToString.restype = c_int
-
-
-SIO_ADDRESS_LIST_QUERY = 0x48000016
-WSAEFAULT = 10014
-
-class SOCKET_ADDRESS(Structure):
- _fields_ = [('lpSockaddr', c_void_p),
- ('iSockaddrLength', c_int)]
-
-
-
-def make_SAL(ln):
- class SOCKET_ADDRESS_LIST(Structure):
- _fields_ = [('iAddressCount', c_int),
- ('Address', SOCKET_ADDRESS * ln)]
- return SOCKET_ADDRESS_LIST
-
-
-
-def win32GetLinkLocalIPv6Addresses():
- """
- Return a list of strings in colon-hex format representing all the link local
- IPv6 addresses available on the system, as reported by
- I{WSAIoctl}/C{SIO_ADDRESS_LIST_QUERY}.
- """
- s = socket(AF_INET6, SOCK_STREAM)
- size = 4096
- retBytes = c_int()
- for i in range(2):
- buf = create_string_buffer(size)
- ret = WSAIoctl(
- s.fileno(),
- SIO_ADDRESS_LIST_QUERY, 0, 0, buf, size, byref(retBytes), 0, 0)
-
- # WSAIoctl might fail with WSAEFAULT, which means there was not enough
- # space in the buffer we gave it. There's no way to check the errno
- # until Python 2.6, so we don't even try. :/ Maybe if retBytes is still
- # 0 another error happened, though.
- if ret and retBytes.value:
- size = retBytes.value
- else:
- break
-
- # If it failed, then we'll just have to give up. Still no way to see why.
- if ret:
- raise RuntimeError("WSAIoctl failure")
-
- addrList = cast(buf, POINTER(make_SAL(0)))
- addrCount = addrList[0].iAddressCount
- addrList = cast(buf, POINTER(make_SAL(addrCount)))
-
- addressStringBufLength = 1024
- addressStringBuf = create_string_buffer(addressStringBufLength)
-
- retList = []
- for i in range(addrList[0].iAddressCount):
- retBytes.value = addressStringBufLength
- addr = addrList[0].Address[i]
- ret = WSAAddressToString(
- addr.lpSockaddr, addr.iSockaddrLength, 0, addressStringBuf,
- byref(retBytes))
- if ret:
- raise RuntimeError("WSAAddressToString failure")
- retList.append(string_at(addressStringBuf))
- return [addr for addr in retList if '%' in addr]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/connectionmixins.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/connectionmixins.py
deleted file mode 100755
index 655f9092..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/connectionmixins.py
+++ /dev/null
@@ -1,649 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_tcp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Various helpers for tests for connection-oriented transports.
-"""
-
-import socket
-
-from gc import collect
-from weakref import ref
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.python import context, log
-from twisted.python.failure import Failure
-from twisted.python.runtime import platform
-from twisted.python.log import ILogContext, msg, err
-from twisted.internet.defer import Deferred, gatherResults, succeed, fail
-from twisted.internet.interfaces import (
- IConnector, IResolverSimple, IReactorFDSet)
-from twisted.internet.protocol import ClientFactory, Protocol, ServerFactory
-from twisted.test.test_tcp import ClosingProtocol
-from twisted.trial.unittest import SkipTest
-from twisted.internet.error import DNSLookupError
-from twisted.internet.interfaces import ITLSTransport
-from twisted.internet.test.reactormixins import ConnectableProtocol
-from twisted.internet.test.reactormixins import runProtocolsWithReactor
-from twisted.internet.test.reactormixins import needsRunningReactor
-
-
-
-def serverFactoryFor(protocol):
- """
- Helper function which returns a L{ServerFactory} which will build instances
- of C{protocol}.
-
- @param protocol: A callable which returns an L{IProtocol} provider to be
- used to handle connections to the port the returned factory listens on.
- """
- factory = ServerFactory()
- factory.protocol = protocol
- return factory
-
-# ServerFactory is good enough for client endpoints, too.
-factoryFor = serverFactoryFor
-
-
-
-def findFreePort(interface='127.0.0.1', family=socket.AF_INET,
- type=socket.SOCK_STREAM):
- """
- Ask the platform to allocate a free port on the specified interface, then
- release the socket and return the address which was allocated.
-
- @param interface: The local address to try to bind the port on.
- @type interface: C{str}
-
- @param type: The socket type which will use the resulting port.
-
- @return: A two-tuple of address and port, like that returned by
- L{socket.getsockname}.
- """
- addr = socket.getaddrinfo(interface, 0)[0][4]
- probe = socket.socket(family, type)
- try:
- probe.bind(addr)
- return probe.getsockname()
- finally:
- probe.close()
-
-
-
-def _getWriters(reactor):
- """
- Like L{IReactorFDSet.getWriters}, but with support for IOCP reactor as
- well.
- """
- if IReactorFDSet.providedBy(reactor):
- return reactor.getWriters()
- elif 'IOCP' in reactor.__class__.__name__:
- return reactor.handles
- else:
- # Cannot tell what is going on.
- raise Exception("Cannot find writers on %r" % (reactor,))
-
-
-
-class _AcceptOneClient(ServerFactory):
- """
- This factory fires a L{Deferred} with a protocol instance shortly after it
- is constructed (hopefully long enough afterwards so that it has been
- connected to a transport).
-
- @ivar reactor: The reactor used to schedule the I{shortly}.
-
- @ivar result: A L{Deferred} which will be fired with the protocol instance.
- """
- def __init__(self, reactor, result):
- self.reactor = reactor
- self.result = result
-
-
- def buildProtocol(self, addr):
- protocol = ServerFactory.buildProtocol(self, addr)
- self.reactor.callLater(0, self.result.callback, protocol)
- return protocol
-
-
-
-class _SimplePullProducer(object):
- """
- A pull producer which writes one byte whenever it is resumed. For use by
- L{test_unregisterProducerAfterDisconnect}.
- """
- def __init__(self, consumer):
- self.consumer = consumer
-
-
- def stopProducing(self):
- pass
-
-
- def resumeProducing(self):
- log.msg("Producer.resumeProducing")
- self.consumer.write('x')
-
-
-
-class Stop(ClientFactory):
- """
- A client factory which stops a reactor when a connection attempt fails.
- """
- failReason = None
-
- def __init__(self, reactor):
- self.reactor = reactor
-
-
- def clientConnectionFailed(self, connector, reason):
- self.failReason = reason
- msg("Stop(CF) cCFailed: %s" % (reason.getErrorMessage(),))
- self.reactor.stop()
-
-
-
-class FakeResolver(object):
- """
- A resolver implementation based on a C{dict} mapping names to addresses.
- """
- implements(IResolverSimple)
-
- def __init__(self, names):
- self.names = names
-
-
- def getHostByName(self, name, timeout):
- try:
- return succeed(self.names[name])
- except KeyError:
- return fail(DNSLookupError("FakeResolver couldn't find " + name))
-
-
-
-class ClosingLaterProtocol(ConnectableProtocol):
- """
- ClosingLaterProtocol exchanges one byte with its peer and then disconnects
- itself. This is mostly a work-around for the fact that connectionMade is
- called before the SSL handshake has completed.
- """
- def __init__(self, onConnectionLost):
- self.lostConnectionReason = None
- self.onConnectionLost = onConnectionLost
-
-
- def connectionMade(self):
- msg("ClosingLaterProtocol.connectionMade")
-
-
- def dataReceived(self, bytes):
- msg("ClosingLaterProtocol.dataReceived %r" % (bytes,))
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- msg("ClosingLaterProtocol.connectionLost")
- self.lostConnectionReason = reason
- self.onConnectionLost.callback(self)
-
-
-
-class ConnectionTestsMixin(object):
- """
- This mixin defines test methods which should apply to most L{ITransport}
- implementations.
- """
-
- # This should be a reactormixins.EndpointCreator instance.
- endpoints = None
-
-
- def test_logPrefix(self):
- """
- Client and server transports implement L{ILoggingContext.logPrefix} to
- return a message reflecting the protocol they are running.
- """
- class CustomLogPrefixProtocol(ConnectableProtocol):
- def __init__(self, prefix):
- self._prefix = prefix
- self.system = None
-
- def connectionMade(self):
- self.transport.write("a")
-
- def logPrefix(self):
- return self._prefix
-
- def dataReceived(self, bytes):
- self.system = context.get(ILogContext)["system"]
- self.transport.write("b")
- # Only close connection if both sides have received data, so
- # that both sides have system set.
- if "b" in bytes:
- self.transport.loseConnection()
-
- client = CustomLogPrefixProtocol("Custom Client")
- server = CustomLogPrefixProtocol("Custom Server")
- runProtocolsWithReactor(self, server, client, self.endpoints)
- self.assertIn("Custom Client", client.system)
- self.assertIn("Custom Server", server.system)
-
-
- def test_writeAfterDisconnect(self):
- """
- After a connection is disconnected, L{ITransport.write} and
- L{ITransport.writeSequence} are no-ops.
- """
- reactor = self.buildReactor()
-
- finished = []
-
- serverConnectionLostDeferred = Deferred()
- protocol = lambda: ClosingLaterProtocol(serverConnectionLostDeferred)
- portDeferred = self.endpoints.server(reactor).listen(
- serverFactoryFor(protocol))
- def listening(port):
- msg("Listening on %r" % (port.getHost(),))
- endpoint = self.endpoints.client(reactor, port.getHost())
-
- lostConnectionDeferred = Deferred()
- protocol = lambda: ClosingLaterProtocol(lostConnectionDeferred)
- client = endpoint.connect(factoryFor(protocol))
- def write(proto):
- msg("About to write to %r" % (proto,))
- proto.transport.write('x')
- client.addCallbacks(write, lostConnectionDeferred.errback)
-
- def disconnected(proto):
- msg("%r disconnected" % (proto,))
- proto.transport.write("some bytes to get lost")
- proto.transport.writeSequence(["some", "more"])
- finished.append(True)
-
- lostConnectionDeferred.addCallback(disconnected)
- serverConnectionLostDeferred.addCallback(disconnected)
- return gatherResults([
- lostConnectionDeferred,
- serverConnectionLostDeferred])
-
- def onListen():
- portDeferred.addCallback(listening)
- portDeferred.addErrback(err)
- portDeferred.addCallback(lambda ignored: reactor.stop())
- needsRunningReactor(reactor, onListen)
-
- self.runReactor(reactor)
- self.assertEqual(finished, [True, True])
-
-
- def test_protocolGarbageAfterLostConnection(self):
- """
- After the connection a protocol is being used for is closed, the
- reactor discards all of its references to the protocol.
- """
- lostConnectionDeferred = Deferred()
- clientProtocol = ClosingLaterProtocol(lostConnectionDeferred)
- clientRef = ref(clientProtocol)
-
- reactor = self.buildReactor()
- portDeferred = self.endpoints.server(reactor).listen(
- serverFactoryFor(Protocol))
- def listening(port):
- msg("Listening on %r" % (port.getHost(),))
- endpoint = self.endpoints.client(reactor, port.getHost())
-
- client = endpoint.connect(factoryFor(lambda: clientProtocol))
- def disconnect(proto):
- msg("About to disconnect %r" % (proto,))
- proto.transport.loseConnection()
- client.addCallback(disconnect)
- client.addErrback(lostConnectionDeferred.errback)
- return lostConnectionDeferred
-
- def onListening():
- portDeferred.addCallback(listening)
- portDeferred.addErrback(err)
- portDeferred.addBoth(lambda ignored: reactor.stop())
- needsRunningReactor(reactor, onListening)
-
- self.runReactor(reactor)
-
- # Drop the reference and get the garbage collector to tell us if there
- # are no references to the protocol instance left in the reactor.
- clientProtocol = None
- collect()
- self.assertIdentical(None, clientRef())
-
-
-
-class LogObserverMixin(object):
- """
- Mixin for L{TestCase} subclasses which want to observe log events.
- """
- def observe(self):
- loggedMessages = []
- log.addObserver(loggedMessages.append)
- self.addCleanup(log.removeObserver, loggedMessages.append)
- return loggedMessages
-
-
-
-class BrokenContextFactory(object):
- """
- A context factory with a broken C{getContext} method, for exercising the
- error handling for such a case.
- """
- message = "Some path was wrong maybe"
-
- def getContext(self):
- raise ValueError(self.message)
-
-
-
-class TCPClientTestsMixin(object):
- """
- This mixin defines tests applicable to TCP client implementations. Classes
- which mix this in must provide all of the documented instance variables in
- order to specify how the test works. These are documented as instance
- variables rather than declared as methods due to some peculiar inheritance
- ordering concerns, but they are effectively abstract methods.
-
- This must be mixed in to a L{ReactorBuilder
- <twisted.internet.test.reactormixins.ReactorBuilder>} subclass, as it
- depends on several of its methods.
-
- @ivar endpoints: A L{twisted.internet.test.reactormixins.EndpointCreator}
- instance.
-
- @ivar interface: An IP address literal to locally bind a socket to as well
- as to connect to. This can be any valid interface for the local host.
- @type interface: C{str}
-
- @ivar port: An unused local listening port to listen on and connect to.
- This will be used in conjunction with the C{interface}. (Depending on
- what they're testing, some tests will locate their own port with
- L{findFreePort} instead.)
- @type port: C{int}
-
- @ivar family: an address family constant, such as L{socket.AF_INET},
- L{socket.AF_INET6}, or L{socket.AF_UNIX}, which indicates the address
- family of the transport type under test.
- @type family: C{int}
-
- @ivar addressClass: the L{twisted.internet.interfaces.IAddress} implementor
- associated with the transport type under test. Must also be a
- 3-argument callable which produces an instance of same.
- @type addressClass: C{type}
-
- @ivar fakeDomainName: A fake domain name to use, to simulate hostname
- resolution and to distinguish between hostnames and IP addresses where
- necessary.
- @type fakeDomainName: C{str}
- """
-
- def test_interface(self):
- """
- L{IReactorTCP.connectTCP} returns an object providing L{IConnector}.
- """
- reactor = self.buildReactor()
- connector = reactor.connectTCP(self.interface, self.port,
- ClientFactory())
- self.assertTrue(verifyObject(IConnector, connector))
-
-
- def test_clientConnectionFailedStopsReactor(self):
- """
- The reactor can be stopped by a client factory's
- C{clientConnectionFailed} method.
- """
- host, port = findFreePort(self.interface, self.family)[:2]
- reactor = self.buildReactor()
- needsRunningReactor(
- reactor, lambda: reactor.connectTCP(host, port, Stop(reactor)))
- self.runReactor(reactor)
-
-
- def test_addresses(self):
- """
- A client's transport's C{getHost} and C{getPeer} return L{IPv4Address}
- instances which have the dotted-quad string form of the resolved
- adddress of the local and remote endpoints of the connection
- respectively as their C{host} attribute, not the hostname originally
- passed in to L{connectTCP
- <twisted.internet.interfaces.IReactorTCP.connectTCP>}, if a hostname
- was used.
- """
- host, port = findFreePort(self.interface, self.family)[:2]
- reactor = self.buildReactor()
- fakeDomain = self.fakeDomainName
- reactor.installResolver(FakeResolver({fakeDomain: self.interface}))
-
- server = reactor.listenTCP(
- 0, serverFactoryFor(Protocol), interface=host)
- serverAddress = server.getHost()
-
- addresses = {'host': None, 'peer': None}
- class CheckAddress(Protocol):
- def makeConnection(self, transport):
- addresses['host'] = transport.getHost()
- addresses['peer'] = transport.getPeer()
- reactor.stop()
-
- clientFactory = Stop(reactor)
- clientFactory.protocol = CheckAddress
-
- def connectMe():
- reactor.connectTCP(
- fakeDomain, server.getHost().port, clientFactory,
- bindAddress=(self.interface, port))
- needsRunningReactor(reactor, connectMe)
-
- self.runReactor(reactor)
-
- if clientFactory.failReason:
- self.fail(clientFactory.failReason.getTraceback())
-
- self.assertEqual(
- addresses['host'],
- self.addressClass('TCP', self.interface, port))
- self.assertEqual(
- addresses['peer'],
- self.addressClass('TCP', self.interface, serverAddress.port))
-
-
- def test_connectEvent(self):
- """
- This test checks that we correctly get notifications event for a
- client. This ought to prevent a regression under Windows using the
- GTK2 reactor. See #3925.
- """
- reactor = self.buildReactor()
-
- server = reactor.listenTCP(0, serverFactoryFor(Protocol),
- interface=self.interface)
- connected = []
-
- class CheckConnection(Protocol):
- def connectionMade(self):
- connected.append(self)
- reactor.stop()
-
- clientFactory = Stop(reactor)
- clientFactory.protocol = CheckConnection
-
- needsRunningReactor(reactor, lambda: reactor.connectTCP(
- self.interface, server.getHost().port, clientFactory))
-
- reactor.run()
-
- self.assertTrue(connected)
-
-
- def test_unregisterProducerAfterDisconnect(self):
- """
- If a producer is unregistered from a L{ITCPTransport} provider after
- the transport has been disconnected (by the peer) and after
- L{ITCPTransport.loseConnection} has been called, the transport is not
- re-added to the reactor as a writer as would be necessary if the
- transport were still connected.
- """
- reactor = self.buildReactor()
- port = reactor.listenTCP(0, serverFactoryFor(ClosingProtocol),
- interface=self.interface)
-
- finished = Deferred()
- finished.addErrback(log.err)
- finished.addCallback(lambda ign: reactor.stop())
-
- writing = []
-
- class ClientProtocol(Protocol):
- """
- Protocol to connect, register a producer, try to lose the
- connection, wait for the server to disconnect from us, and then
- unregister the producer.
- """
- def connectionMade(self):
- log.msg("ClientProtocol.connectionMade")
- self.transport.registerProducer(
- _SimplePullProducer(self.transport), False)
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- log.msg("ClientProtocol.connectionLost")
- self.unregister()
- writing.append(self.transport in _getWriters(reactor))
- finished.callback(None)
-
- def unregister(self):
- log.msg("ClientProtocol unregister")
- self.transport.unregisterProducer()
-
- clientFactory = ClientFactory()
- clientFactory.protocol = ClientProtocol
- reactor.connectTCP(self.interface, port.getHost().port, clientFactory)
- self.runReactor(reactor)
- self.assertFalse(writing[0],
- "Transport was writing after unregisterProducer.")
-
-
- def test_disconnectWhileProducing(self):
- """
- If L{ITCPTransport.loseConnection} is called while a producer is
- registered with the transport, the connection is closed after the
- producer is unregistered.
- """
- reactor = self.buildReactor()
-
- # For some reason, pyobject/pygtk will not deliver the close
- # notification that should happen after the unregisterProducer call in
- # this test. The selectable is in the write notification set, but no
- # notification ever arrives. Probably for the same reason #5233 led
- # win32eventreactor to be broken.
- skippedReactors = ["Glib2Reactor", "Gtk2Reactor"]
- reactorClassName = reactor.__class__.__name__
- if reactorClassName in skippedReactors and platform.isWindows():
- raise SkipTest(
- "A pygobject/pygtk bug disables this functionality on Windows.")
-
- class Producer:
- def resumeProducing(self):
- log.msg("Producer.resumeProducing")
-
- port = reactor.listenTCP(0, serverFactoryFor(Protocol),
- interface=self.interface)
-
- finished = Deferred()
- finished.addErrback(log.err)
- finished.addCallback(lambda ign: reactor.stop())
-
- class ClientProtocol(Protocol):
- """
- Protocol to connect, register a producer, try to lose the
- connection, unregister the producer, and wait for the connection to
- actually be lost.
- """
- def connectionMade(self):
- log.msg("ClientProtocol.connectionMade")
- self.transport.registerProducer(Producer(), False)
- self.transport.loseConnection()
- # Let the reactor tick over, in case synchronously calling
- # loseConnection and then unregisterProducer is the same as
- # synchronously calling unregisterProducer and then
- # loseConnection (as it is in several reactors).
- reactor.callLater(0, reactor.callLater, 0, self.unregister)
-
- def unregister(self):
- log.msg("ClientProtocol unregister")
- self.transport.unregisterProducer()
- # This should all be pretty quick. Fail the test
- # if we don't get a connectionLost event really
- # soon.
- reactor.callLater(
- 1.0, finished.errback,
- Failure(Exception("Connection was not lost")))
-
- def connectionLost(self, reason):
- log.msg("ClientProtocol.connectionLost")
- finished.callback(None)
-
- clientFactory = ClientFactory()
- clientFactory.protocol = ClientProtocol
- reactor.connectTCP(self.interface, port.getHost().port, clientFactory)
- self.runReactor(reactor)
- # If the test failed, we logged an error already and trial
- # will catch it.
-
-
- def test_badContext(self):
- """
- If the context factory passed to L{ITCPTransport.startTLS} raises an
- exception from its C{getContext} method, that exception is raised by
- L{ITCPTransport.startTLS}.
- """
- reactor = self.buildReactor()
-
- brokenFactory = BrokenContextFactory()
- results = []
-
- serverFactory = ServerFactory()
- serverFactory.protocol = Protocol
-
- port = reactor.listenTCP(0, serverFactory, interface=self.interface)
- endpoint = self.endpoints.client(reactor, port.getHost())
-
- clientFactory = ClientFactory()
- clientFactory.protocol = Protocol
- connectDeferred = endpoint.connect(clientFactory)
-
- def connected(protocol):
- if not ITLSTransport.providedBy(protocol.transport):
- results.append("skip")
- else:
- results.append(self.assertRaises(ValueError,
- protocol.transport.startTLS,
- brokenFactory))
-
- def connectFailed(failure):
- results.append(failure)
-
- def whenRun():
- connectDeferred.addCallback(connected)
- connectDeferred.addErrback(connectFailed)
- connectDeferred.addBoth(lambda ign: reactor.stop())
- needsRunningReactor(reactor, whenRun)
-
- self.runReactor(reactor)
-
- self.assertEqual(len(results), 1,
- "more than one callback result: %s" % (results,))
-
- if isinstance(results[0], Failure):
- # self.fail(Failure)
- results[0].raiseException()
- if results[0] == "skip":
- raise SkipTest("Reactor does not support ITLSTransport")
- self.assertEqual(BrokenContextFactory.message, str(results[0]))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/not-a-certificate b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/not-a-certificate
deleted file mode 100644
index 316453dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/not-a-certificate
+++ /dev/null
@@ -1 +0,0 @@
-This file is not a certificate; it is present to make sure that it will be skipped.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing1.pem b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing1.pem
deleted file mode 100644
index 75e47a64..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing1.pem
+++ /dev/null
@@ -1,26 +0,0 @@
-
-This is a self-signed certificate authority certificate to be used in tests.
-
-It was created with the following command:
-certcreate -f thing1.pem -h fake-ca-1.example.com -e noreply@example.com \
- -S 1234 -o 'Twisted Matrix Labs'
-
-'certcreate' may be obtained from <http://divmod.org/trac/wiki/DivmodEpsilon>
-
------BEGIN CERTIFICATE-----
-MIICwjCCAisCAgTSMA0GCSqGSIb3DQEBBAUAMIGoMREwDwYDVQQLEwhTZWN1cml0
-eTEcMBoGA1UEChMTVHdpc3RlZCBNYXRyaXggTGFiczEeMBwGA1UEAxMVZmFrZS1j
-YS0xLmV4YW1wbGUuY29tMREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMx
-IjAgBgkqhkiG9w0BCQEWE25vcmVwbHlAZXhhbXBsZS5jb20xETAPBgNVBAcTCE5l
-dyBZb3JrMB4XDTEwMDkyMTAxMjUxNFoXDTExMDkyMTAxMjUxNFowgagxETAPBgNV
-BAsTCFNlY3VyaXR5MRwwGgYDVQQKExNUd2lzdGVkIE1hdHJpeCBMYWJzMR4wHAYD
-VQQDExVmYWtlLWNhLTEuZXhhbXBsZS5jb20xETAPBgNVBAgTCE5ldyBZb3JrMQsw
-CQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYTbm9yZXBseUBleGFtcGxlLmNvbTER
-MA8GA1UEBxMITmV3IFlvcmswgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALRb
-VqC0CsaFgq1vbwPfs8zoP3ZYC/0sPMv0RJN+f3Dc7Q6YgNHS7o7TM3uAy/McADeW
-rwVuNJGe9k+4ZBHysmBH1sG64fHT5TlK9saPcUQqkubSWj4cKSDtVbQERWqC5Dy+
-qTQeZGYoPEMlnRXgMpST04DG//Dgzi4PYqUOjwxTAgMBAAEwDQYJKoZIhvcNAQEE
-BQADgYEAqNEdMXWEs8Co76wxL3/cSV3MjiAroVxJdI/3EzlnfPi1JeibbdWw31fC
-bn6428KTjjfhS31zo1yHG3YNXFEJXRscwLAH7ogz5kJwZMy/oS/96EFM10bkNwkK
-v+nWKN8i3t/E5TEIl3BPN8tchtWmH0rycVuzs5LwaewwR1AnUE4=
------END CERTIFICATE-----
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2-duplicate.pem b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2-duplicate.pem
deleted file mode 100644
index 429e1211..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2-duplicate.pem
+++ /dev/null
@@ -1,26 +0,0 @@
-
-This is a self-signed certificate authority certificate to be used in tests.
-
-It was created with the following command:
-certcreate -f thing2.pem -h fake-ca-2.example.com -e noreply@example.com \
- -S 1234 -o 'Twisted Matrix Labs'
-
-'certcreate' may be obtained from <http://divmod.org/trac/wiki/DivmodEpsilon>
-
------BEGIN CERTIFICATE-----
-MIICwjCCAisCAgTSMA0GCSqGSIb3DQEBBAUAMIGoMREwDwYDVQQLEwhTZWN1cml0
-eTEcMBoGA1UEChMTVHdpc3RlZCBNYXRyaXggTGFiczEeMBwGA1UEAxMVZmFrZS1j
-YS0yLmV4YW1wbGUuY29tMREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMx
-IjAgBgkqhkiG9w0BCQEWE25vcmVwbHlAZXhhbXBsZS5jb20xETAPBgNVBAcTCE5l
-dyBZb3JrMB4XDTEwMDkyMTAxMjUzMVoXDTExMDkyMTAxMjUzMVowgagxETAPBgNV
-BAsTCFNlY3VyaXR5MRwwGgYDVQQKExNUd2lzdGVkIE1hdHJpeCBMYWJzMR4wHAYD
-VQQDExVmYWtlLWNhLTIuZXhhbXBsZS5jb20xETAPBgNVBAgTCE5ldyBZb3JrMQsw
-CQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYTbm9yZXBseUBleGFtcGxlLmNvbTER
-MA8GA1UEBxMITmV3IFlvcmswgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn
-b3EcKqBedQed1qJC4uGVx8PYmn2vxL3QwCVW1w0VjpZXyhCq/2VrYBhJAXRzpfvE
-dCqhtJKcdifwavUrTfr4yXu1MvWA0YuaAkj1TbmlHHQYACf3h+MPOXroYzhT72bO
-FSSLDWuitj0ozR+2Fk15QwLWUxaYLmwylxXAf7vpAgMBAAEwDQYJKoZIhvcNAQEE
-BQADgYEADB2N6VHHhm5M2rJqqGDXMm2dU+7abxiuN+PUygN2LXIsqdGBS6U7/rta
-lJNVeRaM423c8imfuklkIBG9Msn5+xm1xIMIULoi/efActDLbsX1x6IyHQrG5aDP
-/RMKBio9RjS8ajgSwyYVUZiCZBsn/T0/JS8K61YLpiv4Tg8uXmM=
------END CERTIFICATE-----
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2.pem b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2.pem
deleted file mode 100644
index 429e1211..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fake_CAs/thing2.pem
+++ /dev/null
@@ -1,26 +0,0 @@
-
-This is a self-signed certificate authority certificate to be used in tests.
-
-It was created with the following command:
-certcreate -f thing2.pem -h fake-ca-2.example.com -e noreply@example.com \
- -S 1234 -o 'Twisted Matrix Labs'
-
-'certcreate' may be obtained from <http://divmod.org/trac/wiki/DivmodEpsilon>
-
------BEGIN CERTIFICATE-----
-MIICwjCCAisCAgTSMA0GCSqGSIb3DQEBBAUAMIGoMREwDwYDVQQLEwhTZWN1cml0
-eTEcMBoGA1UEChMTVHdpc3RlZCBNYXRyaXggTGFiczEeMBwGA1UEAxMVZmFrZS1j
-YS0yLmV4YW1wbGUuY29tMREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMx
-IjAgBgkqhkiG9w0BCQEWE25vcmVwbHlAZXhhbXBsZS5jb20xETAPBgNVBAcTCE5l
-dyBZb3JrMB4XDTEwMDkyMTAxMjUzMVoXDTExMDkyMTAxMjUzMVowgagxETAPBgNV
-BAsTCFNlY3VyaXR5MRwwGgYDVQQKExNUd2lzdGVkIE1hdHJpeCBMYWJzMR4wHAYD
-VQQDExVmYWtlLWNhLTIuZXhhbXBsZS5jb20xETAPBgNVBAgTCE5ldyBZb3JrMQsw
-CQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYTbm9yZXBseUBleGFtcGxlLmNvbTER
-MA8GA1UEBxMITmV3IFlvcmswgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn
-b3EcKqBedQed1qJC4uGVx8PYmn2vxL3QwCVW1w0VjpZXyhCq/2VrYBhJAXRzpfvE
-dCqhtJKcdifwavUrTfr4yXu1MvWA0YuaAkj1TbmlHHQYACf3h+MPOXroYzhT72bO
-FSSLDWuitj0ozR+2Fk15QwLWUxaYLmwylxXAf7vpAgMBAAEwDQYJKoZIhvcNAQEE
-BQADgYEADB2N6VHHhm5M2rJqqGDXMm2dU+7abxiuN+PUygN2LXIsqdGBS6U7/rta
-lJNVeRaM423c8imfuklkIBG9Msn5+xm1xIMIULoi/efActDLbsX1x6IyHQrG5aDP
-/RMKBio9RjS8ajgSwyYVUZiCZBsn/T0/JS8K61YLpiv4Tg8uXmM=
------END CERTIFICATE-----
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fakeendpoint.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fakeendpoint.py
deleted file mode 100755
index dbb74197..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/fakeendpoint.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_endpoints -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Fake client and server endpoint string parser plugins for testing purposes.
-"""
-
-from zope.interface.declarations import implements
-from twisted.plugin import IPlugin
-from twisted.internet.interfaces import (IStreamClientEndpoint,
- IStreamServerEndpoint,
- IStreamClientEndpointStringParser,
- IStreamServerEndpointStringParser)
-
-class PluginBase(object):
- implements(IPlugin)
-
- def __init__(self, pfx):
- self.prefix = pfx
-
-
-
-class FakeClientParser(PluginBase):
-
- implements(IStreamClientEndpointStringParser)
-
- def parseStreamClient(self, *a, **kw):
- return StreamClient(self, a, kw)
-
-
-
-class FakeParser(PluginBase):
-
- implements(IStreamServerEndpointStringParser)
-
- def parseStreamServer(self, *a, **kw):
- return StreamServer(self, a, kw)
-
-
-
-class EndpointBase(object):
-
- def __init__(self, parser, args, kwargs):
- self.parser = parser
- self.args = args
- self.kwargs = kwargs
-
-
-
-class StreamClient(EndpointBase):
-
- implements(IStreamClientEndpoint)
-
-
-
-class StreamServer(EndpointBase):
-
- implements(IStreamServerEndpoint)
-
-
-
-# Instantiate plugin interface providers to register them.
-fake = FakeParser('fake')
-fakeClient = FakeClientParser('cfake')
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/inlinecb_tests.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/inlinecb_tests.py
deleted file mode 100755
index a6d01218..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/inlinecb_tests.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_inlinecb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.defer.inlineCallbacks}.
-
-These tests are defined in a non-C{test_*} module because they are
-syntactically invalid on python < 2.5. test_inlinecb will conditionally import
-these tests on python 2.5 and greater.
-
-Some tests for inlineCallbacks are defined in L{twisted.test.test_defgen} as
-well: see U{http://twistedmatrix.com/trac/ticket/4182}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import Deferred, returnValue, inlineCallbacks
-
-class NonLocalExitTests(TestCase):
- """
- It's possible for L{returnValue} to be (accidentally) invoked at a stack
- level below the L{inlineCallbacks}-decorated function which it is exiting.
- If this happens, L{returnValue} should report useful errors.
-
- If L{returnValue} is invoked from a function not decorated by
- L{inlineCallbacks}, it will emit a warning if it causes an
- L{inlineCallbacks} function further up the stack to exit.
- """
-
- def mistakenMethod(self):
- """
- This method mistakenly invokes L{returnValue}, despite the fact that it
- is not decorated with L{inlineCallbacks}.
- """
- returnValue(1)
-
-
- def assertMistakenMethodWarning(self, resultList):
- """
- Flush the current warnings and assert that we have been told that
- C{mistakenMethod} was invoked, and that the result from the Deferred
- that was fired (appended to the given list) is C{mistakenMethod}'s
- result. The warning should indicate that an inlineCallbacks function
- called 'inline' was made to exit.
- """
- self.assertEqual(resultList, [1])
- warnings = self.flushWarnings(offendingFunctions=[self.mistakenMethod])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "returnValue() in 'mistakenMethod' causing 'inline' to exit: "
- "returnValue should only be invoked by functions decorated with "
- "inlineCallbacks")
-
-
- def test_returnValueNonLocalWarning(self):
- """
- L{returnValue} will emit a non-local exit warning in the simplest case,
- where the offending function is invoked immediately.
- """
- @inlineCallbacks
- def inline():
- self.mistakenMethod()
- returnValue(2)
- yield 0
- d = inline()
- results = []
- d.addCallback(results.append)
- self.assertMistakenMethodWarning(results)
-
-
- def test_returnValueNonLocalDeferred(self):
- """
- L{returnValue} will emit a non-local warning in the case where the
- L{inlineCallbacks}-decorated function has already yielded a Deferred
- and therefore moved its generator function along.
- """
- cause = Deferred()
- @inlineCallbacks
- def inline():
- yield cause
- self.mistakenMethod()
- returnValue(2)
- effect = inline()
- results = []
- effect.addCallback(results.append)
- self.assertEqual(results, [])
- cause.callback(1)
- self.assertMistakenMethodWarning(results)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/process_helper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/process_helper.py
deleted file mode 100755
index b921697a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/process_helper.py
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# A program which exits after starting a child which inherits its
-# stdin/stdout/stderr and keeps them open until stdin is closed.
-
-import sys, os
-
-def grandchild():
- sys.stdout.write('grandchild started')
- sys.stdout.flush()
- sys.stdin.read()
-
-def main():
- if sys.argv[1] == 'child':
- if sys.argv[2] == 'windows':
- import win32api as api, win32process as proc
- info = proc.STARTUPINFO()
- info.hStdInput = api.GetStdHandle(api.STD_INPUT_HANDLE)
- info.hStdOutput = api.GetStdHandle(api.STD_OUTPUT_HANDLE)
- info.hStdError = api.GetStdHandle(api.STD_ERROR_HANDLE)
- python = sys.executable
- scriptDir = os.path.dirname(__file__)
- scriptName = os.path.basename(__file__)
- proc.CreateProcess(
- None, " ".join((python, scriptName, "grandchild")), None,
- None, 1, 0, os.environ, scriptDir, info)
- else:
- if os.fork() == 0:
- grandchild()
- else:
- grandchild()
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/reactormixins.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/reactormixins.py
deleted file mode 100755
index dc9a5d59..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/reactormixins.py
+++ /dev/null
@@ -1,409 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorTime}.
-"""
-
-__metaclass__ = type
-
-import os, signal, time
-
-from twisted.internet.defer import TimeoutError, Deferred, gatherResults
-from twisted.internet.protocol import ClientFactory, Protocol
-from twisted.trial.unittest import TestCase, SkipTest
-from twisted.python.runtime import platform
-from twisted.python.reflect import namedAny, fullyQualifiedName
-from twisted.python import log
-from twisted.python.failure import Failure
-
-# Access private APIs.
-if platform.isWindows():
- process = None
-else:
- from twisted.internet import process
-
-
-
-def needsRunningReactor(reactor, thunk):
- """
- Various functions within these tests need an already-running reactor at
- some point. They need to stop the reactor when the test has completed, and
- that means calling reactor.stop(). However, reactor.stop() raises an
- exception if the reactor isn't already running, so if the L{Deferred} that
- a particular API under test returns fires synchronously (as especially an
- endpoint's C{connect()} method may do, if the connect is to a local
- interface address) then the test won't be able to stop the reactor being
- tested and finish. So this calls C{thunk} only once C{reactor} is running.
-
- (This is just an alias for
- L{twisted.internet.interfaces.IReactorCore.callWhenRunning} on the given
- reactor parameter, in order to centrally reference the above paragraph and
- repeating it everywhere as a comment.)
-
- @param reactor: the L{twisted.internet.interfaces.IReactorCore} under test
-
- @param thunk: a 0-argument callable, which eventually finishes the test in
- question, probably in a L{Deferred} callback.
- """
- reactor.callWhenRunning(thunk)
-
-
-
-class ConnectableProtocol(Protocol):
- """
- A protocol to be used with L{runProtocolsWithReactor}.
-
- The protocol and its pair should eventually disconnect from each other.
-
- @ivar reactor: The reactor used in this test.
-
- @ivar disconnectReason: The L{Failure} passed to C{connectionLost}.
-
- @ivar _done: A L{Deferred} which will be fired when the connection is
- lost.
- """
-
- disconnectReason = None
-
- def _setAttributes(self, reactor, done):
- """
- Set attributes on the protocol that are known only externally; this
- will be called by L{runProtocolsWithReactor} when this protocol is
- instantiated.
-
- @param reactor: The reactor used in this test.
-
- @param done: A L{Deferred} which will be fired when the connection is
- lost.
- """
- self.reactor = reactor
- self._done = done
-
-
- def connectionLost(self, reason):
- self.disconnectReason = reason
- self._done.callback(None)
- del self._done
-
-
-
-class EndpointCreator:
- """
- Create client and server endpoints that know how to connect to each other.
- """
-
- def server(self, reactor):
- """
- Return an object providing C{IStreamServerEndpoint} for use in creating
- a server to use to establish the connection type to be tested.
- """
- raise NotImplementedError()
-
-
- def client(self, reactor, serverAddress):
- """
- Return an object providing C{IStreamClientEndpoint} for use in creating
- a client to use to establish the connection type to be tested.
- """
- raise NotImplementedError()
-
-
-
-class _SingleProtocolFactory(ClientFactory):
- """
- Factory to be used by L{runProtocolsWithReactor}.
-
- It always returns the same protocol (i.e. is intended for only a single connection).
- """
-
- def __init__(self, protocol):
- self._protocol = protocol
-
-
- def buildProtocol(self, addr):
- return self._protocol
-
-
-
-def runProtocolsWithReactor(reactorBuilder, serverProtocol, clientProtocol,
- endpointCreator):
- """
- Connect two protocols using endpoints and a new reactor instance.
-
- A new reactor will be created and run, with the client and server protocol
- instances connected to each other using the given endpoint creator. The
- protocols should run through some set of tests, then disconnect; when both
- have disconnected the reactor will be stopped and the function will
- return.
-
- @param reactorBuilder: A L{ReactorBuilder} instance.
-
- @param serverProtocol: A L{ConnectableProtocol} that will be the server.
-
- @param clientProtocol: A L{ConnectableProtocol} that will be the client.
-
- @param endpointCreator: An instance of L{EndpointCreator}.
-
- @return: The reactor run by this test.
- """
- reactor = reactorBuilder.buildReactor()
- serverProtocol._setAttributes(reactor, Deferred())
- clientProtocol._setAttributes(reactor, Deferred())
- serverFactory = _SingleProtocolFactory(serverProtocol)
- clientFactory = _SingleProtocolFactory(clientProtocol)
-
- # Listen on a port:
- serverEndpoint = endpointCreator.server(reactor)
- d = serverEndpoint.listen(serverFactory)
-
- # Connect to the port:
- def gotPort(p):
- clientEndpoint = endpointCreator.client(
- reactor, p.getHost())
- return clientEndpoint.connect(clientFactory)
- d.addCallback(gotPort)
-
- # Stop reactor when both connections are lost:
- def failed(result):
- log.err(result, "Connection setup failed.")
- disconnected = gatherResults([serverProtocol._done, clientProtocol._done])
- d.addCallback(lambda _: disconnected)
- d.addErrback(failed)
- d.addCallback(lambda _: needsRunningReactor(reactor, reactor.stop))
-
- reactorBuilder.runReactor(reactor)
- return reactor
-
-
-
-class ReactorBuilder:
- """
- L{TestCase} mixin which provides a reactor-creation API. This mixin
- defines C{setUp} and C{tearDown}, so mix it in before L{TestCase} or call
- its methods from the overridden ones in the subclass.
-
- @cvar skippedReactors: A dict mapping FQPN strings of reactors for
- which the tests defined by this class will be skipped to strings
- giving the skip message.
- @cvar requiredInterfaces: A C{list} of interfaces which the reactor must
- provide or these tests will be skipped. The default, C{None}, means
- that no interfaces are required.
- @ivar reactorFactory: A no-argument callable which returns the reactor to
- use for testing.
- @ivar originalHandler: The SIGCHLD handler which was installed when setUp
- ran and which will be re-installed when tearDown runs.
- @ivar _reactors: A list of FQPN strings giving the reactors for which
- TestCases will be created.
- """
-
- _reactors = [
- # Select works everywhere
- "twisted.internet.selectreactor.SelectReactor",
- ]
-
- if platform.isWindows():
- # PortableGtkReactor is only really interesting on Windows,
- # but not really Windows specific; if you want you can
- # temporarily move this up to the all-platforms list to test
- # it on other platforms. It's not there in general because
- # it's not _really_ worth it to support on other platforms,
- # since no one really wants to use it on other platforms.
- _reactors.extend([
- "twisted.internet.gtk2reactor.PortableGtkReactor",
- "twisted.internet.gireactor.PortableGIReactor",
- "twisted.internet.gtk3reactor.PortableGtk3Reactor",
- "twisted.internet.win32eventreactor.Win32Reactor",
- "twisted.internet.iocpreactor.reactor.IOCPReactor"])
- else:
- _reactors.extend([
- "twisted.internet.glib2reactor.Glib2Reactor",
- "twisted.internet.gtk2reactor.Gtk2Reactor",
- "twisted.internet.gireactor.GIReactor",
- "twisted.internet.gtk3reactor.Gtk3Reactor"])
- if platform.isMacOSX():
- _reactors.append("twisted.internet.cfreactor.CFReactor")
- else:
- _reactors.extend([
- "twisted.internet.pollreactor.PollReactor",
- "twisted.internet.epollreactor.EPollReactor"])
- if not platform.isLinux():
- # Presumably Linux is not going to start supporting kqueue, so
- # skip even trying this configuration.
- _reactors.extend([
- # Support KQueue on non-OS-X POSIX platforms for now.
- "twisted.internet.kqreactor.KQueueReactor",
- ])
-
- reactorFactory = None
- originalHandler = None
- requiredInterfaces = None
- skippedReactors = {}
-
- def setUp(self):
- """
- Clear the SIGCHLD handler, if there is one, to ensure an environment
- like the one which exists prior to a call to L{reactor.run}.
- """
- if not platform.isWindows():
- self.originalHandler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
-
-
- def tearDown(self):
- """
- Restore the original SIGCHLD handler and reap processes as long as
- there seem to be any remaining.
- """
- if self.originalHandler is not None:
- signal.signal(signal.SIGCHLD, self.originalHandler)
- if process is not None:
- begin = time.time()
- while process.reapProcessHandlers:
- log.msg(
- "ReactorBuilder.tearDown reaping some processes %r" % (
- process.reapProcessHandlers,))
- process.reapAllProcesses()
-
- # The process should exit on its own. However, if it
- # doesn't, we're stuck in this loop forever. To avoid
- # hanging the test suite, eventually give the process some
- # help exiting and move on.
- time.sleep(0.001)
- if time.time() - begin > 60:
- for pid in process.reapProcessHandlers:
- os.kill(pid, signal.SIGKILL)
- raise Exception(
- "Timeout waiting for child processes to exit: %r" % (
- process.reapProcessHandlers,))
-
-
- def unbuildReactor(self, reactor):
- """
- Clean up any resources which may have been allocated for the given
- reactor by its creation or by a test which used it.
- """
- # Chris says:
- #
- # XXX These explicit calls to clean up the waker (and any other
- # internal readers) should become obsolete when bug #3063 is
- # fixed. -radix, 2008-02-29. Fortunately it should probably cause an
- # error when bug #3063 is fixed, so it should be removed in the same
- # branch that fixes it.
- #
- # -exarkun
- reactor._uninstallHandler()
- if getattr(reactor, '_internalReaders', None) is not None:
- for reader in reactor._internalReaders:
- reactor.removeReader(reader)
- reader.connectionLost(None)
- reactor._internalReaders.clear()
-
- # Here's an extra thing unrelated to wakers but necessary for
- # cleaning up after the reactors we make. -exarkun
- reactor.disconnectAll()
-
- # It would also be bad if any timed calls left over were allowed to
- # run.
- calls = reactor.getDelayedCalls()
- for c in calls:
- c.cancel()
-
-
- def buildReactor(self):
- """
- Create and return a reactor using C{self.reactorFactory}.
- """
- try:
- from twisted.internet.cfreactor import CFReactor
- from twisted.internet import reactor as globalReactor
- except ImportError:
- pass
- else:
- if (isinstance(globalReactor, CFReactor)
- and self.reactorFactory is CFReactor):
- raise SkipTest(
- "CFReactor uses APIs which manipulate global state, "
- "so it's not safe to run its own reactor-builder tests "
- "under itself")
- try:
- reactor = self.reactorFactory()
- except:
- # Unfortunately, not all errors which result in a reactor
- # being unusable are detectable without actually
- # instantiating the reactor. So we catch some more here
- # and skip the test if necessary. We also log it to aid
- # with debugging, but flush the logged error so the test
- # doesn't fail.
- log.err(None, "Failed to install reactor")
- self.flushLoggedErrors()
- raise SkipTest(Failure().getErrorMessage())
- else:
- if self.requiredInterfaces is not None:
- missing = filter(
- lambda required: not required.providedBy(reactor),
- self.requiredInterfaces)
- if missing:
- self.unbuildReactor(reactor)
- raise SkipTest("%s does not provide %s" % (
- fullyQualifiedName(reactor.__class__),
- ",".join([fullyQualifiedName(x) for x in missing])))
- self.addCleanup(self.unbuildReactor, reactor)
- return reactor
-
-
- def runReactor(self, reactor, timeout=None):
- """
- Run the reactor for at most the given amount of time.
-
- @param reactor: The reactor to run.
-
- @type timeout: C{int} or C{float}
- @param timeout: The maximum amount of time, specified in seconds, to
- allow the reactor to run. If the reactor is still running after
- this much time has elapsed, it will be stopped and an exception
- raised. If C{None}, the default test method timeout imposed by
- Trial will be used. This depends on the L{IReactorTime}
- implementation of C{reactor} for correct operation.
-
- @raise TimeoutError: If the reactor is still running after C{timeout}
- seconds.
- """
- if timeout is None:
- timeout = self.getTimeout()
-
- timedOut = []
- def stop():
- timedOut.append(None)
- reactor.stop()
-
- reactor.callLater(timeout, stop)
- reactor.run()
- if timedOut:
- raise TimeoutError(
- "reactor still running after %s seconds" % (timeout,))
-
-
- def makeTestCaseClasses(cls):
- """
- Create a L{TestCase} subclass which mixes in C{cls} for each known
- reactor and return a dict mapping their names to them.
- """
- classes = {}
- for reactor in cls._reactors:
- shortReactorName = reactor.split(".")[-1]
- name = (cls.__name__ + "." + shortReactorName).replace(".", "_")
- class testcase(cls, TestCase):
- __module__ = cls.__module__
- if reactor in cls.skippedReactors:
- skip = cls.skippedReactors[reactor]
- try:
- reactorFactory = namedAny(reactor)
- except:
- skip = Failure().getErrorMessage()
- testcase.__name__ = name
- classes[testcase.__name__] = testcase
- return classes
- makeTestCaseClasses = classmethod(makeTestCaseClasses)
-
-
-__all__ = ['ReactorBuilder']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_abstract.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_abstract.py
deleted file mode 100755
index 5e9c0cfc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_abstract.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.abstract}, a collection of APIs for implementing
-reactors.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.internet.abstract import isIPv6Address
-
-class IPv6AddressTests(TestCase):
- """
- Tests for L{isIPv6Address}, a function for determining if a particular
- string is an IPv6 address literal.
- """
- def test_empty(self):
- """
- The empty string is not an IPv6 address literal.
- """
- self.assertFalse(isIPv6Address(""))
-
-
- def test_colon(self):
- """
- A single C{":"} is not an IPv6 address literal.
- """
- self.assertFalse(isIPv6Address(":"))
-
-
- def test_loopback(self):
- """
- C{"::1"} is the IPv6 loopback address literal.
- """
- self.assertTrue(isIPv6Address("::1"))
-
-
- def test_scopeID(self):
- """
- An otherwise valid IPv6 address literal may also include a C{"%"}
- followed by an arbitrary scope identifier.
- """
- self.assertTrue(isIPv6Address("fe80::1%eth0"))
- self.assertTrue(isIPv6Address("fe80::2%1"))
- self.assertTrue(isIPv6Address("fe80::3%en2"))
-
-
- def test_invalidWithScopeID(self):
- """
- An otherwise invalid IPv6 address literal is still invalid with a
- trailing scope identifier.
- """
- self.assertFalse(isIPv6Address("%eth0"))
- self.assertFalse(isIPv6Address(":%eth0"))
- self.assertFalse(isIPv6Address("hello%eth0"))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_address.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_address.py
deleted file mode 100755
index 5007e3a3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_address.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import re
-import os
-
-from twisted.trial import unittest
-from twisted.internet.address import IPv4Address, UNIXAddress
-
-try:
- os.symlink
-except AttributeError:
- symlinkSkip = "Platform does not support symlinks"
-else:
- symlinkSkip = None
-
-
-class AddressTestCaseMixin(object):
- def test_addressComparison(self):
- """
- Two different address instances, sharing the same properties are
- considered equal by C{==} and not considered not equal by C{!=}.
-
- Note: When applied via UNIXAddress class, this uses the same
- filename for both objects being compared.
- """
- self.assertTrue(self.buildAddress() == self.buildAddress())
- self.assertFalse(self.buildAddress() != self.buildAddress())
-
-
- def _stringRepresentation(self, stringFunction):
- """
- Verify that the string representation of an address object conforms to a
- simple pattern (the usual one for Python object reprs) and contains
- values which accurately reflect the attributes of the address.
- """
- addr = self.buildAddress()
- pattern = "".join([
- "^",
- "([^\(]+Address)", # class name,
- "\(", # opening bracket,
- "([^)]+)", # arguments,
- "\)", # closing bracket,
- "$"
- ])
- stringValue = stringFunction(addr)
- m = re.match(pattern, stringValue)
- self.assertNotEquals(
- None, m,
- "%s does not match the standard __str__ pattern "
- "ClassName(arg1, arg2, etc)" % (stringValue,))
- self.assertEqual(addr.__class__.__name__, m.group(1))
-
- args = [x.strip() for x in m.group(2).split(",")]
- self.assertEqual(
- args,
- [argSpec[1] % (getattr(addr, argSpec[0]),) for argSpec in self.addressArgSpec])
-
-
- def test_str(self):
- """
- C{str} can be used to get a string representation of an address instance
- containing information about that address.
- """
- self._stringRepresentation(str)
-
-
- def test_repr(self):
- """
- C{repr} can be used to get a string representation of an address
- instance containing information about that address.
- """
- self._stringRepresentation(repr)
-
-
- def test_hash(self):
- """
- C{__hash__} can be used to get a hash of an address, allowing
- addresses to be used as keys in dictionaries, for instance.
- """
- addr = self.buildAddress()
- d = {addr: True}
- self.assertTrue(d[self.buildAddress()])
-
-
- def test_differentNamesComparison(self):
- """
- Check that comparison operators work correctly on address objects
- when a different name is passed in
- """
- self.assertFalse(self.buildAddress() == self.buildDifferentAddress())
- self.assertFalse(self.buildDifferentAddress() == self.buildAddress())
-
- self.assertTrue(self.buildAddress() != self.buildDifferentAddress())
- self.assertTrue(self.buildDifferentAddress() != self.buildAddress())
-
-
- def assertDeprecations(self, testMethod, message):
- """
- Assert that the a DeprecationWarning with the given message was
- emitted against the given method.
- """
- warnings = self.flushWarnings([testMethod])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(warnings[0]['message'], message)
- self.assertEqual(len(warnings), 1)
-
-
-
-class IPv4AddressTestCaseMixin(AddressTestCaseMixin):
- addressArgSpec = (("type", "%s"), ("host", "%r"), ("port", "%d"))
-
-
-
-class IPv4AddressTCPTestCase(unittest.TestCase, IPv4AddressTestCaseMixin):
- def buildAddress(self):
- """
- Create an arbitrary new L{IPv4Address} instance with a C{"TCP"}
- type. A new instance is created for each call, but always for the
- same address.
- """
- return IPv4Address("TCP", "127.0.0.1", 0)
-
-
- def buildDifferentAddress(self):
- """
- Like L{buildAddress}, but with a different fixed address.
- """
- return IPv4Address("TCP", "127.0.0.2", 0)
-
-
- def test_bwHackDeprecation(self):
- """
- If a value is passed for the C{_bwHack} parameter to L{IPv4Address},
- a deprecation warning is emitted.
- """
- # Construct this for warning side-effects, disregard the actual object.
- IPv4Address("TCP", "127.0.0.3", 0, _bwHack="TCP")
-
- message = (
- "twisted.internet.address.IPv4Address._bwHack is deprecated "
- "since Twisted 11.0")
- return self.assertDeprecations(self.test_bwHackDeprecation, message)
-
-
-
-class IPv4AddressUDPTestCase(unittest.TestCase, IPv4AddressTestCaseMixin):
- def buildAddress(self):
- """
- Create an arbitrary new L{IPv4Address} instance with a C{"UDP"}
- type. A new instance is created for each call, but always for the
- same address.
- """
- return IPv4Address("UDP", "127.0.0.1", 0)
-
-
- def buildDifferentAddress(self):
- """
- Like L{buildAddress}, but with a different fixed address.
- """
- return IPv4Address("UDP", "127.0.0.2", 0)
-
-
- def test_bwHackDeprecation(self):
- """
- If a value is passed for the C{_bwHack} parameter to L{IPv4Address},
- a deprecation warning is emitted.
- """
- # Construct this for warning side-effects, disregard the actual object.
- IPv4Address("UDP", "127.0.0.3", 0, _bwHack="UDP")
-
- message = (
- "twisted.internet.address.IPv4Address._bwHack is deprecated "
- "since Twisted 11.0")
- return self.assertDeprecations(self.test_bwHackDeprecation, message)
-
-
-
-class UNIXAddressTestCase(unittest.TestCase, AddressTestCaseMixin):
- addressArgSpec = (("name", "%r"),)
-
- def setUp(self):
- self._socketAddress = self.mktemp()
- self._otherAddress = self.mktemp()
-
-
- def buildAddress(self):
- """
- Create an arbitrary new L{UNIXAddress} instance. A new instance is
- created for each call, but always for the same address.
- """
- return UNIXAddress(self._socketAddress)
-
-
- def buildDifferentAddress(self):
- """
- Like L{buildAddress}, but with a different fixed address.
- """
- return UNIXAddress(self._otherAddress)
-
-
- def test_comparisonOfLinkedFiles(self):
- """
- UNIXAddress objects compare as equal if they link to the same file.
- """
- linkName = self.mktemp()
- self.fd = open(self._socketAddress, 'w')
- os.symlink(os.path.abspath(self._socketAddress), linkName)
- self.assertTrue(
- UNIXAddress(self._socketAddress) == UNIXAddress(linkName))
- self.assertTrue(
- UNIXAddress(linkName) == UNIXAddress(self._socketAddress))
- test_comparisonOfLinkedFiles.skip = symlinkSkip
-
-
- def test_hashOfLinkedFiles(self):
- """
- UNIXAddress Objects that compare as equal have the same hash value.
- """
- linkName = self.mktemp()
- self.fd = open(self._socketAddress, 'w')
- os.symlink(os.path.abspath(self._socketAddress), linkName)
- self.assertEqual(
- hash(UNIXAddress(self._socketAddress)), hash(UNIXAddress(linkName)))
- test_hashOfLinkedFiles.skip = symlinkSkip
-
-
- def test_bwHackDeprecation(self):
- """
- If a value is passed for the C{_bwHack} parameter to L{UNIXAddress},
- a deprecation warning is emitted.
- """
- # Construct this for warning side-effects, disregard the actual object.
- UNIXAddress(self.mktemp(), _bwHack='UNIX')
-
- message = (
- "twisted.internet.address.UNIXAddress._bwHack is deprecated "
- "since Twisted 11.0")
- return self.assertDeprecations(self.test_bwHackDeprecation, message)
-
-
-
-class EmptyUNIXAddressTestCase(unittest.TestCase, AddressTestCaseMixin):
- """
- Tests for L{UNIXAddress} operations involving a C{None} address.
- """
- addressArgSpec = (("name", "%r"),)
-
- def setUp(self):
- self._socketAddress = self.mktemp()
-
-
- def buildAddress(self):
- """
- Create an arbitrary new L{UNIXAddress} instance. A new instance is
- created for each call, but always for the same address.
- """
- return UNIXAddress(self._socketAddress)
-
-
- def buildDifferentAddress(self):
- """
- Like L{buildAddress}, but with a fixed address of C{None}.
- """
- return UNIXAddress(None)
-
-
- def test_comparisonOfLinkedFiles(self):
- """
- A UNIXAddress referring to a C{None} address does not compare equal to a
- UNIXAddress referring to a symlink.
- """
- linkName = self.mktemp()
- self.fd = open(self._socketAddress, 'w')
- os.symlink(os.path.abspath(self._socketAddress), linkName)
- self.assertTrue(
- UNIXAddress(self._socketAddress) != UNIXAddress(None))
- self.assertTrue(
- UNIXAddress(None) != UNIXAddress(self._socketAddress))
- test_comparisonOfLinkedFiles.skip = symlinkSkip
-
-
- def test_emptyHash(self):
- """
- C{__hash__} can be used to get a hash of an address, even one referring
- to C{None} rather than a real path.
- """
- addr = self.buildDifferentAddress()
- d = {addr: True}
- self.assertTrue(d[self.buildDifferentAddress()])
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_base.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_base.py
deleted file mode 100755
index 6cab8fad..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_base.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.base}.
-"""
-
-import socket
-from Queue import Queue
-
-from zope.interface import implements
-
-from twisted.python.threadpool import ThreadPool
-from twisted.python.util import setIDFunction
-from twisted.internet.interfaces import IReactorTime, IReactorThreads
-from twisted.internet.error import DNSLookupError
-from twisted.internet.base import ThreadedResolver, DelayedCall
-from twisted.internet.task import Clock
-from twisted.trial.unittest import TestCase
-
-
-class FakeReactor(object):
- """
- A fake reactor implementation which just supports enough reactor APIs for
- L{ThreadedResolver}.
- """
- implements(IReactorTime, IReactorThreads)
-
- def __init__(self):
- self._clock = Clock()
- self.callLater = self._clock.callLater
-
- self._threadpool = ThreadPool()
- self._threadpool.start()
- self.getThreadPool = lambda: self._threadpool
-
- self._threadCalls = Queue()
-
-
- def callFromThread(self, f, *args, **kwargs):
- self._threadCalls.put((f, args, kwargs))
-
-
- def _runThreadCalls(self):
- f, args, kwargs = self._threadCalls.get()
- f(*args, **kwargs)
-
-
- def _stop(self):
- self._threadpool.stop()
-
-
-
-class ThreadedResolverTests(TestCase):
- """
- Tests for L{ThreadedResolver}.
- """
- def test_success(self):
- """
- L{ThreadedResolver.getHostByName} returns a L{Deferred} which fires
- with the value returned by the call to L{socket.gethostbyname} in the
- threadpool of the reactor passed to L{ThreadedResolver.__init__}.
- """
- ip = "10.0.0.17"
- name = "foo.bar.example.com"
- timeout = 30
-
- reactor = FakeReactor()
- self.addCleanup(reactor._stop)
-
- lookedUp = []
- resolvedTo = []
- def fakeGetHostByName(name):
- lookedUp.append(name)
- return ip
-
- self.patch(socket, 'gethostbyname', fakeGetHostByName)
-
- resolver = ThreadedResolver(reactor)
- d = resolver.getHostByName(name, (timeout,))
- d.addCallback(resolvedTo.append)
-
- reactor._runThreadCalls()
-
- self.assertEqual(lookedUp, [name])
- self.assertEqual(resolvedTo, [ip])
-
- # Make sure that any timeout-related stuff gets cleaned up.
- reactor._clock.advance(timeout + 1)
- self.assertEqual(reactor._clock.calls, [])
-
-
- def test_failure(self):
- """
- L{ThreadedResolver.getHostByName} returns a L{Deferred} which fires a
- L{Failure} if the call to L{socket.gethostbyname} raises an exception.
- """
- timeout = 30
-
- reactor = FakeReactor()
- self.addCleanup(reactor._stop)
-
- def fakeGetHostByName(name):
- raise IOError("ENOBUFS (this is a funny joke)")
-
- self.patch(socket, 'gethostbyname', fakeGetHostByName)
-
- failedWith = []
- resolver = ThreadedResolver(reactor)
- d = resolver.getHostByName("some.name", (timeout,))
- self.assertFailure(d, DNSLookupError)
- d.addCallback(failedWith.append)
-
- reactor._runThreadCalls()
-
- self.assertEqual(len(failedWith), 1)
-
- # Make sure that any timeout-related stuff gets cleaned up.
- reactor._clock.advance(timeout + 1)
- self.assertEqual(reactor._clock.calls, [])
-
-
- def test_timeout(self):
- """
- If L{socket.gethostbyname} does not complete before the specified
- timeout elapsed, the L{Deferred} returned by
- L{ThreadedResolver.getHostByBame} fails with L{DNSLookupError}.
- """
- timeout = 10
-
- reactor = FakeReactor()
- self.addCleanup(reactor._stop)
-
- result = Queue()
- def fakeGetHostByName(name):
- raise result.get()
-
- self.patch(socket, 'gethostbyname', fakeGetHostByName)
-
- failedWith = []
- resolver = ThreadedResolver(reactor)
- d = resolver.getHostByName("some.name", (timeout,))
- self.assertFailure(d, DNSLookupError)
- d.addCallback(failedWith.append)
-
- reactor._clock.advance(timeout - 1)
- self.assertEqual(failedWith, [])
- reactor._clock.advance(1)
- self.assertEqual(len(failedWith), 1)
-
- # Eventually the socket.gethostbyname does finish - in this case, with
- # an exception. Nobody cares, though.
- result.put(IOError("The I/O was errorful"))
-
-
-
-class DelayedCallTests(TestCase):
- """
- Tests for L{DelayedCall}.
- """
- def _getDelayedCallAt(self, time):
- """
- Get a L{DelayedCall} instance at a given C{time}.
-
- @param time: The absolute time at which the returned L{DelayedCall}
- will be scheduled.
- """
- def noop(call):
- pass
- return DelayedCall(time, lambda: None, (), {}, noop, noop, None)
-
-
- def setUp(self):
- """
- Create two L{DelayedCall} instanced scheduled to run at different
- times.
- """
- self.zero = self._getDelayedCallAt(0)
- self.one = self._getDelayedCallAt(1)
-
-
- def test_str(self):
- """
- The string representation of a L{DelayedCall} instance, as returned by
- C{str}, includes the unsigned id of the instance, as well as its state,
- the function to be called, and the function arguments.
- """
- def nothing():
- pass
- dc = DelayedCall(12, nothing, (3, ), {"A": 5}, None, None, lambda: 1.5)
- ids = {dc: 200}
- def fakeID(obj):
- try:
- return ids[obj]
- except (TypeError, KeyError):
- return id(obj)
- self.addCleanup(setIDFunction, setIDFunction(fakeID))
- self.assertEqual(
- str(dc),
- "<DelayedCall 0xc8 [10.5s] called=0 cancelled=0 nothing(3, A=5)>")
-
-
- def test_lt(self):
- """
- For two instances of L{DelayedCall} C{a} and C{b}, C{a < b} is true
- if and only if C{a} is scheduled to run before C{b}.
- """
- zero, one = self.zero, self.one
- self.assertTrue(zero < one)
- self.assertFalse(one < zero)
- self.assertFalse(zero < zero)
- self.assertFalse(one < one)
-
-
- def test_le(self):
- """
- For two instances of L{DelayedCall} C{a} and C{b}, C{a <= b} is true
- if and only if C{a} is scheduled to run before C{b} or at the same
- time as C{b}.
- """
- zero, one = self.zero, self.one
- self.assertTrue(zero <= one)
- self.assertFalse(one <= zero)
- self.assertTrue(zero <= zero)
- self.assertTrue(one <= one)
-
-
- def test_gt(self):
- """
- For two instances of L{DelayedCall} C{a} and C{b}, C{a > b} is true
- if and only if C{a} is scheduled to run after C{b}.
- """
- zero, one = self.zero, self.one
- self.assertTrue(one > zero)
- self.assertFalse(zero > one)
- self.assertFalse(zero > zero)
- self.assertFalse(one > one)
-
-
- def test_ge(self):
- """
- For two instances of L{DelayedCall} C{a} and C{b}, C{a > b} is true
- if and only if C{a} is scheduled to run after C{b} or at the same
- time as C{b}.
- """
- zero, one = self.zero, self.one
- self.assertTrue(one >= zero)
- self.assertFalse(zero >= one)
- self.assertTrue(zero >= zero)
- self.assertTrue(one >= one)
-
-
- def test_eq(self):
- """
- A L{DelayedCall} instance is only equal to itself.
- """
- # Explicitly use == here, instead of assertEqual, to be more
- # confident __eq__ is being tested.
- self.assertFalse(self.zero == self.one)
- self.assertTrue(self.zero == self.zero)
- self.assertTrue(self.one == self.one)
-
-
- def test_ne(self):
- """
- A L{DelayedCall} instance is not equal to any other object.
- """
- # Explicitly use != here, instead of assertEqual, to be more
- # confident __ne__ is being tested.
- self.assertTrue(self.zero != self.one)
- self.assertFalse(self.zero != self.zero)
- self.assertFalse(self.one != self.one)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_baseprocess.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_baseprocess.py
deleted file mode 100755
index 750b6604..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_baseprocess.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet._baseprocess} which implements process-related
-functionality that is useful in all platforms supporting L{IReactorProcess}.
-"""
-
-__metaclass__ = type
-
-from twisted.python.deprecate import getWarningMethod, setWarningMethod
-from twisted.trial.unittest import TestCase
-from twisted.internet._baseprocess import BaseProcess
-
-
-class BaseProcessTests(TestCase):
- """
- Tests for L{BaseProcess}, a parent class for other classes which represent
- processes which implements functionality common to many different process
- implementations.
- """
- def test_callProcessExited(self):
- """
- L{BaseProcess._callProcessExited} calls the C{processExited} method of
- its C{proto} attribute and passes it a L{Failure} wrapping the given
- exception.
- """
- class FakeProto:
- reason = None
-
- def processExited(self, reason):
- self.reason = reason
-
- reason = RuntimeError("fake reason")
- process = BaseProcess(FakeProto())
- process._callProcessExited(reason)
- process.proto.reason.trap(RuntimeError)
- self.assertIdentical(reason, process.proto.reason.value)
-
-
- def test_callProcessExitedMissing(self):
- """
- L{BaseProcess._callProcessExited} emits a L{DeprecationWarning} if the
- object referred to by its C{proto} attribute has no C{processExited}
- method.
- """
- class FakeProto:
- pass
-
- reason = object()
- process = BaseProcess(FakeProto())
-
- self.addCleanup(setWarningMethod, getWarningMethod())
- warnings = []
- def collect(message, category, stacklevel):
- warnings.append((message, category, stacklevel))
- setWarningMethod(collect)
-
- process._callProcessExited(reason)
-
- [(message, category, stacklevel)] = warnings
- self.assertEqual(
- message,
- "Since Twisted 8.2, IProcessProtocol.processExited is required. "
- "%s.%s must implement it." % (
- FakeProto.__module__, FakeProto.__name__))
- self.assertIdentical(category, DeprecationWarning)
- # The stacklevel doesn't really make sense for this kind of
- # deprecation. Requiring it to be 0 will at least avoid pointing to
- # any part of Twisted or a random part of the application's code, which
- # I think would be more misleading than having it point inside the
- # warning system itself. -exarkun
- self.assertEqual(stacklevel, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_core.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_core.py
deleted file mode 100755
index 6b2161f6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_core.py
+++ /dev/null
@@ -1,331 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorCore}.
-"""
-
-__metaclass__ = type
-
-import signal
-import time
-import inspect
-
-from twisted.internet.abstract import FileDescriptor
-from twisted.internet.error import ReactorAlreadyRunning, ReactorNotRestartable
-from twisted.internet.defer import Deferred
-from twisted.internet.test.reactormixins import ReactorBuilder
-
-
-class ObjectModelIntegrationMixin(object):
- """
- Helpers for tests about the object model of reactor-related objects.
- """
- def assertFullyNewStyle(self, instance):
- """
- Assert that the given object is an instance of a new-style class and
- that there are no classic classes in the inheritance hierarchy of
- that class.
-
- This is a beneficial condition because PyPy is better able to
- optimize attribute lookup on such classes.
- """
- self.assertIsInstance(instance, object)
- mro = inspect.getmro(type(instance))
- for subclass in mro:
- self.assertTrue(
- issubclass(subclass, object),
- "%r is not new-style" % (subclass,))
-
-
-
-class ObjectModelIntegrationTest(ReactorBuilder, ObjectModelIntegrationMixin):
- """
- Test details of object model integration against all reactors.
- """
-
- def test_newstyleReactor(self):
- """
- Checks that all reactors on a platform have method resolution order
- containing only new style classes.
- """
- reactor = self.buildReactor()
- self.assertFullyNewStyle(reactor)
-
-
-
-class SystemEventTestsBuilder(ReactorBuilder):
- """
- Builder defining tests relating to L{IReactorCore.addSystemEventTrigger}
- and L{IReactorCore.fireSystemEvent}.
- """
- def test_stopWhenNotStarted(self):
- """
- C{reactor.stop()} raises L{RuntimeError} when called when the reactor
- has not been started.
- """
- reactor = self.buildReactor()
- self.assertRaises(RuntimeError, reactor.stop)
-
-
- def test_stopWhenAlreadyStopped(self):
- """
- C{reactor.stop()} raises L{RuntimeError} when called after the reactor
- has been stopped.
- """
- reactor = self.buildReactor()
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- self.assertRaises(RuntimeError, reactor.stop)
-
-
- def test_callWhenRunningOrder(self):
- """
- Functions are run in the order that they were passed to
- L{reactor.callWhenRunning}.
- """
- reactor = self.buildReactor()
- events = []
- reactor.callWhenRunning(events.append, "first")
- reactor.callWhenRunning(events.append, "second")
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- self.assertEqual(events, ["first", "second"])
-
-
- def test_runningForStartupEvents(self):
- """
- The reactor is not running when C{"before"} C{"startup"} triggers are
- called and is running when C{"during"} and C{"after"} C{"startup"}
- triggers are called.
- """
- reactor = self.buildReactor()
- state = {}
- def beforeStartup():
- state['before'] = reactor.running
- def duringStartup():
- state['during'] = reactor.running
- def afterStartup():
- state['after'] = reactor.running
- reactor.addSystemEventTrigger("before", "startup", beforeStartup)
- reactor.addSystemEventTrigger("during", "startup", duringStartup)
- reactor.addSystemEventTrigger("after", "startup", afterStartup)
- reactor.callWhenRunning(reactor.stop)
- self.assertEqual(state, {})
- self.runReactor(reactor)
- self.assertEqual(
- state,
- {"before": False,
- "during": True,
- "after": True})
-
-
- def test_signalHandlersInstalledDuringStartup(self):
- """
- Signal handlers are installed in responsed to the C{"during"}
- C{"startup"}.
- """
- reactor = self.buildReactor()
- phase = [None]
- def beforeStartup():
- phase[0] = "before"
- def afterStartup():
- phase[0] = "after"
- reactor.addSystemEventTrigger("before", "startup", beforeStartup)
- reactor.addSystemEventTrigger("after", "startup", afterStartup)
-
- sawPhase = []
- def fakeSignal(signum, action):
- sawPhase.append(phase[0])
- self.patch(signal, 'signal', fakeSignal)
- reactor.callWhenRunning(reactor.stop)
- self.assertEqual(phase[0], None)
- self.assertEqual(sawPhase, [])
- self.runReactor(reactor)
- self.assertIn("before", sawPhase)
- self.assertEqual(phase[0], "after")
-
-
- def test_stopShutDownEvents(self):
- """
- C{reactor.stop()} fires all three phases of shutdown event triggers
- before it makes C{reactor.run()} return.
- """
- reactor = self.buildReactor()
- events = []
- reactor.addSystemEventTrigger(
- "before", "shutdown",
- lambda: events.append(("before", "shutdown")))
- reactor.addSystemEventTrigger(
- "during", "shutdown",
- lambda: events.append(("during", "shutdown")))
- reactor.addSystemEventTrigger(
- "after", "shutdown",
- lambda: events.append(("after", "shutdown")))
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- self.assertEqual(events, [("before", "shutdown"),
- ("during", "shutdown"),
- ("after", "shutdown")])
-
-
- def test_shutdownFiresTriggersAsynchronously(self):
- """
- C{"before"} C{"shutdown"} triggers are not run synchronously from
- L{reactor.stop}.
- """
- reactor = self.buildReactor()
- events = []
- reactor.addSystemEventTrigger(
- "before", "shutdown", events.append, "before shutdown")
- def stopIt():
- reactor.stop()
- events.append("stopped")
- reactor.callWhenRunning(stopIt)
- self.assertEqual(events, [])
- self.runReactor(reactor)
- self.assertEqual(events, ["stopped", "before shutdown"])
-
-
- def test_shutdownDisconnectsCleanly(self):
- """
- A L{IFileDescriptor.connectionLost} implementation which raises an
- exception does not prevent the remaining L{IFileDescriptor}s from
- having their C{connectionLost} method called.
- """
- lostOK = [False]
-
- # Subclass FileDescriptor to get logPrefix
- class ProblematicFileDescriptor(FileDescriptor):
- def connectionLost(self, reason):
- raise RuntimeError("simulated connectionLost error")
-
- class OKFileDescriptor(FileDescriptor):
- def connectionLost(self, reason):
- lostOK[0] = True
-
- reactor = self.buildReactor()
-
- # Unfortunately, it is necessary to patch removeAll to directly control
- # the order of the returned values. The test is only valid if
- # ProblematicFileDescriptor comes first. Also, return these
- # descriptors only the first time removeAll is called so that if it is
- # called again the file descriptors aren't re-disconnected.
- fds = iter([ProblematicFileDescriptor(), OKFileDescriptor()])
- reactor.removeAll = lambda: fds
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- self.assertTrue(lostOK[0])
-
-
- def test_multipleRun(self):
- """
- C{reactor.run()} raises L{ReactorAlreadyRunning} when called when
- the reactor is already running.
- """
- events = []
- def reentrantRun():
- self.assertRaises(ReactorAlreadyRunning, reactor.run)
- events.append("tested")
- reactor = self.buildReactor()
- reactor.callWhenRunning(reentrantRun)
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- self.assertEqual(events, ["tested"])
-
-
- def test_runWithAsynchronousBeforeStartupTrigger(self):
- """
- When there is a C{'before'} C{'startup'} trigger which returns an
- unfired L{Deferred}, C{reactor.run()} starts the reactor and does not
- return until after C{reactor.stop()} is called
- """
- events = []
- def trigger():
- events.append('trigger')
- d = Deferred()
- d.addCallback(callback)
- reactor.callLater(0, d.callback, None)
- return d
- def callback(ignored):
- events.append('callback')
- reactor.stop()
- reactor = self.buildReactor()
- reactor.addSystemEventTrigger('before', 'startup', trigger)
- self.runReactor(reactor)
- self.assertEqual(events, ['trigger', 'callback'])
-
-
- def test_iterate(self):
- """
- C{reactor.iterate()} does not block.
- """
- reactor = self.buildReactor()
- t = reactor.callLater(5, reactor.crash)
-
- start = time.time()
- reactor.iterate(0) # Shouldn't block
- elapsed = time.time() - start
-
- self.failUnless(elapsed < 2)
- t.cancel()
-
-
- def test_crash(self):
- """
- C{reactor.crash()} stops the reactor and does not fire shutdown
- triggers.
- """
- reactor = self.buildReactor()
- events = []
- reactor.addSystemEventTrigger(
- "before", "shutdown",
- lambda: events.append(("before", "shutdown")))
- reactor.callWhenRunning(reactor.callLater, 0, reactor.crash)
- self.runReactor(reactor)
- self.assertFalse(reactor.running)
- self.assertFalse(
- events,
- "Shutdown triggers invoked but they should not have been.")
-
-
- def test_runAfterCrash(self):
- """
- C{reactor.run()} restarts the reactor after it has been stopped by
- C{reactor.crash()}.
- """
- events = []
- def crash():
- events.append('crash')
- reactor.crash()
- reactor = self.buildReactor()
- reactor.callWhenRunning(crash)
- self.runReactor(reactor)
- def stop():
- events.append(('stop', reactor.running))
- reactor.stop()
- reactor.callWhenRunning(stop)
- self.runReactor(reactor)
- self.assertEqual(events, ['crash', ('stop', True)])
-
-
- def test_runAfterStop(self):
- """
- C{reactor.run()} raises L{ReactorNotRestartable} when called when
- the reactor is being run after getting stopped priorly.
- """
- events = []
- def restart():
- self.assertRaises(ReactorNotRestartable, reactor.run)
- events.append('tested')
- reactor = self.buildReactor()
- reactor.callWhenRunning(reactor.stop)
- reactor.addSystemEventTrigger('after', 'shutdown', restart)
- self.runReactor(reactor)
- self.assertEqual(events, ['tested'])
-
-
-
-globals().update(SystemEventTestsBuilder.makeTestCaseClasses())
-globals().update(ObjectModelIntegrationTest.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_default.py
deleted file mode 100755
index 635c0f9c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_default.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.default}.
-"""
-
-import select
-from twisted.trial.unittest import TestCase
-from twisted.python.runtime import Platform
-from twisted.internet.default import _getInstallFunction
-
-unix = Platform('posix', 'other')
-linux = Platform('posix', 'linux2')
-windows = Platform('nt', 'win32')
-osx = Platform('posix', 'darwin')
-
-
-class PollReactorTests(TestCase):
- """
- Tests for the cases of L{twisted.internet.default._getInstallFunction}
- in which it picks the poll(2) or epoll(7)-based reactors.
- """
-
- def assertIsPoll(self, install):
- """
- Assert the given function will install the poll() reactor, or select()
- if poll() is unavailable.
- """
- if hasattr(select, "poll"):
- self.assertEqual(
- install.__module__, 'twisted.internet.pollreactor')
- else:
- self.assertEqual(
- install.__module__, 'twisted.internet.selectreactor')
-
-
- def test_unix(self):
- """
- L{_getInstallFunction} chooses the poll reactor on arbitrary Unix
- platforms, falling back to select(2) if it is unavailable.
- """
- install = _getInstallFunction(unix)
- self.assertIsPoll(install)
-
-
- def test_linux(self):
- """
- L{_getInstallFunction} chooses the epoll reactor on Linux, or poll if
- epoll is unavailable.
- """
- install = _getInstallFunction(linux)
- try:
- from twisted.internet import epollreactor
- except ImportError:
- self.assertIsPoll(install)
- else:
- self.assertEqual(
- install.__module__, 'twisted.internet.epollreactor')
-
-
-
-class SelectReactorTests(TestCase):
- """
- Tests for the cases of L{twisted.internet.default._getInstallFunction}
- in which it picks the select(2)-based reactor.
- """
- def test_osx(self):
- """
- L{_getInstallFunction} chooses the select reactor on OS X.
- """
- install = _getInstallFunction(osx)
- self.assertEqual(
- install.__module__, 'twisted.internet.selectreactor')
-
-
- def test_windows(self):
- """
- L{_getInstallFunction} chooses the select reactor on Windows.
- """
- install = _getInstallFunction(windows)
- self.assertEqual(
- install.__module__, 'twisted.internet.selectreactor')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_endpoints.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_endpoints.py
deleted file mode 100755
index 0f4fa682..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_endpoints.py
+++ /dev/null
@@ -1,2021 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-"""
-Test the C{I...Endpoint} implementations that wrap the L{IReactorTCP},
-L{IReactorSSL}, and L{IReactorUNIX} interfaces found in
-L{twisted.internet.endpoints}.
-"""
-from errno import EPERM
-from socket import AF_INET, AF_INET6, SOCK_STREAM, IPPROTO_TCP
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.trial import unittest
-from twisted.internet import error, interfaces, defer
-from twisted.internet import endpoints
-from twisted.internet.address import IPv4Address, IPv6Address, UNIXAddress
-from twisted.internet.protocol import ClientFactory, Protocol
-from twisted.test.proto_helpers import (
- MemoryReactor, RaisingMemoryReactor, StringTransport)
-from twisted.python.failure import Failure
-from twisted.python.systemd import ListenFDs
-from twisted.plugin import getPlugins
-
-from twisted import plugins
-from twisted.python.modules import getModule
-from twisted.python.filepath import FilePath
-from twisted.protocols import basic
-from twisted.internet import protocol, reactor, stdio
-from twisted.internet.stdio import PipeAddress
-
-
-pemPath = getModule("twisted.test").filePath.sibling("server.pem")
-casPath = getModule(__name__).filePath.sibling("fake_CAs")
-escapedPEMPathName = endpoints.quoteStringArgument(pemPath.path)
-escapedCAsPathName = endpoints.quoteStringArgument(casPath.path)
-
-try:
- from twisted.test.test_sslverify import makeCertificate
- from twisted.internet.ssl import CertificateOptions, Certificate, \
- KeyPair, PrivateCertificate
- from OpenSSL.SSL import ContextType
- testCertificate = Certificate.loadPEM(pemPath.getContent())
- testPrivateCertificate = PrivateCertificate.loadPEM(pemPath.getContent())
-
- skipSSL = False
-except ImportError:
- skipSSL = "OpenSSL is required to construct SSL Endpoints"
-
-
-class TestProtocol(Protocol):
- """
- Protocol whose only function is to callback deferreds on the
- factory when it is connected or disconnected.
- """
-
- def __init__(self):
- self.data = []
- self.connectionsLost = []
- self.connectionMadeCalls = 0
-
-
- def logPrefix(self):
- return "A Test Protocol"
-
-
- def connectionMade(self):
- self.connectionMadeCalls += 1
-
-
- def dataReceived(self, data):
- self.data.append(data)
-
-
- def connectionLost(self, reason):
- self.connectionsLost.append(reason)
-
-
-
-class TestHalfCloseableProtocol(TestProtocol):
- """
- A Protocol that implements L{IHalfCloseableProtocol} and records whether its
- C{readConnectionLost} and {writeConnectionLost} methods are called.
-
- @ivar readLost: A C{bool} indicating whether C{readConnectionLost} has been
- called.
-
- @ivar writeLost: A C{bool} indicating whether C{writeConnectionLost} has
- been called.
- """
- implements(interfaces.IHalfCloseableProtocol)
-
- def __init__(self):
- TestProtocol.__init__(self)
- self.readLost = False
- self.writeLost = False
-
-
- def readConnectionLost(self):
- self.readLost = True
-
-
- def writeConnectionLost(self):
- self.writeLost = True
-
-
-
-class TestFileDescriptorReceiverProtocol(TestProtocol):
- """
- A Protocol that implements L{IFileDescriptorReceiver} and records how its
- C{fileDescriptorReceived} method is called.
-
- @ivar receivedDescriptors: A C{list} containing all of the file descriptors
- passed to C{fileDescriptorReceived} calls made on this instance.
- """
- implements(interfaces.IFileDescriptorReceiver)
-
- def connectionMade(self):
- TestProtocol.connectionMade(self)
- self.receivedDescriptors = []
-
-
- def fileDescriptorReceived(self, descriptor):
- self.receivedDescriptors.append(descriptor)
-
-
-
-class TestFactory(ClientFactory):
- """
- Simple factory to be used both when connecting and listening. It contains
- two deferreds which are called back when my protocol connects and
- disconnects.
- """
-
- protocol = TestProtocol
-
-
-
-class WrappingFactoryTests(unittest.TestCase):
- """
- Test the behaviour of our ugly implementation detail C{_WrappingFactory}.
- """
- def test_doStart(self):
- """
- L{_WrappingFactory.doStart} passes through to the wrapped factory's
- C{doStart} method, allowing application-specific setup and logging.
- """
- factory = ClientFactory()
- wf = endpoints._WrappingFactory(factory)
- wf.doStart()
- self.assertEqual(1, factory.numPorts)
-
-
- def test_doStop(self):
- """
- L{_WrappingFactory.doStop} passes through to the wrapped factory's
- C{doStop} method, allowing application-specific cleanup and logging.
- """
- factory = ClientFactory()
- factory.numPorts = 3
- wf = endpoints._WrappingFactory(factory)
- wf.doStop()
- self.assertEqual(2, factory.numPorts)
-
-
- def test_failedBuildProtocol(self):
- """
- An exception raised in C{buildProtocol} of our wrappedFactory
- results in our C{onConnection} errback being fired.
- """
-
- class BogusFactory(ClientFactory):
- """
- A one off factory whose C{buildProtocol} raises an C{Exception}.
- """
-
- def buildProtocol(self, addr):
- raise ValueError("My protocol is poorly defined.")
-
-
- wf = endpoints._WrappingFactory(BogusFactory())
-
- wf.buildProtocol(None)
-
- d = self.assertFailure(wf._onConnection, ValueError)
- d.addCallback(lambda e: self.assertEqual(
- e.args,
- ("My protocol is poorly defined.",)))
-
- return d
-
-
- def test_logPrefixPassthrough(self):
- """
- If the wrapped protocol provides L{ILoggingContext}, whatever is
- returned from the wrapped C{logPrefix} method is returned from
- L{_WrappingProtocol.logPrefix}.
- """
- wf = endpoints._WrappingFactory(TestFactory())
- wp = wf.buildProtocol(None)
- self.assertEqual(wp.logPrefix(), "A Test Protocol")
-
-
- def test_logPrefixDefault(self):
- """
- If the wrapped protocol does not provide L{ILoggingContext}, the wrapped
- protocol's class name is returned from L{_WrappingProtocol.logPrefix}.
- """
- class NoProtocol(object):
- pass
- factory = TestFactory()
- factory.protocol = NoProtocol
- wf = endpoints._WrappingFactory(factory)
- wp = wf.buildProtocol(None)
- self.assertEqual(wp.logPrefix(), "NoProtocol")
-
-
- def test_wrappedProtocolDataReceived(self):
- """
- The wrapped C{Protocol}'s C{dataReceived} will get called when our
- C{_WrappingProtocol}'s C{dataReceived} gets called.
- """
- wf = endpoints._WrappingFactory(TestFactory())
- p = wf.buildProtocol(None)
- p.makeConnection(None)
-
- p.dataReceived('foo')
- self.assertEqual(p._wrappedProtocol.data, ['foo'])
-
- p.dataReceived('bar')
- self.assertEqual(p._wrappedProtocol.data, ['foo', 'bar'])
-
-
- def test_wrappedProtocolTransport(self):
- """
- Our transport is properly hooked up to the wrappedProtocol when a
- connection is made.
- """
- wf = endpoints._WrappingFactory(TestFactory())
- p = wf.buildProtocol(None)
-
- dummyTransport = object()
-
- p.makeConnection(dummyTransport)
-
- self.assertEqual(p.transport, dummyTransport)
-
- self.assertEqual(p._wrappedProtocol.transport, dummyTransport)
-
-
- def test_wrappedProtocolConnectionLost(self):
- """
- Our wrappedProtocol's connectionLost method is called when
- L{_WrappingProtocol.connectionLost} is called.
- """
- tf = TestFactory()
- wf = endpoints._WrappingFactory(tf)
- p = wf.buildProtocol(None)
-
- p.connectionLost("fail")
-
- self.assertEqual(p._wrappedProtocol.connectionsLost, ["fail"])
-
-
- def test_clientConnectionFailed(self):
- """
- Calls to L{_WrappingFactory.clientConnectionLost} should errback the
- L{_WrappingFactory._onConnection} L{Deferred}
- """
- wf = endpoints._WrappingFactory(TestFactory())
- expectedFailure = Failure(error.ConnectError(string="fail"))
-
- wf.clientConnectionFailed(
- None,
- expectedFailure)
-
- errors = []
- def gotError(f):
- errors.append(f)
-
- wf._onConnection.addErrback(gotError)
-
- self.assertEqual(errors, [expectedFailure])
-
-
- def test_wrappingProtocolFileDescriptorReceiver(self):
- """
- Our L{_WrappingProtocol} should be an L{IFileDescriptorReceiver} if the
- wrapped protocol is.
- """
- connectedDeferred = None
- applicationProtocol = TestFileDescriptorReceiverProtocol()
- wrapper = endpoints._WrappingProtocol(
- connectedDeferred, applicationProtocol)
- self.assertTrue(interfaces.IFileDescriptorReceiver.providedBy(wrapper))
- self.assertTrue(verifyObject(interfaces.IFileDescriptorReceiver, wrapper))
-
-
- def test_wrappingProtocolNotFileDescriptorReceiver(self):
- """
- Our L{_WrappingProtocol} does not provide L{IHalfCloseableProtocol} if
- the wrapped protocol doesn't.
- """
- tp = TestProtocol()
- p = endpoints._WrappingProtocol(None, tp)
- self.assertFalse(interfaces.IFileDescriptorReceiver.providedBy(p))
-
-
- def test_wrappedProtocolFileDescriptorReceived(self):
- """
- L{_WrappingProtocol.fileDescriptorReceived} calls the wrapped protocol's
- C{fileDescriptorReceived} method.
- """
- wrappedProtocol = TestFileDescriptorReceiverProtocol()
- wrapper = endpoints._WrappingProtocol(
- defer.Deferred(), wrappedProtocol)
- wrapper.makeConnection(StringTransport())
- wrapper.fileDescriptorReceived(42)
- self.assertEqual(wrappedProtocol.receivedDescriptors, [42])
-
-
- def test_wrappingProtocolHalfCloseable(self):
- """
- Our L{_WrappingProtocol} should be an L{IHalfCloseableProtocol} if the
- C{wrappedProtocol} is.
- """
- cd = object()
- hcp = TestHalfCloseableProtocol()
- p = endpoints._WrappingProtocol(cd, hcp)
- self.assertEqual(
- interfaces.IHalfCloseableProtocol.providedBy(p), True)
-
-
- def test_wrappingProtocolNotHalfCloseable(self):
- """
- Our L{_WrappingProtocol} should not provide L{IHalfCloseableProtocol}
- if the C{WrappedProtocol} doesn't.
- """
- tp = TestProtocol()
- p = endpoints._WrappingProtocol(None, tp)
- self.assertEqual(
- interfaces.IHalfCloseableProtocol.providedBy(p), False)
-
-
- def test_wrappedProtocolReadConnectionLost(self):
- """
- L{_WrappingProtocol.readConnectionLost} should proxy to the wrapped
- protocol's C{readConnectionLost}
- """
- hcp = TestHalfCloseableProtocol()
- p = endpoints._WrappingProtocol(None, hcp)
- p.readConnectionLost()
- self.assertEqual(hcp.readLost, True)
-
-
- def test_wrappedProtocolWriteConnectionLost(self):
- """
- L{_WrappingProtocol.writeConnectionLost} should proxy to the wrapped
- protocol's C{writeConnectionLost}
- """
- hcp = TestHalfCloseableProtocol()
- p = endpoints._WrappingProtocol(None, hcp)
- p.writeConnectionLost()
- self.assertEqual(hcp.writeLost, True)
-
-
-
-class ClientEndpointTestCaseMixin(object):
- """
- Generic test methods to be mixed into all client endpoint test classes.
- """
- def retrieveConnectedFactory(self, reactor):
- """
- Retrieve a single factory that has connected using the given reactor.
- (This behavior is valid for TCP and SSL but needs to be overridden for
- UNIX.)
-
- @param reactor: a L{MemoryReactor}
- """
- return self.expectedClients(reactor)[0][2]
-
-
- def test_endpointConnectSuccess(self):
- """
- A client endpoint can connect and returns a deferred who gets called
- back with a protocol instance.
- """
- proto = object()
- mreactor = MemoryReactor()
-
- clientFactory = object()
-
- ep, expectedArgs, ignoredDest = self.createClientEndpoint(
- mreactor, clientFactory)
-
- d = ep.connect(clientFactory)
-
- receivedProtos = []
-
- def checkProto(p):
- receivedProtos.append(p)
-
- d.addCallback(checkProto)
-
- factory = self.retrieveConnectedFactory(mreactor)
- factory._onConnection.callback(proto)
- self.assertEqual(receivedProtos, [proto])
-
- expectedClients = self.expectedClients(mreactor)
-
- self.assertEqual(len(expectedClients), 1)
- self.assertConnectArgs(expectedClients[0], expectedArgs)
-
-
- def test_endpointConnectFailure(self):
- """
- If an endpoint tries to connect to a non-listening port it gets
- a C{ConnectError} failure.
- """
- expectedError = error.ConnectError(string="Connection Failed")
-
- mreactor = RaisingMemoryReactor(connectException=expectedError)
-
- clientFactory = object()
-
- ep, ignoredArgs, ignoredDest = self.createClientEndpoint(
- mreactor, clientFactory)
-
- d = ep.connect(clientFactory)
-
- receivedExceptions = []
-
- def checkFailure(f):
- receivedExceptions.append(f.value)
-
- d.addErrback(checkFailure)
-
- self.assertEqual(receivedExceptions, [expectedError])
-
-
- def test_endpointConnectingCancelled(self):
- """
- Calling L{Deferred.cancel} on the L{Deferred} returned from
- L{IStreamClientEndpoint.connect} is errbacked with an expected
- L{ConnectingCancelledError} exception.
- """
- mreactor = MemoryReactor()
-
- clientFactory = object()
-
- ep, ignoredArgs, address = self.createClientEndpoint(
- mreactor, clientFactory)
-
- d = ep.connect(clientFactory)
-
- receivedFailures = []
-
- def checkFailure(f):
- receivedFailures.append(f)
-
- d.addErrback(checkFailure)
-
- d.cancel()
- # When canceled, the connector will immediately notify its factory that
- # the connection attempt has failed due to a UserError.
- attemptFactory = self.retrieveConnectedFactory(mreactor)
- attemptFactory.clientConnectionFailed(None, Failure(error.UserError()))
- # This should be a feature of MemoryReactor: <http://tm.tl/5630>.
-
- self.assertEqual(len(receivedFailures), 1)
-
- failure = receivedFailures[0]
-
- self.assertIsInstance(failure.value, error.ConnectingCancelledError)
- self.assertEqual(failure.value.address, address)
-
-
- def test_endpointConnectNonDefaultArgs(self):
- """
- The endpoint should pass it's connectArgs parameter to the reactor's
- listen methods.
- """
- factory = object()
-
- mreactor = MemoryReactor()
-
- ep, expectedArgs, ignoredHost = self.createClientEndpoint(
- mreactor, factory,
- **self.connectArgs())
-
- ep.connect(factory)
-
- expectedClients = self.expectedClients(mreactor)
-
- self.assertEqual(len(expectedClients), 1)
- self.assertConnectArgs(expectedClients[0], expectedArgs)
-
-
-
-class ServerEndpointTestCaseMixin(object):
- """
- Generic test methods to be mixed into all client endpoint test classes.
- """
- def test_endpointListenSuccess(self):
- """
- An endpoint can listen and returns a deferred that gets called back
- with a port instance.
- """
- mreactor = MemoryReactor()
-
- factory = object()
-
- ep, expectedArgs, expectedHost = self.createServerEndpoint(
- mreactor, factory)
-
- d = ep.listen(factory)
-
- receivedHosts = []
-
- def checkPortAndServer(port):
- receivedHosts.append(port.getHost())
-
- d.addCallback(checkPortAndServer)
-
- self.assertEqual(receivedHosts, [expectedHost])
- self.assertEqual(self.expectedServers(mreactor), [expectedArgs])
-
-
- def test_endpointListenFailure(self):
- """
- When an endpoint tries to listen on an already listening port, a
- C{CannotListenError} failure is errbacked.
- """
- factory = object()
- exception = error.CannotListenError('', 80, factory)
- mreactor = RaisingMemoryReactor(listenException=exception)
-
- ep, ignoredArgs, ignoredDest = self.createServerEndpoint(
- mreactor, factory)
-
- d = ep.listen(object())
-
- receivedExceptions = []
-
- def checkFailure(f):
- receivedExceptions.append(f.value)
-
- d.addErrback(checkFailure)
-
- self.assertEqual(receivedExceptions, [exception])
-
-
- def test_endpointListenNonDefaultArgs(self):
- """
- The endpoint should pass it's listenArgs parameter to the reactor's
- listen methods.
- """
- factory = object()
-
- mreactor = MemoryReactor()
-
- ep, expectedArgs, ignoredHost = self.createServerEndpoint(
- mreactor, factory,
- **self.listenArgs())
-
- ep.listen(factory)
-
- expectedServers = self.expectedServers(mreactor)
-
- self.assertEqual(expectedServers, [expectedArgs])
-
-
-
-class EndpointTestCaseMixin(ServerEndpointTestCaseMixin,
- ClientEndpointTestCaseMixin):
- """
- Generic test methods to be mixed into all endpoint test classes.
- """
-
-
-
-class StdioFactory(protocol.Factory):
- protocol = basic.LineReceiver
-
-
-
-class StandardIOEndpointsTestCase(unittest.TestCase):
- """
- Tests for Standard I/O Endpoints
- """
- def setUp(self):
- self.ep = endpoints.StandardIOEndpoint(reactor)
-
-
- def test_standardIOInstance(self):
- """
- The endpoint creates an L{endpoints.StandardIO} instance.
- """
- self.d = self.ep.listen(StdioFactory())
- def checkInstanceAndLoseConnection(stdioOb):
- self.assertIsInstance(stdioOb, stdio.StandardIO)
- stdioOb.loseConnection()
- self.d.addCallback(checkInstanceAndLoseConnection)
- return self.d
-
-
- def test_reactor(self):
- """
- The reactor passed to the endpoint is set as its _reactor attribute.
- """
- self.assertEqual(self.ep._reactor, reactor)
-
-
- def test_protocol(self):
- """
- The protocol used in the endpoint is a L{basic.LineReceiver} instance.
- """
- self.d = self.ep.listen(StdioFactory())
- def checkProtocol(stdioOb):
- from twisted.python.runtime import platform
- if platform.isWindows():
- self.assertIsInstance(stdioOb.proto, basic.LineReceiver)
- else:
- self.assertIsInstance(stdioOb.protocol, basic.LineReceiver)
- stdioOb.loseConnection()
- self.d.addCallback(checkProtocol)
- return self.d
-
-
- def test_address(self):
- """
- The address passed to the factory's buildProtocol in the endpoint
- should be a PipeAddress instance.
- """
- class TestAddrFactory(protocol.Factory):
- protocol = basic.LineReceiver
- _address = None
- def buildProtocol(self, addr):
- self._address = addr
- p = self.protocol()
- p.factory = self
- return p
- def getAddress(self):
- return self._address
-
- myFactory = TestAddrFactory()
- self.d = self.ep.listen(myFactory)
- def checkAddress(stdioOb):
- self.assertIsInstance(myFactory.getAddress(), PipeAddress)
- stdioOb.loseConnection()
- self.d.addCallback(checkAddress)
- return self.d
-
-
-
-class TCP4EndpointsTestCase(EndpointTestCaseMixin, unittest.TestCase):
- """
- Tests for TCP IPv4 Endpoints.
- """
-
- def expectedServers(self, reactor):
- """
- @return: List of calls to L{IReactorTCP.listenTCP}
- """
- return reactor.tcpServers
-
-
- def expectedClients(self, reactor):
- """
- @return: List of calls to L{IReactorTCP.connectTCP}
- """
- return reactor.tcpClients
-
-
- def assertConnectArgs(self, receivedArgs, expectedArgs):
- """
- Compare host, port, timeout, and bindAddress in C{receivedArgs}
- to C{expectedArgs}. We ignore the factory because we don't
- only care what protocol comes out of the
- C{IStreamClientEndpoint.connect} call.
-
- @param receivedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{timeout}, C{bindAddress}) that was passed to
- L{IReactorTCP.connectTCP}.
- @param expectedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{timeout}, C{bindAddress}) that we expect to have been passed
- to L{IReactorTCP.connectTCP}.
- """
- (host, port, ignoredFactory, timeout, bindAddress) = receivedArgs
- (expectedHost, expectedPort, _ignoredFactory,
- expectedTimeout, expectedBindAddress) = expectedArgs
-
- self.assertEqual(host, expectedHost)
- self.assertEqual(port, expectedPort)
- self.assertEqual(timeout, expectedTimeout)
- self.assertEqual(bindAddress, expectedBindAddress)
-
-
- def connectArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to connect.
- """
- return {'timeout': 10, 'bindAddress': ('localhost', 49595)}
-
-
- def listenArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to listen
- """
- return {'backlog': 100, 'interface': '127.0.0.1'}
-
-
- def createServerEndpoint(self, reactor, factory, **listenArgs):
- """
- Create an L{TCP4ServerEndpoint} and return the values needed to verify
- its behaviour.
-
- @param reactor: A fake L{IReactorTCP} that L{TCP4ServerEndpoint} can
- call L{IReactorTCP.listenTCP} on.
- @param factory: The thing that we expect to be passed to our
- L{IStreamServerEndpoint.listen} implementation.
- @param listenArgs: Optional dictionary of arguments to
- L{IReactorTCP.listenTCP}.
- """
- address = IPv4Address("TCP", "0.0.0.0", 0)
-
- if listenArgs is None:
- listenArgs = {}
-
- return (endpoints.TCP4ServerEndpoint(reactor,
- address.port,
- **listenArgs),
- (address.port, factory,
- listenArgs.get('backlog', 50),
- listenArgs.get('interface', '')),
- address)
-
-
- def createClientEndpoint(self, reactor, clientFactory, **connectArgs):
- """
- Create an L{TCP4ClientEndpoint} and return the values needed to verify
- its behavior.
-
- @param reactor: A fake L{IReactorTCP} that L{TCP4ClientEndpoint} can
- call L{IReactorTCP.connectTCP} on.
- @param clientFactory: The thing that we expect to be passed to our
- L{IStreamClientEndpoint.connect} implementation.
- @param connectArgs: Optional dictionary of arguments to
- L{IReactorTCP.connectTCP}
- """
- address = IPv4Address("TCP", "localhost", 80)
-
- return (endpoints.TCP4ClientEndpoint(reactor,
- address.host,
- address.port,
- **connectArgs),
- (address.host, address.port, clientFactory,
- connectArgs.get('timeout', 30),
- connectArgs.get('bindAddress', None)),
- address)
-
-
-
-class TCP6EndpointsTestCase(EndpointTestCaseMixin, unittest.TestCase):
- """
- Tests for TCP IPv6 Endpoints.
- """
-
- def expectedServers(self, reactor):
- """
- @return: List of calls to L{IReactorTCP.listenTCP}
- """
- return reactor.tcpServers
-
-
- def expectedClients(self, reactor):
- """
- @return: List of calls to L{IReactorTCP.connectTCP}
- """
- return reactor.tcpClients
-
-
- def assertConnectArgs(self, receivedArgs, expectedArgs):
- """
- Compare host, port, timeout, and bindAddress in C{receivedArgs}
- to C{expectedArgs}. We ignore the factory because we don't
- only care what protocol comes out of the
- C{IStreamClientEndpoint.connect} call.
-
- @param receivedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{timeout}, C{bindAddress}) that was passed to
- L{IReactorTCP.connectTCP}.
- @param expectedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{timeout}, C{bindAddress}) that we expect to have been passed
- to L{IReactorTCP.connectTCP}.
- """
- (host, port, ignoredFactory, timeout, bindAddress) = receivedArgs
- (expectedHost, expectedPort, _ignoredFactory,
- expectedTimeout, expectedBindAddress) = expectedArgs
-
- self.assertEqual(host, expectedHost)
- self.assertEqual(port, expectedPort)
- self.assertEqual(timeout, expectedTimeout)
- self.assertEqual(bindAddress, expectedBindAddress)
-
-
- def connectArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to connect.
- """
- return {'timeout': 10, 'bindAddress': ('localhost', 49595)}
-
-
- def listenArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to listen
- """
- return {'backlog': 100, 'interface': '::1'}
-
-
- def createServerEndpoint(self, reactor, factory, **listenArgs):
- """
- Create a L{TCP6ServerEndpoint} and return the values needed to verify
- its behaviour.
-
- @param reactor: A fake L{IReactorTCP} that L{TCP6ServerEndpoint} can
- call L{IReactorTCP.listenTCP} on.
- @param factory: The thing that we expect to be passed to our
- L{IStreamServerEndpoint.listen} implementation.
- @param listenArgs: Optional dictionary of arguments to
- L{IReactorTCP.listenTCP}.
- """
- interface = listenArgs.get('interface', '::')
- address = IPv6Address("TCP", interface, 0)
-
- if listenArgs is None:
- listenArgs = {}
-
- return (endpoints.TCP6ServerEndpoint(reactor,
- address.port,
- **listenArgs),
- (address.port, factory,
- listenArgs.get('backlog', 50),
- interface),
- address)
-
-
- def createClientEndpoint(self, reactor, clientFactory, **connectArgs):
- """
- Create a L{TCP6ClientEndpoint} and return the values needed to verify
- its behavior.
-
- @param reactor: A fake L{IReactorTCP} that L{TCP6ClientEndpoint} can
- call L{IReactorTCP.connectTCP} on.
- @param clientFactory: The thing that we expect to be passed to our
- L{IStreamClientEndpoint.connect} implementation.
- @param connectArgs: Optional dictionary of arguments to
- L{IReactorTCP.connectTCP}
- """
- address = IPv6Address("TCP", "::1", 80)
-
- return (endpoints.TCP6ClientEndpoint(reactor,
- address.host,
- address.port,
- **connectArgs),
- (address.host, address.port, clientFactory,
- connectArgs.get('timeout', 30),
- connectArgs.get('bindAddress', None)),
- address)
-
-
-class TCP6EndpointNameResolutionTestCase(ClientEndpointTestCaseMixin,
- unittest.TestCase):
- """
- Tests for a TCP IPv6 Client Endpoint pointed at a hostname instead
- of an IPv6 address literal.
- """
-
-
- def createClientEndpoint(self, reactor, clientFactory, **connectArgs):
- """
- Create a L{TCP6ClientEndpoint} and return the values needed to verify
- its behavior.
-
- @param reactor: A fake L{IReactorTCP} that L{TCP6ClientEndpoint} can
- call L{IReactorTCP.connectTCP} on.
- @param clientFactory: The thing that we expect to be passed to our
- L{IStreamClientEndpoint.connect} implementation.
- @param connectArgs: Optional dictionary of arguments to
- L{IReactorTCP.connectTCP}
- """
- address = IPv6Address("TCP", "::2", 80)
- self.ep = endpoints.TCP6ClientEndpoint(reactor,
- 'ipv6.example.com',
- address.port,
- **connectArgs)
-
- def testNameResolution(host):
- self.assertEqual("ipv6.example.com", host)
- data = [(AF_INET6, SOCK_STREAM, IPPROTO_TCP, '', ('::2', 0, 0, 0)),
- (AF_INET6, SOCK_STREAM, IPPROTO_TCP, '', ('::3', 0, 0, 0)),
- (AF_INET6, SOCK_STREAM, IPPROTO_TCP, '', ('::4', 0, 0, 0))]
- return defer.succeed(data)
-
- self.ep._nameResolution = testNameResolution
-
- return (self.ep,
- (address.host, address.port, clientFactory,
- connectArgs.get('timeout', 30),
- connectArgs.get('bindAddress', None)),
- address)
-
-
- def connectArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to connect.
- """
- return {'timeout': 10, 'bindAddress': ('localhost', 49595)}
-
-
- def expectedClients(self, reactor):
- """
- @return: List of calls to L{IReactorTCP.connectTCP}
- """
- return reactor.tcpClients
-
-
- def assertConnectArgs(self, receivedArgs, expectedArgs):
- """
- Compare host, port, timeout, and bindAddress in C{receivedArgs}
- to C{expectedArgs}. We ignore the factory because we don't
- only care what protocol comes out of the
- C{IStreamClientEndpoint.connect} call.
-
- @param receivedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{timeout}, C{bindAddress}) that was passed to
- L{IReactorTCP.connectTCP}.
- @param expectedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{timeout}, C{bindAddress}) that we expect to have been passed
- to L{IReactorTCP.connectTCP}.
- """
- (host, port, ignoredFactory, timeout, bindAddress) = receivedArgs
- (expectedHost, expectedPort, _ignoredFactory,
- expectedTimeout, expectedBindAddress) = expectedArgs
-
- self.assertEqual(host, expectedHost)
- self.assertEqual(port, expectedPort)
- self.assertEqual(timeout, expectedTimeout)
- self.assertEqual(bindAddress, expectedBindAddress)
-
-
- def test_nameResolution(self):
- """
- While resolving host names, _nameResolution calls
- _deferToThread with _getaddrinfo.
- """
- calls = []
-
- def fakeDeferToThread(f, *args, **kwargs):
- calls.append((f, args, kwargs))
- return defer.Deferred()
-
- endpoint = endpoints.TCP6ClientEndpoint(reactor, 'ipv6.example.com',
- 1234)
- fakegetaddrinfo = object()
- endpoint._getaddrinfo = fakegetaddrinfo
- endpoint._deferToThread = fakeDeferToThread
- endpoint.connect(TestFactory())
- self.assertEqual(
- [(fakegetaddrinfo, ("ipv6.example.com", 0, AF_INET6), {})], calls)
-
-
-
-class SSL4EndpointsTestCase(EndpointTestCaseMixin,
- unittest.TestCase):
- """
- Tests for SSL Endpoints.
- """
- if skipSSL:
- skip = skipSSL
-
- def expectedServers(self, reactor):
- """
- @return: List of calls to L{IReactorSSL.listenSSL}
- """
- return reactor.sslServers
-
-
- def expectedClients(self, reactor):
- """
- @return: List of calls to L{IReactorSSL.connectSSL}
- """
- return reactor.sslClients
-
-
- def assertConnectArgs(self, receivedArgs, expectedArgs):
- """
- Compare host, port, contextFactory, timeout, and bindAddress in
- C{receivedArgs} to C{expectedArgs}. We ignore the factory because we
- don't only care what protocol comes out of the
- C{IStreamClientEndpoint.connect} call.
-
- @param receivedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{contextFactory}, C{timeout}, C{bindAddress}) that was passed to
- L{IReactorSSL.connectSSL}.
- @param expectedArgs: C{tuple} of (C{host}, C{port}, C{factory},
- C{contextFactory}, C{timeout}, C{bindAddress}) that we expect to
- have been passed to L{IReactorSSL.connectSSL}.
- """
- (host, port, ignoredFactory, contextFactory, timeout,
- bindAddress) = receivedArgs
-
- (expectedHost, expectedPort, _ignoredFactory, expectedContextFactory,
- expectedTimeout, expectedBindAddress) = expectedArgs
-
- self.assertEqual(host, expectedHost)
- self.assertEqual(port, expectedPort)
- self.assertEqual(contextFactory, expectedContextFactory)
- self.assertEqual(timeout, expectedTimeout)
- self.assertEqual(bindAddress, expectedBindAddress)
-
-
- def connectArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to connect.
- """
- return {'timeout': 10, 'bindAddress': ('localhost', 49595)}
-
-
- def listenArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to listen
- """
- return {'backlog': 100, 'interface': '127.0.0.1'}
-
-
- def setUp(self):
- """
- Set up client and server SSL contexts for use later.
- """
- self.sKey, self.sCert = makeCertificate(
- O="Server Test Certificate",
- CN="server")
- self.cKey, self.cCert = makeCertificate(
- O="Client Test Certificate",
- CN="client")
- self.serverSSLContext = CertificateOptions(
- privateKey=self.sKey,
- certificate=self.sCert,
- requireCertificate=False)
- self.clientSSLContext = CertificateOptions(
- requireCertificate=False)
-
-
- def createServerEndpoint(self, reactor, factory, **listenArgs):
- """
- Create an L{SSL4ServerEndpoint} and return the tools to verify its
- behaviour.
-
- @param factory: The thing that we expect to be passed to our
- L{IStreamServerEndpoint.listen} implementation.
- @param reactor: A fake L{IReactorSSL} that L{SSL4ServerEndpoint} can
- call L{IReactorSSL.listenSSL} on.
- @param listenArgs: Optional dictionary of arguments to
- L{IReactorSSL.listenSSL}.
- """
- address = IPv4Address("TCP", "0.0.0.0", 0)
-
- return (endpoints.SSL4ServerEndpoint(reactor,
- address.port,
- self.serverSSLContext,
- **listenArgs),
- (address.port, factory, self.serverSSLContext,
- listenArgs.get('backlog', 50),
- listenArgs.get('interface', '')),
- address)
-
-
- def createClientEndpoint(self, reactor, clientFactory, **connectArgs):
- """
- Create an L{SSL4ClientEndpoint} and return the values needed to verify
- its behaviour.
-
- @param reactor: A fake L{IReactorSSL} that L{SSL4ClientEndpoint} can
- call L{IReactorSSL.connectSSL} on.
- @param clientFactory: The thing that we expect to be passed to our
- L{IStreamClientEndpoint.connect} implementation.
- @param connectArgs: Optional dictionary of arguments to
- L{IReactorSSL.connectSSL}
- """
- address = IPv4Address("TCP", "localhost", 80)
-
- if connectArgs is None:
- connectArgs = {}
-
- return (endpoints.SSL4ClientEndpoint(reactor,
- address.host,
- address.port,
- self.clientSSLContext,
- **connectArgs),
- (address.host, address.port, clientFactory,
- self.clientSSLContext,
- connectArgs.get('timeout', 30),
- connectArgs.get('bindAddress', None)),
- address)
-
-
-
-class UNIXEndpointsTestCase(EndpointTestCaseMixin,
- unittest.TestCase):
- """
- Tests for UnixSocket Endpoints.
- """
-
- def retrieveConnectedFactory(self, reactor):
- """
- Override L{EndpointTestCaseMixin.retrieveConnectedFactory} to account
- for different index of 'factory' in C{connectUNIX} args.
- """
- return self.expectedClients(reactor)[0][1]
-
- def expectedServers(self, reactor):
- """
- @return: List of calls to L{IReactorUNIX.listenUNIX}
- """
- return reactor.unixServers
-
-
- def expectedClients(self, reactor):
- """
- @return: List of calls to L{IReactorUNIX.connectUNIX}
- """
- return reactor.unixClients
-
-
- def assertConnectArgs(self, receivedArgs, expectedArgs):
- """
- Compare path, timeout, checkPID in C{receivedArgs} to C{expectedArgs}.
- We ignore the factory because we don't only care what protocol comes
- out of the C{IStreamClientEndpoint.connect} call.
-
- @param receivedArgs: C{tuple} of (C{path}, C{timeout}, C{checkPID})
- that was passed to L{IReactorUNIX.connectUNIX}.
- @param expectedArgs: C{tuple} of (C{path}, C{timeout}, C{checkPID})
- that we expect to have been passed to L{IReactorUNIX.connectUNIX}.
- """
-
- (path, ignoredFactory, timeout, checkPID) = receivedArgs
-
- (expectedPath, _ignoredFactory, expectedTimeout,
- expectedCheckPID) = expectedArgs
-
- self.assertEqual(path, expectedPath)
- self.assertEqual(timeout, expectedTimeout)
- self.assertEqual(checkPID, expectedCheckPID)
-
-
- def connectArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to connect.
- """
- return {'timeout': 10, 'checkPID': 1}
-
-
- def listenArgs(self):
- """
- @return: C{dict} of keyword arguments to pass to listen
- """
- return {'backlog': 100, 'mode': 0600, 'wantPID': 1}
-
-
- def createServerEndpoint(self, reactor, factory, **listenArgs):
- """
- Create an L{UNIXServerEndpoint} and return the tools to verify its
- behaviour.
-
- @param reactor: A fake L{IReactorUNIX} that L{UNIXServerEndpoint} can
- call L{IReactorUNIX.listenUNIX} on.
- @param factory: The thing that we expect to be passed to our
- L{IStreamServerEndpoint.listen} implementation.
- @param listenArgs: Optional dictionary of arguments to
- L{IReactorUNIX.listenUNIX}.
- """
- address = UNIXAddress(self.mktemp())
-
- return (endpoints.UNIXServerEndpoint(reactor, address.name,
- **listenArgs),
- (address.name, factory,
- listenArgs.get('backlog', 50),
- listenArgs.get('mode', 0666),
- listenArgs.get('wantPID', 0)),
- address)
-
-
- def createClientEndpoint(self, reactor, clientFactory, **connectArgs):
- """
- Create an L{UNIXClientEndpoint} and return the values needed to verify
- its behaviour.
-
- @param reactor: A fake L{IReactorUNIX} that L{UNIXClientEndpoint} can
- call L{IReactorUNIX.connectUNIX} on.
- @param clientFactory: The thing that we expect to be passed to our
- L{IStreamClientEndpoint.connect} implementation.
- @param connectArgs: Optional dictionary of arguments to
- L{IReactorUNIX.connectUNIX}
- """
- address = UNIXAddress(self.mktemp())
-
- return (endpoints.UNIXClientEndpoint(reactor, address.name,
- **connectArgs),
- (address.name, clientFactory,
- connectArgs.get('timeout', 30),
- connectArgs.get('checkPID', 0)),
- address)
-
-
-
-class ParserTestCase(unittest.TestCase):
- """
- Tests for L{endpoints._parseServer}, the low-level parsing logic.
- """
-
- f = "Factory"
-
- def parse(self, *a, **kw):
- """
- Provide a hook for test_strports to substitute the deprecated API.
- """
- return endpoints._parseServer(*a, **kw)
-
-
- def test_simpleTCP(self):
- """
- Simple strings with a 'tcp:' prefix should be parsed as TCP.
- """
- self.assertEqual(self.parse('tcp:80', self.f),
- ('TCP', (80, self.f), {'interface':'', 'backlog':50}))
-
-
- def test_interfaceTCP(self):
- """
- TCP port descriptions parse their 'interface' argument as a string.
- """
- self.assertEqual(
- self.parse('tcp:80:interface=127.0.0.1', self.f),
- ('TCP', (80, self.f), {'interface':'127.0.0.1', 'backlog':50}))
-
-
- def test_backlogTCP(self):
- """
- TCP port descriptions parse their 'backlog' argument as an integer.
- """
- self.assertEqual(self.parse('tcp:80:backlog=6', self.f),
- ('TCP', (80, self.f),
- {'interface':'', 'backlog':6}))
-
-
- def test_simpleUNIX(self):
- """
- L{endpoints._parseServer} returns a C{'UNIX'} port description with
- defaults for C{'mode'}, C{'backlog'}, and C{'wantPID'} when passed a
- string with the C{'unix:'} prefix and no other parameter values.
- """
- self.assertEqual(
- self.parse('unix:/var/run/finger', self.f),
- ('UNIX', ('/var/run/finger', self.f),
- {'mode': 0666, 'backlog': 50, 'wantPID': True}))
-
-
- def test_modeUNIX(self):
- """
- C{mode} can be set by including C{"mode=<some integer>"}.
- """
- self.assertEqual(
- self.parse('unix:/var/run/finger:mode=0660', self.f),
- ('UNIX', ('/var/run/finger', self.f),
- {'mode': 0660, 'backlog': 50, 'wantPID': True}))
-
-
- def test_wantPIDUNIX(self):
- """
- C{wantPID} can be set to false by included C{"lockfile=0"}.
- """
- self.assertEqual(
- self.parse('unix:/var/run/finger:lockfile=0', self.f),
- ('UNIX', ('/var/run/finger', self.f),
- {'mode': 0666, 'backlog': 50, 'wantPID': False}))
-
-
- def test_escape(self):
- """
- Backslash can be used to escape colons and backslashes in port
- descriptions.
- """
- self.assertEqual(
- self.parse(r'unix:foo\:bar\=baz\:qux\\', self.f),
- ('UNIX', ('foo:bar=baz:qux\\', self.f),
- {'mode': 0666, 'backlog': 50, 'wantPID': True}))
-
-
- def test_quoteStringArgument(self):
- """
- L{endpoints.quoteStringArgument} should quote backslashes and colons
- for interpolation into L{endpoints.serverFromString} and
- L{endpoints.clientFactory} arguments.
- """
- self.assertEqual(endpoints.quoteStringArgument("some : stuff \\"),
- "some \\: stuff \\\\")
-
-
- def test_impliedEscape(self):
- """
- In strports descriptions, '=' in a parameter value does not need to be
- quoted; it will simply be parsed as part of the value.
- """
- self.assertEqual(
- self.parse(r'unix:address=foo=bar', self.f),
- ('UNIX', ('foo=bar', self.f),
- {'mode': 0666, 'backlog': 50, 'wantPID': True}))
-
-
- def test_nonstandardDefault(self):
- """
- For compatibility with the old L{twisted.application.strports.parse},
- the third 'mode' argument may be specified to L{endpoints.parse} to
- indicate a default other than TCP.
- """
- self.assertEqual(
- self.parse('filename', self.f, 'unix'),
- ('UNIX', ('filename', self.f),
- {'mode': 0666, 'backlog': 50, 'wantPID': True}))
-
-
- def test_unknownType(self):
- """
- L{strports.parse} raises C{ValueError} when given an unknown endpoint
- type.
- """
- self.assertRaises(ValueError, self.parse, "bogus-type:nothing", self.f)
-
-
-
-class ServerStringTests(unittest.TestCase):
- """
- Tests for L{twisted.internet.endpoints.serverFromString}.
- """
-
- def test_tcp(self):
- """
- When passed a TCP strports description, L{endpoints.serverFromString}
- returns a L{TCP4ServerEndpoint} instance initialized with the values
- from the string.
- """
- reactor = object()
- server = endpoints.serverFromString(
- reactor, "tcp:1234:backlog=12:interface=10.0.0.1")
- self.assertIsInstance(server, endpoints.TCP4ServerEndpoint)
- self.assertIdentical(server._reactor, reactor)
- self.assertEqual(server._port, 1234)
- self.assertEqual(server._backlog, 12)
- self.assertEqual(server._interface, "10.0.0.1")
-
-
- def test_ssl(self):
- """
- When passed an SSL strports description, L{endpoints.serverFromString}
- returns a L{SSL4ServerEndpoint} instance initialized with the values
- from the string.
- """
- reactor = object()
- server = endpoints.serverFromString(
- reactor,
- "ssl:1234:backlog=12:privateKey=%s:"
- "certKey=%s:interface=10.0.0.1" % (escapedPEMPathName,
- escapedPEMPathName))
- self.assertIsInstance(server, endpoints.SSL4ServerEndpoint)
- self.assertIdentical(server._reactor, reactor)
- self.assertEqual(server._port, 1234)
- self.assertEqual(server._backlog, 12)
- self.assertEqual(server._interface, "10.0.0.1")
- ctx = server._sslContextFactory.getContext()
- self.assertIsInstance(ctx, ContextType)
-
- if skipSSL:
- test_ssl.skip = skipSSL
-
-
- def test_unix(self):
- """
- When passed a UNIX strports description, L{endpoint.serverFromString}
- returns a L{UNIXServerEndpoint} instance initialized with the values
- from the string.
- """
- reactor = object()
- endpoint = endpoints.serverFromString(
- reactor,
- "unix:/var/foo/bar:backlog=7:mode=0123:lockfile=1")
- self.assertIsInstance(endpoint, endpoints.UNIXServerEndpoint)
- self.assertIdentical(endpoint._reactor, reactor)
- self.assertEqual(endpoint._address, "/var/foo/bar")
- self.assertEqual(endpoint._backlog, 7)
- self.assertEqual(endpoint._mode, 0123)
- self.assertEqual(endpoint._wantPID, True)
-
-
- def test_implicitDefaultNotAllowed(self):
- """
- The older service-based API (L{twisted.internet.strports.service})
- allowed an implicit default of 'tcp' so that TCP ports could be
- specified as a simple integer, but we've since decided that's a bad
- idea, and the new API does not accept an implicit default argument; you
- have to say 'tcp:' now. If you try passing an old implicit port number
- to the new API, you'll get a C{ValueError}.
- """
- value = self.assertRaises(
- ValueError, endpoints.serverFromString, None, "4321")
- self.assertEqual(
- str(value),
- "Unqualified strport description passed to 'service'."
- "Use qualified endpoint descriptions; for example, 'tcp:4321'.")
-
-
- def test_unknownType(self):
- """
- L{endpoints.serverFromString} raises C{ValueError} when given an
- unknown endpoint type.
- """
- value = self.assertRaises(
- # faster-than-light communication not supported
- ValueError, endpoints.serverFromString, None,
- "ftl:andromeda/carcosa/hali/2387")
- self.assertEqual(
- str(value),
- "Unknown endpoint type: 'ftl'")
-
-
- def test_typeFromPlugin(self):
- """
- L{endpoints.serverFromString} looks up plugins of type
- L{IStreamServerEndpoint} and constructs endpoints from them.
- """
- # Set up a plugin which will only be accessible for the duration of
- # this test.
- addFakePlugin(self)
- # Plugin is set up: now actually test.
- notAReactor = object()
- fakeEndpoint = endpoints.serverFromString(
- notAReactor, "fake:hello:world:yes=no:up=down")
- from twisted.plugins.fakeendpoint import fake
- self.assertIdentical(fakeEndpoint.parser, fake)
- self.assertEqual(fakeEndpoint.args, (notAReactor, 'hello', 'world'))
- self.assertEqual(fakeEndpoint.kwargs, dict(yes='no', up='down'))
-
-
-
-def addFakePlugin(testCase, dropinSource="fakeendpoint.py"):
- """
- For the duration of C{testCase}, add a fake plugin to twisted.plugins which
- contains some sample endpoint parsers.
- """
- import sys
- savedModules = sys.modules.copy()
- savedPluginPath = plugins.__path__
- def cleanup():
- sys.modules.clear()
- sys.modules.update(savedModules)
- plugins.__path__[:] = savedPluginPath
- testCase.addCleanup(cleanup)
- fp = FilePath(testCase.mktemp())
- fp.createDirectory()
- getModule(__name__).filePath.sibling(dropinSource).copyTo(
- fp.child(dropinSource))
- plugins.__path__.append(fp.path)
-
-
-
-class ClientStringTests(unittest.TestCase):
- """
- Tests for L{twisted.internet.endpoints.clientFromString}.
- """
-
- def test_tcp(self):
- """
- When passed a TCP strports description, L{endpoints.clientFromString}
- returns a L{TCP4ClientEndpoint} instance initialized with the values
- from the string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "tcp:host=example.com:port=1234:timeout=7:bindAddress=10.0.0.2")
- self.assertIsInstance(client, endpoints.TCP4ClientEndpoint)
- self.assertIdentical(client._reactor, reactor)
- self.assertEqual(client._host, "example.com")
- self.assertEqual(client._port, 1234)
- self.assertEqual(client._timeout, 7)
- self.assertEqual(client._bindAddress, "10.0.0.2")
-
-
- def test_tcpPositionalArgs(self):
- """
- When passed a TCP strports description using positional arguments,
- L{endpoints.clientFromString} returns a L{TCP4ClientEndpoint} instance
- initialized with the values from the string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "tcp:example.com:1234:timeout=7:bindAddress=10.0.0.2")
- self.assertIsInstance(client, endpoints.TCP4ClientEndpoint)
- self.assertIdentical(client._reactor, reactor)
- self.assertEqual(client._host, "example.com")
- self.assertEqual(client._port, 1234)
- self.assertEqual(client._timeout, 7)
- self.assertEqual(client._bindAddress, "10.0.0.2")
-
-
- def test_tcpHostPositionalArg(self):
- """
- When passed a TCP strports description specifying host as a positional
- argument, L{endpoints.clientFromString} returns a L{TCP4ClientEndpoint}
- instance initialized with the values from the string.
- """
- reactor = object()
-
- client = endpoints.clientFromString(
- reactor,
- "tcp:example.com:port=1234:timeout=7:bindAddress=10.0.0.2")
- self.assertEqual(client._host, "example.com")
- self.assertEqual(client._port, 1234)
-
-
- def test_tcpPortPositionalArg(self):
- """
- When passed a TCP strports description specifying port as a positional
- argument, L{endpoints.clientFromString} returns a L{TCP4ClientEndpoint}
- instance initialized with the values from the string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "tcp:host=example.com:1234:timeout=7:bindAddress=10.0.0.2")
- self.assertEqual(client._host, "example.com")
- self.assertEqual(client._port, 1234)
-
-
- def test_tcpDefaults(self):
- """
- A TCP strports description may omit I{timeout} or I{bindAddress} to
- allow the default to be used.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "tcp:host=example.com:port=1234")
- self.assertEqual(client._timeout, 30)
- self.assertEqual(client._bindAddress, None)
-
-
- def test_unix(self):
- """
- When passed a UNIX strports description, L{endpoints.clientFromString}
- returns a L{UNIXClientEndpoint} instance initialized with the values
- from the string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "unix:path=/var/foo/bar:lockfile=1:timeout=9")
- self.assertIsInstance(client, endpoints.UNIXClientEndpoint)
- self.assertIdentical(client._reactor, reactor)
- self.assertEqual(client._path, "/var/foo/bar")
- self.assertEqual(client._timeout, 9)
- self.assertEqual(client._checkPID, True)
-
-
- def test_unixDefaults(self):
- """
- A UNIX strports description may omit I{lockfile} or I{timeout} to allow
- the defaults to be used.
- """
- client = endpoints.clientFromString(object(), "unix:path=/var/foo/bar")
- self.assertEqual(client._timeout, 30)
- self.assertEqual(client._checkPID, False)
-
-
- def test_unixPathPositionalArg(self):
- """
- When passed a UNIX strports description specifying path as a positional
- argument, L{endpoints.clientFromString} returns a L{UNIXClientEndpoint}
- instance initialized with the values from the string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "unix:/var/foo/bar:lockfile=1:timeout=9")
- self.assertIsInstance(client, endpoints.UNIXClientEndpoint)
- self.assertIdentical(client._reactor, reactor)
- self.assertEqual(client._path, "/var/foo/bar")
- self.assertEqual(client._timeout, 9)
- self.assertEqual(client._checkPID, True)
-
-
- def test_typeFromPlugin(self):
- """
- L{endpoints.clientFromString} looks up plugins of type
- L{IStreamClientEndpoint} and constructs endpoints from them.
- """
- addFakePlugin(self)
- notAReactor = object()
- clientEndpoint = endpoints.clientFromString(
- notAReactor, "cfake:alpha:beta:cee=dee:num=1")
- from twisted.plugins.fakeendpoint import fakeClient
- self.assertIdentical(clientEndpoint.parser, fakeClient)
- self.assertEqual(clientEndpoint.args, ('alpha', 'beta'))
- self.assertEqual(clientEndpoint.kwargs, dict(cee='dee', num='1'))
-
-
- def test_unknownType(self):
- """
- L{endpoints.serverFromString} raises C{ValueError} when given an
- unknown endpoint type.
- """
- value = self.assertRaises(
- # faster-than-light communication not supported
- ValueError, endpoints.clientFromString, None,
- "ftl:andromeda/carcosa/hali/2387")
- self.assertEqual(
- str(value),
- "Unknown endpoint type: 'ftl'")
-
-
-
-class SSLClientStringTests(unittest.TestCase):
- """
- Tests for L{twisted.internet.endpoints.clientFromString} which require SSL.
- """
-
- if skipSSL:
- skip = skipSSL
-
- def test_ssl(self):
- """
- When passed an SSL strports description, L{clientFromString} returns a
- L{SSL4ClientEndpoint} instance initialized with the values from the
- string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "ssl:host=example.net:port=4321:privateKey=%s:"
- "certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%s" %
- (escapedPEMPathName,
- escapedPEMPathName,
- escapedCAsPathName))
- self.assertIsInstance(client, endpoints.SSL4ClientEndpoint)
- self.assertIdentical(client._reactor, reactor)
- self.assertEqual(client._host, "example.net")
- self.assertEqual(client._port, 4321)
- self.assertEqual(client._timeout, 3)
- self.assertEqual(client._bindAddress, "10.0.0.3")
- certOptions = client._sslContextFactory
- self.assertIsInstance(certOptions, CertificateOptions)
- ctx = certOptions.getContext()
- self.assertIsInstance(ctx, ContextType)
- self.assertEqual(Certificate(certOptions.certificate),
- testCertificate)
- privateCert = PrivateCertificate(certOptions.certificate)
- privateCert._setPrivateKey(KeyPair(certOptions.privateKey))
- self.assertEqual(privateCert, testPrivateCertificate)
- expectedCerts = [
- Certificate.loadPEM(x.getContent()) for x in
- [casPath.child("thing1.pem"), casPath.child("thing2.pem")]
- if x.basename().lower().endswith('.pem')
- ]
- self.assertEqual(sorted((Certificate(x) for x in certOptions.caCerts),
- key=lambda cert: cert.digest()),
- sorted(expectedCerts,
- key=lambda cert: cert.digest()))
-
-
- def test_sslPositionalArgs(self):
- """
- When passed an SSL strports description, L{clientFromString} returns a
- L{SSL4ClientEndpoint} instance initialized with the values from the
- string.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor,
- "ssl:example.net:4321:privateKey=%s:"
- "certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%s" %
- (escapedPEMPathName,
- escapedPEMPathName,
- escapedCAsPathName))
- self.assertIsInstance(client, endpoints.SSL4ClientEndpoint)
- self.assertIdentical(client._reactor, reactor)
- self.assertEqual(client._host, "example.net")
- self.assertEqual(client._port, 4321)
- self.assertEqual(client._timeout, 3)
- self.assertEqual(client._bindAddress, "10.0.0.3")
-
-
- def test_unreadableCertificate(self):
- """
- If a certificate in the directory is unreadable,
- L{endpoints._loadCAsFromDir} will ignore that certificate.
- """
- class UnreadableFilePath(FilePath):
- def getContent(self):
- data = FilePath.getContent(self)
- # There is a duplicate of thing2.pem, so ignore anything that
- # looks like it.
- if data == casPath.child("thing2.pem").getContent():
- raise IOError(EPERM)
- else:
- return data
- casPathClone = casPath.child("ignored").parent()
- casPathClone.clonePath = UnreadableFilePath
- self.assertEqual(
- [Certificate(x) for x in endpoints._loadCAsFromDir(casPathClone)],
- [Certificate.loadPEM(casPath.child("thing1.pem").getContent())])
-
-
- def test_sslSimple(self):
- """
- When passed an SSL strports description without any extra parameters,
- L{clientFromString} returns a simple non-verifying endpoint that will
- speak SSL.
- """
- reactor = object()
- client = endpoints.clientFromString(
- reactor, "ssl:host=simple.example.org:port=4321")
- certOptions = client._sslContextFactory
- self.assertIsInstance(certOptions, CertificateOptions)
- self.assertEqual(certOptions.verify, False)
- ctx = certOptions.getContext()
- self.assertIsInstance(ctx, ContextType)
-
-
-
-class AdoptedStreamServerEndpointTestCase(ServerEndpointTestCaseMixin,
- unittest.TestCase):
- """
- Tests for adopted socket-based stream server endpoints.
- """
- def _createStubbedAdoptedEndpoint(self, reactor, fileno, addressFamily):
- """
- Create an L{AdoptedStreamServerEndpoint} which may safely be used with
- an invalid file descriptor. This is convenient for a number of unit
- tests.
- """
- e = endpoints.AdoptedStreamServerEndpoint(reactor, fileno, addressFamily)
- # Stub out some syscalls which would fail, given our invalid file
- # descriptor.
- e._close = lambda fd: None
- e._setNonBlocking = lambda fd: None
- return e
-
-
- def createServerEndpoint(self, reactor, factory):
- """
- Create a new L{AdoptedStreamServerEndpoint} for use by a test.
-
- @return: A three-tuple:
- - The endpoint
- - A tuple of the arguments expected to be passed to the underlying
- reactor method
- - An IAddress object which will match the result of
- L{IListeningPort.getHost} on the port returned by the endpoint.
- """
- fileno = 12
- addressFamily = AF_INET
- endpoint = self._createStubbedAdoptedEndpoint(
- reactor, fileno, addressFamily)
- # Magic numbers come from the implementation of MemoryReactor
- address = IPv4Address("TCP", "0.0.0.0", 1234)
- return (endpoint, (fileno, addressFamily, factory), address)
-
-
- def expectedServers(self, reactor):
- """
- @return: The ports which were actually adopted by C{reactor} via calls
- to its L{IReactorSocket.adoptStreamPort} implementation.
- """
- return reactor.adoptedPorts
-
-
- def listenArgs(self):
- """
- @return: A C{dict} of additional keyword arguments to pass to the
- C{createServerEndpoint}.
- """
- return {}
-
-
- def test_singleUse(self):
- """
- L{AdoptedStreamServerEndpoint.listen} can only be used once. The file
- descriptor given is closed after the first use, and subsequent calls to
- C{listen} return a L{Deferred} that fails with L{AlreadyListened}.
- """
- reactor = MemoryReactor()
- endpoint = self._createStubbedAdoptedEndpoint(reactor, 13, AF_INET)
- endpoint.listen(object())
- d = self.assertFailure(endpoint.listen(object()), error.AlreadyListened)
- def listenFailed(ignored):
- self.assertEqual(1, len(reactor.adoptedPorts))
- d.addCallback(listenFailed)
- return d
-
-
- def test_descriptionNonBlocking(self):
- """
- L{AdoptedStreamServerEndpoint.listen} sets the file description given to
- it to non-blocking.
- """
- reactor = MemoryReactor()
- endpoint = self._createStubbedAdoptedEndpoint(reactor, 13, AF_INET)
- events = []
- def setNonBlocking(fileno):
- events.append(("setNonBlocking", fileno))
- endpoint._setNonBlocking = setNonBlocking
-
- d = endpoint.listen(object())
- def listened(ignored):
- self.assertEqual([("setNonBlocking", 13)], events)
- d.addCallback(listened)
- return d
-
-
- def test_descriptorClosed(self):
- """
- L{AdoptedStreamServerEndpoint.listen} closes its file descriptor after
- adding it to the reactor with L{IReactorSocket.adoptStreamPort}.
- """
- reactor = MemoryReactor()
- endpoint = self._createStubbedAdoptedEndpoint(reactor, 13, AF_INET)
- events = []
- def close(fileno):
- events.append(("close", fileno, len(reactor.adoptedPorts)))
- endpoint._close = close
-
- d = endpoint.listen(object())
- def listened(ignored):
- self.assertEqual([("close", 13, 1)], events)
- d.addCallback(listened)
- return d
-
-
-
-class SystemdEndpointPluginTests(unittest.TestCase):
- """
- Unit tests for the systemd stream server endpoint and endpoint string
- description parser.
-
- @see: U{systemd<http://www.freedesktop.org/wiki/Software/systemd>}
- """
-
- _parserClass = endpoints._SystemdParser
-
- def test_pluginDiscovery(self):
- """
- L{endpoints._SystemdParser} is found as a plugin for
- L{interfaces.IStreamServerEndpointStringParser} interface.
- """
- parsers = list(getPlugins(
- interfaces.IStreamServerEndpointStringParser))
- for p in parsers:
- if isinstance(p, self._parserClass):
- break
- else:
- self.fail("Did not find systemd parser in %r" % (parsers,))
-
-
- def test_interface(self):
- """
- L{endpoints._SystemdParser} instances provide
- L{interfaces.IStreamServerEndpointStringParser}.
- """
- parser = self._parserClass()
- self.assertTrue(verifyObject(
- interfaces.IStreamServerEndpointStringParser, parser))
-
-
- def _parseStreamServerTest(self, addressFamily, addressFamilyString):
- """
- Helper for unit tests for L{endpoints._SystemdParser.parseStreamServer}
- for different address families.
-
- Handling of the address family given will be verify. If there is a
- problem a test-failing exception will be raised.
-
- @param addressFamily: An address family constant, like L{socket.AF_INET}.
-
- @param addressFamilyString: A string which should be recognized by the
- parser as representing C{addressFamily}.
- """
- reactor = object()
- descriptors = [5, 6, 7, 8, 9]
- index = 3
-
- parser = self._parserClass()
- parser._sddaemon = ListenFDs(descriptors)
-
- server = parser.parseStreamServer(
- reactor, domain=addressFamilyString, index=str(index))
- self.assertIdentical(server.reactor, reactor)
- self.assertEqual(server.addressFamily, addressFamily)
- self.assertEqual(server.fileno, descriptors[index])
-
-
- def test_parseStreamServerINET(self):
- """
- IPv4 can be specified using the string C{"INET"}.
- """
- self._parseStreamServerTest(AF_INET, "INET")
-
-
- def test_parseStreamServerINET6(self):
- """
- IPv6 can be specified using the string C{"INET6"}.
- """
- self._parseStreamServerTest(AF_INET6, "INET6")
-
-
- def test_parseStreamServerUNIX(self):
- """
- A UNIX domain socket can be specified using the string C{"UNIX"}.
- """
- try:
- from socket import AF_UNIX
- except ImportError:
- raise unittest.SkipTest("Platform lacks AF_UNIX support")
- else:
- self._parseStreamServerTest(AF_UNIX, "UNIX")
-
-
-
-class TCP6ServerEndpointPluginTests(unittest.TestCase):
- """
- Unit tests for the TCP IPv6 stream server endpoint string description parser.
- """
- _parserClass = endpoints._TCP6ServerParser
-
- def test_pluginDiscovery(self):
- """
- L{endpoints._TCP6ServerParser} is found as a plugin for
- L{interfaces.IStreamServerEndpointStringParser} interface.
- """
- parsers = list(getPlugins(
- interfaces.IStreamServerEndpointStringParser))
- for p in parsers:
- if isinstance(p, self._parserClass):
- break
- else:
- self.fail("Did not find TCP6ServerEndpoint parser in %r" % (parsers,))
-
-
- def test_interface(self):
- """
- L{endpoints._TCP6ServerParser} instances provide
- L{interfaces.IStreamServerEndpointStringParser}.
- """
- parser = self._parserClass()
- self.assertTrue(verifyObject(
- interfaces.IStreamServerEndpointStringParser, parser))
-
-
- def test_stringDescription(self):
- """
- L{serverFromString} returns a L{TCP6ServerEndpoint} instance with a 'tcp6'
- endpoint string description.
- """
- ep = endpoints.serverFromString(MemoryReactor(),
- "tcp6:8080:backlog=12:interface=\:\:1")
- self.assertIsInstance(ep, endpoints.TCP6ServerEndpoint)
- self.assertIsInstance(ep._reactor, MemoryReactor)
- self.assertEqual(ep._port, 8080)
- self.assertEqual(ep._backlog, 12)
- self.assertEqual(ep._interface, '::1')
-
-
-
-class StandardIOEndpointPluginTests(unittest.TestCase):
- """
- Unit tests for the Standard I/O endpoint string description parser.
- """
- _parserClass = endpoints._StandardIOParser
-
- def test_pluginDiscovery(self):
- """
- L{endpoints._StandardIOParser} is found as a plugin for
- L{interfaces.IStreamServerEndpointStringParser} interface.
- """
- parsers = list(getPlugins(
- interfaces.IStreamServerEndpointStringParser))
- for p in parsers:
- if isinstance(p, self._parserClass):
- break
- else:
- self.fail("Did not find StandardIOEndpoint parser in %r" % (parsers,))
-
-
- def test_interface(self):
- """
- L{endpoints._StandardIOParser} instances provide
- L{interfaces.IStreamServerEndpointStringParser}.
- """
- parser = self._parserClass()
- self.assertTrue(verifyObject(
- interfaces.IStreamServerEndpointStringParser, parser))
-
-
- def test_stringDescription(self):
- """
- L{serverFromString} returns a L{StandardIOEndpoint} instance with a 'stdio'
- endpoint string description.
- """
- ep = endpoints.serverFromString(MemoryReactor(), "stdio:")
- self.assertIsInstance(ep, endpoints.StandardIOEndpoint)
- self.assertIsInstance(ep._reactor, MemoryReactor)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_epollreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_epollreactor.py
deleted file mode 100755
index b8363ee8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_epollreactor.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.epollreactor}.
-"""
-
-from twisted.trial.unittest import TestCase
-try:
- from twisted.internet.epollreactor import _ContinuousPolling
-except ImportError:
- _ContinuousPolling = None
-from twisted.internet.task import Clock
-from twisted.internet.error import ConnectionDone
-
-
-
-class Descriptor(object):
- """
- Records reads and writes, as if it were a C{FileDescriptor}.
- """
-
- def __init__(self):
- self.events = []
-
-
- def fileno(self):
- return 1
-
-
- def doRead(self):
- self.events.append("read")
-
-
- def doWrite(self):
- self.events.append("write")
-
-
- def connectionLost(self, reason):
- reason.trap(ConnectionDone)
- self.events.append("lost")
-
-
-
-class ContinuousPollingTests(TestCase):
- """
- L{_ContinuousPolling} can be used to read and write from C{FileDescriptor}
- objects.
- """
-
- def test_addReader(self):
- """
- Adding a reader when there was previously no reader starts up a
- C{LoopingCall}.
- """
- poller = _ContinuousPolling(Clock())
- self.assertEqual(poller._loop, None)
- reader = object()
- self.assertFalse(poller.isReading(reader))
- poller.addReader(reader)
- self.assertNotEqual(poller._loop, None)
- self.assertTrue(poller._loop.running)
- self.assertIdentical(poller._loop.clock, poller._reactor)
- self.assertTrue(poller.isReading(reader))
-
-
- def test_addWriter(self):
- """
- Adding a writer when there was previously no writer starts up a
- C{LoopingCall}.
- """
- poller = _ContinuousPolling(Clock())
- self.assertEqual(poller._loop, None)
- writer = object()
- self.assertFalse(poller.isWriting(writer))
- poller.addWriter(writer)
- self.assertNotEqual(poller._loop, None)
- self.assertTrue(poller._loop.running)
- self.assertIdentical(poller._loop.clock, poller._reactor)
- self.assertTrue(poller.isWriting(writer))
-
-
- def test_removeReader(self):
- """
- Removing a reader stops the C{LoopingCall}.
- """
- poller = _ContinuousPolling(Clock())
- reader = object()
- poller.addReader(reader)
- poller.removeReader(reader)
- self.assertEqual(poller._loop, None)
- self.assertEqual(poller._reactor.getDelayedCalls(), [])
- self.assertFalse(poller.isReading(reader))
-
-
- def test_removeWriter(self):
- """
- Removing a writer stops the C{LoopingCall}.
- """
- poller = _ContinuousPolling(Clock())
- writer = object()
- poller.addWriter(writer)
- poller.removeWriter(writer)
- self.assertEqual(poller._loop, None)
- self.assertEqual(poller._reactor.getDelayedCalls(), [])
- self.assertFalse(poller.isWriting(writer))
-
-
- def test_removeUnknown(self):
- """
- Removing unknown readers and writers silently does nothing.
- """
- poller = _ContinuousPolling(Clock())
- poller.removeWriter(object())
- poller.removeReader(object())
-
-
- def test_multipleReadersAndWriters(self):
- """
- Adding multiple readers and writers results in a single
- C{LoopingCall}.
- """
- poller = _ContinuousPolling(Clock())
- writer = object()
- poller.addWriter(writer)
- self.assertNotEqual(poller._loop, None)
- poller.addWriter(object())
- self.assertNotEqual(poller._loop, None)
- poller.addReader(object())
- self.assertNotEqual(poller._loop, None)
- poller.addReader(object())
- poller.removeWriter(writer)
- self.assertNotEqual(poller._loop, None)
- self.assertTrue(poller._loop.running)
- self.assertEqual(len(poller._reactor.getDelayedCalls()), 1)
-
-
- def test_readerPolling(self):
- """
- Adding a reader causes its C{doRead} to be called every 1
- milliseconds.
- """
- reactor = Clock()
- poller = _ContinuousPolling(reactor)
- desc = Descriptor()
- poller.addReader(desc)
- self.assertEqual(desc.events, [])
- reactor.advance(0.00001)
- self.assertEqual(desc.events, ["read"])
- reactor.advance(0.00001)
- self.assertEqual(desc.events, ["read", "read"])
- reactor.advance(0.00001)
- self.assertEqual(desc.events, ["read", "read", "read"])
-
-
- def test_writerPolling(self):
- """
- Adding a writer causes its C{doWrite} to be called every 1
- milliseconds.
- """
- reactor = Clock()
- poller = _ContinuousPolling(reactor)
- desc = Descriptor()
- poller.addWriter(desc)
- self.assertEqual(desc.events, [])
- reactor.advance(0.001)
- self.assertEqual(desc.events, ["write"])
- reactor.advance(0.001)
- self.assertEqual(desc.events, ["write", "write"])
- reactor.advance(0.001)
- self.assertEqual(desc.events, ["write", "write", "write"])
-
-
- def test_connectionLostOnRead(self):
- """
- If a C{doRead} returns a value indicating disconnection,
- C{connectionLost} is called on it.
- """
- reactor = Clock()
- poller = _ContinuousPolling(reactor)
- desc = Descriptor()
- desc.doRead = lambda: ConnectionDone()
- poller.addReader(desc)
- self.assertEqual(desc.events, [])
- reactor.advance(0.001)
- self.assertEqual(desc.events, ["lost"])
-
-
- def test_connectionLostOnWrite(self):
- """
- If a C{doWrite} returns a value indicating disconnection,
- C{connectionLost} is called on it.
- """
- reactor = Clock()
- poller = _ContinuousPolling(reactor)
- desc = Descriptor()
- desc.doWrite = lambda: ConnectionDone()
- poller.addWriter(desc)
- self.assertEqual(desc.events, [])
- reactor.advance(0.001)
- self.assertEqual(desc.events, ["lost"])
-
-
- def test_removeAll(self):
- """
- L{_ContinuousPolling.removeAll} removes all descriptors and returns
- the readers and writers.
- """
- poller = _ContinuousPolling(Clock())
- reader = object()
- writer = object()
- both = object()
- poller.addReader(reader)
- poller.addReader(both)
- poller.addWriter(writer)
- poller.addWriter(both)
- removed = poller.removeAll()
- self.assertEqual(poller.getReaders(), [])
- self.assertEqual(poller.getWriters(), [])
- self.assertEqual(len(removed), 3)
- self.assertEqual(set(removed), set([reader, writer, both]))
-
-
- def test_getReaders(self):
- """
- L{_ContinuousPolling.getReaders} returns a list of the read
- descriptors.
- """
- poller = _ContinuousPolling(Clock())
- reader = object()
- poller.addReader(reader)
- self.assertIn(reader, poller.getReaders())
-
-
- def test_getWriters(self):
- """
- L{_ContinuousPolling.getWriters} returns a list of the write
- descriptors.
- """
- poller = _ContinuousPolling(Clock())
- writer = object()
- poller.addWriter(writer)
- self.assertIn(writer, poller.getWriters())
-
- if _ContinuousPolling is None:
- skip = "epoll not supported in this environment."
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_fdset.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_fdset.py
deleted file mode 100755
index f05ca08f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_fdset.py
+++ /dev/null
@@ -1,394 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorFDSet}.
-"""
-
-__metaclass__ = type
-
-import os, socket, traceback
-
-from zope.interface import implements
-
-from twisted.python.runtime import platform
-from twisted.trial.unittest import SkipTest
-from twisted.internet.interfaces import IReactorFDSet, IReadDescriptor
-from twisted.internet.abstract import FileDescriptor
-from twisted.internet.test.reactormixins import ReactorBuilder
-
-# twisted.internet.tcp nicely defines some names with proper values on
-# several different platforms.
-from twisted.internet.tcp import EINPROGRESS, EWOULDBLOCK
-
-
-def socketpair():
- serverSocket = socket.socket()
- serverSocket.bind(('127.0.0.1', 0))
- serverSocket.listen(1)
- try:
- client = socket.socket()
- try:
- client.setblocking(False)
- try:
- client.connect(('127.0.0.1', serverSocket.getsockname()[1]))
- except socket.error, e:
- if e.args[0] not in (EINPROGRESS, EWOULDBLOCK):
- raise
- server, addr = serverSocket.accept()
- except:
- client.close()
- raise
- finally:
- serverSocket.close()
-
- return client, server
-
-
-class ReactorFDSetTestsBuilder(ReactorBuilder):
- """
- Builder defining tests relating to L{IReactorFDSet}.
- """
- requiredInterfaces = [IReactorFDSet]
-
- def _connectedPair(self):
- """
- Return the two sockets which make up a new TCP connection.
- """
- client, server = socketpair()
- self.addCleanup(client.close)
- self.addCleanup(server.close)
- return client, server
-
-
- def _simpleSetup(self):
- reactor = self.buildReactor()
-
- client, server = self._connectedPair()
-
- fd = FileDescriptor(reactor)
- fd.fileno = client.fileno
-
- return reactor, fd, server
-
-
- def test_addReader(self):
- """
- C{reactor.addReader()} accepts an L{IReadDescriptor} provider and calls
- its C{doRead} method when there may be data available on its C{fileno}.
- """
- reactor, fd, server = self._simpleSetup()
-
- def removeAndStop():
- reactor.removeReader(fd)
- reactor.stop()
- fd.doRead = removeAndStop
- reactor.addReader(fd)
- server.sendall('x')
-
- # The reactor will only stop if it calls fd.doRead.
- self.runReactor(reactor)
- # Nothing to assert, just be glad we got this far.
-
-
- def test_removeReader(self):
- """
- L{reactor.removeReader()} accepts an L{IReadDescriptor} provider
- previously passed to C{reactor.addReader()} and causes it to no longer
- be monitored for input events.
- """
- reactor, fd, server = self._simpleSetup()
-
- def fail():
- self.fail("doRead should not be called")
- fd.doRead = fail
-
- reactor.addReader(fd)
- reactor.removeReader(fd)
- server.sendall('x')
-
- # Give the reactor two timed event passes to notice that there's I/O
- # (if it is incorrectly watching for I/O).
- reactor.callLater(0, reactor.callLater, 0, reactor.stop)
-
- self.runReactor(reactor)
- # Getting here means the right thing happened probably.
-
-
- def test_addWriter(self):
- """
- C{reactor.addWriter()} accepts an L{IWriteDescriptor} provider and
- calls its C{doWrite} method when it may be possible to write to its
- C{fileno}.
- """
- reactor, fd, server = self._simpleSetup()
-
- def removeAndStop():
- reactor.removeWriter(fd)
- reactor.stop()
- fd.doWrite = removeAndStop
- reactor.addWriter(fd)
-
- self.runReactor(reactor)
- # Getting here is great.
-
-
- def _getFDTest(self, kind):
- """
- Helper for getReaders and getWriters tests.
- """
- reactor = self.buildReactor()
- get = getattr(reactor, 'get' + kind + 's')
- add = getattr(reactor, 'add' + kind)
- remove = getattr(reactor, 'remove' + kind)
-
- client, server = self._connectedPair()
-
- self.assertNotIn(client, get())
- self.assertNotIn(server, get())
-
- add(client)
- self.assertIn(client, get())
- self.assertNotIn(server, get())
-
- remove(client)
- self.assertNotIn(client, get())
- self.assertNotIn(server, get())
-
-
- def test_getReaders(self):
- """
- L{IReactorFDSet.getReaders} reflects the additions and removals made
- with L{IReactorFDSet.addReader} and L{IReactorFDSet.removeReader}.
- """
- self._getFDTest('Reader')
-
-
- def test_removeWriter(self):
- """
- L{reactor.removeWriter()} accepts an L{IWriteDescriptor} provider
- previously passed to C{reactor.addWriter()} and causes it to no longer
- be monitored for outputability.
- """
- reactor, fd, server = self._simpleSetup()
-
- def fail():
- self.fail("doWrite should not be called")
- fd.doWrite = fail
-
- reactor.addWriter(fd)
- reactor.removeWriter(fd)
-
- # Give the reactor two timed event passes to notice that there's I/O
- # (if it is incorrectly watching for I/O).
- reactor.callLater(0, reactor.callLater, 0, reactor.stop)
-
- self.runReactor(reactor)
- # Getting here means the right thing happened probably.
-
-
- def test_getWriters(self):
- """
- L{IReactorFDSet.getWriters} reflects the additions and removals made
- with L{IReactorFDSet.addWriter} and L{IReactorFDSet.removeWriter}.
- """
- self._getFDTest('Writer')
-
-
- def test_removeAll(self):
- """
- C{reactor.removeAll()} removes all registered L{IReadDescriptor}
- providers and all registered L{IWriteDescriptor} providers and returns
- them.
- """
- reactor = self.buildReactor()
-
- reactor, fd, server = self._simpleSetup()
-
- fd.doRead = lambda: self.fail("doRead should not be called")
- fd.doWrite = lambda: self.fail("doWrite should not be called")
-
- server.sendall('x')
-
- reactor.addReader(fd)
- reactor.addWriter(fd)
-
- removed = reactor.removeAll()
-
- # Give the reactor two timed event passes to notice that there's I/O
- # (if it is incorrectly watching for I/O).
- reactor.callLater(0, reactor.callLater, 0, reactor.stop)
-
- self.runReactor(reactor)
- # Getting here means the right thing happened probably.
-
- self.assertEqual(removed, [fd])
-
-
- def test_removedFromReactor(self):
- """
- A descriptor's C{fileno} method should not be called after the
- descriptor has been removed from the reactor.
- """
- reactor = self.buildReactor()
- descriptor = RemovingDescriptor(reactor)
- reactor.callWhenRunning(descriptor.start)
- self.runReactor(reactor)
- self.assertEqual(descriptor.calls, [])
-
-
- def test_negativeOneFileDescriptor(self):
- """
- If L{FileDescriptor.fileno} returns C{-1}, the descriptor is removed
- from the reactor.
- """
- reactor = self.buildReactor()
-
- client, server = self._connectedPair()
-
- class DisappearingDescriptor(FileDescriptor):
- _fileno = server.fileno()
-
- _received = ""
-
- def fileno(self):
- return self._fileno
-
- def doRead(self):
- self._fileno = -1
- self._received += server.recv(1)
- client.send('y')
-
- def connectionLost(self, reason):
- reactor.stop()
-
- descriptor = DisappearingDescriptor(reactor)
- reactor.addReader(descriptor)
- client.send('x')
- self.runReactor(reactor)
- self.assertEqual(descriptor._received, "x")
-
-
- def test_lostFileDescriptor(self):
- """
- The file descriptor underlying a FileDescriptor may be closed and
- replaced by another at some point. Bytes which arrive on the new
- descriptor must not be delivered to the FileDescriptor which was
- originally registered with the original descriptor of the same number.
-
- Practically speaking, this is difficult or impossible to detect. The
- implementation relies on C{fileno} raising an exception if the original
- descriptor has gone away. If C{fileno} continues to return the original
- file descriptor value, the reactor may deliver events from that
- descriptor. This is a best effort attempt to ease certain debugging
- situations. Applications should not rely on it intentionally.
- """
- reactor = self.buildReactor()
-
- name = reactor.__class__.__name__
- if name in ('EPollReactor', 'KQueueReactor', 'CFReactor'):
- # Closing a file descriptor immediately removes it from the epoll
- # set without generating a notification. That means epollreactor
- # will not call any methods on Victim after the close, so there's
- # no chance to notice the socket is no longer valid.
- raise SkipTest("%r cannot detect lost file descriptors" % (name,))
-
- client, server = self._connectedPair()
-
- class Victim(FileDescriptor):
- """
- This L{FileDescriptor} will have its socket closed out from under it
- and another socket will take its place. It will raise a
- socket.error from C{fileno} after this happens (because socket
- objects remember whether they have been closed), so as long as the
- reactor calls the C{fileno} method the problem will be detected.
- """
- def fileno(self):
- return server.fileno()
-
- def doRead(self):
- raise Exception("Victim.doRead should never be called")
-
- def connectionLost(self, reason):
- """
- When the problem is detected, the reactor should disconnect this
- file descriptor. When that happens, stop the reactor so the
- test ends.
- """
- reactor.stop()
-
- reactor.addReader(Victim())
-
- # Arrange for the socket to be replaced at some unspecified time.
- # Significantly, this will not be while any I/O processing code is on
- # the stack. It is something that happens independently and cannot be
- # relied upon to happen at a convenient time, such as within a call to
- # doRead.
- def messItUp():
- newC, newS = self._connectedPair()
- fileno = server.fileno()
- server.close()
- os.dup2(newS.fileno(), fileno)
- newC.send("x")
- reactor.callLater(0, messItUp)
-
- self.runReactor(reactor)
-
- # If the implementation feels like logging the exception raised by
- # MessedUp.fileno, that's fine.
- self.flushLoggedErrors(socket.error)
- if platform.isWindows():
- test_lostFileDescriptor.skip = (
- "Cannot duplicate socket filenos on Windows")
-
-
-
-class RemovingDescriptor(object):
- """
- A read descriptor which removes itself from the reactor as soon as it
- gets a chance to do a read and keeps track of when its own C{fileno}
- method is called.
-
- @ivar insideReactor: A flag which is true as long as the reactor has
- this descriptor as a reader.
-
- @ivar calls: A list of the bottom of the call stack for any call to
- C{fileno} when C{insideReactor} is false.
- """
- implements(IReadDescriptor)
-
-
- def __init__(self, reactor):
- self.reactor = reactor
- self.insideReactor = False
- self.calls = []
- self.read, self.write = socketpair()
-
-
- def start(self):
- self.insideReactor = True
- self.reactor.addReader(self)
- self.write.send('a')
-
-
- def logPrefix(self):
- return 'foo'
-
-
- def doRead(self):
- self.reactor.removeReader(self)
- self.insideReactor = False
- self.reactor.stop()
-
-
- def fileno(self):
- if not self.insideReactor:
- self.calls.append(traceback.extract_stack(limit=5)[:-1])
- return self.read.fileno()
-
-
- def connectionLost(self, reason):
- pass
-
-
-globals().update(ReactorFDSetTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_filedescriptor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_filedescriptor.py
deleted file mode 100755
index 5537a673..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_filedescriptor.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Whitebox tests for L{twisted.internet.abstract.FileDescriptor}.
-"""
-
-from zope.interface.verify import verifyClass
-
-from twisted.internet.abstract import FileDescriptor
-from twisted.internet.interfaces import IPushProducer
-from twisted.trial.unittest import TestCase
-
-
-
-class FileDescriptorTests(TestCase):
- """
- Tests for L{FileDescriptor}.
- """
- def test_writeWithUnicodeRaisesException(self):
- """
- L{FileDescriptor.write} doesn't accept unicode data.
- """
- fileDescriptor = FileDescriptor()
- self.assertRaises(TypeError, fileDescriptor.write, u'foo')
-
-
- def test_writeSequenceWithUnicodeRaisesException(self):
- """
- L{FileDescriptor.writeSequence} doesn't accept unicode data.
- """
- fileDescriptor = FileDescriptor()
- self.assertRaises(
- TypeError, fileDescriptor.writeSequence, ['foo', u'bar', 'baz'])
-
-
- def test_implementInterfaceIPushProducer(self):
- """
- L{FileDescriptor} should implement L{IPushProducer}.
- """
- self.assertTrue(verifyClass(IPushProducer, FileDescriptor))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_glibbase.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_glibbase.py
deleted file mode 100755
index 0bf79d8a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_glibbase.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for twisted.internet.glibbase.
-"""
-
-import sys
-from twisted.trial.unittest import TestCase
-from twisted.internet._glibbase import ensureNotImported
-
-
-
-class EnsureNotImportedTests(TestCase):
- """
- L{ensureNotImported} protects against unwanted past and future imports.
- """
-
- def test_ensureWhenNotImported(self):
- """
- If the specified modules have never been imported, and import
- prevention is requested, L{ensureNotImported} makes sure they will not
- be imported in the future.
- """
- modules = {}
- self.patch(sys, "modules", modules)
- ensureNotImported(["m1", "m2"], "A message.",
- preventImports=["m1", "m2", "m3"])
- self.assertEquals(modules, {"m1": None, "m2": None, "m3": None})
-
-
- def test_ensureWhenNotImportedDontPrevent(self):
- """
- If the specified modules have never been imported, and import
- prevention is not requested, L{ensureNotImported} has no effect.
- """
- modules = {}
- self.patch(sys, "modules", modules)
- ensureNotImported(["m1", "m2"], "A message.")
- self.assertEquals(modules, {})
-
-
- def test_ensureWhenFailedToImport(self):
- """
- If the specified modules have been set to C{None} in C{sys.modules},
- L{ensureNotImported} does not complain.
- """
- modules = {"m2": None}
- self.patch(sys, "modules", modules)
- ensureNotImported(["m1", "m2"], "A message.", preventImports=["m1", "m2"])
- self.assertEquals(modules, {"m1": None, "m2": None})
-
-
- def test_ensureFailsWhenImported(self):
- """
- If one of the specified modules has been previously imported,
- L{ensureNotImported} raises an exception.
- """
- module = object()
- modules = {"m2": module}
- self.patch(sys, "modules", modules)
- e = self.assertRaises(ImportError, ensureNotImported,
- ["m1", "m2"], "A message.",
- preventImports=["m1", "m2"])
- self.assertEquals(modules, {"m2": module})
- self.assertEquals(e.args, ("A message.",))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtk3reactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtk3reactor.py
deleted file mode 100755
index 60a20e0c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtk3reactor.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-GI/GTK3 reactor tests.
-"""
-
-try:
- from twisted.internet import gireactor, gtk3reactor
- from gi.repository import Gtk, Gio
-except ImportError:
- gireactor = None
-
-from twisted.internet.error import ReactorAlreadyRunning
-from twisted.trial.unittest import TestCase, SkipTest
-from twisted.internet.test.reactormixins import ReactorBuilder
-
-
-
-class GtkApplicationRegistration(ReactorBuilder, TestCase):
- """
- GtkApplication and GApplication are supported by
- L{twisted.internet.gtk3reactor} and L{twisted.internet.gireactor}.
-
- We inherit from L{ReactorBuilder} in order to use some of its
- reactor-running infrastructure, but don't need its test-creation
- functionality.
- """
- if gireactor is None:
- skip = "gtk3/gi not importable"
-
-
- def runReactor(self, app, reactor):
- """
- Register the app, run the reactor, make sure app was activated, and
- that reactor was running, and that reactor can be stopped.
- """
- if not hasattr(app, "quit"):
- raise SkipTest("Version of PyGObject is too old.")
-
- result = []
- def stop():
- result.append("stopped")
- reactor.stop()
- def activate(widget):
- result.append("activated")
- reactor.callLater(0, stop)
- app.connect('activate', activate)
-
- # We want reactor.stop() to *always* stop the event loop, even if
- # someone has called hold() on the application and never done the
- # corresponding release() -- for more details see
- # http://developer.gnome.org/gio/unstable/GApplication.html.
- app.hold()
-
- reactor.registerGApplication(app)
- ReactorBuilder.runReactor(self, reactor)
- self.assertEqual(result, ["activated", "stopped"])
-
-
- def test_gApplicationActivate(self):
- """
- L{Gio.Application} instances can be registered with a gireactor.
- """
- reactor = gireactor.GIReactor(useGtk=False)
- self.addCleanup(self.unbuildReactor, reactor)
- app = Gio.Application(
- application_id='com.twistedmatrix.trial.gireactor',
- flags=Gio.ApplicationFlags.FLAGS_NONE)
-
- self.runReactor(app, reactor)
-
-
- def test_gtkApplicationActivate(self):
- """
- L{Gtk.Application} instances can be registered with a gtk3reactor.
- """
- reactor = gtk3reactor.Gtk3Reactor()
- self.addCleanup(self.unbuildReactor, reactor)
- app = Gtk.Application(
- application_id='com.twistedmatrix.trial.gtk3reactor',
- flags=Gio.ApplicationFlags.FLAGS_NONE)
-
- self.runReactor(app, reactor)
-
-
- def test_portable(self):
- """
- L{gireactor.PortableGIReactor} doesn't support application
- registration at this time.
- """
- reactor = gireactor.PortableGIReactor()
- self.addCleanup(self.unbuildReactor, reactor)
- app = Gio.Application(
- application_id='com.twistedmatrix.trial.gireactor',
- flags=Gio.ApplicationFlags.FLAGS_NONE)
- self.assertRaises(NotImplementedError,
- reactor.registerGApplication, app)
-
-
- def test_noQuit(self):
- """
- Older versions of PyGObject lack C{Application.quit}, and so won't
- allow registration.
- """
- reactor = gireactor.GIReactor(useGtk=False)
- self.addCleanup(self.unbuildReactor, reactor)
- # An app with no "quit" method:
- app = object()
- exc = self.assertRaises(RuntimeError, reactor.registerGApplication, app)
- self.assertTrue(exc.args[0].startswith(
- "Application registration is not"))
-
-
- def test_cantRegisterAfterRun(self):
- """
- It is not possible to register a C{Application} after the reactor has
- already started.
- """
- reactor = gireactor.GIReactor(useGtk=False)
- self.addCleanup(self.unbuildReactor, reactor)
- app = Gio.Application(
- application_id='com.twistedmatrix.trial.gireactor',
- flags=Gio.ApplicationFlags.FLAGS_NONE)
-
- def tryRegister():
- exc = self.assertRaises(ReactorAlreadyRunning,
- reactor.registerGApplication, app)
- self.assertEqual(exc.args[0],
- "Can't register application after reactor was started.")
- reactor.stop()
- reactor.callLater(0, tryRegister)
- ReactorBuilder.runReactor(self, reactor)
-
-
- def test_cantRegisterTwice(self):
- """
- It is not possible to register more than one C{Application}.
- """
- reactor = gireactor.GIReactor(useGtk=False)
- self.addCleanup(self.unbuildReactor, reactor)
- app = Gio.Application(
- application_id='com.twistedmatrix.trial.gireactor',
- flags=Gio.ApplicationFlags.FLAGS_NONE)
- reactor.registerGApplication(app)
- app2 = Gio.Application(
- application_id='com.twistedmatrix.trial.gireactor2',
- flags=Gio.ApplicationFlags.FLAGS_NONE)
- exc = self.assertRaises(RuntimeError,
- reactor.registerGApplication, app2)
- self.assertEqual(exc.args[0],
- "Can't register more than one application instance.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtkreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtkreactor.py
deleted file mode 100755
index 78039c00..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_gtkreactor.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests to ensure all attributes of L{twisted.internet.gtkreactor} are
-deprecated.
-"""
-
-import sys
-
-from twisted.trial.unittest import TestCase
-
-
-class GtkReactorDeprecation(TestCase):
- """
- Tests to ensure all attributes of L{twisted.internet.gtkreactor} are
- deprecated.
- """
-
- class StubGTK:
- class GDK:
- INPUT_READ = None
- def input_add(self, *params):
- pass
-
- class StubPyGTK:
- def require(self, something):
- pass
-
- def setUp(self):
- """
- Create a stub for the module 'gtk' if it does not exist, so that it can
- be imported without errors or warnings.
- """
- self.mods = sys.modules.copy()
- sys.modules['gtk'] = self.StubGTK()
- sys.modules['pygtk'] = self.StubPyGTK()
-
-
- def tearDown(self):
- """
- Return sys.modules to the way it was before the test.
- """
- sys.modules.clear()
- sys.modules.update(self.mods)
-
-
- def lookForDeprecationWarning(self, testmethod, attributeName):
- warningsShown = self.flushWarnings([testmethod])
- self.assertEqual(len(warningsShown), 1)
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- warningsShown[0]['message'],
- "twisted.internet.gtkreactor." + attributeName + " "
- "was deprecated in Twisted 10.1.0: All new applications should be "
- "written with gtk 2.x, which is supported by "
- "twisted.internet.gtk2reactor.")
-
-
- def test_gtkReactor(self):
- """
- Test deprecation of L{gtkreactor.GtkReactor}
- """
- from twisted.internet import gtkreactor
- gtkreactor.GtkReactor();
- self.lookForDeprecationWarning(self.test_gtkReactor, "GtkReactor")
-
-
- def test_portableGtkReactor(self):
- """
- Test deprecation of L{gtkreactor.GtkReactor}
- """
- from twisted.internet import gtkreactor
- gtkreactor.PortableGtkReactor()
- self.lookForDeprecationWarning(self.test_portableGtkReactor,
- "PortableGtkReactor")
-
-
- def test_install(self):
- """
- Test deprecation of L{gtkreactor.install}
- """
- from twisted.internet import gtkreactor
- self.assertRaises(AssertionError, gtkreactor.install)
- self.lookForDeprecationWarning(self.test_install, "install")
-
-
- def test_portableInstall(self):
- """
- Test deprecation of L{gtkreactor.portableInstall}
- """
- from twisted.internet import gtkreactor
- self.assertRaises(AssertionError, gtkreactor.portableInstall)
- self.lookForDeprecationWarning(self.test_portableInstall,
- "portableInstall")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inlinecb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inlinecb.py
deleted file mode 100755
index 7b818d2d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inlinecb.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Conditional import of C{inlinecb_tests} for Python 2.5 and greater.
-"""
-import sys
-
-__all__ = ['NonLocalExitTests']
-
-if sys.version_info[:2] >= (2, 5):
- from twisted.internet.test.inlinecb_tests import NonLocalExitTests
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inotify.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inotify.py
deleted file mode 100755
index a0035622..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_inotify.py
+++ /dev/null
@@ -1,504 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the inotify wrapper in L{twisted.internet.inotify}.
-"""
-
-from twisted.internet import defer, reactor
-from twisted.python import filepath, runtime
-from twisted.trial import unittest
-
-try:
- from twisted.python import _inotify
-except ImportError:
- inotify = None
-else:
- from twisted.internet import inotify
-
-
-
-class TestINotify(unittest.TestCase):
- """
- Define all the tests for the basic functionality exposed by
- L{inotify.INotify}.
- """
- if not runtime.platform.supportsINotify():
- skip = "This platform doesn't support INotify."
-
- def setUp(self):
- self.dirname = filepath.FilePath(self.mktemp())
- self.dirname.createDirectory()
- self.inotify = inotify.INotify()
- self.inotify.startReading()
- self.addCleanup(self.inotify.loseConnection)
-
-
- def test_initializationErrors(self):
- """
- L{inotify.INotify} emits a C{RuntimeError} when initialized
- in an environment that doesn't support inotify as we expect it.
-
- We just try to raise an exception for every possible case in
- the for loop in L{inotify.INotify._inotify__init__}.
- """
- class FakeINotify:
- def init(self):
- raise inotify.INotifyError()
- self.patch(inotify.INotify, '_inotify', FakeINotify())
- self.assertRaises(inotify.INotifyError, inotify.INotify)
-
-
- def _notificationTest(self, mask, operation, expectedPath=None):
- """
- Test notification from some filesystem operation.
-
- @param mask: The event mask to use when setting up the watch.
-
- @param operation: A function which will be called with the
- name of a file in the watched directory and which should
- trigger the event.
-
- @param expectedPath: Optionally, the name of the path which is
- expected to come back in the notification event; this will
- also be passed to C{operation} (primarily useful when the
- operation is being done to the directory itself, not a
- file in it).
-
- @return: A L{Deferred} which fires successfully when the
- expected event has been received or fails otherwise.
- """
- if expectedPath is None:
- expectedPath = self.dirname.child("foo.bar")
- notified = defer.Deferred()
- def cbNotified((watch, filename, events)):
- self.assertEqual(filename, expectedPath)
- self.assertTrue(events & mask)
- notified.addCallback(cbNotified)
-
- self.inotify.watch(
- self.dirname, mask=mask,
- callbacks=[lambda *args: notified.callback(args)])
- operation(expectedPath)
- return notified
-
-
- def test_access(self):
- """
- Reading from a file in a monitored directory sends an
- C{inotify.IN_ACCESS} event to the callback.
- """
- def operation(path):
- path.setContent("foo")
- path.getContent()
-
- return self._notificationTest(inotify.IN_ACCESS, operation)
-
-
- def test_modify(self):
- """
- Writing to a file in a monitored directory sends an
- C{inotify.IN_MODIFY} event to the callback.
- """
- def operation(path):
- fObj = path.open("w")
- fObj.write('foo')
- fObj.close()
-
- return self._notificationTest(inotify.IN_MODIFY, operation)
-
-
- def test_attrib(self):
- """
- Changing the metadata of a a file in a monitored directory
- sends an C{inotify.IN_ATTRIB} event to the callback.
- """
- def operation(path):
- path.touch()
- path.touch()
-
- return self._notificationTest(inotify.IN_ATTRIB, operation)
-
-
- def test_closeWrite(self):
- """
- Closing a file which was open for writing in a monitored
- directory sends an C{inotify.IN_CLOSE_WRITE} event to the
- callback.
- """
- def operation(path):
- fObj = path.open("w")
- fObj.close()
-
- return self._notificationTest(inotify.IN_CLOSE_WRITE, operation)
-
-
- def test_closeNoWrite(self):
- """
- Closing a file which was open for reading but not writing in a
- monitored directory sends an C{inotify.IN_CLOSE_NOWRITE} event
- to the callback.
- """
- def operation(path):
- path.touch()
- fObj = path.open("r")
- fObj.close()
-
- return self._notificationTest(inotify.IN_CLOSE_NOWRITE, operation)
-
-
- def test_open(self):
- """
- Opening a file in a monitored directory sends an
- C{inotify.IN_OPEN} event to the callback.
- """
- def operation(path):
- fObj = path.open("w")
- fObj.close()
-
- return self._notificationTest(inotify.IN_OPEN, operation)
-
-
- def test_movedFrom(self):
- """
- Moving a file out of a monitored directory sends an
- C{inotify.IN_MOVED_FROM} event to the callback.
- """
- def operation(path):
- fObj = path.open("w")
- fObj.close()
- path.moveTo(filepath.FilePath(self.mktemp()))
-
- return self._notificationTest(inotify.IN_MOVED_FROM, operation)
-
-
- def test_movedTo(self):
- """
- Moving a file into a monitored directory sends an
- C{inotify.IN_MOVED_TO} event to the callback.
- """
- def operation(path):
- p = filepath.FilePath(self.mktemp())
- p.touch()
- p.moveTo(path)
-
- return self._notificationTest(inotify.IN_MOVED_TO, operation)
-
-
- def test_create(self):
- """
- Creating a file in a monitored directory sends an
- C{inotify.IN_CREATE} event to the callback.
- """
- def operation(path):
- fObj = path.open("w")
- fObj.close()
-
- return self._notificationTest(inotify.IN_CREATE, operation)
-
-
- def test_delete(self):
- """
- Deleting a file in a monitored directory sends an
- C{inotify.IN_DELETE} event to the callback.
- """
- def operation(path):
- path.touch()
- path.remove()
-
- return self._notificationTest(inotify.IN_DELETE, operation)
-
-
- def test_deleteSelf(self):
- """
- Deleting the monitored directory itself sends an
- C{inotify.IN_DELETE_SELF} event to the callback.
- """
- def operation(path):
- path.remove()
-
- return self._notificationTest(
- inotify.IN_DELETE_SELF, operation, expectedPath=self.dirname)
-
-
- def test_moveSelf(self):
- """
- Renaming the monitored directory itself sends an
- C{inotify.IN_MOVE_SELF} event to the callback.
- """
- def operation(path):
- path.moveTo(filepath.FilePath(self.mktemp()))
-
- return self._notificationTest(
- inotify.IN_MOVE_SELF, operation, expectedPath=self.dirname)
-
-
- def test_simpleSubdirectoryAutoAdd(self):
- """
- L{inotify.INotify} when initialized with autoAdd==True adds
- also adds the created subdirectories to the watchlist.
- """
- def _callback(wp, filename, mask):
- # We are notified before we actually process new
- # directories, so we need to defer this check.
- def _():
- try:
- self.assertTrue(self.inotify._isWatched(subdir))
- d.callback(None)
- except Exception:
- d.errback()
- reactor.callLater(0, _)
-
- checkMask = inotify.IN_ISDIR | inotify.IN_CREATE
- self.inotify.watch(
- self.dirname, mask=checkMask, autoAdd=True,
- callbacks=[_callback])
- subdir = self.dirname.child('test')
- d = defer.Deferred()
- subdir.createDirectory()
- return d
-
-
- def test_simpleDeleteDirectory(self):
- """
- L{inotify.INotify} removes a directory from the watchlist when
- it's removed from the filesystem.
- """
- calls = []
- def _callback(wp, filename, mask):
- # We are notified before we actually process new
- # directories, so we need to defer this check.
- def _():
- try:
- self.assertTrue(self.inotify._isWatched(subdir))
- subdir.remove()
- except Exception:
- d.errback()
- def _eb():
- # second call, we have just removed the subdir
- try:
- self.assertTrue(not self.inotify._isWatched(subdir))
- d.callback(None)
- except Exception:
- d.errback()
-
- if not calls:
- # first call, it's the create subdir
- calls.append(filename)
- reactor.callLater(0, _)
-
- else:
- reactor.callLater(0, _eb)
-
- checkMask = inotify.IN_ISDIR | inotify.IN_CREATE
- self.inotify.watch(
- self.dirname, mask=checkMask, autoAdd=True,
- callbacks=[_callback])
- subdir = self.dirname.child('test')
- d = defer.Deferred()
- subdir.createDirectory()
- return d
-
-
- def test_ignoreDirectory(self):
- """
- L{inotify.INotify.ignore} removes a directory from the watchlist
- """
- self.inotify.watch(self.dirname, autoAdd=True)
- self.assertTrue(self.inotify._isWatched(self.dirname))
- self.inotify.ignore(self.dirname)
- self.assertFalse(self.inotify._isWatched(self.dirname))
-
-
- def test_humanReadableMask(self):
- """
- L{inotify.humaReadableMask} translates all the possible event
- masks to a human readable string.
- """
- for mask, value in inotify._FLAG_TO_HUMAN:
- self.assertEqual(inotify.humanReadableMask(mask)[0], value)
-
- checkMask = (
- inotify.IN_CLOSE_WRITE | inotify.IN_ACCESS | inotify.IN_OPEN)
- self.assertEqual(
- set(inotify.humanReadableMask(checkMask)),
- set(['close_write', 'access', 'open']))
-
-
- def test_recursiveWatch(self):
- """
- L{inotify.INotify.watch} with recursive==True will add all the
- subdirectories under the given path to the watchlist.
- """
- subdir = self.dirname.child('test')
- subdir2 = subdir.child('test2')
- subdir3 = subdir2.child('test3')
- subdir3.makedirs()
- dirs = [subdir, subdir2, subdir3]
- self.inotify.watch(self.dirname, recursive=True)
- # let's even call this twice so that we test that nothing breaks
- self.inotify.watch(self.dirname, recursive=True)
- for d in dirs:
- self.assertTrue(self.inotify._isWatched(d))
-
-
- def test_connectionLostError(self):
- """
- L{inotify.INotify.connectionLost} if there's a problem while closing
- the fd shouldn't raise the exception but should log the error
- """
- import os
- in_ = inotify.INotify()
- os.close(in_._fd)
- in_.loseConnection()
- self.flushLoggedErrors()
-
- def test_noAutoAddSubdirectory(self):
- """
- L{inotify.INotify.watch} with autoAdd==False will stop inotify
- from watching subdirectories created under the watched one.
- """
- def _callback(wp, fp, mask):
- # We are notified before we actually process new
- # directories, so we need to defer this check.
- def _():
- try:
- self.assertFalse(self.inotify._isWatched(subdir.path))
- d.callback(None)
- except Exception:
- d.errback()
- reactor.callLater(0, _)
-
- checkMask = inotify.IN_ISDIR | inotify.IN_CREATE
- self.inotify.watch(
- self.dirname, mask=checkMask, autoAdd=False,
- callbacks=[_callback])
- subdir = self.dirname.child('test')
- d = defer.Deferred()
- subdir.createDirectory()
- return d
-
-
- def test_seriesOfWatchAndIgnore(self):
- """
- L{inotify.INotify} will watch a filepath for events even if the same
- path is repeatedly added/removed/re-added to the watchpoints.
- """
- expectedPath = self.dirname.child("foo.bar2")
- expectedPath.touch()
-
- notified = defer.Deferred()
- def cbNotified((ignored, filename, events)):
- self.assertEqual(filename, expectedPath)
- self.assertTrue(events & inotify.IN_DELETE_SELF)
-
- def callIt(*args):
- notified.callback(args)
-
- # Watch, ignore, watch again to get into the state being tested.
- self.assertTrue(self.inotify.watch(expectedPath, callbacks=[callIt]))
- self.inotify.ignore(expectedPath)
- self.assertTrue(
- self.inotify.watch(
- expectedPath, mask=inotify.IN_DELETE_SELF, callbacks=[callIt]))
-
- notified.addCallback(cbNotified)
-
- # Apparently in kernel version < 2.6.25, inofify has a bug in the way
- # similar events are coalesced. So, be sure to generate a different
- # event here than the touch() at the top of this method might have
- # generated.
- expectedPath.remove()
-
- return notified
-
-
- def test_ignoreFilePath(self):
- """
- L{inotify.INotify} will ignore a filepath after it has been removed from
- the watch list.
- """
- expectedPath = self.dirname.child("foo.bar2")
- expectedPath.touch()
- expectedPath2 = self.dirname.child("foo.bar3")
- expectedPath2.touch()
-
- notified = defer.Deferred()
- def cbNotified((ignored, filename, events)):
- self.assertEqual(filename, expectedPath2)
- self.assertTrue(events & inotify.IN_DELETE_SELF)
-
- def callIt(*args):
- notified.callback(args)
-
- self.assertTrue(
- self.inotify.watch(
- expectedPath, inotify.IN_DELETE_SELF, callbacks=[callIt]))
- notified.addCallback(cbNotified)
-
- self.assertTrue(
- self.inotify.watch(
- expectedPath2, inotify.IN_DELETE_SELF, callbacks=[callIt]))
-
- self.inotify.ignore(expectedPath)
-
- expectedPath.remove()
- expectedPath2.remove()
-
- return notified
-
-
- def test_ignoreNonWatchedFile(self):
- """
- L{inotify.INotify} will raise KeyError if a non-watched filepath is
- ignored.
- """
- expectedPath = self.dirname.child("foo.ignored")
- expectedPath.touch()
-
- self.assertRaises(KeyError, self.inotify.ignore, expectedPath)
-
-
- def test_complexSubdirectoryAutoAdd(self):
- """
- L{inotify.INotify} with autoAdd==True for a watched path
- generates events for every file or directory already present
- in a newly created subdirectory under the watched one.
-
- This tests that we solve a race condition in inotify even though
- we may generate duplicate events.
- """
- calls = set()
- def _callback(wp, filename, mask):
- calls.add(filename)
- if len(calls) == 6:
- try:
- self.assertTrue(self.inotify._isWatched(subdir))
- self.assertTrue(self.inotify._isWatched(subdir2))
- self.assertTrue(self.inotify._isWatched(subdir3))
- created = someFiles + [subdir, subdir2, subdir3]
- self.assertEqual(len(calls), len(created))
- self.assertEqual(calls, set(created))
- except Exception:
- d.errback()
- else:
- d.callback(None)
-
- checkMask = inotify.IN_ISDIR | inotify.IN_CREATE
- self.inotify.watch(
- self.dirname, mask=checkMask, autoAdd=True,
- callbacks=[_callback])
- subdir = self.dirname.child('test')
- subdir2 = subdir.child('test2')
- subdir3 = subdir2.child('test3')
- d = defer.Deferred()
- subdir3.makedirs()
-
- someFiles = [subdir.child('file1.dat'),
- subdir2.child('file2.dat'),
- subdir3.child('file3.dat')]
- # Add some files in pretty much all the directories so that we
- # see that we process all of them.
- for i, filename in enumerate(someFiles):
- filename.setContent(filename.path)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_interfaces.py
deleted file mode 100755
index f9f60dab..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_interfaces.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.interfaces}.
-"""
-
-from twisted.trial import unittest
-
-
-class TestIFinishableConsumer(unittest.TestCase):
- """
- L{IFinishableConsumer} is deprecated.
- """
-
- def lookForDeprecationWarning(self, testmethod):
- """
- Importing C{testmethod} emits a deprecation warning.
- """
- warningsShown = self.flushWarnings([testmethod])
- self.assertEqual(len(warningsShown), 1)
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- warningsShown[0]['message'],
- "twisted.internet.interfaces.IFinishableConsumer "
- "was deprecated in Twisted 11.1.0: Please use IConsumer "
- "(and IConsumer.unregisterProducer) instead.")
-
-
- def test_deprecationWithDirectImport(self):
- """
- Importing L{IFinishableConsumer} causes a deprecation warning
- """
- from twisted.internet.interfaces import IFinishableConsumer
- self.lookForDeprecationWarning(
- TestIFinishableConsumer.test_deprecationWithDirectImport)
-
-
- def test_deprecationWithIndirectImport(self):
- """
- Importing L{interfaces} and implementing
- L{interfaces.IFinishableConsumer} causes a deprecation warning
- """
- from zope.interface import implements
- from twisted.internet import interfaces
-
- class FakeIFinishableConsumer:
- implements(interfaces.IFinishableConsumer)
- def finish(self):
- pass
-
- self.lookForDeprecationWarning(
- TestIFinishableConsumer.test_deprecationWithIndirectImport)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_iocp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_iocp.py
deleted file mode 100755
index 76d7646a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_iocp.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.iocpreactor}.
-"""
-
-import errno
-from array import array
-from struct import pack
-from socket import AF_INET6, AF_INET, SOCK_STREAM, SOL_SOCKET, error, socket
-
-from zope.interface.verify import verifyClass
-
-from twisted.trial import unittest
-from twisted.python.log import msg
-from twisted.internet.interfaces import IPushProducer
-
-try:
- from twisted.internet.iocpreactor import iocpsupport as _iocp, tcp, udp
- from twisted.internet.iocpreactor.reactor import IOCPReactor, EVENTS_PER_LOOP, KEY_NORMAL
- from twisted.internet.iocpreactor.interfaces import IReadWriteHandle
- from twisted.internet.iocpreactor.const import SO_UPDATE_ACCEPT_CONTEXT
- from twisted.internet.iocpreactor.abstract import FileHandle
-except ImportError:
- skip = 'This test only applies to IOCPReactor'
-
-try:
- socket(AF_INET6, SOCK_STREAM).close()
-except error, e:
- ipv6Skip = str(e)
-else:
- ipv6Skip = None
-
-class SupportTests(unittest.TestCase):
- """
- Tests for L{twisted.internet.iocpreactor.iocpsupport}, low-level reactor
- implementation helpers.
- """
- def _acceptAddressTest(self, family, localhost):
- """
- Create a C{SOCK_STREAM} connection to localhost using a socket with an
- address family of C{family} and assert that the result of
- L{iocpsupport.get_accept_addrs} is consistent with the result of
- C{socket.getsockname} and C{socket.getpeername}.
- """
- msg("family = %r" % (family,))
- port = socket(family, SOCK_STREAM)
- self.addCleanup(port.close)
- port.bind(('', 0))
- port.listen(1)
- client = socket(family, SOCK_STREAM)
- self.addCleanup(client.close)
- client.setblocking(False)
- try:
- client.connect((localhost, port.getsockname()[1]))
- except error, (errnum, message):
- self.assertIn(errnum, (errno.EINPROGRESS, errno.EWOULDBLOCK))
-
- server = socket(family, SOCK_STREAM)
- self.addCleanup(server.close)
- buff = array('c', '\0' * 256)
- self.assertEqual(
- 0, _iocp.accept(port.fileno(), server.fileno(), buff, None))
- server.setsockopt(
- SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, pack('P', server.fileno()))
- self.assertEqual(
- (family, client.getpeername()[:2], client.getsockname()[:2]),
- _iocp.get_accept_addrs(server.fileno(), buff))
-
-
- def test_ipv4AcceptAddress(self):
- """
- L{iocpsupport.get_accept_addrs} returns a three-tuple of address
- information about the socket associated with the file descriptor passed
- to it. For a connection using IPv4:
-
- - the first element is C{AF_INET}
- - the second element is a two-tuple of a dotted decimal notation IPv4
- address and a port number giving the peer address of the connection
- - the third element is the same type giving the host address of the
- connection
- """
- self._acceptAddressTest(AF_INET, '127.0.0.1')
-
-
- def test_ipv6AcceptAddress(self):
- """
- Like L{test_ipv4AcceptAddress}, but for IPv6 connections. In this case:
-
- - the first element is C{AF_INET6}
- - the second element is a two-tuple of a hexadecimal IPv6 address
- literal and a port number giving the peer address of the connection
- - the third element is the same type giving the host address of the
- connection
- """
- self._acceptAddressTest(AF_INET6, '::1')
- if ipv6Skip is not None:
- test_ipv6AcceptAddress.skip = ipv6Skip
-
-
-
-class IOCPReactorTestCase(unittest.TestCase):
- def test_noPendingTimerEvents(self):
- """
- Test reactor behavior (doIteration) when there are no pending time
- events.
- """
- ir = IOCPReactor()
- ir.wakeUp()
- self.failIf(ir.doIteration(None))
-
-
- def test_reactorInterfaces(self):
- """
- Verify that IOCP socket-representing classes implement IReadWriteHandle
- """
- self.assertTrue(verifyClass(IReadWriteHandle, tcp.Connection))
- self.assertTrue(verifyClass(IReadWriteHandle, udp.Port))
-
-
- def test_fileHandleInterfaces(self):
- """
- Verify that L{Filehandle} implements L{IPushProducer}.
- """
- self.assertTrue(verifyClass(IPushProducer, FileHandle))
-
-
- def test_maxEventsPerIteration(self):
- """
- Verify that we don't lose an event when more than EVENTS_PER_LOOP
- events occur in the same reactor iteration
- """
- class FakeFD:
- counter = 0
- def logPrefix(self):
- return 'FakeFD'
- def cb(self, rc, bytes, evt):
- self.counter += 1
-
- ir = IOCPReactor()
- fd = FakeFD()
- event = _iocp.Event(fd.cb, fd)
- for _ in range(EVENTS_PER_LOOP + 1):
- ir.port.postEvent(0, KEY_NORMAL, event)
- ir.doIteration(None)
- self.assertEqual(fd.counter, EVENTS_PER_LOOP)
- ir.doIteration(0)
- self.assertEqual(fd.counter, EVENTS_PER_LOOP + 1)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_main.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_main.py
deleted file mode 100755
index 12c8a3f2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_main.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.main}.
-"""
-
-from twisted.trial import unittest
-from twisted.internet.error import ReactorAlreadyInstalledError
-from twisted.internet.main import installReactor
-
-
-class InstallReactorTests(unittest.TestCase):
- """
- Tests for L{installReactor}
- """
-
- def test_alreadyInstalled(self):
- """
- If a reactor is already installed, L{installReactor} raises
- L{ReactorAlreadyInstalledError}.
- """
- # Because this test runs in trial, assume a reactor is already
- # installed.
- self.assertRaises(ReactorAlreadyInstalledError, installReactor,
- object())
-
-
- def test_errorIsAnAssertionError(self):
- """
- For backwards compatibility, L{ReactorAlreadyInstalledError} is an
- L{AssertionError}.
- """
- self.assertTrue(issubclass(ReactorAlreadyInstalledError,
- AssertionError))
-
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_newtls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_newtls.py
deleted file mode 100755
index a196cb51..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_newtls.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet._newtls}.
-"""
-
-from twisted.trial import unittest
-from twisted.internet.test.reactormixins import ReactorBuilder, runProtocolsWithReactor
-from twisted.internet.test.reactormixins import ConnectableProtocol
-from twisted.internet.test.test_tls import SSLCreator, TLSMixin
-from twisted.internet.test.test_tls import StartTLSClientCreator
-from twisted.internet.test.test_tls import ContextGeneratingMixin
-from twisted.internet.test.test_tcp import TCPCreator
-try:
- from twisted.protocols import tls
- from twisted.internet import _newtls
-except ImportError:
- _newtls = None
-
-
-class BypassTLSTests(unittest.TestCase):
- """
- Tests for the L{_newtls._BypassTLS} class.
- """
-
- if not _newtls:
- skip = "Couldn't import _newtls, perhaps pyOpenSSL is old or missing"
-
- def test_loseConnectionPassThrough(self):
- """
- C{_BypassTLS.loseConnection} calls C{loseConnection} on the base
- class, while preserving any default argument in the base class'
- C{loseConnection} implementation.
- """
- default = object()
- result = []
-
- class FakeTransport(object):
- def loseConnection(self, _connDone=default):
- result.append(_connDone)
-
- bypass = _newtls._BypassTLS(FakeTransport, FakeTransport())
-
- # The default from FakeTransport is used:
- bypass.loseConnection()
- self.assertEqual(result, [default])
-
- # And we can pass our own:
- notDefault = object()
- bypass.loseConnection(notDefault)
- self.assertEqual(result, [default, notDefault])
-
-
-
-class FakeProducer(object):
- """
- A producer that does nothing.
- """
-
- def pauseProducing(self):
- pass
-
-
- def resumeProducing(self):
- pass
-
-
- def stopProducing(self):
- pass
-
-
-
-class ProducerProtocol(ConnectableProtocol):
- """
- Register a producer, unregister it, and verify the producer hooks up to
- innards of C{TLSMemoryBIOProtocol}.
- """
-
- def __init__(self, producer, result):
- self.producer = producer
- self.result = result
-
-
- def connectionMade(self):
- if not isinstance(self.transport.protocol,
- tls.TLSMemoryBIOProtocol):
- # Either the test or the code have a bug...
- raise RuntimeError("TLSMemoryBIOProtocol not hooked up.")
-
- self.transport.registerProducer(self.producer, True)
- # The producer was registered with the TLSMemoryBIOProtocol:
- self.result.append(self.transport.protocol._producer._producer)
-
- self.transport.unregisterProducer()
- # The producer was unregistered from the TLSMemoryBIOProtocol:
- self.result.append(self.transport.protocol._producer)
- self.transport.loseConnection()
-
-
-
-class ProducerTestsMixin(ReactorBuilder, TLSMixin, ContextGeneratingMixin):
- """
- Test the new TLS code integrates C{TLSMemoryBIOProtocol} correctly.
- """
-
- if not _newtls:
- skip = "Could not import twisted.internet._newtls"
-
- def test_producerSSLFromStart(self):
- """
- C{registerProducer} and C{unregisterProducer} on TLS transports
- created as SSL from the get go are passed to the
- C{TLSMemoryBIOProtocol}, not the underlying transport directly.
- """
- result = []
- producer = FakeProducer()
-
- runProtocolsWithReactor(self, ConnectableProtocol(),
- ProducerProtocol(producer, result),
- SSLCreator())
- self.assertEqual(result, [producer, None])
-
-
- def test_producerAfterStartTLS(self):
- """
- C{registerProducer} and C{unregisterProducer} on TLS transports
- created by C{startTLS} are passed to the C{TLSMemoryBIOProtocol}, not
- the underlying transport directly.
- """
- result = []
- producer = FakeProducer()
-
- runProtocolsWithReactor(self, ConnectableProtocol(),
- ProducerProtocol(producer, result),
- StartTLSClientCreator())
- self.assertEqual(result, [producer, None])
-
-
- def startTLSAfterRegisterProducer(self, streaming):
- """
- When a producer is registered, and then startTLS is called,
- the producer is re-registered with the C{TLSMemoryBIOProtocol}.
- """
- clientContext = self.getClientContext()
- serverContext = self.getServerContext()
- result = []
- producer = FakeProducer()
-
- class RegisterTLSProtocol(ConnectableProtocol):
- def connectionMade(self):
- self.transport.registerProducer(producer, streaming)
- self.transport.startTLS(serverContext)
- # Store TLSMemoryBIOProtocol and underlying transport producer
- # status:
- if streaming:
- # _ProducerMembrane -> producer:
- result.append(self.transport.protocol._producer._producer)
- result.append(self.transport.producer._producer)
- else:
- # _ProducerMembrane -> _PullToPush -> producer:
- result.append(
- self.transport.protocol._producer._producer._producer)
- result.append(self.transport.producer._producer._producer)
- self.transport.unregisterProducer()
- self.transport.loseConnection()
-
- class StartTLSProtocol(ConnectableProtocol):
- def connectionMade(self):
- self.transport.startTLS(clientContext)
-
- runProtocolsWithReactor(self, RegisterTLSProtocol(),
- StartTLSProtocol(), TCPCreator())
- self.assertEqual(result, [producer, producer])
-
-
- def test_startTLSAfterRegisterProducerStreaming(self):
- """
- When a streaming producer is registered, and then startTLS is called,
- the producer is re-registered with the C{TLSMemoryBIOProtocol}.
- """
- self.startTLSAfterRegisterProducer(True)
-
-
- def test_startTLSAfterRegisterProducerNonStreaming(self):
- """
- When a non-streaming producer is registered, and then startTLS is
- called, the producer is re-registered with the
- C{TLSMemoryBIOProtocol}.
- """
- self.startTLSAfterRegisterProducer(False)
-
-
-globals().update(ProducerTestsMixin.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_pollingfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_pollingfile.py
deleted file mode 100755
index 75022adf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_pollingfile.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet._pollingfile}.
-"""
-
-from twisted.python.runtime import platform
-from twisted.trial.unittest import TestCase
-
-if platform.isWindows():
- from twisted.internet import _pollingfile
-else:
- _pollingfile = None
-
-
-
-class TestPollableWritePipe(TestCase):
- """
- Tests for L{_pollingfile._PollableWritePipe}.
- """
-
- def test_writeUnicode(self):
- """
- L{_pollingfile._PollableWritePipe.write} raises a C{TypeError} if an
- attempt is made to append unicode data to the output buffer.
- """
- p = _pollingfile._PollableWritePipe(1, lambda: None)
- self.assertRaises(TypeError, p.write, u"test")
-
-
- def test_writeSequenceUnicode(self):
- """
- L{_pollingfile._PollableWritePipe.writeSequence} raises a C{TypeError}
- if unicode data is part of the data sequence to be appended to the
- output buffer.
- """
- p = _pollingfile._PollableWritePipe(1, lambda: None)
- self.assertRaises(TypeError, p.writeSequence, [u"test"])
- self.assertRaises(TypeError, p.writeSequence, (u"test", ))
-
-
-
-
-if _pollingfile is None:
- TestPollableWritePipe.skip = "Test will run only on Windows."
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixbase.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixbase.py
deleted file mode 100755
index 2e0c2ec4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixbase.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.posixbase} and supporting code.
-"""
-
-from twisted.python.compat import set
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import Deferred
-from twisted.internet.posixbase import PosixReactorBase, _Waker
-from twisted.internet.protocol import ServerFactory
-
-
-skipSockets = None
-try:
- from twisted.internet import unix
-except ImportError:
- skipSockets = "Platform does not support AF_UNIX sockets"
-
-from twisted.internet.tcp import Port
-from twisted.internet import reactor
-from twisted.test.test_unix import ClientProto
-
-class TrivialReactor(PosixReactorBase):
- def __init__(self):
- self._readers = {}
- self._writers = {}
- PosixReactorBase.__init__(self)
-
-
- def addReader(self, reader):
- self._readers[reader] = True
-
-
- def removeReader(self, reader):
- del self._readers[reader]
-
-
- def addWriter(self, writer):
- self._writers[writer] = True
-
-
- def removeWriter(self, writer):
- del self._writers[writer]
-
-
-
-class PosixReactorBaseTests(TestCase):
- """
- Tests for L{PosixReactorBase}.
- """
-
- def _checkWaker(self, reactor):
- self.assertIsInstance(reactor.waker, _Waker)
- self.assertIn(reactor.waker, reactor._internalReaders)
- self.assertIn(reactor.waker, reactor._readers)
-
-
- def test_wakerIsInternalReader(self):
- """
- When L{PosixReactorBase} is instantiated, it creates a waker and adds
- it to its internal readers set.
- """
- reactor = TrivialReactor()
- self._checkWaker(reactor)
-
-
- def test_removeAllSkipsInternalReaders(self):
- """
- Any L{IReadDescriptors} in L{PosixReactorBase._internalReaders} are
- left alone by L{PosixReactorBase._removeAll}.
- """
- reactor = TrivialReactor()
- extra = object()
- reactor._internalReaders.add(extra)
- reactor.addReader(extra)
- reactor._removeAll(reactor._readers, reactor._writers)
- self._checkWaker(reactor)
- self.assertIn(extra, reactor._internalReaders)
- self.assertIn(extra, reactor._readers)
-
-
- def test_removeAllReturnsRemovedDescriptors(self):
- """
- L{PosixReactorBase._removeAll} returns a list of removed
- L{IReadDescriptor} and L{IWriteDescriptor} objects.
- """
- reactor = TrivialReactor()
- reader = object()
- writer = object()
- reactor.addReader(reader)
- reactor.addWriter(writer)
- removed = reactor._removeAll(
- reactor._readers, reactor._writers)
- self.assertEqual(set(removed), set([reader, writer]))
- self.assertNotIn(reader, reactor._readers)
- self.assertNotIn(writer, reactor._writers)
-
-
- def test_IReactorArbitraryIsDeprecated(self):
- """
- L{twisted.internet.interfaces.IReactorArbitrary} is redundant with
- L{twisted.internet.interfaces.IReactorFDSet} and is deprecated.
- """
- from twisted.internet import interfaces
- interfaces.IReactorArbitrary
-
- warningsShown = self.flushWarnings(
- [self.test_IReactorArbitraryIsDeprecated])
- self.assertEqual(len(warningsShown), 1)
- self.assertEqual(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- "twisted.internet.interfaces.IReactorArbitrary was deprecated "
- "in Twisted 10.1.0: See IReactorFDSet.",
- warningsShown[0]['message'])
-
-
- def test_listenWithIsDeprecated(self):
- """
- L{PosixReactorBase} implements the deprecated L{IReactorArbitrary}, and
- L{PosixReactorBase.listenWith} is a part of that interface. To avoid
- unnecessary deprecation warnings when importing posixbase, the
- L{twisted.internet.interfaces._IReactorArbitrary} alias that doesn't
- have the deprecation warning is imported, and instead
- L{PosixReactorBase.listenWith} generates its own deprecation warning.
- """
- class fakePort:
- def __init__(self, *args, **kw):
- pass
-
- def startListening(self):
- pass
-
- reactor = TrivialReactor()
- reactor.listenWith(fakePort)
-
- warnings = self.flushWarnings([self.test_listenWithIsDeprecated])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- "listenWith is deprecated since Twisted 10.1. "
- "See IReactorFDSet.",
- warnings[0]['message'])
-
-
- def test_connectWithIsDeprecated(self):
- """
- L{PosixReactorBase} implements the deprecated L{IReactorArbitrary}, and
- L{PosixReactorBase.connectWith} is a part of that interface. To avoid
- unnecessary deprecation warnings when importing posixbase, the
- L{twisted.internet.interfaces._IReactorArbitrary} alias that doesn't
- have the deprecation warning is imported, and instead
- L{PosixReactorBase.connectWith} generates its own deprecation warning.
- """
- class fakeConnector:
- def __init__(self, *args, **kw):
- pass
-
- def connect(self):
- pass
-
- reactor = TrivialReactor()
- reactor.connectWith(fakeConnector)
-
- warnings = self.flushWarnings([self.test_connectWithIsDeprecated])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- "connectWith is deprecated since Twisted 10.1. "
- "See IReactorFDSet.",
- warnings[0]['message'])
-
-
-
-class TCPPortTests(TestCase):
- """
- Tests for L{twisted.internet.tcp.Port}.
- """
-
- if not isinstance(reactor, PosixReactorBase):
- skip = "Non-posixbase reactor"
-
- def test_connectionLostFailed(self):
- """
- L{Port.stopListening} returns a L{Deferred} which errbacks if
- L{Port.connectionLost} raises an exception.
- """
- port = Port(12345, ServerFactory())
- port.connected = True
- port.connectionLost = lambda reason: 1 // 0
- return self.assertFailure(port.stopListening(), ZeroDivisionError)
-
-
-
-class TimeoutReportReactor(PosixReactorBase):
- """
- A reactor which is just barely runnable and which cannot monitor any
- readers or writers, and which fires a L{Deferred} with the timeout
- passed to its C{doIteration} method as soon as that method is invoked.
- """
- def __init__(self):
- PosixReactorBase.__init__(self)
- self.iterationTimeout = Deferred()
- self.now = 100
-
-
- def addReader(self, reader):
- """
- Ignore the reader. This is necessary because the waker will be
- added. However, we won't actually monitor it for any events.
- """
-
-
- def removeAll(self):
- """
- There are no readers or writers, so there is nothing to remove.
- This will be called when the reactor stops, though, so it must be
- implemented.
- """
- return []
-
-
- def seconds(self):
- """
- Override the real clock with a deterministic one that can be easily
- controlled in a unit test.
- """
- return self.now
-
-
- def doIteration(self, timeout):
- d = self.iterationTimeout
- if d is not None:
- self.iterationTimeout = None
- d.callback(timeout)
-
-
-
-class IterationTimeoutTests(TestCase):
- """
- Tests for the timeout argument L{PosixReactorBase.run} calls
- L{PosixReactorBase.doIteration} with in the presence of various delayed
- calls.
- """
- def _checkIterationTimeout(self, reactor):
- timeout = []
- reactor.iterationTimeout.addCallback(timeout.append)
- reactor.iterationTimeout.addCallback(lambda ignored: reactor.stop())
- reactor.run()
- return timeout[0]
-
-
- def test_noCalls(self):
- """
- If there are no delayed calls, C{doIteration} is called with a
- timeout of C{None}.
- """
- reactor = TimeoutReportReactor()
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, None)
-
-
- def test_delayedCall(self):
- """
- If there is a delayed call, C{doIteration} is called with a timeout
- which is the difference between the current time and the time at
- which that call is to run.
- """
- reactor = TimeoutReportReactor()
- reactor.callLater(100, lambda: None)
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, 100)
-
-
- def test_timePasses(self):
- """
- If a delayed call is scheduled and then some time passes, the
- timeout passed to C{doIteration} is reduced by the amount of time
- which passed.
- """
- reactor = TimeoutReportReactor()
- reactor.callLater(100, lambda: None)
- reactor.now += 25
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, 75)
-
-
- def test_multipleDelayedCalls(self):
- """
- If there are several delayed calls, C{doIteration} is called with a
- timeout which is the difference between the current time and the
- time at which the earlier of the two calls is to run.
- """
- reactor = TimeoutReportReactor()
- reactor.callLater(50, lambda: None)
- reactor.callLater(10, lambda: None)
- reactor.callLater(100, lambda: None)
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, 10)
-
-
- def test_resetDelayedCall(self):
- """
- If a delayed call is reset, the timeout passed to C{doIteration} is
- based on the interval between the time when reset is called and the
- new delay of the call.
- """
- reactor = TimeoutReportReactor()
- call = reactor.callLater(50, lambda: None)
- reactor.now += 25
- call.reset(15)
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, 15)
-
-
- def test_delayDelayedCall(self):
- """
- If a delayed call is re-delayed, the timeout passed to
- C{doIteration} is based on the remaining time before the call would
- have been made and the additional amount of time passed to the delay
- method.
- """
- reactor = TimeoutReportReactor()
- call = reactor.callLater(50, lambda: None)
- reactor.now += 10
- call.delay(20)
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, 60)
-
-
- def test_cancelDelayedCall(self):
- """
- If the only delayed call is canceled, C{None} is the timeout passed
- to C{doIteration}.
- """
- reactor = TimeoutReportReactor()
- call = reactor.callLater(50, lambda: None)
- call.cancel()
- timeout = self._checkIterationTimeout(reactor)
- self.assertEqual(timeout, None)
-
-
-
-class ConnectedDatagramPortTestCase(TestCase):
- """
- Test connected datagram UNIX sockets.
- """
- if skipSockets is not None:
- skip = skipSockets
-
-
- def test_connectionFailedDoesntCallLoseConnection(self):
- """
- L{ConnectedDatagramPort} does not call the deprecated C{loseConnection}
- in L{ConnectedDatagramPort.connectionFailed}.
- """
- def loseConnection():
- """
- Dummy C{loseConnection} method. C{loseConnection} is deprecated and
- should not get called.
- """
- self.fail("loseConnection is deprecated and should not get called.")
-
- port = unix.ConnectedDatagramPort(None, ClientProto())
- port.loseConnection = loseConnection
- port.connectionFailed("goodbye")
-
-
- def test_connectionFailedCallsStopListening(self):
- """
- L{ConnectedDatagramPort} calls L{ConnectedDatagramPort.stopListening}
- instead of the deprecated C{loseConnection} in
- L{ConnectedDatagramPort.connectionFailed}.
- """
- self.called = False
-
- def stopListening():
- """
- Dummy C{stopListening} method.
- """
- self.called = True
-
- port = unix.ConnectedDatagramPort(None, ClientProto())
- port.stopListening = stopListening
- port.connectionFailed("goodbye")
- self.assertEqual(self.called, True)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixprocess.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixprocess.py
deleted file mode 100755
index f7abd55b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_posixprocess.py
+++ /dev/null
@@ -1,340 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for POSIX-based L{IReactorProcess} implementations.
-"""
-
-import errno, os, sys
-
-try:
- import fcntl
-except ImportError:
- platformSkip = "non-POSIX platform"
-else:
- from twisted.internet import process
- platformSkip = None
-
-from twisted.trial.unittest import TestCase
-
-
-class FakeFile(object):
- """
- A dummy file object which records when it is closed.
- """
- def __init__(self, testcase, fd):
- self.testcase = testcase
- self.fd = fd
-
-
- def close(self):
- self.testcase._files.remove(self.fd)
-
-
-
-class FakeResourceModule(object):
- """
- Fake version of L{resource} which hard-codes a particular rlimit for maximum
- open files.
-
- @ivar _limit: The value to return for the hard limit of number of open files.
- """
- RLIMIT_NOFILE = 1
-
- def __init__(self, limit):
- self._limit = limit
-
-
- def getrlimit(self, no):
- """
- A fake of L{resource.getrlimit} which returns a pre-determined result.
- """
- if no == self.RLIMIT_NOFILE:
- return [0, self._limit]
- return [123, 456]
-
-
-
-class FDDetectorTests(TestCase):
- """
- Tests for _FDDetector class in twisted.internet.process, which detects
- which function to drop in place for the _listOpenFDs method.
-
- @ivar devfs: A flag indicating whether the filesystem fake will indicate
- that /dev/fd exists.
-
- @ivar accurateDevFDResults: A flag indicating whether the /dev/fd fake
- returns accurate open file information.
-
- @ivar procfs: A flag indicating whether the filesystem fake will indicate
- that /proc/<pid>/fd exists.
- """
- skip = platformSkip
-
- devfs = False
- accurateDevFDResults = False
-
- procfs = False
-
- def getpid(self):
- """
- Fake os.getpid, always return the same thing
- """
- return 123
-
-
- def listdir(self, arg):
- """
- Fake os.listdir, depending on what mode we're in to simulate behaviour.
-
- @param arg: the directory to list
- """
- accurate = map(str, self._files)
- if self.procfs and arg == ('/proc/%d/fd' % (self.getpid(),)):
- return accurate
- if self.devfs and arg == '/dev/fd':
- if self.accurateDevFDResults:
- return accurate
- return ["0", "1", "2"]
- raise OSError()
-
-
- def openfile(self, fname, mode):
- """
- This is a mock for L{open}. It keeps track of opened files so extra
- descriptors can be returned from the mock for L{os.listdir} when used on
- one of the list-of-filedescriptors directories.
-
- A L{FakeFile} is returned which can be closed to remove the new
- descriptor from the open list.
- """
- # Find the smallest unused file descriptor and give it to the new file.
- f = FakeFile(self, min(set(range(1024)) - set(self._files)))
- self._files.append(f.fd)
- return f
-
-
- def hideResourceModule(self):
- """
- Make the L{resource} module unimportable for the remainder of the
- current test method.
- """
- sys.modules['resource'] = None
-
-
- def revealResourceModule(self, limit):
- """
- Make a L{FakeResourceModule} instance importable at the L{resource}
- name.
-
- @param limit: The value which will be returned for the hard limit of
- number of open files by the fake resource module's C{getrlimit}
- function.
- """
- sys.modules['resource'] = FakeResourceModule(limit)
-
-
- def replaceResourceModule(self, value):
- """
- Restore the original resource module to L{sys.modules}.
- """
- if value is None:
- try:
- del sys.modules['resource']
- except KeyError:
- pass
- else:
- sys.modules['resource'] = value
-
-
- def setUp(self):
- """
- Set up the tests, giving ourselves a detector object to play with and
- setting up its testable knobs to refer to our mocked versions.
- """
- self.detector = process._FDDetector()
- self.detector.listdir = self.listdir
- self.detector.getpid = self.getpid
- self.detector.openfile = self.openfile
- self._files = [0, 1, 2]
- self.addCleanup(
- self.replaceResourceModule, sys.modules.get('resource'))
-
-
- def test_selectFirstWorking(self):
- """
- L{FDDetector._getImplementation} returns the first method from its
- C{_implementations} list which returns results which reflect a newly
- opened file descriptor.
- """
- def failWithException():
- raise ValueError("This does not work")
-
- def failWithWrongResults():
- return [0, 1, 2]
-
- def correct():
- return self._files[:]
-
- self.detector._implementations = [
- failWithException, failWithWrongResults, correct]
-
- self.assertIdentical(correct, self.detector._getImplementation())
-
-
- def test_selectLast(self):
- """
- L{FDDetector._getImplementation} returns the last method from its
- C{_implementations} list if none of the implementations manage to return
- results which reflect a newly opened file descriptor.
- """
- def failWithWrongResults():
- return [3, 5, 9]
-
- def failWithOtherWrongResults():
- return [0, 1, 2]
-
- self.detector._implementations = [
- failWithWrongResults, failWithOtherWrongResults]
-
- self.assertIdentical(
- failWithOtherWrongResults, self.detector._getImplementation())
-
-
- def test_identityOfListOpenFDsChanges(self):
- """
- Check that the identity of _listOpenFDs changes after running
- _listOpenFDs the first time, but not after the second time it's run.
-
- In other words, check that the monkey patching actually works.
- """
- # Create a new instance
- detector = process._FDDetector()
-
- first = detector._listOpenFDs.func_name
- detector._listOpenFDs()
- second = detector._listOpenFDs.func_name
- detector._listOpenFDs()
- third = detector._listOpenFDs.func_name
-
- self.assertNotEqual(first, second)
- self.assertEqual(second, third)
-
-
- def test_devFDImplementation(self):
- """
- L{_FDDetector._devFDImplementation} raises L{OSError} if there is no
- I{/dev/fd} directory, otherwise it returns the basenames of its children
- interpreted as integers.
- """
- self.devfs = False
- self.assertRaises(OSError, self.detector._devFDImplementation)
- self.devfs = True
- self.accurateDevFDResults = False
- self.assertEqual([0, 1, 2], self.detector._devFDImplementation())
-
-
- def test_procFDImplementation(self):
- """
- L{_FDDetector._procFDImplementation} raises L{OSError} if there is no
- I{/proc/<pid>/fd} directory, otherwise it returns the basenames of its
- children interpreted as integers.
- """
- self.procfs = False
- self.assertRaises(OSError, self.detector._procFDImplementation)
- self.procfs = True
- self.assertEqual([0, 1, 2], self.detector._procFDImplementation())
-
-
- def test_resourceFDImplementation(self):
- """
- L{_FDDetector._fallbackFDImplementation} uses the L{resource} module if
- it is available, returning a range of integers from 0 to the the
- minimum of C{1024} and the hard I{NOFILE} limit.
- """
- # When the resource module is here, use its value.
- self.revealResourceModule(512)
- self.assertEqual(
- range(512), self.detector._fallbackFDImplementation())
-
- # But limit its value to the arbitrarily selected value 1024.
- self.revealResourceModule(2048)
- self.assertEqual(
- range(1024), self.detector._fallbackFDImplementation())
-
-
- def test_fallbackFDImplementation(self):
- """
- L{_FDDetector._fallbackFDImplementation}, the implementation of last
- resort, succeeds with a fixed range of integers from 0 to 1024 when the
- L{resource} module is not importable.
- """
- self.hideResourceModule()
- self.assertEqual(range(1024), self.detector._fallbackFDImplementation())
-
-
-
-class FileDescriptorTests(TestCase):
- """
- Tests for L{twisted.internet.process._listOpenFDs}
- """
- skip = platformSkip
-
- def test_openFDs(self):
- """
- File descriptors returned by L{_listOpenFDs} are mostly open.
-
- This test assumes that zero-legth writes fail with EBADF on closed
- file descriptors.
- """
- for fd in process._listOpenFDs():
- try:
- fcntl.fcntl(fd, fcntl.F_GETFL)
- except IOError, err:
- self.assertEqual(
- errno.EBADF, err.errno,
- "fcntl(%d, F_GETFL) failed with unexpected errno %d" % (
- fd, err.errno))
-
-
- def test_expectedFDs(self):
- """
- L{_listOpenFDs} lists expected file descriptors.
- """
- # This is a tricky test. A priori, there is no way to know what file
- # descriptors are open now, so there is no way to know what _listOpenFDs
- # should return. Work around this by creating some new file descriptors
- # which we can know the state of and then just making assertions about
- # their presence or absence in the result.
-
- # Expect a file we just opened to be listed.
- f = file(os.devnull)
- openfds = process._listOpenFDs()
- self.assertIn(f.fileno(), openfds)
-
- # Expect a file we just closed not to be listed - with a caveat. The
- # implementation may need to open a file to discover the result. That
- # open file descriptor will be allocated the same number as the one we
- # just closed. So, instead, create a hole in the file descriptor space
- # to catch that internal descriptor and make the assertion about a
- # different closed file descriptor.
-
- # This gets allocated a file descriptor larger than f's, since nothing
- # has been closed since we opened f.
- fd = os.dup(f.fileno())
-
- # But sanity check that; if it fails the test is invalid.
- self.assertTrue(
- fd > f.fileno(),
- "Expected duplicate file descriptor to be greater than original")
-
- try:
- # Get rid of the original, creating the hole. The copy should still
- # be open, of course.
- f.close()
- self.assertIn(fd, process._listOpenFDs())
- finally:
- # Get rid of the copy now
- os.close(fd)
- # And it should not appear in the result.
- self.assertNotIn(fd, process._listOpenFDs())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_process.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_process.py
deleted file mode 100755
index c56c225a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_process.py
+++ /dev/null
@@ -1,711 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorProcess}.
-"""
-
-__metaclass__ = type
-
-import os, sys, signal, threading
-
-from twisted.trial.unittest import TestCase, SkipTest
-from twisted.internet.test.reactormixins import ReactorBuilder
-from twisted.python.compat import set
-from twisted.python.log import msg, err
-from twisted.python.runtime import platform
-from twisted.python.filepath import FilePath
-from twisted.internet import utils
-from twisted.internet.interfaces import IReactorProcess, IProcessTransport
-from twisted.internet.defer import Deferred, succeed
-from twisted.internet.protocol import ProcessProtocol
-from twisted.internet.error import ProcessDone, ProcessTerminated
-from twisted.internet import _signals
-
-
-
-class _ShutdownCallbackProcessProtocol(ProcessProtocol):
- """
- An L{IProcessProtocol} which fires a Deferred when the process it is
- associated with ends.
-
- @ivar received: A C{dict} mapping file descriptors to lists of bytes
- received from the child process on those file descriptors.
- """
- def __init__(self, whenFinished):
- self.whenFinished = whenFinished
- self.received = {}
-
-
- def childDataReceived(self, fd, bytes):
- self.received.setdefault(fd, []).append(bytes)
-
-
- def processEnded(self, reason):
- self.whenFinished.callback(None)
-
-
-
-class ProcessTestsBuilderBase(ReactorBuilder):
- """
- Base class for L{IReactorProcess} tests which defines some tests which
- can be applied to PTY or non-PTY uses of C{spawnProcess}.
-
- Subclasses are expected to set the C{usePTY} attribute to C{True} or
- C{False}.
- """
- requiredInterfaces = [IReactorProcess]
-
-
- def test_processTransportInterface(self):
- """
- L{IReactorProcess.spawnProcess} connects the protocol passed to it
- to a transport which provides L{IProcessTransport}.
- """
- ended = Deferred()
- protocol = _ShutdownCallbackProcessProtocol(ended)
-
- reactor = self.buildReactor()
- transport = reactor.spawnProcess(
- protocol, sys.executable, [sys.executable, "-c", ""],
- usePTY=self.usePTY)
-
- # The transport is available synchronously, so we can check it right
- # away (unlike many transport-based tests). This is convenient even
- # though it's probably not how the spawnProcess interface should really
- # work.
- # We're not using verifyObject here because part of
- # IProcessTransport is a lie - there are no getHost or getPeer
- # methods. See #1124.
- self.assertTrue(IProcessTransport.providedBy(transport))
-
- # Let the process run and exit so we don't leave a zombie around.
- ended.addCallback(lambda ignored: reactor.stop())
- self.runReactor(reactor)
-
-
- def _writeTest(self, write):
- """
- Helper for testing L{IProcessTransport} write functionality. This
- method spawns a child process and gives C{write} a chance to write some
- bytes to it. It then verifies that the bytes were actually written to
- it (by relying on the child process to echo them back).
-
- @param write: A two-argument callable. This is invoked with a process
- transport and some bytes to write to it.
- """
- reactor = self.buildReactor()
-
- ended = Deferred()
- protocol = _ShutdownCallbackProcessProtocol(ended)
-
- bytes = "hello, world" + os.linesep
- program = (
- "import sys\n"
- "sys.stdout.write(sys.stdin.readline())\n"
- )
-
- def startup():
- transport = reactor.spawnProcess(
- protocol, sys.executable, [sys.executable, "-c", program])
- try:
- write(transport, bytes)
- except:
- err(None, "Unhandled exception while writing")
- transport.signalProcess('KILL')
- reactor.callWhenRunning(startup)
-
- ended.addCallback(lambda ignored: reactor.stop())
-
- self.runReactor(reactor)
- self.assertEqual(bytes, "".join(protocol.received[1]))
-
-
- def test_write(self):
- """
- L{IProcessTransport.write} writes the specified C{str} to the standard
- input of the child process.
- """
- def write(transport, bytes):
- transport.write(bytes)
- self._writeTest(write)
-
-
- def test_writeSequence(self):
- """
- L{IProcessTransport.writeSequence} writes the specified C{list} of
- C{str} to the standard input of the child process.
- """
- def write(transport, bytes):
- transport.writeSequence(list(bytes))
- self._writeTest(write)
-
-
- def test_writeToChild(self):
- """
- L{IProcessTransport.writeToChild} writes the specified C{str} to the
- specified file descriptor of the child process.
- """
- def write(transport, bytes):
- transport.writeToChild(0, bytes)
- self._writeTest(write)
-
-
- def test_writeToChildBadFileDescriptor(self):
- """
- L{IProcessTransport.writeToChild} raises L{KeyError} if passed a file
- descriptor which is was not set up by L{IReactorProcess.spawnProcess}.
- """
- def write(transport, bytes):
- try:
- self.assertRaises(KeyError, transport.writeToChild, 13, bytes)
- finally:
- # Just get the process to exit so the test can complete
- transport.write(bytes)
- self._writeTest(write)
-
-
- def test_spawnProcessEarlyIsReaped(self):
- """
- If, before the reactor is started with L{IReactorCore.run}, a
- process is started with L{IReactorProcess.spawnProcess} and
- terminates, the process is reaped once the reactor is started.
- """
- reactor = self.buildReactor()
-
- # Create the process with no shared file descriptors, so that there
- # are no other events for the reactor to notice and "cheat" with.
- # We want to be sure it's really dealing with the process exiting,
- # not some associated event.
- if self.usePTY:
- childFDs = None
- else:
- childFDs = {}
-
- # Arrange to notice the SIGCHLD.
- signaled = threading.Event()
- def handler(*args):
- signaled.set()
- signal.signal(signal.SIGCHLD, handler)
-
- # Start a process - before starting the reactor!
- ended = Deferred()
- reactor.spawnProcess(
- _ShutdownCallbackProcessProtocol(ended), sys.executable,
- [sys.executable, "-c", ""], usePTY=self.usePTY, childFDs=childFDs)
-
- # Wait for the SIGCHLD (which might have been delivered before we got
- # here, but that's okay because the signal handler was installed above,
- # before we could have gotten it).
- signaled.wait(120)
- if not signaled.isSet():
- self.fail("Timed out waiting for child process to exit.")
-
- # Capture the processEnded callback.
- result = []
- ended.addCallback(result.append)
-
- if result:
- # The synchronous path through spawnProcess / Process.__init__ /
- # registerReapProcessHandler was encountered. There's no reason to
- # start the reactor, because everything is done already.
- return
-
- # Otherwise, though, start the reactor so it can tell us the process
- # exited.
- ended.addCallback(lambda ignored: reactor.stop())
- self.runReactor(reactor)
-
- # Make sure the reactor stopped because the Deferred fired.
- self.assertTrue(result)
-
- if getattr(signal, 'SIGCHLD', None) is None:
- test_spawnProcessEarlyIsReaped.skip = (
- "Platform lacks SIGCHLD, early-spawnProcess test can't work.")
-
-
- def test_processExitedWithSignal(self):
- """
- The C{reason} argument passed to L{IProcessProtocol.processExited} is a
- L{ProcessTerminated} instance if the child process exits with a signal.
- """
- sigName = 'TERM'
- sigNum = getattr(signal, 'SIG' + sigName)
- exited = Deferred()
- source = (
- "import sys\n"
- # Talk so the parent process knows the process is running. This is
- # necessary because ProcessProtocol.makeConnection may be called
- # before this process is exec'd. It would be unfortunate if we
- # SIGTERM'd the Twisted process while it was on its way to doing
- # the exec.
- "sys.stdout.write('x')\n"
- "sys.stdout.flush()\n"
- "sys.stdin.read()\n")
-
- class Exiter(ProcessProtocol):
- def childDataReceived(self, fd, data):
- msg('childDataReceived(%d, %r)' % (fd, data))
- self.transport.signalProcess(sigName)
-
- def childConnectionLost(self, fd):
- msg('childConnectionLost(%d)' % (fd,))
-
- def processExited(self, reason):
- msg('processExited(%r)' % (reason,))
- # Protect the Deferred from the failure so that it follows
- # the callback chain. This doesn't use the errback chain
- # because it wants to make sure reason is a Failure. An
- # Exception would also make an errback-based test pass, and
- # that would be wrong.
- exited.callback([reason])
-
- def processEnded(self, reason):
- msg('processEnded(%r)' % (reason,))
-
- reactor = self.buildReactor()
- reactor.callWhenRunning(
- reactor.spawnProcess, Exiter(), sys.executable,
- [sys.executable, "-c", source], usePTY=self.usePTY)
-
- def cbExited((failure,)):
- # Trapping implicitly verifies that it's a Failure (rather than
- # an exception) and explicitly makes sure it's the right type.
- failure.trap(ProcessTerminated)
- err = failure.value
- if platform.isWindows():
- # Windows can't really /have/ signals, so it certainly can't
- # report them as the reason for termination. Maybe there's
- # something better we could be doing here, anyway? Hard to
- # say. Anyway, this inconsistency between different platforms
- # is extremely unfortunate and I would remove it if I
- # could. -exarkun
- self.assertIdentical(err.signal, None)
- self.assertEqual(err.exitCode, 1)
- else:
- self.assertEqual(err.signal, sigNum)
- self.assertIdentical(err.exitCode, None)
-
- exited.addCallback(cbExited)
- exited.addErrback(err)
- exited.addCallback(lambda ign: reactor.stop())
-
- self.runReactor(reactor)
-
-
- def test_systemCallUninterruptedByChildExit(self):
- """
- If a child process exits while a system call is in progress, the system
- call should not be interfered with. In particular, it should not fail
- with EINTR.
-
- Older versions of Twisted installed a SIGCHLD handler on POSIX without
- using the feature exposed by the SA_RESTART flag to sigaction(2). The
- most noticable problem this caused was for blocking reads and writes to
- sometimes fail with EINTR.
- """
- reactor = self.buildReactor()
-
- # XXX Since pygobject/pygtk wants to use signal.set_wakeup_fd,
- # we aren't actually providing this functionality on the glib2
- # or gtk2 reactors yet. See #4286 for the possibility of
- # improving this.
- skippedReactors = ["Glib2Reactor", "Gtk2Reactor", "PortableGtkReactor"]
- hasSigInterrupt = getattr(signal, "siginterrupt", None) is not None
- reactorClassName = reactor.__class__.__name__
- if reactorClassName in skippedReactors and not hasSigInterrupt:
- raise SkipTest(
- "%s is not supported without siginterrupt" % reactorClassName)
- if _signals.installHandler.__name__ == "_installHandlerUsingSignal":
- raise SkipTest("_signals._installHandlerUsingSignal doesn't support this feature")
-
- result = []
-
- def f():
- try:
- f1 = os.popen('%s -c "import time; time.sleep(0.1)"' %
- (sys.executable,))
- f2 = os.popen('%s -c "import time; time.sleep(0.5); print \'Foo\'"' %
- (sys.executable,))
- # The read call below will blow up with an EINTR from the
- # SIGCHLD from the first process exiting if we install a
- # SIGCHLD handler without SA_RESTART. (which we used to do)
- result.append(f2.read())
- finally:
- reactor.stop()
-
- reactor.callWhenRunning(f)
- self.runReactor(reactor)
- self.assertEqual(result, ["Foo\n"])
-
-
- def test_openFileDescriptors(self):
- """
- A spawned process has only stdin, stdout and stderr open
- (file descriptor 3 is also reported as open, because of the call to
- 'os.listdir()').
- """
- from twisted.python.runtime import platformType
- if platformType != "posix":
- raise SkipTest("Test only applies to POSIX platforms")
-
- here = FilePath(__file__)
- top = here.parent().parent().parent().parent()
- source = (
- "import sys",
- "sys.path.insert(0, '%s')" % (top.path,),
- "from twisted.internet import process",
- "sys.stdout.write(str(process._listOpenFDs()))",
- "sys.stdout.flush()")
-
- def checkOutput(output):
- self.assertEqual('[0, 1, 2, 3]', output)
-
- reactor = self.buildReactor()
-
- class Protocol(ProcessProtocol):
- def __init__(self):
- self.output = []
-
- def outReceived(self, data):
- self.output.append(data)
-
- def processEnded(self, reason):
- try:
- checkOutput("".join(self.output))
- finally:
- reactor.stop()
-
- proto = Protocol()
- reactor.callWhenRunning(
- reactor.spawnProcess, proto, sys.executable,
- [sys.executable, "-Wignore", "-c", "\n".join(source)],
- usePTY=self.usePTY)
- self.runReactor(reactor)
-
-
- def test_timelyProcessExited(self):
- """
- If a spawned process exits, C{processExited} will be called in a
- timely manner.
- """
- reactor = self.buildReactor()
-
- class ExitingProtocol(ProcessProtocol):
- exited = False
-
- def processExited(protoSelf, reason):
- protoSelf.exited = True
- reactor.stop()
- self.assertEqual(reason.value.exitCode, 0)
-
- protocol = ExitingProtocol()
- reactor.callWhenRunning(
- reactor.spawnProcess, protocol, sys.executable,
- [sys.executable, "-c", "raise SystemExit(0)"],
- usePTY=self.usePTY)
-
- # This will timeout if processExited isn't called:
- self.runReactor(reactor, timeout=30)
- self.assertEqual(protocol.exited, True)
-
-
-
-class ProcessTestsBuilder(ProcessTestsBuilderBase):
- """
- Builder defining tests relating to L{IReactorProcess} for child processes
- which do not have a PTY.
- """
- usePTY = False
-
- keepStdioOpenProgram = FilePath(__file__).sibling('process_helper.py').path
- if platform.isWindows():
- keepStdioOpenArg = "windows"
- else:
- # Just a value that doesn't equal "windows"
- keepStdioOpenArg = ""
-
- # Define this test here because PTY-using processes only have stdin and
- # stdout and the test would need to be different for that to work.
- def test_childConnectionLost(self):
- """
- L{IProcessProtocol.childConnectionLost} is called each time a file
- descriptor associated with a child process is closed.
- """
- connected = Deferred()
- lost = {0: Deferred(), 1: Deferred(), 2: Deferred()}
-
- class Closer(ProcessProtocol):
- def makeConnection(self, transport):
- connected.callback(transport)
-
- def childConnectionLost(self, childFD):
- lost[childFD].callback(None)
-
- source = (
- "import os, sys\n"
- "while 1:\n"
- " line = sys.stdin.readline().strip()\n"
- " if not line:\n"
- " break\n"
- " os.close(int(line))\n")
-
- reactor = self.buildReactor()
- reactor.callWhenRunning(
- reactor.spawnProcess, Closer(), sys.executable,
- [sys.executable, "-c", source], usePTY=self.usePTY)
-
- def cbConnected(transport):
- transport.write('2\n')
- return lost[2].addCallback(lambda ign: transport)
- connected.addCallback(cbConnected)
-
- def lostSecond(transport):
- transport.write('1\n')
- return lost[1].addCallback(lambda ign: transport)
- connected.addCallback(lostSecond)
-
- def lostFirst(transport):
- transport.write('\n')
- connected.addCallback(lostFirst)
- connected.addErrback(err)
-
- def cbEnded(ignored):
- reactor.stop()
- connected.addCallback(cbEnded)
-
- self.runReactor(reactor)
-
-
- # This test is here because PTYProcess never delivers childConnectionLost.
- def test_processEnded(self):
- """
- L{IProcessProtocol.processEnded} is called after the child process
- exits and L{IProcessProtocol.childConnectionLost} is called for each of
- its file descriptors.
- """
- ended = Deferred()
- lost = []
-
- class Ender(ProcessProtocol):
- def childDataReceived(self, fd, data):
- msg('childDataReceived(%d, %r)' % (fd, data))
- self.transport.loseConnection()
-
- def childConnectionLost(self, childFD):
- msg('childConnectionLost(%d)' % (childFD,))
- lost.append(childFD)
-
- def processExited(self, reason):
- msg('processExited(%r)' % (reason,))
-
- def processEnded(self, reason):
- msg('processEnded(%r)' % (reason,))
- ended.callback([reason])
-
- reactor = self.buildReactor()
- reactor.callWhenRunning(
- reactor.spawnProcess, Ender(), sys.executable,
- [sys.executable, self.keepStdioOpenProgram, "child",
- self.keepStdioOpenArg],
- usePTY=self.usePTY)
-
- def cbEnded((failure,)):
- failure.trap(ProcessDone)
- self.assertEqual(set(lost), set([0, 1, 2]))
- ended.addCallback(cbEnded)
-
- ended.addErrback(err)
- ended.addCallback(lambda ign: reactor.stop())
-
- self.runReactor(reactor)
-
-
- # This test is here because PTYProcess.loseConnection does not actually
- # close the file descriptors to the child process. This test needs to be
- # written fairly differently for PTYProcess.
- def test_processExited(self):
- """
- L{IProcessProtocol.processExited} is called when the child process
- exits, even if file descriptors associated with the child are still
- open.
- """
- exited = Deferred()
- allLost = Deferred()
- lost = []
-
- class Waiter(ProcessProtocol):
- def childDataReceived(self, fd, data):
- msg('childDataReceived(%d, %r)' % (fd, data))
-
- def childConnectionLost(self, childFD):
- msg('childConnectionLost(%d)' % (childFD,))
- lost.append(childFD)
- if len(lost) == 3:
- allLost.callback(None)
-
- def processExited(self, reason):
- msg('processExited(%r)' % (reason,))
- # See test_processExitedWithSignal
- exited.callback([reason])
- self.transport.loseConnection()
-
- reactor = self.buildReactor()
- reactor.callWhenRunning(
- reactor.spawnProcess, Waiter(), sys.executable,
- [sys.executable, self.keepStdioOpenProgram, "child",
- self.keepStdioOpenArg],
- usePTY=self.usePTY)
-
- def cbExited((failure,)):
- failure.trap(ProcessDone)
- msg('cbExited; lost = %s' % (lost,))
- self.assertEqual(lost, [])
- return allLost
- exited.addCallback(cbExited)
-
- def cbAllLost(ignored):
- self.assertEqual(set(lost), set([0, 1, 2]))
- exited.addCallback(cbAllLost)
-
- exited.addErrback(err)
- exited.addCallback(lambda ign: reactor.stop())
-
- self.runReactor(reactor)
-
-
- def makeSourceFile(self, sourceLines):
- """
- Write the given list of lines to a text file and return the absolute
- path to it.
- """
- script = self.mktemp()
- scriptFile = file(script, 'wt')
- scriptFile.write(os.linesep.join(sourceLines) + os.linesep)
- scriptFile.close()
- return os.path.abspath(script)
-
-
- def test_shebang(self):
- """
- Spawning a process with an executable which is a script starting
- with an interpreter definition line (#!) uses that interpreter to
- evaluate the script.
- """
- SHEBANG_OUTPUT = 'this is the shebang output'
-
- scriptFile = self.makeSourceFile([
- "#!%s" % (sys.executable,),
- "import sys",
- "sys.stdout.write('%s')" % (SHEBANG_OUTPUT,),
- "sys.stdout.flush()"])
- os.chmod(scriptFile, 0700)
-
- reactor = self.buildReactor()
-
- def cbProcessExited((out, err, code)):
- msg("cbProcessExited((%r, %r, %d))" % (out, err, code))
- self.assertEqual(out, SHEBANG_OUTPUT)
- self.assertEqual(err, "")
- self.assertEqual(code, 0)
-
- def shutdown(passthrough):
- reactor.stop()
- return passthrough
-
- def start():
- d = utils.getProcessOutputAndValue(scriptFile, reactor=reactor)
- d.addBoth(shutdown)
- d.addCallback(cbProcessExited)
- d.addErrback(err)
-
- reactor.callWhenRunning(start)
- self.runReactor(reactor)
-
-
- def test_processCommandLineArguments(self):
- """
- Arguments given to spawnProcess are passed to the child process as
- originally intended.
- """
- source = (
- # On Windows, stdout is not opened in binary mode by default,
- # so newline characters are munged on writing, interfering with
- # the tests.
- 'import sys, os\n'
- 'try:\n'
- ' import msvcrt\n'
- ' msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\n'
- 'except ImportError:\n'
- ' pass\n'
- 'for arg in sys.argv[1:]:\n'
- ' sys.stdout.write(arg + chr(0))\n'
- ' sys.stdout.flush()')
-
- args = ['hello', '"', ' \t|<>^&', r'"\\"hello\\"', r'"foo\ bar baz\""']
- # Ensure that all non-NUL characters can be passed too.
- args.append(''.join(map(chr, xrange(1, 256))))
-
- reactor = self.buildReactor()
-
- def processFinished(output):
- output = output.split('\0')
- # Drop the trailing \0.
- output.pop()
- self.assertEqual(args, output)
-
- def shutdown(result):
- reactor.stop()
- return result
-
- def spawnChild():
- d = succeed(None)
- d.addCallback(lambda dummy: utils.getProcessOutput(
- sys.executable, ['-c', source] + args, reactor=reactor))
- d.addCallback(processFinished)
- d.addBoth(shutdown)
-
- reactor.callWhenRunning(spawnChild)
- self.runReactor(reactor)
-globals().update(ProcessTestsBuilder.makeTestCaseClasses())
-
-
-
-class PTYProcessTestsBuilder(ProcessTestsBuilderBase):
- """
- Builder defining tests relating to L{IReactorProcess} for child processes
- which have a PTY.
- """
- usePTY = True
-
- if platform.isWindows():
- skip = "PTYs are not supported on Windows."
- elif platform.isMacOSX():
- skippedReactors = {
- "twisted.internet.pollreactor.PollReactor":
- "OS X's poll() does not support PTYs"}
-globals().update(PTYProcessTestsBuilder.makeTestCaseClasses())
-
-
-
-class PotentialZombieWarningTests(TestCase):
- """
- Tests for L{twisted.internet.error.PotentialZombieWarning}.
- """
- def test_deprecated(self):
- """
- Accessing L{PotentialZombieWarning} via the
- I{PotentialZombieWarning} attribute of L{twisted.internet.error}
- results in a deprecation warning being emitted.
- """
- from twisted.internet import error
- error.PotentialZombieWarning
-
- warnings = self.flushWarnings([self.test_deprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "twisted.internet.error.PotentialZombieWarning was deprecated in "
- "Twisted 10.0.0: There is no longer any potential for zombie "
- "process.")
- self.assertEqual(len(warnings), 1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_protocol.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_protocol.py
deleted file mode 100755
index 18ef114c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_protocol.py
+++ /dev/null
@@ -1,357 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.protocol}.
-"""
-
-from zope.interface.verify import verifyObject
-
-from twisted.python.failure import Failure
-from twisted.internet.interfaces import IProtocol, ILoggingContext
-from twisted.internet.defer import CancelledError
-from twisted.internet.protocol import Protocol, ClientCreator
-from twisted.internet.task import Clock
-from twisted.trial.unittest import TestCase
-from twisted.test.proto_helpers import MemoryReactor, StringTransport
-
-
-
-class MemoryConnector:
- _disconnected = False
-
- def disconnect(self):
- self._disconnected = True
-
-
-
-class MemoryReactorWithConnectorsAndTime(MemoryReactor, Clock):
- """
- An extension of L{MemoryReactor} which returns L{IConnector}
- providers from its C{connectTCP} method.
- """
- def __init__(self):
- MemoryReactor.__init__(self)
- Clock.__init__(self)
- self.connectors = []
-
-
- def connectTCP(self, *a, **kw):
- MemoryReactor.connectTCP(self, *a, **kw)
- connector = MemoryConnector()
- self.connectors.append(connector)
- return connector
-
-
- def connectUNIX(self, *a, **kw):
- MemoryReactor.connectUNIX(self, *a, **kw)
- connector = MemoryConnector()
- self.connectors.append(connector)
- return connector
-
-
- def connectSSL(self, *a, **kw):
- MemoryReactor.connectSSL(self, *a, **kw)
- connector = MemoryConnector()
- self.connectors.append(connector)
- return connector
-
-
-
-class ClientCreatorTests(TestCase):
- """
- Tests for L{twisted.internet.protocol.ClientCreator}.
- """
- def _basicConnectTest(self, check):
- """
- Helper for implementing a test to verify that one of the I{connect}
- methods of L{ClientCreator} passes the right arguments to the right
- reactor method.
-
- @param check: A function which will be invoked with a reactor and a
- L{ClientCreator} instance and which should call one of the
- L{ClientCreator}'s I{connect} methods and assert that all of its
- arguments except for the factory are passed on as expected to the
- reactor. The factory should be returned.
- """
- class SomeProtocol(Protocol):
- pass
-
- reactor = MemoryReactorWithConnectorsAndTime()
- cc = ClientCreator(reactor, SomeProtocol)
- factory = check(reactor, cc)
- protocol = factory.buildProtocol(None)
- self.assertIsInstance(protocol, SomeProtocol)
-
-
- def test_connectTCP(self):
- """
- L{ClientCreator.connectTCP} calls C{reactor.connectTCP} with the host
- and port information passed to it, and with a factory which will
- construct the protocol passed to L{ClientCreator.__init__}.
- """
- def check(reactor, cc):
- cc.connectTCP('example.com', 1234, 4321, ('1.2.3.4', 9876))
- host, port, factory, timeout, bindAddress = reactor.tcpClients.pop()
- self.assertEqual(host, 'example.com')
- self.assertEqual(port, 1234)
- self.assertEqual(timeout, 4321)
- self.assertEqual(bindAddress, ('1.2.3.4', 9876))
- return factory
- self._basicConnectTest(check)
-
-
- def test_connectUNIX(self):
- """
- L{ClientCreator.connectUNIX} calls C{reactor.connectUNIX} with the
- filename passed to it, and with a factory which will construct the
- protocol passed to L{ClientCreator.__init__}.
- """
- def check(reactor, cc):
- cc.connectUNIX('/foo/bar', 123, True)
- address, factory, timeout, checkPID = reactor.unixClients.pop()
- self.assertEqual(address, '/foo/bar')
- self.assertEqual(timeout, 123)
- self.assertEqual(checkPID, True)
- return factory
- self._basicConnectTest(check)
-
-
- def test_connectSSL(self):
- """
- L{ClientCreator.connectSSL} calls C{reactor.connectSSL} with the host,
- port, and context factory passed to it, and with a factory which will
- construct the protocol passed to L{ClientCreator.__init__}.
- """
- def check(reactor, cc):
- expectedContextFactory = object()
- cc.connectSSL('example.com', 1234, expectedContextFactory, 4321, ('4.3.2.1', 5678))
- host, port, factory, contextFactory, timeout, bindAddress = reactor.sslClients.pop()
- self.assertEqual(host, 'example.com')
- self.assertEqual(port, 1234)
- self.assertIdentical(contextFactory, expectedContextFactory)
- self.assertEqual(timeout, 4321)
- self.assertEqual(bindAddress, ('4.3.2.1', 5678))
- return factory
- self._basicConnectTest(check)
-
-
- def _cancelConnectTest(self, connect):
- """
- Helper for implementing a test to verify that cancellation of the
- L{Deferred} returned by one of L{ClientCreator}'s I{connect} methods is
- implemented to cancel the underlying connector.
-
- @param connect: A function which will be invoked with a L{ClientCreator}
- instance as an argument and which should call one its I{connect}
- methods and return the result.
-
- @return: A L{Deferred} which fires when the test is complete or fails if
- there is a problem.
- """
- reactor = MemoryReactorWithConnectorsAndTime()
- cc = ClientCreator(reactor, Protocol)
- d = connect(cc)
- connector = reactor.connectors.pop()
- self.assertFalse(connector._disconnected)
- d.cancel()
- self.assertTrue(connector._disconnected)
- return self.assertFailure(d, CancelledError)
-
-
- def test_cancelConnectTCP(self):
- """
- The L{Deferred} returned by L{ClientCreator.connectTCP} can be cancelled
- to abort the connection attempt before it completes.
- """
- def connect(cc):
- return cc.connectTCP('example.com', 1234)
- return self._cancelConnectTest(connect)
-
-
- def test_cancelConnectUNIX(self):
- """
- The L{Deferred} returned by L{ClientCreator.connectTCP} can be cancelled
- to abort the connection attempt before it completes.
- """
- def connect(cc):
- return cc.connectUNIX('/foo/bar')
- return self._cancelConnectTest(connect)
-
-
- def test_cancelConnectSSL(self):
- """
- The L{Deferred} returned by L{ClientCreator.connectTCP} can be cancelled
- to abort the connection attempt before it completes.
- """
- def connect(cc):
- return cc.connectSSL('example.com', 1234, object())
- return self._cancelConnectTest(connect)
-
-
- def _cancelConnectTimeoutTest(self, connect):
- """
- Like L{_cancelConnectTest}, but for the case where the L{Deferred} is
- cancelled after the connection is set up but before it is fired with the
- resulting protocol instance.
- """
- reactor = MemoryReactorWithConnectorsAndTime()
- cc = ClientCreator(reactor, Protocol)
- d = connect(reactor, cc)
- connector = reactor.connectors.pop()
- # Sanity check - there is an outstanding delayed call to fire the
- # Deferred.
- self.assertEqual(len(reactor.getDelayedCalls()), 1)
-
- # Cancel the Deferred, disconnecting the transport just set up and
- # cancelling the delayed call.
- d.cancel()
-
- self.assertEqual(reactor.getDelayedCalls(), [])
-
- # A real connector implementation is responsible for disconnecting the
- # transport as well. For our purposes, just check that someone told the
- # connector to disconnect.
- self.assertTrue(connector._disconnected)
-
- return self.assertFailure(d, CancelledError)
-
-
- def test_cancelConnectTCPTimeout(self):
- """
- L{ClientCreator.connectTCP} inserts a very short delayed call between
- the time the connection is established and the time the L{Deferred}
- returned from one of its connect methods actually fires. If the
- L{Deferred} is cancelled in this interval, the established connection is
- closed, the timeout is cancelled, and the L{Deferred} fails with
- L{CancelledError}.
- """
- def connect(reactor, cc):
- d = cc.connectTCP('example.com', 1234)
- host, port, factory, timeout, bindAddress = reactor.tcpClients.pop()
- protocol = factory.buildProtocol(None)
- transport = StringTransport()
- protocol.makeConnection(transport)
- return d
- return self._cancelConnectTimeoutTest(connect)
-
-
- def test_cancelConnectUNIXTimeout(self):
- """
- L{ClientCreator.connectUNIX} inserts a very short delayed call between
- the time the connection is established and the time the L{Deferred}
- returned from one of its connect methods actually fires. If the
- L{Deferred} is cancelled in this interval, the established connection is
- closed, the timeout is cancelled, and the L{Deferred} fails with
- L{CancelledError}.
- """
- def connect(reactor, cc):
- d = cc.connectUNIX('/foo/bar')
- address, factory, timeout, bindAddress = reactor.unixClients.pop()
- protocol = factory.buildProtocol(None)
- transport = StringTransport()
- protocol.makeConnection(transport)
- return d
- return self._cancelConnectTimeoutTest(connect)
-
-
- def test_cancelConnectSSLTimeout(self):
- """
- L{ClientCreator.connectSSL} inserts a very short delayed call between
- the time the connection is established and the time the L{Deferred}
- returned from one of its connect methods actually fires. If the
- L{Deferred} is cancelled in this interval, the established connection is
- closed, the timeout is cancelled, and the L{Deferred} fails with
- L{CancelledError}.
- """
- def connect(reactor, cc):
- d = cc.connectSSL('example.com', 1234, object())
- host, port, factory, contextFactory, timeout, bindADdress = reactor.sslClients.pop()
- protocol = factory.buildProtocol(None)
- transport = StringTransport()
- protocol.makeConnection(transport)
- return d
- return self._cancelConnectTimeoutTest(connect)
-
-
- def _cancelConnectFailedTimeoutTest(self, connect):
- """
- Like L{_cancelConnectTest}, but for the case where the L{Deferred} is
- cancelled after the connection attempt has failed but before it is fired
- with the resulting failure.
- """
- reactor = MemoryReactorWithConnectorsAndTime()
- cc = ClientCreator(reactor, Protocol)
- d, factory = connect(reactor, cc)
- connector = reactor.connectors.pop()
- factory.clientConnectionFailed(
- connector, Failure(Exception("Simulated failure")))
-
- # Sanity check - there is an outstanding delayed call to fire the
- # Deferred.
- self.assertEqual(len(reactor.getDelayedCalls()), 1)
-
- # Cancel the Deferred, cancelling the delayed call.
- d.cancel()
-
- self.assertEqual(reactor.getDelayedCalls(), [])
-
- return self.assertFailure(d, CancelledError)
-
-
- def test_cancelConnectTCPFailedTimeout(self):
- """
- Similar to L{test_cancelConnectTCPTimeout}, but for the case where the
- connection attempt fails.
- """
- def connect(reactor, cc):
- d = cc.connectTCP('example.com', 1234)
- host, port, factory, timeout, bindAddress = reactor.tcpClients.pop()
- return d, factory
- return self._cancelConnectFailedTimeoutTest(connect)
-
-
- def test_cancelConnectUNIXFailedTimeout(self):
- """
- Similar to L{test_cancelConnectUNIXTimeout}, but for the case where the
- connection attempt fails.
- """
- def connect(reactor, cc):
- d = cc.connectUNIX('/foo/bar')
- address, factory, timeout, bindAddress = reactor.unixClients.pop()
- return d, factory
- return self._cancelConnectFailedTimeoutTest(connect)
-
-
- def test_cancelConnectSSLFailedTimeout(self):
- """
- Similar to L{test_cancelConnectSSLTimeout}, but for the case where the
- connection attempt fails.
- """
- def connect(reactor, cc):
- d = cc.connectSSL('example.com', 1234, object())
- host, port, factory, contextFactory, timeout, bindADdress = reactor.sslClients.pop()
- return d, factory
- return self._cancelConnectFailedTimeoutTest(connect)
-
-
-class ProtocolTests(TestCase):
- """
- Tests for L{twisted.internet.protocol.Protocol}.
- """
- def test_interfaces(self):
- """
- L{Protocol} instances provide L{IProtocol} and L{ILoggingContext}.
- """
- proto = Protocol()
- self.assertTrue(verifyObject(IProtocol, proto))
- self.assertTrue(verifyObject(ILoggingContext, proto))
-
-
- def test_logPrefix(self):
- """
- L{Protocol.logPrefix} returns the protocol class's name.
- """
- class SomeThing(Protocol):
- pass
- self.assertEqual("SomeThing", SomeThing().logPrefix())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_qtreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_qtreactor.py
deleted file mode 100755
index e87b74fd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_qtreactor.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys
-
-from twisted.trial import unittest
-from twisted.python.runtime import platform
-from twisted.python.util import sibpath
-from twisted.internet.utils import getProcessOutputAndValue
-
-
-skipWindowsNopywin32 = None
-if platform.isWindows():
- try:
- import win32process
- except ImportError:
- skipWindowsNopywin32 = ("On windows, spawnProcess is not available "
- "in the absence of win32process.")
-
-class QtreactorTestCase(unittest.TestCase):
- """
- Tests for L{twisted.internet.qtreactor}.
- """
- def test_importQtreactor(self):
- """
- Attempting to import L{twisted.internet.qtreactor} should raise an
- C{ImportError} indicating that C{qtreactor} is no longer a part of
- Twisted.
- """
- sys.modules["qtreactor"] = None
- from twisted.plugins.twisted_qtstub import errorMessage
- try:
- import twisted.internet.qtreactor
- except ImportError, e:
- self.assertEqual(str(e), errorMessage)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_serialport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_serialport.py
deleted file mode 100755
index 85b3f3a6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_serialport.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.serialport}.
-"""
-
-from twisted.trial import unittest
-from twisted.python.failure import Failure
-from twisted.internet.protocol import Protocol
-from twisted.internet.error import ConnectionDone
-try:
- from twisted.internet import serialport
-except ImportError:
- serialport = None
-
-
-
-class DoNothing(object):
- """
- Object with methods that do nothing.
- """
-
- def __init__(self, *args, **kwargs):
- pass
-
-
- def __getattr__(self, attr):
- return lambda *args, **kwargs: None
-
-
-
-class SerialPortTests(unittest.TestCase):
- """
- Minimal testing for Twisted's serial port support.
-
- See ticket #2462 for the eventual full test suite.
- """
-
- if serialport is None:
- skip = "Serial port support is not available."
-
-
- def test_connectionMadeLost(self):
- """
- C{connectionMade} and C{connectionLost} are called on the protocol by
- the C{SerialPort}.
- """
- # Serial port that doesn't actually connect to anything:
- class DummySerialPort(serialport.SerialPort):
- _serialFactory = DoNothing
-
- def _finishPortSetup(self):
- pass # override default win32 actions
-
- events = []
-
- class SerialProtocol(Protocol):
- def connectionMade(self):
- events.append("connectionMade")
-
- def connectionLost(self, reason):
- events.append(("connectionLost", reason))
-
- # Creation of port should result in connectionMade call:
- port = DummySerialPort(SerialProtocol(), "", reactor=DoNothing())
- self.assertEqual(events, ["connectionMade"])
-
- # Simulate reactor calling connectionLost on the SerialPort:
- f = Failure(ConnectionDone())
- port.connectionLost(f)
- self.assertEqual(events, ["connectionMade", ("connectionLost", f)])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_sigchld.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_sigchld.py
deleted file mode 100755
index 86a711a5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_sigchld.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet._sigchld}, an alternate, superior SIGCHLD
-monitoring API.
-"""
-
-import os, signal, errno
-
-from twisted.python.log import msg
-from twisted.trial.unittest import TestCase
-from twisted.internet.fdesc import setNonBlocking
-from twisted.internet._signals import installHandler, isDefaultHandler
-from twisted.internet._signals import _extInstallHandler, _extIsDefaultHandler
-from twisted.internet._signals import _installHandlerUsingSetWakeup, \
- _installHandlerUsingSignal, _isDefaultHandler
-
-
-class SIGCHLDTestsMixin:
- """
- Mixin for L{TestCase} subclasses which defines several tests for
- I{installHandler} and I{isDefaultHandler}. Subclasses are expected to
- define C{self.installHandler} and C{self.isDefaultHandler} to invoke the
- implementation to be tested.
- """
-
- if getattr(signal, 'SIGCHLD', None) is None:
- skip = "Platform does not have SIGCHLD"
-
- def installHandler(self, fd):
- """
- Override in a subclass to install a SIGCHLD handler which writes a byte
- to the given file descriptor. Return the previously registered file
- descriptor.
- """
- raise NotImplementedError()
-
-
- def isDefaultHandler(self):
- """
- Override in a subclass to determine if the current SIGCHLD handler is
- SIG_DFL or not. Return True if it is SIG_DFL, False otherwise.
- """
- raise NotImplementedError()
-
-
- def pipe(self):
- """
- Create a non-blocking pipe which will be closed after the currently
- running test.
- """
- read, write = os.pipe()
- self.addCleanup(os.close, read)
- self.addCleanup(os.close, write)
- setNonBlocking(read)
- setNonBlocking(write)
- return read, write
-
-
- def setUp(self):
- """
- Save the current SIGCHLD handler as reported by L{signal.signal} and
- the current file descriptor registered with L{installHandler}.
- """
- handler = signal.getsignal(signal.SIGCHLD)
- if handler != signal.SIG_DFL:
- self.signalModuleHandler = handler
- signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- else:
- self.signalModuleHandler = None
-
- self.oldFD = self.installHandler(-1)
-
- if self.signalModuleHandler is not None and self.oldFD != -1:
- msg("SIGCHLD setup issue: %r %r" % (self.signalModuleHandler, self.oldFD))
- raise RuntimeError("You used some signal APIs wrong! Try again.")
-
-
- def tearDown(self):
- """
- Restore whatever signal handler was present when setUp ran.
- """
- # If tests set up any kind of handlers, clear them out.
- self.installHandler(-1)
- signal.signal(signal.SIGCHLD, signal.SIG_DFL)
-
- # Now restore whatever the setup was before the test ran.
- if self.signalModuleHandler is not None:
- signal.signal(signal.SIGCHLD, self.signalModuleHandler)
- elif self.oldFD != -1:
- self.installHandler(self.oldFD)
-
-
- def test_isDefaultHandler(self):
- """
- L{isDefaultHandler} returns true if the SIGCHLD handler is SIG_DFL,
- false otherwise.
- """
- self.assertTrue(self.isDefaultHandler())
- signal.signal(signal.SIGCHLD, signal.SIG_IGN)
- self.assertFalse(self.isDefaultHandler())
- signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- self.assertTrue(self.isDefaultHandler())
- signal.signal(signal.SIGCHLD, lambda *args: None)
- self.assertFalse(self.isDefaultHandler())
-
-
- def test_returnOldFD(self):
- """
- L{installHandler} returns the previously registered file descriptor.
- """
- read, write = self.pipe()
- oldFD = self.installHandler(write)
- self.assertEqual(self.installHandler(oldFD), write)
-
-
- def test_uninstallHandler(self):
- """
- C{installHandler(-1)} removes the SIGCHLD handler completely.
- """
- read, write = self.pipe()
- self.assertTrue(self.isDefaultHandler())
- self.installHandler(write)
- self.assertFalse(self.isDefaultHandler())
- self.installHandler(-1)
- self.assertTrue(self.isDefaultHandler())
-
-
- def test_installHandler(self):
- """
- The file descriptor passed to L{installHandler} has a byte written to
- it when SIGCHLD is delivered to the process.
- """
- read, write = self.pipe()
- self.installHandler(write)
-
- exc = self.assertRaises(OSError, os.read, read, 1)
- self.assertEqual(exc.errno, errno.EAGAIN)
-
- os.kill(os.getpid(), signal.SIGCHLD)
-
- self.assertEqual(len(os.read(read, 5)), 1)
-
-
-
-class DefaultSIGCHLDTests(SIGCHLDTestsMixin, TestCase):
- """
- Tests for whatever implementation is selected for the L{installHandler}
- and L{isDefaultHandler} APIs.
- """
- installHandler = staticmethod(installHandler)
- isDefaultHandler = staticmethod(isDefaultHandler)
-
-
-
-class ExtensionSIGCHLDTests(SIGCHLDTestsMixin, TestCase):
- """
- Tests for the L{twisted.internet._sigchld} implementation of the
- L{installHandler} and L{isDefaultHandler} APIs.
- """
- try:
- import twisted.internet._sigchld
- except ImportError:
- skip = "twisted.internet._sigchld is not available"
-
- installHandler = _extInstallHandler
- isDefaultHandler = _extIsDefaultHandler
-
-
-
-class SetWakeupSIGCHLDTests(SIGCHLDTestsMixin, TestCase):
- """
- Tests for the L{signal.set_wakeup_fd} implementation of the
- L{installHandler} and L{isDefaultHandler} APIs.
- """
- # Check both of these. On Ubuntu 9.10 (to take an example completely at
- # random), Python 2.5 has set_wakeup_fd but not siginterrupt.
- if (getattr(signal, 'set_wakeup_fd', None) is None
- or getattr(signal, 'siginterrupt', None) is None):
- skip = "signal.set_wakeup_fd is not available"
-
- installHandler = staticmethod(_installHandlerUsingSetWakeup)
- isDefaultHandler = staticmethod(_isDefaultHandler)
-
-
-
-class PlainSignalModuleSIGCHLDTests(SIGCHLDTestsMixin, TestCase):
- """
- Tests for the L{signal.signal} implementation of the L{installHandler}
- and L{isDefaultHandler} APIs.
- """
- installHandler = staticmethod(_installHandlerUsingSignal)
- isDefaultHandler = staticmethod(_isDefaultHandler)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_socket.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_socket.py
deleted file mode 100755
index b31eb914..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_socket.py
+++ /dev/null
@@ -1,128 +0,0 @@
-
-import errno, socket
-
-from twisted.python.log import err
-from twisted.internet.interfaces import IReactorSocket
-from twisted.internet.error import UnsupportedAddressFamily
-from twisted.internet.protocol import ServerFactory
-from twisted.internet.test.reactormixins import (
- ReactorBuilder, needsRunningReactor)
-
-
-class AdoptStreamPortErrorsTestsBuilder(ReactorBuilder):
- """
- Builder for testing L{IReactorSocket.adoptStreamPort} implementations.
-
- Generally only tests for failure cases are found here. Success cases for
- this interface are tested elsewhere. For example, the success case for
- I{AF_INET} is in L{twisted.internet.test.test_tcp}, since that case should
- behave exactly the same as L{IReactorTCP.listenTCP}.
- """
- requiredInterfaces = [IReactorSocket]
-
- def test_invalidDescriptor(self):
- """
- An implementation of L{IReactorSocket.adoptStreamPort} raises
- L{socket.error} if passed an integer which is not associated with a
- socket.
- """
- reactor = self.buildReactor()
-
- probe = socket.socket()
- fileno = probe.fileno()
- probe.close()
-
- exc = self.assertRaises(
- socket.error,
- reactor.adoptStreamPort, fileno, socket.AF_INET, ServerFactory())
- self.assertEqual(exc.args[0], errno.EBADF)
-
-
- def test_invalidAddressFamily(self):
- """
- An implementation of L{IReactorSocket.adoptStreamPort} raises
- L{UnsupportedAddressFamily} if passed an address family it does not
- support.
- """
- reactor = self.buildReactor()
-
- port = socket.socket()
- port.listen(1)
- self.addCleanup(port.close)
-
- arbitrary = 2 ** 16 + 7
-
- self.assertRaises(
- UnsupportedAddressFamily,
- reactor.adoptStreamPort, port.fileno(), arbitrary, ServerFactory())
-
-
- def test_stopOnlyCloses(self):
- """
- When the L{IListeningPort} returned by L{IReactorSocket.adoptStreamPort}
- is stopped using C{stopListening}, the underlying socket is closed but
- not shutdown. This allows another process which still has a reference
- to it to continue accepting connections over it.
- """
- reactor = self.buildReactor()
-
- portSocket = socket.socket()
- self.addCleanup(portSocket.close)
-
- portSocket.listen(1)
- portSocket.setblocking(False)
-
- # The file descriptor is duplicated by adoptStreamPort
- port = reactor.adoptStreamPort(
- portSocket.fileno(), portSocket.family, ServerFactory())
- d = port.stopListening()
- def stopped(ignored):
- # Should still be possible to accept a connection on portSocket. If
- # it was shutdown, the exception would be EINVAL instead.
- exc = self.assertRaises(socket.error, portSocket.accept)
- self.assertEqual(exc.args[0], errno.EAGAIN)
- d.addCallback(stopped)
- d.addErrback(err, "Failed to accept on original port.")
-
- needsRunningReactor(
- reactor,
- lambda: d.addCallback(lambda ignored: reactor.stop()))
-
- reactor.run()
-
-
-
-class AdoptStreamConnectionErrorsTestsBuilder(ReactorBuilder):
- """
- Builder for testing L{IReactorSocket.adoptStreamConnection}
- implementations.
-
- Generally only tests for failure cases are found here. Success cases for
- this interface are tested elsewhere. For example, the success case for
- I{AF_INET} is in L{twisted.internet.test.test_tcp}, since that case should
- behave exactly the same as L{IReactorTCP.listenTCP}.
- """
- requiredInterfaces = [IReactorSocket]
-
- def test_invalidAddressFamily(self):
- """
- An implementation of L{IReactorSocket.adoptStreamConnection} raises
- L{UnsupportedAddressFamily} if passed an address family it does not
- support.
- """
- reactor = self.buildReactor()
-
- connection = socket.socket()
- self.addCleanup(connection.close)
-
- arbitrary = 2 ** 16 + 7
-
- self.assertRaises(
- UnsupportedAddressFamily,
- reactor.adoptStreamConnection, connection.fileno(), arbitrary,
- ServerFactory())
-
-
-
-globals().update(AdoptStreamPortErrorsTestsBuilder.makeTestCaseClasses())
-globals().update(AdoptStreamConnectionErrorsTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_stdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_stdio.py
deleted file mode 100755
index 4163e414..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_stdio.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.stdio}.
-"""
-
-from twisted.python.runtime import platform
-from twisted.internet.test.reactormixins import ReactorBuilder
-from twisted.internet.protocol import Protocol
-if not platform.isWindows():
- from twisted.internet._posixstdio import StandardIO
-
-
-
-class StdioFilesTests(ReactorBuilder):
- """
- L{StandardIO} supports reading and writing to filesystem files.
- """
-
- def setUp(self):
- path = self.mktemp()
- file(path, "w").close()
- self.extraFile = file(path, "r+")
-
-
- def test_addReader(self):
- """
- Adding a filesystem file reader to a reactor will make sure it is
- polled.
- """
- reactor = self.buildReactor()
-
- class DataProtocol(Protocol):
- data = ""
- def dataReceived(self, data):
- self.data += data
- # It'd be better to stop reactor on connectionLost, but that
- # fails on FreeBSD, probably due to
- # http://bugs.python.org/issue9591:
- if self.data == "hello!":
- reactor.stop()
-
- path = self.mktemp()
- f = file(path, "w")
- f.write("hello!")
- f.close()
- f = file(path, "r")
-
- # Read bytes from a file, deliver them to a protocol instance:
- protocol = DataProtocol()
- StandardIO(protocol, stdin=f.fileno(),
- stdout=self.extraFile.fileno(),
- reactor=reactor)
-
- self.runReactor(reactor)
- self.assertEqual(protocol.data, "hello!")
-
-
- def test_addWriter(self):
- """
- Adding a filesystem file writer to a reactor will make sure it is
- polled.
- """
- reactor = self.buildReactor()
-
- class DisconnectProtocol(Protocol):
- def connectionLost(self, reason):
- reactor.stop()
-
- path = self.mktemp()
- f = file(path, "w")
-
- # Write bytes to a transport, hopefully have them written to a file:
- protocol = DisconnectProtocol()
- StandardIO(protocol, stdout=f.fileno(),
- stdin=self.extraFile.fileno(), reactor=reactor)
- protocol.transport.write("hello")
- protocol.transport.write(", world")
- protocol.transport.loseConnection()
-
- self.runReactor(reactor)
- f.close()
- f = file(path, "r")
- self.assertEqual(f.read(), "hello, world")
- f.close()
-
-
- def test_removeReader(self):
- """
- Removing a filesystem file reader from a reactor will make sure it is
- no longer polled.
- """
- reactor = self.buildReactor()
- self.addCleanup(self.unbuildReactor, reactor)
-
- path = self.mktemp()
- file(path, "w").close()
- # Cleanup might fail if file is GCed too soon:
- self.f = f = file(path, "r")
-
- # Have the reader added:
- stdio = StandardIO(Protocol(), stdin=f.fileno(),
- stdout=self.extraFile.fileno(),
- reactor=reactor)
- self.assertIn(stdio._reader, reactor.getReaders())
- stdio._reader.stopReading()
- self.assertNotIn(stdio._reader, reactor.getReaders())
-
-
- def test_removeWriter(self):
- """
- Removing a filesystem file writer from a reactor will make sure it is
- no longer polled.
- """
- reactor = self.buildReactor()
- self.addCleanup(self.unbuildReactor, reactor)
-
- # Cleanup might fail if file is GCed too soon:
- self.f = f = file(self.mktemp(), "w")
-
- # Have the reader added:
- protocol = Protocol()
- stdio = StandardIO(protocol, stdout=f.fileno(),
- stdin=self.extraFile.fileno(),
- reactor=reactor)
- protocol.transport.write("hello")
- self.assertIn(stdio._writer, reactor.getWriters())
- stdio._writer.stopWriting()
- self.assertNotIn(stdio._writer, reactor.getWriters())
-
-
- def test_removeAll(self):
- """
- Calling C{removeAll} on a reactor includes descriptors that are
- filesystem files.
- """
- reactor = self.buildReactor()
- self.addCleanup(self.unbuildReactor, reactor)
-
- path = self.mktemp()
- file(path, "w").close()
- # Cleanup might fail if file is GCed too soon:
- self.f = f = file(path, "r")
-
- # Have the reader added:
- stdio = StandardIO(Protocol(), stdin=f.fileno(),
- stdout=self.extraFile.fileno(), reactor=reactor)
- # And then removed:
- removed = reactor.removeAll()
- self.assertIn(stdio._reader, removed)
- self.assertNotIn(stdio._reader, reactor.getReaders())
-
-
- def test_getReaders(self):
- """
- C{reactor.getReaders} includes descriptors that are filesystem files.
- """
- reactor = self.buildReactor()
- self.addCleanup(self.unbuildReactor, reactor)
-
- path = self.mktemp()
- file(path, "w").close()
- # Cleanup might fail if file is GCed too soon:
- self.f = f = file(path, "r")
-
- # Have the reader added:
- stdio = StandardIO(Protocol(), stdin=f.fileno(),
- stdout=self.extraFile.fileno(), reactor=reactor)
- self.assertIn(stdio._reader, reactor.getReaders())
-
-
- def test_getWriters(self):
- """
- C{reactor.getWriters} includes descriptors that are filesystem files.
- """
- reactor = self.buildReactor()
- self.addCleanup(self.unbuildReactor, reactor)
-
- # Cleanup might fail if file is GCed too soon:
- self.f = f = file(self.mktemp(), "w")
-
- # Have the reader added:
- stdio = StandardIO(Protocol(), stdout=f.fileno(),
- stdin=self.extraFile.fileno(), reactor=reactor)
- self.assertNotIn(stdio._writer, reactor.getWriters())
- stdio._writer.startWriting()
- self.assertIn(stdio._writer, reactor.getWriters())
-
- if platform.isWindows():
- skip = ("StandardIO does not accept stdout as an argument to Windows. "
- "Testing redirection to a file is therefore harder.")
-
-
-globals().update(StdioFilesTests.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tcp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tcp.py
deleted file mode 100755
index 862cc25b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tcp.py
+++ /dev/null
@@ -1,2077 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorTCP} and the TCP parts of
-L{IReactorSocket}.
-"""
-
-__metaclass__ = type
-
-import socket, errno
-
-from zope.interface import implements
-
-from twisted.python.runtime import platform
-from twisted.python.failure import Failure
-from twisted.python import log
-
-from twisted.trial.unittest import SkipTest, TestCase
-from twisted.internet.test.reactormixins import ReactorBuilder, EndpointCreator
-from twisted.internet.test.reactormixins import ConnectableProtocol
-from twisted.internet.test.reactormixins import runProtocolsWithReactor
-from twisted.internet.error import (
- ConnectionLost, UserError, ConnectionRefusedError, ConnectionDone,
- ConnectionAborted)
-from twisted.internet.interfaces import (
- ILoggingContext, IConnector, IReactorFDSet, IReactorSocket, IReactorTCP)
-from twisted.internet.address import IPv4Address, IPv6Address
-from twisted.internet.defer import (
- Deferred, DeferredList, maybeDeferred, gatherResults)
-from twisted.internet.endpoints import (
- TCP4ServerEndpoint, TCP4ClientEndpoint)
-from twisted.internet.protocol import ServerFactory, ClientFactory, Protocol
-from twisted.internet.interfaces import (
- IPushProducer, IPullProducer, IHalfCloseableProtocol)
-from twisted.internet.tcp import Connection, Server, _resolveIPv6
-
-from twisted.internet.test.connectionmixins import (
- LogObserverMixin, ConnectionTestsMixin, TCPClientTestsMixin, findFreePort)
-from twisted.internet.test.test_core import ObjectModelIntegrationMixin
-from twisted.test.test_tcp import MyClientFactory, MyServerFactory
-from twisted.test.test_tcp import ClosingFactory, ClientStartStopFactory
-
-try:
- from OpenSSL import SSL
-except ImportError:
- useSSL = False
-else:
- from twisted.internet.ssl import ClientContextFactory
- useSSL = True
-
-try:
- socket.socket(socket.AF_INET6, socket.SOCK_STREAM).close()
-except socket.error, e:
- ipv6Skip = str(e)
-else:
- ipv6Skip = None
-
-
-
-if platform.isWindows():
- from twisted.internet.test import _win32ifaces
- getLinkLocalIPv6Addresses = _win32ifaces.win32GetLinkLocalIPv6Addresses
-else:
- try:
- from twisted.internet.test import _posixifaces
- except ImportError:
- getLinkLocalIPv6Addresses = lambda: []
- else:
- getLinkLocalIPv6Addresses = _posixifaces.posixGetLinkLocalIPv6Addresses
-
-
-
-def getLinkLocalIPv6Address():
- """
- Find and return a configured link local IPv6 address including a scope
- identifier using the % separation syntax. If the system has no link local
- IPv6 addresses, raise L{SkipTest} instead.
-
- @raise SkipTest: if no link local address can be found or if the
- C{netifaces} module is not available.
-
- @return: a C{str} giving the address
- """
- addresses = getLinkLocalIPv6Addresses()
- if addresses:
- return addresses[0]
- raise SkipTest("Link local IPv6 address unavailable")
-
-
-
-def connect(client, (host, port)):
- if '%' in host or ':' in host:
- address = socket.getaddrinfo(host, port)[0][4]
- else:
- address = (host, port)
- client.connect(address)
-
-
-
-class FakeSocket(object):
- """
- A fake for L{socket.socket} objects.
-
- @ivar data: A C{str} giving the data which will be returned from
- L{FakeSocket.recv}.
-
- @ivar sendBuffer: A C{list} of the objects passed to L{FakeSocket.send}.
- """
- def __init__(self, data):
- self.data = data
- self.sendBuffer = []
-
- def setblocking(self, blocking):
- self.blocking = blocking
-
- def recv(self, size):
- return self.data
-
- def send(self, bytes):
- """
- I{Send} all of C{bytes} by accumulating it into C{self.sendBuffer}.
-
- @return: The length of C{bytes}, indicating all the data has been
- accepted.
- """
- self.sendBuffer.append(bytes)
- return len(bytes)
-
-
- def shutdown(self, how):
- """
- Shutdown is not implemented. The method is provided since real sockets
- have it and some code expects it. No behavior of L{FakeSocket} is
- affected by a call to it.
- """
-
-
- def close(self):
- """
- Close is not implemented. The method is provided since real sockets
- have it and some code expects it. No behavior of L{FakeSocket} is
- affected by a call to it.
- """
-
-
- def setsockopt(self, *args):
- """
- Setsockopt is not implemented. The method is provided since
- real sockets have it and some code expects it. No behavior of
- L{FakeSocket} is affected by a call to it.
- """
-
-
- def fileno(self):
- """
- Return a fake file descriptor. If actually used, this will have no
- connection to this L{FakeSocket} and will probably cause surprising
- results.
- """
- return 1
-
-
-
-class TestFakeSocket(TestCase):
- """
- Test that the FakeSocket can be used by the doRead method of L{Connection}
- """
-
- def test_blocking(self):
- skt = FakeSocket("someData")
- skt.setblocking(0)
- self.assertEqual(skt.blocking, 0)
-
-
- def test_recv(self):
- skt = FakeSocket("someData")
- self.assertEqual(skt.recv(10), "someData")
-
-
- def test_send(self):
- """
- L{FakeSocket.send} accepts the entire string passed to it, adds it to
- its send buffer, and returns its length.
- """
- skt = FakeSocket("")
- count = skt.send("foo")
- self.assertEqual(count, 3)
- self.assertEqual(skt.sendBuffer, ["foo"])
-
-
-
-class FakeProtocol(Protocol):
- """
- An L{IProtocol} that returns a value from its dataReceived method.
- """
- def dataReceived(self, data):
- """
- Return something other than C{None} to trigger a deprecation warning for
- that behavior.
- """
- return ()
-
-
-
-class _FakeFDSetReactor(object):
- """
- A no-op implementation of L{IReactorFDSet}, which ignores all adds and
- removes.
- """
- implements(IReactorFDSet)
-
- addReader = addWriter = removeReader = removeWriter = (
- lambda self, desc: None)
-
-
-
-class TCPServerTests(TestCase):
- """
- Whitebox tests for L{twisted.internet.tcp.Server}.
- """
- def setUp(self):
- self.reactor = _FakeFDSetReactor()
- class FakePort(object):
- _realPortNumber = 3
- self.skt = FakeSocket("")
- self.protocol = Protocol()
- self.server = Server(
- self.skt, self.protocol, ("", 0), FakePort(), None, self.reactor)
-
-
- def test_writeAfterDisconnect(self):
- """
- L{Server.write} discards bytes passed to it if called after it has lost
- its connection.
- """
- self.server.connectionLost(
- Failure(Exception("Simulated lost connection")))
- self.server.write("hello world")
- self.assertEqual(self.skt.sendBuffer, [])
-
-
- def test_writeAfteDisconnectAfterTLS(self):
- """
- L{Server.write} discards bytes passed to it if called after it has lost
- its connection when the connection had started TLS.
- """
- self.server.TLS = True
- self.test_writeAfterDisconnect()
-
-
- def test_writeSequenceAfterDisconnect(self):
- """
- L{Server.writeSequence} discards bytes passed to it if called after it
- has lost its connection.
- """
- self.server.connectionLost(
- Failure(Exception("Simulated lost connection")))
- self.server.writeSequence(["hello world"])
- self.assertEqual(self.skt.sendBuffer, [])
-
-
- def test_writeSequenceAfteDisconnectAfterTLS(self):
- """
- L{Server.writeSequence} discards bytes passed to it if called after it
- has lost its connection when the connection had started TLS.
- """
- self.server.TLS = True
- self.test_writeSequenceAfterDisconnect()
-
-
-
-class TCPConnectionTests(TestCase):
- """
- Whitebox tests for L{twisted.internet.tcp.Connection}.
- """
- def test_doReadWarningIsRaised(self):
- """
- When an L{IProtocol} implementation that returns a value from its
- C{dataReceived} method, a deprecated warning is emitted.
- """
- skt = FakeSocket("someData")
- protocol = FakeProtocol()
- conn = Connection(skt, protocol)
- conn.doRead()
- warnings = self.flushWarnings([FakeProtocol.dataReceived])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]["message"],
- "Returning a value other than None from "
- "twisted.internet.test.test_tcp.FakeProtocol.dataReceived "
- "is deprecated since Twisted 11.0.0.")
- self.assertEqual(len(warnings), 1)
-
-
- def test_noTLSBeforeStartTLS(self):
- """
- The C{TLS} attribute of a L{Connection} instance is C{False} before
- L{Connection.startTLS} is called.
- """
- skt = FakeSocket("")
- protocol = FakeProtocol()
- conn = Connection(skt, protocol)
- self.assertFalse(conn.TLS)
-
-
- def test_tlsAfterStartTLS(self):
- """
- The C{TLS} attribute of a L{Connection} instance is C{True} after
- L{Connection.startTLS} is called.
- """
- skt = FakeSocket("")
- protocol = FakeProtocol()
- conn = Connection(skt, protocol, reactor=_FakeFDSetReactor())
- conn._tlsClientDefault = True
- conn.startTLS(ClientContextFactory(), True)
- self.assertTrue(conn.TLS)
- if not useSSL:
- test_tlsAfterStartTLS.skip = "No SSL support available"
-
-
-
-class TCPCreator(EndpointCreator):
- """
- Create IPv4 TCP endpoints for L{runProtocolsWithReactor}-based tests.
- """
-
- interface = "127.0.0.1"
-
- def server(self, reactor):
- """
- Create a server-side TCP endpoint.
- """
- return TCP4ServerEndpoint(reactor, 0, interface=self.interface)
-
-
- def client(self, reactor, serverAddress):
- """
- Create a client end point that will connect to the given address.
-
- @type serverAddress: L{IPv4Address}
- """
- return TCP4ClientEndpoint(reactor, self.interface, serverAddress.port)
-
-
-
-class TCP6Creator(TCPCreator):
- """
- Create IPv6 TCP endpoints for
- C{ReactorBuilder.runProtocolsWithReactor}-based tests.
-
- The endpoint types in question here are still the TCP4 variety, since
- these simply pass through IPv6 address literals to the reactor, and we are
- only testing address literals, not name resolution (as name resolution has
- not yet been implemented). See http://twistedmatrix.com/trac/ticket/4470
- for more specific information about new endpoint classes. The naming is
- slightly misleading, but presumably if you're passing an IPv6 literal, you
- know what you're asking for.
- """
- def __init__(self):
- self.interface = getLinkLocalIPv6Address()
-
-
-
-class TCPClientTestsBase(ReactorBuilder, ConnectionTestsMixin,
- TCPClientTestsMixin):
- """
- Base class for builders defining tests related to L{IReactorTCP.connectTCP}.
- """
- requiredInterfaces = (IReactorTCP,)
-
- port = 1234
-
- @property
- def interface(self):
- """
- Return the interface attribute from the endpoints object.
- """
- return self.endpoints.interface
-
-
-
-class TCP4ClientTestsBuilder(TCPClientTestsBase):
- """
- Builder configured with IPv4 parameters for tests related to
- L{IReactorTCP.connectTCP}.
- """
- fakeDomainName = 'some-fake.domain.example.com'
- family = socket.AF_INET
- addressClass = IPv4Address
-
- endpoints = TCPCreator()
-
-
-
-class TCP6ClientTestsBuilder(TCPClientTestsBase):
- """
- Builder configured with IPv6 parameters for tests related to
- L{IReactorTCP.connectTCP}.
- """
- if ipv6Skip:
- skip = ipv6Skip
-
- family = socket.AF_INET6
- addressClass = IPv6Address
-
- def setUp(self):
- # Only create this object here, so that it won't be created if tests
- # are being skipped:
- self.endpoints = TCP6Creator()
- # This is used by test_addresses to test the distinction between the
- # resolved name and the name on the socket itself. All the same
- # invariants should hold, but giving back an IPv6 address from a
- # resolver is not something the reactor can handle, so instead, we make
- # it so that the connect call for the IPv6 address test simply uses an
- # address literal.
- self.fakeDomainName = self.endpoints.interface
-
-
-
-class TCPConnectorTestsBuilder(ReactorBuilder):
- """
- Tests for the L{IConnector} provider returned by L{IReactorTCP.connectTCP}.
- """
- requiredInterfaces = (IReactorTCP,)
-
- def test_connectorIdentity(self):
- """
- L{IReactorTCP.connectTCP} returns an object which provides
- L{IConnector}. The destination of the connector is the address which
- was passed to C{connectTCP}. The same connector object is passed to
- the factory's C{startedConnecting} method as to the factory's
- C{clientConnectionLost} method.
- """
- serverFactory = ClosingFactory()
- reactor = self.buildReactor()
- tcpPort = reactor.listenTCP(0, serverFactory, interface=self.interface)
- serverFactory.port = tcpPort
- portNumber = tcpPort.getHost().port
-
- seenConnectors = []
- seenFailures = []
-
- clientFactory = ClientStartStopFactory()
- clientFactory.clientConnectionLost = (
- lambda connector, reason: (seenConnectors.append(connector),
- seenFailures.append(reason)))
- clientFactory.startedConnecting = seenConnectors.append
-
- connector = reactor.connectTCP(self.interface, portNumber,
- clientFactory)
- self.assertTrue(IConnector.providedBy(connector))
- dest = connector.getDestination()
- self.assertEqual(dest.type, "TCP")
- self.assertEqual(dest.host, self.interface)
- self.assertEqual(dest.port, portNumber)
-
- clientFactory.whenStopped.addBoth(lambda _: reactor.stop())
-
- self.runReactor(reactor)
-
- seenFailures[0].trap(ConnectionDone)
- self.assertEqual(seenConnectors, [connector, connector])
-
-
- def test_userFail(self):
- """
- Calling L{IConnector.stopConnecting} in C{Factory.startedConnecting}
- results in C{Factory.clientConnectionFailed} being called with
- L{error.UserError} as the reason.
- """
- serverFactory = MyServerFactory()
- reactor = self.buildReactor()
- tcpPort = reactor.listenTCP(0, serverFactory, interface=self.interface)
- portNumber = tcpPort.getHost().port
-
- fatalErrors = []
-
- def startedConnecting(connector):
- try:
- connector.stopConnecting()
- except Exception:
- fatalErrors.append(Failure())
- reactor.stop()
-
- clientFactory = ClientStartStopFactory()
- clientFactory.startedConnecting = startedConnecting
-
- clientFactory.whenStopped.addBoth(lambda _: reactor.stop())
-
- reactor.callWhenRunning(lambda: reactor.connectTCP(self.interface,
- portNumber,
- clientFactory))
-
- self.runReactor(reactor)
-
- if fatalErrors:
- self.fail(fatalErrors[0].getTraceback())
- clientFactory.reason.trap(UserError)
- self.assertEqual(clientFactory.failed, 1)
-
-
- def test_reconnect(self):
- """
- Calling L{IConnector.connect} in C{Factory.clientConnectionLost} causes
- a new connection attempt to be made.
- """
- serverFactory = ClosingFactory()
- reactor = self.buildReactor()
- tcpPort = reactor.listenTCP(0, serverFactory, interface=self.interface)
- serverFactory.port = tcpPort
- portNumber = tcpPort.getHost().port
-
- clientFactory = MyClientFactory()
-
- def clientConnectionLost(connector, reason):
- connector.connect()
- clientFactory.clientConnectionLost = clientConnectionLost
- reactor.connectTCP(self.interface, portNumber, clientFactory)
-
- protocolMadeAndClosed = []
- def reconnectFailed(ignored):
- p = clientFactory.protocol
- protocolMadeAndClosed.append((p.made, p.closed))
- reactor.stop()
-
- clientFactory.failDeferred.addCallback(reconnectFailed)
-
- self.runReactor(reactor)
-
- clientFactory.reason.trap(ConnectionRefusedError)
- self.assertEqual(protocolMadeAndClosed, [(1, 1)])
-
-
-
-class TCP4ConnectorTestsBuilder(TCPConnectorTestsBuilder):
- interface = '127.0.0.1'
- family = socket.AF_INET
- addressClass = IPv4Address
-
-
-
-class TCP6ConnectorTestsBuilder(TCPConnectorTestsBuilder):
- family = socket.AF_INET6
- addressClass = IPv6Address
-
- if ipv6Skip:
- skip = ipv6Skip
-
- def setUp(self):
- self.interface = getLinkLocalIPv6Address()
-
-
-
-def createTestSocket(test, addressFamily, socketType):
- """
- Create a socket for the duration of the given test.
-
- @param test: the test to add cleanup to.
-
- @param addressFamily: an C{AF_*} constant
-
- @param socketType: a C{SOCK_*} constant.
-
- @return: a socket object.
- """
- skt = socket.socket(addressFamily, socketType)
- test.addCleanup(skt.close)
- return skt
-
-
-
-class StreamTransportTestsMixin(LogObserverMixin):
- """
- Mixin defining tests which apply to any port/connection based transport.
- """
- def test_startedListeningLogMessage(self):
- """
- When a port starts, a message including a description of the associated
- factory is logged.
- """
- loggedMessages = self.observe()
- reactor = self.buildReactor()
- class SomeFactory(ServerFactory):
- implements(ILoggingContext)
- def logPrefix(self):
- return "Crazy Factory"
- factory = SomeFactory()
- p = self.getListeningPort(reactor, factory)
- expectedMessage = self.getExpectedStartListeningLogMessage(
- p, "Crazy Factory")
- self.assertEqual((expectedMessage,), loggedMessages[0]['message'])
-
-
- def test_connectionLostLogMsg(self):
- """
- When a connection is lost, an informative message should be logged
- (see L{getExpectedConnectionLostLogMsg}): an address identifying
- the port and the fact that it was closed.
- """
-
- loggedMessages = []
- def logConnectionLostMsg(eventDict):
- loggedMessages.append(log.textFromEventDict(eventDict))
-
- reactor = self.buildReactor()
- p = self.getListeningPort(reactor, ServerFactory())
- expectedMessage = self.getExpectedConnectionLostLogMsg(p)
- log.addObserver(logConnectionLostMsg)
-
- def stopReactor(ignored):
- log.removeObserver(logConnectionLostMsg)
- reactor.stop()
-
- def doStopListening():
- log.addObserver(logConnectionLostMsg)
- maybeDeferred(p.stopListening).addCallback(stopReactor)
-
- reactor.callWhenRunning(doStopListening)
- reactor.run()
-
- self.assertIn(expectedMessage, loggedMessages)
-
-
- def test_allNewStyle(self):
- """
- The L{IListeningPort} object is an instance of a class with no
- classic classes in its hierarchy.
- """
- reactor = self.buildReactor()
- port = self.getListeningPort(reactor, ServerFactory())
- self.assertFullyNewStyle(port)
-
-
-class ListenTCPMixin(object):
- """
- Mixin which uses L{IReactorTCP.listenTCP} to hand out listening TCP ports.
- """
- def getListeningPort(self, reactor, factory, port=0, interface=''):
- """
- Get a TCP port from a reactor.
- """
- return reactor.listenTCP(port, factory, interface=interface)
-
-
-
-class SocketTCPMixin(object):
- """
- Mixin which uses L{IReactorSocket.adoptStreamPort} to hand out listening TCP
- ports.
- """
- def getListeningPort(self, reactor, factory, port=0, interface=''):
- """
- Get a TCP port from a reactor, wrapping an already-initialized file
- descriptor.
- """
- if IReactorSocket.providedBy(reactor):
- if ':' in interface:
- domain = socket.AF_INET6
- address = socket.getaddrinfo(interface, port)[0][4]
- else:
- domain = socket.AF_INET
- address = (interface, port)
- portSock = socket.socket(domain)
- portSock.bind(address)
- portSock.listen(3)
- portSock.setblocking(False)
- try:
- return reactor.adoptStreamPort(
- portSock.fileno(), portSock.family, factory)
- finally:
- # The socket should still be open; fileno will raise if it is
- # not.
- portSock.fileno()
- # Now clean it up, because the rest of the test does not need
- # it.
- portSock.close()
- else:
- raise SkipTest("Reactor does not provide IReactorSocket")
-
-
-
-class TCPPortTestsMixin(object):
- """
- Tests for L{IReactorTCP.listenTCP}
- """
- requiredInterfaces = (IReactorTCP,)
-
- def getExpectedStartListeningLogMessage(self, port, factory):
- """
- Get the message expected to be logged when a TCP port starts listening.
- """
- return "%s starting on %d" % (
- factory, port.getHost().port)
-
-
- def getExpectedConnectionLostLogMsg(self, port):
- """
- Get the expected connection lost message for a TCP port.
- """
- return "(TCP Port %s Closed)" % (port.getHost().port,)
-
-
- def test_portGetHostOnIPv4(self):
- """
- When no interface is passed to L{IReactorTCP.listenTCP}, the returned
- listening port listens on an IPv4 address.
- """
- reactor = self.buildReactor()
- port = self.getListeningPort(reactor, ServerFactory())
- address = port.getHost()
- self.assertIsInstance(address, IPv4Address)
-
-
- def test_portGetHostOnIPv6(self):
- """
- When listening on an IPv6 address, L{IListeningPort.getHost} returns
- an L{IPv6Address} with C{host} and C{port} attributes reflecting the
- address the port is bound to.
- """
- reactor = self.buildReactor()
- host, portNumber = findFreePort(
- family=socket.AF_INET6, interface='::1')[:2]
- port = self.getListeningPort(
- reactor, ServerFactory(), portNumber, host)
- address = port.getHost()
- self.assertIsInstance(address, IPv6Address)
- self.assertEqual('::1', address.host)
- self.assertEqual(portNumber, address.port)
- if ipv6Skip:
- test_portGetHostOnIPv6.skip = ipv6Skip
-
-
- def test_portGetHostOnIPv6ScopeID(self):
- """
- When a link-local IPv6 address including a scope identifier is passed as
- the C{interface} argument to L{IReactorTCP.listenTCP}, the resulting
- L{IListeningPort} reports its address as an L{IPv6Address} with a host
- value that includes the scope identifier.
- """
- linkLocal = getLinkLocalIPv6Address()
- reactor = self.buildReactor()
- port = self.getListeningPort(reactor, ServerFactory(), 0, linkLocal)
- address = port.getHost()
- self.assertIsInstance(address, IPv6Address)
- self.assertEqual(linkLocal, address.host)
- if ipv6Skip:
- test_portGetHostOnIPv6ScopeID.skip = ipv6Skip
-
-
- def _buildProtocolAddressTest(self, client, interface):
- """
- Connect C{client} to a server listening on C{interface} started with
- L{IReactorTCP.listenTCP} and return the address passed to the factory's
- C{buildProtocol} method.
-
- @param client: A C{SOCK_STREAM} L{socket.socket} created with an address
- family such that it will be able to connect to a server listening on
- C{interface}.
-
- @param interface: A C{str} giving an address for a server to listen on.
- This should almost certainly be the loopback address for some
- address family supported by L{IReactorTCP.listenTCP}.
-
- @return: Whatever object, probably an L{IAddress} provider, is passed to
- a server factory's C{buildProtocol} method when C{client}
- establishes a connection.
- """
- class ObserveAddress(ServerFactory):
- def buildProtocol(self, address):
- reactor.stop()
- self.observedAddress = address
- return Protocol()
-
- factory = ObserveAddress()
- reactor = self.buildReactor()
- port = self.getListeningPort(reactor, factory, 0, interface)
- client.setblocking(False)
- try:
- connect(client, (port.getHost().host, port.getHost().port))
- except socket.error, (errnum, message):
- self.assertIn(errnum, (errno.EINPROGRESS, errno.EWOULDBLOCK))
-
- self.runReactor(reactor)
-
- return factory.observedAddress
-
-
- def test_buildProtocolIPv4Address(self):
- """
- When a connection is accepted over IPv4, an L{IPv4Address} is passed
- to the factory's C{buildProtocol} method giving the peer's address.
- """
- interface = '127.0.0.1'
- client = createTestSocket(self, socket.AF_INET, socket.SOCK_STREAM)
- observedAddress = self._buildProtocolAddressTest(client, interface)
- self.assertEqual(
- IPv4Address('TCP', *client.getsockname()), observedAddress)
-
-
- def test_buildProtocolIPv6Address(self):
- """
- When a connection is accepted to an IPv6 address, an L{IPv6Address} is
- passed to the factory's C{buildProtocol} method giving the peer's
- address.
- """
- interface = '::1'
- client = createTestSocket(self, socket.AF_INET6, socket.SOCK_STREAM)
- observedAddress = self._buildProtocolAddressTest(client, interface)
- self.assertEqual(
- IPv6Address('TCP', *client.getsockname()[:2]), observedAddress)
- if ipv6Skip:
- test_buildProtocolIPv6Address.skip = ipv6Skip
-
-
- def test_buildProtocolIPv6AddressScopeID(self):
- """
- When a connection is accepted to a link-local IPv6 address, an
- L{IPv6Address} is passed to the factory's C{buildProtocol} method
- giving the peer's address, including a scope identifier.
- """
- interface = getLinkLocalIPv6Address()
- client = createTestSocket(self, socket.AF_INET6, socket.SOCK_STREAM)
- observedAddress = self._buildProtocolAddressTest(client, interface)
- self.assertEqual(
- IPv6Address('TCP', *client.getsockname()[:2]), observedAddress)
- if ipv6Skip:
- test_buildProtocolIPv6AddressScopeID.skip = ipv6Skip
-
-
- def _serverGetConnectionAddressTest(self, client, interface, which):
- """
- Connect C{client} to a server listening on C{interface} started with
- L{IReactorTCP.listenTCP} and return the address returned by one of the
- server transport's address lookup methods, C{getHost} or C{getPeer}.
-
- @param client: A C{SOCK_STREAM} L{socket.socket} created with an address
- family such that it will be able to connect to a server listening on
- C{interface}.
-
- @param interface: A C{str} giving an address for a server to listen on.
- This should almost certainly be the loopback address for some
- address family supported by L{IReactorTCP.listenTCP}.
-
- @param which: A C{str} equal to either C{"getHost"} or C{"getPeer"}
- determining which address will be returned.
-
- @return: Whatever object, probably an L{IAddress} provider, is returned
- from the method indicated by C{which}.
- """
- class ObserveAddress(Protocol):
- def makeConnection(self, transport):
- reactor.stop()
- self.factory.address = getattr(transport, which)()
-
- reactor = self.buildReactor()
- factory = ServerFactory()
- factory.protocol = ObserveAddress
- port = self.getListeningPort(reactor, factory, 0, interface)
- client.setblocking(False)
- try:
- connect(client, (port.getHost().host, port.getHost().port))
- except socket.error, (errnum, message):
- self.assertIn(errnum, (errno.EINPROGRESS, errno.EWOULDBLOCK))
- self.runReactor(reactor)
- return factory.address
-
-
- def test_serverGetHostOnIPv4(self):
- """
- When a connection is accepted over IPv4, the server
- L{ITransport.getHost} method returns an L{IPv4Address} giving the
- address on which the server accepted the connection.
- """
- interface = '127.0.0.1'
- client = createTestSocket(self, socket.AF_INET, socket.SOCK_STREAM)
- hostAddress = self._serverGetConnectionAddressTest(
- client, interface, 'getHost')
- self.assertEqual(
- IPv4Address('TCP', *client.getpeername()), hostAddress)
-
-
- def test_serverGetHostOnIPv6(self):
- """
- When a connection is accepted over IPv6, the server
- L{ITransport.getHost} method returns an L{IPv6Address} giving the
- address on which the server accepted the connection.
- """
- interface = '::1'
- client = createTestSocket(self, socket.AF_INET6, socket.SOCK_STREAM)
- hostAddress = self._serverGetConnectionAddressTest(
- client, interface, 'getHost')
- self.assertEqual(
- IPv6Address('TCP', *client.getpeername()[:2]), hostAddress)
- if ipv6Skip:
- test_serverGetHostOnIPv6.skip = ipv6Skip
-
-
- def test_serverGetHostOnIPv6ScopeID(self):
- """
- When a connection is accepted over IPv6, the server
- L{ITransport.getHost} method returns an L{IPv6Address} giving the
- address on which the server accepted the connection, including the scope
- identifier.
- """
- interface = getLinkLocalIPv6Address()
- client = createTestSocket(self, socket.AF_INET6, socket.SOCK_STREAM)
- hostAddress = self._serverGetConnectionAddressTest(
- client, interface, 'getHost')
- self.assertEqual(
- IPv6Address('TCP', *client.getpeername()[:2]), hostAddress)
- if ipv6Skip:
- test_serverGetHostOnIPv6ScopeID.skip = ipv6Skip
-
-
- def test_serverGetPeerOnIPv4(self):
- """
- When a connection is accepted over IPv4, the server
- L{ITransport.getPeer} method returns an L{IPv4Address} giving the
- address of the remote end of the connection.
- """
- interface = '127.0.0.1'
- client = createTestSocket(self, socket.AF_INET, socket.SOCK_STREAM)
- peerAddress = self._serverGetConnectionAddressTest(
- client, interface, 'getPeer')
- self.assertEqual(
- IPv4Address('TCP', *client.getsockname()), peerAddress)
-
-
- def test_serverGetPeerOnIPv6(self):
- """
- When a connection is accepted over IPv6, the server
- L{ITransport.getPeer} method returns an L{IPv6Address} giving the
- address on the remote end of the connection.
- """
- interface = '::1'
- client = createTestSocket(self, socket.AF_INET6, socket.SOCK_STREAM)
- peerAddress = self._serverGetConnectionAddressTest(
- client, interface, 'getPeer')
- self.assertEqual(
- IPv6Address('TCP', *client.getsockname()[:2]), peerAddress)
- if ipv6Skip:
- test_serverGetPeerOnIPv6.skip = ipv6Skip
-
-
- def test_serverGetPeerOnIPv6ScopeID(self):
- """
- When a connection is accepted over IPv6, the server
- L{ITransport.getPeer} method returns an L{IPv6Address} giving the
- address on the remote end of the connection, including the scope
- identifier.
- """
- interface = getLinkLocalIPv6Address()
- client = createTestSocket(self, socket.AF_INET6, socket.SOCK_STREAM)
- peerAddress = self._serverGetConnectionAddressTest(
- client, interface, 'getPeer')
- self.assertEqual(
- IPv6Address('TCP', *client.getsockname()[:2]), peerAddress)
- if ipv6Skip:
- test_serverGetPeerOnIPv6ScopeID.skip = ipv6Skip
-
-
-
-class TCPPortTestsBuilder(ReactorBuilder, ListenTCPMixin, TCPPortTestsMixin,
- ObjectModelIntegrationMixin,
- StreamTransportTestsMixin):
- pass
-
-
-
-class TCPFDPortTestsBuilder(ReactorBuilder, SocketTCPMixin, TCPPortTestsMixin,
- ObjectModelIntegrationMixin,
- StreamTransportTestsMixin):
- pass
-
-
-
-class StopStartReadingProtocol(Protocol):
- """
- Protocol that pauses and resumes the transport a few times
- """
-
- def connectionMade(self):
- self.data = ''
- self.pauseResumeProducing(3)
-
-
- def pauseResumeProducing(self, counter):
- """
- Toggle transport read state, then count down.
- """
- self.transport.pauseProducing()
- self.transport.resumeProducing()
- if counter:
- self.factory.reactor.callLater(0,
- self.pauseResumeProducing, counter - 1)
- else:
- self.factory.reactor.callLater(0,
- self.factory.ready.callback, self)
-
-
- def dataReceived(self, data):
- log.msg('got data', len(data))
- self.data += data
- if len(self.data) == 4*4096:
- self.factory.stop.callback(self.data)
-
-
-
-class TCPConnectionTestsBuilder(ReactorBuilder):
- """
- Builder defining tests relating to L{twisted.internet.tcp.Connection}.
- """
- requiredInterfaces = (IReactorTCP,)
-
- def test_stopStartReading(self):
- """
- This test verifies transport socket read state after multiple
- pause/resumeProducing calls.
- """
- sf = ServerFactory()
- reactor = sf.reactor = self.buildReactor()
-
- skippedReactors = ["Glib2Reactor", "Gtk2Reactor"]
- reactorClassName = reactor.__class__.__name__
- if reactorClassName in skippedReactors and platform.isWindows():
- raise SkipTest(
- "This test is broken on gtk/glib under Windows.")
-
- sf.protocol = StopStartReadingProtocol
- sf.ready = Deferred()
- sf.stop = Deferred()
- p = reactor.listenTCP(0, sf)
- port = p.getHost().port
- def proceed(protos, port):
- """
- Send several IOCPReactor's buffers' worth of data.
- """
- self.assertTrue(protos[0])
- self.assertTrue(protos[1])
- protos = protos[0][1], protos[1][1]
- protos[0].transport.write('x' * (2 * 4096) + 'y' * (2 * 4096))
- return (sf.stop.addCallback(cleanup, protos, port)
- .addCallback(lambda ign: reactor.stop()))
-
- def cleanup(data, protos, port):
- """
- Make sure IOCPReactor didn't start several WSARecv operations
- that clobbered each other's results.
- """
- self.assertEqual(data, 'x'*(2*4096) + 'y'*(2*4096),
- 'did not get the right data')
- return DeferredList([
- maybeDeferred(protos[0].transport.loseConnection),
- maybeDeferred(protos[1].transport.loseConnection),
- maybeDeferred(port.stopListening)])
-
- cc = TCP4ClientEndpoint(reactor, '127.0.0.1', port)
- cf = ClientFactory()
- cf.protocol = Protocol
- d = DeferredList([cc.connect(cf), sf.ready]).addCallback(proceed, p)
- d.addErrback(log.err)
- self.runReactor(reactor)
-
-
- def test_connectionLostAfterPausedTransport(self):
- """
- Alice connects to Bob. Alice writes some bytes and then shuts down the
- connection. Bob receives the bytes from the connection and then pauses
- the transport object. Shortly afterwards Bob resumes the transport
- object. At that point, Bob is notified that the connection has been
- closed.
-
- This is no problem for most reactors. The underlying event notification
- API will probably just remind them that the connection has been closed.
- It is a little tricky for win32eventreactor (MsgWaitForMultipleObjects).
- MsgWaitForMultipleObjects will only deliver the close notification once.
- The reactor needs to remember that notification until Bob resumes the
- transport.
- """
- class Pauser(ConnectableProtocol):
- def __init__(self):
- self.events = []
-
- def dataReceived(self, bytes):
- self.events.append("paused")
- self.transport.pauseProducing()
- self.reactor.callLater(0, self.resume)
-
- def resume(self):
- self.events.append("resumed")
- self.transport.resumeProducing()
-
- def connectionLost(self, reason):
- # This is the event you have been waiting for.
- self.events.append("lost")
- ConnectableProtocol.connectionLost(self, reason)
-
- class Client(ConnectableProtocol):
- def connectionMade(self):
- self.transport.write("some bytes for you")
- self.transport.loseConnection()
-
- pauser = Pauser()
- runProtocolsWithReactor(self, pauser, Client(), TCPCreator())
- self.assertEqual(pauser.events, ["paused", "resumed", "lost"])
-
-
- def test_doubleHalfClose(self):
- """
- If one side half-closes its connection, and then the other side of the
- connection calls C{loseWriteConnection}, and then C{loseConnection} in
- {writeConnectionLost}, the connection is closed correctly.
-
- This rather obscure case used to fail (see ticket #3037).
- """
- class ListenerProtocol(ConnectableProtocol):
- implements(IHalfCloseableProtocol)
-
- def readConnectionLost(self):
- self.transport.loseWriteConnection()
-
- def writeConnectionLost(self):
- self.transport.loseConnection()
-
- class Client(ConnectableProtocol):
- def connectionMade(self):
- self.transport.loseConnection()
-
- # If test fails, reactor won't stop and we'll hit timeout:
- runProtocolsWithReactor(
- self, ListenerProtocol(), Client(), TCPCreator())
-
-
-
-class WriteSequenceTestsMixin(object):
- """
- Test for L{twisted.internet.abstract.FileDescriptor.writeSequence}.
- """
- requiredInterfaces = (IReactorTCP,)
-
- def setWriteBufferSize(self, transport, value):
- """
- Set the write buffer size for the given transport, mananing possible
- differences (ie, IOCP). Bug #4322 should remove the need of that hack.
- """
- if getattr(transport, "writeBufferSize", None) is not None:
- transport.writeBufferSize = value
- else:
- transport.bufferSize = value
-
-
- def test_writeSequeceWithoutWrite(self):
- """
- C{writeSequence} sends the data even if C{write} hasn't been called.
- """
-
- def connected(protocols):
- client, server, port = protocols
-
- def dataReceived(data):
- log.msg("data received: %r" % data)
- self.assertEqual(data, "Some sequence splitted")
- client.transport.loseConnection()
-
- server.dataReceived = dataReceived
-
- client.transport.writeSequence(["Some ", "sequence ", "splitted"])
-
- reactor = self.buildReactor()
- d = self.getConnectedClientAndServer(reactor, "127.0.0.1",
- socket.AF_INET)
- d.addCallback(connected)
- d.addErrback(log.err)
- self.runReactor(reactor)
-
-
- def test_writeSequenceWithUnicodeRaisesException(self):
- """
- C{writeSequence} with an element in the sequence of type unicode raises
- C{TypeError}.
- """
-
- def connected(protocols):
- client, server, port = protocols
-
- exc = self.assertRaises(
- TypeError,
- server.transport.writeSequence, [u"Unicode is not kosher"])
-
- self.assertEqual(str(exc), "Data must not be unicode")
-
- server.transport.loseConnection()
-
- reactor = self.buildReactor()
- d = self.getConnectedClientAndServer(reactor, "127.0.0.1",
- socket.AF_INET)
- d.addCallback(connected)
- d.addErrback(log.err)
- self.runReactor(reactor)
-
-
- def test_streamingProducer(self):
- """
- C{writeSequence} pauses its streaming producer if too much data is
- buffered, and then resumes it.
- """
-
- class SaveActionProducer(object):
- implements(IPushProducer)
- client = None
- server = None
-
- def __init__(self):
- self.actions = []
-
- def pauseProducing(self):
- self.actions.append("pause")
-
- def resumeProducing(self):
- self.actions.append("resume")
- # Unregister the producer so the connection can close
- self.client.transport.unregisterProducer()
- # This is why the code below waits for the server connection
- # first - so we have it to close here. We close the server
- # side because win32evenreactor cannot reliably observe us
- # closing the client side (#5285).
- self.server.transport.loseConnection()
-
- def stopProducing(self):
- self.actions.append("stop")
-
- producer = SaveActionProducer()
-
- def connected(protocols):
- client, server = protocols[:2]
- producer.client = client
- producer.server = server
- # Register a streaming producer and verify that it gets paused
- # after it writes more than the local send buffer can hold.
- client.transport.registerProducer(producer, True)
- self.assertEqual(producer.actions, [])
- self.setWriteBufferSize(client.transport, 500)
- client.transport.writeSequence(["x" * 50] * 20)
- self.assertEqual(producer.actions, ["pause"])
-
- reactor = self.buildReactor()
- d = self.getConnectedClientAndServer(reactor, "127.0.0.1",
- socket.AF_INET)
- d.addCallback(connected)
- d.addErrback(log.err)
- self.runReactor(reactor)
- # After the send buffer gets a chance to empty out a bit, the producer
- # should be resumed.
- self.assertEqual(producer.actions, ["pause", "resume"])
-
-
- def test_nonStreamingProducer(self):
- """
- C{writeSequence} pauses its producer if too much data is buffered only
- if this is a streaming producer.
- """
- test = self
-
- class SaveActionProducer(object):
- implements(IPullProducer)
- client = None
-
- def __init__(self):
- self.actions = []
-
- def resumeProducing(self):
- self.actions.append("resume")
- if self.actions.count("resume") == 2:
- self.client.transport.stopConsuming()
- else:
- test.setWriteBufferSize(self.client.transport, 500)
- self.client.transport.writeSequence(["x" * 50] * 20)
-
- def stopProducing(self):
- self.actions.append("stop")
-
-
- producer = SaveActionProducer()
-
- def connected(protocols):
- client = protocols[0]
- producer.client = client
- # Register a non-streaming producer and verify that it is resumed
- # immediately.
- client.transport.registerProducer(producer, False)
- self.assertEqual(producer.actions, ["resume"])
-
- reactor = self.buildReactor()
- d = self.getConnectedClientAndServer(reactor, "127.0.0.1",
- socket.AF_INET)
- d.addCallback(connected)
- d.addErrback(log.err)
- self.runReactor(reactor)
- # After the local send buffer empties out, the producer should be
- # resumed again.
- self.assertEqual(producer.actions, ["resume", "resume"])
-
-
-
-class TCPTransportServerAddressTestMixin(object):
- """
- Test mixing for TCP server address building and log prefix.
- """
-
- def getConnectedClientAndServer(self, reactor, interface, addressFamily):
- """
- Helper method returnine a L{Deferred} firing with a tuple of a client
- protocol, a server protocol, and a running TCP port.
- """
- raise NotImplementedError()
-
-
- def _testServerAddress(self, interface, addressFamily, adressClass):
- """
- Helper method to test TCP server addresses on either IPv4 or IPv6.
- """
-
- def connected(protocols):
- client, server, port = protocols
-
- self.assertEqual(
- "<AccumulatingProtocol #%s on %s>" %
- (server.transport.sessionno, port.getHost().port),
- str(server.transport))
-
- self.assertEqual(
- "AccumulatingProtocol,%s,%s" %
- (server.transport.sessionno, interface),
- server.transport.logstr)
-
- [peerAddress] = server.factory.peerAddresses
- self.assertIsInstance(peerAddress, adressClass)
- self.assertEqual('TCP', peerAddress.type)
- self.assertEqual(interface, peerAddress.host)
-
- server.transport.loseConnection()
-
- reactor = self.buildReactor()
- d = self.getConnectedClientAndServer(reactor, interface, addressFamily)
- d.addCallback(connected)
- d.addErrback(log.err)
- self.runReactor(reactor)
-
-
- def test_serverAddressTCP4(self):
- """
- L{Server} instances have a string representation indicating on which
- port they're running, and the connected address is stored on the
- C{peerAddresses} attribute of the factory.
- """
- return self._testServerAddress("127.0.0.1", socket.AF_INET,
- IPv4Address)
-
-
- def test_serverAddressTCP6(self):
- """
- IPv6 L{Server} instances have a string representation indicating on
- which port they're running, and the connected address is stored on the
- C{peerAddresses} attribute of the factory.
- """
- return self._testServerAddress(getLinkLocalIPv6Address(),
- socket.AF_INET6, IPv6Address)
-
- if ipv6Skip:
- test_serverAddressTCP6.skip = ipv6Skip
-
-
-
-class TCPTransportTestsBuilder(TCPTransportServerAddressTestMixin,
- WriteSequenceTestsMixin, ReactorBuilder):
- """
- Test standard L{ITCPTransport}s built with C{listenTCP} and C{connectTCP}.
- """
-
- def getConnectedClientAndServer(self, reactor, interface, addressFamily):
- """
- Return a L{Deferred} firing with a L{MyClientFactory} and
- L{MyServerFactory} connected pair, and the listening C{Port}.
- """
- server = MyServerFactory()
- server.protocolConnectionMade = Deferred()
- server.protocolConnectionLost = Deferred()
-
- client = MyClientFactory()
- client.protocolConnectionMade = Deferred()
- client.protocolConnectionLost = Deferred()
-
- port = reactor.listenTCP(0, server, interface=interface)
-
- lostDeferred = gatherResults([client.protocolConnectionLost,
- server.protocolConnectionLost])
- def stop(result):
- reactor.stop()
- return result
-
- lostDeferred.addBoth(stop)
-
- startDeferred = gatherResults([client.protocolConnectionMade,
- server.protocolConnectionMade])
-
- deferred = Deferred()
-
- def start(protocols):
- client, server = protocols
- log.msg("client connected %s" % client)
- log.msg("server connected %s" % server)
- deferred.callback((client, server, port))
-
- startDeferred.addCallback(start)
-
- reactor.connectTCP(interface, port.getHost().port, client)
-
- return deferred
-
-
-
-class AdoptStreamConnectionTestsBuilder(TCPTransportServerAddressTestMixin,
- WriteSequenceTestsMixin,
- ReactorBuilder):
- """
- Test server transports built using C{adoptStreamConnection}.
- """
-
- requiredInterfaces = (IReactorFDSet, IReactorSocket)
-
- def getConnectedClientAndServer(self, reactor, interface, addressFamily):
- """
- Return a L{Deferred} firing with a L{MyClientFactory} and
- L{MyServerFactory} connected pair, and the listening C{Port}. The
- particularity is that the server protocol has been obtained after doing
- a C{adoptStreamConnection} against the original server connection.
- """
- firstServer = MyServerFactory()
- firstServer.protocolConnectionMade = Deferred()
-
- server = MyServerFactory()
- server.protocolConnectionMade = Deferred()
- server.protocolConnectionLost = Deferred()
-
- client = MyClientFactory()
- client.protocolConnectionMade = Deferred()
- client.protocolConnectionLost = Deferred()
-
- port = reactor.listenTCP(0, firstServer, interface=interface)
-
- def firtServerConnected(proto):
- reactor.removeReader(proto.transport)
- reactor.removeWriter(proto.transport)
- reactor.adoptStreamConnection(
- proto.transport.fileno(), addressFamily, server)
-
- firstServer.protocolConnectionMade.addCallback(firtServerConnected)
-
- lostDeferred = gatherResults([client.protocolConnectionLost,
- server.protocolConnectionLost])
- def stop(result):
- if reactor.running:
- reactor.stop()
- return result
-
- lostDeferred.addBoth(stop)
-
- deferred = Deferred()
- deferred.addErrback(stop)
-
- startDeferred = gatherResults([client.protocolConnectionMade,
- server.protocolConnectionMade])
- def start(protocols):
- client, server = protocols
- log.msg("client connected %s" % client)
- log.msg("server connected %s" % server)
- deferred.callback((client, server, port))
-
- startDeferred.addCallback(start)
-
- reactor.connectTCP(interface, port.getHost().port, client)
- return deferred
-
-
-
-globals().update(TCP4ClientTestsBuilder.makeTestCaseClasses())
-globals().update(TCP6ClientTestsBuilder.makeTestCaseClasses())
-globals().update(TCPPortTestsBuilder.makeTestCaseClasses())
-globals().update(TCPFDPortTestsBuilder.makeTestCaseClasses())
-globals().update(TCPConnectionTestsBuilder.makeTestCaseClasses())
-globals().update(TCP4ConnectorTestsBuilder.makeTestCaseClasses())
-globals().update(TCP6ConnectorTestsBuilder.makeTestCaseClasses())
-globals().update(TCPTransportTestsBuilder.makeTestCaseClasses())
-globals().update(AdoptStreamConnectionTestsBuilder.makeTestCaseClasses())
-
-
-
-class ServerAbortsTwice(ConnectableProtocol):
- """
- Call abortConnection() twice.
- """
-
- def dataReceived(self, data):
- self.transport.abortConnection()
- self.transport.abortConnection()
-
-
-
-class ServerAbortsThenLoses(ConnectableProtocol):
- """
- Call abortConnection() followed by loseConnection().
- """
-
- def dataReceived(self, data):
- self.transport.abortConnection()
- self.transport.loseConnection()
-
-
-
-class AbortServerWritingProtocol(ConnectableProtocol):
- """
- Protocol that writes data upon connection.
- """
-
- def connectionMade(self):
- """
- Tell the client that the connection is set up and it's time to abort.
- """
- self.transport.write("ready")
-
-
-
-class ReadAbortServerProtocol(AbortServerWritingProtocol):
- """
- Server that should never receive any data, except 'X's which are written
- by the other side of the connection before abortConnection, and so might
- possibly arrive.
- """
-
- def dataReceived(self, data):
- if data.replace('X', ''):
- raise Exception("Unexpectedly received data.")
-
-
-
-class NoReadServer(ConnectableProtocol):
- """
- Stop reading immediately on connection.
-
- This simulates a lost connection that will cause the other side to time
- out, and therefore call abortConnection().
- """
-
- def connectionMade(self):
- self.transport.stopReading()
-
-
-
-class EventualNoReadServer(ConnectableProtocol):
- """
- Like NoReadServer, except we Wait until some bytes have been delivered
- before stopping reading. This means TLS handshake has finished, where
- applicable.
- """
-
- gotData = False
- stoppedReading = False
-
-
- def dataReceived(self, data):
- if not self.gotData:
- self.gotData = True
- self.transport.registerProducer(self, False)
- self.transport.write("hello")
-
-
- def resumeProducing(self):
- if self.stoppedReading:
- return
- self.stoppedReading = True
- # We've written out the data:
- self.transport.stopReading()
-
-
- def pauseProducing(self):
- pass
-
-
- def stopProducing(self):
- pass
-
-
-
-class BaseAbortingClient(ConnectableProtocol):
- """
- Base class for abort-testing clients.
- """
- inReactorMethod = False
-
- def connectionLost(self, reason):
- if self.inReactorMethod:
- raise RuntimeError("BUG: connectionLost was called re-entrantly!")
- ConnectableProtocol.connectionLost(self, reason)
-
-
-
-class WritingButNotAbortingClient(BaseAbortingClient):
- """
- Write data, but don't abort.
- """
-
- def connectionMade(self):
- self.transport.write("hello")
-
-
-
-class AbortingClient(BaseAbortingClient):
- """
- Call abortConnection() after writing some data.
- """
-
- def dataReceived(self, data):
- """
- Some data was received, so the connection is set up.
- """
- self.inReactorMethod = True
- self.writeAndAbort()
- self.inReactorMethod = False
-
-
- def writeAndAbort(self):
- # X is written before abortConnection, and so there is a chance it
- # might arrive. Y is written after, and so no Ys should ever be
- # delivered:
- self.transport.write("X" * 10000)
- self.transport.abortConnection()
- self.transport.write("Y" * 10000)
-
-
-
-class AbortingTwiceClient(AbortingClient):
- """
- Call abortConnection() twice, after writing some data.
- """
-
- def writeAndAbort(self):
- AbortingClient.writeAndAbort(self)
- self.transport.abortConnection()
-
-
-
-class AbortingThenLosingClient(AbortingClient):
- """
- Call abortConnection() and then loseConnection().
- """
-
- def writeAndAbort(self):
- AbortingClient.writeAndAbort(self)
- self.transport.loseConnection()
-
-
-
-class ProducerAbortingClient(ConnectableProtocol):
- """
- Call abortConnection from doWrite, via resumeProducing.
- """
-
- inReactorMethod = True
- producerStopped = False
-
- def write(self):
- self.transport.write("lalala" * 127000)
- self.inRegisterProducer = True
- self.transport.registerProducer(self, False)
- self.inRegisterProducer = False
-
-
- def connectionMade(self):
- self.write()
-
-
- def resumeProducing(self):
- self.inReactorMethod = True
- if not self.inRegisterProducer:
- self.transport.abortConnection()
- self.inReactorMethod = False
-
-
- def stopProducing(self):
- self.producerStopped = True
-
-
- def connectionLost(self, reason):
- if not self.producerStopped:
- raise RuntimeError("BUG: stopProducing() was never called.")
- if self.inReactorMethod:
- raise RuntimeError("BUG: connectionLost called re-entrantly!")
- ConnectableProtocol.connectionLost(self, reason)
-
-
-
-class StreamingProducerClient(ConnectableProtocol):
- """
- Call abortConnection() when the other side has stopped reading.
-
- In particular, we want to call abortConnection() only once our local
- socket hits a state where it is no longer writeable. This helps emulate
- the most common use case for abortConnection(), closing a connection after
- a timeout, with write buffers being full.
-
- Since it's very difficult to know when this actually happens, we just
- write a lot of data, and assume at that point no more writes will happen.
- """
- paused = False
- extraWrites = 0
- inReactorMethod = False
-
- def connectionMade(self):
- self.write()
-
-
- def write(self):
- """
- Write large amount to transport, then wait for a while for buffers to
- fill up.
- """
- self.transport.registerProducer(self, True)
- for i in range(100):
- self.transport.write("1234567890" * 32000)
-
-
- def resumeProducing(self):
- self.paused = False
-
-
- def stopProducing(self):
- pass
-
-
- def pauseProducing(self):
- """
- Called when local buffer fills up.
-
- The goal is to hit the point where the local file descriptor is not
- writeable (or the moral equivalent). The fact that pauseProducing has
- been called is not sufficient, since that can happen when Twisted's
- buffers fill up but OS hasn't gotten any writes yet. We want to be as
- close as possible to every buffer (including OS buffers) being full.
-
- So, we wait a bit more after this for Twisted to write out a few
- chunks, then abortConnection.
- """
- if self.paused:
- return
- self.paused = True
- # The amount we wait is arbitrary, we just want to make sure some
- # writes have happened and outgoing OS buffers filled up -- see
- # http://twistedmatrix.com/trac/ticket/5303 for details:
- self.reactor.callLater(0.01, self.doAbort)
-
-
- def doAbort(self):
- if not self.paused:
- log.err(RuntimeError("BUG: We should be paused a this point."))
- self.inReactorMethod = True
- self.transport.abortConnection()
- self.inReactorMethod = False
-
-
- def connectionLost(self, reason):
- # Tell server to start reading again so it knows to go away:
- self.otherProtocol.transport.startReading()
- ConnectableProtocol.connectionLost(self, reason)
-
-
-
-class StreamingProducerClientLater(StreamingProducerClient):
- """
- Call abortConnection() from dataReceived, after bytes have been
- exchanged.
- """
-
- def connectionMade(self):
- self.transport.write("hello")
- self.gotData = False
-
-
- def dataReceived(self, data):
- if not self.gotData:
- self.gotData = True
- self.write()
-
-
-class ProducerAbortingClientLater(ProducerAbortingClient):
- """
- Call abortConnection from doWrite, via resumeProducing.
-
- Try to do so after some bytes have already been exchanged, so we
- don't interrupt SSL handshake.
- """
-
- def connectionMade(self):
- # Override base class connectionMade().
- pass
-
-
- def dataReceived(self, data):
- self.write()
-
-
-
-class DataReceivedRaisingClient(AbortingClient):
- """
- Call abortConnection(), and then throw exception, from dataReceived.
- """
-
- def dataReceived(self, data):
- self.transport.abortConnection()
- raise ZeroDivisionError("ONO")
-
-
-
-class ResumeThrowsClient(ProducerAbortingClient):
- """
- Call abortConnection() and throw exception from resumeProducing().
- """
-
- def resumeProducing(self):
- if not self.inRegisterProducer:
- self.transport.abortConnection()
- raise ZeroDivisionError("ono!")
-
-
- def connectionLost(self, reason):
- # Base class assertion about stopProducing being called isn't valid;
- # if the we blew up in resumeProducing, consumers are justified in
- # giving up on the producer and not calling stopProducing.
- ConnectableProtocol.connectionLost(self, reason)
-
-
-
-class AbortConnectionMixin(object):
- """
- Unit tests for L{ITransport.abortConnection}.
- """
- # Override in subclasses, should be a EndpointCreator instance:
- endpoints = None
-
- def runAbortTest(self, clientClass, serverClass,
- clientConnectionLostReason=None):
- """
- A test runner utility function, which hooks up a matched pair of client
- and server protocols.
-
- We then run the reactor until both sides have disconnected, and then
- verify that the right exception resulted.
- """
- clientExpectedExceptions = (ConnectionAborted, ConnectionLost)
- serverExpectedExceptions = (ConnectionLost, ConnectionDone)
- # In TLS tests we may get SSL.Error instead of ConnectionLost,
- # since we're trashing the TLS protocol layer.
- if useSSL:
- clientExpectedExceptions = clientExpectedExceptions + (SSL.Error,)
- serverExpectedExceptions = serverExpectedExceptions + (SSL.Error,)
-
- client = clientClass()
- server = serverClass()
- client.otherProtocol = server
- server.otherProtocol = client
- reactor = runProtocolsWithReactor(self, server, client, self.endpoints)
-
- # Make sure everything was shutdown correctly:
- self.assertEqual(reactor.removeAll(), [])
- # The reactor always has a timeout added in runReactor():
- delayedCalls = reactor.getDelayedCalls()
- self.assertEqual(len(delayedCalls), 1, map(str, delayedCalls))
-
- if clientConnectionLostReason is not None:
- self.assertIsInstance(
- client.disconnectReason.value,
- (clientConnectionLostReason,) + clientExpectedExceptions)
- else:
- self.assertIsInstance(client.disconnectReason.value,
- clientExpectedExceptions)
- self.assertIsInstance(server.disconnectReason.value, serverExpectedExceptions)
-
-
- def test_dataReceivedAbort(self):
- """
- abortConnection() is called in dataReceived. The protocol should be
- disconnected, but connectionLost should not be called re-entrantly.
- """
- return self.runAbortTest(AbortingClient, ReadAbortServerProtocol)
-
-
- def test_clientAbortsConnectionTwice(self):
- """
- abortConnection() is called twice by client.
-
- No exception should be thrown, and the connection will be closed.
- """
- return self.runAbortTest(AbortingTwiceClient, ReadAbortServerProtocol)
-
-
- def test_clientAbortsConnectionThenLosesConnection(self):
- """
- Client calls abortConnection(), followed by loseConnection().
-
- No exception should be thrown, and the connection will be closed.
- """
- return self.runAbortTest(AbortingThenLosingClient,
- ReadAbortServerProtocol)
-
-
- def test_serverAbortsConnectionTwice(self):
- """
- abortConnection() is called twice by server.
-
- No exception should be thrown, and the connection will be closed.
- """
- return self.runAbortTest(WritingButNotAbortingClient, ServerAbortsTwice,
- clientConnectionLostReason=ConnectionLost)
-
-
- def test_serverAbortsConnectionThenLosesConnection(self):
- """
- Server calls abortConnection(), followed by loseConnection().
-
- No exception should be thrown, and the connection will be closed.
- """
- return self.runAbortTest(WritingButNotAbortingClient,
- ServerAbortsThenLoses,
- clientConnectionLostReason=ConnectionLost)
-
-
- def test_resumeProducingAbort(self):
- """
- abortConnection() is called in resumeProducing, before any bytes have
- been exchanged. The protocol should be disconnected, but
- connectionLost should not be called re-entrantly.
- """
- self.runAbortTest(ProducerAbortingClient,
- ConnectableProtocol)
-
-
- def test_resumeProducingAbortLater(self):
- """
- abortConnection() is called in resumeProducing, after some
- bytes have been exchanged. The protocol should be disconnected.
- """
- return self.runAbortTest(ProducerAbortingClientLater,
- AbortServerWritingProtocol)
-
-
- def test_fullWriteBuffer(self):
- """
- abortConnection() triggered by the write buffer being full.
-
- In particular, the server side stops reading. This is supposed
- to simulate a realistic timeout scenario where the client
- notices the server is no longer accepting data.
-
- The protocol should be disconnected, but connectionLost should not be
- called re-entrantly.
- """
- self.runAbortTest(StreamingProducerClient,
- NoReadServer)
-
-
- def test_fullWriteBufferAfterByteExchange(self):
- """
- abortConnection() is triggered by a write buffer being full.
-
- However, this buffer is filled after some bytes have been exchanged,
- allowing a TLS handshake if we're testing TLS. The connection will
- then be lost.
- """
- return self.runAbortTest(StreamingProducerClientLater,
- EventualNoReadServer)
-
-
- def test_dataReceivedThrows(self):
- """
- dataReceived calls abortConnection(), and then raises an exception.
-
- The connection will be lost, with the thrown exception
- (C{ZeroDivisionError}) as the reason on the client. The idea here is
- that bugs should not be masked by abortConnection, in particular
- unexpected exceptions.
- """
- self.runAbortTest(DataReceivedRaisingClient,
- AbortServerWritingProtocol,
- clientConnectionLostReason=ZeroDivisionError)
- errors = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(errors), 1)
-
-
- def test_resumeProducingThrows(self):
- """
- resumeProducing calls abortConnection(), and then raises an exception.
-
- The connection will be lost, with the thrown exception
- (C{ZeroDivisionError}) as the reason on the client. The idea here is
- that bugs should not be masked by abortConnection, in particular
- unexpected exceptions.
- """
- self.runAbortTest(ResumeThrowsClient,
- ConnectableProtocol,
- clientConnectionLostReason=ZeroDivisionError)
- errors = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(errors), 1)
-
-
-
-class AbortConnectionTestCase(ReactorBuilder, AbortConnectionMixin):
- """
- TCP-specific L{AbortConnectionMixin} tests.
- """
- requiredInterfaces = (IReactorTCP,)
-
- endpoints = TCPCreator()
-
-globals().update(AbortConnectionTestCase.makeTestCaseClasses())
-
-
-
-class SimpleUtilityTestCase(TestCase):
- """
- Simple, direct tests for helpers within L{twisted.internet.tcp}.
- """
- if ipv6Skip:
- skip = ipv6Skip
-
- def test_resolveNumericHost(self):
- """
- L{_resolveIPv6} raises a L{socket.gaierror} (L{socket.EAI_NONAME}) when
- invoked with a non-numeric host. (In other words, it is passing
- L{socket.AI_NUMERICHOST} to L{socket.getaddrinfo} and will not
- accidentally block if it receives bad input.)
- """
- err = self.assertRaises(socket.gaierror, _resolveIPv6, "localhost", 1)
- self.assertEqual(err.args[0], socket.EAI_NONAME)
-
-
- def test_resolveNumericService(self):
- """
- L{_resolveIPv6} raises a L{socket.gaierror} (L{socket.EAI_NONAME}) when
- invoked with a non-numeric port. (In other words, it is passing
- L{socket.AI_NUMERICSERV} to L{socket.getaddrinfo} and will not
- accidentally block if it receives bad input.)
- """
- err = self.assertRaises(socket.gaierror, _resolveIPv6, "::1", "http")
- self.assertEqual(err.args[0], socket.EAI_NONAME)
-
- if platform.isWindows():
- test_resolveNumericService.skip = ("The AI_NUMERICSERV flag is not "
- "supported by Microsoft providers.")
- # http://msdn.microsoft.com/en-us/library/windows/desktop/ms738520.aspx
-
-
- def test_resolveIPv6(self):
- """
- L{_resolveIPv6} discovers the flow info and scope ID of an IPv6
- address.
- """
- result = _resolveIPv6("::1", 2)
- self.assertEqual(len(result), 4)
- # We can't say anything more useful about these than that they're
- # integers, because the whole point of getaddrinfo is that you can never
- # know a-priori know _anything_ about the network interfaces of the
- # computer that you're on and you have to ask it.
- self.assertIsInstance(result[2], int) # flow info
- self.assertIsInstance(result[3], int) # scope id
- # but, luckily, IP presentation format and what it means to be a port
- # number are a little better specified.
- self.assertEqual(result[:2], ("::1", 2))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_threads.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_threads.py
deleted file mode 100755
index 00683a31..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_threads.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorThreads}.
-"""
-
-__metaclass__ = type
-
-from weakref import ref
-import gc, threading
-
-from twisted.python.threadable import isInIOThread
-from twisted.internet.test.reactormixins import ReactorBuilder
-from twisted.python.threadpool import ThreadPool
-from twisted.internet.interfaces import IReactorThreads
-
-
-class ThreadTestsBuilder(ReactorBuilder):
- """
- Builder for defining tests relating to L{IReactorThreads}.
- """
- requiredInterfaces = (IReactorThreads,)
-
- def test_getThreadPool(self):
- """
- C{reactor.getThreadPool()} returns an instance of L{ThreadPool} which
- starts when C{reactor.run()} is called and stops before it returns.
- """
- state = []
- reactor = self.buildReactor()
-
- pool = reactor.getThreadPool()
- self.assertIsInstance(pool, ThreadPool)
- self.assertFalse(
- pool.started, "Pool should not start before reactor.run")
-
- def f():
- # Record the state for later assertions
- state.append(pool.started)
- state.append(pool.joined)
- reactor.stop()
-
- reactor.callWhenRunning(f)
- self.runReactor(reactor, 2)
-
- self.assertTrue(
- state[0], "Pool should start after reactor.run")
- self.assertFalse(
- state[1], "Pool should not be joined before reactor.stop")
- self.assertTrue(
- pool.joined,
- "Pool should be stopped after reactor.run returns")
-
-
- def test_suggestThreadPoolSize(self):
- """
- C{reactor.suggestThreadPoolSize()} sets the maximum size of the reactor
- threadpool.
- """
- reactor = self.buildReactor()
- reactor.suggestThreadPoolSize(17)
- pool = reactor.getThreadPool()
- self.assertEqual(pool.max, 17)
-
-
- def test_delayedCallFromThread(self):
- """
- A function scheduled with L{IReactorThreads.callFromThread} invoked
- from a delayed call is run immediately in the next reactor iteration.
-
- When invoked from the reactor thread, previous implementations of
- L{IReactorThreads.callFromThread} would skip the pipe/socket based wake
- up step, assuming the reactor would wake up on its own. However, this
- resulted in the reactor not noticing a insert into the thread queue at
- the right time (in this case, after the thread queue has been processed
- for that reactor iteration).
- """
- reactor = self.buildReactor()
-
- def threadCall():
- reactor.stop()
-
- # Set up the use of callFromThread being tested.
- reactor.callLater(0, reactor.callFromThread, threadCall)
-
- before = reactor.seconds()
- self.runReactor(reactor, 60)
- after = reactor.seconds()
-
- # We specified a timeout of 60 seconds. The timeout code in runReactor
- # probably won't actually work, though. If the reactor comes out of
- # the event notification API just a little bit early, say after 59.9999
- # seconds instead of after 60 seconds, then the queued thread call will
- # get processed but the timeout delayed call runReactor sets up won't!
- # Then the reactor will stop and runReactor will return without the
- # timeout firing. As it turns out, select() and poll() are quite
- # likely to return *slightly* earlier than we ask them to, so the
- # timeout will rarely happen, even if callFromThread is broken. So,
- # instead we'll measure the elapsed time and make sure it's something
- # less than about half of the timeout we specified. This is heuristic.
- # It assumes that select() won't ever return after 30 seconds when we
- # asked it to timeout after 60 seconds. And of course like all
- # time-based tests, it's slightly non-deterministic. If the OS doesn't
- # schedule this process for 30 seconds, then the test might fail even
- # if callFromThread is working.
- self.assertTrue(after - before < 30)
-
-
- def test_callFromThread(self):
- """
- A function scheduled with L{IReactorThreads.callFromThread} invoked
- from another thread is run in the reactor thread.
- """
- reactor = self.buildReactor()
- result = []
-
- def threadCall():
- result.append(threading.currentThread())
- reactor.stop()
- reactor.callLater(0, reactor.callInThread,
- reactor.callFromThread, threadCall)
- self.runReactor(reactor, 5)
-
- self.assertEquals(result, [threading.currentThread()])
-
-
- def test_stopThreadPool(self):
- """
- When the reactor stops, L{ReactorBase._stopThreadPool} drops the
- reactor's direct reference to its internal threadpool and removes
- the associated startup and shutdown triggers.
-
- This is the case of the thread pool being created before the reactor
- is run.
- """
- reactor = self.buildReactor()
- threadpool = ref(reactor.getThreadPool())
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- gc.collect()
- self.assertIdentical(threadpool(), None)
-
-
- def test_stopThreadPoolWhenStartedAfterReactorRan(self):
- """
- We must handle the case of shutting down the thread pool when it was
- started after the reactor was run in a special way.
-
- Some implementation background: The thread pool is started with
- callWhenRunning, which only returns a system trigger ID when it is
- invoked before the reactor is started.
-
- This is the case of the thread pool being created after the reactor
- is started.
- """
- reactor = self.buildReactor()
- threadPoolRefs = []
- def acquireThreadPool():
- threadPoolRefs.append(ref(reactor.getThreadPool()))
- reactor.stop()
- reactor.callWhenRunning(acquireThreadPool)
- self.runReactor(reactor)
- gc.collect()
- self.assertIdentical(threadPoolRefs[0](), None)
-
-
- def test_cleanUpThreadPoolEvenBeforeReactorIsRun(self):
- """
- When the reactor has its shutdown event fired before it is run, the
- thread pool is completely destroyed.
-
- For what it's worth, the reason we support this behavior at all is
- because Trial does this.
-
- This is the case of the thread pool being created without the reactor
- being started at al.
- """
- reactor = self.buildReactor()
- threadPoolRef = ref(reactor.getThreadPool())
- reactor.fireSystemEvent("shutdown")
- gc.collect()
- self.assertIdentical(threadPoolRef(), None)
-
-
- def test_isInIOThread(self):
- """
- The reactor registers itself as the I/O thread when it runs so that
- L{twisted.python.threadable.isInIOThread} returns C{True} if it is
- called in the thread the reactor is running in.
- """
- results = []
- reactor = self.buildReactor()
- def check():
- results.append(isInIOThread())
- reactor.stop()
- reactor.callWhenRunning(check)
- self.runReactor(reactor)
- self.assertEqual([True], results)
-
-
- def test_isNotInIOThread(self):
- """
- The reactor registers itself as the I/O thread when it runs so that
- L{twisted.python.threadable.isInIOThread} returns C{False} if it is
- called in a different thread than the reactor is running in.
- """
- results = []
- reactor = self.buildReactor()
- def check():
- results.append(isInIOThread())
- reactor.callFromThread(reactor.stop)
- reactor.callInThread(check)
- self.runReactor(reactor)
- self.assertEqual([False], results)
-
-
-globals().update(ThreadTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_time.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_time.py
deleted file mode 100755
index b6f9e1db..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_time.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorTime}.
-"""
-
-__metaclass__ = type
-
-from twisted.python.runtime import platform
-from twisted.internet.test.reactormixins import ReactorBuilder
-from twisted.internet.interfaces import IReactorTime
-
-
-class TimeTestsBuilder(ReactorBuilder):
- """
- Builder for defining tests relating to L{IReactorTime}.
- """
- requiredInterfaces = (IReactorTime,)
-
- def test_delayedCallStopsReactor(self):
- """
- The reactor can be stopped by a delayed call.
- """
- reactor = self.buildReactor()
- reactor.callLater(0, reactor.stop)
- reactor.run()
-
-
-
-class GlibTimeTestsBuilder(ReactorBuilder):
- """
- Builder for defining tests relating to L{IReactorTime} for reactors based
- off glib.
- """
- requiredInterfaces = (IReactorTime,)
-
- if platform.isWindows():
- _reactors = ["twisted.internet.gtk2reactor.PortableGtkReactor"]
- else:
- _reactors = ["twisted.internet.glib2reactor.Glib2Reactor",
- "twisted.internet.gtk2reactor.Gtk2Reactor"]
-
- def test_timeout_add(self):
- """
- A C{reactor.callLater} call scheduled from a C{gobject.timeout_add}
- call is run on time.
- """
- import gobject
- reactor = self.buildReactor()
-
- result = []
- def gschedule():
- reactor.callLater(0, callback)
- return 0
- def callback():
- result.append(True)
- reactor.stop()
-
- reactor.callWhenRunning(gobject.timeout_add, 10, gschedule)
- self.runReactor(reactor, 5)
- self.assertEqual(result, [True])
-
-
-globals().update(TimeTestsBuilder.makeTestCaseClasses())
-globals().update(GlibTimeTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tls.py
deleted file mode 100755
index 223d5f68..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_tls.py
+++ /dev/null
@@ -1,432 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{ITLSTransport}.
-"""
-
-__metaclass__ = type
-
-import sys, operator
-
-from zope.interface import implements
-
-from twisted.internet.test.reactormixins import ReactorBuilder, EndpointCreator
-from twisted.internet.protocol import ServerFactory, ClientFactory, Protocol
-from twisted.internet.interfaces import (
- IReactorSSL, ITLSTransport, IStreamClientEndpoint)
-from twisted.internet.defer import Deferred, DeferredList
-from twisted.internet.endpoints import (
- SSL4ServerEndpoint, SSL4ClientEndpoint, TCP4ClientEndpoint)
-from twisted.internet.error import ConnectionClosed
-from twisted.internet.task import Cooperator
-from twisted.trial.unittest import TestCase, SkipTest
-from twisted.python.runtime import platform
-
-from twisted.internet.test.test_core import ObjectModelIntegrationMixin
-from twisted.internet.test.test_tcp import (
- StreamTransportTestsMixin, AbortConnectionMixin)
-from twisted.internet.test.connectionmixins import ConnectionTestsMixin
-from twisted.internet.test.connectionmixins import BrokenContextFactory
-
-try:
- from OpenSSL.crypto import FILETYPE_PEM
-except ImportError:
- FILETYPE_PEM = None
-else:
- from twisted.internet.ssl import PrivateCertificate, KeyPair
- from twisted.internet.ssl import ClientContextFactory
-
-
-class TLSMixin:
- requiredInterfaces = [IReactorSSL]
-
- if platform.isWindows():
- msg = (
- "For some reason, these reactors don't deal with SSL "
- "disconnection correctly on Windows. See #3371.")
- skippedReactors = {
- "twisted.internet.glib2reactor.Glib2Reactor": msg,
- "twisted.internet.gtk2reactor.Gtk2Reactor": msg}
-
-
-class ContextGeneratingMixin(object):
- _certificateText = (
- "-----BEGIN CERTIFICATE-----\n"
- "MIIDBjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER\n"
- "MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD\n"
- "ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n\n"
- "cHNAcG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzEL\n"
- "MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhv\n"
- "c3QxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEB\n"
- "BQADSwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh\n"
- "5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQC\n"
- "MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl\n"
- "MB0GA1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7\n"
- "hyNp65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoT\n"
- "CE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlw\n"
- "dG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3Qx\n"
- "LmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6\n"
- "BoJuVwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++\n"
- "7QGG/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JE\n"
- "WUQ9Ho4EzbYCOQ==\n"
- "-----END CERTIFICATE-----\n")
-
- _privateKeyText = (
- "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh\n"
- "5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAQJBAIqm/bz4NA1H++Vx5Ewx\n"
- "OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT\n"
- "ZIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4\n"
- "nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2\n"
- "HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNEH+vRWsAYU/gbx+OQB+7VOcBAiEA\n"
- "oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=\n"
- "-----END RSA PRIVATE KEY-----\n")
-
-
- def getServerContext(self):
- """
- Return a new SSL context suitable for use in a test server.
- """
- cert = PrivateCertificate.load(
- self._certificateText,
- KeyPair.load(self._privateKeyText, FILETYPE_PEM),
- FILETYPE_PEM)
- return cert.options()
-
-
- def getClientContext(self):
- return ClientContextFactory()
-
-
-
-class StartTLSClientEndpoint(object):
- """
- An endpoint which wraps another one and adds a TLS layer immediately when
- connections are set up.
-
- @ivar wrapped: A L{IStreamClientEndpoint} provider which will be used to
- really set up connections.
-
- @ivar contextFactory: A L{ContextFactory} to use to do TLS.
- """
- implements(IStreamClientEndpoint)
-
- def __init__(self, wrapped, contextFactory):
- self.wrapped = wrapped
- self.contextFactory = contextFactory
-
-
- def connect(self, factory):
- """
- Establish a connection using a protocol build by C{factory} and
- immediately start TLS on it. Return a L{Deferred} which fires with the
- protocol instance.
- """
- # This would be cleaner when we have ITransport.switchProtocol, which
- # will be added with ticket #3204:
- class WrapperFactory(ServerFactory):
- def buildProtocol(wrapperSelf, addr):
- protocol = factory.buildProtocol(addr)
- def connectionMade(orig=protocol.connectionMade):
- protocol.transport.startTLS(self.contextFactory)
- orig()
- protocol.connectionMade = connectionMade
- return protocol
-
- return self.wrapped.connect(WrapperFactory())
-
-
-
-class StartTLSClientCreator(EndpointCreator, ContextGeneratingMixin):
- """
- Create L{ITLSTransport.startTLS} endpoint for the client, and normal SSL
- for server just because it's easier.
- """
- def server(self, reactor):
- """
- Construct an SSL server endpoint. This should be be constructing a TCP
- server endpoint which immediately calls C{startTLS} instead, but that
- is hard.
- """
- return SSL4ServerEndpoint(reactor, 0, self.getServerContext())
-
-
- def client(self, reactor, serverAddress):
- """
- Construct a TCP client endpoint wrapped to immediately start TLS.
- """
- return StartTLSClientEndpoint(
- TCP4ClientEndpoint(
- reactor, '127.0.0.1', serverAddress.port),
- ClientContextFactory())
-
-
-
-class BadContextTestsMixin(object):
- """
- Mixin for L{ReactorBuilder} subclasses which defines a helper for testing
- the handling of broken context factories.
- """
- def _testBadContext(self, useIt):
- """
- Assert that the exception raised by a broken context factory's
- C{getContext} method is raised by some reactor method. If it is not, an
- exception will be raised to fail the test.
-
- @param useIt: A two-argument callable which will be called with a
- reactor and a broken context factory and which is expected to raise
- the same exception as the broken context factory's C{getContext}
- method.
- """
- reactor = self.buildReactor()
- exc = self.assertRaises(
- ValueError, useIt, reactor, BrokenContextFactory())
- self.assertEqual(BrokenContextFactory.message, str(exc))
-
-
-
-class StartTLSClientTestsMixin(TLSMixin, ReactorBuilder, ConnectionTestsMixin):
- """
- Tests for TLS connections established using L{ITLSTransport.startTLS} (as
- opposed to L{IReactorSSL.connectSSL} or L{IReactorSSL.listenSSL}).
- """
- endpoints = StartTLSClientCreator()
-
-
-
-class SSLCreator(EndpointCreator, ContextGeneratingMixin):
- """
- Create SSL endpoints.
- """
- def server(self, reactor):
- """
- Create an SSL server endpoint on a TCP/IP-stack allocated port.
- """
- return SSL4ServerEndpoint(reactor, 0, self.getServerContext())
-
-
- def client(self, reactor, serverAddress):
- """
- Create an SSL client endpoint which will connect localhost on
- the port given by C{serverAddress}.
-
- @type serverAddress: L{IPv4Address}
- """
- return SSL4ClientEndpoint(
- reactor, '127.0.0.1', serverAddress.port,
- ClientContextFactory())
-
-
-class SSLClientTestsMixin(TLSMixin, ReactorBuilder, ContextGeneratingMixin,
- ConnectionTestsMixin, BadContextTestsMixin):
- """
- Mixin defining tests relating to L{ITLSTransport}.
- """
- endpoints = SSLCreator()
-
- def test_badContext(self):
- """
- If the context factory passed to L{IReactorSSL.connectSSL} raises an
- exception from its C{getContext} method, that exception is raised by
- L{IReactorSSL.connectSSL}.
- """
- def useIt(reactor, contextFactory):
- return reactor.connectSSL(
- "127.0.0.1", 1234, ClientFactory(), contextFactory)
- self._testBadContext(useIt)
-
-
- def test_disconnectAfterWriteAfterStartTLS(self):
- """
- L{ITCPTransport.loseConnection} ends a connection which was set up with
- L{ITLSTransport.startTLS} and which has recently been written to. This
- is intended to verify that a socket send error masked by the TLS
- implementation doesn't prevent the connection from being reported as
- closed.
- """
- class ShortProtocol(Protocol):
- def connectionMade(self):
- if not ITLSTransport.providedBy(self.transport):
- # Functionality isn't available to be tested.
- finished = self.factory.finished
- self.factory.finished = None
- finished.errback(SkipTest("No ITLSTransport support"))
- return
-
- # Switch the transport to TLS.
- self.transport.startTLS(self.factory.context)
- # Force TLS to really get negotiated. If nobody talks, nothing
- # will happen.
- self.transport.write("x")
-
- def dataReceived(self, data):
- # Stuff some bytes into the socket. This mostly has the effect
- # of causing the next write to fail with ENOTCONN or EPIPE.
- # With the pyOpenSSL implementation of ITLSTransport, the error
- # is swallowed outside of the control of Twisted.
- self.transport.write("y")
- # Now close the connection, which requires a TLS close alert to
- # be sent.
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- # This is the success case. The client and the server want to
- # get here.
- finished = self.factory.finished
- if finished is not None:
- self.factory.finished = None
- finished.callback(reason)
-
- reactor = self.buildReactor()
-
- serverFactory = ServerFactory()
- serverFactory.finished = Deferred()
- serverFactory.protocol = ShortProtocol
- serverFactory.context = self.getServerContext()
-
- clientFactory = ClientFactory()
- clientFactory.finished = Deferred()
- clientFactory.protocol = ShortProtocol
- clientFactory.context = self.getClientContext()
- clientFactory.context.method = serverFactory.context.method
-
- lostConnectionResults = []
- finished = DeferredList(
- [serverFactory.finished, clientFactory.finished],
- consumeErrors=True)
- def cbFinished(results):
- lostConnectionResults.extend([results[0][1], results[1][1]])
- finished.addCallback(cbFinished)
-
- port = reactor.listenTCP(0, serverFactory, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
-
- connector = reactor.connectTCP(
- port.getHost().host, port.getHost().port, clientFactory)
- self.addCleanup(connector.disconnect)
-
- finished.addCallback(lambda ign: reactor.stop())
- self.runReactor(reactor)
- lostConnectionResults[0].trap(ConnectionClosed)
- lostConnectionResults[1].trap(ConnectionClosed)
-
-
-
-class TLSPortTestsBuilder(TLSMixin, ContextGeneratingMixin,
- ObjectModelIntegrationMixin, BadContextTestsMixin,
- StreamTransportTestsMixin, ReactorBuilder):
- """
- Tests for L{IReactorSSL.listenSSL}
- """
- def getListeningPort(self, reactor, factory):
- """
- Get a TLS port from a reactor.
- """
- return reactor.listenSSL(0, factory, self.getServerContext())
-
-
- def getExpectedStartListeningLogMessage(self, port, factory):
- """
- Get the message expected to be logged when a TLS port starts listening.
- """
- return "%s (TLS) starting on %d" % (factory, port.getHost().port)
-
-
- def getExpectedConnectionLostLogMsg(self, port):
- """
- Get the expected connection lost message for a TLS port.
- """
- return "(TLS Port %s Closed)" % (port.getHost().port,)
-
-
- def test_badContext(self):
- """
- If the context factory passed to L{IReactorSSL.listenSSL} raises an
- exception from its C{getContext} method, that exception is raised by
- L{IReactorSSL.listenSSL}.
- """
- def useIt(reactor, contextFactory):
- return reactor.listenSSL(0, ServerFactory(), contextFactory)
- self._testBadContext(useIt)
-
-
-
-globals().update(SSLClientTestsMixin.makeTestCaseClasses())
-globals().update(StartTLSClientTestsMixin.makeTestCaseClasses())
-globals().update(TLSPortTestsBuilder().makeTestCaseClasses())
-
-
-
-class AbortSSLConnectionTest(ReactorBuilder, AbortConnectionMixin, ContextGeneratingMixin):
- """
- C{abortConnection} tests using SSL.
- """
- requiredInterfaces = (IReactorSSL,)
- endpoints = SSLCreator()
-
- def buildReactor(self):
- reactor = ReactorBuilder.buildReactor(self)
- try:
- from twisted.protocols import tls
- except ImportError:
- return reactor
-
- # Patch twisted.protocols.tls to use this reactor, until we get
- # around to fixing #5206, or the TLS code uses an explicit reactor:
- cooperator = Cooperator(
- scheduler=lambda x: reactor.callLater(0.00001, x))
- self.patch(tls, "cooperate", cooperator.cooperate)
- return reactor
-
-
- def setUp(self):
- if FILETYPE_PEM is None:
- raise SkipTest("OpenSSL not available.")
-
-globals().update(AbortSSLConnectionTest.makeTestCaseClasses())
-
-class OldTLSDeprecationTest(TestCase):
- """
- Tests for the deprecation of L{twisted.internet._oldtls}, the implementation
- module for L{IReactorSSL} used when only an old version of pyOpenSSL is
- available.
- """
- def test_warning(self):
- """
- The use of L{twisted.internet._oldtls} is deprecated, and emits a
- L{DeprecationWarning}.
- """
- # Since _oldtls depends on OpenSSL, just skip this test if it isn't
- # installed on the system. Faking it would be error prone.
- try:
- import OpenSSL
- except ImportError:
- raise SkipTest("OpenSSL not available.")
-
- # Change the apparent version of OpenSSL to one support for which is
- # deprecated. And have it change back again after the test.
- self.patch(OpenSSL, '__version__', '0.5')
-
- # If the module was already imported, the import statement below won't
- # execute its top-level code. Take it out of sys.modules so the import
- # system re-evaluates it. Arrange to put the original back afterwards.
- # Also handle the case where it hasn't yet been imported.
- try:
- oldtls = sys.modules['twisted.internet._oldtls']
- except KeyError:
- self.addCleanup(sys.modules.pop, 'twisted.internet._oldtls')
- else:
- del sys.modules['twisted.internet._oldtls']
- self.addCleanup(
- operator.setitem, sys.modules, 'twisted.internet._oldtls',
- oldtls)
-
- # The actual test.
- import twisted.internet._oldtls
- warnings = self.flushWarnings()
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "Support for pyOpenSSL 0.5 is deprecated. "
- "Upgrade to pyOpenSSL 0.10 or newer.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp.py
deleted file mode 100755
index 8760a942..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorUDP}.
-"""
-
-__metaclass__ = type
-
-from socket import SOCK_DGRAM
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.python import context
-from twisted.python.log import ILogContext, err
-from twisted.internet.test.reactormixins import ReactorBuilder
-from twisted.internet.defer import Deferred, maybeDeferred
-from twisted.internet.interfaces import (
- ILoggingContext, IListeningPort, IReactorUDP)
-from twisted.internet.address import IPv4Address
-from twisted.internet.protocol import DatagramProtocol
-
-from twisted.internet.test.test_tcp import findFreePort
-from twisted.internet.test.connectionmixins import LogObserverMixin
-
-
-class UDPPortMixin(object):
- def getListeningPort(self, reactor, protocol):
- """
- Get a UDP port from a reactor.
- """
- return reactor.listenUDP(0, protocol)
-
-
- def getExpectedStartListeningLogMessage(self, port, protocol):
- """
- Get the message expected to be logged when a UDP port starts listening.
- """
- return "%s starting on %d" % (protocol, port.getHost().port)
-
-
- def getExpectedConnectionLostLogMessage(self, port):
- """
- Get the expected connection lost message for a UDP port.
- """
- return "(UDP Port %s Closed)" % (port.getHost().port,)
-
-
-
-class DatagramTransportTestsMixin(LogObserverMixin):
- """
- Mixin defining tests which apply to any port/datagram based transport.
- """
- def test_startedListeningLogMessage(self):
- """
- When a port starts, a message including a description of the associated
- protocol is logged.
- """
- loggedMessages = self.observe()
- reactor = self.buildReactor()
- class SomeProtocol(DatagramProtocol):
- implements(ILoggingContext)
- def logPrefix(self):
- return "Crazy Protocol"
- protocol = SomeProtocol()
- p = self.getListeningPort(reactor, protocol)
- expectedMessage = self.getExpectedStartListeningLogMessage(
- p, "Crazy Protocol")
- self.assertEqual((expectedMessage,), loggedMessages[0]['message'])
-
-
- def test_connectionLostLogMessage(self):
- """
- When a connection is lost, an informative message should be logged (see
- L{getExpectedConnectionLostLogMessage}): an address identifying the port
- and the fact that it was closed.
- """
- loggedMessages = self.observe()
- reactor = self.buildReactor()
- p = self.getListeningPort(reactor, DatagramProtocol())
- expectedMessage = self.getExpectedConnectionLostLogMessage(p)
-
- def stopReactor(ignored):
- reactor.stop()
-
- def doStopListening():
- del loggedMessages[:]
- maybeDeferred(p.stopListening).addCallback(stopReactor)
-
- reactor.callWhenRunning(doStopListening)
- self.runReactor(reactor)
-
- self.assertEqual((expectedMessage,), loggedMessages[0]['message'])
-
-
- def test_stopProtocolScheduling(self):
- """
- L{DatagramProtocol.stopProtocol} is called asynchronously (ie, not
- re-entrantly) when C{stopListening} is used to stop the the datagram
- transport.
- """
- class DisconnectingProtocol(DatagramProtocol):
-
- started = False
- stopped = False
- inStartProtocol = False
- stoppedInStart = False
-
- def startProtocol(self):
- self.started = True
- self.inStartProtocol = True
- self.transport.stopListening()
- self.inStartProtocol = False
-
- def stopProtocol(self):
- self.stopped = True
- self.stoppedInStart = self.inStartProtocol
- reactor.stop()
-
- reactor = self.buildReactor()
- protocol = DisconnectingProtocol()
- self.getListeningPort(reactor, protocol)
- self.runReactor(reactor)
-
- self.assertTrue(protocol.started)
- self.assertTrue(protocol.stopped)
- self.assertFalse(protocol.stoppedInStart)
-
-
-
-class UDPServerTestsBuilder(ReactorBuilder, UDPPortMixin,
- DatagramTransportTestsMixin):
- """
- Builder defining tests relating to L{IReactorUDP.listenUDP}.
- """
- requiredInterfaces = (IReactorUDP,)
-
- def test_interface(self):
- """
- L{IReactorUDP.listenUDP} returns an object providing L{IListeningPort}.
- """
- reactor = self.buildReactor()
- port = reactor.listenUDP(0, DatagramProtocol())
- self.assertTrue(verifyObject(IListeningPort, port))
-
-
- def test_getHost(self):
- """
- L{IListeningPort.getHost} returns an L{IPv4Address} giving a
- dotted-quad of the IPv4 address the port is listening on as well as
- the port number.
- """
- host, portNumber = findFreePort(type=SOCK_DGRAM)
- reactor = self.buildReactor()
- port = reactor.listenUDP(
- portNumber, DatagramProtocol(), interface=host)
- self.assertEqual(
- port.getHost(), IPv4Address('UDP', host, portNumber))
-
-
- def test_logPrefix(self):
- """
- Datagram transports implement L{ILoggingContext.logPrefix} to return a
- message reflecting the protocol they are running.
- """
- class CustomLogPrefixDatagramProtocol(DatagramProtocol):
- def __init__(self, prefix):
- self._prefix = prefix
- self.system = Deferred()
-
- def logPrefix(self):
- return self._prefix
-
- def datagramReceived(self, bytes, addr):
- if self.system is not None:
- system = self.system
- self.system = None
- system.callback(context.get(ILogContext)["system"])
-
- reactor = self.buildReactor()
- protocol = CustomLogPrefixDatagramProtocol("Custom Datagrams")
- d = protocol.system
- port = reactor.listenUDP(0, protocol)
- address = port.getHost()
-
- def gotSystem(system):
- self.assertEqual("Custom Datagrams (UDP)", system)
- d.addCallback(gotSystem)
- d.addErrback(err)
- d.addCallback(lambda ignored: reactor.stop())
-
- port.write("some bytes", ('127.0.0.1', address.port))
- self.runReactor(reactor)
-
-
-globals().update(UDPServerTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp_internals.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp_internals.py
deleted file mode 100755
index 75dc1e2a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_udp_internals.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the internal implementation details of L{twisted.internet.udp}.
-"""
-
-import socket
-
-from twisted.trial import unittest
-from twisted.internet.protocol import DatagramProtocol
-from twisted.internet import udp
-from twisted.python.runtime import platformType
-
-if platformType == 'win32':
- from errno import WSAEWOULDBLOCK as EWOULDBLOCK
- from errno import WSAECONNREFUSED as ECONNREFUSED
-else:
- from errno import EWOULDBLOCK
- from errno import ECONNREFUSED
-
-
-
-class StringUDPSocket(object):
- """
- A fake UDP socket object, which returns a fixed sequence of strings and/or
- socket errors. Useful for testing.
-
- @ivar retvals: A C{list} containing either strings or C{socket.error}s.
-
- @ivar connectedAddr: The address the socket is connected to.
- """
-
- def __init__(self, retvals):
- self.retvals = retvals
- self.connectedAddr = None
-
-
- def connect(self, addr):
- self.connectedAddr = addr
-
-
- def recvfrom(self, size):
- """
- Return (or raise) the next value from C{self.retvals}.
- """
- ret = self.retvals.pop(0)
- if isinstance(ret, socket.error):
- raise ret
- return ret, None
-
-
-
-class KeepReads(DatagramProtocol):
- """
- Accumulate reads in a list.
- """
-
- def __init__(self):
- self.reads = []
-
-
- def datagramReceived(self, data, addr):
- self.reads.append(data)
-
-
-
-class ErrorsTestCase(unittest.TestCase):
- """
- Error handling tests for C{udp.Port}.
- """
-
- def test_socketReadNormal(self):
- """
- Socket reads with some good data followed by a socket error which can
- be ignored causes reading to stop, and no log messages to be logged.
- """
- # Add a fake error to the list of ignorables:
- udp._sockErrReadIgnore.append(-7000)
- self.addCleanup(udp._sockErrReadIgnore.remove, -7000)
-
- protocol = KeepReads()
- port = udp.Port(None, protocol)
-
- # Normal result, no errors
- port.socket = StringUDPSocket(
- ["result", "123", socket.error(-7000), "456",
- socket.error(-7000)])
- port.doRead()
- # Read stops on error:
- self.assertEqual(protocol.reads, ["result", "123"])
- port.doRead()
- self.assertEqual(protocol.reads, ["result", "123", "456"])
-
-
- def test_readImmediateError(self):
- """
- If the socket is unconnected, socket reads with an immediate
- connection refusal are ignored, and reading stops. The protocol's
- C{connectionRefused} method is not called.
- """
- # Add a fake error to the list of those that count as connection
- # refused:
- udp._sockErrReadRefuse.append(-6000)
- self.addCleanup(udp._sockErrReadRefuse.remove, -6000)
-
- protocol = KeepReads()
- # Fail if connectionRefused is called:
- protocol.connectionRefused = lambda: 1/0
-
- port = udp.Port(None, protocol)
-
- # Try an immediate "connection refused"
- port.socket = StringUDPSocket(["a", socket.error(-6000), "b",
- socket.error(EWOULDBLOCK)])
- port.doRead()
- # Read stops on error:
- self.assertEqual(protocol.reads, ["a"])
- # Read again:
- port.doRead()
- self.assertEqual(protocol.reads, ["a", "b"])
-
-
- def test_connectedReadImmediateError(self):
- """
- If the socket connected, socket reads with an immediate
- connection refusal are ignored, and reading stops. The protocol's
- C{connectionRefused} method is called.
- """
- # Add a fake error to the list of those that count as connection
- # refused:
- udp._sockErrReadRefuse.append(-6000)
- self.addCleanup(udp._sockErrReadRefuse.remove, -6000)
-
- protocol = KeepReads()
- refused = []
- protocol.connectionRefused = lambda: refused.append(True)
-
- port = udp.Port(None, protocol)
- port.socket = StringUDPSocket(["a", socket.error(-6000), "b",
- socket.error(EWOULDBLOCK)])
- port.connect("127.0.0.1", 9999)
-
- # Read stops on error:
- port.doRead()
- self.assertEqual(protocol.reads, ["a"])
- self.assertEqual(refused, [True])
-
- # Read again:
- port.doRead()
- self.assertEqual(protocol.reads, ["a", "b"])
- self.assertEqual(refused, [True])
-
-
- def test_readUnknownError(self):
- """
- Socket reads with an unknown socket error are raised.
- """
- protocol = KeepReads()
- port = udp.Port(None, protocol)
-
- # Some good data, followed by an unknown error
- port.socket = StringUDPSocket(["good", socket.error(-1337)])
- self.assertRaises(socket.error, port.doRead)
- self.assertEqual(protocol.reads, ["good"])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_unix.py
deleted file mode 100755
index b9370da5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_unix.py
+++ /dev/null
@@ -1,558 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorUNIX}.
-"""
-
-from stat import S_IMODE
-from os import stat, close
-from tempfile import mktemp
-from socket import AF_INET, SOCK_STREAM, socket
-from pprint import pformat
-
-try:
- from socket import AF_UNIX
-except ImportError:
- AF_UNIX = None
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.python.log import addObserver, removeObserver, err
-from twisted.python.failure import Failure
-from twisted.python.hashlib import md5
-from twisted.python.runtime import platform
-from twisted.internet.interfaces import (
- IConnector, IFileDescriptorReceiver, IReactorUNIX)
-from twisted.internet.error import ConnectionClosed, FileDescriptorOverrun
-from twisted.internet.address import UNIXAddress
-from twisted.internet.endpoints import UNIXServerEndpoint, UNIXClientEndpoint
-from twisted.internet.defer import Deferred, fail
-from twisted.internet.task import LoopingCall
-from twisted.internet import interfaces
-from twisted.internet.protocol import (
- ServerFactory, ClientFactory, DatagramProtocol)
-from twisted.internet.test.reactormixins import ReactorBuilder, EndpointCreator
-from twisted.internet.test.test_core import ObjectModelIntegrationMixin
-from twisted.internet.test.test_tcp import StreamTransportTestsMixin
-from twisted.internet.test.reactormixins import (
- ConnectableProtocol, runProtocolsWithReactor)
-from twisted.internet.test.connectionmixins import ConnectionTestsMixin
-
-try:
- from twisted.python import sendmsg
-except ImportError:
- sendmsgSkip = (
- "sendmsg extension unavailable, extended UNIX features disabled")
-else:
- sendmsgSkip = None
-
-
-class UNIXFamilyMixin:
- """
- Test-helper defining mixin for things related to AF_UNIX sockets.
- """
- def _modeTest(self, methodName, path, factory):
- """
- Assert that the mode of the created unix socket is set to the mode
- specified to the reactor method.
- """
- mode = 0600
- reactor = self.buildReactor()
- unixPort = getattr(reactor, methodName)(path, factory, mode=mode)
- unixPort.stopListening()
- self.assertEqual(S_IMODE(stat(path).st_mode), mode)
-
-
-def _abstractPath(case):
- """
- Return a new, unique abstract namespace path to be listened on.
- """
- # Use the test cases's mktemp to get something unique, but also squash it
- # down to make sure it fits in the unix socket path limit (something around
- # 110 bytes).
- return md5(case.mktemp()).hexdigest()
-
-
-
-class UNIXCreator(EndpointCreator):
- """
- Create UNIX socket end points.
- """
- requiredInterfaces = (interfaces.IReactorUNIX,)
-
- def server(self, reactor):
- """
- Construct a UNIX server endpoint.
- """
- # self.mktemp() often returns a path which is too long to be used.
- path = mktemp(suffix='.sock', dir='.')
- return UNIXServerEndpoint(reactor, path)
-
-
- def client(self, reactor, serverAddress):
- """
- Construct a UNIX client endpoint.
- """
- return UNIXClientEndpoint(reactor, serverAddress.name)
-
-
-
-class SendFileDescriptor(ConnectableProtocol):
- """
- L{SendFileDescriptorAndBytes} sends a file descriptor and optionally some
- normal bytes and then closes its connection.
-
- @ivar reason: The reason the connection was lost, after C{connectionLost}
- is called.
- """
- reason = None
-
- def __init__(self, fd, data):
- """
- @param fd: A C{int} giving a file descriptor to send over the
- connection.
-
- @param data: A C{str} giving data to send over the connection, or
- C{None} if no data is to be sent.
- """
- self.fd = fd
- self.data = data
-
-
- def connectionMade(self):
- """
- Send C{self.fd} and, if it is not C{None}, C{self.data}. Then close the
- connection.
- """
- self.transport.sendFileDescriptor(self.fd)
- if self.data:
- self.transport.write(self.data)
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- ConnectableProtocol.connectionLost(self, reason)
- self.reason = reason
-
-
-
-class ReceiveFileDescriptor(ConnectableProtocol):
- """
- L{ReceiveFileDescriptor} provides an API for waiting for file descriptors to
- be received.
-
- @ivar reason: The reason the connection was lost, after C{connectionLost}
- is called.
-
- @ivar waiting: A L{Deferred} which fires with a file descriptor once one is
- received, or with a failure if the connection is lost with no descriptor
- arriving.
- """
- implements(IFileDescriptorReceiver)
-
- reason = None
- waiting = None
-
- def waitForDescriptor(self):
- """
- Return a L{Deferred} which will fire with the next file descriptor
- received, or with a failure if the connection is or has already been
- lost.
- """
- if self.reason is None:
- self.waiting = Deferred()
- return self.waiting
- else:
- return fail(self.reason)
-
-
- def fileDescriptorReceived(self, descriptor):
- """
- Fire the waiting Deferred, initialized by C{waitForDescriptor}, with the
- file descriptor just received.
- """
- self.waiting.callback(descriptor)
- self.waiting = None
-
-
- def dataReceived(self, data):
- """
- Fail the waiting Deferred, if it has not already been fired by
- C{fileDescriptorReceived}. The bytes sent along with a file descriptor
- are guaranteed to be delivered to the protocol's C{dataReceived} method
- only after the file descriptor has been delivered to the protocol's
- C{fileDescriptorReceived}.
- """
- if self.waiting is not None:
- self.waiting.errback(Failure(Exception(
- "Received bytes (%r) before descriptor." % (data,))))
- self.waiting = None
-
-
- def connectionLost(self, reason):
- """
- Fail the waiting Deferred, initialized by C{waitForDescriptor}, if there
- is one.
- """
- ConnectableProtocol.connectionLost(self, reason)
- if self.waiting is not None:
- self.waiting.errback(reason)
- self.waiting = None
- self.reason = reason
-
-
-
-class UNIXTestsBuilder(UNIXFamilyMixin, ReactorBuilder, ConnectionTestsMixin):
- """
- Builder defining tests relating to L{IReactorUNIX}.
- """
- requiredInterfaces = (IReactorUNIX,)
-
- endpoints = UNIXCreator()
-
- def test_interface(self):
- """
- L{IReactorUNIX.connectUNIX} returns an object providing L{IConnector}.
- """
- reactor = self.buildReactor()
- connector = reactor.connectUNIX(self.mktemp(), ClientFactory())
- self.assertTrue(verifyObject(IConnector, connector))
-
-
- def test_mode(self):
- """
- The UNIX socket created by L{IReactorUNIX.listenUNIX} is created with
- the mode specified.
- """
- self._modeTest('listenUNIX', self.mktemp(), ServerFactory())
-
-
- def test_listenOnLinuxAbstractNamespace(self):
- """
- On Linux, a UNIX socket path may begin with C{'\0'} to indicate a socket
- in the abstract namespace. L{IReactorUNIX.listenUNIX} accepts such a
- path.
- """
- # Don't listen on a path longer than the maximum allowed.
- path = _abstractPath(self)
- reactor = self.buildReactor()
- port = reactor.listenUNIX('\0' + path, ServerFactory())
- self.assertEqual(port.getHost(), UNIXAddress('\0' + path))
- if not platform.isLinux():
- test_listenOnLinuxAbstractNamespace.skip = (
- 'Abstract namespace UNIX sockets only supported on Linux.')
-
-
- def test_connectToLinuxAbstractNamespace(self):
- """
- L{IReactorUNIX.connectUNIX} also accepts a Linux abstract namespace
- path.
- """
- path = _abstractPath(self)
- reactor = self.buildReactor()
- connector = reactor.connectUNIX('\0' + path, ClientFactory())
- self.assertEqual(
- connector.getDestination(), UNIXAddress('\0' + path))
- if not platform.isLinux():
- test_connectToLinuxAbstractNamespace.skip = (
- 'Abstract namespace UNIX sockets only supported on Linux.')
-
-
- def test_addresses(self):
- """
- A client's transport's C{getHost} and C{getPeer} return L{UNIXAddress}
- instances which have the filesystem path of the host and peer ends of
- the connection.
- """
- class SaveAddress(ConnectableProtocol):
- def makeConnection(self, transport):
- self.addresses = dict(
- host=transport.getHost(), peer=transport.getPeer())
- transport.loseConnection()
-
- server = SaveAddress()
- client = SaveAddress()
-
- runProtocolsWithReactor(self, server, client, self.endpoints)
-
- self.assertEqual(server.addresses['host'], client.addresses['peer'])
- self.assertEqual(server.addresses['peer'], client.addresses['host'])
-
-
- def test_sendFileDescriptor(self):
- """
- L{IUNIXTransport.sendFileDescriptor} accepts an integer file descriptor
- and sends a copy of it to the process reading from the connection.
- """
- from socket import fromfd
-
- s = socket()
- s.bind(('', 0))
- server = SendFileDescriptor(s.fileno(), "junk")
-
- client = ReceiveFileDescriptor()
- d = client.waitForDescriptor()
- def checkDescriptor(descriptor):
- received = fromfd(descriptor, AF_INET, SOCK_STREAM)
- # Thanks for the free dup, fromfd()
- close(descriptor)
-
- # If the sockets have the same local address, they're probably the
- # same.
- self.assertEqual(s.getsockname(), received.getsockname())
-
- # But it would be cheating for them to be identified by the same
- # file descriptor. The point was to get a copy, as we might get if
- # there were two processes involved here.
- self.assertNotEqual(s.fileno(), received.fileno())
- d.addCallback(checkDescriptor)
- d.addErrback(err, "Sending file descriptor encountered a problem")
- d.addBoth(lambda ignored: server.transport.loseConnection())
-
- runProtocolsWithReactor(self, server, client, self.endpoints)
- if sendmsgSkip is not None:
- test_sendFileDescriptor.skip = sendmsgSkip
-
-
- def test_sendFileDescriptorTriggersPauseProducing(self):
- """
- If a L{IUNIXTransport.sendFileDescriptor} call fills up the send buffer,
- any registered producer is paused.
- """
- class DoesNotRead(ConnectableProtocol):
- def connectionMade(self):
- self.transport.pauseProducing()
-
- class SendsManyFileDescriptors(ConnectableProtocol):
- paused = False
-
- def connectionMade(self):
- self.socket = socket()
- self.transport.registerProducer(self, True)
- def sender():
- self.transport.sendFileDescriptor(self.socket.fileno())
- self.transport.write("x")
- self.task = LoopingCall(sender)
- self.task.clock = self.transport.reactor
- self.task.start(0).addErrback(err, "Send loop failure")
-
- def stopProducing(self):
- self._disconnect()
-
- def resumeProducing(self):
- self._disconnect()
-
- def pauseProducing(self):
- self.paused = True
- self.transport.unregisterProducer()
- self._disconnect()
-
- def _disconnect(self):
- self.task.stop()
- self.transport.abortConnection()
- self.other.transport.abortConnection()
-
- server = SendsManyFileDescriptors()
- client = DoesNotRead()
- server.other = client
- runProtocolsWithReactor(self, server, client, self.endpoints)
-
- self.assertTrue(
- server.paused, "sendFileDescriptor producer was not paused")
- if sendmsgSkip is not None:
- test_sendFileDescriptorTriggersPauseProducing.skip = sendmsgSkip
-
-
- def test_fileDescriptorOverrun(self):
- """
- If L{IUNIXTransport.sendFileDescriptor} is used to queue a greater
- number of file descriptors than the number of bytes sent using
- L{ITransport.write}, the connection is closed and the protocol connected
- to the transport has its C{connectionLost} method called with a failure
- wrapping L{FileDescriptorOverrun}.
- """
- cargo = socket()
- server = SendFileDescriptor(cargo.fileno(), None)
-
- client = ReceiveFileDescriptor()
- d = self.assertFailure(
- client.waitForDescriptor(), ConnectionClosed)
- d.addErrback(
- err, "Sending file descriptor encountered unexpected problem")
- d.addBoth(lambda ignored: server.transport.loseConnection())
-
- runProtocolsWithReactor(self, server, client, self.endpoints)
-
- self.assertIsInstance(server.reason.value, FileDescriptorOverrun)
- if sendmsgSkip is not None:
- test_fileDescriptorOverrun.skip = sendmsgSkip
-
-
- def test_avoidLeakingFileDescriptors(self):
- """
- If associated with a protocol which does not provide
- L{IFileDescriptorReceiver}, file descriptors received by the
- L{IUNIXTransport} implementation are closed and a warning is emitted.
- """
- # To verify this, establish a connection. Send one end of the
- # connection over the IUNIXTransport implementation. After the copy
- # should no longer exist, close the original. If the opposite end of
- # the connection decides the connection is closed, the copy does not
- # exist.
- from socket import socketpair
- probeClient, probeServer = socketpair()
-
- events = []
- addObserver(events.append)
- self.addCleanup(removeObserver, events.append)
-
- class RecordEndpointAddresses(SendFileDescriptor):
- def connectionMade(self):
- self.hostAddress = self.transport.getHost()
- self.peerAddress = self.transport.getPeer()
- SendFileDescriptor.connectionMade(self)
-
- server = RecordEndpointAddresses(probeClient.fileno(), "junk")
- client = ConnectableProtocol()
-
- runProtocolsWithReactor(self, server, client, self.endpoints)
-
- # Get rid of the original reference to the socket.
- probeClient.close()
-
- # A non-blocking recv will return "" if the connection is closed, as
- # desired. If the connection has not been closed, because the duplicate
- # file descriptor is still open, it will fail with EAGAIN instead.
- probeServer.setblocking(False)
- self.assertEqual("", probeServer.recv(1024))
-
- # This is a surprising circumstance, so it should be logged.
- format = (
- "%(protocolName)s (on %(hostAddress)r) does not "
- "provide IFileDescriptorReceiver; closing file "
- "descriptor received (from %(peerAddress)r).")
- clsName = "ConnectableProtocol"
-
- # Reverse host and peer, since the log event is from the client
- # perspective.
- expectedEvent = dict(hostAddress=server.peerAddress,
- peerAddress=server.hostAddress,
- protocolName=clsName,
- format=format)
-
- for logEvent in events:
- for k, v in expectedEvent.iteritems():
- if v != logEvent.get(k):
- break
- else:
- # No mismatches were found, stop looking at events
- break
- else:
- # No fully matching events were found, fail the test.
- self.fail(
- "Expected event (%s) not found in logged events (%s)" % (
- expectedEvent, pformat(events,)))
- if sendmsgSkip is not None:
- test_avoidLeakingFileDescriptors.skip = sendmsgSkip
-
-
- def test_descriptorDeliveredBeforeBytes(self):
- """
- L{IUNIXTransport.sendFileDescriptor} sends file descriptors before
- L{ITransport.write} sends normal bytes.
- """
- class RecordEvents(ConnectableProtocol):
- implements(IFileDescriptorReceiver)
-
- def connectionMade(self):
- ConnectableProtocol.connectionMade(self)
- self.events = []
-
- def fileDescriptorReceived(innerSelf, descriptor):
- self.addCleanup(close, descriptor)
- innerSelf.events.append(type(descriptor))
-
- def dataReceived(self, data):
- self.events.extend(data)
-
- cargo = socket()
- server = SendFileDescriptor(cargo.fileno(), "junk")
- client = RecordEvents()
-
- runProtocolsWithReactor(self, server, client, self.endpoints)
-
- self.assertEqual([int, "j", "u", "n", "k"], client.events)
- if sendmsgSkip is not None:
- test_descriptorDeliveredBeforeBytes.skip = sendmsgSkip
-
-
-
-class UNIXDatagramTestsBuilder(UNIXFamilyMixin, ReactorBuilder):
- """
- Builder defining tests relating to L{IReactorUNIXDatagram}.
- """
- requiredInterfaces = (interfaces.IReactorUNIXDatagram,)
-
- # There's no corresponding test_connectMode because the mode parameter to
- # connectUNIXDatagram has been completely ignored since that API was first
- # introduced.
- def test_listenMode(self):
- """
- The UNIX socket created by L{IReactorUNIXDatagram.listenUNIXDatagram}
- is created with the mode specified.
- """
- self._modeTest('listenUNIXDatagram', self.mktemp(), DatagramProtocol())
-
-
- def test_listenOnLinuxAbstractNamespace(self):
- """
- On Linux, a UNIX socket path may begin with C{'\0'} to indicate a socket
- in the abstract namespace. L{IReactorUNIX.listenUNIXDatagram} accepts
- such a path.
- """
- path = _abstractPath(self)
- reactor = self.buildReactor()
- port = reactor.listenUNIXDatagram('\0' + path, DatagramProtocol())
- self.assertEqual(port.getHost(), UNIXAddress('\0' + path))
- if not platform.isLinux():
- test_listenOnLinuxAbstractNamespace.skip = (
- 'Abstract namespace UNIX sockets only supported on Linux.')
-
-
-
-class UNIXPortTestsBuilder(ReactorBuilder, ObjectModelIntegrationMixin,
- StreamTransportTestsMixin):
- """
- Tests for L{IReactorUNIX.listenUnix}
- """
- requiredInterfaces = (interfaces.IReactorUNIX,)
-
- def getListeningPort(self, reactor, factory):
- """
- Get a UNIX port from a reactor
- """
- # self.mktemp() often returns a path which is too long to be used.
- path = mktemp(suffix='.sock', dir='.')
- return reactor.listenUNIX(path, factory)
-
-
- def getExpectedStartListeningLogMessage(self, port, factory):
- """
- Get the message expected to be logged when a UNIX port starts listening.
- """
- return "%s starting on %r" % (factory, port.getHost().name)
-
-
- def getExpectedConnectionLostLogMsg(self, port):
- """
- Get the expected connection lost message for a UNIX port
- """
- return "(UNIX Port %s Closed)" % (repr(port.port),)
-
-
-
-globals().update(UNIXTestsBuilder.makeTestCaseClasses())
-globals().update(UNIXDatagramTestsBuilder.makeTestCaseClasses())
-globals().update(UNIXPortTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_win32events.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_win32events.py
deleted file mode 100755
index b8ba59b6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/test/test_win32events.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorWin32Events}.
-"""
-
-from thread import get_ident
-
-try:
- import win32event
-except ImportError:
- win32event = None
-
-from zope.interface.verify import verifyObject
-
-from twisted.python.threadable import isInIOThread
-from twisted.internet.interfaces import IReactorWin32Events
-from twisted.internet.defer import Deferred
-from twisted.internet.test.reactormixins import ReactorBuilder
-
-
-class Listener(object):
- """
- L{Listener} is an object that can be added to a L{IReactorWin32Events}
- reactor to receive callback notification when a Windows event is set. It
- records what thread its callback is invoked in and fires a Deferred.
-
- @ivar success: A flag which is set to C{True} when the event callback is
- called.
-
- @ivar logThreadID: The id of the thread in which the C{logPrefix} method is
- called.
-
- @ivar eventThreadID: The id of the thread in which the event callback is
- called.
-
- @ivar connLostThreadID: The id of the thread in which the C{connectionLost}
- method is called.
-
- @ivar _finished: The L{Deferred} which will be fired when the event callback
- is called.
- """
- success = False
- logThreadID = eventThreadID = connLostThreadID = None
-
- def __init__(self, finished):
- self._finished = finished
-
-
- def logPrefix(self):
- self.logThreadID = get_ident()
- return 'Listener'
-
-
- def occurred(self):
- self.success = True
- self.eventThreadID = get_ident()
- self._finished.callback(None)
-
-
- def brokenOccurred(self):
- raise RuntimeError("Some problem")
-
-
- def returnValueOccurred(self):
- return EnvironmentError("Entirely different problem")
-
-
- def connectionLost(self, reason):
- self.connLostThreadID = get_ident()
- self._finished.errback(reason)
-
-
-
-class Win32EventsTestsBuilder(ReactorBuilder):
- """
- Builder defining tests relating to L{IReactorWin32Events}.
- """
- requiredInterfaces = [IReactorWin32Events]
-
- def test_interface(self):
- """
- An instance of the reactor has all of the methods defined on
- L{IReactorWin32Events}.
- """
- reactor = self.buildReactor()
- verifyObject(IReactorWin32Events, reactor)
-
-
- def test_addEvent(self):
- """
- When an event which has been added to the reactor is set, the action
- associated with the event is invoked in the reactor thread.
- """
- reactorThreadID = get_ident()
- reactor = self.buildReactor()
- event = win32event.CreateEvent(None, False, False, None)
- finished = Deferred()
- finished.addCallback(lambda ignored: reactor.stop())
- listener = Listener(finished)
- reactor.addEvent(event, listener, 'occurred')
- reactor.callWhenRunning(win32event.SetEvent, event)
- self.runReactor(reactor)
- self.assertTrue(listener.success)
- self.assertEqual(reactorThreadID, listener.logThreadID)
- self.assertEqual(reactorThreadID, listener.eventThreadID)
-
-
- def test_ioThreadDoesNotChange(self):
- """
- Using L{IReactorWin32Events.addEvent} does not change which thread is
- reported as the I/O thread.
- """
- results = []
- def check(ignored):
- results.append(isInIOThread())
- reactor.stop()
- reactor = self.buildReactor()
- event = win32event.CreateEvent(None, False, False, None)
- finished = Deferred()
- listener = Listener(finished)
- finished.addCallback(check)
- reactor.addEvent(event, listener, 'occurred')
- reactor.callWhenRunning(win32event.SetEvent, event)
- self.runReactor(reactor)
- self.assertTrue(listener.success)
- self.assertEqual([True], results)
-
-
- def test_disconnectedOnError(self):
- """
- If the event handler raises an exception, the event is removed from the
- reactor and the handler's C{connectionLost} method is called in the I/O
- thread and the exception is logged.
- """
- reactorThreadID = get_ident()
- reactor = self.buildReactor()
- event = win32event.CreateEvent(None, False, False, None)
- finished = self.assertFailure(Deferred(), RuntimeError)
- finished.addCallback(lambda ignored: reactor.stop())
- listener = Listener(finished)
- reactor.addEvent(event, listener, 'brokenOccurred')
- reactor.callWhenRunning(win32event.SetEvent, event)
- self.runReactor(reactor)
- self.assertEqual(reactorThreadID, listener.connLostThreadID)
- self.assertEqual(1, len(self.flushLoggedErrors(RuntimeError)))
-
-
- def test_disconnectOnReturnValue(self):
- """
- If the event handler returns a value, the event is removed from the
- reactor and the handler's C{connectionLost} method is called in the I/O
- thread.
- """
- reactorThreadID = get_ident()
- reactor = self.buildReactor()
- event = win32event.CreateEvent(None, False, False, None)
- finished = self.assertFailure(Deferred(), EnvironmentError)
- finished.addCallback(lambda ignored: reactor.stop())
- listener = Listener(finished)
- reactor.addEvent(event, listener, 'returnValueOccurred')
- reactor.callWhenRunning(win32event.SetEvent, event)
- self.runReactor(reactor)
- self.assertEqual(reactorThreadID, listener.connLostThreadID)
-
-
- def test_notDisconnectedOnShutdown(self):
- """
- Event handlers added with L{IReactorWin32Events.addEvent} do not have
- C{connectionLost} called on them if they are still active when the
- reactor shuts down.
- """
- reactor = self.buildReactor()
- event = win32event.CreateEvent(None, False, False, None)
- finished = Deferred()
- listener = Listener(finished)
- reactor.addEvent(event, listener, 'occurred')
- reactor.callWhenRunning(reactor.stop)
- self.runReactor(reactor)
- self.assertIdentical(None, listener.connLostThreadID)
-
-globals().update(Win32EventsTestsBuilder.makeTestCaseClasses())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/threads.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/threads.py
deleted file mode 100755
index a69a3471..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/threads.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Extended thread dispatching support.
-
-For basic support see reactor threading API docs.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-import Queue
-
-from twisted.python import failure
-from twisted.internet import defer
-
-
-def deferToThreadPool(reactor, threadpool, f, *args, **kwargs):
- """
- Call the function C{f} using a thread from the given threadpool and return
- the result as a Deferred.
-
- This function is only used by client code which is maintaining its own
- threadpool. To run a function in the reactor's threadpool, use
- C{deferToThread}.
-
- @param reactor: The reactor in whose main thread the Deferred will be
- invoked.
-
- @param threadpool: An object which supports the C{callInThreadWithCallback}
- method of C{twisted.python.threadpool.ThreadPool}.
-
- @param f: The function to call.
- @param *args: positional arguments to pass to f.
- @param **kwargs: keyword arguments to pass to f.
-
- @return: A Deferred which fires a callback with the result of f, or an
- errback with a L{twisted.python.failure.Failure} if f throws an
- exception.
- """
- d = defer.Deferred()
-
- def onResult(success, result):
- if success:
- reactor.callFromThread(d.callback, result)
- else:
- reactor.callFromThread(d.errback, result)
-
- threadpool.callInThreadWithCallback(onResult, f, *args, **kwargs)
-
- return d
-
-
-def deferToThread(f, *args, **kwargs):
- """
- Run a function in a thread and return the result as a Deferred.
-
- @param f: The function to call.
- @param *args: positional arguments to pass to f.
- @param **kwargs: keyword arguments to pass to f.
-
- @return: A Deferred which fires a callback with the result of f,
- or an errback with a L{twisted.python.failure.Failure} if f throws
- an exception.
- """
- from twisted.internet import reactor
- return deferToThreadPool(reactor, reactor.getThreadPool(),
- f, *args, **kwargs)
-
-
-def _runMultiple(tupleList):
- """
- Run a list of functions.
- """
- for f, args, kwargs in tupleList:
- f(*args, **kwargs)
-
-
-def callMultipleInThread(tupleList):
- """
- Run a list of functions in the same thread.
-
- tupleList should be a list of (function, argsList, kwargsDict) tuples.
- """
- from twisted.internet import reactor
- reactor.callInThread(_runMultiple, tupleList)
-
-
-def blockingCallFromThread(reactor, f, *a, **kw):
- """
- Run a function in the reactor from a thread, and wait for the result
- synchronously. If the function returns a L{Deferred}, wait for its
- result and return that.
-
- @param reactor: The L{IReactorThreads} provider which will be used to
- schedule the function call.
- @param f: the callable to run in the reactor thread
- @type f: any callable.
- @param a: the arguments to pass to C{f}.
- @param kw: the keyword arguments to pass to C{f}.
-
- @return: the result of the L{Deferred} returned by C{f}, or the result
- of C{f} if it returns anything other than a L{Deferred}.
-
- @raise: If C{f} raises a synchronous exception,
- C{blockingCallFromThread} will raise that exception. If C{f}
- returns a L{Deferred} which fires with a L{Failure},
- C{blockingCallFromThread} will raise that failure's exception (see
- L{Failure.raiseException}).
- """
- queue = Queue.Queue()
- def _callFromThread():
- result = defer.maybeDeferred(f, *a, **kw)
- result.addBoth(queue.put)
- reactor.callFromThread(_callFromThread)
- result = queue.get()
- if isinstance(result, failure.Failure):
- result.raiseException()
- return result
-
-
-__all__ = ["deferToThread", "deferToThreadPool", "callMultipleInThread",
- "blockingCallFromThread"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tksupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tksupport.py
deleted file mode 100755
index ddec55ed..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/tksupport.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-This module integrates Tkinter with twisted.internet's mainloop.
-
-Maintainer: Itamar Shtull-Trauring
-
-To use, do::
-
- | tksupport.install(rootWidget)
-
-and then run your reactor as usual - do *not* call Tk's mainloop(),
-use Twisted's regular mechanism for running the event loop.
-
-Likewise, to stop your program you will need to stop Twisted's
-event loop. For example, if you want closing your root widget to
-stop Twisted::
-
- | root.protocol('WM_DELETE_WINDOW', reactor.stop)
-
-When using Aqua Tcl/Tk on Mac OS X the standard Quit menu item in
-your application might become unresponsive without the additional
-fix::
-
- | root.createcommand("::tk::mac::Quit", reactor.stop)
-
-@see: U{Tcl/TkAqua FAQ for more info<http://wiki.tcl.tk/12987>}
-"""
-
-# system imports
-import Tkinter, tkSimpleDialog, tkMessageBox
-
-# twisted imports
-from twisted.python import log
-from twisted.internet import task
-
-
-_task = None
-
-def install(widget, ms=10, reactor=None):
- """Install a Tkinter.Tk() object into the reactor."""
- installTkFunctions()
- global _task
- _task = task.LoopingCall(widget.update)
- _task.start(ms / 1000.0, False)
-
-def uninstall():
- """Remove the root Tk widget from the reactor.
-
- Call this before destroy()ing the root widget.
- """
- global _task
- _task.stop()
- _task = None
-
-
-def installTkFunctions():
- import twisted.python.util
- twisted.python.util.getPassword = getPassword
-
-
-def getPassword(prompt = '', confirm = 0):
- while 1:
- try1 = tkSimpleDialog.askstring('Password Dialog', prompt, show='*')
- if not confirm:
- return try1
- try2 = tkSimpleDialog.askstring('Password Dialog', 'Confirm Password', show='*')
- if try1 == try2:
- return try1
- else:
- tkMessageBox.showerror('Password Mismatch', 'Passwords did not match, starting over')
-
-__all__ = ["install", "uninstall"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py
deleted file mode 100755
index 42bd3489..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py
+++ /dev/null
@@ -1,347 +0,0 @@
-# -*- test-case-name: twisted.test.test_udp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Various asynchronous UDP classes.
-
-Please do not use this module directly.
-
-@var _sockErrReadIgnore: list of symbolic error constants (from the C{errno}
- module) representing socket errors where the error is temporary and can be
- ignored.
-
-@var _sockErrReadRefuse: list of symbolic error constants (from the C{errno}
- module) representing socket errors that indicate connection refused.
-"""
-
-# System Imports
-import socket
-import operator
-import struct
-import warnings
-
-from zope.interface import implements
-
-from twisted.python.runtime import platformType
-if platformType == 'win32':
- from errno import WSAEWOULDBLOCK
- from errno import WSAEINTR, WSAEMSGSIZE, WSAETIMEDOUT
- from errno import WSAECONNREFUSED, WSAECONNRESET, WSAENETRESET
- from errno import WSAEINPROGRESS
-
- # Classify read and write errors
- _sockErrReadIgnore = [WSAEINTR, WSAEWOULDBLOCK, WSAEMSGSIZE, WSAEINPROGRESS]
- _sockErrReadRefuse = [WSAECONNREFUSED, WSAECONNRESET, WSAENETRESET,
- WSAETIMEDOUT]
-
- # POSIX-compatible write errors
- EMSGSIZE = WSAEMSGSIZE
- ECONNREFUSED = WSAECONNREFUSED
- EAGAIN = WSAEWOULDBLOCK
- EINTR = WSAEINTR
-else:
- from errno import EWOULDBLOCK, EINTR, EMSGSIZE, ECONNREFUSED, EAGAIN
- _sockErrReadIgnore = [EAGAIN, EINTR, EWOULDBLOCK]
- _sockErrReadRefuse = [ECONNREFUSED]
-
-# Twisted Imports
-from twisted.internet import base, defer, address
-from twisted.python import log, failure
-from twisted.internet import abstract, error, interfaces
-
-
-class Port(base.BasePort):
- """
- UDP port, listening for packets.
- """
- implements(
- interfaces.IListeningPort, interfaces.IUDPTransport,
- interfaces.ISystemHandle)
-
- addressFamily = socket.AF_INET
- socketType = socket.SOCK_DGRAM
- maxThroughput = 256 * 1024 # max bytes we read in one eventloop iteration
-
- # Actual port number being listened on, only set to a non-None
- # value when we are actually listening.
- _realPortNumber = None
-
- def __init__(self, port, proto, interface='', maxPacketSize=8192, reactor=None):
- """
- Initialize with a numeric port to listen on.
- """
- base.BasePort.__init__(self, reactor)
- self.port = port
- self.protocol = proto
- self.maxPacketSize = maxPacketSize
- self.interface = interface
- self.setLogStr()
- self._connectedAddr = None
-
- def __repr__(self):
- if self._realPortNumber is not None:
- return "<%s on %s>" % (self.protocol.__class__, self._realPortNumber)
- else:
- return "<%s not connected>" % (self.protocol.__class__,)
-
- def getHandle(self):
- """
- Return a socket object.
- """
- return self.socket
-
- def startListening(self):
- """
- Create and bind my socket, and begin listening on it.
-
- This is called on unserialization, and must be called after creating a
- server to begin listening on the specified port.
- """
- self._bindSocket()
- self._connectToProtocol()
-
- def _bindSocket(self):
- try:
- skt = self.createInternetSocket()
- skt.bind((self.interface, self.port))
- except socket.error, le:
- raise error.CannotListenError, (self.interface, self.port, le)
-
- # Make sure that if we listened on port 0, we update that to
- # reflect what the OS actually assigned us.
- self._realPortNumber = skt.getsockname()[1]
-
- log.msg("%s starting on %s" % (
- self._getLogPrefix(self.protocol), self._realPortNumber))
-
- self.connected = 1
- self.socket = skt
- self.fileno = self.socket.fileno
-
- def _connectToProtocol(self):
- self.protocol.makeConnection(self)
- self.startReading()
-
-
- def doRead(self):
- """
- Called when my socket is ready for reading.
- """
- read = 0
- while read < self.maxThroughput:
- try:
- data, addr = self.socket.recvfrom(self.maxPacketSize)
- except socket.error, se:
- no = se.args[0]
- if no in _sockErrReadIgnore:
- return
- if no in _sockErrReadRefuse:
- if self._connectedAddr:
- self.protocol.connectionRefused()
- return
- raise
- else:
- read += len(data)
- try:
- self.protocol.datagramReceived(data, addr)
- except:
- log.err()
-
-
- def write(self, datagram, addr=None):
- """
- Write a datagram.
-
- @type datagram: C{str}
- @param datagram: The datagram to be sent.
-
- @type addr: C{tuple} containing C{str} as first element and C{int} as
- second element, or C{None}
- @param addr: A tuple of (I{stringified dotted-quad IP address},
- I{integer port number}); can be C{None} in connected mode.
- """
- if self._connectedAddr:
- assert addr in (None, self._connectedAddr)
- try:
- return self.socket.send(datagram)
- except socket.error, se:
- no = se.args[0]
- if no == EINTR:
- return self.write(datagram)
- elif no == EMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif no == ECONNREFUSED:
- self.protocol.connectionRefused()
- else:
- raise
- else:
- assert addr != None
- if not addr[0].replace(".", "").isdigit() and addr[0] != "<broadcast>":
- warnings.warn("Please only pass IPs to write(), not hostnames",
- DeprecationWarning, stacklevel=2)
- try:
- return self.socket.sendto(datagram, addr)
- except socket.error, se:
- no = se.args[0]
- if no == EINTR:
- return self.write(datagram, addr)
- elif no == EMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif no == ECONNREFUSED:
- # in non-connected UDP ECONNREFUSED is platform dependent, I
- # think and the info is not necessarily useful. Nevertheless
- # maybe we should call connectionRefused? XXX
- return
- else:
- raise
-
- def writeSequence(self, seq, addr):
- self.write("".join(seq), addr)
-
- def connect(self, host, port):
- """
- 'Connect' to remote server.
- """
- if self._connectedAddr:
- raise RuntimeError, "already connected, reconnecting is not currently supported (talk to itamar if you want this)"
- if not abstract.isIPAddress(host):
- raise ValueError, "please pass only IP addresses, not domain names"
- self._connectedAddr = (host, port)
- self.socket.connect((host, port))
-
- def _loseConnection(self):
- self.stopReading()
- if self.connected: # actually means if we are *listening*
- self.reactor.callLater(0, self.connectionLost)
-
- def stopListening(self):
- if self.connected:
- result = self.d = defer.Deferred()
- else:
- result = None
- self._loseConnection()
- return result
-
- def loseConnection(self):
- warnings.warn("Please use stopListening() to disconnect port", DeprecationWarning, stacklevel=2)
- self.stopListening()
-
- def connectionLost(self, reason=None):
- """
- Cleans up my socket.
- """
- log.msg('(UDP Port %s Closed)' % self._realPortNumber)
- self._realPortNumber = None
- base.BasePort.connectionLost(self, reason)
- self.protocol.doStop()
- self.socket.close()
- del self.socket
- del self.fileno
- if hasattr(self, "d"):
- self.d.callback(None)
- del self.d
-
-
- def setLogStr(self):
- """
- Initialize the C{logstr} attribute to be used by C{logPrefix}.
- """
- logPrefix = self._getLogPrefix(self.protocol)
- self.logstr = "%s (UDP)" % logPrefix
-
-
- def logPrefix(self):
- """
- Return the prefix to log with.
- """
- return self.logstr
-
-
- def getHost(self):
- """
- Returns an IPv4Address.
-
- This indicates the address from which I am connecting.
- """
- return address.IPv4Address('UDP', *self.socket.getsockname())
-
-
-
-class MulticastMixin:
- """
- Implement multicast functionality.
- """
-
- def getOutgoingInterface(self):
- i = self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF)
- return socket.inet_ntoa(struct.pack("@i", i))
-
- def setOutgoingInterface(self, addr):
- """Returns Deferred of success."""
- return self.reactor.resolve(addr).addCallback(self._setInterface)
-
- def _setInterface(self, addr):
- i = socket.inet_aton(addr)
- self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, i)
- return 1
-
- def getLoopbackMode(self):
- return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP)
-
- def setLoopbackMode(self, mode):
- mode = struct.pack("b", operator.truth(mode))
- self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, mode)
-
- def getTTL(self):
- return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL)
-
- def setTTL(self, ttl):
- ttl = struct.pack("B", ttl)
- self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
-
- def joinGroup(self, addr, interface=""):
- """Join a multicast group. Returns Deferred of success."""
- return self.reactor.resolve(addr).addCallback(self._joinAddr1, interface, 1)
-
- def _joinAddr1(self, addr, interface, join):
- return self.reactor.resolve(interface).addCallback(self._joinAddr2, addr, join)
-
- def _joinAddr2(self, interface, addr, join):
- addr = socket.inet_aton(addr)
- interface = socket.inet_aton(interface)
- if join:
- cmd = socket.IP_ADD_MEMBERSHIP
- else:
- cmd = socket.IP_DROP_MEMBERSHIP
- try:
- self.socket.setsockopt(socket.IPPROTO_IP, cmd, addr + interface)
- except socket.error, e:
- return failure.Failure(error.MulticastJoinError(addr, interface, *e.args))
-
- def leaveGroup(self, addr, interface=""):
- """Leave multicast group, return Deferred of success."""
- return self.reactor.resolve(addr).addCallback(self._joinAddr1, interface, 0)
-
-
-class MulticastPort(MulticastMixin, Port):
- """
- UDP Port that supports multicasting.
- """
-
- implements(interfaces.IMulticastTransport)
-
- def __init__(self, port, proto, interface='', maxPacketSize=8192, reactor=None, listenMultiple=False):
- """
- @see: L{twisted.internet.interfaces.IReactorMulticast.listenMulticast}
- """
- Port.__init__(self, port, proto, interface, maxPacketSize, reactor)
- self.listenMultiple = listenMultiple
-
- def createInternetSocket(self):
- skt = Port.createInternetSocket(self)
- if self.listenMultiple:
- skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- if hasattr(socket, "SO_REUSEPORT"):
- skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
- return skt
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/unix.py
deleted file mode 100755
index 77b87cd2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/unix.py
+++ /dev/null
@@ -1,518 +0,0 @@
-# -*- test-case-name: twisted.test.test_unix,twisted.internet.test.test_unix,twisted.internet.test.test_posixbase -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Various asynchronous TCP/IP classes.
-
-End users shouldn't use this module directly - use the reactor APIs instead.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-# System imports
-import os, sys, stat, socket, struct
-from errno import EINTR, EMSGSIZE, EAGAIN, EWOULDBLOCK, ECONNREFUSED, ENOBUFS
-
-from zope.interface import implements, implementsOnly, implementedBy
-
-if not hasattr(socket, 'AF_UNIX'):
- raise ImportError("UNIX sockets not supported on this platform")
-
-# Twisted imports
-from twisted.internet import main, base, tcp, udp, error, interfaces, protocol, address
-from twisted.internet.error import CannotListenError
-from twisted.python.util import untilConcludes
-from twisted.python import lockfile, log, reflect, failure
-
-try:
- from twisted.python import sendmsg
-except ImportError:
- sendmsg = None
-
-
-def _ancillaryDescriptor(fd):
- """
- Pack an integer into an ancillary data structure suitable for use with
- L{sendmsg.send1msg}.
- """
- packed = struct.pack("i", fd)
- return [(socket.SOL_SOCKET, sendmsg.SCM_RIGHTS, packed)]
-
-
-
-class _SendmsgMixin(object):
- """
- Mixin for stream-oriented UNIX transports which uses sendmsg and recvmsg to
- offer additional functionality, such as copying file descriptors into other
- processes.
-
- @ivar _writeSomeDataBase: The class which provides the basic implementation
- of C{writeSomeData}. Ultimately this should be a subclass of
- L{twisted.internet.abstract.FileDescriptor}. Subclasses which mix in
- L{_SendmsgMixin} must define this.
-
- @ivar _sendmsgQueue: A C{list} of C{int} holding file descriptors which are
- currently buffered before being sent.
-
- @ivar _fileDescriptorBufferSize: An C{int} giving the maximum number of file
- descriptors to accept and queue for sending before pausing the
- registered producer, if there is one.
- """
- implements(interfaces.IUNIXTransport)
-
- _writeSomeDataBase = None
- _fileDescriptorBufferSize = 64
-
- def __init__(self):
- self._sendmsgQueue = []
-
-
- def _isSendBufferFull(self):
- """
- Determine whether the user-space send buffer for this transport is full
- or not.
-
- This extends the base determination by adding consideration of how many
- file descriptors need to be sent using L{sendmsg.send1msg}. When there
- are more than C{self._fileDescriptorBufferSize}, the buffer is
- considered full.
-
- @return: C{True} if it is full, C{False} otherwise.
- """
- # There must be some bytes in the normal send buffer, checked by
- # _writeSomeDataBase._isSendBufferFull, in order to send file
- # descriptors from _sendmsgQueue. That means that the buffer will
- # eventually be considered full even without this additional logic.
- # However, since we send only one byte per file descriptor, having lots
- # of elements in _sendmsgQueue incurs more overhead and perhaps slows
- # things down. Anyway, try this for now, maybe rethink it later.
- return (
- len(self._sendmsgQueue) > self._fileDescriptorBufferSize
- or self._writeSomeDataBase._isSendBufferFull(self))
-
-
- def sendFileDescriptor(self, fileno):
- """
- Queue the given file descriptor to be sent and start trying to send it.
- """
- self._sendmsgQueue.append(fileno)
- self._maybePauseProducer()
- self.startWriting()
-
-
- def writeSomeData(self, data):
- """
- Send as much of C{data} as possible. Also send any pending file
- descriptors.
- """
- # Make it a programming error to send more file descriptors than you
- # send regular bytes. Otherwise, due to the limitation mentioned below,
- # we could end up with file descriptors left, but no bytes to send with
- # them, therefore no way to send those file descriptors.
- if len(self._sendmsgQueue) > len(data):
- return error.FileDescriptorOverrun()
-
- # If there are file descriptors to send, try sending them first, using a
- # little bit of data from the stream-oriented write buffer too. It is
- # not possible to send a file descriptor without sending some regular
- # data.
- index = 0
- try:
- while index < len(self._sendmsgQueue):
- fd = self._sendmsgQueue[index]
- try:
- untilConcludes(
- sendmsg.send1msg, self.socket.fileno(), data[index], 0,
- _ancillaryDescriptor(fd))
- except socket.error, se:
- if se.args[0] in (EWOULDBLOCK, ENOBUFS):
- return index
- else:
- return main.CONNECTION_LOST
- else:
- index += 1
- finally:
- del self._sendmsgQueue[:index]
-
- # Hand the remaining data to the base implementation. Avoid slicing in
- # favor of a buffer, in case that happens to be any faster.
- limitedData = buffer(data, index)
- result = self._writeSomeDataBase.writeSomeData(self, limitedData)
- try:
- return index + result
- except TypeError:
- return result
-
-
- def doRead(self):
- """
- Calls L{IFileDescriptorReceiver.fileDescriptorReceived} and
- L{IProtocol.dataReceived} with all available data.
-
- This reads up to C{self.bufferSize} bytes of data from its socket, then
- dispatches the data to protocol callbacks to be handled. If the
- connection is not lost through an error in the underlying recvmsg(),
- this function will return the result of the dataReceived call.
- """
- try:
- data, flags, ancillary = untilConcludes(
- sendmsg.recv1msg, self.socket.fileno(), 0, self.bufferSize)
- except socket.error, se:
- if se.args[0] == EWOULDBLOCK:
- return
- else:
- return main.CONNECTION_LOST
-
- if ancillary:
- fd = struct.unpack('i', ancillary[0][2])[0]
- if interfaces.IFileDescriptorReceiver.providedBy(self.protocol):
- self.protocol.fileDescriptorReceived(fd)
- else:
- log.msg(
- format=(
- "%(protocolName)s (on %(hostAddress)r) does not "
- "provide IFileDescriptorReceiver; closing file "
- "descriptor received (from %(peerAddress)r)."),
- hostAddress=self.getHost(), peerAddress=self.getPeer(),
- protocolName=self._getLogPrefix(self.protocol),
- )
- os.close(fd)
-
- return self._dataReceived(data)
-
-if sendmsg is None:
- class _SendmsgMixin(object):
- """
- Behaviorless placeholder used when L{twisted.python.sendmsg} is not
- available, preventing L{IUNIXTransport} from being supported.
- """
-
-
-
-class Server(_SendmsgMixin, tcp.Server):
-
- _writeSomeDataBase = tcp.Server
-
- def __init__(self, sock, protocol, client, server, sessionno, reactor):
- _SendmsgMixin.__init__(self)
- tcp.Server.__init__(self, sock, protocol, (client, None), server, sessionno, reactor)
-
-
- def getHost(self):
- return address.UNIXAddress(self.socket.getsockname())
-
- def getPeer(self):
- return address.UNIXAddress(self.hostname or None)
-
-
-
-def _inFilesystemNamespace(path):
- """
- Determine whether the given unix socket path is in a filesystem namespace.
-
- While most PF_UNIX sockets are entries in the filesystem, Linux 2.2 and
- above support PF_UNIX sockets in an "abstract namespace" that does not
- correspond to any path. This function returns C{True} if the given socket
- path is stored in the filesystem and C{False} if the path is in this
- abstract namespace.
- """
- return path[:1] != "\0"
-
-
-class _UNIXPort(object):
- def getHost(self):
- """Returns a UNIXAddress.
-
- This indicates the server's address.
- """
- if sys.version_info > (2, 5) or _inFilesystemNamespace(self.port):
- path = self.socket.getsockname()
- else:
- # Abstract namespace sockets aren't well supported on Python 2.4.
- # getsockname() always returns ''.
- path = self.port
- return address.UNIXAddress(path)
-
-
-
-class Port(_UNIXPort, tcp.Port):
- addressFamily = socket.AF_UNIX
- socketType = socket.SOCK_STREAM
-
- transport = Server
- lockFile = None
-
- def __init__(self, fileName, factory, backlog=50, mode=0666, reactor=None, wantPID = 0):
- tcp.Port.__init__(self, fileName, factory, backlog, reactor=reactor)
- self.mode = mode
- self.wantPID = wantPID
-
- def __repr__(self):
- factoryName = reflect.qual(self.factory.__class__)
- if hasattr(self, 'socket'):
- return '<%s on %r>' % (factoryName, self.port)
- else:
- return '<%s (not listening)>' % (factoryName,)
-
- def _buildAddr(self, name):
- return address.UNIXAddress(name)
-
- def startListening(self):
- """
- Create and bind my socket, and begin listening on it.
-
- This is called on unserialization, and must be called after creating a
- server to begin listening on the specified port.
- """
- log.msg("%s starting on %r" % (
- self._getLogPrefix(self.factory), self.port))
- if self.wantPID:
- self.lockFile = lockfile.FilesystemLock(self.port + ".lock")
- if not self.lockFile.lock():
- raise CannotListenError, (None, self.port, "Cannot acquire lock")
- else:
- if not self.lockFile.clean:
- try:
- # This is a best-attempt at cleaning up
- # left-over unix sockets on the filesystem.
- # If it fails, there's not much else we can
- # do. The bind() below will fail with an
- # exception that actually propagates.
- if stat.S_ISSOCK(os.stat(self.port).st_mode):
- os.remove(self.port)
- except:
- pass
-
- self.factory.doStart()
- try:
- skt = self.createInternetSocket()
- skt.bind(self.port)
- except socket.error, le:
- raise CannotListenError, (None, self.port, le)
- else:
- if _inFilesystemNamespace(self.port):
- # Make the socket readable and writable to the world.
- os.chmod(self.port, self.mode)
- skt.listen(self.backlog)
- self.connected = True
- self.socket = skt
- self.fileno = self.socket.fileno
- self.numberAccepts = 100
- self.startReading()
-
-
- def _logConnectionLostMsg(self):
- """
- Log message for closing socket
- """
- log.msg('(UNIX Port %s Closed)' % (repr(self.port),))
-
-
- def connectionLost(self, reason):
- if _inFilesystemNamespace(self.port):
- os.unlink(self.port)
- if self.lockFile is not None:
- self.lockFile.unlock()
- tcp.Port.connectionLost(self, reason)
-
-
-
-class Client(_SendmsgMixin, tcp.BaseClient):
- """A client for Unix sockets."""
- addressFamily = socket.AF_UNIX
- socketType = socket.SOCK_STREAM
-
- _writeSomeDataBase = tcp.BaseClient
-
- def __init__(self, filename, connector, reactor=None, checkPID = 0):
- _SendmsgMixin.__init__(self)
- self.connector = connector
- self.realAddress = self.addr = filename
- if checkPID and not lockfile.isLocked(filename + ".lock"):
- self._finishInit(None, None, error.BadFileError(filename), reactor)
- self._finishInit(self.doConnect, self.createInternetSocket(),
- None, reactor)
-
- def getPeer(self):
- return address.UNIXAddress(self.addr)
-
- def getHost(self):
- return address.UNIXAddress(None)
-
-
-class Connector(base.BaseConnector):
- def __init__(self, address, factory, timeout, reactor, checkPID):
- base.BaseConnector.__init__(self, factory, timeout, reactor)
- self.address = address
- self.checkPID = checkPID
-
- def _makeTransport(self):
- return Client(self.address, self, self.reactor, self.checkPID)
-
- def getDestination(self):
- return address.UNIXAddress(self.address)
-
-
-class DatagramPort(_UNIXPort, udp.Port):
- """Datagram UNIX port, listening for packets."""
-
- implements(interfaces.IUNIXDatagramTransport)
-
- addressFamily = socket.AF_UNIX
-
- def __init__(self, addr, proto, maxPacketSize=8192, mode=0666, reactor=None):
- """Initialize with address to listen on.
- """
- udp.Port.__init__(self, addr, proto, maxPacketSize=maxPacketSize, reactor=reactor)
- self.mode = mode
-
-
- def __repr__(self):
- protocolName = reflect.qual(self.protocol.__class__,)
- if hasattr(self, 'socket'):
- return '<%s on %r>' % (protocolName, self.port)
- else:
- return '<%s (not listening)>' % (protocolName,)
-
-
- def _bindSocket(self):
- log.msg("%s starting on %s"%(self.protocol.__class__, repr(self.port)))
- try:
- skt = self.createInternetSocket() # XXX: haha misnamed method
- if self.port:
- skt.bind(self.port)
- except socket.error, le:
- raise error.CannotListenError, (None, self.port, le)
- if self.port and _inFilesystemNamespace(self.port):
- # Make the socket readable and writable to the world.
- os.chmod(self.port, self.mode)
- self.connected = 1
- self.socket = skt
- self.fileno = self.socket.fileno
-
- def write(self, datagram, address):
- """Write a datagram."""
- try:
- return self.socket.sendto(datagram, address)
- except socket.error, se:
- no = se.args[0]
- if no == EINTR:
- return self.write(datagram, address)
- elif no == EMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif no == EAGAIN:
- # oh, well, drop the data. The only difference from UDP
- # is that UDP won't ever notice.
- # TODO: add TCP-like buffering
- pass
- else:
- raise
-
- def connectionLost(self, reason=None):
- """Cleans up my socket.
- """
- log.msg('(Port %s Closed)' % repr(self.port))
- base.BasePort.connectionLost(self, reason)
- if hasattr(self, "protocol"):
- # we won't have attribute in ConnectedPort, in cases
- # where there was an error in connection process
- self.protocol.doStop()
- self.connected = 0
- self.socket.close()
- del self.socket
- del self.fileno
- if hasattr(self, "d"):
- self.d.callback(None)
- del self.d
-
- def setLogStr(self):
- self.logstr = reflect.qual(self.protocol.__class__) + " (UDP)"
-
-
-
-class ConnectedDatagramPort(DatagramPort):
- """
- A connected datagram UNIX socket.
- """
-
- implementsOnly(interfaces.IUNIXDatagramConnectedTransport,
- *(implementedBy(base.BasePort)))
-
- def __init__(self, addr, proto, maxPacketSize=8192, mode=0666,
- bindAddress=None, reactor=None):
- assert isinstance(proto, protocol.ConnectedDatagramProtocol)
- DatagramPort.__init__(self, bindAddress, proto, maxPacketSize, mode,
- reactor)
- self.remoteaddr = addr
-
-
- def startListening(self):
- try:
- self._bindSocket()
- self.socket.connect(self.remoteaddr)
- self._connectToProtocol()
- except:
- self.connectionFailed(failure.Failure())
-
-
- def connectionFailed(self, reason):
- """
- Called when a connection fails. Stop listening on the socket.
-
- @type reason: L{Failure}
- @param reason: Why the connection failed.
- """
- self.stopListening()
- self.protocol.connectionFailed(reason)
- del self.protocol
-
-
- def doRead(self):
- """
- Called when my socket is ready for reading.
- """
- read = 0
- while read < self.maxThroughput:
- try:
- data, addr = self.socket.recvfrom(self.maxPacketSize)
- read += len(data)
- self.protocol.datagramReceived(data)
- except socket.error, se:
- no = se.args[0]
- if no in (EAGAIN, EINTR, EWOULDBLOCK):
- return
- if no == ECONNREFUSED:
- self.protocol.connectionRefused()
- else:
- raise
- except:
- log.deferr()
-
-
- def write(self, data):
- """
- Write a datagram.
- """
- try:
- return self.socket.send(data)
- except socket.error, se:
- no = se.args[0]
- if no == EINTR:
- return self.write(data)
- elif no == EMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif no == ECONNREFUSED:
- self.protocol.connectionRefused()
- elif no == EAGAIN:
- # oh, well, drop the data. The only difference from UDP
- # is that UDP won't ever notice.
- # TODO: add TCP-like buffering
- pass
- else:
- raise
-
-
- def getPeer(self):
- return address.UNIXAddress(self.remoteaddr)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/utils.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/utils.py
deleted file mode 100755
index 82508337..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/utils.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# -*- test-case-name: twisted.test.test_iutils -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Utility methods.
-"""
-
-import sys, warnings
-
-from twisted.internet import protocol, defer
-from twisted.python import failure, util as tputil
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-def _callProtocolWithDeferred(protocol, executable, args, env, path, reactor=None):
- if reactor is None:
- from twisted.internet import reactor
-
- d = defer.Deferred()
- p = protocol(d)
- reactor.spawnProcess(p, executable, (executable,)+tuple(args), env, path)
- return d
-
-
-
-class _UnexpectedErrorOutput(IOError):
- """
- Standard error data was received where it was not expected. This is a
- subclass of L{IOError} to preserve backward compatibility with the previous
- error behavior of L{getProcessOutput}.
-
- @ivar processEnded: A L{Deferred} which will fire when the process which
- produced the data on stderr has ended (exited and all file descriptors
- closed).
- """
- def __init__(self, text, processEnded):
- IOError.__init__(self, "got stderr: %r" % (text,))
- self.processEnded = processEnded
-
-
-
-class _BackRelay(protocol.ProcessProtocol):
- """
- Trivial protocol for communicating with a process and turning its output
- into the result of a L{Deferred}.
-
- @ivar deferred: A L{Deferred} which will be called back with all of stdout
- and, if C{errortoo} is true, all of stderr as well (mixed together in
- one string). If C{errortoo} is false and any bytes are received over
- stderr, this will fire with an L{_UnexpectedErrorOutput} instance and
- the attribute will be set to C{None}.
-
- @ivar onProcessEnded: If C{errortoo} is false and bytes are received over
- stderr, this attribute will refer to a L{Deferred} which will be called
- back when the process ends. This C{Deferred} is also associated with
- the L{_UnexpectedErrorOutput} which C{deferred} fires with earlier in
- this case so that users can determine when the process has actually
- ended, in addition to knowing when bytes have been received via stderr.
- """
-
- def __init__(self, deferred, errortoo=0):
- self.deferred = deferred
- self.s = StringIO.StringIO()
- if errortoo:
- self.errReceived = self.errReceivedIsGood
- else:
- self.errReceived = self.errReceivedIsBad
-
- def errReceivedIsBad(self, text):
- if self.deferred is not None:
- self.onProcessEnded = defer.Deferred()
- err = _UnexpectedErrorOutput(text, self.onProcessEnded)
- self.deferred.errback(failure.Failure(err))
- self.deferred = None
- self.transport.loseConnection()
-
- def errReceivedIsGood(self, text):
- self.s.write(text)
-
- def outReceived(self, text):
- self.s.write(text)
-
- def processEnded(self, reason):
- if self.deferred is not None:
- self.deferred.callback(self.s.getvalue())
- elif self.onProcessEnded is not None:
- self.onProcessEnded.errback(reason)
-
-
-
-def getProcessOutput(executable, args=(), env={}, path=None, reactor=None,
- errortoo=0):
- """
- Spawn a process and return its output as a deferred returning a string.
-
- @param executable: The file name to run and get the output of - the
- full path should be used.
-
- @param args: the command line arguments to pass to the process; a
- sequence of strings. The first string should *NOT* be the
- executable's name.
-
- @param env: the environment variables to pass to the processs; a
- dictionary of strings.
-
- @param path: the path to run the subprocess in - defaults to the
- current directory.
-
- @param reactor: the reactor to use - defaults to the default reactor
-
- @param errortoo: If true, include stderr in the result. If false, if
- stderr is received the returned L{Deferred} will errback with an
- L{IOError} instance with a C{processEnded} attribute. The
- C{processEnded} attribute refers to a L{Deferred} which fires when the
- executed process ends.
- """
- return _callProtocolWithDeferred(lambda d:
- _BackRelay(d, errortoo=errortoo),
- executable, args, env, path,
- reactor)
-
-
-class _ValueGetter(protocol.ProcessProtocol):
-
- def __init__(self, deferred):
- self.deferred = deferred
-
- def processEnded(self, reason):
- self.deferred.callback(reason.value.exitCode)
-
-
-def getProcessValue(executable, args=(), env={}, path=None, reactor=None):
- """Spawn a process and return its exit code as a Deferred."""
- return _callProtocolWithDeferred(_ValueGetter, executable, args, env, path,
- reactor)
-
-
-class _EverythingGetter(protocol.ProcessProtocol):
-
- def __init__(self, deferred):
- self.deferred = deferred
- self.outBuf = StringIO.StringIO()
- self.errBuf = StringIO.StringIO()
- self.outReceived = self.outBuf.write
- self.errReceived = self.errBuf.write
-
- def processEnded(self, reason):
- out = self.outBuf.getvalue()
- err = self.errBuf.getvalue()
- e = reason.value
- code = e.exitCode
- if e.signal:
- self.deferred.errback((out, err, e.signal))
- else:
- self.deferred.callback((out, err, code))
-
-def getProcessOutputAndValue(executable, args=(), env={}, path=None,
- reactor=None):
- """Spawn a process and returns a Deferred that will be called back with
- its output (from stdout and stderr) and it's exit code as (out, err, code)
- If a signal is raised, the Deferred will errback with the stdout and
- stderr up to that point, along with the signal, as (out, err, signalNum)
- """
- return _callProtocolWithDeferred(_EverythingGetter, executable, args, env, path,
- reactor)
-
-def _resetWarningFilters(passthrough, addedFilters):
- for f in addedFilters:
- try:
- warnings.filters.remove(f)
- except ValueError:
- pass
- return passthrough
-
-
-def runWithWarningsSuppressed(suppressedWarnings, f, *a, **kw):
- """Run the function C{f}, but with some warnings suppressed.
-
- @param suppressedWarnings: A list of arguments to pass to filterwarnings.
- Must be a sequence of 2-tuples (args, kwargs).
- @param f: A callable, followed by its arguments and keyword arguments
- """
- for args, kwargs in suppressedWarnings:
- warnings.filterwarnings(*args, **kwargs)
- addedFilters = warnings.filters[:len(suppressedWarnings)]
- try:
- result = f(*a, **kw)
- except:
- exc_info = sys.exc_info()
- _resetWarningFilters(None, addedFilters)
- raise exc_info[0], exc_info[1], exc_info[2]
- else:
- if isinstance(result, defer.Deferred):
- result.addBoth(_resetWarningFilters, addedFilters)
- else:
- _resetWarningFilters(None, addedFilters)
- return result
-
-
-def suppressWarnings(f, *suppressedWarnings):
- """
- Wrap C{f} in a callable which suppresses the indicated warnings before
- invoking C{f} and unsuppresses them afterwards. If f returns a Deferred,
- warnings will remain suppressed until the Deferred fires.
- """
- def warningSuppressingWrapper(*a, **kw):
- return runWithWarningsSuppressed(suppressedWarnings, f, *a, **kw)
- return tputil.mergeFunctionMetadata(f, warningSuppressingWrapper)
-
-
-__all__ = [
- "runWithWarningsSuppressed", "suppressWarnings",
-
- "getProcessOutput", "getProcessValue", "getProcessOutputAndValue",
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/win32eventreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/win32eventreactor.py
deleted file mode 100755
index 3c0e09c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/win32eventreactor.py
+++ /dev/null
@@ -1,430 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-A win32event based implementation of the Twisted main loop.
-
-This requires pywin32 (formerly win32all) or ActivePython to be installed.
-
-To install the event loop (and you should do this before any connections,
-listeners or connectors are added)::
-
- from twisted.internet import win32eventreactor
- win32eventreactor.install()
-
-LIMITATIONS:
- 1. WaitForMultipleObjects and thus the event loop can only handle 64 objects.
- 2. Process running has some problems (see L{Process} docstring).
-
-
-TODO:
- 1. Event loop handling of writes is *very* problematic (this is causing failed tests).
- Switch to doing it the correct way, whatever that means (see below).
- 2. Replace icky socket loopback waker with event based waker (use dummyEvent object)
- 3. Switch everyone to using Free Software so we don't have to deal with proprietary APIs.
-
-
-ALTERNATIVE SOLUTIONS:
- - IIRC, sockets can only be registered once. So we switch to a structure
- like the poll() reactor, thus allowing us to deal with write events in
- a decent fashion. This should allow us to pass tests, but we're still
- limited to 64 events.
-
-Or:
-
- - Instead of doing a reactor, we make this an addon to the select reactor.
- The WFMO event loop runs in a separate thread. This means no need to maintain
- separate code for networking, 64 event limit doesn't apply to sockets,
- we can run processes and other win32 stuff in default event loop. The
- only problem is that we're stuck with the icky socket based waker.
- Another benefit is that this could be extended to support >64 events
- in a simpler manner than the previous solution.
-
-The 2nd solution is probably what will get implemented.
-"""
-
-# System imports
-import time
-import sys
-from threading import Thread
-from weakref import WeakKeyDictionary
-
-from zope.interface import implements
-
-# Win32 imports
-from win32file import FD_READ, FD_CLOSE, FD_ACCEPT, FD_CONNECT, WSAEventSelect
-try:
- # WSAEnumNetworkEvents was added in pywin32 215
- from win32file import WSAEnumNetworkEvents
-except ImportError:
- import warnings
- warnings.warn(
- 'Reliable disconnection notification requires pywin32 215 or later',
- category=UserWarning)
- def WSAEnumNetworkEvents(fd, event):
- return set([FD_READ])
-
-from win32event import CreateEvent, MsgWaitForMultipleObjects
-from win32event import WAIT_OBJECT_0, WAIT_TIMEOUT, QS_ALLINPUT, QS_ALLEVENTS
-
-import win32gui
-
-# Twisted imports
-from twisted.internet import posixbase
-from twisted.python import log, threadable, failure
-from twisted.internet.interfaces import IReactorFDSet
-from twisted.internet.interfaces import IReactorWin32Events
-from twisted.internet.threads import blockingCallFromThread
-
-
-class Win32Reactor(posixbase.PosixReactorBase):
- """
- Reactor that uses Win32 event APIs.
-
- @ivar _reads: A dictionary mapping L{FileDescriptor} instances to a
- win32 event object used to check for read events for that descriptor.
-
- @ivar _writes: A dictionary mapping L{FileDescriptor} instances to a
- arbitrary value. Keys in this dictionary will be given a chance to
- write out their data.
-
- @ivar _events: A dictionary mapping win32 event object to tuples of
- L{FileDescriptor} instances and event masks.
-
- @ivar _closedAndReading: Along with C{_closedAndNotReading}, keeps track of
- descriptors which have had close notification delivered from the OS but
- which we have not finished reading data from. MsgWaitForMultipleObjects
- will only deliver close notification to us once, so we remember it in
- these two dictionaries until we're ready to act on it. The OS has
- delivered close notification for each descriptor in this dictionary, and
- the descriptors are marked as allowed to handle read events in the
- reactor, so they can be processed. When a descriptor is marked as not
- allowed to handle read events in the reactor (ie, it is passed to
- L{IReactorFDSet.removeReader}), it is moved out of this dictionary and
- into C{_closedAndNotReading}. The descriptors are keys in this
- dictionary. The values are arbitrary.
- @type _closedAndReading: C{dict}
-
- @ivar _closedAndNotReading: These descriptors have had close notification
- delivered from the OS, but are not marked as allowed to handle read
- events in the reactor. They are saved here to record their closed
- state, but not processed at all. When one of these descriptors is
- passed to L{IReactorFDSet.addReader}, it is moved out of this dictionary
- and into C{_closedAndReading}. The descriptors are keys in this
- dictionary. The values are arbitrary. This is a weak key dictionary so
- that if an application tells the reactor to stop reading from a
- descriptor and then forgets about that descriptor itself, the reactor
- will also forget about it.
- @type _closedAndNotReading: C{WeakKeyDictionary}
- """
- implements(IReactorFDSet, IReactorWin32Events)
-
- dummyEvent = CreateEvent(None, 0, 0, None)
-
- def __init__(self):
- self._reads = {}
- self._writes = {}
- self._events = {}
- self._closedAndReading = {}
- self._closedAndNotReading = WeakKeyDictionary()
- posixbase.PosixReactorBase.__init__(self)
-
-
- def _makeSocketEvent(self, fd, action, why):
- """
- Make a win32 event object for a socket.
- """
- event = CreateEvent(None, 0, 0, None)
- WSAEventSelect(fd, event, why)
- self._events[event] = (fd, action)
- return event
-
-
- def addEvent(self, event, fd, action):
- """
- Add a new win32 event to the event loop.
- """
- self._events[event] = (fd, action)
-
-
- def removeEvent(self, event):
- """
- Remove an event.
- """
- del self._events[event]
-
-
- def addReader(self, reader):
- """
- Add a socket FileDescriptor for notification of data available to read.
- """
- if reader not in self._reads:
- self._reads[reader] = self._makeSocketEvent(
- reader, 'doRead', FD_READ | FD_ACCEPT | FD_CONNECT | FD_CLOSE)
- # If the reader is closed, move it over to the dictionary of reading
- # descriptors.
- if reader in self._closedAndNotReading:
- self._closedAndReading[reader] = True
- del self._closedAndNotReading[reader]
-
-
- def addWriter(self, writer):
- """
- Add a socket FileDescriptor for notification of data available to write.
- """
- if writer not in self._writes:
- self._writes[writer] = 1
-
-
- def removeReader(self, reader):
- """Remove a Selectable for notification of data available to read.
- """
- if reader in self._reads:
- del self._events[self._reads[reader]]
- del self._reads[reader]
-
- # If the descriptor is closed, move it out of the dictionary of
- # reading descriptors into the dictionary of waiting descriptors.
- if reader in self._closedAndReading:
- self._closedAndNotReading[reader] = True
- del self._closedAndReading[reader]
-
-
- def removeWriter(self, writer):
- """Remove a Selectable for notification of data available to write.
- """
- if writer in self._writes:
- del self._writes[writer]
-
-
- def removeAll(self):
- """
- Remove all selectables, and return a list of them.
- """
- return self._removeAll(self._reads, self._writes)
-
-
- def getReaders(self):
- return self._reads.keys()
-
-
- def getWriters(self):
- return self._writes.keys()
-
-
- def doWaitForMultipleEvents(self, timeout):
- log.msg(channel='system', event='iteration', reactor=self)
- if timeout is None:
- timeout = 100
-
- # Keep track of whether we run any application code before we get to the
- # MsgWaitForMultipleObjects. If so, there's a chance it will schedule a
- # new timed call or stop the reactor or do something else that means we
- # shouldn't block in MsgWaitForMultipleObjects for the full timeout.
- ranUserCode = False
-
- # If any descriptors are trying to close, try to get them out of the way
- # first.
- for reader in self._closedAndReading.keys():
- ranUserCode = True
- self._runAction('doRead', reader)
-
- for fd in self._writes.keys():
- ranUserCode = True
- log.callWithLogger(fd, self._runWrite, fd)
-
- if ranUserCode:
- # If application code *might* have scheduled an event, assume it
- # did. If we're wrong, we'll get back here shortly anyway. If
- # we're right, we'll be sure to handle the event (including reactor
- # shutdown) in a timely manner.
- timeout = 0
-
- if not (self._events or self._writes):
- # sleep so we don't suck up CPU time
- time.sleep(timeout)
- return
-
- handles = self._events.keys() or [self.dummyEvent]
- timeout = int(timeout * 1000)
- val = MsgWaitForMultipleObjects(handles, 0, timeout, QS_ALLINPUT)
- if val == WAIT_TIMEOUT:
- return
- elif val == WAIT_OBJECT_0 + len(handles):
- exit = win32gui.PumpWaitingMessages()
- if exit:
- self.callLater(0, self.stop)
- return
- elif val >= WAIT_OBJECT_0 and val < WAIT_OBJECT_0 + len(handles):
- event = handles[val - WAIT_OBJECT_0]
- fd, action = self._events[event]
-
- if fd in self._reads:
- # Before anything, make sure it's still a valid file descriptor.
- fileno = fd.fileno()
- if fileno == -1:
- self._disconnectSelectable(fd, posixbase._NO_FILEDESC, False)
- return
-
- # Since it's a socket (not another arbitrary event added via
- # addEvent) and we asked for FD_READ | FD_CLOSE, check to see if
- # we actually got FD_CLOSE. This needs a special check because
- # it only gets delivered once. If we miss it, it's gone forever
- # and we'll never know that the connection is closed.
- events = WSAEnumNetworkEvents(fileno, event)
- if FD_CLOSE in events:
- self._closedAndReading[fd] = True
- log.callWithLogger(fd, self._runAction, action, fd)
-
-
- def _runWrite(self, fd):
- closed = 0
- try:
- closed = fd.doWrite()
- except:
- closed = sys.exc_info()[1]
- log.deferr()
-
- if closed:
- self.removeReader(fd)
- self.removeWriter(fd)
- try:
- fd.connectionLost(failure.Failure(closed))
- except:
- log.deferr()
- elif closed is None:
- return 1
-
- def _runAction(self, action, fd):
- try:
- closed = getattr(fd, action)()
- except:
- closed = sys.exc_info()[1]
- log.deferr()
- if closed:
- self._disconnectSelectable(fd, closed, action == 'doRead')
-
- doIteration = doWaitForMultipleEvents
-
-
-
-class _ThreadFDWrapper(object):
- """
- This wraps an event handler and translates notification in the helper
- L{Win32Reactor} thread into a notification in the primary reactor thread.
-
- @ivar _reactor: The primary reactor, the one to which event notification
- will be sent.
-
- @ivar _fd: The L{FileDescriptor} to which the event will be dispatched.
-
- @ivar _action: A C{str} giving the method of C{_fd} which handles the event.
-
- @ivar _logPrefix: The pre-fetched log prefix string for C{_fd}, so that
- C{_fd.logPrefix} does not need to be called in a non-main thread.
- """
- def __init__(self, reactor, fd, action, logPrefix):
- self._reactor = reactor
- self._fd = fd
- self._action = action
- self._logPrefix = logPrefix
-
-
- def logPrefix(self):
- """
- Return the original handler's log prefix, as it was given to
- C{__init__}.
- """
- return self._logPrefix
-
-
- def _execute(self):
- """
- Callback fired when the associated event is set. Run the C{action}
- callback on the wrapped descriptor in the main reactor thread and raise
- or return whatever it raises or returns to cause this event handler to
- be removed from C{self._reactor} if appropriate.
- """
- return blockingCallFromThread(
- self._reactor, lambda: getattr(self._fd, self._action)())
-
-
- def connectionLost(self, reason):
- """
- Pass through to the wrapped descriptor, but in the main reactor thread
- instead of the helper C{Win32Reactor} thread.
- """
- self._reactor.callFromThread(self._fd.connectionLost, reason)
-
-
-
-class _ThreadedWin32EventsMixin(object):
- """
- This mixin implements L{IReactorWin32Events} for another reactor by running
- a L{Win32Reactor} in a separate thread and dispatching work to it.
-
- @ivar _reactor: The L{Win32Reactor} running in the other thread. This is
- C{None} until it is actually needed.
-
- @ivar _reactorThread: The L{threading.Thread} which is running the
- L{Win32Reactor}. This is C{None} until it is actually needed.
- """
- implements(IReactorWin32Events)
-
- _reactor = None
- _reactorThread = None
-
-
- def _unmakeHelperReactor(self):
- """
- Stop and discard the reactor started by C{_makeHelperReactor}.
- """
- self._reactor.callFromThread(self._reactor.stop)
- self._reactor = None
-
-
- def _makeHelperReactor(self):
- """
- Create and (in a new thread) start a L{Win32Reactor} instance to use for
- the implementation of L{IReactorWin32Events}.
- """
- self._reactor = Win32Reactor()
- # This is a helper reactor, it is not the global reactor and its thread
- # is not "the" I/O thread. Prevent it from registering it as such.
- self._reactor._registerAsIOThread = False
- self._reactorThread = Thread(
- target=self._reactor.run, args=(False,))
- self.addSystemEventTrigger(
- 'after', 'shutdown', self._unmakeHelperReactor)
- self._reactorThread.start()
-
-
- def addEvent(self, event, fd, action):
- """
- @see: L{IReactorWin32Events}
- """
- if self._reactor is None:
- self._makeHelperReactor()
- self._reactor.callFromThread(
- self._reactor.addEvent,
- event, _ThreadFDWrapper(self, fd, action, fd.logPrefix()),
- "_execute")
-
-
- def removeEvent(self, event):
- """
- @see: L{IReactorWin32Events}
- """
- self._reactor.callFromThread(self._reactor.removeEvent, event)
-
-
-
-def install():
- threadable.init(1)
- r = Win32Reactor()
- import main
- main.installReactor(r)
-
-
-__all__ = ["Win32Reactor", "install"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxreactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxreactor.py
deleted file mode 100755
index 71e861ab..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxreactor.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module provides wxPython event loop support for Twisted.
-
-In order to use this support, simply do the following::
-
- | from twisted.internet import wxreactor
- | wxreactor.install()
-
-Then, when your root wxApp has been created::
-
- | from twisted.internet import reactor
- | reactor.registerWxApp(yourApp)
- | reactor.run()
-
-Then use twisted.internet APIs as usual. Stop the event loop using
-reactor.stop(), not yourApp.ExitMainLoop().
-
-IMPORTANT: tests will fail when run under this reactor. This is
-expected and probably does not reflect on the reactor's ability to run
-real applications.
-"""
-
-import Queue
-try:
- from wx import PySimpleApp as wxPySimpleApp, CallAfter as wxCallAfter, \
- Timer as wxTimer
-except ImportError:
- # older version of wxPython:
- from wxPython.wx import wxPySimpleApp, wxCallAfter, wxTimer
-
-from twisted.python import log, runtime
-from twisted.internet import _threadedselect
-
-
-class ProcessEventsTimer(wxTimer):
- """
- Timer that tells wx to process pending events.
-
- This is necessary on OS X, probably due to a bug in wx, if we want
- wxCallAfters to be handled when modal dialogs, menus, etc. are open.
- """
- def __init__(self, wxapp):
- wxTimer.__init__(self)
- self.wxapp = wxapp
-
-
- def Notify(self):
- """
- Called repeatedly by wx event loop.
- """
- self.wxapp.ProcessPendingEvents()
-
-
-
-class WxReactor(_threadedselect.ThreadedSelectReactor):
- """
- wxPython reactor.
-
- wxPython drives the event loop, select() runs in a thread.
- """
-
- _stopping = False
-
- def registerWxApp(self, wxapp):
- """
- Register wxApp instance with the reactor.
- """
- self.wxapp = wxapp
-
-
- def _installSignalHandlersAgain(self):
- """
- wx sometimes removes our own signal handlers, so re-add them.
- """
- try:
- # make _handleSignals happy:
- import signal
- signal.signal(signal.SIGINT, signal.default_int_handler)
- except ImportError:
- return
- self._handleSignals()
-
-
- def stop(self):
- """
- Stop the reactor.
- """
- if self._stopping:
- return
- self._stopping = True
- _threadedselect.ThreadedSelectReactor.stop(self)
-
-
- def _runInMainThread(self, f):
- """
- Schedule function to run in main wx/Twisted thread.
-
- Called by the select() thread.
- """
- if hasattr(self, "wxapp"):
- wxCallAfter(f)
- else:
- # wx shutdown but twisted hasn't
- self._postQueue.put(f)
-
-
- def _stopWx(self):
- """
- Stop the wx event loop if it hasn't already been stopped.
-
- Called during Twisted event loop shutdown.
- """
- if hasattr(self, "wxapp"):
- self.wxapp.ExitMainLoop()
-
-
- def run(self, installSignalHandlers=True):
- """
- Start the reactor.
- """
- self._postQueue = Queue.Queue()
- if not hasattr(self, "wxapp"):
- log.msg("registerWxApp() was not called on reactor, "
- "registering my own wxApp instance.")
- self.registerWxApp(wxPySimpleApp())
-
- # start select() thread:
- self.interleave(self._runInMainThread,
- installSignalHandlers=installSignalHandlers)
- if installSignalHandlers:
- self.callLater(0, self._installSignalHandlersAgain)
-
- # add cleanup events:
- self.addSystemEventTrigger("after", "shutdown", self._stopWx)
- self.addSystemEventTrigger("after", "shutdown",
- lambda: self._postQueue.put(None))
-
- # On Mac OS X, work around wx bug by starting timer to ensure
- # wxCallAfter calls are always processed. We don't wake up as
- # often as we could since that uses too much CPU.
- if runtime.platform.isMacOSX():
- t = ProcessEventsTimer(self.wxapp)
- t.Start(2) # wake up every 2ms
-
- self.wxapp.MainLoop()
- wxapp = self.wxapp
- del self.wxapp
-
- if not self._stopping:
- # wx event loop exited without reactor.stop() being
- # called. At this point events from select() thread will
- # be added to _postQueue, but some may still be waiting
- # unprocessed in wx, thus the ProcessPendingEvents()
- # below.
- self.stop()
- wxapp.ProcessPendingEvents() # deal with any queued wxCallAfters
- while 1:
- try:
- f = self._postQueue.get(timeout=0.01)
- except Queue.Empty:
- continue
- else:
- if f is None:
- break
- try:
- f()
- except:
- log.err()
-
-
-def install():
- """
- Configure the twisted mainloop to be run inside the wxPython mainloop.
- """
- reactor = WxReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
-
-
-__all__ = ['install']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxsupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxsupport.py
deleted file mode 100755
index d17c6663..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/internet/wxsupport.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""Old method of wxPython support for Twisted.
-
-twisted.internet.wxreactor is probably a better choice.
-
-To use::
-
- | # given a wxApp instance called myWxAppInstance:
- | from twisted.internet import wxsupport
- | wxsupport.install(myWxAppInstance)
-
-Use Twisted's APIs for running and stopping the event loop, don't use
-wxPython's methods.
-
-On Windows the Twisted event loop might block when dialogs are open
-or menus are selected.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-import warnings
-warnings.warn("wxsupport is not fully functional on Windows, wxreactor is better.")
-
-# wxPython imports
-from wxPython.wx import wxApp
-
-# twisted imports
-from twisted.internet import reactor
-from twisted.python.runtime import platformType
-
-
-class wxRunner:
- """Make sure GUI events are handled."""
-
- def __init__(self, app):
- self.app = app
-
- def run(self):
- """
- Execute pending WX events followed by WX idle events and
- reschedule.
- """
- # run wx events
- while self.app.Pending():
- self.app.Dispatch()
-
- # run wx idle events
- self.app.ProcessIdle()
- reactor.callLater(0.02, self.run)
-
-
-def install(app):
- """Install the wxPython support, given a wxApp instance"""
- runner = wxRunner(app)
- reactor.callLater(0.02, runner.run)
-
-
-__all__ = ["install"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/__init__.py
deleted file mode 100755
index 89ab2074..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-'''
-The Twisted Documentation Generation System
-
-Maintainer: Andrew Bennetts
-'''
-
-# TODO
-# Abstract
-# Bibliography
-# Index
-# Allow non-web image formats (EPS, specifically)
-# Allow pickle output and input to minimize parses
-# Numbered headers
-# Navigational aides
-
-from twisted.lore._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/_version.py
deleted file mode 100755
index 1413acc7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.lore', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/default.py
deleted file mode 100755
index 5b542ad2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/default.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Default processing factory plugin.
-"""
-
-from xml.dom import minidom as dom
-
-from twisted.lore import tree, latex, lint, process
-from twisted.web import sux
-
-htmlDefault = {'template': 'template.tpl', 'baseurl': '%s', 'ext': '.html'}
-
-class ProcessingFunctionFactory:
-
- def getDoFile(self):
- return tree.doFile
-
- def generate_html(self, options, filenameGenerator=tree.getOutputFileName):
- n = htmlDefault.copy()
- n.update(options)
- options = n
- try:
- fp = open(options['template'])
- templ = dom.parse(fp)
- except IOError, e:
- raise process.NoProcessorError(e.filename+": "+e.strerror)
- except sux.ParseError, e:
- raise process.NoProcessorError(str(e))
- df = lambda file, linkrel: self.getDoFile()(file, linkrel, options['ext'],
- options['baseurl'], templ, options, filenameGenerator)
- return df
-
- latexSpitters = {None: latex.LatexSpitter,
- 'section': latex.SectionLatexSpitter,
- 'chapter': latex.ChapterLatexSpitter,
- 'book': latex.BookLatexSpitter,
- }
-
- def generate_latex(self, options, filenameGenerator=None):
- spitter = self.latexSpitters[None]
- for (key, value) in self.latexSpitters.items():
- if key and options.get(key):
- spitter = value
- df = lambda file, linkrel: latex.convertFile(file, spitter)
- return df
-
- def getLintChecker(self):
- return lint.getDefaultChecker()
-
- def generate_lint(self, options, filenameGenerator=None):
- checker = self.getLintChecker()
- return lambda file, linkrel: lint.doFile(file, checker)
-
-factory = ProcessingFunctionFactory()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/docbook.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/docbook.py
deleted file mode 100755
index 62c8fc6c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/docbook.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-DocBook output support for Lore.
-"""
-
-import os, cgi
-from xml.dom import minidom as dom
-
-from twisted.lore import latex
-
-
-class DocbookSpitter(latex.BaseLatexSpitter):
-
- currentLevel = 1
-
- def writeNodeData(self, node):
- self.writer(node.data)
-
- def visitNode_body(self, node):
- self.visitNodeDefault(node)
- self.writer('</section>'*self.currentLevel)
-
- def visitNodeHeader(self, node):
- level = int(node.tagName[1])
- difference, self.currentLevel = level-self.currentLevel, level
- self.writer('<section>'*difference+'</section>'*-difference)
- if difference<=0:
- self.writer('</section>\n<section>')
- self.writer('<title>')
- self.visitNodeDefault(node)
-
- def visitNode_a_listing(self, node):
- fileName = os.path.join(self.currDir, node.getAttribute('href'))
- self.writer('<programlisting>\n')
- self.writer(cgi.escape(open(fileName).read()))
- self.writer('</programlisting>\n')
-
- def visitNode_a_href(self, node):
- self.visitNodeDefault(node)
-
- def visitNode_a_name(self, node):
- self.visitNodeDefault(node)
-
- def visitNode_li(self, node):
- for child in node.childNodes:
- if getattr(child, 'tagName', None) != 'p':
- new = dom.Element('p')
- new.childNodes = [child]
- node.replaceChild(new, child)
- self.visitNodeDefault(node)
-
- visitNode_h2 = visitNode_h3 = visitNode_h4 = visitNodeHeader
- end_h2 = end_h3 = end_h4 = '</title><para />'
- start_title, end_title = '<section><title>', '</title><para />'
- start_p, end_p = '<para>', '</para>'
- start_strong, end_strong = start_em, end_em = '<emphasis>', '</emphasis>'
- start_span_footnote, end_span_footnote = '<footnote><para>', '</para></footnote>'
- start_q = end_q = '"'
- start_pre, end_pre = '<programlisting>', '</programlisting>'
- start_div_note, end_div_note = '<note>', '</note>'
- start_li, end_li = '<listitem>', '</listitem>'
- start_ul, end_ul = '<itemizedlist>', '</itemizedlist>'
- start_ol, end_ol = '<orderedlist>', '</orderedlist>'
- start_dl, end_dl = '<variablelist>', '</variablelist>'
- start_dt, end_dt = '<varlistentry><term>', '</term>'
- start_dd, end_dd = '<listitem><para>', '</para></listitem></varlistentry>'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/htmlbook.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/htmlbook.py
deleted file mode 100755
index 3b227c06..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/htmlbook.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.python.compat import execfile
-
-
-def getNumber(filename):
- return None
-
-def getReference(filename):
- return None
-
-class Book:
-
- def __init__(self, filename):
- self.chapters = []
- self.indexFilename = None
-
- global Chapter
- Chapter = self.Chapter
- global getNumber
- getNumber = self.getNumber
- global getReference
- getReference = self.getNumber
- global Index
- Index = self.Index
-
- if filename:
- execfile(filename, globals())
-
- def getFiles(self):
- return [c[0] for c in self.chapters]
-
- def getNumber(self, filename):
- for c in self.chapters:
- if c[0] == filename:
- return c[1]
- return None
-
- def getIndexFilename(self):
- return self.indexFilename
-
- def Chapter(self, filename, number):
- self.chapters.append((filename, number))
-
- def Index(self, filename):
- self.indexFilename = filename
-
-#_book = Book(None)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/indexer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/indexer.py
deleted file mode 100755
index 528e7d63..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/indexer.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-def setIndexFilename(filename='index.xhtml'):
- global indexFilename
- indexFilename = filename
-
-def getIndexFilename():
- global indexFilename
- return indexFilename
-
-def addEntry(filename, anchor, text, reference):
- global entries
- if text not in entries:
- entries[text] = []
- entries[text].append((filename, anchor, reference))
-
-def clearEntries():
- global entries
- entries = {}
-
-def generateIndex():
- global entries
- global indexFilename
-
- if not indexFilename:
- return
-
- f = open(indexFilename, 'w')
- sortedEntries = [(e.lower(), e) for e in entries]
- sortedEntries.sort()
- sortedEntries = [e[1] for e in sortedEntries]
- for text in sortedEntries:
- refs = []
- f.write(text.replace('!', ', ') + ': ')
- for (file, anchor, reference) in entries[text]:
- refs.append('<a href="%s#%s">%s</a>' % (file, anchor, reference))
- if text == 'infinite recursion':
- refs.append('<em>See Also:</em> recursion, infinite\n')
- if text == 'recursion!infinite':
- refs.append('<em>See Also:</em> infinite recursion\n')
- f.write('%s<br />\n' % ", ".join(refs))
- f.close()
-
-def reset():
- clearEntries()
- setIndexFilename()
-
-reset()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/latex.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/latex.py
deleted file mode 100755
index ed843ed6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/latex.py
+++ /dev/null
@@ -1,463 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-LaTeX output support for Lore.
-"""
-
-from xml.dom import minidom as dom
-import os.path, re
-from cStringIO import StringIO
-import urlparse
-
-from twisted.web import domhelpers
-from twisted.python import text, procutils
-
-import tree
-
-escapingRE = re.compile(r'([\[\]#$%&_{}^~\\])')
-lowerUpperRE = re.compile(r'([a-z])([A-Z])')
-
-def _escapeMatch(match):
- c = match.group()
- if c == '\\':
- return '$\\backslash$'
- elif c == '~':
- return '\\~{}'
- elif c == '^':
- return '\\^{}'
- elif c in '[]':
- return '{'+c+'}'
- else:
- return '\\' + c
-
-def latexEscape(txt):
- txt = escapingRE.sub(_escapeMatch, txt)
- return txt.replace('\n', ' ')
-
-entities = {'amp': '\&', 'gt': '>', 'lt': '<', 'quot': '"',
- 'copy': '\\copyright', 'mdash': '---', 'rdquo': '``',
- 'ldquo': "''"}
-
-
-def realpath(path):
- # Normalise path
- cwd = os.getcwd()
- path = os.path.normpath(os.path.join(cwd, path))
- return path.replace('\\', '/') # windows slashes make LaTeX blow up
-
-
-def getLatexText(node, writer, filter=lambda x:x, entities=entities):
- if hasattr(node, 'eref'):
- return writer(entities.get(node.eref, ''))
- if hasattr(node, 'data'):
- if isinstance(node.data, unicode):
- data = node.data.encode('utf-8')
- else:
- data = node.data
- return writer(filter(data))
- for child in node.childNodes:
- getLatexText(child, writer, filter, entities)
-
-class BaseLatexSpitter:
-
- def __init__(self, writer, currDir='.', filename=''):
- self.writer = writer
- self.currDir = currDir
- self.filename = filename
-
- def visitNode(self, node):
- if isinstance(node, dom.Comment):
- return
- if not hasattr(node, 'tagName'):
- self.writeNodeData(node)
- return
- getattr(self, 'visitNode_'+node.tagName, self.visitNodeDefault)(node)
-
- def visitNodeDefault(self, node):
- self.writer(getattr(self, 'start_'+node.tagName, ''))
- for child in node.childNodes:
- self.visitNode(child)
- self.writer(getattr(self, 'end_'+node.tagName, ''))
-
- def visitNode_a(self, node):
- if node.hasAttribute('class'):
- if node.getAttribute('class').endswith('listing'):
- return self.visitNode_a_listing(node)
- if node.hasAttribute('href'):
- return self.visitNode_a_href(node)
- if node.hasAttribute('name'):
- return self.visitNode_a_name(node)
- self.visitNodeDefault(node)
-
- def visitNode_span(self, node):
- if not node.hasAttribute('class'):
- return self.visitNodeDefault(node)
- node.tagName += '_'+node.getAttribute('class')
- self.visitNode(node)
-
- visitNode_div = visitNode_span
-
- def visitNode_h1(self, node):
- pass
-
- def visitNode_style(self, node):
- pass
-
-
-class LatexSpitter(BaseLatexSpitter):
-
- baseLevel = 0
- diaHack = bool(procutils.which("dia"))
-
- def writeNodeData(self, node):
- buf = StringIO()
- getLatexText(node, buf.write, latexEscape)
- self.writer(buf.getvalue().replace('<', '$<$').replace('>', '$>$'))
-
- def visitNode_head(self, node):
- authorNodes = domhelpers.findElementsWithAttribute(node, 'rel', 'author')
- authorNodes = [n for n in authorNodes if n.tagName == 'link']
-
- if authorNodes:
- self.writer('\\author{')
- authors = []
- for aNode in authorNodes:
- name = aNode.getAttribute('title')
- href = aNode.getAttribute('href')
- if href.startswith('mailto:'):
- href = href[7:]
- if href:
- if name:
- name += ' '
- name += '$<$' + href + '$>$'
- if name:
- authors.append(name)
-
- self.writer(' \\and '.join(authors))
- self.writer('}')
-
- self.visitNodeDefault(node)
-
- def visitNode_pre(self, node):
- self.writer('\\begin{verbatim}\n')
- buf = StringIO()
- getLatexText(node, buf.write)
- self.writer(text.removeLeadingTrailingBlanks(buf.getvalue()))
- self.writer('\\end{verbatim}\n')
-
- def visitNode_code(self, node):
- fout = StringIO()
- getLatexText(node, fout.write, latexEscape)
- data = lowerUpperRE.sub(r'\1\\linebreak[1]\2', fout.getvalue())
- data = data[:1] + data[1:].replace('.', '.\\linebreak[1]')
- self.writer('\\texttt{'+data+'}')
-
- def visitNode_img(self, node):
- fileName = os.path.join(self.currDir, node.getAttribute('src'))
- target, ext = os.path.splitext(fileName)
- if self.diaHack and os.access(target + '.dia', os.R_OK):
- ext = '.dia'
- fileName = target + ext
- f = getattr(self, 'convert_'+ext[1:], None)
- if not f:
- return
- target = os.path.join(self.currDir, os.path.basename(target)+'.eps')
- f(fileName, target)
- target = os.path.basename(target)
- self._write_img(target)
-
- def _write_img(self, target):
- """Write LaTeX for image."""
- self.writer('\\begin{center}\\includegraphics[%%\n'
- 'width=1.0\n'
- '\\textwidth,height=1.0\\textheight,\nkeepaspectratio]'
- '{%s}\\end{center}\n' % target)
-
- def convert_png(self, src, target):
- # XXX there's a *reason* Python comes with the pipes module -
- # someone fix this to use it.
- r = os.system('pngtopnm "%s" | pnmtops -noturn > "%s"' % (src, target))
- if r != 0:
- raise OSError(r)
-
- def convert_dia(self, src, target):
- # EVIL DISGUSTING HACK
- data = os.popen("gunzip -dc %s" % (src)).read()
- pre = '<dia:attribute name="scaling">\n <dia:real val="1"/>'
- post = '<dia:attribute name="scaling">\n <dia:real val="0.5"/>'
- f = open('%s_hacked.dia' % (src), 'wb')
- f.write(data.replace(pre, post))
- f.close()
- os.system('gzip %s_hacked.dia' % (src,))
- os.system('mv %s_hacked.dia.gz %s_hacked.dia' % (src,src))
- # Let's pretend we never saw that.
-
- # Silly dia needs an X server, even though it doesn't display anything.
- # If this is a problem for you, try using Xvfb.
- os.system("dia %s_hacked.dia -n -e %s" % (src, target))
-
- def visitNodeHeader(self, node):
- level = (int(node.tagName[1])-2)+self.baseLevel
- self.writer('\n\n\\'+level*'sub'+'section{')
- spitter = HeadingLatexSpitter(self.writer, self.currDir, self.filename)
- spitter.visitNodeDefault(node)
- self.writer('}\n')
-
- def visitNode_a_listing(self, node):
- fileName = os.path.join(self.currDir, node.getAttribute('href'))
- self.writer('\\begin{verbatim}\n')
- lines = map(str.rstrip, open(fileName).readlines())
- skipLines = int(node.getAttribute('skipLines') or 0)
- lines = lines[skipLines:]
- self.writer(text.removeLeadingTrailingBlanks('\n'.join(lines)))
- self.writer('\\end{verbatim}')
-
- # Write a caption for this source listing
- fileName = os.path.basename(fileName)
- caption = domhelpers.getNodeText(node)
- if caption == fileName:
- caption = 'Source listing'
- self.writer('\parbox[b]{\linewidth}{\\begin{center}%s --- '
- '\\begin{em}%s\\end{em}\\end{center}}'
- % (latexEscape(caption), latexEscape(fileName)))
-
- def visitNode_a_href(self, node):
- supported_schemes=['http', 'https', 'ftp', 'mailto']
- href = node.getAttribute('href')
- if urlparse.urlparse(href)[0] in supported_schemes:
- text = domhelpers.getNodeText(node)
- self.visitNodeDefault(node)
- if text != href:
- self.writer('\\footnote{%s}' % latexEscape(href))
- else:
- path, fragid = (href.split('#', 1) + [None])[:2]
- if path == '':
- path = self.filename
- else:
- path = os.path.join(os.path.dirname(self.filename), path)
- #if path == '':
- #path = os.path.basename(self.filename)
- #else:
- # # Hack for linking to man pages from howtos, i.e.
- # # ../doc/foo-man.html -> foo-man.html
- # path = os.path.basename(path)
-
- path = realpath(path)
-
- if fragid:
- ref = path + 'HASH' + fragid
- else:
- ref = path
- self.writer('\\textit{')
- self.visitNodeDefault(node)
- self.writer('}')
- self.writer('\\loreref{%s}' % ref)
-
- def visitNode_a_name(self, node):
- self.writer('\\label{%sHASH%s}' % (
- realpath(self.filename), node.getAttribute('name')))
- self.visitNodeDefault(node)
-
- def visitNode_table(self, node):
- rows = [[col for col in row.childNodes
- if getattr(col, 'tagName', None) in ('th', 'td')]
- for row in node.childNodes if getattr(row, 'tagName', None)=='tr']
- numCols = 1+max([len(row) for row in rows])
- self.writer('\\begin{table}[ht]\\begin{center}')
- self.writer('\\begin{tabular}{@{}'+'l'*numCols+'@{}}')
- for row in rows:
- th = 0
- for col in row:
- self.visitNode(col)
- self.writer('&')
- if col.tagName == 'th':
- th = 1
- self.writer('\\\\\n') #\\ ends lines
- if th:
- self.writer('\\hline\n')
- self.writer('\\end{tabular}\n')
- if node.hasAttribute('title'):
- self.writer('\\caption{%s}'
- % latexEscape(node.getAttribute('title')))
- self.writer('\\end{center}\\end{table}\n')
-
- def visitNode_span_footnote(self, node):
- self.writer('\\footnote{')
- spitter = FootnoteLatexSpitter(self.writer, self.currDir, self.filename)
- spitter.visitNodeDefault(node)
- self.writer('}')
-
- def visitNode_span_index(self, node):
- self.writer('\\index{%s}\n' % node.getAttribute('value'))
- self.visitNodeDefault(node)
-
- visitNode_h2 = visitNode_h3 = visitNode_h4 = visitNodeHeader
-
- start_title = '\\title{'
- end_title = '}\n'
-
- start_sub = '$_{'
- end_sub = '}$'
-
- start_sup = '$^{'
- end_sup = '}$'
-
- start_html = '''\\documentclass{article}
- \\newcommand{\\loreref}[1]{%
- \\ifthenelse{\\value{page}=\\pageref{#1}}%
- { (this page)}%
- { (page \\pageref{#1})}%
- }'''
-
- start_body = '\\begin{document}\n\\maketitle\n'
- end_body = '\\end{document}'
-
- start_dl = '\\begin{description}\n'
- end_dl = '\\end{description}\n'
- start_ul = '\\begin{itemize}\n'
- end_ul = '\\end{itemize}\n'
-
- start_ol = '\\begin{enumerate}\n'
- end_ol = '\\end{enumerate}\n'
-
- start_li = '\\item '
- end_li = '\n'
-
- start_dt = '\\item['
- end_dt = ']'
- end_dd = '\n'
-
- start_p = '\n\n'
-
- start_strong = start_em = '\\begin{em}'
- end_strong = end_em = '\\end{em}'
-
- start_q = "``"
- end_q = "''"
-
- start_div_note = '\\begin{quotation}\\textbf{Note:}'
- end_div_note = '\\end{quotation}'
-
- start_th = '\\textbf{'
- end_th = '}'
-
-
-class SectionLatexSpitter(LatexSpitter):
-
- baseLevel = 1
-
- start_title = '\\section{'
-
- def visitNode_title(self, node):
- self.visitNodeDefault(node)
- #self.writer('\\label{%s}}\n' % os.path.basename(self.filename))
- self.writer('\\label{%s}}\n' % realpath(self.filename))
-
- end_title = end_body = start_body = start_html = ''
-
-
-class ChapterLatexSpitter(SectionLatexSpitter):
- baseLevel = 0
- start_title = '\\chapter{'
-
-
-class HeadingLatexSpitter(BaseLatexSpitter):
- start_q = "``"
- end_q = "''"
-
- writeNodeData = LatexSpitter.writeNodeData.im_func
-
-
-class FootnoteLatexSpitter(LatexSpitter):
- """For multi-paragraph footnotes, this avoids having an empty leading
- paragraph."""
-
- start_p = ''
-
- def visitNode_span_footnote(self, node):
- self.visitNodeDefault(node)
-
- def visitNode_p(self, node):
- self.visitNodeDefault(node)
- self.start_p = LatexSpitter.start_p
-
-class BookLatexSpitter(LatexSpitter):
- def visitNode_body(self, node):
- tocs=domhelpers.locateNodes([node], 'class', 'toc')
- domhelpers.clearNode(node)
- if len(tocs):
- toc=tocs[0]
- node.appendChild(toc)
- self.visitNodeDefault(node)
-
- def visitNode_link(self, node):
- if not node.hasAttribute('rel'):
- return self.visitNodeDefault(node)
- node.tagName += '_'+node.getAttribute('rel')
- self.visitNode(node)
-
- def visitNode_link_author(self, node):
- self.writer('\\author{%s}\n' % node.getAttribute('text'))
-
- def visitNode_link_stylesheet(self, node):
- if node.hasAttribute('type') and node.hasAttribute('href'):
- if node.getAttribute('type')=='application/x-latex':
- packagename=node.getAttribute('href')
- packagebase,ext=os.path.splitext(packagename)
- self.writer('\\usepackage{%s}\n' % packagebase)
-
- start_html = r'''\documentclass[oneside]{book}
-\usepackage{graphicx}
-\usepackage{times,mathptmx}
-'''
-
- start_body = r'''\begin{document}
-\maketitle
-\tableofcontents
-'''
-
- start_li=''
- end_li=''
- start_ul=''
- end_ul=''
-
-
- def visitNode_a(self, node):
- if node.hasAttribute('class'):
- a_class=node.getAttribute('class')
- if a_class.endswith('listing'):
- return self.visitNode_a_listing(node)
- else:
- return getattr(self, 'visitNode_a_%s' % a_class)(node)
- if node.hasAttribute('href'):
- return self.visitNode_a_href(node)
- if node.hasAttribute('name'):
- return self.visitNode_a_name(node)
- self.visitNodeDefault(node)
-
- def visitNode_a_chapter(self, node):
- self.writer('\\chapter{')
- self.visitNodeDefault(node)
- self.writer('}\n')
-
- def visitNode_a_sect(self, node):
- base,ext=os.path.splitext(node.getAttribute('href'))
- self.writer('\\input{%s}\n' % base)
-
-
-
-def processFile(spitter, fin):
- # XXX Use Inversion Of Control Pattern to orthogonalize the parsing API
- # from the Visitor Pattern application. (EnterPrise)
- dom = tree.parseFileAndReport(fin.name, lambda x: fin).documentElement
- spitter.visitNode(dom)
-
-
-def convertFile(filename, spitterClass):
- fout = open(os.path.splitext(filename)[0]+".tex", 'w')
- spitter = spitterClass(fout.write, os.path.dirname(filename), filename)
- fin = open(filename)
- processFile(spitter, fin)
- fin.close()
- fout.close()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lint.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lint.py
deleted file mode 100755
index d58d9ad3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lint.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Checker for common errors in Lore documents.
-"""
-
-from xml.dom import minidom as dom
-import parser, urlparse, os.path
-
-from twisted.lore import tree, process
-from twisted.web import domhelpers
-from twisted.python import reflect
-
-
-# parser.suite in Python 2.3 raises SyntaxError, <2.3 raises parser.ParserError
-parserErrors = (SyntaxError, parser.ParserError)
-
-class TagChecker:
-
- def check(self, dom, filename):
- self.hadErrors = 0
- for method in reflect.prefixedMethods(self, 'check_'):
- method(dom, filename)
- if self.hadErrors:
- raise process.ProcessingFailure("invalid format")
-
- def _reportError(self, filename, element, error):
- hlint = element.hasAttribute('hlint') and element.getAttribute('hlint')
- if hlint != 'off':
- self.hadErrors = 1
- pos = getattr(element, '_markpos', None) or (0, 0)
- print "%s:%s:%s: %s" % ((filename,)+pos+(error,))
-
-
-class DefaultTagChecker(TagChecker):
-
- def __init__(self, allowedTags, allowedClasses):
- self.allowedTags = allowedTags
- self.allowedClasses = allowedClasses
-
- def check_disallowedElements(self, dom, filename):
- def m(node, self=self):
- return not self.allowedTags(node.tagName)
- for element in domhelpers.findElements(dom, m):
- self._reportError(filename, element,
- 'unrecommended tag %s' % element.tagName)
-
- def check_disallowedClasses(self, dom, filename):
- def matcher(element, self=self):
- if not element.hasAttribute('class'):
- return 0
- checker = self.allowedClasses.get(element.tagName, lambda x:0)
- return not checker(element.getAttribute('class'))
- for element in domhelpers.findElements(dom, matcher):
- self._reportError(filename, element,
- 'unknown class %s' %element.getAttribute('class'))
-
- def check_quote(self, doc, filename):
- def matcher(node):
- return ('"' in getattr(node, 'data', '') and
- not isinstance(node, dom.Comment) and
- not [1 for n in domhelpers.getParents(node)[1:-1]
- if n.tagName in ('pre', 'code')])
- for node in domhelpers.findNodes(doc, matcher):
- self._reportError(filename, node.parentNode, 'contains quote')
-
- def check_styleattr(self, dom, filename):
- for node in domhelpers.findElementsWithAttribute(dom, 'style'):
- self._reportError(filename, node, 'explicit style')
-
- def check_align(self, dom, filename):
- for node in domhelpers.findElementsWithAttribute(dom, 'align'):
- self._reportError(filename, node, 'explicit alignment')
-
- def check_style(self, dom, filename):
- for node in domhelpers.findNodesNamed(dom, 'style'):
- if domhelpers.getNodeText(node) != '':
- self._reportError(filename, node, 'hand hacked style')
-
- def check_title(self, dom, filename):
- doc = dom.documentElement
- title = domhelpers.findNodesNamed(dom, 'title')
- if len(title)!=1:
- return self._reportError(filename, doc, 'not exactly one title')
- h1 = domhelpers.findNodesNamed(dom, 'h1')
- if len(h1)!=1:
- return self._reportError(filename, doc, 'not exactly one h1')
- if domhelpers.getNodeText(h1[0]) != domhelpers.getNodeText(title[0]):
- self._reportError(filename, h1[0], 'title and h1 text differ')
-
- def check_80_columns(self, dom, filename):
- for node in domhelpers.findNodesNamed(dom, 'pre'):
- # the ps/pdf output is in a font that cuts off at 80 characters,
- # so this is enforced to make sure the interesting parts (which
- # are likely to be on the right-hand edge) stay on the printed
- # page.
- for line in domhelpers.gatherTextNodes(node, 1).split('\n'):
- if len(line.rstrip()) > 80:
- self._reportError(filename, node,
- 'text wider than 80 columns in pre')
- for node in domhelpers.findNodesNamed(dom, 'a'):
- if node.getAttribute('class').endswith('listing'):
- try:
- fn = os.path.dirname(filename)
- fn = os.path.join(fn, node.getAttribute('href'))
- lines = open(fn,'r').readlines()
- except:
- self._reportError(filename, node,
- 'bad listing href: %r' %
- node.getAttribute('href'))
- continue
-
- for line in lines:
- if len(line.rstrip()) > 80:
- self._reportError(filename, node,
- 'listing wider than 80 columns')
-
- def check_pre_py_listing(self, dom, filename):
- for node in domhelpers.findNodesNamed(dom, 'pre'):
- if node.getAttribute('class') == 'python':
- try:
- text = domhelpers.getNodeText(node)
- # Fix < and >
- text = text.replace('&gt;', '>').replace('&lt;', '<')
- # Strip blank lines
- lines = filter(None,[l.rstrip() for l in text.split('\n')])
- # Strip leading space
- while not [1 for line in lines if line[:1] not in ('',' ')]:
- lines = [line[1:] for line in lines]
- text = '\n'.join(lines) + '\n'
- try:
- parser.suite(text)
- except parserErrors, e:
- # Pretend the "..." idiom is syntactically valid
- text = text.replace("...","'...'")
- parser.suite(text)
- except parserErrors, e:
- self._reportError(filename, node,
- 'invalid python code:' + str(e))
-
- def check_anchor_in_heading(self, dom, filename):
- headingNames = ['h%d' % n for n in range(1,7)]
- for hname in headingNames:
- for node in domhelpers.findNodesNamed(dom, hname):
- if domhelpers.findNodesNamed(node, 'a'):
- self._reportError(filename, node, 'anchor in heading')
-
- def check_texturl_matches_href(self, dom, filename):
- for node in domhelpers.findNodesNamed(dom, 'a'):
- if not node.hasAttribute('href'):
- continue
- text = domhelpers.getNodeText(node)
- proto = urlparse.urlparse(text)[0]
- if proto and ' ' not in text:
- if text != node.getAttribute('href'):
- self._reportError(filename, node,
- 'link text does not match href')
-
- def check_lists(self, dom, filename):
- for node in (domhelpers.findNodesNamed(dom, 'ul')+
- domhelpers.findNodesNamed(dom, 'ol')):
- if not node.childNodes:
- self._reportError(filename, node, 'empty list')
- for child in node.childNodes:
- if child.nodeName != 'li':
- self._reportError(filename, node,
- 'only list items allowed in lists')
-
-
-def list2dict(l):
- d = {}
- for el in l:
- d[el] = None
- return d
-
-classes = list2dict(['shell', 'API', 'python', 'py-prototype', 'py-filename',
- 'py-src-string', 'py-signature', 'py-src-parameter',
- 'py-src-identifier', 'py-src-keyword'])
-
-tags = list2dict(["html", "title", "head", "body", "h1", "h2", "h3", "ol", "ul",
- "dl", "li", "dt", "dd", "p", "code", "img", "blockquote", "a",
- "cite", "div", "span", "strong", "em", "pre", "q", "table",
- "tr", "td", "th", "style", "sub", "sup", "link"])
-
-span = list2dict(['footnote', 'manhole-output', 'index'])
-
-div = list2dict(['note', 'boxed', 'doit'])
-
-a = list2dict(['listing', 'py-listing', 'html-listing', 'absolute'])
-
-pre = list2dict(['python', 'shell', 'python-interpreter', 'elisp'])
-
-allowed = {'code': classes.has_key, 'span': span.has_key, 'div': div.has_key,
- 'a': a.has_key, 'pre': pre.has_key, 'ul': lambda x: x=='toc',
- 'ol': lambda x: x=='toc', 'li': lambda x: x=='ignoretoc'}
-
-def getDefaultChecker():
- return DefaultTagChecker(tags.__contains__, allowed)
-
-def doFile(file, checker):
- doc = tree.parseFileAndReport(file)
- if doc:
- checker.check(doc, file)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lmath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lmath.py
deleted file mode 100755
index fbd7e20f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/lmath.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-LaTeX-defined image support for Lore documents.
-"""
-
-import os, tempfile
-from xml.dom import minidom as dom
-
-from twisted.web import domhelpers
-import latex, tree, lint, default
-
-
-class MathLatexSpitter(latex.LatexSpitter):
-
- start_html = '\\documentclass{amsart}\n'
-
- def visitNode_div_latexmacros(self, node):
- self.writer(domhelpers.getNodeText(node))
-
- def visitNode_span_latexformula(self, node):
- self.writer('\[')
- self.writer(domhelpers.getNodeText(node))
- self.writer('\]')
-
-def formulaeToImages(document, dir, _system=os.system):
- # gather all macros
- macros = ''
- for node in domhelpers.findElementsWithAttribute(document, 'class',
- 'latexmacros'):
- macros += domhelpers.getNodeText(node)
- node.parentNode.removeChild(node)
- i = 0
- for node in domhelpers.findElementsWithAttribute(document, 'class',
- 'latexformula'):
- latexText='''\\documentclass[12pt]{amsart}%s
- \\begin{document}\[%s\]
- \\end{document}''' % (macros, domhelpers.getNodeText(node))
- # This file really should be cleaned up by this function, or placed
- # somewhere such that the calling code can find it and clean it up.
- file = tempfile.mktemp()
- f = open(file+'.tex', 'w')
- f.write(latexText)
- f.close()
- _system('latex %s.tex' % file)
- _system('dvips %s.dvi -o %s.ps' % (os.path.basename(file), file))
- baseimgname = 'latexformula%d.png' % i
- imgname = os.path.join(dir, baseimgname)
- i += 1
- _system('pstoimg -type png -crop a -trans -interlace -out '
- '%s %s.ps' % (imgname, file))
- newNode = dom.parseString(
- '<span><br /><img src="%s" /><br /></span>' % (
- baseimgname,)).documentElement
- node.parentNode.replaceChild(newNode, node)
-
-
-def doFile(fn, docsdir, ext, url, templ, linkrel='', d=None):
- d = d or {}
- doc = tree.parseFileAndReport(fn)
- formulaeToImages(doc, os.path.dirname(fn))
- cn = templ.cloneNode(1)
- tree.munge(doc, cn, linkrel, docsdir, fn, ext, url, d)
- cn.writexml(open(os.path.splitext(fn)[0]+ext, 'wb'))
-
-
-class ProcessingFunctionFactory(default.ProcessingFunctionFactory):
-
- latexSpitters = {None: MathLatexSpitter}
-
- def getDoFile(self):
- return doFile
-
- def getLintChecker(self):
- checker = lint.getDefaultChecker()
- checker.allowedClasses = checker.allowedClasses.copy()
- oldDiv = checker.allowedClasses['div']
- oldSpan = checker.allowedClasses['span']
- checker.allowedClasses['div'] = lambda x:oldDiv(x) or x=='latexmacros'
- checker.allowedClasses['span'] = (lambda x:oldSpan(x) or
- x=='latexformula')
- return checker
-
-factory = ProcessingFunctionFactory()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/man2lore.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/man2lore.py
deleted file mode 100755
index fbcba1c8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/man2lore.py
+++ /dev/null
@@ -1,295 +0,0 @@
-# -*- test-case-name: twisted.lore.test.test_man2lore -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-man2lore: Converts man page source (i.e. groff) into lore-compatible html.
-
-This is nasty and hackish (and doesn't support lots of real groff), but is good
-enough for converting fairly simple man pages.
-"""
-
-import re, os
-
-quoteRE = re.compile('"(.*?)"')
-
-
-
-def escape(text):
- text = text.replace('<', '&lt;').replace('>', '&gt;')
- text = quoteRE.sub('<q>\\1</q>', text)
- return text
-
-
-
-def stripQuotes(s):
- if s[0] == s[-1] == '"':
- s = s[1:-1]
- return s
-
-
-
-class ManConverter(object):
- """
- Convert a man page to the Lore format.
-
- @ivar tp: State variable for handling text inside a C{TP} token. It can
- take values from 0 to 3:
- - 0: when outside of a C{TP} token.
- - 1: once a C{TP} token has been encountered. If the previous value
- was 0, a definition list is started. Then, at the first line of
- text, a definition term is started.
- - 2: when the first line after the C{TP} token has been handled.
- The definition term is closed, and a definition is started with
- the next line of text.
- - 3: when the first line as definition data has been handled.
- @type tp: C{int}
- """
- state = 'regular'
- name = None
- tp = 0
- dl = 0
- para = 0
-
- def convert(self, inf, outf):
- self.write = outf.write
- longline = ''
- for line in inf.readlines():
- if line.rstrip() and line.rstrip()[-1] == '\\':
- longline += line.rstrip()[:-1] + ' '
- continue
- if longline:
- line = longline + line
- longline = ''
- self.lineReceived(line)
- self.closeTags()
- self.write('</body>\n</html>\n')
- outf.flush()
-
-
- def lineReceived(self, line):
- if line[0] == '.':
- f = getattr(self, 'macro_' + line[1:3].rstrip().upper(), None)
- if f:
- f(line[3:].strip())
- else:
- self.text(line)
-
-
- def continueReceived(self, cont):
- if not cont:
- return
- if cont[0].isupper():
- f = getattr(self, 'macro_' + cont[:2].rstrip().upper(), None)
- if f:
- f(cont[2:].strip())
- else:
- self.text(cont)
-
-
- def closeTags(self):
- if self.state != 'regular':
- self.write('</%s>' % self.state)
- if self.tp == 3:
- self.write('</dd>\n\n')
- self.tp = 0
- if self.dl:
- self.write('</dl>\n\n')
- self.dl = 0
- if self.para:
- self.write('</p>\n\n')
- self.para = 0
-
-
- def paraCheck(self):
- if not self.tp and not self.para:
- self.write('<p>')
- self.para = 1
-
-
- def macro_TH(self, line):
- self.write(
- '<?xml version="1.0"?>\n'
- '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n'
- ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
- self.write('<html><head>\n')
- parts = [stripQuotes(x) for x in line.split(' ', 2)] + ['', '']
- title, manSection = parts[:2]
- self.write('<title>%s.%s</title>' % (title, manSection))
- self.write('</head>\n<body>\n\n')
- self.write('<h1>%s.%s</h1>\n\n' % (title, manSection))
-
- macro_DT = macro_TH
-
-
- def macro_SH(self, line):
- self.closeTags()
- self.write('<h2>')
- self.para = 1
- self.text(stripQuotes(line))
- self.para = 0
- self.closeTags()
- self.write('</h2>\n\n')
-
-
- def macro_B(self, line):
- words = line.split()
- words[0] = '\\fB' + words[0] + '\\fR '
- self.text(' '.join(words))
-
-
- def macro_NM(self, line):
- if not self.name:
- self.name = line
- self.text(self.name + ' ')
-
-
- def macro_NS(self, line):
- parts = line.split(' Ns ')
- i = 0
- for l in parts:
- i = not i
- if i:
- self.text(l)
- else:
- self.continueReceived(l)
-
-
- def macro_OO(self, line):
- self.text('[')
- self.continueReceived(line)
-
-
- def macro_OC(self, line):
- self.text(']')
- self.continueReceived(line)
-
-
- def macro_OP(self, line):
- self.text('[')
- self.continueReceived(line)
- self.text(']')
-
-
- def macro_FL(self, line):
- parts = line.split()
- self.text('\\fB-%s\\fR' % parts[0])
- self.continueReceived(' '.join(parts[1:]))
-
-
- def macro_AR(self, line):
- parts = line.split()
- self.text('\\fI %s\\fR' % parts[0])
- self.continueReceived(' '.join(parts[1:]))
-
-
- def macro_PP(self, line):
- self.closeTags()
-
-
- def macro_IC(self, line):
- cmd = line.split(' ', 1)[0]
- args = line[line.index(cmd) + len(cmd):]
- args = args.split(' ')
- text = cmd
- while args:
- arg = args.pop(0)
- if arg.lower() == "ar":
- text += " \\fU%s\\fR" % (args.pop(0),)
- elif arg.lower() == "op":
- ign = args.pop(0)
- text += " [\\fU%s\\fR]" % (args.pop(0),)
-
- self.text(text)
-
-
- def macro_TP(self, line):
- """
- Handle C{TP} token: start a definition list if it's first token, or
- close previous definition data.
- """
- if self.tp == 3:
- self.write('</dd>\n\n')
- self.tp = 1
- else:
- self.tp = 1
- self.write('<dl>')
- self.dl = 1
-
-
- def macro_BL(self, line):
- self.write('<dl>')
- self.tp = 1
-
-
- def macro_EL(self, line):
- if self.tp == 3:
- self.write('</dd>')
- self.tp = 1
- self.write('</dl>\n\n')
- self.tp = 0
-
-
- def macro_IT(self, line):
- if self.tp == 3:
- self.write('</dd>')
- self.tp = 1
- self.continueReceived(line)
-
-
- def text(self, line):
- """
- Handle a line of text without detected token.
- """
- if self.tp == 1:
- self.write('<dt>')
- if self.tp == 2:
- self.write('<dd>')
- self.paraCheck()
-
- bits = line.split('\\')
- self.write(escape(bits[0]))
- for bit in bits[1:]:
- if bit[:2] == 'fI':
- self.write('<em>' + escape(bit[2:]))
- self.state = 'em'
- elif bit[:2] == 'fB':
- self.write('<strong>' + escape(bit[2:]))
- self.state = 'strong'
- elif bit[:2] == 'fR':
- self.write('</%s>' % self.state)
- self.write(escape(bit[2:]))
- self.state = 'regular'
- elif bit[:2] == 'fU':
- # fU doesn't really exist, but it helps us to manage underlined
- # text.
- self.write('<u>' + escape(bit[2:]))
- self.state = 'u'
- elif bit[:3] == '(co':
- self.write('&copy;' + escape(bit[3:]))
- else:
- self.write(escape(bit))
-
- if self.tp == 1:
- self.write('</dt>')
- self.tp = 2
- elif self.tp == 2:
- self.tp = 3
-
-
-
-class ProcessingFunctionFactory:
-
- def generate_lore(self, d, filenameGenerator=None):
- ext = d.get('ext', '.html')
- return lambda file,_: ManConverter().convert(open(file),
- open(os.path.splitext(file)[0]+ext, 'w'))
-
-
-
-factory = ProcessingFunctionFactory()
-
-
-if __name__ == '__main__':
- import sys
- mc = ManConverter().convert(open(sys.argv[1]), sys.stdout)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/numberer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/numberer.py
deleted file mode 100755
index f91cc280..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/numberer.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-def reset():
- resetFilenum()
- setNumberSections(False)
-
-def resetFilenum():
- setFilenum(0)
-
-def setFilenum(arg):
- global filenum
- filenum = arg
-
-def getFilenum():
- global filenum
- return filenum
-
-def getNextFilenum():
- global filenum
- filenum += 1
- return filenum
-
-def setNumberSections(arg):
- global numberSections
- numberSections = arg
-
-def getNumberSections():
- global numberSections
- return numberSections
-
-reset()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/process.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/process.py
deleted file mode 100755
index ec5d0363..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/process.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# -*- test-case-name: twisted.lore.test.test_lore -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-import sys, os
-import tree #todo: get rid of this later
-import indexer
-
-class NoProcessorError(Exception):
- pass
-
-class ProcessingFailure(Exception):
- pass
-
-cols = 79
-
-def dircount(d):
- return len([1 for el in d.split("/") if el != '.'])
-
-
-class Walker:
-
- def __init__(self, df, fext, linkrel):
- self.df = df
- self.linkrel = linkrel
- self.fext = fext
- self.walked = []
- self.failures = []
-
- def walkdir(self, topdir, prefix=''):
- self.basecount = dircount(topdir)
- os.path.walk(topdir, self.walk, prefix)
-
- def walk(self, prefix, d, names):
- linkrel = prefix + '../' * (dircount(d) - self.basecount)
- for name in names:
- fullpath = os.path.join(d, name)
- fext = os.path.splitext(name)[1]
- if fext == self.fext:
- self.walked.append((linkrel, fullpath))
-
- def generate(self):
- i = 0
- indexer.clearEntries()
- tree.filenum = 0
- for linkrel, fullpath in self.walked:
- linkrel = self.linkrel + linkrel
- i += 1
- fname = os.path.splitext(fullpath)[0]
- self.percentdone((float(i) / len(self.walked)), fname)
- try:
- self.df(fullpath, linkrel)
- except ProcessingFailure, e:
- self.failures.append((fullpath, e))
- indexer.generateIndex()
- self.percentdone(1., None)
-
- def percentdone(self, percent, fname):
- # override for neater progress bars
- proglen = 40
- hashes = int(percent * proglen)
- spaces = proglen - hashes
- progstat = "[%s%s] (%s)" %('#' * hashes, ' ' * spaces,fname or "*Done*")
- progstat += (cols - len(progstat)) * ' '
- progstat += '\r'
- sys.stdout.write(progstat)
- sys.stdout.flush()
- if fname is None:
- print
-
-class PlainReportingWalker(Walker):
-
- def percentdone(self, percent, fname):
- if fname:
- print fname
-
-class NullReportingWalker(Walker):
-
- def percentdone(self, percent, fname):
- pass
-
-def parallelGenerator(originalFileName, outputExtension):
- return os.path.splitext(originalFileName)[0]+outputExtension
-
-def fooAddingGenerator(originalFileName, outputExtension):
- return os.path.splitext(originalFileName)[0]+"foo"+outputExtension
-
-def outputdirGenerator(originalFileName, outputExtension, inputdir, outputdir):
- originalFileName = os.path.abspath(originalFileName)
- abs_inputdir = os.path.abspath(inputdir)
- if os.path.commonprefix((originalFileName, abs_inputdir)) != abs_inputdir:
- raise ValueError("Original file name '" + originalFileName +
- "' not under input directory '" + abs_inputdir + "'")
-
- adjustedPath = os.path.join(outputdir, os.path.basename(originalFileName))
- return tree.getOutputFileName(adjustedPath, outputExtension)
-
-def getFilenameGenerator(config, outputExt):
- if config.get('outputdir'):
- return (lambda originalFileName, outputExtension:
- outputdirGenerator(originalFileName, outputExtension,
- os.path.abspath(config.get('inputdir')),
- os.path.abspath(config.get('outputdir'))))
- else:
- return tree.getOutputFileName
-
-def getProcessor(module, output, config):
- try:
- m = getattr(module.factory, 'generate_'+output)
- except AttributeError:
- raise NoProcessorError("cannot generate "+output+" output")
-
- if config.get('ext'):
- ext = config['ext']
- else:
- from default import htmlDefault
- ext = htmlDefault['ext']
-
- return m(config, getFilenameGenerator(config, ext))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/__init__.py
deleted file mode 100755
index 265270ef..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"lore scripts"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/lore.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/lore.py
deleted file mode 100755
index c82b2c69..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/scripts/lore.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys
-
-from zope.interface import Interface, Attribute
-
-from twisted.lore import process, indexer, numberer, htmlbook
-
-from twisted.python import usage, reflect
-from twisted import plugin as plugin
-
-class IProcessor(Interface):
- """
- """
-
- name = Attribute("The user-facing name of this processor")
-
- moduleName = Attribute(
- "The fully qualified Python name of the object defining "
- "this processor. This object (typically a module) should "
- "have a C{factory} attribute with C{generate_<output>} methods.")
-
-
-class Options(usage.Options):
-
- longdesc = "lore converts documentation formats."
-
- optFlags = [["plain", 'p', "Report filenames without progress bar"],
- ["null", 'n', "Do not report filenames"],
- ["number", 'N', "Add chapter/section numbers to section headings"],
-]
-
- optParameters = [
- ["input", "i", 'lore'],
- ["inputext", "e", ".xhtml", "The extension that your Lore input files have"],
- ["docsdir", "d", None],
- ["linkrel", "l", ''],
- ["output", "o", 'html'],
- ["index", "x", None, "The base filename you want to give your index file"],
- ["book", "b", None, "The book file to generate a book from"],
- ["prefixurl", None, "", "The prefix to stick on to relative links; only useful when processing directories"],
- ]
-
- compData = usage.Completions(
- extraActions=[usage.CompleteFiles(descr="files", repeat=True)])
-
- def __init__(self, *args, **kw):
- usage.Options.__init__(self, *args, **kw)
- self.config = {}
-
- def opt_config(self, s):
- if '=' in s:
- k, v = s.split('=', 1)
- self.config[k] = v
- else:
- self.config[s] = 1
-
- def parseArgs(self, *files):
- self['files'] = files
-
-
-def getProcessor(input, output, config):
- plugins = plugin.getPlugins(IProcessor)
- for plug in plugins:
- if plug.name == input:
- module = reflect.namedModule(plug.moduleName)
- break
- else:
- # try treating it as a module name
- try:
- module = reflect.namedModule(input)
- except ImportError:
- print '%s: no such input: %s' % (sys.argv[0], input)
- return
- try:
- return process.getProcessor(module, output, config)
- except process.NoProcessorError, e:
- print "%s: %s" % (sys.argv[0], e)
-
-
-def getWalker(df, opt):
- klass = process.Walker
- if opt['plain']:
- klass = process.PlainReportingWalker
- if opt['null']:
- klass = process.NullReportingWalker
- return klass(df, opt['inputext'], opt['linkrel'])
-
-
-def runGivenOptions(opt):
- """Do everything but parse the options; useful for testing.
- Returns a descriptive string if there's an error."""
-
- book = None
- if opt['book']:
- book = htmlbook.Book(opt['book'])
-
- df = getProcessor(opt['input'], opt['output'], opt.config)
- if not df:
- return 'getProcessor() failed'
-
- walker = getWalker(df, opt)
-
- if opt['files']:
- for filename in opt['files']:
- walker.walked.append(('', filename))
- elif book:
- for filename in book.getFiles():
- walker.walked.append(('', filename))
- else:
- walker.walkdir(opt['docsdir'] or '.', opt['prefixurl'])
-
- if opt['index']:
- indexFilename = opt['index']
- elif book:
- indexFilename = book.getIndexFilename()
- else:
- indexFilename = None
-
- if indexFilename:
- indexer.setIndexFilename("%s.%s" % (indexFilename, opt['output']))
- else:
- indexer.setIndexFilename(None)
-
- ## TODO: get numberSections from book, if any
- numberer.setNumberSections(opt['number'])
-
- walker.generate()
-
- if walker.failures:
- for (file, errors) in walker.failures:
- for error in errors:
- print "%s:%s" % (file, error)
- return 'Walker failures'
-
-
-def run():
- opt = Options()
- try:
- opt.parseOptions()
- except usage.UsageError, errortext:
- print '%s: %s' % (sys.argv[0], errortext)
- print '%s: Try --help for usage details.' % sys.argv[0]
- sys.exit(1)
-
- result = runGivenOptions(opt)
- if result:
- print result
- sys.exit(1)
-
-
-if __name__ == '__main__':
- run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/slides.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/slides.py
deleted file mode 100755
index fcddbc5d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/slides.py
+++ /dev/null
@@ -1,359 +0,0 @@
-# -*- test-case-name: twisted.lore.test.test_slides -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Rudimentary slide support for Lore.
-
-TODO:
- - Complete mgp output target
- - syntax highlighting
- - saner font handling
- - probably lots more
- - Add HTML output targets
- - one slides per page (with navigation links)
- - all in one page
-
-Example input file::
- <html>
-
- <head><title>Title of talk</title></head>
-
- <body>
- <h1>Title of talk</h1>
-
- <h2>First Slide</h2>
-
- <ul>
- <li>Bullet point</li>
- <li>Look ma, I'm <strong>bold</strong>!</li>
- <li>... etc ...</li>
- </ul>
-
-
- <h2>Second Slide</h2>
-
- <pre class="python">
- # Sample code sample.
- print "Hello, World!"
- </pre>
-
- </body>
-
- </html>
-"""
-
-from xml.dom import minidom as dom
-import os.path, re
-from cStringIO import StringIO
-
-from twisted.lore import default
-from twisted.web import domhelpers
-from twisted.python import text
-# These should be factored out
-from twisted.lore.latex import BaseLatexSpitter, LatexSpitter, processFile
-from twisted.lore.latex import getLatexText, HeadingLatexSpitter
-from twisted.lore.tree import getHeaders
-from twisted.lore.tree import removeH1, fixAPI, fontifyPython
-from twisted.lore.tree import addPyListings, addHTMLListings, setTitle
-
-hacked_entities = { 'amp': ' &', 'gt': ' >', 'lt': ' <', 'quot': ' "',
- 'copy': ' (c)'}
-
-entities = { 'amp': '&', 'gt': '>', 'lt': '<', 'quot': '"',
- 'copy': '(c)'}
-
-class MagicpointOutput(BaseLatexSpitter):
- bulletDepth = 0
-
- def writeNodeData(self, node):
- buf = StringIO()
- getLatexText(node, buf.write, entities=hacked_entities)
- data = buf.getvalue().rstrip().replace('\n', ' ')
- self.writer(re.sub(' +', ' ', data))
-
- def visitNode_title(self, node):
- self.title = domhelpers.getNodeText(node)
-
- def visitNode_body(self, node):
- # Adapted from tree.generateToC
- self.fontStack = [('standard', None)]
-
- # Title slide
- self.writer(self.start_h2)
- self.writer(self.title)
- self.writer(self.end_h2)
-
- self.writer('%center\n\n\n\n\n')
- for authorNode in domhelpers.findElementsWithAttribute(node, 'class', 'author'):
- getLatexText(authorNode, self.writer, entities=entities)
- self.writer('\n')
-
- # Table of contents
- self.writer(self.start_h2)
- self.writer(self.title)
- self.writer(self.end_h2)
-
- for element in getHeaders(node):
- level = int(element.tagName[1])-1
- self.writer(level * '\t')
- self.writer(domhelpers.getNodeText(element))
- self.writer('\n')
-
- self.visitNodeDefault(node)
-
- def visitNode_div_author(self, node):
- # Skip this node; it's already been used by visitNode_body
- pass
-
- def visitNode_div_pause(self, node):
- self.writer('%pause\n')
-
- def visitNode_pre(self, node):
- # TODO: Syntax highlighting
- buf = StringIO()
- getLatexText(node, buf.write, entities=entities)
- data = buf.getvalue()
- data = text.removeLeadingTrailingBlanks(data)
- lines = data.split('\n')
- self.fontStack.append(('typewriter', 4))
- self.writer('%' + self.fontName() + '\n')
- for line in lines:
- self.writer(' ' + line + '\n')
- del self.fontStack[-1]
- self.writer('%' + self.fontName() + '\n')
-
- def visitNode_ul(self, node):
- if self.bulletDepth > 0:
- self.writer(self._start_ul)
- self.bulletDepth += 1
- self.start_li = self._start_li * self.bulletDepth
- self.visitNodeDefault(node)
- self.bulletDepth -= 1
- self.start_li = self._start_li * self.bulletDepth
-
- def visitNode_strong(self, node):
- self.doFont(node, 'bold')
-
- def visitNode_em(self, node):
- self.doFont(node, 'italic')
-
- def visitNode_code(self, node):
- self.doFont(node, 'typewriter')
-
- def doFont(self, node, style):
- self.fontStack.append((style, None))
- self.writer(' \n%cont, ' + self.fontName() + '\n')
- self.visitNodeDefault(node)
- del self.fontStack[-1]
- self.writer('\n%cont, ' + self.fontName() + '\n')
-
- def fontName(self):
- names = [x[0] for x in self.fontStack]
- if 'typewriter' in names:
- name = 'typewriter'
- else:
- name = ''
-
- if 'bold' in names:
- name += 'bold'
- if 'italic' in names:
- name += 'italic'
-
- if name == '':
- name = 'standard'
-
- sizes = [x[1] for x in self.fontStack]
- sizes.reverse()
- for size in sizes:
- if size:
- return 'font "%s", size %d' % (name, size)
-
- return 'font "%s"' % name
-
- start_h2 = "%page\n\n"
- end_h2 = '\n\n\n'
-
- _start_ul = '\n'
-
- _start_li = "\t"
- end_li = "\n"
-
-
-def convertFile(filename, outputter, template, ext=".mgp"):
- fout = open(os.path.splitext(filename)[0]+ext, 'w')
- fout.write(open(template).read())
- spitter = outputter(fout.write, os.path.dirname(filename), filename)
- fin = open(filename)
- processFile(spitter, fin)
- fin.close()
- fout.close()
-
-
-# HTML DOM tree stuff
-
-def splitIntoSlides(document):
- body = domhelpers.findNodesNamed(document, 'body')[0]
- slides = []
- slide = []
- title = '(unset)'
- for child in body.childNodes:
- if isinstance(child, dom.Element) and child.tagName == 'h2':
- if slide:
- slides.append((title, slide))
- slide = []
- title = domhelpers.getNodeText(child)
- else:
- slide.append(child)
- slides.append((title, slide))
- return slides
-
-def insertPrevNextLinks(slides, filename, ext):
- for slide in slides:
- for name, offset in (("previous", -1), ("next", +1)):
- if (slide.pos > 0 and name == "previous") or \
- (slide.pos < len(slides)-1 and name == "next"):
- for node in domhelpers.findElementsWithAttribute(slide.dom, "class", name):
- if node.tagName == 'a':
- node.setAttribute('href', '%s-%d%s'
- % (filename[0], slide.pos+offset, ext))
- else:
- text = dom.Text()
- text.data = slides[slide.pos+offset].title
- node.appendChild(text)
- else:
- for node in domhelpers.findElementsWithAttribute(slide.dom, "class", name):
- pos = 0
- for child in node.parentNode.childNodes:
- if child is node:
- del node.parentNode.childNodes[pos]
- break
- pos += 1
-
-
-class HTMLSlide:
- def __init__(self, dom, title, pos):
- self.dom = dom
- self.title = title
- self.pos = pos
-
-
-def munge(document, template, linkrel, d, fullpath, ext, url, config):
- # FIXME: This has *way* to much duplicated crap in common with tree.munge
- #fixRelativeLinks(template, linkrel)
- removeH1(document)
- fixAPI(document, url)
- fontifyPython(document)
- addPyListings(document, d)
- addHTMLListings(document, d)
- #fixLinks(document, ext)
- #putInToC(template, generateToC(document))
- template = template.cloneNode(1)
-
- # Insert the slides into the template
- slides = []
- pos = 0
- for title, slide in splitIntoSlides(document):
- t = template.cloneNode(1)
- text = dom.Text()
- text.data = title
- setTitle(t, [text])
- tmplbody = domhelpers.findElementsWithAttribute(t, "class", "body")[0]
- tmplbody.childNodes = slide
- tmplbody.setAttribute("class", "content")
- # FIXME: Next/Prev links
- # FIXME: Perhaps there should be a "Template" class? (setTitle/setBody
- # could be methods...)
- slides.append(HTMLSlide(t, title, pos))
- pos += 1
-
- insertPrevNextLinks(slides, os.path.splitext(os.path.basename(fullpath)), ext)
-
- return slides
-
-from tree import makeSureDirectoryExists
-
-def getOutputFileName(originalFileName, outputExtension, index):
- return os.path.splitext(originalFileName)[0]+'-'+str(index) + outputExtension
-
-def doFile(filename, linkrel, ext, url, templ, options={}, outfileGenerator=getOutputFileName):
- from tree import parseFileAndReport
- doc = parseFileAndReport(filename)
- slides = munge(doc, templ, linkrel, os.path.dirname(filename), filename, ext, url, options)
- for slide, index in zip(slides, range(len(slides))):
- newFilename = outfileGenerator(filename, ext, index)
- makeSureDirectoryExists(newFilename)
- f = open(newFilename, 'wb')
- slide.dom.writexml(f)
- f.close()
-
-# Prosper output
-
-class ProsperSlides(LatexSpitter):
- firstSlide = 1
- start_html = '\\documentclass[ps]{prosper}\n'
- start_body = '\\begin{document}\n'
- start_div_author = '\\author{'
- end_div_author = '}'
-
- def visitNode_h2(self, node):
- if self.firstSlide:
- self.firstSlide = 0
- self.end_body = '\\end{slide}\n\n' + self.end_body
- else:
- self.writer('\\end{slide}\n\n')
- self.writer('\\begin{slide}{')
- spitter = HeadingLatexSpitter(self.writer, self.currDir, self.filename)
- spitter.visitNodeDefault(node)
- self.writer('}')
-
- def _write_img(self, target):
- self.writer('\\begin{center}\\includegraphics[%%\nwidth=1.0\n\\textwidth,'
- 'height=1.0\\textheight,\nkeepaspectratio]{%s}\\end{center}\n' % target)
-
-
-class PagebreakLatex(LatexSpitter):
-
- everyN = 1
- currentN = 0
- seenH2 = 0
-
- start_html = LatexSpitter.start_html+"\\date{}\n"
- start_body = '\\begin{document}\n\n'
-
- def visitNode_h2(self, node):
- if not self.seenH2:
- self.currentN = 0
- self.seenH2 = 1
- else:
- self.currentN += 1
- self.currentN %= self.everyN
- if not self.currentN:
- self.writer('\\clearpage\n')
- level = (int(node.tagName[1])-2)+self.baseLevel
- self.writer('\n\n\\'+level*'sub'+'section*{')
- spitter = HeadingLatexSpitter(self.writer, self.currDir, self.filename)
- spitter.visitNodeDefault(node)
- self.writer('}\n')
-
-class TwoPagebreakLatex(PagebreakLatex):
-
- everyN = 2
-
-
-class SlidesProcessingFunctionFactory(default.ProcessingFunctionFactory):
-
- latexSpitters = default.ProcessingFunctionFactory.latexSpitters.copy()
- latexSpitters['prosper'] = ProsperSlides
- latexSpitters['page'] = PagebreakLatex
- latexSpitters['twopage'] = TwoPagebreakLatex
-
- def getDoFile(self):
- return doFile
-
- def generate_mgp(self, d, fileNameGenerator=None):
- template = d.get('template', 'template.mgp')
- df = lambda file, linkrel: convertFile(file, MagicpointOutput, template, ext=".mgp")
- return df
-
-factory=SlidesProcessingFunctionFactory()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/template.mgp b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/template.mgp
deleted file mode 100644
index 79fc4d1c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/template.mgp
+++ /dev/null
@@ -1,24 +0,0 @@
-%%deffont "standard" tfont "Arial.ttf"
-%%deffont "bold" tfont "Arial_Bold.ttf"
-%%deffont "italic" tfont "Arial_Italic.ttf"
-%%deffont "bolditalic" tfont "Arial_Bold_Italic.ttf"
-%%deffont "typewriter" tfont "Courier_New.ttf"
-%deffont "standard" xfont "Arial-medium-r"
-%deffont "bold" xfont "Arial-bold-r"
-%deffont "italic" xfont "Arial-medium-i"
-%deffont "bolditalic" xfont "Arial-bold-i"
-%deffont "typewriter" xfont "andale mono"
-%%deffont "standard" tfont "tahoma.ttf"
-%%deffont "thick" tfont "tahomabd.ttf"
-#%deffont "typewriter" tfont "Andale_Mono.ttf"
-%default 1 area 90 90, leftfill, size 2, fore "white", back "black", font "bold"
-%default 2 size 7, vgap 10, prefix " ", center
-%default 3 size 2, bar "gray70", vgap 10, leftfill
-%default 4 size 1, fore "white", vgap 30, prefix " ", font "standard"
-%default 5 size 5
-%%tab 1 size 5, vgap 40, prefix " ", icon box "green" 50
-%%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
-%%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
-%tab 1 size 5, vgap 50, prefix " ", icon box "green" 50
-%tab 2 size 5, vgap 50, prefix " ", icon arc "yellow" 50
-%tab 3 size 4, vgap 50, prefix " ", icon delta3 "white" 40
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/__init__.py
deleted file mode 100755
index 1641a431..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"lore tests"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out.html
deleted file mode 100644
index 0490f0c1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out.html
+++ /dev/null
@@ -1,2 +0,0 @@
-language of programming: <a href="lore_index_test.html#index02">1.3</a><br />
-programming language: <a href="lore_index_test.html#index01">1.2</a><br />
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out_multiple.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out_multiple.html
deleted file mode 100644
index fa0235ef..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_out_multiple.html
+++ /dev/null
@@ -1,5 +0,0 @@
-aahz: <a href="lore_index_test2.html#index03">link</a>
-aahz2: <a href="lore_index_test2.html#index02">link</a>
-language of programming: <a href="lore_index_test.html#index02">link</a>
-<a href="lore_index_test2.html#index01">link</a>
-programming language: <a href="lore_index_test.html#index01">link</a>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_unnumbered_out.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_unnumbered_out.html
deleted file mode 100644
index fa724d7c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_file_unnumbered_out.html
+++ /dev/null
@@ -1,2 +0,0 @@
-language of programming: <a href="lore_index_test.html#index02">link</a><br />
-programming language: <a href="lore_index_test.html#index01">link</a><br />
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test.xhtml b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test.xhtml
deleted file mode 100644
index 570b4114..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test.xhtml
+++ /dev/null
@@ -1,21 +0,0 @@
-<html>
-<head>
- <title>The way of the program</title>
-</head>
-
-<body>
-
-<h1>The way of the program</h1>
-
-<p>The first paragraph.</p>
-
-
-<h2>The Python programming language</h2>
-<span class="index" value="programming language" />
-<span class="index" value="language of programming" />
-
-<p>The second paragraph.</p>
-
-
-</body>
-</html>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test2.xhtml b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test2.xhtml
deleted file mode 100644
index 4214e485..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_index_test2.xhtml
+++ /dev/null
@@ -1,22 +0,0 @@
-<html>
-<head>
- <title>The second page to index</title>
-</head>
-
-<body>
-
-<h1>The second page to index</h1>
-
-<p>The first paragraph of the second page.</p>
-
-
-<h2>The Jython programming language</h2>
-<span class="index" value="language of programming" />
-<span class="index" value="aahz2" />
-<span class="index" value="aahz" />
-
-<p>The second paragraph of the second page.</p>
-
-
-</body>
-</html>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out.html
deleted file mode 100644
index 15bb2b78..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: 1. The way of the program</title><link href="resources/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">1. The way of the program</h1><div class="toc"><ol><li><a href="#auto0">The Python programming language</a></li><li><a href="#auto1">Section The Second</a></li><li><a href="#auto2">Section The Third</a></li></ol></div><div class="content"><span></span><p>The first paragraph.</p><h2>1.1 The Python programming language<a name="auto0"></a></h2><a name="index01"></a><a name="index02"></a><p>The second paragraph.</p><h2>1.2 Section The Second<a name="auto1"></a></h2><p>The second section.</p><h2>1.3 Section The Third<a name="auto2"></a></h2><p>The Third section.</p></div><p><a href="theIndexFile.html">Index</a></p></body></html> \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out2.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out2.html
deleted file mode 100644
index 33aff77a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/lore_numbering_test_out2.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: 2. The second page to index</title><link href="resources/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">2. The second page to index</h1><div class="toc"><ol><li><a href="#auto0">The Jython programming language</a></li><li><a href="#auto1">Second Section</a></li><li><a href="#auto2">Third Section of Second Page</a></li></ol></div><div class="content"><span></span><p>The first paragraph of the second page.</p><h2>2.1 The Jython programming language<a name="auto0"></a></h2><a name="index01"></a><a name="index02"></a><a name="index03"></a><p>The second paragraph of the second page.</p><h2>2.2 Second Section<a name="auto1"></a></h2><p>The second section of the second page.</p><h2>2.3 Third Section of Second Page<a name="auto2"></a></h2><p>The Third section.</p></div><p><a href="theIndexFile.html">Index</a></p></body></html> \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple.html
deleted file mode 100644
index 8d776090..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>My Test Lore Input</title>
-</head>
-<body>
-<h1>My Test Lore Input</h1>
-<p>A Body.</p>
-</body>
-</html> \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple3.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple3.html
deleted file mode 100644
index 8d776090..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple3.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>My Test Lore Input</title>
-</head>
-<body>
-<h1>My Test Lore Input</h1>
-<p>A Body.</p>
-</body>
-</html> \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple4.html b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple4.html
deleted file mode 100644
index 8d776090..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/simple4.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>My Test Lore Input</title>
-</head>
-<body>
-<h1>My Test Lore Input</h1>
-<p>A Body.</p>
-</body>
-</html> \ No newline at end of file
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/template.tpl b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/template.tpl
deleted file mode 100644
index 195f6ca3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/template.tpl
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
- <head><title>Twisted Documentation: </title></head>
- <body bgcolor="white">
- <h1 class="title" />
- <div class="body" />
- <span class="index-link">Index</span>
- </body>
-</html>
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_docbook.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_docbook.py
deleted file mode 100755
index 4bec127f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_docbook.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.lore.docbook}.
-"""
-
-from xml.dom.minidom import Element, Text
-
-from twisted.trial.unittest import TestCase
-from twisted.lore.docbook import DocbookSpitter
-
-
-class DocbookSpitterTests(TestCase):
- """
- Tests for L{twisted.lore.docbook.DocbookSpitter}.
- """
- def test_li(self):
- """
- L{DocbookSpitter} wraps any non-I{p} elements found intside any I{li}
- elements with I{p} elements.
- """
- output = []
- spitter = DocbookSpitter(output.append)
-
- li = Element('li')
- li.appendChild(Element('p'))
- text = Text()
- text.data = 'foo bar'
- li.appendChild(text)
-
- spitter.visitNode(li)
- self.assertEqual(
- ''.join(output),
- '<listitem><para></para><para>foo bar</para></listitem>')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_latex.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_latex.py
deleted file mode 100755
index 21d5029c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_latex.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.lore.latex}.
-"""
-
-import os.path
-from xml.dom.minidom import Comment, Element, Text
-
-from twisted.python.filepath import FilePath
-from twisted.trial.unittest import TestCase
-from twisted.lore.latex import LatexSpitter, getLatexText
-
-
-class LatexHelperTests(TestCase):
- """
- Tests for free functions in L{twisted.lore.latex}.
- """
- def test_getLatexText(self):
- """
- L{getLatexText} calls the writer function with all of the text at or
- beneath the given node. Non-ASCII characters are encoded using
- UTF-8.
- """
- node = Element('foo')
- text = Text()
- text.data = u"foo \N{SNOWMAN}"
- node.appendChild(text)
- result = []
- getLatexText(node, result.append)
- self.assertEqual(result, [u"foo \N{SNOWMAN}".encode('utf-8')])
-
-
-
-class LatexSpitterTests(TestCase):
- """
- Tests for L{LatexSpitter}.
- """
- def setUp(self):
- self.filename = self.mktemp()
- self.output = []
- self.spitter = LatexSpitter(self.output.append, filename=self.filename)
-
-
- def test_head(self):
- """
- L{LatexSpitter.visitNode} writes out author information for each
- I{link} element with a I{rel} attribute set to I{author}.
- """
- head = Element('head')
- first = Element('link')
- first.setAttribute('rel', 'author')
- first.setAttribute('title', 'alice')
- second = Element('link')
- second.setAttribute('rel', 'author')
- second.setAttribute('href', 'http://example.com/bob')
- third = Element('link')
- third.setAttribute('rel', 'author')
- third.setAttribute('href', 'mailto:carol@example.com')
- head.appendChild(first)
- head.appendChild(second)
- head.appendChild(third)
-
- self.spitter.visitNode(head)
-
- self.assertEqual(
- ''.join(self.output),
- '\\author{alice \\and $<$http://example.com/bob$>$ \\and $<$carol@example.com$>$}')
-
-
- def test_skipComments(self):
- """
- L{LatexSpitter.visitNode} writes nothing to its output stream for
- comments.
- """
- self.spitter.visitNode(Comment('foo'))
- self.assertNotIn('foo', ''.join(self.output))
-
-
- def test_anchorListing(self):
- """
- L{LatexSpitter.visitNode} emits a verbatim block when it encounters a
- code listing (represented by an I{a} element with a I{listing} class).
- """
- path = FilePath(self.mktemp())
- path.setContent('foo\nbar\n')
- listing = Element('a')
- listing.setAttribute('class', 'listing')
- listing.setAttribute('href', path.path)
- self.spitter.visitNode(listing)
- self.assertEqual(
- ''.join(self.output),
- "\\begin{verbatim}\n"
- "foo\n"
- "bar\n"
- "\\end{verbatim}\\parbox[b]{\\linewidth}{\\begin{center} --- "
- "\\begin{em}temp\\end{em}\\end{center}}")
-
-
- def test_anchorListingSkipLines(self):
- """
- When passed an I{a} element with a I{listing} class and an I{skipLines}
- attribute, L{LatexSpitter.visitNode} emits a verbatim block which skips
- the indicated number of lines from the beginning of the source listing.
- """
- path = FilePath(self.mktemp())
- path.setContent('foo\nbar\n')
- listing = Element('a')
- listing.setAttribute('class', 'listing')
- listing.setAttribute('skipLines', '1')
- listing.setAttribute('href', path.path)
- self.spitter.visitNode(listing)
- self.assertEqual(
- ''.join(self.output),
- "\\begin{verbatim}\n"
- "bar\n"
- "\\end{verbatim}\\parbox[b]{\\linewidth}{\\begin{center} --- "
- "\\begin{em}temp\\end{em}\\end{center}}")
-
-
- def test_anchorRef(self):
- """
- L{LatexSpitter.visitNode} emits a footnote when it encounters an I{a}
- element with an I{href} attribute with a network scheme.
- """
- listing = Element('a')
- listing.setAttribute('href', 'http://example.com/foo')
- self.spitter.visitNode(listing)
- self.assertEqual(
- ''.join(self.output),
- "\\footnote{http://example.com/foo}")
-
-
- def test_anchorName(self):
- """
- When passed an I{a} element with a I{name} attribute,
- L{LatexSpitter.visitNode} emits a label.
- """
- listing = Element('a')
- listing.setAttribute('name', 'foo')
- self.spitter.visitNode(listing)
- self.assertEqual(
- ''.join(self.output),
- "\\label{%sHASHfoo}" % (
- os.path.abspath(self.filename).replace('\\', '/'),))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lint.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lint.py
deleted file mode 100755
index ac94df2d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lint.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.lore.lint}.
-"""
-
-import sys
-from xml.dom import minidom
-from cStringIO import StringIO
-
-from twisted.trial.unittest import TestCase
-from twisted.lore.lint import getDefaultChecker
-from twisted.lore.process import ProcessingFailure
-
-
-
-class DefaultTagCheckerTests(TestCase):
- """
- Tests for L{twisted.lore.lint.DefaultTagChecker}.
- """
- def test_quote(self):
- """
- If a non-comment node contains a quote (C{'"'}), the checker returned
- by L{getDefaultChecker} reports an error and raises
- L{ProcessingFailure}.
- """
- documentSource = (
- '<html>'
- '<head><title>foo</title></head>'
- '<body><h1>foo</h1><div>"</div></body>'
- '</html>')
- document = minidom.parseString(documentSource)
- filename = self.mktemp()
- checker = getDefaultChecker()
-
- output = StringIO()
- patch = self.patch(sys, 'stdout', output)
- self.assertRaises(ProcessingFailure, checker.check, document, filename)
- patch.restore()
-
- self.assertIn("contains quote", output.getvalue())
-
-
- def test_quoteComment(self):
- """
- If a comment node contains a quote (C{'"'}), the checker returned by
- L{getDefaultChecker} does not report an error.
- """
- documentSource = (
- '<html>'
- '<head><title>foo</title></head>'
- '<body><h1>foo</h1><!-- " --></body>'
- '</html>')
- document = minidom.parseString(documentSource)
- filename = self.mktemp()
- checker = getDefaultChecker()
-
- output = StringIO()
- patch = self.patch(sys, 'stdout', output)
- checker.check(document, filename)
- patch.restore()
-
- self.assertEqual(output.getvalue(), "")
-
-
- def test_aNode(self):
- """
- If there is an <a> tag in the document, the checker returned by
- L{getDefaultChecker} does not report an error.
- """
- documentSource = (
- '<html>'
- '<head><title>foo</title></head>'
- '<body><h1>foo</h1><a>A link.</a></body>'
- '</html>')
-
- self.assertEqual(self._lintCheck(True, documentSource), "")
-
-
- def test_textMatchesRef(self):
- """
- If an I{a} node has a link with a scheme as its contained text, a
- warning is emitted if that link does not match the value of the
- I{href} attribute.
- """
- documentSource = (
- '<html>'
- '<head><title>foo</title></head>'
- '<body><h1>foo</h1>'
- '<a href="http://bar/baz">%s</a>'
- '</body>'
- '</html>')
- self.assertEqual(
- self._lintCheck(True, documentSource % ("http://bar/baz",)), "")
- self.assertIn(
- "link text does not match href",
- self._lintCheck(False, documentSource % ("http://bar/quux",)))
-
-
- def _lintCheck(self, expectSuccess, source):
- """
- Lint the given document source and return the output.
-
- @param expectSuccess: A flag indicating whether linting is expected
- to succeed or not.
-
- @param source: The document source to lint.
-
- @return: A C{str} of the output of linting.
- """
- document = minidom.parseString(source)
- filename = self.mktemp()
- checker = getDefaultChecker()
-
- output = StringIO()
- patch = self.patch(sys, 'stdout', output)
- try:
- try:
- checker.check(document, filename)
- finally:
- patch.restore()
- except ProcessingFailure, e:
- if expectSuccess:
- raise
- else:
- if not expectSuccess:
- self.fail(
- "Expected checker to fail, but it did not. "
- "Output was: %r" % (output.getvalue(),))
-
- return output.getvalue()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lmath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lmath.py
deleted file mode 100755
index a1e4c095..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lmath.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.lore.lmath}.
-"""
-
-from xml.dom.minidom import Element, Text
-
-from twisted.trial.unittest import TestCase
-from twisted.python.filepath import FilePath
-from twisted.lore.scripts.lore import IProcessor
-
-from twisted.plugin import getPlugins
-
-from twisted.lore.lmath import formulaeToImages
-
-
-class PluginTests(TestCase):
- """
- Tests for the plugin which lets L{twisted.lore.lmath} be used from the lore
- command line tool.
- """
- def test_discoverable(self):
- """
- The plugin for L{twisted.lore.lmath} can be discovered by querying for
- L{IProcessor} plugins.
- """
- plugins = getPlugins(IProcessor)
- lmath = [p for p in plugins if p.name == "mlore"]
- self.assertEqual(len(lmath), 1, "Did not find math lore plugin: %r" % (lmath,))
-
-
-
-class FormulaeTests(TestCase):
- """
- Tests for L{formulaeToImages}.
- """
- def test_insertImages(self):
- """
- L{formulaeToImages} replaces any elements with the I{latexformula}
- class with I{img} elements which refer to external images generated
- based on the latex in the original elements.
- """
- parent = Element('div')
- base = FilePath(self.mktemp())
- base.makedirs()
-
- macros = Element('span')
- macros.setAttribute('class', 'latexmacros')
- text = Text()
- text.data = 'foo'
- macros.appendChild(text)
- parent.appendChild(macros)
-
- formula = Element('span')
- formula.setAttribute('class', 'latexformula')
- text = Text()
- text.data = 'bar'
- formula.appendChild(text)
- parent.appendChild(formula)
-
- # Avoid actually executing the commands to generate images from the
- # latex. It might be nice to have some assertions about what commands
- # are executed, or perhaps even execute them and make sure an image
- # file is created, but that is a task for another day.
- commands = []
- formulaeToImages(parent, base.path, _system=commands.append)
-
- self.assertEqual(
- parent.toxml(),
- '<div><span><br/><img src="latexformula0.png"/><br/></span></div>')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lore.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lore.py
deleted file mode 100755
index 3f399d99..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_lore.py
+++ /dev/null
@@ -1,1198 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# ++ single anchor added to individual output file
-# ++ two anchors added to individual output file
-# ++ anchors added to individual output files
-# ++ entry added to index
-# ++ index entry pointing to correct file and anchor
-# ++ multiple entries added to index
-# ++ multiple index entries pointing to correct files and anchors
-# __ all of above for files in deep directory structure
-#
-# ++ group index entries by indexed term
-# ++ sort index entries by indexed term
-# __ hierarchical index entries (e.g. language!programming)
-#
-# ++ add parameter for what the index filename should be
-# ++ add (default) ability to NOT index (if index not specified)
-#
-# ++ put actual index filename into INDEX link (if any) in the template
-# __ make index links RELATIVE!
-# __ make index pay attention to the outputdir!
-#
-# __ make index look nice
-#
-# ++ add section numbers to headers in lore output
-# ++ make text of index entry links be chapter numbers
-# ++ make text of index entry links be section numbers
-#
-# __ put all of our test files someplace neat and tidy
-#
-
-import os, shutil, errno, time
-from StringIO import StringIO
-from xml.dom import minidom as dom
-
-from twisted.trial import unittest
-from twisted.python.filepath import FilePath
-
-from twisted.lore import tree, process, indexer, numberer, htmlbook, default
-from twisted.lore.default import factory
-from twisted.lore.latex import LatexSpitter
-
-from twisted.python.util import sibpath
-
-from twisted.lore.scripts import lore
-
-from twisted.web import domhelpers
-
-def sp(originalFileName):
- return sibpath(__file__, originalFileName)
-
-options = {"template" : sp("template.tpl"), 'baseurl': '%s', 'ext': '.xhtml' }
-d = options
-
-
-class _XMLAssertionMixin:
- """
- Test mixin defining a method for comparing serialized XML documents.
- """
- def assertXMLEqual(self, first, second):
- """
- Verify that two strings represent the same XML document.
- """
- self.assertEqual(
- dom.parseString(first).toxml(),
- dom.parseString(second).toxml())
-
-
-class TestFactory(unittest.TestCase, _XMLAssertionMixin):
-
- file = sp('simple.html')
- linkrel = ""
-
- def assertEqualFiles1(self, exp, act):
- if (exp == act): return True
- fact = open(act)
- self.assertEqualsFile(exp, fact.read())
-
- def assertEqualFiles(self, exp, act):
- if (exp == act): return True
- fact = open(sp(act))
- self.assertEqualsFile(exp, fact.read())
-
- def assertEqualsFile(self, exp, act):
- expected = open(sp(exp)).read()
- self.assertEqual(expected, act)
-
- def makeTemp(self, *filenames):
- tmp = self.mktemp()
- os.mkdir(tmp)
- for filename in filenames:
- tmpFile = os.path.join(tmp, filename)
- shutil.copyfile(sp(filename), tmpFile)
- return tmp
-
-########################################
-
- def setUp(self):
- indexer.reset()
- numberer.reset()
-
- def testProcessingFunctionFactory(self):
- base = FilePath(self.mktemp())
- base.makedirs()
-
- simple = base.child('simple.html')
- FilePath(__file__).sibling('simple.html').copyTo(simple)
-
- htmlGenerator = factory.generate_html(options)
- htmlGenerator(simple.path, self.linkrel)
-
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: My Test Lore Input</title></head>
- <body bgcolor="white">
- <h1 class="title">My Test Lore Input</h1>
- <div class="content">
-<span/>
-<p>A Body.</p>
-</div>
- <a href="index.xhtml">Index</a>
- </body>
-</html>""",
- simple.sibling('simple.xhtml').getContent())
-
-
- def testProcessingFunctionFactoryWithFilenameGenerator(self):
- base = FilePath(self.mktemp())
- base.makedirs()
-
- def filenameGenerator(originalFileName, outputExtension):
- name = os.path.splitext(FilePath(originalFileName).basename())[0]
- return base.child(name + outputExtension).path
-
- htmlGenerator = factory.generate_html(options, filenameGenerator)
- htmlGenerator(self.file, self.linkrel)
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: My Test Lore Input</title></head>
- <body bgcolor="white">
- <h1 class="title">My Test Lore Input</h1>
- <div class="content">
-<span/>
-<p>A Body.</p>
-</div>
- <a href="index.xhtml">Index</a>
- </body>
-</html>""",
- base.child("simple.xhtml").getContent())
-
-
- def test_doFile(self):
- base = FilePath(self.mktemp())
- base.makedirs()
-
- simple = base.child('simple.html')
- FilePath(__file__).sibling('simple.html').copyTo(simple)
-
- templ = dom.parse(open(d['template']))
-
- tree.doFile(simple.path, self.linkrel, d['ext'], d['baseurl'], templ, d)
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: My Test Lore Input</title></head>
- <body bgcolor="white">
- <h1 class="title">My Test Lore Input</h1>
- <div class="content">
-<span/>
-<p>A Body.</p>
-</div>
- <a href="index.xhtml">Index</a>
- </body>
-</html>""",
- base.child("simple.xhtml").getContent())
-
-
- def test_doFile_withFilenameGenerator(self):
- base = FilePath(self.mktemp())
- base.makedirs()
-
- def filenameGenerator(originalFileName, outputExtension):
- name = os.path.splitext(FilePath(originalFileName).basename())[0]
- return base.child(name + outputExtension).path
-
- templ = dom.parse(open(d['template']))
- tree.doFile(self.file, self.linkrel, d['ext'], d['baseurl'], templ, d, filenameGenerator)
-
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: My Test Lore Input</title></head>
- <body bgcolor="white">
- <h1 class="title">My Test Lore Input</h1>
- <div class="content">
-<span/>
-<p>A Body.</p>
-</div>
- <a href="index.xhtml">Index</a>
- </body>
-</html>""",
- base.child("simple.xhtml").getContent())
-
-
- def test_munge(self):
- indexer.setIndexFilename("lore_index_file.html")
- doc = dom.parse(open(self.file))
- node = dom.parse(open(d['template']))
- tree.munge(doc, node, self.linkrel,
- os.path.dirname(self.file),
- self.file,
- d['ext'], d['baseurl'], d)
-
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: My Test Lore Input</title></head>
- <body bgcolor="white">
- <h1 class="title">My Test Lore Input</h1>
- <div class="content">
-<span/>
-<p>A Body.</p>
-</div>
- <a href="lore_index_file.html">Index</a>
- </body>
-</html>""",
- node.toxml())
-
-
- def test_mungeAuthors(self):
- """
- If there is a node with a I{class} attribute set to C{"authors"},
- L{tree.munge} adds anchors as children to it, takeing the necessary
- information from any I{link} nodes in the I{head} with their I{rel}
- attribute set to C{"author"}.
- """
- document = dom.parseString(
- """\
-<html>
- <head>
- <title>munge authors</title>
- <link rel="author" title="foo" href="bar"/>
- <link rel="author" title="baz" href="quux"/>
- <link rel="author" title="foobar" href="barbaz"/>
- </head>
- <body>
- <h1>munge authors</h1>
- </body>
-</html>""")
- template = dom.parseString(
- """\
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
- <head>
- <title />
- </head>
-
- <body>
- <div class="body" />
- <div class="authors" />
- </body>
-</html>
-""")
- tree.munge(
- document, template, self.linkrel, os.path.dirname(self.file),
- self.file, d['ext'], d['baseurl'], d)
-
- self.assertXMLEqual(
- template.toxml(),
- """\
-<?xml version="1.0" ?><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>munge authors</title>
- <link href="bar" rel="author" title="foo"/><link href="quux" rel="author" title="baz"/><link href="barbaz" rel="author" title="foobar"/></head>
-
- <body>
- <div class="content">
- <span/>
- </div>
- <div class="authors"><span><a href="bar">foo</a>, <a href="quux">baz</a>, and <a href="barbaz">foobar</a></span></div>
- </body>
-</html>""")
-
-
- def test_getProcessor(self):
-
- base = FilePath(self.mktemp())
- base.makedirs()
- input = base.child("simple3.html")
- FilePath(__file__).sibling("simple3.html").copyTo(input)
-
- options = { 'template': sp('template.tpl'), 'ext': '.xhtml', 'baseurl': 'burl',
- 'filenameMapping': None }
- p = process.getProcessor(default, "html", options)
- p(input.path, self.linkrel)
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: My Test Lore Input</title></head>
- <body bgcolor="white">
- <h1 class="title">My Test Lore Input</h1>
- <div class="content">
-<span/>
-<p>A Body.</p>
-</div>
- <a href="index.xhtml">Index</a>
- </body>
-</html>""",
- base.child("simple3.xhtml").getContent())
-
- def test_outputdirGenerator(self):
- normp = os.path.normpath; join = os.path.join
- inputdir = normp(join("/", 'home', 'joe'))
- outputdir = normp(join("/", 'away', 'joseph'))
- actual = process.outputdirGenerator(join("/", 'home', 'joe', "myfile.html"),
- '.xhtml', inputdir, outputdir)
- expected = normp(join("/", 'away', 'joseph', 'myfile.xhtml'))
- self.assertEqual(expected, actual)
-
- def test_outputdirGeneratorBadInput(self):
- options = {'outputdir': '/away/joseph/', 'inputdir': '/home/joe/' }
- self.assertRaises(ValueError, process.outputdirGenerator, '.html', '.xhtml', **options)
-
- def test_makeSureDirectoryExists(self):
- dirname = os.path.join("tmp", 'nonexistentdir')
- if os.path.exists(dirname):
- os.rmdir(dirname)
- self.failIf(os.path.exists(dirname), "Hey: someone already created the dir")
- filename = os.path.join(dirname, 'newfile')
- tree.makeSureDirectoryExists(filename)
- self.failUnless(os.path.exists(dirname), 'should have created dir')
- os.rmdir(dirname)
-
-
- def test_indexAnchorsAdded(self):
- indexer.setIndexFilename('theIndexFile.html')
- # generate the output file
- templ = dom.parse(open(d['template']))
- tmp = self.makeTemp('lore_index_test.xhtml')
-
- tree.doFile(os.path.join(tmp, 'lore_index_test.xhtml'),
- self.linkrel, '.html', d['baseurl'], templ, d)
-
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: The way of the program</title></head>
- <body bgcolor="white">
- <h1 class="title">The way of the program</h1>
- <div class="content">
-
-<span/>
-
-<p>The first paragraph.</p>
-
-
-<h2>The Python programming language<a name="auto0"/></h2>
-<a name="index01"/>
-<a name="index02"/>
-
-<p>The second paragraph.</p>
-
-
-</div>
- <a href="theIndexFile.html">Index</a>
- </body>
-</html>""",
- FilePath(tmp).child("lore_index_test.html").getContent())
-
-
- def test_indexEntriesAdded(self):
- indexer.addEntry('lore_index_test.html', 'index02', 'language of programming', '1.3')
- indexer.addEntry('lore_index_test.html', 'index01', 'programming language', '1.2')
- indexer.setIndexFilename("lore_index_file.html")
- indexer.generateIndex()
- self.assertEqualFiles1("lore_index_file_out.html", "lore_index_file.html")
-
- def test_book(self):
- tmp = self.makeTemp()
- inputFilename = sp('lore_index_test.xhtml')
-
- bookFilename = os.path.join(tmp, 'lore_test_book.book')
- bf = open(bookFilename, 'w')
- bf.write('Chapter(r"%s", None)\r\n' % inputFilename)
- bf.close()
-
- book = htmlbook.Book(bookFilename)
- expected = {'indexFilename': None,
- 'chapters': [(inputFilename, None)],
- }
- dct = book.__dict__
- for k in dct:
- self.assertEqual(dct[k], expected[k])
-
- def test_runningLore(self):
- options = lore.Options()
- tmp = self.makeTemp('lore_index_test.xhtml')
-
- templateFilename = sp('template.tpl')
- inputFilename = os.path.join(tmp, 'lore_index_test.xhtml')
- indexFilename = 'theIndexFile'
-
- bookFilename = os.path.join(tmp, 'lore_test_book.book')
- bf = open(bookFilename, 'w')
- bf.write('Chapter(r"%s", None)\n' % inputFilename)
- bf.close()
-
- options.parseOptions(['--null', '--book=%s' % bookFilename,
- '--config', 'template=%s' % templateFilename,
- '--index=%s' % indexFilename
- ])
- result = lore.runGivenOptions(options)
- self.assertEqual(None, result)
- self.assertEqualFiles1("lore_index_file_unnumbered_out.html", indexFilename + ".html")
-
-
- def test_runningLoreMultipleFiles(self):
- tmp = self.makeTemp('lore_index_test.xhtml', 'lore_index_test2.xhtml')
- templateFilename = sp('template.tpl')
- inputFilename = os.path.join(tmp, 'lore_index_test.xhtml')
- inputFilename2 = os.path.join(tmp, 'lore_index_test2.xhtml')
- indexFilename = 'theIndexFile'
-
- bookFilename = os.path.join(tmp, 'lore_test_book.book')
- bf = open(bookFilename, 'w')
- bf.write('Chapter(r"%s", None)\n' % inputFilename)
- bf.write('Chapter(r"%s", None)\n' % inputFilename2)
- bf.close()
-
- options = lore.Options()
- options.parseOptions(['--null', '--book=%s' % bookFilename,
- '--config', 'template=%s' % templateFilename,
- '--index=%s' % indexFilename
- ])
- result = lore.runGivenOptions(options)
- self.assertEqual(None, result)
-
- self.assertEqual(
- # XXX This doesn't seem like a very good index file.
- """\
-aahz: <a href="lore_index_test2.html#index03">link</a><br />
-aahz2: <a href="lore_index_test2.html#index02">link</a><br />
-language of programming: <a href="lore_index_test.html#index02">link</a>, <a href="lore_index_test2.html#index01">link</a><br />
-programming language: <a href="lore_index_test.html#index01">link</a><br />
-""",
- file(FilePath(indexFilename + ".html").path).read())
-
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: The way of the program</title></head>
- <body bgcolor="white">
- <h1 class="title">The way of the program</h1>
- <div class="content">
-
-<span/>
-
-<p>The first paragraph.</p>
-
-
-<h2>The Python programming language<a name="auto0"/></h2>
-<a name="index01"/>
-<a name="index02"/>
-
-<p>The second paragraph.</p>
-
-
-</div>
- <a href="theIndexFile.html">Index</a>
- </body>
-</html>""",
- FilePath(tmp).child("lore_index_test.html").getContent())
-
- self.assertXMLEqual(
- """\
-<?xml version="1.0" ?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
- <head><title>Twisted Documentation: The second page to index</title></head>
- <body bgcolor="white">
- <h1 class="title">The second page to index</h1>
- <div class="content">
-
-<span/>
-
-<p>The first paragraph of the second page.</p>
-
-
-<h2>The Jython programming language<a name="auto0"/></h2>
-<a name="index01"/>
-<a name="index02"/>
-<a name="index03"/>
-
-<p>The second paragraph of the second page.</p>
-
-
-</div>
- <a href="theIndexFile.html">Index</a>
- </body>
-</html>""",
- FilePath(tmp).child("lore_index_test2.html").getContent())
-
-
-
- def XXXtest_NumberedSections(self):
- # run two files through lore, with numbering turned on
- # every h2 should be numbered:
- # first file's h2s should be 1.1, 1.2
- # second file's h2s should be 2.1, 2.2
- templateFilename = sp('template.tpl')
- inputFilename = sp('lore_numbering_test.xhtml')
- inputFilename2 = sp('lore_numbering_test2.xhtml')
- indexFilename = 'theIndexFile'
-
- # you can number without a book:
- options = lore.Options()
- options.parseOptions(['--null',
- '--index=%s' % indexFilename,
- '--config', 'template=%s' % templateFilename,
- '--config', 'ext=%s' % ".tns",
- '--number',
- inputFilename, inputFilename2])
- result = lore.runGivenOptions(options)
-
- self.assertEqual(None, result)
- #self.assertEqualFiles1("lore_index_file_out_multiple.html", indexFilename + ".tns")
- # VVV change to new, numbered files
- self.assertEqualFiles("lore_numbering_test_out.html", "lore_numbering_test.tns")
- self.assertEqualFiles("lore_numbering_test_out2.html", "lore_numbering_test2.tns")
-
-
- def test_setTitle(self):
- """
- L{tree.setTitle} inserts the given title into the first I{title}
- element and the first element with the I{title} class in the given
- template.
- """
- parent = dom.Element('div')
- firstTitle = dom.Element('title')
- parent.appendChild(firstTitle)
- secondTitle = dom.Element('span')
- secondTitle.setAttribute('class', 'title')
- parent.appendChild(secondTitle)
-
- titleNodes = [dom.Text()]
- # minidom has issues with cloning documentless-nodes. See Python issue
- # 4851.
- titleNodes[0].ownerDocument = dom.Document()
- titleNodes[0].data = 'foo bar'
-
- tree.setTitle(parent, titleNodes, None)
- self.assertEqual(firstTitle.toxml(), '<title>foo bar</title>')
- self.assertEqual(
- secondTitle.toxml(), '<span class="title">foo bar</span>')
-
-
- def test_setTitleWithChapter(self):
- """
- L{tree.setTitle} includes a chapter number if it is passed one.
- """
- document = dom.Document()
-
- parent = dom.Element('div')
- parent.ownerDocument = document
-
- title = dom.Element('title')
- parent.appendChild(title)
-
- titleNodes = [dom.Text()]
- titleNodes[0].ownerDocument = document
- titleNodes[0].data = 'foo bar'
-
- # Oh yea. The numberer has to agree to put the chapter number in, too.
- numberer.setNumberSections(True)
-
- tree.setTitle(parent, titleNodes, '13')
- self.assertEqual(title.toxml(), '<title>13. foo bar</title>')
-
-
- def test_setIndexLink(self):
- """
- Tests to make sure that index links are processed when an index page
- exists and removed when there is not.
- """
- templ = dom.parse(open(d['template']))
- indexFilename = 'theIndexFile'
- numLinks = len(domhelpers.findElementsWithAttribute(templ,
- "class",
- "index-link"))
-
- # if our testing template has no index-link nodes, complain about it
- self.assertNotEquals(
- [],
- domhelpers.findElementsWithAttribute(templ,
- "class",
- "index-link"))
-
- tree.setIndexLink(templ, indexFilename)
-
- self.assertEqual(
- [],
- domhelpers.findElementsWithAttribute(templ,
- "class",
- "index-link"))
-
- indexLinks = domhelpers.findElementsWithAttribute(templ,
- "href",
- indexFilename)
- self.assertTrue(len(indexLinks) >= numLinks)
-
- templ = dom.parse(open(d['template']))
- self.assertNotEquals(
- [],
- domhelpers.findElementsWithAttribute(templ,
- "class",
- "index-link"))
- indexFilename = None
-
- tree.setIndexLink(templ, indexFilename)
-
- self.assertEqual(
- [],
- domhelpers.findElementsWithAttribute(templ,
- "class",
- "index-link"))
-
-
- def test_addMtime(self):
- """
- L{tree.addMtime} inserts a text node giving the last modification time
- of the specified file wherever it encounters an element with the
- I{mtime} class.
- """
- path = FilePath(self.mktemp())
- path.setContent('')
- when = time.ctime(path.getModificationTime())
-
- parent = dom.Element('div')
- mtime = dom.Element('span')
- mtime.setAttribute('class', 'mtime')
- parent.appendChild(mtime)
-
- tree.addMtime(parent, path.path)
- self.assertEqual(
- mtime.toxml(), '<span class="mtime">' + when + '</span>')
-
-
- def test_makeLineNumbers(self):
- """
- L{tree._makeLineNumbers} takes an integer and returns a I{p} tag with
- that number of line numbers in it.
- """
- numbers = tree._makeLineNumbers(1)
- self.assertEqual(numbers.tagName, 'p')
- self.assertEqual(numbers.getAttribute('class'), 'py-linenumber')
- self.assertIsInstance(numbers.firstChild, dom.Text)
- self.assertEqual(numbers.firstChild.nodeValue, '1\n')
-
- numbers = tree._makeLineNumbers(10)
- self.assertEqual(numbers.tagName, 'p')
- self.assertEqual(numbers.getAttribute('class'), 'py-linenumber')
- self.assertIsInstance(numbers.firstChild, dom.Text)
- self.assertEqual(
- numbers.firstChild.nodeValue,
- ' 1\n 2\n 3\n 4\n 5\n'
- ' 6\n 7\n 8\n 9\n10\n')
-
-
- def test_fontifyPythonNode(self):
- """
- L{tree.fontifyPythonNode} accepts a text node and replaces it in its
- parent with a syntax colored and line numbered version of the Python
- source it contains.
- """
- parent = dom.Element('div')
- source = dom.Text()
- source.data = 'def foo():\n pass\n'
- parent.appendChild(source)
-
- tree.fontifyPythonNode(source)
-
- expected = """\
-<div><pre class="python"><p class="py-linenumber">1
-2
-</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">foo</span>():
- <span class="py-src-keyword">pass</span>
-</pre></div>"""
-
- self.assertEqual(parent.toxml(), expected)
-
-
- def test_addPyListings(self):
- """
- L{tree.addPyListings} accepts a document with nodes with their I{class}
- attribute set to I{py-listing} and replaces those nodes with Python
- source listings from the file given by the node's I{href} attribute.
- """
- listingPath = FilePath(self.mktemp())
- listingPath.setContent('def foo():\n pass\n')
-
- parent = dom.Element('div')
- listing = dom.Element('a')
- listing.setAttribute('href', listingPath.basename())
- listing.setAttribute('class', 'py-listing')
- parent.appendChild(listing)
-
- tree.addPyListings(parent, listingPath.dirname())
-
- expected = """\
-<div><div class="py-listing"><pre><p class="py-linenumber">1
-2
-</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">foo</span>():
- <span class="py-src-keyword">pass</span>
-</pre><div class="caption"> - <a href="temp"><span class="filename">temp</span></a></div></div></div>"""
-
- self.assertEqual(parent.toxml(), expected)
-
-
- def test_addPyListingsSkipLines(self):
- """
- If a node with the I{py-listing} class also has a I{skipLines}
- attribute, that number of lines from the beginning of the source
- listing are omitted.
- """
- listingPath = FilePath(self.mktemp())
- listingPath.setContent('def foo():\n pass\n')
-
- parent = dom.Element('div')
- listing = dom.Element('a')
- listing.setAttribute('href', listingPath.basename())
- listing.setAttribute('class', 'py-listing')
- listing.setAttribute('skipLines', 1)
- parent.appendChild(listing)
-
- tree.addPyListings(parent, listingPath.dirname())
-
- expected = """\
-<div><div class="py-listing"><pre><p class="py-linenumber">1
-</p> <span class="py-src-keyword">pass</span>
-</pre><div class="caption"> - <a href="temp"><span class="filename">temp</span></a></div></div></div>"""
-
- self.assertEqual(parent.toxml(), expected)
-
-
- def test_fixAPI(self):
- """
- The element passed to L{tree.fixAPI} has all of its children with the
- I{API} class rewritten to contain links to the API which is referred to
- by the text they contain.
- """
- parent = dom.Element('div')
- link = dom.Element('span')
- link.setAttribute('class', 'API')
- text = dom.Text()
- text.data = 'foo'
- link.appendChild(text)
- parent.appendChild(link)
-
- tree.fixAPI(parent, 'http://example.com/%s')
- self.assertEqual(
- parent.toxml(),
- '<div><span class="API">'
- '<a href="http://example.com/foo" title="foo">foo</a>'
- '</span></div>')
-
-
- def test_fixAPIBase(self):
- """
- If a node with the I{API} class and a value for the I{base} attribute
- is included in the DOM passed to L{tree.fixAPI}, the link added to that
- node refers to the API formed by joining the value of the I{base}
- attribute to the text contents of the node.
- """
- parent = dom.Element('div')
- link = dom.Element('span')
- link.setAttribute('class', 'API')
- link.setAttribute('base', 'bar')
- text = dom.Text()
- text.data = 'baz'
- link.appendChild(text)
- parent.appendChild(link)
-
- tree.fixAPI(parent, 'http://example.com/%s')
-
- self.assertEqual(
- parent.toxml(),
- '<div><span class="API">'
- '<a href="http://example.com/bar.baz" title="bar.baz">baz</a>'
- '</span></div>')
-
-
- def test_fixLinks(self):
- """
- Links in the nodes of the DOM passed to L{tree.fixLinks} have their
- extensions rewritten to the given extension.
- """
- parent = dom.Element('div')
- link = dom.Element('a')
- link.setAttribute('href', 'foo.html')
- parent.appendChild(link)
-
- tree.fixLinks(parent, '.xhtml')
-
- self.assertEqual(parent.toxml(), '<div><a href="foo.xhtml"/></div>')
-
-
- def test_setVersion(self):
- """
- Nodes of the DOM passed to L{tree.setVersion} which have the I{version}
- class have the given version added to them a child.
- """
- parent = dom.Element('div')
- version = dom.Element('span')
- version.setAttribute('class', 'version')
- parent.appendChild(version)
-
- tree.setVersion(parent, '1.2.3')
-
- self.assertEqual(
- parent.toxml(), '<div><span class="version">1.2.3</span></div>')
-
-
- def test_footnotes(self):
- """
- L{tree.footnotes} finds all of the nodes with the I{footnote} class in
- the DOM passed to it and adds a footnotes section to the end of the
- I{body} element which includes them. It also inserts links to those
- footnotes from the original definition location.
- """
- parent = dom.Element('div')
- body = dom.Element('body')
- footnote = dom.Element('span')
- footnote.setAttribute('class', 'footnote')
- text = dom.Text()
- text.data = 'this is the footnote'
- footnote.appendChild(text)
- body.appendChild(footnote)
- body.appendChild(dom.Element('p'))
- parent.appendChild(body)
-
- tree.footnotes(parent)
-
- self.assertEqual(
- parent.toxml(),
- '<div><body>'
- '<a href="#footnote-1" title="this is the footnote">'
- '<super>1</super>'
- '</a>'
- '<p/>'
- '<h2>Footnotes</h2>'
- '<ol><li><a name="footnote-1">'
- '<span class="footnote">this is the footnote</span>'
- '</a></li></ol>'
- '</body></div>')
-
-
- def test_generateTableOfContents(self):
- """
- L{tree.generateToC} returns an element which contains a table of
- contents generated from the headers in the document passed to it.
- """
- parent = dom.Element('body')
- header = dom.Element('h2')
- text = dom.Text()
- text.data = u'header & special character'
- header.appendChild(text)
- parent.appendChild(header)
- subheader = dom.Element('h3')
- text = dom.Text()
- text.data = 'subheader'
- subheader.appendChild(text)
- parent.appendChild(subheader)
-
- tableOfContents = tree.generateToC(parent)
- self.assertEqual(
- tableOfContents.toxml(),
- '<ol><li><a href="#auto0">header &amp; special character</a></li><ul><li><a href="#auto1">subheader</a></li></ul></ol>')
-
- self.assertEqual(
- header.toxml(),
- '<h2>header &amp; special character<a name="auto0"/></h2>')
-
- self.assertEqual(
- subheader.toxml(),
- '<h3>subheader<a name="auto1"/></h3>')
-
-
- def test_putInToC(self):
- """
- L{tree.putInToC} replaces all of the children of the first node with
- the I{toc} class with the given node representing a table of contents.
- """
- parent = dom.Element('div')
- toc = dom.Element('span')
- toc.setAttribute('class', 'toc')
- toc.appendChild(dom.Element('foo'))
- parent.appendChild(toc)
-
- tree.putInToC(parent, dom.Element('toc'))
-
- self.assertEqual(toc.toxml(), '<span class="toc"><toc/></span>')
-
-
- def test_invalidTableOfContents(self):
- """
- If passed a document with I{h3} elements before any I{h2} element,
- L{tree.generateToC} raises L{ValueError} explaining that this is not a
- valid document.
- """
- parent = dom.Element('body')
- parent.appendChild(dom.Element('h3'))
- err = self.assertRaises(ValueError, tree.generateToC, parent)
- self.assertEqual(
- str(err), "No H3 element is allowed until after an H2 element")
-
-
- def test_notes(self):
- """
- L{tree.notes} inserts some additional markup before the first child of
- any node with the I{note} class.
- """
- parent = dom.Element('div')
- noteworthy = dom.Element('span')
- noteworthy.setAttribute('class', 'note')
- noteworthy.appendChild(dom.Element('foo'))
- parent.appendChild(noteworthy)
-
- tree.notes(parent)
-
- self.assertEqual(
- noteworthy.toxml(),
- '<span class="note"><strong>Note: </strong><foo/></span>')
-
-
- def test_findNodeJustBefore(self):
- """
- L{tree.findNodeJustBefore} returns the previous sibling of the node it
- is passed. The list of nodes passed in is ignored.
- """
- parent = dom.Element('div')
- result = dom.Element('foo')
- target = dom.Element('bar')
- parent.appendChild(result)
- parent.appendChild(target)
-
- self.assertIdentical(
- tree.findNodeJustBefore(target, [parent, result]),
- result)
-
- # Also, support other configurations. This is a really not nice API.
- newTarget = dom.Element('baz')
- target.appendChild(newTarget)
- self.assertIdentical(
- tree.findNodeJustBefore(newTarget, [parent, result]),
- result)
-
-
- def test_getSectionNumber(self):
- """
- L{tree.getSectionNumber} accepts an I{H2} element and returns its text
- content.
- """
- header = dom.Element('foo')
- text = dom.Text()
- text.data = 'foobar'
- header.appendChild(text)
- self.assertEqual(tree.getSectionNumber(header), 'foobar')
-
-
- def test_numberDocument(self):
- """
- L{tree.numberDocument} inserts section numbers into the text of each
- header.
- """
- parent = dom.Element('foo')
- section = dom.Element('h2')
- text = dom.Text()
- text.data = 'foo'
- section.appendChild(text)
- parent.appendChild(section)
-
- tree.numberDocument(parent, '7')
-
- self.assertEqual(section.toxml(), '<h2>7.1 foo</h2>')
-
-
- def test_parseFileAndReport(self):
- """
- L{tree.parseFileAndReport} parses the contents of the filename passed
- to it and returns the corresponding DOM.
- """
- path = FilePath(self.mktemp())
- path.setContent('<foo bar="baz">hello</foo>\n')
-
- document = tree.parseFileAndReport(path.path)
- self.assertXMLEqual(
- document.toxml(),
- '<?xml version="1.0" ?><foo bar="baz">hello</foo>')
-
-
- def test_parseFileAndReportMismatchedTags(self):
- """
- If the contents of the file passed to L{tree.parseFileAndReport}
- contain a mismatched tag, L{process.ProcessingFailure} is raised
- indicating the location of the open and close tags which were
- mismatched.
- """
- path = FilePath(self.mktemp())
- path.setContent(' <foo>\n\n </bar>')
-
- err = self.assertRaises(
- process.ProcessingFailure, tree.parseFileAndReport, path.path)
- self.assertEqual(
- str(err),
- "mismatched close tag at line 3, column 4; expected </foo> "
- "(from line 1, column 2)")
-
- # Test a case which requires involves proper close tag handling.
- path.setContent('<foo><bar></bar>\n </baz>')
-
- err = self.assertRaises(
- process.ProcessingFailure, tree.parseFileAndReport, path.path)
- self.assertEqual(
- str(err),
- "mismatched close tag at line 2, column 4; expected </foo> "
- "(from line 1, column 0)")
-
-
- def test_parseFileAndReportParseError(self):
- """
- If the contents of the file passed to L{tree.parseFileAndReport} cannot
- be parsed for a reason other than mismatched tags,
- L{process.ProcessingFailure} is raised with a string describing the
- parse error.
- """
- path = FilePath(self.mktemp())
- path.setContent('\n foo')
-
- err = self.assertRaises(
- process.ProcessingFailure, tree.parseFileAndReport, path.path)
- self.assertEqual(str(err), 'syntax error at line 2, column 3')
-
-
- def test_parseFileAndReportIOError(self):
- """
- If an L{IOError} is raised while reading from the file specified to
- L{tree.parseFileAndReport}, a L{process.ProcessingFailure} is raised
- indicating what the error was. The file should be closed by the
- time the exception is raised to the caller.
- """
- class FakeFile:
- _open = True
- def read(self, bytes=None):
- raise IOError(errno.ENOTCONN, 'socket not connected')
-
- def close(self):
- self._open = False
-
- theFile = FakeFile()
- def fakeOpen(filename):
- return theFile
-
- err = self.assertRaises(
- process.ProcessingFailure, tree.parseFileAndReport, "foo", fakeOpen)
- self.assertEqual(str(err), "socket not connected, filename was 'foo'")
- self.assertFalse(theFile._open)
-
-
-
-class XMLParsingTests(unittest.TestCase):
- """
- Tests for various aspects of parsing a Lore XML input document using
- L{tree.parseFileAndReport}.
- """
- def _parseTest(self, xml):
- path = FilePath(self.mktemp())
- path.setContent(xml)
- return tree.parseFileAndReport(path.path)
-
-
- def test_withoutDocType(self):
- """
- A Lore XML input document may omit a I{DOCTYPE} declaration. If it
- does so, the XHTML1 Strict DTD is used.
- """
- # Parsing should succeed.
- document = self._parseTest("<foo>uses an xhtml entity: &copy;</foo>")
- # But even more than that, the &copy; entity should be turned into the
- # appropriate unicode codepoint.
- self.assertEqual(
- domhelpers.gatherTextNodes(document.documentElement),
- u"uses an xhtml entity: \N{COPYRIGHT SIGN}")
-
-
- def test_withTransitionalDocType(self):
- """
- A Lore XML input document may include a I{DOCTYPE} declaration
- referring to the XHTML1 Transitional DTD.
- """
- # Parsing should succeed.
- document = self._parseTest("""\
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<foo>uses an xhtml entity: &copy;</foo>
-""")
- # But even more than that, the &copy; entity should be turned into the
- # appropriate unicode codepoint.
- self.assertEqual(
- domhelpers.gatherTextNodes(document.documentElement),
- u"uses an xhtml entity: \N{COPYRIGHT SIGN}")
-
-
- def test_withStrictDocType(self):
- """
- A Lore XML input document may include a I{DOCTYPE} declaration
- referring to the XHTML1 Strict DTD.
- """
- # Parsing should succeed.
- document = self._parseTest("""\
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<foo>uses an xhtml entity: &copy;</foo>
-""")
- # But even more than that, the &copy; entity should be turned into the
- # appropriate unicode codepoint.
- self.assertEqual(
- domhelpers.gatherTextNodes(document.documentElement),
- u"uses an xhtml entity: \N{COPYRIGHT SIGN}")
-
-
- def test_withDisallowedDocType(self):
- """
- A Lore XML input document may not include a I{DOCTYPE} declaration
- referring to any DTD other than XHTML1 Transitional or XHTML1 Strict.
- """
- self.assertRaises(
- process.ProcessingFailure,
- self._parseTest,
- """\
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
-<foo>uses an xhtml entity: &copy;</foo>
-""")
-
-
-
-class XMLSerializationTests(unittest.TestCase, _XMLAssertionMixin):
- """
- Tests for L{tree._writeDocument}.
- """
- def test_nonASCIIData(self):
- """
- A document which contains non-ascii characters is serialized to a
- file using UTF-8.
- """
- document = dom.Document()
- parent = dom.Element('foo')
- text = dom.Text()
- text.data = u'\N{SNOWMAN}'
- parent.appendChild(text)
- document.appendChild(parent)
- outFile = self.mktemp()
- tree._writeDocument(outFile, document)
- self.assertXMLEqual(
- FilePath(outFile).getContent(),
- u'<foo>\N{SNOWMAN}</foo>'.encode('utf-8'))
-
-
-
-class LatexSpitterTestCase(unittest.TestCase):
- """
- Tests for the Latex output plugin.
- """
- def test_indexedSpan(self):
- """
- Test processing of a span tag with an index class results in a latex
- \\index directive the correct value.
- """
- doc = dom.parseString('<span class="index" value="name" />').documentElement
- out = StringIO()
- spitter = LatexSpitter(out.write)
- spitter.visitNode(doc)
- self.assertEqual(out.getvalue(), u'\\index{name}\n')
-
-
-
-class ScriptTests(unittest.TestCase):
- """
- Tests for L{twisted.lore.scripts.lore}, the I{lore} command's
- implementation,
- """
- def test_getProcessor(self):
- """
- L{lore.getProcessor} loads the specified output plugin from the
- specified input plugin.
- """
- processor = lore.getProcessor("lore", "html", options)
- self.assertNotIdentical(processor, None)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_man2lore.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_man2lore.py
deleted file mode 100755
index 06ada301..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_man2lore.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Tests for L{twisted.lore.man2lore}.
-"""
-
-from StringIO import StringIO
-
-from twisted.trial.unittest import TestCase
-
-from twisted.lore.man2lore import ManConverter
-
-
-_TRANSITIONAL_XHTML_DTD = ("""\
-<?xml version="1.0"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-""")
-
-
-class ManConverterTestCase(TestCase):
- """
- Tests for L{ManConverter}.
- """
-
- def setUp(self):
- """
- Build instance variables useful for tests.
-
- @ivar converter: a L{ManConverter} to be used during tests.
- """
- self.converter = ManConverter()
-
-
- def assertConvert(self, inputLines, expectedOutput):
- """
- Helper method to check conversion from a man page to a Lore output.
-
- @param inputLines: lines of the manpages.
- @type inputLines: C{list}
-
- @param expectedOutput: expected Lore content.
- @type expectedOutput: C{str}
- """
- inputFile = StringIO()
- for line in inputLines:
- inputFile.write(line + '\n')
- inputFile.seek(0)
- outputFile = StringIO()
- self.converter.convert(inputFile, outputFile)
- self.assertEqual(
- outputFile.getvalue(), _TRANSITIONAL_XHTML_DTD + expectedOutput)
-
-
- def test_convert(self):
- """
- Test convert on a minimal example.
- """
- inputLines = ['.TH BAR "1" "Oct 2007" "" ""', "Foo\n"]
- output = ("<html><head>\n<title>BAR.1</title></head>\n<body>\n\n"
- "<h1>BAR.1</h1>\n\n<p>Foo\n\n</p>\n\n</body>\n</html>\n")
- self.assertConvert(inputLines, output)
-
-
- def test_TP(self):
- """
- Test C{TP} parsing.
- """
- inputLines = ['.TH BAR "1" "Oct 2007" "" ""',
- ".SH HEADER",
- ".TP",
- "\\fB-o\\fR, \\fB--option\\fR",
- "An option"]
- output = ("<html><head>\n<title>BAR.1</title></head>\n<body>\n\n"
- "<h1>BAR.1</h1>\n\n<h2>HEADER</h2>\n\n<dl><dt>"
- "<strong>-o</strong>, <strong>--option</strong>\n</dt>"
- "<dd>An option\n</dd>\n\n</dl>\n\n</body>\n</html>\n")
- self.assertConvert(inputLines, output)
-
-
- def test_TPMultipleOptions(self):
- """
- Try to parse multiple C{TP} fields.
- """
- inputLines = ['.TH BAR "1" "Oct 2007" "" ""',
- ".SH HEADER",
- ".TP",
- "\\fB-o\\fR, \\fB--option\\fR",
- "An option",
- ".TP",
- "\\fB-n\\fR, \\fB--another\\fR",
- "Another option",
- ]
- output = ("<html><head>\n<title>BAR.1</title></head>\n<body>\n\n"
- "<h1>BAR.1</h1>\n\n<h2>HEADER</h2>\n\n<dl><dt>"
- "<strong>-o</strong>, <strong>--option</strong>\n</dt>"
- "<dd>An option\n</dd>\n\n<dt>"
- "<strong>-n</strong>, <strong>--another</strong>\n</dt>"
- "<dd>Another option\n</dd>\n\n</dl>\n\n</body>\n</html>\n")
- self.assertConvert(inputLines, output)
-
-
- def test_TPMultiLineOptions(self):
- """
- Try to parse multiple C{TP} fields, with options text on several lines.
- """
- inputLines = ['.TH BAR "1" "Oct 2007" "" ""',
- ".SH HEADER",
- ".TP",
- "\\fB-o\\fR, \\fB--option\\fR",
- "An option",
- "on two lines",
- ".TP",
- "\\fB-n\\fR, \\fB--another\\fR",
- "Another option",
- "on two lines",
- ]
- output = ("<html><head>\n<title>BAR.1</title></head>\n<body>\n\n"
- "<h1>BAR.1</h1>\n\n<h2>HEADER</h2>\n\n<dl><dt>"
- "<strong>-o</strong>, <strong>--option</strong>\n</dt>"
- "<dd>An option\non two lines\n</dd>\n\n"
- "<dt><strong>-n</strong>, <strong>--another</strong>\n</dt>"
- "<dd>Another option\non two lines\n</dd>\n\n</dl>\n\n"
- "</body>\n</html>\n")
- self.assertConvert(inputLines, output)
-
-
- def test_ITLegacyManagement(self):
- """
- Test management of BL/IT/EL used in some man pages.
- """
- inputLines = ['.TH BAR "1" "Oct 2007" "" ""',
- ".SH HEADER",
- ".BL",
- ".IT An option",
- "on two lines",
- ".IT",
- "Another option",
- "on two lines",
- ".EL"
- ]
- output = ("<html><head>\n<title>BAR.1</title></head>\n<body>\n\n"
- "<h1>BAR.1</h1>\n\n<h2>HEADER</h2>\n\n<dl>"
- "<dt>on two lines\n</dt><dd>Another option\non two lines\n"
- "</dd></dl>\n\n</body>\n</html>\n")
- self.assertConvert(inputLines, output)
-
-
- def test_interactiveCommand(self):
- """
- Test management of interactive command tag.
- """
- inputLines = ['.TH BAR "1" "Oct 2007" "" ""',
- ".SH HEADER",
- ".BL",
- ".IT IC foo AR bar",
- "option 1",
- ".IT IC egg AR spam OP AR stuff",
- "option 2",
- ".EL"
- ]
- output = ("<html><head>\n<title>BAR.1</title></head>\n<body>\n\n"
- "<h1>BAR.1</h1>\n\n<h2>HEADER</h2>\n\n<dl>"
- "<dt>foo <u>bar</u></dt><dd>option 1\n</dd><dt>egg "
- "<u>spam</u> [<u>stuff</u>]</dt><dd>option 2\n</dd></dl>"
- "\n\n</body>\n</html>\n")
- self.assertConvert(inputLines, output)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_scripts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_scripts.py
deleted file mode 100755
index 0a8328b9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_scripts.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the command-line interface to lore.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.scripts.test.test_scripts import ScriptTestsMixin
-from twisted.python.test.test_shellcomp import ZshScriptTestMixin
-
-
-
-class ScriptTests(TestCase, ScriptTestsMixin):
- """
- Tests for all one of lore's scripts.
- """
- def test_lore(self):
- self.scriptTest("lore/lore")
-
-
-
-class ZshIntegrationTestCase(TestCase, ZshScriptTestMixin):
- """
- Test that zsh completion functions are generated without error
- """
- generateFor = [('lore', 'twisted.lore.scripts.lore.Options')]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_slides.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_slides.py
deleted file mode 100755
index 78d2cbe6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/test/test_slides.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.lore.slides}.
-"""
-
-from xml.dom.minidom import Element, Text
-
-from twisted.trial.unittest import TestCase
-from twisted.lore.slides import HTMLSlide, splitIntoSlides, insertPrevNextLinks
-
-
-class SlidesTests(TestCase):
- """
- Tests for functions in L{twisted.lore.slides}.
- """
- def test_splitIntoSlides(self):
- """
- L{splitIntoSlides} accepts a document and returns a list of two-tuples,
- each element of which contains the title of a slide taken from an I{h2}
- element and the body of that slide.
- """
- parent = Element('html')
- body = Element('body')
- parent.appendChild(body)
-
- first = Element('h2')
- text = Text()
- text.data = 'first slide'
- first.appendChild(text)
- body.appendChild(first)
- body.appendChild(Element('div'))
- body.appendChild(Element('span'))
-
- second = Element('h2')
- text = Text()
- text.data = 'second slide'
- second.appendChild(text)
- body.appendChild(second)
- body.appendChild(Element('p'))
- body.appendChild(Element('br'))
-
- slides = splitIntoSlides(parent)
-
- self.assertEqual(slides[0][0], 'first slide')
- firstContent = slides[0][1]
- self.assertEqual(firstContent[0].tagName, 'div')
- self.assertEqual(firstContent[1].tagName, 'span')
- self.assertEqual(len(firstContent), 2)
-
- self.assertEqual(slides[1][0], 'second slide')
- secondContent = slides[1][1]
- self.assertEqual(secondContent[0].tagName, 'p')
- self.assertEqual(secondContent[1].tagName, 'br')
- self.assertEqual(len(secondContent), 2)
-
- self.assertEqual(len(slides), 2)
-
-
- def test_insertPrevNextText(self):
- """
- L{insertPrevNextLinks} appends a text node with the title of the
- previous slide to each node with a I{previous} class and the title of
- the next slide to each node with a I{next} class.
- """
- next = Element('span')
- next.setAttribute('class', 'next')
- container = Element('div')
- container.appendChild(next)
- slideWithNext = HTMLSlide(container, 'first', 0)
-
- previous = Element('span')
- previous.setAttribute('class', 'previous')
- container = Element('div')
- container.appendChild(previous)
- slideWithPrevious = HTMLSlide(container, 'second', 1)
-
- insertPrevNextLinks(
- [slideWithNext, slideWithPrevious], None, None)
-
- self.assertEqual(
- next.toxml(), '<span class="next">second</span>')
- self.assertEqual(
- previous.toxml(), '<span class="previous">first</span>')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/texi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/texi.py
deleted file mode 100755
index 03f7347b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/texi.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-from cStringIO import StringIO
-import os, re
-from twisted.python import text
-from twisted.web import domhelpers
-import latex, tree
-
-spaceRe = re.compile('\s+')
-
-def texiEscape(text):
- return spaceRe.sub(text, ' ')
-
-entities = latex.entities.copy()
-entities['copy'] = '@copyright{}'
-
-class TexiSpitter(latex.BaseLatexSpitter):
-
- baseLevel = 1
-
- def writeNodeData(self, node):
- buf = StringIO()
- latex.getLatexText(node, self.writer, texiEscape, entities)
-
- def visitNode_title(self, node):
- self.writer('@node ')
- self.visitNodeDefault(node)
- self.writer('\n')
- self.writer('@section ')
- self.visitNodeDefault(node)
- self.writer('\n')
- headers = tree.getHeaders(domhelpers.getParents(node)[-1])
- if not headers:
- return
- self.writer('@menu\n')
- for header in headers:
- self.writer('* %s::\n' % domhelpers.getNodeText(header))
- self.writer('@end menu\n')
-
- def visitNode_pre(self, node):
- self.writer('@verbatim\n')
- buf = StringIO()
- latex.getLatexText(node, buf.write, entities=entities)
- self.writer(text.removeLeadingTrailingBlanks(buf.getvalue()))
- self.writer('@end verbatim\n')
-
- def visitNode_code(self, node):
- fout = StringIO()
- latex.getLatexText(node, fout.write, texiEscape, entities)
- self.writer('@code{'+fout.getvalue()+'}')
-
- def visitNodeHeader(self, node):
- self.writer('\n\n@node ')
- self.visitNodeDefault(node)
- self.writer('\n')
- level = (int(node.tagName[1])-2)+self.baseLevel
- self.writer('\n\n@'+level*'sub'+'section ')
- self.visitNodeDefault(node)
- self.writer('\n')
-
- def visitNode_a_listing(self, node):
- fileName = os.path.join(self.currDir, node.getAttribute('href'))
- self.writer('@verbatim\n')
- self.writer(open(fileName).read())
- self.writer('@end verbatim')
- # Write a caption for this source listing
-
- def visitNode_a_href(self, node):
- self.visitNodeDefault(node)
-
- def visitNode_a_name(self, node):
- self.visitNodeDefault(node)
-
- visitNode_h2 = visitNode_h3 = visitNode_h4 = visitNodeHeader
-
- start_dl = '@itemize\n'
- end_dl = '@end itemize\n'
- start_ul = '@itemize\n'
- end_ul = '@end itemize\n'
-
- start_ol = '@enumerate\n'
- end_ol = '@end enumerate\n'
-
- start_li = '@item\n'
- end_li = '\n'
-
- start_dt = '@item\n'
- end_dt = ': '
- end_dd = '\n'
-
- start_p = '\n\n'
-
- start_strong = start_em = '@emph{'
- end_strong = end_em = '}'
-
- start_q = "``"
- end_q = "''"
-
- start_span_footnote = '@footnote{'
- end_span_footnote = '}'
-
- start_div_note = '@quotation\n@strong{Note:}'
- end_div_note = '@end quotation\n'
-
- start_th = '@strong{'
- end_th = '}'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/NEWS
deleted file mode 100644
index ab50ef4d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/NEWS
+++ /dev/null
@@ -1,161 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Lore 12.2.0 (2012-08-26)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Lore 12.1.0 (2012-06-02)
-================================
-
-Bugfixes
---------
- - twisted.plugins.twisted_lore's MathProcessor plugin is now
- associated with the correct implementation module. (#5326)
-
-
-Twisted Lore 12.0.0 (2012-02-10)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Lore 11.1.0 (2011-11-15)
-================================
-
-Bugfixes
---------
- - When run from an unpacked source tarball or a VCS checkout,
- bin/lore/lore will now use the version of Twisted it is part of.
- (#3526)
-
-Deprecations and Removals
--------------------------
- - Removed compareMarkPos and comparePosition from lore.tree,
- deprecated in Twisted 9.0. (#5127)
-
-
-Twisted Lore 11.0.0 (2011-04-01)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Lore 10.2.0 (2010-11-29)
-================================
-
-No significant changes have been made for this release.
-
-Other
------
- - #4571
-
-
-Twisted Lore 10.1.0 (2010-06-27)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Lore 10.0.0 (2010-03-01)
-================================
-
-Other
------
- - #4241
-
-
-Twisted Lore 9.0.0 (2009-11-24)
-===============================
-
-Features
---------
- - Python source listings now include line numbers (#3486)
-
-Fixes
------
- - Lore now uses minidom instead of Twisted's microdom, which incidentally
- fixes some Lore bugs such as throwing away certain whitespace
- (#3560, #414, #3619)
- - Lore's "lint" command should no longer break on documents with links in them
- (#4051, #4115)
-
-Deprecations and Removals
--------------------------
- - Lore no longer uses the ancient "tml" Twisted plugin system (#1911)
-
-Other
------
- - #3565, #3246, #3540, #3750, #4050
-
-
-Lore 8.2.0 (2008-12-16)
-=======================
-
-Other
------
- - #2207, #2514
-
-
-8.1.0 (2008-05-18)
-==================
-
-Fixes
------
- - The deprecated mktap API is no longer used (#3127)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Fixes
------
- - Change twisted.lore.tree.setIndexLin so that it removes node with index-link
- class when the specified index filename is None. (#812)
- - Fix the conversion of the list of options in man pages to Lore format.
- (#3017)
- - Fix conch man pages generation. (#3075)
- - Fix management of the interactive command tag in man2lore. (#3076)
-
-Misc
-----
- - #2847
-
-
-0.3.0 (2007-01-06)
-==================
-
-Features
---------
- - Many docstrings were added to twisted.lore.tree (#2301)
-
-Fixes
------
- - Emitting a span with an index class to latex now works (#2134)
-
-
-0.2.0 (2006-05-24)
-==================
-
-Features
---------
- - Docstring improvements.
-
-Fixes
------
- - Embedded Dia support for Latex no longer requires the 'which'
- command line tool.
- - Misc: #1142.
-
-Deprecations
-------------
- - The unused, undocumented, untested and severely crashy 'bookify'
- functionality was removed.
-
-
-0.1.0
-=====
- - Use htmlizer mode that doesn't insert extra span tags, thus making
- it not mess up in Safari.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/README
deleted file mode 100644
index c520f7ac..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/topfiles/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Twisted Lore 12.2.0
-
-Twisted Lore depends on Twisted and Twisted Web.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/tree.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/tree.py
deleted file mode 100755
index 5cc71aa7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/tree.py
+++ /dev/null
@@ -1,1122 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from itertools import count
-import re, os, cStringIO, time, cgi, urlparse
-from xml.dom import minidom as dom
-from xml.sax.handler import ErrorHandler, feature_validation
-from xml.dom.pulldom import SAX2DOM
-from xml.sax import make_parser
-from xml.sax.xmlreader import InputSource
-
-from twisted.python import htmlizer, text
-from twisted.python.filepath import FilePath
-from twisted.web import domhelpers
-import process, latex, indexer, numberer, htmlbook
-
-# relative links to html files
-def fixLinks(document, ext):
- """
- Rewrite links to XHTML lore input documents so they point to lore XHTML
- output documents.
-
- Any node with an C{href} attribute which does not contain a value starting
- with C{http}, C{https}, C{ftp}, or C{mailto} and which does not have a
- C{class} attribute of C{absolute} or which contains C{listing} and which
- does point to an URL ending with C{html} will have that attribute value
- rewritten so that the filename extension is C{ext} instead of C{html}.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @type ext: C{str}
- @param ext: The extension to use when selecting an output file name. This
- replaces the extension of the input file name.
-
- @return: C{None}
- """
- supported_schemes=['http', 'https', 'ftp', 'mailto']
- for node in domhelpers.findElementsWithAttribute(document, 'href'):
- href = node.getAttribute("href")
- if urlparse.urlparse(href)[0] in supported_schemes:
- continue
- if node.getAttribute("class") == "absolute":
- continue
- if node.getAttribute("class").find('listing') != -1:
- continue
-
- # This is a relative link, so it should be munged.
- if href.endswith('html') or href[:href.rfind('#')].endswith('html'):
- fname, fext = os.path.splitext(href)
- if '#' in fext:
- fext = ext+'#'+fext.split('#', 1)[1]
- else:
- fext = ext
- node.setAttribute("href", fname + fext)
-
-
-
-def addMtime(document, fullpath):
- """
- Set the last modified time of the given document.
-
- @type document: A DOM Node or Document
- @param document: The output template which defines the presentation of the
- last modified time.
-
- @type fullpath: C{str}
- @param fullpath: The file name from which to take the last modified time.
-
- @return: C{None}
- """
- for node in domhelpers.findElementsWithAttribute(document, "class","mtime"):
- txt = dom.Text()
- txt.data = time.ctime(os.path.getmtime(fullpath))
- node.appendChild(txt)
-
-
-
-def _getAPI(node):
- """
- Retrieve the fully qualified Python name represented by the given node.
-
- The name is represented by one or two aspects of the node: the value of the
- node's first child forms the end of the name. If the node has a C{base}
- attribute, that attribute's value is prepended to the node's value, with
- C{.} separating the two parts.
-
- @rtype: C{str}
- @return: The fully qualified Python name.
- """
- base = ""
- if node.hasAttribute("base"):
- base = node.getAttribute("base") + "."
- return base+node.childNodes[0].nodeValue
-
-
-
-def fixAPI(document, url):
- """
- Replace API references with links to API documentation.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @type url: C{str}
- @param url: A string which will be interpolated with the fully qualified
- Python name of any API reference encountered in the input document, the
- result of which will be used as a link to API documentation for that name
- in the output document.
-
- @return: C{None}
- """
- # API references
- for node in domhelpers.findElementsWithAttribute(document, "class", "API"):
- fullname = _getAPI(node)
- anchor = dom.Element('a')
- anchor.setAttribute('href', url % (fullname,))
- anchor.setAttribute('title', fullname)
- while node.childNodes:
- child = node.childNodes[0]
- node.removeChild(child)
- anchor.appendChild(child)
- node.appendChild(anchor)
- if node.hasAttribute('base'):
- node.removeAttribute('base')
-
-
-
-def fontifyPython(document):
- """
- Syntax color any node in the given document which contains a Python source
- listing.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @return: C{None}
- """
- def matcher(node):
- return (node.nodeName == 'pre' and node.hasAttribute('class') and
- node.getAttribute('class') == 'python')
- for node in domhelpers.findElements(document, matcher):
- fontifyPythonNode(node)
-
-
-
-def fontifyPythonNode(node):
- """
- Syntax color the given node containing Python source code.
-
- The node must have a parent.
-
- @return: C{None}
- """
- oldio = cStringIO.StringIO()
- latex.getLatexText(node, oldio.write,
- entities={'lt': '<', 'gt': '>', 'amp': '&'})
- oldio = cStringIO.StringIO(oldio.getvalue().strip()+'\n')
- howManyLines = len(oldio.getvalue().splitlines())
- newio = cStringIO.StringIO()
- htmlizer.filter(oldio, newio, writer=htmlizer.SmallerHTMLWriter)
- lineLabels = _makeLineNumbers(howManyLines)
- newel = dom.parseString(newio.getvalue()).documentElement
- newel.setAttribute("class", "python")
- node.parentNode.replaceChild(newel, node)
- newel.insertBefore(lineLabels, newel.firstChild)
-
-
-
-def addPyListings(document, dir):
- """
- Insert Python source listings into the given document from files in the
- given directory based on C{py-listing} nodes.
-
- Any node in C{document} with a C{class} attribute set to C{py-listing} will
- have source lines taken from the file named in that node's C{href}
- attribute (searched for in C{dir}) inserted in place of that node.
-
- If a node has a C{skipLines} attribute, its value will be parsed as an
- integer and that many lines will be skipped at the beginning of the source
- file.
-
- @type document: A DOM Node or Document
- @param document: The document within which to make listing replacements.
-
- @type dir: C{str}
- @param dir: The directory in which to find source files containing the
- referenced Python listings.
-
- @return: C{None}
- """
- for node in domhelpers.findElementsWithAttribute(document, "class",
- "py-listing"):
- filename = node.getAttribute("href")
- outfile = cStringIO.StringIO()
- lines = map(str.rstrip, open(os.path.join(dir, filename)).readlines())
-
- skip = node.getAttribute('skipLines') or 0
- lines = lines[int(skip):]
- howManyLines = len(lines)
- data = '\n'.join(lines)
-
- data = cStringIO.StringIO(text.removeLeadingTrailingBlanks(data))
- htmlizer.filter(data, outfile, writer=htmlizer.SmallerHTMLWriter)
- sourceNode = dom.parseString(outfile.getvalue()).documentElement
- sourceNode.insertBefore(_makeLineNumbers(howManyLines), sourceNode.firstChild)
- _replaceWithListing(node, sourceNode.toxml(), filename, "py-listing")
-
-
-
-def _makeLineNumbers(howMany):
- """
- Return an element which will render line numbers for a source listing.
-
- @param howMany: The number of lines in the source listing.
- @type howMany: C{int}
-
- @return: An L{dom.Element} which can be added to the document before
- the source listing to add line numbers to it.
- """
- # Figure out how many digits wide the widest line number label will be.
- width = len(str(howMany))
-
- # Render all the line labels with appropriate padding
- labels = ['%*d' % (width, i) for i in range(1, howMany + 1)]
-
- # Create a p element with the right style containing the labels
- p = dom.Element('p')
- p.setAttribute('class', 'py-linenumber')
- t = dom.Text()
- t.data = '\n'.join(labels) + '\n'
- p.appendChild(t)
- return p
-
-
-def _replaceWithListing(node, val, filename, class_):
- captionTitle = domhelpers.getNodeText(node)
- if captionTitle == os.path.basename(filename):
- captionTitle = 'Source listing'
- text = ('<div class="%s">%s<div class="caption">%s - '
- '<a href="%s"><span class="filename">%s</span></a></div></div>' %
- (class_, val, captionTitle, filename, filename))
- newnode = dom.parseString(text).documentElement
- node.parentNode.replaceChild(newnode, node)
-
-
-
-def addHTMLListings(document, dir):
- """
- Insert HTML source listings into the given document from files in the given
- directory based on C{html-listing} nodes.
-
- Any node in C{document} with a C{class} attribute set to C{html-listing}
- will have source lines taken from the file named in that node's C{href}
- attribute (searched for in C{dir}) inserted in place of that node.
-
- @type document: A DOM Node or Document
- @param document: The document within which to make listing replacements.
-
- @type dir: C{str}
- @param dir: The directory in which to find source files containing the
- referenced HTML listings.
-
- @return: C{None}
- """
- for node in domhelpers.findElementsWithAttribute(document, "class",
- "html-listing"):
- filename = node.getAttribute("href")
- val = ('<pre class="htmlsource">\n%s</pre>' %
- cgi.escape(open(os.path.join(dir, filename)).read()))
- _replaceWithListing(node, val, filename, "html-listing")
-
-
-
-def addPlainListings(document, dir):
- """
- Insert text listings into the given document from files in the given
- directory based on C{listing} nodes.
-
- Any node in C{document} with a C{class} attribute set to C{listing} will
- have source lines taken from the file named in that node's C{href}
- attribute (searched for in C{dir}) inserted in place of that node.
-
- @type document: A DOM Node or Document
- @param document: The document within which to make listing replacements.
-
- @type dir: C{str}
- @param dir: The directory in which to find source files containing the
- referenced text listings.
-
- @return: C{None}
- """
- for node in domhelpers.findElementsWithAttribute(document, "class",
- "listing"):
- filename = node.getAttribute("href")
- val = ('<pre>\n%s</pre>' %
- cgi.escape(open(os.path.join(dir, filename)).read()))
- _replaceWithListing(node, val, filename, "listing")
-
-
-
-def getHeaders(document):
- """
- Return all H2 and H3 nodes in the given document.
-
- @type document: A DOM Node or Document
-
- @rtype: C{list}
- """
- return domhelpers.findElements(
- document,
- lambda n, m=re.compile('h[23]$').match: m(n.nodeName))
-
-
-
-def generateToC(document):
- """
- Create a table of contents for the given document.
-
- @type document: A DOM Node or Document
-
- @rtype: A DOM Node
- @return: a Node containing a table of contents based on the headers of the
- given document.
- """
- subHeaders = None
- headers = []
- for element in getHeaders(document):
- if element.tagName == 'h2':
- subHeaders = []
- headers.append((element, subHeaders))
- elif subHeaders is None:
- raise ValueError(
- "No H3 element is allowed until after an H2 element")
- else:
- subHeaders.append(element)
-
- auto = count().next
-
- def addItem(headerElement, parent):
- anchor = dom.Element('a')
- name = 'auto%d' % (auto(),)
- anchor.setAttribute('href', '#' + name)
- text = dom.Text()
- text.data = domhelpers.getNodeText(headerElement)
- anchor.appendChild(text)
- headerNameItem = dom.Element('li')
- headerNameItem.appendChild(anchor)
- parent.appendChild(headerNameItem)
- anchor = dom.Element('a')
- anchor.setAttribute('name', name)
- headerElement.appendChild(anchor)
-
- toc = dom.Element('ol')
- for headerElement, subHeaders in headers:
- addItem(headerElement, toc)
- if subHeaders:
- subtoc = dom.Element('ul')
- toc.appendChild(subtoc)
- for subHeaderElement in subHeaders:
- addItem(subHeaderElement, subtoc)
-
- return toc
-
-
-
-def putInToC(document, toc):
- """
- Insert the given table of contents into the given document.
-
- The node with C{class} attribute set to C{toc} has its children replaced
- with C{toc}.
-
- @type document: A DOM Node or Document
- @type toc: A DOM Node
- """
- tocOrig = domhelpers.findElementsWithAttribute(document, 'class', 'toc')
- if tocOrig:
- tocOrig= tocOrig[0]
- tocOrig.childNodes = [toc]
-
-
-
-def removeH1(document):
- """
- Replace all C{h1} nodes in the given document with empty C{span} nodes.
-
- C{h1} nodes mark up document sections and the output template is given an
- opportunity to present this information in a different way.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @return: C{None}
- """
- h1 = domhelpers.findNodesNamed(document, 'h1')
- empty = dom.Element('span')
- for node in h1:
- node.parentNode.replaceChild(empty, node)
-
-
-
-def footnotes(document):
- """
- Find footnotes in the given document, move them to the end of the body, and
- generate links to them.
-
- A footnote is any node with a C{class} attribute set to C{footnote}.
- Footnote links are generated as superscript. Footnotes are collected in a
- C{ol} node at the end of the document.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @return: C{None}
- """
- footnotes = domhelpers.findElementsWithAttribute(document, "class",
- "footnote")
- if not footnotes:
- return
- footnoteElement = dom.Element('ol')
- id = 1
- for footnote in footnotes:
- href = dom.parseString('<a href="#footnote-%(id)d">'
- '<super>%(id)d</super></a>'
- % vars()).documentElement
- text = ' '.join(domhelpers.getNodeText(footnote).split())
- href.setAttribute('title', text)
- target = dom.Element('a')
- target.setAttribute('name', 'footnote-%d' % (id,))
- target.childNodes = [footnote]
- footnoteContent = dom.Element('li')
- footnoteContent.childNodes = [target]
- footnoteElement.childNodes.append(footnoteContent)
- footnote.parentNode.replaceChild(href, footnote)
- id += 1
- body = domhelpers.findNodesNamed(document, "body")[0]
- header = dom.parseString('<h2>Footnotes</h2>').documentElement
- body.childNodes.append(header)
- body.childNodes.append(footnoteElement)
-
-
-
-def notes(document):
- """
- Find notes in the given document and mark them up as such.
-
- A note is any node with a C{class} attribute set to C{note}.
-
- (I think this is a very stupid feature. When I found it I actually
- exclaimed out loud. -exarkun)
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @return: C{None}
- """
- notes = domhelpers.findElementsWithAttribute(document, "class", "note")
- notePrefix = dom.parseString('<strong>Note: </strong>').documentElement
- for note in notes:
- note.childNodes.insert(0, notePrefix)
-
-
-
-def findNodeJustBefore(target, nodes):
- """
- Find the last Element which is a sibling of C{target} and is in C{nodes}.
-
- @param target: A node the previous sibling of which to return.
- @param nodes: A list of nodes which might be the right node.
-
- @return: The previous sibling of C{target}.
- """
- while target is not None:
- node = target.previousSibling
- while node is not None:
- if node in nodes:
- return node
- node = node.previousSibling
- target = target.parentNode
- raise RuntimeError("Oops")
-
-
-
-def getFirstAncestorWithSectionHeader(entry):
- """
- Visit the ancestors of C{entry} until one with at least one C{h2} child
- node is found, then return all of that node's C{h2} child nodes.
-
- @type entry: A DOM Node
- @param entry: The node from which to begin traversal. This node itself is
- excluded from consideration.
-
- @rtype: C{list} of DOM Nodes
- @return: All C{h2} nodes of the ultimately selected parent node.
- """
- for a in domhelpers.getParents(entry)[1:]:
- headers = domhelpers.findNodesNamed(a, "h2")
- if len(headers) > 0:
- return headers
- return []
-
-
-
-def getSectionNumber(header):
- """
- Retrieve the section number of the given node.
-
- This is probably intended to interact in a rather specific way with
- L{numberDocument}.
-
- @type header: A DOM Node or L{None}
- @param header: The section from which to extract a number. The section
- number is the value of this node's first child.
-
- @return: C{None} or a C{str} giving the section number.
- """
- if not header:
- return None
- return domhelpers.gatherTextNodes(header.childNodes[0])
-
-
-
-def getSectionReference(entry):
- """
- Find the section number which contains the given node.
-
- This function looks at the given node's ancestry until it finds a node
- which defines a section, then returns that section's number.
-
- @type entry: A DOM Node
- @param entry: The node for which to determine the section.
-
- @rtype: C{str}
- @return: The section number, as returned by C{getSectionNumber} of the
- first ancestor of C{entry} which defines a section, as determined by
- L{getFirstAncestorWithSectionHeader}.
- """
- headers = getFirstAncestorWithSectionHeader(entry)
- myHeader = findNodeJustBefore(entry, headers)
- return getSectionNumber(myHeader)
-
-
-
-def index(document, filename, chapterReference):
- """
- Extract index entries from the given document and store them for later use
- and insert named anchors so that the index can link back to those entries.
-
- Any node with a C{class} attribute set to C{index} is considered an index
- entry.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @type filename: C{str}
- @param filename: A link to the output for the given document which will be
- included in the index to link to any index entry found here.
-
- @type chapterReference: ???
- @param chapterReference: ???
-
- @return: C{None}
- """
- entries = domhelpers.findElementsWithAttribute(document, "class", "index")
- if not entries:
- return
- i = 0;
- for entry in entries:
- i += 1
- anchor = 'index%02d' % i
- if chapterReference:
- ref = getSectionReference(entry) or chapterReference
- else:
- ref = 'link'
- indexer.addEntry(filename, anchor, entry.getAttribute('value'), ref)
- # does nodeName even affect anything?
- entry.nodeName = entry.tagName = entry.endTagName = 'a'
- for attrName in entry.attributes.keys():
- entry.removeAttribute(attrName)
- entry.setAttribute('name', anchor)
-
-
-
-def setIndexLink(template, indexFilename):
- """
- Insert a link to an index document.
-
- Any node with a C{class} attribute set to C{index-link} will have its tag
- name changed to C{a} and its C{href} attribute set to C{indexFilename}.
-
- @type template: A DOM Node or Document
- @param template: The output template which defines the presentation of the
- version information.
-
- @type indexFilename: C{str}
- @param indexFilename: The address of the index document to which to link.
- If any C{False} value, this function will remove all index-link nodes.
-
- @return: C{None}
- """
- indexLinks = domhelpers.findElementsWithAttribute(template,
- "class",
- "index-link")
- for link in indexLinks:
- if indexFilename is None:
- link.parentNode.removeChild(link)
- else:
- link.nodeName = link.tagName = link.endTagName = 'a'
- for attrName in link.attributes.keys():
- link.removeAttribute(attrName)
- link.setAttribute('href', indexFilename)
-
-
-
-def numberDocument(document, chapterNumber):
- """
- Number the sections of the given document.
-
- A dot-separated chapter, section number is added to the beginning of each
- section, as defined by C{h2} nodes.
-
- This is probably intended to interact in a rather specific way with
- L{getSectionNumber}.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @type chapterNumber: C{int}
- @param chapterNumber: The chapter number of this content in an overall
- document.
-
- @return: C{None}
- """
- i = 1
- for node in domhelpers.findNodesNamed(document, "h2"):
- label = dom.Text()
- label.data = "%s.%d " % (chapterNumber, i)
- node.insertBefore(label, node.firstChild)
- i += 1
-
-
-
-def fixRelativeLinks(document, linkrel):
- """
- Replace relative links in C{str} and C{href} attributes with links relative
- to C{linkrel}.
-
- @type document: A DOM Node or Document
- @param document: The output template.
-
- @type linkrel: C{str}
- @param linkrel: An prefix to apply to all relative links in C{src} or
- C{href} attributes in the input document when generating the output
- document.
- """
- for attr in 'src', 'href':
- for node in domhelpers.findElementsWithAttribute(document, attr):
- href = node.getAttribute(attr)
- if not href.startswith('http') and not href.startswith('/'):
- node.setAttribute(attr, linkrel+node.getAttribute(attr))
-
-
-
-def setTitle(template, title, chapterNumber):
- """
- Add title and chapter number information to the template document.
-
- The title is added to the end of the first C{title} tag and the end of the
- first tag with a C{class} attribute set to C{title}. If specified, the
- chapter is inserted before the title.
-
- @type template: A DOM Node or Document
- @param template: The output template which defines the presentation of the
- version information.
-
- @type title: C{list} of DOM Nodes
- @param title: Nodes from the input document defining its title.
-
- @type chapterNumber: C{int}
- @param chapterNumber: The chapter number of this content in an overall
- document. If not applicable, any C{False} value will result in this
- information being omitted.
-
- @return: C{None}
- """
- if numberer.getNumberSections() and chapterNumber:
- titleNode = dom.Text()
- # This is necessary in order for cloning below to work. See Python
- # isuse 4851.
- titleNode.ownerDocument = template.ownerDocument
- titleNode.data = '%s. ' % (chapterNumber,)
- title.insert(0, titleNode)
-
- for nodeList in (domhelpers.findNodesNamed(template, "title"),
- domhelpers.findElementsWithAttribute(template, "class",
- 'title')):
- if nodeList:
- for titleNode in title:
- nodeList[0].appendChild(titleNode.cloneNode(True))
-
-
-
-def setAuthors(template, authors):
- """
- Add author information to the template document.
-
- Names and contact information for authors are added to each node with a
- C{class} attribute set to C{authors} and to the template head as C{link}
- nodes.
-
- @type template: A DOM Node or Document
- @param template: The output template which defines the presentation of the
- version information.
-
- @type authors: C{list} of two-tuples of C{str}
- @param authors: List of names and contact information for the authors of
- the input document.
-
- @return: C{None}
- """
-
- for node in domhelpers.findElementsWithAttribute(template,
- "class", 'authors'):
-
- # First, similarly to setTitle, insert text into an <div
- # class="authors">
- container = dom.Element('span')
- for name, href in authors:
- anchor = dom.Element('a')
- anchor.setAttribute('href', href)
- anchorText = dom.Text()
- anchorText.data = name
- anchor.appendChild(anchorText)
- if (name, href) == authors[-1]:
- if len(authors) == 1:
- container.appendChild(anchor)
- else:
- andText = dom.Text()
- andText.data = 'and '
- container.appendChild(andText)
- container.appendChild(anchor)
- else:
- container.appendChild(anchor)
- commaText = dom.Text()
- commaText.data = ', '
- container.appendChild(commaText)
-
- node.appendChild(container)
-
- # Second, add appropriate <link rel="author" ...> tags to the <head>.
- head = domhelpers.findNodesNamed(template, 'head')[0]
- authors = [dom.parseString('<link rel="author" href="%s" title="%s"/>'
- % (href, name)).childNodes[0]
- for name, href in authors]
- head.childNodes.extend(authors)
-
-
-
-def setVersion(template, version):
- """
- Add a version indicator to the given template.
-
- @type template: A DOM Node or Document
- @param template: The output template which defines the presentation of the
- version information.
-
- @type version: C{str}
- @param version: The version string to add to the template.
-
- @return: C{None}
- """
- for node in domhelpers.findElementsWithAttribute(template, "class",
- "version"):
- text = dom.Text()
- text.data = version
- node.appendChild(text)
-
-
-
-def getOutputFileName(originalFileName, outputExtension, index=None):
- """
- Return a filename which is the same as C{originalFileName} except for the
- extension, which is replaced with C{outputExtension}.
-
- For example, if C{originalFileName} is C{'/foo/bar.baz'} and
- C{outputExtension} is C{'quux'}, the return value will be
- C{'/foo/bar.quux'}.
-
- @type originalFileName: C{str}
- @type outputExtension: C{stR}
- @param index: ignored, never passed.
- @rtype: C{str}
- """
- return os.path.splitext(originalFileName)[0]+outputExtension
-
-
-
-def munge(document, template, linkrel, dir, fullpath, ext, url, config, outfileGenerator=getOutputFileName):
- """
- Mutate C{template} until it resembles C{document}.
-
- @type document: A DOM Node or Document
- @param document: The input document which contains all of the content to be
- presented.
-
- @type template: A DOM Node or Document
- @param template: The template document which defines the desired
- presentation format of the content.
-
- @type linkrel: C{str}
- @param linkrel: An prefix to apply to all relative links in C{src} or
- C{href} attributes in the input document when generating the output
- document.
-
- @type dir: C{str}
- @param dir: The directory in which to search for source listing files.
-
- @type fullpath: C{str}
- @param fullpath: The file name which contained the input document.
-
- @type ext: C{str}
- @param ext: The extension to use when selecting an output file name. This
- replaces the extension of the input file name.
-
- @type url: C{str}
- @param url: A string which will be interpolated with the fully qualified
- Python name of any API reference encountered in the input document, the
- result of which will be used as a link to API documentation for that name
- in the output document.
-
- @type config: C{dict}
- @param config: Further specification of the desired form of the output.
- Valid keys in this dictionary::
-
- noapi: If present and set to a True value, links to API documentation
- will not be generated.
-
- version: A string which will be included in the output to indicate the
- version of this documentation.
-
- @type outfileGenerator: Callable of C{str}, C{str} returning C{str}
- @param outfileGenerator: Output filename factory. This is invoked with the
- intput filename and C{ext} and the output document is serialized to the
- file with the name returned.
-
- @return: C{None}
- """
- fixRelativeLinks(template, linkrel)
- addMtime(template, fullpath)
- removeH1(document)
- if not config.get('noapi', False):
- fixAPI(document, url)
- fontifyPython(document)
- fixLinks(document, ext)
- addPyListings(document, dir)
- addHTMLListings(document, dir)
- addPlainListings(document, dir)
- putInToC(template, generateToC(document))
- footnotes(document)
- notes(document)
-
- setIndexLink(template, indexer.getIndexFilename())
- setVersion(template, config.get('version', ''))
-
- # Insert the document into the template
- chapterNumber = htmlbook.getNumber(fullpath)
- title = domhelpers.findNodesNamed(document, 'title')[0].childNodes
- setTitle(template, title, chapterNumber)
- if numberer.getNumberSections() and chapterNumber:
- numberDocument(document, chapterNumber)
- index(document, outfileGenerator(os.path.split(fullpath)[1], ext),
- htmlbook.getReference(fullpath))
-
- authors = domhelpers.findNodesNamed(document, 'link')
- authors = [(node.getAttribute('title') or '',
- node.getAttribute('href') or '')
- for node in authors
- if node.getAttribute('rel') == 'author']
- setAuthors(template, authors)
-
- body = domhelpers.findNodesNamed(document, "body")[0]
- tmplbody = domhelpers.findElementsWithAttribute(template, "class",
- "body")[0]
- tmplbody.childNodes = body.childNodes
- tmplbody.setAttribute("class", "content")
-
-
-class _LocationReportingErrorHandler(ErrorHandler):
- """
- Define a SAX error handler which can report the location of fatal
- errors.
-
- Unlike the errors reported during parsing by other APIs in the xml
- package, this one tries to mismatched tag errors by including the
- location of both the relevant opening and closing tags.
- """
- def __init__(self, contentHandler):
- self.contentHandler = contentHandler
-
- def fatalError(self, err):
- # Unfortunately, the underlying expat error code is only exposed as
- # a string. I surely do hope no one ever goes and localizes expat.
- if err.getMessage() == 'mismatched tag':
- expect, begLine, begCol = self.contentHandler._locationStack[-1]
- endLine, endCol = err.getLineNumber(), err.getColumnNumber()
- raise process.ProcessingFailure(
- "mismatched close tag at line %d, column %d; expected </%s> "
- "(from line %d, column %d)" % (
- endLine, endCol, expect, begLine, begCol))
- raise process.ProcessingFailure(
- '%s at line %d, column %d' % (err.getMessage(),
- err.getLineNumber(),
- err.getColumnNumber()))
-
-
-class _TagTrackingContentHandler(SAX2DOM):
- """
- Define a SAX content handler which keeps track of the start location of
- all open tags. This information is used by the above defined error
- handler to report useful locations when a fatal error is encountered.
- """
- def __init__(self):
- SAX2DOM.__init__(self)
- self._locationStack = []
-
- def setDocumentLocator(self, locator):
- self._docLocator = locator
- SAX2DOM.setDocumentLocator(self, locator)
-
- def startElement(self, name, attrs):
- self._locationStack.append((name, self._docLocator.getLineNumber(), self._docLocator.getColumnNumber()))
- SAX2DOM.startElement(self, name, attrs)
-
- def endElement(self, name):
- self._locationStack.pop()
- SAX2DOM.endElement(self, name)
-
-
-class _LocalEntityResolver(object):
- """
- Implement DTD loading (from a local source) for the limited number of
- DTDs which are allowed for Lore input documents.
-
- @ivar filename: The name of the file containing the lore input
- document.
-
- @ivar knownDTDs: A mapping from DTD system identifiers to L{FilePath}
- instances pointing to the corresponding DTD.
- """
- s = FilePath(__file__).sibling
-
- knownDTDs = {
- None: s("xhtml1-strict.dtd"),
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd": s("xhtml1-strict.dtd"),
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd": s("xhtml1-transitional.dtd"),
- "xhtml-lat1.ent": s("xhtml-lat1.ent"),
- "xhtml-symbol.ent": s("xhtml-symbol.ent"),
- "xhtml-special.ent": s("xhtml-special.ent"),
- }
- del s
-
- def __init__(self, filename):
- self.filename = filename
-
-
- def resolveEntity(self, publicId, systemId):
- source = InputSource()
- source.setSystemId(systemId)
- try:
- dtdPath = self.knownDTDs[systemId]
- except KeyError:
- raise process.ProcessingFailure(
- "Invalid DTD system identifier (%r) in %s. Only "
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "
- "is allowed." % (systemId, self.filename))
- source.setByteStream(dtdPath.open())
- return source
-
-
-
-def parseFileAndReport(filename, _open=file):
- """
- Parse and return the contents of the given lore XHTML document.
-
- @type filename: C{str}
- @param filename: The name of a file containing a lore XHTML document to
- load.
-
- @raise process.ProcessingFailure: When the contents of the specified file
- cannot be parsed.
-
- @rtype: A DOM Document
- @return: The document contained in C{filename}.
- """
- content = _TagTrackingContentHandler()
- error = _LocationReportingErrorHandler(content)
- parser = make_parser()
- parser.setContentHandler(content)
- parser.setErrorHandler(error)
-
- # In order to call a method on the expat parser which will be used by this
- # parser, we need the expat parser to be created. This doesn't happen
- # until reset is called, normally by the parser's parse method. That's too
- # late for us, since it will then go on to parse the document without
- # letting us do any extra set up. So, force the expat parser to be created
- # here, and then disable reset so that the parser created is the one
- # actually used to parse our document. Resetting is only needed if more
- # than one document is going to be parsed, and that isn't the case here.
- parser.reset()
- parser.reset = lambda: None
-
- # This is necessary to make the xhtml1 transitional declaration optional.
- # It causes LocalEntityResolver.resolveEntity(None, None) to be called.
- # LocalEntityResolver handles that case by giving out the xhtml1
- # transitional dtd. Unfortunately, there is no public API for manipulating
- # the expat parser when using xml.sax. Using the private _parser attribute
- # may break. It's also possible that make_parser will return a parser
- # which doesn't use expat, but uses some other parser. Oh well. :(
- # -exarkun
- parser._parser.UseForeignDTD(True)
- parser.setEntityResolver(_LocalEntityResolver(filename))
-
- # This is probably no-op because expat is not a validating parser. Who
- # knows though, maybe you figured out a way to not use expat.
- parser.setFeature(feature_validation, False)
-
- fObj = _open(filename)
- try:
- try:
- parser.parse(fObj)
- except IOError, e:
- raise process.ProcessingFailure(
- e.strerror + ", filename was '" + filename + "'")
- finally:
- fObj.close()
- return content.document
-
-
-def makeSureDirectoryExists(filename):
- filename = os.path.abspath(filename)
- dirname = os.path.dirname(filename)
- if (not os.path.exists(dirname)):
- os.makedirs(dirname)
-
-def doFile(filename, linkrel, ext, url, templ, options={}, outfileGenerator=getOutputFileName):
- """
- Process the input document at C{filename} and write an output document.
-
- @type filename: C{str}
- @param filename: The path to the input file which will be processed.
-
- @type linkrel: C{str}
- @param linkrel: An prefix to apply to all relative links in C{src} or
- C{href} attributes in the input document when generating the output
- document.
-
- @type ext: C{str}
- @param ext: The extension to use when selecting an output file name. This
- replaces the extension of the input file name.
-
- @type url: C{str}
- @param url: A string which will be interpolated with the fully qualified
- Python name of any API reference encountered in the input document, the
- result of which will be used as a link to API documentation for that name
- in the output document.
-
- @type templ: A DOM Node or Document
- @param templ: The template on which the output document will be based.
- This is mutated and then serialized to the output file.
-
- @type options: C{dict}
- @param options: Further specification of the desired form of the output.
- Valid keys in this dictionary::
-
- noapi: If present and set to a True value, links to API documentation
- will not be generated.
-
- version: A string which will be included in the output to indicate the
- version of this documentation.
-
- @type outfileGenerator: Callable of C{str}, C{str} returning C{str}
- @param outfileGenerator: Output filename factory. This is invoked with the
- intput filename and C{ext} and the output document is serialized to the
- file with the name returned.
-
- @return: C{None}
- """
- doc = parseFileAndReport(filename)
- clonedNode = templ.cloneNode(1)
- munge(doc, clonedNode, linkrel, os.path.dirname(filename), filename, ext,
- url, options, outfileGenerator)
- newFilename = outfileGenerator(filename, ext)
- _writeDocument(newFilename, clonedNode)
-
-
-
-def _writeDocument(newFilename, clonedNode):
- """
- Serialize the given node to XML into the named file.
-
- @param newFilename: The name of the file to which the XML will be
- written. If this is in a directory which does not exist, the
- directory will be created.
-
- @param clonedNode: The root DOM node which will be serialized.
-
- @return: C{None}
- """
- makeSureDirectoryExists(newFilename)
- f = open(newFilename, 'w')
- f.write(clonedNode.toxml('utf-8'))
- f.close()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-lat1.ent b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-lat1.ent
deleted file mode 100644
index ffee223e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-lat1.ent
+++ /dev/null
@@ -1,196 +0,0 @@
-<!-- Portions (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
--->
-<!-- Character entity set. Typical invocation:
- <!ENTITY % HTMLlat1 PUBLIC
- "-//W3C//ENTITIES Latin 1 for XHTML//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
- %HTMLlat1;
--->
-
-<!ENTITY nbsp "&#160;"> <!-- no-break space = non-breaking space,
- U+00A0 ISOnum -->
-<!ENTITY iexcl "&#161;"> <!-- inverted exclamation mark, U+00A1 ISOnum -->
-<!ENTITY cent "&#162;"> <!-- cent sign, U+00A2 ISOnum -->
-<!ENTITY pound "&#163;"> <!-- pound sign, U+00A3 ISOnum -->
-<!ENTITY curren "&#164;"> <!-- currency sign, U+00A4 ISOnum -->
-<!ENTITY yen "&#165;"> <!-- yen sign = yuan sign, U+00A5 ISOnum -->
-<!ENTITY brvbar "&#166;"> <!-- broken bar = broken vertical bar,
- U+00A6 ISOnum -->
-<!ENTITY sect "&#167;"> <!-- section sign, U+00A7 ISOnum -->
-<!ENTITY uml "&#168;"> <!-- diaeresis = spacing diaeresis,
- U+00A8 ISOdia -->
-<!ENTITY copy "&#169;"> <!-- copyright sign, U+00A9 ISOnum -->
-<!ENTITY ordf "&#170;"> <!-- feminine ordinal indicator, U+00AA ISOnum -->
-<!ENTITY laquo "&#171;"> <!-- left-pointing double angle quotation mark
- = left pointing guillemet, U+00AB ISOnum -->
-<!ENTITY not "&#172;"> <!-- not sign = angled dash,
- U+00AC ISOnum -->
-<!ENTITY shy "&#173;"> <!-- soft hyphen = discretionary hyphen,
- U+00AD ISOnum -->
-<!ENTITY reg "&#174;"> <!-- registered sign = registered trade mark sign,
- U+00AE ISOnum -->
-<!ENTITY macr "&#175;"> <!-- macron = spacing macron = overline
- = APL overbar, U+00AF ISOdia -->
-<!ENTITY deg "&#176;"> <!-- degree sign, U+00B0 ISOnum -->
-<!ENTITY plusmn "&#177;"> <!-- plus-minus sign = plus-or-minus sign,
- U+00B1 ISOnum -->
-<!ENTITY sup2 "&#178;"> <!-- superscript two = superscript digit two
- = squared, U+00B2 ISOnum -->
-<!ENTITY sup3 "&#179;"> <!-- superscript three = superscript digit three
- = cubed, U+00B3 ISOnum -->
-<!ENTITY acute "&#180;"> <!-- acute accent = spacing acute,
- U+00B4 ISOdia -->
-<!ENTITY micro "&#181;"> <!-- micro sign, U+00B5 ISOnum -->
-<!ENTITY para "&#182;"> <!-- pilcrow sign = paragraph sign,
- U+00B6 ISOnum -->
-<!ENTITY middot "&#183;"> <!-- middle dot = Georgian comma
- = Greek middle dot, U+00B7 ISOnum -->
-<!ENTITY cedil "&#184;"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia -->
-<!ENTITY sup1 "&#185;"> <!-- superscript one = superscript digit one,
- U+00B9 ISOnum -->
-<!ENTITY ordm "&#186;"> <!-- masculine ordinal indicator,
- U+00BA ISOnum -->
-<!ENTITY raquo "&#187;"> <!-- right-pointing double angle quotation mark
- = right pointing guillemet, U+00BB ISOnum -->
-<!ENTITY frac14 "&#188;"> <!-- vulgar fraction one quarter
- = fraction one quarter, U+00BC ISOnum -->
-<!ENTITY frac12 "&#189;"> <!-- vulgar fraction one half
- = fraction one half, U+00BD ISOnum -->
-<!ENTITY frac34 "&#190;"> <!-- vulgar fraction three quarters
- = fraction three quarters, U+00BE ISOnum -->
-<!ENTITY iquest "&#191;"> <!-- inverted question mark
- = turned question mark, U+00BF ISOnum -->
-<!ENTITY Agrave "&#192;"> <!-- latin capital letter A with grave
- = latin capital letter A grave,
- U+00C0 ISOlat1 -->
-<!ENTITY Aacute "&#193;"> <!-- latin capital letter A with acute,
- U+00C1 ISOlat1 -->
-<!ENTITY Acirc "&#194;"> <!-- latin capital letter A with circumflex,
- U+00C2 ISOlat1 -->
-<!ENTITY Atilde "&#195;"> <!-- latin capital letter A with tilde,
- U+00C3 ISOlat1 -->
-<!ENTITY Auml "&#196;"> <!-- latin capital letter A with diaeresis,
- U+00C4 ISOlat1 -->
-<!ENTITY Aring "&#197;"> <!-- latin capital letter A with ring above
- = latin capital letter A ring,
- U+00C5 ISOlat1 -->
-<!ENTITY AElig "&#198;"> <!-- latin capital letter AE
- = latin capital ligature AE,
- U+00C6 ISOlat1 -->
-<!ENTITY Ccedil "&#199;"> <!-- latin capital letter C with cedilla,
- U+00C7 ISOlat1 -->
-<!ENTITY Egrave "&#200;"> <!-- latin capital letter E with grave,
- U+00C8 ISOlat1 -->
-<!ENTITY Eacute "&#201;"> <!-- latin capital letter E with acute,
- U+00C9 ISOlat1 -->
-<!ENTITY Ecirc "&#202;"> <!-- latin capital letter E with circumflex,
- U+00CA ISOlat1 -->
-<!ENTITY Euml "&#203;"> <!-- latin capital letter E with diaeresis,
- U+00CB ISOlat1 -->
-<!ENTITY Igrave "&#204;"> <!-- latin capital letter I with grave,
- U+00CC ISOlat1 -->
-<!ENTITY Iacute "&#205;"> <!-- latin capital letter I with acute,
- U+00CD ISOlat1 -->
-<!ENTITY Icirc "&#206;"> <!-- latin capital letter I with circumflex,
- U+00CE ISOlat1 -->
-<!ENTITY Iuml "&#207;"> <!-- latin capital letter I with diaeresis,
- U+00CF ISOlat1 -->
-<!ENTITY ETH "&#208;"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->
-<!ENTITY Ntilde "&#209;"> <!-- latin capital letter N with tilde,
- U+00D1 ISOlat1 -->
-<!ENTITY Ograve "&#210;"> <!-- latin capital letter O with grave,
- U+00D2 ISOlat1 -->
-<!ENTITY Oacute "&#211;"> <!-- latin capital letter O with acute,
- U+00D3 ISOlat1 -->
-<!ENTITY Ocirc "&#212;"> <!-- latin capital letter O with circumflex,
- U+00D4 ISOlat1 -->
-<!ENTITY Otilde "&#213;"> <!-- latin capital letter O with tilde,
- U+00D5 ISOlat1 -->
-<!ENTITY Ouml "&#214;"> <!-- latin capital letter O with diaeresis,
- U+00D6 ISOlat1 -->
-<!ENTITY times "&#215;"> <!-- multiplication sign, U+00D7 ISOnum -->
-<!ENTITY Oslash "&#216;"> <!-- latin capital letter O with stroke
- = latin capital letter O slash,
- U+00D8 ISOlat1 -->
-<!ENTITY Ugrave "&#217;"> <!-- latin capital letter U with grave,
- U+00D9 ISOlat1 -->
-<!ENTITY Uacute "&#218;"> <!-- latin capital letter U with acute,
- U+00DA ISOlat1 -->
-<!ENTITY Ucirc "&#219;"> <!-- latin capital letter U with circumflex,
- U+00DB ISOlat1 -->
-<!ENTITY Uuml "&#220;"> <!-- latin capital letter U with diaeresis,
- U+00DC ISOlat1 -->
-<!ENTITY Yacute "&#221;"> <!-- latin capital letter Y with acute,
- U+00DD ISOlat1 -->
-<!ENTITY THORN "&#222;"> <!-- latin capital letter THORN,
- U+00DE ISOlat1 -->
-<!ENTITY szlig "&#223;"> <!-- latin small letter sharp s = ess-zed,
- U+00DF ISOlat1 -->
-<!ENTITY agrave "&#224;"> <!-- latin small letter a with grave
- = latin small letter a grave,
- U+00E0 ISOlat1 -->
-<!ENTITY aacute "&#225;"> <!-- latin small letter a with acute,
- U+00E1 ISOlat1 -->
-<!ENTITY acirc "&#226;"> <!-- latin small letter a with circumflex,
- U+00E2 ISOlat1 -->
-<!ENTITY atilde "&#227;"> <!-- latin small letter a with tilde,
- U+00E3 ISOlat1 -->
-<!ENTITY auml "&#228;"> <!-- latin small letter a with diaeresis,
- U+00E4 ISOlat1 -->
-<!ENTITY aring "&#229;"> <!-- latin small letter a with ring above
- = latin small letter a ring,
- U+00E5 ISOlat1 -->
-<!ENTITY aelig "&#230;"> <!-- latin small letter ae
- = latin small ligature ae, U+00E6 ISOlat1 -->
-<!ENTITY ccedil "&#231;"> <!-- latin small letter c with cedilla,
- U+00E7 ISOlat1 -->
-<!ENTITY egrave "&#232;"> <!-- latin small letter e with grave,
- U+00E8 ISOlat1 -->
-<!ENTITY eacute "&#233;"> <!-- latin small letter e with acute,
- U+00E9 ISOlat1 -->
-<!ENTITY ecirc "&#234;"> <!-- latin small letter e with circumflex,
- U+00EA ISOlat1 -->
-<!ENTITY euml "&#235;"> <!-- latin small letter e with diaeresis,
- U+00EB ISOlat1 -->
-<!ENTITY igrave "&#236;"> <!-- latin small letter i with grave,
- U+00EC ISOlat1 -->
-<!ENTITY iacute "&#237;"> <!-- latin small letter i with acute,
- U+00ED ISOlat1 -->
-<!ENTITY icirc "&#238;"> <!-- latin small letter i with circumflex,
- U+00EE ISOlat1 -->
-<!ENTITY iuml "&#239;"> <!-- latin small letter i with diaeresis,
- U+00EF ISOlat1 -->
-<!ENTITY eth "&#240;"> <!-- latin small letter eth, U+00F0 ISOlat1 -->
-<!ENTITY ntilde "&#241;"> <!-- latin small letter n with tilde,
- U+00F1 ISOlat1 -->
-<!ENTITY ograve "&#242;"> <!-- latin small letter o with grave,
- U+00F2 ISOlat1 -->
-<!ENTITY oacute "&#243;"> <!-- latin small letter o with acute,
- U+00F3 ISOlat1 -->
-<!ENTITY ocirc "&#244;"> <!-- latin small letter o with circumflex,
- U+00F4 ISOlat1 -->
-<!ENTITY otilde "&#245;"> <!-- latin small letter o with tilde,
- U+00F5 ISOlat1 -->
-<!ENTITY ouml "&#246;"> <!-- latin small letter o with diaeresis,
- U+00F6 ISOlat1 -->
-<!ENTITY divide "&#247;"> <!-- division sign, U+00F7 ISOnum -->
-<!ENTITY oslash "&#248;"> <!-- latin small letter o with stroke,
- = latin small letter o slash,
- U+00F8 ISOlat1 -->
-<!ENTITY ugrave "&#249;"> <!-- latin small letter u with grave,
- U+00F9 ISOlat1 -->
-<!ENTITY uacute "&#250;"> <!-- latin small letter u with acute,
- U+00FA ISOlat1 -->
-<!ENTITY ucirc "&#251;"> <!-- latin small letter u with circumflex,
- U+00FB ISOlat1 -->
-<!ENTITY uuml "&#252;"> <!-- latin small letter u with diaeresis,
- U+00FC ISOlat1 -->
-<!ENTITY yacute "&#253;"> <!-- latin small letter y with acute,
- U+00FD ISOlat1 -->
-<!ENTITY thorn "&#254;"> <!-- latin small letter thorn,
- U+00FE ISOlat1 -->
-<!ENTITY yuml "&#255;"> <!-- latin small letter y with diaeresis,
- U+00FF ISOlat1 -->
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-special.ent b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-special.ent
deleted file mode 100644
index ca358b2f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-special.ent
+++ /dev/null
@@ -1,80 +0,0 @@
-<!-- Special characters for XHTML -->
-
-<!-- Character entity set. Typical invocation:
- <!ENTITY % HTMLspecial PUBLIC
- "-//W3C//ENTITIES Special for XHTML//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
- %HTMLspecial;
--->
-
-<!-- Portions (C) International Organization for Standardization 1986:
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
--->
-
-<!-- Relevant ISO entity set is given unless names are newly introduced.
- New names (i.e., not in ISO 8879 list) do not clash with any
- existing ISO 8879 entity names. ISO 10646 character numbers
- are given for each character, in hex. values are decimal
- conversions of the ISO 10646 values and refer to the document
- character set. Names are Unicode names.
--->
-
-<!-- C0 Controls and Basic Latin -->
-<!ENTITY quot "&#34;"> <!-- quotation mark, U+0022 ISOnum -->
-<!ENTITY amp "&#38;#38;"> <!-- ampersand, U+0026 ISOnum -->
-<!ENTITY lt "&#38;#60;"> <!-- less-than sign, U+003C ISOnum -->
-<!ENTITY gt "&#62;"> <!-- greater-than sign, U+003E ISOnum -->
-<!ENTITY apos "&#39;"> <!-- apostrophe = APL quote, U+0027 ISOnum -->
-
-<!-- Latin Extended-A -->
-<!ENTITY OElig "&#338;"> <!-- latin capital ligature OE,
- U+0152 ISOlat2 -->
-<!ENTITY oelig "&#339;"> <!-- latin small ligature oe, U+0153 ISOlat2 -->
-<!-- ligature is a misnomer, this is a separate character in some languages -->
-<!ENTITY Scaron "&#352;"> <!-- latin capital letter S with caron,
- U+0160 ISOlat2 -->
-<!ENTITY scaron "&#353;"> <!-- latin small letter s with caron,
- U+0161 ISOlat2 -->
-<!ENTITY Yuml "&#376;"> <!-- latin capital letter Y with diaeresis,
- U+0178 ISOlat2 -->
-
-<!-- Spacing Modifier Letters -->
-<!ENTITY circ "&#710;"> <!-- modifier letter circumflex accent,
- U+02C6 ISOpub -->
-<!ENTITY tilde "&#732;"> <!-- small tilde, U+02DC ISOdia -->
-
-<!-- General Punctuation -->
-<!ENTITY ensp "&#8194;"> <!-- en space, U+2002 ISOpub -->
-<!ENTITY emsp "&#8195;"> <!-- em space, U+2003 ISOpub -->
-<!ENTITY thinsp "&#8201;"> <!-- thin space, U+2009 ISOpub -->
-<!ENTITY zwnj "&#8204;"> <!-- zero width non-joiner,
- U+200C NEW RFC 2070 -->
-<!ENTITY zwj "&#8205;"> <!-- zero width joiner, U+200D NEW RFC 2070 -->
-<!ENTITY lrm "&#8206;"> <!-- left-to-right mark, U+200E NEW RFC 2070 -->
-<!ENTITY rlm "&#8207;"> <!-- right-to-left mark, U+200F NEW RFC 2070 -->
-<!ENTITY ndash "&#8211;"> <!-- en dash, U+2013 ISOpub -->
-<!ENTITY mdash "&#8212;"> <!-- em dash, U+2014 ISOpub -->
-<!ENTITY lsquo "&#8216;"> <!-- left single quotation mark,
- U+2018 ISOnum -->
-<!ENTITY rsquo "&#8217;"> <!-- right single quotation mark,
- U+2019 ISOnum -->
-<!ENTITY sbquo "&#8218;"> <!-- single low-9 quotation mark, U+201A NEW -->
-<!ENTITY ldquo "&#8220;"> <!-- left double quotation mark,
- U+201C ISOnum -->
-<!ENTITY rdquo "&#8221;"> <!-- right double quotation mark,
- U+201D ISOnum -->
-<!ENTITY bdquo "&#8222;"> <!-- double low-9 quotation mark, U+201E NEW -->
-<!ENTITY dagger "&#8224;"> <!-- dagger, U+2020 ISOpub -->
-<!ENTITY Dagger "&#8225;"> <!-- double dagger, U+2021 ISOpub -->
-<!ENTITY permil "&#8240;"> <!-- per mille sign, U+2030 ISOtech -->
-<!ENTITY lsaquo "&#8249;"> <!-- single left-pointing angle quotation mark,
- U+2039 ISO proposed -->
-<!-- lsaquo is proposed but not yet ISO standardized -->
-<!ENTITY rsaquo "&#8250;"> <!-- single right-pointing angle quotation mark,
- U+203A ISO proposed -->
-<!-- rsaquo is proposed but not yet ISO standardized -->
-
-<!-- Currency Symbols -->
-<!ENTITY euro "&#8364;"> <!-- euro sign, U+20AC NEW -->
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-symbol.ent b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-symbol.ent
deleted file mode 100644
index 63c2abfa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml-symbol.ent
+++ /dev/null
@@ -1,237 +0,0 @@
-<!-- Mathematical, Greek and Symbolic characters for XHTML -->
-
-<!-- Character entity set. Typical invocation:
- <!ENTITY % HTMLsymbol PUBLIC
- "-//W3C//ENTITIES Symbols for XHTML//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
- %HTMLsymbol;
--->
-
-<!-- Portions (C) International Organization for Standardization 1986:
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
--->
-
-<!-- Relevant ISO entity set is given unless names are newly introduced.
- New names (i.e., not in ISO 8879 list) do not clash with any
- existing ISO 8879 entity names. ISO 10646 character numbers
- are given for each character, in hex. values are decimal
- conversions of the ISO 10646 values and refer to the document
- character set. Names are Unicode names.
--->
-
-<!-- Latin Extended-B -->
-<!ENTITY fnof "&#402;"> <!-- latin small letter f with hook = function
- = florin, U+0192 ISOtech -->
-
-<!-- Greek -->
-<!ENTITY Alpha "&#913;"> <!-- greek capital letter alpha, U+0391 -->
-<!ENTITY Beta "&#914;"> <!-- greek capital letter beta, U+0392 -->
-<!ENTITY Gamma "&#915;"> <!-- greek capital letter gamma,
- U+0393 ISOgrk3 -->
-<!ENTITY Delta "&#916;"> <!-- greek capital letter delta,
- U+0394 ISOgrk3 -->
-<!ENTITY Epsilon "&#917;"> <!-- greek capital letter epsilon, U+0395 -->
-<!ENTITY Zeta "&#918;"> <!-- greek capital letter zeta, U+0396 -->
-<!ENTITY Eta "&#919;"> <!-- greek capital letter eta, U+0397 -->
-<!ENTITY Theta "&#920;"> <!-- greek capital letter theta,
- U+0398 ISOgrk3 -->
-<!ENTITY Iota "&#921;"> <!-- greek capital letter iota, U+0399 -->
-<!ENTITY Kappa "&#922;"> <!-- greek capital letter kappa, U+039A -->
-<!ENTITY Lambda "&#923;"> <!-- greek capital letter lamda,
- U+039B ISOgrk3 -->
-<!ENTITY Mu "&#924;"> <!-- greek capital letter mu, U+039C -->
-<!ENTITY Nu "&#925;"> <!-- greek capital letter nu, U+039D -->
-<!ENTITY Xi "&#926;"> <!-- greek capital letter xi, U+039E ISOgrk3 -->
-<!ENTITY Omicron "&#927;"> <!-- greek capital letter omicron, U+039F -->
-<!ENTITY Pi "&#928;"> <!-- greek capital letter pi, U+03A0 ISOgrk3 -->
-<!ENTITY Rho "&#929;"> <!-- greek capital letter rho, U+03A1 -->
-<!-- there is no Sigmaf, and no U+03A2 character either -->
-<!ENTITY Sigma "&#931;"> <!-- greek capital letter sigma,
- U+03A3 ISOgrk3 -->
-<!ENTITY Tau "&#932;"> <!-- greek capital letter tau, U+03A4 -->
-<!ENTITY Upsilon "&#933;"> <!-- greek capital letter upsilon,
- U+03A5 ISOgrk3 -->
-<!ENTITY Phi "&#934;"> <!-- greek capital letter phi,
- U+03A6 ISOgrk3 -->
-<!ENTITY Chi "&#935;"> <!-- greek capital letter chi, U+03A7 -->
-<!ENTITY Psi "&#936;"> <!-- greek capital letter psi,
- U+03A8 ISOgrk3 -->
-<!ENTITY Omega "&#937;"> <!-- greek capital letter omega,
- U+03A9 ISOgrk3 -->
-
-<!ENTITY alpha "&#945;"> <!-- greek small letter alpha,
- U+03B1 ISOgrk3 -->
-<!ENTITY beta "&#946;"> <!-- greek small letter beta, U+03B2 ISOgrk3 -->
-<!ENTITY gamma "&#947;"> <!-- greek small letter gamma,
- U+03B3 ISOgrk3 -->
-<!ENTITY delta "&#948;"> <!-- greek small letter delta,
- U+03B4 ISOgrk3 -->
-<!ENTITY epsilon "&#949;"> <!-- greek small letter epsilon,
- U+03B5 ISOgrk3 -->
-<!ENTITY zeta "&#950;"> <!-- greek small letter zeta, U+03B6 ISOgrk3 -->
-<!ENTITY eta "&#951;"> <!-- greek small letter eta, U+03B7 ISOgrk3 -->
-<!ENTITY theta "&#952;"> <!-- greek small letter theta,
- U+03B8 ISOgrk3 -->
-<!ENTITY iota "&#953;"> <!-- greek small letter iota, U+03B9 ISOgrk3 -->
-<!ENTITY kappa "&#954;"> <!-- greek small letter kappa,
- U+03BA ISOgrk3 -->
-<!ENTITY lambda "&#955;"> <!-- greek small letter lamda,
- U+03BB ISOgrk3 -->
-<!ENTITY mu "&#956;"> <!-- greek small letter mu, U+03BC ISOgrk3 -->
-<!ENTITY nu "&#957;"> <!-- greek small letter nu, U+03BD ISOgrk3 -->
-<!ENTITY xi "&#958;"> <!-- greek small letter xi, U+03BE ISOgrk3 -->
-<!ENTITY omicron "&#959;"> <!-- greek small letter omicron, U+03BF NEW -->
-<!ENTITY pi "&#960;"> <!-- greek small letter pi, U+03C0 ISOgrk3 -->
-<!ENTITY rho "&#961;"> <!-- greek small letter rho, U+03C1 ISOgrk3 -->
-<!ENTITY sigmaf "&#962;"> <!-- greek small letter final sigma,
- U+03C2 ISOgrk3 -->
-<!ENTITY sigma "&#963;"> <!-- greek small letter sigma,
- U+03C3 ISOgrk3 -->
-<!ENTITY tau "&#964;"> <!-- greek small letter tau, U+03C4 ISOgrk3 -->
-<!ENTITY upsilon "&#965;"> <!-- greek small letter upsilon,
- U+03C5 ISOgrk3 -->
-<!ENTITY phi "&#966;"> <!-- greek small letter phi, U+03C6 ISOgrk3 -->
-<!ENTITY chi "&#967;"> <!-- greek small letter chi, U+03C7 ISOgrk3 -->
-<!ENTITY psi "&#968;"> <!-- greek small letter psi, U+03C8 ISOgrk3 -->
-<!ENTITY omega "&#969;"> <!-- greek small letter omega,
- U+03C9 ISOgrk3 -->
-<!ENTITY thetasym "&#977;"> <!-- greek theta symbol,
- U+03D1 NEW -->
-<!ENTITY upsih "&#978;"> <!-- greek upsilon with hook symbol,
- U+03D2 NEW -->
-<!ENTITY piv "&#982;"> <!-- greek pi symbol, U+03D6 ISOgrk3 -->
-
-<!-- General Punctuation -->
-<!ENTITY bull "&#8226;"> <!-- bullet = black small circle,
- U+2022 ISOpub -->
-<!-- bullet is NOT the same as bullet operator, U+2219 -->
-<!ENTITY hellip "&#8230;"> <!-- horizontal ellipsis = three dot leader,
- U+2026 ISOpub -->
-<!ENTITY prime "&#8242;"> <!-- prime = minutes = feet, U+2032 ISOtech -->
-<!ENTITY Prime "&#8243;"> <!-- double prime = seconds = inches,
- U+2033 ISOtech -->
-<!ENTITY oline "&#8254;"> <!-- overline = spacing overscore,
- U+203E NEW -->
-<!ENTITY frasl "&#8260;"> <!-- fraction slash, U+2044 NEW -->
-
-<!-- Letterlike Symbols -->
-<!ENTITY weierp "&#8472;"> <!-- script capital P = power set
- = Weierstrass p, U+2118 ISOamso -->
-<!ENTITY image "&#8465;"> <!-- black-letter capital I = imaginary part,
- U+2111 ISOamso -->
-<!ENTITY real "&#8476;"> <!-- black-letter capital R = real part symbol,
- U+211C ISOamso -->
-<!ENTITY trade "&#8482;"> <!-- trade mark sign, U+2122 ISOnum -->
-<!ENTITY alefsym "&#8501;"> <!-- alef symbol = first transfinite cardinal,
- U+2135 NEW -->
-<!-- alef symbol is NOT the same as hebrew letter alef,
- U+05D0 although the same glyph could be used to depict both characters -->
-
-<!-- Arrows -->
-<!ENTITY larr "&#8592;"> <!-- leftwards arrow, U+2190 ISOnum -->
-<!ENTITY uarr "&#8593;"> <!-- upwards arrow, U+2191 ISOnum-->
-<!ENTITY rarr "&#8594;"> <!-- rightwards arrow, U+2192 ISOnum -->
-<!ENTITY darr "&#8595;"> <!-- downwards arrow, U+2193 ISOnum -->
-<!ENTITY harr "&#8596;"> <!-- left right arrow, U+2194 ISOamsa -->
-<!ENTITY crarr "&#8629;"> <!-- downwards arrow with corner leftwards
- = carriage return, U+21B5 NEW -->
-<!ENTITY lArr "&#8656;"> <!-- leftwards double arrow, U+21D0 ISOtech -->
-<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow
- but also does not have any other character for that function. So lArr can
- be used for 'is implied by' as ISOtech suggests -->
-<!ENTITY uArr "&#8657;"> <!-- upwards double arrow, U+21D1 ISOamsa -->
-<!ENTITY rArr "&#8658;"> <!-- rightwards double arrow,
- U+21D2 ISOtech -->
-<!-- Unicode does not say this is the 'implies' character but does not have
- another character with this function so rArr can be used for 'implies'
- as ISOtech suggests -->
-<!ENTITY dArr "&#8659;"> <!-- downwards double arrow, U+21D3 ISOamsa -->
-<!ENTITY hArr "&#8660;"> <!-- left right double arrow,
- U+21D4 ISOamsa -->
-
-<!-- Mathematical Operators -->
-<!ENTITY forall "&#8704;"> <!-- for all, U+2200 ISOtech -->
-<!ENTITY part "&#8706;"> <!-- partial differential, U+2202 ISOtech -->
-<!ENTITY exist "&#8707;"> <!-- there exists, U+2203 ISOtech -->
-<!ENTITY empty "&#8709;"> <!-- empty set = null set, U+2205 ISOamso -->
-<!ENTITY nabla "&#8711;"> <!-- nabla = backward difference,
- U+2207 ISOtech -->
-<!ENTITY isin "&#8712;"> <!-- element of, U+2208 ISOtech -->
-<!ENTITY notin "&#8713;"> <!-- not an element of, U+2209 ISOtech -->
-<!ENTITY ni "&#8715;"> <!-- contains as member, U+220B ISOtech -->
-<!ENTITY prod "&#8719;"> <!-- n-ary product = product sign,
- U+220F ISOamsb -->
-<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
- the same glyph might be used for both -->
-<!ENTITY sum "&#8721;"> <!-- n-ary summation, U+2211 ISOamsb -->
-<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
- though the same glyph might be used for both -->
-<!ENTITY minus "&#8722;"> <!-- minus sign, U+2212 ISOtech -->
-<!ENTITY lowast "&#8727;"> <!-- asterisk operator, U+2217 ISOtech -->
-<!ENTITY radic "&#8730;"> <!-- square root = radical sign,
- U+221A ISOtech -->
-<!ENTITY prop "&#8733;"> <!-- proportional to, U+221D ISOtech -->
-<!ENTITY infin "&#8734;"> <!-- infinity, U+221E ISOtech -->
-<!ENTITY ang "&#8736;"> <!-- angle, U+2220 ISOamso -->
-<!ENTITY and "&#8743;"> <!-- logical and = wedge, U+2227 ISOtech -->
-<!ENTITY or "&#8744;"> <!-- logical or = vee, U+2228 ISOtech -->
-<!ENTITY cap "&#8745;"> <!-- intersection = cap, U+2229 ISOtech -->
-<!ENTITY cup "&#8746;"> <!-- union = cup, U+222A ISOtech -->
-<!ENTITY int "&#8747;"> <!-- integral, U+222B ISOtech -->
-<!ENTITY there4 "&#8756;"> <!-- therefore, U+2234 ISOtech -->
-<!ENTITY sim "&#8764;"> <!-- tilde operator = varies with = similar to,
- U+223C ISOtech -->
-<!-- tilde operator is NOT the same character as the tilde, U+007E,
- although the same glyph might be used to represent both -->
-<!ENTITY cong "&#8773;"> <!-- approximately equal to, U+2245 ISOtech -->
-<!ENTITY asymp "&#8776;"> <!-- almost equal to = asymptotic to,
- U+2248 ISOamsr -->
-<!ENTITY ne "&#8800;"> <!-- not equal to, U+2260 ISOtech -->
-<!ENTITY equiv "&#8801;"> <!-- identical to, U+2261 ISOtech -->
-<!ENTITY le "&#8804;"> <!-- less-than or equal to, U+2264 ISOtech -->
-<!ENTITY ge "&#8805;"> <!-- greater-than or equal to,
- U+2265 ISOtech -->
-<!ENTITY sub "&#8834;"> <!-- subset of, U+2282 ISOtech -->
-<!ENTITY sup "&#8835;"> <!-- superset of, U+2283 ISOtech -->
-<!ENTITY nsub "&#8836;"> <!-- not a subset of, U+2284 ISOamsn -->
-<!ENTITY sube "&#8838;"> <!-- subset of or equal to, U+2286 ISOtech -->
-<!ENTITY supe "&#8839;"> <!-- superset of or equal to,
- U+2287 ISOtech -->
-<!ENTITY oplus "&#8853;"> <!-- circled plus = direct sum,
- U+2295 ISOamsb -->
-<!ENTITY otimes "&#8855;"> <!-- circled times = vector product,
- U+2297 ISOamsb -->
-<!ENTITY perp "&#8869;"> <!-- up tack = orthogonal to = perpendicular,
- U+22A5 ISOtech -->
-<!ENTITY sdot "&#8901;"> <!-- dot operator, U+22C5 ISOamsb -->
-<!-- dot operator is NOT the same character as U+00B7 middle dot -->
-
-<!-- Miscellaneous Technical -->
-<!ENTITY lceil "&#8968;"> <!-- left ceiling = APL upstile,
- U+2308 ISOamsc -->
-<!ENTITY rceil "&#8969;"> <!-- right ceiling, U+2309 ISOamsc -->
-<!ENTITY lfloor "&#8970;"> <!-- left floor = APL downstile,
- U+230A ISOamsc -->
-<!ENTITY rfloor "&#8971;"> <!-- right floor, U+230B ISOamsc -->
-<!ENTITY lang "&#9001;"> <!-- left-pointing angle bracket = bra,
- U+2329 ISOtech -->
-<!-- lang is NOT the same character as U+003C 'less than sign'
- or U+2039 'single left-pointing angle quotation mark' -->
-<!ENTITY rang "&#9002;"> <!-- right-pointing angle bracket = ket,
- U+232A ISOtech -->
-<!-- rang is NOT the same character as U+003E 'greater than sign'
- or U+203A 'single right-pointing angle quotation mark' -->
-
-<!-- Geometric Shapes -->
-<!ENTITY loz "&#9674;"> <!-- lozenge, U+25CA ISOpub -->
-
-<!-- Miscellaneous Symbols -->
-<!ENTITY spades "&#9824;"> <!-- black spade suit, U+2660 ISOpub -->
-<!-- black here seems to mean filled as opposed to hollow -->
-<!ENTITY clubs "&#9827;"> <!-- black club suit = shamrock,
- U+2663 ISOpub -->
-<!ENTITY hearts "&#9829;"> <!-- black heart suit = valentine,
- U+2665 ISOpub -->
-<!ENTITY diams "&#9830;"> <!-- black diamond suit, U+2666 ISOpub -->
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-strict.dtd b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-strict.dtd
deleted file mode 100644
index 2927b9ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-strict.dtd
+++ /dev/null
@@ -1,978 +0,0 @@
-<!--
- Extensible HTML version 1.0 Strict DTD
-
- This is the same as HTML 4 Strict except for
- changes due to the differences between XML and SGML.
-
- Namespace = http://www.w3.org/1999/xhtml
-
- For further information, see: http://www.w3.org/TR/xhtml1
-
- Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
- All Rights Reserved.
-
- This DTD module is identified by the PUBLIC and SYSTEM identifiers:
-
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
-
- $Revision: 1.1 $
- $Date: 2002/08/01 13:56:03 $
-
--->
-
-<!--================ Character mnemonic entities =========================-->
-
-<!ENTITY % HTMLlat1 PUBLIC
- "-//W3C//ENTITIES Latin 1 for XHTML//EN"
- "xhtml-lat1.ent">
-%HTMLlat1;
-
-<!ENTITY % HTMLsymbol PUBLIC
- "-//W3C//ENTITIES Symbols for XHTML//EN"
- "xhtml-symbol.ent">
-%HTMLsymbol;
-
-<!ENTITY % HTMLspecial PUBLIC
- "-//W3C//ENTITIES Special for XHTML//EN"
- "xhtml-special.ent">
-%HTMLspecial;
-
-<!--================== Imported Names ====================================-->
-
-<!ENTITY % ContentType "CDATA">
- <!-- media type, as per [RFC2045] -->
-
-<!ENTITY % ContentTypes "CDATA">
- <!-- comma-separated list of media types, as per [RFC2045] -->
-
-<!ENTITY % Charset "CDATA">
- <!-- a character encoding, as per [RFC2045] -->
-
-<!ENTITY % Charsets "CDATA">
- <!-- a space separated list of character encodings, as per [RFC2045] -->
-
-<!ENTITY % LanguageCode "NMTOKEN">
- <!-- a language code, as per [RFC3066] -->
-
-<!ENTITY % Character "CDATA">
- <!-- a single character, as per section 2.2 of [XML] -->
-
-<!ENTITY % Number "CDATA">
- <!-- one or more digits -->
-
-<!ENTITY % LinkTypes "CDATA">
- <!-- space-separated list of link types -->
-
-<!ENTITY % MediaDesc "CDATA">
- <!-- single or comma-separated list of media descriptors -->
-
-<!ENTITY % URI "CDATA">
- <!-- a Uniform Resource Identifier, see [RFC2396] -->
-
-<!ENTITY % UriList "CDATA">
- <!-- a space separated list of Uniform Resource Identifiers -->
-
-<!ENTITY % Datetime "CDATA">
- <!-- date and time information. ISO date format -->
-
-<!ENTITY % Script "CDATA">
- <!-- script expression -->
-
-<!ENTITY % StyleSheet "CDATA">
- <!-- style sheet data -->
-
-<!ENTITY % Text "CDATA">
- <!-- used for titles etc. -->
-
-<!ENTITY % Length "CDATA">
- <!-- nn for pixels or nn% for percentage length -->
-
-<!ENTITY % MultiLength "CDATA">
- <!-- pixel, percentage, or relative -->
-
-<!ENTITY % Pixels "CDATA">
- <!-- integer representing length in pixels -->
-
-<!-- these are used for image maps -->
-
-<!ENTITY % Shape "(rect|circle|poly|default)">
-
-<!ENTITY % Coords "CDATA">
- <!-- comma separated list of lengths -->
-
-<!--=================== Generic Attributes ===============================-->
-
-<!-- core attributes common to most elements
- id document-wide unique id
- class space separated list of classes
- style associated style info
- title advisory title/amplification
--->
-<!ENTITY % coreattrs
- "id ID #IMPLIED
- class CDATA #IMPLIED
- style %StyleSheet; #IMPLIED
- title %Text; #IMPLIED"
- >
-
-<!-- internationalization attributes
- lang language code (backwards compatible)
- xml:lang language code (as per XML 1.0 spec)
- dir direction for weak/neutral text
--->
-<!ENTITY % i18n
- "lang %LanguageCode; #IMPLIED
- xml:lang %LanguageCode; #IMPLIED
- dir (ltr|rtl) #IMPLIED"
- >
-
-<!-- attributes for common UI events
- onclick a pointer button was clicked
- ondblclick a pointer button was double clicked
- onmousedown a pointer button was pressed down
- onmouseup a pointer button was released
- onmousemove a pointer was moved onto the element
- onmouseout a pointer was moved away from the element
- onkeypress a key was pressed and released
- onkeydown a key was pressed down
- onkeyup a key was released
--->
-<!ENTITY % events
- "onclick %Script; #IMPLIED
- ondblclick %Script; #IMPLIED
- onmousedown %Script; #IMPLIED
- onmouseup %Script; #IMPLIED
- onmouseover %Script; #IMPLIED
- onmousemove %Script; #IMPLIED
- onmouseout %Script; #IMPLIED
- onkeypress %Script; #IMPLIED
- onkeydown %Script; #IMPLIED
- onkeyup %Script; #IMPLIED"
- >
-
-<!-- attributes for elements that can get the focus
- accesskey accessibility key character
- tabindex position in tabbing order
- onfocus the element got the focus
- onblur the element lost the focus
--->
-<!ENTITY % focus
- "accesskey %Character; #IMPLIED
- tabindex %Number; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED"
- >
-
-<!ENTITY % attrs "%coreattrs; %i18n; %events;">
-
-<!--=================== Text Elements ====================================-->
-
-<!ENTITY % special.pre
- "br | span | bdo | map">
-
-
-<!ENTITY % special
- "%special.pre; | object | img ">
-
-<!ENTITY % fontstyle "tt | i | b | big | small ">
-
-<!ENTITY % phrase "em | strong | dfn | code | q |
- samp | kbd | var | cite | abbr | acronym | sub | sup ">
-
-<!ENTITY % inline.forms "input | select | textarea | label | button">
-
-<!-- these can occur at block or inline level -->
-<!ENTITY % misc.inline "ins | del | script">
-
-<!-- these can only occur at block level -->
-<!ENTITY % misc "noscript | %misc.inline;">
-
-<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
-
-<!-- %Inline; covers inline or "text-level" elements -->
-<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
-
-<!--================== Block level elements ==============================-->
-
-<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
-<!ENTITY % lists "ul | ol | dl">
-<!ENTITY % blocktext "pre | hr | blockquote | address">
-
-<!ENTITY % block
- "p | %heading; | div | %lists; | %blocktext; | fieldset | table">
-
-<!ENTITY % Block "(%block; | form | %misc;)*">
-
-<!-- %Flow; mixes block and inline and is used for list items etc. -->
-<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
-
-<!--================== Content models for exclusions =====================-->
-
-<!-- a elements use %Inline; excluding a -->
-
-<!ENTITY % a.content
- "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
-
-<!-- pre uses %Inline excluding big, small, sup or sup -->
-
-<!ENTITY % pre.content
- "(#PCDATA | a | %fontstyle; | %phrase; | %special.pre; | %misc.inline;
- | %inline.forms;)*">
-
-<!-- form uses %Block; excluding form -->
-
-<!ENTITY % form.content "(%block; | %misc;)*">
-
-<!-- button uses %Flow; but excludes a, form and form controls -->
-
-<!ENTITY % button.content
- "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
- table | %special; | %fontstyle; | %phrase; | %misc;)*">
-
-<!--================ Document Structure ==================================-->
-
-<!-- the namespace URI designates the document profile -->
-
-<!ELEMENT html (head, body)>
-<!ATTLIST html
- %i18n;
- id ID #IMPLIED
- xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml'
- >
-
-<!--================ Document Head =======================================-->
-
-<!ENTITY % head.misc "(script|style|meta|link|object)*">
-
-<!-- content model is %head.misc; combined with a single
- title and an optional base element in any order -->
-
-<!ELEMENT head (%head.misc;,
- ((title, %head.misc;, (base, %head.misc;)?) |
- (base, %head.misc;, (title, %head.misc;))))>
-
-<!ATTLIST head
- %i18n;
- id ID #IMPLIED
- profile %URI; #IMPLIED
- >
-
-<!-- The title element is not considered part of the flow of text.
- It should be displayed, for example as the page header or
- window title. Exactly one title is required per document.
- -->
-<!ELEMENT title (#PCDATA)>
-<!ATTLIST title
- %i18n;
- id ID #IMPLIED
- >
-
-<!-- document base URI -->
-
-<!ELEMENT base EMPTY>
-<!ATTLIST base
- href %URI; #REQUIRED
- id ID #IMPLIED
- >
-
-<!-- generic metainformation -->
-<!ELEMENT meta EMPTY>
-<!ATTLIST meta
- %i18n;
- id ID #IMPLIED
- http-equiv CDATA #IMPLIED
- name CDATA #IMPLIED
- content CDATA #REQUIRED
- scheme CDATA #IMPLIED
- >
-
-<!--
- Relationship values can be used in principle:
-
- a) for document specific toolbars/menus when used
- with the link element in document head e.g.
- start, contents, previous, next, index, end, help
- b) to link to a separate style sheet (rel="stylesheet")
- c) to make a link to a script (rel="script")
- d) by stylesheets to control how collections of
- html nodes are rendered into printed documents
- e) to make a link to a printable version of this document
- e.g. a PostScript or PDF version (rel="alternate" media="print")
--->
-
-<!ELEMENT link EMPTY>
-<!ATTLIST link
- %attrs;
- charset %Charset; #IMPLIED
- href %URI; #IMPLIED
- hreflang %LanguageCode; #IMPLIED
- type %ContentType; #IMPLIED
- rel %LinkTypes; #IMPLIED
- rev %LinkTypes; #IMPLIED
- media %MediaDesc; #IMPLIED
- >
-
-<!-- style info, which may include CDATA sections -->
-<!ELEMENT style (#PCDATA)>
-<!ATTLIST style
- %i18n;
- id ID #IMPLIED
- type %ContentType; #REQUIRED
- media %MediaDesc; #IMPLIED
- title %Text; #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!-- script statements, which may include CDATA sections -->
-<!ELEMENT script (#PCDATA)>
-<!ATTLIST script
- id ID #IMPLIED
- charset %Charset; #IMPLIED
- type %ContentType; #REQUIRED
- src %URI; #IMPLIED
- defer (defer) #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!-- alternate content container for non script-based rendering -->
-
-<!ELEMENT noscript %Block;>
-<!ATTLIST noscript
- %attrs;
- >
-
-<!--=================== Document Body ====================================-->
-
-<!ELEMENT body %Block;>
-<!ATTLIST body
- %attrs;
- onload %Script; #IMPLIED
- onunload %Script; #IMPLIED
- >
-
-<!ELEMENT div %Flow;> <!-- generic language/style container -->
-<!ATTLIST div
- %attrs;
- >
-
-<!--=================== Paragraphs =======================================-->
-
-<!ELEMENT p %Inline;>
-<!ATTLIST p
- %attrs;
- >
-
-<!--=================== Headings =========================================-->
-
-<!--
- There are six levels of headings from h1 (the most important)
- to h6 (the least important).
--->
-
-<!ELEMENT h1 %Inline;>
-<!ATTLIST h1
- %attrs;
- >
-
-<!ELEMENT h2 %Inline;>
-<!ATTLIST h2
- %attrs;
- >
-
-<!ELEMENT h3 %Inline;>
-<!ATTLIST h3
- %attrs;
- >
-
-<!ELEMENT h4 %Inline;>
-<!ATTLIST h4
- %attrs;
- >
-
-<!ELEMENT h5 %Inline;>
-<!ATTLIST h5
- %attrs;
- >
-
-<!ELEMENT h6 %Inline;>
-<!ATTLIST h6
- %attrs;
- >
-
-<!--=================== Lists ============================================-->
-
-<!-- Unordered list -->
-
-<!ELEMENT ul (li)+>
-<!ATTLIST ul
- %attrs;
- >
-
-<!-- Ordered (numbered) list -->
-
-<!ELEMENT ol (li)+>
-<!ATTLIST ol
- %attrs;
- >
-
-<!-- list item -->
-
-<!ELEMENT li %Flow;>
-<!ATTLIST li
- %attrs;
- >
-
-<!-- definition lists - dt for term, dd for its definition -->
-
-<!ELEMENT dl (dt|dd)+>
-<!ATTLIST dl
- %attrs;
- >
-
-<!ELEMENT dt %Inline;>
-<!ATTLIST dt
- %attrs;
- >
-
-<!ELEMENT dd %Flow;>
-<!ATTLIST dd
- %attrs;
- >
-
-<!--=================== Address ==========================================-->
-
-<!-- information on author -->
-
-<!ELEMENT address %Inline;>
-<!ATTLIST address
- %attrs;
- >
-
-<!--=================== Horizontal Rule ==================================-->
-
-<!ELEMENT hr EMPTY>
-<!ATTLIST hr
- %attrs;
- >
-
-<!--=================== Preformatted Text ================================-->
-
-<!-- content is %Inline; excluding "img|object|big|small|sub|sup" -->
-
-<!ELEMENT pre %pre.content;>
-<!ATTLIST pre
- %attrs;
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!--=================== Block-like Quotes ================================-->
-
-<!ELEMENT blockquote %Block;>
-<!ATTLIST blockquote
- %attrs;
- cite %URI; #IMPLIED
- >
-
-<!--=================== Inserted/Deleted Text ============================-->
-
-<!--
- ins/del are allowed in block and inline content, but its
- inappropriate to include block content within an ins element
- occurring in inline content.
--->
-<!ELEMENT ins %Flow;>
-<!ATTLIST ins
- %attrs;
- cite %URI; #IMPLIED
- datetime %Datetime; #IMPLIED
- >
-
-<!ELEMENT del %Flow;>
-<!ATTLIST del
- %attrs;
- cite %URI; #IMPLIED
- datetime %Datetime; #IMPLIED
- >
-
-<!--================== The Anchor Element ================================-->
-
-<!-- content is %Inline; except that anchors shouldn't be nested -->
-
-<!ELEMENT a %a.content;>
-<!ATTLIST a
- %attrs;
- %focus;
- charset %Charset; #IMPLIED
- type %ContentType; #IMPLIED
- name NMTOKEN #IMPLIED
- href %URI; #IMPLIED
- hreflang %LanguageCode; #IMPLIED
- rel %LinkTypes; #IMPLIED
- rev %LinkTypes; #IMPLIED
- shape %Shape; "rect"
- coords %Coords; #IMPLIED
- >
-
-<!--===================== Inline Elements ================================-->
-
-<!ELEMENT span %Inline;> <!-- generic language/style container -->
-<!ATTLIST span
- %attrs;
- >
-
-<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride -->
-<!ATTLIST bdo
- %coreattrs;
- %events;
- lang %LanguageCode; #IMPLIED
- xml:lang %LanguageCode; #IMPLIED
- dir (ltr|rtl) #REQUIRED
- >
-
-<!ELEMENT br EMPTY> <!-- forced line break -->
-<!ATTLIST br
- %coreattrs;
- >
-
-<!ELEMENT em %Inline;> <!-- emphasis -->
-<!ATTLIST em %attrs;>
-
-<!ELEMENT strong %Inline;> <!-- strong emphasis -->
-<!ATTLIST strong %attrs;>
-
-<!ELEMENT dfn %Inline;> <!-- definitional -->
-<!ATTLIST dfn %attrs;>
-
-<!ELEMENT code %Inline;> <!-- program code -->
-<!ATTLIST code %attrs;>
-
-<!ELEMENT samp %Inline;> <!-- sample -->
-<!ATTLIST samp %attrs;>
-
-<!ELEMENT kbd %Inline;> <!-- something user would type -->
-<!ATTLIST kbd %attrs;>
-
-<!ELEMENT var %Inline;> <!-- variable -->
-<!ATTLIST var %attrs;>
-
-<!ELEMENT cite %Inline;> <!-- citation -->
-<!ATTLIST cite %attrs;>
-
-<!ELEMENT abbr %Inline;> <!-- abbreviation -->
-<!ATTLIST abbr %attrs;>
-
-<!ELEMENT acronym %Inline;> <!-- acronym -->
-<!ATTLIST acronym %attrs;>
-
-<!ELEMENT q %Inline;> <!-- inlined quote -->
-<!ATTLIST q
- %attrs;
- cite %URI; #IMPLIED
- >
-
-<!ELEMENT sub %Inline;> <!-- subscript -->
-<!ATTLIST sub %attrs;>
-
-<!ELEMENT sup %Inline;> <!-- superscript -->
-<!ATTLIST sup %attrs;>
-
-<!ELEMENT tt %Inline;> <!-- fixed pitch font -->
-<!ATTLIST tt %attrs;>
-
-<!ELEMENT i %Inline;> <!-- italic font -->
-<!ATTLIST i %attrs;>
-
-<!ELEMENT b %Inline;> <!-- bold font -->
-<!ATTLIST b %attrs;>
-
-<!ELEMENT big %Inline;> <!-- bigger font -->
-<!ATTLIST big %attrs;>
-
-<!ELEMENT small %Inline;> <!-- smaller font -->
-<!ATTLIST small %attrs;>
-
-<!--==================== Object ======================================-->
-<!--
- object is used to embed objects as part of HTML pages.
- param elements should precede other content. Parameters
- can also be expressed as attribute/value pairs on the
- object element itself when brevity is desired.
--->
-
-<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
-<!ATTLIST object
- %attrs;
- declare (declare) #IMPLIED
- classid %URI; #IMPLIED
- codebase %URI; #IMPLIED
- data %URI; #IMPLIED
- type %ContentType; #IMPLIED
- codetype %ContentType; #IMPLIED
- archive %UriList; #IMPLIED
- standby %Text; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- usemap %URI; #IMPLIED
- name NMTOKEN #IMPLIED
- tabindex %Number; #IMPLIED
- >
-
-<!--
- param is used to supply a named property value.
- In XML it would seem natural to follow RDF and support an
- abbreviated syntax where the param elements are replaced
- by attribute value pairs on the object start tag.
--->
-<!ELEMENT param EMPTY>
-<!ATTLIST param
- id ID #IMPLIED
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- valuetype (data|ref|object) "data"
- type %ContentType; #IMPLIED
- >
-
-<!--=================== Images ===========================================-->
-
-<!--
- To avoid accessibility problems for people who aren't
- able to see the image, you should provide a text
- description using the alt and longdesc attributes.
- In addition, avoid the use of server-side image maps.
- Note that in this DTD there is no name attribute. That
- is only available in the transitional and frameset DTD.
--->
-
-<!ELEMENT img EMPTY>
-<!ATTLIST img
- %attrs;
- src %URI; #REQUIRED
- alt %Text; #REQUIRED
- longdesc %URI; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- usemap %URI; #IMPLIED
- ismap (ismap) #IMPLIED
- >
-
-<!-- usemap points to a map element which may be in this document
- or an external document, although the latter is not widely supported -->
-
-<!--================== Client-side image maps ============================-->
-
-<!-- These can be placed in the same document or grouped in a
- separate document although this isn't yet widely supported -->
-
-<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
-<!ATTLIST map
- %i18n;
- %events;
- id ID #REQUIRED
- class CDATA #IMPLIED
- style %StyleSheet; #IMPLIED
- title %Text; #IMPLIED
- name NMTOKEN #IMPLIED
- >
-
-<!ELEMENT area EMPTY>
-<!ATTLIST area
- %attrs;
- %focus;
- shape %Shape; "rect"
- coords %Coords; #IMPLIED
- href %URI; #IMPLIED
- nohref (nohref) #IMPLIED
- alt %Text; #REQUIRED
- >
-
-<!--================ Forms ===============================================-->
-<!ELEMENT form %form.content;> <!-- forms shouldn't be nested -->
-
-<!ATTLIST form
- %attrs;
- action %URI; #REQUIRED
- method (get|post) "get"
- enctype %ContentType; "application/x-www-form-urlencoded"
- onsubmit %Script; #IMPLIED
- onreset %Script; #IMPLIED
- accept %ContentTypes; #IMPLIED
- accept-charset %Charsets; #IMPLIED
- >
-
-<!--
- Each label must not contain more than ONE field
- Label elements shouldn't be nested.
--->
-<!ELEMENT label %Inline;>
-<!ATTLIST label
- %attrs;
- for IDREF #IMPLIED
- accesskey %Character; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED
- >
-
-<!ENTITY % InputType
- "(text | password | checkbox |
- radio | submit | reset |
- file | hidden | image | button)"
- >
-
-<!-- the name attribute is required for all but submit & reset -->
-
-<!ELEMENT input EMPTY> <!-- form control -->
-<!ATTLIST input
- %attrs;
- %focus;
- type %InputType; "text"
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- checked (checked) #IMPLIED
- disabled (disabled) #IMPLIED
- readonly (readonly) #IMPLIED
- size CDATA #IMPLIED
- maxlength %Number; #IMPLIED
- src %URI; #IMPLIED
- alt CDATA #IMPLIED
- usemap %URI; #IMPLIED
- onselect %Script; #IMPLIED
- onchange %Script; #IMPLIED
- accept %ContentTypes; #IMPLIED
- >
-
-<!ELEMENT select (optgroup|option)+> <!-- option selector -->
-<!ATTLIST select
- %attrs;
- name CDATA #IMPLIED
- size %Number; #IMPLIED
- multiple (multiple) #IMPLIED
- disabled (disabled) #IMPLIED
- tabindex %Number; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED
- onchange %Script; #IMPLIED
- >
-
-<!ELEMENT optgroup (option)+> <!-- option group -->
-<!ATTLIST optgroup
- %attrs;
- disabled (disabled) #IMPLIED
- label %Text; #REQUIRED
- >
-
-<!ELEMENT option (#PCDATA)> <!-- selectable choice -->
-<!ATTLIST option
- %attrs;
- selected (selected) #IMPLIED
- disabled (disabled) #IMPLIED
- label %Text; #IMPLIED
- value CDATA #IMPLIED
- >
-
-<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field -->
-<!ATTLIST textarea
- %attrs;
- %focus;
- name CDATA #IMPLIED
- rows %Number; #REQUIRED
- cols %Number; #REQUIRED
- disabled (disabled) #IMPLIED
- readonly (readonly) #IMPLIED
- onselect %Script; #IMPLIED
- onchange %Script; #IMPLIED
- >
-
-<!--
- The fieldset element is used to group form fields.
- Only one legend element should occur in the content
- and if present should only be preceded by whitespace.
--->
-<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
-<!ATTLIST fieldset
- %attrs;
- >
-
-<!ELEMENT legend %Inline;> <!-- fieldset label -->
-<!ATTLIST legend
- %attrs;
- accesskey %Character; #IMPLIED
- >
-
-<!--
- Content is %Flow; excluding a, form and form controls
--->
-<!ELEMENT button %button.content;> <!-- push button -->
-<!ATTLIST button
- %attrs;
- %focus;
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- type (button|submit|reset) "submit"
- disabled (disabled) #IMPLIED
- >
-
-<!--======================= Tables =======================================-->
-
-<!-- Derived from IETF HTML table standard, see [RFC1942] -->
-
-<!--
- The border attribute sets the thickness of the frame around the
- table. The default units are screen pixels.
-
- The frame attribute specifies which parts of the frame around
- the table should be rendered. The values are not the same as
- CALS to avoid a name clash with the valign attribute.
--->
-<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
-
-<!--
- The rules attribute defines which rules to draw between cells:
-
- If rules is absent then assume:
- "none" if border is absent or border="0" otherwise "all"
--->
-
-<!ENTITY % TRules "(none | groups | rows | cols | all)">
-
-<!-- horizontal alignment attributes for cell contents
-
- char alignment char, e.g. char=':'
- charoff offset for alignment char
--->
-<!ENTITY % cellhalign
- "align (left|center|right|justify|char) #IMPLIED
- char %Character; #IMPLIED
- charoff %Length; #IMPLIED"
- >
-
-<!-- vertical alignment attributes for cell contents -->
-<!ENTITY % cellvalign
- "valign (top|middle|bottom|baseline) #IMPLIED"
- >
-
-<!ELEMENT table
- (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
-<!ELEMENT caption %Inline;>
-<!ELEMENT thead (tr)+>
-<!ELEMENT tfoot (tr)+>
-<!ELEMENT tbody (tr)+>
-<!ELEMENT colgroup (col)*>
-<!ELEMENT col EMPTY>
-<!ELEMENT tr (th|td)+>
-<!ELEMENT th %Flow;>
-<!ELEMENT td %Flow;>
-
-<!ATTLIST table
- %attrs;
- summary %Text; #IMPLIED
- width %Length; #IMPLIED
- border %Pixels; #IMPLIED
- frame %TFrame; #IMPLIED
- rules %TRules; #IMPLIED
- cellspacing %Length; #IMPLIED
- cellpadding %Length; #IMPLIED
- >
-
-<!ATTLIST caption
- %attrs;
- >
-
-<!--
-colgroup groups a set of col elements. It allows you to group
-several semantically related columns together.
--->
-<!ATTLIST colgroup
- %attrs;
- span %Number; "1"
- width %MultiLength; #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!--
- col elements define the alignment properties for cells in
- one or more columns.
-
- The width attribute specifies the width of the columns, e.g.
-
- width=64 width in screen pixels
- width=0.5* relative width of 0.5
-
- The span attribute causes the attributes of one
- col element to apply to more than one column.
--->
-<!ATTLIST col
- %attrs;
- span %Number; "1"
- width %MultiLength; #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!--
- Use thead to duplicate headers when breaking table
- across page boundaries, or for static headers when
- tbody sections are rendered in scrolling panel.
-
- Use tfoot to duplicate footers when breaking table
- across page boundaries, or for static footers when
- tbody sections are rendered in scrolling panel.
-
- Use multiple tbody sections when rules are needed
- between groups of table rows.
--->
-<!ATTLIST thead
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tfoot
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tbody
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tr
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-
-<!-- Scope is simpler than headers attribute for common tables -->
-<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
-
-<!-- th is for headers, td for data and for cells acting as both -->
-
-<!ATTLIST th
- %attrs;
- abbr %Text; #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope %Scope; #IMPLIED
- rowspan %Number; "1"
- colspan %Number; "1"
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST td
- %attrs;
- abbr %Text; #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope %Scope; #IMPLIED
- rowspan %Number; "1"
- colspan %Number; "1"
- %cellhalign;
- %cellvalign;
- >
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-transitional.dtd b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-transitional.dtd
deleted file mode 100644
index 628f27ac..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/lore/xhtml1-transitional.dtd
+++ /dev/null
@@ -1,1201 +0,0 @@
-<!--
- Extensible HTML version 1.0 Transitional DTD
-
- This is the same as HTML 4 Transitional except for
- changes due to the differences between XML and SGML.
-
- Namespace = http://www.w3.org/1999/xhtml
-
- For further information, see: http://www.w3.org/TR/xhtml1
-
- Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
- All Rights Reserved.
-
- This DTD module is identified by the PUBLIC and SYSTEM identifiers:
-
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
-
- $Revision: 1.2 $
- $Date: 2002/08/01 18:37:55 $
-
--->
-
-<!--================ Character mnemonic entities =========================-->
-
-<!ENTITY % HTMLlat1 PUBLIC
- "-//W3C//ENTITIES Latin 1 for XHTML//EN"
- "xhtml-lat1.ent">
-%HTMLlat1;
-
-<!ENTITY % HTMLsymbol PUBLIC
- "-//W3C//ENTITIES Symbols for XHTML//EN"
- "xhtml-symbol.ent">
-%HTMLsymbol;
-
-<!ENTITY % HTMLspecial PUBLIC
- "-//W3C//ENTITIES Special for XHTML//EN"
- "xhtml-special.ent">
-%HTMLspecial;
-
-<!--================== Imported Names ====================================-->
-
-<!ENTITY % ContentType "CDATA">
- <!-- media type, as per [RFC2045] -->
-
-<!ENTITY % ContentTypes "CDATA">
- <!-- comma-separated list of media types, as per [RFC2045] -->
-
-<!ENTITY % Charset "CDATA">
- <!-- a character encoding, as per [RFC2045] -->
-
-<!ENTITY % Charsets "CDATA">
- <!-- a space separated list of character encodings, as per [RFC2045] -->
-
-<!ENTITY % LanguageCode "NMTOKEN">
- <!-- a language code, as per [RFC3066] -->
-
-<!ENTITY % Character "CDATA">
- <!-- a single character, as per section 2.2 of [XML] -->
-
-<!ENTITY % Number "CDATA">
- <!-- one or more digits -->
-
-<!ENTITY % LinkTypes "CDATA">
- <!-- space-separated list of link types -->
-
-<!ENTITY % MediaDesc "CDATA">
- <!-- single or comma-separated list of media descriptors -->
-
-<!ENTITY % URI "CDATA">
- <!-- a Uniform Resource Identifier, see [RFC2396] -->
-
-<!ENTITY % UriList "CDATA">
- <!-- a space separated list of Uniform Resource Identifiers -->
-
-<!ENTITY % Datetime "CDATA">
- <!-- date and time information. ISO date format -->
-
-<!ENTITY % Script "CDATA">
- <!-- script expression -->
-
-<!ENTITY % StyleSheet "CDATA">
- <!-- style sheet data -->
-
-<!ENTITY % Text "CDATA">
- <!-- used for titles etc. -->
-
-<!ENTITY % FrameTarget "NMTOKEN">
- <!-- render in this frame -->
-
-<!ENTITY % Length "CDATA">
- <!-- nn for pixels or nn% for percentage length -->
-
-<!ENTITY % MultiLength "CDATA">
- <!-- pixel, percentage, or relative -->
-
-<!ENTITY % Pixels "CDATA">
- <!-- integer representing length in pixels -->
-
-<!-- these are used for image maps -->
-
-<!ENTITY % Shape "(rect|circle|poly|default)">
-
-<!ENTITY % Coords "CDATA">
- <!-- comma separated list of lengths -->
-
-<!-- used for object, applet, img, input and iframe -->
-<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">
-
-<!-- a color using sRGB: #RRGGBB as Hex values -->
-<!ENTITY % Color "CDATA">
-
-<!-- There are also 16 widely known color names with their sRGB values:
-
- Black = #000000 Green = #008000
- Silver = #C0C0C0 Lime = #00FF00
- Gray = #808080 Olive = #808000
- White = #FFFFFF Yellow = #FFFF00
- Maroon = #800000 Navy = #000080
- Red = #FF0000 Blue = #0000FF
- Purple = #800080 Teal = #008080
- Fuchsia= #FF00FF Aqua = #00FFFF
--->
-
-<!--=================== Generic Attributes ===============================-->
-
-<!-- core attributes common to most elements
- id document-wide unique id
- class space separated list of classes
- style associated style info
- title advisory title/amplification
--->
-<!ENTITY % coreattrs
- "id ID #IMPLIED
- class CDATA #IMPLIED
- style %StyleSheet; #IMPLIED
- title %Text; #IMPLIED"
- >
-
-<!-- internationalization attributes
- lang language code (backwards compatible)
- xml:lang language code (as per XML 1.0 spec)
- dir direction for weak/neutral text
--->
-<!ENTITY % i18n
- "lang %LanguageCode; #IMPLIED
- xml:lang %LanguageCode; #IMPLIED
- dir (ltr|rtl) #IMPLIED"
- >
-
-<!-- attributes for common UI events
- onclick a pointer button was clicked
- ondblclick a pointer button was double clicked
- onmousedown a pointer button was pressed down
- onmouseup a pointer button was released
- onmousemove a pointer was moved onto the element
- onmouseout a pointer was moved away from the element
- onkeypress a key was pressed and released
- onkeydown a key was pressed down
- onkeyup a key was released
--->
-<!ENTITY % events
- "onclick %Script; #IMPLIED
- ondblclick %Script; #IMPLIED
- onmousedown %Script; #IMPLIED
- onmouseup %Script; #IMPLIED
- onmouseover %Script; #IMPLIED
- onmousemove %Script; #IMPLIED
- onmouseout %Script; #IMPLIED
- onkeypress %Script; #IMPLIED
- onkeydown %Script; #IMPLIED
- onkeyup %Script; #IMPLIED"
- >
-
-<!-- attributes for elements that can get the focus
- accesskey accessibility key character
- tabindex position in tabbing order
- onfocus the element got the focus
- onblur the element lost the focus
--->
-<!ENTITY % focus
- "accesskey %Character; #IMPLIED
- tabindex %Number; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED"
- >
-
-<!ENTITY % attrs "%coreattrs; %i18n; %events;">
-
-<!-- text alignment for p, div, h1-h6. The default is
- align="left" for ltr headings, "right" for rtl -->
-
-<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED">
-
-<!--=================== Text Elements ====================================-->
-
-<!ENTITY % special.extra
- "object | applet | img | map | iframe">
-
-<!ENTITY % special.basic
- "br | span | bdo">
-
-<!ENTITY % special
- "%special.basic; | %special.extra;">
-
-<!ENTITY % fontstyle.extra "big | small | font | basefont">
-
-<!ENTITY % fontstyle.basic "tt | i | b | u
- | s | strike ">
-
-<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;">
-
-<!ENTITY % phrase.extra "sub | sup">
-<!ENTITY % phrase.basic "em | strong | dfn | code | q |
- samp | kbd | var | cite | abbr | acronym">
-
-<!ENTITY % phrase "%phrase.basic; | %phrase.extra;">
-
-<!ENTITY % inline.forms "input | select | textarea | label | button">
-
-<!-- these can occur at block or inline level -->
-<!ENTITY % misc.inline "ins | del | script">
-
-<!-- these can only occur at block level -->
-<!ENTITY % misc "noscript | %misc.inline;">
-
-<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
-
-<!-- %Inline; covers inline or "text-level" elements -->
-<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
-
-<!--================== Block level elements ==============================-->
-
-<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
-<!ENTITY % lists "ul | ol | dl | menu | dir">
-<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes">
-
-<!ENTITY % block
- "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table">
-
-<!-- %Flow; mixes block and inline and is used for list items etc. -->
-<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
-
-<!--================== Content models for exclusions =====================-->
-
-<!-- a elements use %Inline; excluding a -->
-
-<!ENTITY % a.content
- "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
-
-<!-- pre uses %Inline excluding img, object, applet, big, small,
- font, or basefont -->
-
-<!ENTITY % pre.content
- "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; |
- %inline.forms; | %misc.inline;)*">
-
-<!-- form uses %Flow; excluding form -->
-
-<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">
-
-<!-- button uses %Flow; but excludes a, form, form controls, iframe -->
-
-<!ENTITY % button.content
- "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
- table | br | span | bdo | object | applet | img | map |
- %fontstyle; | %phrase; | %misc;)*">
-
-<!--================ Document Structure ==================================-->
-
-<!-- the namespace URI designates the document profile -->
-
-<!ELEMENT html (head, body)>
-<!ATTLIST html
- %i18n;
- id ID #IMPLIED
- xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml'
- >
-
-<!--================ Document Head =======================================-->
-
-<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">
-
-<!-- content model is %head.misc; combined with a single
- title and an optional base element in any order -->
-
-<!ELEMENT head (%head.misc;,
- ((title, %head.misc;, (base, %head.misc;)?) |
- (base, %head.misc;, (title, %head.misc;))))>
-
-<!ATTLIST head
- %i18n;
- id ID #IMPLIED
- profile %URI; #IMPLIED
- >
-
-<!-- The title element is not considered part of the flow of text.
- It should be displayed, for example as the page header or
- window title. Exactly one title is required per document.
- -->
-<!ELEMENT title (#PCDATA)>
-<!ATTLIST title
- %i18n;
- id ID #IMPLIED
- >
-
-<!-- document base URI -->
-
-<!ELEMENT base EMPTY>
-<!ATTLIST base
- id ID #IMPLIED
- href %URI; #IMPLIED
- target %FrameTarget; #IMPLIED
- >
-
-<!-- generic metainformation -->
-<!ELEMENT meta EMPTY>
-<!ATTLIST meta
- %i18n;
- id ID #IMPLIED
- http-equiv CDATA #IMPLIED
- name CDATA #IMPLIED
- content CDATA #REQUIRED
- scheme CDATA #IMPLIED
- >
-
-<!--
- Relationship values can be used in principle:
-
- a) for document specific toolbars/menus when used
- with the link element in document head e.g.
- start, contents, previous, next, index, end, help
- b) to link to a separate style sheet (rel="stylesheet")
- c) to make a link to a script (rel="script")
- d) by stylesheets to control how collections of
- html nodes are rendered into printed documents
- e) to make a link to a printable version of this document
- e.g. a PostScript or PDF version (rel="alternate" media="print")
--->
-
-<!ELEMENT link EMPTY>
-<!ATTLIST link
- %attrs;
- charset %Charset; #IMPLIED
- href %URI; #IMPLIED
- hreflang %LanguageCode; #IMPLIED
- type %ContentType; #IMPLIED
- rel %LinkTypes; #IMPLIED
- rev %LinkTypes; #IMPLIED
- media %MediaDesc; #IMPLIED
- target %FrameTarget; #IMPLIED
- >
-
-<!-- style info, which may include CDATA sections -->
-<!ELEMENT style (#PCDATA)>
-<!ATTLIST style
- %i18n;
- id ID #IMPLIED
- type %ContentType; #REQUIRED
- media %MediaDesc; #IMPLIED
- title %Text; #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!-- script statements, which may include CDATA sections -->
-<!ELEMENT script (#PCDATA)>
-<!ATTLIST script
- id ID #IMPLIED
- charset %Charset; #IMPLIED
- type %ContentType; #REQUIRED
- language CDATA #IMPLIED
- src %URI; #IMPLIED
- defer (defer) #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!-- alternate content container for non script-based rendering -->
-
-<!ELEMENT noscript %Flow;>
-<!ATTLIST noscript
- %attrs;
- >
-
-<!--======================= Frames =======================================-->
-
-<!-- inline subwindow -->
-
-<!ELEMENT iframe %Flow;>
-<!ATTLIST iframe
- %coreattrs;
- longdesc %URI; #IMPLIED
- name NMTOKEN #IMPLIED
- src %URI; #IMPLIED
- frameborder (1|0) "1"
- marginwidth %Pixels; #IMPLIED
- marginheight %Pixels; #IMPLIED
- scrolling (yes|no|auto) "auto"
- align %ImgAlign; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- >
-
-<!-- alternate content container for non frame-based rendering -->
-
-<!ELEMENT noframes %Flow;>
-<!ATTLIST noframes
- %attrs;
- >
-
-<!--=================== Document Body ====================================-->
-
-<!ELEMENT body %Flow;>
-<!ATTLIST body
- %attrs;
- onload %Script; #IMPLIED
- onunload %Script; #IMPLIED
- background %URI; #IMPLIED
- bgcolor %Color; #IMPLIED
- text %Color; #IMPLIED
- link %Color; #IMPLIED
- vlink %Color; #IMPLIED
- alink %Color; #IMPLIED
- >
-
-<!ELEMENT div %Flow;> <!-- generic language/style container -->
-<!ATTLIST div
- %attrs;
- %TextAlign;
- >
-
-<!--=================== Paragraphs =======================================-->
-
-<!ELEMENT p %Inline;>
-<!ATTLIST p
- %attrs;
- %TextAlign;
- >
-
-<!--=================== Headings =========================================-->
-
-<!--
- There are six levels of headings from h1 (the most important)
- to h6 (the least important).
--->
-
-<!ELEMENT h1 %Inline;>
-<!ATTLIST h1
- %attrs;
- %TextAlign;
- >
-
-<!ELEMENT h2 %Inline;>
-<!ATTLIST h2
- %attrs;
- %TextAlign;
- >
-
-<!ELEMENT h3 %Inline;>
-<!ATTLIST h3
- %attrs;
- %TextAlign;
- >
-
-<!ELEMENT h4 %Inline;>
-<!ATTLIST h4
- %attrs;
- %TextAlign;
- >
-
-<!ELEMENT h5 %Inline;>
-<!ATTLIST h5
- %attrs;
- %TextAlign;
- >
-
-<!ELEMENT h6 %Inline;>
-<!ATTLIST h6
- %attrs;
- %TextAlign;
- >
-
-<!--=================== Lists ============================================-->
-
-<!-- Unordered list bullet styles -->
-
-<!ENTITY % ULStyle "(disc|square|circle)">
-
-<!-- Unordered list -->
-
-<!ELEMENT ul (li)+>
-<!ATTLIST ul
- %attrs;
- type %ULStyle; #IMPLIED
- compact (compact) #IMPLIED
- >
-
-<!-- Ordered list numbering style
-
- 1 arabic numbers 1, 2, 3, ...
- a lower alpha a, b, c, ...
- A upper alpha A, B, C, ...
- i lower roman i, ii, iii, ...
- I upper roman I, II, III, ...
-
- The style is applied to the sequence number which by default
- is reset to 1 for the first list item in an ordered list.
--->
-<!ENTITY % OLStyle "CDATA">
-
-<!-- Ordered (numbered) list -->
-
-<!ELEMENT ol (li)+>
-<!ATTLIST ol
- %attrs;
- type %OLStyle; #IMPLIED
- compact (compact) #IMPLIED
- start %Number; #IMPLIED
- >
-
-<!-- single column list (DEPRECATED) -->
-<!ELEMENT menu (li)+>
-<!ATTLIST menu
- %attrs;
- compact (compact) #IMPLIED
- >
-
-<!-- multiple column list (DEPRECATED) -->
-<!ELEMENT dir (li)+>
-<!ATTLIST dir
- %attrs;
- compact (compact) #IMPLIED
- >
-
-<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->
-<!ENTITY % LIStyle "CDATA">
-
-<!-- list item -->
-
-<!ELEMENT li %Flow;>
-<!ATTLIST li
- %attrs;
- type %LIStyle; #IMPLIED
- value %Number; #IMPLIED
- >
-
-<!-- definition lists - dt for term, dd for its definition -->
-
-<!ELEMENT dl (dt|dd)+>
-<!ATTLIST dl
- %attrs;
- compact (compact) #IMPLIED
- >
-
-<!ELEMENT dt %Inline;>
-<!ATTLIST dt
- %attrs;
- >
-
-<!ELEMENT dd %Flow;>
-<!ATTLIST dd
- %attrs;
- >
-
-<!--=================== Address ==========================================-->
-
-<!-- information on author -->
-
-<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*>
-<!ATTLIST address
- %attrs;
- >
-
-<!--=================== Horizontal Rule ==================================-->
-
-<!ELEMENT hr EMPTY>
-<!ATTLIST hr
- %attrs;
- align (left|center|right) #IMPLIED
- noshade (noshade) #IMPLIED
- size %Pixels; #IMPLIED
- width %Length; #IMPLIED
- >
-
-<!--=================== Preformatted Text ================================-->
-
-<!-- content is %Inline; excluding
- "img|object|applet|big|small|sub|sup|font|basefont" -->
-
-<!ELEMENT pre %pre.content;>
-<!ATTLIST pre
- %attrs;
- width %Number; #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!--=================== Block-like Quotes ================================-->
-
-<!ELEMENT blockquote %Flow;>
-<!ATTLIST blockquote
- %attrs;
- cite %URI; #IMPLIED
- >
-
-<!--=================== Text alignment ===================================-->
-
-<!-- center content -->
-<!ELEMENT center %Flow;>
-<!ATTLIST center
- %attrs;
- >
-
-<!--=================== Inserted/Deleted Text ============================-->
-
-<!--
- ins/del are allowed in block and inline content, but its
- inappropriate to include block content within an ins element
- occurring in inline content.
--->
-<!ELEMENT ins %Flow;>
-<!ATTLIST ins
- %attrs;
- cite %URI; #IMPLIED
- datetime %Datetime; #IMPLIED
- >
-
-<!ELEMENT del %Flow;>
-<!ATTLIST del
- %attrs;
- cite %URI; #IMPLIED
- datetime %Datetime; #IMPLIED
- >
-
-<!--================== The Anchor Element ================================-->
-
-<!-- content is %Inline; except that anchors shouldn't be nested -->
-
-<!ELEMENT a %a.content;>
-<!ATTLIST a
- %attrs;
- %focus;
- charset %Charset; #IMPLIED
- type %ContentType; #IMPLIED
- name NMTOKEN #IMPLIED
- href %URI; #IMPLIED
- hreflang %LanguageCode; #IMPLIED
- rel %LinkTypes; #IMPLIED
- rev %LinkTypes; #IMPLIED
- shape %Shape; "rect"
- coords %Coords; #IMPLIED
- target %FrameTarget; #IMPLIED
- >
-
-<!--===================== Inline Elements ================================-->
-
-<!ELEMENT span %Inline;> <!-- generic language/style container -->
-<!ATTLIST span
- %attrs;
- >
-
-<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride -->
-<!ATTLIST bdo
- %coreattrs;
- %events;
- lang %LanguageCode; #IMPLIED
- xml:lang %LanguageCode; #IMPLIED
- dir (ltr|rtl) #REQUIRED
- >
-
-<!ELEMENT br EMPTY> <!-- forced line break -->
-<!ATTLIST br
- %coreattrs;
- clear (left|all|right|none) "none"
- >
-
-<!ELEMENT em %Inline;> <!-- emphasis -->
-<!ATTLIST em %attrs;>
-
-<!ELEMENT strong %Inline;> <!-- strong emphasis -->
-<!ATTLIST strong %attrs;>
-
-<!ELEMENT dfn %Inline;> <!-- definitional -->
-<!ATTLIST dfn %attrs;>
-
-<!ELEMENT code %Inline;> <!-- program code -->
-<!ATTLIST code %attrs;>
-
-<!ELEMENT samp %Inline;> <!-- sample -->
-<!ATTLIST samp %attrs;>
-
-<!ELEMENT kbd %Inline;> <!-- something user would type -->
-<!ATTLIST kbd %attrs;>
-
-<!ELEMENT var %Inline;> <!-- variable -->
-<!ATTLIST var %attrs;>
-
-<!ELEMENT cite %Inline;> <!-- citation -->
-<!ATTLIST cite %attrs;>
-
-<!ELEMENT abbr %Inline;> <!-- abbreviation -->
-<!ATTLIST abbr %attrs;>
-
-<!ELEMENT acronym %Inline;> <!-- acronym -->
-<!ATTLIST acronym %attrs;>
-
-<!ELEMENT q %Inline;> <!-- inlined quote -->
-<!ATTLIST q
- %attrs;
- cite %URI; #IMPLIED
- >
-
-<!ELEMENT sub %Inline;> <!-- subscript -->
-<!ATTLIST sub %attrs;>
-
-<!ELEMENT sup %Inline;> <!-- superscript -->
-<!ATTLIST sup %attrs;>
-
-<!ELEMENT tt %Inline;> <!-- fixed pitch font -->
-<!ATTLIST tt %attrs;>
-
-<!ELEMENT i %Inline;> <!-- italic font -->
-<!ATTLIST i %attrs;>
-
-<!ELEMENT b %Inline;> <!-- bold font -->
-<!ATTLIST b %attrs;>
-
-<!ELEMENT big %Inline;> <!-- bigger font -->
-<!ATTLIST big %attrs;>
-
-<!ELEMENT small %Inline;> <!-- smaller font -->
-<!ATTLIST small %attrs;>
-
-<!ELEMENT u %Inline;> <!-- underline -->
-<!ATTLIST u %attrs;>
-
-<!ELEMENT s %Inline;> <!-- strike-through -->
-<!ATTLIST s %attrs;>
-
-<!ELEMENT strike %Inline;> <!-- strike-through -->
-<!ATTLIST strike %attrs;>
-
-<!ELEMENT basefont EMPTY> <!-- base font size -->
-<!ATTLIST basefont
- id ID #IMPLIED
- size CDATA #REQUIRED
- color %Color; #IMPLIED
- face CDATA #IMPLIED
- >
-
-<!ELEMENT font %Inline;> <!-- local change to font -->
-<!ATTLIST font
- %coreattrs;
- %i18n;
- size CDATA #IMPLIED
- color %Color; #IMPLIED
- face CDATA #IMPLIED
- >
-
-<!--==================== Object ======================================-->
-<!--
- object is used to embed objects as part of HTML pages.
- param elements should precede other content. Parameters
- can also be expressed as attribute/value pairs on the
- object element itself when brevity is desired.
--->
-
-<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
-<!ATTLIST object
- %attrs;
- declare (declare) #IMPLIED
- classid %URI; #IMPLIED
- codebase %URI; #IMPLIED
- data %URI; #IMPLIED
- type %ContentType; #IMPLIED
- codetype %ContentType; #IMPLIED
- archive %UriList; #IMPLIED
- standby %Text; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- usemap %URI; #IMPLIED
- name NMTOKEN #IMPLIED
- tabindex %Number; #IMPLIED
- align %ImgAlign; #IMPLIED
- border %Pixels; #IMPLIED
- hspace %Pixels; #IMPLIED
- vspace %Pixels; #IMPLIED
- >
-
-<!--
- param is used to supply a named property value.
- In XML it would seem natural to follow RDF and support an
- abbreviated syntax where the param elements are replaced
- by attribute value pairs on the object start tag.
--->
-<!ELEMENT param EMPTY>
-<!ATTLIST param
- id ID #IMPLIED
- name CDATA #REQUIRED
- value CDATA #IMPLIED
- valuetype (data|ref|object) "data"
- type %ContentType; #IMPLIED
- >
-
-<!--=================== Java applet ==================================-->
-<!--
- One of code or object attributes must be present.
- Place param elements before other content.
--->
-<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>
-<!ATTLIST applet
- %coreattrs;
- codebase %URI; #IMPLIED
- archive CDATA #IMPLIED
- code CDATA #IMPLIED
- object CDATA #IMPLIED
- alt %Text; #IMPLIED
- name NMTOKEN #IMPLIED
- width %Length; #REQUIRED
- height %Length; #REQUIRED
- align %ImgAlign; #IMPLIED
- hspace %Pixels; #IMPLIED
- vspace %Pixels; #IMPLIED
- >
-
-<!--=================== Images ===========================================-->
-
-<!--
- To avoid accessibility problems for people who aren't
- able to see the image, you should provide a text
- description using the alt and longdesc attributes.
- In addition, avoid the use of server-side image maps.
--->
-
-<!ELEMENT img EMPTY>
-<!ATTLIST img
- %attrs;
- src %URI; #REQUIRED
- alt %Text; #REQUIRED
- name NMTOKEN #IMPLIED
- longdesc %URI; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- usemap %URI; #IMPLIED
- ismap (ismap) #IMPLIED
- align %ImgAlign; #IMPLIED
- border %Length; #IMPLIED
- hspace %Pixels; #IMPLIED
- vspace %Pixels; #IMPLIED
- >
-
-<!-- usemap points to a map element which may be in this document
- or an external document, although the latter is not widely supported -->
-
-<!--================== Client-side image maps ============================-->
-
-<!-- These can be placed in the same document or grouped in a
- separate document although this isn't yet widely supported -->
-
-<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
-<!ATTLIST map
- %i18n;
- %events;
- id ID #REQUIRED
- class CDATA #IMPLIED
- style %StyleSheet; #IMPLIED
- title %Text; #IMPLIED
- name CDATA #IMPLIED
- >
-
-<!ELEMENT area EMPTY>
-<!ATTLIST area
- %attrs;
- %focus;
- shape %Shape; "rect"
- coords %Coords; #IMPLIED
- href %URI; #IMPLIED
- nohref (nohref) #IMPLIED
- alt %Text; #REQUIRED
- target %FrameTarget; #IMPLIED
- >
-
-<!--================ Forms ===============================================-->
-
-<!ELEMENT form %form.content;> <!-- forms shouldn't be nested -->
-
-<!ATTLIST form
- %attrs;
- action %URI; #REQUIRED
- method (get|post) "get"
- name NMTOKEN #IMPLIED
- enctype %ContentType; "application/x-www-form-urlencoded"
- onsubmit %Script; #IMPLIED
- onreset %Script; #IMPLIED
- accept %ContentTypes; #IMPLIED
- accept-charset %Charsets; #IMPLIED
- target %FrameTarget; #IMPLIED
- >
-
-<!--
- Each label must not contain more than ONE field
- Label elements shouldn't be nested.
--->
-<!ELEMENT label %Inline;>
-<!ATTLIST label
- %attrs;
- for IDREF #IMPLIED
- accesskey %Character; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED
- >
-
-<!ENTITY % InputType
- "(text | password | checkbox |
- radio | submit | reset |
- file | hidden | image | button)"
- >
-
-<!-- the name attribute is required for all but submit & reset -->
-
-<!ELEMENT input EMPTY> <!-- form control -->
-<!ATTLIST input
- %attrs;
- %focus;
- type %InputType; "text"
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- checked (checked) #IMPLIED
- disabled (disabled) #IMPLIED
- readonly (readonly) #IMPLIED
- size CDATA #IMPLIED
- maxlength %Number; #IMPLIED
- src %URI; #IMPLIED
- alt CDATA #IMPLIED
- usemap %URI; #IMPLIED
- onselect %Script; #IMPLIED
- onchange %Script; #IMPLIED
- accept %ContentTypes; #IMPLIED
- align %ImgAlign; #IMPLIED
- >
-
-<!ELEMENT select (optgroup|option)+> <!-- option selector -->
-<!ATTLIST select
- %attrs;
- name CDATA #IMPLIED
- size %Number; #IMPLIED
- multiple (multiple) #IMPLIED
- disabled (disabled) #IMPLIED
- tabindex %Number; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED
- onchange %Script; #IMPLIED
- >
-
-<!ELEMENT optgroup (option)+> <!-- option group -->
-<!ATTLIST optgroup
- %attrs;
- disabled (disabled) #IMPLIED
- label %Text; #REQUIRED
- >
-
-<!ELEMENT option (#PCDATA)> <!-- selectable choice -->
-<!ATTLIST option
- %attrs;
- selected (selected) #IMPLIED
- disabled (disabled) #IMPLIED
- label %Text; #IMPLIED
- value CDATA #IMPLIED
- >
-
-<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field -->
-<!ATTLIST textarea
- %attrs;
- %focus;
- name CDATA #IMPLIED
- rows %Number; #REQUIRED
- cols %Number; #REQUIRED
- disabled (disabled) #IMPLIED
- readonly (readonly) #IMPLIED
- onselect %Script; #IMPLIED
- onchange %Script; #IMPLIED
- >
-
-<!--
- The fieldset element is used to group form fields.
- Only one legend element should occur in the content
- and if present should only be preceded by whitespace.
--->
-<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
-<!ATTLIST fieldset
- %attrs;
- >
-
-<!ENTITY % LAlign "(top|bottom|left|right)">
-
-<!ELEMENT legend %Inline;> <!-- fieldset label -->
-<!ATTLIST legend
- %attrs;
- accesskey %Character; #IMPLIED
- align %LAlign; #IMPLIED
- >
-
-<!--
- Content is %Flow; excluding a, form, form controls, iframe
--->
-<!ELEMENT button %button.content;> <!-- push button -->
-<!ATTLIST button
- %attrs;
- %focus;
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- type (button|submit|reset) "submit"
- disabled (disabled) #IMPLIED
- >
-
-<!-- single-line text input control (DEPRECATED) -->
-<!ELEMENT isindex EMPTY>
-<!ATTLIST isindex
- %coreattrs;
- %i18n;
- prompt %Text; #IMPLIED
- >
-
-<!--======================= Tables =======================================-->
-
-<!-- Derived from IETF HTML table standard, see [RFC1942] -->
-
-<!--
- The border attribute sets the thickness of the frame around the
- table. The default units are screen pixels.
-
- The frame attribute specifies which parts of the frame around
- the table should be rendered. The values are not the same as
- CALS to avoid a name clash with the valign attribute.
--->
-<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
-
-<!--
- The rules attribute defines which rules to draw between cells:
-
- If rules is absent then assume:
- "none" if border is absent or border="0" otherwise "all"
--->
-
-<!ENTITY % TRules "(none | groups | rows | cols | all)">
-
-<!-- horizontal placement of table relative to document -->
-<!ENTITY % TAlign "(left|center|right)">
-
-<!-- horizontal alignment attributes for cell contents
-
- char alignment char, e.g. char=':'
- charoff offset for alignment char
--->
-<!ENTITY % cellhalign
- "align (left|center|right|justify|char) #IMPLIED
- char %Character; #IMPLIED
- charoff %Length; #IMPLIED"
- >
-
-<!-- vertical alignment attributes for cell contents -->
-<!ENTITY % cellvalign
- "valign (top|middle|bottom|baseline) #IMPLIED"
- >
-
-<!ELEMENT table
- (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
-<!ELEMENT caption %Inline;>
-<!ELEMENT thead (tr)+>
-<!ELEMENT tfoot (tr)+>
-<!ELEMENT tbody (tr)+>
-<!ELEMENT colgroup (col)*>
-<!ELEMENT col EMPTY>
-<!ELEMENT tr (th|td)+>
-<!ELEMENT th %Flow;>
-<!ELEMENT td %Flow;>
-
-<!ATTLIST table
- %attrs;
- summary %Text; #IMPLIED
- width %Length; #IMPLIED
- border %Pixels; #IMPLIED
- frame %TFrame; #IMPLIED
- rules %TRules; #IMPLIED
- cellspacing %Length; #IMPLIED
- cellpadding %Length; #IMPLIED
- align %TAlign; #IMPLIED
- bgcolor %Color; #IMPLIED
- >
-
-<!ENTITY % CAlign "(top|bottom|left|right)">
-
-<!ATTLIST caption
- %attrs;
- align %CAlign; #IMPLIED
- >
-
-<!--
-colgroup groups a set of col elements. It allows you to group
-several semantically related columns together.
--->
-<!ATTLIST colgroup
- %attrs;
- span %Number; "1"
- width %MultiLength; #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!--
- col elements define the alignment properties for cells in
- one or more columns.
-
- The width attribute specifies the width of the columns, e.g.
-
- width=64 width in screen pixels
- width=0.5* relative width of 0.5
-
- The span attribute causes the attributes of one
- col element to apply to more than one column.
--->
-<!ATTLIST col
- %attrs;
- span %Number; "1"
- width %MultiLength; #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!--
- Use thead to duplicate headers when breaking table
- across page boundaries, or for static headers when
- tbody sections are rendered in scrolling panel.
-
- Use tfoot to duplicate footers when breaking table
- across page boundaries, or for static footers when
- tbody sections are rendered in scrolling panel.
-
- Use multiple tbody sections when rules are needed
- between groups of table rows.
--->
-<!ATTLIST thead
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tfoot
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tbody
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tr
- %attrs;
- %cellhalign;
- %cellvalign;
- bgcolor %Color; #IMPLIED
- >
-
-<!-- Scope is simpler than headers attribute for common tables -->
-<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
-
-<!-- th is for headers, td for data and for cells acting as both -->
-
-<!ATTLIST th
- %attrs;
- abbr %Text; #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope %Scope; #IMPLIED
- rowspan %Number; "1"
- colspan %Number; "1"
- %cellhalign;
- %cellvalign;
- nowrap (nowrap) #IMPLIED
- bgcolor %Color; #IMPLIED
- width %Length; #IMPLIED
- height %Length; #IMPLIED
- >
-
-<!ATTLIST td
- %attrs;
- abbr %Text; #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope %Scope; #IMPLIED
- rowspan %Number; "1"
- colspan %Number; "1"
- %cellhalign;
- %cellvalign;
- nowrap (nowrap) #IMPLIED
- bgcolor %Color; #IMPLIED
- width %Length; #IMPLIED
- height %Length; #IMPLIED
- >
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/__init__.py
deleted file mode 100755
index b434715f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-
-Twisted Mail: a Twisted E-Mail Server.
-
-Maintainer: Jp Calderone
-
-"""
-
-from twisted.mail._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/_version.py
deleted file mode 100755
index de980e31..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.mail', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/alias.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/alias.py
deleted file mode 100755
index 8eccea6b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/alias.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mail -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Support for aliases(5) configuration files
-
-@author: Jp Calderone
-
-TODO::
- Monitor files for reparsing
- Handle non-local alias targets
- Handle maildir alias targets
-"""
-
-import os
-import tempfile
-
-from twisted.mail import smtp
-from twisted.internet import reactor
-from twisted.internet import protocol
-from twisted.internet import defer
-from twisted.python import failure
-from twisted.python import log
-from zope.interface import implements, Interface
-
-
-def handle(result, line, filename, lineNo):
- parts = [p.strip() for p in line.split(':', 1)]
- if len(parts) != 2:
- fmt = "Invalid format on line %d of alias file %s."
- arg = (lineNo, filename)
- log.err(fmt % arg)
- else:
- user, alias = parts
- result.setdefault(user.strip(), []).extend(map(str.strip, alias.split(',')))
-
-def loadAliasFile(domains, filename=None, fp=None):
- """Load a file containing email aliases.
-
- Lines in the file should be formatted like so::
-
- username: alias1,alias2,...,aliasN
-
- Aliases beginning with a | will be treated as programs, will be run, and
- the message will be written to their stdin.
-
- Aliases without a host part will be assumed to be addresses on localhost.
-
- If a username is specified multiple times, the aliases for each are joined
- together as if they had all been on one line.
-
- @type domains: C{dict} of implementor of C{IDomain}
- @param domains: The domains to which these aliases will belong.
-
- @type filename: C{str}
- @param filename: The filename from which to load aliases.
-
- @type fp: Any file-like object.
- @param fp: If specified, overrides C{filename}, and aliases are read from
- it.
-
- @rtype: C{dict}
- @return: A dictionary mapping usernames to C{AliasGroup} objects.
- """
- result = {}
- if fp is None:
- fp = file(filename)
- else:
- filename = getattr(fp, 'name', '<unknown>')
- i = 0
- prev = ''
- for line in fp:
- i += 1
- line = line.rstrip()
- if line.lstrip().startswith('#'):
- continue
- elif line.startswith(' ') or line.startswith('\t'):
- prev = prev + line
- else:
- if prev:
- handle(result, prev, filename, i)
- prev = line
- if prev:
- handle(result, prev, filename, i)
- for (u, a) in result.items():
- addr = smtp.Address(u)
- result[u] = AliasGroup(a, domains, u)
- return result
-
-class IAlias(Interface):
- def createMessageReceiver():
- pass
-
-class AliasBase:
- def __init__(self, domains, original):
- self.domains = domains
- self.original = smtp.Address(original)
-
- def domain(self):
- return self.domains[self.original.domain]
-
- def resolve(self, aliasmap, memo=None):
- if memo is None:
- memo = {}
- if str(self) in memo:
- return None
- memo[str(self)] = None
- return self.createMessageReceiver()
-
-class AddressAlias(AliasBase):
- """The simplest alias, translating one email address into another."""
-
- implements(IAlias)
-
- def __init__(self, alias, *args):
- AliasBase.__init__(self, *args)
- self.alias = smtp.Address(alias)
-
- def __str__(self):
- return '<Address %s>' % (self.alias,)
-
- def createMessageReceiver(self):
- return self.domain().startMessage(str(self.alias))
-
- def resolve(self, aliasmap, memo=None):
- if memo is None:
- memo = {}
- if str(self) in memo:
- return None
- memo[str(self)] = None
- try:
- return self.domain().exists(smtp.User(self.alias, None, None, None), memo)()
- except smtp.SMTPBadRcpt:
- pass
- if self.alias.local in aliasmap:
- return aliasmap[self.alias.local].resolve(aliasmap, memo)
- return None
-
-class FileWrapper:
- implements(smtp.IMessage)
-
- def __init__(self, filename):
- self.fp = tempfile.TemporaryFile()
- self.finalname = filename
-
- def lineReceived(self, line):
- self.fp.write(line + '\n')
-
- def eomReceived(self):
- self.fp.seek(0, 0)
- try:
- f = file(self.finalname, 'a')
- except:
- return defer.fail(failure.Failure())
-
- f.write(self.fp.read())
- self.fp.close()
- f.close()
-
- return defer.succeed(self.finalname)
-
- def connectionLost(self):
- self.fp.close()
- self.fp = None
-
- def __str__(self):
- return '<FileWrapper %s>' % (self.finalname,)
-
-
-class FileAlias(AliasBase):
-
- implements(IAlias)
-
- def __init__(self, filename, *args):
- AliasBase.__init__(self, *args)
- self.filename = filename
-
- def __str__(self):
- return '<File %s>' % (self.filename,)
-
- def createMessageReceiver(self):
- return FileWrapper(self.filename)
-
-
-
-class ProcessAliasTimeout(Exception):
- """
- A timeout occurred while processing aliases.
- """
-
-
-
-class MessageWrapper:
- """
- A message receiver which delivers content to a child process.
-
- @type completionTimeout: C{int} or C{float}
- @ivar completionTimeout: The number of seconds to wait for the child
- process to exit before reporting the delivery as a failure.
-
- @type _timeoutCallID: C{NoneType} or L{IDelayedCall}
- @ivar _timeoutCallID: The call used to time out delivery, started when the
- connection to the child process is closed.
-
- @type done: C{bool}
- @ivar done: Flag indicating whether the child process has exited or not.
-
- @ivar reactor: An L{IReactorTime} provider which will be used to schedule
- timeouts.
- """
- implements(smtp.IMessage)
-
- done = False
-
- completionTimeout = 60
- _timeoutCallID = None
-
- reactor = reactor
-
- def __init__(self, protocol, process=None, reactor=None):
- self.processName = process
- self.protocol = protocol
- self.completion = defer.Deferred()
- self.protocol.onEnd = self.completion
- self.completion.addBoth(self._processEnded)
-
- if reactor is not None:
- self.reactor = reactor
-
-
- def _processEnded(self, result):
- """
- Record process termination and cancel the timeout call if it is active.
- """
- self.done = True
- if self._timeoutCallID is not None:
- # eomReceived was called, we're actually waiting for the process to
- # exit.
- self._timeoutCallID.cancel()
- self._timeoutCallID = None
- else:
- # eomReceived was not called, this is unexpected, propagate the
- # error.
- return result
-
-
- def lineReceived(self, line):
- if self.done:
- return
- self.protocol.transport.write(line + '\n')
-
-
- def eomReceived(self):
- """
- Disconnect from the child process, set up a timeout to wait for it to
- exit, and return a Deferred which will be called back when the child
- process exits.
- """
- if not self.done:
- self.protocol.transport.loseConnection()
- self._timeoutCallID = self.reactor.callLater(
- self.completionTimeout, self._completionCancel)
- return self.completion
-
-
- def _completionCancel(self):
- """
- Handle the expiration of the timeout for the child process to exit by
- terminating the child process forcefully and issuing a failure to the
- completion deferred returned by L{eomReceived}.
- """
- self._timeoutCallID = None
- self.protocol.transport.signalProcess('KILL')
- exc = ProcessAliasTimeout(
- "No answer after %s seconds" % (self.completionTimeout,))
- self.protocol.onEnd = None
- self.completion.errback(failure.Failure(exc))
-
-
- def connectionLost(self):
- # Heh heh
- pass
-
-
- def __str__(self):
- return '<ProcessWrapper %s>' % (self.processName,)
-
-
-
-class ProcessAliasProtocol(protocol.ProcessProtocol):
- """
- Trivial process protocol which will callback a Deferred when the associated
- process ends.
-
- @ivar onEnd: If not C{None}, a L{Deferred} which will be called back with
- the failure passed to C{processEnded}, when C{processEnded} is called.
- """
-
- onEnd = None
-
- def processEnded(self, reason):
- """
- Call back C{onEnd} if it is set.
- """
- if self.onEnd is not None:
- self.onEnd.errback(reason)
-
-
-
-class ProcessAlias(AliasBase):
- """
- An alias which is handled by the execution of a particular program.
-
- @ivar reactor: An L{IReactorProcess} and L{IReactorTime} provider which
- will be used to create and timeout the alias child process.
- """
- implements(IAlias)
-
- reactor = reactor
-
- def __init__(self, path, *args):
- AliasBase.__init__(self, *args)
- self.path = path.split()
- self.program = self.path[0]
-
-
- def __str__(self):
- """
- Build a string representation containing the path.
- """
- return '<Process %s>' % (self.path,)
-
-
- def spawnProcess(self, proto, program, path):
- """
- Wrapper around C{reactor.spawnProcess}, to be customized for tests
- purpose.
- """
- return self.reactor.spawnProcess(proto, program, path)
-
-
- def createMessageReceiver(self):
- """
- Create a message receiver by launching a process.
- """
- p = ProcessAliasProtocol()
- m = MessageWrapper(p, self.program, self.reactor)
- fd = self.spawnProcess(p, self.program, self.path)
- return m
-
-
-
-class MultiWrapper:
- """
- Wrapper to deliver a single message to multiple recipients.
- """
-
- implements(smtp.IMessage)
-
- def __init__(self, objs):
- self.objs = objs
-
- def lineReceived(self, line):
- for o in self.objs:
- o.lineReceived(line)
-
- def eomReceived(self):
- return defer.DeferredList([
- o.eomReceived() for o in self.objs
- ])
-
- def connectionLost(self):
- for o in self.objs:
- o.connectionLost()
-
- def __str__(self):
- return '<GroupWrapper %r>' % (map(str, self.objs),)
-
-
-
-class AliasGroup(AliasBase):
- """
- An alias which points to more than one recipient.
-
- @ivar processAliasFactory: a factory for resolving process aliases.
- @type processAliasFactory: C{class}
- """
-
- implements(IAlias)
-
- processAliasFactory = ProcessAlias
-
- def __init__(self, items, *args):
- AliasBase.__init__(self, *args)
- self.aliases = []
- while items:
- addr = items.pop().strip()
- if addr.startswith(':'):
- try:
- f = file(addr[1:])
- except:
- log.err("Invalid filename in alias file %r" % (addr[1:],))
- else:
- addr = ' '.join([l.strip() for l in f])
- items.extend(addr.split(','))
- elif addr.startswith('|'):
- self.aliases.append(self.processAliasFactory(addr[1:], *args))
- elif addr.startswith('/'):
- if os.path.isdir(addr):
- log.err("Directory delivery not supported")
- else:
- self.aliases.append(FileAlias(addr, *args))
- else:
- self.aliases.append(AddressAlias(addr, *args))
-
- def __len__(self):
- return len(self.aliases)
-
- def __str__(self):
- return '<AliasGroup [%s]>' % (', '.join(map(str, self.aliases)))
-
- def createMessageReceiver(self):
- return MultiWrapper([a.createMessageReceiver() for a in self.aliases])
-
- def resolve(self, aliasmap, memo=None):
- if memo is None:
- memo = {}
- r = []
- for a in self.aliases:
- r.append(a.resolve(aliasmap, memo))
- return MultiWrapper(filter(None, r))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/bounce.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/bounce.py
deleted file mode 100755
index 5d5bde9a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/bounce.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_bounce -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-import StringIO
-import rfc822
-import time
-import os
-
-
-from twisted.mail import smtp
-
-BOUNCE_FORMAT = """\
-From: postmaster@%(failedDomain)s
-To: %(failedFrom)s
-Subject: Returned Mail: see transcript for details
-Message-ID: %(messageID)s
-Content-Type: multipart/report; report-type=delivery-status;
- boundary="%(boundary)s"
-
---%(boundary)s
-
-%(transcript)s
-
---%(boundary)s
-Content-Type: message/delivery-status
-Arrival-Date: %(ctime)s
-Final-Recipient: RFC822; %(failedTo)s
-"""
-
-def generateBounce(message, failedFrom, failedTo, transcript=''):
- if not transcript:
- transcript = '''\
-I'm sorry, the following address has permanent errors: %(failedTo)s.
-I've given up, and I will not retry the message again.
-''' % vars()
-
- boundary = "%s_%s_%s" % (time.time(), os.getpid(), 'XXXXX')
- failedAddress = rfc822.AddressList(failedTo)[0][1]
- failedDomain = failedAddress.split('@', 1)[1]
- messageID = smtp.messageid(uniq='bounce')
- ctime = time.ctime(time.time())
-
- fp = StringIO.StringIO()
- fp.write(BOUNCE_FORMAT % vars())
- orig = message.tell()
- message.seek(2, 0)
- sz = message.tell()
- message.seek(0, orig)
- if sz > 10000:
- while 1:
- line = message.readline()
- if len(line)<=1:
- break
- fp.write(line)
- else:
- fp.write(message.read())
- return '', failedFrom, fp.getvalue()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/imap4.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/imap4.py
deleted file mode 100755
index f23483bd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/imap4.py
+++ /dev/null
@@ -1,6208 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_imap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An IMAP4 protocol implementation
-
-@author: Jp Calderone
-
-To do::
- Suspend idle timeout while server is processing
- Use an async message parser instead of buffering in memory
- Figure out a way to not queue multi-message client requests (Flow? A simple callback?)
- Clarify some API docs (Query, etc)
- Make APPEND recognize (again) non-existent mailboxes before accepting the literal
-"""
-
-import rfc822
-import base64
-import binascii
-import hmac
-import re
-import copy
-import tempfile
-import string
-import time
-import random
-import types
-
-import email.Utils
-
-try:
- import cStringIO as StringIO
-except:
- import StringIO
-
-from zope.interface import implements, Interface
-
-from twisted.protocols import basic
-from twisted.protocols import policies
-from twisted.internet import defer
-from twisted.internet import error
-from twisted.internet.defer import maybeDeferred
-from twisted.python import log, text
-from twisted.internet import interfaces
-
-from twisted import cred
-import twisted.cred.error
-import twisted.cred.credentials
-
-
-# locale-independent month names to use instead of strftime's
-_MONTH_NAMES = dict(zip(
- range(1, 13),
- "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split()))
-
-
-class MessageSet(object):
- """
- Essentially an infinite bitfield, with some extra features.
-
- @type getnext: Function taking C{int} returning C{int}
- @ivar getnext: A function that returns the next message number,
- used when iterating through the MessageSet. By default, a function
- returning the next integer is supplied, but as this can be rather
- inefficient for sparse UID iterations, it is recommended to supply
- one when messages are requested by UID. The argument is provided
- as a hint to the implementation and may be ignored if it makes sense
- to do so (eg, if an iterator is being used that maintains its own
- state, it is guaranteed that it will not be called out-of-order).
- """
- _empty = []
-
- def __init__(self, start=_empty, end=_empty):
- """
- Create a new MessageSet()
-
- @type start: Optional C{int}
- @param start: Start of range, or only message number
-
- @type end: Optional C{int}
- @param end: End of range.
- """
- self._last = self._empty # Last message/UID in use
- self.ranges = [] # List of ranges included
- self.getnext = lambda x: x+1 # A function which will return the next
- # message id. Handy for UID requests.
-
- if start is self._empty:
- return
-
- if isinstance(start, types.ListType):
- self.ranges = start[:]
- self.clean()
- else:
- self.add(start,end)
-
- # Ooo. A property.
- def last():
- def _setLast(self, value):
- if self._last is not self._empty:
- raise ValueError("last already set")
-
- self._last = value
- for i, (l, h) in enumerate(self.ranges):
- if l is not None:
- break # There are no more Nones after this
- l = value
- if h is None:
- h = value
- if l > h:
- l, h = h, l
- self.ranges[i] = (l, h)
-
- self.clean()
-
- def _getLast(self):
- return self._last
-
- doc = '''
- "Highest" message number, refered to by "*".
- Must be set before attempting to use the MessageSet.
- '''
- return _getLast, _setLast, None, doc
- last = property(*last())
-
- def add(self, start, end=_empty):
- """
- Add another range
-
- @type start: C{int}
- @param start: Start of range, or only message number
-
- @type end: Optional C{int}
- @param end: End of range.
- """
- if end is self._empty:
- end = start
-
- if self._last is not self._empty:
- if start is None:
- start = self.last
- if end is None:
- end = self.last
-
- if start > end:
- # Try to keep in low, high order if possible
- # (But we don't know what None means, this will keep
- # None at the start of the ranges list)
- start, end = end, start
-
- self.ranges.append((start, end))
- self.clean()
-
- def __add__(self, other):
- if isinstance(other, MessageSet):
- ranges = self.ranges + other.ranges
- return MessageSet(ranges)
- else:
- res = MessageSet(self.ranges)
- try:
- res.add(*other)
- except TypeError:
- res.add(other)
- return res
-
-
- def extend(self, other):
- if isinstance(other, MessageSet):
- self.ranges.extend(other.ranges)
- self.clean()
- else:
- try:
- self.add(*other)
- except TypeError:
- self.add(other)
-
- return self
-
-
- def clean(self):
- """
- Clean ranges list, combining adjacent ranges
- """
-
- self.ranges.sort()
-
- oldl, oldh = None, None
- for i,(l, h) in enumerate(self.ranges):
- if l is None:
- continue
- # l is >= oldl and h is >= oldh due to sort()
- if oldl is not None and l <= oldh + 1:
- l = oldl
- h = max(oldh, h)
- self.ranges[i - 1] = None
- self.ranges[i] = (l, h)
-
- oldl, oldh = l, h
-
- self.ranges = filter(None, self.ranges)
-
-
- def __contains__(self, value):
- """
- May raise TypeError if we encounter an open-ended range
- """
- for l, h in self.ranges:
- if l is None:
- raise TypeError(
- "Can't determine membership; last value not set")
- if l <= value <= h:
- return True
-
- return False
-
-
- def _iterator(self):
- for l, h in self.ranges:
- l = self.getnext(l-1)
- while l <= h:
- yield l
- l = self.getnext(l)
- if l is None:
- break
-
- def __iter__(self):
- if self.ranges and self.ranges[0][0] is None:
- raise TypeError("Can't iterate; last value not set")
-
- return self._iterator()
-
- def __len__(self):
- res = 0
- for l, h in self.ranges:
- if l is None:
- if h is None:
- res += 1
- else:
- raise TypeError("Can't size object; last value not set")
- else:
- res += (h - l) + 1
-
- return res
-
- def __str__(self):
- p = []
- for low, high in self.ranges:
- if low == high:
- if low is None:
- p.append('*')
- else:
- p.append(str(low))
- elif low is None:
- p.append('%d:*' % (high,))
- else:
- p.append('%d:%d' % (low, high))
- return ','.join(p)
-
- def __repr__(self):
- return '<MessageSet %s>' % (str(self),)
-
- def __eq__(self, other):
- if isinstance(other, MessageSet):
- return self.ranges == other.ranges
- return False
-
-
-class LiteralString:
- def __init__(self, size, defered):
- self.size = size
- self.data = []
- self.defer = defered
-
- def write(self, data):
- self.size -= len(data)
- passon = None
- if self.size > 0:
- self.data.append(data)
- else:
- if self.size:
- data, passon = data[:self.size], data[self.size:]
- else:
- passon = ''
- if data:
- self.data.append(data)
- return passon
-
- def callback(self, line):
- """
- Call defered with data and rest of line
- """
- self.defer.callback((''.join(self.data), line))
-
-class LiteralFile:
- _memoryFileLimit = 1024 * 1024 * 10
-
- def __init__(self, size, defered):
- self.size = size
- self.defer = defered
- if size > self._memoryFileLimit:
- self.data = tempfile.TemporaryFile()
- else:
- self.data = StringIO.StringIO()
-
- def write(self, data):
- self.size -= len(data)
- passon = None
- if self.size > 0:
- self.data.write(data)
- else:
- if self.size:
- data, passon = data[:self.size], data[self.size:]
- else:
- passon = ''
- if data:
- self.data.write(data)
- return passon
-
- def callback(self, line):
- """
- Call defered with data and rest of line
- """
- self.data.seek(0,0)
- self.defer.callback((self.data, line))
-
-
-class WriteBuffer:
- """Buffer up a bunch of writes before sending them all to a transport at once.
- """
- def __init__(self, transport, size=8192):
- self.bufferSize = size
- self.transport = transport
- self._length = 0
- self._writes = []
-
- def write(self, s):
- self._length += len(s)
- self._writes.append(s)
- if self._length > self.bufferSize:
- self.flush()
-
- def flush(self):
- if self._writes:
- self.transport.writeSequence(self._writes)
- self._writes = []
- self._length = 0
-
-
-class Command:
- _1_RESPONSES = ('CAPABILITY', 'FLAGS', 'LIST', 'LSUB', 'STATUS', 'SEARCH', 'NAMESPACE')
- _2_RESPONSES = ('EXISTS', 'EXPUNGE', 'FETCH', 'RECENT')
- _OK_RESPONSES = ('UIDVALIDITY', 'UNSEEN', 'READ-WRITE', 'READ-ONLY', 'UIDNEXT', 'PERMANENTFLAGS')
- defer = None
-
- def __init__(self, command, args=None, wantResponse=(),
- continuation=None, *contArgs, **contKw):
- self.command = command
- self.args = args
- self.wantResponse = wantResponse
- self.continuation = lambda x: continuation(x, *contArgs, **contKw)
- self.lines = []
-
- def format(self, tag):
- if self.args is None:
- return ' '.join((tag, self.command))
- return ' '.join((tag, self.command, self.args))
-
- def finish(self, lastLine, unusedCallback):
- send = []
- unuse = []
- for L in self.lines:
- names = parseNestedParens(L)
- N = len(names)
- if (N >= 1 and names[0] in self._1_RESPONSES or
- N >= 2 and names[1] in self._2_RESPONSES or
- N >= 2 and names[0] == 'OK' and isinstance(names[1], types.ListType) and names[1][0] in self._OK_RESPONSES):
- send.append(names)
- else:
- unuse.append(names)
- d, self.defer = self.defer, None
- d.callback((send, lastLine))
- if unuse:
- unusedCallback(unuse)
-
-class LOGINCredentials(cred.credentials.UsernamePassword):
- def __init__(self):
- self.challenges = ['Password\0', 'User Name\0']
- self.responses = ['password', 'username']
- cred.credentials.UsernamePassword.__init__(self, None, None)
-
- def getChallenge(self):
- return self.challenges.pop()
-
- def setResponse(self, response):
- setattr(self, self.responses.pop(), response)
-
- def moreChallenges(self):
- return bool(self.challenges)
-
-class PLAINCredentials(cred.credentials.UsernamePassword):
- def __init__(self):
- cred.credentials.UsernamePassword.__init__(self, None, None)
-
- def getChallenge(self):
- return ''
-
- def setResponse(self, response):
- parts = response.split('\0')
- if len(parts) != 3:
- raise IllegalClientResponse("Malformed Response - wrong number of parts")
- useless, self.username, self.password = parts
-
- def moreChallenges(self):
- return False
-
-class IMAP4Exception(Exception):
- def __init__(self, *args):
- Exception.__init__(self, *args)
-
-class IllegalClientResponse(IMAP4Exception): pass
-
-class IllegalOperation(IMAP4Exception): pass
-
-class IllegalMailboxEncoding(IMAP4Exception): pass
-
-class IMailboxListener(Interface):
- """Interface for objects interested in mailbox events"""
-
- def modeChanged(writeable):
- """Indicates that the write status of a mailbox has changed.
-
- @type writeable: C{bool}
- @param writeable: A true value if write is now allowed, false
- otherwise.
- """
-
- def flagsChanged(newFlags):
- """Indicates that the flags of one or more messages have changed.
-
- @type newFlags: C{dict}
- @param newFlags: A mapping of message identifiers to tuples of flags
- now set on that message.
- """
-
- def newMessages(exists, recent):
- """Indicates that the number of messages in a mailbox has changed.
-
- @type exists: C{int} or C{None}
- @param exists: The total number of messages now in this mailbox.
- If the total number of messages has not changed, this should be
- C{None}.
-
- @type recent: C{int}
- @param recent: The number of messages now flagged \\Recent.
- If the number of recent messages has not changed, this should be
- C{None}.
- """
-
-class IMAP4Server(basic.LineReceiver, policies.TimeoutMixin):
- """
- Protocol implementation for an IMAP4rev1 server.
-
- The server can be in any of four states:
- - Non-authenticated
- - Authenticated
- - Selected
- - Logout
- """
- implements(IMailboxListener)
-
- # Identifier for this server software
- IDENT = 'Twisted IMAP4rev1 Ready'
-
- # Number of seconds before idle timeout
- # Initially 1 minute. Raised to 30 minutes after login.
- timeOut = 60
-
- POSTAUTH_TIMEOUT = 60 * 30
-
- # Whether STARTTLS has been issued successfully yet or not.
- startedTLS = False
-
- # Whether our transport supports TLS
- canStartTLS = False
-
- # Mapping of tags to commands we have received
- tags = None
-
- # The object which will handle logins for us
- portal = None
-
- # The account object for this connection
- account = None
-
- # Logout callback
- _onLogout = None
-
- # The currently selected mailbox
- mbox = None
-
- # Command data to be processed when literal data is received
- _pendingLiteral = None
-
- # Maximum length to accept for a "short" string literal
- _literalStringLimit = 4096
-
- # IChallengeResponse factories for AUTHENTICATE command
- challengers = None
-
- # Search terms the implementation of which needs to be passed both the last
- # message identifier (UID) and the last sequence id.
- _requiresLastMessageInfo = set(["OR", "NOT", "UID"])
-
- state = 'unauth'
-
- parseState = 'command'
-
- def __init__(self, chal = None, contextFactory = None, scheduler = None):
- if chal is None:
- chal = {}
- self.challengers = chal
- self.ctx = contextFactory
- if scheduler is None:
- scheduler = iterateInReactor
- self._scheduler = scheduler
- self._queuedAsync = []
-
- def capabilities(self):
- cap = {'AUTH': self.challengers.keys()}
- if self.ctx and self.canStartTLS:
- if not self.startedTLS and interfaces.ISSLTransport(self.transport, None) is None:
- cap['LOGINDISABLED'] = None
- cap['STARTTLS'] = None
- cap['NAMESPACE'] = None
- cap['IDLE'] = None
- return cap
-
- def connectionMade(self):
- self.tags = {}
- self.canStartTLS = interfaces.ITLSTransport(self.transport, None) is not None
- self.setTimeout(self.timeOut)
- self.sendServerGreeting()
-
- def connectionLost(self, reason):
- self.setTimeout(None)
- if self._onLogout:
- self._onLogout()
- self._onLogout = None
-
- def timeoutConnection(self):
- self.sendLine('* BYE Autologout; connection idle too long')
- self.transport.loseConnection()
- if self.mbox:
- self.mbox.removeListener(self)
- cmbx = ICloseableMailbox(self.mbox, None)
- if cmbx is not None:
- maybeDeferred(cmbx.close).addErrback(log.err)
- self.mbox = None
- self.state = 'timeout'
-
- def rawDataReceived(self, data):
- self.resetTimeout()
- passon = self._pendingLiteral.write(data)
- if passon is not None:
- self.setLineMode(passon)
-
- # Avoid processing commands while buffers are being dumped to
- # our transport
- blocked = None
-
- def _unblock(self):
- commands = self.blocked
- self.blocked = None
- while commands and self.blocked is None:
- self.lineReceived(commands.pop(0))
- if self.blocked is not None:
- self.blocked.extend(commands)
-
- def lineReceived(self, line):
- if self.blocked is not None:
- self.blocked.append(line)
- return
-
- self.resetTimeout()
-
- f = getattr(self, 'parse_' + self.parseState)
- try:
- f(line)
- except Exception, e:
- self.sendUntaggedResponse('BAD Server error: ' + str(e))
- log.err()
-
- def parse_command(self, line):
- args = line.split(None, 2)
- rest = None
- if len(args) == 3:
- tag, cmd, rest = args
- elif len(args) == 2:
- tag, cmd = args
- elif len(args) == 1:
- tag = args[0]
- self.sendBadResponse(tag, 'Missing command')
- return None
- else:
- self.sendBadResponse(None, 'Null command')
- return None
-
- cmd = cmd.upper()
- try:
- return self.dispatchCommand(tag, cmd, rest)
- except IllegalClientResponse, e:
- self.sendBadResponse(tag, 'Illegal syntax: ' + str(e))
- except IllegalOperation, e:
- self.sendNegativeResponse(tag, 'Illegal operation: ' + str(e))
- except IllegalMailboxEncoding, e:
- self.sendNegativeResponse(tag, 'Illegal mailbox name: ' + str(e))
-
- def parse_pending(self, line):
- d = self._pendingLiteral
- self._pendingLiteral = None
- self.parseState = 'command'
- d.callback(line)
-
- def dispatchCommand(self, tag, cmd, rest, uid=None):
- f = self.lookupCommand(cmd)
- if f:
- fn = f[0]
- parseargs = f[1:]
- self.__doCommand(tag, fn, [self, tag], parseargs, rest, uid)
- else:
- self.sendBadResponse(tag, 'Unsupported command')
-
- def lookupCommand(self, cmd):
- return getattr(self, '_'.join((self.state, cmd.upper())), None)
-
- def __doCommand(self, tag, handler, args, parseargs, line, uid):
- for (i, arg) in enumerate(parseargs):
- if callable(arg):
- parseargs = parseargs[i+1:]
- maybeDeferred(arg, self, line).addCallback(
- self.__cbDispatch, tag, handler, args,
- parseargs, uid).addErrback(self.__ebDispatch, tag)
- return
- else:
- args.append(arg)
-
- if line:
- # Too many arguments
- raise IllegalClientResponse("Too many arguments for command: " + repr(line))
-
- if uid is not None:
- handler(uid=uid, *args)
- else:
- handler(*args)
-
- def __cbDispatch(self, (arg, rest), tag, fn, args, parseargs, uid):
- args.append(arg)
- self.__doCommand(tag, fn, args, parseargs, rest, uid)
-
- def __ebDispatch(self, failure, tag):
- if failure.check(IllegalClientResponse):
- self.sendBadResponse(tag, 'Illegal syntax: ' + str(failure.value))
- elif failure.check(IllegalOperation):
- self.sendNegativeResponse(tag, 'Illegal operation: ' +
- str(failure.value))
- elif failure.check(IllegalMailboxEncoding):
- self.sendNegativeResponse(tag, 'Illegal mailbox name: ' +
- str(failure.value))
- else:
- self.sendBadResponse(tag, 'Server error: ' + str(failure.value))
- log.err(failure)
-
- def _stringLiteral(self, size):
- if size > self._literalStringLimit:
- raise IllegalClientResponse(
- "Literal too long! I accept at most %d octets" %
- (self._literalStringLimit,))
- d = defer.Deferred()
- self.parseState = 'pending'
- self._pendingLiteral = LiteralString(size, d)
- self.sendContinuationRequest('Ready for %d octets of text' % size)
- self.setRawMode()
- return d
-
- def _fileLiteral(self, size):
- d = defer.Deferred()
- self.parseState = 'pending'
- self._pendingLiteral = LiteralFile(size, d)
- self.sendContinuationRequest('Ready for %d octets of data' % size)
- self.setRawMode()
- return d
-
- def arg_astring(self, line):
- """
- Parse an astring from the line, return (arg, rest), possibly
- via a deferred (to handle literals)
- """
- line = line.strip()
- if not line:
- raise IllegalClientResponse("Missing argument")
- d = None
- arg, rest = None, None
- if line[0] == '"':
- try:
- spam, arg, rest = line.split('"',2)
- rest = rest[1:] # Strip space
- except ValueError:
- raise IllegalClientResponse("Unmatched quotes")
- elif line[0] == '{':
- # literal
- if line[-1] != '}':
- raise IllegalClientResponse("Malformed literal")
- try:
- size = int(line[1:-1])
- except ValueError:
- raise IllegalClientResponse("Bad literal size: " + line[1:-1])
- d = self._stringLiteral(size)
- else:
- arg = line.split(' ',1)
- if len(arg) == 1:
- arg.append('')
- arg, rest = arg
- return d or (arg, rest)
-
- # ATOM: Any CHAR except ( ) { % * " \ ] CTL SP (CHAR is 7bit)
- atomre = re.compile(r'(?P<atom>[^\](){%*"\\\x00-\x20\x80-\xff]+)( (?P<rest>.*$)|$)')
-
- def arg_atom(self, line):
- """
- Parse an atom from the line
- """
- if not line:
- raise IllegalClientResponse("Missing argument")
- m = self.atomre.match(line)
- if m:
- return m.group('atom'), m.group('rest')
- else:
- raise IllegalClientResponse("Malformed ATOM")
-
- def arg_plist(self, line):
- """
- Parse a (non-nested) parenthesised list from the line
- """
- if not line:
- raise IllegalClientResponse("Missing argument")
-
- if line[0] != "(":
- raise IllegalClientResponse("Missing parenthesis")
-
- i = line.find(")")
-
- if i == -1:
- raise IllegalClientResponse("Mismatched parenthesis")
-
- return (parseNestedParens(line[1:i],0), line[i+2:])
-
- def arg_literal(self, line):
- """
- Parse a literal from the line
- """
- if not line:
- raise IllegalClientResponse("Missing argument")
-
- if line[0] != '{':
- raise IllegalClientResponse("Missing literal")
-
- if line[-1] != '}':
- raise IllegalClientResponse("Malformed literal")
-
- try:
- size = int(line[1:-1])
- except ValueError:
- raise IllegalClientResponse("Bad literal size: " + line[1:-1])
-
- return self._fileLiteral(size)
-
- def arg_searchkeys(self, line):
- """
- searchkeys
- """
- query = parseNestedParens(line)
- # XXX Should really use list of search terms and parse into
- # a proper tree
-
- return (query, '')
-
- def arg_seqset(self, line):
- """
- sequence-set
- """
- rest = ''
- arg = line.split(' ',1)
- if len(arg) == 2:
- rest = arg[1]
- arg = arg[0]
-
- try:
- return (parseIdList(arg), rest)
- except IllegalIdentifierError, e:
- raise IllegalClientResponse("Bad message number " + str(e))
-
- def arg_fetchatt(self, line):
- """
- fetch-att
- """
- p = _FetchParser()
- p.parseString(line)
- return (p.result, '')
-
- def arg_flaglist(self, line):
- """
- Flag part of store-att-flag
- """
- flags = []
- if line[0] == '(':
- if line[-1] != ')':
- raise IllegalClientResponse("Mismatched parenthesis")
- line = line[1:-1]
-
- while line:
- m = self.atomre.search(line)
- if not m:
- raise IllegalClientResponse("Malformed flag")
- if line[0] == '\\' and m.start() == 1:
- flags.append('\\' + m.group('atom'))
- elif m.start() == 0:
- flags.append(m.group('atom'))
- else:
- raise IllegalClientResponse("Malformed flag")
- line = m.group('rest')
-
- return (flags, '')
-
- def arg_line(self, line):
- """
- Command line of UID command
- """
- return (line, '')
-
- def opt_plist(self, line):
- """
- Optional parenthesised list
- """
- if line.startswith('('):
- return self.arg_plist(line)
- else:
- return (None, line)
-
- def opt_datetime(self, line):
- """
- Optional date-time string
- """
- if line.startswith('"'):
- try:
- spam, date, rest = line.split('"',2)
- except IndexError:
- raise IllegalClientResponse("Malformed date-time")
- return (date, rest[1:])
- else:
- return (None, line)
-
- def opt_charset(self, line):
- """
- Optional charset of SEARCH command
- """
- if line[:7].upper() == 'CHARSET':
- arg = line.split(' ',2)
- if len(arg) == 1:
- raise IllegalClientResponse("Missing charset identifier")
- if len(arg) == 2:
- arg.append('')
- spam, arg, rest = arg
- return (arg, rest)
- else:
- return (None, line)
-
- def sendServerGreeting(self):
- msg = '[CAPABILITY %s] %s' % (' '.join(self.listCapabilities()), self.IDENT)
- self.sendPositiveResponse(message=msg)
-
- def sendBadResponse(self, tag = None, message = ''):
- self._respond('BAD', tag, message)
-
- def sendPositiveResponse(self, tag = None, message = ''):
- self._respond('OK', tag, message)
-
- def sendNegativeResponse(self, tag = None, message = ''):
- self._respond('NO', tag, message)
-
- def sendUntaggedResponse(self, message, async=False):
- if not async or (self.blocked is None):
- self._respond(message, None, None)
- else:
- self._queuedAsync.append(message)
-
- def sendContinuationRequest(self, msg = 'Ready for additional command text'):
- if msg:
- self.sendLine('+ ' + msg)
- else:
- self.sendLine('+')
-
- def _respond(self, state, tag, message):
- if state in ('OK', 'NO', 'BAD') and self._queuedAsync:
- lines = self._queuedAsync
- self._queuedAsync = []
- for msg in lines:
- self._respond(msg, None, None)
- if not tag:
- tag = '*'
- if message:
- self.sendLine(' '.join((tag, state, message)))
- else:
- self.sendLine(' '.join((tag, state)))
-
- def listCapabilities(self):
- caps = ['IMAP4rev1']
- for c, v in self.capabilities().iteritems():
- if v is None:
- caps.append(c)
- elif len(v):
- caps.extend([('%s=%s' % (c, cap)) for cap in v])
- return caps
-
- def do_CAPABILITY(self, tag):
- self.sendUntaggedResponse('CAPABILITY ' + ' '.join(self.listCapabilities()))
- self.sendPositiveResponse(tag, 'CAPABILITY completed')
-
- unauth_CAPABILITY = (do_CAPABILITY,)
- auth_CAPABILITY = unauth_CAPABILITY
- select_CAPABILITY = unauth_CAPABILITY
- logout_CAPABILITY = unauth_CAPABILITY
-
- def do_LOGOUT(self, tag):
- self.sendUntaggedResponse('BYE Nice talking to you')
- self.sendPositiveResponse(tag, 'LOGOUT successful')
- self.transport.loseConnection()
-
- unauth_LOGOUT = (do_LOGOUT,)
- auth_LOGOUT = unauth_LOGOUT
- select_LOGOUT = unauth_LOGOUT
- logout_LOGOUT = unauth_LOGOUT
-
- def do_NOOP(self, tag):
- self.sendPositiveResponse(tag, 'NOOP No operation performed')
-
- unauth_NOOP = (do_NOOP,)
- auth_NOOP = unauth_NOOP
- select_NOOP = unauth_NOOP
- logout_NOOP = unauth_NOOP
-
- def do_AUTHENTICATE(self, tag, args):
- args = args.upper().strip()
- if args not in self.challengers:
- self.sendNegativeResponse(tag, 'AUTHENTICATE method unsupported')
- else:
- self.authenticate(self.challengers[args](), tag)
-
- unauth_AUTHENTICATE = (do_AUTHENTICATE, arg_atom)
-
- def authenticate(self, chal, tag):
- if self.portal is None:
- self.sendNegativeResponse(tag, 'Temporary authentication failure')
- return
-
- self._setupChallenge(chal, tag)
-
- def _setupChallenge(self, chal, tag):
- try:
- challenge = chal.getChallenge()
- except Exception, e:
- self.sendBadResponse(tag, 'Server error: ' + str(e))
- else:
- coded = base64.encodestring(challenge)[:-1]
- self.parseState = 'pending'
- self._pendingLiteral = defer.Deferred()
- self.sendContinuationRequest(coded)
- self._pendingLiteral.addCallback(self.__cbAuthChunk, chal, tag)
- self._pendingLiteral.addErrback(self.__ebAuthChunk, tag)
-
- def __cbAuthChunk(self, result, chal, tag):
- try:
- uncoded = base64.decodestring(result)
- except binascii.Error:
- raise IllegalClientResponse("Malformed Response - not base64")
-
- chal.setResponse(uncoded)
- if chal.moreChallenges():
- self._setupChallenge(chal, tag)
- else:
- self.portal.login(chal, None, IAccount).addCallbacks(
- self.__cbAuthResp,
- self.__ebAuthResp,
- (tag,), None, (tag,), None
- )
-
- def __cbAuthResp(self, (iface, avatar, logout), tag):
- assert iface is IAccount, "IAccount is the only supported interface"
- self.account = avatar
- self.state = 'auth'
- self._onLogout = logout
- self.sendPositiveResponse(tag, 'Authentication successful')
- self.setTimeout(self.POSTAUTH_TIMEOUT)
-
- def __ebAuthResp(self, failure, tag):
- if failure.check(cred.error.UnauthorizedLogin):
- self.sendNegativeResponse(tag, 'Authentication failed: unauthorized')
- elif failure.check(cred.error.UnhandledCredentials):
- self.sendNegativeResponse(tag, 'Authentication failed: server misconfigured')
- else:
- self.sendBadResponse(tag, 'Server error: login failed unexpectedly')
- log.err(failure)
-
- def __ebAuthChunk(self, failure, tag):
- self.sendNegativeResponse(tag, 'Authentication failed: ' + str(failure.value))
-
- def do_STARTTLS(self, tag):
- if self.startedTLS:
- self.sendNegativeResponse(tag, 'TLS already negotiated')
- elif self.ctx and self.canStartTLS:
- self.sendPositiveResponse(tag, 'Begin TLS negotiation now')
- self.transport.startTLS(self.ctx)
- self.startedTLS = True
- self.challengers = self.challengers.copy()
- if 'LOGIN' not in self.challengers:
- self.challengers['LOGIN'] = LOGINCredentials
- if 'PLAIN' not in self.challengers:
- self.challengers['PLAIN'] = PLAINCredentials
- else:
- self.sendNegativeResponse(tag, 'TLS not available')
-
- unauth_STARTTLS = (do_STARTTLS,)
-
- def do_LOGIN(self, tag, user, passwd):
- if 'LOGINDISABLED' in self.capabilities():
- self.sendBadResponse(tag, 'LOGIN is disabled before STARTTLS')
- return
-
- maybeDeferred(self.authenticateLogin, user, passwd
- ).addCallback(self.__cbLogin, tag
- ).addErrback(self.__ebLogin, tag
- )
-
- unauth_LOGIN = (do_LOGIN, arg_astring, arg_astring)
-
- def authenticateLogin(self, user, passwd):
- """Lookup the account associated with the given parameters
-
- Override this method to define the desired authentication behavior.
-
- The default behavior is to defer authentication to C{self.portal}
- if it is not None, or to deny the login otherwise.
-
- @type user: C{str}
- @param user: The username to lookup
-
- @type passwd: C{str}
- @param passwd: The password to login with
- """
- if self.portal:
- return self.portal.login(
- cred.credentials.UsernamePassword(user, passwd),
- None, IAccount
- )
- raise cred.error.UnauthorizedLogin()
-
- def __cbLogin(self, (iface, avatar, logout), tag):
- if iface is not IAccount:
- self.sendBadResponse(tag, 'Server error: login returned unexpected value')
- log.err("__cbLogin called with %r, IAccount expected" % (iface,))
- else:
- self.account = avatar
- self._onLogout = logout
- self.sendPositiveResponse(tag, 'LOGIN succeeded')
- self.state = 'auth'
- self.setTimeout(self.POSTAUTH_TIMEOUT)
-
- def __ebLogin(self, failure, tag):
- if failure.check(cred.error.UnauthorizedLogin):
- self.sendNegativeResponse(tag, 'LOGIN failed')
- else:
- self.sendBadResponse(tag, 'Server error: ' + str(failure.value))
- log.err(failure)
-
- def do_NAMESPACE(self, tag):
- personal = public = shared = None
- np = INamespacePresenter(self.account, None)
- if np is not None:
- personal = np.getPersonalNamespaces()
- public = np.getSharedNamespaces()
- shared = np.getSharedNamespaces()
- self.sendUntaggedResponse('NAMESPACE ' + collapseNestedLists([personal, public, shared]))
- self.sendPositiveResponse(tag, "NAMESPACE command completed")
-
- auth_NAMESPACE = (do_NAMESPACE,)
- select_NAMESPACE = auth_NAMESPACE
-
- def _parseMbox(self, name):
- if isinstance(name, unicode):
- return name
- try:
- return name.decode('imap4-utf-7')
- except:
- log.err()
- raise IllegalMailboxEncoding(name)
-
- def _selectWork(self, tag, name, rw, cmdName):
- if self.mbox:
- self.mbox.removeListener(self)
- cmbx = ICloseableMailbox(self.mbox, None)
- if cmbx is not None:
- maybeDeferred(cmbx.close).addErrback(log.err)
- self.mbox = None
- self.state = 'auth'
-
- name = self._parseMbox(name)
- maybeDeferred(self.account.select, self._parseMbox(name), rw
- ).addCallback(self._cbSelectWork, cmdName, tag
- ).addErrback(self._ebSelectWork, cmdName, tag
- )
-
- def _ebSelectWork(self, failure, cmdName, tag):
- self.sendBadResponse(tag, "%s failed: Server error" % (cmdName,))
- log.err(failure)
-
- def _cbSelectWork(self, mbox, cmdName, tag):
- if mbox is None:
- self.sendNegativeResponse(tag, 'No such mailbox')
- return
- if '\\noselect' in [s.lower() for s in mbox.getFlags()]:
- self.sendNegativeResponse(tag, 'Mailbox cannot be selected')
- return
-
- flags = mbox.getFlags()
- self.sendUntaggedResponse(str(mbox.getMessageCount()) + ' EXISTS')
- self.sendUntaggedResponse(str(mbox.getRecentCount()) + ' RECENT')
- self.sendUntaggedResponse('FLAGS (%s)' % ' '.join(flags))
- self.sendPositiveResponse(None, '[UIDVALIDITY %d]' % mbox.getUIDValidity())
-
- s = mbox.isWriteable() and 'READ-WRITE' or 'READ-ONLY'
- mbox.addListener(self)
- self.sendPositiveResponse(tag, '[%s] %s successful' % (s, cmdName))
- self.state = 'select'
- self.mbox = mbox
-
- auth_SELECT = ( _selectWork, arg_astring, 1, 'SELECT' )
- select_SELECT = auth_SELECT
-
- auth_EXAMINE = ( _selectWork, arg_astring, 0, 'EXAMINE' )
- select_EXAMINE = auth_EXAMINE
-
-
- def do_IDLE(self, tag):
- self.sendContinuationRequest(None)
- self.parseTag = tag
- self.lastState = self.parseState
- self.parseState = 'idle'
-
- def parse_idle(self, *args):
- self.parseState = self.lastState
- del self.lastState
- self.sendPositiveResponse(self.parseTag, "IDLE terminated")
- del self.parseTag
-
- select_IDLE = ( do_IDLE, )
- auth_IDLE = select_IDLE
-
-
- def do_CREATE(self, tag, name):
- name = self._parseMbox(name)
- try:
- result = self.account.create(name)
- except MailboxException, c:
- self.sendNegativeResponse(tag, str(c))
- except:
- self.sendBadResponse(tag, "Server error encountered while creating mailbox")
- log.err()
- else:
- if result:
- self.sendPositiveResponse(tag, 'Mailbox created')
- else:
- self.sendNegativeResponse(tag, 'Mailbox not created')
-
- auth_CREATE = (do_CREATE, arg_astring)
- select_CREATE = auth_CREATE
-
- def do_DELETE(self, tag, name):
- name = self._parseMbox(name)
- if name.lower() == 'inbox':
- self.sendNegativeResponse(tag, 'You cannot delete the inbox')
- return
- try:
- self.account.delete(name)
- except MailboxException, m:
- self.sendNegativeResponse(tag, str(m))
- except:
- self.sendBadResponse(tag, "Server error encountered while deleting mailbox")
- log.err()
- else:
- self.sendPositiveResponse(tag, 'Mailbox deleted')
-
- auth_DELETE = (do_DELETE, arg_astring)
- select_DELETE = auth_DELETE
-
- def do_RENAME(self, tag, oldname, newname):
- oldname, newname = [self._parseMbox(n) for n in oldname, newname]
- if oldname.lower() == 'inbox' or newname.lower() == 'inbox':
- self.sendNegativeResponse(tag, 'You cannot rename the inbox, or rename another mailbox to inbox.')
- return
- try:
- self.account.rename(oldname, newname)
- except TypeError:
- self.sendBadResponse(tag, 'Invalid command syntax')
- except MailboxException, m:
- self.sendNegativeResponse(tag, str(m))
- except:
- self.sendBadResponse(tag, "Server error encountered while renaming mailbox")
- log.err()
- else:
- self.sendPositiveResponse(tag, 'Mailbox renamed')
-
- auth_RENAME = (do_RENAME, arg_astring, arg_astring)
- select_RENAME = auth_RENAME
-
- def do_SUBSCRIBE(self, tag, name):
- name = self._parseMbox(name)
- try:
- self.account.subscribe(name)
- except MailboxException, m:
- self.sendNegativeResponse(tag, str(m))
- except:
- self.sendBadResponse(tag, "Server error encountered while subscribing to mailbox")
- log.err()
- else:
- self.sendPositiveResponse(tag, 'Subscribed')
-
- auth_SUBSCRIBE = (do_SUBSCRIBE, arg_astring)
- select_SUBSCRIBE = auth_SUBSCRIBE
-
- def do_UNSUBSCRIBE(self, tag, name):
- name = self._parseMbox(name)
- try:
- self.account.unsubscribe(name)
- except MailboxException, m:
- self.sendNegativeResponse(tag, str(m))
- except:
- self.sendBadResponse(tag, "Server error encountered while unsubscribing from mailbox")
- log.err()
- else:
- self.sendPositiveResponse(tag, 'Unsubscribed')
-
- auth_UNSUBSCRIBE = (do_UNSUBSCRIBE, arg_astring)
- select_UNSUBSCRIBE = auth_UNSUBSCRIBE
-
- def _listWork(self, tag, ref, mbox, sub, cmdName):
- mbox = self._parseMbox(mbox)
- maybeDeferred(self.account.listMailboxes, ref, mbox
- ).addCallback(self._cbListWork, tag, sub, cmdName
- ).addErrback(self._ebListWork, tag
- )
-
- def _cbListWork(self, mailboxes, tag, sub, cmdName):
- for (name, box) in mailboxes:
- if not sub or self.account.isSubscribed(name):
- flags = box.getFlags()
- delim = box.getHierarchicalDelimiter()
- resp = (DontQuoteMe(cmdName), map(DontQuoteMe, flags), delim, name.encode('imap4-utf-7'))
- self.sendUntaggedResponse(collapseNestedLists(resp))
- self.sendPositiveResponse(tag, '%s completed' % (cmdName,))
-
- def _ebListWork(self, failure, tag):
- self.sendBadResponse(tag, "Server error encountered while listing mailboxes.")
- log.err(failure)
-
- auth_LIST = (_listWork, arg_astring, arg_astring, 0, 'LIST')
- select_LIST = auth_LIST
-
- auth_LSUB = (_listWork, arg_astring, arg_astring, 1, 'LSUB')
- select_LSUB = auth_LSUB
-
- def do_STATUS(self, tag, mailbox, names):
- mailbox = self._parseMbox(mailbox)
- maybeDeferred(self.account.select, mailbox, 0
- ).addCallback(self._cbStatusGotMailbox, tag, mailbox, names
- ).addErrback(self._ebStatusGotMailbox, tag
- )
-
- def _cbStatusGotMailbox(self, mbox, tag, mailbox, names):
- if mbox:
- maybeDeferred(mbox.requestStatus, names).addCallbacks(
- self.__cbStatus, self.__ebStatus,
- (tag, mailbox), None, (tag, mailbox), None
- )
- else:
- self.sendNegativeResponse(tag, "Could not open mailbox")
-
- def _ebStatusGotMailbox(self, failure, tag):
- self.sendBadResponse(tag, "Server error encountered while opening mailbox.")
- log.err(failure)
-
- auth_STATUS = (do_STATUS, arg_astring, arg_plist)
- select_STATUS = auth_STATUS
-
- def __cbStatus(self, status, tag, box):
- line = ' '.join(['%s %s' % x for x in status.iteritems()])
- self.sendUntaggedResponse('STATUS %s (%s)' % (box, line))
- self.sendPositiveResponse(tag, 'STATUS complete')
-
- def __ebStatus(self, failure, tag, box):
- self.sendBadResponse(tag, 'STATUS %s failed: %s' % (box, str(failure.value)))
-
- def do_APPEND(self, tag, mailbox, flags, date, message):
- mailbox = self._parseMbox(mailbox)
- maybeDeferred(self.account.select, mailbox
- ).addCallback(self._cbAppendGotMailbox, tag, flags, date, message
- ).addErrback(self._ebAppendGotMailbox, tag
- )
-
- def _cbAppendGotMailbox(self, mbox, tag, flags, date, message):
- if not mbox:
- self.sendNegativeResponse(tag, '[TRYCREATE] No such mailbox')
- return
-
- d = mbox.addMessage(message, flags, date)
- d.addCallback(self.__cbAppend, tag, mbox)
- d.addErrback(self.__ebAppend, tag)
-
- def _ebAppendGotMailbox(self, failure, tag):
- self.sendBadResponse(tag, "Server error encountered while opening mailbox.")
- log.err(failure)
-
- auth_APPEND = (do_APPEND, arg_astring, opt_plist, opt_datetime,
- arg_literal)
- select_APPEND = auth_APPEND
-
- def __cbAppend(self, result, tag, mbox):
- self.sendUntaggedResponse('%d EXISTS' % mbox.getMessageCount())
- self.sendPositiveResponse(tag, 'APPEND complete')
-
- def __ebAppend(self, failure, tag):
- self.sendBadResponse(tag, 'APPEND failed: ' + str(failure.value))
-
- def do_CHECK(self, tag):
- d = self.checkpoint()
- if d is None:
- self.__cbCheck(None, tag)
- else:
- d.addCallbacks(
- self.__cbCheck,
- self.__ebCheck,
- callbackArgs=(tag,),
- errbackArgs=(tag,)
- )
- select_CHECK = (do_CHECK,)
-
- def __cbCheck(self, result, tag):
- self.sendPositiveResponse(tag, 'CHECK completed')
-
- def __ebCheck(self, failure, tag):
- self.sendBadResponse(tag, 'CHECK failed: ' + str(failure.value))
-
- def checkpoint(self):
- """Called when the client issues a CHECK command.
-
- This should perform any checkpoint operations required by the server.
- It may be a long running operation, but may not block. If it returns
- a deferred, the client will only be informed of success (or failure)
- when the deferred's callback (or errback) is invoked.
- """
- return None
-
- def do_CLOSE(self, tag):
- d = None
- if self.mbox.isWriteable():
- d = maybeDeferred(self.mbox.expunge)
- cmbx = ICloseableMailbox(self.mbox, None)
- if cmbx is not None:
- if d is not None:
- d.addCallback(lambda result: cmbx.close())
- else:
- d = maybeDeferred(cmbx.close)
- if d is not None:
- d.addCallbacks(self.__cbClose, self.__ebClose, (tag,), None, (tag,), None)
- else:
- self.__cbClose(None, tag)
-
- select_CLOSE = (do_CLOSE,)
-
- def __cbClose(self, result, tag):
- self.sendPositiveResponse(tag, 'CLOSE completed')
- self.mbox.removeListener(self)
- self.mbox = None
- self.state = 'auth'
-
- def __ebClose(self, failure, tag):
- self.sendBadResponse(tag, 'CLOSE failed: ' + str(failure.value))
-
- def do_EXPUNGE(self, tag):
- if self.mbox.isWriteable():
- maybeDeferred(self.mbox.expunge).addCallbacks(
- self.__cbExpunge, self.__ebExpunge, (tag,), None, (tag,), None
- )
- else:
- self.sendNegativeResponse(tag, 'EXPUNGE ignored on read-only mailbox')
-
- select_EXPUNGE = (do_EXPUNGE,)
-
- def __cbExpunge(self, result, tag):
- for e in result:
- self.sendUntaggedResponse('%d EXPUNGE' % e)
- self.sendPositiveResponse(tag, 'EXPUNGE completed')
-
- def __ebExpunge(self, failure, tag):
- self.sendBadResponse(tag, 'EXPUNGE failed: ' + str(failure.value))
- log.err(failure)
-
- def do_SEARCH(self, tag, charset, query, uid=0):
- sm = ISearchableMailbox(self.mbox, None)
- if sm is not None:
- maybeDeferred(sm.search, query, uid=uid
- ).addCallback(self.__cbSearch, tag, self.mbox, uid
- ).addErrback(self.__ebSearch, tag)
- else:
- # that's not the ideal way to get all messages, there should be a
- # method on mailboxes that gives you all of them
- s = parseIdList('1:*')
- maybeDeferred(self.mbox.fetch, s, uid=uid
- ).addCallback(self.__cbManualSearch,
- tag, self.mbox, query, uid
- ).addErrback(self.__ebSearch, tag)
-
-
- select_SEARCH = (do_SEARCH, opt_charset, arg_searchkeys)
-
- def __cbSearch(self, result, tag, mbox, uid):
- if uid:
- result = map(mbox.getUID, result)
- ids = ' '.join([str(i) for i in result])
- self.sendUntaggedResponse('SEARCH ' + ids)
- self.sendPositiveResponse(tag, 'SEARCH completed')
-
-
- def __cbManualSearch(self, result, tag, mbox, query, uid,
- searchResults=None):
- """
- Apply the search filter to a set of messages. Send the response to the
- client.
-
- @type result: C{list} of C{tuple} of (C{int}, provider of
- L{imap4.IMessage})
- @param result: A list two tuples of messages with their sequence ids,
- sorted by the ids in descending order.
-
- @type tag: C{str}
- @param tag: A command tag.
-
- @type mbox: Provider of L{imap4.IMailbox}
- @param mbox: The searched mailbox.
-
- @type query: C{list}
- @param query: A list representing the parsed form of the search query.
-
- @param uid: A flag indicating whether the search is over message
- sequence numbers or UIDs.
-
- @type searchResults: C{list}
- @param searchResults: The search results so far or C{None} if no
- results yet.
- """
- if searchResults is None:
- searchResults = []
- i = 0
-
- # result is a list of tuples (sequenceId, Message)
- lastSequenceId = result and result[-1][0]
- lastMessageId = result and result[-1][1].getUID()
-
- for (i, (id, msg)) in zip(range(5), result):
- # searchFilter and singleSearchStep will mutate the query. Dang.
- # Copy it here or else things will go poorly for subsequent
- # messages.
- if self._searchFilter(copy.deepcopy(query), id, msg,
- lastSequenceId, lastMessageId):
- if uid:
- searchResults.append(str(msg.getUID()))
- else:
- searchResults.append(str(id))
- if i == 4:
- from twisted.internet import reactor
- reactor.callLater(
- 0, self.__cbManualSearch, result[5:], tag, mbox, query, uid,
- searchResults)
- else:
- if searchResults:
- self.sendUntaggedResponse('SEARCH ' + ' '.join(searchResults))
- self.sendPositiveResponse(tag, 'SEARCH completed')
-
-
- def _searchFilter(self, query, id, msg, lastSequenceId, lastMessageId):
- """
- Pop search terms from the beginning of C{query} until there are none
- left and apply them to the given message.
-
- @param query: A list representing the parsed form of the search query.
-
- @param id: The sequence number of the message being checked.
-
- @param msg: The message being checked.
-
- @type lastSequenceId: C{int}
- @param lastSequenceId: The highest sequence number of any message in
- the mailbox being searched.
-
- @type lastMessageId: C{int}
- @param lastMessageId: The highest UID of any message in the mailbox
- being searched.
-
- @return: Boolean indicating whether all of the query terms match the
- message.
- """
- while query:
- if not self._singleSearchStep(query, id, msg,
- lastSequenceId, lastMessageId):
- return False
- return True
-
-
- def _singleSearchStep(self, query, id, msg, lastSequenceId, lastMessageId):
- """
- Pop one search term from the beginning of C{query} (possibly more than
- one element) and return whether it matches the given message.
-
- @param query: A list representing the parsed form of the search query.
-
- @param id: The sequence number of the message being checked.
-
- @param msg: The message being checked.
-
- @param lastSequenceId: The highest sequence number of any message in
- the mailbox being searched.
-
- @param lastMessageId: The highest UID of any message in the mailbox
- being searched.
-
- @return: Boolean indicating whether the query term matched the message.
- """
-
- q = query.pop(0)
- if isinstance(q, list):
- if not self._searchFilter(q, id, msg,
- lastSequenceId, lastMessageId):
- return False
- else:
- c = q.upper()
- if not c[:1].isalpha():
- # A search term may be a word like ALL, ANSWERED, BCC, etc (see
- # below) or it may be a message sequence set. Here we
- # recognize a message sequence set "N:M".
- messageSet = parseIdList(c, lastSequenceId)
- return id in messageSet
- else:
- f = getattr(self, 'search_' + c, None)
- if f is None:
- raise IllegalQueryError("Invalid search command %s" % c)
-
- if c in self._requiresLastMessageInfo:
- result = f(query, id, msg, (lastSequenceId,
- lastMessageId))
- else:
- result = f(query, id, msg)
-
- if not result:
- return False
- return True
-
- def search_ALL(self, query, id, msg):
- """
- Returns C{True} if the message matches the ALL search key (always).
-
- @type query: A C{list} of C{str}
- @param query: A list representing the parsed query string.
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- """
- return True
-
- def search_ANSWERED(self, query, id, msg):
- """
- Returns C{True} if the message has been answered.
-
- @type query: A C{list} of C{str}
- @param query: A list representing the parsed query string.
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- """
- return '\\Answered' in msg.getFlags()
-
- def search_BCC(self, query, id, msg):
- """
- Returns C{True} if the message has a BCC address matching the query.
-
- @type query: A C{list} of C{str}
- @param query: A list whose first element is a BCC C{str}
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- """
- bcc = msg.getHeaders(False, 'bcc').get('bcc', '')
- return bcc.lower().find(query.pop(0).lower()) != -1
-
- def search_BEFORE(self, query, id, msg):
- date = parseTime(query.pop(0))
- return rfc822.parsedate(msg.getInternalDate()) < date
-
- def search_BODY(self, query, id, msg):
- body = query.pop(0).lower()
- return text.strFile(body, msg.getBodyFile(), False)
-
- def search_CC(self, query, id, msg):
- cc = msg.getHeaders(False, 'cc').get('cc', '')
- return cc.lower().find(query.pop(0).lower()) != -1
-
- def search_DELETED(self, query, id, msg):
- return '\\Deleted' in msg.getFlags()
-
- def search_DRAFT(self, query, id, msg):
- return '\\Draft' in msg.getFlags()
-
- def search_FLAGGED(self, query, id, msg):
- return '\\Flagged' in msg.getFlags()
-
- def search_FROM(self, query, id, msg):
- fm = msg.getHeaders(False, 'from').get('from', '')
- return fm.lower().find(query.pop(0).lower()) != -1
-
- def search_HEADER(self, query, id, msg):
- hdr = query.pop(0).lower()
- hdr = msg.getHeaders(False, hdr).get(hdr, '')
- return hdr.lower().find(query.pop(0).lower()) != -1
-
- def search_KEYWORD(self, query, id, msg):
- query.pop(0)
- return False
-
- def search_LARGER(self, query, id, msg):
- return int(query.pop(0)) < msg.getSize()
-
- def search_NEW(self, query, id, msg):
- return '\\Recent' in msg.getFlags() and '\\Seen' not in msg.getFlags()
-
- def search_NOT(self, query, id, msg, (lastSequenceId, lastMessageId)):
- """
- Returns C{True} if the message does not match the query.
-
- @type query: A C{list} of C{str}
- @param query: A list representing the parsed form of the search query.
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- @param msg: The message being checked.
-
- @type lastSequenceId: C{int}
- @param lastSequenceId: The highest sequence number of a message in the
- mailbox.
-
- @type lastMessageId: C{int}
- @param lastMessageId: The highest UID of a message in the mailbox.
- """
- return not self._singleSearchStep(query, id, msg,
- lastSequenceId, lastMessageId)
-
- def search_OLD(self, query, id, msg):
- return '\\Recent' not in msg.getFlags()
-
- def search_ON(self, query, id, msg):
- date = parseTime(query.pop(0))
- return rfc822.parsedate(msg.getInternalDate()) == date
-
- def search_OR(self, query, id, msg, (lastSequenceId, lastMessageId)):
- """
- Returns C{True} if the message matches any of the first two query
- items.
-
- @type query: A C{list} of C{str}
- @param query: A list representing the parsed form of the search query.
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- @param msg: The message being checked.
-
- @type lastSequenceId: C{int}
- @param lastSequenceId: The highest sequence number of a message in the
- mailbox.
-
- @type lastMessageId: C{int}
- @param lastMessageId: The highest UID of a message in the mailbox.
- """
- a = self._singleSearchStep(query, id, msg,
- lastSequenceId, lastMessageId)
- b = self._singleSearchStep(query, id, msg,
- lastSequenceId, lastMessageId)
- return a or b
-
- def search_RECENT(self, query, id, msg):
- return '\\Recent' in msg.getFlags()
-
- def search_SEEN(self, query, id, msg):
- return '\\Seen' in msg.getFlags()
-
- def search_SENTBEFORE(self, query, id, msg):
- """
- Returns C{True} if the message date is earlier than the query date.
-
- @type query: A C{list} of C{str}
- @param query: A list whose first element starts with a stringified date
- that is a fragment of an L{imap4.Query()}. The date must be in the
- format 'DD-Mon-YYYY', for example '03-March-2003' or '03-Mar-2003'.
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- """
- date = msg.getHeaders(False, 'date').get('date', '')
- date = rfc822.parsedate(date)
- return date < parseTime(query.pop(0))
-
- def search_SENTON(self, query, id, msg):
- """
- Returns C{True} if the message date is the same as the query date.
-
- @type query: A C{list} of C{str}
- @param query: A list whose first element starts with a stringified date
- that is a fragment of an L{imap4.Query()}. The date must be in the
- format 'DD-Mon-YYYY', for example '03-March-2003' or '03-Mar-2003'.
-
- @type msg: Provider of L{imap4.IMessage}
- """
- date = msg.getHeaders(False, 'date').get('date', '')
- date = rfc822.parsedate(date)
- return date[:3] == parseTime(query.pop(0))[:3]
-
- def search_SENTSINCE(self, query, id, msg):
- """
- Returns C{True} if the message date is later than the query date.
-
- @type query: A C{list} of C{str}
- @param query: A list whose first element starts with a stringified date
- that is a fragment of an L{imap4.Query()}. The date must be in the
- format 'DD-Mon-YYYY', for example '03-March-2003' or '03-Mar-2003'.
-
- @type msg: Provider of L{imap4.IMessage}
- """
- date = msg.getHeaders(False, 'date').get('date', '')
- date = rfc822.parsedate(date)
- return date > parseTime(query.pop(0))
-
- def search_SINCE(self, query, id, msg):
- date = parseTime(query.pop(0))
- return rfc822.parsedate(msg.getInternalDate()) > date
-
- def search_SMALLER(self, query, id, msg):
- return int(query.pop(0)) > msg.getSize()
-
- def search_SUBJECT(self, query, id, msg):
- subj = msg.getHeaders(False, 'subject').get('subject', '')
- return subj.lower().find(query.pop(0).lower()) != -1
-
- def search_TEXT(self, query, id, msg):
- # XXX - This must search headers too
- body = query.pop(0).lower()
- return text.strFile(body, msg.getBodyFile(), False)
-
- def search_TO(self, query, id, msg):
- to = msg.getHeaders(False, 'to').get('to', '')
- return to.lower().find(query.pop(0).lower()) != -1
-
- def search_UID(self, query, id, msg, (lastSequenceId, lastMessageId)):
- """
- Returns C{True} if the message UID is in the range defined by the
- search query.
-
- @type query: A C{list} of C{str}
- @param query: A list representing the parsed form of the search
- query. Its first element should be a C{str} that can be interpreted
- as a sequence range, for example '2:4,5:*'.
-
- @type id: C{int}
- @param id: The sequence number of the message being checked.
-
- @type msg: Provider of L{imap4.IMessage}
- @param msg: The message being checked.
-
- @type lastSequenceId: C{int}
- @param lastSequenceId: The highest sequence number of a message in the
- mailbox.
-
- @type lastMessageId: C{int}
- @param lastMessageId: The highest UID of a message in the mailbox.
- """
- c = query.pop(0)
- m = parseIdList(c, lastMessageId)
- return msg.getUID() in m
-
- def search_UNANSWERED(self, query, id, msg):
- return '\\Answered' not in msg.getFlags()
-
- def search_UNDELETED(self, query, id, msg):
- return '\\Deleted' not in msg.getFlags()
-
- def search_UNDRAFT(self, query, id, msg):
- return '\\Draft' not in msg.getFlags()
-
- def search_UNFLAGGED(self, query, id, msg):
- return '\\Flagged' not in msg.getFlags()
-
- def search_UNKEYWORD(self, query, id, msg):
- query.pop(0)
- return False
-
- def search_UNSEEN(self, query, id, msg):
- return '\\Seen' not in msg.getFlags()
-
- def __ebSearch(self, failure, tag):
- self.sendBadResponse(tag, 'SEARCH failed: ' + str(failure.value))
- log.err(failure)
-
- def do_FETCH(self, tag, messages, query, uid=0):
- if query:
- self._oldTimeout = self.setTimeout(None)
- maybeDeferred(self.mbox.fetch, messages, uid=uid
- ).addCallback(iter
- ).addCallback(self.__cbFetch, tag, query, uid
- ).addErrback(self.__ebFetch, tag
- )
- else:
- self.sendPositiveResponse(tag, 'FETCH complete')
-
- select_FETCH = (do_FETCH, arg_seqset, arg_fetchatt)
-
- def __cbFetch(self, results, tag, query, uid):
- if self.blocked is None:
- self.blocked = []
- try:
- id, msg = results.next()
- except StopIteration:
- # The idle timeout was suspended while we delivered results,
- # restore it now.
- self.setTimeout(self._oldTimeout)
- del self._oldTimeout
-
- # All results have been processed, deliver completion notification.
-
- # It's important to run this *after* resetting the timeout to "rig
- # a race" in some test code. writing to the transport will
- # synchronously call test code, which synchronously loses the
- # connection, calling our connectionLost method, which cancels the
- # timeout. We want to make sure that timeout is cancelled *after*
- # we reset it above, so that the final state is no timed
- # calls. This avoids reactor uncleanliness errors in the test
- # suite.
- # XXX: Perhaps loopback should be fixed to not call the user code
- # synchronously in transport.write?
- self.sendPositiveResponse(tag, 'FETCH completed')
-
- # Instance state is now consistent again (ie, it is as though
- # the fetch command never ran), so allow any pending blocked
- # commands to execute.
- self._unblock()
- else:
- self.spewMessage(id, msg, query, uid
- ).addCallback(lambda _: self.__cbFetch(results, tag, query, uid)
- ).addErrback(self.__ebSpewMessage
- )
-
- def __ebSpewMessage(self, failure):
- # This indicates a programming error.
- # There's no reliable way to indicate anything to the client, since we
- # may have already written an arbitrary amount of data in response to
- # the command.
- log.err(failure)
- self.transport.loseConnection()
-
- def spew_envelope(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- _w('ENVELOPE ' + collapseNestedLists([getEnvelope(msg)]))
-
- def spew_flags(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- _w('FLAGS ' + '(%s)' % (' '.join(msg.getFlags())))
-
- def spew_internaldate(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- idate = msg.getInternalDate()
- ttup = rfc822.parsedate_tz(idate)
- if ttup is None:
- log.msg("%d:%r: unpareseable internaldate: %r" % (id, msg, idate))
- raise IMAP4Exception("Internal failure generating INTERNALDATE")
-
- # need to specify the month manually, as strftime depends on locale
- strdate = time.strftime("%d-%%s-%Y %H:%M:%S ", ttup[:9])
- odate = strdate % (_MONTH_NAMES[ttup[1]],)
- if ttup[9] is None:
- odate = odate + "+0000"
- else:
- if ttup[9] >= 0:
- sign = "+"
- else:
- sign = "-"
- odate = odate + sign + str(((abs(ttup[9]) // 3600) * 100 + (abs(ttup[9]) % 3600) // 60)).zfill(4)
- _w('INTERNALDATE ' + _quote(odate))
-
- def spew_rfc822header(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- hdrs = _formatHeaders(msg.getHeaders(True))
- _w('RFC822.HEADER ' + _literal(hdrs))
-
- def spew_rfc822text(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- _w('RFC822.TEXT ')
- _f()
- return FileProducer(msg.getBodyFile()
- ).beginProducing(self.transport
- )
-
- def spew_rfc822size(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- _w('RFC822.SIZE ' + str(msg.getSize()))
-
- def spew_rfc822(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- _w('RFC822 ')
- _f()
- mf = IMessageFile(msg, None)
- if mf is not None:
- return FileProducer(mf.open()
- ).beginProducing(self.transport
- )
- return MessageProducer(msg, None, self._scheduler
- ).beginProducing(self.transport
- )
-
- def spew_uid(self, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- _w('UID ' + str(msg.getUID()))
-
- def spew_bodystructure(self, id, msg, _w=None, _f=None):
- _w('BODYSTRUCTURE ' + collapseNestedLists([getBodyStructure(msg, True)]))
-
- def spew_body(self, part, id, msg, _w=None, _f=None):
- if _w is None:
- _w = self.transport.write
- for p in part.part:
- if msg.isMultipart():
- msg = msg.getSubPart(p)
- elif p > 0:
- # Non-multipart messages have an implicit first part but no
- # other parts - reject any request for any other part.
- raise TypeError("Requested subpart of non-multipart message")
-
- if part.header:
- hdrs = msg.getHeaders(part.header.negate, *part.header.fields)
- hdrs = _formatHeaders(hdrs)
- _w(str(part) + ' ' + _literal(hdrs))
- elif part.text:
- _w(str(part) + ' ')
- _f()
- return FileProducer(msg.getBodyFile()
- ).beginProducing(self.transport
- )
- elif part.mime:
- hdrs = _formatHeaders(msg.getHeaders(True))
- _w(str(part) + ' ' + _literal(hdrs))
- elif part.empty:
- _w(str(part) + ' ')
- _f()
- if part.part:
- return FileProducer(msg.getBodyFile()
- ).beginProducing(self.transport
- )
- else:
- mf = IMessageFile(msg, None)
- if mf is not None:
- return FileProducer(mf.open()).beginProducing(self.transport)
- return MessageProducer(msg, None, self._scheduler).beginProducing(self.transport)
-
- else:
- _w('BODY ' + collapseNestedLists([getBodyStructure(msg)]))
-
- def spewMessage(self, id, msg, query, uid):
- wbuf = WriteBuffer(self.transport)
- write = wbuf.write
- flush = wbuf.flush
- def start():
- write('* %d FETCH (' % (id,))
- def finish():
- write(')\r\n')
- def space():
- write(' ')
-
- def spew():
- seenUID = False
- start()
- for part in query:
- if part.type == 'uid':
- seenUID = True
- if part.type == 'body':
- yield self.spew_body(part, id, msg, write, flush)
- else:
- f = getattr(self, 'spew_' + part.type)
- yield f(id, msg, write, flush)
- if part is not query[-1]:
- space()
- if uid and not seenUID:
- space()
- yield self.spew_uid(id, msg, write, flush)
- finish()
- flush()
- return self._scheduler(spew())
-
- def __ebFetch(self, failure, tag):
- self.setTimeout(self._oldTimeout)
- del self._oldTimeout
- log.err(failure)
- self.sendBadResponse(tag, 'FETCH failed: ' + str(failure.value))
-
- def do_STORE(self, tag, messages, mode, flags, uid=0):
- mode = mode.upper()
- silent = mode.endswith('SILENT')
- if mode.startswith('+'):
- mode = 1
- elif mode.startswith('-'):
- mode = -1
- else:
- mode = 0
-
- maybeDeferred(self.mbox.store, messages, flags, mode, uid=uid).addCallbacks(
- self.__cbStore, self.__ebStore, (tag, self.mbox, uid, silent), None, (tag,), None
- )
-
- select_STORE = (do_STORE, arg_seqset, arg_atom, arg_flaglist)
-
- def __cbStore(self, result, tag, mbox, uid, silent):
- if result and not silent:
- for (k, v) in result.iteritems():
- if uid:
- uidstr = ' UID %d' % mbox.getUID(k)
- else:
- uidstr = ''
- self.sendUntaggedResponse('%d FETCH (FLAGS (%s)%s)' %
- (k, ' '.join(v), uidstr))
- self.sendPositiveResponse(tag, 'STORE completed')
-
- def __ebStore(self, failure, tag):
- self.sendBadResponse(tag, 'Server error: ' + str(failure.value))
-
- def do_COPY(self, tag, messages, mailbox, uid=0):
- mailbox = self._parseMbox(mailbox)
- maybeDeferred(self.account.select, mailbox
- ).addCallback(self._cbCopySelectedMailbox, tag, messages, mailbox, uid
- ).addErrback(self._ebCopySelectedMailbox, tag
- )
- select_COPY = (do_COPY, arg_seqset, arg_astring)
-
- def _cbCopySelectedMailbox(self, mbox, tag, messages, mailbox, uid):
- if not mbox:
- self.sendNegativeResponse(tag, 'No such mailbox: ' + mailbox)
- else:
- maybeDeferred(self.mbox.fetch, messages, uid
- ).addCallback(self.__cbCopy, tag, mbox
- ).addCallback(self.__cbCopied, tag, mbox
- ).addErrback(self.__ebCopy, tag
- )
-
- def _ebCopySelectedMailbox(self, failure, tag):
- self.sendBadResponse(tag, 'Server error: ' + str(failure.value))
-
- def __cbCopy(self, messages, tag, mbox):
- # XXX - This should handle failures with a rollback or something
- addedDeferreds = []
- addedIDs = []
- failures = []
-
- fastCopyMbox = IMessageCopier(mbox, None)
- for (id, msg) in messages:
- if fastCopyMbox is not None:
- d = maybeDeferred(fastCopyMbox.copy, msg)
- addedDeferreds.append(d)
- continue
-
- # XXX - The following should be an implementation of IMessageCopier.copy
- # on an IMailbox->IMessageCopier adapter.
-
- flags = msg.getFlags()
- date = msg.getInternalDate()
-
- body = IMessageFile(msg, None)
- if body is not None:
- bodyFile = body.open()
- d = maybeDeferred(mbox.addMessage, bodyFile, flags, date)
- else:
- def rewind(f):
- f.seek(0)
- return f
- buffer = tempfile.TemporaryFile()
- d = MessageProducer(msg, buffer, self._scheduler
- ).beginProducing(None
- ).addCallback(lambda _, b=buffer, f=flags, d=date: mbox.addMessage(rewind(b), f, d)
- )
- addedDeferreds.append(d)
- return defer.DeferredList(addedDeferreds)
-
- def __cbCopied(self, deferredIds, tag, mbox):
- ids = []
- failures = []
- for (status, result) in deferredIds:
- if status:
- ids.append(result)
- else:
- failures.append(result.value)
- if failures:
- self.sendNegativeResponse(tag, '[ALERT] Some messages were not copied')
- else:
- self.sendPositiveResponse(tag, 'COPY completed')
-
- def __ebCopy(self, failure, tag):
- self.sendBadResponse(tag, 'COPY failed:' + str(failure.value))
- log.err(failure)
-
- def do_UID(self, tag, command, line):
- command = command.upper()
-
- if command not in ('COPY', 'FETCH', 'STORE', 'SEARCH'):
- raise IllegalClientResponse(command)
-
- self.dispatchCommand(tag, command, line, uid=1)
-
- select_UID = (do_UID, arg_atom, arg_line)
- #
- # IMailboxListener implementation
- #
- def modeChanged(self, writeable):
- if writeable:
- self.sendUntaggedResponse(message='[READ-WRITE]', async=True)
- else:
- self.sendUntaggedResponse(message='[READ-ONLY]', async=True)
-
- def flagsChanged(self, newFlags):
- for (mId, flags) in newFlags.iteritems():
- msg = '%d FETCH (FLAGS (%s))' % (mId, ' '.join(flags))
- self.sendUntaggedResponse(msg, async=True)
-
- def newMessages(self, exists, recent):
- if exists is not None:
- self.sendUntaggedResponse('%d EXISTS' % exists, async=True)
- if recent is not None:
- self.sendUntaggedResponse('%d RECENT' % recent, async=True)
-
-
-class UnhandledResponse(IMAP4Exception): pass
-
-class NegativeResponse(IMAP4Exception): pass
-
-class NoSupportedAuthentication(IMAP4Exception):
- def __init__(self, serverSupports, clientSupports):
- IMAP4Exception.__init__(self, 'No supported authentication schemes available')
- self.serverSupports = serverSupports
- self.clientSupports = clientSupports
-
- def __str__(self):
- return (IMAP4Exception.__str__(self)
- + ': Server supports %r, client supports %r'
- % (self.serverSupports, self.clientSupports))
-
-class IllegalServerResponse(IMAP4Exception): pass
-
-TIMEOUT_ERROR = error.TimeoutError()
-
-class IMAP4Client(basic.LineReceiver, policies.TimeoutMixin):
- """IMAP4 client protocol implementation
-
- @ivar state: A string representing the state the connection is currently
- in.
- """
- implements(IMailboxListener)
-
- tags = None
- waiting = None
- queued = None
- tagID = 1
- state = None
-
- startedTLS = False
-
- # Number of seconds to wait before timing out a connection.
- # If the number is <= 0 no timeout checking will be performed.
- timeout = 0
-
- # Capabilities are not allowed to change during the session
- # So cache the first response and use that for all later
- # lookups
- _capCache = None
-
- _memoryFileLimit = 1024 * 1024 * 10
-
- # Authentication is pluggable. This maps names to IClientAuthentication
- # objects.
- authenticators = None
-
- STATUS_CODES = ('OK', 'NO', 'BAD', 'PREAUTH', 'BYE')
-
- STATUS_TRANSFORMATIONS = {
- 'MESSAGES': int, 'RECENT': int, 'UNSEEN': int
- }
-
- context = None
-
- def __init__(self, contextFactory = None):
- self.tags = {}
- self.queued = []
- self.authenticators = {}
- self.context = contextFactory
-
- self._tag = None
- self._parts = None
- self._lastCmd = None
-
- def registerAuthenticator(self, auth):
- """Register a new form of authentication
-
- When invoking the authenticate() method of IMAP4Client, the first
- matching authentication scheme found will be used. The ordering is
- that in which the server lists support authentication schemes.
-
- @type auth: Implementor of C{IClientAuthentication}
- @param auth: The object to use to perform the client
- side of this authentication scheme.
- """
- self.authenticators[auth.getName().upper()] = auth
-
- def rawDataReceived(self, data):
- if self.timeout > 0:
- self.resetTimeout()
-
- self._pendingSize -= len(data)
- if self._pendingSize > 0:
- self._pendingBuffer.write(data)
- else:
- passon = ''
- if self._pendingSize < 0:
- data, passon = data[:self._pendingSize], data[self._pendingSize:]
- self._pendingBuffer.write(data)
- rest = self._pendingBuffer
- self._pendingBuffer = None
- self._pendingSize = None
- rest.seek(0, 0)
- self._parts.append(rest.read())
- self.setLineMode(passon.lstrip('\r\n'))
-
-# def sendLine(self, line):
-# print 'S:', repr(line)
-# return basic.LineReceiver.sendLine(self, line)
-
- def _setupForLiteral(self, rest, octets):
- self._pendingBuffer = self.messageFile(octets)
- self._pendingSize = octets
- if self._parts is None:
- self._parts = [rest, '\r\n']
- else:
- self._parts.extend([rest, '\r\n'])
- self.setRawMode()
-
- def connectionMade(self):
- if self.timeout > 0:
- self.setTimeout(self.timeout)
-
- def connectionLost(self, reason):
- """We are no longer connected"""
- if self.timeout > 0:
- self.setTimeout(None)
- if self.queued is not None:
- queued = self.queued
- self.queued = None
- for cmd in queued:
- cmd.defer.errback(reason)
- if self.tags is not None:
- tags = self.tags
- self.tags = None
- for cmd in tags.itervalues():
- if cmd is not None and cmd.defer is not None:
- cmd.defer.errback(reason)
-
-
- def lineReceived(self, line):
- """
- Attempt to parse a single line from the server.
-
- @type line: C{str}
- @param line: The line from the server, without the line delimiter.
-
- @raise IllegalServerResponse: If the line or some part of the line
- does not represent an allowed message from the server at this time.
- """
-# print 'C: ' + repr(line)
- if self.timeout > 0:
- self.resetTimeout()
-
- lastPart = line.rfind('{')
- if lastPart != -1:
- lastPart = line[lastPart + 1:]
- if lastPart.endswith('}'):
- # It's a literal a-comin' in
- try:
- octets = int(lastPart[:-1])
- except ValueError:
- raise IllegalServerResponse(line)
- if self._parts is None:
- self._tag, parts = line.split(None, 1)
- else:
- parts = line
- self._setupForLiteral(parts, octets)
- return
-
- if self._parts is None:
- # It isn't a literal at all
- self._regularDispatch(line)
- else:
- # If an expression is in progress, no tag is required here
- # Since we didn't find a literal indicator, this expression
- # is done.
- self._parts.append(line)
- tag, rest = self._tag, ''.join(self._parts)
- self._tag = self._parts = None
- self.dispatchCommand(tag, rest)
-
- def timeoutConnection(self):
- if self._lastCmd and self._lastCmd.defer is not None:
- d, self._lastCmd.defer = self._lastCmd.defer, None
- d.errback(TIMEOUT_ERROR)
-
- if self.queued:
- for cmd in self.queued:
- if cmd.defer is not None:
- d, cmd.defer = cmd.defer, d
- d.errback(TIMEOUT_ERROR)
-
- self.transport.loseConnection()
-
- def _regularDispatch(self, line):
- parts = line.split(None, 1)
- if len(parts) != 2:
- parts.append('')
- tag, rest = parts
- self.dispatchCommand(tag, rest)
-
- def messageFile(self, octets):
- """Create a file to which an incoming message may be written.
-
- @type octets: C{int}
- @param octets: The number of octets which will be written to the file
-
- @rtype: Any object which implements C{write(string)} and
- C{seek(int, int)}
- @return: A file-like object
- """
- if octets > self._memoryFileLimit:
- return tempfile.TemporaryFile()
- else:
- return StringIO.StringIO()
-
- def makeTag(self):
- tag = '%0.4X' % self.tagID
- self.tagID += 1
- return tag
-
- def dispatchCommand(self, tag, rest):
- if self.state is None:
- f = self.response_UNAUTH
- else:
- f = getattr(self, 'response_' + self.state.upper(), None)
- if f:
- try:
- f(tag, rest)
- except:
- log.err()
- self.transport.loseConnection()
- else:
- log.err("Cannot dispatch: %s, %s, %s" % (self.state, tag, rest))
- self.transport.loseConnection()
-
- def response_UNAUTH(self, tag, rest):
- if self.state is None:
- # Server greeting, this is
- status, rest = rest.split(None, 1)
- if status.upper() == 'OK':
- self.state = 'unauth'
- elif status.upper() == 'PREAUTH':
- self.state = 'auth'
- else:
- # XXX - This is rude.
- self.transport.loseConnection()
- raise IllegalServerResponse(tag + ' ' + rest)
-
- b, e = rest.find('['), rest.find(']')
- if b != -1 and e != -1:
- self.serverGreeting(
- self.__cbCapabilities(
- ([parseNestedParens(rest[b + 1:e])], None)))
- else:
- self.serverGreeting(None)
- else:
- self._defaultHandler(tag, rest)
-
- def response_AUTH(self, tag, rest):
- self._defaultHandler(tag, rest)
-
- def _defaultHandler(self, tag, rest):
- if tag == '*' or tag == '+':
- if not self.waiting:
- self._extraInfo([parseNestedParens(rest)])
- else:
- cmd = self.tags[self.waiting]
- if tag == '+':
- cmd.continuation(rest)
- else:
- cmd.lines.append(rest)
- else:
- try:
- cmd = self.tags[tag]
- except KeyError:
- # XXX - This is rude.
- self.transport.loseConnection()
- raise IllegalServerResponse(tag + ' ' + rest)
- else:
- status, line = rest.split(None, 1)
- if status == 'OK':
- # Give them this last line, too
- cmd.finish(rest, self._extraInfo)
- else:
- cmd.defer.errback(IMAP4Exception(line))
- del self.tags[tag]
- self.waiting = None
- self._flushQueue()
-
- def _flushQueue(self):
- if self.queued:
- cmd = self.queued.pop(0)
- t = self.makeTag()
- self.tags[t] = cmd
- self.sendLine(cmd.format(t))
- self.waiting = t
-
- def _extraInfo(self, lines):
- # XXX - This is terrible.
- # XXX - Also, this should collapse temporally proximate calls into single
- # invocations of IMailboxListener methods, where possible.
- flags = {}
- recent = exists = None
- for response in lines:
- elements = len(response)
- if elements == 1 and response[0] == ['READ-ONLY']:
- self.modeChanged(False)
- elif elements == 1 and response[0] == ['READ-WRITE']:
- self.modeChanged(True)
- elif elements == 2 and response[1] == 'EXISTS':
- exists = int(response[0])
- elif elements == 2 and response[1] == 'RECENT':
- recent = int(response[0])
- elif elements == 3 and response[1] == 'FETCH':
- mId = int(response[0])
- values = self._parseFetchPairs(response[2])
- flags.setdefault(mId, []).extend(values.get('FLAGS', ()))
- else:
- log.msg('Unhandled unsolicited response: %s' % (response,))
-
- if flags:
- self.flagsChanged(flags)
- if recent is not None or exists is not None:
- self.newMessages(exists, recent)
-
- def sendCommand(self, cmd):
- cmd.defer = defer.Deferred()
- if self.waiting:
- self.queued.append(cmd)
- return cmd.defer
- t = self.makeTag()
- self.tags[t] = cmd
- self.sendLine(cmd.format(t))
- self.waiting = t
- self._lastCmd = cmd
- return cmd.defer
-
- def getCapabilities(self, useCache=1):
- """Request the capabilities available on this server.
-
- This command is allowed in any state of connection.
-
- @type useCache: C{bool}
- @param useCache: Specify whether to use the capability-cache or to
- re-retrieve the capabilities from the server. Server capabilities
- should never change, so for normal use, this flag should never be
- false.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback will be invoked with a
- dictionary mapping capability types to lists of supported
- mechanisms, or to None if a support list is not applicable.
- """
- if useCache and self._capCache is not None:
- return defer.succeed(self._capCache)
- cmd = 'CAPABILITY'
- resp = ('CAPABILITY',)
- d = self.sendCommand(Command(cmd, wantResponse=resp))
- d.addCallback(self.__cbCapabilities)
- return d
-
- def __cbCapabilities(self, (lines, tagline)):
- caps = {}
- for rest in lines:
- for cap in rest[1:]:
- parts = cap.split('=', 1)
- if len(parts) == 1:
- category, value = parts[0], None
- else:
- category, value = parts
- caps.setdefault(category, []).append(value)
-
- # Preserve a non-ideal API for backwards compatibility. It would
- # probably be entirely sensible to have an object with a wider API than
- # dict here so this could be presented less insanely.
- for category in caps:
- if caps[category] == [None]:
- caps[category] = None
- self._capCache = caps
- return caps
-
- def logout(self):
- """Inform the server that we are done with the connection.
-
- This command is allowed in any state of connection.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback will be invoked with None
- when the proper server acknowledgement has been received.
- """
- d = self.sendCommand(Command('LOGOUT', wantResponse=('BYE',)))
- d.addCallback(self.__cbLogout)
- return d
-
- def __cbLogout(self, (lines, tagline)):
- self.transport.loseConnection()
- # We don't particularly care what the server said
- return None
-
-
- def noop(self):
- """Perform no operation.
-
- This command is allowed in any state of connection.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback will be invoked with a list
- of untagged status updates the server responds with.
- """
- d = self.sendCommand(Command('NOOP'))
- d.addCallback(self.__cbNoop)
- return d
-
- def __cbNoop(self, (lines, tagline)):
- # Conceivable, this is elidable.
- # It is, afterall, a no-op.
- return lines
-
- def startTLS(self, contextFactory=None):
- """
- Initiates a 'STARTTLS' request and negotiates the TLS / SSL
- Handshake.
-
- @param contextFactory: The TLS / SSL Context Factory to
- leverage. If the contextFactory is None the IMAP4Client will
- either use the current TLS / SSL Context Factory or attempt to
- create a new one.
-
- @type contextFactory: C{ssl.ClientContextFactory}
-
- @return: A Deferred which fires when the transport has been
- secured according to the given contextFactory, or which fails
- if the transport cannot be secured.
- """
- assert not self.startedTLS, "Client and Server are currently communicating via TLS"
-
- if contextFactory is None:
- contextFactory = self._getContextFactory()
-
- if contextFactory is None:
- return defer.fail(IMAP4Exception(
- "IMAP4Client requires a TLS context to "
- "initiate the STARTTLS handshake"))
-
- if 'STARTTLS' not in self._capCache:
- return defer.fail(IMAP4Exception(
- "Server does not support secure communication "
- "via TLS / SSL"))
-
- tls = interfaces.ITLSTransport(self.transport, None)
- if tls is None:
- return defer.fail(IMAP4Exception(
- "IMAP4Client transport does not implement "
- "interfaces.ITLSTransport"))
-
- d = self.sendCommand(Command('STARTTLS'))
- d.addCallback(self._startedTLS, contextFactory)
- d.addCallback(lambda _: self.getCapabilities())
- return d
-
-
- def authenticate(self, secret):
- """Attempt to enter the authenticated state with the server
-
- This command is allowed in the Non-Authenticated state.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the authentication
- succeeds and whose errback will be invoked otherwise.
- """
- if self._capCache is None:
- d = self.getCapabilities()
- else:
- d = defer.succeed(self._capCache)
- d.addCallback(self.__cbAuthenticate, secret)
- return d
-
- def __cbAuthenticate(self, caps, secret):
- auths = caps.get('AUTH', ())
- for scheme in auths:
- if scheme.upper() in self.authenticators:
- cmd = Command('AUTHENTICATE', scheme, (),
- self.__cbContinueAuth, scheme,
- secret)
- return self.sendCommand(cmd)
-
- if self.startedTLS:
- return defer.fail(NoSupportedAuthentication(
- auths, self.authenticators.keys()))
- else:
- def ebStartTLS(err):
- err.trap(IMAP4Exception)
- # We couldn't negotiate TLS for some reason
- return defer.fail(NoSupportedAuthentication(
- auths, self.authenticators.keys()))
-
- d = self.startTLS()
- d.addErrback(ebStartTLS)
- d.addCallback(lambda _: self.getCapabilities())
- d.addCallback(self.__cbAuthTLS, secret)
- return d
-
-
- def __cbContinueAuth(self, rest, scheme, secret):
- try:
- chal = base64.decodestring(rest + '\n')
- except binascii.Error:
- self.sendLine('*')
- raise IllegalServerResponse(rest)
- self.transport.loseConnection()
- else:
- auth = self.authenticators[scheme]
- chal = auth.challengeResponse(secret, chal)
- self.sendLine(base64.encodestring(chal).strip())
-
- def __cbAuthTLS(self, caps, secret):
- auths = caps.get('AUTH', ())
- for scheme in auths:
- if scheme.upper() in self.authenticators:
- cmd = Command('AUTHENTICATE', scheme, (),
- self.__cbContinueAuth, scheme,
- secret)
- return self.sendCommand(cmd)
- raise NoSupportedAuthentication(auths, self.authenticators.keys())
-
-
- def login(self, username, password):
- """Authenticate with the server using a username and password
-
- This command is allowed in the Non-Authenticated state. If the
- server supports the STARTTLS capability and our transport supports
- TLS, TLS is negotiated before the login command is issued.
-
- A more secure way to log in is to use C{startTLS} or
- C{authenticate} or both.
-
- @type username: C{str}
- @param username: The username to log in with
-
- @type password: C{str}
- @param password: The password to log in with
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if login is successful
- and whose errback is invoked otherwise.
- """
- d = maybeDeferred(self.getCapabilities)
- d.addCallback(self.__cbLoginCaps, username, password)
- return d
-
- def serverGreeting(self, caps):
- """Called when the server has sent us a greeting.
-
- @type caps: C{dict}
- @param caps: Capabilities the server advertised in its greeting.
- """
-
- def _getContextFactory(self):
- if self.context is not None:
- return self.context
- try:
- from twisted.internet import ssl
- except ImportError:
- return None
- else:
- context = ssl.ClientContextFactory()
- context.method = ssl.SSL.TLSv1_METHOD
- return context
-
- def __cbLoginCaps(self, capabilities, username, password):
- # If the server advertises STARTTLS, we might want to try to switch to TLS
- tryTLS = 'STARTTLS' in capabilities
-
- # If our transport supports switching to TLS, we might want to try to switch to TLS.
- tlsableTransport = interfaces.ITLSTransport(self.transport, None) is not None
-
- # If our transport is not already using TLS, we might want to try to switch to TLS.
- nontlsTransport = interfaces.ISSLTransport(self.transport, None) is None
-
- if not self.startedTLS and tryTLS and tlsableTransport and nontlsTransport:
- d = self.startTLS()
-
- d.addCallbacks(
- self.__cbLoginTLS,
- self.__ebLoginTLS,
- callbackArgs=(username, password),
- )
- return d
- else:
- if nontlsTransport:
- log.msg("Server has no TLS support. logging in over cleartext!")
- args = ' '.join((_quote(username), _quote(password)))
- return self.sendCommand(Command('LOGIN', args))
-
- def _startedTLS(self, result, context):
- self.transport.startTLS(context)
- self._capCache = None
- self.startedTLS = True
- return result
-
- def __cbLoginTLS(self, result, username, password):
- args = ' '.join((_quote(username), _quote(password)))
- return self.sendCommand(Command('LOGIN', args))
-
- def __ebLoginTLS(self, failure):
- log.err(failure)
- return failure
-
- def namespace(self):
- """Retrieve information about the namespaces available to this account
-
- This command is allowed in the Authenticated and Selected states.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with namespace
- information. An example of this information is::
-
- [[['', '/']], [], []]
-
- which indicates a single personal namespace called '' with '/'
- as its hierarchical delimiter, and no shared or user namespaces.
- """
- cmd = 'NAMESPACE'
- resp = ('NAMESPACE',)
- d = self.sendCommand(Command(cmd, wantResponse=resp))
- d.addCallback(self.__cbNamespace)
- return d
-
- def __cbNamespace(self, (lines, last)):
- for parts in lines:
- if len(parts) == 4 and parts[0] == 'NAMESPACE':
- return [e or [] for e in parts[1:]]
- log.err("No NAMESPACE response to NAMESPACE command")
- return [[], [], []]
-
-
- def select(self, mailbox):
- """
- Select a mailbox
-
- This command is allowed in the Authenticated and Selected states.
-
- @type mailbox: C{str}
- @param mailbox: The name of the mailbox to select
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with mailbox
- information if the select is successful and whose errback is
- invoked otherwise. Mailbox information consists of a dictionary
- with the following keys and values::
-
- FLAGS: A list of strings containing the flags settable on
- messages in this mailbox.
-
- EXISTS: An integer indicating the number of messages in this
- mailbox.
-
- RECENT: An integer indicating the number of "recent"
- messages in this mailbox.
-
- UNSEEN: The message sequence number (an integer) of the
- first unseen message in the mailbox.
-
- PERMANENTFLAGS: A list of strings containing the flags that
- can be permanently set on messages in this mailbox.
-
- UIDVALIDITY: An integer uniquely identifying this mailbox.
- """
- cmd = 'SELECT'
- args = _prepareMailboxName(mailbox)
- resp = ('FLAGS', 'EXISTS', 'RECENT', 'UNSEEN', 'PERMANENTFLAGS', 'UIDVALIDITY')
- d = self.sendCommand(Command(cmd, args, wantResponse=resp))
- d.addCallback(self.__cbSelect, 1)
- return d
-
-
- def examine(self, mailbox):
- """Select a mailbox in read-only mode
-
- This command is allowed in the Authenticated and Selected states.
-
- @type mailbox: C{str}
- @param mailbox: The name of the mailbox to examine
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with mailbox
- information if the examine is successful and whose errback
- is invoked otherwise. Mailbox information consists of a dictionary
- with the following keys and values::
-
- 'FLAGS': A list of strings containing the flags settable on
- messages in this mailbox.
-
- 'EXISTS': An integer indicating the number of messages in this
- mailbox.
-
- 'RECENT': An integer indicating the number of \"recent\"
- messages in this mailbox.
-
- 'UNSEEN': An integer indicating the number of messages not
- flagged \\Seen in this mailbox.
-
- 'PERMANENTFLAGS': A list of strings containing the flags that
- can be permanently set on messages in this mailbox.
-
- 'UIDVALIDITY': An integer uniquely identifying this mailbox.
- """
- cmd = 'EXAMINE'
- args = _prepareMailboxName(mailbox)
- resp = ('FLAGS', 'EXISTS', 'RECENT', 'UNSEEN', 'PERMANENTFLAGS', 'UIDVALIDITY')
- d = self.sendCommand(Command(cmd, args, wantResponse=resp))
- d.addCallback(self.__cbSelect, 0)
- return d
-
-
- def _intOrRaise(self, value, phrase):
- """
- Parse C{value} as an integer and return the result or raise
- L{IllegalServerResponse} with C{phrase} as an argument if C{value}
- cannot be parsed as an integer.
- """
- try:
- return int(value)
- except ValueError:
- raise IllegalServerResponse(phrase)
-
-
- def __cbSelect(self, (lines, tagline), rw):
- """
- Handle lines received in response to a SELECT or EXAMINE command.
-
- See RFC 3501, section 6.3.1.
- """
- # In the absense of specification, we are free to assume:
- # READ-WRITE access
- datum = {'READ-WRITE': rw}
- lines.append(parseNestedParens(tagline))
- for split in lines:
- if len(split) > 0 and split[0].upper() == 'OK':
- # Handle all the kinds of OK response.
- content = split[1]
- key = content[0].upper()
- if key == 'READ-ONLY':
- datum['READ-WRITE'] = False
- elif key == 'READ-WRITE':
- datum['READ-WRITE'] = True
- elif key == 'UIDVALIDITY':
- datum['UIDVALIDITY'] = self._intOrRaise(
- content[1], split)
- elif key == 'UNSEEN':
- datum['UNSEEN'] = self._intOrRaise(content[1], split)
- elif key == 'UIDNEXT':
- datum['UIDNEXT'] = self._intOrRaise(content[1], split)
- elif key == 'PERMANENTFLAGS':
- datum['PERMANENTFLAGS'] = tuple(content[1])
- else:
- log.err('Unhandled SELECT response (2): %s' % (split,))
- elif len(split) == 2:
- # Handle FLAGS, EXISTS, and RECENT
- if split[0].upper() == 'FLAGS':
- datum['FLAGS'] = tuple(split[1])
- elif isinstance(split[1], str):
- # Must make sure things are strings before treating them as
- # strings since some other forms of response have nesting in
- # places which results in lists instead.
- if split[1].upper() == 'EXISTS':
- datum['EXISTS'] = self._intOrRaise(split[0], split)
- elif split[1].upper() == 'RECENT':
- datum['RECENT'] = self._intOrRaise(split[0], split)
- else:
- log.err('Unhandled SELECT response (0): %s' % (split,))
- else:
- log.err('Unhandled SELECT response (1): %s' % (split,))
- else:
- log.err('Unhandled SELECT response (4): %s' % (split,))
- return datum
-
-
- def create(self, name):
- """Create a new mailbox on the server
-
- This command is allowed in the Authenticated and Selected states.
-
- @type name: C{str}
- @param name: The name of the mailbox to create.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the mailbox creation
- is successful and whose errback is invoked otherwise.
- """
- return self.sendCommand(Command('CREATE', _prepareMailboxName(name)))
-
- def delete(self, name):
- """Delete a mailbox
-
- This command is allowed in the Authenticated and Selected states.
-
- @type name: C{str}
- @param name: The name of the mailbox to delete.
-
- @rtype: C{Deferred}
- @return: A deferred whose calblack is invoked if the mailbox is
- deleted successfully and whose errback is invoked otherwise.
- """
- return self.sendCommand(Command('DELETE', _prepareMailboxName(name)))
-
- def rename(self, oldname, newname):
- """Rename a mailbox
-
- This command is allowed in the Authenticated and Selected states.
-
- @type oldname: C{str}
- @param oldname: The current name of the mailbox to rename.
-
- @type newname: C{str}
- @param newname: The new name to give the mailbox.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the rename is
- successful and whose errback is invoked otherwise.
- """
- oldname = _prepareMailboxName(oldname)
- newname = _prepareMailboxName(newname)
- return self.sendCommand(Command('RENAME', ' '.join((oldname, newname))))
-
- def subscribe(self, name):
- """Add a mailbox to the subscription list
-
- This command is allowed in the Authenticated and Selected states.
-
- @type name: C{str}
- @param name: The mailbox to mark as 'active' or 'subscribed'
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the subscription
- is successful and whose errback is invoked otherwise.
- """
- return self.sendCommand(Command('SUBSCRIBE', _prepareMailboxName(name)))
-
- def unsubscribe(self, name):
- """Remove a mailbox from the subscription list
-
- This command is allowed in the Authenticated and Selected states.
-
- @type name: C{str}
- @param name: The mailbox to unsubscribe
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the unsubscription
- is successful and whose errback is invoked otherwise.
- """
- return self.sendCommand(Command('UNSUBSCRIBE', _prepareMailboxName(name)))
-
- def list(self, reference, wildcard):
- """List a subset of the available mailboxes
-
- This command is allowed in the Authenticated and Selected states.
-
- @type reference: C{str}
- @param reference: The context in which to interpret C{wildcard}
-
- @type wildcard: C{str}
- @param wildcard: The pattern of mailbox names to match, optionally
- including either or both of the '*' and '%' wildcards. '*' will
- match zero or more characters and cross hierarchical boundaries.
- '%' will also match zero or more characters, but is limited to a
- single hierarchical level.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a list of C{tuple}s,
- the first element of which is a C{tuple} of mailbox flags, the second
- element of which is the hierarchy delimiter for this mailbox, and the
- third of which is the mailbox name; if the command is unsuccessful,
- the deferred's errback is invoked instead.
- """
- cmd = 'LIST'
- args = '"%s" "%s"' % (reference, wildcard.encode('imap4-utf-7'))
- resp = ('LIST',)
- d = self.sendCommand(Command(cmd, args, wantResponse=resp))
- d.addCallback(self.__cbList, 'LIST')
- return d
-
- def lsub(self, reference, wildcard):
- """List a subset of the subscribed available mailboxes
-
- This command is allowed in the Authenticated and Selected states.
-
- The parameters and returned object are the same as for the C{list}
- method, with one slight difference: Only mailboxes which have been
- subscribed can be included in the resulting list.
- """
- cmd = 'LSUB'
- args = '"%s" "%s"' % (reference, wildcard.encode('imap4-utf-7'))
- resp = ('LSUB',)
- d = self.sendCommand(Command(cmd, args, wantResponse=resp))
- d.addCallback(self.__cbList, 'LSUB')
- return d
-
- def __cbList(self, (lines, last), command):
- results = []
- for parts in lines:
- if len(parts) == 4 and parts[0] == command:
- parts[1] = tuple(parts[1])
- results.append(tuple(parts[1:]))
- return results
-
- def status(self, mailbox, *names):
- """
- Retrieve the status of the given mailbox
-
- This command is allowed in the Authenticated and Selected states.
-
- @type mailbox: C{str}
- @param mailbox: The name of the mailbox to query
-
- @type *names: C{str}
- @param *names: The status names to query. These may be any number of:
- C{'MESSAGES'}, C{'RECENT'}, C{'UIDNEXT'}, C{'UIDVALIDITY'}, and
- C{'UNSEEN'}.
-
- @rtype: C{Deferred}
- @return: A deferred which fires with with the status information if the
- command is successful and whose errback is invoked otherwise. The
- status information is in the form of a C{dict}. Each element of
- C{names} is a key in the dictionary. The value for each key is the
- corresponding response from the server.
- """
- cmd = 'STATUS'
- args = "%s (%s)" % (_prepareMailboxName(mailbox), ' '.join(names))
- resp = ('STATUS',)
- d = self.sendCommand(Command(cmd, args, wantResponse=resp))
- d.addCallback(self.__cbStatus)
- return d
-
- def __cbStatus(self, (lines, last)):
- status = {}
- for parts in lines:
- if parts[0] == 'STATUS':
- items = parts[2]
- items = [items[i:i+2] for i in range(0, len(items), 2)]
- status.update(dict(items))
- for k in status.keys():
- t = self.STATUS_TRANSFORMATIONS.get(k)
- if t:
- try:
- status[k] = t(status[k])
- except Exception, e:
- raise IllegalServerResponse('(%s %s): %s' % (k, status[k], str(e)))
- return status
-
- def append(self, mailbox, message, flags = (), date = None):
- """Add the given message to the given mailbox.
-
- This command is allowed in the Authenticated and Selected states.
-
- @type mailbox: C{str}
- @param mailbox: The mailbox to which to add this message.
-
- @type message: Any file-like object
- @param message: The message to add, in RFC822 format. Newlines
- in this file should be \\r\\n-style.
-
- @type flags: Any iterable of C{str}
- @param flags: The flags to associated with this message.
-
- @type date: C{str}
- @param date: The date to associate with this message. This should
- be of the format DD-MM-YYYY HH:MM:SS +/-HHMM. For example, in
- Eastern Standard Time, on July 1st 2004 at half past 1 PM,
- \"01-07-2004 13:30:00 -0500\".
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked when this command
- succeeds or whose errback is invoked if it fails.
- """
- message.seek(0, 2)
- L = message.tell()
- message.seek(0, 0)
- fmt = '%s (%s)%s {%d}'
- if date:
- date = ' "%s"' % date
- else:
- date = ''
- cmd = fmt % (
- _prepareMailboxName(mailbox), ' '.join(flags),
- date, L
- )
- d = self.sendCommand(Command('APPEND', cmd, (), self.__cbContinueAppend, message))
- return d
-
- def __cbContinueAppend(self, lines, message):
- s = basic.FileSender()
- return s.beginFileTransfer(message, self.transport, None
- ).addCallback(self.__cbFinishAppend)
-
- def __cbFinishAppend(self, foo):
- self.sendLine('')
-
- def check(self):
- """Tell the server to perform a checkpoint
-
- This command is allowed in the Selected state.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked when this command
- succeeds or whose errback is invoked if it fails.
- """
- return self.sendCommand(Command('CHECK'))
-
- def close(self):
- """Return the connection to the Authenticated state.
-
- This command is allowed in the Selected state.
-
- Issuing this command will also remove all messages flagged \\Deleted
- from the selected mailbox if it is opened in read-write mode,
- otherwise it indicates success by no messages are removed.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked when the command
- completes successfully or whose errback is invoked if it fails.
- """
- return self.sendCommand(Command('CLOSE'))
-
-
- def expunge(self):
- """Return the connection to the Authenticate state.
-
- This command is allowed in the Selected state.
-
- Issuing this command will perform the same actions as issuing the
- close command, but will also generate an 'expunge' response for
- every message deleted.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a list of the
- 'expunge' responses when this command is successful or whose errback
- is invoked otherwise.
- """
- cmd = 'EXPUNGE'
- resp = ('EXPUNGE',)
- d = self.sendCommand(Command(cmd, wantResponse=resp))
- d.addCallback(self.__cbExpunge)
- return d
-
-
- def __cbExpunge(self, (lines, last)):
- ids = []
- for parts in lines:
- if len(parts) == 2 and parts[1] == 'EXPUNGE':
- ids.append(self._intOrRaise(parts[0], parts))
- return ids
-
-
- def search(self, *queries, **kwarg):
- """Search messages in the currently selected mailbox
-
- This command is allowed in the Selected state.
-
- Any non-zero number of queries are accepted by this method, as
- returned by the C{Query}, C{Or}, and C{Not} functions.
-
- One keyword argument is accepted: if uid is passed in with a non-zero
- value, the server is asked to return message UIDs instead of message
- sequence numbers.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback will be invoked with a list of all
- the message sequence numbers return by the search, or whose errback
- will be invoked if there is an error.
- """
- if kwarg.get('uid'):
- cmd = 'UID SEARCH'
- else:
- cmd = 'SEARCH'
- args = ' '.join(queries)
- d = self.sendCommand(Command(cmd, args, wantResponse=(cmd,)))
- d.addCallback(self.__cbSearch)
- return d
-
-
- def __cbSearch(self, (lines, end)):
- ids = []
- for parts in lines:
- if len(parts) > 0 and parts[0] == 'SEARCH':
- ids.extend([self._intOrRaise(p, parts) for p in parts[1:]])
- return ids
-
-
- def fetchUID(self, messages, uid=0):
- """Retrieve the unique identifier for one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message sequence numbers to unique message identifiers, or whose
- errback is invoked if there is an error.
- """
- return self._fetch(messages, useUID=uid, uid=1)
-
-
- def fetchFlags(self, messages, uid=0):
- """Retrieve the flags for one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: The messages for which to retrieve flags.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to lists of flags, or whose errback is invoked if
- there is an error.
- """
- return self._fetch(str(messages), useUID=uid, flags=1)
-
-
- def fetchInternalDate(self, messages, uid=0):
- """Retrieve the internal date associated with one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: The messages for which to retrieve the internal date.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to date strings, or whose errback is invoked
- if there is an error. Date strings take the format of
- \"day-month-year time timezone\".
- """
- return self._fetch(str(messages), useUID=uid, internaldate=1)
-
-
- def fetchEnvelope(self, messages, uid=0):
- """Retrieve the envelope data for one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: The messages for which to retrieve envelope data.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to envelope data, or whose errback is invoked
- if there is an error. Envelope data consists of a sequence of the
- date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to,
- and message-id header fields. The date, subject, in-reply-to, and
- message-id fields are strings, while the from, sender, reply-to,
- to, cc, and bcc fields contain address data. Address data consists
- of a sequence of name, source route, mailbox name, and hostname.
- Fields which are not present for a particular address may be C{None}.
- """
- return self._fetch(str(messages), useUID=uid, envelope=1)
-
-
- def fetchBodyStructure(self, messages, uid=0):
- """Retrieve the structure of the body of one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: The messages for which to retrieve body structure
- data.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to body structure data, or whose errback is invoked
- if there is an error. Body structure data describes the MIME-IMB
- format of a message and consists of a sequence of mime type, mime
- subtype, parameters, content id, description, encoding, and size.
- The fields following the size field are variable: if the mime
- type/subtype is message/rfc822, the contained message's envelope
- information, body structure data, and number of lines of text; if
- the mime type is text, the number of lines of text. Extension fields
- may also be included; if present, they are: the MD5 hash of the body,
- body disposition, body language.
- """
- return self._fetch(messages, useUID=uid, bodystructure=1)
-
-
- def fetchSimplifiedBody(self, messages, uid=0):
- """Retrieve the simplified body structure of one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to body data, or whose errback is invoked
- if there is an error. The simplified body structure is the same
- as the body structure, except that extension fields will never be
- present.
- """
- return self._fetch(messages, useUID=uid, body=1)
-
-
- def fetchMessage(self, messages, uid=0):
- """Retrieve one or more entire messages
-
- This command is allowed in the Selected state.
-
- @type messages: L{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: L{Deferred}
-
- @return: A L{Deferred} which will fire with a C{dict} mapping message
- sequence numbers to C{dict}s giving message data for the
- corresponding message. If C{uid} is true, the inner dictionaries
- have a C{'UID'} key mapped to a C{str} giving the UID for the
- message. The text of the message is a C{str} associated with the
- C{'RFC822'} key in each dictionary.
- """
- return self._fetch(messages, useUID=uid, rfc822=1)
-
-
- def fetchHeaders(self, messages, uid=0):
- """Retrieve headers of one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to dicts of message headers, or whose errback is
- invoked if there is an error.
- """
- return self._fetch(messages, useUID=uid, rfc822header=1)
-
-
- def fetchBody(self, messages, uid=0):
- """Retrieve body text of one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to file-like objects containing body text, or whose
- errback is invoked if there is an error.
- """
- return self._fetch(messages, useUID=uid, rfc822text=1)
-
-
- def fetchSize(self, messages, uid=0):
- """Retrieve the size, in octets, of one or more messages
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to sizes, or whose errback is invoked if there is
- an error.
- """
- return self._fetch(messages, useUID=uid, rfc822size=1)
-
-
- def fetchFull(self, messages, uid=0):
- """Retrieve several different fields of one or more messages
-
- This command is allowed in the Selected state. This is equivalent
- to issuing all of the C{fetchFlags}, C{fetchInternalDate},
- C{fetchSize}, C{fetchEnvelope}, and C{fetchSimplifiedBody}
- functions.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to dict of the retrieved data values, or whose
- errback is invoked if there is an error. They dictionary keys
- are "flags", "date", "size", "envelope", and "body".
- """
- return self._fetch(
- messages, useUID=uid, flags=1, internaldate=1,
- rfc822size=1, envelope=1, body=1)
-
-
- def fetchAll(self, messages, uid=0):
- """Retrieve several different fields of one or more messages
-
- This command is allowed in the Selected state. This is equivalent
- to issuing all of the C{fetchFlags}, C{fetchInternalDate},
- C{fetchSize}, and C{fetchEnvelope} functions.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to dict of the retrieved data values, or whose
- errback is invoked if there is an error. They dictionary keys
- are "flags", "date", "size", and "envelope".
- """
- return self._fetch(
- messages, useUID=uid, flags=1, internaldate=1,
- rfc822size=1, envelope=1)
-
-
- def fetchFast(self, messages, uid=0):
- """Retrieve several different fields of one or more messages
-
- This command is allowed in the Selected state. This is equivalent
- to issuing all of the C{fetchFlags}, C{fetchInternalDate}, and
- C{fetchSize} functions.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a dict mapping
- message numbers to dict of the retrieved data values, or whose
- errback is invoked if there is an error. They dictionary keys are
- "flags", "date", and "size".
- """
- return self._fetch(
- messages, useUID=uid, flags=1, internaldate=1, rfc822size=1)
-
-
- def _parseFetchPairs(self, fetchResponseList):
- """
- Given the result of parsing a single I{FETCH} response, construct a
- C{dict} mapping response keys to response values.
-
- @param fetchResponseList: The result of parsing a I{FETCH} response
- with L{parseNestedParens} and extracting just the response data
- (that is, just the part that comes after C{"FETCH"}). The form
- of this input (and therefore the output of this method) is very
- disagreable. A valuable improvement would be to enumerate the
- possible keys (representing them as structured objects of some
- sort) rather than using strings and tuples of tuples of strings
- and so forth. This would allow the keys to be documented more
- easily and would allow for a much simpler application-facing API
- (one not based on looking up somewhat hard to predict keys in a
- dict). Since C{fetchResponseList} notionally represents a
- flattened sequence of pairs (identifying keys followed by their
- associated values), collapsing such complex elements of this
- list as C{["BODY", ["HEADER.FIELDS", ["SUBJECT"]]]} into a
- single object would also greatly simplify the implementation of
- this method.
-
- @return: A C{dict} of the response data represented by C{pairs}. Keys
- in this dictionary are things like C{"RFC822.TEXT"}, C{"FLAGS"}, or
- C{("BODY", ("HEADER.FIELDS", ("SUBJECT",)))}. Values are entirely
- dependent on the key with which they are associated, but retain the
- same structured as produced by L{parseNestedParens}.
- """
- values = {}
- responseParts = iter(fetchResponseList)
- while True:
- try:
- key = responseParts.next()
- except StopIteration:
- break
-
- try:
- value = responseParts.next()
- except StopIteration:
- raise IllegalServerResponse(
- "Not enough arguments", fetchResponseList)
-
- # The parsed forms of responses like:
- #
- # BODY[] VALUE
- # BODY[TEXT] VALUE
- # BODY[HEADER.FIELDS (SUBJECT)] VALUE
- # BODY[HEADER.FIELDS (SUBJECT)]<N.M> VALUE
- #
- # are:
- #
- # ["BODY", [], VALUE]
- # ["BODY", ["TEXT"], VALUE]
- # ["BODY", ["HEADER.FIELDS", ["SUBJECT"]], VALUE]
- # ["BODY", ["HEADER.FIELDS", ["SUBJECT"]], "<N.M>", VALUE]
- #
- # Here, check for these cases and grab as many extra elements as
- # necessary to retrieve the body information.
- if key in ("BODY", "BODY.PEEK") and isinstance(value, list) and len(value) < 3:
- if len(value) < 2:
- key = (key, tuple(value))
- else:
- key = (key, (value[0], tuple(value[1])))
- try:
- value = responseParts.next()
- except StopIteration:
- raise IllegalServerResponse(
- "Not enough arguments", fetchResponseList)
-
- # Handle partial ranges
- if value.startswith('<') and value.endswith('>'):
- try:
- int(value[1:-1])
- except ValueError:
- # This isn't really a range, it's some content.
- pass
- else:
- key = key + (value,)
- try:
- value = responseParts.next()
- except StopIteration:
- raise IllegalServerResponse(
- "Not enough arguments", fetchResponseList)
-
- values[key] = value
- return values
-
-
- def _cbFetch(self, (lines, last), requestedParts, structured):
- info = {}
- for parts in lines:
- if len(parts) == 3 and parts[1] == 'FETCH':
- id = self._intOrRaise(parts[0], parts)
- if id not in info:
- info[id] = [parts[2]]
- else:
- info[id][0].extend(parts[2])
-
- results = {}
- for (messageId, values) in info.iteritems():
- mapping = self._parseFetchPairs(values[0])
- results.setdefault(messageId, {}).update(mapping)
-
- flagChanges = {}
- for messageId in results.keys():
- values = results[messageId]
- for part in values.keys():
- if part not in requestedParts and part == 'FLAGS':
- flagChanges[messageId] = values['FLAGS']
- # Find flags in the result and get rid of them.
- for i in range(len(info[messageId][0])):
- if info[messageId][0][i] == 'FLAGS':
- del info[messageId][0][i:i+2]
- break
- del values['FLAGS']
- if not values:
- del results[messageId]
-
- if flagChanges:
- self.flagsChanged(flagChanges)
-
- if structured:
- return results
- else:
- return info
-
-
- def fetchSpecific(self, messages, uid=0, headerType=None,
- headerNumber=None, headerArgs=None, peek=None,
- offset=None, length=None):
- """Retrieve a specific section of one or more messages
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @type headerType: C{str}
- @param headerType: If specified, must be one of HEADER,
- HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, or TEXT, and will determine
- which part of the message is retrieved. For HEADER.FIELDS and
- HEADER.FIELDS.NOT, C{headerArgs} must be a sequence of header names.
- For MIME, C{headerNumber} must be specified.
-
- @type headerNumber: C{int} or C{int} sequence
- @param headerNumber: The nested rfc822 index specifying the
- entity to retrieve. For example, C{1} retrieves the first
- entity of the message, and C{(2, 1, 3}) retrieves the 3rd
- entity inside the first entity inside the second entity of
- the message.
-
- @type headerArgs: A sequence of C{str}
- @param headerArgs: If C{headerType} is HEADER.FIELDS, these are the
- headers to retrieve. If it is HEADER.FIELDS.NOT, these are the
- headers to exclude from retrieval.
-
- @type peek: C{bool}
- @param peek: If true, cause the server to not set the \\Seen
- flag on this message as a result of this command.
-
- @type offset: C{int}
- @param offset: The number of octets at the beginning of the result
- to skip.
-
- @type length: C{int}
- @param length: The number of octets to retrieve.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a mapping of
- message numbers to retrieved data, or whose errback is invoked
- if there is an error.
- """
- fmt = '%s BODY%s[%s%s%s]%s'
- if headerNumber is None:
- number = ''
- elif isinstance(headerNumber, int):
- number = str(headerNumber)
- else:
- number = '.'.join(map(str, headerNumber))
- if headerType is None:
- header = ''
- elif number:
- header = '.' + headerType
- else:
- header = headerType
- if header and headerType not in ('TEXT', 'MIME'):
- if headerArgs is not None:
- payload = ' (%s)' % ' '.join(headerArgs)
- else:
- payload = ' ()'
- else:
- payload = ''
- if offset is None:
- extra = ''
- else:
- extra = '<%d.%d>' % (offset, length)
- fetch = uid and 'UID FETCH' or 'FETCH'
- cmd = fmt % (messages, peek and '.PEEK' or '', number, header, payload, extra)
- d = self.sendCommand(Command(fetch, cmd, wantResponse=('FETCH',)))
- d.addCallback(self._cbFetch, (), False)
- return d
-
-
- def _fetch(self, messages, useUID=0, **terms):
- fetch = useUID and 'UID FETCH' or 'FETCH'
-
- if 'rfc822text' in terms:
- del terms['rfc822text']
- terms['rfc822.text'] = True
- if 'rfc822size' in terms:
- del terms['rfc822size']
- terms['rfc822.size'] = True
- if 'rfc822header' in terms:
- del terms['rfc822header']
- terms['rfc822.header'] = True
-
- cmd = '%s (%s)' % (messages, ' '.join([s.upper() for s in terms.keys()]))
- d = self.sendCommand(Command(fetch, cmd, wantResponse=('FETCH',)))
- d.addCallback(self._cbFetch, map(str.upper, terms.keys()), True)
- return d
-
- def setFlags(self, messages, flags, silent=1, uid=0):
- """Set the flags for one or more messages.
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type flags: Any iterable of C{str}
- @param flags: The flags to set
-
- @type silent: C{bool}
- @param silent: If true, cause the server to supress its verbose
- response.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a list of the
- the server's responses (C{[]} if C{silent} is true) or whose
- errback is invoked if there is an error.
- """
- return self._store(str(messages), 'FLAGS', silent, flags, uid)
-
- def addFlags(self, messages, flags, silent=1, uid=0):
- """Add to the set flags for one or more messages.
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type flags: Any iterable of C{str}
- @param flags: The flags to set
-
- @type silent: C{bool}
- @param silent: If true, cause the server to supress its verbose
- response.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a list of the
- the server's responses (C{[]} if C{silent} is true) or whose
- errback is invoked if there is an error.
- """
- return self._store(str(messages),'+FLAGS', silent, flags, uid)
-
- def removeFlags(self, messages, flags, silent=1, uid=0):
- """Remove from the set flags for one or more messages.
-
- This command is allowed in the Selected state.
-
- @type messages: C{MessageSet} or C{str}
- @param messages: A message sequence set
-
- @type flags: Any iterable of C{str}
- @param flags: The flags to set
-
- @type silent: C{bool}
- @param silent: If true, cause the server to supress its verbose
- response.
-
- @type uid: C{bool}
- @param uid: Indicates whether the message sequence set is of message
- numbers or of unique message IDs.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a list of the
- the server's responses (C{[]} if C{silent} is true) or whose
- errback is invoked if there is an error.
- """
- return self._store(str(messages), '-FLAGS', silent, flags, uid)
-
-
- def _store(self, messages, cmd, silent, flags, uid):
- if silent:
- cmd = cmd + '.SILENT'
- store = uid and 'UID STORE' or 'STORE'
- args = ' '.join((messages, cmd, '(%s)' % ' '.join(flags)))
- d = self.sendCommand(Command(store, args, wantResponse=('FETCH',)))
- expected = ()
- if not silent:
- expected = ('FLAGS',)
- d.addCallback(self._cbFetch, expected, True)
- return d
-
-
- def copy(self, messages, mailbox, uid):
- """Copy the specified messages to the specified mailbox.
-
- This command is allowed in the Selected state.
-
- @type messages: C{str}
- @param messages: A message sequence set
-
- @type mailbox: C{str}
- @param mailbox: The mailbox to which to copy the messages
-
- @type uid: C{bool}
- @param uid: If true, the C{messages} refers to message UIDs, rather
- than message sequence numbers.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with a true value
- when the copy is successful, or whose errback is invoked if there
- is an error.
- """
- if uid:
- cmd = 'UID COPY'
- else:
- cmd = 'COPY'
- args = '%s %s' % (messages, _prepareMailboxName(mailbox))
- return self.sendCommand(Command(cmd, args))
-
- #
- # IMailboxListener methods
- #
- def modeChanged(self, writeable):
- """Override me"""
-
- def flagsChanged(self, newFlags):
- """Override me"""
-
- def newMessages(self, exists, recent):
- """Override me"""
-
-
-class IllegalIdentifierError(IMAP4Exception): pass
-
-def parseIdList(s, lastMessageId=None):
- """
- Parse a message set search key into a C{MessageSet}.
-
- @type s: C{str}
- @param s: A string description of a id list, for example "1:3, 4:*"
-
- @type lastMessageId: C{int}
- @param lastMessageId: The last message sequence id or UID, depending on
- whether we are parsing the list in UID or sequence id context. The
- caller should pass in the correct value.
-
- @rtype: C{MessageSet}
- @return: A C{MessageSet} that contains the ids defined in the list
- """
- res = MessageSet()
- parts = s.split(',')
- for p in parts:
- if ':' in p:
- low, high = p.split(':', 1)
- try:
- if low == '*':
- low = None
- else:
- low = long(low)
- if high == '*':
- high = None
- else:
- high = long(high)
- if low is high is None:
- # *:* does not make sense
- raise IllegalIdentifierError(p)
- # non-positive values are illegal according to RFC 3501
- if ((low is not None and low <= 0) or
- (high is not None and high <= 0)):
- raise IllegalIdentifierError(p)
- # star means "highest value of an id in the mailbox"
- high = high or lastMessageId
- low = low or lastMessageId
-
- # RFC says that 2:4 and 4:2 are equivalent
- if low > high:
- low, high = high, low
- res.extend((low, high))
- except ValueError:
- raise IllegalIdentifierError(p)
- else:
- try:
- if p == '*':
- p = None
- else:
- p = long(p)
- if p is not None and p <= 0:
- raise IllegalIdentifierError(p)
- except ValueError:
- raise IllegalIdentifierError(p)
- else:
- res.extend(p or lastMessageId)
- return res
-
-class IllegalQueryError(IMAP4Exception): pass
-
-_SIMPLE_BOOL = (
- 'ALL', 'ANSWERED', 'DELETED', 'DRAFT', 'FLAGGED', 'NEW', 'OLD', 'RECENT',
- 'SEEN', 'UNANSWERED', 'UNDELETED', 'UNDRAFT', 'UNFLAGGED', 'UNSEEN'
-)
-
-_NO_QUOTES = (
- 'LARGER', 'SMALLER', 'UID'
-)
-
-def Query(sorted=0, **kwarg):
- """Create a query string
-
- Among the accepted keywords are::
-
- all : If set to a true value, search all messages in the
- current mailbox
-
- answered : If set to a true value, search messages flagged with
- \\Answered
-
- bcc : A substring to search the BCC header field for
-
- before : Search messages with an internal date before this
- value. The given date should be a string in the format
- of 'DD-Mon-YYYY'. For example, '03-Mar-2003'.
-
- body : A substring to search the body of the messages for
-
- cc : A substring to search the CC header field for
-
- deleted : If set to a true value, search messages flagged with
- \\Deleted
-
- draft : If set to a true value, search messages flagged with
- \\Draft
-
- flagged : If set to a true value, search messages flagged with
- \\Flagged
-
- from : A substring to search the From header field for
-
- header : A two-tuple of a header name and substring to search
- for in that header
-
- keyword : Search for messages with the given keyword set
-
- larger : Search for messages larger than this number of octets
-
- messages : Search only the given message sequence set.
-
- new : If set to a true value, search messages flagged with
- \\Recent but not \\Seen
-
- old : If set to a true value, search messages not flagged with
- \\Recent
-
- on : Search messages with an internal date which is on this
- date. The given date should be a string in the format
- of 'DD-Mon-YYYY'. For example, '03-Mar-2003'.
-
- recent : If set to a true value, search for messages flagged with
- \\Recent
-
- seen : If set to a true value, search for messages flagged with
- \\Seen
-
- sentbefore : Search for messages with an RFC822 'Date' header before
- this date. The given date should be a string in the format
- of 'DD-Mon-YYYY'. For example, '03-Mar-2003'.
-
- senton : Search for messages with an RFC822 'Date' header which is
- on this date The given date should be a string in the format
- of 'DD-Mon-YYYY'. For example, '03-Mar-2003'.
-
- sentsince : Search for messages with an RFC822 'Date' header which is
- after this date. The given date should be a string in the format
- of 'DD-Mon-YYYY'. For example, '03-Mar-2003'.
-
- since : Search for messages with an internal date that is after
- this date.. The given date should be a string in the format
- of 'DD-Mon-YYYY'. For example, '03-Mar-2003'.
-
- smaller : Search for messages smaller than this number of octets
-
- subject : A substring to search the 'subject' header for
-
- text : A substring to search the entire message for
-
- to : A substring to search the 'to' header for
-
- uid : Search only the messages in the given message set
-
- unanswered : If set to a true value, search for messages not
- flagged with \\Answered
-
- undeleted : If set to a true value, search for messages not
- flagged with \\Deleted
-
- undraft : If set to a true value, search for messages not
- flagged with \\Draft
-
- unflagged : If set to a true value, search for messages not
- flagged with \\Flagged
-
- unkeyword : Search for messages without the given keyword set
-
- unseen : If set to a true value, search for messages not
- flagged with \\Seen
-
- @type sorted: C{bool}
- @param sorted: If true, the output will be sorted, alphabetically.
- The standard does not require it, but it makes testing this function
- easier. The default is zero, and this should be acceptable for any
- application.
-
- @rtype: C{str}
- @return: The formatted query string
- """
- cmd = []
- keys = kwarg.keys()
- if sorted:
- keys.sort()
- for k in keys:
- v = kwarg[k]
- k = k.upper()
- if k in _SIMPLE_BOOL and v:
- cmd.append(k)
- elif k == 'HEADER':
- cmd.extend([k, v[0], '"%s"' % (v[1],)])
- elif k not in _NO_QUOTES:
- cmd.extend([k, '"%s"' % (v,)])
- else:
- cmd.extend([k, '%s' % (v,)])
- if len(cmd) > 1:
- return '(%s)' % ' '.join(cmd)
- else:
- return ' '.join(cmd)
-
-def Or(*args):
- """The disjunction of two or more queries"""
- if len(args) < 2:
- raise IllegalQueryError, args
- elif len(args) == 2:
- return '(OR %s %s)' % args
- else:
- return '(OR %s %s)' % (args[0], Or(*args[1:]))
-
-def Not(query):
- """The negation of a query"""
- return '(NOT %s)' % (query,)
-
-class MismatchedNesting(IMAP4Exception):
- pass
-
-class MismatchedQuoting(IMAP4Exception):
- pass
-
-def wildcardToRegexp(wildcard, delim=None):
- wildcard = wildcard.replace('*', '(?:.*?)')
- if delim is None:
- wildcard = wildcard.replace('%', '(?:.*?)')
- else:
- wildcard = wildcard.replace('%', '(?:(?:[^%s])*?)' % re.escape(delim))
- return re.compile(wildcard, re.I)
-
-def splitQuoted(s):
- """Split a string into whitespace delimited tokens
-
- Tokens that would otherwise be separated but are surrounded by \"
- remain as a single token. Any token that is not quoted and is
- equal to \"NIL\" is tokenized as C{None}.
-
- @type s: C{str}
- @param s: The string to be split
-
- @rtype: C{list} of C{str}
- @return: A list of the resulting tokens
-
- @raise MismatchedQuoting: Raised if an odd number of quotes are present
- """
- s = s.strip()
- result = []
- word = []
- inQuote = inWord = False
- for i, c in enumerate(s):
- if c == '"':
- if i and s[i-1] == '\\':
- word.pop()
- word.append('"')
- elif not inQuote:
- inQuote = True
- else:
- inQuote = False
- result.append(''.join(word))
- word = []
- elif not inWord and not inQuote and c not in ('"' + string.whitespace):
- inWord = True
- word.append(c)
- elif inWord and not inQuote and c in string.whitespace:
- w = ''.join(word)
- if w == 'NIL':
- result.append(None)
- else:
- result.append(w)
- word = []
- inWord = False
- elif inWord or inQuote:
- word.append(c)
-
- if inQuote:
- raise MismatchedQuoting(s)
- if inWord:
- w = ''.join(word)
- if w == 'NIL':
- result.append(None)
- else:
- result.append(w)
-
- return result
-
-
-
-def splitOn(sequence, predicate, transformers):
- result = []
- mode = predicate(sequence[0])
- tmp = [sequence[0]]
- for e in sequence[1:]:
- p = predicate(e)
- if p != mode:
- result.extend(transformers[mode](tmp))
- tmp = [e]
- mode = p
- else:
- tmp.append(e)
- result.extend(transformers[mode](tmp))
- return result
-
-def collapseStrings(results):
- """
- Turns a list of length-one strings and lists into a list of longer
- strings and lists. For example,
-
- ['a', 'b', ['c', 'd']] is returned as ['ab', ['cd']]
-
- @type results: C{list} of C{str} and C{list}
- @param results: The list to be collapsed
-
- @rtype: C{list} of C{str} and C{list}
- @return: A new list which is the collapsed form of C{results}
- """
- copy = []
- begun = None
- listsList = [isinstance(s, types.ListType) for s in results]
-
- pred = lambda e: isinstance(e, types.TupleType)
- tran = {
- 0: lambda e: splitQuoted(''.join(e)),
- 1: lambda e: [''.join([i[0] for i in e])]
- }
- for (i, c, isList) in zip(range(len(results)), results, listsList):
- if isList:
- if begun is not None:
- copy.extend(splitOn(results[begun:i], pred, tran))
- begun = None
- copy.append(collapseStrings(c))
- elif begun is None:
- begun = i
- if begun is not None:
- copy.extend(splitOn(results[begun:], pred, tran))
- return copy
-
-
-def parseNestedParens(s, handleLiteral = 1):
- """Parse an s-exp-like string into a more useful data structure.
-
- @type s: C{str}
- @param s: The s-exp-like string to parse
-
- @rtype: C{list} of C{str} and C{list}
- @return: A list containing the tokens present in the input.
-
- @raise MismatchedNesting: Raised if the number or placement
- of opening or closing parenthesis is invalid.
- """
- s = s.strip()
- inQuote = 0
- contentStack = [[]]
- try:
- i = 0
- L = len(s)
- while i < L:
- c = s[i]
- if inQuote:
- if c == '\\':
- contentStack[-1].append(s[i:i+2])
- i += 2
- continue
- elif c == '"':
- inQuote = not inQuote
- contentStack[-1].append(c)
- i += 1
- else:
- if c == '"':
- contentStack[-1].append(c)
- inQuote = not inQuote
- i += 1
- elif handleLiteral and c == '{':
- end = s.find('}', i)
- if end == -1:
- raise ValueError, "Malformed literal"
- literalSize = int(s[i+1:end])
- contentStack[-1].append((s[end+3:end+3+literalSize],))
- i = end + 3 + literalSize
- elif c == '(' or c == '[':
- contentStack.append([])
- i += 1
- elif c == ')' or c == ']':
- contentStack[-2].append(contentStack.pop())
- i += 1
- else:
- contentStack[-1].append(c)
- i += 1
- except IndexError:
- raise MismatchedNesting(s)
- if len(contentStack) != 1:
- raise MismatchedNesting(s)
- return collapseStrings(contentStack[0])
-
-def _quote(s):
- return '"%s"' % (s.replace('\\', '\\\\').replace('"', '\\"'),)
-
-def _literal(s):
- return '{%d}\r\n%s' % (len(s), s)
-
-class DontQuoteMe:
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return str(self.value)
-
-_ATOM_SPECIALS = '(){ %*"'
-def _needsQuote(s):
- if s == '':
- return 1
- for c in s:
- if c < '\x20' or c > '\x7f':
- return 1
- if c in _ATOM_SPECIALS:
- return 1
- return 0
-
-def _prepareMailboxName(name):
- name = name.encode('imap4-utf-7')
- if _needsQuote(name):
- return _quote(name)
- return name
-
-def _needsLiteral(s):
- # Change this to "return 1" to wig out stupid clients
- return '\n' in s or '\r' in s or len(s) > 1000
-
-def collapseNestedLists(items):
- """Turn a nested list structure into an s-exp-like string.
-
- Strings in C{items} will be sent as literals if they contain CR or LF,
- otherwise they will be quoted. References to None in C{items} will be
- translated to the atom NIL. Objects with a 'read' attribute will have
- it called on them with no arguments and the returned string will be
- inserted into the output as a literal. Integers will be converted to
- strings and inserted into the output unquoted. Instances of
- C{DontQuoteMe} will be converted to strings and inserted into the output
- unquoted.
-
- This function used to be much nicer, and only quote things that really
- needed to be quoted (and C{DontQuoteMe} did not exist), however, many
- broken IMAP4 clients were unable to deal with this level of sophistication,
- forcing the current behavior to be adopted for practical reasons.
-
- @type items: Any iterable
-
- @rtype: C{str}
- """
- pieces = []
- for i in items:
- if i is None:
- pieces.extend([' ', 'NIL'])
- elif isinstance(i, (DontQuoteMe, int, long)):
- pieces.extend([' ', str(i)])
- elif isinstance(i, types.StringTypes):
- if _needsLiteral(i):
- pieces.extend([' ', '{', str(len(i)), '}', IMAP4Server.delimiter, i])
- else:
- pieces.extend([' ', _quote(i)])
- elif hasattr(i, 'read'):
- d = i.read()
- pieces.extend([' ', '{', str(len(d)), '}', IMAP4Server.delimiter, d])
- else:
- pieces.extend([' ', '(%s)' % (collapseNestedLists(i),)])
- return ''.join(pieces[1:])
-
-
-class IClientAuthentication(Interface):
- def getName():
- """Return an identifier associated with this authentication scheme.
-
- @rtype: C{str}
- """
-
- def challengeResponse(secret, challenge):
- """Generate a challenge response string"""
-
-
-
-class CramMD5ClientAuthenticator:
- implements(IClientAuthentication)
-
- def __init__(self, user):
- self.user = user
-
- def getName(self):
- return "CRAM-MD5"
-
- def challengeResponse(self, secret, chal):
- response = hmac.HMAC(secret, chal).hexdigest()
- return '%s %s' % (self.user, response)
-
-
-
-class LOGINAuthenticator:
- implements(IClientAuthentication)
-
- def __init__(self, user):
- self.user = user
- self.challengeResponse = self.challengeUsername
-
- def getName(self):
- return "LOGIN"
-
- def challengeUsername(self, secret, chal):
- # Respond to something like "Username:"
- self.challengeResponse = self.challengeSecret
- return self.user
-
- def challengeSecret(self, secret, chal):
- # Respond to something like "Password:"
- return secret
-
-class PLAINAuthenticator:
- implements(IClientAuthentication)
-
- def __init__(self, user):
- self.user = user
-
- def getName(self):
- return "PLAIN"
-
- def challengeResponse(self, secret, chal):
- return '\0%s\0%s' % (self.user, secret)
-
-
-class MailboxException(IMAP4Exception): pass
-
-class MailboxCollision(MailboxException):
- def __str__(self):
- return 'Mailbox named %s already exists' % self.args
-
-class NoSuchMailbox(MailboxException):
- def __str__(self):
- return 'No mailbox named %s exists' % self.args
-
-class ReadOnlyMailbox(MailboxException):
- def __str__(self):
- return 'Mailbox open in read-only state'
-
-
-class IAccount(Interface):
- """Interface for Account classes
-
- Implementors of this interface should consider implementing
- C{INamespacePresenter}.
- """
-
- def addMailbox(name, mbox = None):
- """Add a new mailbox to this account
-
- @type name: C{str}
- @param name: The name associated with this mailbox. It may not
- contain multiple hierarchical parts.
-
- @type mbox: An object implementing C{IMailbox}
- @param mbox: The mailbox to associate with this name. If C{None},
- a suitable default is created and used.
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the creation succeeds, or a deferred whose
- callback will be invoked when the creation succeeds.
-
- @raise MailboxException: Raised if this mailbox cannot be added for
- some reason. This may also be raised asynchronously, if a C{Deferred}
- is returned.
- """
-
- def create(pathspec):
- """Create a new mailbox from the given hierarchical name.
-
- @type pathspec: C{str}
- @param pathspec: The full hierarchical name of a new mailbox to create.
- If any of the inferior hierarchical names to this one do not exist,
- they are created as well.
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the creation succeeds, or a deferred whose
- callback will be invoked when the creation succeeds.
-
- @raise MailboxException: Raised if this mailbox cannot be added.
- This may also be raised asynchronously, if a C{Deferred} is
- returned.
- """
-
- def select(name, rw=True):
- """Acquire a mailbox, given its name.
-
- @type name: C{str}
- @param name: The mailbox to acquire
-
- @type rw: C{bool}
- @param rw: If a true value, request a read-write version of this
- mailbox. If a false value, request a read-only version.
-
- @rtype: Any object implementing C{IMailbox} or C{Deferred}
- @return: The mailbox object, or a C{Deferred} whose callback will
- be invoked with the mailbox object. None may be returned if the
- specified mailbox may not be selected for any reason.
- """
-
- def delete(name):
- """Delete the mailbox with the specified name.
-
- @type name: C{str}
- @param name: The mailbox to delete.
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the mailbox is successfully deleted, or a
- C{Deferred} whose callback will be invoked when the deletion
- completes.
-
- @raise MailboxException: Raised if this mailbox cannot be deleted.
- This may also be raised asynchronously, if a C{Deferred} is returned.
- """
-
- def rename(oldname, newname):
- """Rename a mailbox
-
- @type oldname: C{str}
- @param oldname: The current name of the mailbox to rename.
-
- @type newname: C{str}
- @param newname: The new name to associate with the mailbox.
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the mailbox is successfully renamed, or a
- C{Deferred} whose callback will be invoked when the rename operation
- is completed.
-
- @raise MailboxException: Raised if this mailbox cannot be
- renamed. This may also be raised asynchronously, if a C{Deferred}
- is returned.
- """
-
- def isSubscribed(name):
- """Check the subscription status of a mailbox
-
- @type name: C{str}
- @param name: The name of the mailbox to check
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the given mailbox is currently subscribed
- to, a false value otherwise. A C{Deferred} may also be returned
- whose callback will be invoked with one of these values.
- """
-
- def subscribe(name):
- """Subscribe to a mailbox
-
- @type name: C{str}
- @param name: The name of the mailbox to subscribe to
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the mailbox is subscribed to successfully,
- or a Deferred whose callback will be invoked with this value when
- the subscription is successful.
-
- @raise MailboxException: Raised if this mailbox cannot be
- subscribed to. This may also be raised asynchronously, if a
- C{Deferred} is returned.
- """
-
- def unsubscribe(name):
- """Unsubscribe from a mailbox
-
- @type name: C{str}
- @param name: The name of the mailbox to unsubscribe from
-
- @rtype: C{Deferred} or C{bool}
- @return: A true value if the mailbox is unsubscribed from successfully,
- or a Deferred whose callback will be invoked with this value when
- the unsubscription is successful.
-
- @raise MailboxException: Raised if this mailbox cannot be
- unsubscribed from. This may also be raised asynchronously, if a
- C{Deferred} is returned.
- """
-
- def listMailboxes(ref, wildcard):
- """List all the mailboxes that meet a certain criteria
-
- @type ref: C{str}
- @param ref: The context in which to apply the wildcard
-
- @type wildcard: C{str}
- @param wildcard: An expression against which to match mailbox names.
- '*' matches any number of characters in a mailbox name, and '%'
- matches similarly, but will not match across hierarchical boundaries.
-
- @rtype: C{list} of C{tuple}
- @return: A list of C{(mailboxName, mailboxObject)} which meet the
- given criteria. C{mailboxObject} should implement either
- C{IMailboxInfo} or C{IMailbox}. A Deferred may also be returned.
- """
-
-class INamespacePresenter(Interface):
- def getPersonalNamespaces():
- """Report the available personal namespaces.
-
- Typically there should be only one personal namespace. A common
- name for it is \"\", and its hierarchical delimiter is usually
- \"/\".
-
- @rtype: iterable of two-tuples of strings
- @return: The personal namespaces and their hierarchical delimiters.
- If no namespaces of this type exist, None should be returned.
- """
-
- def getSharedNamespaces():
- """Report the available shared namespaces.
-
- Shared namespaces do not belong to any individual user but are
- usually to one or more of them. Examples of shared namespaces
- might be \"#news\" for a usenet gateway.
-
- @rtype: iterable of two-tuples of strings
- @return: The shared namespaces and their hierarchical delimiters.
- If no namespaces of this type exist, None should be returned.
- """
-
- def getUserNamespaces():
- """Report the available user namespaces.
-
- These are namespaces that contain folders belonging to other users
- access to which this account has been granted.
-
- @rtype: iterable of two-tuples of strings
- @return: The user namespaces and their hierarchical delimiters.
- If no namespaces of this type exist, None should be returned.
- """
-
-
-class MemoryAccount(object):
- implements(IAccount, INamespacePresenter)
-
- mailboxes = None
- subscriptions = None
- top_id = 0
-
- def __init__(self, name):
- self.name = name
- self.mailboxes = {}
- self.subscriptions = []
-
- def allocateID(self):
- id = self.top_id
- self.top_id += 1
- return id
-
- ##
- ## IAccount
- ##
- def addMailbox(self, name, mbox = None):
- name = name.upper()
- if name in self.mailboxes:
- raise MailboxCollision, name
- if mbox is None:
- mbox = self._emptyMailbox(name, self.allocateID())
- self.mailboxes[name] = mbox
- return 1
-
- def create(self, pathspec):
- paths = filter(None, pathspec.split('/'))
- for accum in range(1, len(paths)):
- try:
- self.addMailbox('/'.join(paths[:accum]))
- except MailboxCollision:
- pass
- try:
- self.addMailbox('/'.join(paths))
- except MailboxCollision:
- if not pathspec.endswith('/'):
- return False
- return True
-
- def _emptyMailbox(self, name, id):
- raise NotImplementedError
-
- def select(self, name, readwrite=1):
- return self.mailboxes.get(name.upper())
-
- def delete(self, name):
- name = name.upper()
- # See if this mailbox exists at all
- mbox = self.mailboxes.get(name)
- if not mbox:
- raise MailboxException("No such mailbox")
- # See if this box is flagged \Noselect
- if r'\Noselect' in mbox.getFlags():
- # Check for hierarchically inferior mailboxes with this one
- # as part of their root.
- for others in self.mailboxes.keys():
- if others != name and others.startswith(name):
- raise MailboxException, "Hierarchically inferior mailboxes exist and \\Noselect is set"
- mbox.destroy()
-
- # iff there are no hierarchically inferior names, we will
- # delete it from our ken.
- if self._inferiorNames(name) > 1:
- del self.mailboxes[name]
-
- def rename(self, oldname, newname):
- oldname = oldname.upper()
- newname = newname.upper()
- if oldname not in self.mailboxes:
- raise NoSuchMailbox, oldname
-
- inferiors = self._inferiorNames(oldname)
- inferiors = [(o, o.replace(oldname, newname, 1)) for o in inferiors]
-
- for (old, new) in inferiors:
- if new in self.mailboxes:
- raise MailboxCollision, new
-
- for (old, new) in inferiors:
- self.mailboxes[new] = self.mailboxes[old]
- del self.mailboxes[old]
-
- def _inferiorNames(self, name):
- inferiors = []
- for infname in self.mailboxes.keys():
- if infname.startswith(name):
- inferiors.append(infname)
- return inferiors
-
- def isSubscribed(self, name):
- return name.upper() in self.subscriptions
-
- def subscribe(self, name):
- name = name.upper()
- if name not in self.subscriptions:
- self.subscriptions.append(name)
-
- def unsubscribe(self, name):
- name = name.upper()
- if name not in self.subscriptions:
- raise MailboxException, "Not currently subscribed to " + name
- self.subscriptions.remove(name)
-
- def listMailboxes(self, ref, wildcard):
- ref = self._inferiorNames(ref.upper())
- wildcard = wildcardToRegexp(wildcard, '/')
- return [(i, self.mailboxes[i]) for i in ref if wildcard.match(i)]
-
- ##
- ## INamespacePresenter
- ##
- def getPersonalNamespaces(self):
- return [["", "/"]]
-
- def getSharedNamespaces(self):
- return None
-
- def getOtherNamespaces(self):
- return None
-
-
-
-_statusRequestDict = {
- 'MESSAGES': 'getMessageCount',
- 'RECENT': 'getRecentCount',
- 'UIDNEXT': 'getUIDNext',
- 'UIDVALIDITY': 'getUIDValidity',
- 'UNSEEN': 'getUnseenCount'
-}
-def statusRequestHelper(mbox, names):
- r = {}
- for n in names:
- r[n] = getattr(mbox, _statusRequestDict[n.upper()])()
- return r
-
-def parseAddr(addr):
- if addr is None:
- return [(None, None, None),]
- addrs = email.Utils.getaddresses([addr])
- return [[fn or None, None] + addr.split('@') for fn, addr in addrs]
-
-def getEnvelope(msg):
- headers = msg.getHeaders(True)
- date = headers.get('date')
- subject = headers.get('subject')
- from_ = headers.get('from')
- sender = headers.get('sender', from_)
- reply_to = headers.get('reply-to', from_)
- to = headers.get('to')
- cc = headers.get('cc')
- bcc = headers.get('bcc')
- in_reply_to = headers.get('in-reply-to')
- mid = headers.get('message-id')
- return (date, subject, parseAddr(from_), parseAddr(sender),
- reply_to and parseAddr(reply_to), to and parseAddr(to),
- cc and parseAddr(cc), bcc and parseAddr(bcc), in_reply_to, mid)
-
-def getLineCount(msg):
- # XXX - Super expensive, CACHE THIS VALUE FOR LATER RE-USE
- # XXX - This must be the number of lines in the ENCODED version
- lines = 0
- for _ in msg.getBodyFile():
- lines += 1
- return lines
-
-def unquote(s):
- if s[0] == s[-1] == '"':
- return s[1:-1]
- return s
-
-
-def _getContentType(msg):
- """
- Return a two-tuple of the main and subtype of the given message.
- """
- attrs = None
- mm = msg.getHeaders(False, 'content-type').get('content-type', None)
- if mm:
- mm = ''.join(mm.splitlines())
- mimetype = mm.split(';')
- if mimetype:
- type = mimetype[0].split('/', 1)
- if len(type) == 1:
- major = type[0]
- minor = None
- elif len(type) == 2:
- major, minor = type
- else:
- major = minor = None
- attrs = dict(x.strip().lower().split('=', 1) for x in mimetype[1:])
- else:
- major = minor = None
- else:
- major = minor = None
- return major, minor, attrs
-
-
-
-def _getMessageStructure(message):
- """
- Construct an appropriate type of message structure object for the given
- message object.
-
- @param message: A L{IMessagePart} provider
-
- @return: A L{_MessageStructure} instance of the most specific type available
- for the given message, determined by inspecting the MIME type of the
- message.
- """
- main, subtype, attrs = _getContentType(message)
- if main is not None:
- main = main.lower()
- if subtype is not None:
- subtype = subtype.lower()
- if main == 'multipart':
- return _MultipartMessageStructure(message, subtype, attrs)
- elif (main, subtype) == ('message', 'rfc822'):
- return _RFC822MessageStructure(message, main, subtype, attrs)
- elif main == 'text':
- return _TextMessageStructure(message, main, subtype, attrs)
- else:
- return _SinglepartMessageStructure(message, main, subtype, attrs)
-
-
-
-class _MessageStructure(object):
- """
- L{_MessageStructure} is a helper base class for message structure classes
- representing the structure of particular kinds of messages, as defined by
- their MIME type.
- """
- def __init__(self, message, attrs):
- """
- @param message: An L{IMessagePart} provider which this structure object
- reports on.
-
- @param attrs: A C{dict} giving the parameters of the I{Content-Type}
- header of the message.
- """
- self.message = message
- self.attrs = attrs
-
-
- def _disposition(self, disp):
- """
- Parse a I{Content-Disposition} header into a two-sequence of the
- disposition and a flattened list of its parameters.
-
- @return: C{None} if there is no disposition header value, a C{list} with
- two elements otherwise.
- """
- if disp:
- disp = disp.split('; ')
- if len(disp) == 1:
- disp = (disp[0].lower(), None)
- elif len(disp) > 1:
- # XXX Poorly tested parser
- params = [x for param in disp[1:] for x in param.split('=', 1)]
- disp = [disp[0].lower(), params]
- return disp
- else:
- return None
-
-
- def _unquotedAttrs(self):
- """
- @return: The I{Content-Type} parameters, unquoted, as a flat list with
- each Nth element giving a parameter name and N+1th element giving
- the corresponding parameter value.
- """
- if self.attrs:
- unquoted = [(k, unquote(v)) for (k, v) in self.attrs.iteritems()]
- return [y for x in sorted(unquoted) for y in x]
- return None
-
-
-
-class _SinglepartMessageStructure(_MessageStructure):
- """
- L{_SinglepartMessageStructure} represents the message structure of a
- non-I{multipart/*} message.
- """
- _HEADERS = [
- 'content-id', 'content-description',
- 'content-transfer-encoding']
-
- def __init__(self, message, main, subtype, attrs):
- """
- @param message: An L{IMessagePart} provider which this structure object
- reports on.
-
- @param main: A C{str} giving the main MIME type of the message (for
- example, C{"text"}).
-
- @param subtype: A C{str} giving the MIME subtype of the message (for
- example, C{"plain"}).
-
- @param attrs: A C{dict} giving the parameters of the I{Content-Type}
- header of the message.
- """
- _MessageStructure.__init__(self, message, attrs)
- self.main = main
- self.subtype = subtype
- self.attrs = attrs
-
-
- def _basicFields(self):
- """
- Return a list of the basic fields for a single-part message.
- """
- headers = self.message.getHeaders(False, *self._HEADERS)
-
- # Number of octets total
- size = self.message.getSize()
-
- major, minor = self.main, self.subtype
-
- # content-type parameter list
- unquotedAttrs = self._unquotedAttrs()
-
- return [
- major, minor, unquotedAttrs,
- headers.get('content-id'),
- headers.get('content-description'),
- headers.get('content-transfer-encoding'),
- size,
- ]
-
-
- def encode(self, extended):
- """
- Construct and return a list of the basic and extended fields for a
- single-part message. The list suitable to be encoded into a BODY or
- BODYSTRUCTURE response.
- """
- result = self._basicFields()
- if extended:
- result.extend(self._extended())
- return result
-
-
- def _extended(self):
- """
- The extension data of a non-multipart body part are in the
- following order:
-
- 1. body MD5
-
- A string giving the body MD5 value as defined in [MD5].
-
- 2. body disposition
-
- A parenthesized list with the same content and function as
- the body disposition for a multipart body part.
-
- 3. body language
-
- A string or parenthesized list giving the body language
- value as defined in [LANGUAGE-TAGS].
-
- 4. body location
-
- A string list giving the body content URI as defined in
- [LOCATION].
-
- """
- result = []
- headers = self.message.getHeaders(
- False, 'content-md5', 'content-disposition',
- 'content-language', 'content-language')
-
- result.append(headers.get('content-md5'))
- result.append(self._disposition(headers.get('content-disposition')))
- result.append(headers.get('content-language'))
- result.append(headers.get('content-location'))
-
- return result
-
-
-
-class _TextMessageStructure(_SinglepartMessageStructure):
- """
- L{_TextMessageStructure} represents the message structure of a I{text/*}
- message.
- """
- def encode(self, extended):
- """
- A body type of type TEXT contains, immediately after the basic
- fields, the size of the body in text lines. Note that this
- size is the size in its content transfer encoding and not the
- resulting size after any decoding.
- """
- result = _SinglepartMessageStructure._basicFields(self)
- result.append(getLineCount(self.message))
- if extended:
- result.extend(self._extended())
- return result
-
-
-
-class _RFC822MessageStructure(_SinglepartMessageStructure):
- """
- L{_RFC822MessageStructure} represents the message structure of a
- I{message/rfc822} message.
- """
- def encode(self, extended):
- """
- A body type of type MESSAGE and subtype RFC822 contains,
- immediately after the basic fields, the envelope structure,
- body structure, and size in text lines of the encapsulated
- message.
- """
- result = _SinglepartMessageStructure.encode(self, extended)
- contained = self.message.getSubPart(0)
- result.append(getEnvelope(contained))
- result.append(getBodyStructure(contained, False))
- result.append(getLineCount(contained))
- return result
-
-
-
-class _MultipartMessageStructure(_MessageStructure):
- """
- L{_MultipartMessageStructure} represents the message structure of a
- I{multipart/*} message.
- """
- def __init__(self, message, subtype, attrs):
- """
- @param message: An L{IMessagePart} provider which this structure object
- reports on.
-
- @param subtype: A C{str} giving the MIME subtype of the message (for
- example, C{"plain"}).
-
- @param attrs: A C{dict} giving the parameters of the I{Content-Type}
- header of the message.
- """
- _MessageStructure.__init__(self, message, attrs)
- self.subtype = subtype
-
-
- def _getParts(self):
- """
- Return an iterator over all of the sub-messages of this message.
- """
- i = 0
- while True:
- try:
- part = self.message.getSubPart(i)
- except IndexError:
- break
- else:
- yield part
- i += 1
-
-
- def encode(self, extended):
- """
- Encode each sub-message and added the additional I{multipart} fields.
- """
- result = [_getMessageStructure(p).encode(extended) for p in self._getParts()]
- result.append(self.subtype)
- if extended:
- result.extend(self._extended())
- return result
-
-
- def _extended(self):
- """
- The extension data of a multipart body part are in the following order:
-
- 1. body parameter parenthesized list
- A parenthesized list of attribute/value pairs [e.g., ("foo"
- "bar" "baz" "rag") where "bar" is the value of "foo", and
- "rag" is the value of "baz"] as defined in [MIME-IMB].
-
- 2. body disposition
- A parenthesized list, consisting of a disposition type
- string, followed by a parenthesized list of disposition
- attribute/value pairs as defined in [DISPOSITION].
-
- 3. body language
- A string or parenthesized list giving the body language
- value as defined in [LANGUAGE-TAGS].
-
- 4. body location
- A string list giving the body content URI as defined in
- [LOCATION].
- """
- result = []
- headers = self.message.getHeaders(
- False, 'content-language', 'content-location',
- 'content-disposition')
-
- result.append(self._unquotedAttrs())
- result.append(self._disposition(headers.get('content-disposition')))
- result.append(headers.get('content-language', None))
- result.append(headers.get('content-location', None))
-
- return result
-
-
-
-def getBodyStructure(msg, extended=False):
- """
- RFC 3501, 7.4.2, BODYSTRUCTURE::
-
- A parenthesized list that describes the [MIME-IMB] body structure of a
- message. This is computed by the server by parsing the [MIME-IMB] header
- fields, defaulting various fields as necessary.
-
- For example, a simple text message of 48 lines and 2279 octets can have
- a body structure of: ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL
- "7BIT" 2279 48)
-
- This is represented as::
-
- ["TEXT", "PLAIN", ["CHARSET", "US-ASCII"], None, None, "7BIT", 2279, 48]
-
- These basic fields are documented in the RFC as:
-
- 1. body type
-
- A string giving the content media type name as defined in
- [MIME-IMB].
-
- 2. body subtype
-
- A string giving the content subtype name as defined in
- [MIME-IMB].
-
- 3. body parameter parenthesized list
-
- A parenthesized list of attribute/value pairs [e.g., ("foo"
- "bar" "baz" "rag") where "bar" is the value of "foo" and
- "rag" is the value of "baz"] as defined in [MIME-IMB].
-
- 4. body id
-
- A string giving the content id as defined in [MIME-IMB].
-
- 5. body description
-
- A string giving the content description as defined in
- [MIME-IMB].
-
- 6. body encoding
-
- A string giving the content transfer encoding as defined in
- [MIME-IMB].
-
- 7. body size
-
- A number giving the size of the body in octets. Note that this size is
- the size in its transfer encoding and not the resulting size after any
- decoding.
-
- Put another way, the body structure is a list of seven elements. The
- semantics of the elements of this list are:
-
- 1. Byte string giving the major MIME type
- 2. Byte string giving the minor MIME type
- 3. A list giving the Content-Type parameters of the message
- 4. A byte string giving the content identifier for the message part, or
- None if it has no content identifier.
- 5. A byte string giving the content description for the message part, or
- None if it has no content description.
- 6. A byte string giving the Content-Encoding of the message body
- 7. An integer giving the number of octets in the message body
-
- The RFC goes on::
-
- Multiple parts are indicated by parenthesis nesting. Instead of a body
- type as the first element of the parenthesized list, there is a sequence
- of one or more nested body structures. The second element of the
- parenthesized list is the multipart subtype (mixed, digest, parallel,
- alternative, etc.).
-
- For example, a two part message consisting of a text and a
- BASE64-encoded text attachment can have a body structure of: (("TEXT"
- "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152 23)("TEXT" "PLAIN"
- ("CHARSET" "US-ASCII" "NAME" "cc.diff")
- "<960723163407.20117h@cac.washington.edu>" "Compiler diff" "BASE64" 4554
- 73) "MIXED")
-
- This is represented as::
-
- [["TEXT", "PLAIN", ["CHARSET", "US-ASCII"], None, None, "7BIT", 1152,
- 23],
- ["TEXT", "PLAIN", ["CHARSET", "US-ASCII", "NAME", "cc.diff"],
- "<960723163407.20117h@cac.washington.edu>", "Compiler diff",
- "BASE64", 4554, 73],
- "MIXED"]
-
- In other words, a list of N + 1 elements, where N is the number of parts in
- the message. The first N elements are structures as defined by the previous
- section. The last element is the minor MIME subtype of the multipart
- message.
-
- Additionally, the RFC describes extension data::
-
- Extension data follows the multipart subtype. Extension data is never
- returned with the BODY fetch, but can be returned with a BODYSTRUCTURE
- fetch. Extension data, if present, MUST be in the defined order.
-
- The C{extended} flag controls whether extension data might be returned with
- the normal data.
- """
- return _getMessageStructure(msg).encode(extended)
-
-
-
-class IMessagePart(Interface):
- def getHeaders(negate, *names):
- """Retrieve a group of message headers.
-
- @type names: C{tuple} of C{str}
- @param names: The names of the headers to retrieve or omit.
-
- @type negate: C{bool}
- @param negate: If True, indicates that the headers listed in C{names}
- should be omitted from the return value, rather than included.
-
- @rtype: C{dict}
- @return: A mapping of header field names to header field values
- """
-
- def getBodyFile():
- """Retrieve a file object containing only the body of this message.
- """
-
- def getSize():
- """Retrieve the total size, in octets, of this message.
-
- @rtype: C{int}
- """
-
- def isMultipart():
- """Indicate whether this message has subparts.
-
- @rtype: C{bool}
- """
-
- def getSubPart(part):
- """Retrieve a MIME sub-message
-
- @type part: C{int}
- @param part: The number of the part to retrieve, indexed from 0.
-
- @raise IndexError: Raised if the specified part does not exist.
- @raise TypeError: Raised if this message is not multipart.
-
- @rtype: Any object implementing C{IMessagePart}.
- @return: The specified sub-part.
- """
-
-class IMessage(IMessagePart):
- def getUID():
- """Retrieve the unique identifier associated with this message.
- """
-
- def getFlags():
- """Retrieve the flags associated with this message.
-
- @rtype: C{iterable}
- @return: The flags, represented as strings.
- """
-
- def getInternalDate():
- """Retrieve the date internally associated with this message.
-
- @rtype: C{str}
- @return: An RFC822-formatted date string.
- """
-
-class IMessageFile(Interface):
- """Optional message interface for representing messages as files.
-
- If provided by message objects, this interface will be used instead
- the more complex MIME-based interface.
- """
- def open():
- """Return an file-like object opened for reading.
-
- Reading from the returned file will return all the bytes
- of which this message consists.
- """
-
-class ISearchableMailbox(Interface):
- def search(query, uid):
- """Search for messages that meet the given query criteria.
-
- If this interface is not implemented by the mailbox, L{IMailbox.fetch}
- and various methods of L{IMessage} will be used instead.
-
- Implementations which wish to offer better performance than the
- default implementation should implement this interface.
-
- @type query: C{list}
- @param query: The search criteria
-
- @type uid: C{bool}
- @param uid: If true, the IDs specified in the query are UIDs;
- otherwise they are message sequence IDs.
-
- @rtype: C{list} or C{Deferred}
- @return: A list of message sequence numbers or message UIDs which
- match the search criteria or a C{Deferred} whose callback will be
- invoked with such a list.
-
- @raise IllegalQueryError: Raised when query is not valid.
- """
-
-class IMessageCopier(Interface):
- def copy(messageObject):
- """Copy the given message object into this mailbox.
-
- The message object will be one which was previously returned by
- L{IMailbox.fetch}.
-
- Implementations which wish to offer better performance than the
- default implementation should implement this interface.
-
- If this interface is not implemented by the mailbox, IMailbox.addMessage
- will be used instead.
-
- @rtype: C{Deferred} or C{int}
- @return: Either the UID of the message or a Deferred which fires
- with the UID when the copy finishes.
- """
-
-class IMailboxInfo(Interface):
- """Interface specifying only the methods required for C{listMailboxes}.
-
- Implementations can return objects implementing only these methods for
- return to C{listMailboxes} if it can allow them to operate more
- efficiently.
- """
-
- def getFlags():
- """Return the flags defined in this mailbox
-
- Flags with the \\ prefix are reserved for use as system flags.
-
- @rtype: C{list} of C{str}
- @return: A list of the flags that can be set on messages in this mailbox.
- """
-
- def getHierarchicalDelimiter():
- """Get the character which delimits namespaces for in this mailbox.
-
- @rtype: C{str}
- """
-
-class IMailbox(IMailboxInfo):
- def getUIDValidity():
- """Return the unique validity identifier for this mailbox.
-
- @rtype: C{int}
- """
-
- def getUIDNext():
- """Return the likely UID for the next message added to this mailbox.
-
- @rtype: C{int}
- """
-
- def getUID(message):
- """Return the UID of a message in the mailbox
-
- @type message: C{int}
- @param message: The message sequence number
-
- @rtype: C{int}
- @return: The UID of the message.
- """
-
- def getMessageCount():
- """Return the number of messages in this mailbox.
-
- @rtype: C{int}
- """
-
- def getRecentCount():
- """Return the number of messages with the 'Recent' flag.
-
- @rtype: C{int}
- """
-
- def getUnseenCount():
- """Return the number of messages with the 'Unseen' flag.
-
- @rtype: C{int}
- """
-
- def isWriteable():
- """Get the read/write status of the mailbox.
-
- @rtype: C{int}
- @return: A true value if write permission is allowed, a false value otherwise.
- """
-
- def destroy():
- """Called before this mailbox is deleted, permanently.
-
- If necessary, all resources held by this mailbox should be cleaned
- up here. This function _must_ set the \\Noselect flag on this
- mailbox.
- """
-
- def requestStatus(names):
- """Return status information about this mailbox.
-
- Mailboxes which do not intend to do any special processing to
- generate the return value, C{statusRequestHelper} can be used
- to build the dictionary by calling the other interface methods
- which return the data for each name.
-
- @type names: Any iterable
- @param names: The status names to return information regarding.
- The possible values for each name are: MESSAGES, RECENT, UIDNEXT,
- UIDVALIDITY, UNSEEN.
-
- @rtype: C{dict} or C{Deferred}
- @return: A dictionary containing status information about the
- requested names is returned. If the process of looking this
- information up would be costly, a deferred whose callback will
- eventually be passed this dictionary is returned instead.
- """
-
- def addListener(listener):
- """Add a mailbox change listener
-
- @type listener: Any object which implements C{IMailboxListener}
- @param listener: An object to add to the set of those which will
- be notified when the contents of this mailbox change.
- """
-
- def removeListener(listener):
- """Remove a mailbox change listener
-
- @type listener: Any object previously added to and not removed from
- this mailbox as a listener.
- @param listener: The object to remove from the set of listeners.
-
- @raise ValueError: Raised when the given object is not a listener for
- this mailbox.
- """
-
- def addMessage(message, flags = (), date = None):
- """Add the given message to this mailbox.
-
- @type message: A file-like object
- @param message: The RFC822 formatted message
-
- @type flags: Any iterable of C{str}
- @param flags: The flags to associate with this message
-
- @type date: C{str}
- @param date: If specified, the date to associate with this
- message.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked with the message
- id if the message is added successfully and whose errback is
- invoked otherwise.
-
- @raise ReadOnlyMailbox: Raised if this Mailbox is not open for
- read-write.
- """
-
- def expunge():
- """Remove all messages flagged \\Deleted.
-
- @rtype: C{list} or C{Deferred}
- @return: The list of message sequence numbers which were deleted,
- or a C{Deferred} whose callback will be invoked with such a list.
-
- @raise ReadOnlyMailbox: Raised if this Mailbox is not open for
- read-write.
- """
-
- def fetch(messages, uid):
- """Retrieve one or more messages.
-
- @type messages: C{MessageSet}
- @param messages: The identifiers of messages to retrieve information
- about
-
- @type uid: C{bool}
- @param uid: If true, the IDs specified in the query are UIDs;
- otherwise they are message sequence IDs.
-
- @rtype: Any iterable of two-tuples of message sequence numbers and
- implementors of C{IMessage}.
- """
-
- def store(messages, flags, mode, uid):
- """Set the flags of one or more messages.
-
- @type messages: A MessageSet object with the list of messages requested
- @param messages: The identifiers of the messages to set the flags of.
-
- @type flags: sequence of C{str}
- @param flags: The flags to set, unset, or add.
-
- @type mode: -1, 0, or 1
- @param mode: If mode is -1, these flags should be removed from the
- specified messages. If mode is 1, these flags should be added to
- the specified messages. If mode is 0, all existing flags should be
- cleared and these flags should be added.
-
- @type uid: C{bool}
- @param uid: If true, the IDs specified in the query are UIDs;
- otherwise they are message sequence IDs.
-
- @rtype: C{dict} or C{Deferred}
- @return: A C{dict} mapping message sequence numbers to sequences of C{str}
- representing the flags set on the message after this operation has
- been performed, or a C{Deferred} whose callback will be invoked with
- such a C{dict}.
-
- @raise ReadOnlyMailbox: Raised if this mailbox is not open for
- read-write.
- """
-
-class ICloseableMailbox(Interface):
- """A supplementary interface for mailboxes which require cleanup on close.
-
- Implementing this interface is optional. If it is implemented, the protocol
- code will call the close method defined whenever a mailbox is closed.
- """
- def close():
- """Close this mailbox.
-
- @return: A C{Deferred} which fires when this mailbox
- has been closed, or None if the mailbox can be closed
- immediately.
- """
-
-def _formatHeaders(headers):
- hdrs = [': '.join((k.title(), '\r\n'.join(v.splitlines()))) for (k, v)
- in headers.iteritems()]
- hdrs = '\r\n'.join(hdrs) + '\r\n'
- return hdrs
-
-def subparts(m):
- i = 0
- try:
- while True:
- yield m.getSubPart(i)
- i += 1
- except IndexError:
- pass
-
-def iterateInReactor(i):
- """Consume an interator at most a single iteration per reactor iteration.
-
- If the iterator produces a Deferred, the next iteration will not occur
- until the Deferred fires, otherwise the next iteration will be taken
- in the next reactor iteration.
-
- @rtype: C{Deferred}
- @return: A deferred which fires (with None) when the iterator is
- exhausted or whose errback is called if there is an exception.
- """
- from twisted.internet import reactor
- d = defer.Deferred()
- def go(last):
- try:
- r = i.next()
- except StopIteration:
- d.callback(last)
- except:
- d.errback()
- else:
- if isinstance(r, defer.Deferred):
- r.addCallback(go)
- else:
- reactor.callLater(0, go, r)
- go(None)
- return d
-
-class MessageProducer:
- CHUNK_SIZE = 2 ** 2 ** 2 ** 2
-
- def __init__(self, msg, buffer = None, scheduler = None):
- """Produce this message.
-
- @param msg: The message I am to produce.
- @type msg: L{IMessage}
-
- @param buffer: A buffer to hold the message in. If None, I will
- use a L{tempfile.TemporaryFile}.
- @type buffer: file-like
- """
- self.msg = msg
- if buffer is None:
- buffer = tempfile.TemporaryFile()
- self.buffer = buffer
- if scheduler is None:
- scheduler = iterateInReactor
- self.scheduler = scheduler
- self.write = self.buffer.write
-
- def beginProducing(self, consumer):
- self.consumer = consumer
- return self.scheduler(self._produce())
-
- def _produce(self):
- headers = self.msg.getHeaders(True)
- boundary = None
- if self.msg.isMultipart():
- content = headers.get('content-type')
- parts = [x.split('=', 1) for x in content.split(';')[1:]]
- parts = dict([(k.lower().strip(), v) for (k, v) in parts])
- boundary = parts.get('boundary')
- if boundary is None:
- # Bastards
- boundary = '----=_%f_boundary_%f' % (time.time(), random.random())
- headers['content-type'] += '; boundary="%s"' % (boundary,)
- else:
- if boundary.startswith('"') and boundary.endswith('"'):
- boundary = boundary[1:-1]
-
- self.write(_formatHeaders(headers))
- self.write('\r\n')
- if self.msg.isMultipart():
- for p in subparts(self.msg):
- self.write('\r\n--%s\r\n' % (boundary,))
- yield MessageProducer(p, self.buffer, self.scheduler
- ).beginProducing(None
- )
- self.write('\r\n--%s--\r\n' % (boundary,))
- else:
- f = self.msg.getBodyFile()
- while True:
- b = f.read(self.CHUNK_SIZE)
- if b:
- self.buffer.write(b)
- yield None
- else:
- break
- if self.consumer:
- self.buffer.seek(0, 0)
- yield FileProducer(self.buffer
- ).beginProducing(self.consumer
- ).addCallback(lambda _: self
- )
-
-class _FetchParser:
- class Envelope:
- # Response should be a list of fields from the message:
- # date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to,
- # and message-id.
- #
- # from, sender, reply-to, to, cc, and bcc are themselves lists of
- # address information:
- # personal name, source route, mailbox name, host name
- #
- # reply-to and sender must not be None. If not present in a message
- # they should be defaulted to the value of the from field.
- type = 'envelope'
- __str__ = lambda self: 'envelope'
-
- class Flags:
- type = 'flags'
- __str__ = lambda self: 'flags'
-
- class InternalDate:
- type = 'internaldate'
- __str__ = lambda self: 'internaldate'
-
- class RFC822Header:
- type = 'rfc822header'
- __str__ = lambda self: 'rfc822.header'
-
- class RFC822Text:
- type = 'rfc822text'
- __str__ = lambda self: 'rfc822.text'
-
- class RFC822Size:
- type = 'rfc822size'
- __str__ = lambda self: 'rfc822.size'
-
- class RFC822:
- type = 'rfc822'
- __str__ = lambda self: 'rfc822'
-
- class UID:
- type = 'uid'
- __str__ = lambda self: 'uid'
-
- class Body:
- type = 'body'
- peek = False
- header = None
- mime = None
- text = None
- part = ()
- empty = False
- partialBegin = None
- partialLength = None
- def __str__(self):
- base = 'BODY'
- part = ''
- separator = ''
- if self.part:
- part = '.'.join([str(x + 1) for x in self.part])
- separator = '.'
-# if self.peek:
-# base += '.PEEK'
- if self.header:
- base += '[%s%s%s]' % (part, separator, self.header,)
- elif self.text:
- base += '[%s%sTEXT]' % (part, separator)
- elif self.mime:
- base += '[%s%sMIME]' % (part, separator)
- elif self.empty:
- base += '[%s]' % (part,)
- if self.partialBegin is not None:
- base += '<%d.%d>' % (self.partialBegin, self.partialLength)
- return base
-
- class BodyStructure:
- type = 'bodystructure'
- __str__ = lambda self: 'bodystructure'
-
- # These three aren't top-level, they don't need type indicators
- class Header:
- negate = False
- fields = None
- part = None
- def __str__(self):
- base = 'HEADER'
- if self.fields:
- base += '.FIELDS'
- if self.negate:
- base += '.NOT'
- fields = []
- for f in self.fields:
- f = f.title()
- if _needsQuote(f):
- f = _quote(f)
- fields.append(f)
- base += ' (%s)' % ' '.join(fields)
- if self.part:
- base = '.'.join([str(x + 1) for x in self.part]) + '.' + base
- return base
-
- class Text:
- pass
-
- class MIME:
- pass
-
- parts = None
-
- _simple_fetch_att = [
- ('envelope', Envelope),
- ('flags', Flags),
- ('internaldate', InternalDate),
- ('rfc822.header', RFC822Header),
- ('rfc822.text', RFC822Text),
- ('rfc822.size', RFC822Size),
- ('rfc822', RFC822),
- ('uid', UID),
- ('bodystructure', BodyStructure),
- ]
-
- def __init__(self):
- self.state = ['initial']
- self.result = []
- self.remaining = ''
-
- def parseString(self, s):
- s = self.remaining + s
- try:
- while s or self.state:
- # print 'Entering state_' + self.state[-1] + ' with', repr(s)
- state = self.state.pop()
- try:
- used = getattr(self, 'state_' + state)(s)
- except:
- self.state.append(state)
- raise
- else:
- # print state, 'consumed', repr(s[:used])
- s = s[used:]
- finally:
- self.remaining = s
-
- def state_initial(self, s):
- # In the initial state, the literals "ALL", "FULL", and "FAST"
- # are accepted, as is a ( indicating the beginning of a fetch_att
- # token, as is the beginning of a fetch_att token.
- if s == '':
- return 0
-
- l = s.lower()
- if l.startswith('all'):
- self.result.extend((
- self.Flags(), self.InternalDate(),
- self.RFC822Size(), self.Envelope()
- ))
- return 3
- if l.startswith('full'):
- self.result.extend((
- self.Flags(), self.InternalDate(),
- self.RFC822Size(), self.Envelope(),
- self.Body()
- ))
- return 4
- if l.startswith('fast'):
- self.result.extend((
- self.Flags(), self.InternalDate(), self.RFC822Size(),
- ))
- return 4
-
- if l.startswith('('):
- self.state.extend(('close_paren', 'maybe_fetch_att', 'fetch_att'))
- return 1
-
- self.state.append('fetch_att')
- return 0
-
- def state_close_paren(self, s):
- if s.startswith(')'):
- return 1
- raise Exception("Missing )")
-
- def state_whitespace(self, s):
- # Eat up all the leading whitespace
- if not s or not s[0].isspace():
- raise Exception("Whitespace expected, none found")
- i = 0
- for i in range(len(s)):
- if not s[i].isspace():
- break
- return i
-
- def state_maybe_fetch_att(self, s):
- if not s.startswith(')'):
- self.state.extend(('maybe_fetch_att', 'fetch_att', 'whitespace'))
- return 0
-
- def state_fetch_att(self, s):
- # Allowed fetch_att tokens are "ENVELOPE", "FLAGS", "INTERNALDATE",
- # "RFC822", "RFC822.HEADER", "RFC822.SIZE", "RFC822.TEXT", "BODY",
- # "BODYSTRUCTURE", "UID",
- # "BODY [".PEEK"] [<section>] ["<" <number> "." <nz_number> ">"]
-
- l = s.lower()
- for (name, cls) in self._simple_fetch_att:
- if l.startswith(name):
- self.result.append(cls())
- return len(name)
-
- b = self.Body()
- if l.startswith('body.peek'):
- b.peek = True
- used = 9
- elif l.startswith('body'):
- used = 4
- else:
- raise Exception("Nothing recognized in fetch_att: %s" % (l,))
-
- self.pending_body = b
- self.state.extend(('got_body', 'maybe_partial', 'maybe_section'))
- return used
-
- def state_got_body(self, s):
- self.result.append(self.pending_body)
- del self.pending_body
- return 0
-
- def state_maybe_section(self, s):
- if not s.startswith("["):
- return 0
-
- self.state.extend(('section', 'part_number'))
- return 1
-
- _partExpr = re.compile(r'(\d+(?:\.\d+)*)\.?')
- def state_part_number(self, s):
- m = self._partExpr.match(s)
- if m is not None:
- self.parts = [int(p) - 1 for p in m.groups()[0].split('.')]
- return m.end()
- else:
- self.parts = []
- return 0
-
- def state_section(self, s):
- # Grab "HEADER]" or "HEADER.FIELDS (Header list)]" or
- # "HEADER.FIELDS.NOT (Header list)]" or "TEXT]" or "MIME]" or
- # just "]".
-
- l = s.lower()
- used = 0
- if l.startswith(']'):
- self.pending_body.empty = True
- used += 1
- elif l.startswith('header]'):
- h = self.pending_body.header = self.Header()
- h.negate = True
- h.fields = ()
- used += 7
- elif l.startswith('text]'):
- self.pending_body.text = self.Text()
- used += 5
- elif l.startswith('mime]'):
- self.pending_body.mime = self.MIME()
- used += 5
- else:
- h = self.Header()
- if l.startswith('header.fields.not'):
- h.negate = True
- used += 17
- elif l.startswith('header.fields'):
- used += 13
- else:
- raise Exception("Unhandled section contents: %r" % (l,))
-
- self.pending_body.header = h
- self.state.extend(('finish_section', 'header_list', 'whitespace'))
- self.pending_body.part = tuple(self.parts)
- self.parts = None
- return used
-
- def state_finish_section(self, s):
- if not s.startswith(']'):
- raise Exception("section must end with ]")
- return 1
-
- def state_header_list(self, s):
- if not s.startswith('('):
- raise Exception("Header list must begin with (")
- end = s.find(')')
- if end == -1:
- raise Exception("Header list must end with )")
-
- headers = s[1:end].split()
- self.pending_body.header.fields = map(str.upper, headers)
- return end + 1
-
- def state_maybe_partial(self, s):
- # Grab <number.number> or nothing at all
- if not s.startswith('<'):
- return 0
- end = s.find('>')
- if end == -1:
- raise Exception("Found < but not >")
-
- partial = s[1:end]
- parts = partial.split('.', 1)
- if len(parts) != 2:
- raise Exception("Partial specification did not include two .-delimited integers")
- begin, length = map(int, parts)
- self.pending_body.partialBegin = begin
- self.pending_body.partialLength = length
-
- return end + 1
-
-class FileProducer:
- CHUNK_SIZE = 2 ** 2 ** 2 ** 2
-
- firstWrite = True
-
- def __init__(self, f):
- self.f = f
-
- def beginProducing(self, consumer):
- self.consumer = consumer
- self.produce = consumer.write
- d = self._onDone = defer.Deferred()
- self.consumer.registerProducer(self, False)
- return d
-
- def resumeProducing(self):
- b = ''
- if self.firstWrite:
- b = '{%d}\r\n' % self._size()
- self.firstWrite = False
- if not self.f:
- return
- b = b + self.f.read(self.CHUNK_SIZE)
- if not b:
- self.consumer.unregisterProducer()
- self._onDone.callback(self)
- self._onDone = self.f = self.consumer = None
- else:
- self.produce(b)
-
- def pauseProducing(self):
- pass
-
- def stopProducing(self):
- pass
-
- def _size(self):
- b = self.f.tell()
- self.f.seek(0, 2)
- e = self.f.tell()
- self.f.seek(b, 0)
- return e - b
-
-def parseTime(s):
- # XXX - This may require localization :(
- months = [
- 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct',
- 'nov', 'dec', 'january', 'february', 'march', 'april', 'may', 'june',
- 'july', 'august', 'september', 'october', 'november', 'december'
- ]
- expr = {
- 'day': r"(?P<day>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])",
- 'mon': r"(?P<mon>\w+)",
- 'year': r"(?P<year>\d\d\d\d)"
- }
- m = re.match('%(day)s-%(mon)s-%(year)s' % expr, s)
- if not m:
- raise ValueError, "Cannot parse time string %r" % (s,)
- d = m.groupdict()
- try:
- d['mon'] = 1 + (months.index(d['mon'].lower()) % 12)
- d['year'] = int(d['year'])
- d['day'] = int(d['day'])
- except ValueError:
- raise ValueError, "Cannot parse time string %r" % (s,)
- else:
- return time.struct_time(
- (d['year'], d['mon'], d['day'], 0, 0, 0, -1, -1, -1)
- )
-
-import codecs
-def modified_base64(s):
- s_utf7 = s.encode('utf-7')
- return s_utf7[1:-1].replace('/', ',')
-
-def modified_unbase64(s):
- s_utf7 = '+' + s.replace(',', '/') + '-'
- return s_utf7.decode('utf-7')
-
-def encoder(s, errors=None):
- """
- Encode the given C{unicode} string using the IMAP4 specific variation of
- UTF-7.
-
- @type s: C{unicode}
- @param s: The text to encode.
-
- @param errors: Policy for handling encoding errors. Currently ignored.
-
- @return: C{tuple} of a C{str} giving the encoded bytes and an C{int}
- giving the number of code units consumed from the input.
- """
- r = []
- _in = []
- for c in s:
- if ord(c) in (range(0x20, 0x26) + range(0x27, 0x7f)):
- if _in:
- r.extend(['&', modified_base64(''.join(_in)), '-'])
- del _in[:]
- r.append(str(c))
- elif c == '&':
- if _in:
- r.extend(['&', modified_base64(''.join(_in)), '-'])
- del _in[:]
- r.append('&-')
- else:
- _in.append(c)
- if _in:
- r.extend(['&', modified_base64(''.join(_in)), '-'])
- return (''.join(r), len(s))
-
-def decoder(s, errors=None):
- """
- Decode the given C{str} using the IMAP4 specific variation of UTF-7.
-
- @type s: C{str}
- @param s: The bytes to decode.
-
- @param errors: Policy for handling decoding errors. Currently ignored.
-
- @return: a C{tuple} of a C{unicode} string giving the text which was
- decoded and an C{int} giving the number of bytes consumed from the
- input.
- """
- r = []
- decode = []
- for c in s:
- if c == '&' and not decode:
- decode.append('&')
- elif c == '-' and decode:
- if len(decode) == 1:
- r.append('&')
- else:
- r.append(modified_unbase64(''.join(decode[1:])))
- decode = []
- elif decode:
- decode.append(c)
- else:
- r.append(c)
- if decode:
- r.append(modified_unbase64(''.join(decode[1:])))
- return (''.join(r), len(s))
-
-class StreamReader(codecs.StreamReader):
- def decode(self, s, errors='strict'):
- return decoder(s)
-
-class StreamWriter(codecs.StreamWriter):
- def encode(self, s, errors='strict'):
- return encoder(s)
-
-_codecInfo = (encoder, decoder, StreamReader, StreamWriter)
-try:
- _codecInfoClass = codecs.CodecInfo
-except AttributeError:
- pass
-else:
- _codecInfo = _codecInfoClass(*_codecInfo)
-
-def imap4_utf_7(name):
- if name == 'imap4-utf-7':
- return _codecInfo
-codecs.register(imap4_utf_7)
-
-__all__ = [
- # Protocol classes
- 'IMAP4Server', 'IMAP4Client',
-
- # Interfaces
- 'IMailboxListener', 'IClientAuthentication', 'IAccount', 'IMailbox',
- 'INamespacePresenter', 'ICloseableMailbox', 'IMailboxInfo',
- 'IMessage', 'IMessageCopier', 'IMessageFile', 'ISearchableMailbox',
-
- # Exceptions
- 'IMAP4Exception', 'IllegalClientResponse', 'IllegalOperation',
- 'IllegalMailboxEncoding', 'UnhandledResponse', 'NegativeResponse',
- 'NoSupportedAuthentication', 'IllegalServerResponse',
- 'IllegalIdentifierError', 'IllegalQueryError', 'MismatchedNesting',
- 'MismatchedQuoting', 'MailboxException', 'MailboxCollision',
- 'NoSuchMailbox', 'ReadOnlyMailbox',
-
- # Auth objects
- 'CramMD5ClientAuthenticator', 'PLAINAuthenticator', 'LOGINAuthenticator',
- 'PLAINCredentials', 'LOGINCredentials',
-
- # Simple query interface
- 'Query', 'Not', 'Or',
-
- # Miscellaneous
- 'MemoryAccount',
- 'statusRequestHelper',
-]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/mail.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/mail.py
deleted file mode 100755
index 07789aa8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/mail.py
+++ /dev/null
@@ -1,333 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mail -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Mail support for twisted python.
-"""
-
-# Twisted imports
-from twisted.internet import defer
-from twisted.application import service, internet
-from twisted.python import util
-from twisted.python import log
-
-from twisted import cred
-import twisted.cred.portal
-
-# Sibling imports
-from twisted.mail import protocols, smtp
-
-# System imports
-import os
-from zope.interface import implements, Interface
-
-
-class DomainWithDefaultDict:
- '''Simulate a dictionary with a default value for non-existing keys.
- '''
- def __init__(self, domains, default):
- self.domains = domains
- self.default = default
-
- def setDefaultDomain(self, domain):
- self.default = domain
-
- def has_key(self, name):
- return 1
-
- def fromkeys(klass, keys, value=None):
- d = klass()
- for k in keys:
- d[k] = value
- return d
- fromkeys = classmethod(fromkeys)
-
- def __contains__(self, name):
- return 1
-
- def __getitem__(self, name):
- return self.domains.get(name, self.default)
-
- def __setitem__(self, name, value):
- self.domains[name] = value
-
- def __delitem__(self, name):
- del self.domains[name]
-
- def __iter__(self):
- return iter(self.domains)
-
- def __len__(self):
- return len(self.domains)
-
-
- def __str__(self):
- """
- Return a string describing the underlying domain mapping of this
- object.
- """
- return '<DomainWithDefaultDict %s>' % (self.domains,)
-
-
- def __repr__(self):
- """
- Return a pseudo-executable string describing the underlying domain
- mapping of this object.
- """
- return 'DomainWithDefaultDict(%s)' % (self.domains,)
-
-
- def get(self, key, default=None):
- return self.domains.get(key, default)
-
- def copy(self):
- return DomainWithDefaultDict(self.domains.copy(), self.default)
-
- def iteritems(self):
- return self.domains.iteritems()
-
- def iterkeys(self):
- return self.domains.iterkeys()
-
- def itervalues(self):
- return self.domains.itervalues()
-
- def keys(self):
- return self.domains.keys()
-
- def values(self):
- return self.domains.values()
-
- def items(self):
- return self.domains.items()
-
- def popitem(self):
- return self.domains.popitem()
-
- def update(self, other):
- return self.domains.update(other)
-
- def clear(self):
- return self.domains.clear()
-
- def setdefault(self, key, default):
- return self.domains.setdefault(key, default)
-
-class IDomain(Interface):
- """An email domain."""
-
- def exists(user):
- """
- Check whether or not the specified user exists in this domain.
-
- @type user: C{twisted.protocols.smtp.User}
- @param user: The user to check
-
- @rtype: No-argument callable
- @return: A C{Deferred} which becomes, or a callable which
- takes no arguments and returns an object implementing C{IMessage}.
- This will be called and the returned object used to deliver the
- message when it arrives.
-
- @raise twisted.protocols.smtp.SMTPBadRcpt: Raised if the given
- user does not exist in this domain.
- """
-
- def addUser(user, password):
- """Add a username/password to this domain."""
-
- def startMessage(user):
- """Create and return a new message to be delivered to the given user.
-
- DEPRECATED. Implement validateTo() correctly instead.
- """
-
- def getCredentialsCheckers():
- """Return a list of ICredentialsChecker implementors for this domain.
- """
-
-class IAliasableDomain(IDomain):
- def setAliasGroup(aliases):
- """Set the group of defined aliases for this domain
-
- @type aliases: C{dict}
- @param aliases: Mapping of domain names to objects implementing
- C{IAlias}
- """
-
- def exists(user, memo=None):
- """
- Check whether or not the specified user exists in this domain.
-
- @type user: C{twisted.protocols.smtp.User}
- @param user: The user to check
-
- @type memo: C{dict}
- @param memo: A record of the addresses already considered while
- resolving aliases. The default value should be used by all
- external code.
-
- @rtype: No-argument callable
- @return: A C{Deferred} which becomes, or a callable which
- takes no arguments and returns an object implementing C{IMessage}.
- This will be called and the returned object used to deliver the
- message when it arrives.
-
- @raise twisted.protocols.smtp.SMTPBadRcpt: Raised if the given
- user does not exist in this domain.
- """
-
-class BounceDomain:
- """A domain in which no user exists.
-
- This can be used to block off certain domains.
- """
-
- implements(IDomain)
-
- def exists(self, user):
- raise smtp.SMTPBadRcpt(user)
-
- def willRelay(self, user, protocol):
- return False
-
- def addUser(self, user, password):
- pass
-
- def startMessage(self, user):
- """
- No code should ever call this function.
- """
- raise NotImplementedError(
- "No code should ever call this method for any reason")
-
- def getCredentialsCheckers(self):
- return []
-
-
-class FileMessage:
- """A file we can write an email too."""
-
- implements(smtp.IMessage)
-
- def __init__(self, fp, name, finalName):
- self.fp = fp
- self.name = name
- self.finalName = finalName
-
- def lineReceived(self, line):
- self.fp.write(line+'\n')
-
- def eomReceived(self):
- self.fp.close()
- os.rename(self.name, self.finalName)
- return defer.succeed(self.finalName)
-
- def connectionLost(self):
- self.fp.close()
- os.remove(self.name)
-
-
-class MailService(service.MultiService):
- """An email service."""
-
- queue = None
- domains = None
- portals = None
- aliases = None
- smtpPortal = None
-
- def __init__(self):
- service.MultiService.__init__(self)
- # Domains and portals for "client" protocols - POP3, IMAP4, etc
- self.domains = DomainWithDefaultDict({}, BounceDomain())
- self.portals = {}
-
- self.monitor = FileMonitoringService()
- self.monitor.setServiceParent(self)
- self.smtpPortal = cred.portal.Portal(self)
-
- def getPOP3Factory(self):
- return protocols.POP3Factory(self)
-
- def getSMTPFactory(self):
- return protocols.SMTPFactory(self, self.smtpPortal)
-
- def getESMTPFactory(self):
- return protocols.ESMTPFactory(self, self.smtpPortal)
-
- def addDomain(self, name, domain):
- portal = cred.portal.Portal(domain)
- map(portal.registerChecker, domain.getCredentialsCheckers())
- self.domains[name] = domain
- self.portals[name] = portal
- if self.aliases and IAliasableDomain.providedBy(domain):
- domain.setAliasGroup(self.aliases)
-
- def setQueue(self, queue):
- """Set the queue for outgoing emails."""
- self.queue = queue
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if smtp.IMessageDelivery in interfaces:
- a = protocols.ESMTPDomainDelivery(self, avatarId)
- return smtp.IMessageDelivery, a, lambda: None
- raise NotImplementedError()
-
- def lookupPortal(self, name):
- return self.portals[name]
-
- def defaultPortal(self):
- return self.portals['']
-
-
-class FileMonitoringService(internet.TimerService):
-
- def __init__(self):
- self.files = []
- self.intervals = iter(util.IntervalDifferential([], 60))
-
- def startService(self):
- service.Service.startService(self)
- self._setupMonitor()
-
- def _setupMonitor(self):
- from twisted.internet import reactor
- t, self.index = self.intervals.next()
- self._call = reactor.callLater(t, self._monitor)
-
- def stopService(self):
- service.Service.stopService(self)
- if self._call:
- self._call.cancel()
- self._call = None
-
- def monitorFile(self, name, callback, interval=10):
- try:
- mtime = os.path.getmtime(name)
- except:
- mtime = 0
- self.files.append([interval, name, callback, mtime])
- self.intervals.addInterval(interval)
-
- def unmonitorFile(self, name):
- for i in range(len(self.files)):
- if name == self.files[i][1]:
- self.intervals.removeInterval(self.files[i][0])
- del self.files[i]
- break
-
- def _monitor(self):
- self._call = None
- if self.index is not None:
- name, callback, mtime = self.files[self.index][1:]
- try:
- now = os.path.getmtime(name)
- except:
- now = 0
- if now > mtime:
- log.msg("%s changed, notifying listener" % (name,))
- self.files[self.index][3] = now
- callback(name)
- self._setupMonitor()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/maildir.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/maildir.py
deleted file mode 100755
index 7927b325..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/maildir.py
+++ /dev/null
@@ -1,518 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mail -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Maildir-style mailbox support
-"""
-
-import os
-import stat
-import socket
-
-from zope.interface import implements
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-from twisted.python.compat import set
-from twisted.mail import pop3
-from twisted.mail import smtp
-from twisted.protocols import basic
-from twisted.persisted import dirdbm
-from twisted.python import log, failure
-from twisted.python.hashlib import md5
-from twisted.mail import mail
-from twisted.internet import interfaces, defer, reactor
-from twisted.cred import portal, credentials, checkers
-from twisted.cred.error import UnauthorizedLogin
-
-INTERNAL_ERROR = '''\
-From: Twisted.mail Internals
-Subject: An Error Occurred
-
- An internal server error has occurred. Please contact the
- server administrator.
-'''
-
-class _MaildirNameGenerator:
- """
- Utility class to generate a unique maildir name
-
- @ivar _clock: An L{IReactorTime} provider which will be used to learn
- the current time to include in names returned by L{generate} so that
- they sort properly.
- """
- n = 0
- p = os.getpid()
- s = socket.gethostname().replace('/', r'\057').replace(':', r'\072')
-
- def __init__(self, clock):
- self._clock = clock
-
- def generate(self):
- """
- Return a string which is intended to unique across all calls to this
- function (across all processes, reboots, etc).
-
- Strings returned by earlier calls to this method will compare less
- than strings returned by later calls as long as the clock provided
- doesn't go backwards.
- """
- self.n = self.n + 1
- t = self._clock.seconds()
- seconds = str(int(t))
- microseconds = '%07d' % (int((t - int(t)) * 10e6),)
- return '%s.M%sP%sQ%s.%s' % (seconds, microseconds,
- self.p, self.n, self.s)
-
-_generateMaildirName = _MaildirNameGenerator(reactor).generate
-
-def initializeMaildir(dir):
- if not os.path.isdir(dir):
- os.mkdir(dir, 0700)
- for subdir in ['new', 'cur', 'tmp', '.Trash']:
- os.mkdir(os.path.join(dir, subdir), 0700)
- for subdir in ['new', 'cur', 'tmp']:
- os.mkdir(os.path.join(dir, '.Trash', subdir), 0700)
- # touch
- open(os.path.join(dir, '.Trash', 'maildirfolder'), 'w').close()
-
-
-class MaildirMessage(mail.FileMessage):
- size = None
-
- def __init__(self, address, fp, *a, **kw):
- header = "Delivered-To: %s\n" % address
- fp.write(header)
- self.size = len(header)
- mail.FileMessage.__init__(self, fp, *a, **kw)
-
- def lineReceived(self, line):
- mail.FileMessage.lineReceived(self, line)
- self.size += len(line)+1
-
- def eomReceived(self):
- self.finalName = self.finalName+',S=%d' % self.size
- return mail.FileMessage.eomReceived(self)
-
-class AbstractMaildirDomain:
- """Abstract maildir-backed domain.
- """
- alias = None
- root = None
-
- def __init__(self, service, root):
- """Initialize.
- """
- self.root = root
-
- def userDirectory(self, user):
- """Get the maildir directory for a given user
-
- Override to specify where to save mails for users.
- Return None for non-existing users.
- """
- return None
-
- ##
- ## IAliasableDomain
- ##
-
- def setAliasGroup(self, alias):
- self.alias = alias
-
- ##
- ## IDomain
- ##
- def exists(self, user, memo=None):
- """Check for existence of user in the domain
- """
- if self.userDirectory(user.dest.local) is not None:
- return lambda: self.startMessage(user)
- try:
- a = self.alias[user.dest.local]
- except:
- raise smtp.SMTPBadRcpt(user)
- else:
- aliases = a.resolve(self.alias, memo)
- if aliases:
- return lambda: aliases
- log.err("Bad alias configuration: " + str(user))
- raise smtp.SMTPBadRcpt(user)
-
- def startMessage(self, user):
- """Save a message for a given user
- """
- if isinstance(user, str):
- name, domain = user.split('@', 1)
- else:
- name, domain = user.dest.local, user.dest.domain
- dir = self.userDirectory(name)
- fname = _generateMaildirName()
- filename = os.path.join(dir, 'tmp', fname)
- fp = open(filename, 'w')
- return MaildirMessage('%s@%s' % (name, domain), fp, filename,
- os.path.join(dir, 'new', fname))
-
- def willRelay(self, user, protocol):
- return False
-
- def addUser(self, user, password):
- raise NotImplementedError
-
- def getCredentialsCheckers(self):
- raise NotImplementedError
- ##
- ## end of IDomain
- ##
-
-class _MaildirMailboxAppendMessageTask:
- implements(interfaces.IConsumer)
-
- osopen = staticmethod(os.open)
- oswrite = staticmethod(os.write)
- osclose = staticmethod(os.close)
- osrename = staticmethod(os.rename)
-
- def __init__(self, mbox, msg):
- self.mbox = mbox
- self.defer = defer.Deferred()
- self.openCall = None
- if not hasattr(msg, "read"):
- msg = StringIO.StringIO(msg)
- self.msg = msg
-
- def startUp(self):
- self.createTempFile()
- if self.fh != -1:
- self.filesender = basic.FileSender()
- self.filesender.beginFileTransfer(self.msg, self)
-
- def registerProducer(self, producer, streaming):
- self.myproducer = producer
- self.streaming = streaming
- if not streaming:
- self.prodProducer()
-
- def prodProducer(self):
- self.openCall = None
- if self.myproducer is not None:
- self.openCall = reactor.callLater(0, self.prodProducer)
- self.myproducer.resumeProducing()
-
- def unregisterProducer(self):
- self.myproducer = None
- self.streaming = None
- self.osclose(self.fh)
- self.moveFileToNew()
-
- def write(self, data):
- try:
- self.oswrite(self.fh, data)
- except:
- self.fail()
-
- def fail(self, err=None):
- if err is None:
- err = failure.Failure()
- if self.openCall is not None:
- self.openCall.cancel()
- self.defer.errback(err)
- self.defer = None
-
- def moveFileToNew(self):
- while True:
- newname = os.path.join(self.mbox.path, "new", _generateMaildirName())
- try:
- self.osrename(self.tmpname, newname)
- break
- except OSError, (err, estr):
- import errno
- # if the newname exists, retry with a new newname.
- if err != errno.EEXIST:
- self.fail()
- newname = None
- break
- if newname is not None:
- self.mbox.list.append(newname)
- self.defer.callback(None)
- self.defer = None
-
- def createTempFile(self):
- attr = (os.O_RDWR | os.O_CREAT | os.O_EXCL
- | getattr(os, "O_NOINHERIT", 0)
- | getattr(os, "O_NOFOLLOW", 0))
- tries = 0
- self.fh = -1
- while True:
- self.tmpname = os.path.join(self.mbox.path, "tmp", _generateMaildirName())
- try:
- self.fh = self.osopen(self.tmpname, attr, 0600)
- return None
- except OSError:
- tries += 1
- if tries > 500:
- self.defer.errback(RuntimeError("Could not create tmp file for %s" % self.mbox.path))
- self.defer = None
- return None
-
-class MaildirMailbox(pop3.Mailbox):
- """Implement the POP3 mailbox semantics for a Maildir mailbox
- """
- AppendFactory = _MaildirMailboxAppendMessageTask
-
- def __init__(self, path):
- """Initialize with name of the Maildir mailbox
- """
- self.path = path
- self.list = []
- self.deleted = {}
- initializeMaildir(path)
- for name in ('cur', 'new'):
- for file in os.listdir(os.path.join(path, name)):
- self.list.append((file, os.path.join(path, name, file)))
- self.list.sort()
- self.list = [e[1] for e in self.list]
-
- def listMessages(self, i=None):
- """Return a list of lengths of all files in new/ and cur/
- """
- if i is None:
- ret = []
- for mess in self.list:
- if mess:
- ret.append(os.stat(mess)[stat.ST_SIZE])
- else:
- ret.append(0)
- return ret
- return self.list[i] and os.stat(self.list[i])[stat.ST_SIZE] or 0
-
- def getMessage(self, i):
- """Return an open file-pointer to a message
- """
- return open(self.list[i])
-
- def getUidl(self, i):
- """Return a unique identifier for a message
-
- This is done using the basename of the filename.
- It is globally unique because this is how Maildirs are designed.
- """
- # Returning the actual filename is a mistake. Hash it.
- base = os.path.basename(self.list[i])
- return md5(base).hexdigest()
-
- def deleteMessage(self, i):
- """Delete a message
-
- This only moves a message to the .Trash/ subfolder,
- so it can be undeleted by an administrator.
- """
- trashFile = os.path.join(
- self.path, '.Trash', 'cur', os.path.basename(self.list[i])
- )
- os.rename(self.list[i], trashFile)
- self.deleted[self.list[i]] = trashFile
- self.list[i] = 0
-
- def undeleteMessages(self):
- """Undelete any deleted messages it is possible to undelete
-
- This moves any messages from .Trash/ subfolder back to their
- original position, and empties out the deleted dictionary.
- """
- for (real, trash) in self.deleted.items():
- try:
- os.rename(trash, real)
- except OSError, (err, estr):
- import errno
- # If the file has been deleted from disk, oh well!
- if err != errno.ENOENT:
- raise
- # This is a pass
- else:
- try:
- self.list[self.list.index(0)] = real
- except ValueError:
- self.list.append(real)
- self.deleted.clear()
-
- def appendMessage(self, txt):
- """
- Appends a message into the mailbox.
-
- @param txt: A C{str} or file-like object giving the message to append.
-
- @return: A L{Deferred} which fires when the message has been appended to
- the mailbox.
- """
- task = self.AppendFactory(self, txt)
- result = task.defer
- task.startUp()
- return result
-
-class StringListMailbox:
- """
- L{StringListMailbox} is an in-memory mailbox.
-
- @ivar msgs: A C{list} of C{str} giving the contents of each message in the
- mailbox.
-
- @ivar _delete: A C{set} of the indexes of messages which have been deleted
- since the last C{sync} call.
- """
- implements(pop3.IMailbox)
-
- def __init__(self, msgs):
- self.msgs = msgs
- self._delete = set()
-
-
- def listMessages(self, i=None):
- """
- Return the length of the message at the given offset, or a list of all
- message lengths.
- """
- if i is None:
- return [self.listMessages(i) for i in range(len(self.msgs))]
- if i in self._delete:
- return 0
- return len(self.msgs[i])
-
-
- def getMessage(self, i):
- """
- Return an in-memory file-like object for the message content at the
- given offset.
- """
- return StringIO.StringIO(self.msgs[i])
-
-
- def getUidl(self, i):
- """
- Return a hash of the contents of the message at the given offset.
- """
- return md5(self.msgs[i]).hexdigest()
-
-
- def deleteMessage(self, i):
- """
- Mark the given message for deletion.
- """
- self._delete.add(i)
-
-
- def undeleteMessages(self):
- """
- Reset deletion tracking, undeleting any messages which have been
- deleted since the last call to C{sync}.
- """
- self._delete = set()
-
-
- def sync(self):
- """
- Discard the contents of any message marked for deletion and reset
- deletion tracking.
- """
- for index in self._delete:
- self.msgs[index] = ""
- self._delete = set()
-
-
-
-class MaildirDirdbmDomain(AbstractMaildirDomain):
- """A Maildir Domain where membership is checked by a dirdbm file
- """
-
- implements(portal.IRealm, mail.IAliasableDomain)
-
- portal = None
- _credcheckers = None
-
- def __init__(self, service, root, postmaster=0):
- """Initialize
-
- The first argument is where the Domain directory is rooted.
- The second is whether non-existing addresses are simply
- forwarded to postmaster instead of outright bounce
-
- The directory structure of a MailddirDirdbmDomain is:
-
- /passwd <-- a dirdbm file
- /USER/{cur,new,del} <-- each user has these three directories
- """
- AbstractMaildirDomain.__init__(self, service, root)
- dbm = os.path.join(root, 'passwd')
- if not os.path.exists(dbm):
- os.makedirs(dbm)
- self.dbm = dirdbm.open(dbm)
- self.postmaster = postmaster
-
- def userDirectory(self, name):
- """Get the directory for a user
-
- If the user exists in the dirdbm file, return the directory
- os.path.join(root, name), creating it if necessary.
- Otherwise, returns postmaster's mailbox instead if bounces
- go to postmaster, otherwise return None
- """
- if not self.dbm.has_key(name):
- if not self.postmaster:
- return None
- name = 'postmaster'
- dir = os.path.join(self.root, name)
- if not os.path.exists(dir):
- initializeMaildir(dir)
- return dir
-
- ##
- ## IDomain
- ##
- def addUser(self, user, password):
- self.dbm[user] = password
- # Ensure it is initialized
- self.userDirectory(user)
-
- def getCredentialsCheckers(self):
- if self._credcheckers is None:
- self._credcheckers = [DirdbmDatabase(self.dbm)]
- return self._credcheckers
-
- ##
- ## IRealm
- ##
- def requestAvatar(self, avatarId, mind, *interfaces):
- if pop3.IMailbox not in interfaces:
- raise NotImplementedError("No interface")
- if avatarId == checkers.ANONYMOUS:
- mbox = StringListMailbox([INTERNAL_ERROR])
- else:
- mbox = MaildirMailbox(os.path.join(self.root, avatarId))
-
- return (
- pop3.IMailbox,
- mbox,
- lambda: None
- )
-
-class DirdbmDatabase:
- implements(checkers.ICredentialsChecker)
-
- credentialInterfaces = (
- credentials.IUsernamePassword,
- credentials.IUsernameHashedPassword
- )
-
- def __init__(self, dbm):
- self.dirdbm = dbm
-
- def requestAvatarId(self, c):
- if c.username in self.dirdbm:
- if c.checkPassword(self.dirdbm[c.username]):
- return c.username
- raise UnauthorizedLogin()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pb.py
deleted file mode 100755
index 8a9417fa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pb.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.spread import pb
-from twisted.spread import banana
-
-import os
-import types
-
-class Maildir(pb.Referenceable):
-
- def __init__(self, directory, rootDirectory):
- self.virtualDirectory = directory
- self.rootDirectory = rootDirectory
- self.directory = os.path.join(rootDirectory, directory)
-
- def getFolderMessage(self, folder, name):
- if '/' in name:
- raise IOError("can only open files in '%s' directory'" % folder)
- fp = open(os.path.join(self.directory, 'new', name))
- try:
- return fp.read()
- finally:
- fp.close()
-
- def deleteFolderMessage(self, folder, name):
- if '/' in name:
- raise IOError("can only delete files in '%s' directory'" % folder)
- os.rename(os.path.join(self.directory, folder, name),
- os.path.join(self.rootDirectory, '.Trash', folder, name))
-
- def deleteNewMessage(self, name):
- return self.deleteFolderMessage('new', name)
- remote_deleteNewMessage = deleteNewMessage
-
- def deleteCurMessage(self, name):
- return self.deleteFolderMessage('cur', name)
- remote_deleteCurMessage = deleteCurMessage
-
- def getNewMessages(self):
- return os.listdir(os.path.join(self.directory, 'new'))
- remote_getNewMessages = getNewMessages
-
- def getCurMessages(self):
- return os.listdir(os.path.join(self.directory, 'cur'))
- remote_getCurMessages = getCurMessages
-
- def getNewMessage(self, name):
- return self.getFolderMessage('new', name)
- remote_getNewMessage = getNewMessage
-
- def getCurMessage(self, name):
- return self.getFolderMessage('cur', name)
- remote_getCurMessage = getCurMessage
-
- def getSubFolder(self, name):
- if name[0] == '.':
- raise IOError("subfolder name cannot begin with a '.'")
- name = name.replace('/', ':')
- if self.virtualDirectoy == '.':
- name = '.'+name
- else:
- name = self.virtualDirectory+':'+name
- if not self._isSubFolder(name):
- raise IOError("not a subfolder")
- return Maildir(name, self.rootDirectory)
- remote_getSubFolder = getSubFolder
-
- def _isSubFolder(self, name):
- return (not os.path.isdir(os.path.join(self.rootDirectory, name)) or
- not os.path.isfile(os.path.join(self.rootDirectory, name,
- 'maildirfolder')))
-
-
-class MaildirCollection(pb.Referenceable):
-
- def __init__(self, root):
- self.root = root
-
- def getSubFolders(self):
- return os.listdir(self.getRoot())
- remote_getSubFolders = getSubFolders
-
- def getSubFolder(self, name):
- if '/' in name or name[0] == '.':
- raise IOError("invalid name")
- return Maildir('.', os.path.join(self.getRoot(), name))
- remote_getSubFolder = getSubFolder
-
-
-class MaildirBroker(pb.Broker):
-
- def proto_getCollection(self, requestID, name, domain, password):
- collection = self._getCollection()
- if collection is None:
- self.sendError(requestID, "permission denied")
- else:
- self.sendAnswer(requestID, collection)
-
- def getCollection(self, name, domain, password):
- if not self.domains.has_key(domain):
- return
- domain = self.domains[domain]
- if (domain.dbm.has_key(name) and
- domain.dbm[name] == password):
- return MaildirCollection(domain.userDirectory(name))
-
-
-class MaildirClient(pb.Broker):
-
- def getCollection(self, name, domain, password, callback, errback):
- requestID = self.newRequestID()
- self.waitingForAnswers[requestID] = callback, errback
- self.sendCall("getCollection", requestID, name, domain, password)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3.py
deleted file mode 100755
index 3b65242d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3.py
+++ /dev/null
@@ -1,1071 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_pop3 -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Post-office Protocol version 3
-
-@author: Glyph Lefkowitz
-@author: Jp Calderone
-"""
-
-import base64
-import binascii
-import warnings
-
-from zope.interface import implements, Interface
-
-from twisted.mail import smtp
-from twisted.protocols import basic
-from twisted.protocols import policies
-from twisted.internet import task
-from twisted.internet import defer
-from twisted.internet import interfaces
-from twisted.python import log
-from twisted.python.hashlib import md5
-
-from twisted import cred
-import twisted.cred.error
-import twisted.cred.credentials
-
-##
-## Authentication
-##
-class APOPCredentials:
- implements(cred.credentials.IUsernamePassword)
-
- def __init__(self, magic, username, digest):
- self.magic = magic
- self.username = username
- self.digest = digest
-
- def checkPassword(self, password):
- seed = self.magic + password
- myDigest = md5(seed).hexdigest()
- return myDigest == self.digest
-
-
-class _HeadersPlusNLines:
- def __init__(self, f, n):
- self.f = f
- self.n = n
- self.linecount = 0
- self.headers = 1
- self.done = 0
- self.buf = ''
-
- def read(self, bytes):
- if self.done:
- return ''
- data = self.f.read(bytes)
- if not data:
- return data
- if self.headers:
- df, sz = data.find('\r\n\r\n'), 4
- if df == -1:
- df, sz = data.find('\n\n'), 2
- if df != -1:
- df += sz
- val = data[:df]
- data = data[df:]
- self.linecount = 1
- self.headers = 0
- else:
- val = ''
- if self.linecount > 0:
- dsplit = (self.buf+data).split('\n')
- self.buf = dsplit[-1]
- for ln in dsplit[:-1]:
- if self.linecount > self.n:
- self.done = 1
- return val
- val += (ln + '\n')
- self.linecount += 1
- return val
- else:
- return data
-
-
-
-class _POP3MessageDeleted(Exception):
- """
- Internal control-flow exception. Indicates the file of a deleted message
- was requested.
- """
-
-
-class POP3Error(Exception):
- pass
-
-
-
-class _IteratorBuffer(object):
- bufSize = 0
-
- def __init__(self, write, iterable, memoryBufferSize=None):
- """
- Create a _IteratorBuffer.
-
- @param write: A one-argument callable which will be invoked with a list
- of strings which have been buffered.
-
- @param iterable: The source of input strings as any iterable.
-
- @param memoryBufferSize: The upper limit on buffered string length,
- beyond which the buffer will be flushed to the writer.
- """
- self.lines = []
- self.write = write
- self.iterator = iter(iterable)
- if memoryBufferSize is None:
- memoryBufferSize = 2 ** 16
- self.memoryBufferSize = memoryBufferSize
-
-
- def __iter__(self):
- return self
-
-
- def next(self):
- try:
- v = self.iterator.next()
- except StopIteration:
- if self.lines:
- self.write(self.lines)
- # Drop some references, in case they're edges in a cycle.
- del self.iterator, self.lines, self.write
- raise
- else:
- if v is not None:
- self.lines.append(v)
- self.bufSize += len(v)
- if self.bufSize > self.memoryBufferSize:
- self.write(self.lines)
- self.lines = []
- self.bufSize = 0
-
-
-
-def iterateLineGenerator(proto, gen):
- """
- Hook the given protocol instance up to the given iterator with an
- _IteratorBuffer and schedule the result to be exhausted via the protocol.
-
- @type proto: L{POP3}
- @type gen: iterator
- @rtype: L{twisted.internet.defer.Deferred}
- """
- coll = _IteratorBuffer(proto.transport.writeSequence, gen)
- return proto.schedule(coll)
-
-
-
-def successResponse(response):
- """
- Format the given object as a positive response.
- """
- response = str(response)
- return '+OK %s\r\n' % (response,)
-
-
-
-def formatStatResponse(msgs):
- """
- Format the list of message sizes appropriately for a STAT response.
-
- Yields None until it finishes computing a result, then yields a str
- instance that is suitable for use as a response to the STAT command.
- Intended to be used with a L{twisted.internet.task.Cooperator}.
- """
- i = 0
- bytes = 0
- for size in msgs:
- i += 1
- bytes += size
- yield None
- yield successResponse('%d %d' % (i, bytes))
-
-
-
-def formatListLines(msgs):
- """
- Format a list of message sizes appropriately for the lines of a LIST
- response.
-
- Yields str instances formatted appropriately for use as lines in the
- response to the LIST command. Does not include the trailing '.'.
- """
- i = 0
- for size in msgs:
- i += 1
- yield '%d %d\r\n' % (i, size)
-
-
-
-def formatListResponse(msgs):
- """
- Format a list of message sizes appropriately for a complete LIST response.
-
- Yields str instances formatted appropriately for use as a LIST command
- response.
- """
- yield successResponse(len(msgs))
- for ele in formatListLines(msgs):
- yield ele
- yield '.\r\n'
-
-
-
-def formatUIDListLines(msgs, getUidl):
- """
- Format the list of message sizes appropriately for the lines of a UIDL
- response.
-
- Yields str instances formatted appropriately for use as lines in the
- response to the UIDL command. Does not include the trailing '.'.
- """
- for i, m in enumerate(msgs):
- if m is not None:
- uid = getUidl(i)
- yield '%d %s\r\n' % (i + 1, uid)
-
-
-
-def formatUIDListResponse(msgs, getUidl):
- """
- Format a list of message sizes appropriately for a complete UIDL response.
-
- Yields str instances formatted appropriately for use as a UIDL command
- response.
- """
- yield successResponse('')
- for ele in formatUIDListLines(msgs, getUidl):
- yield ele
- yield '.\r\n'
-
-
-
-class POP3(basic.LineOnlyReceiver, policies.TimeoutMixin):
- """
- POP3 server protocol implementation.
-
- @ivar portal: A reference to the L{twisted.cred.portal.Portal} instance we
- will authenticate through.
-
- @ivar factory: A L{twisted.mail.pop3.IServerFactory} which will be used to
- determine some extended behavior of the server.
-
- @ivar timeOut: An integer which defines the minimum amount of time which
- may elapse without receiving any traffic after which the client will be
- disconnected.
-
- @ivar schedule: A one-argument callable which should behave like
- L{twisted.internet.task.coiterate}.
- """
- implements(interfaces.IProducer)
-
- magic = None
- _userIs = None
- _onLogout = None
-
- AUTH_CMDS = ['CAPA', 'USER', 'PASS', 'APOP', 'AUTH', 'RPOP', 'QUIT']
-
- portal = None
- factory = None
-
- # The mailbox we're serving
- mbox = None
-
- # Set this pretty low -- POP3 clients are expected to log in, download
- # everything, and log out.
- timeOut = 300
-
- # Current protocol state
- state = "COMMAND"
-
- # PIPELINE
- blocked = None
-
- # Cooperate and suchlike.
- schedule = staticmethod(task.coiterate)
-
- # Message index of the highest retrieved message.
- _highest = 0
-
- def connectionMade(self):
- if self.magic is None:
- self.magic = self.generateMagic()
- self.successResponse(self.magic)
- self.setTimeout(self.timeOut)
- if getattr(self.factory, 'noisy', True):
- log.msg("New connection from " + str(self.transport.getPeer()))
-
-
- def connectionLost(self, reason):
- if self._onLogout is not None:
- self._onLogout()
- self._onLogout = None
- self.setTimeout(None)
-
-
- def generateMagic(self):
- return smtp.messageid()
-
-
- def successResponse(self, message=''):
- self.transport.write(successResponse(message))
-
- def failResponse(self, message=''):
- self.sendLine('-ERR ' + str(message))
-
-# def sendLine(self, line):
-# print 'S:', repr(line)
-# basic.LineOnlyReceiver.sendLine(self, line)
-
- def lineReceived(self, line):
-# print 'C:', repr(line)
- self.resetTimeout()
- getattr(self, 'state_' + self.state)(line)
-
- def _unblock(self, _):
- commands = self.blocked
- self.blocked = None
- while commands and self.blocked is None:
- cmd, args = commands.pop(0)
- self.processCommand(cmd, *args)
- if self.blocked is not None:
- self.blocked.extend(commands)
-
- def state_COMMAND(self, line):
- try:
- return self.processCommand(*line.split(' '))
- except (ValueError, AttributeError, POP3Error, TypeError), e:
- log.err()
- self.failResponse('bad protocol or server: %s: %s' % (e.__class__.__name__, e))
-
- def processCommand(self, command, *args):
- if self.blocked is not None:
- self.blocked.append((command, args))
- return
-
- command = command.upper()
- authCmd = command in self.AUTH_CMDS
- if not self.mbox and not authCmd:
- raise POP3Error("not authenticated yet: cannot do " + command)
- f = getattr(self, 'do_' + command, None)
- if f:
- return f(*args)
- raise POP3Error("Unknown protocol command: " + command)
-
-
- def listCapabilities(self):
- baseCaps = [
- "TOP",
- "USER",
- "UIDL",
- "PIPELINE",
- "CELERITY",
- "AUSPEX",
- "POTENCE",
- ]
-
- if IServerFactory.providedBy(self.factory):
- # Oh my god. We can't just loop over a list of these because
- # each has spectacularly different return value semantics!
- try:
- v = self.factory.cap_IMPLEMENTATION()
- except NotImplementedError:
- pass
- except:
- log.err()
- else:
- baseCaps.append("IMPLEMENTATION " + str(v))
-
- try:
- v = self.factory.cap_EXPIRE()
- except NotImplementedError:
- pass
- except:
- log.err()
- else:
- if v is None:
- v = "NEVER"
- if self.factory.perUserExpiration():
- if self.mbox:
- v = str(self.mbox.messageExpiration)
- else:
- v = str(v) + " USER"
- v = str(v)
- baseCaps.append("EXPIRE " + v)
-
- try:
- v = self.factory.cap_LOGIN_DELAY()
- except NotImplementedError:
- pass
- except:
- log.err()
- else:
- if self.factory.perUserLoginDelay():
- if self.mbox:
- v = str(self.mbox.loginDelay)
- else:
- v = str(v) + " USER"
- v = str(v)
- baseCaps.append("LOGIN-DELAY " + v)
-
- try:
- v = self.factory.challengers
- except AttributeError:
- pass
- except:
- log.err()
- else:
- baseCaps.append("SASL " + ' '.join(v.keys()))
- return baseCaps
-
- def do_CAPA(self):
- self.successResponse("I can do the following:")
- for cap in self.listCapabilities():
- self.sendLine(cap)
- self.sendLine(".")
-
- def do_AUTH(self, args=None):
- if not getattr(self.factory, 'challengers', None):
- self.failResponse("AUTH extension unsupported")
- return
-
- if args is None:
- self.successResponse("Supported authentication methods:")
- for a in self.factory.challengers:
- self.sendLine(a.upper())
- self.sendLine(".")
- return
-
- auth = self.factory.challengers.get(args.strip().upper())
- if not self.portal or not auth:
- self.failResponse("Unsupported SASL selected")
- return
-
- self._auth = auth()
- chal = self._auth.getChallenge()
-
- self.sendLine('+ ' + base64.encodestring(chal).rstrip('\n'))
- self.state = 'AUTH'
-
- def state_AUTH(self, line):
- self.state = "COMMAND"
- try:
- parts = base64.decodestring(line).split(None, 1)
- except binascii.Error:
- self.failResponse("Invalid BASE64 encoding")
- else:
- if len(parts) != 2:
- self.failResponse("Invalid AUTH response")
- return
- self._auth.username = parts[0]
- self._auth.response = parts[1]
- d = self.portal.login(self._auth, None, IMailbox)
- d.addCallback(self._cbMailbox, parts[0])
- d.addErrback(self._ebMailbox)
- d.addErrback(self._ebUnexpected)
-
- def do_APOP(self, user, digest):
- d = defer.maybeDeferred(self.authenticateUserAPOP, user, digest)
- d.addCallbacks(self._cbMailbox, self._ebMailbox, callbackArgs=(user,)
- ).addErrback(self._ebUnexpected)
-
- def _cbMailbox(self, (interface, avatar, logout), user):
- if interface is not IMailbox:
- self.failResponse('Authentication failed')
- log.err("_cbMailbox() called with an interface other than IMailbox")
- return
-
- self.mbox = avatar
- self._onLogout = logout
- self.successResponse('Authentication succeeded')
- if getattr(self.factory, 'noisy', True):
- log.msg("Authenticated login for " + user)
-
- def _ebMailbox(self, failure):
- failure = failure.trap(cred.error.LoginDenied, cred.error.LoginFailed)
- if issubclass(failure, cred.error.LoginDenied):
- self.failResponse("Access denied: " + str(failure))
- elif issubclass(failure, cred.error.LoginFailed):
- self.failResponse('Authentication failed')
- if getattr(self.factory, 'noisy', True):
- log.msg("Denied login attempt from " + str(self.transport.getPeer()))
-
- def _ebUnexpected(self, failure):
- self.failResponse('Server error: ' + failure.getErrorMessage())
- log.err(failure)
-
- def do_USER(self, user):
- self._userIs = user
- self.successResponse('USER accepted, send PASS')
-
- def do_PASS(self, password):
- if self._userIs is None:
- self.failResponse("USER required before PASS")
- return
- user = self._userIs
- self._userIs = None
- d = defer.maybeDeferred(self.authenticateUserPASS, user, password)
- d.addCallbacks(self._cbMailbox, self._ebMailbox, callbackArgs=(user,)
- ).addErrback(self._ebUnexpected)
-
-
- def _longOperation(self, d):
- # Turn off timeouts and block further processing until the Deferred
- # fires, then reverse those changes.
- timeOut = self.timeOut
- self.setTimeout(None)
- self.blocked = []
- d.addCallback(self._unblock)
- d.addCallback(lambda ign: self.setTimeout(timeOut))
- return d
-
-
- def _coiterate(self, gen):
- return self.schedule(_IteratorBuffer(self.transport.writeSequence, gen))
-
-
- def do_STAT(self):
- d = defer.maybeDeferred(self.mbox.listMessages)
- def cbMessages(msgs):
- return self._coiterate(formatStatResponse(msgs))
- def ebMessages(err):
- self.failResponse(err.getErrorMessage())
- log.msg("Unexpected do_STAT failure:")
- log.err(err)
- return self._longOperation(d.addCallbacks(cbMessages, ebMessages))
-
-
- def do_LIST(self, i=None):
- if i is None:
- d = defer.maybeDeferred(self.mbox.listMessages)
- def cbMessages(msgs):
- return self._coiterate(formatListResponse(msgs))
- def ebMessages(err):
- self.failResponse(err.getErrorMessage())
- log.msg("Unexpected do_LIST failure:")
- log.err(err)
- return self._longOperation(d.addCallbacks(cbMessages, ebMessages))
- else:
- try:
- i = int(i)
- if i < 1:
- raise ValueError()
- except ValueError:
- self.failResponse("Invalid message-number: %r" % (i,))
- else:
- d = defer.maybeDeferred(self.mbox.listMessages, i - 1)
- def cbMessage(msg):
- self.successResponse('%d %d' % (i, msg))
- def ebMessage(err):
- errcls = err.check(ValueError, IndexError)
- if errcls is not None:
- if errcls is IndexError:
- # IndexError was supported for a while, but really
- # shouldn't be. One error condition, one exception
- # type.
- warnings.warn(
- "twisted.mail.pop3.IMailbox.listMessages may not "
- "raise IndexError for out-of-bounds message numbers: "
- "raise ValueError instead.",
- PendingDeprecationWarning)
- self.failResponse("Invalid message-number: %r" % (i,))
- else:
- self.failResponse(err.getErrorMessage())
- log.msg("Unexpected do_LIST failure:")
- log.err(err)
- return self._longOperation(d.addCallbacks(cbMessage, ebMessage))
-
-
- def do_UIDL(self, i=None):
- if i is None:
- d = defer.maybeDeferred(self.mbox.listMessages)
- def cbMessages(msgs):
- return self._coiterate(formatUIDListResponse(msgs, self.mbox.getUidl))
- def ebMessages(err):
- self.failResponse(err.getErrorMessage())
- log.msg("Unexpected do_UIDL failure:")
- log.err(err)
- return self._longOperation(d.addCallbacks(cbMessages, ebMessages))
- else:
- try:
- i = int(i)
- if i < 1:
- raise ValueError()
- except ValueError:
- self.failResponse("Bad message number argument")
- else:
- try:
- msg = self.mbox.getUidl(i - 1)
- except IndexError:
- # XXX TODO See above comment regarding IndexError.
- warnings.warn(
- "twisted.mail.pop3.IMailbox.getUidl may not "
- "raise IndexError for out-of-bounds message numbers: "
- "raise ValueError instead.",
- PendingDeprecationWarning)
- self.failResponse("Bad message number argument")
- except ValueError:
- self.failResponse("Bad message number argument")
- else:
- self.successResponse(str(msg))
-
-
- def _getMessageFile(self, i):
- """
- Retrieve the size and contents of a given message, as a two-tuple.
-
- @param i: The number of the message to operate on. This is a base-ten
- string representation starting at 1.
-
- @return: A Deferred which fires with a two-tuple of an integer and a
- file-like object.
- """
- try:
- msg = int(i) - 1
- if msg < 0:
- raise ValueError()
- except ValueError:
- self.failResponse("Bad message number argument")
- return defer.succeed(None)
-
- sizeDeferred = defer.maybeDeferred(self.mbox.listMessages, msg)
- def cbMessageSize(size):
- if not size:
- return defer.fail(_POP3MessageDeleted())
- fileDeferred = defer.maybeDeferred(self.mbox.getMessage, msg)
- fileDeferred.addCallback(lambda fObj: (size, fObj))
- return fileDeferred
-
- def ebMessageSomething(err):
- errcls = err.check(_POP3MessageDeleted, ValueError, IndexError)
- if errcls is _POP3MessageDeleted:
- self.failResponse("message deleted")
- elif errcls in (ValueError, IndexError):
- if errcls is IndexError:
- # XXX TODO See above comment regarding IndexError.
- warnings.warn(
- "twisted.mail.pop3.IMailbox.listMessages may not "
- "raise IndexError for out-of-bounds message numbers: "
- "raise ValueError instead.",
- PendingDeprecationWarning)
- self.failResponse("Bad message number argument")
- else:
- log.msg("Unexpected _getMessageFile failure:")
- log.err(err)
- return None
-
- sizeDeferred.addCallback(cbMessageSize)
- sizeDeferred.addErrback(ebMessageSomething)
- return sizeDeferred
-
-
- def _sendMessageContent(self, i, fpWrapper, successResponse):
- d = self._getMessageFile(i)
- def cbMessageFile(info):
- if info is None:
- # Some error occurred - a failure response has been sent
- # already, just give up.
- return
-
- self._highest = max(self._highest, int(i))
- resp, fp = info
- fp = fpWrapper(fp)
- self.successResponse(successResponse(resp))
- s = basic.FileSender()
- d = s.beginFileTransfer(fp, self.transport, self.transformChunk)
-
- def cbFileTransfer(lastsent):
- if lastsent != '\n':
- line = '\r\n.'
- else:
- line = '.'
- self.sendLine(line)
-
- def ebFileTransfer(err):
- self.transport.loseConnection()
- log.msg("Unexpected error in _sendMessageContent:")
- log.err(err)
-
- d.addCallback(cbFileTransfer)
- d.addErrback(ebFileTransfer)
- return d
- return self._longOperation(d.addCallback(cbMessageFile))
-
-
- def do_TOP(self, i, size):
- try:
- size = int(size)
- if size < 0:
- raise ValueError
- except ValueError:
- self.failResponse("Bad line count argument")
- else:
- return self._sendMessageContent(
- i,
- lambda fp: _HeadersPlusNLines(fp, size),
- lambda size: "Top of message follows")
-
-
- def do_RETR(self, i):
- return self._sendMessageContent(
- i,
- lambda fp: fp,
- lambda size: "%d" % (size,))
-
-
- def transformChunk(self, chunk):
- return chunk.replace('\n', '\r\n').replace('\r\n.', '\r\n..')
-
-
- def finishedFileTransfer(self, lastsent):
- if lastsent != '\n':
- line = '\r\n.'
- else:
- line = '.'
- self.sendLine(line)
-
-
- def do_DELE(self, i):
- i = int(i)-1
- self.mbox.deleteMessage(i)
- self.successResponse()
-
-
- def do_NOOP(self):
- """Perform no operation. Return a success code"""
- self.successResponse()
-
-
- def do_RSET(self):
- """Unset all deleted message flags"""
- try:
- self.mbox.undeleteMessages()
- except:
- log.err()
- self.failResponse()
- else:
- self._highest = 0
- self.successResponse()
-
-
- def do_LAST(self):
- """
- Return the index of the highest message yet downloaded.
- """
- self.successResponse(self._highest)
-
-
- def do_RPOP(self, user):
- self.failResponse('permission denied, sucker')
-
-
- def do_QUIT(self):
- if self.mbox:
- self.mbox.sync()
- self.successResponse()
- self.transport.loseConnection()
-
-
- def authenticateUserAPOP(self, user, digest):
- """Perform authentication of an APOP login.
-
- @type user: C{str}
- @param user: The name of the user attempting to log in.
-
- @type digest: C{str}
- @param digest: The response string with which the user replied.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the login is
- successful, and whose errback will be invoked otherwise. The
- callback will be passed a 3-tuple consisting of IMailbox,
- an object implementing IMailbox, and a zero-argument callable
- to be invoked when this session is terminated.
- """
- if self.portal is not None:
- return self.portal.login(
- APOPCredentials(self.magic, user, digest),
- None,
- IMailbox
- )
- raise cred.error.UnauthorizedLogin()
-
- def authenticateUserPASS(self, user, password):
- """Perform authentication of a username/password login.
-
- @type user: C{str}
- @param user: The name of the user attempting to log in.
-
- @type password: C{str}
- @param password: The password to attempt to authenticate with.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback is invoked if the login is
- successful, and whose errback will be invoked otherwise. The
- callback will be passed a 3-tuple consisting of IMailbox,
- an object implementing IMailbox, and a zero-argument callable
- to be invoked when this session is terminated.
- """
- if self.portal is not None:
- return self.portal.login(
- cred.credentials.UsernamePassword(user, password),
- None,
- IMailbox
- )
- raise cred.error.UnauthorizedLogin()
-
-
-class IServerFactory(Interface):
- """Interface for querying additional parameters of this POP3 server.
-
- Any cap_* method may raise NotImplementedError if the particular
- capability is not supported. If cap_EXPIRE() does not raise
- NotImplementedError, perUserExpiration() must be implemented, otherwise
- they are optional. If cap_LOGIN_DELAY() is implemented,
- perUserLoginDelay() must be implemented, otherwise they are optional.
-
- @ivar challengers: A dictionary mapping challenger names to classes
- implementing C{IUsernameHashedPassword}.
- """
-
- def cap_IMPLEMENTATION():
- """Return a string describing this POP3 server implementation."""
-
- def cap_EXPIRE():
- """Return the minimum number of days messages are retained."""
-
- def perUserExpiration():
- """Indicate whether message expiration is per-user.
-
- @return: True if it is, false otherwise.
- """
-
- def cap_LOGIN_DELAY():
- """Return the minimum number of seconds between client logins."""
-
- def perUserLoginDelay():
- """Indicate whether the login delay period is per-user.
-
- @return: True if it is, false otherwise.
- """
-
-class IMailbox(Interface):
- """
- @type loginDelay: C{int}
- @ivar loginDelay: The number of seconds between allowed logins for the
- user associated with this mailbox. None
-
- @type messageExpiration: C{int}
- @ivar messageExpiration: The number of days messages in this mailbox will
- remain on the server before being deleted.
- """
-
- def listMessages(index=None):
- """Retrieve the size of one or more messages.
-
- @type index: C{int} or C{None}
- @param index: The number of the message for which to retrieve the
- size (starting at 0), or None to retrieve the size of all messages.
-
- @rtype: C{int} or any iterable of C{int} or a L{Deferred} which fires
- with one of these.
-
- @return: The number of octets in the specified message, or an iterable
- of integers representing the number of octets in all the messages. Any
- value which would have referred to a deleted message should be set to 0.
-
- @raise ValueError: if C{index} is greater than the index of any message
- in the mailbox.
- """
-
- def getMessage(index):
- """Retrieve a file-like object for a particular message.
-
- @type index: C{int}
- @param index: The number of the message to retrieve
-
- @rtype: A file-like object
- @return: A file containing the message data with lines delimited by
- C{\\n}.
- """
-
- def getUidl(index):
- """Get a unique identifier for a particular message.
-
- @type index: C{int}
- @param index: The number of the message for which to retrieve a UIDL
-
- @rtype: C{str}
- @return: A string of printable characters uniquely identifying for all
- time the specified message.
-
- @raise ValueError: if C{index} is greater than the index of any message
- in the mailbox.
- """
-
- def deleteMessage(index):
- """Delete a particular message.
-
- This must not change the number of messages in this mailbox. Further
- requests for the size of deleted messages should return 0. Further
- requests for the message itself may raise an exception.
-
- @type index: C{int}
- @param index: The number of the message to delete.
- """
-
- def undeleteMessages():
- """
- Undelete any messages which have been marked for deletion since the
- most recent L{sync} call.
-
- Any message which can be undeleted should be returned to its
- original position in the message sequence and retain its original
- UID.
- """
-
- def sync():
- """Perform checkpointing.
-
- This method will be called to indicate the mailbox should attempt to
- clean up any remaining deleted messages.
- """
-
-
-
-class Mailbox:
- implements(IMailbox)
-
- def listMessages(self, i=None):
- return []
- def getMessage(self, i):
- raise ValueError
- def getUidl(self, i):
- raise ValueError
- def deleteMessage(self, i):
- raise ValueError
- def undeleteMessages(self):
- pass
- def sync(self):
- pass
-
-
-NONE, SHORT, FIRST_LONG, LONG = range(4)
-
-NEXT = {}
-NEXT[NONE] = NONE
-NEXT[SHORT] = NONE
-NEXT[FIRST_LONG] = LONG
-NEXT[LONG] = NONE
-
-class POP3Client(basic.LineOnlyReceiver):
-
- mode = SHORT
- command = 'WELCOME'
- import re
- welcomeRe = re.compile('<(.*)>')
-
- def __init__(self):
- import warnings
- warnings.warn("twisted.mail.pop3.POP3Client is deprecated, "
- "please use twisted.mail.pop3.AdvancedPOP3Client "
- "instead.", DeprecationWarning,
- stacklevel=3)
-
- def sendShort(self, command, params=None):
- if params is not None:
- self.sendLine('%s %s' % (command, params))
- else:
- self.sendLine(command)
- self.command = command
- self.mode = SHORT
-
- def sendLong(self, command, params):
- if params:
- self.sendLine('%s %s' % (command, params))
- else:
- self.sendLine(command)
- self.command = command
- self.mode = FIRST_LONG
-
- def handle_default(self, line):
- if line[:-4] == '-ERR':
- self.mode = NONE
-
- def handle_WELCOME(self, line):
- code, data = line.split(' ', 1)
- if code != '+OK':
- self.transport.loseConnection()
- else:
- m = self.welcomeRe.match(line)
- if m:
- self.welcomeCode = m.group(1)
-
- def _dispatch(self, command, default, *args):
- try:
- method = getattr(self, 'handle_'+command, default)
- if method is not None:
- method(*args)
- except:
- log.err()
-
- def lineReceived(self, line):
- if self.mode == SHORT or self.mode == FIRST_LONG:
- self.mode = NEXT[self.mode]
- self._dispatch(self.command, self.handle_default, line)
- elif self.mode == LONG:
- if line == '.':
- self.mode = NEXT[self.mode]
- self._dispatch(self.command+'_end', None)
- return
- if line[:1] == '.':
- line = line[1:]
- self._dispatch(self.command+"_continue", None, line)
-
- def apopAuthenticate(self, user, password, magic):
- digest = md5(magic + password).hexdigest()
- self.apop(user, digest)
-
- def apop(self, user, digest):
- self.sendLong('APOP', ' '.join((user, digest)))
- def retr(self, i):
- self.sendLong('RETR', i)
- def dele(self, i):
- self.sendShort('DELE', i)
- def list(self, i=''):
- self.sendLong('LIST', i)
- def uidl(self, i=''):
- self.sendLong('UIDL', i)
- def user(self, name):
- self.sendShort('USER', name)
- def pass_(self, pass_):
- self.sendShort('PASS', pass_)
- def quit(self):
- self.sendShort('QUIT')
-
-from twisted.mail.pop3client import POP3Client as AdvancedPOP3Client
-from twisted.mail.pop3client import POP3ClientError
-from twisted.mail.pop3client import InsecureAuthenticationDisallowed
-from twisted.mail.pop3client import ServerErrorResponse
-from twisted.mail.pop3client import LineTooLong
-
-__all__ = [
- # Interfaces
- 'IMailbox', 'IServerFactory',
-
- # Exceptions
- 'POP3Error', 'POP3ClientError', 'InsecureAuthenticationDisallowed',
- 'ServerErrorResponse', 'LineTooLong',
-
- # Protocol classes
- 'POP3', 'POP3Client', 'AdvancedPOP3Client',
-
- # Misc
- 'APOPCredentials', 'Mailbox']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3client.py
deleted file mode 100755
index fe8f497e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/pop3client.py
+++ /dev/null
@@ -1,706 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_pop3client -*-
-# Copyright (c) 2001-2004 Divmod Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-POP3 client protocol implementation
-
-Don't use this module directly. Use twisted.mail.pop3 instead.
-
-@author: Jp Calderone
-"""
-
-import re
-
-from twisted.python import log
-from twisted.python.hashlib import md5
-from twisted.internet import defer
-from twisted.protocols import basic
-from twisted.protocols import policies
-from twisted.internet import error
-from twisted.internet import interfaces
-
-OK = '+OK'
-ERR = '-ERR'
-
-class POP3ClientError(Exception):
- """Base class for all exceptions raised by POP3Client.
- """
-
-class InsecureAuthenticationDisallowed(POP3ClientError):
- """Secure authentication was required but no mechanism could be found.
- """
-
-class TLSError(POP3ClientError):
- """
- Secure authentication was required but either the transport does
- not support TLS or no TLS context factory was supplied.
- """
-
-class TLSNotSupportedError(POP3ClientError):
- """
- Secure authentication was required but the server does not support
- TLS.
- """
-
-class ServerErrorResponse(POP3ClientError):
- """The server returned an error response to a request.
- """
- def __init__(self, reason, consumer=None):
- POP3ClientError.__init__(self, reason)
- self.consumer = consumer
-
-class LineTooLong(POP3ClientError):
- """The server sent an extremely long line.
- """
-
-class _ListSetter:
- # Internal helper. POP3 responses sometimes occur in the
- # form of a list of lines containing two pieces of data,
- # a message index and a value of some sort. When a message
- # is deleted, it is omitted from these responses. The
- # setitem method of this class is meant to be called with
- # these two values. In the cases where indexes are skipped,
- # it takes care of padding out the missing values with None.
- def __init__(self, L):
- self.L = L
- def setitem(self, (item, value)):
- diff = item - len(self.L) + 1
- if diff > 0:
- self.L.extend([None] * diff)
- self.L[item] = value
-
-
-def _statXform(line):
- # Parse a STAT response
- numMsgs, totalSize = line.split(None, 1)
- return int(numMsgs), int(totalSize)
-
-
-def _listXform(line):
- # Parse a LIST response
- index, size = line.split(None, 1)
- return int(index) - 1, int(size)
-
-
-def _uidXform(line):
- # Parse a UIDL response
- index, uid = line.split(None, 1)
- return int(index) - 1, uid
-
-def _codeStatusSplit(line):
- # Parse an +OK or -ERR response
- parts = line.split(' ', 1)
- if len(parts) == 1:
- return parts[0], ''
- return parts
-
-def _dotUnquoter(line):
- """
- C{'.'} characters which begin a line of a message are doubled to avoid
- confusing with the terminating C{'.\\r\\n'} sequence. This function
- unquotes them.
- """
- if line.startswith('..'):
- return line[1:]
- return line
-
-class POP3Client(basic.LineOnlyReceiver, policies.TimeoutMixin):
- """POP3 client protocol implementation class
-
- Instances of this class provide a convenient, efficient API for
- retrieving and deleting messages from a POP3 server.
-
- @type startedTLS: C{bool}
- @ivar startedTLS: Whether TLS has been negotiated successfully.
-
-
- @type allowInsecureLogin: C{bool}
- @ivar allowInsecureLogin: Indicate whether login() should be
- allowed if the server offers no authentication challenge and if
- our transport does not offer any protection via encryption.
-
- @type serverChallenge: C{str} or C{None}
- @ivar serverChallenge: Challenge received from the server
-
- @type timeout: C{int}
- @ivar timeout: Number of seconds to wait before timing out a
- connection. If the number is <= 0, no timeout checking will be
- performed.
- """
-
- startedTLS = False
- allowInsecureLogin = False
- timeout = 0
- serverChallenge = None
-
- # Capabilities are not allowed to change during the session
- # (except when TLS is negotiated), so cache the first response and
- # use that for all later lookups
- _capCache = None
-
- # Regular expression to search for in the challenge string in the server
- # greeting line.
- _challengeMagicRe = re.compile('(<[^>]+>)')
-
- # List of pending calls.
- # We are a pipelining API but don't actually
- # support pipelining on the network yet.
- _blockedQueue = None
-
- # The Deferred to which the very next result will go.
- _waiting = None
-
- # Whether we dropped the connection because of a timeout
- _timedOut = False
-
- # If the server sends an initial -ERR, this is the message it sent
- # with it.
- _greetingError = None
-
- def _blocked(self, f, *a):
- # Internal helper. If commands are being blocked, append
- # the given command and arguments to a list and return a Deferred
- # that will be chained with the return value of the function
- # when it eventually runs. Otherwise, set up for commands to be
-
- # blocked and return None.
- if self._blockedQueue is not None:
- d = defer.Deferred()
- self._blockedQueue.append((d, f, a))
- return d
- self._blockedQueue = []
- return None
-
- def _unblock(self):
- # Internal helper. Indicate that a function has completed.
- # If there are blocked commands, run the next one. If there
- # are not, set up for the next command to not be blocked.
- if self._blockedQueue == []:
- self._blockedQueue = None
- elif self._blockedQueue is not None:
- _blockedQueue = self._blockedQueue
- self._blockedQueue = None
-
- d, f, a = _blockedQueue.pop(0)
- d2 = f(*a)
- d2.chainDeferred(d)
- # f is a function which uses _blocked (otherwise it wouldn't
- # have gotten into the blocked queue), which means it will have
- # re-set _blockedQueue to an empty list, so we can put the rest
- # of the blocked queue back into it now.
- self._blockedQueue.extend(_blockedQueue)
-
-
- def sendShort(self, cmd, args):
- # Internal helper. Send a command to which a short response
- # is expected. Return a Deferred that fires when the response
- # is received. Block all further commands from being sent until
- # the response is received. Transition the state to SHORT.
- d = self._blocked(self.sendShort, cmd, args)
- if d is not None:
- return d
-
- if args:
- self.sendLine(cmd + ' ' + args)
- else:
- self.sendLine(cmd)
- self.state = 'SHORT'
- self._waiting = defer.Deferred()
- return self._waiting
-
- def sendLong(self, cmd, args, consumer, xform):
- # Internal helper. Send a command to which a multiline
- # response is expected. Return a Deferred that fires when
- # the entire response is received. Block all further commands
- # from being sent until the entire response is received.
- # Transition the state to LONG_INITIAL.
- d = self._blocked(self.sendLong, cmd, args, consumer, xform)
- if d is not None:
- return d
-
- if args:
- self.sendLine(cmd + ' ' + args)
- else:
- self.sendLine(cmd)
- self.state = 'LONG_INITIAL'
- self._xform = xform
- self._consumer = consumer
- self._waiting = defer.Deferred()
- return self._waiting
-
- # Twisted protocol callback
- def connectionMade(self):
- if self.timeout > 0:
- self.setTimeout(self.timeout)
-
- self.state = 'WELCOME'
- self._blockedQueue = []
-
- def timeoutConnection(self):
- self._timedOut = True
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- if self.timeout > 0:
- self.setTimeout(None)
-
- if self._timedOut:
- reason = error.TimeoutError()
- elif self._greetingError:
- reason = ServerErrorResponse(self._greetingError)
-
- d = []
- if self._waiting is not None:
- d.append(self._waiting)
- self._waiting = None
- if self._blockedQueue is not None:
- d.extend([deferred for (deferred, f, a) in self._blockedQueue])
- self._blockedQueue = None
- for w in d:
- w.errback(reason)
-
- def lineReceived(self, line):
- if self.timeout > 0:
- self.resetTimeout()
-
- state = self.state
- self.state = None
- state = getattr(self, 'state_' + state)(line) or state
- if self.state is None:
- self.state = state
-
- def lineLengthExceeded(self, buffer):
- # XXX - We need to be smarter about this
- if self._waiting is not None:
- waiting, self._waiting = self._waiting, None
- waiting.errback(LineTooLong())
- self.transport.loseConnection()
-
- # POP3 Client state logic - don't touch this.
- def state_WELCOME(self, line):
- # WELCOME is the first state. The server sends one line of text
- # greeting us, possibly with an APOP challenge. Transition the
- # state to WAITING.
- code, status = _codeStatusSplit(line)
- if code != OK:
- self._greetingError = status
- self.transport.loseConnection()
- else:
- m = self._challengeMagicRe.search(status)
-
- if m is not None:
- self.serverChallenge = m.group(1)
-
- self.serverGreeting(status)
-
- self._unblock()
- return 'WAITING'
-
- def state_WAITING(self, line):
- # The server isn't supposed to send us anything in this state.
- log.msg("Illegal line from server: " + repr(line))
-
- def state_SHORT(self, line):
- # This is the state we are in when waiting for a single
- # line response. Parse it and fire the appropriate callback
- # or errback. Transition the state back to WAITING.
- deferred, self._waiting = self._waiting, None
- self._unblock()
- code, status = _codeStatusSplit(line)
- if code == OK:
- deferred.callback(status)
- else:
- deferred.errback(ServerErrorResponse(status))
- return 'WAITING'
-
- def state_LONG_INITIAL(self, line):
- # This is the state we are in when waiting for the first
- # line of a long response. Parse it and transition the
- # state to LONG if it is an okay response; if it is an
- # error response, fire an errback, clean up the things
- # waiting for a long response, and transition the state
- # to WAITING.
- code, status = _codeStatusSplit(line)
- if code == OK:
- return 'LONG'
- consumer = self._consumer
- deferred = self._waiting
- self._consumer = self._waiting = self._xform = None
- self._unblock()
- deferred.errback(ServerErrorResponse(status, consumer))
- return 'WAITING'
-
- def state_LONG(self, line):
- # This is the state for each line of a long response.
- # If it is the last line, finish things, fire the
- # Deferred, and transition the state to WAITING.
- # Otherwise, pass the line to the consumer.
- if line == '.':
- consumer = self._consumer
- deferred = self._waiting
- self._consumer = self._waiting = self._xform = None
- self._unblock()
- deferred.callback(consumer)
- return 'WAITING'
- else:
- if self._xform is not None:
- self._consumer(self._xform(line))
- else:
- self._consumer(line)
- return 'LONG'
-
-
- # Callbacks - override these
- def serverGreeting(self, greeting):
- """Called when the server has sent us a greeting.
-
- @type greeting: C{str} or C{None}
- @param greeting: The status message sent with the server
- greeting. For servers implementing APOP authentication, this
- will be a challenge string. .
- """
-
-
- # External API - call these (most of 'em anyway)
- def startTLS(self, contextFactory=None):
- """
- Initiates a 'STLS' request and negotiates the TLS / SSL
- Handshake.
-
- @type contextFactory: C{ssl.ClientContextFactory} @param
- contextFactory: The context factory with which to negotiate
- TLS. If C{None}, try to create a new one.
-
- @return: A Deferred which fires when the transport has been
- secured according to the given contextFactory, or which fails
- if the transport cannot be secured.
- """
- tls = interfaces.ITLSTransport(self.transport, None)
- if tls is None:
- return defer.fail(TLSError(
- "POP3Client transport does not implement "
- "interfaces.ITLSTransport"))
-
- if contextFactory is None:
- contextFactory = self._getContextFactory()
-
- if contextFactory is None:
- return defer.fail(TLSError(
- "POP3Client requires a TLS context to "
- "initiate the STLS handshake"))
-
- d = self.capabilities()
- d.addCallback(self._startTLS, contextFactory, tls)
- return d
-
-
- def _startTLS(self, caps, contextFactory, tls):
- assert not self.startedTLS, "Client and Server are currently communicating via TLS"
-
- if 'STLS' not in caps:
- return defer.fail(TLSNotSupportedError(
- "Server does not support secure communication "
- "via TLS / SSL"))
-
- d = self.sendShort('STLS', None)
- d.addCallback(self._startedTLS, contextFactory, tls)
- d.addCallback(lambda _: self.capabilities())
- return d
-
-
- def _startedTLS(self, result, context, tls):
- self.transport = tls
- self.transport.startTLS(context)
- self._capCache = None
- self.startedTLS = True
- return result
-
-
- def _getContextFactory(self):
- try:
- from twisted.internet import ssl
- except ImportError:
- return None
- else:
- context = ssl.ClientContextFactory()
- context.method = ssl.SSL.TLSv1_METHOD
- return context
-
-
- def login(self, username, password):
- """Log into the server.
-
- If APOP is available it will be used. Otherwise, if TLS is
- available an 'STLS' session will be started and plaintext
- login will proceed. Otherwise, if the instance attribute
- allowInsecureLogin is set to True, insecure plaintext login
- will proceed. Otherwise, InsecureAuthenticationDisallowed
- will be raised (asynchronously).
-
- @param username: The username with which to log in.
- @param password: The password with which to log in.
-
- @rtype: C{Deferred}
- @return: A deferred which fires when login has
- completed.
- """
- d = self.capabilities()
- d.addCallback(self._login, username, password)
- return d
-
-
- def _login(self, caps, username, password):
- if self.serverChallenge is not None:
- return self._apop(username, password, self.serverChallenge)
-
- tryTLS = 'STLS' in caps
-
- #If our transport supports switching to TLS, we might want to try to switch to TLS.
- tlsableTransport = interfaces.ITLSTransport(self.transport, None) is not None
-
- # If our transport is not already using TLS, we might want to try to switch to TLS.
- nontlsTransport = interfaces.ISSLTransport(self.transport, None) is None
-
- if not self.startedTLS and tryTLS and tlsableTransport and nontlsTransport:
- d = self.startTLS()
-
- d.addCallback(self._loginTLS, username, password)
- return d
-
- elif self.startedTLS or not nontlsTransport or self.allowInsecureLogin:
- return self._plaintext(username, password)
- else:
- return defer.fail(InsecureAuthenticationDisallowed())
-
-
- def _loginTLS(self, res, username, password):
- return self._plaintext(username, password)
-
- def _plaintext(self, username, password):
- # Internal helper. Send a username/password pair, returning a Deferred
- # that fires when both have succeeded or fails when the server rejects
- # either.
- return self.user(username).addCallback(lambda r: self.password(password))
-
- def _apop(self, username, password, challenge):
- # Internal helper. Computes and sends an APOP response. Returns
- # a Deferred that fires when the server responds to the response.
- digest = md5(challenge + password).hexdigest()
- return self.apop(username, digest)
-
- def apop(self, username, digest):
- """Perform APOP login.
-
- This should be used in special circumstances only, when it is
- known that the server supports APOP authentication, and APOP
- authentication is absolutely required. For the common case,
- use L{login} instead.
-
- @param username: The username with which to log in.
- @param digest: The challenge response to authenticate with.
- """
- return self.sendShort('APOP', username + ' ' + digest)
-
- def user(self, username):
- """Send the user command.
-
- This performs the first half of plaintext login. Unless this
- is absolutely required, use the L{login} method instead.
-
- @param username: The username with which to log in.
- """
- return self.sendShort('USER', username)
-
- def password(self, password):
- """Send the password command.
-
- This performs the second half of plaintext login. Unless this
- is absolutely required, use the L{login} method instead.
-
- @param password: The plaintext password with which to authenticate.
- """
- return self.sendShort('PASS', password)
-
- def delete(self, index):
- """Delete a message from the server.
-
- @type index: C{int}
- @param index: The index of the message to delete.
- This is 0-based.
-
- @rtype: C{Deferred}
- @return: A deferred which fires when the delete command
- is successful, or fails if the server returns an error.
- """
- return self.sendShort('DELE', str(index + 1))
-
- def _consumeOrSetItem(self, cmd, args, consumer, xform):
- # Internal helper. Send a long command. If no consumer is
- # provided, create a consumer that puts results into a list
- # and return a Deferred that fires with that list when it
- # is complete.
- if consumer is None:
- L = []
- consumer = _ListSetter(L).setitem
- return self.sendLong(cmd, args, consumer, xform).addCallback(lambda r: L)
- return self.sendLong(cmd, args, consumer, xform)
-
- def _consumeOrAppend(self, cmd, args, consumer, xform):
- # Internal helper. Send a long command. If no consumer is
- # provided, create a consumer that appends results to a list
- # and return a Deferred that fires with that list when it is
- # complete.
- if consumer is None:
- L = []
- consumer = L.append
- return self.sendLong(cmd, args, consumer, xform).addCallback(lambda r: L)
- return self.sendLong(cmd, args, consumer, xform)
-
- def capabilities(self, useCache=True):
- """Retrieve the capabilities supported by this server.
-
- Not all servers support this command. If the server does not
- support this, it is treated as though it returned a successful
- response listing no capabilities. At some future time, this may be
- changed to instead seek out information about a server's
- capabilities in some other fashion (only if it proves useful to do
- so, and only if there are servers still in use which do not support
- CAPA but which do support POP3 extensions that are useful).
-
- @type useCache: C{bool}
- @param useCache: If set, and if capabilities have been
- retrieved previously, just return the previously retrieved
- results.
-
- @return: A Deferred which fires with a C{dict} mapping C{str}
- to C{None} or C{list}s of C{str}. For example::
-
- C: CAPA
- S: +OK Capability list follows
- S: TOP
- S: USER
- S: SASL CRAM-MD5 KERBEROS_V4
- S: RESP-CODES
- S: LOGIN-DELAY 900
- S: PIPELINING
- S: EXPIRE 60
- S: UIDL
- S: IMPLEMENTATION Shlemazle-Plotz-v302
- S: .
-
- will be lead to a result of::
-
- | {'TOP': None,
- | 'USER': None,
- | 'SASL': ['CRAM-MD5', 'KERBEROS_V4'],
- | 'RESP-CODES': None,
- | 'LOGIN-DELAY': ['900'],
- | 'PIPELINING': None,
- | 'EXPIRE': ['60'],
- | 'UIDL': None,
- | 'IMPLEMENTATION': ['Shlemazle-Plotz-v302']}
- """
- if useCache and self._capCache is not None:
- return defer.succeed(self._capCache)
-
- cache = {}
- def consume(line):
- tmp = line.split()
- if len(tmp) == 1:
- cache[tmp[0]] = None
- elif len(tmp) > 1:
- cache[tmp[0]] = tmp[1:]
-
- def capaNotSupported(err):
- err.trap(ServerErrorResponse)
- return None
-
- def gotCapabilities(result):
- self._capCache = cache
- return cache
-
- d = self._consumeOrAppend('CAPA', None, consume, None)
- d.addErrback(capaNotSupported).addCallback(gotCapabilities)
- return d
-
-
- def noop(self):
- """Do nothing, with the help of the server.
-
- No operation is performed. The returned Deferred fires when
- the server responds.
- """
- return self.sendShort("NOOP", None)
-
-
- def reset(self):
- """Remove the deleted flag from any messages which have it.
-
- The returned Deferred fires when the server responds.
- """
- return self.sendShort("RSET", None)
-
-
- def retrieve(self, index, consumer=None, lines=None):
- """Retrieve a message from the server.
-
- If L{consumer} is not None, it will be called with
- each line of the message as it is received. Otherwise,
- the returned Deferred will be fired with a list of all
- the lines when the message has been completely received.
- """
- idx = str(index + 1)
- if lines is None:
- return self._consumeOrAppend('RETR', idx, consumer, _dotUnquoter)
-
- return self._consumeOrAppend('TOP', '%s %d' % (idx, lines), consumer, _dotUnquoter)
-
-
- def stat(self):
- """Get information about the size of this mailbox.
-
- The returned Deferred will be fired with a tuple containing
- the number or messages in the mailbox and the size (in bytes)
- of the mailbox.
- """
- return self.sendShort('STAT', None).addCallback(_statXform)
-
-
- def listSize(self, consumer=None):
- """Retrieve a list of the size of all messages on the server.
-
- If L{consumer} is not None, it will be called with two-tuples
- of message index number and message size as they are received.
- Otherwise, a Deferred which will fire with a list of B{only}
- message sizes will be returned. For messages which have been
- deleted, None will be used in place of the message size.
- """
- return self._consumeOrSetItem('LIST', None, consumer, _listXform)
-
-
- def listUID(self, consumer=None):
- """Retrieve a list of the UIDs of all messages on the server.
-
- If L{consumer} is not None, it will be called with two-tuples
- of message index number and message UID as they are received.
- Otherwise, a Deferred which will fire with of list of B{only}
- message UIDs will be returned. For messages which have been
- deleted, None will be used in place of the message UID.
- """
- return self._consumeOrSetItem('UIDL', None, consumer, _uidXform)
-
-
- def quit(self):
- """Disconnect from the server.
- """
- return self.sendShort('QUIT', None)
-
-__all__ = [
- # Exceptions
- 'InsecureAuthenticationDisallowed', 'LineTooLong', 'POP3ClientError',
- 'ServerErrorResponse', 'TLSError', 'TLSNotSupportedError',
-
- # Protocol classes
- 'POP3Client']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/protocols.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/protocols.py
deleted file mode 100755
index 446592be..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/protocols.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mail -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Protocol support for twisted.mail."""
-
-# twisted imports
-from twisted.mail import pop3
-from twisted.mail import smtp
-from twisted.internet import protocol
-from twisted.internet import defer
-from twisted.copyright import longversion
-from twisted.python import log
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-from twisted import cred
-import twisted.cred.error
-import twisted.cred.credentials
-
-from twisted.mail import relay
-
-from zope.interface import implements
-
-
-class DomainDeliveryBase:
- """A server that uses twisted.mail service's domains."""
-
- implements(smtp.IMessageDelivery)
-
- service = None
- protocolName = None
-
- def __init__(self, service, user, host=smtp.DNSNAME):
- self.service = service
- self.user = user
- self.host = host
-
- def receivedHeader(self, helo, origin, recipients):
- authStr = heloStr = ""
- if self.user:
- authStr = " auth=%s" % (self.user.encode('xtext'),)
- if helo[0]:
- heloStr = " helo=%s" % (helo[0],)
- from_ = "from %s ([%s]%s%s)" % (helo[0], helo[1], heloStr, authStr)
- by = "by %s with %s (%s)" % (
- self.host, self.protocolName, longversion
- )
- for_ = "for <%s>; %s" % (' '.join(map(str, recipients)), smtp.rfc822date())
- return "Received: %s\n\t%s\n\t%s" % (from_, by, for_)
-
- def validateTo(self, user):
- # XXX - Yick. This needs cleaning up.
- if self.user and self.service.queue:
- d = self.service.domains.get(user.dest.domain, None)
- if d is None:
- d = relay.DomainQueuer(self.service, True)
- else:
- d = self.service.domains[user.dest.domain]
- return defer.maybeDeferred(d.exists, user)
-
- def validateFrom(self, helo, origin):
- if not helo:
- raise smtp.SMTPBadSender(origin, 503, "Who are you? Say HELO first.")
- if origin.local != '' and origin.domain == '':
- raise smtp.SMTPBadSender(origin, 501, "Sender address must contain domain.")
- return origin
-
- def startMessage(self, users):
- ret = []
- for user in users:
- ret.append(self.service.domains[user.dest.domain].startMessage(user))
- return ret
-
-
-class SMTPDomainDelivery(DomainDeliveryBase):
- protocolName = 'smtp'
-
-class ESMTPDomainDelivery(DomainDeliveryBase):
- protocolName = 'esmtp'
-
-class DomainSMTP(SMTPDomainDelivery, smtp.SMTP):
- service = user = None
-
- def __init__(self, *args, **kw):
- import warnings
- warnings.warn(
- "DomainSMTP is deprecated. Use IMessageDelivery objects instead.",
- DeprecationWarning, stacklevel=2,
- )
- smtp.SMTP.__init__(self, *args, **kw)
- if self.delivery is None:
- self.delivery = self
-
-class DomainESMTP(ESMTPDomainDelivery, smtp.ESMTP):
- service = user = None
-
- def __init__(self, *args, **kw):
- import warnings
- warnings.warn(
- "DomainESMTP is deprecated. Use IMessageDelivery objects instead.",
- DeprecationWarning, stacklevel=2,
- )
- smtp.ESMTP.__init__(self, *args, **kw)
- if self.delivery is None:
- self.delivery = self
-
-class SMTPFactory(smtp.SMTPFactory):
- """A protocol factory for SMTP."""
-
- protocol = smtp.SMTP
- portal = None
-
- def __init__(self, service, portal = None):
- smtp.SMTPFactory.__init__(self)
- self.service = service
- self.portal = portal
-
- def buildProtocol(self, addr):
- log.msg('Connection from %s' % (addr,))
- p = smtp.SMTPFactory.buildProtocol(self, addr)
- p.service = self.service
- p.portal = self.portal
- return p
-
-class ESMTPFactory(SMTPFactory):
- protocol = smtp.ESMTP
- context = None
-
- def __init__(self, *args):
- SMTPFactory.__init__(self, *args)
- self.challengers = {
- 'CRAM-MD5': cred.credentials.CramMD5Credentials
- }
-
- def buildProtocol(self, addr):
- p = SMTPFactory.buildProtocol(self, addr)
- p.challengers = self.challengers
- p.ctx = self.context
- return p
-
-class VirtualPOP3(pop3.POP3):
- """Virtual hosting POP3."""
-
- service = None
-
- domainSpecifier = '@' # Gaagh! I hate POP3. No standardized way
- # to indicate user@host. '@' doesn't work
- # with NS, e.g.
-
- def authenticateUserAPOP(self, user, digest):
- # Override the default lookup scheme to allow virtual domains
- user, domain = self.lookupDomain(user)
- try:
- portal = self.service.lookupPortal(domain)
- except KeyError:
- return defer.fail(cred.error.UnauthorizedLogin())
- else:
- return portal.login(
- pop3.APOPCredentials(self.magic, user, digest),
- None,
- pop3.IMailbox
- )
-
- def authenticateUserPASS(self, user, password):
- user, domain = self.lookupDomain(user)
- try:
- portal = self.service.lookupPortal(domain)
- except KeyError:
- return defer.fail(cred.error.UnauthorizedLogin())
- else:
- return portal.login(
- cred.credentials.UsernamePassword(user, password),
- None,
- pop3.IMailbox
- )
-
- def lookupDomain(self, user):
- try:
- user, domain = user.split(self.domainSpecifier, 1)
- except ValueError:
- domain = ''
- if domain not in self.service.domains:
- raise pop3.POP3Error("no such domain %s" % domain)
- return user, domain
-
-
-class POP3Factory(protocol.ServerFactory):
- """POP3 protocol factory."""
-
- protocol = VirtualPOP3
- service = None
-
- def __init__(self, service):
- self.service = service
-
- def buildProtocol(self, addr):
- p = protocol.ServerFactory.buildProtocol(self, addr)
- p.service = self.service
- return p
-
-#
-# It is useful to know, perhaps, that the required file for this to work can
-# be created thusly:
-#
-# openssl req -x509 -newkey rsa:2048 -keyout file.key -out file.crt \
-# -days 365 -nodes
-#
-# And then cat file.key and file.crt together. The number of days and bits
-# can be changed, of course.
-#
-class SSLContextFactory:
- """
- An SSL Context Factory.
-
- This loads a certificate and private key from a specified file.
- """
- deprecatedModuleAttribute(
- Version("Twisted", 12, 2, 0),
- "Use twisted.internet.ssl.DefaultOpenSSLContextFactory instead.",
- "twisted.mail.protocols", "SSLContextFactory")
-
- def __init__(self, filename):
- self.filename = filename
-
- def getContext(self):
- """Create an SSL context."""
- from OpenSSL import SSL
- ctx = SSL.Context(SSL.SSLv23_METHOD)
- ctx.use_certificate_file(self.filename)
- ctx.use_privatekey_file(self.filename)
- return ctx
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relay.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relay.py
deleted file mode 100755
index ac68095a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relay.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mail -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Support for relaying mail for twisted.mail"""
-
-from twisted.mail import smtp
-from twisted.python import log
-from twisted.internet.address import UNIXAddress
-
-import os
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-class DomainQueuer:
- """An SMTP domain which add messages to a queue intended for relaying."""
-
- def __init__(self, service, authenticated=False):
- self.service = service
- self.authed = authenticated
-
- def exists(self, user):
- """Check whether we will relay
-
- Call overridable willRelay method
- """
- if self.willRelay(user.dest, user.protocol):
- # The most cursor form of verification of the addresses
- orig = filter(None, str(user.orig).split('@', 1))
- dest = filter(None, str(user.dest).split('@', 1))
- if len(orig) == 2 and len(dest) == 2:
- return lambda: self.startMessage(user)
- raise smtp.SMTPBadRcpt(user)
-
- def willRelay(self, address, protocol):
- """Check whether we agree to relay
-
- The default is to relay for all connections over UNIX
- sockets and all connections from localhost.
- """
- peer = protocol.transport.getPeer()
- return self.authed or isinstance(peer, UNIXAddress) or peer.host == '127.0.0.1'
-
- def startMessage(self, user):
- """Add envelope to queue and returns ISMTPMessage."""
- queue = self.service.queue
- envelopeFile, smtpMessage = queue.createNewMessage()
- try:
- log.msg('Queueing mail %r -> %r' % (str(user.orig), str(user.dest)))
- pickle.dump([str(user.orig), str(user.dest)], envelopeFile)
- finally:
- envelopeFile.close()
- return smtpMessage
-
-class RelayerMixin:
-
- # XXX - This is -totally- bogus
- # It opens about a -hundred- -billion- files
- # and -leaves- them open!
-
- def loadMessages(self, messagePaths):
- self.messages = []
- self.names = []
- for message in messagePaths:
- fp = open(message+'-H')
- try:
- messageContents = pickle.load(fp)
- finally:
- fp.close()
- fp = open(message+'-D')
- messageContents.append(fp)
- self.messages.append(messageContents)
- self.names.append(message)
-
- def getMailFrom(self):
- if not self.messages:
- return None
- return self.messages[0][0]
-
- def getMailTo(self):
- if not self.messages:
- return None
- return [self.messages[0][1]]
-
- def getMailData(self):
- if not self.messages:
- return None
- return self.messages[0][2]
-
- def sentMail(self, code, resp, numOk, addresses, log):
- """Since we only use one recipient per envelope, this
- will be called with 0 or 1 addresses. We probably want
- to do something with the error message if we failed.
- """
- if code in smtp.SUCCESS:
- # At least one, i.e. all, recipients successfully delivered
- os.remove(self.names[0]+'-D')
- os.remove(self.names[0]+'-H')
- del self.messages[0]
- del self.names[0]
-
-class SMTPRelayer(RelayerMixin, smtp.SMTPClient):
- def __init__(self, messagePaths, *args, **kw):
- smtp.SMTPClient.__init__(self, *args, **kw)
- self.loadMessages(messagePaths)
-
-class ESMTPRelayer(RelayerMixin, smtp.ESMTPClient):
- def __init__(self, messagePaths, *args, **kw):
- smtp.ESMTPClient.__init__(self, *args, **kw)
- self.loadMessages(messagePaths)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relaymanager.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relaymanager.py
deleted file mode 100755
index 66c777ad..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/relaymanager.py
+++ /dev/null
@@ -1,631 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mail -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Infrastructure for relaying mail through smart host
-
-Today, internet e-mail has stopped being Peer-to-peer for many problems,
-spam (unsolicited bulk mail) among them. Instead, most nodes on the
-internet send all e-mail to a single computer, usually the ISP's though
-sometimes other schemes, such as SMTP-after-POP, are used. This computer
-is supposedly permanently up and traceable, and will do the work of
-figuring out MXs and connecting to them. This kind of configuration
-is usually termed "smart host", since the host we are connecting to
-is "smart" (and will find MXs and connect to them) rather then just
-accepting mail for a small set of domains.
-
-The classes here are meant to facilitate support for such a configuration
-for the twisted.mail SMTP server
-"""
-
-import rfc822
-import os
-import time
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.python.compat import set
-from twisted.mail import relay
-from twisted.mail import bounce
-from twisted.internet import protocol
-from twisted.internet.defer import Deferred, DeferredList
-from twisted.internet.error import DNSLookupError
-from twisted.mail import smtp
-from twisted.application import internet
-
-class ManagedRelayerMixin:
- """SMTP Relayer which notifies a manager
-
- Notify the manager about successful mail, failed mail
- and broken connections
- """
-
- def __init__(self, manager):
- self.manager = manager
-
- def sentMail(self, code, resp, numOk, addresses, log):
- """called when e-mail has been sent
-
- we will always get 0 or 1 addresses.
- """
- message = self.names[0]
- if code in smtp.SUCCESS:
- self.manager.notifySuccess(self.factory, message)
- else:
- self.manager.notifyFailure(self.factory, message)
- del self.messages[0]
- del self.names[0]
-
- def connectionLost(self, reason):
- """called when connection is broken
-
- notify manager we will try to send no more e-mail
- """
- self.manager.notifyDone(self.factory)
-
-class SMTPManagedRelayer(ManagedRelayerMixin, relay.SMTPRelayer):
- def __init__(self, messages, manager, *args, **kw):
- """
- @type messages: C{list} of C{str}
- @param messages: Filenames of messages to relay
-
- manager should support .notifySuccess, .notifyFailure
- and .notifyDone
- """
- ManagedRelayerMixin.__init__(self, manager)
- relay.SMTPRelayer.__init__(self, messages, *args, **kw)
-
-class ESMTPManagedRelayer(ManagedRelayerMixin, relay.ESMTPRelayer):
- def __init__(self, messages, manager, *args, **kw):
- """
- @type messages: C{list} of C{str}
- @param messages: Filenames of messages to relay
-
- manager should support .notifySuccess, .notifyFailure
- and .notifyDone
- """
- ManagedRelayerMixin.__init__(self, manager)
- relay.ESMTPRelayer.__init__(self, messages, *args, **kw)
-
-class SMTPManagedRelayerFactory(protocol.ClientFactory):
- protocol = SMTPManagedRelayer
-
- def __init__(self, messages, manager, *args, **kw):
- self.messages = messages
- self.manager = manager
- self.pArgs = args
- self.pKwArgs = kw
-
- def buildProtocol(self, addr):
- protocol = self.protocol(self.messages, self.manager, *self.pArgs,
- **self.pKwArgs)
- protocol.factory = self
- return protocol
-
- def clientConnectionFailed(self, connector, reason):
- """called when connection could not be made
-
- our manager should be notified that this happened,
- it might prefer some other host in that case"""
- self.manager.notifyNoConnection(self)
- self.manager.notifyDone(self)
-
-class ESMTPManagedRelayerFactory(SMTPManagedRelayerFactory):
- protocol = ESMTPManagedRelayer
-
- def __init__(self, messages, manager, secret, contextFactory, *args, **kw):
- self.secret = secret
- self.contextFactory = contextFactory
- SMTPManagedRelayerFactory.__init__(self, messages, manager, *args, **kw)
-
- def buildProtocol(self, addr):
- s = self.secret and self.secret(addr)
- protocol = self.protocol(self.messages, self.manager, s,
- self.contextFactory, *self.pArgs, **self.pKwArgs)
- protocol.factory = self
- return protocol
-
-class Queue:
- """A queue of ougoing emails."""
-
- noisy = True
-
- def __init__(self, directory):
- self.directory = directory
- self._init()
-
- def _init(self):
- self.n = 0
- self.waiting = {}
- self.relayed = {}
- self.readDirectory()
-
- def __getstate__(self):
- """(internal) delete volatile state"""
- return {'directory' : self.directory}
-
- def __setstate__(self, state):
- """(internal) restore volatile state"""
- self.__dict__.update(state)
- self._init()
-
- def readDirectory(self):
- """Read the messages directory.
-
- look for new messages.
- """
- for message in os.listdir(self.directory):
- # Skip non data files
- if message[-2:]!='-D':
- continue
- self.addMessage(message[:-2])
-
- def getWaiting(self):
- return self.waiting.keys()
-
- def hasWaiting(self):
- return len(self.waiting) > 0
-
- def getRelayed(self):
- return self.relayed.keys()
-
- def setRelaying(self, message):
- del self.waiting[message]
- self.relayed[message] = 1
-
- def setWaiting(self, message):
- del self.relayed[message]
- self.waiting[message] = 1
-
- def addMessage(self, message):
- if message not in self.relayed:
- self.waiting[message] = 1
- if self.noisy:
- log.msg('Set ' + message + ' waiting')
-
- def done(self, message):
- """Remove message to from queue."""
- message = os.path.basename(message)
- os.remove(self.getPath(message) + '-D')
- os.remove(self.getPath(message) + '-H')
- del self.relayed[message]
-
- def getPath(self, message):
- """Get the path in the filesystem of a message."""
- return os.path.join(self.directory, message)
-
- def getEnvelope(self, message):
- return pickle.load(self.getEnvelopeFile(message))
-
- def getEnvelopeFile(self, message):
- return open(os.path.join(self.directory, message+'-H'), 'rb')
-
- def createNewMessage(self):
- """Create a new message in the queue.
-
- Return a tuple - file-like object for headers, and ISMTPMessage.
- """
- fname = "%s_%s_%s_%s" % (os.getpid(), time.time(), self.n, id(self))
- self.n = self.n + 1
- headerFile = open(os.path.join(self.directory, fname+'-H'), 'wb')
- tempFilename = os.path.join(self.directory, fname+'-C')
- finalFilename = os.path.join(self.directory, fname+'-D')
- messageFile = open(tempFilename, 'wb')
-
- from twisted.mail.mail import FileMessage
- return headerFile,FileMessage(messageFile, tempFilename, finalFilename)
-
-
-class _AttemptManager(object):
- """
- Manage the state of a single attempt to flush the relay queue.
- """
- def __init__(self, manager):
- self.manager = manager
- self._completionDeferreds = []
-
-
- def getCompletionDeferred(self):
- self._completionDeferreds.append(Deferred())
- return self._completionDeferreds[-1]
-
-
- def _finish(self, relay, message):
- self.manager.managed[relay].remove(os.path.basename(message))
- self.manager.queue.done(message)
-
-
- def notifySuccess(self, relay, message):
- """a relay sent a message successfully
-
- Mark it as sent in our lists
- """
- if self.manager.queue.noisy:
- log.msg("success sending %s, removing from queue" % message)
- self._finish(relay, message)
-
-
- def notifyFailure(self, relay, message):
- """Relaying the message has failed."""
- if self.manager.queue.noisy:
- log.msg("could not relay "+message)
- # Moshe - Bounce E-mail here
- # Be careful: if it's a bounced bounce, silently
- # discard it
- message = os.path.basename(message)
- fp = self.manager.queue.getEnvelopeFile(message)
- from_, to = pickle.load(fp)
- fp.close()
- from_, to, bounceMessage = bounce.generateBounce(open(self.manager.queue.getPath(message)+'-D'), from_, to)
- fp, outgoingMessage = self.manager.queue.createNewMessage()
- pickle.dump([from_, to], fp)
- fp.close()
- for line in bounceMessage.splitlines():
- outgoingMessage.lineReceived(line)
- outgoingMessage.eomReceived()
- self._finish(relay, self.manager.queue.getPath(message))
-
-
- def notifyDone(self, relay):
- """A relaying SMTP client is disconnected.
-
- unmark all pending messages under this relay's responsibility
- as being relayed, and remove the relay.
- """
- for message in self.manager.managed.get(relay, ()):
- if self.manager.queue.noisy:
- log.msg("Setting " + message + " waiting")
- self.manager.queue.setWaiting(message)
- try:
- del self.manager.managed[relay]
- except KeyError:
- pass
- notifications = self._completionDeferreds
- self._completionDeferreds = None
- for d in notifications:
- d.callback(None)
-
-
- def notifyNoConnection(self, relay):
- """Relaying SMTP client couldn't connect.
-
- Useful because it tells us our upstream server is unavailable.
- """
- # Back off a bit
- try:
- msgs = self.manager.managed[relay]
- except KeyError:
- log.msg("notifyNoConnection passed unknown relay!")
- return
-
- if self.manager.queue.noisy:
- log.msg("Backing off on delivery of " + str(msgs))
- def setWaiting(queue, messages):
- map(queue.setWaiting, messages)
- from twisted.internet import reactor
- reactor.callLater(30, setWaiting, self.manager.queue, msgs)
- del self.manager.managed[relay]
-
-
-
-class SmartHostSMTPRelayingManager:
- """Manage SMTP Relayers
-
- Manage SMTP relayers, keeping track of the existing connections,
- each connection's responsibility in term of messages. Create
- more relayers if the need arises.
-
- Someone should press .checkState periodically
-
- @ivar fArgs: Additional positional arguments used to instantiate
- C{factory}.
-
- @ivar fKwArgs: Additional keyword arguments used to instantiate
- C{factory}.
-
- @ivar factory: A callable which returns a ClientFactory suitable for
- making SMTP connections.
- """
-
- factory = SMTPManagedRelayerFactory
-
- PORT = 25
-
- mxcalc = None
-
- def __init__(self, queue, maxConnections=2, maxMessagesPerConnection=10):
- """
- @type queue: Any implementor of C{IQueue}
- @param queue: The object used to queue messages on their way to
- delivery.
-
- @type maxConnections: C{int}
- @param maxConnections: The maximum number of SMTP connections to
- allow to be opened at any given time.
-
- @type maxMessagesPerConnection: C{int}
- @param maxMessagesPerConnection: The maximum number of messages a
- relayer will be given responsibility for.
-
- Default values are meant for a small box with 1-5 users.
- """
- self.maxConnections = maxConnections
- self.maxMessagesPerConnection = maxMessagesPerConnection
- self.managed = {} # SMTP clients we're managing
- self.queue = queue
- self.fArgs = ()
- self.fKwArgs = {}
-
- def __getstate__(self):
- """(internal) delete volatile state"""
- dct = self.__dict__.copy()
- del dct['managed']
- return dct
-
- def __setstate__(self, state):
- """(internal) restore volatile state"""
- self.__dict__.update(state)
- self.managed = {}
-
- def checkState(self):
- """
- Synchronize with the state of the world, and maybe launch a new
- relay.
-
- Call me periodically to check I am still up to date.
-
- @return: None or a Deferred which fires when all of the SMTP clients
- started by this call have disconnected.
- """
- self.queue.readDirectory()
- if (len(self.managed) >= self.maxConnections):
- return
- if not self.queue.hasWaiting():
- return
-
- return self._checkStateMX()
-
- def _checkStateMX(self):
- nextMessages = self.queue.getWaiting()
- nextMessages.reverse()
-
- exchanges = {}
- for msg in nextMessages:
- from_, to = self.queue.getEnvelope(msg)
- name, addr = rfc822.parseaddr(to)
- parts = addr.split('@', 1)
- if len(parts) != 2:
- log.err("Illegal message destination: " + to)
- continue
- domain = parts[1]
-
- self.queue.setRelaying(msg)
- exchanges.setdefault(domain, []).append(self.queue.getPath(msg))
- if len(exchanges) >= (self.maxConnections - len(self.managed)):
- break
-
- if self.mxcalc is None:
- self.mxcalc = MXCalculator()
-
- relays = []
- for (domain, msgs) in exchanges.iteritems():
- manager = _AttemptManager(self)
- factory = self.factory(msgs, manager, *self.fArgs, **self.fKwArgs)
- self.managed[factory] = map(os.path.basename, msgs)
- relayAttemptDeferred = manager.getCompletionDeferred()
- connectSetupDeferred = self.mxcalc.getMX(domain)
- connectSetupDeferred.addCallback(lambda mx: str(mx.name))
- connectSetupDeferred.addCallback(self._cbExchange, self.PORT, factory)
- connectSetupDeferred.addErrback(lambda err: (relayAttemptDeferred.errback(err), err)[1])
- connectSetupDeferred.addErrback(self._ebExchange, factory, domain)
- relays.append(relayAttemptDeferred)
- return DeferredList(relays)
-
-
- def _cbExchange(self, address, port, factory):
- from twisted.internet import reactor
- reactor.connectTCP(address, port, factory)
-
- def _ebExchange(self, failure, factory, domain):
- log.err('Error setting up managed relay factory for ' + domain)
- log.err(failure)
- def setWaiting(queue, messages):
- map(queue.setWaiting, messages)
- from twisted.internet import reactor
- reactor.callLater(30, setWaiting, self.queue, self.managed[factory])
- del self.managed[factory]
-
-class SmartHostESMTPRelayingManager(SmartHostSMTPRelayingManager):
- factory = ESMTPManagedRelayerFactory
-
-def _checkState(manager):
- manager.checkState()
-
-def RelayStateHelper(manager, delay):
- return internet.TimerService(delay, _checkState, manager)
-
-
-
-class CanonicalNameLoop(Exception):
- """
- When trying to look up the MX record for a host, a set of CNAME records was
- found which form a cycle and resolution was abandoned.
- """
-
-
-class CanonicalNameChainTooLong(Exception):
- """
- When trying to look up the MX record for a host, too many CNAME records
- which point to other CNAME records were encountered and resolution was
- abandoned.
- """
-
-
-class MXCalculator:
- """
- A utility for looking up mail exchange hosts and tracking whether they are
- working or not.
-
- @ivar clock: L{IReactorTime} provider which will be used to decide when to
- retry mail exchanges which have not been working.
- """
- timeOutBadMX = 60 * 60 # One hour
- fallbackToDomain = True
-
- def __init__(self, resolver=None, clock=None):
- self.badMXs = {}
- if resolver is None:
- from twisted.names.client import createResolver
- resolver = createResolver()
- self.resolver = resolver
- if clock is None:
- from twisted.internet import reactor as clock
- self.clock = clock
-
-
- def markBad(self, mx):
- """Indicate a given mx host is not currently functioning.
-
- @type mx: C{str}
- @param mx: The hostname of the host which is down.
- """
- self.badMXs[str(mx)] = self.clock.seconds() + self.timeOutBadMX
-
- def markGood(self, mx):
- """Indicate a given mx host is back online.
-
- @type mx: C{str}
- @param mx: The hostname of the host which is up.
- """
- try:
- del self.badMXs[mx]
- except KeyError:
- pass
-
- def getMX(self, domain, maximumCanonicalChainLength=3):
- """
- Find an MX record for the given domain.
-
- @type domain: C{str}
- @param domain: The domain name for which to look up an MX record.
-
- @type maximumCanonicalChainLength: C{int}
- @param maximumCanonicalChainLength: The maximum number of unique CNAME
- records to follow while looking up the MX record.
-
- @return: A L{Deferred} which is called back with a string giving the
- name in the found MX record or which is errbacked if no MX record
- can be found.
- """
- mailExchangeDeferred = self.resolver.lookupMailExchange(domain)
- mailExchangeDeferred.addCallback(self._filterRecords)
- mailExchangeDeferred.addCallback(
- self._cbMX, domain, maximumCanonicalChainLength)
- mailExchangeDeferred.addErrback(self._ebMX, domain)
- return mailExchangeDeferred
-
-
- def _filterRecords(self, records):
- """
- Convert a DNS response (a three-tuple of lists of RRHeaders) into a
- mapping from record names to lists of corresponding record payloads.
- """
- recordBag = {}
- for answer in records[0]:
- recordBag.setdefault(str(answer.name), []).append(answer.payload)
- return recordBag
-
-
- def _cbMX(self, answers, domain, cnamesLeft):
- """
- Try to find the MX host from the given DNS information.
-
- This will attempt to resolve CNAME results. It can recognize loops
- and will give up on non-cyclic chains after a specified number of
- lookups.
- """
- # Do this import here so that relaymanager.py doesn't depend on
- # twisted.names, only MXCalculator will.
- from twisted.names import dns, error
-
- seenAliases = set()
- exchanges = []
- # Examine the answers for the domain we asked about
- pertinentRecords = answers.get(domain, [])
- while pertinentRecords:
- record = pertinentRecords.pop()
-
- # If it's a CNAME, we'll need to do some more processing
- if record.TYPE == dns.CNAME:
-
- # Remember that this name was an alias.
- seenAliases.add(domain)
-
- canonicalName = str(record.name)
- # See if we have some local records which might be relevant.
- if canonicalName in answers:
-
- # Make sure it isn't a loop contained entirely within the
- # results we have here.
- if canonicalName in seenAliases:
- return Failure(CanonicalNameLoop(record))
-
- pertinentRecords = answers[canonicalName]
- exchanges = []
- else:
- if cnamesLeft:
- # Request more information from the server.
- return self.getMX(canonicalName, cnamesLeft - 1)
- else:
- # Give up.
- return Failure(CanonicalNameChainTooLong(record))
-
- # If it's an MX, collect it.
- if record.TYPE == dns.MX:
- exchanges.append((record.preference, record))
-
- if exchanges:
- exchanges.sort()
- for (preference, record) in exchanges:
- host = str(record.name)
- if host not in self.badMXs:
- return record
- t = self.clock.seconds() - self.badMXs[host]
- if t >= 0:
- del self.badMXs[host]
- return record
- return exchanges[0][1]
- else:
- # Treat no answers the same as an error - jump to the errback to try
- # to look up an A record. This provides behavior described as a
- # special case in RFC 974 in the section headed I{Interpreting the
- # List of MX RRs}.
- return Failure(
- error.DNSNameError("No MX records for %r" % (domain,)))
-
-
- def _ebMX(self, failure, domain):
- from twisted.names import error, dns
-
- if self.fallbackToDomain:
- failure.trap(error.DNSNameError)
- log.msg("MX lookup failed; attempting to use hostname (%s) directly" % (domain,))
-
- # Alright, I admit, this is a bit icky.
- d = self.resolver.getHostByName(domain)
- def cbResolved(addr):
- return dns.Record_MX(name=addr)
- def ebResolved(err):
- err.trap(error.DNSNameError)
- raise DNSLookupError()
- d.addCallbacks(cbResolved, ebResolved)
- return d
- elif failure.check(error.DNSNameError):
- raise IOError("No MX found for %r" % (domain,))
- return failure
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/__init__.py
deleted file mode 100755
index f653cc71..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"mail scripts"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/mailmail.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/mailmail.py
deleted file mode 100755
index a045e822..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/scripts/mailmail.py
+++ /dev/null
@@ -1,366 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_mailmail -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation module for the I{mailmail} command.
-"""
-
-import os
-import sys
-import rfc822
-import getpass
-from ConfigParser import ConfigParser
-
-try:
- import cStringIO as StringIO
-except:
- import StringIO
-
-from twisted.copyright import version
-from twisted.internet import reactor
-from twisted.mail import smtp
-
-GLOBAL_CFG = "/etc/mailmail"
-LOCAL_CFG = os.path.expanduser("~/.twisted/mailmail")
-SMARTHOST = '127.0.0.1'
-
-ERROR_FMT = """\
-Subject: Failed Message Delivery
-
- Message delivery failed. The following occurred:
-
- %s
---
-The Twisted sendmail application.
-"""
-
-def log(message, *args):
- sys.stderr.write(str(message) % args + '\n')
-
-class Options:
- """
- @type to: C{list} of C{str}
- @ivar to: The addresses to which to deliver this message.
-
- @type sender: C{str}
- @ivar sender: The address from which this message is being sent.
-
- @type body: C{file}
- @ivar body: The object from which the message is to be read.
- """
-
-def getlogin():
- try:
- return os.getlogin()
- except:
- return getpass.getuser()
-
-
-_unsupportedOption = SystemExit("Unsupported option.")
-
-def parseOptions(argv):
- o = Options()
- o.to = [e for e in argv if not e.startswith('-')]
- o.sender = getlogin()
-
- # Just be very stupid
-
- # Skip -bm -- it is the default
-
- # Add a non-standard option for querying the version of this tool.
- if '--version' in argv:
- print 'mailmail version:', version
- raise SystemExit()
-
- # -bp lists queue information. Screw that.
- if '-bp' in argv:
- raise _unsupportedOption
-
- # -bs makes sendmail use stdin/stdout as its transport. Screw that.
- if '-bs' in argv:
- raise _unsupportedOption
-
- # -F sets who the mail is from, but is overridable by the From header
- if '-F' in argv:
- o.sender = argv[argv.index('-F') + 1]
- o.to.remove(o.sender)
-
- # -i and -oi makes us ignore lone "."
- if ('-i' in argv) or ('-oi' in argv):
- raise _unsupportedOption
-
- # -odb is background delivery
- if '-odb' in argv:
- o.background = True
- else:
- o.background = False
-
- # -odf is foreground delivery
- if '-odf' in argv:
- o.background = False
- else:
- o.background = True
-
- # -oem and -em cause errors to be mailed back to the sender.
- # It is also the default.
-
- # -oep and -ep cause errors to be printed to stderr
- if ('-oep' in argv) or ('-ep' in argv):
- o.printErrors = True
- else:
- o.printErrors = False
-
- # -om causes a copy of the message to be sent to the sender if the sender
- # appears in an alias expansion. We do not support aliases.
- if '-om' in argv:
- raise _unsupportedOption
-
- # -t causes us to pick the recipients of the message from the To, Cc, and Bcc
- # headers, and to remove the Bcc header if present.
- if '-t' in argv:
- o.recipientsFromHeaders = True
- o.excludeAddresses = o.to
- o.to = []
- else:
- o.recipientsFromHeaders = False
- o.exludeAddresses = []
-
- requiredHeaders = {
- 'from': [],
- 'to': [],
- 'cc': [],
- 'bcc': [],
- 'date': [],
- }
-
- headers = []
- buffer = StringIO.StringIO()
- while 1:
- write = 1
- line = sys.stdin.readline()
- if not line.strip():
- break
-
- hdrs = line.split(': ', 1)
-
- hdr = hdrs[0].lower()
- if o.recipientsFromHeaders and hdr in ('to', 'cc', 'bcc'):
- o.to.extend([
- a[1] for a in rfc822.AddressList(hdrs[1]).addresslist
- ])
- if hdr == 'bcc':
- write = 0
- elif hdr == 'from':
- o.sender = rfc822.parseaddr(hdrs[1])[1]
-
- if hdr in requiredHeaders:
- requiredHeaders[hdr].append(hdrs[1])
-
- if write:
- buffer.write(line)
-
- if not requiredHeaders['from']:
- buffer.write('From: %s\r\n' % (o.sender,))
- if not requiredHeaders['to']:
- if not o.to:
- raise SystemExit("No recipients specified.")
- buffer.write('To: %s\r\n' % (', '.join(o.to),))
- if not requiredHeaders['date']:
- buffer.write('Date: %s\r\n' % (smtp.rfc822date(),))
-
- buffer.write(line)
-
- if o.recipientsFromHeaders:
- for a in o.excludeAddresses:
- try:
- o.to.remove(a)
- except:
- pass
-
- buffer.seek(0, 0)
- o.body = StringIO.StringIO(buffer.getvalue() + sys.stdin.read())
- return o
-
-class Configuration:
- """
- @ivar allowUIDs: A list of UIDs which are allowed to send mail.
- @ivar allowGIDs: A list of GIDs which are allowed to send mail.
- @ivar denyUIDs: A list of UIDs which are not allowed to send mail.
- @ivar denyGIDs: A list of GIDs which are not allowed to send mail.
-
- @type defaultAccess: C{bool}
- @ivar defaultAccess: C{True} if access will be allowed when no other access
- control rule matches or C{False} if it will be denied in that case.
-
- @ivar useraccess: Either C{'allow'} to check C{allowUID} first
- or C{'deny'} to check C{denyUID} first.
-
- @ivar groupaccess: Either C{'allow'} to check C{allowGID} first or
- C{'deny'} to check C{denyGID} first.
-
- @ivar identities: A C{dict} mapping hostnames to credentials to use when
- sending mail to that host.
-
- @ivar smarthost: C{None} or a hostname through which all outgoing mail will
- be sent.
-
- @ivar domain: C{None} or the hostname with which to identify ourselves when
- connecting to an MTA.
- """
- def __init__(self):
- self.allowUIDs = []
- self.denyUIDs = []
- self.allowGIDs = []
- self.denyGIDs = []
- self.useraccess = 'deny'
- self.groupaccess= 'deny'
-
- self.identities = {}
- self.smarthost = None
- self.domain = None
-
- self.defaultAccess = True
-
-
-def loadConfig(path):
- # [useraccess]
- # allow=uid1,uid2,...
- # deny=uid1,uid2,...
- # order=allow,deny
- # [groupaccess]
- # allow=gid1,gid2,...
- # deny=gid1,gid2,...
- # order=deny,allow
- # [identity]
- # host1=username:password
- # host2=username:password
- # [addresses]
- # smarthost=a.b.c.d
- # default_domain=x.y.z
-
- c = Configuration()
-
- if not os.access(path, os.R_OK):
- return c
-
- p = ConfigParser()
- p.read(path)
-
- au = c.allowUIDs
- du = c.denyUIDs
- ag = c.allowGIDs
- dg = c.denyGIDs
- for (section, a, d) in (('useraccess', au, du), ('groupaccess', ag, dg)):
- if p.has_section(section):
- for (mode, L) in (('allow', a), ('deny', d)):
- if p.has_option(section, mode) and p.get(section, mode):
- for id in p.get(section, mode).split(','):
- try:
- id = int(id)
- except ValueError:
- log("Illegal %sID in [%s] section: %s", section[0].upper(), section, id)
- else:
- L.append(id)
- order = p.get(section, 'order')
- order = map(str.split, map(str.lower, order.split(',')))
- if order[0] == 'allow':
- setattr(c, section, 'allow')
- else:
- setattr(c, section, 'deny')
-
- if p.has_section('identity'):
- for (host, up) in p.items('identity'):
- parts = up.split(':', 1)
- if len(parts) != 2:
- log("Illegal entry in [identity] section: %s", up)
- continue
- p.identities[host] = parts
-
- if p.has_section('addresses'):
- if p.has_option('addresses', 'smarthost'):
- c.smarthost = p.get('addresses', 'smarthost')
- if p.has_option('addresses', 'default_domain'):
- c.domain = p.get('addresses', 'default_domain')
-
- return c
-
-def success(result):
- reactor.stop()
-
-failed = None
-def failure(f):
- global failed
- reactor.stop()
- failed = f
-
-def sendmail(host, options, ident):
- d = smtp.sendmail(host, options.sender, options.to, options.body)
- d.addCallbacks(success, failure)
- reactor.run()
-
-def senderror(failure, options):
- recipient = [options.sender]
- sender = '"Internally Generated Message (%s)"<postmaster@%s>' % (sys.argv[0], smtp.DNSNAME)
- error = StringIO.StringIO()
- failure.printTraceback(file=error)
- body = StringIO.StringIO(ERROR_FMT % error.getvalue())
-
- d = smtp.sendmail('localhost', sender, recipient, body)
- d.addBoth(lambda _: reactor.stop())
-
-def deny(conf):
- uid = os.getuid()
- gid = os.getgid()
-
- if conf.useraccess == 'deny':
- if uid in conf.denyUIDs:
- return True
- if uid in conf.allowUIDs:
- return False
- else:
- if uid in conf.allowUIDs:
- return False
- if uid in conf.denyUIDs:
- return True
-
- if conf.groupaccess == 'deny':
- if gid in conf.denyGIDs:
- return True
- if gid in conf.allowGIDs:
- return False
- else:
- if gid in conf.allowGIDs:
- return False
- if gid in conf.denyGIDs:
- return True
-
- return not conf.defaultAccess
-
-def run():
- o = parseOptions(sys.argv[1:])
- gConf = loadConfig(GLOBAL_CFG)
- lConf = loadConfig(LOCAL_CFG)
-
- if deny(gConf) or deny(lConf):
- log("Permission denied")
- return
-
- host = lConf.smarthost or gConf.smarthost or SMARTHOST
-
- ident = gConf.identities.copy()
- ident.update(lConf.identities)
-
- if lConf.domain:
- smtp.DNSNAME = lConf.domain
- elif gConf.domain:
- smtp.DNSNAME = gConf.domain
-
- sendmail(host, o, ident)
-
- if failed:
- if o.printErrors:
- failed.printTraceback(file=sys.stderr)
- raise SystemExit(1)
- else:
- senderror(failed, o)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/smtp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/smtp.py
deleted file mode 100755
index 3b8bd0a4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/smtp.py
+++ /dev/null
@@ -1,1934 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_smtp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Simple Mail Transfer Protocol implementation.
-"""
-
-import time, re, base64, types, socket, os, random, rfc822
-import binascii
-from email.base64MIME import encode as encode_base64
-
-from zope.interface import implements, Interface
-
-from twisted.copyright import longversion
-from twisted.protocols import basic
-from twisted.protocols import policies
-from twisted.internet import protocol
-from twisted.internet import defer
-from twisted.internet import error
-from twisted.internet import reactor
-from twisted.internet.interfaces import ITLSTransport
-from twisted.python import log
-from twisted.python import util
-
-from twisted import cred
-from twisted.python.runtime import platform
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-# Cache the hostname (XXX Yes - this is broken)
-if platform.isMacOSX():
- # On OS X, getfqdn() is ridiculously slow - use the
- # probably-identical-but-sometimes-not gethostname() there.
- DNSNAME = socket.gethostname()
-else:
- DNSNAME = socket.getfqdn()
-
-# Used for fast success code lookup
-SUCCESS = dict.fromkeys(xrange(200,300))
-
-class IMessageDelivery(Interface):
- def receivedHeader(helo, origin, recipients):
- """
- Generate the Received header for a message
-
- @type helo: C{(str, str)}
- @param helo: The argument to the HELO command and the client's IP
- address.
-
- @type origin: C{Address}
- @param origin: The address the message is from
-
- @type recipients: C{list} of L{User}
- @param recipients: A list of the addresses for which this message
- is bound.
-
- @rtype: C{str}
- @return: The full \"Received\" header string.
- """
-
- def validateTo(user):
- """
- Validate the address for which the message is destined.
-
- @type user: C{User}
- @param user: The address to validate.
-
- @rtype: no-argument callable
- @return: A C{Deferred} which becomes, or a callable which
- takes no arguments and returns an object implementing C{IMessage}.
- This will be called and the returned object used to deliver the
- message when it arrives.
-
- @raise SMTPBadRcpt: Raised if messages to the address are
- not to be accepted.
- """
-
- def validateFrom(helo, origin):
- """
- Validate the address from which the message originates.
-
- @type helo: C{(str, str)}
- @param helo: The argument to the HELO command and the client's IP
- address.
-
- @type origin: C{Address}
- @param origin: The address the message is from
-
- @rtype: C{Deferred} or C{Address}
- @return: C{origin} or a C{Deferred} whose callback will be
- passed C{origin}.
-
- @raise SMTPBadSender: Raised of messages from this address are
- not to be accepted.
- """
-
-class IMessageDeliveryFactory(Interface):
- """An alternate interface to implement for handling message delivery.
-
- It is useful to implement this interface instead of L{IMessageDelivery}
- directly because it allows the implementor to distinguish between
- different messages delivery over the same connection. This can be
- used to optimize delivery of a single message to multiple recipients,
- something which cannot be done by L{IMessageDelivery} implementors
- due to their lack of information.
- """
- def getMessageDelivery():
- """Return an L{IMessageDelivery} object.
-
- This will be called once per message.
- """
-
-class SMTPError(Exception):
- pass
-
-
-
-class SMTPClientError(SMTPError):
- """Base class for SMTP client errors.
- """
- def __init__(self, code, resp, log=None, addresses=None, isFatal=False, retry=False):
- """
- @param code: The SMTP response code associated with this error.
- @param resp: The string response associated with this error.
-
- @param log: A string log of the exchange leading up to and including
- the error.
- @type log: L{str}
-
- @param isFatal: A boolean indicating whether this connection can
- proceed or not. If True, the connection will be dropped.
-
- @param retry: A boolean indicating whether the delivery should be
- retried. If True and the factory indicates further retries are
- desirable, they will be attempted, otherwise the delivery will
- be failed.
- """
- self.code = code
- self.resp = resp
- self.log = log
- self.addresses = addresses
- self.isFatal = isFatal
- self.retry = retry
-
-
- def __str__(self):
- if self.code > 0:
- res = ["%.3d %s" % (self.code, self.resp)]
- else:
- res = [self.resp]
- if self.log:
- res.append(self.log)
- res.append('')
- return '\n'.join(res)
-
-
-class ESMTPClientError(SMTPClientError):
- """Base class for ESMTP client errors.
- """
-
-class EHLORequiredError(ESMTPClientError):
- """The server does not support EHLO.
-
- This is considered a non-fatal error (the connection will not be
- dropped).
- """
-
-class AUTHRequiredError(ESMTPClientError):
- """Authentication was required but the server does not support it.
-
- This is considered a non-fatal error (the connection will not be
- dropped).
- """
-
-class TLSRequiredError(ESMTPClientError):
- """Transport security was required but the server does not support it.
-
- This is considered a non-fatal error (the connection will not be
- dropped).
- """
-
-class AUTHDeclinedError(ESMTPClientError):
- """The server rejected our credentials.
-
- Either the username, password, or challenge response
- given to the server was rejected.
-
- This is considered a non-fatal error (the connection will not be
- dropped).
- """
-
-class AuthenticationError(ESMTPClientError):
- """An error ocurred while authenticating.
-
- Either the server rejected our request for authentication or the
- challenge received was malformed.
-
- This is considered a non-fatal error (the connection will not be
- dropped).
- """
-
-class TLSError(ESMTPClientError):
- """An error occurred while negiotiating for transport security.
-
- This is considered a non-fatal error (the connection will not be
- dropped).
- """
-
-class SMTPConnectError(SMTPClientError):
- """Failed to connect to the mail exchange host.
-
- This is considered a fatal error. A retry will be made.
- """
- def __init__(self, code, resp, log=None, addresses=None, isFatal=True, retry=True):
- SMTPClientError.__init__(self, code, resp, log, addresses, isFatal, retry)
-
-class SMTPTimeoutError(SMTPClientError):
- """Failed to receive a response from the server in the expected time period.
-
- This is considered a fatal error. A retry will be made.
- """
- def __init__(self, code, resp, log=None, addresses=None, isFatal=True, retry=True):
- SMTPClientError.__init__(self, code, resp, log, addresses, isFatal, retry)
-
-class SMTPProtocolError(SMTPClientError):
- """The server sent a mangled response.
-
- This is considered a fatal error. A retry will not be made.
- """
- def __init__(self, code, resp, log=None, addresses=None, isFatal=True, retry=False):
- SMTPClientError.__init__(self, code, resp, log, addresses, isFatal, retry)
-
-class SMTPDeliveryError(SMTPClientError):
- """Indicates that a delivery attempt has had an error.
- """
-
-class SMTPServerError(SMTPError):
- def __init__(self, code, resp):
- self.code = code
- self.resp = resp
-
- def __str__(self):
- return "%.3d %s" % (self.code, self.resp)
-
-class SMTPAddressError(SMTPServerError):
- def __init__(self, addr, code, resp):
- SMTPServerError.__init__(self, code, resp)
- self.addr = Address(addr)
-
- def __str__(self):
- return "%.3d <%s>... %s" % (self.code, self.addr, self.resp)
-
-class SMTPBadRcpt(SMTPAddressError):
- def __init__(self, addr, code=550,
- resp='Cannot receive for specified address'):
- SMTPAddressError.__init__(self, addr, code, resp)
-
-class SMTPBadSender(SMTPAddressError):
- def __init__(self, addr, code=550, resp='Sender not acceptable'):
- SMTPAddressError.__init__(self, addr, code, resp)
-
-def rfc822date(timeinfo=None,local=1):
- """
- Format an RFC-2822 compliant date string.
-
- @param timeinfo: (optional) A sequence as returned by C{time.localtime()}
- or C{time.gmtime()}. Default is now.
- @param local: (optional) Indicates if the supplied time is local or
- universal time, or if no time is given, whether now should be local or
- universal time. Default is local, as suggested (SHOULD) by rfc-2822.
-
- @returns: A string representing the time and date in RFC-2822 format.
- """
- if not timeinfo:
- if local:
- timeinfo = time.localtime()
- else:
- timeinfo = time.gmtime()
- if local:
- if timeinfo[8]:
- # DST
- tz = -time.altzone
- else:
- tz = -time.timezone
-
- (tzhr, tzmin) = divmod(abs(tz), 3600)
- if tz:
- tzhr *= int(abs(tz)//tz)
- (tzmin, tzsec) = divmod(tzmin, 60)
- else:
- (tzhr, tzmin) = (0,0)
-
- return "%s, %02d %s %04d %02d:%02d:%02d %+03d%02d" % (
- ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][timeinfo[6]],
- timeinfo[2],
- ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][timeinfo[1] - 1],
- timeinfo[0], timeinfo[3], timeinfo[4], timeinfo[5],
- tzhr, tzmin)
-
-def idGenerator():
- i = 0
- while True:
- yield i
- i += 1
-
-def messageid(uniq=None, N=idGenerator().next):
- """Return a globally unique random string in RFC 2822 Message-ID format
-
- <datetime.pid.random@host.dom.ain>
-
- Optional uniq string will be added to strenghten uniqueness if given.
- """
- datetime = time.strftime('%Y%m%d%H%M%S', time.gmtime())
- pid = os.getpid()
- rand = random.randrange(2**31L-1)
- if uniq is None:
- uniq = ''
- else:
- uniq = '.' + uniq
-
- return '<%s.%s.%s%s.%s@%s>' % (datetime, pid, rand, uniq, N(), DNSNAME)
-
-def quoteaddr(addr):
- """Turn an email address, possibly with realname part etc, into
- a form suitable for and SMTP envelope.
- """
-
- if isinstance(addr, Address):
- return '<%s>' % str(addr)
-
- res = rfc822.parseaddr(addr)
-
- if res == (None, None):
- # It didn't parse, use it as-is
- return '<%s>' % str(addr)
- else:
- return '<%s>' % str(res[1])
-
-COMMAND, DATA, AUTH = 'COMMAND', 'DATA', 'AUTH'
-
-class AddressError(SMTPError):
- "Parse error in address"
-
-# Character classes for parsing addresses
-atom = r"[-A-Za-z0-9!\#$%&'*+/=?^_`{|}~]"
-
-class Address:
- """Parse and hold an RFC 2821 address.
-
- Source routes are stipped and ignored, UUCP-style bang-paths
- and %-style routing are not parsed.
-
- @type domain: C{str}
- @ivar domain: The domain within which this address resides.
-
- @type local: C{str}
- @ivar local: The local (\"user\") portion of this address.
- """
-
- tstring = re.compile(r'''( # A string of
- (?:"[^"]*" # quoted string
- |\\. # backslash-escaped characted
- |''' + atom + r''' # atom character
- )+|.) # or any single character''',re.X)
- atomre = re.compile(atom) # match any one atom character
-
- def __init__(self, addr, defaultDomain=None):
- if isinstance(addr, User):
- addr = addr.dest
- if isinstance(addr, Address):
- self.__dict__ = addr.__dict__.copy()
- return
- elif not isinstance(addr, types.StringTypes):
- addr = str(addr)
- self.addrstr = addr
-
- # Tokenize
- atl = filter(None,self.tstring.split(addr))
-
- local = []
- domain = []
-
- while atl:
- if atl[0] == '<':
- if atl[-1] != '>':
- raise AddressError, "Unbalanced <>"
- atl = atl[1:-1]
- elif atl[0] == '@':
- atl = atl[1:]
- if not local:
- # Source route
- while atl and atl[0] != ':':
- # remove it
- atl = atl[1:]
- if not atl:
- raise AddressError, "Malformed source route"
- atl = atl[1:] # remove :
- elif domain:
- raise AddressError, "Too many @"
- else:
- # Now in domain
- domain = ['']
- elif len(atl[0]) == 1 and not self.atomre.match(atl[0]) and atl[0] != '.':
- raise AddressError, "Parse error at %r of %r" % (atl[0], (addr, atl))
- else:
- if not domain:
- local.append(atl[0])
- else:
- domain.append(atl[0])
- atl = atl[1:]
-
- self.local = ''.join(local)
- self.domain = ''.join(domain)
- if self.local != '' and self.domain == '':
- if defaultDomain is None:
- defaultDomain = DNSNAME
- self.domain = defaultDomain
-
- dequotebs = re.compile(r'\\(.)')
-
- def dequote(self,addr):
- """Remove RFC-2821 quotes from address."""
- res = []
-
- atl = filter(None,self.tstring.split(str(addr)))
-
- for t in atl:
- if t[0] == '"' and t[-1] == '"':
- res.append(t[1:-1])
- elif '\\' in t:
- res.append(self.dequotebs.sub(r'\1',t))
- else:
- res.append(t)
-
- return ''.join(res)
-
- def __str__(self):
- if self.local or self.domain:
- return '@'.join((self.local, self.domain))
- else:
- return ''
-
- def __repr__(self):
- return "%s.%s(%s)" % (self.__module__, self.__class__.__name__,
- repr(str(self)))
-
-class User:
- """Hold information about and SMTP message recipient,
- including information on where the message came from
- """
-
- def __init__(self, destination, helo, protocol, orig):
- host = getattr(protocol, 'host', None)
- self.dest = Address(destination, host)
- self.helo = helo
- self.protocol = protocol
- if isinstance(orig, Address):
- self.orig = orig
- else:
- self.orig = Address(orig, host)
-
- def __getstate__(self):
- """Helper for pickle.
-
- protocol isn't picklabe, but we want User to be, so skip it in
- the pickle.
- """
- return { 'dest' : self.dest,
- 'helo' : self.helo,
- 'protocol' : None,
- 'orig' : self.orig }
-
- def __str__(self):
- return str(self.dest)
-
-class IMessage(Interface):
- """Interface definition for messages that can be sent via SMTP."""
-
- def lineReceived(line):
- """handle another line"""
-
- def eomReceived():
- """handle end of message
-
- return a deferred. The deferred should be called with either:
- callback(string) or errback(error)
- """
-
- def connectionLost():
- """handle message truncated
-
- semantics should be to discard the message
- """
-
-class SMTP(basic.LineOnlyReceiver, policies.TimeoutMixin):
- """SMTP server-side protocol."""
-
- timeout = 600
- host = DNSNAME
- portal = None
-
- # Control whether we log SMTP events
- noisy = True
-
- # A factory for IMessageDelivery objects. If an
- # avatar implementing IMessageDeliveryFactory can
- # be acquired from the portal, it will be used to
- # create a new IMessageDelivery object for each
- # message which is received.
- deliveryFactory = None
-
- # An IMessageDelivery object. A new instance is
- # used for each message received if we can get an
- # IMessageDeliveryFactory from the portal. Otherwise,
- # a single instance is used throughout the lifetime
- # of the connection.
- delivery = None
-
- # Cred cleanup function.
- _onLogout = None
-
- def __init__(self, delivery=None, deliveryFactory=None):
- self.mode = COMMAND
- self._from = None
- self._helo = None
- self._to = []
- self.delivery = delivery
- self.deliveryFactory = deliveryFactory
-
- def timeoutConnection(self):
- msg = '%s Timeout. Try talking faster next time!' % (self.host,)
- self.sendCode(421, msg)
- self.transport.loseConnection()
-
- def greeting(self):
- return '%s NO UCE NO UBE NO RELAY PROBES' % (self.host,)
-
- def connectionMade(self):
- # Ensure user-code always gets something sane for _helo
- peer = self.transport.getPeer()
- try:
- host = peer.host
- except AttributeError: # not an IPv4Address
- host = str(peer)
- self._helo = (None, host)
- self.sendCode(220, self.greeting())
- self.setTimeout(self.timeout)
-
- def sendCode(self, code, message=''):
- "Send an SMTP code with a message."
- lines = message.splitlines()
- lastline = lines[-1:]
- for line in lines[:-1]:
- self.sendLine('%3.3d-%s' % (code, line))
- self.sendLine('%3.3d %s' % (code,
- lastline and lastline[0] or ''))
-
- def lineReceived(self, line):
- self.resetTimeout()
- return getattr(self, 'state_' + self.mode)(line)
-
- def state_COMMAND(self, line):
- # Ignore leading and trailing whitespace, as well as an arbitrary
- # amount of whitespace between the command and its argument, though
- # it is not required by the protocol, for it is a nice thing to do.
- line = line.strip()
-
- parts = line.split(None, 1)
- if parts:
- method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
- if len(parts) == 2:
- method(parts[1])
- else:
- method('')
- else:
- self.sendSyntaxError()
-
- def sendSyntaxError(self):
- self.sendCode(500, 'Error: bad syntax')
-
- def lookupMethod(self, command):
- return getattr(self, 'do_' + command.upper(), None)
-
- def lineLengthExceeded(self, line):
- if self.mode is DATA:
- for message in self.__messages:
- message.connectionLost()
- self.mode = COMMAND
- del self.__messages
- self.sendCode(500, 'Line too long')
-
- def do_UNKNOWN(self, rest):
- self.sendCode(500, 'Command not implemented')
-
- def do_HELO(self, rest):
- peer = self.transport.getPeer()
- try:
- host = peer.host
- except AttributeError:
- host = str(peer)
- self._helo = (rest, host)
- self._from = None
- self._to = []
- self.sendCode(250, '%s Hello %s, nice to meet you' % (self.host, host))
-
- def do_QUIT(self, rest):
- self.sendCode(221, 'See you later')
- self.transport.loseConnection()
-
- # A string of quoted strings, backslash-escaped character or
- # atom characters + '@.,:'
- qstring = r'("[^"]*"|\\.|' + atom + r'|[@.,:])+'
-
- mail_re = re.compile(r'''\s*FROM:\s*(?P<path><> # Empty <>
- |<''' + qstring + r'''> # <addr>
- |''' + qstring + r''' # addr
- )\s*(\s(?P<opts>.*))? # Optional WS + ESMTP options
- $''',re.I|re.X)
- rcpt_re = re.compile(r'\s*TO:\s*(?P<path><' + qstring + r'''> # <addr>
- |''' + qstring + r''' # addr
- )\s*(\s(?P<opts>.*))? # Optional WS + ESMTP options
- $''',re.I|re.X)
-
- def do_MAIL(self, rest):
- if self._from:
- self.sendCode(503,"Only one sender per message, please")
- return
- # Clear old recipient list
- self._to = []
- m = self.mail_re.match(rest)
- if not m:
- self.sendCode(501, "Syntax error")
- return
-
- try:
- addr = Address(m.group('path'), self.host)
- except AddressError, e:
- self.sendCode(553, str(e))
- return
-
- validated = defer.maybeDeferred(self.validateFrom, self._helo, addr)
- validated.addCallbacks(self._cbFromValidate, self._ebFromValidate)
-
-
- def _cbFromValidate(self, from_, code=250, msg='Sender address accepted'):
- self._from = from_
- self.sendCode(code, msg)
-
-
- def _ebFromValidate(self, failure):
- if failure.check(SMTPBadSender):
- self.sendCode(failure.value.code,
- 'Cannot receive from specified address %s: %s'
- % (quoteaddr(failure.value.addr), failure.value.resp))
- elif failure.check(SMTPServerError):
- self.sendCode(failure.value.code, failure.value.resp)
- else:
- log.err(failure, "SMTP sender validation failure")
- self.sendCode(
- 451,
- 'Requested action aborted: local error in processing')
-
-
- def do_RCPT(self, rest):
- if not self._from:
- self.sendCode(503, "Must have sender before recipient")
- return
- m = self.rcpt_re.match(rest)
- if not m:
- self.sendCode(501, "Syntax error")
- return
-
- try:
- user = User(m.group('path'), self._helo, self, self._from)
- except AddressError, e:
- self.sendCode(553, str(e))
- return
-
- d = defer.maybeDeferred(self.validateTo, user)
- d.addCallbacks(
- self._cbToValidate,
- self._ebToValidate,
- callbackArgs=(user,)
- )
-
- def _cbToValidate(self, to, user=None, code=250, msg='Recipient address accepted'):
- if user is None:
- user = to
- self._to.append((user, to))
- self.sendCode(code, msg)
-
- def _ebToValidate(self, failure):
- if failure.check(SMTPBadRcpt, SMTPServerError):
- self.sendCode(failure.value.code, failure.value.resp)
- else:
- log.err(failure)
- self.sendCode(
- 451,
- 'Requested action aborted: local error in processing'
- )
-
- def _disconnect(self, msgs):
- for msg in msgs:
- try:
- msg.connectionLost()
- except:
- log.msg("msg raised exception from connectionLost")
- log.err()
-
- def do_DATA(self, rest):
- if self._from is None or (not self._to):
- self.sendCode(503, 'Must have valid receiver and originator')
- return
- self.mode = DATA
- helo, origin = self._helo, self._from
- recipients = self._to
-
- self._from = None
- self._to = []
- self.datafailed = None
-
- msgs = []
- for (user, msgFunc) in recipients:
- try:
- msg = msgFunc()
- rcvdhdr = self.receivedHeader(helo, origin, [user])
- if rcvdhdr:
- msg.lineReceived(rcvdhdr)
- msgs.append(msg)
- except SMTPServerError, e:
- self.sendCode(e.code, e.resp)
- self.mode = COMMAND
- self._disconnect(msgs)
- return
- except:
- log.err()
- self.sendCode(550, "Internal server error")
- self.mode = COMMAND
- self._disconnect(msgs)
- return
- self.__messages = msgs
-
- self.__inheader = self.__inbody = 0
- self.sendCode(354, 'Continue')
-
- if self.noisy:
- fmt = 'Receiving message for delivery: from=%s to=%s'
- log.msg(fmt % (origin, [str(u) for (u, f) in recipients]))
-
- def connectionLost(self, reason):
- # self.sendCode(421, 'Dropping connection.') # This does nothing...
- # Ideally, if we (rather than the other side) lose the connection,
- # we should be able to tell the other side that we are going away.
- # RFC-2821 requires that we try.
- if self.mode is DATA:
- try:
- for message in self.__messages:
- try:
- message.connectionLost()
- except:
- log.err()
- del self.__messages
- except AttributeError:
- pass
- if self._onLogout:
- self._onLogout()
- self._onLogout = None
- self.setTimeout(None)
-
- def do_RSET(self, rest):
- self._from = None
- self._to = []
- self.sendCode(250, 'I remember nothing.')
-
- def dataLineReceived(self, line):
- if line[:1] == '.':
- if line == '.':
- self.mode = COMMAND
- if self.datafailed:
- self.sendCode(self.datafailed.code,
- self.datafailed.resp)
- return
- if not self.__messages:
- self._messageHandled("thrown away")
- return
- defer.DeferredList([
- m.eomReceived() for m in self.__messages
- ], consumeErrors=True).addCallback(self._messageHandled
- )
- del self.__messages
- return
- line = line[1:]
-
- if self.datafailed:
- return
-
- try:
- # Add a blank line between the generated Received:-header
- # and the message body if the message comes in without any
- # headers
- if not self.__inheader and not self.__inbody:
- if ':' in line:
- self.__inheader = 1
- elif line:
- for message in self.__messages:
- message.lineReceived('')
- self.__inbody = 1
-
- if not line:
- self.__inbody = 1
-
- for message in self.__messages:
- message.lineReceived(line)
- except SMTPServerError, e:
- self.datafailed = e
- for message in self.__messages:
- message.connectionLost()
- state_DATA = dataLineReceived
-
- def _messageHandled(self, resultList):
- failures = 0
- for (success, result) in resultList:
- if not success:
- failures += 1
- log.err(result)
- if failures:
- msg = 'Could not send e-mail'
- L = len(resultList)
- if L > 1:
- msg += ' (%d failures out of %d recipients)' % (failures, L)
- self.sendCode(550, msg)
- else:
- self.sendCode(250, 'Delivery in progress')
-
-
- def _cbAnonymousAuthentication(self, (iface, avatar, logout)):
- """
- Save the state resulting from a successful anonymous cred login.
- """
- if issubclass(iface, IMessageDeliveryFactory):
- self.deliveryFactory = avatar
- self.delivery = None
- elif issubclass(iface, IMessageDelivery):
- self.deliveryFactory = None
- self.delivery = avatar
- else:
- raise RuntimeError("%s is not a supported interface" % (iface.__name__,))
- self._onLogout = logout
- self.challenger = None
-
-
- # overridable methods:
- def validateFrom(self, helo, origin):
- """
- Validate the address from which the message originates.
-
- @type helo: C{(str, str)}
- @param helo: The argument to the HELO command and the client's IP
- address.
-
- @type origin: C{Address}
- @param origin: The address the message is from
-
- @rtype: C{Deferred} or C{Address}
- @return: C{origin} or a C{Deferred} whose callback will be
- passed C{origin}.
-
- @raise SMTPBadSender: Raised of messages from this address are
- not to be accepted.
- """
- if self.deliveryFactory is not None:
- self.delivery = self.deliveryFactory.getMessageDelivery()
-
- if self.delivery is not None:
- return defer.maybeDeferred(self.delivery.validateFrom,
- helo, origin)
-
- # No login has been performed, no default delivery object has been
- # provided: try to perform an anonymous login and then invoke this
- # method again.
- if self.portal:
-
- result = self.portal.login(
- cred.credentials.Anonymous(),
- None,
- IMessageDeliveryFactory, IMessageDelivery)
-
- def ebAuthentication(err):
- """
- Translate cred exceptions into SMTP exceptions so that the
- protocol code which invokes C{validateFrom} can properly report
- the failure.
- """
- if err.check(cred.error.UnauthorizedLogin):
- exc = SMTPBadSender(origin)
- elif err.check(cred.error.UnhandledCredentials):
- exc = SMTPBadSender(
- origin, resp="Unauthenticated senders not allowed")
- else:
- return err
- return defer.fail(exc)
-
- result.addCallbacks(
- self._cbAnonymousAuthentication, ebAuthentication)
-
- def continueValidation(ignored):
- """
- Re-attempt from address validation.
- """
- return self.validateFrom(helo, origin)
-
- result.addCallback(continueValidation)
- return result
-
- raise SMTPBadSender(origin)
-
-
- def validateTo(self, user):
- """
- Validate the address for which the message is destined.
-
- @type user: C{User}
- @param user: The address to validate.
-
- @rtype: no-argument callable
- @return: A C{Deferred} which becomes, or a callable which
- takes no arguments and returns an object implementing C{IMessage}.
- This will be called and the returned object used to deliver the
- message when it arrives.
-
- @raise SMTPBadRcpt: Raised if messages to the address are
- not to be accepted.
- """
- if self.delivery is not None:
- return self.delivery.validateTo(user)
- raise SMTPBadRcpt(user)
-
- def receivedHeader(self, helo, origin, recipients):
- if self.delivery is not None:
- return self.delivery.receivedHeader(helo, origin, recipients)
-
- heloStr = ""
- if helo[0]:
- heloStr = " helo=%s" % (helo[0],)
- domain = self.transport.getHost().host
- from_ = "from %s ([%s]%s)" % (helo[0], helo[1], heloStr)
- by = "by %s with %s (%s)" % (domain,
- self.__class__.__name__,
- longversion)
- for_ = "for %s; %s" % (' '.join(map(str, recipients)),
- rfc822date())
- return "Received: %s\n\t%s\n\t%s" % (from_, by, for_)
-
- def startMessage(self, recipients):
- if self.delivery:
- return self.delivery.startMessage(recipients)
- return []
-
-
-class SMTPFactory(protocol.ServerFactory):
- """Factory for SMTP."""
-
- # override in instances or subclasses
- domain = DNSNAME
- timeout = 600
- protocol = SMTP
-
- portal = None
-
- def __init__(self, portal = None):
- self.portal = portal
-
- def buildProtocol(self, addr):
- p = protocol.ServerFactory.buildProtocol(self, addr)
- p.portal = self.portal
- p.host = self.domain
- return p
-
-class SMTPClient(basic.LineReceiver, policies.TimeoutMixin):
- """
- SMTP client for sending emails.
-
- After the client has connected to the SMTP server, it repeatedly calls
- L{SMTPClient.getMailFrom}, L{SMTPClient.getMailTo} and
- L{SMTPClient.getMailData} and uses this information to send an email.
- It then calls L{SMTPClient.getMailFrom} again; if it returns C{None}, the
- client will disconnect, otherwise it will continue as normal i.e. call
- L{SMTPClient.getMailTo} and L{SMTPClient.getMailData} and send a new email.
- """
-
- # If enabled then log SMTP client server communication
- debug = True
-
- # Number of seconds to wait before timing out a connection. If
- # None, perform no timeout checking.
- timeout = None
-
- def __init__(self, identity, logsize=10):
- self.identity = identity or ''
- self.toAddressesResult = []
- self.successAddresses = []
- self._from = None
- self.resp = []
- self.code = -1
- self.log = util.LineLog(logsize)
-
- def sendLine(self, line):
- # Log sendLine only if you are in debug mode for performance
- if self.debug:
- self.log.append('>>> ' + line)
-
- basic.LineReceiver.sendLine(self,line)
-
- def connectionMade(self):
- self.setTimeout(self.timeout)
-
- self._expected = [ 220 ]
- self._okresponse = self.smtpState_helo
- self._failresponse = self.smtpConnectionFailed
-
- def connectionLost(self, reason=protocol.connectionDone):
- """We are no longer connected"""
- self.setTimeout(None)
- self.mailFile = None
-
- def timeoutConnection(self):
- self.sendError(
- SMTPTimeoutError(
- -1, "Timeout waiting for SMTP server response",
- self.log.str()))
-
- def lineReceived(self, line):
- self.resetTimeout()
-
- # Log lineReceived only if you are in debug mode for performance
- if self.debug:
- self.log.append('<<< ' + line)
-
- why = None
-
- try:
- self.code = int(line[:3])
- except ValueError:
- # This is a fatal error and will disconnect the transport lineReceived will not be called again
- self.sendError(SMTPProtocolError(-1, "Invalid response from SMTP server: %s" % line, self.log.str()))
- return
-
- if line[0] == '0':
- # Verbose informational message, ignore it
- return
-
- self.resp.append(line[4:])
-
- if line[3:4] == '-':
- # continuation
- return
-
- if self.code in self._expected:
- why = self._okresponse(self.code,'\n'.join(self.resp))
- else:
- why = self._failresponse(self.code,'\n'.join(self.resp))
-
- self.code = -1
- self.resp = []
- return why
-
- def smtpConnectionFailed(self, code, resp):
- self.sendError(SMTPConnectError(code, resp, self.log.str()))
-
- def smtpTransferFailed(self, code, resp):
- if code < 0:
- self.sendError(SMTPProtocolError(code, resp, self.log.str()))
- else:
- self.smtpState_msgSent(code, resp)
-
- def smtpState_helo(self, code, resp):
- self.sendLine('HELO ' + self.identity)
- self._expected = SUCCESS
- self._okresponse = self.smtpState_from
-
- def smtpState_from(self, code, resp):
- self._from = self.getMailFrom()
- self._failresponse = self.smtpTransferFailed
- if self._from is not None:
- self.sendLine('MAIL FROM:%s' % quoteaddr(self._from))
- self._expected = [250]
- self._okresponse = self.smtpState_to
- else:
- # All messages have been sent, disconnect
- self._disconnectFromServer()
-
- def smtpState_disconnect(self, code, resp):
- self.transport.loseConnection()
-
- def smtpState_to(self, code, resp):
- self.toAddresses = iter(self.getMailTo())
- self.toAddressesResult = []
- self.successAddresses = []
- self._okresponse = self.smtpState_toOrData
- self._expected = xrange(0,1000)
- self.lastAddress = None
- return self.smtpState_toOrData(0, '')
-
- def smtpState_toOrData(self, code, resp):
- if self.lastAddress is not None:
- self.toAddressesResult.append((self.lastAddress, code, resp))
- if code in SUCCESS:
- self.successAddresses.append(self.lastAddress)
- try:
- self.lastAddress = self.toAddresses.next()
- except StopIteration:
- if self.successAddresses:
- self.sendLine('DATA')
- self._expected = [ 354 ]
- self._okresponse = self.smtpState_data
- else:
- return self.smtpState_msgSent(code,'No recipients accepted')
- else:
- self.sendLine('RCPT TO:%s' % quoteaddr(self.lastAddress))
-
- def smtpState_data(self, code, resp):
- s = basic.FileSender()
- d = s.beginFileTransfer(
- self.getMailData(), self.transport, self.transformChunk)
- def ebTransfer(err):
- self.sendError(err.value)
- d.addCallbacks(self.finishedFileTransfer, ebTransfer)
- self._expected = SUCCESS
- self._okresponse = self.smtpState_msgSent
-
-
- def smtpState_msgSent(self, code, resp):
- if self._from is not None:
- self.sentMail(code, resp, len(self.successAddresses),
- self.toAddressesResult, self.log)
-
- self.toAddressesResult = []
- self._from = None
- self.sendLine('RSET')
- self._expected = SUCCESS
- self._okresponse = self.smtpState_from
-
- ##
- ## Helpers for FileSender
- ##
- def transformChunk(self, chunk):
- """
- Perform the necessary local to network newline conversion and escape
- leading periods.
-
- This method also resets the idle timeout so that as long as process is
- being made sending the message body, the client will not time out.
- """
- self.resetTimeout()
- return chunk.replace('\n', '\r\n').replace('\r\n.', '\r\n..')
-
- def finishedFileTransfer(self, lastsent):
- if lastsent != '\n':
- line = '\r\n.'
- else:
- line = '.'
- self.sendLine(line)
-
- ##
- # these methods should be overriden in subclasses
- def getMailFrom(self):
- """Return the email address the mail is from."""
- raise NotImplementedError
-
- def getMailTo(self):
- """Return a list of emails to send to."""
- raise NotImplementedError
-
- def getMailData(self):
- """Return file-like object containing data of message to be sent.
-
- Lines in the file should be delimited by '\\n'.
- """
- raise NotImplementedError
-
- def sendError(self, exc):
- """
- If an error occurs before a mail message is sent sendError will be
- called. This base class method sends a QUIT if the error is
- non-fatal and disconnects the connection.
-
- @param exc: The SMTPClientError (or child class) raised
- @type exc: C{SMTPClientError}
- """
- if isinstance(exc, SMTPClientError) and not exc.isFatal:
- self._disconnectFromServer()
- else:
- # If the error was fatal then the communication channel with the
- # SMTP Server is broken so just close the transport connection
- self.smtpState_disconnect(-1, None)
-
-
- def sentMail(self, code, resp, numOk, addresses, log):
- """Called when an attempt to send an email is completed.
-
- If some addresses were accepted, code and resp are the response
- to the DATA command. If no addresses were accepted, code is -1
- and resp is an informative message.
-
- @param code: the code returned by the SMTP Server
- @param resp: The string response returned from the SMTP Server
- @param numOK: the number of addresses accepted by the remote host.
- @param addresses: is a list of tuples (address, code, resp) listing
- the response to each RCPT command.
- @param log: is the SMTP session log
- """
- raise NotImplementedError
-
- def _disconnectFromServer(self):
- self._expected = xrange(0, 1000)
- self._okresponse = self.smtpState_disconnect
- self.sendLine('QUIT')
-
-
-
-class ESMTPClient(SMTPClient):
- # Fall back to HELO if the server does not support EHLO
- heloFallback = True
-
- # Refuse to proceed if authentication cannot be performed
- requireAuthentication = False
-
- # Refuse to proceed if TLS is not available
- requireTransportSecurity = False
-
- # Indicate whether or not our transport can be considered secure.
- tlsMode = False
-
- # ClientContextFactory to use for STARTTLS
- context = None
-
- def __init__(self, secret, contextFactory=None, *args, **kw):
- SMTPClient.__init__(self, *args, **kw)
- self.authenticators = []
- self.secret = secret
- self.context = contextFactory
- self.tlsMode = False
-
-
- def esmtpEHLORequired(self, code=-1, resp=None):
- self.sendError(EHLORequiredError(502, "Server does not support ESMTP Authentication", self.log.str()))
-
-
- def esmtpAUTHRequired(self, code=-1, resp=None):
- tmp = []
-
- for a in self.authenticators:
- tmp.append(a.getName().upper())
-
- auth = "[%s]" % ', '.join(tmp)
-
- self.sendError(AUTHRequiredError(502, "Server does not support Client Authentication schemes %s" % auth,
- self.log.str()))
-
-
- def esmtpTLSRequired(self, code=-1, resp=None):
- self.sendError(TLSRequiredError(502, "Server does not support secure communication via TLS / SSL",
- self.log.str()))
-
- def esmtpTLSFailed(self, code=-1, resp=None):
- self.sendError(TLSError(code, "Could not complete the SSL/TLS handshake", self.log.str()))
-
- def esmtpAUTHDeclined(self, code=-1, resp=None):
- self.sendError(AUTHDeclinedError(code, resp, self.log.str()))
-
- def esmtpAUTHMalformedChallenge(self, code=-1, resp=None):
- str = "Login failed because the SMTP Server returned a malformed Authentication Challenge"
- self.sendError(AuthenticationError(501, str, self.log.str()))
-
- def esmtpAUTHServerError(self, code=-1, resp=None):
- self.sendError(AuthenticationError(code, resp, self.log.str()))
-
- def registerAuthenticator(self, auth):
- """Registers an Authenticator with the ESMTPClient. The ESMTPClient
- will attempt to login to the SMTP Server in the order the
- Authenticators are registered. The most secure Authentication
- mechanism should be registered first.
-
- @param auth: The Authentication mechanism to register
- @type auth: class implementing C{IClientAuthentication}
- """
-
- self.authenticators.append(auth)
-
- def connectionMade(self):
- SMTPClient.connectionMade(self)
- self._okresponse = self.esmtpState_ehlo
-
- def esmtpState_ehlo(self, code, resp):
- self._expected = SUCCESS
-
- self._okresponse = self.esmtpState_serverConfig
- self._failresponse = self.esmtpEHLORequired
-
- if self.heloFallback:
- self._failresponse = self.smtpState_helo
-
- self.sendLine('EHLO ' + self.identity)
-
- def esmtpState_serverConfig(self, code, resp):
- items = {}
- for line in resp.splitlines():
- e = line.split(None, 1)
- if len(e) > 1:
- items[e[0]] = e[1]
- else:
- items[e[0]] = None
-
- if self.tlsMode:
- self.authenticate(code, resp, items)
- else:
- self.tryTLS(code, resp, items)
-
- def tryTLS(self, code, resp, items):
- if self.context and 'STARTTLS' in items:
- self._expected = [220]
- self._okresponse = self.esmtpState_starttls
- self._failresponse = self.esmtpTLSFailed
- self.sendLine('STARTTLS')
- elif self.requireTransportSecurity:
- self.tlsMode = False
- self.esmtpTLSRequired()
- else:
- self.tlsMode = False
- self.authenticate(code, resp, items)
-
- def esmtpState_starttls(self, code, resp):
- try:
- self.transport.startTLS(self.context)
- self.tlsMode = True
- except:
- log.err()
- self.esmtpTLSFailed(451)
-
- # Send another EHLO once TLS has been started to
- # get the TLS / AUTH schemes. Some servers only allow AUTH in TLS mode.
- self.esmtpState_ehlo(code, resp)
-
- def authenticate(self, code, resp, items):
- if self.secret and items.get('AUTH'):
- schemes = items['AUTH'].split()
- tmpSchemes = {}
-
- #XXX: May want to come up with a more efficient way to do this
- for s in schemes:
- tmpSchemes[s.upper()] = 1
-
- for a in self.authenticators:
- auth = a.getName().upper()
-
- if auth in tmpSchemes:
- self._authinfo = a
-
- # Special condition handled
- if auth == "PLAIN":
- self._okresponse = self.smtpState_from
- self._failresponse = self._esmtpState_plainAuth
- self._expected = [235]
- challenge = encode_base64(self._authinfo.challengeResponse(self.secret, 1), eol="")
- self.sendLine('AUTH ' + auth + ' ' + challenge)
- else:
- self._expected = [334]
- self._okresponse = self.esmtpState_challenge
- # If some error occurs here, the server declined the AUTH
- # before the user / password phase. This would be
- # a very rare case
- self._failresponse = self.esmtpAUTHServerError
- self.sendLine('AUTH ' + auth)
- return
-
- if self.requireAuthentication:
- self.esmtpAUTHRequired()
- else:
- self.smtpState_from(code, resp)
-
- def _esmtpState_plainAuth(self, code, resp):
- self._okresponse = self.smtpState_from
- self._failresponse = self.esmtpAUTHDeclined
- self._expected = [235]
- challenge = encode_base64(self._authinfo.challengeResponse(self.secret, 2), eol="")
- self.sendLine('AUTH PLAIN ' + challenge)
-
- def esmtpState_challenge(self, code, resp):
- self._authResponse(self._authinfo, resp)
-
- def _authResponse(self, auth, challenge):
- self._failresponse = self.esmtpAUTHDeclined
- try:
- challenge = base64.decodestring(challenge)
- except binascii.Error:
- # Illegal challenge, give up, then quit
- self.sendLine('*')
- self._okresponse = self.esmtpAUTHMalformedChallenge
- self._failresponse = self.esmtpAUTHMalformedChallenge
- else:
- resp = auth.challengeResponse(self.secret, challenge)
- self._expected = [235, 334]
- self._okresponse = self.smtpState_maybeAuthenticated
- self.sendLine(encode_base64(resp, eol=""))
-
-
- def smtpState_maybeAuthenticated(self, code, resp):
- """
- Called to handle the next message from the server after sending a
- response to a SASL challenge. The server response might be another
- challenge or it might indicate authentication has succeeded.
- """
- if code == 235:
- # Yes, authenticated!
- del self._authinfo
- self.smtpState_from(code, resp)
- else:
- # No, not authenticated yet. Keep trying.
- self._authResponse(self._authinfo, resp)
-
-
-
-class ESMTP(SMTP):
-
- ctx = None
- canStartTLS = False
- startedTLS = False
-
- authenticated = False
-
- def __init__(self, chal = None, contextFactory = None):
- SMTP.__init__(self)
- if chal is None:
- chal = {}
- self.challengers = chal
- self.authenticated = False
- self.ctx = contextFactory
-
- def connectionMade(self):
- SMTP.connectionMade(self)
- self.canStartTLS = ITLSTransport.providedBy(self.transport)
- self.canStartTLS = self.canStartTLS and (self.ctx is not None)
-
-
- def greeting(self):
- return SMTP.greeting(self) + ' ESMTP'
-
-
- def extensions(self):
- ext = {'AUTH': self.challengers.keys()}
- if self.canStartTLS and not self.startedTLS:
- ext['STARTTLS'] = None
- return ext
-
- def lookupMethod(self, command):
- m = SMTP.lookupMethod(self, command)
- if m is None:
- m = getattr(self, 'ext_' + command.upper(), None)
- return m
-
- def listExtensions(self):
- r = []
- for (c, v) in self.extensions().iteritems():
- if v is not None:
- if v:
- # Intentionally omit extensions with empty argument lists
- r.append('%s %s' % (c, ' '.join(v)))
- else:
- r.append(c)
- return '\n'.join(r)
-
- def do_EHLO(self, rest):
- peer = self.transport.getPeer().host
- self._helo = (rest, peer)
- self._from = None
- self._to = []
- self.sendCode(
- 250,
- '%s Hello %s, nice to meet you\n%s' % (
- self.host, peer,
- self.listExtensions(),
- )
- )
-
- def ext_STARTTLS(self, rest):
- if self.startedTLS:
- self.sendCode(503, 'TLS already negotiated')
- elif self.ctx and self.canStartTLS:
- self.sendCode(220, 'Begin TLS negotiation now')
- self.transport.startTLS(self.ctx)
- self.startedTLS = True
- else:
- self.sendCode(454, 'TLS not available')
-
- def ext_AUTH(self, rest):
- if self.authenticated:
- self.sendCode(503, 'Already authenticated')
- return
- parts = rest.split(None, 1)
- chal = self.challengers.get(parts[0].upper(), lambda: None)()
- if not chal:
- self.sendCode(504, 'Unrecognized authentication type')
- return
-
- self.mode = AUTH
- self.challenger = chal
-
- if len(parts) > 1:
- chal.getChallenge() # Discard it, apparently the client does not
- # care about it.
- rest = parts[1]
- else:
- rest = None
- self.state_AUTH(rest)
-
-
- def _cbAuthenticated(self, loginInfo):
- """
- Save the state resulting from a successful cred login and mark this
- connection as authenticated.
- """
- result = SMTP._cbAnonymousAuthentication(self, loginInfo)
- self.authenticated = True
- return result
-
-
- def _ebAuthenticated(self, reason):
- """
- Handle cred login errors by translating them to the SMTP authenticate
- failed. Translate all other errors into a generic SMTP error code and
- log the failure for inspection. Stop all errors from propagating.
- """
- self.challenge = None
- if reason.check(cred.error.UnauthorizedLogin):
- self.sendCode(535, 'Authentication failed')
- else:
- log.err(reason, "SMTP authentication failure")
- self.sendCode(
- 451,
- 'Requested action aborted: local error in processing')
-
-
- def state_AUTH(self, response):
- """
- Handle one step of challenge/response authentication.
-
- @param response: The text of a response. If None, this
- function has been called as a result of an AUTH command with
- no initial response. A response of '*' aborts authentication,
- as per RFC 2554.
- """
- if self.portal is None:
- self.sendCode(454, 'Temporary authentication failure')
- self.mode = COMMAND
- return
-
- if response is None:
- challenge = self.challenger.getChallenge()
- encoded = challenge.encode('base64')
- self.sendCode(334, encoded)
- return
-
- if response == '*':
- self.sendCode(501, 'Authentication aborted')
- self.challenger = None
- self.mode = COMMAND
- return
-
- try:
- uncoded = response.decode('base64')
- except binascii.Error:
- self.sendCode(501, 'Syntax error in parameters or arguments')
- self.challenger = None
- self.mode = COMMAND
- return
-
- self.challenger.setResponse(uncoded)
- if self.challenger.moreChallenges():
- challenge = self.challenger.getChallenge()
- coded = challenge.encode('base64')[:-1]
- self.sendCode(334, coded)
- return
-
- self.mode = COMMAND
- result = self.portal.login(
- self.challenger, None,
- IMessageDeliveryFactory, IMessageDelivery)
- result.addCallback(self._cbAuthenticated)
- result.addCallback(lambda ign: self.sendCode(235, 'Authentication successful.'))
- result.addErrback(self._ebAuthenticated)
-
-
-
-class SenderMixin:
- """Utility class for sending emails easily.
-
- Use with SMTPSenderFactory or ESMTPSenderFactory.
- """
- done = 0
-
- def getMailFrom(self):
- if not self.done:
- self.done = 1
- return str(self.factory.fromEmail)
- else:
- return None
-
- def getMailTo(self):
- return self.factory.toEmail
-
- def getMailData(self):
- return self.factory.file
-
- def sendError(self, exc):
- # Call the base class to close the connection with the SMTP server
- SMTPClient.sendError(self, exc)
-
- # Do not retry to connect to SMTP Server if:
- # 1. No more retries left (This allows the correct error to be returned to the errorback)
- # 2. retry is false
- # 3. The error code is not in the 4xx range (Communication Errors)
-
- if (self.factory.retries >= 0 or
- (not exc.retry and not (exc.code >= 400 and exc.code < 500))):
- self.factory.sendFinished = 1
- self.factory.result.errback(exc)
-
- def sentMail(self, code, resp, numOk, addresses, log):
- # Do not retry, the SMTP server acknowledged the request
- self.factory.sendFinished = 1
- if code not in SUCCESS:
- errlog = []
- for addr, acode, aresp in addresses:
- if acode not in SUCCESS:
- errlog.append("%s: %03d %s" % (addr, acode, aresp))
-
- errlog.append(log.str())
-
- exc = SMTPDeliveryError(code, resp, '\n'.join(errlog), addresses)
- self.factory.result.errback(exc)
- else:
- self.factory.result.callback((numOk, addresses))
-
-
-class SMTPSender(SenderMixin, SMTPClient):
- """
- SMTP protocol that sends a single email based on information it
- gets from its factory, a L{SMTPSenderFactory}.
- """
-
-
-class SMTPSenderFactory(protocol.ClientFactory):
- """
- Utility factory for sending emails easily.
- """
-
- domain = DNSNAME
- protocol = SMTPSender
-
- def __init__(self, fromEmail, toEmail, file, deferred, retries=5,
- timeout=None):
- """
- @param fromEmail: The RFC 2821 address from which to send this
- message.
-
- @param toEmail: A sequence of RFC 2821 addresses to which to
- send this message.
-
- @param file: A file-like object containing the message to send.
-
- @param deferred: A Deferred to callback or errback when sending
- of this message completes.
-
- @param retries: The number of times to retry delivery of this
- message.
-
- @param timeout: Period, in seconds, for which to wait for
- server responses, or None to wait forever.
- """
- assert isinstance(retries, (int, long))
-
- if isinstance(toEmail, types.StringTypes):
- toEmail = [toEmail]
- self.fromEmail = Address(fromEmail)
- self.nEmails = len(toEmail)
- self.toEmail = toEmail
- self.file = file
- self.result = deferred
- self.result.addBoth(self._removeDeferred)
- self.sendFinished = 0
-
- self.retries = -retries
- self.timeout = timeout
-
- def _removeDeferred(self, argh):
- del self.result
- return argh
-
- def clientConnectionFailed(self, connector, err):
- self._processConnectionError(connector, err)
-
- def clientConnectionLost(self, connector, err):
- self._processConnectionError(connector, err)
-
- def _processConnectionError(self, connector, err):
- if self.retries < self.sendFinished <= 0:
- log.msg("SMTP Client retrying server. Retry: %s" % -self.retries)
-
- # Rewind the file in case part of it was read while attempting to
- # send the message.
- self.file.seek(0, 0)
- connector.connect()
- self.retries += 1
- elif self.sendFinished <= 0:
- # If we were unable to communicate with the SMTP server a ConnectionDone will be
- # returned. We want a more clear error message for debugging
- if err.check(error.ConnectionDone):
- err.value = SMTPConnectError(-1, "Unable to connect to server.")
- self.result.errback(err.value)
-
- def buildProtocol(self, addr):
- p = self.protocol(self.domain, self.nEmails*2+2)
- p.factory = self
- p.timeout = self.timeout
- return p
-
-
-
-from twisted.mail.imap4 import IClientAuthentication
-from twisted.mail.imap4 import CramMD5ClientAuthenticator, LOGINAuthenticator
-from twisted.mail.imap4 import LOGINCredentials as _lcredentials
-
-class LOGINCredentials(_lcredentials):
- """
- L{LOGINCredentials} generates challenges for I{LOGIN} authentication.
-
- For interoperability with Outlook, the challenge generated does not exactly
- match the one defined in the
- U{draft specification<http://sepp.oetiker.ch/sasl-2.1.19-ds/draft-murchison-sasl-login-00.txt>}.
- """
-
- def __init__(self):
- _lcredentials.__init__(self)
- self.challenges = ['Password:', 'Username:']
-
-
-
-class PLAINAuthenticator:
- implements(IClientAuthentication)
-
- def __init__(self, user):
- self.user = user
-
- def getName(self):
- return "PLAIN"
-
- def challengeResponse(self, secret, chal=1):
- if chal == 1:
- return "%s\0%s\0%s" % (self.user, self.user, secret)
- else:
- return "%s\0%s" % (self.user, secret)
-
-
-
-class ESMTPSender(SenderMixin, ESMTPClient):
-
- requireAuthentication = True
- requireTransportSecurity = True
-
- def __init__(self, username, secret, contextFactory=None, *args, **kw):
- self.heloFallback = 0
- self.username = username
-
- if contextFactory is None:
- contextFactory = self._getContextFactory()
-
- ESMTPClient.__init__(self, secret, contextFactory, *args, **kw)
-
- self._registerAuthenticators()
-
- def _registerAuthenticators(self):
- # Register Authenticator in order from most secure to least secure
- self.registerAuthenticator(CramMD5ClientAuthenticator(self.username))
- self.registerAuthenticator(LOGINAuthenticator(self.username))
- self.registerAuthenticator(PLAINAuthenticator(self.username))
-
- def _getContextFactory(self):
- if self.context is not None:
- return self.context
- try:
- from twisted.internet import ssl
- except ImportError:
- return None
- else:
- try:
- context = ssl.ClientContextFactory()
- context.method = ssl.SSL.TLSv1_METHOD
- return context
- except AttributeError:
- return None
-
-
-class ESMTPSenderFactory(SMTPSenderFactory):
- """
- Utility factory for sending emails easily.
- """
-
- protocol = ESMTPSender
-
- def __init__(self, username, password, fromEmail, toEmail, file,
- deferred, retries=5, timeout=None,
- contextFactory=None, heloFallback=False,
- requireAuthentication=True,
- requireTransportSecurity=True):
-
- SMTPSenderFactory.__init__(self, fromEmail, toEmail, file, deferred, retries, timeout)
- self.username = username
- self.password = password
- self._contextFactory = contextFactory
- self._heloFallback = heloFallback
- self._requireAuthentication = requireAuthentication
- self._requireTransportSecurity = requireTransportSecurity
-
- def buildProtocol(self, addr):
- p = self.protocol(self.username, self.password, self._contextFactory, self.domain, self.nEmails*2+2)
- p.heloFallback = self._heloFallback
- p.requireAuthentication = self._requireAuthentication
- p.requireTransportSecurity = self._requireTransportSecurity
- p.factory = self
- p.timeout = self.timeout
- return p
-
-def sendmail(smtphost, from_addr, to_addrs, msg, senderDomainName=None, port=25):
- """Send an email
-
- This interface is intended to be a direct replacement for
- smtplib.SMTP.sendmail() (with the obvious change that
- you specify the smtphost as well). Also, ESMTP options
- are not accepted, as we don't do ESMTP yet. I reserve the
- right to implement the ESMTP options differently.
-
- @param smtphost: The host the message should be sent to
- @param from_addr: The (envelope) address sending this mail.
- @param to_addrs: A list of addresses to send this mail to. A string will
- be treated as a list of one address
- @param msg: The message, including headers, either as a file or a string.
- File-like objects need to support read() and close(). Lines must be
- delimited by '\\n'. If you pass something that doesn't look like a
- file, we try to convert it to a string (so you should be able to
- pass an email.Message directly, but doing the conversion with
- email.Generator manually will give you more control over the
- process).
-
- @param senderDomainName: Name by which to identify. If None, try
- to pick something sane (but this depends on external configuration
- and may not succeed).
-
- @param port: Remote port to which to connect.
-
- @rtype: L{Deferred}
- @returns: A L{Deferred}, its callback will be called if a message is sent
- to ANY address, the errback if no message is sent.
-
- The callback will be called with a tuple (numOk, addresses) where numOk
- is the number of successful recipient addresses and addresses is a list
- of tuples (address, code, resp) giving the response to the RCPT command
- for each address.
- """
- if not hasattr(msg,'read'):
- # It's not a file
- msg = StringIO(str(msg))
-
- d = defer.Deferred()
- factory = SMTPSenderFactory(from_addr, to_addrs, msg, d)
-
- if senderDomainName is not None:
- factory.domain = senderDomainName
-
- reactor.connectTCP(smtphost, port, factory)
-
- return d
-
-
-
-##
-## Yerg. Codecs!
-##
-import codecs
-def xtext_encode(s, errors=None):
- r = []
- for ch in s:
- o = ord(ch)
- if ch == '+' or ch == '=' or o < 33 or o > 126:
- r.append('+%02X' % o)
- else:
- r.append(chr(o))
- return (''.join(r), len(s))
-
-
-def xtext_decode(s, errors=None):
- """
- Decode the xtext-encoded string C{s}.
- """
- r = []
- i = 0
- while i < len(s):
- if s[i] == '+':
- try:
- r.append(chr(int(s[i + 1:i + 3], 16)))
- except ValueError:
- r.append(s[i:i + 3])
- i += 3
- else:
- r.append(s[i])
- i += 1
- return (''.join(r), len(s))
-
-class xtextStreamReader(codecs.StreamReader):
- def decode(self, s, errors='strict'):
- return xtext_decode(s)
-
-class xtextStreamWriter(codecs.StreamWriter):
- def decode(self, s, errors='strict'):
- return xtext_encode(s)
-
-def xtext_codec(name):
- if name == 'xtext':
- return (xtext_encode, xtext_decode, xtextStreamReader, xtextStreamWriter)
-codecs.register(xtext_codec)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/tap.py
deleted file mode 100755
index fe525f30..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/tap.py
+++ /dev/null
@@ -1,333 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_options -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-I am the support module for creating mail servers with twistd
-"""
-
-import os
-import warnings
-
-from twisted.mail import mail
-from twisted.mail import maildir
-from twisted.mail import relay
-from twisted.mail import relaymanager
-from twisted.mail import alias
-
-from twisted.internet import endpoints
-
-from twisted.python import usage
-
-from twisted.cred import checkers
-from twisted.cred import strcred
-
-from twisted.application import internet
-
-
-class Options(usage.Options, strcred.AuthOptionMixin):
- synopsis = "[options]"
-
- optParameters = [
- ["pop3s", "S", 0,
- "Port to start the POP3-over-SSL server on (0 to disable). "
- "DEPRECATED: use "
- "'--pop3 ssl:port:privateKey=pkey.pem:certKey=cert.pem'"],
-
- ["certificate", "c", None,
- "Certificate file to use for SSL connections. "
- "DEPRECATED: use "
- "'--pop3 ssl:port:privateKey=pkey.pem:certKey=cert.pem'"],
-
- ["relay", "R", None,
- "Relay messages according to their envelope 'To', using "
- "the given path as a queue directory."],
-
- ["hostname", "H", None,
- "The hostname by which to identify this server."],
- ]
-
- optFlags = [
- ["esmtp", "E", "Use RFC 1425/1869 SMTP extensions"],
- ["disable-anonymous", None,
- "Disallow non-authenticated SMTP connections"],
- ["no-pop3", None, "Disable the default POP3 server."],
- ["no-smtp", None, "Disable the default SMTP server."],
- ]
-
- _protoDefaults = {
- "pop3": 8110,
- "smtp": 8025,
- }
-
- compData = usage.Completions(
- optActions={"hostname" : usage.CompleteHostnames(),
- "certificate" : usage.CompleteFiles("*.pem")}
- )
-
- longdesc = "This creates a mail.tap file that can be used by twistd."
-
- def __init__(self):
- usage.Options.__init__(self)
- self.service = mail.MailService()
- self.last_domain = None
- for service in self._protoDefaults:
- self[service] = []
-
-
- def addEndpoint(self, service, description, certificate=None):
- """
- Given a 'service' (pop3 or smtp), add an endpoint.
- """
- self[service].append(
- _toEndpoint(description, certificate=certificate))
-
-
- def opt_pop3(self, description):
- """
- Add a pop3 port listener on the specified endpoint. You can listen on
- multiple ports by specifying multiple --pop3 options. For backwards
- compatibility, a bare TCP port number can be specified, but this is
- deprecated. [SSL Example: ssl:8995:privateKey=mycert.pem] [default:
- tcp:8110]
- """
- self.addEndpoint('pop3', description)
- opt_p = opt_pop3
-
-
- def opt_smtp(self, description):
- """
- Add an smtp port listener on the specified endpoint. You can listen on
- multiple ports by specifying multiple --smtp options For backwards
- compatibility, a bare TCP port number can be specified, but this is
- deprecated. [SSL Example: ssl:8465:privateKey=mycert.pem] [default:
- tcp:8025]
- """
- self.addEndpoint('smtp', description)
- opt_s = opt_smtp
-
-
- def opt_default(self):
- """Make the most recently specified domain the default domain."""
- if self.last_domain:
- self.service.addDomain('', self.last_domain)
- else:
- raise usage.UsageError("Specify a domain before specifying using --default")
- opt_D = opt_default
-
-
- def opt_maildirdbmdomain(self, domain):
- """generate an SMTP/POP3 virtual domain which saves to \"path\"
- """
- try:
- name, path = domain.split('=')
- except ValueError:
- raise usage.UsageError("Argument to --maildirdbmdomain must be of the form 'name=path'")
-
- self.last_domain = maildir.MaildirDirdbmDomain(self.service, os.path.abspath(path))
- self.service.addDomain(name, self.last_domain)
- opt_d = opt_maildirdbmdomain
-
- def opt_user(self, user_pass):
- """add a user/password to the last specified domains
- """
- try:
- user, password = user_pass.split('=', 1)
- except ValueError:
- raise usage.UsageError("Argument to --user must be of the form 'user=password'")
- if self.last_domain:
- self.last_domain.addUser(user, password)
- else:
- raise usage.UsageError("Specify a domain before specifying users")
- opt_u = opt_user
-
- def opt_bounce_to_postmaster(self):
- """undelivered mails are sent to the postmaster
- """
- self.last_domain.postmaster = 1
- opt_b = opt_bounce_to_postmaster
-
- def opt_aliases(self, filename):
- """Specify an aliases(5) file to use for this domain"""
- if self.last_domain is not None:
- if mail.IAliasableDomain.providedBy(self.last_domain):
- aliases = alias.loadAliasFile(self.service.domains, filename)
- self.last_domain.setAliasGroup(aliases)
- self.service.monitor.monitorFile(
- filename,
- AliasUpdater(self.service.domains, self.last_domain)
- )
- else:
- raise usage.UsageError(
- "%s does not support alias files" % (
- self.last_domain.__class__.__name__,
- )
- )
- else:
- raise usage.UsageError("Specify a domain before specifying aliases")
- opt_A = opt_aliases
-
- def _getEndpoints(self, reactor, service):
- """
- Return a list of endpoints for the specified service, constructing
- defaults if necessary.
-
- @param reactor: If any endpoints are created, this is the reactor with
- which they are created.
-
- @param service: A key into self indicating the type of service to
- retrieve endpoints for. This is either C{"pop3"} or C{"smtp"}.
-
- @return: A C{list} of C{IServerStreamEndpoint} providers corresponding
- to the command line parameters that were specified for C{service}.
- If none were and the protocol was not explicitly disabled with a
- I{--no-*} option, a default endpoint for the service is created
- using C{self._protoDefaults}.
- """
- if service == 'pop3' and self['pop3s'] and len(self[service]) == 1:
- # The single endpoint here is the POP3S service we added in
- # postOptions. Include the default endpoint alongside it.
- return self[service] + [
- endpoints.TCP4ServerEndpoint(
- reactor, self._protoDefaults[service])]
- elif self[service]:
- # For any non-POP3S case, if there are any services set up, just
- # return those.
- return self[service]
- elif self['no-' + service]:
- # If there are no services, but the service was explicitly disabled,
- # return nothing.
- return []
- else:
- # Otherwise, return the old default service.
- return [
- endpoints.TCP4ServerEndpoint(
- reactor, self._protoDefaults[service])]
-
-
- def postOptions(self):
- from twisted.internet import reactor
-
- if self['pop3s']:
- if not self['certificate']:
- raise usage.UsageError("Cannot specify --pop3s without "
- "--certificate")
- elif not os.path.exists(self['certificate']):
- raise usage.UsageError("Certificate file %r does not exist."
- % self['certificate'])
- else:
- self.addEndpoint(
- 'pop3', self['pop3s'], certificate=self['certificate'])
-
- if self['esmtp'] and self['hostname'] is None:
- raise usage.UsageError("--esmtp requires --hostname")
-
- # If the --auth option was passed, this will be present -- otherwise,
- # it won't be, which is also a perfectly valid state.
- if 'credCheckers' in self:
- for ch in self['credCheckers']:
- self.service.smtpPortal.registerChecker(ch)
-
- if not self['disable-anonymous']:
- self.service.smtpPortal.registerChecker(checkers.AllowAnonymousAccess())
-
- anything = False
- for service in self._protoDefaults:
- self[service] = self._getEndpoints(reactor, service)
- if self[service]:
- anything = True
-
- if not anything:
- raise usage.UsageError("You cannot disable all protocols")
-
-
-
-class AliasUpdater:
- def __init__(self, domains, domain):
- self.domains = domains
- self.domain = domain
- def __call__(self, new):
- self.domain.setAliasGroup(alias.loadAliasFile(self.domains, new))
-
-
-def _toEndpoint(description, certificate=None):
- """
- Tries to guess whether a description is a bare TCP port or a endpoint. If a
- bare port is specified and a certificate file is present, returns an
- SSL4ServerEndpoint and otherwise returns a TCP4ServerEndpoint.
- """
- from twisted.internet import reactor
- try:
- port = int(description)
- except ValueError:
- return endpoints.serverFromString(reactor, description)
-
- warnings.warn(
- "Specifying plain ports and/or a certificate is deprecated since "
- "Twisted 11.0; use endpoint descriptions instead.",
- category=DeprecationWarning, stacklevel=3)
-
- if certificate:
- from twisted.internet.ssl import DefaultOpenSSLContextFactory
- ctx = DefaultOpenSSLContextFactory(certificate, certificate)
- return endpoints.SSL4ServerEndpoint(reactor, port, ctx)
- return endpoints.TCP4ServerEndpoint(reactor, port)
-
-
-def makeService(config):
- """
- Construct a service for operating a mail server.
-
- The returned service may include POP3 servers or SMTP servers (or both),
- depending on the configuration passed in. If there are multiple servers,
- they will share all of their non-network state (eg, the same user accounts
- are available on all of them).
-
- @param config: An L{Options} instance specifying what servers to include in
- the returned service and where they should keep mail data.
-
- @return: An L{IService} provider which contains the requested mail servers.
- """
- if config['esmtp']:
- rmType = relaymanager.SmartHostESMTPRelayingManager
- smtpFactory = config.service.getESMTPFactory
- else:
- rmType = relaymanager.SmartHostSMTPRelayingManager
- smtpFactory = config.service.getSMTPFactory
-
- if config['relay']:
- dir = config['relay']
- if not os.path.isdir(dir):
- os.mkdir(dir)
-
- config.service.setQueue(relaymanager.Queue(dir))
- default = relay.DomainQueuer(config.service)
-
- manager = rmType(config.service.queue)
- if config['esmtp']:
- manager.fArgs += (None, None)
- manager.fArgs += (config['hostname'],)
-
- helper = relaymanager.RelayStateHelper(manager, 1)
- helper.setServiceParent(config.service)
- config.service.domains.setDefaultDomain(default)
-
- if config['pop3']:
- f = config.service.getPOP3Factory()
- for endpoint in config['pop3']:
- svc = internet.StreamServerEndpointService(endpoint, f)
- svc.setServiceParent(config.service)
-
- if config['smtp']:
- f = smtpFactory()
- if config['hostname']:
- f.domain = config['hostname']
- f.fArgs = (f.domain,)
- if config['esmtp']:
- f.fArgs = (None, None) + f.fArgs
- for endpoint in config['smtp']:
- svc = internet.StreamServerEndpointService(endpoint, f)
- svc.setServiceParent(config.service)
-
- return config.service
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/__init__.py
deleted file mode 100755
index f8ec7056..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"Tests for twistd.mail"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/pop3testserver.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/pop3testserver.py
deleted file mode 100755
index c87892c0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/pop3testserver.py
+++ /dev/null
@@ -1,314 +0,0 @@
-#!/usr/bin/env python
-# -*- test-case-name: twisted.mail.test.test_pop3client -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.internet.protocol import Factory
-from twisted.protocols import basic
-from twisted.internet import reactor
-import sys, time
-
-USER = "test"
-PASS = "twisted"
-
-PORT = 1100
-
-SSL_SUPPORT = True
-UIDL_SUPPORT = True
-INVALID_SERVER_RESPONSE = False
-INVALID_CAPABILITY_RESPONSE = False
-INVALID_LOGIN_RESPONSE = False
-DENY_CONNECTION = False
-DROP_CONNECTION = False
-BAD_TLS_RESPONSE = False
-TIMEOUT_RESPONSE = False
-TIMEOUT_DEFERRED = False
-SLOW_GREETING = False
-
-"""Commands"""
-CONNECTION_MADE = "+OK POP3 localhost v2003.83 server ready"
-
-CAPABILITIES = [
-"TOP",
-"LOGIN-DELAY 180",
-"USER",
-"SASL LOGIN"
-]
-
-CAPABILITIES_SSL = "STLS"
-CAPABILITIES_UIDL = "UIDL"
-
-
-INVALID_RESPONSE = "-ERR Unknown request"
-VALID_RESPONSE = "+OK Command Completed"
-AUTH_DECLINED = "-ERR LOGIN failed"
-AUTH_ACCEPTED = "+OK Mailbox open, 0 messages"
-TLS_ERROR = "-ERR server side error start TLS handshake"
-LOGOUT_COMPLETE = "+OK quit completed"
-NOT_LOGGED_IN = "-ERR Unknown AUHORIZATION state command"
-STAT = "+OK 0 0"
-UIDL = "+OK Unique-ID listing follows\r\n."
-LIST = "+OK Mailbox scan listing follows\r\n."
-CAP_START = "+OK Capability list follows:"
-
-
-class POP3TestServer(basic.LineReceiver):
- def __init__(self, contextFactory = None):
- self.loggedIn = False
- self.caps = None
- self.tmpUser = None
- self.ctx = contextFactory
-
- def sendSTATResp(self, req):
- self.sendLine(STAT)
-
- def sendUIDLResp(self, req):
- self.sendLine(UIDL)
-
- def sendLISTResp(self, req):
- self.sendLine(LIST)
-
- def sendCapabilities(self):
- if self.caps is None:
- self.caps = [CAP_START]
-
- if UIDL_SUPPORT:
- self.caps.append(CAPABILITIES_UIDL)
-
- if SSL_SUPPORT:
- self.caps.append(CAPABILITIES_SSL)
-
- for cap in CAPABILITIES:
- self.caps.append(cap)
- resp = '\r\n'.join(self.caps)
- resp += "\r\n."
-
- self.sendLine(resp)
-
-
- def connectionMade(self):
- if DENY_CONNECTION:
- self.disconnect()
- return
-
- if SLOW_GREETING:
- reactor.callLater(20, self.sendGreeting)
-
- else:
- self.sendGreeting()
-
- def sendGreeting(self):
- self.sendLine(CONNECTION_MADE)
-
- def lineReceived(self, line):
- """Error Conditions"""
-
- uline = line.upper()
- find = lambda s: uline.find(s) != -1
-
- if TIMEOUT_RESPONSE:
- # Do not respond to clients request
- return
-
- if DROP_CONNECTION:
- self.disconnect()
- return
-
- elif find("CAPA"):
- if INVALID_CAPABILITY_RESPONSE:
- self.sendLine(INVALID_RESPONSE)
- else:
- self.sendCapabilities()
-
- elif find("STLS") and SSL_SUPPORT:
- self.startTLS()
-
- elif find("USER"):
- if INVALID_LOGIN_RESPONSE:
- self.sendLine(INVALID_RESPONSE)
- return
-
- resp = None
- try:
- self.tmpUser = line.split(" ")[1]
- resp = VALID_RESPONSE
- except:
- resp = AUTH_DECLINED
-
- self.sendLine(resp)
-
- elif find("PASS"):
- resp = None
- try:
- pwd = line.split(" ")[1]
-
- if self.tmpUser is None or pwd is None:
- resp = AUTH_DECLINED
- elif self.tmpUser == USER and pwd == PASS:
- resp = AUTH_ACCEPTED
- self.loggedIn = True
- else:
- resp = AUTH_DECLINED
- except:
- resp = AUTH_DECLINED
-
- self.sendLine(resp)
-
- elif find("QUIT"):
- self.loggedIn = False
- self.sendLine(LOGOUT_COMPLETE)
- self.disconnect()
-
- elif INVALID_SERVER_RESPONSE:
- self.sendLine(INVALID_RESPONSE)
-
- elif not self.loggedIn:
- self.sendLine(NOT_LOGGED_IN)
-
- elif find("NOOP"):
- self.sendLine(VALID_RESPONSE)
-
- elif find("STAT"):
- if TIMEOUT_DEFERRED:
- return
- self.sendLine(STAT)
-
- elif find("LIST"):
- if TIMEOUT_DEFERRED:
- return
- self.sendLine(LIST)
-
- elif find("UIDL"):
- if TIMEOUT_DEFERRED:
- return
- elif not UIDL_SUPPORT:
- self.sendLine(INVALID_RESPONSE)
- return
-
- self.sendLine(UIDL)
-
- def startTLS(self):
- if self.ctx is None:
- self.getContext()
-
- if SSL_SUPPORT and self.ctx is not None:
- self.sendLine('+OK Begin TLS negotiation now')
- self.transport.startTLS(self.ctx)
- else:
- self.sendLine('-ERR TLS not available')
-
- def disconnect(self):
- self.transport.loseConnection()
-
- def getContext(self):
- try:
- from twisted.internet import ssl
- except ImportError:
- self.ctx = None
- else:
- self.ctx = ssl.ClientContextFactory()
- self.ctx.method = ssl.SSL.TLSv1_METHOD
-
-
-usage = """popServer.py [arg] (default is Standard POP Server with no messages)
-no_ssl - Start with no SSL support
-no_uidl - Start with no UIDL support
-bad_resp - Send a non-RFC compliant response to the Client
-bad_cap_resp - send a non-RFC compliant response when the Client sends a 'CAPABILITY' request
-bad_login_resp - send a non-RFC compliant response when the Client sends a 'LOGIN' request
-deny - Deny the connection
-drop - Drop the connection after sending the greeting
-bad_tls - Send a bad response to a STARTTLS
-timeout - Do not return a response to a Client request
-to_deferred - Do not return a response on a 'Select' request. This
- will test Deferred callback handling
-slow - Wait 20 seconds after the connection is made to return a Server Greeting
-"""
-
-def printMessage(msg):
- print "Server Starting in %s mode" % msg
-
-def processArg(arg):
-
- if arg.lower() == 'no_ssl':
- global SSL_SUPPORT
- SSL_SUPPORT = False
- printMessage("NON-SSL")
-
- elif arg.lower() == 'no_uidl':
- global UIDL_SUPPORT
- UIDL_SUPPORT = False
- printMessage("NON-UIDL")
-
- elif arg.lower() == 'bad_resp':
- global INVALID_SERVER_RESPONSE
- INVALID_SERVER_RESPONSE = True
- printMessage("Invalid Server Response")
-
- elif arg.lower() == 'bad_cap_resp':
- global INVALID_CAPABILITY_RESPONSE
- INVALID_CAPABILITY_RESPONSE = True
- printMessage("Invalid Capability Response")
-
- elif arg.lower() == 'bad_login_resp':
- global INVALID_LOGIN_RESPONSE
- INVALID_LOGIN_RESPONSE = True
- printMessage("Invalid Capability Response")
-
- elif arg.lower() == 'deny':
- global DENY_CONNECTION
- DENY_CONNECTION = True
- printMessage("Deny Connection")
-
- elif arg.lower() == 'drop':
- global DROP_CONNECTION
- DROP_CONNECTION = True
- printMessage("Drop Connection")
-
-
- elif arg.lower() == 'bad_tls':
- global BAD_TLS_RESPONSE
- BAD_TLS_RESPONSE = True
- printMessage("Bad TLS Response")
-
- elif arg.lower() == 'timeout':
- global TIMEOUT_RESPONSE
- TIMEOUT_RESPONSE = True
- printMessage("Timeout Response")
-
- elif arg.lower() == 'to_deferred':
- global TIMEOUT_DEFERRED
- TIMEOUT_DEFERRED = True
- printMessage("Timeout Deferred Response")
-
- elif arg.lower() == 'slow':
- global SLOW_GREETING
- SLOW_GREETING = True
- printMessage("Slow Greeting")
-
- elif arg.lower() == '--help':
- print usage
- sys.exit()
-
- else:
- print usage
- sys.exit()
-
-def main():
-
- if len(sys.argv) < 2:
- printMessage("POP3 with no messages")
- else:
- args = sys.argv[1:]
-
- for arg in args:
- processArg(arg)
-
- f = Factory()
- f.protocol = POP3TestServer
- reactor.listenTCP(PORT, f)
- reactor.run()
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/rfc822.message b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/rfc822.message
deleted file mode 100644
index ee97ab92..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/rfc822.message
+++ /dev/null
@@ -1,86 +0,0 @@
-Return-Path: <twisted-commits-admin@twistedmatrix.com>
-Delivered-To: exarkun@meson.dyndns.org
-Received: from localhost [127.0.0.1]
- by localhost with POP3 (fetchmail-6.2.1)
- for exarkun@localhost (single-drop); Thu, 20 Mar 2003 14:50:20 -0500 (EST)
-Received: from pyramid.twistedmatrix.com (adsl-64-123-27-105.dsl.austtx.swbell.net [64.123.27.105])
- by intarweb.us (Postfix) with ESMTP id 4A4A513EA4
- for <exarkun@meson.dyndns.org>; Thu, 20 Mar 2003 14:49:27 -0500 (EST)
-Received: from localhost ([127.0.0.1] helo=pyramid.twistedmatrix.com)
- by pyramid.twistedmatrix.com with esmtp (Exim 3.35 #1 (Debian))
- id 18w648-0007Vl-00; Thu, 20 Mar 2003 13:51:04 -0600
-Received: from acapnotic by pyramid.twistedmatrix.com with local (Exim 3.35 #1 (Debian))
- id 18w63j-0007VK-00
- for <twisted-commits@twistedmatrix.com>; Thu, 20 Mar 2003 13:50:39 -0600
-To: twisted-commits@twistedmatrix.com
-From: etrepum CVS <etrepum@twistedmatrix.com>
-Reply-To: twisted-python@twistedmatrix.com
-X-Mailer: CVSToys
-Message-Id: <E18w63j-0007VK-00@pyramid.twistedmatrix.com>
-Subject: [Twisted-commits] rebuild now works on python versions from 2.2.0 and up.
-Sender: twisted-commits-admin@twistedmatrix.com
-Errors-To: twisted-commits-admin@twistedmatrix.com
-X-BeenThere: twisted-commits@twistedmatrix.com
-X-Mailman-Version: 2.0.11
-Precedence: bulk
-List-Help: <mailto:twisted-commits-request@twistedmatrix.com?subject=help>
-List-Post: <mailto:twisted-commits@twistedmatrix.com>
-List-Subscribe: <http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits>,
- <mailto:twisted-commits-request@twistedmatrix.com?subject=subscribe>
-List-Id: <twisted-commits.twistedmatrix.com>
-List-Unsubscribe: <http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits>,
- <mailto:twisted-commits-request@twistedmatrix.com?subject=unsubscribe>
-List-Archive: <http://twistedmatrix.com/pipermail/twisted-commits/>
-Date: Thu, 20 Mar 2003 13:50:39 -0600
-
-Modified files:
-Twisted/twisted/python/rebuild.py 1.19 1.20
-
-Log message:
-rebuild now works on python versions from 2.2.0 and up.
-
-
-ViewCVS links:
-http://twistedmatrix.com/users/jh.twistd/viewcvs/cgi/viewcvs.cgi/twisted/python/rebuild.py.diff?r1=text&tr1=1.19&r2=text&tr2=1.20&cvsroot=Twisted
-
-Index: Twisted/twisted/python/rebuild.py
-diff -u Twisted/twisted/python/rebuild.py:1.19 Twisted/twisted/python/rebuild.py:1.20
---- Twisted/twisted/python/rebuild.py:1.19 Fri Jan 17 13:50:49 2003
-+++ Twisted/twisted/python/rebuild.py Thu Mar 20 11:50:08 2003
-@@ -206,15 +206,27 @@
- clazz.__dict__.clear()
- clazz.__getattr__ = __getattr__
- clazz.__module__ = module.__name__
-+ if newclasses:
-+ import gc
-+ if (2, 2, 0) <= sys.version_info[:3] < (2, 2, 2):
-+ hasBrokenRebuild = 1
-+ gc_objects = gc.get_objects()
-+ else:
-+ hasBrokenRebuild = 0
- for nclass in newclasses:
- ga = getattr(module, nclass.__name__)
- if ga is nclass:
- log.msg("WARNING: new-class %s not replaced by reload!" % reflect.qual(nclass))
- else:
-- import gc
-- for r in gc.get_referrers(nclass):
-- if isinstance(r, nclass):
-+ if hasBrokenRebuild:
-+ for r in gc_objects:
-+ if not getattr(r, '__class__', None) is nclass:
-+ continue
- r.__class__ = ga
-+ else:
-+ for r in gc.get_referrers(nclass):
-+ if getattr(r, '__class__', None) is nclass:
-+ r.__class__ = ga
- if doLog:
- log.msg('')
- log.msg(' (fixing %s): ' % str(module.__name__))
-
-
-_______________________________________________
-Twisted-commits mailing list
-Twisted-commits@twistedmatrix.com
-http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/server.pem b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/server.pem
deleted file mode 100644
index 80ef9dcf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDBjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzEL
-MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhv
-c3QxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEB
-BQADSwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
-5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQC
-MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
-MB0GA1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7
-hyNp65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoT
-CE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlw
-dG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3Qx
-LmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6
-BoJuVwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++
-7QGG/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JE
-WUQ9Ho4EzbYCOQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
-5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAQJBAIqm/bz4NA1H++Vx5Ewx
-OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
-ZIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
-nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
-HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNEH+vRWsAYU/gbx+OQB+7VOcBAiEA
-oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE REQUEST-----
-MIIBDTCBuAIBADBTMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQ
-BgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20w
-XDANBgkqhkiG9w0BAQEFAANLADBIAkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5Ad
-NgLzJ1/MfsQQJ7hHVeHmTAjM664V+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABoAAw
-DQYJKoZIhvcNAQEEBQADQQA7uqbrNTjVWpF6By5ZNPvhZ4YdFgkeXFVWi5ao/TaP
-Vq4BG021fJ9nlHRtr4rotpgHDX1rr+iWeHKsx4+5DRSy
------END CERTIFICATE REQUEST-----
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_bounce.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_bounce.py
deleted file mode 100755
index 963d21dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_bounce.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Test cases for bounce message generation
-"""
-
-from twisted.trial import unittest
-from twisted.mail import bounce
-import rfc822, cStringIO
-
-class BounceTestCase(unittest.TestCase):
- """
- testcases for bounce message generation
- """
-
- def testBounceFormat(self):
- from_, to, s = bounce.generateBounce(cStringIO.StringIO('''\
-From: Moshe Zadka <moshez@example.com>
-To: nonexistant@example.org
-Subject: test
-
-'''), 'moshez@example.com', 'nonexistant@example.org')
- self.assertEqual(from_, '')
- self.assertEqual(to, 'moshez@example.com')
- mess = rfc822.Message(cStringIO.StringIO(s))
- self.assertEqual(mess['To'], 'moshez@example.com')
- self.assertEqual(mess['From'], 'postmaster@example.org')
- self.assertEqual(mess['subject'], 'Returned Mail: see transcript for details')
-
- def testBounceMIME(self):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_imap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_imap.py
deleted file mode 100755
index b2461ce1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_imap.py
+++ /dev/null
@@ -1,4829 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_imap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test case for twisted.mail.imap4
-"""
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-import codecs
-import locale
-import os
-import types
-
-from zope.interface import implements
-
-from twisted.mail.imap4 import MessageSet
-from twisted.mail import imap4
-from twisted.protocols import loopback
-from twisted.internet import defer
-from twisted.internet import error
-from twisted.internet import reactor
-from twisted.internet import interfaces
-from twisted.internet.task import Clock
-from twisted.trial import unittest
-from twisted.python import util
-from twisted.python import failure
-
-from twisted import cred
-import twisted.cred.error
-import twisted.cred.checkers
-import twisted.cred.credentials
-import twisted.cred.portal
-
-from twisted.test.proto_helpers import StringTransport, StringTransportWithDisconnection
-
-try:
- from twisted.test.ssl_helpers import ClientTLSContext, ServerTLSContext
-except ImportError:
- ClientTLSContext = ServerTLSContext = None
-
-def strip(f):
- return lambda result, f=f: f()
-
-def sortNest(l):
- l = l[:]
- l.sort()
- for i in range(len(l)):
- if isinstance(l[i], types.ListType):
- l[i] = sortNest(l[i])
- elif isinstance(l[i], types.TupleType):
- l[i] = tuple(sortNest(list(l[i])))
- return l
-
-class IMAP4UTF7TestCase(unittest.TestCase):
- tests = [
- [u'Hello world', 'Hello world'],
- [u'Hello & world', 'Hello &- world'],
- [u'Hello\xffworld', 'Hello&AP8-world'],
- [u'\xff\xfe\xfd\xfc', '&AP8A,gD9APw-'],
- [u'~peter/mail/\u65e5\u672c\u8a9e/\u53f0\u5317',
- '~peter/mail/&ZeVnLIqe-/&U,BTFw-'], # example from RFC 2060
- ]
-
- def test_encodeWithErrors(self):
- """
- Specifying an error policy to C{unicode.encode} with the
- I{imap4-utf-7} codec should produce the same result as not
- specifying the error policy.
- """
- text = u'Hello world'
- self.assertEqual(
- text.encode('imap4-utf-7', 'strict'),
- text.encode('imap4-utf-7'))
-
-
- def test_decodeWithErrors(self):
- """
- Similar to L{test_encodeWithErrors}, but for C{str.decode}.
- """
- bytes = 'Hello world'
- self.assertEqual(
- bytes.decode('imap4-utf-7', 'strict'),
- bytes.decode('imap4-utf-7'))
-
-
- def test_getreader(self):
- """
- C{codecs.getreader('imap4-utf-7')} returns the I{imap4-utf-7} stream
- reader class.
- """
- reader = codecs.getreader('imap4-utf-7')(StringIO('Hello&AP8-world'))
- self.assertEqual(reader.read(), u'Hello\xffworld')
-
-
- def test_getwriter(self):
- """
- C{codecs.getwriter('imap4-utf-7')} returns the I{imap4-utf-7} stream
- writer class.
- """
- output = StringIO()
- writer = codecs.getwriter('imap4-utf-7')(output)
- writer.write(u'Hello\xffworld')
- self.assertEqual(output.getvalue(), 'Hello&AP8-world')
-
-
- def test_encode(self):
- """
- The I{imap4-utf-7} can be used to encode a unicode string into a byte
- string according to the IMAP4 modified UTF-7 encoding rules.
- """
- for (input, output) in self.tests:
- self.assertEqual(input.encode('imap4-utf-7'), output)
-
-
- def test_decode(self):
- """
- The I{imap4-utf-7} can be used to decode a byte string into a unicode
- string according to the IMAP4 modified UTF-7 encoding rules.
- """
- for (input, output) in self.tests:
- self.assertEqual(input, output.decode('imap4-utf-7'))
-
-
- def test_printableSingletons(self):
- """
- The IMAP4 modified UTF-7 implementation encodes all printable
- characters which are in ASCII using the corresponding ASCII byte.
- """
- # All printables represent themselves
- for o in range(0x20, 0x26) + range(0x27, 0x7f):
- self.assertEqual(chr(o), chr(o).encode('imap4-utf-7'))
- self.assertEqual(chr(o), chr(o).decode('imap4-utf-7'))
- self.assertEqual('&'.encode('imap4-utf-7'), '&-')
- self.assertEqual('&-'.decode('imap4-utf-7'), '&')
-
-
-
-class BufferingConsumer:
- def __init__(self):
- self.buffer = []
-
- def write(self, bytes):
- self.buffer.append(bytes)
- if self.consumer:
- self.consumer.resumeProducing()
-
- def registerProducer(self, consumer, streaming):
- self.consumer = consumer
- self.consumer.resumeProducing()
-
- def unregisterProducer(self):
- self.consumer = None
-
-class MessageProducerTestCase(unittest.TestCase):
- def testSinglePart(self):
- body = 'This is body text. Rar.'
- headers = util.OrderedDict()
- headers['from'] = 'sender@host'
- headers['to'] = 'recipient@domain'
- headers['subject'] = 'booga booga boo'
- headers['content-type'] = 'text/plain'
-
- msg = FakeyMessage(headers, (), None, body, 123, None )
-
- c = BufferingConsumer()
- p = imap4.MessageProducer(msg)
- d = p.beginProducing(c)
-
- def cbProduced(result):
- self.assertIdentical(result, p)
- self.assertEqual(
- ''.join(c.buffer),
-
- '{119}\r\n'
- 'From: sender@host\r\n'
- 'To: recipient@domain\r\n'
- 'Subject: booga booga boo\r\n'
- 'Content-Type: text/plain\r\n'
- '\r\n'
- + body)
- return d.addCallback(cbProduced)
-
-
- def testSingleMultiPart(self):
- outerBody = ''
- innerBody = 'Contained body message text. Squarge.'
- headers = util.OrderedDict()
- headers['from'] = 'sender@host'
- headers['to'] = 'recipient@domain'
- headers['subject'] = 'booga booga boo'
- headers['content-type'] = 'multipart/alternative; boundary="xyz"'
-
- innerHeaders = util.OrderedDict()
- innerHeaders['subject'] = 'this is subject text'
- innerHeaders['content-type'] = 'text/plain'
- msg = FakeyMessage(headers, (), None, outerBody, 123,
- [FakeyMessage(innerHeaders, (), None, innerBody,
- None, None)],
- )
-
- c = BufferingConsumer()
- p = imap4.MessageProducer(msg)
- d = p.beginProducing(c)
-
- def cbProduced(result):
- self.failUnlessIdentical(result, p)
-
- self.assertEqual(
- ''.join(c.buffer),
-
- '{239}\r\n'
- 'From: sender@host\r\n'
- 'To: recipient@domain\r\n'
- 'Subject: booga booga boo\r\n'
- 'Content-Type: multipart/alternative; boundary="xyz"\r\n'
- '\r\n'
- '\r\n'
- '--xyz\r\n'
- 'Subject: this is subject text\r\n'
- 'Content-Type: text/plain\r\n'
- '\r\n'
- + innerBody
- + '\r\n--xyz--\r\n')
-
- return d.addCallback(cbProduced)
-
-
- def testMultipleMultiPart(self):
- outerBody = ''
- innerBody1 = 'Contained body message text. Squarge.'
- innerBody2 = 'Secondary <i>message</i> text of squarge body.'
- headers = util.OrderedDict()
- headers['from'] = 'sender@host'
- headers['to'] = 'recipient@domain'
- headers['subject'] = 'booga booga boo'
- headers['content-type'] = 'multipart/alternative; boundary="xyz"'
- innerHeaders = util.OrderedDict()
- innerHeaders['subject'] = 'this is subject text'
- innerHeaders['content-type'] = 'text/plain'
- innerHeaders2 = util.OrderedDict()
- innerHeaders2['subject'] = '<b>this is subject</b>'
- innerHeaders2['content-type'] = 'text/html'
- msg = FakeyMessage(headers, (), None, outerBody, 123, [
- FakeyMessage(innerHeaders, (), None, innerBody1, None, None),
- FakeyMessage(innerHeaders2, (), None, innerBody2, None, None)
- ],
- )
-
- c = BufferingConsumer()
- p = imap4.MessageProducer(msg)
- d = p.beginProducing(c)
-
- def cbProduced(result):
- self.failUnlessIdentical(result, p)
-
- self.assertEqual(
- ''.join(c.buffer),
-
- '{354}\r\n'
- 'From: sender@host\r\n'
- 'To: recipient@domain\r\n'
- 'Subject: booga booga boo\r\n'
- 'Content-Type: multipart/alternative; boundary="xyz"\r\n'
- '\r\n'
- '\r\n'
- '--xyz\r\n'
- 'Subject: this is subject text\r\n'
- 'Content-Type: text/plain\r\n'
- '\r\n'
- + innerBody1
- + '\r\n--xyz\r\n'
- 'Subject: <b>this is subject</b>\r\n'
- 'Content-Type: text/html\r\n'
- '\r\n'
- + innerBody2
- + '\r\n--xyz--\r\n')
- return d.addCallback(cbProduced)
-
-
-
-class IMAP4HelperTestCase(unittest.TestCase):
- """
- Tests for various helper utilities in the IMAP4 module.
- """
-
- def test_fileProducer(self):
- b = (('x' * 1) + ('y' * 1) + ('z' * 1)) * 10
- c = BufferingConsumer()
- f = StringIO(b)
- p = imap4.FileProducer(f)
- d = p.beginProducing(c)
-
- def cbProduced(result):
- self.failUnlessIdentical(result, p)
- self.assertEqual(
- ('{%d}\r\n' % len(b))+ b,
- ''.join(c.buffer))
- return d.addCallback(cbProduced)
-
-
- def test_wildcard(self):
- cases = [
- ['foo/%gum/bar',
- ['foo/bar', 'oo/lalagum/bar', 'foo/gumx/bar', 'foo/gum/baz'],
- ['foo/xgum/bar', 'foo/gum/bar'],
- ], ['foo/x%x/bar',
- ['foo', 'bar', 'fuz fuz fuz', 'foo/*/bar', 'foo/xyz/bar', 'foo/xx/baz'],
- ['foo/xyx/bar', 'foo/xx/bar', 'foo/xxxxxxxxxxxxxx/bar'],
- ], ['foo/xyz*abc/bar',
- ['foo/xyz/bar', 'foo/abc/bar', 'foo/xyzab/cbar', 'foo/xyza/bcbar'],
- ['foo/xyzabc/bar', 'foo/xyz/abc/bar', 'foo/xyz/123/abc/bar'],
- ]
- ]
-
- for (wildcard, fail, succeed) in cases:
- wildcard = imap4.wildcardToRegexp(wildcard, '/')
- for x in fail:
- self.failIf(wildcard.match(x))
- for x in succeed:
- self.failUnless(wildcard.match(x))
-
-
- def test_wildcardNoDelim(self):
- cases = [
- ['foo/%gum/bar',
- ['foo/bar', 'oo/lalagum/bar', 'foo/gumx/bar', 'foo/gum/baz'],
- ['foo/xgum/bar', 'foo/gum/bar', 'foo/x/gum/bar'],
- ], ['foo/x%x/bar',
- ['foo', 'bar', 'fuz fuz fuz', 'foo/*/bar', 'foo/xyz/bar', 'foo/xx/baz'],
- ['foo/xyx/bar', 'foo/xx/bar', 'foo/xxxxxxxxxxxxxx/bar', 'foo/x/x/bar'],
- ], ['foo/xyz*abc/bar',
- ['foo/xyz/bar', 'foo/abc/bar', 'foo/xyzab/cbar', 'foo/xyza/bcbar'],
- ['foo/xyzabc/bar', 'foo/xyz/abc/bar', 'foo/xyz/123/abc/bar'],
- ]
- ]
-
- for (wildcard, fail, succeed) in cases:
- wildcard = imap4.wildcardToRegexp(wildcard, None)
- for x in fail:
- self.failIf(wildcard.match(x), x)
- for x in succeed:
- self.failUnless(wildcard.match(x), x)
-
-
- def test_headerFormatter(self):
- """
- L{imap4._formatHeaders} accepts a C{dict} of header name/value pairs and
- returns a string representing those headers in the standard multiline,
- C{":"}-separated format.
- """
- cases = [
- ({'Header1': 'Value1', 'Header2': 'Value2'}, 'Header2: Value2\r\nHeader1: Value1\r\n'),
- ]
-
- for (input, expected) in cases:
- output = imap4._formatHeaders(input)
- self.assertEqual(sorted(output.splitlines(True)),
- sorted(expected.splitlines(True)))
-
-
- def test_messageSet(self):
- m1 = MessageSet()
- m2 = MessageSet()
-
- self.assertEqual(m1, m2)
-
- m1 = m1 + (1, 3)
- self.assertEqual(len(m1), 3)
- self.assertEqual(list(m1), [1, 2, 3])
-
- m2 = m2 + (1, 3)
- self.assertEqual(m1, m2)
- self.assertEqual(list(m1 + m2), [1, 2, 3])
-
-
- def test_messageSetStringRepresentationWithWildcards(self):
- """
- In a L{MessageSet}, in the presence of wildcards, if the highest message
- id is known, the wildcard should get replaced by that high value.
- """
- inputs = [
- MessageSet(imap4.parseIdList('*')),
- MessageSet(imap4.parseIdList('3:*', 6)),
- MessageSet(imap4.parseIdList('*:2', 6)),
- ]
-
- outputs = [
- "*",
- "3:6",
- "2:6",
- ]
-
- for i, o in zip(inputs, outputs):
- self.assertEqual(str(i), o)
-
-
- def test_messageSetStringRepresentationWithInversion(self):
- """
- In a L{MessageSet}, inverting the high and low numbers in a range
- doesn't affect the meaning of the range. For example, 3:2 displays just
- like 2:3, because according to the RFC they have the same meaning.
- """
- inputs = [
- MessageSet(imap4.parseIdList('2:3')),
- MessageSet(imap4.parseIdList('3:2')),
- ]
-
- outputs = [
- "2:3",
- "2:3",
- ]
-
- for i, o in zip(inputs, outputs):
- self.assertEqual(str(i), o)
-
-
- def test_quotedSplitter(self):
- cases = [
- '''Hello World''',
- '''Hello "World!"''',
- '''World "Hello" "How are you?"''',
- '''"Hello world" How "are you?"''',
- '''foo bar "baz buz" NIL''',
- '''foo bar "baz buz" "NIL"''',
- '''foo NIL "baz buz" bar''',
- '''foo "NIL" "baz buz" bar''',
- '''"NIL" bar "baz buz" foo''',
- 'oo \\"oo\\" oo',
- '"oo \\"oo\\" oo"',
- 'oo \t oo',
- '"oo \t oo"',
- 'oo \\t oo',
- '"oo \\t oo"',
- 'oo \o oo',
- '"oo \o oo"',
- 'oo \\o oo',
- '"oo \\o oo"',
- ]
-
- answers = [
- ['Hello', 'World'],
- ['Hello', 'World!'],
- ['World', 'Hello', 'How are you?'],
- ['Hello world', 'How', 'are you?'],
- ['foo', 'bar', 'baz buz', None],
- ['foo', 'bar', 'baz buz', 'NIL'],
- ['foo', None, 'baz buz', 'bar'],
- ['foo', 'NIL', 'baz buz', 'bar'],
- ['NIL', 'bar', 'baz buz', 'foo'],
- ['oo', '"oo"', 'oo'],
- ['oo "oo" oo'],
- ['oo', 'oo'],
- ['oo \t oo'],
- ['oo', '\\t', 'oo'],
- ['oo \\t oo'],
- ['oo', '\o', 'oo'],
- ['oo \o oo'],
- ['oo', '\\o', 'oo'],
- ['oo \\o oo'],
-
- ]
-
- errors = [
- '"mismatched quote',
- 'mismatched quote"',
- 'mismatched"quote',
- '"oops here is" another"',
- ]
-
- for s in errors:
- self.assertRaises(imap4.MismatchedQuoting, imap4.splitQuoted, s)
-
- for (case, expected) in zip(cases, answers):
- self.assertEqual(imap4.splitQuoted(case), expected)
-
-
- def test_stringCollapser(self):
- cases = [
- ['a', 'b', 'c', 'd', 'e'],
- ['a', ' ', '"', 'b', 'c', ' ', '"', ' ', 'd', 'e'],
- [['a', 'b', 'c'], 'd', 'e'],
- ['a', ['b', 'c', 'd'], 'e'],
- ['a', 'b', ['c', 'd', 'e']],
- ['"', 'a', ' ', '"', ['b', 'c', 'd'], '"', ' ', 'e', '"'],
- ['a', ['"', ' ', 'b', 'c', ' ', ' ', '"'], 'd', 'e'],
- ]
-
- answers = [
- ['abcde'],
- ['a', 'bc ', 'de'],
- [['abc'], 'de'],
- ['a', ['bcd'], 'e'],
- ['ab', ['cde']],
- ['a ', ['bcd'], ' e'],
- ['a', [' bc '], 'de'],
- ]
-
- for (case, expected) in zip(cases, answers):
- self.assertEqual(imap4.collapseStrings(case), expected)
-
-
- def test_parenParser(self):
- s = '\r\n'.join(['xx'] * 4)
- cases = [
- '(BODY.PEEK[HEADER.FIELDS.NOT (subject bcc cc)] {%d}\r\n%s)' % (len(s), s,),
-
-# '(FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700" '
-# 'RFC822.SIZE 4286 ENVELOPE ("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)" '
-# '"IMAP4rev1 WG mtg summary and minutes" '
-# '(("Terry Gray" NIL "gray" "cac.washington.edu")) '
-# '(("Terry Gray" NIL "gray" "cac.washington.edu")) '
-# '(("Terry Gray" NIL "gray" "cac.washington.edu")) '
-# '((NIL NIL "imap" "cac.washington.edu")) '
-# '((NIL NIL "minutes" "CNRI.Reston.VA.US") '
-# '("John Klensin" NIL "KLENSIN" "INFOODS.MIT.EDU")) NIL NIL '
-# '"<B27397-0100000@cac.washington.edu>") '
-# 'BODY ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 3028 92))',
-
- '(FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700" '
- 'RFC822.SIZE 4286 ENVELOPE ("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)" '
- '"IMAP4rev1 WG mtg summary and minutes" '
- '(("Terry Gray" NIL gray cac.washington.edu)) '
- '(("Terry Gray" NIL gray cac.washington.edu)) '
- '(("Terry Gray" NIL gray cac.washington.edu)) '
- '((NIL NIL imap cac.washington.edu)) '
- '((NIL NIL minutes CNRI.Reston.VA.US) '
- '("John Klensin" NIL KLENSIN INFOODS.MIT.EDU)) NIL NIL '
- '<B27397-0100000@cac.washington.edu>) '
- 'BODY (TEXT PLAIN (CHARSET US-ASCII) NIL NIL 7BIT 3028 92))',
- '("oo \\"oo\\" oo")',
- '("oo \\\\ oo")',
- '("oo \\ oo")',
- '("oo \\o")',
- '("oo \o")',
- '(oo \o)',
- '(oo \\o)',
-
- ]
-
- answers = [
- ['BODY.PEEK', ['HEADER.FIELDS.NOT', ['subject', 'bcc', 'cc']], s],
-
- ['FLAGS', [r'\Seen'], 'INTERNALDATE',
- '17-Jul-1996 02:44:25 -0700', 'RFC822.SIZE', '4286', 'ENVELOPE',
- ['Wed, 17 Jul 1996 02:23:25 -0700 (PDT)',
- 'IMAP4rev1 WG mtg summary and minutes', [["Terry Gray", None,
- "gray", "cac.washington.edu"]], [["Terry Gray", None,
- "gray", "cac.washington.edu"]], [["Terry Gray", None,
- "gray", "cac.washington.edu"]], [[None, None, "imap",
- "cac.washington.edu"]], [[None, None, "minutes",
- "CNRI.Reston.VA.US"], ["John Klensin", None, "KLENSIN",
- "INFOODS.MIT.EDU"]], None, None,
- "<B27397-0100000@cac.washington.edu>"], "BODY", ["TEXT", "PLAIN",
- ["CHARSET", "US-ASCII"], None, None, "7BIT", "3028", "92"]],
- ['oo "oo" oo'],
- ['oo \\\\ oo'],
- ['oo \\ oo'],
- ['oo \\o'],
- ['oo \o'],
- ['oo', '\o'],
- ['oo', '\\o'],
- ]
-
- for (case, expected) in zip(cases, answers):
- self.assertEqual(imap4.parseNestedParens(case), [expected])
-
- # XXX This code used to work, but changes occurred within the
- # imap4.py module which made it no longer necessary for *all* of it
- # to work. In particular, only the part that makes
- # 'BODY.PEEK[HEADER.FIELDS.NOT (Subject Bcc Cc)]' come out correctly
- # no longer needs to work. So, I am loathe to delete the entire
- # section of the test. --exarkun
- #
-
-# for (case, expected) in zip(answers, cases):
-# self.assertEqual('(' + imap4.collapseNestedLists(case) + ')', expected)
-
-
- def test_fetchParserSimple(self):
- cases = [
- ['ENVELOPE', 'Envelope'],
- ['FLAGS', 'Flags'],
- ['INTERNALDATE', 'InternalDate'],
- ['RFC822.HEADER', 'RFC822Header'],
- ['RFC822.SIZE', 'RFC822Size'],
- ['RFC822.TEXT', 'RFC822Text'],
- ['RFC822', 'RFC822'],
- ['UID', 'UID'],
- ['BODYSTRUCTURE', 'BodyStructure'],
- ]
-
- for (inp, outp) in cases:
- p = imap4._FetchParser()
- p.parseString(inp)
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], getattr(p, outp)))
-
-
- def test_fetchParserMacros(self):
- cases = [
- ['ALL', (4, ['flags', 'internaldate', 'rfc822.size', 'envelope'])],
- ['FULL', (5, ['flags', 'internaldate', 'rfc822.size', 'envelope', 'body'])],
- ['FAST', (3, ['flags', 'internaldate', 'rfc822.size'])],
- ]
-
- for (inp, outp) in cases:
- p = imap4._FetchParser()
- p.parseString(inp)
- self.assertEqual(len(p.result), outp[0])
- p = [str(p).lower() for p in p.result]
- p.sort()
- outp[1].sort()
- self.assertEqual(p, outp[1])
-
-
- def test_fetchParserBody(self):
- P = imap4._FetchParser
-
- p = P()
- p.parseString('BODY')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, False)
- self.assertEqual(p.result[0].header, None)
- self.assertEqual(str(p.result[0]), 'BODY')
-
- p = P()
- p.parseString('BODY.PEEK')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, True)
- self.assertEqual(str(p.result[0]), 'BODY')
-
- p = P()
- p.parseString('BODY[]')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].empty, True)
- self.assertEqual(str(p.result[0]), 'BODY[]')
-
- p = P()
- p.parseString('BODY[HEADER]')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, False)
- self.failUnless(isinstance(p.result[0].header, p.Header))
- self.assertEqual(p.result[0].header.negate, True)
- self.assertEqual(p.result[0].header.fields, ())
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[HEADER]')
-
- p = P()
- p.parseString('BODY.PEEK[HEADER]')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, True)
- self.failUnless(isinstance(p.result[0].header, p.Header))
- self.assertEqual(p.result[0].header.negate, True)
- self.assertEqual(p.result[0].header.fields, ())
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[HEADER]')
-
- p = P()
- p.parseString('BODY[HEADER.FIELDS (Subject Cc Message-Id)]')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, False)
- self.failUnless(isinstance(p.result[0].header, p.Header))
- self.assertEqual(p.result[0].header.negate, False)
- self.assertEqual(p.result[0].header.fields, ['SUBJECT', 'CC', 'MESSAGE-ID'])
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[HEADER.FIELDS (Subject Cc Message-Id)]')
-
- p = P()
- p.parseString('BODY.PEEK[HEADER.FIELDS (Subject Cc Message-Id)]')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, True)
- self.failUnless(isinstance(p.result[0].header, p.Header))
- self.assertEqual(p.result[0].header.negate, False)
- self.assertEqual(p.result[0].header.fields, ['SUBJECT', 'CC', 'MESSAGE-ID'])
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[HEADER.FIELDS (Subject Cc Message-Id)]')
-
- p = P()
- p.parseString('BODY.PEEK[HEADER.FIELDS.NOT (Subject Cc Message-Id)]')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, True)
- self.failUnless(isinstance(p.result[0].header, p.Header))
- self.assertEqual(p.result[0].header.negate, True)
- self.assertEqual(p.result[0].header.fields, ['SUBJECT', 'CC', 'MESSAGE-ID'])
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[HEADER.FIELDS.NOT (Subject Cc Message-Id)]')
-
- p = P()
- p.parseString('BODY[1.MIME]<10.50>')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, False)
- self.failUnless(isinstance(p.result[0].mime, p.MIME))
- self.assertEqual(p.result[0].part, (0,))
- self.assertEqual(p.result[0].partialBegin, 10)
- self.assertEqual(p.result[0].partialLength, 50)
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[1.MIME]<10.50>')
-
- p = P()
- p.parseString('BODY.PEEK[1.3.9.11.HEADER.FIELDS.NOT (Message-Id Date)]<103.69>')
- self.assertEqual(len(p.result), 1)
- self.failUnless(isinstance(p.result[0], p.Body))
- self.assertEqual(p.result[0].peek, True)
- self.failUnless(isinstance(p.result[0].header, p.Header))
- self.assertEqual(p.result[0].part, (0, 2, 8, 10))
- self.assertEqual(p.result[0].header.fields, ['MESSAGE-ID', 'DATE'])
- self.assertEqual(p.result[0].partialBegin, 103)
- self.assertEqual(p.result[0].partialLength, 69)
- self.assertEqual(p.result[0].empty, False)
- self.assertEqual(str(p.result[0]), 'BODY[1.3.9.11.HEADER.FIELDS.NOT (Message-Id Date)]<103.69>')
-
-
- def test_files(self):
- inputStructure = [
- 'foo', 'bar', 'baz', StringIO('this is a file\r\n'), 'buz'
- ]
-
- output = '"foo" "bar" "baz" {16}\r\nthis is a file\r\n "buz"'
-
- self.assertEqual(imap4.collapseNestedLists(inputStructure), output)
-
-
- def test_quoteAvoider(self):
- input = [
- 'foo', imap4.DontQuoteMe('bar'), "baz", StringIO('this is a file\r\n'),
- imap4.DontQuoteMe('buz'), ""
- ]
-
- output = '"foo" bar "baz" {16}\r\nthis is a file\r\n buz ""'
-
- self.assertEqual(imap4.collapseNestedLists(input), output)
-
-
- def test_literals(self):
- cases = [
- ('({10}\r\n0123456789)', [['0123456789']]),
- ]
-
- for (case, expected) in cases:
- self.assertEqual(imap4.parseNestedParens(case), expected)
-
-
- def test_queryBuilder(self):
- inputs = [
- imap4.Query(flagged=1),
- imap4.Query(sorted=1, unflagged=1, deleted=1),
- imap4.Or(imap4.Query(flagged=1), imap4.Query(deleted=1)),
- imap4.Query(before='today'),
- imap4.Or(
- imap4.Query(deleted=1),
- imap4.Query(unseen=1),
- imap4.Query(new=1)
- ),
- imap4.Or(
- imap4.Not(
- imap4.Or(
- imap4.Query(sorted=1, since='yesterday', smaller=1000),
- imap4.Query(sorted=1, before='tuesday', larger=10000),
- imap4.Query(sorted=1, unseen=1, deleted=1, before='today'),
- imap4.Not(
- imap4.Query(subject='spam')
- ),
- ),
- ),
- imap4.Not(
- imap4.Query(uid='1:5')
- ),
- )
- ]
-
- outputs = [
- 'FLAGGED',
- '(DELETED UNFLAGGED)',
- '(OR FLAGGED DELETED)',
- '(BEFORE "today")',
- '(OR DELETED (OR UNSEEN NEW))',
- '(OR (NOT (OR (SINCE "yesterday" SMALLER 1000) ' # Continuing
- '(OR (BEFORE "tuesday" LARGER 10000) (OR (BEFORE ' # Some more
- '"today" DELETED UNSEEN) (NOT (SUBJECT "spam")))))) ' # And more
- '(NOT (UID 1:5)))',
- ]
-
- for (query, expected) in zip(inputs, outputs):
- self.assertEqual(query, expected)
-
-
- def test_invalidIdListParser(self):
- """
- Trying to parse an invalid representation of a sequence range raises an
- L{IllegalIdentifierError}.
- """
- inputs = [
- '*:*',
- 'foo',
- '4:',
- 'bar:5'
- ]
-
- for input in inputs:
- self.assertRaises(imap4.IllegalIdentifierError,
- imap4.parseIdList, input, 12345)
-
-
- def test_invalidIdListParserNonPositive(self):
- """
- Zeroes and negative values are not accepted in id range expressions. RFC
- 3501 states that sequence numbers and sequence ranges consist of
- non-negative numbers (RFC 3501 section 9, the seq-number grammar item).
- """
- inputs = [
- '0:5',
- '0:0',
- '*:0',
- '0',
- '-3:5',
- '1:-2',
- '-1'
- ]
-
- for input in inputs:
- self.assertRaises(imap4.IllegalIdentifierError,
- imap4.parseIdList, input, 12345)
-
-
- def test_parseIdList(self):
- """
- The function to parse sequence ranges yields appropriate L{MessageSet}
- objects.
- """
- inputs = [
- '1:*',
- '5:*',
- '1:2,5:*',
- '*',
- '1',
- '1,2',
- '1,3,5',
- '1:10',
- '1:10,11',
- '1:5,10:20',
- '1,5:10',
- '1,5:10,15:20',
- '1:10,15,20:25',
- '4:2'
- ]
-
- outputs = [
- MessageSet(1, None),
- MessageSet(5, None),
- MessageSet(5, None) + MessageSet(1, 2),
- MessageSet(None, None),
- MessageSet(1),
- MessageSet(1, 2),
- MessageSet(1) + MessageSet(3) + MessageSet(5),
- MessageSet(1, 10),
- MessageSet(1, 11),
- MessageSet(1, 5) + MessageSet(10, 20),
- MessageSet(1) + MessageSet(5, 10),
- MessageSet(1) + MessageSet(5, 10) + MessageSet(15, 20),
- MessageSet(1, 10) + MessageSet(15) + MessageSet(20, 25),
- MessageSet(2, 4),
- ]
-
- lengths = [
- None, None, None,
- 1, 1, 2, 3, 10, 11, 16, 7, 13, 17, 3
- ]
-
- for (input, expected) in zip(inputs, outputs):
- self.assertEqual(imap4.parseIdList(input), expected)
-
- for (input, expected) in zip(inputs, lengths):
- if expected is None:
- self.assertRaises(TypeError, len, imap4.parseIdList(input))
- else:
- L = len(imap4.parseIdList(input))
- self.assertEqual(L, expected,
- "len(%r) = %r != %r" % (input, L, expected))
-
-class SimpleMailbox:
- implements(imap4.IMailboxInfo, imap4.IMailbox, imap4.ICloseableMailbox)
-
- flags = ('\\Flag1', 'Flag2', '\\AnotherSysFlag', 'LastFlag')
- messages = []
- mUID = 0
- rw = 1
- closed = False
-
- def __init__(self):
- self.listeners = []
- self.addListener = self.listeners.append
- self.removeListener = self.listeners.remove
-
- def getFlags(self):
- return self.flags
-
- def getUIDValidity(self):
- return 42
-
- def getUIDNext(self):
- return len(self.messages) + 1
-
- def getMessageCount(self):
- return 9
-
- def getRecentCount(self):
- return 3
-
- def getUnseenCount(self):
- return 4
-
- def isWriteable(self):
- return self.rw
-
- def destroy(self):
- pass
-
- def getHierarchicalDelimiter(self):
- return '/'
-
- def requestStatus(self, names):
- r = {}
- if 'MESSAGES' in names:
- r['MESSAGES'] = self.getMessageCount()
- if 'RECENT' in names:
- r['RECENT'] = self.getRecentCount()
- if 'UIDNEXT' in names:
- r['UIDNEXT'] = self.getMessageCount() + 1
- if 'UIDVALIDITY' in names:
- r['UIDVALIDITY'] = self.getUID()
- if 'UNSEEN' in names:
- r['UNSEEN'] = self.getUnseenCount()
- return defer.succeed(r)
-
- def addMessage(self, message, flags, date = None):
- self.messages.append((message, flags, date, self.mUID))
- self.mUID += 1
- return defer.succeed(None)
-
- def expunge(self):
- delete = []
- for i in self.messages:
- if '\\Deleted' in i[1]:
- delete.append(i)
- for i in delete:
- self.messages.remove(i)
- return [i[3] for i in delete]
-
- def close(self):
- self.closed = True
-
-class Account(imap4.MemoryAccount):
- mailboxFactory = SimpleMailbox
- def _emptyMailbox(self, name, id):
- return self.mailboxFactory()
-
- def select(self, name, rw=1):
- mbox = imap4.MemoryAccount.select(self, name)
- if mbox is not None:
- mbox.rw = rw
- return mbox
-
-class SimpleServer(imap4.IMAP4Server):
- def __init__(self, *args, **kw):
- imap4.IMAP4Server.__init__(self, *args, **kw)
- realm = TestRealm()
- realm.theAccount = Account('testuser')
- portal = cred.portal.Portal(realm)
- c = cred.checkers.InMemoryUsernamePasswordDatabaseDontUse()
- self.checker = c
- self.portal = portal
- portal.registerChecker(c)
- self.timeoutTest = False
-
- def lineReceived(self, line):
- if self.timeoutTest:
- #Do not send a respones
- return
-
- imap4.IMAP4Server.lineReceived(self, line)
-
- _username = 'testuser'
- _password = 'password-test'
- def authenticateLogin(self, username, password):
- if username == self._username and password == self._password:
- return imap4.IAccount, self.theAccount, lambda: None
- raise cred.error.UnauthorizedLogin()
-
-
-class SimpleClient(imap4.IMAP4Client):
- def __init__(self, deferred, contextFactory = None):
- imap4.IMAP4Client.__init__(self, contextFactory)
- self.deferred = deferred
- self.events = []
-
- def serverGreeting(self, caps):
- self.deferred.callback(None)
-
- def modeChanged(self, writeable):
- self.events.append(['modeChanged', writeable])
- self.transport.loseConnection()
-
- def flagsChanged(self, newFlags):
- self.events.append(['flagsChanged', newFlags])
- self.transport.loseConnection()
-
- def newMessages(self, exists, recent):
- self.events.append(['newMessages', exists, recent])
- self.transport.loseConnection()
-
-
-
-class IMAP4HelperMixin:
-
- serverCTX = None
- clientCTX = None
-
- def setUp(self):
- d = defer.Deferred()
- self.server = SimpleServer(contextFactory=self.serverCTX)
- self.client = SimpleClient(d, contextFactory=self.clientCTX)
- self.connected = d
-
- SimpleMailbox.messages = []
- theAccount = Account('testuser')
- theAccount.mboxType = SimpleMailbox
- SimpleServer.theAccount = theAccount
-
- def tearDown(self):
- del self.server
- del self.client
- del self.connected
-
- def _cbStopClient(self, ignore):
- self.client.transport.loseConnection()
-
- def _ebGeneral(self, failure):
- self.client.transport.loseConnection()
- self.server.transport.loseConnection()
- failure.raiseException()
-
- def loopback(self):
- return loopback.loopbackAsync(self.server, self.client)
-
-class IMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
- def testCapability(self):
- caps = {}
- def getCaps():
- def gotCaps(c):
- caps.update(c)
- self.server.transport.loseConnection()
- return self.client.getCapabilities().addCallback(gotCaps)
- d1 = self.connected.addCallback(strip(getCaps)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- expected = {'IMAP4rev1': None, 'NAMESPACE': None, 'IDLE': None}
- return d.addCallback(lambda _: self.assertEqual(expected, caps))
-
- def testCapabilityWithAuth(self):
- caps = {}
- self.server.challengers['CRAM-MD5'] = cred.credentials.CramMD5Credentials
- def getCaps():
- def gotCaps(c):
- caps.update(c)
- self.server.transport.loseConnection()
- return self.client.getCapabilities().addCallback(gotCaps)
- d1 = self.connected.addCallback(strip(getCaps)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
-
- expCap = {'IMAP4rev1': None, 'NAMESPACE': None,
- 'IDLE': None, 'AUTH': ['CRAM-MD5']}
-
- return d.addCallback(lambda _: self.assertEqual(expCap, caps))
-
- def testLogout(self):
- self.loggedOut = 0
- def logout():
- def setLoggedOut():
- self.loggedOut = 1
- self.client.logout().addCallback(strip(setLoggedOut))
- self.connected.addCallback(strip(logout)).addErrback(self._ebGeneral)
- d = self.loopback()
- return d.addCallback(lambda _: self.assertEqual(self.loggedOut, 1))
-
- def testNoop(self):
- self.responses = None
- def noop():
- def setResponses(responses):
- self.responses = responses
- self.server.transport.loseConnection()
- self.client.noop().addCallback(setResponses)
- self.connected.addCallback(strip(noop)).addErrback(self._ebGeneral)
- d = self.loopback()
- return d.addCallback(lambda _: self.assertEqual(self.responses, []))
-
- def testLogin(self):
- def login():
- d = self.client.login('testuser', 'password-test')
- d.addCallback(self._cbStopClient)
- d1 = self.connected.addCallback(strip(login)).addErrback(self._ebGeneral)
- d = defer.gatherResults([d1, self.loopback()])
- return d.addCallback(self._cbTestLogin)
-
- def _cbTestLogin(self, ignored):
- self.assertEqual(self.server.account, SimpleServer.theAccount)
- self.assertEqual(self.server.state, 'auth')
-
- def testFailedLogin(self):
- def login():
- d = self.client.login('testuser', 'wrong-password')
- d.addBoth(self._cbStopClient)
-
- d1 = self.connected.addCallback(strip(login)).addErrback(self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestFailedLogin)
-
- def _cbTestFailedLogin(self, ignored):
- self.assertEqual(self.server.account, None)
- self.assertEqual(self.server.state, 'unauth')
-
-
- def testLoginRequiringQuoting(self):
- self.server._username = '{test}user'
- self.server._password = '{test}password'
-
- def login():
- d = self.client.login('{test}user', '{test}password')
- d.addBoth(self._cbStopClient)
-
- d1 = self.connected.addCallback(strip(login)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestLoginRequiringQuoting)
-
- def _cbTestLoginRequiringQuoting(self, ignored):
- self.assertEqual(self.server.account, SimpleServer.theAccount)
- self.assertEqual(self.server.state, 'auth')
-
-
- def testNamespace(self):
- self.namespaceArgs = None
- def login():
- return self.client.login('testuser', 'password-test')
- def namespace():
- def gotNamespace(args):
- self.namespaceArgs = args
- self._cbStopClient(None)
- return self.client.namespace().addCallback(gotNamespace)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(namespace))
- d1.addErrback(self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _: self.assertEqual(self.namespaceArgs,
- [[['', '/']], [], []]))
- return d
-
- def testSelect(self):
- SimpleServer.theAccount.addMailbox('test-mailbox')
- self.selectedArgs = None
- def login():
- return self.client.login('testuser', 'password-test')
- def select():
- def selected(args):
- self.selectedArgs = args
- self._cbStopClient(None)
- d = self.client.select('test-mailbox')
- d.addCallback(selected)
- return d
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(select))
- d1.addErrback(self._ebGeneral)
- d2 = self.loopback()
- return defer.gatherResults([d1, d2]).addCallback(self._cbTestSelect)
-
- def _cbTestSelect(self, ignored):
- mbox = SimpleServer.theAccount.mailboxes['TEST-MAILBOX']
- self.assertEqual(self.server.mbox, mbox)
- self.assertEqual(self.selectedArgs, {
- 'EXISTS': 9, 'RECENT': 3, 'UIDVALIDITY': 42,
- 'FLAGS': ('\\Flag1', 'Flag2', '\\AnotherSysFlag', 'LastFlag'),
- 'READ-WRITE': 1
- })
-
-
- def test_examine(self):
- """
- L{IMAP4Client.examine} issues an I{EXAMINE} command to the server and
- returns a L{Deferred} which fires with a C{dict} with as many of the
- following keys as the server includes in its response: C{'FLAGS'},
- C{'EXISTS'}, C{'RECENT'}, C{'UNSEEN'}, C{'READ-WRITE'}, C{'READ-ONLY'},
- C{'UIDVALIDITY'}, and C{'PERMANENTFLAGS'}.
-
- Unfortunately the server doesn't generate all of these so it's hard to
- test the client's handling of them here. See
- L{IMAP4ClientExamineTests} below.
-
- See U{RFC 3501<http://www.faqs.org/rfcs/rfc3501.html>}, section 6.3.2,
- for details.
- """
- SimpleServer.theAccount.addMailbox('test-mailbox')
- self.examinedArgs = None
- def login():
- return self.client.login('testuser', 'password-test')
- def examine():
- def examined(args):
- self.examinedArgs = args
- self._cbStopClient(None)
- d = self.client.examine('test-mailbox')
- d.addCallback(examined)
- return d
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(examine))
- d1.addErrback(self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestExamine)
-
-
- def _cbTestExamine(self, ignored):
- mbox = SimpleServer.theAccount.mailboxes['TEST-MAILBOX']
- self.assertEqual(self.server.mbox, mbox)
- self.assertEqual(self.examinedArgs, {
- 'EXISTS': 9, 'RECENT': 3, 'UIDVALIDITY': 42,
- 'FLAGS': ('\\Flag1', 'Flag2', '\\AnotherSysFlag', 'LastFlag'),
- 'READ-WRITE': False})
-
-
- def testCreate(self):
- succeed = ('testbox', 'test/box', 'test/', 'test/box/box', 'INBOX')
- fail = ('testbox', 'test/box')
-
- def cb(): self.result.append(1)
- def eb(failure): self.result.append(0)
-
- def login():
- return self.client.login('testuser', 'password-test')
- def create():
- for name in succeed + fail:
- d = self.client.create(name)
- d.addCallback(strip(cb)).addErrback(eb)
- d.addCallbacks(self._cbStopClient, self._ebGeneral)
-
- self.result = []
- d1 = self.connected.addCallback(strip(login)).addCallback(strip(create))
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestCreate, succeed, fail)
-
- def _cbTestCreate(self, ignored, succeed, fail):
- self.assertEqual(self.result, [1] * len(succeed) + [0] * len(fail))
- mbox = SimpleServer.theAccount.mailboxes.keys()
- answers = ['inbox', 'testbox', 'test/box', 'test', 'test/box/box']
- mbox.sort()
- answers.sort()
- self.assertEqual(mbox, [a.upper() for a in answers])
-
- def testDelete(self):
- SimpleServer.theAccount.addMailbox('delete/me')
-
- def login():
- return self.client.login('testuser', 'password-test')
- def delete():
- return self.client.delete('delete/me')
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(delete), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.assertEqual(SimpleServer.theAccount.mailboxes.keys(), []))
- return d
-
- def testIllegalInboxDelete(self):
- self.stashed = None
- def login():
- return self.client.login('testuser', 'password-test')
- def delete():
- return self.client.delete('inbox')
- def stash(result):
- self.stashed = result
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(delete), self._ebGeneral)
- d1.addBoth(stash)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _: self.failUnless(isinstance(self.stashed,
- failure.Failure)))
- return d
-
-
- def testNonExistentDelete(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def delete():
- return self.client.delete('delete/me')
- def deleteFailed(failure):
- self.failure = failure
-
- self.failure = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(delete)).addErrback(deleteFailed)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _: self.assertEqual(str(self.failure.value),
- 'No such mailbox'))
- return d
-
-
- def testIllegalDelete(self):
- m = SimpleMailbox()
- m.flags = (r'\Noselect',)
- SimpleServer.theAccount.addMailbox('delete', m)
- SimpleServer.theAccount.addMailbox('delete/me')
-
- def login():
- return self.client.login('testuser', 'password-test')
- def delete():
- return self.client.delete('delete')
- def deleteFailed(failure):
- self.failure = failure
-
- self.failure = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(delete)).addErrback(deleteFailed)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- expected = "Hierarchically inferior mailboxes exist and \\Noselect is set"
- d.addCallback(lambda _:
- self.assertEqual(str(self.failure.value), expected))
- return d
-
- def testRename(self):
- SimpleServer.theAccount.addMailbox('oldmbox')
- def login():
- return self.client.login('testuser', 'password-test')
- def rename():
- return self.client.rename('oldmbox', 'newname')
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(rename), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.assertEqual(SimpleServer.theAccount.mailboxes.keys(),
- ['NEWNAME']))
- return d
-
- def testIllegalInboxRename(self):
- self.stashed = None
- def login():
- return self.client.login('testuser', 'password-test')
- def rename():
- return self.client.rename('inbox', 'frotz')
- def stash(stuff):
- self.stashed = stuff
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(rename), self._ebGeneral)
- d1.addBoth(stash)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.failUnless(isinstance(self.stashed, failure.Failure)))
- return d
-
- def testHierarchicalRename(self):
- SimpleServer.theAccount.create('oldmbox/m1')
- SimpleServer.theAccount.create('oldmbox/m2')
- def login():
- return self.client.login('testuser', 'password-test')
- def rename():
- return self.client.rename('oldmbox', 'newname')
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(rename), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestHierarchicalRename)
-
- def _cbTestHierarchicalRename(self, ignored):
- mboxes = SimpleServer.theAccount.mailboxes.keys()
- expected = ['newname', 'newname/m1', 'newname/m2']
- mboxes.sort()
- self.assertEqual(mboxes, [s.upper() for s in expected])
-
- def testSubscribe(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def subscribe():
- return self.client.subscribe('this/mbox')
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(subscribe), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.assertEqual(SimpleServer.theAccount.subscriptions,
- ['THIS/MBOX']))
- return d
-
- def testUnsubscribe(self):
- SimpleServer.theAccount.subscriptions = ['THIS/MBOX', 'THAT/MBOX']
- def login():
- return self.client.login('testuser', 'password-test')
- def unsubscribe():
- return self.client.unsubscribe('this/mbox')
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(unsubscribe), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.assertEqual(SimpleServer.theAccount.subscriptions,
- ['THAT/MBOX']))
- return d
-
- def _listSetup(self, f):
- SimpleServer.theAccount.addMailbox('root/subthing')
- SimpleServer.theAccount.addMailbox('root/another-thing')
- SimpleServer.theAccount.addMailbox('non-root/subthing')
-
- def login():
- return self.client.login('testuser', 'password-test')
- def listed(answers):
- self.listed = answers
-
- self.listed = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(f), self._ebGeneral)
- d1.addCallbacks(listed, self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- return defer.gatherResults([d1, d2]).addCallback(lambda _: self.listed)
-
- def testList(self):
- def list():
- return self.client.list('root', '%')
- d = self._listSetup(list)
- d.addCallback(lambda listed: self.assertEqual(
- sortNest(listed),
- sortNest([
- (SimpleMailbox.flags, "/", "ROOT/SUBTHING"),
- (SimpleMailbox.flags, "/", "ROOT/ANOTHER-THING")
- ])
- ))
- return d
-
- def testLSub(self):
- SimpleServer.theAccount.subscribe('ROOT/SUBTHING')
- def lsub():
- return self.client.lsub('root', '%')
- d = self._listSetup(lsub)
- d.addCallback(self.assertEqual,
- [(SimpleMailbox.flags, "/", "ROOT/SUBTHING")])
- return d
-
- def testStatus(self):
- SimpleServer.theAccount.addMailbox('root/subthing')
- def login():
- return self.client.login('testuser', 'password-test')
- def status():
- return self.client.status('root/subthing', 'MESSAGES', 'UIDNEXT', 'UNSEEN')
- def statused(result):
- self.statused = result
-
- self.statused = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(status), self._ebGeneral)
- d1.addCallbacks(statused, self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _: self.assertEqual(
- self.statused,
- {'MESSAGES': 9, 'UIDNEXT': '10', 'UNSEEN': 4}
- ))
- return d
-
- def testFailedStatus(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def status():
- return self.client.status('root/nonexistent', 'MESSAGES', 'UIDNEXT', 'UNSEEN')
- def statused(result):
- self.statused = result
- def failed(failure):
- self.failure = failure
-
- self.statused = self.failure = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(status), self._ebGeneral)
- d1.addCallbacks(statused, failed)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- return defer.gatherResults([d1, d2]).addCallback(self._cbTestFailedStatus)
-
- def _cbTestFailedStatus(self, ignored):
- self.assertEqual(
- self.statused, None
- )
- self.assertEqual(
- self.failure.value.args,
- ('Could not open mailbox',)
- )
-
- def testFullAppend(self):
- infile = util.sibpath(__file__, 'rfc822.message')
- message = open(infile)
- SimpleServer.theAccount.addMailbox('root/subthing')
- def login():
- return self.client.login('testuser', 'password-test')
- def append():
- return self.client.append(
- 'root/subthing',
- message,
- ('\\SEEN', '\\DELETED'),
- 'Tue, 17 Jun 2003 11:22:16 -0600 (MDT)',
- )
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(append), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestFullAppend, infile)
-
- def _cbTestFullAppend(self, ignored, infile):
- mb = SimpleServer.theAccount.mailboxes['ROOT/SUBTHING']
- self.assertEqual(1, len(mb.messages))
- self.assertEqual(
- (['\\SEEN', '\\DELETED'], 'Tue, 17 Jun 2003 11:22:16 -0600 (MDT)', 0),
- mb.messages[0][1:]
- )
- self.assertEqual(open(infile).read(), mb.messages[0][0].getvalue())
-
- def testPartialAppend(self):
- infile = util.sibpath(__file__, 'rfc822.message')
- message = open(infile)
- SimpleServer.theAccount.addMailbox('PARTIAL/SUBTHING')
- def login():
- return self.client.login('testuser', 'password-test')
- def append():
- message = file(infile)
- return self.client.sendCommand(
- imap4.Command(
- 'APPEND',
- 'PARTIAL/SUBTHING (\\SEEN) "Right now" {%d}' % os.path.getsize(infile),
- (), self.client._IMAP4Client__cbContinueAppend, message
- )
- )
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(append), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestPartialAppend, infile)
-
- def _cbTestPartialAppend(self, ignored, infile):
- mb = SimpleServer.theAccount.mailboxes['PARTIAL/SUBTHING']
- self.assertEqual(1, len(mb.messages))
- self.assertEqual(
- (['\\SEEN'], 'Right now', 0),
- mb.messages[0][1:]
- )
- self.assertEqual(open(infile).read(), mb.messages[0][0].getvalue())
-
- def testCheck(self):
- SimpleServer.theAccount.addMailbox('root/subthing')
- def login():
- return self.client.login('testuser', 'password-test')
- def select():
- return self.client.select('root/subthing')
- def check():
- return self.client.check()
-
- d = self.connected.addCallback(strip(login))
- d.addCallbacks(strip(select), self._ebGeneral)
- d.addCallbacks(strip(check), self._ebGeneral)
- d.addCallbacks(self._cbStopClient, self._ebGeneral)
- return self.loopback()
-
- # Okay, that was fun
-
- def testClose(self):
- m = SimpleMailbox()
- m.messages = [
- ('Message 1', ('\\Deleted', 'AnotherFlag'), None, 0),
- ('Message 2', ('AnotherFlag',), None, 1),
- ('Message 3', ('\\Deleted',), None, 2),
- ]
- SimpleServer.theAccount.addMailbox('mailbox', m)
- def login():
- return self.client.login('testuser', 'password-test')
- def select():
- return self.client.select('mailbox')
- def close():
- return self.client.close()
-
- d = self.connected.addCallback(strip(login))
- d.addCallbacks(strip(select), self._ebGeneral)
- d.addCallbacks(strip(close), self._ebGeneral)
- d.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- return defer.gatherResults([d, d2]).addCallback(self._cbTestClose, m)
-
- def _cbTestClose(self, ignored, m):
- self.assertEqual(len(m.messages), 1)
- self.assertEqual(m.messages[0], ('Message 2', ('AnotherFlag',), None, 1))
- self.failUnless(m.closed)
-
- def testExpunge(self):
- m = SimpleMailbox()
- m.messages = [
- ('Message 1', ('\\Deleted', 'AnotherFlag'), None, 0),
- ('Message 2', ('AnotherFlag',), None, 1),
- ('Message 3', ('\\Deleted',), None, 2),
- ]
- SimpleServer.theAccount.addMailbox('mailbox', m)
- def login():
- return self.client.login('testuser', 'password-test')
- def select():
- return self.client.select('mailbox')
- def expunge():
- return self.client.expunge()
- def expunged(results):
- self.failIf(self.server.mbox is None)
- self.results = results
-
- self.results = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(select), self._ebGeneral)
- d1.addCallbacks(strip(expunge), self._ebGeneral)
- d1.addCallbacks(expunged, self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestExpunge, m)
-
- def _cbTestExpunge(self, ignored, m):
- self.assertEqual(len(m.messages), 1)
- self.assertEqual(m.messages[0], ('Message 2', ('AnotherFlag',), None, 1))
-
- self.assertEqual(self.results, [0, 2])
-
-
-
-class IMAP4ServerSearchTestCase(IMAP4HelperMixin, unittest.TestCase):
- """
- Tests for the behavior of the search_* functions in L{imap4.IMAP4Server}.
- """
- def setUp(self):
- IMAP4HelperMixin.setUp(self)
- self.earlierQuery = ["10-Dec-2009"]
- self.sameDateQuery = ["13-Dec-2009"]
- self.laterQuery = ["16-Dec-2009"]
- self.seq = 0
- self.msg = FakeyMessage({"date" : "Mon, 13 Dec 2009 21:25:10 GMT"}, [],
- '', '', 1234, None)
-
-
- def test_searchSentBefore(self):
- """
- L{imap4.IMAP4Server.search_SENTBEFORE} returns True if the message date
- is earlier than the query date.
- """
- self.assertFalse(
- self.server.search_SENTBEFORE(self.earlierQuery, self.seq, self.msg))
- self.assertTrue(
- self.server.search_SENTBEFORE(self.laterQuery, self.seq, self.msg))
-
- def test_searchWildcard(self):
- """
- L{imap4.IMAP4Server.search_UID} returns True if the message UID is in
- the search range.
- """
- self.assertFalse(
- self.server.search_UID(['2:3'], self.seq, self.msg, (1, 1234)))
- # 2:* should get translated to 2:<max UID> and then to 1:2
- self.assertTrue(
- self.server.search_UID(['2:*'], self.seq, self.msg, (1, 1234)))
- self.assertTrue(
- self.server.search_UID(['*'], self.seq, self.msg, (1, 1234)))
-
- def test_searchWildcardHigh(self):
- """
- L{imap4.IMAP4Server.search_UID} should return True if there is a
- wildcard, because a wildcard means "highest UID in the mailbox".
- """
- self.assertTrue(
- self.server.search_UID(['1235:*'], self.seq, self.msg, (1234, 1)))
-
- def test_reversedSearchTerms(self):
- """
- L{imap4.IMAP4Server.search_SENTON} returns True if the message date is
- the same as the query date.
- """
- msgset = imap4.parseIdList('4:2')
- self.assertEqual(list(msgset), [2, 3, 4])
-
- def test_searchSentOn(self):
- """
- L{imap4.IMAP4Server.search_SENTON} returns True if the message date is
- the same as the query date.
- """
- self.assertFalse(
- self.server.search_SENTON(self.earlierQuery, self.seq, self.msg))
- self.assertTrue(
- self.server.search_SENTON(self.sameDateQuery, self.seq, self.msg))
- self.assertFalse(
- self.server.search_SENTON(self.laterQuery, self.seq, self.msg))
-
-
- def test_searchSentSince(self):
- """
- L{imap4.IMAP4Server.search_SENTSINCE} returns True if the message date
- is later than the query date.
- """
- self.assertTrue(
- self.server.search_SENTSINCE(self.earlierQuery, self.seq, self.msg))
- self.assertFalse(
- self.server.search_SENTSINCE(self.laterQuery, self.seq, self.msg))
-
-
- def test_searchOr(self):
- """
- L{imap4.IMAP4Server.search_OR} returns true if either of the two
- expressions supplied to it returns true and returns false if neither
- does.
- """
- self.assertTrue(
- self.server.search_OR(
- ["SENTSINCE"] + self.earlierQuery +
- ["SENTSINCE"] + self.laterQuery,
- self.seq, self.msg, (None, None)))
- self.assertTrue(
- self.server.search_OR(
- ["SENTSINCE"] + self.laterQuery +
- ["SENTSINCE"] + self.earlierQuery,
- self.seq, self.msg, (None, None)))
- self.assertFalse(
- self.server.search_OR(
- ["SENTON"] + self.laterQuery +
- ["SENTSINCE"] + self.laterQuery,
- self.seq, self.msg, (None, None)))
-
-
- def test_searchNot(self):
- """
- L{imap4.IMAP4Server.search_NOT} returns the negation of the result
- of the expression supplied to it.
- """
- self.assertFalse(self.server.search_NOT(
- ["SENTSINCE"] + self.earlierQuery, self.seq, self.msg,
- (None, None)))
- self.assertTrue(self.server.search_NOT(
- ["SENTON"] + self.laterQuery, self.seq, self.msg,
- (None, None)))
-
-
-
-class TestRealm:
- theAccount = None
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- return imap4.IAccount, self.theAccount, lambda: None
-
-class TestChecker:
- credentialInterfaces = (cred.credentials.IUsernameHashedPassword, cred.credentials.IUsernamePassword)
-
- users = {
- 'testuser': 'secret'
- }
-
- def requestAvatarId(self, credentials):
- if credentials.username in self.users:
- return defer.maybeDeferred(
- credentials.checkPassword, self.users[credentials.username]
- ).addCallback(self._cbCheck, credentials.username)
-
- def _cbCheck(self, result, username):
- if result:
- return username
- raise cred.error.UnauthorizedLogin()
-
-class AuthenticatorTestCase(IMAP4HelperMixin, unittest.TestCase):
- def setUp(self):
- IMAP4HelperMixin.setUp(self)
-
- realm = TestRealm()
- realm.theAccount = Account('testuser')
- portal = cred.portal.Portal(realm)
- portal.registerChecker(TestChecker())
- self.server.portal = portal
-
- self.authenticated = 0
- self.account = realm.theAccount
-
- def testCramMD5(self):
- self.server.challengers['CRAM-MD5'] = cred.credentials.CramMD5Credentials
- cAuth = imap4.CramMD5ClientAuthenticator('testuser')
- self.client.registerAuthenticator(cAuth)
-
- def auth():
- return self.client.authenticate('secret')
- def authed():
- self.authenticated = 1
-
- d1 = self.connected.addCallback(strip(auth))
- d1.addCallbacks(strip(authed), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestCramMD5)
-
- def _cbTestCramMD5(self, ignored):
- self.assertEqual(self.authenticated, 1)
- self.assertEqual(self.server.account, self.account)
-
- def testFailedCramMD5(self):
- self.server.challengers['CRAM-MD5'] = cred.credentials.CramMD5Credentials
- cAuth = imap4.CramMD5ClientAuthenticator('testuser')
- self.client.registerAuthenticator(cAuth)
-
- def misauth():
- return self.client.authenticate('not the secret')
- def authed():
- self.authenticated = 1
- def misauthed():
- self.authenticated = -1
-
- d1 = self.connected.addCallback(strip(misauth))
- d1.addCallbacks(strip(authed), strip(misauthed))
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestFailedCramMD5)
-
- def _cbTestFailedCramMD5(self, ignored):
- self.assertEqual(self.authenticated, -1)
- self.assertEqual(self.server.account, None)
-
- def testLOGIN(self):
- self.server.challengers['LOGIN'] = imap4.LOGINCredentials
- cAuth = imap4.LOGINAuthenticator('testuser')
- self.client.registerAuthenticator(cAuth)
-
- def auth():
- return self.client.authenticate('secret')
- def authed():
- self.authenticated = 1
-
- d1 = self.connected.addCallback(strip(auth))
- d1.addCallbacks(strip(authed), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestLOGIN)
-
- def _cbTestLOGIN(self, ignored):
- self.assertEqual(self.authenticated, 1)
- self.assertEqual(self.server.account, self.account)
-
- def testFailedLOGIN(self):
- self.server.challengers['LOGIN'] = imap4.LOGINCredentials
- cAuth = imap4.LOGINAuthenticator('testuser')
- self.client.registerAuthenticator(cAuth)
-
- def misauth():
- return self.client.authenticate('not the secret')
- def authed():
- self.authenticated = 1
- def misauthed():
- self.authenticated = -1
-
- d1 = self.connected.addCallback(strip(misauth))
- d1.addCallbacks(strip(authed), strip(misauthed))
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestFailedLOGIN)
-
- def _cbTestFailedLOGIN(self, ignored):
- self.assertEqual(self.authenticated, -1)
- self.assertEqual(self.server.account, None)
-
- def testPLAIN(self):
- self.server.challengers['PLAIN'] = imap4.PLAINCredentials
- cAuth = imap4.PLAINAuthenticator('testuser')
- self.client.registerAuthenticator(cAuth)
-
- def auth():
- return self.client.authenticate('secret')
- def authed():
- self.authenticated = 1
-
- d1 = self.connected.addCallback(strip(auth))
- d1.addCallbacks(strip(authed), self._ebGeneral)
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestPLAIN)
-
- def _cbTestPLAIN(self, ignored):
- self.assertEqual(self.authenticated, 1)
- self.assertEqual(self.server.account, self.account)
-
- def testFailedPLAIN(self):
- self.server.challengers['PLAIN'] = imap4.PLAINCredentials
- cAuth = imap4.PLAINAuthenticator('testuser')
- self.client.registerAuthenticator(cAuth)
-
- def misauth():
- return self.client.authenticate('not the secret')
- def authed():
- self.authenticated = 1
- def misauthed():
- self.authenticated = -1
-
- d1 = self.connected.addCallback(strip(misauth))
- d1.addCallbacks(strip(authed), strip(misauthed))
- d1.addCallbacks(self._cbStopClient, self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestFailedPLAIN)
-
- def _cbTestFailedPLAIN(self, ignored):
- self.assertEqual(self.authenticated, -1)
- self.assertEqual(self.server.account, None)
-
-
-
-class SASLPLAINTestCase(unittest.TestCase):
- """
- Tests for I{SASL PLAIN} authentication, as implemented by
- L{imap4.PLAINAuthenticator} and L{imap4.PLAINCredentials}.
-
- @see: U{http://www.faqs.org/rfcs/rfc2595.html}
- @see: U{http://www.faqs.org/rfcs/rfc4616.html}
- """
- def test_authenticatorChallengeResponse(self):
- """
- L{PLAINAuthenticator.challengeResponse} returns challenge strings of
- the form::
-
- NUL<authn-id>NUL<secret>
- """
- username = 'testuser'
- secret = 'secret'
- chal = 'challenge'
- cAuth = imap4.PLAINAuthenticator(username)
- response = cAuth.challengeResponse(secret, chal)
- self.assertEqual(response, '\0%s\0%s' % (username, secret))
-
-
- def test_credentialsSetResponse(self):
- """
- L{PLAINCredentials.setResponse} parses challenge strings of the
- form::
-
- NUL<authn-id>NUL<secret>
- """
- cred = imap4.PLAINCredentials()
- cred.setResponse('\0testuser\0secret')
- self.assertEqual(cred.username, 'testuser')
- self.assertEqual(cred.password, 'secret')
-
-
- def test_credentialsInvalidResponse(self):
- """
- L{PLAINCredentials.setResponse} raises L{imap4.IllegalClientResponse}
- when passed a string not of the expected form.
- """
- cred = imap4.PLAINCredentials()
- self.assertRaises(
- imap4.IllegalClientResponse, cred.setResponse, 'hello')
- self.assertRaises(
- imap4.IllegalClientResponse, cred.setResponse, 'hello\0world')
- self.assertRaises(
- imap4.IllegalClientResponse, cred.setResponse,
- 'hello\0world\0Zoom!\0')
-
-
-
-class UnsolicitedResponseTestCase(IMAP4HelperMixin, unittest.TestCase):
- def testReadWrite(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def loggedIn():
- self.server.modeChanged(1)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(loggedIn)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestReadWrite)
-
- def _cbTestReadWrite(self, ignored):
- E = self.client.events
- self.assertEqual(E, [['modeChanged', 1]])
-
- def testReadOnly(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def loggedIn():
- self.server.modeChanged(0)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(loggedIn)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestReadOnly)
-
- def _cbTestReadOnly(self, ignored):
- E = self.client.events
- self.assertEqual(E, [['modeChanged', 0]])
-
- def testFlagChange(self):
- flags = {
- 1: ['\\Answered', '\\Deleted'],
- 5: [],
- 10: ['\\Recent']
- }
- def login():
- return self.client.login('testuser', 'password-test')
- def loggedIn():
- self.server.flagsChanged(flags)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(loggedIn)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestFlagChange, flags)
-
- def _cbTestFlagChange(self, ignored, flags):
- E = self.client.events
- expect = [['flagsChanged', {x[0]: x[1]}] for x in flags.items()]
- E.sort()
- expect.sort()
- self.assertEqual(E, expect)
-
- def testNewMessages(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def loggedIn():
- self.server.newMessages(10, None)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(loggedIn)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestNewMessages)
-
- def _cbTestNewMessages(self, ignored):
- E = self.client.events
- self.assertEqual(E, [['newMessages', 10, None]])
-
- def testNewRecentMessages(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def loggedIn():
- self.server.newMessages(None, 10)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(loggedIn)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestNewRecentMessages)
-
- def _cbTestNewRecentMessages(self, ignored):
- E = self.client.events
- self.assertEqual(E, [['newMessages', None, 10]])
-
- def testNewMessagesAndRecent(self):
- def login():
- return self.client.login('testuser', 'password-test')
- def loggedIn():
- self.server.newMessages(20, 10)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(loggedIn)).addErrback(self._ebGeneral)
- d = defer.gatherResults([self.loopback(), d1])
- return d.addCallback(self._cbTestNewMessagesAndRecent)
-
- def _cbTestNewMessagesAndRecent(self, ignored):
- E = self.client.events
- self.assertEqual(E, [['newMessages', 20, None], ['newMessages', None, 10]])
-
-
-class ClientCapabilityTests(unittest.TestCase):
- """
- Tests for issuance of the CAPABILITY command and handling of its response.
- """
- def setUp(self):
- """
- Create an L{imap4.IMAP4Client} connected to a L{StringTransport}.
- """
- self.transport = StringTransport()
- self.protocol = imap4.IMAP4Client()
- self.protocol.makeConnection(self.transport)
- self.protocol.dataReceived('* OK [IMAP4rev1]\r\n')
-
-
- def test_simpleAtoms(self):
- """
- A capability response consisting only of atoms without C{'='} in them
- should result in a dict mapping those atoms to C{None}.
- """
- capabilitiesResult = self.protocol.getCapabilities(useCache=False)
- self.protocol.dataReceived('* CAPABILITY IMAP4rev1 LOGINDISABLED\r\n')
- self.protocol.dataReceived('0001 OK Capability completed.\r\n')
- def gotCapabilities(capabilities):
- self.assertEqual(
- capabilities, {'IMAP4rev1': None, 'LOGINDISABLED': None})
- capabilitiesResult.addCallback(gotCapabilities)
- return capabilitiesResult
-
-
- def test_categoryAtoms(self):
- """
- A capability response consisting of atoms including C{'='} should have
- those atoms split on that byte and have capabilities in the same
- category aggregated into lists in the resulting dictionary.
-
- (n.b. - I made up the word "category atom"; the protocol has no notion
- of structure here, but rather allows each capability to define the
- semantics of its entry in the capability response in a freeform manner.
- If I had realized this earlier, the API for capabilities would look
- different. As it is, we can hope that no one defines any crazy
- semantics which are incompatible with this API, or try to figure out a
- better API when someone does. -exarkun)
- """
- capabilitiesResult = self.protocol.getCapabilities(useCache=False)
- self.protocol.dataReceived('* CAPABILITY IMAP4rev1 AUTH=LOGIN AUTH=PLAIN\r\n')
- self.protocol.dataReceived('0001 OK Capability completed.\r\n')
- def gotCapabilities(capabilities):
- self.assertEqual(
- capabilities, {'IMAP4rev1': None, 'AUTH': ['LOGIN', 'PLAIN']})
- capabilitiesResult.addCallback(gotCapabilities)
- return capabilitiesResult
-
-
- def test_mixedAtoms(self):
- """
- A capability response consisting of both simple and category atoms of
- the same type should result in a list containing C{None} as well as the
- values for the category.
- """
- capabilitiesResult = self.protocol.getCapabilities(useCache=False)
- # Exercise codepath for both orderings of =-having and =-missing
- # capabilities.
- self.protocol.dataReceived(
- '* CAPABILITY IMAP4rev1 FOO FOO=BAR BAR=FOO BAR\r\n')
- self.protocol.dataReceived('0001 OK Capability completed.\r\n')
- def gotCapabilities(capabilities):
- self.assertEqual(capabilities, {'IMAP4rev1': None,
- 'FOO': [None, 'BAR'],
- 'BAR': ['FOO', None]})
- capabilitiesResult.addCallback(gotCapabilities)
- return capabilitiesResult
-
-
-
-class StillSimplerClient(imap4.IMAP4Client):
- """
- An IMAP4 client which keeps track of unsolicited flag changes.
- """
- def __init__(self):
- imap4.IMAP4Client.__init__(self)
- self.flags = {}
-
-
- def flagsChanged(self, newFlags):
- self.flags.update(newFlags)
-
-
-
-class HandCraftedTestCase(IMAP4HelperMixin, unittest.TestCase):
- def testTrailingLiteral(self):
- transport = StringTransport()
- c = imap4.IMAP4Client()
- c.makeConnection(transport)
- c.lineReceived('* OK [IMAP4rev1]')
-
- def cbSelect(ignored):
- d = c.fetchMessage('1')
- c.dataReceived('* 1 FETCH (RFC822 {10}\r\n0123456789\r\n RFC822.SIZE 10)\r\n')
- c.dataReceived('0003 OK FETCH\r\n')
- return d
-
- def cbLogin(ignored):
- d = c.select('inbox')
- c.lineReceived('0002 OK SELECT')
- d.addCallback(cbSelect)
- return d
-
- d = c.login('blah', 'blah')
- c.dataReceived('0001 OK LOGIN\r\n')
- d.addCallback(cbLogin)
- return d
-
-
- def testPathelogicalScatteringOfLiterals(self):
- self.server.checker.addUser('testuser', 'password-test')
- transport = StringTransport()
- self.server.makeConnection(transport)
-
- transport.clear()
- self.server.dataReceived("01 LOGIN {8}\r\n")
- self.assertEqual(transport.value(), "+ Ready for 8 octets of text\r\n")
-
- transport.clear()
- self.server.dataReceived("testuser {13}\r\n")
- self.assertEqual(transport.value(), "+ Ready for 13 octets of text\r\n")
-
- transport.clear()
- self.server.dataReceived("password-test\r\n")
- self.assertEqual(transport.value(), "01 OK LOGIN succeeded\r\n")
- self.assertEqual(self.server.state, 'auth')
-
- self.server.connectionLost(error.ConnectionDone("Connection done."))
-
-
- def test_unsolicitedResponseMixedWithSolicitedResponse(self):
- """
- If unsolicited data is received along with solicited data in the
- response to a I{FETCH} command issued by L{IMAP4Client.fetchSpecific},
- the unsolicited data is passed to the appropriate callback and not
- included in the result with wihch the L{Deferred} returned by
- L{IMAP4Client.fetchSpecific} fires.
- """
- transport = StringTransport()
- c = StillSimplerClient()
- c.makeConnection(transport)
- c.lineReceived('* OK [IMAP4rev1]')
-
- def login():
- d = c.login('blah', 'blah')
- c.dataReceived('0001 OK LOGIN\r\n')
- return d
- def select():
- d = c.select('inbox')
- c.lineReceived('0002 OK SELECT')
- return d
- def fetch():
- d = c.fetchSpecific('1:*',
- headerType='HEADER.FIELDS',
- headerArgs=['SUBJECT'])
- c.dataReceived('* 1 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {38}\r\n')
- c.dataReceived('Subject: Suprise for your woman...\r\n')
- c.dataReceived('\r\n')
- c.dataReceived(')\r\n')
- c.dataReceived('* 1 FETCH (FLAGS (\Seen))\r\n')
- c.dataReceived('* 2 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {75}\r\n')
- c.dataReceived('Subject: What you been doing. Order your meds here . ,. handcuff madsen\r\n')
- c.dataReceived('\r\n')
- c.dataReceived(')\r\n')
- c.dataReceived('0003 OK FETCH completed\r\n')
- return d
- def test(res):
- self.assertEqual(res, {
- 1: [['BODY', ['HEADER.FIELDS', ['SUBJECT']],
- 'Subject: Suprise for your woman...\r\n\r\n']],
- 2: [['BODY', ['HEADER.FIELDS', ['SUBJECT']],
- 'Subject: What you been doing. Order your meds here . ,. handcuff madsen\r\n\r\n']]
- })
-
- self.assertEqual(c.flags, {1: ['\\Seen']})
-
- return login(
- ).addCallback(strip(select)
- ).addCallback(strip(fetch)
- ).addCallback(test)
-
-
- def test_literalWithoutPrecedingWhitespace(self):
- """
- Literals should be recognized even when they are not preceded by
- whitespace.
- """
- transport = StringTransport()
- protocol = imap4.IMAP4Client()
-
- protocol.makeConnection(transport)
- protocol.lineReceived('* OK [IMAP4rev1]')
-
- def login():
- d = protocol.login('blah', 'blah')
- protocol.dataReceived('0001 OK LOGIN\r\n')
- return d
- def select():
- d = protocol.select('inbox')
- protocol.lineReceived('0002 OK SELECT')
- return d
- def fetch():
- d = protocol.fetchSpecific('1:*',
- headerType='HEADER.FIELDS',
- headerArgs=['SUBJECT'])
- protocol.dataReceived(
- '* 1 FETCH (BODY[HEADER.FIELDS ({7}\r\nSUBJECT)] "Hello")\r\n')
- protocol.dataReceived('0003 OK FETCH completed\r\n')
- return d
- def test(result):
- self.assertEqual(
- result, {1: [['BODY', ['HEADER.FIELDS', ['SUBJECT']], 'Hello']]})
-
- d = login()
- d.addCallback(strip(select))
- d.addCallback(strip(fetch))
- d.addCallback(test)
- return d
-
-
- def test_nonIntegerLiteralLength(self):
- """
- If the server sends a literal length which cannot be parsed as an
- integer, L{IMAP4Client.lineReceived} should cause the protocol to be
- disconnected by raising L{imap4.IllegalServerResponse}.
- """
- transport = StringTransport()
- protocol = imap4.IMAP4Client()
-
- protocol.makeConnection(transport)
- protocol.lineReceived('* OK [IMAP4rev1]')
-
- def login():
- d = protocol.login('blah', 'blah')
- protocol.dataReceived('0001 OK LOGIN\r\n')
- return d
- def select():
- d = protocol.select('inbox')
- protocol.lineReceived('0002 OK SELECT')
- return d
- def fetch():
- d = protocol.fetchSpecific('1:*',
- headerType='HEADER.FIELDS',
- headerArgs=['SUBJECT'])
- self.assertRaises(
- imap4.IllegalServerResponse,
- protocol.dataReceived,
- '* 1 FETCH {xyz}\r\n...')
- d = login()
- d.addCallback(strip(select))
- d.addCallback(strip(fetch))
- return d
-
-
- def test_flagsChangedInsideFetchSpecificResponse(self):
- """
- Any unrequested flag information received along with other requested
- information in an untagged I{FETCH} received in response to a request
- issued with L{IMAP4Client.fetchSpecific} is passed to the
- C{flagsChanged} callback.
- """
- transport = StringTransport()
- c = StillSimplerClient()
- c.makeConnection(transport)
- c.lineReceived('* OK [IMAP4rev1]')
-
- def login():
- d = c.login('blah', 'blah')
- c.dataReceived('0001 OK LOGIN\r\n')
- return d
- def select():
- d = c.select('inbox')
- c.lineReceived('0002 OK SELECT')
- return d
- def fetch():
- d = c.fetchSpecific('1:*',
- headerType='HEADER.FIELDS',
- headerArgs=['SUBJECT'])
- # This response includes FLAGS after the requested data.
- c.dataReceived('* 1 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {22}\r\n')
- c.dataReceived('Subject: subject one\r\n')
- c.dataReceived(' FLAGS (\\Recent))\r\n')
- # And this one includes it before! Either is possible.
- c.dataReceived('* 2 FETCH (FLAGS (\\Seen) BODY[HEADER.FIELDS ("SUBJECT")] {22}\r\n')
- c.dataReceived('Subject: subject two\r\n')
- c.dataReceived(')\r\n')
- c.dataReceived('0003 OK FETCH completed\r\n')
- return d
-
- def test(res):
- self.assertEqual(res, {
- 1: [['BODY', ['HEADER.FIELDS', ['SUBJECT']],
- 'Subject: subject one\r\n']],
- 2: [['BODY', ['HEADER.FIELDS', ['SUBJECT']],
- 'Subject: subject two\r\n']]
- })
-
- self.assertEqual(c.flags, {1: ['\\Recent'], 2: ['\\Seen']})
-
- return login(
- ).addCallback(strip(select)
- ).addCallback(strip(fetch)
- ).addCallback(test)
-
-
- def test_flagsChangedInsideFetchMessageResponse(self):
- """
- Any unrequested flag information received along with other requested
- information in an untagged I{FETCH} received in response to a request
- issued with L{IMAP4Client.fetchMessage} is passed to the
- C{flagsChanged} callback.
- """
- transport = StringTransport()
- c = StillSimplerClient()
- c.makeConnection(transport)
- c.lineReceived('* OK [IMAP4rev1]')
-
- def login():
- d = c.login('blah', 'blah')
- c.dataReceived('0001 OK LOGIN\r\n')
- return d
- def select():
- d = c.select('inbox')
- c.lineReceived('0002 OK SELECT')
- return d
- def fetch():
- d = c.fetchMessage('1:*')
- c.dataReceived('* 1 FETCH (RFC822 {24}\r\n')
- c.dataReceived('Subject: first subject\r\n')
- c.dataReceived(' FLAGS (\Seen))\r\n')
- c.dataReceived('* 2 FETCH (FLAGS (\Recent \Seen) RFC822 {25}\r\n')
- c.dataReceived('Subject: second subject\r\n')
- c.dataReceived(')\r\n')
- c.dataReceived('0003 OK FETCH completed\r\n')
- return d
-
- def test(res):
- self.assertEqual(res, {
- 1: {'RFC822': 'Subject: first subject\r\n'},
- 2: {'RFC822': 'Subject: second subject\r\n'}})
-
- self.assertEqual(
- c.flags, {1: ['\\Seen'], 2: ['\\Recent', '\\Seen']})
-
- return login(
- ).addCallback(strip(select)
- ).addCallback(strip(fetch)
- ).addCallback(test)
-
-
-
-class PreauthIMAP4ClientMixin:
- """
- Mixin for L{unittest.TestCase} subclasses which provides a C{setUp} method
- which creates an L{IMAP4Client} connected to a L{StringTransport} and puts
- it into the I{authenticated} state.
-
- @ivar transport: A L{StringTransport} to which C{client} is connected.
- @ivar client: An L{IMAP4Client} which is connected to C{transport}.
- """
- clientProtocol = imap4.IMAP4Client
-
- def setUp(self):
- """
- Create an IMAP4Client connected to a fake transport and in the
- authenticated state.
- """
- self.transport = StringTransport()
- self.client = self.clientProtocol()
- self.client.makeConnection(self.transport)
- self.client.dataReceived('* PREAUTH Hello unittest\r\n')
-
-
- def _extractDeferredResult(self, d):
- """
- Synchronously extract the result of the given L{Deferred}. Fail the
- test if that is not possible.
- """
- result = []
- error = []
- d.addCallbacks(result.append, error.append)
- if result:
- return result[0]
- elif error:
- error[0].raiseException()
- else:
- self.fail("Expected result not available")
-
-
-
-class SelectionTestsMixin(PreauthIMAP4ClientMixin):
- """
- Mixin for test cases which defines tests which apply to both I{EXAMINE} and
- I{SELECT} support.
- """
- def _examineOrSelect(self):
- """
- Issue either an I{EXAMINE} or I{SELECT} command (depending on
- C{self.method}), assert that the correct bytes are written to the
- transport, and return the L{Deferred} returned by whichever method was
- called.
- """
- d = getattr(self.client, self.method)('foobox')
- self.assertEqual(
- self.transport.value(), '0001 %s foobox\r\n' % (self.command,))
- return d
-
-
- def _response(self, *lines):
- """
- Deliver the given (unterminated) response lines to C{self.client} and
- then deliver a tagged SELECT or EXAMINE completion line to finish the
- SELECT or EXAMINE response.
- """
- for line in lines:
- self.client.dataReceived(line + '\r\n')
- self.client.dataReceived(
- '0001 OK [READ-ONLY] %s completed\r\n' % (self.command,))
-
-
- def test_exists(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{EXISTS} response, the L{Deferred} return by L{IMAP4Client.select} or
- L{IMAP4Client.examine} fires with a C{dict} including the value
- associated with the C{'EXISTS'} key.
- """
- d = self._examineOrSelect()
- self._response('* 3 EXISTS')
- self.assertEqual(
- self._extractDeferredResult(d),
- {'READ-WRITE': False, 'EXISTS': 3})
-
-
- def test_nonIntegerExists(self):
- """
- If the server returns a non-integer EXISTS value in its response to a
- I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
- L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
- L{IllegalServerResponse}.
- """
- d = self._examineOrSelect()
- self._response('* foo EXISTS')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_recent(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{RECENT} response, the L{Deferred} return by L{IMAP4Client.select} or
- L{IMAP4Client.examine} fires with a C{dict} including the value
- associated with the C{'RECENT'} key.
- """
- d = self._examineOrSelect()
- self._response('* 5 RECENT')
- self.assertEqual(
- self._extractDeferredResult(d),
- {'READ-WRITE': False, 'RECENT': 5})
-
-
- def test_nonIntegerRecent(self):
- """
- If the server returns a non-integer RECENT value in its response to a
- I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
- L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
- L{IllegalServerResponse}.
- """
- d = self._examineOrSelect()
- self._response('* foo RECENT')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_unseen(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{UNSEEN} response, the L{Deferred} returned by L{IMAP4Client.select} or
- L{IMAP4Client.examine} fires with a C{dict} including the value
- associated with the C{'UNSEEN'} key.
- """
- d = self._examineOrSelect()
- self._response('* OK [UNSEEN 8] Message 8 is first unseen')
- self.assertEqual(
- self._extractDeferredResult(d),
- {'READ-WRITE': False, 'UNSEEN': 8})
-
-
- def test_nonIntegerUnseen(self):
- """
- If the server returns a non-integer UNSEEN value in its response to a
- I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
- L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
- L{IllegalServerResponse}.
- """
- d = self._examineOrSelect()
- self._response('* OK [UNSEEN foo] Message foo is first unseen')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_uidvalidity(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{UIDVALIDITY} response, the L{Deferred} returned by
- L{IMAP4Client.select} or L{IMAP4Client.examine} fires with a C{dict}
- including the value associated with the C{'UIDVALIDITY'} key.
- """
- d = self._examineOrSelect()
- self._response('* OK [UIDVALIDITY 12345] UIDs valid')
- self.assertEqual(
- self._extractDeferredResult(d),
- {'READ-WRITE': False, 'UIDVALIDITY': 12345})
-
-
- def test_nonIntegerUIDVALIDITY(self):
- """
- If the server returns a non-integer UIDVALIDITY value in its response to
- a I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
- L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
- L{IllegalServerResponse}.
- """
- d = self._examineOrSelect()
- self._response('* OK [UIDVALIDITY foo] UIDs valid')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_uidnext(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{UIDNEXT} response, the L{Deferred} returned by L{IMAP4Client.select}
- or L{IMAP4Client.examine} fires with a C{dict} including the value
- associated with the C{'UIDNEXT'} key.
- """
- d = self._examineOrSelect()
- self._response('* OK [UIDNEXT 4392] Predicted next UID')
- self.assertEqual(
- self._extractDeferredResult(d),
- {'READ-WRITE': False, 'UIDNEXT': 4392})
-
-
- def test_nonIntegerUIDNEXT(self):
- """
- If the server returns a non-integer UIDNEXT value in its response to a
- I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
- L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
- L{IllegalServerResponse}.
- """
- d = self._examineOrSelect()
- self._response('* OK [UIDNEXT foo] Predicted next UID')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_flags(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{FLAGS} response, the L{Deferred} returned by L{IMAP4Client.select} or
- L{IMAP4Client.examine} fires with a C{dict} including the value
- associated with the C{'FLAGS'} key.
- """
- d = self._examineOrSelect()
- self._response(
- '* FLAGS (\\Answered \\Flagged \\Deleted \\Seen \\Draft)')
- self.assertEqual(
- self._extractDeferredResult(d), {
- 'READ-WRITE': False,
- 'FLAGS': ('\\Answered', '\\Flagged', '\\Deleted', '\\Seen',
- '\\Draft')})
-
-
- def test_permanentflags(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{FLAGS} response, the L{Deferred} returned by L{IMAP4Client.select} or
- L{IMAP4Client.examine} fires with a C{dict} including the value
- associated with the C{'FLAGS'} key.
- """
- d = self._examineOrSelect()
- self._response(
- '* OK [PERMANENTFLAGS (\\Starred)] Just one permanent flag in '
- 'that list up there')
- self.assertEqual(
- self._extractDeferredResult(d), {
- 'READ-WRITE': False,
- 'PERMANENTFLAGS': ('\\Starred',)})
-
-
- def test_unrecognizedOk(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{OK} with unrecognized response code text, parsing does not fail.
- """
- d = self._examineOrSelect()
- self._response(
- '* OK [X-MADE-UP] I just made this response text up.')
- # The value won't show up in the result. It would be okay if it did
- # someday, perhaps. This shouldn't ever happen, though.
- self.assertEqual(
- self._extractDeferredResult(d), {'READ-WRITE': False})
-
-
- def test_bareOk(self):
- """
- If the server response to a I{SELECT} or I{EXAMINE} command includes an
- I{OK} with no response code text, parsing does not fail.
- """
- d = self._examineOrSelect()
- self._response('* OK')
- self.assertEqual(
- self._extractDeferredResult(d), {'READ-WRITE': False})
-
-
-
-class IMAP4ClientExamineTests(SelectionTestsMixin, unittest.TestCase):
- """
- Tests for the L{IMAP4Client.examine} method.
-
- An example of usage of the EXAMINE command from RFC 3501, section 6.3.2::
-
- S: * 17 EXISTS
- S: * 2 RECENT
- S: * OK [UNSEEN 8] Message 8 is first unseen
- S: * OK [UIDVALIDITY 3857529045] UIDs valid
- S: * OK [UIDNEXT 4392] Predicted next UID
- S: * FLAGS (\\Answered \\Flagged \\Deleted \\Seen \\Draft)
- S: * OK [PERMANENTFLAGS ()] No permanent flags permitted
- S: A932 OK [READ-ONLY] EXAMINE completed
- """
- method = 'examine'
- command = 'EXAMINE'
-
-
-
-
-class IMAP4ClientSelectTests(SelectionTestsMixin, unittest.TestCase):
- """
- Tests for the L{IMAP4Client.select} method.
-
- An example of usage of the SELECT command from RFC 3501, section 6.3.1::
-
- C: A142 SELECT INBOX
- S: * 172 EXISTS
- S: * 1 RECENT
- S: * OK [UNSEEN 12] Message 12 is first unseen
- S: * OK [UIDVALIDITY 3857529045] UIDs valid
- S: * OK [UIDNEXT 4392] Predicted next UID
- S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
- S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
- S: A142 OK [READ-WRITE] SELECT completed
- """
- method = 'select'
- command = 'SELECT'
-
-
-
-class IMAP4ClientExpungeTests(PreauthIMAP4ClientMixin, unittest.TestCase):
- """
- Tests for the L{IMAP4Client.expunge} method.
-
- An example of usage of the EXPUNGE command from RFC 3501, section 6.4.3::
-
- C: A202 EXPUNGE
- S: * 3 EXPUNGE
- S: * 3 EXPUNGE
- S: * 5 EXPUNGE
- S: * 8 EXPUNGE
- S: A202 OK EXPUNGE completed
- """
- def _expunge(self):
- d = self.client.expunge()
- self.assertEqual(self.transport.value(), '0001 EXPUNGE\r\n')
- self.transport.clear()
- return d
-
-
- def _response(self, sequenceNumbers):
- for number in sequenceNumbers:
- self.client.lineReceived('* %s EXPUNGE' % (number,))
- self.client.lineReceived('0001 OK EXPUNGE COMPLETED')
-
-
- def test_expunge(self):
- """
- L{IMAP4Client.expunge} sends the I{EXPUNGE} command and returns a
- L{Deferred} which fires with a C{list} of message sequence numbers
- given by the server's response.
- """
- d = self._expunge()
- self._response([3, 3, 5, 8])
- self.assertEqual(self._extractDeferredResult(d), [3, 3, 5, 8])
-
-
- def test_nonIntegerExpunged(self):
- """
- If the server responds with a non-integer where a message sequence
- number is expected, the L{Deferred} returned by L{IMAP4Client.expunge}
- fails with L{IllegalServerResponse}.
- """
- d = self._expunge()
- self._response([3, 3, 'foo', 8])
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
-
-class IMAP4ClientSearchTests(PreauthIMAP4ClientMixin, unittest.TestCase):
- """
- Tests for the L{IMAP4Client.search} method.
-
- An example of usage of the SEARCH command from RFC 3501, section 6.4.4::
-
- C: A282 SEARCH FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"
- S: * SEARCH 2 84 882
- S: A282 OK SEARCH completed
- C: A283 SEARCH TEXT "string not in mailbox"
- S: * SEARCH
- S: A283 OK SEARCH completed
- C: A284 SEARCH CHARSET UTF-8 TEXT {6}
- C: XXXXXX
- S: * SEARCH 43
- S: A284 OK SEARCH completed
- """
- def _search(self):
- d = self.client.search(imap4.Query(text="ABCDEF"))
- self.assertEqual(
- self.transport.value(), '0001 SEARCH (TEXT "ABCDEF")\r\n')
- return d
-
-
- def _response(self, messageNumbers):
- self.client.lineReceived(
- "* SEARCH " + " ".join(map(str, messageNumbers)))
- self.client.lineReceived("0001 OK SEARCH completed")
-
-
- def test_search(self):
- """
- L{IMAP4Client.search} sends the I{SEARCH} command and returns a
- L{Deferred} which fires with a C{list} of message sequence numbers
- given by the server's response.
- """
- d = self._search()
- self._response([2, 5, 10])
- self.assertEqual(self._extractDeferredResult(d), [2, 5, 10])
-
-
- def test_nonIntegerFound(self):
- """
- If the server responds with a non-integer where a message sequence
- number is expected, the L{Deferred} returned by L{IMAP4Client.search}
- fails with L{IllegalServerResponse}.
- """
- d = self._search()
- self._response([2, "foo", 10])
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
-
-class IMAP4ClientFetchTests(PreauthIMAP4ClientMixin, unittest.TestCase):
- """
- Tests for the L{IMAP4Client.fetch} method.
-
- See RFC 3501, section 6.4.5.
- """
- def test_fetchUID(self):
- """
- L{IMAP4Client.fetchUID} sends the I{FETCH UID} command and returns a
- L{Deferred} which fires with a C{dict} mapping message sequence numbers
- to C{dict}s mapping C{'UID'} to that message's I{UID} in the server's
- response.
- """
- d = self.client.fetchUID('1:7')
- self.assertEqual(self.transport.value(), '0001 FETCH 1:7 (UID)\r\n')
- self.client.lineReceived('* 2 FETCH (UID 22)')
- self.client.lineReceived('* 3 FETCH (UID 23)')
- self.client.lineReceived('* 4 FETCH (UID 24)')
- self.client.lineReceived('* 5 FETCH (UID 25)')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d), {
- 2: {'UID': '22'},
- 3: {'UID': '23'},
- 4: {'UID': '24'},
- 5: {'UID': '25'}})
-
-
- def test_fetchUIDNonIntegerFound(self):
- """
- If the server responds with a non-integer where a message sequence
- number is expected, the L{Deferred} returned by L{IMAP4Client.fetchUID}
- fails with L{IllegalServerResponse}.
- """
- d = self.client.fetchUID('1')
- self.assertEqual(self.transport.value(), '0001 FETCH 1 (UID)\r\n')
- self.client.lineReceived('* foo FETCH (UID 22)')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_incompleteFetchUIDResponse(self):
- """
- If the server responds with an incomplete I{FETCH} response line, the
- L{Deferred} returned by L{IMAP4Client.fetchUID} fails with
- L{IllegalServerResponse}.
- """
- d = self.client.fetchUID('1:7')
- self.assertEqual(self.transport.value(), '0001 FETCH 1:7 (UID)\r\n')
- self.client.lineReceived('* 2 FETCH (UID 22)')
- self.client.lineReceived('* 3 FETCH (UID)')
- self.client.lineReceived('* 4 FETCH (UID 24)')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_fetchBody(self):
- """
- L{IMAP4Client.fetchBody} sends the I{FETCH BODY} command and returns a
- L{Deferred} which fires with a C{dict} mapping message sequence numbers
- to C{dict}s mapping C{'RFC822.TEXT'} to that message's body as given in
- the server's response.
- """
- d = self.client.fetchBody('3')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 3 (RFC822.TEXT)\r\n')
- self.client.lineReceived('* 3 FETCH (RFC822.TEXT "Message text")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {3: {'RFC822.TEXT': 'Message text'}})
-
-
- def test_fetchSpecific(self):
- """
- L{IMAP4Client.fetchSpecific} sends the I{BODY[]} command if no
- parameters beyond the message set to retrieve are given. It returns a
- L{Deferred} which fires with a C{dict} mapping message sequence numbers
- to C{list}s of corresponding message data given by the server's
- response.
- """
- d = self.client.fetchSpecific('7')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 7 BODY[]\r\n')
- self.client.lineReceived('* 7 FETCH (BODY[] "Some body")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d), {7: [['BODY', [], "Some body"]]})
-
-
- def test_fetchSpecificPeek(self):
- """
- L{IMAP4Client.fetchSpecific} issues a I{BODY.PEEK[]} command if passed
- C{True} for the C{peek} parameter.
- """
- d = self.client.fetchSpecific('6', peek=True)
- self.assertEqual(
- self.transport.value(), '0001 FETCH 6 BODY.PEEK[]\r\n')
- # BODY.PEEK responses are just BODY
- self.client.lineReceived('* 6 FETCH (BODY[] "Some body")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d), {6: [['BODY', [], "Some body"]]})
-
-
- def test_fetchSpecificNumbered(self):
- """
- L{IMAP4Client.fetchSpecific}, when passed a sequence for for
- C{headerNumber}, sends the I{BODY[N.M]} command. It returns a
- L{Deferred} which fires with a C{dict} mapping message sequence numbers
- to C{list}s of corresponding message data given by the server's
- response.
- """
- d = self.client.fetchSpecific('7', headerNumber=(1, 2, 3))
- self.assertEqual(
- self.transport.value(), '0001 FETCH 7 BODY[1.2.3]\r\n')
- self.client.lineReceived('* 7 FETCH (BODY[1.2.3] "Some body")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {7: [['BODY', ['1.2.3'], "Some body"]]})
-
-
- def test_fetchSpecificText(self):
- """
- L{IMAP4Client.fetchSpecific}, when passed C{'TEXT'} for C{headerType},
- sends the I{BODY[TEXT]} command. It returns a L{Deferred} which fires
- with a C{dict} mapping message sequence numbers to C{list}s of
- corresponding message data given by the server's response.
- """
- d = self.client.fetchSpecific('8', headerType='TEXT')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 8 BODY[TEXT]\r\n')
- self.client.lineReceived('* 8 FETCH (BODY[TEXT] "Some body")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {8: [['BODY', ['TEXT'], "Some body"]]})
-
-
- def test_fetchSpecificNumberedText(self):
- """
- If passed a value for the C{headerNumber} parameter and C{'TEXT'} for
- the C{headerType} parameter, L{IMAP4Client.fetchSpecific} sends a
- I{BODY[number.TEXT]} request and returns a L{Deferred} which fires with
- a C{dict} mapping message sequence numbers to C{list}s of message data
- given by the server's response.
- """
- d = self.client.fetchSpecific('4', headerType='TEXT', headerNumber=7)
- self.assertEqual(
- self.transport.value(), '0001 FETCH 4 BODY[7.TEXT]\r\n')
- self.client.lineReceived('* 4 FETCH (BODY[7.TEXT] "Some body")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {4: [['BODY', ['7.TEXT'], "Some body"]]})
-
-
- def test_incompleteFetchSpecificTextResponse(self):
- """
- If the server responds to a I{BODY[TEXT]} request with a I{FETCH} line
- which is truncated after the I{BODY[TEXT]} tokens, the L{Deferred}
- returned by L{IMAP4Client.fetchUID} fails with
- L{IllegalServerResponse}.
- """
- d = self.client.fetchSpecific('8', headerType='TEXT')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 8 BODY[TEXT]\r\n')
- self.client.lineReceived('* 8 FETCH (BODY[TEXT])')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_fetchSpecificMIME(self):
- """
- L{IMAP4Client.fetchSpecific}, when passed C{'MIME'} for C{headerType},
- sends the I{BODY[MIME]} command. It returns a L{Deferred} which fires
- with a C{dict} mapping message sequence numbers to C{list}s of
- corresponding message data given by the server's response.
- """
- d = self.client.fetchSpecific('8', headerType='MIME')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 8 BODY[MIME]\r\n')
- self.client.lineReceived('* 8 FETCH (BODY[MIME] "Some body")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {8: [['BODY', ['MIME'], "Some body"]]})
-
-
- def test_fetchSpecificPartial(self):
- """
- L{IMAP4Client.fetchSpecific}, when passed C{offset} and C{length},
- sends a partial content request (like I{BODY[TEXT]<offset.length>}).
- It returns a L{Deferred} which fires with a C{dict} mapping message
- sequence numbers to C{list}s of corresponding message data given by the
- server's response.
- """
- d = self.client.fetchSpecific(
- '9', headerType='TEXT', offset=17, length=3)
- self.assertEqual(
- self.transport.value(), '0001 FETCH 9 BODY[TEXT]<17.3>\r\n')
- self.client.lineReceived('* 9 FETCH (BODY[TEXT]<17> "foo")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {9: [['BODY', ['TEXT'], '<17>', 'foo']]})
-
-
- def test_incompleteFetchSpecificPartialResponse(self):
- """
- If the server responds to a I{BODY[TEXT]} request with a I{FETCH} line
- which is truncated after the I{BODY[TEXT]<offset>} tokens, the
- L{Deferred} returned by L{IMAP4Client.fetchUID} fails with
- L{IllegalServerResponse}.
- """
- d = self.client.fetchSpecific('8', headerType='TEXT')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 8 BODY[TEXT]\r\n')
- self.client.lineReceived('* 8 FETCH (BODY[TEXT]<17>)')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertRaises(
- imap4.IllegalServerResponse, self._extractDeferredResult, d)
-
-
- def test_fetchSpecificHTML(self):
- """
- If the body of a message begins with I{<} and ends with I{>} (as,
- for example, HTML bodies typically will), this is still interpreted
- as the body by L{IMAP4Client.fetchSpecific} (and particularly, not
- as a length indicator for a response to a request for a partial
- body).
- """
- d = self.client.fetchSpecific('7')
- self.assertEqual(
- self.transport.value(), '0001 FETCH 7 BODY[]\r\n')
- self.client.lineReceived('* 7 FETCH (BODY[] "<html>test</html>")')
- self.client.lineReceived('0001 OK FETCH completed')
- self.assertEqual(
- self._extractDeferredResult(d), {7: [['BODY', [], "<html>test</html>"]]})
-
-
-
-class IMAP4ClientStoreTests(PreauthIMAP4ClientMixin, unittest.TestCase):
- """
- Tests for the L{IMAP4Client.setFlags}, L{IMAP4Client.addFlags}, and
- L{IMAP4Client.removeFlags} methods.
-
- An example of usage of the STORE command, in terms of which these three
- methods are implemented, from RFC 3501, section 6.4.6::
-
- C: A003 STORE 2:4 +FLAGS (\Deleted)
- S: * 2 FETCH (FLAGS (\Deleted \Seen))
- S: * 3 FETCH (FLAGS (\Deleted))
- S: * 4 FETCH (FLAGS (\Deleted \Flagged \Seen))
- S: A003 OK STORE completed
- """
- clientProtocol = StillSimplerClient
-
- def _flagsTest(self, method, item):
- """
- Test a non-silent flag modifying method. Call the method, assert that
- the correct bytes are sent, deliver a I{FETCH} response, and assert
- that the result of the Deferred returned by the method is correct.
-
- @param method: The name of the method to test.
- @param item: The data item which is expected to be specified.
- """
- d = getattr(self.client, method)('3', ('\\Read', '\\Seen'), False)
- self.assertEqual(
- self.transport.value(),
- '0001 STORE 3 ' + item + ' (\\Read \\Seen)\r\n')
- self.client.lineReceived('* 3 FETCH (FLAGS (\\Read \\Seen))')
- self.client.lineReceived('0001 OK STORE completed')
- self.assertEqual(
- self._extractDeferredResult(d),
- {3: {'FLAGS': ['\\Read', '\\Seen']}})
-
-
- def _flagsSilentlyTest(self, method, item):
- """
- Test a silent flag modifying method. Call the method, assert that the
- correct bytes are sent, deliver an I{OK} response, and assert that the
- result of the Deferred returned by the method is correct.
-
- @param method: The name of the method to test.
- @param item: The data item which is expected to be specified.
- """
- d = getattr(self.client, method)('3', ('\\Read', '\\Seen'), True)
- self.assertEqual(
- self.transport.value(),
- '0001 STORE 3 ' + item + ' (\\Read \\Seen)\r\n')
- self.client.lineReceived('0001 OK STORE completed')
- self.assertEqual(self._extractDeferredResult(d), {})
-
-
- def _flagsSilentlyWithUnsolicitedDataTest(self, method, item):
- """
- Test unsolicited data received in response to a silent flag modifying
- method. Call the method, assert that the correct bytes are sent,
- deliver the unsolicited I{FETCH} response, and assert that the result
- of the Deferred returned by the method is correct.
-
- @param method: The name of the method to test.
- @param item: The data item which is expected to be specified.
- """
- d = getattr(self.client, method)('3', ('\\Read', '\\Seen'), True)
- self.assertEqual(
- self.transport.value(),
- '0001 STORE 3 ' + item + ' (\\Read \\Seen)\r\n')
- self.client.lineReceived('* 2 FETCH (FLAGS (\\Read \\Seen))')
- self.client.lineReceived('0001 OK STORE completed')
- self.assertEqual(self._extractDeferredResult(d), {})
- self.assertEqual(self.client.flags, {2: ['\\Read', '\\Seen']})
-
-
- def test_setFlags(self):
- """
- When passed a C{False} value for the C{silent} parameter,
- L{IMAP4Client.setFlags} sends the I{STORE} command with a I{FLAGS} data
- item and returns a L{Deferred} which fires with a C{dict} mapping
- message sequence numbers to C{dict}s mapping C{'FLAGS'} to the new
- flags of those messages.
- """
- self._flagsTest('setFlags', 'FLAGS')
-
-
- def test_setFlagsSilently(self):
- """
- When passed a C{True} value for the C{silent} parameter,
- L{IMAP4Client.setFlags} sends the I{STORE} command with a
- I{FLAGS.SILENT} data item and returns a L{Deferred} which fires with an
- empty dictionary.
- """
- self._flagsSilentlyTest('setFlags', 'FLAGS.SILENT')
-
-
- def test_setFlagsSilentlyWithUnsolicitedData(self):
- """
- If unsolicited flag data is received in response to a I{STORE}
- I{FLAGS.SILENT} request, that data is passed to the C{flagsChanged}
- callback.
- """
- self._flagsSilentlyWithUnsolicitedDataTest('setFlags', 'FLAGS.SILENT')
-
-
- def test_addFlags(self):
- """
- L{IMAP4Client.addFlags} is like L{IMAP4Client.setFlags}, but sends
- I{+FLAGS} instead of I{FLAGS}.
- """
- self._flagsTest('addFlags', '+FLAGS')
-
-
- def test_addFlagsSilently(self):
- """
- L{IMAP4Client.addFlags} with a C{True} value for C{silent} behaves like
- L{IMAP4Client.setFlags} with a C{True} value for C{silent}, but it
- sends I{+FLAGS.SILENT} instead of I{FLAGS.SILENT}.
- """
- self._flagsSilentlyTest('addFlags', '+FLAGS.SILENT')
-
-
- def test_addFlagsSilentlyWithUnsolicitedData(self):
- """
- L{IMAP4Client.addFlags} behaves like L{IMAP4Client.setFlags} when used
- in silent mode and unsolicited data is received.
- """
- self._flagsSilentlyWithUnsolicitedDataTest('addFlags', '+FLAGS.SILENT')
-
-
- def test_removeFlags(self):
- """
- L{IMAP4Client.removeFlags} is like L{IMAP4Client.setFlags}, but sends
- I{-FLAGS} instead of I{FLAGS}.
- """
- self._flagsTest('removeFlags', '-FLAGS')
-
-
- def test_removeFlagsSilently(self):
- """
- L{IMAP4Client.removeFlags} with a C{True} value for C{silent} behaves
- like L{IMAP4Client.setFlags} with a C{True} value for C{silent}, but it
- sends I{-FLAGS.SILENT} instead of I{FLAGS.SILENT}.
- """
- self._flagsSilentlyTest('removeFlags', '-FLAGS.SILENT')
-
-
- def test_removeFlagsSilentlyWithUnsolicitedData(self):
- """
- L{IMAP4Client.removeFlags} behaves like L{IMAP4Client.setFlags} when
- used in silent mode and unsolicited data is received.
- """
- self._flagsSilentlyWithUnsolicitedDataTest('removeFlags', '-FLAGS.SILENT')
-
-
-
-class FakeyServer(imap4.IMAP4Server):
- state = 'select'
- timeout = None
-
- def sendServerGreeting(self):
- pass
-
-class FakeyMessage(util.FancyStrMixin):
- implements(imap4.IMessage)
-
- showAttributes = ('headers', 'flags', 'date', 'body', 'uid')
-
- def __init__(self, headers, flags, date, body, uid, subpart):
- self.headers = headers
- self.flags = flags
- self._body = body
- self.size = len(body)
- self.date = date
- self.uid = uid
- self.subpart = subpart
-
- def getHeaders(self, negate, *names):
- self.got_headers = negate, names
- return self.headers
-
- def getFlags(self):
- return self.flags
-
- def getInternalDate(self):
- return self.date
-
- def getBodyFile(self):
- return StringIO(self._body)
-
- def getSize(self):
- return self.size
-
- def getUID(self):
- return self.uid
-
- def isMultipart(self):
- return self.subpart is not None
-
- def getSubPart(self, part):
- self.got_subpart = part
- return self.subpart[part]
-
-class NewStoreTestCase(unittest.TestCase, IMAP4HelperMixin):
- result = None
- storeArgs = None
-
- def setUp(self):
- self.received_messages = self.received_uid = None
-
- self.server = imap4.IMAP4Server()
- self.server.state = 'select'
- self.server.mbox = self
- self.connected = defer.Deferred()
- self.client = SimpleClient(self.connected)
-
- def addListener(self, x):
- pass
- def removeListener(self, x):
- pass
-
- def store(self, *args, **kw):
- self.storeArgs = args, kw
- return self.response
-
- def _storeWork(self):
- def connected():
- return self.function(self.messages, self.flags, self.silent, self.uid)
- def result(R):
- self.result = R
-
- self.connected.addCallback(strip(connected)
- ).addCallback(result
- ).addCallback(self._cbStopClient
- ).addErrback(self._ebGeneral)
-
- def check(ignored):
- self.assertEqual(self.result, self.expected)
- self.assertEqual(self.storeArgs, self.expectedArgs)
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(check)
- return d
-
- def testSetFlags(self, uid=0):
- self.function = self.client.setFlags
- self.messages = '1,5,9'
- self.flags = ['\\A', '\\B', 'C']
- self.silent = False
- self.uid = uid
- self.response = {
- 1: ['\\A', '\\B', 'C'],
- 5: ['\\A', '\\B', 'C'],
- 9: ['\\A', '\\B', 'C'],
- }
- self.expected = {
- 1: {'FLAGS': ['\\A', '\\B', 'C']},
- 5: {'FLAGS': ['\\A', '\\B', 'C']},
- 9: {'FLAGS': ['\\A', '\\B', 'C']},
- }
- msg = imap4.MessageSet()
- msg.add(1)
- msg.add(5)
- msg.add(9)
- self.expectedArgs = ((msg, ['\\A', '\\B', 'C'], 0), {'uid': 0})
- return self._storeWork()
-
-
-
-class GetBodyStructureTests(unittest.TestCase):
- """
- Tests for L{imap4.getBodyStructure}, a helper for constructing a list which
- directly corresponds to the wire information needed for a I{BODY} or
- I{BODYSTRUCTURE} response.
- """
- def test_singlePart(self):
- """
- L{imap4.getBodyStructure} accepts a L{IMessagePart} provider and returns
- a list giving the basic fields for the I{BODY} response for that
- message.
- """
- body = 'hello, world'
- major = 'image'
- minor = 'jpeg'
- charset = 'us-ascii'
- identifier = 'some kind of id'
- description = 'great justice'
- encoding = 'maximum'
- msg = FakeyMessage({
- 'content-type': '%s/%s; charset=%s; x=y' % (
- major, minor, charset),
- 'content-id': identifier,
- 'content-description': description,
- 'content-transfer-encoding': encoding,
- }, (), '', body, 123, None)
- structure = imap4.getBodyStructure(msg)
- self.assertEqual(
- [major, minor, ["charset", charset, 'x', 'y'], identifier,
- description, encoding, len(body)],
- structure)
-
-
- def test_singlePartExtended(self):
- """
- L{imap4.getBodyStructure} returns a list giving the basic and extended
- fields for a I{BODYSTRUCTURE} response if passed C{True} for the
- C{extended} parameter.
- """
- body = 'hello, world'
- major = 'image'
- minor = 'jpeg'
- charset = 'us-ascii'
- identifier = 'some kind of id'
- description = 'great justice'
- encoding = 'maximum'
- md5 = 'abcdefabcdef'
- msg = FakeyMessage({
- 'content-type': '%s/%s; charset=%s; x=y' % (
- major, minor, charset),
- 'content-id': identifier,
- 'content-description': description,
- 'content-transfer-encoding': encoding,
- 'content-md5': md5,
- 'content-disposition': 'attachment; name=foo; size=bar',
- 'content-language': 'fr',
- 'content-location': 'France',
- }, (), '', body, 123, None)
- structure = imap4.getBodyStructure(msg, extended=True)
- self.assertEqual(
- [major, minor, ["charset", charset, 'x', 'y'], identifier,
- description, encoding, len(body), md5,
- ['attachment', ['name', 'foo', 'size', 'bar']], 'fr', 'France'],
- structure)
-
-
- def test_singlePartWithMissing(self):
- """
- For fields with no information contained in the message headers,
- L{imap4.getBodyStructure} fills in C{None} values in its result.
- """
- major = 'image'
- minor = 'jpeg'
- body = 'hello, world'
- msg = FakeyMessage({
- 'content-type': '%s/%s' % (major, minor),
- }, (), '', body, 123, None)
- structure = imap4.getBodyStructure(msg, extended=True)
- self.assertEqual(
- [major, minor, None, None, None, None, len(body), None, None,
- None, None],
- structure)
-
-
- def test_textPart(self):
- """
- For a I{text/*} message, the number of lines in the message body are
- included after the common single-part basic fields.
- """
- body = 'hello, world\nhow are you?\ngoodbye\n'
- major = 'text'
- minor = 'jpeg'
- charset = 'us-ascii'
- identifier = 'some kind of id'
- description = 'great justice'
- encoding = 'maximum'
- msg = FakeyMessage({
- 'content-type': '%s/%s; charset=%s; x=y' % (
- major, minor, charset),
- 'content-id': identifier,
- 'content-description': description,
- 'content-transfer-encoding': encoding,
- }, (), '', body, 123, None)
- structure = imap4.getBodyStructure(msg)
- self.assertEqual(
- [major, minor, ["charset", charset, 'x', 'y'], identifier,
- description, encoding, len(body), len(body.splitlines())],
- structure)
-
-
- def test_rfc822Message(self):
- """
- For a I{message/rfc822} message, the common basic fields are followed
- by information about the contained message.
- """
- body = 'hello, world\nhow are you?\ngoodbye\n'
- major = 'text'
- minor = 'jpeg'
- charset = 'us-ascii'
- identifier = 'some kind of id'
- description = 'great justice'
- encoding = 'maximum'
- msg = FakeyMessage({
- 'content-type': '%s/%s; charset=%s; x=y' % (
- major, minor, charset),
- 'from': 'Alice <alice@example.com>',
- 'to': 'Bob <bob@example.com>',
- 'content-id': identifier,
- 'content-description': description,
- 'content-transfer-encoding': encoding,
- }, (), '', body, 123, None)
-
- container = FakeyMessage({
- 'content-type': 'message/rfc822',
- }, (), '', '', 123, [msg])
-
- structure = imap4.getBodyStructure(container)
- self.assertEqual(
- ['message', 'rfc822', None, None, None, None, 0,
- imap4.getEnvelope(msg), imap4.getBodyStructure(msg), 3],
- structure)
-
-
- def test_multiPart(self):
- """
- For a I{multipart/*} message, L{imap4.getBodyStructure} returns a list
- containing the body structure information for each part of the message
- followed by an element giving the MIME subtype of the message.
- """
- oneSubPart = FakeyMessage({
- 'content-type': 'image/jpeg; x=y',
- 'content-id': 'some kind of id',
- 'content-description': 'great justice',
- 'content-transfer-encoding': 'maximum',
- }, (), '', 'hello world', 123, None)
-
- anotherSubPart = FakeyMessage({
- 'content-type': 'text/plain; charset=us-ascii',
- }, (), '', 'some stuff', 321, None)
-
- container = FakeyMessage({
- 'content-type': 'multipart/related',
- }, (), '', '', 555, [oneSubPart, anotherSubPart])
-
- self.assertEqual(
- [imap4.getBodyStructure(oneSubPart),
- imap4.getBodyStructure(anotherSubPart),
- 'related'],
- imap4.getBodyStructure(container))
-
-
- def test_multiPartExtended(self):
- """
- When passed a I{multipart/*} message and C{True} for the C{extended}
- argument, L{imap4.getBodyStructure} includes extended structure
- information from the parts of the multipart message and extended
- structure information about the multipart message itself.
- """
- oneSubPart = FakeyMessage({
- 'content-type': 'image/jpeg; x=y',
- 'content-id': 'some kind of id',
- 'content-description': 'great justice',
- 'content-transfer-encoding': 'maximum',
- }, (), '', 'hello world', 123, None)
-
- anotherSubPart = FakeyMessage({
- 'content-type': 'text/plain; charset=us-ascii',
- }, (), '', 'some stuff', 321, None)
-
- container = FakeyMessage({
- 'content-type': 'multipart/related; foo=bar',
- 'content-language': 'es',
- 'content-location': 'Spain',
- 'content-disposition': 'attachment; name=monkeys',
- }, (), '', '', 555, [oneSubPart, anotherSubPart])
-
- self.assertEqual(
- [imap4.getBodyStructure(oneSubPart, extended=True),
- imap4.getBodyStructure(anotherSubPart, extended=True),
- 'related', ['foo', 'bar'], ['attachment', ['name', 'monkeys']],
- 'es', 'Spain'],
- imap4.getBodyStructure(container, extended=True))
-
-
-
-class NewFetchTestCase(unittest.TestCase, IMAP4HelperMixin):
- def setUp(self):
- self.received_messages = self.received_uid = None
- self.result = None
-
- self.server = imap4.IMAP4Server()
- self.server.state = 'select'
- self.server.mbox = self
- self.connected = defer.Deferred()
- self.client = SimpleClient(self.connected)
-
- def addListener(self, x):
- pass
- def removeListener(self, x):
- pass
-
- def fetch(self, messages, uid):
- self.received_messages = messages
- self.received_uid = uid
- return iter(zip(range(len(self.msgObjs)), self.msgObjs))
-
- def _fetchWork(self, uid):
- if uid:
- for (i, msg) in zip(range(len(self.msgObjs)), self.msgObjs):
- self.expected[i]['UID'] = str(msg.getUID())
-
- def result(R):
- self.result = R
-
- self.connected.addCallback(lambda _: self.function(self.messages, uid)
- ).addCallback(result
- ).addCallback(self._cbStopClient
- ).addErrback(self._ebGeneral)
-
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(lambda x : self.assertEqual(self.result, self.expected))
- return d
-
- def testFetchUID(self):
- self.function = lambda m, u: self.client.fetchUID(m)
-
- self.messages = '7'
- self.msgObjs = [
- FakeyMessage({}, (), '', '', 12345, None),
- FakeyMessage({}, (), '', '', 999, None),
- FakeyMessage({}, (), '', '', 10101, None),
- ]
- self.expected = {
- 0: {'UID': '12345'},
- 1: {'UID': '999'},
- 2: {'UID': '10101'},
- }
- return self._fetchWork(0)
-
- def testFetchFlags(self, uid=0):
- self.function = self.client.fetchFlags
- self.messages = '9'
- self.msgObjs = [
- FakeyMessage({}, ['FlagA', 'FlagB', '\\FlagC'], '', '', 54321, None),
- FakeyMessage({}, ['\\FlagC', 'FlagA', 'FlagB'], '', '', 12345, None),
- ]
- self.expected = {
- 0: {'FLAGS': ['FlagA', 'FlagB', '\\FlagC']},
- 1: {'FLAGS': ['\\FlagC', 'FlagA', 'FlagB']},
- }
- return self._fetchWork(uid)
-
- def testFetchFlagsUID(self):
- return self.testFetchFlags(1)
-
- def testFetchInternalDate(self, uid=0):
- self.function = self.client.fetchInternalDate
- self.messages = '13'
- self.msgObjs = [
- FakeyMessage({}, (), 'Fri, 02 Nov 2003 21:25:10 GMT', '', 23232, None),
- FakeyMessage({}, (), 'Thu, 29 Dec 2013 11:31:52 EST', '', 101, None),
- FakeyMessage({}, (), 'Mon, 10 Mar 1992 02:44:30 CST', '', 202, None),
- FakeyMessage({}, (), 'Sat, 11 Jan 2000 14:40:24 PST', '', 303, None),
- ]
- self.expected = {
- 0: {'INTERNALDATE': '02-Nov-2003 21:25:10 +0000'},
- 1: {'INTERNALDATE': '29-Dec-2013 11:31:52 -0500'},
- 2: {'INTERNALDATE': '10-Mar-1992 02:44:30 -0600'},
- 3: {'INTERNALDATE': '11-Jan-2000 14:40:24 -0800'},
- }
- return self._fetchWork(uid)
-
- def testFetchInternalDateUID(self):
- return self.testFetchInternalDate(1)
-
-
- def test_fetchInternalDateLocaleIndependent(self):
- """
- The month name in the date is locale independent.
- """
- # Fake that we're in a language where December is not Dec
- currentLocale = locale.setlocale(locale.LC_ALL, None)
- locale.setlocale(locale.LC_ALL, "es_AR.UTF8")
- self.addCleanup(locale.setlocale, locale.LC_ALL, currentLocale)
- return self.testFetchInternalDate(1)
-
- # if alternate locale is not available, the previous test will be skipped,
- # please install this locale for it to run. Avoid using locale.getlocale to
- # learn the current locale; its values don't round-trip well on all
- # platforms. Fortunately setlocale returns a value which does round-trip
- # well.
- currentLocale = locale.setlocale(locale.LC_ALL, None)
- try:
- locale.setlocale(locale.LC_ALL, "es_AR.UTF8")
- except locale.Error:
- test_fetchInternalDateLocaleIndependent.skip = (
- "The es_AR.UTF8 locale is not installed.")
- else:
- locale.setlocale(locale.LC_ALL, currentLocale)
-
-
- def testFetchEnvelope(self, uid=0):
- self.function = self.client.fetchEnvelope
- self.messages = '15'
- self.msgObjs = [
- FakeyMessage({
- 'from': 'user@domain', 'to': 'resu@domain',
- 'date': 'thursday', 'subject': 'it is a message',
- 'message-id': 'id-id-id-yayaya'}, (), '', '', 65656,
- None),
- ]
- self.expected = {
- 0: {'ENVELOPE':
- ['thursday', 'it is a message',
- [[None, None, 'user', 'domain']],
- [[None, None, 'user', 'domain']],
- [[None, None, 'user', 'domain']],
- [[None, None, 'resu', 'domain']],
- None, None, None, 'id-id-id-yayaya']
- }
- }
- return self._fetchWork(uid)
-
- def testFetchEnvelopeUID(self):
- return self.testFetchEnvelope(1)
-
-
- def test_fetchBodyStructure(self, uid=0):
- """
- L{IMAP4Client.fetchBodyStructure} issues a I{FETCH BODYSTRUCTURE}
- command and returns a Deferred which fires with a structure giving the
- result of parsing the server's response. The structure is a list
- reflecting the parenthesized data sent by the server, as described by
- RFC 3501, section 7.4.2.
- """
- self.function = self.client.fetchBodyStructure
- self.messages = '3:9,10:*'
- self.msgObjs = [FakeyMessage({
- 'content-type': 'text/plain; name=thing; key="value"',
- 'content-id': 'this-is-the-content-id',
- 'content-description': 'describing-the-content-goes-here!',
- 'content-transfer-encoding': '8BIT',
- 'content-md5': 'abcdef123456',
- 'content-disposition': 'attachment; filename=monkeys',
- 'content-language': 'es',
- 'content-location': 'http://example.com/monkeys',
- }, (), '', 'Body\nText\nGoes\nHere\n', 919293, None)]
- self.expected = {0: {'BODYSTRUCTURE': [
- 'text', 'plain', ['key', 'value', 'name', 'thing'],
- 'this-is-the-content-id', 'describing-the-content-goes-here!',
- '8BIT', '20', '4', 'abcdef123456',
- ['attachment', ['filename', 'monkeys']], 'es',
- 'http://example.com/monkeys']}}
- return self._fetchWork(uid)
-
-
- def testFetchBodyStructureUID(self):
- """
- If passed C{True} for the C{uid} argument, C{fetchBodyStructure} can
- also issue a I{UID FETCH BODYSTRUCTURE} command.
- """
- return self.test_fetchBodyStructure(1)
-
-
- def test_fetchBodyStructureMultipart(self, uid=0):
- """
- L{IMAP4Client.fetchBodyStructure} can also parse the response to a
- I{FETCH BODYSTRUCTURE} command for a multipart message.
- """
- self.function = self.client.fetchBodyStructure
- self.messages = '3:9,10:*'
- innerMessage = FakeyMessage({
- 'content-type': 'text/plain; name=thing; key="value"',
- 'content-id': 'this-is-the-content-id',
- 'content-description': 'describing-the-content-goes-here!',
- 'content-transfer-encoding': '8BIT',
- 'content-language': 'fr',
- 'content-md5': '123456abcdef',
- 'content-disposition': 'inline',
- 'content-location': 'outer space',
- }, (), '', 'Body\nText\nGoes\nHere\n', 919293, None)
- self.msgObjs = [FakeyMessage({
- 'content-type': 'multipart/mixed; boundary="xyz"',
- 'content-language': 'en',
- 'content-location': 'nearby',
- }, (), '', '', 919293, [innerMessage])]
- self.expected = {0: {'BODYSTRUCTURE': [
- ['text', 'plain', ['key', 'value', 'name', 'thing'],
- 'this-is-the-content-id', 'describing-the-content-goes-here!',
- '8BIT', '20', '4', '123456abcdef', ['inline', None], 'fr',
- 'outer space'],
- 'mixed', ['boundary', 'xyz'], None, 'en', 'nearby'
- ]}}
- return self._fetchWork(uid)
-
-
- def testFetchSimplifiedBody(self, uid=0):
- self.function = self.client.fetchSimplifiedBody
- self.messages = '21'
- self.msgObjs = [FakeyMessage({}, (), '', 'Yea whatever', 91825,
- [FakeyMessage({'content-type': 'image/jpg'}, (), '',
- 'Body Body Body', None, None
- )]
- )]
- self.expected = {0:
- {'BODY':
- [None, None, None, None, None, None,
- '12'
- ]
- }
- }
-
- return self._fetchWork(uid)
-
- def testFetchSimplifiedBodyUID(self):
- return self.testFetchSimplifiedBody(1)
-
- def testFetchSimplifiedBodyText(self, uid=0):
- self.function = self.client.fetchSimplifiedBody
- self.messages = '21'
- self.msgObjs = [FakeyMessage({'content-type': 'text/plain'},
- (), '', 'Yea whatever', 91825, None)]
- self.expected = {0:
- {'BODY':
- ['text', 'plain', None, None, None, None,
- '12', '1'
- ]
- }
- }
-
- return self._fetchWork(uid)
-
- def testFetchSimplifiedBodyTextUID(self):
- return self.testFetchSimplifiedBodyText(1)
-
- def testFetchSimplifiedBodyRFC822(self, uid=0):
- self.function = self.client.fetchSimplifiedBody
- self.messages = '21'
- self.msgObjs = [FakeyMessage({'content-type': 'message/rfc822'},
- (), '', 'Yea whatever', 91825,
- [FakeyMessage({'content-type': 'image/jpg'}, (), '',
- 'Body Body Body', None, None
- )]
- )]
- self.expected = {0:
- {'BODY':
- ['message', 'rfc822', None, None, None, None,
- '12', [None, None, [[None, None, None]],
- [[None, None, None]], None, None, None,
- None, None, None], ['image', 'jpg', None,
- None, None, None, '14'], '1'
- ]
- }
- }
-
- return self._fetchWork(uid)
-
- def testFetchSimplifiedBodyRFC822UID(self):
- return self.testFetchSimplifiedBodyRFC822(1)
-
- def testFetchMessage(self, uid=0):
- self.function = self.client.fetchMessage
- self.messages = '1,3,7,10101'
- self.msgObjs = [
- FakeyMessage({'Header': 'Value'}, (), '', 'BODY TEXT\r\n', 91, None),
- ]
- self.expected = {
- 0: {'RFC822': 'Header: Value\r\n\r\nBODY TEXT\r\n'}
- }
- return self._fetchWork(uid)
-
- def testFetchMessageUID(self):
- return self.testFetchMessage(1)
-
- def testFetchHeaders(self, uid=0):
- self.function = self.client.fetchHeaders
- self.messages = '9,6,2'
- self.msgObjs = [
- FakeyMessage({'H1': 'V1', 'H2': 'V2'}, (), '', '', 99, None),
- ]
- self.expected = {
- 0: {'RFC822.HEADER': imap4._formatHeaders({'H1': 'V1', 'H2': 'V2'})},
- }
- return self._fetchWork(uid)
-
- def testFetchHeadersUID(self):
- return self.testFetchHeaders(1)
-
- def testFetchBody(self, uid=0):
- self.function = self.client.fetchBody
- self.messages = '1,2,3,4,5,6,7'
- self.msgObjs = [
- FakeyMessage({'Header': 'Value'}, (), '', 'Body goes here\r\n', 171, None),
- ]
- self.expected = {
- 0: {'RFC822.TEXT': 'Body goes here\r\n'},
- }
- return self._fetchWork(uid)
-
- def testFetchBodyUID(self):
- return self.testFetchBody(1)
-
- def testFetchBodyParts(self):
- """
- Test the server's handling of requests for specific body sections.
- """
- self.function = self.client.fetchSpecific
- self.messages = '1'
- outerBody = ''
- innerBody1 = 'Contained body message text. Squarge.'
- innerBody2 = 'Secondary <i>message</i> text of squarge body.'
- headers = util.OrderedDict()
- headers['from'] = 'sender@host'
- headers['to'] = 'recipient@domain'
- headers['subject'] = 'booga booga boo'
- headers['content-type'] = 'multipart/alternative; boundary="xyz"'
- innerHeaders = util.OrderedDict()
- innerHeaders['subject'] = 'this is subject text'
- innerHeaders['content-type'] = 'text/plain'
- innerHeaders2 = util.OrderedDict()
- innerHeaders2['subject'] = '<b>this is subject</b>'
- innerHeaders2['content-type'] = 'text/html'
- self.msgObjs = [FakeyMessage(
- headers, (), None, outerBody, 123,
- [FakeyMessage(innerHeaders, (), None, innerBody1, None, None),
- FakeyMessage(innerHeaders2, (), None, innerBody2, None, None)])]
- self.expected = {
- 0: [['BODY', ['1'], 'Contained body message text. Squarge.']]}
-
- def result(R):
- self.result = R
-
- self.connected.addCallback(
- lambda _: self.function(self.messages, headerNumber=1))
- self.connected.addCallback(result)
- self.connected.addCallback(self._cbStopClient)
- self.connected.addErrback(self._ebGeneral)
-
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(lambda ign: self.assertEqual(self.result, self.expected))
- return d
-
-
- def test_fetchBodyPartOfNonMultipart(self):
- """
- Single-part messages have an implicit first part which clients
- should be able to retrieve explicitly. Test that a client
- requesting part 1 of a text/plain message receives the body of the
- text/plain part.
- """
- self.function = self.client.fetchSpecific
- self.messages = '1'
- parts = [1]
- outerBody = 'DA body'
- headers = util.OrderedDict()
- headers['from'] = 'sender@host'
- headers['to'] = 'recipient@domain'
- headers['subject'] = 'booga booga boo'
- headers['content-type'] = 'text/plain'
- self.msgObjs = [FakeyMessage(
- headers, (), None, outerBody, 123, None)]
-
- self.expected = {0: [['BODY', ['1'], 'DA body']]}
-
- def result(R):
- self.result = R
-
- self.connected.addCallback(
- lambda _: self.function(self.messages, headerNumber=parts))
- self.connected.addCallback(result)
- self.connected.addCallback(self._cbStopClient)
- self.connected.addErrback(self._ebGeneral)
-
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(lambda ign: self.assertEqual(self.result, self.expected))
- return d
-
-
- def testFetchSize(self, uid=0):
- self.function = self.client.fetchSize
- self.messages = '1:100,2:*'
- self.msgObjs = [
- FakeyMessage({}, (), '', 'x' * 20, 123, None),
- ]
- self.expected = {
- 0: {'RFC822.SIZE': '20'},
- }
- return self._fetchWork(uid)
-
- def testFetchSizeUID(self):
- return self.testFetchSize(1)
-
- def testFetchFull(self, uid=0):
- self.function = self.client.fetchFull
- self.messages = '1,3'
- self.msgObjs = [
- FakeyMessage({}, ('\\XYZ', '\\YZX', 'Abc'),
- 'Sun, 25 Jul 2010 06:20:30 -0400 (EDT)',
- 'xyz' * 2, 654, None),
- FakeyMessage({}, ('\\One', '\\Two', 'Three'),
- 'Mon, 14 Apr 2003 19:43:44 -0400',
- 'abc' * 4, 555, None),
- ]
- self.expected = {
- 0: {'FLAGS': ['\\XYZ', '\\YZX', 'Abc'],
- 'INTERNALDATE': '25-Jul-2010 06:20:30 -0400',
- 'RFC822.SIZE': '6',
- 'ENVELOPE': [None, None, [[None, None, None]], [[None, None, None]], None, None, None, None, None, None],
- 'BODY': [None, None, None, None, None, None, '6']},
- 1: {'FLAGS': ['\\One', '\\Two', 'Three'],
- 'INTERNALDATE': '14-Apr-2003 19:43:44 -0400',
- 'RFC822.SIZE': '12',
- 'ENVELOPE': [None, None, [[None, None, None]], [[None, None, None]], None, None, None, None, None, None],
- 'BODY': [None, None, None, None, None, None, '12']},
- }
- return self._fetchWork(uid)
-
- def testFetchFullUID(self):
- return self.testFetchFull(1)
-
- def testFetchAll(self, uid=0):
- self.function = self.client.fetchAll
- self.messages = '1,2:3'
- self.msgObjs = [
- FakeyMessage({}, (), 'Mon, 14 Apr 2003 19:43:44 +0400',
- 'Lalala', 10101, None),
- FakeyMessage({}, (), 'Tue, 15 Apr 2003 19:43:44 +0200',
- 'Alalal', 20202, None),
- ]
- self.expected = {
- 0: {'ENVELOPE': [None, None, [[None, None, None]], [[None, None, None]], None, None, None, None, None, None],
- 'RFC822.SIZE': '6',
- 'INTERNALDATE': '14-Apr-2003 19:43:44 +0400',
- 'FLAGS': []},
- 1: {'ENVELOPE': [None, None, [[None, None, None]], [[None, None, None]], None, None, None, None, None, None],
- 'RFC822.SIZE': '6',
- 'INTERNALDATE': '15-Apr-2003 19:43:44 +0200',
- 'FLAGS': []},
- }
- return self._fetchWork(uid)
-
- def testFetchAllUID(self):
- return self.testFetchAll(1)
-
- def testFetchFast(self, uid=0):
- self.function = self.client.fetchFast
- self.messages = '1'
- self.msgObjs = [
- FakeyMessage({}, ('\\X',), '19 Mar 2003 19:22:21 -0500', '', 9, None),
- ]
- self.expected = {
- 0: {'FLAGS': ['\\X'],
- 'INTERNALDATE': '19-Mar-2003 19:22:21 -0500',
- 'RFC822.SIZE': '0'},
- }
- return self._fetchWork(uid)
-
- def testFetchFastUID(self):
- return self.testFetchFast(1)
-
-
-
-class DefaultSearchTestCase(IMAP4HelperMixin, unittest.TestCase):
- """
- Test the behavior of the server's SEARCH implementation, particularly in
- the face of unhandled search terms.
- """
- def setUp(self):
- self.server = imap4.IMAP4Server()
- self.server.state = 'select'
- self.server.mbox = self
- self.connected = defer.Deferred()
- self.client = SimpleClient(self.connected)
- self.msgObjs = [
- FakeyMessage({}, (), '', '', 999, None),
- FakeyMessage({}, (), '', '', 10101, None),
- FakeyMessage({}, (), '', '', 12345, None),
- FakeyMessage({}, (), '', '', 20001, None),
- FakeyMessage({}, (), '', '', 20002, None),
- ]
-
-
- def fetch(self, messages, uid):
- """
- Pretend to be a mailbox and let C{self.server} lookup messages on me.
- """
- return zip(range(1, len(self.msgObjs) + 1), self.msgObjs)
-
-
- def _messageSetSearchTest(self, queryTerms, expectedMessages):
- """
- Issue a search with given query and verify that the returned messages
- match the given expected messages.
-
- @param queryTerms: A string giving the search query.
- @param expectedMessages: A list of the message sequence numbers
- expected as the result of the search.
- @return: A L{Deferred} which fires when the test is complete.
- """
- def search():
- return self.client.search(queryTerms)
-
- d = self.connected.addCallback(strip(search))
- def searched(results):
- self.assertEqual(results, expectedMessages)
- d.addCallback(searched)
- d.addCallback(self._cbStopClient)
- d.addErrback(self._ebGeneral)
- self.loopback()
- return d
-
-
- def test_searchMessageSet(self):
- """
- Test that a search which starts with a message set properly limits
- the search results to messages in that set.
- """
- return self._messageSetSearchTest('1', [1])
-
-
- def test_searchMessageSetWithStar(self):
- """
- If the search filter ends with a star, all the message from the
- starting point are returned.
- """
- return self._messageSetSearchTest('2:*', [2, 3, 4, 5])
-
-
- def test_searchMessageSetWithStarFirst(self):
- """
- If the search filter starts with a star, the result should be identical
- with if the filter would end with a star.
- """
- return self._messageSetSearchTest('*:2', [2, 3, 4, 5])
-
-
- def test_searchMessageSetUIDWithStar(self):
- """
- If the search filter ends with a star, all the message from the
- starting point are returned (also for the SEARCH UID case).
- """
- return self._messageSetSearchTest('UID 10000:*', [2, 3, 4, 5])
-
-
- def test_searchMessageSetUIDWithStarFirst(self):
- """
- If the search filter starts with a star, the result should be identical
- with if the filter would end with a star (also for the SEARCH UID case).
- """
- return self._messageSetSearchTest('UID *:10000', [2, 3, 4, 5])
-
-
- def test_searchMessageSetUIDWithStarAndHighStart(self):
- """
- A search filter of 1234:* should include the UID of the last message in
- the mailbox, even if its UID is less than 1234.
- """
- # in our fake mbox the highest message UID is 20002
- return self._messageSetSearchTest('UID 30000:*', [5])
-
-
- def test_searchMessageSetWithList(self):
- """
- If the search filter contains nesting terms, one of which includes a
- message sequence set with a wildcard, IT ALL WORKS GOOD.
- """
- # 6 is bigger than the biggest message sequence number, but that's
- # okay, because N:* includes the biggest message sequence number even
- # if N is bigger than that (read the rfc nub).
- return self._messageSetSearchTest('(6:*)', [5])
-
-
- def test_searchOr(self):
- """
- If the search filter contains an I{OR} term, all messages
- which match either subexpression are returned.
- """
- return self._messageSetSearchTest('OR 1 2', [1, 2])
-
-
- def test_searchOrMessageSet(self):
- """
- If the search filter contains an I{OR} term with a
- subexpression which includes a message sequence set wildcard,
- all messages in that set are considered for inclusion in the
- results.
- """
- return self._messageSetSearchTest('OR 2:* 2:*', [2, 3, 4, 5])
-
-
- def test_searchNot(self):
- """
- If the search filter contains a I{NOT} term, all messages
- which do not match the subexpression are returned.
- """
- return self._messageSetSearchTest('NOT 3', [1, 2, 4, 5])
-
-
- def test_searchNotMessageSet(self):
- """
- If the search filter contains a I{NOT} term with a
- subexpression which includes a message sequence set wildcard,
- no messages in that set are considered for inclusion in the
- result.
- """
- return self._messageSetSearchTest('NOT 2:*', [1])
-
-
- def test_searchAndMessageSet(self):
- """
- If the search filter contains multiple terms implicitly
- conjoined with a message sequence set wildcard, only the
- intersection of the results of each term are returned.
- """
- return self._messageSetSearchTest('2:* 3', [3])
-
- def test_searchInvalidCriteria(self):
- """
- If the search criteria is not a valid key, a NO result is returned to
- the client (resulting in an error callback), and an IllegalQueryError is
- logged on the server side.
- """
- queryTerms = 'FOO'
- def search():
- return self.client.search(queryTerms)
-
- d = self.connected.addCallback(strip(search))
- d = self.assertFailure(d, imap4.IMAP4Exception)
-
- def errorReceived(results):
- """
- Verify that the server logs an IllegalQueryError and the
- client raises an IMAP4Exception with 'Search failed:...'
- """
- self.client.transport.loseConnection()
- self.server.transport.loseConnection()
-
- # Check what the server logs
- errors = self.flushLoggedErrors(imap4.IllegalQueryError)
- self.assertEqual(len(errors), 1)
-
- # Verify exception given to client has the correct message
- self.assertEqual(
- "SEARCH failed: Invalid search command FOO", str(results))
-
- d.addCallback(errorReceived)
- d.addErrback(self._ebGeneral)
- self.loopback()
- return d
-
-
-
-class FetchSearchStoreTestCase(unittest.TestCase, IMAP4HelperMixin):
- implements(imap4.ISearchableMailbox)
-
- def setUp(self):
- self.expected = self.result = None
- self.server_received_query = None
- self.server_received_uid = None
- self.server_received_parts = None
- self.server_received_messages = None
-
- self.server = imap4.IMAP4Server()
- self.server.state = 'select'
- self.server.mbox = self
- self.connected = defer.Deferred()
- self.client = SimpleClient(self.connected)
-
- def search(self, query, uid):
- # Look for a specific bad query, so we can verify we handle it properly
- if query == ['FOO']:
- raise imap4.IllegalQueryError("FOO is not a valid search criteria")
-
- self.server_received_query = query
- self.server_received_uid = uid
- return self.expected
-
- def addListener(self, *a, **kw):
- pass
- removeListener = addListener
-
- def _searchWork(self, uid):
- def search():
- return self.client.search(self.query, uid=uid)
- def result(R):
- self.result = R
-
- self.connected.addCallback(strip(search)
- ).addCallback(result
- ).addCallback(self._cbStopClient
- ).addErrback(self._ebGeneral)
-
- def check(ignored):
- # Ensure no short-circuiting wierdness is going on
- self.failIf(self.result is self.expected)
-
- self.assertEqual(self.result, self.expected)
- self.assertEqual(self.uid, self.server_received_uid)
- self.assertEqual(
- imap4.parseNestedParens(self.query),
- self.server_received_query
- )
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(check)
- return d
-
- def testSearch(self):
- self.query = imap4.Or(
- imap4.Query(header=('subject', 'substring')),
- imap4.Query(larger=1024, smaller=4096),
- )
- self.expected = [1, 4, 5, 7]
- self.uid = 0
- return self._searchWork(0)
-
- def testUIDSearch(self):
- self.query = imap4.Or(
- imap4.Query(header=('subject', 'substring')),
- imap4.Query(larger=1024, smaller=4096),
- )
- self.uid = 1
- self.expected = [1, 2, 3]
- return self._searchWork(1)
-
- def getUID(self, msg):
- try:
- return self.expected[msg]['UID']
- except (TypeError, IndexError):
- return self.expected[msg-1]
- except KeyError:
- return 42
-
- def fetch(self, messages, uid):
- self.server_received_uid = uid
- self.server_received_messages = str(messages)
- return self.expected
-
- def _fetchWork(self, fetch):
- def result(R):
- self.result = R
-
- self.connected.addCallback(strip(fetch)
- ).addCallback(result
- ).addCallback(self._cbStopClient
- ).addErrback(self._ebGeneral)
-
- def check(ignored):
- # Ensure no short-circuiting wierdness is going on
- self.failIf(self.result is self.expected)
-
- self.parts and self.parts.sort()
- self.server_received_parts and self.server_received_parts.sort()
-
- if self.uid:
- for (k, v) in self.expected.items():
- v['UID'] = str(k)
-
- self.assertEqual(self.result, self.expected)
- self.assertEqual(self.uid, self.server_received_uid)
- self.assertEqual(self.parts, self.server_received_parts)
- self.assertEqual(imap4.parseIdList(self.messages),
- imap4.parseIdList(self.server_received_messages))
-
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(check)
- return d
-
-
- def test_invalidTerm(self):
- """
- If, as part of a search, an ISearchableMailbox raises an
- IllegalQueryError (e.g. due to invalid search criteria), client sees a
- failure response, and an IllegalQueryError is logged on the server.
- """
- query = 'FOO'
-
- def search():
- return self.client.search(query)
-
- d = self.connected.addCallback(strip(search))
- d = self.assertFailure(d, imap4.IMAP4Exception)
-
- def errorReceived(results):
- """
- Verify that the server logs an IllegalQueryError and the
- client raises an IMAP4Exception with 'Search failed:...'
- """
- self.client.transport.loseConnection()
- self.server.transport.loseConnection()
-
- # Check what the server logs
- errors = self.flushLoggedErrors(imap4.IllegalQueryError)
- self.assertEqual(len(errors), 1)
-
- # Verify exception given to client has the correct message
- self.assertEqual(
- "SEARCH failed: FOO is not a valid search criteria",
- str(results))
-
- d.addCallback(errorReceived)
- d.addErrback(self._ebGeneral)
- self.loopback()
- return d
-
-
-
-class FakeMailbox:
- def __init__(self):
- self.args = []
- def addMessage(self, body, flags, date):
- self.args.append((body, flags, date))
- return defer.succeed(None)
-
-class FeaturefulMessage:
- implements(imap4.IMessageFile)
-
- def getFlags(self):
- return 'flags'
-
- def getInternalDate(self):
- return 'internaldate'
-
- def open(self):
- return StringIO("open")
-
-class MessageCopierMailbox:
- implements(imap4.IMessageCopier)
-
- def __init__(self):
- self.msgs = []
-
- def copy(self, msg):
- self.msgs.append(msg)
- return len(self.msgs)
-
-class CopyWorkerTestCase(unittest.TestCase):
- def testFeaturefulMessage(self):
- s = imap4.IMAP4Server()
-
- # Yes. I am grabbing this uber-non-public method to test it.
- # It is complex. It needs to be tested directly!
- # Perhaps it should be refactored, simplified, or split up into
- # not-so-private components, but that is a task for another day.
-
- # Ha ha! Addendum! Soon it will be split up, and this test will
- # be re-written to just use the default adapter for IMailbox to
- # IMessageCopier and call .copy on that adapter.
- f = s._IMAP4Server__cbCopy
-
- m = FakeMailbox()
- d = f([(i, FeaturefulMessage()) for i in range(1, 11)], 'tag', m)
-
- def cbCopy(results):
- for a in m.args:
- self.assertEqual(a[0].read(), "open")
- self.assertEqual(a[1], "flags")
- self.assertEqual(a[2], "internaldate")
-
- for (status, result) in results:
- self.failUnless(status)
- self.assertEqual(result, None)
-
- return d.addCallback(cbCopy)
-
-
- def testUnfeaturefulMessage(self):
- s = imap4.IMAP4Server()
-
- # See above comment
- f = s._IMAP4Server__cbCopy
-
- m = FakeMailbox()
- msgs = [FakeyMessage({'Header-Counter': str(i)}, (), 'Date', 'Body %d' % (i,), i + 10, None) for i in range(1, 11)]
- d = f([im for im in zip(range(1, 11), msgs)], 'tag', m)
-
- def cbCopy(results):
- seen = []
- for a in m.args:
- seen.append(a[0].read())
- self.assertEqual(a[1], ())
- self.assertEqual(a[2], "Date")
-
- seen.sort()
- exp = ["Header-Counter: %d\r\n\r\nBody %d" % (i, i) for i in range(1, 11)]
- exp.sort()
- self.assertEqual(seen, exp)
-
- for (status, result) in results:
- self.failUnless(status)
- self.assertEqual(result, None)
-
- return d.addCallback(cbCopy)
-
- def testMessageCopier(self):
- s = imap4.IMAP4Server()
-
- # See above comment
- f = s._IMAP4Server__cbCopy
-
- m = MessageCopierMailbox()
- msgs = [object() for i in range(1, 11)]
- d = f([im for im in zip(range(1, 11), msgs)], 'tag', m)
-
- def cbCopy(results):
- self.assertEqual(results, zip([1] * 10, range(1, 11)))
- for (orig, new) in zip(msgs, m.msgs):
- self.assertIdentical(orig, new)
-
- return d.addCallback(cbCopy)
-
-
-class TLSTestCase(IMAP4HelperMixin, unittest.TestCase):
- serverCTX = ServerTLSContext and ServerTLSContext()
- clientCTX = ClientTLSContext and ClientTLSContext()
-
- def loopback(self):
- return loopback.loopbackTCP(self.server, self.client, noisy=False)
-
- def testAPileOfThings(self):
- SimpleServer.theAccount.addMailbox('inbox')
- called = []
- def login():
- called.append(None)
- return self.client.login('testuser', 'password-test')
- def list():
- called.append(None)
- return self.client.list('inbox', '%')
- def status():
- called.append(None)
- return self.client.status('inbox', 'UIDNEXT')
- def examine():
- called.append(None)
- return self.client.examine('inbox')
- def logout():
- called.append(None)
- return self.client.logout()
-
- self.client.requireTransportSecurity = True
-
- methods = [login, list, status, examine, logout]
- map(self.connected.addCallback, map(strip, methods))
- self.connected.addCallbacks(self._cbStopClient, self._ebGeneral)
- def check(ignored):
- self.assertEqual(self.server.startedTLS, True)
- self.assertEqual(self.client.startedTLS, True)
- self.assertEqual(len(called), len(methods))
- d = self.loopback()
- d.addCallback(check)
- return d
-
- def testLoginLogin(self):
- self.server.checker.addUser('testuser', 'password-test')
- success = []
- self.client.registerAuthenticator(imap4.LOGINAuthenticator('testuser'))
- self.connected.addCallback(
- lambda _: self.client.authenticate('password-test')
- ).addCallback(
- lambda _: self.client.logout()
- ).addCallback(success.append
- ).addCallback(self._cbStopClient
- ).addErrback(self._ebGeneral)
-
- d = self.loopback()
- d.addCallback(lambda x : self.assertEqual(len(success), 1))
- return d
-
-
- def test_startTLS(self):
- """
- L{IMAP4Client.startTLS} triggers TLS negotiation and returns a
- L{Deferred} which fires after the client's transport is using
- encryption.
- """
- success = []
- self.connected.addCallback(lambda _: self.client.startTLS())
- def checkSecure(ignored):
- self.assertTrue(
- interfaces.ISSLTransport.providedBy(self.client.transport))
- self.connected.addCallback(checkSecure)
- self.connected.addCallback(self._cbStopClient)
- self.connected.addCallback(success.append)
- self.connected.addErrback(self._ebGeneral)
-
- d = self.loopback()
- d.addCallback(lambda x : self.failUnless(success))
- return defer.gatherResults([d, self.connected])
-
-
- def testFailedStartTLS(self):
- failure = []
- def breakServerTLS(ign):
- self.server.canStartTLS = False
-
- self.connected.addCallback(breakServerTLS)
- self.connected.addCallback(lambda ign: self.client.startTLS())
- self.connected.addErrback(lambda err: failure.append(err.trap(imap4.IMAP4Exception)))
- self.connected.addCallback(self._cbStopClient)
- self.connected.addErrback(self._ebGeneral)
-
- def check(ignored):
- self.failUnless(failure)
- self.assertIdentical(failure[0], imap4.IMAP4Exception)
- return self.loopback().addCallback(check)
-
-
-
-class SlowMailbox(SimpleMailbox):
- howSlow = 2
- callLater = None
- fetchDeferred = None
-
- # Not a very nice implementation of fetch(), but it'll
- # do for the purposes of testing.
- def fetch(self, messages, uid):
- d = defer.Deferred()
- self.callLater(self.howSlow, d.callback, ())
- self.fetchDeferred.callback(None)
- return d
-
-class Timeout(IMAP4HelperMixin, unittest.TestCase):
-
- def test_serverTimeout(self):
- """
- The *client* has a timeout mechanism which will close connections that
- are inactive for a period.
- """
- c = Clock()
- self.server.timeoutTest = True
- self.client.timeout = 5 #seconds
- self.client.callLater = c.callLater
- self.selectedArgs = None
-
- def login():
- d = self.client.login('testuser', 'password-test')
- c.advance(5)
- d.addErrback(timedOut)
- return d
-
- def timedOut(failure):
- self._cbStopClient(None)
- failure.trap(error.TimeoutError)
-
- d = self.connected.addCallback(strip(login))
- d.addErrback(self._ebGeneral)
- return defer.gatherResults([d, self.loopback()])
-
-
- def test_longFetchDoesntTimeout(self):
- """
- The connection timeout does not take effect during fetches.
- """
- c = Clock()
- SlowMailbox.callLater = c.callLater
- SlowMailbox.fetchDeferred = defer.Deferred()
- self.server.callLater = c.callLater
- SimpleServer.theAccount.mailboxFactory = SlowMailbox
- SimpleServer.theAccount.addMailbox('mailbox-test')
-
- self.server.setTimeout(1)
-
- def login():
- return self.client.login('testuser', 'password-test')
- def select():
- self.server.setTimeout(1)
- return self.client.select('mailbox-test')
- def fetch():
- return self.client.fetchUID('1:*')
- def stillConnected():
- self.assertNotEquals(self.server.state, 'timeout')
-
- def cbAdvance(ignored):
- for i in xrange(4):
- c.advance(.5)
-
- SlowMailbox.fetchDeferred.addCallback(cbAdvance)
-
- d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(select))
- d1.addCallback(strip(fetch))
- d1.addCallback(strip(stillConnected))
- d1.addCallback(self._cbStopClient)
- d1.addErrback(self._ebGeneral)
- d = defer.gatherResults([d1, self.loopback()])
- return d
-
-
- def test_idleClientDoesDisconnect(self):
- """
- The *server* has a timeout mechanism which will close connections that
- are inactive for a period.
- """
- c = Clock()
- # Hook up our server protocol
- transport = StringTransportWithDisconnection()
- transport.protocol = self.server
- self.server.callLater = c.callLater
- self.server.makeConnection(transport)
-
- # Make sure we can notice when the connection goes away
- lost = []
- connLost = self.server.connectionLost
- self.server.connectionLost = lambda reason: (lost.append(None), connLost(reason))[1]
-
- # 2/3rds of the idle timeout elapses...
- c.pump([0.0] + [self.server.timeOut / 3.0] * 2)
- self.failIf(lost, lost)
-
- # Now some more
- c.pump([0.0, self.server.timeOut / 2.0])
- self.failUnless(lost)
-
-
-
-class Disconnection(unittest.TestCase):
- def testClientDisconnectFailsDeferreds(self):
- c = imap4.IMAP4Client()
- t = StringTransportWithDisconnection()
- c.makeConnection(t)
- d = self.assertFailure(c.login('testuser', 'example.com'), error.ConnectionDone)
- c.connectionLost(error.ConnectionDone("Connection closed"))
- return d
-
-
-
-class SynchronousMailbox(object):
- """
- Trivial, in-memory mailbox implementation which can produce a message
- synchronously.
- """
- def __init__(self, messages):
- self.messages = messages
-
-
- def fetch(self, msgset, uid):
- assert not uid, "Cannot handle uid requests."
- for msg in msgset:
- yield msg, self.messages[msg - 1]
-
-
-
-class StringTransportConsumer(StringTransport):
- producer = None
- streaming = None
-
- def registerProducer(self, producer, streaming):
- self.producer = producer
- self.streaming = streaming
-
-
-
-class Pipelining(unittest.TestCase):
- """
- Tests for various aspects of the IMAP4 server's pipelining support.
- """
- messages = [
- FakeyMessage({}, [], '', '0', None, None),
- FakeyMessage({}, [], '', '1', None, None),
- FakeyMessage({}, [], '', '2', None, None),
- ]
-
- def setUp(self):
- self.iterators = []
-
- self.transport = StringTransportConsumer()
- self.server = imap4.IMAP4Server(None, None, self.iterateInReactor)
- self.server.makeConnection(self.transport)
-
-
- def iterateInReactor(self, iterator):
- d = defer.Deferred()
- self.iterators.append((iterator, d))
- return d
-
-
- def tearDown(self):
- self.server.connectionLost(failure.Failure(error.ConnectionDone()))
-
-
- def test_synchronousFetch(self):
- """
- Test that pipelined FETCH commands which can be responded to
- synchronously are responded to correctly.
- """
- mailbox = SynchronousMailbox(self.messages)
-
- # Skip over authentication and folder selection
- self.server.state = 'select'
- self.server.mbox = mailbox
-
- # Get rid of any greeting junk
- self.transport.clear()
-
- # Here's some pipelined stuff
- self.server.dataReceived(
- '01 FETCH 1 BODY[]\r\n'
- '02 FETCH 2 BODY[]\r\n'
- '03 FETCH 3 BODY[]\r\n')
-
- # Flush anything the server has scheduled to run
- while self.iterators:
- for e in self.iterators[0][0]:
- break
- else:
- self.iterators.pop(0)[1].callback(None)
-
- # The bodies are empty because we aren't simulating a transport
- # exactly correctly (we have StringTransportConsumer but we never
- # call resumeProducing on its producer). It doesn't matter: just
- # make sure the surrounding structure is okay, and that no
- # exceptions occurred.
- self.assertEqual(
- self.transport.value(),
- '* 1 FETCH (BODY[] )\r\n'
- '01 OK FETCH completed\r\n'
- '* 2 FETCH (BODY[] )\r\n'
- '02 OK FETCH completed\r\n'
- '* 3 FETCH (BODY[] )\r\n'
- '03 OK FETCH completed\r\n')
-
-
-
-if ClientTLSContext is None:
- for case in (TLSTestCase,):
- case.skip = "OpenSSL not present"
-elif interfaces.IReactorSSL(reactor, None) is None:
- for case in (TLSTestCase,):
- case.skip = "Reactor doesn't support SSL"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mail.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mail.py
deleted file mode 100755
index 6d2bdddb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mail.py
+++ /dev/null
@@ -1,2062 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for large portions of L{twisted.mail}.
-"""
-
-import os
-import errno
-import shutil
-import pickle
-import StringIO
-import rfc822
-import tempfile
-import signal
-
-from zope.interface import Interface, implements
-
-from twisted.trial import unittest
-from twisted.mail import smtp
-from twisted.mail import pop3
-from twisted.names import dns
-from twisted.internet import protocol
-from twisted.internet import defer
-from twisted.internet.defer import Deferred
-from twisted.internet import reactor
-from twisted.internet import interfaces
-from twisted.internet import task
-from twisted.internet.error import DNSLookupError, CannotListenError
-from twisted.internet.error import ProcessDone, ProcessTerminated
-from twisted.internet import address
-from twisted.python import failure
-from twisted.python.filepath import FilePath
-from twisted.python.hashlib import md5
-
-from twisted import mail
-import twisted.mail.mail
-import twisted.mail.maildir
-import twisted.mail.relay
-import twisted.mail.relaymanager
-import twisted.mail.protocols
-import twisted.mail.alias
-
-from twisted.names.error import DNSNameError
-from twisted.names.dns import RRHeader, Record_CNAME, Record_MX
-
-from twisted import cred
-import twisted.cred.credentials
-import twisted.cred.checkers
-import twisted.cred.portal
-
-from twisted.test.proto_helpers import LineSendingProtocol
-
-class DomainWithDefaultsTestCase(unittest.TestCase):
- def testMethods(self):
- d = dict([(x, x + 10) for x in range(10)])
- d = mail.mail.DomainWithDefaultDict(d, 'Default')
-
- self.assertEqual(len(d), 10)
- self.assertEqual(list(iter(d)), range(10))
- self.assertEqual(list(d.iterkeys()), list(iter(d)))
-
- items = list(d.iteritems())
- items.sort()
- self.assertEqual(items, [(x, x + 10) for x in range(10)])
-
- values = list(d.itervalues())
- values.sort()
- self.assertEqual(values, range(10, 20))
-
- items = d.items()
- items.sort()
- self.assertEqual(items, [(x, x + 10) for x in range(10)])
-
- values = d.values()
- values.sort()
- self.assertEqual(values, range(10, 20))
-
- for x in range(10):
- self.assertEqual(d[x], x + 10)
- self.assertEqual(d.get(x), x + 10)
- self.failUnless(x in d)
- self.failUnless(d.has_key(x))
-
- del d[2], d[4], d[6]
-
- self.assertEqual(len(d), 7)
- self.assertEqual(d[2], 'Default')
- self.assertEqual(d[4], 'Default')
- self.assertEqual(d[6], 'Default')
-
- d.update({'a': None, 'b': (), 'c': '*'})
- self.assertEqual(len(d), 10)
- self.assertEqual(d['a'], None)
- self.assertEqual(d['b'], ())
- self.assertEqual(d['c'], '*')
-
- d.clear()
- self.assertEqual(len(d), 0)
-
- self.assertEqual(d.setdefault('key', 'value'), 'value')
- self.assertEqual(d['key'], 'value')
-
- self.assertEqual(d.popitem(), ('key', 'value'))
- self.assertEqual(len(d), 0)
-
- dcopy = d.copy()
- self.assertEqual(d.domains, dcopy.domains)
- self.assertEqual(d.default, dcopy.default)
-
-
- def _stringificationTest(self, stringifier):
- """
- Assert that the class name of a L{mail.mail.DomainWithDefaultDict}
- instance and the string-formatted underlying domain dictionary both
- appear in the string produced by the given string-returning function.
-
- @type stringifier: one-argument callable
- @param stringifier: either C{str} or C{repr}, to be used to get a
- string to make assertions against.
- """
- domain = mail.mail.DomainWithDefaultDict({}, 'Default')
- self.assertIn(domain.__class__.__name__, stringifier(domain))
- domain['key'] = 'value'
- self.assertIn(str({'key': 'value'}), stringifier(domain))
-
-
- def test_str(self):
- """
- L{DomainWithDefaultDict.__str__} should return a string including
- the class name and the domain mapping held by the instance.
- """
- self._stringificationTest(str)
-
-
- def test_repr(self):
- """
- L{DomainWithDefaultDict.__repr__} should return a string including
- the class name and the domain mapping held by the instance.
- """
- self._stringificationTest(repr)
-
-
-
-class BounceTestCase(unittest.TestCase):
- def setUp(self):
- self.domain = mail.mail.BounceDomain()
-
- def testExists(self):
- self.assertRaises(smtp.AddressError, self.domain.exists, "any user")
-
- def testRelay(self):
- self.assertEqual(
- self.domain.willRelay("random q emailer", "protocol"),
- False
- )
-
- def testMessage(self):
- self.assertRaises(NotImplementedError, self.domain.startMessage, "whomever")
-
- def testAddUser(self):
- self.domain.addUser("bob", "password")
- self.assertRaises(smtp.SMTPBadRcpt, self.domain.exists, "bob")
-
-class FileMessageTestCase(unittest.TestCase):
- def setUp(self):
- self.name = "fileMessage.testFile"
- self.final = "final.fileMessage.testFile"
- self.f = file(self.name, 'w')
- self.fp = mail.mail.FileMessage(self.f, self.name, self.final)
-
- def tearDown(self):
- try:
- self.f.close()
- except:
- pass
- try:
- os.remove(self.name)
- except:
- pass
- try:
- os.remove(self.final)
- except:
- pass
-
- def testFinalName(self):
- return self.fp.eomReceived().addCallback(self._cbFinalName)
-
- def _cbFinalName(self, result):
- self.assertEqual(result, self.final)
- self.failUnless(self.f.closed)
- self.failIf(os.path.exists(self.name))
-
- def testContents(self):
- contents = "first line\nsecond line\nthird line\n"
- for line in contents.splitlines():
- self.fp.lineReceived(line)
- self.fp.eomReceived()
- self.assertEqual(file(self.final).read(), contents)
-
- def testInterrupted(self):
- contents = "first line\nsecond line\n"
- for line in contents.splitlines():
- self.fp.lineReceived(line)
- self.fp.connectionLost()
- self.failIf(os.path.exists(self.name))
- self.failIf(os.path.exists(self.final))
-
-class MailServiceTestCase(unittest.TestCase):
- def setUp(self):
- self.service = mail.mail.MailService()
-
- def testFactories(self):
- f = self.service.getPOP3Factory()
- self.failUnless(isinstance(f, protocol.ServerFactory))
- self.failUnless(f.buildProtocol(('127.0.0.1', 12345)), pop3.POP3)
-
- f = self.service.getSMTPFactory()
- self.failUnless(isinstance(f, protocol.ServerFactory))
- self.failUnless(f.buildProtocol(('127.0.0.1', 12345)), smtp.SMTP)
-
- f = self.service.getESMTPFactory()
- self.failUnless(isinstance(f, protocol.ServerFactory))
- self.failUnless(f.buildProtocol(('127.0.0.1', 12345)), smtp.ESMTP)
-
- def testPortals(self):
- o1 = object()
- o2 = object()
- self.service.portals['domain'] = o1
- self.service.portals[''] = o2
-
- self.failUnless(self.service.lookupPortal('domain') is o1)
- self.failUnless(self.service.defaultPortal() is o2)
-
-
-class StringListMailboxTests(unittest.TestCase):
- """
- Tests for L{StringListMailbox}, an in-memory only implementation of
- L{pop3.IMailbox}.
- """
- def test_listOneMessage(self):
- """
- L{StringListMailbox.listMessages} returns the length of the message at
- the offset into the mailbox passed to it.
- """
- mailbox = mail.maildir.StringListMailbox(["abc", "ab", "a"])
- self.assertEqual(mailbox.listMessages(0), 3)
- self.assertEqual(mailbox.listMessages(1), 2)
- self.assertEqual(mailbox.listMessages(2), 1)
-
-
- def test_listAllMessages(self):
- """
- L{StringListMailbox.listMessages} returns a list of the lengths of all
- messages if not passed an index.
- """
- mailbox = mail.maildir.StringListMailbox(["a", "abc", "ab"])
- self.assertEqual(mailbox.listMessages(), [1, 3, 2])
-
-
- def test_getMessage(self):
- """
- L{StringListMailbox.getMessage} returns a file-like object from which
- the contents of the message at the given offset into the mailbox can be
- read.
- """
- mailbox = mail.maildir.StringListMailbox(["foo", "real contents"])
- self.assertEqual(mailbox.getMessage(1).read(), "real contents")
-
-
- def test_getUidl(self):
- """
- L{StringListMailbox.getUidl} returns a unique identifier for the
- message at the given offset into the mailbox.
- """
- mailbox = mail.maildir.StringListMailbox(["foo", "bar"])
- self.assertNotEqual(mailbox.getUidl(0), mailbox.getUidl(1))
-
-
- def test_deleteMessage(self):
- """
- L{StringListMailbox.deleteMessage} marks a message for deletion causing
- further requests for its length to return 0.
- """
- mailbox = mail.maildir.StringListMailbox(["foo"])
- mailbox.deleteMessage(0)
- self.assertEqual(mailbox.listMessages(0), 0)
- self.assertEqual(mailbox.listMessages(), [0])
-
-
- def test_undeleteMessages(self):
- """
- L{StringListMailbox.undeleteMessages} causes any messages marked for
- deletion to be returned to their original state.
- """
- mailbox = mail.maildir.StringListMailbox(["foo"])
- mailbox.deleteMessage(0)
- mailbox.undeleteMessages()
- self.assertEqual(mailbox.listMessages(0), 3)
- self.assertEqual(mailbox.listMessages(), [3])
-
-
- def test_sync(self):
- """
- L{StringListMailbox.sync} causes any messages as marked for deletion to
- be permanently deleted.
- """
- mailbox = mail.maildir.StringListMailbox(["foo"])
- mailbox.deleteMessage(0)
- mailbox.sync()
- mailbox.undeleteMessages()
- self.assertEqual(mailbox.listMessages(0), 0)
- self.assertEqual(mailbox.listMessages(), [0])
-
-
-
-class FailingMaildirMailboxAppendMessageTask(mail.maildir._MaildirMailboxAppendMessageTask):
- _openstate = True
- _writestate = True
- _renamestate = True
- def osopen(self, fn, attr, mode):
- if self._openstate:
- return os.open(fn, attr, mode)
- else:
- raise OSError(errno.EPERM, "Faked Permission Problem")
- def oswrite(self, fh, data):
- if self._writestate:
- return os.write(fh, data)
- else:
- raise OSError(errno.ENOSPC, "Faked Space problem")
- def osrename(self, oldname, newname):
- if self._renamestate:
- return os.rename(oldname, newname)
- else:
- raise OSError(errno.EPERM, "Faked Permission Problem")
-
-
-class _AppendTestMixin(object):
- """
- Mixin for L{MaildirMailbox.appendMessage} test cases which defines a helper
- for serially appending multiple messages to a mailbox.
- """
- def _appendMessages(self, mbox, messages):
- """
- Deliver the given messages one at a time. Delivery is serialized to
- guarantee a predictable order in the mailbox (overlapped message deliver
- makes no guarantees about which message which appear first).
- """
- results = []
- def append():
- for m in messages:
- d = mbox.appendMessage(m)
- d.addCallback(results.append)
- yield d
- d = task.cooperate(append()).whenDone()
- d.addCallback(lambda ignored: results)
- return d
-
-
-
-class MaildirAppendStringTestCase(unittest.TestCase, _AppendTestMixin):
- """
- Tests for L{MaildirMailbox.appendMessage} when invoked with a C{str}.
- """
- def setUp(self):
- self.d = self.mktemp()
- mail.maildir.initializeMaildir(self.d)
-
-
- def _append(self, ignored, mbox):
- d = mbox.appendMessage('TEST')
- return self.assertFailure(d, Exception)
-
-
- def _setState(self, ignored, mbox, rename=None, write=None, open=None):
- """
- Change the behavior of future C{rename}, C{write}, or C{open} calls made
- by the mailbox C{mbox}.
-
- @param rename: If not C{None}, a new value for the C{_renamestate}
- attribute of the mailbox's append factory. The original value will
- be restored at the end of the test.
-
- @param write: Like C{rename}, but for the C{_writestate} attribute.
-
- @param open: Like C{rename}, but for the C{_openstate} attribute.
- """
- if rename is not None:
- self.addCleanup(
- setattr, mbox.AppendFactory, '_renamestate',
- mbox.AppendFactory._renamestate)
- mbox.AppendFactory._renamestate = rename
- if write is not None:
- self.addCleanup(
- setattr, mbox.AppendFactory, '_writestate',
- mbox.AppendFactory._writestate)
- mbox.AppendFactory._writestate = write
- if open is not None:
- self.addCleanup(
- setattr, mbox.AppendFactory, '_openstate',
- mbox.AppendFactory._openstate)
- mbox.AppendFactory._openstate = open
-
-
- def test_append(self):
- """
- L{MaildirMailbox.appendMessage} returns a L{Deferred} which fires when
- the message has been added to the end of the mailbox.
- """
- mbox = mail.maildir.MaildirMailbox(self.d)
- mbox.AppendFactory = FailingMaildirMailboxAppendMessageTask
-
- d = self._appendMessages(mbox, ["X" * i for i in range(1, 11)])
- d.addCallback(self.assertEqual, [None] * 10)
- d.addCallback(self._cbTestAppend, mbox)
- return d
-
-
- def _cbTestAppend(self, ignored, mbox):
- """
- Check that the mailbox has the expected number (ten) of messages in it,
- and that each has the expected contents, and that they are in the same
- order as that in which they were appended.
- """
- self.assertEqual(len(mbox.listMessages()), 10)
- self.assertEqual(
- [len(mbox.getMessage(i).read()) for i in range(10)],
- range(1, 11))
- # test in the right order: last to first error location.
- self._setState(None, mbox, rename=False)
- d = self._append(None, mbox)
- d.addCallback(self._setState, mbox, rename=True, write=False)
- d.addCallback(self._append, mbox)
- d.addCallback(self._setState, mbox, write=True, open=False)
- d.addCallback(self._append, mbox)
- d.addCallback(self._setState, mbox, open=True)
- return d
-
-
-
-class MaildirAppendFileTestCase(unittest.TestCase, _AppendTestMixin):
- """
- Tests for L{MaildirMailbox.appendMessage} when invoked with a C{str}.
- """
- def setUp(self):
- self.d = self.mktemp()
- mail.maildir.initializeMaildir(self.d)
-
-
- def test_append(self):
- """
- L{MaildirMailbox.appendMessage} returns a L{Deferred} which fires when
- the message has been added to the end of the mailbox.
- """
- mbox = mail.maildir.MaildirMailbox(self.d)
- messages = []
- for i in xrange(1, 11):
- temp = tempfile.TemporaryFile()
- temp.write("X" * i)
- temp.seek(0, 0)
- messages.append(temp)
- self.addCleanup(temp.close)
-
- d = self._appendMessages(mbox, messages)
- d.addCallback(self._cbTestAppend, mbox)
- return d
-
-
- def _cbTestAppend(self, result, mbox):
- """
- Check that the mailbox has the expected number (ten) of messages in it,
- and that each has the expected contents, and that they are in the same
- order as that in which they were appended.
- """
- self.assertEqual(len(mbox.listMessages()), 10)
- self.assertEqual(
- [len(mbox.getMessage(i).read()) for i in range(10)],
- range(1, 11))
-
-
-
-class MaildirTestCase(unittest.TestCase):
- def setUp(self):
- self.d = self.mktemp()
- mail.maildir.initializeMaildir(self.d)
-
- def tearDown(self):
- shutil.rmtree(self.d)
-
- def testInitializer(self):
- d = self.d
- trash = os.path.join(d, '.Trash')
-
- self.failUnless(os.path.exists(d) and os.path.isdir(d))
- self.failUnless(os.path.exists(os.path.join(d, 'new')))
- self.failUnless(os.path.exists(os.path.join(d, 'cur')))
- self.failUnless(os.path.exists(os.path.join(d, 'tmp')))
- self.failUnless(os.path.isdir(os.path.join(d, 'new')))
- self.failUnless(os.path.isdir(os.path.join(d, 'cur')))
- self.failUnless(os.path.isdir(os.path.join(d, 'tmp')))
-
- self.failUnless(os.path.exists(os.path.join(trash, 'new')))
- self.failUnless(os.path.exists(os.path.join(trash, 'cur')))
- self.failUnless(os.path.exists(os.path.join(trash, 'tmp')))
- self.failUnless(os.path.isdir(os.path.join(trash, 'new')))
- self.failUnless(os.path.isdir(os.path.join(trash, 'cur')))
- self.failUnless(os.path.isdir(os.path.join(trash, 'tmp')))
-
-
- def test_nameGenerator(self):
- """
- Each call to L{_MaildirNameGenerator.generate} returns a unique
- string suitable for use as the basename of a new message file. The
- names are ordered such that those generated earlier sort less than
- those generated later.
- """
- clock = task.Clock()
- clock.advance(0.05)
- generator = mail.maildir._MaildirNameGenerator(clock)
-
- firstName = generator.generate()
- clock.advance(0.05)
- secondName = generator.generate()
-
- self.assertTrue(firstName < secondName)
-
-
- def test_mailbox(self):
- """
- Exercise the methods of L{IMailbox} as implemented by
- L{MaildirMailbox}.
- """
- j = os.path.join
- n = mail.maildir._generateMaildirName
- msgs = [j(b, n()) for b in ('cur', 'new') for x in range(5)]
-
- # Toss a few files into the mailbox
- i = 1
- for f in msgs:
- fObj = file(j(self.d, f), 'w')
- fObj.write('x' * i)
- fObj.close()
- i = i + 1
-
- mb = mail.maildir.MaildirMailbox(self.d)
- self.assertEqual(mb.listMessages(), range(1, 11))
- self.assertEqual(mb.listMessages(1), 2)
- self.assertEqual(mb.listMessages(5), 6)
-
- self.assertEqual(mb.getMessage(6).read(), 'x' * 7)
- self.assertEqual(mb.getMessage(1).read(), 'x' * 2)
-
- d = {}
- for i in range(10):
- u = mb.getUidl(i)
- self.failIf(u in d)
- d[u] = None
-
- p, f = os.path.split(msgs[5])
-
- mb.deleteMessage(5)
- self.assertEqual(mb.listMessages(5), 0)
- self.failUnless(os.path.exists(j(self.d, '.Trash', 'cur', f)))
- self.failIf(os.path.exists(j(self.d, msgs[5])))
-
- mb.undeleteMessages()
- self.assertEqual(mb.listMessages(5), 6)
- self.failIf(os.path.exists(j(self.d, '.Trash', 'cur', f)))
- self.failUnless(os.path.exists(j(self.d, msgs[5])))
-
-class MaildirDirdbmDomainTestCase(unittest.TestCase):
- def setUp(self):
- self.P = self.mktemp()
- self.S = mail.mail.MailService()
- self.D = mail.maildir.MaildirDirdbmDomain(self.S, self.P)
-
- def tearDown(self):
- shutil.rmtree(self.P)
-
- def testAddUser(self):
- toAdd = (('user1', 'pwd1'), ('user2', 'pwd2'), ('user3', 'pwd3'))
- for (u, p) in toAdd:
- self.D.addUser(u, p)
-
- for (u, p) in toAdd:
- self.failUnless(u in self.D.dbm)
- self.assertEqual(self.D.dbm[u], p)
- self.failUnless(os.path.exists(os.path.join(self.P, u)))
-
- def testCredentials(self):
- creds = self.D.getCredentialsCheckers()
-
- self.assertEqual(len(creds), 1)
- self.failUnless(cred.checkers.ICredentialsChecker.providedBy(creds[0]))
- self.failUnless(cred.credentials.IUsernamePassword in creds[0].credentialInterfaces)
-
- def testRequestAvatar(self):
- class ISomething(Interface):
- pass
-
- self.D.addUser('user', 'password')
- self.assertRaises(
- NotImplementedError,
- self.D.requestAvatar, 'user', None, ISomething
- )
-
- t = self.D.requestAvatar('user', None, pop3.IMailbox)
- self.assertEqual(len(t), 3)
- self.failUnless(t[0] is pop3.IMailbox)
- self.failUnless(pop3.IMailbox.providedBy(t[1]))
-
- t[2]()
-
- def testRequestAvatarId(self):
- self.D.addUser('user', 'password')
- database = self.D.getCredentialsCheckers()[0]
-
- creds = cred.credentials.UsernamePassword('user', 'wrong password')
- self.assertRaises(
- cred.error.UnauthorizedLogin,
- database.requestAvatarId, creds
- )
-
- creds = cred.credentials.UsernamePassword('user', 'password')
- self.assertEqual(database.requestAvatarId(creds), 'user')
-
-
-class StubAliasableDomain(object):
- """
- Minimal testable implementation of IAliasableDomain.
- """
- implements(mail.mail.IAliasableDomain)
-
- def exists(self, user):
- """
- No test coverage for invocations of this method on domain objects,
- so we just won't implement it.
- """
- raise NotImplementedError()
-
-
- def addUser(self, user, password):
- """
- No test coverage for invocations of this method on domain objects,
- so we just won't implement it.
- """
- raise NotImplementedError()
-
-
- def getCredentialsCheckers(self):
- """
- This needs to succeed in order for other tests to complete
- successfully, but we don't actually assert anything about its
- behavior. Return an empty list. Sometime later we should return
- something else and assert that a portal got set up properly.
- """
- return []
-
-
- def setAliasGroup(self, aliases):
- """
- Just record the value so the test can check it later.
- """
- self.aliasGroup = aliases
-
-
-class ServiceDomainTestCase(unittest.TestCase):
- def setUp(self):
- self.S = mail.mail.MailService()
- self.D = mail.protocols.DomainDeliveryBase(self.S, None)
- self.D.service = self.S
- self.D.protocolName = 'TEST'
- self.D.host = 'hostname'
-
- self.tmpdir = self.mktemp()
- domain = mail.maildir.MaildirDirdbmDomain(self.S, self.tmpdir)
- domain.addUser('user', 'password')
- self.S.addDomain('test.domain', domain)
-
- def tearDown(self):
- shutil.rmtree(self.tmpdir)
-
-
- def testAddAliasableDomain(self):
- """
- Test that adding an IAliasableDomain to a mail service properly sets
- up alias group references and such.
- """
- aliases = object()
- domain = StubAliasableDomain()
- self.S.aliases = aliases
- self.S.addDomain('example.com', domain)
- self.assertIdentical(domain.aliasGroup, aliases)
-
-
- def testReceivedHeader(self):
- hdr = self.D.receivedHeader(
- ('remotehost', '123.232.101.234'),
- smtp.Address('<someguy@somplace>'),
- ['user@host.name']
- )
- fp = StringIO.StringIO(hdr)
- m = rfc822.Message(fp)
- self.assertEqual(len(m.items()), 1)
- self.failUnless(m.has_key('Received'))
-
- def testValidateTo(self):
- user = smtp.User('user@test.domain', 'helo', None, 'wherever@whatever')
- return defer.maybeDeferred(self.D.validateTo, user
- ).addCallback(self._cbValidateTo
- )
-
- def _cbValidateTo(self, result):
- self.failUnless(callable(result))
-
- def testValidateToBadUsername(self):
- user = smtp.User('resu@test.domain', 'helo', None, 'wherever@whatever')
- return self.assertFailure(
- defer.maybeDeferred(self.D.validateTo, user),
- smtp.SMTPBadRcpt)
-
- def testValidateToBadDomain(self):
- user = smtp.User('user@domain.test', 'helo', None, 'wherever@whatever')
- return self.assertFailure(
- defer.maybeDeferred(self.D.validateTo, user),
- smtp.SMTPBadRcpt)
-
- def testValidateFrom(self):
- helo = ('hostname', '127.0.0.1')
- origin = smtp.Address('<user@hostname>')
- self.failUnless(self.D.validateFrom(helo, origin) is origin)
-
- helo = ('hostname', '1.2.3.4')
- origin = smtp.Address('<user@hostname>')
- self.failUnless(self.D.validateFrom(helo, origin) is origin)
-
- helo = ('hostname', '1.2.3.4')
- origin = smtp.Address('<>')
- self.failUnless(self.D.validateFrom(helo, origin) is origin)
-
- self.assertRaises(
- smtp.SMTPBadSender,
- self.D.validateFrom, None, origin
- )
-
-class VirtualPOP3TestCase(unittest.TestCase):
- def setUp(self):
- self.tmpdir = self.mktemp()
- self.S = mail.mail.MailService()
- self.D = mail.maildir.MaildirDirdbmDomain(self.S, self.tmpdir)
- self.D.addUser('user', 'password')
- self.S.addDomain('test.domain', self.D)
-
- portal = cred.portal.Portal(self.D)
- map(portal.registerChecker, self.D.getCredentialsCheckers())
- self.S.portals[''] = self.S.portals['test.domain'] = portal
-
- self.P = mail.protocols.VirtualPOP3()
- self.P.service = self.S
- self.P.magic = '<unit test magic>'
-
- def tearDown(self):
- shutil.rmtree(self.tmpdir)
-
- def testAuthenticateAPOP(self):
- resp = md5(self.P.magic + 'password').hexdigest()
- return self.P.authenticateUserAPOP('user', resp
- ).addCallback(self._cbAuthenticateAPOP
- )
-
- def _cbAuthenticateAPOP(self, result):
- self.assertEqual(len(result), 3)
- self.assertEqual(result[0], pop3.IMailbox)
- self.failUnless(pop3.IMailbox.providedBy(result[1]))
- result[2]()
-
- def testAuthenticateIncorrectUserAPOP(self):
- resp = md5(self.P.magic + 'password').hexdigest()
- return self.assertFailure(
- self.P.authenticateUserAPOP('resu', resp),
- cred.error.UnauthorizedLogin)
-
- def testAuthenticateIncorrectResponseAPOP(self):
- resp = md5('wrong digest').hexdigest()
- return self.assertFailure(
- self.P.authenticateUserAPOP('user', resp),
- cred.error.UnauthorizedLogin)
-
- def testAuthenticatePASS(self):
- return self.P.authenticateUserPASS('user', 'password'
- ).addCallback(self._cbAuthenticatePASS
- )
-
- def _cbAuthenticatePASS(self, result):
- self.assertEqual(len(result), 3)
- self.assertEqual(result[0], pop3.IMailbox)
- self.failUnless(pop3.IMailbox.providedBy(result[1]))
- result[2]()
-
- def testAuthenticateBadUserPASS(self):
- return self.assertFailure(
- self.P.authenticateUserPASS('resu', 'password'),
- cred.error.UnauthorizedLogin)
-
- def testAuthenticateBadPasswordPASS(self):
- return self.assertFailure(
- self.P.authenticateUserPASS('user', 'wrong password'),
- cred.error.UnauthorizedLogin)
-
-class empty(smtp.User):
- def __init__(self):
- pass
-
-class RelayTestCase(unittest.TestCase):
- def testExists(self):
- service = mail.mail.MailService()
- domain = mail.relay.DomainQueuer(service)
-
- doRelay = [
- address.UNIXAddress('/var/run/mail-relay'),
- address.IPv4Address('TCP', '127.0.0.1', 12345),
- ]
-
- dontRelay = [
- address.IPv4Address('TCP', '192.168.2.1', 62),
- address.IPv4Address('TCP', '1.2.3.4', 1943),
- ]
-
- for peer in doRelay:
- user = empty()
- user.orig = 'user@host'
- user.dest = 'tsoh@resu'
- user.protocol = empty()
- user.protocol.transport = empty()
- user.protocol.transport.getPeer = lambda: peer
-
- self.failUnless(callable(domain.exists(user)))
-
- for peer in dontRelay:
- user = empty()
- user.orig = 'some@place'
- user.protocol = empty()
- user.protocol.transport = empty()
- user.protocol.transport.getPeer = lambda: peer
- user.dest = 'who@cares'
-
- self.assertRaises(smtp.SMTPBadRcpt, domain.exists, user)
-
-class RelayerTestCase(unittest.TestCase):
- def setUp(self):
- self.tmpdir = self.mktemp()
- os.mkdir(self.tmpdir)
- self.messageFiles = []
- for i in range(10):
- name = os.path.join(self.tmpdir, 'body-%d' % (i,))
- f = file(name + '-H', 'w')
- pickle.dump(['from-%d' % (i,), 'to-%d' % (i,)], f)
- f.close()
-
- f = file(name + '-D', 'w')
- f.write(name)
- f.seek(0, 0)
- self.messageFiles.append(name)
-
- self.R = mail.relay.RelayerMixin()
- self.R.loadMessages(self.messageFiles)
-
- def tearDown(self):
- shutil.rmtree(self.tmpdir)
-
- def testMailFrom(self):
- for i in range(10):
- self.assertEqual(self.R.getMailFrom(), 'from-%d' % (i,))
- self.R.sentMail(250, None, None, None, None)
- self.assertEqual(self.R.getMailFrom(), None)
-
- def testMailTo(self):
- for i in range(10):
- self.assertEqual(self.R.getMailTo(), ['to-%d' % (i,)])
- self.R.sentMail(250, None, None, None, None)
- self.assertEqual(self.R.getMailTo(), None)
-
- def testMailData(self):
- for i in range(10):
- name = os.path.join(self.tmpdir, 'body-%d' % (i,))
- self.assertEqual(self.R.getMailData().read(), name)
- self.R.sentMail(250, None, None, None, None)
- self.assertEqual(self.R.getMailData(), None)
-
-class Manager:
- def __init__(self):
- self.success = []
- self.failure = []
- self.done = []
-
- def notifySuccess(self, factory, message):
- self.success.append((factory, message))
-
- def notifyFailure(self, factory, message):
- self.failure.append((factory, message))
-
- def notifyDone(self, factory):
- self.done.append(factory)
-
-class ManagedRelayerTestCase(unittest.TestCase):
- def setUp(self):
- self.manager = Manager()
- self.messages = range(0, 20, 2)
- self.factory = object()
- self.relay = mail.relaymanager.ManagedRelayerMixin(self.manager)
- self.relay.messages = self.messages[:]
- self.relay.names = self.messages[:]
- self.relay.factory = self.factory
-
- def testSuccessfulSentMail(self):
- for i in self.messages:
- self.relay.sentMail(250, None, None, None, None)
-
- self.assertEqual(
- self.manager.success,
- [(self.factory, m) for m in self.messages]
- )
-
- def testFailedSentMail(self):
- for i in self.messages:
- self.relay.sentMail(550, None, None, None, None)
-
- self.assertEqual(
- self.manager.failure,
- [(self.factory, m) for m in self.messages]
- )
-
- def testConnectionLost(self):
- self.relay.connectionLost(failure.Failure(Exception()))
- self.assertEqual(self.manager.done, [self.factory])
-
-class DirectoryQueueTestCase(unittest.TestCase):
- def setUp(self):
- # This is almost a test case itself.
- self.tmpdir = self.mktemp()
- os.mkdir(self.tmpdir)
- self.queue = mail.relaymanager.Queue(self.tmpdir)
- self.queue.noisy = False
- for m in range(25):
- hdrF, msgF = self.queue.createNewMessage()
- pickle.dump(['header', m], hdrF)
- hdrF.close()
- msgF.lineReceived('body: %d' % (m,))
- msgF.eomReceived()
- self.queue.readDirectory()
-
- def tearDown(self):
- shutil.rmtree(self.tmpdir)
-
- def testWaiting(self):
- self.failUnless(self.queue.hasWaiting())
- self.assertEqual(len(self.queue.getWaiting()), 25)
-
- waiting = self.queue.getWaiting()
- self.queue.setRelaying(waiting[0])
- self.assertEqual(len(self.queue.getWaiting()), 24)
-
- self.queue.setWaiting(waiting[0])
- self.assertEqual(len(self.queue.getWaiting()), 25)
-
- def testRelaying(self):
- for m in self.queue.getWaiting():
- self.queue.setRelaying(m)
- self.assertEqual(
- len(self.queue.getRelayed()),
- 25 - len(self.queue.getWaiting())
- )
-
- self.failIf(self.queue.hasWaiting())
-
- relayed = self.queue.getRelayed()
- self.queue.setWaiting(relayed[0])
- self.assertEqual(len(self.queue.getWaiting()), 1)
- self.assertEqual(len(self.queue.getRelayed()), 24)
-
- def testDone(self):
- msg = self.queue.getWaiting()[0]
- self.queue.setRelaying(msg)
- self.queue.done(msg)
-
- self.assertEqual(len(self.queue.getWaiting()), 24)
- self.assertEqual(len(self.queue.getRelayed()), 0)
-
- self.failIf(msg in self.queue.getWaiting())
- self.failIf(msg in self.queue.getRelayed())
-
- def testEnvelope(self):
- envelopes = []
-
- for msg in self.queue.getWaiting():
- envelopes.append(self.queue.getEnvelope(msg))
-
- envelopes.sort()
- for i in range(25):
- self.assertEqual(
- envelopes.pop(0),
- ['header', i]
- )
-
-from twisted.names import server
-from twisted.names import client
-from twisted.names import common
-
-class TestAuthority(common.ResolverBase):
- def __init__(self):
- common.ResolverBase.__init__(self)
- self.addresses = {}
-
- def _lookup(self, name, cls, type, timeout = None):
- if name in self.addresses and type == dns.MX:
- results = []
- for a in self.addresses[name]:
- hdr = dns.RRHeader(
- name, dns.MX, dns.IN, 60, dns.Record_MX(0, a)
- )
- results.append(hdr)
- return defer.succeed((results, [], []))
- return defer.fail(failure.Failure(dns.DomainError(name)))
-
-def setUpDNS(self):
- self.auth = TestAuthority()
- factory = server.DNSServerFactory([self.auth])
- protocol = dns.DNSDatagramProtocol(factory)
- while 1:
- self.port = reactor.listenTCP(0, factory, interface='127.0.0.1')
- portNumber = self.port.getHost().port
-
- try:
- self.udpPort = reactor.listenUDP(portNumber, protocol, interface='127.0.0.1')
- except CannotListenError:
- self.port.stopListening()
- else:
- break
- self.resolver = client.Resolver(servers=[('127.0.0.1', portNumber)])
-
-
-def tearDownDNS(self):
- dl = []
- dl.append(defer.maybeDeferred(self.port.stopListening))
- dl.append(defer.maybeDeferred(self.udpPort.stopListening))
- if self.resolver.protocol.transport is not None:
- dl.append(defer.maybeDeferred(self.resolver.protocol.transport.stopListening))
- try:
- self.resolver._parseCall.cancel()
- except:
- pass
- return defer.DeferredList(dl)
-
-class MXTestCase(unittest.TestCase):
- """
- Tests for L{mail.relaymanager.MXCalculator}.
- """
- def setUp(self):
- setUpDNS(self)
- self.clock = task.Clock()
- self.mx = mail.relaymanager.MXCalculator(self.resolver, self.clock)
-
- def tearDown(self):
- return tearDownDNS(self)
-
-
- def test_defaultClock(self):
- """
- L{MXCalculator}'s default clock is C{twisted.internet.reactor}.
- """
- self.assertIdentical(
- mail.relaymanager.MXCalculator(self.resolver).clock,
- reactor)
-
-
- def testSimpleSuccess(self):
- self.auth.addresses['test.domain'] = ['the.email.test.domain']
- return self.mx.getMX('test.domain').addCallback(self._cbSimpleSuccess)
-
- def _cbSimpleSuccess(self, mx):
- self.assertEqual(mx.preference, 0)
- self.assertEqual(str(mx.name), 'the.email.test.domain')
-
- def testSimpleFailure(self):
- self.mx.fallbackToDomain = False
- return self.assertFailure(self.mx.getMX('test.domain'), IOError)
-
- def testSimpleFailureWithFallback(self):
- return self.assertFailure(self.mx.getMX('test.domain'), DNSLookupError)
-
-
- def _exchangeTest(self, domain, records, correctMailExchange):
- """
- Issue an MX request for the given domain and arrange for it to be
- responded to with the given records. Verify that the resulting mail
- exchange is the indicated host.
-
- @type domain: C{str}
- @type records: C{list} of L{RRHeader}
- @type correctMailExchange: C{str}
- @rtype: L{Deferred}
- """
- class DummyResolver(object):
- def lookupMailExchange(self, name):
- if name == domain:
- return defer.succeed((
- records,
- [],
- []))
- return defer.fail(DNSNameError(domain))
-
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX(domain)
- def gotMailExchange(record):
- self.assertEqual(str(record.name), correctMailExchange)
- d.addCallback(gotMailExchange)
- return d
-
-
- def test_mailExchangePreference(self):
- """
- The MX record with the lowest preference is returned by
- L{MXCalculator.getMX}.
- """
- domain = "example.com"
- good = "good.example.com"
- bad = "bad.example.com"
-
- records = [
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(1, bad)),
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(0, good)),
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(2, bad))]
- return self._exchangeTest(domain, records, good)
-
-
- def test_badExchangeExcluded(self):
- """
- L{MXCalculator.getMX} returns the MX record with the lowest preference
- which is not also marked as bad.
- """
- domain = "example.com"
- good = "good.example.com"
- bad = "bad.example.com"
-
- records = [
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(0, bad)),
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(1, good))]
- self.mx.markBad(bad)
- return self._exchangeTest(domain, records, good)
-
-
- def test_fallbackForAllBadExchanges(self):
- """
- L{MXCalculator.getMX} returns the MX record with the lowest preference
- if all the MX records in the response have been marked bad.
- """
- domain = "example.com"
- bad = "bad.example.com"
- worse = "worse.example.com"
-
- records = [
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(0, bad)),
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(1, worse))]
- self.mx.markBad(bad)
- self.mx.markBad(worse)
- return self._exchangeTest(domain, records, bad)
-
-
- def test_badExchangeExpires(self):
- """
- L{MXCalculator.getMX} returns the MX record with the lowest preference
- if it was last marked bad longer than L{MXCalculator.timeOutBadMX}
- seconds ago.
- """
- domain = "example.com"
- good = "good.example.com"
- previouslyBad = "bad.example.com"
-
- records = [
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(0, previouslyBad)),
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(1, good))]
- self.mx.markBad(previouslyBad)
- self.clock.advance(self.mx.timeOutBadMX)
- return self._exchangeTest(domain, records, previouslyBad)
-
-
- def test_goodExchangeUsed(self):
- """
- L{MXCalculator.getMX} returns the MX record with the lowest preference
- if it was marked good after it was marked bad.
- """
- domain = "example.com"
- good = "good.example.com"
- previouslyBad = "bad.example.com"
-
- records = [
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(0, previouslyBad)),
- RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(1, good))]
- self.mx.markBad(previouslyBad)
- self.mx.markGood(previouslyBad)
- self.clock.advance(self.mx.timeOutBadMX)
- return self._exchangeTest(domain, records, previouslyBad)
-
-
- def test_successWithoutResults(self):
- """
- If an MX lookup succeeds but the result set is empty,
- L{MXCalculator.getMX} should try to look up an I{A} record for the
- requested name and call back its returned Deferred with that
- address.
- """
- ip = '1.2.3.4'
- domain = 'example.org'
-
- class DummyResolver(object):
- """
- Fake resolver which will respond to an MX lookup with an empty
- result set.
-
- @ivar mx: A dictionary mapping hostnames to three-tuples of
- results to be returned from I{MX} lookups.
-
- @ivar a: A dictionary mapping hostnames to addresses to be
- returned from I{A} lookups.
- """
- mx = {domain: ([], [], [])}
- a = {domain: ip}
-
- def lookupMailExchange(self, domain):
- return defer.succeed(self.mx[domain])
-
- def getHostByName(self, domain):
- return defer.succeed(self.a[domain])
-
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX(domain)
- d.addCallback(self.assertEqual, Record_MX(name=ip))
- return d
-
-
- def test_failureWithSuccessfulFallback(self):
- """
- Test that if the MX record lookup fails, fallback is enabled, and an A
- record is available for the name, then the Deferred returned by
- L{MXCalculator.getMX} ultimately fires with a Record_MX instance which
- gives the address in the A record for the name.
- """
- class DummyResolver(object):
- """
- Fake resolver which will fail an MX lookup but then succeed a
- getHostByName call.
- """
- def lookupMailExchange(self, domain):
- return defer.fail(DNSNameError())
-
- def getHostByName(self, domain):
- return defer.succeed("1.2.3.4")
-
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX("domain")
- d.addCallback(self.assertEqual, Record_MX(name="1.2.3.4"))
- return d
-
-
- def test_cnameWithoutGlueRecords(self):
- """
- If an MX lookup returns a single CNAME record as a result, MXCalculator
- will perform an MX lookup for the canonical name indicated and return
- the MX record which results.
- """
- alias = "alias.example.com"
- canonical = "canonical.example.com"
- exchange = "mail.example.com"
-
- class DummyResolver(object):
- """
- Fake resolver which will return a CNAME for an MX lookup of a name
- which is an alias and an MX for an MX lookup of the canonical name.
- """
- def lookupMailExchange(self, domain):
- if domain == alias:
- return defer.succeed((
- [RRHeader(name=domain,
- type=Record_CNAME.TYPE,
- payload=Record_CNAME(canonical))],
- [], []))
- elif domain == canonical:
- return defer.succeed((
- [RRHeader(name=domain,
- type=Record_MX.TYPE,
- payload=Record_MX(0, exchange))],
- [], []))
- else:
- return defer.fail(DNSNameError(domain))
-
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX(alias)
- d.addCallback(self.assertEqual, Record_MX(name=exchange))
- return d
-
-
- def test_cnameChain(self):
- """
- If L{MXCalculator.getMX} encounters a CNAME chain which is longer than
- the length specified, the returned L{Deferred} should errback with
- L{CanonicalNameChainTooLong}.
- """
- class DummyResolver(object):
- """
- Fake resolver which generates a CNAME chain of infinite length in
- response to MX lookups.
- """
- chainCounter = 0
-
- def lookupMailExchange(self, domain):
- self.chainCounter += 1
- name = 'x-%d.example.com' % (self.chainCounter,)
- return defer.succeed((
- [RRHeader(name=domain,
- type=Record_CNAME.TYPE,
- payload=Record_CNAME(name))],
- [], []))
-
- cnameLimit = 3
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX("mail.example.com", cnameLimit)
- self.assertFailure(
- d, twisted.mail.relaymanager.CanonicalNameChainTooLong)
- def cbChainTooLong(error):
- self.assertEqual(error.args[0], Record_CNAME("x-%d.example.com" % (cnameLimit + 1,)))
- self.assertEqual(self.mx.resolver.chainCounter, cnameLimit + 1)
- d.addCallback(cbChainTooLong)
- return d
-
-
- def test_cnameWithGlueRecords(self):
- """
- If an MX lookup returns a CNAME and the MX record for the CNAME, the
- L{Deferred} returned by L{MXCalculator.getMX} should be called back
- with the name from the MX record without further lookups being
- attempted.
- """
- lookedUp = []
- alias = "alias.example.com"
- canonical = "canonical.example.com"
- exchange = "mail.example.com"
-
- class DummyResolver(object):
- def lookupMailExchange(self, domain):
- if domain != alias or lookedUp:
- # Don't give back any results for anything except the alias
- # or on any request after the first.
- return ([], [], [])
- return defer.succeed((
- [RRHeader(name=alias,
- type=Record_CNAME.TYPE,
- payload=Record_CNAME(canonical)),
- RRHeader(name=canonical,
- type=Record_MX.TYPE,
- payload=Record_MX(name=exchange))],
- [], []))
-
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX(alias)
- d.addCallback(self.assertEqual, Record_MX(name=exchange))
- return d
-
-
- def test_cnameLoopWithGlueRecords(self):
- """
- If an MX lookup returns two CNAME records which point to each other,
- the loop should be detected and the L{Deferred} returned by
- L{MXCalculator.getMX} should be errbacked with L{CanonicalNameLoop}.
- """
- firstAlias = "cname1.example.com"
- secondAlias = "cname2.example.com"
-
- class DummyResolver(object):
- def lookupMailExchange(self, domain):
- return defer.succeed((
- [RRHeader(name=firstAlias,
- type=Record_CNAME.TYPE,
- payload=Record_CNAME(secondAlias)),
- RRHeader(name=secondAlias,
- type=Record_CNAME.TYPE,
- payload=Record_CNAME(firstAlias))],
- [], []))
-
- self.mx.resolver = DummyResolver()
- d = self.mx.getMX(firstAlias)
- self.assertFailure(d, twisted.mail.relaymanager.CanonicalNameLoop)
- return d
-
-
- def testManyRecords(self):
- self.auth.addresses['test.domain'] = [
- 'mx1.test.domain', 'mx2.test.domain', 'mx3.test.domain'
- ]
- return self.mx.getMX('test.domain'
- ).addCallback(self._cbManyRecordsSuccessfulLookup
- )
-
- def _cbManyRecordsSuccessfulLookup(self, mx):
- self.failUnless(str(mx.name).split('.', 1)[0] in ('mx1', 'mx2', 'mx3'))
- self.mx.markBad(str(mx.name))
- return self.mx.getMX('test.domain'
- ).addCallback(self._cbManyRecordsDifferentResult, mx
- )
-
- def _cbManyRecordsDifferentResult(self, nextMX, mx):
- self.assertNotEqual(str(mx.name), str(nextMX.name))
- self.mx.markBad(str(nextMX.name))
-
- return self.mx.getMX('test.domain'
- ).addCallback(self._cbManyRecordsLastResult, mx, nextMX
- )
-
- def _cbManyRecordsLastResult(self, lastMX, mx, nextMX):
- self.assertNotEqual(str(mx.name), str(lastMX.name))
- self.assertNotEqual(str(nextMX.name), str(lastMX.name))
-
- self.mx.markBad(str(lastMX.name))
- self.mx.markGood(str(nextMX.name))
-
- return self.mx.getMX('test.domain'
- ).addCallback(self._cbManyRecordsRepeatSpecificResult, nextMX
- )
-
- def _cbManyRecordsRepeatSpecificResult(self, againMX, nextMX):
- self.assertEqual(str(againMX.name), str(nextMX.name))
-
-class LiveFireExercise(unittest.TestCase):
- if interfaces.IReactorUDP(reactor, None) is None:
- skip = "UDP support is required to determining MX records"
-
- def setUp(self):
- setUpDNS(self)
- self.tmpdirs = [
- 'domainDir', 'insertionDomain', 'insertionQueue',
- 'destinationDomain', 'destinationQueue'
- ]
-
- def tearDown(self):
- for d in self.tmpdirs:
- if os.path.exists(d):
- shutil.rmtree(d)
- return tearDownDNS(self)
-
- def testLocalDelivery(self):
- service = mail.mail.MailService()
- service.smtpPortal.registerChecker(cred.checkers.AllowAnonymousAccess())
- domain = mail.maildir.MaildirDirdbmDomain(service, 'domainDir')
- domain.addUser('user', 'password')
- service.addDomain('test.domain', domain)
- service.portals[''] = service.portals['test.domain']
- map(service.portals[''].registerChecker, domain.getCredentialsCheckers())
-
- service.setQueue(mail.relay.DomainQueuer(service))
- manager = mail.relaymanager.SmartHostSMTPRelayingManager(service.queue, None)
- helper = mail.relaymanager.RelayStateHelper(manager, 1)
-
- f = service.getSMTPFactory()
-
- self.smtpServer = reactor.listenTCP(0, f, interface='127.0.0.1')
-
- client = LineSendingProtocol([
- 'HELO meson',
- 'MAIL FROM: <user@hostname>',
- 'RCPT TO: <user@test.domain>',
- 'DATA',
- 'This is the message',
- '.',
- 'QUIT'
- ])
-
- done = Deferred()
- f = protocol.ClientFactory()
- f.protocol = lambda: client
- f.clientConnectionLost = lambda *args: done.callback(None)
- reactor.connectTCP('127.0.0.1', self.smtpServer.getHost().port, f)
-
- def finished(ign):
- mbox = domain.requestAvatar('user', None, pop3.IMailbox)[1]
- msg = mbox.getMessage(0).read()
- self.failIfEqual(msg.find('This is the message'), -1)
-
- return self.smtpServer.stopListening()
- done.addCallback(finished)
- return done
-
-
- def testRelayDelivery(self):
- # Here is the service we will connect to and send mail from
- insServ = mail.mail.MailService()
- insServ.smtpPortal.registerChecker(cred.checkers.AllowAnonymousAccess())
- domain = mail.maildir.MaildirDirdbmDomain(insServ, 'insertionDomain')
- insServ.addDomain('insertion.domain', domain)
- os.mkdir('insertionQueue')
- insServ.setQueue(mail.relaymanager.Queue('insertionQueue'))
- insServ.domains.setDefaultDomain(mail.relay.DomainQueuer(insServ))
- manager = mail.relaymanager.SmartHostSMTPRelayingManager(insServ.queue)
- manager.fArgs += ('test.identity.hostname',)
- helper = mail.relaymanager.RelayStateHelper(manager, 1)
- # Yoink! Now the internet obeys OUR every whim!
- manager.mxcalc = mail.relaymanager.MXCalculator(self.resolver)
- # And this is our whim.
- self.auth.addresses['destination.domain'] = ['127.0.0.1']
-
- f = insServ.getSMTPFactory()
- self.insServer = reactor.listenTCP(0, f, interface='127.0.0.1')
-
- # Here is the service the previous one will connect to for final
- # delivery
- destServ = mail.mail.MailService()
- destServ.smtpPortal.registerChecker(cred.checkers.AllowAnonymousAccess())
- domain = mail.maildir.MaildirDirdbmDomain(destServ, 'destinationDomain')
- domain.addUser('user', 'password')
- destServ.addDomain('destination.domain', domain)
- os.mkdir('destinationQueue')
- destServ.setQueue(mail.relaymanager.Queue('destinationQueue'))
- manager2 = mail.relaymanager.SmartHostSMTPRelayingManager(destServ.queue)
- helper = mail.relaymanager.RelayStateHelper(manager, 1)
- helper.startService()
-
- f = destServ.getSMTPFactory()
- self.destServer = reactor.listenTCP(0, f, interface='127.0.0.1')
-
- # Update the port number the *first* relay will connect to, because we can't use
- # port 25
- manager.PORT = self.destServer.getHost().port
-
- client = LineSendingProtocol([
- 'HELO meson',
- 'MAIL FROM: <user@wherever>',
- 'RCPT TO: <user@destination.domain>',
- 'DATA',
- 'This is the message',
- '.',
- 'QUIT'
- ])
-
- done = Deferred()
- f = protocol.ClientFactory()
- f.protocol = lambda: client
- f.clientConnectionLost = lambda *args: done.callback(None)
- reactor.connectTCP('127.0.0.1', self.insServer.getHost().port, f)
-
- def finished(ign):
- # First part of the delivery is done. Poke the queue manually now
- # so we don't have to wait for the queue to be flushed.
- delivery = manager.checkState()
- def delivered(ign):
- mbox = domain.requestAvatar('user', None, pop3.IMailbox)[1]
- msg = mbox.getMessage(0).read()
- self.failIfEqual(msg.find('This is the message'), -1)
-
- self.insServer.stopListening()
- self.destServer.stopListening()
- helper.stopService()
- delivery.addCallback(delivered)
- return delivery
- done.addCallback(finished)
- return done
-
-
-aliasFile = StringIO.StringIO("""\
-# Here's a comment
- # woop another one
-testuser: address1,address2, address3,
- continuation@address, |/bin/process/this
-
-usertwo:thisaddress,thataddress, lastaddress
-lastuser: :/includable, /filename, |/program, address
-""")
-
-class LineBufferMessage:
- def __init__(self):
- self.lines = []
- self.eom = False
- self.lost = False
-
- def lineReceived(self, line):
- self.lines.append(line)
-
- def eomReceived(self):
- self.eom = True
- return defer.succeed('<Whatever>')
-
- def connectionLost(self):
- self.lost = True
-
-class AliasTestCase(unittest.TestCase):
- lines = [
- 'First line',
- 'Next line',
- '',
- 'After a blank line',
- 'Last line'
- ]
-
- def setUp(self):
- aliasFile.seek(0)
-
- def testHandle(self):
- result = {}
- lines = [
- 'user: another@host\n',
- 'nextuser: |/bin/program\n',
- 'user: me@again\n',
- 'moreusers: :/etc/include/filename\n',
- 'multiuser: first@host, second@host,last@anotherhost',
- ]
-
- for l in lines:
- mail.alias.handle(result, l, 'TestCase', None)
-
- self.assertEqual(result['user'], ['another@host', 'me@again'])
- self.assertEqual(result['nextuser'], ['|/bin/program'])
- self.assertEqual(result['moreusers'], [':/etc/include/filename'])
- self.assertEqual(result['multiuser'], ['first@host', 'second@host', 'last@anotherhost'])
-
- def testFileLoader(self):
- domains = {'': object()}
- result = mail.alias.loadAliasFile(domains, fp=aliasFile)
-
- self.assertEqual(len(result), 3)
-
- group = result['testuser']
- s = str(group)
- for a in ('address1', 'address2', 'address3', 'continuation@address', '/bin/process/this'):
- self.failIfEqual(s.find(a), -1)
- self.assertEqual(len(group), 5)
-
- group = result['usertwo']
- s = str(group)
- for a in ('thisaddress', 'thataddress', 'lastaddress'):
- self.failIfEqual(s.find(a), -1)
- self.assertEqual(len(group), 3)
-
- group = result['lastuser']
- s = str(group)
- self.assertEqual(s.find('/includable'), -1)
- for a in ('/filename', 'program', 'address'):
- self.failIfEqual(s.find(a), -1, '%s not found' % a)
- self.assertEqual(len(group), 3)
-
- def testMultiWrapper(self):
- msgs = LineBufferMessage(), LineBufferMessage(), LineBufferMessage()
- msg = mail.alias.MultiWrapper(msgs)
-
- for L in self.lines:
- msg.lineReceived(L)
- return msg.eomReceived().addCallback(self._cbMultiWrapper, msgs)
-
- def _cbMultiWrapper(self, ignored, msgs):
- for m in msgs:
- self.failUnless(m.eom)
- self.failIf(m.lost)
- self.assertEqual(self.lines, m.lines)
-
- def testFileAlias(self):
- tmpfile = self.mktemp()
- a = mail.alias.FileAlias(tmpfile, None, None)
- m = a.createMessageReceiver()
-
- for l in self.lines:
- m.lineReceived(l)
- return m.eomReceived().addCallback(self._cbTestFileAlias, tmpfile)
-
- def _cbTestFileAlias(self, ignored, tmpfile):
- lines = file(tmpfile).readlines()
- self.assertEqual([L[:-1] for L in lines], self.lines)
-
-
-
-class DummyProcess(object):
- __slots__ = ['onEnd']
-
-
-
-class MockProcessAlias(mail.alias.ProcessAlias):
- """
- A alias processor that doesn't actually launch processes.
- """
-
- def spawnProcess(self, proto, program, path):
- """
- Don't spawn a process.
- """
-
-
-
-class MockAliasGroup(mail.alias.AliasGroup):
- """
- An alias group using C{MockProcessAlias}.
- """
- processAliasFactory = MockProcessAlias
-
-
-
-class StubProcess(object):
- """
- Fake implementation of L{IProcessTransport}.
-
- @ivar signals: A list of all the signals which have been sent to this fake
- process.
- """
- def __init__(self):
- self.signals = []
-
-
- def loseConnection(self):
- """
- No-op implementation of disconnection.
- """
-
-
- def signalProcess(self, signal):
- """
- Record a signal sent to this process for later inspection.
- """
- self.signals.append(signal)
-
-
-
-class ProcessAliasTestCase(unittest.TestCase):
- """
- Tests for alias resolution.
- """
- if interfaces.IReactorProcess(reactor, None) is None:
- skip = "IReactorProcess not supported"
-
- lines = [
- 'First line',
- 'Next line',
- '',
- 'After a blank line',
- 'Last line'
- ]
-
- def exitStatus(self, code):
- """
- Construct a status from the given exit code.
-
- @type code: L{int} between 0 and 255 inclusive.
- @param code: The exit status which the code will represent.
-
- @rtype: L{int}
- @return: A status integer for the given exit code.
- """
- # /* Macros for constructing status values. */
- # #define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
- status = (code << 8) | 0
-
- # Sanity check
- self.assertTrue(os.WIFEXITED(status))
- self.assertEqual(os.WEXITSTATUS(status), code)
- self.assertFalse(os.WIFSIGNALED(status))
-
- return status
-
-
- def signalStatus(self, signal):
- """
- Construct a status from the given signal.
-
- @type signal: L{int} between 0 and 255 inclusive.
- @param signal: The signal number which the status will represent.
-
- @rtype: L{int}
- @return: A status integer for the given signal.
- """
- # /* If WIFSIGNALED(STATUS), the terminating signal. */
- # #define __WTERMSIG(status) ((status) & 0x7f)
- # /* Nonzero if STATUS indicates termination by a signal. */
- # #define __WIFSIGNALED(status) \
- # (((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
- status = signal
-
- # Sanity check
- self.assertTrue(os.WIFSIGNALED(status))
- self.assertEqual(os.WTERMSIG(status), signal)
- self.assertFalse(os.WIFEXITED(status))
-
- return status
-
-
- def setUp(self):
- """
- Replace L{smtp.DNSNAME} with a well-known value.
- """
- self.DNSNAME = smtp.DNSNAME
- smtp.DNSNAME = ''
-
-
- def tearDown(self):
- """
- Restore the original value of L{smtp.DNSNAME}.
- """
- smtp.DNSNAME = self.DNSNAME
-
-
- def test_processAlias(self):
- """
- Standard call to C{mail.alias.ProcessAlias}: check that the specified
- script is called, and that the input is correctly transferred to it.
- """
- sh = FilePath(self.mktemp())
- sh.setContent("""\
-#!/bin/sh
-rm -f process.alias.out
-while read i; do
- echo $i >> process.alias.out
-done""")
- os.chmod(sh.path, 0700)
- a = mail.alias.ProcessAlias(sh.path, None, None)
- m = a.createMessageReceiver()
-
- for l in self.lines:
- m.lineReceived(l)
-
- def _cbProcessAlias(ignored):
- lines = file('process.alias.out').readlines()
- self.assertEqual([L[:-1] for L in lines], self.lines)
-
- return m.eomReceived().addCallback(_cbProcessAlias)
-
-
- def test_processAliasTimeout(self):
- """
- If the alias child process does not exit within a particular period of
- time, the L{Deferred} returned by L{MessageWrapper.eomReceived} should
- fail with L{ProcessAliasTimeout} and send the I{KILL} signal to the
- child process..
- """
- reactor = task.Clock()
- transport = StubProcess()
- proto = mail.alias.ProcessAliasProtocol()
- proto.makeConnection(transport)
-
- receiver = mail.alias.MessageWrapper(proto, None, reactor)
- d = receiver.eomReceived()
- reactor.advance(receiver.completionTimeout)
- def timedOut(ignored):
- self.assertEqual(transport.signals, ['KILL'])
- # Now that it has been killed, disconnect the protocol associated
- # with it.
- proto.processEnded(
- ProcessTerminated(self.signalStatus(signal.SIGKILL)))
- self.assertFailure(d, mail.alias.ProcessAliasTimeout)
- d.addCallback(timedOut)
- return d
-
-
- def test_earlyProcessTermination(self):
- """
- If the process associated with an L{mail.alias.MessageWrapper} exits
- before I{eomReceived} is called, the L{Deferred} returned by
- I{eomReceived} should fail.
- """
- transport = StubProcess()
- protocol = mail.alias.ProcessAliasProtocol()
- protocol.makeConnection(transport)
- receiver = mail.alias.MessageWrapper(protocol, None, None)
- protocol.processEnded(failure.Failure(ProcessDone(0)))
- return self.assertFailure(receiver.eomReceived(), ProcessDone)
-
-
- def _terminationTest(self, status):
- """
- Verify that if the process associated with an
- L{mail.alias.MessageWrapper} exits with the given status, the
- L{Deferred} returned by I{eomReceived} fails with L{ProcessTerminated}.
- """
- transport = StubProcess()
- protocol = mail.alias.ProcessAliasProtocol()
- protocol.makeConnection(transport)
- receiver = mail.alias.MessageWrapper(protocol, None, None)
- protocol.processEnded(
- failure.Failure(ProcessTerminated(status)))
- return self.assertFailure(receiver.eomReceived(), ProcessTerminated)
-
-
- def test_errorProcessTermination(self):
- """
- If the process associated with an L{mail.alias.MessageWrapper} exits
- with a non-zero exit code, the L{Deferred} returned by I{eomReceived}
- should fail.
- """
- return self._terminationTest(self.exitStatus(1))
-
-
- def test_signalProcessTermination(self):
- """
- If the process associated with an L{mail.alias.MessageWrapper} exits
- because it received a signal, the L{Deferred} returned by
- I{eomReceived} should fail.
- """
- return self._terminationTest(self.signalStatus(signal.SIGHUP))
-
-
- def test_aliasResolution(self):
- """
- Check that the C{resolve} method of alias processors produce the correct
- set of objects:
- - direct alias with L{mail.alias.AddressAlias} if a simple input is passed
- - aliases in a file with L{mail.alias.FileWrapper} if an input in the format
- '/file' is given
- - aliases resulting of a process call wrapped by L{mail.alias.MessageWrapper}
- if the format is '|process'
- """
- aliases = {}
- domain = {'': TestDomain(aliases, ['user1', 'user2', 'user3'])}
- A1 = MockAliasGroup(['user1', '|echo', '/file'], domain, 'alias1')
- A2 = MockAliasGroup(['user2', 'user3'], domain, 'alias2')
- A3 = mail.alias.AddressAlias('alias1', domain, 'alias3')
- aliases.update({
- 'alias1': A1,
- 'alias2': A2,
- 'alias3': A3,
- })
-
- res1 = A1.resolve(aliases)
- r1 = map(str, res1.objs)
- r1.sort()
- expected = map(str, [
- mail.alias.AddressAlias('user1', None, None),
- mail.alias.MessageWrapper(DummyProcess(), 'echo'),
- mail.alias.FileWrapper('/file'),
- ])
- expected.sort()
- self.assertEqual(r1, expected)
-
- res2 = A2.resolve(aliases)
- r2 = map(str, res2.objs)
- r2.sort()
- expected = map(str, [
- mail.alias.AddressAlias('user2', None, None),
- mail.alias.AddressAlias('user3', None, None)
- ])
- expected.sort()
- self.assertEqual(r2, expected)
-
- res3 = A3.resolve(aliases)
- r3 = map(str, res3.objs)
- r3.sort()
- expected = map(str, [
- mail.alias.AddressAlias('user1', None, None),
- mail.alias.MessageWrapper(DummyProcess(), 'echo'),
- mail.alias.FileWrapper('/file'),
- ])
- expected.sort()
- self.assertEqual(r3, expected)
-
-
- def test_cyclicAlias(self):
- """
- Check that a cycle in alias resolution is correctly handled.
- """
- aliases = {}
- domain = {'': TestDomain(aliases, [])}
- A1 = mail.alias.AddressAlias('alias2', domain, 'alias1')
- A2 = mail.alias.AddressAlias('alias3', domain, 'alias2')
- A3 = mail.alias.AddressAlias('alias1', domain, 'alias3')
- aliases.update({
- 'alias1': A1,
- 'alias2': A2,
- 'alias3': A3
- })
-
- self.assertEqual(aliases['alias1'].resolve(aliases), None)
- self.assertEqual(aliases['alias2'].resolve(aliases), None)
- self.assertEqual(aliases['alias3'].resolve(aliases), None)
-
- A4 = MockAliasGroup(['|echo', 'alias1'], domain, 'alias4')
- aliases['alias4'] = A4
-
- res = A4.resolve(aliases)
- r = map(str, res.objs)
- r.sort()
- expected = map(str, [
- mail.alias.MessageWrapper(DummyProcess(), 'echo')
- ])
- expected.sort()
- self.assertEqual(r, expected)
-
-
-
-
-
-
-class TestDomain:
- def __init__(self, aliases, users):
- self.aliases = aliases
- self.users = users
-
- def exists(self, user, memo=None):
- user = user.dest.local
- if user in self.users:
- return lambda: mail.alias.AddressAlias(user, None, None)
- try:
- a = self.aliases[user]
- except:
- raise smtp.SMTPBadRcpt(user)
- else:
- aliases = a.resolve(self.aliases, memo)
- if aliases:
- return lambda: aliases
- raise smtp.SMTPBadRcpt(user)
-
-
-
-class SSLContextFactoryTests(unittest.TestCase):
- """
- Tests for twisted.mail.protocols.SSLContextFactory.
- """
- def test_deprecation(self):
- """
- Accessing L{twisted.mail.protocols.SSLContextFactory} emits a
- deprecation warning recommending the use of the more general SSL context
- factory from L{twisted.internet.ssl}.
- """
- mail.protocols.SSLContextFactory
- warningsShown = self.flushWarnings([self.test_deprecation])
- self.assertEqual(len(warningsShown), 1)
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- warningsShown[0]['message'],
- 'twisted.mail.protocols.SSLContextFactory was deprecated in '
- 'Twisted 12.2.0: Use twisted.internet.ssl.'
- 'DefaultOpenSSLContextFactory instead.')
-
-
-
-from twisted.python.runtime import platformType
-import types
-if platformType != "posix":
- for o in locals().values():
- if isinstance(o, (types.ClassType, type)) and issubclass(o, unittest.TestCase):
- o.skip = "twisted.mail only works on posix"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mailmail.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mailmail.py
deleted file mode 100755
index 8b9e4d87..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_mailmail.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.mail.scripts.mailmail}, the implementation of the
-command line program I{mailmail}.
-"""
-
-import sys
-from StringIO import StringIO
-
-from twisted.trial.unittest import TestCase
-from twisted.mail.scripts.mailmail import parseOptions
-
-
-class OptionsTests(TestCase):
- """
- Tests for L{parseOptions} which parses command line arguments and reads
- message text from stdin to produce an L{Options} instance which can be
- used to send a message.
- """
- def test_unspecifiedRecipients(self):
- """
- If no recipients are given in the argument list and there is no
- recipient header in the message text, L{parseOptions} raises
- L{SystemExit} with a string describing the problem.
- """
- self.addCleanup(setattr, sys, 'stdin', sys.stdin)
- sys.stdin = StringIO(
- 'Subject: foo\n'
- '\n'
- 'Hello, goodbye.\n')
- exc = self.assertRaises(SystemExit, parseOptions, [])
- self.assertEqual(exc.args, ('No recipients specified.',))
-
-
- def test_listQueueInformation(self):
- """
- The I{-bp} option for listing queue information is unsupported and
- if it is passed to L{parseOptions}, L{SystemExit} is raised.
- """
- exc = self.assertRaises(SystemExit, parseOptions, ['-bp'])
- self.assertEqual(exc.args, ("Unsupported option.",))
-
-
- def test_stdioTransport(self):
- """
- The I{-bs} option for using stdin and stdout as the SMTP transport
- is unsupported and if it is passed to L{parseOptions}, L{SystemExit}
- is raised.
- """
- exc = self.assertRaises(SystemExit, parseOptions, ['-bs'])
- self.assertEqual(exc.args, ("Unsupported option.",))
-
-
- def test_ignoreFullStop(self):
- """
- The I{-i} and I{-oi} options for ignoring C{"."} by itself on a line
- are unsupported and if either is passed to L{parseOptions},
- L{SystemExit} is raised.
- """
- exc = self.assertRaises(SystemExit, parseOptions, ['-i'])
- self.assertEqual(exc.args, ("Unsupported option.",))
- exc = self.assertRaises(SystemExit, parseOptions, ['-oi'])
- self.assertEqual(exc.args, ("Unsupported option.",))
-
-
- def test_copyAliasedSender(self):
- """
- The I{-om} option for copying the sender if they appear in an alias
- expansion is unsupported and if it is passed to L{parseOptions},
- L{SystemExit} is raised.
- """
- exc = self.assertRaises(SystemExit, parseOptions, ['-om'])
- self.assertEqual(exc.args, ("Unsupported option.",))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_options.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_options.py
deleted file mode 100755
index daee5d26..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_options.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.mail.tap}.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python.usage import UsageError
-from twisted.mail import protocols
-from twisted.mail.tap import Options, makeService
-from twisted.python.filepath import FilePath
-from twisted.internet import endpoints, defer
-from twisted.python import util
-
-try:
- import OpenSSL
-except ImportError, e:
- sslSkip = str(e)
-else:
- sslSkip = None
-
-
-class OptionsTestCase(TestCase):
- """
- Tests for the command line option parser used for I{twistd mail}.
- """
- def setUp(self):
- self.aliasFilename = self.mktemp()
- aliasFile = file(self.aliasFilename, 'w')
- aliasFile.write('someuser:\tdifferentuser\n')
- aliasFile.close()
-
-
- def testAliasesWithoutDomain(self):
- """
- Test that adding an aliases(5) file before adding a domain raises a
- UsageError.
- """
- self.assertRaises(
- UsageError,
- Options().parseOptions,
- ['--aliases', self.aliasFilename])
-
-
- def testAliases(self):
- """
- Test that adding an aliases(5) file to an IAliasableDomain at least
- doesn't raise an unhandled exception.
- """
- Options().parseOptions([
- '--maildirdbmdomain', 'example.com=example.com',
- '--aliases', self.aliasFilename])
-
-
- def test_barePort(self):
- """
- A bare port passed to I{--pop3} results in deprecation warning in
- addition to a TCP4ServerEndpoint.
- """
- options = Options()
- options.parseOptions(['--pop3', '8110'])
- self.assertEqual(len(options['pop3']), 1)
- self.assertIsInstance(
- options['pop3'][0], endpoints.TCP4ServerEndpoint)
- warnings = self.flushWarnings([options.opt_pop3])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "Specifying plain ports and/or a certificate is deprecated since "
- "Twisted 11.0; use endpoint descriptions instead.")
-
-
- def _endpointTest(self, service):
- """
- Use L{Options} to parse a single service configuration parameter and
- verify that an endpoint of the correct type is added to the list for
- that service.
- """
- options = Options()
- options.parseOptions(['--' + service, 'tcp:1234'])
- self.assertEqual(len(options[service]), 1)
- self.assertIsInstance(
- options[service][0], endpoints.TCP4ServerEndpoint)
-
-
- def test_endpointSMTP(self):
- """
- When I{--smtp} is given a TCP endpoint description as an argument, a
- TCPServerEndpoint is added to the list of SMTP endpoints.
- """
- self._endpointTest('smtp')
-
-
- def test_endpointPOP3(self):
- """
- When I{--pop3} is given a TCP endpoint description as an argument, a
- TCPServerEndpoint is added to the list of POP3 endpoints.
- """
- self._endpointTest('pop3')
-
-
- def test_protoDefaults(self):
- """
- POP3 and SMTP each listen on a TCP4ServerEndpoint by default.
- """
- options = Options()
- options.parseOptions([])
-
- self.assertEqual(len(options['pop3']), 1)
- self.assertIsInstance(
- options['pop3'][0], endpoints.TCP4ServerEndpoint)
-
- self.assertEqual(len(options['smtp']), 1)
- self.assertIsInstance(
- options['smtp'][0], endpoints.TCP4ServerEndpoint)
-
-
- def test_protoDisable(self):
- """
- The I{--no-pop3} and I{--no-smtp} options disable POP3 and SMTP
- respectively.
- """
- options = Options()
- options.parseOptions(['--no-pop3'])
- self.assertEqual(options._getEndpoints(None, 'pop3'), [])
- self.assertNotEquals(options._getEndpoints(None, 'smtp'), [])
-
- options = Options()
- options.parseOptions(['--no-smtp'])
- self.assertNotEquals(options._getEndpoints(None, 'pop3'), [])
- self.assertEqual(options._getEndpoints(None, 'smtp'), [])
-
-
- def test_allProtosDisabledError(self):
- """
- If all protocols are disabled, L{UsageError} is raised.
- """
- options = Options()
- self.assertRaises(
- UsageError, options.parseOptions, (['--no-pop3', '--no-smtp']))
-
-
- def test_pop3sBackwardCompatibility(self):
- """
- The deprecated I{--pop3s} and I{--certificate} options set up a POP3 SSL
- server.
- """
- cert = FilePath(__file__).sibling("server.pem")
- options = Options()
- options.parseOptions(['--pop3s', '8995',
- '--certificate', cert.path])
- self.assertEqual(len(options['pop3']), 2)
- self.assertIsInstance(
- options['pop3'][0], endpoints.SSL4ServerEndpoint)
- self.assertIsInstance(
- options['pop3'][1], endpoints.TCP4ServerEndpoint)
-
- warnings = self.flushWarnings([options.postOptions])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "Specifying plain ports and/or a certificate is deprecated since "
- "Twisted 11.0; use endpoint descriptions instead.")
- if sslSkip is not None:
- test_pop3sBackwardCompatibility.skip = sslSkip
-
-
- def test_esmtpWithoutHostname(self):
- """
- If I{--esmtp} is given without I{--hostname}, L{Options.parseOptions}
- raises L{UsageError}.
- """
- options = Options()
- exc = self.assertRaises(UsageError, options.parseOptions, ['--esmtp'])
- self.assertEqual("--esmtp requires --hostname", str(exc))
-
-
- def test_auth(self):
- """
- Tests that the --auth option registers a checker.
- """
- options = Options()
- options.parseOptions(['--auth', 'memory:admin:admin:bob:password'])
- self.assertEqual(len(options['credCheckers']), 1)
- checker = options['credCheckers'][0]
- interfaces = checker.credentialInterfaces
- registered_checkers = options.service.smtpPortal.checkers
- for iface in interfaces:
- self.assertEqual(checker, registered_checkers[iface])
-
-
-
-class SpyEndpoint(object):
- """
- SpyEndpoint remembers what factory it is told to listen with.
- """
- listeningWith = None
- def listen(self, factory):
- self.listeningWith = factory
- return defer.succeed(None)
-
-
-
-class MakeServiceTests(TestCase):
- """
- Tests for L{twisted.mail.tap.makeService}
- """
- def _endpointServerTest(self, key, factoryClass):
- """
- Configure a service with two endpoints for the protocol associated with
- C{key} and verify that when the service is started a factory of type
- C{factoryClass} is used to listen on each of them.
- """
- cleartext = SpyEndpoint()
- secure = SpyEndpoint()
- config = Options()
- config[key] = [cleartext, secure]
- service = makeService(config)
- service.privilegedStartService()
- service.startService()
- self.addCleanup(service.stopService)
- self.assertIsInstance(cleartext.listeningWith, factoryClass)
- self.assertIsInstance(secure.listeningWith, factoryClass)
-
-
- def test_pop3(self):
- """
- If one or more endpoints is included in the configuration passed to
- L{makeService} for the C{"pop3"} key, a service for starting a POP3
- server is constructed for each of them and attached to the returned
- service.
- """
- self._endpointServerTest("pop3", protocols.POP3Factory)
-
-
- def test_smtp(self):
- """
- If one or more endpoints is included in the configuration passed to
- L{makeService} for the C{"smtp"} key, a service for starting an SMTP
- server is constructed for each of them and attached to the returned
- service.
- """
- self._endpointServerTest("smtp", protocols.SMTPFactory)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3.py
deleted file mode 100755
index 4379a1e3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3.py
+++ /dev/null
@@ -1,1071 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for Ltwisted.mail.pop3} module.
-"""
-
-import StringIO
-import hmac
-import base64
-import itertools
-
-from zope.interface import implements
-
-from twisted.internet import defer
-
-from twisted.trial import unittest, util
-from twisted import mail
-import twisted.mail.protocols
-import twisted.mail.pop3
-import twisted.internet.protocol
-from twisted import internet
-from twisted.mail import pop3
-from twisted.protocols import loopback
-from twisted.python import failure
-from twisted.python.util import OrderedDict
-
-from twisted import cred
-import twisted.cred.portal
-import twisted.cred.checkers
-import twisted.cred.credentials
-
-from twisted.test.proto_helpers import LineSendingProtocol
-
-
-class UtilityTestCase(unittest.TestCase):
- """
- Test the various helper functions and classes used by the POP3 server
- protocol implementation.
- """
-
- def testLineBuffering(self):
- """
- Test creating a LineBuffer and feeding it some lines. The lines should
- build up in its internal buffer for a while and then get spat out to
- the writer.
- """
- output = []
- input = iter(itertools.cycle(['012', '345', '6', '7', '8', '9']))
- c = pop3._IteratorBuffer(output.extend, input, 6)
- i = iter(c)
- self.assertEqual(output, []) # nothing is buffer
- i.next()
- self.assertEqual(output, []) # '012' is buffered
- i.next()
- self.assertEqual(output, []) # '012345' is buffered
- i.next()
- self.assertEqual(output, ['012', '345', '6']) # nothing is buffered
- for n in range(5):
- i.next()
- self.assertEqual(output, ['012', '345', '6', '7', '8', '9', '012', '345'])
-
-
- def testFinishLineBuffering(self):
- """
- Test that a LineBuffer flushes everything when its iterator is
- exhausted, and itself raises StopIteration.
- """
- output = []
- input = iter(['a', 'b', 'c'])
- c = pop3._IteratorBuffer(output.extend, input, 5)
- for i in c:
- pass
- self.assertEqual(output, ['a', 'b', 'c'])
-
-
- def testSuccessResponseFormatter(self):
- """
- Test that the thing that spits out POP3 'success responses' works
- right.
- """
- self.assertEqual(
- pop3.successResponse('Great.'),
- '+OK Great.\r\n')
-
-
- def testStatLineFormatter(self):
- """
- Test that the function which formats stat lines does so appropriately.
- """
- statLine = list(pop3.formatStatResponse([]))[-1]
- self.assertEqual(statLine, '+OK 0 0\r\n')
-
- statLine = list(pop3.formatStatResponse([10, 31, 0, 10101]))[-1]
- self.assertEqual(statLine, '+OK 4 10142\r\n')
-
-
- def testListLineFormatter(self):
- """
- Test that the function which formats the lines in response to a LIST
- command does so appropriately.
- """
- listLines = list(pop3.formatListResponse([]))
- self.assertEqual(
- listLines,
- ['+OK 0\r\n', '.\r\n'])
-
- listLines = list(pop3.formatListResponse([1, 2, 3, 100]))
- self.assertEqual(
- listLines,
- ['+OK 4\r\n', '1 1\r\n', '2 2\r\n', '3 3\r\n', '4 100\r\n', '.\r\n'])
-
-
-
- def testUIDListLineFormatter(self):
- """
- Test that the function which formats lines in response to a UIDL
- command does so appropriately.
- """
- UIDs = ['abc', 'def', 'ghi']
- listLines = list(pop3.formatUIDListResponse([], UIDs.__getitem__))
- self.assertEqual(
- listLines,
- ['+OK \r\n', '.\r\n'])
-
- listLines = list(pop3.formatUIDListResponse([123, 431, 591], UIDs.__getitem__))
- self.assertEqual(
- listLines,
- ['+OK \r\n', '1 abc\r\n', '2 def\r\n', '3 ghi\r\n', '.\r\n'])
-
- listLines = list(pop3.formatUIDListResponse([0, None, 591], UIDs.__getitem__))
- self.assertEqual(
- listLines,
- ['+OK \r\n', '1 abc\r\n', '3 ghi\r\n', '.\r\n'])
-
-
-
-class MyVirtualPOP3(mail.protocols.VirtualPOP3):
-
- magic = '<moshez>'
-
- def authenticateUserAPOP(self, user, digest):
- user, domain = self.lookupDomain(user)
- return self.service.domains['baz.com'].authenticateUserAPOP(user, digest, self.magic, domain)
-
-class DummyDomain:
-
- def __init__(self):
- self.users = {}
-
- def addUser(self, name):
- self.users[name] = []
-
- def addMessage(self, name, message):
- self.users[name].append(message)
-
- def authenticateUserAPOP(self, name, digest, magic, domain):
- return pop3.IMailbox, ListMailbox(self.users[name]), lambda: None
-
-
-class ListMailbox:
-
- def __init__(self, list):
- self.list = list
-
- def listMessages(self, i=None):
- if i is None:
- return map(len, self.list)
- return len(self.list[i])
-
- def getMessage(self, i):
- return StringIO.StringIO(self.list[i])
-
- def getUidl(self, i):
- return i
-
- def deleteMessage(self, i):
- self.list[i] = ''
-
- def sync(self):
- pass
-
-class MyPOP3Downloader(pop3.POP3Client):
-
- def handle_WELCOME(self, line):
- pop3.POP3Client.handle_WELCOME(self, line)
- self.apop('hello@baz.com', 'world')
-
- def handle_APOP(self, line):
- parts = line.split()
- code = parts[0]
- data = (parts[1:] or ['NONE'])[0]
- if code != '+OK':
- print parts
- raise AssertionError, 'code is ' + code
- self.lines = []
- self.retr(1)
-
- def handle_RETR_continue(self, line):
- self.lines.append(line)
-
- def handle_RETR_end(self):
- self.message = '\n'.join(self.lines) + '\n'
- self.quit()
-
- def handle_QUIT(self, line):
- if line[:3] != '+OK':
- raise AssertionError, 'code is ' + line
-
-
-class POP3TestCase(unittest.TestCase):
-
- message = '''\
-Subject: urgent
-
-Someone set up us the bomb!
-'''
-
- expectedOutput = '''\
-+OK <moshez>\015
-+OK Authentication succeeded\015
-+OK \015
-1 0\015
-.\015
-+OK %d\015
-Subject: urgent\015
-\015
-Someone set up us the bomb!\015
-.\015
-+OK \015
-''' % len(message)
-
- def setUp(self):
- self.factory = internet.protocol.Factory()
- self.factory.domains = {}
- self.factory.domains['baz.com'] = DummyDomain()
- self.factory.domains['baz.com'].addUser('hello')
- self.factory.domains['baz.com'].addMessage('hello', self.message)
-
- def testMessages(self):
- client = LineSendingProtocol([
- 'APOP hello@baz.com world',
- 'UIDL',
- 'RETR 1',
- 'QUIT',
- ])
- server = MyVirtualPOP3()
- server.service = self.factory
- def check(ignored):
- output = '\r\n'.join(client.response) + '\r\n'
- self.assertEqual(output, self.expectedOutput)
- return loopback.loopbackTCP(server, client).addCallback(check)
-
- def testLoopback(self):
- protocol = MyVirtualPOP3()
- protocol.service = self.factory
- clientProtocol = MyPOP3Downloader()
- def check(ignored):
- self.assertEqual(clientProtocol.message, self.message)
- protocol.connectionLost(
- failure.Failure(Exception("Test harness disconnect")))
- d = loopback.loopbackAsync(protocol, clientProtocol)
- return d.addCallback(check)
- testLoopback.suppress = [util.suppress(message="twisted.mail.pop3.POP3Client is deprecated")]
-
-
-
-class DummyPOP3(pop3.POP3):
-
- magic = '<moshez>'
-
- def authenticateUserAPOP(self, user, password):
- return pop3.IMailbox, DummyMailbox(ValueError), lambda: None
-
-
-
-class DummyMailbox(pop3.Mailbox):
-
- messages = ['From: moshe\nTo: moshe\n\nHow are you, friend?\n']
-
- def __init__(self, exceptionType):
- self.messages = DummyMailbox.messages[:]
- self.exceptionType = exceptionType
-
- def listMessages(self, i=None):
- if i is None:
- return map(len, self.messages)
- if i >= len(self.messages):
- raise self.exceptionType()
- return len(self.messages[i])
-
- def getMessage(self, i):
- return StringIO.StringIO(self.messages[i])
-
- def getUidl(self, i):
- if i >= len(self.messages):
- raise self.exceptionType()
- return str(i)
-
- def deleteMessage(self, i):
- self.messages[i] = ''
-
-
-class AnotherPOP3TestCase(unittest.TestCase):
-
- def runTest(self, lines, expectedOutput):
- dummy = DummyPOP3()
- client = LineSendingProtocol(lines)
- d = loopback.loopbackAsync(dummy, client)
- return d.addCallback(self._cbRunTest, client, dummy, expectedOutput)
-
-
- def _cbRunTest(self, ignored, client, dummy, expectedOutput):
- self.assertEqual('\r\n'.join(expectedOutput),
- '\r\n'.join(client.response))
- dummy.connectionLost(failure.Failure(Exception("Test harness disconnect")))
- return ignored
-
-
- def test_buffer(self):
- """
- Test a lot of different POP3 commands in an extremely pipelined
- scenario.
-
- This test may cover legitimate behavior, but the intent and
- granularity are not very good. It would likely be an improvement to
- split it into a number of smaller, more focused tests.
- """
- return self.runTest(
- ["APOP moshez dummy",
- "LIST",
- "UIDL",
- "RETR 1",
- "RETR 2",
- "DELE 1",
- "RETR 1",
- "QUIT"],
- ['+OK <moshez>',
- '+OK Authentication succeeded',
- '+OK 1',
- '1 44',
- '.',
- '+OK ',
- '1 0',
- '.',
- '+OK 44',
- 'From: moshe',
- 'To: moshe',
- '',
- 'How are you, friend?',
- '.',
- '-ERR Bad message number argument',
- '+OK ',
- '-ERR message deleted',
- '+OK '])
-
-
- def test_noop(self):
- """
- Test the no-op command.
- """
- return self.runTest(
- ['APOP spiv dummy',
- 'NOOP',
- 'QUIT'],
- ['+OK <moshez>',
- '+OK Authentication succeeded',
- '+OK ',
- '+OK '])
-
-
- def testAuthListing(self):
- p = DummyPOP3()
- p.factory = internet.protocol.Factory()
- p.factory.challengers = {'Auth1': None, 'secondAuth': None, 'authLast': None}
- client = LineSendingProtocol([
- "AUTH",
- "QUIT",
- ])
-
- d = loopback.loopbackAsync(p, client)
- return d.addCallback(self._cbTestAuthListing, client)
-
- def _cbTestAuthListing(self, ignored, client):
- self.failUnless(client.response[1].startswith('+OK'))
- self.assertEqual(sorted(client.response[2:5]),
- ["AUTH1", "AUTHLAST", "SECONDAUTH"])
- self.assertEqual(client.response[5], ".")
-
- def testIllegalPASS(self):
- dummy = DummyPOP3()
- client = LineSendingProtocol([
- "PASS fooz",
- "QUIT"
- ])
- d = loopback.loopbackAsync(dummy, client)
- return d.addCallback(self._cbTestIllegalPASS, client, dummy)
-
- def _cbTestIllegalPASS(self, ignored, client, dummy):
- expected_output = '+OK <moshez>\r\n-ERR USER required before PASS\r\n+OK \r\n'
- self.assertEqual(expected_output, '\r\n'.join(client.response) + '\r\n')
- dummy.connectionLost(failure.Failure(Exception("Test harness disconnect")))
-
- def testEmptyPASS(self):
- dummy = DummyPOP3()
- client = LineSendingProtocol([
- "PASS ",
- "QUIT"
- ])
- d = loopback.loopbackAsync(dummy, client)
- return d.addCallback(self._cbTestEmptyPASS, client, dummy)
-
- def _cbTestEmptyPASS(self, ignored, client, dummy):
- expected_output = '+OK <moshez>\r\n-ERR USER required before PASS\r\n+OK \r\n'
- self.assertEqual(expected_output, '\r\n'.join(client.response) + '\r\n')
- dummy.connectionLost(failure.Failure(Exception("Test harness disconnect")))
-
-
-class TestServerFactory:
- implements(pop3.IServerFactory)
-
- def cap_IMPLEMENTATION(self):
- return "Test Implementation String"
-
- def cap_EXPIRE(self):
- return 60
-
- challengers = OrderedDict([("SCHEME_1", None), ("SCHEME_2", None)])
-
- def cap_LOGIN_DELAY(self):
- return 120
-
- pue = True
- def perUserExpiration(self):
- return self.pue
-
- puld = True
- def perUserLoginDelay(self):
- return self.puld
-
-
-class TestMailbox:
- loginDelay = 100
- messageExpiration = 25
-
-
-class CapabilityTestCase(unittest.TestCase):
- def setUp(self):
- s = StringIO.StringIO()
- p = pop3.POP3()
- p.factory = TestServerFactory()
- p.transport = internet.protocol.FileWrapper(s)
- p.connectionMade()
- p.do_CAPA()
-
- self.caps = p.listCapabilities()
- self.pcaps = s.getvalue().splitlines()
-
- s = StringIO.StringIO()
- p.mbox = TestMailbox()
- p.transport = internet.protocol.FileWrapper(s)
- p.do_CAPA()
-
- self.lpcaps = s.getvalue().splitlines()
- p.connectionLost(failure.Failure(Exception("Test harness disconnect")))
-
- def contained(self, s, *caps):
- for c in caps:
- self.assertIn(s, c)
-
- def testUIDL(self):
- self.contained("UIDL", self.caps, self.pcaps, self.lpcaps)
-
- def testTOP(self):
- self.contained("TOP", self.caps, self.pcaps, self.lpcaps)
-
- def testUSER(self):
- self.contained("USER", self.caps, self.pcaps, self.lpcaps)
-
- def testEXPIRE(self):
- self.contained("EXPIRE 60 USER", self.caps, self.pcaps)
- self.contained("EXPIRE 25", self.lpcaps)
-
- def testIMPLEMENTATION(self):
- self.contained(
- "IMPLEMENTATION Test Implementation String",
- self.caps, self.pcaps, self.lpcaps
- )
-
- def testSASL(self):
- self.contained(
- "SASL SCHEME_1 SCHEME_2",
- self.caps, self.pcaps, self.lpcaps
- )
-
- def testLOGIN_DELAY(self):
- self.contained("LOGIN-DELAY 120 USER", self.caps, self.pcaps)
- self.assertIn("LOGIN-DELAY 100", self.lpcaps)
-
-
-
-class GlobalCapabilitiesTestCase(unittest.TestCase):
- def setUp(self):
- s = StringIO.StringIO()
- p = pop3.POP3()
- p.factory = TestServerFactory()
- p.factory.pue = p.factory.puld = False
- p.transport = internet.protocol.FileWrapper(s)
- p.connectionMade()
- p.do_CAPA()
-
- self.caps = p.listCapabilities()
- self.pcaps = s.getvalue().splitlines()
-
- s = StringIO.StringIO()
- p.mbox = TestMailbox()
- p.transport = internet.protocol.FileWrapper(s)
- p.do_CAPA()
-
- self.lpcaps = s.getvalue().splitlines()
- p.connectionLost(failure.Failure(Exception("Test harness disconnect")))
-
- def contained(self, s, *caps):
- for c in caps:
- self.assertIn(s, c)
-
- def testEXPIRE(self):
- self.contained("EXPIRE 60", self.caps, self.pcaps, self.lpcaps)
-
- def testLOGIN_DELAY(self):
- self.contained("LOGIN-DELAY 120", self.caps, self.pcaps, self.lpcaps)
-
-
-
-class TestRealm:
- def requestAvatar(self, avatarId, mind, *interfaces):
- if avatarId == 'testuser':
- return pop3.IMailbox, DummyMailbox(ValueError), lambda: None
- assert False
-
-
-
-class SASLTestCase(unittest.TestCase):
- def testValidLogin(self):
- p = pop3.POP3()
- p.factory = TestServerFactory()
- p.factory.challengers = {'CRAM-MD5': cred.credentials.CramMD5Credentials}
- p.portal = cred.portal.Portal(TestRealm())
- ch = cred.checkers.InMemoryUsernamePasswordDatabaseDontUse()
- ch.addUser('testuser', 'testpassword')
- p.portal.registerChecker(ch)
-
- s = StringIO.StringIO()
- p.transport = internet.protocol.FileWrapper(s)
- p.connectionMade()
-
- p.lineReceived("CAPA")
- self.failUnless(s.getvalue().find("SASL CRAM-MD5") >= 0)
-
- p.lineReceived("AUTH CRAM-MD5")
- chal = s.getvalue().splitlines()[-1][2:]
- chal = base64.decodestring(chal)
- response = hmac.HMAC('testpassword', chal).hexdigest()
-
- p.lineReceived(base64.encodestring('testuser ' + response).rstrip('\n'))
- self.failUnless(p.mbox)
- self.failUnless(s.getvalue().splitlines()[-1].find("+OK") >= 0)
- p.connectionLost(failure.Failure(Exception("Test harness disconnect")))
-
-
-
-class CommandMixin:
- """
- Tests for all the commands a POP3 server is allowed to receive.
- """
-
- extraMessage = '''\
-From: guy
-To: fellow
-
-More message text for you.
-'''
-
-
- def setUp(self):
- """
- Make a POP3 server protocol instance hooked up to a simple mailbox and
- a transport that buffers output to a StringIO.
- """
- p = pop3.POP3()
- p.mbox = self.mailboxType(self.exceptionType)
- p.schedule = list
- self.pop3Server = p
-
- s = StringIO.StringIO()
- p.transport = internet.protocol.FileWrapper(s)
- p.connectionMade()
- s.truncate(0)
- self.pop3Transport = s
-
-
- def tearDown(self):
- """
- Disconnect the server protocol so it can clean up anything it might
- need to clean up.
- """
- self.pop3Server.connectionLost(failure.Failure(Exception("Test harness disconnect")))
-
-
- def _flush(self):
- """
- Do some of the things that the reactor would take care of, if the
- reactor were actually running.
- """
- # Oh man FileWrapper is pooh.
- self.pop3Server.transport._checkProducer()
-
-
- def testLIST(self):
- """
- Test the two forms of list: with a message index number, which should
- return a short-form response, and without a message index number, which
- should return a long-form response, one line per message.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("LIST 1")
- self._flush()
- self.assertEqual(s.getvalue(), "+OK 1 44\r\n")
- s.truncate(0)
-
- p.lineReceived("LIST")
- self._flush()
- self.assertEqual(s.getvalue(), "+OK 1\r\n1 44\r\n.\r\n")
-
-
- def testLISTWithBadArgument(self):
- """
- Test that non-integers and out-of-bound integers produce appropriate
- error responses.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("LIST a")
- self.assertEqual(
- s.getvalue(),
- "-ERR Invalid message-number: 'a'\r\n")
- s.truncate(0)
-
- p.lineReceived("LIST 0")
- self.assertEqual(
- s.getvalue(),
- "-ERR Invalid message-number: 0\r\n")
- s.truncate(0)
-
- p.lineReceived("LIST 2")
- self.assertEqual(
- s.getvalue(),
- "-ERR Invalid message-number: 2\r\n")
- s.truncate(0)
-
-
- def testUIDL(self):
- """
- Test the two forms of the UIDL command. These are just like the two
- forms of the LIST command.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("UIDL 1")
- self.assertEqual(s.getvalue(), "+OK 0\r\n")
- s.truncate(0)
-
- p.lineReceived("UIDL")
- self._flush()
- self.assertEqual(s.getvalue(), "+OK \r\n1 0\r\n.\r\n")
-
-
- def testUIDLWithBadArgument(self):
- """
- Test that UIDL with a non-integer or an out-of-bounds integer produces
- the appropriate error response.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("UIDL a")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
- p.lineReceived("UIDL 0")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
- p.lineReceived("UIDL 2")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
-
- def testSTAT(self):
- """
- Test the single form of the STAT command, which returns a short-form
- response of the number of messages in the mailbox and their total size.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("STAT")
- self._flush()
- self.assertEqual(s.getvalue(), "+OK 1 44\r\n")
-
-
- def testRETR(self):
- """
- Test downloading a message.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("RETR 1")
- self._flush()
- self.assertEqual(
- s.getvalue(),
- "+OK 44\r\n"
- "From: moshe\r\n"
- "To: moshe\r\n"
- "\r\n"
- "How are you, friend?\r\n"
- ".\r\n")
- s.truncate(0)
-
-
- def testRETRWithBadArgument(self):
- """
- Test that trying to download a message with a bad argument, either not
- an integer or an out-of-bounds integer, fails with the appropriate
- error response.
- """
- p = self.pop3Server
- s = self.pop3Transport
-
- p.lineReceived("RETR a")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
- p.lineReceived("RETR 0")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
- p.lineReceived("RETR 2")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
-
- def testTOP(self):
- """
- Test downloading the headers and part of the body of a message.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived("TOP 1 0")
- self._flush()
- self.assertEqual(
- s.getvalue(),
- "+OK Top of message follows\r\n"
- "From: moshe\r\n"
- "To: moshe\r\n"
- "\r\n"
- ".\r\n")
-
-
- def testTOPWithBadArgument(self):
- """
- Test that trying to download a message with a bad argument, either a
- message number which isn't an integer or is an out-of-bounds integer or
- a number of lines which isn't an integer or is a negative integer,
- fails with the appropriate error response.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived("TOP 1 a")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad line count argument\r\n")
- s.truncate(0)
-
- p.lineReceived("TOP 1 -1")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad line count argument\r\n")
- s.truncate(0)
-
- p.lineReceived("TOP a 1")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
- p.lineReceived("TOP 0 1")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
- p.lineReceived("TOP 3 1")
- self.assertEqual(
- s.getvalue(),
- "-ERR Bad message number argument\r\n")
- s.truncate(0)
-
-
- def testLAST(self):
- """
- Test the exceedingly pointless LAST command, which tells you the
- highest message index which you have already downloaded.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived('LAST')
- self.assertEqual(
- s.getvalue(),
- "+OK 0\r\n")
- s.truncate(0)
-
-
- def testRetrieveUpdatesHighest(self):
- """
- Test that issuing a RETR command updates the LAST response.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived('RETR 2')
- self._flush()
- s.truncate(0)
- p.lineReceived('LAST')
- self.assertEqual(
- s.getvalue(),
- '+OK 2\r\n')
- s.truncate(0)
-
-
- def testTopUpdatesHighest(self):
- """
- Test that issuing a TOP command updates the LAST response.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived('TOP 2 10')
- self._flush()
- s.truncate(0)
- p.lineReceived('LAST')
- self.assertEqual(
- s.getvalue(),
- '+OK 2\r\n')
-
-
- def testHighestOnlyProgresses(self):
- """
- Test that downloading a message with a smaller index than the current
- LAST response doesn't change the LAST response.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived('RETR 2')
- self._flush()
- p.lineReceived('TOP 1 10')
- self._flush()
- s.truncate(0)
- p.lineReceived('LAST')
- self.assertEqual(
- s.getvalue(),
- '+OK 2\r\n')
-
-
- def testResetClearsHighest(self):
- """
- Test that issuing RSET changes the LAST response to 0.
- """
- p = self.pop3Server
- s = self.pop3Transport
- p.mbox.messages.append(self.extraMessage)
-
- p.lineReceived('RETR 2')
- self._flush()
- p.lineReceived('RSET')
- s.truncate(0)
- p.lineReceived('LAST')
- self.assertEqual(
- s.getvalue(),
- '+OK 0\r\n')
-
-
-
-_listMessageDeprecation = (
- "twisted.mail.pop3.IMailbox.listMessages may not "
- "raise IndexError for out-of-bounds message numbers: "
- "raise ValueError instead.")
-_listMessageSuppression = util.suppress(
- message=_listMessageDeprecation,
- category=PendingDeprecationWarning)
-
-_getUidlDeprecation = (
- "twisted.mail.pop3.IMailbox.getUidl may not "
- "raise IndexError for out-of-bounds message numbers: "
- "raise ValueError instead.")
-_getUidlSuppression = util.suppress(
- message=_getUidlDeprecation,
- category=PendingDeprecationWarning)
-
-class IndexErrorCommandTestCase(CommandMixin, unittest.TestCase):
- """
- Run all of the command tests against a mailbox which raises IndexError
- when an out of bounds request is made. This behavior will be deprecated
- shortly and then removed.
- """
- exceptionType = IndexError
- mailboxType = DummyMailbox
-
- def testLISTWithBadArgument(self):
- return CommandMixin.testLISTWithBadArgument(self)
- testLISTWithBadArgument.suppress = [_listMessageSuppression]
-
-
- def testUIDLWithBadArgument(self):
- return CommandMixin.testUIDLWithBadArgument(self)
- testUIDLWithBadArgument.suppress = [_getUidlSuppression]
-
-
- def testTOPWithBadArgument(self):
- return CommandMixin.testTOPWithBadArgument(self)
- testTOPWithBadArgument.suppress = [_listMessageSuppression]
-
-
- def testRETRWithBadArgument(self):
- return CommandMixin.testRETRWithBadArgument(self)
- testRETRWithBadArgument.suppress = [_listMessageSuppression]
-
-
-
-class ValueErrorCommandTestCase(CommandMixin, unittest.TestCase):
- """
- Run all of the command tests against a mailbox which raises ValueError
- when an out of bounds request is made. This is the correct behavior and
- after support for mailboxes which raise IndexError is removed, this will
- become just C{CommandTestCase}.
- """
- exceptionType = ValueError
- mailboxType = DummyMailbox
-
-
-
-class SyncDeferredMailbox(DummyMailbox):
- """
- Mailbox which has a listMessages implementation which returns a Deferred
- which has already fired.
- """
- def listMessages(self, n=None):
- return defer.succeed(DummyMailbox.listMessages(self, n))
-
-
-
-class IndexErrorSyncDeferredCommandTestCase(IndexErrorCommandTestCase):
- """
- Run all of the L{IndexErrorCommandTestCase} tests with a
- synchronous-Deferred returning IMailbox implementation.
- """
- mailboxType = SyncDeferredMailbox
-
-
-
-class ValueErrorSyncDeferredCommandTestCase(ValueErrorCommandTestCase):
- """
- Run all of the L{ValueErrorCommandTestCase} tests with a
- synchronous-Deferred returning IMailbox implementation.
- """
- mailboxType = SyncDeferredMailbox
-
-
-
-class AsyncDeferredMailbox(DummyMailbox):
- """
- Mailbox which has a listMessages implementation which returns a Deferred
- which has not yet fired.
- """
- def __init__(self, *a, **kw):
- self.waiting = []
- DummyMailbox.__init__(self, *a, **kw)
-
-
- def listMessages(self, n=None):
- d = defer.Deferred()
- # See AsyncDeferredMailbox._flush
- self.waiting.append((d, DummyMailbox.listMessages(self, n)))
- return d
-
-
-
-class IndexErrorAsyncDeferredCommandTestCase(IndexErrorCommandTestCase):
- """
- Run all of the L{IndexErrorCommandTestCase} tests with an asynchronous-Deferred
- returning IMailbox implementation.
- """
- mailboxType = AsyncDeferredMailbox
-
- def _flush(self):
- """
- Fire whatever Deferreds we've built up in our mailbox.
- """
- while self.pop3Server.mbox.waiting:
- d, a = self.pop3Server.mbox.waiting.pop()
- d.callback(a)
- IndexErrorCommandTestCase._flush(self)
-
-
-
-class ValueErrorAsyncDeferredCommandTestCase(ValueErrorCommandTestCase):
- """
- Run all of the L{IndexErrorCommandTestCase} tests with an asynchronous-Deferred
- returning IMailbox implementation.
- """
- mailboxType = AsyncDeferredMailbox
-
- def _flush(self):
- """
- Fire whatever Deferreds we've built up in our mailbox.
- """
- while self.pop3Server.mbox.waiting:
- d, a = self.pop3Server.mbox.waiting.pop()
- d.callback(a)
- ValueErrorCommandTestCase._flush(self)
-
-class POP3MiscTestCase(unittest.TestCase):
- """
- Miscellaneous tests more to do with module/package structure than
- anything to do with the Post Office Protocol.
- """
- def test_all(self):
- """
- This test checks that all names listed in
- twisted.mail.pop3.__all__ are actually present in the module.
- """
- mod = twisted.mail.pop3
- for attr in mod.__all__:
- self.failUnless(hasattr(mod, attr))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3client.py
deleted file mode 100755
index 502aae82..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_pop3client.py
+++ /dev/null
@@ -1,582 +0,0 @@
-# -*- test-case-name: twisted.mail.test.test_pop3client -*-
-# Copyright (c) 2001-2004 Divmod Inc.
-# See LICENSE for details.
-
-from zope.interface import directlyProvides
-
-from twisted.mail.pop3 import AdvancedPOP3Client as POP3Client
-from twisted.mail.pop3 import InsecureAuthenticationDisallowed
-from twisted.mail.pop3 import ServerErrorResponse
-from twisted.protocols import loopback
-from twisted.internet import reactor, defer, error, protocol, interfaces
-from twisted.python import log
-
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport
-from twisted.protocols import basic
-
-from twisted.mail.test import pop3testserver
-
-try:
- from twisted.test.ssl_helpers import ClientTLSContext, ServerTLSContext
-except ImportError:
- ClientTLSContext = ServerTLSContext = None
-
-
-class StringTransportWithConnectionLosing(StringTransport):
- def loseConnection(self):
- self.protocol.connectionLost(error.ConnectionDone())
-
-
-capCache = {"TOP": None, "LOGIN-DELAY": "180", "UIDL": None, \
- "STLS": None, "USER": None, "SASL": "LOGIN"}
-def setUp(greet=True):
- p = POP3Client()
-
- # Skip the CAPA login will issue if it doesn't already have a
- # capability cache
- p._capCache = capCache
-
- t = StringTransportWithConnectionLosing()
- t.protocol = p
- p.makeConnection(t)
-
- if greet:
- p.dataReceived('+OK Hello!\r\n')
-
- return p, t
-
-def strip(f):
- return lambda result, f=f: f()
-
-class POP3ClientLoginTestCase(unittest.TestCase):
- def testNegativeGreeting(self):
- p, t = setUp(greet=False)
- p.allowInsecureLogin = True
- d = p.login("username", "password")
- p.dataReceived('-ERR Offline for maintenance\r\n')
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "Offline for maintenance"))
-
-
- def testOkUser(self):
- p, t = setUp()
- d = p.user("username")
- self.assertEqual(t.value(), "USER username\r\n")
- p.dataReceived("+OK send password\r\n")
- return d.addCallback(self.assertEqual, "send password")
-
- def testBadUser(self):
- p, t = setUp()
- d = p.user("username")
- self.assertEqual(t.value(), "USER username\r\n")
- p.dataReceived("-ERR account suspended\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "account suspended"))
-
- def testOkPass(self):
- p, t = setUp()
- d = p.password("password")
- self.assertEqual(t.value(), "PASS password\r\n")
- p.dataReceived("+OK you're in!\r\n")
- return d.addCallback(self.assertEqual, "you're in!")
-
- def testBadPass(self):
- p, t = setUp()
- d = p.password("password")
- self.assertEqual(t.value(), "PASS password\r\n")
- p.dataReceived("-ERR go away\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "go away"))
-
- def testOkLogin(self):
- p, t = setUp()
- p.allowInsecureLogin = True
- d = p.login("username", "password")
- self.assertEqual(t.value(), "USER username\r\n")
- p.dataReceived("+OK go ahead\r\n")
- self.assertEqual(t.value(), "USER username\r\nPASS password\r\n")
- p.dataReceived("+OK password accepted\r\n")
- return d.addCallback(self.assertEqual, "password accepted")
-
- def testBadPasswordLogin(self):
- p, t = setUp()
- p.allowInsecureLogin = True
- d = p.login("username", "password")
- self.assertEqual(t.value(), "USER username\r\n")
- p.dataReceived("+OK waiting on you\r\n")
- self.assertEqual(t.value(), "USER username\r\nPASS password\r\n")
- p.dataReceived("-ERR bogus login\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "bogus login"))
-
- def testBadUsernameLogin(self):
- p, t = setUp()
- p.allowInsecureLogin = True
- d = p.login("username", "password")
- self.assertEqual(t.value(), "USER username\r\n")
- p.dataReceived("-ERR bogus login\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "bogus login"))
-
- def testServerGreeting(self):
- p, t = setUp(greet=False)
- p.dataReceived("+OK lalala this has no challenge\r\n")
- self.assertEqual(p.serverChallenge, None)
-
- def testServerGreetingWithChallenge(self):
- p, t = setUp(greet=False)
- p.dataReceived("+OK <here is the challenge>\r\n")
- self.assertEqual(p.serverChallenge, "<here is the challenge>")
-
- def testAPOP(self):
- p, t = setUp(greet=False)
- p.dataReceived("+OK <challenge string goes here>\r\n")
- d = p.login("username", "password")
- self.assertEqual(t.value(), "APOP username f34f1e464d0d7927607753129cabe39a\r\n")
- p.dataReceived("+OK Welcome!\r\n")
- return d.addCallback(self.assertEqual, "Welcome!")
-
- def testInsecureLoginRaisesException(self):
- p, t = setUp(greet=False)
- p.dataReceived("+OK Howdy\r\n")
- d = p.login("username", "password")
- self.failIf(t.value())
- return self.assertFailure(
- d, InsecureAuthenticationDisallowed)
-
-
- def testSSLTransportConsideredSecure(self):
- """
- If a server doesn't offer APOP but the transport is secured using
- SSL or TLS, a plaintext login should be allowed, not rejected with
- an InsecureAuthenticationDisallowed exception.
- """
- p, t = setUp(greet=False)
- directlyProvides(t, interfaces.ISSLTransport)
- p.dataReceived("+OK Howdy\r\n")
- d = p.login("username", "password")
- self.assertEqual(t.value(), "USER username\r\n")
- t.clear()
- p.dataReceived("+OK\r\n")
- self.assertEqual(t.value(), "PASS password\r\n")
- p.dataReceived("+OK\r\n")
- return d
-
-
-
-class ListConsumer:
- def __init__(self):
- self.data = {}
-
- def consume(self, (item, value)):
- self.data.setdefault(item, []).append(value)
-
-class MessageConsumer:
- def __init__(self):
- self.data = []
-
- def consume(self, line):
- self.data.append(line)
-
-class POP3ClientListTestCase(unittest.TestCase):
- def testListSize(self):
- p, t = setUp()
- d = p.listSize()
- self.assertEqual(t.value(), "LIST\r\n")
- p.dataReceived("+OK Here it comes\r\n")
- p.dataReceived("1 3\r\n2 2\r\n3 1\r\n.\r\n")
- return d.addCallback(self.assertEqual, [3, 2, 1])
-
- def testListSizeWithConsumer(self):
- p, t = setUp()
- c = ListConsumer()
- f = c.consume
- d = p.listSize(f)
- self.assertEqual(t.value(), "LIST\r\n")
- p.dataReceived("+OK Here it comes\r\n")
- p.dataReceived("1 3\r\n2 2\r\n3 1\r\n")
- self.assertEqual(c.data, {0: [3], 1: [2], 2: [1]})
- p.dataReceived("5 3\r\n6 2\r\n7 1\r\n")
- self.assertEqual(c.data, {0: [3], 1: [2], 2: [1], 4: [3], 5: [2], 6: [1]})
- p.dataReceived(".\r\n")
- return d.addCallback(self.assertIdentical, f)
-
- def testFailedListSize(self):
- p, t = setUp()
- d = p.listSize()
- self.assertEqual(t.value(), "LIST\r\n")
- p.dataReceived("-ERR Fatal doom server exploded\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "Fatal doom server exploded"))
-
- def testListUID(self):
- p, t = setUp()
- d = p.listUID()
- self.assertEqual(t.value(), "UIDL\r\n")
- p.dataReceived("+OK Here it comes\r\n")
- p.dataReceived("1 abc\r\n2 def\r\n3 ghi\r\n.\r\n")
- return d.addCallback(self.assertEqual, ["abc", "def", "ghi"])
-
- def testListUIDWithConsumer(self):
- p, t = setUp()
- c = ListConsumer()
- f = c.consume
- d = p.listUID(f)
- self.assertEqual(t.value(), "UIDL\r\n")
- p.dataReceived("+OK Here it comes\r\n")
- p.dataReceived("1 xyz\r\n2 abc\r\n5 mno\r\n")
- self.assertEqual(c.data, {0: ["xyz"], 1: ["abc"], 4: ["mno"]})
- p.dataReceived(".\r\n")
- return d.addCallback(self.assertIdentical, f)
-
- def testFailedListUID(self):
- p, t = setUp()
- d = p.listUID()
- self.assertEqual(t.value(), "UIDL\r\n")
- p.dataReceived("-ERR Fatal doom server exploded\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "Fatal doom server exploded"))
-
-class POP3ClientMessageTestCase(unittest.TestCase):
- def testRetrieve(self):
- p, t = setUp()
- d = p.retrieve(7)
- self.assertEqual(t.value(), "RETR 8\r\n")
- p.dataReceived("+OK Message incoming\r\n")
- p.dataReceived("La la la here is message text\r\n")
- p.dataReceived("..Further message text tra la la\r\n")
- p.dataReceived(".\r\n")
- return d.addCallback(
- self.assertEqual,
- ["La la la here is message text",
- ".Further message text tra la la"])
-
- def testRetrieveWithConsumer(self):
- p, t = setUp()
- c = MessageConsumer()
- f = c.consume
- d = p.retrieve(7, f)
- self.assertEqual(t.value(), "RETR 8\r\n")
- p.dataReceived("+OK Message incoming\r\n")
- p.dataReceived("La la la here is message text\r\n")
- p.dataReceived("..Further message text\r\n.\r\n")
- return d.addCallback(self._cbTestRetrieveWithConsumer, f, c)
-
- def _cbTestRetrieveWithConsumer(self, result, f, c):
- self.assertIdentical(result, f)
- self.assertEqual(c.data, ["La la la here is message text",
- ".Further message text"])
-
- def testPartialRetrieve(self):
- p, t = setUp()
- d = p.retrieve(7, lines=2)
- self.assertEqual(t.value(), "TOP 8 2\r\n")
- p.dataReceived("+OK 2 lines on the way\r\n")
- p.dataReceived("Line the first! Woop\r\n")
- p.dataReceived("Line the last! Bye\r\n")
- p.dataReceived(".\r\n")
- return d.addCallback(
- self.assertEqual,
- ["Line the first! Woop",
- "Line the last! Bye"])
-
- def testPartialRetrieveWithConsumer(self):
- p, t = setUp()
- c = MessageConsumer()
- f = c.consume
- d = p.retrieve(7, f, lines=2)
- self.assertEqual(t.value(), "TOP 8 2\r\n")
- p.dataReceived("+OK 2 lines on the way\r\n")
- p.dataReceived("Line the first! Woop\r\n")
- p.dataReceived("Line the last! Bye\r\n")
- p.dataReceived(".\r\n")
- return d.addCallback(self._cbTestPartialRetrieveWithConsumer, f, c)
-
- def _cbTestPartialRetrieveWithConsumer(self, result, f, c):
- self.assertIdentical(result, f)
- self.assertEqual(c.data, ["Line the first! Woop",
- "Line the last! Bye"])
-
- def testFailedRetrieve(self):
- p, t = setUp()
- d = p.retrieve(0)
- self.assertEqual(t.value(), "RETR 1\r\n")
- p.dataReceived("-ERR Fatal doom server exploded\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "Fatal doom server exploded"))
-
-
- def test_concurrentRetrieves(self):
- """
- Issue three retrieve calls immediately without waiting for any to
- succeed and make sure they all do succeed eventually.
- """
- p, t = setUp()
- messages = [
- p.retrieve(i).addCallback(
- self.assertEqual,
- ["First line of %d." % (i + 1,),
- "Second line of %d." % (i + 1,)])
- for i
- in range(3)]
-
- for i in range(1, 4):
- self.assertEqual(t.value(), "RETR %d\r\n" % (i,))
- t.clear()
- p.dataReceived("+OK 2 lines on the way\r\n")
- p.dataReceived("First line of %d.\r\n" % (i,))
- p.dataReceived("Second line of %d.\r\n" % (i,))
- self.assertEqual(t.value(), "")
- p.dataReceived(".\r\n")
-
- return defer.DeferredList(messages, fireOnOneErrback=True)
-
-
-
-class POP3ClientMiscTestCase(unittest.TestCase):
- def testCapability(self):
- p, t = setUp()
- d = p.capabilities(useCache=0)
- self.assertEqual(t.value(), "CAPA\r\n")
- p.dataReceived("+OK Capabilities on the way\r\n")
- p.dataReceived("X\r\nY\r\nZ\r\nA 1 2 3\r\nB 1 2\r\nC 1\r\n.\r\n")
- return d.addCallback(
- self.assertEqual,
- {"X": None, "Y": None, "Z": None,
- "A": ["1", "2", "3"],
- "B": ["1", "2"],
- "C": ["1"]})
-
- def testCapabilityError(self):
- p, t = setUp()
- d = p.capabilities(useCache=0)
- self.assertEqual(t.value(), "CAPA\r\n")
- p.dataReceived("-ERR This server is lame!\r\n")
- return d.addCallback(self.assertEqual, {})
-
- def testStat(self):
- p, t = setUp()
- d = p.stat()
- self.assertEqual(t.value(), "STAT\r\n")
- p.dataReceived("+OK 1 1212\r\n")
- return d.addCallback(self.assertEqual, (1, 1212))
-
- def testStatError(self):
- p, t = setUp()
- d = p.stat()
- self.assertEqual(t.value(), "STAT\r\n")
- p.dataReceived("-ERR This server is lame!\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "This server is lame!"))
-
- def testNoop(self):
- p, t = setUp()
- d = p.noop()
- self.assertEqual(t.value(), "NOOP\r\n")
- p.dataReceived("+OK No-op to you too!\r\n")
- return d.addCallback(self.assertEqual, "No-op to you too!")
-
- def testNoopError(self):
- p, t = setUp()
- d = p.noop()
- self.assertEqual(t.value(), "NOOP\r\n")
- p.dataReceived("-ERR This server is lame!\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "This server is lame!"))
-
- def testRset(self):
- p, t = setUp()
- d = p.reset()
- self.assertEqual(t.value(), "RSET\r\n")
- p.dataReceived("+OK Reset state\r\n")
- return d.addCallback(self.assertEqual, "Reset state")
-
- def testRsetError(self):
- p, t = setUp()
- d = p.reset()
- self.assertEqual(t.value(), "RSET\r\n")
- p.dataReceived("-ERR This server is lame!\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "This server is lame!"))
-
- def testDelete(self):
- p, t = setUp()
- d = p.delete(3)
- self.assertEqual(t.value(), "DELE 4\r\n")
- p.dataReceived("+OK Hasta la vista\r\n")
- return d.addCallback(self.assertEqual, "Hasta la vista")
-
- def testDeleteError(self):
- p, t = setUp()
- d = p.delete(3)
- self.assertEqual(t.value(), "DELE 4\r\n")
- p.dataReceived("-ERR Winner is not you.\r\n")
- return self.assertFailure(
- d, ServerErrorResponse).addCallback(
- lambda exc: self.assertEqual(exc.args[0], "Winner is not you."))
-
-
-class SimpleClient(POP3Client):
- def __init__(self, deferred, contextFactory = None):
- self.deferred = deferred
- self.allowInsecureLogin = True
-
- def serverGreeting(self, challenge):
- self.deferred.callback(None)
-
-class POP3HelperMixin:
- serverCTX = None
- clientCTX = None
-
- def setUp(self):
- d = defer.Deferred()
- self.server = pop3testserver.POP3TestServer(contextFactory=self.serverCTX)
- self.client = SimpleClient(d, contextFactory=self.clientCTX)
- self.client.timeout = 30
- self.connected = d
-
- def tearDown(self):
- del self.server
- del self.client
- del self.connected
-
- def _cbStopClient(self, ignore):
- self.client.transport.loseConnection()
-
- def _ebGeneral(self, failure):
- self.client.transport.loseConnection()
- self.server.transport.loseConnection()
- return failure
-
- def loopback(self):
- return loopback.loopbackTCP(self.server, self.client, noisy=False)
-
-
-class TLSServerFactory(protocol.ServerFactory):
- class protocol(basic.LineReceiver):
- context = None
- output = []
- def connectionMade(self):
- self.factory.input = []
- self.output = self.output[:]
- map(self.sendLine, self.output.pop(0))
- def lineReceived(self, line):
- self.factory.input.append(line)
- map(self.sendLine, self.output.pop(0))
- if line == 'STLS':
- self.transport.startTLS(self.context)
-
-
-class POP3TLSTestCase(unittest.TestCase):
- """
- Tests for POP3Client's support for TLS connections.
- """
-
- def test_startTLS(self):
- """
- POP3Client.startTLS starts a TLS session over its existing TCP
- connection.
- """
- sf = TLSServerFactory()
- sf.protocol.output = [
- ['+OK'], # Server greeting
- ['+OK', 'STLS', '.'], # CAPA response
- ['+OK'], # STLS response
- ['+OK', '.'], # Second CAPA response
- ['+OK'] # QUIT response
- ]
- sf.protocol.context = ServerTLSContext()
- port = reactor.listenTCP(0, sf, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
- H = port.getHost().host
- P = port.getHost().port
-
- connLostDeferred = defer.Deferred()
- cp = SimpleClient(defer.Deferred(), ClientTLSContext())
- def connectionLost(reason):
- SimpleClient.connectionLost(cp, reason)
- connLostDeferred.callback(None)
- cp.connectionLost = connectionLost
- cf = protocol.ClientFactory()
- cf.protocol = lambda: cp
-
- conn = reactor.connectTCP(H, P, cf)
-
- def cbConnected(ignored):
- log.msg("Connected to server; starting TLS")
- return cp.startTLS()
-
- def cbStartedTLS(ignored):
- log.msg("Started TLS; disconnecting")
- return cp.quit()
-
- def cbDisconnected(ign):
- log.msg("Disconnected; asserting correct input received")
- self.assertEqual(
- sf.input,
- ['CAPA', 'STLS', 'CAPA', 'QUIT'])
-
- def cleanup(result):
- log.msg("Asserted correct input; disconnecting client and shutting down server")
- conn.disconnect()
- return connLostDeferred
-
- cp.deferred.addCallback(cbConnected)
- cp.deferred.addCallback(cbStartedTLS)
- cp.deferred.addCallback(cbDisconnected)
- cp.deferred.addBoth(cleanup)
-
- return cp.deferred
-
-
-class POP3TimeoutTestCase(POP3HelperMixin, unittest.TestCase):
- def testTimeout(self):
- def login():
- d = self.client.login('test', 'twisted')
- d.addCallback(loggedIn)
- d.addErrback(timedOut)
- return d
-
- def loggedIn(result):
- self.fail("Successfully logged in!? Impossible!")
-
-
- def timedOut(failure):
- failure.trap(error.TimeoutError)
- self._cbStopClient(None)
-
- def quit():
- return self.client.quit()
-
- self.client.timeout = 0.01
-
- # Tell the server to not return a response to client. This
- # will trigger a timeout.
- pop3testserver.TIMEOUT_RESPONSE = True
-
- methods = [login, quit]
- map(self.connected.addCallback, map(strip, methods))
- self.connected.addCallback(self._cbStopClient)
- self.connected.addErrback(self._ebGeneral)
- return self.loopback()
-
-
-if ClientTLSContext is None:
- for case in (POP3TLSTestCase,):
- case.skip = "OpenSSL not present"
-elif interfaces.IReactorSSL(reactor, None) is None:
- for case in (POP3TLSTestCase,):
- case.skip = "Reactor doesn't support SSL"
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_scripts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_scripts.py
deleted file mode 100755
index cc14061f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_scripts.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the command-line mailer tool provided by Twisted Mail.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.scripts.test.test_scripts import ScriptTestsMixin
-
-
-
-class ScriptTests(TestCase, ScriptTestsMixin):
- """
- Tests for all one of mail's scripts.
- """
- def test_mailmail(self):
- self.scriptTest("mail/mailmail")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_smtp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_smtp.py
deleted file mode 100755
index 058bb8ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/test/test_smtp.py
+++ /dev/null
@@ -1,1520 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.mail.smtp module.
-"""
-
-from zope.interface import implements
-
-from twisted.python.util import LineLog
-from twisted.trial import unittest, util
-from twisted.protocols import basic, loopback
-from twisted.mail import smtp
-from twisted.internet import defer, protocol, reactor, interfaces
-from twisted.internet import address, error, task
-from twisted.test.proto_helpers import StringTransport
-
-from twisted import cred
-import twisted.cred.error
-import twisted.cred.portal
-import twisted.cred.checkers
-import twisted.cred.credentials
-
-from twisted.cred.portal import IRealm, Portal
-from twisted.cred.checkers import ICredentialsChecker, AllowAnonymousAccess
-from twisted.cred.credentials import IAnonymous
-from twisted.cred.error import UnauthorizedLogin
-
-from twisted.mail import imap4
-
-
-try:
- from twisted.test.ssl_helpers import ClientTLSContext, ServerTLSContext
-except ImportError:
- ClientTLSContext = ServerTLSContext = None
-
-import re
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-
-def spameater(*spam, **eggs):
- return None
-
-
-
-class BrokenMessage(object):
- """
- L{BrokenMessage} is an L{IMessage} which raises an unexpected exception
- from its C{eomReceived} method. This is useful for creating a server which
- can be used to test client retry behavior.
- """
- implements(smtp.IMessage)
-
- def __init__(self, user):
- pass
-
-
- def lineReceived(self, line):
- pass
-
-
- def eomReceived(self):
- raise RuntimeError("Some problem, delivery is failing.")
-
-
- def connectionLost(self):
- pass
-
-
-
-class DummyMessage(object):
- """
- L{BrokenMessage} is an L{IMessage} which saves the message delivered to it
- to its domain object.
-
- @ivar domain: A L{DummyDomain} which will be used to store the message once
- it is received.
- """
- def __init__(self, domain, user):
- self.domain = domain
- self.user = user
- self.buffer = []
-
-
- def lineReceived(self, line):
- # Throw away the generated Received: header
- if not re.match('Received: From yyy.com \(\[.*\]\) by localhost;', line):
- self.buffer.append(line)
-
-
- def eomReceived(self):
- message = '\n'.join(self.buffer) + '\n'
- self.domain.messages[self.user.dest.local].append(message)
- deferred = defer.Deferred()
- deferred.callback("saved")
- return deferred
-
-
-
-class DummyDomain(object):
- """
- L{DummyDomain} is an L{IDomain} which keeps track of messages delivered to
- it in memory.
- """
- def __init__(self, names):
- self.messages = {}
- for name in names:
- self.messages[name] = []
-
-
- def exists(self, user):
- if user.dest.local in self.messages:
- return defer.succeed(lambda: self.startMessage(user))
- return defer.fail(smtp.SMTPBadRcpt(user))
-
-
- def startMessage(self, user):
- return DummyMessage(self, user)
-
-
-
-class SMTPTestCase(unittest.TestCase):
-
- messages = [('foo@bar.com', ['foo@baz.com', 'qux@baz.com'], '''\
-Subject: urgent\015
-\015
-Someone set up us the bomb!\015
-''')]
-
- mbox = {'foo': ['Subject: urgent\n\nSomeone set up us the bomb!\n']}
-
- def setUp(self):
- """
- Create an in-memory mail domain to which messages may be delivered by
- tests and create a factory and transport to do the delivering.
- """
- self.factory = smtp.SMTPFactory()
- self.factory.domains = {}
- self.factory.domains['baz.com'] = DummyDomain(['foo'])
- self.transport = StringTransport()
-
-
- def testMessages(self):
- from twisted.mail import protocols
- protocol = protocols.DomainSMTP()
- protocol.service = self.factory
- protocol.factory = self.factory
- protocol.receivedHeader = spameater
- protocol.makeConnection(self.transport)
- protocol.lineReceived('HELO yyy.com')
- for message in self.messages:
- protocol.lineReceived('MAIL FROM:<%s>' % message[0])
- for target in message[1]:
- protocol.lineReceived('RCPT TO:<%s>' % target)
- protocol.lineReceived('DATA')
- protocol.dataReceived(message[2])
- protocol.lineReceived('.')
- protocol.lineReceived('QUIT')
- if self.mbox != self.factory.domains['baz.com'].messages:
- raise AssertionError(self.factory.domains['baz.com'].messages)
- protocol.setTimeout(None)
-
- testMessages.suppress = [util.suppress(message='DomainSMTP', category=DeprecationWarning)]
-
-mail = '''\
-Subject: hello
-
-Goodbye
-'''
-
-class MyClient:
- def __init__(self, messageInfo=None):
- if messageInfo is None:
- messageInfo = (
- 'moshez@foo.bar', ['moshez@foo.bar'], StringIO(mail))
- self._sender = messageInfo[0]
- self._recipient = messageInfo[1]
- self._data = messageInfo[2]
-
-
- def getMailFrom(self):
- return self._sender
-
-
- def getMailTo(self):
- return self._recipient
-
-
- def getMailData(self):
- return self._data
-
-
- def sendError(self, exc):
- self._error = exc
-
-
- def sentMail(self, code, resp, numOk, addresses, log):
- # Prevent another mail from being sent.
- self._sender = None
- self._recipient = None
- self._data = None
-
-
-
-class MySMTPClient(MyClient, smtp.SMTPClient):
- def __init__(self, messageInfo=None):
- smtp.SMTPClient.__init__(self, 'foo.baz')
- MyClient.__init__(self, messageInfo)
-
-class MyESMTPClient(MyClient, smtp.ESMTPClient):
- def __init__(self, secret = '', contextFactory = None):
- smtp.ESMTPClient.__init__(self, secret, contextFactory, 'foo.baz')
- MyClient.__init__(self)
-
-class LoopbackMixin:
- def loopback(self, server, client):
- return loopback.loopbackTCP(server, client)
-
-class LoopbackTestCase(LoopbackMixin):
- def testMessages(self):
- factory = smtp.SMTPFactory()
- factory.domains = {}
- factory.domains['foo.bar'] = DummyDomain(['moshez'])
- from twisted.mail.protocols import DomainSMTP
- protocol = DomainSMTP()
- protocol.service = factory
- protocol.factory = factory
- clientProtocol = self.clientClass()
- return self.loopback(protocol, clientProtocol)
- testMessages.suppress = [util.suppress(message='DomainSMTP', category=DeprecationWarning)]
-
-class LoopbackSMTPTestCase(LoopbackTestCase, unittest.TestCase):
- clientClass = MySMTPClient
-
-class LoopbackESMTPTestCase(LoopbackTestCase, unittest.TestCase):
- clientClass = MyESMTPClient
-
-
-class FakeSMTPServer(basic.LineReceiver):
-
- clientData = [
- '220 hello', '250 nice to meet you',
- '250 great', '250 great', '354 go on, lad'
- ]
-
- def connectionMade(self):
- self.buffer = []
- self.clientData = self.clientData[:]
- self.clientData.reverse()
- self.sendLine(self.clientData.pop())
-
- def lineReceived(self, line):
- self.buffer.append(line)
- if line == "QUIT":
- self.transport.write("221 see ya around\r\n")
- self.transport.loseConnection()
- elif line == ".":
- self.transport.write("250 gotcha\r\n")
- elif line == "RSET":
- self.transport.loseConnection()
-
- if self.clientData:
- self.sendLine(self.clientData.pop())
-
-
-class SMTPClientTestCase(unittest.TestCase, LoopbackMixin):
- """
- Tests for L{smtp.SMTPClient}.
- """
-
- def test_timeoutConnection(self):
- """
- L{smtp.SMTPClient.timeoutConnection} calls the C{sendError} hook with a
- fatal L{SMTPTimeoutError} with the current line log.
- """
- error = []
- client = MySMTPClient()
- client.sendError = error.append
- client.makeConnection(StringTransport())
- client.lineReceived("220 hello")
- client.timeoutConnection()
- self.assertIsInstance(error[0], smtp.SMTPTimeoutError)
- self.assertTrue(error[0].isFatal)
- self.assertEqual(
- str(error[0]),
- "Timeout waiting for SMTP server response\n"
- "<<< 220 hello\n"
- ">>> HELO foo.baz\n")
-
-
- expected_output = [
- 'HELO foo.baz', 'MAIL FROM:<moshez@foo.bar>',
- 'RCPT TO:<moshez@foo.bar>', 'DATA',
- 'Subject: hello', '', 'Goodbye', '.', 'RSET'
- ]
-
- def test_messages(self):
- """
- L{smtp.SMTPClient} sends I{HELO}, I{MAIL FROM}, I{RCPT TO}, and I{DATA}
- commands based on the return values of its C{getMailFrom},
- C{getMailTo}, and C{getMailData} methods.
- """
- client = MySMTPClient()
- server = FakeSMTPServer()
- d = self.loopback(server, client)
- d.addCallback(lambda x :
- self.assertEqual(server.buffer, self.expected_output))
- return d
-
-
- def test_transferError(self):
- """
- If there is an error while producing the message body to the
- connection, the C{sendError} callback is invoked.
- """
- client = MySMTPClient(
- ('alice@example.com', ['bob@example.com'], StringIO("foo")))
- transport = StringTransport()
- client.makeConnection(transport)
- client.dataReceived(
- '220 Ok\r\n' # Greeting
- '250 Ok\r\n' # EHLO response
- '250 Ok\r\n' # MAIL FROM response
- '250 Ok\r\n' # RCPT TO response
- '354 Ok\r\n' # DATA response
- )
-
- # Sanity check - a pull producer should be registered now.
- self.assertNotIdentical(transport.producer, None)
- self.assertFalse(transport.streaming)
-
- # Now stop the producer prematurely, meaning the message was not sent.
- transport.producer.stopProducing()
-
- # The sendError hook should have been invoked as a result.
- self.assertIsInstance(client._error, Exception)
-
-
- def test_sendFatalError(self):
- """
- If L{smtp.SMTPClient.sendError} is called with an L{SMTPClientError}
- which is fatal, it disconnects its transport without writing anything
- more to it.
- """
- client = smtp.SMTPClient(None)
- transport = StringTransport()
- client.makeConnection(transport)
- client.sendError(smtp.SMTPClientError(123, "foo", isFatal=True))
- self.assertEqual(transport.value(), "")
- self.assertTrue(transport.disconnecting)
-
-
- def test_sendNonFatalError(self):
- """
- If L{smtp.SMTPClient.sendError} is called with an L{SMTPClientError}
- which is not fatal, it sends C{"QUIT"} and waits for the server to
- close the connection.
- """
- client = smtp.SMTPClient(None)
- transport = StringTransport()
- client.makeConnection(transport)
- client.sendError(smtp.SMTPClientError(123, "foo", isFatal=False))
- self.assertEqual(transport.value(), "QUIT\r\n")
- self.assertFalse(transport.disconnecting)
-
-
- def test_sendOtherError(self):
- """
- If L{smtp.SMTPClient.sendError} is called with an exception which is
- not an L{SMTPClientError}, it disconnects its transport without
- writing anything more to it.
- """
- client = smtp.SMTPClient(None)
- transport = StringTransport()
- client.makeConnection(transport)
- client.sendError(Exception("foo"))
- self.assertEqual(transport.value(), "")
- self.assertTrue(transport.disconnecting)
-
-
-
-class DummySMTPMessage:
-
- def __init__(self, protocol, users):
- self.protocol = protocol
- self.users = users
- self.buffer = []
-
- def lineReceived(self, line):
- self.buffer.append(line)
-
- def eomReceived(self):
- message = '\n'.join(self.buffer) + '\n'
- helo, origin = self.users[0].helo[0], str(self.users[0].orig)
- recipients = []
- for user in self.users:
- recipients.append(str(user))
- self.protocol.message[tuple(recipients)] = (helo, origin, recipients, message)
- return defer.succeed("saved")
-
-
-
-class DummyProto:
- def connectionMade(self):
- self.dummyMixinBase.connectionMade(self)
- self.message = {}
-
- def startMessage(self, users):
- return DummySMTPMessage(self, users)
-
- def receivedHeader(*spam):
- return None
-
- def validateTo(self, user):
- self.delivery = SimpleDelivery(None)
- return lambda: self.startMessage([user])
-
- def validateFrom(self, helo, origin):
- return origin
-
-
-
-class DummySMTP(DummyProto, smtp.SMTP):
- dummyMixinBase = smtp.SMTP
-
-class DummyESMTP(DummyProto, smtp.ESMTP):
- dummyMixinBase = smtp.ESMTP
-
-class AnotherTestCase:
- serverClass = None
- clientClass = None
-
- messages = [ ('foo.com', 'moshez@foo.com', ['moshez@bar.com'],
- 'moshez@foo.com', ['moshez@bar.com'], '''\
-From: Moshe
-To: Moshe
-
-Hi,
-how are you?
-'''),
- ('foo.com', 'tttt@rrr.com', ['uuu@ooo', 'yyy@eee'],
- 'tttt@rrr.com', ['uuu@ooo', 'yyy@eee'], '''\
-Subject: pass
-
-..rrrr..
-'''),
- ('foo.com', '@this,@is,@ignored:foo@bar.com',
- ['@ignore,@this,@too:bar@foo.com'],
- 'foo@bar.com', ['bar@foo.com'], '''\
-Subject: apa
-To: foo
-
-123
-.
-456
-'''),
- ]
-
- data = [
- ('', '220.*\r\n$', None, None),
- ('HELO foo.com\r\n', '250.*\r\n$', None, None),
- ('RSET\r\n', '250.*\r\n$', None, None),
- ]
- for helo_, from_, to_, realfrom, realto, msg in messages:
- data.append(('MAIL FROM:<%s>\r\n' % from_, '250.*\r\n',
- None, None))
- for rcpt in to_:
- data.append(('RCPT TO:<%s>\r\n' % rcpt, '250.*\r\n',
- None, None))
-
- data.append(('DATA\r\n','354.*\r\n',
- msg, ('250.*\r\n',
- (helo_, realfrom, realto, msg))))
-
-
- def test_buffer(self):
- """
- Exercise a lot of the SMTP client code. This is a "shotgun" style unit
- test. It does a lot of things and hopes that something will go really
- wrong if it is going to go wrong. This test should be replaced with a
- suite of nicer tests.
- """
- transport = StringTransport()
- a = self.serverClass()
- class fooFactory:
- domain = 'foo.com'
-
- a.factory = fooFactory()
- a.makeConnection(transport)
- for (send, expect, msg, msgexpect) in self.data:
- if send:
- a.dataReceived(send)
- data = transport.value()
- transport.clear()
- if not re.match(expect, data):
- raise AssertionError, (send, expect, data)
- if data[:3] == '354':
- for line in msg.splitlines():
- if line and line[0] == '.':
- line = '.' + line
- a.dataReceived(line + '\r\n')
- a.dataReceived('.\r\n')
- # Special case for DATA. Now we want a 250, and then
- # we compare the messages
- data = transport.value()
- transport.clear()
- resp, msgdata = msgexpect
- if not re.match(resp, data):
- raise AssertionError, (resp, data)
- for recip in msgdata[2]:
- expected = list(msgdata[:])
- expected[2] = [recip]
- self.assertEqual(
- a.message[(recip,)],
- tuple(expected)
- )
- a.setTimeout(None)
-
-
-class AnotherESMTPTestCase(AnotherTestCase, unittest.TestCase):
- serverClass = DummyESMTP
- clientClass = MyESMTPClient
-
-class AnotherSMTPTestCase(AnotherTestCase, unittest.TestCase):
- serverClass = DummySMTP
- clientClass = MySMTPClient
-
-
-
-class DummyChecker:
- implements(cred.checkers.ICredentialsChecker)
-
- users = {
- 'testuser': 'testpassword'
- }
-
- credentialInterfaces = (cred.credentials.IUsernamePassword,
- cred.credentials.IUsernameHashedPassword)
-
- def requestAvatarId(self, credentials):
- return defer.maybeDeferred(
- credentials.checkPassword, self.users[credentials.username]
- ).addCallback(self._cbCheck, credentials.username)
-
- def _cbCheck(self, result, username):
- if result:
- return username
- raise cred.error.UnauthorizedLogin()
-
-
-
-class SimpleDelivery(object):
- """
- L{SimpleDelivery} is a message delivery factory with no interesting
- behavior.
- """
- implements(smtp.IMessageDelivery)
-
- def __init__(self, messageFactory):
- self._messageFactory = messageFactory
-
-
- def receivedHeader(self, helo, origin, recipients):
- return None
-
-
- def validateFrom(self, helo, origin):
- return origin
-
-
- def validateTo(self, user):
- return lambda: self._messageFactory(user)
-
-
-
-class DummyRealm:
- def requestAvatar(self, avatarId, mind, *interfaces):
- return smtp.IMessageDelivery, SimpleDelivery(None), lambda: None
-
-
-
-class AuthTestCase(unittest.TestCase, LoopbackMixin):
- def test_crammd5Auth(self):
- """
- L{ESMTPClient} can authenticate using the I{CRAM-MD5} SASL mechanism.
-
- @see: U{http://tools.ietf.org/html/rfc2195}
- """
- realm = DummyRealm()
- p = cred.portal.Portal(realm)
- p.registerChecker(DummyChecker())
-
- server = DummyESMTP({'CRAM-MD5': cred.credentials.CramMD5Credentials})
- server.portal = p
- client = MyESMTPClient('testpassword')
-
- cAuth = smtp.CramMD5ClientAuthenticator('testuser')
- client.registerAuthenticator(cAuth)
-
- d = self.loopback(server, client)
- d.addCallback(lambda x : self.assertEqual(server.authenticated, 1))
- return d
-
-
- def test_loginAuth(self):
- """
- L{ESMTPClient} can authenticate using the I{LOGIN} SASL mechanism.
-
- @see: U{http://sepp.oetiker.ch/sasl-2.1.19-ds/draft-murchison-sasl-login-00.txt}
- """
- realm = DummyRealm()
- p = cred.portal.Portal(realm)
- p.registerChecker(DummyChecker())
-
- server = DummyESMTP({'LOGIN': imap4.LOGINCredentials})
- server.portal = p
- client = MyESMTPClient('testpassword')
-
- cAuth = smtp.LOGINAuthenticator('testuser')
- client.registerAuthenticator(cAuth)
-
- d = self.loopback(server, client)
- d.addCallback(lambda x: self.assertTrue(server.authenticated))
- return d
-
-
- def test_loginAgainstWeirdServer(self):
- """
- When communicating with a server which implements the I{LOGIN} SASL
- mechanism using C{"Username:"} as the challenge (rather than C{"User
- Name\\0"}), L{ESMTPClient} can still authenticate successfully using
- the I{LOGIN} mechanism.
- """
- realm = DummyRealm()
- p = cred.portal.Portal(realm)
- p.registerChecker(DummyChecker())
-
- server = DummyESMTP({'LOGIN': smtp.LOGINCredentials})
- server.portal = p
-
- client = MyESMTPClient('testpassword')
- cAuth = smtp.LOGINAuthenticator('testuser')
- client.registerAuthenticator(cAuth)
-
- d = self.loopback(server, client)
- d.addCallback(lambda x: self.assertTrue(server.authenticated))
- return d
-
-
-
-class SMTPHelperTestCase(unittest.TestCase):
- def testMessageID(self):
- d = {}
- for i in range(1000):
- m = smtp.messageid('testcase')
- self.failIf(m in d)
- d[m] = None
-
- def testQuoteAddr(self):
- cases = [
- ['user@host.name', '<user@host.name>'],
- ['"User Name" <user@host.name>', '<user@host.name>'],
- [smtp.Address('someguy@someplace'), '<someguy@someplace>'],
- ['', '<>'],
- [smtp.Address(''), '<>'],
- ]
-
- for (c, e) in cases:
- self.assertEqual(smtp.quoteaddr(c), e)
-
- def testUser(self):
- u = smtp.User('user@host', 'helo.host.name', None, None)
- self.assertEqual(str(u), 'user@host')
-
- def testXtextEncoding(self):
- cases = [
- ('Hello world', 'Hello+20world'),
- ('Hello+world', 'Hello+2Bworld'),
- ('\0\1\2\3\4\5', '+00+01+02+03+04+05'),
- ('e=mc2@example.com', 'e+3Dmc2@example.com')
- ]
-
- for (case, expected) in cases:
- self.assertEqual(smtp.xtext_encode(case), (expected, len(case)))
- self.assertEqual(case.encode('xtext'), expected)
- self.assertEqual(
- smtp.xtext_decode(expected), (case, len(expected)))
- self.assertEqual(expected.decode('xtext'), case)
-
-
- def test_encodeWithErrors(self):
- """
- Specifying an error policy to C{unicode.encode} with the
- I{xtext} codec should produce the same result as not
- specifying the error policy.
- """
- text = u'Hello world'
- self.assertEqual(
- smtp.xtext_encode(text, 'strict'),
- (text.encode('xtext'), len(text)))
- self.assertEqual(
- text.encode('xtext', 'strict'),
- text.encode('xtext'))
-
-
- def test_decodeWithErrors(self):
- """
- Similar to L{test_encodeWithErrors}, but for C{str.decode}.
- """
- bytes = 'Hello world'
- self.assertEqual(
- smtp.xtext_decode(bytes, 'strict'),
- (bytes.decode('xtext'), len(bytes)))
- self.assertEqual(
- bytes.decode('xtext', 'strict'),
- bytes.decode('xtext'))
-
-
-
-class NoticeTLSClient(MyESMTPClient):
- tls = False
-
- def esmtpState_starttls(self, code, resp):
- MyESMTPClient.esmtpState_starttls(self, code, resp)
- self.tls = True
-
-class TLSTestCase(unittest.TestCase, LoopbackMixin):
- def testTLS(self):
- clientCTX = ClientTLSContext()
- serverCTX = ServerTLSContext()
-
- client = NoticeTLSClient(contextFactory=clientCTX)
- server = DummyESMTP(contextFactory=serverCTX)
-
- def check(ignored):
- self.assertEqual(client.tls, True)
- self.assertEqual(server.startedTLS, True)
-
- return self.loopback(server, client).addCallback(check)
-
-if ClientTLSContext is None:
- for case in (TLSTestCase,):
- case.skip = "OpenSSL not present"
-
-if not interfaces.IReactorSSL.providedBy(reactor):
- for case in (TLSTestCase,):
- case.skip = "Reactor doesn't support SSL"
-
-class EmptyLineTestCase(unittest.TestCase):
- def test_emptyLineSyntaxError(self):
- """
- If L{smtp.SMTP} receives an empty line, it responds with a 500 error
- response code and a message about a syntax error.
- """
- proto = smtp.SMTP()
- transport = StringTransport()
- proto.makeConnection(transport)
- proto.lineReceived('')
- proto.setTimeout(None)
-
- out = transport.value().splitlines()
- self.assertEqual(len(out), 2)
- self.failUnless(out[0].startswith('220'))
- self.assertEqual(out[1], "500 Error: bad syntax")
-
-
-
-class TimeoutTestCase(unittest.TestCase, LoopbackMixin):
- """
- Check that SMTP client factories correctly use the timeout.
- """
-
- def _timeoutTest(self, onDone, clientFactory):
- """
- Connect the clientFactory, and check the timeout on the request.
- """
- clock = task.Clock()
- client = clientFactory.buildProtocol(
- address.IPv4Address('TCP', 'example.net', 25))
- client.callLater = clock.callLater
- t = StringTransport()
- client.makeConnection(t)
- t.protocol = client
- def check(ign):
- self.assertEqual(clock.seconds(), 0.5)
- d = self.assertFailure(onDone, smtp.SMTPTimeoutError
- ).addCallback(check)
- # The first call should not trigger the timeout
- clock.advance(0.1)
- # But this one should
- clock.advance(0.4)
- return d
-
-
- def test_SMTPClient(self):
- """
- Test timeout for L{smtp.SMTPSenderFactory}: the response L{Deferred}
- should be errback with a L{smtp.SMTPTimeoutError}.
- """
- onDone = defer.Deferred()
- clientFactory = smtp.SMTPSenderFactory(
- 'source@address', 'recipient@address',
- StringIO("Message body"), onDone,
- retries=0, timeout=0.5)
- return self._timeoutTest(onDone, clientFactory)
-
-
- def test_ESMTPClient(self):
- """
- Test timeout for L{smtp.ESMTPSenderFactory}: the response L{Deferred}
- should be errback with a L{smtp.SMTPTimeoutError}.
- """
- onDone = defer.Deferred()
- clientFactory = smtp.ESMTPSenderFactory(
- 'username', 'password',
- 'source@address', 'recipient@address',
- StringIO("Message body"), onDone,
- retries=0, timeout=0.5)
- return self._timeoutTest(onDone, clientFactory)
-
-
- def test_resetTimeoutWhileSending(self):
- """
- The timeout is not allowed to expire after the server has accepted a
- DATA command and the client is actively sending data to it.
- """
- class SlowFile:
- """
- A file-like which returns one byte from each read call until the
- specified number of bytes have been returned.
- """
- def __init__(self, size):
- self._size = size
-
- def read(self, max=None):
- if self._size:
- self._size -= 1
- return 'x'
- return ''
-
- failed = []
- onDone = defer.Deferred()
- onDone.addErrback(failed.append)
- clientFactory = smtp.SMTPSenderFactory(
- 'source@address', 'recipient@address',
- SlowFile(1), onDone, retries=0, timeout=3)
- clientFactory.domain = "example.org"
- clock = task.Clock()
- client = clientFactory.buildProtocol(
- address.IPv4Address('TCP', 'example.net', 25))
- client.callLater = clock.callLater
- transport = StringTransport()
- client.makeConnection(transport)
-
- client.dataReceived(
- "220 Ok\r\n" # Greet the client
- "250 Ok\r\n" # Respond to HELO
- "250 Ok\r\n" # Respond to MAIL FROM
- "250 Ok\r\n" # Respond to RCPT TO
- "354 Ok\r\n" # Respond to DATA
- )
-
- # Now the client is producing data to the server. Any time
- # resumeProducing is called on the producer, the timeout should be
- # extended. First, a sanity check. This test is only written to
- # handle pull producers.
- self.assertNotIdentical(transport.producer, None)
- self.assertFalse(transport.streaming)
-
- # Now, allow 2 seconds (1 less than the timeout of 3 seconds) to
- # elapse.
- clock.advance(2)
-
- # The timeout has not expired, so the failure should not have happened.
- self.assertEqual(failed, [])
-
- # Let some bytes be produced, extending the timeout. Then advance the
- # clock some more and verify that the timeout still hasn't happened.
- transport.producer.resumeProducing()
- clock.advance(2)
- self.assertEqual(failed, [])
-
- # The file has been completely produced - the next resume producing
- # finishes the upload, successfully.
- transport.producer.resumeProducing()
- client.dataReceived("250 Ok\r\n")
- self.assertEqual(failed, [])
-
- # Verify that the client actually did send the things expected.
- self.assertEqual(
- transport.value(),
- "HELO example.org\r\n"
- "MAIL FROM:<source@address>\r\n"
- "RCPT TO:<recipient@address>\r\n"
- "DATA\r\n"
- "x\r\n"
- ".\r\n"
- # This RSET is just an implementation detail. It's nice, but this
- # test doesn't really care about it.
- "RSET\r\n")
-
-
-
-class MultipleDeliveryFactorySMTPServerFactory(protocol.ServerFactory):
- """
- L{MultipleDeliveryFactorySMTPServerFactory} creates SMTP server protocol
- instances with message delivery factory objects supplied to it. Each
- factory is used for one connection and then discarded. Factories are used
- in the order they are supplied.
- """
- def __init__(self, messageFactories):
- self._messageFactories = messageFactories
-
-
- def buildProtocol(self, addr):
- p = protocol.ServerFactory.buildProtocol(self, addr)
- p.delivery = SimpleDelivery(self._messageFactories.pop(0))
- return p
-
-
-
-class SMTPSenderFactoryRetryTestCase(unittest.TestCase):
- """
- Tests for the retry behavior of L{smtp.SMTPSenderFactory}.
- """
- def test_retryAfterDisconnect(self):
- """
- If the protocol created by L{SMTPSenderFactory} loses its connection
- before receiving confirmation of message delivery, it reconnects and
- tries to deliver the message again.
- """
- recipient = 'alice'
- message = "some message text"
- domain = DummyDomain([recipient])
-
- class CleanSMTP(smtp.SMTP):
- """
- An SMTP subclass which ensures that its transport will be
- disconnected before the test ends.
- """
- def makeConnection(innerSelf, transport):
- self.addCleanup(transport.loseConnection)
- smtp.SMTP.makeConnection(innerSelf, transport)
-
- # Create a server which will fail the first message deliver attempt to
- # it with a 500 and a disconnect, but which will accept a message
- # delivered over the 2nd connection to it.
- serverFactory = MultipleDeliveryFactorySMTPServerFactory([
- BrokenMessage,
- lambda user: DummyMessage(domain, user)])
- serverFactory.protocol = CleanSMTP
- serverPort = reactor.listenTCP(0, serverFactory, interface='127.0.0.1')
- serverHost = serverPort.getHost()
- self.addCleanup(serverPort.stopListening)
-
- # Set up a client to try to deliver a message to the above created
- # server.
- sentDeferred = defer.Deferred()
- clientFactory = smtp.SMTPSenderFactory(
- "bob@example.org", recipient + "@example.com",
- StringIO(message), sentDeferred)
- clientFactory.domain = "example.org"
- clientConnector = reactor.connectTCP(
- serverHost.host, serverHost.port, clientFactory)
- self.addCleanup(clientConnector.disconnect)
-
- def cbSent(ignored):
- """
- Verify that the message was successfully delivered and flush the
- error which caused the first attempt to fail.
- """
- self.assertEqual(
- domain.messages,
- {recipient: ["\n%s\n" % (message,)]})
- # Flush the RuntimeError that BrokenMessage caused to be logged.
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- sentDeferred.addCallback(cbSent)
- return sentDeferred
-
-
-
-class SingletonRealm(object):
- """
- Trivial realm implementation which is constructed with an interface and an
- avatar and returns that avatar when asked for that interface.
- """
- implements(IRealm)
-
- def __init__(self, interface, avatar):
- self.interface = interface
- self.avatar = avatar
-
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- for iface in interfaces:
- if iface is self.interface:
- return iface, self.avatar, lambda: None
-
-
-
-class NotImplementedDelivery(object):
- """
- Non-implementation of L{smtp.IMessageDelivery} which only has methods which
- raise L{NotImplementedError}. Subclassed by various tests to provide the
- particular behavior being tested.
- """
- def validateFrom(self, helo, origin):
- raise NotImplementedError("This oughtn't be called in the course of this test.")
-
-
- def validateTo(self, user):
- raise NotImplementedError("This oughtn't be called in the course of this test.")
-
-
- def receivedHeader(self, helo, origin, recipients):
- raise NotImplementedError("This oughtn't be called in the course of this test.")
-
-
-
-class SMTPServerTestCase(unittest.TestCase):
- """
- Test various behaviors of L{twisted.mail.smtp.SMTP} and
- L{twisted.mail.smtp.ESMTP}.
- """
- def testSMTPGreetingHost(self, serverClass=smtp.SMTP):
- """
- Test that the specified hostname shows up in the SMTP server's
- greeting.
- """
- s = serverClass()
- s.host = "example.com"
- t = StringTransport()
- s.makeConnection(t)
- s.connectionLost(error.ConnectionDone())
- self.assertIn("example.com", t.value())
-
-
- def testSMTPGreetingNotExtended(self):
- """
- Test that the string "ESMTP" does not appear in the SMTP server's
- greeting since that string strongly suggests the presence of support
- for various SMTP extensions which are not supported by L{smtp.SMTP}.
- """
- s = smtp.SMTP()
- t = StringTransport()
- s.makeConnection(t)
- s.connectionLost(error.ConnectionDone())
- self.assertNotIn("ESMTP", t.value())
-
-
- def testESMTPGreetingHost(self):
- """
- Similar to testSMTPGreetingHost, but for the L{smtp.ESMTP} class.
- """
- self.testSMTPGreetingHost(smtp.ESMTP)
-
-
- def testESMTPGreetingExtended(self):
- """
- Test that the string "ESMTP" does appear in the ESMTP server's
- greeting since L{smtp.ESMTP} does support the SMTP extensions which
- that advertises to the client.
- """
- s = smtp.ESMTP()
- t = StringTransport()
- s.makeConnection(t)
- s.connectionLost(error.ConnectionDone())
- self.assertIn("ESMTP", t.value())
-
-
- def test_acceptSenderAddress(self):
- """
- Test that a C{MAIL FROM} command with an acceptable address is
- responded to with the correct success code.
- """
- class AcceptanceDelivery(NotImplementedDelivery):
- """
- Delivery object which accepts all senders as valid.
- """
- def validateFrom(self, helo, origin):
- return origin
-
- realm = SingletonRealm(smtp.IMessageDelivery, AcceptanceDelivery())
- portal = Portal(realm, [AllowAnonymousAccess()])
- proto = smtp.SMTP()
- proto.portal = portal
- trans = StringTransport()
- proto.makeConnection(trans)
-
- # Deal with the necessary preliminaries
- proto.dataReceived('HELO example.com\r\n')
- trans.clear()
-
- # Try to specify our sender address
- proto.dataReceived('MAIL FROM:<alice@example.com>\r\n')
-
- # Clean up the protocol before doing anything that might raise an
- # exception.
- proto.connectionLost(error.ConnectionLost())
-
- # Make sure that we received exactly the correct response
- self.assertEqual(
- trans.value(),
- '250 Sender address accepted\r\n')
-
-
- def test_deliveryRejectedSenderAddress(self):
- """
- Test that a C{MAIL FROM} command with an address rejected by a
- L{smtp.IMessageDelivery} instance is responded to with the correct
- error code.
- """
- class RejectionDelivery(NotImplementedDelivery):
- """
- Delivery object which rejects all senders as invalid.
- """
- def validateFrom(self, helo, origin):
- raise smtp.SMTPBadSender(origin)
-
- realm = SingletonRealm(smtp.IMessageDelivery, RejectionDelivery())
- portal = Portal(realm, [AllowAnonymousAccess()])
- proto = smtp.SMTP()
- proto.portal = portal
- trans = StringTransport()
- proto.makeConnection(trans)
-
- # Deal with the necessary preliminaries
- proto.dataReceived('HELO example.com\r\n')
- trans.clear()
-
- # Try to specify our sender address
- proto.dataReceived('MAIL FROM:<alice@example.com>\r\n')
-
- # Clean up the protocol before doing anything that might raise an
- # exception.
- proto.connectionLost(error.ConnectionLost())
-
- # Make sure that we received exactly the correct response
- self.assertEqual(
- trans.value(),
- '550 Cannot receive from specified address '
- '<alice@example.com>: Sender not acceptable\r\n')
-
-
- def test_portalRejectedSenderAddress(self):
- """
- Test that a C{MAIL FROM} command with an address rejected by an
- L{smtp.SMTP} instance's portal is responded to with the correct error
- code.
- """
- class DisallowAnonymousAccess(object):
- """
- Checker for L{IAnonymous} which rejects authentication attempts.
- """
- implements(ICredentialsChecker)
-
- credentialInterfaces = (IAnonymous,)
-
- def requestAvatarId(self, credentials):
- return defer.fail(UnauthorizedLogin())
-
- realm = SingletonRealm(smtp.IMessageDelivery, NotImplementedDelivery())
- portal = Portal(realm, [DisallowAnonymousAccess()])
- proto = smtp.SMTP()
- proto.portal = portal
- trans = StringTransport()
- proto.makeConnection(trans)
-
- # Deal with the necessary preliminaries
- proto.dataReceived('HELO example.com\r\n')
- trans.clear()
-
- # Try to specify our sender address
- proto.dataReceived('MAIL FROM:<alice@example.com>\r\n')
-
- # Clean up the protocol before doing anything that might raise an
- # exception.
- proto.connectionLost(error.ConnectionLost())
-
- # Make sure that we received exactly the correct response
- self.assertEqual(
- trans.value(),
- '550 Cannot receive from specified address '
- '<alice@example.com>: Sender not acceptable\r\n')
-
-
- def test_portalRejectedAnonymousSender(self):
- """
- Test that a C{MAIL FROM} command issued without first authenticating
- when a portal has been configured to disallow anonymous logins is
- responded to with the correct error code.
- """
- realm = SingletonRealm(smtp.IMessageDelivery, NotImplementedDelivery())
- portal = Portal(realm, [])
- proto = smtp.SMTP()
- proto.portal = portal
- trans = StringTransport()
- proto.makeConnection(trans)
-
- # Deal with the necessary preliminaries
- proto.dataReceived('HELO example.com\r\n')
- trans.clear()
-
- # Try to specify our sender address
- proto.dataReceived('MAIL FROM:<alice@example.com>\r\n')
-
- # Clean up the protocol before doing anything that might raise an
- # exception.
- proto.connectionLost(error.ConnectionLost())
-
- # Make sure that we received exactly the correct response
- self.assertEqual(
- trans.value(),
- '550 Cannot receive from specified address '
- '<alice@example.com>: Unauthenticated senders not allowed\r\n')
-
-
-
-class ESMTPAuthenticationTestCase(unittest.TestCase):
- def assertServerResponse(self, bytes, response):
- """
- Assert that when the given bytes are delivered to the ESMTP server
- instance, it responds with the indicated lines.
-
- @type bytes: str
- @type response: list of str
- """
- self.transport.clear()
- self.server.dataReceived(bytes)
- self.assertEqual(
- response,
- self.transport.value().splitlines())
-
-
- def assertServerAuthenticated(self, loginArgs, username="username", password="password"):
- """
- Assert that a login attempt has been made, that the credentials and
- interfaces passed to it are correct, and that when the login request
- is satisfied, a successful response is sent by the ESMTP server
- instance.
-
- @param loginArgs: A C{list} previously passed to L{portalFactory}.
- """
- d, credentials, mind, interfaces = loginArgs.pop()
- self.assertEqual(loginArgs, [])
- self.failUnless(twisted.cred.credentials.IUsernamePassword.providedBy(credentials))
- self.assertEqual(credentials.username, username)
- self.failUnless(credentials.checkPassword(password))
- self.assertIn(smtp.IMessageDeliveryFactory, interfaces)
- self.assertIn(smtp.IMessageDelivery, interfaces)
- d.callback((smtp.IMessageDeliveryFactory, None, lambda: None))
-
- self.assertEqual(
- ["235 Authentication successful."],
- self.transport.value().splitlines())
-
-
- def setUp(self):
- """
- Create an ESMTP instance attached to a StringTransport.
- """
- self.server = smtp.ESMTP({
- 'LOGIN': imap4.LOGINCredentials})
- self.server.host = 'localhost'
- self.transport = StringTransport(
- peerAddress=address.IPv4Address('TCP', '127.0.0.1', 12345))
- self.server.makeConnection(self.transport)
-
-
- def tearDown(self):
- """
- Disconnect the ESMTP instance to clean up its timeout DelayedCall.
- """
- self.server.connectionLost(error.ConnectionDone())
-
-
- def portalFactory(self, loginList):
- class DummyPortal:
- def login(self, credentials, mind, *interfaces):
- d = defer.Deferred()
- loginList.append((d, credentials, mind, interfaces))
- return d
- return DummyPortal()
-
-
- def test_authenticationCapabilityAdvertised(self):
- """
- Test that AUTH is advertised to clients which issue an EHLO command.
- """
- self.transport.clear()
- self.server.dataReceived('EHLO\r\n')
- responseLines = self.transport.value().splitlines()
- self.assertEqual(
- responseLines[0],
- "250-localhost Hello 127.0.0.1, nice to meet you")
- self.assertEqual(
- responseLines[1],
- "250 AUTH LOGIN")
- self.assertEqual(len(responseLines), 2)
-
-
- def test_plainAuthentication(self):
- """
- Test that the LOGIN authentication mechanism can be used
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.transport.clear()
-
- self.assertServerResponse(
- 'AUTH LOGIN\r\n',
- ["334 " + "User Name\0".encode('base64').strip()])
-
- self.assertServerResponse(
- 'username'.encode('base64') + '\r\n',
- ["334 " + "Password\0".encode('base64').strip()])
-
- self.assertServerResponse(
- 'password'.encode('base64').strip() + '\r\n',
- [])
-
- self.assertServerAuthenticated(loginArgs)
-
-
- def test_plainAuthenticationEmptyPassword(self):
- """
- Test that giving an empty password for plain auth succeeds.
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.transport.clear()
-
- self.assertServerResponse(
- 'AUTH LOGIN\r\n',
- ["334 " + "User Name\0".encode('base64').strip()])
-
- self.assertServerResponse(
- 'username'.encode('base64') + '\r\n',
- ["334 " + "Password\0".encode('base64').strip()])
-
- self.assertServerResponse('\r\n', [])
- self.assertServerAuthenticated(loginArgs, password='')
-
-
- def test_plainAuthenticationInitialResponse(self):
- """
- The response to the first challenge may be included on the AUTH command
- line. Test that this is also supported.
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.transport.clear()
-
- self.assertServerResponse(
- 'AUTH LOGIN ' + "username".encode('base64').strip() + '\r\n',
- ["334 " + "Password\0".encode('base64').strip()])
-
- self.assertServerResponse(
- 'password'.encode('base64').strip() + '\r\n',
- [])
-
- self.assertServerAuthenticated(loginArgs)
-
-
- def test_abortAuthentication(self):
- """
- Test that a challenge/response sequence can be aborted by the client.
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.server.dataReceived('AUTH LOGIN\r\n')
-
- self.assertServerResponse(
- '*\r\n',
- ['501 Authentication aborted'])
-
-
- def test_invalidBase64EncodedResponse(self):
- """
- Test that a response which is not properly Base64 encoded results in
- the appropriate error code.
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.server.dataReceived('AUTH LOGIN\r\n')
-
- self.assertServerResponse(
- 'x\r\n',
- ['501 Syntax error in parameters or arguments'])
-
- self.assertEqual(loginArgs, [])
-
-
- def test_invalidBase64EncodedInitialResponse(self):
- """
- Like L{test_invalidBase64EncodedResponse} but for the case of an
- initial response included with the C{AUTH} command.
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.assertServerResponse(
- 'AUTH LOGIN x\r\n',
- ['501 Syntax error in parameters or arguments'])
-
- self.assertEqual(loginArgs, [])
-
-
- def test_unexpectedLoginFailure(self):
- """
- If the L{Deferred} returned by L{Portal.login} fires with an
- exception of any type other than L{UnauthorizedLogin}, the exception
- is logged and the client is informed that the authentication attempt
- has failed.
- """
- loginArgs = []
- self.server.portal = self.portalFactory(loginArgs)
-
- self.server.dataReceived('EHLO\r\n')
- self.transport.clear()
-
- self.assertServerResponse(
- 'AUTH LOGIN ' + 'username'.encode('base64').strip() + '\r\n',
- ['334 ' + 'Password\0'.encode('base64').strip()])
- self.assertServerResponse(
- 'password'.encode('base64').strip() + '\r\n',
- [])
-
- d, credentials, mind, interfaces = loginArgs.pop()
- d.errback(RuntimeError("Something wrong with the server"))
-
- self.assertEqual(
- '451 Requested action aborted: local error in processing\r\n',
- self.transport.value())
-
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
-
-
-
-class SMTPClientErrorTestCase(unittest.TestCase):
- """
- Tests for L{smtp.SMTPClientError}.
- """
- def test_str(self):
- """
- The string representation of a L{SMTPClientError} instance includes
- the response code and response string.
- """
- err = smtp.SMTPClientError(123, "some text")
- self.assertEqual(str(err), "123 some text")
-
-
- def test_strWithNegativeCode(self):
- """
- If the response code supplied to L{SMTPClientError} is negative, it
- is excluded from the string representation.
- """
- err = smtp.SMTPClientError(-1, "foo bar")
- self.assertEqual(str(err), "foo bar")
-
-
- def test_strWithLog(self):
- """
- If a line log is supplied to L{SMTPClientError}, its contents are
- included in the string representation of the exception instance.
- """
- log = LineLog(10)
- log.append("testlog")
- log.append("secondline")
- err = smtp.SMTPClientError(100, "test error", log=log.str())
- self.assertEqual(
- str(err),
- "100 test error\n"
- "testlog\n"
- "secondline\n")
-
-
-
-class SenderMixinSentMailTests(unittest.TestCase):
- """
- Tests for L{smtp.SenderMixin.sentMail}, used in particular by
- L{smtp.SMTPSenderFactory} and L{smtp.ESMTPSenderFactory}.
- """
- def test_onlyLogFailedAddresses(self):
- """
- L{smtp.SenderMixin.sentMail} adds only the addresses with failing
- SMTP response codes to the log passed to the factory's errback.
- """
- onDone = self.assertFailure(defer.Deferred(), smtp.SMTPDeliveryError)
- onDone.addCallback(lambda e: self.assertEqual(
- e.log, "bob@example.com: 199 Error in sending.\n"))
-
- clientFactory = smtp.SMTPSenderFactory(
- 'source@address', 'recipient@address',
- StringIO("Message body"), onDone,
- retries=0, timeout=0.5)
-
- client = clientFactory.buildProtocol(
- address.IPv4Address('TCP', 'example.net', 25))
-
- addresses = [("alice@example.com", 200, "No errors here!"),
- ("bob@example.com", 199, "Error in sending.")]
- client.sentMail(199, "Test response", 1, addresses, client.log)
-
- return onDone
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/NEWS
deleted file mode 100644
index a1468dec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/NEWS
+++ /dev/null
@@ -1,309 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Mail 12.2.0 (2012-08-26)
-================================
-
-Bugfixes
---------
- - twisted.mail.imap4.IMAP4Server will now generate an error response
- when it receives an illegal SEARCH term from a client. (#4080)
- - twisted.mail.imap4 now serves BODYSTRUCTURE responses which provide
- more information and conform to the IMAP4 RFC more closely. (#5763)
-
-Deprecations and Removals
--------------------------
- - twisted.mail.protocols.SSLContextFactory is now deprecated. (#4963)
- - The --passwordfile option to twistd mail is now removed. (#5541)
-
-Other
------
- - #5697, #5750, #5751, #5783
-
-
-Twisted Mail 12.1.0 (2012-06-02)
-================================
-
-Bugfixes
---------
- - twistd mail --auth, broken in 11.0, now correctly connects
- authentication to the portal being used (#5219)
-
-Other
------
- - #5686
-
-
-Twisted Mail 12.0.0 (2012-02-10)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Mail 11.1.0 (2011-11-15)
-================================
-
-Features
---------
- - twisted.mail.smtp.LOGINCredentials now generates challenges with
- ":" instead of "\0" for interoperability with Microsoft Outlook.
- (#4692)
-
-Bugfixes
---------
- - When run from an unpacked source tarball or a VCS checkout,
- bin/mail/mailmail will now use the version of Twisted it is part
- of. (#3526)
-
-Other
------
- - #4796, #5006
-
-
-Twisted Mail 11.0.0 (2011-04-01)
-================================
-
-Features
---------
- - The `twistd mail` command line now accepts endpoint descriptions
- for POP3 and SMTP servers. (#4739)
- - The twistd mail plugin now accepts new authentication options via
- strcred.AuthOptionMixin. These include --auth, --auth-help, and
- authentication type-specific help options. (#4740)
-
-Bugfixes
---------
- - twisted.mail.imap4.IMAP4Server now generates INTERNALDATE strings
- which do not consider the locale. (#4937)
-
-Improved Documentation
-----------------------
- - Added a simple SMTP example, showing how to use sendmail. (#4042)
-
-Other
------
-
- - #4162
-
-
-Twisted Mail 10.2.0 (2010-11-29)
-================================
-
-Improved Documentation
-----------------------
- - The email server example now demonstrates how to set up
- authentication and authorization using twisted.cred. (#4609)
-
-Deprecations and Removals
--------------------------
- - twisted.mail.smtp.sendEmail, deprecated since mid 2003 (before
- Twisted 2.0), has been removed. (#4529)
-
-Other
------
- - #4038, #4572
-
-
-Twisted Mail 10.1.0 (2010-06-27)
-================================
-
-Bugfixes
---------
- - twisted.mail.imap4.IMAP4Server no longer fails on search queries
- that contain wildcards. (#2278)
- - A case which would cause twisted.mail.imap4.IMAP4Server to loop
- indefinitely when handling a search command has been fixed. (#4385)
-
-Other
------
- - #4069, #4271, #4467
-
-
-Twisted Mail 10.0.0 (2010-03-01)
-================================
-
-Bugfixes
---------
- - twisted.mail.smtp.ESMTPClient and
- twisted.mail.smtp.LOGINAuthenticator now implement the (obsolete)
- LOGIN SASL mechanism according to the draft specification. (#4031)
-
- - twisted.mail.imap4.IMAP4Client will no longer misparse all html-
- formatted message bodies received in response to a fetch command.
- (#4049)
-
- - The regression in IMAP4 search handling of "OR" and "NOT" terms has
- been fixed. (#4178)
-
-Other
------
- - #4028, #4170, #4200
-
-
-Twisted Mail 9.0.0 (2009-11-24)
-===============================
-
-Features
---------
- - maildir.StringListMailbox, an in-memory maildir mailbox, now supports
- deletion, undeletion, and syncing (#3547)
- - SMTPClient's callbacks are now more completely documented (#684)
-
-Fixes
------
- - Parse UNSEEN response data and include it in the result of
- IMAP4Client.examine (#3550)
- - The IMAP4 client now delivers more unsolicited server responses to callbacks
- rather than ignoring them, and also won't ignore solicited responses that
- arrive on the same line as an unsolicited one (#1105)
- - Several bugs in the SMTP client's idle timeout support were fixed (#3641,
- #1219)
- - A case where the SMTP client could skip some recipients when retrying
- delivery has been fixed (#3638)
- - Errors during certain data transfers will no longer be swallowed. They will
- now bubble up to the higher-level API (such as the sendmail function) (#3642)
- - Escape sequences inside quoted strings in IMAP4 should now be parsed
- correctly by the IMAP4 server protocol (#3659)
- - The "imap4-utf-7" codec that is registered by twisted.mail.imap4 had a number
- of fixes that allow it to work better with the Python codecs system, and to
- actually work (#3663)
- - The Maildir implementation now ensures time-based ordering of filenames so
- that the lexical sorting of messages matches the order in which they were
- received (#3812)
- - SASL PLAIN credentials generated by the IMAP4 protocol implementations
- (client and server) should now be RFC-compliant (#3939)
- - Searching for a set of sequences using the IMAP4 "SEARCH" command should
- now work on the IMAP4 server protocol implementation. This at least improves
- support for the Pine mail client (#1977)
-
-Other
------
- - #2763, #3647, #3750, #3819, #3540, #3846, #2023, #4050
-
-
-Mail 8.2.0 (2008-12-16)
-=======================
-
-Fixes
------
- - The mailmail tool now provides better error messages for usage errors (#3339)
- - The SMTP protocol implementation now works on PyPy (#2976)
-
-Other
------
- - #3475
-
-
-8.1.0 (2008-05-18)
-==================
-
-Fixes
------
- - The deprecated mktap API is no longer used (#3127)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Features
---------
- - Support CAPABILITY responses that include atoms of the form "FOO" and
- "FOO=BAR" in IMAP4 (#2695)
- - Parameterize error handling behavior of imap4.encoder and imap4.decoder.
- (#2929)
-
-Fixes
------
- - Handle empty passwords in SMTP auth. (#2521)
- - Fix IMAP4Client's parsing of literals which are not preceeded by whitespace.
- (#2700)
- - Handle MX lookup suceeding without answers. (#2807)
- - Fix issues with aliases(5) process support. (#2729)
-
-Misc
-----
- - #2371, #2123, #2378, #739, #2640, #2746, #1917, #2266, #2864, #2832, #2063,
- #2865, #2847
-
-
-0.4.0 (2007-01-06)
-==================
-
-Features
---------
- - Plaintext POP3 logins are now possible over SSL or TLS (#1809)
-
-Fixes
------
- - ESMTP servers now greet with an "ESMTP" string (#1891)
- - The POP3 client can now correctly deal with concurrent POP3
- retrievals (#1988, #1691)
- - In the IMAP4 server, a bug involving retrieving the first part
- of a single-part message was fixed. This improves compatibility
- with Pine (#1978)
- - A bug in the IMAP4 server which caused corruption under heavy
- pipelining was fixed (#1992)
- - More strict support for the AUTH command was added to the SMTP
- server, to support the AUTH <mechanism>
- <initial-authentication-data> form of the command (#1552)
- - An SMTP bug involving the interaction with validateFrom, which
- caused multiple conflicting SMTP messages to be sent over the wire,
- was fixed (#2158)
-
-Misc
-----
- - #1648, #1801, #1636, #2003, #1936, #1202, #2051, #2072, #2248, #2250
-
-0.3.0 (2006-05-21)
-==================
-
-Features
---------
- - Support Deferred results from POP3's IMailbox.listMessages (#1701).
-
-Fixes
------
- - Quote usernames and passwords automatically in the IMAP client (#1411).
- - Improved parsing of literals in IMAP4 client and server (#1417).
- - Recognize unsolicted FLAGS response in IMAP4 client (#1105).
- - Parse and respond to requests with multiple BODY arguments in IMAP4
- server (#1307).
- - Misc: #1356, #1290, #1602
-
-0.2.0:
- - SMTP server:
- - Now gives application-level code opportunity to set a different
- Received header for each recipient of a multi-recipient message.
- - IMAP client:
- - New `startTLS' method to allow explicit negotiation of transport
- security.
-- POP client:
- - Support for per-command timeouts
- - New `startTLS' method, similar to the one added to the IMAP
- client.
- - NOOP, RSET, and STAT support added
-- POP server:
- - Bug handling passwords of "" fixed
-
-
-0.1.0:
- - Tons of bugfixes in IMAP4, POP3, and SMTP protocols
- - Maildir append support
- - Brand new, improved POP3 client (twisted.mail.pop3.AdvancedPOP3Client)
- - Deprecated the old POP3 client (twisted.mail.pop3.POP3Client)
- - SMTP client:
- - Support SMTP AUTH
- - Allow user to supply SSL context
- - Improved error handling, via new exception classes and an overridable
- hook to customize handling.
- - Order to try the authenication schemes is user-definable.
- - Timeout support.
- - SMTP server:
- - Properly understand <> sender.
- - Parameterize remote port
- - IMAP4:
- - LOGIN authentication compatibility improved
- - Improved unicode mailbox support
- - Fix parsing/handling of "FETCH BODY[HEADER]"
- - Many many quoting fixes
- - Timeout support on client
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/README
deleted file mode 100644
index b302614f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/mail/topfiles/README
+++ /dev/null
@@ -1,6 +0,0 @@
-Twisted Mail 12.2.0
-
-Twisted Mail depends on Twisted Core and (sometimes) Twisted Names. For TLS
-support, pyOpenSSL (<http://launchpad.net/pyopenssl>) is also required. Aside
-from protocol implementations, much of Twisted Mail also only runs on POSIX
-platforms.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/__init__.py
deleted file mode 100755
index 64e2bbc1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Manhole: interactive interpreter and direct manipulation support for Twisted.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/_inspectro.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/_inspectro.py
deleted file mode 100755
index 430ae7b0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/_inspectro.py
+++ /dev/null
@@ -1,369 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""An input/output window for the glade reactor inspector.
-"""
-
-import time
-import gtk
-import gobject
-import gtk.glade
-from twisted.python.util import sibpath
-from twisted.python import reflect
-
-from twisted.manhole.ui import gtk2manhole
-from twisted.python.components import Adapter, registerAdapter
-from twisted.python import log
-from twisted.protocols import policies
-from zope.interface import implements, Interface
-
-# the glade file uses stock icons, which requires gnome to be installed
-import gnome
-version = "$Revision: 1.1 $"[11:-2]
-gnome.init("gladereactor Inspector", version)
-
-class ConsoleOutput(gtk2manhole.ConsoleOutput):
- def _captureLocalLog(self):
- self.fobs = log.FileLogObserver(gtk2manhole._Notafile(self, "log"))
- self.fobs.start()
-
- def stop(self):
- self.fobs.stop()
- del self.fobs
-
-class ConsoleInput(gtk2manhole.ConsoleInput):
- def sendMessage(self):
- buffer = self.textView.get_buffer()
- iter1, iter2 = buffer.get_bounds()
- text = buffer.get_text(iter1, iter2, False)
- self.do(text)
-
- def do(self, text):
- self.toplevel.do(text)
-
-class INode(Interface):
- """A node in the inspector tree model.
- """
-
- def __adapt__(adaptable, default):
- if hasattr(adaptable, "__dict__"):
- return InstanceNode(adaptable)
- return AttributesNode(adaptable)
-
-class InspectorNode(Adapter):
- implements(INode)
-
- def postInit(self, offset, parent, slot):
- self.offset = offset
- self.parent = parent
- self.slot = slot
-
- def getPath(self):
- L = []
- x = self
- while x.parent is not None:
- L.append(x.offset)
- x = x.parent
- L.reverse()
- return L
-
- def __getitem__(self, index):
- slot, o = self.get(index)
- n = INode(o, persist=False)
- n.postInit(index, self, slot)
- return n
-
- def origstr(self):
- return str(self.original)
-
- def format(self):
- return (self.slot, self.origstr())
-
-
-class ConstantNode(InspectorNode):
- def __len__(self):
- return 0
-
-class DictionaryNode(InspectorNode):
- def get(self, index):
- L = self.original.items()
- L.sort()
- return L[index]
-
- def __len__(self):
- return len(self.original)
-
- def origstr(self):
- return "Dictionary"
-
-class ListNode(InspectorNode):
- def get(self, index):
- return index, self.original[index]
-
- def origstr(self):
- return "List"
-
- def __len__(self):
- return len(self.original)
-
-class AttributesNode(InspectorNode):
- def __len__(self):
- return len(dir(self.original))
-
- def get(self, index):
- L = dir(self.original)
- L.sort()
- return L[index], getattr(self.original, L[index])
-
-class InstanceNode(InspectorNode):
- def __len__(self):
- return len(self.original.__dict__) + 1
-
- def get(self, index):
- if index == 0:
- if hasattr(self.original, "__class__"):
- v = self.original.__class__
- else:
- v = type(self.original)
- return "__class__", v
- else:
- index -= 1
- L = self.original.__dict__.items()
- L.sort()
- return L[index]
-
-import types
-
-for x in dict, types.DictProxyType:
- registerAdapter(DictionaryNode, x, INode)
-for x in list, tuple:
- registerAdapter(ListNode, x, INode)
-for x in int, str:
- registerAdapter(ConstantNode, x, INode)
-
-
-class InspectorTreeModel(gtk.GenericTreeModel):
- def __init__(self, root):
- gtk.GenericTreeModel.__init__(self)
- self.root = INode(root, persist=False)
- self.root.postInit(0, None, 'root')
-
- def on_get_flags(self):
- return 0
-
- def on_get_n_columns(self):
- return 1
-
- def on_get_column_type(self, index):
- return gobject.TYPE_STRING
-
- def on_get_path(self, node):
- return node.getPath()
-
- def on_get_iter(self, path):
- x = self.root
- for elem in path:
- x = x[elem]
- return x
-
- def on_get_value(self, node, column):
- return node.format()[column]
-
- def on_iter_next(self, node):
- try:
- return node.parent[node.offset + 1]
- except IndexError:
- return None
-
- def on_iter_children(self, node):
- return node[0]
-
- def on_iter_has_child(self, node):
- return len(node)
-
- def on_iter_n_children(self, node):
- return len(node)
-
- def on_iter_nth_child(self, node, n):
- if node is None:
- return None
- return node[n]
-
- def on_iter_parent(self, node):
- return node.parent
-
-
-class Inspectro:
- selected = None
- def __init__(self, o=None):
- self.xml = x = gtk.glade.XML(sibpath(__file__, "inspectro.glade"))
- self.tree_view = x.get_widget("treeview")
- colnames = ["Name", "Value"]
- for i in range(len(colnames)):
- self.tree_view.append_column(
- gtk.TreeViewColumn(
- colnames[i], gtk.CellRendererText(), text=i))
- d = {}
- for m in reflect.prefixedMethods(self, "on_"):
- d[m.im_func.__name__] = m
- self.xml.signal_autoconnect(d)
- if o is not None:
- self.inspect(o)
- self.ns = {'inspect': self.inspect}
- iwidget = x.get_widget('input')
- self.input = ConsoleInput(iwidget)
- self.input.toplevel = self
- iwidget.connect("key_press_event", self.input._on_key_press_event)
- self.output = ConsoleOutput(x.get_widget('output'))
-
- def select(self, o):
- self.selected = o
- self.ns['it'] = o
- self.xml.get_widget("itname").set_text(repr(o))
- self.xml.get_widget("itpath").set_text("???")
-
- def inspect(self, o):
- self.model = InspectorTreeModel(o)
- self.tree_view.set_model(self.model)
- self.inspected = o
-
- def do(self, command):
- filename = '<inspector>'
- try:
- print repr(command)
- try:
- code = compile(command, filename, 'eval')
- except:
- code = compile(command, filename, 'single')
- val = eval(code, self.ns, self.ns)
- if val is not None:
- print repr(val)
- self.ns['_'] = val
- except:
- log.err()
-
- def on_inspect(self, *a):
- self.inspect(self.selected)
-
- def on_inspect_new(self, *a):
- Inspectro(self.selected)
-
- def on_row_activated(self, tv, path, column):
- self.select(self.model.on_get_iter(path).original)
-
-
-class LoggingProtocol(policies.ProtocolWrapper):
- """Log network traffic."""
-
- logging = True
- logViewer = None
-
- def __init__(self, *args):
- policies.ProtocolWrapper.__init__(self, *args)
- self.inLog = []
- self.outLog = []
-
- def write(self, data):
- if self.logging:
- self.outLog.append((time.time(), data))
- if self.logViewer:
- self.logViewer.updateOut(self.outLog[-1])
- policies.ProtocolWrapper.write(self, data)
-
- def dataReceived(self, data):
- if self.logging:
- self.inLog.append((time.time(), data))
- if self.logViewer:
- self.logViewer.updateIn(self.inLog[-1])
- policies.ProtocolWrapper.dataReceived(self, data)
-
- def __repr__(self):
- r = "wrapped " + repr(self.wrappedProtocol)
- if self.logging:
- r += " (logging)"
- return r
-
-
-class LoggingFactory(policies.WrappingFactory):
- """Wrap protocols with logging wrappers."""
-
- protocol = LoggingProtocol
- logging = True
-
- def buildProtocol(self, addr):
- p = self.protocol(self, self.wrappedFactory.buildProtocol(addr))
- p.logging = self.logging
- return p
-
- def __repr__(self):
- r = "wrapped " + repr(self.wrappedFactory)
- if self.logging:
- r += " (logging)"
- return r
-
-
-class LogViewer:
- """Display log of network traffic."""
-
- def __init__(self, p):
- self.p = p
- vals = [time.time()]
- if p.inLog:
- vals.append(p.inLog[0][0])
- if p.outLog:
- vals.append(p.outLog[0][0])
- self.startTime = min(vals)
- p.logViewer = self
- self.xml = x = gtk.glade.XML(sibpath(__file__, "logview.glade"))
- self.xml.signal_autoconnect(self)
- self.loglist = self.xml.get_widget("loglist")
- # setup model, connect it to my treeview
- self.model = gtk.ListStore(str, str, str)
- self.loglist.set_model(self.model)
- self.loglist.set_reorderable(1)
- self.loglist.set_headers_clickable(1)
- # self.servers.set_headers_draggable(1)
- # add a column
- for col in [
- gtk.TreeViewColumn('Time',
- gtk.CellRendererText(),
- text=0),
- gtk.TreeViewColumn('D',
- gtk.CellRendererText(),
- text=1),
- gtk.TreeViewColumn('Data',
- gtk.CellRendererText(),
- text=2)]:
- self.loglist.append_column(col)
- col.set_resizable(1)
- r = []
- for t, data in p.inLog:
- r.append(((str(t - self.startTime), "R", repr(data)[1:-1])))
- for t, data in p.outLog:
- r.append(((str(t - self.startTime), "S", repr(data)[1:-1])))
- r.sort()
- for i in r:
- self.model.append(i)
-
- def updateIn(self, (time, data)):
- self.model.append((str(time - self.startTime), "R", repr(data)[1:-1]))
-
- def updateOut(self, (time, data)):
- self.model.append((str(time - self.startTime), "S", repr(data)[1:-1]))
-
- def on_logview_destroy(self, w):
- self.p.logViewer = None
- del self.p
-
-
-def main():
- x = Inspectro()
- x.inspect(x)
- gtk.main()
-
-if __name__ == '__main__':
- import sys
- log.startLogging(sys.stdout)
- main()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/explorer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/explorer.py
deleted file mode 100755
index 30db8e23..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/explorer.py
+++ /dev/null
@@ -1,654 +0,0 @@
-# -*- test-case-name: twisted.test.test_explorer -*-
-# $Id: explorer.py,v 1.6 2003/02/18 21:15:30 acapnotic Exp $
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Support for python object introspection and exploration.
-
-Note that Explorers, what with their list of attributes, are much like
-manhole.coil.Configurables. Someone should investigate this further. (TODO)
-
-Also TODO: Determine how much code in here (particularly the function
-signature stuff) can be replaced with functions available in the
-L{inspect} module available in Python 2.1.
-"""
-
-# System Imports
-import inspect, string, sys, types
-import UserDict
-
-# Twisted Imports
-from twisted.spread import pb
-from twisted.python import reflect
-
-
-True=(1==1)
-False=not True
-
-class Pool(UserDict.UserDict):
- def getExplorer(self, object, identifier):
- oid = id(object)
- if oid in self.data:
- # XXX: This potentially returns something with
- # 'identifier' set to a different value.
- return self.data[oid]
- else:
- klass = typeTable.get(type(object), ExplorerGeneric)
- e = types.InstanceType(klass, {})
- self.data[oid] = e
- klass.__init__(e, object, identifier)
- return e
-
-explorerPool = Pool()
-
-class Explorer(pb.Cacheable):
- properties = ["id", "identifier"]
- attributeGroups = []
- accessors = ["get_refcount"]
-
- id = None
- identifier = None
-
- def __init__(self, object, identifier):
- self.object = object
- self.identifier = identifier
- self.id = id(object)
-
- self.properties = []
- reflect.accumulateClassList(self.__class__, 'properties',
- self.properties)
-
- self.attributeGroups = []
- reflect.accumulateClassList(self.__class__, 'attributeGroups',
- self.attributeGroups)
-
- self.accessors = []
- reflect.accumulateClassList(self.__class__, 'accessors',
- self.accessors)
-
- def getStateToCopyFor(self, perspective):
- all = ["properties", "attributeGroups", "accessors"]
- all.extend(self.properties)
- all.extend(self.attributeGroups)
-
- state = {}
- for key in all:
- state[key] = getattr(self, key)
-
- state['view'] = pb.ViewPoint(perspective, self)
- state['explorerClass'] = self.__class__.__name__
- return state
-
- def view_get_refcount(self, perspective):
- return sys.getrefcount(self)
-
-class ExplorerGeneric(Explorer):
- properties = ["str", "repr", "typename"]
-
- def __init__(self, object, identifier):
- Explorer.__init__(self, object, identifier)
- self.str = str(object)
- self.repr = repr(object)
- self.typename = type(object).__name__
-
-
-class ExplorerImmutable(Explorer):
- properties = ["value"]
-
- def __init__(self, object, identifier):
- Explorer.__init__(self, object, identifier)
- self.value = object
-
-
-class ExplorerSequence(Explorer):
- properties = ["len"]
- attributeGroups = ["elements"]
- accessors = ["get_elements"]
-
- def __init__(self, seq, identifier):
- Explorer.__init__(self, seq, identifier)
- self.seq = seq
- self.len = len(seq)
-
- # Use accessor method to fill me in.
- self.elements = []
-
- def get_elements(self):
- self.len = len(self.seq)
- l = []
- for i in xrange(self.len):
- identifier = "%s[%s]" % (self.identifier, i)
-
- # GLOBAL: using global explorerPool
- l.append(explorerPool.getExplorer(self.seq[i], identifier))
-
- return l
-
- def view_get_elements(self, perspective):
- # XXX: set the .elements member of all my remoteCaches
- return self.get_elements()
-
-
-class ExplorerMapping(Explorer):
- properties = ["len"]
- attributeGroups = ["keys"]
- accessors = ["get_keys", "get_item"]
-
- def __init__(self, dct, identifier):
- Explorer.__init__(self, dct, identifier)
-
- self.dct = dct
- self.len = len(dct)
-
- # Use accessor method to fill me in.
- self.keys = []
-
- def get_keys(self):
- keys = self.dct.keys()
- self.len = len(keys)
- l = []
- for i in xrange(self.len):
- identifier = "%s.keys()[%s]" % (self.identifier, i)
-
- # GLOBAL: using global explorerPool
- l.append(explorerPool.getExplorer(keys[i], identifier))
-
- return l
-
- def view_get_keys(self, perspective):
- # XXX: set the .keys member of all my remoteCaches
- return self.get_keys()
-
- def view_get_item(self, perspective, key):
- if type(key) is types.InstanceType:
- key = key.object
-
- item = self.dct[key]
-
- identifier = "%s[%s]" % (self.identifier, repr(key))
- # GLOBAL: using global explorerPool
- item = explorerPool.getExplorer(item, identifier)
- return item
-
-
-class ExplorerBuiltin(Explorer):
- """
- @ivar name: the name the function was defined as
- @ivar doc: function's docstring, or C{None} if unavailable
- @ivar self: if not C{None}, the function is a method of this object.
- """
- properties = ["doc", "name", "self"]
- def __init__(self, function, identifier):
- Explorer.__init__(self, function, identifier)
- self.doc = function.__doc__
- self.name = function.__name__
- self.self = function.__self__
-
-
-class ExplorerInstance(Explorer):
- """
- Attribute groups:
- - B{methods} -- dictionary of methods
- - B{data} -- dictionary of data members
-
- Note these are only the *instance* methods and members --
- if you want the class methods, you'll have to look up the class.
-
- TODO: Detail levels (me, me & class, me & class ancestory)
-
- @ivar klass: the class this is an instance of.
- """
- properties = ["klass"]
- attributeGroups = ["methods", "data"]
-
- def __init__(self, instance, identifier):
- Explorer.__init__(self, instance, identifier)
- members = {}
- methods = {}
- for i in dir(instance):
- # TODO: Make screening of private attributes configurable.
- if i[0] == '_':
- continue
- mIdentifier = string.join([identifier, i], ".")
- member = getattr(instance, i)
- mType = type(member)
-
- if mType is types.MethodType:
- methods[i] = explorerPool.getExplorer(member, mIdentifier)
- else:
- members[i] = explorerPool.getExplorer(member, mIdentifier)
-
- self.klass = explorerPool.getExplorer(instance.__class__,
- self.identifier +
- '.__class__')
- self.data = members
- self.methods = methods
-
-
-class ExplorerClass(Explorer):
- """
- @ivar name: the name the class was defined with
- @ivar doc: the class's docstring
- @ivar bases: a list of this class's base classes.
- @ivar module: the module the class is defined in
-
- Attribute groups:
- - B{methods} -- class methods
- - B{data} -- other members of the class
- """
- properties = ["name", "doc", "bases", "module"]
- attributeGroups = ["methods", "data"]
- def __init__(self, theClass, identifier):
- Explorer.__init__(self, theClass, identifier)
- if not identifier:
- identifier = theClass.__name__
- members = {}
- methods = {}
- for i in dir(theClass):
- if (i[0] == '_') and (i != '__init__'):
- continue
-
- mIdentifier = string.join([identifier, i], ".")
- member = getattr(theClass, i)
- mType = type(member)
-
- if mType is types.MethodType:
- methods[i] = explorerPool.getExplorer(member, mIdentifier)
- else:
- members[i] = explorerPool.getExplorer(member, mIdentifier)
-
- self.name = theClass.__name__
- self.doc = inspect.getdoc(theClass)
- self.data = members
- self.methods = methods
- self.bases = explorerPool.getExplorer(theClass.__bases__,
- identifier + ".__bases__")
- self.module = getattr(theClass, '__module__', None)
-
-
-class ExplorerFunction(Explorer):
- properties = ["name", "doc", "file", "line","signature"]
- """
- name -- the name the function was defined as
- signature -- the function's calling signature (Signature instance)
- doc -- the function's docstring
- file -- the file the function is defined in
- line -- the line in the file the function begins on
- """
- def __init__(self, function, identifier):
- Explorer.__init__(self, function, identifier)
- code = function.func_code
- argcount = code.co_argcount
- takesList = (code.co_flags & 0x04) and 1
- takesKeywords = (code.co_flags & 0x08) and 1
-
- n = (argcount + takesList + takesKeywords)
- signature = Signature(code.co_varnames[:n])
-
- if function.func_defaults:
- i_d = 0
- for i in xrange(argcount - len(function.func_defaults),
- argcount):
- default = function.func_defaults[i_d]
- default = explorerPool.getExplorer(
- default, '%s.func_defaults[%d]' % (identifier, i_d))
- signature.set_default(i, default)
-
- i_d = i_d + 1
-
- if takesKeywords:
- signature.set_keyword(n - 1)
-
- if takesList:
- signature.set_varlist(n - 1 - takesKeywords)
-
- # maybe also: function.func_globals,
- # or at least func_globals.__name__?
- # maybe the bytecode, for disassembly-view?
-
- self.name = function.__name__
- self.signature = signature
- self.doc = inspect.getdoc(function)
- self.file = code.co_filename
- self.line = code.co_firstlineno
-
-
-class ExplorerMethod(ExplorerFunction):
- properties = ["self", "klass"]
- """
- In addition to ExplorerFunction properties:
- self -- the object I am bound to, or None if unbound
- klass -- the class I am a method of
- """
- def __init__(self, method, identifier):
-
- function = method.im_func
- if type(function) is types.InstanceType:
- function = function.__call__.im_func
-
- ExplorerFunction.__init__(self, function, identifier)
- self.id = id(method)
- self.klass = explorerPool.getExplorer(method.im_class,
- identifier + '.im_class')
- self.self = explorerPool.getExplorer(method.im_self,
- identifier + '.im_self')
-
- if method.im_self:
- # I'm a bound method -- eat the 'self' arg.
- self.signature.discardSelf()
-
-
-class ExplorerModule(Explorer):
- """
- @ivar name: the name the module was defined as
- @ivar doc: documentation string for the module
- @ivar file: the file the module is defined in
-
- Attribute groups:
- - B{classes} -- the public classes provided by the module
- - B{functions} -- the public functions provided by the module
- - B{data} -- the public data members provided by the module
-
- (\"Public\" is taken to be \"anything that doesn't start with _\")
- """
- properties = ["name","doc","file"]
- attributeGroups = ["classes", "functions", "data"]
-
- def __init__(self, module, identifier):
- Explorer.__init__(self, module, identifier)
- functions = {}
- classes = {}
- data = {}
- for key, value in module.__dict__.items():
- if key[0] == '_':
- continue
-
- mIdentifier = "%s.%s" % (identifier, key)
-
- if type(value) is types.ClassType:
- classes[key] = explorerPool.getExplorer(value,
- mIdentifier)
- elif type(value) is types.FunctionType:
- functions[key] = explorerPool.getExplorer(value,
- mIdentifier)
- elif type(value) is types.ModuleType:
- pass # pass on imported modules
- else:
- data[key] = explorerPool.getExplorer(value, mIdentifier)
-
- self.name = module.__name__
- self.doc = inspect.getdoc(module)
- self.file = getattr(module, '__file__', None)
- self.classes = classes
- self.functions = functions
- self.data = data
-
-typeTable = {types.InstanceType: ExplorerInstance,
- types.ClassType: ExplorerClass,
- types.MethodType: ExplorerMethod,
- types.FunctionType: ExplorerFunction,
- types.ModuleType: ExplorerModule,
- types.BuiltinFunctionType: ExplorerBuiltin,
- types.ListType: ExplorerSequence,
- types.TupleType: ExplorerSequence,
- types.DictType: ExplorerMapping,
- types.StringType: ExplorerImmutable,
- types.NoneType: ExplorerImmutable,
- types.IntType: ExplorerImmutable,
- types.FloatType: ExplorerImmutable,
- types.LongType: ExplorerImmutable,
- types.ComplexType: ExplorerImmutable,
- }
-
-class Signature(pb.Copyable):
- """I represent the signature of a callable.
-
- Signatures are immutable, so don't expect my contents to change once
- they've been set.
- """
- _FLAVOURLESS = None
- _HAS_DEFAULT = 2
- _VAR_LIST = 4
- _KEYWORD_DICT = 8
-
- def __init__(self, argNames):
- self.name = argNames
- self.default = [None] * len(argNames)
- self.flavour = [None] * len(argNames)
-
- def get_name(self, arg):
- return self.name[arg]
-
- def get_default(self, arg):
- if arg is types.StringType:
- arg = self.name.index(arg)
-
- # Wouldn't it be nice if we just returned "None" when there
- # wasn't a default? Well, yes, but often times "None" *is*
- # the default, so return a tuple instead.
- if self.flavour[arg] == self._HAS_DEFAULT:
- return (True, self.default[arg])
- else:
- return (False, None)
-
- def set_default(self, arg, value):
- if arg is types.StringType:
- arg = self.name.index(arg)
-
- self.flavour[arg] = self._HAS_DEFAULT
- self.default[arg] = value
-
- def set_varlist(self, arg):
- if arg is types.StringType:
- arg = self.name.index(arg)
-
- self.flavour[arg] = self._VAR_LIST
-
- def set_keyword(self, arg):
- if arg is types.StringType:
- arg = self.name.index(arg)
-
- self.flavour[arg] = self._KEYWORD_DICT
-
- def is_varlist(self, arg):
- if arg is types.StringType:
- arg = self.name.index(arg)
-
- return (self.flavour[arg] == self._VAR_LIST)
-
- def is_keyword(self, arg):
- if arg is types.StringType:
- arg = self.name.index(arg)
-
- return (self.flavour[arg] == self._KEYWORD_DICT)
-
- def discardSelf(self):
- """Invoke me to discard the first argument if this is a bound method.
- """
- ## if self.name[0] != 'self':
- ## log.msg("Warning: Told to discard self, but name is %s" %
- ## self.name[0])
- self.name = self.name[1:]
- self.default.pop(0)
- self.flavour.pop(0)
-
- def getStateToCopy(self):
- return {'name': tuple(self.name),
- 'flavour': tuple(self.flavour),
- 'default': tuple(self.default)}
-
- def __len__(self):
- return len(self.name)
-
- def __str__(self):
- arglist = []
- for arg in xrange(len(self)):
- name = self.get_name(arg)
- hasDefault, default = self.get_default(arg)
- if hasDefault:
- a = "%s=%s" % (name, default)
- elif self.is_varlist(arg):
- a = "*%s" % (name,)
- elif self.is_keyword(arg):
- a = "**%s" % (name,)
- else:
- a = name
- arglist.append(a)
-
- return string.join(arglist,", ")
-
-
-
-
-
-class CRUFT_WatchyThingie:
- # TODO:
- #
- # * an exclude mechanism for the watcher's browser, to avoid
- # sending back large and uninteresting data structures.
- #
- # * an exclude mechanism for the watcher's trigger, to avoid
- # triggering on some frequently-called-method-that-doesn't-
- # actually-change-anything.
- #
- # * XXX! need removeWatch()
-
- def watchIdentifier(self, identifier, callback):
- """Watch the object returned by evaluating the identifier.
-
- Whenever I think the object might have changed, I'll send an
- ObjectLink of it to the callback.
-
- WARNING: This calls eval() on its argument!
- """
- object = eval(identifier,
- self.globalNamespace,
- self.localNamespace)
- return self.watchObject(object, identifier, callback)
-
- def watchObject(self, object, identifier, callback):
- """Watch the given object.
-
- Whenever I think the object might have changed, I'll send an
- ObjectLink of it to the callback.
-
- The identifier argument is used to generate identifiers for
- objects which are members of this one.
- """
- if type(object) is not types.InstanceType:
- raise TypeError, "Sorry, can only place a watch on Instances."
-
- # uninstallers = []
-
- dct = {}
- reflect.addMethodNamesToDict(object.__class__, dct, '')
- for k in object.__dict__.keys():
- dct[k] = 1
-
- members = dct.keys()
-
- clazzNS = {}
- clazz = types.ClassType('Watching%s%X' %
- (object.__class__.__name__, id(object)),
- (_MonkeysSetattrMixin, object.__class__,),
- clazzNS)
-
- clazzNS['_watchEmitChanged'] = types.MethodType(
- lambda slf, i=identifier, b=self, cb=callback:
- cb(b.browseObject(slf, i)),
- None, clazz)
-
- # orig_class = object.__class__
- object.__class__ = clazz
-
- for name in members:
- m = getattr(object, name)
- # Only hook bound methods.
- if ((type(m) is types.MethodType)
- and (m.im_self is not None)):
- # What's the use of putting watch monkeys on methods
- # in addition to __setattr__? Well, um, uh, if the
- # methods modify their attributes (i.e. add a key to
- # a dictionary) instead of [re]setting them, then
- # we wouldn't know about it unless we did this.
- # (Is that convincing?)
-
- monkey = _WatchMonkey(object)
- monkey.install(name)
- # uninstallers.append(monkey.uninstall)
-
- # XXX: This probably prevents these objects from ever having a
- # zero refcount. Leak, Leak!
- ## self.watchUninstallers[object] = uninstallers
-
-
-class _WatchMonkey:
- """I hang on a method and tell you what I see.
-
- TODO: Aya! Now I just do browseObject all the time, but I could
- tell you what got called with what when and returning what.
- """
- oldMethod = None
-
- def __init__(self, instance):
- """Make a monkey to hang on this instance object.
- """
- self.instance = instance
-
- def install(self, methodIdentifier):
- """Install myself on my instance in place of this method.
- """
- oldMethod = getattr(self.instance, methodIdentifier, None)
-
- # XXX: this conditional probably isn't effective.
- if oldMethod is not self:
- # avoid triggering __setattr__
- self.instance.__dict__[methodIdentifier] = types.MethodType(
- self, self.instance, self.instance.__class__)
- self.oldMethod = (methodIdentifier, oldMethod)
-
- def uninstall(self):
- """Remove myself from this instance and restore the original method.
-
- (I hope.)
- """
- if self.oldMethod is None:
- return
-
- # XXX: This probably doesn't work if multiple monkies are hanging
- # on a method and they're not removed in order.
- if self.oldMethod[1] is None:
- delattr(self.instance, self.oldMethod[0])
- else:
- setattr(self.instance, self.oldMethod[0], self.oldMethod[1])
-
- def __call__(self, instance, *a, **kw):
- """Pretend to be the method I replaced, and ring the bell.
- """
- if self.oldMethod[1]:
- rval = apply(self.oldMethod[1], a, kw)
- else:
- rval = None
-
- instance._watchEmitChanged()
- return rval
-
-
-class _MonkeysSetattrMixin:
- """A mix-in class providing __setattr__ for objects being watched.
- """
- def __setattr__(self, k, v):
- """Set the attribute and ring the bell.
- """
- if hasattr(self.__class__.__bases__[1], '__setattr__'):
- # Hack! Using __bases__[1] is Bad, but since we created
- # this class, we can be reasonably sure it'll work.
- self.__class__.__bases__[1].__setattr__(self, k, v)
- else:
- self.__dict__[k] = v
-
- # XXX: Hey, waitasec, did someone just hang a new method on me?
- # Do I need to put a monkey on it?
-
- self._watchEmitChanged()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.glade b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.glade
deleted file mode 100644
index c78dd5a4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.glade
+++ /dev/null
@@ -1,342 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkWindow" id="window1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Twisted Daemon</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="default_width">256</property>
- <property name="default_height">300</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="servertree">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">True</property>
- <property name="enable_search">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHButtonBox" id="hbuttonbox1">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="suspend">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <signal name="clicked" handler="on_suspend_clicked" last_modification_time="Sun, 22 Jun 2003 05:09:20 GMT"/>
-
- <child>
- <widget class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-undo</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Suspend</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="disconnect">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <signal name="clicked" handler="on_disconnect_clicked" last_modification_time="Sun, 22 Jun 2003 05:09:27 GMT"/>
-
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-warning</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Disconnect</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="inspect">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <signal name="clicked" handler="on_inspect_clicked" last_modification_time="Wed, 17 Dec 2003 06:14:18 GMT"/>
-
- <child>
- <widget class="GtkAlignment" id="alignment3">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox4">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="stock">gtk-open</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Inspect</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="viewlog">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <signal name="clicked" handler="on_viewlog_clicked" last_modification_time="Sun, 04 Jan 2004 22:28:19 GMT"/>
-
- <child>
- <widget class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox5">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-info</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label13">
- <property name="visible">True</property>
- <property name="label" translatable="yes">View Log</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="quit">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-quit</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <signal name="clicked" handler="on_quit_clicked" last_modification_time="Sun, 04 Jan 2004 22:26:43 GMT"/>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.py
deleted file mode 100755
index 148fc5e6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/gladereactor.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-A modified gtk2 reactor with a Glade dialog in-process that allows you to stop,
-suspend, resume and inspect transports interactively.
-"""
-
-__all__ = ['install']
-
-# Twisted Imports
-from twisted.python import log, threadable, runtime, failure, util, reflect
-from twisted.internet.gtk2reactor import Gtk2Reactor as sup
-
-import gtk
-import gobject
-import gtk.glade
-
-COLUMN_DESCRIPTION = 0
-COLUMN_TRANSPORT = 1
-COLUMN_READING = 2
-COLUMN_WRITING = 3
-
-
-class GladeReactor(sup):
- """GTK+-2 event loop reactor with GUI.
- """
-
- def listenTCP(self, port, factory, backlog=50, interface=''):
- from _inspectro import LoggingFactory
- factory = LoggingFactory(factory)
- return sup.listenTCP(self, port, factory, backlog, interface)
-
- def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):
- from _inspectro import LoggingFactory
- factory = LoggingFactory(factory)
- return sup.connectTCP(self, host, port, factory, timeout, bindAddress)
-
- def listenSSL(self, port, factory, contextFactory, backlog=50, interface=''):
- from _inspectro import LoggingFactory
- factory = LoggingFactory(factory)
- return sup.listenSSL(self, port, factory, contextFactory, backlog, interface)
-
- def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None):
- from _inspectro import LoggingFactory
- factory = LoggingFactory(factory)
- return sup.connectSSL(self, host, port, factory, contextFactory, timeout, bindAddress)
-
- def connectUNIX(self, address, factory, timeout=30):
- from _inspectro import LoggingFactory
- factory = LoggingFactory(factory)
- return sup.connectUNIX(self, address, factory, timeout)
-
- def listenUNIX(self, address, factory, backlog=50, mode=0666):
- from _inspectro import LoggingFactory
- factory = LoggingFactory(factory)
- return sup.listenUNIX(self, address, factory, backlog, mode)
-
- def on_disconnect_clicked(self, w):
- store, iter = self.servers.get_selection().get_selected()
- store[iter][COLUMN_TRANSPORT].loseConnection()
-
- def on_viewlog_clicked(self, w):
- store, iter = self.servers.get_selection().get_selected()
- data = store[iter][1]
- from _inspectro import LogViewer
- if hasattr(data, "protocol") and not data.protocol.logViewer:
- LogViewer(data.protocol)
-
- def on_inspect_clicked(self, w):
- store, iter = self.servers.get_selection().get_selected()
- data = store[iter]
- from _inspectro import Inspectro
- Inspectro(data[1])
-
- def on_suspend_clicked(self, w):
- store, iter = self.servers.get_selection().get_selected()
- data = store[iter]
- sup.removeReader(self, data[1])
- sup.removeWriter(self, data[1])
- if data[COLUMN_DESCRIPTION].endswith('(suspended)'):
- if data[COLUMN_READING]:
- sup.addReader(self, data[COLUMN_TRANSPORT])
- if data[COLUMN_WRITING]:
- sup.addWriter(self, data[COLUMN_TRANSPORT])
- data[COLUMN_DESCRIPTION] = str(data[COLUMN_TRANSPORT])
- self.toggle_suspend(1)
- else:
- data[0] += ' (suspended)'
- self.toggle_suspend(0)
-
- def toggle_suspend(self, suspending=0):
- stock, nonstock = [('gtk-redo', 'Resume'),
- ('gtk-undo', 'Suspend')][suspending]
- b = self.xml.get_widget("suspend")
- b.set_use_stock(1)
- b.set_label(stock)
- b.get_child().get_child().get_children()[1].set_label(nonstock)
-
- def servers_selection_changed(self, w):
- store, iter = w.get_selected()
- if iter is None:
- self.xml.get_widget("suspend").set_sensitive(0)
- self.xml.get_widget('disconnect').set_sensitive(0)
- else:
- data = store[iter]
- self.toggle_suspend(not
- data[COLUMN_DESCRIPTION].endswith('(suspended)'))
- self.xml.get_widget("suspend").set_sensitive(1)
- self.xml.get_widget('disconnect').set_sensitive(1)
-
- def on_quit_clicked(self, w):
- self.stop()
-
- def __init__(self):
- self.xml = gtk.glade.XML(util.sibpath(__file__,"gladereactor.glade"))
- d = {}
- for m in reflect.prefixedMethods(self, "on_"):
- d[m.im_func.__name__] = m
- self.xml.signal_autoconnect(d)
- self.xml.get_widget('window1').connect('destroy',
- lambda w: self.stop())
- self.servers = self.xml.get_widget("servertree")
- sel = self.servers.get_selection()
- sel.set_mode(gtk.SELECTION_SINGLE)
- sel.connect("changed",
- self.servers_selection_changed)
- ## argh coredump: self.servers_selection_changed(sel)
- self.xml.get_widget('suspend').set_sensitive(0)
- self.xml.get_widget('disconnect').set_sensitive(0)
- # setup model, connect it to my treeview
- self.model = gtk.ListStore(str, object, gobject.TYPE_BOOLEAN,
- gobject.TYPE_BOOLEAN)
- self.servers.set_model(self.model)
- self.servers.set_reorderable(1)
- self.servers.set_headers_clickable(1)
- # self.servers.set_headers_draggable(1)
- # add a column
- for col in [
- gtk.TreeViewColumn('Server',
- gtk.CellRendererText(),
- text=0),
- gtk.TreeViewColumn('Reading',
- gtk.CellRendererToggle(),
- active=2),
- gtk.TreeViewColumn('Writing',
- gtk.CellRendererToggle(),
- active=3)]:
-
- self.servers.append_column(col)
- col.set_resizable(1)
- sup.__init__(self)
-
- def addReader(self, reader):
- sup.addReader(self, reader)
-## gtk docs suggest this - but it's stupid
-## self.model.set(self.model.append(),
-## 0, str(reader),
-## 1, reader)
- self._maybeAddServer(reader, read=1)
-
- def _goAway(self,reader):
- for p in range(len(self.model)):
- if self.model[p][1] == reader:
- self.model.remove(self.model.get_iter_from_string(str(p)))
- return
-
-
- def _maybeAddServer(self, reader, read=0, write=0):
- p = 0
- for x in self.model:
- if x[1] == reader:
- if reader == 0:
- reader += 1
- x[2] += read
- x[3] += write
- x[2] = max(x[2],0)
- x[3] = max(x[3],0)
-
- if not (x[2] or x[3]):
- x[0] = x[0] + '(disconnected)'
- self.callLater(5, self._goAway, reader)
- return
- p += 1
- else:
- read = max(read,0)
- write = max(write, 0)
- if read or write:
- self.model.append((reader,reader,read,write))
-
- def addWriter(self, writer):
- sup.addWriter(self, writer)
- self._maybeAddServer(writer, write=1)
-
- def removeReader(self, reader):
- sup.removeReader(self, reader)
- self._maybeAddServer(reader, read=-1)
-
- def removeWriter(self, writer):
- sup.removeWriter(self, writer)
- self._maybeAddServer(writer, write=-1)
-
- def crash(self):
- gtk.main_quit()
-
- def run(self, installSignalHandlers=1):
- self.startRunning(installSignalHandlers=installSignalHandlers)
- self.simulate()
- gtk.main()
-
-
-def install():
- """Configure the twisted mainloop to be run inside the gtk mainloop.
- """
- reactor = GladeReactor()
- from twisted.internet.main import installReactor
- installReactor(reactor)
- return reactor
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/inspectro.glade b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/inspectro.glade
deleted file mode 100644
index 94b87170..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/inspectro.glade
+++ /dev/null
@@ -1,510 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-<requires lib="bonobo"/>
-
-<widget class="GnomeApp" id="app1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Inspectro</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="default_width">640</property>
- <property name="default_height">480</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="enable_layout_config">True</property>
-
- <child internal-child="dock">
- <widget class="BonoboDock" id="bonobodock1">
- <property name="visible">True</property>
- <property name="allow_floating">True</property>
-
- <child>
- <widget class="BonoboDockItem" id="bonobodockitem1">
- <property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
-
- <child>
- <widget class="GtkMenuBar" id="menubar1">
- <property name="visible">True</property>
-
- <child>
- <widget class="GtkMenuItem" id="inspector1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Inspector</property>
- <property name="use_underline">True</property>
-
- <child>
- <widget class="GtkMenu" id="inspector1_menu">
-
- <child>
- <widget class="GtkMenuItem" id="select1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Select</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="on_select" last_modification_time="Wed, 17 Dec 2003 05:05:34 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="inspect1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Inspect</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="on_inspect" last_modification_time="Wed, 17 Dec 2003 05:05:34 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="inspect_new1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Inspect New</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="on_inspect_new" last_modification_time="Wed, 17 Dec 2003 05:05:34 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="help1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_HELP_TREE</property>
-
- <child>
- <widget class="GtkMenu" id="help1_menu">
-
- <child>
- <widget class="GtkImageMenuItem" id="about1">
- <property name="visible">True</property>
- <property name="stock_item">GNOMEUIINFO_MENU_ABOUT_ITEM</property>
- <signal name="activate" handler="on_about1_activate" last_modification_time="Wed, 17 Dec 2003 04:48:59 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="placement">BONOBO_DOCK_TOP</property>
- <property name="band">0</property>
- <property name="position">0</property>
- <property name="offset">0</property>
- <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL|BONOBO_DOCK_ITEM_BEH_LOCKED</property>
- </packing>
- </child>
-
- <child>
- <widget class="BonoboDockItem" id="bonobodockitem2">
- <property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_OUT</property>
-
- <child>
- <widget class="GtkToolbar" id="toolbar2">
- <property name="visible">True</property>
- <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
- <property name="tooltips">True</property>
-
- <child>
- <widget class="button" id="button13">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Select</property>
- <property name="use_underline">True</property>
- <property name="stock_pixmap">gtk-convert</property>
- <signal name="clicked" handler="on_select" last_modification_time="Wed, 17 Dec 2003 05:05:14 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="button" id="button14">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Inspect</property>
- <property name="use_underline">True</property>
- <property name="stock_pixmap">gtk-jump-to</property>
- <signal name="clicked" handler="on_inspect" last_modification_time="Wed, 17 Dec 2003 05:05:02 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="button" id="button15">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Inspect New</property>
- <property name="use_underline">True</property>
- <property name="stock_pixmap">gtk-redo</property>
- <signal name="clicked" handler="on_inspect_new" last_modification_time="Wed, 17 Dec 2003 05:04:50 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="placement">BONOBO_DOCK_TOP</property>
- <property name="band">1</property>
- <property name="position">0</property>
- <property name="offset">0</property>
- <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHPaned" id="hpaned1">
- <property name="width_request">350</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="position">250</property>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow4">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="treeview">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <signal name="row_activated" handler="on_row_activated" last_modification_time="Wed, 17 Dec 2003 05:07:55 GMT"/>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">0</property>
- <property name="column_spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="itname">
- <property name="visible">True</property>
- <property name="label" translatable="yes">None</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="itpath">
- <property name="visible">True</property>
- <property name="label" translatable="yes">[]</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">It: </property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_padding">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Path: </property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_padding">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">3</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="shrink">True</property>
- <property name="resize">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVPaned" id="vpaned1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="position">303</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTextView" id="output">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="justification">GTK_JUSTIFY_LEFT</property>
- <property name="wrap_mode">GTK_WRAP_NONE</property>
- <property name="cursor_visible">True</property>
- <property name="pixels_above_lines">0</property>
- <property name="pixels_below_lines">0</property>
- <property name="pixels_inside_wrap">0</property>
- <property name="left_margin">0</property>
- <property name="right_margin">0</property>
- <property name="indent">0</property>
- <property name="text" translatable="yes"></property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="shrink">False</property>
- <property name="resize">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkViewport" id="viewport1">
- <property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="button16">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <signal name="clicked" handler="on_execute" last_modification_time="Wed, 17 Dec 2003 05:06:44 GMT"/>
-
- <child>
- <widget class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-execute</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&gt;&gt;&gt;</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTextView" id="input">
- <property name="height_request">25</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="editable">True</property>
- <property name="justification">GTK_JUSTIFY_LEFT</property>
- <property name="wrap_mode">GTK_WRAP_NONE</property>
- <property name="cursor_visible">True</property>
- <property name="pixels_above_lines">0</property>
- <property name="pixels_below_lines">0</property>
- <property name="pixels_inside_wrap">0</property>
- <property name="left_margin">0</property>
- <property name="right_margin">0</property>
- <property name="indent">0</property>
- <property name="text" translatable="yes"></property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="shrink">False</property>
- <property name="resize">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="shrink">True</property>
- <property name="resize">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child internal-child="appbar">
- <widget class="GnomeAppBar" id="appbar1">
- <property name="visible">True</property>
- <property name="has_progress">False</property>
- <property name="has_status">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/logview.glade b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/logview.glade
deleted file mode 100644
index 1ec0b1f6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/logview.glade
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkWindow" id="logview">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Log</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <signal name="destroy" handler="on_logview_destroy" last_modification_time="Sun, 04 Jan 2004 22:16:59 GMT"/>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
- <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="loglist">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- </widget>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/service.py
deleted file mode 100755
index c9d46790..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/service.py
+++ /dev/null
@@ -1,399 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""L{twisted.manhole} L{PB<twisted.spread.pb>} service implementation.
-"""
-
-# twisted imports
-from twisted import copyright
-from twisted.spread import pb
-from twisted.python import log, failure
-from twisted.cred import portal
-from twisted.application import service
-from zope.interface import implements, Interface
-
-# sibling imports
-import explorer
-
-# system imports
-from cStringIO import StringIO
-
-import string
-import sys
-import traceback
-import types
-
-
-class FakeStdIO:
- def __init__(self, type_, list):
- self.type = type_
- self.list = list
-
- def write(self, text):
- log.msg("%s: %s" % (self.type, string.strip(str(text))))
- self.list.append((self.type, text))
-
- def flush(self):
- pass
-
- def consolidate(self):
- """Concatenate adjacent messages of same type into one.
-
- Greatly cuts down on the number of elements, increasing
- network transport friendliness considerably.
- """
- if not self.list:
- return
-
- inlist = self.list
- outlist = []
- last_type = inlist[0]
- block_begin = 0
- for i in xrange(1, len(self.list)):
- (mtype, message) = inlist[i]
- if mtype == last_type:
- continue
- else:
- if (i - block_begin) == 1:
- outlist.append(inlist[block_begin])
- else:
- messages = map(lambda l: l[1],
- inlist[block_begin:i])
- message = string.join(messages, '')
- outlist.append((last_type, message))
- last_type = mtype
- block_begin = i
-
-
-class IManholeClient(Interface):
- def console(list_of_messages):
- """Takes a list of (type, message) pairs to display.
-
- Types include:
- - \"stdout\" -- string sent to sys.stdout
-
- - \"stderr\" -- string sent to sys.stderr
-
- - \"result\" -- string repr of the resulting value
- of the expression
-
- - \"exception\" -- a L{failure.Failure}
- """
-
- def receiveExplorer(xplorer):
- """Receives an explorer.Explorer
- """
-
- def listCapabilities():
- """List what manholey things I am capable of doing.
-
- i.e. C{\"Explorer\"}, C{\"Failure\"}
- """
-
-def runInConsole(command, console, globalNS=None, localNS=None,
- filename=None, args=None, kw=None, unsafeTracebacks=False):
- """Run this, directing all output to the specified console.
-
- If command is callable, it will be called with the args and keywords
- provided. Otherwise, command will be compiled and eval'd.
- (Wouldn't you like a macro?)
-
- Returns the command's return value.
-
- The console is called with a list of (type, message) pairs for
- display, see L{IManholeClient.console}.
- """
- output = []
- fakeout = FakeStdIO("stdout", output)
- fakeerr = FakeStdIO("stderr", output)
- errfile = FakeStdIO("exception", output)
- code = None
- val = None
- if filename is None:
- filename = str(console)
- if args is None:
- args = ()
- if kw is None:
- kw = {}
- if localNS is None:
- localNS = globalNS
- if (globalNS is None) and (not callable(command)):
- raise ValueError("Need a namespace to evaluate the command in.")
-
- try:
- out = sys.stdout
- err = sys.stderr
- sys.stdout = fakeout
- sys.stderr = fakeerr
- try:
- if callable(command):
- val = apply(command, args, kw)
- else:
- try:
- code = compile(command, filename, 'eval')
- except:
- code = compile(command, filename, 'single')
-
- if code:
- val = eval(code, globalNS, localNS)
- finally:
- sys.stdout = out
- sys.stderr = err
- except:
- (eType, eVal, tb) = sys.exc_info()
- fail = failure.Failure(eVal, eType, tb)
- del tb
- # In CVS reversion 1.35, there was some code here to fill in the
- # source lines in the traceback for frames in the local command
- # buffer. But I can't figure out when that's triggered, so it's
- # going away in the conversion to Failure, until you bring it back.
- errfile.write(pb.failure2Copyable(fail, unsafeTracebacks))
-
- if console:
- fakeout.consolidate()
- console(output)
-
- return val
-
-def _failureOldStyle(fail):
- """Pre-Failure manhole representation of exceptions.
-
- For compatibility with manhole clients without the \"Failure\"
- capability.
-
- A dictionary with two members:
- - \'traceback\' -- traceback.extract_tb output; a list of tuples
- (filename, line number, function name, text) suitable for
- feeding to traceback.format_list.
-
- - \'exception\' -- a list of one or more strings, each
- ending in a newline. (traceback.format_exception_only output)
- """
- import linecache
- tb = []
- for f in fail.frames:
- # (filename, line number, function name, text)
- tb.append((f[1], f[2], f[0], linecache.getline(f[1], f[2])))
-
- return {
- 'traceback': tb,
- 'exception': traceback.format_exception_only(fail.type, fail.value)
- }
-
-# Capabilities clients are likely to have before they knew how to answer a
-# "listCapabilities" query.
-_defaultCapabilities = {
- "Explorer": 'Set'
- }
-
-class Perspective(pb.Avatar):
- lastDeferred = 0
- def __init__(self, service):
- self.localNamespace = {
- "service": service,
- "avatar": self,
- "_": None,
- }
- self.clients = {}
- self.service = service
-
- def __getstate__(self):
- state = self.__dict__.copy()
- state['clients'] = {}
- if state['localNamespace'].has_key("__builtins__"):
- del state['localNamespace']['__builtins__']
- return state
-
- def attached(self, client, identity):
- """A client has attached -- welcome them and add them to the list.
- """
- self.clients[client] = identity
-
- host = ':'.join(map(str, client.broker.transport.getHost()[1:]))
-
- msg = self.service.welcomeMessage % {
- 'you': getattr(identity, 'name', str(identity)),
- 'host': host,
- 'longversion': copyright.longversion,
- }
-
- client.callRemote('console', [("stdout", msg)])
-
- client.capabilities = _defaultCapabilities
- client.callRemote('listCapabilities').addCallbacks(
- self._cbClientCapable, self._ebClientCapable,
- callbackArgs=(client,),errbackArgs=(client,))
-
- def detached(self, client, identity):
- try:
- del self.clients[client]
- except KeyError:
- pass
-
- def runInConsole(self, command, *args, **kw):
- """Convience method to \"runInConsole with my stuff\".
- """
- return runInConsole(command,
- self.console,
- self.service.namespace,
- self.localNamespace,
- str(self.service),
- args=args,
- kw=kw,
- unsafeTracebacks=self.service.unsafeTracebacks)
-
-
- ### Methods for communicating to my clients.
-
- def console(self, message):
- """Pass a message to my clients' console.
- """
- clients = self.clients.keys()
- origMessage = message
- compatMessage = None
- for client in clients:
- try:
- if "Failure" not in client.capabilities:
- if compatMessage is None:
- compatMessage = origMessage[:]
- for i in xrange(len(message)):
- if ((message[i][0] == "exception") and
- isinstance(message[i][1], failure.Failure)):
- compatMessage[i] = (
- message[i][0],
- _failureOldStyle(message[i][1]))
- client.callRemote('console', compatMessage)
- else:
- client.callRemote('console', message)
- except pb.ProtocolError:
- # Stale broker.
- self.detached(client, None)
-
- def receiveExplorer(self, objectLink):
- """Pass an Explorer on to my clients.
- """
- clients = self.clients.keys()
- for client in clients:
- try:
- client.callRemote('receiveExplorer', objectLink)
- except pb.ProtocolError:
- # Stale broker.
- self.detached(client, None)
-
-
- def _cbResult(self, val, dnum):
- self.console([('result', "Deferred #%s Result: %r\n" %(dnum, val))])
- return val
-
- def _cbClientCapable(self, capabilities, client):
- log.msg("client %x has %s" % (id(client), capabilities))
- client.capabilities = capabilities
-
- def _ebClientCapable(self, reason, client):
- reason.trap(AttributeError)
- log.msg("Couldn't get capabilities from %s, assuming defaults." %
- (client,))
-
- ### perspective_ methods, commands used by the client.
-
- def perspective_do(self, expr):
- """Evaluate the given expression, with output to the console.
-
- The result is stored in the local variable '_', and its repr()
- string is sent to the console as a \"result\" message.
- """
- log.msg(">>> %s" % expr)
- val = self.runInConsole(expr)
- if val is not None:
- self.localNamespace["_"] = val
- from twisted.internet.defer import Deferred
- # TODO: client support for Deferred.
- if isinstance(val, Deferred):
- self.lastDeferred += 1
- self.console([('result', "Waiting for Deferred #%s...\n" % self.lastDeferred)])
- val.addBoth(self._cbResult, self.lastDeferred)
- else:
- self.console([("result", repr(val) + '\n')])
- log.msg("<<<")
-
- def perspective_explore(self, identifier):
- """Browse the object obtained by evaluating the identifier.
-
- The resulting ObjectLink is passed back through the client's
- receiveBrowserObject method.
- """
- object = self.runInConsole(identifier)
- if object:
- expl = explorer.explorerPool.getExplorer(object, identifier)
- self.receiveExplorer(expl)
-
- def perspective_watch(self, identifier):
- """Watch the object obtained by evaluating the identifier.
-
- Whenever I think this object might have changed, I will pass
- an ObjectLink of it back to the client's receiveBrowserObject
- method.
- """
- raise NotImplementedError
- object = self.runInConsole(identifier)
- if object:
- # Return an ObjectLink of this right away, before the watch.
- oLink = self.runInConsole(self.browser.browseObject,
- object, identifier)
- self.receiveExplorer(oLink)
-
- self.runInConsole(self.browser.watchObject,
- object, identifier,
- self.receiveExplorer)
-
-
-class Realm:
-
- implements(portal.IRealm)
-
- def __init__(self, service):
- self.service = service
- self._cache = {}
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if pb.IPerspective not in interfaces:
- raise NotImplementedError("no interface")
- if avatarId in self._cache:
- p = self._cache[avatarId]
- else:
- p = Perspective(self.service)
- p.attached(mind, avatarId)
- def detached():
- p.detached(mind, avatarId)
- return (pb.IPerspective, p, detached)
-
-
-class Service(service.Service):
-
- welcomeMessage = (
- "\nHello %(you)s, welcome to Manhole "
- "on %(host)s.\n"
- "%(longversion)s.\n\n")
-
- def __init__(self, unsafeTracebacks=False, namespace=None):
- self.unsafeTracebacks = unsafeTracebacks
- self.namespace = {
- '__name__': '__manhole%x__' % (id(self),),
- 'sys': sys
- }
- if namespace:
- self.namespace.update(namespace)
-
- def __getstate__(self):
- """This returns the persistent state of this shell factory.
- """
- # TODO -- refactor this and twisted.reality.author.Author to
- # use common functionality (perhaps the 'code' module?)
- dict = self.__dict__.copy()
- ns = dict['namespace'].copy()
- dict['namespace'] = ns
- if ns.has_key('__builtins__'):
- del ns['__builtins__']
- return dict
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/telnet.py
deleted file mode 100755
index d63b3a6b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/telnet.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Telnet-based shell."""
-
-# twisted imports
-from twisted.protocols import telnet
-from twisted.internet import protocol
-from twisted.python import log, failure
-
-# system imports
-import string, copy, sys
-from cStringIO import StringIO
-
-
-class Shell(telnet.Telnet):
- """A Python command-line shell."""
-
- def connectionMade(self):
- telnet.Telnet.connectionMade(self)
- self.lineBuffer = []
-
- def loggedIn(self):
- self.transport.write(">>> ")
-
- def checkUserAndPass(self, username, password):
- return ((self.factory.username == username) and (password == self.factory.password))
-
- def write(self, data):
- """Write some data to the transport.
- """
- self.transport.write(data)
-
- def telnet_Command(self, cmd):
- if self.lineBuffer:
- if not cmd:
- cmd = string.join(self.lineBuffer, '\n') + '\n\n\n'
- self.doCommand(cmd)
- self.lineBuffer = []
- return "Command"
- else:
- self.lineBuffer.append(cmd)
- self.transport.write("... ")
- return "Command"
- else:
- self.doCommand(cmd)
- return "Command"
-
- def doCommand(self, cmd):
-
- # TODO -- refactor this, Reality.author.Author, and the manhole shell
- #to use common functionality (perhaps a twisted.python.code module?)
- fn = '$telnet$'
- result = None
- try:
- out = sys.stdout
- sys.stdout = self
- try:
- code = compile(cmd,fn,'eval')
- result = eval(code, self.factory.namespace)
- except:
- try:
- code = compile(cmd, fn, 'exec')
- exec code in self.factory.namespace
- except SyntaxError, e:
- if not self.lineBuffer and str(e)[:14] == "unexpected EOF":
- self.lineBuffer.append(cmd)
- self.transport.write("... ")
- return
- else:
- failure.Failure().printTraceback(file=self)
- log.deferr()
- self.write('\r\n>>> ')
- return
- except:
- io = StringIO()
- failure.Failure().printTraceback(file=self)
- log.deferr()
- self.write('\r\n>>> ')
- return
- finally:
- sys.stdout = out
-
- self.factory.namespace['_'] = result
- if result is not None:
- self.transport.write(repr(result))
- self.transport.write('\r\n')
- self.transport.write(">>> ")
-
-
-
-class ShellFactory(protocol.Factory):
- username = "admin"
- password = "admin"
- protocol = Shell
- service = None
-
- def __init__(self):
- self.namespace = {
- 'factory': self,
- 'service': None,
- '_': None
- }
-
- def setService(self, service):
- self.namespace['service'] = self.service = service
-
- def __getstate__(self):
- """This returns the persistent state of this shell factory.
- """
- dict = self.__dict__
- ns = copy.copy(dict['namespace'])
- dict['namespace'] = ns
- if ns.has_key('__builtins__'):
- del ns['__builtins__']
- return dict
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/__init__.py
deleted file mode 100755
index 83c9ea12..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.manhole}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/test_explorer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/test_explorer.py
deleted file mode 100755
index a52d3c1a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/test/test_explorer.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.manhole.explorer}.
-"""
-
-from twisted.trial import unittest
-from twisted.manhole.explorer import (
- CRUFT_WatchyThingie,
- ExplorerImmutable,
- Pool,
- _WatchMonkey,
- )
-
-
-class Foo:
- """
- Test helper.
- """
-
-
-class PoolTestCase(unittest.TestCase):
- """
- Tests for the Pool class.
- """
-
- def test_instanceBuilding(self):
- """
- If the object is not in the pool a new instance is created and
- returned.
- """
- p = Pool()
- e = p.getExplorer(123, 'id')
- self.assertIsInstance(e, ExplorerImmutable)
- self.assertEqual(e.value, 123)
- self.assertEqual(e.identifier, 'id')
-
-
-
-class CRUFTWatchyThingieTestCase(unittest.TestCase):
- """
- Tests for the CRUFT_WatchyThingie class.
- """
- def test_watchObjectConstructedClass(self):
- """
- L{CRUFT_WatchyThingie.watchObject} changes the class of its
- first argument to a custom watching class.
- """
- foo = Foo()
- cwt = CRUFT_WatchyThingie()
- cwt.watchObject(foo, 'id', 'cback')
-
- # check new constructed class
- newClassName = foo.__class__.__name__
- self.assertEqual(newClassName, "WatchingFoo%X" % (id(foo),))
-
-
- def test_watchObjectConstructedInstanceMethod(self):
- """
- L{CRUFT_WatchyThingie.watchingfoo} adds a C{_watchEmitChanged}
- attribute which refers to a bound method on the instance
- passed to it.
- """
- foo = Foo()
- cwt = CRUFT_WatchyThingie()
- cwt.watchObject(foo, 'id', 'cback')
-
- # check new constructed instance method
- self.assertIdentical(foo._watchEmitChanged.im_self, foo)
-
-
-
-class WatchMonkeyTestCase(unittest.TestCase):
- """
- Tests for the _WatchMonkey class.
- """
- def test_install(self):
- """
- When _WatchMonkey is installed on a method, calling that
- method calls the _WatchMonkey.
- """
- class Foo:
- """
- Helper.
- """
- def someMethod(self):
- """
- Just a method.
- """
-
- foo = Foo()
- wm = _WatchMonkey(foo)
- wm.install('someMethod')
-
- # patch wm's method to check that the method was exchanged
- called = []
- wm.__call__ = lambda s: called.append(True)
-
- # call and check
- foo.someMethod()
- self.assertTrue(called)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/__init__.py
deleted file mode 100755
index 14af615e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Twisted Manhole UI: User interface for direct manipulation in Twisted.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.glade b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.glade
deleted file mode 100644
index 423b3fb8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.glade
+++ /dev/null
@@ -1,268 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkWindow" id="manholeWindow">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Manhole</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="default_width">620</property>
- <property name="default_height">320</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <signal name="delete_event" handler="_on_manholeWindow_delete_event" last_modification_time="Mon, 27 Jan 2003 05:14:26 GMT"/>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkMenuBar" id="menubar1">
- <property name="visible">True</property>
-
- <child>
- <widget class="GtkMenuItem" id="menuitem4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_File</property>
- <property name="use_underline">True</property>
-
- <child>
- <widget class="GtkMenu" id="menuitem4_menu">
-
- <child>
- <widget class="GtkImageMenuItem" id="openMenuItem">
- <property name="visible">True</property>
- <property name="label">gtk-open</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="_on_openMenuItem_activate" last_modification_time="Sun, 02 Feb 2003 18:44:51 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkImageMenuItem" id="reload_self">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Reload the manhole client code. (Only useful for client development.)</property>
- <property name="label" translatable="yes">_Reload self</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="on_reload_self_activate" last_modification_time="Mon, 24 Feb 2003 00:15:10 GMT"/>
-
- <child internal-child="image">
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-revert-to-saved</property>
- <property name="icon_size">1</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="separatormenuitem1">
- <property name="visible">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkImageMenuItem" id="quitMenuItem">
- <property name="visible">True</property>
- <property name="label">gtk-quit</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="_on_quitMenuItem_activate" last_modification_time="Sun, 02 Feb 2003 18:48:12 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="menuitem5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Edit</property>
- <property name="use_underline">True</property>
-
- <child>
- <widget class="GtkMenu" id="menuitem5_menu">
-
- <child>
- <widget class="GtkImageMenuItem" id="cut1">
- <property name="visible">True</property>
- <property name="label">gtk-cut</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="on_cut1_activate" last_modification_time="Mon, 27 Jan 2003 04:50:50 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkImageMenuItem" id="copy1">
- <property name="visible">True</property>
- <property name="label">gtk-copy</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="on_copy1_activate" last_modification_time="Mon, 27 Jan 2003 04:50:50 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkImageMenuItem" id="paste1">
- <property name="visible">True</property>
- <property name="label">gtk-paste</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="on_paste1_activate" last_modification_time="Mon, 27 Jan 2003 04:50:50 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkImageMenuItem" id="delete1">
- <property name="visible">True</property>
- <property name="label">gtk-delete</property>
- <property name="use_stock">True</property>
- <signal name="activate" handler="on_delete1_activate" last_modification_time="Mon, 27 Jan 2003 04:50:50 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="menuitem7">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Help</property>
- <property name="use_underline">True</property>
-
- <child>
- <widget class="GtkMenu" id="menuitem7_menu">
-
- <child>
- <widget class="GtkMenuItem" id="aboutMenuItem">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_About</property>
- <property name="use_underline">True</property>
- <signal name="activate" handler="_on_aboutMenuItem_activate" last_modification_time="Thu, 06 Feb 2003 19:49:53 GMT"/>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVPaned" id="vpaned1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTextView" id="output">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="overwrite">False</property>
- <property name="accepts_tab">True</property>
- <property name="justification">GTK_JUSTIFY_LEFT</property>
- <property name="wrap_mode">GTK_WRAP_WORD</property>
- <property name="cursor_visible">True</property>
- <property name="pixels_above_lines">0</property>
- <property name="pixels_below_lines">0</property>
- <property name="pixels_inside_wrap">0</property>
- <property name="left_margin">0</property>
- <property name="right_margin">0</property>
- <property name="indent">0</property>
- <property name="text" translatable="yes"></property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="shrink">True</property>
- <property name="resize">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTextView" id="input">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="editable">True</property>
- <property name="overwrite">False</property>
- <property name="accepts_tab">True</property>
- <property name="justification">GTK_JUSTIFY_LEFT</property>
- <property name="wrap_mode">GTK_WRAP_NONE</property>
- <property name="cursor_visible">True</property>
- <property name="pixels_above_lines">0</property>
- <property name="pixels_below_lines">0</property>
- <property name="pixels_inside_wrap">0</property>
- <property name="left_margin">0</property>
- <property name="right_margin">0</property>
- <property name="indent">0</property>
- <property name="text" translatable="yes"></property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="shrink">True</property>
- <property name="resize">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkStatusbar" id="statusbar1">
- <property name="visible">True</property>
- <property name="has_resize_grip">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.py
deleted file mode 100755
index 2c6a532e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/gtk2manhole.py
+++ /dev/null
@@ -1,375 +0,0 @@
-# -*- test-case-name: twisted.manhole.ui.test.test_gtk2manhole -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Manhole client with a GTK v2.x front-end.
-"""
-
-__version__ = '$Revision: 1.9 $'[11:-2]
-
-from twisted import copyright
-from twisted.internet import reactor
-from twisted.python import components, failure, log, util
-from twisted.python.reflect import prefixedMethodNames
-from twisted.spread import pb
-from twisted.spread.ui import gtk2util
-
-from twisted.manhole.service import IManholeClient
-from zope.interface import implements
-
-# The pygtk.require for version 2.0 has already been done by the reactor.
-import gtk
-
-import code, types, inspect
-
-# TODO:
-# Make wrap-mode a run-time option.
-# Explorer.
-# Code doesn't cleanly handle opening a second connection. Fix that.
-# Make some acknowledgement of when a command has completed, even if
-# it has no return value so it doesn't print anything to the console.
-
-class OfflineError(Exception):
- pass
-
-class ManholeWindow(components.Componentized, gtk2util.GladeKeeper):
- gladefile = util.sibpath(__file__, "gtk2manhole.glade")
-
- _widgets = ('input','output','manholeWindow')
-
- def __init__(self):
- self.defaults = {}
- gtk2util.GladeKeeper.__init__(self)
- components.Componentized.__init__(self)
-
- self.input = ConsoleInput(self._input)
- self.input.toplevel = self
- self.output = ConsoleOutput(self._output)
-
- # Ugh. GladeKeeper actually isn't so good for composite objects.
- # I want this connected to the ConsoleInput's handler, not something
- # on this class.
- self._input.connect("key_press_event", self.input._on_key_press_event)
-
- def setDefaults(self, defaults):
- self.defaults = defaults
-
- def login(self):
- client = self.getComponent(IManholeClient)
- d = gtk2util.login(client, **self.defaults)
- d.addCallback(self._cbLogin)
- d.addCallback(client._cbLogin)
- d.addErrback(self._ebLogin)
-
- def _cbDisconnected(self, perspective):
- self.output.append("%s went away. :(\n" % (perspective,), "local")
- self._manholeWindow.set_title("Manhole")
-
- def _cbLogin(self, perspective):
- peer = perspective.broker.transport.getPeer()
- self.output.append("Connected to %s\n" % (peer,), "local")
- perspective.notifyOnDisconnect(self._cbDisconnected)
- self._manholeWindow.set_title("Manhole - %s" % (peer))
- return perspective
-
- def _ebLogin(self, reason):
- self.output.append("Login FAILED %s\n" % (reason.value,), "exception")
-
- def _on_aboutMenuItem_activate(self, widget, *unused):
- import sys
- from os import path
- self.output.append("""\
-a Twisted Manhole client
- Versions:
- %(twistedVer)s
- Python %(pythonVer)s on %(platform)s
- GTK %(gtkVer)s / PyGTK %(pygtkVer)s
- %(module)s %(modVer)s
-http://twistedmatrix.com/
-""" % {'twistedVer': copyright.longversion,
- 'pythonVer': sys.version.replace('\n', '\n '),
- 'platform': sys.platform,
- 'gtkVer': ".".join(map(str, gtk.gtk_version)),
- 'pygtkVer': ".".join(map(str, gtk.pygtk_version)),
- 'module': path.basename(__file__),
- 'modVer': __version__,
- }, "local")
-
- def _on_openMenuItem_activate(self, widget, userdata=None):
- self.login()
-
- def _on_manholeWindow_delete_event(self, widget, *unused):
- reactor.stop()
-
- def _on_quitMenuItem_activate(self, widget, *unused):
- reactor.stop()
-
- def on_reload_self_activate(self, *unused):
- from twisted.python import rebuild
- rebuild.rebuild(inspect.getmodule(self.__class__))
-
-
-tagdefs = {
- 'default': {"family": "monospace"},
- # These are message types we get from the server.
- 'stdout': {"foreground": "black"},
- 'stderr': {"foreground": "#AA8000"},
- 'result': {"foreground": "blue"},
- 'exception': {"foreground": "red"},
- # Messages generate locally.
- 'local': {"foreground": "#008000"},
- 'log': {"foreground": "#000080"},
- 'command': {"foreground": "#666666"},
- }
-
-# TODO: Factor Python console stuff back out to pywidgets.
-
-class ConsoleOutput:
- _willScroll = None
- def __init__(self, textView):
- self.textView = textView
- self.buffer = textView.get_buffer()
-
- # TODO: Make this a singleton tag table.
- for name, props in tagdefs.iteritems():
- tag = self.buffer.create_tag(name)
- # This can be done in the constructor in newer pygtk (post 1.99.14)
- for k, v in props.iteritems():
- tag.set_property(k, v)
-
- self.buffer.tag_table.lookup("default").set_priority(0)
-
- self._captureLocalLog()
-
- def _captureLocalLog(self):
- return log.startLogging(_Notafile(self, "log"), setStdout=False)
-
- def append(self, text, kind=None):
- # XXX: It seems weird to have to do this thing with always applying
- # a 'default' tag. Can't we change the fundamental look instead?
- tags = ["default"]
- if kind is not None:
- tags.append(kind)
-
- self.buffer.insert_with_tags_by_name(self.buffer.get_end_iter(),
- text, *tags)
- # Silly things, the TextView needs to update itself before it knows
- # where the bottom is.
- if self._willScroll is None:
- self._willScroll = gtk.idle_add(self._scrollDown)
-
- def _scrollDown(self, *unused):
- self.textView.scroll_to_iter(self.buffer.get_end_iter(), 0,
- True, 1.0, 1.0)
- self._willScroll = None
- return False
-
-class History:
- def __init__(self, maxhist=10000):
- self.ringbuffer = ['']
- self.maxhist = maxhist
- self.histCursor = 0
-
- def append(self, htext):
- self.ringbuffer.insert(-1, htext)
- if len(self.ringbuffer) > self.maxhist:
- self.ringbuffer.pop(0)
- self.histCursor = len(self.ringbuffer) - 1
- self.ringbuffer[-1] = ''
-
- def move(self, prevnext=1):
- '''
- Return next/previous item in the history, stopping at top/bottom.
- '''
- hcpn = self.histCursor + prevnext
- if hcpn >= 0 and hcpn < len(self.ringbuffer):
- self.histCursor = hcpn
- return self.ringbuffer[hcpn]
- else:
- return None
-
- def histup(self, textbuffer):
- if self.histCursor == len(self.ringbuffer) - 1:
- si, ei = textbuffer.get_start_iter(), textbuffer.get_end_iter()
- self.ringbuffer[-1] = textbuffer.get_text(si,ei)
- newtext = self.move(-1)
- if newtext is None:
- return
- textbuffer.set_text(newtext)
-
- def histdown(self, textbuffer):
- newtext = self.move(1)
- if newtext is None:
- return
- textbuffer.set_text(newtext)
-
-
-class ConsoleInput:
- toplevel, rkeymap = None, None
- __debug = False
-
- def __init__(self, textView):
- self.textView=textView
- self.rkeymap = {}
- self.history = History()
- for name in prefixedMethodNames(self.__class__, "key_"):
- keysymName = name.split("_")[-1]
- self.rkeymap[getattr(gtk.keysyms, keysymName)] = keysymName
-
- def _on_key_press_event(self, entry, event):
- stopSignal = False
- ksym = self.rkeymap.get(event.keyval, None)
-
- mods = []
- for prefix, mask in [('ctrl', gtk.gdk.CONTROL_MASK), ('shift', gtk.gdk.SHIFT_MASK)]:
- if event.state & mask:
- mods.append(prefix)
-
- if mods:
- ksym = '_'.join(mods + [ksym])
-
- if ksym:
- rvalue = getattr(
- self, 'key_%s' % ksym, lambda *a, **kw: None)(entry, event)
-
- if self.__debug:
- print ksym
- return rvalue
-
- def getText(self):
- buffer = self.textView.get_buffer()
- iter1, iter2 = buffer.get_bounds()
- text = buffer.get_text(iter1, iter2, False)
- return text
-
- def setText(self, text):
- self.textView.get_buffer().set_text(text)
-
- def key_Return(self, entry, event):
- text = self.getText()
- # Figure out if that Return meant "next line" or "execute."
- try:
- c = code.compile_command(text)
- except SyntaxError, e:
- # This could conceivably piss you off if the client's python
- # doesn't accept keywords that are known to the manhole's
- # python.
- point = buffer.get_iter_at_line_offset(e.lineno, e.offset)
- buffer.place(point)
- # TODO: Componentize!
- self.toplevel.output.append(str(e), "exception")
- except (OverflowError, ValueError), e:
- self.toplevel.output.append(str(e), "exception")
- else:
- if c is not None:
- self.sendMessage()
- # Don't insert Return as a newline in the buffer.
- self.history.append(text)
- self.clear()
- # entry.emit_stop_by_name("key_press_event")
- return True
- else:
- # not a complete code block
- return False
-
- return False
-
- def key_Up(self, entry, event):
- # if I'm at the top, previous history item.
- textbuffer = self.textView.get_buffer()
- if textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_line() == 0:
- self.history.histup(textbuffer)
- return True
- return False
-
- def key_Down(self, entry, event):
- textbuffer = self.textView.get_buffer()
- if textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_line() == (
- textbuffer.get_line_count() - 1):
- self.history.histdown(textbuffer)
- return True
- return False
-
- key_ctrl_p = key_Up
- key_ctrl_n = key_Down
-
- def key_ctrl_shift_F9(self, entry, event):
- if self.__debug:
- import pdb; pdb.set_trace()
-
- def clear(self):
- buffer = self.textView.get_buffer()
- buffer.delete(*buffer.get_bounds())
-
- def sendMessage(self):
- buffer = self.textView.get_buffer()
- iter1, iter2 = buffer.get_bounds()
- text = buffer.get_text(iter1, iter2, False)
- self.toplevel.output.append(pythonify(text), 'command')
- # TODO: Componentize better!
- try:
- return self.toplevel.getComponent(IManholeClient).do(text)
- except OfflineError:
- self.toplevel.output.append("Not connected, command not sent.\n",
- "exception")
-
-
-def pythonify(text):
- '''
- Make some text appear as though it was typed in at a Python prompt.
- '''
- lines = text.split('\n')
- lines[0] = '>>> ' + lines[0]
- return '\n... '.join(lines) + '\n'
-
-class _Notafile:
- """Curry to make failure.printTraceback work with the output widget."""
- def __init__(self, output, kind):
- self.output = output
- self.kind = kind
-
- def write(self, txt):
- self.output.append(txt, self.kind)
-
- def flush(self):
- pass
-
-class ManholeClient(components.Adapter, pb.Referenceable):
- implements(IManholeClient)
-
- capabilities = {
-# "Explorer": 'Set',
- "Failure": 'Set'
- }
-
- def _cbLogin(self, perspective):
- self.perspective = perspective
- perspective.notifyOnDisconnect(self._cbDisconnected)
- return perspective
-
- def remote_console(self, messages):
- for kind, content in messages:
- if isinstance(content, types.StringTypes):
- self.original.output.append(content, kind)
- elif (kind == "exception") and isinstance(content, failure.Failure):
- content.printTraceback(_Notafile(self.original.output,
- "exception"))
- else:
- self.original.output.append(str(content), kind)
-
- def remote_receiveExplorer(self, xplorer):
- pass
-
- def remote_listCapabilities(self):
- return self.capabilities
-
- def _cbDisconnected(self, perspective):
- self.perspective = None
-
- def do(self, text):
- if self.perspective is None:
- raise OfflineError
- return self.perspective.callRemote("do", text)
-
-components.registerAdapter(ManholeClient, ManholeWindow, IManholeClient)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/__init__.py
deleted file mode 100755
index 36214ba7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2009 Twisted Matrix Laboratories.
-"""
-Tests for the L{twisted.manhole.ui} package.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/test_gtk2manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/test_gtk2manhole.py
deleted file mode 100755
index b59f9370..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/manhole/ui/test/test_gtk2manhole.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (c) 2009 Twisted Matrix Laboratories.
-"""
-Tests for GTK2 GUI manhole.
-"""
-
-skip = False
-
-try:
- import pygtk
- pygtk.require("2.0")
-except:
- skip = "GTK 2.0 not available"
-else:
- try:
- import gtk
- except ImportError:
- skip = "GTK 2.0 not available"
- except RuntimeError:
- skip = "Old version of GTK 2.0 requires DISPLAY, and we don't have one."
- else:
- if gtk.gtk_version[0] == 1:
- skip = "Requested GTK 2.0, but 1.0 was already imported."
- else:
- from twisted.manhole.ui.gtk2manhole import ConsoleInput
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python.reflect import prefixedMethodNames
-
-class ConsoleInputTests(TestCase):
- """
- Tests for L{ConsoleInput}.
- """
-
- def test_reverseKeymap(self):
- """
- Verify that a L{ConsoleInput} has a reverse mapping of the keysym names
- it needs for event handling to their corresponding keysym.
- """
- ci = ConsoleInput(None)
- for eventName in prefixedMethodNames(ConsoleInput, 'key_'):
- keysymName = eventName.split("_")[-1]
- keysymValue = getattr(gtk.keysyms, keysymName)
- self.assertEqual(ci.rkeymap[keysymValue], keysymName)
-
-
- skip = skip
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/__init__.py
deleted file mode 100755
index 4c1d7c92..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""Resolving Internet Names"""
-
-from twisted.names._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/_version.py
deleted file mode 100755
index 736065b6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.names', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/authority.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/authority.py
deleted file mode 100755
index 0dc7c1c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/authority.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_names -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Authoritative resolvers.
-"""
-
-import os
-import time
-
-from twisted.names import dns
-from twisted.internet import defer
-from twisted.python import failure
-from twisted.python.compat import execfile
-
-import common
-
-def getSerial(filename = '/tmp/twisted-names.serial'):
- """Return a monotonically increasing (across program runs) integer.
-
- State is stored in the given file. If it does not exist, it is
- created with rw-/---/--- permissions.
- """
- serial = time.strftime('%Y%m%d')
-
- o = os.umask(0177)
- try:
- if not os.path.exists(filename):
- f = file(filename, 'w')
- f.write(serial + ' 0')
- f.close()
- finally:
- os.umask(o)
-
- serialFile = file(filename, 'r')
- lastSerial, ID = serialFile.readline().split()
- ID = (lastSerial == serial) and (int(ID) + 1) or 0
- serialFile.close()
- serialFile = file(filename, 'w')
- serialFile.write('%s %d' % (serial, ID))
- serialFile.close()
- serial = serial + ('%02d' % (ID,))
- return serial
-
-
-#class LookupCacherMixin(object):
-# _cache = None
-#
-# def _lookup(self, name, cls, type, timeout = 10):
-# if not self._cache:
-# self._cache = {}
-# self._meth = super(LookupCacherMixin, self)._lookup
-#
-# if self._cache.has_key((name, cls, type)):
-# return self._cache[(name, cls, type)]
-# else:
-# r = self._meth(name, cls, type, timeout)
-# self._cache[(name, cls, type)] = r
-# return r
-
-
-class FileAuthority(common.ResolverBase):
- """An Authority that is loaded from a file."""
-
- soa = None
- records = None
-
- def __init__(self, filename):
- common.ResolverBase.__init__(self)
- self.loadFile(filename)
- self._cache = {}
-
-
- def __setstate__(self, state):
- self.__dict__ = state
-# print 'setstate ', self.soa
-
- def _lookup(self, name, cls, type, timeout = None):
- cnames = []
- results = []
- authority = []
- additional = []
- default_ttl = max(self.soa[1].minimum, self.soa[1].expire)
-
- domain_records = self.records.get(name.lower())
-
- if domain_records:
- for record in domain_records:
- if record.ttl is not None:
- ttl = record.ttl
- else:
- ttl = default_ttl
-
- if record.TYPE == dns.NS and name.lower() != self.soa[0].lower():
- # NS record belong to a child zone: this is a referral. As
- # NS records are authoritative in the child zone, ours here
- # are not. RFC 2181, section 6.1.
- authority.append(
- dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=False)
- )
- elif record.TYPE == type or type == dns.ALL_RECORDS:
- results.append(
- dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
- )
- if record.TYPE == dns.CNAME:
- cnames.append(
- dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
- )
- if not results:
- results = cnames
-
- for record in results + authority:
- section = {dns.NS: additional, dns.CNAME: results, dns.MX: additional}.get(record.type)
- if section is not None:
- n = str(record.payload.name)
- for rec in self.records.get(n.lower(), ()):
- if rec.TYPE == dns.A:
- section.append(
- dns.RRHeader(n, dns.A, dns.IN, rec.ttl or default_ttl, rec, auth=True)
- )
-
- if not results and not authority:
- # Empty response. Include SOA record to allow clients to cache
- # this response. RFC 1034, sections 3.7 and 4.3.4, and RFC 2181
- # section 7.1.
- authority.append(
- dns.RRHeader(self.soa[0], dns.SOA, dns.IN, ttl, self.soa[1], auth=True)
- )
- return defer.succeed((results, authority, additional))
- else:
- if name.lower().endswith(self.soa[0].lower()):
- # We are the authority and we didn't find it. Goodbye.
- return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
- return defer.fail(failure.Failure(dns.DomainError(name)))
-
-
- def lookupZone(self, name, timeout = 10):
- if self.soa[0].lower() == name.lower():
- # Wee hee hee hooo yea
- default_ttl = max(self.soa[1].minimum, self.soa[1].expire)
- if self.soa[1].ttl is not None:
- soa_ttl = self.soa[1].ttl
- else:
- soa_ttl = default_ttl
- results = [dns.RRHeader(self.soa[0], dns.SOA, dns.IN, soa_ttl, self.soa[1], auth=True)]
- for (k, r) in self.records.items():
- for rec in r:
- if rec.ttl is not None:
- ttl = rec.ttl
- else:
- ttl = default_ttl
- if rec.TYPE != dns.SOA:
- results.append(dns.RRHeader(k, rec.TYPE, dns.IN, ttl, rec, auth=True))
- results.append(results[0])
- return defer.succeed((results, (), ()))
- return defer.fail(failure.Failure(dns.DomainError(name)))
-
- def _cbAllRecords(self, results):
- ans, auth, add = [], [], []
- for res in results:
- if res[0]:
- ans.extend(res[1][0])
- auth.extend(res[1][1])
- add.extend(res[1][2])
- return ans, auth, add
-
-
-class PySourceAuthority(FileAuthority):
- """A FileAuthority that is built up from Python source code."""
-
- def loadFile(self, filename):
- g, l = self.setupConfigNamespace(), {}
- execfile(filename, g, l)
- if not l.has_key('zone'):
- raise ValueError, "No zone defined in " + filename
-
- self.records = {}
- for rr in l['zone']:
- if isinstance(rr[1], dns.Record_SOA):
- self.soa = rr
- self.records.setdefault(rr[0].lower(), []).append(rr[1])
-
-
- def wrapRecord(self, type):
- return lambda name, *arg, **kw: (name, type(*arg, **kw))
-
-
- def setupConfigNamespace(self):
- r = {}
- items = dns.__dict__.iterkeys()
- for record in [x for x in items if x.startswith('Record_')]:
- type = getattr(dns, record)
- f = self.wrapRecord(type)
- r[record[len('Record_'):]] = f
- return r
-
-
-class BindAuthority(FileAuthority):
- """An Authority that loads BIND configuration files"""
-
- def loadFile(self, filename):
- self.origin = os.path.basename(filename) + '.' # XXX - this might suck
- lines = open(filename).readlines()
- lines = self.stripComments(lines)
- lines = self.collapseContinuations(lines)
- self.parseLines(lines)
-
-
- def stripComments(self, lines):
- return [
- a.find(';') == -1 and a or a[:a.find(';')] for a in [
- b.strip() for b in lines
- ]
- ]
-
-
- def collapseContinuations(self, lines):
- L = []
- state = 0
- for line in lines:
- if state == 0:
- if line.find('(') == -1:
- L.append(line)
- else:
- L.append(line[:line.find('(')])
- state = 1
- else:
- if line.find(')') != -1:
- L[-1] += ' ' + line[:line.find(')')]
- state = 0
- else:
- L[-1] += ' ' + line
- lines = L
- L = []
- for line in lines:
- L.append(line.split())
- return filter(None, L)
-
-
- def parseLines(self, lines):
- TTL = 60 * 60 * 3
- ORIGIN = self.origin
-
- self.records = {}
-
- for (line, index) in zip(lines, range(len(lines))):
- if line[0] == '$TTL':
- TTL = dns.str2time(line[1])
- elif line[0] == '$ORIGIN':
- ORIGIN = line[1]
- elif line[0] == '$INCLUDE': # XXX - oh, fuck me
- raise NotImplementedError('$INCLUDE directive not implemented')
- elif line[0] == '$GENERATE':
- raise NotImplementedError('$GENERATE directive not implemented')
- else:
- self.parseRecordLine(ORIGIN, TTL, line)
-
-
- def addRecord(self, owner, ttl, type, domain, cls, rdata):
- if not domain.endswith('.'):
- domain = domain + '.' + owner
- else:
- domain = domain[:-1]
- f = getattr(self, 'class_%s' % cls, None)
- if f:
- f(ttl, type, domain, rdata)
- else:
- raise NotImplementedError, "Record class %r not supported" % cls
-
-
- def class_IN(self, ttl, type, domain, rdata):
- record = getattr(dns, 'Record_%s' % type, None)
- if record:
- r = record(*rdata)
- r.ttl = ttl
- self.records.setdefault(domain.lower(), []).append(r)
-
- print 'Adding IN Record', domain, ttl, r
- if type == 'SOA':
- self.soa = (domain, r)
- else:
- raise NotImplementedError, "Record type %r not supported" % type
-
-
- #
- # This file ends here. Read no further.
- #
- def parseRecordLine(self, origin, ttl, line):
- MARKERS = dns.QUERY_CLASSES.values() + dns.QUERY_TYPES.values()
- cls = 'IN'
- owner = origin
-
- if line[0] == '@':
- line = line[1:]
- owner = origin
-# print 'default owner'
- elif not line[0].isdigit() and line[0] not in MARKERS:
- owner = line[0]
- line = line[1:]
-# print 'owner is ', owner
-
- if line[0].isdigit() or line[0] in MARKERS:
- domain = owner
- owner = origin
-# print 'woops, owner is ', owner, ' domain is ', domain
- else:
- domain = line[0]
- line = line[1:]
-# print 'domain is ', domain
-
- if line[0] in dns.QUERY_CLASSES.values():
- cls = line[0]
- line = line[1:]
-# print 'cls is ', cls
- if line[0].isdigit():
- ttl = int(line[0])
- line = line[1:]
-# print 'ttl is ', ttl
- elif line[0].isdigit():
- ttl = int(line[0])
- line = line[1:]
-# print 'ttl is ', ttl
- if line[0] in dns.QUERY_CLASSES.values():
- cls = line[0]
- line = line[1:]
-# print 'cls is ', cls
-
- type = line[0]
-# print 'type is ', type
- rdata = line[1:]
-# print 'rdata is ', rdata
-
- self.addRecord(owner, ttl, type, domain, cls, rdata)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/cache.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/cache.py
deleted file mode 100755
index 854050b3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/cache.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- test-case-name: twisted.names.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from zope.interface import implements
-
-from twisted.names import dns, common
-from twisted.python import failure, log
-from twisted.internet import interfaces, defer
-
-
-
-class CacheResolver(common.ResolverBase):
- """
- A resolver that serves records from a local, memory cache.
-
- @ivar _reactor: A provider of L{interfaces.IReactorTime}.
- """
-
- implements(interfaces.IResolver)
-
- cache = None
-
- def __init__(self, cache=None, verbose=0, reactor=None):
- common.ResolverBase.__init__(self)
-
- self.cache = {}
- self.verbose = verbose
- self.cancel = {}
- if reactor is None:
- from twisted.internet import reactor
- self._reactor = reactor
-
- if cache:
- for query, (seconds, payload) in cache.items():
- self.cacheResult(query, payload, seconds)
-
-
- def __setstate__(self, state):
- self.__dict__ = state
-
- now = self._reactor.seconds()
- for (k, (when, (ans, add, ns))) in self.cache.items():
- diff = now - when
- for rec in ans + add + ns:
- if rec.ttl < diff:
- del self.cache[k]
- break
-
-
- def __getstate__(self):
- for c in self.cancel.values():
- c.cancel()
- self.cancel.clear()
- return self.__dict__
-
-
- def _lookup(self, name, cls, type, timeout):
- now = self._reactor.seconds()
- q = dns.Query(name, type, cls)
- try:
- when, (ans, auth, add) = self.cache[q]
- except KeyError:
- if self.verbose > 1:
- log.msg('Cache miss for ' + repr(name))
- return defer.fail(failure.Failure(dns.DomainError(name)))
- else:
- if self.verbose:
- log.msg('Cache hit for ' + repr(name))
- diff = now - when
-
- try:
- result = (
- [dns.RRHeader(str(r.name), r.type, r.cls, r.ttl - diff,
- r.payload) for r in ans],
- [dns.RRHeader(str(r.name), r.type, r.cls, r.ttl - diff,
- r.payload) for r in auth],
- [dns.RRHeader(str(r.name), r.type, r.cls, r.ttl - diff,
- r.payload) for r in add])
- except ValueError:
- return defer.fail(failure.Failure(dns.DomainError(name)))
- else:
- return defer.succeed(result)
-
-
- def lookupAllRecords(self, name, timeout = None):
- return defer.fail(failure.Failure(dns.DomainError(name)))
-
-
- def cacheResult(self, query, payload, cacheTime=None):
- """
- Cache a DNS entry.
-
- @param query: a L{dns.Query} instance.
-
- @param payload: a 3-tuple of lists of L{dns.RRHeader} records, the
- matching result of the query (answers, authority and additional).
-
- @param cacheTime: The time (seconds since epoch) at which the entry is
- considered to have been added to the cache. If C{None} is given,
- the current time is used.
- """
- if self.verbose > 1:
- log.msg('Adding %r to cache' % query)
-
- self.cache[query] = (cacheTime or self._reactor.seconds(), payload)
-
- if query in self.cancel:
- self.cancel[query].cancel()
-
- s = list(payload[0]) + list(payload[1]) + list(payload[2])
- if s:
- m = s[0].ttl
- for r in s:
- m = min(m, r.ttl)
- else:
- m = 0
-
- self.cancel[query] = self._reactor.callLater(m, self.clearEntry, query)
-
-
- def clearEntry(self, query):
- del self.cache[query]
- del self.cancel[query]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/client.py
deleted file mode 100755
index a8dd0c5d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/client.py
+++ /dev/null
@@ -1,955 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_names -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Asynchronous client DNS
-
-The functions exposed in this module can be used for asynchronous name
-resolution and dns queries.
-
-If you need to create a resolver with specific requirements, such as needing to
-do queries against a particular host, the L{createResolver} function will
-return an C{IResolver}.
-
-Future plans: Proper nameserver acquisition on Windows/MacOS,
-better caching, respect timeouts
-
-@author: Jp Calderone
-"""
-
-import os
-import errno
-import warnings
-
-from zope.interface import implements
-
-# Twisted imports
-from twisted.python.runtime import platform
-from twisted.internet import error, defer, protocol, interfaces
-from twisted.python import log, failure
-from twisted.python.deprecate import getWarningMethod
-from twisted.names import dns, common
-
-
-class Resolver(common.ResolverBase):
- """
- @ivar _waiting: A C{dict} mapping tuple keys of query name/type/class to
- Deferreds which will be called back with the result of those queries.
- This is used to avoid issuing the same query more than once in
- parallel. This is more efficient on the network and helps avoid a
- "birthday paradox" attack by keeping the number of outstanding requests
- for a particular query fixed at one instead of allowing the attacker to
- raise it to an arbitrary number.
-
- @ivar _reactor: A provider of L{IReactorTCP}, L{IReactorUDP}, and
- L{IReactorTime} which will be used to set up network resources and
- track timeouts.
- """
- implements(interfaces.IResolver)
-
- index = 0
- timeout = None
-
- factory = None
- servers = None
- dynServers = ()
- pending = None
- connections = None
-
- resolv = None
- _lastResolvTime = None
- _resolvReadInterval = 60
-
- def _getProtocol(self):
- getWarningMethod()(
- "Resolver.protocol is deprecated; use Resolver.queryUDP instead.",
- PendingDeprecationWarning,
- stacklevel=0)
- self.protocol = dns.DNSDatagramProtocol(self)
- return self.protocol
- protocol = property(_getProtocol)
-
-
- def __init__(self, resolv=None, servers=None, timeout=(1, 3, 11, 45), reactor=None):
- """
- Construct a resolver which will query domain name servers listed in
- the C{resolv.conf(5)}-format file given by C{resolv} as well as
- those in the given C{servers} list. Servers are queried in a
- round-robin fashion. If given, C{resolv} is periodically checked
- for modification and re-parsed if it is noticed to have changed.
-
- @type servers: C{list} of C{(str, int)} or C{None}
- @param servers: If not None, interpreted as a list of (host, port)
- pairs specifying addresses of domain name servers to attempt to use
- for this lookup. Host addresses should be in IPv4 dotted-quad
- form. If specified, overrides C{resolv}.
-
- @type resolv: C{str}
- @param resolv: Filename to read and parse as a resolver(5)
- configuration file.
-
- @type timeout: Sequence of C{int}
- @param timeout: Default number of seconds after which to reissue the
- query. When the last timeout expires, the query is considered
- failed.
-
- @param reactor: A provider of L{IReactorTime}, L{IReactorUDP}, and
- L{IReactorTCP} which will be used to establish connections, listen
- for DNS datagrams, and enforce timeouts. If not provided, the
- global reactor will be used.
-
- @raise ValueError: Raised if no nameserver addresses can be found.
- """
- common.ResolverBase.__init__(self)
-
- if reactor is None:
- from twisted.internet import reactor
- self._reactor = reactor
-
- self.timeout = timeout
-
- if servers is None:
- self.servers = []
- else:
- self.servers = servers
-
- self.resolv = resolv
-
- if not len(self.servers) and not resolv:
- raise ValueError, "No nameservers specified"
-
- self.factory = DNSClientFactory(self, timeout)
- self.factory.noisy = 0 # Be quiet by default
-
- self.connections = []
- self.pending = []
-
- self._waiting = {}
-
- self.maybeParseConfig()
-
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['connections'] = []
- d['_parseCall'] = None
- return d
-
-
- def __setstate__(self, state):
- self.__dict__.update(state)
- self.maybeParseConfig()
-
-
- def maybeParseConfig(self):
- if self.resolv is None:
- # Don't try to parse it, don't set up a call loop
- return
-
- try:
- resolvConf = file(self.resolv)
- except IOError, e:
- if e.errno == errno.ENOENT:
- # Missing resolv.conf is treated the same as an empty resolv.conf
- self.parseConfig(())
- else:
- raise
- else:
- mtime = os.fstat(resolvConf.fileno()).st_mtime
- if mtime != self._lastResolvTime:
- log.msg('%s changed, reparsing' % (self.resolv,))
- self._lastResolvTime = mtime
- self.parseConfig(resolvConf)
-
- # Check again in a little while
- self._parseCall = self._reactor.callLater(
- self._resolvReadInterval, self.maybeParseConfig)
-
-
- def parseConfig(self, resolvConf):
- servers = []
- for L in resolvConf:
- L = L.strip()
- if L.startswith('nameserver'):
- resolver = (L.split()[1], dns.PORT)
- servers.append(resolver)
- log.msg("Resolver added %r to server list" % (resolver,))
- elif L.startswith('domain'):
- try:
- self.domain = L.split()[1]
- except IndexError:
- self.domain = ''
- self.search = None
- elif L.startswith('search'):
- try:
- self.search = L.split()[1:]
- except IndexError:
- self.search = ''
- self.domain = None
- if not servers:
- servers.append(('127.0.0.1', dns.PORT))
- self.dynServers = servers
-
-
- def pickServer(self):
- """
- Return the address of a nameserver.
-
- TODO: Weight servers for response time so faster ones can be
- preferred.
- """
- if not self.servers and not self.dynServers:
- return None
- serverL = len(self.servers)
- dynL = len(self.dynServers)
-
- self.index += 1
- self.index %= (serverL + dynL)
- if self.index < serverL:
- return self.servers[self.index]
- else:
- return self.dynServers[self.index - serverL]
-
-
- def _connectedProtocol(self):
- """
- Return a new L{DNSDatagramProtocol} bound to a randomly selected port
- number.
- """
- if 'protocol' in self.__dict__:
- # Some code previously asked for or set the deprecated `protocol`
- # attribute, so it probably expects that object to be used for
- # queries. Give it back and skip the super awesome source port
- # randomization logic. This is actually a really good reason to
- # remove this deprecated backward compatibility as soon as
- # possible. -exarkun
- return self.protocol
- proto = dns.DNSDatagramProtocol(self)
- while True:
- try:
- self._reactor.listenUDP(dns.randomSource(), proto)
- except error.CannotListenError:
- pass
- else:
- return proto
-
-
- def connectionMade(self, protocol):
- """
- Called by associated L{dns.DNSProtocol} instances when they connect.
- """
- self.connections.append(protocol)
- for (d, q, t) in self.pending:
- self.queryTCP(q, t).chainDeferred(d)
- del self.pending[:]
-
-
- def connectionLost(self, protocol):
- """
- Called by associated L{dns.DNSProtocol} instances when they disconnect.
- """
- if protocol in self.connections:
- self.connections.remove(protocol)
-
-
- def messageReceived(self, message, protocol, address = None):
- log.msg("Unexpected message (%d) received from %r" % (message.id, address))
-
-
- def _query(self, *args):
- """
- Get a new L{DNSDatagramProtocol} instance from L{_connectedProtocol},
- issue a query to it using C{*args}, and arrange for it to be
- disconnected from its transport after the query completes.
-
- @param *args: Positional arguments to be passed to
- L{DNSDatagramProtocol.query}.
-
- @return: A L{Deferred} which will be called back with the result of the
- query.
- """
- protocol = self._connectedProtocol()
- d = protocol.query(*args)
- def cbQueried(result):
- protocol.transport.stopListening()
- return result
- d.addBoth(cbQueried)
- return d
-
-
- def queryUDP(self, queries, timeout = None):
- """
- Make a number of DNS queries via UDP.
-
- @type queries: A C{list} of C{dns.Query} instances
- @param queries: The queries to make.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- @raise C{twisted.internet.defer.TimeoutError}: When the query times
- out.
- """
- if timeout is None:
- timeout = self.timeout
-
- addresses = self.servers + list(self.dynServers)
- if not addresses:
- return defer.fail(IOError("No domain name servers available"))
-
- # Make sure we go through servers in the list in the order they were
- # specified.
- addresses.reverse()
-
- used = addresses.pop()
- d = self._query(used, queries, timeout[0])
- d.addErrback(self._reissue, addresses, [used], queries, timeout)
- return d
-
-
- def _reissue(self, reason, addressesLeft, addressesUsed, query, timeout):
- reason.trap(dns.DNSQueryTimeoutError)
-
- # If there are no servers left to be tried, adjust the timeout
- # to the next longest timeout period and move all the
- # "used" addresses back to the list of addresses to try.
- if not addressesLeft:
- addressesLeft = addressesUsed
- addressesLeft.reverse()
- addressesUsed = []
- timeout = timeout[1:]
-
- # If all timeout values have been used this query has failed. Tell the
- # protocol we're giving up on it and return a terminal timeout failure
- # to our caller.
- if not timeout:
- return failure.Failure(defer.TimeoutError(query))
-
- # Get an address to try. Take it out of the list of addresses
- # to try and put it ino the list of already tried addresses.
- address = addressesLeft.pop()
- addressesUsed.append(address)
-
- # Issue a query to a server. Use the current timeout. Add this
- # function as a timeout errback in case another retry is required.
- d = self._query(address, query, timeout[0], reason.value.id)
- d.addErrback(self._reissue, addressesLeft, addressesUsed, query, timeout)
- return d
-
-
- def queryTCP(self, queries, timeout = 10):
- """
- Make a number of DNS queries via TCP.
-
- @type queries: Any non-zero number of C{dns.Query} instances
- @param queries: The queries to make.
-
- @type timeout: C{int}
- @param timeout: The number of seconds after which to fail.
-
- @rtype: C{Deferred}
- """
- if not len(self.connections):
- address = self.pickServer()
- if address is None:
- return defer.fail(IOError("No domain name servers available"))
- host, port = address
- self._reactor.connectTCP(host, port, self.factory)
- self.pending.append((defer.Deferred(), queries, timeout))
- return self.pending[-1][0]
- else:
- return self.connections[0].query(queries, timeout)
-
-
- def filterAnswers(self, message):
- """
- Extract results from the given message.
-
- If the message was truncated, re-attempt the query over TCP and return
- a Deferred which will fire with the results of that query.
-
- If the message's result code is not L{dns.OK}, return a Failure
- indicating the type of error which occurred.
-
- Otherwise, return a three-tuple of lists containing the results from
- the answers section, the authority section, and the additional section.
- """
- if message.trunc:
- return self.queryTCP(message.queries).addCallback(self.filterAnswers)
- if message.rCode != dns.OK:
- return failure.Failure(self.exceptionForCode(message.rCode)(message))
- return (message.answers, message.authority, message.additional)
-
-
- def _lookup(self, name, cls, type, timeout):
- """
- Build a L{dns.Query} for the given parameters and dispatch it via UDP.
-
- If this query is already outstanding, it will not be re-issued.
- Instead, when the outstanding query receives a response, that response
- will be re-used for this query as well.
-
- @type name: C{str}
- @type type: C{int}
- @type cls: C{int}
-
- @return: A L{Deferred} which fires with a three-tuple giving the
- answer, authority, and additional sections of the response or with
- a L{Failure} if the response code is anything other than C{dns.OK}.
- """
- key = (name, type, cls)
- waiting = self._waiting.get(key)
- if waiting is None:
- self._waiting[key] = []
- d = self.queryUDP([dns.Query(name, type, cls)], timeout)
- def cbResult(result):
- for d in self._waiting.pop(key):
- d.callback(result)
- return result
- d.addCallback(self.filterAnswers)
- d.addBoth(cbResult)
- else:
- d = defer.Deferred()
- waiting.append(d)
- return d
-
-
- # This one doesn't ever belong on UDP
- def lookupZone(self, name, timeout = 10):
- """
- Perform an AXFR request. This is quite different from usual
- DNS requests. See http://cr.yp.to/djbdns/axfr-notes.html for
- more information.
- """
- address = self.pickServer()
- if address is None:
- return defer.fail(IOError('No domain name servers available'))
- host, port = address
- d = defer.Deferred()
- controller = AXFRController(name, d)
- factory = DNSClientFactory(controller, timeout)
- factory.noisy = False #stfu
-
- connector = self._reactor.connectTCP(host, port, factory)
- controller.timeoutCall = self._reactor.callLater(
- timeout or 10, self._timeoutZone, d, controller,
- connector, timeout or 10)
- return d.addCallback(self._cbLookupZone, connector)
-
- def _timeoutZone(self, d, controller, connector, seconds):
- connector.disconnect()
- controller.timeoutCall = None
- controller.deferred = None
- d.errback(error.TimeoutError("Zone lookup timed out after %d seconds" % (seconds,)))
-
- def _cbLookupZone(self, result, connector):
- connector.disconnect()
- return (result, [], [])
-
-
-class AXFRController:
- timeoutCall = None
-
- def __init__(self, name, deferred):
- self.name = name
- self.deferred = deferred
- self.soa = None
- self.records = []
-
- def connectionMade(self, protocol):
- # dig saids recursion-desired to 0, so I will too
- message = dns.Message(protocol.pickID(), recDes=0)
- message.queries = [dns.Query(self.name, dns.AXFR, dns.IN)]
- protocol.writeMessage(message)
-
-
- def connectionLost(self, protocol):
- # XXX Do something here - see #3428
- pass
-
-
- def messageReceived(self, message, protocol):
- # Caveat: We have to handle two cases: All records are in 1
- # message, or all records are in N messages.
-
- # According to http://cr.yp.to/djbdns/axfr-notes.html,
- # 'authority' and 'additional' are always empty, and only
- # 'answers' is present.
- self.records.extend(message.answers)
- if not self.records:
- return
- if not self.soa:
- if self.records[0].type == dns.SOA:
- #print "first SOA!"
- self.soa = self.records[0]
- if len(self.records) > 1 and self.records[-1].type == dns.SOA:
- #print "It's the second SOA! We're done."
- if self.timeoutCall is not None:
- self.timeoutCall.cancel()
- self.timeoutCall = None
- if self.deferred is not None:
- self.deferred.callback(self.records)
- self.deferred = None
-
-
-
-from twisted.internet.base import ThreadedResolver as _ThreadedResolverImpl
-
-class ThreadedResolver(_ThreadedResolverImpl):
- def __init__(self, reactor=None):
- if reactor is None:
- from twisted.internet import reactor
- _ThreadedResolverImpl.__init__(self, reactor)
- warnings.warn(
- "twisted.names.client.ThreadedResolver is deprecated since "
- "Twisted 9.0, use twisted.internet.base.ThreadedResolver "
- "instead.",
- category=DeprecationWarning, stacklevel=2)
-
-class DNSClientFactory(protocol.ClientFactory):
- def __init__(self, controller, timeout = 10):
- self.controller = controller
- self.timeout = timeout
-
-
- def clientConnectionLost(self, connector, reason):
- pass
-
-
- def buildProtocol(self, addr):
- p = dns.DNSProtocol(self.controller)
- p.factory = self
- return p
-
-
-
-def createResolver(servers=None, resolvconf=None, hosts=None):
- """
- Create and return a Resolver.
-
- @type servers: C{list} of C{(str, int)} or C{None}
-
- @param servers: If not C{None}, interpreted as a list of domain name servers
- to attempt to use. Each server is a tuple of address in C{str} dotted-quad
- form and C{int} port number.
-
- @type resolvconf: C{str} or C{None}
- @param resolvconf: If not C{None}, on posix systems will be interpreted as
- an alternate resolv.conf to use. Will do nothing on windows systems. If
- C{None}, /etc/resolv.conf will be used.
-
- @type hosts: C{str} or C{None}
- @param hosts: If not C{None}, an alternate hosts file to use. If C{None}
- on posix systems, /etc/hosts will be used. On windows, C:\windows\hosts
- will be used.
-
- @rtype: C{IResolver}
- """
- from twisted.names import resolve, cache, root, hosts as hostsModule
- if platform.getType() == 'posix':
- if resolvconf is None:
- resolvconf = '/etc/resolv.conf'
- if hosts is None:
- hosts = '/etc/hosts'
- theResolver = Resolver(resolvconf, servers)
- hostResolver = hostsModule.Resolver(hosts)
- else:
- if hosts is None:
- hosts = r'c:\windows\hosts'
- from twisted.internet import reactor
- bootstrap = _ThreadedResolverImpl(reactor)
- hostResolver = hostsModule.Resolver(hosts)
- theResolver = root.bootstrap(bootstrap)
-
- L = [hostResolver, cache.CacheResolver(), theResolver]
- return resolve.ResolverChain(L)
-
-theResolver = None
-def getResolver():
- """
- Get a Resolver instance.
-
- Create twisted.names.client.theResolver if it is C{None}, and then return
- that value.
-
- @rtype: C{IResolver}
- """
- global theResolver
- if theResolver is None:
- try:
- theResolver = createResolver()
- except ValueError:
- theResolver = createResolver(servers=[('127.0.0.1', 53)])
- return theResolver
-
-def getHostByName(name, timeout=None, effort=10):
- """
- Resolve a name to a valid ipv4 or ipv6 address.
-
- Will errback with C{DNSQueryTimeoutError} on a timeout, C{DomainError} or
- C{AuthoritativeDomainError} (or subclasses) on other errors.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @type effort: C{int}
- @param effort: How many times CNAME and NS records to follow while
- resolving this name.
-
- @rtype: C{Deferred}
- """
- return getResolver().getHostByName(name, timeout, effort)
-
-def lookupAddress(name, timeout=None):
- """
- Perform an A record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupAddress(name, timeout)
-
-def lookupIPV6Address(name, timeout=None):
- """
- Perform an AAAA record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupIPV6Address(name, timeout)
-
-def lookupAddress6(name, timeout=None):
- """
- Perform an A6 record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupAddress6(name, timeout)
-
-def lookupMailExchange(name, timeout=None):
- """
- Perform an MX record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupMailExchange(name, timeout)
-
-def lookupNameservers(name, timeout=None):
- """
- Perform an NS record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupNameservers(name, timeout)
-
-def lookupCanonicalName(name, timeout=None):
- """
- Perform a CNAME record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupCanonicalName(name, timeout)
-
-def lookupMailBox(name, timeout=None):
- """
- Perform an MB record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupMailBox(name, timeout)
-
-def lookupMailGroup(name, timeout=None):
- """
- Perform an MG record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupMailGroup(name, timeout)
-
-def lookupMailRename(name, timeout=None):
- """
- Perform an MR record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupMailRename(name, timeout)
-
-def lookupPointer(name, timeout=None):
- """
- Perform a PTR record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupPointer(name, timeout)
-
-def lookupAuthority(name, timeout=None):
- """
- Perform an SOA record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupAuthority(name, timeout)
-
-def lookupNull(name, timeout=None):
- """
- Perform a NULL record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupNull(name, timeout)
-
-def lookupWellKnownServices(name, timeout=None):
- """
- Perform a WKS record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupWellKnownServices(name, timeout)
-
-def lookupService(name, timeout=None):
- """
- Perform an SRV record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupService(name, timeout)
-
-def lookupHostInfo(name, timeout=None):
- """
- Perform a HINFO record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupHostInfo(name, timeout)
-
-def lookupMailboxInfo(name, timeout=None):
- """
- Perform an MINFO record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupMailboxInfo(name, timeout)
-
-def lookupText(name, timeout=None):
- """
- Perform a TXT record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupText(name, timeout)
-
-def lookupSenderPolicy(name, timeout=None):
- """
- Perform a SPF record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupSenderPolicy(name, timeout)
-
-def lookupResponsibility(name, timeout=None):
- """
- Perform an RP record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupResponsibility(name, timeout)
-
-def lookupAFSDatabase(name, timeout=None):
- """
- Perform an AFSDB record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupAFSDatabase(name, timeout)
-
-def lookupZone(name, timeout=None):
- """
- Perform an AXFR record lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: C{int}
- @param timeout: When this timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- # XXX: timeout here is not a list of ints, it is a single int.
- return getResolver().lookupZone(name, timeout)
-
-def lookupAllRecords(name, timeout=None):
- """
- ALL_RECORD lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupAllRecords(name, timeout)
-
-
-
-def lookupNamingAuthorityPointer(name, timeout=None):
- """
- NAPTR lookup.
-
- @type name: C{str}
- @param name: DNS name to resolve.
-
- @type timeout: Sequence of C{int}
- @param timeout: Number of seconds after which to reissue the query.
- When the last timeout expires, the query is considered failed.
-
- @rtype: C{Deferred}
- """
- return getResolver().lookupNamingAuthorityPointer(name, timeout)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/common.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/common.py
deleted file mode 100755
index 440913ea..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/common.py
+++ /dev/null
@@ -1,278 +0,0 @@
-# -*- test-case-name: twisted.names.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Base functionality useful to various parts of Twisted Names.
-"""
-
-import socket
-
-from twisted.names import dns
-from twisted.names.error import DNSFormatError, DNSServerError, DNSNameError
-from twisted.names.error import DNSNotImplementedError, DNSQueryRefusedError
-from twisted.names.error import DNSUnknownError
-
-from twisted.internet import defer, error
-from twisted.python import failure
-
-EMPTY_RESULT = (), (), ()
-
-class ResolverBase:
- """
- L{ResolverBase} is a base class for L{IResolver} implementations which
- deals with a lot of the boilerplate of implementing all of the lookup
- methods.
-
- @cvar _errormap: A C{dict} mapping DNS protocol failure response codes
- to exception classes which will be used to represent those failures.
- """
- _errormap = {
- dns.EFORMAT: DNSFormatError,
- dns.ESERVER: DNSServerError,
- dns.ENAME: DNSNameError,
- dns.ENOTIMP: DNSNotImplementedError,
- dns.EREFUSED: DNSQueryRefusedError}
-
- typeToMethod = None
-
- def __init__(self):
- self.typeToMethod = {}
- for (k, v) in typeToMethod.items():
- self.typeToMethod[k] = getattr(self, v)
-
-
- def exceptionForCode(self, responseCode):
- """
- Convert a response code (one of the possible values of
- L{dns.Message.rCode} to an exception instance representing it.
-
- @since: 10.0
- """
- return self._errormap.get(responseCode, DNSUnknownError)
-
-
- def query(self, query, timeout = None):
- try:
- return self.typeToMethod[query.type](str(query.name), timeout)
- except KeyError, e:
- return defer.fail(failure.Failure(NotImplementedError(str(self.__class__) + " " + str(query.type))))
-
- def _lookup(self, name, cls, type, timeout):
- return defer.fail(NotImplementedError("ResolverBase._lookup"))
-
- def lookupAddress(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupAddress
- """
- return self._lookup(name, dns.IN, dns.A, timeout)
-
- def lookupIPV6Address(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupIPV6Address
- """
- return self._lookup(name, dns.IN, dns.AAAA, timeout)
-
- def lookupAddress6(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupAddress6
- """
- return self._lookup(name, dns.IN, dns.A6, timeout)
-
- def lookupMailExchange(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupMailExchange
- """
- return self._lookup(name, dns.IN, dns.MX, timeout)
-
- def lookupNameservers(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupNameservers
- """
- return self._lookup(name, dns.IN, dns.NS, timeout)
-
- def lookupCanonicalName(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupCanonicalName
- """
- return self._lookup(name, dns.IN, dns.CNAME, timeout)
-
- def lookupMailBox(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupMailBox
- """
- return self._lookup(name, dns.IN, dns.MB, timeout)
-
- def lookupMailGroup(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupMailGroup
- """
- return self._lookup(name, dns.IN, dns.MG, timeout)
-
- def lookupMailRename(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupMailRename
- """
- return self._lookup(name, dns.IN, dns.MR, timeout)
-
- def lookupPointer(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupPointer
- """
- return self._lookup(name, dns.IN, dns.PTR, timeout)
-
- def lookupAuthority(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupAuthority
- """
- return self._lookup(name, dns.IN, dns.SOA, timeout)
-
- def lookupNull(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupNull
- """
- return self._lookup(name, dns.IN, dns.NULL, timeout)
-
- def lookupWellKnownServices(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupWellKnownServices
- """
- return self._lookup(name, dns.IN, dns.WKS, timeout)
-
- def lookupService(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupService
- """
- return self._lookup(name, dns.IN, dns.SRV, timeout)
-
- def lookupHostInfo(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupHostInfo
- """
- return self._lookup(name, dns.IN, dns.HINFO, timeout)
-
- def lookupMailboxInfo(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupMailboxInfo
- """
- return self._lookup(name, dns.IN, dns.MINFO, timeout)
-
- def lookupText(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupText
- """
- return self._lookup(name, dns.IN, dns.TXT, timeout)
-
- def lookupSenderPolicy(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupSenderPolicy
- """
- return self._lookup(name, dns.IN, dns.SPF, timeout)
-
- def lookupResponsibility(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupResponsibility
- """
- return self._lookup(name, dns.IN, dns.RP, timeout)
-
- def lookupAFSDatabase(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupAFSDatabase
- """
- return self._lookup(name, dns.IN, dns.AFSDB, timeout)
-
- def lookupZone(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupZone
- """
- return self._lookup(name, dns.IN, dns.AXFR, timeout)
-
-
- def lookupNamingAuthorityPointer(self, name, timeout=None):
- """
- @see: twisted.names.client.lookupNamingAuthorityPointer
- """
- return self._lookup(name, dns.IN, dns.NAPTR, timeout)
-
-
- def lookupAllRecords(self, name, timeout = None):
- """
- @see: twisted.names.client.lookupAllRecords
- """
- return self._lookup(name, dns.IN, dns.ALL_RECORDS, timeout)
-
- def getHostByName(self, name, timeout = None, effort = 10):
- """
- @see: twisted.names.client.getHostByName
- """
- # XXX - respect timeout
- return self.lookupAllRecords(name, timeout
- ).addCallback(self._cbRecords, name, effort
- )
-
- def _cbRecords(self, (ans, auth, add), name, effort):
- result = extractRecord(self, dns.Name(name), ans + auth + add, effort)
- if not result:
- raise error.DNSLookupError(name)
- return result
-
-
-def extractRecord(resolver, name, answers, level=10):
- if not level:
- return None
- if hasattr(socket, 'inet_ntop'):
- for r in answers:
- if r.name == name and r.type == dns.A6:
- return socket.inet_ntop(socket.AF_INET6, r.payload.address)
- for r in answers:
- if r.name == name and r.type == dns.AAAA:
- return socket.inet_ntop(socket.AF_INET6, r.payload.address)
- for r in answers:
- if r.name == name and r.type == dns.A:
- return socket.inet_ntop(socket.AF_INET, r.payload.address)
- for r in answers:
- if r.name == name and r.type == dns.CNAME:
- result = extractRecord(
- resolver, r.payload.name, answers, level - 1)
- if not result:
- return resolver.getHostByName(
- str(r.payload.name), effort=level - 1)
- return result
- # No answers, but maybe there's a hint at who we should be asking about
- # this
- for r in answers:
- if r.type == dns.NS:
- from twisted.names import client
- r = client.Resolver(servers=[(str(r.payload.name), dns.PORT)])
- return r.lookupAddress(str(name)
- ).addCallback(
- lambda (ans, auth, add):
- extractRecord(r, name, ans + auth + add, level - 1))
-
-
-typeToMethod = {
- dns.A: 'lookupAddress',
- dns.AAAA: 'lookupIPV6Address',
- dns.A6: 'lookupAddress6',
- dns.NS: 'lookupNameservers',
- dns.CNAME: 'lookupCanonicalName',
- dns.SOA: 'lookupAuthority',
- dns.MB: 'lookupMailBox',
- dns.MG: 'lookupMailGroup',
- dns.MR: 'lookupMailRename',
- dns.NULL: 'lookupNull',
- dns.WKS: 'lookupWellKnownServices',
- dns.PTR: 'lookupPointer',
- dns.HINFO: 'lookupHostInfo',
- dns.MINFO: 'lookupMailboxInfo',
- dns.MX: 'lookupMailExchange',
- dns.TXT: 'lookupText',
- dns.SPF: 'lookupSenderPolicy',
-
- dns.RP: 'lookupResponsibility',
- dns.AFSDB: 'lookupAFSDatabase',
- dns.SRV: 'lookupService',
- dns.NAPTR: 'lookupNamingAuthorityPointer',
- dns.AXFR: 'lookupZone',
- dns.ALL_RECORDS: 'lookupAllRecords',
-}
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/dns.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/dns.py
deleted file mode 100755
index 2b47d4d5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/dns.py
+++ /dev/null
@@ -1,1954 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_dns -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-DNS protocol implementation.
-
-Future Plans:
- - Get rid of some toplevels, maybe.
-
-@author: Moshe Zadka
-@author: Jean-Paul Calderone
-"""
-
-__all__ = [
- 'IEncodable', 'IRecord',
-
- 'A', 'A6', 'AAAA', 'AFSDB', 'CNAME', 'DNAME', 'HINFO',
- 'MAILA', 'MAILB', 'MB', 'MD', 'MF', 'MG', 'MINFO', 'MR', 'MX',
- 'NAPTR', 'NS', 'NULL', 'PTR', 'RP', 'SOA', 'SPF', 'SRV', 'TXT', 'WKS',
-
- 'ANY', 'CH', 'CS', 'HS', 'IN',
-
- 'ALL_RECORDS', 'AXFR', 'IXFR',
-
- 'EFORMAT', 'ENAME', 'ENOTIMP', 'EREFUSED', 'ESERVER',
-
- 'Record_A', 'Record_A6', 'Record_AAAA', 'Record_AFSDB', 'Record_CNAME',
- 'Record_DNAME', 'Record_HINFO', 'Record_MB', 'Record_MD', 'Record_MF',
- 'Record_MG', 'Record_MINFO', 'Record_MR', 'Record_MX', 'Record_NAPTR',
- 'Record_NS', 'Record_NULL', 'Record_PTR', 'Record_RP', 'Record_SOA',
- 'Record_SPF', 'Record_SRV', 'Record_TXT', 'Record_WKS', 'UnknownRecord',
-
- 'QUERY_CLASSES', 'QUERY_TYPES', 'REV_CLASSES', 'REV_TYPES', 'EXT_QUERIES',
-
- 'Charstr', 'Message', 'Name', 'Query', 'RRHeader', 'SimpleRecord',
- 'DNSDatagramProtocol', 'DNSMixin', 'DNSProtocol',
-
- 'OK', 'OP_INVERSE', 'OP_NOTIFY', 'OP_QUERY', 'OP_STATUS', 'OP_UPDATE',
- 'PORT',
-
- 'AuthoritativeDomainError', 'DNSQueryTimeoutError', 'DomainError',
- ]
-
-
-# System imports
-import warnings
-
-import struct, random, types, socket
-
-import cStringIO as StringIO
-
-AF_INET6 = socket.AF_INET6
-
-from zope.interface import implements, Interface, Attribute
-
-
-# Twisted imports
-from twisted.internet import protocol, defer
-from twisted.internet.error import CannotListenError
-from twisted.python import log, failure
-from twisted.python import util as tputil
-from twisted.python import randbytes
-
-
-def randomSource():
- """
- Wrapper around L{randbytes.secureRandom} to return 2 random chars.
- """
- return struct.unpack('H', randbytes.secureRandom(2, fallback=True))[0]
-
-
-PORT = 53
-
-(A, NS, MD, MF, CNAME, SOA, MB, MG, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT,
- RP, AFSDB) = range(1, 19)
-AAAA = 28
-SRV = 33
-NAPTR = 35
-A6 = 38
-DNAME = 39
-SPF = 99
-
-QUERY_TYPES = {
- A: 'A',
- NS: 'NS',
- MD: 'MD',
- MF: 'MF',
- CNAME: 'CNAME',
- SOA: 'SOA',
- MB: 'MB',
- MG: 'MG',
- MR: 'MR',
- NULL: 'NULL',
- WKS: 'WKS',
- PTR: 'PTR',
- HINFO: 'HINFO',
- MINFO: 'MINFO',
- MX: 'MX',
- TXT: 'TXT',
- RP: 'RP',
- AFSDB: 'AFSDB',
-
- # 19 through 27? Eh, I'll get to 'em.
-
- AAAA: 'AAAA',
- SRV: 'SRV',
- NAPTR: 'NAPTR',
- A6: 'A6',
- DNAME: 'DNAME',
- SPF: 'SPF'
-}
-
-IXFR, AXFR, MAILB, MAILA, ALL_RECORDS = range(251, 256)
-
-# "Extended" queries (Hey, half of these are deprecated, good job)
-EXT_QUERIES = {
- IXFR: 'IXFR',
- AXFR: 'AXFR',
- MAILB: 'MAILB',
- MAILA: 'MAILA',
- ALL_RECORDS: 'ALL_RECORDS'
-}
-
-REV_TYPES = dict([
- (v, k) for (k, v) in QUERY_TYPES.items() + EXT_QUERIES.items()
-])
-
-IN, CS, CH, HS = range(1, 5)
-ANY = 255
-
-QUERY_CLASSES = {
- IN: 'IN',
- CS: 'CS',
- CH: 'CH',
- HS: 'HS',
- ANY: 'ANY'
-}
-REV_CLASSES = dict([
- (v, k) for (k, v) in QUERY_CLASSES.items()
-])
-
-
-# Opcodes
-OP_QUERY, OP_INVERSE, OP_STATUS = range(3)
-OP_NOTIFY = 4 # RFC 1996
-OP_UPDATE = 5 # RFC 2136
-
-
-# Response Codes
-OK, EFORMAT, ESERVER, ENAME, ENOTIMP, EREFUSED = range(6)
-
-class IRecord(Interface):
- """
- An single entry in a zone of authority.
- """
-
- TYPE = Attribute("An indicator of what kind of record this is.")
-
-
-# Backwards compatibility aliases - these should be deprecated or something I
-# suppose. -exarkun
-from twisted.names.error import DomainError, AuthoritativeDomainError
-from twisted.names.error import DNSQueryTimeoutError
-
-
-def str2time(s):
- suffixes = (
- ('S', 1), ('M', 60), ('H', 60 * 60), ('D', 60 * 60 * 24),
- ('W', 60 * 60 * 24 * 7), ('Y', 60 * 60 * 24 * 365)
- )
- if isinstance(s, types.StringType):
- s = s.upper().strip()
- for (suff, mult) in suffixes:
- if s.endswith(suff):
- return int(float(s[:-1]) * mult)
- try:
- s = int(s)
- except ValueError:
- raise ValueError, "Invalid time interval specifier: " + s
- return s
-
-
-def readPrecisely(file, l):
- buff = file.read(l)
- if len(buff) < l:
- raise EOFError
- return buff
-
-
-class IEncodable(Interface):
- """
- Interface for something which can be encoded to and decoded
- from a file object.
- """
-
- def encode(strio, compDict = None):
- """
- Write a representation of this object to the given
- file object.
-
- @type strio: File-like object
- @param strio: The stream to which to write bytes
-
- @type compDict: C{dict} or C{None}
- @param compDict: A dictionary of backreference addresses that have
- have already been written to this stream and that may be used for
- compression.
- """
-
- def decode(strio, length = None):
- """
- Reconstruct an object from data read from the given
- file object.
-
- @type strio: File-like object
- @param strio: The stream from which bytes may be read
-
- @type length: C{int} or C{None}
- @param length: The number of bytes in this RDATA field. Most
- implementations can ignore this value. Only in the case of
- records similar to TXT where the total length is in no way
- encoded in the data is it necessary.
- """
-
-
-
-class Charstr(object):
- implements(IEncodable)
-
- def __init__(self, string=''):
- if not isinstance(string, str):
- raise ValueError("%r is not a string" % (string,))
- self.string = string
-
-
- def encode(self, strio, compDict=None):
- """
- Encode this Character string into the appropriate byte format.
-
- @type strio: file
- @param strio: The byte representation of this Charstr will be written
- to this file.
- """
- string = self.string
- ind = len(string)
- strio.write(chr(ind))
- strio.write(string)
-
-
- def decode(self, strio, length=None):
- """
- Decode a byte string into this Name.
-
- @type strio: file
- @param strio: Bytes will be read from this file until the full string
- is decoded.
-
- @raise EOFError: Raised when there are not enough bytes available from
- C{strio}.
- """
- self.string = ''
- l = ord(readPrecisely(strio, 1))
- self.string = readPrecisely(strio, l)
-
-
- def __eq__(self, other):
- if isinstance(other, Charstr):
- return self.string == other.string
- return False
-
-
- def __hash__(self):
- return hash(self.string)
-
-
- def __str__(self):
- return self.string
-
-
-
-class Name:
- implements(IEncodable)
-
- def __init__(self, name=''):
- assert isinstance(name, types.StringTypes), "%r is not a string" % (name,)
- self.name = name
-
- def encode(self, strio, compDict=None):
- """
- Encode this Name into the appropriate byte format.
-
- @type strio: file
- @param strio: The byte representation of this Name will be written to
- this file.
-
- @type compDict: dict
- @param compDict: dictionary of Names that have already been encoded
- and whose addresses may be backreferenced by this Name (for the purpose
- of reducing the message size).
- """
- name = self.name
- while name:
- if compDict is not None:
- if name in compDict:
- strio.write(
- struct.pack("!H", 0xc000 | compDict[name]))
- return
- else:
- compDict[name] = strio.tell() + Message.headerSize
- ind = name.find('.')
- if ind > 0:
- label, name = name[:ind], name[ind + 1:]
- else:
- label, name = name, ''
- ind = len(label)
- strio.write(chr(ind))
- strio.write(label)
- strio.write(chr(0))
-
-
- def decode(self, strio, length=None):
- """
- Decode a byte string into this Name.
-
- @type strio: file
- @param strio: Bytes will be read from this file until the full Name
- is decoded.
-
- @raise EOFError: Raised when there are not enough bytes available
- from C{strio}.
-
- @raise ValueError: Raised when the name cannot be decoded (for example,
- because it contains a loop).
- """
- visited = set()
- self.name = ''
- off = 0
- while 1:
- l = ord(readPrecisely(strio, 1))
- if l == 0:
- if off > 0:
- strio.seek(off)
- return
- if (l >> 6) == 3:
- new_off = ((l&63) << 8
- | ord(readPrecisely(strio, 1)))
- if new_off in visited:
- raise ValueError("Compression loop in encoded name")
- visited.add(new_off)
- if off == 0:
- off = strio.tell()
- strio.seek(new_off)
- continue
- label = readPrecisely(strio, l)
- if self.name == '':
- self.name = label
- else:
- self.name = self.name + '.' + label
-
- def __eq__(self, other):
- if isinstance(other, Name):
- return str(self) == str(other)
- return 0
-
-
- def __hash__(self):
- return hash(str(self))
-
-
- def __str__(self):
- return self.name
-
-class Query:
- """
- Represent a single DNS query.
-
- @ivar name: The name about which this query is requesting information.
- @ivar type: The query type.
- @ivar cls: The query class.
- """
-
- implements(IEncodable)
-
- name = None
- type = None
- cls = None
-
- def __init__(self, name='', type=A, cls=IN):
- """
- @type name: C{str}
- @param name: The name about which to request information.
-
- @type type: C{int}
- @param type: The query type.
-
- @type cls: C{int}
- @param cls: The query class.
- """
- self.name = Name(name)
- self.type = type
- self.cls = cls
-
-
- def encode(self, strio, compDict=None):
- self.name.encode(strio, compDict)
- strio.write(struct.pack("!HH", self.type, self.cls))
-
-
- def decode(self, strio, length = None):
- self.name.decode(strio)
- buff = readPrecisely(strio, 4)
- self.type, self.cls = struct.unpack("!HH", buff)
-
-
- def __hash__(self):
- return hash((str(self.name).lower(), self.type, self.cls))
-
-
- def __cmp__(self, other):
- return isinstance(other, Query) and cmp(
- (str(self.name).lower(), self.type, self.cls),
- (str(other.name).lower(), other.type, other.cls)
- ) or cmp(self.__class__, other.__class__)
-
-
- def __str__(self):
- t = QUERY_TYPES.get(self.type, EXT_QUERIES.get(self.type, 'UNKNOWN (%d)' % self.type))
- c = QUERY_CLASSES.get(self.cls, 'UNKNOWN (%d)' % self.cls)
- return '<Query %s %s %s>' % (self.name, t, c)
-
-
- def __repr__(self):
- return 'Query(%r, %r, %r)' % (str(self.name), self.type, self.cls)
-
-
-class RRHeader(tputil.FancyEqMixin):
- """
- A resource record header.
-
- @cvar fmt: C{str} specifying the byte format of an RR.
-
- @ivar name: The name about which this reply contains information.
- @ivar type: The query type of the original request.
- @ivar cls: The query class of the original request.
- @ivar ttl: The time-to-live for this record.
- @ivar payload: An object that implements the IEncodable interface
-
- @ivar auth: A C{bool} indicating whether this C{RRHeader} was parsed from an
- authoritative message.
- """
-
- implements(IEncodable)
-
- compareAttributes = ('name', 'type', 'cls', 'ttl', 'payload', 'auth')
-
- fmt = "!HHIH"
-
- name = None
- type = None
- cls = None
- ttl = None
- payload = None
- rdlength = None
-
- cachedResponse = None
-
- def __init__(self, name='', type=A, cls=IN, ttl=0, payload=None, auth=False):
- """
- @type name: C{str}
- @param name: The name about which this reply contains information.
-
- @type type: C{int}
- @param type: The query type.
-
- @type cls: C{int}
- @param cls: The query class.
-
- @type ttl: C{int}
- @param ttl: Time to live for this record.
-
- @type payload: An object implementing C{IEncodable}
- @param payload: A Query Type specific data object.
-
- @raises ValueError: if the ttl is negative.
- """
- assert (payload is None) or isinstance(payload, UnknownRecord) or (payload.TYPE == type)
-
- if ttl < 0:
- raise ValueError("TTL cannot be negative")
-
- self.name = Name(name)
- self.type = type
- self.cls = cls
- self.ttl = ttl
- self.payload = payload
- self.auth = auth
-
-
- def encode(self, strio, compDict=None):
- self.name.encode(strio, compDict)
- strio.write(struct.pack(self.fmt, self.type, self.cls, self.ttl, 0))
- if self.payload:
- prefix = strio.tell()
- self.payload.encode(strio, compDict)
- aft = strio.tell()
- strio.seek(prefix - 2, 0)
- strio.write(struct.pack('!H', aft - prefix))
- strio.seek(aft, 0)
-
-
- def decode(self, strio, length = None):
- self.name.decode(strio)
- l = struct.calcsize(self.fmt)
- buff = readPrecisely(strio, l)
- r = struct.unpack(self.fmt, buff)
- self.type, self.cls, self.ttl, self.rdlength = r
-
-
- def isAuthoritative(self):
- return self.auth
-
-
- def __str__(self):
- t = QUERY_TYPES.get(self.type, EXT_QUERIES.get(self.type, 'UNKNOWN (%d)' % self.type))
- c = QUERY_CLASSES.get(self.cls, 'UNKNOWN (%d)' % self.cls)
- return '<RR name=%s type=%s class=%s ttl=%ds auth=%s>' % (self.name, t, c, self.ttl, self.auth and 'True' or 'False')
-
-
- __repr__ = __str__
-
-
-
-class SimpleRecord(tputil.FancyStrMixin, tputil.FancyEqMixin):
- """
- A Resource Record which consists of a single RFC 1035 domain-name.
-
- @type name: L{Name}
- @ivar name: The name associated with this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
-
- showAttributes = (('name', 'name', '%s'), 'ttl')
- compareAttributes = ('name', 'ttl')
-
- TYPE = None
- name = None
-
- def __init__(self, name='', ttl=None):
- self.name = Name(name)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- self.name.encode(strio, compDict)
-
-
- def decode(self, strio, length = None):
- self.name = Name()
- self.name.decode(strio)
-
-
- def __hash__(self):
- return hash(self.name)
-
-
-# Kinds of RRs - oh my!
-class Record_NS(SimpleRecord):
- """
- An authoritative nameserver.
- """
- TYPE = NS
- fancybasename = 'NS'
-
-
-
-class Record_MD(SimpleRecord):
- """
- A mail destination.
-
- This record type is obsolete.
-
- @see: L{Record_MX}
- """
- TYPE = MD
- fancybasename = 'MD'
-
-
-
-class Record_MF(SimpleRecord):
- """
- A mail forwarder.
-
- This record type is obsolete.
-
- @see: L{Record_MX}
- """
- TYPE = MF
- fancybasename = 'MF'
-
-
-
-class Record_CNAME(SimpleRecord):
- """
- The canonical name for an alias.
- """
- TYPE = CNAME
- fancybasename = 'CNAME'
-
-
-
-class Record_MB(SimpleRecord):
- """
- A mailbox domain name.
-
- This is an experimental record type.
- """
- TYPE = MB
- fancybasename = 'MB'
-
-
-
-class Record_MG(SimpleRecord):
- """
- A mail group member.
-
- This is an experimental record type.
- """
- TYPE = MG
- fancybasename = 'MG'
-
-
-
-class Record_MR(SimpleRecord):
- """
- A mail rename domain name.
-
- This is an experimental record type.
- """
- TYPE = MR
- fancybasename = 'MR'
-
-
-
-class Record_PTR(SimpleRecord):
- """
- A domain name pointer.
- """
- TYPE = PTR
- fancybasename = 'PTR'
-
-
-
-class Record_DNAME(SimpleRecord):
- """
- A non-terminal DNS name redirection.
-
- This record type provides the capability to map an entire subtree of the
- DNS name space to another domain. It differs from the CNAME record which
- maps a single node of the name space.
-
- @see: U{http://www.faqs.org/rfcs/rfc2672.html}
- @see: U{http://www.faqs.org/rfcs/rfc3363.html}
- """
- TYPE = DNAME
- fancybasename = 'DNAME'
-
-
-
-class Record_A(tputil.FancyEqMixin):
- """
- An IPv4 host address.
-
- @type address: C{str}
- @ivar address: The packed network-order representation of the IPv4 address
- associated with this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
-
- compareAttributes = ('address', 'ttl')
-
- TYPE = A
- address = None
-
- def __init__(self, address='0.0.0.0', ttl=None):
- address = socket.inet_aton(address)
- self.address = address
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(self.address)
-
-
- def decode(self, strio, length = None):
- self.address = readPrecisely(strio, 4)
-
-
- def __hash__(self):
- return hash(self.address)
-
-
- def __str__(self):
- return '<A address=%s ttl=%s>' % (self.dottedQuad(), self.ttl)
- __repr__ = __str__
-
-
- def dottedQuad(self):
- return socket.inet_ntoa(self.address)
-
-
-
-class Record_SOA(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- Marks the start of a zone of authority.
-
- This record describes parameters which are shared by all records within a
- particular zone.
-
- @type mname: L{Name}
- @ivar mname: The domain-name of the name server that was the original or
- primary source of data for this zone.
-
- @type rname: L{Name}
- @ivar rname: A domain-name which specifies the mailbox of the person
- responsible for this zone.
-
- @type serial: C{int}
- @ivar serial: The unsigned 32 bit version number of the original copy of
- the zone. Zone transfers preserve this value. This value wraps and
- should be compared using sequence space arithmetic.
-
- @type refresh: C{int}
- @ivar refresh: A 32 bit time interval before the zone should be refreshed.
-
- @type minimum: C{int}
- @ivar minimum: The unsigned 32 bit minimum TTL field that should be
- exported with any RR from this zone.
-
- @type expire: C{int}
- @ivar expire: A 32 bit time value that specifies the upper limit on the
- time interval that can elapse before the zone is no longer
- authoritative.
-
- @type retry: C{int}
- @ivar retry: A 32 bit time interval that should elapse before a failed
- refresh should be retried.
-
- @type ttl: C{int}
- @ivar ttl: The default TTL to use for records served from this zone.
- """
- implements(IEncodable, IRecord)
-
- fancybasename = 'SOA'
- compareAttributes = ('serial', 'mname', 'rname', 'refresh', 'expire', 'retry', 'minimum', 'ttl')
- showAttributes = (('mname', 'mname', '%s'), ('rname', 'rname', '%s'), 'serial', 'refresh', 'retry', 'expire', 'minimum', 'ttl')
-
- TYPE = SOA
-
- def __init__(self, mname='', rname='', serial=0, refresh=0, retry=0, expire=0, minimum=0, ttl=None):
- self.mname, self.rname = Name(mname), Name(rname)
- self.serial, self.refresh = str2time(serial), str2time(refresh)
- self.minimum, self.expire = str2time(minimum), str2time(expire)
- self.retry = str2time(retry)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- self.mname.encode(strio, compDict)
- self.rname.encode(strio, compDict)
- strio.write(
- struct.pack(
- '!LlllL',
- self.serial, self.refresh, self.retry, self.expire,
- self.minimum
- )
- )
-
-
- def decode(self, strio, length = None):
- self.mname, self.rname = Name(), Name()
- self.mname.decode(strio)
- self.rname.decode(strio)
- r = struct.unpack('!LlllL', readPrecisely(strio, 20))
- self.serial, self.refresh, self.retry, self.expire, self.minimum = r
-
-
- def __hash__(self):
- return hash((
- self.serial, self.mname, self.rname,
- self.refresh, self.expire, self.retry
- ))
-
-
-
-class Record_NULL(tputil.FancyStrMixin, tputil.FancyEqMixin):
- """
- A null record.
-
- This is an experimental record type.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
-
- fancybasename = 'NULL'
- showAttributes = compareAttributes = ('payload', 'ttl')
-
- TYPE = NULL
-
- def __init__(self, payload=None, ttl=None):
- self.payload = payload
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(self.payload)
-
-
- def decode(self, strio, length = None):
- self.payload = readPrecisely(strio, length)
-
-
- def __hash__(self):
- return hash(self.payload)
-
-
-
-class Record_WKS(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- A well known service description.
-
- This record type is obsolete. See L{Record_SRV}.
-
- @type address: C{str}
- @ivar address: The packed network-order representation of the IPv4 address
- associated with this record.
-
- @type protocol: C{int}
- @ivar protocol: The 8 bit IP protocol number for which this service map is
- relevant.
-
- @type map: C{str}
- @ivar map: A bitvector indicating the services available at the specified
- address.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
-
- fancybasename = "WKS"
- compareAttributes = ('address', 'protocol', 'map', 'ttl')
- showAttributes = [('_address', 'address', '%s'), 'protocol', 'ttl']
-
- TYPE = WKS
-
- _address = property(lambda self: socket.inet_ntoa(self.address))
-
- def __init__(self, address='0.0.0.0', protocol=0, map='', ttl=None):
- self.address = socket.inet_aton(address)
- self.protocol, self.map = protocol, map
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(self.address)
- strio.write(struct.pack('!B', self.protocol))
- strio.write(self.map)
-
-
- def decode(self, strio, length = None):
- self.address = readPrecisely(strio, 4)
- self.protocol = struct.unpack('!B', readPrecisely(strio, 1))[0]
- self.map = readPrecisely(strio, length - 5)
-
-
- def __hash__(self):
- return hash((self.address, self.protocol, self.map))
-
-
-
-class Record_AAAA(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- An IPv6 host address.
-
- @type address: C{str}
- @ivar address: The packed network-order representation of the IPv6 address
- associated with this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
-
- @see: U{http://www.faqs.org/rfcs/rfc1886.html}
- """
- implements(IEncodable, IRecord)
- TYPE = AAAA
-
- fancybasename = 'AAAA'
- showAttributes = (('_address', 'address', '%s'), 'ttl')
- compareAttributes = ('address', 'ttl')
-
- _address = property(lambda self: socket.inet_ntop(AF_INET6, self.address))
-
- def __init__(self, address = '::', ttl=None):
- self.address = socket.inet_pton(AF_INET6, address)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(self.address)
-
-
- def decode(self, strio, length = None):
- self.address = readPrecisely(strio, 16)
-
-
- def __hash__(self):
- return hash(self.address)
-
-
-
-class Record_A6(tputil.FancyStrMixin, tputil.FancyEqMixin):
- """
- An IPv6 address.
-
- This is an experimental record type.
-
- @type prefixLen: C{int}
- @ivar prefixLen: The length of the suffix.
-
- @type suffix: C{str}
- @ivar suffix: An IPv6 address suffix in network order.
-
- @type prefix: L{Name}
- @ivar prefix: If specified, a name which will be used as a prefix for other
- A6 records.
-
- @type bytes: C{int}
- @ivar bytes: The length of the prefix.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
-
- @see: U{http://www.faqs.org/rfcs/rfc2874.html}
- @see: U{http://www.faqs.org/rfcs/rfc3363.html}
- @see: U{http://www.faqs.org/rfcs/rfc3364.html}
- """
- implements(IEncodable, IRecord)
- TYPE = A6
-
- fancybasename = 'A6'
- showAttributes = (('_suffix', 'suffix', '%s'), ('prefix', 'prefix', '%s'), 'ttl')
- compareAttributes = ('prefixLen', 'prefix', 'suffix', 'ttl')
-
- _suffix = property(lambda self: socket.inet_ntop(AF_INET6, self.suffix))
-
- def __init__(self, prefixLen=0, suffix='::', prefix='', ttl=None):
- self.prefixLen = prefixLen
- self.suffix = socket.inet_pton(AF_INET6, suffix)
- self.prefix = Name(prefix)
- self.bytes = int((128 - self.prefixLen) / 8.0)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(struct.pack('!B', self.prefixLen))
- if self.bytes:
- strio.write(self.suffix[-self.bytes:])
- if self.prefixLen:
- # This may not be compressed
- self.prefix.encode(strio, None)
-
-
- def decode(self, strio, length = None):
- self.prefixLen = struct.unpack('!B', readPrecisely(strio, 1))[0]
- self.bytes = int((128 - self.prefixLen) / 8.0)
- if self.bytes:
- self.suffix = '\x00' * (16 - self.bytes) + readPrecisely(strio, self.bytes)
- if self.prefixLen:
- self.prefix.decode(strio)
-
-
- def __eq__(self, other):
- if isinstance(other, Record_A6):
- return (self.prefixLen == other.prefixLen and
- self.suffix[-self.bytes:] == other.suffix[-self.bytes:] and
- self.prefix == other.prefix and
- self.ttl == other.ttl)
- return NotImplemented
-
-
- def __hash__(self):
- return hash((self.prefixLen, self.suffix[-self.bytes:], self.prefix))
-
-
- def __str__(self):
- return '<A6 %s %s (%d) ttl=%s>' % (
- self.prefix,
- socket.inet_ntop(AF_INET6, self.suffix),
- self.prefixLen, self.ttl
- )
-
-
-
-class Record_SRV(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- The location of the server(s) for a specific protocol and domain.
-
- This is an experimental record type.
-
- @type priority: C{int}
- @ivar priority: The priority of this target host. A client MUST attempt to
- contact the target host with the lowest-numbered priority it can reach;
- target hosts with the same priority SHOULD be tried in an order defined
- by the weight field.
-
- @type weight: C{int}
- @ivar weight: Specifies a relative weight for entries with the same
- priority. Larger weights SHOULD be given a proportionately higher
- probability of being selected.
-
- @type port: C{int}
- @ivar port: The port on this target host of this service.
-
- @type target: L{Name}
- @ivar target: The domain name of the target host. There MUST be one or
- more address records for this name, the name MUST NOT be an alias (in
- the sense of RFC 1034 or RFC 2181). Implementors are urged, but not
- required, to return the address record(s) in the Additional Data
- section. Unless and until permitted by future standards action, name
- compression is not to be used for this field.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
-
- @see: U{http://www.faqs.org/rfcs/rfc2782.html}
- """
- implements(IEncodable, IRecord)
- TYPE = SRV
-
- fancybasename = 'SRV'
- compareAttributes = ('priority', 'weight', 'target', 'port', 'ttl')
- showAttributes = ('priority', 'weight', ('target', 'target', '%s'), 'port', 'ttl')
-
- def __init__(self, priority=0, weight=0, port=0, target='', ttl=None):
- self.priority = int(priority)
- self.weight = int(weight)
- self.port = int(port)
- self.target = Name(target)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(struct.pack('!HHH', self.priority, self.weight, self.port))
- # This can't be compressed
- self.target.encode(strio, None)
-
-
- def decode(self, strio, length = None):
- r = struct.unpack('!HHH', readPrecisely(strio, struct.calcsize('!HHH')))
- self.priority, self.weight, self.port = r
- self.target = Name()
- self.target.decode(strio)
-
-
- def __hash__(self):
- return hash((self.priority, self.weight, self.port, self.target))
-
-
-
-class Record_NAPTR(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- The location of the server(s) for a specific protocol and domain.
-
- @type order: C{int}
- @ivar order: An integer specifying the order in which the NAPTR records
- MUST be processed to ensure the correct ordering of rules. Low numbers
- are processed before high numbers.
-
- @type preference: C{int}
- @ivar preference: An integer that specifies the order in which NAPTR
- records with equal "order" values SHOULD be processed, low numbers
- being processed before high numbers.
-
- @type flag: L{Charstr}
- @ivar flag: A <character-string> containing flags to control aspects of the
- rewriting and interpretation of the fields in the record. Flags
- aresingle characters from the set [A-Z0-9]. The case of the alphabetic
- characters is not significant.
-
- At this time only four flags, "S", "A", "U", and "P", are defined.
-
- @type service: L{Charstr}
- @ivar service: Specifies the service(s) available down this rewrite path.
- It may also specify the particular protocol that is used to talk with a
- service. A protocol MUST be specified if the flags field states that
- the NAPTR is terminal.
-
- @type regexp: L{Charstr}
- @ivar regexp: A STRING containing a substitution expression that is applied
- to the original string held by the client in order to construct the
- next domain name to lookup.
-
- @type replacement: L{Name}
- @ivar replacement: The next NAME to query for NAPTR, SRV, or address
- records depending on the value of the flags field. This MUST be a
- fully qualified domain-name.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
-
- @see: U{http://www.faqs.org/rfcs/rfc2915.html}
- """
- implements(IEncodable, IRecord)
- TYPE = NAPTR
-
- compareAttributes = ('order', 'preference', 'flags', 'service', 'regexp',
- 'replacement')
- fancybasename = 'NAPTR'
- showAttributes = ('order', 'preference', ('flags', 'flags', '%s'),
- ('service', 'service', '%s'), ('regexp', 'regexp', '%s'),
- ('replacement', 'replacement', '%s'), 'ttl')
-
- def __init__(self, order=0, preference=0, flags='', service='', regexp='',
- replacement='', ttl=None):
- self.order = int(order)
- self.preference = int(preference)
- self.flags = Charstr(flags)
- self.service = Charstr(service)
- self.regexp = Charstr(regexp)
- self.replacement = Name(replacement)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict=None):
- strio.write(struct.pack('!HH', self.order, self.preference))
- # This can't be compressed
- self.flags.encode(strio, None)
- self.service.encode(strio, None)
- self.regexp.encode(strio, None)
- self.replacement.encode(strio, None)
-
-
- def decode(self, strio, length=None):
- r = struct.unpack('!HH', readPrecisely(strio, struct.calcsize('!HH')))
- self.order, self.preference = r
- self.flags = Charstr()
- self.service = Charstr()
- self.regexp = Charstr()
- self.replacement = Name()
- self.flags.decode(strio)
- self.service.decode(strio)
- self.regexp.decode(strio)
- self.replacement.decode(strio)
-
-
- def __hash__(self):
- return hash((
- self.order, self.preference, self.flags,
- self.service, self.regexp, self.replacement))
-
-
-
-class Record_AFSDB(tputil.FancyStrMixin, tputil.FancyEqMixin):
- """
- Map from a domain name to the name of an AFS cell database server.
-
- @type subtype: C{int}
- @ivar subtype: In the case of subtype 1, the host has an AFS version 3.0
- Volume Location Server for the named AFS cell. In the case of subtype
- 2, the host has an authenticated name server holding the cell-root
- directory node for the named DCE/NCA cell.
-
- @type hostname: L{Name}
- @ivar hostname: The domain name of a host that has a server for the cell
- named by this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
-
- @see: U{http://www.faqs.org/rfcs/rfc1183.html}
- """
- implements(IEncodable, IRecord)
- TYPE = AFSDB
-
- fancybasename = 'AFSDB'
- compareAttributes = ('subtype', 'hostname', 'ttl')
- showAttributes = ('subtype', ('hostname', 'hostname', '%s'), 'ttl')
-
- def __init__(self, subtype=0, hostname='', ttl=None):
- self.subtype = int(subtype)
- self.hostname = Name(hostname)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(struct.pack('!H', self.subtype))
- self.hostname.encode(strio, compDict)
-
-
- def decode(self, strio, length = None):
- r = struct.unpack('!H', readPrecisely(strio, struct.calcsize('!H')))
- self.subtype, = r
- self.hostname.decode(strio)
-
-
- def __hash__(self):
- return hash((self.subtype, self.hostname))
-
-
-
-class Record_RP(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- The responsible person for a domain.
-
- @type mbox: L{Name}
- @ivar mbox: A domain name that specifies the mailbox for the responsible
- person.
-
- @type txt: L{Name}
- @ivar txt: A domain name for which TXT RR's exist (indirection through
- which allows information sharing about the contents of this RP record).
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
-
- @see: U{http://www.faqs.org/rfcs/rfc1183.html}
- """
- implements(IEncodable, IRecord)
- TYPE = RP
-
- fancybasename = 'RP'
- compareAttributes = ('mbox', 'txt', 'ttl')
- showAttributes = (('mbox', 'mbox', '%s'), ('txt', 'txt', '%s'), 'ttl')
-
- def __init__(self, mbox='', txt='', ttl=None):
- self.mbox = Name(mbox)
- self.txt = Name(txt)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- self.mbox.encode(strio, compDict)
- self.txt.encode(strio, compDict)
-
-
- def decode(self, strio, length = None):
- self.mbox = Name()
- self.txt = Name()
- self.mbox.decode(strio)
- self.txt.decode(strio)
-
-
- def __hash__(self):
- return hash((self.mbox, self.txt))
-
-
-
-class Record_HINFO(tputil.FancyStrMixin, tputil.FancyEqMixin):
- """
- Host information.
-
- @type cpu: C{str}
- @ivar cpu: Specifies the CPU type.
-
- @type os: C{str}
- @ivar os: Specifies the OS.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
- TYPE = HINFO
-
- fancybasename = 'HINFO'
- showAttributes = compareAttributes = ('cpu', 'os', 'ttl')
-
- def __init__(self, cpu='', os='', ttl=None):
- self.cpu, self.os = cpu, os
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- strio.write(struct.pack('!B', len(self.cpu)) + self.cpu)
- strio.write(struct.pack('!B', len(self.os)) + self.os)
-
-
- def decode(self, strio, length = None):
- cpu = struct.unpack('!B', readPrecisely(strio, 1))[0]
- self.cpu = readPrecisely(strio, cpu)
- os = struct.unpack('!B', readPrecisely(strio, 1))[0]
- self.os = readPrecisely(strio, os)
-
-
- def __eq__(self, other):
- if isinstance(other, Record_HINFO):
- return (self.os.lower() == other.os.lower() and
- self.cpu.lower() == other.cpu.lower() and
- self.ttl == other.ttl)
- return NotImplemented
-
-
- def __hash__(self):
- return hash((self.os.lower(), self.cpu.lower()))
-
-
-
-class Record_MINFO(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- Mailbox or mail list information.
-
- This is an experimental record type.
-
- @type rmailbx: L{Name}
- @ivar rmailbx: A domain-name which specifies a mailbox which is responsible
- for the mailing list or mailbox. If this domain name names the root,
- the owner of the MINFO RR is responsible for itself.
-
- @type emailbx: L{Name}
- @ivar emailbx: A domain-name which specifies a mailbox which is to receive
- error messages related to the mailing list or mailbox specified by the
- owner of the MINFO record. If this domain name names the root, errors
- should be returned to the sender of the message.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
- TYPE = MINFO
-
- rmailbx = None
- emailbx = None
-
- fancybasename = 'MINFO'
- compareAttributes = ('rmailbx', 'emailbx', 'ttl')
- showAttributes = (('rmailbx', 'responsibility', '%s'),
- ('emailbx', 'errors', '%s'),
- 'ttl')
-
- def __init__(self, rmailbx='', emailbx='', ttl=None):
- self.rmailbx, self.emailbx = Name(rmailbx), Name(emailbx)
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict = None):
- self.rmailbx.encode(strio, compDict)
- self.emailbx.encode(strio, compDict)
-
-
- def decode(self, strio, length = None):
- self.rmailbx, self.emailbx = Name(), Name()
- self.rmailbx.decode(strio)
- self.emailbx.decode(strio)
-
-
- def __hash__(self):
- return hash((self.rmailbx, self.emailbx))
-
-
-
-class Record_MX(tputil.FancyStrMixin, tputil.FancyEqMixin):
- """
- Mail exchange.
-
- @type preference: C{int}
- @ivar preference: Specifies the preference given to this RR among others at
- the same owner. Lower values are preferred.
-
- @type name: L{Name}
- @ivar name: A domain-name which specifies a host willing to act as a mail
- exchange.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be
- cached.
- """
- implements(IEncodable, IRecord)
- TYPE = MX
-
- fancybasename = 'MX'
- compareAttributes = ('preference', 'name', 'ttl')
- showAttributes = ('preference', ('name', 'name', '%s'), 'ttl')
-
- def __init__(self, preference=0, name='', ttl=None, **kwargs):
- self.preference, self.name = int(preference), Name(kwargs.get('exchange', name))
- self.ttl = str2time(ttl)
-
- def encode(self, strio, compDict = None):
- strio.write(struct.pack('!H', self.preference))
- self.name.encode(strio, compDict)
-
-
- def decode(self, strio, length = None):
- self.preference = struct.unpack('!H', readPrecisely(strio, 2))[0]
- self.name = Name()
- self.name.decode(strio)
-
- def __hash__(self):
- return hash((self.preference, self.name))
-
-
-
-# Oh god, Record_TXT how I hate thee.
-class Record_TXT(tputil.FancyEqMixin, tputil.FancyStrMixin):
- """
- Freeform text.
-
- @type data: C{list} of C{str}
- @ivar data: Freeform text which makes up this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be cached.
- """
- implements(IEncodable, IRecord)
-
- TYPE = TXT
-
- fancybasename = 'TXT'
- showAttributes = compareAttributes = ('data', 'ttl')
-
- def __init__(self, *data, **kw):
- self.data = list(data)
- # arg man python sucks so bad
- self.ttl = str2time(kw.get('ttl', None))
-
-
- def encode(self, strio, compDict = None):
- for d in self.data:
- strio.write(struct.pack('!B', len(d)) + d)
-
-
- def decode(self, strio, length = None):
- soFar = 0
- self.data = []
- while soFar < length:
- L = struct.unpack('!B', readPrecisely(strio, 1))[0]
- self.data.append(readPrecisely(strio, L))
- soFar += L + 1
- if soFar != length:
- log.msg(
- "Decoded %d bytes in %s record, but rdlength is %d" % (
- soFar, self.fancybasename, length
- )
- )
-
-
- def __hash__(self):
- return hash(tuple(self.data))
-
-
-
-# This is a fallback record
-class UnknownRecord(tputil.FancyEqMixin, tputil.FancyStrMixin, object):
- """
- Encapsulate the wire data for unkown record types so that they can
- pass through the system unchanged.
-
- @type data: C{str}
- @ivar data: Wire data which makes up this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be cached.
-
- @since: 11.1
- """
- implements(IEncodable, IRecord)
-
- fancybasename = 'UNKNOWN'
- compareAttributes = ('data', 'ttl')
- showAttributes = ('data', 'ttl')
-
- def __init__(self, data='', ttl=None):
- self.data = data
- self.ttl = str2time(ttl)
-
-
- def encode(self, strio, compDict=None):
- """
- Write the raw bytes corresponding to this record's payload to the
- stream.
- """
- strio.write(self.data)
-
-
- def decode(self, strio, length=None):
- """
- Load the bytes which are part of this record from the stream and store
- them unparsed and unmodified.
- """
- if length is None:
- raise Exception('must know length for unknown record types')
- self.data = readPrecisely(strio, length)
-
-
- def __hash__(self):
- return hash((self.data, self.ttl))
-
-
-
-class Record_SPF(Record_TXT):
- """
- Structurally, freeform text. Semantically, a policy definition, formatted
- as defined in U{rfc 4408<http://www.faqs.org/rfcs/rfc4408.html>}.
-
- @type data: C{list} of C{str}
- @ivar data: Freeform text which makes up this record.
-
- @type ttl: C{int}
- @ivar ttl: The maximum number of seconds which this record should be cached.
- """
- TYPE = SPF
- fancybasename = 'SPF'
-
-
-
-class Message:
- """
- L{Message} contains all the information represented by a single
- DNS request or response.
- """
- headerFmt = "!H2B4H"
- headerSize = struct.calcsize(headerFmt)
-
- # Question, answer, additional, and nameserver lists
- queries = answers = add = ns = None
-
- def __init__(self, id=0, answer=0, opCode=0, recDes=0, recAv=0,
- auth=0, rCode=OK, trunc=0, maxSize=512):
- self.maxSize = maxSize
- self.id = id
- self.answer = answer
- self.opCode = opCode
- self.auth = auth
- self.trunc = trunc
- self.recDes = recDes
- self.recAv = recAv
- self.rCode = rCode
- self.queries = []
- self.answers = []
- self.authority = []
- self.additional = []
-
-
- def addQuery(self, name, type=ALL_RECORDS, cls=IN):
- """
- Add another query to this Message.
-
- @type name: C{str}
- @param name: The name to query.
-
- @type type: C{int}
- @param type: Query type
-
- @type cls: C{int}
- @param cls: Query class
- """
- self.queries.append(Query(name, type, cls))
-
-
- def encode(self, strio):
- compDict = {}
- body_tmp = StringIO.StringIO()
- for q in self.queries:
- q.encode(body_tmp, compDict)
- for q in self.answers:
- q.encode(body_tmp, compDict)
- for q in self.authority:
- q.encode(body_tmp, compDict)
- for q in self.additional:
- q.encode(body_tmp, compDict)
- body = body_tmp.getvalue()
- size = len(body) + self.headerSize
- if self.maxSize and size > self.maxSize:
- self.trunc = 1
- body = body[:self.maxSize - self.headerSize]
- byte3 = (( ( self.answer & 1 ) << 7 )
- | ((self.opCode & 0xf ) << 3 )
- | ((self.auth & 1 ) << 2 )
- | ((self.trunc & 1 ) << 1 )
- | ( self.recDes & 1 ) )
- byte4 = ( ( (self.recAv & 1 ) << 7 )
- | (self.rCode & 0xf ) )
-
- strio.write(struct.pack(self.headerFmt, self.id, byte3, byte4,
- len(self.queries), len(self.answers),
- len(self.authority), len(self.additional)))
- strio.write(body)
-
-
- def decode(self, strio, length=None):
- self.maxSize = 0
- header = readPrecisely(strio, self.headerSize)
- r = struct.unpack(self.headerFmt, header)
- self.id, byte3, byte4, nqueries, nans, nns, nadd = r
- self.answer = ( byte3 >> 7 ) & 1
- self.opCode = ( byte3 >> 3 ) & 0xf
- self.auth = ( byte3 >> 2 ) & 1
- self.trunc = ( byte3 >> 1 ) & 1
- self.recDes = byte3 & 1
- self.recAv = ( byte4 >> 7 ) & 1
- self.rCode = byte4 & 0xf
-
- self.queries = []
- for i in range(nqueries):
- q = Query()
- try:
- q.decode(strio)
- except EOFError:
- return
- self.queries.append(q)
-
- items = ((self.answers, nans), (self.authority, nns), (self.additional, nadd))
- for (l, n) in items:
- self.parseRecords(l, n, strio)
-
-
- def parseRecords(self, list, num, strio):
- for i in range(num):
- header = RRHeader(auth=self.auth)
- try:
- header.decode(strio)
- except EOFError:
- return
- t = self.lookupRecordType(header.type)
- if not t:
- continue
- header.payload = t(ttl=header.ttl)
- try:
- header.payload.decode(strio, header.rdlength)
- except EOFError:
- return
- list.append(header)
-
-
- # Create a mapping from record types to their corresponding Record_*
- # classes. This relies on the global state which has been created so
- # far in initializing this module (so don't define Record classes after
- # this).
- _recordTypes = {}
- for name in globals():
- if name.startswith('Record_'):
- _recordTypes[globals()[name].TYPE] = globals()[name]
-
- # Clear the iteration variable out of the class namespace so it
- # doesn't become an attribute.
- del name
-
-
- def lookupRecordType(self, type):
- """
- Retrieve the L{IRecord} implementation for the given record type.
-
- @param type: A record type, such as L{A} or L{NS}.
- @type type: C{int}
-
- @return: An object which implements L{IRecord} or C{None} if none
- can be found for the given type.
- @rtype: L{types.ClassType}
- """
- return self._recordTypes.get(type, UnknownRecord)
-
-
- def toStr(self):
- strio = StringIO.StringIO()
- self.encode(strio)
- return strio.getvalue()
-
-
- def fromStr(self, str):
- strio = StringIO.StringIO(str)
- self.decode(strio)
-
-
-
-class DNSMixin(object):
- """
- DNS protocol mixin shared by UDP and TCP implementations.
-
- @ivar _reactor: A L{IReactorTime} and L{IReactorUDP} provider which will
- be used to issue DNS queries and manage request timeouts.
- """
- id = None
- liveMessages = None
-
- def __init__(self, controller, reactor=None):
- self.controller = controller
- self.id = random.randrange(2 ** 10, 2 ** 15)
- if reactor is None:
- from twisted.internet import reactor
- self._reactor = reactor
-
-
- def pickID(self):
- """
- Return a unique ID for queries.
- """
- while True:
- id = randomSource()
- if id not in self.liveMessages:
- return id
-
-
- def callLater(self, period, func, *args):
- """
- Wrapper around reactor.callLater, mainly for test purpose.
- """
- return self._reactor.callLater(period, func, *args)
-
-
- def _query(self, queries, timeout, id, writeMessage):
- """
- Send out a message with the given queries.
-
- @type queries: C{list} of C{Query} instances
- @param queries: The queries to transmit
-
- @type timeout: C{int} or C{float}
- @param timeout: How long to wait before giving up
-
- @type id: C{int}
- @param id: Unique key for this request
-
- @type writeMessage: C{callable}
- @param writeMessage: One-parameter callback which writes the message
-
- @rtype: C{Deferred}
- @return: a C{Deferred} which will be fired with the result of the
- query, or errbacked with any errors that could happen (exceptions
- during writing of the query, timeout errors, ...).
- """
- m = Message(id, recDes=1)
- m.queries = queries
-
- try:
- writeMessage(m)
- except:
- return defer.fail()
-
- resultDeferred = defer.Deferred()
- cancelCall = self.callLater(timeout, self._clearFailed, resultDeferred, id)
- self.liveMessages[id] = (resultDeferred, cancelCall)
-
- return resultDeferred
-
- def _clearFailed(self, deferred, id):
- """
- Clean the Deferred after a timeout.
- """
- try:
- del self.liveMessages[id]
- except KeyError:
- pass
- deferred.errback(failure.Failure(DNSQueryTimeoutError(id)))
-
-
-class DNSDatagramProtocol(DNSMixin, protocol.DatagramProtocol):
- """
- DNS protocol over UDP.
- """
- resends = None
-
- def stopProtocol(self):
- """
- Stop protocol: reset state variables.
- """
- self.liveMessages = {}
- self.resends = {}
- self.transport = None
-
- def startProtocol(self):
- """
- Upon start, reset internal state.
- """
- self.liveMessages = {}
- self.resends = {}
-
- def writeMessage(self, message, address):
- """
- Send a message holding DNS queries.
-
- @type message: L{Message}
- """
- self.transport.write(message.toStr(), address)
-
- def startListening(self):
- self._reactor.listenUDP(0, self, maxPacketSize=512)
-
- def datagramReceived(self, data, addr):
- """
- Read a datagram, extract the message in it and trigger the associated
- Deferred.
- """
- m = Message()
- try:
- m.fromStr(data)
- except EOFError:
- log.msg("Truncated packet (%d bytes) from %s" % (len(data), addr))
- return
- except:
- # Nothing should trigger this, but since we're potentially
- # invoking a lot of different decoding methods, we might as well
- # be extra cautious. Anything that triggers this is itself
- # buggy.
- log.err(failure.Failure(), "Unexpected decoding error")
- return
-
- if m.id in self.liveMessages:
- d, canceller = self.liveMessages[m.id]
- del self.liveMessages[m.id]
- canceller.cancel()
- # XXX we shouldn't need this hack of catching exception on callback()
- try:
- d.callback(m)
- except:
- log.err()
- else:
- if m.id not in self.resends:
- self.controller.messageReceived(m, self, addr)
-
-
- def removeResend(self, id):
- """
- Mark message ID as no longer having duplication suppression.
- """
- try:
- del self.resends[id]
- except KeyError:
- pass
-
- def query(self, address, queries, timeout=10, id=None):
- """
- Send out a message with the given queries.
-
- @type address: C{tuple} of C{str} and C{int}
- @param address: The address to which to send the query
-
- @type queries: C{list} of C{Query} instances
- @param queries: The queries to transmit
-
- @rtype: C{Deferred}
- """
- if not self.transport:
- # XXX transport might not get created automatically, use callLater?
- try:
- self.startListening()
- except CannotListenError:
- return defer.fail()
-
- if id is None:
- id = self.pickID()
- else:
- self.resends[id] = 1
-
- def writeMessage(m):
- self.writeMessage(m, address)
-
- return self._query(queries, timeout, id, writeMessage)
-
-
-class DNSProtocol(DNSMixin, protocol.Protocol):
- """
- DNS protocol over TCP.
- """
- length = None
- buffer = ''
-
- def writeMessage(self, message):
- """
- Send a message holding DNS queries.
-
- @type message: L{Message}
- """
- s = message.toStr()
- self.transport.write(struct.pack('!H', len(s)) + s)
-
- def connectionMade(self):
- """
- Connection is made: reset internal state, and notify the controller.
- """
- self.liveMessages = {}
- self.controller.connectionMade(self)
-
-
- def connectionLost(self, reason):
- """
- Notify the controller that this protocol is no longer
- connected.
- """
- self.controller.connectionLost(self)
-
-
- def dataReceived(self, data):
- self.buffer += data
-
- while self.buffer:
- if self.length is None and len(self.buffer) >= 2:
- self.length = struct.unpack('!H', self.buffer[:2])[0]
- self.buffer = self.buffer[2:]
-
- if len(self.buffer) >= self.length:
- myChunk = self.buffer[:self.length]
- m = Message()
- m.fromStr(myChunk)
-
- try:
- d, canceller = self.liveMessages[m.id]
- except KeyError:
- self.controller.messageReceived(m, self)
- else:
- del self.liveMessages[m.id]
- canceller.cancel()
- # XXX we shouldn't need this hack
- try:
- d.callback(m)
- except:
- log.err()
-
- self.buffer = self.buffer[self.length:]
- self.length = None
- else:
- break
-
-
- def query(self, queries, timeout=60):
- """
- Send out a message with the given queries.
-
- @type queries: C{list} of C{Query} instances
- @param queries: The queries to transmit
-
- @rtype: C{Deferred}
- """
- id = self.pickID()
- return self._query(queries, timeout, id, self.writeMessage)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/error.py
deleted file mode 100755
index 3163cfef..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/error.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- test-case-name: twisted.names.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Exception class definitions for Twisted Names.
-"""
-
-from twisted.internet.defer import TimeoutError
-
-
-class DomainError(ValueError):
- """
- Indicates a lookup failed because there were no records matching the given
- C{name, class, type} triple.
- """
-
-
-
-class AuthoritativeDomainError(ValueError):
- """
- Indicates a lookup failed for a name for which this server is authoritative
- because there were no records matching the given C{name, class, type}
- triple.
- """
-
-
-
-class DNSQueryTimeoutError(TimeoutError):
- """
- Indicates a lookup failed due to a timeout.
-
- @ivar id: The id of the message which timed out.
- """
- def __init__(self, id):
- TimeoutError.__init__(self)
- self.id = id
-
-
-
-class DNSFormatError(DomainError):
- """
- Indicates a query failed with a result of L{twisted.names.dns.EFORMAT}.
- """
-
-
-
-class DNSServerError(DomainError):
- """
- Indicates a query failed with a result of L{twisted.names.dns.ESERVER}.
- """
-
-
-
-class DNSNameError(DomainError):
- """
- Indicates a query failed with a result of L{twisted.names.dns.ENAME}.
- """
-
-
-
-class DNSNotImplementedError(DomainError):
- """
- Indicates a query failed with a result of L{twisted.names.dns.ENOTIMP}.
- """
-
-
-
-class DNSQueryRefusedError(DomainError):
- """
- Indicates a query failed with a result of L{twisted.names.dns.EREFUSED}.
- """
-
-
-
-class DNSUnknownError(DomainError):
- """
- Indicates a query failed with an unknown result.
- """
-
-
-
-class ResolverError(Exception):
- """
- Indicates a query failed because of a decision made by the local
- resolver object.
- """
-
-
-__all__ = [
- 'DomainError', 'AuthoritativeDomainError', 'DNSQueryTimeoutError',
-
- 'DNSFormatError', 'DNSServerError', 'DNSNameError',
- 'DNSNotImplementedError', 'DNSQueryRefusedError',
- 'DNSUnknownError', 'ResolverError']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/hosts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/hosts.py
deleted file mode 100755
index fd2cd5eb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/hosts.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_hosts -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-hosts(5) support.
-"""
-
-from twisted.names import dns
-from twisted.persisted import styles
-from twisted.python import failure
-from twisted.python.filepath import FilePath
-from twisted.internet import defer
-from twisted.internet.abstract import isIPAddress
-
-from twisted.names import common
-
-def searchFileForAll(hostsFile, name):
- """
- Search the given file, which is in hosts(5) standard format, for an address
- entry with a given name.
-
- @param hostsFile: The name of the hosts(5)-format file to search.
- @type hostsFile: L{FilePath}
-
- @param name: The name to search for.
- @type name: C{str}
-
- @return: C{None} if the name is not found in the file, otherwise a
- C{str} giving the address in the file associated with the name.
- """
- results = []
- try:
- lines = hostsFile.getContent().splitlines()
- except:
- return results
-
- name = name.lower()
- for line in lines:
- idx = line.find('#')
- if idx != -1:
- line = line[:idx]
- if not line:
- continue
- parts = line.split()
-
- if name.lower() in [s.lower() for s in parts[1:]]:
- results.append(parts[0])
- return results
-
-
-
-def searchFileFor(file, name):
- """
- Grep given file, which is in hosts(5) standard format, for an address
- entry with a given name.
-
- @param file: The name of the hosts(5)-format file to search.
-
- @param name: The name to search for.
- @type name: C{str}
-
- @return: C{None} if the name is not found in the file, otherwise a
- C{str} giving the address in the file associated with the name.
- """
- addresses = searchFileForAll(FilePath(file), name)
- if addresses:
- return addresses[0]
- return None
-
-
-
-class Resolver(common.ResolverBase, styles.Versioned):
- """
- A resolver that services hosts(5) format files.
- """
-
- persistenceVersion = 1
-
- def upgradeToVersion1(self):
- # <3 exarkun
- self.typeToMethod = {}
- for (k, v) in common.typeToMethod.items():
- self.typeToMethod[k] = getattr(self, v)
-
-
- def __init__(self, file='/etc/hosts', ttl = 60 * 60):
- common.ResolverBase.__init__(self)
- self.file = file
- self.ttl = ttl
-
-
- def _aRecords(self, name):
- """
- Return a tuple of L{dns.RRHeader} instances for all of the IPv4
- addresses in the hosts file.
- """
- return tuple([
- dns.RRHeader(name, dns.A, dns.IN, self.ttl,
- dns.Record_A(addr, self.ttl))
- for addr
- in searchFileForAll(FilePath(self.file), name)
- if isIPAddress(addr)])
-
-
- def _aaaaRecords(self, name):
- """
- Return a tuple of L{dns.RRHeader} instances for all of the IPv6
- addresses in the hosts file.
- """
- return tuple([
- dns.RRHeader(name, dns.AAAA, dns.IN, self.ttl,
- dns.Record_AAAA(addr, self.ttl))
- for addr
- in searchFileForAll(FilePath(self.file), name)
- if not isIPAddress(addr)])
-
-
- def _respond(self, name, records):
- """
- Generate a response for the given name containing the given result
- records, or a failure if there are no result records.
-
- @param name: The DNS name the response is for.
- @type name: C{str}
-
- @param records: A tuple of L{dns.RRHeader} instances giving the results
- that will go into the response.
-
- @return: A L{Deferred} which will fire with a three-tuple of result
- records, authority records, and additional records, or which will
- fail with L{dns.DomainError} if there are no result records.
- """
- if records:
- return defer.succeed((records, (), ()))
- return defer.fail(failure.Failure(dns.DomainError(name)))
-
-
- def lookupAddress(self, name, timeout=None):
- """
- Read any IPv4 addresses from C{self.file} and return them as L{Record_A}
- instances.
- """
- return self._respond(name, self._aRecords(name))
-
-
- def lookupIPV6Address(self, name, timeout=None):
- """
- Read any IPv4 addresses from C{self.file} and return them as L{Record_A}
- instances.
- """
- return self._respond(name, self._aaaaRecords(name))
-
- # Someday this should include IPv6 addresses too, but that will cause
- # problems if users of the API (mainly via getHostByName) aren't updated to
- # know about IPv6 first.
- lookupAllRecords = lookupAddress
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/resolve.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/resolve.py
deleted file mode 100755
index 19996e93..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/resolve.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Lookup a name using multiple resolvers.
-
-Future Plans: This needs someway to specify which resolver answered
-the query, or someway to specify (authority|ttl|cache behavior|more?)
-
-@author: Jp Calderone
-"""
-
-from twisted.internet import defer, interfaces
-from twisted.names import dns
-from zope.interface import implements
-import common
-
-class FailureHandler:
- def __init__(self, resolver, query, timeout):
- self.resolver = resolver
- self.query = query
- self.timeout = timeout
-
-
- def __call__(self, failure):
- # AuthoritativeDomainErrors should halt resolution attempts
- failure.trap(dns.DomainError, defer.TimeoutError, NotImplementedError)
- return self.resolver(self.query, self.timeout)
-
-
-class ResolverChain(common.ResolverBase):
- """Lookup an address using multiple C{IResolver}s"""
-
- implements(interfaces.IResolver)
-
-
- def __init__(self, resolvers):
- common.ResolverBase.__init__(self)
- self.resolvers = resolvers
-
-
- def _lookup(self, name, cls, type, timeout):
- q = dns.Query(name, type, cls)
- d = self.resolvers[0].query(q, timeout)
- for r in self.resolvers[1:]:
- d = d.addErrback(
- FailureHandler(r.query, q, timeout)
- )
- return d
-
-
- def lookupAllRecords(self, name, timeout = None):
- d = self.resolvers[0].lookupAllRecords(name, timeout)
- for r in self.resolvers[1:]:
- d = d.addErrback(
- FailureHandler(r.lookupAllRecords, name, timeout)
- )
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/root.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/root.py
deleted file mode 100755
index 18908e7f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/root.py
+++ /dev/null
@@ -1,446 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_rootresolve -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Resolver implementation for querying successive authoritative servers to
-lookup a record, starting from the root nameservers.
-
-@author: Jp Calderone
-
-todo::
- robustify it
- documentation
-"""
-
-import warnings
-
-from twisted.python.failure import Failure
-from twisted.internet import defer
-from twisted.names import dns, common, error
-
-
-def retry(t, p, *args):
- """
- Issue a query one or more times.
-
- This function is deprecated. Use one of the resolver classes for retry
- logic, or implement it yourself.
- """
- warnings.warn(
- "twisted.names.root.retry is deprecated since Twisted 10.0. Use a "
- "Resolver object for retry logic.", category=DeprecationWarning,
- stacklevel=2)
-
- assert t, "Timeout is required"
- t = list(t)
- def errback(failure):
- failure.trap(defer.TimeoutError)
- if not t:
- return failure
- return p.query(timeout=t.pop(0), *args
- ).addErrback(errback
- )
- return p.query(timeout=t.pop(0), *args
- ).addErrback(errback
- )
-
-
-
-class _DummyController:
- """
- A do-nothing DNS controller. This is useful when all messages received
- will be responses to previously issued queries. Anything else received
- will be ignored.
- """
- def messageReceived(self, *args):
- pass
-
-
-
-class Resolver(common.ResolverBase):
- """
- L{Resolver} implements recursive lookup starting from a specified list of
- root servers.
-
- @ivar hints: A C{list} of C{str} giving the dotted quad representation
- of IP addresses of root servers at which to begin resolving names.
-
- @ivar _maximumQueries: A C{int} giving the maximum number of queries
- which will be attempted to resolve a single name.
-
- @ivar _reactor: A L{IReactorTime} and L{IReactorUDP} provider to use to
- bind UDP ports and manage timeouts.
- """
- def __init__(self, hints, maximumQueries=10, reactor=None):
- common.ResolverBase.__init__(self)
- self.hints = hints
- self._maximumQueries = maximumQueries
- self._reactor = reactor
-
-
- def _roots(self):
- """
- Return a list of two-tuples representing the addresses of the root
- servers, as defined by C{self.hints}.
- """
- return [(ip, dns.PORT) for ip in self.hints]
-
-
- def _query(self, query, servers, timeout, filter):
- """
- Issue one query and return a L{Deferred} which fires with its response.
-
- @param query: The query to issue.
- @type query: L{dns.Query}
-
- @param servers: The servers which might have an answer for this
- query.
- @type servers: L{list} of L{tuple} of L{str} and L{int}
-
- @param timeout: A timeout on how long to wait for the response.
- @type timeout: L{tuple} of L{int}
-
- @param filter: A flag indicating whether to filter the results. If
- C{True}, the returned L{Deferred} will fire with a three-tuple of
- lists of L{RRHeaders} (like the return value of the I{lookup*}
- methods of L{IResolver}. IF C{False}, the result will be a
- L{Message} instance.
- @type filter: L{bool}
-
- @return: A L{Deferred} which fires with the response or a timeout
- error.
- @rtype: L{Deferred}
- """
- from twisted.names import client
- r = client.Resolver(servers=servers, reactor=self._reactor)
- d = r.queryUDP([query], timeout)
- if filter:
- d.addCallback(r.filterAnswers)
- return d
-
-
- def _lookup(self, name, cls, type, timeout):
- """
- Implement name lookup by recursively discovering the authoritative
- server for the name and then asking it, starting at one of the servers
- in C{self.hints}.
- """
- if timeout is None:
- # A series of timeouts for semi-exponential backoff, summing to an
- # arbitrary total of 60 seconds.
- timeout = (1, 3, 11, 45)
- return self._discoverAuthority(
- dns.Query(name, type, cls), self._roots(), timeout,
- self._maximumQueries)
-
-
- def _discoverAuthority(self, query, servers, timeout, queriesLeft):
- """
- Issue a query to a server and follow a delegation if necessary.
-
- @param query: The query to issue.
- @type query: L{dns.Query}
-
- @param servers: The servers which might have an answer for this
- query.
- @type servers: L{list} of L{tuple} of L{str} and L{int}
-
- @param timeout: A C{tuple} of C{int} giving the timeout to use for this
- query.
-
- @param queriesLeft: A C{int} giving the number of queries which may
- yet be attempted to answer this query before the attempt will be
- abandoned.
-
- @return: A L{Deferred} which fires with a three-tuple of lists of
- L{RRHeaders} giving the response, or with a L{Failure} if there is
- a timeout or response error.
- """
- # Stop now if we've hit the query limit.
- if queriesLeft <= 0:
- return Failure(
- error.ResolverError("Query limit reached without result"))
-
- d = self._query(query, servers, timeout, False)
- d.addCallback(
- self._discoveredAuthority, query, timeout, queriesLeft - 1)
- return d
-
-
- def _discoveredAuthority(self, response, query, timeout, queriesLeft):
- """
- Interpret the response to a query, checking for error codes and
- following delegations if necessary.
-
- @param response: The L{Message} received in response to issuing C{query}.
- @type response: L{Message}
-
- @param query: The L{dns.Query} which was issued.
- @type query: L{dns.Query}.
-
- @param timeout: The timeout to use if another query is indicated by
- this response.
- @type timeout: L{tuple} of L{int}
-
- @param queriesLeft: A C{int} giving the number of queries which may
- yet be attempted to answer this query before the attempt will be
- abandoned.
-
- @return: A L{Failure} indicating a response error, a three-tuple of
- lists of L{RRHeaders} giving the response to C{query} or a
- L{Deferred} which will fire with one of those.
- """
- if response.rCode != dns.OK:
- return Failure(self.exceptionForCode(response.rCode)(response))
-
- # Turn the answers into a structure that's a little easier to work with.
- records = {}
- for answer in response.answers:
- records.setdefault(answer.name, []).append(answer)
-
- def findAnswerOrCName(name, type, cls):
- cname = None
- for record in records.get(name, []):
- if record.cls == cls:
- if record.type == type:
- return record
- elif record.type == dns.CNAME:
- cname = record
- # If there were any CNAME records, return the last one. There's
- # only supposed to be zero or one, though.
- return cname
-
- seen = set()
- name = query.name
- record = None
- while True:
- seen.add(name)
- previous = record
- record = findAnswerOrCName(name, query.type, query.cls)
- if record is None:
- if name == query.name:
- # If there's no answer for the original name, then this may
- # be a delegation. Code below handles it.
- break
- else:
- # Try to resolve the CNAME with another query.
- d = self._discoverAuthority(
- dns.Query(str(name), query.type, query.cls),
- self._roots(), timeout, queriesLeft)
- # We also want to include the CNAME in the ultimate result,
- # otherwise this will be pretty confusing.
- def cbResolved((answers, authority, additional)):
- answers.insert(0, previous)
- return (answers, authority, additional)
- d.addCallback(cbResolved)
- return d
- elif record.type == query.type:
- return (
- response.answers,
- response.authority,
- response.additional)
- else:
- # It's a CNAME record. Try to resolve it from the records
- # in this response with another iteration around the loop.
- if record.payload.name in seen:
- raise error.ResolverError("Cycle in CNAME processing")
- name = record.payload.name
-
-
- # Build a map to use to convert NS names into IP addresses.
- addresses = {}
- for rr in response.additional:
- if rr.type == dns.A:
- addresses[str(rr.name)] = rr.payload.dottedQuad()
-
- hints = []
- traps = []
- for rr in response.authority:
- if rr.type == dns.NS:
- ns = str(rr.payload.name)
- if ns in addresses:
- hints.append((addresses[ns], dns.PORT))
- else:
- traps.append(ns)
- if hints:
- return self._discoverAuthority(
- query, hints, timeout, queriesLeft)
- elif traps:
- d = self.lookupAddress(traps[0], timeout)
- d.addCallback(
- lambda (answers, authority, additional):
- answers[0].payload.dottedQuad())
- d.addCallback(
- lambda hint: self._discoverAuthority(
- query, [(hint, dns.PORT)], timeout, queriesLeft - 1))
- return d
- else:
- return Failure(error.ResolverError(
- "Stuck at response without answers or delegation"))
-
-
- def discoveredAuthority(self, auth, name, cls, type, timeout):
- warnings.warn(
- 'twisted.names.root.Resolver.discoveredAuthority is deprecated since '
- 'Twisted 10.0. Use twisted.names.client.Resolver directly, instead.',
- category=DeprecationWarning, stacklevel=2)
- from twisted.names import client
- q = dns.Query(name, type, cls)
- r = client.Resolver(servers=[(auth, dns.PORT)])
- d = r.queryUDP([q], timeout)
- d.addCallback(r.filterAnswers)
- return d
-
-
-
-def lookupNameservers(host, atServer, p=None):
- warnings.warn(
- 'twisted.names.root.lookupNameservers is deprecated since Twisted '
- '10.0. Use twisted.names.root.Resolver.lookupNameservers instead.',
- category=DeprecationWarning, stacklevel=2)
- # print 'Nameserver lookup for', host, 'at', atServer, 'with', p
- if p is None:
- p = dns.DNSDatagramProtocol(_DummyController())
- p.noisy = False
- return retry(
- (1, 3, 11, 45), # Timeouts
- p, # Protocol instance
- (atServer, dns.PORT), # Server to query
- [dns.Query(host, dns.NS, dns.IN)] # Question to ask
- )
-
-def lookupAddress(host, atServer, p=None):
- warnings.warn(
- 'twisted.names.root.lookupAddress is deprecated since Twisted '
- '10.0. Use twisted.names.root.Resolver.lookupAddress instead.',
- category=DeprecationWarning, stacklevel=2)
- # print 'Address lookup for', host, 'at', atServer, 'with', p
- if p is None:
- p = dns.DNSDatagramProtocol(_DummyController())
- p.noisy = False
- return retry(
- (1, 3, 11, 45), # Timeouts
- p, # Protocol instance
- (atServer, dns.PORT), # Server to query
- [dns.Query(host, dns.A, dns.IN)] # Question to ask
- )
-
-def extractAuthority(msg, cache):
- warnings.warn(
- 'twisted.names.root.extractAuthority is deprecated since Twisted '
- '10.0. Please inspect the Message object directly.',
- category=DeprecationWarning, stacklevel=2)
- records = msg.answers + msg.authority + msg.additional
- nameservers = [r for r in records if r.type == dns.NS]
-
- # print 'Records for', soFar, ':', records
- # print 'NS for', soFar, ':', nameservers
-
- if not nameservers:
- return None, nameservers
- if not records:
- raise IOError("No records")
- for r in records:
- if r.type == dns.A:
- cache[str(r.name)] = r.payload.dottedQuad()
- for r in records:
- if r.type == dns.NS:
- if str(r.payload.name) in cache:
- return cache[str(r.payload.name)], nameservers
- for addr in records:
- if addr.type == dns.A and addr.name == r.name:
- return addr.payload.dottedQuad(), nameservers
- return None, nameservers
-
-def discoverAuthority(host, roots, cache=None, p=None):
- warnings.warn(
- 'twisted.names.root.discoverAuthority is deprecated since Twisted '
- '10.0. Use twisted.names.root.Resolver.lookupNameservers instead.',
- category=DeprecationWarning, stacklevel=4)
-
- if cache is None:
- cache = {}
-
- rootAuths = list(roots)
-
- parts = host.rstrip('.').split('.')
- parts.reverse()
-
- authority = rootAuths.pop()
-
- soFar = ''
- for part in parts:
- soFar = part + '.' + soFar
- # print '///////', soFar, authority, p
- msg = defer.waitForDeferred(lookupNameservers(soFar, authority, p))
- yield msg
- msg = msg.getResult()
-
- newAuth, nameservers = extractAuthority(msg, cache)
-
- if newAuth is not None:
- # print "newAuth is not None"
- authority = newAuth
- else:
- if nameservers:
- r = str(nameservers[0].payload.name)
- # print 'Recursively discovering authority for', r
- authority = defer.waitForDeferred(discoverAuthority(r, roots, cache, p))
- yield authority
- authority = authority.getResult()
- # print 'Discovered to be', authority, 'for', r
-## else:
-## # print 'Doing address lookup for', soFar, 'at', authority
-## msg = defer.waitForDeferred(lookupAddress(soFar, authority, p))
-## yield msg
-## msg = msg.getResult()
-## records = msg.answers + msg.authority + msg.additional
-## addresses = [r for r in records if r.type == dns.A]
-## if addresses:
-## authority = addresses[0].payload.dottedQuad()
-## else:
-## raise IOError("Resolution error")
- # print "Yielding authority", authority
- yield authority
-
-discoverAuthority = defer.deferredGenerator(discoverAuthority)
-
-def makePlaceholder(deferred, name):
- def placeholder(*args, **kw):
- deferred.addCallback(lambda r: getattr(r, name)(*args, **kw))
- return deferred
- return placeholder
-
-class DeferredResolver:
- def __init__(self, resolverDeferred):
- self.waiting = []
- resolverDeferred.addCallback(self.gotRealResolver)
-
- def gotRealResolver(self, resolver):
- w = self.waiting
- self.__dict__ = resolver.__dict__
- self.__class__ = resolver.__class__
- for d in w:
- d.callback(resolver)
-
- def __getattr__(self, name):
- if name.startswith('lookup') or name in ('getHostByName', 'query'):
- self.waiting.append(defer.Deferred())
- return makePlaceholder(self.waiting[-1], name)
- raise AttributeError(name)
-
-def bootstrap(resolver):
- """Lookup the root nameserver addresses using the given resolver
-
- Return a Resolver which will eventually become a C{root.Resolver}
- instance that has references to all the root servers that we were able
- to look up.
- """
- domains = [chr(ord('a') + i) for i in range(13)]
- # f = lambda r: (log.msg('Root server address: ' + str(r)), r)[1]
- f = lambda r: r
- L = [resolver.getHostByName('%s.root-servers.net' % d).addCallback(f) for d in domains]
- d = defer.DeferredList(L)
- d.addCallback(lambda r: Resolver([e[1] for e in r if e[0]]))
- return DeferredResolver(d)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/secondary.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/secondary.py
deleted file mode 100755
index c7c098c6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/secondary.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_names -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-__all__ = ['SecondaryAuthority', 'SecondaryAuthorityService']
-
-from twisted.internet import task, defer
-from twisted.names import dns
-from twisted.names import common
-from twisted.names import client
-from twisted.names import resolve
-from twisted.names.authority import FileAuthority
-
-from twisted.python import log, failure
-from twisted.application import service
-
-class SecondaryAuthorityService(service.Service):
- calls = None
-
- _port = 53
-
- def __init__(self, primary, domains):
- """
- @param primary: The IP address of the server from which to perform
- zone transfers.
-
- @param domains: A sequence of domain names for which to perform
- zone transfers.
- """
- self.primary = primary
- self.domains = [SecondaryAuthority(primary, d) for d in domains]
-
-
- @classmethod
- def fromServerAddressAndDomains(cls, serverAddress, domains):
- """
- Construct a new L{SecondaryAuthorityService} from a tuple giving a
- server address and a C{str} giving the name of a domain for which this
- is an authority.
-
- @param serverAddress: A two-tuple, the first element of which is a
- C{str} giving an IP address and the second element of which is a
- C{int} giving a port number. Together, these define where zone
- transfers will be attempted from.
-
- @param domain: A C{str} giving the domain to transfer.
-
- @return: A new instance of L{SecondaryAuthorityService}.
- """
- service = cls(None, [])
- service.primary = serverAddress[0]
- service._port = serverAddress[1]
- service.domains = [
- SecondaryAuthority.fromServerAddressAndDomain(serverAddress, d)
- for d in domains]
- return service
-
-
- def getAuthority(self):
- return resolve.ResolverChain(self.domains)
-
- def startService(self):
- service.Service.startService(self)
- self.calls = [task.LoopingCall(d.transfer) for d in self.domains]
- i = 0
- from twisted.internet import reactor
- for c in self.calls:
- # XXX Add errbacks, respect proper timeouts
- reactor.callLater(i, c.start, 60 * 60)
- i += 1
-
- def stopService(self):
- service.Service.stopService(self)
- for c in self.calls:
- c.stop()
-
-
-
-class SecondaryAuthority(common.ResolverBase):
- """
- An Authority that keeps itself updated by performing zone transfers.
-
- @ivar primary: The IP address of the server from which zone transfers will
- be attempted.
- @type primary: C{str}
-
- @ivar _port: The port number of the server from which zone transfers will be
- attempted.
- @type: C{int}
-
- @ivar _reactor: The reactor to use to perform the zone transfers, or C{None}
- to use the global reactor.
- """
-
- transferring = False
- soa = records = None
- _port = 53
- _reactor = None
-
- def __init__(self, primaryIP, domain):
- common.ResolverBase.__init__(self)
- self.primary = primaryIP
- self.domain = domain
-
-
- @classmethod
- def fromServerAddressAndDomain(cls, serverAddress, domain):
- """
- Construct a new L{SecondaryAuthority} from a tuple giving a server
- address and a C{str} giving the name of a domain for which this is an
- authority.
-
- @param serverAddress: A two-tuple, the first element of which is a
- C{str} giving an IP address and the second element of which is a
- C{int} giving a port number. Together, these define where zone
- transfers will be attempted from.
-
- @param domain: A C{str} giving the domain to transfer.
-
- @return: A new instance of L{SecondaryAuthority}.
- """
- secondary = cls(None, None)
- secondary.primary = serverAddress[0]
- secondary._port = serverAddress[1]
- secondary.domain = domain
- return secondary
-
-
- def transfer(self):
- if self.transferring:
- return
- self.transfering = True
-
- reactor = self._reactor
- if reactor is None:
- from twisted.internet import reactor
-
- resolver = client.Resolver(
- servers=[(self.primary, self._port)], reactor=reactor)
- return resolver.lookupZone(self.domain
- ).addCallback(self._cbZone
- ).addErrback(self._ebZone
- )
-
-
- def _lookup(self, name, cls, type, timeout=None):
- if not self.soa or not self.records:
- return defer.fail(failure.Failure(dns.DomainError(name)))
-
-
- return FileAuthority.__dict__['_lookup'](self, name, cls, type, timeout)
-
- #shouldn't we just subclass? :P
-
- lookupZone = FileAuthority.__dict__['lookupZone']
-
- def _cbZone(self, zone):
- ans, _, _ = zone
- self.records = r = {}
- for rec in ans:
- if not self.soa and rec.type == dns.SOA:
- self.soa = (str(rec.name).lower(), rec.payload)
- else:
- r.setdefault(str(rec.name).lower(), []).append(rec.payload)
-
- def _ebZone(self, failure):
- log.msg("Updating %s from %s failed during zone transfer" % (self.domain, self.primary))
- log.err(failure)
-
- def update(self):
- self.transfer().addCallbacks(self._cbTransferred, self._ebTransferred)
-
- def _cbTransferred(self, result):
- self.transferring = False
-
- def _ebTransferred(self, failure):
- self.transferred = False
- log.msg("Transferring %s from %s failed after zone transfer" % (self.domain, self.primary))
- log.err(failure)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/server.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/server.py
deleted file mode 100755
index 0da6acd5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/server.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_names -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Async DNS server
-
-Future plans:
- - Better config file format maybe
- - Make sure to differentiate between different classes
- - notice truncation bit
-
-Important: No additional processing is done on some of the record types.
-This violates the most basic RFC and is just plain annoying
-for resolvers to deal with. Fix it.
-
-@author: Jp Calderone
-"""
-
-import time
-
-from twisted.internet import protocol
-from twisted.names import dns, resolve
-from twisted.python import log
-
-
-class DNSServerFactory(protocol.ServerFactory):
- """
- Server factory and tracker for L{DNSProtocol} connections. This
- class also provides records for responses to DNS queries.
-
- @ivar connections: A list of all the connected L{DNSProtocol}
- instances using this object as their controller.
- @type connections: C{list} of L{DNSProtocol}
- """
-
- protocol = dns.DNSProtocol
- cache = None
-
- def __init__(self, authorities = None, caches = None, clients = None, verbose = 0):
- resolvers = []
- if authorities is not None:
- resolvers.extend(authorities)
- if caches is not None:
- resolvers.extend(caches)
- if clients is not None:
- resolvers.extend(clients)
-
- self.canRecurse = not not clients
- self.resolver = resolve.ResolverChain(resolvers)
- self.verbose = verbose
- if caches:
- self.cache = caches[-1]
- self.connections = []
-
-
- def buildProtocol(self, addr):
- p = self.protocol(self)
- p.factory = self
- return p
-
-
- def connectionMade(self, protocol):
- """
- Track a newly connected L{DNSProtocol}.
- """
- self.connections.append(protocol)
-
-
- def connectionLost(self, protocol):
- """
- Stop tracking a no-longer connected L{DNSProtocol}.
- """
- self.connections.remove(protocol)
-
-
- def sendReply(self, protocol, message, address):
- if self.verbose > 1:
- s = ' '.join([str(a.payload) for a in message.answers])
- auth = ' '.join([str(a.payload) for a in message.authority])
- add = ' '.join([str(a.payload) for a in message.additional])
- if not s:
- log.msg("Replying with no answers")
- else:
- log.msg("Answers are " + s)
- log.msg("Authority is " + auth)
- log.msg("Additional is " + add)
-
- if address is None:
- protocol.writeMessage(message)
- else:
- protocol.writeMessage(message, address)
-
- if self.verbose > 1:
- log.msg("Processed query in %0.3f seconds" % (time.time() - message.timeReceived))
-
-
- def gotResolverResponse(self, (ans, auth, add), protocol, message, address):
- message.rCode = dns.OK
- message.answers = ans
- for x in ans:
- if x.isAuthoritative():
- message.auth = 1
- break
- message.authority = auth
- message.additional = add
- self.sendReply(protocol, message, address)
-
- l = len(ans) + len(auth) + len(add)
- if self.verbose:
- log.msg("Lookup found %d record%s" % (l, l != 1 and "s" or ""))
-
- if self.cache and l:
- self.cache.cacheResult(
- message.queries[0], (ans, auth, add)
- )
-
-
- def gotResolverError(self, failure, protocol, message, address):
- if failure.check(dns.DomainError, dns.AuthoritativeDomainError):
- message.rCode = dns.ENAME
- else:
- message.rCode = dns.ESERVER
- log.err(failure)
-
- self.sendReply(protocol, message, address)
- if self.verbose:
- log.msg("Lookup failed")
-
-
- def handleQuery(self, message, protocol, address):
- # Discard all but the first query! HOO-AAH HOOOOO-AAAAH
- # (no other servers implement multi-query messages, so we won't either)
- query = message.queries[0]
-
- return self.resolver.query(query).addCallback(
- self.gotResolverResponse, protocol, message, address
- ).addErrback(
- self.gotResolverError, protocol, message, address
- )
-
-
- def handleInverseQuery(self, message, protocol, address):
- message.rCode = dns.ENOTIMP
- self.sendReply(protocol, message, address)
- if self.verbose:
- log.msg("Inverse query from %r" % (address,))
-
-
- def handleStatus(self, message, protocol, address):
- message.rCode = dns.ENOTIMP
- self.sendReply(protocol, message, address)
- if self.verbose:
- log.msg("Status request from %r" % (address,))
-
-
- def handleNotify(self, message, protocol, address):
- message.rCode = dns.ENOTIMP
- self.sendReply(protocol, message, address)
- if self.verbose:
- log.msg("Notify message from %r" % (address,))
-
-
- def handleOther(self, message, protocol, address):
- message.rCode = dns.ENOTIMP
- self.sendReply(protocol, message, address)
- if self.verbose:
- log.msg("Unknown op code (%d) from %r" % (message.opCode, address))
-
-
- def messageReceived(self, message, proto, address = None):
- message.timeReceived = time.time()
-
- if self.verbose:
- if self.verbose > 1:
- s = ' '.join([str(q) for q in message.queries])
- elif self.verbose > 0:
- s = ' '.join([dns.QUERY_TYPES.get(q.type, 'UNKNOWN') for q in message.queries])
-
- if not len(s):
- log.msg("Empty query from %r" % ((address or proto.transport.getPeer()),))
- else:
- log.msg("%s query from %r" % (s, address or proto.transport.getPeer()))
-
- message.recAv = self.canRecurse
- message.answer = 1
-
- if not self.allowQuery(message, proto, address):
- message.rCode = dns.EREFUSED
- self.sendReply(proto, message, address)
- elif message.opCode == dns.OP_QUERY:
- self.handleQuery(message, proto, address)
- elif message.opCode == dns.OP_INVERSE:
- self.handleInverseQuery(message, proto, address)
- elif message.opCode == dns.OP_STATUS:
- self.handleStatus(message, proto, address)
- elif message.opCode == dns.OP_NOTIFY:
- self.handleNotify(message, proto, address)
- else:
- self.handleOther(message, proto, address)
-
-
- def allowQuery(self, message, protocol, address):
- # Allow anything but empty queries
- return len(message.queries)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/srvconnect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/srvconnect.py
deleted file mode 100755
index 34434db6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/srvconnect.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_srvconnect -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import random
-
-from zope.interface import implements
-
-from twisted.internet import error, interfaces
-
-from twisted.names import client, dns
-from twisted.names.error import DNSNameError
-from twisted.python.compat import reduce
-
-class _SRVConnector_ClientFactoryWrapper:
- def __init__(self, connector, wrappedFactory):
- self.__connector = connector
- self.__wrappedFactory = wrappedFactory
-
- def startedConnecting(self, connector):
- self.__wrappedFactory.startedConnecting(self.__connector)
-
- def clientConnectionFailed(self, connector, reason):
- self.__connector.connectionFailed(reason)
-
- def clientConnectionLost(self, connector, reason):
- self.__connector.connectionLost(reason)
-
- def __getattr__(self, key):
- return getattr(self.__wrappedFactory, key)
-
-class SRVConnector:
- """A connector that looks up DNS SRV records. See RFC2782."""
-
- implements(interfaces.IConnector)
-
- stopAfterDNS=0
-
- def __init__(self, reactor, service, domain, factory,
- protocol='tcp', connectFuncName='connectTCP',
- connectFuncArgs=(),
- connectFuncKwArgs={},
- defaultPort=None,
- ):
- """
- @ivar defaultPort: Optional default port number to be used when SRV
- lookup fails and the service name is unknown. This should be the
- port number associated with the service name as defined by the IANA
- registry.
- @type defaultPort: C{int}
- """
- self.reactor = reactor
- self.service = service
- self.domain = domain
- self.factory = factory
-
- self.protocol = protocol
- self.connectFuncName = connectFuncName
- self.connectFuncArgs = connectFuncArgs
- self.connectFuncKwArgs = connectFuncKwArgs
- self._defaultPort = defaultPort
-
- self.connector = None
- self.servers = None
- self.orderedServers = None # list of servers already used in this round
-
- def connect(self):
- """Start connection to remote server."""
- self.factory.doStart()
- self.factory.startedConnecting(self)
-
- if not self.servers:
- if self.domain is None:
- self.connectionFailed(error.DNSLookupError("Domain is not defined."))
- return
- d = client.lookupService('_%s._%s.%s' % (self.service,
- self.protocol,
- self.domain))
- d.addCallbacks(self._cbGotServers, self._ebGotServers)
- d.addCallback(lambda x, self=self: self._reallyConnect())
- if self._defaultPort:
- d.addErrback(self._ebServiceUnknown)
- d.addErrback(self.connectionFailed)
- elif self.connector is None:
- self._reallyConnect()
- else:
- self.connector.connect()
-
- def _ebGotServers(self, failure):
- failure.trap(DNSNameError)
-
- # Some DNS servers reply with NXDOMAIN when in fact there are
- # just no SRV records for that domain. Act as if we just got an
- # empty response and use fallback.
-
- self.servers = []
- self.orderedServers = []
-
- def _cbGotServers(self, (answers, auth, add)):
- if len(answers) == 1 and answers[0].type == dns.SRV \
- and answers[0].payload \
- and answers[0].payload.target == dns.Name('.'):
- # decidedly not available
- raise error.DNSLookupError("Service %s not available for domain %s."
- % (repr(self.service), repr(self.domain)))
-
- self.servers = []
- self.orderedServers = []
- for a in answers:
- if a.type != dns.SRV or not a.payload:
- continue
-
- self.orderedServers.append((a.payload.priority, a.payload.weight,
- str(a.payload.target), a.payload.port))
-
- def _ebServiceUnknown(self, failure):
- """
- Connect to the default port when the service name is unknown.
-
- If no SRV records were found, the service name will be passed as the
- port. If resolving the name fails with
- L{error.ServiceNameUnknownError}, a final attempt is done using the
- default port.
- """
- failure.trap(error.ServiceNameUnknownError)
- self.servers = [(0, 0, self.domain, self._defaultPort)]
- self.orderedServers = []
- self.connect()
-
- def _serverCmp(self, a, b):
- if a[0]!=b[0]:
- return cmp(a[0], b[0])
- else:
- return cmp(a[1], b[1])
-
- def pickServer(self):
- assert self.servers is not None
- assert self.orderedServers is not None
-
- if not self.servers and not self.orderedServers:
- # no SRV record, fall back..
- return self.domain, self.service
-
- if not self.servers and self.orderedServers:
- # start new round
- self.servers = self.orderedServers
- self.orderedServers = []
-
- assert self.servers
-
- self.servers.sort(self._serverCmp)
- minPriority=self.servers[0][0]
-
- weightIndex = zip(xrange(len(self.servers)), [x[1] for x in self.servers
- if x[0]==minPriority])
- weightSum = reduce(lambda x, y: (None, x[1]+y[1]), weightIndex, (None, 0))[1]
- rand = random.randint(0, weightSum)
-
- for index, weight in weightIndex:
- weightSum -= weight
- if weightSum <= 0:
- chosen = self.servers[index]
- del self.servers[index]
- self.orderedServers.append(chosen)
-
- p, w, host, port = chosen
- return host, port
-
- raise RuntimeError, 'Impossible %s pickServer result.' % self.__class__.__name__
-
- def _reallyConnect(self):
- if self.stopAfterDNS:
- self.stopAfterDNS=0
- return
-
- self.host, self.port = self.pickServer()
- assert self.host is not None, 'Must have a host to connect to.'
- assert self.port is not None, 'Must have a port to connect to.'
-
- connectFunc = getattr(self.reactor, self.connectFuncName)
- self.connector=connectFunc(
- self.host, self.port,
- _SRVConnector_ClientFactoryWrapper(self, self.factory),
- *self.connectFuncArgs, **self.connectFuncKwArgs)
-
- def stopConnecting(self):
- """Stop attempting to connect."""
- if self.connector:
- self.connector.stopConnecting()
- else:
- self.stopAfterDNS=1
-
- def disconnect(self):
- """Disconnect whatever our are state is."""
- if self.connector is not None:
- self.connector.disconnect()
- else:
- self.stopConnecting()
-
- def getDestination(self):
- assert self.connector
- return self.connector.getDestination()
-
- def connectionFailed(self, reason):
- self.factory.clientConnectionFailed(self, reason)
- self.factory.doStop()
-
- def connectionLost(self, reason):
- self.factory.clientConnectionLost(self, reason)
- self.factory.doStop()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/tap.py
deleted file mode 100755
index d0e3b1d0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/tap.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_tap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Domain Name Server
-"""
-
-import os, traceback
-
-from twisted.python import usage
-from twisted.names import dns
-from twisted.application import internet, service
-
-from twisted.names import server
-from twisted.names import authority
-from twisted.names import secondary
-
-class Options(usage.Options):
- optParameters = [
- ["interface", "i", "", "The interface to which to bind"],
- ["port", "p", "53", "The port on which to listen"],
- ["resolv-conf", None, None,
- "Override location of resolv.conf (implies --recursive)"],
- ["hosts-file", None, None, "Perform lookups with a hosts file"],
- ]
-
- optFlags = [
- ["cache", "c", "Enable record caching"],
- ["recursive", "r", "Perform recursive lookups"],
- ["verbose", "v", "Log verbosely"],
- ]
-
- compData = usage.Completions(
- optActions={"interface" : usage.CompleteNetInterfaces()}
- )
-
- zones = None
- zonefiles = None
-
- def __init__(self):
- usage.Options.__init__(self)
- self['verbose'] = 0
- self.bindfiles = []
- self.zonefiles = []
- self.secondaries = []
-
-
- def opt_pyzone(self, filename):
- """Specify the filename of a Python syntax zone definition"""
- if not os.path.exists(filename):
- raise usage.UsageError(filename + ": No such file")
- self.zonefiles.append(filename)
-
- def opt_bindzone(self, filename):
- """Specify the filename of a BIND9 syntax zone definition"""
- if not os.path.exists(filename):
- raise usage.UsageError(filename + ": No such file")
- self.bindfiles.append(filename)
-
-
- def opt_secondary(self, ip_domain):
- """Act as secondary for the specified domain, performing
- zone transfers from the specified IP (IP/domain)
- """
- args = ip_domain.split('/', 1)
- if len(args) != 2:
- raise usage.UsageError("Argument must be of the form IP[:port]/domain")
- address = args[0].split(':')
- if len(address) == 1:
- address = (address[0], dns.PORT)
- else:
- try:
- port = int(address[1])
- except ValueError:
- raise usage.UsageError(
- "Specify an integer port number, not %r" % (address[1],))
- address = (address[0], port)
- self.secondaries.append((address, [args[1]]))
-
-
- def opt_verbose(self):
- """Increment verbosity level"""
- self['verbose'] += 1
-
-
- def postOptions(self):
- if self['resolv-conf']:
- self['recursive'] = True
-
- self.svcs = []
- self.zones = []
- for f in self.zonefiles:
- try:
- self.zones.append(authority.PySourceAuthority(f))
- except Exception:
- traceback.print_exc()
- raise usage.UsageError("Invalid syntax in " + f)
- for f in self.bindfiles:
- try:
- self.zones.append(authority.BindAuthority(f))
- except Exception:
- traceback.print_exc()
- raise usage.UsageError("Invalid syntax in " + f)
- for f in self.secondaries:
- svc = secondary.SecondaryAuthorityService.fromServerAddressAndDomains(*f)
- self.svcs.append(svc)
- self.zones.append(self.svcs[-1].getAuthority())
- try:
- self['port'] = int(self['port'])
- except ValueError:
- raise usage.UsageError("Invalid port: %r" % (self['port'],))
-
-
-def _buildResolvers(config):
- """
- Build DNS resolver instances in an order which leaves recursive
- resolving as a last resort.
-
- @type config: L{Options} instance
- @param config: Parsed command-line configuration
-
- @return: Two-item tuple of a list of cache resovers and a list of client
- resolvers
- """
- from twisted.names import client, cache, hosts
-
- ca, cl = [], []
- if config['cache']:
- ca.append(cache.CacheResolver(verbose=config['verbose']))
- if config['hosts-file']:
- cl.append(hosts.Resolver(file=config['hosts-file']))
- if config['recursive']:
- cl.append(client.createResolver(resolvconf=config['resolv-conf']))
- return ca, cl
-
-
-def makeService(config):
- ca, cl = _buildResolvers(config)
-
- f = server.DNSServerFactory(config.zones, ca, cl, config['verbose'])
- p = dns.DNSDatagramProtocol(f)
- f.noisy = 0
- ret = service.MultiService()
- for (klass, arg) in [(internet.TCPServer, f), (internet.UDPServer, p)]:
- s = klass(config['port'], arg, interface=config['interface'])
- s.setServiceParent(ret)
- for svc in config.svcs:
- svc.setServiceParent(ret)
- return ret
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/__init__.py
deleted file mode 100755
index f6b7e3ae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"Tests for twisted.names"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_cache.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_cache.py
deleted file mode 100755
index 7afafedf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_cache.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import time
-
-from twisted.trial import unittest
-
-from twisted.names import dns, cache
-from twisted.internet import task
-
-class Caching(unittest.TestCase):
- """
- Tests for L{cache.CacheResolver}.
- """
-
- def test_lookup(self):
- c = cache.CacheResolver({
- dns.Query(name='example.com', type=dns.MX, cls=dns.IN):
- (time.time(), ([], [], []))})
- return c.lookupMailExchange('example.com').addCallback(
- self.assertEqual, ([], [], []))
-
-
- def test_constructorExpires(self):
- """
- Cache entries passed into L{cache.CacheResolver.__init__} get
- cancelled just like entries added with cacheResult
- """
-
- r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
- dns.Record_A("127.0.0.1", 60))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 50,
- dns.Record_A("127.0.0.1", 50))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 40,
- dns.Record_A("127.0.0.1", 40))])
-
- clock = task.Clock()
- query = dns.Query(name="example.com", type=dns.A, cls=dns.IN)
-
- c = cache.CacheResolver({ query : (clock.seconds(), r)}, reactor=clock)
-
- # 40 seconds is enough to expire the entry because expiration is based
- # on the minimum TTL.
- clock.advance(40)
-
- self.assertNotIn(query, c.cache)
-
- return self.assertFailure(
- c.lookupAddress("example.com"), dns.DomainError)
-
-
- def test_normalLookup(self):
- """
- When a cache lookup finds a cached entry from 1 second ago, it is
- returned with a TTL of original TTL minus the elapsed 1 second.
- """
- r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
- dns.Record_A("127.0.0.1", 60))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 50,
- dns.Record_A("127.0.0.1", 50))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 40,
- dns.Record_A("127.0.0.1", 40))])
-
- clock = task.Clock()
-
- c = cache.CacheResolver(reactor=clock)
- c.cacheResult(dns.Query(name="example.com", type=dns.A, cls=dns.IN), r)
-
- clock.advance(1)
-
- def cbLookup(result):
- self.assertEquals(result[0][0].ttl, 59)
- self.assertEquals(result[1][0].ttl, 49)
- self.assertEquals(result[2][0].ttl, 39)
- self.assertEquals(result[0][0].name.name, "example.com")
-
- return c.lookupAddress("example.com").addCallback(cbLookup)
-
-
- def test_cachedResultExpires(self):
- """
- Once the TTL has been exceeded, the result is removed from the cache.
- """
- r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
- dns.Record_A("127.0.0.1", 60))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 50,
- dns.Record_A("127.0.0.1", 50))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 40,
- dns.Record_A("127.0.0.1", 40))])
-
- clock = task.Clock()
-
- c = cache.CacheResolver(reactor=clock)
- query = dns.Query(name="example.com", type=dns.A, cls=dns.IN)
- c.cacheResult(query, r)
-
- clock.advance(40)
-
- self.assertNotIn(query, c.cache)
-
- return self.assertFailure(
- c.lookupAddress("example.com"), dns.DomainError)
-
-
- def test_expiredTTLLookup(self):
- """
- When the cache is queried exactly as the cached entry should expire but
- before it has actually been cleared, the cache does not return the
- expired entry.
- """
- r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
- dns.Record_A("127.0.0.1", 60))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 50,
- dns.Record_A("127.0.0.1", 50))],
- [dns.RRHeader("example.com", dns.A, dns.IN, 40,
- dns.Record_A("127.0.0.1", 40))])
-
- clock = task.Clock()
- # Make sure timeouts never happen, so entries won't get cleared:
- clock.callLater = lambda *args, **kwargs: None
-
- c = cache.CacheResolver({
- dns.Query(name="example.com", type=dns.A, cls=dns.IN) :
- (clock.seconds(), r)}, reactor=clock)
-
- clock.advance(60.1)
-
- return self.assertFailure(
- c.lookupAddress("example.com"), dns.DomainError)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_client.py
deleted file mode 100755
index d2ed09c3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_client.py
+++ /dev/null
@@ -1,678 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for L{twisted.names.client}.
-"""
-
-from twisted.names import client, dns
-from twisted.names.error import DNSQueryTimeoutError
-from twisted.trial import unittest
-from twisted.names.common import ResolverBase
-from twisted.internet import defer, error
-from twisted.python import failure
-from twisted.python.deprecate import getWarningMethod, setWarningMethod
-from twisted.python.compat import set
-
-
-class FakeResolver(ResolverBase):
-
- def _lookup(self, name, cls, qtype, timeout):
- """
- The getHostByNameTest does a different type of query that requires it
- return an A record from an ALL_RECORDS lookup, so we accomodate that
- here.
- """
- if name == 'getHostByNameTest':
- rr = dns.RRHeader(name=name, type=dns.A, cls=cls, ttl=60,
- payload=dns.Record_A(address='127.0.0.1', ttl=60))
- else:
- rr = dns.RRHeader(name=name, type=qtype, cls=cls, ttl=60)
-
- results = [rr]
- authority = []
- addtional = []
- return defer.succeed((results, authority, addtional))
-
-
-
-class StubPort(object):
- """
- A partial implementation of L{IListeningPort} which only keeps track of
- whether it has been stopped.
-
- @ivar disconnected: A C{bool} which is C{False} until C{stopListening} is
- called, C{True} afterwards.
- """
- disconnected = False
-
- def stopListening(self):
- self.disconnected = True
-
-
-
-class StubDNSDatagramProtocol(object):
- """
- L{dns.DNSDatagramProtocol}-alike.
-
- @ivar queries: A C{list} of tuples giving the arguments passed to
- C{query} along with the L{defer.Deferred} which was returned from
- the call.
- """
- def __init__(self):
- self.queries = []
- self.transport = StubPort()
-
-
- def query(self, address, queries, timeout=10, id=None):
- """
- Record the given arguments and return a Deferred which will not be
- called back by this code.
- """
- result = defer.Deferred()
- self.queries.append((address, queries, timeout, id, result))
- return result
-
-
-
-class ResolverTests(unittest.TestCase):
- """
- Tests for L{client.Resolver}.
- """
- def test_resolverProtocol(self):
- """
- Reading L{client.Resolver.protocol} causes a deprecation warning to be
- emitted and evaluates to an instance of L{DNSDatagramProtocol}.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- self.addCleanup(setWarningMethod, getWarningMethod())
- warnings = []
- setWarningMethod(
- lambda message, category, stacklevel:
- warnings.append((message, category, stacklevel)))
- protocol = resolver.protocol
- self.assertIsInstance(protocol, dns.DNSDatagramProtocol)
- self.assertEqual(
- warnings, [("Resolver.protocol is deprecated; use "
- "Resolver.queryUDP instead.",
- PendingDeprecationWarning, 0)])
- self.assertIdentical(protocol, resolver.protocol)
-
-
- def test_datagramQueryServerOrder(self):
- """
- L{client.Resolver.queryUDP} should issue queries to its
- L{dns.DNSDatagramProtocol} with server addresses taken from its own
- C{servers} and C{dynServers} lists, proceeding through them in order
- as L{DNSQueryTimeoutError}s occur.
- """
- protocol = StubDNSDatagramProtocol()
-
- servers = [object(), object()]
- dynServers = [object(), object()]
- resolver = client.Resolver(servers=servers)
- resolver.dynServers = dynServers
- resolver.protocol = protocol
-
- expectedResult = object()
- queryResult = resolver.queryUDP(None)
- queryResult.addCallback(self.assertEqual, expectedResult)
-
- self.assertEqual(len(protocol.queries), 1)
- self.assertIdentical(protocol.queries[0][0], servers[0])
- protocol.queries[0][-1].errback(DNSQueryTimeoutError(0))
- self.assertEqual(len(protocol.queries), 2)
- self.assertIdentical(protocol.queries[1][0], servers[1])
- protocol.queries[1][-1].errback(DNSQueryTimeoutError(1))
- self.assertEqual(len(protocol.queries), 3)
- self.assertIdentical(protocol.queries[2][0], dynServers[0])
- protocol.queries[2][-1].errback(DNSQueryTimeoutError(2))
- self.assertEqual(len(protocol.queries), 4)
- self.assertIdentical(protocol.queries[3][0], dynServers[1])
- protocol.queries[3][-1].callback(expectedResult)
-
- return queryResult
-
-
- def test_singleConcurrentRequest(self):
- """
- L{client.Resolver.query} only issues one request at a time per query.
- Subsequent requests made before responses to prior ones are received
- are queued and given the same response as is given to the first one.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- resolver.protocol = StubDNSDatagramProtocol()
- queries = resolver.protocol.queries
-
- query = dns.Query('foo.example.com', dns.A, dns.IN)
- # The first query should be passed to the underlying protocol.
- firstResult = resolver.query(query)
- self.assertEqual(len(queries), 1)
-
- # The same query again should not be passed to the underlying protocol.
- secondResult = resolver.query(query)
- self.assertEqual(len(queries), 1)
-
- # The response to the first query should be sent in response to both
- # queries.
- answer = object()
- response = dns.Message()
- response.answers.append(answer)
- queries.pop()[-1].callback(response)
-
- d = defer.gatherResults([firstResult, secondResult])
- def cbFinished((firstResponse, secondResponse)):
- self.assertEqual(firstResponse, ([answer], [], []))
- self.assertEqual(secondResponse, ([answer], [], []))
- d.addCallback(cbFinished)
- return d
-
-
- def test_multipleConcurrentRequests(self):
- """
- L{client.Resolver.query} issues a request for each different concurrent
- query.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- resolver.protocol = StubDNSDatagramProtocol()
- queries = resolver.protocol.queries
-
- # The first query should be passed to the underlying protocol.
- firstQuery = dns.Query('foo.example.com', dns.A)
- resolver.query(firstQuery)
- self.assertEqual(len(queries), 1)
-
- # A query for a different name is also passed to the underlying
- # protocol.
- secondQuery = dns.Query('bar.example.com', dns.A)
- resolver.query(secondQuery)
- self.assertEqual(len(queries), 2)
-
- # A query for a different type is also passed to the underlying
- # protocol.
- thirdQuery = dns.Query('foo.example.com', dns.A6)
- resolver.query(thirdQuery)
- self.assertEqual(len(queries), 3)
-
-
- def test_multipleSequentialRequests(self):
- """
- After a response is received to a query issued with
- L{client.Resolver.query}, another query with the same parameters
- results in a new network request.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- resolver.protocol = StubDNSDatagramProtocol()
- queries = resolver.protocol.queries
-
- query = dns.Query('foo.example.com', dns.A)
-
- # The first query should be passed to the underlying protocol.
- resolver.query(query)
- self.assertEqual(len(queries), 1)
-
- # Deliver the response.
- queries.pop()[-1].callback(dns.Message())
-
- # Repeating the first query should touch the protocol again.
- resolver.query(query)
- self.assertEqual(len(queries), 1)
-
-
- def test_multipleConcurrentFailure(self):
- """
- If the result of a request is an error response, the Deferreds for all
- concurrently issued requests associated with that result fire with the
- L{Failure}.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- resolver.protocol = StubDNSDatagramProtocol()
- queries = resolver.protocol.queries
-
- query = dns.Query('foo.example.com', dns.A)
- firstResult = resolver.query(query)
- secondResult = resolver.query(query)
-
- class ExpectedException(Exception):
- pass
-
- queries.pop()[-1].errback(failure.Failure(ExpectedException()))
-
- return defer.gatherResults([
- self.assertFailure(firstResult, ExpectedException),
- self.assertFailure(secondResult, ExpectedException)])
-
-
- def test_connectedProtocol(self):
- """
- L{client.Resolver._connectedProtocol} returns a new
- L{DNSDatagramProtocol} connected to a new address with a
- cryptographically secure random port number.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- firstProto = resolver._connectedProtocol()
- secondProto = resolver._connectedProtocol()
-
- self.assertNotIdentical(firstProto.transport, None)
- self.assertNotIdentical(secondProto.transport, None)
- self.assertNotEqual(
- firstProto.transport.getHost().port,
- secondProto.transport.getHost().port)
-
- return defer.gatherResults([
- defer.maybeDeferred(firstProto.transport.stopListening),
- defer.maybeDeferred(secondProto.transport.stopListening)])
-
-
- def test_differentProtocol(self):
- """
- L{client.Resolver._connectedProtocol} is called once each time a UDP
- request needs to be issued and the resulting protocol instance is used
- for that request.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- protocols = []
-
- class FakeProtocol(object):
- def __init__(self):
- self.transport = StubPort()
-
- def query(self, address, query, timeout=10, id=None):
- protocols.append(self)
- return defer.succeed(dns.Message())
-
- resolver._connectedProtocol = FakeProtocol
- resolver.query(dns.Query('foo.example.com'))
- resolver.query(dns.Query('bar.example.com'))
- self.assertEqual(len(set(protocols)), 2)
-
-
- def test_disallowedPort(self):
- """
- If a port number is initially selected which cannot be bound, the
- L{CannotListenError} is handled and another port number is attempted.
- """
- ports = []
-
- class FakeReactor(object):
- def listenUDP(self, port, *args):
- ports.append(port)
- if len(ports) == 1:
- raise error.CannotListenError(None, port, None)
-
- resolver = client.Resolver(servers=[('example.com', 53)])
- resolver._reactor = FakeReactor()
-
- proto = resolver._connectedProtocol()
- self.assertEqual(len(set(ports)), 2)
-
-
- def test_differentProtocolAfterTimeout(self):
- """
- When a query issued by L{client.Resolver.query} times out, the retry
- uses a new protocol instance.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- protocols = []
- results = [defer.fail(failure.Failure(DNSQueryTimeoutError(None))),
- defer.succeed(dns.Message())]
-
- class FakeProtocol(object):
- def __init__(self):
- self.transport = StubPort()
-
- def query(self, address, query, timeout=10, id=None):
- protocols.append(self)
- return results.pop(0)
-
- resolver._connectedProtocol = FakeProtocol
- resolver.query(dns.Query('foo.example.com'))
- self.assertEqual(len(set(protocols)), 2)
-
-
- def test_protocolShutDown(self):
- """
- After the L{Deferred} returned by L{DNSDatagramProtocol.query} is
- called back, the L{DNSDatagramProtocol} is disconnected from its
- transport.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- protocols = []
- result = defer.Deferred()
-
- class FakeProtocol(object):
- def __init__(self):
- self.transport = StubPort()
-
- def query(self, address, query, timeout=10, id=None):
- protocols.append(self)
- return result
-
- resolver._connectedProtocol = FakeProtocol
- resolver.query(dns.Query('foo.example.com'))
-
- self.assertFalse(protocols[0].transport.disconnected)
- result.callback(dns.Message())
- self.assertTrue(protocols[0].transport.disconnected)
-
-
- def test_protocolShutDownAfterTimeout(self):
- """
- The L{DNSDatagramProtocol} created when an interim timeout occurs is
- also disconnected from its transport after the Deferred returned by its
- query method completes.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- protocols = []
- result = defer.Deferred()
- results = [defer.fail(failure.Failure(DNSQueryTimeoutError(None))),
- result]
-
- class FakeProtocol(object):
- def __init__(self):
- self.transport = StubPort()
-
- def query(self, address, query, timeout=10, id=None):
- protocols.append(self)
- return results.pop(0)
-
- resolver._connectedProtocol = FakeProtocol
- resolver.query(dns.Query('foo.example.com'))
-
- self.assertFalse(protocols[1].transport.disconnected)
- result.callback(dns.Message())
- self.assertTrue(protocols[1].transport.disconnected)
-
-
- def test_protocolShutDownAfterFailure(self):
- """
- If the L{Deferred} returned by L{DNSDatagramProtocol.query} fires with
- a failure, the L{DNSDatagramProtocol} is still disconnected from its
- transport.
- """
- class ExpectedException(Exception):
- pass
-
- resolver = client.Resolver(servers=[('example.com', 53)])
- protocols = []
- result = defer.Deferred()
-
- class FakeProtocol(object):
- def __init__(self):
- self.transport = StubPort()
-
- def query(self, address, query, timeout=10, id=None):
- protocols.append(self)
- return result
-
- resolver._connectedProtocol = FakeProtocol
- queryResult = resolver.query(dns.Query('foo.example.com'))
-
- self.assertFalse(protocols[0].transport.disconnected)
- result.errback(failure.Failure(ExpectedException()))
- self.assertTrue(protocols[0].transport.disconnected)
-
- return self.assertFailure(queryResult, ExpectedException)
-
-
- def test_tcpDisconnectRemovesFromConnections(self):
- """
- When a TCP DNS protocol associated with a Resolver disconnects, it is
- removed from the Resolver's connection list.
- """
- resolver = client.Resolver(servers=[('example.com', 53)])
- protocol = resolver.factory.buildProtocol(None)
- protocol.makeConnection(None)
- self.assertIn(protocol, resolver.connections)
-
- # Disconnecting should remove the protocol from the connection list:
- protocol.connectionLost(None)
- self.assertNotIn(protocol, resolver.connections)
-
-
-
-class ClientTestCase(unittest.TestCase):
-
- def setUp(self):
- """
- Replace the resolver with a FakeResolver
- """
- client.theResolver = FakeResolver()
- self.hostname = 'example.com'
- self.ghbntest = 'getHostByNameTest'
-
- def tearDown(self):
- """
- By setting the resolver to None, it will be recreated next time a name
- lookup is done.
- """
- client.theResolver = None
-
- def checkResult(self, (results, authority, additional), qtype):
- """
- Verify that the result is the same query type as what is expected.
- """
- result = results[0]
- self.assertEqual(str(result.name), self.hostname)
- self.assertEqual(result.type, qtype)
-
- def checkGetHostByName(self, result):
- """
- Test that the getHostByName query returns the 127.0.0.1 address.
- """
- self.assertEqual(result, '127.0.0.1')
-
- def test_getHostByName(self):
- """
- do a getHostByName of a value that should return 127.0.0.1.
- """
- d = client.getHostByName(self.ghbntest)
- d.addCallback(self.checkGetHostByName)
- return d
-
- def test_lookupAddress(self):
- """
- Do a lookup and test that the resolver will issue the correct type of
- query type. We do this by checking that FakeResolver returns a result
- record with the same query type as what we issued.
- """
- d = client.lookupAddress(self.hostname)
- d.addCallback(self.checkResult, dns.A)
- return d
-
- def test_lookupIPV6Address(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupIPV6Address(self.hostname)
- d.addCallback(self.checkResult, dns.AAAA)
- return d
-
- def test_lookupAddress6(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupAddress6(self.hostname)
- d.addCallback(self.checkResult, dns.A6)
- return d
-
- def test_lookupNameservers(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupNameservers(self.hostname)
- d.addCallback(self.checkResult, dns.NS)
- return d
-
- def test_lookupCanonicalName(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupCanonicalName(self.hostname)
- d.addCallback(self.checkResult, dns.CNAME)
- return d
-
- def test_lookupAuthority(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupAuthority(self.hostname)
- d.addCallback(self.checkResult, dns.SOA)
- return d
-
- def test_lookupMailBox(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupMailBox(self.hostname)
- d.addCallback(self.checkResult, dns.MB)
- return d
-
- def test_lookupMailGroup(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupMailGroup(self.hostname)
- d.addCallback(self.checkResult, dns.MG)
- return d
-
- def test_lookupMailRename(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupMailRename(self.hostname)
- d.addCallback(self.checkResult, dns.MR)
- return d
-
- def test_lookupNull(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupNull(self.hostname)
- d.addCallback(self.checkResult, dns.NULL)
- return d
-
- def test_lookupWellKnownServices(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupWellKnownServices(self.hostname)
- d.addCallback(self.checkResult, dns.WKS)
- return d
-
- def test_lookupPointer(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupPointer(self.hostname)
- d.addCallback(self.checkResult, dns.PTR)
- return d
-
- def test_lookupHostInfo(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupHostInfo(self.hostname)
- d.addCallback(self.checkResult, dns.HINFO)
- return d
-
- def test_lookupMailboxInfo(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupMailboxInfo(self.hostname)
- d.addCallback(self.checkResult, dns.MINFO)
- return d
-
- def test_lookupMailExchange(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupMailExchange(self.hostname)
- d.addCallback(self.checkResult, dns.MX)
- return d
-
- def test_lookupText(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupText(self.hostname)
- d.addCallback(self.checkResult, dns.TXT)
- return d
-
- def test_lookupSenderPolicy(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupSenderPolicy(self.hostname)
- d.addCallback(self.checkResult, dns.SPF)
- return d
-
- def test_lookupResponsibility(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupResponsibility(self.hostname)
- d.addCallback(self.checkResult, dns.RP)
- return d
-
- def test_lookupAFSDatabase(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupAFSDatabase(self.hostname)
- d.addCallback(self.checkResult, dns.AFSDB)
- return d
-
- def test_lookupService(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupService(self.hostname)
- d.addCallback(self.checkResult, dns.SRV)
- return d
-
- def test_lookupZone(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupZone(self.hostname)
- d.addCallback(self.checkResult, dns.AXFR)
- return d
-
- def test_lookupAllRecords(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupAllRecords(self.hostname)
- d.addCallback(self.checkResult, dns.ALL_RECORDS)
- return d
-
-
- def test_lookupNamingAuthorityPointer(self):
- """
- See L{test_lookupAddress}
- """
- d = client.lookupNamingAuthorityPointer(self.hostname)
- d.addCallback(self.checkResult, dns.NAPTR)
- return d
-
-
-class ThreadedResolverTests(unittest.TestCase):
- """
- Tests for L{client.ThreadedResolver}.
- """
- def test_deprecated(self):
- """
- L{client.ThreadedResolver} is deprecated. Instantiating it emits a
- deprecation warning pointing at the code that does the instantiation.
- """
- client.ThreadedResolver()
- warnings = self.flushWarnings(offendingFunctions=[self.test_deprecated])
- self.assertEqual(
- warnings[0]['message'],
- "twisted.names.client.ThreadedResolver is deprecated since "
- "Twisted 9.0, use twisted.internet.base.ThreadedResolver "
- "instead.")
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(len(warnings), 1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_common.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_common.py
deleted file mode 100755
index b44e2067..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_common.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.names.common}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.names.common import ResolverBase
-from twisted.names.dns import EFORMAT, ESERVER, ENAME, ENOTIMP, EREFUSED
-from twisted.names.error import DNSFormatError, DNSServerError, DNSNameError
-from twisted.names.error import DNSNotImplementedError, DNSQueryRefusedError
-from twisted.names.error import DNSUnknownError
-
-
-class ExceptionForCodeTests(TestCase):
- """
- Tests for L{ResolverBase.exceptionForCode}.
- """
- def setUp(self):
- self.exceptionForCode = ResolverBase().exceptionForCode
-
-
- def test_eformat(self):
- """
- L{ResolverBase.exceptionForCode} converts L{EFORMAT} to
- L{DNSFormatError}.
- """
- self.assertIdentical(self.exceptionForCode(EFORMAT), DNSFormatError)
-
-
- def test_eserver(self):
- """
- L{ResolverBase.exceptionForCode} converts L{ESERVER} to
- L{DNSServerError}.
- """
- self.assertIdentical(self.exceptionForCode(ESERVER), DNSServerError)
-
-
- def test_ename(self):
- """
- L{ResolverBase.exceptionForCode} converts L{ENAME} to L{DNSNameError}.
- """
- self.assertIdentical(self.exceptionForCode(ENAME), DNSNameError)
-
-
- def test_enotimp(self):
- """
- L{ResolverBase.exceptionForCode} converts L{ENOTIMP} to
- L{DNSNotImplementedError}.
- """
- self.assertIdentical(
- self.exceptionForCode(ENOTIMP), DNSNotImplementedError)
-
-
- def test_erefused(self):
- """
- L{ResolverBase.exceptionForCode} converts L{EREFUSED} to
- L{DNSQueryRefusedError}.
- """
- self.assertIdentical(
- self.exceptionForCode(EREFUSED), DNSQueryRefusedError)
-
-
- def test_other(self):
- """
- L{ResolverBase.exceptionForCode} converts any other response code to
- L{DNSUnknownError}.
- """
- self.assertIdentical(
- self.exceptionForCode(object()), DNSUnknownError)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_dns.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_dns.py
deleted file mode 100755
index 5e24b42f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_dns.py
+++ /dev/null
@@ -1,1501 +0,0 @@
-# test-case-name: twisted.names.test.test_dns
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for twisted.names.dns.
-"""
-
-from cStringIO import StringIO
-
-import struct
-
-from twisted.python.failure import Failure
-from twisted.internet import address, task
-from twisted.internet.error import CannotListenError, ConnectionDone
-from twisted.trial import unittest
-from twisted.names import dns
-
-from twisted.test import proto_helpers
-
-RECORD_TYPES = [
- dns.Record_NS, dns.Record_MD, dns.Record_MF, dns.Record_CNAME,
- dns.Record_MB, dns.Record_MG, dns.Record_MR, dns.Record_PTR,
- dns.Record_DNAME, dns.Record_A, dns.Record_SOA, dns.Record_NULL,
- dns.Record_WKS, dns.Record_SRV, dns.Record_AFSDB, dns.Record_RP,
- dns.Record_HINFO, dns.Record_MINFO, dns.Record_MX, dns.Record_TXT,
- dns.Record_AAAA, dns.Record_A6, dns.Record_NAPTR, dns.UnknownRecord,
- ]
-
-class NameTests(unittest.TestCase):
- """
- Tests for L{Name}, the representation of a single domain name with support
- for encoding into and decoding from DNS message format.
- """
- def test_decode(self):
- """
- L{Name.decode} populates the L{Name} instance with name information read
- from the file-like object passed to it.
- """
- n = dns.Name()
- n.decode(StringIO("\x07example\x03com\x00"))
- self.assertEqual(n.name, "example.com")
-
-
- def test_encode(self):
- """
- L{Name.encode} encodes its name information and writes it to the
- file-like object passed to it.
- """
- name = dns.Name("foo.example.com")
- stream = StringIO()
- name.encode(stream)
- self.assertEqual(stream.getvalue(), "\x03foo\x07example\x03com\x00")
-
-
- def test_encodeWithCompression(self):
- """
- If a compression dictionary is passed to it, L{Name.encode} uses offset
- information from it to encode its name with references to existing
- labels in the stream instead of including another copy of them in the
- output. It also updates the compression dictionary with the location of
- the name it writes to the stream.
- """
- name = dns.Name("foo.example.com")
- compression = {"example.com": 0x17}
-
- # Some bytes already encoded into the stream for this message
- previous = "some prefix to change .tell()"
- stream = StringIO()
- stream.write(previous)
-
- # The position at which the encoded form of this new name will appear in
- # the stream.
- expected = len(previous) + dns.Message.headerSize
- name.encode(stream, compression)
- self.assertEqual(
- "\x03foo\xc0\x17",
- stream.getvalue()[len(previous):])
- self.assertEqual(
- {"example.com": 0x17, "foo.example.com": expected},
- compression)
-
-
- def test_unknown(self):
- """
- A resource record of unknown type and class is parsed into an
- L{UnknownRecord} instance with its data preserved, and an
- L{UnknownRecord} instance is serialized to a string equal to the one it
- was parsed from.
- """
- wire = (
- '\x01\x00' # Message ID
- '\x00' # answer bit, opCode nibble, auth bit, trunc bit, recursive
- # bit
- '\x00' # recursion bit, empty bit, empty bit, empty bit, response
- # code nibble
- '\x00\x01' # number of queries
- '\x00\x01' # number of answers
- '\x00\x00' # number of authorities
- '\x00\x01' # number of additionals
-
- # query
- '\x03foo\x03bar\x00' # foo.bar
- '\xde\xad' # type=0xdead
- '\xbe\xef' # cls=0xbeef
-
- # 1st answer
- '\xc0\x0c' # foo.bar - compressed
- '\xde\xad' # type=0xdead
- '\xbe\xef' # cls=0xbeef
- '\x00\x00\x01\x01' # ttl=257
- '\x00\x08somedata' # some payload data
-
- # 1st additional
- '\x03baz\x03ban\x00' # baz.ban
- '\x00\x01' # type=A
- '\x00\x01' # cls=IN
- '\x00\x00\x01\x01' # ttl=257
- '\x00\x04' # len=4
- '\x01\x02\x03\x04' # 1.2.3.4
-
- )
-
- msg = dns.Message()
- msg.fromStr(wire)
-
- self.assertEqual(msg.queries, [
- dns.Query('foo.bar', type=0xdead, cls=0xbeef),
- ])
- self.assertEqual(msg.answers, [
- dns.RRHeader('foo.bar', type=0xdead, cls=0xbeef, ttl=257,
- payload=dns.UnknownRecord('somedata', ttl=257)),
- ])
- self.assertEqual(msg.additional, [
- dns.RRHeader('baz.ban', type=dns.A, cls=dns.IN, ttl=257,
- payload=dns.Record_A('1.2.3.4', ttl=257)),
- ])
-
- enc = msg.toStr()
-
- self.assertEqual(enc, wire)
-
-
- def test_decodeWithCompression(self):
- """
- If the leading byte of an encoded label (in bytes read from a stream
- passed to L{Name.decode}) has its two high bits set, the next byte is
- treated as a pointer to another label in the stream and that label is
- included in the name being decoded.
- """
- # Slightly modified version of the example from RFC 1035, section 4.1.4.
- stream = StringIO(
- "x" * 20 +
- "\x01f\x03isi\x04arpa\x00"
- "\x03foo\xc0\x14"
- "\x03bar\xc0\x20")
- stream.seek(20)
- name = dns.Name()
- name.decode(stream)
- # Verify we found the first name in the stream and that the stream
- # position is left at the first byte after the decoded name.
- self.assertEqual("f.isi.arpa", name.name)
- self.assertEqual(32, stream.tell())
-
- # Get the second name from the stream and make the same assertions.
- name.decode(stream)
- self.assertEqual(name.name, "foo.f.isi.arpa")
- self.assertEqual(38, stream.tell())
-
- # Get the third and final name
- name.decode(stream)
- self.assertEqual(name.name, "bar.foo.f.isi.arpa")
- self.assertEqual(44, stream.tell())
-
-
- def test_rejectCompressionLoop(self):
- """
- L{Name.decode} raises L{ValueError} if the stream passed to it includes
- a compression pointer which forms a loop, causing the name to be
- undecodable.
- """
- name = dns.Name()
- stream = StringIO("\xc0\x00")
- self.assertRaises(ValueError, name.decode, stream)
-
-
-
-class RoundtripDNSTestCase(unittest.TestCase):
- """Encoding and then decoding various objects."""
-
- names = ["example.org", "go-away.fish.tv", "23strikesback.net"]
-
- def testName(self):
- for n in self.names:
- # encode the name
- f = StringIO()
- dns.Name(n).encode(f)
-
- # decode the name
- f.seek(0, 0)
- result = dns.Name()
- result.decode(f)
- self.assertEqual(result.name, n)
-
- def testQuery(self):
- for n in self.names:
- for dnstype in range(1, 17):
- for dnscls in range(1, 5):
- # encode the query
- f = StringIO()
- dns.Query(n, dnstype, dnscls).encode(f)
-
- # decode the result
- f.seek(0, 0)
- result = dns.Query()
- result.decode(f)
- self.assertEqual(result.name.name, n)
- self.assertEqual(result.type, dnstype)
- self.assertEqual(result.cls, dnscls)
-
- def testRR(self):
- # encode the RR
- f = StringIO()
- dns.RRHeader("test.org", 3, 4, 17).encode(f)
-
- # decode the result
- f.seek(0, 0)
- result = dns.RRHeader()
- result.decode(f)
- self.assertEqual(str(result.name), "test.org")
- self.assertEqual(result.type, 3)
- self.assertEqual(result.cls, 4)
- self.assertEqual(result.ttl, 17)
-
-
- def testResources(self):
- names = (
- "this.are.test.name",
- "will.compress.will.this.will.name.will.hopefully",
- "test.CASE.preSErVatIOn.YeAH",
- "a.s.h.o.r.t.c.a.s.e.t.o.t.e.s.t",
- "singleton"
- )
- for s in names:
- f = StringIO()
- dns.SimpleRecord(s).encode(f)
- f.seek(0, 0)
- result = dns.SimpleRecord()
- result.decode(f)
- self.assertEqual(str(result.name), s)
-
- def test_hashable(self):
- """
- Instances of all record types are hashable.
- """
- for k in RECORD_TYPES:
- k1, k2 = k(), k()
- hk1 = hash(k1)
- hk2 = hash(k2)
- self.assertEqual(hk1, hk2, "%s != %s (for %s)" % (hk1,hk2,k))
-
-
- def test_Charstr(self):
- """
- Test L{dns.Charstr} encode and decode.
- """
- for n in self.names:
- # encode the name
- f = StringIO()
- dns.Charstr(n).encode(f)
-
- # decode the name
- f.seek(0, 0)
- result = dns.Charstr()
- result.decode(f)
- self.assertEqual(result.string, n)
-
-
- def test_NAPTR(self):
- """
- Test L{dns.Record_NAPTR} encode and decode.
- """
- naptrs = [(100, 10, "u", "sip+E2U",
- "!^.*$!sip:information@domain.tld!", ""),
- (100, 50, "s", "http+I2L+I2C+I2R", "",
- "_http._tcp.gatech.edu")]
-
- for (order, preference, flags, service, regexp, replacement) in naptrs:
- rin = dns.Record_NAPTR(order, preference, flags, service, regexp,
- replacement)
- e = StringIO()
- rin.encode(e)
- e.seek(0,0)
- rout = dns.Record_NAPTR()
- rout.decode(e)
- self.assertEqual(rin.order, rout.order)
- self.assertEqual(rin.preference, rout.preference)
- self.assertEqual(rin.flags, rout.flags)
- self.assertEqual(rin.service, rout.service)
- self.assertEqual(rin.regexp, rout.regexp)
- self.assertEqual(rin.replacement.name, rout.replacement.name)
- self.assertEqual(rin.ttl, rout.ttl)
-
-
-
-class MessageTestCase(unittest.TestCase):
- """
- Tests for L{twisted.names.dns.Message}.
- """
-
- def testEmptyMessage(self):
- """
- Test that a message which has been truncated causes an EOFError to
- be raised when it is parsed.
- """
- msg = dns.Message()
- self.assertRaises(EOFError, msg.fromStr, '')
-
-
- def testEmptyQuery(self):
- """
- Test that bytes representing an empty query message can be decoded
- as such.
- """
- msg = dns.Message()
- msg.fromStr(
- '\x01\x00' # Message ID
- '\x00' # answer bit, opCode nibble, auth bit, trunc bit, recursive bit
- '\x00' # recursion bit, empty bit, empty bit, empty bit, response code nibble
- '\x00\x00' # number of queries
- '\x00\x00' # number of answers
- '\x00\x00' # number of authorities
- '\x00\x00' # number of additionals
- )
- self.assertEqual(msg.id, 256)
- self.failIf(msg.answer, "Message was not supposed to be an answer.")
- self.assertEqual(msg.opCode, dns.OP_QUERY)
- self.failIf(msg.auth, "Message was not supposed to be authoritative.")
- self.failIf(msg.trunc, "Message was not supposed to be truncated.")
- self.assertEqual(msg.queries, [])
- self.assertEqual(msg.answers, [])
- self.assertEqual(msg.authority, [])
- self.assertEqual(msg.additional, [])
-
-
- def testNULL(self):
- bytes = ''.join([chr(i) for i in range(256)])
- rec = dns.Record_NULL(bytes)
- rr = dns.RRHeader('testname', dns.NULL, payload=rec)
- msg1 = dns.Message()
- msg1.answers.append(rr)
- s = StringIO()
- msg1.encode(s)
- s.seek(0, 0)
- msg2 = dns.Message()
- msg2.decode(s)
-
- self.failUnless(isinstance(msg2.answers[0].payload, dns.Record_NULL))
- self.assertEqual(msg2.answers[0].payload.payload, bytes)
-
-
- def test_lookupRecordTypeDefault(self):
- """
- L{Message.lookupRecordType} returns C{dns.UnknownRecord} if it is
- called with an integer which doesn't correspond to any known record
- type.
- """
- # 65280 is the first value in the range reserved for private
- # use, so it shouldn't ever conflict with an officially
- # allocated value.
- self.assertIdentical(
- dns.Message().lookupRecordType(65280), dns.UnknownRecord)
-
-
- def test_nonAuthoritativeMessage(self):
- """
- The L{RRHeader} instances created by L{Message} from a non-authoritative
- message are marked as not authoritative.
- """
- buf = StringIO()
- answer = dns.RRHeader(payload=dns.Record_A('1.2.3.4', ttl=0))
- answer.encode(buf)
- message = dns.Message()
- message.fromStr(
- '\x01\x00' # Message ID
- # answer bit, opCode nibble, auth bit, trunc bit, recursive bit
- '\x00'
- # recursion bit, empty bit, empty bit, empty bit, response code
- # nibble
- '\x00'
- '\x00\x00' # number of queries
- '\x00\x01' # number of answers
- '\x00\x00' # number of authorities
- '\x00\x00' # number of additionals
- + buf.getvalue()
- )
- self.assertEqual(message.answers, [answer])
- self.assertFalse(message.answers[0].auth)
-
-
- def test_authoritativeMessage(self):
- """
- The L{RRHeader} instances created by L{Message} from an authoritative
- message are marked as authoritative.
- """
- buf = StringIO()
- answer = dns.RRHeader(payload=dns.Record_A('1.2.3.4', ttl=0))
- answer.encode(buf)
- message = dns.Message()
- message.fromStr(
- '\x01\x00' # Message ID
- # answer bit, opCode nibble, auth bit, trunc bit, recursive bit
- '\x04'
- # recursion bit, empty bit, empty bit, empty bit, response code
- # nibble
- '\x00'
- '\x00\x00' # number of queries
- '\x00\x01' # number of answers
- '\x00\x00' # number of authorities
- '\x00\x00' # number of additionals
- + buf.getvalue()
- )
- answer.auth = True
- self.assertEqual(message.answers, [answer])
- self.assertTrue(message.answers[0].auth)
-
-
-
-class TestController(object):
- """
- Pretend to be a DNS query processor for a DNSDatagramProtocol.
-
- @ivar messages: the list of received messages.
- @type messages: C{list} of (msg, protocol, address)
- """
-
- def __init__(self):
- """
- Initialize the controller: create a list of messages.
- """
- self.messages = []
-
-
- def messageReceived(self, msg, proto, addr):
- """
- Save the message so that it can be checked during the tests.
- """
- self.messages.append((msg, proto, addr))
-
-
-
-class DatagramProtocolTestCase(unittest.TestCase):
- """
- Test various aspects of L{dns.DNSDatagramProtocol}.
- """
-
- def setUp(self):
- """
- Create a L{dns.DNSDatagramProtocol} with a deterministic clock.
- """
- self.clock = task.Clock()
- self.controller = TestController()
- self.proto = dns.DNSDatagramProtocol(self.controller)
- transport = proto_helpers.FakeDatagramTransport()
- self.proto.makeConnection(transport)
- self.proto.callLater = self.clock.callLater
-
-
- def test_truncatedPacket(self):
- """
- Test that when a short datagram is received, datagramReceived does
- not raise an exception while processing it.
- """
- self.proto.datagramReceived('',
- address.IPv4Address('UDP', '127.0.0.1', 12345))
- self.assertEqual(self.controller.messages, [])
-
-
- def test_simpleQuery(self):
- """
- Test content received after a query.
- """
- d = self.proto.query(('127.0.0.1', 21345), [dns.Query('foo')])
- self.assertEqual(len(self.proto.liveMessages.keys()), 1)
- m = dns.Message()
- m.id = self.proto.liveMessages.items()[0][0]
- m.answers = [dns.RRHeader(payload=dns.Record_A(address='1.2.3.4'))]
- def cb(result):
- self.assertEqual(result.answers[0].payload.dottedQuad(), '1.2.3.4')
- d.addCallback(cb)
- self.proto.datagramReceived(m.toStr(), ('127.0.0.1', 21345))
- return d
-
-
- def test_queryTimeout(self):
- """
- Test that query timeouts after some seconds.
- """
- d = self.proto.query(('127.0.0.1', 21345), [dns.Query('foo')])
- self.assertEqual(len(self.proto.liveMessages), 1)
- self.clock.advance(10)
- self.assertFailure(d, dns.DNSQueryTimeoutError)
- self.assertEqual(len(self.proto.liveMessages), 0)
- return d
-
-
- def test_writeError(self):
- """
- Exceptions raised by the transport's write method should be turned into
- C{Failure}s passed to errbacks of the C{Deferred} returned by
- L{DNSDatagramProtocol.query}.
- """
- def writeError(message, addr):
- raise RuntimeError("bar")
- self.proto.transport.write = writeError
-
- d = self.proto.query(('127.0.0.1', 21345), [dns.Query('foo')])
- return self.assertFailure(d, RuntimeError)
-
-
- def test_listenError(self):
- """
- Exception L{CannotListenError} raised by C{listenUDP} should be turned
- into a C{Failure} passed to errback of the C{Deferred} returned by
- L{DNSDatagramProtocol.query}.
- """
- def startListeningError():
- raise CannotListenError(None, None, None)
- self.proto.startListening = startListeningError
- # Clean up transport so that the protocol calls startListening again
- self.proto.transport = None
-
- d = self.proto.query(('127.0.0.1', 21345), [dns.Query('foo')])
- return self.assertFailure(d, CannotListenError)
-
-
-
-class TestTCPController(TestController):
- """
- Pretend to be a DNS query processor for a DNSProtocol.
-
- @ivar connections: A list of L{DNSProtocol} instances which have
- notified this controller that they are connected and have not
- yet notified it that their connection has been lost.
- """
- def __init__(self):
- TestController.__init__(self)
- self.connections = []
-
-
- def connectionMade(self, proto):
- self.connections.append(proto)
-
-
- def connectionLost(self, proto):
- self.connections.remove(proto)
-
-
-
-class DNSProtocolTestCase(unittest.TestCase):
- """
- Test various aspects of L{dns.DNSProtocol}.
- """
-
- def setUp(self):
- """
- Create a L{dns.DNSProtocol} with a deterministic clock.
- """
- self.clock = task.Clock()
- self.controller = TestTCPController()
- self.proto = dns.DNSProtocol(self.controller)
- self.proto.makeConnection(proto_helpers.StringTransport())
- self.proto.callLater = self.clock.callLater
-
-
- def test_connectionTracking(self):
- """
- L{dns.DNSProtocol} calls its controller's C{connectionMade}
- method with itself when it is connected to a transport and its
- controller's C{connectionLost} method when it is disconnected.
- """
- self.assertEqual(self.controller.connections, [self.proto])
- self.proto.connectionLost(
- Failure(ConnectionDone("Fake Connection Done")))
- self.assertEqual(self.controller.connections, [])
-
-
- def test_queryTimeout(self):
- """
- Test that query timeouts after some seconds.
- """
- d = self.proto.query([dns.Query('foo')])
- self.assertEqual(len(self.proto.liveMessages), 1)
- self.clock.advance(60)
- self.assertFailure(d, dns.DNSQueryTimeoutError)
- self.assertEqual(len(self.proto.liveMessages), 0)
- return d
-
-
- def test_simpleQuery(self):
- """
- Test content received after a query.
- """
- d = self.proto.query([dns.Query('foo')])
- self.assertEqual(len(self.proto.liveMessages.keys()), 1)
- m = dns.Message()
- m.id = self.proto.liveMessages.items()[0][0]
- m.answers = [dns.RRHeader(payload=dns.Record_A(address='1.2.3.4'))]
- def cb(result):
- self.assertEqual(result.answers[0].payload.dottedQuad(), '1.2.3.4')
- d.addCallback(cb)
- s = m.toStr()
- s = struct.pack('!H', len(s)) + s
- self.proto.dataReceived(s)
- return d
-
-
- def test_writeError(self):
- """
- Exceptions raised by the transport's write method should be turned into
- C{Failure}s passed to errbacks of the C{Deferred} returned by
- L{DNSProtocol.query}.
- """
- def writeError(message):
- raise RuntimeError("bar")
- self.proto.transport.write = writeError
-
- d = self.proto.query([dns.Query('foo')])
- return self.assertFailure(d, RuntimeError)
-
-
-
-class ReprTests(unittest.TestCase):
- """
- Tests for the C{__repr__} implementation of record classes.
- """
- def test_ns(self):
- """
- The repr of a L{dns.Record_NS} instance includes the name of the
- nameserver and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_NS('example.com', 4321)),
- "<NS name=example.com ttl=4321>")
-
-
- def test_md(self):
- """
- The repr of a L{dns.Record_MD} instance includes the name of the
- mail destination and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_MD('example.com', 4321)),
- "<MD name=example.com ttl=4321>")
-
-
- def test_mf(self):
- """
- The repr of a L{dns.Record_MF} instance includes the name of the
- mail forwarder and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_MF('example.com', 4321)),
- "<MF name=example.com ttl=4321>")
-
-
- def test_cname(self):
- """
- The repr of a L{dns.Record_CNAME} instance includes the name of the
- mail forwarder and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_CNAME('example.com', 4321)),
- "<CNAME name=example.com ttl=4321>")
-
-
- def test_mb(self):
- """
- The repr of a L{dns.Record_MB} instance includes the name of the
- mailbox and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_MB('example.com', 4321)),
- "<MB name=example.com ttl=4321>")
-
-
- def test_mg(self):
- """
- The repr of a L{dns.Record_MG} instance includes the name of the
- mail group memeber and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_MG('example.com', 4321)),
- "<MG name=example.com ttl=4321>")
-
-
- def test_mr(self):
- """
- The repr of a L{dns.Record_MR} instance includes the name of the
- mail rename domain and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_MR('example.com', 4321)),
- "<MR name=example.com ttl=4321>")
-
-
- def test_ptr(self):
- """
- The repr of a L{dns.Record_PTR} instance includes the name of the
- pointer and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_PTR('example.com', 4321)),
- "<PTR name=example.com ttl=4321>")
-
-
- def test_dname(self):
- """
- The repr of a L{dns.Record_DNAME} instance includes the name of the
- non-terminal DNS name redirection and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_DNAME('example.com', 4321)),
- "<DNAME name=example.com ttl=4321>")
-
-
- def test_a(self):
- """
- The repr of a L{dns.Record_A} instance includes the dotted-quad
- string representation of the address it is for and the TTL of the
- record.
- """
- self.assertEqual(
- repr(dns.Record_A('1.2.3.4', 567)),
- '<A address=1.2.3.4 ttl=567>')
-
-
- def test_soa(self):
- """
- The repr of a L{dns.Record_SOA} instance includes all of the
- authority fields.
- """
- self.assertEqual(
- repr(dns.Record_SOA(mname='mName', rname='rName', serial=123,
- refresh=456, retry=789, expire=10,
- minimum=11, ttl=12)),
- "<SOA mname=mName rname=rName serial=123 refresh=456 "
- "retry=789 expire=10 minimum=11 ttl=12>")
-
-
- def test_null(self):
- """
- The repr of a L{dns.Record_NULL} instance includes the repr of its
- payload and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_NULL('abcd', 123)),
- "<NULL payload='abcd' ttl=123>")
-
-
- def test_wks(self):
- """
- The repr of a L{dns.Record_WKS} instance includes the dotted-quad
- string representation of the address it is for, the IP protocol
- number it is for, and the TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_WKS('2.3.4.5', 7, ttl=8)),
- "<WKS address=2.3.4.5 protocol=7 ttl=8>")
-
-
- def test_aaaa(self):
- """
- The repr of a L{dns.Record_AAAA} instance includes the colon-separated
- hex string representation of the address it is for and the TTL of the
- record.
- """
- self.assertEqual(
- repr(dns.Record_AAAA('8765::1234', ttl=10)),
- "<AAAA address=8765::1234 ttl=10>")
-
-
- def test_a6(self):
- """
- The repr of a L{dns.Record_A6} instance includes the colon-separated
- hex string representation of the address it is for and the TTL of the
- record.
- """
- self.assertEqual(
- repr(dns.Record_A6(0, '1234::5678', 'foo.bar', ttl=10)),
- "<A6 suffix=1234::5678 prefix=foo.bar ttl=10>")
-
-
- def test_srv(self):
- """
- The repr of a L{dns.Record_SRV} instance includes the name and port of
- the target and the priority, weight, and TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_SRV(1, 2, 3, 'example.org', 4)),
- "<SRV priority=1 weight=2 target=example.org port=3 ttl=4>")
-
-
- def test_naptr(self):
- """
- The repr of a L{dns.Record_NAPTR} instance includes the order,
- preference, flags, service, regular expression, replacement, and TTL of
- the record.
- """
- self.assertEqual(
- repr(dns.Record_NAPTR(5, 9, "S", "http", "/foo/bar/i", "baz", 3)),
- "<NAPTR order=5 preference=9 flags=S service=http "
- "regexp=/foo/bar/i replacement=baz ttl=3>")
-
-
- def test_afsdb(self):
- """
- The repr of a L{dns.Record_AFSDB} instance includes the subtype,
- hostname, and TTL of the record.
- """
- self.assertEqual(
- repr(dns.Record_AFSDB(3, 'example.org', 5)),
- "<AFSDB subtype=3 hostname=example.org ttl=5>")
-
-
- def test_rp(self):
- """
- The repr of a L{dns.Record_RP} instance includes the mbox, txt, and TTL
- fields of the record.
- """
- self.assertEqual(
- repr(dns.Record_RP('alice.example.com', 'admin.example.com', 3)),
- "<RP mbox=alice.example.com txt=admin.example.com ttl=3>")
-
-
- def test_hinfo(self):
- """
- The repr of a L{dns.Record_HINFO} instance includes the cpu, os, and
- TTL fields of the record.
- """
- self.assertEqual(
- repr(dns.Record_HINFO('sparc', 'minix', 12)),
- "<HINFO cpu='sparc' os='minix' ttl=12>")
-
-
- def test_minfo(self):
- """
- The repr of a L{dns.Record_MINFO} instance includes the rmailbx,
- emailbx, and TTL fields of the record.
- """
- self.assertEqual(
- repr(dns.Record_MINFO('alice.example.com', 'bob.example.com', 15)),
- "<MINFO responsibility=alice.example.com "
- "errors=bob.example.com ttl=15>")
-
-
- def test_mx(self):
- """
- The repr of a L{dns.Record_MX} instance includes the preference, name,
- and TTL fields of the record.
- """
- self.assertEqual(
- repr(dns.Record_MX(13, 'mx.example.com', 2)),
- "<MX preference=13 name=mx.example.com ttl=2>")
-
-
- def test_txt(self):
- """
- The repr of a L{dns.Record_TXT} instance includes the data and ttl
- fields of the record.
- """
- self.assertEqual(
- repr(dns.Record_TXT("foo", "bar", ttl=15)),
- "<TXT data=['foo', 'bar'] ttl=15>")
-
-
- def test_spf(self):
- """
- The repr of a L{dns.Record_SPF} instance includes the data and ttl
- fields of the record.
- """
- self.assertEqual(
- repr(dns.Record_SPF("foo", "bar", ttl=15)),
- "<SPF data=['foo', 'bar'] ttl=15>")
-
-
- def test_unknown(self):
- """
- The repr of a L{dns.UnknownRecord} instance includes the data and ttl
- fields of the record.
- """
- self.assertEqual(
- repr(dns.UnknownRecord("foo\x1fbar", 12)),
- "<UNKNOWN data='foo\\x1fbar' ttl=12>")
-
-
-
-class _Equal(object):
- """
- A class the instances of which are equal to anything and everything.
- """
- def __eq__(self, other):
- return True
-
-
- def __ne__(self, other):
- return False
-
-
-
-class _NotEqual(object):
- """
- A class the instances of which are equal to nothing.
- """
- def __eq__(self, other):
- return False
-
-
- def __ne__(self, other):
- return True
-
-
-
-class EqualityTests(unittest.TestCase):
- """
- Tests for the equality and non-equality behavior of record classes.
- """
- def _equalityTest(self, firstValueOne, secondValueOne, valueTwo):
- """
- Assert that C{firstValueOne} is equal to C{secondValueOne} but not
- equal to C{valueOne} and that it defines equality cooperatively with
- other types it doesn't know about.
- """
- # This doesn't use assertEqual and assertNotEqual because the exact
- # operator those functions use is not very well defined. The point
- # of these assertions is to check the results of the use of specific
- # operators (precisely to ensure that using different permutations
- # (eg "x == y" or "not (x != y)") which should yield the same results
- # actually does yield the same result). -exarkun
- self.assertTrue(firstValueOne == firstValueOne)
- self.assertTrue(firstValueOne == secondValueOne)
- self.assertFalse(firstValueOne == valueTwo)
- self.assertFalse(firstValueOne != firstValueOne)
- self.assertFalse(firstValueOne != secondValueOne)
- self.assertTrue(firstValueOne != valueTwo)
- self.assertTrue(firstValueOne == _Equal())
- self.assertFalse(firstValueOne != _Equal())
- self.assertFalse(firstValueOne == _NotEqual())
- self.assertTrue(firstValueOne != _NotEqual())
-
-
- def _simpleEqualityTest(self, cls):
- # Vary the TTL
- self._equalityTest(
- cls('example.com', 123),
- cls('example.com', 123),
- cls('example.com', 321))
- # Vary the name
- self._equalityTest(
- cls('example.com', 123),
- cls('example.com', 123),
- cls('example.org', 123))
-
-
- def test_rrheader(self):
- """
- Two L{dns.RRHeader} instances compare equal if and only if they have
- the same name, type, class, time to live, payload, and authoritative
- bit.
- """
- # Vary the name
- self._equalityTest(
- dns.RRHeader('example.com', payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.org', payload=dns.Record_A('1.2.3.4')))
-
- # Vary the payload
- self._equalityTest(
- dns.RRHeader('example.com', payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', payload=dns.Record_A('1.2.3.5')))
-
- # Vary the type. Leave the payload as None so that we don't have to
- # provide non-equal values.
- self._equalityTest(
- dns.RRHeader('example.com', dns.A),
- dns.RRHeader('example.com', dns.A),
- dns.RRHeader('example.com', dns.MX))
-
- # Probably not likely to come up. Most people use the internet.
- self._equalityTest(
- dns.RRHeader('example.com', cls=dns.IN, payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', cls=dns.IN, payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', cls=dns.CS, payload=dns.Record_A('1.2.3.4')))
-
- # Vary the ttl
- self._equalityTest(
- dns.RRHeader('example.com', ttl=60, payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', ttl=60, payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', ttl=120, payload=dns.Record_A('1.2.3.4')))
-
- # Vary the auth bit
- self._equalityTest(
- dns.RRHeader('example.com', auth=1, payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', auth=1, payload=dns.Record_A('1.2.3.4')),
- dns.RRHeader('example.com', auth=0, payload=dns.Record_A('1.2.3.4')))
-
-
- def test_ns(self):
- """
- Two L{dns.Record_NS} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_NS)
-
-
- def test_md(self):
- """
- Two L{dns.Record_MD} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_MD)
-
-
- def test_mf(self):
- """
- Two L{dns.Record_MF} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_MF)
-
-
- def test_cname(self):
- """
- Two L{dns.Record_CNAME} instances compare equal if and only if they
- have the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_CNAME)
-
-
- def test_mb(self):
- """
- Two L{dns.Record_MB} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_MB)
-
-
- def test_mg(self):
- """
- Two L{dns.Record_MG} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_MG)
-
-
- def test_mr(self):
- """
- Two L{dns.Record_MR} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_MR)
-
-
- def test_ptr(self):
- """
- Two L{dns.Record_PTR} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_PTR)
-
-
- def test_dname(self):
- """
- Two L{dns.Record_MD} instances compare equal if and only if they have
- the same name and TTL.
- """
- self._simpleEqualityTest(dns.Record_DNAME)
-
-
- def test_a(self):
- """
- Two L{dns.Record_A} instances compare equal if and only if they have
- the same address and TTL.
- """
- # Vary the TTL
- self._equalityTest(
- dns.Record_A('1.2.3.4', 5),
- dns.Record_A('1.2.3.4', 5),
- dns.Record_A('1.2.3.4', 6))
- # Vary the address
- self._equalityTest(
- dns.Record_A('1.2.3.4', 5),
- dns.Record_A('1.2.3.4', 5),
- dns.Record_A('1.2.3.5', 5))
-
-
- def test_soa(self):
- """
- Two L{dns.Record_SOA} instances compare equal if and only if they have
- the same mname, rname, serial, refresh, minimum, expire, retry, and
- ttl.
- """
- # Vary the mname
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('xname', 'rname', 123, 456, 789, 10, 20, 30))
- # Vary the rname
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'xname', 123, 456, 789, 10, 20, 30))
- # Vary the serial
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 1, 456, 789, 10, 20, 30))
- # Vary the refresh
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 1, 789, 10, 20, 30))
- # Vary the minimum
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 1, 10, 20, 30))
- # Vary the expire
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 1, 20, 30))
- # Vary the retry
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 1, 30))
- # Vary the ttl
- self._equalityTest(
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'rname', 123, 456, 789, 10, 20, 30),
- dns.Record_SOA('mname', 'xname', 123, 456, 789, 10, 20, 1))
-
-
- def test_null(self):
- """
- Two L{dns.Record_NULL} instances compare equal if and only if they have
- the same payload and ttl.
- """
- # Vary the payload
- self._equalityTest(
- dns.Record_NULL('foo bar', 10),
- dns.Record_NULL('foo bar', 10),
- dns.Record_NULL('bar foo', 10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_NULL('foo bar', 10),
- dns.Record_NULL('foo bar', 10),
- dns.Record_NULL('foo bar', 100))
-
-
- def test_wks(self):
- """
- Two L{dns.Record_WKS} instances compare equal if and only if they have
- the same address, protocol, map, and ttl.
- """
- # Vary the address
- self._equalityTest(
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('4.3.2.1', 1, 'foo', 2))
- # Vary the protocol
- self._equalityTest(
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 100, 'foo', 2))
- # Vary the map
- self._equalityTest(
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 1, 'bar', 2))
- # Vary the ttl
- self._equalityTest(
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
- dns.Record_WKS('1.2.3.4', 1, 'foo', 200))
-
-
- def test_aaaa(self):
- """
- Two L{dns.Record_AAAA} instances compare equal if and only if they have
- the same address and ttl.
- """
- # Vary the address
- self._equalityTest(
- dns.Record_AAAA('1::2', 1),
- dns.Record_AAAA('1::2', 1),
- dns.Record_AAAA('2::1', 1))
- # Vary the ttl
- self._equalityTest(
- dns.Record_AAAA('1::2', 1),
- dns.Record_AAAA('1::2', 1),
- dns.Record_AAAA('1::2', 10))
-
-
- def test_a6(self):
- """
- Two L{dns.Record_A6} instances compare equal if and only if they have
- the same prefix, prefix length, suffix, and ttl.
- """
- # Note, A6 is crazy, I'm not sure these values are actually legal.
- # Hopefully that doesn't matter for this test. -exarkun
-
- # Vary the prefix length
- self._equalityTest(
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(32, '::abcd', 'example.com', 10))
- # Vary the suffix
- self._equalityTest(
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd:0', 'example.com', 10))
- # Vary the prefix
- self._equalityTest(
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd', 'example.org', 10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd', 'example.com', 10),
- dns.Record_A6(16, '::abcd', 'example.com', 100))
-
-
- def test_srv(self):
- """
- Two L{dns.Record_SRV} instances compare equal if and only if they have
- the same priority, weight, port, target, and ttl.
- """
- # Vary the priority
- self._equalityTest(
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(100, 20, 30, 'example.com', 40))
- # Vary the weight
- self._equalityTest(
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 200, 30, 'example.com', 40))
- # Vary the port
- self._equalityTest(
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 300, 'example.com', 40))
- # Vary the target
- self._equalityTest(
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.org', 40))
- # Vary the ttl
- self._equalityTest(
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.com', 40),
- dns.Record_SRV(10, 20, 30, 'example.com', 400))
-
-
- def test_naptr(self):
- """
- Two L{dns.Record_NAPTR} instances compare equal if and only if they
- have the same order, preference, flags, service, regexp, replacement,
- and ttl.
- """
- # Vary the order
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(2, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12))
- # Vary the preference
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 3, "u", "sip+E2U", "/foo/bar/", "baz", 12))
- # Vary the flags
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "p", "sip+E2U", "/foo/bar/", "baz", 12))
- # Vary the service
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "http", "/foo/bar/", "baz", 12))
- # Vary the regexp
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/bar/foo/", "baz", 12))
- # Vary the replacement
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/bar/foo/", "quux", 12))
- # Vary the ttl
- self._equalityTest(
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/foo/bar/", "baz", 12),
- dns.Record_NAPTR(1, 2, "u", "sip+E2U", "/bar/foo/", "baz", 5))
-
-
- def test_afsdb(self):
- """
- Two L{dns.Record_AFSDB} instances compare equal if and only if they
- have the same subtype, hostname, and ttl.
- """
- # Vary the subtype
- self._equalityTest(
- dns.Record_AFSDB(1, 'example.com', 2),
- dns.Record_AFSDB(1, 'example.com', 2),
- dns.Record_AFSDB(2, 'example.com', 2))
- # Vary the hostname
- self._equalityTest(
- dns.Record_AFSDB(1, 'example.com', 2),
- dns.Record_AFSDB(1, 'example.com', 2),
- dns.Record_AFSDB(1, 'example.org', 2))
- # Vary the ttl
- self._equalityTest(
- dns.Record_AFSDB(1, 'example.com', 2),
- dns.Record_AFSDB(1, 'example.com', 2),
- dns.Record_AFSDB(1, 'example.com', 3))
-
-
- def test_rp(self):
- """
- Two L{Record_RP} instances compare equal if and only if they have the
- same mbox, txt, and ttl.
- """
- # Vary the mbox
- self._equalityTest(
- dns.Record_RP('alice.example.com', 'alice is nice', 10),
- dns.Record_RP('alice.example.com', 'alice is nice', 10),
- dns.Record_RP('bob.example.com', 'alice is nice', 10))
- # Vary the txt
- self._equalityTest(
- dns.Record_RP('alice.example.com', 'alice is nice', 10),
- dns.Record_RP('alice.example.com', 'alice is nice', 10),
- dns.Record_RP('alice.example.com', 'alice is not nice', 10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_RP('alice.example.com', 'alice is nice', 10),
- dns.Record_RP('alice.example.com', 'alice is nice', 10),
- dns.Record_RP('alice.example.com', 'alice is nice', 100))
-
-
- def test_hinfo(self):
- """
- Two L{dns.Record_HINFO} instances compare equal if and only if they
- have the same cpu, os, and ttl.
- """
- # Vary the cpu
- self._equalityTest(
- dns.Record_HINFO('x86-64', 'plan9', 10),
- dns.Record_HINFO('x86-64', 'plan9', 10),
- dns.Record_HINFO('i386', 'plan9', 10))
- # Vary the os
- self._equalityTest(
- dns.Record_HINFO('x86-64', 'plan9', 10),
- dns.Record_HINFO('x86-64', 'plan9', 10),
- dns.Record_HINFO('x86-64', 'plan11', 10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_HINFO('x86-64', 'plan9', 10),
- dns.Record_HINFO('x86-64', 'plan9', 10),
- dns.Record_HINFO('x86-64', 'plan9', 100))
-
-
- def test_minfo(self):
- """
- Two L{dns.Record_MINFO} instances compare equal if and only if they
- have the same rmailbx, emailbx, and ttl.
- """
- # Vary the rmailbx
- self._equalityTest(
- dns.Record_MINFO('rmailbox', 'emailbox', 10),
- dns.Record_MINFO('rmailbox', 'emailbox', 10),
- dns.Record_MINFO('someplace', 'emailbox', 10))
- # Vary the emailbx
- self._equalityTest(
- dns.Record_MINFO('rmailbox', 'emailbox', 10),
- dns.Record_MINFO('rmailbox', 'emailbox', 10),
- dns.Record_MINFO('rmailbox', 'something', 10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_MINFO('rmailbox', 'emailbox', 10),
- dns.Record_MINFO('rmailbox', 'emailbox', 10),
- dns.Record_MINFO('rmailbox', 'emailbox', 100))
-
-
- def test_mx(self):
- """
- Two L{dns.Record_MX} instances compare equal if and only if they have
- the same preference, name, and ttl.
- """
- # Vary the preference
- self._equalityTest(
- dns.Record_MX(10, 'example.org', 20),
- dns.Record_MX(10, 'example.org', 20),
- dns.Record_MX(100, 'example.org', 20))
- # Vary the name
- self._equalityTest(
- dns.Record_MX(10, 'example.org', 20),
- dns.Record_MX(10, 'example.org', 20),
- dns.Record_MX(10, 'example.net', 20))
- # Vary the ttl
- self._equalityTest(
- dns.Record_MX(10, 'example.org', 20),
- dns.Record_MX(10, 'example.org', 20),
- dns.Record_MX(10, 'example.org', 200))
-
-
- def test_txt(self):
- """
- Two L{dns.Record_TXT} instances compare equal if and only if they have
- the same data and ttl.
- """
- # Vary the length of the data
- self._equalityTest(
- dns.Record_TXT('foo', 'bar', ttl=10),
- dns.Record_TXT('foo', 'bar', ttl=10),
- dns.Record_TXT('foo', 'bar', 'baz', ttl=10))
- # Vary the value of the data
- self._equalityTest(
- dns.Record_TXT('foo', 'bar', ttl=10),
- dns.Record_TXT('foo', 'bar', ttl=10),
- dns.Record_TXT('bar', 'foo', ttl=10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_TXT('foo', 'bar', ttl=10),
- dns.Record_TXT('foo', 'bar', ttl=10),
- dns.Record_TXT('foo', 'bar', ttl=100))
-
-
- def test_spf(self):
- """
- L{dns.Record_SPF} instances compare equal if and only if they have the
- same data and ttl.
- """
- # Vary the length of the data
- self._equalityTest(
- dns.Record_SPF('foo', 'bar', ttl=10),
- dns.Record_SPF('foo', 'bar', ttl=10),
- dns.Record_SPF('foo', 'bar', 'baz', ttl=10))
- # Vary the value of the data
- self._equalityTest(
- dns.Record_SPF('foo', 'bar', ttl=10),
- dns.Record_SPF('foo', 'bar', ttl=10),
- dns.Record_SPF('bar', 'foo', ttl=10))
- # Vary the ttl
- self._equalityTest(
- dns.Record_SPF('foo', 'bar', ttl=10),
- dns.Record_SPF('foo', 'bar', ttl=10),
- dns.Record_SPF('foo', 'bar', ttl=100))
-
-
- def test_unknown(self):
- """
- L{dns.UnknownRecord} instances compare equal if and only if they have
- the same data and ttl.
- """
- # Vary the length of the data
- self._equalityTest(
- dns.UnknownRecord('foo', ttl=10),
- dns.UnknownRecord('foo', ttl=10),
- dns.UnknownRecord('foobar', ttl=10))
- # Vary the value of the data
- self._equalityTest(
- dns.UnknownRecord('foo', ttl=10),
- dns.UnknownRecord('foo', ttl=10),
- dns.UnknownRecord('bar', ttl=10))
- # Vary the ttl
- self._equalityTest(
- dns.UnknownRecord('foo', ttl=10),
- dns.UnknownRecord('foo', ttl=10),
- dns.UnknownRecord('foo', ttl=100))
-
-
-
-class RRHeaderTests(unittest.TestCase):
- """
- Tests for L{twisted.names.dns.RRHeader}.
- """
-
- def test_negativeTTL(self):
- """
- Attempting to create a L{dns.RRHeader} instance with a negative TTL
- causes L{ValueError} to be raised.
- """
- self.assertRaises(
- ValueError, dns.RRHeader, "example.com", dns.A,
- dns.IN, -1, dns.Record_A("127.0.0.1"))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_hosts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_hosts.py
deleted file mode 100755
index d4cdb698..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_hosts.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the I{hosts(5)}-based resolver, L{twisted.names.hosts}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.python.filepath import FilePath
-from twisted.internet.defer import gatherResults
-
-from twisted.names.dns import (
- A, AAAA, IN, DomainError, RRHeader, Query, Record_A, Record_AAAA)
-from twisted.names.hosts import Resolver, searchFileFor, searchFileForAll
-
-
-class SearchHostsFileTests(TestCase):
- """
- Tests for L{searchFileFor}, a helper which finds the first address for a
- particular hostname in a I{hosts(5)}-style file.
- """
- def test_findAddress(self):
- """
- If there is an IPv4 address for the hostname passed to
- L{searchFileFor}, it is returned.
- """
- hosts = FilePath(self.mktemp())
- hosts.setContent(
- "10.2.3.4 foo.example.com\n")
- self.assertEqual(
- "10.2.3.4", searchFileFor(hosts.path, "foo.example.com"))
-
-
- def test_notFoundAddress(self):
- """
- If there is no address information for the hostname passed to
- L{searchFileFor}, C{None} is returned.
- """
- hosts = FilePath(self.mktemp())
- hosts.setContent(
- "10.2.3.4 foo.example.com\n")
- self.assertIdentical(
- None, searchFileFor(hosts.path, "bar.example.com"))
-
-
- def test_firstAddress(self):
- """
- The first address associated with the given hostname is returned.
- """
- hosts = FilePath(self.mktemp())
- hosts.setContent(
- "::1 foo.example.com\n"
- "10.1.2.3 foo.example.com\n"
- "fe80::21b:fcff:feee:5a1d foo.example.com\n")
- self.assertEqual(
- "::1", searchFileFor(hosts.path, "foo.example.com"))
-
-
- def test_searchFileForAliases(self):
- """
- For a host with a canonical name and one or more aliases,
- L{searchFileFor} can find an address given any of the names.
- """
- hosts = FilePath(self.mktemp())
- hosts.setContent(
- "127.0.1.1 helmut.example.org helmut\n"
- "# a comment\n"
- "::1 localhost ip6-localhost ip6-loopback\n")
- self.assertEqual(searchFileFor(hosts.path, 'helmut'), '127.0.1.1')
- self.assertEqual(
- searchFileFor(hosts.path, 'helmut.example.org'), '127.0.1.1')
- self.assertEqual(searchFileFor(hosts.path, 'ip6-localhost'), '::1')
- self.assertEqual(searchFileFor(hosts.path, 'ip6-loopback'), '::1')
- self.assertEqual(searchFileFor(hosts.path, 'localhost'), '::1')
-
-
-
-class SearchHostsFileForAllTests(TestCase):
- """
- Tests for L{searchFileForAll}, a helper which finds all addresses for a
- particular hostname in a I{hosts(5)}-style file.
- """
- def test_allAddresses(self):
- """
- L{searchFileForAll} returns a list of all addresses associated with the
- name passed to it.
- """
- hosts = FilePath(self.mktemp())
- hosts.setContent(
- "127.0.0.1 foobar.example.com\n"
- "127.0.0.2 foobar.example.com\n"
- "::1 foobar.example.com\n")
- self.assertEqual(
- ["127.0.0.1", "127.0.0.2", "::1"],
- searchFileForAll(hosts, "foobar.example.com"))
-
-
- def test_caseInsensitively(self):
- """
- L{searchFileForAll} searches for names case-insensitively.
- """
- hosts = FilePath(self.mktemp())
- hosts.setContent("127.0.0.1 foobar.EXAMPLE.com\n")
- self.assertEqual(
- ["127.0.0.1"], searchFileForAll(hosts, "FOOBAR.example.com"))
-
-
- def test_readError(self):
- """
- If there is an error reading the contents of the hosts file,
- L{searchFileForAll} returns an empty list.
- """
- self.assertEqual(
- [], searchFileForAll(FilePath(self.mktemp()), "example.com"))
-
-
-
-class HostsTestCase(TestCase):
- """
- Tests for the I{hosts(5)}-based L{twisted.names.hosts.Resolver}.
- """
- def setUp(self):
- f = open('EtcHosts', 'w')
- f.write('''
-1.1.1.1 EXAMPLE EXAMPLE.EXAMPLETHING
-::2 mixed
-1.1.1.2 MIXED
-::1 ip6thingy
-1.1.1.3 multiple
-1.1.1.4 multiple
-::3 ip6-multiple
-::4 ip6-multiple
-''')
- f.close()
- self.ttl = 4200
- self.resolver = Resolver('EtcHosts', self.ttl)
-
- def testGetHostByName(self):
- data = [('EXAMPLE', '1.1.1.1'),
- ('EXAMPLE.EXAMPLETHING', '1.1.1.1'),
- ('MIXED', '1.1.1.2'),
- ]
- ds = [self.resolver.getHostByName(n).addCallback(self.assertEqual, ip)
- for n, ip in data]
- return gatherResults(ds)
-
-
- def test_lookupAddress(self):
- """
- L{hosts.Resolver.lookupAddress} returns a L{Deferred} which fires with A
- records from the hosts file.
- """
- d = self.resolver.lookupAddress('multiple')
- def resolved((results, authority, additional)):
- self.assertEqual(
- (RRHeader("multiple", A, IN, self.ttl,
- Record_A("1.1.1.3", self.ttl)),
- RRHeader("multiple", A, IN, self.ttl,
- Record_A("1.1.1.4", self.ttl))),
- results)
- d.addCallback(resolved)
- return d
-
-
- def test_lookupIPV6Address(self):
- """
- L{hosts.Resolver.lookupIPV6Address} returns a L{Deferred} which fires
- with AAAA records from the hosts file.
- """
- d = self.resolver.lookupIPV6Address('ip6-multiple')
- def resolved((results, authority, additional)):
- self.assertEqual(
- (RRHeader("ip6-multiple", AAAA, IN, self.ttl,
- Record_AAAA("::3", self.ttl)),
- RRHeader("ip6-multiple", AAAA, IN, self.ttl,
- Record_AAAA("::4", self.ttl))),
- results)
- d.addCallback(resolved)
- return d
-
-
- def test_lookupAllRecords(self):
- """
- L{hosts.Resolver.lookupAllRecords} returns a L{Deferred} which fires
- with A records from the hosts file.
- """
- d = self.resolver.lookupAllRecords('mixed')
- def resolved((results, authority, additional)):
- self.assertEqual(
- (RRHeader("mixed", A, IN, self.ttl,
- Record_A("1.1.1.2", self.ttl)),),
- results)
- d.addCallback(resolved)
- return d
-
-
- def testNotImplemented(self):
- return self.assertFailure(self.resolver.lookupMailExchange('EXAMPLE'),
- NotImplementedError)
-
- def testQuery(self):
- d = self.resolver.query(Query('EXAMPLE'))
- d.addCallback(lambda x: self.assertEqual(x[0][0].payload.dottedQuad(),
- '1.1.1.1'))
- return d
-
- def test_lookupAddressNotFound(self):
- """
- L{hosts.Resolver.lookupAddress} returns a L{Deferred} which fires with
- L{dns.DomainError} if the name passed in has no addresses in the hosts
- file.
- """
- return self.assertFailure(self.resolver.lookupAddress('foueoa'),
- DomainError)
-
- def test_lookupIPV6AddressNotFound(self):
- """
- Like L{test_lookupAddressNotFound}, but for
- L{hosts.Resolver.lookupIPV6Address}.
- """
- return self.assertFailure(self.resolver.lookupIPV6Address('foueoa'),
- DomainError)
-
- def test_lookupAllRecordsNotFound(self):
- """
- Like L{test_lookupAddressNotFound}, but for
- L{hosts.Resolver.lookupAllRecords}.
- """
- return self.assertFailure(self.resolver.lookupAllRecords('foueoa'),
- DomainError)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_names.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_names.py
deleted file mode 100755
index a5b20c1b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_names.py
+++ /dev/null
@@ -1,956 +0,0 @@
-# -*- test-case-name: twisted.names.test.test_names -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.names.
-"""
-
-import socket, operator, copy
-from StringIO import StringIO
-
-from twisted.trial import unittest
-
-from twisted.internet import reactor, defer, error
-from twisted.internet.task import Clock
-from twisted.internet.defer import succeed
-from twisted.names import client, server, common, authority, dns
-from twisted.python import failure
-from twisted.names.error import DNSFormatError, DNSServerError, DNSNameError
-from twisted.names.error import DNSNotImplementedError, DNSQueryRefusedError
-from twisted.names.error import DNSUnknownError
-from twisted.names.dns import EFORMAT, ESERVER, ENAME, ENOTIMP, EREFUSED
-from twisted.names.dns import Message
-from twisted.names.client import Resolver
-from twisted.names.secondary import (
- SecondaryAuthorityService, SecondaryAuthority)
-from twisted.names.test.test_client import StubPort
-
-from twisted.python.compat import reduce
-from twisted.test.proto_helpers import StringTransport, MemoryReactor
-
-def justPayload(results):
- return [r.payload for r in results[0]]
-
-class NoFileAuthority(authority.FileAuthority):
- def __init__(self, soa, records):
- # Yes, skip FileAuthority
- common.ResolverBase.__init__(self)
- self.soa, self.records = soa, records
-
-
-soa_record = dns.Record_SOA(
- mname = 'test-domain.com',
- rname = 'root.test-domain.com',
- serial = 100,
- refresh = 1234,
- minimum = 7654,
- expire = 19283784,
- retry = 15,
- ttl=1
- )
-
-reverse_soa = dns.Record_SOA(
- mname = '93.84.28.in-addr.arpa',
- rname = '93.84.28.in-addr.arpa',
- serial = 120,
- refresh = 54321,
- minimum = 382,
- expire = 11193983,
- retry = 30,
- ttl=3
- )
-
-my_soa = dns.Record_SOA(
- mname = 'my-domain.com',
- rname = 'postmaster.test-domain.com',
- serial = 130,
- refresh = 12345,
- minimum = 1,
- expire = 999999,
- retry = 100,
- )
-
-test_domain_com = NoFileAuthority(
- soa = ('test-domain.com', soa_record),
- records = {
- 'test-domain.com': [
- soa_record,
- dns.Record_A('127.0.0.1'),
- dns.Record_NS('39.28.189.39'),
- dns.Record_SPF('v=spf1 mx/30 mx:example.org/30 -all'),
- dns.Record_SPF('v=spf1 +mx a:\0colo', '.example.com/28 -all not valid'),
- dns.Record_MX(10, 'host.test-domain.com'),
- dns.Record_HINFO(os='Linux', cpu='A Fast One, Dontcha know'),
- dns.Record_CNAME('canonical.name.com'),
- dns.Record_MB('mailbox.test-domain.com'),
- dns.Record_MG('mail.group.someplace'),
- dns.Record_TXT('A First piece of Text', 'a SecoNd piece'),
- dns.Record_A6(0, 'ABCD::4321', ''),
- dns.Record_A6(12, '0:0069::0', 'some.network.tld'),
- dns.Record_A6(8, '0:5634:1294:AFCB:56AC:48EF:34C3:01FF', 'tra.la.la.net'),
- dns.Record_TXT('Some more text, haha! Yes. \0 Still here?'),
- dns.Record_MR('mail.redirect.or.whatever'),
- dns.Record_MINFO(rmailbx='r mail box', emailbx='e mail box'),
- dns.Record_AFSDB(subtype=1, hostname='afsdb.test-domain.com'),
- dns.Record_RP(mbox='whatever.i.dunno', txt='some.more.text'),
- dns.Record_WKS('12.54.78.12', socket.IPPROTO_TCP,
- '\x12\x01\x16\xfe\xc1\x00\x01'),
- dns.Record_NAPTR(100, 10, "u", "sip+E2U",
- "!^.*$!sip:information@domain.tld!"),
- dns.Record_AAAA('AF43:5634:1294:AFCB:56AC:48EF:34C3:01FF')],
- 'http.tcp.test-domain.com': [
- dns.Record_SRV(257, 16383, 43690, 'some.other.place.fool')
- ],
- 'host.test-domain.com': [
- dns.Record_A('123.242.1.5'),
- dns.Record_A('0.255.0.255'),
- ],
- 'host-two.test-domain.com': [
-#
-# Python bug
-# dns.Record_A('255.255.255.255'),
-#
- dns.Record_A('255.255.255.254'),
- dns.Record_A('0.0.0.0')
- ],
- 'cname.test-domain.com': [
- dns.Record_CNAME('test-domain.com')
- ],
- 'anothertest-domain.com': [
- dns.Record_A('1.2.3.4')],
- }
-)
-
-reverse_domain = NoFileAuthority(
- soa = ('93.84.28.in-addr.arpa', reverse_soa),
- records = {
- '123.93.84.28.in-addr.arpa': [
- dns.Record_PTR('test.host-reverse.lookup.com'),
- reverse_soa
- ]
- }
-)
-
-
-my_domain_com = NoFileAuthority(
- soa = ('my-domain.com', my_soa),
- records = {
- 'my-domain.com': [
- my_soa,
- dns.Record_A('1.2.3.4', ttl='1S'),
- dns.Record_NS('ns1.domain', ttl='2M'),
- dns.Record_NS('ns2.domain', ttl='3H'),
- dns.Record_SRV(257, 16383, 43690, 'some.other.place.fool', ttl='4D')
- ]
- }
- )
-
-
-class ServerDNSTestCase(unittest.TestCase):
- """
- Test cases for DNS server and client.
- """
-
- def setUp(self):
- self.factory = server.DNSServerFactory([
- test_domain_com, reverse_domain, my_domain_com
- ], verbose=2)
-
- p = dns.DNSDatagramProtocol(self.factory)
-
- while 1:
- listenerTCP = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
- # It's simpler to do the stop listening with addCleanup,
- # even though we might not end up using this TCP port in
- # the test (if the listenUDP below fails). Cleaning up
- # this TCP port sooner than "cleanup time" would mean
- # adding more code to keep track of the Deferred returned
- # by stopListening.
- self.addCleanup(listenerTCP.stopListening)
- port = listenerTCP.getHost().port
-
- try:
- listenerUDP = reactor.listenUDP(port, p, interface="127.0.0.1")
- except error.CannotListenError:
- pass
- else:
- self.addCleanup(listenerUDP.stopListening)
- break
-
- self.listenerTCP = listenerTCP
- self.listenerUDP = listenerUDP
- self.resolver = client.Resolver(servers=[('127.0.0.1', port)])
-
-
- def tearDown(self):
- """
- Clean up any server connections associated with the
- L{DNSServerFactory} created in L{setUp}
- """
- # It'd be great if DNSServerFactory had a method that
- # encapsulated this task. At least the necessary data is
- # available, though.
- for conn in self.factory.connections[:]:
- conn.transport.loseConnection()
-
-
- def namesTest(self, d, r):
- self.response = None
- def setDone(response):
- self.response = response
-
- def checkResults(ignored):
- if isinstance(self.response, failure.Failure):
- raise self.response
- results = justPayload(self.response)
- assert len(results) == len(r), "%s != %s" % (map(str, results), map(str, r))
- for rec in results:
- assert rec in r, "%s not in %s" % (rec, map(str, r))
-
- d.addBoth(setDone)
- d.addCallback(checkResults)
- return d
-
- def testAddressRecord1(self):
- """Test simple DNS 'A' record queries"""
- return self.namesTest(
- self.resolver.lookupAddress('test-domain.com'),
- [dns.Record_A('127.0.0.1', ttl=19283784)]
- )
-
-
- def testAddressRecord2(self):
- """Test DNS 'A' record queries with multiple answers"""
- return self.namesTest(
- self.resolver.lookupAddress('host.test-domain.com'),
- [dns.Record_A('123.242.1.5', ttl=19283784), dns.Record_A('0.255.0.255', ttl=19283784)]
- )
-
-
- def testAddressRecord3(self):
- """Test DNS 'A' record queries with edge cases"""
- return self.namesTest(
- self.resolver.lookupAddress('host-two.test-domain.com'),
- [dns.Record_A('255.255.255.254', ttl=19283784), dns.Record_A('0.0.0.0', ttl=19283784)]
- )
-
-
- def testAuthority(self):
- """Test DNS 'SOA' record queries"""
- return self.namesTest(
- self.resolver.lookupAuthority('test-domain.com'),
- [soa_record]
- )
-
-
- def testMailExchangeRecord(self):
- """Test DNS 'MX' record queries"""
- return self.namesTest(
- self.resolver.lookupMailExchange('test-domain.com'),
- [dns.Record_MX(10, 'host.test-domain.com', ttl=19283784)]
- )
-
-
- def testNameserver(self):
- """Test DNS 'NS' record queries"""
- return self.namesTest(
- self.resolver.lookupNameservers('test-domain.com'),
- [dns.Record_NS('39.28.189.39', ttl=19283784)]
- )
-
-
- def testHINFO(self):
- """Test DNS 'HINFO' record queries"""
- return self.namesTest(
- self.resolver.lookupHostInfo('test-domain.com'),
- [dns.Record_HINFO(os='Linux', cpu='A Fast One, Dontcha know', ttl=19283784)]
- )
-
- def testPTR(self):
- """Test DNS 'PTR' record queries"""
- return self.namesTest(
- self.resolver.lookupPointer('123.93.84.28.in-addr.arpa'),
- [dns.Record_PTR('test.host-reverse.lookup.com', ttl=11193983)]
- )
-
-
- def testCNAME(self):
- """Test DNS 'CNAME' record queries"""
- return self.namesTest(
- self.resolver.lookupCanonicalName('test-domain.com'),
- [dns.Record_CNAME('canonical.name.com', ttl=19283784)]
- )
-
- def testCNAMEAdditional(self):
- """Test additional processing for CNAME records"""
- return self.namesTest(
- self.resolver.lookupAddress('cname.test-domain.com'),
- [dns.Record_CNAME('test-domain.com', ttl=19283784), dns.Record_A('127.0.0.1', ttl=19283784)]
- )
-
- def testMB(self):
- """Test DNS 'MB' record queries"""
- return self.namesTest(
- self.resolver.lookupMailBox('test-domain.com'),
- [dns.Record_MB('mailbox.test-domain.com', ttl=19283784)]
- )
-
-
- def testMG(self):
- """Test DNS 'MG' record queries"""
- return self.namesTest(
- self.resolver.lookupMailGroup('test-domain.com'),
- [dns.Record_MG('mail.group.someplace', ttl=19283784)]
- )
-
-
- def testMR(self):
- """Test DNS 'MR' record queries"""
- return self.namesTest(
- self.resolver.lookupMailRename('test-domain.com'),
- [dns.Record_MR('mail.redirect.or.whatever', ttl=19283784)]
- )
-
-
- def testMINFO(self):
- """Test DNS 'MINFO' record queries"""
- return self.namesTest(
- self.resolver.lookupMailboxInfo('test-domain.com'),
- [dns.Record_MINFO(rmailbx='r mail box', emailbx='e mail box', ttl=19283784)]
- )
-
-
- def testSRV(self):
- """Test DNS 'SRV' record queries"""
- return self.namesTest(
- self.resolver.lookupService('http.tcp.test-domain.com'),
- [dns.Record_SRV(257, 16383, 43690, 'some.other.place.fool', ttl=19283784)]
- )
-
- def testAFSDB(self):
- """Test DNS 'AFSDB' record queries"""
- return self.namesTest(
- self.resolver.lookupAFSDatabase('test-domain.com'),
- [dns.Record_AFSDB(subtype=1, hostname='afsdb.test-domain.com', ttl=19283784)]
- )
-
-
- def testRP(self):
- """Test DNS 'RP' record queries"""
- return self.namesTest(
- self.resolver.lookupResponsibility('test-domain.com'),
- [dns.Record_RP(mbox='whatever.i.dunno', txt='some.more.text', ttl=19283784)]
- )
-
-
- def testTXT(self):
- """Test DNS 'TXT' record queries"""
- return self.namesTest(
- self.resolver.lookupText('test-domain.com'),
- [dns.Record_TXT('A First piece of Text', 'a SecoNd piece', ttl=19283784),
- dns.Record_TXT('Some more text, haha! Yes. \0 Still here?', ttl=19283784)]
- )
-
-
- def test_spf(self):
- """
- L{DNSServerFactory} can serve I{SPF} resource records.
- """
- return self.namesTest(
- self.resolver.lookupSenderPolicy('test-domain.com'),
- [dns.Record_SPF('v=spf1 mx/30 mx:example.org/30 -all', ttl=19283784),
- dns.Record_SPF('v=spf1 +mx a:\0colo', '.example.com/28 -all not valid', ttl=19283784)]
- )
-
-
- def testWKS(self):
- """Test DNS 'WKS' record queries"""
- return self.namesTest(
- self.resolver.lookupWellKnownServices('test-domain.com'),
- [dns.Record_WKS('12.54.78.12', socket.IPPROTO_TCP, '\x12\x01\x16\xfe\xc1\x00\x01', ttl=19283784)]
- )
-
-
- def testSomeRecordsWithTTLs(self):
- result_soa = copy.copy(my_soa)
- result_soa.ttl = my_soa.expire
- return self.namesTest(
- self.resolver.lookupAllRecords('my-domain.com'),
- [result_soa,
- dns.Record_A('1.2.3.4', ttl='1S'),
- dns.Record_NS('ns1.domain', ttl='2M'),
- dns.Record_NS('ns2.domain', ttl='3H'),
- dns.Record_SRV(257, 16383, 43690, 'some.other.place.fool', ttl='4D')]
- )
-
-
- def testAAAA(self):
- """Test DNS 'AAAA' record queries (IPv6)"""
- return self.namesTest(
- self.resolver.lookupIPV6Address('test-domain.com'),
- [dns.Record_AAAA('AF43:5634:1294:AFCB:56AC:48EF:34C3:01FF', ttl=19283784)]
- )
-
- def testA6(self):
- """Test DNS 'A6' record queries (IPv6)"""
- return self.namesTest(
- self.resolver.lookupAddress6('test-domain.com'),
- [dns.Record_A6(0, 'ABCD::4321', '', ttl=19283784),
- dns.Record_A6(12, '0:0069::0', 'some.network.tld', ttl=19283784),
- dns.Record_A6(8, '0:5634:1294:AFCB:56AC:48EF:34C3:01FF', 'tra.la.la.net', ttl=19283784)]
- )
-
-
- def test_zoneTransfer(self):
- """
- Test DNS 'AXFR' queries (Zone transfer)
- """
- default_ttl = soa_record.expire
- results = [copy.copy(r) for r in reduce(operator.add, test_domain_com.records.values())]
- for r in results:
- if r.ttl is None:
- r.ttl = default_ttl
- return self.namesTest(
- self.resolver.lookupZone('test-domain.com').addCallback(lambda r: (r[0][:-1],)),
- results
- )
-
-
- def testSimilarZonesDontInterfere(self):
- """Tests that unrelated zones don't mess with each other."""
- return self.namesTest(
- self.resolver.lookupAddress("anothertest-domain.com"),
- [dns.Record_A('1.2.3.4', ttl=19283784)]
- )
-
-
- def test_NAPTR(self):
- """
- Test DNS 'NAPTR' record queries.
- """
- return self.namesTest(
- self.resolver.lookupNamingAuthorityPointer('test-domain.com'),
- [dns.Record_NAPTR(100, 10, "u", "sip+E2U",
- "!^.*$!sip:information@domain.tld!",
- ttl=19283784)])
-
-
-
-class DNSServerFactoryTests(unittest.TestCase):
- """
- Tests for L{server.DNSServerFactory}.
- """
- def _messageReceivedTest(self, methodName, message):
- """
- Assert that the named method is called with the given message when
- it is passed to L{DNSServerFactory.messageReceived}.
- """
- # Make it appear to have some queries so that
- # DNSServerFactory.allowQuery allows it.
- message.queries = [None]
-
- receivedMessages = []
- def fakeHandler(message, protocol, address):
- receivedMessages.append((message, protocol, address))
-
- class FakeProtocol(object):
- def writeMessage(self, message):
- pass
-
- protocol = FakeProtocol()
- factory = server.DNSServerFactory(None)
- setattr(factory, methodName, fakeHandler)
- factory.messageReceived(message, protocol)
- self.assertEqual(receivedMessages, [(message, protocol, None)])
-
-
- def test_notifyMessageReceived(self):
- """
- L{DNSServerFactory.messageReceived} passes messages with an opcode
- of C{OP_NOTIFY} on to L{DNSServerFactory.handleNotify}.
- """
- # RFC 1996, section 4.5
- opCode = 4
- self._messageReceivedTest('handleNotify', Message(opCode=opCode))
-
-
- def test_updateMessageReceived(self):
- """
- L{DNSServerFactory.messageReceived} passes messages with an opcode
- of C{OP_UPDATE} on to L{DNSServerFactory.handleOther}.
-
- This may change if the implementation ever covers update messages.
- """
- # RFC 2136, section 1.3
- opCode = 5
- self._messageReceivedTest('handleOther', Message(opCode=opCode))
-
-
- def test_connectionTracking(self):
- """
- The C{connectionMade} and C{connectionLost} methods of
- L{DNSServerFactory} cooperate to keep track of all
- L{DNSProtocol} objects created by a factory which are
- connected.
- """
- protoA, protoB = object(), object()
- factory = server.DNSServerFactory()
- factory.connectionMade(protoA)
- self.assertEqual(factory.connections, [protoA])
- factory.connectionMade(protoB)
- self.assertEqual(factory.connections, [protoA, protoB])
- factory.connectionLost(protoA)
- self.assertEqual(factory.connections, [protoB])
- factory.connectionLost(protoB)
- self.assertEqual(factory.connections, [])
-
-
-class HelperTestCase(unittest.TestCase):
- def testSerialGenerator(self):
- f = self.mktemp()
- a = authority.getSerial(f)
- for i in range(20):
- b = authority.getSerial(f)
- self.failUnless(a < b)
- a = b
-
-
-class AXFRTest(unittest.TestCase):
- def setUp(self):
- self.results = None
- self.d = defer.Deferred()
- self.d.addCallback(self._gotResults)
- self.controller = client.AXFRController('fooby.com', self.d)
-
- self.soa = dns.RRHeader(name='fooby.com', type=dns.SOA, cls=dns.IN, ttl=86400, auth=False,
- payload=dns.Record_SOA(mname='fooby.com',
- rname='hooj.fooby.com',
- serial=100,
- refresh=200,
- retry=300,
- expire=400,
- minimum=500,
- ttl=600))
-
- self.records = [
- self.soa,
- dns.RRHeader(name='fooby.com', type=dns.NS, cls=dns.IN, ttl=700, auth=False,
- payload=dns.Record_NS(name='ns.twistedmatrix.com', ttl=700)),
-
- dns.RRHeader(name='fooby.com', type=dns.MX, cls=dns.IN, ttl=700, auth=False,
- payload=dns.Record_MX(preference=10, exchange='mail.mv3d.com', ttl=700)),
-
- dns.RRHeader(name='fooby.com', type=dns.A, cls=dns.IN, ttl=700, auth=False,
- payload=dns.Record_A(address='64.123.27.105', ttl=700)),
- self.soa
- ]
-
- def _makeMessage(self):
- # hooray they all have the same message format
- return dns.Message(id=999, answer=1, opCode=0, recDes=0, recAv=1, auth=1, rCode=0, trunc=0, maxSize=0)
-
- def testBindAndTNamesStyle(self):
- # Bind style = One big single message
- m = self._makeMessage()
- m.queries = [dns.Query('fooby.com', dns.AXFR, dns.IN)]
- m.answers = self.records
- self.controller.messageReceived(m, None)
- self.assertEqual(self.results, self.records)
-
- def _gotResults(self, result):
- self.results = result
-
- def testDJBStyle(self):
- # DJB style = message per record
- records = self.records[:]
- while records:
- m = self._makeMessage()
- m.queries = [] # DJB *doesn't* specify any queries.. hmm..
- m.answers = [records.pop(0)]
- self.controller.messageReceived(m, None)
- self.assertEqual(self.results, self.records)
-
-class FakeDNSDatagramProtocol(object):
- def __init__(self):
- self.queries = []
- self.transport = StubPort()
-
- def query(self, address, queries, timeout=10, id=None):
- self.queries.append((address, queries, timeout, id))
- return defer.fail(dns.DNSQueryTimeoutError(queries))
-
- def removeResend(self, id):
- # Ignore this for the time being.
- pass
-
-class RetryLogic(unittest.TestCase):
- testServers = [
- '1.2.3.4',
- '4.3.2.1',
- 'a.b.c.d',
- 'z.y.x.w']
-
- def testRoundRobinBackoff(self):
- addrs = [(x, 53) for x in self.testServers]
- r = client.Resolver(resolv=None, servers=addrs)
- r.protocol = proto = FakeDNSDatagramProtocol()
- return r.lookupAddress("foo.example.com"
- ).addCallback(self._cbRoundRobinBackoff
- ).addErrback(self._ebRoundRobinBackoff, proto
- )
-
- def _cbRoundRobinBackoff(self, result):
- raise unittest.FailTest("Lookup address succeeded, should have timed out")
-
- def _ebRoundRobinBackoff(self, failure, fakeProto):
- failure.trap(defer.TimeoutError)
-
- # Assert that each server is tried with a particular timeout
- # before the timeout is increased and the attempts are repeated.
-
- for t in (1, 3, 11, 45):
- tries = fakeProto.queries[:len(self.testServers)]
- del fakeProto.queries[:len(self.testServers)]
-
- tries.sort()
- expected = list(self.testServers)
- expected.sort()
-
- for ((addr, query, timeout, id), expectedAddr) in zip(tries, expected):
- self.assertEqual(addr, (expectedAddr, 53))
- self.assertEqual(timeout, t)
-
- self.failIf(fakeProto.queries)
-
-class ResolvConfHandling(unittest.TestCase):
- def testMissing(self):
- resolvConf = self.mktemp()
- r = client.Resolver(resolv=resolvConf)
- self.assertEqual(r.dynServers, [('127.0.0.1', 53)])
- r._parseCall.cancel()
-
- def testEmpty(self):
- resolvConf = self.mktemp()
- fObj = file(resolvConf, 'w')
- fObj.close()
- r = client.Resolver(resolv=resolvConf)
- self.assertEqual(r.dynServers, [('127.0.0.1', 53)])
- r._parseCall.cancel()
-
-
-
-class FilterAnswersTests(unittest.TestCase):
- """
- Test L{twisted.names.client.Resolver.filterAnswers}'s handling of various
- error conditions it might encounter.
- """
- def setUp(self):
- # Create a resolver pointed at an invalid server - we won't be hitting
- # the network in any of these tests.
- self.resolver = Resolver(servers=[('0.0.0.0', 0)])
-
-
- def test_truncatedMessage(self):
- """
- Test that a truncated message results in an equivalent request made via
- TCP.
- """
- m = Message(trunc=True)
- m.addQuery('example.com')
-
- def queryTCP(queries):
- self.assertEqual(queries, m.queries)
- response = Message()
- response.answers = ['answer']
- response.authority = ['authority']
- response.additional = ['additional']
- return succeed(response)
- self.resolver.queryTCP = queryTCP
- d = self.resolver.filterAnswers(m)
- d.addCallback(
- self.assertEqual, (['answer'], ['authority'], ['additional']))
- return d
-
-
- def _rcodeTest(self, rcode, exc):
- m = Message(rCode=rcode)
- err = self.resolver.filterAnswers(m)
- err.trap(exc)
-
-
- def test_formatError(self):
- """
- Test that a message with a result code of C{EFORMAT} results in a
- failure wrapped around L{DNSFormatError}.
- """
- return self._rcodeTest(EFORMAT, DNSFormatError)
-
-
- def test_serverError(self):
- """
- Like L{test_formatError} but for C{ESERVER}/L{DNSServerError}.
- """
- return self._rcodeTest(ESERVER, DNSServerError)
-
-
- def test_nameError(self):
- """
- Like L{test_formatError} but for C{ENAME}/L{DNSNameError}.
- """
- return self._rcodeTest(ENAME, DNSNameError)
-
-
- def test_notImplementedError(self):
- """
- Like L{test_formatError} but for C{ENOTIMP}/L{DNSNotImplementedError}.
- """
- return self._rcodeTest(ENOTIMP, DNSNotImplementedError)
-
-
- def test_refusedError(self):
- """
- Like L{test_formatError} but for C{EREFUSED}/L{DNSQueryRefusedError}.
- """
- return self._rcodeTest(EREFUSED, DNSQueryRefusedError)
-
-
- def test_refusedErrorUnknown(self):
- """
- Like L{test_formatError} but for an unrecognized error code and
- L{DNSUnknownError}.
- """
- return self._rcodeTest(EREFUSED + 1, DNSUnknownError)
-
-
-
-class AuthorityTests(unittest.TestCase):
- """
- Tests for the basic response record selection code in L{FileAuthority}
- (independent of its fileness).
- """
- def test_recordMissing(self):
- """
- If a L{FileAuthority} has a zone which includes an I{NS} record for a
- particular name and that authority is asked for another record for the
- same name which does not exist, the I{NS} record is not included in the
- authority section of the response.
- """
- authority = NoFileAuthority(
- soa=(str(soa_record.mname), soa_record),
- records={
- str(soa_record.mname): [
- soa_record,
- dns.Record_NS('1.2.3.4'),
- ]})
- d = authority.lookupAddress(str(soa_record.mname))
- result = []
- d.addCallback(result.append)
- answer, authority, additional = result[0]
- self.assertEqual(answer, [])
- self.assertEqual(
- authority, [
- dns.RRHeader(
- str(soa_record.mname), soa_record.TYPE,
- ttl=soa_record.expire, payload=soa_record,
- auth=True)])
- self.assertEqual(additional, [])
-
-
- def _referralTest(self, method):
- """
- Create an authority and make a request against it. Then verify that the
- result is a referral, including no records in the answers or additional
- sections, but with an I{NS} record in the authority section.
- """
- subdomain = 'example.' + str(soa_record.mname)
- nameserver = dns.Record_NS('1.2.3.4')
- authority = NoFileAuthority(
- soa=(str(soa_record.mname), soa_record),
- records={
- subdomain: [
- nameserver,
- ]})
- d = getattr(authority, method)(subdomain)
- result = []
- d.addCallback(result.append)
- answer, authority, additional = result[0]
- self.assertEqual(answer, [])
- self.assertEqual(
- authority, [dns.RRHeader(
- subdomain, dns.NS, ttl=soa_record.expire,
- payload=nameserver, auth=False)])
- self.assertEqual(additional, [])
-
-
- def test_referral(self):
- """
- When an I{NS} record is found for a child zone, it is included in the
- authority section of the response. It is marked as non-authoritative if
- the authority is not also authoritative for the child zone (RFC 2181,
- section 6.1).
- """
- self._referralTest('lookupAddress')
-
-
- def test_allRecordsReferral(self):
- """
- A referral is also generated for a request of type C{ALL_RECORDS}.
- """
- self._referralTest('lookupAllRecords')
-
-
-
-class NoInitialResponseTestCase(unittest.TestCase):
-
- def test_no_answer(self):
- """
- If a request returns a L{dns.NS} response, but we can't connect to the
- given server, the request fails with the error returned at connection.
- """
-
- def query(self, *args):
- # Pop from the message list, so that it blows up if more queries
- # are run than expected.
- return succeed(messages.pop(0))
-
- def queryProtocol(self, *args, **kwargs):
- return defer.fail(socket.gaierror("Couldn't connect"))
-
- resolver = Resolver(servers=[('0.0.0.0', 0)])
- resolver._query = query
- messages = []
- # Let's patch dns.DNSDatagramProtocol.query, as there is no easy way to
- # customize it.
- self.patch(dns.DNSDatagramProtocol, "query", queryProtocol)
-
- records = [
- dns.RRHeader(name='fooba.com', type=dns.NS, cls=dns.IN, ttl=700,
- auth=False,
- payload=dns.Record_NS(name='ns.twistedmatrix.com',
- ttl=700))]
- m = dns.Message(id=999, answer=1, opCode=0, recDes=0, recAv=1, auth=1,
- rCode=0, trunc=0, maxSize=0)
- m.answers = records
- messages.append(m)
- return self.assertFailure(
- resolver.getHostByName("fooby.com"), socket.gaierror)
-
-
-
-class SecondaryAuthorityServiceTests(unittest.TestCase):
- """
- Tests for L{SecondaryAuthorityService}, a service which keeps one or more
- authorities up to date by doing zone transfers from a master.
- """
-
- def test_constructAuthorityFromHost(self):
- """
- L{SecondaryAuthorityService} can be constructed with a C{str} giving a
- master server address and several domains, causing the creation of a
- secondary authority for each domain and that master server address and
- the default DNS port.
- """
- primary = '192.168.1.2'
- service = SecondaryAuthorityService(
- primary, ['example.com', 'example.org'])
- self.assertEqual(service.primary, primary)
- self.assertEqual(service._port, 53)
-
- self.assertEqual(service.domains[0].primary, primary)
- self.assertEqual(service.domains[0]._port, 53)
- self.assertEqual(service.domains[0].domain, 'example.com')
-
- self.assertEqual(service.domains[1].primary, primary)
- self.assertEqual(service.domains[1]._port, 53)
- self.assertEqual(service.domains[1].domain, 'example.org')
-
-
- def test_constructAuthorityFromHostAndPort(self):
- """
- L{SecondaryAuthorityService.fromServerAddressAndDomains} constructs a
- new L{SecondaryAuthorityService} from a C{str} giving a master server
- address and DNS port and several domains, causing the creation of a secondary
- authority for each domain and that master server address and the given
- DNS port.
- """
- primary = '192.168.1.3'
- port = 5335
- service = SecondaryAuthorityService.fromServerAddressAndDomains(
- (primary, port), ['example.net', 'example.edu'])
- self.assertEqual(service.primary, primary)
- self.assertEqual(service._port, 5335)
-
- self.assertEqual(service.domains[0].primary, primary)
- self.assertEqual(service.domains[0]._port, port)
- self.assertEqual(service.domains[0].domain, 'example.net')
-
- self.assertEqual(service.domains[1].primary, primary)
- self.assertEqual(service.domains[1]._port, port)
- self.assertEqual(service.domains[1].domain, 'example.edu')
-
-
-
-class SecondaryAuthorityTests(unittest.TestCase):
- """
- L{twisted.names.secondary.SecondaryAuthority} correctly constructs objects
- with a specified IP address and optionally specified DNS port.
- """
-
- def test_defaultPort(self):
- """
- When constructed using L{SecondaryAuthority.__init__}, the default port
- of 53 is used.
- """
- secondary = SecondaryAuthority('192.168.1.1', 'inside.com')
- self.assertEqual(secondary.primary, '192.168.1.1')
- self.assertEqual(secondary._port, 53)
- self.assertEqual(secondary.domain, 'inside.com')
-
-
- def test_explicitPort(self):
- """
- When constructed using L{SecondaryAuthority.fromServerAddressAndDomain},
- the specified port is used.
- """
- secondary = SecondaryAuthority.fromServerAddressAndDomain(
- ('192.168.1.1', 5353), 'inside.com')
- self.assertEqual(secondary.primary, '192.168.1.1')
- self.assertEqual(secondary._port, 5353)
- self.assertEqual(secondary.domain, 'inside.com')
-
-
- def test_transfer(self):
- """
- An attempt is made to transfer the zone for the domain the
- L{SecondaryAuthority} was constructed with from the server address it
- was constructed with when L{SecondaryAuthority.transfer} is called.
- """
- class ClockMemoryReactor(Clock, MemoryReactor):
- def __init__(self):
- Clock.__init__(self)
- MemoryReactor.__init__(self)
-
- secondary = SecondaryAuthority.fromServerAddressAndDomain(
- ('192.168.1.2', 1234), 'example.com')
- secondary._reactor = reactor = ClockMemoryReactor()
-
- secondary.transfer()
-
- # Verify a connection attempt to the server address above
- host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0)
- self.assertEqual(host, '192.168.1.2')
- self.assertEqual(port, 1234)
-
- # See if a zone transfer query is issued.
- proto = factory.buildProtocol((host, port))
- transport = StringTransport()
- proto.makeConnection(transport)
-
- msg = Message()
- # DNSProtocol.writeMessage length encodes the message by prepending a
- # 2 byte message length to the buffered value.
- msg.decode(StringIO(transport.value()[2:]))
-
- self.assertEqual(
- [dns.Query('example.com', dns.AXFR, dns.IN)], msg.queries)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_rootresolve.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_rootresolve.py
deleted file mode 100755
index b3d34f38..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_rootresolve.py
+++ /dev/null
@@ -1,705 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for Twisted.names' root resolver.
-"""
-
-from random import randrange
-
-from zope.interface import implements
-from zope.interface.verify import verifyClass
-
-from twisted.python.log import msg
-from twisted.trial import util
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import Deferred, succeed, gatherResults
-from twisted.internet.task import Clock
-from twisted.internet.address import IPv4Address
-from twisted.internet.interfaces import IReactorUDP, IUDPTransport
-from twisted.names.root import Resolver, lookupNameservers, lookupAddress
-from twisted.names.root import extractAuthority, discoverAuthority, retry
-from twisted.names.dns import IN, HS, A, NS, CNAME, OK, ENAME, Record_CNAME
-from twisted.names.dns import Query, Message, RRHeader, Record_A, Record_NS
-from twisted.names.error import DNSNameError, ResolverError
-
-
-class MemoryDatagramTransport(object):
- """
- This L{IUDPTransport} implementation enforces the usual connection rules
- and captures sent traffic in a list for later inspection.
-
- @ivar _host: The host address to which this transport is bound.
- @ivar _protocol: The protocol connected to this transport.
- @ivar _sentPackets: A C{list} of two-tuples of the datagrams passed to
- C{write} and the addresses to which they are destined.
-
- @ivar _connectedTo: C{None} if this transport is unconnected, otherwise an
- address to which all traffic is supposedly sent.
-
- @ivar _maxPacketSize: An C{int} giving the maximum length of a datagram
- which will be successfully handled by C{write}.
- """
- implements(IUDPTransport)
-
- def __init__(self, host, protocol, maxPacketSize):
- self._host = host
- self._protocol = protocol
- self._sentPackets = []
- self._connectedTo = None
- self._maxPacketSize = maxPacketSize
-
-
- def getHost(self):
- """
- Return the address which this transport is pretending to be bound
- to.
- """
- return IPv4Address('UDP', *self._host)
-
-
- def connect(self, host, port):
- """
- Connect this transport to the given address.
- """
- if self._connectedTo is not None:
- raise ValueError("Already connected")
- self._connectedTo = (host, port)
-
-
- def write(self, datagram, addr=None):
- """
- Send the given datagram.
- """
- if addr is None:
- addr = self._connectedTo
- if addr is None:
- raise ValueError("Need an address")
- if len(datagram) > self._maxPacketSize:
- raise ValueError("Packet too big")
- self._sentPackets.append((datagram, addr))
-
-
- def stopListening(self):
- """
- Shut down this transport.
- """
- self._protocol.stopProtocol()
- return succeed(None)
-
-verifyClass(IUDPTransport, MemoryDatagramTransport)
-
-
-
-class MemoryReactor(Clock):
- """
- An L{IReactorTime} and L{IReactorUDP} provider.
-
- Time is controlled deterministically via the base class, L{Clock}. UDP is
- handled in-memory by connecting protocols to instances of
- L{MemoryDatagramTransport}.
-
- @ivar udpPorts: A C{dict} mapping port numbers to instances of
- L{MemoryDatagramTransport}.
- """
- implements(IReactorUDP)
-
- def __init__(self):
- Clock.__init__(self)
- self.udpPorts = {}
-
-
- def listenUDP(self, port, protocol, interface='', maxPacketSize=8192):
- """
- Pretend to bind a UDP port and connect the given protocol to it.
- """
- if port == 0:
- while True:
- port = randrange(1, 2 ** 16)
- if port not in self.udpPorts:
- break
- if port in self.udpPorts:
- raise ValueError("Address in use")
- transport = MemoryDatagramTransport(
- (interface, port), protocol, maxPacketSize)
- self.udpPorts[port] = transport
- protocol.makeConnection(transport)
- return transport
-
-verifyClass(IReactorUDP, MemoryReactor)
-
-
-
-class RootResolverTests(TestCase):
- """
- Tests for L{twisted.names.root.Resolver}.
- """
- def _queryTest(self, filter):
- """
- Invoke L{Resolver._query} and verify that it sends the correct DNS
- query. Deliver a canned response to the query and return whatever the
- L{Deferred} returned by L{Resolver._query} fires with.
-
- @param filter: The value to pass for the C{filter} parameter to
- L{Resolver._query}.
- """
- reactor = MemoryReactor()
- resolver = Resolver([], reactor=reactor)
- d = resolver._query(
- Query('foo.example.com', A, IN), [('1.1.2.3', 1053)], (30,),
- filter)
-
- # A UDP port should have been started.
- portNumber, transport = reactor.udpPorts.popitem()
-
- # And a DNS packet sent.
- [(packet, address)] = transport._sentPackets
-
- msg = Message()
- msg.fromStr(packet)
-
- # It should be a query with the parameters used above.
- self.assertEqual(msg.queries, [Query('foo.example.com', A, IN)])
- self.assertEqual(msg.answers, [])
- self.assertEqual(msg.authority, [])
- self.assertEqual(msg.additional, [])
-
- response = []
- d.addCallback(response.append)
- self.assertEqual(response, [])
-
- # Once a reply is received, the Deferred should fire.
- del msg.queries[:]
- msg.answer = 1
- msg.answers.append(RRHeader('foo.example.com', payload=Record_A('5.8.13.21')))
- transport._protocol.datagramReceived(msg.toStr(), ('1.1.2.3', 1053))
- return response[0]
-
-
- def test_filteredQuery(self):
- """
- L{Resolver._query} accepts a L{Query} instance and an address, issues
- the query, and returns a L{Deferred} which fires with the response to
- the query. If a true value is passed for the C{filter} parameter, the
- result is a three-tuple of lists of records.
- """
- answer, authority, additional = self._queryTest(True)
- self.assertEqual(
- answer,
- [RRHeader('foo.example.com', payload=Record_A('5.8.13.21', ttl=0))])
- self.assertEqual(authority, [])
- self.assertEqual(additional, [])
-
-
- def test_unfilteredQuery(self):
- """
- Similar to L{test_filteredQuery}, but for the case where a false value
- is passed for the C{filter} parameter. In this case, the result is a
- L{Message} instance.
- """
- message = self._queryTest(False)
- self.assertIsInstance(message, Message)
- self.assertEqual(message.queries, [])
- self.assertEqual(
- message.answers,
- [RRHeader('foo.example.com', payload=Record_A('5.8.13.21', ttl=0))])
- self.assertEqual(message.authority, [])
- self.assertEqual(message.additional, [])
-
-
- def _respond(self, answers=[], authority=[], additional=[], rCode=OK):
- """
- Create a L{Message} suitable for use as a response to a query.
-
- @param answers: A C{list} of two-tuples giving data for the answers
- section of the message. The first element of each tuple is a name
- for the L{RRHeader}. The second element is the payload.
- @param authority: A C{list} like C{answers}, but for the authority
- section of the response.
- @param additional: A C{list} like C{answers}, but for the
- additional section of the response.
- @param rCode: The response code the message will be created with.
-
- @return: A new L{Message} initialized with the given values.
- """
- response = Message(rCode=rCode)
- for (section, data) in [(response.answers, answers),
- (response.authority, authority),
- (response.additional, additional)]:
- section.extend([
- RRHeader(name, record.TYPE, getattr(record, 'CLASS', IN),
- payload=record)
- for (name, record) in data])
- return response
-
-
- def _getResolver(self, serverResponses, maximumQueries=10):
- """
- Create and return a new L{root.Resolver} modified to resolve queries
- against the record data represented by C{servers}.
-
- @param serverResponses: A mapping from dns server addresses to
- mappings. The inner mappings are from query two-tuples (name,
- type) to dictionaries suitable for use as **arguments to
- L{_respond}. See that method for details.
- """
- roots = ['1.1.2.3']
- resolver = Resolver(roots, maximumQueries)
-
- def query(query, serverAddresses, timeout, filter):
- msg("Query for QNAME %s at %r" % (query.name, serverAddresses))
- for addr in serverAddresses:
- try:
- server = serverResponses[addr]
- except KeyError:
- continue
- records = server[str(query.name), query.type]
- return succeed(self._respond(**records))
- resolver._query = query
- return resolver
-
-
- def test_lookupAddress(self):
- """
- L{root.Resolver.lookupAddress} looks up the I{A} records for the
- specified hostname by first querying one of the root servers the
- resolver was created with and then following the authority delegations
- until a result is received.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('foo.example.com', A): {
- 'authority': [('foo.example.com', Record_NS('ns1.example.com'))],
- 'additional': [('ns1.example.com', Record_A('34.55.89.144'))],
- },
- },
- ('34.55.89.144', 53): {
- ('foo.example.com', A): {
- 'answers': [('foo.example.com', Record_A('10.0.0.1'))],
- }
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('foo.example.com')
- d.addCallback(lambda (ans, auth, add): ans[0].payload.dottedQuad())
- d.addCallback(self.assertEqual, '10.0.0.1')
- return d
-
-
- def test_lookupChecksClass(self):
- """
- If a response includes a record with a class different from the one
- in the query, it is ignored and lookup continues until a record with
- the right class is found.
- """
- badClass = Record_A('10.0.0.1')
- badClass.CLASS = HS
- servers = {
- ('1.1.2.3', 53): {
- ('foo.example.com', A): {
- 'answers': [('foo.example.com', badClass)],
- 'authority': [('foo.example.com', Record_NS('ns1.example.com'))],
- 'additional': [('ns1.example.com', Record_A('10.0.0.2'))],
- },
- },
- ('10.0.0.2', 53): {
- ('foo.example.com', A): {
- 'answers': [('foo.example.com', Record_A('10.0.0.3'))],
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('foo.example.com')
- d.addCallback(lambda (ans, auth, add): ans[0].payload)
- d.addCallback(self.assertEqual, Record_A('10.0.0.3'))
- return d
-
-
- def test_missingGlue(self):
- """
- If an intermediate response includes no glue records for the
- authorities, separate queries are made to find those addresses.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('foo.example.com', A): {
- 'authority': [('foo.example.com', Record_NS('ns1.example.org'))],
- # Conspicuous lack of an additional section naming ns1.example.com
- },
- ('ns1.example.org', A): {
- 'answers': [('ns1.example.org', Record_A('10.0.0.1'))],
- },
- },
- ('10.0.0.1', 53): {
- ('foo.example.com', A): {
- 'answers': [('foo.example.com', Record_A('10.0.0.2'))],
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('foo.example.com')
- d.addCallback(lambda (ans, auth, add): ans[0].payload.dottedQuad())
- d.addCallback(self.assertEqual, '10.0.0.2')
- return d
-
-
- def test_missingName(self):
- """
- If a name is missing, L{Resolver.lookupAddress} returns a L{Deferred}
- which fails with L{DNSNameError}.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('foo.example.com', A): {
- 'rCode': ENAME,
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('foo.example.com')
- return self.assertFailure(d, DNSNameError)
-
-
- def test_answerless(self):
- """
- If a query is responded to with no answers or nameserver records, the
- L{Deferred} returned by L{Resolver.lookupAddress} fires with
- L{ResolverError}.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('example.com')
- return self.assertFailure(d, ResolverError)
-
-
- def test_delegationLookupError(self):
- """
- If there is an error resolving the nameserver in a delegation response,
- the L{Deferred} returned by L{Resolver.lookupAddress} fires with that
- error.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- 'authority': [('example.com', Record_NS('ns1.example.com'))],
- },
- ('ns1.example.com', A): {
- 'rCode': ENAME,
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('example.com')
- return self.assertFailure(d, DNSNameError)
-
-
- def test_delegationLookupEmpty(self):
- """
- If there are no records in the response to a lookup of a delegation
- nameserver, the L{Deferred} returned by L{Resolver.lookupAddress} fires
- with L{ResolverError}.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- 'authority': [('example.com', Record_NS('ns1.example.com'))],
- },
- ('ns1.example.com', A): {
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('example.com')
- return self.assertFailure(d, ResolverError)
-
-
- def test_lookupNameservers(self):
- """
- L{Resolver.lookupNameservers} is like L{Resolver.lookupAddress}, except
- it queries for I{NS} records instead of I{A} records.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- 'rCode': ENAME,
- },
- ('example.com', NS): {
- 'answers': [('example.com', Record_NS('ns1.example.com'))],
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupNameservers('example.com')
- d.addCallback(lambda (ans, auth, add): str(ans[0].payload.name))
- d.addCallback(self.assertEqual, 'ns1.example.com')
- return d
-
-
- def test_returnCanonicalName(self):
- """
- If a I{CNAME} record is encountered as the answer to a query for
- another record type, that record is returned as the answer.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- 'answers': [('example.com', Record_CNAME('example.net')),
- ('example.net', Record_A('10.0.0.7'))],
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('example.com')
- d.addCallback(lambda (ans, auth, add): ans)
- d.addCallback(
- self.assertEqual,
- [RRHeader('example.com', CNAME, payload=Record_CNAME('example.net')),
- RRHeader('example.net', A, payload=Record_A('10.0.0.7'))])
- return d
-
-
- def test_followCanonicalName(self):
- """
- If no record of the requested type is included in a response, but a
- I{CNAME} record for the query name is included, queries are made to
- resolve the value of the I{CNAME}.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- 'answers': [('example.com', Record_CNAME('example.net'))],
- },
- ('example.net', A): {
- 'answers': [('example.net', Record_A('10.0.0.5'))],
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('example.com')
- d.addCallback(lambda (ans, auth, add): ans)
- d.addCallback(
- self.assertEqual,
- [RRHeader('example.com', CNAME, payload=Record_CNAME('example.net')),
- RRHeader('example.net', A, payload=Record_A('10.0.0.5'))])
- return d
-
-
- def test_detectCanonicalNameLoop(self):
- """
- If there is a cycle between I{CNAME} records in a response, this is
- detected and the L{Deferred} returned by the lookup method fails
- with L{ResolverError}.
- """
- servers = {
- ('1.1.2.3', 53): {
- ('example.com', A): {
- 'answers': [('example.com', Record_CNAME('example.net')),
- ('example.net', Record_CNAME('example.com'))],
- },
- },
- }
- resolver = self._getResolver(servers)
- d = resolver.lookupAddress('example.com')
- return self.assertFailure(d, ResolverError)
-
-
- def test_boundedQueries(self):
- """
- L{Resolver.lookupAddress} won't issue more queries following
- delegations than the limit passed to its initializer.
- """
- servers = {
- ('1.1.2.3', 53): {
- # First query - force it to start over with a name lookup of
- # ns1.example.com
- ('example.com', A): {
- 'authority': [('example.com', Record_NS('ns1.example.com'))],
- },
- # Second query - let it resume the original lookup with the
- # address of the nameserver handling the delegation.
- ('ns1.example.com', A): {
- 'answers': [('ns1.example.com', Record_A('10.0.0.2'))],
- },
- },
- ('10.0.0.2', 53): {
- # Third query - let it jump straight to asking the
- # delegation server by including its address here (different
- # case from the first query).
- ('example.com', A): {
- 'authority': [('example.com', Record_NS('ns2.example.com'))],
- 'additional': [('ns2.example.com', Record_A('10.0.0.3'))],
- },
- },
- ('10.0.0.3', 53): {
- # Fourth query - give it the answer, we're done.
- ('example.com', A): {
- 'answers': [('example.com', Record_A('10.0.0.4'))],
- },
- },
- }
-
- # Make two resolvers. One which is allowed to make 3 queries
- # maximum, and so will fail, and on which may make 4, and so should
- # succeed.
- failer = self._getResolver(servers, 3)
- failD = self.assertFailure(
- failer.lookupAddress('example.com'), ResolverError)
-
- succeeder = self._getResolver(servers, 4)
- succeedD = succeeder.lookupAddress('example.com')
- succeedD.addCallback(lambda (ans, auth, add): ans[0].payload)
- succeedD.addCallback(self.assertEqual, Record_A('10.0.0.4'))
-
- return gatherResults([failD, succeedD])
-
-
- def test_discoveredAuthorityDeprecated(self):
- """
- Calling L{Resolver.discoveredAuthority} produces a deprecation warning.
- """
- resolver = Resolver([])
- d = resolver.discoveredAuthority('127.0.0.1', 'example.com', IN, A, (0,))
-
- warnings = self.flushWarnings([
- self.test_discoveredAuthorityDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- 'twisted.names.root.Resolver.discoveredAuthority is deprecated since '
- 'Twisted 10.0. Use twisted.names.client.Resolver directly, instead.')
- self.assertEqual(len(warnings), 1)
-
- # This will time out quickly, but we need to wait for it because there
- # are resources associated with.
- d.addErrback(lambda ignored: None)
- return d
-
-
-
-class StubDNSDatagramProtocol:
- """
- A do-nothing stand-in for L{DNSDatagramProtocol} which can be used to avoid
- network traffic in tests where that kind of thing doesn't matter.
- """
- def query(self, *a, **kw):
- return Deferred()
-
-
-
-_retrySuppression = util.suppress(
- category=DeprecationWarning,
- message=(
- 'twisted.names.root.retry is deprecated since Twisted 10.0. Use a '
- 'Resolver object for retry logic.'))
-
-
-class DiscoveryToolsTests(TestCase):
- """
- Tests for the free functions in L{twisted.names.root} which help out with
- authority discovery. Since these are mostly deprecated, these are mostly
- deprecation tests.
- """
- def test_lookupNameserversDeprecated(self):
- """
- Calling L{root.lookupNameservers} produces a deprecation warning.
- """
- # Don't care about the return value, since it will never have a result,
- # since StubDNSDatagramProtocol doesn't actually work.
- lookupNameservers('example.com', '127.0.0.1', StubDNSDatagramProtocol())
-
- warnings = self.flushWarnings([
- self.test_lookupNameserversDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- 'twisted.names.root.lookupNameservers is deprecated since Twisted '
- '10.0. Use twisted.names.root.Resolver.lookupNameservers '
- 'instead.')
- self.assertEqual(len(warnings), 1)
- test_lookupNameserversDeprecated.suppress = [_retrySuppression]
-
-
- def test_lookupAddressDeprecated(self):
- """
- Calling L{root.lookupAddress} produces a deprecation warning.
- """
- # Don't care about the return value, since it will never have a result,
- # since StubDNSDatagramProtocol doesn't actually work.
- lookupAddress('example.com', '127.0.0.1', StubDNSDatagramProtocol())
-
- warnings = self.flushWarnings([
- self.test_lookupAddressDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- 'twisted.names.root.lookupAddress is deprecated since Twisted '
- '10.0. Use twisted.names.root.Resolver.lookupAddress '
- 'instead.')
- self.assertEqual(len(warnings), 1)
- test_lookupAddressDeprecated.suppress = [_retrySuppression]
-
-
- def test_extractAuthorityDeprecated(self):
- """
- Calling L{root.extractAuthority} produces a deprecation warning.
- """
- extractAuthority(Message(), {})
-
- warnings = self.flushWarnings([
- self.test_extractAuthorityDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- 'twisted.names.root.extractAuthority is deprecated since Twisted '
- '10.0. Please inspect the Message object directly.')
- self.assertEqual(len(warnings), 1)
-
-
- def test_discoverAuthorityDeprecated(self):
- """
- Calling L{root.discoverAuthority} produces a deprecation warning.
- """
- discoverAuthority(
- 'example.com', ['10.0.0.1'], p=StubDNSDatagramProtocol())
-
- warnings = self.flushWarnings([
- self.test_discoverAuthorityDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- 'twisted.names.root.discoverAuthority is deprecated since Twisted '
- '10.0. Use twisted.names.root.Resolver.lookupNameservers '
- 'instead.')
- self.assertEqual(len(warnings), 1)
-
- # discoverAuthority is implemented in terms of deprecated functions,
- # too. Ignore those.
- test_discoverAuthorityDeprecated.suppress = [
- util.suppress(
- category=DeprecationWarning,
- message=(
- 'twisted.names.root.lookupNameservers is deprecated since '
- 'Twisted 10.0. Use '
- 'twisted.names.root.Resolver.lookupNameservers instead.')),
- _retrySuppression]
-
-
- def test_retryDeprecated(self):
- """
- Calling L{root.retry} produces a deprecation warning.
- """
- retry([0], StubDNSDatagramProtocol())
-
- warnings = self.flushWarnings([
- self.test_retryDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- 'twisted.names.root.retry is deprecated since Twisted '
- '10.0. Use a Resolver object for retry logic.')
- self.assertEqual(len(warnings), 1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_srvconnect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_srvconnect.py
deleted file mode 100755
index 2eabdfd2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_srvconnect.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for L{twisted.names.srvconnect}.
-"""
-
-from twisted.internet import defer, protocol
-from twisted.names import client, dns, srvconnect
-from twisted.names.common import ResolverBase
-from twisted.names.error import DNSNameError
-from twisted.internet.error import DNSLookupError, ServiceNameUnknownError
-from twisted.trial import unittest
-from twisted.test.proto_helpers import MemoryReactor
-
-
-class FakeResolver(ResolverBase):
- """
- Resolver that only gives out one given result.
-
- Either L{results} or L{failure} must be set and will be used for
- the return value of L{_lookup}
-
- @ivar results: List of L{dns.RRHeader} for the desired result.
- @type results: C{list}
- @ivar failure: Failure with an exception from L{twisted.names.error}.
- @type failure: L{Failure<twisted.python.failure.Failure>}
- """
-
- def __init__(self, results=None, failure=None):
- self.results = results
- self.failure = failure
-
- def _lookup(self, name, cls, qtype, timeout):
- """
- Return the result or failure on lookup.
- """
- if self.results is not None:
- return defer.succeed((self.results, [], []))
- else:
- return defer.fail(self.failure)
-
-
-
-class DummyFactory(protocol.ClientFactory):
- """
- Dummy client factory that stores the reason of connection failure.
- """
- def __init__(self):
- self.reason = None
-
- def clientConnectionFailed(self, connector, reason):
- self.reason = reason
-
-
-
-class SRVConnectorTest(unittest.TestCase):
- """
- Tests for L{srvconnect.SRVConnector}.
- """
-
- def setUp(self):
- self.patch(client, 'theResolver', FakeResolver())
- self.reactor = MemoryReactor()
- self.factory = DummyFactory()
- self.connector = srvconnect.SRVConnector(self.reactor, 'xmpp-server',
- 'example.org', self.factory)
-
-
- def test_SRVPresent(self):
- """
- Test connectTCP gets called with the address from the SRV record.
- """
- payload = dns.Record_SRV(port=6269, target='host.example.org', ttl=60)
- client.theResolver.results = [dns.RRHeader(name='example.org',
- type=dns.SRV,
- cls=dns.IN, ttl=60,
- payload=payload)]
- self.connector.connect()
-
- self.assertIdentical(None, self.factory.reason)
- self.assertEqual(
- self.reactor.tcpClients.pop()[:2], ('host.example.org', 6269))
-
-
- def test_SRVNotPresent(self):
- """
- Test connectTCP gets called with fallback parameters on NXDOMAIN.
- """
- client.theResolver.failure = DNSNameError('example.org')
- self.connector.connect()
-
- self.assertIdentical(None, self.factory.reason)
- self.assertEqual(
- self.reactor.tcpClients.pop()[:2], ('example.org', 'xmpp-server'))
-
-
- def test_SRVNoResult(self):
- """
- Test connectTCP gets called with fallback parameters on empty result.
- """
- client.theResolver.results = []
- self.connector.connect()
-
- self.assertIdentical(None, self.factory.reason)
- self.assertEqual(
- self.reactor.tcpClients.pop()[:2], ('example.org', 'xmpp-server'))
-
-
- def test_SRVNoResultUnknownServiceDefaultPort(self):
- """
- connectTCP gets called with default port if the service is not defined.
- """
- self.connector = srvconnect.SRVConnector(self.reactor,
- 'thisbetternotexist',
- 'example.org', self.factory,
- defaultPort=5222)
-
- client.theResolver.failure = ServiceNameUnknownError()
- self.connector.connect()
-
- self.assertIdentical(None, self.factory.reason)
- self.assertEqual(
- self.reactor.tcpClients.pop()[:2], ('example.org', 5222))
-
-
- def test_SRVNoResultUnknownServiceNoDefaultPort(self):
- """
- Connect fails on no result, unknown service and no default port.
- """
- self.connector = srvconnect.SRVConnector(self.reactor,
- 'thisbetternotexist',
- 'example.org', self.factory)
-
- client.theResolver.failure = ServiceNameUnknownError()
- self.connector.connect()
-
- self.assertTrue(self.factory.reason.check(ServiceNameUnknownError))
-
-
- def test_SRVBadResult(self):
- """
- Test connectTCP gets called with fallback parameters on bad result.
- """
- client.theResolver.results = [dns.RRHeader(name='example.org',
- type=dns.CNAME,
- cls=dns.IN, ttl=60,
- payload=None)]
- self.connector.connect()
-
- self.assertIdentical(None, self.factory.reason)
- self.assertEqual(
- self.reactor.tcpClients.pop()[:2], ('example.org', 'xmpp-server'))
-
-
- def test_SRVNoService(self):
- """
- Test that connecting fails when no service is present.
- """
- payload = dns.Record_SRV(port=5269, target='.', ttl=60)
- client.theResolver.results = [dns.RRHeader(name='example.org',
- type=dns.SRV,
- cls=dns.IN, ttl=60,
- payload=payload)]
- self.connector.connect()
-
- self.assertNotIdentical(None, self.factory.reason)
- self.factory.reason.trap(DNSLookupError)
- self.assertEqual(self.reactor.tcpClients, [])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_tap.py
deleted file mode 100755
index 0858d265..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/test/test_tap.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.names.tap}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.python.usage import UsageError
-from twisted.names.tap import Options, _buildResolvers
-from twisted.names.dns import PORT
-from twisted.names.secondary import SecondaryAuthorityService
-from twisted.names.resolve import ResolverChain
-from twisted.names.client import Resolver
-
-class OptionsTests(TestCase):
- """
- Tests for L{Options}, defining how command line arguments for the DNS server
- are parsed.
- """
- def test_malformedSecondary(self):
- """
- If the value supplied for an I{--secondary} option does not provide a
- server IP address, optional port number, and domain name,
- L{Options.parseOptions} raises L{UsageError}.
- """
- options = Options()
- self.assertRaises(
- UsageError, options.parseOptions, ['--secondary', ''])
- self.assertRaises(
- UsageError, options.parseOptions, ['--secondary', '1.2.3.4'])
- self.assertRaises(
- UsageError, options.parseOptions, ['--secondary', '1.2.3.4:hello'])
- self.assertRaises(
- UsageError, options.parseOptions,
- ['--secondary', '1.2.3.4:hello/example.com'])
-
-
- def test_secondary(self):
- """
- An argument of the form C{"ip/domain"} is parsed by L{Options} for the
- I{--secondary} option and added to its list of secondaries, using the
- default DNS port number.
- """
- options = Options()
- options.parseOptions(['--secondary', '1.2.3.4/example.com'])
- self.assertEqual(
- [(('1.2.3.4', PORT), ['example.com'])], options.secondaries)
-
-
- def test_secondaryExplicitPort(self):
- """
- An argument of the form C{"ip:port/domain"} can be used to specify an
- alternate port number for for which to act as a secondary.
- """
- options = Options()
- options.parseOptions(['--secondary', '1.2.3.4:5353/example.com'])
- self.assertEqual(
- [(('1.2.3.4', 5353), ['example.com'])], options.secondaries)
-
-
- def test_secondaryAuthorityServices(self):
- """
- After parsing I{--secondary} options, L{Options} constructs a
- L{SecondaryAuthorityService} instance for each configured secondary.
- """
- options = Options()
- options.parseOptions(['--secondary', '1.2.3.4:5353/example.com',
- '--secondary', '1.2.3.5:5354/example.com'])
- self.assertEqual(len(options.svcs), 2)
- secondary = options.svcs[0]
- self.assertIsInstance(options.svcs[0], SecondaryAuthorityService)
- self.assertEqual(secondary.primary, '1.2.3.4')
- self.assertEqual(secondary._port, 5353)
- secondary = options.svcs[1]
- self.assertIsInstance(options.svcs[1], SecondaryAuthorityService)
- self.assertEqual(secondary.primary, '1.2.3.5')
- self.assertEqual(secondary._port, 5354)
-
-
- def test_recursiveConfiguration(self):
- """
- Recursive DNS lookups, if enabled, should be a last-resort option.
- Any other lookup method (cache, local lookup, etc.) should take
- precedence over recursive lookups
- """
- options = Options()
- options.parseOptions(['--hosts-file', 'hosts.txt', '--recursive'])
- ca, cl = _buildResolvers(options)
-
- # Extra cleanup, necessary on POSIX because client.Resolver doesn't know
- # when to stop parsing resolv.conf. See #NNN for improving this.
- for x in cl:
- if isinstance(x, ResolverChain):
- recurser = x.resolvers[-1]
- if isinstance(recurser, Resolver):
- recurser._parseCall.cancel()
-
- self.assertIsInstance(cl[-1], ResolverChain)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/NEWS
deleted file mode 100644
index 5e032e2c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/NEWS
+++ /dev/null
@@ -1,243 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Names 12.2.0 (2012-08-26)
-=================================
-
-Features
---------
- - twisted.names.srvconnect.SRVConnector now takes a default port to
- use when SRV lookup fails. (#3456)
-
-Other
------
- - #5647
-
-
-Twisted Names 12.1.0 (2012-06-02)
-=================================
-
-Features
---------
- - "twistd dns" secondary server functionality and
- twisted.names.secondary now support retrieving zone information
- from a master running on a non-standard DNS port. (#5468)
-
-Bugfixes
---------
- - twisted.names.dns.DNSProtocol instances no longer throw an
- exception when disconnecting. (#5471)
- - twisted.names.tap.makeService (thus also "twistd dns") now makes a
- DNS server which gives precedence to the hosts file from its
- configuration over the remote DNS servers from its configuration.
- (#5524)
- - twisted.name.cache.CacheResolver now makes sure TTLs on returned
- results are never negative. (#5579)
- - twisted.names.cache.CacheResolver entries added via the initializer
- are now timed out correctly. (#5638)
-
-Improved Documentation
-----------------------
- - The examples now contain instructions on how to run them and
- descriptions in the examples index. (#5588)
-
-Deprecations and Removals
--------------------------
- - The deprecated twisted.names.dns.Record_mx.exchange attribute was
- removed. (#4549)
-
-
-Twisted Names 12.0.0 (2012-02-10)
-=================================
-
-Bugfixes
---------
- - twisted.names.dns.Message now sets the `auth` flag on RRHeader
- instances it creates to reflect the authority of the message
- itself. (#5421)
-
-
-Twisted Names 11.1.0 (2011-11-15)
-=================================
-
-Features
---------
- - twisted.names.dns.Message now parses records of unknown type into
- instances of a new `UnknownType` class. (#4603)
-
-Bugfixes
---------
- - twisted.names.dns.Name now detects loops in names it is decoding
- and raises an exception. Previously it would follow the loop
- forever, allowing a remote denial of service attack against any
- twisted.names client or server. (#5064)
- - twisted.names.hosts.Resolver now supports IPv6 addresses; its
- lookupAddress method now filters them out and its lookupIPV6Address
- method is now implemented. (#5098)
-
-
-Twisted Names 11.0.0 (2011-04-01)
-=================================
-
-No significant changes have been made for this release.
-
-
-Twisted Names 10.2.0 (2010-11-29)
-=================================
-
-Features
---------
- - twisted.names.server can now serve SPF resource records using
- twisted.names.dns.Record_SPF. twisted.names.client can query for
- them using lookupSenderPolicy. (#3928)
-
-Bugfixes
---------
- - twisted.names.common.extractRecords doesn't try to close the
- transport anymore in case of recursion, as it's done by the
- Resolver itself now. (#3998)
-
-Improved Documentation
-----------------------
- - Tidied up the Twisted Names documentation for easier conversion.
- (#4573)
-
-
-Twisted Names 10.1.0 (2010-06-27)
-=================================
-
-Features
---------
- - twisted.names.dns.Message now uses a specially constructed
- dictionary for looking up record types. This yields a significant
- performance improvement on PyPy. (#4283)
-
-
-Twisted Names 10.0.0 (2010-03-01)
-=================================
-
-Bugfixes
---------
- - twisted.names.root.Resolver no longer leaks UDP sockets while
- resolving names. (#970)
-
-Deprecations and Removals
--------------------------
- - Several top-level functions in twisted.names.root are now
- deprecated. (#970)
-
-Other
------
- - #4066
-
-
-Twisted Names 9.0.0 (2009-11-24)
-================================
-
-Deprecations and Removals
--------------------------
- - client.ThreadedResolver is deprecated in favor of
- twisted.internet.base.ThreadedResolver (#3710)
-
-Other
------
- - #3540, #3560, #3712, #3750, #3990
-
-
-Names 8.2.0 (2008-12-16)
-========================
-
-Features
---------
- - The NAPTR record type is now supported (#2276)
-
-Fixes
------
- - Make client.Resolver less vulnerable to the Birthday Paradox attack by
- avoiding sending duplicate queries when it's not necessary (#3347)
- - client.Resolver now uses a random source port for each DNS request (#3342)
- - client.Resolver now uses a full 16 bits of randomness for message IDs,
- instead of 10 which it previously used (#3342)
- - All record types now have value-based equality and a string representation
- (#2935)
-
-Other
------
- - #1622, #3424
-
-
-8.1.0 (2008-05-18)
-==================
-
-Fixes
------
- - The deprecated mktap API is no longer used (#3127)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Fixes
------
-
- - Refactor DNSDatagramProtocol and DNSProtocol to use same base class (#2414)
- - Change Resolver to query specified nameservers in specified order, instead
- of reverse order. (#2290)
- - Make SRVConnector work with bad results and NXDOMAIN responses.
- (#1908, #2777)
- - Handle write errors happening in dns queries, to have correct deferred
- failures. (#2492)
- - Fix the value of OP_NOTIFY and add a definition for OP_UPDATE. (#2945)
-
-Misc
-----
- - #2685, #2936, #2581, #2847
-
-
-0.4.0 (2007-01-06)
-==================
-
-Features
---------
-
- - In the twisted.names client, DNS responses which represent errors
- are now translated to informative exception objects, rather than
- empty lists. This means that client requests which fail will now
- errback their Deferreds (#2248)
-
-Fixes
------
- - A major DoS vulnerability in the UDP DNS server was fixed (#1708)
-
-Misc
-----
- - #1799, #1636, #2149, #2181
-
-
-0.3.0 (2006-05-21)
-==================
-
-Features
---------
- - Some docstring improvements
-
-Fixes
------
- - Fix a problem where the response for the first query with a
- newly-created Resolver object would be dropped.(#1447)
- - Misc: #1581, #1583
-
-
-0.2.0
-=====
- - Fix occassional TCP connection leak in gethostbyname()
- - Fix TCP connection leak in recursive lookups
- - Remove deprecated use of Deferred.setTimeout
- - Improved test coverage for zone transfers
-
-0.1.0
-=====
- - Fix TCP connection leak in zone transfers
- - Handle empty or missing resolv.conf as if 127.0.0.1 was specified
- - Don't use blocking kernel entropy sources
- - Retry logic now properly tries all specified servers.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/README
deleted file mode 100644
index a560b43c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/names/topfiles/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Twisted Names 12.2.0
-
-Twisted Names depends on Twisted Core.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/__init__.py
deleted file mode 100755
index d70440c6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-
-Twisted News: an NNTP-based news service.
-
-"""
-
-from twisted.news._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/_version.py
deleted file mode 100755
index c93334b8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.news', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/database.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/database.py
deleted file mode 100755
index 137736a2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/database.py
+++ /dev/null
@@ -1,1051 +0,0 @@
-# -*- test-case-name: twisted.news.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-News server backend implementations.
-"""
-
-import getpass, pickle, time, socket
-import os
-import StringIO
-from email.Message import Message
-from email.Generator import Generator
-from zope.interface import implements, Interface
-
-from twisted.news.nntp import NNTPError
-from twisted.mail import smtp
-from twisted.internet import defer
-from twisted.enterprise import adbapi
-from twisted.persisted import dirdbm
-from twisted.python.hashlib import md5
-
-
-
-ERR_NOGROUP, ERR_NOARTICLE = range(2, 4) # XXX - put NNTP values here (I guess?)
-
-OVERVIEW_FMT = [
- 'Subject', 'From', 'Date', 'Message-ID', 'References',
- 'Bytes', 'Lines', 'Xref'
-]
-
-def hexdigest(md5): #XXX: argh. 1.5.2 doesn't have this.
- return ''.join(map(lambda x: hex(ord(x))[2:], md5.digest()))
-
-class Article:
- def __init__(self, head, body):
- self.body = body
- self.headers = {}
- header = None
- for line in head.split('\r\n'):
- if line[0] in ' \t':
- i = list(self.headers[header])
- i[1] += '\r\n' + line
- else:
- i = line.split(': ', 1)
- header = i[0].lower()
- self.headers[header] = tuple(i)
-
- if not self.getHeader('Message-ID'):
- s = str(time.time()) + self.body
- id = hexdigest(md5(s)) + '@' + socket.gethostname()
- self.putHeader('Message-ID', '<%s>' % id)
-
- if not self.getHeader('Bytes'):
- self.putHeader('Bytes', str(len(self.body)))
-
- if not self.getHeader('Lines'):
- self.putHeader('Lines', str(self.body.count('\n')))
-
- if not self.getHeader('Date'):
- self.putHeader('Date', time.ctime(time.time()))
-
-
- def getHeader(self, header):
- h = header.lower()
- if h in self.headers:
- return self.headers[h][1]
- else:
- return ''
-
-
- def putHeader(self, header, value):
- self.headers[header.lower()] = (header, value)
-
-
- def textHeaders(self):
- headers = []
- for i in self.headers.values():
- headers.append('%s: %s' % i)
- return '\r\n'.join(headers) + '\r\n'
-
- def overview(self):
- xover = []
- for i in OVERVIEW_FMT:
- xover.append(self.getHeader(i))
- return xover
-
-
-class NewsServerError(Exception):
- pass
-
-
-class INewsStorage(Interface):
- """
- An interface for storing and requesting news articles
- """
-
- def listRequest():
- """
- Returns a deferred whose callback will be passed a list of 4-tuples
- containing (name, max index, min index, flags) for each news group
- """
-
-
- def subscriptionRequest():
- """
- Returns a deferred whose callback will be passed the list of
- recommended subscription groups for new server users
- """
-
-
- def postRequest(message):
- """
- Returns a deferred whose callback will be invoked if 'message'
- is successfully posted to one or more specified groups and
- whose errback will be invoked otherwise.
- """
-
-
- def overviewRequest():
- """
- Returns a deferred whose callback will be passed the a list of
- headers describing this server's overview format.
- """
-
-
- def xoverRequest(group, low, high):
- """
- Returns a deferred whose callback will be passed a list of xover
- headers for the given group over the given range. If low is None,
- the range starts at the first article. If high is None, the range
- ends at the last article.
- """
-
-
- def xhdrRequest(group, low, high, header):
- """
- Returns a deferred whose callback will be passed a list of XHDR data
- for the given group over the given range. If low is None,
- the range starts at the first article. If high is None, the range
- ends at the last article.
- """
-
-
- def listGroupRequest(group):
- """
- Returns a deferred whose callback will be passed a two-tuple of
- (group name, [article indices])
- """
-
-
- def groupRequest(group):
- """
- Returns a deferred whose callback will be passed a five-tuple of
- (group name, article count, highest index, lowest index, group flags)
- """
-
-
- def articleExistsRequest(id):
- """
- Returns a deferred whose callback will be passed with a true value
- if a message with the specified Message-ID exists in the database
- and with a false value otherwise.
- """
-
-
- def articleRequest(group, index, id = None):
- """
- Returns a deferred whose callback will be passed a file-like object
- containing the full article text (headers and body) for the article
- of the specified index in the specified group, and whose errback
- will be invoked if the article or group does not exist. If id is
- not None, index is ignored and the article with the given Message-ID
- will be returned instead, along with its index in the specified
- group.
- """
-
-
- def headRequest(group, index):
- """
- Returns a deferred whose callback will be passed the header for
- the article of the specified index in the specified group, and
- whose errback will be invoked if the article or group does not
- exist.
- """
-
-
- def bodyRequest(group, index):
- """
- Returns a deferred whose callback will be passed the body for
- the article of the specified index in the specified group, and
- whose errback will be invoked if the article or group does not
- exist.
- """
-
-class NewsStorage:
- """
- Backwards compatibility class -- There is no reason to inherit from this,
- just implement INewsStorage instead.
- """
- def listRequest(self):
- raise NotImplementedError()
- def subscriptionRequest(self):
- raise NotImplementedError()
- def postRequest(self, message):
- raise NotImplementedError()
- def overviewRequest(self):
- return defer.succeed(OVERVIEW_FMT)
- def xoverRequest(self, group, low, high):
- raise NotImplementedError()
- def xhdrRequest(self, group, low, high, header):
- raise NotImplementedError()
- def listGroupRequest(self, group):
- raise NotImplementedError()
- def groupRequest(self, group):
- raise NotImplementedError()
- def articleExistsRequest(self, id):
- raise NotImplementedError()
- def articleRequest(self, group, index, id = None):
- raise NotImplementedError()
- def headRequest(self, group, index):
- raise NotImplementedError()
- def bodyRequest(self, group, index):
- raise NotImplementedError()
-
-
-
-class _ModerationMixin:
- """
- Storage implementations can inherit from this class to get the easy-to-use
- C{notifyModerators} method which will take care of sending messages which
- require moderation to a list of moderators.
- """
- sendmail = staticmethod(smtp.sendmail)
-
- def notifyModerators(self, moderators, article):
- """
- Send an article to a list of group moderators to be moderated.
-
- @param moderators: A C{list} of C{str} giving RFC 2821 addresses of
- group moderators to notify.
-
- @param article: The article requiring moderation.
- @type article: L{Article}
-
- @return: A L{Deferred} which fires with the result of sending the email.
- """
- # Moderated postings go through as long as they have an Approved
- # header, regardless of what the value is
- group = article.getHeader('Newsgroups')
- subject = article.getHeader('Subject')
-
- if self._sender is None:
- # This case should really go away. This isn't a good default.
- sender = 'twisted-news@' + socket.gethostname()
- else:
- sender = self._sender
-
- msg = Message()
- msg['Message-ID'] = smtp.messageid()
- msg['From'] = sender
- msg['To'] = ', '.join(moderators)
- msg['Subject'] = 'Moderate new %s message: %s' % (group, subject)
- msg['Content-Type'] = 'message/rfc822'
-
- payload = Message()
- for header, value in article.headers.values():
- payload.add_header(header, value)
- payload.set_payload(article.body)
-
- msg.attach(payload)
-
- out = StringIO.StringIO()
- gen = Generator(out, False)
- gen.flatten(msg)
- msg = out.getvalue()
-
- return self.sendmail(self._mailhost, sender, moderators, msg)
-
-
-
-class PickleStorage(_ModerationMixin):
- """
- A trivial NewsStorage implementation using pickles
-
- Contains numerous flaws and is generally unsuitable for any
- real applications. Consider yourself warned!
- """
-
- implements(INewsStorage)
-
- sharedDBs = {}
-
- def __init__(self, filename, groups=None, moderators=(),
- mailhost=None, sender=None):
- """
- @param mailhost: A C{str} giving the mail exchange host which will
- accept moderation emails from this server. Must accept emails
- destined for any address specified as a moderator.
-
- @param sender: A C{str} giving the address which will be used as the
- sender of any moderation email generated by this server.
- """
- self.datafile = filename
- self.load(filename, groups, moderators)
- self._mailhost = mailhost
- self._sender = sender
-
-
- def getModerators(self, groups):
- # first see if any groups are moderated. if so, nothing gets posted,
- # but the whole messages gets forwarded to the moderator address
- moderators = []
- for group in groups:
- moderators.extend(self.db['moderators'].get(group, None))
- return filter(None, moderators)
-
-
- def listRequest(self):
- "Returns a list of 4-tuples: (name, max index, min index, flags)"
- l = self.db['groups']
- r = []
- for i in l:
- if len(self.db[i].keys()):
- low = min(self.db[i].keys())
- high = max(self.db[i].keys()) + 1
- else:
- low = high = 0
- if self.db['moderators'].has_key(i):
- flags = 'm'
- else:
- flags = 'y'
- r.append((i, high, low, flags))
- return defer.succeed(r)
-
- def subscriptionRequest(self):
- return defer.succeed(['alt.test'])
-
- def postRequest(self, message):
- cleave = message.find('\r\n\r\n')
- headers, article = message[:cleave], message[cleave + 4:]
-
- a = Article(headers, article)
- groups = a.getHeader('Newsgroups').split()
- xref = []
-
- # Check moderated status
- moderators = self.getModerators(groups)
- if moderators and not a.getHeader('Approved'):
- return self.notifyModerators(moderators, a)
-
- for group in groups:
- if group in self.db:
- if len(self.db[group].keys()):
- index = max(self.db[group].keys()) + 1
- else:
- index = 1
- xref.append((group, str(index)))
- self.db[group][index] = a
-
- if len(xref) == 0:
- return defer.fail(None)
-
- a.putHeader('Xref', '%s %s' % (
- socket.gethostname().split()[0],
- ''.join(map(lambda x: ':'.join(x), xref))
- ))
-
- self.flush()
- return defer.succeed(None)
-
-
- def overviewRequest(self):
- return defer.succeed(OVERVIEW_FMT)
-
-
- def xoverRequest(self, group, low, high):
- if not self.db.has_key(group):
- return defer.succeed([])
- r = []
- for i in self.db[group].keys():
- if (low is None or i >= low) and (high is None or i <= high):
- r.append([str(i)] + self.db[group][i].overview())
- return defer.succeed(r)
-
-
- def xhdrRequest(self, group, low, high, header):
- if not self.db.has_key(group):
- return defer.succeed([])
- r = []
- for i in self.db[group].keys():
- if low is None or i >= low and high is None or i <= high:
- r.append((i, self.db[group][i].getHeader(header)))
- return defer.succeed(r)
-
-
- def listGroupRequest(self, group):
- if self.db.has_key(group):
- return defer.succeed((group, self.db[group].keys()))
- else:
- return defer.fail(None)
-
- def groupRequest(self, group):
- if self.db.has_key(group):
- if len(self.db[group].keys()):
- num = len(self.db[group].keys())
- low = min(self.db[group].keys())
- high = max(self.db[group].keys())
- else:
- num = low = high = 0
- flags = 'y'
- return defer.succeed((group, num, high, low, flags))
- else:
- return defer.fail(ERR_NOGROUP)
-
-
- def articleExistsRequest(self, id):
- for group in self.db['groups']:
- for a in self.db[group].values():
- if a.getHeader('Message-ID') == id:
- return defer.succeed(1)
- return defer.succeed(0)
-
-
- def articleRequest(self, group, index, id = None):
- if id is not None:
- raise NotImplementedError
-
- if self.db.has_key(group):
- if self.db[group].has_key(index):
- a = self.db[group][index]
- return defer.succeed((
- index,
- a.getHeader('Message-ID'),
- StringIO.StringIO(a.textHeaders() + '\r\n' + a.body)
- ))
- else:
- return defer.fail(ERR_NOARTICLE)
- else:
- return defer.fail(ERR_NOGROUP)
-
-
- def headRequest(self, group, index):
- if self.db.has_key(group):
- if self.db[group].has_key(index):
- a = self.db[group][index]
- return defer.succeed((index, a.getHeader('Message-ID'), a.textHeaders()))
- else:
- return defer.fail(ERR_NOARTICLE)
- else:
- return defer.fail(ERR_NOGROUP)
-
-
- def bodyRequest(self, group, index):
- if self.db.has_key(group):
- if self.db[group].has_key(index):
- a = self.db[group][index]
- return defer.succeed((index, a.getHeader('Message-ID'), StringIO.StringIO(a.body)))
- else:
- return defer.fail(ERR_NOARTICLE)
- else:
- return defer.fail(ERR_NOGROUP)
-
-
- def flush(self):
- f = open(self.datafile, 'w')
- pickle.dump(self.db, f)
- f.close()
-
-
- def load(self, filename, groups = None, moderators = ()):
- if filename in PickleStorage.sharedDBs:
- self.db = PickleStorage.sharedDBs[filename]
- else:
- try:
- self.db = pickle.load(open(filename))
- PickleStorage.sharedDBs[filename] = self.db
- except IOError:
- self.db = PickleStorage.sharedDBs[filename] = {}
- self.db['groups'] = groups
- if groups is not None:
- for i in groups:
- self.db[i] = {}
- self.db['moderators'] = dict(moderators)
- self.flush()
-
-
-class Group:
- name = None
- flags = ''
- minArticle = 1
- maxArticle = 0
- articles = None
-
- def __init__(self, name, flags = 'y'):
- self.name = name
- self.flags = flags
- self.articles = {}
-
-
-class NewsShelf(_ModerationMixin):
- """
- A NewStorage implementation using Twisted's dirdbm persistence module.
- """
-
- implements(INewsStorage)
-
- def __init__(self, mailhost, path, sender=None):
- """
- @param mailhost: A C{str} giving the mail exchange host which will
- accept moderation emails from this server. Must accept emails
- destined for any address specified as a moderator.
-
- @param sender: A C{str} giving the address which will be used as the
- sender of any moderation email generated by this server.
- """
- self.path = path
- self._mailhost = self.mailhost = mailhost
- self._sender = sender
-
- if not os.path.exists(path):
- os.mkdir(path)
-
- self.dbm = dirdbm.Shelf(os.path.join(path, "newsshelf"))
- if not len(self.dbm.keys()):
- self.initialize()
-
-
- def initialize(self):
- # A dictionary of group name/Group instance items
- self.dbm['groups'] = dirdbm.Shelf(os.path.join(self.path, 'groups'))
-
- # A dictionary of group name/email address
- self.dbm['moderators'] = dirdbm.Shelf(os.path.join(self.path, 'moderators'))
-
- # A list of group names
- self.dbm['subscriptions'] = []
-
- # A dictionary of MessageID strings/xref lists
- self.dbm['Message-IDs'] = dirdbm.Shelf(os.path.join(self.path, 'Message-IDs'))
-
-
- def addGroup(self, name, flags):
- self.dbm['groups'][name] = Group(name, flags)
-
-
- def addSubscription(self, name):
- self.dbm['subscriptions'] = self.dbm['subscriptions'] + [name]
-
-
- def addModerator(self, group, email):
- self.dbm['moderators'][group] = email
-
-
- def listRequest(self):
- result = []
- for g in self.dbm['groups'].values():
- result.append((g.name, g.maxArticle, g.minArticle, g.flags))
- return defer.succeed(result)
-
-
- def subscriptionRequest(self):
- return defer.succeed(self.dbm['subscriptions'])
-
-
- def getModerator(self, groups):
- # first see if any groups are moderated. if so, nothing gets posted,
- # but the whole messages gets forwarded to the moderator address
- for group in groups:
- try:
- return self.dbm['moderators'][group]
- except KeyError:
- pass
- return None
-
-
- def notifyModerator(self, moderator, article):
- """
- Notify a single moderator about an article requiring moderation.
-
- C{notifyModerators} should be preferred.
- """
- return self.notifyModerators([moderator], article)
-
-
- def postRequest(self, message):
- cleave = message.find('\r\n\r\n')
- headers, article = message[:cleave], message[cleave + 4:]
-
- article = Article(headers, article)
- groups = article.getHeader('Newsgroups').split()
- xref = []
-
- # Check for moderated status
- moderator = self.getModerator(groups)
- if moderator and not article.getHeader('Approved'):
- return self.notifyModerators([moderator], article)
-
-
- for group in groups:
- try:
- g = self.dbm['groups'][group]
- except KeyError:
- pass
- else:
- index = g.maxArticle + 1
- g.maxArticle += 1
- g.articles[index] = article
- xref.append((group, str(index)))
- self.dbm['groups'][group] = g
-
- if not xref:
- return defer.fail(NewsServerError("No groups carried: " + ' '.join(groups)))
-
- article.putHeader('Xref', '%s %s' % (socket.gethostname().split()[0], ' '.join(map(lambda x: ':'.join(x), xref))))
- self.dbm['Message-IDs'][article.getHeader('Message-ID')] = xref
- return defer.succeed(None)
-
-
- def overviewRequest(self):
- return defer.succeed(OVERVIEW_FMT)
-
-
- def xoverRequest(self, group, low, high):
- if not self.dbm['groups'].has_key(group):
- return defer.succeed([])
-
- if low is None:
- low = 0
- if high is None:
- high = self.dbm['groups'][group].maxArticle
- r = []
- for i in range(low, high + 1):
- if self.dbm['groups'][group].articles.has_key(i):
- r.append([str(i)] + self.dbm['groups'][group].articles[i].overview())
- return defer.succeed(r)
-
-
- def xhdrRequest(self, group, low, high, header):
- if group not in self.dbm['groups']:
- return defer.succeed([])
-
- if low is None:
- low = 0
- if high is None:
- high = self.dbm['groups'][group].maxArticle
- r = []
- for i in range(low, high + 1):
- if i in self.dbm['groups'][group].articles:
- r.append((i, self.dbm['groups'][group].articles[i].getHeader(header)))
- return defer.succeed(r)
-
-
- def listGroupRequest(self, group):
- if self.dbm['groups'].has_key(group):
- return defer.succeed((group, self.dbm['groups'][group].articles.keys()))
- return defer.fail(NewsServerError("No such group: " + group))
-
-
- def groupRequest(self, group):
- try:
- g = self.dbm['groups'][group]
- except KeyError:
- return defer.fail(NewsServerError("No such group: " + group))
- else:
- flags = g.flags
- low = g.minArticle
- high = g.maxArticle
- num = high - low + 1
- return defer.succeed((group, num, high, low, flags))
-
-
- def articleExistsRequest(self, id):
- return defer.succeed(id in self.dbm['Message-IDs'])
-
-
- def articleRequest(self, group, index, id = None):
- if id is not None:
- try:
- xref = self.dbm['Message-IDs'][id]
- except KeyError:
- return defer.fail(NewsServerError("No such article: " + id))
- else:
- group, index = xref[0]
- index = int(index)
-
- try:
- a = self.dbm['groups'][group].articles[index]
- except KeyError:
- return defer.fail(NewsServerError("No such group: " + group))
- else:
- return defer.succeed((
- index,
- a.getHeader('Message-ID'),
- StringIO.StringIO(a.textHeaders() + '\r\n' + a.body)
- ))
-
-
- def headRequest(self, group, index, id = None):
- if id is not None:
- try:
- xref = self.dbm['Message-IDs'][id]
- except KeyError:
- return defer.fail(NewsServerError("No such article: " + id))
- else:
- group, index = xref[0]
- index = int(index)
-
- try:
- a = self.dbm['groups'][group].articles[index]
- except KeyError:
- return defer.fail(NewsServerError("No such group: " + group))
- else:
- return defer.succeed((index, a.getHeader('Message-ID'), a.textHeaders()))
-
-
- def bodyRequest(self, group, index, id = None):
- if id is not None:
- try:
- xref = self.dbm['Message-IDs'][id]
- except KeyError:
- return defer.fail(NewsServerError("No such article: " + id))
- else:
- group, index = xref[0]
- index = int(index)
-
- try:
- a = self.dbm['groups'][group].articles[index]
- except KeyError:
- return defer.fail(NewsServerError("No such group: " + group))
- else:
- return defer.succeed((index, a.getHeader('Message-ID'), StringIO.StringIO(a.body)))
-
-
-class NewsStorageAugmentation:
- """
- A NewsStorage implementation using Twisted's asynchronous DB-API
- """
-
- implements(INewsStorage)
-
- schema = """
-
- CREATE TABLE groups (
- group_id SERIAL,
- name VARCHAR(80) NOT NULL,
-
- flags INTEGER DEFAULT 0 NOT NULL
- );
-
- CREATE UNIQUE INDEX group_id_index ON groups (group_id);
- CREATE UNIQUE INDEX name_id_index ON groups (name);
-
- CREATE TABLE articles (
- article_id SERIAL,
- message_id TEXT,
-
- header TEXT,
- body TEXT
- );
-
- CREATE UNIQUE INDEX article_id_index ON articles (article_id);
- CREATE UNIQUE INDEX article_message_index ON articles (message_id);
-
- CREATE TABLE postings (
- group_id INTEGER,
- article_id INTEGER,
- article_index INTEGER NOT NULL
- );
-
- CREATE UNIQUE INDEX posting_article_index ON postings (article_id);
-
- CREATE TABLE subscriptions (
- group_id INTEGER
- );
-
- CREATE TABLE overview (
- header TEXT
- );
- """
-
- def __init__(self, info):
- self.info = info
- self.dbpool = adbapi.ConnectionPool(**self.info)
-
-
- def __setstate__(self, state):
- self.__dict__ = state
- self.info['password'] = getpass.getpass('Database password for %s: ' % (self.info['user'],))
- self.dbpool = adbapi.ConnectionPool(**self.info)
- del self.info['password']
-
-
- def listRequest(self):
- # COALESCE may not be totally portable
- # it is shorthand for
- # CASE WHEN (first parameter) IS NOT NULL then (first parameter) ELSE (second parameter) END
- sql = """
- SELECT groups.name,
- COALESCE(MAX(postings.article_index), 0),
- COALESCE(MIN(postings.article_index), 0),
- groups.flags
- FROM groups LEFT OUTER JOIN postings
- ON postings.group_id = groups.group_id
- GROUP BY groups.name, groups.flags
- ORDER BY groups.name
- """
- return self.dbpool.runQuery(sql)
-
-
- def subscriptionRequest(self):
- sql = """
- SELECT groups.name FROM groups,subscriptions WHERE groups.group_id = subscriptions.group_id
- """
- return self.dbpool.runQuery(sql)
-
-
- def postRequest(self, message):
- cleave = message.find('\r\n\r\n')
- headers, article = message[:cleave], message[cleave + 4:]
- article = Article(headers, article)
- return self.dbpool.runInteraction(self._doPost, article)
-
-
- def _doPost(self, transaction, article):
- # Get the group ids
- groups = article.getHeader('Newsgroups').split()
- if not len(groups):
- raise NNTPError('Missing Newsgroups header')
-
- sql = """
- SELECT name, group_id FROM groups
- WHERE name IN (%s)
- """ % (', '.join([("'%s'" % (adbapi.safe(group),)) for group in groups]),)
-
- transaction.execute(sql)
- result = transaction.fetchall()
-
- # No relevant groups, bye bye!
- if not len(result):
- raise NNTPError('None of groups in Newsgroup header carried')
-
- # Got some groups, now find the indices this article will have in each
- sql = """
- SELECT groups.group_id, COALESCE(MAX(postings.article_index), 0) + 1
- FROM groups LEFT OUTER JOIN postings
- ON postings.group_id = groups.group_id
- WHERE groups.group_id IN (%s)
- GROUP BY groups.group_id
- """ % (', '.join([("%d" % (id,)) for (group, id) in result]),)
-
- transaction.execute(sql)
- indices = transaction.fetchall()
-
- if not len(indices):
- raise NNTPError('Internal server error - no indices found')
-
- # Associate indices with group names
- gidToName = dict([(b, a) for (a, b) in result])
- gidToIndex = dict(indices)
-
- nameIndex = []
- for i in gidToName:
- nameIndex.append((gidToName[i], gidToIndex[i]))
-
- # Build xrefs
- xrefs = socket.gethostname().split()[0]
- xrefs = xrefs + ' ' + ' '.join([('%s:%d' % (group, id)) for (group, id) in nameIndex])
- article.putHeader('Xref', xrefs)
-
- # Hey! The article is ready to be posted! God damn f'in finally.
- sql = """
- INSERT INTO articles (message_id, header, body)
- VALUES ('%s', '%s', '%s')
- """ % (
- adbapi.safe(article.getHeader('Message-ID')),
- adbapi.safe(article.textHeaders()),
- adbapi.safe(article.body)
- )
-
- transaction.execute(sql)
-
- # Now update the posting to reflect the groups to which this belongs
- for gid in gidToName:
- sql = """
- INSERT INTO postings (group_id, article_id, article_index)
- VALUES (%d, (SELECT last_value FROM articles_article_id_seq), %d)
- """ % (gid, gidToIndex[gid])
- transaction.execute(sql)
-
- return len(nameIndex)
-
-
- def overviewRequest(self):
- sql = """
- SELECT header FROM overview
- """
- return self.dbpool.runQuery(sql).addCallback(lambda result: [header[0] for header in result])
-
-
- def xoverRequest(self, group, low, high):
- sql = """
- SELECT postings.article_index, articles.header
- FROM articles,postings,groups
- WHERE postings.group_id = groups.group_id
- AND groups.name = '%s'
- AND postings.article_id = articles.article_id
- %s
- %s
- """ % (
- adbapi.safe(group),
- low is not None and "AND postings.article_index >= %d" % (low,) or "",
- high is not None and "AND postings.article_index <= %d" % (high,) or ""
- )
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda results: [
- [id] + Article(header, None).overview() for (id, header) in results
- ]
- )
-
-
- def xhdrRequest(self, group, low, high, header):
- sql = """
- SELECT articles.header
- FROM groups,postings,articles
- WHERE groups.name = '%s' AND postings.group_id = groups.group_id
- AND postings.article_index >= %d
- AND postings.article_index <= %d
- """ % (adbapi.safe(group), low, high)
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda results: [
- (i, Article(h, None).getHeader(h)) for (i, h) in results
- ]
- )
-
-
- def listGroupRequest(self, group):
- sql = """
- SELECT postings.article_index FROM postings,groups
- WHERE postings.group_id = groups.group_id
- AND groups.name = '%s'
- """ % (adbapi.safe(group),)
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda results, group = group: (group, [res[0] for res in results])
- )
-
-
- def groupRequest(self, group):
- sql = """
- SELECT groups.name,
- COUNT(postings.article_index),
- COALESCE(MAX(postings.article_index), 0),
- COALESCE(MIN(postings.article_index), 0),
- groups.flags
- FROM groups LEFT OUTER JOIN postings
- ON postings.group_id = groups.group_id
- WHERE groups.name = '%s'
- GROUP BY groups.name, groups.flags
- """ % (adbapi.safe(group),)
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda results: tuple(results[0])
- )
-
-
- def articleExistsRequest(self, id):
- sql = """
- SELECT COUNT(message_id) FROM articles
- WHERE message_id = '%s'
- """ % (adbapi.safe(id),)
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda result: bool(result[0][0])
- )
-
-
- def articleRequest(self, group, index, id = None):
- if id is not None:
- sql = """
- SELECT postings.article_index, articles.message_id, articles.header, articles.body
- FROM groups,postings LEFT OUTER JOIN articles
- ON articles.message_id = '%s'
- WHERE groups.name = '%s'
- AND groups.group_id = postings.group_id
- """ % (adbapi.safe(id), adbapi.safe(group))
- else:
- sql = """
- SELECT postings.article_index, articles.message_id, articles.header, articles.body
- FROM groups,articles LEFT OUTER JOIN postings
- ON postings.article_id = articles.article_id
- WHERE postings.article_index = %d
- AND postings.group_id = groups.group_id
- AND groups.name = '%s'
- """ % (index, adbapi.safe(group))
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda result: (
- result[0][0],
- result[0][1],
- StringIO.StringIO(result[0][2] + '\r\n' + result[0][3])
- )
- )
-
-
- def headRequest(self, group, index):
- sql = """
- SELECT postings.article_index, articles.message_id, articles.header
- FROM groups,articles LEFT OUTER JOIN postings
- ON postings.article_id = articles.article_id
- WHERE postings.article_index = %d
- AND postings.group_id = groups.group_id
- AND groups.name = '%s'
- """ % (index, adbapi.safe(group))
-
- return self.dbpool.runQuery(sql).addCallback(lambda result: result[0])
-
-
- def bodyRequest(self, group, index):
- sql = """
- SELECT postings.article_index, articles.message_id, articles.body
- FROM groups,articles LEFT OUTER JOIN postings
- ON postings.article_id = articles.article_id
- WHERE postings.article_index = %d
- AND postings.group_id = groups.group_id
- AND groups.name = '%s'
- """ % (index, adbapi.safe(group))
-
- return self.dbpool.runQuery(sql).addCallback(
- lambda result: result[0]
- ).addCallback(
- lambda (index, id, body): (index, id, StringIO.StringIO(body))
- )
-
-####
-#### XXX - make these static methods some day
-####
-def makeGroupSQL(groups):
- res = ''
- for g in groups:
- res = res + """\n INSERT INTO groups (name) VALUES ('%s');\n""" % (adbapi.safe(g),)
- return res
-
-
-def makeOverviewSQL():
- res = ''
- for o in OVERVIEW_FMT:
- res = res + """\n INSERT INTO overview (header) VALUES ('%s');\n""" % (adbapi.safe(o),)
- return res
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/news.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/news.py
deleted file mode 100755
index 81651715..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/news.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Maintainer: Jp Calderone
-"""
-
-from twisted.news import nntp
-from twisted.internet import protocol, reactor
-
-import time
-
-class NNTPFactory(protocol.ServerFactory):
- """A factory for NNTP server protocols."""
-
- protocol = nntp.NNTPServer
-
- def __init__(self, backend):
- self.backend = backend
-
- def buildProtocol(self, connection):
- p = self.protocol()
- p.factory = self
- return p
-
-
-class UsenetClientFactory(protocol.ClientFactory):
- def __init__(self, groups, storage):
- self.lastChecks = {}
- self.groups = groups
- self.storage = storage
-
-
- def clientConnectionLost(self, connector, reason):
- pass
-
-
- def clientConnectionFailed(self, connector, reason):
- print 'Connection failed: ', reason
-
-
- def updateChecks(self, addr):
- self.lastChecks[addr] = time.mktime(time.gmtime())
-
-
- def buildProtocol(self, addr):
- last = self.lastChecks.setdefault(addr, time.mktime(time.gmtime()) - (60 * 60 * 24 * 7))
- p = nntp.UsenetClientProtocol(self.groups, last, self.storage)
- p.factory = self
- return p
-
-
-# XXX - Maybe this inheritence doesn't make so much sense?
-class UsenetServerFactory(NNTPFactory):
- """A factory for NNTP Usenet server protocols."""
-
- protocol = nntp.NNTPServer
-
- def __init__(self, backend, remoteHosts = None, updatePeriod = 60):
- NNTPFactory.__init__(self, backend)
- self.updatePeriod = updatePeriod
- self.remoteHosts = remoteHosts or []
- self.clientFactory = UsenetClientFactory(self.remoteHosts, self.backend)
-
-
- def startFactory(self):
- self._updateCall = reactor.callLater(0, self.syncWithRemotes)
-
-
- def stopFactory(self):
- if self._updateCall:
- self._updateCall.cancel()
- self._updateCall = None
-
-
- def buildProtocol(self, connection):
- p = self.protocol()
- p.factory = self
- return p
-
-
- def syncWithRemotes(self):
- for remote in self.remoteHosts:
- reactor.connectTCP(remote, 119, self.clientFactory)
- self._updateCall = reactor.callLater(self.updatePeriod, self.syncWithRemotes)
-
-
-# backwards compatability
-Factory = UsenetServerFactory
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/nntp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/nntp.py
deleted file mode 100755
index 864bd535..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/nntp.py
+++ /dev/null
@@ -1,1036 +0,0 @@
-# -*- test-case-name: twisted.news.test.test_nntp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-NNTP protocol support.
-
-The following protocol commands are currently understood::
-
- LIST LISTGROUP XOVER XHDR
- POST GROUP ARTICLE STAT HEAD
- BODY NEXT MODE STREAM MODE READER SLAVE
- LAST QUIT HELP IHAVE XPATH
- XINDEX XROVER TAKETHIS CHECK
-
-The following protocol commands require implementation::
-
- NEWNEWS
- XGTITLE XPAT
- XTHREAD AUTHINFO NEWGROUPS
-
-
-Other desired features:
-
- - A real backend
- - More robust client input handling
- - A control protocol
-"""
-
-import time
-
-from twisted.protocols import basic
-from twisted.python import log
-
-def parseRange(text):
- articles = text.split('-')
- if len(articles) == 1:
- try:
- a = int(articles[0])
- return a, a
- except ValueError:
- return None, None
- elif len(articles) == 2:
- try:
- if len(articles[0]):
- l = int(articles[0])
- else:
- l = None
- if len(articles[1]):
- h = int(articles[1])
- else:
- h = None
- except ValueError:
- return None, None
- return l, h
-
-
-def extractCode(line):
- line = line.split(' ', 1)
- if len(line) != 2:
- return None
- try:
- return int(line[0]), line[1]
- except ValueError:
- return None
-
-
-class NNTPError(Exception):
- def __init__(self, string):
- self.string = string
-
- def __str__(self):
- return 'NNTPError: %s' % self.string
-
-
-class NNTPClient(basic.LineReceiver):
- MAX_COMMAND_LENGTH = 510
-
- def __init__(self):
- self.currentGroup = None
-
- self._state = []
- self._error = []
- self._inputBuffers = []
- self._responseCodes = []
- self._responseHandlers = []
-
- self._postText = []
-
- self._newState(self._statePassive, None, self._headerInitial)
-
-
- def gotAllGroups(self, groups):
- "Override for notification when fetchGroups() action is completed"
-
-
- def getAllGroupsFailed(self, error):
- "Override for notification when fetchGroups() action fails"
-
-
- def gotOverview(self, overview):
- "Override for notification when fetchOverview() action is completed"
-
-
- def getOverviewFailed(self, error):
- "Override for notification when fetchOverview() action fails"
-
-
- def gotSubscriptions(self, subscriptions):
- "Override for notification when fetchSubscriptions() action is completed"
-
-
- def getSubscriptionsFailed(self, error):
- "Override for notification when fetchSubscriptions() action fails"
-
-
- def gotGroup(self, group):
- "Override for notification when fetchGroup() action is completed"
-
-
- def getGroupFailed(self, error):
- "Override for notification when fetchGroup() action fails"
-
-
- def gotArticle(self, article):
- "Override for notification when fetchArticle() action is completed"
-
-
- def getArticleFailed(self, error):
- "Override for notification when fetchArticle() action fails"
-
-
- def gotHead(self, head):
- "Override for notification when fetchHead() action is completed"
-
-
- def getHeadFailed(self, error):
- "Override for notification when fetchHead() action fails"
-
-
- def gotBody(self, info):
- "Override for notification when fetchBody() action is completed"
-
-
- def getBodyFailed(self, body):
- "Override for notification when fetchBody() action fails"
-
-
- def postedOk(self):
- "Override for notification when postArticle() action is successful"
-
-
- def postFailed(self, error):
- "Override for notification when postArticle() action fails"
-
-
- def gotXHeader(self, headers):
- "Override for notification when getXHeader() action is successful"
-
-
- def getXHeaderFailed(self, error):
- "Override for notification when getXHeader() action fails"
-
-
- def gotNewNews(self, news):
- "Override for notification when getNewNews() action is successful"
-
-
- def getNewNewsFailed(self, error):
- "Override for notification when getNewNews() action fails"
-
-
- def gotNewGroups(self, groups):
- "Override for notification when getNewGroups() action is successful"
-
-
- def getNewGroupsFailed(self, error):
- "Override for notification when getNewGroups() action fails"
-
-
- def setStreamSuccess(self):
- "Override for notification when setStream() action is successful"
-
-
- def setStreamFailed(self, error):
- "Override for notification when setStream() action fails"
-
-
- def fetchGroups(self):
- """
- Request a list of all news groups from the server. gotAllGroups()
- is called on success, getGroupsFailed() on failure
- """
- self.sendLine('LIST')
- self._newState(self._stateList, self.getAllGroupsFailed)
-
-
- def fetchOverview(self):
- """
- Request the overview format from the server. gotOverview() is called
- on success, getOverviewFailed() on failure
- """
- self.sendLine('LIST OVERVIEW.FMT')
- self._newState(self._stateOverview, self.getOverviewFailed)
-
-
- def fetchSubscriptions(self):
- """
- Request a list of the groups it is recommended a new user subscribe to.
- gotSubscriptions() is called on success, getSubscriptionsFailed() on
- failure
- """
- self.sendLine('LIST SUBSCRIPTIONS')
- self._newState(self._stateSubscriptions, self.getSubscriptionsFailed)
-
-
- def fetchGroup(self, group):
- """
- Get group information for the specified group from the server. gotGroup()
- is called on success, getGroupFailed() on failure.
- """
- self.sendLine('GROUP %s' % (group,))
- self._newState(None, self.getGroupFailed, self._headerGroup)
-
-
- def fetchHead(self, index = ''):
- """
- Get the header for the specified article (or the currently selected
- article if index is '') from the server. gotHead() is called on
- success, getHeadFailed() on failure
- """
- self.sendLine('HEAD %s' % (index,))
- self._newState(self._stateHead, self.getHeadFailed)
-
-
- def fetchBody(self, index = ''):
- """
- Get the body for the specified article (or the currently selected
- article if index is '') from the server. gotBody() is called on
- success, getBodyFailed() on failure
- """
- self.sendLine('BODY %s' % (index,))
- self._newState(self._stateBody, self.getBodyFailed)
-
-
- def fetchArticle(self, index = ''):
- """
- Get the complete article with the specified index (or the currently
- selected article if index is '') or Message-ID from the server.
- gotArticle() is called on success, getArticleFailed() on failure.
- """
- self.sendLine('ARTICLE %s' % (index,))
- self._newState(self._stateArticle, self.getArticleFailed)
-
-
- def postArticle(self, text):
- """
- Attempt to post an article with the specified text to the server. 'text'
- must consist of both head and body data, as specified by RFC 850. If the
- article is posted successfully, postedOk() is called, otherwise postFailed()
- is called.
- """
- self.sendLine('POST')
- self._newState(None, self.postFailed, self._headerPost)
- self._postText.append(text)
-
-
- def fetchNewNews(self, groups, date, distributions = ''):
- """
- Get the Message-IDs for all new news posted to any of the given
- groups since the specified date - in seconds since the epoch, GMT -
- optionally restricted to the given distributions. gotNewNews() is
- called on success, getNewNewsFailed() on failure.
-
- One invocation of this function may result in multiple invocations
- of gotNewNews()/getNewNewsFailed().
- """
- date, timeStr = time.strftime('%y%m%d %H%M%S', time.gmtime(date)).split()
- line = 'NEWNEWS %%s %s %s %s' % (date, timeStr, distributions)
- groupPart = ''
- while len(groups) and len(line) + len(groupPart) + len(groups[-1]) + 1 < NNTPClient.MAX_COMMAND_LENGTH:
- group = groups.pop()
- groupPart = groupPart + ',' + group
-
- self.sendLine(line % (groupPart,))
- self._newState(self._stateNewNews, self.getNewNewsFailed)
-
- if len(groups):
- self.fetchNewNews(groups, date, distributions)
-
-
- def fetchNewGroups(self, date, distributions):
- """
- Get the names of all new groups created/added to the server since
- the specified date - in seconds since the ecpoh, GMT - optionally
- restricted to the given distributions. gotNewGroups() is called
- on success, getNewGroupsFailed() on failure.
- """
- date, timeStr = time.strftime('%y%m%d %H%M%S', time.gmtime(date)).split()
- self.sendLine('NEWGROUPS %s %s %s' % (date, timeStr, distributions))
- self._newState(self._stateNewGroups, self.getNewGroupsFailed)
-
-
- def fetchXHeader(self, header, low = None, high = None, id = None):
- """
- Request a specific header from the server for an article or range
- of articles. If 'id' is not None, a header for only the article
- with that Message-ID will be requested. If both low and high are
- None, a header for the currently selected article will be selected;
- If both low and high are zero-length strings, headers for all articles
- in the currently selected group will be requested; Otherwise, high
- and low will be used as bounds - if one is None the first or last
- article index will be substituted, as appropriate.
- """
- if id is not None:
- r = header + ' <%s>' % (id,)
- elif low is high is None:
- r = header
- elif high is None:
- r = header + ' %d-' % (low,)
- elif low is None:
- r = header + ' -%d' % (high,)
- else:
- r = header + ' %d-%d' % (low, high)
- self.sendLine('XHDR ' + r)
- self._newState(self._stateXHDR, self.getXHeaderFailed)
-
-
- def setStream(self):
- """
- Set the mode to STREAM, suspending the normal "lock-step" mode of
- communications. setStreamSuccess() is called on success,
- setStreamFailed() on failure.
- """
- self.sendLine('MODE STREAM')
- self._newState(None, self.setStreamFailed, self._headerMode)
-
-
- def quit(self):
- self.sendLine('QUIT')
- self.transport.loseConnection()
-
-
- def _newState(self, method, error, responseHandler = None):
- self._inputBuffers.append([])
- self._responseCodes.append(None)
- self._state.append(method)
- self._error.append(error)
- self._responseHandlers.append(responseHandler)
-
-
- def _endState(self):
- buf = self._inputBuffers[0]
- del self._responseCodes[0]
- del self._inputBuffers[0]
- del self._state[0]
- del self._error[0]
- del self._responseHandlers[0]
- return buf
-
-
- def _newLine(self, line, check = 1):
- if check and line and line[0] == '.':
- line = line[1:]
- self._inputBuffers[0].append(line)
-
-
- def _setResponseCode(self, code):
- self._responseCodes[0] = code
-
-
- def _getResponseCode(self):
- return self._responseCodes[0]
-
-
- def lineReceived(self, line):
- if not len(self._state):
- self._statePassive(line)
- elif self._getResponseCode() is None:
- code = extractCode(line)
- if code is None or not (200 <= code[0] < 400): # An error!
- self._error[0](line)
- self._endState()
- else:
- self._setResponseCode(code)
- if self._responseHandlers[0]:
- self._responseHandlers[0](code)
- else:
- self._state[0](line)
-
-
- def _statePassive(self, line):
- log.msg('Server said: %s' % line)
-
-
- def _passiveError(self, error):
- log.err('Passive Error: %s' % (error,))
-
-
- def _headerInitial(self, (code, message)):
- if code == 200:
- self.canPost = 1
- else:
- self.canPost = 0
- self._endState()
-
-
- def _stateList(self, line):
- if line != '.':
- data = filter(None, line.strip().split())
- self._newLine((data[0], int(data[1]), int(data[2]), data[3]), 0)
- else:
- self.gotAllGroups(self._endState())
-
-
- def _stateOverview(self, line):
- if line != '.':
- self._newLine(filter(None, line.strip().split()), 0)
- else:
- self.gotOverview(self._endState())
-
-
- def _stateSubscriptions(self, line):
- if line != '.':
- self._newLine(line.strip(), 0)
- else:
- self.gotSubscriptions(self._endState())
-
-
- def _headerGroup(self, (code, line)):
- self.gotGroup(tuple(line.split()))
- self._endState()
-
-
- def _stateArticle(self, line):
- if line != '.':
- if line.startswith('.'):
- line = line[1:]
- self._newLine(line, 0)
- else:
- self.gotArticle('\n'.join(self._endState())+'\n')
-
-
- def _stateHead(self, line):
- if line != '.':
- self._newLine(line, 0)
- else:
- self.gotHead('\n'.join(self._endState()))
-
-
- def _stateBody(self, line):
- if line != '.':
- if line.startswith('.'):
- line = line[1:]
- self._newLine(line, 0)
- else:
- self.gotBody('\n'.join(self._endState())+'\n')
-
-
- def _headerPost(self, (code, message)):
- if code == 340:
- self.transport.write(self._postText[0].replace('\n', '\r\n').replace('\r\n.', '\r\n..'))
- if self._postText[0][-1:] != '\n':
- self.sendLine('')
- self.sendLine('.')
- del self._postText[0]
- self._newState(None, self.postFailed, self._headerPosted)
- else:
- self.postFailed('%d %s' % (code, message))
- self._endState()
-
-
- def _headerPosted(self, (code, message)):
- if code == 240:
- self.postedOk()
- else:
- self.postFailed('%d %s' % (code, message))
- self._endState()
-
-
- def _stateXHDR(self, line):
- if line != '.':
- self._newLine(line.split(), 0)
- else:
- self._gotXHeader(self._endState())
-
-
- def _stateNewNews(self, line):
- if line != '.':
- self._newLine(line, 0)
- else:
- self.gotNewNews(self._endState())
-
-
- def _stateNewGroups(self, line):
- if line != '.':
- self._newLine(line, 0)
- else:
- self.gotNewGroups(self._endState())
-
-
- def _headerMode(self, (code, message)):
- if code == 203:
- self.setStreamSuccess()
- else:
- self.setStreamFailed((code, message))
- self._endState()
-
-
-class NNTPServer(basic.LineReceiver):
- COMMANDS = [
- 'LIST', 'GROUP', 'ARTICLE', 'STAT', 'MODE', 'LISTGROUP', 'XOVER',
- 'XHDR', 'HEAD', 'BODY', 'NEXT', 'LAST', 'POST', 'QUIT', 'IHAVE',
- 'HELP', 'SLAVE', 'XPATH', 'XINDEX', 'XROVER', 'TAKETHIS', 'CHECK'
- ]
-
- def __init__(self):
- self.servingSlave = 0
-
-
- def connectionMade(self):
- self.inputHandler = None
- self.currentGroup = None
- self.currentIndex = None
- self.sendLine('200 server ready - posting allowed')
-
- def lineReceived(self, line):
- if self.inputHandler is not None:
- self.inputHandler(line)
- else:
- parts = line.strip().split()
- if len(parts):
- cmd, parts = parts[0].upper(), parts[1:]
- if cmd in NNTPServer.COMMANDS:
- func = getattr(self, 'do_%s' % cmd)
- try:
- func(*parts)
- except TypeError:
- self.sendLine('501 command syntax error')
- log.msg("501 command syntax error")
- log.msg("command was", line)
- log.deferr()
- except:
- self.sendLine('503 program fault - command not performed')
- log.msg("503 program fault")
- log.msg("command was", line)
- log.deferr()
- else:
- self.sendLine('500 command not recognized')
-
-
- def do_LIST(self, subcmd = '', *dummy):
- subcmd = subcmd.strip().lower()
- if subcmd == 'newsgroups':
- # XXX - this could use a real implementation, eh?
- self.sendLine('215 Descriptions in form "group description"')
- self.sendLine('.')
- elif subcmd == 'overview.fmt':
- defer = self.factory.backend.overviewRequest()
- defer.addCallbacks(self._gotOverview, self._errOverview)
- log.msg('overview')
- elif subcmd == 'subscriptions':
- defer = self.factory.backend.subscriptionRequest()
- defer.addCallbacks(self._gotSubscription, self._errSubscription)
- log.msg('subscriptions')
- elif subcmd == '':
- defer = self.factory.backend.listRequest()
- defer.addCallbacks(self._gotList, self._errList)
- else:
- self.sendLine('500 command not recognized')
-
-
- def _gotList(self, list):
- self.sendLine('215 newsgroups in form "group high low flags"')
- for i in list:
- self.sendLine('%s %d %d %s' % tuple(i))
- self.sendLine('.')
-
-
- def _errList(self, failure):
- print 'LIST failed: ', failure
- self.sendLine('503 program fault - command not performed')
-
-
- def _gotSubscription(self, parts):
- self.sendLine('215 information follows')
- for i in parts:
- self.sendLine(i)
- self.sendLine('.')
-
-
- def _errSubscription(self, failure):
- print 'SUBSCRIPTIONS failed: ', failure
- self.sendLine('503 program fault - comand not performed')
-
-
- def _gotOverview(self, parts):
- self.sendLine('215 Order of fields in overview database.')
- for i in parts:
- self.sendLine(i + ':')
- self.sendLine('.')
-
-
- def _errOverview(self, failure):
- print 'LIST OVERVIEW.FMT failed: ', failure
- self.sendLine('503 program fault - command not performed')
-
-
- def do_LISTGROUP(self, group = None):
- group = group or self.currentGroup
- if group is None:
- self.sendLine('412 Not currently in newsgroup')
- else:
- defer = self.factory.backend.listGroupRequest(group)
- defer.addCallbacks(self._gotListGroup, self._errListGroup)
-
-
- def _gotListGroup(self, (group, articles)):
- self.currentGroup = group
- if len(articles):
- self.currentIndex = int(articles[0])
- else:
- self.currentIndex = None
-
- self.sendLine('211 list of article numbers follow')
- for i in articles:
- self.sendLine(str(i))
- self.sendLine('.')
-
-
- def _errListGroup(self, failure):
- print 'LISTGROUP failed: ', failure
- self.sendLine('502 no permission')
-
-
- def do_XOVER(self, range):
- if self.currentGroup is None:
- self.sendLine('412 No news group currently selected')
- else:
- l, h = parseRange(range)
- defer = self.factory.backend.xoverRequest(self.currentGroup, l, h)
- defer.addCallbacks(self._gotXOver, self._errXOver)
-
-
- def _gotXOver(self, parts):
- self.sendLine('224 Overview information follows')
- for i in parts:
- self.sendLine('\t'.join(map(str, i)))
- self.sendLine('.')
-
-
- def _errXOver(self, failure):
- print 'XOVER failed: ', failure
- self.sendLine('420 No article(s) selected')
-
-
- def xhdrWork(self, header, range):
- if self.currentGroup is None:
- self.sendLine('412 No news group currently selected')
- else:
- if range is None:
- if self.currentIndex is None:
- self.sendLine('420 No current article selected')
- return
- else:
- l = h = self.currentIndex
- else:
- # FIXME: articles may be a message-id
- l, h = parseRange(range)
-
- if l is h is None:
- self.sendLine('430 no such article')
- else:
- return self.factory.backend.xhdrRequest(self.currentGroup, l, h, header)
-
-
- def do_XHDR(self, header, range = None):
- d = self.xhdrWork(header, range)
- if d:
- d.addCallbacks(self._gotXHDR, self._errXHDR)
-
-
- def _gotXHDR(self, parts):
- self.sendLine('221 Header follows')
- for i in parts:
- self.sendLine('%d %s' % i)
- self.sendLine('.')
-
- def _errXHDR(self, failure):
- print 'XHDR failed: ', failure
- self.sendLine('502 no permission')
-
-
- def do_POST(self):
- self.inputHandler = self._doingPost
- self.message = ''
- self.sendLine('340 send article to be posted. End with <CR-LF>.<CR-LF>')
-
-
- def _doingPost(self, line):
- if line == '.':
- self.inputHandler = None
- group, article = self.currentGroup, self.message
- self.message = ''
-
- defer = self.factory.backend.postRequest(article)
- defer.addCallbacks(self._gotPost, self._errPost)
- else:
- self.message = self.message + line + '\r\n'
-
-
- def _gotPost(self, parts):
- self.sendLine('240 article posted ok')
-
-
- def _errPost(self, failure):
- print 'POST failed: ', failure
- self.sendLine('441 posting failed')
-
-
- def do_CHECK(self, id):
- d = self.factory.backend.articleExistsRequest(id)
- d.addCallbacks(self._gotCheck, self._errCheck)
-
-
- def _gotCheck(self, result):
- if result:
- self.sendLine("438 already have it, please don't send it to me")
- else:
- self.sendLine('238 no such article found, please send it to me')
-
-
- def _errCheck(self, failure):
- print 'CHECK failed: ', failure
- self.sendLine('431 try sending it again later')
-
-
- def do_TAKETHIS(self, id):
- self.inputHandler = self._doingTakeThis
- self.message = ''
-
-
- def _doingTakeThis(self, line):
- if line == '.':
- self.inputHandler = None
- article = self.message
- self.message = ''
- d = self.factory.backend.postRequest(article)
- d.addCallbacks(self._didTakeThis, self._errTakeThis)
- else:
- self.message = self.message + line + '\r\n'
-
-
- def _didTakeThis(self, result):
- self.sendLine('239 article transferred ok')
-
-
- def _errTakeThis(self, failure):
- print 'TAKETHIS failed: ', failure
- self.sendLine('439 article transfer failed')
-
-
- def do_GROUP(self, group):
- defer = self.factory.backend.groupRequest(group)
- defer.addCallbacks(self._gotGroup, self._errGroup)
-
-
- def _gotGroup(self, (name, num, high, low, flags)):
- self.currentGroup = name
- self.currentIndex = low
- self.sendLine('211 %d %d %d %s group selected' % (num, low, high, name))
-
-
- def _errGroup(self, failure):
- print 'GROUP failed: ', failure
- self.sendLine('411 no such group')
-
-
- def articleWork(self, article, cmd, func):
- if self.currentGroup is None:
- self.sendLine('412 no newsgroup has been selected')
- else:
- if not article:
- if self.currentIndex is None:
- self.sendLine('420 no current article has been selected')
- else:
- article = self.currentIndex
- else:
- if article[0] == '<':
- return func(self.currentGroup, index = None, id = article)
- else:
- try:
- article = int(article)
- return func(self.currentGroup, article)
- except ValueError:
- self.sendLine('501 command syntax error')
-
-
- def do_ARTICLE(self, article = None):
- defer = self.articleWork(article, 'ARTICLE', self.factory.backend.articleRequest)
- if defer:
- defer.addCallbacks(self._gotArticle, self._errArticle)
-
-
- def _gotArticle(self, (index, id, article)):
- self.currentIndex = index
- self.sendLine('220 %d %s article' % (index, id))
- s = basic.FileSender()
- d = s.beginFileTransfer(article, self.transport)
- d.addCallback(self.finishedFileTransfer)
-
- ##
- ## Helper for FileSender
- ##
- def finishedFileTransfer(self, lastsent):
- if lastsent != '\n':
- line = '\r\n.'
- else:
- line = '.'
- self.sendLine(line)
- ##
-
- def _errArticle(self, failure):
- print 'ARTICLE failed: ', failure
- self.sendLine('423 bad article number')
-
-
- def do_STAT(self, article = None):
- defer = self.articleWork(article, 'STAT', self.factory.backend.articleRequest)
- if defer:
- defer.addCallbacks(self._gotStat, self._errStat)
-
-
- def _gotStat(self, (index, id, article)):
- self.currentIndex = index
- self.sendLine('223 %d %s article retreived - request text separately' % (index, id))
-
-
- def _errStat(self, failure):
- print 'STAT failed: ', failure
- self.sendLine('423 bad article number')
-
-
- def do_HEAD(self, article = None):
- defer = self.articleWork(article, 'HEAD', self.factory.backend.headRequest)
- if defer:
- defer.addCallbacks(self._gotHead, self._errHead)
-
-
- def _gotHead(self, (index, id, head)):
- self.currentIndex = index
- self.sendLine('221 %d %s article retrieved' % (index, id))
- self.transport.write(head + '\r\n')
- self.sendLine('.')
-
-
- def _errHead(self, failure):
- print 'HEAD failed: ', failure
- self.sendLine('423 no such article number in this group')
-
-
- def do_BODY(self, article):
- defer = self.articleWork(article, 'BODY', self.factory.backend.bodyRequest)
- if defer:
- defer.addCallbacks(self._gotBody, self._errBody)
-
-
- def _gotBody(self, (index, id, body)):
- self.currentIndex = index
- self.sendLine('221 %d %s article retrieved' % (index, id))
- self.lastsent = ''
- s = basic.FileSender()
- d = s.beginFileTransfer(body, self.transport)
- d.addCallback(self.finishedFileTransfer)
-
- def _errBody(self, failure):
- print 'BODY failed: ', failure
- self.sendLine('423 no such article number in this group')
-
-
- # NEXT and LAST are just STATs that increment currentIndex first.
- # Accordingly, use the STAT callbacks.
- def do_NEXT(self):
- i = self.currentIndex + 1
- defer = self.factory.backend.articleRequest(self.currentGroup, i)
- defer.addCallbacks(self._gotStat, self._errStat)
-
-
- def do_LAST(self):
- i = self.currentIndex - 1
- defer = self.factory.backend.articleRequest(self.currentGroup, i)
- defer.addCallbacks(self._gotStat, self._errStat)
-
-
- def do_MODE(self, cmd):
- cmd = cmd.strip().upper()
- if cmd == 'READER':
- self.servingSlave = 0
- self.sendLine('200 Hello, you can post')
- elif cmd == 'STREAM':
- self.sendLine('500 Command not understood')
- else:
- # This is not a mistake
- self.sendLine('500 Command not understood')
-
-
- def do_QUIT(self):
- self.sendLine('205 goodbye')
- self.transport.loseConnection()
-
-
- def do_HELP(self):
- self.sendLine('100 help text follows')
- self.sendLine('Read the RFC.')
- self.sendLine('.')
-
-
- def do_SLAVE(self):
- self.sendLine('202 slave status noted')
- self.servingeSlave = 1
-
-
- def do_XPATH(self, article):
- # XPATH is a silly thing to have. No client has the right to ask
- # for this piece of information from me, and so that is what I'll
- # tell them.
- self.sendLine('502 access restriction or permission denied')
-
-
- def do_XINDEX(self, article):
- # XINDEX is another silly command. The RFC suggests it be relegated
- # to the history books, and who am I to disagree?
- self.sendLine('502 access restriction or permission denied')
-
-
- def do_XROVER(self, range=None):
- """
- Handle a request for references of all messages in the currently
- selected group.
-
- This generates the same response a I{XHDR References} request would
- generate.
- """
- self.do_XHDR('References', range)
-
-
- def do_IHAVE(self, id):
- self.factory.backend.articleExistsRequest(id).addCallback(self._foundArticle)
-
-
- def _foundArticle(self, result):
- if result:
- self.sendLine('437 article rejected - do not try again')
- else:
- self.sendLine('335 send article to be transferred. End with <CR-LF>.<CR-LF>')
- self.inputHandler = self._handleIHAVE
- self.message = ''
-
-
- def _handleIHAVE(self, line):
- if line == '.':
- self.inputHandler = None
- self.factory.backend.postRequest(
- self.message
- ).addCallbacks(self._gotIHAVE, self._errIHAVE)
-
- self.message = ''
- else:
- self.message = self.message + line + '\r\n'
-
-
- def _gotIHAVE(self, result):
- self.sendLine('235 article transferred ok')
-
-
- def _errIHAVE(self, failure):
- print 'IHAVE failed: ', failure
- self.sendLine('436 transfer failed - try again later')
-
-
-class UsenetClientProtocol(NNTPClient):
- """
- A client that connects to an NNTP server and asks for articles new
- since a certain time.
- """
-
- def __init__(self, groups, date, storage):
- """
- Fetch all new articles from the given groups since the
- given date and dump them into the given storage. groups
- is a list of group names. date is an integer or floating
- point representing seconds since the epoch (GMT). storage is
- any object that implements the NewsStorage interface.
- """
- NNTPClient.__init__(self)
- self.groups, self.date, self.storage = groups, date, storage
-
-
- def connectionMade(self):
- NNTPClient.connectionMade(self)
- log.msg("Initiating update with remote host: " + str(self.transport.getPeer()))
- self.setStream()
- self.fetchNewNews(self.groups, self.date, '')
-
-
- def articleExists(self, exists, article):
- if exists:
- self.fetchArticle(article)
- else:
- self.count = self.count - 1
- self.disregard = self.disregard + 1
-
-
- def gotNewNews(self, news):
- self.disregard = 0
- self.count = len(news)
- log.msg("Transfering " + str(self.count) + " articles from remote host: " + str(self.transport.getPeer()))
- for i in news:
- self.storage.articleExistsRequest(i).addCallback(self.articleExists, i)
-
-
- def getNewNewsFailed(self, reason):
- log.msg("Updated failed (" + reason + ") with remote host: " + str(self.transport.getPeer()))
- self.quit()
-
-
- def gotArticle(self, article):
- self.storage.postRequest(article)
- self.count = self.count - 1
- if not self.count:
- log.msg("Completed update with remote host: " + str(self.transport.getPeer()))
- if self.disregard:
- log.msg("Disregarded %d articles." % (self.disregard,))
- self.factory.updateChecks(self.transport.getPeer())
- self.quit()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/tap.py
deleted file mode 100755
index a4cf5428..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/tap.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.news import news, database
-from twisted.application import strports
-from twisted.python import usage, log
-
-class DBOptions(usage.Options):
- optParameters = [
- ['module', None, 'pyPgSQL.PgSQL', "DB-API 2.0 module to use"],
- ['dbhost', None, 'localhost', "Host where database manager is listening"],
- ['dbuser', None, 'news', "Username with which to connect to database"],
- ['database', None, 'news', "Database name to use"],
- ['schema', None, 'schema.sql', "File to which to write SQL schema initialisation"],
-
- # XXX - Hrm.
- ["groups", "g", "groups.list", "File containing group list"],
- ["servers", "s", "servers.list", "File containing server list"]
- ]
-
- def postOptions(self):
- # XXX - Hmmm.
- self['groups'] = [g.strip() for g in open(self['groups']).readlines() if not g.startswith('#')]
- self['servers'] = [s.strip() for s in open(self['servers']).readlines() if not s.startswith('#')]
-
- try:
- __import__(self['module'])
- except ImportError:
- log.msg("Warning: Cannot import %s" % (self['module'],))
-
- f = open(self['schema'], 'w')
- f.write(
- database.NewsStorageAugmentation.schema + '\n' +
- database.makeGroupSQL(self['groups']) + '\n' +
- database.makeOverviewSQL()
- )
- f.close()
-
- info = {
- 'host': self['dbhost'], 'user': self['dbuser'],
- 'database': self['database'], 'dbapiName': self['module']
- }
- self.db = database.NewsStorageAugmentation(info)
-
-
-class PickleOptions(usage.Options):
- optParameters = [
- ['file', None, 'news.pickle', "File to which to save pickle"],
-
- # XXX - Hrm.
- ["groups", "g", "groups.list", "File containing group list"],
- ["servers", "s", "servers.list", "File containing server list"],
- ["moderators", "m", "moderators.list",
- "File containing moderators list"],
- ]
-
- subCommands = None
-
- def postOptions(self):
- # XXX - Hmmm.
- filename = self['file']
- self['groups'] = [g.strip() for g in open(self['groups']).readlines()
- if not g.startswith('#')]
- self['servers'] = [s.strip() for s in open(self['servers']).readlines()
- if not s.startswith('#')]
- self['moderators'] = [s.split()
- for s in open(self['moderators']).readlines()
- if not s.startswith('#')]
- self.db = database.PickleStorage(filename, self['groups'],
- self['moderators'])
-
-
-class Options(usage.Options):
- synopsis = "[options]"
-
- groups = None
- servers = None
- subscriptions = None
-
- optParameters = [
- ["port", "p", "119", "Listen port"],
- ["interface", "i", "", "Interface to which to bind"],
- ["datadir", "d", "news.db", "Root data storage path"],
- ["mailhost", "m", "localhost", "Host of SMTP server to use"]
- ]
- compData = usage.Completions(
- optActions={"datadir" : usage.CompleteDirs(),
- "mailhost" : usage.CompleteHostnames(),
- "interface" : usage.CompleteNetInterfaces()}
- )
-
- def __init__(self):
- usage.Options.__init__(self)
- self.groups = []
- self.servers = []
- self.subscriptions = []
-
-
- def opt_group(self, group):
- """The name of a newsgroup to carry."""
- self.groups.append([group, None])
-
-
- def opt_moderator(self, moderator):
- """The email of the moderator for the most recently passed group."""
- self.groups[-1][1] = moderator
-
-
- def opt_subscription(self, group):
- """A newsgroup to list as a recommended subscription."""
- self.subscriptions.append(group)
-
-
- def opt_server(self, server):
- """The address of a Usenet server to pass messages to and receive messages from."""
- self.servers.append(server)
-
-
-def makeService(config):
- if not len(config.groups):
- raise usage.UsageError("No newsgroups specified")
-
- db = database.NewsShelf(config['mailhost'], config['datadir'])
- for (g, m) in config.groups:
- if m:
- db.addGroup(g, 'm')
- db.addModerator(g, m)
- else:
- db.addGroup(g, 'y')
- for s in config.subscriptions:
- print s
- db.addSubscription(s)
- s = config['port']
- if config['interface']:
- # Add a warning here
- s += ':interface='+config['interface']
- return strports.service(s, news.UsenetServerFactory(db, config.servers))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/__init__.py
deleted file mode 100755
index 677518dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""News Tests"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_database.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_database.py
deleted file mode 100755
index 42900a2b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_database.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.news.database}.
-"""
-
-__metaclass__ = type
-
-from email.Parser import Parser
-from socket import gethostname
-
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import succeed
-from twisted.mail.smtp import messageid
-from twisted.news.database import Article, PickleStorage, NewsShelf
-
-
-
-class ModerationTestsMixin:
- """
- Tests for the moderation features of L{INewsStorage} implementations.
- """
- def setUp(self):
- self._email = []
-
-
- def sendmail(self, smtphost, from_addr, to_addrs, msg,
- senderDomainName=None, port=25):
- """
- Fake of L{twisted.mail.smtp.sendmail} which records attempts to send
- email and immediately pretends success.
-
- Subclasses should arrange for their storage implementation to call this
- instead of the real C{sendmail} function.
- """
- self._email.append((
- smtphost, from_addr, to_addrs, msg, senderDomainName, port))
- return succeed(None)
-
-
- _messageTemplate = """\
-From: some dude
-To: another person
-Subject: activities etc
-Message-ID: %(articleID)s
-Newsgroups: %(newsgroup)s
-%(approved)s
-Body of the message is such.
-""".replace('\n', '\r\n')
-
-
- def getApprovedMessage(self, articleID, group):
- """
- Return a C{str} containing an RFC 2822 formatted message including an
- I{Approved} header indicating it has passed through moderation.
- """
- return self._messageTemplate % {
- 'articleID': articleID,
- 'newsgroup': group,
- 'approved': 'Approved: yup\r\n'}
-
-
- def getUnapprovedMessage(self, articleID, group):
- """
- Return a C{str} containing an RFC 2822 formatted message with no
- I{Approved} header indicating it may require moderation.
- """
- return self._messageTemplate % {
- 'articleID': articleID,
- 'newsgroup': group,
- 'approved': '\r\n'}
-
-
- def getStorage(self, groups, moderators, mailhost, sender):
- """
- Override in a subclass to return a L{INewsStorage} provider to test for
- correct moderation behavior.
-
- @param groups: A C{list} of C{str} naming the groups which should exist
- in the resulting storage object.
-
- @param moderators: A C{dict} mapping C{str} each group name to a C{list}
- of C{str} giving moderator email (RFC 2821) addresses.
- """
- raise NotImplementedError()
-
-
- def test_postApproved(self):
- """
- L{INewsStorage.postRequest} posts the message if it includes an
- I{Approved} header.
- """
- group = "example.group"
- moderator = "alice@example.com"
- mailhost = "127.0.0.1"
- sender = "bob@example.org"
- articleID = messageid()
- storage = self.getStorage(
- [group], {group: [moderator]}, mailhost, sender)
- message = self.getApprovedMessage(articleID, group)
- result = storage.postRequest(message)
-
- def cbPosted(ignored):
- self.assertEqual(self._email, [])
- exists = storage.articleExistsRequest(articleID)
- exists.addCallback(self.assertTrue)
- return exists
- result.addCallback(cbPosted)
- return result
-
-
- def test_postModerated(self):
- """
- L{INewsStorage.postRequest} forwards a message to the moderator if it
- does not include an I{Approved} header.
- """
- group = "example.group"
- moderator = "alice@example.com"
- mailhost = "127.0.0.1"
- sender = "bob@example.org"
- articleID = messageid()
- storage = self.getStorage(
- [group], {group: [moderator]}, mailhost, sender)
- message = self.getUnapprovedMessage(articleID, group)
- result = storage.postRequest(message)
-
- def cbModerated(ignored):
- self.assertEqual(len(self._email), 1)
- self.assertEqual(self._email[0][0], mailhost)
- self.assertEqual(self._email[0][1], sender)
- self.assertEqual(self._email[0][2], [moderator])
- self._checkModeratorMessage(
- self._email[0][3], sender, moderator, group, message)
- self.assertEqual(self._email[0][4], None)
- self.assertEqual(self._email[0][5], 25)
- exists = storage.articleExistsRequest(articleID)
- exists.addCallback(self.assertFalse)
- return exists
- result.addCallback(cbModerated)
- return result
-
-
- def _checkModeratorMessage(self, messageText, sender, moderator, group, postingText):
- p = Parser()
- msg = p.parsestr(messageText)
- headers = dict(msg.items())
- del headers['Message-ID']
- self.assertEqual(
- headers,
- {'From': sender,
- 'To': moderator,
- 'Subject': 'Moderate new %s message: activities etc' % (group,),
- 'Content-Type': 'message/rfc822'})
-
- posting = p.parsestr(postingText)
- attachment = msg.get_payload()[0]
-
- for header in ['from', 'to', 'subject', 'message-id', 'newsgroups']:
- self.assertEqual(posting[header], attachment[header])
-
- self.assertEqual(posting.get_payload(), attachment.get_payload())
-
-
-
-class PickleStorageTests(ModerationTestsMixin, TestCase):
- """
- Tests for L{PickleStorage}.
- """
- def getStorage(self, groups, moderators, mailhost, sender):
- """
- Create and return a L{PickleStorage} instance configured to require
- moderation.
- """
- storageFilename = self.mktemp()
- storage = PickleStorage(
- storageFilename, groups, moderators, mailhost, sender)
- storage.sendmail = self.sendmail
- self.addCleanup(PickleStorage.sharedDBs.pop, storageFilename)
- return storage
-
-
-
-class NewsShelfTests(ModerationTestsMixin, TestCase):
- """
- Tests for L{NewsShelf}.
- """
- def getStorage(self, groups, moderators, mailhost, sender):
- """
- Create and return a L{NewsShelf} instance configured to require
- moderation.
- """
- storageFilename = self.mktemp()
- shelf = NewsShelf(mailhost, storageFilename, sender)
- for name in groups:
- shelf.addGroup(name, 'm') # Dial 'm' for moderator
- for address in moderators.get(name, []):
- shelf.addModerator(name, address)
- shelf.sendmail = self.sendmail
- return shelf
-
-
- def test_notifyModerator(self):
- """
- L{NewsShelf.notifyModerator} sends a moderation email to a single
- moderator.
- """
- shelf = NewsShelf('example.com', self.mktemp(), 'alice@example.com')
- shelf.sendmail = self.sendmail
- shelf.notifyModerator('bob@example.org', Article('Foo: bar', 'Some text'))
- self.assertEqual(len(self._email), 1)
-
-
- def test_defaultSender(self):
- """
- If no sender is specified to L{NewsShelf.notifyModerators}, a default
- address based on the system hostname is used for both the envelope and
- RFC 2822 sender addresses.
- """
- shelf = NewsShelf('example.com', self.mktemp())
- shelf.sendmail = self.sendmail
- shelf.notifyModerators(['bob@example.org'], Article('Foo: bar', 'Some text'))
- self.assertEqual(self._email[0][1], 'twisted-news@' + gethostname())
- self.assertIn('From: twisted-news@' + gethostname(), self._email[0][3])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_news.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_news.py
deleted file mode 100755
index 35ac7d75..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_news.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, types
-from pprint import pformat
-
-from twisted.trial import unittest
-from twisted.news import database
-from twisted.internet import reactor
-
-MESSAGE_ID = "f83ba57450ed0fd8ac9a472b847e830e"
-
-POST_STRING = """Path: not-for-mail
-From: <exarkun@somehost.domain.com>
-Subject: a test
-Newsgroups: alt.test.nntp
-Organization:
-Summary:
-Keywords:
-Message-Id: %s
-User-Agent: tin/1.4.5-20010409 ("One More Nightmare") (UNIX) (Linux/2.4.17 (i686))
-
-this is a test
-...
-lala
-moo
---
-"One World, one Web, one Program." - Microsoft(R) promotional ad
-"Ein Volk, ein Reich, ein Fuhrer." - Adolf Hitler
---
- 10:56pm up 4 days, 4:42, 1 user, load average: 0.08, 0.08, 0.12
-""" % (MESSAGE_ID)
-
-class NewsTestCase(unittest.TestCase):
- def setUp(self):
- self.backend = database.NewsShelf(None, 'news2.db')
- self.backend.addGroup('alt.test.nntp', 'y')
- self.backend.postRequest(POST_STRING.replace('\n', '\r\n'))
-
-
- def testArticleExists(self):
- d = self.backend.articleExistsRequest(MESSAGE_ID)
- d.addCallback(self.failUnless)
- return d
-
-
- def testArticleRequest(self):
- d = self.backend.articleRequest(None, None, MESSAGE_ID)
-
- def cbArticle(result):
- self.failUnless(isinstance(result, tuple),
- 'callback result is wrong type: ' + str(result))
- self.assertEqual(len(result), 3,
- 'callback result list should have three entries: ' +
- str(result))
- self.assertEqual(result[1], MESSAGE_ID,
- "callback result Message-Id doesn't match: %s vs %s" %
- (MESSAGE_ID, result[1]))
- body = result[2].read()
- self.failIfEqual(body.find('\r\n\r\n'), -1,
- "Can't find \\r\\n\\r\\n between header and body")
- return result
-
- d.addCallback(cbArticle)
- return d
-
-
- def testHeadRequest(self):
- d = self.testArticleRequest()
-
- def cbArticle(result):
- index = result[0]
-
- d = self.backend.headRequest("alt.test.nntp", index)
- d.addCallback(cbHead)
- return d
-
- def cbHead(result):
- self.assertEqual(result[1], MESSAGE_ID,
- "callback result Message-Id doesn't match: %s vs %s" %
- (MESSAGE_ID, result[1]))
-
- self.assertEqual(result[2][-2:], '\r\n',
- "headers must be \\r\\n terminated.")
-
- d.addCallback(cbArticle)
- return d
-
-
- def testBodyRequest(self):
- d = self.testArticleRequest()
-
- def cbArticle(result):
- index = result[0]
-
- d = self.backend.bodyRequest("alt.test.nntp", index)
- d.addCallback(cbBody)
- return d
-
- def cbBody(result):
- body = result[2].read()
- self.assertEqual(body[0:4], 'this',
- "message body has been altered: " +
- pformat(body[0:4]))
-
- d.addCallback(cbArticle)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_nntp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_nntp.py
deleted file mode 100755
index 987546ba..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/test/test_nntp.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-from twisted.news import database
-from twisted.news import nntp
-from twisted.protocols import loopback
-from twisted.test import proto_helpers
-
-ALL_GROUPS = ('alt.test.nntp', 0, 1, 'y'),
-GROUP = ('0', '1', '0', 'alt.test.nntp', 'group', 'selected')
-SUBSCRIPTIONS = ['alt.test.nntp', 'news.testgroup']
-
-POST_STRING = """Path: not-for-mail
-From: <exarkun@somehost.domain.com>
-Subject: a test
-Newsgroups: alt.test.nntp
-Organization:
-Summary:
-Keywords:
-User-Agent: tin/1.4.5-20010409 ("One More Nightmare") (UNIX) (Linux/2.4.17 (i686))
-
-this is a test
-.
-..
-...
-lala
-moo
---
-"One World, one Web, one Program." - Microsoft(R) promotional ad
-"Ein Volk, ein Reich, ein Fuhrer." - Adolf Hitler
---
- 10:56pm up 4 days, 4:42, 1 user, load average: 0.08, 0.08, 0.12
-"""
-
-class TestNNTPClient(nntp.NNTPClient):
- def __init__(self):
- nntp.NNTPClient.__init__(self)
-
- def assertEqual(self, foo, bar):
- if foo != bar: raise AssertionError("%r != %r!" % (foo, bar))
-
- def connectionMade(self):
- nntp.NNTPClient.connectionMade(self)
- self.fetchSubscriptions()
-
-
- def gotSubscriptions(self, subscriptions):
- self.assertEqual(len(subscriptions), len(SUBSCRIPTIONS))
- for s in subscriptions:
- assert s in SUBSCRIPTIONS
-
- self.fetchGroups()
-
- def gotAllGroups(self, info):
- self.assertEqual(len(info), len(ALL_GROUPS))
- self.assertEqual(info[0], ALL_GROUPS[0])
-
- self.fetchGroup('alt.test.nntp')
-
-
- def getAllGroupsFailed(self, error):
- raise AssertionError("fetchGroups() failed: %s" % (error,))
-
-
- def gotGroup(self, info):
- self.assertEqual(len(info), 6)
- self.assertEqual(info, GROUP)
-
- self.postArticle(POST_STRING)
-
-
- def getSubscriptionsFailed(self, error):
- raise AssertionError("fetchSubscriptions() failed: %s" % (error,))
-
-
- def getGroupFailed(self, error):
- raise AssertionError("fetchGroup() failed: %s" % (error,))
-
-
- def postFailed(self, error):
- raise AssertionError("postArticle() failed: %s" % (error,))
-
-
- def postedOk(self):
- self.fetchArticle(1)
-
-
- def gotArticle(self, info):
- origBody = POST_STRING.split('\n\n')[1]
- newBody = info.split('\n\n', 1)[1]
-
- self.assertEqual(origBody, newBody)
-
- # We're done
- self.transport.loseConnection()
-
-
- def getArticleFailed(self, error):
- raise AssertionError("fetchArticle() failed: %s" % (error,))
-
-
-class NNTPTestCase(unittest.TestCase):
- def setUp(self):
- self.server = nntp.NNTPServer()
- self.server.factory = self
- self.backend = database.NewsShelf(None, 'news.db')
- self.backend.addGroup('alt.test.nntp', 'y')
-
- for s in SUBSCRIPTIONS:
- self.backend.addSubscription(s)
-
- self.transport = proto_helpers.StringTransport()
- self.server.makeConnection(self.transport)
- self.client = TestNNTPClient()
-
- def testLoopback(self):
- return loopback.loopbackAsync(self.server, self.client)
-
- # XXX This test is woefully incomplete. It tests the single
- # most common code path and nothing else. Expand it and the
- # test fairy will leave you a surprise.
-
- # reactor.iterate(1) # fetchGroups()
- # reactor.iterate(1) # fetchGroup()
- # reactor.iterate(1) # postArticle()
-
-
- def test_connectionMade(self):
- """
- When L{NNTPServer} is connected, it sends a server greeting to the
- client.
- """
- self.assertEqual(
- self.transport.value().split('\r\n'), [
- '200 server ready - posting allowed',
- ''])
-
-
- def test_LIST(self):
- """
- When L{NTTPServer} receives a I{LIST} command, it sends a list of news
- groups to the client (RFC 3977, section 7.6.1.1).
- """
- self.transport.clear()
- self.server.do_LIST()
- self.assertEqual(
- self.transport.value().split('\r\n'), [
- '215 newsgroups in form "group high low flags"',
- 'alt.test.nntp 0 1 y',
- '.',
- ''])
-
-
- def test_GROUP(self):
- """
- When L{NNTPServer} receives a I{GROUP} command, it sends a line of
- information about that group to the client (RFC 3977, section 6.1.1.1).
- """
- self.transport.clear()
- self.server.do_GROUP('alt.test.nntp')
- self.assertEqual(
- self.transport.value().split('\r\n'), [
- '211 0 1 0 alt.test.nntp group selected',
- ''])
-
-
- def test_LISTGROUP(self):
- """
- When L{NNTPServer} receives a I{LISTGROUP} command, it sends a list of
- message numbers for the messages in a particular group (RFC 3977,
- section 6.1.2.1).
- """
- self.transport.clear()
- self.server.do_LISTGROUP('alt.test.nntp')
- self.assertEqual(
- self.transport.value().split('\r\n'), [
- '211 list of article numbers follow',
- '.',
- ''])
-
-
- def test_XROVER(self):
- """
- When L{NTTPServer} receives a I{XROVER} command, it sends a list of
- I{References} header values for the messages in a particular group (RFC
- 2980, section 2.11).
- """
- self.server.do_GROUP('alt.test.nntp')
- self.transport.clear()
-
- self.server.do_XROVER()
- self.assertEqual(
- self.transport.value().split('\r\n'), [
- '221 Header follows',
- '.',
- ''])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/NEWS
deleted file mode 100644
index 2b6509f1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/NEWS
+++ /dev/null
@@ -1,112 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted News 12.2.0 (2012-08-26)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted News 12.1.0 (2012-06-02)
-================================
-
-Bugfixes
---------
- - twisted.news.nntp.NNTPServer now has additional test coverage and
- less redundant implementation code. (#5537)
-
-Deprecations and Removals
--------------------------
- - The ability to pass a string article to NNTPServer._gotBody and
- NNTPServer._gotArticle in t.news.nntp has been deprecated for years
- and is now removed. (#4548)
-
-
-Twisted News 12.0.0 (2012-02-10)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted News 11.1.0 (2011-11-15)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted News 11.0.0 (2011-04-01)
-================================
-
-No significant changes have been made for this release.
-
-Other
------
- - #4580
-
-
-Twisted News 10.2.0 (2010-11-29)
-================================
-
-Bugfixes
---------
- - twisted.news.database.PickleStorage now invokes the email APIs
- correctly, allowing it to actually send moderation emails. (#4528)
-
-
-Twisted News 10.1.0 (2010-06-27)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted News 10.0.0 (2010-03-01)
-================================
-
-No interesting changes since Twisted 9.0.
-
-
-Twisted News 9.0.0 (2009-11-24)
-===============================
-
-Other
------
- - #2763, #3540
-
-
-News 8.2.0 (2008-12-16)
-=======================
-
-No interesting changes since Twisted 8.0.
-
-
-8.1.0 (2008-05-18)
-==================
-
-Fixes
------
- - The deprecated mktap API is no longer used (#3127)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Misc
-----
- - Remove all "API Stability" markers (#2847)
-
-
-0.3.0 (2007-01-06)
-==================
-Fixes
------
- - News was updated to work with the latest twisted.components changes
- to Twisted (#1636)
- - The 'ip' attribute is no longer available on NNTP protocols (#1936)
-
-
-0.2.0 (2006-05-24)
-==================
-
-Fixes:
- - Fixed a critical bug in moderation support.
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/README
deleted file mode 100644
index 4921a3a3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/news/topfiles/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Twisted News 12.2.0
-
-News depends on Twisted, and, if you want to use the moderation
-features, Twisted Mail.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/__init__.py
deleted file mode 100755
index 6d3f5aa9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-
-Twisted Pair: The framework of your ethernet.
-
-Low-level networking transports and utilities.
-
-See also twisted.protocols.ethernet, twisted.protocols.ip,
-twisted.protocols.raw and twisted.protocols.rawudp.
-
-Maintainer: Tommi Virtanen
-
-"""
-
-from twisted.pair._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/_version.py
deleted file mode 100755
index 4f1e2e40..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.pair', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ethernet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ethernet.py
deleted file mode 100755
index b432c6fc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ethernet.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- test-case-name: twisted.pair.test.test_ethernet -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-
-"""Support for working directly with ethernet frames"""
-
-import struct
-
-
-from twisted.internet import protocol
-from twisted.pair import raw
-from zope.interface import implements, Interface
-
-
-class IEthernetProtocol(Interface):
- """An interface for protocols that handle Ethernet frames"""
- def addProto():
- """Add an IRawPacketProtocol protocol"""
-
- def datagramReceived():
- """An Ethernet frame has been received"""
-
-class EthernetHeader:
- def __init__(self, data):
-
- (self.dest, self.source, self.proto) \
- = struct.unpack("!6s6sH", data[:6+6+2])
-
-class EthernetProtocol(protocol.AbstractDatagramProtocol):
-
- implements(IEthernetProtocol)
-
- def __init__(self):
- self.etherProtos = {}
-
- def addProto(self, num, proto):
- proto = raw.IRawPacketProtocol(proto)
- if num < 0:
- raise TypeError, 'Added protocol must be positive or zero'
- if num >= 2**16:
- raise TypeError, 'Added protocol must fit in 16 bits'
- if num not in self.etherProtos:
- self.etherProtos[num] = []
- self.etherProtos[num].append(proto)
-
- def datagramReceived(self, data, partial=0):
- header = EthernetHeader(data[:14])
- for proto in self.etherProtos.get(header.proto, ()):
- proto.datagramReceived(data=data[14:],
- partial=partial,
- dest=header.dest,
- source=header.source,
- protocol=header.proto)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ip.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ip.py
deleted file mode 100755
index de03bd41..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/ip.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- test-case-name: twisted.pair.test.test_ip -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-
-"""Support for working directly with IP packets"""
-
-import struct
-import socket
-
-from twisted.internet import protocol
-from twisted.pair import raw
-from zope.interface import implements
-
-
-class IPHeader:
- def __init__(self, data):
-
- (ihlversion, self.tos, self.tot_len, self.fragment_id, frag_off,
- self.ttl, self.protocol, self.check, saddr, daddr) \
- = struct.unpack("!BBHHHBBH4s4s", data[:20])
- self.saddr = socket.inet_ntoa(saddr)
- self.daddr = socket.inet_ntoa(daddr)
- self.version = ihlversion & 0x0F
- self.ihl = ((ihlversion & 0xF0) >> 4) << 2
- self.fragment_offset = frag_off & 0x1FFF
- self.dont_fragment = (frag_off & 0x4000 != 0)
- self.more_fragments = (frag_off & 0x2000 != 0)
-
-MAX_SIZE = 2L**32
-
-class IPProtocol(protocol.AbstractDatagramProtocol):
- implements(raw.IRawPacketProtocol)
-
- def __init__(self):
- self.ipProtos = {}
-
- def addProto(self, num, proto):
- proto = raw.IRawDatagramProtocol(proto)
- if num < 0:
- raise TypeError, 'Added protocol must be positive or zero'
- if num >= MAX_SIZE:
- raise TypeError, 'Added protocol must fit in 32 bits'
- if num not in self.ipProtos:
- self.ipProtos[num] = []
- self.ipProtos[num].append(proto)
-
- def datagramReceived(self,
- data,
- partial,
- dest,
- source,
- protocol):
- header = IPHeader(data)
- for proto in self.ipProtos.get(header.protocol, ()):
- proto.datagramReceived(data=data[20:],
- partial=partial,
- source=header.saddr,
- dest=header.daddr,
- protocol=header.protocol,
- version=header.version,
- ihl=header.ihl,
- tos=header.tos,
- tot_len=header.tot_len,
- fragment_id=header.fragment_id,
- fragment_offset=header.fragment_offset,
- dont_fragment=header.dont_fragment,
- more_fragments=header.more_fragments,
- ttl=header.ttl,
- )
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/raw.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/raw.py
deleted file mode 100755
index 0d3875ba..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/raw.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""Interface definitions for working with raw packets"""
-
-from twisted.internet import protocol
-from zope.interface import Interface
-
-class IRawDatagramProtocol(Interface):
- """An interface for protocols such as UDP, ICMP and TCP."""
-
- def addProto():
- """
- Add a protocol on top of this one.
- """
-
- def datagramReceived():
- """
- An IP datagram has been received. Parse and process it.
- """
-
-class IRawPacketProtocol(Interface):
- """An interface for low-level protocols such as IP and ARP."""
-
- def addProto():
- """
- Add a protocol on top of this one.
- """
-
- def datagramReceived():
- """
- An IP datagram has been received. Parse and process it.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/rawudp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/rawudp.py
deleted file mode 100755
index 1425e6bd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/rawudp.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- test-case-name: twisted.pair.test.test_rawudp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""Implementation of raw packet interfaces for UDP"""
-
-import struct
-
-from twisted.internet import protocol
-from twisted.pair import raw
-from zope.interface import implements
-
-class UDPHeader:
- def __init__(self, data):
-
- (self.source, self.dest, self.len, self.check) \
- = struct.unpack("!HHHH", data[:8])
-
-class RawUDPProtocol(protocol.AbstractDatagramProtocol):
- implements(raw.IRawDatagramProtocol)
- def __init__(self):
- self.udpProtos = {}
-
- def addProto(self, num, proto):
- if not isinstance(proto, protocol.DatagramProtocol):
- raise TypeError, 'Added protocol must be an instance of DatagramProtocol'
- if num < 0:
- raise TypeError, 'Added protocol must be positive or zero'
- if num >= 2**16:
- raise TypeError, 'Added protocol must fit in 16 bits'
- if num not in self.udpProtos:
- self.udpProtos[num] = []
- self.udpProtos[num].append(proto)
-
- def datagramReceived(self,
- data,
- partial,
- source,
- dest,
- protocol,
- version,
- ihl,
- tos,
- tot_len,
- fragment_id,
- fragment_offset,
- dont_fragment,
- more_fragments,
- ttl):
- header = UDPHeader(data)
- for proto in self.udpProtos.get(header.dest, ()):
- proto.datagramReceived(data[8:],
- (source, header.source))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/__init__.py
deleted file mode 100755
index 5aa286eb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-'pair tests'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ethernet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ethernet.py
deleted file mode 100755
index 2b675fe8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ethernet.py
+++ /dev/null
@@ -1,226 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-from twisted.trial import unittest
-
-from twisted.internet import protocol, reactor, error
-from twisted.python import failure, components
-from twisted.pair import ethernet, raw
-from zope.interface import implements
-
-class MyProtocol:
- implements(raw.IRawPacketProtocol)
-
- def __init__(self, expecting):
- self.expecting = list(expecting)
-
- def datagramReceived(self, data, **kw):
- assert self.expecting, 'Got a packet when not expecting anymore.'
- expect = self.expecting.pop(0)
- assert expect == (data, kw), \
- "Expected %r, got %r" % (
- expect, (data, kw),
- )
-
-class EthernetTestCase(unittest.TestCase):
- def testPacketParsing(self):
- proto = ethernet.EthernetProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': "123456",
- 'source': "987654",
- 'protocol': 0x0800,
- }),
-
- ])
- proto.addProto(0x0800, p1)
-
- proto.datagramReceived("123456987654\x08\x00foobar",
- partial=0)
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
-
-
- def testMultiplePackets(self):
- proto = ethernet.EthernetProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': "123456",
- 'source': "987654",
- 'protocol': 0x0800,
- }),
-
- ('quux', {
- 'partial': 1,
- 'dest': "012345",
- 'source': "abcdef",
- 'protocol': 0x0800,
- }),
-
- ])
- proto.addProto(0x0800, p1)
-
- proto.datagramReceived("123456987654\x08\x00foobar",
- partial=0)
- proto.datagramReceived("012345abcdef\x08\x00quux",
- partial=1)
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
-
-
- def testMultipleSameProtos(self):
- proto = ethernet.EthernetProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': "123456",
- 'source': "987654",
- 'protocol': 0x0800,
- }),
-
- ])
-
- p2 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': "123456",
- 'source': "987654",
- 'protocol': 0x0800,
- }),
-
- ])
-
- proto.addProto(0x0800, p1)
- proto.addProto(0x0800, p2)
-
- proto.datagramReceived("123456987654\x08\x00foobar",
- partial=0)
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
- assert not p2.expecting, \
- 'Should not expect any more packets, but still want %r' % p2.expecting
-
- def testWrongProtoNotSeen(self):
- proto = ethernet.EthernetProtocol()
- p1 = MyProtocol([])
- proto.addProto(0x0801, p1)
-
- proto.datagramReceived("123456987654\x08\x00foobar",
- partial=0)
- proto.datagramReceived("012345abcdef\x08\x00quux",
- partial=1)
-
- def testDemuxing(self):
- proto = ethernet.EthernetProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': "123456",
- 'source': "987654",
- 'protocol': 0x0800,
- }),
-
- ('quux', {
- 'partial': 1,
- 'dest': "012345",
- 'source': "abcdef",
- 'protocol': 0x0800,
- }),
-
- ])
- proto.addProto(0x0800, p1)
-
- p2 = MyProtocol([
-
- ('quux', {
- 'partial': 1,
- 'dest': "012345",
- 'source': "abcdef",
- 'protocol': 0x0806,
- }),
-
- ('foobar', {
- 'partial': 0,
- 'dest': "123456",
- 'source': "987654",
- 'protocol': 0x0806,
- }),
-
- ])
- proto.addProto(0x0806, p2)
-
- proto.datagramReceived("123456987654\x08\x00foobar",
- partial=0)
- proto.datagramReceived("012345abcdef\x08\x06quux",
- partial=1)
- proto.datagramReceived("123456987654\x08\x06foobar",
- partial=0)
- proto.datagramReceived("012345abcdef\x08\x00quux",
- partial=1)
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
- assert not p2.expecting, \
- 'Should not expect any more packets, but still want %r' % p2.expecting
-
- def testAddingBadProtos_WrongLevel(self):
- """Adding a wrong level protocol raises an exception."""
- e = ethernet.EthernetProtocol()
- try:
- e.addProto(42, "silliness")
- except components.CannotAdapt:
- pass
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
-
- def testAddingBadProtos_TooSmall(self):
- """Adding a protocol with a negative number raises an exception."""
- e = ethernet.EthernetProtocol()
- try:
- e.addProto(-1, MyProtocol([]))
- except TypeError, e:
- if e.args == ('Added protocol must be positive or zero',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
-
- def testAddingBadProtos_TooBig(self):
- """Adding a protocol with a number >=2**16 raises an exception."""
- e = ethernet.EthernetProtocol()
- try:
- e.addProto(2**16, MyProtocol([]))
- except TypeError, e:
- if e.args == ('Added protocol must fit in 16 bits',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
- def testAddingBadProtos_TooBig2(self):
- """Adding a protocol with a number >=2**16 raises an exception."""
- e = ethernet.EthernetProtocol()
- try:
- e.addProto(2**16+1, MyProtocol([]))
- except TypeError, e:
- if e.args == ('Added protocol must fit in 16 bits',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ip.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ip.py
deleted file mode 100755
index ed1623b6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_ip.py
+++ /dev/null
@@ -1,417 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-from twisted.trial import unittest
-
-from twisted.internet import protocol, reactor, error
-from twisted.python import failure, components
-from twisted.pair import ip, raw
-from zope import interface
-
-class MyProtocol:
- interface.implements(raw.IRawDatagramProtocol)
-
- def __init__(self, expecting):
- self.expecting = list(expecting)
-
- def datagramReceived(self, data, **kw):
- assert self.expecting, 'Got a packet when not expecting anymore.'
- expectData, expectKw = self.expecting.pop(0)
-
- expectKwKeys = expectKw.keys(); expectKwKeys.sort()
- kwKeys = kw.keys(); kwKeys.sort()
- assert expectKwKeys == kwKeys, "Expected %r, got %r" % (expectKwKeys, kwKeys)
-
- for k in expectKwKeys:
- assert expectKw[k] == kw[k], "Expected %s=%r, got %r" % (k, expectKw[k], kw[k])
- assert expectKw == kw, "Expected %r, got %r" % (expectKw, kw)
- assert expectData == data, "Expected %r, got %r" % (expectData, data)
-
-class IPTestCase(unittest.TestCase):
- def testPacketParsing(self):
- proto = ip.IPProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': '1.2.3.4',
- 'source': '5.6.7.8',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ])
- proto.addProto(0x0F, p1)
-
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x05\x06\x07\x08" + "\x01\x02\x03\x04" + "foobar",
- partial=0,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
-
- def testMultiplePackets(self):
- proto = ip.IPProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': '1.2.3.4',
- 'source': '5.6.7.8',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ('quux', {
- 'partial': 1,
- 'dest': '5.4.3.2',
- 'source': '6.7.8.9',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ])
- proto.addProto(0x0F, p1)
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x05\x06\x07\x08" + "\x01\x02\x03\x04" + "foobar",
- partial=0,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x06\x07\x08\x09" + "\x05\x04\x03\x02" + "quux",
- partial=1,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
-
-
- def testMultipleSameProtos(self):
- proto = ip.IPProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': '1.2.3.4',
- 'source': '5.6.7.8',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ])
-
- p2 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': '1.2.3.4',
- 'source': '5.6.7.8',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ])
-
- proto.addProto(0x0F, p1)
- proto.addProto(0x0F, p2)
-
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x05\x06\x07\x08" + "\x01\x02\x03\x04" + "foobar",
- partial=0,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
- assert not p2.expecting, \
- 'Should not expect any more packets, but still want %r' % p2.expecting
-
- def testWrongProtoNotSeen(self):
- proto = ip.IPProtocol()
- p1 = MyProtocol([])
- proto.addProto(1, p1)
-
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x05\x06\x07\x08" + "\x01\x02\x03\x04" + "foobar",
- partial=0,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
-
- def testDemuxing(self):
- proto = ip.IPProtocol()
- p1 = MyProtocol([
-
- ('foobar', {
- 'partial': 0,
- 'dest': '1.2.3.4',
- 'source': '5.6.7.8',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ('quux', {
- 'partial': 1,
- 'dest': '5.4.3.2',
- 'source': '6.7.8.9',
- 'protocol': 0x0F,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ])
- proto.addProto(0x0F, p1)
-
- p2 = MyProtocol([
-
- ('quux', {
- 'partial': 1,
- 'dest': '5.4.3.2',
- 'source': '6.7.8.9',
- 'protocol': 0x0A,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
- ('foobar', {
- 'partial': 0,
- 'dest': '1.2.3.4',
- 'source': '5.6.7.8',
- 'protocol': 0x0A,
- 'version': 4,
- 'ihl': 20,
- 'tos': 7,
- 'tot_len': 20+6,
- 'fragment_id': 0xDEAD,
- 'fragment_offset': 0x1EEF,
- 'dont_fragment': 0,
- 'more_fragments': 1,
- 'ttl': 0xC0,
- }),
-
-
- ])
- proto.addProto(0x0A, p2)
-
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0A" #protocol
- + "FE" #checksum
- + "\x06\x07\x08\x09" + "\x05\x04\x03\x02" + "quux",
- partial=1,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x05\x06\x07\x08" + "\x01\x02\x03\x04" + "foobar",
- partial=0,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0F" #protocol
- + "FE" #checksum
- + "\x06\x07\x08\x09" + "\x05\x04\x03\x02" + "quux",
- partial=1,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
- proto.datagramReceived("\x54" #ihl version
- + "\x07" #tos
- + "\x00\x1a" #tot_len
- + "\xDE\xAD" #id
- + "\xBE\xEF" #frag_off
- + "\xC0" #ttl
- + "\x0A" #protocol
- + "FE" #checksum
- + "\x05\x06\x07\x08" + "\x01\x02\x03\x04" + "foobar",
- partial=0,
- dest='dummy',
- source='dummy',
- protocol='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
- assert not p2.expecting, \
- 'Should not expect any more packets, but still want %r' % p2.expecting
-
- def testAddingBadProtos_WrongLevel(self):
- """Adding a wrong level protocol raises an exception."""
- e = ip.IPProtocol()
- try:
- e.addProto(42, "silliness")
- except components.CannotAdapt:
- pass
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
-
- def testAddingBadProtos_TooSmall(self):
- """Adding a protocol with a negative number raises an exception."""
- e = ip.IPProtocol()
- try:
- e.addProto(-1, MyProtocol([]))
- except TypeError, e:
- if e.args == ('Added protocol must be positive or zero',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
-
- def testAddingBadProtos_TooBig(self):
- """Adding a protocol with a number >=2**32 raises an exception."""
- e = ip.IPProtocol()
- try:
- e.addProto(2L**32, MyProtocol([]))
- except TypeError, e:
- if e.args == ('Added protocol must fit in 32 bits',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
- def testAddingBadProtos_TooBig2(self):
- """Adding a protocol with a number >=2**32 raises an exception."""
- e = ip.IPProtocol()
- try:
- e.addProto(2L**32+1, MyProtocol([]))
- except TypeError, e:
- if e.args == ('Added protocol must fit in 32 bits',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_rawudp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_rawudp.py
deleted file mode 100755
index f53f0783..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/test/test_rawudp.py
+++ /dev/null
@@ -1,327 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-from twisted.trial import unittest
-
-from twisted.internet import protocol, reactor, error
-from twisted.python import failure
-from twisted.pair import rawudp
-
-class MyProtocol(protocol.DatagramProtocol):
- def __init__(self, expecting):
- self.expecting = list(expecting)
-
- def datagramReceived(self, data, (host, port)):
- assert self.expecting, 'Got a packet when not expecting anymore.'
- expectData, expectHost, expectPort = self.expecting.pop(0)
-
- assert expectData == data, "Expected data %r, got %r" % (expectData, data)
- assert expectHost == host, "Expected host %r, got %r" % (expectHost, host)
- assert expectPort == port, "Expected port %d=0x%04x, got %d=0x%04x" % (expectPort, expectPort, port, port)
-
-class RawUDPTestCase(unittest.TestCase):
- def testPacketParsing(self):
- proto = rawudp.RawUDPProtocol()
- p1 = MyProtocol([
-
- ('foobar', 'testHost', 0x43A2),
-
- ])
- proto.addProto(0xF00F, p1)
-
- proto.datagramReceived("\x43\xA2" #source
- + "\xf0\x0f" #dest
- + "\x00\x06" #len
- + "\xDE\xAD" #check
- + "foobar",
- partial=0,
- dest='dummy',
- source='testHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
-
- def testMultiplePackets(self):
- proto = rawudp.RawUDPProtocol()
- p1 = MyProtocol([
-
- ('foobar', 'testHost', 0x43A2),
- ('quux', 'otherHost', 0x33FE),
-
- ])
- proto.addProto(0xF00F, p1)
- proto.datagramReceived("\x43\xA2" #source
- + "\xf0\x0f" #dest
- + "\x00\x06" #len
- + "\xDE\xAD" #check
- + "foobar",
- partial=0,
- dest='dummy',
- source='testHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
- proto.datagramReceived("\x33\xFE" #source
- + "\xf0\x0f" #dest
- + "\x00\x05" #len
- + "\xDE\xAD" #check
- + "quux",
- partial=0,
- dest='dummy',
- source='otherHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
-
-
- def testMultipleSameProtos(self):
- proto = rawudp.RawUDPProtocol()
- p1 = MyProtocol([
-
- ('foobar', 'testHost', 0x43A2),
-
- ])
-
- p2 = MyProtocol([
-
- ('foobar', 'testHost', 0x43A2),
-
- ])
-
- proto.addProto(0xF00F, p1)
- proto.addProto(0xF00F, p2)
-
- proto.datagramReceived("\x43\xA2" #source
- + "\xf0\x0f" #dest
- + "\x00\x06" #len
- + "\xDE\xAD" #check
- + "foobar",
- partial=0,
- dest='dummy',
- source='testHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
- assert not p2.expecting, \
- 'Should not expect any more packets, but still want %r' % p2.expecting
-
- def testWrongProtoNotSeen(self):
- proto = rawudp.RawUDPProtocol()
- p1 = MyProtocol([])
- proto.addProto(1, p1)
-
- proto.datagramReceived("\x43\xA2" #source
- + "\xf0\x0f" #dest
- + "\x00\x06" #len
- + "\xDE\xAD" #check
- + "foobar",
- partial=0,
- dest='dummy',
- source='testHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
-
- def testDemuxing(self):
- proto = rawudp.RawUDPProtocol()
- p1 = MyProtocol([
-
- ('foobar', 'testHost', 0x43A2),
- ('quux', 'otherHost', 0x33FE),
-
- ])
- proto.addProto(0xF00F, p1)
-
- p2 = MyProtocol([
-
- ('quux', 'otherHost', 0xA401),
- ('foobar', 'testHost', 0xA302),
-
- ])
- proto.addProto(0xB050, p2)
-
- proto.datagramReceived("\xA4\x01" #source
- + "\xB0\x50" #dest
- + "\x00\x05" #len
- + "\xDE\xAD" #check
- + "quux",
- partial=0,
- dest='dummy',
- source='otherHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
- proto.datagramReceived("\x43\xA2" #source
- + "\xf0\x0f" #dest
- + "\x00\x06" #len
- + "\xDE\xAD" #check
- + "foobar",
- partial=0,
- dest='dummy',
- source='testHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
- proto.datagramReceived("\x33\xFE" #source
- + "\xf0\x0f" #dest
- + "\x00\x05" #len
- + "\xDE\xAD" #check
- + "quux",
- partial=0,
- dest='dummy',
- source='otherHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
- proto.datagramReceived("\xA3\x02" #source
- + "\xB0\x50" #dest
- + "\x00\x06" #len
- + "\xDE\xAD" #check
- + "foobar",
- partial=0,
- dest='dummy',
- source='testHost',
- protocol='dummy',
- version='dummy',
- ihl='dummy',
- tos='dummy',
- tot_len='dummy',
- fragment_id='dummy',
- fragment_offset='dummy',
- dont_fragment='dummy',
- more_fragments='dummy',
- ttl='dummy',
- )
-
- assert not p1.expecting, \
- 'Should not expect any more packets, but still want %r' % p1.expecting
- assert not p2.expecting, \
- 'Should not expect any more packets, but still want %r' % p2.expecting
-
- def testAddingBadProtos_WrongLevel(self):
- """Adding a wrong level protocol raises an exception."""
- e = rawudp.RawUDPProtocol()
- try:
- e.addProto(42, "silliness")
- except TypeError, e:
- if e.args == ('Added protocol must be an instance of DatagramProtocol',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
-
- def testAddingBadProtos_TooSmall(self):
- """Adding a protocol with a negative number raises an exception."""
- e = rawudp.RawUDPProtocol()
- try:
- e.addProto(-1, protocol.DatagramProtocol())
- except TypeError, e:
- if e.args == ('Added protocol must be positive or zero',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
-
- def testAddingBadProtos_TooBig(self):
- """Adding a protocol with a number >=2**16 raises an exception."""
- e = rawudp.RawUDPProtocol()
- try:
- e.addProto(2**16, protocol.DatagramProtocol())
- except TypeError, e:
- if e.args == ('Added protocol must fit in 16 bits',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
-
- def testAddingBadProtos_TooBig2(self):
- """Adding a protocol with a number >=2**16 raises an exception."""
- e = rawudp.RawUDPProtocol()
- try:
- e.addProto(2**16+1, protocol.DatagramProtocol())
- except TypeError, e:
- if e.args == ('Added protocol must fit in 16 bits',):
- pass
- else:
- raise
- else:
- raise AssertionError, 'addProto must raise an exception for bad protocols'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/NEWS
deleted file mode 100644
index 2161528e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/NEWS
+++ /dev/null
@@ -1,62 +0,0 @@
-Twisted Pair 12.2.0 (2012-08-26)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 12.1.0 (2012-06-02)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 12.0.0 (2012-02-10)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 11.1.0 (2011-11-15)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 11.0.0 (2011-04-01)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 10.2.0 (2010-11-29)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 10.1.0 (2010-06-27)
-================================
-
-No significant changes have been made for this release.
-
-
-Twisted Pair 10.0.0 (2010-03-01)
-================================
-
-Other
------
- - #4170
-
-
-Twisted Pair 9.0.0 (2009-11-24)
-===============================
-
-Other
------
- - #3540, #4050
-
-
-Pair 8.2.0 (2008-12-16)
-=======================
-
-No interesting changes since Twisted 8.0.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/README
deleted file mode 100644
index 8d022a91..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/topfiles/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Twisted Pair 12.2.0
-
-Twisted Pair depends on Twisted Core. For TUN/TAP access, python-eunuchs
-(<http://pypi.python.org/pypi/python-eunuchs/0.0.0>) is also required.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/tuntap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/tuntap.py
deleted file mode 100755
index e3ece5e0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/pair/tuntap.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-import errno, os
-from twisted.python import log, reflect, components
-from twisted.internet import base, fdesc, error
-from twisted.pair import ethernet, ip
-
-"""
-You need Eunuchs for twisted.pair.tuntap to work.
-
-Eunuchs is a library containing the missing manly parts of
-UNIX API for Python.
-
-Eunuchs is a library of Python extension that complement the standard
-libraries in parts where full support for the UNIX API (or the Linux
-API) is missing.
-
-Most of the functions wrapped by Eunuchs are low-level, dirty, but
-absolutely necessary functions for real systems programming. The aim is
-to have the functions added to mainstream Python libraries.
-
-Current list of functions included:
-
- - fchdir(2)
- - recvmsg(2) and sendmsg(2), including use of cmsg(3)
- - socketpair(2)
- - support for TUN/TAP virtual network interfaces
-
-Eunuchs doesn't have a proper web home right now, but you can fetch
-the source from http://ftp.debian.org/debian/pool/main/e/eunuch
--- debian users can just use 'apt-get install python-eunuchs'.
-
-"""
-from eunuchs.tuntap import opentuntap, TuntapPacketInfo, makePacketInfo
-
-class TuntapPort(base.BasePort):
- """A Port that reads and writes packets from/to a TUN/TAP-device.
-
- TODO: Share general start/stop etc implementation details with
- twisted.internet.udp.Port.
- """
- maxThroughput = 256 * 1024 # max bytes we read in one eventloop iteration
-
- def __init__(self, interface, proto, maxPacketSize=8192, reactor=None):
- if components.implements(proto, ethernet.IEthernetProtocol):
- self.ethernet = 1
- else:
- self.ethernet = 0
- assert components.implements(proto, ip.IIPProtocol) # XXX: fix me
- base.BasePort.__init__(self, reactor)
- self.interface = interface
- self.protocol = proto
- self.maxPacketSize = maxPacketSize
- self.setLogStr()
-
- def __repr__(self):
- return "<%s on %s>" % (self.protocol.__class__, self.interface)
-
- def startListening(self):
- """Create and bind my socket, and begin listening on it.
-
- This is called on unserialization, and must be called after creating a
- server to begin listening on the specified port.
- """
- self._bindSocket()
- self._connectToProtocol()
-
- def _bindSocket(self):
- log.msg("%s starting on %s"%(self.protocol.__class__, self.interface))
- try:
- fd, name = opentuntap(name=self.interface,
- ethernet=self.ethernet,
- packetinfo=0)
- except OSError, e:
- raise error.CannotListenError, (None, self.interface, e)
- fdesc.setNonBlocking(fd)
- self.interface = name
- self.connected = 1
- self.fd = fd
-
- def fileno(self):
- return self.fd
-
- def _connectToProtocol(self):
- self.protocol.makeConnection(self)
- self.startReading()
-
- def doRead(self):
- """Called when my socket is ready for reading."""
- read = 0
- while read < self.maxThroughput:
- try:
- data = os.read(self.fd, self.maxPacketSize)
- read += len(data)
-# pkt = TuntapPacketInfo(data)
- self.protocol.datagramReceived(data,
- partial=0 # pkt.isPartial(),
- )
- except OSError, e:
- if e.errno in (errno.EWOULDBLOCK,):
- return
- else:
- raise
- except IOError, e:
- if e.errno in (errno.EAGAIN, errno.EINTR):
- return
- else:
- raise
- except:
- log.deferr()
-
- def write(self, datagram):
- """Write a datagram."""
-# header = makePacketInfo(0, 0)
- try:
- return os.write(self.fd, datagram)
- except IOError, e:
- if e.errno == errno.EINTR:
- return self.write(datagram)
- elif e.errno == errno.EMSGSIZE:
- raise error.MessageLengthError, "message too long"
- elif e.errno == errno.ECONNREFUSED:
- raise error.ConnectionRefusedError
- else:
- raise
-
- def writeSequence(self, seq):
- self.write("".join(seq))
-
- def loseConnection(self):
- """Stop accepting connections on this port.
-
- This will shut down my socket and call self.connectionLost().
- """
- self.stopReading()
- if self.connected:
- from twisted.internet import reactor
- reactor.callLater(0, self.connectionLost)
-
- stopListening = loseConnection
-
- def connectionLost(self, reason=None):
- """Cleans up my socket.
- """
- log.msg('(Tuntap %s Closed)' % self.interface)
- base.BasePort.connectionLost(self, reason)
- if hasattr(self, "protocol"):
- # we won't have attribute in ConnectedPort, in cases
- # where there was an error in connection process
- self.protocol.doStop()
- self.connected = 0
- os.close(self.fd)
- del self.fd
-
- def setLogStr(self):
- self.logstr = reflect.qual(self.protocol.__class__) + " (TUNTAP)"
-
- def logPrefix(self):
- """Returns the name of my class, to prefix log entries with.
- """
- return self.logstr
-
- def getHost(self):
- """
- Returns a tuple of ('TUNTAP', interface), indicating
- the servers address
- """
- return ('TUNTAP',)+self.interface
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/__init__.py
deleted file mode 100755
index a8a918b2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Twisted Persisted: utilities for managing persistence.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/aot.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/aot.py
deleted file mode 100755
index c0e0282c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/aot.py
+++ /dev/null
@@ -1,560 +0,0 @@
-# -*- test-case-name: twisted.test.test_persisted -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-
-"""
-AOT: Abstract Object Trees
-The source-code-marshallin'est abstract-object-serializin'est persister
-this side of Marmalade!
-"""
-
-import types, copy_reg, tokenize, re
-
-from twisted.python import reflect, log
-from twisted.persisted import crefutil
-
-###########################
-# Abstract Object Classes #
-###########################
-
-#"\0" in a getSource means "insert variable-width indention here".
-#see `indentify'.
-
-class Named:
- def __init__(self, name):
- self.name = name
-
-class Class(Named):
- def getSource(self):
- return "Class(%r)" % self.name
-
-class Function(Named):
- def getSource(self):
- return "Function(%r)" % self.name
-
-class Module(Named):
- def getSource(self):
- return "Module(%r)" % self.name
-
-
-class InstanceMethod:
- def __init__(self, name, klass, inst):
- if not (isinstance(inst, Ref) or isinstance(inst, Instance) or isinstance(inst, Deref)):
- raise TypeError("%s isn't an Instance, Ref, or Deref!" % inst)
- self.name = name
- self.klass = klass
- self.instance = inst
-
- def getSource(self):
- return "InstanceMethod(%r, %r, \n\0%s)" % (self.name, self.klass, prettify(self.instance))
-
-
-class _NoStateObj:
- pass
-NoStateObj = _NoStateObj()
-
-_SIMPLE_BUILTINS = [
- types.StringType, types.UnicodeType, types.IntType, types.FloatType,
- types.ComplexType, types.LongType, types.NoneType, types.SliceType,
- types.EllipsisType]
-
-try:
- _SIMPLE_BUILTINS.append(types.BooleanType)
-except AttributeError:
- pass
-
-class Instance:
- def __init__(self, className, __stateObj__=NoStateObj, **state):
- if not isinstance(className, types.StringType):
- raise TypeError("%s isn't a string!" % className)
- self.klass = className
- if __stateObj__ is not NoStateObj:
- self.state = __stateObj__
- self.stateIsDict = 0
- else:
- self.state = state
- self.stateIsDict = 1
-
- def getSource(self):
- #XXX make state be foo=bar instead of a dict.
- if self.stateIsDict:
- stateDict = self.state
- elif isinstance(self.state, Ref) and isinstance(self.state.obj, types.DictType):
- stateDict = self.state.obj
- else:
- stateDict = None
- if stateDict is not None:
- try:
- return "Instance(%r, %s)" % (self.klass, dictToKW(stateDict))
- except NonFormattableDict:
- return "Instance(%r, %s)" % (self.klass, prettify(stateDict))
- return "Instance(%r, %s)" % (self.klass, prettify(self.state))
-
-class Ref:
-
- def __init__(self, *args):
- #blargh, lame.
- if len(args) == 2:
- self.refnum = args[0]
- self.obj = args[1]
- elif not args:
- self.refnum = None
- self.obj = None
-
- def setRef(self, num):
- if self.refnum:
- raise ValueError("Error setting id %s, I already have %s" % (num, self.refnum))
- self.refnum = num
-
- def setObj(self, obj):
- if self.obj:
- raise ValueError("Error setting obj %s, I already have %s" % (obj, self.obj))
- self.obj = obj
-
- def getSource(self):
- if self.obj is None:
- raise RuntimeError("Don't try to display me before setting an object on me!")
- if self.refnum:
- return "Ref(%d, \n\0%s)" % (self.refnum, prettify(self.obj))
- return prettify(self.obj)
-
-
-class Deref:
- def __init__(self, num):
- self.refnum = num
-
- def getSource(self):
- return "Deref(%d)" % self.refnum
-
- __repr__ = getSource
-
-
-class Copyreg:
- def __init__(self, loadfunc, state):
- self.loadfunc = loadfunc
- self.state = state
-
- def getSource(self):
- return "Copyreg(%r, %s)" % (self.loadfunc, prettify(self.state))
-
-
-
-###############
-# Marshalling #
-###############
-
-
-def getSource(ao):
- """Pass me an AO, I'll return a nicely-formatted source representation."""
- return indentify("app = " + prettify(ao))
-
-
-class NonFormattableDict(Exception):
- """A dictionary was not formattable.
- """
-
-r = re.compile('[a-zA-Z_][a-zA-Z0-9_]*$')
-
-def dictToKW(d):
- out = []
- items = d.items()
- items.sort()
- for k,v in items:
- if not isinstance(k, types.StringType):
- raise NonFormattableDict("%r ain't a string" % k)
- if not r.match(k):
- raise NonFormattableDict("%r ain't an identifier" % k)
- out.append(
- "\n\0%s=%s," % (k, prettify(v))
- )
- return ''.join(out)
-
-
-def prettify(obj):
- if hasattr(obj, 'getSource'):
- return obj.getSource()
- else:
- #basic type
- t = type(obj)
-
- if t in _SIMPLE_BUILTINS:
- return repr(obj)
-
- elif t is types.DictType:
- out = ['{']
- for k,v in obj.items():
- out.append('\n\0%s: %s,' % (prettify(k), prettify(v)))
- out.append(len(obj) and '\n\0}' or '}')
- return ''.join(out)
-
- elif t is types.ListType:
- out = ["["]
- for x in obj:
- out.append('\n\0%s,' % prettify(x))
- out.append(len(obj) and '\n\0]' or ']')
- return ''.join(out)
-
- elif t is types.TupleType:
- out = ["("]
- for x in obj:
- out.append('\n\0%s,' % prettify(x))
- out.append(len(obj) and '\n\0)' or ')')
- return ''.join(out)
- else:
- raise TypeError("Unsupported type %s when trying to prettify %s." % (t, obj))
-
-def indentify(s):
- out = []
- stack = []
- def eater(type, val, r, c, l, out=out, stack=stack):
- #import sys
- #sys.stdout.write(val)
- if val in ['[', '(', '{']:
- stack.append(val)
- elif val in [']', ')', '}']:
- stack.pop()
- if val == '\0':
- out.append(' '*len(stack))
- else:
- out.append(val)
- l = ['', s]
- tokenize.tokenize(l.pop, eater)
- return ''.join(out)
-
-
-
-
-
-###########
-# Unjelly #
-###########
-
-def unjellyFromAOT(aot):
- """
- Pass me an Abstract Object Tree, and I'll unjelly it for you.
- """
- return AOTUnjellier().unjelly(aot)
-
-def unjellyFromSource(stringOrFile):
- """
- Pass me a string of code or a filename that defines an 'app' variable (in
- terms of Abstract Objects!), and I'll execute it and unjelly the resulting
- AOT for you, returning a newly unpersisted Application object!
- """
-
- ns = {"Instance": Instance,
- "InstanceMethod": InstanceMethod,
- "Class": Class,
- "Function": Function,
- "Module": Module,
- "Ref": Ref,
- "Deref": Deref,
- "Copyreg": Copyreg,
- }
-
- if hasattr(stringOrFile, "read"):
- exec stringOrFile.read() in ns
- else:
- exec stringOrFile in ns
-
- if 'app' in ns:
- return unjellyFromAOT(ns['app'])
- else:
- raise ValueError("%s needs to define an 'app', it didn't!" % stringOrFile)
-
-
-class AOTUnjellier:
- """I handle the unjellying of an Abstract Object Tree.
- See AOTUnjellier.unjellyAO
- """
- def __init__(self):
- self.references = {}
- self.stack = []
- self.afterUnjelly = []
-
- ##
- # unjelly helpers (copied pretty much directly from (now deleted) marmalade)
- ##
- def unjellyLater(self, node):
- """Unjelly a node, later.
- """
- d = crefutil._Defer()
- self.unjellyInto(d, 0, node)
- return d
-
- def unjellyInto(self, obj, loc, ao):
- """Utility method for unjellying one object into another.
- This automates the handling of backreferences.
- """
- o = self.unjellyAO(ao)
- obj[loc] = o
- if isinstance(o, crefutil.NotKnown):
- o.addDependant(obj, loc)
- return o
-
- def callAfter(self, callable, result):
- if isinstance(result, crefutil.NotKnown):
- l = [None]
- result.addDependant(l, 1)
- else:
- l = [result]
- self.afterUnjelly.append((callable, l))
-
- def unjellyAttribute(self, instance, attrName, ao):
- #XXX this is unused????
- """Utility method for unjellying into instances of attributes.
-
- Use this rather than unjellyAO unless you like surprising bugs!
- Alternatively, you can use unjellyInto on your instance's __dict__.
- """
- self.unjellyInto(instance.__dict__, attrName, ao)
-
- def unjellyAO(self, ao):
- """Unjelly an Abstract Object and everything it contains.
- I return the real object.
- """
- self.stack.append(ao)
- t = type(ao)
- if t is types.InstanceType:
- #Abstract Objects
- c = ao.__class__
- if c is Module:
- return reflect.namedModule(ao.name)
-
- elif c in [Class, Function] or issubclass(c, type):
- return reflect.namedObject(ao.name)
-
- elif c is InstanceMethod:
- im_name = ao.name
- im_class = reflect.namedObject(ao.klass)
- im_self = self.unjellyAO(ao.instance)
- if im_name in im_class.__dict__:
- if im_self is None:
- return getattr(im_class, im_name)
- elif isinstance(im_self, crefutil.NotKnown):
- return crefutil._InstanceMethod(im_name, im_self, im_class)
- else:
- return types.MethodType(im_class.__dict__[im_name],
- im_self,
- im_class)
- else:
- raise TypeError("instance method changed")
-
- elif c is Instance:
- klass = reflect.namedObject(ao.klass)
- state = self.unjellyAO(ao.state)
- if hasattr(klass, "__setstate__"):
- inst = types.InstanceType(klass, {})
- self.callAfter(inst.__setstate__, state)
- else:
- inst = types.InstanceType(klass, state)
- return inst
-
- elif c is Ref:
- o = self.unjellyAO(ao.obj) #THIS IS CHANGING THE REF OMG
- refkey = ao.refnum
- ref = self.references.get(refkey)
- if ref is None:
- self.references[refkey] = o
- elif isinstance(ref, crefutil.NotKnown):
- ref.resolveDependants(o)
- self.references[refkey] = o
- elif refkey is None:
- # This happens when you're unjellying from an AOT not read from source
- pass
- else:
- raise ValueError("Multiple references with the same ID: %s, %s, %s!" % (ref, refkey, ao))
- return o
-
- elif c is Deref:
- num = ao.refnum
- ref = self.references.get(num)
- if ref is None:
- der = crefutil._Dereference(num)
- self.references[num] = der
- return der
- return ref
-
- elif c is Copyreg:
- loadfunc = reflect.namedObject(ao.loadfunc)
- d = self.unjellyLater(ao.state).addCallback(
- lambda result, _l: _l(*result), loadfunc)
- return d
-
- #Types
-
- elif t in _SIMPLE_BUILTINS:
- return ao
-
- elif t is types.ListType:
- l = []
- for x in ao:
- l.append(None)
- self.unjellyInto(l, len(l)-1, x)
- return l
-
- elif t is types.TupleType:
- l = []
- tuple_ = tuple
- for x in ao:
- l.append(None)
- if isinstance(self.unjellyInto(l, len(l)-1, x), crefutil.NotKnown):
- tuple_ = crefutil._Tuple
- return tuple_(l)
-
- elif t is types.DictType:
- d = {}
- for k,v in ao.items():
- kvd = crefutil._DictKeyAndValue(d)
- self.unjellyInto(kvd, 0, k)
- self.unjellyInto(kvd, 1, v)
- return d
-
- else:
- raise TypeError("Unsupported AOT type: %s" % t)
-
- del self.stack[-1]
-
-
- def unjelly(self, ao):
- try:
- l = [None]
- self.unjellyInto(l, 0, ao)
- for func, v in self.afterUnjelly:
- func(v[0])
- return l[0]
- except:
- log.msg("Error jellying object! Stacktrace follows::")
- log.msg("\n".join(map(repr, self.stack)))
- raise
-#########
-# Jelly #
-#########
-
-
-def jellyToAOT(obj):
- """Convert an object to an Abstract Object Tree."""
- return AOTJellier().jelly(obj)
-
-def jellyToSource(obj, file=None):
- """
- Pass me an object and, optionally, a file object.
- I'll convert the object to an AOT either return it (if no file was
- specified) or write it to the file.
- """
-
- aot = jellyToAOT(obj)
- if file:
- file.write(getSource(aot))
- else:
- return getSource(aot)
-
-
-class AOTJellier:
- def __init__(self):
- # dict of {id(obj): (obj, node)}
- self.prepared = {}
- self._ref_id = 0
- self.stack = []
-
- def prepareForRef(self, aoref, object):
- """I prepare an object for later referencing, by storing its id()
- and its _AORef in a cache."""
- self.prepared[id(object)] = aoref
-
- def jellyToAO(self, obj):
- """I turn an object into an AOT and return it."""
- objType = type(obj)
- self.stack.append(repr(obj))
-
- #immutable: We don't care if these have multiple refs!
- if objType in _SIMPLE_BUILTINS:
- retval = obj
-
- elif objType is types.MethodType:
- # TODO: make methods 'prefer' not to jelly the object internally,
- # so that the object will show up where it's referenced first NOT
- # by a method.
- retval = InstanceMethod(obj.im_func.__name__, reflect.qual(obj.im_class),
- self.jellyToAO(obj.im_self))
-
- elif objType is types.ModuleType:
- retval = Module(obj.__name__)
-
- elif objType is types.ClassType:
- retval = Class(reflect.qual(obj))
-
- elif issubclass(objType, type):
- retval = Class(reflect.qual(obj))
-
- elif objType is types.FunctionType:
- retval = Function(reflect.fullFuncName(obj))
-
- else: #mutable! gotta watch for refs.
-
-#Marmalade had the nicety of being able to just stick a 'reference' attribute
-#on any Node object that was referenced, but in AOT, the referenced object
-#is *inside* of a Ref call (Ref(num, obj) instead of
-#<objtype ... reference="1">). The problem is, especially for built-in types,
-#I can't just assign some attribute to them to give them a refnum. So, I have
-#to "wrap" a Ref(..) around them later -- that's why I put *everything* that's
-#mutable inside one. The Ref() class will only print the "Ref(..)" around an
-#object if it has a Reference explicitly attached.
-
- if id(obj) in self.prepared:
- oldRef = self.prepared[id(obj)]
- if oldRef.refnum:
- # it's been referenced already
- key = oldRef.refnum
- else:
- # it hasn't been referenced yet
- self._ref_id = self._ref_id + 1
- key = self._ref_id
- oldRef.setRef(key)
- return Deref(key)
-
- retval = Ref()
- self.prepareForRef(retval, obj)
-
- if objType is types.ListType:
- retval.setObj(map(self.jellyToAO, obj)) #hah!
-
- elif objType is types.TupleType:
- retval.setObj(tuple(map(self.jellyToAO, obj)))
-
- elif objType is types.DictionaryType:
- d = {}
- for k,v in obj.items():
- d[self.jellyToAO(k)] = self.jellyToAO(v)
- retval.setObj(d)
-
- elif objType is types.InstanceType:
- if hasattr(obj, "__getstate__"):
- state = self.jellyToAO(obj.__getstate__())
- else:
- state = self.jellyToAO(obj.__dict__)
- retval.setObj(Instance(reflect.qual(obj.__class__), state))
-
- elif objType in copy_reg.dispatch_table:
- unpickleFunc, state = copy_reg.dispatch_table[objType](obj)
-
- retval.setObj(Copyreg( reflect.fullFuncName(unpickleFunc),
- self.jellyToAO(state)))
-
- else:
- raise TypeError("Unsupported type: %s" % objType.__name__)
-
- del self.stack[-1]
- return retval
-
- def jelly(self, obj):
- try:
- ao = self.jellyToAO(obj)
- return ao
- except:
- log.msg("Error jellying object! Stacktrace follows::")
- log.msg('\n'.join(self.stack))
- raise
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/crefutil.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/crefutil.py
deleted file mode 100755
index 39d7eb96..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/crefutil.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# -*- test-case-name: twisted.test.test_persisted -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Utility classes for dealing with circular references.
-"""
-
-import types
-
-from twisted.python import log, reflect
-
-
-class NotKnown:
- def __init__(self):
- self.dependants = []
- self.resolved = 0
-
- def addDependant(self, mutableObject, key):
- assert not self.resolved
- self.dependants.append( (mutableObject, key) )
-
- resolvedObject = None
-
- def resolveDependants(self, newObject):
- self.resolved = 1
- self.resolvedObject = newObject
- for mut, key in self.dependants:
- mut[key] = newObject
- if isinstance(newObject, NotKnown):
- newObject.addDependant(mut, key)
-
- def __hash__(self):
- assert 0, "I am not to be used as a dictionary key."
-
-
-
-class _Container(NotKnown):
- """
- Helper class to resolve circular references on container objects.
- """
-
- def __init__(self, l, containerType):
- """
- @param l: The list of object which may contain some not yet referenced
- objects.
-
- @param containerType: A type of container objects (e.g., C{tuple} or
- C{set}).
- """
- NotKnown.__init__(self)
- self.containerType = containerType
- self.l = l
- self.locs = range(len(l))
- for idx in xrange(len(l)):
- if not isinstance(l[idx], NotKnown):
- self.locs.remove(idx)
- else:
- l[idx].addDependant(self, idx)
- if not self.locs:
- self.resolveDependants(self.containerType(self.l))
-
-
- def __setitem__(self, n, obj):
- """
- Change the value of one contained objects, and resolve references if
- all objects have been referenced.
- """
- self.l[n] = obj
- if not isinstance(obj, NotKnown):
- self.locs.remove(n)
- if not self.locs:
- self.resolveDependants(self.containerType(self.l))
-
-
-
-class _Tuple(_Container):
- """
- Manage tuple containing circular references. Deprecated: use C{_Container}
- instead.
- """
-
- def __init__(self, l):
- """
- @param l: The list of object which may contain some not yet referenced
- objects.
- """
- _Container.__init__(self, l, tuple)
-
-
-
-class _InstanceMethod(NotKnown):
- def __init__(self, im_name, im_self, im_class):
- NotKnown.__init__(self)
- self.my_class = im_class
- self.name = im_name
- # im_self _must_ be a
- im_self.addDependant(self, 0)
-
- def __call__(self, *args, **kw):
- import traceback
- log.msg('instance method %s.%s' % (reflect.qual(self.my_class), self.name))
- log.msg('being called with %r %r' % (args, kw))
- traceback.print_stack(file=log.logfile)
- assert 0
-
- def __setitem__(self, n, obj):
- assert n == 0, "only zero index allowed"
- if not isinstance(obj, NotKnown):
- method = types.MethodType(self.my_class.__dict__[self.name],
- obj, self.my_class)
- self.resolveDependants(method)
-
-class _DictKeyAndValue:
- def __init__(self, dict):
- self.dict = dict
- def __setitem__(self, n, obj):
- if n not in (1, 0):
- raise RuntimeError("DictKeyAndValue should only ever be called with 0 or 1")
- if n: # value
- self.value = obj
- else:
- self.key = obj
- if hasattr(self, "key") and hasattr(self, "value"):
- self.dict[self.key] = self.value
-
-
-class _Dereference(NotKnown):
- def __init__(self, id):
- NotKnown.__init__(self)
- self.id = id
-
-
-from twisted.internet.defer import Deferred
-
-class _Catcher:
- def catch(self, value):
- self.value = value
-
-class _Defer(Deferred, NotKnown):
- def __init__(self):
- Deferred.__init__(self)
- NotKnown.__init__(self)
- self.pause()
-
- wasset = 0
-
- def __setitem__(self, n, obj):
- if self.wasset:
- raise RuntimeError('setitem should only be called once, setting %r to %r' % (n, obj))
- else:
- self.wasset = 1
- self.callback(obj)
-
- def addDependant(self, dep, key):
- # by the time I'm adding a dependant, I'm *not* adding any more
- # callbacks
- NotKnown.addDependant(self, dep, key)
- self.unpause()
- resovd = self.result
- self.resolveDependants(resovd)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/dirdbm.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/dirdbm.py
deleted file mode 100755
index 26bbc1b2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/dirdbm.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# -*- test-case-name: twisted.test.test_dirdbm -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-
-"""
-DBM-style interface to a directory.
-
-Each key is stored as a single file. This is not expected to be very fast or
-efficient, but it's good for easy debugging.
-
-DirDBMs are *not* thread-safe, they should only be accessed by one thread at
-a time.
-
-No files should be placed in the working directory of a DirDBM save those
-created by the DirDBM itself!
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-
-import os
-import types
-import base64
-import glob
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-try:
- _open
-except NameError:
- _open = open
-
-
-class DirDBM:
- """A directory with a DBM interface.
-
- This class presents a hash-like interface to a directory of small,
- flat files. It can only use strings as keys or values.
- """
-
- def __init__(self, name):
- """
- @type name: str
- @param name: Base path to use for the directory storage.
- """
- self.dname = os.path.abspath(name)
- if not os.path.isdir(self.dname):
- os.mkdir(self.dname)
- else:
- # Run recovery, in case we crashed. we delete all files ending
- # with ".new". Then we find all files who end with ".rpl". If a
- # corresponding file exists without ".rpl", we assume the write
- # failed and delete the ".rpl" file. If only a ".rpl" exist we
- # assume the program crashed right after deleting the old entry
- # but before renaming the replacement entry.
- #
- # NOTE: '.' is NOT in the base64 alphabet!
- for f in glob.glob(os.path.join(self.dname, "*.new")):
- os.remove(f)
- replacements = glob.glob(os.path.join(self.dname, "*.rpl"))
- for f in replacements:
- old = f[:-4]
- if os.path.exists(old):
- os.remove(f)
- else:
- os.rename(f, old)
-
- def _encode(self, k):
- """Encode a key so it can be used as a filename.
- """
- # NOTE: '_' is NOT in the base64 alphabet!
- return base64.encodestring(k).replace('\n', '_').replace("/", "-")
-
- def _decode(self, k):
- """Decode a filename to get the key.
- """
- return base64.decodestring(k.replace('_', '\n').replace("-", "/"))
-
- def _readFile(self, path):
- """Read in the contents of a file.
-
- Override in subclasses to e.g. provide transparently encrypted dirdbm.
- """
- f = _open(path, "rb")
- s = f.read()
- f.close()
- return s
-
- def _writeFile(self, path, data):
- """Write data to a file.
-
- Override in subclasses to e.g. provide transparently encrypted dirdbm.
- """
- f = _open(path, "wb")
- f.write(data)
- f.flush()
- f.close()
-
- def __len__(self):
- """
- @return: The number of key/value pairs in this Shelf
- """
- return len(os.listdir(self.dname))
-
- def __setitem__(self, k, v):
- """
- C{dirdbm[k] = v}
- Create or modify a textfile in this directory
-
- @type k: str
- @param k: key to set
-
- @type v: str
- @param v: value to associate with C{k}
- """
- assert type(k) == types.StringType, "DirDBM key must be a string"
- assert type(v) == types.StringType, "DirDBM value must be a string"
- k = self._encode(k)
-
- # we create a new file with extension .new, write the data to it, and
- # if the write succeeds delete the old file and rename the new one.
- old = os.path.join(self.dname, k)
- if os.path.exists(old):
- new = old + ".rpl" # replacement entry
- else:
- new = old + ".new" # new entry
- try:
- self._writeFile(new, v)
- except:
- os.remove(new)
- raise
- else:
- if os.path.exists(old): os.remove(old)
- os.rename(new, old)
-
- def __getitem__(self, k):
- """
- C{dirdbm[k]}
- Get the contents of a file in this directory as a string.
-
- @type k: str
- @param k: key to lookup
-
- @return: The value associated with C{k}
- @raise KeyError: Raised when there is no such key
- """
- assert type(k) == types.StringType, "DirDBM key must be a string"
- path = os.path.join(self.dname, self._encode(k))
- try:
- return self._readFile(path)
- except:
- raise KeyError, k
-
- def __delitem__(self, k):
- """
- C{del dirdbm[foo]}
- Delete a file in this directory.
-
- @type k: str
- @param k: key to delete
-
- @raise KeyError: Raised when there is no such key
- """
- assert type(k) == types.StringType, "DirDBM key must be a string"
- k = self._encode(k)
- try: os.remove(os.path.join(self.dname, k))
- except (OSError, IOError): raise KeyError(self._decode(k))
-
- def keys(self):
- """
- @return: a C{list} of filenames (keys).
- """
- return map(self._decode, os.listdir(self.dname))
-
- def values(self):
- """
- @return: a C{list} of file-contents (values).
- """
- vals = []
- keys = self.keys()
- for key in keys:
- vals.append(self[key])
- return vals
-
- def items(self):
- """
- @return: a C{list} of 2-tuples containing key/value pairs.
- """
- items = []
- keys = self.keys()
- for key in keys:
- items.append((key, self[key]))
- return items
-
- def has_key(self, key):
- """
- @type key: str
- @param key: The key to test
-
- @return: A true value if this dirdbm has the specified key, a faluse
- value otherwise.
- """
- assert type(key) == types.StringType, "DirDBM key must be a string"
- key = self._encode(key)
- return os.path.isfile(os.path.join(self.dname, key))
-
- def setdefault(self, key, value):
- """
- @type key: str
- @param key: The key to lookup
-
- @param value: The value to associate with key if key is not already
- associated with a value.
- """
- if not self.has_key(key):
- self[key] = value
- return value
- return self[key]
-
- def get(self, key, default = None):
- """
- @type key: str
- @param key: The key to lookup
-
- @param default: The value to return if the given key does not exist
-
- @return: The value associated with C{key} or C{default} if not
- C{self.has_key(key)}
- """
- if self.has_key(key):
- return self[key]
- else:
- return default
-
- def __contains__(self, key):
- """
- C{key in dirdbm}
-
- @type key: str
- @param key: The key to test
-
- @return: A true value if C{self.has_key(key)}, a false value otherwise.
- """
- assert type(key) == types.StringType, "DirDBM key must be a string"
- key = self._encode(key)
- return os.path.isfile(os.path.join(self.dname, key))
-
- def update(self, dict):
- """
- Add all the key/value pairs in C{dict} to this dirdbm. Any conflicting
- keys will be overwritten with the values from C{dict}.
-
- @type dict: mapping
- @param dict: A mapping of key/value pairs to add to this dirdbm.
- """
- for key, val in dict.items():
- self[key]=val
-
- def copyTo(self, path):
- """
- Copy the contents of this dirdbm to the dirdbm at C{path}.
-
- @type path: C{str}
- @param path: The path of the dirdbm to copy to. If a dirdbm
- exists at the destination path, it is cleared first.
-
- @rtype: C{DirDBM}
- @return: The dirdbm this dirdbm was copied to.
- """
- path = os.path.abspath(path)
- assert path != self.dname
-
- d = self.__class__(path)
- d.clear()
- for k in self.keys():
- d[k] = self[k]
- return d
-
- def clear(self):
- """
- Delete all key/value pairs in this dirdbm.
- """
- for k in self.keys():
- del self[k]
-
- def close(self):
- """
- Close this dbm: no-op, for dbm-style interface compliance.
- """
-
- def getModificationTime(self, key):
- """
- Returns modification time of an entry.
-
- @return: Last modification date (seconds since epoch) of entry C{key}
- @raise KeyError: Raised when there is no such key
- """
- assert type(key) == types.StringType, "DirDBM key must be a string"
- path = os.path.join(self.dname, self._encode(key))
- if os.path.isfile(path):
- return os.path.getmtime(path)
- else:
- raise KeyError, key
-
-
-class Shelf(DirDBM):
- """A directory with a DBM shelf interface.
-
- This class presents a hash-like interface to a directory of small,
- flat files. Keys must be strings, but values can be any given object.
- """
-
- def __setitem__(self, k, v):
- """
- C{shelf[foo] = bar}
- Create or modify a textfile in this directory.
-
- @type k: str
- @param k: The key to set
-
- @param v: The value to associate with C{key}
- """
- v = pickle.dumps(v)
- DirDBM.__setitem__(self, k, v)
-
- def __getitem__(self, k):
- """
- C{dirdbm[foo]}
- Get and unpickle the contents of a file in this directory.
-
- @type k: str
- @param k: The key to lookup
-
- @return: The value associated with the given key
- @raise KeyError: Raised if the given key does not exist
- """
- return pickle.loads(DirDBM.__getitem__(self, k))
-
-
-def open(file, flag = None, mode = None):
- """
- This is for 'anydbm' compatibility.
-
- @param file: The parameter to pass to the DirDBM constructor.
-
- @param flag: ignored
- @param mode: ignored
- """
- return DirDBM(file)
-
-
-__all__ = ["open", "DirDBM", "Shelf"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/sob.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/sob.py
deleted file mode 100755
index 2ba2e49f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/sob.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# -*- test-case-name: twisted.test.test_sob -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""
-Save and load Small OBjects to and from files, using various formats.
-
-Maintainer: Moshe Zadka
-"""
-
-import os, sys
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-from twisted.python import log, runtime
-from twisted.python.hashlib import md5
-from twisted.persisted import styles
-from zope.interface import implements, Interface
-
-# Note:
-# These encrypt/decrypt functions only work for data formats
-# which are immune to having spaces tucked at the end.
-# All data formats which persist saves hold that condition.
-def _encrypt(passphrase, data):
- from Crypto.Cipher import AES as cipher
- leftover = len(data) % cipher.block_size
- if leftover:
- data += ' '*(cipher.block_size - leftover)
- return cipher.new(md5(passphrase).digest()[:16]).encrypt(data)
-
-def _decrypt(passphrase, data):
- from Crypto.Cipher import AES
- return AES.new(md5(passphrase).digest()[:16]).decrypt(data)
-
-
-class IPersistable(Interface):
-
- """An object which can be saved in several formats to a file"""
-
- def setStyle(style):
- """Set desired format.
-
- @type style: string (one of 'pickle' or 'source')
- """
-
- def save(tag=None, filename=None, passphrase=None):
- """Save object to file.
-
- @type tag: string
- @type filename: string
- @type passphrase: string
- """
-
-
-class Persistent:
-
- implements(IPersistable)
-
- style = "pickle"
-
- def __init__(self, original, name):
- self.original = original
- self.name = name
-
- def setStyle(self, style):
- """Set desired format.
-
- @type style: string (one of 'pickle' or 'source')
- """
- self.style = style
-
- def _getFilename(self, filename, ext, tag):
- if filename:
- finalname = filename
- filename = finalname + "-2"
- elif tag:
- filename = "%s-%s-2.%s" % (self.name, tag, ext)
- finalname = "%s-%s.%s" % (self.name, tag, ext)
- else:
- filename = "%s-2.%s" % (self.name, ext)
- finalname = "%s.%s" % (self.name, ext)
- return finalname, filename
-
- def _saveTemp(self, filename, passphrase, dumpFunc):
- f = open(filename, 'wb')
- if passphrase is None:
- dumpFunc(self.original, f)
- else:
- s = StringIO.StringIO()
- dumpFunc(self.original, s)
- f.write(_encrypt(passphrase, s.getvalue()))
- f.close()
-
- def _getStyle(self):
- if self.style == "source":
- from twisted.persisted.aot import jellyToSource as dumpFunc
- ext = "tas"
- else:
- def dumpFunc(obj, file):
- pickle.dump(obj, file, 2)
- ext = "tap"
- return ext, dumpFunc
-
- def save(self, tag=None, filename=None, passphrase=None):
- """Save object to file.
-
- @type tag: string
- @type filename: string
- @type passphrase: string
- """
- ext, dumpFunc = self._getStyle()
- if passphrase:
- ext = 'e' + ext
- finalname, filename = self._getFilename(filename, ext, tag)
- log.msg("Saving "+self.name+" application to "+finalname+"...")
- self._saveTemp(filename, passphrase, dumpFunc)
- if runtime.platformType == "win32" and os.path.isfile(finalname):
- os.remove(finalname)
- os.rename(filename, finalname)
- log.msg("Saved.")
-
-# "Persistant" has been present since 1.0.7, so retain it for compatibility
-Persistant = Persistent
-
-class _EverythingEphemeral(styles.Ephemeral):
-
- initRun = 0
-
- def __init__(self, mainMod):
- """
- @param mainMod: The '__main__' module that this class will proxy.
- """
- self.mainMod = mainMod
-
- def __getattr__(self, key):
- try:
- return getattr(self.mainMod, key)
- except AttributeError:
- if self.initRun:
- raise
- else:
- log.msg("Warning! Loading from __main__: %s" % key)
- return styles.Ephemeral()
-
-
-def load(filename, style, passphrase=None):
- """Load an object from a file.
-
- Deserialize an object from a file. The file can be encrypted.
-
- @param filename: string
- @param style: string (one of 'pickle' or 'source')
- @param passphrase: string
- """
- mode = 'r'
- if style=='source':
- from twisted.persisted.aot import unjellyFromSource as _load
- else:
- _load, mode = pickle.load, 'rb'
- if passphrase:
- fp = StringIO.StringIO(_decrypt(passphrase,
- open(filename, 'rb').read()))
- else:
- fp = open(filename, mode)
- ee = _EverythingEphemeral(sys.modules['__main__'])
- sys.modules['__main__'] = ee
- ee.initRun = 1
- try:
- value = _load(fp)
- finally:
- # restore __main__ if an exception is raised.
- sys.modules['__main__'] = ee.mainMod
-
- styles.doUpgrade()
- ee.initRun = 0
- persistable = IPersistable(value, None)
- if persistable is not None:
- persistable.setStyle(style)
- return value
-
-
-def loadValueFromFile(filename, variable, passphrase=None):
- """Load the value of a variable in a Python file.
-
- Run the contents of the file, after decrypting if C{passphrase} is
- given, in a namespace and return the result of the variable
- named C{variable}.
-
- @param filename: string
- @param variable: string
- @param passphrase: string
- """
- if passphrase:
- mode = 'rb'
- else:
- mode = 'r'
- fileObj = open(filename, mode)
- d = {'__file__': filename}
- if passphrase:
- data = fileObj.read()
- data = _decrypt(passphrase, data)
- exec data in d, d
- else:
- exec fileObj in d, d
- value = d[variable]
- return value
-
-def guessType(filename):
- ext = os.path.splitext(filename)[1]
- return {
- '.tac': 'python',
- '.etac': 'python',
- '.py': 'python',
- '.tap': 'pickle',
- '.etap': 'pickle',
- '.tas': 'source',
- '.etas': 'source',
- }[ext]
-
-__all__ = ['loadValueFromFile', 'load', 'Persistent', 'Persistant',
- 'IPersistable', 'guessType']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/styles.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/styles.py
deleted file mode 100755
index e3ca39bf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/styles.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# -*- test-case-name: twisted.test.test_persisted -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-
-"""
-Different styles of persisted objects.
-"""
-
-# System Imports
-import types
-import copy_reg
-import copy
-import inspect
-import sys
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-# Twisted Imports
-from twisted.python import log
-from twisted.python import reflect
-
-oldModules = {}
-
-## First, let's register support for some stuff that really ought to
-## be registerable...
-
-def pickleMethod(method):
- 'support function for copy_reg to pickle method refs'
- return unpickleMethod, (method.im_func.__name__,
- method.im_self,
- method.im_class)
-
-def unpickleMethod(im_name,
- im_self,
- im_class):
- 'support function for copy_reg to unpickle method refs'
- try:
- unbound = getattr(im_class,im_name)
- if im_self is None:
- return unbound
- bound = types.MethodType(unbound.im_func, im_self, im_class)
- return bound
- except AttributeError:
- log.msg("Method",im_name,"not on class",im_class)
- assert im_self is not None,"No recourse: no instance to guess from."
- # Attempt a common fix before bailing -- if classes have
- # changed around since we pickled this method, we may still be
- # able to get it by looking on the instance's current class.
- unbound = getattr(im_self.__class__,im_name)
- log.msg("Attempting fixup with",unbound)
- if im_self is None:
- return unbound
- bound = types.MethodType(unbound.im_func, im_self, im_self.__class__)
- return bound
-
-copy_reg.pickle(types.MethodType,
- pickleMethod,
- unpickleMethod)
-
-def pickleModule(module):
- 'support function for copy_reg to pickle module refs'
- return unpickleModule, (module.__name__,)
-
-def unpickleModule(name):
- 'support function for copy_reg to unpickle module refs'
- if name in oldModules:
- log.msg("Module has moved: %s" % name)
- name = oldModules[name]
- log.msg(name)
- return __import__(name,{},{},'x')
-
-
-copy_reg.pickle(types.ModuleType,
- pickleModule,
- unpickleModule)
-
-def pickleStringO(stringo):
- 'support function for copy_reg to pickle StringIO.OutputTypes'
- return unpickleStringO, (stringo.getvalue(), stringo.tell())
-
-def unpickleStringO(val, sek):
- x = StringIO.StringIO()
- x.write(val)
- x.seek(sek)
- return x
-
-if hasattr(StringIO, 'OutputType'):
- copy_reg.pickle(StringIO.OutputType,
- pickleStringO,
- unpickleStringO)
-
-def pickleStringI(stringi):
- return unpickleStringI, (stringi.getvalue(), stringi.tell())
-
-def unpickleStringI(val, sek):
- x = StringIO.StringIO(val)
- x.seek(sek)
- return x
-
-
-if hasattr(StringIO, 'InputType'):
- copy_reg.pickle(StringIO.InputType,
- pickleStringI,
- unpickleStringI)
-
-class Ephemeral:
- """
- This type of object is never persisted; if possible, even references to it
- are eliminated.
- """
-
- def __getstate__(self):
- log.msg( "WARNING: serializing ephemeral %s" % self )
- import gc
- if '__pypy__' not in sys.builtin_module_names:
- if getattr(gc, 'get_referrers', None):
- for r in gc.get_referrers(self):
- log.msg( " referred to by %s" % (r,))
- return None
-
- def __setstate__(self, state):
- log.msg( "WARNING: unserializing ephemeral %s" % self.__class__ )
- self.__class__ = Ephemeral
-
-
-versionedsToUpgrade = {}
-upgraded = {}
-
-def doUpgrade():
- global versionedsToUpgrade, upgraded
- for versioned in versionedsToUpgrade.values():
- requireUpgrade(versioned)
- versionedsToUpgrade = {}
- upgraded = {}
-
-def requireUpgrade(obj):
- """Require that a Versioned instance be upgraded completely first.
- """
- objID = id(obj)
- if objID in versionedsToUpgrade and objID not in upgraded:
- upgraded[objID] = 1
- obj.versionUpgrade()
- return obj
-
-def _aybabtu(c):
- """
- Get all of the parent classes of C{c}, not including C{c} itself, which are
- strict subclasses of L{Versioned}.
-
- The name comes from "all your base are belong to us", from the deprecated
- L{twisted.python.reflect.allYourBase} function.
-
- @param c: a class
- @returns: list of classes
- """
- # begin with two classes that should *not* be included in the
- # final result
- l = [c, Versioned]
- for b in inspect.getmro(c):
- if b not in l and issubclass(b, Versioned):
- l.append(b)
- # return all except the unwanted classes
- return l[2:]
-
-class Versioned:
- """
- This type of object is persisted with versioning information.
-
- I have a single class attribute, the int persistenceVersion. After I am
- unserialized (and styles.doUpgrade() is called), self.upgradeToVersionX()
- will be called for each version upgrade I must undergo.
-
- For example, if I serialize an instance of a Foo(Versioned) at version 4
- and then unserialize it when the code is at version 9, the calls::
-
- self.upgradeToVersion5()
- self.upgradeToVersion6()
- self.upgradeToVersion7()
- self.upgradeToVersion8()
- self.upgradeToVersion9()
-
- will be made. If any of these methods are undefined, a warning message
- will be printed.
- """
- persistenceVersion = 0
- persistenceForgets = ()
-
- def __setstate__(self, state):
- versionedsToUpgrade[id(self)] = self
- self.__dict__ = state
-
- def __getstate__(self, dict=None):
- """Get state, adding a version number to it on its way out.
- """
- dct = copy.copy(dict or self.__dict__)
- bases = _aybabtu(self.__class__)
- bases.reverse()
- bases.append(self.__class__) # don't forget me!!
- for base in bases:
- if 'persistenceForgets' in base.__dict__:
- for slot in base.persistenceForgets:
- if slot in dct:
- del dct[slot]
- if 'persistenceVersion' in base.__dict__:
- dct['%s.persistenceVersion' % reflect.qual(base)] = base.persistenceVersion
- return dct
-
- def versionUpgrade(self):
- """(internal) Do a version upgrade.
- """
- bases = _aybabtu(self.__class__)
- # put the bases in order so superclasses' persistenceVersion methods
- # will be called first.
- bases.reverse()
- bases.append(self.__class__) # don't forget me!!
- # first let's look for old-skool versioned's
- if "persistenceVersion" in self.__dict__:
-
- # Hacky heuristic: if more than one class subclasses Versioned,
- # we'll assume that the higher version number wins for the older
- # class, so we'll consider the attribute the version of the older
- # class. There are obviously possibly times when this will
- # eventually be an incorrect assumption, but hopefully old-school
- # persistenceVersion stuff won't make it that far into multiple
- # classes inheriting from Versioned.
-
- pver = self.__dict__['persistenceVersion']
- del self.__dict__['persistenceVersion']
- highestVersion = 0
- highestBase = None
- for base in bases:
- if not base.__dict__.has_key('persistenceVersion'):
- continue
- if base.persistenceVersion > highestVersion:
- highestBase = base
- highestVersion = base.persistenceVersion
- if highestBase:
- self.__dict__['%s.persistenceVersion' % reflect.qual(highestBase)] = pver
- for base in bases:
- # ugly hack, but it's what the user expects, really
- if (Versioned not in base.__bases__ and
- 'persistenceVersion' not in base.__dict__):
- continue
- currentVers = base.persistenceVersion
- pverName = '%s.persistenceVersion' % reflect.qual(base)
- persistVers = (self.__dict__.get(pverName) or 0)
- if persistVers:
- del self.__dict__[pverName]
- assert persistVers <= currentVers, "Sorry, can't go backwards in time."
- while persistVers < currentVers:
- persistVers = persistVers + 1
- method = base.__dict__.get('upgradeToVersion%s' % persistVers, None)
- if method:
- log.msg( "Upgrading %s (of %s @ %s) to version %s" % (reflect.qual(base), reflect.qual(self.__class__), id(self), persistVers) )
- method(self)
- else:
- log.msg( 'Warning: cannot upgrade %s to version %s' % (base, persistVers) )
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/__init__.py
deleted file mode 100755
index 01ae065f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.persisted}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/test_styles.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/test_styles.py
deleted file mode 100755
index 29647a92..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/persisted/test/test_styles.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.persisted.styles}.
-"""
-
-from twisted.trial import unittest
-from twisted.persisted.styles import unpickleMethod
-
-
-class Foo:
- """
- Helper class.
- """
- def method(self):
- """
- Helper method.
- """
-
-
-
-class Bar:
- """
- Helper class.
- """
-
-
-
-class UnpickleMethodTestCase(unittest.TestCase):
- """
- Tests for the unpickleMethod function.
- """
-
- def test_instanceBuildingNamePresent(self):
- """
- L{unpickleMethod} returns an instance method bound to the
- instance passed to it.
- """
- foo = Foo()
- m = unpickleMethod('method', foo, Foo)
- self.assertEqual(m, foo.method)
- self.assertNotIdentical(m, foo.method)
-
-
- def test_instanceBuildingNameNotPresent(self):
- """
- If the named method is not present in the class,
- L{unpickleMethod} finds a method on the class of the instance
- and returns a bound method from there.
- """
- foo = Foo()
- m = unpickleMethod('method', foo, Bar)
- self.assertEqual(m, foo.method)
- self.assertNotIdentical(m, foo.method)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugin.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugin.py
deleted file mode 100755
index a4f83346..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugin.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# -*- test-case-name: twisted.test.test_plugin -*-
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Plugin system for Twisted.
-
-@author: Jp Calderone
-@author: Glyph Lefkowitz
-"""
-
-import os
-import sys
-
-from zope.interface import Interface, providedBy
-
-def _determinePickleModule():
- """
- Determine which 'pickle' API module to use.
- """
- try:
- import cPickle
- return cPickle
- except ImportError:
- import pickle
- return pickle
-
-pickle = _determinePickleModule()
-
-from twisted.python.components import getAdapterFactory
-from twisted.python.reflect import namedAny
-from twisted.python import log
-from twisted.python.modules import getModule
-
-
-
-class IPlugin(Interface):
- """
- Interface that must be implemented by all plugins.
-
- Only objects which implement this interface will be considered for return
- by C{getPlugins}. To be useful, plugins should also implement some other
- application-specific interface.
- """
-
-
-
-class CachedPlugin(object):
- def __init__(self, dropin, name, description, provided):
- self.dropin = dropin
- self.name = name
- self.description = description
- self.provided = provided
- self.dropin.plugins.append(self)
-
- def __repr__(self):
- return '<CachedPlugin %r/%r (provides %r)>' % (
- self.name, self.dropin.moduleName,
- ', '.join([i.__name__ for i in self.provided]))
-
- def load(self):
- return namedAny(self.dropin.moduleName + '.' + self.name)
-
- def __conform__(self, interface, registry=None, default=None):
- for providedInterface in self.provided:
- if providedInterface.isOrExtends(interface):
- return self.load()
- if getAdapterFactory(providedInterface, interface, None) is not None:
- return interface(self.load(), default)
- return default
-
- # backwards compat HOORJ
- getComponent = __conform__
-
-
-
-class CachedDropin(object):
- """
- A collection of L{CachedPlugin} instances from a particular module in a
- plugin package.
-
- @type moduleName: C{str}
- @ivar moduleName: The fully qualified name of the plugin module this
- represents.
-
- @type description: C{str} or C{NoneType}
- @ivar description: A brief explanation of this collection of plugins
- (probably the plugin module's docstring).
-
- @type plugins: C{list}
- @ivar plugins: The L{CachedPlugin} instances which were loaded from this
- dropin.
- """
- def __init__(self, moduleName, description):
- self.moduleName = moduleName
- self.description = description
- self.plugins = []
-
-
-
-def _generateCacheEntry(provider):
- dropin = CachedDropin(provider.__name__,
- provider.__doc__)
- for k, v in provider.__dict__.iteritems():
- plugin = IPlugin(v, None)
- if plugin is not None:
- # Instantiated for its side-effects.
- CachedPlugin(dropin, k, v.__doc__, list(providedBy(plugin)))
- return dropin
-
-try:
- fromkeys = dict.fromkeys
-except AttributeError:
- def fromkeys(keys, value=None):
- d = {}
- for k in keys:
- d[k] = value
- return d
-
-
-
-def getCache(module):
- """
- Compute all the possible loadable plugins, while loading as few as
- possible and hitting the filesystem as little as possible.
-
- @param module: a Python module object. This represents a package to search
- for plugins.
-
- @return: a dictionary mapping module names to L{CachedDropin} instances.
- """
- allCachesCombined = {}
- mod = getModule(module.__name__)
- # don't want to walk deep, only immediate children.
- buckets = {}
- # Fill buckets with modules by related entry on the given package's
- # __path__. There's an abstraction inversion going on here, because this
- # information is already represented internally in twisted.python.modules,
- # but it's simple enough that I'm willing to live with it. If anyone else
- # wants to fix up this iteration so that it's one path segment at a time,
- # be my guest. --glyph
- for plugmod in mod.iterModules():
- fpp = plugmod.filePath.parent()
- if fpp not in buckets:
- buckets[fpp] = []
- bucket = buckets[fpp]
- bucket.append(plugmod)
- for pseudoPackagePath, bucket in buckets.iteritems():
- dropinPath = pseudoPackagePath.child('dropin.cache')
- try:
- lastCached = dropinPath.getModificationTime()
- dropinDotCache = pickle.load(dropinPath.open('r'))
- except:
- dropinDotCache = {}
- lastCached = 0
-
- needsWrite = False
- existingKeys = {}
- for pluginModule in bucket:
- pluginKey = pluginModule.name.split('.')[-1]
- existingKeys[pluginKey] = True
- if ((pluginKey not in dropinDotCache) or
- (pluginModule.filePath.getModificationTime() >= lastCached)):
- needsWrite = True
- try:
- provider = pluginModule.load()
- except:
- # dropinDotCache.pop(pluginKey, None)
- log.err()
- else:
- entry = _generateCacheEntry(provider)
- dropinDotCache[pluginKey] = entry
- # Make sure that the cache doesn't contain any stale plugins.
- for pluginKey in dropinDotCache.keys():
- if pluginKey not in existingKeys:
- del dropinDotCache[pluginKey]
- needsWrite = True
- if needsWrite:
- try:
- dropinPath.setContent(pickle.dumps(dropinDotCache))
- except OSError, e:
- log.msg(
- format=(
- "Unable to write to plugin cache %(path)s: error "
- "number %(errno)d"),
- path=dropinPath.path, errno=e.errno)
- except:
- log.err(None, "Unexpected error while writing cache file")
- allCachesCombined.update(dropinDotCache)
- return allCachesCombined
-
-
-
-def getPlugins(interface, package=None):
- """
- Retrieve all plugins implementing the given interface beneath the given module.
-
- @param interface: An interface class. Only plugins which implement this
- interface will be returned.
-
- @param package: A package beneath which plugins are installed. For
- most uses, the default value is correct.
-
- @return: An iterator of plugins.
- """
- if package is None:
- import twisted.plugins as package
- allDropins = getCache(package)
- for dropin in allDropins.itervalues():
- for plugin in dropin.plugins:
- try:
- adapted = interface(plugin, None)
- except:
- log.err()
- else:
- if adapted is not None:
- yield adapted
-
-
-# Old, backwards compatible name. Don't use this.
-getPlugIns = getPlugins
-
-
-def pluginPackagePaths(name):
- """
- Return a list of additional directories which should be searched for
- modules to be included as part of the named plugin package.
-
- @type name: C{str}
- @param name: The fully-qualified Python name of a plugin package, eg
- C{'twisted.plugins'}.
-
- @rtype: C{list} of C{str}
- @return: The absolute paths to other directories which may contain plugin
- modules for the named plugin package.
- """
- package = name.split('.')
- # Note that this may include directories which do not exist. It may be
- # preferable to remove such directories at this point, rather than allow
- # them to be searched later on.
- #
- # Note as well that only '__init__.py' will be considered to make a
- # directory a package (and thus exclude it from this list). This means
- # that if you create a master plugin package which has some other kind of
- # __init__ (eg, __init__.pyc) it will be incorrectly treated as a
- # supplementary plugin directory.
- return [
- os.path.abspath(os.path.join(x, *package))
- for x
- in sys.path
- if
- not os.path.exists(os.path.join(x, *package + ['__init__.py']))]
-
-__all__ = ['getPlugins', 'pluginPackagePaths']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/__init__.py
deleted file mode 100755
index 0c117606..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- test-case-name: twisted.test.test_plugin -*-
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Plugins go in directories on your PYTHONPATH named twisted/plugins:
-this is the only place where an __init__.py is necessary, thanks to
-the __path__ variable.
-
-@author: Jp Calderone
-@author: Glyph Lefkowitz
-"""
-
-from twisted.plugin import pluginPackagePaths
-__path__.extend(pluginPackagePaths(__name__))
-__all__ = [] # nothing to see here, move along, move along
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_anonymous.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_anonymous.py
deleted file mode 100755
index ad0ea9e2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_anonymous.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- test-case-name: twisted.test.test_strcred -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cred plugin for anonymous logins.
-"""
-
-from zope.interface import implements
-
-from twisted import plugin
-from twisted.cred.checkers import AllowAnonymousAccess
-from twisted.cred.strcred import ICheckerFactory
-from twisted.cred.credentials import IAnonymous
-
-
-anonymousCheckerFactoryHelp = """
-This allows anonymous authentication for servers that support it.
-"""
-
-
-class AnonymousCheckerFactory(object):
- """
- Generates checkers that will authenticate an anonymous request.
- """
- implements(ICheckerFactory, plugin.IPlugin)
- authType = 'anonymous'
- authHelp = anonymousCheckerFactoryHelp
- argStringFormat = 'No argstring required.'
- credentialInterfaces = (IAnonymous,)
-
-
- def generateChecker(self, argstring=''):
- return AllowAnonymousAccess()
-
-
-
-theAnonymousCheckerFactory = AnonymousCheckerFactory()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_file.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_file.py
deleted file mode 100755
index 3ff9b379..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_file.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- test-case-name: twisted.test.test_strcred -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cred plugin for a file of the format 'username:password'.
-"""
-
-import sys
-
-from zope.interface import implements
-
-from twisted import plugin
-from twisted.cred.checkers import FilePasswordDB
-from twisted.cred.strcred import ICheckerFactory
-from twisted.cred.credentials import IUsernamePassword, IUsernameHashedPassword
-
-
-
-fileCheckerFactoryHelp = """
-This checker expects to receive the location of a file that
-conforms to the FilePasswordDB format. Each line in the file
-should be of the format 'username:password', in plain text.
-"""
-
-invalidFileWarning = 'Warning: not a valid file'
-
-
-
-class FileCheckerFactory(object):
- """
- A factory for instances of L{FilePasswordDB}.
- """
- implements(ICheckerFactory, plugin.IPlugin)
- authType = 'file'
- authHelp = fileCheckerFactoryHelp
- argStringFormat = 'Location of a FilePasswordDB-formatted file.'
- # Explicitly defined here because FilePasswordDB doesn't do it for us
- credentialInterfaces = (IUsernamePassword, IUsernameHashedPassword)
-
- errorOutput = sys.stderr
-
- def generateChecker(self, argstring):
- """
- This checker factory expects to get the location of a file.
- The file should conform to the format required by
- L{FilePasswordDB} (using defaults for all
- initialization parameters).
- """
- from twisted.python.filepath import FilePath
- if not argstring.strip():
- raise ValueError, '%r requires a filename' % self.authType
- elif not FilePath(argstring).isfile():
- self.errorOutput.write('%s: %s\n' % (invalidFileWarning, argstring))
- return FilePasswordDB(argstring)
-
-
-
-theFileCheckerFactory = FileCheckerFactory()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_memory.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_memory.py
deleted file mode 100755
index 0ed90836..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_memory.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- test-case-name: twisted.test.test_strcred -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cred plugin for an in-memory user database.
-"""
-
-from zope.interface import implements
-
-from twisted import plugin
-from twisted.cred.strcred import ICheckerFactory
-from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
-from twisted.cred.credentials import IUsernamePassword, IUsernameHashedPassword
-
-
-
-inMemoryCheckerFactoryHelp = """
-A checker that uses an in-memory user database.
-
-This is only of use in one-off test programs or examples which
-don't want to focus too much on how credentials are verified. You
-really don't want to use this for anything else. It is a toy.
-"""
-
-
-
-class InMemoryCheckerFactory(object):
- """
- A factory for in-memory credentials checkers.
-
- This is only of use in one-off test programs or examples which don't
- want to focus too much on how credentials are verified.
-
- You really don't want to use this for anything else. It is, at best, a
- toy. If you need a simple credentials checker for a real application,
- see L{cred_passwd.PasswdCheckerFactory}.
- """
- implements(ICheckerFactory, plugin.IPlugin)
- authType = 'memory'
- authHelp = inMemoryCheckerFactoryHelp
- argStringFormat = 'A colon-separated list (name:password:...)'
- credentialInterfaces = (IUsernamePassword,
- IUsernameHashedPassword)
-
- def generateChecker(self, argstring):
- """
- This checker factory expects to get a list of
- username:password pairs, with each pair also separated by a
- colon. For example, the string 'alice:f:bob:g' would generate
- two users, one named 'alice' and one named 'bob'.
- """
- checker = InMemoryUsernamePasswordDatabaseDontUse()
- if argstring:
- pieces = argstring.split(':')
- if len(pieces) % 2:
- from twisted.cred.strcred import InvalidAuthArgumentString
- raise InvalidAuthArgumentString(
- "argstring must be in format U:P:...")
- for i in range(0, len(pieces), 2):
- username, password = pieces[i], pieces[i+1]
- checker.addUser(username, password)
- return checker
-
-
-
-theInMemoryCheckerFactory = InMemoryCheckerFactory()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_sshkeys.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_sshkeys.py
deleted file mode 100755
index 226b34a5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_sshkeys.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- test-case-name: twisted.test.test_strcred -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cred plugin for ssh key login
-"""
-
-from zope.interface import implements
-
-from twisted import plugin
-from twisted.cred.strcred import ICheckerFactory
-from twisted.cred.credentials import ISSHPrivateKey
-
-
-sshKeyCheckerFactoryHelp = """
-This allows SSH public key authentication, based on public keys listed in
-authorized_keys and authorized_keys2 files in user .ssh/ directories.
-"""
-
-
-try:
- from twisted.conch.checkers import SSHPublicKeyDatabase
-
- class SSHKeyCheckerFactory(object):
- """
- Generates checkers that will authenticate a SSH public key
- """
- implements(ICheckerFactory, plugin.IPlugin)
- authType = 'sshkey'
- authHelp = sshKeyCheckerFactoryHelp
- argStringFormat = 'No argstring required.'
- credentialInterfaces = SSHPublicKeyDatabase.credentialInterfaces
-
-
- def generateChecker(self, argstring=''):
- """
- This checker factory ignores the argument string. Everything
- needed to authenticate users is pulled out of the public keys
- listed in user .ssh/ directories.
- """
- return SSHPublicKeyDatabase()
-
-
-
- theSSHKeyCheckerFactory = SSHKeyCheckerFactory()
-
-except ImportError:
- # if checkers can't be imported, then there should be no SSH cred plugin
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_unix.py
deleted file mode 100755
index a6364972..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/cred_unix.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# -*- test-case-name: twisted.test.test_strcred -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cred plugin for UNIX user accounts.
-"""
-
-from zope.interface import implements
-
-from twisted import plugin
-from twisted.cred.strcred import ICheckerFactory
-from twisted.cred.checkers import ICredentialsChecker
-from twisted.cred.credentials import IUsernamePassword
-from twisted.cred.error import UnauthorizedLogin
-from twisted.internet import defer
-
-
-
-def verifyCryptedPassword(crypted, pw):
- if crypted[0] == '$': # md5_crypt encrypted
- salt = '$1$' + crypted.split('$')[2]
- else:
- salt = crypted[:2]
- try:
- import crypt
- except ImportError:
- crypt = None
-
- if crypt is None:
- raise NotImplementedError("cred_unix not supported on this platform")
- return crypt.crypt(pw, salt) == crypted
-
-
-
-class UNIXChecker(object):
- """
- A credentials checker for a UNIX server. This will check that
- an authenticating username/password is a valid user on the system.
-
- Does not work on Windows.
-
- Right now this supports Python's pwd and spwd modules, if they are
- installed. It does not support PAM.
- """
- implements(ICredentialsChecker)
- credentialInterfaces = (IUsernamePassword,)
-
-
- def checkPwd(self, pwd, username, password):
- try:
- cryptedPass = pwd.getpwnam(username)[1]
- except KeyError:
- return defer.fail(UnauthorizedLogin())
- else:
- if cryptedPass in ('*', 'x'):
- # Allow checkSpwd to take over
- return None
- elif verifyCryptedPassword(cryptedPass, password):
- return defer.succeed(username)
-
-
- def checkSpwd(self, spwd, username, password):
- try:
- cryptedPass = spwd.getspnam(username)[1]
- except KeyError:
- return defer.fail(UnauthorizedLogin())
- else:
- if verifyCryptedPassword(cryptedPass, password):
- return defer.succeed(username)
-
-
- def requestAvatarId(self, credentials):
- username, password = credentials.username, credentials.password
-
- try:
- import pwd
- except ImportError:
- pwd = None
-
- if pwd is not None:
- checked = self.checkPwd(pwd, username, password)
- if checked is not None:
- return checked
-
- try:
- import spwd
- except ImportError:
- spwd = None
-
- if spwd is not None:
- checked = self.checkSpwd(spwd, username, password)
- if checked is not None:
- return checked
- # TODO: check_pam?
- # TODO: check_shadow?
- return defer.fail(UnauthorizedLogin())
-
-
-
-unixCheckerFactoryHelp = """
-This checker will attempt to use every resource available to
-authenticate against the list of users on the local UNIX system.
-(This does not support Windows servers for very obvious reasons.)
-
-Right now, this includes support for:
-
- * Python's pwd module (which checks /etc/passwd)
- * Python's spwd module (which checks /etc/shadow)
-
-Future versions may include support for PAM authentication.
-"""
-
-
-
-class UNIXCheckerFactory(object):
- """
- A factory for L{UNIXChecker}.
- """
- implements(ICheckerFactory, plugin.IPlugin)
- authType = 'unix'
- authHelp = unixCheckerFactoryHelp
- argStringFormat = 'No argstring required.'
- credentialInterfaces = UNIXChecker.credentialInterfaces
-
- def generateChecker(self, argstring):
- """
- This checker factory ignores the argument string. Everything
- needed to generate a user database is pulled out of the local
- UNIX environment.
- """
- return UNIXChecker()
-
-
-
-theUnixCheckerFactory = UNIXCheckerFactory()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_conch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_conch.py
deleted file mode 100755
index 4b37e0b2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_conch.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedSSH = ServiceMaker(
- "Twisted Conch Server",
- "twisted.conch.tap",
- "A Conch SSH service.",
- "conch")
-
-TwistedManhole = ServiceMaker(
- "Twisted Manhole (new)",
- "twisted.conch.manhole_tap",
- ("An interactive remote debugger service accessible via telnet "
- "and ssh and providing syntax coloring and basic line editing "
- "functionality."),
- "manhole")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_core.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_core.py
deleted file mode 100755
index 3907d42a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_core.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.internet.endpoints import _SystemdParser, _TCP6ServerParser, _StandardIOParser
-
-systemdEndpointParser = _SystemdParser()
-tcp6ServerEndpointParser = _TCP6ServerParser()
-stdioEndpointParser = _StandardIOParser()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_ftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_ftp.py
deleted file mode 100755
index 474a9c7c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_ftp.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedFTP = ServiceMaker(
- "Twisted FTP",
- "twisted.tap.ftp",
- "An FTP server.",
- "ftp")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_inet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_inet.py
deleted file mode 100755
index 1196343b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_inet.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedINETD = ServiceMaker(
- "Twisted INETD Server",
- "twisted.runner.inetdtap",
- "An inetd(8) replacement.",
- "inetd")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_lore.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_lore.py
deleted file mode 100755
index 1ab57a5d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_lore.py
+++ /dev/null
@@ -1,38 +0,0 @@
-
-from zope.interface import implements
-
-from twisted.lore.scripts.lore import IProcessor
-from twisted.plugin import IPlugin
-
-class _LorePlugin(object):
- implements(IPlugin, IProcessor)
-
- def __init__(self, name, moduleName, description):
- self.name = name
- self.moduleName = moduleName
- self.description = description
-
-DefaultProcessor = _LorePlugin(
- "lore",
- "twisted.lore.default",
- "Lore format")
-
-MathProcessor = _LorePlugin(
- "mlore",
- "twisted.lore.lmath",
- "Lore format with LaTeX formula")
-
-SlideProcessor = _LorePlugin(
- "lore-slides",
- "twisted.lore.slides",
- "Lore for slides")
-
-ManProcessor = _LorePlugin(
- "man",
- "twisted.lore.man2lore",
- "UNIX Man pages")
-
-NevowProcessor = _LorePlugin(
- "nevow",
- "twisted.lore.nevowlore",
- "Nevow for Lore")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_mail.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_mail.py
deleted file mode 100755
index 7e9a5bd5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_mail.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedMail = ServiceMaker(
- "Twisted Mail",
- "twisted.mail.tap",
- "An email service",
- "mail")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_manhole.py
deleted file mode 100755
index 24818908..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_manhole.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedManhole = ServiceMaker(
- "Twisted Manhole (old)",
- "twisted.tap.manhole",
- "An interactive remote debugger service.",
- "manhole-old")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_names.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_names.py
deleted file mode 100755
index 7123bf00..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_names.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedNames = ServiceMaker(
- "Twisted DNS Server",
- "twisted.names.tap",
- "A domain name server.",
- "dns")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_news.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_news.py
deleted file mode 100755
index 0fc88d81..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_news.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedNews = ServiceMaker(
- "Twisted News",
- "twisted.news.tap",
- "A news server.",
- "news")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_portforward.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_portforward.py
deleted file mode 100755
index 1969434b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_portforward.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedPortForward = ServiceMaker(
- "Twisted Port-Forwarding",
- "twisted.tap.portforward",
- "A simple port-forwarder.",
- "portforward")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_qtstub.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_qtstub.py
deleted file mode 100755
index ddf88438..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_qtstub.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Backwards-compatibility plugin for the Qt reactor.
-
-This provides a Qt reactor plugin named C{qt} which emits a deprecation
-warning and a pointer to the separately distributed Qt reactor plugins.
-"""
-
-import warnings
-
-from twisted.application.reactors import Reactor, NoSuchReactor
-
-wikiURL = 'http://twistedmatrix.com/trac/wiki/QTReactor'
-errorMessage = ('qtreactor is no longer a part of Twisted due to licensing '
- 'issues. Please see %s for details.' % (wikiURL,))
-
-class QTStub(Reactor):
- """
- Reactor plugin which emits a deprecation warning on the successful
- installation of its reactor or a pointer to further information if an
- ImportError occurs while attempting to install it.
- """
- def __init__(self):
- super(QTStub, self).__init__(
- 'qt', 'qtreactor', 'QT integration reactor')
-
-
- def install(self):
- """
- Install the Qt reactor with a deprecation warning or try to point
- the user to further information if it cannot be installed.
- """
- try:
- super(QTStub, self).install()
- except (ValueError, ImportError):
- raise NoSuchReactor(errorMessage)
- else:
- warnings.warn(
- "Please use -r qt3 to import qtreactor",
- category=DeprecationWarning)
-
-
-qt = QTStub()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_reactors.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_reactors.py
deleted file mode 100755
index 8562aa9c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_reactors.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.reactors import Reactor
-
-default = Reactor(
- 'default', 'twisted.internet.default',
- 'A reasonable default: poll(2) if available, otherwise select(2).')
-
-select = Reactor(
- 'select', 'twisted.internet.selectreactor', 'select(2)-based reactor.')
-wx = Reactor(
- 'wx', 'twisted.internet.wxreactor', 'wxPython integration reactor.')
-gi = Reactor(
- 'gi', 'twisted.internet.gireactor', 'GObject Introspection integration reactor.')
-gtk3 = Reactor(
- 'gtk3', 'twisted.internet.gtk3reactor', 'Gtk3 integration reactor.')
-gtk = Reactor(
- 'gtk', 'twisted.internet.gtkreactor', 'Gtk1 integration reactor.')
-gtk2 = Reactor(
- 'gtk2', 'twisted.internet.gtk2reactor', 'Gtk2 integration reactor.')
-glib2 = Reactor(
- 'glib2', 'twisted.internet.glib2reactor',
- 'GLib2 event-loop integration reactor.')
-glade = Reactor(
- 'debug-gui', 'twisted.manhole.gladereactor',
- 'Semi-functional debugging/introspection reactor.')
-win32er = Reactor(
- 'win32', 'twisted.internet.win32eventreactor',
- 'Win32 WaitForMultipleObjects-based reactor.')
-poll = Reactor(
- 'poll', 'twisted.internet.pollreactor', 'poll(2)-based reactor.')
-epoll = Reactor(
- 'epoll', 'twisted.internet.epollreactor', 'epoll(4)-based reactor.')
-cf = Reactor(
- 'cf' , 'twisted.internet.cfreactor',
- 'CoreFoundation integration reactor.')
-kqueue = Reactor(
- 'kqueue', 'twisted.internet.kqreactor', 'kqueue(2)-based reactor.')
-iocp = Reactor(
- 'iocp', 'twisted.internet.iocpreactor',
- 'Win32 IO Completion Ports-based reactor.')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_runner.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_runner.py
deleted file mode 100755
index dc630281..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_runner.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedProcmon = ServiceMaker(
- "Twisted Process Monitor",
- "twisted.runner.procmontap",
- ("A process watchdog / supervisor"),
- "procmon")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_socks.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_socks.py
deleted file mode 100755
index 5a94f871..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_socks.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedSOCKS = ServiceMaker(
- "Twisted SOCKS",
- "twisted.tap.socks",
- "A SOCKSv4 proxy service.",
- "socks")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_telnet.py
deleted file mode 100755
index 4cb1f98e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_telnet.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedTelnet = ServiceMaker(
- "Twisted Telnet Shell Server",
- "twisted.tap.telnet",
- "A simple, telnet-based remote debugging service.",
- "telnet")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_trial.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_trial.py
deleted file mode 100755
index debc8afa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_trial.py
+++ /dev/null
@@ -1,59 +0,0 @@
-
-from zope.interface import implements
-
-from twisted.trial.itrial import IReporter
-from twisted.plugin import IPlugin
-
-class _Reporter(object):
- implements(IPlugin, IReporter)
-
- def __init__(self, name, module, description, longOpt, shortOpt, klass):
- self.name = name
- self.module = module
- self.description = description
- self.longOpt = longOpt
- self.shortOpt = shortOpt
- self.klass = klass
-
-
-Tree = _Reporter("Tree Reporter",
- "twisted.trial.reporter",
- description="verbose color output (default reporter)",
- longOpt="verbose",
- shortOpt="v",
- klass="TreeReporter")
-
-BlackAndWhite = _Reporter("Black-And-White Reporter",
- "twisted.trial.reporter",
- description="Colorless verbose output",
- longOpt="bwverbose",
- shortOpt="o",
- klass="VerboseTextReporter")
-
-Minimal = _Reporter("Minimal Reporter",
- "twisted.trial.reporter",
- description="minimal summary output",
- longOpt="summary",
- shortOpt="s",
- klass="MinimalReporter")
-
-Classic = _Reporter("Classic Reporter",
- "twisted.trial.reporter",
- description="terse text output",
- longOpt="text",
- shortOpt="t",
- klass="TextReporter")
-
-Timing = _Reporter("Timing Reporter",
- "twisted.trial.reporter",
- description="Timing output",
- longOpt="timing",
- shortOpt=None,
- klass="TimingTextReporter")
-
-Subunit = _Reporter("Subunit Reporter",
- "twisted.trial.reporter",
- description="subunit output",
- longOpt="subunit",
- shortOpt=None,
- klass="SubunitReporter")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_web.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_web.py
deleted file mode 100755
index c7655a6d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_web.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application.service import ServiceMaker
-
-TwistedWeb = ServiceMaker(
- "Twisted Web",
- "twisted.web.tap",
- ("A general-purpose web server which can serve from a "
- "filesystem or application resource."),
- "web")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_words.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_words.py
deleted file mode 100755
index 6f14aefa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/plugins/twisted_words.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from zope.interface import classProvides
-
-from twisted.plugin import IPlugin
-
-from twisted.application.service import ServiceMaker
-from twisted.words import iwords
-
-
-NewTwistedWords = ServiceMaker(
- "New Twisted Words",
- "twisted.words.tap",
- "A modern words server",
- "words")
-
-TwistedXMPPRouter = ServiceMaker(
- "XMPP Router",
- "twisted.words.xmpproutertap",
- "An XMPP Router server",
- "xmpp-router")
-
-class RelayChatInterface(object):
- classProvides(IPlugin, iwords.IProtocolPlugin)
-
- name = 'irc'
-
- def getFactory(cls, realm, portal):
- from twisted.words import service
- return service.IRCFactory(realm, portal)
- getFactory = classmethod(getFactory)
-
-class PBChatInterface(object):
- classProvides(IPlugin, iwords.IProtocolPlugin)
-
- name = 'pb'
-
- def getFactory(cls, realm, portal):
- from twisted.spread import pb
- return pb.PBServerFactory(portal, True)
- getFactory = classmethod(getFactory)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/__init__.py
deleted file mode 100755
index a0796514..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Protocols: a collection of internet protocol implementations.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/amp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/amp.py
deleted file mode 100755
index 72a3e7ae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/amp.py
+++ /dev/null
@@ -1,2705 +0,0 @@
-# -*- test-case-name: twisted.test.test_amp -*-
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module implements AMP, the Asynchronous Messaging Protocol.
-
-AMP is a protocol for sending multiple asynchronous request/response pairs over
-the same connection. Requests and responses are both collections of key/value
-pairs.
-
-AMP is a very simple protocol which is not an application. This module is a
-"protocol construction kit" of sorts; it attempts to be the simplest wire-level
-implementation of Deferreds. AMP provides the following base-level features:
-
- - Asynchronous request/response handling (hence the name)
-
- - Requests and responses are both key/value pairs
-
- - Binary transfer of all data: all data is length-prefixed. Your
- application will never need to worry about quoting.
-
- - Command dispatching (like HTTP Verbs): the protocol is extensible, and
- multiple AMP sub-protocols can be grouped together easily.
-
-The protocol implementation also provides a few additional features which are
-not part of the core wire protocol, but are nevertheless very useful:
-
- - Tight TLS integration, with an included StartTLS command.
-
- - Handshaking to other protocols: because AMP has well-defined message
- boundaries and maintains all incoming and outgoing requests for you, you
- can start a connection over AMP and then switch to another protocol.
- This makes it ideal for firewall-traversal applications where you may
- have only one forwarded port but multiple applications that want to use
- it.
-
-Using AMP with Twisted is simple. Each message is a command, with a response.
-You begin by defining a command type. Commands specify their input and output
-in terms of the types that they expect to see in the request and response
-key-value pairs. Here's an example of a command that adds two integers, 'a'
-and 'b'::
-
- class Sum(amp.Command):
- arguments = [('a', amp.Integer()),
- ('b', amp.Integer())]
- response = [('total', amp.Integer())]
-
-Once you have specified a command, you need to make it part of a protocol, and
-define a responder for it. Here's a 'JustSum' protocol that includes a
-responder for our 'Sum' command::
-
- class JustSum(amp.AMP):
- def sum(self, a, b):
- total = a + b
- print 'Did a sum: %d + %d = %d' % (a, b, total)
- return {'total': total}
- Sum.responder(sum)
-
-Later, when you want to actually do a sum, the following expression will return
-a L{Deferred} which will fire with the result::
-
- ClientCreator(reactor, amp.AMP).connectTCP(...).addCallback(
- lambda p: p.callRemote(Sum, a=13, b=81)).addCallback(
- lambda result: result['total'])
-
-Command responders may also return Deferreds, causing the response to be
-sent only once the Deferred fires::
-
- class DelayedSum(amp.AMP):
- def slowSum(self, a, b):
- total = a + b
- result = defer.Deferred()
- reactor.callLater(3, result.callback, {'total': total})
- return result
- Sum.responder(slowSum)
-
-This is transparent to the caller.
-
-You can also define the propagation of specific errors in AMP. For example,
-for the slightly more complicated case of division, we might have to deal with
-division by zero::
-
- class Divide(amp.Command):
- arguments = [('numerator', amp.Integer()),
- ('denominator', amp.Integer())]
- response = [('result', amp.Float())]
- errors = {ZeroDivisionError: 'ZERO_DIVISION'}
-
-The 'errors' mapping here tells AMP that if a responder to Divide emits a
-L{ZeroDivisionError}, then the other side should be informed that an error of
-the type 'ZERO_DIVISION' has occurred. Writing a responder which takes
-advantage of this is very simple - just raise your exception normally::
-
- class JustDivide(amp.AMP):
- def divide(self, numerator, denominator):
- result = numerator / denominator
- print 'Divided: %d / %d = %d' % (numerator, denominator, total)
- return {'result': result}
- Divide.responder(divide)
-
-On the client side, the errors mapping will be used to determine what the
-'ZERO_DIVISION' error means, and translated into an asynchronous exception,
-which can be handled normally as any L{Deferred} would be::
-
- def trapZero(result):
- result.trap(ZeroDivisionError)
- print "Divided by zero: returning INF"
- return 1e1000
- ClientCreator(reactor, amp.AMP).connectTCP(...).addCallback(
- lambda p: p.callRemote(Divide, numerator=1234,
- denominator=0)
- ).addErrback(trapZero)
-
-For a complete, runnable example of both of these commands, see the files in
-the Twisted repository::
-
- doc/core/examples/ampserver.py
- doc/core/examples/ampclient.py
-
-On the wire, AMP is a protocol which uses 2-byte lengths to prefix keys and
-values, and empty keys to separate messages::
-
- <2-byte length><key><2-byte length><value>
- <2-byte length><key><2-byte length><value>
- ...
- <2-byte length><key><2-byte length><value>
- <NUL><NUL> # Empty Key == End of Message
-
-And so on. Because it's tedious to refer to lengths and NULs constantly, the
-documentation will refer to packets as if they were newline delimited, like
-so::
-
- C: _command: sum
- C: _ask: ef639e5c892ccb54
- C: a: 13
- C: b: 81
-
- S: _answer: ef639e5c892ccb54
- S: total: 94
-
-Notes:
-
-In general, the order of keys is arbitrary. Specific uses of AMP may impose an
-ordering requirement, but unless this is specified explicitly, any ordering may
-be generated and any ordering must be accepted. This applies to the
-command-related keys I{_command} and I{_ask} as well as any other keys.
-
-Values are limited to the maximum encodable size in a 16-bit length, 65535
-bytes.
-
-Keys are limited to the maximum encodable size in a 8-bit length, 255 bytes.
-Note that we still use 2-byte lengths to encode keys. This small redundancy
-has several features:
-
- - If an implementation becomes confused and starts emitting corrupt data,
- or gets keys confused with values, many common errors will be signalled
- immediately instead of delivering obviously corrupt packets.
-
- - A single NUL will separate every key, and a double NUL separates
- messages. This provides some redundancy when debugging traffic dumps.
-
- - NULs will be present at regular intervals along the protocol, providing
- some padding for otherwise braindead C implementations of the protocol,
- so that <stdio.h> string functions will see the NUL and stop.
-
- - This makes it possible to run an AMP server on a port also used by a
- plain-text protocol, and easily distinguish between non-AMP clients (like
- web browsers) which issue non-NUL as the first byte, and AMP clients,
- which always issue NUL as the first byte.
-"""
-
-__metaclass__ = type
-
-import types, warnings
-
-from cStringIO import StringIO
-from struct import pack
-import decimal, datetime
-from itertools import count
-
-from zope.interface import Interface, implements
-
-from twisted.python.compat import set
-from twisted.python.util import unsignedID
-from twisted.python.reflect import accumulateClassDict
-from twisted.python.failure import Failure
-from twisted.python import log, filepath
-
-from twisted.internet.interfaces import IFileDescriptorReceiver
-from twisted.internet.main import CONNECTION_LOST
-from twisted.internet.error import PeerVerifyError, ConnectionLost
-from twisted.internet.error import ConnectionClosed
-from twisted.internet.defer import Deferred, maybeDeferred, fail
-from twisted.protocols.basic import Int16StringReceiver, StatefulStringProtocol
-
-try:
- from twisted.internet import ssl
-except ImportError:
- ssl = None
-
-if ssl and not ssl.supported:
- ssl = None
-
-if ssl is not None:
- from twisted.internet.ssl import CertificateOptions, Certificate, DN, KeyPair
-
-ASK = '_ask'
-ANSWER = '_answer'
-COMMAND = '_command'
-ERROR = '_error'
-ERROR_CODE = '_error_code'
-ERROR_DESCRIPTION = '_error_description'
-UNKNOWN_ERROR_CODE = 'UNKNOWN'
-UNHANDLED_ERROR_CODE = 'UNHANDLED'
-
-MAX_KEY_LENGTH = 0xff
-MAX_VALUE_LENGTH = 0xffff
-
-
-class IArgumentType(Interface):
- """
- An L{IArgumentType} can serialize a Python object into an AMP box and
- deserialize information from an AMP box back into a Python object.
-
- @since: 9.0
- """
- def fromBox(name, strings, objects, proto):
- """
- Given an argument name and an AMP box containing serialized values,
- extract one or more Python objects and add them to the C{objects}
- dictionary.
-
- @param name: The name associated with this argument. Most commonly,
- this is the key which can be used to find a serialized value in
- C{strings} and which should be used as the key in C{objects} to
- associate with a structured Python object.
- @type name: C{str}
-
- @param strings: The AMP box from which to extract one or more
- values.
- @type strings: C{dict}
-
- @param objects: The output dictionary to populate with the value for
- this argument.
- @type objects: C{dict}
-
- @param proto: The protocol instance which received the AMP box being
- interpreted. Most likely this is an instance of L{AMP}, but
- this is not guaranteed.
-
- @return: C{None}
- """
-
-
- def toBox(name, strings, objects, proto):
- """
- Given an argument name and a dictionary containing structured Python
- objects, serialize values into one or more strings and add them to
- the C{strings} dictionary.
-
- @param name: The name associated with this argument. Most commonly,
- this is the key which can be used to find an object in
- C{objects} and which should be used as the key in C{strings} to
- associate with a C{str} giving the serialized form of that
- object.
- @type name: C{str}
-
- @param strings: The AMP box into which to insert one or more
- strings.
- @type strings: C{dict}
-
- @param objects: The input dictionary from which to extract Python
- objects to serialize.
- @type objects: C{dict}
-
- @param proto: The protocol instance which will send the AMP box once
- it is fully populated. Most likely this is an instance of
- L{AMP}, but this is not guaranteed.
-
- @return: C{None}
- """
-
-
-
-class IBoxSender(Interface):
- """
- A transport which can send L{AmpBox} objects.
- """
-
- def sendBox(box):
- """
- Send an L{AmpBox}.
-
- @raise ProtocolSwitched: if the underlying protocol has been
- switched.
-
- @raise ConnectionLost: if the underlying connection has already been
- lost.
- """
-
- def unhandledError(failure):
- """
- An unhandled error occurred in response to a box. Log it
- appropriately.
-
- @param failure: a L{Failure} describing the error that occurred.
- """
-
-
-
-class IBoxReceiver(Interface):
- """
- An application object which can receive L{AmpBox} objects and dispatch them
- appropriately.
- """
-
- def startReceivingBoxes(boxSender):
- """
- The L{ampBoxReceived} method will start being called; boxes may be
- responded to by responding to the given L{IBoxSender}.
-
- @param boxSender: an L{IBoxSender} provider.
- """
-
-
- def ampBoxReceived(box):
- """
- A box was received from the transport; dispatch it appropriately.
- """
-
-
- def stopReceivingBoxes(reason):
- """
- No further boxes will be received on this connection.
-
- @type reason: L{Failure}
- """
-
-
-
-class IResponderLocator(Interface):
- """
- An application object which can look up appropriate responder methods for
- AMP commands.
- """
-
- def locateResponder(name):
- """
- Locate a responder method appropriate for the named command.
-
- @param name: the wire-level name (commandName) of the AMP command to be
- responded to.
-
- @return: a 1-argument callable that takes an L{AmpBox} with argument
- values for the given command, and returns an L{AmpBox} containing
- argument values for the named command, or a L{Deferred} that fires the
- same.
- """
-
-
-
-class AmpError(Exception):
- """
- Base class of all Amp-related exceptions.
- """
-
-
-
-class ProtocolSwitched(Exception):
- """
- Connections which have been switched to other protocols can no longer
- accept traffic at the AMP level. This is raised when you try to send it.
- """
-
-
-
-class OnlyOneTLS(AmpError):
- """
- This is an implementation limitation; TLS may only be started once per
- connection.
- """
-
-
-
-class NoEmptyBoxes(AmpError):
- """
- You can't have empty boxes on the connection. This is raised when you
- receive or attempt to send one.
- """
-
-
-
-class InvalidSignature(AmpError):
- """
- You didn't pass all the required arguments.
- """
-
-
-
-class TooLong(AmpError):
- """
- One of the protocol's length limitations was violated.
-
- @ivar isKey: true if the string being encoded in a key position, false if
- it was in a value position.
-
- @ivar isLocal: Was the string encoded locally, or received too long from
- the network? (It's only physically possible to encode "too long" values on
- the network for keys.)
-
- @ivar value: The string that was too long.
-
- @ivar keyName: If the string being encoded was in a value position, what
- key was it being encoded for?
- """
-
- def __init__(self, isKey, isLocal, value, keyName=None):
- AmpError.__init__(self)
- self.isKey = isKey
- self.isLocal = isLocal
- self.value = value
- self.keyName = keyName
-
-
- def __repr__(self):
- hdr = self.isKey and "key" or "value"
- if not self.isKey:
- hdr += ' ' + repr(self.keyName)
- lcl = self.isLocal and "local" or "remote"
- return "%s %s too long: %d" % (lcl, hdr, len(self.value))
-
-
-
-class BadLocalReturn(AmpError):
- """
- A bad value was returned from a local command; we were unable to coerce it.
- """
- def __init__(self, message, enclosed):
- AmpError.__init__(self)
- self.message = message
- self.enclosed = enclosed
-
-
- def __repr__(self):
- return self.message + " " + self.enclosed.getBriefTraceback()
-
- __str__ = __repr__
-
-
-
-class RemoteAmpError(AmpError):
- """
- This error indicates that something went wrong on the remote end of the
- connection, and the error was serialized and transmitted to you.
- """
- def __init__(self, errorCode, description, fatal=False, local=None):
- """Create a remote error with an error code and description.
-
- @param errorCode: the AMP error code of this error.
-
- @param description: some text to show to the user.
-
- @param fatal: a boolean, true if this error should terminate the
- connection.
-
- @param local: a local Failure, if one exists.
- """
- if local:
- localwhat = ' (local)'
- othertb = local.getBriefTraceback()
- else:
- localwhat = ''
- othertb = ''
- Exception.__init__(self, "Code<%s>%s: %s%s" % (
- errorCode, localwhat,
- description, othertb))
- self.local = local
- self.errorCode = errorCode
- self.description = description
- self.fatal = fatal
-
-
-
-class UnknownRemoteError(RemoteAmpError):
- """
- This means that an error whose type we can't identify was raised from the
- other side.
- """
- def __init__(self, description):
- errorCode = UNKNOWN_ERROR_CODE
- RemoteAmpError.__init__(self, errorCode, description)
-
-
-
-class MalformedAmpBox(AmpError):
- """
- This error indicates that the wire-level protocol was malformed.
- """
-
-
-
-class UnhandledCommand(AmpError):
- """
- A command received via amp could not be dispatched.
- """
-
-
-
-class IncompatibleVersions(AmpError):
- """
- It was impossible to negotiate a compatible version of the protocol with
- the other end of the connection.
- """
-
-
-PROTOCOL_ERRORS = {UNHANDLED_ERROR_CODE: UnhandledCommand}
-
-class AmpBox(dict):
- """
- I am a packet in the AMP protocol, much like a regular str:str dictionary.
- """
- __slots__ = [] # be like a regular dictionary, don't magically
- # acquire a __dict__...
-
-
- def copy(self):
- """
- Return another AmpBox just like me.
- """
- newBox = self.__class__()
- newBox.update(self)
- return newBox
-
-
- def serialize(self):
- """
- Convert me into a wire-encoded string.
-
- @return: a str encoded according to the rules described in the module
- docstring.
- """
- i = self.items()
- i.sort()
- L = []
- w = L.append
- for k, v in i:
- if type(k) == unicode:
- raise TypeError("Unicode key not allowed: %r" % k)
- if type(v) == unicode:
- raise TypeError(
- "Unicode value for key %r not allowed: %r" % (k, v))
- if len(k) > MAX_KEY_LENGTH:
- raise TooLong(True, True, k, None)
- if len(v) > MAX_VALUE_LENGTH:
- raise TooLong(False, True, v, k)
- for kv in k, v:
- w(pack("!H", len(kv)))
- w(kv)
- w(pack("!H", 0))
- return ''.join(L)
-
-
- def _sendTo(self, proto):
- """
- Serialize and send this box to a Amp instance. By the time it is being
- sent, several keys are required. I must have exactly ONE of::
-
- _ask
- _answer
- _error
-
- If the '_ask' key is set, then the '_command' key must also be
- set.
-
- @param proto: an AMP instance.
- """
- proto.sendBox(self)
-
- def __repr__(self):
- return 'AmpBox(%s)' % (dict.__repr__(self),)
-
-# amp.Box => AmpBox
-
-Box = AmpBox
-
-class QuitBox(AmpBox):
- """
- I am an AmpBox that, upon being sent, terminates the connection.
- """
- __slots__ = []
-
-
- def __repr__(self):
- return 'QuitBox(**%s)' % (super(QuitBox, self).__repr__(),)
-
-
- def _sendTo(self, proto):
- """
- Immediately call loseConnection after sending.
- """
- super(QuitBox, self)._sendTo(proto)
- proto.transport.loseConnection()
-
-
-
-class _SwitchBox(AmpBox):
- """
- Implementation detail of ProtocolSwitchCommand: I am a AmpBox which sets
- up state for the protocol to switch.
- """
-
- # DON'T set __slots__ here; we do have an attribute.
-
- def __init__(self, innerProto, **kw):
- """
- Create a _SwitchBox with the protocol to switch to after being sent.
-
- @param innerProto: the protocol instance to switch to.
- @type innerProto: an IProtocol provider.
- """
- super(_SwitchBox, self).__init__(**kw)
- self.innerProto = innerProto
-
-
- def __repr__(self):
- return '_SwitchBox(%r, **%s)' % (self.innerProto,
- dict.__repr__(self),)
-
-
- def _sendTo(self, proto):
- """
- Send me; I am the last box on the connection. All further traffic will be
- over the new protocol.
- """
- super(_SwitchBox, self)._sendTo(proto)
- proto._lockForSwitch()
- proto._switchTo(self.innerProto)
-
-
-
-class BoxDispatcher:
- """
- A L{BoxDispatcher} dispatches '_ask', '_answer', and '_error' L{AmpBox}es,
- both incoming and outgoing, to their appropriate destinations.
-
- Outgoing commands are converted into L{Deferred}s and outgoing boxes, and
- associated tracking state to fire those L{Deferred} when '_answer' boxes
- come back. Incoming '_answer' and '_error' boxes are converted into
- callbacks and errbacks on those L{Deferred}s, respectively.
-
- Incoming '_ask' boxes are converted into method calls on a supplied method
- locator.
-
- @ivar _outstandingRequests: a dictionary mapping request IDs to
- L{Deferred}s which were returned for those requests.
-
- @ivar locator: an object with a L{locateResponder} method that locates a
- responder function that takes a Box and returns a result (either a Box or a
- Deferred which fires one).
-
- @ivar boxSender: an object which can send boxes, via the L{_sendBox}
- method, such as an L{AMP} instance.
- @type boxSender: L{IBoxSender}
- """
-
- implements(IBoxReceiver)
-
- _failAllReason = None
- _outstandingRequests = None
- _counter = 0L
- boxSender = None
-
- def __init__(self, locator):
- self._outstandingRequests = {}
- self.locator = locator
-
-
- def startReceivingBoxes(self, boxSender):
- """
- The given boxSender is going to start calling boxReceived on this
- L{BoxDispatcher}.
-
- @param boxSender: The L{IBoxSender} to send command responses to.
- """
- self.boxSender = boxSender
-
-
- def stopReceivingBoxes(self, reason):
- """
- No further boxes will be received here. Terminate all currently
- oustanding command deferreds with the given reason.
- """
- self.failAllOutgoing(reason)
-
-
- def failAllOutgoing(self, reason):
- """
- Call the errback on all outstanding requests awaiting responses.
-
- @param reason: the Failure instance to pass to those errbacks.
- """
- self._failAllReason = reason
- OR = self._outstandingRequests.items()
- self._outstandingRequests = None # we can never send another request
- for key, value in OR:
- value.errback(reason)
-
-
- def _nextTag(self):
- """
- Generate protocol-local serial numbers for _ask keys.
-
- @return: a string that has not yet been used on this connection.
- """
- self._counter += 1
- return '%x' % (self._counter,)
-
-
- def _sendBoxCommand(self, command, box, requiresAnswer=True):
- """
- Send a command across the wire with the given C{amp.Box}.
-
- Mutate the given box to give it any additional keys (_command, _ask)
- required for the command and request/response machinery, then send it.
-
- If requiresAnswer is True, returns a C{Deferred} which fires when a
- response is received. The C{Deferred} is fired with an C{amp.Box} on
- success, or with an C{amp.RemoteAmpError} if an error is received.
-
- If the Deferred fails and the error is not handled by the caller of
- this method, the failure will be logged and the connection dropped.
-
- @param command: a str, the name of the command to issue.
-
- @param box: an AmpBox with the arguments for the command.
-
- @param requiresAnswer: a boolean. Defaults to True. If True, return a
- Deferred which will fire when the other side responds to this command.
- If False, return None and do not ask the other side for acknowledgement.
-
- @return: a Deferred which fires the AmpBox that holds the response to
- this command, or None, as specified by requiresAnswer.
-
- @raise ProtocolSwitched: if the protocol has been switched.
- """
- if self._failAllReason is not None:
- return fail(self._failAllReason)
- box[COMMAND] = command
- tag = self._nextTag()
- if requiresAnswer:
- box[ASK] = tag
- box._sendTo(self.boxSender)
- if requiresAnswer:
- result = self._outstandingRequests[tag] = Deferred()
- else:
- result = None
- return result
-
-
- def callRemoteString(self, command, requiresAnswer=True, **kw):
- """
- This is a low-level API, designed only for optimizing simple messages
- for which the overhead of parsing is too great.
-
- @param command: a str naming the command.
-
- @param kw: arguments to the amp box.
-
- @param requiresAnswer: a boolean. Defaults to True. If True, return a
- Deferred which will fire when the other side responds to this command.
- If False, return None and do not ask the other side for acknowledgement.
-
- @return: a Deferred which fires the AmpBox that holds the response to
- this command, or None, as specified by requiresAnswer.
- """
- box = Box(kw)
- return self._sendBoxCommand(command, box, requiresAnswer)
-
-
- def callRemote(self, commandType, *a, **kw):
- """
- This is the primary high-level API for sending messages via AMP. Invoke it
- with a command and appropriate arguments to send a message to this
- connection's peer.
-
- @param commandType: a subclass of Command.
- @type commandType: L{type}
-
- @param a: Positional (special) parameters taken by the command.
- Positional parameters will typically not be sent over the wire. The
- only command included with AMP which uses positional parameters is
- L{ProtocolSwitchCommand}, which takes the protocol that will be
- switched to as its first argument.
-
- @param kw: Keyword arguments taken by the command. These are the
- arguments declared in the command's 'arguments' attribute. They will
- be encoded and sent to the peer as arguments for the L{commandType}.
-
- @return: If L{commandType} has a C{requiresAnswer} attribute set to
- L{False}, then return L{None}. Otherwise, return a L{Deferred} which
- fires with a dictionary of objects representing the result of this
- call. Additionally, this L{Deferred} may fail with an exception
- representing a connection failure, with L{UnknownRemoteError} if the
- other end of the connection fails for an unknown reason, or with any
- error specified as a key in L{commandType}'s C{errors} dictionary.
- """
-
- # XXX this takes command subclasses and not command objects on purpose.
- # There's really no reason to have all this back-and-forth between
- # command objects and the protocol, and the extra object being created
- # (the Command instance) is pointless. Command is kind of like
- # Interface, and should be more like it.
-
- # In other words, the fact that commandType is instantiated here is an
- # implementation detail. Don't rely on it.
-
- try:
- co = commandType(*a, **kw)
- except:
- return fail()
- return co._doCommand(self)
-
-
- def unhandledError(self, failure):
- """
- This is a terminal callback called after application code has had a
- chance to quash any errors.
- """
- return self.boxSender.unhandledError(failure)
-
-
- def _answerReceived(self, box):
- """
- An AMP box was received that answered a command previously sent with
- L{callRemote}.
-
- @param box: an AmpBox with a value for its L{ANSWER} key.
- """
- question = self._outstandingRequests.pop(box[ANSWER])
- question.addErrback(self.unhandledError)
- question.callback(box)
-
-
- def _errorReceived(self, box):
- """
- An AMP box was received that answered a command previously sent with
- L{callRemote}, with an error.
-
- @param box: an L{AmpBox} with a value for its L{ERROR}, L{ERROR_CODE},
- and L{ERROR_DESCRIPTION} keys.
- """
- question = self._outstandingRequests.pop(box[ERROR])
- question.addErrback(self.unhandledError)
- errorCode = box[ERROR_CODE]
- description = box[ERROR_DESCRIPTION]
- if errorCode in PROTOCOL_ERRORS:
- exc = PROTOCOL_ERRORS[errorCode](errorCode, description)
- else:
- exc = RemoteAmpError(errorCode, description)
- question.errback(Failure(exc))
-
-
- def _commandReceived(self, box):
- """
- @param box: an L{AmpBox} with a value for its L{COMMAND} and L{ASK}
- keys.
- """
- def formatAnswer(answerBox):
- answerBox[ANSWER] = box[ASK]
- return answerBox
- def formatError(error):
- if error.check(RemoteAmpError):
- code = error.value.errorCode
- desc = error.value.description
- if error.value.fatal:
- errorBox = QuitBox()
- else:
- errorBox = AmpBox()
- else:
- errorBox = QuitBox()
- log.err(error) # here is where server-side logging happens
- # if the error isn't handled
- code = UNKNOWN_ERROR_CODE
- desc = "Unknown Error"
- errorBox[ERROR] = box[ASK]
- errorBox[ERROR_DESCRIPTION] = desc
- errorBox[ERROR_CODE] = code
- return errorBox
- deferred = self.dispatchCommand(box)
- if ASK in box:
- deferred.addCallbacks(formatAnswer, formatError)
- deferred.addCallback(self._safeEmit)
- deferred.addErrback(self.unhandledError)
-
-
- def ampBoxReceived(self, box):
- """
- An AmpBox was received, representing a command, or an answer to a
- previously issued command (either successful or erroneous). Respond to
- it according to its contents.
-
- @param box: an AmpBox
-
- @raise NoEmptyBoxes: when a box is received that does not contain an
- '_answer', '_command' / '_ask', or '_error' key; i.e. one which does not
- fit into the command / response protocol defined by AMP.
- """
- if ANSWER in box:
- self._answerReceived(box)
- elif ERROR in box:
- self._errorReceived(box)
- elif COMMAND in box:
- self._commandReceived(box)
- else:
- raise NoEmptyBoxes(box)
-
-
- def _safeEmit(self, aBox):
- """
- Emit a box, ignoring L{ProtocolSwitched} and L{ConnectionLost} errors
- which cannot be usefully handled.
- """
- try:
- aBox._sendTo(self.boxSender)
- except (ProtocolSwitched, ConnectionLost):
- pass
-
-
- def dispatchCommand(self, box):
- """
- A box with a _command key was received.
-
- Dispatch it to a local handler call it.
-
- @param proto: an AMP instance.
- @param box: an AmpBox to be dispatched.
- """
- cmd = box[COMMAND]
- responder = self.locator.locateResponder(cmd)
- if responder is None:
- return fail(RemoteAmpError(
- UNHANDLED_ERROR_CODE,
- "Unhandled Command: %r" % (cmd,),
- False,
- local=Failure(UnhandledCommand())))
- return maybeDeferred(responder, box)
-
-
-
-class CommandLocator:
- """
- A L{CommandLocator} is a collection of responders to AMP L{Command}s, with
- the help of the L{Command.responder} decorator.
- """
-
- class __metaclass__(type):
- """
- This metaclass keeps track of all of the Command.responder-decorated
- methods defined since the last CommandLocator subclass was defined. It
- assumes (usually correctly, but unfortunately not necessarily so) that
- those commands responders were all declared as methods of the class
- being defined. Note that this list can be incorrect if users use the
- Command.responder decorator outside the context of a CommandLocator
- class declaration.
-
- Command responders defined on subclasses are given precedence over
- those inherited from a base class.
-
- The Command.responder decorator explicitly cooperates with this
- metaclass.
- """
-
- _currentClassCommands = []
- def __new__(cls, name, bases, attrs):
- commands = cls._currentClassCommands[:]
- cls._currentClassCommands[:] = []
- cd = attrs['_commandDispatch'] = {}
- subcls = type.__new__(cls, name, bases, attrs)
- ancestors = list(subcls.__mro__[1:])
- ancestors.reverse()
- for ancestor in ancestors:
- cd.update(getattr(ancestor, '_commandDispatch', {}))
- for commandClass, responderFunc in commands:
- cd[commandClass.commandName] = (commandClass, responderFunc)
- if (bases and (
- subcls.lookupFunction != CommandLocator.lookupFunction)):
- def locateResponder(self, name):
- warnings.warn(
- "Override locateResponder, not lookupFunction.",
- category=PendingDeprecationWarning,
- stacklevel=2)
- return self.lookupFunction(name)
- subcls.locateResponder = locateResponder
- return subcls
-
-
- implements(IResponderLocator)
-
-
- def _wrapWithSerialization(self, aCallable, command):
- """
- Wrap aCallable with its command's argument de-serialization
- and result serialization logic.
-
- @param aCallable: a callable with a 'command' attribute, designed to be
- called with keyword arguments.
-
- @param command: the command class whose serialization to use.
-
- @return: a 1-arg callable which, when invoked with an AmpBox, will
- deserialize the argument list and invoke appropriate user code for the
- callable's command, returning a Deferred which fires with the result or
- fails with an error.
- """
- def doit(box):
- kw = command.parseArguments(box, self)
- def checkKnownErrors(error):
- key = error.trap(*command.allErrors)
- code = command.allErrors[key]
- desc = str(error.value)
- return Failure(RemoteAmpError(
- code, desc, key in command.fatalErrors, local=error))
- def makeResponseFor(objects):
- try:
- return command.makeResponse(objects, self)
- except:
- # let's helpfully log this.
- originalFailure = Failure()
- raise BadLocalReturn(
- "%r returned %r and %r could not serialize it" % (
- aCallable,
- objects,
- command),
- originalFailure)
- return maybeDeferred(aCallable, **kw).addCallback(
- makeResponseFor).addErrback(
- checkKnownErrors)
- return doit
-
-
- def lookupFunction(self, name):
- """
- Deprecated synonym for L{locateResponder}
- """
- if self.__class__.lookupFunction != CommandLocator.lookupFunction:
- return CommandLocator.locateResponder(self, name)
- else:
- warnings.warn("Call locateResponder, not lookupFunction.",
- category=PendingDeprecationWarning,
- stacklevel=2)
- return self.locateResponder(name)
-
-
- def locateResponder(self, name):
- """
- Locate a callable to invoke when executing the named command.
-
- @param name: the normalized name (from the wire) of the command.
-
- @return: a 1-argument function that takes a Box and returns a box or a
- Deferred which fires a Box, for handling the command identified by the
- given name, or None, if no appropriate responder can be found.
- """
- # Try to find a high-level method to invoke, and if we can't find one,
- # fall back to a low-level one.
- cd = self._commandDispatch
- if name in cd:
- commandClass, responderFunc = cd[name]
- responderMethod = types.MethodType(
- responderFunc, self, self.__class__)
- return self._wrapWithSerialization(responderMethod, commandClass)
-
-
-
-class SimpleStringLocator(object):
- """
- Implement the L{locateResponder} method to do simple, string-based
- dispatch.
- """
-
- implements(IResponderLocator)
-
- baseDispatchPrefix = 'amp_'
-
- def locateResponder(self, name):
- """
- Locate a callable to invoke when executing the named command.
-
- @return: a function with the name C{"amp_" + name} on L{self}, or None
- if no such function exists. This function will then be called with the
- L{AmpBox} itself as an argument.
-
- @param name: the normalized name (from the wire) of the command.
- """
- fName = self.baseDispatchPrefix + (name.upper())
- return getattr(self, fName, None)
-
-
-
-PYTHON_KEYWORDS = [
- 'and', 'del', 'for', 'is', 'raise', 'assert', 'elif', 'from', 'lambda',
- 'return', 'break', 'else', 'global', 'not', 'try', 'class', 'except',
- 'if', 'or', 'while', 'continue', 'exec', 'import', 'pass', 'yield',
- 'def', 'finally', 'in', 'print']
-
-
-
-def _wireNameToPythonIdentifier(key):
- """
- (Private) Normalize an argument name from the wire for use with Python
- code. If the return value is going to be a python keyword it will be
- capitalized. If it contains any dashes they will be replaced with
- underscores.
-
- The rationale behind this method is that AMP should be an inherently
- multi-language protocol, so message keys may contain all manner of bizarre
- bytes. This is not a complete solution; there are still forms of arguments
- that this implementation will be unable to parse. However, Python
- identifiers share a huge raft of properties with identifiers from many
- other languages, so this is a 'good enough' effort for now. We deal
- explicitly with dashes because that is the most likely departure: Lisps
- commonly use dashes to separate method names, so protocols initially
- implemented in a lisp amp dialect may use dashes in argument or command
- names.
-
- @param key: a str, looking something like 'foo-bar-baz' or 'from'
-
- @return: a str which is a valid python identifier, looking something like
- 'foo_bar_baz' or 'From'.
- """
- lkey = key.replace("-", "_")
- if lkey in PYTHON_KEYWORDS:
- return lkey.title()
- return lkey
-
-
-
-class Argument:
- """
- Base-class of all objects that take values from Amp packets and convert
- them into objects for Python functions.
-
- This implementation of L{IArgumentType} provides several higher-level
- hooks for subclasses to override. See L{toString} and L{fromString}
- which will be used to define the behavior of L{IArgumentType.toBox} and
- L{IArgumentType.fromBox}, respectively.
- """
- implements(IArgumentType)
-
- optional = False
-
-
- def __init__(self, optional=False):
- """
- Create an Argument.
-
- @param optional: a boolean indicating whether this argument can be
- omitted in the protocol.
- """
- self.optional = optional
-
-
- def retrieve(self, d, name, proto):
- """
- Retrieve the given key from the given dictionary, removing it if found.
-
- @param d: a dictionary.
-
- @param name: a key in L{d}.
-
- @param proto: an instance of an AMP.
-
- @raise KeyError: if I am not optional and no value was found.
-
- @return: d[name].
- """
- if self.optional:
- value = d.get(name)
- if value is not None:
- del d[name]
- else:
- value = d.pop(name)
- return value
-
-
- def fromBox(self, name, strings, objects, proto):
- """
- Populate an 'out' dictionary with mapping names to Python values
- decoded from an 'in' AmpBox mapping strings to string values.
-
- @param name: the argument name to retrieve
- @type name: str
-
- @param strings: The AmpBox to read string(s) from, a mapping of
- argument names to string values.
- @type strings: AmpBox
-
- @param objects: The dictionary to write object(s) to, a mapping of
- names to Python objects.
- @type objects: dict
-
- @param proto: an AMP instance.
- """
- st = self.retrieve(strings, name, proto)
- nk = _wireNameToPythonIdentifier(name)
- if self.optional and st is None:
- objects[nk] = None
- else:
- objects[nk] = self.fromStringProto(st, proto)
-
-
- def toBox(self, name, strings, objects, proto):
- """
- Populate an 'out' AmpBox with strings encoded from an 'in' dictionary
- mapping names to Python values.
-
- @param name: the argument name to retrieve
- @type name: str
-
- @param strings: The AmpBox to write string(s) to, a mapping of
- argument names to string values.
- @type strings: AmpBox
-
- @param objects: The dictionary to read object(s) from, a mapping of
- names to Python objects.
-
- @type objects: dict
-
- @param proto: the protocol we are converting for.
- @type proto: AMP
- """
- obj = self.retrieve(objects, _wireNameToPythonIdentifier(name), proto)
- if self.optional and obj is None:
- # strings[name] = None
- pass
- else:
- strings[name] = self.toStringProto(obj, proto)
-
-
- def fromStringProto(self, inString, proto):
- """
- Convert a string to a Python value.
-
- @param inString: the string to convert.
-
- @param proto: the protocol we are converting for.
- @type proto: AMP
-
- @return: a Python object.
- """
- return self.fromString(inString)
-
-
- def toStringProto(self, inObject, proto):
- """
- Convert a Python object to a string.
-
- @param inObject: the object to convert.
-
- @param proto: the protocol we are converting for.
- @type proto: AMP
- """
- return self.toString(inObject)
-
-
- def fromString(self, inString):
- """
- Convert a string to a Python object. Subclasses must implement this.
-
- @param inString: the string to convert.
- @type inString: str
-
- @return: the decoded value from inString
- """
-
-
- def toString(self, inObject):
- """
- Convert a Python object into a string for passing over the network.
-
- @param inObject: an object of the type that this Argument is intended
- to deal with.
-
- @return: the wire encoding of inObject
- @rtype: str
- """
-
-
-
-class Integer(Argument):
- """
- Encode any integer values of any size on the wire as the string
- representation.
-
- Example: C{123} becomes C{"123"}
- """
- fromString = int
- def toString(self, inObject):
- return str(int(inObject))
-
-
-
-class String(Argument):
- """
- Don't do any conversion at all; just pass through 'str'.
- """
- def toString(self, inObject):
- return inObject
-
-
- def fromString(self, inString):
- return inString
-
-
-
-class Float(Argument):
- """
- Encode floating-point values on the wire as their repr.
- """
- fromString = float
- toString = repr
-
-
-
-class Boolean(Argument):
- """
- Encode True or False as "True" or "False" on the wire.
- """
- def fromString(self, inString):
- if inString == 'True':
- return True
- elif inString == 'False':
- return False
- else:
- raise TypeError("Bad boolean value: %r" % (inString,))
-
-
- def toString(self, inObject):
- if inObject:
- return 'True'
- else:
- return 'False'
-
-
-
-class Unicode(String):
- """
- Encode a unicode string on the wire as UTF-8.
- """
-
- def toString(self, inObject):
- # assert isinstance(inObject, unicode)
- return String.toString(self, inObject.encode('utf-8'))
-
-
- def fromString(self, inString):
- # assert isinstance(inString, str)
- return String.fromString(self, inString).decode('utf-8')
-
-
-
-class Path(Unicode):
- """
- Encode and decode L{filepath.FilePath} instances as paths on the wire.
-
- This is really intended for use with subprocess communication tools:
- exchanging pathnames on different machines over a network is not generally
- meaningful, but neither is it disallowed; you can use this to communicate
- about NFS paths, for example.
- """
- def fromString(self, inString):
- return filepath.FilePath(Unicode.fromString(self, inString))
-
-
- def toString(self, inObject):
- return Unicode.toString(self, inObject.path)
-
-
-
-class ListOf(Argument):
- """
- Encode and decode lists of instances of a single other argument type.
-
- For example, if you want to pass::
-
- [3, 7, 9, 15]
-
- You can create an argument like this::
-
- ListOf(Integer())
-
- The serialized form of the entire list is subject to the limit imposed by
- L{MAX_VALUE_LENGTH}. List elements are represented as 16-bit length
- prefixed strings. The argument type passed to the L{ListOf} initializer is
- responsible for producing the serialized form of each element.
-
- @ivar elementType: The L{Argument} instance used to encode and decode list
- elements (note, not an arbitrary L{IArgument} implementation:
- arguments must be implemented using only the C{fromString} and
- C{toString} methods, not the C{fromBox} and C{toBox} methods).
-
- @param optional: a boolean indicating whether this argument can be
- omitted in the protocol.
-
- @since: 10.0
- """
- def __init__(self, elementType, optional=False):
- self.elementType = elementType
- Argument.__init__(self, optional)
-
-
- def fromString(self, inString):
- """
- Convert the serialized form of a list of instances of some type back
- into that list.
- """
- strings = []
- parser = Int16StringReceiver()
- parser.stringReceived = strings.append
- parser.dataReceived(inString)
- return map(self.elementType.fromString, strings)
-
-
- def toString(self, inObject):
- """
- Serialize the given list of objects to a single string.
- """
- strings = []
- for obj in inObject:
- serialized = self.elementType.toString(obj)
- strings.append(pack('!H', len(serialized)))
- strings.append(serialized)
- return ''.join(strings)
-
-
-
-class AmpList(Argument):
- """
- Convert a list of dictionaries into a list of AMP boxes on the wire.
-
- For example, if you want to pass::
-
- [{'a': 7, 'b': u'hello'}, {'a': 9, 'b': u'goodbye'}]
-
- You might use an AmpList like this in your arguments or response list::
-
- AmpList([('a', Integer()),
- ('b', Unicode())])
- """
- def __init__(self, subargs, optional=False):
- """
- Create an AmpList.
-
- @param subargs: a list of 2-tuples of ('name', argument) describing the
- schema of the dictionaries in the sequence of amp boxes.
-
- @param optional: a boolean indicating whether this argument can be
- omitted in the protocol.
- """
- self.subargs = subargs
- Argument.__init__(self, optional)
-
-
- def fromStringProto(self, inString, proto):
- boxes = parseString(inString)
- values = [_stringsToObjects(box, self.subargs, proto)
- for box in boxes]
- return values
-
-
- def toStringProto(self, inObject, proto):
- return ''.join([_objectsToStrings(
- objects, self.subargs, Box(), proto
- ).serialize() for objects in inObject])
-
-
-
-class Descriptor(Integer):
- """
- Encode and decode file descriptors for exchange over a UNIX domain socket.
-
- This argument type requires an AMP connection set up over an
- L{IUNIXTransport<twisted.internet.interfaces.IUNIXTransport>} provider (for
- example, the kind of connection created by
- L{IReactorUNIX.connectUNIX<twisted.internet.interfaces.IReactorUNIX.connectUNIX>}
- and L{UNIXClientEndpoint<twisted.internet.endpoints.UNIXClientEndpoint>}).
-
- There is no correspondence between the integer value of the file descriptor
- on the sending and receiving sides, therefore an alternate approach is taken
- to matching up received descriptors with particular L{Descriptor}
- parameters. The argument is encoded to an ordinal (unique per connection)
- for inclusion in the AMP command or response box. The descriptor itself is
- sent using
- L{IUNIXTransport.sendFileDescriptor<twisted.internet.interfaces.IUNIXTransport.sendFileDescriptor>}.
- The receiver uses the order in which file descriptors are received and the
- ordinal value to come up with the received copy of the descriptor.
- """
- def fromStringProto(self, inString, proto):
- """
- Take a unique identifier associated with a file descriptor which must
- have been received by now and use it to look up that descriptor in a
- dictionary where they are kept.
-
- @param inString: The base representation (as a byte string) of an
- ordinal indicating which file descriptor corresponds to this usage
- of this argument.
- @type inString: C{str}
-
- @param proto: The protocol used to receive this descriptor. This
- protocol must be connected via a transport providing
- L{IUNIXTransport<twisted.internet.interfaces.IUNIXTransport>}.
- @type proto: L{BinaryBoxProtocol}
-
- @return: The file descriptor represented by C{inString}.
- @rtype: C{int}
- """
- return proto._getDescriptor(int(inString))
-
-
- def toStringProto(self, inObject, proto):
- """
- Send C{inObject}, an integer file descriptor, over C{proto}'s connection
- and return a unique identifier which will allow the receiver to
- associate the file descriptor with this argument.
-
- @param inObject: A file descriptor to duplicate over an AMP connection
- as the value for this argument.
- @type inObject: C{int}
-
- @param proto: The protocol which will be used to send this descriptor.
- This protocol must be connected via a transport providing
- L{IUNIXTransport<twisted.internet.interfaces.IUNIXTransport>}.
-
- @return: A byte string which can be used by the receiver to reconstruct
- the file descriptor.
- @type: C{str}
- """
- identifier = proto._sendFileDescriptor(inObject)
- outString = Integer.toStringProto(self, identifier, proto)
- return outString
-
-
-
-class Command:
- """
- Subclass me to specify an AMP Command.
-
- @cvar arguments: A list of 2-tuples of (name, Argument-subclass-instance),
- specifying the names and values of the parameters which are required for
- this command.
-
- @cvar response: A list like L{arguments}, but instead used for the return
- value.
-
- @cvar errors: A mapping of subclasses of L{Exception} to wire-protocol tags
- for errors represented as L{str}s. Responders which raise keys from this
- dictionary will have the error translated to the corresponding tag on the
- wire. Invokers which receive Deferreds from invoking this command with
- L{AMP.callRemote} will potentially receive Failures with keys from this
- mapping as their value. This mapping is inherited; if you declare a
- command which handles C{FooError} as 'FOO_ERROR', then subclass it and
- specify C{BarError} as 'BAR_ERROR', responders to the subclass may raise
- either C{FooError} or C{BarError}, and invokers must be able to deal with
- either of those exceptions.
-
- @cvar fatalErrors: like 'errors', but errors in this list will always
- terminate the connection, despite being of a recognizable error type.
-
- @cvar commandType: The type of Box used to issue commands; useful only for
- protocol-modifying behavior like startTLS or protocol switching. Defaults
- to a plain vanilla L{Box}.
-
- @cvar responseType: The type of Box used to respond to this command; only
- useful for protocol-modifying behavior like startTLS or protocol switching.
- Defaults to a plain vanilla L{Box}.
-
- @ivar requiresAnswer: a boolean; defaults to True. Set it to False on your
- subclass if you want callRemote to return None. Note: this is a hint only
- to the client side of the protocol. The return-type of a command responder
- method must always be a dictionary adhering to the contract specified by
- L{response}, because clients are always free to request a response if they
- want one.
- """
-
- class __metaclass__(type):
- """
- Metaclass hack to establish reverse-mappings for 'errors' and
- 'fatalErrors' as class vars.
- """
- def __new__(cls, name, bases, attrs):
- reverseErrors = attrs['reverseErrors'] = {}
- er = attrs['allErrors'] = {}
- if 'commandName' not in attrs:
- attrs['commandName'] = name
- newtype = type.__new__(cls, name, bases, attrs)
- errors = {}
- fatalErrors = {}
- accumulateClassDict(newtype, 'errors', errors)
- accumulateClassDict(newtype, 'fatalErrors', fatalErrors)
- for v, k in errors.iteritems():
- reverseErrors[k] = v
- er[v] = k
- for v, k in fatalErrors.iteritems():
- reverseErrors[k] = v
- er[v] = k
- return newtype
-
- arguments = []
- response = []
- extra = []
- errors = {}
- fatalErrors = {}
-
- commandType = Box
- responseType = Box
-
- requiresAnswer = True
-
-
- def __init__(self, **kw):
- """
- Create an instance of this command with specified values for its
- parameters.
-
- @param kw: a dict containing an appropriate value for each name
- specified in the L{arguments} attribute of my class.
-
- @raise InvalidSignature: if you forgot any required arguments.
- """
- self.structured = kw
- givenArgs = kw.keys()
- forgotten = []
- for name, arg in self.arguments:
- pythonName = _wireNameToPythonIdentifier(name)
- if pythonName not in givenArgs and not arg.optional:
- forgotten.append(pythonName)
- if forgotten:
- raise InvalidSignature("forgot %s for %s" % (
- ', '.join(forgotten), self.commandName))
- forgotten = []
-
-
- def makeResponse(cls, objects, proto):
- """
- Serialize a mapping of arguments using this L{Command}'s
- response schema.
-
- @param objects: a dict with keys matching the names specified in
- self.response, having values of the types that the Argument objects in
- self.response can format.
-
- @param proto: an L{AMP}.
-
- @return: an L{AmpBox}.
- """
- try:
- responseType = cls.responseType()
- except:
- return fail()
- return _objectsToStrings(objects, cls.response, responseType, proto)
- makeResponse = classmethod(makeResponse)
-
-
- def makeArguments(cls, objects, proto):
- """
- Serialize a mapping of arguments using this L{Command}'s
- argument schema.
-
- @param objects: a dict with keys similar to the names specified in
- self.arguments, having values of the types that the Argument objects in
- self.arguments can parse.
-
- @param proto: an L{AMP}.
-
- @return: An instance of this L{Command}'s C{commandType}.
- """
- allowedNames = set()
- for (argName, ignored) in cls.arguments:
- allowedNames.add(_wireNameToPythonIdentifier(argName))
-
- for intendedArg in objects:
- if intendedArg not in allowedNames:
- raise InvalidSignature(
- "%s is not a valid argument" % (intendedArg,))
- return _objectsToStrings(objects, cls.arguments, cls.commandType(),
- proto)
- makeArguments = classmethod(makeArguments)
-
-
- def parseResponse(cls, box, protocol):
- """
- Parse a mapping of serialized arguments using this
- L{Command}'s response schema.
-
- @param box: A mapping of response-argument names to the
- serialized forms of those arguments.
- @param protocol: The L{AMP} protocol.
-
- @return: A mapping of response-argument names to the parsed
- forms.
- """
- return _stringsToObjects(box, cls.response, protocol)
- parseResponse = classmethod(parseResponse)
-
-
- def parseArguments(cls, box, protocol):
- """
- Parse a mapping of serialized arguments using this
- L{Command}'s argument schema.
-
- @param box: A mapping of argument names to the seralized forms
- of those arguments.
- @param protocol: The L{AMP} protocol.
-
- @return: A mapping of argument names to the parsed forms.
- """
- return _stringsToObjects(box, cls.arguments, protocol)
- parseArguments = classmethod(parseArguments)
-
-
- def responder(cls, methodfunc):
- """
- Declare a method to be a responder for a particular command.
-
- This is a decorator.
-
- Use like so::
-
- class MyCommand(Command):
- arguments = [('a', ...), ('b', ...)]
-
- class MyProto(AMP):
- def myFunMethod(self, a, b):
- ...
- MyCommand.responder(myFunMethod)
-
- Notes: Although decorator syntax is not used within Twisted, this
- function returns its argument and is therefore safe to use with
- decorator syntax.
-
- This is not thread safe. Don't declare AMP subclasses in other
- threads. Don't declare responders outside the scope of AMP subclasses;
- the behavior is undefined.
-
- @param methodfunc: A function which will later become a method, which
- has a keyword signature compatible with this command's L{argument} list
- and returns a dictionary with a set of keys compatible with this
- command's L{response} list.
-
- @return: the methodfunc parameter.
- """
- CommandLocator._currentClassCommands.append((cls, methodfunc))
- return methodfunc
- responder = classmethod(responder)
-
-
- # Our only instance method
- def _doCommand(self, proto):
- """
- Encode and send this Command to the given protocol.
-
- @param proto: an AMP, representing the connection to send to.
-
- @return: a Deferred which will fire or error appropriately when the
- other side responds to the command (or error if the connection is lost
- before it is responded to).
- """
-
- def _massageError(error):
- error.trap(RemoteAmpError)
- rje = error.value
- errorType = self.reverseErrors.get(rje.errorCode,
- UnknownRemoteError)
- return Failure(errorType(rje.description))
-
- d = proto._sendBoxCommand(self.commandName,
- self.makeArguments(self.structured, proto),
- self.requiresAnswer)
-
- if self.requiresAnswer:
- d.addCallback(self.parseResponse, proto)
- d.addErrback(_massageError)
-
- return d
-
-
-
-class _NoCertificate:
- """
- This is for peers which don't want to use a local certificate. Used by
- AMP because AMP's internal language is all about certificates and this
- duck-types in the appropriate place; this API isn't really stable though,
- so it's not exposed anywhere public.
-
- For clients, it will use ephemeral DH keys, or whatever the default is for
- certificate-less clients in OpenSSL. For servers, it will generate a
- temporary self-signed certificate with garbage values in the DN and use
- that.
- """
-
- def __init__(self, client):
- """
- Create a _NoCertificate which either is or isn't for the client side of
- the connection.
-
- @param client: True if we are a client and should truly have no
- certificate and be anonymous, False if we are a server and actually
- have to generate a temporary certificate.
-
- @type client: bool
- """
- self.client = client
-
-
- def options(self, *authorities):
- """
- Behaves like L{twisted.internet.ssl.PrivateCertificate.options}().
- """
- if not self.client:
- # do some crud with sslverify to generate a temporary self-signed
- # certificate. This is SLOOOWWWWW so it is only in the absolute
- # worst, most naive case.
-
- # We have to do this because OpenSSL will not let both the server
- # and client be anonymous.
- sharedDN = DN(CN='TEMPORARY CERTIFICATE')
- key = KeyPair.generate()
- cr = key.certificateRequest(sharedDN)
- sscrd = key.signCertificateRequest(sharedDN, cr, lambda dn: True, 1)
- cert = key.newCertificate(sscrd)
- return cert.options(*authorities)
- options = dict()
- if authorities:
- options.update(dict(verify=True,
- requireCertificate=True,
- caCerts=[auth.original for auth in authorities]))
- occo = CertificateOptions(**options)
- return occo
-
-
-
-class _TLSBox(AmpBox):
- """
- I am an AmpBox that, upon being sent, initiates a TLS connection.
- """
- __slots__ = []
-
- def __init__(self):
- if ssl is None:
- raise RemoteAmpError("TLS_ERROR", "TLS not available")
- AmpBox.__init__(self)
-
-
- def _keyprop(k, default):
- return property(lambda self: self.get(k, default))
-
-
- # These properties are described in startTLS
- certificate = _keyprop('tls_localCertificate', _NoCertificate(False))
- verify = _keyprop('tls_verifyAuthorities', None)
-
- def _sendTo(self, proto):
- """
- Send my encoded value to the protocol, then initiate TLS.
- """
- ab = AmpBox(self)
- for k in ['tls_localCertificate',
- 'tls_verifyAuthorities']:
- ab.pop(k, None)
- ab._sendTo(proto)
- proto._startTLS(self.certificate, self.verify)
-
-
-
-class _LocalArgument(String):
- """
- Local arguments are never actually relayed across the wire. This is just a
- shim so that StartTLS can pretend to have some arguments: if arguments
- acquire documentation properties, replace this with something nicer later.
- """
-
- def fromBox(self, name, strings, objects, proto):
- pass
-
-
-
-class StartTLS(Command):
- """
- Use, or subclass, me to implement a command that starts TLS.
-
- Callers of StartTLS may pass several special arguments, which affect the
- TLS negotiation:
-
- - tls_localCertificate: This is a
- twisted.internet.ssl.PrivateCertificate which will be used to secure
- the side of the connection it is returned on.
-
- - tls_verifyAuthorities: This is a list of
- twisted.internet.ssl.Certificate objects that will be used as the
- certificate authorities to verify our peer's certificate.
-
- Each of those special parameters may also be present as a key in the
- response dictionary.
- """
-
- arguments = [("tls_localCertificate", _LocalArgument(optional=True)),
- ("tls_verifyAuthorities", _LocalArgument(optional=True))]
-
- response = [("tls_localCertificate", _LocalArgument(optional=True)),
- ("tls_verifyAuthorities", _LocalArgument(optional=True))]
-
- responseType = _TLSBox
-
- def __init__(self, **kw):
- """
- Create a StartTLS command. (This is private. Use AMP.callRemote.)
-
- @param tls_localCertificate: the PrivateCertificate object to use to
- secure the connection. If it's None, or unspecified, an ephemeral DH
- key is used instead.
-
- @param tls_verifyAuthorities: a list of Certificate objects which
- represent root certificates to verify our peer with.
- """
- if ssl is None:
- raise RuntimeError("TLS not available.")
- self.certificate = kw.pop('tls_localCertificate', _NoCertificate(True))
- self.authorities = kw.pop('tls_verifyAuthorities', None)
- Command.__init__(self, **kw)
-
-
- def _doCommand(self, proto):
- """
- When a StartTLS command is sent, prepare to start TLS, but don't actually
- do it; wait for the acknowledgement, then initiate the TLS handshake.
- """
- d = Command._doCommand(self, proto)
- proto._prepareTLS(self.certificate, self.authorities)
- # XXX before we get back to user code we are going to start TLS...
- def actuallystart(response):
- proto._startTLS(self.certificate, self.authorities)
- return response
- d.addCallback(actuallystart)
- return d
-
-
-
-class ProtocolSwitchCommand(Command):
- """
- Use this command to switch from something Amp-derived to a different
- protocol mid-connection. This can be useful to use amp as the
- connection-startup negotiation phase. Since TLS is a different layer
- entirely, you can use Amp to negotiate the security parameters of your
- connection, then switch to a different protocol, and the connection will
- remain secured.
- """
-
- def __init__(self, _protoToSwitchToFactory, **kw):
- """
- Create a ProtocolSwitchCommand.
-
- @param _protoToSwitchToFactory: a ProtocolFactory which will generate
- the Protocol to switch to.
-
- @param kw: Keyword arguments, encoded and handled normally as
- L{Command} would.
- """
-
- self.protoToSwitchToFactory = _protoToSwitchToFactory
- super(ProtocolSwitchCommand, self).__init__(**kw)
-
-
- def makeResponse(cls, innerProto, proto):
- return _SwitchBox(innerProto)
- makeResponse = classmethod(makeResponse)
-
-
- def _doCommand(self, proto):
- """
- When we emit a ProtocolSwitchCommand, lock the protocol, but don't actually
- switch to the new protocol unless an acknowledgement is received. If
- an error is received, switch back.
- """
- d = super(ProtocolSwitchCommand, self)._doCommand(proto)
- proto._lockForSwitch()
- def switchNow(ign):
- innerProto = self.protoToSwitchToFactory.buildProtocol(
- proto.transport.getPeer())
- proto._switchTo(innerProto, self.protoToSwitchToFactory)
- return ign
- def handle(ign):
- proto._unlockFromSwitch()
- self.protoToSwitchToFactory.clientConnectionFailed(
- None, Failure(CONNECTION_LOST))
- return ign
- return d.addCallbacks(switchNow, handle)
-
-
-
-class _DescriptorExchanger(object):
- """
- L{_DescriptorExchanger} is a mixin for L{BinaryBoxProtocol} which adds
- support for receiving file descriptors, a feature offered by
- L{IUNIXTransport<twisted.internet.interfaces.IUNIXTransport>}.
-
- @ivar _descriptors: Temporary storage for all file descriptors received.
- Values in this dictionary are the file descriptors (as integers). Keys
- in this dictionary are ordinals giving the order in which each
- descriptor was received. The ordering information is used to allow
- L{Descriptor} to determine which is the correct descriptor for any
- particular usage of that argument type.
- @type _descriptors: C{dict}
-
- @ivar _sendingDescriptorCounter: A no-argument callable which returns the
- ordinals, starting from 0. This is used to construct values for
- C{_sendFileDescriptor}.
-
- @ivar _receivingDescriptorCounter: A no-argument callable which returns the
- ordinals, starting from 0. This is used to construct values for
- C{fileDescriptorReceived}.
- """
- implements(IFileDescriptorReceiver)
-
- def __init__(self):
- self._descriptors = {}
- self._getDescriptor = self._descriptors.pop
- self._sendingDescriptorCounter = count().next
- self._receivingDescriptorCounter = count().next
-
-
- def _sendFileDescriptor(self, descriptor):
- """
- Assign and return the next ordinal to the given descriptor after sending
- the descriptor over this protocol's transport.
- """
- self.transport.sendFileDescriptor(descriptor)
- return self._sendingDescriptorCounter()
-
-
- def fileDescriptorReceived(self, descriptor):
- """
- Collect received file descriptors to be claimed later by L{Descriptor}.
-
- @param descriptor: The received file descriptor.
- @type descriptor: C{int}
- """
- self._descriptors[self._receivingDescriptorCounter()] = descriptor
-
-
-
-class BinaryBoxProtocol(StatefulStringProtocol, Int16StringReceiver,
- _DescriptorExchanger):
- """
- A protocol for receiving L{AmpBox}es - key/value pairs - via length-prefixed
- strings. A box is composed of:
-
- - any number of key-value pairs, described by:
- - a 2-byte network-endian packed key length (of which the first
- byte must be null, and the second must be non-null: i.e. the
- value of the length must be 1-255)
- - a key, comprised of that many bytes
- - a 2-byte network-endian unsigned value length (up to the maximum
- of 65535)
- - a value, comprised of that many bytes
- - 2 null bytes
-
- In other words, an even number of strings prefixed with packed unsigned
- 16-bit integers, and then a 0-length string to indicate the end of the box.
-
- This protocol also implements 2 extra private bits of functionality related
- to the byte boundaries between messages; it can start TLS between two given
- boxes or switch to an entirely different protocol. However, due to some
- tricky elements of the implementation, the public interface to this
- functionality is L{ProtocolSwitchCommand} and L{StartTLS}.
-
- @ivar _keyLengthLimitExceeded: A flag which is only true when the
- connection is being closed because a key length prefix which was longer
- than allowed by the protocol was received.
-
- @ivar boxReceiver: an L{IBoxReceiver} provider, whose L{ampBoxReceived}
- method will be invoked for each L{AmpBox} that is received.
- """
-
- implements(IBoxSender)
-
- _justStartedTLS = False
- _startingTLSBuffer = None
- _locked = False
- _currentKey = None
- _currentBox = None
-
- _keyLengthLimitExceeded = False
-
- hostCertificate = None
- noPeerCertificate = False # for tests
- innerProtocol = None
- innerProtocolClientFactory = None
-
- def __init__(self, boxReceiver):
- _DescriptorExchanger.__init__(self)
- self.boxReceiver = boxReceiver
-
-
- def _switchTo(self, newProto, clientFactory=None):
- """
- Switch this BinaryBoxProtocol's transport to a new protocol. You need
- to do this 'simultaneously' on both ends of a connection; the easiest
- way to do this is to use a subclass of ProtocolSwitchCommand.
-
- @param newProto: the new protocol instance to switch to.
-
- @param clientFactory: the ClientFactory to send the
- L{clientConnectionLost} notification to.
- """
- # All the data that Int16Receiver has not yet dealt with belongs to our
- # new protocol: luckily it's keeping that in a handy (although
- # ostensibly internal) variable for us:
- newProtoData = self.recvd
- # We're quite possibly in the middle of a 'dataReceived' loop in
- # Int16StringReceiver: let's make sure that the next iteration, the
- # loop will break and not attempt to look at something that isn't a
- # length prefix.
- self.recvd = ''
- # Finally, do the actual work of setting up the protocol and delivering
- # its first chunk of data, if one is available.
- self.innerProtocol = newProto
- self.innerProtocolClientFactory = clientFactory
- newProto.makeConnection(self.transport)
- if newProtoData:
- newProto.dataReceived(newProtoData)
-
-
- def sendBox(self, box):
- """
- Send a amp.Box to my peer.
-
- Note: transport.write is never called outside of this method.
-
- @param box: an AmpBox.
-
- @raise ProtocolSwitched: if the protocol has previously been switched.
-
- @raise ConnectionLost: if the connection has previously been lost.
- """
- if self._locked:
- raise ProtocolSwitched(
- "This connection has switched: no AMP traffic allowed.")
- if self.transport is None:
- raise ConnectionLost()
- if self._startingTLSBuffer is not None:
- self._startingTLSBuffer.append(box)
- else:
- self.transport.write(box.serialize())
-
-
- def makeConnection(self, transport):
- """
- Notify L{boxReceiver} that it is about to receive boxes from this
- protocol by invoking L{startReceivingBoxes}.
- """
- self.transport = transport
- self.boxReceiver.startReceivingBoxes(self)
- self.connectionMade()
-
-
- def dataReceived(self, data):
- """
- Either parse incoming data as L{AmpBox}es or relay it to our nested
- protocol.
- """
- if self._justStartedTLS:
- self._justStartedTLS = False
- # If we already have an inner protocol, then we don't deliver data to
- # the protocol parser any more; we just hand it off.
- if self.innerProtocol is not None:
- self.innerProtocol.dataReceived(data)
- return
- return Int16StringReceiver.dataReceived(self, data)
-
-
- def connectionLost(self, reason):
- """
- The connection was lost; notify any nested protocol.
- """
- if self.innerProtocol is not None:
- self.innerProtocol.connectionLost(reason)
- if self.innerProtocolClientFactory is not None:
- self.innerProtocolClientFactory.clientConnectionLost(None, reason)
- if self._keyLengthLimitExceeded:
- failReason = Failure(TooLong(True, False, None, None))
- elif reason.check(ConnectionClosed) and self._justStartedTLS:
- # We just started TLS and haven't received any data. This means
- # the other connection didn't like our cert (although they may not
- # have told us why - later Twisted should make 'reason' into a TLS
- # error.)
- failReason = PeerVerifyError(
- "Peer rejected our certificate for an unknown reason.")
- else:
- failReason = reason
- self.boxReceiver.stopReceivingBoxes(failReason)
-
-
- # The longest key allowed
- _MAX_KEY_LENGTH = 255
-
- # The longest value allowed (this is somewhat redundant, as longer values
- # cannot be encoded - ah well).
- _MAX_VALUE_LENGTH = 65535
-
- # The first thing received is a key.
- MAX_LENGTH = _MAX_KEY_LENGTH
-
- def proto_init(self, string):
- """
- String received in the 'init' state.
- """
- self._currentBox = AmpBox()
- return self.proto_key(string)
-
-
- def proto_key(self, string):
- """
- String received in the 'key' state. If the key is empty, a complete
- box has been received.
- """
- if string:
- self._currentKey = string
- self.MAX_LENGTH = self._MAX_VALUE_LENGTH
- return 'value'
- else:
- self.boxReceiver.ampBoxReceived(self._currentBox)
- self._currentBox = None
- return 'init'
-
-
- def proto_value(self, string):
- """
- String received in the 'value' state.
- """
- self._currentBox[self._currentKey] = string
- self._currentKey = None
- self.MAX_LENGTH = self._MAX_KEY_LENGTH
- return 'key'
-
-
- def lengthLimitExceeded(self, length):
- """
- The key length limit was exceeded. Disconnect the transport and make
- sure a meaningful exception is reported.
- """
- self._keyLengthLimitExceeded = True
- self.transport.loseConnection()
-
-
- def _lockForSwitch(self):
- """
- Lock this binary protocol so that no further boxes may be sent. This
- is used when sending a request to switch underlying protocols. You
- probably want to subclass ProtocolSwitchCommand rather than calling
- this directly.
- """
- self._locked = True
-
-
- def _unlockFromSwitch(self):
- """
- Unlock this locked binary protocol so that further boxes may be sent
- again. This is used after an attempt to switch protocols has failed
- for some reason.
- """
- if self.innerProtocol is not None:
- raise ProtocolSwitched("Protocol already switched. Cannot unlock.")
- self._locked = False
-
-
- def _prepareTLS(self, certificate, verifyAuthorities):
- """
- Used by StartTLSCommand to put us into the state where we don't
- actually send things that get sent, instead we buffer them. see
- L{_sendBox}.
- """
- self._startingTLSBuffer = []
- if self.hostCertificate is not None:
- raise OnlyOneTLS(
- "Previously authenticated connection between %s and %s "
- "is trying to re-establish as %s" % (
- self.hostCertificate,
- self.peerCertificate,
- (certificate, verifyAuthorities)))
-
-
- def _startTLS(self, certificate, verifyAuthorities):
- """
- Used by TLSBox to initiate the SSL handshake.
-
- @param certificate: a L{twisted.internet.ssl.PrivateCertificate} for
- use locally.
-
- @param verifyAuthorities: L{twisted.internet.ssl.Certificate} instances
- representing certificate authorities which will verify our peer.
- """
- self.hostCertificate = certificate
- self._justStartedTLS = True
- if verifyAuthorities is None:
- verifyAuthorities = ()
- self.transport.startTLS(certificate.options(*verifyAuthorities))
- stlsb = self._startingTLSBuffer
- if stlsb is not None:
- self._startingTLSBuffer = None
- for box in stlsb:
- self.sendBox(box)
-
-
- def _getPeerCertificate(self):
- if self.noPeerCertificate:
- return None
- return Certificate.peerFromTransport(self.transport)
- peerCertificate = property(_getPeerCertificate)
-
-
- def unhandledError(self, failure):
- """
- The buck stops here. This error was completely unhandled, time to
- terminate the connection.
- """
- log.err(
- failure,
- "Amp server or network failure unhandled by client application. "
- "Dropping connection! To avoid, add errbacks to ALL remote "
- "commands!")
- if self.transport is not None:
- self.transport.loseConnection()
-
-
- def _defaultStartTLSResponder(self):
- """
- The default TLS responder doesn't specify any certificate or anything.
-
- From a security perspective, it's little better than a plain-text
- connection - but it is still a *bit* better, so it's included for
- convenience.
-
- You probably want to override this by providing your own StartTLS.responder.
- """
- return {}
- StartTLS.responder(_defaultStartTLSResponder)
-
-
-
-class AMP(BinaryBoxProtocol, BoxDispatcher,
- CommandLocator, SimpleStringLocator):
- """
- This protocol is an AMP connection. See the module docstring for protocol
- details.
- """
-
- _ampInitialized = False
-
- def __init__(self, boxReceiver=None, locator=None):
- # For backwards compatibility. When AMP did not separate parsing logic
- # (L{BinaryBoxProtocol}), request-response logic (L{BoxDispatcher}) and
- # command routing (L{CommandLocator}), it did not have a constructor.
- # Now it does, so old subclasses might have defined their own that did
- # not upcall. If this flag isn't set, we'll call the constructor in
- # makeConnection before anything actually happens.
- self._ampInitialized = True
- if boxReceiver is None:
- boxReceiver = self
- if locator is None:
- locator = self
- BoxDispatcher.__init__(self, locator)
- BinaryBoxProtocol.__init__(self, boxReceiver)
-
-
- def locateResponder(self, name):
- """
- Unify the implementations of L{CommandLocator} and
- L{SimpleStringLocator} to perform both kinds of dispatch, preferring
- L{CommandLocator}.
- """
- firstResponder = CommandLocator.locateResponder(self, name)
- if firstResponder is not None:
- return firstResponder
- secondResponder = SimpleStringLocator.locateResponder(self, name)
- return secondResponder
-
-
- def __repr__(self):
- """
- A verbose string representation which gives us information about this
- AMP connection.
- """
- if self.innerProtocol is not None:
- innerRepr = ' inner %r' % (self.innerProtocol,)
- else:
- innerRepr = ''
- return '<%s%s at 0x%x>' % (
- self.__class__.__name__, innerRepr, unsignedID(self))
-
-
- def makeConnection(self, transport):
- """
- Emit a helpful log message when the connection is made.
- """
- if not self._ampInitialized:
- # See comment in the constructor re: backward compatibility. I
- # should probably emit a deprecation warning here.
- AMP.__init__(self)
- # Save these so we can emit a similar log message in L{connectionLost}.
- self._transportPeer = transport.getPeer()
- self._transportHost = transport.getHost()
- log.msg("%s connection established (HOST:%s PEER:%s)" % (
- self.__class__.__name__,
- self._transportHost,
- self._transportPeer))
- BinaryBoxProtocol.makeConnection(self, transport)
-
-
- def connectionLost(self, reason):
- """
- Emit a helpful log message when the connection is lost.
- """
- log.msg("%s connection lost (HOST:%s PEER:%s)" %
- (self.__class__.__name__,
- self._transportHost,
- self._transportPeer))
- BinaryBoxProtocol.connectionLost(self, reason)
- self.transport = None
-
-
-
-class _ParserHelper:
- """
- A box receiver which records all boxes received.
- """
- def __init__(self):
- self.boxes = []
-
-
- def getPeer(self):
- return 'string'
-
-
- def getHost(self):
- return 'string'
-
- disconnecting = False
-
-
- def startReceivingBoxes(self, sender):
- """
- No initialization is required.
- """
-
-
- def ampBoxReceived(self, box):
- self.boxes.append(box)
-
-
- # Synchronous helpers
- def parse(cls, fileObj):
- """
- Parse some amp data stored in a file.
-
- @param fileObj: a file-like object.
-
- @return: a list of AmpBoxes encoded in the given file.
- """
- parserHelper = cls()
- bbp = BinaryBoxProtocol(boxReceiver=parserHelper)
- bbp.makeConnection(parserHelper)
- bbp.dataReceived(fileObj.read())
- return parserHelper.boxes
- parse = classmethod(parse)
-
-
- def parseString(cls, data):
- """
- Parse some amp data stored in a string.
-
- @param data: a str holding some amp-encoded data.
-
- @return: a list of AmpBoxes encoded in the given string.
- """
- return cls.parse(StringIO(data))
- parseString = classmethod(parseString)
-
-
-
-parse = _ParserHelper.parse
-parseString = _ParserHelper.parseString
-
-def _stringsToObjects(strings, arglist, proto):
- """
- Convert an AmpBox to a dictionary of python objects, converting through a
- given arglist.
-
- @param strings: an AmpBox (or dict of strings)
-
- @param arglist: a list of 2-tuples of strings and Argument objects, as
- described in L{Command.arguments}.
-
- @param proto: an L{AMP} instance.
-
- @return: the converted dictionary mapping names to argument objects.
- """
- objects = {}
- myStrings = strings.copy()
- for argname, argparser in arglist:
- argparser.fromBox(argname, myStrings, objects, proto)
- return objects
-
-
-
-def _objectsToStrings(objects, arglist, strings, proto):
- """
- Convert a dictionary of python objects to an AmpBox, converting through a
- given arglist.
-
- @param objects: a dict mapping names to python objects
-
- @param arglist: a list of 2-tuples of strings and Argument objects, as
- described in L{Command.arguments}.
-
- @param strings: [OUT PARAMETER] An object providing the L{dict}
- interface which will be populated with serialized data.
-
- @param proto: an L{AMP} instance.
-
- @return: The converted dictionary mapping names to encoded argument
- strings (identical to C{strings}).
- """
- myObjects = objects.copy()
- for argname, argparser in arglist:
- argparser.toBox(argname, strings, myObjects, proto)
- return strings
-
-
-
-class _FixedOffsetTZInfo(datetime.tzinfo):
- """
- Represents a fixed timezone offset (without daylight saving time).
-
- @ivar name: A C{str} giving the name of this timezone; the name just
- includes how much time this offset represents.
-
- @ivar offset: A C{datetime.timedelta} giving the amount of time this
- timezone is offset.
- """
-
- def __init__(self, sign, hours, minutes):
- self.name = '%s%02i:%02i' % (sign, hours, minutes)
- if sign == '-':
- hours = -hours
- minutes = -minutes
- elif sign != '+':
- raise ValueError('invalid sign for timezone %r' % (sign,))
- self.offset = datetime.timedelta(hours=hours, minutes=minutes)
-
-
- def utcoffset(self, dt):
- """
- Return this timezone's offset from UTC.
- """
- return self.offset
-
-
- def dst(self, dt):
- """
- Return a zero C{datetime.timedelta} for the daylight saving time offset,
- since there is never one.
- """
- return datetime.timedelta(0)
-
-
- def tzname(self, dt):
- """
- Return a string describing this timezone.
- """
- return self.name
-
-
-
-utc = _FixedOffsetTZInfo('+', 0, 0)
-
-
-
-class Decimal(Argument):
- """
- Encodes C{decimal.Decimal} instances.
-
- There are several ways in which a decimal value might be encoded.
-
- Special values are encoded as special strings::
-
- - Positive infinity is encoded as C{"Infinity"}
- - Negative infinity is encoded as C{"-Infinity"}
- - Quiet not-a-number is encoded as either C{"NaN"} or C{"-NaN"}
- - Signalling not-a-number is encoded as either C{"sNaN"} or C{"-sNaN"}
-
- Normal values are encoded using the base ten string representation, using
- engineering notation to indicate magnitude without precision, and "normal"
- digits to indicate precision. For example::
-
- - C{"1"} represents the value I{1} with precision to one place.
- - C{"-1"} represents the value I{-1} with precision to one place.
- - C{"1.0"} represents the value I{1} with precision to two places.
- - C{"10"} represents the value I{10} with precision to two places.
- - C{"1E+2"} represents the value I{10} with precision to one place.
- - C{"1E-1"} represents the value I{0.1} with precision to one place.
- - C{"1.5E+2"} represents the value I{15} with precision to two places.
-
- U{http://speleotrove.com/decimal/} should be considered the authoritative
- specification for the format.
- """
- fromString = decimal.Decimal
-
- def toString(self, inObject):
- """
- Serialize a C{decimal.Decimal} instance to the specified wire format.
- """
- if isinstance(inObject, decimal.Decimal):
- # Hopefully decimal.Decimal.__str__ actually does what we want.
- return str(inObject)
- raise ValueError(
- "amp.Decimal can only encode instances of decimal.Decimal")
-
-
-
-class DateTime(Argument):
- """
- Encodes C{datetime.datetime} instances.
-
- Wire format: '%04i-%02i-%02iT%02i:%02i:%02i.%06i%s%02i:%02i'. Fields in
- order are: year, month, day, hour, minute, second, microsecond, timezone
- direction (+ or -), timezone hour, timezone minute. Encoded string is
- always exactly 32 characters long. This format is compatible with ISO 8601,
- but that does not mean all ISO 8601 dates can be accepted.
-
- Also, note that the datetime module's notion of a "timezone" can be
- complex, but the wire format includes only a fixed offset, so the
- conversion is not lossless. A lossless transmission of a C{datetime} instance
- is not feasible since the receiving end would require a Python interpreter.
-
- @ivar _positions: A sequence of slices giving the positions of various
- interesting parts of the wire format.
- """
-
- _positions = [
- slice(0, 4), slice(5, 7), slice(8, 10), # year, month, day
- slice(11, 13), slice(14, 16), slice(17, 19), # hour, minute, second
- slice(20, 26), # microsecond
- # intentionally skip timezone direction, as it is not an integer
- slice(27, 29), slice(30, 32) # timezone hour, timezone minute
- ]
-
- def fromString(self, s):
- """
- Parse a string containing a date and time in the wire format into a
- C{datetime.datetime} instance.
- """
- if len(s) != 32:
- raise ValueError('invalid date format %r' % (s,))
-
- values = [int(s[p]) for p in self._positions]
- sign = s[26]
- timezone = _FixedOffsetTZInfo(sign, *values[7:])
- values[7:] = [timezone]
- return datetime.datetime(*values)
-
-
- def toString(self, i):
- """
- Serialize a C{datetime.datetime} instance to a string in the specified
- wire format.
- """
- offset = i.utcoffset()
- if offset is None:
- raise ValueError(
- 'amp.DateTime cannot serialize naive datetime instances. '
- 'You may find amp.utc useful.')
-
- minutesOffset = (offset.days * 86400 + offset.seconds) // 60
-
- if minutesOffset > 0:
- sign = '+'
- else:
- sign = '-'
-
- # strftime has no way to format the microseconds, or put a ':' in the
- # timezone. Suprise!
-
- return '%04i-%02i-%02iT%02i:%02i:%02i.%06i%s%02i:%02i' % (
- i.year,
- i.month,
- i.day,
- i.hour,
- i.minute,
- i.second,
- i.microsecond,
- sign,
- abs(minutesOffset) // 60,
- abs(minutesOffset) % 60)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/basic.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/basic.py
deleted file mode 100755
index 7c4c9403..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/basic.py
+++ /dev/null
@@ -1,939 +0,0 @@
-# -*- test-case-name: twisted.test.test_protocols -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Basic protocols, such as line-oriented, netstring, and int prefixed strings.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-# System imports
-import re
-from struct import pack, unpack, calcsize
-import warnings
-import cStringIO
-import math
-
-from zope.interface import implements
-
-# Twisted imports
-from twisted.internet import protocol, defer, interfaces, error
-from twisted.python import log, deprecate, versions
-
-
-LENGTH, DATA, COMMA = range(3)
-NUMBER = re.compile('(\d*)(:?)')
-
-deprecatedSince = versions.Version("Twisted", 10, 2, 0)
-message = "NetstringReceiver parser state is private."
-for attr in ["LENGTH", "DATA", "COMMA", "NUMBER"]:
- deprecate.deprecatedModuleAttribute(
- deprecatedSince, message, __name__, attr)
-del deprecatedSince, message, attr
-
-DEBUG = 0
-
-class NetstringParseError(ValueError):
- """
- The incoming data is not in valid Netstring format.
- """
-
-
-
-class IncompleteNetstring(Exception):
- """
- Not enough data to complete a netstring.
- """
-
-
-
-class NetstringReceiver(protocol.Protocol):
- """
- A protocol that sends and receives netstrings.
-
- See U{http://cr.yp.to/proto/netstrings.txt} for the specification of
- netstrings. Every netstring starts with digits that specify the length
- of the data. This length specification is separated from the data by
- a colon. The data is terminated with a comma.
-
- Override L{stringReceived} to handle received netstrings. This
- method is called with the netstring payload as a single argument
- whenever a complete netstring is received.
-
- Security features:
- 1. Messages are limited in size, useful if you don't want
- someone sending you a 500MB netstring (change C{self.MAX_LENGTH}
- to the maximum length you wish to accept).
- 2. The connection is lost if an illegal message is received.
-
- @ivar MAX_LENGTH: Defines the maximum length of netstrings that can be
- received.
- @type MAX_LENGTH: C{int}
-
- @ivar _LENGTH: A pattern describing all strings that contain a netstring
- length specification. Examples for length specifications are '0:',
- '12:', and '179:'. '007:' is no valid length specification, since
- leading zeros are not allowed.
- @type _LENGTH: C{re.Match}
-
- @ivar _LENGTH_PREFIX: A pattern describing all strings that contain
- the first part of a netstring length specification (without the
- trailing comma). Examples are '0', '12', and '179'. '007' does not
- start a netstring length specification, since leading zeros are
- not allowed.
- @type _LENGTH_PREFIX: C{re.Match}
-
- @ivar _PARSING_LENGTH: Indicates that the C{NetstringReceiver} is in
- the state of parsing the length portion of a netstring.
- @type _PARSING_LENGTH: C{int}
-
- @ivar _PARSING_PAYLOAD: Indicates that the C{NetstringReceiver} is in
- the state of parsing the payload portion (data and trailing comma)
- of a netstring.
- @type _PARSING_PAYLOAD: C{int}
-
- @ivar brokenPeer: Indicates if the connection is still functional
- @type brokenPeer: C{int}
-
- @ivar _state: Indicates if the protocol is consuming the length portion
- (C{PARSING_LENGTH}) or the payload (C{PARSING_PAYLOAD}) of a netstring
- @type _state: C{int}
-
- @ivar _remainingData: Holds the chunk of data that has not yet been consumed
- @type _remainingData: C{string}
-
- @ivar _payload: Holds the payload portion of a netstring including the
- trailing comma
- @type _payload: C{cStringIO.StringIO}
-
- @ivar _expectedPayloadSize: Holds the payload size plus one for the trailing
- comma.
- @type _expectedPayloadSize: C{int}
- """
- MAX_LENGTH = 99999
- _LENGTH = re.compile('(0|[1-9]\d*)(:)')
-
- _LENGTH_PREFIX = re.compile('(0|[1-9]\d*)$')
-
- # Some error information for NetstringParseError instances.
- _MISSING_LENGTH = ("The received netstring does not start with a "
- "length specification.")
- _OVERFLOW = ("The length specification of the received netstring "
- "cannot be represented in Python - it causes an "
- "OverflowError!")
- _TOO_LONG = ("The received netstring is longer than the maximum %s "
- "specified by self.MAX_LENGTH")
- _MISSING_COMMA = "The received netstring is not terminated by a comma."
- _DATA_SUPPORT_DEPRECATED = ("Data passed to sendString() must be a string. "
- "Non-string support is deprecated since "
- "Twisted 10.0")
-
- # The following constants are used for determining if the NetstringReceiver
- # is parsing the length portion of a netstring, or the payload.
- _PARSING_LENGTH, _PARSING_PAYLOAD = range(2)
-
- def makeConnection(self, transport):
- """
- Initializes the protocol.
- """
- protocol.Protocol.makeConnection(self, transport)
- self._remainingData = ""
- self._currentPayloadSize = 0
- self._payload = cStringIO.StringIO()
- self._state = self._PARSING_LENGTH
- self._expectedPayloadSize = 0
- self.brokenPeer = 0
-
-
- def sendString(self, string):
- """
- Sends a netstring.
-
- Wraps up C{string} by adding length information and a
- trailing comma; writes the result to the transport.
-
- @param string: The string to send. The necessary framing (length
- prefix, etc) will be added.
- @type string: C{str}
- """
- if not isinstance(string, str):
- warnings.warn(self._DATA_SUPPORT_DEPRECATED, DeprecationWarning, 2)
- string = str(string)
- self.transport.write('%d:%s,' % (len(string), string))
-
-
- def dataReceived(self, data):
- """
- Receives some characters of a netstring.
-
- Whenever a complete netstring is received, this method extracts
- its payload and calls L{stringReceived} to process it.
-
- @param data: A chunk of data representing a (possibly partial)
- netstring
- @type data: C{str}
- """
- self._remainingData += data
- while self._remainingData:
- try:
- self._consumeData()
- except IncompleteNetstring:
- break
- except NetstringParseError:
- self._handleParseError()
- break
-
-
- def stringReceived(self, string):
- """
- Override this for notification when each complete string is received.
-
- @param string: The complete string which was received with all
- framing (length prefix, etc) removed.
- @type string: C{str}
-
- @raise NotImplementedError: because the method has to be implemented
- by the child class.
- """
- raise NotImplementedError()
-
-
- def _maxLengthSize(self):
- """
- Calculate and return the string size of C{self.MAX_LENGTH}.
-
- @return: The size of the string representation for C{self.MAX_LENGTH}
- @rtype: C{float}
- """
- return math.ceil(math.log10(self.MAX_LENGTH)) + 1
-
-
- def _consumeData(self):
- """
- Consumes the content of C{self._remainingData}.
-
- @raise IncompleteNetstring: if C{self._remainingData} does not
- contain enough data to complete the current netstring.
- @raise NetstringParseError: if the received data do not
- form a valid netstring.
- """
- if self._state == self._PARSING_LENGTH:
- self._consumeLength()
- self._prepareForPayloadConsumption()
- if self._state == self._PARSING_PAYLOAD:
- self._consumePayload()
-
-
- def _consumeLength(self):
- """
- Consumes the length portion of C{self._remainingData}.
-
- @raise IncompleteNetstring: if C{self._remainingData} contains
- a partial length specification (digits without trailing
- comma).
- @raise NetstringParseError: if the received data do not form a valid
- netstring.
- """
- lengthMatch = self._LENGTH.match(self._remainingData)
- if not lengthMatch:
- self._checkPartialLengthSpecification()
- raise IncompleteNetstring()
- self._processLength(lengthMatch)
-
-
- def _checkPartialLengthSpecification(self):
- """
- Makes sure that the received data represents a valid number.
-
- Checks if C{self._remainingData} represents a number smaller or
- equal to C{self.MAX_LENGTH}.
-
- @raise NetstringParseError: if C{self._remainingData} is no
- number or is too big (checked by L{extractLength}).
- """
- partialLengthMatch = self._LENGTH_PREFIX.match(self._remainingData)
- if not partialLengthMatch:
- raise NetstringParseError(self._MISSING_LENGTH)
- lengthSpecification = (partialLengthMatch.group(1))
- self._extractLength(lengthSpecification)
-
-
- def _processLength(self, lengthMatch):
- """
- Processes the length definition of a netstring.
-
- Extracts and stores in C{self._expectedPayloadSize} the number
- representing the netstring size. Removes the prefix
- representing the length specification from
- C{self._remainingData}.
-
- @raise NetstringParseError: if the received netstring does not
- start with a number or the number is bigger than
- C{self.MAX_LENGTH}.
- @param lengthMatch: A regular expression match object matching
- a netstring length specification
- @type lengthMatch: C{re.Match}
- """
- endOfNumber = lengthMatch.end(1)
- startOfData = lengthMatch.end(2)
- lengthString = self._remainingData[:endOfNumber]
- # Expect payload plus trailing comma:
- self._expectedPayloadSize = self._extractLength(lengthString) + 1
- self._remainingData = self._remainingData[startOfData:]
-
-
- def _extractLength(self, lengthAsString):
- """
- Attempts to extract the length information of a netstring.
-
- @raise NetstringParseError: if the number is bigger than
- C{self.MAX_LENGTH}.
- @param lengthAsString: A chunk of data starting with a length
- specification
- @type lengthAsString: C{str}
- @return: The length of the netstring
- @rtype: C{int}
- """
- self._checkStringSize(lengthAsString)
- length = int(lengthAsString)
- if length > self.MAX_LENGTH:
- raise NetstringParseError(self._TOO_LONG % (self.MAX_LENGTH,))
- return length
-
-
- def _checkStringSize(self, lengthAsString):
- """
- Checks the sanity of lengthAsString.
-
- Checks if the size of the length specification exceeds the
- size of the string representing self.MAX_LENGTH. If this is
- not the case, the number represented by lengthAsString is
- certainly bigger than self.MAX_LENGTH, and a
- NetstringParseError can be raised.
-
- This method should make sure that netstrings with extremely
- long length specifications are refused before even attempting
- to convert them to an integer (which might trigger a
- MemoryError).
- """
- if len(lengthAsString) > self._maxLengthSize():
- raise NetstringParseError(self._TOO_LONG % (self.MAX_LENGTH,))
-
-
- def _prepareForPayloadConsumption(self):
- """
- Sets up variables necessary for consuming the payload of a netstring.
- """
- self._state = self._PARSING_PAYLOAD
- self._currentPayloadSize = 0
- self._payload.seek(0)
- self._payload.truncate()
-
-
- def _consumePayload(self):
- """
- Consumes the payload portion of C{self._remainingData}.
-
- If the payload is complete, checks for the trailing comma and
- processes the payload. If not, raises an L{IncompleteNetstring}
- exception.
-
- @raise IncompleteNetstring: if the payload received so far
- contains fewer characters than expected.
- @raise NetstringParseError: if the payload does not end with a
- comma.
- """
- self._extractPayload()
- if self._currentPayloadSize < self._expectedPayloadSize:
- raise IncompleteNetstring()
- self._checkForTrailingComma()
- self._state = self._PARSING_LENGTH
- self._processPayload()
-
-
- def _extractPayload(self):
- """
- Extracts payload information from C{self._remainingData}.
-
- Splits C{self._remainingData} at the end of the netstring. The
- first part becomes C{self._payload}, the second part is stored
- in C{self._remainingData}.
-
- If the netstring is not yet complete, the whole content of
- C{self._remainingData} is moved to C{self._payload}.
- """
- if self._payloadComplete():
- remainingPayloadSize = (self._expectedPayloadSize -
- self._currentPayloadSize)
- self._payload.write(self._remainingData[:remainingPayloadSize])
- self._remainingData = self._remainingData[remainingPayloadSize:]
- self._currentPayloadSize = self._expectedPayloadSize
- else:
- self._payload.write(self._remainingData)
- self._currentPayloadSize += len(self._remainingData)
- self._remainingData = ""
-
-
- def _payloadComplete(self):
- """
- Checks if enough data have been received to complete the netstring.
-
- @return: C{True} iff the received data contain at least as many
- characters as specified in the length section of the
- netstring
- @rtype: C{bool}
- """
- return (len(self._remainingData) + self._currentPayloadSize >=
- self._expectedPayloadSize)
-
-
- def _processPayload(self):
- """
- Processes the actual payload with L{stringReceived}.
-
- Strips C{self._payload} of the trailing comma and calls
- L{stringReceived} with the result.
- """
- self.stringReceived(self._payload.getvalue()[:-1])
-
-
- def _checkForTrailingComma(self):
- """
- Checks if the netstring has a trailing comma at the expected position.
-
- @raise NetstringParseError: if the last payload character is
- anything but a comma.
- """
- if self._payload.getvalue()[-1] != ",":
- raise NetstringParseError(self._MISSING_COMMA)
-
-
- def _handleParseError(self):
- """
- Terminates the connection and sets the flag C{self.brokenPeer}.
- """
- self.transport.loseConnection()
- self.brokenPeer = 1
-
-
-
-class LineOnlyReceiver(protocol.Protocol):
- """
- A protocol that receives only lines.
-
- This is purely a speed optimisation over LineReceiver, for the
- cases that raw mode is known to be unnecessary.
-
- @cvar delimiter: The line-ending delimiter to use. By default this is
- '\\r\\n'.
- @cvar MAX_LENGTH: The maximum length of a line to allow (If a
- sent line is longer than this, the connection is dropped).
- Default is 16384.
- """
- _buffer = ''
- delimiter = '\r\n'
- MAX_LENGTH = 16384
-
- def dataReceived(self, data):
- """
- Translates bytes into lines, and calls lineReceived.
- """
- lines = (self._buffer+data).split(self.delimiter)
- self._buffer = lines.pop(-1)
- for line in lines:
- if self.transport.disconnecting:
- # this is necessary because the transport may be told to lose
- # the connection by a line within a larger packet, and it is
- # important to disregard all the lines in that packet following
- # the one that told it to close.
- return
- if len(line) > self.MAX_LENGTH:
- return self.lineLengthExceeded(line)
- else:
- self.lineReceived(line)
- if len(self._buffer) > self.MAX_LENGTH:
- return self.lineLengthExceeded(self._buffer)
-
-
- def lineReceived(self, line):
- """
- Override this for when each line is received.
-
- @param line: The line which was received with the delimiter removed.
- @type line: C{str}
- """
- raise NotImplementedError
-
-
- def sendLine(self, line):
- """
- Sends a line to the other end of the connection.
-
- @param line: The line to send, not including the delimiter.
- @type line: C{str}
- """
- return self.transport.writeSequence((line, self.delimiter))
-
-
- def lineLengthExceeded(self, line):
- """
- Called when the maximum line length has been reached.
- Override if it needs to be dealt with in some special way.
- """
- return error.ConnectionLost('Line length exceeded')
-
-
-
-class _PauseableMixin:
- paused = False
-
- def pauseProducing(self):
- self.paused = True
- self.transport.pauseProducing()
-
-
- def resumeProducing(self):
- self.paused = False
- self.transport.resumeProducing()
- self.dataReceived('')
-
-
- def stopProducing(self):
- self.paused = True
- self.transport.stopProducing()
-
-
-
-class LineReceiver(protocol.Protocol, _PauseableMixin):
- """
- A protocol that receives lines and/or raw data, depending on mode.
-
- In line mode, each line that's received becomes a callback to
- L{lineReceived}. In raw data mode, each chunk of raw data becomes a
- callback to L{rawDataReceived}. The L{setLineMode} and L{setRawMode}
- methods switch between the two modes.
-
- This is useful for line-oriented protocols such as IRC, HTTP, POP, etc.
-
- @cvar delimiter: The line-ending delimiter to use. By default this is
- '\\r\\n'.
- @cvar MAX_LENGTH: The maximum length of a line to allow (If a
- sent line is longer than this, the connection is dropped).
- Default is 16384.
- """
- line_mode = 1
- __buffer = ''
- delimiter = '\r\n'
- MAX_LENGTH = 16384
-
- def clearLineBuffer(self):
- """
- Clear buffered data.
-
- @return: All of the cleared buffered data.
- @rtype: C{str}
- """
- b = self.__buffer
- self.__buffer = ""
- return b
-
-
- def dataReceived(self, data):
- """
- Protocol.dataReceived.
- Translates bytes into lines, and calls lineReceived (or
- rawDataReceived, depending on mode.)
- """
- self.__buffer = self.__buffer+data
- while self.line_mode and not self.paused:
- try:
- line, self.__buffer = self.__buffer.split(self.delimiter, 1)
- except ValueError:
- if len(self.__buffer) > self.MAX_LENGTH:
- line, self.__buffer = self.__buffer, ''
- return self.lineLengthExceeded(line)
- break
- else:
- linelength = len(line)
- if linelength > self.MAX_LENGTH:
- exceeded = line + self.__buffer
- self.__buffer = ''
- return self.lineLengthExceeded(exceeded)
- why = self.lineReceived(line)
- if why or self.transport and self.transport.disconnecting:
- return why
- else:
- if not self.paused:
- data=self.__buffer
- self.__buffer=''
- if data:
- return self.rawDataReceived(data)
-
-
- def setLineMode(self, extra=''):
- """
- Sets the line-mode of this receiver.
-
- If you are calling this from a rawDataReceived callback,
- you can pass in extra unhandled data, and that data will
- be parsed for lines. Further data received will be sent
- to lineReceived rather than rawDataReceived.
-
- Do not pass extra data if calling this function from
- within a lineReceived callback.
- """
- self.line_mode = 1
- if extra:
- return self.dataReceived(extra)
-
-
- def setRawMode(self):
- """
- Sets the raw mode of this receiver.
- Further data received will be sent to rawDataReceived rather
- than lineReceived.
- """
- self.line_mode = 0
-
-
- def rawDataReceived(self, data):
- """
- Override this for when raw data is received.
- """
- raise NotImplementedError
-
-
- def lineReceived(self, line):
- """
- Override this for when each line is received.
-
- @param line: The line which was received with the delimiter removed.
- @type line: C{str}
- """
- raise NotImplementedError
-
-
- def sendLine(self, line):
- """
- Sends a line to the other end of the connection.
-
- @param line: The line to send, not including the delimiter.
- @type line: C{str}
- """
- return self.transport.write(line + self.delimiter)
-
-
- def lineLengthExceeded(self, line):
- """
- Called when the maximum line length has been reached.
- Override if it needs to be dealt with in some special way.
-
- The argument 'line' contains the remainder of the buffer, starting
- with (at least some part) of the line which is too long. This may
- be more than one line, or may be only the initial portion of the
- line.
- """
- return self.transport.loseConnection()
-
-
-
-class StringTooLongError(AssertionError):
- """
- Raised when trying to send a string too long for a length prefixed
- protocol.
- """
-
-
-
-class _RecvdCompatHack(object):
- """
- Emulates the to-be-deprecated C{IntNStringReceiver.recvd} attribute.
-
- The C{recvd} attribute was where the working buffer for buffering and
- parsing netstrings was kept. It was updated each time new data arrived and
- each time some of that data was parsed and delivered to application code.
- The piecemeal updates to its string value were expensive and have been
- removed from C{IntNStringReceiver} in the normal case. However, for
- applications directly reading this attribute, this descriptor restores that
- behavior. It only copies the working buffer when necessary (ie, when
- accessed). This avoids the cost for applications not using the data.
-
- This is a custom descriptor rather than a property, because we still need
- the default __set__ behavior in both new-style and old-style subclasses.
- """
- def __get__(self, oself, type=None):
- return oself._unprocessed[oself._compatibilityOffset:]
-
-
-
-class IntNStringReceiver(protocol.Protocol, _PauseableMixin):
- """
- Generic class for length prefixed protocols.
-
- @ivar _unprocessed: bytes received, but not yet broken up into messages /
- sent to stringReceived. _compatibilityOffset must be updated when this
- value is updated so that the C{recvd} attribute can be generated
- correctly.
- @type _unprocessed: C{bytes}
-
- @ivar structFormat: format used for struct packing/unpacking. Define it in
- subclass.
- @type structFormat: C{str}
-
- @ivar prefixLength: length of the prefix, in bytes. Define it in subclass,
- using C{struct.calcsize(structFormat)}
- @type prefixLength: C{int}
-
- @ivar _compatibilityOffset: the offset within C{_unprocessed} to the next
- message to be parsed. (used to generate the recvd attribute)
- @type _compatibilityOffset: C{int}
- """
-
- MAX_LENGTH = 99999
- _unprocessed = ""
- _compatibilityOffset = 0
-
- # Backwards compatibility support for applications which directly touch the
- # "internal" parse buffer.
- recvd = _RecvdCompatHack()
-
- def stringReceived(self, string):
- """
- Override this for notification when each complete string is received.
-
- @param string: The complete string which was received with all
- framing (length prefix, etc) removed.
- @type string: C{str}
- """
- raise NotImplementedError
-
-
- def lengthLimitExceeded(self, length):
- """
- Callback invoked when a length prefix greater than C{MAX_LENGTH} is
- received. The default implementation disconnects the transport.
- Override this.
-
- @param length: The length prefix which was received.
- @type length: C{int}
- """
- self.transport.loseConnection()
-
-
- def dataReceived(self, data):
- """
- Convert int prefixed strings into calls to stringReceived.
- """
- # Try to minimize string copying (via slices) by keeping one buffer
- # containing all the data we have so far and a separate offset into that
- # buffer.
- alldata = self._unprocessed + data
- currentOffset = 0
- prefixLength = self.prefixLength
- fmt = self.structFormat
- self._unprocessed = alldata
-
- while len(alldata) >= (currentOffset + prefixLength) and not self.paused:
- messageStart = currentOffset + prefixLength
- length, = unpack(fmt, alldata[currentOffset:messageStart])
- if length > self.MAX_LENGTH:
- self._unprocessed = alldata
- self._compatibilityOffset = currentOffset
- self.lengthLimitExceeded(length)
- return
- messageEnd = messageStart + length
- if len(alldata) < messageEnd:
- break
-
- # Here we have to slice the working buffer so we can send just the
- # netstring into the stringReceived callback.
- packet = alldata[messageStart:messageEnd]
- currentOffset = messageEnd
- self._compatibilityOffset = currentOffset
- self.stringReceived(packet)
-
- # Check to see if the backwards compat "recvd" attribute got written
- # to by application code. If so, drop the current data buffer and
- # switch to the new buffer given by that attribute's value.
- if 'recvd' in self.__dict__:
- alldata = self.__dict__.pop('recvd')
- self._unprocessed = alldata
- self._compatibilityOffset = currentOffset = 0
- if alldata:
- continue
- return
-
- # Slice off all the data that has been processed, avoiding holding onto
- # memory to store it, and update the compatibility attributes to reflect
- # that change.
- self._unprocessed = alldata[currentOffset:]
- self._compatibilityOffset = 0
-
-
- def sendString(self, string):
- """
- Send a prefixed string to the other end of the connection.
-
- @param string: The string to send. The necessary framing (length
- prefix, etc) will be added.
- @type string: C{str}
- """
- if len(string) >= 2 ** (8 * self.prefixLength):
- raise StringTooLongError(
- "Try to send %s bytes whereas maximum is %s" % (
- len(string), 2 ** (8 * self.prefixLength)))
- self.transport.write(
- pack(self.structFormat, len(string)) + string)
-
-
-
-class Int32StringReceiver(IntNStringReceiver):
- """
- A receiver for int32-prefixed strings.
-
- An int32 string is a string prefixed by 4 bytes, the 32-bit length of
- the string encoded in network byte order.
-
- This class publishes the same interface as NetstringReceiver.
- """
- structFormat = "!I"
- prefixLength = calcsize(structFormat)
-
-
-
-class Int16StringReceiver(IntNStringReceiver):
- """
- A receiver for int16-prefixed strings.
-
- An int16 string is a string prefixed by 2 bytes, the 16-bit length of
- the string encoded in network byte order.
-
- This class publishes the same interface as NetstringReceiver.
- """
- structFormat = "!H"
- prefixLength = calcsize(structFormat)
-
-
-
-class Int8StringReceiver(IntNStringReceiver):
- """
- A receiver for int8-prefixed strings.
-
- An int8 string is a string prefixed by 1 byte, the 8-bit length of
- the string.
-
- This class publishes the same interface as NetstringReceiver.
- """
- structFormat = "!B"
- prefixLength = calcsize(structFormat)
-
-
-
-class StatefulStringProtocol:
- """
- A stateful string protocol.
-
- This is a mixin for string protocols (Int32StringReceiver,
- NetstringReceiver) which translates stringReceived into a callback
- (prefixed with 'proto_') depending on state.
-
- The state 'done' is special; if a proto_* method returns it, the
- connection will be closed immediately.
- """
-
- state = 'init'
-
- def stringReceived(self, string):
- """
- Choose a protocol phase function and call it.
-
- Call back to the appropriate protocol phase; this begins with
- the function proto_init and moves on to proto_* depending on
- what each proto_* function returns. (For example, if
- self.proto_init returns 'foo', then self.proto_foo will be the
- next function called when a protocol message is received.
- """
- try:
- pto = 'proto_'+self.state
- statehandler = getattr(self,pto)
- except AttributeError:
- log.msg('callback',self.state,'not found')
- else:
- self.state = statehandler(string)
- if self.state == 'done':
- self.transport.loseConnection()
-
-
-
-class FileSender:
- """
- A producer that sends the contents of a file to a consumer.
-
- This is a helper for protocols that, at some point, will take a
- file-like object, read its contents, and write them out to the network,
- optionally performing some transformation on the bytes in between.
- """
- implements(interfaces.IProducer)
-
- CHUNK_SIZE = 2 ** 14
-
- lastSent = ''
- deferred = None
-
- def beginFileTransfer(self, file, consumer, transform = None):
- """
- Begin transferring a file
-
- @type file: Any file-like object
- @param file: The file object to read data from
-
- @type consumer: Any implementor of IConsumer
- @param consumer: The object to write data to
-
- @param transform: A callable taking one string argument and returning
- the same. All bytes read from the file are passed through this before
- being written to the consumer.
-
- @rtype: C{Deferred}
- @return: A deferred whose callback will be invoked when the file has
- been completely written to the consumer. The last byte written to the
- consumer is passed to the callback.
- """
- self.file = file
- self.consumer = consumer
- self.transform = transform
-
- self.deferred = deferred = defer.Deferred()
- self.consumer.registerProducer(self, False)
- return deferred
-
-
- def resumeProducing(self):
- chunk = ''
- if self.file:
- chunk = self.file.read(self.CHUNK_SIZE)
- if not chunk:
- self.file = None
- self.consumer.unregisterProducer()
- if self.deferred:
- self.deferred.callback(self.lastSent)
- self.deferred = None
- return
-
- if self.transform:
- chunk = self.transform(chunk)
- self.consumer.write(chunk)
- self.lastSent = chunk[-1]
-
-
- def pauseProducing(self):
- pass
-
-
- def stopProducing(self):
- if self.deferred:
- self.deferred.errback(
- Exception("Consumer asked us to stop producing"))
- self.deferred = None
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/dict.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/dict.py
deleted file mode 100755
index c3af402d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/dict.py
+++ /dev/null
@@ -1,362 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Dict client protocol implementation.
-
-@author: Pavel Pergamenshchik
-"""
-
-from twisted.protocols import basic
-from twisted.internet import defer, protocol
-from twisted.python import log
-from StringIO import StringIO
-
-def parseParam(line):
- """Chew one dqstring or atom from beginning of line and return (param, remaningline)"""
- if line == '':
- return (None, '')
- elif line[0] != '"': # atom
- mode = 1
- else: # dqstring
- mode = 2
- res = ""
- io = StringIO(line)
- if mode == 2: # skip the opening quote
- io.read(1)
- while 1:
- a = io.read(1)
- if a == '"':
- if mode == 2:
- io.read(1) # skip the separating space
- return (res, io.read())
- elif a == '\\':
- a = io.read(1)
- if a == '':
- return (None, line) # unexpected end of string
- elif a == '':
- if mode == 1:
- return (res, io.read())
- else:
- return (None, line) # unexpected end of string
- elif a == ' ':
- if mode == 1:
- return (res, io.read())
- res += a
-
-def makeAtom(line):
- """Munch a string into an 'atom'"""
- # FIXME: proper quoting
- return filter(lambda x: not (x in map(chr, range(33)+[34, 39, 92])), line)
-
-def makeWord(s):
- mustquote = range(33)+[34, 39, 92]
- result = []
- for c in s:
- if ord(c) in mustquote:
- result.append("\\")
- result.append(c)
- s = "".join(result)
- return s
-
-def parseText(line):
- if len(line) == 1 and line == '.':
- return None
- else:
- if len(line) > 1 and line[0:2] == '..':
- line = line[1:]
- return line
-
-class Definition:
- """A word definition"""
- def __init__(self, name, db, dbdesc, text):
- self.name = name
- self.db = db
- self.dbdesc = dbdesc
- self.text = text # list of strings not terminated by newline
-
-class DictClient(basic.LineReceiver):
- """dict (RFC2229) client"""
-
- data = None # multiline data
- MAX_LENGTH = 1024
- state = None
- mode = None
- result = None
- factory = None
-
- def __init__(self):
- self.data = None
- self.result = None
-
- def connectionMade(self):
- self.state = "conn"
- self.mode = "command"
-
- def sendLine(self, line):
- """Throw up if the line is longer than 1022 characters"""
- if len(line) > self.MAX_LENGTH - 2:
- raise ValueError("DictClient tried to send a too long line")
- basic.LineReceiver.sendLine(self, line)
-
- def lineReceived(self, line):
- try:
- line = line.decode("UTF-8")
- except UnicodeError: # garbage received, skip
- return
- if self.mode == "text": # we are receiving textual data
- code = "text"
- else:
- if len(line) < 4:
- log.msg("DictClient got invalid line from server -- %s" % line)
- self.protocolError("Invalid line from server")
- self.transport.LoseConnection()
- return
- code = int(line[:3])
- line = line[4:]
- method = getattr(self, 'dictCode_%s_%s' % (code, self.state), self.dictCode_default)
- method(line)
-
- def dictCode_default(self, line):
- """Unkown message"""
- log.msg("DictClient got unexpected message from server -- %s" % line)
- self.protocolError("Unexpected server message")
- self.transport.loseConnection()
-
- def dictCode_221_ready(self, line):
- """We are about to get kicked off, do nothing"""
- pass
-
- def dictCode_220_conn(self, line):
- """Greeting message"""
- self.state = "ready"
- self.dictConnected()
-
- def dictCode_530_conn(self):
- self.protocolError("Access denied")
- self.transport.loseConnection()
-
- def dictCode_420_conn(self):
- self.protocolError("Server temporarily unavailable")
- self.transport.loseConnection()
-
- def dictCode_421_conn(self):
- self.protocolError("Server shutting down at operator request")
- self.transport.loseConnection()
-
- def sendDefine(self, database, word):
- """Send a dict DEFINE command"""
- assert self.state == "ready", "DictClient.sendDefine called when not in ready state"
- self.result = None # these two are just in case. In "ready" state, result and data
- self.data = None # should be None
- self.state = "define"
- command = "DEFINE %s %s" % (makeAtom(database.encode("UTF-8")), makeWord(word.encode("UTF-8")))
- self.sendLine(command)
-
- def sendMatch(self, database, strategy, word):
- """Send a dict MATCH command"""
- assert self.state == "ready", "DictClient.sendMatch called when not in ready state"
- self.result = None
- self.data = None
- self.state = "match"
- command = "MATCH %s %s %s" % (makeAtom(database), makeAtom(strategy), makeAtom(word))
- self.sendLine(command.encode("UTF-8"))
-
- def dictCode_550_define(self, line):
- """Invalid database"""
- self.mode = "ready"
- self.defineFailed("Invalid database")
-
- def dictCode_550_match(self, line):
- """Invalid database"""
- self.mode = "ready"
- self.matchFailed("Invalid database")
-
- def dictCode_551_match(self, line):
- """Invalid strategy"""
- self.mode = "ready"
- self.matchFailed("Invalid strategy")
-
- def dictCode_552_define(self, line):
- """No match"""
- self.mode = "ready"
- self.defineFailed("No match")
-
- def dictCode_552_match(self, line):
- """No match"""
- self.mode = "ready"
- self.matchFailed("No match")
-
- def dictCode_150_define(self, line):
- """n definitions retrieved"""
- self.result = []
-
- def dictCode_151_define(self, line):
- """Definition text follows"""
- self.mode = "text"
- (word, line) = parseParam(line)
- (db, line) = parseParam(line)
- (dbdesc, line) = parseParam(line)
- if not (word and db and dbdesc):
- self.protocolError("Invalid server response")
- self.transport.loseConnection()
- else:
- self.result.append(Definition(word, db, dbdesc, []))
- self.data = []
-
- def dictCode_152_match(self, line):
- """n matches found, text follows"""
- self.mode = "text"
- self.result = []
- self.data = []
-
- def dictCode_text_define(self, line):
- """A line of definition text received"""
- res = parseText(line)
- if res == None:
- self.mode = "command"
- self.result[-1].text = self.data
- self.data = None
- else:
- self.data.append(line)
-
- def dictCode_text_match(self, line):
- """One line of match text received"""
- def l(s):
- p1, t = parseParam(s)
- p2, t = parseParam(t)
- return (p1, p2)
- res = parseText(line)
- if res == None:
- self.mode = "command"
- self.result = map(l, self.data)
- self.data = None
- else:
- self.data.append(line)
-
- def dictCode_250_define(self, line):
- """ok"""
- t = self.result
- self.result = None
- self.state = "ready"
- self.defineDone(t)
-
- def dictCode_250_match(self, line):
- """ok"""
- t = self.result
- self.result = None
- self.state = "ready"
- self.matchDone(t)
-
- def protocolError(self, reason):
- """override to catch unexpected dict protocol conditions"""
- pass
-
- def dictConnected(self):
- """override to be notified when the server is ready to accept commands"""
- pass
-
- def defineFailed(self, reason):
- """override to catch reasonable failure responses to DEFINE"""
- pass
-
- def defineDone(self, result):
- """override to catch succesful DEFINE"""
- pass
-
- def matchFailed(self, reason):
- """override to catch resonable failure responses to MATCH"""
- pass
-
- def matchDone(self, result):
- """override to catch succesful MATCH"""
- pass
-
-
-class InvalidResponse(Exception):
- pass
-
-
-class DictLookup(DictClient):
- """Utility class for a single dict transaction. To be used with DictLookupFactory"""
-
- def protocolError(self, reason):
- if not self.factory.done:
- self.factory.d.errback(InvalidResponse(reason))
- self.factory.clientDone()
-
- def dictConnected(self):
- if self.factory.queryType == "define":
- apply(self.sendDefine, self.factory.param)
- elif self.factory.queryType == "match":
- apply(self.sendMatch, self.factory.param)
-
- def defineFailed(self, reason):
- self.factory.d.callback([])
- self.factory.clientDone()
- self.transport.loseConnection()
-
- def defineDone(self, result):
- self.factory.d.callback(result)
- self.factory.clientDone()
- self.transport.loseConnection()
-
- def matchFailed(self, reason):
- self.factory.d.callback([])
- self.factory.clientDone()
- self.transport.loseConnection()
-
- def matchDone(self, result):
- self.factory.d.callback(result)
- self.factory.clientDone()
- self.transport.loseConnection()
-
-
-class DictLookupFactory(protocol.ClientFactory):
- """Utility factory for a single dict transaction"""
- protocol = DictLookup
- done = None
-
- def __init__(self, queryType, param, d):
- self.queryType = queryType
- self.param = param
- self.d = d
- self.done = 0
-
- def clientDone(self):
- """Called by client when done."""
- self.done = 1
- del self.d
-
- def clientConnectionFailed(self, connector, error):
- self.d.errback(error)
-
- def clientConnectionLost(self, connector, error):
- if not self.done:
- self.d.errback(error)
-
- def buildProtocol(self, addr):
- p = self.protocol()
- p.factory = self
- return p
-
-
-def define(host, port, database, word):
- """Look up a word using a dict server"""
- d = defer.Deferred()
- factory = DictLookupFactory("define", (database, word), d)
-
- from twisted.internet import reactor
- reactor.connectTCP(host, port, factory)
- return d
-
-def match(host, port, database, strategy, word):
- """Match a word using a dict server"""
- d = defer.Deferred()
- factory = DictLookupFactory("match", (database, strategy, word), d)
-
- from twisted.internet import reactor
- reactor.connectTCP(host, port, factory)
- return d
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/finger.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/finger.py
deleted file mode 100755
index fcb93967..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/finger.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""The Finger User Information Protocol (RFC 1288)"""
-
-from twisted.protocols import basic
-
-class Finger(basic.LineReceiver):
-
- def lineReceived(self, line):
- parts = line.split()
- if not parts:
- parts = ['']
- if len(parts) == 1:
- slash_w = 0
- else:
- slash_w = 1
- user = parts[-1]
- if '@' in user:
- host_place = user.rfind('@')
- user = user[:host_place]
- host = user[host_place+1:]
- return self.forwardQuery(slash_w, user, host)
- if user:
- return self.getUser(slash_w, user)
- else:
- return self.getDomain(slash_w)
-
- def _refuseMessage(self, message):
- self.transport.write(message+"\n")
- self.transport.loseConnection()
-
- def forwardQuery(self, slash_w, user, host):
- self._refuseMessage('Finger forwarding service denied')
-
- def getDomain(self, slash_w):
- self._refuseMessage('Finger online list denied')
-
- def getUser(self, slash_w, user):
- self.transport.write('Login: '+user+'\n')
- self._refuseMessage('No such user')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ftp.py
deleted file mode 100755
index b035f04e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ftp.py
+++ /dev/null
@@ -1,2955 +0,0 @@
-# -*- test-case-name: twisted.test.test_ftp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An FTP protocol implementation
-"""
-
-# System Imports
-import os
-import time
-import re
-import operator
-import stat
-import errno
-import fnmatch
-import warnings
-
-try:
- import pwd, grp
-except ImportError:
- pwd = grp = None
-
-from zope.interface import Interface, implements
-
-# Twisted Imports
-from twisted import copyright
-from twisted.internet import reactor, interfaces, protocol, error, defer
-from twisted.protocols import basic, policies
-
-from twisted.python import log, failure, filepath
-from twisted.python.compat import reduce
-
-from twisted.cred import error as cred_error, portal, credentials, checkers
-
-# constants
-# response codes
-
-RESTART_MARKER_REPLY = "100"
-SERVICE_READY_IN_N_MINUTES = "120"
-DATA_CNX_ALREADY_OPEN_START_XFR = "125"
-FILE_STATUS_OK_OPEN_DATA_CNX = "150"
-
-CMD_OK = "200.1"
-TYPE_SET_OK = "200.2"
-ENTERING_PORT_MODE = "200.3"
-CMD_NOT_IMPLMNTD_SUPERFLUOUS = "202"
-SYS_STATUS_OR_HELP_REPLY = "211"
-DIR_STATUS = "212"
-FILE_STATUS = "213"
-HELP_MSG = "214"
-NAME_SYS_TYPE = "215"
-SVC_READY_FOR_NEW_USER = "220.1"
-WELCOME_MSG = "220.2"
-SVC_CLOSING_CTRL_CNX = "221.1"
-GOODBYE_MSG = "221.2"
-DATA_CNX_OPEN_NO_XFR_IN_PROGRESS = "225"
-CLOSING_DATA_CNX = "226.1"
-TXFR_COMPLETE_OK = "226.2"
-ENTERING_PASV_MODE = "227"
-ENTERING_EPSV_MODE = "229"
-USR_LOGGED_IN_PROCEED = "230.1" # v1 of code 230
-GUEST_LOGGED_IN_PROCEED = "230.2" # v2 of code 230
-REQ_FILE_ACTN_COMPLETED_OK = "250"
-PWD_REPLY = "257.1"
-MKD_REPLY = "257.2"
-
-USR_NAME_OK_NEED_PASS = "331.1" # v1 of Code 331
-GUEST_NAME_OK_NEED_EMAIL = "331.2" # v2 of code 331
-NEED_ACCT_FOR_LOGIN = "332"
-REQ_FILE_ACTN_PENDING_FURTHER_INFO = "350"
-
-SVC_NOT_AVAIL_CLOSING_CTRL_CNX = "421.1"
-TOO_MANY_CONNECTIONS = "421.2"
-CANT_OPEN_DATA_CNX = "425"
-CNX_CLOSED_TXFR_ABORTED = "426"
-REQ_ACTN_ABRTD_FILE_UNAVAIL = "450"
-REQ_ACTN_ABRTD_LOCAL_ERR = "451"
-REQ_ACTN_ABRTD_INSUFF_STORAGE = "452"
-
-SYNTAX_ERR = "500"
-SYNTAX_ERR_IN_ARGS = "501"
-CMD_NOT_IMPLMNTD = "502"
-BAD_CMD_SEQ = "503"
-CMD_NOT_IMPLMNTD_FOR_PARAM = "504"
-NOT_LOGGED_IN = "530.1" # v1 of code 530 - please log in
-AUTH_FAILURE = "530.2" # v2 of code 530 - authorization failure
-NEED_ACCT_FOR_STOR = "532"
-FILE_NOT_FOUND = "550.1" # no such file or directory
-PERMISSION_DENIED = "550.2" # permission denied
-ANON_USER_DENIED = "550.3" # anonymous users can't alter filesystem
-IS_NOT_A_DIR = "550.4" # rmd called on a path that is not a directory
-REQ_ACTN_NOT_TAKEN = "550.5"
-FILE_EXISTS = "550.6"
-IS_A_DIR = "550.7"
-PAGE_TYPE_UNK = "551"
-EXCEEDED_STORAGE_ALLOC = "552"
-FILENAME_NOT_ALLOWED = "553"
-
-
-RESPONSE = {
- # -- 100's --
- RESTART_MARKER_REPLY: '110 MARK yyyy-mmmm', # TODO: this must be fixed
- SERVICE_READY_IN_N_MINUTES: '120 service ready in %s minutes',
- DATA_CNX_ALREADY_OPEN_START_XFR: '125 Data connection already open, starting transfer',
- FILE_STATUS_OK_OPEN_DATA_CNX: '150 File status okay; about to open data connection.',
-
- # -- 200's --
- CMD_OK: '200 Command OK',
- TYPE_SET_OK: '200 Type set to %s.',
- ENTERING_PORT_MODE: '200 PORT OK',
- CMD_NOT_IMPLMNTD_SUPERFLUOUS: '202 Command not implemented, superfluous at this site',
- SYS_STATUS_OR_HELP_REPLY: '211 System status reply',
- DIR_STATUS: '212 %s',
- FILE_STATUS: '213 %s',
- HELP_MSG: '214 help: %s',
- NAME_SYS_TYPE: '215 UNIX Type: L8',
- WELCOME_MSG: "220 %s",
- SVC_READY_FOR_NEW_USER: '220 Service ready',
- SVC_CLOSING_CTRL_CNX: '221 Service closing control connection',
- GOODBYE_MSG: '221 Goodbye.',
- DATA_CNX_OPEN_NO_XFR_IN_PROGRESS: '225 data connection open, no transfer in progress',
- CLOSING_DATA_CNX: '226 Abort successful',
- TXFR_COMPLETE_OK: '226 Transfer Complete.',
- ENTERING_PASV_MODE: '227 Entering Passive Mode (%s).',
- ENTERING_EPSV_MODE: '229 Entering Extended Passive Mode (|||%s|).', # where is epsv defined in the rfc's?
- USR_LOGGED_IN_PROCEED: '230 User logged in, proceed',
- GUEST_LOGGED_IN_PROCEED: '230 Anonymous login ok, access restrictions apply.',
- REQ_FILE_ACTN_COMPLETED_OK: '250 Requested File Action Completed OK', #i.e. CWD completed ok
- PWD_REPLY: '257 "%s"',
- MKD_REPLY: '257 "%s" created',
-
- # -- 300's --
- USR_NAME_OK_NEED_PASS: '331 Password required for %s.',
- GUEST_NAME_OK_NEED_EMAIL: '331 Guest login ok, type your email address as password.',
- NEED_ACCT_FOR_LOGIN: '332 Need account for login.',
-
- REQ_FILE_ACTN_PENDING_FURTHER_INFO: '350 Requested file action pending further information.',
-
-# -- 400's --
- SVC_NOT_AVAIL_CLOSING_CTRL_CNX: '421 Service not available, closing control connection.',
- TOO_MANY_CONNECTIONS: '421 Too many users right now, try again in a few minutes.',
- CANT_OPEN_DATA_CNX: "425 Can't open data connection.",
- CNX_CLOSED_TXFR_ABORTED: '426 Transfer aborted. Data connection closed.',
-
- REQ_ACTN_ABRTD_FILE_UNAVAIL: '450 Requested action aborted. File unavailable.',
- REQ_ACTN_ABRTD_LOCAL_ERR: '451 Requested action aborted. Local error in processing.',
- REQ_ACTN_ABRTD_INSUFF_STORAGE: '452 Requested action aborted. Insufficient storage.',
-
- # -- 500's --
- SYNTAX_ERR: "500 Syntax error: %s",
- SYNTAX_ERR_IN_ARGS: '501 syntax error in argument(s) %s.',
- CMD_NOT_IMPLMNTD: "502 Command '%s' not implemented",
- BAD_CMD_SEQ: '503 Incorrect sequence of commands: %s',
- CMD_NOT_IMPLMNTD_FOR_PARAM: "504 Not implemented for parameter '%s'.",
- NOT_LOGGED_IN: '530 Please login with USER and PASS.',
- AUTH_FAILURE: '530 Sorry, Authentication failed.',
- NEED_ACCT_FOR_STOR: '532 Need an account for storing files',
- FILE_NOT_FOUND: '550 %s: No such file or directory.',
- PERMISSION_DENIED: '550 %s: Permission denied.',
- ANON_USER_DENIED: '550 Anonymous users are forbidden to change the filesystem',
- IS_NOT_A_DIR: '550 Cannot rmd, %s is not a directory',
- FILE_EXISTS: '550 %s: File exists',
- IS_A_DIR: '550 %s: is a directory',
- REQ_ACTN_NOT_TAKEN: '550 Requested action not taken: %s',
- PAGE_TYPE_UNK: '551 Page type unknown',
- EXCEEDED_STORAGE_ALLOC: '552 Requested file action aborted, exceeded file storage allocation',
- FILENAME_NOT_ALLOWED: '553 Requested action not taken, file name not allowed'
-}
-
-
-
-class InvalidPath(Exception):
- """
- Internal exception used to signify an error during parsing a path.
- """
-
-
-
-def toSegments(cwd, path):
- """
- Normalize a path, as represented by a list of strings each
- representing one segment of the path.
- """
- if path.startswith('/'):
- segs = []
- else:
- segs = cwd[:]
-
- for s in path.split('/'):
- if s == '.' or s == '':
- continue
- elif s == '..':
- if segs:
- segs.pop()
- else:
- raise InvalidPath(cwd, path)
- elif '\0' in s or '/' in s:
- raise InvalidPath(cwd, path)
- else:
- segs.append(s)
- return segs
-
-
-def errnoToFailure(e, path):
- """
- Map C{OSError} and C{IOError} to standard FTP errors.
- """
- if e == errno.ENOENT:
- return defer.fail(FileNotFoundError(path))
- elif e == errno.EACCES or e == errno.EPERM:
- return defer.fail(PermissionDeniedError(path))
- elif e == errno.ENOTDIR:
- return defer.fail(IsNotADirectoryError(path))
- elif e == errno.EEXIST:
- return defer.fail(FileExistsError(path))
- elif e == errno.EISDIR:
- return defer.fail(IsADirectoryError(path))
- else:
- return defer.fail()
-
-
-
-class FTPCmdError(Exception):
- """
- Generic exception for FTP commands.
- """
- def __init__(self, *msg):
- Exception.__init__(self, *msg)
- self.errorMessage = msg
-
-
- def response(self):
- """
- Generate a FTP response message for this error.
- """
- return RESPONSE[self.errorCode] % self.errorMessage
-
-
-
-class FileNotFoundError(FTPCmdError):
- """
- Raised when trying to access a non existent file or directory.
- """
- errorCode = FILE_NOT_FOUND
-
-
-
-class AnonUserDeniedError(FTPCmdError):
- """
- Raised when an anonymous user issues a command that will alter the
- filesystem
- """
-
- errorCode = ANON_USER_DENIED
-
-
-
-class PermissionDeniedError(FTPCmdError):
- """
- Raised when access is attempted to a resource to which access is
- not allowed.
- """
- errorCode = PERMISSION_DENIED
-
-
-
-class IsNotADirectoryError(FTPCmdError):
- """
- Raised when RMD is called on a path that isn't a directory.
- """
- errorCode = IS_NOT_A_DIR
-
-
-
-class FileExistsError(FTPCmdError):
- """
- Raised when attempted to override an existing resource.
- """
- errorCode = FILE_EXISTS
-
-
-
-class IsADirectoryError(FTPCmdError):
- """
- Raised when DELE is called on a path that is a directory.
- """
- errorCode = IS_A_DIR
-
-
-
-class CmdSyntaxError(FTPCmdError):
- """
- Raised when a command syntax is wrong.
- """
- errorCode = SYNTAX_ERR
-
-
-
-class CmdArgSyntaxError(FTPCmdError):
- """
- Raised when a command is called with wrong value or a wrong number of
- arguments.
- """
- errorCode = SYNTAX_ERR_IN_ARGS
-
-
-
-class CmdNotImplementedError(FTPCmdError):
- """
- Raised when an unimplemented command is given to the server.
- """
- errorCode = CMD_NOT_IMPLMNTD
-
-
-
-class CmdNotImplementedForArgError(FTPCmdError):
- """
- Raised when the handling of a parameter for a command is not implemented by
- the server.
- """
- errorCode = CMD_NOT_IMPLMNTD_FOR_PARAM
-
-
-
-class FTPError(Exception):
- pass
-
-
-
-class PortConnectionError(Exception):
- pass
-
-
-
-class BadCmdSequenceError(FTPCmdError):
- """
- Raised when a client sends a series of commands in an illogical sequence.
- """
- errorCode = BAD_CMD_SEQ
-
-
-
-class AuthorizationError(FTPCmdError):
- """
- Raised when client authentication fails.
- """
- errorCode = AUTH_FAILURE
-
-
-
-def debugDeferred(self, *_):
- log.msg('debugDeferred(): %s' % str(_), debug=True)
-
-
-# -- DTP Protocol --
-
-
-_months = [
- None,
- 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
-
-class DTP(object, protocol.Protocol):
- implements(interfaces.IConsumer)
-
- isConnected = False
-
- _cons = None
- _onConnLost = None
- _buffer = None
-
- def connectionMade(self):
- self.isConnected = True
- self.factory.deferred.callback(None)
- self._buffer = []
-
- def connectionLost(self, reason):
- self.isConnected = False
- if self._onConnLost is not None:
- self._onConnLost.callback(None)
-
- def sendLine(self, line):
- self.transport.write(line + '\r\n')
-
-
- def _formatOneListResponse(self, name, size, directory, permissions, hardlinks, modified, owner, group):
- def formatMode(mode):
- return ''.join([mode & (256 >> n) and 'rwx'[n % 3] or '-' for n in range(9)])
-
- def formatDate(mtime):
- now = time.gmtime()
- info = {
- 'month': _months[mtime.tm_mon],
- 'day': mtime.tm_mday,
- 'year': mtime.tm_year,
- 'hour': mtime.tm_hour,
- 'minute': mtime.tm_min
- }
- if now.tm_year != mtime.tm_year:
- return '%(month)s %(day)02d %(year)5d' % info
- else:
- return '%(month)s %(day)02d %(hour)02d:%(minute)02d' % info
-
- format = ('%(directory)s%(permissions)s%(hardlinks)4d '
- '%(owner)-9s %(group)-9s %(size)15d %(date)12s '
- '%(name)s')
-
- return format % {
- 'directory': directory and 'd' or '-',
- 'permissions': formatMode(permissions),
- 'hardlinks': hardlinks,
- 'owner': owner[:8],
- 'group': group[:8],
- 'size': size,
- 'date': formatDate(time.gmtime(modified)),
- 'name': name}
-
- def sendListResponse(self, name, response):
- self.sendLine(self._formatOneListResponse(name, *response))
-
-
- # Proxy IConsumer to our transport
- def registerProducer(self, producer, streaming):
- return self.transport.registerProducer(producer, streaming)
-
- def unregisterProducer(self):
- self.transport.unregisterProducer()
- self.transport.loseConnection()
-
- def write(self, data):
- if self.isConnected:
- return self.transport.write(data)
- raise Exception("Crap damn crap damn crap damn")
-
-
- # Pretend to be a producer, too.
- def _conswrite(self, bytes):
- try:
- self._cons.write(bytes)
- except:
- self._onConnLost.errback()
-
- def dataReceived(self, bytes):
- if self._cons is not None:
- self._conswrite(bytes)
- else:
- self._buffer.append(bytes)
-
- def _unregConsumer(self, ignored):
- self._cons.unregisterProducer()
- self._cons = None
- del self._onConnLost
- return ignored
-
- def registerConsumer(self, cons):
- assert self._cons is None
- self._cons = cons
- self._cons.registerProducer(self, True)
- for chunk in self._buffer:
- self._conswrite(chunk)
- self._buffer = None
- if self.isConnected:
- self._onConnLost = d = defer.Deferred()
- d.addBoth(self._unregConsumer)
- return d
- else:
- self._cons.unregisterProducer()
- self._cons = None
- return defer.succeed(None)
-
- def resumeProducing(self):
- self.transport.resumeProducing()
-
- def pauseProducing(self):
- self.transport.pauseProducing()
-
- def stopProducing(self):
- self.transport.stopProducing()
-
-class DTPFactory(protocol.ClientFactory):
- """
- Client factory for I{data transfer process} protocols.
-
- @ivar peerCheck: perform checks to make sure the ftp-pi's peer is the same
- as the dtp's
- @ivar pi: a reference to this factory's protocol interpreter
-
- @ivar _state: Indicates the current state of the DTPFactory. Initially,
- this is L{_IN_PROGRESS}. If the connection fails or times out, it is
- L{_FAILED}. If the connection succeeds before the timeout, it is
- L{_FINISHED}.
- """
-
- _IN_PROGRESS = object()
- _FAILED = object()
- _FINISHED = object()
-
- _state = _IN_PROGRESS
-
- # -- configuration variables --
- peerCheck = False
-
- # -- class variables --
- def __init__(self, pi, peerHost=None, reactor=None):
- """Constructor
- @param pi: this factory's protocol interpreter
- @param peerHost: if peerCheck is True, this is the tuple that the
- generated instance will use to perform security checks
- """
- self.pi = pi # the protocol interpreter that is using this factory
- self.peerHost = peerHost # the from FTP.transport.peerHost()
- self.deferred = defer.Deferred() # deferred will fire when instance is connected
- self.delayedCall = None
- if reactor is None:
- from twisted.internet import reactor
- self._reactor = reactor
-
-
- def buildProtocol(self, addr):
- log.msg('DTPFactory.buildProtocol', debug=True)
-
- if self._state is not self._IN_PROGRESS:
- return None
- self._state = self._FINISHED
-
- self.cancelTimeout()
- p = DTP()
- p.factory = self
- p.pi = self.pi
- self.pi.dtpInstance = p
- return p
-
-
- def stopFactory(self):
- log.msg('dtpFactory.stopFactory', debug=True)
- self.cancelTimeout()
-
-
- def timeoutFactory(self):
- log.msg('timed out waiting for DTP connection')
- if self._state is not self._IN_PROGRESS:
- return
- self._state = self._FAILED
-
- d = self.deferred
- self.deferred = None
- d.errback(
- PortConnectionError(defer.TimeoutError("DTPFactory timeout")))
-
-
- def cancelTimeout(self):
- if self.delayedCall is not None and self.delayedCall.active():
- log.msg('cancelling DTP timeout', debug=True)
- self.delayedCall.cancel()
-
-
- def setTimeout(self, seconds):
- log.msg('DTPFactory.setTimeout set to %s seconds' % seconds)
- self.delayedCall = self._reactor.callLater(seconds, self.timeoutFactory)
-
-
- def clientConnectionFailed(self, connector, reason):
- if self._state is not self._IN_PROGRESS:
- return
- self._state = self._FAILED
- d = self.deferred
- self.deferred = None
- d.errback(PortConnectionError(reason))
-
-
-# -- FTP-PI (Protocol Interpreter) --
-
-class ASCIIConsumerWrapper(object):
- def __init__(self, cons):
- self.cons = cons
- self.registerProducer = cons.registerProducer
- self.unregisterProducer = cons.unregisterProducer
-
- assert os.linesep == "\r\n" or len(os.linesep) == 1, "Unsupported platform (yea right like this even exists)"
-
- if os.linesep == "\r\n":
- self.write = cons.write
-
- def write(self, bytes):
- return self.cons.write(bytes.replace(os.linesep, "\r\n"))
-
-
-
-class FileConsumer(object):
- """
- A consumer for FTP input that writes data to a file.
-
- @ivar fObj: a file object opened for writing, used to write data received.
- @type fObj: C{file}
- """
-
- implements(interfaces.IConsumer)
-
- def __init__(self, fObj):
- self.fObj = fObj
-
-
- def registerProducer(self, producer, streaming):
- self.producer = producer
- assert streaming
-
-
- def unregisterProducer(self):
- self.producer = None
- self.fObj.close()
-
-
- def write(self, bytes):
- self.fObj.write(bytes)
-
-
-
-class FTPOverflowProtocol(basic.LineReceiver):
- """FTP mini-protocol for when there are too many connections."""
- def connectionMade(self):
- self.sendLine(RESPONSE[TOO_MANY_CONNECTIONS])
- self.transport.loseConnection()
-
-
-class FTP(object, basic.LineReceiver, policies.TimeoutMixin):
- """
- Protocol Interpreter for the File Transfer Protocol
-
- @ivar state: The current server state. One of L{UNAUTH},
- L{INAUTH}, L{AUTHED}, L{RENAMING}.
-
- @ivar shell: The connected avatar
- @ivar binary: The transfer mode. If false, ASCII.
- @ivar dtpFactory: Generates a single DTP for this session
- @ivar dtpPort: Port returned from listenTCP
- @ivar listenFactory: A callable with the signature of
- L{twisted.internet.interfaces.IReactorTCP.listenTCP} which will be used
- to create Ports for passive connections (mainly for testing).
-
- @ivar passivePortRange: iterator used as source of passive port numbers.
- @type passivePortRange: C{iterator}
- """
-
- disconnected = False
-
- # States an FTP can be in
- UNAUTH, INAUTH, AUTHED, RENAMING = range(4)
-
- # how long the DTP waits for a connection
- dtpTimeout = 10
-
- portal = None
- shell = None
- dtpFactory = None
- dtpPort = None
- dtpInstance = None
- binary = True
-
- passivePortRange = xrange(0, 1)
-
- listenFactory = reactor.listenTCP
-
- def reply(self, key, *args):
- msg = RESPONSE[key] % args
- self.sendLine(msg)
-
-
- def connectionMade(self):
- self.state = self.UNAUTH
- self.setTimeout(self.timeOut)
- self.reply(WELCOME_MSG, self.factory.welcomeMessage)
-
- def connectionLost(self, reason):
- # if we have a DTP protocol instance running and
- # we lose connection to the client's PI, kill the
- # DTP connection and close the port
- if self.dtpFactory:
- self.cleanupDTP()
- self.setTimeout(None)
- if hasattr(self.shell, 'logout') and self.shell.logout is not None:
- self.shell.logout()
- self.shell = None
- self.transport = None
-
- def timeoutConnection(self):
- self.transport.loseConnection()
-
- def lineReceived(self, line):
- self.resetTimeout()
- self.pauseProducing()
-
- def processFailed(err):
- if err.check(FTPCmdError):
- self.sendLine(err.value.response())
- elif (err.check(TypeError) and
- err.value.args[0].find('takes exactly') != -1):
- self.reply(SYNTAX_ERR, "%s requires an argument." % (cmd,))
- else:
- log.msg("Unexpected FTP error")
- log.err(err)
- self.reply(REQ_ACTN_NOT_TAKEN, "internal server error")
-
- def processSucceeded(result):
- if isinstance(result, tuple):
- self.reply(*result)
- elif result is not None:
- self.reply(result)
-
- def allDone(ignored):
- if not self.disconnected:
- self.resumeProducing()
-
- spaceIndex = line.find(' ')
- if spaceIndex != -1:
- cmd = line[:spaceIndex]
- args = (line[spaceIndex + 1:],)
- else:
- cmd = line
- args = ()
- d = defer.maybeDeferred(self.processCommand, cmd, *args)
- d.addCallbacks(processSucceeded, processFailed)
- d.addErrback(log.err)
-
- # XXX It burnsss
- # LineReceiver doesn't let you resumeProducing inside
- # lineReceived atm
- from twisted.internet import reactor
- reactor.callLater(0, d.addBoth, allDone)
-
-
- def processCommand(self, cmd, *params):
- cmd = cmd.upper()
-
- if self.state == self.UNAUTH:
- if cmd == 'USER':
- return self.ftp_USER(*params)
- elif cmd == 'PASS':
- return BAD_CMD_SEQ, "USER required before PASS"
- else:
- return NOT_LOGGED_IN
-
- elif self.state == self.INAUTH:
- if cmd == 'PASS':
- return self.ftp_PASS(*params)
- else:
- return BAD_CMD_SEQ, "PASS required after USER"
-
- elif self.state == self.AUTHED:
- method = getattr(self, "ftp_" + cmd, None)
- if method is not None:
- return method(*params)
- return defer.fail(CmdNotImplementedError(cmd))
-
- elif self.state == self.RENAMING:
- if cmd == 'RNTO':
- return self.ftp_RNTO(*params)
- else:
- return BAD_CMD_SEQ, "RNTO required after RNFR"
-
-
- def getDTPPort(self, factory):
- """
- Return a port for passive access, using C{self.passivePortRange}
- attribute.
- """
- for portn in self.passivePortRange:
- try:
- dtpPort = self.listenFactory(portn, factory)
- except error.CannotListenError:
- continue
- else:
- return dtpPort
- raise error.CannotListenError('', portn,
- "No port available in range %s" %
- (self.passivePortRange,))
-
-
- def ftp_USER(self, username):
- """
- First part of login. Get the username the peer wants to
- authenticate as.
- """
- if not username:
- return defer.fail(CmdSyntaxError('USER requires an argument'))
-
- self._user = username
- self.state = self.INAUTH
- if self.factory.allowAnonymous and self._user == self.factory.userAnonymous:
- return GUEST_NAME_OK_NEED_EMAIL
- else:
- return (USR_NAME_OK_NEED_PASS, username)
-
- # TODO: add max auth try before timeout from ip...
- # TODO: need to implement minimal ABOR command
-
- def ftp_PASS(self, password):
- """
- Second part of login. Get the password the peer wants to
- authenticate with.
- """
- if self.factory.allowAnonymous and self._user == self.factory.userAnonymous:
- # anonymous login
- creds = credentials.Anonymous()
- reply = GUEST_LOGGED_IN_PROCEED
- else:
- # user login
- creds = credentials.UsernamePassword(self._user, password)
- reply = USR_LOGGED_IN_PROCEED
- del self._user
-
- def _cbLogin((interface, avatar, logout)):
- assert interface is IFTPShell, "The realm is busted, jerk."
- self.shell = avatar
- self.logout = logout
- self.workingDirectory = []
- self.state = self.AUTHED
- return reply
-
- def _ebLogin(failure):
- failure.trap(cred_error.UnauthorizedLogin, cred_error.UnhandledCredentials)
- self.state = self.UNAUTH
- raise AuthorizationError
-
- d = self.portal.login(creds, None, IFTPShell)
- d.addCallbacks(_cbLogin, _ebLogin)
- return d
-
-
- def ftp_PASV(self):
- """Request for a passive connection
-
- from the rfc::
-
- This command requests the server-DTP to \"listen\" on a data port
- (which is not its default data port) and to wait for a connection
- rather than initiate one upon receipt of a transfer command. The
- response to this command includes the host and port address this
- server is listening on.
- """
- # if we have a DTP port set up, lose it.
- if self.dtpFactory is not None:
- # cleanupDTP sets dtpFactory to none. Later we'll do
- # cleanup here or something.
- self.cleanupDTP()
- self.dtpFactory = DTPFactory(pi=self)
- self.dtpFactory.setTimeout(self.dtpTimeout)
- self.dtpPort = self.getDTPPort(self.dtpFactory)
-
- host = self.transport.getHost().host
- port = self.dtpPort.getHost().port
- self.reply(ENTERING_PASV_MODE, encodeHostPort(host, port))
- return self.dtpFactory.deferred.addCallback(lambda ign: None)
-
-
- def ftp_PORT(self, address):
- addr = map(int, address.split(','))
- ip = '%d.%d.%d.%d' % tuple(addr[:4])
- port = addr[4] << 8 | addr[5]
-
- # if we have a DTP port set up, lose it.
- if self.dtpFactory is not None:
- self.cleanupDTP()
-
- self.dtpFactory = DTPFactory(pi=self, peerHost=self.transport.getPeer().host)
- self.dtpFactory.setTimeout(self.dtpTimeout)
- self.dtpPort = reactor.connectTCP(ip, port, self.dtpFactory)
-
- def connected(ignored):
- return ENTERING_PORT_MODE
- def connFailed(err):
- err.trap(PortConnectionError)
- return CANT_OPEN_DATA_CNX
- return self.dtpFactory.deferred.addCallbacks(connected, connFailed)
-
-
- def ftp_LIST(self, path=''):
- """ This command causes a list to be sent from the server to the
- passive DTP. If the pathname specifies a directory or other
- group of files, the server should transfer a list of files
- in the specified directory. If the pathname specifies a
- file then the server should send current information on the
- file. A null argument implies the user's current working or
- default directory.
- """
- # Uh, for now, do this retarded thing.
- if self.dtpInstance is None or not self.dtpInstance.isConnected:
- return defer.fail(BadCmdSequenceError('must send PORT or PASV before RETR'))
-
- # bug in konqueror
- if path == "-a":
- path = ''
- # bug in gFTP 2.0.15
- if path == "-aL":
- path = ''
- # bug in Nautilus 2.10.0
- if path == "-L":
- path = ''
- # bug in ange-ftp
- if path == "-la":
- path = ''
-
- def gotListing(results):
- self.reply(DATA_CNX_ALREADY_OPEN_START_XFR)
- for (name, attrs) in results:
- self.dtpInstance.sendListResponse(name, attrs)
- self.dtpInstance.transport.loseConnection()
- return (TXFR_COMPLETE_OK,)
-
- try:
- segments = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
-
- d = self.shell.list(
- segments,
- ('size', 'directory', 'permissions', 'hardlinks',
- 'modified', 'owner', 'group'))
- d.addCallback(gotListing)
- return d
-
-
- def ftp_NLST(self, path):
- """
- This command causes a directory listing to be sent from the server to
- the client. The pathname should specify a directory or other
- system-specific file group descriptor. An empty path implies the current
- working directory. If the path is non-existent, send nothing. If the
- path is to a file, send only the file name.
-
- @type path: C{str}
- @param path: The path for which a directory listing should be returned.
-
- @rtype: L{Deferred}
- @return: a L{Deferred} which will be fired when the listing request
- is finished.
- """
- # XXX: why is this check different from ftp_RETR/ftp_STOR? See #4180
- if self.dtpInstance is None or not self.dtpInstance.isConnected:
- return defer.fail(
- BadCmdSequenceError('must send PORT or PASV before RETR'))
-
- try:
- segments = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
-
- def cbList(results):
- """
- Send, line by line, each file in the directory listing, and then
- close the connection.
-
- @type results: A C{list} of C{tuple}. The first element of each
- C{tuple} is a C{str} and the second element is a C{list}.
- @param results: The names of the files in the directory.
-
- @rtype: C{tuple}
- @return: A C{tuple} containing the status code for a successful
- transfer.
- """
- self.reply(DATA_CNX_ALREADY_OPEN_START_XFR)
- for (name, ignored) in results:
- self.dtpInstance.sendLine(name)
- self.dtpInstance.transport.loseConnection()
- return (TXFR_COMPLETE_OK,)
-
- def cbGlob(results):
- self.reply(DATA_CNX_ALREADY_OPEN_START_XFR)
- for (name, ignored) in results:
- if fnmatch.fnmatch(name, segments[-1]):
- self.dtpInstance.sendLine(name)
- self.dtpInstance.transport.loseConnection()
- return (TXFR_COMPLETE_OK,)
-
- def listErr(results):
- """
- RFC 959 specifies that an NLST request may only return directory
- listings. Thus, send nothing and just close the connection.
-
- @type results: L{Failure}
- @param results: The L{Failure} wrapping a L{FileNotFoundError} that
- occurred while trying to list the contents of a nonexistent
- directory.
-
- @rtype: C{tuple}
- @returns: A C{tuple} containing the status code for a successful
- transfer.
- """
- self.dtpInstance.transport.loseConnection()
- return (TXFR_COMPLETE_OK,)
-
- # XXX This globbing may be incomplete: see #4181
- if segments and (
- '*' in segments[-1] or '?' in segments[-1] or
- ('[' in segments[-1] and ']' in segments[-1])):
- d = self.shell.list(segments[:-1])
- d.addCallback(cbGlob)
- else:
- d = self.shell.list(segments)
- d.addCallback(cbList)
- # self.shell.list will generate an error if the path is invalid
- d.addErrback(listErr)
- return d
-
-
- def ftp_CWD(self, path):
- try:
- segments = toSegments(self.workingDirectory, path)
- except InvalidPath:
- # XXX Eh, what to fail with here?
- return defer.fail(FileNotFoundError(path))
-
- def accessGranted(result):
- self.workingDirectory = segments
- return (REQ_FILE_ACTN_COMPLETED_OK,)
-
- return self.shell.access(segments).addCallback(accessGranted)
-
-
- def ftp_CDUP(self):
- return self.ftp_CWD('..')
-
-
- def ftp_PWD(self):
- return (PWD_REPLY, '/' + '/'.join(self.workingDirectory))
-
-
- def ftp_RETR(self, path):
- """
- This command causes the content of a file to be sent over the data
- transfer channel. If the path is to a folder, an error will be raised.
-
- @type path: C{str}
- @param path: The path to the file which should be transferred over the
- data transfer channel.
-
- @rtype: L{Deferred}
- @return: a L{Deferred} which will be fired when the transfer is done.
- """
- if self.dtpInstance is None:
- raise BadCmdSequenceError('PORT or PASV required before RETR')
-
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
-
- # XXX For now, just disable the timeout. Later we'll want to
- # leave it active and have the DTP connection reset it
- # periodically.
- self.setTimeout(None)
-
- # Put it back later
- def enableTimeout(result):
- self.setTimeout(self.factory.timeOut)
- return result
-
- # And away she goes
- if not self.binary:
- cons = ASCIIConsumerWrapper(self.dtpInstance)
- else:
- cons = self.dtpInstance
-
- def cbSent(result):
- return (TXFR_COMPLETE_OK,)
-
- def ebSent(err):
- log.msg("Unexpected error attempting to transmit file to client:")
- log.err(err)
- if err.check(FTPCmdError):
- return err
- return (CNX_CLOSED_TXFR_ABORTED,)
-
- def cbOpened(file):
- # Tell them what to doooo
- if self.dtpInstance.isConnected:
- self.reply(DATA_CNX_ALREADY_OPEN_START_XFR)
- else:
- self.reply(FILE_STATUS_OK_OPEN_DATA_CNX)
-
- d = file.send(cons)
- d.addCallbacks(cbSent, ebSent)
- return d
-
- def ebOpened(err):
- if not err.check(PermissionDeniedError, FileNotFoundError, IsADirectoryError):
- log.msg("Unexpected error attempting to open file for transmission:")
- log.err(err)
- if err.check(FTPCmdError):
- return (err.value.errorCode, '/'.join(newsegs))
- return (FILE_NOT_FOUND, '/'.join(newsegs))
-
- d = self.shell.openForReading(newsegs)
- d.addCallbacks(cbOpened, ebOpened)
- d.addBoth(enableTimeout)
-
- # Pass back Deferred that fires when the transfer is done
- return d
-
-
- def ftp_STOR(self, path):
- if self.dtpInstance is None:
- raise BadCmdSequenceError('PORT or PASV required before STOR')
-
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
-
- # XXX For now, just disable the timeout. Later we'll want to
- # leave it active and have the DTP connection reset it
- # periodically.
- self.setTimeout(None)
-
- # Put it back later
- def enableTimeout(result):
- self.setTimeout(self.factory.timeOut)
- return result
-
- def cbSent(result):
- return (TXFR_COMPLETE_OK,)
-
- def ebSent(err):
- log.msg("Unexpected error receiving file from client:")
- log.err(err)
- if err.check(FTPCmdError):
- return err
- return (CNX_CLOSED_TXFR_ABORTED,)
-
- def cbConsumer(cons):
- if not self.binary:
- cons = ASCIIConsumerWrapper(cons)
-
- d = self.dtpInstance.registerConsumer(cons)
-
- # Tell them what to doooo
- if self.dtpInstance.isConnected:
- self.reply(DATA_CNX_ALREADY_OPEN_START_XFR)
- else:
- self.reply(FILE_STATUS_OK_OPEN_DATA_CNX)
-
- return d
-
- def cbOpened(file):
- d = file.receive()
- d.addCallback(cbConsumer)
- d.addCallback(lambda ignored: file.close())
- d.addCallbacks(cbSent, ebSent)
- return d
-
- def ebOpened(err):
- if not err.check(PermissionDeniedError, FileNotFoundError, IsNotADirectoryError):
- log.msg("Unexpected error attempting to open file for upload:")
- log.err(err)
- if isinstance(err.value, FTPCmdError):
- return (err.value.errorCode, '/'.join(newsegs))
- return (FILE_NOT_FOUND, '/'.join(newsegs))
-
- d = self.shell.openForWriting(newsegs)
- d.addCallbacks(cbOpened, ebOpened)
- d.addBoth(enableTimeout)
-
- # Pass back Deferred that fires when the transfer is done
- return d
-
-
- def ftp_SIZE(self, path):
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
-
- def cbStat((size,)):
- return (FILE_STATUS, str(size))
-
- return self.shell.stat(newsegs, ('size',)).addCallback(cbStat)
-
-
- def ftp_MDTM(self, path):
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
-
- def cbStat((modified,)):
- return (FILE_STATUS, time.strftime('%Y%m%d%H%M%S', time.gmtime(modified)))
-
- return self.shell.stat(newsegs, ('modified',)).addCallback(cbStat)
-
-
- def ftp_TYPE(self, type):
- p = type.upper()
- if p:
- f = getattr(self, 'type_' + p[0], None)
- if f is not None:
- return f(p[1:])
- return self.type_UNKNOWN(p)
- return (SYNTAX_ERR,)
-
- def type_A(self, code):
- if code == '' or code == 'N':
- self.binary = False
- return (TYPE_SET_OK, 'A' + code)
- else:
- return defer.fail(CmdArgSyntaxError(code))
-
- def type_I(self, code):
- if code == '':
- self.binary = True
- return (TYPE_SET_OK, 'I')
- else:
- return defer.fail(CmdArgSyntaxError(code))
-
- def type_UNKNOWN(self, code):
- return defer.fail(CmdNotImplementedForArgError(code))
-
-
-
- def ftp_SYST(self):
- return NAME_SYS_TYPE
-
-
- def ftp_STRU(self, structure):
- p = structure.upper()
- if p == 'F':
- return (CMD_OK,)
- return defer.fail(CmdNotImplementedForArgError(structure))
-
-
- def ftp_MODE(self, mode):
- p = mode.upper()
- if p == 'S':
- return (CMD_OK,)
- return defer.fail(CmdNotImplementedForArgError(mode))
-
-
- def ftp_MKD(self, path):
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
- return self.shell.makeDirectory(newsegs).addCallback(lambda ign: (MKD_REPLY, path))
-
-
- def ftp_RMD(self, path):
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
- return self.shell.removeDirectory(newsegs).addCallback(lambda ign: (REQ_FILE_ACTN_COMPLETED_OK,))
-
-
- def ftp_DELE(self, path):
- try:
- newsegs = toSegments(self.workingDirectory, path)
- except InvalidPath:
- return defer.fail(FileNotFoundError(path))
- return self.shell.removeFile(newsegs).addCallback(lambda ign: (REQ_FILE_ACTN_COMPLETED_OK,))
-
-
- def ftp_NOOP(self):
- return (CMD_OK,)
-
-
- def ftp_RNFR(self, fromName):
- self._fromName = fromName
- self.state = self.RENAMING
- return (REQ_FILE_ACTN_PENDING_FURTHER_INFO,)
-
-
- def ftp_RNTO(self, toName):
- fromName = self._fromName
- del self._fromName
- self.state = self.AUTHED
-
- try:
- fromsegs = toSegments(self.workingDirectory, fromName)
- tosegs = toSegments(self.workingDirectory, toName)
- except InvalidPath:
- return defer.fail(FileNotFoundError(fromName))
- return self.shell.rename(fromsegs, tosegs).addCallback(lambda ign: (REQ_FILE_ACTN_COMPLETED_OK,))
-
-
- def ftp_QUIT(self):
- self.reply(GOODBYE_MSG)
- self.transport.loseConnection()
- self.disconnected = True
-
-
- def cleanupDTP(self):
- """call when DTP connection exits
- """
- log.msg('cleanupDTP', debug=True)
-
- log.msg(self.dtpPort)
- dtpPort, self.dtpPort = self.dtpPort, None
- if interfaces.IListeningPort.providedBy(dtpPort):
- dtpPort.stopListening()
- elif interfaces.IConnector.providedBy(dtpPort):
- dtpPort.disconnect()
- else:
- assert False, "dtpPort should be an IListeningPort or IConnector, instead is %r" % (dtpPort,)
-
- self.dtpFactory.stopFactory()
- self.dtpFactory = None
-
- if self.dtpInstance is not None:
- self.dtpInstance = None
-
-
-class FTPFactory(policies.LimitTotalConnectionsFactory):
- """
- A factory for producing ftp protocol instances
-
- @ivar timeOut: the protocol interpreter's idle timeout time in seconds,
- default is 600 seconds.
-
- @ivar passivePortRange: value forwarded to C{protocol.passivePortRange}.
- @type passivePortRange: C{iterator}
- """
- protocol = FTP
- overflowProtocol = FTPOverflowProtocol
- allowAnonymous = True
- userAnonymous = 'anonymous'
- timeOut = 600
-
- welcomeMessage = "Twisted %s FTP Server" % (copyright.version,)
-
- passivePortRange = xrange(0, 1)
-
- def __init__(self, portal=None, userAnonymous='anonymous'):
- self.portal = portal
- self.userAnonymous = userAnonymous
- self.instances = []
-
- def buildProtocol(self, addr):
- p = policies.LimitTotalConnectionsFactory.buildProtocol(self, addr)
- if p is not None:
- p.wrappedProtocol.portal = self.portal
- p.wrappedProtocol.timeOut = self.timeOut
- p.wrappedProtocol.passivePortRange = self.passivePortRange
- return p
-
- def stopFactory(self):
- # make sure ftp instance's timeouts are set to None
- # to avoid reactor complaints
- [p.setTimeout(None) for p in self.instances if p.timeOut is not None]
- policies.LimitTotalConnectionsFactory.stopFactory(self)
-
-# -- Cred Objects --
-
-
-class IFTPShell(Interface):
- """
- An abstraction of the shell commands used by the FTP protocol for
- a given user account.
-
- All path names must be absolute.
- """
-
- def makeDirectory(path):
- """
- Create a directory.
-
- @param path: The path, as a list of segments, to create
- @type path: C{list} of C{unicode}
-
- @return: A Deferred which fires when the directory has been
- created, or which fails if the directory cannot be created.
- """
-
-
- def removeDirectory(path):
- """
- Remove a directory.
-
- @param path: The path, as a list of segments, to remove
- @type path: C{list} of C{unicode}
-
- @return: A Deferred which fires when the directory has been
- removed, or which fails if the directory cannot be removed.
- """
-
-
- def removeFile(path):
- """
- Remove a file.
-
- @param path: The path, as a list of segments, to remove
- @type path: C{list} of C{unicode}
-
- @return: A Deferred which fires when the file has been
- removed, or which fails if the file cannot be removed.
- """
-
-
- def rename(fromPath, toPath):
- """
- Rename a file or directory.
-
- @param fromPath: The current name of the path.
- @type fromPath: C{list} of C{unicode}
-
- @param toPath: The desired new name of the path.
- @type toPath: C{list} of C{unicode}
-
- @return: A Deferred which fires when the path has been
- renamed, or which fails if the path cannot be renamed.
- """
-
-
- def access(path):
- """
- Determine whether access to the given path is allowed.
-
- @param path: The path, as a list of segments
-
- @return: A Deferred which fires with None if access is allowed
- or which fails with a specific exception type if access is
- denied.
- """
-
-
- def stat(path, keys=()):
- """
- Retrieve information about the given path.
-
- This is like list, except it will never return results about
- child paths.
- """
-
-
- def list(path, keys=()):
- """
- Retrieve information about the given path.
-
- If the path represents a non-directory, the result list should
- have only one entry with information about that non-directory.
- Otherwise, the result list should have an element for each
- child of the directory.
-
- @param path: The path, as a list of segments, to list
- @type path: C{list} of C{unicode}
-
- @param keys: A tuple of keys desired in the resulting
- dictionaries.
-
- @return: A Deferred which fires with a list of (name, list),
- where the name is the name of the entry as a unicode string
- and each list contains values corresponding to the requested
- keys. The following are possible elements of keys, and the
- values which should be returned for them:
-
- - C{'size'}: size in bytes, as an integer (this is kinda required)
-
- - C{'directory'}: boolean indicating the type of this entry
-
- - C{'permissions'}: a bitvector (see os.stat(foo).st_mode)
-
- - C{'hardlinks'}: Number of hard links to this entry
-
- - C{'modified'}: number of seconds since the epoch since entry was
- modified
-
- - C{'owner'}: string indicating the user owner of this entry
-
- - C{'group'}: string indicating the group owner of this entry
- """
-
-
- def openForReading(path):
- """
- @param path: The path, as a list of segments, to open
- @type path: C{list} of C{unicode}
-
- @rtype: C{Deferred} which will fire with L{IReadFile}
- """
-
-
- def openForWriting(path):
- """
- @param path: The path, as a list of segments, to open
- @type path: C{list} of C{unicode}
-
- @rtype: C{Deferred} which will fire with L{IWriteFile}
- """
-
-
-
-class IReadFile(Interface):
- """
- A file out of which bytes may be read.
- """
-
- def send(consumer):
- """
- Produce the contents of the given path to the given consumer. This
- method may only be invoked once on each provider.
-
- @type consumer: C{IConsumer}
-
- @return: A Deferred which fires when the file has been
- consumed completely.
- """
-
-
-
-class IWriteFile(Interface):
- """
- A file into which bytes may be written.
- """
-
- def receive():
- """
- Create a consumer which will write to this file. This method may
- only be invoked once on each provider.
-
- @rtype: C{Deferred} of C{IConsumer}
- """
-
- def close():
- """
- Perform any post-write work that needs to be done. This method may
- only be invoked once on each provider, and will always be invoked
- after receive().
-
- @rtype: C{Deferred} of anything: the value is ignored. The FTP client
- will not see their upload request complete until this Deferred has
- been fired.
- """
-
-def _getgroups(uid):
- """Return the primary and supplementary groups for the given UID.
-
- @type uid: C{int}
- """
- result = []
- pwent = pwd.getpwuid(uid)
-
- result.append(pwent.pw_gid)
-
- for grent in grp.getgrall():
- if pwent.pw_name in grent.gr_mem:
- result.append(grent.gr_gid)
-
- return result
-
-
-def _testPermissions(uid, gid, spath, mode='r'):
- """
- checks to see if uid has proper permissions to access path with mode
-
- @type uid: C{int}
- @param uid: numeric user id
-
- @type gid: C{int}
- @param gid: numeric group id
-
- @type spath: C{str}
- @param spath: the path on the server to test
-
- @type mode: C{str}
- @param mode: 'r' or 'w' (read or write)
-
- @rtype: C{bool}
- @return: True if the given credentials have the specified form of
- access to the given path
- """
- if mode == 'r':
- usr = stat.S_IRUSR
- grp = stat.S_IRGRP
- oth = stat.S_IROTH
- amode = os.R_OK
- elif mode == 'w':
- usr = stat.S_IWUSR
- grp = stat.S_IWGRP
- oth = stat.S_IWOTH
- amode = os.W_OK
- else:
- raise ValueError("Invalid mode %r: must specify 'r' or 'w'" % (mode,))
-
- access = False
- if os.path.exists(spath):
- if uid == 0:
- access = True
- else:
- s = os.stat(spath)
- if usr & s.st_mode and uid == s.st_uid:
- access = True
- elif grp & s.st_mode and gid in _getgroups(uid):
- access = True
- elif oth & s.st_mode:
- access = True
-
- if access:
- if not os.access(spath, amode):
- access = False
- log.msg("Filesystem grants permission to UID %d but it is inaccessible to me running as UID %d" % (
- uid, os.getuid()))
- return access
-
-
-
-class FTPAnonymousShell(object):
- """
- An anonymous implementation of IFTPShell
-
- @type filesystemRoot: L{twisted.python.filepath.FilePath}
- @ivar filesystemRoot: The path which is considered the root of
- this shell.
- """
- implements(IFTPShell)
-
- def __init__(self, filesystemRoot):
- self.filesystemRoot = filesystemRoot
-
-
- def _path(self, path):
- return reduce(filepath.FilePath.child, path, self.filesystemRoot)
-
-
- def makeDirectory(self, path):
- return defer.fail(AnonUserDeniedError())
-
-
- def removeDirectory(self, path):
- return defer.fail(AnonUserDeniedError())
-
-
- def removeFile(self, path):
- return defer.fail(AnonUserDeniedError())
-
-
- def rename(self, fromPath, toPath):
- return defer.fail(AnonUserDeniedError())
-
-
- def receive(self, path):
- path = self._path(path)
- return defer.fail(AnonUserDeniedError())
-
-
- def openForReading(self, path):
- """
- Open C{path} for reading.
-
- @param path: The path, as a list of segments, to open.
- @type path: C{list} of C{unicode}
- @return: A L{Deferred} is returned that will fire with an object
- implementing L{IReadFile} if the file is successfully opened. If
- C{path} is a directory, or if an exception is raised while trying
- to open the file, the L{Deferred} will fire with an error.
- """
- p = self._path(path)
- if p.isdir():
- # Normally, we would only check for EISDIR in open, but win32
- # returns EACCES in this case, so we check before
- return defer.fail(IsADirectoryError(path))
- try:
- f = p.open('r')
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- else:
- return defer.succeed(_FileReader(f))
-
-
- def openForWriting(self, path):
- """
- Reject write attempts by anonymous users with
- L{PermissionDeniedError}.
- """
- return defer.fail(PermissionDeniedError("STOR not allowed"))
-
-
- def access(self, path):
- p = self._path(path)
- if not p.exists():
- # Again, win32 doesn't report a sane error after, so let's fail
- # early if we can
- return defer.fail(FileNotFoundError(path))
- # For now, just see if we can os.listdir() it
- try:
- p.listdir()
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- else:
- return defer.succeed(None)
-
-
- def stat(self, path, keys=()):
- p = self._path(path)
- if p.isdir():
- try:
- statResult = self._statNode(p, keys)
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- else:
- return defer.succeed(statResult)
- else:
- return self.list(path, keys).addCallback(lambda res: res[0][1])
-
-
- def list(self, path, keys=()):
- """
- Return the list of files at given C{path}, adding C{keys} stat
- informations if specified.
-
- @param path: the directory or file to check.
- @type path: C{str}
-
- @param keys: the list of desired metadata
- @type keys: C{list} of C{str}
- """
- filePath = self._path(path)
- if filePath.isdir():
- entries = filePath.listdir()
- fileEntries = [filePath.child(p) for p in entries]
- elif filePath.isfile():
- entries = [os.path.join(*filePath.segmentsFrom(self.filesystemRoot))]
- fileEntries = [filePath]
- else:
- return defer.fail(FileNotFoundError(path))
-
- results = []
- for fileName, filePath in zip(entries, fileEntries):
- ent = []
- results.append((fileName, ent))
- if keys:
- try:
- ent.extend(self._statNode(filePath, keys))
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, fileName)
- except:
- return defer.fail()
-
- return defer.succeed(results)
-
-
- def _statNode(self, filePath, keys):
- """
- Shortcut method to get stat info on a node.
-
- @param filePath: the node to stat.
- @type filePath: C{filepath.FilePath}
-
- @param keys: the stat keys to get.
- @type keys: C{iterable}
- """
- filePath.restat()
- return [getattr(self, '_stat_' + k)(filePath.statinfo) for k in keys]
-
- _stat_size = operator.attrgetter('st_size')
- _stat_permissions = operator.attrgetter('st_mode')
- _stat_hardlinks = operator.attrgetter('st_nlink')
- _stat_modified = operator.attrgetter('st_mtime')
-
-
- def _stat_owner(self, st):
- if pwd is not None:
- try:
- return pwd.getpwuid(st.st_uid)[0]
- except KeyError:
- pass
- return str(st.st_uid)
-
-
- def _stat_group(self, st):
- if grp is not None:
- try:
- return grp.getgrgid(st.st_gid)[0]
- except KeyError:
- pass
- return str(st.st_gid)
-
-
- def _stat_directory(self, st):
- return bool(st.st_mode & stat.S_IFDIR)
-
-
-
-class _FileReader(object):
- implements(IReadFile)
-
- def __init__(self, fObj):
- self.fObj = fObj
- self._send = False
-
- def _close(self, passthrough):
- self._send = True
- self.fObj.close()
- return passthrough
-
- def send(self, consumer):
- assert not self._send, "Can only call IReadFile.send *once* per instance"
- self._send = True
- d = basic.FileSender().beginFileTransfer(self.fObj, consumer)
- d.addBoth(self._close)
- return d
-
-
-
-class FTPShell(FTPAnonymousShell):
- """
- An authenticated implementation of L{IFTPShell}.
- """
-
- def makeDirectory(self, path):
- p = self._path(path)
- try:
- p.makedirs()
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- else:
- return defer.succeed(None)
-
-
- def removeDirectory(self, path):
- p = self._path(path)
- if p.isfile():
- # Win32 returns the wrong errno when rmdir is called on a file
- # instead of a directory, so as we have the info here, let's fail
- # early with a pertinent error
- return defer.fail(IsNotADirectoryError(path))
- try:
- os.rmdir(p.path)
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- else:
- return defer.succeed(None)
-
-
- def removeFile(self, path):
- p = self._path(path)
- if p.isdir():
- # Win32 returns the wrong errno when remove is called on a
- # directory instead of a file, so as we have the info here,
- # let's fail early with a pertinent error
- return defer.fail(IsADirectoryError(path))
- try:
- p.remove()
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- else:
- return defer.succeed(None)
-
-
- def rename(self, fromPath, toPath):
- fp = self._path(fromPath)
- tp = self._path(toPath)
- try:
- os.rename(fp.path, tp.path)
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, fromPath)
- except:
- return defer.fail()
- else:
- return defer.succeed(None)
-
-
- def openForWriting(self, path):
- """
- Open C{path} for writing.
-
- @param path: The path, as a list of segments, to open.
- @type path: C{list} of C{unicode}
- @return: A L{Deferred} is returned that will fire with an object
- implementing L{IWriteFile} if the file is successfully opened. If
- C{path} is a directory, or if an exception is raised while trying
- to open the file, the L{Deferred} will fire with an error.
- """
- p = self._path(path)
- if p.isdir():
- # Normally, we would only check for EISDIR in open, but win32
- # returns EACCES in this case, so we check before
- return defer.fail(IsADirectoryError(path))
- try:
- fObj = p.open('w')
- except (IOError, OSError), e:
- return errnoToFailure(e.errno, path)
- except:
- return defer.fail()
- return defer.succeed(_FileWriter(fObj))
-
-
-
-class _FileWriter(object):
- implements(IWriteFile)
-
- def __init__(self, fObj):
- self.fObj = fObj
- self._receive = False
-
- def receive(self):
- assert not self._receive, "Can only call IWriteFile.receive *once* per instance"
- self._receive = True
- # FileConsumer will close the file object
- return defer.succeed(FileConsumer(self.fObj))
-
- def close(self):
- return defer.succeed(None)
-
-
-
-class BaseFTPRealm:
- """
- Base class for simple FTP realms which provides an easy hook for specifying
- the home directory for each user.
- """
- implements(portal.IRealm)
-
- def __init__(self, anonymousRoot):
- self.anonymousRoot = filepath.FilePath(anonymousRoot)
-
-
- def getHomeDirectory(self, avatarId):
- """
- Return a L{FilePath} representing the home directory of the given
- avatar. Override this in a subclass.
-
- @param avatarId: A user identifier returned from a credentials checker.
- @type avatarId: C{str}
-
- @rtype: L{FilePath}
- """
- raise NotImplementedError(
- "%r did not override getHomeDirectory" % (self.__class__,))
-
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- for iface in interfaces:
- if iface is IFTPShell:
- if avatarId is checkers.ANONYMOUS:
- avatar = FTPAnonymousShell(self.anonymousRoot)
- else:
- avatar = FTPShell(self.getHomeDirectory(avatarId))
- return (IFTPShell, avatar,
- getattr(avatar, 'logout', lambda: None))
- raise NotImplementedError(
- "Only IFTPShell interface is supported by this realm")
-
-
-
-class FTPRealm(BaseFTPRealm):
- """
- @type anonymousRoot: L{twisted.python.filepath.FilePath}
- @ivar anonymousRoot: Root of the filesystem to which anonymous
- users will be granted access.
-
- @type userHome: L{filepath.FilePath}
- @ivar userHome: Root of the filesystem containing user home directories.
- """
- def __init__(self, anonymousRoot, userHome='/home'):
- BaseFTPRealm.__init__(self, anonymousRoot)
- self.userHome = filepath.FilePath(userHome)
-
-
- def getHomeDirectory(self, avatarId):
- """
- Use C{avatarId} as a single path segment to construct a child of
- C{self.userHome} and return that child.
- """
- return self.userHome.child(avatarId)
-
-
-
-class SystemFTPRealm(BaseFTPRealm):
- """
- L{SystemFTPRealm} uses system user account information to decide what the
- home directory for a particular avatarId is.
-
- This works on POSIX but probably is not reliable on Windows.
- """
- def getHomeDirectory(self, avatarId):
- """
- Return the system-defined home directory of the system user account with
- the name C{avatarId}.
- """
- path = os.path.expanduser('~' + avatarId)
- if path.startswith('~'):
- raise cred_error.UnauthorizedLogin()
- return filepath.FilePath(path)
-
-
-
-# --- FTP CLIENT -------------------------------------------------------------
-
-####
-# And now for the client...
-
-# Notes:
-# * Reference: http://cr.yp.to/ftp.html
-# * FIXME: Does not support pipelining (which is not supported by all
-# servers anyway). This isn't a functionality limitation, just a
-# small performance issue.
-# * Only has a rudimentary understanding of FTP response codes (although
-# the full response is passed to the caller if they so choose).
-# * Assumes that USER and PASS should always be sent
-# * Always sets TYPE I (binary mode)
-# * Doesn't understand any of the weird, obscure TELNET stuff (\377...)
-# * FIXME: Doesn't share any code with the FTPServer
-
-class ConnectionLost(FTPError):
- pass
-
-class CommandFailed(FTPError):
- pass
-
-class BadResponse(FTPError):
- pass
-
-class UnexpectedResponse(FTPError):
- pass
-
-class UnexpectedData(FTPError):
- pass
-
-class FTPCommand:
- def __init__(self, text=None, public=0):
- self.text = text
- self.deferred = defer.Deferred()
- self.ready = 1
- self.public = public
- self.transferDeferred = None
-
- def fail(self, failure):
- if self.public:
- self.deferred.errback(failure)
-
-
-class ProtocolWrapper(protocol.Protocol):
- def __init__(self, original, deferred):
- self.original = original
- self.deferred = deferred
- def makeConnection(self, transport):
- self.original.makeConnection(transport)
- def dataReceived(self, data):
- self.original.dataReceived(data)
- def connectionLost(self, reason):
- self.original.connectionLost(reason)
- # Signal that transfer has completed
- self.deferred.callback(None)
-
-
-
-class IFinishableConsumer(interfaces.IConsumer):
- """
- A Consumer for producers that finish.
-
- @since: 11.0
- """
-
- def finish():
- """
- The producer has finished producing.
- """
-
-
-
-class SenderProtocol(protocol.Protocol):
- implements(IFinishableConsumer)
-
- def __init__(self):
- # Fired upon connection
- self.connectedDeferred = defer.Deferred()
-
- # Fired upon disconnection
- self.deferred = defer.Deferred()
-
- #Protocol stuff
- def dataReceived(self, data):
- raise UnexpectedData(
- "Received data from the server on a "
- "send-only data-connection"
- )
-
- def makeConnection(self, transport):
- protocol.Protocol.makeConnection(self, transport)
- self.connectedDeferred.callback(self)
-
- def connectionLost(self, reason):
- if reason.check(error.ConnectionDone):
- self.deferred.callback('connection done')
- else:
- self.deferred.errback(reason)
-
- #IFinishableConsumer stuff
- def write(self, data):
- self.transport.write(data)
-
- def registerProducer(self, producer, streaming):
- """
- Register the given producer with our transport.
- """
- self.transport.registerProducer(producer, streaming)
-
- def unregisterProducer(self):
- """
- Unregister the previously registered producer.
- """
- self.transport.unregisterProducer()
-
- def finish(self):
- self.transport.loseConnection()
-
-
-def decodeHostPort(line):
- """Decode an FTP response specifying a host and port.
-
- @return: a 2-tuple of (host, port).
- """
- abcdef = re.sub('[^0-9, ]', '', line)
- parsed = [int(p.strip()) for p in abcdef.split(',')]
- for x in parsed:
- if x < 0 or x > 255:
- raise ValueError("Out of range", line, x)
- a, b, c, d, e, f = parsed
- host = "%s.%s.%s.%s" % (a, b, c, d)
- port = (int(e) << 8) + int(f)
- return host, port
-
-def encodeHostPort(host, port):
- numbers = host.split('.') + [str(port >> 8), str(port % 256)]
- return ','.join(numbers)
-
-def _unwrapFirstError(failure):
- failure.trap(defer.FirstError)
- return failure.value.subFailure
-
-class FTPDataPortFactory(protocol.ServerFactory):
- """Factory for data connections that use the PORT command
-
- (i.e. "active" transfers)
- """
- noisy = 0
- def buildProtocol(self, addr):
- # This is a bit hackish -- we already have a Protocol instance,
- # so just return it instead of making a new one
- # FIXME: Reject connections from the wrong address/port
- # (potential security problem)
- self.protocol.factory = self
- self.port.loseConnection()
- return self.protocol
-
-
-class FTPClientBasic(basic.LineReceiver):
- """
- Foundations of an FTP client.
- """
- debug = False
-
- def __init__(self):
- self.actionQueue = []
- self.greeting = None
- self.nextDeferred = defer.Deferred().addCallback(self._cb_greeting)
- self.nextDeferred.addErrback(self.fail)
- self.response = []
- self._failed = 0
-
- def fail(self, error):
- """
- Give an error to any queued deferreds.
- """
- self._fail(error)
-
- def _fail(self, error):
- """
- Errback all queued deferreds.
- """
- if self._failed:
- # We're recursing; bail out here for simplicity
- return error
- self._failed = 1
- if self.nextDeferred:
- try:
- self.nextDeferred.errback(failure.Failure(ConnectionLost('FTP connection lost', error)))
- except defer.AlreadyCalledError:
- pass
- for ftpCommand in self.actionQueue:
- ftpCommand.fail(failure.Failure(ConnectionLost('FTP connection lost', error)))
- return error
-
- def _cb_greeting(self, greeting):
- self.greeting = greeting
-
- def sendLine(self, line):
- """
- (Private) Sends a line, unless line is None.
- """
- if line is None:
- return
- basic.LineReceiver.sendLine(self, line)
-
- def sendNextCommand(self):
- """
- (Private) Processes the next command in the queue.
- """
- ftpCommand = self.popCommandQueue()
- if ftpCommand is None:
- self.nextDeferred = None
- return
- if not ftpCommand.ready:
- self.actionQueue.insert(0, ftpCommand)
- reactor.callLater(1.0, self.sendNextCommand)
- self.nextDeferred = None
- return
-
- # FIXME: this if block doesn't belong in FTPClientBasic, it belongs in
- # FTPClient.
- if ftpCommand.text == 'PORT':
- self.generatePortCommand(ftpCommand)
-
- if self.debug:
- log.msg('<-- %s' % ftpCommand.text)
- self.nextDeferred = ftpCommand.deferred
- self.sendLine(ftpCommand.text)
-
- def queueCommand(self, ftpCommand):
- """
- Add an FTPCommand object to the queue.
-
- If it's the only thing in the queue, and we are connected and we aren't
- waiting for a response of an earlier command, the command will be sent
- immediately.
-
- @param ftpCommand: an L{FTPCommand}
- """
- self.actionQueue.append(ftpCommand)
- if (len(self.actionQueue) == 1 and self.transport is not None and
- self.nextDeferred is None):
- self.sendNextCommand()
-
- def queueStringCommand(self, command, public=1):
- """
- Queues a string to be issued as an FTP command
-
- @param command: string of an FTP command to queue
- @param public: a flag intended for internal use by FTPClient. Don't
- change it unless you know what you're doing.
-
- @return: a L{Deferred} that will be called when the response to the
- command has been received.
- """
- ftpCommand = FTPCommand(command, public)
- self.queueCommand(ftpCommand)
- return ftpCommand.deferred
-
- def popCommandQueue(self):
- """
- Return the front element of the command queue, or None if empty.
- """
- if self.actionQueue:
- return self.actionQueue.pop(0)
- else:
- return None
-
- def queueLogin(self, username, password):
- """
- Login: send the username, send the password.
-
- If the password is C{None}, the PASS command won't be sent. Also, if
- the response to the USER command has a response code of 230 (User logged
- in), then PASS won't be sent either.
- """
- # Prepare the USER command
- deferreds = []
- userDeferred = self.queueStringCommand('USER ' + username, public=0)
- deferreds.append(userDeferred)
-
- # Prepare the PASS command (if a password is given)
- if password is not None:
- passwordCmd = FTPCommand('PASS ' + password, public=0)
- self.queueCommand(passwordCmd)
- deferreds.append(passwordCmd.deferred)
-
- # Avoid sending PASS if the response to USER is 230.
- # (ref: http://cr.yp.to/ftp/user.html#user)
- def cancelPasswordIfNotNeeded(response):
- if response[0].startswith('230'):
- # No password needed!
- self.actionQueue.remove(passwordCmd)
- return response
- userDeferred.addCallback(cancelPasswordIfNotNeeded)
-
- # Error handling.
- for deferred in deferreds:
- # If something goes wrong, call fail
- deferred.addErrback(self.fail)
- # But also swallow the error, so we don't cause spurious errors
- deferred.addErrback(lambda x: None)
-
- def lineReceived(self, line):
- """
- (Private) Parses the response messages from the FTP server.
- """
- # Add this line to the current response
- if self.debug:
- log.msg('--> %s' % line)
- self.response.append(line)
-
- # Bail out if this isn't the last line of a response
- # The last line of response starts with 3 digits followed by a space
- codeIsValid = re.match(r'\d{3} ', line)
- if not codeIsValid:
- return
-
- code = line[0:3]
-
- # Ignore marks
- if code[0] == '1':
- return
-
- # Check that we were expecting a response
- if self.nextDeferred is None:
- self.fail(UnexpectedResponse(self.response))
- return
-
- # Reset the response
- response = self.response
- self.response = []
-
- # Look for a success or error code, and call the appropriate callback
- if code[0] in ('2', '3'):
- # Success
- self.nextDeferred.callback(response)
- elif code[0] in ('4', '5'):
- # Failure
- self.nextDeferred.errback(failure.Failure(CommandFailed(response)))
- else:
- # This shouldn't happen unless something screwed up.
- log.msg('Server sent invalid response code %s' % (code,))
- self.nextDeferred.errback(failure.Failure(BadResponse(response)))
-
- # Run the next command
- self.sendNextCommand()
-
- def connectionLost(self, reason):
- self._fail(reason)
-
-
-
-class _PassiveConnectionFactory(protocol.ClientFactory):
- noisy = False
-
- def __init__(self, protoInstance):
- self.protoInstance = protoInstance
-
- def buildProtocol(self, ignored):
- self.protoInstance.factory = self
- return self.protoInstance
-
- def clientConnectionFailed(self, connector, reason):
- e = FTPError('Connection Failed', reason)
- self.protoInstance.deferred.errback(e)
-
-
-
-class FTPClient(FTPClientBasic):
- """
- L{FTPClient} is a client implementation of the FTP protocol which
- exposes FTP commands as methods which return L{Deferred}s.
-
- Each command method returns a L{Deferred} which is called back when a
- successful response code (2xx or 3xx) is received from the server or
- which is error backed if an error response code (4xx or 5xx) is received
- from the server or if a protocol violation occurs. If an error response
- code is received, the L{Deferred} fires with a L{Failure} wrapping a
- L{CommandFailed} instance. The L{CommandFailed} instance is created
- with a list of the response lines received from the server.
-
- See U{RFC 959<http://www.ietf.org/rfc/rfc959.txt>} for error code
- definitions.
-
- Both active and passive transfers are supported.
-
- @ivar passive: See description in __init__.
- """
- connectFactory = reactor.connectTCP
-
- def __init__(self, username='anonymous',
- password='twisted@twistedmatrix.com',
- passive=1):
- """
- Constructor.
-
- I will login as soon as I receive the welcome message from the server.
-
- @param username: FTP username
- @param password: FTP password
- @param passive: flag that controls if I use active or passive data
- connections. You can also change this after construction by
- assigning to C{self.passive}.
- """
- FTPClientBasic.__init__(self)
- self.queueLogin(username, password)
-
- self.passive = passive
-
- def fail(self, error):
- """
- Disconnect, and also give an error to any queued deferreds.
- """
- self.transport.loseConnection()
- self._fail(error)
-
- def receiveFromConnection(self, commands, protocol):
- """
- Retrieves a file or listing generated by the given command,
- feeding it to the given protocol.
-
- @param commands: list of strings of FTP commands to execute then receive
- the results of (e.g. C{LIST}, C{RETR})
- @param protocol: A L{Protocol} B{instance} e.g. an
- L{FTPFileListProtocol}, or something that can be adapted to one.
- Typically this will be an L{IConsumer} implementation.
-
- @return: L{Deferred}.
- """
- protocol = interfaces.IProtocol(protocol)
- wrapper = ProtocolWrapper(protocol, defer.Deferred())
- return self._openDataConnection(commands, wrapper)
-
- def queueLogin(self, username, password):
- """
- Login: send the username, send the password, and
- set retrieval mode to binary
- """
- FTPClientBasic.queueLogin(self, username, password)
- d = self.queueStringCommand('TYPE I', public=0)
- # If something goes wrong, call fail
- d.addErrback(self.fail)
- # But also swallow the error, so we don't cause spurious errors
- d.addErrback(lambda x: None)
-
- def sendToConnection(self, commands):
- """
- XXX
-
- @return: A tuple of two L{Deferred}s:
- - L{Deferred} L{IFinishableConsumer}. You must call
- the C{finish} method on the IFinishableConsumer when the file
- is completely transferred.
- - L{Deferred} list of control-connection responses.
- """
- s = SenderProtocol()
- r = self._openDataConnection(commands, s)
- return (s.connectedDeferred, r)
-
- def _openDataConnection(self, commands, protocol):
- """
- This method returns a DeferredList.
- """
- cmds = [FTPCommand(command, public=1) for command in commands]
- cmdsDeferred = defer.DeferredList([cmd.deferred for cmd in cmds],
- fireOnOneErrback=True, consumeErrors=True)
- cmdsDeferred.addErrback(_unwrapFirstError)
-
- if self.passive:
- # Hack: use a mutable object to sneak a variable out of the
- # scope of doPassive
- _mutable = [None]
- def doPassive(response):
- """Connect to the port specified in the response to PASV"""
- host, port = decodeHostPort(response[-1][4:])
-
- f = _PassiveConnectionFactory(protocol)
- _mutable[0] = self.connectFactory(host, port, f)
-
- pasvCmd = FTPCommand('PASV')
- self.queueCommand(pasvCmd)
- pasvCmd.deferred.addCallback(doPassive).addErrback(self.fail)
-
- results = [cmdsDeferred, pasvCmd.deferred, protocol.deferred]
- d = defer.DeferredList(results, fireOnOneErrback=True, consumeErrors=True)
- d.addErrback(_unwrapFirstError)
-
- # Ensure the connection is always closed
- def close(x, m=_mutable):
- m[0] and m[0].disconnect()
- return x
- d.addBoth(close)
-
- else:
- # We just place a marker command in the queue, and will fill in
- # the host and port numbers later (see generatePortCommand)
- portCmd = FTPCommand('PORT')
-
- # Ok, now we jump through a few hoops here.
- # This is the problem: a transfer is not to be trusted as complete
- # until we get both the "226 Transfer complete" message on the
- # control connection, and the data socket is closed. Thus, we use
- # a DeferredList to make sure we only fire the callback at the
- # right time.
-
- portCmd.transferDeferred = protocol.deferred
- portCmd.protocol = protocol
- portCmd.deferred.addErrback(portCmd.transferDeferred.errback)
- self.queueCommand(portCmd)
-
- # Create dummy functions for the next callback to call.
- # These will also be replaced with real functions in
- # generatePortCommand.
- portCmd.loseConnection = lambda result: result
- portCmd.fail = lambda error: error
-
- # Ensure that the connection always gets closed
- cmdsDeferred.addErrback(lambda e, pc=portCmd: pc.fail(e) or e)
-
- results = [cmdsDeferred, portCmd.deferred, portCmd.transferDeferred]
- d = defer.DeferredList(results, fireOnOneErrback=True, consumeErrors=True)
- d.addErrback(_unwrapFirstError)
-
- for cmd in cmds:
- self.queueCommand(cmd)
- return d
-
- def generatePortCommand(self, portCmd):
- """
- (Private) Generates the text of a given PORT command.
- """
-
- # The problem is that we don't create the listening port until we need
- # it for various reasons, and so we have to muck about to figure out
- # what interface and port it's listening on, and then finally we can
- # create the text of the PORT command to send to the FTP server.
-
- # FIXME: This method is far too ugly.
-
- # FIXME: The best solution is probably to only create the data port
- # once per FTPClient, and just recycle it for each new download.
- # This should be ok, because we don't pipeline commands.
-
- # Start listening on a port
- factory = FTPDataPortFactory()
- factory.protocol = portCmd.protocol
- listener = reactor.listenTCP(0, factory)
- factory.port = listener
-
- # Ensure we close the listening port if something goes wrong
- def listenerFail(error, listener=listener):
- if listener.connected:
- listener.loseConnection()
- return error
- portCmd.fail = listenerFail
-
- # Construct crufty FTP magic numbers that represent host & port
- host = self.transport.getHost().host
- port = listener.getHost().port
- portCmd.text = 'PORT ' + encodeHostPort(host, port)
-
- def escapePath(self, path):
- """
- Returns a FTP escaped path (replace newlines with nulls).
- """
- # Escape newline characters
- return path.replace('\n', '\0')
-
- def retrieveFile(self, path, protocol, offset=0):
- """
- Retrieve a file from the given path
-
- This method issues the 'RETR' FTP command.
-
- The file is fed into the given Protocol instance. The data connection
- will be passive if self.passive is set.
-
- @param path: path to file that you wish to receive.
- @param protocol: a L{Protocol} instance.
- @param offset: offset to start downloading from
-
- @return: L{Deferred}
- """
- cmds = ['RETR ' + self.escapePath(path)]
- if offset:
- cmds.insert(0, ('REST ' + str(offset)))
- return self.receiveFromConnection(cmds, protocol)
-
- retr = retrieveFile
-
- def storeFile(self, path, offset=0):
- """
- Store a file at the given path.
-
- This method issues the 'STOR' FTP command.
-
- @return: A tuple of two L{Deferred}s:
- - L{Deferred} L{IFinishableConsumer}. You must call
- the C{finish} method on the IFinishableConsumer when the file
- is completely transferred.
- - L{Deferred} list of control-connection responses.
- """
- cmds = ['STOR ' + self.escapePath(path)]
- if offset:
- cmds.insert(0, ('REST ' + str(offset)))
- return self.sendToConnection(cmds)
-
- stor = storeFile
-
-
- def rename(self, pathFrom, pathTo):
- """
- Rename a file.
-
- This method issues the I{RNFR}/I{RNTO} command sequence to rename
- C{pathFrom} to C{pathTo}.
-
- @param: pathFrom: the absolute path to the file to be renamed
- @type pathFrom: C{str}
-
- @param: pathTo: the absolute path to rename the file to.
- @type pathTo: C{str}
-
- @return: A L{Deferred} which fires when the rename operation has
- succeeded or failed. If it succeeds, the L{Deferred} is called
- back with a two-tuple of lists. The first list contains the
- responses to the I{RNFR} command. The second list contains the
- responses to the I{RNTO} command. If either I{RNFR} or I{RNTO}
- fails, the L{Deferred} is errbacked with L{CommandFailed} or
- L{BadResponse}.
- @rtype: L{Deferred}
-
- @since: 8.2
- """
- renameFrom = self.queueStringCommand('RNFR ' + self.escapePath(pathFrom))
- renameTo = self.queueStringCommand('RNTO ' + self.escapePath(pathTo))
-
- fromResponse = []
-
- # Use a separate Deferred for the ultimate result so that Deferred
- # chaining can't interfere with its result.
- result = defer.Deferred()
- # Bundle up all the responses
- result.addCallback(lambda toResponse: (fromResponse, toResponse))
-
- def ebFrom(failure):
- # Make sure the RNTO doesn't run if the RNFR failed.
- self.popCommandQueue()
- result.errback(failure)
-
- # Save the RNFR response to pass to the result Deferred later
- renameFrom.addCallbacks(fromResponse.extend, ebFrom)
-
- # Hook up the RNTO to the result Deferred as well
- renameTo.chainDeferred(result)
-
- return result
-
-
- def list(self, path, protocol):
- """
- Retrieve a file listing into the given protocol instance.
-
- This method issues the 'LIST' FTP command.
-
- @param path: path to get a file listing for.
- @param protocol: a L{Protocol} instance, probably a
- L{FTPFileListProtocol} instance. It can cope with most common file
- listing formats.
-
- @return: L{Deferred}
- """
- if path is None:
- path = ''
- return self.receiveFromConnection(['LIST ' + self.escapePath(path)], protocol)
-
-
- def nlst(self, path, protocol):
- """
- Retrieve a short file listing into the given protocol instance.
-
- This method issues the 'NLST' FTP command.
-
- NLST (should) return a list of filenames, one per line.
-
- @param path: path to get short file listing for.
- @param protocol: a L{Protocol} instance.
- """
- if path is None:
- path = ''
- return self.receiveFromConnection(['NLST ' + self.escapePath(path)], protocol)
-
-
- def cwd(self, path):
- """
- Issues the CWD (Change Working Directory) command. It's also
- available as changeDirectory, which parses the result.
-
- @return: a L{Deferred} that will be called when done.
- """
- return self.queueStringCommand('CWD ' + self.escapePath(path))
-
-
- def changeDirectory(self, path):
- """
- Change the directory on the server and parse the result to determine
- if it was successful or not.
-
- @type path: C{str}
- @param path: The path to which to change.
-
- @return: a L{Deferred} which will be called back when the directory
- change has succeeded or errbacked if an error occurrs.
- """
- warnings.warn(
- "FTPClient.changeDirectory is deprecated in Twisted 8.2 and "
- "newer. Use FTPClient.cwd instead.",
- category=DeprecationWarning,
- stacklevel=2)
-
- def cbResult(result):
- if result[-1][:3] != '250':
- return failure.Failure(CommandFailed(result))
- return True
- return self.cwd(path).addCallback(cbResult)
-
-
- def makeDirectory(self, path):
- """
- Make a directory
-
- This method issues the MKD command.
-
- @param path: The path to the directory to create.
- @type path: C{str}
-
- @return: A L{Deferred} which fires when the server responds. If the
- directory is created, the L{Deferred} is called back with the
- server response. If the server response indicates the directory
- was not created, the L{Deferred} is errbacked with a L{Failure}
- wrapping L{CommandFailed} or L{BadResponse}.
- @rtype: L{Deferred}
-
- @since: 8.2
- """
- return self.queueStringCommand('MKD ' + self.escapePath(path))
-
-
- def removeFile(self, path):
- """
- Delete a file on the server.
-
- L{removeFile} issues a I{DELE} command to the server to remove the
- indicated file. Note that this command cannot remove a directory.
-
- @param path: The path to the file to delete. May be relative to the
- current dir.
- @type path: C{str}
-
- @return: A L{Deferred} which fires when the server responds. On error,
- it is errbacked with either L{CommandFailed} or L{BadResponse}. On
- success, it is called back with a list of response lines.
- @rtype: L{Deferred}
-
- @since: 8.2
- """
- return self.queueStringCommand('DELE ' + self.escapePath(path))
-
-
- def removeDirectory(self, path):
- """
- Delete a directory on the server.
-
- L{removeDirectory} issues a I{RMD} command to the server to remove the
- indicated directory. Described in RFC959.
-
- @param path: The path to the directory to delete. May be relative to
- the current working directory.
- @type path: C{str}
-
- @return: A L{Deferred} which fires when the server responds. On error,
- it is errbacked with either L{CommandFailed} or L{BadResponse}. On
- success, it is called back with a list of response lines.
- @rtype: L{Deferred}
-
- @since: 11.1
- """
- return self.queueStringCommand('RMD ' + self.escapePath(path))
-
-
- def cdup(self):
- """
- Issues the CDUP (Change Directory UP) command.
-
- @return: a L{Deferred} that will be called when done.
- """
- return self.queueStringCommand('CDUP')
-
-
- def pwd(self):
- """
- Issues the PWD (Print Working Directory) command.
-
- The L{getDirectory} does the same job but automatically parses the
- result.
-
- @return: a L{Deferred} that will be called when done. It is up to the
- caller to interpret the response, but the L{parsePWDResponse} method
- in this module should work.
- """
- return self.queueStringCommand('PWD')
-
-
- def getDirectory(self):
- """
- Returns the current remote directory.
-
- @return: a L{Deferred} that will be called back with a C{str} giving
- the remote directory or which will errback with L{CommandFailed}
- if an error response is returned.
- """
- def cbParse(result):
- try:
- # The only valid code is 257
- if int(result[0].split(' ', 1)[0]) != 257:
- raise ValueError
- except (IndexError, ValueError):
- return failure.Failure(CommandFailed(result))
- path = parsePWDResponse(result[0])
- if path is None:
- return failure.Failure(CommandFailed(result))
- return path
- return self.pwd().addCallback(cbParse)
-
-
- def quit(self):
- """
- Issues the I{QUIT} command.
-
- @return: A L{Deferred} that fires when the server acknowledges the
- I{QUIT} command. The transport should not be disconnected until
- this L{Deferred} fires.
- """
- return self.queueStringCommand('QUIT')
-
-
-
-class FTPFileListProtocol(basic.LineReceiver):
- """Parser for standard FTP file listings
-
- This is the evil required to match::
-
- -rw-r--r-- 1 root other 531 Jan 29 03:26 README
-
- If you need different evil for a wacky FTP server, you can
- override either C{fileLinePattern} or C{parseDirectoryLine()}.
-
- It populates the instance attribute self.files, which is a list containing
- dicts with the following keys (examples from the above line):
- - filetype: e.g. 'd' for directories, or '-' for an ordinary file
- - perms: e.g. 'rw-r--r--'
- - nlinks: e.g. 1
- - owner: e.g. 'root'
- - group: e.g. 'other'
- - size: e.g. 531
- - date: e.g. 'Jan 29 03:26'
- - filename: e.g. 'README'
- - linktarget: e.g. 'some/file'
-
- Note that the 'date' value will be formatted differently depending on the
- date. Check U{http://cr.yp.to/ftp.html} if you really want to try to parse
- it.
-
- @ivar files: list of dicts describing the files in this listing
- """
- fileLinePattern = re.compile(
- r'^(?P<filetype>.)(?P<perms>.{9})\s+(?P<nlinks>\d*)\s*'
- r'(?P<owner>\S+)\s+(?P<group>\S+)\s+(?P<size>\d+)\s+'
- r'(?P<date>...\s+\d+\s+[\d:]+)\s+(?P<filename>([^ ]|\\ )*?)'
- r'( -> (?P<linktarget>[^\r]*))?\r?$'
- )
- delimiter = '\n'
-
- def __init__(self):
- self.files = []
-
- def lineReceived(self, line):
- d = self.parseDirectoryLine(line)
- if d is None:
- self.unknownLine(line)
- else:
- self.addFile(d)
-
- def parseDirectoryLine(self, line):
- """Return a dictionary of fields, or None if line cannot be parsed.
-
- @param line: line of text expected to contain a directory entry
- @type line: str
-
- @return: dict
- """
- match = self.fileLinePattern.match(line)
- if match is None:
- return None
- else:
- d = match.groupdict()
- d['filename'] = d['filename'].replace(r'\ ', ' ')
- d['nlinks'] = int(d['nlinks'])
- d['size'] = int(d['size'])
- if d['linktarget']:
- d['linktarget'] = d['linktarget'].replace(r'\ ', ' ')
- return d
-
- def addFile(self, info):
- """Append file information dictionary to the list of known files.
-
- Subclasses can override or extend this method to handle file
- information differently without affecting the parsing of data
- from the server.
-
- @param info: dictionary containing the parsed representation
- of the file information
- @type info: dict
- """
- self.files.append(info)
-
- def unknownLine(self, line):
- """Deal with received lines which could not be parsed as file
- information.
-
- Subclasses can override this to perform any special processing
- needed.
-
- @param line: unparsable line as received
- @type line: str
- """
- pass
-
-def parsePWDResponse(response):
- """Returns the path from a response to a PWD command.
-
- Responses typically look like::
-
- 257 "/home/andrew" is current directory.
-
- For this example, I will return C{'/home/andrew'}.
-
- If I can't find the path, I return C{None}.
- """
- match = re.search('"(.*)"', response)
- if match:
- return match.groups()[0]
- else:
- return None
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/__init__.py
deleted file mode 100755
index 278648c3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""Global Positioning System protocols."""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/nmea.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/nmea.py
deleted file mode 100755
index 71d37ea6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/nmea.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- test-case-name: twisted.test.test_nmea -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""NMEA 0183 implementation
-
-Maintainer: Bob Ippolito
-
-The following NMEA 0183 sentences are currently understood::
- GPGGA (fix)
- GPGLL (position)
- GPRMC (position and time)
- GPGSA (active satellites)
-
-The following NMEA 0183 sentences require implementation::
- None really, the others aren't generally useful or implemented in most devices anyhow
-
-Other desired features::
- - A NMEA 0183 producer to emulate GPS devices (?)
-"""
-
-import operator
-from twisted.protocols import basic
-from twisted.python.compat import reduce
-
-POSFIX_INVALID, POSFIX_SPS, POSFIX_DGPS, POSFIX_PPS = 0, 1, 2, 3
-MODE_AUTO, MODE_FORCED = 'A', 'M'
-MODE_NOFIX, MODE_2D, MODE_3D = 1, 2, 3
-
-class InvalidSentence(Exception):
- pass
-
-class InvalidChecksum(Exception):
- pass
-
-class NMEAReceiver(basic.LineReceiver):
- """This parses most common NMEA-0183 messages, presumably from a serial GPS device at 4800 bps
- """
- delimiter = '\r\n'
- dispatch = {
- 'GPGGA': 'fix',
- 'GPGLL': 'position',
- 'GPGSA': 'activesatellites',
- 'GPRMC': 'positiontime',
- 'GPGSV': 'viewsatellites', # not implemented
- 'GPVTG': 'course', # not implemented
- 'GPALM': 'almanac', # not implemented
- 'GPGRS': 'range', # not implemented
- 'GPGST': 'noise', # not implemented
- 'GPMSS': 'beacon', # not implemented
- 'GPZDA': 'time', # not implemented
- }
- # generally you may miss the beginning of the first message
- ignore_invalid_sentence = 1
- # checksums shouldn't be invalid
- ignore_checksum_mismatch = 0
- # ignore unknown sentence types
- ignore_unknown_sentencetypes = 0
- # do we want to even bother checking to see if it's from the 20th century?
- convert_dates_before_y2k = 1
-
- def lineReceived(self, line):
- if not line.startswith('$'):
- if self.ignore_invalid_sentence:
- return
- raise InvalidSentence("%r does not begin with $" % (line,))
- # message is everything between $ and *, checksum is xor of all ASCII values of the message
- strmessage, checksum = line[1:].strip().split('*')
- message = strmessage.split(',')
- sentencetype, message = message[0], message[1:]
- dispatch = self.dispatch.get(sentencetype, None)
- if (not dispatch) and (not self.ignore_unknown_sentencetypes):
- raise InvalidSentence("sentencetype %r" % (sentencetype,))
- if not self.ignore_checksum_mismatch:
- checksum, calculated_checksum = int(checksum, 16), reduce(operator.xor, map(ord, strmessage))
- if checksum != calculated_checksum:
- raise InvalidChecksum("Given 0x%02X != 0x%02X" % (checksum, calculated_checksum))
- handler = getattr(self, "handle_%s" % dispatch, None)
- decoder = getattr(self, "decode_%s" % dispatch, None)
- if not (dispatch and handler and decoder):
- # missing dispatch, handler, or decoder
- return
- # return handler(*decoder(*message))
- try:
- decoded = decoder(*message)
- except Exception, e:
- raise InvalidSentence("%r is not a valid %s (%s) sentence" % (line, sentencetype, dispatch))
- return handler(*decoded)
-
- def decode_position(self, latitude, ns, longitude, ew, utc, status):
- latitude, longitude = self._decode_latlon(latitude, ns, longitude, ew)
- utc = self._decode_utc(utc)
- if status == 'A':
- status = 1
- else:
- status = 0
- return (
- latitude,
- longitude,
- utc,
- status,
- )
-
- def decode_positiontime(self, utc, status, latitude, ns, longitude, ew, speed, course, utcdate, magvar, magdir):
- utc = self._decode_utc(utc)
- latitude, longitude = self._decode_latlon(latitude, ns, longitude, ew)
- if speed != '':
- speed = float(speed)
- else:
- speed = None
- if course != '':
- course = float(course)
- else:
- course = None
- utcdate = 2000+int(utcdate[4:6]), int(utcdate[2:4]), int(utcdate[0:2])
- if self.convert_dates_before_y2k and utcdate[0] > 2073:
- # GPS was invented by the US DoD in 1973, but NMEA uses 2 digit year.
- # Highly unlikely that we'll be using NMEA or this twisted module in 70 years,
- # but remotely possible that you'll be using it to play back data from the 20th century.
- utcdate = (utcdate[0] - 100, utcdate[1], utcdate[2])
- if magvar != '':
- magvar = float(magvar)
- if magdir == 'W':
- magvar = -magvar
- else:
- magvar = None
- return (
- latitude,
- longitude,
- speed,
- course,
- # UTC seconds past utcdate
- utc,
- # UTC (year, month, day)
- utcdate,
- # None or magnetic variation in degrees (west is negative)
- magvar,
- )
-
- def _decode_utc(self, utc):
- utc_hh, utc_mm, utc_ss = map(float, (utc[:2], utc[2:4], utc[4:]))
- return utc_hh * 3600.0 + utc_mm * 60.0 + utc_ss
-
- def _decode_latlon(self, latitude, ns, longitude, ew):
- latitude = float(latitude[:2]) + float(latitude[2:])/60.0
- if ns == 'S':
- latitude = -latitude
- longitude = float(longitude[:3]) + float(longitude[3:])/60.0
- if ew == 'W':
- longitude = -longitude
- return (latitude, longitude)
-
- def decode_activesatellites(self, mode1, mode2, *args):
- satellites, (pdop, hdop, vdop) = args[:12], map(float, args[12:])
- satlist = []
- for n in satellites:
- if n:
- satlist.append(int(n))
- else:
- satlist.append(None)
- mode = (mode1, int(mode2))
- return (
- # satellite list by channel
- tuple(satlist),
- # (MODE_AUTO/MODE_FORCED, MODE_NOFIX/MODE_2DFIX/MODE_3DFIX)
- mode,
- # position dilution of precision
- pdop,
- # horizontal dilution of precision
- hdop,
- # vertical dilution of precision
- vdop,
- )
-
- def decode_fix(self, utc, latitude, ns, longitude, ew, posfix, satellites, hdop, altitude, altitude_units, geoid_separation, geoid_separation_units, dgps_age, dgps_station_id):
- latitude, longitude = self._decode_latlon(latitude, ns, longitude, ew)
- utc = self._decode_utc(utc)
- posfix = int(posfix)
- satellites = int(satellites)
- hdop = float(hdop)
- altitude = (float(altitude), altitude_units)
- if geoid_separation != '':
- geoid = (float(geoid_separation), geoid_separation_units)
- else:
- geoid = None
- if dgps_age != '':
- dgps = (float(dgps_age), dgps_station_id)
- else:
- dgps = None
- return (
- # seconds since 00:00 UTC
- utc,
- # latitude (degrees)
- latitude,
- # longitude (degrees)
- longitude,
- # position fix status (POSFIX_INVALID, POSFIX_SPS, POSFIX_DGPS, POSFIX_PPS)
- posfix,
- # number of satellites used for fix 0 <= satellites <= 12
- satellites,
- # horizontal dilution of precision
- hdop,
- # None or (altitude according to WGS-84 ellipsoid, units (typically 'M' for meters))
- altitude,
- # None or (geoid separation according to WGS-84 ellipsoid, units (typically 'M' for meters))
- geoid,
- # (age of dgps data in seconds, dgps station id)
- dgps,
- )
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/rockwell.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/rockwell.py
deleted file mode 100755
index 7c1d2adc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/gps/rockwell.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Rockwell Semiconductor Zodiac Serial Protocol
-Coded from official protocol specs (Order No. GPS-25, 09/24/1996, Revision 11)
-
-Maintainer: Bob Ippolito
-
-The following Rockwell Zodiac messages are currently understood::
- EARTHA\\r\\n (a hack to "turn on" a DeLorme Earthmate)
- 1000 (Geodesic Position Status Output)
- 1002 (Channel Summary)
- 1003 (Visible Satellites)
- 1011 (Receiver ID)
-
-The following Rockwell Zodiac messages require implementation::
- None really, the others aren't quite so useful and require bidirectional communication w/ the device
-
-Other desired features::
- - Compatability with the DeLorme Tripmate and other devices with this chipset (?)
-"""
-
-import struct, operator, math
-from twisted.internet import protocol
-from twisted.python import log
-
-DEBUG = 1
-
-class ZodiacParseError(ValueError):
- pass
-
-class Zodiac(protocol.Protocol):
- dispatch = {
- # Output Messages (* means they get sent by the receiver by default periodically)
- 1000: 'fix', # *Geodesic Position Status Output
- 1001: 'ecef', # ECEF Position Status Output
- 1002: 'channels', # *Channel Summary
- 1003: 'satellites', # *Visible Satellites
- 1005: 'dgps', # Differential GPS Status
- 1007: 'channelmeas', # Channel Measurement
- 1011: 'id', # *Receiver ID
- 1012: 'usersettings', # User-Settings Output
- 1100: 'testresults', # Built-In Test Results
- 1102: 'meastimemark', # Measurement Time Mark
- 1108: 'utctimemark', # UTC Time Mark Pulse Output
- 1130: 'serial', # Serial Port Communication Parameters In Use
- 1135: 'eepromupdate', # EEPROM Update
- 1136: 'eepromstatus', # EEPROM Status
- }
- # these aren't used for anything yet, just sitting here for reference
- messages = {
- # Input Messages
- 'fix': 1200, # Geodesic Position and Velocity Initialization
- 'udatum': 1210, # User-Defined Datum Definition
- 'mdatum': 1211, # Map Datum Select
- 'smask': 1212, # Satellite Elevation Mask Control
- 'sselect': 1213, # Satellite Candidate Select
- 'dgpsc': 1214, # Differential GPS Control
- 'startc': 1216, # Cold Start Control
- 'svalid': 1217, # Solution Validity Control
- 'antenna': 1218, # Antenna Type Select
- 'altinput': 1219, # User-Entered Altitude Input
- 'appctl': 1220, # Application Platform Control
- 'navcfg': 1221, # Nav Configuration
- 'test': 1300, # Perform Built-In Test Command
- 'restart': 1303, # Restart Command
- 'serial': 1330, # Serial Port Communications Parameters
- 'msgctl': 1331, # Message Protocol Control
- 'dgpsd': 1351, # Raw DGPS RTCM SC-104 Data
- }
- MAX_LENGTH = 296
- allow_earthmate_hack = 1
- recvd = ""
-
- def dataReceived(self, recd):
- self.recvd = self.recvd + recd
- while len(self.recvd) >= 10:
-
- # hack for DeLorme EarthMate
- if self.recvd[:8] == 'EARTHA\r\n':
- if self.allow_earthmate_hack:
- self.allow_earthmate_hack = 0
- self.transport.write('EARTHA\r\n')
- self.recvd = self.recvd[8:]
- continue
-
- if self.recvd[0:2] != '\xFF\x81':
- if DEBUG:
- raise ZodiacParseError('Invalid Sync %r' % self.recvd)
- else:
- raise ZodiacParseError
- sync, msg_id, length, acknak, checksum = struct.unpack('<HHHHh', self.recvd[:10])
-
- # verify checksum
- cksum = -(reduce(operator.add, (sync, msg_id, length, acknak)) & 0xFFFF)
- cksum, = struct.unpack('<h', struct.pack('<h', cksum))
- if cksum != checksum:
- if DEBUG:
- raise ZodiacParseError('Invalid Header Checksum %r != %r %r' % (checksum, cksum, self.recvd[:8]))
- else:
- raise ZodiacParseError
-
- # length was in words, now it's bytes
- length = length * 2
-
- # do we need more data ?
- neededBytes = 10
- if length:
- neededBytes += length + 2
- if len(self.recvd) < neededBytes:
- break
-
- if neededBytes > self.MAX_LENGTH:
- raise ZodiacParseError("Invalid Header??")
-
- # empty messages pass empty strings
- message = ''
-
- # does this message have data ?
- if length:
- message, checksum = self.recvd[10:10+length], struct.unpack('<h', self.recvd[10+length:neededBytes])[0]
- cksum = 0x10000 - (reduce(operator.add, struct.unpack('<%dH' % (length/2), message)) & 0xFFFF)
- cksum, = struct.unpack('<h', struct.pack('<h', cksum))
- if cksum != checksum:
- if DEBUG:
- log.dmsg('msg_id = %r length = %r' % (msg_id, length), debug=True)
- raise ZodiacParseError('Invalid Data Checksum %r != %r %r' % (checksum, cksum, message))
- else:
- raise ZodiacParseError
-
- # discard used buffer, dispatch message
- self.recvd = self.recvd[neededBytes:]
- self.receivedMessage(msg_id, message, acknak)
-
- def receivedMessage(self, msg_id, message, acknak):
- dispatch = self.dispatch.get(msg_id, None)
- if not dispatch:
- raise ZodiacParseError('Unknown msg_id = %r' % msg_id)
- handler = getattr(self, 'handle_%s' % dispatch, None)
- decoder = getattr(self, 'decode_%s' % dispatch, None)
- if not (handler and decoder):
- # missing handler or decoder
- #if DEBUG:
- # log.msg('MISSING HANDLER/DECODER PAIR FOR: %r' % (dispatch,), debug=True)
- return
- decoded = decoder(message)
- return handler(*decoded)
-
- def decode_fix(self, message):
- assert len(message) == 98, "Geodesic Position Status Output should be 55 words total (98 byte message)"
- (ticks, msgseq, satseq, navstatus, navtype, nmeasure, polar, gpswk, gpses, gpsns, utcdy, utcmo, utcyr, utchr, utcmn, utcsc, utcns, latitude, longitude, height, geoidalsep, speed, course, magvar, climb, mapdatum, exhposerr, exvposerr, extimeerr, exphvelerr, clkbias, clkbiasdev, clkdrift, clkdriftdev) = struct.unpack('<LhhHHHHHLLHHHHHHLlllhLHhhHLLLHllll', message)
-
- # there's a lot of shit in here..
- # I'll just snag the important stuff and spit it out like my NMEA decoder
- utc = (utchr * 3600.0) + (utcmn * 60.0) + utcsc + (float(utcns) * 0.000000001)
-
- log.msg('utchr, utcmn, utcsc, utcns = ' + repr((utchr, utcmn, utcsc, utcns)), debug=True)
-
- latitude = float(latitude) * 0.00000180 / math.pi
- longitude = float(longitude) * 0.00000180 / math.pi
- posfix = not (navstatus & 0x001c)
- satellites = nmeasure
- hdop = float(exhposerr) * 0.01
- altitude = float(height) * 0.01, 'M'
- geoid = float(geoidalsep) * 0.01, 'M'
- dgps = None
- return (
- # seconds since 00:00 UTC
- utc,
- # latitude (degrees)
- latitude,
- # longitude (degrees)
- longitude,
- # position fix status (invalid = False, valid = True)
- posfix,
- # number of satellites [measurements] used for fix 0 <= satellites <= 12
- satellites,
- # horizontal dilution of precision
- hdop,
- # (altitude according to WGS-84 ellipsoid, units (always 'M' for meters))
- altitude,
- # (geoid separation according to WGS-84 ellipsoid, units (always 'M' for meters))
- geoid,
- # None, for compatability w/ NMEA code
- dgps,
- )
-
- def decode_id(self, message):
- assert len(message) == 106, "Receiver ID Message should be 59 words total (106 byte message)"
- ticks, msgseq, channels, software_version, software_date, options_list, reserved = struct.unpack('<Lh20s20s20s20s20s', message)
- channels, software_version, software_date, options_list = map(lambda s: s.split('\0')[0], (channels, software_version, software_date, options_list))
- software_version = float(software_version)
- channels = int(channels) # 0-12 .. but ALWAYS 12, so we ignore.
- options_list = int(options_list[:4], 16) # only two bitflags, others are reserved
- minimize_rom = (options_list & 0x01) > 0
- minimize_ram = (options_list & 0x02) > 0
- # (version info), (options info)
- return ((software_version, software_date), (minimize_rom, minimize_ram))
-
- def decode_channels(self, message):
- assert len(message) == 90, "Channel Summary Message should be 51 words total (90 byte message)"
- ticks, msgseq, satseq, gpswk, gpsws, gpsns = struct.unpack('<LhhHLL', message[:18])
- channels = []
- message = message[18:]
- for i in range(12):
- flags, prn, cno = struct.unpack('<HHH', message[6 * i:6 * (i + 1)])
- # measurement used, ephemeris available, measurement valid, dgps corrections available
- flags = (flags & 0x01, flags & 0x02, flags & 0x04, flags & 0x08)
- channels.append((flags, prn, cno))
- # ((flags, satellite PRN, C/No in dbHz)) for 12 channels
- # satellite message sequence number
- # gps week number, gps seconds in week (??), gps nanoseconds from Epoch
- return (tuple(channels),) #, satseq, (gpswk, gpsws, gpsns))
-
- def decode_satellites(self, message):
- assert len(message) == 90, "Visible Satellites Message should be 51 words total (90 byte message)"
- ticks, msgseq, gdop, pdop, hdop, vdop, tdop, numsatellites = struct.unpack('<LhhhhhhH', message[:18])
- gdop, pdop, hdop, vdop, tdop = map(lambda n: float(n) * 0.01, (gdop, pdop, hdop, vdop, tdop))
- satellites = []
- message = message[18:]
- for i in range(numsatellites):
- prn, azi, elev = struct.unpack('<Hhh', message[6 * i:6 * (i + 1)])
- azi, elev = map(lambda n: (float(n) * 0.0180 / math.pi), (azi, elev))
- satellites.push((prn, azi, elev))
- # ((PRN [0, 32], azimuth +=[0.0, 180.0] deg, elevation +-[0.0, 90.0] deg)) satellite info (0-12)
- # (geometric, position, horizontal, vertical, time) dilution of precision
- return (tuple(satellites), (gdop, pdop, hdop, vdop, tdop))
-
- def decode_dgps(self, message):
- assert len(message) == 38, "Differential GPS Status Message should be 25 words total (38 byte message)"
- raise NotImplementedError
-
- def decode_ecef(self, message):
- assert len(message) == 96, "ECEF Position Status Output Message should be 54 words total (96 byte message)"
- raise NotImplementedError
-
- def decode_channelmeas(self, message):
- assert len(message) == 296, "Channel Measurement Message should be 154 words total (296 byte message)"
- raise NotImplementedError
-
- def decode_usersettings(self, message):
- assert len(message) == 32, "User-Settings Output Message should be 22 words total (32 byte message)"
- raise NotImplementedError
-
- def decode_testresults(self, message):
- assert len(message) == 28, "Built-In Test Results Message should be 20 words total (28 byte message)"
- raise NotImplementedError
-
- def decode_meastimemark(self, message):
- assert len(message) == 494, "Measurement Time Mark Message should be 253 words total (494 byte message)"
- raise NotImplementedError
-
- def decode_utctimemark(self, message):
- assert len(message) == 28, "UTC Time Mark Pulse Output Message should be 20 words total (28 byte message)"
- raise NotImplementedError
-
- def decode_serial(self, message):
- assert len(message) == 30, "Serial Port Communication Paramaters In Use Message should be 21 words total (30 byte message)"
- raise NotImplementedError
-
- def decode_eepromupdate(self, message):
- assert len(message) == 8, "EEPROM Update Message should be 10 words total (8 byte message)"
- raise NotImplementedError
-
- def decode_eepromstatus(self, message):
- assert len(message) == 24, "EEPROM Status Message should be 18 words total (24 byte message)"
- raise NotImplementedError
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py
deleted file mode 100755
index 10008cf4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/htb.py
+++ /dev/null
@@ -1,297 +0,0 @@
-# -*- test-case-name: twisted.test.test_htb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Hierarchical Token Bucket traffic shaping.
-
-Patterned after U{Martin Devera's Hierarchical Token Bucket traffic
-shaper for the Linux kernel<http://luxik.cdi.cz/~devik/qos/htb/>}.
-
-@seealso: U{HTB Linux queuing discipline manual - user guide
- <http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm>}
-@seealso: U{Token Bucket Filter in Linux Advanced Routing & Traffic Control
- HOWTO<http://lartc.org/howto/lartc.qdisc.classless.html#AEN682>}
-"""
-
-
-# TODO: Investigate whether we should be using os.times()[-1] instead of
-# time.time. time.time, it has been pointed out, can go backwards. Is
-# the same true of os.times?
-from time import time
-from zope.interface import implements, Interface
-
-from twisted.protocols import pcp
-
-
-class Bucket:
- """
- Implementation of a Token bucket.
-
- A bucket can hold a certain number of tokens and it drains over time.
-
- @cvar maxburst: The maximum number of tokens that the bucket can
- hold at any given time. If this is C{None}, the bucket has
- an infinite size.
- @type maxburst: C{int}
- @cvar rate: The rate at which the bucket drains, in number
- of tokens per second. If the rate is C{None}, the bucket
- drains instantaneously.
- @type rate: C{int}
- """
-
- maxburst = None
- rate = None
-
- _refcount = 0
-
- def __init__(self, parentBucket=None):
- """
- Create a L{Bucket} that may have a parent L{Bucket}.
-
- @param parentBucket: If a parent Bucket is specified,
- all L{add} and L{drip} operations on this L{Bucket}
- will be applied on the parent L{Bucket} as well.
- @type parentBucket: L{Bucket}
- """
- self.content = 0
- self.parentBucket = parentBucket
- self.lastDrip = time()
-
-
- def add(self, amount):
- """
- Adds tokens to the L{Bucket} and its C{parentBucket}.
-
- This will add as many of the C{amount} tokens as will fit into both
- this L{Bucket} and its C{parentBucket}.
-
- @param amount: The number of tokens to try to add.
- @type amount: C{int}
-
- @returns: The number of tokens that actually fit.
- @returntype: C{int}
- """
- self.drip()
- if self.maxburst is None:
- allowable = amount
- else:
- allowable = min(amount, self.maxburst - self.content)
-
- if self.parentBucket is not None:
- allowable = self.parentBucket.add(allowable)
- self.content += allowable
- return allowable
-
-
- def drip(self):
- """
- Let some of the bucket drain.
-
- The L{Bucket} drains at the rate specified by the class
- variable C{rate}.
-
- @returns: C{True} if the bucket is empty after this drip.
- @returntype: C{bool}
- """
- if self.parentBucket is not None:
- self.parentBucket.drip()
-
- if self.rate is None:
- self.content = 0
- else:
- now = time()
- deltaTime = now - self.lastDrip
- deltaTokens = deltaTime * self.rate
- self.content = max(0, self.content - deltaTokens)
- self.lastDrip = now
- return self.content == 0
-
-
-class IBucketFilter(Interface):
- def getBucketFor(*somethings, **some_kw):
- """
- Return a L{Bucket} corresponding to the provided parameters.
-
- @returntype: L{Bucket}
- """
-
-class HierarchicalBucketFilter:
- """
- Filter things into buckets that can be nested.
-
- @cvar bucketFactory: Class of buckets to make.
- @type bucketFactory: L{Bucket}
- @cvar sweepInterval: Seconds between sweeping out the bucket cache.
- @type sweepInterval: C{int}
- """
-
- implements(IBucketFilter)
-
- bucketFactory = Bucket
- sweepInterval = None
-
- def __init__(self, parentFilter=None):
- self.buckets = {}
- self.parentFilter = parentFilter
- self.lastSweep = time()
-
- def getBucketFor(self, *a, **kw):
- """
- Find or create a L{Bucket} corresponding to the provided parameters.
-
- Any parameters are passed on to L{getBucketKey}, from them it
- decides which bucket you get.
-
- @returntype: L{Bucket}
- """
- if ((self.sweepInterval is not None)
- and ((time() - self.lastSweep) > self.sweepInterval)):
- self.sweep()
-
- if self.parentFilter:
- parentBucket = self.parentFilter.getBucketFor(self, *a, **kw)
- else:
- parentBucket = None
-
- key = self.getBucketKey(*a, **kw)
- bucket = self.buckets.get(key)
- if bucket is None:
- bucket = self.bucketFactory(parentBucket)
- self.buckets[key] = bucket
- return bucket
-
- def getBucketKey(self, *a, **kw):
- """
- Construct a key based on the input parameters to choose a L{Bucket}.
-
- The default implementation returns the same key for all
- arguments. Override this method to provide L{Bucket} selection.
-
- @returns: Something to be used as a key in the bucket cache.
- """
- return None
-
- def sweep(self):
- """
- Remove empty buckets.
- """
- for key, bucket in self.buckets.items():
- bucket_is_empty = bucket.drip()
- if (bucket._refcount == 0) and bucket_is_empty:
- del self.buckets[key]
-
- self.lastSweep = time()
-
-
-class FilterByHost(HierarchicalBucketFilter):
- """
- A Hierarchical Bucket filter with a L{Bucket} for each host.
- """
- sweepInterval = 60 * 20
-
- def getBucketKey(self, transport):
- return transport.getPeer()[1]
-
-
-class FilterByServer(HierarchicalBucketFilter):
- """
- A Hierarchical Bucket filter with a L{Bucket} for each service.
- """
- sweepInterval = None
-
- def getBucketKey(self, transport):
- return transport.getHost()[2]
-
-
-class ShapedConsumer(pcp.ProducerConsumerProxy):
- """
- Wraps a C{Consumer} and shapes the rate at which it receives data.
- """
- # Providing a Pull interface means I don't have to try to schedule
- # traffic with callLaters.
- iAmStreaming = False
-
- def __init__(self, consumer, bucket):
- pcp.ProducerConsumerProxy.__init__(self, consumer)
- self.bucket = bucket
- self.bucket._refcount += 1
-
- def _writeSomeData(self, data):
- # In practice, this actually results in obscene amounts of
- # overhead, as a result of generating lots and lots of packets
- # with twelve-byte payloads. We may need to do a version of
- # this with scheduled writes after all.
- amount = self.bucket.add(len(data))
- return pcp.ProducerConsumerProxy._writeSomeData(self, data[:amount])
-
- def stopProducing(self):
- pcp.ProducerConsumerProxy.stopProducing(self)
- self.bucket._refcount -= 1
-
-
-class ShapedTransport(ShapedConsumer):
- """
- Wraps a C{Transport} and shapes the rate at which it receives data.
-
- This is a L{ShapedConsumer} with a little bit of magic to provide for
- the case where the consumer it wraps is also a C{Transport} and people
- will be attempting to access attributes this does not proxy as a
- C{Consumer} (e.g. C{loseConnection}).
- """
- # Ugh. We only wanted to filter IConsumer, not ITransport.
-
- iAmStreaming = False
- def __getattr__(self, name):
- # Because people will be doing things like .getPeer and
- # .loseConnection on me.
- return getattr(self.consumer, name)
-
-
-class ShapedProtocolFactory:
- """
- Dispense C{Protocols} with traffic shaping on their transports.
-
- Usage::
-
- myserver = SomeFactory()
- myserver.protocol = ShapedProtocolFactory(myserver.protocol,
- bucketFilter)
-
- Where C{SomeServerFactory} is a L{twisted.internet.protocol.Factory}, and
- C{bucketFilter} is an instance of L{HierarchicalBucketFilter}.
- """
- def __init__(self, protoClass, bucketFilter):
- """
- Tell me what to wrap and where to get buckets.
-
- @param protoClass: The class of C{Protocol} this will generate
- wrapped instances of.
- @type protoClass: L{Protocol<twisted.internet.interfaces.IProtocol>}
- class
- @param bucketFilter: The filter which will determine how
- traffic is shaped.
- @type bucketFilter: L{HierarchicalBucketFilter}.
- """
- # More precisely, protoClass can be any callable that will return
- # instances of something that implements IProtocol.
- self.protocol = protoClass
- self.bucketFilter = bucketFilter
-
- def __call__(self, *a, **kw):
- """
- Make a C{Protocol} instance with a shaped transport.
-
- Any parameters will be passed on to the protocol's initializer.
-
- @returns: A C{Protocol} instance with a L{ShapedTransport}.
- """
- proto = self.protocol(*a, **kw)
- origMakeConnection = proto.makeConnection
- def makeConnection(transport):
- bucket = self.bucketFilter.getBucketFor(transport)
- shapedTransport = ShapedTransport(transport, bucket)
- return origMakeConnection(shapedTransport)
- proto.makeConnection = makeConnection
- return proto
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ident.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ident.py
deleted file mode 100755
index 985322df..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/ident.py
+++ /dev/null
@@ -1,231 +0,0 @@
-# -*- test-case-name: twisted.test.test_ident -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Ident protocol implementation.
-"""
-
-import struct
-
-from twisted.internet import defer
-from twisted.protocols import basic
-from twisted.python import log, failure
-
-_MIN_PORT = 1
-_MAX_PORT = 2 ** 16 - 1
-
-class IdentError(Exception):
- """
- Can't determine connection owner; reason unknown.
- """
-
- identDescription = 'UNKNOWN-ERROR'
-
- def __str__(self):
- return self.identDescription
-
-
-class NoUser(IdentError):
- """
- The connection specified by the port pair is not currently in use or
- currently not owned by an identifiable entity.
- """
- identDescription = 'NO-USER'
-
-
-class InvalidPort(IdentError):
- """
- Either the local or foreign port was improperly specified. This should
- be returned if either or both of the port ids were out of range (TCP
- port numbers are from 1-65535), negative integers, reals or in any
- fashion not recognized as a non-negative integer.
- """
- identDescription = 'INVALID-PORT'
-
-
-class HiddenUser(IdentError):
- """
- The server was able to identify the user of this port, but the
- information was not returned at the request of the user.
- """
- identDescription = 'HIDDEN-USER'
-
-
-class IdentServer(basic.LineOnlyReceiver):
- """
- The Identification Protocol (a.k.a., "ident", a.k.a., "the Ident
- Protocol") provides a means to determine the identity of a user of a
- particular TCP connection. Given a TCP port number pair, it returns a
- character string which identifies the owner of that connection on the
- server's system.
-
- Server authors should subclass this class and override the lookup method.
- The default implementation returns an UNKNOWN-ERROR response for every
- query.
- """
-
- def lineReceived(self, line):
- parts = line.split(',')
- if len(parts) != 2:
- self.invalidQuery()
- else:
- try:
- portOnServer, portOnClient = map(int, parts)
- except ValueError:
- self.invalidQuery()
- else:
- if _MIN_PORT <= portOnServer <= _MAX_PORT and _MIN_PORT <= portOnClient <= _MAX_PORT:
- self.validQuery(portOnServer, portOnClient)
- else:
- self._ebLookup(failure.Failure(InvalidPort()), portOnServer, portOnClient)
-
- def invalidQuery(self):
- self.transport.loseConnection()
-
-
- def validQuery(self, portOnServer, portOnClient):
- """
- Called when a valid query is received to look up and deliver the
- response.
-
- @param portOnServer: The server port from the query.
- @param portOnClient: The client port from the query.
- """
- serverAddr = self.transport.getHost().host, portOnServer
- clientAddr = self.transport.getPeer().host, portOnClient
- defer.maybeDeferred(self.lookup, serverAddr, clientAddr
- ).addCallback(self._cbLookup, portOnServer, portOnClient
- ).addErrback(self._ebLookup, portOnServer, portOnClient
- )
-
-
- def _cbLookup(self, (sysName, userId), sport, cport):
- self.sendLine('%d, %d : USERID : %s : %s' % (sport, cport, sysName, userId))
-
- def _ebLookup(self, failure, sport, cport):
- if failure.check(IdentError):
- self.sendLine('%d, %d : ERROR : %s' % (sport, cport, failure.value))
- else:
- log.err(failure)
- self.sendLine('%d, %d : ERROR : %s' % (sport, cport, IdentError(failure.value)))
-
- def lookup(self, serverAddress, clientAddress):
- """Lookup user information about the specified address pair.
-
- Return value should be a two-tuple of system name and username.
- Acceptable values for the system name may be found online at::
-
- U{http://www.iana.org/assignments/operating-system-names}
-
- This method may also raise any IdentError subclass (or IdentError
- itself) to indicate user information will not be provided for the
- given query.
-
- A Deferred may also be returned.
-
- @param serverAddress: A two-tuple representing the server endpoint
- of the address being queried. The first element is a string holding
- a dotted-quad IP address. The second element is an integer
- representing the port.
-
- @param clientAddress: Like L{serverAddress}, but represents the
- client endpoint of the address being queried.
- """
- raise IdentError()
-
-class ProcServerMixin:
- """Implements lookup() to grab entries for responses from /proc/net/tcp
- """
-
- SYSTEM_NAME = 'LINUX'
-
- try:
- from pwd import getpwuid
- def getUsername(self, uid, getpwuid=getpwuid):
- return getpwuid(uid)[0]
- del getpwuid
- except ImportError:
- def getUsername(self, uid):
- raise IdentError()
-
- def entries(self):
- f = file('/proc/net/tcp')
- f.readline()
- for L in f:
- yield L.strip()
-
- def dottedQuadFromHexString(self, hexstr):
- return '.'.join(map(str, struct.unpack('4B', struct.pack('=L', int(hexstr, 16)))))
-
- def unpackAddress(self, packed):
- addr, port = packed.split(':')
- addr = self.dottedQuadFromHexString(addr)
- port = int(port, 16)
- return addr, port
-
- def parseLine(self, line):
- parts = line.strip().split()
- localAddr, localPort = self.unpackAddress(parts[1])
- remoteAddr, remotePort = self.unpackAddress(parts[2])
- uid = int(parts[7])
- return (localAddr, localPort), (remoteAddr, remotePort), uid
-
- def lookup(self, serverAddress, clientAddress):
- for ent in self.entries():
- localAddr, remoteAddr, uid = self.parseLine(ent)
- if remoteAddr == clientAddress and localAddr[1] == serverAddress[1]:
- return (self.SYSTEM_NAME, self.getUsername(uid))
-
- raise NoUser()
-
-
-class IdentClient(basic.LineOnlyReceiver):
-
- errorTypes = (IdentError, NoUser, InvalidPort, HiddenUser)
-
- def __init__(self):
- self.queries = []
-
- def lookup(self, portOnServer, portOnClient):
- """Lookup user information about the specified address pair.
- """
- self.queries.append((defer.Deferred(), portOnServer, portOnClient))
- if len(self.queries) > 1:
- return self.queries[-1][0]
-
- self.sendLine('%d, %d' % (portOnServer, portOnClient))
- return self.queries[-1][0]
-
- def lineReceived(self, line):
- if not self.queries:
- log.msg("Unexpected server response: %r" % (line,))
- else:
- d, _, _ = self.queries.pop(0)
- self.parseResponse(d, line)
- if self.queries:
- self.sendLine('%d, %d' % (self.queries[0][1], self.queries[0][2]))
-
- def connectionLost(self, reason):
- for q in self.queries:
- q[0].errback(IdentError(reason))
- self.queries = []
-
- def parseResponse(self, deferred, line):
- parts = line.split(':', 2)
- if len(parts) != 3:
- deferred.errback(IdentError(line))
- else:
- ports, type, addInfo = map(str.strip, parts)
- if type == 'ERROR':
- for et in self.errorTypes:
- if et.identDescription == addInfo:
- deferred.errback(et(line))
- return
- deferred.errback(IdentError(line))
- else:
- deferred.callback((type, addInfo))
-
-__all__ = ['IdentError', 'NoUser', 'InvalidPort', 'HiddenUser',
- 'IdentServer', 'IdentClient',
- 'ProcServerMixin']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/loopback.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/loopback.py
deleted file mode 100755
index e5848279..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/loopback.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# -*- test-case-name: twisted.test.test_loopback -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Testing support for protocols -- loopback between client and server.
-"""
-
-# system imports
-import tempfile
-from zope.interface import implements
-
-# Twisted Imports
-from twisted.protocols import policies
-from twisted.internet import interfaces, protocol, main, defer
-from twisted.internet.task import deferLater
-from twisted.python import failure
-from twisted.internet.interfaces import IAddress
-
-
-class _LoopbackQueue(object):
- """
- Trivial wrapper around a list to give it an interface like a queue, which
- the addition of also sending notifications by way of a Deferred whenever
- the list has something added to it.
- """
-
- _notificationDeferred = None
- disconnect = False
-
- def __init__(self):
- self._queue = []
-
-
- def put(self, v):
- self._queue.append(v)
- if self._notificationDeferred is not None:
- d, self._notificationDeferred = self._notificationDeferred, None
- d.callback(None)
-
-
- def __nonzero__(self):
- return bool(self._queue)
-
-
- def get(self):
- return self._queue.pop(0)
-
-
-
-class _LoopbackAddress(object):
- implements(IAddress)
-
-
-class _LoopbackTransport(object):
- implements(interfaces.ITransport, interfaces.IConsumer)
-
- disconnecting = False
- producer = None
-
- # ITransport
- def __init__(self, q):
- self.q = q
-
- def write(self, bytes):
- self.q.put(bytes)
-
- def writeSequence(self, iovec):
- self.q.put(''.join(iovec))
-
- def loseConnection(self):
- self.q.disconnect = True
- self.q.put(None)
-
- def getPeer(self):
- return _LoopbackAddress()
-
- def getHost(self):
- return _LoopbackAddress()
-
- # IConsumer
- def registerProducer(self, producer, streaming):
- assert self.producer is None
- self.producer = producer
- self.streamingProducer = streaming
- self._pollProducer()
-
- def unregisterProducer(self):
- assert self.producer is not None
- self.producer = None
-
- def _pollProducer(self):
- if self.producer is not None and not self.streamingProducer:
- self.producer.resumeProducing()
-
-
-
-def identityPumpPolicy(queue, target):
- """
- L{identityPumpPolicy} is a policy which delivers each chunk of data written
- to the given queue as-is to the target.
-
- This isn't a particularly realistic policy.
-
- @see: L{loopbackAsync}
- """
- while queue:
- bytes = queue.get()
- if bytes is None:
- break
- target.dataReceived(bytes)
-
-
-
-def collapsingPumpPolicy(queue, target):
- """
- L{collapsingPumpPolicy} is a policy which collapses all outstanding chunks
- into a single string and delivers it to the target.
-
- @see: L{loopbackAsync}
- """
- bytes = []
- while queue:
- chunk = queue.get()
- if chunk is None:
- break
- bytes.append(chunk)
- if bytes:
- target.dataReceived(''.join(bytes))
-
-
-
-def loopbackAsync(server, client, pumpPolicy=identityPumpPolicy):
- """
- Establish a connection between C{server} and C{client} then transfer data
- between them until the connection is closed. This is often useful for
- testing a protocol.
-
- @param server: The protocol instance representing the server-side of this
- connection.
-
- @param client: The protocol instance representing the client-side of this
- connection.
-
- @param pumpPolicy: When either C{server} or C{client} writes to its
- transport, the string passed in is added to a queue of data for the
- other protocol. Eventually, C{pumpPolicy} will be called with one such
- queue and the corresponding protocol object. The pump policy callable
- is responsible for emptying the queue and passing the strings it
- contains to the given protocol's C{dataReceived} method. The signature
- of C{pumpPolicy} is C{(queue, protocol)}. C{queue} is an object with a
- C{get} method which will return the next string written to the
- transport, or C{None} if the transport has been disconnected, and which
- evaluates to C{True} if and only if there are more items to be
- retrieved via C{get}.
-
- @return: A L{Deferred} which fires when the connection has been closed and
- both sides have received notification of this.
- """
- serverToClient = _LoopbackQueue()
- clientToServer = _LoopbackQueue()
-
- server.makeConnection(_LoopbackTransport(serverToClient))
- client.makeConnection(_LoopbackTransport(clientToServer))
-
- return _loopbackAsyncBody(
- server, serverToClient, client, clientToServer, pumpPolicy)
-
-
-
-def _loopbackAsyncBody(server, serverToClient, client, clientToServer,
- pumpPolicy):
- """
- Transfer bytes from the output queue of each protocol to the input of the other.
-
- @param server: The protocol instance representing the server-side of this
- connection.
-
- @param serverToClient: The L{_LoopbackQueue} holding the server's output.
-
- @param client: The protocol instance representing the client-side of this
- connection.
-
- @param clientToServer: The L{_LoopbackQueue} holding the client's output.
-
- @param pumpPolicy: See L{loopbackAsync}.
-
- @return: A L{Deferred} which fires when the connection has been closed and
- both sides have received notification of this.
- """
- def pump(source, q, target):
- sent = False
- if q:
- pumpPolicy(q, target)
- sent = True
- if sent and not q:
- # A write buffer has now been emptied. Give any producer on that
- # side an opportunity to produce more data.
- source.transport._pollProducer()
-
- return sent
-
- while 1:
- disconnect = clientSent = serverSent = False
-
- # Deliver the data which has been written.
- serverSent = pump(server, serverToClient, client)
- clientSent = pump(client, clientToServer, server)
-
- if not clientSent and not serverSent:
- # Neither side wrote any data. Wait for some new data to be added
- # before trying to do anything further.
- d = defer.Deferred()
- clientToServer._notificationDeferred = d
- serverToClient._notificationDeferred = d
- d.addCallback(
- _loopbackAsyncContinue,
- server, serverToClient, client, clientToServer, pumpPolicy)
- return d
- if serverToClient.disconnect:
- # The server wants to drop the connection. Flush any remaining
- # data it has.
- disconnect = True
- pump(server, serverToClient, client)
- elif clientToServer.disconnect:
- # The client wants to drop the connection. Flush any remaining
- # data it has.
- disconnect = True
- pump(client, clientToServer, server)
- if disconnect:
- # Someone wanted to disconnect, so okay, the connection is gone.
- server.connectionLost(failure.Failure(main.CONNECTION_DONE))
- client.connectionLost(failure.Failure(main.CONNECTION_DONE))
- return defer.succeed(None)
-
-
-
-def _loopbackAsyncContinue(ignored, server, serverToClient, client,
- clientToServer, pumpPolicy):
- # Clear the Deferred from each message queue, since it has already fired
- # and cannot be used again.
- clientToServer._notificationDeferred = None
- serverToClient._notificationDeferred = None
-
- # Schedule some more byte-pushing to happen. This isn't done
- # synchronously because no actual transport can re-enter dataReceived as
- # a result of calling write, and doing this synchronously could result
- # in that.
- from twisted.internet import reactor
- return deferLater(
- reactor, 0,
- _loopbackAsyncBody,
- server, serverToClient, client, clientToServer, pumpPolicy)
-
-
-
-class LoopbackRelay:
-
- implements(interfaces.ITransport, interfaces.IConsumer)
-
- buffer = ''
- shouldLose = 0
- disconnecting = 0
- producer = None
-
- def __init__(self, target, logFile=None):
- self.target = target
- self.logFile = logFile
-
- def write(self, data):
- self.buffer = self.buffer + data
- if self.logFile:
- self.logFile.write("loopback writing %s\n" % repr(data))
-
- def writeSequence(self, iovec):
- self.write("".join(iovec))
-
- def clearBuffer(self):
- if self.shouldLose == -1:
- return
-
- if self.producer:
- self.producer.resumeProducing()
- if self.buffer:
- if self.logFile:
- self.logFile.write("loopback receiving %s\n" % repr(self.buffer))
- buffer = self.buffer
- self.buffer = ''
- self.target.dataReceived(buffer)
- if self.shouldLose == 1:
- self.shouldLose = -1
- self.target.connectionLost(failure.Failure(main.CONNECTION_DONE))
-
- def loseConnection(self):
- if self.shouldLose != -1:
- self.shouldLose = 1
-
- def getHost(self):
- return 'loopback'
-
- def getPeer(self):
- return 'loopback'
-
- def registerProducer(self, producer, streaming):
- self.producer = producer
-
- def unregisterProducer(self):
- self.producer = None
-
- def logPrefix(self):
- return 'Loopback(%r)' % (self.target.__class__.__name__,)
-
-
-
-class LoopbackClientFactory(protocol.ClientFactory):
-
- def __init__(self, protocol):
- self.disconnected = 0
- self.deferred = defer.Deferred()
- self.protocol = protocol
-
- def buildProtocol(self, addr):
- return self.protocol
-
- def clientConnectionLost(self, connector, reason):
- self.disconnected = 1
- self.deferred.callback(None)
-
-
-class _FireOnClose(policies.ProtocolWrapper):
- def __init__(self, protocol, factory):
- policies.ProtocolWrapper.__init__(self, protocol, factory)
- self.deferred = defer.Deferred()
-
- def connectionLost(self, reason):
- policies.ProtocolWrapper.connectionLost(self, reason)
- self.deferred.callback(None)
-
-
-def loopbackTCP(server, client, port=0, noisy=True):
- """Run session between server and client protocol instances over TCP."""
- from twisted.internet import reactor
- f = policies.WrappingFactory(protocol.Factory())
- serverWrapper = _FireOnClose(f, server)
- f.noisy = noisy
- f.buildProtocol = lambda addr: serverWrapper
- serverPort = reactor.listenTCP(port, f, interface='127.0.0.1')
- clientF = LoopbackClientFactory(client)
- clientF.noisy = noisy
- reactor.connectTCP('127.0.0.1', serverPort.getHost().port, clientF)
- d = clientF.deferred
- d.addCallback(lambda x: serverWrapper.deferred)
- d.addCallback(lambda x: serverPort.stopListening())
- return d
-
-
-def loopbackUNIX(server, client, noisy=True):
- """Run session between server and client protocol instances over UNIX socket."""
- path = tempfile.mktemp()
- from twisted.internet import reactor
- f = policies.WrappingFactory(protocol.Factory())
- serverWrapper = _FireOnClose(f, server)
- f.noisy = noisy
- f.buildProtocol = lambda addr: serverWrapper
- serverPort = reactor.listenUNIX(path, f)
- clientF = LoopbackClientFactory(client)
- clientF.noisy = noisy
- reactor.connectUNIX(path, clientF)
- d = clientF.deferred
- d.addCallback(lambda x: serverWrapper.deferred)
- d.addCallback(lambda x: serverPort.stopListening())
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/memcache.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/memcache.py
deleted file mode 100755
index a5e987d2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/memcache.py
+++ /dev/null
@@ -1,758 +0,0 @@
-# -*- test-case-name: twisted.test.test_memcache -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Memcache client protocol. Memcached is a caching server, storing data in the
-form of pairs key/value, and memcache is the protocol to talk with it.
-
-To connect to a server, create a factory for L{MemCacheProtocol}::
-
- from twisted.internet import reactor, protocol
- from twisted.protocols.memcache import MemCacheProtocol, DEFAULT_PORT
- d = protocol.ClientCreator(reactor, MemCacheProtocol
- ).connectTCP("localhost", DEFAULT_PORT)
- def doSomething(proto):
- # Here you call the memcache operations
- return proto.set("mykey", "a lot of data")
- d.addCallback(doSomething)
- reactor.run()
-
-All the operations of the memcache protocol are present, but
-L{MemCacheProtocol.set} and L{MemCacheProtocol.get} are the more important.
-
-See U{http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt} for
-more information about the protocol.
-"""
-
-try:
- from collections import deque
-except ImportError:
- class deque(list):
- def popleft(self):
- return self.pop(0)
-
-
-from twisted.protocols.basic import LineReceiver
-from twisted.protocols.policies import TimeoutMixin
-from twisted.internet.defer import Deferred, fail, TimeoutError
-from twisted.python import log
-
-
-
-DEFAULT_PORT = 11211
-
-
-
-class NoSuchCommand(Exception):
- """
- Exception raised when a non existent command is called.
- """
-
-
-
-class ClientError(Exception):
- """
- Error caused by an invalid client call.
- """
-
-
-
-class ServerError(Exception):
- """
- Problem happening on the server.
- """
-
-
-
-class Command(object):
- """
- Wrap a client action into an object, that holds the values used in the
- protocol.
-
- @ivar _deferred: the L{Deferred} object that will be fired when the result
- arrives.
- @type _deferred: L{Deferred}
-
- @ivar command: name of the command sent to the server.
- @type command: C{str}
- """
-
- def __init__(self, command, **kwargs):
- """
- Create a command.
-
- @param command: the name of the command.
- @type command: C{str}
-
- @param kwargs: this values will be stored as attributes of the object
- for future use
- """
- self.command = command
- self._deferred = Deferred()
- for k, v in kwargs.items():
- setattr(self, k, v)
-
-
- def success(self, value):
- """
- Shortcut method to fire the underlying deferred.
- """
- self._deferred.callback(value)
-
-
- def fail(self, error):
- """
- Make the underlying deferred fails.
- """
- self._deferred.errback(error)
-
-
-
-class MemCacheProtocol(LineReceiver, TimeoutMixin):
- """
- MemCache protocol: connect to a memcached server to store/retrieve values.
-
- @ivar persistentTimeOut: the timeout period used to wait for a response.
- @type persistentTimeOut: C{int}
-
- @ivar _current: current list of requests waiting for an answer from the
- server.
- @type _current: C{deque} of L{Command}
-
- @ivar _lenExpected: amount of data expected in raw mode, when reading for
- a value.
- @type _lenExpected: C{int}
-
- @ivar _getBuffer: current buffer of data, used to store temporary data
- when reading in raw mode.
- @type _getBuffer: C{list}
-
- @ivar _bufferLength: the total amount of bytes in C{_getBuffer}.
- @type _bufferLength: C{int}
-
- @ivar _disconnected: indicate if the connectionLost has been called or not.
- @type _disconnected: C{bool}
- """
- MAX_KEY_LENGTH = 250
- _disconnected = False
-
- def __init__(self, timeOut=60):
- """
- Create the protocol.
-
- @param timeOut: the timeout to wait before detecting that the
- connection is dead and close it. It's expressed in seconds.
- @type timeOut: C{int}
- """
- self._current = deque()
- self._lenExpected = None
- self._getBuffer = None
- self._bufferLength = None
- self.persistentTimeOut = self.timeOut = timeOut
-
-
- def _cancelCommands(self, reason):
- """
- Cancel all the outstanding commands, making them fail with C{reason}.
- """
- while self._current:
- cmd = self._current.popleft()
- cmd.fail(reason)
-
-
- def timeoutConnection(self):
- """
- Close the connection in case of timeout.
- """
- self._cancelCommands(TimeoutError("Connection timeout"))
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- """
- Cause any outstanding commands to fail.
- """
- self._disconnected = True
- self._cancelCommands(reason)
- LineReceiver.connectionLost(self, reason)
-
-
- def sendLine(self, line):
- """
- Override sendLine to add a timeout to response.
- """
- if not self._current:
- self.setTimeout(self.persistentTimeOut)
- LineReceiver.sendLine(self, line)
-
-
- def rawDataReceived(self, data):
- """
- Collect data for a get.
- """
- self.resetTimeout()
- self._getBuffer.append(data)
- self._bufferLength += len(data)
- if self._bufferLength >= self._lenExpected + 2:
- data = "".join(self._getBuffer)
- buf = data[:self._lenExpected]
- rem = data[self._lenExpected + 2:]
- val = buf
- self._lenExpected = None
- self._getBuffer = None
- self._bufferLength = None
- cmd = self._current[0]
- if cmd.multiple:
- flags, cas = cmd.values[cmd.currentKey]
- cmd.values[cmd.currentKey] = (flags, cas, val)
- else:
- cmd.value = val
- self.setLineMode(rem)
-
-
- def cmd_STORED(self):
- """
- Manage a success response to a set operation.
- """
- self._current.popleft().success(True)
-
-
- def cmd_NOT_STORED(self):
- """
- Manage a specific 'not stored' response to a set operation: this is not
- an error, but some condition wasn't met.
- """
- self._current.popleft().success(False)
-
-
- def cmd_END(self):
- """
- This the end token to a get or a stat operation.
- """
- cmd = self._current.popleft()
- if cmd.command == "get":
- if cmd.multiple:
- values = dict([(key, val[::2]) for key, val in
- cmd.values.iteritems()])
- cmd.success(values)
- else:
- cmd.success((cmd.flags, cmd.value))
- elif cmd.command == "gets":
- if cmd.multiple:
- cmd.success(cmd.values)
- else:
- cmd.success((cmd.flags, cmd.cas, cmd.value))
- elif cmd.command == "stats":
- cmd.success(cmd.values)
-
-
- def cmd_NOT_FOUND(self):
- """
- Manage error response for incr/decr/delete.
- """
- self._current.popleft().success(False)
-
-
- def cmd_VALUE(self, line):
- """
- Prepare the reading a value after a get.
- """
- cmd = self._current[0]
- if cmd.command == "get":
- key, flags, length = line.split()
- cas = ""
- else:
- key, flags, length, cas = line.split()
- self._lenExpected = int(length)
- self._getBuffer = []
- self._bufferLength = 0
- if cmd.multiple:
- if key not in cmd.keys:
- raise RuntimeError("Unexpected commands answer.")
- cmd.currentKey = key
- cmd.values[key] = [int(flags), cas]
- else:
- if cmd.key != key:
- raise RuntimeError("Unexpected commands answer.")
- cmd.flags = int(flags)
- cmd.cas = cas
- self.setRawMode()
-
-
- def cmd_STAT(self, line):
- """
- Reception of one stat line.
- """
- cmd = self._current[0]
- key, val = line.split(" ", 1)
- cmd.values[key] = val
-
-
- def cmd_VERSION(self, versionData):
- """
- Read version token.
- """
- self._current.popleft().success(versionData)
-
-
- def cmd_ERROR(self):
- """
- An non-existent command has been sent.
- """
- log.err("Non-existent command sent.")
- cmd = self._current.popleft()
- cmd.fail(NoSuchCommand())
-
-
- def cmd_CLIENT_ERROR(self, errText):
- """
- An invalid input as been sent.
- """
- log.err("Invalid input: %s" % (errText,))
- cmd = self._current.popleft()
- cmd.fail(ClientError(errText))
-
-
- def cmd_SERVER_ERROR(self, errText):
- """
- An error has happened server-side.
- """
- log.err("Server error: %s" % (errText,))
- cmd = self._current.popleft()
- cmd.fail(ServerError(errText))
-
-
- def cmd_DELETED(self):
- """
- A delete command has completed successfully.
- """
- self._current.popleft().success(True)
-
-
- def cmd_OK(self):
- """
- The last command has been completed.
- """
- self._current.popleft().success(True)
-
-
- def cmd_EXISTS(self):
- """
- A C{checkAndSet} update has failed.
- """
- self._current.popleft().success(False)
-
-
- def lineReceived(self, line):
- """
- Receive line commands from the server.
- """
- self.resetTimeout()
- token = line.split(" ", 1)[0]
- # First manage standard commands without space
- cmd = getattr(self, "cmd_%s" % (token,), None)
- if cmd is not None:
- args = line.split(" ", 1)[1:]
- if args:
- cmd(args[0])
- else:
- cmd()
- else:
- # Then manage commands with space in it
- line = line.replace(" ", "_")
- cmd = getattr(self, "cmd_%s" % (line,), None)
- if cmd is not None:
- cmd()
- else:
- # Increment/Decrement response
- cmd = self._current.popleft()
- val = int(line)
- cmd.success(val)
- if not self._current:
- # No pending request, remove timeout
- self.setTimeout(None)
-
-
- def increment(self, key, val=1):
- """
- Increment the value of C{key} by given value (default to 1).
- C{key} must be consistent with an int. Return the new value.
-
- @param key: the key to modify.
- @type key: C{str}
-
- @param val: the value to increment.
- @type val: C{int}
-
- @return: a deferred with will be called back with the new value
- associated with the key (after the increment).
- @rtype: L{Deferred}
- """
- return self._incrdecr("incr", key, val)
-
-
- def decrement(self, key, val=1):
- """
- Decrement the value of C{key} by given value (default to 1).
- C{key} must be consistent with an int. Return the new value, coerced to
- 0 if negative.
-
- @param key: the key to modify.
- @type key: C{str}
-
- @param val: the value to decrement.
- @type val: C{int}
-
- @return: a deferred with will be called back with the new value
- associated with the key (after the decrement).
- @rtype: L{Deferred}
- """
- return self._incrdecr("decr", key, val)
-
-
- def _incrdecr(self, cmd, key, val):
- """
- Internal wrapper for incr/decr.
- """
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- if not isinstance(key, str):
- return fail(ClientError(
- "Invalid type for key: %s, expecting a string" % (type(key),)))
- if len(key) > self.MAX_KEY_LENGTH:
- return fail(ClientError("Key too long"))
- fullcmd = "%s %s %d" % (cmd, key, int(val))
- self.sendLine(fullcmd)
- cmdObj = Command(cmd, key=key)
- self._current.append(cmdObj)
- return cmdObj._deferred
-
-
- def replace(self, key, val, flags=0, expireTime=0):
- """
- Replace the given C{key}. It must already exist in the server.
-
- @param key: the key to replace.
- @type key: C{str}
-
- @param val: the new value associated with the key.
- @type val: C{str}
-
- @param flags: the flags to store with the key.
- @type flags: C{int}
-
- @param expireTime: if different from 0, the relative time in seconds
- when the key will be deleted from the store.
- @type expireTime: C{int}
-
- @return: a deferred that will fire with C{True} if the operation has
- succeeded, and C{False} with the key didn't previously exist.
- @rtype: L{Deferred}
- """
- return self._set("replace", key, val, flags, expireTime, "")
-
-
- def add(self, key, val, flags=0, expireTime=0):
- """
- Add the given C{key}. It must not exist in the server.
-
- @param key: the key to add.
- @type key: C{str}
-
- @param val: the value associated with the key.
- @type val: C{str}
-
- @param flags: the flags to store with the key.
- @type flags: C{int}
-
- @param expireTime: if different from 0, the relative time in seconds
- when the key will be deleted from the store.
- @type expireTime: C{int}
-
- @return: a deferred that will fire with C{True} if the operation has
- succeeded, and C{False} with the key already exists.
- @rtype: L{Deferred}
- """
- return self._set("add", key, val, flags, expireTime, "")
-
-
- def set(self, key, val, flags=0, expireTime=0):
- """
- Set the given C{key}.
-
- @param key: the key to set.
- @type key: C{str}
-
- @param val: the value associated with the key.
- @type val: C{str}
-
- @param flags: the flags to store with the key.
- @type flags: C{int}
-
- @param expireTime: if different from 0, the relative time in seconds
- when the key will be deleted from the store.
- @type expireTime: C{int}
-
- @return: a deferred that will fire with C{True} if the operation has
- succeeded.
- @rtype: L{Deferred}
- """
- return self._set("set", key, val, flags, expireTime, "")
-
-
- def checkAndSet(self, key, val, cas, flags=0, expireTime=0):
- """
- Change the content of C{key} only if the C{cas} value matches the
- current one associated with the key. Use this to store a value which
- hasn't been modified since last time you fetched it.
-
- @param key: The key to set.
- @type key: C{str}
-
- @param val: The value associated with the key.
- @type val: C{str}
-
- @param cas: Unique 64-bit value returned by previous call of C{get}.
- @type cas: C{str}
-
- @param flags: The flags to store with the key.
- @type flags: C{int}
-
- @param expireTime: If different from 0, the relative time in seconds
- when the key will be deleted from the store.
- @type expireTime: C{int}
-
- @return: A deferred that will fire with C{True} if the operation has
- succeeded, C{False} otherwise.
- @rtype: L{Deferred}
- """
- return self._set("cas", key, val, flags, expireTime, cas)
-
-
- def _set(self, cmd, key, val, flags, expireTime, cas):
- """
- Internal wrapper for setting values.
- """
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- if not isinstance(key, str):
- return fail(ClientError(
- "Invalid type for key: %s, expecting a string" % (type(key),)))
- if len(key) > self.MAX_KEY_LENGTH:
- return fail(ClientError("Key too long"))
- if not isinstance(val, str):
- return fail(ClientError(
- "Invalid type for value: %s, expecting a string" %
- (type(val),)))
- if cas:
- cas = " " + cas
- length = len(val)
- fullcmd = "%s %s %d %d %d%s" % (
- cmd, key, flags, expireTime, length, cas)
- self.sendLine(fullcmd)
- self.sendLine(val)
- cmdObj = Command(cmd, key=key, flags=flags, length=length)
- self._current.append(cmdObj)
- return cmdObj._deferred
-
-
- def append(self, key, val):
- """
- Append given data to the value of an existing key.
-
- @param key: The key to modify.
- @type key: C{str}
-
- @param val: The value to append to the current value associated with
- the key.
- @type val: C{str}
-
- @return: A deferred that will fire with C{True} if the operation has
- succeeded, C{False} otherwise.
- @rtype: L{Deferred}
- """
- # Even if flags and expTime values are ignored, we have to pass them
- return self._set("append", key, val, 0, 0, "")
-
-
- def prepend(self, key, val):
- """
- Prepend given data to the value of an existing key.
-
- @param key: The key to modify.
- @type key: C{str}
-
- @param val: The value to prepend to the current value associated with
- the key.
- @type val: C{str}
-
- @return: A deferred that will fire with C{True} if the operation has
- succeeded, C{False} otherwise.
- @rtype: L{Deferred}
- """
- # Even if flags and expTime values are ignored, we have to pass them
- return self._set("prepend", key, val, 0, 0, "")
-
-
- def get(self, key, withIdentifier=False):
- """
- Get the given C{key}. It doesn't support multiple keys. If
- C{withIdentifier} is set to C{True}, the command issued is a C{gets},
- that will return the current identifier associated with the value. This
- identifier has to be used when issuing C{checkAndSet} update later,
- using the corresponding method.
-
- @param key: The key to retrieve.
- @type key: C{str}
-
- @param withIdentifier: If set to C{True}, retrieve the current
- identifier along with the value and the flags.
- @type withIdentifier: C{bool}
-
- @return: A deferred that will fire with the tuple (flags, value) if
- C{withIdentifier} is C{False}, or (flags, cas identifier, value)
- if C{True}. If the server indicates there is no value
- associated with C{key}, the returned value will be C{None} and
- the returned flags will be C{0}.
- @rtype: L{Deferred}
- """
- return self._get([key], withIdentifier, False)
-
-
- def getMultiple(self, keys, withIdentifier=False):
- """
- Get the given list of C{keys}. If C{withIdentifier} is set to C{True},
- the command issued is a C{gets}, that will return the identifiers
- associated with each values. This identifier has to be used when
- issuing C{checkAndSet} update later, using the corresponding method.
-
- @param keys: The keys to retrieve.
- @type keys: C{list} of C{str}
-
- @param withIdentifier: If set to C{True}, retrieve the identifiers
- along with the values and the flags.
- @type withIdentifier: C{bool}
-
- @return: A deferred that will fire with a dictionary with the elements
- of C{keys} as keys and the tuples (flags, value) as values if
- C{withIdentifier} is C{False}, or (flags, cas identifier, value) if
- C{True}. If the server indicates there is no value associated with
- C{key}, the returned values will be C{None} and the returned flags
- will be C{0}.
- @rtype: L{Deferred}
-
- @since: 9.0
- """
- return self._get(keys, withIdentifier, True)
-
- def _get(self, keys, withIdentifier, multiple):
- """
- Helper method for C{get} and C{getMultiple}.
- """
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- for key in keys:
- if not isinstance(key, str):
- return fail(ClientError(
- "Invalid type for key: %s, expecting a string" % (type(key),)))
- if len(key) > self.MAX_KEY_LENGTH:
- return fail(ClientError("Key too long"))
- if withIdentifier:
- cmd = "gets"
- else:
- cmd = "get"
- fullcmd = "%s %s" % (cmd, " ".join(keys))
- self.sendLine(fullcmd)
- if multiple:
- values = dict([(key, (0, "", None)) for key in keys])
- cmdObj = Command(cmd, keys=keys, values=values, multiple=True)
- else:
- cmdObj = Command(cmd, key=keys[0], value=None, flags=0, cas="",
- multiple=False)
- self._current.append(cmdObj)
- return cmdObj._deferred
-
- def stats(self, arg=None):
- """
- Get some stats from the server. It will be available as a dict.
-
- @param arg: An optional additional string which will be sent along
- with the I{stats} command. The interpretation of this value by
- the server is left undefined by the memcache protocol
- specification.
- @type arg: L{NoneType} or L{str}
-
- @return: a deferred that will fire with a C{dict} of the available
- statistics.
- @rtype: L{Deferred}
- """
- if arg:
- cmd = "stats " + arg
- else:
- cmd = "stats"
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- self.sendLine(cmd)
- cmdObj = Command("stats", values={})
- self._current.append(cmdObj)
- return cmdObj._deferred
-
-
- def version(self):
- """
- Get the version of the server.
-
- @return: a deferred that will fire with the string value of the
- version.
- @rtype: L{Deferred}
- """
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- self.sendLine("version")
- cmdObj = Command("version")
- self._current.append(cmdObj)
- return cmdObj._deferred
-
-
- def delete(self, key):
- """
- Delete an existing C{key}.
-
- @param key: the key to delete.
- @type key: C{str}
-
- @return: a deferred that will be called back with C{True} if the key
- was successfully deleted, or C{False} if not.
- @rtype: L{Deferred}
- """
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- if not isinstance(key, str):
- return fail(ClientError(
- "Invalid type for key: %s, expecting a string" % (type(key),)))
- self.sendLine("delete %s" % key)
- cmdObj = Command("delete", key=key)
- self._current.append(cmdObj)
- return cmdObj._deferred
-
-
- def flushAll(self):
- """
- Flush all cached values.
-
- @return: a deferred that will be called back with C{True} when the
- operation has succeeded.
- @rtype: L{Deferred}
- """
- if self._disconnected:
- return fail(RuntimeError("not connected"))
- self.sendLine("flush_all")
- cmdObj = Command("flush_all")
- self._current.append(cmdObj)
- return cmdObj._deferred
-
-
-
-__all__ = ["MemCacheProtocol", "DEFAULT_PORT", "NoSuchCommand", "ClientError",
- "ServerError"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/__init__.py
deleted file mode 100755
index fda89c58..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""Mice Protocols."""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/mouseman.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/mouseman.py
deleted file mode 100755
index 4071b202..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/mice/mouseman.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""Logictech MouseMan serial protocol.
-
-http://www.softnco.demon.co.uk/SerialMouse.txt
-"""
-
-from twisted.internet import protocol
-
-class MouseMan(protocol.Protocol):
- """
-
- Parser for Logitech MouseMan serial mouse protocol (compatible
- with Microsoft Serial Mouse).
-
- """
-
- state = 'initial'
-
- leftbutton=None
- rightbutton=None
- middlebutton=None
-
- leftold=None
- rightold=None
- middleold=None
-
- horiz=None
- vert=None
- horizold=None
- vertold=None
-
- def down_left(self):
- pass
-
- def up_left(self):
- pass
-
- def down_middle(self):
- pass
-
- def up_middle(self):
- pass
-
- def down_right(self):
- pass
-
- def up_right(self):
- pass
-
- def move(self, x, y):
- pass
-
- horiz=None
- vert=None
-
- def state_initial(self, byte):
- if byte & 1<<6:
- self.word1=byte
- self.leftbutton = byte & 1<<5
- self.rightbutton = byte & 1<<4
- return 'horiz'
- else:
- return 'initial'
-
- def state_horiz(self, byte):
- if byte & 1<<6:
- return self.state_initial(byte)
- else:
- x=(self.word1 & 0x03)<<6 | (byte & 0x3f)
- if x>=128:
- x=-256+x
- self.horiz = x
- return 'vert'
-
- def state_vert(self, byte):
- if byte & 1<<6:
- # short packet
- return self.state_initial(byte)
- else:
- x = (self.word1 & 0x0c)<<4 | (byte & 0x3f)
- if x>=128:
- x=-256+x
- self.vert = x
- self.snapshot()
- return 'maybemiddle'
-
- def state_maybemiddle(self, byte):
- if byte & 1<<6:
- self.snapshot()
- return self.state_initial(byte)
- else:
- self.middlebutton=byte & 1<<5
- self.snapshot()
- return 'initial'
-
- def snapshot(self):
- if self.leftbutton and not self.leftold:
- self.down_left()
- self.leftold=1
- if not self.leftbutton and self.leftold:
- self.up_left()
- self.leftold=0
-
- if self.middlebutton and not self.middleold:
- self.down_middle()
- self.middleold=1
- if not self.middlebutton and self.middleold:
- self.up_middle()
- self.middleold=0
-
- if self.rightbutton and not self.rightold:
- self.down_right()
- self.rightold=1
- if not self.rightbutton and self.rightold:
- self.up_right()
- self.rightold=0
-
- if self.horiz or self.vert:
- self.move(self.horiz, self.vert)
-
- def dataReceived(self, data):
- for c in data:
- byte = ord(c)
- self.state = getattr(self, 'state_'+self.state)(byte)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/pcp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/pcp.py
deleted file mode 100755
index 8970f901..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/pcp.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# -*- test-case-name: twisted.test.test_pcp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Producer-Consumer Proxy.
-"""
-
-from zope.interface import implements
-
-from twisted.internet import interfaces
-
-
-class BasicProducerConsumerProxy:
- """
- I can act as a man in the middle between any Producer and Consumer.
-
- @ivar producer: the Producer I subscribe to.
- @type producer: L{IProducer<interfaces.IProducer>}
- @ivar consumer: the Consumer I publish to.
- @type consumer: L{IConsumer<interfaces.IConsumer>}
- @ivar paused: As a Producer, am I paused?
- @type paused: bool
- """
- implements(interfaces.IProducer, interfaces.IConsumer)
-
- consumer = None
- producer = None
- producerIsStreaming = None
- iAmStreaming = True
- outstandingPull = False
- paused = False
- stopped = False
-
- def __init__(self, consumer):
- self._buffer = []
- if consumer is not None:
- self.consumer = consumer
- consumer.registerProducer(self, self.iAmStreaming)
-
- # Producer methods:
-
- def pauseProducing(self):
- self.paused = True
- if self.producer:
- self.producer.pauseProducing()
-
- def resumeProducing(self):
- self.paused = False
- if self._buffer:
- # TODO: Check to see if consumer supports writeSeq.
- self.consumer.write(''.join(self._buffer))
- self._buffer[:] = []
- else:
- if not self.iAmStreaming:
- self.outstandingPull = True
-
- if self.producer is not None:
- self.producer.resumeProducing()
-
- def stopProducing(self):
- if self.producer is not None:
- self.producer.stopProducing()
- if self.consumer is not None:
- del self.consumer
-
- # Consumer methods:
-
- def write(self, data):
- if self.paused or (not self.iAmStreaming and not self.outstandingPull):
- # We could use that fifo queue here.
- self._buffer.append(data)
-
- elif self.consumer is not None:
- self.consumer.write(data)
- self.outstandingPull = False
-
- def finish(self):
- if self.consumer is not None:
- self.consumer.finish()
- self.unregisterProducer()
-
- def registerProducer(self, producer, streaming):
- self.producer = producer
- self.producerIsStreaming = streaming
-
- def unregisterProducer(self):
- if self.producer is not None:
- del self.producer
- del self.producerIsStreaming
- if self.consumer:
- self.consumer.unregisterProducer()
-
- def __repr__(self):
- return '<%s@%x around %s>' % (self.__class__, id(self), self.consumer)
-
-
-class ProducerConsumerProxy(BasicProducerConsumerProxy):
- """ProducerConsumerProxy with a finite buffer.
-
- When my buffer fills up, I have my parent Producer pause until my buffer
- has room in it again.
- """
- # Copies much from abstract.FileDescriptor
- bufferSize = 2**2**2**2
-
- producerPaused = False
- unregistered = False
-
- def pauseProducing(self):
- # Does *not* call up to ProducerConsumerProxy to relay the pause
- # message through to my parent Producer.
- self.paused = True
-
- def resumeProducing(self):
- self.paused = False
- if self._buffer:
- data = ''.join(self._buffer)
- bytesSent = self._writeSomeData(data)
- if bytesSent < len(data):
- unsent = data[bytesSent:]
- assert not self.iAmStreaming, (
- "Streaming producer did not write all its data.")
- self._buffer[:] = [unsent]
- else:
- self._buffer[:] = []
- else:
- bytesSent = 0
-
- if (self.unregistered and bytesSent and not self._buffer and
- self.consumer is not None):
- self.consumer.unregisterProducer()
-
- if not self.iAmStreaming:
- self.outstandingPull = not bytesSent
-
- if self.producer is not None:
- bytesBuffered = sum([len(s) for s in self._buffer])
- # TODO: You can see here the potential for high and low
- # watermarks, where bufferSize would be the high mark when we
- # ask the upstream producer to pause, and we wouldn't have
- # it resume again until it hit the low mark. Or if producer
- # is Pull, maybe we'd like to pull from it as much as necessary
- # to keep our buffer full to the low mark, so we're never caught
- # without something to send.
- if self.producerPaused and (bytesBuffered < self.bufferSize):
- # Now that our buffer is empty,
- self.producerPaused = False
- self.producer.resumeProducing()
- elif self.outstandingPull:
- # I did not have any data to write in response to a pull,
- # so I'd better pull some myself.
- self.producer.resumeProducing()
-
- def write(self, data):
- if self.paused or (not self.iAmStreaming and not self.outstandingPull):
- # We could use that fifo queue here.
- self._buffer.append(data)
-
- elif self.consumer is not None:
- assert not self._buffer, (
- "Writing fresh data to consumer before my buffer is empty!")
- # I'm going to use _writeSomeData here so that there is only one
- # path to self.consumer.write. But it doesn't actually make sense,
- # if I am streaming, for some data to not be all data. But maybe I
- # am not streaming, but I am writing here anyway, because there was
- # an earlier request for data which was not answered.
- bytesSent = self._writeSomeData(data)
- self.outstandingPull = False
- if not bytesSent == len(data):
- assert not self.iAmStreaming, (
- "Streaming producer did not write all its data.")
- self._buffer.append(data[bytesSent:])
-
- if (self.producer is not None) and self.producerIsStreaming:
- bytesBuffered = sum([len(s) for s in self._buffer])
- if bytesBuffered >= self.bufferSize:
-
- self.producer.pauseProducing()
- self.producerPaused = True
-
- def registerProducer(self, producer, streaming):
- self.unregistered = False
- BasicProducerConsumerProxy.registerProducer(self, producer, streaming)
- if not streaming:
- producer.resumeProducing()
-
- def unregisterProducer(self):
- if self.producer is not None:
- del self.producer
- del self.producerIsStreaming
- self.unregistered = True
- if self.consumer and not self._buffer:
- self.consumer.unregisterProducer()
-
- def _writeSomeData(self, data):
- """Write as much of this data as possible.
-
- @returns: The number of bytes written.
- """
- if self.consumer is None:
- return 0
- self.consumer.write(data)
- return len(data)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/policies.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/policies.py
deleted file mode 100755
index 83a3ec7d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/policies.py
+++ /dev/null
@@ -1,725 +0,0 @@
-# -*- test-case-name: twisted.test.test_policies -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Resource limiting policies.
-
-@seealso: See also L{twisted.protocols.htb} for rate limiting.
-"""
-
-# system imports
-import sys, operator
-
-from zope.interface import directlyProvides, providedBy
-
-# twisted imports
-from twisted.internet.protocol import ServerFactory, Protocol, ClientFactory
-from twisted.internet import error
-from twisted.internet.interfaces import ILoggingContext
-from twisted.python import log
-
-
-def _wrappedLogPrefix(wrapper, wrapped):
- """
- Compute a log prefix for a wrapper and the object it wraps.
-
- @rtype: C{str}
- """
- if ILoggingContext.providedBy(wrapped):
- logPrefix = wrapped.logPrefix()
- else:
- logPrefix = wrapped.__class__.__name__
- return "%s (%s)" % (logPrefix, wrapper.__class__.__name__)
-
-
-
-class ProtocolWrapper(Protocol):
- """
- Wraps protocol instances and acts as their transport as well.
-
- @ivar wrappedProtocol: An L{IProtocol<twisted.internet.interfaces.IProtocol>}
- provider to which L{IProtocol<twisted.internet.interfaces.IProtocol>}
- method calls onto this L{ProtocolWrapper} will be proxied.
-
- @ivar factory: The L{WrappingFactory} which created this
- L{ProtocolWrapper}.
- """
-
- disconnecting = 0
-
- def __init__(self, factory, wrappedProtocol):
- self.wrappedProtocol = wrappedProtocol
- self.factory = factory
-
-
- def logPrefix(self):
- """
- Use a customized log prefix mentioning both the wrapped protocol and
- the current one.
- """
- return _wrappedLogPrefix(self, self.wrappedProtocol)
-
-
- def makeConnection(self, transport):
- """
- When a connection is made, register this wrapper with its factory,
- save the real transport, and connect the wrapped protocol to this
- L{ProtocolWrapper} to intercept any transport calls it makes.
- """
- directlyProvides(self, providedBy(transport))
- Protocol.makeConnection(self, transport)
- self.factory.registerProtocol(self)
- self.wrappedProtocol.makeConnection(self)
-
-
- # Transport relaying
-
- def write(self, data):
- self.transport.write(data)
-
-
- def writeSequence(self, data):
- self.transport.writeSequence(data)
-
-
- def loseConnection(self):
- self.disconnecting = 1
- self.transport.loseConnection()
-
-
- def getPeer(self):
- return self.transport.getPeer()
-
-
- def getHost(self):
- return self.transport.getHost()
-
-
- def registerProducer(self, producer, streaming):
- self.transport.registerProducer(producer, streaming)
-
-
- def unregisterProducer(self):
- self.transport.unregisterProducer()
-
-
- def stopConsuming(self):
- self.transport.stopConsuming()
-
-
- def __getattr__(self, name):
- return getattr(self.transport, name)
-
-
- # Protocol relaying
-
- def dataReceived(self, data):
- self.wrappedProtocol.dataReceived(data)
-
-
- def connectionLost(self, reason):
- self.factory.unregisterProtocol(self)
- self.wrappedProtocol.connectionLost(reason)
-
-
-
-class WrappingFactory(ClientFactory):
- """
- Wraps a factory and its protocols, and keeps track of them.
- """
-
- protocol = ProtocolWrapper
-
- def __init__(self, wrappedFactory):
- self.wrappedFactory = wrappedFactory
- self.protocols = {}
-
-
- def logPrefix(self):
- """
- Generate a log prefix mentioning both the wrapped factory and this one.
- """
- return _wrappedLogPrefix(self, self.wrappedFactory)
-
-
- def doStart(self):
- self.wrappedFactory.doStart()
- ClientFactory.doStart(self)
-
-
- def doStop(self):
- self.wrappedFactory.doStop()
- ClientFactory.doStop(self)
-
-
- def startedConnecting(self, connector):
- self.wrappedFactory.startedConnecting(connector)
-
-
- def clientConnectionFailed(self, connector, reason):
- self.wrappedFactory.clientConnectionFailed(connector, reason)
-
-
- def clientConnectionLost(self, connector, reason):
- self.wrappedFactory.clientConnectionLost(connector, reason)
-
-
- def buildProtocol(self, addr):
- return self.protocol(self, self.wrappedFactory.buildProtocol(addr))
-
-
- def registerProtocol(self, p):
- """
- Called by protocol to register itself.
- """
- self.protocols[p] = 1
-
-
- def unregisterProtocol(self, p):
- """
- Called by protocols when they go away.
- """
- del self.protocols[p]
-
-
-
-class ThrottlingProtocol(ProtocolWrapper):
- """Protocol for ThrottlingFactory."""
-
- # wrap API for tracking bandwidth
-
- def write(self, data):
- self.factory.registerWritten(len(data))
- ProtocolWrapper.write(self, data)
-
- def writeSequence(self, seq):
- self.factory.registerWritten(reduce(operator.add, map(len, seq)))
- ProtocolWrapper.writeSequence(self, seq)
-
- def dataReceived(self, data):
- self.factory.registerRead(len(data))
- ProtocolWrapper.dataReceived(self, data)
-
- def registerProducer(self, producer, streaming):
- self.producer = producer
- ProtocolWrapper.registerProducer(self, producer, streaming)
-
- def unregisterProducer(self):
- del self.producer
- ProtocolWrapper.unregisterProducer(self)
-
-
- def throttleReads(self):
- self.transport.pauseProducing()
-
- def unthrottleReads(self):
- self.transport.resumeProducing()
-
- def throttleWrites(self):
- if hasattr(self, "producer"):
- self.producer.pauseProducing()
-
- def unthrottleWrites(self):
- if hasattr(self, "producer"):
- self.producer.resumeProducing()
-
-
-class ThrottlingFactory(WrappingFactory):
- """
- Throttles bandwidth and number of connections.
-
- Write bandwidth will only be throttled if there is a producer
- registered.
- """
-
- protocol = ThrottlingProtocol
-
- def __init__(self, wrappedFactory, maxConnectionCount=sys.maxint,
- readLimit=None, writeLimit=None):
- WrappingFactory.__init__(self, wrappedFactory)
- self.connectionCount = 0
- self.maxConnectionCount = maxConnectionCount
- self.readLimit = readLimit # max bytes we should read per second
- self.writeLimit = writeLimit # max bytes we should write per second
- self.readThisSecond = 0
- self.writtenThisSecond = 0
- self.unthrottleReadsID = None
- self.checkReadBandwidthID = None
- self.unthrottleWritesID = None
- self.checkWriteBandwidthID = None
-
-
- def callLater(self, period, func):
- """
- Wrapper around L{reactor.callLater} for test purpose.
- """
- from twisted.internet import reactor
- return reactor.callLater(period, func)
-
-
- def registerWritten(self, length):
- """
- Called by protocol to tell us more bytes were written.
- """
- self.writtenThisSecond += length
-
-
- def registerRead(self, length):
- """
- Called by protocol to tell us more bytes were read.
- """
- self.readThisSecond += length
-
-
- def checkReadBandwidth(self):
- """
- Checks if we've passed bandwidth limits.
- """
- if self.readThisSecond > self.readLimit:
- self.throttleReads()
- throttleTime = (float(self.readThisSecond) / self.readLimit) - 1.0
- self.unthrottleReadsID = self.callLater(throttleTime,
- self.unthrottleReads)
- self.readThisSecond = 0
- self.checkReadBandwidthID = self.callLater(1, self.checkReadBandwidth)
-
-
- def checkWriteBandwidth(self):
- if self.writtenThisSecond > self.writeLimit:
- self.throttleWrites()
- throttleTime = (float(self.writtenThisSecond) / self.writeLimit) - 1.0
- self.unthrottleWritesID = self.callLater(throttleTime,
- self.unthrottleWrites)
- # reset for next round
- self.writtenThisSecond = 0
- self.checkWriteBandwidthID = self.callLater(1, self.checkWriteBandwidth)
-
-
- def throttleReads(self):
- """
- Throttle reads on all protocols.
- """
- log.msg("Throttling reads on %s" % self)
- for p in self.protocols.keys():
- p.throttleReads()
-
-
- def unthrottleReads(self):
- """
- Stop throttling reads on all protocols.
- """
- self.unthrottleReadsID = None
- log.msg("Stopped throttling reads on %s" % self)
- for p in self.protocols.keys():
- p.unthrottleReads()
-
-
- def throttleWrites(self):
- """
- Throttle writes on all protocols.
- """
- log.msg("Throttling writes on %s" % self)
- for p in self.protocols.keys():
- p.throttleWrites()
-
-
- def unthrottleWrites(self):
- """
- Stop throttling writes on all protocols.
- """
- self.unthrottleWritesID = None
- log.msg("Stopped throttling writes on %s" % self)
- for p in self.protocols.keys():
- p.unthrottleWrites()
-
-
- def buildProtocol(self, addr):
- if self.connectionCount == 0:
- if self.readLimit is not None:
- self.checkReadBandwidth()
- if self.writeLimit is not None:
- self.checkWriteBandwidth()
-
- if self.connectionCount < self.maxConnectionCount:
- self.connectionCount += 1
- return WrappingFactory.buildProtocol(self, addr)
- else:
- log.msg("Max connection count reached!")
- return None
-
-
- def unregisterProtocol(self, p):
- WrappingFactory.unregisterProtocol(self, p)
- self.connectionCount -= 1
- if self.connectionCount == 0:
- if self.unthrottleReadsID is not None:
- self.unthrottleReadsID.cancel()
- if self.checkReadBandwidthID is not None:
- self.checkReadBandwidthID.cancel()
- if self.unthrottleWritesID is not None:
- self.unthrottleWritesID.cancel()
- if self.checkWriteBandwidthID is not None:
- self.checkWriteBandwidthID.cancel()
-
-
-
-class SpewingProtocol(ProtocolWrapper):
- def dataReceived(self, data):
- log.msg("Received: %r" % data)
- ProtocolWrapper.dataReceived(self,data)
-
- def write(self, data):
- log.msg("Sending: %r" % data)
- ProtocolWrapper.write(self,data)
-
-
-
-class SpewingFactory(WrappingFactory):
- protocol = SpewingProtocol
-
-
-
-class LimitConnectionsByPeer(WrappingFactory):
-
- maxConnectionsPerPeer = 5
-
- def startFactory(self):
- self.peerConnections = {}
-
- def buildProtocol(self, addr):
- peerHost = addr[0]
- connectionCount = self.peerConnections.get(peerHost, 0)
- if connectionCount >= self.maxConnectionsPerPeer:
- return None
- self.peerConnections[peerHost] = connectionCount + 1
- return WrappingFactory.buildProtocol(self, addr)
-
- def unregisterProtocol(self, p):
- peerHost = p.getPeer()[1]
- self.peerConnections[peerHost] -= 1
- if self.peerConnections[peerHost] == 0:
- del self.peerConnections[peerHost]
-
-
-class LimitTotalConnectionsFactory(ServerFactory):
- """
- Factory that limits the number of simultaneous connections.
-
- @type connectionCount: C{int}
- @ivar connectionCount: number of current connections.
- @type connectionLimit: C{int} or C{None}
- @cvar connectionLimit: maximum number of connections.
- @type overflowProtocol: L{Protocol} or C{None}
- @cvar overflowProtocol: Protocol to use for new connections when
- connectionLimit is exceeded. If C{None} (the default value), excess
- connections will be closed immediately.
- """
- connectionCount = 0
- connectionLimit = None
- overflowProtocol = None
-
- def buildProtocol(self, addr):
- if (self.connectionLimit is None or
- self.connectionCount < self.connectionLimit):
- # Build the normal protocol
- wrappedProtocol = self.protocol()
- elif self.overflowProtocol is None:
- # Just drop the connection
- return None
- else:
- # Too many connections, so build the overflow protocol
- wrappedProtocol = self.overflowProtocol()
-
- wrappedProtocol.factory = self
- protocol = ProtocolWrapper(self, wrappedProtocol)
- self.connectionCount += 1
- return protocol
-
- def registerProtocol(self, p):
- pass
-
- def unregisterProtocol(self, p):
- self.connectionCount -= 1
-
-
-
-class TimeoutProtocol(ProtocolWrapper):
- """
- Protocol that automatically disconnects when the connection is idle.
- """
-
- def __init__(self, factory, wrappedProtocol, timeoutPeriod):
- """
- Constructor.
-
- @param factory: An L{IFactory}.
- @param wrappedProtocol: A L{Protocol} to wrapp.
- @param timeoutPeriod: Number of seconds to wait for activity before
- timing out.
- """
- ProtocolWrapper.__init__(self, factory, wrappedProtocol)
- self.timeoutCall = None
- self.setTimeout(timeoutPeriod)
-
-
- def setTimeout(self, timeoutPeriod=None):
- """
- Set a timeout.
-
- This will cancel any existing timeouts.
-
- @param timeoutPeriod: If not C{None}, change the timeout period.
- Otherwise, use the existing value.
- """
- self.cancelTimeout()
- if timeoutPeriod is not None:
- self.timeoutPeriod = timeoutPeriod
- self.timeoutCall = self.factory.callLater(self.timeoutPeriod, self.timeoutFunc)
-
-
- def cancelTimeout(self):
- """
- Cancel the timeout.
-
- If the timeout was already cancelled, this does nothing.
- """
- if self.timeoutCall:
- try:
- self.timeoutCall.cancel()
- except error.AlreadyCalled:
- pass
- self.timeoutCall = None
-
-
- def resetTimeout(self):
- """
- Reset the timeout, usually because some activity just happened.
- """
- if self.timeoutCall:
- self.timeoutCall.reset(self.timeoutPeriod)
-
-
- def write(self, data):
- self.resetTimeout()
- ProtocolWrapper.write(self, data)
-
-
- def writeSequence(self, seq):
- self.resetTimeout()
- ProtocolWrapper.writeSequence(self, seq)
-
-
- def dataReceived(self, data):
- self.resetTimeout()
- ProtocolWrapper.dataReceived(self, data)
-
-
- def connectionLost(self, reason):
- self.cancelTimeout()
- ProtocolWrapper.connectionLost(self, reason)
-
-
- def timeoutFunc(self):
- """
- This method is called when the timeout is triggered.
-
- By default it calls L{loseConnection}. Override this if you want
- something else to happen.
- """
- self.loseConnection()
-
-
-
-class TimeoutFactory(WrappingFactory):
- """
- Factory for TimeoutWrapper.
- """
- protocol = TimeoutProtocol
-
-
- def __init__(self, wrappedFactory, timeoutPeriod=30*60):
- self.timeoutPeriod = timeoutPeriod
- WrappingFactory.__init__(self, wrappedFactory)
-
-
- def buildProtocol(self, addr):
- return self.protocol(self, self.wrappedFactory.buildProtocol(addr),
- timeoutPeriod=self.timeoutPeriod)
-
-
- def callLater(self, period, func):
- """
- Wrapper around L{reactor.callLater} for test purpose.
- """
- from twisted.internet import reactor
- return reactor.callLater(period, func)
-
-
-
-class TrafficLoggingProtocol(ProtocolWrapper):
-
- def __init__(self, factory, wrappedProtocol, logfile, lengthLimit=None,
- number=0):
- """
- @param factory: factory which created this protocol.
- @type factory: C{protocol.Factory}.
- @param wrappedProtocol: the underlying protocol.
- @type wrappedProtocol: C{protocol.Protocol}.
- @param logfile: file opened for writing used to write log messages.
- @type logfile: C{file}
- @param lengthLimit: maximum size of the datareceived logged.
- @type lengthLimit: C{int}
- @param number: identifier of the connection.
- @type number: C{int}.
- """
- ProtocolWrapper.__init__(self, factory, wrappedProtocol)
- self.logfile = logfile
- self.lengthLimit = lengthLimit
- self._number = number
-
-
- def _log(self, line):
- self.logfile.write(line + '\n')
- self.logfile.flush()
-
-
- def _mungeData(self, data):
- if self.lengthLimit and len(data) > self.lengthLimit:
- data = data[:self.lengthLimit - 12] + '<... elided>'
- return data
-
-
- # IProtocol
- def connectionMade(self):
- self._log('*')
- return ProtocolWrapper.connectionMade(self)
-
-
- def dataReceived(self, data):
- self._log('C %d: %r' % (self._number, self._mungeData(data)))
- return ProtocolWrapper.dataReceived(self, data)
-
-
- def connectionLost(self, reason):
- self._log('C %d: %r' % (self._number, reason))
- return ProtocolWrapper.connectionLost(self, reason)
-
-
- # ITransport
- def write(self, data):
- self._log('S %d: %r' % (self._number, self._mungeData(data)))
- return ProtocolWrapper.write(self, data)
-
-
- def writeSequence(self, iovec):
- self._log('SV %d: %r' % (self._number, [self._mungeData(d) for d in iovec]))
- return ProtocolWrapper.writeSequence(self, iovec)
-
-
- def loseConnection(self):
- self._log('S %d: *' % (self._number,))
- return ProtocolWrapper.loseConnection(self)
-
-
-
-class TrafficLoggingFactory(WrappingFactory):
- protocol = TrafficLoggingProtocol
-
- _counter = 0
-
- def __init__(self, wrappedFactory, logfilePrefix, lengthLimit=None):
- self.logfilePrefix = logfilePrefix
- self.lengthLimit = lengthLimit
- WrappingFactory.__init__(self, wrappedFactory)
-
-
- def open(self, name):
- return file(name, 'w')
-
-
- def buildProtocol(self, addr):
- self._counter += 1
- logfile = self.open(self.logfilePrefix + '-' + str(self._counter))
- return self.protocol(self, self.wrappedFactory.buildProtocol(addr),
- logfile, self.lengthLimit, self._counter)
-
-
- def resetCounter(self):
- """
- Reset the value of the counter used to identify connections.
- """
- self._counter = 0
-
-
-
-class TimeoutMixin:
- """
- Mixin for protocols which wish to timeout connections.
-
- Protocols that mix this in have a single timeout, set using L{setTimeout}.
- When the timeout is hit, L{timeoutConnection} is called, which, by
- default, closes the connection.
-
- @cvar timeOut: The number of seconds after which to timeout the connection.
- """
- timeOut = None
-
- __timeoutCall = None
-
- def callLater(self, period, func):
- """
- Wrapper around L{reactor.callLater} for test purpose.
- """
- from twisted.internet import reactor
- return reactor.callLater(period, func)
-
-
- def resetTimeout(self):
- """
- Reset the timeout count down.
-
- If the connection has already timed out, then do nothing. If the
- timeout has been cancelled (probably using C{setTimeout(None)}), also
- do nothing.
-
- It's often a good idea to call this when the protocol has received
- some meaningful input from the other end of the connection. "I've got
- some data, they're still there, reset the timeout".
- """
- if self.__timeoutCall is not None and self.timeOut is not None:
- self.__timeoutCall.reset(self.timeOut)
-
- def setTimeout(self, period):
- """
- Change the timeout period
-
- @type period: C{int} or C{NoneType}
- @param period: The period, in seconds, to change the timeout to, or
- C{None} to disable the timeout.
- """
- prev = self.timeOut
- self.timeOut = period
-
- if self.__timeoutCall is not None:
- if period is None:
- self.__timeoutCall.cancel()
- self.__timeoutCall = None
- else:
- self.__timeoutCall.reset(period)
- elif period is not None:
- self.__timeoutCall = self.callLater(period, self.__timedOut)
-
- return prev
-
- def __timedOut(self):
- self.__timeoutCall = None
- self.timeoutConnection()
-
- def timeoutConnection(self):
- """
- Called when the connection times out.
-
- Override to define behavior other than dropping the connection.
- """
- self.transport.loseConnection()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/portforward.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/portforward.py
deleted file mode 100755
index 626d5aaf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/portforward.py
+++ /dev/null
@@ -1,87 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A simple port forwarder.
-"""
-
-# Twisted imports
-from twisted.internet import protocol
-from twisted.python import log
-
-class Proxy(protocol.Protocol):
- noisy = True
-
- peer = None
-
- def setPeer(self, peer):
- self.peer = peer
-
- def connectionLost(self, reason):
- if self.peer is not None:
- self.peer.transport.loseConnection()
- self.peer = None
- elif self.noisy:
- log.msg("Unable to connect to peer: %s" % (reason,))
-
- def dataReceived(self, data):
- self.peer.transport.write(data)
-
-class ProxyClient(Proxy):
- def connectionMade(self):
- self.peer.setPeer(self)
-
- # Wire this and the peer transport together to enable
- # flow control (this stops connections from filling
- # this proxy memory when one side produces data at a
- # higher rate than the other can consume).
- self.transport.registerProducer(self.peer.transport, True)
- self.peer.transport.registerProducer(self.transport, True)
-
- # We're connected, everybody can read to their hearts content.
- self.peer.transport.resumeProducing()
-
-class ProxyClientFactory(protocol.ClientFactory):
-
- protocol = ProxyClient
-
- def setServer(self, server):
- self.server = server
-
- def buildProtocol(self, *args, **kw):
- prot = protocol.ClientFactory.buildProtocol(self, *args, **kw)
- prot.setPeer(self.server)
- return prot
-
- def clientConnectionFailed(self, connector, reason):
- self.server.transport.loseConnection()
-
-
-class ProxyServer(Proxy):
-
- clientProtocolFactory = ProxyClientFactory
- reactor = None
-
- def connectionMade(self):
- # Don't read anything from the connecting client until we have
- # somewhere to send it to.
- self.transport.pauseProducing()
-
- client = self.clientProtocolFactory()
- client.setServer(self)
-
- if self.reactor is None:
- from twisted.internet import reactor
- self.reactor = reactor
- self.reactor.connectTCP(self.factory.host, self.factory.port, client)
-
-
-class ProxyFactory(protocol.Factory):
- """Factory for port forwarder."""
-
- protocol = ProxyServer
-
- def __init__(self, host, port):
- self.host = host
- self.port = port
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/postfix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/postfix.py
deleted file mode 100755
index 7a2079d7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/postfix.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# -*- test-case-name: twisted.test.test_postfix -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Postfix mail transport agent related protocols.
-"""
-
-import sys
-import UserDict
-import urllib
-
-from twisted.protocols import basic
-from twisted.protocols import policies
-from twisted.internet import protocol, defer
-from twisted.python import log
-
-# urllib's quote functions just happen to match
-# the postfix semantics.
-def quote(s):
- return urllib.quote(s)
-
-def unquote(s):
- return urllib.unquote(s)
-
-class PostfixTCPMapServer(basic.LineReceiver, policies.TimeoutMixin):
- """Postfix mail transport agent TCP map protocol implementation.
-
- Receive requests for data matching given key via lineReceived,
- asks it's factory for the data with self.factory.get(key), and
- returns the data to the requester. None means no entry found.
-
- You can use postfix's postmap to test the map service::
-
- /usr/sbin/postmap -q KEY tcp:localhost:4242
-
- """
-
- timeout = 600
- delimiter = '\n'
-
- def connectionMade(self):
- self.setTimeout(self.timeout)
-
- def sendCode(self, code, message=''):
- "Send an SMTP-like code with a message."
- self.sendLine('%3.3d %s' % (code, message or ''))
-
- def lineReceived(self, line):
- self.resetTimeout()
- try:
- request, params = line.split(None, 1)
- except ValueError:
- request = line
- params = None
- try:
- f = getattr(self, 'do_' + request)
- except AttributeError:
- self.sendCode(400, 'unknown command')
- else:
- try:
- f(params)
- except:
- self.sendCode(400, 'Command %r failed: %s.' % (request, sys.exc_info()[1]))
-
- def do_get(self, key):
- if key is None:
- self.sendCode(400, 'Command %r takes 1 parameters.' % 'get')
- else:
- d = defer.maybeDeferred(self.factory.get, key)
- d.addCallbacks(self._cbGot, self._cbNot)
- d.addErrback(log.err)
-
- def _cbNot(self, fail):
- self.sendCode(400, fail.getErrorMessage())
-
- def _cbGot(self, value):
- if value is None:
- self.sendCode(500)
- else:
- self.sendCode(200, quote(value))
-
- def do_put(self, keyAndValue):
- if keyAndValue is None:
- self.sendCode(400, 'Command %r takes 2 parameters.' % 'put')
- else:
- try:
- key, value = keyAndValue.split(None, 1)
- except ValueError:
- self.sendCode(400, 'Command %r takes 2 parameters.' % 'put')
- else:
- self.sendCode(500, 'put is not implemented yet.')
-
-
-class PostfixTCPMapDictServerFactory(protocol.ServerFactory,
- UserDict.UserDict):
- """An in-memory dictionary factory for PostfixTCPMapServer."""
-
- protocol = PostfixTCPMapServer
-
-class PostfixTCPMapDeferringDictServerFactory(protocol.ServerFactory):
- """An in-memory dictionary factory for PostfixTCPMapServer."""
-
- protocol = PostfixTCPMapServer
-
- def __init__(self, data=None):
- self.data = {}
- if data is not None:
- self.data.update(data)
-
- def get(self, key):
- return defer.succeed(self.data.get(key))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/shoutcast.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/shoutcast.py
deleted file mode 100755
index 317d5e85..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/shoutcast.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Chop up shoutcast stream into MP3s and metadata, if available.
-"""
-
-from twisted.web import http
-from twisted import copyright
-
-
-class ShoutcastClient(http.HTTPClient):
- """
- Shoutcast HTTP stream.
-
- Modes can be 'length', 'meta' and 'mp3'.
-
- See U{http://www.smackfu.com/stuff/programming/shoutcast.html}
- for details on the protocol.
- """
-
- userAgent = "Twisted Shoutcast client " + copyright.version
-
- def __init__(self, path="/"):
- self.path = path
- self.got_metadata = False
- self.metaint = None
- self.metamode = "mp3"
- self.databuffer = ""
-
- def connectionMade(self):
- self.sendCommand("GET", self.path)
- self.sendHeader("User-Agent", self.userAgent)
- self.sendHeader("Icy-MetaData", "1")
- self.endHeaders()
-
- def lineReceived(self, line):
- # fix shoutcast crappiness
- if not self.firstLine and line:
- if len(line.split(": ", 1)) == 1:
- line = line.replace(":", ": ", 1)
- http.HTTPClient.lineReceived(self, line)
-
- def handleHeader(self, key, value):
- if key.lower() == 'icy-metaint':
- self.metaint = int(value)
- self.got_metadata = True
-
- def handleEndHeaders(self):
- # Lets check if we got metadata, and set the
- # appropriate handleResponsePart method.
- if self.got_metadata:
- # if we have metadata, then it has to be parsed out of the data stream
- self.handleResponsePart = self.handleResponsePart_with_metadata
- else:
- # otherwise, all the data is MP3 data
- self.handleResponsePart = self.gotMP3Data
-
- def handleResponsePart_with_metadata(self, data):
- self.databuffer += data
- while self.databuffer:
- stop = getattr(self, "handle_%s" % self.metamode)()
- if stop:
- return
-
- def handle_length(self):
- self.remaining = ord(self.databuffer[0]) * 16
- self.databuffer = self.databuffer[1:]
- self.metamode = "meta"
-
- def handle_mp3(self):
- if len(self.databuffer) > self.metaint:
- self.gotMP3Data(self.databuffer[:self.metaint])
- self.databuffer = self.databuffer[self.metaint:]
- self.metamode = "length"
- else:
- return 1
-
- def handle_meta(self):
- if len(self.databuffer) >= self.remaining:
- if self.remaining:
- data = self.databuffer[:self.remaining]
- self.gotMetaData(self.parseMetadata(data))
- self.databuffer = self.databuffer[self.remaining:]
- self.metamode = "mp3"
- else:
- return 1
-
- def parseMetadata(self, data):
- meta = []
- for chunk in data.split(';'):
- chunk = chunk.strip().replace("\x00", "")
- if not chunk:
- continue
- key, value = chunk.split('=', 1)
- if value.startswith("'") and value.endswith("'"):
- value = value[1:-1]
- meta.append((key, value))
- return meta
-
- def gotMetaData(self, metadata):
- """Called with a list of (key, value) pairs of metadata,
- if metadata is available on the server.
-
- Will only be called on non-empty metadata.
- """
- raise NotImplementedError, "implement in subclass"
-
- def gotMP3Data(self, data):
- """Called with chunk of MP3 data."""
- raise NotImplementedError, "implement in subclass"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/sip.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/sip.py
deleted file mode 100755
index 8a3f05cb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/sip.py
+++ /dev/null
@@ -1,1347 +0,0 @@
-# -*- test-case-name: twisted.test.test_sip -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Session Initialization Protocol.
-
-Documented in RFC 2543.
-[Superceded by 3261]
-
-
-This module contains a deprecated implementation of HTTP Digest authentication.
-See L{twisted.cred.credentials} and L{twisted.cred._digest} for its new home.
-"""
-
-# system imports
-import socket, time, sys, random, warnings
-from zope.interface import implements, Interface
-
-# twisted imports
-from twisted.python import log, util
-from twisted.python.deprecate import deprecated
-from twisted.python.versions import Version
-from twisted.python.hashlib import md5
-from twisted.internet import protocol, defer, reactor
-
-from twisted import cred
-import twisted.cred.error
-from twisted.cred.credentials import UsernameHashedPassword, UsernamePassword
-
-
-# sibling imports
-from twisted.protocols import basic
-
-PORT = 5060
-
-# SIP headers have short forms
-shortHeaders = {"call-id": "i",
- "contact": "m",
- "content-encoding": "e",
- "content-length": "l",
- "content-type": "c",
- "from": "f",
- "subject": "s",
- "to": "t",
- "via": "v",
- }
-
-longHeaders = {}
-for k, v in shortHeaders.items():
- longHeaders[v] = k
-del k, v
-
-statusCodes = {
- 100: "Trying",
- 180: "Ringing",
- 181: "Call Is Being Forwarded",
- 182: "Queued",
- 183: "Session Progress",
-
- 200: "OK",
-
- 300: "Multiple Choices",
- 301: "Moved Permanently",
- 302: "Moved Temporarily",
- 303: "See Other",
- 305: "Use Proxy",
- 380: "Alternative Service",
-
- 400: "Bad Request",
- 401: "Unauthorized",
- 402: "Payment Required",
- 403: "Forbidden",
- 404: "Not Found",
- 405: "Method Not Allowed",
- 406: "Not Acceptable",
- 407: "Proxy Authentication Required",
- 408: "Request Timeout",
- 409: "Conflict", # Not in RFC3261
- 410: "Gone",
- 411: "Length Required", # Not in RFC3261
- 413: "Request Entity Too Large",
- 414: "Request-URI Too Large",
- 415: "Unsupported Media Type",
- 416: "Unsupported URI Scheme",
- 420: "Bad Extension",
- 421: "Extension Required",
- 423: "Interval Too Brief",
- 480: "Temporarily Unavailable",
- 481: "Call/Transaction Does Not Exist",
- 482: "Loop Detected",
- 483: "Too Many Hops",
- 484: "Address Incomplete",
- 485: "Ambiguous",
- 486: "Busy Here",
- 487: "Request Terminated",
- 488: "Not Acceptable Here",
- 491: "Request Pending",
- 493: "Undecipherable",
-
- 500: "Internal Server Error",
- 501: "Not Implemented",
- 502: "Bad Gateway", # no donut
- 503: "Service Unavailable",
- 504: "Server Time-out",
- 505: "SIP Version not supported",
- 513: "Message Too Large",
-
- 600: "Busy Everywhere",
- 603: "Decline",
- 604: "Does not exist anywhere",
- 606: "Not Acceptable",
-}
-
-specialCases = {
- 'cseq': 'CSeq',
- 'call-id': 'Call-ID',
- 'www-authenticate': 'WWW-Authenticate',
-}
-
-
-def dashCapitalize(s):
- ''' Capitalize a string, making sure to treat - as a word seperator '''
- return '-'.join([ x.capitalize() for x in s.split('-')])
-
-def unq(s):
- if s[0] == s[-1] == '"':
- return s[1:-1]
- return s
-
-def DigestCalcHA1(
- pszAlg,
- pszUserName,
- pszRealm,
- pszPassword,
- pszNonce,
- pszCNonce,
-):
- m = md5()
- m.update(pszUserName)
- m.update(":")
- m.update(pszRealm)
- m.update(":")
- m.update(pszPassword)
- HA1 = m.digest()
- if pszAlg == "md5-sess":
- m = md5()
- m.update(HA1)
- m.update(":")
- m.update(pszNonce)
- m.update(":")
- m.update(pszCNonce)
- HA1 = m.digest()
- return HA1.encode('hex')
-
-
-DigestCalcHA1 = deprecated(Version("Twisted", 9, 0, 0))(DigestCalcHA1)
-
-def DigestCalcResponse(
- HA1,
- pszNonce,
- pszNonceCount,
- pszCNonce,
- pszQop,
- pszMethod,
- pszDigestUri,
- pszHEntity,
-):
- m = md5()
- m.update(pszMethod)
- m.update(":")
- m.update(pszDigestUri)
- if pszQop == "auth-int":
- m.update(":")
- m.update(pszHEntity)
- HA2 = m.digest().encode('hex')
-
- m = md5()
- m.update(HA1)
- m.update(":")
- m.update(pszNonce)
- m.update(":")
- if pszNonceCount and pszCNonce: # pszQop:
- m.update(pszNonceCount)
- m.update(":")
- m.update(pszCNonce)
- m.update(":")
- m.update(pszQop)
- m.update(":")
- m.update(HA2)
- hash = m.digest().encode('hex')
- return hash
-
-
-DigestCalcResponse = deprecated(Version("Twisted", 9, 0, 0))(DigestCalcResponse)
-
-_absent = object()
-
-class Via(object):
- """
- A L{Via} is a SIP Via header, representing a segment of the path taken by
- the request.
-
- See RFC 3261, sections 8.1.1.7, 18.2.2, and 20.42.
-
- @ivar transport: Network protocol used for this leg. (Probably either "TCP"
- or "UDP".)
- @type transport: C{str}
- @ivar branch: Unique identifier for this request.
- @type branch: C{str}
- @ivar host: Hostname or IP for this leg.
- @type host: C{str}
- @ivar port: Port used for this leg.
- @type port C{int}, or None.
- @ivar rportRequested: Whether to request RFC 3581 client processing or not.
- @type rportRequested: C{bool}
- @ivar rportValue: Servers wishing to honor requests for RFC 3581 processing
- should set this parameter to the source port the request was received
- from.
- @type rportValue: C{int}, or None.
-
- @ivar ttl: Time-to-live for requests on multicast paths.
- @type ttl: C{int}, or None.
- @ivar maddr: The destination multicast address, if any.
- @type maddr: C{str}, or None.
- @ivar hidden: Obsolete in SIP 2.0.
- @type hidden: C{bool}
- @ivar otherParams: Any other parameters in the header.
- @type otherParams: C{dict}
- """
-
- def __init__(self, host, port=PORT, transport="UDP", ttl=None,
- hidden=False, received=None, rport=_absent, branch=None,
- maddr=None, **kw):
- """
- Set parameters of this Via header. All arguments correspond to
- attributes of the same name.
-
- To maintain compatibility with old SIP
- code, the 'rport' argument is used to determine the values of
- C{rportRequested} and C{rportValue}. If None, C{rportRequested} is set
- to True. (The deprecated method for doing this is to pass True.) If an
- integer, C{rportValue} is set to the given value.
-
- Any arguments not explicitly named here are collected into the
- C{otherParams} dict.
- """
- self.transport = transport
- self.host = host
- self.port = port
- self.ttl = ttl
- self.hidden = hidden
- self.received = received
- if rport is True:
- warnings.warn(
- "rport=True is deprecated since Twisted 9.0.",
- DeprecationWarning,
- stacklevel=2)
- self.rportValue = None
- self.rportRequested = True
- elif rport is None:
- self.rportValue = None
- self.rportRequested = True
- elif rport is _absent:
- self.rportValue = None
- self.rportRequested = False
- else:
- self.rportValue = rport
- self.rportRequested = False
-
- self.branch = branch
- self.maddr = maddr
- self.otherParams = kw
-
-
- def _getrport(self):
- """
- Returns the rport value expected by the old SIP code.
- """
- if self.rportRequested == True:
- return True
- elif self.rportValue is not None:
- return self.rportValue
- else:
- return None
-
-
- def _setrport(self, newRPort):
- """
- L{Base._fixupNAT} sets C{rport} directly, so this method sets
- C{rportValue} based on that.
-
- @param newRPort: The new rport value.
- @type newRPort: C{int}
- """
- self.rportValue = newRPort
- self.rportRequested = False
-
-
- rport = property(_getrport, _setrport)
-
- def toString(self):
- """
- Serialize this header for use in a request or response.
- """
- s = "SIP/2.0/%s %s:%s" % (self.transport, self.host, self.port)
- if self.hidden:
- s += ";hidden"
- for n in "ttl", "branch", "maddr", "received":
- value = getattr(self, n)
- if value is not None:
- s += ";%s=%s" % (n, value)
- if self.rportRequested:
- s += ";rport"
- elif self.rportValue is not None:
- s += ";rport=%s" % (self.rport,)
-
- etc = self.otherParams.items()
- etc.sort()
- for k, v in etc:
- if v is None:
- s += ";" + k
- else:
- s += ";%s=%s" % (k, v)
- return s
-
-
-def parseViaHeader(value):
- """
- Parse a Via header.
-
- @return: The parsed version of this header.
- @rtype: L{Via}
- """
- parts = value.split(";")
- sent, params = parts[0], parts[1:]
- protocolinfo, by = sent.split(" ", 1)
- by = by.strip()
- result = {}
- pname, pversion, transport = protocolinfo.split("/")
- if pname != "SIP" or pversion != "2.0":
- raise ValueError, "wrong protocol or version: %r" % value
- result["transport"] = transport
- if ":" in by:
- host, port = by.split(":")
- result["port"] = int(port)
- result["host"] = host
- else:
- result["host"] = by
- for p in params:
- # it's the comment-striping dance!
- p = p.strip().split(" ", 1)
- if len(p) == 1:
- p, comment = p[0], ""
- else:
- p, comment = p
- if p == "hidden":
- result["hidden"] = True
- continue
- parts = p.split("=", 1)
- if len(parts) == 1:
- name, value = parts[0], None
- else:
- name, value = parts
- if name in ("rport", "ttl"):
- value = int(value)
- result[name] = value
- return Via(**result)
-
-
-class URL:
- """A SIP URL."""
-
- def __init__(self, host, username=None, password=None, port=None,
- transport=None, usertype=None, method=None,
- ttl=None, maddr=None, tag=None, other=None, headers=None):
- self.username = username
- self.host = host
- self.password = password
- self.port = port
- self.transport = transport
- self.usertype = usertype
- self.method = method
- self.tag = tag
- self.ttl = ttl
- self.maddr = maddr
- if other == None:
- self.other = []
- else:
- self.other = other
- if headers == None:
- self.headers = {}
- else:
- self.headers = headers
-
- def toString(self):
- l = []; w = l.append
- w("sip:")
- if self.username != None:
- w(self.username)
- if self.password != None:
- w(":%s" % self.password)
- w("@")
- w(self.host)
- if self.port != None:
- w(":%d" % self.port)
- if self.usertype != None:
- w(";user=%s" % self.usertype)
- for n in ("transport", "ttl", "maddr", "method", "tag"):
- v = getattr(self, n)
- if v != None:
- w(";%s=%s" % (n, v))
- for v in self.other:
- w(";%s" % v)
- if self.headers:
- w("?")
- w("&".join([("%s=%s" % (specialCases.get(h) or dashCapitalize(h), v)) for (h, v) in self.headers.items()]))
- return "".join(l)
-
- def __str__(self):
- return self.toString()
-
- def __repr__(self):
- return '<URL %s:%s@%s:%r/%s>' % (self.username, self.password, self.host, self.port, self.transport)
-
-
-def parseURL(url, host=None, port=None):
- """Return string into URL object.
-
- URIs are of of form 'sip:user@example.com'.
- """
- d = {}
- if not url.startswith("sip:"):
- raise ValueError("unsupported scheme: " + url[:4])
- parts = url[4:].split(";")
- userdomain, params = parts[0], parts[1:]
- udparts = userdomain.split("@", 1)
- if len(udparts) == 2:
- userpass, hostport = udparts
- upparts = userpass.split(":", 1)
- if len(upparts) == 1:
- d["username"] = upparts[0]
- else:
- d["username"] = upparts[0]
- d["password"] = upparts[1]
- else:
- hostport = udparts[0]
- hpparts = hostport.split(":", 1)
- if len(hpparts) == 1:
- d["host"] = hpparts[0]
- else:
- d["host"] = hpparts[0]
- d["port"] = int(hpparts[1])
- if host != None:
- d["host"] = host
- if port != None:
- d["port"] = port
- for p in params:
- if p == params[-1] and "?" in p:
- d["headers"] = h = {}
- p, headers = p.split("?", 1)
- for header in headers.split("&"):
- k, v = header.split("=")
- h[k] = v
- nv = p.split("=", 1)
- if len(nv) == 1:
- d.setdefault("other", []).append(p)
- continue
- name, value = nv
- if name == "user":
- d["usertype"] = value
- elif name in ("transport", "ttl", "maddr", "method", "tag"):
- if name == "ttl":
- value = int(value)
- d[name] = value
- else:
- d.setdefault("other", []).append(p)
- return URL(**d)
-
-
-def cleanRequestURL(url):
- """Clean a URL from a Request line."""
- url.transport = None
- url.maddr = None
- url.ttl = None
- url.headers = {}
-
-
-def parseAddress(address, host=None, port=None, clean=0):
- """Return (name, uri, params) for From/To/Contact header.
-
- @param clean: remove unnecessary info, usually for From and To headers.
- """
- address = address.strip()
- # simple 'sip:foo' case
- if address.startswith("sip:"):
- return "", parseURL(address, host=host, port=port), {}
- params = {}
- name, url = address.split("<", 1)
- name = name.strip()
- if name.startswith('"'):
- name = name[1:]
- if name.endswith('"'):
- name = name[:-1]
- url, paramstring = url.split(">", 1)
- url = parseURL(url, host=host, port=port)
- paramstring = paramstring.strip()
- if paramstring:
- for l in paramstring.split(";"):
- if not l:
- continue
- k, v = l.split("=")
- params[k] = v
- if clean:
- # rfc 2543 6.21
- url.ttl = None
- url.headers = {}
- url.transport = None
- url.maddr = None
- return name, url, params
-
-
-class SIPError(Exception):
- def __init__(self, code, phrase=None):
- if phrase is None:
- phrase = statusCodes[code]
- Exception.__init__(self, "SIP error (%d): %s" % (code, phrase))
- self.code = code
- self.phrase = phrase
-
-
-class RegistrationError(SIPError):
- """Registration was not possible."""
-
-
-class Message:
- """A SIP message."""
-
- length = None
-
- def __init__(self):
- self.headers = util.OrderedDict() # map name to list of values
- self.body = ""
- self.finished = 0
-
- def addHeader(self, name, value):
- name = name.lower()
- name = longHeaders.get(name, name)
- if name == "content-length":
- self.length = int(value)
- self.headers.setdefault(name,[]).append(value)
-
- def bodyDataReceived(self, data):
- self.body += data
-
- def creationFinished(self):
- if (self.length != None) and (self.length != len(self.body)):
- raise ValueError, "wrong body length"
- self.finished = 1
-
- def toString(self):
- s = "%s\r\n" % self._getHeaderLine()
- for n, vs in self.headers.items():
- for v in vs:
- s += "%s: %s\r\n" % (specialCases.get(n) or dashCapitalize(n), v)
- s += "\r\n"
- s += self.body
- return s
-
- def _getHeaderLine(self):
- raise NotImplementedError
-
-
-class Request(Message):
- """A Request for a URI"""
-
-
- def __init__(self, method, uri, version="SIP/2.0"):
- Message.__init__(self)
- self.method = method
- if isinstance(uri, URL):
- self.uri = uri
- else:
- self.uri = parseURL(uri)
- cleanRequestURL(self.uri)
-
- def __repr__(self):
- return "<SIP Request %d:%s %s>" % (id(self), self.method, self.uri.toString())
-
- def _getHeaderLine(self):
- return "%s %s SIP/2.0" % (self.method, self.uri.toString())
-
-
-class Response(Message):
- """A Response to a URI Request"""
-
- def __init__(self, code, phrase=None, version="SIP/2.0"):
- Message.__init__(self)
- self.code = code
- if phrase == None:
- phrase = statusCodes[code]
- self.phrase = phrase
-
- def __repr__(self):
- return "<SIP Response %d:%s>" % (id(self), self.code)
-
- def _getHeaderLine(self):
- return "SIP/2.0 %s %s" % (self.code, self.phrase)
-
-
-class MessagesParser(basic.LineReceiver):
- """A SIP messages parser.
-
- Expects dataReceived, dataDone repeatedly,
- in that order. Shouldn't be connected to actual transport.
- """
-
- version = "SIP/2.0"
- acceptResponses = 1
- acceptRequests = 1
- state = "firstline" # or "headers", "body" or "invalid"
-
- debug = 0
-
- def __init__(self, messageReceivedCallback):
- self.messageReceived = messageReceivedCallback
- self.reset()
-
- def reset(self, remainingData=""):
- self.state = "firstline"
- self.length = None # body length
- self.bodyReceived = 0 # how much of the body we received
- self.message = None
- self.header = None
- self.setLineMode(remainingData)
-
- def invalidMessage(self):
- self.state = "invalid"
- self.setRawMode()
-
- def dataDone(self):
- # clear out any buffered data that may be hanging around
- self.clearLineBuffer()
- if self.state == "firstline":
- return
- if self.state != "body":
- self.reset()
- return
- if self.length == None:
- # no content-length header, so end of data signals message done
- self.messageDone()
- elif self.length < self.bodyReceived:
- # aborted in the middle
- self.reset()
- else:
- # we have enough data and message wasn't finished? something is wrong
- raise RuntimeError, "this should never happen"
-
- def dataReceived(self, data):
- try:
- basic.LineReceiver.dataReceived(self, data)
- except:
- log.err()
- self.invalidMessage()
-
- def handleFirstLine(self, line):
- """Expected to create self.message."""
- raise NotImplementedError
-
- def lineLengthExceeded(self, line):
- self.invalidMessage()
-
- def lineReceived(self, line):
- if self.state == "firstline":
- while line.startswith("\n") or line.startswith("\r"):
- line = line[1:]
- if not line:
- return
- try:
- a, b, c = line.split(" ", 2)
- except ValueError:
- self.invalidMessage()
- return
- if a == "SIP/2.0" and self.acceptResponses:
- # response
- try:
- code = int(b)
- except ValueError:
- self.invalidMessage()
- return
- self.message = Response(code, c)
- elif c == "SIP/2.0" and self.acceptRequests:
- self.message = Request(a, b)
- else:
- self.invalidMessage()
- return
- self.state = "headers"
- return
- else:
- assert self.state == "headers"
- if line:
- # multiline header
- if line.startswith(" ") or line.startswith("\t"):
- name, value = self.header
- self.header = name, (value + line.lstrip())
- else:
- # new header
- if self.header:
- self.message.addHeader(*self.header)
- self.header = None
- try:
- name, value = line.split(":", 1)
- except ValueError:
- self.invalidMessage()
- return
- self.header = name, value.lstrip()
- # XXX we assume content-length won't be multiline
- if name.lower() == "content-length":
- try:
- self.length = int(value.lstrip())
- except ValueError:
- self.invalidMessage()
- return
- else:
- # CRLF, we now have message body until self.length bytes,
- # or if no length was given, until there is no more data
- # from the connection sending us data.
- self.state = "body"
- if self.header:
- self.message.addHeader(*self.header)
- self.header = None
- if self.length == 0:
- self.messageDone()
- return
- self.setRawMode()
-
- def messageDone(self, remainingData=""):
- assert self.state == "body"
- self.message.creationFinished()
- self.messageReceived(self.message)
- self.reset(remainingData)
-
- def rawDataReceived(self, data):
- assert self.state in ("body", "invalid")
- if self.state == "invalid":
- return
- if self.length == None:
- self.message.bodyDataReceived(data)
- else:
- dataLen = len(data)
- expectedLen = self.length - self.bodyReceived
- if dataLen > expectedLen:
- self.message.bodyDataReceived(data[:expectedLen])
- self.messageDone(data[expectedLen:])
- return
- else:
- self.bodyReceived += dataLen
- self.message.bodyDataReceived(data)
- if self.bodyReceived == self.length:
- self.messageDone()
-
-
-class Base(protocol.DatagramProtocol):
- """Base class for SIP clients and servers."""
-
- PORT = PORT
- debug = False
-
- def __init__(self):
- self.messages = []
- self.parser = MessagesParser(self.addMessage)
-
- def addMessage(self, msg):
- self.messages.append(msg)
-
- def datagramReceived(self, data, addr):
- self.parser.dataReceived(data)
- self.parser.dataDone()
- for m in self.messages:
- self._fixupNAT(m, addr)
- if self.debug:
- log.msg("Received %r from %r" % (m.toString(), addr))
- if isinstance(m, Request):
- self.handle_request(m, addr)
- else:
- self.handle_response(m, addr)
- self.messages[:] = []
-
- def _fixupNAT(self, message, (srcHost, srcPort)):
- # RFC 2543 6.40.2,
- senderVia = parseViaHeader(message.headers["via"][0])
- if senderVia.host != srcHost:
- senderVia.received = srcHost
- if senderVia.port != srcPort:
- senderVia.rport = srcPort
- message.headers["via"][0] = senderVia.toString()
- elif senderVia.rport == True:
- senderVia.received = srcHost
- senderVia.rport = srcPort
- message.headers["via"][0] = senderVia.toString()
-
- def deliverResponse(self, responseMessage):
- """Deliver response.
-
- Destination is based on topmost Via header."""
- destVia = parseViaHeader(responseMessage.headers["via"][0])
- # XXX we don't do multicast yet
- host = destVia.received or destVia.host
- port = destVia.rport or destVia.port or self.PORT
- destAddr = URL(host=host, port=port)
- self.sendMessage(destAddr, responseMessage)
-
- def responseFromRequest(self, code, request):
- """Create a response to a request message."""
- response = Response(code)
- for name in ("via", "to", "from", "call-id", "cseq"):
- response.headers[name] = request.headers.get(name, [])[:]
-
- return response
-
- def sendMessage(self, destURL, message):
- """Send a message.
-
- @param destURL: C{URL}. This should be a *physical* URL, not a logical one.
- @param message: The message to send.
- """
- if destURL.transport not in ("udp", None):
- raise RuntimeError, "only UDP currently supported"
- if self.debug:
- log.msg("Sending %r to %r" % (message.toString(), destURL))
- self.transport.write(message.toString(), (destURL.host, destURL.port or self.PORT))
-
- def handle_request(self, message, addr):
- """Override to define behavior for requests received
-
- @type message: C{Message}
- @type addr: C{tuple}
- """
- raise NotImplementedError
-
- def handle_response(self, message, addr):
- """Override to define behavior for responses received.
-
- @type message: C{Message}
- @type addr: C{tuple}
- """
- raise NotImplementedError
-
-
-class IContact(Interface):
- """A user of a registrar or proxy"""
-
-
-class Registration:
- def __init__(self, secondsToExpiry, contactURL):
- self.secondsToExpiry = secondsToExpiry
- self.contactURL = contactURL
-
-class IRegistry(Interface):
- """Allows registration of logical->physical URL mapping."""
-
- def registerAddress(domainURL, logicalURL, physicalURL):
- """Register the physical address of a logical URL.
-
- @return: Deferred of C{Registration} or failure with RegistrationError.
- """
-
- def unregisterAddress(domainURL, logicalURL, physicalURL):
- """Unregister the physical address of a logical URL.
-
- @return: Deferred of C{Registration} or failure with RegistrationError.
- """
-
- def getRegistrationInfo(logicalURL):
- """Get registration info for logical URL.
-
- @return: Deferred of C{Registration} object or failure of LookupError.
- """
-
-
-class ILocator(Interface):
- """Allow looking up physical address for logical URL."""
-
- def getAddress(logicalURL):
- """Return physical URL of server for logical URL of user.
-
- @param logicalURL: a logical C{URL}.
- @return: Deferred which becomes URL or fails with LookupError.
- """
-
-
-class Proxy(Base):
- """SIP proxy."""
-
- PORT = PORT
-
- locator = None # object implementing ILocator
-
- def __init__(self, host=None, port=PORT):
- """Create new instance.
-
- @param host: our hostname/IP as set in Via headers.
- @param port: our port as set in Via headers.
- """
- self.host = host or socket.getfqdn()
- self.port = port
- Base.__init__(self)
-
- def getVia(self):
- """Return value of Via header for this proxy."""
- return Via(host=self.host, port=self.port)
-
- def handle_request(self, message, addr):
- # send immediate 100/trying message before processing
- #self.deliverResponse(self.responseFromRequest(100, message))
- f = getattr(self, "handle_%s_request" % message.method, None)
- if f is None:
- f = self.handle_request_default
- try:
- d = f(message, addr)
- except SIPError, e:
- self.deliverResponse(self.responseFromRequest(e.code, message))
- except:
- log.err()
- self.deliverResponse(self.responseFromRequest(500, message))
- else:
- if d is not None:
- d.addErrback(lambda e:
- self.deliverResponse(self.responseFromRequest(e.code, message))
- )
-
- def handle_request_default(self, message, (srcHost, srcPort)):
- """Default request handler.
-
- Default behaviour for OPTIONS and unknown methods for proxies
- is to forward message on to the client.
-
- Since at the moment we are stateless proxy, thats basically
- everything.
- """
- def _mungContactHeader(uri, message):
- message.headers['contact'][0] = uri.toString()
- return self.sendMessage(uri, message)
-
- viaHeader = self.getVia()
- if viaHeader.toString() in message.headers["via"]:
- # must be a loop, so drop message
- log.msg("Dropping looped message.")
- return
-
- message.headers["via"].insert(0, viaHeader.toString())
- name, uri, tags = parseAddress(message.headers["to"][0], clean=1)
-
- # this is broken and needs refactoring to use cred
- d = self.locator.getAddress(uri)
- d.addCallback(self.sendMessage, message)
- d.addErrback(self._cantForwardRequest, message)
-
- def _cantForwardRequest(self, error, message):
- error.trap(LookupError)
- del message.headers["via"][0] # this'll be us
- self.deliverResponse(self.responseFromRequest(404, message))
-
- def deliverResponse(self, responseMessage):
- """Deliver response.
-
- Destination is based on topmost Via header."""
- destVia = parseViaHeader(responseMessage.headers["via"][0])
- # XXX we don't do multicast yet
- host = destVia.received or destVia.host
- port = destVia.rport or destVia.port or self.PORT
-
- destAddr = URL(host=host, port=port)
- self.sendMessage(destAddr, responseMessage)
-
- def responseFromRequest(self, code, request):
- """Create a response to a request message."""
- response = Response(code)
- for name in ("via", "to", "from", "call-id", "cseq"):
- response.headers[name] = request.headers.get(name, [])[:]
- return response
-
- def handle_response(self, message, addr):
- """Default response handler."""
- v = parseViaHeader(message.headers["via"][0])
- if (v.host, v.port) != (self.host, self.port):
- # we got a message not intended for us?
- # XXX note this check breaks if we have multiple external IPs
- # yay for suck protocols
- log.msg("Dropping incorrectly addressed message")
- return
- del message.headers["via"][0]
- if not message.headers["via"]:
- # this message is addressed to us
- self.gotResponse(message, addr)
- return
- self.deliverResponse(message)
-
- def gotResponse(self, message, addr):
- """Called with responses that are addressed at this server."""
- pass
-
-class IAuthorizer(Interface):
- def getChallenge(peer):
- """Generate a challenge the client may respond to.
-
- @type peer: C{tuple}
- @param peer: The client's address
-
- @rtype: C{str}
- @return: The challenge string
- """
-
- def decode(response):
- """Create a credentials object from the given response.
-
- @type response: C{str}
- """
-
-class BasicAuthorizer:
- """Authorizer for insecure Basic (base64-encoded plaintext) authentication.
-
- This form of authentication is broken and insecure. Do not use it.
- """
-
- implements(IAuthorizer)
-
- def __init__(self):
- """
- This method exists solely to issue a deprecation warning.
- """
- warnings.warn(
- "twisted.protocols.sip.BasicAuthorizer was deprecated "
- "in Twisted 9.0.0",
- category=DeprecationWarning,
- stacklevel=2)
-
-
- def getChallenge(self, peer):
- return None
-
- def decode(self, response):
- # At least one SIP client improperly pads its Base64 encoded messages
- for i in range(3):
- try:
- creds = (response + ('=' * i)).decode('base64')
- except:
- pass
- else:
- break
- else:
- # Totally bogus
- raise SIPError(400)
- p = creds.split(':', 1)
- if len(p) == 2:
- return UsernamePassword(*p)
- raise SIPError(400)
-
-
-
-class DigestedCredentials(UsernameHashedPassword):
- """Yet Another Simple Digest-MD5 authentication scheme"""
-
- def __init__(self, username, fields, challenges):
- warnings.warn(
- "twisted.protocols.sip.DigestedCredentials was deprecated "
- "in Twisted 9.0.0",
- category=DeprecationWarning,
- stacklevel=2)
- self.username = username
- self.fields = fields
- self.challenges = challenges
-
- def checkPassword(self, password):
- method = 'REGISTER'
- response = self.fields.get('response')
- uri = self.fields.get('uri')
- nonce = self.fields.get('nonce')
- cnonce = self.fields.get('cnonce')
- nc = self.fields.get('nc')
- algo = self.fields.get('algorithm', 'MD5')
- qop = self.fields.get('qop-options', 'auth')
- opaque = self.fields.get('opaque')
-
- if opaque not in self.challenges:
- return False
- del self.challenges[opaque]
-
- user, domain = self.username.split('@', 1)
- if uri is None:
- uri = 'sip:' + domain
-
- expected = DigestCalcResponse(
- DigestCalcHA1(algo, user, domain, password, nonce, cnonce),
- nonce, nc, cnonce, qop, method, uri, None,
- )
-
- return expected == response
-
-class DigestAuthorizer:
- CHALLENGE_LIFETIME = 15
-
- implements(IAuthorizer)
-
- def __init__(self):
- warnings.warn(
- "twisted.protocols.sip.DigestAuthorizer was deprecated "
- "in Twisted 9.0.0",
- category=DeprecationWarning,
- stacklevel=2)
-
- self.outstanding = {}
-
-
-
- def generateNonce(self):
- c = tuple([random.randrange(sys.maxint) for _ in range(3)])
- c = '%d%d%d' % c
- return c
-
- def generateOpaque(self):
- return str(random.randrange(sys.maxint))
-
- def getChallenge(self, peer):
- c = self.generateNonce()
- o = self.generateOpaque()
- self.outstanding[o] = c
- return ','.join((
- 'nonce="%s"' % c,
- 'opaque="%s"' % o,
- 'qop-options="auth"',
- 'algorithm="MD5"',
- ))
-
- def decode(self, response):
- response = ' '.join(response.splitlines())
- parts = response.split(',')
- auth = dict([(k.strip(), unq(v.strip())) for (k, v) in [p.split('=', 1) for p in parts]])
- try:
- username = auth['username']
- except KeyError:
- raise SIPError(401)
- try:
- return DigestedCredentials(username, auth, self.outstanding)
- except:
- raise SIPError(400)
-
-
-class RegisterProxy(Proxy):
- """A proxy that allows registration for a specific domain.
-
- Unregistered users won't be handled.
- """
-
- portal = None
-
- registry = None # should implement IRegistry
-
- authorizers = {}
-
- def __init__(self, *args, **kw):
- Proxy.__init__(self, *args, **kw)
- self.liveChallenges = {}
- if "digest" not in self.authorizers:
- self.authorizers["digest"] = DigestAuthorizer()
-
- def handle_ACK_request(self, message, (host, port)):
- # XXX
- # ACKs are a client's way of indicating they got the last message
- # Responding to them is not a good idea.
- # However, we should keep track of terminal messages and re-transmit
- # if no ACK is received.
- pass
-
- def handle_REGISTER_request(self, message, (host, port)):
- """Handle a registration request.
-
- Currently registration is not proxied.
- """
- if self.portal is None:
- # There is no portal. Let anyone in.
- self.register(message, host, port)
- else:
- # There is a portal. Check for credentials.
- if not message.headers.has_key("authorization"):
- return self.unauthorized(message, host, port)
- else:
- return self.login(message, host, port)
-
- def unauthorized(self, message, host, port):
- m = self.responseFromRequest(401, message)
- for (scheme, auth) in self.authorizers.iteritems():
- chal = auth.getChallenge((host, port))
- if chal is None:
- value = '%s realm="%s"' % (scheme.title(), self.host)
- else:
- value = '%s %s,realm="%s"' % (scheme.title(), chal, self.host)
- m.headers.setdefault('www-authenticate', []).append(value)
- self.deliverResponse(m)
-
-
- def login(self, message, host, port):
- parts = message.headers['authorization'][0].split(None, 1)
- a = self.authorizers.get(parts[0].lower())
- if a:
- try:
- c = a.decode(parts[1])
- except SIPError:
- raise
- except:
- log.err()
- self.deliverResponse(self.responseFromRequest(500, message))
- else:
- c.username += '@' + self.host
- self.portal.login(c, None, IContact
- ).addCallback(self._cbLogin, message, host, port
- ).addErrback(self._ebLogin, message, host, port
- ).addErrback(log.err
- )
- else:
- self.deliverResponse(self.responseFromRequest(501, message))
-
- def _cbLogin(self, (i, a, l), message, host, port):
- # It's stateless, matey. What a joke.
- self.register(message, host, port)
-
- def _ebLogin(self, failure, message, host, port):
- failure.trap(cred.error.UnauthorizedLogin)
- self.unauthorized(message, host, port)
-
- def register(self, message, host, port):
- """Allow all users to register"""
- name, toURL, params = parseAddress(message.headers["to"][0], clean=1)
- contact = None
- if message.headers.has_key("contact"):
- contact = message.headers["contact"][0]
-
- if message.headers.get("expires", [None])[0] == "0":
- self.unregister(message, toURL, contact)
- else:
- # XXX Check expires on appropriate URL, and pass it to registry
- # instead of having registry hardcode it.
- if contact is not None:
- name, contactURL, params = parseAddress(contact, host=host, port=port)
- d = self.registry.registerAddress(message.uri, toURL, contactURL)
- else:
- d = self.registry.getRegistrationInfo(toURL)
- d.addCallbacks(self._cbRegister, self._ebRegister,
- callbackArgs=(message,),
- errbackArgs=(message,)
- )
-
- def _cbRegister(self, registration, message):
- response = self.responseFromRequest(200, message)
- if registration.contactURL != None:
- response.addHeader("contact", registration.contactURL.toString())
- response.addHeader("expires", "%d" % registration.secondsToExpiry)
- response.addHeader("content-length", "0")
- self.deliverResponse(response)
-
- def _ebRegister(self, error, message):
- error.trap(RegistrationError, LookupError)
- # XXX return error message, and alter tests to deal with
- # this, currently tests assume no message sent on failure
-
- def unregister(self, message, toURL, contact):
- try:
- expires = int(message.headers["expires"][0])
- except ValueError:
- self.deliverResponse(self.responseFromRequest(400, message))
- else:
- if expires == 0:
- if contact == "*":
- contactURL = "*"
- else:
- name, contactURL, params = parseAddress(contact)
- d = self.registry.unregisterAddress(message.uri, toURL, contactURL)
- d.addCallback(self._cbUnregister, message
- ).addErrback(self._ebUnregister, message
- )
-
- def _cbUnregister(self, registration, message):
- msg = self.responseFromRequest(200, message)
- msg.headers.setdefault('contact', []).append(registration.contactURL.toString())
- msg.addHeader("expires", "0")
- self.deliverResponse(msg)
-
- def _ebUnregister(self, registration, message):
- pass
-
-
-class InMemoryRegistry:
- """A simplistic registry for a specific domain."""
-
- implements(IRegistry, ILocator)
-
- def __init__(self, domain):
- self.domain = domain # the domain we handle registration for
- self.users = {} # map username to (IDelayedCall for expiry, address URI)
-
- def getAddress(self, userURI):
- if userURI.host != self.domain:
- return defer.fail(LookupError("unknown domain"))
- if userURI.username in self.users:
- dc, url = self.users[userURI.username]
- return defer.succeed(url)
- else:
- return defer.fail(LookupError("no such user"))
-
- def getRegistrationInfo(self, userURI):
- if userURI.host != self.domain:
- return defer.fail(LookupError("unknown domain"))
- if self.users.has_key(userURI.username):
- dc, url = self.users[userURI.username]
- return defer.succeed(Registration(int(dc.getTime() - time.time()), url))
- else:
- return defer.fail(LookupError("no such user"))
-
- def _expireRegistration(self, username):
- try:
- dc, url = self.users[username]
- except KeyError:
- return defer.fail(LookupError("no such user"))
- else:
- dc.cancel()
- del self.users[username]
- return defer.succeed(Registration(0, url))
-
- def registerAddress(self, domainURL, logicalURL, physicalURL):
- if domainURL.host != self.domain:
- log.msg("Registration for domain we don't handle.")
- return defer.fail(RegistrationError(404))
- if logicalURL.host != self.domain:
- log.msg("Registration for domain we don't handle.")
- return defer.fail(RegistrationError(404))
- if logicalURL.username in self.users:
- dc, old = self.users[logicalURL.username]
- dc.reset(3600)
- else:
- dc = reactor.callLater(3600, self._expireRegistration, logicalURL.username)
- log.msg("Registered %s at %s" % (logicalURL.toString(), physicalURL.toString()))
- self.users[logicalURL.username] = (dc, physicalURL)
- return defer.succeed(Registration(int(dc.getTime() - time.time()), physicalURL))
-
- def unregisterAddress(self, domainURL, logicalURL, physicalURL):
- return self._expireRegistration(logicalURL.username)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/socks.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/socks.py
deleted file mode 100755
index 445b9f35..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/socks.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# -*- test-case-name: twisted.test.test_socks -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation of the SOCKSv4 protocol.
-"""
-
-# python imports
-import struct
-import string
-import socket
-import time
-
-# twisted imports
-from twisted.internet import reactor, protocol, defer
-from twisted.python import log
-
-
-class SOCKSv4Outgoing(protocol.Protocol):
-
- def __init__(self,socks):
- self.socks=socks
-
- def connectionMade(self):
- peer = self.transport.getPeer()
- self.socks.makeReply(90, 0, port=peer.port, ip=peer.host)
- self.socks.otherConn=self
-
- def connectionLost(self, reason):
- self.socks.transport.loseConnection()
-
- def dataReceived(self,data):
- self.socks.write(data)
-
- def write(self,data):
- self.socks.log(self,data)
- self.transport.write(data)
-
-
-
-class SOCKSv4Incoming(protocol.Protocol):
-
- def __init__(self,socks):
- self.socks=socks
- self.socks.otherConn=self
-
- def connectionLost(self, reason):
- self.socks.transport.loseConnection()
-
- def dataReceived(self,data):
- self.socks.write(data)
-
- def write(self,data):
- self.socks.log(self,data)
- self.transport.write(data)
-
-
-class SOCKSv4(protocol.Protocol):
- """
- An implementation of the SOCKSv4 protocol.
-
- @type logging: C{str} or C{None}
- @ivar logging: If not C{None}, the name of the logfile to which connection
- information will be written.
-
- @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
- @ivar reactor: The reactor used to create connections.
-
- @type buf: C{str}
- @ivar buf: Part of a SOCKSv4 connection request.
-
- @type otherConn: C{SOCKSv4Incoming}, C{SOCKSv4Outgoing} or C{None}
- @ivar otherConn: Until the connection has been established, C{otherConn} is
- C{None}. After that, it is the proxy-to-destination protocol instance
- along which the client's connection is being forwarded.
- """
- def __init__(self, logging=None, reactor=reactor):
- self.logging = logging
- self.reactor = reactor
-
- def connectionMade(self):
- self.buf = ""
- self.otherConn = None
-
- def dataReceived(self, data):
- """
- Called whenever data is received.
-
- @type data: C{str}
- @param data: Part or all of a SOCKSv4 packet.
- """
- if self.otherConn:
- self.otherConn.write(data)
- return
- self.buf = self.buf + data
- completeBuffer = self.buf
- if "\000" in self.buf[8:]:
- head, self.buf = self.buf[:8], self.buf[8:]
- version, code, port = struct.unpack("!BBH", head[:4])
- user, self.buf = self.buf.split("\000", 1)
- if head[4:7] == "\000\000\000" and head[7] != "\000":
- # An IP address of the form 0.0.0.X, where X is non-zero,
- # signifies that this is a SOCKSv4a packet.
- # If the complete packet hasn't been received, restore the
- # buffer and wait for it.
- if "\000" not in self.buf:
- self.buf = completeBuffer
- return
- server, self.buf = self.buf.split("\000", 1)
- d = self.reactor.resolve(server)
- d.addCallback(self._dataReceived2, user,
- version, code, port)
- d.addErrback(lambda result, self = self: self.makeReply(91))
- return
- else:
- server = socket.inet_ntoa(head[4:8])
-
- self._dataReceived2(server, user, version, code, port)
-
- def _dataReceived2(self, server, user, version, code, port):
- """
- The second half of the SOCKS connection setup. For a SOCKSv4 packet this
- is after the server address has been extracted from the header. For a
- SOCKSv4a packet this is after the host name has been resolved.
-
- @type server: C{str}
- @param server: The IP address of the destination, represented as a
- dotted quad.
-
- @type user: C{str}
- @param user: The username associated with the connection.
-
- @type version: C{int}
- @param version: The SOCKS protocol version number.
-
- @type code: C{int}
- @param code: The comand code. 1 means establish a TCP/IP stream
- connection, and 2 means establish a TCP/IP port binding.
-
- @type port: C{int}
- @param port: The port number associated with the connection.
- """
- assert version == 4, "Bad version code: %s" % version
- if not self.authorize(code, server, port, user):
- self.makeReply(91)
- return
- if code == 1: # CONNECT
- d = self.connectClass(server, port, SOCKSv4Outgoing, self)
- d.addErrback(lambda result, self = self: self.makeReply(91))
- elif code == 2: # BIND
- d = self.listenClass(0, SOCKSv4IncomingFactory, self, server)
- d.addCallback(lambda (h, p),
- self = self: self.makeReply(90, 0, p, h))
- else:
- raise RuntimeError, "Bad Connect Code: %s" % code
- assert self.buf == "", "hmm, still stuff in buffer... %s" % repr(
- self.buf)
-
- def connectionLost(self, reason):
- if self.otherConn:
- self.otherConn.transport.loseConnection()
-
- def authorize(self,code,server,port,user):
- log.msg("code %s connection to %s:%s (user %s) authorized" % (code,server,port,user))
- return 1
-
- def connectClass(self, host, port, klass, *args):
- return protocol.ClientCreator(reactor, klass, *args).connectTCP(host,port)
-
- def listenClass(self, port, klass, *args):
- serv = reactor.listenTCP(port, klass(*args))
- return defer.succeed(serv.getHost()[1:])
-
- def makeReply(self,reply,version=0,port=0,ip="0.0.0.0"):
- self.transport.write(struct.pack("!BBH",version,reply,port)+socket.inet_aton(ip))
- if reply!=90: self.transport.loseConnection()
-
- def write(self,data):
- self.log(self,data)
- self.transport.write(data)
-
- def log(self,proto,data):
- if not self.logging: return
- peer = self.transport.getPeer()
- their_peer = self.otherConn.transport.getPeer()
- f=open(self.logging,"a")
- f.write("%s\t%s:%d %s %s:%d\n"%(time.ctime(),
- peer.host,peer.port,
- ((proto==self and '<') or '>'),
- their_peer.host,their_peer.port))
- while data:
- p,data=data[:16],data[16:]
- f.write(string.join(map(lambda x:'%02X'%ord(x),p),' ')+' ')
- f.write((16-len(p))*3*' ')
- for c in p:
- if len(repr(c))>3: f.write('.')
- else: f.write(c)
- f.write('\n')
- f.write('\n')
- f.close()
-
-
-
-class SOCKSv4Factory(protocol.Factory):
- """
- A factory for a SOCKSv4 proxy.
-
- Constructor accepts one argument, a log file name.
- """
-
- def __init__(self, log):
- self.logging = log
-
- def buildProtocol(self, addr):
- return SOCKSv4(self.logging, reactor)
-
-
-
-class SOCKSv4IncomingFactory(protocol.Factory):
- """
- A utility class for building protocols for incoming connections.
- """
-
- def __init__(self, socks, ip):
- self.socks = socks
- self.ip = ip
-
-
- def buildProtocol(self, addr):
- if addr[0] == self.ip:
- self.ip = ""
- self.socks.makeReply(90, 0)
- return SOCKSv4Incoming(self.socks)
- elif self.ip == "":
- return None
- else:
- self.socks.makeReply(91, 0)
- self.ip = ""
- return None
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/stateful.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/stateful.py
deleted file mode 100755
index 7b82ae3d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/stateful.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- test-case-name: twisted.test.test_stateful -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.internet import protocol
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-class StatefulProtocol(protocol.Protocol):
- """A Protocol that stores state for you.
-
- state is a pair (function, num_bytes). When num_bytes bytes of data arrives
- from the network, function is called. It is expected to return the next
- state or None to keep same state. Initial state is returned by
- getInitialState (override it).
- """
- _sful_data = None, None, 0
-
- def makeConnection(self, transport):
- protocol.Protocol.makeConnection(self, transport)
- self._sful_data = self.getInitialState(), StringIO(), 0
-
- def getInitialState(self):
- raise NotImplementedError
-
- def dataReceived(self, data):
- state, buffer, offset = self._sful_data
- buffer.seek(0, 2)
- buffer.write(data)
- blen = buffer.tell() # how many bytes total is in the buffer
- buffer.seek(offset)
- while blen - offset >= state[1]:
- d = buffer.read(state[1])
- offset += state[1]
- next = state[0](d)
- if self.transport.disconnecting: # XXX: argh stupid hack borrowed right from LineReceiver
- return # dataReceived won't be called again, so who cares about consistent state
- if next:
- state = next
- if offset != 0:
- b = buffer.read()
- buffer.seek(0)
- buffer.truncate()
- buffer.write(b)
- offset = 0
- self._sful_data = state, buffer, offset
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/telnet.py
deleted file mode 100755
index ba1c8263..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/telnet.py
+++ /dev/null
@@ -1,325 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""TELNET implementation, with line-oriented command handling.
-"""
-
-import warnings
-warnings.warn(
- "As of Twisted 2.1, twisted.protocols.telnet is deprecated. "
- "See twisted.conch.telnet for the current, supported API.",
- DeprecationWarning,
- stacklevel=2)
-
-
-# System Imports
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-# Twisted Imports
-from twisted import copyright
-from twisted.internet import protocol
-
-# Some utility chars.
-ESC = chr(27) # ESC for doing fanciness
-BOLD_MODE_ON = ESC+"[1m" # turn bold on
-BOLD_MODE_OFF= ESC+"[m" # no char attributes
-
-
-# Characters gleaned from the various (and conflicting) RFCs. Not all of these are correct.
-
-NULL = chr(0) # No operation.
-LF = chr(10) # Moves the printer to the
- # next print line, keeping the
- # same horizontal position.
-CR = chr(13) # Moves the printer to the left
- # margin of the current line.
-BEL = chr(7) # Produces an audible or
- # visible signal (which does
- # NOT move the print head).
-BS = chr(8) # Moves the print head one
- # character position towards
- # the left margin.
-HT = chr(9) # Moves the printer to the
- # next horizontal tab stop.
- # It remains unspecified how
- # either party determines or
- # establishes where such tab
- # stops are located.
-VT = chr(11) # Moves the printer to the
- # next vertical tab stop. It
- # remains unspecified how
- # either party determines or
- # establishes where such tab
- # stops are located.
-FF = chr(12) # Moves the printer to the top
- # of the next page, keeping
- # the same horizontal position.
-SE = chr(240) # End of subnegotiation parameters.
-NOP= chr(241) # No operation.
-DM = chr(242) # "Data Mark": The data stream portion
- # of a Synch. This should always be
- # accompanied by a TCP Urgent
- # notification.
-BRK= chr(243) # NVT character Break.
-IP = chr(244) # The function Interrupt Process.
-AO = chr(245) # The function Abort Output
-AYT= chr(246) # The function Are You There.
-EC = chr(247) # The function Erase Character.
-EL = chr(248) # The function Erase Line
-GA = chr(249) # The Go Ahead signal.
-SB = chr(250) # Indicates that what follows is
- # subnegotiation of the indicated
- # option.
-WILL = chr(251) # Indicates the desire to begin
- # performing, or confirmation that
- # you are now performing, the
- # indicated option.
-WONT = chr(252) # Indicates the refusal to perform,
- # or continue performing, the
- # indicated option.
-DO = chr(253) # Indicates the request that the
- # other party perform, or
- # confirmation that you are expecting
- # the other party to perform, the
- # indicated option.
-DONT = chr(254) # Indicates the demand that the
- # other party stop performing,
- # or confirmation that you are no
- # longer expecting the other party
- # to perform, the indicated option.
-IAC = chr(255) # Data Byte 255.
-
-# features
-
-ECHO = chr(1) # User-to-Server: Asks the server to send
- # Echos of the transmitted data.
-
- # Server-to User: States that the server is
- # sending echos of the transmitted data.
- # Sent only as a reply to ECHO or NO ECHO.
-
-SUPGA = chr(3) # Supress Go Ahead...? "Modern" telnet servers
- # are supposed to do this.
-
-LINEMODE = chr(34) # I don't care that Jon Postel is dead.
-
-HIDE = chr(133) # The intention is that a server will send
- # this signal to a user system which is
- # echoing locally (to the user) when the user
- # is about to type something secret (e.g. a
- # password). In this case, the user system
- # is to suppress local echoing or overprint
- # the input (or something) until the server
- # sends a NOECHO signal. In situations where
- # the user system is not echoing locally,
- # this signal must not be sent by the server.
-
-
-NOECHO= chr(131) # User-to-Server: Asks the server not to
- # return Echos of the transmitted data.
- #
- # Server-to-User: States that the server is
- # not sending echos of the transmitted data.
- # Sent only as a reply to ECHO or NO ECHO,
- # or to end the hide your input.
-
-
-
-iacBytes = {
- DO: 'DO',
- DONT: 'DONT',
- WILL: 'WILL',
- WONT: 'WONT',
- IP: 'IP'
- }
-
-def multireplace(st, dct):
- for k, v in dct.items():
- st = st.replace(k, v)
- return st
-
-class Telnet(protocol.Protocol):
- """I am a Protocol for handling Telnet connections. I have two
- sets of special methods, telnet_* and iac_*.
-
- telnet_* methods get called on every line sent to me. The method
- to call is decided by the current mode. The initial mode is 'User';
- this means that telnet_User is the first telnet_* method to be called.
- All telnet_* methods should return a string which specifies the mode
- to go into next; thus dictating which telnet_* method to call next.
- For example, the default telnet_User method returns 'Password' to go
- into Password mode, and the default telnet_Password method returns
- 'Command' to go into Command mode.
-
- The iac_* methods are less-used; they are called when an IAC telnet
- byte is received. You can define iac_DO, iac_DONT, iac_WILL, iac_WONT,
- and iac_IP methods to do what you want when one of these bytes is
- received."""
-
-
- gotIAC = 0
- iacByte = None
- lastLine = None
- buffer = ''
- echo = 0
- delimiters = ['\r\n', '\r\000']
- mode = "User"
-
- def write(self, data):
- """Send the given data over my transport."""
- self.transport.write(data)
-
-
- def connectionMade(self):
- """I will write a welcomeMessage and loginPrompt to the client."""
- self.write(self.welcomeMessage() + self.loginPrompt())
-
- def welcomeMessage(self):
- """Override me to return a string which will be sent to the client
- before login."""
- x = self.factory.__class__
- return ("\r\n" + x.__module__ + '.' + x.__name__ +
- '\r\nTwisted %s\r\n' % copyright.version
- )
-
- def loginPrompt(self):
- """Override me to return a 'login:'-type prompt."""
- return "username: "
-
- def iacSBchunk(self, chunk):
- pass
-
- def iac_DO(self, feature):
- pass
-
- def iac_DONT(self, feature):
- pass
-
- def iac_WILL(self, feature):
- pass
-
- def iac_WONT(self, feature):
- pass
-
- def iac_IP(self, feature):
- pass
-
- def processLine(self, line):
- """I call a method that looks like 'telnet_*' where '*' is filled
- in by the current mode. telnet_* methods should return a string which
- will become the new mode. If None is returned, the mode will not change.
- """
- mode = getattr(self, "telnet_"+self.mode)(line)
- if mode is not None:
- self.mode = mode
-
- def telnet_User(self, user):
- """I take a username, set it to the 'self.username' attribute,
- print out a password prompt, and switch to 'Password' mode. If
- you want to do something else when the username is received (ie,
- create a new user if the user doesn't exist), override me."""
- self.username = user
- self.write(IAC+WILL+ECHO+"password: ")
- return "Password"
-
- def telnet_Password(self, paswd):
- """I accept a password as an argument, and check it with the
- checkUserAndPass method. If the login is successful, I call
- loggedIn()."""
- self.write(IAC+WONT+ECHO+"*****\r\n")
- try:
- checked = self.checkUserAndPass(self.username, paswd)
- except:
- return "Done"
- if not checked:
- return "Done"
- self.loggedIn()
- return "Command"
-
- def telnet_Command(self, cmd):
- """The default 'command processing' mode. You probably want to
- override me."""
- return "Command"
-
- def processChunk(self, chunk):
- """I take a chunk of data and delegate out to telnet_* methods
- by way of processLine. If the current mode is 'Done', I'll close
- the connection. """
- self.buffer = self.buffer + chunk
-
- #yech.
- for delim in self.delimiters:
- idx = self.buffer.find(delim)
- if idx != -1:
- break
-
- while idx != -1:
- buf, self.buffer = self.buffer[:idx], self.buffer[idx+2:]
- self.processLine(buf)
- if self.mode == 'Done':
- self.transport.loseConnection()
-
- for delim in self.delimiters:
- idx = self.buffer.find(delim)
- if idx != -1:
- break
-
- def dataReceived(self, data):
- chunk = StringIO()
- # silly little IAC state-machine
- for char in data:
- if self.gotIAC:
- # working on an IAC request state
- if self.iacByte:
- # we're in SB mode, getting a chunk
- if self.iacByte == SB:
- if char == SE:
- self.iacSBchunk(chunk.getvalue())
- chunk = StringIO()
- del self.iacByte
- del self.gotIAC
- else:
- chunk.write(char)
- else:
- # got all I need to know state
- try:
- getattr(self, 'iac_%s' % iacBytes[self.iacByte])(char)
- except KeyError:
- pass
- del self.iacByte
- del self.gotIAC
- else:
- # got IAC, this is my W/W/D/D (or perhaps sb)
- self.iacByte = char
- elif char == IAC:
- # Process what I've got so far before going into
- # the IAC state; don't want to process characters
- # in an inconsistent state with what they were
- # received in.
- c = chunk.getvalue()
- if c:
- why = self.processChunk(c)
- if why:
- return why
- chunk = StringIO()
- self.gotIAC = 1
- else:
- chunk.write(char)
- # chunks are of a relatively indeterminate size.
- c = chunk.getvalue()
- if c:
- why = self.processChunk(c)
- if why:
- return why
-
- def loggedIn(self):
- """Called after the user succesfully logged in.
-
- Override in subclasses.
- """
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/__init__.py
deleted file mode 100755
index fd1e0588..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Unit tests for L{twisted.protocols}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/test_tls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/test_tls.py
deleted file mode 100755
index 6227d02a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/test/test_tls.py
+++ /dev/null
@@ -1,1499 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.protocols.tls}.
-"""
-
-from zope.interface.verify import verifyObject
-from zope.interface import Interface, directlyProvides
-
-try:
- from twisted.protocols.tls import TLSMemoryBIOProtocol, TLSMemoryBIOFactory
- from twisted.protocols.tls import _PullToPush, _ProducerMembrane
-except ImportError:
- # Skip the whole test module if it can't be imported.
- skip = "pyOpenSSL 0.10 or newer required for twisted.protocol.tls"
-else:
- # Otherwise, the pyOpenSSL dependency must be satisfied, so all these
- # imports will work.
- from OpenSSL.crypto import X509Type
- from OpenSSL.SSL import TLSv1_METHOD, Error, Context, ConnectionType, WantReadError
- from twisted.internet.ssl import ClientContextFactory, PrivateCertificate
- from twisted.internet.ssl import DefaultOpenSSLContextFactory
-
-from twisted.python.filepath import FilePath
-from twisted.python.failure import Failure
-from twisted.python import log
-from twisted.internet.interfaces import ISystemHandle, ISSLTransport
-from twisted.internet.interfaces import IPushProducer
-from twisted.internet.error import ConnectionDone, ConnectionLost
-from twisted.internet.defer import Deferred, gatherResults
-from twisted.internet.protocol import Protocol, ClientFactory, ServerFactory
-from twisted.internet.task import TaskStopped
-from twisted.protocols.loopback import loopbackAsync, collapsingPumpPolicy
-from twisted.trial.unittest import TestCase
-from twisted.test.test_tcp import ConnectionLostNotifyingProtocol
-from twisted.test.test_ssl import certPath
-from twisted.test.proto_helpers import StringTransport
-
-
-class HandshakeCallbackContextFactory:
- """
- L{HandshakeCallbackContextFactory} is a factory for SSL contexts which
- allows applications to get notification when the SSL handshake completes.
-
- @ivar _finished: A L{Deferred} which will be called back when the handshake
- is done.
- """
- # pyOpenSSL needs to expose this.
- # https://bugs.launchpad.net/pyopenssl/+bug/372832
- SSL_CB_HANDSHAKE_DONE = 0x20
-
- def __init__(self):
- self._finished = Deferred()
-
-
- def factoryAndDeferred(cls):
- """
- Create a new L{HandshakeCallbackContextFactory} and return a two-tuple
- of it and a L{Deferred} which will fire when a connection created with
- it completes a TLS handshake.
- """
- contextFactory = cls()
- return contextFactory, contextFactory._finished
- factoryAndDeferred = classmethod(factoryAndDeferred)
-
-
- def _info(self, connection, where, ret):
- """
- This is the "info callback" on the context. It will be called
- periodically by pyOpenSSL with information about the state of a
- connection. When it indicates the handshake is complete, it will fire
- C{self._finished}.
- """
- if where & self.SSL_CB_HANDSHAKE_DONE:
- self._finished.callback(None)
-
-
- def getContext(self):
- """
- Create and return an SSL context configured to use L{self._info} as the
- info callback.
- """
- context = Context(TLSv1_METHOD)
- context.set_info_callback(self._info)
- return context
-
-
-
-class AccumulatingProtocol(Protocol):
- """
- A protocol which collects the bytes it receives and closes its connection
- after receiving a certain minimum of data.
-
- @ivar howMany: The number of bytes of data to wait for before closing the
- connection.
-
- @ivar receiving: A C{list} of C{str} of the bytes received so far.
- """
- def __init__(self, howMany):
- self.howMany = howMany
-
-
- def connectionMade(self):
- self.received = []
-
-
- def dataReceived(self, bytes):
- self.received.append(bytes)
- if sum(map(len, self.received)) >= self.howMany:
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- if not reason.check(ConnectionDone):
- log.err(reason)
-
-
-
-def buildTLSProtocol(server=False, transport=None):
- """
- Create a protocol hooked up to a TLS transport hooked up to a
- StringTransport.
- """
- # We want to accumulate bytes without disconnecting, so set high limit:
- clientProtocol = AccumulatingProtocol(999999999999)
- clientFactory = ClientFactory()
- clientFactory.protocol = lambda: clientProtocol
-
- if server:
- contextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- else:
- contextFactory = ClientContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- contextFactory, not server, clientFactory)
- sslProtocol = wrapperFactory.buildProtocol(None)
-
- if transport is None:
- transport = StringTransport()
- sslProtocol.makeConnection(transport)
- return clientProtocol, sslProtocol
-
-
-
-class TLSMemoryBIOFactoryTests(TestCase):
- """
- Ensure TLSMemoryBIOFactory logging acts correctly.
- """
-
- def test_quiet(self):
- """
- L{TLSMemoryBIOFactory.doStart} and L{TLSMemoryBIOFactory.doStop} do
- not log any messages.
- """
- contextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
-
- logs = []
- logger = logs.append
- log.addObserver(logger)
- self.addCleanup(log.removeObserver, logger)
- wrappedFactory = ServerFactory()
- # Disable logging on the wrapped factory:
- wrappedFactory.doStart = lambda: None
- wrappedFactory.doStop = lambda: None
- factory = TLSMemoryBIOFactory(contextFactory, False, wrappedFactory)
- factory.doStart()
- factory.doStop()
- self.assertEqual(logs, [])
-
-
- def test_logPrefix(self):
- """
- L{TLSMemoryBIOFactory.logPrefix} amends the wrapped factory's log prefix
- with a short string (C{"TLS"}) indicating the wrapping, rather than its
- full class name.
- """
- contextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- factory = TLSMemoryBIOFactory(contextFactory, False, ServerFactory())
- self.assertEqual("ServerFactory (TLS)", factory.logPrefix())
-
-
- def test_logPrefixFallback(self):
- """
- If the wrapped factory does not provide L{ILoggingContext},
- L{TLSMemoryBIOFactory.logPrefix} uses the wrapped factory's class name.
- """
- class NoFactory(object):
- pass
-
- contextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- factory = TLSMemoryBIOFactory(contextFactory, False, NoFactory())
- self.assertEqual("NoFactory (TLS)", factory.logPrefix())
-
-
-
-class TLSMemoryBIOTests(TestCase):
- """
- Tests for the implementation of L{ISSLTransport} which runs over another
- L{ITransport}.
- """
-
- def test_interfaces(self):
- """
- L{TLSMemoryBIOProtocol} instances provide L{ISSLTransport} and
- L{ISystemHandle}.
- """
- proto = TLSMemoryBIOProtocol(None, None)
- self.assertTrue(ISSLTransport.providedBy(proto))
- self.assertTrue(ISystemHandle.providedBy(proto))
-
-
- def test_wrappedProtocolInterfaces(self):
- """
- L{TLSMemoryBIOProtocol} instances provide the interfaces provided by
- the transport they wrap.
- """
- class ITransport(Interface):
- pass
-
- class MyTransport(object):
- def write(self, bytes):
- pass
-
- clientFactory = ClientFactory()
- contextFactory = ClientContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- contextFactory, True, clientFactory)
-
- transport = MyTransport()
- directlyProvides(transport, ITransport)
- tlsProtocol = TLSMemoryBIOProtocol(wrapperFactory, Protocol())
- tlsProtocol.makeConnection(transport)
- self.assertTrue(ITransport.providedBy(tlsProtocol))
-
-
- def test_getHandle(self):
- """
- L{TLSMemoryBIOProtocol.getHandle} returns the L{OpenSSL.SSL.Connection}
- instance it uses to actually implement TLS.
-
- This may seem odd. In fact, it is. The L{OpenSSL.SSL.Connection} is
- not actually the "system handle" here, nor even an object the reactor
- knows about directly. However, L{twisted.internet.ssl.Certificate}'s
- C{peerFromTransport} and C{hostFromTransport} methods depend on being
- able to get an L{OpenSSL.SSL.Connection} object in order to work
- properly. Implementing L{ISystemHandle.getHandle} like this is the
- easiest way for those APIs to be made to work. If they are changed,
- then it may make sense to get rid of this implementation of
- L{ISystemHandle} and return the underlying socket instead.
- """
- factory = ClientFactory()
- contextFactory = ClientContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(contextFactory, True, factory)
- proto = TLSMemoryBIOProtocol(wrapperFactory, Protocol())
- transport = StringTransport()
- proto.makeConnection(transport)
- self.assertIsInstance(proto.getHandle(), ConnectionType)
-
-
- def test_makeConnection(self):
- """
- When L{TLSMemoryBIOProtocol} is connected to a transport, it connects
- the protocol it wraps to a transport.
- """
- clientProtocol = Protocol()
- clientFactory = ClientFactory()
- clientFactory.protocol = lambda: clientProtocol
-
- contextFactory = ClientContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- contextFactory, True, clientFactory)
- sslProtocol = wrapperFactory.buildProtocol(None)
-
- transport = StringTransport()
- sslProtocol.makeConnection(transport)
-
- self.assertNotIdentical(clientProtocol.transport, None)
- self.assertNotIdentical(clientProtocol.transport, transport)
- self.assertIdentical(clientProtocol.transport, sslProtocol)
-
-
- def handshakeProtocols(self):
- """
- Start handshake between TLS client and server.
- """
- clientFactory = ClientFactory()
- clientFactory.protocol = Protocol
-
- clientContextFactory, handshakeDeferred = (
- HandshakeCallbackContextFactory.factoryAndDeferred())
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverFactory = ServerFactory()
- serverFactory.protocol = Protocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol)
- return (sslClientProtocol, sslServerProtocol, handshakeDeferred,
- connectionDeferred)
-
-
- def test_handshake(self):
- """
- The TLS handshake is performed when L{TLSMemoryBIOProtocol} is
- connected to a transport.
- """
- tlsClient, tlsServer, handshakeDeferred, _ = self.handshakeProtocols()
-
- # Only wait for the handshake to complete. Anything after that isn't
- # important here.
- return handshakeDeferred
-
-
- def test_handshakeFailure(self):
- """
- L{TLSMemoryBIOProtocol} reports errors in the handshake process to the
- application-level protocol object using its C{connectionLost} method
- and disconnects the underlying transport.
- """
- clientConnectionLost = Deferred()
- clientFactory = ClientFactory()
- clientFactory.protocol = (
- lambda: ConnectionLostNotifyingProtocol(
- clientConnectionLost))
-
- clientContextFactory = HandshakeCallbackContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverConnectionLost = Deferred()
- serverFactory = ServerFactory()
- serverFactory.protocol = (
- lambda: ConnectionLostNotifyingProtocol(
- serverConnectionLost))
-
- # This context factory rejects any clients which do not present a
- # certificate.
- certificateData = FilePath(certPath).getContent()
- certificate = PrivateCertificate.loadPEM(certificateData)
- serverContextFactory = certificate.options(certificate)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol)
-
- def cbConnectionLost(protocol):
- # The connection should close on its own in response to the error
- # induced by the client not supplying the required certificate.
- # After that, check to make sure the protocol's connectionLost was
- # called with the right thing.
- protocol.lostConnectionReason.trap(Error)
- clientConnectionLost.addCallback(cbConnectionLost)
- serverConnectionLost.addCallback(cbConnectionLost)
-
- # Additionally, the underlying transport should have been told to
- # go away.
- return gatherResults([
- clientConnectionLost, serverConnectionLost,
- connectionDeferred])
-
-
- def test_getPeerCertificate(self):
- """
- L{TLSMemoryBIOProtocol.getPeerCertificate} returns the
- L{OpenSSL.crypto.X509Type} instance representing the peer's
- certificate.
- """
- # Set up a client and server so there's a certificate to grab.
- clientFactory = ClientFactory()
- clientFactory.protocol = Protocol
-
- clientContextFactory, handshakeDeferred = (
- HandshakeCallbackContextFactory.factoryAndDeferred())
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverFactory = ServerFactory()
- serverFactory.protocol = Protocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- loopbackAsync(sslServerProtocol, sslClientProtocol)
-
- # Wait for the handshake
- def cbHandshook(ignored):
- # Grab the server's certificate and check it out
- cert = sslClientProtocol.getPeerCertificate()
- self.assertIsInstance(cert, X509Type)
- self.assertEqual(
- cert.digest('md5'),
- '9B:A4:AB:43:10:BE:82:AE:94:3E:6B:91:F2:F3:40:E8')
- handshakeDeferred.addCallback(cbHandshook)
- return handshakeDeferred
-
-
- def test_writeAfterHandshake(self):
- """
- Bytes written to L{TLSMemoryBIOProtocol} before the handshake is
- complete are received by the protocol on the other side of the
- connection once the handshake succeeds.
- """
- bytes = "some bytes"
-
- clientProtocol = Protocol()
- clientFactory = ClientFactory()
- clientFactory.protocol = lambda: clientProtocol
-
- clientContextFactory, handshakeDeferred = (
- HandshakeCallbackContextFactory.factoryAndDeferred())
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverProtocol = AccumulatingProtocol(len(bytes))
- serverFactory = ServerFactory()
- serverFactory.protocol = lambda: serverProtocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol)
-
- # Wait for the handshake to finish before writing anything.
- def cbHandshook(ignored):
- clientProtocol.transport.write(bytes)
-
- # The server will drop the connection once it gets the bytes.
- return connectionDeferred
- handshakeDeferred.addCallback(cbHandshook)
-
- # Once the connection is lost, make sure the server received the
- # expected bytes.
- def cbDisconnected(ignored):
- self.assertEqual("".join(serverProtocol.received), bytes)
- handshakeDeferred.addCallback(cbDisconnected)
-
- return handshakeDeferred
-
-
- def writeBeforeHandshakeTest(self, sendingProtocol, bytes):
- """
- Run test where client sends data before handshake, given the sending
- protocol and expected bytes.
- """
- clientFactory = ClientFactory()
- clientFactory.protocol = sendingProtocol
-
- clientContextFactory, handshakeDeferred = (
- HandshakeCallbackContextFactory.factoryAndDeferred())
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverProtocol = AccumulatingProtocol(len(bytes))
- serverFactory = ServerFactory()
- serverFactory.protocol = lambda: serverProtocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol)
-
- # Wait for the connection to end, then make sure the server received
- # the bytes sent by the client.
- def cbConnectionDone(ignored):
- self.assertEqual("".join(serverProtocol.received), bytes)
- connectionDeferred.addCallback(cbConnectionDone)
- return connectionDeferred
-
-
- def test_writeBeforeHandshake(self):
- """
- Bytes written to L{TLSMemoryBIOProtocol} before the handshake is
- complete are received by the protocol on the other side of the
- connection once the handshake succeeds.
- """
- bytes = "some bytes"
-
- class SimpleSendingProtocol(Protocol):
- def connectionMade(self):
- self.transport.write(bytes)
-
- return self.writeBeforeHandshakeTest(SimpleSendingProtocol, bytes)
-
-
- def test_writeSequence(self):
- """
- Bytes written to L{TLSMemoryBIOProtocol} with C{writeSequence} are
- received by the protocol on the other side of the connection.
- """
- bytes = "some bytes"
- class SimpleSendingProtocol(Protocol):
- def connectionMade(self):
- self.transport.writeSequence(list(bytes))
-
- return self.writeBeforeHandshakeTest(SimpleSendingProtocol, bytes)
-
-
- def test_writeAfterLoseConnection(self):
- """
- Bytes written to L{TLSMemoryBIOProtocol} after C{loseConnection} is
- called are not transmitted (unless there is a registered producer,
- which will be tested elsewhere).
- """
- bytes = "some bytes"
- class SimpleSendingProtocol(Protocol):
- def connectionMade(self):
- self.transport.write(bytes)
- self.transport.loseConnection()
- self.transport.write("hello")
- self.transport.writeSequence(["world"])
- return self.writeBeforeHandshakeTest(SimpleSendingProtocol, bytes)
-
-
- def test_multipleWrites(self):
- """
- If multiple separate TLS messages are received in a single chunk from
- the underlying transport, all of the application bytes from each
- message are delivered to the application-level protocol.
- """
- bytes = [str(i) for i in range(10)]
- class SimpleSendingProtocol(Protocol):
- def connectionMade(self):
- for b in bytes:
- self.transport.write(b)
-
- clientFactory = ClientFactory()
- clientFactory.protocol = SimpleSendingProtocol
-
- clientContextFactory = HandshakeCallbackContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverProtocol = AccumulatingProtocol(sum(map(len, bytes)))
- serverFactory = ServerFactory()
- serverFactory.protocol = lambda: serverProtocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol, collapsingPumpPolicy)
-
- # Wait for the connection to end, then make sure the server received
- # the bytes sent by the client.
- def cbConnectionDone(ignored):
- self.assertEqual("".join(serverProtocol.received), ''.join(bytes))
- connectionDeferred.addCallback(cbConnectionDone)
- return connectionDeferred
-
-
- def test_hugeWrite(self):
- """
- If a very long string is passed to L{TLSMemoryBIOProtocol.write}, any
- trailing part of it which cannot be send immediately is buffered and
- sent later.
- """
- bytes = "some bytes"
- factor = 8192
- class SimpleSendingProtocol(Protocol):
- def connectionMade(self):
- self.transport.write(bytes * factor)
-
- clientFactory = ClientFactory()
- clientFactory.protocol = SimpleSendingProtocol
-
- clientContextFactory = HandshakeCallbackContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverProtocol = AccumulatingProtocol(len(bytes) * factor)
- serverFactory = ServerFactory()
- serverFactory.protocol = lambda: serverProtocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol)
-
- # Wait for the connection to end, then make sure the server received
- # the bytes sent by the client.
- def cbConnectionDone(ignored):
- self.assertEqual("".join(serverProtocol.received), bytes * factor)
- connectionDeferred.addCallback(cbConnectionDone)
- return connectionDeferred
-
-
- def test_disorderlyShutdown(self):
- """
- If a L{TLSMemoryBIOProtocol} loses its connection unexpectedly, this is
- reported to the application.
- """
- clientConnectionLost = Deferred()
- clientFactory = ClientFactory()
- clientFactory.protocol = (
- lambda: ConnectionLostNotifyingProtocol(
- clientConnectionLost))
-
- clientContextFactory = HandshakeCallbackContextFactory()
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- # Client speaks first, so the server can be dumb.
- serverProtocol = Protocol()
-
- loopbackAsync(serverProtocol, sslClientProtocol)
-
- # Now destroy the connection.
- serverProtocol.transport.loseConnection()
-
- # And when the connection completely dies, check the reason.
- def cbDisconnected(clientProtocol):
- clientProtocol.lostConnectionReason.trap(Error)
- clientConnectionLost.addCallback(cbDisconnected)
- return clientConnectionLost
-
-
- def test_loseConnectionAfterHandshake(self):
- """
- L{TLSMemoryBIOProtocol.loseConnection} sends a TLS close alert and
- shuts down the underlying connection cleanly on both sides, after
- transmitting all buffered data.
- """
- class NotifyingProtocol(ConnectionLostNotifyingProtocol):
- def __init__(self, onConnectionLost):
- ConnectionLostNotifyingProtocol.__init__(self,
- onConnectionLost)
- self.data = []
-
- def dataReceived(self, bytes):
- self.data.append(bytes)
-
- clientConnectionLost = Deferred()
- clientFactory = ClientFactory()
- clientProtocol = NotifyingProtocol(clientConnectionLost)
- clientFactory.protocol = lambda: clientProtocol
-
- clientContextFactory, handshakeDeferred = (
- HandshakeCallbackContextFactory.factoryAndDeferred())
- wrapperFactory = TLSMemoryBIOFactory(
- clientContextFactory, True, clientFactory)
- sslClientProtocol = wrapperFactory.buildProtocol(None)
-
- serverConnectionLost = Deferred()
- serverProtocol = NotifyingProtocol(serverConnectionLost)
- serverFactory = ServerFactory()
- serverFactory.protocol = lambda: serverProtocol
-
- serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
- wrapperFactory = TLSMemoryBIOFactory(
- serverContextFactory, False, serverFactory)
- sslServerProtocol = wrapperFactory.buildProtocol(None)
-
- loopbackAsync(sslServerProtocol, sslClientProtocol)
- chunkOfBytes = "123456890" * 100000
-
- # Wait for the handshake before dropping the connection.
- def cbHandshake(ignored):
- # Write more than a single bio_read, to ensure client will still
- # have some data it needs to write when it receives the TLS close
- # alert, and that simply doing a single bio_read won't be
- # sufficient. Thus we will verify that any amount of buffered data
- # will be written out before the connection is closed, rather than
- # just small amounts that can be returned in a single bio_read:
- clientProtocol.transport.write(chunkOfBytes)
- serverProtocol.transport.loseConnection()
-
- # Now wait for the client and server to notice.
- return gatherResults([clientConnectionLost, serverConnectionLost])
- handshakeDeferred.addCallback(cbHandshake)
-
- # Wait for the connection to end, then make sure the client and server
- # weren't notified of a handshake failure that would cause the test to
- # fail.
- def cbConnectionDone((clientProtocol, serverProtocol)):
- clientProtocol.lostConnectionReason.trap(ConnectionDone)
- serverProtocol.lostConnectionReason.trap(ConnectionDone)
-
- # The server should have received all bytes sent by the client:
- self.assertEqual("".join(serverProtocol.data), chunkOfBytes)
-
- # The server should have closed its underlying transport, in
- # addition to whatever it did to shut down the TLS layer.
- self.assertTrue(serverProtocol.transport.q.disconnect)
-
- # The client should also have closed its underlying transport once
- # it saw the server shut down the TLS layer, so as to avoid relying
- # on the server to close the underlying connection.
- self.assertTrue(clientProtocol.transport.q.disconnect)
- handshakeDeferred.addCallback(cbConnectionDone)
- return handshakeDeferred
-
-
- def test_connectionLostOnlyAfterUnderlyingCloses(self):
- """
- The user protocol's connectionLost is only called when transport
- underlying TLS is disconnected.
- """
- class LostProtocol(Protocol):
- disconnected = None
- def connectionLost(self, reason):
- self.disconnected = reason
- wrapperFactory = TLSMemoryBIOFactory(ClientContextFactory(),
- True, ClientFactory())
- protocol = LostProtocol()
- tlsProtocol = TLSMemoryBIOProtocol(wrapperFactory, protocol)
- transport = StringTransport()
- tlsProtocol.makeConnection(transport)
-
- # Pretend TLS shutdown finished cleanly; the underlying transport
- # should be told to close, but the user protocol should not yet be
- # notified:
- tlsProtocol._tlsShutdownFinished(None)
- self.assertEqual(transport.disconnecting, True)
- self.assertEqual(protocol.disconnected, None)
-
- # Now close the underlying connection; the user protocol should be
- # notified with the given reason (since TLS closed cleanly):
- tlsProtocol.connectionLost(Failure(ConnectionLost("ono")))
- self.assertTrue(protocol.disconnected.check(ConnectionLost))
- self.assertEqual(protocol.disconnected.value.args, ("ono",))
-
-
- def test_loseConnectionTwice(self):
- """
- If TLSMemoryBIOProtocol.loseConnection is called multiple times, all
- but the first call have no effect.
- """
- wrapperFactory = TLSMemoryBIOFactory(ClientContextFactory(),
- True, ClientFactory())
- tlsProtocol = TLSMemoryBIOProtocol(wrapperFactory, Protocol())
- transport = StringTransport()
- tlsProtocol.makeConnection(transport)
- self.assertEqual(tlsProtocol.disconnecting, False)
-
- # Make sure loseConnection calls _shutdownTLS the first time (mostly
- # to make sure we've overriding it correctly):
- calls = []
- def _shutdownTLS(shutdown=tlsProtocol._shutdownTLS):
- calls.append(1)
- return shutdown()
- tlsProtocol._shutdownTLS = _shutdownTLS
- tlsProtocol.loseConnection()
- self.assertEqual(tlsProtocol.disconnecting, True)
- self.assertEqual(calls, [1])
-
- # Make sure _shutdownTLS isn't called a second time:
- tlsProtocol.loseConnection()
- self.assertEqual(calls, [1])
-
-
- def test_unexpectedEOF(self):
- """
- Unexpected disconnects get converted to ConnectionLost errors.
- """
- tlsClient, tlsServer, handshakeDeferred, disconnectDeferred = (
- self.handshakeProtocols())
- serverProtocol = tlsServer.wrappedProtocol
- data = []
- reason = []
- serverProtocol.dataReceived = data.append
- serverProtocol.connectionLost = reason.append
-
- # Write data, then disconnect *underlying* transport, resulting in an
- # unexpected TLS disconnect:
- def handshakeDone(ign):
- tlsClient.write("hello")
- tlsClient.transport.loseConnection()
- handshakeDeferred.addCallback(handshakeDone)
-
- # Receiver should be disconnected, with ConnectionLost notification
- # (masking the Unexpected EOF SSL error):
- def disconnected(ign):
- self.assertTrue(reason[0].check(ConnectionLost), reason[0])
- disconnectDeferred.addCallback(disconnected)
- return disconnectDeferred
-
-
- def test_errorWriting(self):
- """
- Errors while writing cause the protocols to be disconnected.
- """
- tlsClient, tlsServer, handshakeDeferred, disconnectDeferred = (
- self.handshakeProtocols())
- reason = []
- tlsClient.wrappedProtocol.connectionLost = reason.append
-
- # Pretend TLS connection is unhappy sending:
- class Wrapper(object):
- def __init__(self, wrapped):
- self._wrapped = wrapped
- def __getattr__(self, attr):
- return getattr(self._wrapped, attr)
- def send(self, *args):
- raise Error("ONO!")
- tlsClient._tlsConnection = Wrapper(tlsClient._tlsConnection)
-
- # Write some data:
- def handshakeDone(ign):
- tlsClient.write("hello")
- handshakeDeferred.addCallback(handshakeDone)
-
- # Failed writer should be disconnected with SSL error:
- def disconnected(ign):
- self.assertTrue(reason[0].check(Error), reason[0])
- disconnectDeferred.addCallback(disconnected)
- return disconnectDeferred
-
-
-
-class TLSProducerTests(TestCase):
- """
- The TLS transport must support the IConsumer interface.
- """
-
- def setupStreamingProducer(self, transport=None):
- class HistoryStringTransport(StringTransport):
- def __init__(self):
- StringTransport.__init__(self)
- self.producerHistory = []
-
- def pauseProducing(self):
- self.producerHistory.append("pause")
- StringTransport.pauseProducing(self)
-
- def resumeProducing(self):
- self.producerHistory.append("resume")
- StringTransport.resumeProducing(self)
-
- def stopProducing(self):
- self.producerHistory.append("stop")
- StringTransport.stopProducing(self)
-
- clientProtocol, tlsProtocol = buildTLSProtocol(transport=transport)
- producer = HistoryStringTransport()
- clientProtocol.transport.registerProducer(producer, True)
- self.assertEqual(tlsProtocol.transport.streaming, True)
- return clientProtocol, tlsProtocol, producer
-
-
- def flushTwoTLSProtocols(self, tlsProtocol, serverTLSProtocol):
- """
- Transfer bytes back and forth between two TLS protocols.
- """
- # We want to make sure all bytes are passed back and forth; JP
- # estimated that 3 rounds should be enough:
- for i in range(3):
- clientData = tlsProtocol.transport.value()
- if clientData:
- serverTLSProtocol.dataReceived(clientData)
- tlsProtocol.transport.clear()
- serverData = serverTLSProtocol.transport.value()
- if serverData:
- tlsProtocol.dataReceived(serverData)
- serverTLSProtocol.transport.clear()
- if not serverData and not clientData:
- break
- self.assertEqual(tlsProtocol.transport.value(), "")
- self.assertEqual(serverTLSProtocol.transport.value(), "")
-
-
- def test_streamingProducerPausedInNormalMode(self):
- """
- When the TLS transport is not blocked on reads, it correctly calls
- pauseProducing on the registered producer.
- """
- _, tlsProtocol, producer = self.setupStreamingProducer()
-
- # The TLS protocol's transport pretends to be full, pausing its
- # producer:
- tlsProtocol.transport.producer.pauseProducing()
- self.assertEqual(producer.producerState, 'paused')
- self.assertEqual(producer.producerHistory, ['pause'])
- self.assertEqual(tlsProtocol._producer._producerPaused, True)
-
-
- def test_streamingProducerResumedInNormalMode(self):
- """
- When the TLS transport is not blocked on reads, it correctly calls
- resumeProducing on the registered producer.
- """
- _, tlsProtocol, producer = self.setupStreamingProducer()
- tlsProtocol.transport.producer.pauseProducing()
- self.assertEqual(producer.producerHistory, ['pause'])
-
- # The TLS protocol's transport pretends to have written everything
- # out, so it resumes its producer:
- tlsProtocol.transport.producer.resumeProducing()
- self.assertEqual(producer.producerState, 'producing')
- self.assertEqual(producer.producerHistory, ['pause', 'resume'])
- self.assertEqual(tlsProtocol._producer._producerPaused, False)
-
-
- def test_streamingProducerPausedInWriteBlockedOnReadMode(self):
- """
- When the TLS transport is blocked on reads, it correctly calls
- pauseProducing on the registered producer.
- """
- clientProtocol, tlsProtocol, producer = self.setupStreamingProducer()
-
- # Write to TLS transport. Because we do this before the initial TLS
- # handshake is finished, writing bytes triggers a WantReadError,
- # indicating that until bytes are read for the handshake, more bytes
- # cannot be written. Thus writing bytes before the handshake should
- # cause the producer to be paused:
- clientProtocol.transport.write("hello")
- self.assertEqual(producer.producerState, 'paused')
- self.assertEqual(producer.producerHistory, ['pause'])
- self.assertEqual(tlsProtocol._producer._producerPaused, True)
-
-
- def test_streamingProducerResumedInWriteBlockedOnReadMode(self):
- """
- When the TLS transport is blocked on reads, it correctly calls
- resumeProducing on the registered producer.
- """
- clientProtocol, tlsProtocol, producer = self.setupStreamingProducer()
-
- # Write to TLS transport, triggering WantReadError; this should cause
- # the producer to be paused. We use a large chunk of data to make sure
- # large writes don't trigger multiple pauses:
- clientProtocol.transport.write("hello world" * 320000)
- self.assertEqual(producer.producerHistory, ['pause'])
-
- # Now deliver bytes that will fix the WantRead condition; this should
- # unpause the producer:
- serverProtocol, serverTLSProtocol = buildTLSProtocol(server=True)
- self.flushTwoTLSProtocols(tlsProtocol, serverTLSProtocol)
- self.assertEqual(producer.producerHistory, ['pause', 'resume'])
- self.assertEqual(tlsProtocol._producer._producerPaused, False)
-
- # Make sure we haven't disconnected for some reason:
- self.assertEqual(tlsProtocol.transport.disconnecting, False)
- self.assertEqual(producer.producerState, 'producing')
-
-
- def test_streamingProducerTwice(self):
- """
- Registering a streaming producer twice throws an exception.
- """
- clientProtocol, tlsProtocol, producer = self.setupStreamingProducer()
- originalProducer = tlsProtocol._producer
- producer2 = object()
- self.assertRaises(RuntimeError,
- clientProtocol.transport.registerProducer, producer2, True)
- self.assertIdentical(tlsProtocol._producer, originalProducer)
-
-
- def test_streamingProducerUnregister(self):
- """
- Unregistering a streaming producer removes it, reverting to initial state.
- """
- clientProtocol, tlsProtocol, producer = self.setupStreamingProducer()
- clientProtocol.transport.unregisterProducer()
- self.assertEqual(tlsProtocol._producer, None)
- self.assertEqual(tlsProtocol.transport.producer, None)
-
-
- def loseConnectionWithProducer(self, writeBlockedOnRead):
- """
- Common code for tests involving writes by producer after
- loseConnection is called.
- """
- clientProtocol, tlsProtocol, producer = self.setupStreamingProducer()
- serverProtocol, serverTLSProtocol = buildTLSProtocol(server=True)
-
- if not writeBlockedOnRead:
- # Do the initial handshake before write:
- self.flushTwoTLSProtocols(tlsProtocol, serverTLSProtocol)
- else:
- # In this case the write below will trigger write-blocked-on-read
- # condition...
- pass
-
- # Now write, then lose connection:
- clientProtocol.transport.write("x ")
- clientProtocol.transport.loseConnection()
- self.flushTwoTLSProtocols(tlsProtocol, serverTLSProtocol)
-
- # Underlying transport should not have loseConnection called yet, nor
- # should producer be stopped:
- self.assertEqual(tlsProtocol.transport.disconnecting, False)
- self.assertFalse("stop" in producer.producerHistory)
-
- # Writes from client to server should continue to go through, since we
- # haven't unregistered producer yet:
- clientProtocol.transport.write("hello")
- clientProtocol.transport.writeSequence([" ", "world"])
-
- # Unregister producer; this should trigger TLS shutdown:
- clientProtocol.transport.unregisterProducer()
- self.assertNotEqual(tlsProtocol.transport.value(), "")
- self.assertEqual(tlsProtocol.transport.disconnecting, False)
-
- # Additional writes should not go through:
- clientProtocol.transport.write("won't")
- clientProtocol.transport.writeSequence(["won't!"])
-
- # Finish TLS close handshake:
- self.flushTwoTLSProtocols(tlsProtocol, serverTLSProtocol)
- self.assertEqual(tlsProtocol.transport.disconnecting, True)
-
- # Bytes made it through, as long as they were written before producer
- # was unregistered:
- self.assertEqual("".join(serverProtocol.received), "x hello world")
-
-
- def test_streamingProducerLoseConnectionWithProducer(self):
- """
- loseConnection() waits for the producer to unregister itself, then
- does a clean TLS close alert, then closes the underlying connection.
- """
- return self.loseConnectionWithProducer(False)
-
-
- def test_streamingProducerLoseConnectionWithProducerWBOR(self):
- """
- Even when writes are blocked on reading, loseConnection() waits for
- the producer to unregister itself, then does a clean TLS close alert,
- then closes the underlying connection.
- """
- return self.loseConnectionWithProducer(True)
-
-
- def test_streamingProducerBothTransportsDecideToPause(self):
- """
- pauseProducing() events can come from both the TLS transport layer and
- the underlying transport. In this case, both decide to pause,
- underlying first.
- """
- class PausingStringTransport(StringTransport):
- _didPause = False
-
- def write(self, data):
- if not self._didPause and self.producer is not None:
- self._didPause = True
- self.producer.pauseProducing()
- StringTransport.write(self, data)
-
-
- class TLSConnection(object):
- def __init__(self):
- self.l = []
-
- def send(self, bytes):
- # on first write, don't send all bytes:
- if not self.l:
- bytes = bytes[:-1]
- # pause on second write:
- if len(self.l) == 1:
- self.l.append("paused")
- raise WantReadError()
- # otherwise just take in data:
- self.l.append(bytes)
- return len(bytes)
-
- def bio_write(self, data):
- pass
-
- def bio_read(self, size):
- return chr(ord('A') + len(self.l))
-
- def recv(self, size):
- raise WantReadError()
-
- transport = PausingStringTransport()
- clientProtocol, tlsProtocol, producer = self.setupStreamingProducer(
- transport)
- self.assertEqual(producer.producerState, 'producing')
-
- # Shove in fake TLSConnection that will raise WantReadError the second
- # time send() is called. This will allow us to have bytes written to
- # to the PausingStringTransport, so it will pause the producer. Then,
- # WantReadError will be thrown, triggering the TLS transport's
- # producer code path.
- tlsProtocol._tlsConnection = TLSConnection()
- clientProtocol.transport.write("hello")
- self.assertEqual(producer.producerState, 'paused')
- self.assertEqual(producer.producerHistory, ['pause'])
-
- # Now, underlying transport resumes, and then we deliver some data to
- # TLS transport so that it will resume:
- tlsProtocol.transport.producer.resumeProducing()
- self.assertEqual(producer.producerState, 'producing')
- self.assertEqual(producer.producerHistory, ['pause', 'resume'])
- tlsProtocol.dataReceived("hello")
- self.assertEqual(producer.producerState, 'producing')
- self.assertEqual(producer.producerHistory, ['pause', 'resume'])
-
-
- def test_streamingProducerStopProducing(self):
- """
- If the underlying transport tells its producer to stopProducing(),
- this is passed on to the high-level producer.
- """
- _, tlsProtocol, producer = self.setupStreamingProducer()
- tlsProtocol.transport.producer.stopProducing()
- self.assertEqual(producer.producerState, 'stopped')
-
-
- def test_nonStreamingProducer(self):
- """
- Non-streaming producers get wrapped as streaming producers.
- """
- clientProtocol, tlsProtocol = buildTLSProtocol()
- producer = NonStreamingProducer(clientProtocol.transport)
-
- # Register non-streaming producer:
- clientProtocol.transport.registerProducer(producer, False)
- streamingProducer = tlsProtocol.transport.producer._producer
-
- # Verify it was wrapped into streaming producer:
- self.assertIsInstance(streamingProducer, _PullToPush)
- self.assertEqual(streamingProducer._producer, producer)
- self.assertEqual(streamingProducer._consumer, clientProtocol.transport)
- self.assertEqual(tlsProtocol.transport.streaming, True)
-
- # Verify the streaming producer was started, and ran until the end:
- def done(ignore):
- # Our own producer is done:
- self.assertEqual(producer.consumer, None)
- # The producer has been unregistered:
- self.assertEqual(tlsProtocol.transport.producer, None)
- # The streaming producer wrapper knows it's done:
- self.assertEqual(streamingProducer._finished, True)
- producer.result.addCallback(done)
-
- serverProtocol, serverTLSProtocol = buildTLSProtocol(server=True)
- self.flushTwoTLSProtocols(tlsProtocol, serverTLSProtocol)
- return producer.result
-
-
- def test_interface(self):
- """
- L{_ProducerMembrane} implements L{IPushProducer}.
- """
- producer = StringTransport()
- membrane = _ProducerMembrane(producer)
- self.assertTrue(verifyObject(IPushProducer, membrane))
-
-
- def registerProducerAfterConnectionLost(self, streaming):
- """
- If a producer is registered after the transport has disconnected, the
- producer is not used, and its stopProducing method is called.
- """
- clientProtocol, tlsProtocol = buildTLSProtocol()
- clientProtocol.connectionLost = lambda reason: reason.trap(Error)
-
- class Producer(object):
- stopped = False
-
- def resumeProducing(self):
- return 1/0 # this should never be called
-
- def stopProducing(self):
- self.stopped = True
-
- # Disconnect the transport:
- tlsProtocol.connectionLost(Failure(ConnectionDone()))
-
- # Register the producer; startProducing should not be called, but
- # stopProducing will:
- producer = Producer()
- tlsProtocol.registerProducer(producer, False)
- self.assertIdentical(tlsProtocol.transport.producer, None)
- self.assertEqual(producer.stopped, True)
-
-
- def test_streamingProducerAfterConnectionLost(self):
- """
- If a streaming producer is registered after the transport has
- disconnected, the producer is not used, and its stopProducing method
- is called.
- """
- self.registerProducerAfterConnectionLost(True)
-
-
- def test_nonStreamingProducerAfterConnectionLost(self):
- """
- If a non-streaming producer is registered after the transport has
- disconnected, the producer is not used, and its stopProducing method
- is called.
- """
- self.registerProducerAfterConnectionLost(False)
-
-
-
-class NonStreamingProducer(object):
- """
- A pull producer which writes 10 times only.
- """
-
- counter = 0
- stopped = False
-
- def __init__(self, consumer):
- self.consumer = consumer
- self.result = Deferred()
-
- def resumeProducing(self):
- if self.counter < 10:
- self.consumer.write(str(self.counter))
- self.counter += 1
- if self.counter == 10:
- self.consumer.unregisterProducer()
- self._done()
- else:
- if self.consumer is None:
- raise RuntimeError("BUG: resume after unregister/stop.")
-
-
- def pauseProducing(self):
- raise RuntimeError("BUG: pause should never be called.")
-
-
- def _done(self):
- self.consumer = None
- d = self.result
- del self.result
- d.callback(None)
-
-
- def stopProducing(self):
- self.stopped = True
- self._done()
-
-
-
-class NonStreamingProducerTests(TestCase):
- """
- Non-streaming producers can be adapted into being streaming producers.
- """
-
- def streamUntilEnd(self, consumer):
- """
- Verify the consumer writes out all its data, but is not called after
- that.
- """
- nsProducer = NonStreamingProducer(consumer)
- streamingProducer = _PullToPush(nsProducer, consumer)
- consumer.registerProducer(streamingProducer, True)
-
- # The producer will call unregisterProducer(), and we need to hook
- # that up so the streaming wrapper is notified; the
- # TLSMemoryBIOProtocol will have to do this itself, which is tested
- # elsewhere:
- def unregister(orig=consumer.unregisterProducer):
- orig()
- streamingProducer.stopStreaming()
- consumer.unregisterProducer = unregister
-
- done = nsProducer.result
- def doneStreaming(_):
- # All data was streamed, and the producer unregistered itself:
- self.assertEqual(consumer.value(), "0123456789")
- self.assertEqual(consumer.producer, None)
- # And the streaming wrapper stopped:
- self.assertEqual(streamingProducer._finished, True)
- done.addCallback(doneStreaming)
-
- # Now, start streaming:
- streamingProducer.startStreaming()
- return done
-
-
- def test_writeUntilDone(self):
- """
- When converted to a streaming producer, the non-streaming producer
- writes out all its data, but is not called after that.
- """
- consumer = StringTransport()
- return self.streamUntilEnd(consumer)
-
-
- def test_pause(self):
- """
- When the streaming producer is paused, the underlying producer stops
- getting resumeProducing calls.
- """
- class PausingStringTransport(StringTransport):
- writes = 0
-
- def __init__(self):
- StringTransport.__init__(self)
- self.paused = Deferred()
-
- def write(self, data):
- self.writes += 1
- StringTransport.write(self, data)
- if self.writes == 3:
- self.producer.pauseProducing()
- d = self.paused
- del self.paused
- d.callback(None)
-
-
- consumer = PausingStringTransport()
- nsProducer = NonStreamingProducer(consumer)
- streamingProducer = _PullToPush(nsProducer, consumer)
- consumer.registerProducer(streamingProducer, True)
-
- # Make sure the consumer does not continue:
- def shouldNotBeCalled(ignore):
- self.fail("BUG: The producer should not finish!")
- nsProducer.result.addCallback(shouldNotBeCalled)
-
- done = consumer.paused
- def paused(ignore):
- # The CooperatorTask driving the producer was paused:
- self.assertEqual(streamingProducer._coopTask._pauseCount, 1)
- done.addCallback(paused)
-
- # Now, start streaming:
- streamingProducer.startStreaming()
- return done
-
-
- def test_resume(self):
- """
- When the streaming producer is paused and then resumed, the underlying
- producer starts getting resumeProducing calls again after the resume.
-
- The test will never finish (or rather, time out) if the resume
- producing call is not working.
- """
- class PausingStringTransport(StringTransport):
- writes = 0
-
- def write(self, data):
- self.writes += 1
- StringTransport.write(self, data)
- if self.writes == 3:
- self.producer.pauseProducing()
- self.producer.resumeProducing()
-
- consumer = PausingStringTransport()
- return self.streamUntilEnd(consumer)
-
-
- def test_stopProducing(self):
- """
- When the streaming producer is stopped by the consumer, the underlying
- producer is stopped, and streaming is stopped.
- """
- class StoppingStringTransport(StringTransport):
- writes = 0
-
- def write(self, data):
- self.writes += 1
- StringTransport.write(self, data)
- if self.writes == 3:
- self.producer.stopProducing()
-
- consumer = StoppingStringTransport()
- nsProducer = NonStreamingProducer(consumer)
- streamingProducer = _PullToPush(nsProducer, consumer)
- consumer.registerProducer(streamingProducer, True)
-
- done = nsProducer.result
- def doneStreaming(_):
- # Not all data was streamed, and the producer was stopped:
- self.assertEqual(consumer.value(), "012")
- self.assertEqual(nsProducer.stopped, True)
- # And the streaming wrapper stopped:
- self.assertEqual(streamingProducer._finished, True)
- done.addCallback(doneStreaming)
-
- # Now, start streaming:
- streamingProducer.startStreaming()
- return done
-
-
- def resumeProducingRaises(self, consumer, expectedExceptions):
- """
- Common implementation for tests where the underlying producer throws
- an exception when its resumeProducing is called.
- """
- class ThrowingProducer(NonStreamingProducer):
-
- def resumeProducing(self):
- if self.counter == 2:
- return 1/0
- else:
- NonStreamingProducer.resumeProducing(self)
-
- nsProducer = ThrowingProducer(consumer)
- streamingProducer = _PullToPush(nsProducer, consumer)
- consumer.registerProducer(streamingProducer, True)
-
- # Register log observer:
- loggedMsgs = []
- log.addObserver(loggedMsgs.append)
- self.addCleanup(log.removeObserver, loggedMsgs.append)
-
- # Make consumer unregister do what TLSMemoryBIOProtocol would do:
- def unregister(orig=consumer.unregisterProducer):
- orig()
- streamingProducer.stopStreaming()
- consumer.unregisterProducer = unregister
-
- # Start streaming:
- streamingProducer.startStreaming()
-
- done = streamingProducer._coopTask.whenDone()
- done.addErrback(lambda reason: reason.trap(TaskStopped))
- def stopped(ign):
- self.assertEqual(consumer.value(), "01")
- # Any errors from resumeProducing were logged:
- errors = self.flushLoggedErrors()
- self.assertEqual(len(errors), len(expectedExceptions))
- for f, (expected, msg), logMsg in zip(
- errors, expectedExceptions, loggedMsgs):
- self.assertTrue(f.check(expected))
- self.assertIn(msg, logMsg['why'])
- # And the streaming wrapper stopped:
- self.assertEqual(streamingProducer._finished, True)
- done.addCallback(stopped)
- return done
-
-
- def test_resumeProducingRaises(self):
- """
- If the underlying producer raises an exception when resumeProducing is
- called, the streaming wrapper should log the error, unregister from
- the consumer and stop streaming.
- """
- consumer = StringTransport()
- done = self.resumeProducingRaises(
- consumer,
- [(ZeroDivisionError, "failed, producing will be stopped")])
- def cleanShutdown(ignore):
- # Producer was unregistered from consumer:
- self.assertEqual(consumer.producer, None)
- done.addCallback(cleanShutdown)
- return done
-
-
- def test_resumeProducingRaiseAndUnregisterProducerRaises(self):
- """
- If the underlying producer raises an exception when resumeProducing is
- called, the streaming wrapper should log the error, unregister from
- the consumer and stop streaming even if the unregisterProducer call
- also raise.
- """
- consumer = StringTransport()
- def raiser():
- raise RuntimeError()
- consumer.unregisterProducer = raiser
- return self.resumeProducingRaises(
- consumer,
- [(ZeroDivisionError, "failed, producing will be stopped"),
- (RuntimeError, "failed to unregister producer")])
-
-
- def test_stopStreamingTwice(self):
- """
- stopStreaming() can be called more than once without blowing
- up. This is useful for error-handling paths.
- """
- consumer = StringTransport()
- nsProducer = NonStreamingProducer(consumer)
- streamingProducer = _PullToPush(nsProducer, consumer)
- streamingProducer.startStreaming()
- streamingProducer.stopStreaming()
- streamingProducer.stopStreaming()
- self.assertEqual(streamingProducer._finished, True)
-
-
- def test_interface(self):
- """
- L{_PullToPush} implements L{IPushProducer}.
- """
- consumer = StringTransport()
- nsProducer = NonStreamingProducer(consumer)
- streamingProducer = _PullToPush(nsProducer, consumer)
- self.assertTrue(verifyObject(IPushProducer, streamingProducer))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/tls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/tls.py
deleted file mode 100755
index a1b782f8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/tls.py
+++ /dev/null
@@ -1,613 +0,0 @@
-# -*- test-case-name: twisted.protocols.test.test_tls,twisted.internet.test.test_tls,twisted.test.test_sslverify -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation of a TLS transport (L{ISSLTransport}) as an
-L{IProtocol<twisted.internet.interfaces.IProtocol>} layered on top of any
-L{ITransport<twisted.internet.interfaces.ITransport>} implementation, based on
-U{OpenSSL<http://www.openssl.org>}'s memory BIO features.
-
-L{TLSMemoryBIOFactory} is a L{WrappingFactory} which wraps protocols created by
-the factory it wraps with L{TLSMemoryBIOProtocol}. L{TLSMemoryBIOProtocol}
-intercedes between the underlying transport and the wrapped protocol to
-implement SSL and TLS. Typical usage of this module looks like this::
-
- from twisted.protocols.tls import TLSMemoryBIOFactory
- from twisted.internet.protocol import ServerFactory
- from twisted.internet.ssl import PrivateCertificate
- from twisted.internet import reactor
-
- from someapplication import ApplicationProtocol
-
- serverFactory = ServerFactory()
- serverFactory.protocol = ApplicationProtocol
- certificate = PrivateCertificate.loadPEM(certPEMData)
- contextFactory = certificate.options()
- tlsFactory = TLSMemoryBIOFactory(contextFactory, False, serverFactory)
- reactor.listenTCP(12345, tlsFactory)
- reactor.run()
-
-This API offers somewhat more flexibility than
-L{twisted.internet.interfaces.IReactorSSL}; for example, a L{TLSMemoryBIOProtocol}
-instance can use another instance of L{TLSMemoryBIOProtocol} as its transport,
-yielding TLS over TLS - useful to implement onion routing. It can also be used
-to run TLS over unusual transports, such as UNIX sockets and stdio.
-"""
-
-
-from OpenSSL.SSL import Error, ZeroReturnError, WantReadError
-from OpenSSL.SSL import TLSv1_METHOD, Context, Connection
-
-try:
- Connection(Context(TLSv1_METHOD), None)
-except TypeError, e:
- if str(e) != "argument must be an int, or have a fileno() method.":
- raise
- raise ImportError("twisted.protocols.tls requires pyOpenSSL 0.10 or newer.")
-
-from zope.interface import implements, providedBy, directlyProvides
-
-from twisted.python.failure import Failure
-from twisted.python import log
-from twisted.python.reflect import safe_str
-from twisted.internet.interfaces import ISystemHandle, ISSLTransport
-from twisted.internet.interfaces import IPushProducer, ILoggingContext
-from twisted.internet.main import CONNECTION_LOST
-from twisted.internet.protocol import Protocol
-from twisted.internet.task import cooperate
-from twisted.protocols.policies import ProtocolWrapper, WrappingFactory
-
-
-class _PullToPush(object):
- """
- An adapter that converts a non-streaming to a streaming producer.
-
- Because of limitations of the producer API, this adapter requires the
- cooperation of the consumer. When the consumer's C{registerProducer} is
- called with a non-streaming producer, it must wrap it with L{_PullToPush}
- and then call C{startStreaming} on the resulting object. When the
- consumer's C{unregisterProducer} is called, it must call
- C{stopStreaming} on the L{_PullToPush} instance.
-
- If the underlying producer throws an exception from C{resumeProducing},
- the producer will be unregistered from the consumer.
-
- @ivar _producer: the underling non-streaming producer.
-
- @ivar _consumer: the consumer with which the underlying producer was
- registered.
-
- @ivar _finished: C{bool} indicating whether the producer has finished.
-
- @ivar _coopTask: the result of calling L{cooperate}, the task driving the
- streaming producer.
- """
- implements(IPushProducer)
-
- _finished = False
-
-
- def __init__(self, pullProducer, consumer):
- self._producer = pullProducer
- self._consumer = consumer
-
-
- def _pull(self):
- """
- A generator that calls C{resumeProducing} on the underlying producer
- forever.
-
- If C{resumeProducing} throws an exception, the producer is
- unregistered, which should result in streaming stopping.
- """
- while True:
- try:
- self._producer.resumeProducing()
- except:
- log.err(None, "%s failed, producing will be stopped:" %
- (safe_str(self._producer),))
- try:
- self._consumer.unregisterProducer()
- # The consumer should now call stopStreaming() on us,
- # thus stopping the streaming.
- except:
- # Since the consumer blew up, we may not have had
- # stopStreaming() called, so we just stop on our own:
- log.err(None, "%s failed to unregister producer:" %
- (safe_str(self._consumer),))
- self._finished = True
- return
- yield None
-
-
- def startStreaming(self):
- """
- This should be called by the consumer when the producer is registered.
-
- Start streaming data to the consumer.
- """
- self._coopTask = cooperate(self._pull())
-
-
- def stopStreaming(self):
- """
- This should be called by the consumer when the producer is unregistered.
-
- Stop streaming data to the consumer.
- """
- if self._finished:
- return
- self._finished = True
- self._coopTask.stop()
-
-
- # IPushProducer implementation:
- def pauseProducing(self):
- self._coopTask.pause()
-
-
- def resumeProducing(self):
- self._coopTask.resume()
-
-
- def stopProducing(self):
- self.stopStreaming()
- self._producer.stopProducing()
-
-
-
-class _ProducerMembrane(object):
- """
- Stand-in for producer registered with a L{TLSMemoryBIOProtocol} transport.
-
- Ensures that producer pause/resume events from the undelying transport are
- coordinated with pause/resume events from the TLS layer.
-
- @ivar _producer: The application-layer producer.
- """
- implements(IPushProducer)
-
- _producerPaused = False
-
- def __init__(self, producer):
- self._producer = producer
-
-
- def pauseProducing(self):
- """
- C{pauseProducing} the underlying producer, if it's not paused.
- """
- if self._producerPaused:
- return
- self._producerPaused = True
- self._producer.pauseProducing()
-
-
- def resumeProducing(self):
- """
- C{resumeProducing} the underlying producer, if it's paused.
- """
- if not self._producerPaused:
- return
- self._producerPaused = False
- self._producer.resumeProducing()
-
-
- def stopProducing(self):
- """
- C{stopProducing} the underlying producer.
-
- There is only a single source for this event, so it's simply passed
- on.
- """
- self._producer.stopProducing()
-
-
-
-class TLSMemoryBIOProtocol(ProtocolWrapper):
- """
- L{TLSMemoryBIOProtocol} is a protocol wrapper which uses OpenSSL via a
- memory BIO to encrypt bytes written to it before sending them on to the
- underlying transport and decrypts bytes received from the underlying
- transport before delivering them to the wrapped protocol.
-
- In addition to producer events from the underlying transport, the need to
- wait for reads before a write can proceed means the
- L{TLSMemoryBIOProtocol} may also want to pause a producer. Pause/resume
- events are therefore merged using the L{_ProducerMembrane}
- wrapper. Non-streaming (pull) producers are supported by wrapping them
- with L{_PullToPush}.
-
- @ivar _tlsConnection: The L{OpenSSL.SSL.Connection} instance which is
- encrypted and decrypting this connection.
-
- @ivar _lostTLSConnection: A flag indicating whether connection loss has
- already been dealt with (C{True}) or not (C{False}). TLS disconnection
- is distinct from the underlying connection being lost.
-
- @ivar _writeBlockedOnRead: A flag indicating whether further writing must
- wait for data to be received (C{True}) or not (C{False}).
-
- @ivar _appSendBuffer: A C{list} of C{str} of application-level (cleartext)
- data which is waiting for C{_writeBlockedOnRead} to be reset to
- C{False} so it can be passed to and perhaps accepted by
- C{_tlsConnection.send}.
-
- @ivar _connectWrapped: A flag indicating whether or not to call
- C{makeConnection} on the wrapped protocol. This is for the reactor's
- L{twisted.internet.interfaces.ITLSTransport.startTLS} implementation,
- since it has a protocol which it has already called C{makeConnection}
- on, and which has no interest in a new transport. See #3821.
-
- @ivar _handshakeDone: A flag indicating whether or not the handshake is
- known to have completed successfully (C{True}) or not (C{False}). This
- is used to control error reporting behavior. If the handshake has not
- completed, the underlying L{OpenSSL.SSL.Error} will be passed to the
- application's C{connectionLost} method. If it has completed, any
- unexpected L{OpenSSL.SSL.Error} will be turned into a
- L{ConnectionLost}. This is weird; however, it is simply an attempt at
- a faithful re-implementation of the behavior provided by
- L{twisted.internet.ssl}.
-
- @ivar _reason: If an unexpected L{OpenSSL.SSL.Error} occurs which causes
- the connection to be lost, it is saved here. If appropriate, this may
- be used as the reason passed to the application protocol's
- C{connectionLost} method.
-
- @ivar _producer: The current producer registered via C{registerProducer},
- or C{None} if no producer has been registered or a previous one was
- unregistered.
- """
- implements(ISystemHandle, ISSLTransport)
-
- _reason = None
- _handshakeDone = False
- _lostTLSConnection = False
- _writeBlockedOnRead = False
- _producer = None
-
- def __init__(self, factory, wrappedProtocol, _connectWrapped=True):
- ProtocolWrapper.__init__(self, factory, wrappedProtocol)
- self._connectWrapped = _connectWrapped
-
-
- def getHandle(self):
- """
- Return the L{OpenSSL.SSL.Connection} object being used to encrypt and
- decrypt this connection.
-
- This is done for the benefit of L{twisted.internet.ssl.Certificate}'s
- C{peerFromTransport} and C{hostFromTransport} methods only. A
- different system handle may be returned by future versions of this
- method.
- """
- return self._tlsConnection
-
-
- def makeConnection(self, transport):
- """
- Connect this wrapper to the given transport and initialize the
- necessary L{OpenSSL.SSL.Connection} with a memory BIO.
- """
- tlsContext = self.factory._contextFactory.getContext()
- self._tlsConnection = Connection(tlsContext, None)
- if self.factory._isClient:
- self._tlsConnection.set_connect_state()
- else:
- self._tlsConnection.set_accept_state()
- self._appSendBuffer = []
-
- # Add interfaces provided by the transport we are wrapping:
- for interface in providedBy(transport):
- directlyProvides(self, interface)
-
- # Intentionally skip ProtocolWrapper.makeConnection - it might call
- # wrappedProtocol.makeConnection, which we want to make conditional.
- Protocol.makeConnection(self, transport)
- self.factory.registerProtocol(self)
- if self._connectWrapped:
- # Now that the TLS layer is initialized, notify the application of
- # the connection.
- ProtocolWrapper.makeConnection(self, transport)
-
- # Now that we ourselves have a transport (initialized by the
- # ProtocolWrapper.makeConnection call above), kick off the TLS
- # handshake.
- try:
- self._tlsConnection.do_handshake()
- except WantReadError:
- # This is the expected case - there's no data in the connection's
- # input buffer yet, so it won't be able to complete the whole
- # handshake now. If this is the speak-first side of the
- # connection, then some bytes will be in the send buffer now; flush
- # them.
- self._flushSendBIO()
-
-
- def _flushSendBIO(self):
- """
- Read any bytes out of the send BIO and write them to the underlying
- transport.
- """
- try:
- bytes = self._tlsConnection.bio_read(2 ** 15)
- except WantReadError:
- # There may be nothing in the send BIO right now.
- pass
- else:
- self.transport.write(bytes)
-
-
- def _flushReceiveBIO(self):
- """
- Try to receive any application-level bytes which are now available
- because of a previous write into the receive BIO. This will take
- care of delivering any application-level bytes which are received to
- the protocol, as well as handling of the various exceptions which
- can come from trying to get such bytes.
- """
- # Keep trying this until an error indicates we should stop or we
- # close the connection. Looping is necessary to make sure we
- # process all of the data which was put into the receive BIO, as
- # there is no guarantee that a single recv call will do it all.
- while not self._lostTLSConnection:
- try:
- bytes = self._tlsConnection.recv(2 ** 15)
- except WantReadError:
- # The newly received bytes might not have been enough to produce
- # any application data.
- break
- except ZeroReturnError:
- # TLS has shut down and no more TLS data will be received over
- # this connection.
- self._shutdownTLS()
- # Passing in None means the user protocol's connnectionLost
- # will get called with reason from underlying transport:
- self._tlsShutdownFinished(None)
- except Error, e:
- # Something went pretty wrong. For example, this might be a
- # handshake failure (because there were no shared ciphers, because
- # a certificate failed to verify, etc). TLS can no longer proceed.
-
- # Squash EOF in violation of protocol into ConnectionLost; we
- # create Failure before calling _flushSendBio so that no new
- # exception will get thrown in the interim.
- if e.args[0] == -1 and e.args[1] == 'Unexpected EOF':
- failure = Failure(CONNECTION_LOST)
- else:
- failure = Failure()
-
- self._flushSendBIO()
- self._tlsShutdownFinished(failure)
- else:
- # If we got application bytes, the handshake must be done by
- # now. Keep track of this to control error reporting later.
- self._handshakeDone = True
- ProtocolWrapper.dataReceived(self, bytes)
-
- # The received bytes might have generated a response which needs to be
- # sent now. For example, the handshake involves several round-trip
- # exchanges without ever producing application-bytes.
- self._flushSendBIO()
-
-
- def dataReceived(self, bytes):
- """
- Deliver any received bytes to the receive BIO and then read and deliver
- to the application any application-level data which becomes available
- as a result of this.
- """
- self._tlsConnection.bio_write(bytes)
-
- if self._writeBlockedOnRead:
- # A read just happened, so we might not be blocked anymore. Try to
- # flush all the pending application bytes.
- self._writeBlockedOnRead = False
- appSendBuffer = self._appSendBuffer
- self._appSendBuffer = []
- for bytes in appSendBuffer:
- self._write(bytes)
- if (not self._writeBlockedOnRead and self.disconnecting and
- self.producer is None):
- self._shutdownTLS()
- if self._producer is not None:
- self._producer.resumeProducing()
-
- self._flushReceiveBIO()
-
-
- def _shutdownTLS(self):
- """
- Initiate, or reply to, the shutdown handshake of the TLS layer.
- """
- shutdownSuccess = self._tlsConnection.shutdown()
- self._flushSendBIO()
- if shutdownSuccess:
- # Both sides have shutdown, so we can start closing lower-level
- # transport. This will also happen if we haven't started
- # negotiation at all yet, in which case shutdown succeeds
- # immediately.
- self.transport.loseConnection()
-
-
- def _tlsShutdownFinished(self, reason):
- """
- Called when TLS connection has gone away; tell underlying transport to
- disconnect.
- """
- self._reason = reason
- self._lostTLSConnection = True
- # Using loseConnection causes the application protocol's
- # connectionLost method to be invoked non-reentrantly, which is always
- # a nice feature. However, for error cases (reason != None) we might
- # want to use abortConnection when it becomes available. The
- # loseConnection call is basically tested by test_handshakeFailure.
- # At least one side will need to do it or the test never finishes.
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- """
- Handle the possible repetition of calls to this method (due to either
- the underlying transport going away or due to an error at the TLS
- layer) and make sure the base implementation only gets invoked once.
- """
- if not self._lostTLSConnection:
- # Tell the TLS connection that it's not going to get any more data
- # and give it a chance to finish reading.
- self._tlsConnection.bio_shutdown()
- self._flushReceiveBIO()
- self._lostTLSConnection = True
- reason = self._reason or reason
- self._reason = None
- ProtocolWrapper.connectionLost(self, reason)
-
-
- def loseConnection(self):
- """
- Send a TLS close alert and close the underlying connection.
- """
- if self.disconnecting:
- return
- self.disconnecting = True
- if not self._writeBlockedOnRead and self._producer is None:
- self._shutdownTLS()
-
-
- def write(self, bytes):
- """
- Process the given application bytes and send any resulting TLS traffic
- which arrives in the send BIO.
-
- If C{loseConnection} was called, subsequent calls to C{write} will
- drop the bytes on the floor.
- """
- # Writes after loseConnection are not supported, unless a producer has
- # been registered, in which case writes can happen until the producer
- # is unregistered:
- if self.disconnecting and self._producer is None:
- return
- self._write(bytes)
-
-
- def _write(self, bytes):
- """
- Process the given application bytes and send any resulting TLS traffic
- which arrives in the send BIO.
-
- This may be called by C{dataReceived} with bytes that were buffered
- before C{loseConnection} was called, which is why this function
- doesn't check for disconnection but accepts the bytes regardless.
- """
- if self._lostTLSConnection:
- return
-
- leftToSend = bytes
- while leftToSend:
- try:
- sent = self._tlsConnection.send(leftToSend)
- except WantReadError:
- self._writeBlockedOnRead = True
- self._appSendBuffer.append(leftToSend)
- if self._producer is not None:
- self._producer.pauseProducing()
- break
- except Error:
- # Pretend TLS connection disconnected, which will trigger
- # disconnect of underlying transport. The error will be passed
- # to the application protocol's connectionLost method. The
- # other SSL implementation doesn't, but losing helpful
- # debugging information is a bad idea.
- self._tlsShutdownFinished(Failure())
- break
- else:
- # If we sent some bytes, the handshake must be done. Keep
- # track of this to control error reporting behavior.
- self._handshakeDone = True
- self._flushSendBIO()
- leftToSend = leftToSend[sent:]
-
-
- def writeSequence(self, iovec):
- """
- Write a sequence of application bytes by joining them into one string
- and passing them to L{write}.
- """
- self.write("".join(iovec))
-
-
- def getPeerCertificate(self):
- return self._tlsConnection.get_peer_certificate()
-
-
- def registerProducer(self, producer, streaming):
- # If we've already disconnected, nothing to do here:
- if self._lostTLSConnection:
- producer.stopProducing()
- return
-
- # If we received a non-streaming producer, wrap it so it becomes a
- # streaming producer:
- if not streaming:
- producer = streamingProducer = _PullToPush(producer, self)
- producer = _ProducerMembrane(producer)
- # This will raise an exception if a producer is already registered:
- self.transport.registerProducer(producer, True)
- self._producer = producer
- # If we received a non-streaming producer, we need to start the
- # streaming wrapper:
- if not streaming:
- streamingProducer.startStreaming()
-
-
- def unregisterProducer(self):
- # If we received a non-streaming producer, we need to stop the
- # streaming wrapper:
- if isinstance(self._producer._producer, _PullToPush):
- self._producer._producer.stopStreaming()
- self._producer = None
- self._producerPaused = False
- self.transport.unregisterProducer()
- if self.disconnecting and not self._writeBlockedOnRead:
- self._shutdownTLS()
-
-
-
-class TLSMemoryBIOFactory(WrappingFactory):
- """
- L{TLSMemoryBIOFactory} adds TLS to connections.
-
- @ivar _contextFactory: The TLS context factory which will be used to define
- certain TLS connection parameters.
-
- @ivar _isClient: A flag which is C{True} if this is a client TLS
- connection, C{False} if it is a server TLS connection.
- """
- protocol = TLSMemoryBIOProtocol
-
- noisy = False # disable unnecessary logging.
-
- def __init__(self, contextFactory, isClient, wrappedFactory):
- WrappingFactory.__init__(self, wrappedFactory)
- self._contextFactory = contextFactory
- self._isClient = isClient
-
- # Force some parameter checking in pyOpenSSL. It's better to fail now
- # than after we've set up the transport.
- contextFactory.getContext()
-
-
- def logPrefix(self):
- """
- Annotate the wrapped factory's log prefix with some text indicating TLS
- is in use.
-
- @rtype: C{str}
- """
- if ILoggingContext.providedBy(self.wrappedFactory):
- logPrefix = self.wrappedFactory.logPrefix()
- else:
- logPrefix = self.wrappedFactory.__class__.__name__
- return "%s (TLS)" % (logPrefix,)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/wire.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/wire.py
deleted file mode 100755
index dddf215f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/protocols/wire.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""Implement standard (and unused) TCP protocols.
-
-These protocols are either provided by inetd, or are not provided at all.
-"""
-
-# system imports
-import time, struct
-from zope.interface import implements
-
-# twisted import
-from twisted.internet import protocol, interfaces
-
-
-class Echo(protocol.Protocol):
- """As soon as any data is received, write it back (RFC 862)"""
-
- def dataReceived(self, data):
- self.transport.write(data)
-
-
-class Discard(protocol.Protocol):
- """Discard any received data (RFC 863)"""
-
- def dataReceived(self, data):
- # I'm ignoring you, nyah-nyah
- pass
-
-
-class Chargen(protocol.Protocol):
- """Generate repeating noise (RFC 864)"""
- noise = r'@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&?'
-
- implements(interfaces.IProducer)
-
- def connectionMade(self):
- self.transport.registerProducer(self, 0)
-
- def resumeProducing(self):
- self.transport.write(self.noise)
-
- def pauseProducing(self):
- pass
-
- def stopProducing(self):
- pass
-
-
-class QOTD(protocol.Protocol):
- """Return a quote of the day (RFC 865)"""
-
- def connectionMade(self):
- self.transport.write(self.getQuote())
- self.transport.loseConnection()
-
- def getQuote(self):
- """Return a quote. May be overrriden in subclasses."""
- return "An apple a day keeps the doctor away.\r\n"
-
-class Who(protocol.Protocol):
- """Return list of active users (RFC 866)"""
-
- def connectionMade(self):
- self.transport.write(self.getUsers())
- self.transport.loseConnection()
-
- def getUsers(self):
- """Return active users. Override in subclasses."""
- return "root\r\n"
-
-
-class Daytime(protocol.Protocol):
- """Send back the daytime in ASCII form (RFC 867)"""
-
- def connectionMade(self):
- self.transport.write(time.asctime(time.gmtime(time.time())) + '\r\n')
- self.transport.loseConnection()
-
-
-class Time(protocol.Protocol):
- """Send back the time in machine readable form (RFC 868)"""
-
- def connectionMade(self):
- # is this correct only for 32-bit machines?
- result = struct.pack("!i", int(time.time()))
- self.transport.write(result)
- self.transport.loseConnection()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/__init__.py
deleted file mode 100755
index ae78c7bf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-
-Twisted Python: Utilities and Enhancements for Python.
-
-"""
-
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.c
deleted file mode 100644
index dffbe259..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.c
+++ /dev/null
@@ -1,3348 +0,0 @@
-/* Generated by Cython 0.15.1 on Fri Feb 17 23:33:28 2012 */
-
-#define PY_SSIZE_T_CLEAN
-#include "Python.h"
-#ifndef Py_PYTHON_H
- #error Python headers needed to compile C extensions, please install development version of Python.
-#else
-
-#include <stddef.h> /* For offsetof */
-#ifndef offsetof
-#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
-#endif
-
-#if !defined(WIN32) && !defined(MS_WINDOWS)
- #ifndef __stdcall
- #define __stdcall
- #endif
- #ifndef __cdecl
- #define __cdecl
- #endif
- #ifndef __fastcall
- #define __fastcall
- #endif
-#endif
-
-#ifndef DL_IMPORT
- #define DL_IMPORT(t) t
-#endif
-#ifndef DL_EXPORT
- #define DL_EXPORT(t) t
-#endif
-
-#ifndef PY_LONG_LONG
- #define PY_LONG_LONG LONG_LONG
-#endif
-
-#if PY_VERSION_HEX < 0x02040000
- #define METH_COEXIST 0
- #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
- #define PyDict_Contains(d,o) PySequence_Contains(d,o)
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- typedef int Py_ssize_t;
- #define PY_SSIZE_T_MAX INT_MAX
- #define PY_SSIZE_T_MIN INT_MIN
- #define PY_FORMAT_SIZE_T ""
- #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
- #define PyInt_AsSsize_t(o) __Pyx_PyInt_AsInt(o)
- #define PyNumber_Index(o) PyNumber_Int(o)
- #define PyIndex_Check(o) PyNumber_Check(o)
- #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
- #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
- #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
- #define PyVarObject_HEAD_INIT(type, size) \
- PyObject_HEAD_INIT(type) size,
- #define PyType_Modified(t)
-
- typedef struct {
- void *buf;
- PyObject *obj;
- Py_ssize_t len;
- Py_ssize_t itemsize;
- int readonly;
- int ndim;
- char *format;
- Py_ssize_t *shape;
- Py_ssize_t *strides;
- Py_ssize_t *suboffsets;
- void *internal;
- } Py_buffer;
-
- #define PyBUF_SIMPLE 0
- #define PyBUF_WRITABLE 0x0001
- #define PyBUF_FORMAT 0x0004
- #define PyBUF_ND 0x0008
- #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
- #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
- #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
- #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
- #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
-
-#endif
-
-#if PY_MAJOR_VERSION < 3
- #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-#else
- #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define Py_TPFLAGS_CHECKTYPES 0
- #define Py_TPFLAGS_HAVE_INDEX 0
-#endif
-
-#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
- #define Py_TPFLAGS_HAVE_NEWBUFFER 0
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyBaseString_Type PyUnicode_Type
- #define PyStringObject PyUnicodeObject
- #define PyString_Type PyUnicode_Type
- #define PyString_Check PyUnicode_Check
- #define PyString_CheckExact PyUnicode_CheckExact
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define PyBytesObject PyStringObject
- #define PyBytes_Type PyString_Type
- #define PyBytes_Check PyString_Check
- #define PyBytes_CheckExact PyString_CheckExact
- #define PyBytes_FromString PyString_FromString
- #define PyBytes_FromStringAndSize PyString_FromStringAndSize
- #define PyBytes_FromFormat PyString_FromFormat
- #define PyBytes_DecodeEscape PyString_DecodeEscape
- #define PyBytes_AsString PyString_AsString
- #define PyBytes_AsStringAndSize PyString_AsStringAndSize
- #define PyBytes_Size PyString_Size
- #define PyBytes_AS_STRING PyString_AS_STRING
- #define PyBytes_GET_SIZE PyString_GET_SIZE
- #define PyBytes_Repr PyString_Repr
- #define PyBytes_Concat PyString_Concat
- #define PyBytes_ConcatAndDel PyString_ConcatAndDel
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
- #define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
-#endif
-#ifndef PySet_CheckExact
- #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
-#endif
-
-#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
-
-#if PY_MAJOR_VERSION >= 3
- #define PyIntObject PyLongObject
- #define PyInt_Type PyLong_Type
- #define PyInt_Check(op) PyLong_Check(op)
- #define PyInt_CheckExact(op) PyLong_CheckExact(op)
- #define PyInt_FromString PyLong_FromString
- #define PyInt_FromUnicode PyLong_FromUnicode
- #define PyInt_FromLong PyLong_FromLong
- #define PyInt_FromSize_t PyLong_FromSize_t
- #define PyInt_FromSsize_t PyLong_FromSsize_t
- #define PyInt_AsLong PyLong_AsLong
- #define PyInt_AS_LONG PyLong_AS_LONG
- #define PyInt_AsSsize_t PyLong_AsSsize_t
- #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
- #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyBoolObject PyLongObject
-#endif
-
-#if PY_VERSION_HEX < 0x03020000
- typedef long Py_hash_t;
- #define __Pyx_PyInt_FromHash_t PyInt_FromLong
- #define __Pyx_PyInt_AsHash_t PyInt_AsLong
-#else
- #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
- #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
- #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
- #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
-#else
- #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
- #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
-#endif
-
-#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
- #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
- #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
- #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
-#else
- #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
- #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
- #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
- #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
- #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
-#else
- #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
- #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
- #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- #define __Pyx_NAMESTR(n) ((char *)(n))
- #define __Pyx_DOCSTR(n) ((char *)(n))
-#else
- #define __Pyx_NAMESTR(n) (n)
- #define __Pyx_DOCSTR(n) (n)
-#endif
-
-#ifndef __PYX_EXTERN_C
- #ifdef __cplusplus
- #define __PYX_EXTERN_C extern "C"
- #else
- #define __PYX_EXTERN_C extern
- #endif
-#endif
-
-#if defined(WIN32) || defined(MS_WINDOWS)
-#define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-#define __PYX_HAVE__twisted__python___epoll
-#define __PYX_HAVE_API__twisted__python___epoll
-#include "stdio.h"
-#include "errno.h"
-#include "string.h"
-#include "stdint.h"
-#include "sys/epoll.h"
-#ifdef _OPENMP
-#include <omp.h>
-#endif /* _OPENMP */
-
-#ifdef PYREX_WITHOUT_ASSERTIONS
-#define CYTHON_WITHOUT_ASSERTIONS
-#endif
-
-
-/* inline attribute */
-#ifndef CYTHON_INLINE
- #if defined(__GNUC__)
- #define CYTHON_INLINE __inline__
- #elif defined(_MSC_VER)
- #define CYTHON_INLINE __inline
- #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- #define CYTHON_INLINE inline
- #else
- #define CYTHON_INLINE
- #endif
-#endif
-
-/* unused attribute */
-#ifndef CYTHON_UNUSED
-# if defined(__GNUC__)
-# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-# define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-# define CYTHON_UNUSED
-# endif
-# elif defined(__ICC) || defined(__INTEL_COMPILER)
-# define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-# define CYTHON_UNUSED
-# endif
-#endif
-
-typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
-
-
-/* Type Conversion Predeclarations */
-
-#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
-#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) PyBytes_AsString(s))
-
-#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
-#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
-
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
-
-#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
-
-
-#ifdef __GNUC__
- /* Test for GCC > 2.95 */
- #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
- #define likely(x) __builtin_expect(!!(x), 1)
- #define unlikely(x) __builtin_expect(!!(x), 0)
- #else /* __GNUC__ > 2 ... */
- #define likely(x) (x)
- #define unlikely(x) (x)
- #endif /* __GNUC__ > 2 ... */
-#else /* __GNUC__ */
- #define likely(x) (x)
- #define unlikely(x) (x)
-#endif /* __GNUC__ */
-
-static PyObject *__pyx_m;
-static PyObject *__pyx_b;
-static PyObject *__pyx_empty_tuple;
-static PyObject *__pyx_empty_bytes;
-static int __pyx_lineno;
-static int __pyx_clineno = 0;
-static const char * __pyx_cfilenm= __FILE__;
-static const char *__pyx_filename;
-
-
-static const char *__pyx_f[] = {
- "_epoll.pyx",
-};
-
-/*--- Type declarations ---*/
-struct __pyx_obj_7twisted_6python_6_epoll_epoll;
-
-/* "twisted/python/_epoll.pyx":106
- * free(events)
- *
- * cdef class epoll: # <<<<<<<<<<<<<<
- * """
- * Represent a set of file descriptors being monitored for events.
- */
-struct __pyx_obj_7twisted_6python_6_epoll_epoll {
- PyObject_HEAD
- int fd;
- int initialized;
-};
-
-
-#ifndef CYTHON_REFNANNY
- #define CYTHON_REFNANNY 0
-#endif
-
-#if CYTHON_REFNANNY
- typedef struct {
- void (*INCREF)(void*, PyObject*, int);
- void (*DECREF)(void*, PyObject*, int);
- void (*GOTREF)(void*, PyObject*, int);
- void (*GIVEREF)(void*, PyObject*, int);
- void* (*SetupContext)(const char*, int, const char*);
- void (*FinishContext)(void**);
- } __Pyx_RefNannyAPIStruct;
- static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
- static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
- #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
- #define __Pyx_RefNannySetupContext(name) __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
- #define __Pyx_RefNannyFinishContext() __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
- #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
- #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
- #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
- #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
-#else
- #define __Pyx_RefNannyDeclarations
- #define __Pyx_RefNannySetupContext(name)
- #define __Pyx_RefNannyFinishContext()
- #define __Pyx_INCREF(r) Py_INCREF(r)
- #define __Pyx_DECREF(r) Py_DECREF(r)
- #define __Pyx_GOTREF(r)
- #define __Pyx_GIVEREF(r)
- #define __Pyx_XINCREF(r) Py_XINCREF(r)
- #define __Pyx_XDECREF(r) Py_XDECREF(r)
- #define __Pyx_XGOTREF(r)
- #define __Pyx_XGIVEREF(r)
-#endif /* CYTHON_REFNANNY */
-
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
-
-static void __Pyx_RaiseDoubleKeywordsError(
- const char* func_name, PyObject* kw_name); /*proto*/
-
-static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/
-
-static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
- Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
-
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
-
-static int __Pyx_check_binary_version(void);
-
-static void __Pyx_AddTraceback(const char *funcname, int __pyx_clineno,
- int __pyx_lineno, const char *__pyx_filename); /*proto*/
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
-
-/* Module declarations from 'twisted.python._epoll' */
-static PyTypeObject *__pyx_ptype_7twisted_6python_6_epoll_epoll = 0;
-static PyObject *__pyx_f_7twisted_6python_6_epoll_call_epoll_wait(int, unsigned int, int); /*proto*/
-#define __Pyx_MODULE_NAME "twisted.python._epoll"
-int __pyx_module_is_main_twisted__python___epoll = 0;
-
-/* Implementation of 'twisted.python._epoll' */
-static PyObject *__pyx_builtin_IOError;
-static char __pyx_k_1[] = "\nInterface to epoll I/O event notification facility.\n";
-static char __pyx_k__ET[] = "ET";
-static char __pyx_k__IN[] = "IN";
-static char __pyx_k__fd[] = "fd";
-static char __pyx_k__op[] = "op";
-static char __pyx_k__ERR[] = "ERR";
-static char __pyx_k__HUP[] = "HUP";
-static char __pyx_k__MSG[] = "MSG";
-static char __pyx_k__OUT[] = "OUT";
-static char __pyx_k__PRI[] = "PRI";
-static char __pyx_k__size[] = "size";
-static char __pyx_k__RDBAND[] = "RDBAND";
-static char __pyx_k__RDNORM[] = "RDNORM";
-static char __pyx_k__WRBAND[] = "WRBAND";
-static char __pyx_k__WRNORM[] = "WRNORM";
-static char __pyx_k__events[] = "events";
-static char __pyx_k__CTL_ADD[] = "CTL_ADD";
-static char __pyx_k__CTL_DEL[] = "CTL_DEL";
-static char __pyx_k__CTL_MOD[] = "CTL_MOD";
-static char __pyx_k__EPOLLET[] = "EPOLLET";
-static char __pyx_k__EPOLLIN[] = "EPOLLIN";
-static char __pyx_k__IOError[] = "IOError";
-static char __pyx_k__timeout[] = "timeout";
-static char __pyx_k__EPOLLERR[] = "EPOLLERR";
-static char __pyx_k__EPOLLHUP[] = "EPOLLHUP";
-static char __pyx_k__EPOLLMSG[] = "EPOLLMSG";
-static char __pyx_k__EPOLLOUT[] = "EPOLLOUT";
-static char __pyx_k__EPOLLPRI[] = "EPOLLPRI";
-static char __pyx_k____main__[] = "__main__";
-static char __pyx_k____test__[] = "__test__";
-static char __pyx_k__maxevents[] = "maxevents";
-static char __pyx_k__EPOLLRDBAND[] = "EPOLLRDBAND";
-static char __pyx_k__EPOLLRDNORM[] = "EPOLLRDNORM";
-static char __pyx_k__EPOLLWRBAND[] = "EPOLLWRBAND";
-static char __pyx_k__EPOLLWRNORM[] = "EPOLLWRNORM";
-static PyObject *__pyx_n_s__CTL_ADD;
-static PyObject *__pyx_n_s__CTL_DEL;
-static PyObject *__pyx_n_s__CTL_MOD;
-static PyObject *__pyx_n_s__EPOLLERR;
-static PyObject *__pyx_n_s__EPOLLET;
-static PyObject *__pyx_n_s__EPOLLHUP;
-static PyObject *__pyx_n_s__EPOLLIN;
-static PyObject *__pyx_n_s__EPOLLMSG;
-static PyObject *__pyx_n_s__EPOLLOUT;
-static PyObject *__pyx_n_s__EPOLLPRI;
-static PyObject *__pyx_n_s__EPOLLRDBAND;
-static PyObject *__pyx_n_s__EPOLLRDNORM;
-static PyObject *__pyx_n_s__EPOLLWRBAND;
-static PyObject *__pyx_n_s__EPOLLWRNORM;
-static PyObject *__pyx_n_s__ERR;
-static PyObject *__pyx_n_s__ET;
-static PyObject *__pyx_n_s__HUP;
-static PyObject *__pyx_n_s__IN;
-static PyObject *__pyx_n_s__IOError;
-static PyObject *__pyx_n_s__MSG;
-static PyObject *__pyx_n_s__OUT;
-static PyObject *__pyx_n_s__PRI;
-static PyObject *__pyx_n_s__RDBAND;
-static PyObject *__pyx_n_s__RDNORM;
-static PyObject *__pyx_n_s__WRBAND;
-static PyObject *__pyx_n_s__WRNORM;
-static PyObject *__pyx_n_s____main__;
-static PyObject *__pyx_n_s____test__;
-static PyObject *__pyx_n_s__events;
-static PyObject *__pyx_n_s__fd;
-static PyObject *__pyx_n_s__maxevents;
-static PyObject *__pyx_n_s__op;
-static PyObject *__pyx_n_s__size;
-static PyObject *__pyx_n_s__timeout;
-
-/* "twisted/python/_epoll.pyx":68
- * cdef extern void PyEval_RestoreThread(PyThreadState*)
- *
- * cdef call_epoll_wait(int fd, unsigned int maxevents, int timeout_msec): # <<<<<<<<<<<<<<
- * """
- * Wait for an I/O event, wrap epoll_wait(2).
- */
-
-static PyObject *__pyx_f_7twisted_6python_6_epoll_call_epoll_wait(int __pyx_v_fd, unsigned int __pyx_v_maxevents, int __pyx_v_timeout_msec) {
- struct epoll_event *__pyx_v_events;
- int __pyx_v_result;
- int __pyx_v_nbytes;
- PyThreadState *__pyx_v__save;
- PyObject *__pyx_v_results = NULL;
- long __pyx_v_i;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- int __pyx_t_5;
- int __pyx_t_6;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("call_epoll_wait");
-
- /* "twisted/python/_epoll.pyx":89
- * cdef PyThreadState *_save
- *
- * nbytes = sizeof(epoll_event) * maxevents # <<<<<<<<<<<<<<
- * events = <epoll_event*>malloc(nbytes)
- * memset(events, 0, nbytes)
- */
- __pyx_v_nbytes = ((sizeof(struct epoll_event)) * __pyx_v_maxevents);
-
- /* "twisted/python/_epoll.pyx":90
- *
- * nbytes = sizeof(epoll_event) * maxevents
- * events = <epoll_event*>malloc(nbytes) # <<<<<<<<<<<<<<
- * memset(events, 0, nbytes)
- * try:
- */
- __pyx_v_events = ((struct epoll_event *)malloc(__pyx_v_nbytes));
-
- /* "twisted/python/_epoll.pyx":91
- * nbytes = sizeof(epoll_event) * maxevents
- * events = <epoll_event*>malloc(nbytes)
- * memset(events, 0, nbytes) # <<<<<<<<<<<<<<
- * try:
- * _save = PyEval_SaveThread()
- */
- memset(__pyx_v_events, 0, __pyx_v_nbytes);
-
- /* "twisted/python/_epoll.pyx":92
- * events = <epoll_event*>malloc(nbytes)
- * memset(events, 0, nbytes)
- * try: # <<<<<<<<<<<<<<
- * _save = PyEval_SaveThread()
- * result = epoll_wait(fd, events, maxevents, timeout_msec)
- */
- /*try:*/ {
-
- /* "twisted/python/_epoll.pyx":93
- * memset(events, 0, nbytes)
- * try:
- * _save = PyEval_SaveThread() # <<<<<<<<<<<<<<
- * result = epoll_wait(fd, events, maxevents, timeout_msec)
- * PyEval_RestoreThread(_save)
- */
- __pyx_v__save = PyEval_SaveThread();
-
- /* "twisted/python/_epoll.pyx":94
- * try:
- * _save = PyEval_SaveThread()
- * result = epoll_wait(fd, events, maxevents, timeout_msec) # <<<<<<<<<<<<<<
- * PyEval_RestoreThread(_save)
- *
- */
- __pyx_v_result = epoll_wait(__pyx_v_fd, __pyx_v_events, __pyx_v_maxevents, __pyx_v_timeout_msec);
-
- /* "twisted/python/_epoll.pyx":95
- * _save = PyEval_SaveThread()
- * result = epoll_wait(fd, events, maxevents, timeout_msec)
- * PyEval_RestoreThread(_save) # <<<<<<<<<<<<<<
- *
- * if result == -1:
- */
- PyEval_RestoreThread(__pyx_v__save);
-
- /* "twisted/python/_epoll.pyx":97
- * PyEval_RestoreThread(_save)
- *
- * if result == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- * results = []
- */
- __pyx_t_1 = (__pyx_v_result == -1);
- if (__pyx_t_1) {
-
- /* "twisted/python/_epoll.pyx":98
- *
- * if result == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- * results = []
- * for i from 0 <= i < result:
- */
- __pyx_t_2 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_t_3));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_t_3 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
- __Pyx_Raise(__pyx_t_3, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L4;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "twisted/python/_epoll.pyx":99
- * if result == -1:
- * raise IOError(errno, strerror(errno))
- * results = [] # <<<<<<<<<<<<<<
- * for i from 0 <= i < result:
- * results.append((events[i].data.fd, <int>events[i].events))
- */
- __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __pyx_v_results = __pyx_t_3;
- __pyx_t_3 = 0;
-
- /* "twisted/python/_epoll.pyx":100
- * raise IOError(errno, strerror(errno))
- * results = []
- * for i from 0 <= i < result: # <<<<<<<<<<<<<<
- * results.append((events[i].data.fd, <int>events[i].events))
- * return results
- */
- __pyx_t_5 = __pyx_v_result;
- for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_5; __pyx_v_i++) {
-
- /* "twisted/python/_epoll.pyx":101
- * results = []
- * for i from 0 <= i < result:
- * results.append((events[i].data.fd, <int>events[i].events)) # <<<<<<<<<<<<<<
- * return results
- * finally:
- */
- if (unlikely(((PyObject *)__pyx_v_results) == Py_None)) {
- PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "append"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L4;}
- }
- __pyx_t_3 = PyInt_FromLong((__pyx_v_events[__pyx_v_i]).data.fd); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(__pyx_t_3);
- __pyx_t_4 = PyInt_FromLong(((int)(__pyx_v_events[__pyx_v_i]).events)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(__pyx_t_4);
- __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_2));
- PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
- __Pyx_GIVEREF(__pyx_t_4);
- __pyx_t_3 = 0;
- __pyx_t_4 = 0;
- __pyx_t_6 = PyList_Append(__pyx_v_results, ((PyObject *)__pyx_t_2)); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L4;}
- __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
- }
-
- /* "twisted/python/_epoll.pyx":102
- * for i from 0 <= i < result:
- * results.append((events[i].data.fd, <int>events[i].events))
- * return results # <<<<<<<<<<<<<<
- * finally:
- * free(events)
- */
- __Pyx_XDECREF(__pyx_r);
- __Pyx_INCREF(((PyObject *)__pyx_v_results));
- __pyx_r = ((PyObject *)__pyx_v_results);
- goto __pyx_L3;
- }
-
- /* "twisted/python/_epoll.pyx":104
- * return results
- * finally:
- * free(events) # <<<<<<<<<<<<<<
- *
- * cdef class epoll:
- */
- /*finally:*/ {
- int __pyx_why;
- PyObject *__pyx_exc_type, *__pyx_exc_value, *__pyx_exc_tb;
- int __pyx_exc_lineno;
- __pyx_exc_type = 0; __pyx_exc_value = 0; __pyx_exc_tb = 0; __pyx_exc_lineno = 0;
- __pyx_why = 0; goto __pyx_L5;
- __pyx_L3: __pyx_exc_type = 0; __pyx_exc_value = 0; __pyx_exc_tb = 0; __pyx_exc_lineno = 0;
- __pyx_why = 3; goto __pyx_L5;
- __pyx_L4: {
- __pyx_why = 4;
- __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
- __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
- __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
- __Pyx_ErrFetch(&__pyx_exc_type, &__pyx_exc_value, &__pyx_exc_tb);
- __pyx_exc_lineno = __pyx_lineno;
- goto __pyx_L5;
- }
- __pyx_L5:;
- free(__pyx_v_events);
- switch (__pyx_why) {
- case 3: goto __pyx_L0;
- case 4: {
- __Pyx_ErrRestore(__pyx_exc_type, __pyx_exc_value, __pyx_exc_tb);
- __pyx_lineno = __pyx_exc_lineno;
- __pyx_exc_type = 0;
- __pyx_exc_value = 0;
- __pyx_exc_tb = 0;
- goto __pyx_L1_error;
- }
- }
- }
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_AddTraceback("twisted.python._epoll.call_epoll_wait", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = 0;
- __pyx_L0:;
- __Pyx_XDECREF(__pyx_v_results);
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":114
- * cdef int initialized
- *
- * def __init__(self, int size=1023): # <<<<<<<<<<<<<<
- * """
- * The constructor arguments are compatible with select.poll.__init__.
- */
-
-static int __pyx_pf_7twisted_6python_6_epoll_5epoll___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll___init__[] = "\n The constructor arguments are compatible with select.poll.__init__.\n ";
-struct wrapperbase __pyx_wrapperbase_7twisted_6python_6_epoll_5epoll___init__;
-static int __pyx_pf_7twisted_6python_6_epoll_5epoll___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- int __pyx_v_size;
- int __pyx_r;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__size,0};
- __Pyx_RefNannySetupContext("__init__");
- {
- PyObject* values[1] = {0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__size);
- if (value) { values[0] = value; kw_args--; }
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else {
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- }
- if (values[0]) {
- __pyx_v_size = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_size = ((int)1023);
- }
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return -1;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":118
- * The constructor arguments are compatible with select.poll.__init__.
- * """
- * self.fd = epoll_create(size) # <<<<<<<<<<<<<<
- * if self.fd == -1:
- * raise IOError(errno, strerror(errno))
- */
- ((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd = epoll_create(__pyx_v_size);
-
- /* "twisted/python/_epoll.pyx":119
- * """
- * self.fd = epoll_create(size)
- * if self.fd == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- * self.initialized = 1
- */
- __pyx_t_1 = (((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd == -1);
- if (__pyx_t_1) {
-
- /* "twisted/python/_epoll.pyx":120
- * self.fd = epoll_create(size)
- * if self.fd == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- * self.initialized = 1
- *
- */
- __pyx_t_2 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_t_3));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_t_3 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
- __Pyx_Raise(__pyx_t_3, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "twisted/python/_epoll.pyx":121
- * if self.fd == -1:
- * raise IOError(errno, strerror(errno))
- * self.initialized = 1 # <<<<<<<<<<<<<<
- *
- * def __dealloc__(self):
- */
- ((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->initialized = 1;
-
- __pyx_r = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = -1;
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":123
- * self.initialized = 1
- *
- * def __dealloc__(self): # <<<<<<<<<<<<<<
- * if self.initialized:
- * close(self.fd)
- */
-
-static void __pyx_pf_7twisted_6python_6_epoll_5epoll_1__dealloc__(PyObject *__pyx_v_self); /*proto*/
-static void __pyx_pf_7twisted_6python_6_epoll_5epoll_1__dealloc__(PyObject *__pyx_v_self) {
- __Pyx_RefNannyDeclarations
- __Pyx_RefNannySetupContext("__dealloc__");
-
- /* "twisted/python/_epoll.pyx":124
- *
- * def __dealloc__(self):
- * if self.initialized: # <<<<<<<<<<<<<<
- * close(self.fd)
- * self.initialized = 0
- */
- if (((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->initialized) {
-
- /* "twisted/python/_epoll.pyx":125
- * def __dealloc__(self):
- * if self.initialized:
- * close(self.fd) # <<<<<<<<<<<<<<
- * self.initialized = 0
- *
- */
- close(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd);
-
- /* "twisted/python/_epoll.pyx":126
- * if self.initialized:
- * close(self.fd)
- * self.initialized = 0 # <<<<<<<<<<<<<<
- *
- * def close(self):
- */
- ((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->initialized = 0;
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- __Pyx_RefNannyFinishContext();
-}
-
-/* "twisted/python/_epoll.pyx":128
- * self.initialized = 0
- *
- * def close(self): # <<<<<<<<<<<<<<
- * """
- * Close the epoll file descriptor.
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_2close(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_2close[] = "\n Close the epoll file descriptor.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_2close(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("close");
-
- /* "twisted/python/_epoll.pyx":132
- * Close the epoll file descriptor.
- * """
- * if self.initialized: # <<<<<<<<<<<<<<
- * if close(self.fd) == -1:
- * raise IOError(errno, strerror(errno))
- */
- if (((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->initialized) {
-
- /* "twisted/python/_epoll.pyx":133
- * """
- * if self.initialized:
- * if close(self.fd) == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- * self.initialized = 0
- */
- __pyx_t_1 = (close(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd) == -1);
- if (__pyx_t_1) {
-
- /* "twisted/python/_epoll.pyx":134
- * if self.initialized:
- * if close(self.fd) == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- * self.initialized = 0
- *
- */
- __pyx_t_2 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_t_3));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_t_3 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
- __Pyx_Raise(__pyx_t_3, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- /* "twisted/python/_epoll.pyx":135
- * if close(self.fd) == -1:
- * raise IOError(errno, strerror(errno))
- * self.initialized = 0 # <<<<<<<<<<<<<<
- *
- * def fileno(self):
- */
- ((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->initialized = 0;
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.close", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":137
- * self.initialized = 0
- *
- * def fileno(self): # <<<<<<<<<<<<<<
- * """
- * Return the epoll file descriptor number.
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_3fileno(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_3fileno[] = "\n Return the epoll file descriptor number.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_3fileno(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("fileno");
-
- /* "twisted/python/_epoll.pyx":141
- * Return the epoll file descriptor number.
- * """
- * return self.fd # <<<<<<<<<<<<<<
- *
- * def register(self, int fd, int events):
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_1 = PyInt_FromLong(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_r = __pyx_t_1;
- __pyx_t_1 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.fileno", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":143
- * return self.fd
- *
- * def register(self, int fd, int events): # <<<<<<<<<<<<<<
- * """
- * Add (register) a file descriptor to be monitored by self.
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_4register(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_4register[] = "\n Add (register) a file descriptor to be monitored by self.\n\n This method is compatible with select.epoll.register in Python 2.6.\n\n Wrap epoll_ctl(2).\n\n @type fd: C{int}\n @param fd: File descriptor to modify\n\n @type events: C{int}\n @param events: A bit set of IN, OUT, PRI, ERR, HUP, and ET.\n\n @raise IOError: Raised if the underlying epoll_ctl() call fails.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_4register(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- int __pyx_v_fd;
- int __pyx_v_events;
- int __pyx_v_result;
- struct epoll_event __pyx_v_evt;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_t_2;
- int __pyx_t_3;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__fd,&__pyx_n_s__events,0};
- __Pyx_RefNannySetupContext("register");
- {
- PyObject* values[2] = {0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fd);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__events);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("register", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "register") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- }
- __pyx_v_fd = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_fd == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_events = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_events == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("register", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll.register", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":161
- * cdef int result
- * cdef epoll_event evt
- * evt.events = events # <<<<<<<<<<<<<<
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_ADD, fd, &evt)
- */
- __pyx_v_evt.events = __pyx_v_events;
-
- /* "twisted/python/_epoll.pyx":162
- * cdef epoll_event evt
- * evt.events = events
- * evt.data.fd = fd # <<<<<<<<<<<<<<
- * result = epoll_ctl(self.fd, CTL_ADD, fd, &evt)
- * if result == -1:
- */
- __pyx_v_evt.data.fd = __pyx_v_fd;
-
- /* "twisted/python/_epoll.pyx":163
- * evt.events = events
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_ADD, fd, &evt) # <<<<<<<<<<<<<<
- * if result == -1:
- * raise IOError(errno, strerror(errno))
- */
- __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__CTL_ADD); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_v_result = epoll_ctl(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd, __pyx_t_2, __pyx_v_fd, (&__pyx_v_evt));
-
- /* "twisted/python/_epoll.pyx":164
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_ADD, fd, &evt)
- * if result == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- *
- */
- __pyx_t_3 = (__pyx_v_result == -1);
- if (__pyx_t_3) {
-
- /* "twisted/python/_epoll.pyx":165
- * result = epoll_ctl(self.fd, CTL_ADD, fd, &evt)
- * if result == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- *
- * def unregister(self, int fd):
- */
- __pyx_t_1 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_4 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_5));
- PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
- __Pyx_GIVEREF(__pyx_t_1);
- PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_t_4));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
- __pyx_t_1 = 0;
- __pyx_t_4 = 0;
- __pyx_t_4 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
- __Pyx_Raise(__pyx_t_4, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.register", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":167
- * raise IOError(errno, strerror(errno))
- *
- * def unregister(self, int fd): # <<<<<<<<<<<<<<
- * """
- * Remove (unregister) a file descriptor monitored by self.
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_5unregister(PyObject *__pyx_v_self, PyObject *__pyx_arg_fd); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_5unregister[] = "\n Remove (unregister) a file descriptor monitored by self.\n\n This method is compatible with select.epoll.unregister in Python 2.6.\n\n Wrap epoll_ctl(2).\n\n @type fd: C{int}\n @param fd: File descriptor to modify\n\n @raise IOError: Raised if the underlying epoll_ctl() call fails.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_5unregister(PyObject *__pyx_v_self, PyObject *__pyx_arg_fd) {
- int __pyx_v_fd;
- int __pyx_v_result;
- struct epoll_event __pyx_v_evt;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_t_2;
- int __pyx_t_3;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- __Pyx_RefNannySetupContext("unregister");
- assert(__pyx_arg_fd); {
- __pyx_v_fd = __Pyx_PyInt_AsInt(__pyx_arg_fd); if (unlikely((__pyx_v_fd == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll.unregister", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":183
- * cdef epoll_event evt
- * # We don't have to fill evt.events for CTL_DEL.
- * evt.data.fd = fd # <<<<<<<<<<<<<<
- * result = epoll_ctl(self.fd, CTL_DEL, fd, &evt)
- * if result == -1:
- */
- __pyx_v_evt.data.fd = __pyx_v_fd;
-
- /* "twisted/python/_epoll.pyx":184
- * # We don't have to fill evt.events for CTL_DEL.
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_DEL, fd, &evt) # <<<<<<<<<<<<<<
- * if result == -1:
- * raise IOError(errno, strerror(errno))
- */
- __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__CTL_DEL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_v_result = epoll_ctl(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd, __pyx_t_2, __pyx_v_fd, (&__pyx_v_evt));
-
- /* "twisted/python/_epoll.pyx":185
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_DEL, fd, &evt)
- * if result == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- *
- */
- __pyx_t_3 = (__pyx_v_result == -1);
- if (__pyx_t_3) {
-
- /* "twisted/python/_epoll.pyx":186
- * result = epoll_ctl(self.fd, CTL_DEL, fd, &evt)
- * if result == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- *
- * def modify(self, int fd, int events):
- */
- __pyx_t_1 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_4 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_5));
- PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
- __Pyx_GIVEREF(__pyx_t_1);
- PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_t_4));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
- __pyx_t_1 = 0;
- __pyx_t_4 = 0;
- __pyx_t_4 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
- __Pyx_Raise(__pyx_t_4, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L5;
- }
- __pyx_L5:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.unregister", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":188
- * raise IOError(errno, strerror(errno))
- *
- * def modify(self, int fd, int events): # <<<<<<<<<<<<<<
- * """
- * Modify the modified state of a file descriptor monitored by self.
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_6modify(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_6modify[] = "\n Modify the modified state of a file descriptor monitored by self.\n\n This method is compatible with select.epoll.modify in Python 2.6.\n\n Wrap epoll_ctl(2).\n\n @type fd: C{int}\n @param fd: File descriptor to modify\n\n @type events: C{int}\n @param events: A bit set of IN, OUT, PRI, ERR, HUP, and ET.\n\n @raise IOError: Raised if the underlying epoll_ctl() call fails.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_6modify(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- int __pyx_v_fd;
- int __pyx_v_events;
- int __pyx_v_result;
- struct epoll_event __pyx_v_evt;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_t_2;
- int __pyx_t_3;
- PyObject *__pyx_t_4 = NULL;
- PyObject *__pyx_t_5 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__fd,&__pyx_n_s__events,0};
- __Pyx_RefNannySetupContext("modify");
- {
- PyObject* values[2] = {0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fd);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__events);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("modify", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "modify") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- }
- __pyx_v_fd = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_fd == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_events = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_events == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("modify", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll.modify", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":206
- * cdef int result
- * cdef epoll_event evt
- * evt.events = events # <<<<<<<<<<<<<<
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_MOD, fd, &evt)
- */
- __pyx_v_evt.events = __pyx_v_events;
-
- /* "twisted/python/_epoll.pyx":207
- * cdef epoll_event evt
- * evt.events = events
- * evt.data.fd = fd # <<<<<<<<<<<<<<
- * result = epoll_ctl(self.fd, CTL_MOD, fd, &evt)
- * if result == -1:
- */
- __pyx_v_evt.data.fd = __pyx_v_fd;
-
- /* "twisted/python/_epoll.pyx":208
- * evt.events = events
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_MOD, fd, &evt) # <<<<<<<<<<<<<<
- * if result == -1:
- * raise IOError(errno, strerror(errno))
- */
- __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__CTL_MOD); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_v_result = epoll_ctl(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd, __pyx_t_2, __pyx_v_fd, (&__pyx_v_evt));
-
- /* "twisted/python/_epoll.pyx":209
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, CTL_MOD, fd, &evt)
- * if result == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- *
- */
- __pyx_t_3 = (__pyx_v_result == -1);
- if (__pyx_t_3) {
-
- /* "twisted/python/_epoll.pyx":210
- * result = epoll_ctl(self.fd, CTL_MOD, fd, &evt)
- * if result == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- *
- * def _control(self, int op, int fd, int events):
- */
- __pyx_t_1 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_4 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_5));
- PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
- __Pyx_GIVEREF(__pyx_t_1);
- PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_t_4));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
- __pyx_t_1 = 0;
- __pyx_t_4 = 0;
- __pyx_t_4 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_4);
- __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
- __Pyx_Raise(__pyx_t_4, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_XDECREF(__pyx_t_5);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.modify", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":212
- * raise IOError(errno, strerror(errno))
- *
- * def _control(self, int op, int fd, int events): # <<<<<<<<<<<<<<
- * """
- * Modify the monitored state of a particular file descriptor.
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_7_control(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_7_control[] = "\n Modify the monitored state of a particular file descriptor.\n \n Wrap epoll_ctl(2).\n\n @type op: C{int}\n @param op: One of CTL_ADD, CTL_DEL, or CTL_MOD\n\n @type fd: C{int}\n @param fd: File descriptor to modify\n\n @type events: C{int}\n @param events: A bit set of IN, OUT, PRI, ERR, HUP, and ET.\n\n @raise IOError: Raised if the underlying epoll_ctl() call fails.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_7_control(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- int __pyx_v_op;
- int __pyx_v_fd;
- int __pyx_v_events;
- int __pyx_v_result;
- struct epoll_event __pyx_v_evt;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- int __pyx_t_1;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- PyObject *__pyx_t_4 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__op,&__pyx_n_s__fd,&__pyx_n_s__events,0};
- __Pyx_RefNannySetupContext("_control");
- {
- PyObject* values[3] = {0,0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__op);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fd);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("_control", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- case 2:
- values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__events);
- if (likely(values[2])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("_control", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "_control") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
- }
- __pyx_v_op = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_op == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_fd = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_fd == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_events = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_events == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("_control", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll._control", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":231
- * cdef int result
- * cdef epoll_event evt
- * evt.events = events # <<<<<<<<<<<<<<
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, op, fd, &evt)
- */
- __pyx_v_evt.events = __pyx_v_events;
-
- /* "twisted/python/_epoll.pyx":232
- * cdef epoll_event evt
- * evt.events = events
- * evt.data.fd = fd # <<<<<<<<<<<<<<
- * result = epoll_ctl(self.fd, op, fd, &evt)
- * if result == -1:
- */
- __pyx_v_evt.data.fd = __pyx_v_fd;
-
- /* "twisted/python/_epoll.pyx":233
- * evt.events = events
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, op, fd, &evt) # <<<<<<<<<<<<<<
- * if result == -1:
- * raise IOError(errno, strerror(errno))
- */
- __pyx_v_result = epoll_ctl(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd, __pyx_v_op, __pyx_v_fd, (&__pyx_v_evt));
-
- /* "twisted/python/_epoll.pyx":234
- * evt.data.fd = fd
- * result = epoll_ctl(self.fd, op, fd, &evt)
- * if result == -1: # <<<<<<<<<<<<<<
- * raise IOError(errno, strerror(errno))
- *
- */
- __pyx_t_1 = (__pyx_v_result == -1);
- if (__pyx_t_1) {
-
- /* "twisted/python/_epoll.pyx":235
- * result = epoll_ctl(self.fd, op, fd, &evt)
- * if result == -1:
- * raise IOError(errno, strerror(errno)) # <<<<<<<<<<<<<<
- *
- * def wait(self, unsigned int maxevents, int timeout):
- */
- __pyx_t_2 = PyInt_FromLong(errno); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __pyx_t_3 = PyBytes_FromString(strerror(errno)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_3));
- __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_4));
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
- __Pyx_GIVEREF(__pyx_t_2);
- PyTuple_SET_ITEM(__pyx_t_4, 1, ((PyObject *)__pyx_t_3));
- __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
- __pyx_t_2 = 0;
- __pyx_t_3 = 0;
- __pyx_t_3 = PyObject_Call(__pyx_builtin_IOError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
- __Pyx_Raise(__pyx_t_3, 0, 0, 0);
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- goto __pyx_L6;
- }
- __pyx_L6:;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- __Pyx_XDECREF(__pyx_t_4);
- __Pyx_AddTraceback("twisted.python._epoll.epoll._control", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":237
- * raise IOError(errno, strerror(errno))
- *
- * def wait(self, unsigned int maxevents, int timeout): # <<<<<<<<<<<<<<
- * """
- * Wait for an I/O event, wrap epoll_wait(2).
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_8wait(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_8wait[] = "\n Wait for an I/O event, wrap epoll_wait(2).\n\n @type maxevents: C{int}\n @param maxevents: Maximum number of events returned.\n\n @type timeout: C{int}\n @param timeout: Maximum time in milliseconds waiting for events. 0\n makes it return immediately whereas -1 makes it wait indefinitely.\n \n @raise IOError: Raised if the underlying epoll_wait() call fails.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_8wait(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- unsigned int __pyx_v_maxevents;
- int __pyx_v_timeout;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__maxevents,&__pyx_n_s__timeout,0};
- __Pyx_RefNannySetupContext("wait");
- {
- PyObject* values[2] = {0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__maxevents);
- if (likely(values[0])) kw_args--;
- else goto __pyx_L5_argtuple_error;
- case 1:
- values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__timeout);
- if (likely(values[1])) kw_args--;
- else {
- __Pyx_RaiseArgtupleInvalid("wait", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "wait") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
- goto __pyx_L5_argtuple_error;
- } else {
- values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- }
- __pyx_v_maxevents = __Pyx_PyInt_AsUnsignedInt(values[0]); if (unlikely((__pyx_v_maxevents == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_v_timeout = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_timeout == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("wait", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll.wait", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":250
- * @raise IOError: Raised if the underlying epoll_wait() call fails.
- * """
- * return call_epoll_wait(self.fd, maxevents, timeout) # <<<<<<<<<<<<<<
- *
- * def poll(self, float timeout=-1, unsigned int maxevents=1024):
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_1 = __pyx_f_7twisted_6python_6_epoll_call_epoll_wait(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd, __pyx_v_maxevents, __pyx_v_timeout); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_r = __pyx_t_1;
- __pyx_t_1 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.wait", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-/* "twisted/python/_epoll.pyx":252
- * return call_epoll_wait(self.fd, maxevents, timeout)
- *
- * def poll(self, float timeout=-1, unsigned int maxevents=1024): # <<<<<<<<<<<<<<
- * """
- * Wait for an I/O event, wrap epoll_wait(2).
- */
-
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_9poll(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7twisted_6python_6_epoll_5epoll_9poll[] = "\n Wait for an I/O event, wrap epoll_wait(2).\n\n This method is compatible with select.epoll.poll in Python 2.6.\n\n @type maxevents: C{int}\n @param maxevents: Maximum number of events returned.\n\n @type timeout: C{int}\n @param timeout: Maximum time waiting for events. 0 makes it return\n immediately whereas -1 makes it wait indefinitely.\n \n @raise IOError: Raised if the underlying epoll_wait() call fails.\n ";
-static PyObject *__pyx_pf_7twisted_6python_6_epoll_5epoll_9poll(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- float __pyx_v_timeout;
- unsigned int __pyx_v_maxevents;
- PyObject *__pyx_r = NULL;
- __Pyx_RefNannyDeclarations
- PyObject *__pyx_t_1 = NULL;
- int __pyx_lineno = 0;
- const char *__pyx_filename = NULL;
- int __pyx_clineno = 0;
- static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__timeout,&__pyx_n_s__maxevents,0};
- __Pyx_RefNannySetupContext("poll");
- {
- PyObject* values[2] = {0,0};
- if (unlikely(__pyx_kwds)) {
- Py_ssize_t kw_args;
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- kw_args = PyDict_Size(__pyx_kwds);
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 0:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__timeout);
- if (value) { values[0] = value; kw_args--; }
- }
- case 1:
- if (kw_args > 0) {
- PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__maxevents);
- if (value) { values[1] = value; kw_args--; }
- }
- }
- if (unlikely(kw_args > 0)) {
- if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "poll") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- }
- } else {
- switch (PyTuple_GET_SIZE(__pyx_args)) {
- case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
- case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
- case 0: break;
- default: goto __pyx_L5_argtuple_error;
- }
- }
- if (values[0]) {
- __pyx_v_timeout = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_timeout == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_timeout = ((float)-1.0);
- }
- if (values[1]) {
- __pyx_v_maxevents = __Pyx_PyInt_AsUnsignedInt(values[1]); if (unlikely((__pyx_v_maxevents == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- } else {
- __pyx_v_maxevents = ((unsigned int)1024);
- }
- }
- goto __pyx_L4_argument_unpacking_done;
- __pyx_L5_argtuple_error:;
- __Pyx_RaiseArgtupleInvalid("poll", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
- __pyx_L3_error:;
- __Pyx_AddTraceback("twisted.python._epoll.epoll.poll", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __Pyx_RefNannyFinishContext();
- return NULL;
- __pyx_L4_argument_unpacking_done:;
-
- /* "twisted/python/_epoll.pyx":267
- * @raise IOError: Raised if the underlying epoll_wait() call fails.
- * """
- * return call_epoll_wait(self.fd, maxevents, <int>(timeout * 1000.0)) # <<<<<<<<<<<<<<
- *
- *
- */
- __Pyx_XDECREF(__pyx_r);
- __pyx_t_1 = __pyx_f_7twisted_6python_6_epoll_call_epoll_wait(((struct __pyx_obj_7twisted_6python_6_epoll_epoll *)__pyx_v_self)->fd, __pyx_v_maxevents, ((int)(__pyx_v_timeout * 1000.0))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_r = __pyx_t_1;
- __pyx_t_1 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_AddTraceback("twisted.python._epoll.epoll.poll", __pyx_clineno, __pyx_lineno, __pyx_filename);
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-static PyObject *__pyx_tp_new_7twisted_6python_6_epoll_epoll(PyTypeObject *t, PyObject *a, PyObject *k) {
- PyObject *o = (*t->tp_alloc)(t, 0);
- if (!o) return 0;
- return o;
-}
-
-static void __pyx_tp_dealloc_7twisted_6python_6_epoll_epoll(PyObject *o) {
- {
- PyObject *etype, *eval, *etb;
- PyErr_Fetch(&etype, &eval, &etb);
- ++Py_REFCNT(o);
- __pyx_pf_7twisted_6python_6_epoll_5epoll_1__dealloc__(o);
- if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
- --Py_REFCNT(o);
- PyErr_Restore(etype, eval, etb);
- }
- (*Py_TYPE(o)->tp_free)(o);
-}
-
-static PyMethodDef __pyx_methods_7twisted_6python_6_epoll_epoll[] = {
- {__Pyx_NAMESTR("close"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_2close, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_2close)},
- {__Pyx_NAMESTR("fileno"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_3fileno, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_3fileno)},
- {__Pyx_NAMESTR("register"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_4register, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_4register)},
- {__Pyx_NAMESTR("unregister"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_5unregister, METH_O, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_5unregister)},
- {__Pyx_NAMESTR("modify"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_6modify, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_6modify)},
- {__Pyx_NAMESTR("_control"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_7_control, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_7_control)},
- {__Pyx_NAMESTR("wait"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_8wait, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_8wait)},
- {__Pyx_NAMESTR("poll"), (PyCFunction)__pyx_pf_7twisted_6python_6_epoll_5epoll_9poll, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7twisted_6python_6_epoll_5epoll_9poll)},
- {0, 0, 0, 0}
-};
-
-static PyNumberMethods __pyx_tp_as_number_epoll = {
- 0, /*nb_add*/
- 0, /*nb_subtract*/
- 0, /*nb_multiply*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_divide*/
- #endif
- 0, /*nb_remainder*/
- 0, /*nb_divmod*/
- 0, /*nb_power*/
- 0, /*nb_negative*/
- 0, /*nb_positive*/
- 0, /*nb_absolute*/
- 0, /*nb_nonzero*/
- 0, /*nb_invert*/
- 0, /*nb_lshift*/
- 0, /*nb_rshift*/
- 0, /*nb_and*/
- 0, /*nb_xor*/
- 0, /*nb_or*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_coerce*/
- #endif
- 0, /*nb_int*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_long*/
- #else
- 0, /*reserved*/
- #endif
- 0, /*nb_float*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_oct*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_hex*/
- #endif
- 0, /*nb_inplace_add*/
- 0, /*nb_inplace_subtract*/
- 0, /*nb_inplace_multiply*/
- #if PY_MAJOR_VERSION < 3
- 0, /*nb_inplace_divide*/
- #endif
- 0, /*nb_inplace_remainder*/
- 0, /*nb_inplace_power*/
- 0, /*nb_inplace_lshift*/
- 0, /*nb_inplace_rshift*/
- 0, /*nb_inplace_and*/
- 0, /*nb_inplace_xor*/
- 0, /*nb_inplace_or*/
- 0, /*nb_floor_divide*/
- 0, /*nb_true_divide*/
- 0, /*nb_inplace_floor_divide*/
- 0, /*nb_inplace_true_divide*/
- #if PY_VERSION_HEX >= 0x02050000
- 0, /*nb_index*/
- #endif
-};
-
-static PySequenceMethods __pyx_tp_as_sequence_epoll = {
- 0, /*sq_length*/
- 0, /*sq_concat*/
- 0, /*sq_repeat*/
- 0, /*sq_item*/
- 0, /*sq_slice*/
- 0, /*sq_ass_item*/
- 0, /*sq_ass_slice*/
- 0, /*sq_contains*/
- 0, /*sq_inplace_concat*/
- 0, /*sq_inplace_repeat*/
-};
-
-static PyMappingMethods __pyx_tp_as_mapping_epoll = {
- 0, /*mp_length*/
- 0, /*mp_subscript*/
- 0, /*mp_ass_subscript*/
-};
-
-static PyBufferProcs __pyx_tp_as_buffer_epoll = {
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getreadbuffer*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getwritebuffer*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getsegcount*/
- #endif
- #if PY_MAJOR_VERSION < 3
- 0, /*bf_getcharbuffer*/
- #endif
- #if PY_VERSION_HEX >= 0x02060000
- 0, /*bf_getbuffer*/
- #endif
- #if PY_VERSION_HEX >= 0x02060000
- 0, /*bf_releasebuffer*/
- #endif
-};
-
-static PyTypeObject __pyx_type_7twisted_6python_6_epoll_epoll = {
- PyVarObject_HEAD_INIT(0, 0)
- __Pyx_NAMESTR("twisted.python._epoll.epoll"), /*tp_name*/
- sizeof(struct __pyx_obj_7twisted_6python_6_epoll_epoll), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- __pyx_tp_dealloc_7twisted_6python_6_epoll_epoll, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- #if PY_MAJOR_VERSION < 3
- 0, /*tp_compare*/
- #else
- 0, /*reserved*/
- #endif
- 0, /*tp_repr*/
- &__pyx_tp_as_number_epoll, /*tp_as_number*/
- &__pyx_tp_as_sequence_epoll, /*tp_as_sequence*/
- &__pyx_tp_as_mapping_epoll, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- &__pyx_tp_as_buffer_epoll, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
- __Pyx_DOCSTR("\n Represent a set of file descriptors being monitored for events.\n "), /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- __pyx_methods_7twisted_6python_6_epoll_epoll, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- __pyx_pf_7twisted_6python_6_epoll_5epoll___init__, /*tp_init*/
- 0, /*tp_alloc*/
- __pyx_tp_new_7twisted_6python_6_epoll_epoll, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
- 0, /*tp_bases*/
- 0, /*tp_mro*/
- 0, /*tp_cache*/
- 0, /*tp_subclasses*/
- 0, /*tp_weaklist*/
- 0, /*tp_del*/
- #if PY_VERSION_HEX >= 0x02060000
- 0, /*tp_version_tag*/
- #endif
-};
-
-static PyMethodDef __pyx_methods[] = {
- {0, 0, 0, 0}
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef __pyx_moduledef = {
- PyModuleDef_HEAD_INIT,
- __Pyx_NAMESTR("_epoll"),
- __Pyx_DOCSTR(__pyx_k_1), /* m_doc */
- -1, /* m_size */
- __pyx_methods /* m_methods */,
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL /* m_free */
-};
-#endif
-
-static __Pyx_StringTabEntry __pyx_string_tab[] = {
- {&__pyx_n_s__CTL_ADD, __pyx_k__CTL_ADD, sizeof(__pyx_k__CTL_ADD), 0, 0, 1, 1},
- {&__pyx_n_s__CTL_DEL, __pyx_k__CTL_DEL, sizeof(__pyx_k__CTL_DEL), 0, 0, 1, 1},
- {&__pyx_n_s__CTL_MOD, __pyx_k__CTL_MOD, sizeof(__pyx_k__CTL_MOD), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLERR, __pyx_k__EPOLLERR, sizeof(__pyx_k__EPOLLERR), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLET, __pyx_k__EPOLLET, sizeof(__pyx_k__EPOLLET), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLHUP, __pyx_k__EPOLLHUP, sizeof(__pyx_k__EPOLLHUP), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLIN, __pyx_k__EPOLLIN, sizeof(__pyx_k__EPOLLIN), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLMSG, __pyx_k__EPOLLMSG, sizeof(__pyx_k__EPOLLMSG), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLOUT, __pyx_k__EPOLLOUT, sizeof(__pyx_k__EPOLLOUT), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLPRI, __pyx_k__EPOLLPRI, sizeof(__pyx_k__EPOLLPRI), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLRDBAND, __pyx_k__EPOLLRDBAND, sizeof(__pyx_k__EPOLLRDBAND), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLRDNORM, __pyx_k__EPOLLRDNORM, sizeof(__pyx_k__EPOLLRDNORM), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLWRBAND, __pyx_k__EPOLLWRBAND, sizeof(__pyx_k__EPOLLWRBAND), 0, 0, 1, 1},
- {&__pyx_n_s__EPOLLWRNORM, __pyx_k__EPOLLWRNORM, sizeof(__pyx_k__EPOLLWRNORM), 0, 0, 1, 1},
- {&__pyx_n_s__ERR, __pyx_k__ERR, sizeof(__pyx_k__ERR), 0, 0, 1, 1},
- {&__pyx_n_s__ET, __pyx_k__ET, sizeof(__pyx_k__ET), 0, 0, 1, 1},
- {&__pyx_n_s__HUP, __pyx_k__HUP, sizeof(__pyx_k__HUP), 0, 0, 1, 1},
- {&__pyx_n_s__IN, __pyx_k__IN, sizeof(__pyx_k__IN), 0, 0, 1, 1},
- {&__pyx_n_s__IOError, __pyx_k__IOError, sizeof(__pyx_k__IOError), 0, 0, 1, 1},
- {&__pyx_n_s__MSG, __pyx_k__MSG, sizeof(__pyx_k__MSG), 0, 0, 1, 1},
- {&__pyx_n_s__OUT, __pyx_k__OUT, sizeof(__pyx_k__OUT), 0, 0, 1, 1},
- {&__pyx_n_s__PRI, __pyx_k__PRI, sizeof(__pyx_k__PRI), 0, 0, 1, 1},
- {&__pyx_n_s__RDBAND, __pyx_k__RDBAND, sizeof(__pyx_k__RDBAND), 0, 0, 1, 1},
- {&__pyx_n_s__RDNORM, __pyx_k__RDNORM, sizeof(__pyx_k__RDNORM), 0, 0, 1, 1},
- {&__pyx_n_s__WRBAND, __pyx_k__WRBAND, sizeof(__pyx_k__WRBAND), 0, 0, 1, 1},
- {&__pyx_n_s__WRNORM, __pyx_k__WRNORM, sizeof(__pyx_k__WRNORM), 0, 0, 1, 1},
- {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
- {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
- {&__pyx_n_s__events, __pyx_k__events, sizeof(__pyx_k__events), 0, 0, 1, 1},
- {&__pyx_n_s__fd, __pyx_k__fd, sizeof(__pyx_k__fd), 0, 0, 1, 1},
- {&__pyx_n_s__maxevents, __pyx_k__maxevents, sizeof(__pyx_k__maxevents), 0, 0, 1, 1},
- {&__pyx_n_s__op, __pyx_k__op, sizeof(__pyx_k__op), 0, 0, 1, 1},
- {&__pyx_n_s__size, __pyx_k__size, sizeof(__pyx_k__size), 0, 0, 1, 1},
- {&__pyx_n_s__timeout, __pyx_k__timeout, sizeof(__pyx_k__timeout), 0, 0, 1, 1},
- {0, 0, 0, 0, 0, 0, 0}
-};
-static int __Pyx_InitCachedBuiltins(void) {
- __pyx_builtin_IOError = __Pyx_GetName(__pyx_b, __pyx_n_s__IOError); if (!__pyx_builtin_IOError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- return 0;
- __pyx_L1_error:;
- return -1;
-}
-
-static int __Pyx_InitCachedConstants(void) {
- __Pyx_RefNannyDeclarations
- __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants");
- __Pyx_RefNannyFinishContext();
- return 0;
-}
-
-static int __Pyx_InitGlobals(void) {
- if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- return 0;
- __pyx_L1_error:;
- return -1;
-}
-
-#if PY_MAJOR_VERSION < 3
-PyMODINIT_FUNC init_epoll(void); /*proto*/
-PyMODINIT_FUNC init_epoll(void)
-#else
-PyMODINIT_FUNC PyInit__epoll(void); /*proto*/
-PyMODINIT_FUNC PyInit__epoll(void)
-#endif
-{
- PyObject *__pyx_t_1 = NULL;
- __Pyx_RefNannyDeclarations
- #if CYTHON_REFNANNY
- __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
- if (!__Pyx_RefNanny) {
- PyErr_Clear();
- __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
- if (!__Pyx_RefNanny)
- Py_FatalError("failed to import 'refnanny' module");
- }
- #endif
- __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__epoll(void)");
- if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- #ifdef __pyx_binding_PyCFunctionType_USED
- if (__pyx_binding_PyCFunctionType_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- #endif
- /*--- Library function declarations ---*/
- /*--- Threads initialization code ---*/
- #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
- #ifdef WITH_THREAD /* Python build with threading support? */
- PyEval_InitThreads();
- #endif
- #endif
- /*--- Module creation code ---*/
- #if PY_MAJOR_VERSION < 3
- __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_epoll"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_1), 0, PYTHON_API_VERSION);
- #else
- __pyx_m = PyModule_Create(&__pyx_moduledef);
- #endif
- if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- #if PY_MAJOR_VERSION < 3
- Py_INCREF(__pyx_m);
- #endif
- __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));
- if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- /*--- Initialize various global constants etc. ---*/
- if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- if (__pyx_module_is_main_twisted__python___epoll) {
- if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- }
- /*--- Builtin init code ---*/
- if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- /*--- Constants init code ---*/
- if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- /*--- Global init code ---*/
- /*--- Variable export code ---*/
- /*--- Function export code ---*/
- /*--- Type init code ---*/
- if (PyType_Ready(&__pyx_type_7twisted_6python_6_epoll_epoll) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- {
- PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&__pyx_type_7twisted_6python_6_epoll_epoll, "__init__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
- __pyx_wrapperbase_7twisted_6python_6_epoll_5epoll___init__ = *((PyWrapperDescrObject *)wrapper)->d_base;
- __pyx_wrapperbase_7twisted_6python_6_epoll_5epoll___init__.doc = __pyx_doc_7twisted_6python_6_epoll_5epoll___init__;
- ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7twisted_6python_6_epoll_5epoll___init__;
- }
- }
- if (__Pyx_SetAttrString(__pyx_m, "epoll", (PyObject *)&__pyx_type_7twisted_6python_6_epoll_epoll) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_ptype_7twisted_6python_6_epoll_epoll = &__pyx_type_7twisted_6python_6_epoll_epoll;
- /*--- Type import code ---*/
- /*--- Variable import code ---*/
- /*--- Function import code ---*/
- /*--- Execution code ---*/
-
- /* "twisted/python/_epoll.pyx":270
- *
- *
- * CTL_ADD = EPOLL_CTL_ADD # <<<<<<<<<<<<<<
- * CTL_DEL = EPOLL_CTL_DEL
- * CTL_MOD = EPOLL_CTL_MOD
- */
- __pyx_t_1 = PyInt_FromLong(EPOLL_CTL_ADD); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__CTL_ADD, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":271
- *
- * CTL_ADD = EPOLL_CTL_ADD
- * CTL_DEL = EPOLL_CTL_DEL # <<<<<<<<<<<<<<
- * CTL_MOD = EPOLL_CTL_MOD
- *
- */
- __pyx_t_1 = PyInt_FromLong(EPOLL_CTL_DEL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__CTL_DEL, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":272
- * CTL_ADD = EPOLL_CTL_ADD
- * CTL_DEL = EPOLL_CTL_DEL
- * CTL_MOD = EPOLL_CTL_MOD # <<<<<<<<<<<<<<
- *
- * IN = EPOLLIN = c_EPOLLIN
- */
- __pyx_t_1 = PyInt_FromLong(EPOLL_CTL_MOD); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__CTL_MOD, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":274
- * CTL_MOD = EPOLL_CTL_MOD
- *
- * IN = EPOLLIN = c_EPOLLIN # <<<<<<<<<<<<<<
- * OUT = EPOLLOUT = c_EPOLLOUT
- * PRI = EPOLLPRI = c_EPOLLPRI
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLIN); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__IN, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLIN); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLIN, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":275
- *
- * IN = EPOLLIN = c_EPOLLIN
- * OUT = EPOLLOUT = c_EPOLLOUT # <<<<<<<<<<<<<<
- * PRI = EPOLLPRI = c_EPOLLPRI
- * ERR = EPOLLERR = c_EPOLLERR
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLOUT); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__OUT, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLOUT); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLOUT, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":276
- * IN = EPOLLIN = c_EPOLLIN
- * OUT = EPOLLOUT = c_EPOLLOUT
- * PRI = EPOLLPRI = c_EPOLLPRI # <<<<<<<<<<<<<<
- * ERR = EPOLLERR = c_EPOLLERR
- * HUP = EPOLLHUP = c_EPOLLHUP
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLPRI); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__PRI, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLPRI); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLPRI, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":277
- * OUT = EPOLLOUT = c_EPOLLOUT
- * PRI = EPOLLPRI = c_EPOLLPRI
- * ERR = EPOLLERR = c_EPOLLERR # <<<<<<<<<<<<<<
- * HUP = EPOLLHUP = c_EPOLLHUP
- * ET = EPOLLET = c_EPOLLET
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLERR); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__ERR, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLERR); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLERR, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":278
- * PRI = EPOLLPRI = c_EPOLLPRI
- * ERR = EPOLLERR = c_EPOLLERR
- * HUP = EPOLLHUP = c_EPOLLHUP # <<<<<<<<<<<<<<
- * ET = EPOLLET = c_EPOLLET
- *
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLHUP); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__HUP, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLHUP); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLHUP, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":279
- * ERR = EPOLLERR = c_EPOLLERR
- * HUP = EPOLLHUP = c_EPOLLHUP
- * ET = EPOLLET = c_EPOLLET # <<<<<<<<<<<<<<
- *
- * RDNORM = EPOLLRDNORM = c_EPOLLRDNORM
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLET); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__ET, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLET); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLET, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":281
- * ET = EPOLLET = c_EPOLLET
- *
- * RDNORM = EPOLLRDNORM = c_EPOLLRDNORM # <<<<<<<<<<<<<<
- * RDBAND = EPOLLRDBAND = c_EPOLLRDBAND
- * WRNORM = EPOLLWRNORM = c_EPOLLWRNORM
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLRDNORM); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__RDNORM, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLRDNORM); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLRDNORM, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":282
- *
- * RDNORM = EPOLLRDNORM = c_EPOLLRDNORM
- * RDBAND = EPOLLRDBAND = c_EPOLLRDBAND # <<<<<<<<<<<<<<
- * WRNORM = EPOLLWRNORM = c_EPOLLWRNORM
- * WRBAND = EPOLLWRBAND = c_EPOLLWRBAND
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLRDBAND); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__RDBAND, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLRDBAND); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLRDBAND, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":283
- * RDNORM = EPOLLRDNORM = c_EPOLLRDNORM
- * RDBAND = EPOLLRDBAND = c_EPOLLRDBAND
- * WRNORM = EPOLLWRNORM = c_EPOLLWRNORM # <<<<<<<<<<<<<<
- * WRBAND = EPOLLWRBAND = c_EPOLLWRBAND
- * MSG = EPOLLMSG = c_EPOLLMSG
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLWRNORM); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__WRNORM, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLWRNORM); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLWRNORM, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":284
- * RDBAND = EPOLLRDBAND = c_EPOLLRDBAND
- * WRNORM = EPOLLWRNORM = c_EPOLLWRNORM
- * WRBAND = EPOLLWRBAND = c_EPOLLWRBAND # <<<<<<<<<<<<<<
- * MSG = EPOLLMSG = c_EPOLLMSG
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLWRBAND); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__WRBAND, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLWRBAND); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLWRBAND, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":285
- * WRNORM = EPOLLWRNORM = c_EPOLLWRNORM
- * WRBAND = EPOLLWRBAND = c_EPOLLWRBAND
- * MSG = EPOLLMSG = c_EPOLLMSG # <<<<<<<<<<<<<<
- */
- __pyx_t_1 = PyInt_FromLong(EPOLLMSG); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__MSG, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __pyx_t_1 = PyInt_FromLong(EPOLLMSG); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__EPOLLMSG, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/python/_epoll.pyx":1
- * # Copyright (c) Twisted Matrix Laboratories. # <<<<<<<<<<<<<<
- * # See LICENSE for details.
- *
- */
- __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_1));
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- if (__pyx_m) {
- __Pyx_AddTraceback("init twisted.python._epoll", __pyx_clineno, __pyx_lineno, __pyx_filename);
- Py_DECREF(__pyx_m); __pyx_m = 0;
- } else if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_ImportError, "init twisted.python._epoll");
- }
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- #if PY_MAJOR_VERSION < 3
- return;
- #else
- return __pyx_m;
- #endif
-}
-
-/* Runtime support code */
-
-#if CYTHON_REFNANNY
-static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
- PyObject *m = NULL, *p = NULL;
- void *r = NULL;
- m = PyImport_ImportModule((char *)modname);
- if (!m) goto end;
- p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
- if (!p) goto end;
- r = PyLong_AsVoidPtr(p);
-end:
- Py_XDECREF(p);
- Py_XDECREF(m);
- return (__Pyx_RefNannyAPIStruct *)r;
-}
-#endif /* CYTHON_REFNANNY */
-
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
- PyObject *result;
- result = PyObject_GetAttr(dict, name);
- if (!result) {
- if (dict != __pyx_b) {
- PyErr_Clear();
- result = PyObject_GetAttr(__pyx_b, name);
- }
- if (!result) {
- PyErr_SetObject(PyExc_NameError, name);
- }
- }
- return result;
-}
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
- PyObject *tmp_type, *tmp_value, *tmp_tb;
- PyThreadState *tstate = PyThreadState_GET();
-
- tmp_type = tstate->curexc_type;
- tmp_value = tstate->curexc_value;
- tmp_tb = tstate->curexc_traceback;
- tstate->curexc_type = type;
- tstate->curexc_value = value;
- tstate->curexc_traceback = tb;
- Py_XDECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
-}
-
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
- PyThreadState *tstate = PyThreadState_GET();
- *type = tstate->curexc_type;
- *value = tstate->curexc_value;
- *tb = tstate->curexc_traceback;
-
- tstate->curexc_type = 0;
- tstate->curexc_value = 0;
- tstate->curexc_traceback = 0;
-}
-
-
-#if PY_MAJOR_VERSION < 3
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
- /* cause is unused */
- Py_XINCREF(type);
- Py_XINCREF(value);
- Py_XINCREF(tb);
- /* First, check the traceback argument, replacing None with NULL. */
- if (tb == Py_None) {
- Py_DECREF(tb);
- tb = 0;
- }
- else if (tb != NULL && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto raise_error;
- }
- /* Next, replace a missing value with None */
- if (value == NULL) {
- value = Py_None;
- Py_INCREF(value);
- }
- #if PY_VERSION_HEX < 0x02050000
- if (!PyClass_Check(type))
- #else
- if (!PyType_Check(type))
- #endif
- {
- /* Raising an instance. The value should be a dummy. */
- if (value != Py_None) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto raise_error;
- }
- /* Normalize to raise <class>, <instance> */
- Py_DECREF(value);
- value = type;
- #if PY_VERSION_HEX < 0x02050000
- if (PyInstance_Check(type)) {
- type = (PyObject*) ((PyInstanceObject*)type)->in_class;
- Py_INCREF(type);
- }
- else {
- type = 0;
- PyErr_SetString(PyExc_TypeError,
- "raise: exception must be an old-style class or instance");
- goto raise_error;
- }
- #else
- type = (PyObject*) Py_TYPE(type);
- Py_INCREF(type);
- if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto raise_error;
- }
- #endif
- }
-
- __Pyx_ErrRestore(type, value, tb);
- return;
-raise_error:
- Py_XDECREF(value);
- Py_XDECREF(type);
- Py_XDECREF(tb);
- return;
-}
-
-#else /* Python 3+ */
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
- if (tb == Py_None) {
- tb = 0;
- } else if (tb && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto bad;
- }
- if (value == Py_None)
- value = 0;
-
- if (PyExceptionInstance_Check(type)) {
- if (value) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto bad;
- }
- value = type;
- type = (PyObject*) Py_TYPE(value);
- } else if (!PyExceptionClass_Check(type)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto bad;
- }
-
- if (cause) {
- PyObject *fixed_cause;
- if (PyExceptionClass_Check(cause)) {
- fixed_cause = PyObject_CallObject(cause, NULL);
- if (fixed_cause == NULL)
- goto bad;
- }
- else if (PyExceptionInstance_Check(cause)) {
- fixed_cause = cause;
- Py_INCREF(fixed_cause);
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "exception causes must derive from "
- "BaseException");
- goto bad;
- }
- if (!value) {
- value = PyObject_CallObject(type, NULL);
- }
- PyException_SetCause(value, fixed_cause);
- }
-
- PyErr_SetObject(type, value);
-
- if (tb) {
- PyThreadState *tstate = PyThreadState_GET();
- PyObject* tmp_tb = tstate->curexc_traceback;
- if (tb != tmp_tb) {
- Py_INCREF(tb);
- tstate->curexc_traceback = tb;
- Py_XDECREF(tmp_tb);
- }
- }
-
-bad:
- return;
-}
-#endif
-
-static void __Pyx_RaiseDoubleKeywordsError(
- const char* func_name,
- PyObject* kw_name)
-{
- PyErr_Format(PyExc_TypeError,
- #if PY_MAJOR_VERSION >= 3
- "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
- #else
- "%s() got multiple values for keyword argument '%s'", func_name,
- PyString_AS_STRING(kw_name));
- #endif
-}
-
-static int __Pyx_ParseOptionalKeywords(
- PyObject *kwds,
- PyObject **argnames[],
- PyObject *kwds2,
- PyObject *values[],
- Py_ssize_t num_pos_args,
- const char* function_name)
-{
- PyObject *key = 0, *value = 0;
- Py_ssize_t pos = 0;
- PyObject*** name;
- PyObject*** first_kw_arg = argnames + num_pos_args;
-
- while (PyDict_Next(kwds, &pos, &key, &value)) {
- name = first_kw_arg;
- while (*name && (**name != key)) name++;
- if (*name) {
- values[name-argnames] = value;
- } else {
- #if PY_MAJOR_VERSION < 3
- if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
- #else
- if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
- #endif
- goto invalid_keyword_type;
- } else {
- for (name = first_kw_arg; *name; name++) {
- #if PY_MAJOR_VERSION >= 3
- if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
- PyUnicode_Compare(**name, key) == 0) break;
- #else
- if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
- _PyString_Eq(**name, key)) break;
- #endif
- }
- if (*name) {
- values[name-argnames] = value;
- } else {
- /* unexpected keyword found */
- for (name=argnames; name != first_kw_arg; name++) {
- if (**name == key) goto arg_passed_twice;
- #if PY_MAJOR_VERSION >= 3
- if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
- PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
- #else
- if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
- _PyString_Eq(**name, key)) goto arg_passed_twice;
- #endif
- }
- if (kwds2) {
- if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
- } else {
- goto invalid_keyword;
- }
- }
- }
- }
- }
- return 0;
-arg_passed_twice:
- __Pyx_RaiseDoubleKeywordsError(function_name, **name);
- goto bad;
-invalid_keyword_type:
- PyErr_Format(PyExc_TypeError,
- "%s() keywords must be strings", function_name);
- goto bad;
-invalid_keyword:
- PyErr_Format(PyExc_TypeError,
- #if PY_MAJOR_VERSION < 3
- "%s() got an unexpected keyword argument '%s'",
- function_name, PyString_AsString(key));
- #else
- "%s() got an unexpected keyword argument '%U'",
- function_name, key);
- #endif
-bad:
- return -1;
-}
-
-static void __Pyx_RaiseArgtupleInvalid(
- const char* func_name,
- int exact,
- Py_ssize_t num_min,
- Py_ssize_t num_max,
- Py_ssize_t num_found)
-{
- Py_ssize_t num_expected;
- const char *more_or_less;
-
- if (num_found < num_min) {
- num_expected = num_min;
- more_or_less = "at least";
- } else {
- num_expected = num_max;
- more_or_less = "at most";
- }
- if (exact) {
- more_or_less = "exactly";
- }
- PyErr_Format(PyExc_TypeError,
- "%s() takes %s %"PY_FORMAT_SIZE_T"d positional argument%s (%"PY_FORMAT_SIZE_T"d given)",
- func_name, more_or_less, num_expected,
- (num_expected == 1) ? "" : "s", num_found);
-}
-
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
- const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned char" :
- "value too large to convert to unsigned char");
- }
- return (unsigned char)-1;
- }
- return (unsigned char)val;
- }
- return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
- const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned short" :
- "value too large to convert to unsigned short");
- }
- return (unsigned short)-1;
- }
- return (unsigned short)val;
- }
- return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
- const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned int" :
- "value too large to convert to unsigned int");
- }
- return (unsigned int)-1;
- }
- return (unsigned int)val;
- }
- return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
- const char neg_one = (char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to char" :
- "value too large to convert to char");
- }
- return (char)-1;
- }
- return (char)val;
- }
- return (char)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
- const short neg_one = (short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to short" :
- "value too large to convert to short");
- }
- return (short)-1;
- }
- return (short)val;
- }
- return (short)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
- const int neg_one = (int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to int" :
- "value too large to convert to int");
- }
- return (int)-1;
- }
- return (int)val;
- }
- return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
- const signed char neg_one = (signed char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed char" :
- "value too large to convert to signed char");
- }
- return (signed char)-1;
- }
- return (signed char)val;
- }
- return (signed char)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
- const signed short neg_one = (signed short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed short" :
- "value too large to convert to signed short");
- }
- return (signed short)-1;
- }
- return (signed short)val;
- }
- return (signed short)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
- const signed int neg_one = (signed int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed int" :
- "value too large to convert to signed int");
- }
- return (signed int)-1;
- }
- return (signed int)val;
- }
- return (signed int)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
- const int neg_one = (int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to int" :
- "value too large to convert to int");
- }
- return (int)-1;
- }
- return (int)val;
- }
- return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
- const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
- return (unsigned long)-1;
- }
- return (unsigned long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
- return (unsigned long)-1;
- }
- return (unsigned long)PyLong_AsUnsignedLong(x);
- } else {
- return (unsigned long)PyLong_AsLong(x);
- }
- } else {
- unsigned long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (unsigned long)-1;
- val = __Pyx_PyInt_AsUnsignedLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
- const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned PY_LONG_LONG");
- return (unsigned PY_LONG_LONG)-1;
- }
- return (unsigned PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned PY_LONG_LONG");
- return (unsigned PY_LONG_LONG)-1;
- }
- return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
- } else {
- return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
- }
- } else {
- unsigned PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (unsigned PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
- const long neg_one = (long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to long");
- return (long)-1;
- }
- return (long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to long");
- return (long)-1;
- }
- return (long)PyLong_AsUnsignedLong(x);
- } else {
- return (long)PyLong_AsLong(x);
- }
- } else {
- long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (long)-1;
- val = __Pyx_PyInt_AsLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
- const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to PY_LONG_LONG");
- return (PY_LONG_LONG)-1;
- }
- return (PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to PY_LONG_LONG");
- return (PY_LONG_LONG)-1;
- }
- return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
- } else {
- return (PY_LONG_LONG)PyLong_AsLongLong(x);
- }
- } else {
- PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
- const signed long neg_one = (signed long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed long");
- return (signed long)-1;
- }
- return (signed long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed long");
- return (signed long)-1;
- }
- return (signed long)PyLong_AsUnsignedLong(x);
- } else {
- return (signed long)PyLong_AsLong(x);
- }
- } else {
- signed long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (signed long)-1;
- val = __Pyx_PyInt_AsSignedLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
- const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed PY_LONG_LONG");
- return (signed PY_LONG_LONG)-1;
- }
- return (signed PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed PY_LONG_LONG");
- return (signed PY_LONG_LONG)-1;
- }
- return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
- } else {
- return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
- }
- } else {
- signed PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (signed PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsSignedLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static int __Pyx_check_binary_version(void) {
- char ctversion[4], rtversion[4];
- PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
- PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
- if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
- char message[200];
- PyOS_snprintf(message, sizeof(message),
- "compiletime version %s of module '%.100s' "
- "does not match runtime version %s",
- ctversion, __Pyx_MODULE_NAME, rtversion);
- #if PY_VERSION_HEX < 0x02050000
- return PyErr_Warn(NULL, message);
- #else
- return PyErr_WarnEx(NULL, message, 1);
- #endif
- }
- return 0;
-}
-
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-
-static void __Pyx_AddTraceback(const char *funcname, int __pyx_clineno,
- int __pyx_lineno, const char *__pyx_filename) {
- PyObject *py_srcfile = 0;
- PyObject *py_funcname = 0;
- PyObject *py_globals = 0;
- PyCodeObject *py_code = 0;
- PyFrameObject *py_frame = 0;
-
- #if PY_MAJOR_VERSION < 3
- py_srcfile = PyString_FromString(__pyx_filename);
- #else
- py_srcfile = PyUnicode_FromString(__pyx_filename);
- #endif
- if (!py_srcfile) goto bad;
- if (__pyx_clineno) {
- #if PY_MAJOR_VERSION < 3
- py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
- #else
- py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
- #endif
- }
- else {
- #if PY_MAJOR_VERSION < 3
- py_funcname = PyString_FromString(funcname);
- #else
- py_funcname = PyUnicode_FromString(funcname);
- #endif
- }
- if (!py_funcname) goto bad;
- py_globals = PyModule_GetDict(__pyx_m);
- if (!py_globals) goto bad;
- py_code = PyCode_New(
- 0, /*int argcount,*/
- #if PY_MAJOR_VERSION >= 3
- 0, /*int kwonlyargcount,*/
- #endif
- 0, /*int nlocals,*/
- 0, /*int stacksize,*/
- 0, /*int flags,*/
- __pyx_empty_bytes, /*PyObject *code,*/
- __pyx_empty_tuple, /*PyObject *consts,*/
- __pyx_empty_tuple, /*PyObject *names,*/
- __pyx_empty_tuple, /*PyObject *varnames,*/
- __pyx_empty_tuple, /*PyObject *freevars,*/
- __pyx_empty_tuple, /*PyObject *cellvars,*/
- py_srcfile, /*PyObject *filename,*/
- py_funcname, /*PyObject *name,*/
- __pyx_lineno, /*int firstlineno,*/
- __pyx_empty_bytes /*PyObject *lnotab*/
- );
- if (!py_code) goto bad;
- py_frame = PyFrame_New(
- PyThreadState_GET(), /*PyThreadState *tstate,*/
- py_code, /*PyCodeObject *code,*/
- py_globals, /*PyObject *globals,*/
- 0 /*PyObject *locals*/
- );
- if (!py_frame) goto bad;
- py_frame->f_lineno = __pyx_lineno;
- PyTraceBack_Here(py_frame);
-bad:
- Py_XDECREF(py_srcfile);
- Py_XDECREF(py_funcname);
- Py_XDECREF(py_code);
- Py_XDECREF(py_frame);
-}
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
- while (t->p) {
- #if PY_MAJOR_VERSION < 3
- if (t->is_unicode) {
- *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
- } else if (t->intern) {
- *t->p = PyString_InternFromString(t->s);
- } else {
- *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
- }
- #else /* Python 3+ has unicode identifiers */
- if (t->is_unicode | t->is_str) {
- if (t->intern) {
- *t->p = PyUnicode_InternFromString(t->s);
- } else if (t->encoding) {
- *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
- } else {
- *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
- }
- } else {
- *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
- }
- #endif
- if (!*t->p)
- return -1;
- ++t;
- }
- return 0;
-}
-
-/* Type Conversion Functions */
-
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
- int is_true = x == Py_True;
- if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
- else return PyObject_IsTrue(x);
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
- PyNumberMethods *m;
- const char *name = NULL;
- PyObject *res = NULL;
-#if PY_VERSION_HEX < 0x03000000
- if (PyInt_Check(x) || PyLong_Check(x))
-#else
- if (PyLong_Check(x))
-#endif
- return Py_INCREF(x), x;
- m = Py_TYPE(x)->tp_as_number;
-#if PY_VERSION_HEX < 0x03000000
- if (m && m->nb_int) {
- name = "int";
- res = PyNumber_Int(x);
- }
- else if (m && m->nb_long) {
- name = "long";
- res = PyNumber_Long(x);
- }
-#else
- if (m && m->nb_int) {
- name = "int";
- res = PyNumber_Long(x);
- }
-#endif
- if (res) {
-#if PY_VERSION_HEX < 0x03000000
- if (!PyInt_Check(res) && !PyLong_Check(res)) {
-#else
- if (!PyLong_Check(res)) {
-#endif
- PyErr_Format(PyExc_TypeError,
- "__%s__ returned non-%s (type %.200s)",
- name, name, Py_TYPE(res)->tp_name);
- Py_DECREF(res);
- return NULL;
- }
- }
- else if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "an integer is required");
- }
- return res;
-}
-
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
- Py_ssize_t ival;
- PyObject* x = PyNumber_Index(b);
- if (!x) return -1;
- ival = PyInt_AsSsize_t(x);
- Py_DECREF(x);
- return ival;
-}
-
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
-#if PY_VERSION_HEX < 0x02050000
- if (ival <= LONG_MAX)
- return PyInt_FromLong((long)ival);
- else {
- unsigned char *bytes = (unsigned char *) &ival;
- int one = 1; int little = (int)*(unsigned char*)&one;
- return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
- }
-#else
- return PyInt_FromSize_t(ival);
-#endif
-}
-
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
- unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
- if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
- return (size_t)-1;
- } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
- PyErr_SetString(PyExc_OverflowError,
- "value too large to convert to size_t");
- return (size_t)-1;
- }
- return (size_t)val;
-}
-
-
-#endif /* Py_PYTHON_H */
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.pyx b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.pyx
deleted file mode 100644
index b8d6aa7f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_epoll.pyx
+++ /dev/null
@@ -1,285 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Interface to epoll I/O event notification facility.
-"""
-
-# NOTE: The version of Pyrex you are using probably _does not work_ with
-# Python 2.5. If you need to recompile this file, _make sure you are using
-# a version of Pyrex which works with Python 2.5_. I am using 0.9.4.1 from
-# <http://codespeak.net/svn/lxml/pyrex/>. -exarkun
-
-cdef extern from "stdio.h":
- cdef extern void *malloc(int)
- cdef extern void free(void *)
- cdef extern int close(int)
-
-cdef extern from "errno.h":
- cdef extern int errno
- cdef extern char *strerror(int)
-
-cdef extern from "string.h":
- cdef extern void *memset(void* s, int c, int n)
-
-cdef extern from "stdint.h":
- ctypedef unsigned long uint32_t
- ctypedef unsigned long long uint64_t
-
-cdef extern from "sys/epoll.h":
-
- cdef enum:
- EPOLL_CTL_ADD = 1
- EPOLL_CTL_DEL = 2
- EPOLL_CTL_MOD = 3
-
- cdef enum EPOLL_EVENTS:
- c_EPOLLIN "EPOLLIN" = 0x001
- c_EPOLLPRI "EPOLLPRI" = 0x002
- c_EPOLLOUT "EPOLLOUT" = 0x004
- c_EPOLLRDNORM "EPOLLRDNORM" = 0x040
- c_EPOLLRDBAND "EPOLLRDBAND" = 0x080
- c_EPOLLWRNORM "EPOLLWRNORM" = 0x100
- c_EPOLLWRBAND "EPOLLWRBAND" = 0x200
- c_EPOLLMSG "EPOLLMSG" = 0x400
- c_EPOLLERR "EPOLLERR" = 0x008
- c_EPOLLHUP "EPOLLHUP" = 0x010
- c_EPOLLET "EPOLLET" = (1 << 31)
-
- ctypedef union epoll_data_t:
- void *ptr
- int fd
- uint32_t u32
- uint64_t u64
-
- cdef struct epoll_event:
- uint32_t events
- epoll_data_t data
-
- int epoll_create(int size)
- int epoll_ctl(int epfd, int op, int fd, epoll_event *event)
- int epoll_wait(int epfd, epoll_event *events, int maxevents, int timeout)
-
-cdef extern from "Python.h":
- ctypedef struct PyThreadState
- cdef extern PyThreadState *PyEval_SaveThread()
- cdef extern void PyEval_RestoreThread(PyThreadState*)
-
-cdef call_epoll_wait(int fd, unsigned int maxevents, int timeout_msec):
- """
- Wait for an I/O event, wrap epoll_wait(2).
-
- @type fd: C{int}
- @param fd: The epoll file descriptor number.
-
- @type maxevents: C{int}
- @param maxevents: Maximum number of events returned.
-
- @type timeout_msec: C{int}
- @param timeout_msec: Maximum time in milliseconds waiting for events. 0
- makes it return immediately whereas -1 makes it wait indefinitely.
-
- @raise IOError: Raised if the underlying epoll_wait() call fails.
- """
- cdef epoll_event *events
- cdef int result
- cdef int nbytes
- cdef PyThreadState *_save
-
- nbytes = sizeof(epoll_event) * maxevents
- events = <epoll_event*>malloc(nbytes)
- memset(events, 0, nbytes)
- try:
- _save = PyEval_SaveThread()
- result = epoll_wait(fd, events, maxevents, timeout_msec)
- PyEval_RestoreThread(_save)
-
- if result == -1:
- raise IOError(errno, strerror(errno))
- results = []
- for i from 0 <= i < result:
- results.append((events[i].data.fd, <int>events[i].events))
- return results
- finally:
- free(events)
-
-cdef class epoll:
- """
- Represent a set of file descriptors being monitored for events.
- """
-
- cdef int fd
- cdef int initialized
-
- def __init__(self, int size=1023):
- """
- The constructor arguments are compatible with select.poll.__init__.
- """
- self.fd = epoll_create(size)
- if self.fd == -1:
- raise IOError(errno, strerror(errno))
- self.initialized = 1
-
- def __dealloc__(self):
- if self.initialized:
- close(self.fd)
- self.initialized = 0
-
- def close(self):
- """
- Close the epoll file descriptor.
- """
- if self.initialized:
- if close(self.fd) == -1:
- raise IOError(errno, strerror(errno))
- self.initialized = 0
-
- def fileno(self):
- """
- Return the epoll file descriptor number.
- """
- return self.fd
-
- def register(self, int fd, int events):
- """
- Add (register) a file descriptor to be monitored by self.
-
- This method is compatible with select.epoll.register in Python 2.6.
-
- Wrap epoll_ctl(2).
-
- @type fd: C{int}
- @param fd: File descriptor to modify
-
- @type events: C{int}
- @param events: A bit set of IN, OUT, PRI, ERR, HUP, and ET.
-
- @raise IOError: Raised if the underlying epoll_ctl() call fails.
- """
- cdef int result
- cdef epoll_event evt
- evt.events = events
- evt.data.fd = fd
- result = epoll_ctl(self.fd, CTL_ADD, fd, &evt)
- if result == -1:
- raise IOError(errno, strerror(errno))
-
- def unregister(self, int fd):
- """
- Remove (unregister) a file descriptor monitored by self.
-
- This method is compatible with select.epoll.unregister in Python 2.6.
-
- Wrap epoll_ctl(2).
-
- @type fd: C{int}
- @param fd: File descriptor to modify
-
- @raise IOError: Raised if the underlying epoll_ctl() call fails.
- """
- cdef int result
- cdef epoll_event evt
- # We don't have to fill evt.events for CTL_DEL.
- evt.data.fd = fd
- result = epoll_ctl(self.fd, CTL_DEL, fd, &evt)
- if result == -1:
- raise IOError(errno, strerror(errno))
-
- def modify(self, int fd, int events):
- """
- Modify the modified state of a file descriptor monitored by self.
-
- This method is compatible with select.epoll.modify in Python 2.6.
-
- Wrap epoll_ctl(2).
-
- @type fd: C{int}
- @param fd: File descriptor to modify
-
- @type events: C{int}
- @param events: A bit set of IN, OUT, PRI, ERR, HUP, and ET.
-
- @raise IOError: Raised if the underlying epoll_ctl() call fails.
- """
- cdef int result
- cdef epoll_event evt
- evt.events = events
- evt.data.fd = fd
- result = epoll_ctl(self.fd, CTL_MOD, fd, &evt)
- if result == -1:
- raise IOError(errno, strerror(errno))
-
- def _control(self, int op, int fd, int events):
- """
- Modify the monitored state of a particular file descriptor.
-
- Wrap epoll_ctl(2).
-
- @type op: C{int}
- @param op: One of CTL_ADD, CTL_DEL, or CTL_MOD
-
- @type fd: C{int}
- @param fd: File descriptor to modify
-
- @type events: C{int}
- @param events: A bit set of IN, OUT, PRI, ERR, HUP, and ET.
-
- @raise IOError: Raised if the underlying epoll_ctl() call fails.
- """
- cdef int result
- cdef epoll_event evt
- evt.events = events
- evt.data.fd = fd
- result = epoll_ctl(self.fd, op, fd, &evt)
- if result == -1:
- raise IOError(errno, strerror(errno))
-
- def wait(self, unsigned int maxevents, int timeout):
- """
- Wait for an I/O event, wrap epoll_wait(2).
-
- @type maxevents: C{int}
- @param maxevents: Maximum number of events returned.
-
- @type timeout: C{int}
- @param timeout: Maximum time in milliseconds waiting for events. 0
- makes it return immediately whereas -1 makes it wait indefinitely.
-
- @raise IOError: Raised if the underlying epoll_wait() call fails.
- """
- return call_epoll_wait(self.fd, maxevents, timeout)
-
- def poll(self, float timeout=-1, unsigned int maxevents=1024):
- """
- Wait for an I/O event, wrap epoll_wait(2).
-
- This method is compatible with select.epoll.poll in Python 2.6.
-
- @type maxevents: C{int}
- @param maxevents: Maximum number of events returned.
-
- @type timeout: C{int}
- @param timeout: Maximum time waiting for events. 0 makes it return
- immediately whereas -1 makes it wait indefinitely.
-
- @raise IOError: Raised if the underlying epoll_wait() call fails.
- """
- return call_epoll_wait(self.fd, maxevents, <int>(timeout * 1000.0))
-
-
-CTL_ADD = EPOLL_CTL_ADD
-CTL_DEL = EPOLL_CTL_DEL
-CTL_MOD = EPOLL_CTL_MOD
-
-IN = EPOLLIN = c_EPOLLIN
-OUT = EPOLLOUT = c_EPOLLOUT
-PRI = EPOLLPRI = c_EPOLLPRI
-ERR = EPOLLERR = c_EPOLLERR
-HUP = EPOLLHUP = c_EPOLLHUP
-ET = EPOLLET = c_EPOLLET
-
-RDNORM = EPOLLRDNORM = c_EPOLLRDNORM
-RDBAND = EPOLLRDBAND = c_EPOLLRDBAND
-WRNORM = EPOLLWRNORM = c_EPOLLWRNORM
-WRBAND = EPOLLWRBAND = c_EPOLLWRBAND
-MSG = EPOLLMSG = c_EPOLLMSG
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.c
deleted file mode 100644
index 93500b52..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*****************************************************************************
-
- Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-
- This software is subject to the provisions of the Zope Public License,
- Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
- WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
- FOR A PARTICULAR PURPOSE
-
- ****************************************************************************/
-
-/*
- * This has been reported for inclusion in Python here: http://bugs.python.org/issue7333
- * Hopefully we may be able to remove this file in some years.
- */
-
-#include "Python.h"
-
-#if defined(__unix__) || defined(unix) || defined(__NetBSD__) || defined(__MACH__) /* Mac OS X */
-
-#include <grp.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-static PyObject *
-initgroups_initgroups(PyObject *self, PyObject *args)
-{
- char *username;
- unsigned int igid;
- gid_t gid;
-
- if (!PyArg_ParseTuple(args, "sI:initgroups", &username, &igid))
- return NULL;
-
- gid = igid;
-
- if (initgroups(username, gid) == -1)
- return PyErr_SetFromErrno(PyExc_OSError);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef InitgroupsMethods[] = {
- {"initgroups", initgroups_initgroups, METH_VARARGS},
- {NULL, NULL}
-};
-
-#else
-
-/* This module is empty on non-UNIX systems. */
-
-static PyMethodDef InitgroupsMethods[] = {
- {NULL, NULL}
-};
-
-#endif /* defined(__unix__) || defined(unix) */
-
-void
-init_initgroups(void)
-{
- Py_InitModule("_initgroups", InitgroupsMethods);
-}
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.py
deleted file mode 100755
index 8a0048fa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'_initgroups.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.so b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.so
deleted file mode 100755
index 3bf026da..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_initgroups.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_inotify.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_inotify.py
deleted file mode 100755
index b4692baa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_inotify.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- test-case-name: twisted.internet.test.test_inotify -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Very low-level ctypes-based interface to Linux inotify(7).
-
-ctypes and a version of libc which supports inotify system calls are
-required.
-"""
-
-import ctypes
-import ctypes.util
-
-
-
-class INotifyError(Exception):
- """
- Unify all the possible exceptions that can be raised by the INotify API.
- """
-
-
-
-def init():
- """
- Create an inotify instance and return the associated file descriptor.
- """
- fd = libc.inotify_init()
- if fd < 0:
- raise INotifyError("INotify initialization error.")
- return fd
-
-
-
-def add(fd, path, mask):
- """
- Add a watch for the given path to the inotify file descriptor, and return
- the watch descriptor.
- """
- wd = libc.inotify_add_watch(fd, path, mask)
- if wd < 0:
- raise INotifyError("Failed to add watch on '%r' - (%r)" % (path, wd))
- return wd
-
-
-
-def remove(fd, wd):
- """
- Remove the given watch descriptor from the inotify file descriptor.
- """
- # When inotify_rm_watch returns -1 there's an error:
- # The errno for this call can be either one of the following:
- # EBADF: fd is not a valid file descriptor.
- # EINVAL: The watch descriptor wd is not valid; or fd is
- # not an inotify file descriptor.
- #
- # if we can't access the errno here we cannot even raise
- # an exception and we need to ignore the problem, one of
- # the most common cases is when you remove a directory from
- # the filesystem and that directory is observed. When inotify
- # tries to call inotify_rm_watch with a non existing directory
- # either of the 2 errors might come up because the files inside
- # it might have events generated way before they were handled.
- # Unfortunately only ctypes in Python 2.6 supports accessing errno:
- # http://bugs.python.org/issue1798 and in order to solve
- # the problem for previous versions we need to introduce
- # code that is quite complex:
- # http://stackoverflow.com/questions/661017/access-to-errno-from-python
- #
- # See #4310 for future resolution of this issue.
- libc.inotify_rm_watch(fd, wd)
-
-
-
-def initializeModule(libc):
- """
- Intialize the module, checking if the expected APIs exist and setting the
- argtypes and restype for for C{inotify_init}, C{inotify_add_watch}, and
- C{inotify_rm_watch}.
- """
- for function in ("inotify_add_watch", "inotify_init", "inotify_rm_watch"):
- if getattr(libc, function, None) is None:
- raise ImportError("libc6 2.4 or higher needed")
- libc.inotify_init.argtypes = []
- libc.inotify_init.restype = ctypes.c_int
-
- libc.inotify_rm_watch.argtypes = [
- ctypes.c_int, ctypes.c_int]
- libc.inotify_rm_watch.restype = ctypes.c_int
-
- libc.inotify_add_watch.argtypes = [
- ctypes.c_int, ctypes.c_char_p, ctypes.c_uint32]
- libc.inotify_add_watch.restype = ctypes.c_int
-
-
-
-name = ctypes.util.find_library('c')
-if not name:
- raise ImportError("Can't find C library.")
-libc = ctypes.cdll.LoadLibrary(name)
-initializeModule(libc)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_release.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_release.py
deleted file mode 100755
index 78d84f6a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_release.py
+++ /dev/null
@@ -1,1371 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_release -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Twisted's automated release system.
-
-This module is only for use within Twisted's release system. If you are anyone
-else, do not use it. The interface and behaviour will change without notice.
-
-Only Linux is supported by this code. It should not be used by any tools
-which must run on multiple platforms (eg the setup.py script).
-"""
-
-import textwrap
-from datetime import date
-import re
-import sys
-import os
-from tempfile import mkdtemp
-import tarfile
-
-from subprocess import PIPE, STDOUT, Popen
-
-from twisted.python.versions import Version
-from twisted.python.filepath import FilePath
-from twisted.python.dist import twisted_subprojects
-from twisted.python.compat import execfile
-
-# This import is an example of why you shouldn't use this module unless you're
-# radix
-try:
- from twisted.lore.scripts import lore
-except ImportError:
- pass
-
-# The offset between a year and the corresponding major version number.
-VERSION_OFFSET = 2000
-
-
-def runCommand(args):
- """
- Execute a vector of arguments.
-
- @type args: C{list} of C{str}
- @param args: A list of arguments, the first of which will be used as the
- executable to run.
-
- @rtype: C{str}
- @return: All of the standard output.
-
- @raise CommandFailed: when the program exited with a non-0 exit code.
- """
- process = Popen(args, stdout=PIPE, stderr=STDOUT)
- stdout = process.stdout.read()
- exitCode = process.wait()
- if exitCode < 0:
- raise CommandFailed(None, -exitCode, stdout)
- elif exitCode > 0:
- raise CommandFailed(exitCode, None, stdout)
- return stdout
-
-
-class CommandFailed(Exception):
- """
- Raised when a child process exits unsuccessfully.
-
- @type exitStatus: C{int}
- @ivar exitStatus: The exit status for the child process.
-
- @type exitSignal: C{int}
- @ivar exitSignal: The exit signal for the child process.
-
- @type output: C{str}
- @ivar output: The bytes read from stdout and stderr of the child process.
- """
- def __init__(self, exitStatus, exitSignal, output):
- Exception.__init__(self, exitStatus, exitSignal, output)
- self.exitStatus = exitStatus
- self.exitSignal = exitSignal
- self.output = output
-
-
-
-def _changeVersionInFile(old, new, filename):
- """
- Replace the C{old} version number with the C{new} one in the given
- C{filename}.
- """
- replaceInFile(filename, {old.base(): new.base()})
-
-
-
-def getNextVersion(version, now=None):
- """
- Calculate the version number for a new release of Twisted based on
- the previous version number.
-
- @param version: The previous version number.
- @param now: (optional) The current date.
- """
- # XXX: This has no way of incrementing the patch number. Currently, we
- # don't need it. See bug 2915. Jonathan Lange, 2007-11-20.
- if now is None:
- now = date.today()
- major = now.year - VERSION_OFFSET
- if major != version.major:
- minor = 0
- else:
- minor = version.minor + 1
- return Version(version.package, major, minor, 0)
-
-
-def changeAllProjectVersions(root, versionTemplate, today=None):
- """
- Change the version of all projects (including core and all subprojects).
-
- If the current version of a project is pre-release, then also change the
- versions in the current NEWS entries for that project.
-
- @type root: L{FilePath}
- @param root: The root of the Twisted source tree.
- @type versionTemplate: L{Version}
- @param versionTemplate: The version of all projects. The name will be
- replaced for each respective project.
- @type today: C{str}
- @param today: A YYYY-MM-DD formatted string. If not provided, defaults to
- the current day, according to the system clock.
- """
- if not today:
- today = date.today().strftime('%Y-%m-%d')
- for project in findTwistedProjects(root):
- if project.directory.basename() == "twisted":
- packageName = "twisted"
- else:
- packageName = "twisted." + project.directory.basename()
- oldVersion = project.getVersion()
- newVersion = Version(packageName, versionTemplate.major,
- versionTemplate.minor, versionTemplate.micro,
- prerelease=versionTemplate.prerelease)
-
- if oldVersion.prerelease:
- builder = NewsBuilder()
- builder._changeNewsVersion(
- root.child("NEWS"), builder._getNewsName(project),
- oldVersion, newVersion, today)
- builder._changeNewsVersion(
- project.directory.child("topfiles").child("NEWS"),
- builder._getNewsName(project), oldVersion, newVersion,
- today)
-
- # The placement of the top-level README with respect to other files (eg
- # _version.py) is sufficiently different from the others that we just
- # have to handle it specially.
- if packageName == "twisted":
- _changeVersionInFile(
- oldVersion, newVersion, root.child('README').path)
-
- project.updateVersion(newVersion)
-
-
-
-
-class Project(object):
- """
- A representation of a project that has a version.
-
- @ivar directory: A L{twisted.python.filepath.FilePath} pointing to the base
- directory of a Twisted-style Python package. The package should contain
- a C{_version.py} file and a C{topfiles} directory that contains a
- C{README} file.
- """
-
- def __init__(self, directory):
- self.directory = directory
-
-
- def __repr__(self):
- return '%s(%r)' % (
- self.__class__.__name__, self.directory)
-
-
- def getVersion(self):
- """
- @return: A L{Version} specifying the version number of the project
- based on live python modules.
- """
- namespace = {}
- execfile(self.directory.child("_version.py").path, namespace)
- return namespace["version"]
-
-
- def updateVersion(self, version):
- """
- Replace the existing version numbers in _version.py and README files
- with the specified version.
- """
- oldVersion = self.getVersion()
- replaceProjectVersion(self.directory.child("_version.py").path,
- version)
- _changeVersionInFile(
- oldVersion, version,
- self.directory.child("topfiles").child("README").path)
-
-
-
-def findTwistedProjects(baseDirectory):
- """
- Find all Twisted-style projects beneath a base directory.
-
- @param baseDirectory: A L{twisted.python.filepath.FilePath} to look inside.
- @return: A list of L{Project}.
- """
- projects = []
- for filePath in baseDirectory.walk():
- if filePath.basename() == 'topfiles':
- projectDirectory = filePath.parent()
- projects.append(Project(projectDirectory))
- return projects
-
-
-
-def updateTwistedVersionInformation(baseDirectory, now):
- """
- Update the version information for Twisted and all subprojects to the
- date-based version number.
-
- @param baseDirectory: Where to look for Twisted. If None, the function
- infers the information from C{twisted.__file__}.
- @param now: The current date (as L{datetime.date}). If None, it defaults
- to today.
- """
- for project in findTwistedProjects(baseDirectory):
- project.updateVersion(getNextVersion(project.getVersion(), now=now))
-
-
-def generateVersionFileData(version):
- """
- Generate the data to be placed into a _version.py file.
-
- @param version: A version object.
- """
- if version.prerelease is not None:
- prerelease = ", prerelease=%r" % (version.prerelease,)
- else:
- prerelease = ""
- data = '''\
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version(%r, %s, %s, %s%s)
-''' % (version.package, version.major, version.minor, version.micro, prerelease)
- return data
-
-
-def replaceProjectVersion(filename, newversion):
- """
- Write version specification code into the given filename, which
- sets the version to the given version number.
-
- @param filename: A filename which is most likely a "_version.py"
- under some Twisted project.
- @param newversion: A version object.
- """
- # XXX - this should be moved to Project and renamed to writeVersionFile.
- # jml, 2007-11-15.
- f = open(filename, 'w')
- f.write(generateVersionFileData(newversion))
- f.close()
-
-
-
-def replaceInFile(filename, oldToNew):
- """
- I replace the text `oldstr' with `newstr' in `filename' using science.
- """
- os.rename(filename, filename+'.bak')
- f = open(filename+'.bak')
- d = f.read()
- f.close()
- for k,v in oldToNew.items():
- d = d.replace(k, v)
- f = open(filename + '.new', 'w')
- f.write(d)
- f.close()
- os.rename(filename+'.new', filename)
- os.unlink(filename+'.bak')
-
-
-
-class NoDocumentsFound(Exception):
- """
- Raised when no input documents are found.
- """
-
-
-
-class LoreBuilderMixin(object):
- """
- Base class for builders which invoke lore.
- """
- def lore(self, arguments):
- """
- Run lore with the given arguments.
-
- @param arguments: A C{list} of C{str} giving command line arguments to
- lore which should be used.
- """
- options = lore.Options()
- options.parseOptions(["--null"] + arguments)
- lore.runGivenOptions(options)
-
-
-
-class DocBuilder(LoreBuilderMixin):
- """
- Generate HTML documentation for projects.
- """
-
- def build(self, version, resourceDir, docDir, template, apiBaseURL=None,
- deleteInput=False):
- """
- Build the documentation in C{docDir} with Lore.
-
- Input files ending in .xhtml will be considered. Output will written as
- .html files.
-
- @param version: the version of the documentation to pass to lore.
- @type version: C{str}
-
- @param resourceDir: The directory which contains the toplevel index and
- stylesheet file for this section of documentation.
- @type resourceDir: L{twisted.python.filepath.FilePath}
-
- @param docDir: The directory of the documentation.
- @type docDir: L{twisted.python.filepath.FilePath}
-
- @param template: The template used to generate the documentation.
- @type template: L{twisted.python.filepath.FilePath}
-
- @type apiBaseURL: C{str} or C{NoneType}
- @param apiBaseURL: A format string which will be interpolated with the
- fully-qualified Python name for each API link. For example, to
- generate the Twisted 8.0.0 documentation, pass
- C{"http://twistedmatrix.com/documents/8.0.0/api/%s.html"}.
-
- @param deleteInput: If True, the input documents will be deleted after
- their output is generated.
- @type deleteInput: C{bool}
-
- @raise NoDocumentsFound: When there are no .xhtml files in the given
- C{docDir}.
- """
- linkrel = self.getLinkrel(resourceDir, docDir)
- inputFiles = docDir.globChildren("*.xhtml")
- filenames = [x.path for x in inputFiles]
- if not filenames:
- raise NoDocumentsFound("No input documents found in %s" % (docDir,))
- if apiBaseURL is not None:
- arguments = ["--config", "baseurl=" + apiBaseURL]
- else:
- arguments = []
- arguments.extend(["--config", "template=%s" % (template.path,),
- "--config", "ext=.html",
- "--config", "version=%s" % (version,),
- "--linkrel", linkrel] + filenames)
- self.lore(arguments)
- if deleteInput:
- for inputFile in inputFiles:
- inputFile.remove()
-
-
- def getLinkrel(self, resourceDir, docDir):
- """
- Calculate a value appropriate for Lore's --linkrel option.
-
- Lore's --linkrel option defines how to 'find' documents that are
- linked to from TEMPLATE files (NOT document bodies). That is, it's a
- prefix for links ('a' and 'link') in the template.
-
- @param resourceDir: The directory which contains the toplevel index and
- stylesheet file for this section of documentation.
- @type resourceDir: L{twisted.python.filepath.FilePath}
-
- @param docDir: The directory containing documents that must link to
- C{resourceDir}.
- @type docDir: L{twisted.python.filepath.FilePath}
- """
- if resourceDir != docDir:
- return '/'.join(filePathDelta(docDir, resourceDir)) + "/"
- else:
- return ""
-
-
-
-class ManBuilder(LoreBuilderMixin):
- """
- Generate man pages of the different existing scripts.
- """
-
- def build(self, manDir):
- """
- Generate Lore input files from the man pages in C{manDir}.
-
- Input files ending in .1 will be considered. Output will written as
- -man.xhtml files.
-
- @param manDir: The directory of the man pages.
- @type manDir: L{twisted.python.filepath.FilePath}
-
- @raise NoDocumentsFound: When there are no .1 files in the given
- C{manDir}.
- """
- inputFiles = manDir.globChildren("*.1")
- filenames = [x.path for x in inputFiles]
- if not filenames:
- raise NoDocumentsFound("No manual pages found in %s" % (manDir,))
- arguments = ["--input", "man",
- "--output", "lore",
- "--config", "ext=-man.xhtml"] + filenames
- self.lore(arguments)
-
-
-
-class APIBuilder(object):
- """
- Generate API documentation from source files using
- U{pydoctor<http://codespeak.net/~mwh/pydoctor/>}. This requires
- pydoctor to be installed and usable (which means you won't be able to
- use it with Python 2.3).
- """
- def build(self, projectName, projectURL, sourceURL, packagePath,
- outputPath):
- """
- Call pydoctor's entry point with options which will generate HTML
- documentation for the specified package's API.
-
- @type projectName: C{str}
- @param projectName: The name of the package for which to generate
- documentation.
-
- @type projectURL: C{str}
- @param projectURL: The location (probably an HTTP URL) of the project
- on the web.
-
- @type sourceURL: C{str}
- @param sourceURL: The location (probably an HTTP URL) of the root of
- the source browser for the project.
-
- @type packagePath: L{FilePath}
- @param packagePath: The path to the top-level of the package named by
- C{projectName}.
-
- @type outputPath: L{FilePath}
- @param outputPath: An existing directory to which the generated API
- documentation will be written.
- """
- from pydoctor.driver import main
- main(
- ["--project-name", projectName,
- "--project-url", projectURL,
- "--system-class", "pydoctor.twistedmodel.TwistedSystem",
- "--project-base-dir", packagePath.parent().path,
- "--html-viewsource-base", sourceURL,
- "--add-package", packagePath.path,
- "--html-output", outputPath.path,
- "--html-write-function-pages", "--quiet", "--make-html"])
-
-
-
-class BookBuilder(LoreBuilderMixin):
- """
- Generate the LaTeX and PDF documentation.
-
- The book is built by assembling a number of LaTeX documents. Only the
- overall document which describes how to assemble the documents is stored
- in LaTeX in the source. The rest of the documentation is generated from
- Lore input files. These are primarily XHTML files (of the particular
- Lore subset), but man pages are stored in GROFF format. BookBuilder
- expects all of its input to be Lore XHTML format, so L{ManBuilder}
- should be invoked first if the man pages are to be included in the
- result (this is determined by the book LaTeX definition file).
- Therefore, a sample usage of BookBuilder may look something like this::
-
- man = ManBuilder()
- man.build(FilePath("doc/core/man"))
- book = BookBuilder()
- book.build(
- FilePath('doc/core/howto'),
- [FilePath('doc/core/howto'), FilePath('doc/core/howto/tutorial'),
- FilePath('doc/core/man'), FilePath('doc/core/specifications')],
- FilePath('doc/core/howto/book.tex'), FilePath('/tmp/book.pdf'))
- """
- def run(self, command):
- """
- Execute a command in a child process and return the output.
-
- @type command: C{str}
- @param command: The shell command to run.
-
- @raise CommandFailed: If the child process exits with an error.
- """
- return runCommand(command)
-
-
- def buildTeX(self, howtoDir):
- """
- Build LaTeX files for lore input files in the given directory.
-
- Input files ending in .xhtml will be considered. Output will written as
- .tex files.
-
- @type howtoDir: L{FilePath}
- @param howtoDir: A directory containing lore input files.
-
- @raise ValueError: If C{howtoDir} does not exist.
- """
- if not howtoDir.exists():
- raise ValueError("%r does not exist." % (howtoDir.path,))
- self.lore(
- ["--output", "latex",
- "--config", "section"] +
- [child.path for child in howtoDir.globChildren("*.xhtml")])
-
-
- def buildPDF(self, bookPath, inputDirectory, outputPath):
- """
- Build a PDF from the given a LaTeX book document.
-
- @type bookPath: L{FilePath}
- @param bookPath: The location of a LaTeX document defining a book.
-
- @type inputDirectory: L{FilePath}
- @param inputDirectory: The directory which the inputs of the book are
- relative to.
-
- @type outputPath: L{FilePath}
- @param outputPath: The location to which to write the resulting book.
- """
- if not bookPath.basename().endswith(".tex"):
- raise ValueError("Book filename must end with .tex")
-
- workPath = FilePath(mkdtemp())
- try:
- startDir = os.getcwd()
- try:
- os.chdir(inputDirectory.path)
-
- texToDVI = [
- "latex", "-interaction=nonstopmode",
- "-output-directory=" + workPath.path,
- bookPath.path]
-
- # What I tell you three times is true!
- # The first two invocations of latex on the book file allows it
- # correctly create page numbers for in-text references. Why this is
- # the case, I could not tell you. -exarkun
- for i in range(3):
- self.run(texToDVI)
-
- bookBaseWithoutExtension = bookPath.basename()[:-4]
- dviPath = workPath.child(bookBaseWithoutExtension + ".dvi")
- psPath = workPath.child(bookBaseWithoutExtension + ".ps")
- pdfPath = workPath.child(bookBaseWithoutExtension + ".pdf")
- self.run([
- "dvips", "-o", psPath.path, "-t", "letter", "-Ppdf",
- dviPath.path])
- self.run(["ps2pdf13", psPath.path, pdfPath.path])
- pdfPath.moveTo(outputPath)
- workPath.remove()
- finally:
- os.chdir(startDir)
- except:
- workPath.moveTo(bookPath.parent().child(workPath.basename()))
- raise
-
-
- def build(self, baseDirectory, inputDirectories, bookPath, outputPath):
- """
- Build a PDF book from the given TeX book definition and directories
- containing lore inputs.
-
- @type baseDirectory: L{FilePath}
- @param baseDirectory: The directory which the inputs of the book are
- relative to.
-
- @type inputDirectories: C{list} of L{FilePath}
- @param inputDirectories: The paths which contain lore inputs to be
- converted to LaTeX.
-
- @type bookPath: L{FilePath}
- @param bookPath: The location of a LaTeX document defining a book.
-
- @type outputPath: L{FilePath}
- @param outputPath: The location to which to write the resulting book.
- """
- for inputDir in inputDirectories:
- self.buildTeX(inputDir)
- self.buildPDF(bookPath, baseDirectory, outputPath)
- for inputDirectory in inputDirectories:
- for child in inputDirectory.children():
- if child.splitext()[1] == ".tex" and child != bookPath:
- child.remove()
-
-
-
-class NewsBuilder(object):
- """
- Generate the new section of a NEWS file.
-
- The C{_FEATURE}, C{_BUGFIX}, C{_DOC}, C{_REMOVAL}, and C{_MISC}
- attributes of this class are symbolic names for the news entry types
- which are supported. Conveniently, they each also take on the value of
- the file name extension which indicates a news entry of that type.
-
- @cvar _headings: A C{dict} mapping one of the news entry types to the
- heading to write out for that type of news entry.
-
- @cvar _NO_CHANGES: A C{str} giving the text which appears when there are
- no significant changes in a release.
-
- @cvar _TICKET_HINT: A C{str} giving the text which appears at the top of
- each news file and which should be kept at the top, not shifted down
- with all the other content. Put another way, this is the text after
- which the new news text is inserted.
- """
-
- _FEATURE = ".feature"
- _BUGFIX = ".bugfix"
- _DOC = ".doc"
- _REMOVAL = ".removal"
- _MISC = ".misc"
-
- _headings = {
- _FEATURE: "Features",
- _BUGFIX: "Bugfixes",
- _DOC: "Improved Documentation",
- _REMOVAL: "Deprecations and Removals",
- _MISC: "Other",
- }
-
- _NO_CHANGES = "No significant changes have been made for this release.\n"
-
- _TICKET_HINT = (
- 'Ticket numbers in this file can be looked up by visiting\n'
- 'http://twistedmatrix.com/trac/ticket/<number>\n'
- '\n')
-
- def _today(self):
- """
- Return today's date as a string in YYYY-MM-DD format.
- """
- return date.today().strftime('%Y-%m-%d')
-
-
- def _findChanges(self, path, ticketType):
- """
- Load all the feature ticket summaries.
-
- @param path: A L{FilePath} the direct children of which to search
- for news entries.
-
- @param ticketType: The type of news entries to search for. One of
- L{NewsBuilder._FEATURE}, L{NewsBuilder._BUGFIX},
- L{NewsBuilder._REMOVAL}, or L{NewsBuilder._MISC}.
-
- @return: A C{list} of two-tuples. The first element is the ticket
- number as an C{int}. The second element of each tuple is the
- description of the feature.
- """
- results = []
- for child in path.children():
- base, ext = os.path.splitext(child.basename())
- if ext == ticketType:
- results.append((
- int(base),
- ' '.join(child.getContent().splitlines())))
- results.sort()
- return results
-
-
- def _formatHeader(self, header):
- """
- Format a header for a NEWS file.
-
- A header is a title with '=' signs underlining it.
-
- @param header: The header string to format.
- @type header: C{str}
- @return: A C{str} containing C{header}.
- """
- return header + '\n' + '=' * len(header) + '\n\n'
-
-
- def _writeHeader(self, fileObj, header):
- """
- Write a version header to the given file.
-
- @param fileObj: A file-like object to which to write the header.
- @param header: The header to write to the file.
- @type header: C{str}
- """
- fileObj.write(self._formatHeader(header))
-
-
- def _writeSection(self, fileObj, header, tickets):
- """
- Write out one section (features, bug fixes, etc) to the given file.
-
- @param fileObj: A file-like object to which to write the news section.
-
- @param header: The header for the section to write.
- @type header: C{str}
-
- @param tickets: A C{list} of ticket information of the sort returned
- by L{NewsBuilder._findChanges}.
- """
- if not tickets:
- return
-
- reverse = {}
- for (ticket, description) in tickets:
- reverse.setdefault(description, []).append(ticket)
- for description in reverse:
- reverse[description].sort()
- reverse = reverse.items()
- reverse.sort(key=lambda (descr, tickets): tickets[0])
-
- fileObj.write(header + '\n' + '-' * len(header) + '\n')
- for (description, relatedTickets) in reverse:
- ticketList = ', '.join([
- '#' + str(ticket) for ticket in relatedTickets])
- entry = ' - %s (%s)' % (description, ticketList)
- entry = textwrap.fill(entry, subsequent_indent=' ')
- fileObj.write(entry + '\n')
- fileObj.write('\n')
-
-
- def _writeMisc(self, fileObj, header, tickets):
- """
- Write out a miscellaneous-changes section to the given file.
-
- @param fileObj: A file-like object to which to write the news section.
-
- @param header: The header for the section to write.
- @type header: C{str}
-
- @param tickets: A C{list} of ticket information of the sort returned
- by L{NewsBuilder._findChanges}.
- """
- if not tickets:
- return
-
- fileObj.write(header + '\n' + '-' * len(header) + '\n')
- formattedTickets = []
- for (ticket, ignored) in tickets:
- formattedTickets.append('#' + str(ticket))
- entry = ' - ' + ', '.join(formattedTickets)
- entry = textwrap.fill(entry, subsequent_indent=' ')
- fileObj.write(entry + '\n\n')
-
-
- def build(self, path, output, header):
- """
- Load all of the change information from the given directory and write
- it out to the given output file.
-
- @param path: A directory (probably a I{topfiles} directory) containing
- change information in the form of <ticket>.<change type> files.
- @type path: L{FilePath}
-
- @param output: The NEWS file to which the results will be prepended.
- @type output: L{FilePath}
-
- @param header: The top-level header to use when writing the news.
- @type header: L{str}
- """
- changes = []
- for part in (self._FEATURE, self._BUGFIX, self._DOC, self._REMOVAL):
- tickets = self._findChanges(path, part)
- if tickets:
- changes.append((part, tickets))
- misc = self._findChanges(path, self._MISC)
-
- oldNews = output.getContent()
- newNews = output.sibling('NEWS.new').open('w')
- if oldNews.startswith(self._TICKET_HINT):
- newNews.write(self._TICKET_HINT)
- oldNews = oldNews[len(self._TICKET_HINT):]
-
- self._writeHeader(newNews, header)
- if changes:
- for (part, tickets) in changes:
- self._writeSection(newNews, self._headings.get(part), tickets)
- else:
- newNews.write(self._NO_CHANGES)
- newNews.write('\n')
- self._writeMisc(newNews, self._headings.get(self._MISC), misc)
- newNews.write('\n')
- newNews.write(oldNews)
- newNews.close()
- output.sibling('NEWS.new').moveTo(output)
-
-
- def _getNewsName(self, project):
- """
- Return the name of C{project} that should appear in NEWS.
-
- @param project: A L{Project}
- @return: The name of C{project}.
- """
- name = project.directory.basename().title()
- if name == 'Twisted':
- name = 'Core'
- return name
-
-
- def _iterProjects(self, baseDirectory):
- """
- Iterate through the Twisted projects in C{baseDirectory}, yielding
- everything we need to know to build news for them.
-
- Yields C{topfiles}, C{news}, C{name}, C{version} for each sub-project
- in reverse-alphabetical order. C{topfile} is the L{FilePath} for the
- topfiles directory, C{news} is the L{FilePath} for the NEWS file,
- C{name} is the nice name of the project (as should appear in the NEWS
- file), C{version} is the current version string for that project.
-
- @param baseDirectory: A L{FilePath} representing the root directory
- beneath which to find Twisted projects for which to generate
- news (see L{findTwistedProjects}).
- @type baseDirectory: L{FilePath}
- """
- # Get all the subprojects to generate news for
- projects = findTwistedProjects(baseDirectory)
- # And order them alphabetically for ease of reading
- projects.sort(key=lambda proj: proj.directory.path)
- # And generate them backwards since we write news by prepending to
- # files.
- projects.reverse()
-
- for aggregateNews in [False, True]:
- for project in projects:
- topfiles = project.directory.child("topfiles")
- if aggregateNews:
- news = baseDirectory.child("NEWS")
- else:
- news = topfiles.child("NEWS")
- name = self._getNewsName(project)
- version = project.getVersion()
- yield topfiles, news, name, version
-
-
- def buildAll(self, baseDirectory):
- """
- Find all of the Twisted subprojects beneath C{baseDirectory} and update
- their news files from the ticket change description files in their
- I{topfiles} directories and update the news file in C{baseDirectory}
- with all of the news.
-
- @param baseDirectory: A L{FilePath} representing the root directory
- beneath which to find Twisted projects for which to generate
- news (see L{findTwistedProjects}).
- """
- today = self._today()
- for topfiles, news, name, version in self._iterProjects(baseDirectory):
- self.build(
- topfiles, news,
- "Twisted %s %s (%s)" % (name, version.base(), today))
-
-
- def _changeNewsVersion(self, news, name, oldVersion, newVersion, today):
- """
- Change all references to the current version number in a NEWS file to
- refer to C{newVersion} instead.
-
- @param news: The NEWS file to change.
- @type news: L{FilePath}
- @param name: The name of the project to change.
- @type name: C{str}
- @param oldVersion: The old version of the project.
- @type oldVersion: L{Version}
- @param newVersion: The new version of the project.
- @type newVersion: L{Version}
- @param today: A YYYY-MM-DD string representing today's date.
- @type today: C{str}
- """
- newHeader = self._formatHeader(
- "Twisted %s %s (%s)" % (name, newVersion.base(), today))
- expectedHeaderRegex = re.compile(
- r"Twisted %s %s \(\d{4}-\d\d-\d\d\)\n=+\n\n" % (
- re.escape(name), re.escape(oldVersion.base())))
- oldNews = news.getContent()
- match = expectedHeaderRegex.search(oldNews)
- if match:
- oldHeader = match.group()
- replaceInFile(news.path, {oldHeader: newHeader})
-
-
- def main(self, args):
- """
- Build all news files.
-
- @param args: The command line arguments to process. This must contain
- one string, the path to the base of the Twisted checkout for which
- to build the news.
- @type args: C{list} of C{str}
- """
- if len(args) != 1:
- sys.exit("Must specify one argument: the path to the Twisted checkout")
- self.buildAll(FilePath(args[0]))
-
-
-
-def filePathDelta(origin, destination):
- """
- Return a list of strings that represent C{destination} as a path relative
- to C{origin}.
-
- It is assumed that both paths represent directories, not files. That is to
- say, the delta of L{twisted.python.filepath.FilePath} /foo/bar to
- L{twisted.python.filepath.FilePath} /foo/baz will be C{../baz},
- not C{baz}.
-
- @type origin: L{twisted.python.filepath.FilePath}
- @param origin: The origin of the relative path.
-
- @type destination: L{twisted.python.filepath.FilePath}
- @param destination: The destination of the relative path.
- """
- commonItems = 0
- path1 = origin.path.split(os.sep)
- path2 = destination.path.split(os.sep)
- for elem1, elem2 in zip(path1, path2):
- if elem1 == elem2:
- commonItems += 1
- else:
- break
- path = [".."] * (len(path1) - commonItems)
- return path + path2[commonItems:]
-
-
-
-class DistributionBuilder(object):
- """
- A builder of Twisted distributions.
-
- This knows how to build tarballs for Twisted and all of its subprojects.
- """
- from twisted.python.dist import twisted_subprojects as subprojects
-
- def __init__(self, rootDirectory, outputDirectory, templatePath=None,
- apiBaseURL=None):
- """
- Create a distribution builder.
-
- @param rootDirectory: root of a Twisted export which will populate
- subsequent tarballs.
- @type rootDirectory: L{FilePath}.
-
- @param outputDirectory: The directory in which to create the tarballs.
- @type outputDirectory: L{FilePath}
-
- @param templatePath: Path to the template file that is used for the
- howto documentation.
- @type templatePath: L{FilePath}
-
- @type apiBaseURL: C{str} or C{NoneType}
- @param apiBaseURL: A format string which will be interpolated with the
- fully-qualified Python name for each API link. For example, to
- generate the Twisted 8.0.0 documentation, pass
- C{"http://twistedmatrix.com/documents/8.0.0/api/%s.html"}.
- """
- self.rootDirectory = rootDirectory
- self.outputDirectory = outputDirectory
- self.templatePath = templatePath
- self.apiBaseURL = apiBaseURL
- self.manBuilder = ManBuilder()
- self.docBuilder = DocBuilder()
-
-
- def _buildDocInDir(self, path, version, howtoPath):
- """
- Generate documentation in the given path, building man pages first if
- necessary and swallowing errors (so that directories without lore
- documentation in them are ignored).
-
- @param path: The path containing documentation to build.
- @type path: L{FilePath}
- @param version: The version of the project to include in all generated
- pages.
- @type version: C{str}
- @param howtoPath: The "resource path" as L{DocBuilder} describes it.
- @type howtoPath: L{FilePath}
- """
- if self.templatePath is None:
- self.templatePath = self.rootDirectory.descendant(
- ["doc", "core", "howto", "template.tpl"])
- if path.basename() == "man":
- self.manBuilder.build(path)
- if path.isdir():
- try:
- self.docBuilder.build(version, howtoPath, path,
- self.templatePath, self.apiBaseURL, True)
- except NoDocumentsFound:
- pass
-
-
- def buildTwisted(self, version):
- """
- Build the main Twisted distribution in C{Twisted-<version>.tar.bz2}.
-
- bin/admin is excluded.
-
- @type version: C{str}
- @param version: The version of Twisted to build.
-
- @return: The tarball file.
- @rtype: L{FilePath}.
- """
- releaseName = "Twisted-%s" % (version,)
- buildPath = lambda *args: '/'.join((releaseName,) + args)
-
- outputFile = self.outputDirectory.child(releaseName + ".tar.bz2")
- tarball = tarfile.TarFile.open(outputFile.path, 'w:bz2')
-
- docPath = self.rootDirectory.child("doc")
-
- # Generate docs!
- if docPath.isdir():
- for subProjectDir in docPath.children():
- if subProjectDir.isdir():
- for child in subProjectDir.walk():
- self._buildDocInDir(child, version,
- subProjectDir.child("howto"))
-
- for binthing in self.rootDirectory.child("bin").children():
- # bin/admin should not be included.
- if binthing.basename() != "admin":
- tarball.add(binthing.path,
- buildPath("bin", binthing.basename()))
-
- for submodule in self.rootDirectory.child("twisted").children():
- if submodule.basename() == "plugins":
- for plugin in submodule.children():
- tarball.add(plugin.path, buildPath("twisted", "plugins",
- plugin.basename()))
- else:
- tarball.add(submodule.path, buildPath("twisted",
- submodule.basename()))
-
- for docDir in self.rootDirectory.child("doc").children():
- if docDir.basename() != "historic":
- tarball.add(docDir.path, buildPath("doc", docDir.basename()))
-
- for toplevel in self.rootDirectory.children():
- if not toplevel.isdir():
- tarball.add(toplevel.path, buildPath(toplevel.basename()))
-
- tarball.close()
-
- return outputFile
-
-
- def buildCore(self, version):
- """
- Build a core distribution in C{TwistedCore-<version>.tar.bz2}.
-
- This is very similar to L{buildSubProject}, but core tarballs and the
- input are laid out slightly differently.
-
- - scripts are in the top level of the C{bin} directory.
- - code is included directly from the C{twisted} directory, excluding
- subprojects.
- - all plugins except the subproject plugins are included.
-
- @type version: C{str}
- @param version: The version of Twisted to build.
-
- @return: The tarball file.
- @rtype: L{FilePath}.
- """
- releaseName = "TwistedCore-%s" % (version,)
- outputFile = self.outputDirectory.child(releaseName + ".tar.bz2")
- buildPath = lambda *args: '/'.join((releaseName,) + args)
- tarball = self._createBasicSubprojectTarball(
- "core", version, outputFile)
-
- # Include the bin directory for the subproject.
- for path in self.rootDirectory.child("bin").children():
- if not path.isdir():
- tarball.add(path.path, buildPath("bin", path.basename()))
-
- # Include all files within twisted/ that aren't part of a subproject.
- for path in self.rootDirectory.child("twisted").children():
- if path.basename() == "plugins":
- for plugin in path.children():
- for subproject in self.subprojects:
- if plugin.basename() == "twisted_%s.py" % (subproject,):
- break
- else:
- tarball.add(plugin.path,
- buildPath("twisted", "plugins",
- plugin.basename()))
- elif not path.basename() in self.subprojects + ["topfiles"]:
- tarball.add(path.path, buildPath("twisted", path.basename()))
-
- tarball.add(self.rootDirectory.child("twisted").child("topfiles").path,
- releaseName)
- tarball.close()
-
- return outputFile
-
-
- def buildSubProject(self, projectName, version):
- """
- Build a subproject distribution in
- C{Twisted<Projectname>-<version>.tar.bz2}.
-
- @type projectName: C{str}
- @param projectName: The lowercase name of the subproject to build.
- @type version: C{str}
- @param version: The version of Twisted to build.
-
- @return: The tarball file.
- @rtype: L{FilePath}.
- """
- releaseName = "Twisted%s-%s" % (projectName.capitalize(), version)
- outputFile = self.outputDirectory.child(releaseName + ".tar.bz2")
- buildPath = lambda *args: '/'.join((releaseName,) + args)
- subProjectDir = self.rootDirectory.child("twisted").child(projectName)
-
- tarball = self._createBasicSubprojectTarball(projectName, version,
- outputFile)
-
- tarball.add(subProjectDir.child("topfiles").path, releaseName)
-
- # Include all files in the subproject package except for topfiles.
- for child in subProjectDir.children():
- name = child.basename()
- if name != "topfiles":
- tarball.add(
- child.path,
- buildPath("twisted", projectName, name))
-
- pluginsDir = self.rootDirectory.child("twisted").child("plugins")
- # Include the plugin for the subproject.
- pluginFileName = "twisted_%s.py" % (projectName,)
- pluginFile = pluginsDir.child(pluginFileName)
- if pluginFile.exists():
- tarball.add(pluginFile.path,
- buildPath("twisted", "plugins", pluginFileName))
-
- # Include the bin directory for the subproject.
- binPath = self.rootDirectory.child("bin").child(projectName)
- if binPath.isdir():
- tarball.add(binPath.path, buildPath("bin"))
- tarball.close()
-
- return outputFile
-
-
- def _createBasicSubprojectTarball(self, projectName, version, outputFile):
- """
- Helper method to create and fill a tarball with things common between
- subprojects and core.
-
- @param projectName: The subproject's name.
- @type projectName: C{str}
- @param version: The version of the release.
- @type version: C{str}
- @param outputFile: The location of the tar file to create.
- @type outputFile: L{FilePath}
- """
- releaseName = "Twisted%s-%s" % (projectName.capitalize(), version)
- buildPath = lambda *args: '/'.join((releaseName,) + args)
-
- tarball = tarfile.TarFile.open(outputFile.path, 'w:bz2')
-
- tarball.add(self.rootDirectory.child("LICENSE").path,
- buildPath("LICENSE"))
-
- docPath = self.rootDirectory.child("doc").child(projectName)
-
- if docPath.isdir():
- for child in docPath.walk():
- self._buildDocInDir(child, version, docPath.child("howto"))
- tarball.add(docPath.path, buildPath("doc"))
-
- return tarball
-
-
-
-class UncleanWorkingDirectory(Exception):
- """
- Raised when the working directory of an SVN checkout is unclean.
- """
-
-
-
-class NotWorkingDirectory(Exception):
- """
- Raised when a directory does not appear to be an SVN working directory.
- """
-
-
-
-def buildAllTarballs(checkout, destination, templatePath=None):
- """
- Build complete tarballs (including documentation) for Twisted and all
- subprojects.
-
- This should be called after the version numbers have been updated and
- NEWS files created.
-
- @type checkout: L{FilePath}
- @param checkout: The SVN working copy from which a pristine source tree
- will be exported.
- @type destination: L{FilePath}
- @param destination: The directory in which tarballs will be placed.
- @type templatePath: L{FilePath}
- @param templatePath: Location of the template file that is used for the
- howto documentation.
-
- @raise UncleanWorkingDirectory: If there are modifications to the
- working directory of C{checkout}.
- @raise NotWorkingDirectory: If the C{checkout} path is not an SVN checkout.
- """
- if not checkout.child(".svn").exists():
- raise NotWorkingDirectory(
- "%s does not appear to be an SVN working directory."
- % (checkout.path,))
- if runCommand(["svn", "st", checkout.path]).strip():
- raise UncleanWorkingDirectory(
- "There are local modifications to the SVN checkout in %s."
- % (checkout.path,))
-
- workPath = FilePath(mkdtemp())
- export = workPath.child("export")
- runCommand(["svn", "export", checkout.path, export.path])
- twistedPath = export.child("twisted")
- version = Project(twistedPath).getVersion()
- versionString = version.base()
-
- apiBaseURL = "http://twistedmatrix.com/documents/%s/api/%%s.html" % (
- versionString)
- if not destination.exists():
- destination.createDirectory()
- db = DistributionBuilder(export, destination, templatePath=templatePath,
- apiBaseURL=apiBaseURL)
-
- db.buildCore(versionString)
- for subproject in twisted_subprojects:
- if twistedPath.child(subproject).exists():
- db.buildSubProject(subproject, versionString)
-
- db.buildTwisted(versionString)
- workPath.remove()
-
-
-class ChangeVersionsScript(object):
- """
- A thing for changing version numbers. See L{main}.
- """
- changeAllProjectVersions = staticmethod(changeAllProjectVersions)
-
- def main(self, args):
- """
- Given a list of command-line arguments, change all the Twisted versions
- in the current directory.
-
- @type args: list of str
- @param args: List of command line arguments. This should only
- contain the version number.
- """
- version_format = (
- "Version should be in a form kind of like '1.2.3[pre4]'")
- if len(args) != 1:
- sys.exit("Must specify exactly one argument to change-versions")
- version = args[0]
- try:
- major, minor, micro_and_pre = version.split(".")
- except ValueError:
- raise SystemExit(version_format)
- if "pre" in micro_and_pre:
- micro, pre = micro_and_pre.split("pre")
- else:
- micro = micro_and_pre
- pre = None
- try:
- major = int(major)
- minor = int(minor)
- micro = int(micro)
- if pre is not None:
- pre = int(pre)
- except ValueError:
- raise SystemExit(version_format)
- version_template = Version("Whatever",
- major, minor, micro, prerelease=pre)
- self.changeAllProjectVersions(FilePath("."), version_template)
-
-
-
-class BuildTarballsScript(object):
- """
- A thing for building release tarballs. See L{main}.
- """
- buildAllTarballs = staticmethod(buildAllTarballs)
-
- def main(self, args):
- """
- Build all release tarballs.
-
- @type args: list of C{str}
- @param args: The command line arguments to process. This must contain
- at least two strings: the checkout directory and the destination
- directory. An optional third string can be specified for the website
- template file, used for building the howto documentation. If this
- string isn't specified, the default template included in twisted
- will be used.
- """
- if len(args) < 2 or len(args) > 3:
- sys.exit("Must specify at least two arguments: "
- "Twisted checkout and destination path. The optional third "
- "argument is the website template path.")
- if len(args) == 2:
- self.buildAllTarballs(FilePath(args[0]), FilePath(args[1]))
- elif len(args) == 3:
- self.buildAllTarballs(FilePath(args[0]), FilePath(args[1]),
- FilePath(args[2]))
-
-
-
-class BuildAPIDocsScript(object):
- """
- A thing for building API documentation. See L{main}.
- """
-
- def buildAPIDocs(self, projectRoot, output):
- """
- Build the API documentation of Twisted, with our project policy.
-
- @param projectRoot: A L{FilePath} representing the root of the Twisted
- checkout.
- @param output: A L{FilePath} pointing to the desired output directory.
- """
- version = Project(projectRoot.child("twisted")).getVersion()
- versionString = version.base()
- sourceURL = ("http://twistedmatrix.com/trac/browser/tags/releases/"
- "twisted-%s" % (versionString,))
- apiBuilder = APIBuilder()
- apiBuilder.build(
- "Twisted",
- "http://twistedmatrix.com/",
- sourceURL,
- projectRoot.child("twisted"),
- output)
-
-
- def main(self, args):
- """
- Build API documentation.
-
- @type args: list of str
- @param args: The command line arguments to process. This must contain
- two strings: the path to the root of the Twisted checkout, and a
- path to an output directory.
- """
- if len(args) != 2:
- sys.exit("Must specify two arguments: "
- "Twisted checkout and destination path")
- self.buildAPIDocs(FilePath(args[0]), FilePath(args[1]))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py
deleted file mode 100755
index b7768027..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py
+++ /dev/null
@@ -1,668 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_shellcomp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-No public APIs are provided by this module. Internal use only.
-
-This module implements dynamic tab-completion for any command that uses
-twisted.python.usage. Currently, only zsh is supported. Bash support may
-be added in the future.
-
-Maintainer: Eric P. Mangold - twisted AT teratorn DOT org
-
-In order for zsh completion to take place the shell must be able to find an
-appropriate "stub" file ("completion function") that invokes this code and
-displays the results to the user.
-
-The stub used for Twisted commands is in the file C{twisted-completion.zsh},
-which is also included in the official Zsh distribution at
-C{Completion/Unix/Command/_twisted}. Use this file as a basis for completion
-functions for your own commands. You should only need to change the first line
-to something like C{#compdef mycommand}.
-
-The main public documentation exists in the L{twisted.python.usage.Options}
-docstring, the L{twisted.python.usage.Completions} docstring, and the
-Options howto.
-"""
-import itertools, getopt, inspect
-
-from twisted.python import reflect, util, usage
-
-
-
-def shellComplete(config, cmdName, words, shellCompFile):
- """
- Perform shell completion.
-
- A completion function (shell script) is generated for the requested
- shell and written to C{shellCompFile}, typically C{stdout}. The result
- is then eval'd by the shell to produce the desired completions.
-
- @type config: L{twisted.python.usage.Options}
- @param config: The L{twisted.python.usage.Options} instance to generate
- completions for.
-
- @type cmdName: C{str}
- @param cmdName: The name of the command we're generating completions for.
- In the case of zsh, this is used to print an appropriate
- "#compdef $CMD" line at the top of the output. This is
- not necessary for the functionality of the system, but it
- helps in debugging, since the output we produce is properly
- formed and may be saved in a file and used as a stand-alone
- completion function.
-
- @type words: C{list} of C{str}
- @param words: The raw command-line words passed to use by the shell
- stub function. argv[0] has already been stripped off.
-
- @type shellCompFile: C{file}
- @param shellCompFile: The file to write completion data to.
- """
- # shellName is provided for forward-compatibility. It is not used,
- # since we currently only support zsh.
- shellName, position = words[-1].split(":")
- position = int(position)
- # zsh gives the completion position ($CURRENT) as a 1-based index,
- # and argv[0] has already been stripped off, so we subtract 2 to
- # get the real 0-based index.
- position -= 2
- cWord = words[position]
-
- # since the user may hit TAB at any time, we may have been called with an
- # incomplete command-line that would generate getopt errors if parsed
- # verbatim. However, we must do *some* parsing in order to determine if
- # there is a specific subcommand that we need to provide completion for.
- # So, to make the command-line more sane we work backwards from the
- # current completion position and strip off all words until we find one
- # that "looks" like a subcommand. It may in fact be the argument to a
- # normal command-line option, but that won't matter for our purposes.
- while position >= 1:
- if words[position - 1].startswith("-"):
- position -= 1
- else:
- break
- words = words[:position]
-
- subCommands = getattr(config, 'subCommands', None)
- if subCommands:
- # OK, this command supports sub-commands, so lets see if we have been
- # given one.
-
- # If the command-line arguments are not valid then we won't be able to
- # sanely detect the sub-command, so just generate completions as if no
- # sub-command was found.
- args = None
- try:
- opts, args = getopt.getopt(words,
- config.shortOpt, config.longOpt)
- except getopt.error:
- pass
-
- if args:
- # yes, we have a subcommand. Try to find it.
- for (cmd, short, parser, doc) in config.subCommands:
- if args[0] == cmd or args[0] == short:
- subOptions = parser()
- subOptions.parent = config
-
- gen = ZshSubcommandBuilder(subOptions, config, cmdName,
- shellCompFile)
- gen.write()
- return
-
- # sub-command not given, or did not match any knowns sub-command names
- genSubs = True
- if cWord.startswith("-"):
- # optimization: if the current word being completed starts
- # with a hyphen then it can't be a sub-command, so skip
- # the expensive generation of the sub-command list
- genSubs = False
- gen = ZshBuilder(config, cmdName, shellCompFile)
- gen.write(genSubs=genSubs)
- else:
- gen = ZshBuilder(config, cmdName, shellCompFile)
- gen.write()
-
-
-
-class SubcommandAction(usage.Completer):
- def _shellCode(self, optName, shellType):
- if shellType == usage._ZSH:
- return '*::subcmd:->subcmd'
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class ZshBuilder(object):
- """
- Constructs zsh code that will complete options for a given usage.Options
- instance, possibly including a list of subcommand names.
-
- Completions for options to subcommands won't be generated because this
- class will never be used if the user is completing options for a specific
- subcommand. (See L{ZshSubcommandBuilder} below)
-
- @type options: L{twisted.python.usage.Options}
- @ivar options: The L{twisted.python.usage.Options} instance defined for this
- command.
-
- @type cmdName: C{str}
- @ivar cmdName: The name of the command we're generating completions for.
-
- @type file: C{file}
- @ivar file: The C{file} to write the completion function to.
- """
- def __init__(self, options, cmdName, file):
- self.options = options
- self.cmdName = cmdName
- self.file = file
-
-
- def write(self, genSubs=True):
- """
- Generate the completion function and write it to the output file
- @return: C{None}
-
- @type genSubs: C{bool}
- @param genSubs: Flag indicating whether or not completions for the list
- of subcommand should be generated. Only has an effect
- if the C{subCommands} attribute has been defined on the
- L{twisted.python.usage.Options} instance.
- """
- if genSubs and getattr(self.options, 'subCommands', None) is not None:
- gen = ZshArgumentsGenerator(self.options, self.cmdName, self.file)
- gen.extraActions.insert(0, SubcommandAction())
- gen.write()
- self.file.write('local _zsh_subcmds_array\n_zsh_subcmds_array=(\n')
- for (cmd, short, parser, desc) in self.options.subCommands:
- self.file.write('"%s:%s"\n' % (cmd, desc))
- self.file.write(")\n\n")
- self.file.write('_describe "sub-command" _zsh_subcmds_array\n')
- else:
- gen = ZshArgumentsGenerator(self.options, self.cmdName, self.file)
- gen.write()
-
-
-
-class ZshSubcommandBuilder(ZshBuilder):
- """
- Constructs zsh code that will complete options for a given usage.Options
- instance, and also for a single sub-command. This will only be used in
- the case where the user is completing options for a specific subcommand.
-
- @type subOptions: L{twisted.python.usage.Options}
- @ivar subOptions: The L{twisted.python.usage.Options} instance defined for
- the sub command.
- """
- def __init__(self, subOptions, *args):
- self.subOptions = subOptions
- ZshBuilder.__init__(self, *args)
-
-
- def write(self):
- """
- Generate the completion function and write it to the output file
- @return: C{None}
- """
- gen = ZshArgumentsGenerator(self.options, self.cmdName, self.file)
- gen.extraActions.insert(0, SubcommandAction())
- gen.write()
-
- gen = ZshArgumentsGenerator(self.subOptions, self.cmdName, self.file)
- gen.write()
-
-
-
-class ZshArgumentsGenerator(object):
- """
- Generate a call to the zsh _arguments completion function
- based on data in a usage.Options instance
-
- @type options: L{twisted.python.usage.Options}
- @ivar options: The L{twisted.python.usage.Options} instance to generate for
-
- @type cmdName: C{str}
- @ivar cmdName: The name of the command we're generating completions for.
-
- @type file: C{file}
- @ivar file: The C{file} to write the completion function to
-
- The following non-constructor variables are populated by this class
- with data gathered from the C{Options} instance passed in, and its
- base classes.
-
- @type descriptions: C{dict}
- @ivar descriptions: A dict mapping long option names to alternate
- descriptions. When this variable is defined, the descriptions
- contained here will override those descriptions provided in the
- optFlags and optParameters variables.
-
- @type multiUse: C{list}
- @ivar multiUse: An iterable containing those long option names which may
- appear on the command line more than once. By default, options will
- only be completed one time.
-
- @type mutuallyExclusive: C{list} of C{tuple}
- @ivar mutuallyExclusive: A sequence of sequences, with each sub-sequence
- containing those long option names that are mutually exclusive. That is,
- those options that cannot appear on the command line together.
-
- @type optActions: C{dict}
- @ivar optActions: A dict mapping long option names to shell "actions".
- These actions define what may be completed as the argument to the
- given option, and should be given as instances of
- L{twisted.python.usage.Completer}.
-
- Callables may instead be given for the values in this dict. The
- callable should accept no arguments, and return a C{Completer}
- instance used as the action.
-
- @type extraActions: C{list} of C{twisted.python.usage.Completer}
- @ivar extraActions: Extra arguments are those arguments typically
- appearing at the end of the command-line, which are not associated
- with any particular named option. That is, the arguments that are
- given to the parseArgs() method of your usage.Options subclass.
- """
- def __init__(self, options, cmdName, file):
- self.options = options
- self.cmdName = cmdName
- self.file = file
-
- self.descriptions = {}
- self.multiUse = set()
- self.mutuallyExclusive = []
- self.optActions = {}
- self.extraActions = []
-
- for cls in reversed(inspect.getmro(options.__class__)):
- data = getattr(cls, 'compData', None)
- if data:
- self.descriptions.update(data.descriptions)
- self.optActions.update(data.optActions)
- self.multiUse.update(data.multiUse)
-
- self.mutuallyExclusive.extend(data.mutuallyExclusive)
-
- # I don't see any sane way to aggregate extraActions, so just
- # take the one at the top of the MRO (nearest the `options'
- # instance).
- if data.extraActions:
- self.extraActions = data.extraActions
-
- aCL = reflect.accumulateClassList
- aCD = reflect.accumulateClassDict
-
- optFlags = []
- optParams = []
-
- aCL(options.__class__, 'optFlags', optFlags)
- aCL(options.__class__, 'optParameters', optParams)
-
- for i, optList in enumerate(optFlags):
- if len(optList) != 3:
- optFlags[i] = util.padTo(3, optList)
-
- for i, optList in enumerate(optParams):
- if len(optList) != 5:
- optParams[i] = util.padTo(5, optList)
-
-
- self.optFlags = optFlags
- self.optParams = optParams
-
- paramNameToDefinition = {}
- for optList in optParams:
- paramNameToDefinition[optList[0]] = optList[1:]
- self.paramNameToDefinition = paramNameToDefinition
-
- flagNameToDefinition = {}
- for optList in optFlags:
- flagNameToDefinition[optList[0]] = optList[1:]
- self.flagNameToDefinition = flagNameToDefinition
-
- allOptionsNameToDefinition = {}
- allOptionsNameToDefinition.update(paramNameToDefinition)
- allOptionsNameToDefinition.update(flagNameToDefinition)
- self.allOptionsNameToDefinition = allOptionsNameToDefinition
-
- self.addAdditionalOptions()
-
- # makes sure none of the Completions metadata references
- # option names that don't exist. (great for catching typos)
- self.verifyZshNames()
-
- self.excludes = self.makeExcludesDict()
-
-
- def write(self):
- """
- Write the zsh completion code to the file given to __init__
- @return: C{None}
- """
- self.writeHeader()
- self.writeExtras()
- self.writeOptions()
- self.writeFooter()
-
-
- def writeHeader(self):
- """
- This is the start of the code that calls _arguments
- @return: C{None}
- """
- self.file.write('#compdef %s\n\n'
- '_arguments -s -A "-*" \\\n' % (self.cmdName,))
-
-
- def writeOptions(self):
- """
- Write out zsh code for each option in this command
- @return: C{None}
- """
- optNames = self.allOptionsNameToDefinition.keys()
- optNames.sort()
- for longname in optNames:
- self.writeOpt(longname)
-
-
- def writeExtras(self):
- """
- Write out completion information for extra arguments appearing on the
- command-line. These are extra positional arguments not associated
- with a named option. That is, the stuff that gets passed to
- Options.parseArgs().
-
- @return: C{None}
-
- @raises: ValueError: if C{Completer} with C{repeat=True} is found and
- is not the last item in the C{extraActions} list.
- """
- for i, action in enumerate(self.extraActions):
- descr = ""
- if action._descr:
- descr = action._descr
- # a repeatable action must be the last action in the list
- if action._repeat and i != len(self.extraActions) - 1:
- raise ValueError("Completer with repeat=True must be "
- "last item in Options.extraActions")
- self.file.write(escape(action._shellCode('', usage._ZSH)))
- self.file.write(' \\\n')
-
-
- def writeFooter(self):
- """
- Write the last bit of code that finishes the call to _arguments
- @return: C{None}
- """
- self.file.write('&& return 0\n')
-
-
- def verifyZshNames(self):
- """
- Ensure that none of the option names given in the metadata are typoed
- @return: C{None}
- @raise ValueError: Raised if unknown option names have been found.
- """
- def err(name):
- raise ValueError("Unknown option name \"%s\" found while\n"
- "examining Completions instances on %s" % (
- name, self.options))
-
- for name in itertools.chain(self.descriptions, self.optActions,
- self.multiUse):
- if name not in self.allOptionsNameToDefinition:
- err(name)
-
- for seq in self.mutuallyExclusive:
- for name in seq:
- if name not in self.allOptionsNameToDefinition:
- err(name)
-
-
- def excludeStr(self, longname, buildShort=False):
- """
- Generate an "exclusion string" for the given option
-
- @type longname: C{str}
- @param longname: The long option name (e.g. "verbose" instead of "v")
-
- @type buildShort: C{bool}
- @param buildShort: May be True to indicate we're building an excludes
- string for the short option that correspondes to the given long opt.
-
- @return: The generated C{str}
- """
- if longname in self.excludes:
- exclusions = self.excludes[longname].copy()
- else:
- exclusions = set()
-
- # if longname isn't a multiUse option (can't appear on the cmd line more
- # than once), then we have to exclude the short option if we're
- # building for the long option, and vice versa.
- if longname not in self.multiUse:
- if buildShort is False:
- short = self.getShortOption(longname)
- if short is not None:
- exclusions.add(short)
- else:
- exclusions.add(longname)
-
- if not exclusions:
- return ''
-
- strings = []
- for optName in exclusions:
- if len(optName) == 1:
- # short option
- strings.append("-" + optName)
- else:
- strings.append("--" + optName)
- strings.sort() # need deterministic order for reliable unit-tests
- return "(%s)" % " ".join(strings)
-
-
- def makeExcludesDict(self):
- """
- @return: A C{dict} that maps each option name appearing in
- self.mutuallyExclusive to a list of those option names that is it
- mutually exclusive with (can't appear on the cmd line with).
- """
-
- #create a mapping of long option name -> single character name
- longToShort = {}
- for optList in itertools.chain(self.optParams, self.optFlags):
- if optList[1] != None:
- longToShort[optList[0]] = optList[1]
-
- excludes = {}
- for lst in self.mutuallyExclusive:
- for i, longname in enumerate(lst):
- tmp = set(lst[:i] + lst[i+1:])
- for name in tmp.copy():
- if name in longToShort:
- tmp.add(longToShort[name])
-
- if longname in excludes:
- excludes[longname] = excludes[longname].union(tmp)
- else:
- excludes[longname] = tmp
- return excludes
-
-
- def writeOpt(self, longname):
- """
- Write out the zsh code for the given argument. This is just part of the
- one big call to _arguments
-
- @type longname: C{str}
- @param longname: The long option name (e.g. "verbose" instead of "v")
-
- @return: C{None}
- """
- if longname in self.flagNameToDefinition:
- # It's a flag option. Not one that takes a parameter.
- longField = "--%s" % longname
- else:
- longField = "--%s=" % longname
-
- short = self.getShortOption(longname)
- if short != None:
- shortField = "-" + short
- else:
- shortField = ''
-
- descr = self.getDescription(longname)
- descriptionField = descr.replace("[", "\[")
- descriptionField = descriptionField.replace("]", "\]")
- descriptionField = '[%s]' % descriptionField
-
- actionField = self.getAction(longname)
- if longname in self.multiUse:
- multiField = '*'
- else:
- multiField = ''
-
- longExclusionsField = self.excludeStr(longname)
-
- if short:
- #we have to write an extra line for the short option if we have one
- shortExclusionsField = self.excludeStr(longname, buildShort=True)
- self.file.write(escape('%s%s%s%s%s' % (shortExclusionsField,
- multiField, shortField, descriptionField, actionField)))
- self.file.write(' \\\n')
-
- self.file.write(escape('%s%s%s%s%s' % (longExclusionsField,
- multiField, longField, descriptionField, actionField)))
- self.file.write(' \\\n')
-
-
- def getAction(self, longname):
- """
- Return a zsh "action" string for the given argument
- @return: C{str}
- """
- if longname in self.optActions:
- if callable(self.optActions[longname]):
- action = self.optActions[longname]()
- else:
- action = self.optActions[longname]
- return action._shellCode(longname, usage._ZSH)
-
- if longname in self.paramNameToDefinition:
- return ':%s:_files' % (longname,)
- return ''
-
-
- def getDescription(self, longname):
- """
- Return the description to be used for this argument
- @return: C{str}
- """
- #check if we have an alternate descr for this arg, and if so use it
- if longname in self.descriptions:
- return self.descriptions[longname]
-
- #otherwise we have to get it from the optFlags or optParams
- try:
- descr = self.flagNameToDefinition[longname][1]
- except KeyError:
- try:
- descr = self.paramNameToDefinition[longname][2]
- except KeyError:
- descr = None
-
- if descr is not None:
- return descr
-
- # let's try to get it from the opt_foo method doc string if there is one
- longMangled = longname.replace('-', '_') # this is what t.p.usage does
- obj = getattr(self.options, 'opt_%s' % longMangled, None)
- if obj is not None:
- descr = descrFromDoc(obj)
- if descr is not None:
- return descr
-
- return longname # we really ought to have a good description to use
-
-
- def getShortOption(self, longname):
- """
- Return the short option letter or None
- @return: C{str} or C{None}
- """
- optList = self.allOptionsNameToDefinition[longname]
- return optList[0] or None
-
-
- def addAdditionalOptions(self):
- """
- Add additional options to the optFlags and optParams lists.
- These will be defined by 'opt_foo' methods of the Options subclass
- @return: C{None}
- """
- methodsDict = {}
- reflect.accumulateMethods(self.options, methodsDict, 'opt_')
- methodToShort = {}
- for name in methodsDict.copy():
- if len(name) == 1:
- methodToShort[methodsDict[name]] = name
- del methodsDict[name]
-
- for methodName, methodObj in methodsDict.items():
- longname = methodName.replace('_', '-') # t.p.usage does this
- # if this option is already defined by the optFlags or
- # optParameters then we don't want to override that data
- if longname in self.allOptionsNameToDefinition:
- continue
-
- descr = self.getDescription(longname)
-
- short = None
- if methodObj in methodToShort:
- short = methodToShort[methodObj]
-
- reqArgs = methodObj.im_func.func_code.co_argcount
- if reqArgs == 2:
- self.optParams.append([longname, short, None, descr])
- self.paramNameToDefinition[longname] = [short, None, descr]
- self.allOptionsNameToDefinition[longname] = [short, None, descr]
- else:
- # reqArgs must equal 1. self.options would have failed
- # to instantiate if it had opt_ methods with bad signatures.
- self.optFlags.append([longname, short, descr])
- self.flagNameToDefinition[longname] = [short, descr]
- self.allOptionsNameToDefinition[longname] = [short, None, descr]
-
-
-
-def descrFromDoc(obj):
- """
- Generate an appropriate description from docstring of the given object
- """
- if obj.__doc__ is None or obj.__doc__.isspace():
- return None
-
- lines = [x.strip() for x in obj.__doc__.split("\n")
- if x and not x.isspace()]
- return " ".join(lines)
-
-
-
-def escape(x):
- """
- Shell escape the given string
-
- Implementation borrowed from now-deprecated commands.mkarg() in the stdlib
- """
- if '\'' not in x:
- return '\'' + x + '\''
- s = '"'
- for c in x:
- if c in '\\$"`':
- s = s + '\\'
- s = s + c
- s = s + '"'
- return s
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/compat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/compat.py
deleted file mode 100755
index 880a4b0d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/compat.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# -*- test-case-name: twisted.test.test_compat -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Compatibility module to provide backwards compatibility for useful Python
-features.
-
-This is mainly for use of internal Twisted code. We encourage you to use
-the latest version of Python directly from your code, if possible.
-"""
-
-import sys, string, socket, struct
-
-def inet_pton(af, addr):
- if af == socket.AF_INET:
- return socket.inet_aton(addr)
- elif af == getattr(socket, 'AF_INET6', 'AF_INET6'):
- if [x for x in addr if x not in string.hexdigits + ':.']:
- raise ValueError("Illegal characters: %r" % (''.join(x),))
-
- parts = addr.split(':')
- elided = parts.count('')
- ipv4Component = '.' in parts[-1]
-
- if len(parts) > (8 - ipv4Component) or elided > 3:
- raise ValueError("Syntactically invalid address")
-
- if elided == 3:
- return '\x00' * 16
-
- if elided:
- zeros = ['0'] * (8 - len(parts) - ipv4Component + elided)
-
- if addr.startswith('::'):
- parts[:2] = zeros
- elif addr.endswith('::'):
- parts[-2:] = zeros
- else:
- idx = parts.index('')
- parts[idx:idx+1] = zeros
-
- if len(parts) != 8 - ipv4Component:
- raise ValueError("Syntactically invalid address")
- else:
- if len(parts) != (8 - ipv4Component):
- raise ValueError("Syntactically invalid address")
-
- if ipv4Component:
- if parts[-1].count('.') != 3:
- raise ValueError("Syntactically invalid address")
- rawipv4 = socket.inet_aton(parts[-1])
- unpackedipv4 = struct.unpack('!HH', rawipv4)
- parts[-1:] = [hex(x)[2:] for x in unpackedipv4]
-
- parts = [int(x, 16) for x in parts]
- return struct.pack('!8H', *parts)
- else:
- raise socket.error(97, 'Address family not supported by protocol')
-
-def inet_ntop(af, addr):
- if af == socket.AF_INET:
- return socket.inet_ntoa(addr)
- elif af == socket.AF_INET6:
- if len(addr) != 16:
- raise ValueError("address length incorrect")
- parts = struct.unpack('!8H', addr)
- curBase = bestBase = None
- for i in range(8):
- if not parts[i]:
- if curBase is None:
- curBase = i
- curLen = 0
- curLen += 1
- else:
- if curBase is not None:
- if bestBase is None or curLen > bestLen:
- bestBase = curBase
- bestLen = curLen
- curBase = None
- if curBase is not None and (bestBase is None or curLen > bestLen):
- bestBase = curBase
- bestLen = curLen
- parts = [hex(x)[2:] for x in parts]
- if bestBase is not None:
- parts[bestBase:bestBase + bestLen] = ['']
- if parts[0] == '':
- parts.insert(0, '')
- if parts[-1] == '':
- parts.insert(len(parts) - 1, '')
- return ':'.join(parts)
- else:
- raise socket.error(97, 'Address family not supported by protocol')
-
-try:
- socket.AF_INET6
-except AttributeError:
- socket.AF_INET6 = 'AF_INET6'
-
-try:
- socket.inet_pton(socket.AF_INET6, "::")
-except (AttributeError, NameError, socket.error):
- socket.inet_pton = inet_pton
- socket.inet_ntop = inet_ntop
-
-adict = dict
-
-# OpenSSL/__init__.py imports OpenSSL.tsafe. OpenSSL/tsafe.py imports
-# threading. threading imports thread. All to make this stupid threadsafe
-# version of its Connection class. We don't even care about threadsafe
-# Connections. In the interest of not screwing over some crazy person
-# calling into OpenSSL from another thread and trying to use Twisted's SSL
-# support, we don't totally destroy OpenSSL.tsafe, but we will replace it
-# with our own version which imports threading as late as possible.
-
-class tsafe(object):
- class Connection:
- """
- OpenSSL.tsafe.Connection, defined in such a way as to not blow.
- """
- __module__ = 'OpenSSL.tsafe'
-
- def __init__(self, *args):
- from OpenSSL import SSL as _ssl
- self._ssl_conn = apply(_ssl.Connection, args)
- from threading import _RLock
- self._lock = _RLock()
-
- for f in ('get_context', 'pending', 'send', 'write', 'recv',
- 'read', 'renegotiate', 'bind', 'listen', 'connect',
- 'accept', 'setblocking', 'fileno', 'shutdown',
- 'close', 'get_cipher_list', 'getpeername',
- 'getsockname', 'getsockopt', 'setsockopt',
- 'makefile', 'get_app_data', 'set_app_data',
- 'state_string', 'sock_shutdown',
- 'get_peer_certificate', 'want_read', 'want_write',
- 'set_connect_state', 'set_accept_state',
- 'connect_ex', 'sendall'):
-
- exec("""def %s(self, *args):
- self._lock.acquire()
- try:
- return apply(self._ssl_conn.%s, args)
- finally:
- self._lock.release()\n""" % (f, f))
-sys.modules['OpenSSL.tsafe'] = tsafe
-
-import operator
-try:
- operator.attrgetter
-except AttributeError:
- class attrgetter(object):
- def __init__(self, name):
- self.name = name
- def __call__(self, obj):
- return getattr(obj, self.name)
- operator.attrgetter = attrgetter
-
-
-try:
- set = set
-except NameError:
- from sets import Set as set
-
-
-try:
- frozenset = frozenset
-except NameError:
- from sets import ImmutableSet as frozenset
-
-
-try:
- from functools import reduce
-except ImportError:
- reduce = reduce
-
-
-
-def execfile(filename, globals, locals=None):
- """
- Execute a Python script in the given namespaces.
-
- Similar to the execfile builtin, but a namespace is mandatory, partly
- because that's a sensible thing to require, and because otherwise we'd
- have to do some frame hacking.
-
- This is a compatibility implementation for Python 3 porting, to avoid the
- use of the deprecated builtin C{execfile} function.
- """
- if locals is None:
- locals = globals
- fin = open(filename, "rbU")
- try:
- source = fin.read()
- finally:
- fin.close()
- code = compile(source, filename, "exec")
- exec(code, globals, locals)
-
-
-__all__ = [
- "execfile",
- "frozenset",
- "reduce",
- "set",
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/components.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/components.py
deleted file mode 100755
index 6fb1f2a8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/components.py
+++ /dev/null
@@ -1,438 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_components -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Component architecture for Twisted, based on Zope3 components.
-
-Using the Zope3 API directly is strongly recommended. Everything
-you need is in the top-level of the zope.interface package, e.g.::
-
- from zope.interface import Interface, implements
-
- class IFoo(Interface):
- pass
-
- class Foo:
- implements(IFoo)
-
- print IFoo.implementedBy(Foo) # True
- print IFoo.providedBy(Foo()) # True
-
-L{twisted.python.components.registerAdapter} from this module may be used to
-add to Twisted's global adapter registry.
-
-L{twisted.python.components.proxyForInterface} is a factory for classes
-which allow access to only the parts of another class defined by a specified
-interface.
-"""
-
-# zope3 imports
-from zope.interface import interface, declarations
-from zope.interface.adapter import AdapterRegistry
-
-# twisted imports
-from twisted.python import reflect
-from twisted.persisted import styles
-
-
-
-# Twisted's global adapter registry
-globalRegistry = AdapterRegistry()
-
-# Attribute that registerAdapter looks at. Is this supposed to be public?
-ALLOW_DUPLICATES = 0
-
-# Define a function to find the registered adapter factory, using either a
-# version of Zope Interface which has the `registered' method or an older
-# version which does not.
-if getattr(AdapterRegistry, 'registered', None) is None:
- def _registered(registry, required, provided):
- """
- Return the adapter factory for the given parameters in the given
- registry, or None if there is not one.
- """
- return registry.get(required).selfImplied.get(provided, {}).get('')
-else:
- def _registered(registry, required, provided):
- """
- Return the adapter factory for the given parameters in the given
- registry, or None if there is not one.
- """
- return registry.registered([required], provided)
-
-
-def registerAdapter(adapterFactory, origInterface, *interfaceClasses):
- """Register an adapter class.
-
- An adapter class is expected to implement the given interface, by
- adapting instances implementing 'origInterface'. An adapter class's
- __init__ method should accept one parameter, an instance implementing
- 'origInterface'.
- """
- self = globalRegistry
- assert interfaceClasses, "You need to pass an Interface"
- global ALLOW_DUPLICATES
-
- # deal with class->interface adapters:
- if not isinstance(origInterface, interface.InterfaceClass):
- origInterface = declarations.implementedBy(origInterface)
-
- for interfaceClass in interfaceClasses:
- factory = _registered(self, origInterface, interfaceClass)
- if factory is not None and not ALLOW_DUPLICATES:
- raise ValueError("an adapter (%s) was already registered." % (factory, ))
- for interfaceClass in interfaceClasses:
- self.register([origInterface], interfaceClass, '', adapterFactory)
-
-
-def getAdapterFactory(fromInterface, toInterface, default):
- """Return registered adapter for a given class and interface.
-
- Note that is tied to the *Twisted* global registry, and will
- thus not find adapters registered elsewhere.
- """
- self = globalRegistry
- if not isinstance(fromInterface, interface.InterfaceClass):
- fromInterface = declarations.implementedBy(fromInterface)
- factory = self.lookup1(fromInterface, toInterface)
- if factory is None:
- factory = default
- return factory
-
-
-def _addHook(registry):
- """
- Add an adapter hook which will attempt to look up adapters in the given
- registry.
-
- @type registry: L{zope.interface.adapter.AdapterRegistry}
-
- @return: The hook which was added, for later use with L{_removeHook}.
- """
- lookup = registry.lookup1
- def _hook(iface, ob):
- factory = lookup(declarations.providedBy(ob), iface)
- if factory is None:
- return None
- else:
- return factory(ob)
- interface.adapter_hooks.append(_hook)
- return _hook
-
-
-def _removeHook(hook):
- """
- Remove a previously added adapter hook.
-
- @param hook: An object previously returned by a call to L{_addHook}. This
- will be removed from the list of adapter hooks.
- """
- interface.adapter_hooks.remove(hook)
-
-# add global adapter lookup hook for our newly created registry
-_addHook(globalRegistry)
-
-
-def getRegistry():
- """Returns the Twisted global
- C{zope.interface.adapter.AdapterRegistry} instance.
- """
- return globalRegistry
-
-# FIXME: deprecate attribute somehow?
-CannotAdapt = TypeError
-
-class Adapter:
- """I am the default implementation of an Adapter for some interface.
-
- This docstring contains a limerick, by popular demand::
-
- Subclassing made Zope and TR
- much harder to work with by far.
- So before you inherit,
- be sure to declare it
- Adapter, not PyObject*
-
- @cvar temporaryAdapter: If this is True, the adapter will not be
- persisted on the Componentized.
- @cvar multiComponent: If this adapter is persistent, should it be
- automatically registered for all appropriate interfaces.
- """
-
- # These attributes are used with Componentized.
-
- temporaryAdapter = 0
- multiComponent = 1
-
- def __init__(self, original):
- """Set my 'original' attribute to be the object I am adapting.
- """
- self.original = original
-
- def __conform__(self, interface):
- """
- I forward __conform__ to self.original if it has it, otherwise I
- simply return None.
- """
- if hasattr(self.original, "__conform__"):
- return self.original.__conform__(interface)
- return None
-
- def isuper(self, iface, adapter):
- """
- Forward isuper to self.original
- """
- return self.original.isuper(iface, adapter)
-
-
-class Componentized(styles.Versioned):
- """I am a mixin to allow you to be adapted in various ways persistently.
-
- I define a list of persistent adapters. This is to allow adapter classes
- to store system-specific state, and initialized on demand. The
- getComponent method implements this. You must also register adapters for
- this class for the interfaces that you wish to pass to getComponent.
-
- Many other classes and utilities listed here are present in Zope3; this one
- is specific to Twisted.
- """
-
- persistenceVersion = 1
-
- def __init__(self):
- self._adapterCache = {}
-
- def locateAdapterClass(self, klass, interfaceClass, default):
- return getAdapterFactory(klass, interfaceClass, default)
-
- def setAdapter(self, interfaceClass, adapterClass):
- self.setComponent(interfaceClass, adapterClass(self))
-
- def addAdapter(self, adapterClass, ignoreClass=0):
- """Utility method that calls addComponent. I take an adapter class and
- instantiate it with myself as the first argument.
-
- @return: The adapter instantiated.
- """
- adapt = adapterClass(self)
- self.addComponent(adapt, ignoreClass)
- return adapt
-
- def setComponent(self, interfaceClass, component):
- """
- """
- self._adapterCache[reflect.qual(interfaceClass)] = component
-
- def addComponent(self, component, ignoreClass=0):
- """
- Add a component to me, for all appropriate interfaces.
-
- In order to determine which interfaces are appropriate, the component's
- provided interfaces will be scanned.
-
- If the argument 'ignoreClass' is True, then all interfaces are
- considered appropriate.
-
- Otherwise, an 'appropriate' interface is one for which its class has
- been registered as an adapter for my class according to the rules of
- getComponent.
-
- @return: the list of appropriate interfaces
- """
- for iface in declarations.providedBy(component):
- if (ignoreClass or
- (self.locateAdapterClass(self.__class__, iface, None)
- == component.__class__)):
- self._adapterCache[reflect.qual(iface)] = component
-
- def unsetComponent(self, interfaceClass):
- """Remove my component specified by the given interface class."""
- del self._adapterCache[reflect.qual(interfaceClass)]
-
- def removeComponent(self, component):
- """
- Remove the given component from me entirely, for all interfaces for which
- it has been registered.
-
- @return: a list of the interfaces that were removed.
- """
- l = []
- for k, v in self._adapterCache.items():
- if v is component:
- del self._adapterCache[k]
- l.append(reflect.namedObject(k))
- return l
-
- def getComponent(self, interface, default=None):
- """Create or retrieve an adapter for the given interface.
-
- If such an adapter has already been created, retrieve it from the cache
- that this instance keeps of all its adapters. Adapters created through
- this mechanism may safely store system-specific state.
-
- If you want to register an adapter that will be created through
- getComponent, but you don't require (or don't want) your adapter to be
- cached and kept alive for the lifetime of this Componentized object,
- set the attribute 'temporaryAdapter' to True on your adapter class.
-
- If you want to automatically register an adapter for all appropriate
- interfaces (with addComponent), set the attribute 'multiComponent' to
- True on your adapter class.
- """
- k = reflect.qual(interface)
- if k in self._adapterCache:
- return self._adapterCache[k]
- else:
- adapter = interface.__adapt__(self)
- if adapter is not None and not (
- hasattr(adapter, "temporaryAdapter") and
- adapter.temporaryAdapter):
- self._adapterCache[k] = adapter
- if (hasattr(adapter, "multiComponent") and
- adapter.multiComponent):
- self.addComponent(adapter)
- if adapter is None:
- return default
- return adapter
-
-
- def __conform__(self, interface):
- return self.getComponent(interface)
-
-
-class ReprableComponentized(Componentized):
- def __init__(self):
- Componentized.__init__(self)
-
- def __repr__(self):
- from cStringIO import StringIO
- from pprint import pprint
- sio = StringIO()
- pprint(self._adapterCache, sio)
- return sio.getvalue()
-
-
-
-def proxyForInterface(iface, originalAttribute='original'):
- """
- Create a class which proxies all method calls which adhere to an interface
- to another provider of that interface.
-
- This function is intended for creating specialized proxies. The typical way
- to use it is by subclassing the result::
-
- class MySpecializedProxy(proxyForInterface(IFoo)):
- def someInterfaceMethod(self, arg):
- if arg == 3:
- return 3
- return self.original.someInterfaceMethod(arg)
-
- @param iface: The Interface to which the resulting object will conform, and
- which the wrapped object must provide.
-
- @param originalAttribute: name of the attribute used to save the original
- object in the resulting class. Default to C{original}.
- @type originalAttribute: C{str}
-
- @return: A class whose constructor takes the original object as its only
- argument. Constructing the class creates the proxy.
- """
- def __init__(self, original):
- setattr(self, originalAttribute, original)
- contents = {"__init__": __init__}
- for name in iface:
- contents[name] = _ProxyDescriptor(name, originalAttribute)
- proxy = type("(Proxy for %s)"
- % (reflect.qual(iface),), (object,), contents)
- declarations.classImplements(proxy, iface)
- return proxy
-
-
-
-class _ProxiedClassMethod(object):
- """
- A proxied class method.
-
- @ivar methodName: the name of the method which this should invoke when
- called.
- @type methodName: C{str}
-
- @ivar originalAttribute: name of the attribute of the proxy where the
- original object is stored.
- @type orginalAttribute: C{str}
- """
- def __init__(self, methodName, originalAttribute):
- self.methodName = methodName
- self.originalAttribute = originalAttribute
-
-
- def __call__(self, oself, *args, **kw):
- """
- Invoke the specified L{methodName} method of the C{original} attribute
- for proxyForInterface.
-
- @param oself: an instance of a L{proxyForInterface} object.
-
- @return: the result of the underlying method.
- """
- original = getattr(oself, self.originalAttribute)
- actualMethod = getattr(original, self.methodName)
- return actualMethod(*args, **kw)
-
-
-
-class _ProxyDescriptor(object):
- """
- A descriptor which will proxy attribute access, mutation, and
- deletion to the L{original} attribute of the object it is being accessed
- from.
-
- @ivar attributeName: the name of the attribute which this descriptor will
- retrieve from instances' C{original} attribute.
- @type attributeName: C{str}
-
- @ivar originalAttribute: name of the attribute of the proxy where the
- original object is stored.
- @type orginalAttribute: C{str}
- """
- def __init__(self, attributeName, originalAttribute):
- self.attributeName = attributeName
- self.originalAttribute = originalAttribute
-
-
- def __get__(self, oself, type=None):
- """
- Retrieve the C{self.attributeName} property from L{oself}.
- """
- if oself is None:
- return _ProxiedClassMethod(self.attributeName,
- self.originalAttribute)
- original = getattr(oself, self.originalAttribute)
- return getattr(original, self.attributeName)
-
-
- def __set__(self, oself, value):
- """
- Set the C{self.attributeName} property of L{oself}.
- """
- original = getattr(oself, self.originalAttribute)
- setattr(original, self.attributeName, value)
-
-
- def __delete__(self, oself):
- """
- Delete the C{self.attributeName} property of L{oself}.
- """
- original = getattr(oself, self.originalAttribute)
- delattr(original, self.attributeName)
-
-
-
-__all__ = [
- # Sticking around:
- "registerAdapter", "getAdapterFactory",
- "Adapter", "Componentized", "ReprableComponentized", "getRegistry",
- "proxyForInterface",
-]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/constants.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/constants.py
deleted file mode 100755
index db708d68..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/constants.py
+++ /dev/null
@@ -1,377 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_constants -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Symbolic constant support, including collections and constants with text,
-numeric, and bit flag values.
-"""
-
-__all__ = [
- 'NamedConstant', 'ValueConstant', 'FlagConstant',
- 'Names', 'Values', 'Flags']
-
-from itertools import count
-from operator import and_, or_, xor
-
-_unspecified = object()
-_constantOrder = count().next
-
-
-class _Constant(object):
- """
- @ivar _index: A C{int} allocated from a shared counter in order to keep
- track of the order in which L{_Constant}s are instantiated.
-
- @ivar name: A C{str} giving the name of this constant; only set once the
- constant is initialized by L{_ConstantsContainer}.
-
- @ivar _container: The L{_ConstantsContainer} subclass this constant belongs
- to; only set once the constant is initialized by that subclass.
- """
- def __init__(self):
- self._index = _constantOrder()
-
-
- def __get__(self, oself, cls):
- """
- Ensure this constant has been initialized before returning it.
- """
- cls._initializeEnumerants()
- return self
-
-
- def __repr__(self):
- """
- Return text identifying both which constant this is and which collection
- it belongs to.
- """
- return "<%s=%s>" % (self._container.__name__, self.name)
-
-
- def _realize(self, container, name, value):
- """
- Complete the initialization of this L{_Constant}.
-
- @param container: The L{_ConstantsContainer} subclass this constant is
- part of.
-
- @param name: The name of this constant in its container.
-
- @param value: The value of this constant; not used, as named constants
- have no value apart from their identity.
- """
- self._container = container
- self.name = name
-
-
-
-class _EnumerantsInitializer(object):
- """
- L{_EnumerantsInitializer} is a descriptor used to initialize a cache of
- objects representing named constants for a particular L{_ConstantsContainer}
- subclass.
- """
- def __get__(self, oself, cls):
- """
- Trigger the initialization of the enumerants cache on C{cls} and then
- return it.
- """
- cls._initializeEnumerants()
- return cls._enumerants
-
-
-
-class _ConstantsContainer(object):
- """
- L{_ConstantsContainer} is a class with attributes used as symbolic
- constants. It is up to subclasses to specify what kind of constants are
- allowed.
-
- @cvar _constantType: Specified by a L{_ConstantsContainer} subclass to
- specify the type of constants allowed by that subclass.
-
- @cvar _enumerantsInitialized: A C{bool} tracking whether C{_enumerants} has
- been initialized yet or not.
-
- @cvar _enumerants: A C{dict} mapping the names of constants (eg
- L{NamedConstant} instances) found in the class definition to those
- instances. This is initialized via the L{_EnumerantsInitializer}
- descriptor the first time it is accessed.
- """
- _constantType = None
-
- _enumerantsInitialized = False
- _enumerants = _EnumerantsInitializer()
-
- def __new__(cls):
- """
- Classes representing constants containers are not intended to be
- instantiated.
-
- The class object itself is used directly.
- """
- raise TypeError("%s may not be instantiated." % (cls.__name__,))
-
-
- def _initializeEnumerants(cls):
- """
- Find all of the L{NamedConstant} instances in the definition of C{cls},
- initialize them with constant values, and build a mapping from their
- names to them to attach to C{cls}.
- """
- if not cls._enumerantsInitialized:
- constants = []
- for (name, descriptor) in cls.__dict__.iteritems():
- if isinstance(descriptor, cls._constantType):
- constants.append((descriptor._index, name, descriptor))
- enumerants = {}
- constants.sort()
- for (index, enumerant, descriptor) in constants:
- value = cls._constantFactory(enumerant, descriptor)
- descriptor._realize(cls, enumerant, value)
- enumerants[enumerant] = descriptor
- # Replace the _enumerants descriptor with the result so future
- # access will go directly to the values. The _enumerantsInitialized
- # flag is still necessary because NamedConstant.__get__ may also
- # call this method.
- cls._enumerants = enumerants
- cls._enumerantsInitialized = True
- _initializeEnumerants = classmethod(_initializeEnumerants)
-
-
- def _constantFactory(cls, name, descriptor):
- """
- Construct the value for a new constant to add to this container.
-
- @param name: The name of the constant to create.
-
- @return: L{NamedConstant} instances have no value apart from identity,
- so return a meaningless dummy value.
- """
- return _unspecified
- _constantFactory = classmethod(_constantFactory)
-
-
- def lookupByName(cls, name):
- """
- Retrieve a constant by its name or raise a C{ValueError} if there is no
- constant associated with that name.
-
- @param name: A C{str} giving the name of one of the constants defined by
- C{cls}.
-
- @raise ValueError: If C{name} is not the name of one of the constants
- defined by C{cls}.
-
- @return: The L{NamedConstant} associated with C{name}.
- """
- if name in cls._enumerants:
- return getattr(cls, name)
- raise ValueError(name)
- lookupByName = classmethod(lookupByName)
-
-
- def iterconstants(cls):
- """
- Iteration over a L{Names} subclass results in all of the constants it
- contains.
-
- @return: an iterator the elements of which are the L{NamedConstant}
- instances defined in the body of this L{Names} subclass.
- """
- constants = cls._enumerants.values()
- constants.sort(key=lambda descriptor: descriptor._index)
- return iter(constants)
- iterconstants = classmethod(iterconstants)
-
-
-
-class NamedConstant(_Constant):
- """
- L{NamedConstant} defines an attribute to be a named constant within a
- collection defined by a L{Names} subclass.
-
- L{NamedConstant} is only for use in the definition of L{Names}
- subclasses. Do not instantiate L{NamedConstant} elsewhere and do not
- subclass it.
- """
-
-
-
-class Names(_ConstantsContainer):
- """
- A L{Names} subclass contains constants which differ only in their names and
- identities.
- """
- _constantType = NamedConstant
-
-
-
-class ValueConstant(_Constant):
- """
- L{ValueConstant} defines an attribute to be a named constant within a
- collection defined by a L{Values} subclass.
-
- L{ValueConstant} is only for use in the definition of L{Values} subclasses.
- Do not instantiate L{ValueConstant} elsewhere and do not subclass it.
- """
- def __init__(self, value):
- _Constant.__init__(self)
- self.value = value
-
-
-
-class Values(_ConstantsContainer):
- """
- A L{Values} subclass contains constants which are associated with arbitrary
- values.
- """
- _constantType = ValueConstant
-
- def lookupByValue(cls, value):
- """
- Retrieve a constant by its value or raise a C{ValueError} if there is no
- constant associated with that value.
-
- @param value: The value of one of the constants defined by C{cls}.
-
- @raise ValueError: If C{value} is not the value of one of the constants
- defined by C{cls}.
-
- @return: The L{ValueConstant} associated with C{value}.
- """
- for constant in cls.iterconstants():
- if constant.value == value:
- return constant
- raise ValueError(value)
- lookupByValue = classmethod(lookupByValue)
-
-
-
-def _flagOp(op, left, right):
- """
- Implement a binary operator for a L{FlagConstant} instance.
-
- @param op: A two-argument callable implementing the binary operation. For
- example, C{operator.or_}.
-
- @param left: The left-hand L{FlagConstant} instance.
- @param right: The right-hand L{FlagConstant} instance.
-
- @return: A new L{FlagConstant} instance representing the result of the
- operation.
- """
- value = op(left.value, right.value)
- names = op(left.names, right.names)
- result = FlagConstant()
- result._realize(left._container, names, value)
- return result
-
-
-
-class FlagConstant(_Constant):
- """
- L{FlagConstant} defines an attribute to be a flag constant within a
- collection defined by a L{Flags} subclass.
-
- L{FlagConstant} is only for use in the definition of L{Flags} subclasses.
- Do not instantiate L{FlagConstant} elsewhere and do not subclass it.
- """
- def __init__(self, value=_unspecified):
- _Constant.__init__(self)
- self.value = value
-
-
- def _realize(self, container, names, value):
- """
- Complete the initialization of this L{FlagConstant}.
-
- This implementation differs from other C{_realize} implementations in
- that a L{FlagConstant} may have several names which apply to it, due to
- flags being combined with various operators.
-
- @param container: The L{Flags} subclass this constant is part of.
-
- @param names: When a single-flag value is being initialized, a C{str}
- giving the name of that flag. This is the case which happens when a
- L{Flags} subclass is being initialized and L{FlagConstant} instances
- from its body are being realized. Otherwise, a C{set} of C{str}
- giving names of all the flags set on this L{FlagConstant} instance.
- This is the case when two flags are combined using C{|}, for
- example.
- """
- if isinstance(names, str):
- name = names
- names = set([names])
- elif len(names) == 1:
- (name,) = names
- else:
- name = "{" + ",".join(sorted(names)) + "}"
- _Constant._realize(self, container, name, value)
- self.value = value
- self.names = names
-
-
- def __or__(self, other):
- """
- Define C{|} on two L{FlagConstant} instances to create a new
- L{FlagConstant} instance with all flags set in either instance set.
- """
- return _flagOp(or_, self, other)
-
-
- def __and__(self, other):
- """
- Define C{&} on two L{FlagConstant} instances to create a new
- L{FlagConstant} instance with only flags set in both instances set.
- """
- return _flagOp(and_, self, other)
-
-
- def __xor__(self, other):
- """
- Define C{^} on two L{FlagConstant} instances to create a new
- L{FlagConstant} instance with only flags set on exactly one instance
- set.
- """
- return _flagOp(xor, self, other)
-
-
- def __invert__(self):
- """
- Define C{~} on a L{FlagConstant} instance to create a new
- L{FlagConstant} instance with all flags not set on this instance set.
- """
- result = FlagConstant()
- result._realize(self._container, set(), 0)
- for flag in self._container.iterconstants():
- if flag.value & self.value == 0:
- result |= flag
- return result
-
-
-
-class Flags(Values):
- """
- A L{Flags} subclass contains constants which can be combined using the
- common bitwise operators (C{|}, C{&}, etc) similar to a I{bitvector} from a
- language like C.
- """
- _constantType = FlagConstant
-
- _value = 1
-
- def _constantFactory(cls, name, descriptor):
- """
- For L{FlagConstant} instances with no explicitly defined value, assign
- the next power of two as its value.
- """
- if descriptor.value is _unspecified:
- value = cls._value
- cls._value <<= 1
- else:
- value = descriptor.value
- cls._value = value << 1
- return value
- _constantFactory = classmethod(_constantFactory)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/context.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/context.py
deleted file mode 100755
index 2bda75f1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/context.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# -*- test-case-name: twisted.test.test_context -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-Dynamic pseudo-scoping for Python.
-
-Call functions with context.call({key: value}, func); func and
-functions that it calls will be able to use 'context.get(key)' to
-retrieve 'value'.
-
-This is thread-safe.
-"""
-
-from threading import local
-
-defaultContextDict = {}
-
-setDefault = defaultContextDict.__setitem__
-
-class ContextTracker:
- """
- A L{ContextTracker} provides a way to pass arbitrary key/value data up and
- down a call stack without passing them as parameters to the functions on
- that call stack.
-
- This can be useful when functions on the top and bottom of the call stack
- need to cooperate but the functions in between them do not allow passing the
- necessary state. For example::
-
- from twisted.python.context import call, get
-
- def handleRequest(request):
- call({'request-id': request.id}, renderRequest, request.url)
-
- def renderRequest(url):
- renderHeader(url)
- renderBody(url)
-
- def renderHeader(url):
- return "the header"
-
- def renderBody(url):
- return "the body (request id=%r)" % (get("request-id"),)
-
- This should be used sparingly, since the lack of a clear connection between
- the two halves can result in code which is difficult to understand and
- maintain.
-
- @ivar contexts: A C{list} of C{dict}s tracking the context state. Each new
- L{ContextTracker.callWithContext} pushes a new C{dict} onto this stack
- for the duration of the call, making the data available to the function
- called and restoring the previous data once it is complete..
- """
- def __init__(self):
- self.contexts = [defaultContextDict]
-
-
- def callWithContext(self, newContext, func, *args, **kw):
- """
- Call C{func(*args, **kw)} such that the contents of C{newContext} will
- be available for it to retrieve using L{getContext}.
-
- @param newContext: A C{dict} of data to push onto the context for the
- duration of the call to C{func}.
-
- @param func: A callable which will be called.
-
- @param *args: Any additional positional arguments to pass to C{func}.
-
- @param **kw: Any additional keyword arguments to pass to C{func}.
-
- @return: Whatever is returned by C{func}
-
- @raise: Whatever is raised by C{func}.
- """
- self.contexts.append(newContext)
- try:
- return func(*args,**kw)
- finally:
- self.contexts.pop()
-
-
- def getContext(self, key, default=None):
- """
- Retrieve the value for a key from the context.
-
- @param key: The key to look up in the context.
-
- @param default: The value to return if C{key} is not found in the
- context.
-
- @return: The value most recently remembered in the context for C{key}.
- """
- for ctx in reversed(self.contexts):
- try:
- return ctx[key]
- except KeyError:
- pass
- return default
-
-
-
-class ThreadedContextTracker(object):
- def __init__(self):
- self.storage = local()
-
- def currentContext(self):
- try:
- return self.storage.ct
- except AttributeError:
- ct = self.storage.ct = ContextTracker()
- return ct
-
- def callWithContext(self, ctx, func, *args, **kw):
- return self.currentContext().callWithContext(ctx, func, *args, **kw)
-
- def getContext(self, key, default=None):
- return self.currentContext().getContext(key, default)
-
-
-def installContextTracker(ctr):
- global theContextTracker
- global call
- global get
-
- theContextTracker = ctr
- call = theContextTracker.callWithContext
- get = theContextTracker.getContext
-
-installContextTracker(ThreadedContextTracker())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/deprecate.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/deprecate.py
deleted file mode 100755
index f4b31b47..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/deprecate.py
+++ /dev/null
@@ -1,534 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_deprecate -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Deprecation framework for Twisted.
-
-To mark a method or function as being deprecated do this::
-
- from twisted.python.versions import Version
- from twisted.python.deprecate import deprecated
-
- @deprecated(Version("Twisted", 8, 0, 0))
- def badAPI(self, first, second):
- '''
- Docstring for badAPI.
- '''
- ...
-
-The newly-decorated badAPI will issue a warning when called. It will also have
-a deprecation notice appended to its docstring.
-
-To mark module-level attributes as being deprecated you can use::
-
- badAttribute = "someValue"
-
- ...
-
- deprecatedModuleAttribute(
- Version("Twisted", 8, 0, 0),
- "Use goodAttribute instead.",
- "your.full.module.name",
- "badAttribute")
-
-The deprecated attributes will issue a warning whenever they are accessed. If
-the attributes being deprecated are in the same module as the
-L{deprecatedModuleAttribute} call is being made from, the C{__name__} global
-can be used as the C{moduleName} parameter.
-
-See also L{Version}.
-
-@type DEPRECATION_WARNING_FORMAT: C{str}
-@var DEPRECATION_WARNING_FORMAT: The default deprecation warning string format
- to use when one is not provided by the user.
-"""
-
-
-__all__ = [
- 'deprecated',
- 'getDeprecationWarningString',
- 'getWarningMethod',
- 'setWarningMethod',
- 'deprecatedModuleAttribute',
- ]
-
-
-import sys, inspect
-from warnings import warn, warn_explicit
-from dis import findlinestarts
-
-from twisted.python.versions import getVersionString
-from twisted.python.util import mergeFunctionMetadata
-
-
-
-DEPRECATION_WARNING_FORMAT = '%(fqpn)s was deprecated in %(version)s'
-
-
-# Notionally, part of twisted.python.reflect, but defining it there causes a
-# cyclic dependency between this module and that module. Define it here,
-# instead, and let reflect import it to re-expose to the public.
-def _fullyQualifiedName(obj):
- """
- Return the fully qualified name of a module, class, method or function.
- Classes and functions need to be module level ones to be correctly
- qualified.
-
- @rtype: C{str}.
- """
- name = obj.__name__
- if inspect.isclass(obj) or inspect.isfunction(obj):
- moduleName = obj.__module__
- return "%s.%s" % (moduleName, name)
- elif inspect.ismethod(obj):
- className = _fullyQualifiedName(obj.im_class)
- return "%s.%s" % (className, name)
- return name
-# Try to keep it looking like something in twisted.python.reflect.
-_fullyQualifiedName.__module__ = 'twisted.python.reflect'
-_fullyQualifiedName.__name__ = 'fullyQualifiedName'
-
-
-
-def getWarningMethod():
- """
- Return the warning method currently used to record deprecation warnings.
- """
- return warn
-
-
-
-def setWarningMethod(newMethod):
- """
- Set the warning method to use to record deprecation warnings.
-
- The callable should take message, category and stacklevel. The return
- value is ignored.
- """
- global warn
- warn = newMethod
-
-
-
-def _getDeprecationDocstring(version, replacement=None):
- """
- Generate an addition to a deprecated object's docstring that explains its
- deprecation.
-
- @param version: the version it was deprecated.
- @type version: L{Version}
-
- @param replacement: The replacement, if specified.
- @type replacement: C{str} or callable
-
- @return: a string like "Deprecated in Twisted 27.2.0; please use
- twisted.timestream.tachyon.flux instead."
- """
- doc = "Deprecated in %s" % (getVersionString(version),)
- if replacement:
- doc = "%s; %s" % (doc, _getReplacementString(replacement))
- return doc + "."
-
-
-
-def _getReplacementString(replacement):
- """
- Surround a replacement for a deprecated API with some polite text exhorting
- the user to consider it as an alternative.
-
- @type replacement: C{str} or callable
-
- @return: a string like "please use twisted.python.modules.getModule
- instead".
- """
- if callable(replacement):
- replacement = _fullyQualifiedName(replacement)
- return "please use %s instead" % (replacement,)
-
-
-
-def _getDeprecationWarningString(fqpn, version, format=None, replacement=None):
- """
- Return a string indicating that the Python name was deprecated in the given
- version.
-
- @param fqpn: Fully qualified Python name of the thing being deprecated
- @type fqpn: C{str}
-
- @param version: Version that C{fqpn} was deprecated in.
- @type version: L{twisted.python.versions.Version}
-
- @param format: A user-provided format to interpolate warning values into, or
- L{DEPRECATION_WARNING_FORMAT
- <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
- given.
- @type format: C{str}
-
- @param replacement: what should be used in place of C{fqpn}. Either pass in
- a string, which will be inserted into the warning message, or a
- callable, which will be expanded to its full import path.
- @type replacement: C{str} or callable
-
- @return: A textual description of the deprecation
- @rtype: C{str}
- """
- if format is None:
- format = DEPRECATION_WARNING_FORMAT
- warningString = format % {
- 'fqpn': fqpn,
- 'version': getVersionString(version)}
- if replacement:
- warningString = "%s; %s" % (
- warningString, _getReplacementString(replacement))
- return warningString
-
-
-
-def getDeprecationWarningString(callableThing, version, format=None,
- replacement=None):
- """
- Return a string indicating that the callable was deprecated in the given
- version.
-
- @type callableThing: C{callable}
- @param callableThing: Callable object to be deprecated
-
- @type version: L{twisted.python.versions.Version}
- @param version: Version that C{callableThing} was deprecated in
-
- @type format: C{str}
- @param format: A user-provided format to interpolate warning values into,
- or L{DEPRECATION_WARNING_FORMAT
- <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
- given
-
- @param callableThing: A callable to be deprecated.
-
- @param version: The L{twisted.python.versions.Version} that the callable
- was deprecated in.
-
- @param replacement: what should be used in place of the callable. Either
- pass in a string, which will be inserted into the warning message,
- or a callable, which will be expanded to its full import path.
- @type replacement: C{str} or callable
-
- @return: A string describing the deprecation.
- @rtype: C{str}
- """
- return _getDeprecationWarningString(
- _fullyQualifiedName(callableThing), version, format, replacement)
-
-
-
-def deprecated(version, replacement=None):
- """
- Return a decorator that marks callables as deprecated.
-
- @type version: L{twisted.python.versions.Version}
- @param version: The version in which the callable will be marked as
- having been deprecated. The decorated function will be annotated
- with this version, having it set as its C{deprecatedVersion}
- attribute.
-
- @param version: the version that the callable was deprecated in.
- @type version: L{twisted.python.versions.Version}
-
- @param replacement: what should be used in place of the callable. Either
- pass in a string, which will be inserted into the warning message,
- or a callable, which will be expanded to its full import path.
- @type replacement: C{str} or callable
- """
- def deprecationDecorator(function):
- """
- Decorator that marks C{function} as deprecated.
- """
- warningString = getDeprecationWarningString(
- function, version, None, replacement)
-
- def deprecatedFunction(*args, **kwargs):
- warn(
- warningString,
- DeprecationWarning,
- stacklevel=2)
- return function(*args, **kwargs)
-
- deprecatedFunction = mergeFunctionMetadata(
- function, deprecatedFunction)
- _appendToDocstring(deprecatedFunction,
- _getDeprecationDocstring(version, replacement))
- deprecatedFunction.deprecatedVersion = version
- return deprecatedFunction
-
- return deprecationDecorator
-
-
-
-def _appendToDocstring(thingWithDoc, textToAppend):
- """
- Append the given text to the docstring of C{thingWithDoc}.
-
- If C{thingWithDoc} has no docstring, then the text just replaces the
- docstring. If it has a single-line docstring then it appends a blank line
- and the message text. If it has a multi-line docstring, then in appends a
- blank line a the message text, and also does the indentation correctly.
- """
- if thingWithDoc.__doc__:
- docstringLines = thingWithDoc.__doc__.splitlines()
- else:
- docstringLines = []
-
- if len(docstringLines) == 0:
- docstringLines.append(textToAppend)
- elif len(docstringLines) == 1:
- docstringLines.extend(['', textToAppend, ''])
- else:
- spaces = docstringLines.pop()
- docstringLines.extend(['',
- spaces + textToAppend,
- spaces])
- thingWithDoc.__doc__ = '\n'.join(docstringLines)
-
-
-
-class _InternalState(object):
- """
- An L{_InternalState} is a helper object for a L{_ModuleProxy}, so that it
- can easily access its own attributes, bypassing its logic for delegating to
- another object that it's proxying for.
-
- @ivar proxy: a L{ModuleProxy}
- """
- def __init__(self, proxy):
- object.__setattr__(self, 'proxy', proxy)
-
-
- def __getattribute__(self, name):
- return object.__getattribute__(object.__getattribute__(self, 'proxy'),
- name)
-
-
- def __setattr__(self, name, value):
- return object.__setattr__(object.__getattribute__(self, 'proxy'),
- name, value)
-
-
-
-class _ModuleProxy(object):
- """
- Python module wrapper to hook module-level attribute access.
-
- Access to deprecated attributes first checks
- L{_ModuleProxy._deprecatedAttributes}, if the attribute does not appear
- there then access falls through to L{_ModuleProxy._module}, the wrapped
- module object.
-
- @ivar _module: Module on which to hook attribute access.
- @type _module: C{module}
-
- @ivar _deprecatedAttributes: Mapping of attribute names to objects that
- retrieve the module attribute's original value.
- @type _deprecatedAttributes: C{dict} mapping C{str} to
- L{_DeprecatedAttribute}
-
- @ivar _lastWasPath: Heuristic guess as to whether warnings about this
- package should be ignored for the next call. If the last attribute
- access of this module was a C{getattr} of C{__path__}, we will assume
- that it was the import system doing it and we won't emit a warning for
- the next access, even if it is to a deprecated attribute. The CPython
- import system always tries to access C{__path__}, then the attribute
- itself, then the attribute itself again, in both successful and failed
- cases.
- @type _lastWasPath: C{bool}
- """
- def __init__(self, module):
- state = _InternalState(self)
- state._module = module
- state._deprecatedAttributes = {}
- state._lastWasPath = False
-
-
- def __repr__(self):
- """
- Get a string containing the type of the module proxy and a
- representation of the wrapped module object.
- """
- state = _InternalState(self)
- return '<%s module=%r>' % (type(self).__name__, state._module)
-
-
- def __setattr__(self, name, value):
- """
- Set an attribute on the wrapped module object.
- """
- state = _InternalState(self)
- state._lastWasPath = False
- setattr(state._module, name, value)
-
-
- def __getattribute__(self, name):
- """
- Get an attribute from the module object, possibly emitting a warning.
-
- If the specified name has been deprecated, then a warning is issued.
- (Unless certain obscure conditions are met; see
- L{_ModuleProxy._lastWasPath} for more information about what might quash
- such a warning.)
- """
- state = _InternalState(self)
- if state._lastWasPath:
- deprecatedAttribute = None
- else:
- deprecatedAttribute = state._deprecatedAttributes.get(name)
-
- if deprecatedAttribute is not None:
- # If we have a _DeprecatedAttribute object from the earlier lookup,
- # allow it to issue the warning.
- value = deprecatedAttribute.get()
- else:
- # Otherwise, just retrieve the underlying value directly; it's not
- # deprecated, there's no warning to issue.
- value = getattr(state._module, name)
- if name == '__path__':
- state._lastWasPath = True
- else:
- state._lastWasPath = False
- return value
-
-
-
-class _DeprecatedAttribute(object):
- """
- Wrapper for deprecated attributes.
-
- This is intended to be used by L{_ModuleProxy}. Calling
- L{_DeprecatedAttribute.get} will issue a warning and retrieve the
- underlying attribute's value.
-
- @type module: C{module}
- @ivar module: The original module instance containing this attribute
-
- @type fqpn: C{str}
- @ivar fqpn: Fully qualified Python name for the deprecated attribute
-
- @type version: L{twisted.python.versions.Version}
- @ivar version: Version that the attribute was deprecated in
-
- @type message: C{str}
- @ivar message: Deprecation message
- """
- def __init__(self, module, name, version, message):
- """
- Initialise a deprecated name wrapper.
- """
- self.module = module
- self.__name__ = name
- self.fqpn = module.__name__ + '.' + name
- self.version = version
- self.message = message
-
-
- def get(self):
- """
- Get the underlying attribute value and issue a deprecation warning.
- """
- # This might fail if the deprecated thing is a module inside a package.
- # In that case, don't emit the warning this time. The import system
- # will come back again when it's not an AttributeError and we can emit
- # the warning then.
- result = getattr(self.module, self.__name__)
- message = _getDeprecationWarningString(self.fqpn, self.version,
- DEPRECATION_WARNING_FORMAT + ': ' + self.message)
- warn(message, DeprecationWarning, stacklevel=3)
- return result
-
-
-
-def _deprecateAttribute(proxy, name, version, message):
- """
- Mark a module-level attribute as being deprecated.
-
- @type proxy: L{_ModuleProxy}
- @param proxy: The module proxy instance proxying the deprecated attributes
-
- @type name: C{str}
- @param name: Attribute name
-
- @type version: L{twisted.python.versions.Version}
- @param version: Version that the attribute was deprecated in
-
- @type message: C{str}
- @param message: Deprecation message
- """
- _module = object.__getattribute__(proxy, '_module')
- attr = _DeprecatedAttribute(_module, name, version, message)
- # Add a deprecated attribute marker for this module's attribute. When this
- # attribute is accessed via _ModuleProxy a warning is emitted.
- _deprecatedAttributes = object.__getattribute__(
- proxy, '_deprecatedAttributes')
- _deprecatedAttributes[name] = attr
-
-
-
-def deprecatedModuleAttribute(version, message, moduleName, name):
- """
- Declare a module-level attribute as being deprecated.
-
- @type version: L{twisted.python.versions.Version}
- @param version: Version that the attribute was deprecated in
-
- @type message: C{str}
- @param message: Deprecation message
-
- @type moduleName: C{str}
- @param moduleName: Fully-qualified Python name of the module containing
- the deprecated attribute; if called from the same module as the
- attributes are being deprecated in, using the C{__name__} global can
- be helpful
-
- @type name: C{str}
- @param name: Attribute name to deprecate
- """
- module = sys.modules[moduleName]
- if not isinstance(module, _ModuleProxy):
- module = _ModuleProxy(module)
- sys.modules[moduleName] = module
-
- _deprecateAttribute(module, name, version, message)
-
-
-def warnAboutFunction(offender, warningString):
- """
- Issue a warning string, identifying C{offender} as the responsible code.
-
- This function is used to deprecate some behavior of a function. It differs
- from L{warnings.warn} in that it is not limited to deprecating the behavior
- of a function currently on the call stack.
-
- @param function: The function that is being deprecated.
-
- @param warningString: The string that should be emitted by this warning.
- @type warningString: C{str}
-
- @since: 11.0
- """
- # inspect.getmodule() is attractive, but somewhat
- # broken in Python < 2.6. See Python bug 4845.
- offenderModule = sys.modules[offender.__module__]
- filename = inspect.getabsfile(offenderModule)
- lineStarts = list(findlinestarts(offender.func_code))
- lastLineNo = lineStarts[-1][1]
- globals = offender.func_globals
-
- kwargs = dict(
- category=DeprecationWarning,
- filename=filename,
- lineno=lastLineNo,
- module=offenderModule.__name__,
- registry=globals.setdefault("__warningregistry__", {}),
- module_globals=None)
-
- if sys.version_info[:2] < (2, 5):
- kwargs.pop('module_globals')
-
- warn_explicit(warningString, **kwargs)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/dist.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/dist.py
deleted file mode 100755
index 26e5b57a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/dist.py
+++ /dev/null
@@ -1,427 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_dist -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Distutils convenience functionality.
-
-Don't use this outside of Twisted.
-
-Maintainer: Christopher Armstrong
-"""
-
-from distutils.command import build_scripts, install_data, build_ext
-from distutils.errors import CompileError
-from distutils import core
-from distutils.core import Extension
-import fnmatch
-import os
-import platform
-import sys
-
-from twisted.python.compat import execfile
-
-
-twisted_subprojects = ["conch", "lore", "mail", "names",
- "news", "pair", "runner", "web",
- "words"]
-
-
-
-class ConditionalExtension(Extension):
- """
- An extension module that will only be compiled if certain conditions are
- met.
-
- @param condition: A callable of one argument which returns True or False to
- indicate whether the extension should be built. The argument is an
- instance of L{build_ext_twisted}, which has useful methods for checking
- things about the platform.
- """
- def __init__(self, *args, **kwargs):
- self.condition = kwargs.pop("condition", lambda builder: True)
- Extension.__init__(self, *args, **kwargs)
-
-
-
-def setup(**kw):
- """
- An alternative to distutils' setup() which is specially designed
- for Twisted subprojects.
-
- Pass twisted_subproject=projname if you want package and data
- files to automatically be found for you.
-
- @param conditionalExtensions: Extensions to optionally build.
- @type conditionalExtensions: C{list} of L{ConditionalExtension}
- """
- return core.setup(**get_setup_args(**kw))
-
-
-def get_setup_args(**kw):
- if 'twisted_subproject' in kw:
- if 'twisted' not in os.listdir('.'):
- raise RuntimeError("Sorry, you need to run setup.py from the "
- "toplevel source directory.")
- projname = kw['twisted_subproject']
- projdir = os.path.join('twisted', projname)
-
- kw['packages'] = getPackages(projdir, parent='twisted')
- kw['version'] = getVersion(projname)
-
- plugin = "twisted/plugins/twisted_" + projname + ".py"
- if os.path.exists(plugin):
- kw.setdefault('py_modules', []).append(
- plugin.replace("/", ".")[:-3])
-
- kw['data_files'] = getDataFiles(projdir, parent='twisted')
-
- del kw['twisted_subproject']
- else:
- if 'plugins' in kw:
- py_modules = []
- for plg in kw['plugins']:
- py_modules.append("twisted.plugins." + plg)
- kw.setdefault('py_modules', []).extend(py_modules)
- del kw['plugins']
-
- if 'cmdclass' not in kw:
- kw['cmdclass'] = {
- 'install_data': install_data_twisted,
- 'build_scripts': build_scripts_twisted}
-
- if "conditionalExtensions" in kw:
- extensions = kw["conditionalExtensions"]
- del kw["conditionalExtensions"]
-
- if 'ext_modules' not in kw:
- # This is a workaround for distutils behavior; ext_modules isn't
- # actually used by our custom builder. distutils deep-down checks
- # to see if there are any ext_modules defined before invoking
- # the build_ext command. We need to trigger build_ext regardless
- # because it is the thing that does the conditional checks to see
- # if it should build any extensions. The reason we have to delay
- # the conditional checks until then is that the compiler objects
- # are not yet set up when this code is executed.
- kw["ext_modules"] = extensions
-
- class my_build_ext(build_ext_twisted):
- conditionalExtensions = extensions
- kw.setdefault('cmdclass', {})['build_ext'] = my_build_ext
- return kw
-
-
-def getVersion(proj, base="twisted"):
- """
- Extract the version number for a given project.
-
- @param proj: the name of the project. Examples are "core",
- "conch", "words", "mail".
-
- @rtype: str
- @returns: The version number of the project, as a string like
- "2.0.0".
- """
- if proj == 'core':
- vfile = os.path.join(base, '_version.py')
- else:
- vfile = os.path.join(base, proj, '_version.py')
- ns = {'__name__': 'Nothing to see here'}
- execfile(vfile, ns)
- return ns['version'].base()
-
-
-# Names that are exluded from globbing results:
-EXCLUDE_NAMES = ["{arch}", "CVS", ".cvsignore", "_darcs",
- "RCS", "SCCS", ".svn"]
-EXCLUDE_PATTERNS = ["*.py[cdo]", "*.s[ol]", ".#*", "*~", "*.py"]
-
-
-def _filterNames(names):
- """
- Given a list of file names, return those names that should be copied.
- """
- names = [n for n in names
- if n not in EXCLUDE_NAMES]
- # This is needed when building a distro from a working
- # copy (likely a checkout) rather than a pristine export:
- for pattern in EXCLUDE_PATTERNS:
- names = [n for n in names
- if (not fnmatch.fnmatch(n, pattern))
- and (not n.endswith('.py'))]
- return names
-
-
-def relativeTo(base, relativee):
- """
- Gets 'relativee' relative to 'basepath'.
-
- i.e.,
-
- >>> relativeTo('/home/', '/home/radix/')
- 'radix'
- >>> relativeTo('.', '/home/radix/Projects/Twisted') # curdir is /home/radix
- 'Projects/Twisted'
-
- The 'relativee' must be a child of 'basepath'.
- """
- basepath = os.path.abspath(base)
- relativee = os.path.abspath(relativee)
- if relativee.startswith(basepath):
- relative = relativee[len(basepath):]
- if relative.startswith(os.sep):
- relative = relative[1:]
- return os.path.join(base, relative)
- raise ValueError("%s is not a subpath of %s" % (relativee, basepath))
-
-
-def getDataFiles(dname, ignore=None, parent=None):
- """
- Get all the data files that should be included in this distutils Project.
-
- 'dname' should be the path to the package that you're distributing.
-
- 'ignore' is a list of sub-packages to ignore. This facilitates
- disparate package hierarchies. That's a fancy way of saying that
- the 'twisted' package doesn't want to include the 'twisted.conch'
- package, so it will pass ['conch'] as the value.
-
- 'parent' is necessary if you're distributing a subpackage like
- twisted.conch. 'dname' should point to 'twisted/conch' and 'parent'
- should point to 'twisted'. This ensures that your data_files are
- generated correctly, only using relative paths for the first element
- of the tuple ('twisted/conch/*').
- The default 'parent' is the current working directory.
- """
- parent = parent or "."
- ignore = ignore or []
- result = []
- for directory, subdirectories, filenames in os.walk(dname):
- resultfiles = []
- for exname in EXCLUDE_NAMES:
- if exname in subdirectories:
- subdirectories.remove(exname)
- for ig in ignore:
- if ig in subdirectories:
- subdirectories.remove(ig)
- for filename in _filterNames(filenames):
- resultfiles.append(filename)
- if resultfiles:
- result.append((relativeTo(parent, directory),
- [relativeTo(parent,
- os.path.join(directory, filename))
- for filename in resultfiles]))
- return result
-
-
-def getExtensions():
- """
- Get all extensions from core and all subprojects.
- """
- extensions = []
-
- if not sys.platform.startswith('java'):
- for dir in os.listdir("twisted") + [""]:
- topfiles = os.path.join("twisted", dir, "topfiles")
- if os.path.isdir(topfiles):
- ns = {}
- setup_py = os.path.join(topfiles, "setup.py")
- execfile(setup_py, ns, ns)
- if "extensions" in ns:
- extensions.extend(ns["extensions"])
-
- return extensions
-
-
-def getPackages(dname, pkgname=None, results=None, ignore=None, parent=None):
- """
- Get all packages which are under dname. This is necessary for
- Python 2.2's distutils. Pretty similar arguments to getDataFiles,
- including 'parent'.
- """
- parent = parent or ""
- prefix = []
- if parent:
- prefix = [parent]
- bname = os.path.basename(dname)
- ignore = ignore or []
- if bname in ignore:
- return []
- if results is None:
- results = []
- if pkgname is None:
- pkgname = []
- subfiles = os.listdir(dname)
- abssubfiles = [os.path.join(dname, x) for x in subfiles]
- if '__init__.py' in subfiles:
- results.append(prefix + pkgname + [bname])
- for subdir in filter(os.path.isdir, abssubfiles):
- getPackages(subdir, pkgname=pkgname + [bname],
- results=results, ignore=ignore,
- parent=parent)
- res = ['.'.join(result) for result in results]
- return res
-
-
-def getScripts(projname, basedir=''):
- """
- Returns a list of scripts for a Twisted subproject; this works in
- any of an SVN checkout, a project-specific tarball.
- """
- scriptdir = os.path.join(basedir, 'bin', projname)
- if not os.path.isdir(scriptdir):
- # Probably a project-specific tarball, in which case only this
- # project's bins are included in 'bin'
- scriptdir = os.path.join(basedir, 'bin')
- if not os.path.isdir(scriptdir):
- return []
- thingies = os.listdir(scriptdir)
- for specialExclusion in ['.svn', '_preamble.py', '_preamble.pyc']:
- if specialExclusion in thingies:
- thingies.remove(specialExclusion)
- return filter(os.path.isfile,
- [os.path.join(scriptdir, x) for x in thingies])
-
-
-## Helpers and distutil tweaks
-
-class build_scripts_twisted(build_scripts.build_scripts):
- """
- Renames scripts so they end with '.py' on Windows.
- """
- def run(self):
- build_scripts.build_scripts.run(self)
- if not os.name == "nt":
- return
- for f in os.listdir(self.build_dir):
- fpath = os.path.join(self.build_dir, f)
- if not fpath.endswith(".py"):
- pypath = fpath + ".py"
- if os.path.exists(pypath):
- os.unlink(pypath)
- os.rename(fpath, pypath)
-
-
-
-class install_data_twisted(install_data.install_data):
- """
- I make sure data files are installed in the package directory.
- """
- def finalize_options(self):
- self.set_undefined_options('install',
- ('install_lib', 'install_dir')
- )
- install_data.install_data.finalize_options(self)
-
-
-
-class build_ext_twisted(build_ext.build_ext):
- """
- Allow subclasses to easily detect and customize Extensions to
- build at install-time.
- """
-
- def prepare_extensions(self):
- """
- Prepare the C{self.extensions} attribute (used by
- L{build_ext.build_ext}) by checking which extensions in
- L{conditionalExtensions} should be built. In addition, if we are
- building on NT, define the WIN32 macro to 1.
- """
- # always define WIN32 under Windows
- if os.name == 'nt':
- self.define_macros = [("WIN32", 1)]
- else:
- self.define_macros = []
- self.extensions = [x for x in self.conditionalExtensions
- if x.condition(self)]
- for ext in self.extensions:
- ext.define_macros.extend(self.define_macros)
-
-
- def build_extensions(self):
- """
- Check to see which extension modules to build and then build them.
- """
- self.prepare_extensions()
- build_ext.build_ext.build_extensions(self)
-
-
- def _remove_conftest(self):
- for filename in ("conftest.c", "conftest.o", "conftest.obj"):
- try:
- os.unlink(filename)
- except EnvironmentError:
- pass
-
-
- def _compile_helper(self, content):
- conftest = open("conftest.c", "w")
- try:
- conftest.write(content)
- conftest.close()
-
- try:
- self.compiler.compile(["conftest.c"], output_dir='')
- except CompileError:
- return False
- return True
- finally:
- self._remove_conftest()
-
-
- def _check_header(self, header_name):
- """
- Check if the given header can be included by trying to compile a file
- that contains only an #include line.
- """
- self.compiler.announce("checking for %s ..." % header_name, 0)
- return self._compile_helper("#include <%s>\n" % header_name)
-
-
-
-def _checkCPython(sys=sys, platform=platform):
- """
- Checks if this implementation is CPython.
-
- On recent versions of Python, will use C{platform.python_implementation}.
- On 2.5, it will try to extract the implementation from sys.subversion. On
- older versions (currently the only supported older version is 2.4), checks
- if C{__pypy__} is in C{sys.modules}, since PyPy is the implementation we
- really care about. If it isn't, assumes CPython.
-
- This takes C{sys} and C{platform} kwargs that by default use the real
- modules. You shouldn't care about these -- they are for testing purposes
- only.
-
- @return: C{False} if the implementation is definitely not CPython, C{True}
- otherwise.
- """
- try:
- return platform.python_implementation() == "CPython"
- except AttributeError:
- # For 2.5:
- try:
- implementation, _, _ = sys.subversion
- return implementation == "CPython"
- except AttributeError:
- pass
-
- # Are we on Pypy?
- if "__pypy__" in sys.modules:
- return False
-
- # No? Well, then we're *probably* on CPython.
- return True
-
-
-_isCPython = _checkCPython()
-
-
-def _hasEpoll(builder):
- """
- Checks if the header for building epoll (C{sys/epoll.h}) is available.
-
- @return: C{True} if the header is available, C{False} otherwise.
- """
- return builder._check_header("sys/epoll.h")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/failure.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/failure.py
deleted file mode 100755
index ed032813..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/failure.py
+++ /dev/null
@@ -1,650 +0,0 @@
-# -*- test-case-name: twisted.test.test_failure -*-
-# See also test suite twisted.test.test_pbfailure
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Asynchronous-friendly error mechanism.
-
-See L{Failure}.
-"""
-
-# System Imports
-import sys
-import linecache
-import inspect
-import opcode
-from cStringIO import StringIO
-from inspect import getmro
-
-from twisted.python import reflect
-
-count = 0
-traceupLength = 4
-
-class DefaultException(Exception):
- pass
-
-def format_frames(frames, write, detail="default"):
- """Format and write frames.
-
- @param frames: is a list of frames as used by Failure.frames, with
- each frame being a list of
- (funcName, fileName, lineNumber, locals.items(), globals.items())
- @type frames: list
- @param write: this will be called with formatted strings.
- @type write: callable
- @param detail: Four detail levels are available:
- default, brief, verbose, and verbose-vars-not-captured.
- C{Failure.printDetailedTraceback} uses the latter when the caller asks
- for verbose, but no vars were captured, so that an explicit warning
- about the missing data is shown.
- @type detail: string
- """
- if detail not in ('default', 'brief', 'verbose',
- 'verbose-vars-not-captured'):
- raise ValueError(
- "Detail must be default, brief, verbose, or "
- "verbose-vars-not-captured. (not %r)" % (detail,))
- w = write
- if detail == "brief":
- for method, filename, lineno, localVars, globalVars in frames:
- w('%s:%s:%s\n' % (filename, lineno, method))
- elif detail == "default":
- for method, filename, lineno, localVars, globalVars in frames:
- w( ' File "%s", line %s, in %s\n' % (filename, lineno, method))
- w( ' %s\n' % linecache.getline(filename, lineno).strip())
- elif detail == "verbose-vars-not-captured":
- for method, filename, lineno, localVars, globalVars in frames:
- w("%s:%d: %s(...)\n" % (filename, lineno, method))
- w(' [Capture of Locals and Globals disabled (use captureVars=True)]\n')
- elif detail == "verbose":
- for method, filename, lineno, localVars, globalVars in frames:
- w("%s:%d: %s(...)\n" % (filename, lineno, method))
- w(' [ Locals ]\n')
- # Note: the repr(val) was (self.pickled and val) or repr(val)))
- for name, val in localVars:
- w(" %s : %s\n" % (name, repr(val)))
- w(' ( Globals )\n')
- for name, val in globalVars:
- w(" %s : %s\n" % (name, repr(val)))
-
-# slyphon: i have a need to check for this value in trial
-# so I made it a module-level constant
-EXCEPTION_CAUGHT_HERE = "--- <exception caught here> ---"
-
-
-
-class NoCurrentExceptionError(Exception):
- """
- Raised when trying to create a Failure from the current interpreter
- exception state and there is no current exception state.
- """
-
-
-class _Traceback(object):
- """
- Fake traceback object which can be passed to functions in the standard
- library L{traceback} module.
- """
-
- def __init__(self, frames):
- """
- Construct a fake traceback object using a list of frames. Note that
- although frames generally include locals and globals, this information
- is not kept by this object, since locals and globals are not used in
- standard tracebacks.
-
- @param frames: [(methodname, filename, lineno, locals, globals), ...]
- """
- assert len(frames) > 0, "Must pass some frames"
- head, frames = frames[0], frames[1:]
- name, filename, lineno, localz, globalz = head
- self.tb_frame = _Frame(name, filename)
- self.tb_lineno = lineno
- if len(frames) == 0:
- self.tb_next = None
- else:
- self.tb_next = _Traceback(frames)
-
-
-class _Frame(object):
- """
- A fake frame object, used by L{_Traceback}.
-
- @ivar f_code: fake L{code<types.CodeType>} object
- @ivar f_globals: fake f_globals dictionary (usually empty)
- @ivar f_locals: fake f_locals dictionary (usually empty)
- """
-
- def __init__(self, name, filename):
- """
- @param name: method/function name for this frame.
- @type name: C{str}
- @param filename: filename for this frame.
- @type name: C{str}
- """
- self.f_code = _Code(name, filename)
- self.f_globals = {}
- self.f_locals = {}
-
-
-class _Code(object):
- """
- A fake code object, used by L{_Traceback} via L{_Frame}.
- """
- def __init__(self, name, filename):
- self.co_name = name
- self.co_filename = filename
-
-
-class Failure:
- """
- A basic abstraction for an error that has occurred.
-
- This is necessary because Python's built-in error mechanisms are
- inconvenient for asynchronous communication.
-
- The C{stack} and C{frame} attributes contain frames. Each frame is a tuple
- of (funcName, fileName, lineNumber, localsItems, globalsItems), where
- localsItems and globalsItems are the contents of
- C{locals().items()}/C{globals().items()} for that frame, or an empty tuple
- if those details were not captured.
-
- @ivar value: The exception instance responsible for this failure.
- @ivar type: The exception's class.
- @ivar stack: list of frames, innermost last, excluding C{Failure.__init__}.
- @ivar frames: list of frames, innermost first.
- """
-
- pickled = 0
- stack = None
-
- # The opcode of "yield" in Python bytecode. We need this in _findFailure in
- # order to identify whether an exception was thrown by a
- # throwExceptionIntoGenerator.
- _yieldOpcode = chr(opcode.opmap["YIELD_VALUE"])
-
- def __init__(self, exc_value=None, exc_type=None, exc_tb=None,
- captureVars=False):
- """
- Initialize me with an explanation of the error.
-
- By default, this will use the current C{exception}
- (L{sys.exc_info}()). However, if you want to specify a
- particular kind of failure, you can pass an exception as an
- argument.
-
- If no C{exc_value} is passed, then an "original" C{Failure} will
- be searched for. If the current exception handler that this
- C{Failure} is being constructed in is handling an exception
- raised by L{raiseException}, then this C{Failure} will act like
- the original C{Failure}.
-
- For C{exc_tb} only L{traceback} instances or C{None} are allowed.
- If C{None} is supplied for C{exc_value}, the value of C{exc_tb} is
- ignored, otherwise if C{exc_tb} is C{None}, it will be found from
- execution context (ie, L{sys.exc_info}).
-
- @param captureVars: if set, capture locals and globals of stack
- frames. This is pretty slow, and makes no difference unless you
- are going to use L{printDetailedTraceback}.
- """
- global count
- count = count + 1
- self.count = count
- self.type = self.value = tb = None
- self.captureVars = captureVars
-
- #strings Exceptions/Failures are bad, mmkay?
- if isinstance(exc_value, (str, unicode)) and exc_type is None:
- import warnings
- warnings.warn(
- "Don't pass strings (like %r) to failure.Failure (replacing with a DefaultException)." %
- exc_value, DeprecationWarning, stacklevel=2)
- exc_value = DefaultException(exc_value)
-
- stackOffset = 0
-
- if exc_value is None:
- exc_value = self._findFailure()
-
- if exc_value is None:
- self.type, self.value, tb = sys.exc_info()
- if self.type is None:
- raise NoCurrentExceptionError()
- stackOffset = 1
- elif exc_type is None:
- if isinstance(exc_value, Exception):
- self.type = exc_value.__class__
- else: #allow arbitrary objects.
- self.type = type(exc_value)
- self.value = exc_value
- else:
- self.type = exc_type
- self.value = exc_value
- if isinstance(self.value, Failure):
- self.__dict__ = self.value.__dict__
- return
- if tb is None:
- if exc_tb:
- tb = exc_tb
-# else:
-# log.msg("Erf, %r created with no traceback, %s %s." % (
-# repr(self), repr(exc_value), repr(exc_type)))
-# for s in traceback.format_stack():
-# log.msg(s)
-
- frames = self.frames = []
- stack = self.stack = []
-
- # added 2003-06-23 by Chris Armstrong. Yes, I actually have a
- # use case where I need this traceback object, and I've made
- # sure that it'll be cleaned up.
- self.tb = tb
-
- if tb:
- f = tb.tb_frame
- elif not isinstance(self.value, Failure):
- # we don't do frame introspection since it's expensive,
- # and if we were passed a plain exception with no
- # traceback, it's not useful anyway
- f = stackOffset = None
-
- while stackOffset and f:
- # This excludes this Failure.__init__ frame from the
- # stack, leaving it to start with our caller instead.
- f = f.f_back
- stackOffset -= 1
-
- # Keeps the *full* stack. Formerly in spread.pb.print_excFullStack:
- #
- # The need for this function arises from the fact that several
- # PB classes have the peculiar habit of discarding exceptions
- # with bareword "except:"s. This premature exception
- # catching means tracebacks generated here don't tend to show
- # what called upon the PB object.
-
- while f:
- if captureVars:
- localz = f.f_locals.copy()
- if f.f_locals is f.f_globals:
- globalz = {}
- else:
- globalz = f.f_globals.copy()
- for d in globalz, localz:
- if "__builtins__" in d:
- del d["__builtins__"]
- localz = localz.items()
- globalz = globalz.items()
- else:
- localz = globalz = ()
- stack.insert(0, (
- f.f_code.co_name,
- f.f_code.co_filename,
- f.f_lineno,
- localz,
- globalz,
- ))
- f = f.f_back
-
- while tb is not None:
- f = tb.tb_frame
- if captureVars:
- localz = f.f_locals.copy()
- if f.f_locals is f.f_globals:
- globalz = {}
- else:
- globalz = f.f_globals.copy()
- for d in globalz, localz:
- if "__builtins__" in d:
- del d["__builtins__"]
- localz = localz.items()
- globalz = globalz.items()
- else:
- localz = globalz = ()
- frames.append((
- f.f_code.co_name,
- f.f_code.co_filename,
- tb.tb_lineno,
- localz,
- globalz,
- ))
- tb = tb.tb_next
- if inspect.isclass(self.type) and issubclass(self.type, Exception):
- parentCs = getmro(self.type)
- self.parents = map(reflect.qual, parentCs)
- else:
- self.parents = [self.type]
-
- def trap(self, *errorTypes):
- """Trap this failure if its type is in a predetermined list.
-
- This allows you to trap a Failure in an error callback. It will be
- automatically re-raised if it is not a type that you expect.
-
- The reason for having this particular API is because it's very useful
- in Deferred errback chains::
-
- def _ebFoo(self, failure):
- r = failure.trap(Spam, Eggs)
- print 'The Failure is due to either Spam or Eggs!'
- if r == Spam:
- print 'Spam did it!'
- elif r == Eggs:
- print 'Eggs did it!'
-
- If the failure is not a Spam or an Eggs, then the Failure
- will be 'passed on' to the next errback.
-
- @type errorTypes: L{Exception}
- """
- error = self.check(*errorTypes)
- if not error:
- raise self
- return error
-
- def check(self, *errorTypes):
- """Check if this failure's type is in a predetermined list.
-
- @type errorTypes: list of L{Exception} classes or
- fully-qualified class names.
- @returns: the matching L{Exception} type, or None if no match.
- """
- for error in errorTypes:
- err = error
- if inspect.isclass(error) and issubclass(error, Exception):
- err = reflect.qual(error)
- if err in self.parents:
- return error
- return None
-
-
- def raiseException(self):
- """
- raise the original exception, preserving traceback
- information if available.
- """
- raise self.type, self.value, self.tb
-
-
- def throwExceptionIntoGenerator(self, g):
- """
- Throw the original exception into the given generator,
- preserving traceback information if available.
-
- @return: The next value yielded from the generator.
- @raise StopIteration: If there are no more values in the generator.
- @raise anything else: Anything that the generator raises.
- """
- return g.throw(self.type, self.value, self.tb)
-
-
- def _findFailure(cls):
- """
- Find the failure that represents the exception currently in context.
- """
- tb = sys.exc_info()[-1]
- if not tb:
- return
-
- secondLastTb = None
- lastTb = tb
- while lastTb.tb_next:
- secondLastTb = lastTb
- lastTb = lastTb.tb_next
-
- lastFrame = lastTb.tb_frame
-
- # NOTE: f_locals.get('self') is used rather than
- # f_locals['self'] because psyco frames do not contain
- # anything in their locals() dicts. psyco makes debugging
- # difficult anyhow, so losing the Failure objects (and thus
- # the tracebacks) here when it is used is not that big a deal.
-
- # handle raiseException-originated exceptions
- if lastFrame.f_code is cls.raiseException.func_code:
- return lastFrame.f_locals.get('self')
-
- # handle throwExceptionIntoGenerator-originated exceptions
- # this is tricky, and differs if the exception was caught
- # inside the generator, or above it:
-
- # it is only really originating from
- # throwExceptionIntoGenerator if the bottom of the traceback
- # is a yield.
- # Pyrex and Cython extensions create traceback frames
- # with no co_code, but they can't yield so we know it's okay to just return here.
- if ((not lastFrame.f_code.co_code) or
- lastFrame.f_code.co_code[lastTb.tb_lasti] != cls._yieldOpcode):
- return
-
- # if the exception was caught above the generator.throw
- # (outside the generator), it will appear in the tb (as the
- # second last item):
- if secondLastTb:
- frame = secondLastTb.tb_frame
- if frame.f_code is cls.throwExceptionIntoGenerator.func_code:
- return frame.f_locals.get('self')
-
- # if the exception was caught below the generator.throw
- # (inside the generator), it will appear in the frames' linked
- # list, above the top-level traceback item (which must be the
- # generator frame itself, thus its caller is
- # throwExceptionIntoGenerator).
- frame = tb.tb_frame.f_back
- if frame and frame.f_code is cls.throwExceptionIntoGenerator.func_code:
- return frame.f_locals.get('self')
-
- _findFailure = classmethod(_findFailure)
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__, self.type)
-
- def __str__(self):
- return "[Failure instance: %s]" % self.getBriefTraceback()
-
- def __getstate__(self):
- """Avoid pickling objects in the traceback.
- """
- if self.pickled:
- return self.__dict__
- c = self.__dict__.copy()
-
- c['frames'] = [
- [
- v[0], v[1], v[2],
- _safeReprVars(v[3]),
- _safeReprVars(v[4]),
- ] for v in self.frames
- ]
-
- # added 2003-06-23. See comment above in __init__
- c['tb'] = None
-
- if self.stack is not None:
- # XXX: This is a band-aid. I can't figure out where these
- # (failure.stack is None) instances are coming from.
- c['stack'] = [
- [
- v[0], v[1], v[2],
- _safeReprVars(v[3]),
- _safeReprVars(v[4]),
- ] for v in self.stack
- ]
-
- c['pickled'] = 1
- return c
-
- def cleanFailure(self):
- """Remove references to other objects, replacing them with strings.
- """
- self.__dict__ = self.__getstate__()
-
- def getTracebackObject(self):
- """
- Get an object that represents this Failure's stack that can be passed
- to traceback.extract_tb.
-
- If the original traceback object is still present, return that. If this
- traceback object has been lost but we still have the information,
- return a fake traceback object (see L{_Traceback}). If there is no
- traceback information at all, return None.
- """
- if self.tb is not None:
- return self.tb
- elif len(self.frames) > 0:
- return _Traceback(self.frames)
- else:
- return None
-
- def getErrorMessage(self):
- """Get a string of the exception which caused this Failure."""
- if isinstance(self.value, Failure):
- return self.value.getErrorMessage()
- return reflect.safe_str(self.value)
-
- def getBriefTraceback(self):
- io = StringIO()
- self.printBriefTraceback(file=io)
- return io.getvalue()
-
- def getTraceback(self, elideFrameworkCode=0, detail='default'):
- io = StringIO()
- self.printTraceback(file=io, elideFrameworkCode=elideFrameworkCode, detail=detail)
- return io.getvalue()
-
-
- def printTraceback(self, file=None, elideFrameworkCode=False, detail='default'):
- """
- Emulate Python's standard error reporting mechanism.
-
- @param file: If specified, a file-like object to which to write the
- traceback.
-
- @param elideFrameworkCode: A flag indicating whether to attempt to
- remove uninteresting frames from within Twisted itself from the
- output.
-
- @param detail: A string indicating how much information to include
- in the traceback. Must be one of C{'brief'}, C{'default'}, or
- C{'verbose'}.
- """
- if file is None:
- file = log.logerr
- w = file.write
-
- if detail == 'verbose' and not self.captureVars:
- # We don't have any locals or globals, so rather than show them as
- # empty make the output explicitly say that we don't have them at
- # all.
- formatDetail = 'verbose-vars-not-captured'
- else:
- formatDetail = detail
-
- # Preamble
- if detail == 'verbose':
- w( '*--- Failure #%d%s---\n' %
- (self.count,
- (self.pickled and ' (pickled) ') or ' '))
- elif detail == 'brief':
- if self.frames:
- hasFrames = 'Traceback'
- else:
- hasFrames = 'Traceback (failure with no frames)'
- w("%s: %s: %s\n" % (
- hasFrames,
- reflect.safe_str(self.type),
- reflect.safe_str(self.value)))
- else:
- w( 'Traceback (most recent call last):\n')
-
- # Frames, formatted in appropriate style
- if self.frames:
- if not elideFrameworkCode:
- format_frames(self.stack[-traceupLength:], w, formatDetail)
- w("%s\n" % (EXCEPTION_CAUGHT_HERE,))
- format_frames(self.frames, w, formatDetail)
- elif not detail == 'brief':
- # Yeah, it's not really a traceback, despite looking like one...
- w("Failure: ")
-
- # postamble, if any
- if not detail == 'brief':
- # Unfortunately, self.type will not be a class object if this
- # Failure was created implicitly from a string exception.
- # qual() doesn't make any sense on a string, so check for this
- # case here and just write out the string if that's what we
- # have.
- if isinstance(self.type, (str, unicode)):
- w(self.type + "\n")
- else:
- w("%s: %s\n" % (reflect.qual(self.type),
- reflect.safe_str(self.value)))
- # chaining
- if isinstance(self.value, Failure):
- # TODO: indentation for chained failures?
- file.write(" (chained Failure)\n")
- self.value.printTraceback(file, elideFrameworkCode, detail)
- if detail == 'verbose':
- w('*--- End of Failure #%d ---\n' % self.count)
-
-
- def printBriefTraceback(self, file=None, elideFrameworkCode=0):
- """Print a traceback as densely as possible.
- """
- self.printTraceback(file, elideFrameworkCode, detail='brief')
-
- def printDetailedTraceback(self, file=None, elideFrameworkCode=0):
- """Print a traceback with detailed locals and globals information.
- """
- self.printTraceback(file, elideFrameworkCode, detail='verbose')
-
-
-def _safeReprVars(varsDictItems):
- """
- Convert a list of (name, object) pairs into (name, repr) pairs.
-
- L{twisted.python.reflect.safe_repr} is used to generate the repr, so no
- exceptions will be raised by faulty C{__repr__} methods.
-
- @param varsDictItems: a sequence of (name, value) pairs as returned by e.g.
- C{locals().items()}.
- @returns: a sequence of (name, repr) pairs.
- """
- return [(name, reflect.safe_repr(obj)) for (name, obj) in varsDictItems]
-
-
-# slyphon: make post-morteming exceptions tweakable
-
-DO_POST_MORTEM = True
-
-def _debuginit(self, exc_value=None, exc_type=None, exc_tb=None,
- captureVars=False,
- Failure__init__=Failure.__init__.im_func):
- """
- Initialize failure object, possibly spawning pdb.
- """
- if (exc_value, exc_type, exc_tb) == (None, None, None):
- exc = sys.exc_info()
- if not exc[0] == self.__class__ and DO_POST_MORTEM:
- try:
- strrepr = str(exc[1])
- except:
- strrepr = "broken str"
- print "Jumping into debugger for post-mortem of exception '%s':" % (strrepr,)
- import pdb
- pdb.post_mortem(exc[2])
- Failure__init__(self, exc_value, exc_type, exc_tb, captureVars)
-
-
-def startDebugMode():
- """Enable debug hooks for Failures."""
- Failure.__init__ = _debuginit
-
-
-# Sibling imports - at the bottom and unqualified to avoid unresolvable
-# circularity
-import log
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/fakepwd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/fakepwd.py
deleted file mode 100755
index 183b30cd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/fakepwd.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_fakepwd -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-L{twisted.python.fakepwd} provides a fake implementation of the L{pwd} API.
-"""
-
-
-__all__ = ['UserDatabase', 'ShadowDatabase']
-
-
-class _UserRecord(object):
- """
- L{_UserRecord} holds the user data for a single user in L{UserDatabase}.
- It corresponds to L{pwd.struct_passwd}. See that class for attribute
- documentation.
- """
- def __init__(self, name, password, uid, gid, gecos, home, shell):
- self.pw_name = name
- self.pw_passwd = password
- self.pw_uid = uid
- self.pw_gid = gid
- self.pw_gecos = gecos
- self.pw_dir = home
- self.pw_shell = shell
-
-
- def __len__(self):
- return 7
-
-
- def __getitem__(self, index):
- return (
- self.pw_name, self.pw_passwd, self.pw_uid,
- self.pw_gid, self.pw_gecos, self.pw_dir, self.pw_shell)[index]
-
-
-
-class UserDatabase(object):
- """
- L{UserDatabase} holds a traditional POSIX user data in memory and makes it
- available via the same API as L{pwd}.
-
- @ivar _users: A C{list} of L{_UserRecord} instances holding all user data
- added to this database.
- """
- def __init__(self):
- self._users = []
-
-
- def addUser(self, username, password, uid, gid, gecos, home, shell):
- """
- Add a new user record to this database.
-
- @param username: The value for the C{pw_name} field of the user
- record to add.
- @type username: C{str}
-
- @param password: The value for the C{pw_passwd} field of the user
- record to add.
- @type password: C{str}
-
- @param uid: The value for the C{pw_uid} field of the user record to
- add.
- @type uid: C{int}
-
- @param gid: The value for the C{pw_gid} field of the user record to
- add.
- @type gid: C{int}
-
- @param gecos: The value for the C{pw_gecos} field of the user record
- to add.
- @type gecos: C{str}
-
- @param home: The value for the C{pw_dir} field of the user record to
- add.
- @type home: C{str}
-
- @param shell: The value for the C{pw_shell} field of the user record to
- add.
- @type shell: C{str}
- """
- self._users.append(_UserRecord(
- username, password, uid, gid, gecos, home, shell))
-
-
- def getpwuid(self, uid):
- """
- Return the user record corresponding to the given uid.
- """
- for entry in self._users:
- if entry.pw_uid == uid:
- return entry
- raise KeyError()
-
-
- def getpwnam(self, name):
- """
- Return the user record corresponding to the given username.
- """
- for entry in self._users:
- if entry.pw_name == name:
- return entry
- raise KeyError()
-
-
- def getpwall(self):
- """
- Return a list of all user records.
- """
- return self._users
-
-
-
-class _ShadowRecord(object):
- """
- L{_ShadowRecord} holds the shadow user data for a single user in
- L{ShadowDatabase}. It corresponds to C{spwd.struct_spwd}. See that class
- for attribute documentation.
- """
- def __init__(self, username, password, lastChange, min, max, warn, inact,
- expire, flag):
- self.sp_nam = username
- self.sp_pwd = password
- self.sp_lstchg = lastChange
- self.sp_min = min
- self.sp_max = max
- self.sp_warn = warn
- self.sp_inact = inact
- self.sp_expire = expire
- self.sp_flag = flag
-
-
- def __len__(self):
- return 9
-
-
- def __getitem__(self, index):
- return (
- self.sp_nam, self.sp_pwd, self.sp_lstchg, self.sp_min,
- self.sp_max, self.sp_warn, self.sp_inact, self.sp_expire,
- self.sp_flag)[index]
-
-
-
-class ShadowDatabase(object):
- """
- L{ShadowDatabase} holds a shadow user database in memory and makes it
- available via the same API as C{spwd}.
-
- @ivar _users: A C{list} of L{_ShadowRecord} instances holding all user data
- added to this database.
-
- @since: 12.0
- """
- def __init__(self):
- self._users = []
-
-
- def addUser(self, username, password, lastChange, min, max, warn, inact,
- expire, flag):
- """
- Add a new user record to this database.
-
- @param username: The value for the C{sp_nam} field of the user record to
- add.
- @type username: C{str}
-
- @param password: The value for the C{sp_pwd} field of the user record to
- add.
- @type password: C{str}
-
- @param lastChange: The value for the C{sp_lstchg} field of the user
- record to add.
- @type lastChange: C{int}
-
- @param min: The value for the C{sp_min} field of the user record to add.
- @type min: C{int}
-
- @param max: The value for the C{sp_max} field of the user record to add.
- @type max: C{int}
-
- @param warn: The value for the C{sp_warn} field of the user record to
- add.
- @type warn: C{int}
-
- @param inact: The value for the C{sp_inact} field of the user record to
- add.
- @type inact: C{int}
-
- @param expire: The value for the C{sp_expire} field of the user record
- to add.
- @type expire: C{int}
-
- @param flag: The value for the C{sp_flag} field of the user record to
- add.
- @type flag: C{int}
- """
- self._users.append(_ShadowRecord(
- username, password, lastChange,
- min, max, warn, inact, expire, flag))
-
-
- def getspnam(self, username):
- """
- Return the shadow user record corresponding to the given username.
- """
- for entry in self._users:
- if entry.sp_nam == username:
- return entry
- raise KeyError
-
-
- def getspall(self):
- """
- Return a list of all shadow user records.
- """
- return self._users
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/filepath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/filepath.py
deleted file mode 100755
index a4016d6d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/filepath.py
+++ /dev/null
@@ -1,1442 +0,0 @@
-# -*- test-case-name: twisted.test.test_paths -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Object-oriented filesystem path representation.
-"""
-
-import os
-import errno
-import random
-import base64
-
-from os.path import isabs, exists, normpath, abspath, splitext
-from os.path import basename, dirname
-from os.path import join as joinpath
-from os import sep as slash
-from os import listdir, utime, stat
-
-from stat import S_ISREG, S_ISDIR, S_IMODE, S_ISBLK, S_ISSOCK
-from stat import S_IRUSR, S_IWUSR, S_IXUSR
-from stat import S_IRGRP, S_IWGRP, S_IXGRP
-from stat import S_IROTH, S_IWOTH, S_IXOTH
-
-
-# Please keep this as light as possible on other Twisted imports; many, many
-# things import this module, and it would be good if it could easily be
-# modified for inclusion in the standard library. --glyph
-
-from twisted.python.runtime import platform
-from twisted.python.hashlib import sha1
-
-from twisted.python.win32 import ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND
-from twisted.python.win32 import ERROR_INVALID_NAME, ERROR_DIRECTORY, O_BINARY
-from twisted.python.win32 import WindowsError
-
-from twisted.python.util import FancyEqMixin
-
-from zope.interface import Interface, Attribute, implements
-
-_CREATE_FLAGS = (os.O_EXCL |
- os.O_CREAT |
- os.O_RDWR |
- O_BINARY)
-
-
-def _stub_islink(path):
- """
- Always return 'false' if the operating system does not support symlinks.
-
- @param path: a path string.
- @type path: L{str}
- @return: false
- """
- return False
-
-
-def _stub_urandom(n):
- """
- Provide random data in versions of Python prior to 2.4. This is an
- effectively compatible replacement for 'os.urandom'.
-
- @type n: L{int}
- @param n: the number of bytes of data to return
- @return: C{n} bytes of random data.
- @rtype: str
- """
- randomData = [random.randrange(256) for n in xrange(n)]
- return ''.join(map(chr, randomData))
-
-
-def _stub_armor(s):
- """
- ASCII-armor for random data. This uses a hex encoding, although we will
- prefer url-safe base64 encoding for features in this module if it is
- available.
- """
- return s.encode('hex')
-
-islink = getattr(os.path, 'islink', _stub_islink)
-randomBytes = getattr(os, 'urandom', _stub_urandom)
-armor = getattr(base64, 'urlsafe_b64encode', _stub_armor)
-
-class IFilePath(Interface):
- """
- File path object.
-
- A file path represents a location for a file-like-object and can be
- organized into a hierarchy; a file path can can children which are
- themselves file paths.
-
- A file path has a name which unique identifies it in the context of its
- parent (if it has one); a file path can not have two children with the same
- name. This name is referred to as the file path's "base name".
-
- A series of such names can be used to locate nested children of a file path;
- such a series is referred to as the child's "path", relative to the parent.
- In this case, each name in the path is referred to as a "path segment"; the
- child's base name is the segment in the path.
-
- When representing a file path as a string, a "path separator" is used to
- delimit the path segments within the string. For a file system path, that
- would be C{os.sep}.
-
- Note that the values of child names may be restricted. For example, a file
- system path will not allow the use of the path separator in a name, and
- certain names (eg. C{"."} and C{".."}) may be reserved or have special
- meanings.
-
- @since: 12.1
- """
- sep = Attribute("The path separator to use in string representations")
-
- def child(name):
- """
- Obtain a direct child of this file path. The child may or may not
- exist.
-
- @param name: the name of a child of this path. C{name} must be a direct
- child of this path and may not contain a path separator.
- @return: the child of this path with the given C{name}.
- @raise InsecurePath: if C{name} describes a file path that is not a
- direct child of this file path.
- """
-
- def open(mode="r"):
- """
- Opens this file path with the given mode.
- @return: a file-like-object.
- @raise Exception: if this file path cannot be opened.
- """
-
- def changed():
- """
- Clear any cached information about the state of this path on disk.
- """
-
- def getsize():
- """
- @return: the size of the file at this file path in bytes.
- @raise Exception: if the size cannot be obtained.
- """
-
- def getModificationTime():
- """
- Retrieve the time of last access from this file.
-
- @return: a number of seconds from the epoch.
- @rtype: float
- """
-
- def getStatusChangeTime():
- """
- Retrieve the time of the last status change for this file.
-
- @return: a number of seconds from the epoch.
- @rtype: float
- """
-
- def getAccessTime():
- """
- Retrieve the time that this file was last accessed.
-
- @return: a number of seconds from the epoch.
- @rtype: float
- """
-
- def exists():
- """
- @return: C{True} if the file at this file path exists, C{False}
- otherwise.
- """
-
- def isdir():
- """
- @return: C{True} if the file at this file path is a directory, C{False}
- otherwise.
- """
-
- def isfile():
- """
- @return: C{True} if the file at this file path is a regular file,
- C{False} otherwise.
- """
-
- def children():
- """
- @return: a sequence of the children of the directory at this file path.
- @raise Exception: if the file at this file path is not a directory.
- """
-
- def basename():
- """
- @return: the base name of this file path.
- """
-
- def parent():
- """
- A file path for the directory containing the file at this file path.
- """
-
- def sibling(name):
- """
- A file path for the directory containing the file at this file path.
- @param name: the name of a sibling of this path. C{name} must be a direct
- sibling of this path and may not contain a path separator.
-
- @return: a sibling file path of this one.
- """
-
-class InsecurePath(Exception):
- """
- Error that is raised when the path provided to FilePath is invalid.
- """
-
-
-
-class LinkError(Exception):
- """
- An error with symlinks - either that there are cyclical symlinks or that
- symlink are not supported on this platform.
- """
-
-
-
-class UnlistableError(OSError):
- """
- An exception which is used to distinguish between errors which mean 'this
- is not a directory you can list' and other, more catastrophic errors.
-
- This error will try to look as much like the original error as possible,
- while still being catchable as an independent type.
-
- @ivar originalException: the actual original exception instance, either an
- L{OSError} or a L{WindowsError}.
- """
- def __init__(self, originalException):
- """
- Create an UnlistableError exception.
-
- @param originalException: an instance of OSError.
- """
- self.__dict__.update(originalException.__dict__)
- self.originalException = originalException
-
-
-
-class _WindowsUnlistableError(UnlistableError, WindowsError):
- """
- This exception is raised on Windows, for compatibility with previous
- releases of FilePath where unportable programs may have done "except
- WindowsError:" around a call to children().
-
- It is private because all application code may portably catch
- L{UnlistableError} instead.
- """
-
-
-
-def _secureEnoughString():
- """
- Create a pseudorandom, 16-character string for use in secure filenames.
- """
- return armor(sha1(randomBytes(64)).digest())[:16]
-
-
-
-class AbstractFilePath(object):
- """
- Abstract implementation of an IFilePath; must be completed by a subclass.
-
- This class primarily exists to provide common implementations of certain
- methods in IFilePath. It is *not* a required parent class for IFilePath
- implementations, just a useful starting point.
- """
-
- def getContent(self):
- fp = self.open()
- try:
- return fp.read()
- finally:
- fp.close()
-
-
- def parents(self):
- """
- @return: an iterator of all the ancestors of this path, from the most
- recent (its immediate parent) to the root of its filesystem.
- """
- path = self
- parent = path.parent()
- # root.parent() == root, so this means "are we the root"
- while path != parent:
- yield parent
- path = parent
- parent = parent.parent()
-
-
- def children(self):
- """
- List the children of this path object.
-
- @raise OSError: If an error occurs while listing the directory. If the
- error is 'serious', meaning that the operation failed due to an access
- violation, exhaustion of some kind of resource (file descriptors or
- memory), OSError or a platform-specific variant will be raised.
-
- @raise UnlistableError: If the inability to list the directory is due
- to this path not existing or not being a directory, the more specific
- OSError subclass L{UnlistableError} is raised instead.
-
- @return: an iterable of all currently-existing children of this object
- accessible with L{_PathHelper.child}.
- """
- try:
- subnames = self.listdir()
- except WindowsError, winErrObj:
- # WindowsError is an OSError subclass, so if not for this clause
- # the OSError clause below would be handling these. Windows error
- # codes aren't the same as POSIX error codes, so we need to handle
- # them differently.
-
- # Under Python 2.5 on Windows, WindowsError has a winerror
- # attribute and an errno attribute. The winerror attribute is
- # bound to the Windows error code while the errno attribute is
- # bound to a translation of that code to a perhaps equivalent POSIX
- # error number.
-
- # Under Python 2.4 on Windows, WindowsError only has an errno
- # attribute. It is bound to the Windows error code.
-
- # For simplicity of code and to keep the number of paths through
- # this suite minimal, we grab the Windows error code under either
- # version.
-
- # Furthermore, attempting to use os.listdir on a non-existent path
- # in Python 2.4 will result in a Windows error code of
- # ERROR_PATH_NOT_FOUND. However, in Python 2.5,
- # ERROR_FILE_NOT_FOUND results instead. -exarkun
- winerror = getattr(winErrObj, 'winerror', winErrObj.errno)
- if winerror not in (ERROR_PATH_NOT_FOUND,
- ERROR_FILE_NOT_FOUND,
- ERROR_INVALID_NAME,
- ERROR_DIRECTORY):
- raise
- raise _WindowsUnlistableError(winErrObj)
- except OSError, ose:
- if ose.errno not in (errno.ENOENT, errno.ENOTDIR):
- # Other possible errors here, according to linux manpages:
- # EACCES, EMIFLE, ENFILE, ENOMEM. None of these seem like the
- # sort of thing which should be handled normally. -glyph
- raise
- raise UnlistableError(ose)
- return map(self.child, subnames)
-
- def walk(self, descend=None):
- """
- Yield myself, then each of my children, and each of those children's
- children in turn. The optional argument C{descend} is a predicate that
- takes a FilePath, and determines whether or not that FilePath is
- traversed/descended into. It will be called with each path for which
- C{isdir} returns C{True}. If C{descend} is not specified, all
- directories will be traversed (including symbolic links which refer to
- directories).
-
- @param descend: A one-argument callable that will return True for
- FilePaths that should be traversed, False otherwise.
-
- @return: a generator yielding FilePath-like objects.
- """
- yield self
- if self.isdir():
- for c in self.children():
- # we should first see if it's what we want, then we
- # can walk through the directory
- if (descend is None or descend(c)):
- for subc in c.walk(descend):
- if os.path.realpath(self.path).startswith(
- os.path.realpath(subc.path)):
- raise LinkError("Cycle in file graph.")
- yield subc
- else:
- yield c
-
-
- def sibling(self, path):
- """
- Return a L{FilePath} with the same directory as this instance but with a
- basename of C{path}.
-
- @param path: The basename of the L{FilePath} to return.
- @type path: C{str}
-
- @rtype: L{FilePath}
- """
- return self.parent().child(path)
-
-
- def descendant(self, segments):
- """
- Retrieve a child or child's child of this path.
-
- @param segments: A sequence of path segments as C{str} instances.
-
- @return: A L{FilePath} constructed by looking up the C{segments[0]}
- child of this path, the C{segments[1]} child of that path, and so
- on.
-
- @since: 10.2
- """
- path = self
- for name in segments:
- path = path.child(name)
- return path
-
-
- def segmentsFrom(self, ancestor):
- """
- Return a list of segments between a child and its ancestor.
-
- For example, in the case of a path X representing /a/b/c/d and a path Y
- representing /a/b, C{Y.segmentsFrom(X)} will return C{['c',
- 'd']}.
-
- @param ancestor: an instance of the same class as self, ostensibly an
- ancestor of self.
-
- @raise: ValueError if the 'ancestor' parameter is not actually an
- ancestor, i.e. a path for /x/y/z is passed as an ancestor for /a/b/c/d.
-
- @return: a list of strs
- """
- # this might be an unnecessarily inefficient implementation but it will
- # work on win32 and for zipfiles; later I will deterimine if the
- # obvious fast implemenation does the right thing too
- f = self
- p = f.parent()
- segments = []
- while f != ancestor and p != f:
- segments[0:0] = [f.basename()]
- f = p
- p = p.parent()
- if f == ancestor and segments:
- return segments
- raise ValueError("%r not parent of %r" % (ancestor, self))
-
-
- # new in 8.0
- def __hash__(self):
- """
- Hash the same as another FilePath with the same path as mine.
- """
- return hash((self.__class__, self.path))
-
-
- # pending deprecation in 8.0
- def getmtime(self):
- """
- Deprecated. Use getModificationTime instead.
- """
- return int(self.getModificationTime())
-
-
- def getatime(self):
- """
- Deprecated. Use getAccessTime instead.
- """
- return int(self.getAccessTime())
-
-
- def getctime(self):
- """
- Deprecated. Use getStatusChangeTime instead.
- """
- return int(self.getStatusChangeTime())
-
-
-
-class RWX(FancyEqMixin, object):
- """
- A class representing read/write/execute permissions for a single user
- category (i.e. user/owner, group, or other/world). Instantiate with
- three boolean values: readable? writable? executable?.
-
- @type read: C{bool}
- @ivar read: Whether permission to read is given
-
- @type write: C{bool}
- @ivar write: Whether permission to write is given
-
- @type execute: C{bool}
- @ivar execute: Whether permission to execute is given
-
- @since: 11.1
- """
- compareAttributes = ('read', 'write', 'execute')
- def __init__(self, readable, writable, executable):
- self.read = readable
- self.write = writable
- self.execute = executable
-
-
- def __repr__(self):
- return "RWX(read=%s, write=%s, execute=%s)" % (
- self.read, self.write, self.execute)
-
-
- def shorthand(self):
- """
- Returns a short string representing the permission bits. Looks like
- part of what is printed by command line utilities such as 'ls -l'
- (e.g. 'rwx')
- """
- returnval = ['r', 'w', 'x']
- i = 0
- for val in (self.read, self.write, self.execute):
- if not val:
- returnval[i] = '-'
- i += 1
- return ''.join(returnval)
-
-
-
-class Permissions(FancyEqMixin, object):
- """
- A class representing read/write/execute permissions. Instantiate with any
- portion of the file's mode that includes the permission bits.
-
- @type user: L{RWX}
- @ivar user: User/Owner permissions
-
- @type group: L{RWX}
- @ivar group: Group permissions
-
- @type other: L{RWX}
- @ivar other: Other/World permissions
-
- @since: 11.1
- """
-
- compareAttributes = ('user', 'group', 'other')
-
- def __init__(self, statModeInt):
- self.user, self.group, self.other = (
- [RWX(*[statModeInt & bit > 0 for bit in bitGroup]) for bitGroup in
- [[S_IRUSR, S_IWUSR, S_IXUSR],
- [S_IRGRP, S_IWGRP, S_IXGRP],
- [S_IROTH, S_IWOTH, S_IXOTH]]]
- )
-
-
- def __repr__(self):
- return "[%s | %s | %s]" % (
- str(self.user), str(self.group), str(self.other))
-
-
- def shorthand(self):
- """
- Returns a short string representing the permission bits. Looks like
- what is printed by command line utilities such as 'ls -l'
- (e.g. 'rwx-wx--x')
- """
- return "".join(
- [x.shorthand() for x in (self.user, self.group, self.other)])
-
-
-
-class FilePath(AbstractFilePath):
- """
- I am a path on the filesystem that only permits 'downwards' access.
-
- Instantiate me with a pathname (for example,
- FilePath('/home/myuser/public_html')) and I will attempt to only provide
- access to files which reside inside that path. I may be a path to a file,
- a directory, or a file which does not exist.
-
- The correct way to use me is to instantiate me, and then do ALL filesystem
- access through me. In other words, do not import the 'os' module; if you
- need to open a file, call my 'open' method. If you need to list a
- directory, call my 'path' method.
-
- Even if you pass me a relative path, I will convert that to an absolute
- path internally.
-
- Note: although time-related methods do return floating-point results, they
- may still be only second resolution depending on the platform and the last
- value passed to L{os.stat_float_times}. If you want greater-than-second
- precision, call C{os.stat_float_times(True)}, or use Python 2.5.
- Greater-than-second precision is only available in Windows on Python2.5 and
- later.
-
- @type alwaysCreate: C{bool}
- @ivar alwaysCreate: When opening this file, only succeed if the file does
- not already exist.
-
- @type path: C{str}
- @ivar path: The path from which 'downward' traversal is permitted.
-
- @ivar statinfo: The currently cached status information about the file on
- the filesystem that this L{FilePath} points to. This attribute is
- C{None} if the file is in an indeterminate state (either this
- L{FilePath} has not yet had cause to call C{stat()} yet or
- L{FilePath.changed} indicated that new information is required), 0 if
- C{stat()} was called and returned an error (i.e. the path did not exist
- when C{stat()} was called), or a C{stat_result} object that describes
- the last known status of the underlying file (or directory, as the case
- may be). Trust me when I tell you that you do not want to use this
- attribute. Instead, use the methods on L{FilePath} which give you
- information about it, like C{getsize()}, C{isdir()},
- C{getModificationTime()}, and so on.
- @type statinfo: C{int} or L{types.NoneType} or L{os.stat_result}
- """
-
- implements(IFilePath)
-
- statinfo = None
- path = None
-
- sep = slash
-
- def __init__(self, path, alwaysCreate=False):
- """
- Convert a path string to an absolute path if necessary and initialize
- the L{FilePath} with the result.
- """
- self.path = abspath(path)
- self.alwaysCreate = alwaysCreate
-
- def __getstate__(self):
- """
- Support serialization by discarding cached L{os.stat} results and
- returning everything else.
- """
- d = self.__dict__.copy()
- if 'statinfo' in d:
- del d['statinfo']
- return d
-
-
- def child(self, path):
- """
- Create and return a new L{FilePath} representing a path contained by
- C{self}.
-
- @param path: The base name of the new L{FilePath}. If this contains
- directory separators or parent references it will be rejected.
- @type path: C{str}
-
- @raise InsecurePath: If the result of combining this path with C{path}
- would result in a path which is not a direct child of this path.
- """
- if platform.isWindows() and path.count(":"):
- # Catch paths like C:blah that don't have a slash
- raise InsecurePath("%r contains a colon." % (path,))
- norm = normpath(path)
- if self.sep in norm:
- raise InsecurePath("%r contains one or more directory separators" % (path,))
- newpath = abspath(joinpath(self.path, norm))
- if not newpath.startswith(self.path):
- raise InsecurePath("%r is not a child of %s" % (newpath, self.path))
- return self.clonePath(newpath)
-
-
- def preauthChild(self, path):
- """
- Use me if `path' might have slashes in it, but you know they're safe.
-
- (NOT slashes at the beginning. It still needs to be a _child_).
- """
- newpath = abspath(joinpath(self.path, normpath(path)))
- if not newpath.startswith(self.path):
- raise InsecurePath("%s is not a child of %s" % (newpath, self.path))
- return self.clonePath(newpath)
-
- def childSearchPreauth(self, *paths):
- """Return my first existing child with a name in 'paths'.
-
- paths is expected to be a list of *pre-secured* path fragments; in most
- cases this will be specified by a system administrator and not an
- arbitrary user.
-
- If no appropriately-named children exist, this will return None.
- """
- p = self.path
- for child in paths:
- jp = joinpath(p, child)
- if exists(jp):
- return self.clonePath(jp)
-
- def siblingExtensionSearch(self, *exts):
- """Attempt to return a path with my name, given multiple possible
- extensions.
-
- Each extension in exts will be tested and the first path which exists
- will be returned. If no path exists, None will be returned. If '' is
- in exts, then if the file referred to by this path exists, 'self' will
- be returned.
-
- The extension '*' has a magic meaning, which means "any path that
- begins with self.path+'.' is acceptable".
- """
- p = self.path
- for ext in exts:
- if not ext and self.exists():
- return self
- if ext == '*':
- basedot = basename(p)+'.'
- for fn in listdir(dirname(p)):
- if fn.startswith(basedot):
- return self.clonePath(joinpath(dirname(p), fn))
- p2 = p + ext
- if exists(p2):
- return self.clonePath(p2)
-
-
- def realpath(self):
- """
- Returns the absolute target as a FilePath if self is a link, self
- otherwise. The absolute link is the ultimate file or directory the
- link refers to (for instance, if the link refers to another link, and
- another...). If the filesystem does not support symlinks, or
- if the link is cyclical, raises a LinkError.
-
- Behaves like L{os.path.realpath} in that it does not resolve link
- names in the middle (ex. /x/y/z, y is a link to w - realpath on z
- will return /x/y/z, not /x/w/z).
-
- @return: FilePath of the target path
- @raises LinkError: if links are not supported or links are cyclical.
- """
- if self.islink():
- result = os.path.realpath(self.path)
- if result == self.path:
- raise LinkError("Cyclical link - will loop forever")
- return self.clonePath(result)
- return self
-
-
- def siblingExtension(self, ext):
- return self.clonePath(self.path+ext)
-
-
- def linkTo(self, linkFilePath):
- """
- Creates a symlink to self to at the path in the L{FilePath}
- C{linkFilePath}. Only works on posix systems due to its dependence on
- C{os.symlink}. Propagates C{OSError}s up from C{os.symlink} if
- C{linkFilePath.parent()} does not exist, or C{linkFilePath} already
- exists.
-
- @param linkFilePath: a FilePath representing the link to be created
- @type linkFilePath: L{FilePath}
- """
- os.symlink(self.path, linkFilePath.path)
-
-
- def open(self, mode='r'):
- """
- Open this file using C{mode} or for writing if C{alwaysCreate} is
- C{True}.
-
- In all cases the file is opened in binary mode, so it is not necessary
- to include C{b} in C{mode}.
-
- @param mode: The mode to open the file in. Default is C{r}.
- @type mode: C{str}
- @raises AssertionError: If C{a} is included in the mode and
- C{alwaysCreate} is C{True}.
- @rtype: C{file}
- @return: An open C{file} object.
- """
- if self.alwaysCreate:
- assert 'a' not in mode, ("Appending not supported when "
- "alwaysCreate == True")
- return self.create()
- # This hack is necessary because of a bug in Python 2.7 on Windows:
- # http://bugs.python.org/issue7686
- mode = mode.replace('b', '')
- return open(self.path, mode + 'b')
-
- # stat methods below
-
- def restat(self, reraise=True):
- """
- Re-calculate cached effects of 'stat'. To refresh information on this path
- after you know the filesystem may have changed, call this method.
-
- @param reraise: a boolean. If true, re-raise exceptions from
- L{os.stat}; otherwise, mark this path as not existing, and remove any
- cached stat information.
-
- @raise Exception: is C{reraise} is C{True} and an exception occurs while
- reloading metadata.
- """
- try:
- self.statinfo = stat(self.path)
- except OSError:
- self.statinfo = 0
- if reraise:
- raise
-
-
- def changed(self):
- """
- Clear any cached information about the state of this path on disk.
-
- @since: 10.1.0
- """
- self.statinfo = None
-
-
- def chmod(self, mode):
- """
- Changes the permissions on self, if possible. Propagates errors from
- C{os.chmod} up.
-
- @param mode: integer representing the new permissions desired (same as
- the command line chmod)
- @type mode: C{int}
- """
- os.chmod(self.path, mode)
-
-
- def getsize(self):
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return st.st_size
-
-
- def getModificationTime(self):
- """
- Retrieve the time of last access from this file.
-
- @return: a number of seconds from the epoch.
- @rtype: float
- """
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return float(st.st_mtime)
-
-
- def getStatusChangeTime(self):
- """
- Retrieve the time of the last status change for this file.
-
- @return: a number of seconds from the epoch.
- @rtype: float
- """
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return float(st.st_ctime)
-
-
- def getAccessTime(self):
- """
- Retrieve the time that this file was last accessed.
-
- @return: a number of seconds from the epoch.
- @rtype: float
- """
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return float(st.st_atime)
-
-
- def getInodeNumber(self):
- """
- Retrieve the file serial number, also called inode number, which
- distinguishes this file from all other files on the same device.
-
- @raise: NotImplementedError if the platform is Windows, since the
- inode number would be a dummy value for all files in Windows
- @return: a number representing the file serial number
- @rtype: C{long}
- @since: 11.0
- """
- if platform.isWindows():
- raise NotImplementedError
-
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return long(st.st_ino)
-
-
- def getDevice(self):
- """
- Retrieves the device containing the file. The inode number and device
- number together uniquely identify the file, but the device number is
- not necessarily consistent across reboots or system crashes.
-
- @raise: NotImplementedError if the platform is Windows, since the
- device number would be 0 for all partitions on a Windows
- platform
- @return: a number representing the device
- @rtype: C{long}
- @since: 11.0
- """
- if platform.isWindows():
- raise NotImplementedError
-
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return long(st.st_dev)
-
-
- def getNumberOfHardLinks(self):
- """
- Retrieves the number of hard links to the file. This count keeps
- track of how many directories have entries for this file. If the
- count is ever decremented to zero then the file itself is discarded
- as soon as no process still holds it open. Symbolic links are not
- counted in the total.
-
- @raise: NotImplementedError if the platform is Windows, since Windows
- doesn't maintain a link count for directories, and os.stat
- does not set st_nlink on Windows anyway.
- @return: the number of hard links to the file
- @rtype: C{int}
- @since: 11.0
- """
- if platform.isWindows():
- raise NotImplementedError
-
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return int(st.st_nlink)
-
-
- def getUserID(self):
- """
- Returns the user ID of the file's owner.
-
- @raise: NotImplementedError if the platform is Windows, since the UID
- is always 0 on Windows
- @return: the user ID of the file's owner
- @rtype: C{int}
- @since: 11.0
- """
- if platform.isWindows():
- raise NotImplementedError
-
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return int(st.st_uid)
-
-
- def getGroupID(self):
- """
- Returns the group ID of the file.
-
- @raise: NotImplementedError if the platform is Windows, since the GID
- is always 0 on windows
- @return: the group ID of the file
- @rtype: C{int}
- @since: 11.0
- """
- if platform.isWindows():
- raise NotImplementedError
-
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return int(st.st_gid)
-
-
- def getPermissions(self):
- """
- Returns the permissions of the file. Should also work on Windows,
- however, those permissions may not what is expected in Windows.
-
- @return: the permissions for the file
- @rtype: L{Permissions}
- @since: 11.1
- """
- st = self.statinfo
- if not st:
- self.restat()
- st = self.statinfo
- return Permissions(S_IMODE(st.st_mode))
-
-
- def exists(self):
- """
- Check if this L{FilePath} exists.
-
- @return: C{True} if the stats of C{path} can be retrieved successfully,
- C{False} in the other cases.
- @rtype: C{bool}
- """
- if self.statinfo:
- return True
- else:
- self.restat(False)
- if self.statinfo:
- return True
- else:
- return False
-
-
- def isdir(self):
- """
- @return: C{True} if this L{FilePath} refers to a directory, C{False}
- otherwise.
- """
- st = self.statinfo
- if not st:
- self.restat(False)
- st = self.statinfo
- if not st:
- return False
- return S_ISDIR(st.st_mode)
-
-
- def isfile(self):
- """
- @return: C{True} if this L{FilePath} points to a regular file (not a
- directory, socket, named pipe, etc), C{False} otherwise.
- """
- st = self.statinfo
- if not st:
- self.restat(False)
- st = self.statinfo
- if not st:
- return False
- return S_ISREG(st.st_mode)
-
-
- def isBlockDevice(self):
- """
- Returns whether the underlying path is a block device.
-
- @return: C{True} if it is a block device, C{False} otherwise
- @rtype: C{bool}
- @since: 11.1
- """
- st = self.statinfo
- if not st:
- self.restat(False)
- st = self.statinfo
- if not st:
- return False
- return S_ISBLK(st.st_mode)
-
-
- def isSocket(self):
- """
- Returns whether the underlying path is a socket.
-
- @return: C{True} if it is a socket, C{False} otherwise
- @rtype: C{bool}
- @since: 11.1
- """
- st = self.statinfo
- if not st:
- self.restat(False)
- st = self.statinfo
- if not st:
- return False
- return S_ISSOCK(st.st_mode)
-
-
- def islink(self):
- """
- @return: C{True} if this L{FilePath} points to a symbolic link.
- """
- # We can't use cached stat results here, because that is the stat of
- # the destination - (see #1773) which in *every case* but this one is
- # the right thing to use. We could call lstat here and use that, but
- # it seems unlikely we'd actually save any work that way. -glyph
- return islink(self.path)
-
-
- def isabs(self):
- """
- @return: C{True}, always.
- """
- return isabs(self.path)
-
-
- def listdir(self):
- """
- List the base names of the direct children of this L{FilePath}.
-
- @return: a C{list} of C{str} giving the names of the contents of the
- directory this L{FilePath} refers to. These names are relative to
- this L{FilePath}.
-
- @raise: Anything the platform C{os.listdir} implementation might raise
- (typically OSError).
- """
- return listdir(self.path)
-
-
- def splitext(self):
- """
- @return: tuple where the first item is the filename and second item is
- the file extension. See Python docs for C{os.path.splitext}
- """
- return splitext(self.path)
-
-
- def __repr__(self):
- return 'FilePath(%r)' % (self.path,)
-
-
- def touch(self):
- """
- Updates the access and last modification times of the file at this
- file path to the current time. Also creates the file if it does not
- already exist.
-
- @raise Exception: if unable to create or modify the last modification
- time of the file.
- """
- try:
- self.open('a').close()
- except IOError:
- pass
- utime(self.path, None)
-
-
- def remove(self):
- """
- Removes the file or directory that is represented by self. If
- C{self.path} is a directory, recursively remove all its children
- before removing the directory. If it's a file or link, just delete it.
- """
- if self.isdir() and not self.islink():
- for child in self.children():
- child.remove()
- os.rmdir(self.path)
- else:
- os.remove(self.path)
- self.changed()
-
-
- def makedirs(self):
- """
- Create all directories not yet existing in C{path} segments, using
- C{os.makedirs}.
- """
- return os.makedirs(self.path)
-
-
- def globChildren(self, pattern):
- """
- Assuming I am representing a directory, return a list of
- FilePaths representing my children that match the given
- pattern.
- """
- import glob
- path = self.path[-1] == '/' and self.path + pattern or self.sep.join([self.path, pattern])
- return map(self.clonePath, glob.glob(path))
-
-
- def basename(self):
- """
- @return: The final component of the L{FilePath}'s path (Everything after
- the final path separator).
- @rtype: C{str}
- """
- return basename(self.path)
-
-
- def dirname(self):
- """
- @return: All of the components of the L{FilePath}'s path except the last
- one (everything up to the final path separator).
- @rtype: C{str}
- """
- return dirname(self.path)
-
-
- def parent(self):
- """
- @return: A L{FilePath} representing the path which directly contains
- this L{FilePath}.
- """
- return self.clonePath(self.dirname())
-
-
- def setContent(self, content, ext='.new'):
- """
- Replace the file at this path with a new file that contains the given
- bytes, trying to avoid data-loss in the meanwhile.
-
- On UNIX-like platforms, this method does its best to ensure that by the
- time this method returns, either the old contents I{or} the new contents
- of the file will be present at this path for subsequent readers
- regardless of premature device removal, program crash, or power loss,
- making the following assumptions:
-
- - your filesystem is journaled (i.e. your filesystem will not
- I{itself} lose data due to power loss)
-
- - your filesystem's C{rename()} is atomic
-
- - your filesystem will not discard new data while preserving new
- metadata (see U{http://mjg59.livejournal.com/108257.html} for more
- detail)
-
- On most versions of Windows there is no atomic C{rename()} (see
- U{http://bit.ly/win32-overwrite} for more information), so this method
- is slightly less helpful. There is a small window where the file at
- this path may be deleted before the new file is moved to replace it:
- however, the new file will be fully written and flushed beforehand so in
- the unlikely event that there is a crash at that point, it should be
- possible for the user to manually recover the new version of their data.
- In the future, Twisted will support atomic file moves on those versions
- of Windows which I{do} support them: see U{Twisted ticket
- 3004<http://twistedmatrix.com/trac/ticket/3004>}.
-
- This method should be safe for use by multiple concurrent processes, but
- note that it is not easy to predict which process's contents will
- ultimately end up on disk if they invoke this method at close to the
- same time.
-
- @param content: The desired contents of the file at this path.
-
- @type content: L{str}
-
- @param ext: An extension to append to the temporary filename used to
- store the bytes while they are being written. This can be used to
- make sure that temporary files can be identified by their suffix,
- for cleanup in case of crashes.
-
- @type ext: C{str}
- """
- sib = self.temporarySibling(ext)
- f = sib.open('w')
- try:
- f.write(content)
- finally:
- f.close()
- if platform.isWindows() and exists(self.path):
- os.unlink(self.path)
- os.rename(sib.path, self.path)
-
-
- def __cmp__(self, other):
- if not isinstance(other, FilePath):
- return NotImplemented
- return cmp(self.path, other.path)
-
-
- def createDirectory(self):
- """
- Create the directory the L{FilePath} refers to.
-
- @see: L{makedirs}
-
- @raise OSError: If the directory cannot be created.
- """
- os.mkdir(self.path)
-
-
- def requireCreate(self, val=1):
- self.alwaysCreate = val
-
-
- def create(self):
- """
- Exclusively create a file, only if this file previously did not exist.
- """
- fdint = os.open(self.path, _CREATE_FLAGS)
-
- # XXX TODO: 'name' attribute of returned files is not mutable or
- # settable via fdopen, so this file is slighly less functional than the
- # one returned from 'open' by default. send a patch to Python...
-
- return os.fdopen(fdint, 'w+b')
-
-
- def temporarySibling(self, extension=""):
- """
- Construct a path referring to a sibling of this path.
-
- The resulting path will be unpredictable, so that other subprocesses
- should neither accidentally attempt to refer to the same path before it
- is created, nor they should other processes be able to guess its name in
- advance.
-
- @param extension: A suffix to append to the created filename. (Note
- that if you want an extension with a '.' you must include the '.'
- yourself.)
-
- @type extension: C{str}
-
- @return: a path object with the given extension suffix, C{alwaysCreate}
- set to True.
-
- @rtype: L{FilePath}
- """
- sib = self.sibling(_secureEnoughString() + self.basename() + extension)
- sib.requireCreate()
- return sib
-
-
- _chunkSize = 2 ** 2 ** 2 ** 2
-
- def copyTo(self, destination, followLinks=True):
- """
- Copies self to destination.
-
- If self doesn't exist, an OSError is raised.
-
- If self is a directory, this method copies its children (but not
- itself) recursively to destination - if destination does not exist as a
- directory, this method creates it. If destination is a file, an
- IOError will be raised.
-
- If self is a file, this method copies it to destination. If
- destination is a file, this method overwrites it. If destination is a
- directory, an IOError will be raised.
-
- If self is a link (and followLinks is False), self will be copied
- over as a new symlink with the same target as returned by os.readlink.
- That means that if it is absolute, both the old and new symlink will
- link to the same thing. If it's relative, then perhaps not (and
- it's also possible that this relative link will be broken).
-
- File/directory permissions and ownership will NOT be copied over.
-
- If followLinks is True, symlinks are followed so that they're treated
- as their targets. In other words, if self is a link, the link's target
- will be copied. If destination is a link, self will be copied to the
- destination's target (the actual destination will be destination's
- target). Symlinks under self (if self is a directory) will be
- followed and its target's children be copied recursively.
-
- If followLinks is False, symlinks will be copied over as symlinks.
-
- @param destination: the destination (a FilePath) to which self
- should be copied
- @param followLinks: whether symlinks in self should be treated as links
- or as their targets
- """
- if self.islink() and not followLinks:
- os.symlink(os.readlink(self.path), destination.path)
- return
- # XXX TODO: *thorough* audit and documentation of the exact desired
- # semantics of this code. Right now the behavior of existent
- # destination symlinks is convenient, and quite possibly correct, but
- # its security properties need to be explained.
- if self.isdir():
- if not destination.exists():
- destination.createDirectory()
- for child in self.children():
- destChild = destination.child(child.basename())
- child.copyTo(destChild, followLinks)
- elif self.isfile():
- writefile = destination.open('w')
- try:
- readfile = self.open()
- try:
- while 1:
- # XXX TODO: optionally use os.open, os.read and O_DIRECT
- # and use os.fstatvfs to determine chunk sizes and make
- # *****sure**** copy is page-atomic; the following is
- # good enough for 99.9% of everybody and won't take a
- # week to audit though.
- chunk = readfile.read(self._chunkSize)
- writefile.write(chunk)
- if len(chunk) < self._chunkSize:
- break
- finally:
- readfile.close()
- finally:
- writefile.close()
- elif not self.exists():
- raise OSError(errno.ENOENT, "No such file or directory")
- else:
- # If you see the following message because you want to copy
- # symlinks, fifos, block devices, character devices, or unix
- # sockets, please feel free to add support to do sensible things in
- # reaction to those types!
- raise NotImplementedError(
- "Only copying of files and directories supported")
-
-
- def moveTo(self, destination, followLinks=True):
- """
- Move self to destination - basically renaming self to whatever
- destination is named. If destination is an already-existing directory,
- moves all children to destination if destination is empty. If
- destination is a non-empty directory, or destination is a file, an
- OSError will be raised.
-
- If moving between filesystems, self needs to be copied, and everything
- that applies to copyTo applies to moveTo.
-
- @param destination: the destination (a FilePath) to which self
- should be copied
- @param followLinks: whether symlinks in self should be treated as links
- or as their targets (only applicable when moving between
- filesystems)
- """
- try:
- os.rename(self.path, destination.path)
- except OSError, ose:
- if ose.errno == errno.EXDEV:
- # man 2 rename, ubuntu linux 5.10 "breezy":
-
- # oldpath and newpath are not on the same mounted filesystem.
- # (Linux permits a filesystem to be mounted at multiple
- # points, but rename(2) does not work across different mount
- # points, even if the same filesystem is mounted on both.)
-
- # that means it's time to copy trees of directories!
- secsib = destination.temporarySibling()
- self.copyTo(secsib, followLinks) # slow
- secsib.moveTo(destination, followLinks) # visible
-
- # done creating new stuff. let's clean me up.
- mysecsib = self.temporarySibling()
- self.moveTo(mysecsib, followLinks) # visible
- mysecsib.remove() # slow
- else:
- raise
- else:
- self.changed()
- destination.changed()
-
-
-FilePath.clonePath = FilePath
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/finalize.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/finalize.py
deleted file mode 100755
index 8b99bf6a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/finalize.py
+++ /dev/null
@@ -1,46 +0,0 @@
-
-"""
-A module for externalized finalizers.
-"""
-
-import weakref
-
-garbageKey = 0
-
-def callbackFactory(num, fins):
- def _cb(w):
- del refs[num]
- for fx in fins:
- fx()
- return _cb
-
-refs = {}
-
-def register(inst):
- global garbageKey
- garbageKey += 1
- r = weakref.ref(inst, callbackFactory(garbageKey, inst.__finalizers__()))
- refs[garbageKey] = r
-
-if __name__ == '__main__':
- def fin():
- print 'I am _so_ dead.'
-
- class Finalizeable:
- """
- An un-sucky __del__
- """
-
- def __finalizers__(self):
- """
- I'm going away.
- """
- return [fin]
-
- f = Finalizeable()
- f.f2 = f
- register(f)
- del f
- import gc
- gc.collect()
- print 'deled'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/formmethod.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/formmethod.py
deleted file mode 100755
index b4d905e5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/formmethod.py
+++ /dev/null
@@ -1,363 +0,0 @@
-# -*- test-case-name: twisted.test.test_formmethod -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Form-based method objects.
-
-This module contains support for descriptive method signatures that can be used
-to format methods.
-"""
-
-import calendar
-
-class FormException(Exception):
- """An error occurred calling the form method.
- """
- def __init__(self, *args, **kwargs):
- Exception.__init__(self, *args)
- self.descriptions = kwargs
-
-
-class InputError(FormException):
- """
- An error occurred with some input.
- """
-
-
-class Argument:
- """Base class for form arguments."""
-
- # default value for argument, if no other default is given
- defaultDefault = None
-
- def __init__(self, name, default=None, shortDesc=None,
- longDesc=None, hints=None, allowNone=1):
- self.name = name
- self.allowNone = allowNone
- if default is None:
- default = self.defaultDefault
- self.default = default
- self.shortDesc = shortDesc
- self.longDesc = longDesc
- if not hints:
- hints = {}
- self.hints = hints
-
- def addHints(self, **kwargs):
- self.hints.update(kwargs)
-
- def getHint(self, name, default=None):
- return self.hints.get(name, default)
-
- def getShortDescription(self):
- return self.shortDesc or self.name.capitalize()
-
- def getLongDescription(self):
- return self.longDesc or '' #self.shortDesc or "The %s." % self.name
-
- def coerce(self, val):
- """Convert the value to the correct format."""
- raise NotImplementedError("implement in subclass")
-
-
-class String(Argument):
- """A single string.
- """
- defaultDefault = ''
- min = 0
- max = None
-
- def __init__(self, name, default=None, shortDesc=None,
- longDesc=None, hints=None, allowNone=1, min=0, max=None):
- Argument.__init__(self, name, default=default, shortDesc=shortDesc,
- longDesc=longDesc, hints=hints, allowNone=allowNone)
- self.min = min
- self.max = max
-
- def coerce(self, val):
- s = str(val)
- if len(s) < self.min:
- raise InputError("Value must be at least %s characters long" % self.min)
- if self.max != None and len(s) > self.max:
- raise InputError("Value must be at most %s characters long" % self.max)
- return str(val)
-
-
-class Text(String):
- """A long string.
- """
-
-
-class Password(String):
- """A string which should be obscured when input.
- """
-
-
-class VerifiedPassword(String):
- """A string that should be obscured when input and needs verification."""
-
- def coerce(self, vals):
- if len(vals) != 2 or vals[0] != vals[1]:
- raise InputError("Please enter the same password twice.")
- s = str(vals[0])
- if len(s) < self.min:
- raise InputError("Value must be at least %s characters long" % self.min)
- if self.max != None and len(s) > self.max:
- raise InputError("Value must be at most %s characters long" % self.max)
- return s
-
-
-class Hidden(String):
- """A string which is not displayed.
-
- The passed default is used as the value.
- """
-
-
-class Integer(Argument):
- """A single integer.
- """
- defaultDefault = None
-
- def __init__(self, name, allowNone=1, default=None, shortDesc=None,
- longDesc=None, hints=None):
- #although Argument now has allowNone, that was recently added, and
- #putting it at the end kept things which relied on argument order
- #from breaking. However, allowNone originally was in here, so
- #I have to keep the same order, to prevent breaking code that
- #depends on argument order only
- Argument.__init__(self, name, default, shortDesc, longDesc, hints,
- allowNone)
-
- def coerce(self, val):
- if not val.strip() and self.allowNone:
- return None
- try:
- return int(val)
- except ValueError:
- raise InputError("%s is not valid, please enter a whole number, e.g. 10" % val)
-
-
-class IntegerRange(Integer):
-
- def __init__(self, name, min, max, allowNone=1, default=None, shortDesc=None,
- longDesc=None, hints=None):
- self.min = min
- self.max = max
- Integer.__init__(self, name, allowNone=allowNone, default=default, shortDesc=shortDesc,
- longDesc=longDesc, hints=hints)
-
- def coerce(self, val):
- result = Integer.coerce(self, val)
- if self.allowNone and result == None:
- return result
- if result < self.min:
- raise InputError("Value %s is too small, it should be at least %s" % (result, self.min))
- if result > self.max:
- raise InputError("Value %s is too large, it should be at most %s" % (result, self.max))
- return result
-
-
-class Float(Argument):
-
- defaultDefault = None
-
- def __init__(self, name, allowNone=1, default=None, shortDesc=None,
- longDesc=None, hints=None):
- #although Argument now has allowNone, that was recently added, and
- #putting it at the end kept things which relied on argument order
- #from breaking. However, allowNone originally was in here, so
- #I have to keep the same order, to prevent breaking code that
- #depends on argument order only
- Argument.__init__(self, name, default, shortDesc, longDesc, hints,
- allowNone)
-
-
- def coerce(self, val):
- if not val.strip() and self.allowNone:
- return None
- try:
- return float(val)
- except ValueError:
- raise InputError("Invalid float: %s" % val)
-
-
-class Choice(Argument):
- """
- The result of a choice between enumerated types. The choices should
- be a list of tuples of tag, value, and description. The tag will be
- the value returned if the user hits "Submit", and the description
- is the bale for the enumerated type. default is a list of all the
- values (seconds element in choices). If no defaults are specified,
- initially the first item will be selected. Only one item can (should)
- be selected at once.
- """
- def __init__(self, name, choices=[], default=[], shortDesc=None,
- longDesc=None, hints=None, allowNone=1):
- self.choices = choices
- if choices and not default:
- default.append(choices[0][1])
- Argument.__init__(self, name, default, shortDesc, longDesc, hints, allowNone=allowNone)
-
- def coerce(self, inIdent):
- for ident, val, desc in self.choices:
- if ident == inIdent:
- return val
- else:
- raise InputError("Invalid Choice: %s" % inIdent)
-
-
-class Flags(Argument):
- """
- The result of a checkbox group or multi-menu. The flags should be a
- list of tuples of tag, value, and description. The tag will be
- the value returned if the user hits "Submit", and the description
- is the bale for the enumerated type. default is a list of all the
- values (second elements in flags). If no defaults are specified,
- initially nothing will be selected. Several items may be selected at
- once.
- """
- def __init__(self, name, flags=(), default=(), shortDesc=None,
- longDesc=None, hints=None, allowNone=1):
- self.flags = flags
- Argument.__init__(self, name, default, shortDesc, longDesc, hints, allowNone=allowNone)
-
- def coerce(self, inFlagKeys):
- if not inFlagKeys:
- return []
- outFlags = []
- for inFlagKey in inFlagKeys:
- for flagKey, flagVal, flagDesc in self.flags:
- if inFlagKey == flagKey:
- outFlags.append(flagVal)
- break
- else:
- raise InputError("Invalid Flag: %s" % inFlagKey)
- return outFlags
-
-
-class CheckGroup(Flags):
- pass
-
-
-class RadioGroup(Choice):
- pass
-
-
-class Boolean(Argument):
- def coerce(self, inVal):
- if not inVal:
- return 0
- lInVal = str(inVal).lower()
- if lInVal in ('no', 'n', 'f', 'false', '0'):
- return 0
- return 1
-
-class File(Argument):
- def __init__(self, name, allowNone=1, shortDesc=None, longDesc=None,
- hints=None):
- Argument.__init__(self, name, None, shortDesc, longDesc, hints,
- allowNone=allowNone)
-
- def coerce(self, file):
- if not file and self.allowNone:
- return None
- elif file:
- return file
- else:
- raise InputError("Invalid File")
-
-def positiveInt(x):
- x = int(x)
- if x <= 0: raise ValueError
- return x
-
-class Date(Argument):
- """A date -- (year, month, day) tuple."""
-
- defaultDefault = None
-
- def __init__(self, name, allowNone=1, default=None, shortDesc=None,
- longDesc=None, hints=None):
- Argument.__init__(self, name, default, shortDesc, longDesc, hints)
- self.allowNone = allowNone
- if not allowNone:
- self.defaultDefault = (1970, 1, 1)
-
- def coerce(self, args):
- """Return tuple of ints (year, month, day)."""
- if tuple(args) == ("", "", "") and self.allowNone:
- return None
-
- try:
- year, month, day = map(positiveInt, args)
- except ValueError:
- raise InputError("Invalid date")
- if (month, day) == (2, 29):
- if not calendar.isleap(year):
- raise InputError("%d was not a leap year" % year)
- else:
- return year, month, day
- try:
- mdays = calendar.mdays[month]
- except IndexError:
- raise InputError("Invalid date")
- if day > mdays:
- raise InputError("Invalid date")
- return year, month, day
-
-
-class Submit(Choice):
- """Submit button or a reasonable facsimile thereof."""
-
- def __init__(self, name, choices=[("Submit", "submit", "Submit form")],
- reset=0, shortDesc=None, longDesc=None, allowNone=0, hints=None):
- Choice.__init__(self, name, choices=choices, shortDesc=shortDesc,
- longDesc=longDesc, hints=hints)
- self.allowNone = allowNone
- self.reset = reset
-
- def coerce(self, value):
- if self.allowNone and not value:
- return None
- else:
- return Choice.coerce(self, value)
-
-
-class PresentationHint:
- """
- A hint to a particular system.
- """
-
-
-class MethodSignature:
-
- def __init__(self, *sigList):
- """
- """
- self.methodSignature = sigList
-
- def getArgument(self, name):
- for a in self.methodSignature:
- if a.name == name:
- return a
-
- def method(self, callable, takesRequest=False):
- return FormMethod(self, callable, takesRequest)
-
-
-class FormMethod:
- """A callable object with a signature."""
-
- def __init__(self, signature, callable, takesRequest=False):
- self.signature = signature
- self.callable = callable
- self.takesRequest = takesRequest
-
- def getArgs(self):
- return tuple(self.signature.methodSignature)
-
- def call(self,*args,**kw):
- return self.callable(*args,**kw)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hashlib.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hashlib.py
deleted file mode 100755
index f3ee0fe0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hashlib.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_hashlib -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-L{twisted.python.hashlib} presents a subset of the interface provided by
-U{hashlib<http://docs.python.org/library/hashlib.html>}. The subset is the
-interface required by various parts of Twisted. This allows application code
-to transparently use APIs which existed before C{hashlib} was introduced or to
-use C{hashlib} if it is available.
-"""
-
-
-try:
- _hashlib = __import__("hashlib")
-except ImportError:
- from md5 import md5
- from sha import sha as sha1
-else:
- md5 = _hashlib.md5
- sha1 = _hashlib.sha1
-
-
-__all__ = ["md5", "sha1"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hook.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hook.py
deleted file mode 100755
index 4142b0a0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/hook.py
+++ /dev/null
@@ -1,176 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-
-"""
-I define support for hookable instance methods.
-
-These are methods which you can register pre-call and post-call external
-functions to augment their functionality. People familiar with more esoteric
-languages may think of these as \"method combinations\".
-
-This could be used to add optional preconditions, user-extensible callbacks
-(a-la emacs) or a thread-safety mechanism.
-
-The four exported calls are:
-
- - L{addPre}
- - L{addPost}
- - L{removePre}
- - L{removePost}
-
-All have the signature (class, methodName, callable), and the callable they
-take must always have the signature (instance, *args, **kw) unless the
-particular signature of the method they hook is known.
-
-Hooks should typically not throw exceptions, however, no effort will be made by
-this module to prevent them from doing so. Pre-hooks will always be called,
-but post-hooks will only be called if the pre-hooks do not raise any exceptions
-(they will still be called if the main method raises an exception). The return
-values and exception status of the main method will be propogated (assuming
-none of the hooks raise an exception). Hooks will be executed in the order in
-which they are added.
-"""
-
-
-### Public Interface
-
-class HookError(Exception):
- "An error which will fire when an invariant is violated."
-
-def addPre(klass, name, func):
- """hook.addPre(klass, name, func) -> None
-
- Add a function to be called before the method klass.name is invoked.
- """
-
- _addHook(klass, name, PRE, func)
-
-def addPost(klass, name, func):
- """hook.addPost(klass, name, func) -> None
-
- Add a function to be called after the method klass.name is invoked.
- """
- _addHook(klass, name, POST, func)
-
-def removePre(klass, name, func):
- """hook.removePre(klass, name, func) -> None
-
- Remove a function (previously registered with addPre) so that it
- is no longer executed before klass.name.
- """
-
- _removeHook(klass, name, PRE, func)
-
-def removePost(klass, name, func):
- """hook.removePre(klass, name, func) -> None
-
- Remove a function (previously registered with addPost) so that it
- is no longer executed after klass.name.
- """
- _removeHook(klass, name, POST, func)
-
-### "Helper" functions.
-
-hooked_func = """
-
-import %(module)s
-
-def %(name)s(*args, **kw):
- klazz = %(module)s.%(klass)s
- for preMethod in klazz.%(preName)s:
- preMethod(*args, **kw)
- try:
- return klazz.%(originalName)s(*args, **kw)
- finally:
- for postMethod in klazz.%(postName)s:
- postMethod(*args, **kw)
-"""
-
-_PRE = '__hook_pre_%s_%s_%s__'
-_POST = '__hook_post_%s_%s_%s__'
-_ORIG = '__hook_orig_%s_%s_%s__'
-
-
-def _XXX(k,n,s):
- """
- String manipulation garbage.
- """
- x = s % (k.__module__.replace('.', '_'), k.__name__, n)
- return x
-
-def PRE(k,n):
- "(private) munging to turn a method name into a pre-hook-method-name"
- return _XXX(k,n,_PRE)
-
-def POST(k,n):
- "(private) munging to turn a method name into a post-hook-method-name"
- return _XXX(k,n,_POST)
-
-def ORIG(k,n):
- "(private) munging to turn a method name into an `original' identifier"
- return _XXX(k,n,_ORIG)
-
-
-def _addHook(klass, name, phase, func):
- "(private) adds a hook to a method on a class"
- _enhook(klass, name)
-
- if not hasattr(klass, phase(klass, name)):
- setattr(klass, phase(klass, name), [])
-
- phaselist = getattr(klass, phase(klass, name))
- phaselist.append(func)
-
-
-def _removeHook(klass, name, phase, func):
- "(private) removes a hook from a method on a class"
- phaselistname = phase(klass, name)
- if not hasattr(klass, ORIG(klass,name)):
- raise HookError("no hooks present!")
-
- phaselist = getattr(klass, phase(klass, name))
- try: phaselist.remove(func)
- except ValueError:
- raise HookError("hook %s not found in removal list for %s"%
- (name,klass))
-
- if not getattr(klass, PRE(klass,name)) and not getattr(klass, POST(klass, name)):
- _dehook(klass, name)
-
-def _enhook(klass, name):
- "(private) causes a certain method name to be hooked on a class"
- if hasattr(klass, ORIG(klass, name)):
- return
-
- def newfunc(*args, **kw):
- for preMethod in getattr(klass, PRE(klass, name)):
- preMethod(*args, **kw)
- try:
- return getattr(klass, ORIG(klass, name))(*args, **kw)
- finally:
- for postMethod in getattr(klass, POST(klass, name)):
- postMethod(*args, **kw)
- try:
- newfunc.func_name = name
- except TypeError:
- # Older python's don't let you do this
- pass
-
- oldfunc = getattr(klass, name).im_func
- setattr(klass, ORIG(klass, name), oldfunc)
- setattr(klass, PRE(klass, name), [])
- setattr(klass, POST(klass, name), [])
- setattr(klass, name, newfunc)
-
-def _dehook(klass, name):
- "(private) causes a certain method name no longer to be hooked on a class"
-
- if not hasattr(klass, ORIG(klass, name)):
- raise HookError("Cannot unhook!")
- setattr(klass, name, getattr(klass, ORIG(klass,name)))
- delattr(klass, PRE(klass,name))
- delattr(klass, POST(klass,name))
- delattr(klass, ORIG(klass,name))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/htmlizer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/htmlizer.py
deleted file mode 100755
index c95fb00b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/htmlizer.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_htmlizer -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-HTML rendering of Python source.
-"""
-
-import tokenize, cgi, keyword
-import reflect
-
-class TokenPrinter:
-
- currentCol, currentLine = 0, 1
- lastIdentifier = parameters = 0
-
- def __init__(self, writer):
- self.writer = writer
-
- def printtoken(self, type, token, (srow, scol), (erow, ecol), line):
- #print "printtoken(%r,%r,%r,(%r,%r),(%r,%r),%r), row=%r,col=%r" % (
- # self, type, token, srow,scol, erow,ecol, line,
- # self.currentLine, self.currentCol)
- if self.currentLine < srow:
- self.writer('\n'*(srow-self.currentLine))
- self.currentLine, self.currentCol = srow, 0
- self.writer(' '*(scol-self.currentCol))
- if self.lastIdentifier:
- type = "identifier"
- self.parameters = 1
- elif type == tokenize.NAME:
- if keyword.iskeyword(token):
- type = 'keyword'
- else:
- if self.parameters:
- type = 'parameter'
- else:
- type = 'variable'
- else:
- type = tokenize.tok_name.get(type).lower()
- self.writer(token, type)
- self.currentCol = ecol
- self.currentLine += token.count('\n')
- if self.currentLine != erow:
- self.currentCol = 0
- self.lastIdentifier = token in ('def', 'class')
- if token == ':':
- self.parameters = 0
-
-
-class HTMLWriter:
-
- noSpan = []
-
- def __init__(self, writer):
- self.writer = writer
- noSpan = []
- reflect.accumulateClassList(self.__class__, "noSpan", noSpan)
- self.noSpan = noSpan
-
- def write(self, token, type=None):
- token = cgi.escape(token)
- if (type is None) or (type in self.noSpan):
- self.writer(token)
- else:
- self.writer('<span class="py-src-%s">%s</span>' %
- (type, token))
-
-
-class SmallerHTMLWriter(HTMLWriter):
- """HTMLWriter that doesn't generate spans for some junk.
-
- Results in much smaller HTML output.
- """
- noSpan = ["endmarker", "indent", "dedent", "op", "newline", "nl"]
-
-def filter(inp, out, writer=HTMLWriter):
- out.write('<pre>')
- printer = TokenPrinter(writer(out.write).write).printtoken
- try:
- tokenize.tokenize(inp.readline, printer)
- except tokenize.TokenError:
- pass
- out.write('</pre>\n')
-
-def main():
- import sys
- filter(open(sys.argv[1]), sys.stdout)
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/lockfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/lockfile.py
deleted file mode 100755
index a0449573..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/lockfile.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# -*- test-case-name: twisted.test.test_lockfile -*-
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Filesystem-based interprocess mutex.
-"""
-
-__metaclass__ = type
-
-import errno, os
-
-from time import time as _uniquefloat
-
-from twisted.python.runtime import platform
-
-def unique():
- return str(long(_uniquefloat() * 1000))
-
-from os import rename
-if not platform.isWindows():
- from os import kill
- from os import symlink
- from os import readlink
- from os import remove as rmlink
- _windows = False
-else:
- _windows = True
-
- try:
- from win32api import OpenProcess
- import pywintypes
- except ImportError:
- kill = None
- else:
- ERROR_ACCESS_DENIED = 5
- ERROR_INVALID_PARAMETER = 87
-
- def kill(pid, signal):
- try:
- OpenProcess(0, 0, pid)
- except pywintypes.error, e:
- if e.args[0] == ERROR_ACCESS_DENIED:
- return
- elif e.args[0] == ERROR_INVALID_PARAMETER:
- raise OSError(errno.ESRCH, None)
- raise
- else:
- raise RuntimeError("OpenProcess is required to fail.")
-
- _open = file
-
- # XXX Implement an atomic thingamajig for win32
- def symlink(value, filename):
- newlinkname = filename+"."+unique()+'.newlink'
- newvalname = os.path.join(newlinkname,"symlink")
- os.mkdir(newlinkname)
- f = _open(newvalname,'wcb')
- f.write(value)
- f.flush()
- f.close()
- try:
- rename(newlinkname, filename)
- except:
- os.remove(newvalname)
- os.rmdir(newlinkname)
- raise
-
- def readlink(filename):
- try:
- fObj = _open(os.path.join(filename,'symlink'), 'rb')
- except IOError, e:
- if e.errno == errno.ENOENT or e.errno == errno.EIO:
- raise OSError(e.errno, None)
- raise
- else:
- result = fObj.read()
- fObj.close()
- return result
-
- def rmlink(filename):
- os.remove(os.path.join(filename, 'symlink'))
- os.rmdir(filename)
-
-
-
-class FilesystemLock:
- """
- A mutex.
-
- This relies on the filesystem property that creating
- a symlink is an atomic operation and that it will
- fail if the symlink already exists. Deleting the
- symlink will release the lock.
-
- @ivar name: The name of the file associated with this lock.
-
- @ivar clean: Indicates whether this lock was released cleanly by its
- last owner. Only meaningful after C{lock} has been called and
- returns True.
-
- @ivar locked: Indicates whether the lock is currently held by this
- object.
- """
-
- clean = None
- locked = False
-
- def __init__(self, name):
- self.name = name
-
-
- def lock(self):
- """
- Acquire this lock.
-
- @rtype: C{bool}
- @return: True if the lock is acquired, false otherwise.
-
- @raise: Any exception os.symlink() may raise, other than
- EEXIST.
- """
- clean = True
- while True:
- try:
- symlink(str(os.getpid()), self.name)
- except OSError, e:
- if _windows and e.errno in (errno.EACCES, errno.EIO):
- # The lock is in the middle of being deleted because we're
- # on Windows where lock removal isn't atomic. Give up, we
- # don't know how long this is going to take.
- return False
- if e.errno == errno.EEXIST:
- try:
- pid = readlink(self.name)
- except OSError, e:
- if e.errno == errno.ENOENT:
- # The lock has vanished, try to claim it in the
- # next iteration through the loop.
- continue
- raise
- except IOError, e:
- if _windows and e.errno == errno.EACCES:
- # The lock is in the middle of being
- # deleted because we're on Windows where
- # lock removal isn't atomic. Give up, we
- # don't know how long this is going to
- # take.
- return False
- raise
- try:
- if kill is not None:
- kill(int(pid), 0)
- except OSError, e:
- if e.errno == errno.ESRCH:
- # The owner has vanished, try to claim it in the next
- # iteration through the loop.
- try:
- rmlink(self.name)
- except OSError, e:
- if e.errno == errno.ENOENT:
- # Another process cleaned up the lock.
- # Race them to acquire it in the next
- # iteration through the loop.
- continue
- raise
- clean = False
- continue
- raise
- return False
- raise
- self.locked = True
- self.clean = clean
- return True
-
-
- def unlock(self):
- """
- Release this lock.
-
- This deletes the directory with the given name.
-
- @raise: Any exception os.readlink() may raise, or
- ValueError if the lock is not owned by this process.
- """
- pid = readlink(self.name)
- if int(pid) != os.getpid():
- raise ValueError("Lock %r not owned by this process" % (self.name,))
- rmlink(self.name)
- self.locked = False
-
-
-def isLocked(name):
- """Determine if the lock of the given name is held or not.
-
- @type name: C{str}
- @param name: The filesystem path to the lock to test
-
- @rtype: C{bool}
- @return: True if the lock is held, False otherwise.
- """
- l = FilesystemLock(name)
- result = None
- try:
- result = l.lock()
- finally:
- if result:
- l.unlock()
- return not result
-
-
-__all__ = ['FilesystemLock', 'isLocked']
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/log.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/log.py
deleted file mode 100755
index d8342e37..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/log.py
+++ /dev/null
@@ -1,627 +0,0 @@
-# -*- test-case-name: twisted.test.test_log -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Logging and metrics infrastructure.
-"""
-
-from __future__ import division
-
-import sys
-import time
-import warnings
-from datetime import datetime
-import logging
-
-from zope.interface import Interface
-
-from twisted.python import util, context, reflect
-
-
-
-class ILogContext:
- """
- Actually, this interface is just a synonym for the dictionary interface,
- but it serves as a key for the default information in a log.
-
- I do not inherit from C{Interface} because the world is a cruel place.
- """
-
-
-
-class ILogObserver(Interface):
- """
- An observer which can do something with log events.
-
- Given that most log observers are actually bound methods, it's okay to not
- explicitly declare provision of this interface.
- """
- def __call__(eventDict):
- """
- Log an event.
-
- @type eventDict: C{dict} with C{str} keys.
- @param eventDict: A dictionary with arbitrary keys. However, these
- keys are often available:
- - C{message}: A C{tuple} of C{str} containing messages to be
- logged.
- - C{system}: A C{str} which indicates the "system" which is
- generating this event.
- - C{isError}: A C{bool} indicating whether this event represents
- an error.
- - C{failure}: A L{failure.Failure} instance
- - C{why}: Used as header of the traceback in case of errors.
- - C{format}: A string format used in place of C{message} to
- customize the event. The intent is for the observer to format
- a message by doing something like C{format % eventDict}.
- """
-
-
-
-context.setDefault(ILogContext,
- {"isError": 0,
- "system": "-"})
-
-def callWithContext(ctx, func, *args, **kw):
- newCtx = context.get(ILogContext).copy()
- newCtx.update(ctx)
- return context.call({ILogContext: newCtx}, func, *args, **kw)
-
-def callWithLogger(logger, func, *args, **kw):
- """
- Utility method which wraps a function in a try:/except:, logs a failure if
- one occurrs, and uses the system's logPrefix.
- """
- try:
- lp = logger.logPrefix()
- except KeyboardInterrupt:
- raise
- except:
- lp = '(buggy logPrefix method)'
- err(system=lp)
- try:
- return callWithContext({"system": lp}, func, *args, **kw)
- except KeyboardInterrupt:
- raise
- except:
- err(system=lp)
-
-
-
-_keepErrors = 0
-_keptErrors = []
-_ignoreErrors = []
-
-
-def err(_stuff=None, _why=None, **kw):
- """
- Write a failure to the log.
-
- The C{_stuff} and C{_why} parameters use an underscore prefix to lessen
- the chance of colliding with a keyword argument the application wishes
- to pass. It is intended that they be supplied with arguments passed
- positionally, not by keyword.
-
- @param _stuff: The failure to log. If C{_stuff} is C{None} a new
- L{Failure} will be created from the current exception state. If
- C{_stuff} is an C{Exception} instance it will be wrapped in a
- L{Failure}.
- @type _stuff: C{NoneType}, C{Exception}, or L{Failure}.
-
- @param _why: The source of this failure. This will be logged along with
- C{_stuff} and should describe the context in which the failure
- occurred.
- @type _why: C{str}
- """
- if _stuff is None:
- _stuff = failure.Failure()
- if isinstance(_stuff, failure.Failure):
- if _keepErrors:
- if _ignoreErrors:
- keep = 0
- for err in _ignoreErrors:
- r = _stuff.check(err)
- if r:
- keep = 0
- break
- else:
- keep = 1
- if keep:
- _keptErrors.append(_stuff)
- else:
- _keptErrors.append(_stuff)
- msg(failure=_stuff, why=_why, isError=1, **kw)
- elif isinstance(_stuff, Exception):
- msg(failure=failure.Failure(_stuff), why=_why, isError=1, **kw)
- else:
- msg(repr(_stuff), why=_why, isError=1, **kw)
-
-deferr = err
-
-
-class Logger:
- """
- This represents a class which may 'own' a log. Used by subclassing.
- """
- def logPrefix(self):
- """
- Override this method to insert custom logging behavior. Its
- return value will be inserted in front of every line. It may
- be called more times than the number of output lines.
- """
- return '-'
-
-
-class LogPublisher:
- """
- Class for singleton log message publishing.
- """
-
- synchronized = ['msg']
-
- def __init__(self):
- self.observers = []
-
- def addObserver(self, other):
- """
- Add a new observer.
-
- @type other: Provider of L{ILogObserver}
- @param other: A callable object that will be called with each new log
- message (a dict).
- """
- assert callable(other)
- self.observers.append(other)
-
- def removeObserver(self, other):
- """
- Remove an observer.
- """
- self.observers.remove(other)
-
- def msg(self, *message, **kw):
- """
- Log a new message.
-
- For example::
-
- >>> log.msg('Hello, world.')
-
- In particular, you MUST avoid the forms::
-
- >>> log.msg(u'Hello, world.')
- >>> log.msg('Hello ', 'world.')
-
- These forms work (sometimes) by accident and will be disabled
- entirely in the future.
- """
- actualEventDict = (context.get(ILogContext) or {}).copy()
- actualEventDict.update(kw)
- actualEventDict['message'] = message
- actualEventDict['time'] = time.time()
- for i in xrange(len(self.observers) - 1, -1, -1):
- try:
- self.observers[i](actualEventDict)
- except KeyboardInterrupt:
- # Don't swallow keyboard interrupt!
- raise
- except UnicodeEncodeError:
- raise
- except:
- observer = self.observers[i]
- self.observers[i] = lambda event: None
- try:
- self._err(failure.Failure(),
- "Log observer %s failed." % (observer,))
- except:
- # Sometimes err() will throw an exception,
- # e.g. RuntimeError due to blowing the stack; if that
- # happens, there's not much we can do...
- pass
- self.observers[i] = observer
-
-
- def _err(self, failure, why):
- """
- Log a failure.
-
- Similar in functionality to the global {err} function, but the failure
- gets published only to observers attached to this publisher.
-
- @param failure: The failure to log.
- @type failure: L{Failure}.
-
- @param why: The source of this failure. This will be logged along with
- the C{failure} and should describe the context in which the failure
- occurred.
- @type why: C{str}
- """
- self.msg(failure=failure, why=why, isError=1)
-
-
- def showwarning(self, message, category, filename, lineno, file=None,
- line=None):
- """
- Twisted-enabled wrapper around L{warnings.showwarning}.
-
- If C{file} is C{None}, the default behaviour is to emit the warning to
- the log system, otherwise the original L{warnings.showwarning} Python
- function is called.
- """
- if file is None:
- self.msg(warning=message, category=reflect.qual(category),
- filename=filename, lineno=lineno,
- format="%(filename)s:%(lineno)s: %(category)s: %(warning)s")
- else:
- if sys.version_info < (2, 6):
- _oldshowwarning(message, category, filename, lineno, file)
- else:
- _oldshowwarning(message, category, filename, lineno, file, line)
-
-
-
-
-try:
- theLogPublisher
-except NameError:
- theLogPublisher = LogPublisher()
- addObserver = theLogPublisher.addObserver
- removeObserver = theLogPublisher.removeObserver
- msg = theLogPublisher.msg
- showwarning = theLogPublisher.showwarning
-
-
-def _safeFormat(fmtString, fmtDict):
- """
- Try to format the string C{fmtString} using C{fmtDict} arguments,
- swallowing all errors to always return a string.
- """
- # There's a way we could make this if not safer at least more
- # informative: perhaps some sort of str/repr wrapper objects
- # could be wrapped around the things inside of C{fmtDict}. That way
- # if the event dict contains an object with a bad __repr__, we
- # can only cry about that individual object instead of the
- # entire event dict.
- try:
- text = fmtString % fmtDict
- except KeyboardInterrupt:
- raise
- except:
- try:
- text = ('Invalid format string or unformattable object in log message: %r, %s' % (fmtString, fmtDict))
- except:
- try:
- text = 'UNFORMATTABLE OBJECT WRITTEN TO LOG with fmt %r, MESSAGE LOST' % (fmtString,)
- except:
- text = 'PATHOLOGICAL ERROR IN BOTH FORMAT STRING AND MESSAGE DETAILS, MESSAGE LOST'
- return text
-
-
-def textFromEventDict(eventDict):
- """
- Extract text from an event dict passed to a log observer. If it cannot
- handle the dict, it returns None.
-
- The possible keys of eventDict are:
- - C{message}: by default, it holds the final text. It's required, but can
- be empty if either C{isError} or C{format} is provided (the first
- having the priority).
- - C{isError}: boolean indicating the nature of the event.
- - C{failure}: L{failure.Failure} instance, required if the event is an
- error.
- - C{why}: if defined, used as header of the traceback in case of errors.
- - C{format}: string format used in place of C{message} to customize
- the event. It uses all keys present in C{eventDict} to format
- the text.
- Other keys will be used when applying the C{format}, or ignored.
- """
- edm = eventDict['message']
- if not edm:
- if eventDict['isError'] and 'failure' in eventDict:
- text = ((eventDict.get('why') or 'Unhandled Error')
- + '\n' + eventDict['failure'].getTraceback())
- elif 'format' in eventDict:
- text = _safeFormat(eventDict['format'], eventDict)
- else:
- # we don't know how to log this
- return
- else:
- text = ' '.join(map(reflect.safe_str, edm))
- return text
-
-
-class FileLogObserver:
- """
- Log observer that writes to a file-like object.
-
- @type timeFormat: C{str} or C{NoneType}
- @ivar timeFormat: If not C{None}, the format string passed to strftime().
- """
- timeFormat = None
-
- def __init__(self, f):
- self.write = f.write
- self.flush = f.flush
-
- def getTimezoneOffset(self, when):
- """
- Return the current local timezone offset from UTC.
-
- @type when: C{int}
- @param when: POSIX (ie, UTC) timestamp for which to find the offset.
-
- @rtype: C{int}
- @return: The number of seconds offset from UTC. West is positive,
- east is negative.
- """
- offset = datetime.utcfromtimestamp(when) - datetime.fromtimestamp(when)
- return offset.days * (60 * 60 * 24) + offset.seconds
-
- def formatTime(self, when):
- """
- Format the given UTC value as a string representing that time in the
- local timezone.
-
- By default it's formatted as a ISO8601-like string (ISO8601 date and
- ISO8601 time separated by a space). It can be customized using the
- C{timeFormat} attribute, which will be used as input for the underlying
- C{time.strftime} call.
-
- @type when: C{int}
- @param when: POSIX (ie, UTC) timestamp for which to find the offset.
-
- @rtype: C{str}
- """
- if self.timeFormat is not None:
- return time.strftime(self.timeFormat, time.localtime(when))
-
- tzOffset = -self.getTimezoneOffset(when)
- when = datetime.utcfromtimestamp(when + tzOffset)
- tzHour = abs(int(tzOffset / 60 / 60))
- tzMin = abs(int(tzOffset / 60 % 60))
- if tzOffset < 0:
- tzSign = '-'
- else:
- tzSign = '+'
- return '%d-%02d-%02d %02d:%02d:%02d%s%02d%02d' % (
- when.year, when.month, when.day,
- when.hour, when.minute, when.second,
- tzSign, tzHour, tzMin)
-
- def emit(self, eventDict):
- text = textFromEventDict(eventDict)
- if text is None:
- return
-
- timeStr = self.formatTime(eventDict['time'])
- fmtDict = {'system': eventDict['system'], 'text': text.replace("\n", "\n\t")}
- msgStr = _safeFormat("[%(system)s] %(text)s\n", fmtDict)
-
- util.untilConcludes(self.write, timeStr + " " + msgStr)
- util.untilConcludes(self.flush) # Hoorj!
-
- def start(self):
- """
- Start observing log events.
- """
- addObserver(self.emit)
-
- def stop(self):
- """
- Stop observing log events.
- """
- removeObserver(self.emit)
-
-
-class PythonLoggingObserver(object):
- """
- Output twisted messages to Python standard library L{logging} module.
-
- WARNING: specific logging configurations (example: network) can lead to
- a blocking system. Nothing is done here to prevent that, so be sure to not
- use this: code within Twisted, such as twisted.web, assumes that logging
- does not block.
- """
-
- def __init__(self, loggerName="twisted"):
- """
- @param loggerName: identifier used for getting logger.
- @type loggerName: C{str}
- """
- self.logger = logging.getLogger(loggerName)
-
- def emit(self, eventDict):
- """
- Receive a twisted log entry, format it and bridge it to python.
-
- By default the logging level used is info; log.err produces error
- level, and you can customize the level by using the C{logLevel} key::
-
- >>> log.msg('debugging', logLevel=logging.DEBUG)
-
- """
- if 'logLevel' in eventDict:
- level = eventDict['logLevel']
- elif eventDict['isError']:
- level = logging.ERROR
- else:
- level = logging.INFO
- text = textFromEventDict(eventDict)
- if text is None:
- return
- self.logger.log(level, text)
-
- def start(self):
- """
- Start observing log events.
- """
- addObserver(self.emit)
-
- def stop(self):
- """
- Stop observing log events.
- """
- removeObserver(self.emit)
-
-
-class StdioOnnaStick:
- """
- Class that pretends to be stdout/err, and turns writes into log messages.
-
- @ivar isError: boolean indicating whether this is stderr, in which cases
- log messages will be logged as errors.
-
- @ivar encoding: unicode encoding used to encode any unicode strings
- written to this object.
- """
-
- closed = 0
- softspace = 0
- mode = 'wb'
- name = '<stdio (log)>'
-
- def __init__(self, isError=0, encoding=None):
- self.isError = isError
- if encoding is None:
- encoding = sys.getdefaultencoding()
- self.encoding = encoding
- self.buf = ''
-
- def close(self):
- pass
-
- def fileno(self):
- return -1
-
- def flush(self):
- pass
-
- def read(self):
- raise IOError("can't read from the log!")
-
- readline = read
- readlines = read
- seek = read
- tell = read
-
- def write(self, data):
- if isinstance(data, unicode):
- data = data.encode(self.encoding)
- d = (self.buf + data).split('\n')
- self.buf = d[-1]
- messages = d[0:-1]
- for message in messages:
- msg(message, printed=1, isError=self.isError)
-
- def writelines(self, lines):
- for line in lines:
- if isinstance(line, unicode):
- line = line.encode(self.encoding)
- msg(line, printed=1, isError=self.isError)
-
-
-try:
- _oldshowwarning
-except NameError:
- _oldshowwarning = None
-
-
-def startLogging(file, *a, **kw):
- """
- Initialize logging to a specified file.
-
- @return: A L{FileLogObserver} if a new observer is added, None otherwise.
- """
- if isinstance(file, StdioOnnaStick):
- return
- flo = FileLogObserver(file)
- startLoggingWithObserver(flo.emit, *a, **kw)
- return flo
-
-
-
-def startLoggingWithObserver(observer, setStdout=1):
- """
- Initialize logging to a specified observer. If setStdout is true
- (defaults to yes), also redirect sys.stdout and sys.stderr
- to the specified file.
- """
- global defaultObserver, _oldshowwarning
- if not _oldshowwarning:
- _oldshowwarning = warnings.showwarning
- warnings.showwarning = showwarning
- if defaultObserver:
- defaultObserver.stop()
- defaultObserver = None
- addObserver(observer)
- msg("Log opened.")
- if setStdout:
- sys.stdout = logfile
- sys.stderr = logerr
-
-
-class NullFile:
- softspace = 0
- def read(self): pass
- def write(self, bytes): pass
- def flush(self): pass
- def close(self): pass
-
-
-def discardLogs():
- """
- Throw away all logs.
- """
- global logfile
- logfile = NullFile()
-
-
-# Prevent logfile from being erased on reload. This only works in cpython.
-try:
- logfile
-except NameError:
- logfile = StdioOnnaStick(0, getattr(sys.stdout, "encoding", None))
- logerr = StdioOnnaStick(1, getattr(sys.stderr, "encoding", None))
-
-
-
-class DefaultObserver:
- """
- Default observer.
-
- Will ignore all non-error messages and send error messages to sys.stderr.
- Will be removed when startLogging() is called for the first time.
- """
- stderr = sys.stderr
-
- def _emit(self, eventDict):
- if eventDict["isError"]:
- if 'failure' in eventDict:
- text = ((eventDict.get('why') or 'Unhandled Error')
- + '\n' + eventDict['failure'].getTraceback())
- else:
- text = " ".join([str(m) for m in eventDict["message"]]) + "\n"
-
- self.stderr.write(text)
- self.stderr.flush()
-
- def start(self):
- addObserver(self._emit)
-
- def stop(self):
- removeObserver(self._emit)
-
-
-# Some more sibling imports, at the bottom and unqualified to avoid
-# unresolvable circularity
-import threadable, failure
-threadable.synchronize(LogPublisher)
-
-
-try:
- defaultObserver
-except NameError:
- defaultObserver = DefaultObserver()
- defaultObserver.start()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/logfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/logfile.py
deleted file mode 100755
index f6522715..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/logfile.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# -*- test-case-name: twisted.test.test_logfile -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A rotating, browsable log file.
-"""
-
-# System Imports
-import os, glob, time, stat
-
-from twisted.python import threadable
-
-
-
-class BaseLogFile:
- """
- The base class for a log file that can be rotated.
- """
-
- synchronized = ["write", "rotate"]
-
- def __init__(self, name, directory, defaultMode=None):
- """
- Create a log file.
-
- @param name: name of the file
- @param directory: directory holding the file
- @param defaultMode: permissions used to create the file. Default to
- current permissions of the file if the file exists.
- """
- self.directory = directory
- self.name = name
- self.path = os.path.join(directory, name)
- if defaultMode is None and os.path.exists(self.path):
- self.defaultMode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
- else:
- self.defaultMode = defaultMode
- self._openFile()
-
- def fromFullPath(cls, filename, *args, **kwargs):
- """
- Construct a log file from a full file path.
- """
- logPath = os.path.abspath(filename)
- return cls(os.path.basename(logPath),
- os.path.dirname(logPath), *args, **kwargs)
- fromFullPath = classmethod(fromFullPath)
-
- def shouldRotate(self):
- """
- Override with a method to that returns true if the log
- should be rotated.
- """
- raise NotImplementedError
-
- def _openFile(self):
- """
- Open the log file.
- """
- self.closed = False
- if os.path.exists(self.path):
- self._file = file(self.path, "r+", 1)
- self._file.seek(0, 2)
- else:
- if self.defaultMode is not None:
- # Set the lowest permissions
- oldUmask = os.umask(0777)
- try:
- self._file = file(self.path, "w+", 1)
- finally:
- os.umask(oldUmask)
- else:
- self._file = file(self.path, "w+", 1)
- if self.defaultMode is not None:
- try:
- os.chmod(self.path, self.defaultMode)
- except OSError:
- # Probably /dev/null or something?
- pass
-
- def __getstate__(self):
- state = self.__dict__.copy()
- del state["_file"]
- return state
-
- def __setstate__(self, state):
- self.__dict__ = state
- self._openFile()
-
- def write(self, data):
- """
- Write some data to the file.
- """
- if self.shouldRotate():
- self.flush()
- self.rotate()
- self._file.write(data)
-
- def flush(self):
- """
- Flush the file.
- """
- self._file.flush()
-
- def close(self):
- """
- Close the file.
-
- The file cannot be used once it has been closed.
- """
- self.closed = True
- self._file.close()
- self._file = None
-
-
- def reopen(self):
- """
- Reopen the log file. This is mainly useful if you use an external log
- rotation tool, which moves under your feet.
-
- Note that on Windows you probably need a specific API to rename the
- file, as it's not supported to simply use os.rename, for example.
- """
- self.close()
- self._openFile()
-
-
- def getCurrentLog(self):
- """
- Return a LogReader for the current log file.
- """
- return LogReader(self.path)
-
-
-class LogFile(BaseLogFile):
- """
- A log file that can be rotated.
-
- A rotateLength of None disables automatic log rotation.
- """
- def __init__(self, name, directory, rotateLength=1000000, defaultMode=None,
- maxRotatedFiles=None):
- """
- Create a log file rotating on length.
-
- @param name: file name.
- @type name: C{str}
- @param directory: path of the log file.
- @type directory: C{str}
- @param rotateLength: size of the log file where it rotates. Default to
- 1M.
- @type rotateLength: C{int}
- @param defaultMode: mode used to create the file.
- @type defaultMode: C{int}
- @param maxRotatedFiles: if not None, max number of log files the class
- creates. Warning: it removes all log files above this number.
- @type maxRotatedFiles: C{int}
- """
- BaseLogFile.__init__(self, name, directory, defaultMode)
- self.rotateLength = rotateLength
- self.maxRotatedFiles = maxRotatedFiles
-
- def _openFile(self):
- BaseLogFile._openFile(self)
- self.size = self._file.tell()
-
- def shouldRotate(self):
- """
- Rotate when the log file size is larger than rotateLength.
- """
- return self.rotateLength and self.size >= self.rotateLength
-
- def getLog(self, identifier):
- """
- Given an integer, return a LogReader for an old log file.
- """
- filename = "%s.%d" % (self.path, identifier)
- if not os.path.exists(filename):
- raise ValueError, "no such logfile exists"
- return LogReader(filename)
-
- def write(self, data):
- """
- Write some data to the file.
- """
- BaseLogFile.write(self, data)
- self.size += len(data)
-
- def rotate(self):
- """
- Rotate the file and create a new one.
-
- If it's not possible to open new logfile, this will fail silently,
- and continue logging to old logfile.
- """
- if not (os.access(self.directory, os.W_OK) and os.access(self.path, os.W_OK)):
- return
- logs = self.listLogs()
- logs.reverse()
- for i in logs:
- if self.maxRotatedFiles is not None and i >= self.maxRotatedFiles:
- os.remove("%s.%d" % (self.path, i))
- else:
- os.rename("%s.%d" % (self.path, i), "%s.%d" % (self.path, i + 1))
- self._file.close()
- os.rename(self.path, "%s.1" % self.path)
- self._openFile()
-
- def listLogs(self):
- """
- Return sorted list of integers - the old logs' identifiers.
- """
- result = []
- for name in glob.glob("%s.*" % self.path):
- try:
- counter = int(name.split('.')[-1])
- if counter:
- result.append(counter)
- except ValueError:
- pass
- result.sort()
- return result
-
- def __getstate__(self):
- state = BaseLogFile.__getstate__(self)
- del state["size"]
- return state
-
-threadable.synchronize(LogFile)
-
-
-class DailyLogFile(BaseLogFile):
- """A log file that is rotated daily (at or after midnight localtime)
- """
- def _openFile(self):
- BaseLogFile._openFile(self)
- self.lastDate = self.toDate(os.stat(self.path)[8])
-
- def shouldRotate(self):
- """Rotate when the date has changed since last write"""
- return self.toDate() > self.lastDate
-
- def toDate(self, *args):
- """Convert a unixtime to (year, month, day) localtime tuple,
- or return the current (year, month, day) localtime tuple.
-
- This function primarily exists so you may overload it with
- gmtime, or some cruft to make unit testing possible.
- """
- # primarily so this can be unit tested easily
- return time.localtime(*args)[:3]
-
- def suffix(self, tupledate):
- """Return the suffix given a (year, month, day) tuple or unixtime"""
- try:
- return '_'.join(map(str, tupledate))
- except:
- # try taking a float unixtime
- return '_'.join(map(str, self.toDate(tupledate)))
-
- def getLog(self, identifier):
- """Given a unix time, return a LogReader for an old log file."""
- if self.toDate(identifier) == self.lastDate:
- return self.getCurrentLog()
- filename = "%s.%s" % (self.path, self.suffix(identifier))
- if not os.path.exists(filename):
- raise ValueError, "no such logfile exists"
- return LogReader(filename)
-
- def write(self, data):
- """Write some data to the log file"""
- BaseLogFile.write(self, data)
- # Guard against a corner case where time.time()
- # could potentially run backwards to yesterday.
- # Primarily due to network time.
- self.lastDate = max(self.lastDate, self.toDate())
-
- def rotate(self):
- """Rotate the file and create a new one.
-
- If it's not possible to open new logfile, this will fail silently,
- and continue logging to old logfile.
- """
- if not (os.access(self.directory, os.W_OK) and os.access(self.path, os.W_OK)):
- return
- newpath = "%s.%s" % (self.path, self.suffix(self.lastDate))
- if os.path.exists(newpath):
- return
- self._file.close()
- os.rename(self.path, newpath)
- self._openFile()
-
- def __getstate__(self):
- state = BaseLogFile.__getstate__(self)
- del state["lastDate"]
- return state
-
-threadable.synchronize(DailyLogFile)
-
-
-class LogReader:
- """Read from a log file."""
-
- def __init__(self, name):
- self._file = file(name, "r")
-
- def readLines(self, lines=10):
- """Read a list of lines from the log file.
-
- This doesn't returns all of the files lines - call it multiple times.
- """
- result = []
- for i in range(lines):
- line = self._file.readline()
- if not line:
- break
- result.append(line)
- return result
-
- def close(self):
- self._file.close()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/modules.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/modules.py
deleted file mode 100755
index 307970c1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/modules.py
+++ /dev/null
@@ -1,758 +0,0 @@
-# -*- test-case-name: twisted.test.test_modules -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module aims to provide a unified, object-oriented view of Python's
-runtime hierarchy.
-
-Python is a very dynamic language with wide variety of introspection utilities.
-However, these utilities can be hard to use, because there is no consistent
-API. The introspection API in python is made up of attributes (__name__,
-__module__, func_name, etc) on instances, modules, classes and functions which
-vary between those four types, utility modules such as 'inspect' which provide
-some functionality, the 'imp' module, the "compiler" module, the semantics of
-PEP 302 support, and setuptools, among other things.
-
-At the top, you have "PythonPath", an abstract representation of sys.path which
-includes methods to locate top-level modules, with or without loading them.
-The top-level exposed functions in this module for accessing the system path
-are "walkModules", "iterModules", and "getModule".
-
-From most to least specific, here are the objects provided::
-
- PythonPath # sys.path
- |
- v
- PathEntry # one entry on sys.path: an importer
- |
- v
- PythonModule # a module or package that can be loaded
- |
- v
- PythonAttribute # an attribute of a module (function or class)
- |
- v
- PythonAttribute # an attribute of a function or class
- |
- v
- ...
-
-Here's an example of idiomatic usage: this is what you would do to list all of
-the modules outside the standard library's python-files directory::
-
- import os
- stdlibdir = os.path.dirname(os.__file__)
-
- from twisted.python.modules import iterModules
-
- for modinfo in iterModules():
- if (modinfo.pathEntry.filePath.path != stdlibdir
- and not modinfo.isPackage()):
- print 'unpackaged: %s: %s' % (
- modinfo.name, modinfo.filePath.path)
-"""
-
-__metaclass__ = type
-
-# let's try to keep path imports to a minimum...
-from os.path import dirname, split as splitpath
-
-import sys
-import zipimport
-import inspect
-import warnings
-from zope.interface import Interface, implements
-
-from twisted.python.components import registerAdapter
-from twisted.python.filepath import FilePath, UnlistableError
-from twisted.python.zippath import ZipArchive
-from twisted.python.reflect import namedAny
-
-_nothing = object()
-
-PYTHON_EXTENSIONS = ['.py']
-OPTIMIZED_MODE = __doc__ is None
-if OPTIMIZED_MODE:
- PYTHON_EXTENSIONS.append('.pyo')
-else:
- PYTHON_EXTENSIONS.append('.pyc')
-
-def _isPythonIdentifier(string):
- """
- cheezy fake test for proper identifier-ness.
-
- @param string: a str which might or might not be a valid python identifier.
-
- @return: True or False
- """
- return (' ' not in string and
- '.' not in string and
- '-' not in string)
-
-
-
-def _isPackagePath(fpath):
- # Determine if a FilePath-like object is a Python package. TODO: deal with
- # __init__module.(so|dll|pyd)?
- extless = fpath.splitext()[0]
- basend = splitpath(extless)[1]
- return basend == "__init__"
-
-
-
-class _ModuleIteratorHelper:
- """
- This mixin provides common behavior between python module and path entries,
- since the mechanism for searching sys.path and __path__ attributes is
- remarkably similar.
- """
-
- def iterModules(self):
- """
- Loop over the modules present below this entry or package on PYTHONPATH.
-
- For modules which are not packages, this will yield nothing.
-
- For packages and path entries, this will only yield modules one level
- down; i.e. if there is a package a.b.c, iterModules on a will only
- return a.b. If you want to descend deeply, use walkModules.
-
- @return: a generator which yields PythonModule instances that describe
- modules which can be, or have been, imported.
- """
- yielded = {}
- if not self.filePath.exists():
- return
-
- for placeToLook in self._packagePaths():
- try:
- children = placeToLook.children()
- except UnlistableError:
- continue
-
- children.sort()
- for potentialTopLevel in children:
- ext = potentialTopLevel.splitext()[1]
- potentialBasename = potentialTopLevel.basename()[:-len(ext)]
- if ext in PYTHON_EXTENSIONS:
- # TODO: this should be a little choosier about which path entry
- # it selects first, and it should do all the .so checking and
- # crud
- if not _isPythonIdentifier(potentialBasename):
- continue
- modname = self._subModuleName(potentialBasename)
- if modname.split(".")[-1] == '__init__':
- # This marks the directory as a package so it can't be
- # a module.
- continue
- if modname not in yielded:
- yielded[modname] = True
- pm = PythonModule(modname, potentialTopLevel, self._getEntry())
- assert pm != self
- yield pm
- else:
- if (ext or not _isPythonIdentifier(potentialBasename)
- or not potentialTopLevel.isdir()):
- continue
- modname = self._subModuleName(potentialTopLevel.basename())
- for ext in PYTHON_EXTENSIONS:
- initpy = potentialTopLevel.child("__init__"+ext)
- if initpy.exists() and modname not in yielded:
- yielded[modname] = True
- pm = PythonModule(modname, initpy, self._getEntry())
- assert pm != self
- yield pm
- break
-
- def walkModules(self, importPackages=False):
- """
- Similar to L{iterModules}, this yields self, and then every module in my
- package or entry, and every submodule in each package or entry.
-
- In other words, this is deep, and L{iterModules} is shallow.
- """
- yield self
- for package in self.iterModules():
- for module in package.walkModules(importPackages=importPackages):
- yield module
-
- def _subModuleName(self, mn):
- """
- This is a hook to provide packages with the ability to specify their names
- as a prefix to submodules here.
- """
- return mn
-
- def _packagePaths(self):
- """
- Implement in subclasses to specify where to look for modules.
-
- @return: iterable of FilePath-like objects.
- """
- raise NotImplementedError()
-
- def _getEntry(self):
- """
- Implement in subclasses to specify what path entry submodules will come
- from.
-
- @return: a PathEntry instance.
- """
- raise NotImplementedError()
-
-
- def __getitem__(self, modname):
- """
- Retrieve a module from below this path or package.
-
- @param modname: a str naming a module to be loaded. For entries, this
- is a top-level, undotted package name, and for packages it is the name
- of the module without the package prefix. For example, if you have a
- PythonModule representing the 'twisted' package, you could use::
-
- twistedPackageObj['python']['modules']
-
- to retrieve this module.
-
- @raise: KeyError if the module is not found.
-
- @return: a PythonModule.
- """
- for module in self.iterModules():
- if module.name == self._subModuleName(modname):
- return module
- raise KeyError(modname)
-
- def __iter__(self):
- """
- Implemented to raise NotImplementedError for clarity, so that attempting to
- loop over this object won't call __getitem__.
-
- Note: in the future there might be some sensible default for iteration,
- like 'walkEverything', so this is deliberately untested and undefined
- behavior.
- """
- raise NotImplementedError()
-
-class PythonAttribute:
- """
- I represent a function, class, or other object that is present.
-
- @ivar name: the fully-qualified python name of this attribute.
-
- @ivar onObject: a reference to a PythonModule or other PythonAttribute that
- is this attribute's logical parent.
-
- @ivar name: the fully qualified python name of the attribute represented by
- this class.
- """
- def __init__(self, name, onObject, loaded, pythonValue):
- """
- Create a PythonAttribute. This is a private constructor. Do not construct
- me directly, use PythonModule.iterAttributes.
-
- @param name: the FQPN
- @param onObject: see ivar
- @param loaded: always True, for now
- @param pythonValue: the value of the attribute we're pointing to.
- """
- self.name = name
- self.onObject = onObject
- self._loaded = loaded
- self.pythonValue = pythonValue
-
- def __repr__(self):
- return 'PythonAttribute<%r>'%(self.name,)
-
- def isLoaded(self):
- """
- Return a boolean describing whether the attribute this describes has
- actually been loaded into memory by importing its module.
-
- Note: this currently always returns true; there is no Python parser
- support in this module yet.
- """
- return self._loaded
-
- def load(self, default=_nothing):
- """
- Load the value associated with this attribute.
-
- @return: an arbitrary Python object, or 'default' if there is an error
- loading it.
- """
- return self.pythonValue
-
- def iterAttributes(self):
- for name, val in inspect.getmembers(self.load()):
- yield PythonAttribute(self.name+'.'+name, self, True, val)
-
-class PythonModule(_ModuleIteratorHelper):
- """
- Representation of a module which could be imported from sys.path.
-
- @ivar name: the fully qualified python name of this module.
-
- @ivar filePath: a FilePath-like object which points to the location of this
- module.
-
- @ivar pathEntry: a L{PathEntry} instance which this module was located
- from.
- """
-
- def __init__(self, name, filePath, pathEntry):
- """
- Create a PythonModule. Do not construct this directly, instead inspect a
- PythonPath or other PythonModule instances.
-
- @param name: see ivar
- @param filePath: see ivar
- @param pathEntry: see ivar
- """
- assert not name.endswith(".__init__")
- self.name = name
- self.filePath = filePath
- self.parentPath = filePath.parent()
- self.pathEntry = pathEntry
-
- def _getEntry(self):
- return self.pathEntry
-
- def __repr__(self):
- """
- Return a string representation including the module name.
- """
- return 'PythonModule<%r>' % (self.name,)
-
-
- def isLoaded(self):
- """
- Determine if the module is loaded into sys.modules.
-
- @return: a boolean: true if loaded, false if not.
- """
- return self.pathEntry.pythonPath.moduleDict.get(self.name) is not None
-
-
- def iterAttributes(self):
- """
- List all the attributes defined in this module.
-
- Note: Future work is planned here to make it possible to list python
- attributes on a module without loading the module by inspecting ASTs or
- bytecode, but currently any iteration of PythonModule objects insists
- they must be loaded, and will use inspect.getmodule.
-
- @raise NotImplementedError: if this module is not loaded.
-
- @return: a generator yielding PythonAttribute instances describing the
- attributes of this module.
- """
- if not self.isLoaded():
- raise NotImplementedError(
- "You can't load attributes from non-loaded modules yet.")
- for name, val in inspect.getmembers(self.load()):
- yield PythonAttribute(self.name+'.'+name, self, True, val)
-
- def isPackage(self):
- """
- Returns true if this module is also a package, and might yield something
- from iterModules.
- """
- return _isPackagePath(self.filePath)
-
- def load(self, default=_nothing):
- """
- Load this module.
-
- @param default: if specified, the value to return in case of an error.
-
- @return: a genuine python module.
-
- @raise: any type of exception. Importing modules is a risky business;
- the erorrs of any code run at module scope may be raised from here, as
- well as ImportError if something bizarre happened to the system path
- between the discovery of this PythonModule object and the attempt to
- import it. If you specify a default, the error will be swallowed
- entirely, and not logged.
-
- @rtype: types.ModuleType.
- """
- try:
- return self.pathEntry.pythonPath.moduleLoader(self.name)
- except: # this needs more thought...
- if default is not _nothing:
- return default
- raise
-
- def __eq__(self, other):
- """
- PythonModules with the same name are equal.
- """
- if not isinstance(other, PythonModule):
- return False
- return other.name == self.name
-
- def __ne__(self, other):
- """
- PythonModules with different names are not equal.
- """
- if not isinstance(other, PythonModule):
- return True
- return other.name != self.name
-
- def walkModules(self, importPackages=False):
- if importPackages and self.isPackage():
- self.load()
- return super(PythonModule, self).walkModules(importPackages=importPackages)
-
- def _subModuleName(self, mn):
- """
- submodules of this module are prefixed with our name.
- """
- return self.name + '.' + mn
-
- def _packagePaths(self):
- """
- Yield a sequence of FilePath-like objects which represent path segments.
- """
- if not self.isPackage():
- return
- if self.isLoaded():
- load = self.load()
- if hasattr(load, '__path__'):
- for fn in load.__path__:
- if fn == self.parentPath.path:
- # this should _really_ exist.
- assert self.parentPath.exists()
- yield self.parentPath
- else:
- smp = self.pathEntry.pythonPath._smartPath(fn)
- if smp.exists():
- yield smp
- else:
- yield self.parentPath
-
-
-class PathEntry(_ModuleIteratorHelper):
- """
- I am a proxy for a single entry on sys.path.
-
- @ivar filePath: a FilePath-like object pointing at the filesystem location
- or archive file where this path entry is stored.
-
- @ivar pythonPath: a PythonPath instance.
- """
- def __init__(self, filePath, pythonPath):
- """
- Create a PathEntry. This is a private constructor.
- """
- self.filePath = filePath
- self.pythonPath = pythonPath
-
- def _getEntry(self):
- return self
-
- def __repr__(self):
- return 'PathEntry<%r>' % (self.filePath,)
-
- def _packagePaths(self):
- yield self.filePath
-
-class IPathImportMapper(Interface):
- """
- This is an internal interface, used to map importers to factories for
- FilePath-like objects.
- """
- def mapPath(self, pathLikeString):
- """
- Return a FilePath-like object.
-
- @param pathLikeString: a path-like string, like one that might be
- passed to an import hook.
-
- @return: a L{FilePath}, or something like it (currently only a
- L{ZipPath}, but more might be added later).
- """
-
-class _DefaultMapImpl:
- """ Wrapper for the default importer, i.e. None. """
- implements(IPathImportMapper)
- def mapPath(self, fsPathString):
- return FilePath(fsPathString)
-_theDefaultMapper = _DefaultMapImpl()
-
-class _ZipMapImpl:
- """ IPathImportMapper implementation for zipimport.ZipImporter. """
- implements(IPathImportMapper)
- def __init__(self, importer):
- self.importer = importer
-
- def mapPath(self, fsPathString):
- """
- Map the given FS path to a ZipPath, by looking at the ZipImporter's
- "archive" attribute and using it as our ZipArchive root, then walking
- down into the archive from there.
-
- @return: a L{zippath.ZipPath} or L{zippath.ZipArchive} instance.
- """
- za = ZipArchive(self.importer.archive)
- myPath = FilePath(self.importer.archive)
- itsPath = FilePath(fsPathString)
- if myPath == itsPath:
- return za
- # This is NOT a general-purpose rule for sys.path or __file__:
- # zipimport specifically uses regular OS path syntax in its pathnames,
- # even though zip files specify that slashes are always the separator,
- # regardless of platform.
- segs = itsPath.segmentsFrom(myPath)
- zp = za
- for seg in segs:
- zp = zp.child(seg)
- return zp
-
-registerAdapter(_ZipMapImpl, zipimport.zipimporter, IPathImportMapper)
-
-def _defaultSysPathFactory():
- """
- Provide the default behavior of PythonPath's sys.path factory, which is to
- return the current value of sys.path.
-
- @return: L{sys.path}
- """
- return sys.path
-
-
-class PythonPath:
- """
- I represent the very top of the Python object-space, the module list in
- sys.path and the modules list in sys.modules.
-
- @ivar _sysPath: a sequence of strings like sys.path. This attribute is
- read-only.
-
- @ivar moduleDict: a dictionary mapping string module names to module
- objects, like sys.modules.
-
- @ivar sysPathHooks: a list of PEP-302 path hooks, like sys.path_hooks.
-
- @ivar moduleLoader: a function that takes a fully-qualified python name and
- returns a module, like twisted.python.reflect.namedAny.
- """
-
- def __init__(self,
- sysPath=None,
- moduleDict=sys.modules,
- sysPathHooks=sys.path_hooks,
- importerCache=sys.path_importer_cache,
- moduleLoader=namedAny,
- sysPathFactory=None):
- """
- Create a PythonPath. You almost certainly want to use
- modules.theSystemPath, or its aliased methods, rather than creating a
- new instance yourself, though.
-
- All parameters are optional, and if unspecified, will use 'system'
- equivalents that makes this PythonPath like the global L{theSystemPath}
- instance.
-
- @param sysPath: a sys.path-like list to use for this PythonPath, to
- specify where to load modules from.
-
- @param moduleDict: a sys.modules-like dictionary to use for keeping
- track of what modules this PythonPath has loaded.
-
- @param sysPathHooks: sys.path_hooks-like list of PEP-302 path hooks to
- be used for this PythonPath, to determie which importers should be
- used.
-
- @param importerCache: a sys.path_importer_cache-like list of PEP-302
- importers. This will be used in conjunction with the given
- sysPathHooks.
-
- @param moduleLoader: a module loader function which takes a string and
- returns a module. That is to say, it is like L{namedAny} - *not* like
- L{__import__}.
-
- @param sysPathFactory: a 0-argument callable which returns the current
- value of a sys.path-like list of strings. Specify either this, or
- sysPath, not both. This alternative interface is provided because the
- way the Python import mechanism works, you can re-bind the 'sys.path'
- name and that is what is used for current imports, so it must be a
- factory rather than a value to deal with modification by rebinding
- rather than modification by mutation. Note: it is not recommended to
- rebind sys.path. Although this mechanism can deal with that, it is a
- subtle point which some tools that it is easy for tools which interact
- with sys.path to miss.
- """
- if sysPath is not None:
- sysPathFactory = lambda : sysPath
- elif sysPathFactory is None:
- sysPathFactory = _defaultSysPathFactory
- self._sysPathFactory = sysPathFactory
- self._sysPath = sysPath
- self.moduleDict = moduleDict
- self.sysPathHooks = sysPathHooks
- self.importerCache = importerCache
- self.moduleLoader = moduleLoader
-
-
- def _getSysPath(self):
- """
- Retrieve the current value of the module search path list.
- """
- return self._sysPathFactory()
-
- sysPath = property(_getSysPath)
-
- def _findEntryPathString(self, modobj):
- """
- Determine where a given Python module object came from by looking at path
- entries.
- """
- topPackageObj = modobj
- while '.' in topPackageObj.__name__:
- topPackageObj = self.moduleDict['.'.join(
- topPackageObj.__name__.split('.')[:-1])]
- if _isPackagePath(FilePath(topPackageObj.__file__)):
- # if package 'foo' is on sys.path at /a/b/foo, package 'foo's
- # __file__ will be /a/b/foo/__init__.py, and we are looking for
- # /a/b here, the path-entry; so go up two steps.
- rval = dirname(dirname(topPackageObj.__file__))
- else:
- # the module is completely top-level, not within any packages. The
- # path entry it's on is just its dirname.
- rval = dirname(topPackageObj.__file__)
-
- # There are probably some awful tricks that an importer could pull
- # which would break this, so let's just make sure... it's a loaded
- # module after all, which means that its path MUST be in
- # path_importer_cache according to PEP 302 -glyph
- if rval not in self.importerCache:
- warnings.warn(
- "%s (for module %s) not in path importer cache "
- "(PEP 302 violation - check your local configuration)." % (
- rval, modobj.__name__),
- stacklevel=3)
-
- return rval
-
- def _smartPath(self, pathName):
- """
- Given a path entry from sys.path which may refer to an importer,
- return the appropriate FilePath-like instance.
-
- @param pathName: a str describing the path.
-
- @return: a FilePath-like object.
- """
- importr = self.importerCache.get(pathName, _nothing)
- if importr is _nothing:
- for hook in self.sysPathHooks:
- try:
- importr = hook(pathName)
- except ImportError:
- pass
- if importr is _nothing: # still
- importr = None
- return IPathImportMapper(importr, _theDefaultMapper).mapPath(pathName)
-
- def iterEntries(self):
- """
- Iterate the entries on my sysPath.
-
- @return: a generator yielding PathEntry objects
- """
- for pathName in self.sysPath:
- fp = self._smartPath(pathName)
- yield PathEntry(fp, self)
-
-
- def __getitem__(self, modname):
- """
- Get a python module by its given fully-qualified name.
-
- @param modname: The fully-qualified Python module name to load.
-
- @type modname: C{str}
-
- @return: an object representing the module identified by C{modname}
-
- @rtype: L{PythonModule}
-
- @raise KeyError: if the module name is not a valid module name, or no
- such module can be identified as loadable.
- """
- # See if the module is already somewhere in Python-land.
- moduleObject = self.moduleDict.get(modname)
- if moduleObject is not None:
- # we need 2 paths; one of the path entry and one for the module.
- pe = PathEntry(
- self._smartPath(
- self._findEntryPathString(moduleObject)),
- self)
- mp = self._smartPath(moduleObject.__file__)
- return PythonModule(modname, mp, pe)
-
- # Recurse if we're trying to get a submodule.
- if '.' in modname:
- pkg = self
- for name in modname.split('.'):
- pkg = pkg[name]
- return pkg
-
- # Finally do the slowest possible thing and iterate
- for module in self.iterModules():
- if module.name == modname:
- return module
- raise KeyError(modname)
-
-
- def __repr__(self):
- """
- Display my sysPath and moduleDict in a string representation.
- """
- return "PythonPath(%r,%r)" % (self.sysPath, self.moduleDict)
-
- def iterModules(self):
- """
- Yield all top-level modules on my sysPath.
- """
- for entry in self.iterEntries():
- for module in entry.iterModules():
- yield module
-
- def walkModules(self, importPackages=False):
- """
- Similar to L{iterModules}, this yields every module on the path, then every
- submodule in each package or entry.
- """
- for package in self.iterModules():
- for module in package.walkModules(importPackages=False):
- yield module
-
-theSystemPath = PythonPath()
-
-def walkModules(importPackages=False):
- """
- Deeply iterate all modules on the global python path.
-
- @param importPackages: Import packages as they are seen.
- """
- return theSystemPath.walkModules(importPackages=importPackages)
-
-def iterModules():
- """
- Iterate all modules and top-level packages on the global Python path, but
- do not descend into packages.
-
- @param importPackages: Import packages as they are seen.
- """
- return theSystemPath.iterModules()
-
-def getModule(moduleName):
- """
- Retrieve a module from the system path.
- """
- return theSystemPath[moduleName]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/monkey.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/monkey.py
deleted file mode 100755
index 9be285dc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/monkey.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- test-case-name: twisted.test.test_monkey -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-class MonkeyPatcher(object):
- """
- Cover up attributes with new objects. Neat for monkey-patching things for
- unit-testing purposes.
- """
-
- def __init__(self, *patches):
- # List of patches to apply in (obj, name, value).
- self._patchesToApply = []
- # List of the original values for things that have been patched.
- # (obj, name, value) format.
- self._originals = []
- for patch in patches:
- self.addPatch(*patch)
-
-
- def addPatch(self, obj, name, value):
- """
- Add a patch so that the attribute C{name} on C{obj} will be assigned to
- C{value} when C{patch} is called or during C{runWithPatches}.
-
- You can restore the original values with a call to restore().
- """
- self._patchesToApply.append((obj, name, value))
-
-
- def _alreadyPatched(self, obj, name):
- """
- Has the C{name} attribute of C{obj} already been patched by this
- patcher?
- """
- for o, n, v in self._originals:
- if (o, n) == (obj, name):
- return True
- return False
-
-
- def patch(self):
- """
- Apply all of the patches that have been specified with L{addPatch}.
- Reverse this operation using L{restore}.
- """
- for obj, name, value in self._patchesToApply:
- if not self._alreadyPatched(obj, name):
- self._originals.append((obj, name, getattr(obj, name)))
- setattr(obj, name, value)
-
-
- def restore(self):
- """
- Restore all original values to any patched objects.
- """
- while self._originals:
- obj, name, value = self._originals.pop()
- setattr(obj, name, value)
-
-
- def runWithPatches(self, f, *args, **kw):
- """
- Apply each patch already specified. Then run the function f with the
- given args and kwargs. Restore everything when done.
- """
- self.patch()
- try:
- return f(*args, **kw)
- finally:
- self.restore()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/procutils.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/procutils.py
deleted file mode 100755
index 26ff95d8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/procutils.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Utilities for dealing with processes.
-"""
-
-import os
-
-def which(name, flags=os.X_OK):
- """Search PATH for executable files with the given name.
-
- On newer versions of MS-Windows, the PATHEXT environment variable will be
- set to the list of file extensions for files considered executable. This
- will normally include things like ".EXE". This fuction will also find files
- with the given name ending with any of these extensions.
-
- On MS-Windows the only flag that has any meaning is os.F_OK. Any other
- flags will be ignored.
-
- @type name: C{str}
- @param name: The name for which to search.
-
- @type flags: C{int}
- @param flags: Arguments to L{os.access}.
-
- @rtype: C{list}
- @param: A list of the full paths to files found, in the
- order in which they were found.
- """
- result = []
- exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep))
- path = os.environ.get('PATH', None)
- if path is None:
- return []
- for p in os.environ.get('PATH', '').split(os.pathsep):
- p = os.path.join(p, name)
- if os.access(p, flags):
- result.append(p)
- for e in exts:
- pext = p + e
- if os.access(pext, flags):
- result.append(pext)
- return result
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/randbytes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/randbytes.py
deleted file mode 100755
index 63ae2dc8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/randbytes.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*- test-case-name: twisted.test.test_randbytes -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Cryptographically secure random implementation, with fallback on normal random.
-"""
-
-# System imports
-import warnings, os, random
-
-getrandbits = getattr(random, 'getrandbits', None)
-
-
-class SecureRandomNotAvailable(RuntimeError):
- """
- Exception raised when no secure random algorithm is found.
- """
-
-
-
-class SourceNotAvailable(RuntimeError):
- """
- Internal exception used when a specific random source is not available.
- """
-
-
-
-class RandomFactory(object):
- """
- Factory providing L{secureRandom} and L{insecureRandom} methods.
-
- You shouldn't have to instantiate this class, use the module level
- functions instead: it is an implementation detail and could be removed or
- changed arbitrarily.
- """
-
- # This variable is no longer used, and will eventually be removed.
- randomSources = ()
-
- getrandbits = getrandbits
-
-
- def _osUrandom(self, nbytes):
- """
- Wrapper around C{os.urandom} that cleanly manage its absence.
- """
- try:
- return os.urandom(nbytes)
- except (AttributeError, NotImplementedError), e:
- raise SourceNotAvailable(e)
-
-
- def secureRandom(self, nbytes, fallback=False):
- """
- Return a number of secure random bytes.
-
- @param nbytes: number of bytes to generate.
- @type nbytes: C{int}
- @param fallback: Whether the function should fallback on non-secure
- random or not. Default to C{False}.
- @type fallback: C{bool}
-
- @return: a string of random bytes.
- @rtype: C{str}
- """
- try:
- return self._osUrandom(nbytes)
- except SourceNotAvailable:
- pass
-
- if fallback:
- warnings.warn(
- "urandom unavailable - "
- "proceeding with non-cryptographically secure random source",
- category=RuntimeWarning,
- stacklevel=2)
- return self.insecureRandom(nbytes)
- else:
- raise SecureRandomNotAvailable("No secure random source available")
-
-
- def _randBits(self, nbytes):
- """
- Wrapper around C{os.getrandbits}.
- """
- if self.getrandbits is not None:
- n = self.getrandbits(nbytes * 8)
- hexBytes = ("%%0%dx" % (nbytes * 2)) % n
- return hexBytes.decode('hex')
- raise SourceNotAvailable("random.getrandbits is not available")
-
-
- def _randRange(self, nbytes):
- """
- Wrapper around C{random.randrange}.
- """
- bytes = ""
- for i in xrange(nbytes):
- bytes += chr(random.randrange(0, 255))
- return bytes
-
-
- def insecureRandom(self, nbytes):
- """
- Return a number of non secure random bytes.
-
- @param nbytes: number of bytes to generate.
- @type nbytes: C{int}
-
- @return: a string of random bytes.
- @rtype: C{str}
- """
- for src in ("_randBits", "_randRange"):
- try:
- return getattr(self, src)(nbytes)
- except SourceNotAvailable:
- pass
-
-
-
-factory = RandomFactory()
-
-secureRandom = factory.secureRandom
-
-insecureRandom = factory.insecureRandom
-
-del factory
-
-
-__all__ = ["secureRandom", "insecureRandom", "SecureRandomNotAvailable"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/rebuild.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/rebuild.py
deleted file mode 100755
index 28a76753..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/rebuild.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# -*- test-case-name: twisted.test.test_rebuild -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-*Real* reloading support for Python.
-"""
-
-# System Imports
-import sys
-import types
-import time
-import linecache
-
-# Sibling Imports
-from twisted.python import log, reflect
-
-lastRebuild = time.time()
-
-
-class Sensitive:
- """
- A utility mixin that's sensitive to rebuilds.
-
- This is a mixin for classes (usually those which represent collections of
- callbacks) to make sure that their code is up-to-date before running.
- """
-
- lastRebuild = lastRebuild
-
- def needRebuildUpdate(self):
- yn = (self.lastRebuild < lastRebuild)
- return yn
-
- def rebuildUpToDate(self):
- self.lastRebuild = time.time()
-
- def latestVersionOf(self, anObject):
- """
- Get the latest version of an object.
-
- This can handle just about anything callable; instances, functions,
- methods, and classes.
- """
- t = type(anObject)
- if t == types.FunctionType:
- return latestFunction(anObject)
- elif t == types.MethodType:
- if anObject.im_self is None:
- return getattr(anObject.im_class, anObject.__name__)
- else:
- return getattr(anObject.im_self, anObject.__name__)
- elif t == types.InstanceType:
- # Kick it, if it's out of date.
- getattr(anObject, 'nothing', None)
- return anObject
- elif t == types.ClassType:
- return latestClass(anObject)
- else:
- log.msg('warning returning anObject!')
- return anObject
-
-_modDictIDMap = {}
-
-def latestFunction(oldFunc):
- """
- Get the latest version of a function.
- """
- # This may be CPython specific, since I believe jython instantiates a new
- # module upon reload.
- dictID = id(oldFunc.func_globals)
- module = _modDictIDMap.get(dictID)
- if module is None:
- return oldFunc
- return getattr(module, oldFunc.__name__)
-
-
-def latestClass(oldClass):
- """
- Get the latest version of a class.
- """
- module = reflect.namedModule(oldClass.__module__)
- newClass = getattr(module, oldClass.__name__)
- newBases = [latestClass(base) for base in newClass.__bases__]
-
- try:
- # This makes old-style stuff work
- newClass.__bases__ = tuple(newBases)
- return newClass
- except TypeError:
- if newClass.__module__ == "__builtin__":
- # __builtin__ members can't be reloaded sanely
- return newClass
- ctor = getattr(newClass, '__metaclass__', type)
- return ctor(newClass.__name__, tuple(newBases), dict(newClass.__dict__))
-
-
-class RebuildError(Exception):
- """
- Exception raised when trying to rebuild a class whereas it's not possible.
- """
-
-
-def updateInstance(self):
- """
- Updates an instance to be current.
- """
- try:
- self.__class__ = latestClass(self.__class__)
- except TypeError:
- if hasattr(self.__class__, '__slots__'):
- raise RebuildError("Can't rebuild class with __slots__ on Python < 2.6")
- else:
- raise
-
-
-def __getattr__(self, name):
- """
- A getattr method to cause a class to be refreshed.
- """
- if name == '__del__':
- raise AttributeError("Without this, Python segfaults.")
- updateInstance(self)
- log.msg("(rebuilding stale %s instance (%s))" % (reflect.qual(self.__class__), name))
- result = getattr(self, name)
- return result
-
-
-def rebuild(module, doLog=1):
- """
- Reload a module and do as much as possible to replace its references.
- """
- global lastRebuild
- lastRebuild = time.time()
- if hasattr(module, 'ALLOW_TWISTED_REBUILD'):
- # Is this module allowed to be rebuilt?
- if not module.ALLOW_TWISTED_REBUILD:
- raise RuntimeError("I am not allowed to be rebuilt.")
- if doLog:
- log.msg('Rebuilding %s...' % str(module.__name__))
-
- ## Safely handle adapter re-registration
- from twisted.python import components
- components.ALLOW_DUPLICATES = True
-
- d = module.__dict__
- _modDictIDMap[id(d)] = module
- newclasses = {}
- classes = {}
- functions = {}
- values = {}
- if doLog:
- log.msg(' (scanning %s): ' % str(module.__name__))
- for k, v in d.items():
- if type(v) == types.ClassType:
- # Failure condition -- instances of classes with buggy
- # __hash__/__cmp__ methods referenced at the module level...
- if v.__module__ == module.__name__:
- classes[v] = 1
- if doLog:
- log.logfile.write("c")
- log.logfile.flush()
- elif type(v) == types.FunctionType:
- if v.func_globals is module.__dict__:
- functions[v] = 1
- if doLog:
- log.logfile.write("f")
- log.logfile.flush()
- elif isinstance(v, type):
- if v.__module__ == module.__name__:
- newclasses[v] = 1
- if doLog:
- log.logfile.write("o")
- log.logfile.flush()
-
- values.update(classes)
- values.update(functions)
- fromOldModule = values.__contains__
- newclasses = newclasses.keys()
- classes = classes.keys()
- functions = functions.keys()
-
- if doLog:
- log.msg('')
- log.msg(' (reload %s)' % str(module.__name__))
-
- # Boom.
- reload(module)
- # Make sure that my traceback printing will at least be recent...
- linecache.clearcache()
-
- if doLog:
- log.msg(' (cleaning %s): ' % str(module.__name__))
-
- for clazz in classes:
- if getattr(module, clazz.__name__) is clazz:
- log.msg("WARNING: class %s not replaced by reload!" % reflect.qual(clazz))
- else:
- if doLog:
- log.logfile.write("x")
- log.logfile.flush()
- clazz.__bases__ = ()
- clazz.__dict__.clear()
- clazz.__getattr__ = __getattr__
- clazz.__module__ = module.__name__
- if newclasses:
- import gc
- for nclass in newclasses:
- ga = getattr(module, nclass.__name__)
- if ga is nclass:
- log.msg("WARNING: new-class %s not replaced by reload!" % reflect.qual(nclass))
- else:
- for r in gc.get_referrers(nclass):
- if getattr(r, '__class__', None) is nclass:
- r.__class__ = ga
- if doLog:
- log.msg('')
- log.msg(' (fixing %s): ' % str(module.__name__))
- modcount = 0
- for mk, mod in sys.modules.items():
- modcount = modcount + 1
- if mod == module or mod is None:
- continue
-
- if not hasattr(mod, '__file__'):
- # It's a builtin module; nothing to replace here.
- continue
-
- if hasattr(mod, '__bundle__'):
- # PyObjC has a few buggy objects which segfault if you hash() them.
- # It doesn't make sense to try rebuilding extension modules like
- # this anyway, so don't try.
- continue
-
- changed = 0
-
- for k, v in mod.__dict__.items():
- try:
- hash(v)
- except Exception:
- continue
- if fromOldModule(v):
- if type(v) == types.ClassType:
- if doLog:
- log.logfile.write("c")
- log.logfile.flush()
- nv = latestClass(v)
- else:
- if doLog:
- log.logfile.write("f")
- log.logfile.flush()
- nv = latestFunction(v)
- changed = 1
- setattr(mod, k, nv)
- else:
- # Replace bases of non-module classes just to be sure.
- if type(v) == types.ClassType:
- for base in v.__bases__:
- if fromOldModule(base):
- latestClass(v)
- if doLog and not changed and ((modcount % 10) ==0) :
- log.logfile.write(".")
- log.logfile.flush()
-
- components.ALLOW_DUPLICATES = False
- if doLog:
- log.msg('')
- log.msg(' Rebuilt %s.' % str(module.__name__))
- return module
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/reflect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/reflect.py
deleted file mode 100755
index f5297548..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/reflect.py
+++ /dev/null
@@ -1,827 +0,0 @@
-# -*- test-case-name: twisted.test.test_reflect -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Standardized versions of various cool and/or strange things that you can do
-with Python's reflection capabilities.
-"""
-
-import sys
-import os
-import types
-import pickle
-import traceback
-import weakref
-import re
-import warnings
-
-try:
- from collections import deque
-except ImportError:
- deque = list
-
-RegexType = type(re.compile(""))
-
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-from twisted.python.util import unsignedID
-from twisted.python.deprecate import deprecated, deprecatedModuleAttribute
-from twisted.python.deprecate import _fullyQualifiedName as fullyQualifiedName
-from twisted.python.versions import Version
-
-
-
-class Settable:
- """
- A mixin class for syntactic sugar. Lets you assign attributes by
- calling with keyword arguments; for example, C{x(a=b,c=d,y=z)} is the
- same as C{x.a=b;x.c=d;x.y=z}. The most useful place for this is
- where you don't want to name a variable, but you do want to set
- some attributes; for example, C{X()(y=z,a=b)}.
- """
-
- deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "Settable is old and untested. Please write your own version of this "
- "functionality if you need it.", "twisted.python.reflect", "Settable")
-
- def __init__(self, **kw):
- self(**kw)
-
- def __call__(self,**kw):
- for key,val in kw.items():
- setattr(self,key,val)
- return self
-
-
-class AccessorType(type):
- """
- Metaclass that generates properties automatically.
-
- This is for Python 2.2 and up.
-
- Using this metaclass for your class will give you explicit accessor
- methods; a method called set_foo, will automatically create a property
- 'foo' that uses set_foo as a setter method. Same for get_foo and del_foo.
-
- Note that this will only work on methods that are present on class
- creation. If you add methods after the class is defined they will not
- automatically become properties. Likewise, class attributes will only
- be used if they are present upon class creation, and no getter function
- was set - if a getter is present, the class attribute will be ignored.
-
- This is a 2.2-only alternative to the Accessor mixin - just set in your
- class definition::
-
- __metaclass__ = AccessorType
-
- """
-
- deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "AccessorType is old and untested. Please write your own version of "
- "this functionality if you need it.", "twisted.python.reflect",
- "AccessorType")
-
- def __init__(self, name, bases, d):
- type.__init__(self, name, bases, d)
- accessors = {}
- prefixs = ["get_", "set_", "del_"]
- for k in d.keys():
- v = getattr(self, k)
- for i in range(3):
- if k.startswith(prefixs[i]):
- accessors.setdefault(k[4:], [None, None, None])[i] = v
- for name, (getter, setter, deler) in accessors.items():
- # create default behaviours for the property - if we leave
- # the getter as None we won't be able to getattr, etc..
- if getter is None:
- if hasattr(self, name):
- value = getattr(self, name)
- def getter(this, value=value, name=name):
- if name in this.__dict__:
- return this.__dict__[name]
- else:
- return value
- else:
- def getter(this, name=name):
- if name in this.__dict__:
- return this.__dict__[name]
- else:
- raise AttributeError("no such attribute %r" % name)
- if setter is None:
- def setter(this, value, name=name):
- this.__dict__[name] = value
- if deler is None:
- def deler(this, name=name):
- del this.__dict__[name]
- setattr(self, name, property(getter, setter, deler, ""))
-
-
-class PropertyAccessor(object):
- """
- A mixin class for Python 2.2 that uses AccessorType.
-
- This provides compatability with the pre-2.2 Accessor mixin, up
- to a point.
-
- Extending this class will give you explicit accessor methods; a
- method called set_foo, for example, is the same as an if statement
- in __setattr__ looking for 'foo'. Same for get_foo and del_foo.
-
- There are also reallyDel and reallySet methods, so you can
- override specifics in subclasses without clobbering __setattr__
- and __getattr__, or using non-2.1 compatible code.
-
- There is are incompatibilities with Accessor - accessor
- methods added after class creation will *not* be detected. OTOH,
- this method is probably way faster.
-
- In addition, class attributes will only be used if no getter
- was defined, and instance attributes will not override getter methods
- whereas in original Accessor the class attribute or instance attribute
- would override the getter method.
- """
- # addendum to above:
- # The behaviour of Accessor is wrong IMHO, and I've found bugs
- # caused by it.
- # -- itamar
-
- deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "PropertyAccessor is old and untested. Please write your own version "
- "of this functionality if you need it.", "twisted.python.reflect",
- "PropertyAccessor")
- __metaclass__ = AccessorType
-
- def reallySet(self, k, v):
- self.__dict__[k] = v
-
- def reallyDel(self, k):
- del self.__dict__[k]
-
-
-class Accessor:
- """
- Extending this class will give you explicit accessor methods; a
- method called C{set_foo}, for example, is the same as an if statement
- in L{__setattr__} looking for C{'foo'}. Same for C{get_foo} and
- C{del_foo}. There are also L{reallyDel} and L{reallySet} methods,
- so you can override specifics in subclasses without clobbering
- L{__setattr__} and L{__getattr__}.
-
- This implementation is for Python 2.1.
- """
-
- deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "Accessor is an implementation for Python 2.1 which is no longer "
- "supported by Twisted.", "twisted.python.reflect", "Accessor")
-
- def __setattr__(self, k,v):
- kstring='set_%s'%k
- if hasattr(self.__class__,kstring):
- return getattr(self,kstring)(v)
- else:
- self.reallySet(k,v)
-
- def __getattr__(self, k):
- kstring='get_%s'%k
- if hasattr(self.__class__,kstring):
- return getattr(self,kstring)()
- raise AttributeError("%s instance has no accessor for: %s" % (qual(self.__class__),k))
-
- def __delattr__(self, k):
- kstring='del_%s'%k
- if hasattr(self.__class__,kstring):
- getattr(self,kstring)()
- return
- self.reallyDel(k)
-
- def reallySet(self, k,v):
- """
- *actually* set self.k to v without incurring side-effects.
- This is a hook to be overridden by subclasses.
- """
- if k == "__dict__":
- self.__dict__.clear()
- self.__dict__.update(v)
- else:
- self.__dict__[k]=v
-
- def reallyDel(self, k):
- """
- *actually* del self.k without incurring side-effects. This is a
- hook to be overridden by subclasses.
- """
- del self.__dict__[k]
-
-# just in case
-OriginalAccessor = Accessor
-deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "OriginalAccessor is a reference to class twisted.python.reflect.Accessor "
- "which is deprecated.", "twisted.python.reflect", "OriginalAccessor")
-
-
-class Summer(Accessor):
- """
- Extend from this class to get the capability to maintain 'related
- sums'. Have a tuple in your class like the following::
-
- sums=(('amount','credit','credit_total'),
- ('amount','debit','debit_total'))
-
- and the 'credit_total' member of the 'credit' member of self will
- always be incremented when the 'amount' member of self is
- incremented, similiarly for the debit versions.
- """
-
- deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "Summer is a child class of twisted.python.reflect.Accessor which is "
- "deprecated.", "twisted.python.reflect", "Summer")
-
- def reallySet(self, k,v):
- "This method does the work."
- for sum in self.sums:
- attr=sum[0]
- obj=sum[1]
- objattr=sum[2]
- if k == attr:
- try:
- oldval=getattr(self, attr)
- except:
- oldval=0
- diff=v-oldval
- if hasattr(self, obj):
- ob=getattr(self,obj)
- if ob is not None:
- try:oldobjval=getattr(ob, objattr)
- except:oldobjval=0.0
- setattr(ob,objattr,oldobjval+diff)
-
- elif k == obj:
- if hasattr(self, attr):
- x=getattr(self,attr)
- setattr(self,attr,0)
- y=getattr(self,k)
- Accessor.reallySet(self,k,v)
- setattr(self,attr,x)
- Accessor.reallySet(self,y,v)
- Accessor.reallySet(self,k,v)
-
-
-class QueueMethod:
- """
- I represent a method that doesn't exist yet.
- """
- def __init__(self, name, calls):
- self.name = name
- self.calls = calls
- def __call__(self, *args):
- self.calls.append((self.name, args))
-
-
-def funcinfo(function):
- """
- this is more documentation for myself than useful code.
- """
- warnings.warn(
- "[v2.5] Use inspect.getargspec instead of twisted.python.reflect.funcinfo",
- DeprecationWarning,
- stacklevel=2)
- code=function.func_code
- name=function.func_name
- argc=code.co_argcount
- argv=code.co_varnames[:argc]
- defaults=function.func_defaults
-
- out = []
-
- out.append('The function %s accepts %s arguments' % (name ,argc))
- if defaults:
- required=argc-len(defaults)
- out.append('It requires %s arguments' % required)
- out.append('The arguments required are: %s' % argv[:required])
- out.append('additional arguments are:')
- for i in range(argc-required):
- j=i+required
- out.append('%s which has a default of' % (argv[j], defaults[i]))
- return out
-
-
-ISNT=0
-WAS=1
-IS=2
-
-
-def fullFuncName(func):
- qualName = (str(pickle.whichmodule(func, func.__name__)) + '.' + func.__name__)
- if namedObject(qualName) is not func:
- raise Exception("Couldn't find %s as %s." % (func, qualName))
- return qualName
-
-
-def qual(clazz):
- """
- Return full import path of a class.
- """
- return clazz.__module__ + '.' + clazz.__name__
-
-
-def getcurrent(clazz):
- assert type(clazz) == types.ClassType, 'must be a class...'
- module = namedModule(clazz.__module__)
- currclass = getattr(module, clazz.__name__, None)
- if currclass is None:
- return clazz
- return currclass
-
-
-def getClass(obj):
- """
- Return the class or type of object 'obj'.
- Returns sensible result for oldstyle and newstyle instances and types.
- """
- if hasattr(obj, '__class__'):
- return obj.__class__
- else:
- return type(obj)
-
-# class graph nonsense
-
-# I should really have a better name for this...
-def isinst(inst,clazz):
- if type(inst) != types.InstanceType or type(clazz)!= types.ClassType:
- return isinstance(inst,clazz)
- cl = inst.__class__
- cl2 = getcurrent(cl)
- clazz = getcurrent(clazz)
- if issubclass(cl2,clazz):
- if cl == cl2:
- return WAS
- else:
- inst.__class__ = cl2
- return IS
- else:
- return ISNT
-
-
-def namedModule(name):
- """
- Return a module given its name.
- """
- topLevel = __import__(name)
- packages = name.split(".")[1:]
- m = topLevel
- for p in packages:
- m = getattr(m, p)
- return m
-
-
-def namedObject(name):
- """
- Get a fully named module-global object.
- """
- classSplit = name.split('.')
- module = namedModule('.'.join(classSplit[:-1]))
- return getattr(module, classSplit[-1])
-
-namedClass = namedObject # backwards compat
-
-
-
-class _NoModuleFound(Exception):
- """
- No module was found because none exists.
- """
-
-
-class InvalidName(ValueError):
- """
- The given name is not a dot-separated list of Python objects.
- """
-
-
-class ModuleNotFound(InvalidName):
- """
- The module associated with the given name doesn't exist and it can't be
- imported.
- """
-
-
-class ObjectNotFound(InvalidName):
- """
- The object associated with the given name doesn't exist and it can't be
- imported.
- """
-
-
-def _importAndCheckStack(importName):
- """
- Import the given name as a module, then walk the stack to determine whether
- the failure was the module not existing, or some code in the module (for
- example a dependent import) failing. This can be helpful to determine
- whether any actual application code was run. For example, to distiguish
- administrative error (entering the wrong module name), from programmer
- error (writing buggy code in a module that fails to import).
-
- @raise Exception: if something bad happens. This can be any type of
- exception, since nobody knows what loading some arbitrary code might do.
-
- @raise _NoModuleFound: if no module was found.
- """
- try:
- try:
- return __import__(importName)
- except ImportError:
- excType, excValue, excTraceback = sys.exc_info()
- while excTraceback:
- execName = excTraceback.tb_frame.f_globals["__name__"]
- if (execName is None or # python 2.4+, post-cleanup
- execName == importName): # python 2.3, no cleanup
- raise excType, excValue, excTraceback
- excTraceback = excTraceback.tb_next
- raise _NoModuleFound()
- except:
- # Necessary for cleaning up modules in 2.3.
- sys.modules.pop(importName, None)
- raise
-
-
-
-def namedAny(name):
- """
- Retrieve a Python object by its fully qualified name from the global Python
- module namespace. The first part of the name, that describes a module,
- will be discovered and imported. Each subsequent part of the name is
- treated as the name of an attribute of the object specified by all of the
- name which came before it. For example, the fully-qualified name of this
- object is 'twisted.python.reflect.namedAny'.
-
- @type name: L{str}
- @param name: The name of the object to return.
-
- @raise InvalidName: If the name is an empty string, starts or ends with
- a '.', or is otherwise syntactically incorrect.
-
- @raise ModuleNotFound: If the name is syntactically correct but the
- module it specifies cannot be imported because it does not appear to
- exist.
-
- @raise ObjectNotFound: If the name is syntactically correct, includes at
- least one '.', but the module it specifies cannot be imported because
- it does not appear to exist.
-
- @raise AttributeError: If an attribute of an object along the way cannot be
- accessed, or a module along the way is not found.
-
- @return: the Python object identified by 'name'.
- """
- if not name:
- raise InvalidName('Empty module name')
-
- names = name.split('.')
-
- # if the name starts or ends with a '.' or contains '..', the __import__
- # will raise an 'Empty module name' error. This will provide a better error
- # message.
- if '' in names:
- raise InvalidName(
- "name must be a string giving a '.'-separated list of Python "
- "identifiers, not %r" % (name,))
-
- topLevelPackage = None
- moduleNames = names[:]
- while not topLevelPackage:
- if moduleNames:
- trialname = '.'.join(moduleNames)
- try:
- topLevelPackage = _importAndCheckStack(trialname)
- except _NoModuleFound:
- moduleNames.pop()
- else:
- if len(names) == 1:
- raise ModuleNotFound("No module named %r" % (name,))
- else:
- raise ObjectNotFound('%r does not name an object' % (name,))
-
- obj = topLevelPackage
- for n in names[1:]:
- obj = getattr(obj, n)
-
- return obj
-
-
-
-def _determineClass(x):
- try:
- return x.__class__
- except:
- return type(x)
-
-
-
-def _determineClassName(x):
- c = _determineClass(x)
- try:
- return c.__name__
- except:
- try:
- return str(c)
- except:
- return '<BROKEN CLASS AT 0x%x>' % unsignedID(c)
-
-
-
-def _safeFormat(formatter, o):
- """
- Helper function for L{safe_repr} and L{safe_str}.
- """
- try:
- return formatter(o)
- except:
- io = StringIO()
- traceback.print_exc(file=io)
- className = _determineClassName(o)
- tbValue = io.getvalue()
- return "<%s instance at 0x%x with %s error:\n %s>" % (
- className, unsignedID(o), formatter.__name__, tbValue)
-
-
-
-def safe_repr(o):
- """
- safe_repr(anything) -> string
-
- Returns a string representation of an object, or a string containing a
- traceback, if that object's __repr__ raised an exception.
- """
- return _safeFormat(repr, o)
-
-
-
-def safe_str(o):
- """
- safe_str(anything) -> string
-
- Returns a string representation of an object, or a string containing a
- traceback, if that object's __str__ raised an exception.
- """
- return _safeFormat(str, o)
-
-
-
-## the following were factored out of usage
-
-@deprecated(Version("Twisted", 11, 0, 0), "inspect.getmro")
-def allYourBase(classObj, baseClass=None):
- """
- allYourBase(classObj, baseClass=None) -> list of all base
- classes that are subclasses of baseClass, unless it is None,
- in which case all bases will be added.
- """
- l = []
- _accumulateBases(classObj, l, baseClass)
- return l
-
-
-@deprecated(Version("Twisted", 11, 0, 0), "inspect.getmro")
-def accumulateBases(classObj, l, baseClass=None):
- _accumulateBases(classObj, l, baseClass)
-
-
-def _accumulateBases(classObj, l, baseClass=None):
- for base in classObj.__bases__:
- if baseClass is None or issubclass(base, baseClass):
- l.append(base)
- _accumulateBases(base, l, baseClass)
-
-
-def prefixedMethodNames(classObj, prefix):
- """
- A list of method names with a given prefix in a given class.
- """
- dct = {}
- addMethodNamesToDict(classObj, dct, prefix)
- return dct.keys()
-
-
-def addMethodNamesToDict(classObj, dict, prefix, baseClass=None):
- """
- addMethodNamesToDict(classObj, dict, prefix, baseClass=None) -> dict
- this goes through 'classObj' (and its bases) and puts method names
- starting with 'prefix' in 'dict' with a value of 1. if baseClass isn't
- None, methods will only be added if classObj is-a baseClass
-
- If the class in question has the methods 'prefix_methodname' and
- 'prefix_methodname2', the resulting dict should look something like:
- {"methodname": 1, "methodname2": 1}.
- """
- for base in classObj.__bases__:
- addMethodNamesToDict(base, dict, prefix, baseClass)
-
- if baseClass is None or baseClass in classObj.__bases__:
- for name, method in classObj.__dict__.items():
- optName = name[len(prefix):]
- if ((type(method) is types.FunctionType)
- and (name[:len(prefix)] == prefix)
- and (len(optName))):
- dict[optName] = 1
-
-
-def prefixedMethods(obj, prefix=''):
- """
- A list of methods with a given prefix on a given instance.
- """
- dct = {}
- accumulateMethods(obj, dct, prefix)
- return dct.values()
-
-
-def accumulateMethods(obj, dict, prefix='', curClass=None):
- """
- accumulateMethods(instance, dict, prefix)
- I recurse through the bases of instance.__class__, and add methods
- beginning with 'prefix' to 'dict', in the form of
- {'methodname':*instance*method_object}.
- """
- if not curClass:
- curClass = obj.__class__
- for base in curClass.__bases__:
- accumulateMethods(obj, dict, prefix, base)
-
- for name, method in curClass.__dict__.items():
- optName = name[len(prefix):]
- if ((type(method) is types.FunctionType)
- and (name[:len(prefix)] == prefix)
- and (len(optName))):
- dict[optName] = getattr(obj, name)
-
-
-def accumulateClassDict(classObj, attr, adict, baseClass=None):
- """
- Accumulate all attributes of a given name in a class hierarchy into a single dictionary.
-
- Assuming all class attributes of this name are dictionaries.
- If any of the dictionaries being accumulated have the same key, the
- one highest in the class heirarchy wins.
- (XXX: If \"higest\" means \"closest to the starting class\".)
-
- Ex::
-
- class Soy:
- properties = {\"taste\": \"bland\"}
-
- class Plant:
- properties = {\"colour\": \"green\"}
-
- class Seaweed(Plant):
- pass
-
- class Lunch(Soy, Seaweed):
- properties = {\"vegan\": 1 }
-
- dct = {}
-
- accumulateClassDict(Lunch, \"properties\", dct)
-
- print dct
-
- {\"taste\": \"bland\", \"colour\": \"green\", \"vegan\": 1}
- """
- for base in classObj.__bases__:
- accumulateClassDict(base, attr, adict)
- if baseClass is None or baseClass in classObj.__bases__:
- adict.update(classObj.__dict__.get(attr, {}))
-
-
-def accumulateClassList(classObj, attr, listObj, baseClass=None):
- """
- Accumulate all attributes of a given name in a class heirarchy into a single list.
-
- Assuming all class attributes of this name are lists.
- """
- for base in classObj.__bases__:
- accumulateClassList(base, attr, listObj)
- if baseClass is None or baseClass in classObj.__bases__:
- listObj.extend(classObj.__dict__.get(attr, []))
-
-
-def isSame(a, b):
- return (a is b)
-
-
-def isLike(a, b):
- return (a == b)
-
-
-def modgrep(goal):
- return objgrep(sys.modules, goal, isLike, 'sys.modules')
-
-
-def isOfType(start, goal):
- return ((type(start) is goal) or
- (isinstance(start, types.InstanceType) and
- start.__class__ is goal))
-
-
-def findInstances(start, t):
- return objgrep(start, t, isOfType)
-
-
-def objgrep(start, goal, eq=isLike, path='', paths=None, seen=None, showUnknowns=0, maxDepth=None):
- """
- An insanely CPU-intensive process for finding stuff.
- """
- if paths is None:
- paths = []
- if seen is None:
- seen = {}
- if eq(start, goal):
- paths.append(path)
- if id(start) in seen:
- if seen[id(start)] is start:
- return
- if maxDepth is not None:
- if maxDepth == 0:
- return
- maxDepth -= 1
- seen[id(start)] = start
- if isinstance(start, types.DictionaryType):
- for k, v in start.items():
- objgrep(k, goal, eq, path+'{'+repr(v)+'}', paths, seen, showUnknowns, maxDepth)
- objgrep(v, goal, eq, path+'['+repr(k)+']', paths, seen, showUnknowns, maxDepth)
- elif isinstance(start, (list, tuple, deque)):
- for idx in xrange(len(start)):
- objgrep(start[idx], goal, eq, path+'['+str(idx)+']', paths, seen, showUnknowns, maxDepth)
- elif isinstance(start, types.MethodType):
- objgrep(start.im_self, goal, eq, path+'.im_self', paths, seen, showUnknowns, maxDepth)
- objgrep(start.im_func, goal, eq, path+'.im_func', paths, seen, showUnknowns, maxDepth)
- objgrep(start.im_class, goal, eq, path+'.im_class', paths, seen, showUnknowns, maxDepth)
- elif hasattr(start, '__dict__'):
- for k, v in start.__dict__.items():
- objgrep(v, goal, eq, path+'.'+k, paths, seen, showUnknowns, maxDepth)
- if isinstance(start, types.InstanceType):
- objgrep(start.__class__, goal, eq, path+'.__class__', paths, seen, showUnknowns, maxDepth)
- elif isinstance(start, weakref.ReferenceType):
- objgrep(start(), goal, eq, path+'()', paths, seen, showUnknowns, maxDepth)
- elif (isinstance(start, types.StringTypes+
- (types.IntType, types.FunctionType,
- types.BuiltinMethodType, RegexType, types.FloatType,
- types.NoneType, types.FileType)) or
- type(start).__name__ in ('wrapper_descriptor', 'method_descriptor',
- 'member_descriptor', 'getset_descriptor')):
- pass
- elif showUnknowns:
- print 'unknown type', type(start), start
- return paths
-
-
-def filenameToModuleName(fn):
- """
- Convert a name in the filesystem to the name of the Python module it is.
-
- This is agressive about getting a module name back from a file; it will
- always return a string. Agressive means 'sometimes wrong'; it won't look
- at the Python path or try to do any error checking: don't use this method
- unless you already know that the filename you're talking about is a Python
- module.
- """
- fullName = os.path.abspath(fn)
- base = os.path.basename(fn)
- if not base:
- # this happens when fn ends with a path separator, just skit it
- base = os.path.basename(fn[:-1])
- modName = os.path.splitext(base)[0]
- while 1:
- fullName = os.path.dirname(fullName)
- if os.path.exists(os.path.join(fullName, "__init__.py")):
- modName = "%s.%s" % (os.path.basename(fullName), modName)
- else:
- break
- return modName
-
-
-
-__all__ = [
- 'InvalidName', 'ModuleNotFound', 'ObjectNotFound',
-
- 'ISNT', 'WAS', 'IS',
-
- 'Settable', 'AccessorType', 'PropertyAccessor', 'Accessor', 'Summer',
- 'QueueMethod', 'OriginalAccessor',
-
- 'funcinfo', 'fullFuncName', 'qual', 'getcurrent', 'getClass', 'isinst',
- 'namedModule', 'namedObject', 'namedClass', 'namedAny',
- 'safe_repr', 'safe_str', 'allYourBase', 'accumulateBases',
- 'prefixedMethodNames', 'addMethodNamesToDict', 'prefixedMethods',
- 'accumulateClassDict', 'accumulateClassList', 'isSame', 'isLike',
- 'modgrep', 'isOfType', 'findInstances', 'objgrep', 'filenameToModuleName',
- 'fullyQualifiedName']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/release.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/release.py
deleted file mode 100755
index 2454792d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/release.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A release-automation toolkit.
-
-Don't use this outside of Twisted.
-
-Maintainer: Christopher Armstrong
-"""
-
-import os
-
-
-# errors
-
-class DirectoryExists(OSError):
- """
- Some directory exists when it shouldn't.
- """
- pass
-
-
-
-class DirectoryDoesntExist(OSError):
- """
- Some directory doesn't exist when it should.
- """
- pass
-
-
-
-class CommandFailed(OSError):
- pass
-
-
-
-# utilities
-
-def sh(command, null=True, prompt=False):
- """
- I'll try to execute C{command}, and if C{prompt} is true, I'll
- ask before running it. If the command returns something other
- than 0, I'll raise C{CommandFailed(command)}.
- """
- print "--$", command
-
- if prompt:
- if raw_input("run ?? ").startswith('n'):
- return
- if null:
- command = "%s > /dev/null" % command
- if os.system(command) != 0:
- raise CommandFailed(command)
-
-
-
-def runChdirSafe(f, *args, **kw):
- origdir = os.path.abspath('.')
- try:
- return f(*args, **kw)
- finally:
- os.chdir(origdir)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/roots.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/roots.py
deleted file mode 100755
index ee3c8a39..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/roots.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# -*- test-case-name: twisted.test.test_roots -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Twisted Python Roots: an abstract hierarchy representation for Twisted.
-
-Maintainer: Glyph Lefkowitz
-"""
-
-# System imports
-import types
-from twisted.python import reflect
-
-class NotSupportedError(NotImplementedError):
- """
- An exception meaning that the tree-manipulation operation
- you're attempting to perform is not supported.
- """
-
-
-class Request:
- """I am an abstract representation of a request for an entity.
-
- I also function as the response. The request is responded to by calling
- self.write(data) until there is no data left and then calling
- self.finish().
- """
- # This attribute should be set to the string name of the protocol being
- # responded to (e.g. HTTP or FTP)
- wireProtocol = None
- def write(self, data):
- """Add some data to the response to this request.
- """
- raise NotImplementedError("%s.write" % reflect.qual(self.__class__))
-
- def finish(self):
- """The response to this request is finished; flush all data to the network stream.
- """
- raise NotImplementedError("%s.finish" % reflect.qual(self.__class__))
-
-
-class Entity:
- """I am a terminal object in a hierarchy, with no children.
-
- I represent a null interface; certain non-instance objects (strings and
- integers, notably) are Entities.
-
- Methods on this class are suggested to be implemented, but are not
- required, and will be emulated on a per-protocol basis for types which do
- not handle them.
- """
- def render(self, request):
- """
- I produce a stream of bytes for the request, by calling request.write()
- and request.finish().
- """
- raise NotImplementedError("%s.render" % reflect.qual(self.__class__))
-
-
-class Collection:
- """I represent a static collection of entities.
-
- I contain methods designed to represent collections that can be dynamically
- created.
- """
-
- def __init__(self, entities=None):
- """Initialize me.
- """
- if entities is not None:
- self.entities = entities
- else:
- self.entities = {}
-
- def getStaticEntity(self, name):
- """Get an entity that was added to me using putEntity.
-
- This method will return 'None' if it fails.
- """
- return self.entities.get(name)
-
- def getDynamicEntity(self, name, request):
- """Subclass this to generate an entity on demand.
-
- This method should return 'None' if it fails.
- """
-
- def getEntity(self, name, request):
- """Retrieve an entity from me.
-
- I will first attempt to retrieve an entity statically; static entities
- will obscure dynamic ones. If that fails, I will retrieve the entity
- dynamically.
-
- If I cannot retrieve an entity, I will return 'None'.
- """
- ent = self.getStaticEntity(name)
- if ent is not None:
- return ent
- ent = self.getDynamicEntity(name, request)
- if ent is not None:
- return ent
- return None
-
- def putEntity(self, name, entity):
- """Store a static reference on 'name' for 'entity'.
-
- Raises a KeyError if the operation fails.
- """
- self.entities[name] = entity
-
- def delEntity(self, name):
- """Remove a static reference for 'name'.
-
- Raises a KeyError if the operation fails.
- """
- del self.entities[name]
-
- def storeEntity(self, name, request):
- """Store an entity for 'name', based on the content of 'request'.
- """
- raise NotSupportedError("%s.storeEntity" % reflect.qual(self.__class__))
-
- def removeEntity(self, name, request):
- """Remove an entity for 'name', based on the content of 'request'.
- """
- raise NotSupportedError("%s.removeEntity" % reflect.qual(self.__class__))
-
- def listStaticEntities(self):
- """Retrieve a list of all name, entity pairs that I store references to.
-
- See getStaticEntity.
- """
- return self.entities.items()
-
- def listDynamicEntities(self, request):
- """A list of all name, entity that I can generate on demand.
-
- See getDynamicEntity.
- """
- return []
-
- def listEntities(self, request):
- """Retrieve a list of all name, entity pairs I contain.
-
- See getEntity.
- """
- return self.listStaticEntities() + self.listDynamicEntities(request)
-
- def listStaticNames(self):
- """Retrieve a list of the names of entities that I store references to.
-
- See getStaticEntity.
- """
- return self.entities.keys()
-
-
- def listDynamicNames(self):
- """Retrieve a list of the names of entities that I store references to.
-
- See getDynamicEntity.
- """
- return []
-
-
- def listNames(self, request):
- """Retrieve a list of all names for entities that I contain.
-
- See getEntity.
- """
- return self.listStaticNames()
-
-
-class ConstraintViolation(Exception):
- """An exception raised when a constraint is violated.
- """
-
-
-class Constrained(Collection):
- """A collection that has constraints on its names and/or entities."""
-
- def nameConstraint(self, name):
- """A method that determines whether an entity may be added to me with a given name.
-
- If the constraint is satisfied, return 1; if the constraint is not
- satisfied, either return 0 or raise a descriptive ConstraintViolation.
- """
- return 1
-
- def entityConstraint(self, entity):
- """A method that determines whether an entity may be added to me.
-
- If the constraint is satisfied, return 1; if the constraint is not
- satisfied, either return 0 or raise a descriptive ConstraintViolation.
- """
- return 1
-
- def reallyPutEntity(self, name, entity):
- Collection.putEntity(self, name, entity)
-
- def putEntity(self, name, entity):
- """Store an entity if it meets both constraints.
-
- Otherwise raise a ConstraintViolation.
- """
- if self.nameConstraint(name):
- if self.entityConstraint(entity):
- self.reallyPutEntity(name, entity)
- else:
- raise ConstraintViolation("Entity constraint violated.")
- else:
- raise ConstraintViolation("Name constraint violated.")
-
-
-class Locked(Constrained):
- """A collection that can be locked from adding entities."""
-
- locked = 0
-
- def lock(self):
- self.locked = 1
-
- def entityConstraint(self, entity):
- return not self.locked
-
-
-class Homogenous(Constrained):
- """A homogenous collection of entities.
-
- I will only contain entities that are an instance of the class or type
- specified by my 'entityType' attribute.
- """
-
- entityType = types.InstanceType
-
- def entityConstraint(self, entity):
- if isinstance(entity, self.entityType):
- return 1
- else:
- raise ConstraintViolation("%s of incorrect type (%s)" %
- (entity, self.entityType))
-
- def getNameType(self):
- return "Name"
-
- def getEntityType(self):
- return self.entityType.__name__
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/runtime.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/runtime.py
deleted file mode 100755
index da078bf5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/runtime.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_runtime -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-# System imports
-import os
-import sys
-import time
-import imp
-
-
-
-def shortPythonVersion():
- """
- Returns the Python version as a dot-separated string.
- """
- return "%s.%s.%s" % sys.version_info[:3]
-
-
-
-knownPlatforms = {
- 'nt': 'win32',
- 'ce': 'win32',
- 'posix': 'posix',
- 'java': 'java',
- 'org.python.modules.os': 'java',
- }
-
-
-
-_timeFunctions = {
- #'win32': time.clock,
- 'win32': time.time,
- }
-
-
-
-class Platform:
- """Gives us information about the platform we're running on"""
-
- type = knownPlatforms.get(os.name)
- seconds = staticmethod(_timeFunctions.get(type, time.time))
- _platform = sys.platform
-
- def __init__(self, name=None, platform=None):
- if name is not None:
- self.type = knownPlatforms.get(name)
- self.seconds = _timeFunctions.get(self.type, time.time)
- if platform is not None:
- self._platform = platform
-
-
- def isKnown(self):
- """Do we know about this platform?"""
- return self.type != None
-
-
- def getType(self):
- """Return 'posix', 'win32' or 'java'"""
- return self.type
-
-
- def isMacOSX(self):
- """Check if current platform is Mac OS X.
-
- @return: C{True} if the current platform has been detected as OS X
- @rtype: C{bool}
- """
- return self._platform == "darwin"
-
-
- def isWinNT(self):
- """Are we running in Windows NT?"""
- if self.getType() == 'win32':
- import _winreg
- try:
- k = _winreg.OpenKeyEx(
- _winreg.HKEY_LOCAL_MACHINE,
- r'Software\Microsoft\Windows NT\CurrentVersion')
- _winreg.QueryValueEx(k, 'SystemRoot')
- return 1
- except WindowsError:
- return 0
- # not windows NT
- return 0
-
-
- def isWindows(self):
- return self.getType() == 'win32'
-
-
- def isVista(self):
- """
- Check if current platform is Windows Vista or Windows Server 2008.
-
- @return: C{True} if the current platform has been detected as Vista
- @rtype: C{bool}
- """
- if getattr(sys, "getwindowsversion", None) is not None:
- return sys.getwindowsversion()[0] == 6
- else:
- return False
-
-
- def isLinux(self):
- """
- Check if current platform is Linux.
-
- @return: C{True} if the current platform has been detected as Linux.
- @rtype: C{bool}
- """
- return self._platform.startswith("linux")
-
-
- def supportsThreads(self):
- """Can threads be created?
- """
- try:
- return imp.find_module('thread')[0] is None
- except ImportError:
- return False
-
-
- def supportsINotify(self):
- """
- Return C{True} if we can use the inotify API on this platform.
-
- @since: 10.1
- """
- try:
- from twisted.python._inotify import INotifyError, init
- except ImportError:
- return False
- try:
- os.close(init())
- except INotifyError:
- return False
- return True
-
-
-platform = Platform()
-platformType = platform.getType()
-seconds = platform.seconds
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.c
deleted file mode 100644
index 4da6aab4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (c) Twisted Matrix Laboratories.
- * See LICENSE for details.
- */
-
-#define PY_SSIZE_T_CLEAN 1
-#include <Python.h>
-
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-/* This may cause some warnings, but if you want to get rid of them, upgrade
- * your Python version. */
-typedef int Py_ssize_t;
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <signal.h>
-
-/*
- * As per
- * <http://pubs.opengroup.org/onlinepubs/007904875/basedefs/sys/socket.h.html
- * #tag_13_61_05>:
- *
- * "To forestall portability problems, it is recommended that applications
- * not use values larger than (2**31)-1 for the socklen_t type."
- */
-
-#define SOCKLEN_MAX 0x7FFFFFFF
-
-PyObject *sendmsg_socket_error;
-
-static PyObject *sendmsg_sendmsg(PyObject *self, PyObject *args, PyObject *keywds);
-static PyObject *sendmsg_recvmsg(PyObject *self, PyObject *args, PyObject *keywds);
-static PyObject *sendmsg_getsockfam(PyObject *self, PyObject *args, PyObject *keywds);
-
-static char sendmsg_doc[] = "\
-Bindings for sendmsg(2), recvmsg(2), and a minimal helper for inspecting\n\
-address family of a socket.\n\
-";
-
-static char sendmsg_sendmsg_doc[] = "\
-Wrap the C sendmsg(2) function for sending \"messages\" on a socket.\n\
-\n\
-@param fd: The file descriptor of the socket over which to send a message.\n\
-@type fd: C{int}\n\
-\n\
-@param data: Bytes to write to the socket.\n\
-@type data: C{str}\n\
-\n\
-@param flags: Flags to affect how the message is sent. See the C{MSG_}\n\
- constants in the sendmsg(2) manual page. By default no flags are set.\n\
-@type flags: C{int}\n\
-\n\
-@param ancillary: Extra data to send over the socket outside of the normal\n\
- datagram or stream mechanism. By default no ancillary data is sent.\n\
-@type ancillary: C{list} of C{tuple} of C{int}, C{int}, and C{str}.\n\
-\n\
-@raise OverflowError: Raised if too much ancillary data is given.\n\
-@raise socket.error: Raised if the underlying syscall indicates an error.\n\
-\n\
-@return: The return value of the underlying syscall, if it succeeds.\n\
-";
-
-static char sendmsg_recvmsg_doc[] = "\
-Wrap the C recvmsg(2) function for receiving \"messages\" on a socket.\n\
-\n\
-@param fd: The file descriptor of the socket over which to receve a message.\n\
-@type fd: C{int}\n\
-\n\
-@param flags: Flags to affect how the message is sent. See the C{MSG_}\n\
- constants in the sendmsg(2) manual page. By default no flags are set.\n\
-@type flags: C{int}\n\
-\n\
-@param maxsize: The maximum number of bytes to receive from the socket\n\
- using the datagram or stream mechanism. The default maximum is 8192.\n\
-@type maxsize: C{int}\n\
-\n\
-@param cmsg_size: The maximum number of bytes to receive from the socket\n\
- outside of the normal datagram or stream mechanism. The default maximum is 4096.\n\
-\n\
-@raise OverflowError: Raised if too much ancillary data is given.\n\
-@raise socket.error: Raised if the underlying syscall indicates an error.\n\
-\n\
-@return: A C{tuple} of three elements: the bytes received using the\n\
- datagram/stream mechanism, flags as an C{int} describing the data\n\
- received, and a C{list} of C{tuples} giving ancillary received data.\n\
-";
-
-static char sendmsg_getsockfam_doc[] = "\
-Retrieve the address family of a given socket.\n\
-\n\
-@param fd: The file descriptor of the socket the address family of which\n\
- to retrieve.\n\
-@type fd: C{int}\n\
-\n\
-@raise socket.error: Raised if the underlying getsockname call indicates\n\
- an error.\n\
-\n\
-@return: A C{int} representing the address family of the socket. For\n\
- example, L{socket.AF_INET}, L{socket.AF_INET6}, or L{socket.AF_UNIX}.\n\
-";
-
-static PyMethodDef sendmsg_methods[] = {
- {"send1msg", (PyCFunction) sendmsg_sendmsg, METH_VARARGS | METH_KEYWORDS,
- sendmsg_sendmsg_doc},
- {"recv1msg", (PyCFunction) sendmsg_recvmsg, METH_VARARGS | METH_KEYWORDS,
- sendmsg_recvmsg_doc},
- {"getsockfam", (PyCFunction) sendmsg_getsockfam,
- METH_VARARGS | METH_KEYWORDS, sendmsg_getsockfam_doc},
- {NULL, NULL, 0, NULL}
-};
-
-
-PyMODINIT_FUNC initsendmsg(void) {
- PyObject *module;
-
- sendmsg_socket_error = NULL; /* Make sure that this has a known value
- before doing anything that might exit. */
-
- module = Py_InitModule3("sendmsg", sendmsg_methods, sendmsg_doc);
-
- if (!module) {
- return;
- }
-
- /*
- The following is the only value mentioned by POSIX:
- http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
- */
-
- if (-1 == PyModule_AddIntConstant(module, "SCM_RIGHTS", SCM_RIGHTS)) {
- return;
- }
-
-
- /* BSD, Darwin, Hurd */
-#if defined(SCM_CREDS)
- if (-1 == PyModule_AddIntConstant(module, "SCM_CREDS", SCM_CREDS)) {
- return;
- }
-#endif
-
- /* Linux */
-#if defined(SCM_CREDENTIALS)
- if (-1 == PyModule_AddIntConstant(module, "SCM_CREDENTIALS", SCM_CREDENTIALS)) {
- return;
- }
-#endif
-
- /* Apparently everywhere, but not standardized. */
-#if defined(SCM_TIMESTAMP)
- if (-1 == PyModule_AddIntConstant(module, "SCM_TIMESTAMP", SCM_TIMESTAMP)) {
- return;
- }
-#endif
-
- module = PyImport_ImportModule("socket");
- if (!module) {
- return;
- }
-
- sendmsg_socket_error = PyObject_GetAttrString(module, "error");
- if (!sendmsg_socket_error) {
- return;
- }
-}
-
-static PyObject *sendmsg_sendmsg(PyObject *self, PyObject *args, PyObject *keywds) {
-
- int fd;
- int flags = 0;
- Py_ssize_t sendmsg_result;
- struct msghdr message_header;
- struct iovec iov[1];
- PyObject *ancillary = NULL;
- PyObject *iterator = NULL;
- PyObject *item = NULL;
- PyObject *result_object = NULL;
-
- static char *kwlist[] = {"fd", "data", "flags", "ancillary", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(
- args, keywds, "it#|iO:sendmsg", kwlist,
- &fd,
- &iov[0].iov_base,
- &iov[0].iov_len,
- &flags,
- &ancillary)) {
- return NULL;
- }
-
- message_header.msg_name = NULL;
- message_header.msg_namelen = 0;
-
- message_header.msg_iov = iov;
- message_header.msg_iovlen = 1;
-
- message_header.msg_control = NULL;
- message_header.msg_controllen = 0;
-
- message_header.msg_flags = 0;
-
- if (ancillary) {
-
- if (!PyList_Check(ancillary)) {
- PyErr_Format(PyExc_TypeError,
- "send1msg argument 3 expected list, got %s",
- ancillary->ob_type->tp_name);
- goto finished;
- }
-
- iterator = PyObject_GetIter(ancillary);
-
- if (iterator == NULL) {
- goto finished;
- }
-
- size_t all_data_len = 0;
-
- /* First we need to know how big the buffer needs to be in order to
- have enough space for all of the messages. */
- while ( (item = PyIter_Next(iterator)) ) {
- int type, level;
- Py_ssize_t data_len;
- size_t prev_all_data_len;
- char *data;
-
- if (!PyTuple_Check(item)) {
- PyErr_Format(PyExc_TypeError,
- "send1msg argument 3 expected list of tuple, "
- "got list containing %s",
- item->ob_type->tp_name);
- goto finished;
- }
-
- if (!PyArg_ParseTuple(
- item, "iit#:sendmsg ancillary data (level, type, data)",
- &level, &type, &data, &data_len)) {
- goto finished;
- }
-
- prev_all_data_len = all_data_len;
- all_data_len += CMSG_SPACE(data_len);
-
- Py_DECREF(item);
- item = NULL;
-
- if (all_data_len < prev_all_data_len) {
- PyErr_Format(PyExc_OverflowError,
- "Too much msg_control to fit in a size_t: %zu",
- prev_all_data_len);
- goto finished;
- }
- }
-
- Py_DECREF(iterator);
- iterator = NULL;
-
- /* Allocate the buffer for all of the ancillary elements, if we have
- * any. */
- if (all_data_len) {
- if (all_data_len > SOCKLEN_MAX) {
- PyErr_Format(PyExc_OverflowError,
- "Too much msg_control to fit in a socklen_t: %zu",
- all_data_len);
- goto finished;
- }
- message_header.msg_control = PyMem_Malloc(all_data_len);
- if (!message_header.msg_control) {
- PyErr_NoMemory();
- goto finished;
- }
- } else {
- message_header.msg_control = NULL;
- }
- message_header.msg_controllen = (socklen_t) all_data_len;
-
- iterator = PyObject_GetIter(ancillary); /* again */
-
- if (!iterator) {
- goto finished;
- }
-
- /* Unpack the tuples into the control message. */
- struct cmsghdr *control_message = CMSG_FIRSTHDR(&message_header);
- while ( (item = PyIter_Next(iterator)) ) {
- int data_len, type, level;
- size_t data_size;
- unsigned char *data, *cmsg_data;
-
- /* We explicitly allocated enough space for all ancillary data
- above; if there isn't enough room, all bets are off. */
- assert(control_message);
-
- if (!PyArg_ParseTuple(item,
- "iit#:sendmsg ancillary data (level, type, data)",
- &level,
- &type,
- &data,
- &data_len)) {
- goto finished;
- }
-
- control_message->cmsg_level = level;
- control_message->cmsg_type = type;
- data_size = CMSG_LEN(data_len);
-
- if (data_size > SOCKLEN_MAX) {
- PyErr_Format(PyExc_OverflowError,
- "CMSG_LEN(%d) > SOCKLEN_MAX", data_len);
- goto finished;
- }
-
- control_message->cmsg_len = (socklen_t) data_size;
-
- cmsg_data = CMSG_DATA(control_message);
- memcpy(cmsg_data, data, data_len);
-
- Py_DECREF(item);
- item = NULL;
-
- control_message = CMSG_NXTHDR(&message_header, control_message);
- }
- Py_DECREF(iterator);
- iterator = NULL;
-
- if (PyErr_Occurred()) {
- goto finished;
- }
- }
-
- sendmsg_result = sendmsg(fd, &message_header, flags);
-
- if (sendmsg_result < 0) {
- PyErr_SetFromErrno(sendmsg_socket_error);
- goto finished;
- }
-
- result_object = Py_BuildValue("n", sendmsg_result);
-
- finished:
-
- if (item) {
- Py_DECREF(item);
- item = NULL;
- }
- if (iterator) {
- Py_DECREF(iterator);
- iterator = NULL;
- }
- if (message_header.msg_control) {
- PyMem_Free(message_header.msg_control);
- message_header.msg_control = NULL;
- }
- return result_object;
-}
-
-static PyObject *sendmsg_recvmsg(PyObject *self, PyObject *args, PyObject *keywds) {
- int fd = -1;
- int flags = 0;
- int maxsize = 8192;
- int cmsg_size = 4096;
- size_t cmsg_space;
- size_t cmsg_overhead;
- Py_ssize_t recvmsg_result;
-
- struct msghdr message_header;
- struct cmsghdr *control_message;
- struct iovec iov[1];
- char *cmsgbuf;
- PyObject *ancillary;
- PyObject *final_result = NULL;
-
- static char *kwlist[] = {"fd", "flags", "maxsize", "cmsg_size", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii:recvmsg", kwlist,
- &fd, &flags, &maxsize, &cmsg_size)) {
- return NULL;
- }
-
- cmsg_space = CMSG_SPACE(cmsg_size);
-
- /* overflow check */
- if (cmsg_space > SOCKLEN_MAX) {
- PyErr_Format(PyExc_OverflowError,
- "CMSG_SPACE(cmsg_size) greater than SOCKLEN_MAX: %d",
- cmsg_size);
- return NULL;
- }
-
- message_header.msg_name = NULL;
- message_header.msg_namelen = 0;
-
- iov[0].iov_len = maxsize;
- iov[0].iov_base = PyMem_Malloc(maxsize);
-
- if (!iov[0].iov_base) {
- PyErr_NoMemory();
- return NULL;
- }
-
- message_header.msg_iov = iov;
- message_header.msg_iovlen = 1;
-
- cmsgbuf = PyMem_Malloc(cmsg_space);
-
- if (!cmsgbuf) {
- PyMem_Free(iov[0].iov_base);
- PyErr_NoMemory();
- return NULL;
- }
-
- memset(cmsgbuf, 0, cmsg_space);
- message_header.msg_control = cmsgbuf;
- /* see above for overflow check */
- message_header.msg_controllen = (socklen_t) cmsg_space;
-
- recvmsg_result = recvmsg(fd, &message_header, flags);
- if (recvmsg_result < 0) {
- PyErr_SetFromErrno(sendmsg_socket_error);
- goto finished;
- }
-
- ancillary = PyList_New(0);
- if (!ancillary) {
- goto finished;
- }
-
- for (control_message = CMSG_FIRSTHDR(&message_header);
- control_message;
- control_message = CMSG_NXTHDR(&message_header,
- control_message)) {
- PyObject *entry;
-
- /* Some platforms apparently always fill out the ancillary data
- structure with a single bogus value if none is provided; ignore it,
- if that is the case. */
-
- if ((!(control_message->cmsg_level)) &&
- (!(control_message->cmsg_type))) {
- continue;
- }
-
- /*
- * Figure out how much of the cmsg size is cmsg structure overhead - in
- * other words, how much is not part of the application data. This lets
- * us compute the right application data size below. There should
- * really be a CMSG_ macro for this.
- */
- cmsg_overhead = (char*)CMSG_DATA(control_message) - (char*)control_message;
-
- entry = Py_BuildValue(
- "(iis#)",
- control_message->cmsg_level,
- control_message->cmsg_type,
- CMSG_DATA(control_message),
- (Py_ssize_t) (control_message->cmsg_len - cmsg_overhead));
-
- if (!entry) {
- Py_DECREF(ancillary);
- goto finished;
- }
-
- if (PyList_Append(ancillary, entry) < 0) {
- Py_DECREF(ancillary);
- Py_DECREF(entry);
- goto finished;
- } else {
- Py_DECREF(entry);
- }
- }
-
- final_result = Py_BuildValue(
- "s#iO",
- iov[0].iov_base,
- recvmsg_result,
- message_header.msg_flags,
- ancillary);
-
- Py_DECREF(ancillary);
-
- finished:
- PyMem_Free(iov[0].iov_base);
- PyMem_Free(cmsgbuf);
- return final_result;
-}
-
-static PyObject *sendmsg_getsockfam(PyObject *self, PyObject *args,
- PyObject *keywds) {
- int fd;
- struct sockaddr sa;
- static char *kwlist[] = {"fd", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, keywds, "i", kwlist, &fd)) {
- return NULL;
- }
- socklen_t sz = sizeof(sa);
- if (getsockname(fd, &sa, &sz)) {
- PyErr_SetFromErrno(sendmsg_socket_error);
- return NULL;
- }
- return Py_BuildValue("i", sa.sa_family);
-}
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.py
deleted file mode 100755
index 292545dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'sendmsg.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.so b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.so
deleted file mode 100755
index 7d14d551..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/sendmsg.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/shortcut.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/shortcut.py
deleted file mode 100755
index 6d6546b1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/shortcut.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Creation of Windows shortcuts.
-
-Requires win32all.
-"""
-
-from win32com.shell import shell
-import pythoncom
-import os
-
-
-def open(filename):
- """Open an existing shortcut for reading.
-
- @return: The shortcut object
- @rtype: Shortcut
- """
- sc=Shortcut()
- sc.load(filename)
- return sc
-
-
-class Shortcut:
- """A shortcut on Win32.
- >>> sc=Shortcut(path, arguments, description, workingdir, iconpath, iconidx)
- @param path: Location of the target
- @param arguments: If path points to an executable, optional arguments to
- pass
- @param description: Human-readable decription of target
- @param workingdir: Directory from which target is launched
- @param iconpath: Filename that contains an icon for the shortcut
- @param iconidx: If iconpath is set, optional index of the icon desired
- """
-
- def __init__(self,
- path=None,
- arguments=None,
- description=None,
- workingdir=None,
- iconpath=None,
- iconidx=0):
- self._base = pythoncom.CoCreateInstance(
- shell.CLSID_ShellLink, None,
- pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink
- )
- data = map(None,
- ['"%s"' % os.path.abspath(path), arguments, description,
- os.path.abspath(workingdir), os.path.abspath(iconpath)],
- ("SetPath", "SetArguments", "SetDescription",
- "SetWorkingDirectory") )
- for value, function in data:
- if value and function:
- # call function on each non-null value
- getattr(self, function)(value)
- if iconpath:
- self.SetIconLocation(iconpath, iconidx)
-
- def load( self, filename ):
- """Read a shortcut file from disk."""
- self._base.QueryInterface(pythoncom.IID_IPersistFile).Load(filename)
-
- def save( self, filename ):
- """Write the shortcut to disk.
-
- The file should be named something.lnk.
- """
- self._base.QueryInterface(pythoncom.IID_IPersistFile).Save(filename, 0)
-
- def __getattr__( self, name ):
- if name != "_base":
- return getattr(self._base, name)
- raise AttributeError, "%s instance has no attribute %s" % \
- (self.__class__.__name__, name)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/syslog.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/syslog.py
deleted file mode 100755
index 88d8d025..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/syslog.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_syslog -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Classes and utility functions for integrating Twisted and syslog.
-
-You probably want to call L{startLogging}.
-"""
-
-syslog = __import__('syslog')
-
-from twisted.python import log
-
-# These defaults come from the Python 2.3 syslog docs.
-DEFAULT_OPTIONS = 0
-DEFAULT_FACILITY = syslog.LOG_USER
-
-
-
-class SyslogObserver:
- """
- A log observer for logging to syslog.
-
- See L{twisted.python.log} for context.
-
- This logObserver will automatically use LOG_ALERT priority for logged
- failures (such as from C{log.err()}), but you can use any priority and
- facility by setting the 'C{syslogPriority}' and 'C{syslogFacility}' keys in
- the event dict.
- """
- openlog = syslog.openlog
- syslog = syslog.syslog
-
- def __init__(self, prefix, options=DEFAULT_OPTIONS,
- facility=DEFAULT_FACILITY):
- """
- @type prefix: C{str}
- @param prefix: The syslog prefix to use.
-
- @type options: C{int}
- @param options: A bitvector represented as an integer of the syslog
- options to use.
-
- @type facility: C{int}
- @param facility: An indication to the syslog daemon of what sort of
- program this is (essentially, an additional arbitrary metadata
- classification for messages sent to syslog by this observer).
- """
- self.openlog(prefix, options, facility)
-
-
- def emit(self, eventDict):
- """
- Send a message event to the I{syslog}.
-
- @param eventDict: The event to send. If it has no C{'message'} key, it
- will be ignored. Otherwise, if it has C{'syslogPriority'} and/or
- C{'syslogFacility'} keys, these will be used as the syslog priority
- and facility. If it has no C{'syslogPriority'} key but a true
- value for the C{'isError'} key, the B{LOG_ALERT} priority will be
- used; if it has a false value for C{'isError'}, B{LOG_INFO} will be
- used. If the C{'message'} key is multiline, each line will be sent
- to the syslog separately.
- """
- # Figure out what the message-text is.
- text = log.textFromEventDict(eventDict)
- if text is None:
- return
-
- # Figure out what syslog parameters we might need to use.
- priority = syslog.LOG_INFO
- facility = 0
- if eventDict['isError']:
- priority = syslog.LOG_ALERT
- if 'syslogPriority' in eventDict:
- priority = int(eventDict['syslogPriority'])
- if 'syslogFacility' in eventDict:
- facility = int(eventDict['syslogFacility'])
-
- # Break the message up into lines and send them.
- lines = text.split('\n')
- while lines[-1:] == ['']:
- lines.pop()
-
- firstLine = True
- for line in lines:
- if firstLine:
- firstLine = False
- else:
- line = '\t' + line
- self.syslog(priority | facility,
- '[%s] %s' % (eventDict['system'], line))
-
-
-
-def startLogging(prefix='Twisted', options=DEFAULT_OPTIONS,
- facility=DEFAULT_FACILITY, setStdout=1):
- """
- Send all Twisted logging output to syslog from now on.
-
- The prefix, options and facility arguments are passed to
- C{syslog.openlog()}, see the Python syslog documentation for details. For
- other parameters, see L{twisted.python.log.startLoggingWithObserver}.
- """
- obs = SyslogObserver(prefix, options, facility)
- log.startLoggingWithObserver(obs.emit, setStdout=setStdout)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/systemd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/systemd.py
deleted file mode 100755
index d20fa04d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/systemd.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_systemd -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Integration with systemd.
-
-Currently only the minimum APIs necessary for using systemd's socket activation
-feature are supported.
-"""
-
-__all__ = ['ListenFDs']
-
-from os import getpid
-
-
-class ListenFDs(object):
- """
- L{ListenFDs} provides access to file descriptors inherited from systemd.
-
- Typically L{ListenFDs.fromEnvironment} should be used to construct a new
- instance of L{ListenFDs}.
-
- @cvar _START: File descriptors inherited from systemd are always
- consecutively numbered, with a fixed lowest "starting" descriptor. This
- gives the default starting descriptor. Since this must agree with the
- value systemd is using, it typically should not be overridden.
- @type _START: C{int}
-
- @ivar _descriptors: A C{list} of C{int} giving the descriptors which were
- inherited.
- """
- _START = 3
-
- def __init__(self, descriptors):
- """
- @param descriptors: The descriptors which will be returned from calls to
- C{inheritedDescriptors}.
- """
- self._descriptors = descriptors
-
-
- @classmethod
- def fromEnvironment(cls, environ=None, start=None):
- """
- @param environ: A dictionary-like object to inspect to discover
- inherited descriptors. By default, C{None}, indicating that the
- real process environment should be inspected. The default is
- suitable for typical usage.
-
- @param start: An integer giving the lowest value of an inherited
- descriptor systemd will give us. By default, C{None}, indicating
- the known correct (that is, in agreement with systemd) value will be
- used. The default is suitable for typical usage.
-
- @return: A new instance of C{cls} which can be used to look up the
- descriptors which have been inherited.
- """
- if environ is None:
- from os import environ
- if start is None:
- start = cls._START
-
- descriptors = []
-
- try:
- pid = int(environ['LISTEN_PID'])
- except (KeyError, ValueError):
- pass
- else:
- if pid == getpid():
- try:
- count = int(environ['LISTEN_FDS'])
- except (KeyError, ValueError):
- pass
- else:
- descriptors = range(start, start + count)
- del environ['LISTEN_PID'], environ['LISTEN_FDS']
-
- return cls(descriptors)
-
-
- def inheritedDescriptors(self):
- """
- @return: The configured list of descriptors.
- """
- return list(self._descriptors)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/__init__.py
deleted file mode 100755
index cfdc40d1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Unit tests for L{twisted.python}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/deprecatedattributes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/deprecatedattributes.py
deleted file mode 100755
index b94c3617..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/deprecatedattributes.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Import reflect first, so that circular imports (between deprecate and
-# reflect) don't cause headaches.
-import twisted.python.reflect
-from twisted.python.versions import Version
-from twisted.python.deprecate import deprecatedModuleAttribute
-
-
-# Known module-level attributes.
-DEPRECATED_ATTRIBUTE = 42
-ANOTHER_ATTRIBUTE = 'hello'
-
-
-version = Version('Twisted', 8, 0, 0)
-message = 'Oh noes!'
-
-
-deprecatedModuleAttribute(
- version,
- message,
- __name__,
- 'DEPRECATED_ATTRIBUTE')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/modules_helpers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/modules_helpers.py
deleted file mode 100755
index 15ef6c1d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/modules_helpers.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Facilities for helping test code which interacts with L{twisted.python.modules},
-or uses Python's own module system to load code.
-"""
-
-import sys
-
-from twisted.trial.unittest import TestCase
-from twisted.python import modules
-from twisted.python.filepath import FilePath
-
-class TwistedModulesTestCase(TestCase):
-
- def findByIteration(self, modname, where=modules, importPackages=False):
- """
- You don't ever actually want to do this, so it's not in the public API, but
- sometimes we want to compare the result of an iterative call with a
- lookup call and make sure they're the same for test purposes.
- """
- for modinfo in where.walkModules(importPackages=importPackages):
- if modinfo.name == modname:
- return modinfo
- self.fail("Unable to find module %r through iteration." % (modname,))
-
-
- def replaceSysPath(self, sysPath):
- """
- Replace sys.path, for the duration of the test, with the given value.
- """
- originalSysPath = sys.path[:]
- def cleanUpSysPath():
- sys.path[:] = originalSysPath
- self.addCleanup(cleanUpSysPath)
- sys.path[:] = sysPath
-
-
- def replaceSysModules(self, sysModules):
- """
- Replace sys.modules, for the duration of the test, with the given value.
- """
- originalSysModules = sys.modules.copy()
- def cleanUpSysModules():
- sys.modules.clear()
- sys.modules.update(originalSysModules)
- self.addCleanup(cleanUpSysModules)
- sys.modules.clear()
- sys.modules.update(sysModules)
-
-
- def pathEntryWithOnePackage(self, pkgname="test_package"):
- """
- Generate a L{FilePath} with one package, named C{pkgname}, on it, and
- return the L{FilePath} of the path entry.
- """
- entry = FilePath(self.mktemp())
- pkg = entry.child("test_package")
- pkg.makedirs()
- pkg.child("__init__.py").setContent("")
- return entry
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/pullpipe.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/pullpipe.py
deleted file mode 100755
index e6066627..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/pullpipe.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python
-# -*- test-case-name: twisted.python.test.test_sendmsg -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os
-from struct import unpack
-
-# This makes me sad. Why aren't things nice?
-sys.path.insert(0, __file__.rsplit('/', 4)[0])
-
-from twisted.python.sendmsg import recv1msg
-
-def recvfd(socketfd):
- """
- Receive a file descriptor from a L{send1msg} message on the given C{AF_UNIX}
- socket.
-
- @param socketfd: An C{AF_UNIX} socket, attached to another process waiting
- to send sockets via the ancillary data mechanism in L{send1msg}.
-
- @param fd: C{int}
-
- @return: a 2-tuple of (new file descriptor, description).
-
- @rtype: 2-tuple of (C{int}, C{str})
- """
- data, flags, ancillary = recv1msg(socketfd)
- [(cmsg_level, cmsg_type, packedFD)] = ancillary
- # cmsg_level and cmsg_type really need to be SOL_SOCKET / SCM_RIGHTS, but
- # since those are the *only* standard values, there's not much point in
- # checking.
- [unpackedFD] = unpack("i", packedFD)
- return (unpackedFD, data)
-
-
-if __name__ == '__main__':
- fd, description = recvfd(int(sys.argv[1]))
- os.write(fd, "Test fixture data: %s.\n" % (description,))
- os.close(fd)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_components.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_components.py
deleted file mode 100755
index c4c1b451..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_components.py
+++ /dev/null
@@ -1,770 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test cases for Twisted component architecture.
-"""
-
-from zope.interface import Interface, implements, Attribute
-from zope.interface.adapter import AdapterRegistry
-
-from twisted.trial import unittest
-from twisted.python import components
-from twisted.python.components import _addHook, _removeHook, proxyForInterface
-
-
-class InterfacesTestCase(unittest.TestCase):
- """Test interfaces."""
-
-class Compo(components.Componentized):
- num = 0
- def inc(self):
- self.num = self.num + 1
- return self.num
-
-class IAdept(Interface):
- def adaptorFunc():
- raise NotImplementedError()
-
-class IElapsed(Interface):
- def elapsedFunc():
- """
- 1!
- """
-
-class Adept(components.Adapter):
- implements(IAdept)
- def __init__(self, orig):
- self.original = orig
- self.num = 0
- def adaptorFunc(self):
- self.num = self.num + 1
- return self.num, self.original.inc()
-
-class Elapsed(components.Adapter):
- implements(IElapsed)
- def elapsedFunc(self):
- return 1
-
-class AComp(components.Componentized):
- pass
-class BComp(AComp):
- pass
-class CComp(BComp):
- pass
-
-class ITest(Interface):
- pass
-class ITest2(Interface):
- pass
-class ITest3(Interface):
- pass
-class ITest4(Interface):
- pass
-class Test(components.Adapter):
- implements(ITest, ITest3, ITest4)
- def __init__(self, orig):
- pass
-class Test2:
- implements(ITest2)
- temporaryAdapter = 1
- def __init__(self, orig):
- pass
-
-
-
-class RegistryUsingMixin(object):
- """
- Mixin for test cases which modify the global registry somehow.
- """
- def setUp(self):
- """
- Configure L{twisted.python.components.registerAdapter} to mutate an
- alternate registry to improve test isolation.
- """
- # Create a brand new, empty registry and put it onto the components
- # module where registerAdapter will use it. Also ensure that it goes
- # away at the end of the test.
- scratchRegistry = AdapterRegistry()
- self.patch(components, 'globalRegistry', scratchRegistry)
- # Hook the new registry up to the adapter lookup system and ensure that
- # association is also discarded after the test.
- hook = _addHook(scratchRegistry)
- self.addCleanup(_removeHook, hook)
-
-
-
-class ComponentizedTestCase(unittest.TestCase, RegistryUsingMixin):
- """
- Simple test case for caching in Componentized.
- """
- def setUp(self):
- RegistryUsingMixin.setUp(self)
-
- components.registerAdapter(Test, AComp, ITest)
- components.registerAdapter(Test, AComp, ITest3)
- components.registerAdapter(Test2, AComp, ITest2)
-
-
- def testComponentized(self):
- components.registerAdapter(Adept, Compo, IAdept)
- components.registerAdapter(Elapsed, Compo, IElapsed)
-
- c = Compo()
- assert c.getComponent(IAdept).adaptorFunc() == (1, 1)
- assert c.getComponent(IAdept).adaptorFunc() == (2, 2)
- assert IElapsed(IAdept(c)).elapsedFunc() == 1
-
- def testInheritanceAdaptation(self):
- c = CComp()
- co1 = c.getComponent(ITest)
- co2 = c.getComponent(ITest)
- co3 = c.getComponent(ITest2)
- co4 = c.getComponent(ITest2)
- assert co1 is co2
- assert co3 is not co4
- c.removeComponent(co1)
- co5 = c.getComponent(ITest)
- co6 = c.getComponent(ITest)
- assert co5 is co6
- assert co1 is not co5
-
- def testMultiAdapter(self):
- c = CComp()
- co1 = c.getComponent(ITest)
- co2 = c.getComponent(ITest2)
- co3 = c.getComponent(ITest3)
- co4 = c.getComponent(ITest4)
- self.assertIdentical(None, co4)
- self.assertIdentical(co1, co3)
-
-
- def test_getComponentDefaults(self):
- """
- Test that a default value specified to Componentized.getComponent if
- there is no component for the requested interface.
- """
- componentized = components.Componentized()
- default = object()
- self.assertIdentical(
- componentized.getComponent(ITest, default),
- default)
- self.assertIdentical(
- componentized.getComponent(ITest, default=default),
- default)
- self.assertIdentical(
- componentized.getComponent(ITest),
- None)
-
-
-
-class AdapterTestCase(unittest.TestCase):
- """Test adapters."""
-
- def testAdapterGetComponent(self):
- o = object()
- a = Adept(o)
- self.assertRaises(components.CannotAdapt, ITest, a)
- self.assertEqual(ITest(a, None), None)
-
-
-
-class IMeta(Interface):
- pass
-
-class MetaAdder(components.Adapter):
- implements(IMeta)
- def add(self, num):
- return self.original.num + num
-
-class BackwardsAdder(components.Adapter):
- implements(IMeta)
- def add(self, num):
- return self.original.num - num
-
-class MetaNumber:
- def __init__(self, num):
- self.num = num
-
-class FakeAdder:
- def add(self, num):
- return num + 5
-
-class FakeNumber:
- num = 3
-
-class ComponentNumber(components.Componentized):
- def __init__(self):
- self.num = 0
- components.Componentized.__init__(self)
-
-class ComponentMeta(components.Adapter):
- implements(IMeta)
- def __init__(self, original):
- components.Adapter.__init__(self, original)
- self.num = self.original.num
-
-class ComponentAdder(ComponentMeta):
- def add(self, num):
- self.num += num
- return self.num
-
-class ComponentDoubler(ComponentMeta):
- def add(self, num):
- self.num += (num * 2)
- return self.original.num
-
-class IAttrX(Interface):
- def x():
- pass
-
-class IAttrXX(Interface):
- def xx():
- pass
-
-class Xcellent:
- implements(IAttrX)
- def x(self):
- return 'x!'
-
-class DoubleXAdapter:
- num = 42
- def __init__(self, original):
- self.original = original
- def xx(self):
- return (self.original.x(), self.original.x())
- def __cmp__(self, other):
- return cmp(self.num, other.num)
-
-
-class TestMetaInterface(RegistryUsingMixin, unittest.TestCase):
- def testBasic(self):
- components.registerAdapter(MetaAdder, MetaNumber, IMeta)
- n = MetaNumber(1)
- self.assertEqual(IMeta(n).add(1), 2)
-
- def testComponentizedInteraction(self):
- components.registerAdapter(ComponentAdder, ComponentNumber, IMeta)
- c = ComponentNumber()
- IMeta(c).add(1)
- IMeta(c).add(1)
- self.assertEqual(IMeta(c).add(1), 3)
-
- def testAdapterWithCmp(self):
- # Make sure that a __cmp__ on an adapter doesn't break anything
- components.registerAdapter(DoubleXAdapter, IAttrX, IAttrXX)
- xx = IAttrXX(Xcellent())
- self.assertEqual(('x!', 'x!'), xx.xx())
-
-
-class RegistrationTestCase(RegistryUsingMixin, unittest.TestCase):
- """
- Tests for adapter registration.
- """
- def _registerAdapterForClassOrInterface(self, original):
- """
- Register an adapter with L{components.registerAdapter} for the given
- class or interface and verify that the adapter can be looked up with
- L{components.getAdapterFactory}.
- """
- adapter = lambda o: None
- components.registerAdapter(adapter, original, ITest)
- self.assertIdentical(
- components.getAdapterFactory(original, ITest, None),
- adapter)
-
-
- def test_registerAdapterForClass(self):
- """
- Test that an adapter from a class can be registered and then looked
- up.
- """
- class TheOriginal(object):
- pass
- return self._registerAdapterForClassOrInterface(TheOriginal)
-
-
- def test_registerAdapterForInterface(self):
- """
- Test that an adapter from an interface can be registered and then
- looked up.
- """
- return self._registerAdapterForClassOrInterface(ITest2)
-
-
- def _duplicateAdapterForClassOrInterface(self, original):
- """
- Verify that L{components.registerAdapter} raises L{ValueError} if the
- from-type/interface and to-interface pair is not unique.
- """
- firstAdapter = lambda o: False
- secondAdapter = lambda o: True
- components.registerAdapter(firstAdapter, original, ITest)
- self.assertRaises(
- ValueError,
- components.registerAdapter,
- secondAdapter, original, ITest)
- # Make sure that the original adapter is still around as well
- self.assertIdentical(
- components.getAdapterFactory(original, ITest, None),
- firstAdapter)
-
-
- def test_duplicateAdapterForClass(self):
- """
- Test that attempting to register a second adapter from a class
- raises the appropriate exception.
- """
- class TheOriginal(object):
- pass
- return self._duplicateAdapterForClassOrInterface(TheOriginal)
-
-
- def test_duplicateAdapterForInterface(self):
- """
- Test that attempting to register a second adapter from an interface
- raises the appropriate exception.
- """
- return self._duplicateAdapterForClassOrInterface(ITest2)
-
-
- def _duplicateAdapterForClassOrInterfaceAllowed(self, original):
- """
- Verify that when C{components.ALLOW_DUPLICATES} is set to C{True}, new
- adapter registrations for a particular from-type/interface and
- to-interface pair replace older registrations.
- """
- firstAdapter = lambda o: False
- secondAdapter = lambda o: True
- class TheInterface(Interface):
- pass
- components.registerAdapter(firstAdapter, original, TheInterface)
- components.ALLOW_DUPLICATES = True
- try:
- components.registerAdapter(secondAdapter, original, TheInterface)
- self.assertIdentical(
- components.getAdapterFactory(original, TheInterface, None),
- secondAdapter)
- finally:
- components.ALLOW_DUPLICATES = False
-
- # It should be rejected again at this point
- self.assertRaises(
- ValueError,
- components.registerAdapter,
- firstAdapter, original, TheInterface)
-
- self.assertIdentical(
- components.getAdapterFactory(original, TheInterface, None),
- secondAdapter)
-
-
- def test_duplicateAdapterForClassAllowed(self):
- """
- Test that when L{components.ALLOW_DUPLICATES} is set to a true
- value, duplicate registrations from classes are allowed to override
- the original registration.
- """
- class TheOriginal(object):
- pass
- return self._duplicateAdapterForClassOrInterfaceAllowed(TheOriginal)
-
-
- def test_duplicateAdapterForInterfaceAllowed(self):
- """
- Test that when L{components.ALLOW_DUPLICATES} is set to a true
- value, duplicate registrations from interfaces are allowed to
- override the original registration.
- """
- class TheOriginal(Interface):
- pass
- return self._duplicateAdapterForClassOrInterfaceAllowed(TheOriginal)
-
-
- def _multipleInterfacesForClassOrInterface(self, original):
- """
- Verify that an adapter can be registered for multiple to-interfaces at a
- time.
- """
- adapter = lambda o: None
- components.registerAdapter(adapter, original, ITest, ITest2)
- self.assertIdentical(
- components.getAdapterFactory(original, ITest, None), adapter)
- self.assertIdentical(
- components.getAdapterFactory(original, ITest2, None), adapter)
-
-
- def test_multipleInterfacesForClass(self):
- """
- Test the registration of an adapter from a class to several
- interfaces at once.
- """
- class TheOriginal(object):
- pass
- return self._multipleInterfacesForClassOrInterface(TheOriginal)
-
-
- def test_multipleInterfacesForInterface(self):
- """
- Test the registration of an adapter from an interface to several
- interfaces at once.
- """
- return self._multipleInterfacesForClassOrInterface(ITest3)
-
-
- def _subclassAdapterRegistrationForClassOrInterface(self, original):
- """
- Verify that a new adapter can be registered for a particular
- to-interface from a subclass of a type or interface which already has an
- adapter registered to that interface and that the subclass adapter takes
- precedence over the base class adapter.
- """
- firstAdapter = lambda o: True
- secondAdapter = lambda o: False
- class TheSubclass(original):
- pass
- components.registerAdapter(firstAdapter, original, ITest)
- components.registerAdapter(secondAdapter, TheSubclass, ITest)
- self.assertIdentical(
- components.getAdapterFactory(original, ITest, None),
- firstAdapter)
- self.assertIdentical(
- components.getAdapterFactory(TheSubclass, ITest, None),
- secondAdapter)
-
-
- def test_subclassAdapterRegistrationForClass(self):
- """
- Test that an adapter to a particular interface can be registered
- from both a class and its subclass.
- """
- class TheOriginal(object):
- pass
- return self._subclassAdapterRegistrationForClassOrInterface(TheOriginal)
-
-
- def test_subclassAdapterRegistrationForInterface(self):
- """
- Test that an adapter to a particular interface can be registered
- from both an interface and its subclass.
- """
- return self._subclassAdapterRegistrationForClassOrInterface(ITest2)
-
-
-
-class IProxiedInterface(Interface):
- """
- An interface class for use by L{proxyForInterface}.
- """
-
- ifaceAttribute = Attribute("""
- An example declared attribute, which should be proxied.""")
-
- def yay(*a, **kw):
- """
- A sample method which should be proxied.
- """
-
-class IProxiedSubInterface(IProxiedInterface):
- """
- An interface that derives from another for use with L{proxyForInterface}.
- """
-
- def boo(self):
- """
- A different sample method which should be proxied.
- """
-
-
-
-class Yayable(object):
- """
- A provider of L{IProxiedInterface} which increments a counter for
- every call to C{yay}.
-
- @ivar yays: The number of times C{yay} has been called.
- """
- implements(IProxiedInterface)
-
- def __init__(self):
- self.yays = 0
- self.yayArgs = []
-
- def yay(self, *a, **kw):
- """
- Increment C{self.yays}.
- """
- self.yays += 1
- self.yayArgs.append((a, kw))
- return self.yays
-
-
-class Booable(object):
- """
- An implementation of IProxiedSubInterface
- """
- implements(IProxiedSubInterface)
- yayed = False
- booed = False
- def yay(self):
- """
- Mark the fact that 'yay' has been called.
- """
- self.yayed = True
-
-
- def boo(self):
- """
- Mark the fact that 'boo' has been called.1
- """
- self.booed = True
-
-
-
-class IMultipleMethods(Interface):
- """
- An interface with multiple methods.
- """
-
- def methodOne():
- """
- The first method. Should return 1.
- """
-
- def methodTwo():
- """
- The second method. Should return 2.
- """
-
-
-
-class MultipleMethodImplementor(object):
- """
- A precise implementation of L{IMultipleMethods}.
- """
-
- def methodOne(self):
- """
- @return: 1
- """
- return 1
-
-
- def methodTwo(self):
- """
- @return: 2
- """
- return 2
-
-
-
-class ProxyForInterfaceTests(unittest.TestCase):
- """
- Tests for L{proxyForInterface}.
- """
-
- def test_original(self):
- """
- Proxy objects should have an C{original} attribute which refers to the
- original object passed to the constructor.
- """
- original = object()
- proxy = proxyForInterface(IProxiedInterface)(original)
- self.assertIdentical(proxy.original, original)
-
-
- def test_proxyMethod(self):
- """
- The class created from L{proxyForInterface} passes methods on an
- interface to the object which is passed to its constructor.
- """
- klass = proxyForInterface(IProxiedInterface)
- yayable = Yayable()
- proxy = klass(yayable)
- proxy.yay()
- self.assertEqual(proxy.yay(), 2)
- self.assertEqual(yayable.yays, 2)
-
-
- def test_proxyAttribute(self):
- """
- Proxy objects should proxy declared attributes, but not other
- attributes.
- """
- yayable = Yayable()
- yayable.ifaceAttribute = object()
- proxy = proxyForInterface(IProxiedInterface)(yayable)
- self.assertIdentical(proxy.ifaceAttribute, yayable.ifaceAttribute)
- self.assertRaises(AttributeError, lambda: proxy.yays)
-
-
- def test_proxySetAttribute(self):
- """
- The attributes that proxy objects proxy should be assignable and affect
- the original object.
- """
- yayable = Yayable()
- proxy = proxyForInterface(IProxiedInterface)(yayable)
- thingy = object()
- proxy.ifaceAttribute = thingy
- self.assertIdentical(yayable.ifaceAttribute, thingy)
-
-
- def test_proxyDeleteAttribute(self):
- """
- The attributes that proxy objects proxy should be deletable and affect
- the original object.
- """
- yayable = Yayable()
- yayable.ifaceAttribute = None
- proxy = proxyForInterface(IProxiedInterface)(yayable)
- del proxy.ifaceAttribute
- self.assertFalse(hasattr(yayable, 'ifaceAttribute'))
-
-
- def test_multipleMethods(self):
- """
- [Regression test] The proxy should send its method calls to the correct
- method, not the incorrect one.
- """
- multi = MultipleMethodImplementor()
- proxy = proxyForInterface(IMultipleMethods)(multi)
- self.assertEqual(proxy.methodOne(), 1)
- self.assertEqual(proxy.methodTwo(), 2)
-
-
- def test_subclassing(self):
- """
- It is possible to subclass the result of L{proxyForInterface}.
- """
-
- class SpecializedProxy(proxyForInterface(IProxiedInterface)):
- """
- A specialized proxy which can decrement the number of yays.
- """
- def boo(self):
- """
- Decrement the number of yays.
- """
- self.original.yays -= 1
-
- yayable = Yayable()
- special = SpecializedProxy(yayable)
- self.assertEqual(yayable.yays, 0)
- special.boo()
- self.assertEqual(yayable.yays, -1)
-
-
- def test_proxyName(self):
- """
- The name of a proxy class indicates which interface it proxies.
- """
- proxy = proxyForInterface(IProxiedInterface)
- self.assertEqual(
- proxy.__name__,
- "(Proxy for "
- "twisted.python.test.test_components.IProxiedInterface)")
-
-
- def test_implements(self):
- """
- The resulting proxy implements the interface that it proxies.
- """
- proxy = proxyForInterface(IProxiedInterface)
- self.assertTrue(IProxiedInterface.implementedBy(proxy))
-
-
- def test_proxyDescriptorGet(self):
- """
- _ProxyDescriptor's __get__ method should return the appropriate
- attribute of its argument's 'original' attribute if it is invoked with
- an object. If it is invoked with None, it should return a false
- class-method emulator instead.
-
- For some reason, Python's documentation recommends to define
- descriptors' __get__ methods with the 'type' parameter as optional,
- despite the fact that Python itself never actually calls the descriptor
- that way. This is probably do to support 'foo.__get__(bar)' as an
- idiom. Let's make sure that the behavior is correct. Since we don't
- actually use the 'type' argument at all, this test calls it the
- idiomatic way to ensure that signature works; test_proxyInheritance
- verifies the how-Python-actually-calls-it signature.
- """
- class Sample:
- called = False
- def hello(self):
- self.called = True
- fakeProxy = Sample()
- testObject = Sample()
- fakeProxy.original = testObject
- pd = components._ProxyDescriptor("hello", "original")
- self.assertEqual(pd.__get__(fakeProxy), testObject.hello)
- fakeClassMethod = pd.__get__(None)
- fakeClassMethod(fakeProxy)
- self.failUnless(testObject.called)
-
-
- def test_proxyInheritance(self):
- """
- Subclasses of the class returned from L{proxyForInterface} should be
- able to upcall methods by reference to their superclass, as any normal
- Python class can.
- """
- class YayableWrapper(proxyForInterface(IProxiedInterface)):
- """
- This class does not override any functionality.
- """
-
- class EnhancedWrapper(YayableWrapper):
- """
- This class overrides the 'yay' method.
- """
- wrappedYays = 1
- def yay(self, *a, **k):
- self.wrappedYays += 1
- return YayableWrapper.yay(self, *a, **k) + 7
-
- yayable = Yayable()
- wrapper = EnhancedWrapper(yayable)
- self.assertEqual(wrapper.yay(3, 4, x=5, y=6), 8)
- self.assertEqual(yayable.yayArgs,
- [((3, 4), dict(x=5, y=6))])
-
-
- def test_interfaceInheritance(self):
- """
- Proxies of subinterfaces generated with proxyForInterface should allow
- access to attributes of both the child and the base interfaces.
- """
- proxyClass = proxyForInterface(IProxiedSubInterface)
- booable = Booable()
- proxy = proxyClass(booable)
- proxy.yay()
- proxy.boo()
- self.failUnless(booable.yayed)
- self.failUnless(booable.booed)
-
-
- def test_attributeCustomization(self):
- """
- The original attribute name can be customized via the
- C{originalAttribute} argument of L{proxyForInterface}: the attribute
- should change, but the methods of the original object should still be
- callable, and the attributes still accessible.
- """
- yayable = Yayable()
- yayable.ifaceAttribute = object()
- proxy = proxyForInterface(
- IProxiedInterface, originalAttribute='foo')(yayable)
- self.assertIdentical(proxy.foo, yayable)
-
- # Check the behavior
- self.assertEqual(proxy.yay(), 1)
- self.assertIdentical(proxy.ifaceAttribute, yayable.ifaceAttribute)
- thingy = object()
- proxy.ifaceAttribute = thingy
- self.assertIdentical(yayable.ifaceAttribute, thingy)
- del proxy.ifaceAttribute
- self.assertFalse(hasattr(yayable, 'ifaceAttribute'))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_constants.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_constants.py
deleted file mode 100755
index 870d342b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_constants.py
+++ /dev/null
@@ -1,778 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Unit tests for L{twisted.python.constants}.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python.constants import (
- NamedConstant, Names, ValueConstant, Values, FlagConstant, Flags)
-
-
-class NamedConstantTests(TestCase):
- """
- Tests for the L{twisted.python.constants.NamedConstant} class which is used
- to represent individual values.
- """
- def setUp(self):
- """
- Create a dummy container into which constants can be placed.
- """
- class foo(Names):
- pass
- self.container = foo
-
-
- def test_name(self):
- """
- The C{name} attribute of a L{NamedConstant} refers to the value passed
- for the C{name} parameter to C{_realize}.
- """
- name = NamedConstant()
- name._realize(self.container, "bar", None)
- self.assertEqual("bar", name.name)
-
-
- def test_representation(self):
- """
- The string representation of an instance of L{NamedConstant} includes
- the container the instances belongs to as well as the instance's name.
- """
- name = NamedConstant()
- name._realize(self.container, "bar", None)
- self.assertEqual("<foo=bar>", repr(name))
-
-
- def test_equality(self):
- """
- A L{NamedConstant} instance compares equal to itself.
- """
- name = NamedConstant()
- name._realize(self.container, "bar", None)
- self.assertTrue(name == name)
- self.assertFalse(name != name)
-
-
- def test_nonequality(self):
- """
- Two different L{NamedConstant} instances do not compare equal to each
- other.
- """
- first = NamedConstant()
- first._realize(self.container, "bar", None)
- second = NamedConstant()
- second._realize(self.container, "bar", None)
- self.assertFalse(first == second)
- self.assertTrue(first != second)
-
-
- def test_hash(self):
- """
- Because two different L{NamedConstant} instances do not compare as equal
- to each other, they also have different hashes to avoid collisions when
- added to a C{dict} or C{set}.
- """
- first = NamedConstant()
- first._realize(self.container, "bar", None)
- second = NamedConstant()
- second._realize(self.container, "bar", None)
- self.assertNotEqual(hash(first), hash(second))
-
-
-
-class _ConstantsTestsMixin(object):
- """
- Mixin defining test helpers common to multiple types of constants
- collections.
- """
- def _notInstantiableTest(self, name, cls):
- """
- Assert that an attempt to instantiate the constants class raises
- C{TypeError}.
-
- @param name: A C{str} giving the name of the constants collection.
- @param cls: The constants class to test.
- """
- exc = self.assertRaises(TypeError, cls)
- self.assertEqual(name + " may not be instantiated.", str(exc))
-
-
-
-class NamesTests(TestCase, _ConstantsTestsMixin):
- """
- Tests for L{twisted.python.constants.Names}, a base class for containers of
- related constaints.
- """
- def setUp(self):
- """
- Create a fresh new L{Names} subclass for each unit test to use. Since
- L{Names} is stateful, re-using the same subclass across test methods
- makes exercising all of the implementation code paths difficult.
- """
- class METHOD(Names):
- """
- A container for some named constants to use in unit tests for
- L{Names}.
- """
- GET = NamedConstant()
- PUT = NamedConstant()
- POST = NamedConstant()
- DELETE = NamedConstant()
-
- self.METHOD = METHOD
-
-
- def test_notInstantiable(self):
- """
- A subclass of L{Names} raises C{TypeError} if an attempt is made to
- instantiate it.
- """
- self._notInstantiableTest("METHOD", self.METHOD)
-
-
- def test_symbolicAttributes(self):
- """
- Each name associated with a L{NamedConstant} instance in the definition
- of a L{Names} subclass is available as an attribute on the resulting
- class.
- """
- self.assertTrue(hasattr(self.METHOD, "GET"))
- self.assertTrue(hasattr(self.METHOD, "PUT"))
- self.assertTrue(hasattr(self.METHOD, "POST"))
- self.assertTrue(hasattr(self.METHOD, "DELETE"))
-
-
- def test_withoutOtherAttributes(self):
- """
- As usual, names not defined in the class scope of a L{Names}
- subclass are not available as attributes on the resulting class.
- """
- self.assertFalse(hasattr(self.METHOD, "foo"))
-
-
- def test_representation(self):
- """
- The string representation of a constant on a L{Names} subclass includes
- the name of the L{Names} subclass and the name of the constant itself.
- """
- self.assertEqual("<METHOD=GET>", repr(self.METHOD.GET))
-
-
- def test_lookupByName(self):
- """
- Constants can be looked up by name using L{Names.lookupByName}.
- """
- method = self.METHOD.lookupByName("GET")
- self.assertIdentical(self.METHOD.GET, method)
-
-
- def test_notLookupMissingByName(self):
- """
- Names not defined with a L{NamedConstant} instance cannot be looked up
- using L{Names.lookupByName}.
- """
- self.assertRaises(ValueError, self.METHOD.lookupByName, "lookupByName")
- self.assertRaises(ValueError, self.METHOD.lookupByName, "__init__")
- self.assertRaises(ValueError, self.METHOD.lookupByName, "foo")
-
-
- def test_name(self):
- """
- The C{name} attribute of one of the named constants gives that
- constant's name.
- """
- self.assertEqual("GET", self.METHOD.GET.name)
-
-
- def test_attributeIdentity(self):
- """
- Repeated access of an attribute associated with a L{NamedConstant} value
- in a L{Names} subclass results in the same object.
- """
- self.assertIdentical(self.METHOD.GET, self.METHOD.GET)
-
-
- def test_iterconstants(self):
- """
- L{Names.iterconstants} returns an iterator over all of the constants
- defined in the class, in the order they were defined.
- """
- constants = list(self.METHOD.iterconstants())
- self.assertEqual(
- [self.METHOD.GET, self.METHOD.PUT,
- self.METHOD.POST, self.METHOD.DELETE],
- constants)
-
-
- def test_attributeIterconstantsIdentity(self):
- """
- The constants returned from L{Names.iterconstants} are identical to the
- constants accessible using attributes.
- """
- constants = list(self.METHOD.iterconstants())
- self.assertIdentical(self.METHOD.GET, constants[0])
- self.assertIdentical(self.METHOD.PUT, constants[1])
- self.assertIdentical(self.METHOD.POST, constants[2])
- self.assertIdentical(self.METHOD.DELETE, constants[3])
-
-
- def test_iterconstantsIdentity(self):
- """
- The constants returned from L{Names.iterconstants} are identical on each
- call to that method.
- """
- constants = list(self.METHOD.iterconstants())
- again = list(self.METHOD.iterconstants())
- self.assertIdentical(again[0], constants[0])
- self.assertIdentical(again[1], constants[1])
- self.assertIdentical(again[2], constants[2])
- self.assertIdentical(again[3], constants[3])
-
-
- def test_initializedOnce(self):
- """
- L{Names._enumerants} is initialized once and its value re-used on
- subsequent access.
- """
- first = self.METHOD._enumerants
- self.METHOD.GET # Side-effects!
- second = self.METHOD._enumerants
- self.assertIdentical(first, second)
-
-
-
-class ValuesTests(TestCase, _ConstantsTestsMixin):
- """
- Tests for L{twisted.python.constants.Names}, a base class for containers of
- related constaints with arbitrary values.
- """
- def setUp(self):
- """
- Create a fresh new L{Values} subclass for each unit test to use. Since
- L{Values} is stateful, re-using the same subclass across test methods
- makes exercising all of the implementation code paths difficult.
- """
- class STATUS(Values):
- OK = ValueConstant("200")
- NOT_FOUND = ValueConstant("404")
-
- self.STATUS = STATUS
-
-
- def test_notInstantiable(self):
- """
- A subclass of L{Values} raises C{TypeError} if an attempt is made to
- instantiate it.
- """
- self._notInstantiableTest("STATUS", self.STATUS)
-
-
- def test_symbolicAttributes(self):
- """
- Each name associated with a L{ValueConstant} instance in the definition
- of a L{Values} subclass is available as an attribute on the resulting
- class.
- """
- self.assertTrue(hasattr(self.STATUS, "OK"))
- self.assertTrue(hasattr(self.STATUS, "NOT_FOUND"))
-
-
- def test_withoutOtherAttributes(self):
- """
- As usual, names not defined in the class scope of a L{Values}
- subclass are not available as attributes on the resulting class.
- """
- self.assertFalse(hasattr(self.STATUS, "foo"))
-
-
- def test_representation(self):
- """
- The string representation of a constant on a L{Values} subclass includes
- the name of the L{Values} subclass and the name of the constant itself.
- """
- self.assertEqual("<STATUS=OK>", repr(self.STATUS.OK))
-
-
- def test_lookupByName(self):
- """
- Constants can be looked up by name using L{Values.lookupByName}.
- """
- method = self.STATUS.lookupByName("OK")
- self.assertIdentical(self.STATUS.OK, method)
-
-
- def test_notLookupMissingByName(self):
- """
- Names not defined with a L{ValueConstant} instance cannot be looked up
- using L{Values.lookupByName}.
- """
- self.assertRaises(ValueError, self.STATUS.lookupByName, "lookupByName")
- self.assertRaises(ValueError, self.STATUS.lookupByName, "__init__")
- self.assertRaises(ValueError, self.STATUS.lookupByName, "foo")
-
-
- def test_lookupByValue(self):
- """
- Constants can be looked up by their associated value, defined by the
- argument passed to L{ValueConstant}, using L{Values.lookupByValue}.
- """
- status = self.STATUS.lookupByValue("200")
- self.assertIdentical(self.STATUS.OK, status)
-
-
- def test_lookupDuplicateByValue(self):
- """
- If more than one constant is associated with a particular value,
- L{Values.lookupByValue} returns whichever of them is defined first.
- """
- class TRANSPORT_MESSAGE(Values):
- """
- Message types supported by an SSH transport.
- """
- KEX_DH_GEX_REQUEST_OLD = ValueConstant(30)
- KEXDH_INIT = ValueConstant(30)
-
- self.assertIdentical(
- TRANSPORT_MESSAGE.lookupByValue(30),
- TRANSPORT_MESSAGE.KEX_DH_GEX_REQUEST_OLD)
-
-
- def test_notLookupMissingByValue(self):
- """
- L{Values.lookupByValue} raises L{ValueError} when called with a value
- with which no constant is associated.
- """
- self.assertRaises(ValueError, self.STATUS.lookupByValue, "OK")
- self.assertRaises(ValueError, self.STATUS.lookupByValue, 200)
- self.assertRaises(ValueError, self.STATUS.lookupByValue, "200.1")
-
-
- def test_name(self):
- """
- The C{name} attribute of one of the constants gives that constant's
- name.
- """
- self.assertEqual("OK", self.STATUS.OK.name)
-
-
- def test_attributeIdentity(self):
- """
- Repeated access of an attribute associated with a L{ValueConstant} value
- in a L{Values} subclass results in the same object.
- """
- self.assertIdentical(self.STATUS.OK, self.STATUS.OK)
-
-
- def test_iterconstants(self):
- """
- L{Values.iterconstants} returns an iterator over all of the constants
- defined in the class, in the order they were defined.
- """
- constants = list(self.STATUS.iterconstants())
- self.assertEqual(
- [self.STATUS.OK, self.STATUS.NOT_FOUND],
- constants)
-
-
- def test_attributeIterconstantsIdentity(self):
- """
- The constants returned from L{Values.iterconstants} are identical to the
- constants accessible using attributes.
- """
- constants = list(self.STATUS.iterconstants())
- self.assertIdentical(self.STATUS.OK, constants[0])
- self.assertIdentical(self.STATUS.NOT_FOUND, constants[1])
-
-
- def test_iterconstantsIdentity(self):
- """
- The constants returned from L{Values.iterconstants} are identical on
- each call to that method.
- """
- constants = list(self.STATUS.iterconstants())
- again = list(self.STATUS.iterconstants())
- self.assertIdentical(again[0], constants[0])
- self.assertIdentical(again[1], constants[1])
-
-
- def test_initializedOnce(self):
- """
- L{Values._enumerants} is initialized once and its value re-used on
- subsequent access.
- """
- first = self.STATUS._enumerants
- self.STATUS.OK # Side-effects!
- second = self.STATUS._enumerants
- self.assertIdentical(first, second)
-
-
-class _FlagsTestsMixin(object):
- """
- Mixin defining setup code for any tests for L{Flags} subclasses.
-
- @ivar FXF: A L{Flags} subclass created for each test method.
- """
- def setUp(self):
- """
- Create a fresh new L{Flags} subclass for each unit test to use. Since
- L{Flags} is stateful, re-using the same subclass across test methods
- makes exercising all of the implementation code paths difficult.
- """
- class FXF(Flags):
- # Implicitly assign three flag values based on definition order
- READ = FlagConstant()
- WRITE = FlagConstant()
- APPEND = FlagConstant()
-
- # Explicitly assign one flag value by passing it in
- EXCLUSIVE = FlagConstant(0x20)
-
- # Implicitly assign another flag value, following the previously
- # specified explicit value.
- TEXT = FlagConstant()
-
- self.FXF = FXF
-
-
-
-class FlagsTests(_FlagsTestsMixin, TestCase, _ConstantsTestsMixin):
- """
- Tests for L{twisted.python.constants.Flags}, a base class for containers of
- related, combinable flag or bitvector-like constants.
- """
- def test_notInstantiable(self):
- """
- A subclass of L{Flags} raises L{TypeError} if an attempt is made to
- instantiate it.
- """
- self._notInstantiableTest("FXF", self.FXF)
-
-
- def test_symbolicAttributes(self):
- """
- Each name associated with a L{FlagConstant} instance in the definition
- of a L{Flags} subclass is available as an attribute on the resulting
- class.
- """
- self.assertTrue(hasattr(self.FXF, "READ"))
- self.assertTrue(hasattr(self.FXF, "WRITE"))
- self.assertTrue(hasattr(self.FXF, "APPEND"))
- self.assertTrue(hasattr(self.FXF, "EXCLUSIVE"))
- self.assertTrue(hasattr(self.FXF, "TEXT"))
-
-
- def test_withoutOtherAttributes(self):
- """
- As usual, names not defined in the class scope of a L{Flags} subclass
- are not available as attributes on the resulting class.
- """
- self.assertFalse(hasattr(self.FXF, "foo"))
-
-
- def test_representation(self):
- """
- The string representation of a constant on a L{Flags} subclass includes
- the name of the L{Flags} subclass and the name of the constant itself.
- """
- self.assertEqual("<FXF=READ>", repr(self.FXF.READ))
-
-
- def test_lookupByName(self):
- """
- Constants can be looked up by name using L{Flags.lookupByName}.
- """
- flag = self.FXF.lookupByName("READ")
- self.assertIdentical(self.FXF.READ, flag)
-
-
- def test_notLookupMissingByName(self):
- """
- Names not defined with a L{FlagConstant} instance cannot be looked up
- using L{Flags.lookupByName}.
- """
- self.assertRaises(ValueError, self.FXF.lookupByName, "lookupByName")
- self.assertRaises(ValueError, self.FXF.lookupByName, "__init__")
- self.assertRaises(ValueError, self.FXF.lookupByName, "foo")
-
-
- def test_lookupByValue(self):
- """
- Constants can be looked up by their associated value, defined implicitly
- by the position in which the constant appears in the class definition or
- explicitly by the argument passed to L{FlagConstant}.
- """
- flag = self.FXF.lookupByValue(0x01)
- self.assertIdentical(flag, self.FXF.READ)
-
- flag = self.FXF.lookupByValue(0x02)
- self.assertIdentical(flag, self.FXF.WRITE)
-
- flag = self.FXF.lookupByValue(0x04)
- self.assertIdentical(flag, self.FXF.APPEND)
-
- flag = self.FXF.lookupByValue(0x20)
- self.assertIdentical(flag, self.FXF.EXCLUSIVE)
-
- flag = self.FXF.lookupByValue(0x40)
- self.assertIdentical(flag, self.FXF.TEXT)
-
-
- def test_lookupDuplicateByValue(self):
- """
- If more than one constant is associated with a particular value,
- L{Flags.lookupByValue} returns whichever of them is defined first.
- """
- class TIMEX(Flags):
- # (timex.mode)
- ADJ_OFFSET = FlagConstant(0x0001) # time offset
-
- # xntp 3.4 compatibility names
- MOD_OFFSET = FlagConstant(0x0001)
-
- self.assertIdentical(TIMEX.lookupByValue(0x0001), TIMEX.ADJ_OFFSET)
-
-
- def test_notLookupMissingByValue(self):
- """
- L{Flags.lookupByValue} raises L{ValueError} when called with a value
- with which no constant is associated.
- """
- self.assertRaises(ValueError, self.FXF.lookupByValue, 0x10)
-
-
- def test_name(self):
- """
- The C{name} attribute of one of the constants gives that constant's
- name.
- """
- self.assertEqual("READ", self.FXF.READ.name)
-
-
- def test_attributeIdentity(self):
- """
- Repeated access of an attribute associated with a L{FlagConstant} value
- in a L{Flags} subclass results in the same object.
- """
- self.assertIdentical(self.FXF.READ, self.FXF.READ)
-
-
- def test_iterconstants(self):
- """
- L{Flags.iterconstants} returns an iterator over all of the constants
- defined in the class, in the order they were defined.
- """
- constants = list(self.FXF.iterconstants())
- self.assertEqual(
- [self.FXF.READ, self.FXF.WRITE, self.FXF.APPEND,
- self.FXF.EXCLUSIVE, self.FXF.TEXT],
- constants)
-
-
- def test_attributeIterconstantsIdentity(self):
- """
- The constants returned from L{Flags.iterconstants} are identical to the
- constants accessible using attributes.
- """
- constants = list(self.FXF.iterconstants())
- self.assertIdentical(self.FXF.READ, constants[0])
- self.assertIdentical(self.FXF.WRITE, constants[1])
- self.assertIdentical(self.FXF.APPEND, constants[2])
- self.assertIdentical(self.FXF.EXCLUSIVE, constants[3])
- self.assertIdentical(self.FXF.TEXT, constants[4])
-
-
- def test_iterconstantsIdentity(self):
- """
- The constants returned from L{Flags.iterconstants} are identical on each
- call to that method.
- """
- constants = list(self.FXF.iterconstants())
- again = list(self.FXF.iterconstants())
- self.assertIdentical(again[0], constants[0])
- self.assertIdentical(again[1], constants[1])
- self.assertIdentical(again[2], constants[2])
- self.assertIdentical(again[3], constants[3])
- self.assertIdentical(again[4], constants[4])
-
-
- def test_initializedOnce(self):
- """
- L{Flags._enumerants} is initialized once and its value re-used on
- subsequent access.
- """
- first = self.FXF._enumerants
- self.FXF.READ # Side-effects!
- second = self.FXF._enumerants
- self.assertIdentical(first, second)
-
-
-
-class FlagConstantSimpleOrTests(_FlagsTestsMixin, TestCase):
- """
- Tests for the C{|} operator as defined for L{FlagConstant} instances, used
- to create new L{FlagConstant} instances representing both of two existing
- L{FlagConstant} instances from the same L{Flags} class.
- """
- def test_value(self):
- """
- The value of the L{FlagConstant} which results from C{|} has all of the
- bits set which were set in either of the values of the two original
- constants.
- """
- flag = self.FXF.READ | self.FXF.WRITE
- self.assertEqual(self.FXF.READ.value | self.FXF.WRITE.value, flag.value)
-
-
- def test_name(self):
- """
- The name of the L{FlagConstant} instance which results from C{|}
- includes the names of both of the two original constants.
- """
- flag = self.FXF.READ | self.FXF.WRITE
- self.assertEqual("{READ,WRITE}", flag.name)
-
-
- def test_representation(self):
- """
- The string representation of a L{FlagConstant} instance which results
- from C{|} includes the names of both of the two original constants.
- """
- flag = self.FXF.READ | self.FXF.WRITE
- self.assertEqual("<FXF={READ,WRITE}>", repr(flag))
-
-
-
-class FlagConstantSimpleAndTests(_FlagsTestsMixin, TestCase):
- """
- Tests for the C{&} operator as defined for L{FlagConstant} instances, used
- to create new L{FlagConstant} instances representing the common parts of two
- existing L{FlagConstant} instances from the same L{Flags} class.
- """
- def test_value(self):
- """
- The value of the L{FlagConstant} which results from C{&} has all of the
- bits set which were set in both of the values of the two original
- constants.
- """
- readWrite = (self.FXF.READ | self.FXF.WRITE)
- writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
- flag = readWrite & writeAppend
- self.assertEqual(self.FXF.WRITE.value, flag.value)
-
-
- def test_name(self):
- """
- The name of the L{FlagConstant} instance which results from C{&}
- includes the names of only the flags which were set in both of the two
- original constants.
- """
- readWrite = (self.FXF.READ | self.FXF.WRITE)
- writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
- flag = readWrite & writeAppend
- self.assertEqual("WRITE", flag.name)
-
-
- def test_representation(self):
- """
- The string representation of a L{FlagConstant} instance which results
- from C{&} includes the names of only the flags which were set in both
- both of the two original constants.
- """
- readWrite = (self.FXF.READ | self.FXF.WRITE)
- writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
- flag = readWrite & writeAppend
- self.assertEqual("<FXF=WRITE>", repr(flag))
-
-
-
-class FlagConstantSimpleExclusiveOrTests(_FlagsTestsMixin, TestCase):
- """
- Tests for the C{^} operator as defined for L{FlagConstant} instances, used
- to create new L{FlagConstant} instances representing the uncommon parts of
- two existing L{FlagConstant} instances from the same L{Flags} class.
- """
- def test_value(self):
- """
- The value of the L{FlagConstant} which results from C{^} has all of the
- bits set which were set in exactly one of the values of the two original
- constants.
- """
- readWrite = (self.FXF.READ | self.FXF.WRITE)
- writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
- flag = readWrite ^ writeAppend
- self.assertEqual(self.FXF.READ.value | self.FXF.APPEND.value, flag.value)
-
-
- def test_name(self):
- """
- The name of the L{FlagConstant} instance which results from C{^}
- includes the names of only the flags which were set in exactly one of
- the two original constants.
- """
- readWrite = (self.FXF.READ | self.FXF.WRITE)
- writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
- flag = readWrite ^ writeAppend
- self.assertEqual("{APPEND,READ}", flag.name)
-
-
- def test_representation(self):
- """
- The string representation of a L{FlagConstant} instance which results
- from C{^} includes the names of only the flags which were set in exactly
- one of the two original constants.
- """
- readWrite = (self.FXF.READ | self.FXF.WRITE)
- writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
- flag = readWrite ^ writeAppend
- self.assertEqual("<FXF={APPEND,READ}>", repr(flag))
-
-
-
-class FlagConstantNegationTests(_FlagsTestsMixin, TestCase):
- """
- Tests for the C{~} operator as defined for L{FlagConstant} instances, used
- to create new L{FlagConstant} instances representing all the flags from a
- L{Flags} class not set in a particular L{FlagConstant} instance.
- """
- def test_value(self):
- """
- The value of the L{FlagConstant} which results from C{~} has all of the
- bits set which were not set in the original constant.
- """
- flag = ~self.FXF.READ
- self.assertEqual(
- self.FXF.WRITE.value |
- self.FXF.APPEND.value |
- self.FXF.EXCLUSIVE.value |
- self.FXF.TEXT.value,
- flag.value)
-
- flag = ~self.FXF.WRITE
- self.assertEqual(
- self.FXF.READ.value |
- self.FXF.APPEND.value |
- self.FXF.EXCLUSIVE.value |
- self.FXF.TEXT.value,
- flag.value)
-
-
- def test_name(self):
- """
- The name of the L{FlagConstant} instance which results from C{~}
- includes the names of all the flags which were not set in the original
- constant.
- """
- flag = ~self.FXF.WRITE
- self.assertEqual("{APPEND,EXCLUSIVE,READ,TEXT}", flag.name)
-
-
- def test_representation(self):
- """
- The string representation of a L{FlagConstant} instance which results
- from C{~} includes the names of all the flags which were not set in the
- original constant.
- """
- flag = ~self.FXF.WRITE
- self.assertEqual("<FXF={APPEND,EXCLUSIVE,READ,TEXT}>", repr(flag))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_deprecate.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_deprecate.py
deleted file mode 100755
index 03498e4e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_deprecate.py
+++ /dev/null
@@ -1,767 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for Twisted's deprecation framework, L{twisted.python.deprecate}.
-"""
-
-import sys, types
-import warnings
-from os.path import normcase
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python import deprecate
-from twisted.python.deprecate import _appendToDocstring
-from twisted.python.deprecate import _getDeprecationDocstring
-from twisted.python.deprecate import deprecated, getDeprecationWarningString
-from twisted.python.deprecate import _getDeprecationWarningString
-from twisted.python.deprecate import DEPRECATION_WARNING_FORMAT
-from twisted.python.reflect import fullyQualifiedName
-from twisted.python.versions import Version
-from twisted.python.filepath import FilePath
-
-from twisted.python.test import deprecatedattributes
-from twisted.python.test.modules_helpers import TwistedModulesTestCase
-
-
-
-def dummyCallable():
- """
- Do nothing.
-
- This is used to test the deprecation decorators.
- """
-
-
-def dummyReplacementMethod():
- """
- Do nothing.
-
- This is used to test the replacement parameter to L{deprecated}.
- """
-
-
-
-class TestDeprecationWarnings(TestCase):
- def test_getDeprecationWarningString(self):
- """
- L{getDeprecationWarningString} returns a string that tells us that a
- callable was deprecated at a certain released version of Twisted.
- """
- version = Version('Twisted', 8, 0, 0)
- self.assertEqual(
- getDeprecationWarningString(self.test_getDeprecationWarningString,
- version),
- "twisted.python.test.test_deprecate.TestDeprecationWarnings."
- "test_getDeprecationWarningString was deprecated in "
- "Twisted 8.0.0")
-
-
- def test_getDeprecationWarningStringWithFormat(self):
- """
- L{getDeprecationWarningString} returns a string that tells us that a
- callable was deprecated at a certain released version of Twisted, with
- a message containing additional information about the deprecation.
- """
- version = Version('Twisted', 8, 0, 0)
- format = deprecate.DEPRECATION_WARNING_FORMAT + ': This is a message'
- self.assertEqual(
- getDeprecationWarningString(self.test_getDeprecationWarningString,
- version, format),
- 'twisted.python.test.test_deprecate.TestDeprecationWarnings.'
- 'test_getDeprecationWarningString was deprecated in '
- 'Twisted 8.0.0: This is a message')
-
-
- def test_deprecateEmitsWarning(self):
- """
- Decorating a callable with L{deprecated} emits a warning.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
- def addStackLevel():
- dummy()
- self.assertWarns(
- DeprecationWarning,
- getDeprecationWarningString(dummyCallable, version),
- __file__,
- addStackLevel)
-
-
- def test_deprecatedPreservesName(self):
- """
- The decorated function has the same name as the original.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
- self.assertEqual(dummyCallable.__name__, dummy.__name__)
- self.assertEqual(fullyQualifiedName(dummyCallable),
- fullyQualifiedName(dummy))
-
-
- def test_getDeprecationDocstring(self):
- """
- L{_getDeprecationDocstring} returns a note about the deprecation to go
- into a docstring.
- """
- version = Version('Twisted', 8, 0, 0)
- self.assertEqual(
- "Deprecated in Twisted 8.0.0.",
- _getDeprecationDocstring(version, ''))
-
-
- def test_deprecatedUpdatesDocstring(self):
- """
- The docstring of the deprecated function is appended with information
- about the deprecation.
- """
-
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
-
- _appendToDocstring(
- dummyCallable,
- _getDeprecationDocstring(version, ''))
-
- self.assertEqual(dummyCallable.__doc__, dummy.__doc__)
-
-
- def test_versionMetadata(self):
- """
- Deprecating a function adds version information to the decorated
- version of that function.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
- self.assertEqual(version, dummy.deprecatedVersion)
-
-
- def test_getDeprecationWarningStringReplacement(self):
- """
- L{getDeprecationWarningString} takes an additional replacement parameter
- that can be used to add information to the deprecation. If the
- replacement parameter is a string, it will be interpolated directly into
- the result.
- """
- version = Version('Twisted', 8, 0, 0)
- warningString = getDeprecationWarningString(
- self.test_getDeprecationWarningString, version,
- replacement="something.foobar")
- self.assertEqual(
- warningString,
- "%s was deprecated in Twisted 8.0.0; please use something.foobar "
- "instead" % (
- fullyQualifiedName(self.test_getDeprecationWarningString),))
-
-
- def test_getDeprecationWarningStringReplacementWithCallable(self):
- """
- L{getDeprecationWarningString} takes an additional replacement parameter
- that can be used to add information to the deprecation. If the
- replacement parameter is a callable, its fully qualified name will be
- interpolated into the result.
- """
- version = Version('Twisted', 8, 0, 0)
- warningString = getDeprecationWarningString(
- self.test_getDeprecationWarningString, version,
- replacement=dummyReplacementMethod)
- self.assertEqual(
- warningString,
- "%s was deprecated in Twisted 8.0.0; please use "
- "twisted.python.test.test_deprecate.dummyReplacementMethod "
- "instead" % (
- fullyQualifiedName(self.test_getDeprecationWarningString),))
-
-
- def test_deprecatedReplacement(self):
- """
- L{deprecated} takes an additional replacement parameter that can be used
- to indicate the new, non-deprecated method developers should use. If
- the replacement parameter is a string, it will be interpolated directly
- into the warning message.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version, "something.foobar")(dummyCallable)
- self.assertEqual(dummy.__doc__,
- "\n"
- " Do nothing.\n\n"
- " This is used to test the deprecation decorators.\n\n"
- " Deprecated in Twisted 8.0.0; please use "
- "something.foobar"
- " instead.\n"
- " ")
-
-
- def test_deprecatedReplacementWithCallable(self):
- """
- L{deprecated} takes an additional replacement parameter that can be used
- to indicate the new, non-deprecated method developers should use. If
- the replacement parameter is a callable, its fully qualified name will
- be interpolated into the warning message.
- """
- version = Version('Twisted', 8, 0, 0)
- decorator = deprecated(version, replacement=dummyReplacementMethod)
- dummy = decorator(dummyCallable)
- self.assertEqual(dummy.__doc__,
- "\n"
- " Do nothing.\n\n"
- " This is used to test the deprecation decorators.\n\n"
- " Deprecated in Twisted 8.0.0; please use "
- "twisted.python.test.test_deprecate.dummyReplacementMethod"
- " instead.\n"
- " ")
-
-
-
-class TestAppendToDocstring(TestCase):
- """
- Test the _appendToDocstring function.
-
- _appendToDocstring is used to add text to a docstring.
- """
-
- def test_appendToEmptyDocstring(self):
- """
- Appending to an empty docstring simply replaces the docstring.
- """
-
- def noDocstring():
- pass
-
- _appendToDocstring(noDocstring, "Appended text.")
- self.assertEqual("Appended text.", noDocstring.__doc__)
-
-
- def test_appendToSingleLineDocstring(self):
- """
- Appending to a single line docstring places the message on a new line,
- with a blank line separating it from the rest of the docstring.
-
- The docstring ends with a newline, conforming to Twisted and PEP 8
- standards. Unfortunately, the indentation is incorrect, since the
- existing docstring doesn't have enough info to help us indent
- properly.
- """
-
- def singleLineDocstring():
- """This doesn't comply with standards, but is here for a test."""
-
- _appendToDocstring(singleLineDocstring, "Appended text.")
- self.assertEqual(
- ["This doesn't comply with standards, but is here for a test.",
- "",
- "Appended text."],
- singleLineDocstring.__doc__.splitlines())
- self.assertTrue(singleLineDocstring.__doc__.endswith('\n'))
-
-
- def test_appendToMultilineDocstring(self):
- """
- Appending to a multi-line docstring places the messade on a new line,
- with a blank line separating it from the rest of the docstring.
-
- Because we have multiple lines, we have enough information to do
- indentation.
- """
-
- def multiLineDocstring():
- """
- This is a multi-line docstring.
- """
-
- def expectedDocstring():
- """
- This is a multi-line docstring.
-
- Appended text.
- """
-
- _appendToDocstring(multiLineDocstring, "Appended text.")
- self.assertEqual(
- expectedDocstring.__doc__, multiLineDocstring.__doc__)
-
-
-
-class _MockDeprecatedAttribute(object):
- """
- Mock of L{twisted.python.deprecate._DeprecatedAttribute}.
-
- @ivar value: The value of the attribute.
- """
- def __init__(self, value):
- self.value = value
-
-
- def get(self):
- """
- Get a known value.
- """
- return self.value
-
-
-
-class ModuleProxyTests(TestCase):
- """
- Tests for L{twisted.python.deprecate._ModuleProxy}, which proxies
- access to module-level attributes, intercepting access to deprecated
- attributes and passing through access to normal attributes.
- """
- def _makeProxy(self, **attrs):
- """
- Create a temporary module proxy object.
-
- @param **kw: Attributes to initialise on the temporary module object
-
- @rtype: L{twistd.python.deprecate._ModuleProxy}
- """
- mod = types.ModuleType('foo')
- for key, value in attrs.iteritems():
- setattr(mod, key, value)
- return deprecate._ModuleProxy(mod)
-
-
- def test_getattrPassthrough(self):
- """
- Getting a normal attribute on a L{twisted.python.deprecate._ModuleProxy}
- retrieves the underlying attribute's value, and raises C{AttributeError}
- if a non-existant attribute is accessed.
- """
- proxy = self._makeProxy(SOME_ATTRIBUTE='hello')
- self.assertIdentical(proxy.SOME_ATTRIBUTE, 'hello')
- self.assertRaises(AttributeError, getattr, proxy, 'DOES_NOT_EXIST')
-
-
- def test_getattrIntercept(self):
- """
- Getting an attribute marked as being deprecated on
- L{twisted.python.deprecate._ModuleProxy} results in calling the
- deprecated wrapper's C{get} method.
- """
- proxy = self._makeProxy()
- _deprecatedAttributes = object.__getattribute__(
- proxy, '_deprecatedAttributes')
- _deprecatedAttributes['foo'] = _MockDeprecatedAttribute(42)
- self.assertEqual(proxy.foo, 42)
-
-
- def test_privateAttributes(self):
- """
- Private attributes of L{twisted.python.deprecate._ModuleProxy} are
- inaccessible when regular attribute access is used.
- """
- proxy = self._makeProxy()
- self.assertRaises(AttributeError, getattr, proxy, '_module')
- self.assertRaises(
- AttributeError, getattr, proxy, '_deprecatedAttributes')
-
-
- def test_setattr(self):
- """
- Setting attributes on L{twisted.python.deprecate._ModuleProxy} proxies
- them through to the wrapped module.
- """
- proxy = self._makeProxy()
- proxy._module = 1
- self.assertNotEquals(object.__getattribute__(proxy, '_module'), 1)
- self.assertEqual(proxy._module, 1)
-
-
- def test_repr(self):
- """
- L{twisted.python.deprecated._ModuleProxy.__repr__} produces a string
- containing the proxy type and a representation of the wrapped module
- object.
- """
- proxy = self._makeProxy()
- realModule = object.__getattribute__(proxy, '_module')
- self.assertEqual(
- repr(proxy), '<%s module=%r>' % (type(proxy).__name__, realModule))
-
-
-
-class DeprecatedAttributeTests(TestCase):
- """
- Tests for L{twisted.python.deprecate._DeprecatedAttribute} and
- L{twisted.python.deprecate.deprecatedModuleAttribute}, which issue
- warnings for deprecated module-level attributes.
- """
- def setUp(self):
- self.version = deprecatedattributes.version
- self.message = deprecatedattributes.message
- self._testModuleName = __name__ + '.foo'
-
-
- def _getWarningString(self, attr):
- """
- Create the warning string used by deprecated attributes.
- """
- return _getDeprecationWarningString(
- deprecatedattributes.__name__ + '.' + attr,
- deprecatedattributes.version,
- DEPRECATION_WARNING_FORMAT + ': ' + deprecatedattributes.message)
-
-
- def test_deprecatedAttributeHelper(self):
- """
- L{twisted.python.deprecate._DeprecatedAttribute} correctly sets its
- __name__ to match that of the deprecated attribute and emits a warning
- when the original attribute value is accessed.
- """
- name = 'ANOTHER_DEPRECATED_ATTRIBUTE'
- setattr(deprecatedattributes, name, 42)
- attr = deprecate._DeprecatedAttribute(
- deprecatedattributes, name, self.version, self.message)
-
- self.assertEqual(attr.__name__, name)
-
- # Since we're accessing the value getter directly, as opposed to via
- # the module proxy, we need to match the warning's stack level.
- def addStackLevel():
- attr.get()
-
- # Access the deprecated attribute.
- addStackLevel()
- warningsShown = self.flushWarnings([
- self.test_deprecatedAttributeHelper])
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- warningsShown[0]['message'],
- self._getWarningString(name))
- self.assertEqual(len(warningsShown), 1)
-
-
- def test_deprecatedAttribute(self):
- """
- L{twisted.python.deprecate.deprecatedModuleAttribute} wraps a
- module-level attribute in an object that emits a deprecation warning
- when it is accessed the first time only, while leaving other unrelated
- attributes alone.
- """
- # Accessing non-deprecated attributes does not issue a warning.
- deprecatedattributes.ANOTHER_ATTRIBUTE
- warningsShown = self.flushWarnings([self.test_deprecatedAttribute])
- self.assertEqual(len(warningsShown), 0)
-
- name = 'DEPRECATED_ATTRIBUTE'
-
- # Access the deprecated attribute. This uses getattr to avoid repeating
- # the attribute name.
- getattr(deprecatedattributes, name)
-
- warningsShown = self.flushWarnings([self.test_deprecatedAttribute])
- self.assertEqual(len(warningsShown), 1)
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- warningsShown[0]['message'],
- self._getWarningString(name))
-
-
- def test_wrappedModule(self):
- """
- Deprecating an attribute in a module replaces and wraps that module
- instance, in C{sys.modules}, with a
- L{twisted.python.deprecate._ModuleProxy} instance but only if it hasn't
- already been wrapped.
- """
- sys.modules[self._testModuleName] = mod = types.ModuleType('foo')
- self.addCleanup(sys.modules.pop, self._testModuleName)
-
- setattr(mod, 'first', 1)
- setattr(mod, 'second', 2)
-
- deprecate.deprecatedModuleAttribute(
- Version('Twisted', 8, 0, 0),
- 'message',
- self._testModuleName,
- 'first')
-
- proxy = sys.modules[self._testModuleName]
- self.assertNotEqual(proxy, mod)
-
- deprecate.deprecatedModuleAttribute(
- Version('Twisted', 8, 0, 0),
- 'message',
- self._testModuleName,
- 'second')
-
- self.assertIdentical(proxy, sys.modules[self._testModuleName])
-
-
-
-class ImportedModuleAttributeTests(TwistedModulesTestCase):
- """
- Tests for L{deprecatedModuleAttribute} which involve loading a module via
- 'import'.
- """
-
- _packageInit = """\
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-deprecatedModuleAttribute(
- Version('Package', 1, 2, 3), 'message', __name__, 'module')
-"""
-
-
- def pathEntryTree(self, tree):
- """
- Create some files in a hierarchy, based on a dictionary describing those
- files. The resulting hierarchy will be placed onto sys.path for the
- duration of the test.
-
- @param tree: A dictionary representing a directory structure. Keys are
- strings, representing filenames, dictionary values represent
- directories, string values represent file contents.
-
- @return: another dictionary similar to the input, with file content
- strings replaced with L{FilePath} objects pointing at where those
- contents are now stored.
- """
- def makeSomeFiles(pathobj, dirdict):
- pathdict = {}
- for (key, value) in dirdict.items():
- child = pathobj.child(key)
- if isinstance(value, str):
- pathdict[key] = child
- child.setContent(value)
- elif isinstance(value, dict):
- child.createDirectory()
- pathdict[key] = makeSomeFiles(child, value)
- else:
- raise ValueError("only strings and dicts allowed as values")
- return pathdict
- base = FilePath(self.mktemp())
- base.makedirs()
-
- result = makeSomeFiles(base, tree)
- self.replaceSysPath([base.path] + sys.path)
- self.replaceSysModules(sys.modules.copy())
- return result
-
-
- def simpleModuleEntry(self):
- """
- Add a sample module and package to the path, returning a L{FilePath}
- pointing at the module which will be loadable as C{package.module}.
- """
- paths = self.pathEntryTree(
- {"package": {"__init__.py": self._packageInit,
- "module.py": ""}})
- return paths['package']['module.py']
-
-
- def checkOneWarning(self, modulePath):
- """
- Verification logic for L{test_deprecatedModule}.
- """
- # import package.module
- from package import module
- self.assertEqual(module.__file__, modulePath.path)
- emitted = self.flushWarnings([self.checkOneWarning])
- self.assertEqual(len(emitted), 1)
- self.assertEqual(emitted[0]['message'],
- 'package.module was deprecated in Package 1.2.3: '
- 'message')
- self.assertEqual(emitted[0]['category'], DeprecationWarning)
-
-
- def test_deprecatedModule(self):
- """
- If L{deprecatedModuleAttribute} is used to deprecate a module attribute
- of a package, only one deprecation warning is emitted when the
- deprecated module is imported.
- """
- self.checkOneWarning(self.simpleModuleEntry())
-
-
- def test_deprecatedModuleMultipleTimes(self):
- """
- If L{deprecatedModuleAttribute} is used to deprecate a module attribute
- of a package, only one deprecation warning is emitted when the
- deprecated module is subsequently imported.
- """
- mp = self.simpleModuleEntry()
- # The first time, the code needs to be loaded.
- self.checkOneWarning(mp)
- # The second time, things are slightly different; the object's already
- # in the namespace.
- self.checkOneWarning(mp)
- # The third and fourth times, things things should all be exactly the
- # same, but this is a sanity check to make sure the implementation isn't
- # special casing the second time. Also, putting these cases into a loop
- # means that the stack will be identical, to make sure that the
- # implementation doesn't rely too much on stack-crawling.
- for x in range(2):
- self.checkOneWarning(mp)
-
-
-
-class WarnAboutFunctionTests(TestCase):
- """
- Tests for L{twisted.python.deprecate.warnAboutFunction} which allows the
- callers of a function to issue a C{DeprecationWarning} about that function.
- """
- def setUp(self):
- """
- Create a file that will have known line numbers when emitting warnings.
- """
- self.package = FilePath(self.mktemp()).child('twisted_private_helper')
- self.package.makedirs()
- self.package.child('__init__.py').setContent('')
- self.package.child('module.py').setContent('''
-"A module string"
-
-from twisted.python import deprecate
-
-def testFunction():
- "A doc string"
- a = 1 + 2
- return a
-
-def callTestFunction():
- b = testFunction()
- if b == 3:
- deprecate.warnAboutFunction(testFunction, "A Warning String")
-''')
- sys.path.insert(0, self.package.parent().path)
- self.addCleanup(sys.path.remove, self.package.parent().path)
-
- modules = sys.modules.copy()
- self.addCleanup(
- lambda: (sys.modules.clear(), sys.modules.update(modules)))
-
-
- def test_warning(self):
- """
- L{deprecate.warnAboutFunction} emits a warning the file and line number
- of which point to the beginning of the implementation of the function
- passed to it.
- """
- def aFunc():
- pass
- deprecate.warnAboutFunction(aFunc, 'A Warning Message')
- warningsShown = self.flushWarnings()
- filename = __file__
- if filename.lower().endswith('.pyc'):
- filename = filename[:-1]
- self.assertSamePath(
- FilePath(warningsShown[0]["filename"]), FilePath(filename))
- self.assertEqual(warningsShown[0]["message"], "A Warning Message")
-
-
- def test_warningLineNumber(self):
- """
- L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the
- number of a line within the implementation of the function passed to it.
- """
- from twisted_private_helper import module
- module.callTestFunction()
- warningsShown = self.flushWarnings()
- self.assertSamePath(
- FilePath(warningsShown[0]["filename"]),
- self.package.sibling('twisted_private_helper').child('module.py'))
- # Line number 9 is the last line in the testFunction in the helper
- # module.
- self.assertEqual(warningsShown[0]["lineno"], 9)
- self.assertEqual(warningsShown[0]["message"], "A Warning String")
- self.assertEqual(len(warningsShown), 1)
-
-
- def assertSamePath(self, first, second):
- """
- Assert that the two paths are the same, considering case normalization
- appropriate for the current platform.
-
- @type first: L{FilePath}
- @type second: L{FilePath}
-
- @raise C{self.failureType}: If the paths are not the same.
- """
- self.assertTrue(
- normcase(first.path) == normcase(second.path),
- "%r != %r" % (first, second))
-
-
- def test_renamedFile(self):
- """
- Even if the implementation of a deprecated function is moved around on
- the filesystem, the line number in the warning emitted by
- L{deprecate.warnAboutFunction} points to a line in the implementation of
- the deprecated function.
- """
- from twisted_private_helper import module
- # Clean up the state resulting from that import; we're not going to use
- # this module, so it should go away.
- del sys.modules['twisted_private_helper']
- del sys.modules[module.__name__]
-
- # Rename the source directory
- self.package.moveTo(self.package.sibling('twisted_renamed_helper'))
-
- # Import the newly renamed version
- from twisted_renamed_helper import module
- self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
- self.addCleanup(sys.modules.pop, module.__name__)
-
- module.callTestFunction()
- warningsShown = self.flushWarnings()
- warnedPath = FilePath(warningsShown[0]["filename"])
- expectedPath = self.package.sibling(
- 'twisted_renamed_helper').child('module.py')
- self.assertSamePath(warnedPath, expectedPath)
- self.assertEqual(warningsShown[0]["lineno"], 9)
- self.assertEqual(warningsShown[0]["message"], "A Warning String")
- self.assertEqual(len(warningsShown), 1)
-
-
- def test_filteredWarning(self):
- """
- L{deprecate.warnAboutFunction} emits a warning that will be filtered if
- L{warnings.filterwarning} is called with the module name of the
- deprecated function.
- """
- # Clean up anything *else* that might spuriously filter out the warning,
- # such as the "always" simplefilter set up by unittest._collectWarnings.
- # We'll also rely on trial to restore the original filters afterwards.
- del warnings.filters[:]
-
- warnings.filterwarnings(
- action="ignore", module="twisted_private_helper")
-
- from twisted_private_helper import module
- module.callTestFunction()
-
- warningsShown = self.flushWarnings()
- self.assertEqual(len(warningsShown), 0)
-
-
- def test_filteredOnceWarning(self):
- """
- L{deprecate.warnAboutFunction} emits a warning that will be filtered
- once if L{warnings.filterwarning} is called with the module name of the
- deprecated function and an action of once.
- """
- # Clean up anything *else* that might spuriously filter out the warning,
- # such as the "always" simplefilter set up by unittest._collectWarnings.
- # We'll also rely on trial to restore the original filters afterwards.
- del warnings.filters[:]
-
- warnings.filterwarnings(
- action="module", module="twisted_private_helper")
-
- from twisted_private_helper import module
- module.callTestFunction()
- module.callTestFunction()
-
- warningsShown = self.flushWarnings()
- self.assertEqual(len(warningsShown), 1)
- message = warningsShown[0]['message']
- category = warningsShown[0]['category']
- filename = warningsShown[0]['filename']
- lineno = warningsShown[0]['lineno']
- msg = warnings.formatwarning(message, category, filename, lineno)
- self.assertTrue(
- msg.endswith("module.py:9: DeprecationWarning: A Warning String\n"
- " return a\n"),
- "Unexpected warning string: %r" % (msg,))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_dist.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_dist.py
deleted file mode 100755
index 34c67896..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_dist.py
+++ /dev/null
@@ -1,526 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for parts of our release automation system.
-"""
-
-
-import os
-import sys
-
-from distutils.core import Distribution
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python import dist
-from twisted.python.dist import (get_setup_args, ConditionalExtension,
- build_scripts_twisted)
-from twisted.python.filepath import FilePath
-
-
-
-class SetupTest(TestCase):
- """
- Tests for L{get_setup_args}.
- """
- def test_conditionalExtensions(self):
- """
- Passing C{conditionalExtensions} as a list of L{ConditionalExtension}
- objects to get_setup_args inserts a custom build_ext into the result
- which knows how to check whether they should be built.
- """
- good_ext = ConditionalExtension("whatever", ["whatever.c"],
- condition=lambda b: True)
- bad_ext = ConditionalExtension("whatever", ["whatever.c"],
- condition=lambda b: False)
- args = get_setup_args(conditionalExtensions=[good_ext, bad_ext])
- # ext_modules should be set even though it's not used. See comment
- # in get_setup_args
- self.assertEqual(args["ext_modules"], [good_ext, bad_ext])
- cmdclass = args["cmdclass"]
- build_ext = cmdclass["build_ext"]
- builder = build_ext(Distribution())
- builder.prepare_extensions()
- self.assertEqual(builder.extensions, [good_ext])
-
-
- def test_win32Definition(self):
- """
- When building on Windows NT, the WIN32 macro will be defined as 1.
- """
- ext = ConditionalExtension("whatever", ["whatever.c"],
- define_macros=[("whatever", 2)])
- args = get_setup_args(conditionalExtensions=[ext])
- builder = args["cmdclass"]["build_ext"](Distribution())
- self.patch(os, "name", "nt")
- builder.prepare_extensions()
- self.assertEqual(ext.define_macros, [("whatever", 2), ("WIN32", 1)])
-
-
-
-class GetExtensionsTest(TestCase):
- """
- Tests for L{dist.getExtensions}.
- """
-
- setupTemplate = (
- "from twisted.python.dist import ConditionalExtension\n"
- "extensions = [\n"
- " ConditionalExtension(\n"
- " '%s', ['twisted/some/thing.c'],\n"
- " condition=lambda builder: True)\n"
- " ]\n")
-
- def setUp(self):
- self.basedir = FilePath(self.mktemp()).child("twisted")
- self.basedir.makedirs()
- self.addCleanup(os.chdir, os.getcwd())
- os.chdir(self.basedir.parent().path)
-
-
- def writeSetup(self, name, *path):
- """
- Write out a C{setup.py} file to a location determined by
- L{self.basedir} and L{path}. L{self.setupTemplate} is used to
- generate its contents.
- """
- outdir = self.basedir.descendant(path)
- outdir.makedirs()
- setup = outdir.child("setup.py")
- setup.setContent(self.setupTemplate % (name,))
-
-
- def writeEmptySetup(self, *path):
- """
- Write out an empty C{setup.py} file to a location determined by
- L{self.basedir} and L{path}.
- """
- outdir = self.basedir.descendant(path)
- outdir.makedirs()
- outdir.child("setup.py").setContent("")
-
-
- def assertExtensions(self, expected):
- """
- Assert that the given names match the (sorted) names of discovered
- extensions.
- """
- extensions = dist.getExtensions()
- names = [extension.name for extension in extensions]
- self.assertEqual(sorted(names), expected)
-
-
- def test_getExtensions(self):
- """
- Files named I{setup.py} in I{twisted/topfiles} and I{twisted/*/topfiles}
- are executed with L{execfile} in order to discover the extensions they
- declare.
- """
- self.writeSetup("twisted.transmutate", "topfiles")
- self.writeSetup("twisted.tele.port", "tele", "topfiles")
- self.assertExtensions(["twisted.tele.port", "twisted.transmutate"])
-
-
- def test_getExtensionsTooDeep(self):
- """
- Files named I{setup.py} in I{topfiles} directories are not considered if
- they are too deep in the directory hierarchy.
- """
- self.writeSetup("twisted.trans.mog.rify", "trans", "mog", "topfiles")
- self.assertExtensions([])
-
-
- def test_getExtensionsNotTopfiles(self):
- """
- The folder in which I{setup.py} is discovered must be called I{topfiles}
- otherwise it is ignored.
- """
- self.writeSetup("twisted.metamorphosis", "notfiles")
- self.assertExtensions([])
-
-
- def test_getExtensionsNotSupportedOnJava(self):
- """
- Extensions are not supported on Java-based platforms.
- """
- self.addCleanup(setattr, sys, "platform", sys.platform)
- sys.platform = "java"
- self.writeSetup("twisted.sorcery", "topfiles")
- self.assertExtensions([])
-
-
- def test_getExtensionsExtensionsLocalIsOptional(self):
- """
- It is acceptable for extensions to not define the C{extensions} local
- variable.
- """
- self.writeEmptySetup("twisted.necromancy", "topfiles")
- self.assertExtensions([])
-
-
-
-class GetVersionTest(TestCase):
- """
- Tests for L{dist.getVersion}.
- """
-
- def setUp(self):
- self.dirname = self.mktemp()
- os.mkdir(self.dirname)
-
- def test_getVersionCore(self):
- """
- Test that getting the version of core reads from the
- [base]/_version.py file.
- """
- f = open(os.path.join(self.dirname, "_version.py"), "w")
- f.write("""
-from twisted.python import versions
-version = versions.Version("twisted", 0, 1, 2)
-""")
- f.close()
- self.assertEqual(dist.getVersion("core", base=self.dirname), "0.1.2")
-
- def test_getVersionOther(self):
- """
- Test that getting the version of a non-core project reads from
- the [base]/[projname]/_version.py file.
- """
- os.mkdir(os.path.join(self.dirname, "blat"))
- f = open(os.path.join(self.dirname, "blat", "_version.py"), "w")
- f.write("""
-from twisted.python import versions
-version = versions.Version("twisted.blat", 9, 8, 10)
-""")
- f.close()
- self.assertEqual(dist.getVersion("blat", base=self.dirname), "9.8.10")
-
-
-
-class GetScriptsTest(TestCase):
- """
- Tests for L{dist.getScripts} which returns the scripts which should be
- included in the distribution of a project.
- """
-
- def test_scriptsInSVN(self):
- """
- getScripts should return the scripts associated with a project
- in the context of Twisted SVN.
- """
- basedir = self.mktemp()
- os.mkdir(basedir)
- os.mkdir(os.path.join(basedir, 'bin'))
- os.mkdir(os.path.join(basedir, 'bin', 'proj'))
- f = open(os.path.join(basedir, 'bin', 'proj', 'exy'), 'w')
- f.write('yay')
- f.close()
- scripts = dist.getScripts('proj', basedir=basedir)
- self.assertEqual(len(scripts), 1)
- self.assertEqual(os.path.basename(scripts[0]), 'exy')
-
-
- def test_excludedPreamble(self):
- """
- L{dist.getScripts} includes neither C{"_preamble.py"} nor
- C{"_preamble.pyc"}.
- """
- basedir = FilePath(self.mktemp())
- bin = basedir.child('bin')
- bin.makedirs()
- bin.child('_preamble.py').setContent('some preamble code\n')
- bin.child('_preamble.pyc').setContent('some preamble byte code\n')
- bin.child('program').setContent('good program code\n')
- scripts = dist.getScripts("", basedir=basedir.path)
- self.assertEqual(scripts, [bin.child('program').path])
-
-
- def test_scriptsInRelease(self):
- """
- getScripts should return the scripts associated with a project
- in the context of a released subproject tarball.
- """
- basedir = self.mktemp()
- os.mkdir(basedir)
- os.mkdir(os.path.join(basedir, 'bin'))
- f = open(os.path.join(basedir, 'bin', 'exy'), 'w')
- f.write('yay')
- f.close()
- scripts = dist.getScripts('proj', basedir=basedir)
- self.assertEqual(len(scripts), 1)
- self.assertEqual(os.path.basename(scripts[0]), 'exy')
-
-
- def test_noScriptsInSVN(self):
- """
- When calling getScripts for a project which doesn't actually
- have any scripts, in the context of an SVN checkout, an
- empty list should be returned.
- """
- basedir = self.mktemp()
- os.mkdir(basedir)
- os.mkdir(os.path.join(basedir, 'bin'))
- os.mkdir(os.path.join(basedir, 'bin', 'otherproj'))
- scripts = dist.getScripts('noscripts', basedir=basedir)
- self.assertEqual(scripts, [])
-
-
- def test_getScriptsTopLevel(self):
- """
- Passing the empty string to getScripts returns scripts that are (only)
- in the top level bin directory.
- """
- basedir = FilePath(self.mktemp())
- basedir.createDirectory()
- bindir = basedir.child("bin")
- bindir.createDirectory()
- included = bindir.child("included")
- included.setContent("yay included")
- subdir = bindir.child("subdir")
- subdir.createDirectory()
- subdir.child("not-included").setContent("not included")
-
- scripts = dist.getScripts("", basedir=basedir.path)
- self.assertEqual(scripts, [included.path])
-
-
- def test_noScriptsInSubproject(self):
- """
- When calling getScripts for a project which doesn't actually
- have any scripts in the context of that project's individual
- project structure, an empty list should be returned.
- """
- basedir = self.mktemp()
- os.mkdir(basedir)
- scripts = dist.getScripts('noscripts', basedir=basedir)
- self.assertEqual(scripts, [])
-
-
-
-class DummyCommand:
- """
- A fake Command.
- """
- def __init__(self, **kwargs):
- for kw, val in kwargs.items():
- setattr(self, kw, val)
-
- def ensure_finalized(self):
- pass
-
-
-
-class BuildScriptsTest(TestCase):
- """
- Tests for L{dist.build_scripts_twisted}.
- """
-
- def setUp(self):
- self.source = FilePath(self.mktemp())
- self.target = FilePath(self.mktemp())
- self.source.makedirs()
- self.addCleanup(os.chdir, os.getcwd())
- os.chdir(self.source.path)
-
-
- def buildScripts(self):
- """
- Write 3 types of scripts and run the L{build_scripts_twisted}
- command.
- """
- self.writeScript(self.source, "script1",
- ("#! /usr/bin/env python2.7\n"
- "# bogus script w/ Python sh-bang\n"
- "pass\n"))
-
- self.writeScript(self.source, "script2.py",
- ("#!/usr/bin/python\n"
- "# bogus script w/ Python sh-bang\n"
- "pass\n"))
-
- self.writeScript(self.source, "shell.sh",
- ("#!/bin/sh\n"
- "# bogus shell script w/ sh-bang\n"
- "exit 0\n"))
-
- expected = ['script1', 'script2.py', 'shell.sh']
- cmd = self.getBuildScriptsCmd(self.target,
- [self.source.child(fn).path
- for fn in expected])
- cmd.finalize_options()
- cmd.run()
-
- return self.target.listdir()
-
-
- def getBuildScriptsCmd(self, target, scripts):
- """
- Create a distutils L{Distribution} with a L{DummyCommand} and wrap it
- in L{build_scripts_twisted}.
-
- @type target: L{FilePath}
- """
- dist = Distribution()
- dist.scripts = scripts
- dist.command_obj["build"] = DummyCommand(
- build_scripts = target.path,
- force = 1,
- executable = sys.executable
- )
- return build_scripts_twisted(dist)
-
-
- def writeScript(self, dir, name, text):
- """
- Write the script to disk.
- """
- with open(dir.child(name).path, "w") as f:
- f.write(text)
-
-
- def test_notWindows(self):
- """
- L{build_scripts_twisted} does not rename scripts on non-Windows
- platforms.
- """
- self.patch(os, "name", "twisted")
- built = self.buildScripts()
- for name in ['script1', 'script2.py', 'shell.sh']:
- self.assertTrue(name in built)
-
-
- def test_windows(self):
- """
- L{build_scripts_twisted} renames scripts so they end with '.py' on
- the Windows platform.
- """
- self.patch(os, "name", "nt")
- built = self.buildScripts()
- for name in ['script1.py', 'script2.py', 'shell.sh.py']:
- self.assertTrue(name in built)
-
-
-
-class FakeModule(object):
- """
- A fake module, suitable for dependency injection in testing.
- """
- def __init__(self, attrs):
- """
- Initializes a fake module.
-
- @param attrs: The attrs that will be accessible on the module.
- @type attrs: C{dict} of C{str} (Python names) to objects
- """
- self._attrs = attrs
-
-
- def __getattr__(self, name):
- """
- Gets an attribute of this fake module from its attrs.
-
- @raise AttributeError: When the requested attribute is missing.
- """
- try:
- return self._attrs[name]
- except KeyError:
- raise AttributeError()
-
-
-
-fakeCPythonPlatform = FakeModule({"python_implementation": lambda: "CPython"})
-fakeOtherPlatform = FakeModule({"python_implementation": lambda: "lvhpy"})
-emptyPlatform = FakeModule({})
-
-
-
-class WithPlatformTests(TestCase):
- """
- Tests for L{_checkCPython} when used with a (fake) recent C{platform}
- module.
- """
- def test_cpython(self):
- """
- L{_checkCPython} returns C{True} when C{platform.python_implementation}
- says we're running on CPython.
- """
- self.assertTrue(dist._checkCPython(platform=fakeCPythonPlatform))
-
-
- def test_other(self):
- """
- L{_checkCPython} returns C{False} when C{platform.python_implementation}
- says we're not running on CPython.
- """
- self.assertFalse(dist._checkCPython(platform=fakeOtherPlatform))
-
-
-
-fakeCPythonSys = FakeModule({"subversion": ("CPython", None, None)})
-fakeOtherSys = FakeModule({"subversion": ("lvhpy", None, None)})
-
-
-def _checkCPythonWithEmptyPlatform(sys):
- """
- A partially applied L{_checkCPython} that uses an empty C{platform}
- module (otherwise the code this test case is supposed to test won't
- even be called).
- """
- return dist._checkCPython(platform=emptyPlatform, sys=sys)
-
-
-
-class WithSubversionTest(TestCase):
- """
- Tests for L{_checkCPython} when used with a (fake) recent (2.5+)
- C{sys.subversion}. This is effectively only relevant for 2.5, since 2.6 and
- beyond have L{platform.python_implementation}, which is tried first.
- """
- def test_cpython(self):
- """
- L{_checkCPython} returns C{True} when C{platform.python_implementation}
- is unavailable and C{sys.subversion} says we're running on CPython.
- """
- isCPython = _checkCPythonWithEmptyPlatform(fakeCPythonSys)
- self.assertTrue(isCPython)
-
-
- def test_other(self):
- """
- L{_checkCPython} returns C{False} when C{platform.python_implementation}
- is unavailable and C{sys.subversion} says we're not running on CPython.
- """
- isCPython = _checkCPythonWithEmptyPlatform(fakeOtherSys)
- self.assertFalse(isCPython)
-
-
-
-oldCPythonSys = FakeModule({"modules": {}})
-oldPypySys = FakeModule({"modules": {"__pypy__": None}})
-
-
-class OldPythonsFallbackTest(TestCase):
- """
- Tests for L{_checkCPython} when used on a Python 2.4-like platform, when
- neither C{platform.python_implementation} nor C{sys.subversion} is
- available.
- """
- def test_cpython(self):
- """
- L{_checkCPython} returns C{True} when both
- C{platform.python_implementation} and C{sys.subversion} are unavailable
- and there is no C{__pypy__} module in C{sys.modules}.
- """
- isCPython = _checkCPythonWithEmptyPlatform(oldCPythonSys)
- self.assertTrue(isCPython)
-
-
- def test_pypy(self):
- """
- L{_checkCPython} returns C{False} when both
- C{platform.python_implementation} and C{sys.subversion} are unavailable
- and there is a C{__pypy__} module in C{sys.modules}.
- """
- isCPython = _checkCPythonWithEmptyPlatform(oldPypySys)
- self.assertFalse(isCPython)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_fakepwd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_fakepwd.py
deleted file mode 100755
index 6c101056..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_fakepwd.py
+++ /dev/null
@@ -1,386 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.fakepwd}.
-"""
-
-try:
- import pwd
-except ImportError:
- pwd = None
-
-try:
- import spwd
-except ImportError:
- spwd = None
-
-import os
-from operator import getitem
-
-from twisted.trial.unittest import TestCase
-from twisted.python.fakepwd import UserDatabase, ShadowDatabase
-from twisted.python.compat import set
-
-
-class UserDatabaseTestsMixin:
- """
- L{UserDatabaseTestsMixin} defines tests which apply to any user database
- implementation. Subclasses should mix it in, implement C{setUp} to create
- C{self.database} bound to a user database instance, and implement
- C{getExistingUserInfo} to return information about a user (such information
- should be unique per test method).
- """
- def test_getpwuid(self):
- """
- I{getpwuid} accepts a uid and returns the user record associated with
- it.
- """
- for i in range(2):
- # Get some user which exists in the database.
- username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
-
- # Now try to look it up and make sure the result is correct.
- entry = self.database.getpwuid(uid)
- self.assertEqual(entry.pw_name, username)
- self.assertEqual(entry.pw_passwd, password)
- self.assertEqual(entry.pw_uid, uid)
- self.assertEqual(entry.pw_gid, gid)
- self.assertEqual(entry.pw_gecos, gecos)
- self.assertEqual(entry.pw_dir, dir)
- self.assertEqual(entry.pw_shell, shell)
-
-
- def test_noSuchUID(self):
- """
- I{getpwuid} raises L{KeyError} when passed a uid which does not exist
- in the user database.
- """
- self.assertRaises(KeyError, self.database.getpwuid, -13)
-
-
- def test_getpwnam(self):
- """
- I{getpwnam} accepts a username and returns the user record associated
- with it.
- """
- for i in range(2):
- # Get some user which exists in the database.
- username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
-
- # Now try to look it up and make sure the result is correct.
- entry = self.database.getpwnam(username)
- self.assertEqual(entry.pw_name, username)
- self.assertEqual(entry.pw_passwd, password)
- self.assertEqual(entry.pw_uid, uid)
- self.assertEqual(entry.pw_gid, gid)
- self.assertEqual(entry.pw_gecos, gecos)
- self.assertEqual(entry.pw_dir, dir)
- self.assertEqual(entry.pw_shell, shell)
-
-
- def test_noSuchName(self):
- """
- I{getpwnam} raises L{KeyError} when passed a username which does not
- exist in the user database.
- """
- self.assertRaises(
- KeyError, self.database.getpwnam,
- 'no' 'such' 'user' 'exists' 'the' 'name' 'is' 'too' 'long' 'and' 'has'
- '\1' 'in' 'it' 'too')
-
-
- def test_recordLength(self):
- """
- The user record returned by I{getpwuid}, I{getpwnam}, and I{getpwall}
- has a length.
- """
- db = self.database
- username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
- for entry in [db.getpwuid(uid), db.getpwnam(username), db.getpwall()[0]]:
- self.assertIsInstance(len(entry), int)
- self.assertEqual(len(entry), 7)
-
-
- def test_recordIndexable(self):
- """
- The user record returned by I{getpwuid}, I{getpwnam}, and I{getpwall}
- is indexable, with successive indexes starting from 0 corresponding to
- the values of the C{pw_name}, C{pw_passwd}, C{pw_uid}, C{pw_gid},
- C{pw_gecos}, C{pw_dir}, and C{pw_shell} attributes, respectively.
- """
- db = self.database
- username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
- for entry in [db.getpwuid(uid), db.getpwnam(username), db.getpwall()[0]]:
- self.assertEqual(entry[0], username)
- self.assertEqual(entry[1], password)
- self.assertEqual(entry[2], uid)
- self.assertEqual(entry[3], gid)
- self.assertEqual(entry[4], gecos)
- self.assertEqual(entry[5], dir)
- self.assertEqual(entry[6], shell)
-
- self.assertEqual(len(entry), len(list(entry)))
- self.assertRaises(IndexError, getitem, entry, 7)
-
-
-
-class UserDatabaseTests(TestCase, UserDatabaseTestsMixin):
- """
- Tests for L{UserDatabase}.
- """
- def setUp(self):
- """
- Create a L{UserDatabase} with no user data in it.
- """
- self.database = UserDatabase()
- self._counter = 0
-
-
- def getExistingUserInfo(self):
- """
- Add a new user to C{self.database} and return its information.
- """
- self._counter += 1
- suffix = '_' + str(self._counter)
- username = 'username' + suffix
- password = 'password' + suffix
- uid = self._counter
- gid = self._counter + 1000
- gecos = 'gecos' + suffix
- dir = 'dir' + suffix
- shell = 'shell' + suffix
-
- self.database.addUser(username, password, uid, gid, gecos, dir, shell)
- return (username, password, uid, gid, gecos, dir, shell)
-
-
- def test_addUser(self):
- """
- L{UserDatabase.addUser} accepts seven arguments, one for each field of
- a L{pwd.struct_passwd}, and makes the new record available via
- L{UserDatabase.getpwuid}, L{UserDatabase.getpwnam}, and
- L{UserDatabase.getpwall}.
- """
- username = 'alice'
- password = 'secr3t'
- uid = 123
- gid = 456
- gecos = 'Alice,,,'
- home = '/users/alice'
- shell = '/usr/bin/foosh'
-
- db = self.database
- db.addUser(username, password, uid, gid, gecos, home, shell)
-
- for [entry] in [[db.getpwuid(uid)], [db.getpwnam(username)],
- db.getpwall()]:
- self.assertEqual(entry.pw_name, username)
- self.assertEqual(entry.pw_passwd, password)
- self.assertEqual(entry.pw_uid, uid)
- self.assertEqual(entry.pw_gid, gid)
- self.assertEqual(entry.pw_gecos, gecos)
- self.assertEqual(entry.pw_dir, home)
- self.assertEqual(entry.pw_shell, shell)
-
-
-
-class PwdModuleTests(TestCase, UserDatabaseTestsMixin):
- """
- L{PwdModuleTests} runs the tests defined by L{UserDatabaseTestsMixin}
- against the built-in C{pwd} module. This serves to verify that
- L{UserDatabase} is really a fake of that API.
- """
- if pwd is None:
- skip = "Cannot verify UserDatabase against pwd without pwd"
- else:
- database = pwd
-
- def setUp(self):
- self._users = iter(self.database.getpwall())
- self._uids = set()
-
-
- def getExistingUserInfo(self):
- """
- Read and return the next record from C{self._users}, filtering out
- any records with previously seen uid values (as these cannot be
- found with C{getpwuid} and only cause trouble).
- """
- while True:
- entry = next(self._users)
- uid = entry.pw_uid
- if uid not in self._uids:
- self._uids.add(uid)
- return entry
-
-
-
-class ShadowDatabaseTestsMixin:
- """
- L{ShadowDatabaseTestsMixin} defines tests which apply to any shadow user
- database implementation. Subclasses should mix it in, implement C{setUp} to
- create C{self.database} bound to a shadow user database instance, and
- implement C{getExistingUserInfo} to return information about a user (such
- information should be unique per test method).
- """
- def test_getspnam(self):
- """
- L{getspnam} accepts a username and returns the user record associated
- with it.
- """
- for i in range(2):
- # Get some user which exists in the database.
- (username, password, lastChange, min, max, warn, inact, expire,
- flag) = self.getExistingUserInfo()
-
- entry = self.database.getspnam(username)
- self.assertEqual(entry.sp_nam, username)
- self.assertEqual(entry.sp_pwd, password)
- self.assertEqual(entry.sp_lstchg, lastChange)
- self.assertEqual(entry.sp_min, min)
- self.assertEqual(entry.sp_max, max)
- self.assertEqual(entry.sp_warn, warn)
- self.assertEqual(entry.sp_inact, inact)
- self.assertEqual(entry.sp_expire, expire)
- self.assertEqual(entry.sp_flag, flag)
-
-
- def test_noSuchName(self):
- """
- I{getspnam} raises L{KeyError} when passed a username which does not
- exist in the user database.
- """
- self.assertRaises(KeyError, self.database.getspnam, "alice")
-
-
- def test_recordLength(self):
- """
- The shadow user record returned by I{getspnam} and I{getspall} has a
- length.
- """
- db = self.database
- username = self.getExistingUserInfo()[0]
- for entry in [db.getspnam(username), db.getspall()[0]]:
- self.assertIsInstance(len(entry), int)
- self.assertEqual(len(entry), 9)
-
-
- def test_recordIndexable(self):
- """
- The shadow user record returned by I{getpwnam} and I{getspall} is
- indexable, with successive indexes starting from 0 corresponding to the
- values of the C{sp_nam}, C{sp_pwd}, C{sp_lstchg}, C{sp_min}, C{sp_max},
- C{sp_warn}, C{sp_inact}, C{sp_expire}, and C{sp_flag} attributes,
- respectively.
- """
- db = self.database
- (username, password, lastChange, min, max, warn, inact, expire,
- flag) = self.getExistingUserInfo()
- for entry in [db.getspnam(username), db.getspall()[0]]:
- self.assertEqual(entry[0], username)
- self.assertEqual(entry[1], password)
- self.assertEqual(entry[2], lastChange)
- self.assertEqual(entry[3], min)
- self.assertEqual(entry[4], max)
- self.assertEqual(entry[5], warn)
- self.assertEqual(entry[6], inact)
- self.assertEqual(entry[7], expire)
- self.assertEqual(entry[8], flag)
-
- self.assertEqual(len(entry), len(list(entry)))
- self.assertRaises(IndexError, getitem, entry, 9)
-
-
-
-class ShadowDatabaseTests(TestCase, ShadowDatabaseTestsMixin):
- """
- Tests for L{ShadowDatabase}.
- """
- def setUp(self):
- """
- Create a L{ShadowDatabase} with no user data in it.
- """
- self.database = ShadowDatabase()
- self._counter = 0
-
-
- def getExistingUserInfo(self):
- """
- Add a new user to C{self.database} and return its information.
- """
- self._counter += 1
- suffix = '_' + str(self._counter)
- username = 'username' + suffix
- password = 'password' + suffix
- lastChange = self._counter + 1
- min = self._counter + 2
- max = self._counter + 3
- warn = self._counter + 4
- inact = self._counter + 5
- expire = self._counter + 6
- flag = self._counter + 7
-
- self.database.addUser(username, password, lastChange, min, max, warn,
- inact, expire, flag)
- return (username, password, lastChange, min, max, warn, inact,
- expire, flag)
-
-
- def test_addUser(self):
- """
- L{UserDatabase.addUser} accepts seven arguments, one for each field of
- a L{pwd.struct_passwd}, and makes the new record available via
- L{UserDatabase.getpwuid}, L{UserDatabase.getpwnam}, and
- L{UserDatabase.getpwall}.
- """
- username = 'alice'
- password = 'secr3t'
- lastChange = 17
- min = 42
- max = 105
- warn = 12
- inact = 3
- expire = 400
- flag = 3
-
- db = self.database
- db.addUser(username, password, lastChange, min, max, warn, inact,
- expire, flag)
-
- for [entry] in [[db.getspnam(username)], db.getspall()]:
- self.assertEqual(entry.sp_nam, username)
- self.assertEqual(entry.sp_pwd, password)
- self.assertEqual(entry.sp_lstchg, lastChange)
- self.assertEqual(entry.sp_min, min)
- self.assertEqual(entry.sp_max, max)
- self.assertEqual(entry.sp_warn, warn)
- self.assertEqual(entry.sp_inact, inact)
- self.assertEqual(entry.sp_expire, expire)
- self.assertEqual(entry.sp_flag, flag)
-
-
-
-class SPwdModuleTests(TestCase, ShadowDatabaseTestsMixin):
- """
- L{SPwdModuleTests} runs the tests defined by L{ShadowDatabaseTestsMixin}
- against the built-in C{spwd} module. This serves to verify that
- L{ShadowDatabase} is really a fake of that API.
- """
- if spwd is None:
- skip = "Cannot verify ShadowDatabase against spwd without spwd"
- elif os.getuid() != 0:
- skip = "Cannot access shadow user database except as root"
- else:
- database = spwd
-
- def setUp(self):
- self._users = iter(self.database.getspall())
-
-
- def getExistingUserInfo(self):
- """
- Read and return the next record from C{self._users}.
- """
- return next(self._users)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_hashlib.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_hashlib.py
deleted file mode 100755
index b50997c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_hashlib.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.hashlib}
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python.hashlib import md5, sha1
-
-
-class HashObjectTests(TestCase):
- """
- Tests for the hash object APIs presented by L{hashlib}, C{md5} and C{sha1}.
- """
- def test_md5(self):
- """
- L{hashlib.md5} returns an object which can be used to compute an MD5
- hash as defined by U{RFC 1321<http://www.ietf.org/rfc/rfc1321.txt>}.
- """
- # Test the result using values from section A.5 of the RFC.
- self.assertEqual(
- md5().hexdigest(), "d41d8cd98f00b204e9800998ecf8427e")
- self.assertEqual(
- md5("a").hexdigest(), "0cc175b9c0f1b6a831c399e269772661")
- self.assertEqual(
- md5("abc").hexdigest(), "900150983cd24fb0d6963f7d28e17f72")
- self.assertEqual(
- md5("message digest").hexdigest(),
- "f96b697d7cb7938d525a2f31aaf161d0")
- self.assertEqual(
- md5("abcdefghijklmnopqrstuvwxyz").hexdigest(),
- "c3fcd3d76192e4007dfb496cca67e13b")
- self.assertEqual(
- md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- "0123456789").hexdigest(),
- "d174ab98d277d9f5a5611c2c9f419d9f")
- self.assertEqual(
- md5("1234567890123456789012345678901234567890123456789012345678901"
- "2345678901234567890").hexdigest(),
- "57edf4a22be3c955ac49da2e2107b67a")
-
- # It should have digest and update methods, too.
- self.assertEqual(
- md5().digest().encode('hex'),
- "d41d8cd98f00b204e9800998ecf8427e")
- hash = md5()
- hash.update("a")
- self.assertEqual(
- hash.digest().encode('hex'),
- "0cc175b9c0f1b6a831c399e269772661")
-
- # Instances of it should have a digest_size attribute
- self.assertEqual(md5().digest_size, 16)
-
-
- def test_sha1(self):
- """
- L{hashlib.sha1} returns an object which can be used to compute a SHA1
- hash as defined by U{RFC 3174<http://tools.ietf.org/rfc/rfc3174.txt>}.
- """
- def format(s):
- return ''.join(s.split()).lower()
- # Test the result using values from section 7.3 of the RFC.
- self.assertEqual(
- sha1("abc").hexdigest(),
- format(
- "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D"))
- self.assertEqual(
- sha1("abcdbcdecdefdefgefghfghighijhi"
- "jkijkljklmklmnlmnomnopnopq").hexdigest(),
- format(
- "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1"))
-
- # It should have digest and update methods, too.
- self.assertEqual(
- sha1("abc").digest().encode('hex'),
- format(
- "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D"))
- hash = sha1()
- hash.update("abc")
- self.assertEqual(
- hash.digest().encode('hex'),
- format(
- "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D"))
-
- # Instances of it should have a digest_size attribute.
- self.assertEqual(
- sha1().digest_size, 20)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_htmlizer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_htmlizer.py
deleted file mode 100755
index 38e607a7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_htmlizer.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.htmlizer}.
-"""
-
-from StringIO import StringIO
-
-from twisted.trial.unittest import TestCase
-from twisted.python.htmlizer import filter
-
-
-class FilterTests(TestCase):
- """
- Tests for L{twisted.python.htmlizer.filter}.
- """
- def test_empty(self):
- """
- If passed an empty input file, L{filter} writes a I{pre} tag containing
- only an end marker to the output file.
- """
- input = StringIO("")
- output = StringIO()
- filter(input, output)
- self.assertEqual(output.getvalue(), '<pre><span class="py-src-endmarker"></span></pre>\n')
-
-
- def test_variable(self):
- """
- If passed an input file containing a variable access, L{filter} writes
- a I{pre} tag containing a I{py-src-variable} span containing the
- variable.
- """
- input = StringIO("foo\n")
- output = StringIO()
- filter(input, output)
- self.assertEqual(
- output.getvalue(),
- '<pre><span class="py-src-variable">foo</span><span class="py-src-newline">\n'
- '</span><span class="py-src-endmarker"></span></pre>\n')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_inotify.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_inotify.py
deleted file mode 100755
index a6cea65e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_inotify.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python._inotify}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.python.runtime import platform
-
-if platform.supportsINotify():
- from ctypes import c_int, c_uint32, c_char_p
- from twisted.python import _inotify
- from twisted.python._inotify import (
- INotifyError, initializeModule, init, add)
-else:
- _inotify = None
-
-
-
-class INotifyTests(TestCase):
- """
- Tests for L{twisted.python._inotify}.
- """
- if _inotify is None:
- skip = "This platform doesn't support INotify."
-
- def test_missingInit(self):
- """
- If the I{libc} object passed to L{initializeModule} has no
- C{inotify_init} attribute, L{ImportError} is raised.
- """
- class libc:
- def inotify_add_watch(self):
- pass
- def inotify_rm_watch(self):
- pass
- self.assertRaises(ImportError, initializeModule, libc())
-
-
- def test_missingAdd(self):
- """
- If the I{libc} object passed to L{initializeModule} has no
- C{inotify_add_watch} attribute, L{ImportError} is raised.
- """
- class libc:
- def inotify_init(self):
- pass
- def inotify_rm_watch(self):
- pass
- self.assertRaises(ImportError, initializeModule, libc())
-
-
- def test_missingRemove(self):
- """
- If the I{libc} object passed to L{initializeModule} has no
- C{inotify_rm_watch} attribute, L{ImportError} is raised.
- """
- class libc:
- def inotify_init(self):
- pass
- def inotify_add_watch(self):
- pass
- self.assertRaises(ImportError, initializeModule, libc())
-
-
- def test_setTypes(self):
- """
- If the I{libc} object passed to L{initializeModule} has all of the
- necessary attributes, it sets the C{argtypes} and C{restype} attributes
- of the three ctypes methods used from libc.
- """
- class libc:
- def inotify_init(self):
- pass
- inotify_init = staticmethod(inotify_init)
-
- def inotify_rm_watch(self):
- pass
- inotify_rm_watch = staticmethod(inotify_rm_watch)
-
- def inotify_add_watch(self):
- pass
- inotify_add_watch = staticmethod(inotify_add_watch)
-
- c = libc()
- initializeModule(c)
- self.assertEqual(c.inotify_init.argtypes, [])
- self.assertEqual(c.inotify_init.restype, c_int)
-
- self.assertEqual(c.inotify_rm_watch.argtypes, [c_int, c_int])
- self.assertEqual(c.inotify_rm_watch.restype, c_int)
-
- self.assertEqual(
- c.inotify_add_watch.argtypes, [c_int, c_char_p, c_uint32])
- self.assertEqual(c.inotify_add_watch.restype, c_int)
-
-
- def test_failedInit(self):
- """
- If C{inotify_init} returns a negative number, L{init} raises
- L{INotifyError}.
- """
- class libc:
- def inotify_init(self):
- return -1
- self.patch(_inotify, 'libc', libc())
- self.assertRaises(INotifyError, init)
-
-
- def test_failedAddWatch(self):
- """
- If C{inotify_add_watch} returns a negative number, L{add}
- raises L{INotifyError}.
- """
- class libc:
- def inotify_add_watch(self, fd, path, mask):
- return -1
- self.patch(_inotify, 'libc', libc())
- self.assertRaises(INotifyError, add, 3, '/foo', 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_release.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_release.py
deleted file mode 100755
index a4f868c7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_release.py
+++ /dev/null
@@ -1,2598 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.release} and L{twisted.python._release}.
-
-All of these tests are skipped on platforms other than Linux, as the release is
-only ever performed on Linux.
-"""
-
-
-import warnings
-import operator
-import os, sys, signal
-from StringIO import StringIO
-import tarfile
-from xml.dom import minidom as dom
-
-from datetime import date
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python.compat import execfile, set
-from twisted.python.procutils import which
-from twisted.python import release
-from twisted.python.filepath import FilePath
-from twisted.python.versions import Version
-from twisted.python._release import _changeVersionInFile, getNextVersion
-from twisted.python._release import findTwistedProjects, replaceInFile
-from twisted.python._release import replaceProjectVersion
-from twisted.python._release import updateTwistedVersionInformation, Project
-from twisted.python._release import generateVersionFileData
-from twisted.python._release import changeAllProjectVersions
-from twisted.python._release import VERSION_OFFSET, DocBuilder, ManBuilder
-from twisted.python._release import NoDocumentsFound, filePathDelta
-from twisted.python._release import CommandFailed, BookBuilder
-from twisted.python._release import DistributionBuilder, APIBuilder
-from twisted.python._release import BuildAPIDocsScript
-from twisted.python._release import buildAllTarballs, runCommand
-from twisted.python._release import UncleanWorkingDirectory, NotWorkingDirectory
-from twisted.python._release import ChangeVersionsScript, BuildTarballsScript
-from twisted.python._release import NewsBuilder
-
-if os.name != 'posix':
- skip = "Release toolchain only supported on POSIX."
-else:
- skip = None
-
-
-# Check a bunch of dependencies to skip tests if necessary.
-try:
- from twisted.lore.scripts import lore
-except ImportError:
- loreSkip = "Lore is not present."
-else:
- loreSkip = skip
-
-
-try:
- import pydoctor.driver
- # it might not be installed, or it might use syntax not available in
- # this version of Python.
-except (ImportError, SyntaxError):
- pydoctorSkip = "Pydoctor is not present."
-else:
- if getattr(pydoctor, "version_info", (0,)) < (0, 1):
- pydoctorSkip = "Pydoctor is too old."
- else:
- pydoctorSkip = skip
-
-
-if which("latex") and which("dvips") and which("ps2pdf13"):
- latexSkip = skip
-else:
- latexSkip = "LaTeX is not available."
-
-
-if which("svn") and which("svnadmin"):
- svnSkip = skip
-else:
- svnSkip = "svn or svnadmin is not present."
-
-
-def genVersion(*args, **kwargs):
- """
- A convenience for generating _version.py data.
-
- @param args: Arguments to pass to L{Version}.
- @param kwargs: Keyword arguments to pass to L{Version}.
- """
- return generateVersionFileData(Version(*args, **kwargs))
-
-
-
-class StructureAssertingMixin(object):
- """
- A mixin for L{TestCase} subclasses which provides some methods for asserting
- the structure and contents of directories and files on the filesystem.
- """
- def createStructure(self, root, dirDict):
- """
- Create a set of directories and files given a dict defining their
- structure.
-
- @param root: The directory in which to create the structure. It must
- already exist.
- @type root: L{FilePath}
-
- @param dirDict: The dict defining the structure. Keys should be strings
- naming files, values should be strings describing file contents OR
- dicts describing subdirectories. All files are written in binary
- mode. Any string values are assumed to describe text files and
- will have their newlines replaced with the platform-native newline
- convention. For example::
-
- {"foofile": "foocontents",
- "bardir": {"barfile": "bar\ncontents"}}
- @type dirDict: C{dict}
- """
- for x in dirDict:
- child = root.child(x)
- if isinstance(dirDict[x], dict):
- child.createDirectory()
- self.createStructure(child, dirDict[x])
- else:
- child.setContent(dirDict[x].replace('\n', os.linesep))
-
- def assertStructure(self, root, dirDict):
- """
- Assert that a directory is equivalent to one described by a dict.
-
- @param root: The filesystem directory to compare.
- @type root: L{FilePath}
- @param dirDict: The dict that should describe the contents of the
- directory. It should be the same structure as the C{dirDict}
- parameter to L{createStructure}.
- @type dirDict: C{dict}
- """
- children = [x.basename() for x in root.children()]
- for x in dirDict:
- child = root.child(x)
- if isinstance(dirDict[x], dict):
- self.assertTrue(child.isdir(), "%s is not a dir!"
- % (child.path,))
- self.assertStructure(child, dirDict[x])
- else:
- a = child.getContent().replace(os.linesep, '\n')
- self.assertEqual(a, dirDict[x], child.path)
- children.remove(x)
- if children:
- self.fail("There were extra children in %s: %s"
- % (root.path, children))
-
-
- def assertExtractedStructure(self, outputFile, dirDict):
- """
- Assert that a tarfile content is equivalent to one described by a dict.
-
- @param outputFile: The tar file built by L{DistributionBuilder}.
- @type outputFile: L{FilePath}.
- @param dirDict: The dict that should describe the contents of the
- directory. It should be the same structure as the C{dirDict}
- parameter to L{createStructure}.
- @type dirDict: C{dict}
- """
- tarFile = tarfile.TarFile.open(outputFile.path, "r:bz2")
- extracted = FilePath(self.mktemp())
- extracted.createDirectory()
- for info in tarFile:
- tarFile.extract(info, path=extracted.path)
- self.assertStructure(extracted.children()[0], dirDict)
-
-
-
-class ChangeVersionTest(TestCase, StructureAssertingMixin):
- """
- Twisted has the ability to change versions.
- """
-
- def makeFile(self, relativePath, content):
- """
- Create a file with the given content relative to a temporary directory.
-
- @param relativePath: The basename of the file to create.
- @param content: The content that the file will have.
- @return: The filename.
- """
- baseDirectory = FilePath(self.mktemp())
- directory, filename = os.path.split(relativePath)
- directory = baseDirectory.preauthChild(directory)
- directory.makedirs()
- file = directory.child(filename)
- directory.child(filename).setContent(content)
- return file
-
-
- def test_getNextVersion(self):
- """
- When calculating the next version to release when a release is
- happening in the same year as the last release, the minor version
- number is incremented.
- """
- now = date.today()
- major = now.year - VERSION_OFFSET
- version = Version("twisted", major, 9, 0)
- self.assertEqual(getNextVersion(version, now=now),
- Version("twisted", major, 10, 0))
-
-
- def test_getNextVersionAfterYearChange(self):
- """
- When calculating the next version to release when a release is
- happening in a later year, the minor version number is reset to 0.
- """
- now = date.today()
- major = now.year - VERSION_OFFSET
- version = Version("twisted", major - 1, 9, 0)
- self.assertEqual(getNextVersion(version, now=now),
- Version("twisted", major, 0, 0))
-
-
- def test_changeVersionInFile(self):
- """
- _changeVersionInFile replaces the old version information in a file
- with the given new version information.
- """
- # The version numbers are arbitrary, the name is only kind of
- # arbitrary.
- packageName = 'foo'
- oldVersion = Version(packageName, 2, 5, 0)
- file = self.makeFile('README',
- "Hello and welcome to %s." % oldVersion.base())
-
- newVersion = Version(packageName, 7, 6, 0)
- _changeVersionInFile(oldVersion, newVersion, file.path)
-
- self.assertEqual(file.getContent(),
- "Hello and welcome to %s." % newVersion.base())
-
-
- def test_changeAllProjectVersions(self):
- """
- L{changeAllProjectVersions} changes all version numbers in _version.py
- and README files for all projects as well as in the the top-level
- README file.
- """
- root = FilePath(self.mktemp())
- root.createDirectory()
- structure = {
- "README": "Hi this is 1.0.0.",
- "twisted": {
- "topfiles": {
- "README": "Hi this is 1.0.0"},
- "_version.py":
- genVersion("twisted", 1, 0, 0),
- "web": {
- "topfiles": {
- "README": "Hi this is 1.0.0"},
- "_version.py": genVersion("twisted.web", 1, 0, 0)
- }}}
- self.createStructure(root, structure)
- changeAllProjectVersions(root, Version("lol", 1, 0, 2))
- outStructure = {
- "README": "Hi this is 1.0.2.",
- "twisted": {
- "topfiles": {
- "README": "Hi this is 1.0.2"},
- "_version.py":
- genVersion("twisted", 1, 0, 2),
- "web": {
- "topfiles": {
- "README": "Hi this is 1.0.2"},
- "_version.py": genVersion("twisted.web", 1, 0, 2),
- }}}
- self.assertStructure(root, outStructure)
-
-
- def test_changeAllProjectVersionsPreRelease(self):
- """
- L{changeAllProjectVersions} changes all version numbers in _version.py
- and README files for all projects as well as in the the top-level
- README file. If the old version was a pre-release, it will change the
- version in NEWS files as well.
- """
- root = FilePath(self.mktemp())
- root.createDirectory()
- coreNews = ("Twisted Core 1.0.0 (2009-12-25)\n"
- "===============================\n"
- "\n")
- webNews = ("Twisted Web 1.0.0pre1 (2009-12-25)\n"
- "==================================\n"
- "\n")
- structure = {
- "README": "Hi this is 1.0.0.",
- "NEWS": coreNews + webNews,
- "twisted": {
- "topfiles": {
- "README": "Hi this is 1.0.0",
- "NEWS": coreNews},
- "_version.py":
- genVersion("twisted", 1, 0, 0),
- "web": {
- "topfiles": {
- "README": "Hi this is 1.0.0pre1",
- "NEWS": webNews},
- "_version.py": genVersion("twisted.web", 1, 0, 0, 1)
- }}}
- self.createStructure(root, structure)
- changeAllProjectVersions(root, Version("lol", 1, 0, 2), '2010-01-01')
- coreNews = (
- "Twisted Core 1.0.0 (2009-12-25)\n"
- "===============================\n"
- "\n")
- webNews = ("Twisted Web 1.0.2 (2010-01-01)\n"
- "==============================\n"
- "\n")
- outStructure = {
- "README": "Hi this is 1.0.2.",
- "NEWS": coreNews + webNews,
- "twisted": {
- "topfiles": {
- "README": "Hi this is 1.0.2",
- "NEWS": coreNews},
- "_version.py":
- genVersion("twisted", 1, 0, 2),
- "web": {
- "topfiles": {
- "README": "Hi this is 1.0.2",
- "NEWS": webNews},
- "_version.py": genVersion("twisted.web", 1, 0, 2),
- }}}
- self.assertStructure(root, outStructure)
-
-
-
-class ProjectTest(TestCase):
- """
- There is a first-class representation of a project.
- """
-
- def assertProjectsEqual(self, observedProjects, expectedProjects):
- """
- Assert that two lists of L{Project}s are equal.
- """
- self.assertEqual(len(observedProjects), len(expectedProjects))
- observedProjects = sorted(observedProjects,
- key=operator.attrgetter('directory'))
- expectedProjects = sorted(expectedProjects,
- key=operator.attrgetter('directory'))
- for observed, expected in zip(observedProjects, expectedProjects):
- self.assertEqual(observed.directory, expected.directory)
-
-
- def makeProject(self, version, baseDirectory=None):
- """
- Make a Twisted-style project in the given base directory.
-
- @param baseDirectory: The directory to create files in
- (as a L{FilePath).
- @param version: The version information for the project.
- @return: L{Project} pointing to the created project.
- """
- if baseDirectory is None:
- baseDirectory = FilePath(self.mktemp())
- baseDirectory.createDirectory()
- segments = version.package.split('.')
- directory = baseDirectory
- for segment in segments:
- directory = directory.child(segment)
- if not directory.exists():
- directory.createDirectory()
- directory.child('__init__.py').setContent('')
- directory.child('topfiles').createDirectory()
- directory.child('topfiles').child('README').setContent(version.base())
- replaceProjectVersion(
- directory.child('_version.py').path, version)
- return Project(directory)
-
-
- def makeProjects(self, *versions):
- """
- Create a series of projects underneath a temporary base directory.
-
- @return: A L{FilePath} for the base directory.
- """
- baseDirectory = FilePath(self.mktemp())
- baseDirectory.createDirectory()
- for version in versions:
- self.makeProject(version, baseDirectory)
- return baseDirectory
-
-
- def test_getVersion(self):
- """
- Project objects know their version.
- """
- version = Version('foo', 2, 1, 0)
- project = self.makeProject(version)
- self.assertEqual(project.getVersion(), version)
-
-
- def test_updateVersion(self):
- """
- Project objects know how to update the version numbers in those
- projects.
- """
- project = self.makeProject(Version("bar", 2, 1, 0))
- newVersion = Version("bar", 3, 2, 9)
- project.updateVersion(newVersion)
- self.assertEqual(project.getVersion(), newVersion)
- self.assertEqual(
- project.directory.child("topfiles").child("README").getContent(),
- "3.2.9")
-
-
- def test_repr(self):
- """
- The representation of a Project is Project(directory).
- """
- foo = Project(FilePath('bar'))
- self.assertEqual(
- repr(foo), 'Project(%r)' % (foo.directory))
-
-
- def test_findTwistedStyleProjects(self):
- """
- findTwistedStyleProjects finds all projects underneath a particular
- directory. A 'project' is defined by the existence of a 'topfiles'
- directory and is returned as a Project object.
- """
- baseDirectory = self.makeProjects(
- Version('foo', 2, 3, 0), Version('foo.bar', 0, 7, 4))
- projects = findTwistedProjects(baseDirectory)
- self.assertProjectsEqual(
- projects,
- [Project(baseDirectory.child('foo')),
- Project(baseDirectory.child('foo').child('bar'))])
-
-
- def test_updateTwistedVersionInformation(self):
- """
- Update Twisted version information in the top-level project and all of
- the subprojects.
- """
- baseDirectory = FilePath(self.mktemp())
- baseDirectory.createDirectory()
- now = date.today()
-
- projectName = 'foo'
- oldVersion = Version(projectName, 2, 5, 0)
- newVersion = getNextVersion(oldVersion, now=now)
-
- project = self.makeProject(oldVersion, baseDirectory)
-
- updateTwistedVersionInformation(baseDirectory, now=now)
-
- self.assertEqual(project.getVersion(), newVersion)
- self.assertEqual(
- project.directory.child('topfiles').child('README').getContent(),
- newVersion.base())
-
-
-
-class UtilityTest(TestCase):
- """
- Tests for various utility functions for releasing.
- """
-
- def test_chdir(self):
- """
- Test that the runChdirSafe is actually safe, i.e., it still
- changes back to the original directory even if an error is
- raised.
- """
- cwd = os.getcwd()
- def chAndBreak():
- os.mkdir('releaseCh')
- os.chdir('releaseCh')
- 1//0
- self.assertRaises(ZeroDivisionError,
- release.runChdirSafe, chAndBreak)
- self.assertEqual(cwd, os.getcwd())
-
-
-
- def test_replaceInFile(self):
- """
- L{replaceInFile} replaces data in a file based on a dict. A key from
- the dict that is found in the file is replaced with the corresponding
- value.
- """
- in_ = 'foo\nhey hey $VER\nbar\n'
- outf = open('release.replace', 'w')
- outf.write(in_)
- outf.close()
-
- expected = in_.replace('$VER', '2.0.0')
- replaceInFile('release.replace', {'$VER': '2.0.0'})
- self.assertEqual(open('release.replace').read(), expected)
-
-
- expected = expected.replace('2.0.0', '3.0.0')
- replaceInFile('release.replace', {'2.0.0': '3.0.0'})
- self.assertEqual(open('release.replace').read(), expected)
-
-
-
-class VersionWritingTest(TestCase):
- """
- Tests for L{replaceProjectVersion}.
- """
-
- def test_replaceProjectVersion(self):
- """
- L{replaceProjectVersion} writes a Python file that defines a
- C{version} variable that corresponds to the given name and version
- number.
- """
- replaceProjectVersion("test_project",
- Version("twisted.test_project", 0, 82, 7))
- ns = {'__name___': 'twisted.test_project'}
- execfile("test_project", ns)
- self.assertEqual(ns["version"].base(), "0.82.7")
-
-
- def test_replaceProjectVersionWithPrerelease(self):
- """
- L{replaceProjectVersion} will write a Version instantiation that
- includes a prerelease parameter if necessary.
- """
- replaceProjectVersion("test_project",
- Version("twisted.test_project", 0, 82, 7,
- prerelease=8))
- ns = {'__name___': 'twisted.test_project'}
- execfile("test_project", ns)
- self.assertEqual(ns["version"].base(), "0.82.7pre8")
-
-
-
-class BuilderTestsMixin(object):
- """
- A mixin class which provides various methods for creating sample Lore input
- and output.
-
- @cvar template: The lore template that will be used to prepare sample
- output.
- @type template: C{str}
-
- @ivar docCounter: A counter which is incremented every time input is
- generated and which is included in the documents.
- @type docCounter: C{int}
- """
- template = '''
- <html>
- <head><title>Yo:</title></head>
- <body>
- <div class="body" />
- <a href="index.html">Index</a>
- <span class="version">Version: </span>
- </body>
- </html>
- '''
-
- def setUp(self):
- """
- Initialize the doc counter which ensures documents are unique.
- """
- self.docCounter = 0
-
-
- def assertXMLEqual(self, first, second):
- """
- Verify that two strings represent the same XML document.
- """
- self.assertEqual(
- dom.parseString(first).toxml(),
- dom.parseString(second).toxml())
-
-
- def getArbitraryOutput(self, version, counter, prefix="", apiBaseURL="%s"):
- """
- Get the correct HTML output for the arbitrary input returned by
- L{getArbitraryLoreInput} for the given parameters.
-
- @param version: The version string to include in the output.
- @type version: C{str}
- @param counter: A counter to include in the output.
- @type counter: C{int}
- """
- document = """\
-<?xml version="1.0"?><html>
- <head><title>Yo:Hi! Title: %(count)d</title></head>
- <body>
- <div class="content">Hi! %(count)d<div class="API"><a href="%(foobarLink)s" title="foobar">foobar</a></div></div>
- <a href="%(prefix)sindex.html">Index</a>
- <span class="version">Version: %(version)s</span>
- </body>
- </html>"""
- # Try to normalize irrelevant whitespace.
- return dom.parseString(
- document % {"count": counter, "prefix": prefix,
- "version": version,
- "foobarLink": apiBaseURL % ("foobar",)}).toxml('utf-8')
-
-
- def getArbitraryLoreInput(self, counter):
- """
- Get an arbitrary, unique (for this test case) string of lore input.
-
- @param counter: A counter to include in the input.
- @type counter: C{int}
- """
- template = (
- '<html>'
- '<head><title>Hi! Title: %(count)s</title></head>'
- '<body>'
- 'Hi! %(count)s'
- '<div class="API">foobar</div>'
- '</body>'
- '</html>')
- return template % {"count": counter}
-
-
- def getArbitraryLoreInputAndOutput(self, version, prefix="",
- apiBaseURL="%s"):
- """
- Get an input document along with expected output for lore run on that
- output document, assuming an appropriately-specified C{self.template}.
-
- @param version: A version string to include in the input and output.
- @type version: C{str}
- @param prefix: The prefix to include in the link to the index.
- @type prefix: C{str}
-
- @return: A two-tuple of input and expected output.
- @rtype: C{(str, str)}.
- """
- self.docCounter += 1
- return (self.getArbitraryLoreInput(self.docCounter),
- self.getArbitraryOutput(version, self.docCounter,
- prefix=prefix, apiBaseURL=apiBaseURL))
-
-
- def getArbitraryManInput(self):
- """
- Get an arbitrary man page content.
- """
- return """.TH MANHOLE "1" "August 2001" "" ""
-.SH NAME
-manhole \- Connect to a Twisted Manhole service
-.SH SYNOPSIS
-.B manhole
-.SH DESCRIPTION
-manhole is a GTK interface to Twisted Manhole services. You can execute python
-code as if at an interactive Python console inside a running Twisted process
-with this."""
-
-
- def getArbitraryManLoreOutput(self):
- """
- Get an arbitrary lore input document which represents man-to-lore
- output based on the man page returned from L{getArbitraryManInput}
- """
- return """\
-<?xml version="1.0"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head>
-<title>MANHOLE.1</title></head>
-<body>
-
-<h1>MANHOLE.1</h1>
-
-<h2>NAME</h2>
-
-<p>manhole - Connect to a Twisted Manhole service
-</p>
-
-<h2>SYNOPSIS</h2>
-
-<p><strong>manhole</strong> </p>
-
-<h2>DESCRIPTION</h2>
-
-<p>manhole is a GTK interface to Twisted Manhole services. You can execute python
-code as if at an interactive Python console inside a running Twisted process
-with this.</p>
-
-</body>
-</html>
-"""
-
- def getArbitraryManHTMLOutput(self, version, prefix=""):
- """
- Get an arbitrary lore output document which represents the lore HTML
- output based on the input document returned from
- L{getArbitraryManLoreOutput}.
-
- @param version: A version string to include in the document.
- @type version: C{str}
- @param prefix: The prefix to include in the link to the index.
- @type prefix: C{str}
- """
- # Try to normalize the XML a little bit.
- return dom.parseString("""\
-<?xml version="1.0" ?><html>
- <head><title>Yo:MANHOLE.1</title></head>
- <body>
- <div class="content">
-
-<span/>
-
-<h2>NAME<a name="auto0"/></h2>
-
-<p>manhole - Connect to a Twisted Manhole service
-</p>
-
-<h2>SYNOPSIS<a name="auto1"/></h2>
-
-<p><strong>manhole</strong> </p>
-
-<h2>DESCRIPTION<a name="auto2"/></h2>
-
-<p>manhole is a GTK interface to Twisted Manhole services. You can execute python
-code as if at an interactive Python console inside a running Twisted process
-with this.</p>
-
-</div>
- <a href="%(prefix)sindex.html">Index</a>
- <span class="version">Version: %(version)s</span>
- </body>
- </html>""" % {
- 'prefix': prefix, 'version': version}).toxml("utf-8")
-
-
-
-class DocBuilderTestCase(TestCase, BuilderTestsMixin):
- """
- Tests for L{DocBuilder}.
-
- Note for future maintainers: The exact byte equality assertions throughout
- this suite may need to be updated due to minor differences in lore. They
- should not be taken to mean that Lore must maintain the same byte format
- forever. Feel free to update the tests when Lore changes, but please be
- careful.
- """
- skip = loreSkip
-
- def setUp(self):
- """
- Set up a few instance variables that will be useful.
-
- @ivar builder: A plain L{DocBuilder}.
- @ivar docCounter: An integer to be used as a counter by the
- C{getArbitrary...} methods.
- @ivar howtoDir: A L{FilePath} representing a directory to be used for
- containing Lore documents.
- @ivar templateFile: A L{FilePath} representing a file with
- C{self.template} as its content.
- """
- BuilderTestsMixin.setUp(self)
- self.builder = DocBuilder()
- self.howtoDir = FilePath(self.mktemp())
- self.howtoDir.createDirectory()
- self.templateFile = self.howtoDir.child("template.tpl")
- self.templateFile.setContent(self.template)
-
-
- def test_build(self):
- """
- The L{DocBuilder} runs lore on all .xhtml files within a directory.
- """
- version = "1.2.3"
- input1, output1 = self.getArbitraryLoreInputAndOutput(version)
- input2, output2 = self.getArbitraryLoreInputAndOutput(version)
-
- self.howtoDir.child("one.xhtml").setContent(input1)
- self.howtoDir.child("two.xhtml").setContent(input2)
-
- self.builder.build(version, self.howtoDir, self.howtoDir,
- self.templateFile)
- out1 = self.howtoDir.child('one.html')
- out2 = self.howtoDir.child('two.html')
- self.assertXMLEqual(out1.getContent(), output1)
- self.assertXMLEqual(out2.getContent(), output2)
-
-
- def test_noDocumentsFound(self):
- """
- The C{build} method raises L{NoDocumentsFound} if there are no
- .xhtml files in the given directory.
- """
- self.assertRaises(
- NoDocumentsFound,
- self.builder.build, "1.2.3", self.howtoDir, self.howtoDir,
- self.templateFile)
-
-
- def test_parentDocumentLinking(self):
- """
- The L{DocBuilder} generates correct links from documents to
- template-generated links like stylesheets and index backreferences.
- """
- input = self.getArbitraryLoreInput(0)
- tutoDir = self.howtoDir.child("tutorial")
- tutoDir.createDirectory()
- tutoDir.child("child.xhtml").setContent(input)
- self.builder.build("1.2.3", self.howtoDir, tutoDir, self.templateFile)
- outFile = tutoDir.child('child.html')
- self.assertIn('<a href="../index.html">Index</a>',
- outFile.getContent())
-
-
- def test_siblingDirectoryDocumentLinking(self):
- """
- It is necessary to generate documentation in a directory foo/bar where
- stylesheet and indexes are located in foo/baz. Such resources should be
- appropriately linked to.
- """
- input = self.getArbitraryLoreInput(0)
- resourceDir = self.howtoDir.child("resources")
- docDir = self.howtoDir.child("docs")
- docDir.createDirectory()
- docDir.child("child.xhtml").setContent(input)
- self.builder.build("1.2.3", resourceDir, docDir, self.templateFile)
- outFile = docDir.child('child.html')
- self.assertIn('<a href="../resources/index.html">Index</a>',
- outFile.getContent())
-
-
- def test_apiLinking(self):
- """
- The L{DocBuilder} generates correct links from documents to API
- documentation.
- """
- version = "1.2.3"
- input, output = self.getArbitraryLoreInputAndOutput(version)
- self.howtoDir.child("one.xhtml").setContent(input)
-
- self.builder.build(version, self.howtoDir, self.howtoDir,
- self.templateFile, "scheme:apilinks/%s.ext")
- out = self.howtoDir.child('one.html')
- self.assertIn(
- '<a href="scheme:apilinks/foobar.ext" title="foobar">foobar</a>',
- out.getContent())
-
-
- def test_deleteInput(self):
- """
- L{DocBuilder.build} can be instructed to delete the input files after
- generating the output based on them.
- """
- input1 = self.getArbitraryLoreInput(0)
- self.howtoDir.child("one.xhtml").setContent(input1)
- self.builder.build("whatever", self.howtoDir, self.howtoDir,
- self.templateFile, deleteInput=True)
- self.assertTrue(self.howtoDir.child('one.html').exists())
- self.assertFalse(self.howtoDir.child('one.xhtml').exists())
-
-
- def test_doNotDeleteInput(self):
- """
- Input will not be deleted by default.
- """
- input1 = self.getArbitraryLoreInput(0)
- self.howtoDir.child("one.xhtml").setContent(input1)
- self.builder.build("whatever", self.howtoDir, self.howtoDir,
- self.templateFile)
- self.assertTrue(self.howtoDir.child('one.html').exists())
- self.assertTrue(self.howtoDir.child('one.xhtml').exists())
-
-
- def test_getLinkrelToSameDirectory(self):
- """
- If the doc and resource directories are the same, the linkrel should be
- an empty string.
- """
- linkrel = self.builder.getLinkrel(FilePath("/foo/bar"),
- FilePath("/foo/bar"))
- self.assertEqual(linkrel, "")
-
-
- def test_getLinkrelToParentDirectory(self):
- """
- If the doc directory is a child of the resource directory, the linkrel
- should make use of '..'.
- """
- linkrel = self.builder.getLinkrel(FilePath("/foo"),
- FilePath("/foo/bar"))
- self.assertEqual(linkrel, "../")
-
-
- def test_getLinkrelToSibling(self):
- """
- If the doc directory is a sibling of the resource directory, the
- linkrel should make use of '..' and a named segment.
- """
- linkrel = self.builder.getLinkrel(FilePath("/foo/howto"),
- FilePath("/foo/examples"))
- self.assertEqual(linkrel, "../howto/")
-
-
- def test_getLinkrelToUncle(self):
- """
- If the doc directory is a sibling of the parent of the resource
- directory, the linkrel should make use of multiple '..'s and a named
- segment.
- """
- linkrel = self.builder.getLinkrel(FilePath("/foo/howto"),
- FilePath("/foo/examples/quotes"))
- self.assertEqual(linkrel, "../../howto/")
-
-
-
-class APIBuilderTestCase(TestCase):
- """
- Tests for L{APIBuilder}.
- """
- skip = pydoctorSkip
-
- def test_build(self):
- """
- L{APIBuilder.build} writes an index file which includes the name of the
- project specified.
- """
- stdout = StringIO()
- self.patch(sys, 'stdout', stdout)
-
- projectName = "Foobar"
- packageName = "quux"
- projectURL = "scheme:project"
- sourceURL = "scheme:source"
- docstring = "text in docstring"
- privateDocstring = "should also appear in output"
-
- inputPath = FilePath(self.mktemp()).child(packageName)
- inputPath.makedirs()
- inputPath.child("__init__.py").setContent(
- "def foo():\n"
- " '%s'\n"
- "def _bar():\n"
- " '%s'" % (docstring, privateDocstring))
-
- outputPath = FilePath(self.mktemp())
- outputPath.makedirs()
-
- builder = APIBuilder()
- builder.build(projectName, projectURL, sourceURL, inputPath, outputPath)
-
- indexPath = outputPath.child("index.html")
- self.assertTrue(
- indexPath.exists(),
- "API index %r did not exist." % (outputPath.path,))
- self.assertIn(
- '<a href="%s">%s</a>' % (projectURL, projectName),
- indexPath.getContent(),
- "Project name/location not in file contents.")
-
- quuxPath = outputPath.child("quux.html")
- self.assertTrue(
- quuxPath.exists(),
- "Package documentation file %r did not exist." % (quuxPath.path,))
- self.assertIn(
- docstring, quuxPath.getContent(),
- "Docstring not in package documentation file.")
- self.assertIn(
- '<a href="%s/%s">View Source</a>' % (sourceURL, packageName),
- quuxPath.getContent())
- self.assertIn(
- '<a href="%s/%s/__init__.py#L1" class="functionSourceLink">' % (
- sourceURL, packageName),
- quuxPath.getContent())
- self.assertIn(privateDocstring, quuxPath.getContent())
-
- # There should also be a page for the foo function in quux.
- self.assertTrue(quuxPath.sibling('quux.foo.html').exists())
-
- self.assertEqual(stdout.getvalue(), '')
-
-
- def test_buildWithPolicy(self):
- """
- L{BuildAPIDocsScript.buildAPIDocs} builds the API docs with values
- appropriate for the Twisted project.
- """
- stdout = StringIO()
- self.patch(sys, 'stdout', stdout)
- docstring = "text in docstring"
-
- projectRoot = FilePath(self.mktemp())
- packagePath = projectRoot.child("twisted")
- packagePath.makedirs()
- packagePath.child("__init__.py").setContent(
- "def foo():\n"
- " '%s'\n" % (docstring,))
- packagePath.child("_version.py").setContent(
- genVersion("twisted", 1, 0, 0))
- outputPath = FilePath(self.mktemp())
-
- script = BuildAPIDocsScript()
- script.buildAPIDocs(projectRoot, outputPath)
-
- indexPath = outputPath.child("index.html")
- self.assertTrue(
- indexPath.exists(),
- "API index %r did not exist." % (outputPath.path,))
- self.assertIn(
- '<a href="http://twistedmatrix.com/">Twisted</a>',
- indexPath.getContent(),
- "Project name/location not in file contents.")
-
- twistedPath = outputPath.child("twisted.html")
- self.assertTrue(
- twistedPath.exists(),
- "Package documentation file %r did not exist."
- % (twistedPath.path,))
- self.assertIn(
- docstring, twistedPath.getContent(),
- "Docstring not in package documentation file.")
- #Here we check that it figured out the correct version based on the
- #source code.
- self.assertIn(
- '<a href="http://twistedmatrix.com/trac/browser/tags/releases/'
- 'twisted-1.0.0/twisted">View Source</a>',
- twistedPath.getContent())
-
- self.assertEqual(stdout.getvalue(), '')
-
-
- def test_apiBuilderScriptMainRequiresTwoArguments(self):
- """
- SystemExit is raised when the incorrect number of command line
- arguments are passed to the API building script.
- """
- script = BuildAPIDocsScript()
- self.assertRaises(SystemExit, script.main, [])
- self.assertRaises(SystemExit, script.main, ["foo"])
- self.assertRaises(SystemExit, script.main, ["foo", "bar", "baz"])
-
-
- def test_apiBuilderScriptMain(self):
- """
- The API building script invokes the same code that
- L{test_buildWithPolicy} tests.
- """
- script = BuildAPIDocsScript()
- calls = []
- script.buildAPIDocs = lambda a, b: calls.append((a, b))
- script.main(["hello", "there"])
- self.assertEqual(calls, [(FilePath("hello"), FilePath("there"))])
-
-
-
-class ManBuilderTestCase(TestCase, BuilderTestsMixin):
- """
- Tests for L{ManBuilder}.
- """
- skip = loreSkip
-
- def setUp(self):
- """
- Set up a few instance variables that will be useful.
-
- @ivar builder: A plain L{ManBuilder}.
- @ivar manDir: A L{FilePath} representing a directory to be used for
- containing man pages.
- """
- BuilderTestsMixin.setUp(self)
- self.builder = ManBuilder()
- self.manDir = FilePath(self.mktemp())
- self.manDir.createDirectory()
-
-
- def test_noDocumentsFound(self):
- """
- L{ManBuilder.build} raises L{NoDocumentsFound} if there are no
- .1 files in the given directory.
- """
- self.assertRaises(NoDocumentsFound, self.builder.build, self.manDir)
-
-
- def test_build(self):
- """
- Check that L{ManBuilder.build} find the man page in the directory, and
- successfully produce a Lore content.
- """
- manContent = self.getArbitraryManInput()
- self.manDir.child('test1.1').setContent(manContent)
- self.builder.build(self.manDir)
- output = self.manDir.child('test1-man.xhtml').getContent()
- expected = self.getArbitraryManLoreOutput()
- # No-op on *nix, fix for windows
- expected = expected.replace('\n', os.linesep)
- self.assertEqual(output, expected)
-
-
- def test_toHTML(self):
- """
- Check that the content output by C{build} is compatible as input of
- L{DocBuilder.build}.
- """
- manContent = self.getArbitraryManInput()
- self.manDir.child('test1.1').setContent(manContent)
- self.builder.build(self.manDir)
-
- templateFile = self.manDir.child("template.tpl")
- templateFile.setContent(DocBuilderTestCase.template)
- docBuilder = DocBuilder()
- docBuilder.build("1.2.3", self.manDir, self.manDir,
- templateFile)
- output = self.manDir.child('test1-man.html').getContent()
-
- self.assertXMLEqual(
- output,
- """\
-<?xml version="1.0" ?><html>
- <head><title>Yo:MANHOLE.1</title></head>
- <body>
- <div class="content">
-
-<span/>
-
-<h2>NAME<a name="auto0"/></h2>
-
-<p>manhole - Connect to a Twisted Manhole service
-</p>
-
-<h2>SYNOPSIS<a name="auto1"/></h2>
-
-<p><strong>manhole</strong> </p>
-
-<h2>DESCRIPTION<a name="auto2"/></h2>
-
-<p>manhole is a GTK interface to Twisted Manhole services. You can execute python
-code as if at an interactive Python console inside a running Twisted process
-with this.</p>
-
-</div>
- <a href="index.html">Index</a>
- <span class="version">Version: 1.2.3</span>
- </body>
- </html>""")
-
-
-
-class BookBuilderTests(TestCase, BuilderTestsMixin):
- """
- Tests for L{BookBuilder}.
- """
- skip = latexSkip or loreSkip
-
- def setUp(self):
- """
- Make a directory into which to place temporary files.
- """
- self.docCounter = 0
- self.howtoDir = FilePath(self.mktemp())
- self.howtoDir.makedirs()
- self.oldHandler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
-
-
- def tearDown(self):
- signal.signal(signal.SIGCHLD, self.oldHandler)
-
-
- def getArbitraryOutput(self, version, counter, prefix="", apiBaseURL=None):
- """
- Create and return a C{str} containing the LaTeX document which is
- expected as the output for processing the result of the document
- returned by C{self.getArbitraryLoreInput(counter)}.
- """
- path = self.howtoDir.child("%d.xhtml" % (counter,)).path
- return (
- r'\section{Hi! Title: %(count)s\label{%(path)s}}'
- '\n'
- r'Hi! %(count)sfoobar') % {'count': counter, 'path': path}
-
-
- def test_runSuccess(self):
- """
- L{BookBuilder.run} executes the command it is passed and returns a
- string giving the stdout and stderr of the command if it completes
- successfully.
- """
- builder = BookBuilder()
- self.assertEqual(
- builder.run([
- sys.executable, '-c',
- 'import sys; '
- 'sys.stdout.write("hi\\n"); '
- 'sys.stdout.flush(); '
- 'sys.stderr.write("bye\\n"); '
- 'sys.stderr.flush()']),
- "hi\nbye\n")
-
-
- def test_runFailed(self):
- """
- L{BookBuilder.run} executes the command it is passed and raises
- L{CommandFailed} if it completes unsuccessfully.
- """
- builder = BookBuilder()
- exc = self.assertRaises(
- CommandFailed, builder.run,
- [sys.executable, '-c', 'print "hi"; raise SystemExit(1)'])
- self.assertEqual(exc.exitStatus, 1)
- self.assertEqual(exc.exitSignal, None)
- self.assertEqual(exc.output, "hi\n")
-
-
- def test_runSignaled(self):
- """
- L{BookBuilder.run} executes the command it is passed and raises
- L{CommandFailed} if it exits due to a signal.
- """
- builder = BookBuilder()
- exc = self.assertRaises(
- CommandFailed, builder.run,
- [sys.executable, '-c',
- 'import sys; print "hi"; sys.stdout.flush(); '
- 'import os; os.kill(os.getpid(), 9)'])
- self.assertEqual(exc.exitSignal, 9)
- self.assertEqual(exc.exitStatus, None)
- self.assertEqual(exc.output, "hi\n")
-
-
- def test_buildTeX(self):
- """
- L{BookBuilder.buildTeX} writes intermediate TeX files for all lore
- input files in a directory.
- """
- version = "3.2.1"
- input1, output1 = self.getArbitraryLoreInputAndOutput(version)
- input2, output2 = self.getArbitraryLoreInputAndOutput(version)
-
- # Filenames are chosen by getArbitraryOutput to match the counter used
- # by getArbitraryLoreInputAndOutput.
- self.howtoDir.child("1.xhtml").setContent(input1)
- self.howtoDir.child("2.xhtml").setContent(input2)
-
- builder = BookBuilder()
- builder.buildTeX(self.howtoDir)
- self.assertEqual(self.howtoDir.child("1.tex").getContent(), output1)
- self.assertEqual(self.howtoDir.child("2.tex").getContent(), output2)
-
-
- def test_buildTeXRejectsInvalidDirectory(self):
- """
- L{BookBuilder.buildTeX} raises L{ValueError} if passed a directory
- which does not exist.
- """
- builder = BookBuilder()
- self.assertRaises(
- ValueError, builder.buildTeX, self.howtoDir.temporarySibling())
-
-
- def test_buildTeXOnlyBuildsXHTML(self):
- """
- L{BookBuilder.buildTeX} ignores files which which don't end with
- ".xhtml".
- """
- # Hopefully ">" is always a parse error from microdom!
- self.howtoDir.child("not-input.dat").setContent(">")
- self.test_buildTeX()
-
-
- def test_stdout(self):
- """
- L{BookBuilder.buildTeX} does not write to stdout.
- """
- stdout = StringIO()
- self.patch(sys, 'stdout', stdout)
-
- # Suppress warnings so that if there are any old-style plugins that
- # lore queries for don't confuse the assertion below. See #3070.
- self.patch(warnings, 'warn', lambda *a, **kw: None)
- self.test_buildTeX()
- self.assertEqual(stdout.getvalue(), '')
-
-
- def test_buildPDFRejectsInvalidBookFilename(self):
- """
- L{BookBuilder.buildPDF} raises L{ValueError} if the book filename does
- not end with ".tex".
- """
- builder = BookBuilder()
- self.assertRaises(
- ValueError,
- builder.buildPDF,
- FilePath(self.mktemp()).child("foo"),
- None,
- None)
-
-
- def _setupTeXFiles(self):
- sections = range(3)
- self._setupTeXSections(sections)
- return self._setupTeXBook(sections)
-
-
- def _setupTeXSections(self, sections):
- for texSectionNumber in sections:
- texPath = self.howtoDir.child("%d.tex" % (texSectionNumber,))
- texPath.setContent(self.getArbitraryOutput(
- "1.2.3", texSectionNumber))
-
-
- def _setupTeXBook(self, sections):
- bookTeX = self.howtoDir.child("book.tex")
- bookTeX.setContent(
- r"\documentclass{book}" "\n"
- r"\begin{document}" "\n" +
- "\n".join([r"\input{%d.tex}" % (n,) for n in sections]) +
- r"\end{document}" "\n")
- return bookTeX
-
-
- def test_buildPDF(self):
- """
- L{BookBuilder.buildPDF} creates a PDF given an index tex file and a
- directory containing .tex files.
- """
- bookPath = self._setupTeXFiles()
- outputPath = FilePath(self.mktemp())
-
- builder = BookBuilder()
- builder.buildPDF(bookPath, self.howtoDir, outputPath)
-
- self.assertTrue(outputPath.exists())
-
-
- def test_buildPDFLongPath(self):
- """
- L{BookBuilder.buildPDF} succeeds even if the paths it is operating on
- are very long.
-
- C{ps2pdf13} seems to have problems when path names are long. This test
- verifies that even if inputs have long paths, generation still
- succeeds.
- """
- # Make it long.
- self.howtoDir = self.howtoDir.child("x" * 128).child("x" * 128).child("x" * 128)
- self.howtoDir.makedirs()
-
- # This will use the above long path.
- bookPath = self._setupTeXFiles()
- outputPath = FilePath(self.mktemp())
-
- builder = BookBuilder()
- builder.buildPDF(bookPath, self.howtoDir, outputPath)
-
- self.assertTrue(outputPath.exists())
-
-
- def test_buildPDFRunsLaTeXThreeTimes(self):
- """
- L{BookBuilder.buildPDF} runs C{latex} three times.
- """
- class InspectableBookBuilder(BookBuilder):
- def __init__(self):
- BookBuilder.__init__(self)
- self.commands = []
-
- def run(self, command):
- """
- Record the command and then execute it.
- """
- self.commands.append(command)
- return BookBuilder.run(self, command)
-
- bookPath = self._setupTeXFiles()
- outputPath = FilePath(self.mktemp())
-
- builder = InspectableBookBuilder()
- builder.buildPDF(bookPath, self.howtoDir, outputPath)
-
- # These string comparisons are very fragile. It would be better to
- # have a test which asserted the correctness of the contents of the
- # output files. I don't know how one could do that, though. -exarkun
- latex1, latex2, latex3, dvips, ps2pdf13 = builder.commands
- self.assertEqual(latex1, latex2)
- self.assertEqual(latex2, latex3)
- self.assertEqual(
- latex1[:1], ["latex"],
- "LaTeX command %r does not seem right." % (latex1,))
- self.assertEqual(
- latex1[-1:], [bookPath.path],
- "LaTeX command %r does not end with the book path (%r)." % (
- latex1, bookPath.path))
-
- self.assertEqual(
- dvips[:1], ["dvips"],
- "dvips command %r does not seem right." % (dvips,))
- self.assertEqual(
- ps2pdf13[:1], ["ps2pdf13"],
- "ps2pdf13 command %r does not seem right." % (ps2pdf13,))
-
-
- def test_noSideEffects(self):
- """
- The working directory is the same before and after a call to
- L{BookBuilder.buildPDF}. Also the contents of the directory containing
- the input book are the same before and after the call.
- """
- startDir = os.getcwd()
- bookTeX = self._setupTeXFiles()
- startTeXSiblings = bookTeX.parent().children()
- startHowtoChildren = self.howtoDir.children()
-
- builder = BookBuilder()
- builder.buildPDF(bookTeX, self.howtoDir, FilePath(self.mktemp()))
-
- self.assertEqual(startDir, os.getcwd())
- self.assertEqual(startTeXSiblings, bookTeX.parent().children())
- self.assertEqual(startHowtoChildren, self.howtoDir.children())
-
-
- def test_failedCommandProvidesOutput(self):
- """
- If a subprocess fails, L{BookBuilder.buildPDF} raises L{CommandFailed}
- with the subprocess's output and leaves the temporary directory as a
- sibling of the book path.
- """
- bookTeX = FilePath(self.mktemp() + ".tex")
- builder = BookBuilder()
- inputState = bookTeX.parent().children()
- exc = self.assertRaises(
- CommandFailed,
- builder.buildPDF,
- bookTeX, self.howtoDir, FilePath(self.mktemp()))
- self.assertTrue(exc.output)
- newOutputState = set(bookTeX.parent().children()) - set(inputState)
- self.assertEqual(len(newOutputState), 1)
- workPath = newOutputState.pop()
- self.assertTrue(
- workPath.isdir(),
- "Expected work path %r was not a directory." % (workPath.path,))
-
-
- def test_build(self):
- """
- L{BookBuilder.build} generates a pdf book file from some lore input
- files.
- """
- sections = range(1, 4)
- for sectionNumber in sections:
- self.howtoDir.child("%d.xhtml" % (sectionNumber,)).setContent(
- self.getArbitraryLoreInput(sectionNumber))
- bookTeX = self._setupTeXBook(sections)
- bookPDF = FilePath(self.mktemp())
-
- builder = BookBuilder()
- builder.build(self.howtoDir, [self.howtoDir], bookTeX, bookPDF)
-
- self.assertTrue(bookPDF.exists())
-
-
- def test_buildRemovesTemporaryLaTeXFiles(self):
- """
- L{BookBuilder.build} removes the intermediate LaTeX files it creates.
- """
- sections = range(1, 4)
- for sectionNumber in sections:
- self.howtoDir.child("%d.xhtml" % (sectionNumber,)).setContent(
- self.getArbitraryLoreInput(sectionNumber))
- bookTeX = self._setupTeXBook(sections)
- bookPDF = FilePath(self.mktemp())
-
- builder = BookBuilder()
- builder.build(self.howtoDir, [self.howtoDir], bookTeX, bookPDF)
-
- self.assertEqual(
- set(self.howtoDir.listdir()),
- set([bookTeX.basename()] + ["%d.xhtml" % (n,) for n in sections]))
-
-
-
-class FilePathDeltaTest(TestCase):
- """
- Tests for L{filePathDelta}.
- """
-
- def test_filePathDeltaSubdir(self):
- """
- L{filePathDelta} can create a simple relative path to a child path.
- """
- self.assertEqual(filePathDelta(FilePath("/foo/bar"),
- FilePath("/foo/bar/baz")),
- ["baz"])
-
-
- def test_filePathDeltaSiblingDir(self):
- """
- L{filePathDelta} can traverse upwards to create relative paths to
- siblings.
- """
- self.assertEqual(filePathDelta(FilePath("/foo/bar"),
- FilePath("/foo/baz")),
- ["..", "baz"])
-
-
- def test_filePathNoCommonElements(self):
- """
- L{filePathDelta} can create relative paths to totally unrelated paths
- for maximum portability.
- """
- self.assertEqual(filePathDelta(FilePath("/foo/bar"),
- FilePath("/baz/quux")),
- ["..", "..", "baz", "quux"])
-
-
- def test_filePathDeltaSimilarEndElements(self):
- """
- L{filePathDelta} doesn't take into account final elements when
- comparing 2 paths, but stops at the first difference.
- """
- self.assertEqual(filePathDelta(FilePath("/foo/bar/bar/spam"),
- FilePath("/foo/bar/baz/spam")),
- ["..", "..", "baz", "spam"])
-
-
-
-class NewsBuilderTests(TestCase, StructureAssertingMixin):
- """
- Tests for L{NewsBuilder}.
- """
- def setUp(self):
- """
- Create a fake project and stuff some basic structure and content into
- it.
- """
- self.builder = NewsBuilder()
- self.project = FilePath(self.mktemp())
- self.project.createDirectory()
- self.existingText = 'Here is stuff which was present previously.\n'
- self.createStructure(self.project, {
- 'NEWS': self.existingText,
- '5.feature': 'We now support the web.\n',
- '12.feature': 'The widget is more robust.\n',
- '15.feature': (
- 'A very long feature which takes many words to '
- 'describe with any accuracy was introduced so that '
- 'the line wrapping behavior of the news generating '
- 'code could be verified.\n'),
- '16.feature': (
- 'A simpler feature\ndescribed on multiple lines\n'
- 'was added.\n'),
- '23.bugfix': 'Broken stuff was fixed.\n',
- '25.removal': 'Stupid stuff was deprecated.\n',
- '30.misc': '',
- '35.misc': '',
- '40.doc': 'foo.bar.Baz.quux',
- '41.doc': 'writing Foo servers'})
-
-
- def test_today(self):
- """
- L{NewsBuilder._today} returns today's date in YYYY-MM-DD form.
- """
- self.assertEqual(
- self.builder._today(), date.today().strftime('%Y-%m-%d'))
-
-
- def test_findFeatures(self):
- """
- When called with L{NewsBuilder._FEATURE}, L{NewsBuilder._findChanges}
- returns a list of bugfix ticket numbers and descriptions as a list of
- two-tuples.
- """
- features = self.builder._findChanges(
- self.project, self.builder._FEATURE)
- self.assertEqual(
- features,
- [(5, "We now support the web."),
- (12, "The widget is more robust."),
- (15,
- "A very long feature which takes many words to describe with "
- "any accuracy was introduced so that the line wrapping behavior "
- "of the news generating code could be verified."),
- (16, "A simpler feature described on multiple lines was added.")])
-
-
- def test_findBugfixes(self):
- """
- When called with L{NewsBuilder._BUGFIX}, L{NewsBuilder._findChanges}
- returns a list of bugfix ticket numbers and descriptions as a list of
- two-tuples.
- """
- bugfixes = self.builder._findChanges(
- self.project, self.builder._BUGFIX)
- self.assertEqual(
- bugfixes,
- [(23, 'Broken stuff was fixed.')])
-
-
- def test_findRemovals(self):
- """
- When called with L{NewsBuilder._REMOVAL}, L{NewsBuilder._findChanges}
- returns a list of removal/deprecation ticket numbers and descriptions
- as a list of two-tuples.
- """
- removals = self.builder._findChanges(
- self.project, self.builder._REMOVAL)
- self.assertEqual(
- removals,
- [(25, 'Stupid stuff was deprecated.')])
-
-
- def test_findDocumentation(self):
- """
- When called with L{NewsBuilder._DOC}, L{NewsBuilder._findChanges}
- returns a list of documentation ticket numbers and descriptions as a
- list of two-tuples.
- """
- doc = self.builder._findChanges(
- self.project, self.builder._DOC)
- self.assertEqual(
- doc,
- [(40, 'foo.bar.Baz.quux'),
- (41, 'writing Foo servers')])
-
-
- def test_findMiscellaneous(self):
- """
- When called with L{NewsBuilder._MISC}, L{NewsBuilder._findChanges}
- returns a list of removal/deprecation ticket numbers and descriptions
- as a list of two-tuples.
- """
- misc = self.builder._findChanges(
- self.project, self.builder._MISC)
- self.assertEqual(
- misc,
- [(30, ''),
- (35, '')])
-
-
- def test_writeHeader(self):
- """
- L{NewsBuilder._writeHeader} accepts a file-like object opened for
- writing and a header string and writes out a news file header to it.
- """
- output = StringIO()
- self.builder._writeHeader(output, "Super Awesometastic 32.16")
- self.assertEqual(
- output.getvalue(),
- "Super Awesometastic 32.16\n"
- "=========================\n"
- "\n")
-
-
- def test_writeSection(self):
- """
- L{NewsBuilder._writeSection} accepts a file-like object opened for
- writing, a section name, and a list of ticket information (as returned
- by L{NewsBuilder._findChanges}) and writes out a section header and all
- of the given ticket information.
- """
- output = StringIO()
- self.builder._writeSection(
- output, "Features",
- [(3, "Great stuff."),
- (17, "Very long line which goes on and on and on, seemingly "
- "without end until suddenly without warning it does end.")])
- self.assertEqual(
- output.getvalue(),
- "Features\n"
- "--------\n"
- " - Great stuff. (#3)\n"
- " - Very long line which goes on and on and on, seemingly without end\n"
- " until suddenly without warning it does end. (#17)\n"
- "\n")
-
-
- def test_writeMisc(self):
- """
- L{NewsBuilder._writeMisc} accepts a file-like object opened for
- writing, a section name, and a list of ticket information (as returned
- by L{NewsBuilder._findChanges} and writes out a section header and all
- of the ticket numbers, but excludes any descriptions.
- """
- output = StringIO()
- self.builder._writeMisc(
- output, "Other",
- [(x, "") for x in range(2, 50, 3)])
- self.assertEqual(
- output.getvalue(),
- "Other\n"
- "-----\n"
- " - #2, #5, #8, #11, #14, #17, #20, #23, #26, #29, #32, #35, #38, #41,\n"
- " #44, #47\n"
- "\n")
-
-
- def test_build(self):
- """
- L{NewsBuilder.build} updates a NEWS file with new features based on the
- I{<ticket>.feature} files found in the directory specified.
- """
- self.builder.build(
- self.project, self.project.child('NEWS'),
- "Super Awesometastic 32.16")
-
- results = self.project.child('NEWS').getContent()
- self.assertEqual(
- results,
- 'Super Awesometastic 32.16\n'
- '=========================\n'
- '\n'
- 'Features\n'
- '--------\n'
- ' - We now support the web. (#5)\n'
- ' - The widget is more robust. (#12)\n'
- ' - A very long feature which takes many words to describe with any\n'
- ' accuracy was introduced so that the line wrapping behavior of the\n'
- ' news generating code could be verified. (#15)\n'
- ' - A simpler feature described on multiple lines was added. (#16)\n'
- '\n'
- 'Bugfixes\n'
- '--------\n'
- ' - Broken stuff was fixed. (#23)\n'
- '\n'
- 'Improved Documentation\n'
- '----------------------\n'
- ' - foo.bar.Baz.quux (#40)\n'
- ' - writing Foo servers (#41)\n'
- '\n'
- 'Deprecations and Removals\n'
- '-------------------------\n'
- ' - Stupid stuff was deprecated. (#25)\n'
- '\n'
- 'Other\n'
- '-----\n'
- ' - #30, #35\n'
- '\n\n' + self.existingText)
-
-
- def test_emptyProjectCalledOut(self):
- """
- If no changes exist for a project, I{NEWS} gains a new section for
- that project that includes some helpful text about how there were no
- interesting changes.
- """
- project = FilePath(self.mktemp()).child("twisted")
- project.makedirs()
- self.createStructure(project, {
- 'NEWS': self.existingText })
-
- self.builder.build(
- project, project.child('NEWS'),
- "Super Awesometastic 32.16")
- results = project.child('NEWS').getContent()
- self.assertEqual(
- results,
- 'Super Awesometastic 32.16\n'
- '=========================\n'
- '\n' +
- self.builder._NO_CHANGES +
- '\n\n' + self.existingText)
-
-
- def test_preserveTicketHint(self):
- """
- If a I{NEWS} file begins with the two magic lines which point readers
- at the issue tracker, those lines are kept at the top of the new file.
- """
- news = self.project.child('NEWS')
- news.setContent(
- 'Ticket numbers in this file can be looked up by visiting\n'
- 'http://twistedmatrix.com/trac/ticket/<number>\n'
- '\n'
- 'Blah blah other stuff.\n')
-
- self.builder.build(self.project, news, "Super Awesometastic 32.16")
-
- self.assertEqual(
- news.getContent(),
- 'Ticket numbers in this file can be looked up by visiting\n'
- 'http://twistedmatrix.com/trac/ticket/<number>\n'
- '\n'
- 'Super Awesometastic 32.16\n'
- '=========================\n'
- '\n'
- 'Features\n'
- '--------\n'
- ' - We now support the web. (#5)\n'
- ' - The widget is more robust. (#12)\n'
- ' - A very long feature which takes many words to describe with any\n'
- ' accuracy was introduced so that the line wrapping behavior of the\n'
- ' news generating code could be verified. (#15)\n'
- ' - A simpler feature described on multiple lines was added. (#16)\n'
- '\n'
- 'Bugfixes\n'
- '--------\n'
- ' - Broken stuff was fixed. (#23)\n'
- '\n'
- 'Improved Documentation\n'
- '----------------------\n'
- ' - foo.bar.Baz.quux (#40)\n'
- ' - writing Foo servers (#41)\n'
- '\n'
- 'Deprecations and Removals\n'
- '-------------------------\n'
- ' - Stupid stuff was deprecated. (#25)\n'
- '\n'
- 'Other\n'
- '-----\n'
- ' - #30, #35\n'
- '\n\n'
- 'Blah blah other stuff.\n')
-
-
- def test_emptySectionsOmitted(self):
- """
- If there are no changes of a particular type (feature, bugfix, etc), no
- section for that type is written by L{NewsBuilder.build}.
- """
- for ticket in self.project.children():
- if ticket.splitext()[1] in ('.feature', '.misc', '.doc'):
- ticket.remove()
-
- self.builder.build(
- self.project, self.project.child('NEWS'),
- 'Some Thing 1.2')
-
- self.assertEqual(
- self.project.child('NEWS').getContent(),
- 'Some Thing 1.2\n'
- '==============\n'
- '\n'
- 'Bugfixes\n'
- '--------\n'
- ' - Broken stuff was fixed. (#23)\n'
- '\n'
- 'Deprecations and Removals\n'
- '-------------------------\n'
- ' - Stupid stuff was deprecated. (#25)\n'
- '\n\n'
- 'Here is stuff which was present previously.\n')
-
-
- def test_duplicatesMerged(self):
- """
- If two change files have the same contents, they are merged in the
- generated news entry.
- """
- def feature(s):
- return self.project.child(s + '.feature')
- feature('5').copyTo(feature('15'))
- feature('5').copyTo(feature('16'))
-
- self.builder.build(
- self.project, self.project.child('NEWS'),
- 'Project Name 5.0')
-
- self.assertEqual(
- self.project.child('NEWS').getContent(),
- 'Project Name 5.0\n'
- '================\n'
- '\n'
- 'Features\n'
- '--------\n'
- ' - We now support the web. (#5, #15, #16)\n'
- ' - The widget is more robust. (#12)\n'
- '\n'
- 'Bugfixes\n'
- '--------\n'
- ' - Broken stuff was fixed. (#23)\n'
- '\n'
- 'Improved Documentation\n'
- '----------------------\n'
- ' - foo.bar.Baz.quux (#40)\n'
- ' - writing Foo servers (#41)\n'
- '\n'
- 'Deprecations and Removals\n'
- '-------------------------\n'
- ' - Stupid stuff was deprecated. (#25)\n'
- '\n'
- 'Other\n'
- '-----\n'
- ' - #30, #35\n'
- '\n\n'
- 'Here is stuff which was present previously.\n')
-
-
- def createFakeTwistedProject(self):
- """
- Create a fake-looking Twisted project to build from.
- """
- project = FilePath(self.mktemp()).child("twisted")
- project.makedirs()
- self.createStructure(project, {
- 'NEWS': 'Old boring stuff from the past.\n',
- '_version.py': genVersion("twisted", 1, 2, 3),
- 'topfiles': {
- 'NEWS': 'Old core news.\n',
- '3.feature': 'Third feature addition.\n',
- '5.misc': ''},
- 'conch': {
- '_version.py': genVersion("twisted.conch", 3, 4, 5),
- 'topfiles': {
- 'NEWS': 'Old conch news.\n',
- '7.bugfix': 'Fixed that bug.\n'}},
- })
- return project
-
-
- def test_buildAll(self):
- """
- L{NewsBuilder.buildAll} calls L{NewsBuilder.build} once for each
- subproject, passing that subproject's I{topfiles} directory as C{path},
- the I{NEWS} file in that directory as C{output}, and the subproject's
- name as C{header}, and then again for each subproject with the
- top-level I{NEWS} file for C{output}. Blacklisted subprojects are
- skipped.
- """
- builds = []
- builder = NewsBuilder()
- builder.build = lambda path, output, header: builds.append((
- path, output, header))
- builder._today = lambda: '2009-12-01'
-
- project = self.createFakeTwistedProject()
- builder.buildAll(project)
-
- coreTopfiles = project.child("topfiles")
- coreNews = coreTopfiles.child("NEWS")
- coreHeader = "Twisted Core 1.2.3 (2009-12-01)"
-
- conchTopfiles = project.child("conch").child("topfiles")
- conchNews = conchTopfiles.child("NEWS")
- conchHeader = "Twisted Conch 3.4.5 (2009-12-01)"
-
- aggregateNews = project.child("NEWS")
-
- self.assertEqual(
- builds,
- [(conchTopfiles, conchNews, conchHeader),
- (coreTopfiles, coreNews, coreHeader),
- (conchTopfiles, aggregateNews, conchHeader),
- (coreTopfiles, aggregateNews, coreHeader)])
-
-
- def test_changeVersionInNews(self):
- """
- L{NewsBuilder._changeVersions} gets the release date for a given
- version of a project as a string.
- """
- builder = NewsBuilder()
- builder._today = lambda: '2009-12-01'
- project = self.createFakeTwistedProject()
- builder.buildAll(project)
- newVersion = Version('TEMPLATE', 7, 7, 14)
- coreNews = project.child('topfiles').child('NEWS')
- # twisted 1.2.3 is the old version.
- builder._changeNewsVersion(
- coreNews, "Core", Version("twisted", 1, 2, 3),
- newVersion, '2010-01-01')
- expectedCore = (
- 'Twisted Core 7.7.14 (2010-01-01)\n'
- '================================\n'
- '\n'
- 'Features\n'
- '--------\n'
- ' - Third feature addition. (#3)\n'
- '\n'
- 'Other\n'
- '-----\n'
- ' - #5\n\n\n')
- self.assertEqual(
- expectedCore + 'Old core news.\n', coreNews.getContent())
-
-
-
-class DistributionBuilderTestBase(BuilderTestsMixin, StructureAssertingMixin,
- TestCase):
- """
- Base for tests of L{DistributionBuilder}.
- """
- skip = loreSkip
-
- def setUp(self):
- BuilderTestsMixin.setUp(self)
-
- self.rootDir = FilePath(self.mktemp())
- self.rootDir.createDirectory()
-
- self.outputDir = FilePath(self.mktemp())
- self.outputDir.createDirectory()
- self.builder = DistributionBuilder(self.rootDir, self.outputDir)
-
-
-
-class DistributionBuilderTest(DistributionBuilderTestBase):
-
- def test_twistedDistribution(self):
- """
- The Twisted tarball contains everything in the source checkout, with
- built documentation.
- """
- loreInput, loreOutput = self.getArbitraryLoreInputAndOutput("10.0.0")
- manInput1 = self.getArbitraryManInput()
- manOutput1 = self.getArbitraryManHTMLOutput("10.0.0", "../howto/")
- manInput2 = self.getArbitraryManInput()
- manOutput2 = self.getArbitraryManHTMLOutput("10.0.0", "../howto/")
- coreIndexInput, coreIndexOutput = self.getArbitraryLoreInputAndOutput(
- "10.0.0", prefix="howto/")
-
- structure = {
- "README": "Twisted",
- "unrelated": "x",
- "LICENSE": "copyright!",
- "setup.py": "import toplevel",
- "bin": {"web": {"websetroot": "SET ROOT"},
- "twistd": "TWISTD"},
- "twisted":
- {"web":
- {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINSTALL",
- "README": "WEB!"}},
- "words": {"__init__.py": "import WORDS"},
- "plugins": {"twisted_web.py": "import WEBPLUG",
- "twisted_words.py": "import WORDPLUG"}},
- "doc": {"web": {"howto": {"index.xhtml": loreInput},
- "man": {"websetroot.1": manInput2}},
- "core": {"howto": {"template.tpl": self.template},
- "man": {"twistd.1": manInput1},
- "index.xhtml": coreIndexInput}}}
-
- outStructure = {
- "README": "Twisted",
- "unrelated": "x",
- "LICENSE": "copyright!",
- "setup.py": "import toplevel",
- "bin": {"web": {"websetroot": "SET ROOT"},
- "twistd": "TWISTD"},
- "twisted":
- {"web": {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINSTALL",
- "README": "WEB!"}},
- "words": {"__init__.py": "import WORDS"},
- "plugins": {"twisted_web.py": "import WEBPLUG",
- "twisted_words.py": "import WORDPLUG"}},
- "doc": {"web": {"howto": {"index.html": loreOutput},
- "man": {"websetroot.1": manInput2,
- "websetroot-man.html": manOutput2}},
- "core": {"howto": {"template.tpl": self.template},
- "man": {"twistd.1": manInput1,
- "twistd-man.html": manOutput1},
- "index.html": coreIndexOutput}}}
-
- self.createStructure(self.rootDir, structure)
-
- outputFile = self.builder.buildTwisted("10.0.0")
-
- self.assertExtractedStructure(outputFile, outStructure)
-
-
- def test_excluded(self):
- """
- bin/admin and doc/historic are excluded from the Twisted tarball.
- """
- structure = {
- "bin": {"admin": {"blah": "ADMIN"},
- "twistd": "TWISTD"},
- "twisted":
- {"web":
- {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINSTALL",
- "README": "WEB!"}},
- },
- "doc": {"historic": {"hello": "there"},
- "other": "contents",
- },
- }
-
- outStructure = {
- "bin": {"twistd": "TWISTD"},
- "twisted":
- {"web":
- {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINSTALL",
- "README": "WEB!"}},
- },
- "doc": {"other": "contents"},
- }
-
- self.createStructure(self.rootDir, structure)
- outputFile = self.builder.buildTwisted("10.0.0")
- self.assertExtractedStructure(outputFile, outStructure)
-
-
- def test_subProjectLayout(self):
- """
- The subproject tarball includes files like so:
-
- 1. twisted/<subproject>/topfiles defines the files that will be in the
- top level in the tarball, except LICENSE, which comes from the real
- top-level directory.
- 2. twisted/<subproject> is included, but without the topfiles entry
- in that directory. No other twisted subpackages are included.
- 3. twisted/plugins/twisted_<subproject>.py is included, but nothing
- else in plugins is.
- """
- structure = {
- "README": "HI!@",
- "unrelated": "x",
- "LICENSE": "copyright!",
- "setup.py": "import toplevel",
- "bin": {"web": {"websetroot": "SET ROOT"},
- "words": {"im": "#!im"}},
- "twisted":
- {"web":
- {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINSTALL",
- "README": "WEB!"}},
- "words": {"__init__.py": "import WORDS"},
- "plugins": {"twisted_web.py": "import WEBPLUG",
- "twisted_words.py": "import WORDPLUG"}}}
-
- outStructure = {
- "README": "WEB!",
- "LICENSE": "copyright!",
- "setup.py": "import WEBINSTALL",
- "bin": {"websetroot": "SET ROOT"},
- "twisted": {"web": {"__init__.py": "import WEB"},
- "plugins": {"twisted_web.py": "import WEBPLUG"}}}
-
- self.createStructure(self.rootDir, structure)
-
- outputFile = self.builder.buildSubProject("web", "0.3.0")
-
- self.assertExtractedStructure(outputFile, outStructure)
-
-
- def test_minimalSubProjectLayout(self):
- """
- buildSubProject should work with minimal subprojects.
- """
- structure = {
- "LICENSE": "copyright!",
- "bin": {},
- "twisted":
- {"web": {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINSTALL"}},
- "plugins": {}}}
-
- outStructure = {
- "setup.py": "import WEBINSTALL",
- "LICENSE": "copyright!",
- "twisted": {"web": {"__init__.py": "import WEB"}}}
-
- self.createStructure(self.rootDir, structure)
-
- outputFile = self.builder.buildSubProject("web", "0.3.0")
-
- self.assertExtractedStructure(outputFile, outStructure)
-
-
- def test_subProjectDocBuilding(self):
- """
- When building a subproject release, documentation should be built with
- lore.
- """
- loreInput, loreOutput = self.getArbitraryLoreInputAndOutput("0.3.0")
- manInput = self.getArbitraryManInput()
- manOutput = self.getArbitraryManHTMLOutput("0.3.0", "../howto/")
- structure = {
- "LICENSE": "copyright!",
- "twisted": {"web": {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINST"}}},
- "doc": {"web": {"howto": {"index.xhtml": loreInput},
- "man": {"twistd.1": manInput}},
- "core": {"howto": {"template.tpl": self.template}}
- }
- }
-
- outStructure = {
- "LICENSE": "copyright!",
- "setup.py": "import WEBINST",
- "twisted": {"web": {"__init__.py": "import WEB"}},
- "doc": {"howto": {"index.html": loreOutput},
- "man": {"twistd.1": manInput,
- "twistd-man.html": manOutput}}}
-
- self.createStructure(self.rootDir, structure)
-
- outputFile = self.builder.buildSubProject("web", "0.3.0")
-
- self.assertExtractedStructure(outputFile, outStructure)
-
-
- def test_coreProjectLayout(self):
- """
- The core tarball looks a lot like a subproject tarball, except it
- doesn't include:
-
- - Python packages from other subprojects
- - plugins from other subprojects
- - scripts from other subprojects
- """
- indexInput, indexOutput = self.getArbitraryLoreInputAndOutput(
- "8.0.0", prefix="howto/")
- howtoInput, howtoOutput = self.getArbitraryLoreInputAndOutput("8.0.0")
- specInput, specOutput = self.getArbitraryLoreInputAndOutput(
- "8.0.0", prefix="../howto/")
- tutorialInput, tutorialOutput = self.getArbitraryLoreInputAndOutput(
- "8.0.0", prefix="../")
-
- structure = {
- "LICENSE": "copyright!",
- "twisted": {"__init__.py": "twisted",
- "python": {"__init__.py": "python",
- "roots.py": "roots!"},
- "conch": {"__init__.py": "conch",
- "unrelated.py": "import conch"},
- "plugin.py": "plugin",
- "plugins": {"twisted_web.py": "webplug",
- "twisted_whatever.py": "include!",
- "cred.py": "include!"},
- "topfiles": {"setup.py": "import CORE",
- "README": "core readme"}},
- "doc": {"core": {"howto": {"template.tpl": self.template,
- "index.xhtml": howtoInput,
- "tutorial":
- {"index.xhtml": tutorialInput}},
- "specifications": {"index.xhtml": specInput},
- "examples": {"foo.py": "foo.py"},
- "index.xhtml": indexInput},
- "web": {"howto": {"index.xhtml": "webindex"}}},
- "bin": {"twistd": "TWISTD",
- "web": {"websetroot": "websetroot"}}
- }
-
- outStructure = {
- "LICENSE": "copyright!",
- "setup.py": "import CORE",
- "README": "core readme",
- "twisted": {"__init__.py": "twisted",
- "python": {"__init__.py": "python",
- "roots.py": "roots!"},
- "plugin.py": "plugin",
- "plugins": {"twisted_whatever.py": "include!",
- "cred.py": "include!"}},
- "doc": {"howto": {"template.tpl": self.template,
- "index.html": howtoOutput,
- "tutorial": {"index.html": tutorialOutput}},
- "specifications": {"index.html": specOutput},
- "examples": {"foo.py": "foo.py"},
- "index.html": indexOutput},
- "bin": {"twistd": "TWISTD"},
- }
-
- self.createStructure(self.rootDir, structure)
- outputFile = self.builder.buildCore("8.0.0")
- self.assertExtractedStructure(outputFile, outStructure)
-
-
- def test_apiBaseURL(self):
- """
- DistributionBuilder builds documentation with the specified
- API base URL.
- """
- apiBaseURL = "http://%s"
- builder = DistributionBuilder(self.rootDir, self.outputDir,
- apiBaseURL=apiBaseURL)
- loreInput, loreOutput = self.getArbitraryLoreInputAndOutput(
- "0.3.0", apiBaseURL=apiBaseURL)
- structure = {
- "LICENSE": "copyright!",
- "twisted": {"web": {"__init__.py": "import WEB",
- "topfiles": {"setup.py": "import WEBINST"}}},
- "doc": {"web": {"howto": {"index.xhtml": loreInput}},
- "core": {"howto": {"template.tpl": self.template}}
- }
- }
-
- outStructure = {
- "LICENSE": "copyright!",
- "setup.py": "import WEBINST",
- "twisted": {"web": {"__init__.py": "import WEB"}},
- "doc": {"howto": {"index.html": loreOutput}}}
-
- self.createStructure(self.rootDir, structure)
- outputFile = builder.buildSubProject("web", "0.3.0")
- self.assertExtractedStructure(outputFile, outStructure)
-
-
-
-class BuildAllTarballsTest(DistributionBuilderTestBase):
- """
- Tests for L{DistributionBuilder.buildAllTarballs}.
- """
- skip = svnSkip
-
- def setUp(self):
- self.oldHandler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- DistributionBuilderTestBase.setUp(self)
-
-
- def tearDown(self):
- signal.signal(signal.SIGCHLD, self.oldHandler)
- DistributionBuilderTestBase.tearDown(self)
-
-
- def test_buildAllTarballs(self):
- """
- L{buildAllTarballs} builds tarballs for Twisted and all of its
- subprojects based on an SVN checkout; the resulting tarballs contain
- no SVN metadata. This involves building documentation, which it will
- build with the correct API documentation reference base URL.
- """
- repositoryPath = self.mktemp()
- repository = FilePath(repositoryPath)
- checkoutPath = self.mktemp()
- checkout = FilePath(checkoutPath)
- self.outputDir.remove()
-
- runCommand(["svnadmin", "create", repositoryPath])
- runCommand(["svn", "checkout", "file://" + repository.path,
- checkout.path])
- coreIndexInput, coreIndexOutput = self.getArbitraryLoreInputAndOutput(
- "1.2.0", prefix="howto/",
- apiBaseURL="http://twistedmatrix.com/documents/1.2.0/api/%s.html")
-
- structure = {
- "README": "Twisted",
- "unrelated": "x",
- "LICENSE": "copyright!",
- "setup.py": "import toplevel",
- "bin": {"words": {"im": "import im"},
- "twistd": "TWISTD"},
- "twisted":
- {
- "topfiles": {"setup.py": "import TOPINSTALL",
- "README": "CORE!"},
- "_version.py": genVersion("twisted", 1, 2, 0),
- "words": {"__init__.py": "import WORDS",
- "_version.py":
- genVersion("twisted.words", 1, 2, 0),
- "topfiles": {"setup.py": "import WORDSINSTALL",
- "README": "WORDS!"},
- },
- "plugins": {"twisted_web.py": "import WEBPLUG",
- "twisted_words.py": "import WORDPLUG",
- "twisted_yay.py": "import YAY"}},
- "doc": {"core": {"howto": {"template.tpl": self.template},
- "index.xhtml": coreIndexInput}}}
-
- twistedStructure = {
- "README": "Twisted",
- "unrelated": "x",
- "LICENSE": "copyright!",
- "setup.py": "import toplevel",
- "bin": {"twistd": "TWISTD",
- "words": {"im": "import im"}},
- "twisted":
- {
- "topfiles": {"setup.py": "import TOPINSTALL",
- "README": "CORE!"},
- "_version.py": genVersion("twisted", 1, 2, 0),
- "words": {"__init__.py": "import WORDS",
- "_version.py":
- genVersion("twisted.words", 1, 2, 0),
- "topfiles": {"setup.py": "import WORDSINSTALL",
- "README": "WORDS!"},
- },
- "plugins": {"twisted_web.py": "import WEBPLUG",
- "twisted_words.py": "import WORDPLUG",
- "twisted_yay.py": "import YAY"}},
- "doc": {"core": {"howto": {"template.tpl": self.template},
- "index.html": coreIndexOutput}}}
-
- coreStructure = {
- "setup.py": "import TOPINSTALL",
- "README": "CORE!",
- "LICENSE": "copyright!",
- "bin": {"twistd": "TWISTD"},
- "twisted": {
- "_version.py": genVersion("twisted", 1, 2, 0),
- "plugins": {"twisted_yay.py": "import YAY"}},
- "doc": {"howto": {"template.tpl": self.template},
- "index.html": coreIndexOutput}}
-
- wordsStructure = {
- "README": "WORDS!",
- "LICENSE": "copyright!",
- "setup.py": "import WORDSINSTALL",
- "bin": {"im": "import im"},
- "twisted":
- {
- "words": {"__init__.py": "import WORDS",
- "_version.py":
- genVersion("twisted.words", 1, 2, 0),
- },
- "plugins": {"twisted_words.py": "import WORDPLUG"}}}
-
- self.createStructure(checkout, structure)
- childs = [x.path for x in checkout.children()]
- runCommand(["svn", "add"] + childs)
- runCommand(["svn", "commit", checkout.path, "-m", "yay"])
-
- buildAllTarballs(checkout, self.outputDir)
- self.assertEqual(
- set(self.outputDir.children()),
- set([self.outputDir.child("Twisted-1.2.0.tar.bz2"),
- self.outputDir.child("TwistedCore-1.2.0.tar.bz2"),
- self.outputDir.child("TwistedWords-1.2.0.tar.bz2")]))
-
- self.assertExtractedStructure(
- self.outputDir.child("Twisted-1.2.0.tar.bz2"),
- twistedStructure)
- self.assertExtractedStructure(
- self.outputDir.child("TwistedCore-1.2.0.tar.bz2"),
- coreStructure)
- self.assertExtractedStructure(
- self.outputDir.child("TwistedWords-1.2.0.tar.bz2"),
- wordsStructure)
-
-
- def test_buildAllTarballsEnsuresCleanCheckout(self):
- """
- L{UncleanWorkingDirectory} is raised by L{buildAllTarballs} when the
- SVN checkout provided has uncommitted changes.
- """
- repositoryPath = self.mktemp()
- repository = FilePath(repositoryPath)
- checkoutPath = self.mktemp()
- checkout = FilePath(checkoutPath)
-
- runCommand(["svnadmin", "create", repositoryPath])
- runCommand(["svn", "checkout", "file://" + repository.path,
- checkout.path])
-
- checkout.child("foo").setContent("whatever")
- self.assertRaises(UncleanWorkingDirectory,
- buildAllTarballs, checkout, FilePath(self.mktemp()))
-
-
- def test_buildAllTarballsEnsuresExistingCheckout(self):
- """
- L{NotWorkingDirectory} is raised by L{buildAllTarballs} when the
- checkout passed does not exist or is not an SVN checkout.
- """
- checkout = FilePath(self.mktemp())
- self.assertRaises(NotWorkingDirectory,
- buildAllTarballs,
- checkout, FilePath(self.mktemp()))
- checkout.createDirectory()
- self.assertRaises(NotWorkingDirectory,
- buildAllTarballs,
- checkout, FilePath(self.mktemp()))
-
-
-
-class ScriptTests(BuilderTestsMixin, StructureAssertingMixin, TestCase):
- """
- Tests for the release script functionality.
- """
-
- def _testVersionChanging(self, major, minor, micro, prerelease=None):
- """
- Check that L{ChangeVersionsScript.main} calls the version-changing
- function with the appropriate version data and filesystem path.
- """
- versionUpdates = []
- def myVersionChanger(sourceTree, versionTemplate):
- versionUpdates.append((sourceTree, versionTemplate))
- versionChanger = ChangeVersionsScript()
- versionChanger.changeAllProjectVersions = myVersionChanger
- version = "%d.%d.%d" % (major, minor, micro)
- if prerelease is not None:
- version += "pre%d" % (prerelease,)
- versionChanger.main([version])
- self.assertEqual(len(versionUpdates), 1)
- self.assertEqual(versionUpdates[0][0], FilePath("."))
- self.assertEqual(versionUpdates[0][1].major, major)
- self.assertEqual(versionUpdates[0][1].minor, minor)
- self.assertEqual(versionUpdates[0][1].micro, micro)
- self.assertEqual(versionUpdates[0][1].prerelease, prerelease)
-
-
- def test_changeVersions(self):
- """
- L{ChangeVersionsScript.main} changes version numbers for all Twisted
- projects.
- """
- self._testVersionChanging(8, 2, 3)
-
-
- def test_changeVersionsWithPrerelease(self):
- """
- A prerelease can be specified to L{changeVersionsScript}.
- """
- self._testVersionChanging(9, 2, 7, 38)
-
-
- def test_defaultChangeVersionsVersionChanger(self):
- """
- The default implementation of C{changeAllProjectVersions} is
- L{changeAllProjectVersions}.
- """
- versionChanger = ChangeVersionsScript()
- self.assertEqual(versionChanger.changeAllProjectVersions,
- changeAllProjectVersions)
-
-
- def test_badNumberOfArgumentsToChangeVersionsScript(self):
- """
- L{changeVersionsScript} raises SystemExit when the wrong number of
- arguments are passed.
- """
- versionChanger = ChangeVersionsScript()
- self.assertRaises(SystemExit, versionChanger.main, [])
-
-
- def test_tooManyDotsToChangeVersionsScript(self):
- """
- L{changeVersionsScript} raises SystemExit when there are the wrong
- number of segments in the version number passed.
- """
- versionChanger = ChangeVersionsScript()
- self.assertRaises(SystemExit, versionChanger.main,
- ["3.2.1.0"])
-
-
- def test_nonIntPartsToChangeVersionsScript(self):
- """
- L{changeVersionsScript} raises SystemExit when the version number isn't
- made out of numbers.
- """
- versionChanger = ChangeVersionsScript()
- self.assertRaises(SystemExit, versionChanger.main,
- ["my united.states.of prewhatever"])
-
-
- def test_buildTarballsScript(self):
- """
- L{BuildTarballsScript.main} invokes L{buildAllTarballs} with
- 2 or 3 L{FilePath} instances representing the paths passed to it.
- """
- builds = []
- def myBuilder(checkout, destination, template=None):
- builds.append((checkout, destination, template))
- tarballBuilder = BuildTarballsScript()
- tarballBuilder.buildAllTarballs = myBuilder
-
- tarballBuilder.main(["checkoutDir", "destinationDir"])
- self.assertEqual(
- builds,
- [(FilePath("checkoutDir"), FilePath("destinationDir"), None)])
-
- builds = []
- tarballBuilder.main(["checkoutDir", "destinationDir", "templatePath"])
- self.assertEqual(
- builds,
- [(FilePath("checkoutDir"), FilePath("destinationDir"),
- FilePath("templatePath"))])
-
-
- def test_defaultBuildTarballsScriptBuilder(self):
- """
- The default implementation of L{BuildTarballsScript.buildAllTarballs}
- is L{buildAllTarballs}.
- """
- tarballBuilder = BuildTarballsScript()
- self.assertEqual(tarballBuilder.buildAllTarballs, buildAllTarballs)
-
-
- def test_badNumberOfArgumentsToBuildTarballs(self):
- """
- L{BuildTarballsScript.main} raises SystemExit when the wrong number of
- arguments are passed.
- """
- tarballBuilder = BuildTarballsScript()
- self.assertRaises(SystemExit, tarballBuilder.main, [])
- self.assertRaises(SystemExit, tarballBuilder.main, ["a", "b", "c", "d"])
-
-
- def test_badNumberOfArgumentsToBuildNews(self):
- """
- L{NewsBuilder.main} raises L{SystemExit} when other than 1 argument is
- passed to it.
- """
- newsBuilder = NewsBuilder()
- self.assertRaises(SystemExit, newsBuilder.main, [])
- self.assertRaises(SystemExit, newsBuilder.main, ["hello", "world"])
-
-
- def test_buildNews(self):
- """
- L{NewsBuilder.main} calls L{NewsBuilder.buildAll} with a L{FilePath}
- instance constructed from the path passed to it.
- """
- builds = []
- newsBuilder = NewsBuilder()
- newsBuilder.buildAll = builds.append
- newsBuilder.main(["/foo/bar/baz"])
- self.assertEqual(builds, [FilePath("/foo/bar/baz")])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_runtime.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_runtime.py
deleted file mode 100755
index 4c94fb5e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_runtime.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for runtime checks.
-"""
-
-import sys
-
-from twisted.python.runtime import Platform, shortPythonVersion
-from twisted.trial.unittest import TestCase
-
-
-
-class PythonVersionTests(TestCase):
- """
- Tests the shortPythonVersion method.
- """
-
- def test_shortPythonVersion(self):
- """
- Verify if the Python version is returned correctly.
- """
- ver = shortPythonVersion().split('.')
- for i in range(3):
- self.assertEqual(int(ver[i]), sys.version_info[i])
-
-
-
-class PlatformTests(TestCase):
- """
- Tests for the default L{Platform} initializer.
- """
-
- def test_isVistaConsistency(self):
- """
- Verify consistency of L{Platform.isVista}: it can only be C{True} if
- L{Platform.isWinNT} and L{Platform.isWindows} are C{True}.
- """
- platform = Platform()
- if platform.isVista():
- self.assertTrue(platform.isWinNT())
- self.assertTrue(platform.isWindows())
- self.assertFalse(platform.isMacOSX())
-
-
- def test_isMacOSXConsistency(self):
- """
- L{Platform.isMacOSX} can only return C{True} if L{Platform.getType}
- returns C{'posix'}.
- """
- platform = Platform()
- if platform.isMacOSX():
- self.assertEqual(platform.getType(), 'posix')
-
-
- def test_isLinuxConsistency(self):
- """
- L{Platform.isLinux} can only return C{True} if L{Platform.getType}
- returns C{'posix'} and L{sys.platform} starts with C{"linux"}.
- """
- platform = Platform()
- if platform.isLinux():
- self.assertTrue(sys.platform.startswith("linux"))
-
-
-
-class ForeignPlatformTests(TestCase):
- """
- Tests for L{Platform} based overridden initializer values.
- """
-
- def test_getType(self):
- """
- If an operating system name is supplied to L{Platform}'s initializer,
- L{Platform.getType} returns the platform type which corresponds to that
- name.
- """
- self.assertEqual(Platform('nt').getType(), 'win32')
- self.assertEqual(Platform('ce').getType(), 'win32')
- self.assertEqual(Platform('posix').getType(), 'posix')
- self.assertEqual(Platform('java').getType(), 'java')
-
-
- def test_isMacOSX(self):
- """
- If a system platform name is supplied to L{Platform}'s initializer, it
- is used to determine the result of L{Platform.isMacOSX}, which returns
- C{True} for C{"darwin"}, C{False} otherwise.
- """
- self.assertTrue(Platform(None, 'darwin').isMacOSX())
- self.assertFalse(Platform(None, 'linux2').isMacOSX())
- self.assertFalse(Platform(None, 'win32').isMacOSX())
-
-
- def test_isLinux(self):
- """
- If a system platform name is supplied to L{Platform}'s initializer, it
- is used to determine the result of L{Platform.isLinux}, which returns
- C{True} for values beginning with C{"linux"}, C{False} otherwise.
- """
- self.assertFalse(Platform(None, 'darwin').isLinux())
- self.assertTrue(Platform(None, 'linux').isLinux())
- self.assertTrue(Platform(None, 'linux2').isLinux())
- self.assertTrue(Platform(None, 'linux3').isLinux())
- self.assertFalse(Platform(None, 'win32').isLinux())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_sendmsg.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_sendmsg.py
deleted file mode 100755
index 48301f5e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_sendmsg.py
+++ /dev/null
@@ -1,543 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.sendmsg}.
-"""
-
-import sys
-import errno
-
-from socket import SOL_SOCKET, AF_INET, AF_INET6, socket, error
-
-try:
- from socket import AF_UNIX, socketpair
-except ImportError:
- nonUNIXSkip = "Platform does not support AF_UNIX sockets"
-else:
- nonUNIXSkip = None
-
-from struct import pack
-from os import devnull, pipe, read, close, environ
-
-from twisted.internet.defer import Deferred
-from twisted.internet.error import ProcessDone
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import inlineCallbacks
-from twisted.internet import reactor
-from twisted.python.filepath import FilePath
-from twisted.python.runtime import platform
-
-from twisted.internet.protocol import ProcessProtocol
-
-if platform.isLinux():
- from socket import MSG_DONTWAIT
- dontWaitSkip = None
-else:
- # It would be nice to be able to test flags on more platforms, but finding a
- # flag that works *at all* is somewhat challenging.
- dontWaitSkip = "MSG_DONTWAIT is only known to work as intended on Linux"
-
-try:
- from twisted.python.sendmsg import SCM_RIGHTS, send1msg, recv1msg, getsockfam
-except ImportError:
- importSkip = "Cannot import twisted.python.sendmsg"
-else:
- importSkip = None
-
-
-class ExitedWithStderr(Exception):
- """
- A process exited with some stderr.
- """
-
- def __str__(self):
- """
- Dump the errors in a pretty way in the event of a subprocess traceback.
- """
- return '\n'.join([''] + list(self.args))
-
-
-class StartStopProcessProtocol(ProcessProtocol):
- """
- An L{IProcessProtocol} with a Deferred for events where the subprocess
- starts and stops.
-
- @ivar started: A L{Deferred} which fires with this protocol's
- L{IProcessTransport} provider when it is connected to one.
-
- @ivar stopped: A L{Deferred} which fires with the process output or a
- failure if the process produces output on standard error.
-
- @ivar output: A C{str} used to accumulate standard output.
-
- @ivar errors: A C{str} used to accumulate standard error.
- """
- def __init__(self):
- self.started = Deferred()
- self.stopped = Deferred()
- self.output = ''
- self.errors = ''
-
-
- def connectionMade(self):
- self.started.callback(self.transport)
-
-
- def outReceived(self, data):
- self.output += data
-
-
- def errReceived(self, data):
- self.errors += data
-
-
- def processEnded(self, reason):
- if reason.check(ProcessDone):
- self.stopped.callback(self.output)
- else:
- self.stopped.errback(ExitedWithStderr(
- self.errors, self.output))
-
-
-
-class BadList(list):
- """
- A list which cannot be iterated sometimes.
-
- This is a C{list} subclass to get past the type check in L{send1msg}, not as
- an example of how real programs might want to interact with L{send1msg} (or
- anything else). A custom C{list} subclass makes it easier to trigger
- certain error cases in the implementation.
-
- @ivar iterate: A flag which indicates whether an instance of L{BadList} will
- allow iteration over itself or not. If C{False}, an attempt to iterate
- over the instance will raise an exception.
- """
- iterate = True
-
- def __iter__(self):
- """
- Allow normal list iteration, or raise an exception.
-
- If C{self.iterate} is C{True}, it will be flipped to C{False} and then
- normal iteration will proceed. If C{self.iterate} is C{False},
- L{RuntimeError} is raised instead.
- """
- if self.iterate:
- self.iterate = False
- return super(BadList, self).__iter__()
- raise RuntimeError("Something bad happened")
-
-
-
-class WorseList(list):
- """
- A list which at first gives the appearance of being iterable, but then
- raises an exception.
-
- See L{BadList} for a warning about not writing code like this.
- """
- def __iter__(self):
- """
- Return an iterator which will raise an exception as soon as C{next} is
- called on it.
- """
- class BadIterator(object):
- def next(self):
- raise RuntimeError("This is a really bad case.")
- return BadIterator()
-
-
-
-class SendmsgTestCase(TestCase):
- """
- Tests for sendmsg extension module and associated file-descriptor sending
- functionality.
- """
- if nonUNIXSkip is not None:
- skip = nonUNIXSkip
- elif importSkip is not None:
- skip = importSkip
-
- def setUp(self):
- """
- Create a pair of UNIX sockets.
- """
- self.input, self.output = socketpair(AF_UNIX)
-
-
- def tearDown(self):
- """
- Close the sockets opened by setUp.
- """
- self.input.close()
- self.output.close()
-
-
- def test_sendmsgBadArguments(self):
- """
- The argument types accepted by L{send1msg} are:
-
- 1. C{int}
- 2. read-only character buffer
- 3. C{int}
- 4. sequence
-
- The 3rd and 4th arguments are optional. If fewer than two arguments or
- more than four arguments are passed, or if any of the arguments passed
- are not compatible with these types, L{TypeError} is raised.
- """
- # Exercise the wrong number of arguments cases
- self.assertRaises(TypeError, send1msg)
- self.assertRaises(TypeError, send1msg, 1)
- self.assertRaises(TypeError, send1msg, 1, "hello world", 2, [], object())
-
- # Exercise the wrong type of arguments cases
- self.assertRaises(TypeError, send1msg, object(), "hello world", 2, [])
- self.assertRaises(TypeError, send1msg, 1, object(), 2, [])
- self.assertRaises(TypeError, send1msg, 1, "hello world", object(), [])
- self.assertRaises(TypeError, send1msg, 1, "hello world", 2, object())
-
-
- def test_badAncillaryIter(self):
- """
- If iteration over the ancillary data list fails (at the point of the
- C{__iter__} call), the exception with which it fails is propagated to
- the caller of L{send1msg}.
- """
- badList = BadList()
- badList.append((1, 2, "hello world"))
- badList.iterate = False
-
- self.assertRaises(RuntimeError, send1msg, 1, "hello world", 2, badList)
-
- # Hit the second iteration
- badList.iterate = True
- self.assertRaises(RuntimeError, send1msg, 1, "hello world", 2, badList)
-
-
- def test_badAncillaryNext(self):
- """
- If iteration over the ancillary data list fails (at the point of a
- C{next} call), the exception with which it fails is propagated to the
- caller of L{send1msg}.
- """
- worseList = WorseList()
- self.assertRaises(RuntimeError, send1msg, 1, "hello world", 2, worseList)
-
-
- def test_sendmsgBadAncillaryItem(self):
- """
- The ancillary data list contains three-tuples with element types of:
-
- 1. C{int}
- 2. C{int}
- 3. read-only character buffer
-
- If a tuple in the ancillary data list does not elements of these types,
- L{TypeError} is raised.
- """
- # Exercise the wrong number of arguments cases
- self.assertRaises(TypeError, send1msg, 1, "hello world", 2, [()])
- self.assertRaises(TypeError, send1msg, 1, "hello world", 2, [(1,)])
- self.assertRaises(TypeError, send1msg, 1, "hello world", 2, [(1, 2)])
- self.assertRaises(
- TypeError,
- send1msg, 1, "hello world", 2, [(1, 2, "goodbye", object())])
-
- # Exercise the wrong type of arguments cases
- exc = self.assertRaises(
- TypeError, send1msg, 1, "hello world", 2, [object()])
- self.assertEqual(
- "send1msg argument 3 expected list of tuple, "
- "got list containing object",
- str(exc))
- self.assertRaises(
- TypeError,
- send1msg, 1, "hello world", 2, [(object(), 1, "goodbye")])
- self.assertRaises(
- TypeError,
- send1msg, 1, "hello world", 2, [(1, object(), "goodbye")])
- self.assertRaises(
- TypeError,
- send1msg, 1, "hello world", 2, [(1, 1, object())])
-
-
- def test_syscallError(self):
- """
- If the underlying C{sendmsg} call fails, L{send1msg} raises
- L{socket.error} with its errno set to the underlying errno value.
- """
- probe = file(devnull)
- fd = probe.fileno()
- probe.close()
- exc = self.assertRaises(error, send1msg, fd, "hello, world")
- self.assertEqual(exc.args[0], errno.EBADF)
-
-
- def test_syscallErrorWithControlMessage(self):
- """
- The behavior when the underlying C{sendmsg} call fails is the same
- whether L{send1msg} is passed ancillary data or not.
- """
- probe = file(devnull)
- fd = probe.fileno()
- probe.close()
- exc = self.assertRaises(
- error, send1msg, fd, "hello, world", 0, [(0, 0, "0123")])
- self.assertEqual(exc.args[0], errno.EBADF)
-
-
- def test_roundtrip(self):
- """
- L{recv1msg} will retrieve a message sent via L{send1msg}.
- """
- message = "hello, world!"
- self.assertEqual(
- len(message),
- send1msg(self.input.fileno(), message, 0))
-
- result = recv1msg(fd=self.output.fileno())
- self.assertEquals(result, (message, 0, []))
-
-
- def test_shortsend(self):
- """
- L{send1msg} returns the number of bytes which it was able to send.
- """
- message = "x" * 1024 * 1024
- self.input.setblocking(False)
- sent = send1msg(self.input.fileno(), message)
- # Sanity check - make sure we did fill the send buffer and then some
- self.assertTrue(sent < len(message))
- received = recv1msg(self.output.fileno(), 0, len(message))
- self.assertEqual(len(received[0]), sent)
-
-
- def test_roundtripEmptyAncillary(self):
- """
- L{send1msg} treats an empty ancillary data list the same way it treats
- receiving no argument for the ancillary parameter at all.
- """
- send1msg(self.input.fileno(), "hello, world!", 0, [])
-
- result = recv1msg(fd=self.output.fileno())
- self.assertEquals(result, ("hello, world!", 0, []))
-
-
- def test_flags(self):
- """
- The C{flags} argument to L{send1msg} is passed on to the underlying
- C{sendmsg} call, to affect it in whatever way is defined by those flags.
- """
- # Just exercise one flag with simple, well-known behavior. MSG_DONTWAIT
- # makes the send a non-blocking call, even if the socket is in blocking
- # mode. See also test_flags in RecvmsgTestCase
- for i in range(1024):
- try:
- send1msg(self.input.fileno(), "x" * 1024, MSG_DONTWAIT)
- except error, e:
- self.assertEqual(e.args[0], errno.EAGAIN)
- break
- else:
- self.fail(
- "Failed to fill up the send buffer, "
- "or maybe send1msg blocked for a while")
- if dontWaitSkip is not None:
- test_flags.skip = dontWaitSkip
-
-
- def test_wrongTypeAncillary(self):
- """
- L{send1msg} will show a helpful exception message when given the wrong
- type of object for the 'ancillary' argument.
- """
- error = self.assertRaises(TypeError,
- send1msg, self.input.fileno(),
- "hello, world!", 0, 4321)
- self.assertEquals(str(error),
- "send1msg argument 3 expected list, got int")
-
-
- def spawn(self, script):
- """
- Start a script that is a peer of this test as a subprocess.
-
- @param script: the module name of the script in this directory (no
- package prefix, no '.py')
- @type script: C{str}
-
- @rtype: L{StartStopProcessProtocol}
- """
- sspp = StartStopProcessProtocol()
- reactor.spawnProcess(
- sspp, sys.executable, [
- sys.executable,
- FilePath(__file__).sibling(script + ".py").path,
- str(self.output.fileno()),
- ],
- environ,
- childFDs={0: "w", 1: "r", 2: "r",
- self.output.fileno(): self.output.fileno()}
- )
- return sspp
-
-
- @inlineCallbacks
- def test_sendSubProcessFD(self):
- """
- Calling L{sendsmsg} with SOL_SOCKET, SCM_RIGHTS, and a platform-endian
- packed file descriptor number should send that file descriptor to a
- different process, where it can be retrieved by using L{recv1msg}.
- """
- sspp = self.spawn("pullpipe")
- yield sspp.started
- pipeOut, pipeIn = pipe()
- self.addCleanup(close, pipeOut)
-
- send1msg(
- self.input.fileno(), "blonk", 0,
- [(SOL_SOCKET, SCM_RIGHTS, pack("i", pipeIn))])
-
- close(pipeIn)
- yield sspp.stopped
- self.assertEquals(read(pipeOut, 1024), "Test fixture data: blonk.\n")
- # Make sure that the pipe is actually closed now.
- self.assertEquals(read(pipeOut, 1024), "")
-
-
-
-class RecvmsgTestCase(TestCase):
- """
- Tests for L{recv1msg} (primarily error handling cases).
- """
- if importSkip is not None:
- skip = importSkip
-
- def test_badArguments(self):
- """
- The argument types accepted by L{recv1msg} are:
-
- 1. C{int}
- 2. C{int}
- 3. C{int}
- 4. C{int}
-
- The 2nd, 3rd, and 4th arguments are optional. If fewer than one
- argument or more than four arguments are passed, or if any of the
- arguments passed are not compatible with these types, L{TypeError} is
- raised.
- """
- # Exercise the wrong number of arguments cases
- self.assertRaises(TypeError, recv1msg)
- self.assertRaises(TypeError, recv1msg, 1, 2, 3, 4, object())
-
- # Exercise the wrong type of arguments cases
- self.assertRaises(TypeError, recv1msg, object(), 2, 3, 4)
- self.assertRaises(TypeError, recv1msg, 1, object(), 3, 4)
- self.assertRaises(TypeError, recv1msg, 1, 2, object(), 4)
- self.assertRaises(TypeError, recv1msg, 1, 2, 3, object())
-
-
- def test_cmsgSpaceOverflow(self):
- """
- L{recv1msg} raises L{OverflowError} if passed a value for the
- C{cmsg_size} argument which exceeds C{SOCKLEN_MAX}.
- """
- self.assertRaises(OverflowError, recv1msg, 0, 0, 0, 0x7FFFFFFF)
-
-
- def test_syscallError(self):
- """
- If the underlying C{recvmsg} call fails, L{recv1msg} raises
- L{socket.error} with its errno set to the underlying errno value.
- """
- probe = file(devnull)
- fd = probe.fileno()
- probe.close()
- exc = self.assertRaises(error, recv1msg, fd)
- self.assertEqual(exc.args[0], errno.EBADF)
-
-
- def test_flags(self):
- """
- The C{flags} argument to L{recv1msg} is passed on to the underlying
- C{recvmsg} call, to affect it in whatever way is defined by those flags.
- """
- # See test_flags in SendmsgTestCase
- reader, writer = socketpair(AF_UNIX)
- exc = self.assertRaises(
- error, recv1msg, reader.fileno(), MSG_DONTWAIT)
- self.assertEqual(exc.args[0], errno.EAGAIN)
- if dontWaitSkip is not None:
- test_flags.skip = dontWaitSkip
-
-
-
-class GetSocketFamilyTests(TestCase):
- """
- Tests for L{getsockfam}, a helper which reveals the address family of an
- arbitrary socket.
- """
- if importSkip is not None:
- skip = importSkip
-
- def _socket(self, addressFamily):
- """
- Create a new socket using the given address family and return that
- socket's file descriptor. The socket will automatically be closed when
- the test is torn down.
- """
- s = socket(addressFamily)
- self.addCleanup(s.close)
- return s.fileno()
-
-
- def test_badArguments(self):
- """
- L{getsockfam} accepts a single C{int} argument. If it is called in some
- other way, L{TypeError} is raised.
- """
- self.assertRaises(TypeError, getsockfam)
- self.assertRaises(TypeError, getsockfam, 1, 2)
-
- self.assertRaises(TypeError, getsockfam, object())
-
-
- def test_syscallError(self):
- """
- If the underlying C{getsockname} call fails, L{getsockfam} raises
- L{socket.error} with its errno set to the underlying errno value.
- """
- probe = file(devnull)
- fd = probe.fileno()
- probe.close()
- exc = self.assertRaises(error, getsockfam, fd)
- self.assertEqual(errno.EBADF, exc.args[0])
-
-
- def test_inet(self):
- """
- When passed the file descriptor of a socket created with the C{AF_INET}
- address family, L{getsockfam} returns C{AF_INET}.
- """
- self.assertEqual(AF_INET, getsockfam(self._socket(AF_INET)))
-
-
- def test_inet6(self):
- """
- When passed the file descriptor of a socket created with the C{AF_INET6}
- address family, L{getsockfam} returns C{AF_INET6}.
- """
- self.assertEqual(AF_INET6, getsockfam(self._socket(AF_INET6)))
-
-
- def test_unix(self):
- """
- When passed the file descriptor of a socket created with the C{AF_UNIX}
- address family, L{getsockfam} returns C{AF_UNIX}.
- """
- self.assertEqual(AF_UNIX, getsockfam(self._socket(AF_UNIX)))
- if nonUNIXSkip is not None:
- test_unix.skip = nonUNIXSkip
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_shellcomp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_shellcomp.py
deleted file mode 100755
index 7f9cc833..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_shellcomp.py
+++ /dev/null
@@ -1,623 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.python._shellcomp
-"""
-
-import sys
-from cStringIO import StringIO
-
-from twisted.trial import unittest
-from twisted.python import _shellcomp, usage, reflect
-from twisted.python.usage import Completions, Completer, CompleteFiles
-from twisted.python.usage import CompleteList
-
-
-
-class ZshScriptTestMeta(type):
- """
- Metaclass of ZshScriptTestMixin.
- """
- def __new__(cls, name, bases, attrs):
- def makeTest(cmdName, optionsFQPN):
- def runTest(self):
- return test_genZshFunction(self, cmdName, optionsFQPN)
- return runTest
-
- # add test_ methods to the class for each script
- # we are testing.
- if 'generateFor' in attrs:
- for cmdName, optionsFQPN in attrs['generateFor']:
- test = makeTest(cmdName, optionsFQPN)
- attrs['test_genZshFunction_' + cmdName] = test
-
- return type.__new__(cls, name, bases, attrs)
-
-
-
-class ZshScriptTestMixin(object):
- """
- Integration test helper to show that C{usage.Options} classes can have zsh
- completion functions generated for them without raising errors.
-
- In your subclasses set a class variable like so:
-
- # | cmd name | Fully Qualified Python Name of Options class |
- #
- generateFor = [('conch', 'twisted.conch.scripts.conch.ClientOptions'),
- ('twistd', 'twisted.scripts.twistd.ServerOptions'),
- ]
-
- Each package that contains Twisted scripts should contain one TestCase
- subclass which also inherits from this mixin, and contains a C{generateFor}
- list appropriate for the scripts in that package.
- """
- __metaclass__ = ZshScriptTestMeta
-
-
-
-def test_genZshFunction(self, cmdName, optionsFQPN):
- """
- Generate completion functions for given twisted command - no errors
- should be raised
-
- @type cmdName: C{str}
- @param cmdName: The name of the command-line utility e.g. 'twistd'
-
- @type optionsFQPN: C{str}
- @param optionsFQPN: The Fully Qualified Python Name of the C{Options}
- class to be tested.
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
-
- # some scripts won't import or instantiate because of missing
- # dependencies (PyCrypto, etc) so we have to skip them.
- try:
- o = reflect.namedAny(optionsFQPN)()
- except Exception, e:
- raise unittest.SkipTest("Couldn't import or instantiate "
- "Options class: %s" % (e,))
-
- try:
- o.parseOptions(["", "--_shell-completion", "zsh:2"])
- except ImportError, e:
- # this can happen for commands which don't have all
- # the necessary dependencies installed. skip test.
- # skip
- raise unittest.SkipTest("ImportError calling parseOptions(): %s", (e,))
- except SystemExit:
- pass # expected
- else:
- self.fail('SystemExit not raised')
- outputFile.seek(0)
- # test that we got some output
- self.assertEqual(1, len(outputFile.read(1)))
- outputFile.seek(0)
- outputFile.truncate()
-
- # now, if it has sub commands, we have to test those too
- if hasattr(o, 'subCommands'):
- for (cmd, short, parser, doc) in o.subCommands:
- try:
- o.parseOptions([cmd, "", "--_shell-completion",
- "zsh:3"])
- except ImportError, e:
- # this can happen for commands which don't have all
- # the necessary dependencies installed. skip test.
- raise unittest.SkipTest("ImportError calling parseOptions() "
- "on subcommand: %s", (e,))
- except SystemExit:
- pass # expected
- else:
- self.fail('SystemExit not raised')
-
- outputFile.seek(0)
- # test that we got some output
- self.assertEqual(1, len(outputFile.read(1)))
- outputFile.seek(0)
- outputFile.truncate()
-
- # flushed because we don't want DeprecationWarnings to be printed when
- # running these test cases.
- self.flushWarnings()
-
-
-
-class ZshTestCase(unittest.TestCase):
- """
- Tests for zsh completion code
- """
- def test_accumulateMetadata(self):
- """
- Are `compData' attributes you can place on Options classes
- picked up correctly?
- """
- opts = FighterAceExtendedOptions()
- ag = _shellcomp.ZshArgumentsGenerator(opts, 'ace', 'dummy_value')
-
- descriptions = FighterAceOptions.compData.descriptions.copy()
- descriptions.update(FighterAceExtendedOptions.compData.descriptions)
-
- self.assertEqual(ag.descriptions, descriptions)
- self.assertEqual(ag.multiUse,
- set(FighterAceOptions.compData.multiUse))
- self.assertEqual(ag.mutuallyExclusive,
- FighterAceOptions.compData.mutuallyExclusive)
-
- optActions = FighterAceOptions.compData.optActions.copy()
- optActions.update(FighterAceExtendedOptions.compData.optActions)
- self.assertEqual(ag.optActions, optActions)
-
- self.assertEqual(ag.extraActions,
- FighterAceOptions.compData.extraActions)
-
-
- def test_mutuallyExclusiveCornerCase(self):
- """
- Exercise a corner-case of ZshArgumentsGenerator.makeExcludesDict()
- where the long option name already exists in the `excludes` dict being
- built.
- """
- class OddFighterAceOptions(FighterAceExtendedOptions):
- # since "fokker", etc, are already defined as mutually-
- # exclusive on the super-class, defining them again here forces
- # the corner-case to be exercised.
- optFlags = [['anatra', None,
- 'Select the Anatra DS as your dogfighter aircraft']]
- compData = Completions(
- mutuallyExclusive=[['anatra', 'fokker', 'albatros',
- 'spad', 'bristol']])
-
- opts = OddFighterAceOptions()
- ag = _shellcomp.ZshArgumentsGenerator(opts, 'ace', 'dummy_value')
-
- expected = {
- 'albatros': set(['anatra', 'b', 'bristol', 'f',
- 'fokker', 's', 'spad']),
- 'anatra': set(['a', 'albatros', 'b', 'bristol',
- 'f', 'fokker', 's', 'spad']),
- 'bristol': set(['a', 'albatros', 'anatra', 'f',
- 'fokker', 's', 'spad']),
- 'fokker': set(['a', 'albatros', 'anatra', 'b',
- 'bristol', 's', 'spad']),
- 'spad': set(['a', 'albatros', 'anatra', 'b',
- 'bristol', 'f', 'fokker'])}
-
- self.assertEqual(ag.excludes, expected)
-
-
- def test_accumulateAdditionalOptions(self):
- """
- We pick up options that are only defined by having an
- appropriately named method on your Options class,
- e.g. def opt_foo(self, foo)
- """
- opts = FighterAceExtendedOptions()
- ag = _shellcomp.ZshArgumentsGenerator(opts, 'ace', 'dummy_value')
-
- self.assertIn('nocrash', ag.flagNameToDefinition)
- self.assertIn('nocrash', ag.allOptionsNameToDefinition)
-
- self.assertIn('difficulty', ag.paramNameToDefinition)
- self.assertIn('difficulty', ag.allOptionsNameToDefinition)
-
-
- def test_verifyZshNames(self):
- """
- Using a parameter/flag name that doesn't exist
- will raise an error
- """
- class TmpOptions(FighterAceExtendedOptions):
- # Note typo of detail
- compData = Completions(optActions={'detaill' : None})
-
- self.assertRaises(ValueError, _shellcomp.ZshArgumentsGenerator,
- TmpOptions(), 'ace', 'dummy_value')
-
- class TmpOptions2(FighterAceExtendedOptions):
- # Note that 'foo' and 'bar' are not real option
- # names defined in this class
- compData = Completions(
- mutuallyExclusive=[("foo", "bar")])
-
- self.assertRaises(ValueError, _shellcomp.ZshArgumentsGenerator,
- TmpOptions2(), 'ace', 'dummy_value')
-
-
- def test_zshCode(self):
- """
- Generate a completion function, and test the textual output
- against a known correct output
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
- self.patch(sys, 'argv', ["silly", "", "--_shell-completion", "zsh:2"])
- opts = SimpleProgOptions()
- self.assertRaises(SystemExit, opts.parseOptions)
- self.assertEqual(testOutput1, outputFile.getvalue())
-
-
- def test_zshCodeWithSubs(self):
- """
- Generate a completion function with subcommands,
- and test the textual output against a known correct output
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
- self.patch(sys, 'argv', ["silly2", "", "--_shell-completion", "zsh:2"])
- opts = SimpleProgWithSubcommands()
- self.assertRaises(SystemExit, opts.parseOptions)
- self.assertEqual(testOutput2, outputFile.getvalue())
-
-
- def test_incompleteCommandLine(self):
- """
- Completion still happens even if a command-line is given
- that would normally throw UsageError.
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
- opts = FighterAceOptions()
-
- self.assertRaises(SystemExit, opts.parseOptions,
- ["--fokker", "server", "--unknown-option",
- "--unknown-option2",
- "--_shell-completion", "zsh:5"])
- outputFile.seek(0)
- # test that we got some output
- self.assertEqual(1, len(outputFile.read(1)))
-
-
- def test_incompleteCommandLine_case2(self):
- """
- Completion still happens even if a command-line is given
- that would normally throw UsageError.
-
- The existance of --unknown-option prior to the subcommand
- will break subcommand detection... but we complete anyway
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
- opts = FighterAceOptions()
-
- self.assertRaises(SystemExit, opts.parseOptions,
- ["--fokker", "--unknown-option", "server",
- "--list-server", "--_shell-completion", "zsh:5"])
- outputFile.seek(0)
- # test that we got some output
- self.assertEqual(1, len(outputFile.read(1)))
-
- outputFile.seek(0)
- outputFile.truncate()
-
-
- def test_incompleteCommandLine_case3(self):
- """
- Completion still happens even if a command-line is given
- that would normally throw UsageError.
-
- Break subcommand detection in a different way by providing
- an invalid subcommand name.
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
- opts = FighterAceOptions()
-
- self.assertRaises(SystemExit, opts.parseOptions,
- ["--fokker", "unknown-subcommand",
- "--list-server", "--_shell-completion", "zsh:4"])
- outputFile.seek(0)
- # test that we got some output
- self.assertEqual(1, len(outputFile.read(1)))
-
-
- def test_skipSubcommandList(self):
- """
- Ensure the optimization which skips building the subcommand list
- under certain conditions isn't broken.
- """
- outputFile = StringIO()
- self.patch(usage.Options, '_shellCompFile', outputFile)
- opts = FighterAceOptions()
-
- self.assertRaises(SystemExit, opts.parseOptions,
- ["--alba", "--_shell-completion", "zsh:2"])
- outputFile.seek(0)
- # test that we got some output
- self.assertEqual(1, len(outputFile.read(1)))
-
-
- def test_poorlyDescribedOptMethod(self):
- """
- Test corner case fetching an option description from a method docstring
- """
- opts = FighterAceOptions()
- argGen = _shellcomp.ZshArgumentsGenerator(opts, 'ace', None)
-
- descr = argGen.getDescription('silly')
-
- # docstring for opt_silly is useless so it should just use the
- # option name as the description
- self.assertEqual(descr, 'silly')
-
-
- def test_brokenActions(self):
- """
- A C{Completer} with repeat=True may only be used as the
- last item in the extraActions list.
- """
- class BrokenActions(usage.Options):
- compData = usage.Completions(
- extraActions=[usage.Completer(repeat=True),
- usage.Completer()]
- )
-
- outputFile = StringIO()
- opts = BrokenActions()
- self.patch(opts, '_shellCompFile', outputFile)
- self.assertRaises(ValueError, opts.parseOptions,
- ["", "--_shell-completion", "zsh:2"])
-
-
- def test_optMethodsDontOverride(self):
- """
- opt_* methods on Options classes should not override the
- data provided in optFlags or optParameters.
- """
- class Options(usage.Options):
- optFlags = [['flag', 'f', 'A flag']]
- optParameters = [['param', 'p', None, 'A param']]
-
- def opt_flag(self):
- """ junk description """
-
- def opt_param(self, param):
- """ junk description """
-
- opts = Options()
- argGen = _shellcomp.ZshArgumentsGenerator(opts, 'ace', None)
-
- self.assertEqual(argGen.getDescription('flag'), 'A flag')
- self.assertEqual(argGen.getDescription('param'), 'A param')
-
-
-
-class EscapeTestCase(unittest.TestCase):
- def test_escape(self):
- """
- Verify _shellcomp.escape() function
- """
- esc = _shellcomp.escape
-
- test = "$"
- self.assertEqual(esc(test), "'$'")
-
- test = 'A--\'$"\\`--B'
- self.assertEqual(esc(test), '"A--\'\\$\\"\\\\\\`--B"')
-
-
-
-class CompleterNotImplementedTestCase(unittest.TestCase):
- """
- Test that using an unknown shell constant with SubcommandAction
- raises NotImplementedError
-
- The other Completer() subclasses are tested in test_usage.py
- """
- def test_unknownShell(self):
- """
- Using an unknown shellType should raise NotImplementedError
- """
- action = _shellcomp.SubcommandAction()
-
- self.assertRaises(NotImplementedError, action._shellCode,
- None, "bad_shell_type")
-
-
-
-class FighterAceServerOptions(usage.Options):
- """
- Options for FighterAce 'server' subcommand
- """
- optFlags = [['list-server', None,
- 'List this server with the online FighterAce network']]
- optParameters = [['packets-per-second', None,
- 'Number of update packets to send per second', '20']]
-
-
-
-class FighterAceOptions(usage.Options):
- """
- Command-line options for an imaginary `Fighter Ace` game
- """
- optFlags = [['fokker', 'f',
- 'Select the Fokker Dr.I as your dogfighter aircraft'],
- ['albatros', 'a',
- 'Select the Albatros D-III as your dogfighter aircraft'],
- ['spad', 's',
- 'Select the SPAD S.VII as your dogfighter aircraft'],
- ['bristol', 'b',
- 'Select the Bristol Scout as your dogfighter aircraft'],
- ['physics', 'p',
- 'Enable secret Twisted physics engine'],
- ['jam', 'j',
- 'Enable a small chance that your machine guns will jam!'],
- ['verbose', 'v',
- 'Verbose logging (may be specified more than once)'],
- ]
-
- optParameters = [['pilot-name', None, "What's your name, Ace?",
- 'Manfred von Richthofen'],
- ['detail', 'd',
- 'Select the level of rendering detail (1-5)', '3'],
- ]
-
- subCommands = [['server', None, FighterAceServerOptions,
- 'Start FighterAce game-server.'],
- ]
-
- compData = Completions(
- descriptions={'physics' : 'Twisted-Physics',
- 'detail' : 'Rendering detail level'},
- multiUse=['verbose'],
- mutuallyExclusive=[['fokker', 'albatros', 'spad',
- 'bristol']],
- optActions={'detail' : CompleteList(['1' '2' '3'
- '4' '5'])},
- extraActions=[CompleteFiles(descr='saved game file to load')]
- )
-
- def opt_silly(self):
- # A silly option which nobody can explain
- """ """
-
-
-
-class FighterAceExtendedOptions(FighterAceOptions):
- """
- Extend the options and zsh metadata provided by FighterAceOptions.
- _shellcomp must accumulate options and metadata from all classes in the
- hiearchy so this is important to test.
- """
- optFlags = [['no-stalls', None,
- 'Turn off the ability to stall your aircraft']]
- optParameters = [['reality-level', None,
- 'Select the level of physics reality (1-5)', '5']]
-
- compData = Completions(
- descriptions={'no-stalls' : 'Can\'t stall your plane'},
- optActions={'reality-level' :
- Completer(descr='Physics reality level')}
- )
-
- def opt_nocrash(self):
- """
- Select that you can't crash your plane
- """
-
-
- def opt_difficulty(self, difficulty):
- """
- How tough are you? (1-10)
- """
-
-
-
-def _accuracyAction():
- # add tick marks just to exercise quoting
- return CompleteList(['1', '2', '3'], descr='Accuracy\'`?')
-
-
-
-class SimpleProgOptions(usage.Options):
- """
- Command-line options for a `Silly` imaginary program
- """
- optFlags = [['color', 'c', 'Turn on color output'],
- ['gray', 'g', 'Turn on gray-scale output'],
- ['verbose', 'v',
- 'Verbose logging (may be specified more than once)'],
- ]
-
- optParameters = [['optimization', None, '5',
- 'Select the level of optimization (1-5)'],
- ['accuracy', 'a', '3',
- 'Select the level of accuracy (1-3)'],
- ]
-
-
- compData = Completions(
- descriptions={'color' : 'Color on',
- 'optimization' : 'Optimization level'},
- multiUse=['verbose'],
- mutuallyExclusive=[['color', 'gray']],
- optActions={'optimization' : CompleteList(['1', '2', '3', '4', '5'],
- descr='Optimization?'),
- 'accuracy' : _accuracyAction},
- extraActions=[CompleteFiles(descr='output file')]
- )
-
- def opt_X(self):
- """
- usage.Options does not recognize single-letter opt_ methods
- """
-
-
-
-class SimpleProgSub1(usage.Options):
- optFlags = [['sub-opt', 's', 'Sub Opt One']]
-
-
-
-class SimpleProgSub2(usage.Options):
- optFlags = [['sub-opt', 's', 'Sub Opt Two']]
-
-
-
-class SimpleProgWithSubcommands(SimpleProgOptions):
- optFlags = [['some-option'],
- ['other-option', 'o']]
-
- optParameters = [['some-param'],
- ['other-param', 'p'],
- ['another-param', 'P', 'Yet Another Param']]
-
- subCommands = [ ['sub1', None, SimpleProgSub1, 'Sub Command 1'],
- ['sub2', None, SimpleProgSub2, 'Sub Command 2']]
-
-
-
-testOutput1 = """#compdef silly
-
-_arguments -s -A "-*" \\
-':output file (*):_files -g "*"' \\
-"(--accuracy)-a[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \\
-"(-a)--accuracy=[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \\
-'(--color --gray -g)-c[Color on]' \\
-'(--gray -c -g)--color[Color on]' \\
-'(--color --gray -c)-g[Turn on gray-scale output]' \\
-'(--color -c -g)--gray[Turn on gray-scale output]' \\
-'--help[Display this help and exit.]' \\
-'--optimization=[Optimization level]:Optimization?:(1 2 3 4 5)' \\
-'*-v[Verbose logging (may be specified more than once)]' \\
-'*--verbose[Verbose logging (may be specified more than once)]' \\
-'--version[Display Twisted version and exit.]' \\
-&& return 0
-"""
-
-# with sub-commands
-testOutput2 = """#compdef silly2
-
-_arguments -s -A "-*" \\
-'*::subcmd:->subcmd' \\
-':output file (*):_files -g "*"' \\
-"(--accuracy)-a[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \\
-"(-a)--accuracy=[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \\
-'(--another-param)-P[another-param]:another-param:_files' \\
-'(-P)--another-param=[another-param]:another-param:_files' \\
-'(--color --gray -g)-c[Color on]' \\
-'(--gray -c -g)--color[Color on]' \\
-'(--color --gray -c)-g[Turn on gray-scale output]' \\
-'(--color -c -g)--gray[Turn on gray-scale output]' \\
-'--help[Display this help and exit.]' \\
-'--optimization=[Optimization level]:Optimization?:(1 2 3 4 5)' \\
-'(--other-option)-o[other-option]' \\
-'(-o)--other-option[other-option]' \\
-'(--other-param)-p[other-param]:other-param:_files' \\
-'(-p)--other-param=[other-param]:other-param:_files' \\
-'--some-option[some-option]' \\
-'--some-param=[some-param]:some-param:_files' \\
-'*-v[Verbose logging (may be specified more than once)]' \\
-'*--verbose[Verbose logging (may be specified more than once)]' \\
-'--version[Display Twisted version and exit.]' \\
-&& return 0
-local _zsh_subcmds_array
-_zsh_subcmds_array=(
-"sub1:Sub Command 1"
-"sub2:Sub Command 2"
-)
-
-_describe "sub-command" _zsh_subcmds_array
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_syslog.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_syslog.py
deleted file mode 100755
index 559c62f3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_syslog.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial.unittest import TestCase
-from twisted.python.failure import Failure
-
-try:
- import syslog as stdsyslog
-except ImportError:
- stdsyslog = None
-else:
- from twisted.python import syslog
-
-
-
-class SyslogObserverTests(TestCase):
- """
- Tests for L{SyslogObserver} which sends Twisted log events to the syslog.
- """
- events = None
-
- if stdsyslog is None:
- skip = "syslog is not supported on this platform"
-
- def setUp(self):
- self.patch(syslog.SyslogObserver, 'openlog', self.openlog)
- self.patch(syslog.SyslogObserver, 'syslog', self.syslog)
- self.observer = syslog.SyslogObserver('SyslogObserverTests')
-
-
- def openlog(self, prefix, options, facility):
- self.logOpened = (prefix, options, facility)
- self.events = []
-
-
- def syslog(self, options, message):
- self.events.append((options, message))
-
-
- def test_emitWithoutMessage(self):
- """
- L{SyslogObserver.emit} ignores events with an empty value for the
- C{'message'} key.
- """
- self.observer.emit({'message': (), 'isError': False, 'system': '-'})
- self.assertEqual(self.events, [])
-
-
- def test_emitCustomPriority(self):
- """
- L{SyslogObserver.emit} uses the value of the C{'syslogPriority'} as the
- syslog priority, if that key is present in the event dictionary.
- """
- self.observer.emit({
- 'message': ('hello, world',), 'isError': False, 'system': '-',
- 'syslogPriority': stdsyslog.LOG_DEBUG})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_DEBUG, '[-] hello, world')])
-
-
- def test_emitErrorPriority(self):
- """
- L{SyslogObserver.emit} uses C{LOG_ALERT} if the event represents an
- error.
- """
- self.observer.emit({
- 'message': ('hello, world',), 'isError': True, 'system': '-',
- 'failure': Failure(Exception("foo"))})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_ALERT, '[-] hello, world')])
-
-
- def test_emitCustomPriorityOverridesError(self):
- """
- L{SyslogObserver.emit} uses the value of the C{'syslogPriority'} key if
- it is specified even if the event dictionary represents an error.
- """
- self.observer.emit({
- 'message': ('hello, world',), 'isError': True, 'system': '-',
- 'syslogPriority': stdsyslog.LOG_NOTICE,
- 'failure': Failure(Exception("bar"))})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_NOTICE, '[-] hello, world')])
-
-
- def test_emitCustomFacility(self):
- """
- L{SyslogObserver.emit} uses the value of the C{'syslogPriority'} as the
- syslog priority, if that key is present in the event dictionary.
- """
- self.observer.emit({
- 'message': ('hello, world',), 'isError': False, 'system': '-',
- 'syslogFacility': stdsyslog.LOG_CRON})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_INFO | stdsyslog.LOG_CRON, '[-] hello, world')])
-
-
- def test_emitCustomSystem(self):
- """
- L{SyslogObserver.emit} uses the value of the C{'system'} key to prefix
- the logged message.
- """
- self.observer.emit({'message': ('hello, world',), 'isError': False,
- 'system': 'nonDefaultSystem'})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_INFO, "[nonDefaultSystem] hello, world")])
-
-
- def test_emitMessage(self):
- """
- L{SyslogObserver.emit} logs the value of the C{'message'} key of the
- event dictionary it is passed to the syslog.
- """
- self.observer.emit({
- 'message': ('hello, world',), 'isError': False,
- 'system': '-'})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_INFO, "[-] hello, world")])
-
-
- def test_emitMultilineMessage(self):
- """
- Each line of a multiline message is emitted separately to the syslog.
- """
- self.observer.emit({
- 'message': ('hello,\nworld',), 'isError': False,
- 'system': '-'})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_INFO, '[-] hello,'),
- (stdsyslog.LOG_INFO, '[-] \tworld')])
-
-
- def test_emitStripsTrailingEmptyLines(self):
- """
- Trailing empty lines of a multiline message are omitted from the
- messages sent to the syslog.
- """
- self.observer.emit({
- 'message': ('hello,\nworld\n\n',), 'isError': False,
- 'system': '-'})
- self.assertEqual(
- self.events,
- [(stdsyslog.LOG_INFO, '[-] hello,'),
- (stdsyslog.LOG_INFO, '[-] \tworld')])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_systemd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_systemd.py
deleted file mode 100755
index 23d590f9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_systemd.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.systemd}.
-"""
-
-import os
-
-from twisted.trial.unittest import TestCase
-from twisted.python.systemd import ListenFDs
-
-
-class InheritedDescriptorsMixin(object):
- """
- Mixin for a L{TestCase} subclass which defines test methods for some kind of
- systemd sd-daemon class. In particular, it defines tests for a
- C{inheritedDescriptors} method.
- """
- def test_inheritedDescriptors(self):
- """
- C{inheritedDescriptors} returns a list of integers giving the file
- descriptors which were inherited from systemd.
- """
- sddaemon = self.getDaemon(7, 3)
- self.assertEqual([7, 8, 9], sddaemon.inheritedDescriptors())
-
-
- def test_repeated(self):
- """
- Any subsequent calls to C{inheritedDescriptors} return the same list.
- """
- sddaemon = self.getDaemon(7, 3)
- self.assertEqual(
- sddaemon.inheritedDescriptors(),
- sddaemon.inheritedDescriptors())
-
-
-
-class MemoryOnlyMixin(object):
- """
- Mixin for a L{TestCase} subclass which creates creating a fake, in-memory
- implementation of C{inheritedDescriptors}. This provides verification that
- the fake behaves in a compatible way with the real implementation.
- """
- def getDaemon(self, start, count):
- """
- Invent C{count} new I{file descriptors} (actually integers, attached to
- no real file description), starting at C{start}. Construct and return a
- new L{ListenFDs} which will claim those integers represent inherited
- file descriptors.
- """
- return ListenFDs(range(start, start + count))
-
-
-
-class EnvironmentMixin(object):
- """
- Mixin for a L{TestCase} subclass which creates a real implementation of
- C{inheritedDescriptors} which is based on the environment variables set by
- systemd. To facilitate testing, this mixin will also create a fake
- environment dictionary and add keys to it to make it look as if some
- descriptors have been inherited.
- """
- def initializeEnvironment(self, count, pid):
- """
- Create a copy of the process environment and add I{LISTEN_FDS} and
- I{LISTEN_PID} (the environment variables set by systemd) to it.
- """
- result = os.environ.copy()
- result['LISTEN_FDS'] = str(count)
- result['LISTEN_PID'] = str(pid)
- return result
-
-
- def getDaemon(self, start, count):
- """
- Create a new L{ListenFDs} instance, initialized with a fake environment
- dictionary which will be set up as systemd would have set it up if
- C{count} descriptors were being inherited. The descriptors will also
- start at C{start}.
- """
- fakeEnvironment = self.initializeEnvironment(count, os.getpid())
- return ListenFDs.fromEnvironment(environ=fakeEnvironment, start=start)
-
-
-
-class MemoryOnlyTests(MemoryOnlyMixin, InheritedDescriptorsMixin, TestCase):
- """
- Apply tests to L{ListenFDs}, explicitly constructed with some fake file
- descriptors.
- """
-
-
-
-class EnvironmentTests(EnvironmentMixin, InheritedDescriptorsMixin, TestCase):
- """
- Apply tests to L{ListenFDs}, constructed based on an environment dictionary.
- """
- def test_secondEnvironment(self):
- """
- Only a single L{Environment} can extract inherited file descriptors.
- """
- fakeEnvironment = self.initializeEnvironment(3, os.getpid())
- first = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- second = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- self.assertEqual(range(3, 6), first.inheritedDescriptors())
- self.assertEqual([], second.inheritedDescriptors())
-
-
- def test_mismatchedPID(self):
- """
- If the current process PID does not match the PID in the environment, no
- inherited descriptors are reported.
- """
- fakeEnvironment = self.initializeEnvironment(3, os.getpid() + 1)
- sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- self.assertEqual([], sddaemon.inheritedDescriptors())
-
-
- def test_missingPIDVariable(self):
- """
- If the I{LISTEN_PID} environment variable is not present, no inherited
- descriptors are reported.
- """
- fakeEnvironment = self.initializeEnvironment(3, os.getpid())
- del fakeEnvironment['LISTEN_PID']
- sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- self.assertEqual([], sddaemon.inheritedDescriptors())
-
-
- def test_nonIntegerPIDVariable(self):
- """
- If the I{LISTEN_PID} environment variable is set to a string that cannot
- be parsed as an integer, no inherited descriptors are reported.
- """
- fakeEnvironment = self.initializeEnvironment(3, "hello, world")
- sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- self.assertEqual([], sddaemon.inheritedDescriptors())
-
-
- def test_missingFDSVariable(self):
- """
- If the I{LISTEN_FDS} environment variable is not present, no inherited
- descriptors are reported.
- """
- fakeEnvironment = self.initializeEnvironment(3, os.getpid())
- del fakeEnvironment['LISTEN_FDS']
- sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- self.assertEqual([], sddaemon.inheritedDescriptors())
-
-
- def test_nonIntegerFDSVariable(self):
- """
- If the I{LISTEN_FDS} environment variable is set to a string that cannot
- be parsed as an integer, no inherited descriptors are reported.
- """
- fakeEnvironment = self.initializeEnvironment("hello, world", os.getpid())
- sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment)
- self.assertEqual([], sddaemon.inheritedDescriptors())
-
-
- def test_defaultEnviron(self):
- """
- If the process environment is not explicitly passed to
- L{Environment.__init__}, the real process environment dictionary is
- used.
- """
- self.patch(os, 'environ', {
- 'LISTEN_PID': str(os.getpid()),
- 'LISTEN_FDS': '5'})
- sddaemon = ListenFDs.fromEnvironment()
- self.assertEqual(range(3, 3 + 5), sddaemon.inheritedDescriptors())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_util.py
deleted file mode 100755
index 08c39d65..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_util.py
+++ /dev/null
@@ -1,928 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_util
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.util}.
-"""
-
-import os.path, sys
-import shutil, errno
-try:
- import pwd, grp
-except ImportError:
- pwd = grp = None
-
-from twisted.trial import unittest
-
-from twisted.python import util
-from twisted.internet import reactor
-from twisted.internet.interfaces import IReactorProcess
-from twisted.internet.protocol import ProcessProtocol
-from twisted.internet.defer import Deferred
-from twisted.internet.error import ProcessDone
-
-from twisted.test.test_process import MockOS
-
-
-
-class UtilTestCase(unittest.TestCase):
-
- def testUniq(self):
- l = ["a", 1, "ab", "a", 3, 4, 1, 2, 2, 4, 6]
- self.assertEqual(util.uniquify(l), ["a", 1, "ab", 3, 4, 2, 6])
-
- def testRaises(self):
- self.failUnless(util.raises(ZeroDivisionError, divmod, 1, 0))
- self.failIf(util.raises(ZeroDivisionError, divmod, 0, 1))
-
- try:
- util.raises(TypeError, divmod, 1, 0)
- except ZeroDivisionError:
- pass
- else:
- raise unittest.FailTest, "util.raises didn't raise when it should have"
-
- def testUninterruptably(self):
- def f(a, b):
- self.calls += 1
- exc = self.exceptions.pop()
- if exc is not None:
- raise exc(errno.EINTR, "Interrupted system call!")
- return a + b
-
- self.exceptions = [None]
- self.calls = 0
- self.assertEqual(util.untilConcludes(f, 1, 2), 3)
- self.assertEqual(self.calls, 1)
-
- self.exceptions = [None, OSError, IOError]
- self.calls = 0
- self.assertEqual(util.untilConcludes(f, 2, 3), 5)
- self.assertEqual(self.calls, 3)
-
- def testNameToLabel(self):
- """
- Test the various kinds of inputs L{nameToLabel} supports.
- """
- nameData = [
- ('f', 'F'),
- ('fo', 'Fo'),
- ('foo', 'Foo'),
- ('fooBar', 'Foo Bar'),
- ('fooBarBaz', 'Foo Bar Baz'),
- ]
- for inp, out in nameData:
- got = util.nameToLabel(inp)
- self.assertEqual(
- got, out,
- "nameToLabel(%r) == %r != %r" % (inp, got, out))
-
-
- def test_uidFromNumericString(self):
- """
- When L{uidFromString} is called with a base-ten string representation
- of an integer, it returns the integer.
- """
- self.assertEqual(util.uidFromString("100"), 100)
-
-
- def test_uidFromUsernameString(self):
- """
- When L{uidFromString} is called with a base-ten string representation
- of an integer, it returns the integer.
- """
- pwent = pwd.getpwuid(os.getuid())
- self.assertEqual(util.uidFromString(pwent.pw_name), pwent.pw_uid)
- if pwd is None:
- test_uidFromUsernameString.skip = (
- "Username/UID conversion requires the pwd module.")
-
-
- def test_gidFromNumericString(self):
- """
- When L{gidFromString} is called with a base-ten string representation
- of an integer, it returns the integer.
- """
- self.assertEqual(util.gidFromString("100"), 100)
-
-
- def test_gidFromGroupnameString(self):
- """
- When L{gidFromString} is called with a base-ten string representation
- of an integer, it returns the integer.
- """
- grent = grp.getgrgid(os.getgid())
- self.assertEqual(util.gidFromString(grent.gr_name), grent.gr_gid)
- if grp is None:
- test_gidFromGroupnameString.skip = (
- "Group Name/GID conversion requires the grp module.")
-
-
-
-class SwitchUIDTest(unittest.TestCase):
- """
- Tests for L{util.switchUID}.
- """
-
- if getattr(os, "getuid", None) is None:
- skip = "getuid/setuid not available"
-
-
- def setUp(self):
- self.mockos = MockOS()
- self.patch(util, "os", self.mockos)
- self.patch(util, "initgroups", self.initgroups)
- self.initgroupsCalls = []
-
-
- def initgroups(self, uid, gid):
- """
- Save L{util.initgroups} calls in C{self.initgroupsCalls}.
- """
- self.initgroupsCalls.append((uid, gid))
-
-
- def test_uid(self):
- """
- L{util.switchUID} calls L{util.initgroups} and then C{os.setuid} with
- the given uid.
- """
- util.switchUID(12000, None)
- self.assertEqual(self.initgroupsCalls, [(12000, None)])
- self.assertEqual(self.mockos.actions, [("setuid", 12000)])
-
-
- def test_euid(self):
- """
- L{util.switchUID} calls L{util.initgroups} and then C{os.seteuid} with
- the given uid if the C{euid} parameter is set to C{True}.
- """
- util.switchUID(12000, None, True)
- self.assertEqual(self.initgroupsCalls, [(12000, None)])
- self.assertEqual(self.mockos.seteuidCalls, [12000])
-
-
- def test_currentUID(self):
- """
- If the current uid is the same as the uid passed to L{util.switchUID},
- then initgroups does not get called, but a warning is issued.
- """
- uid = self.mockos.getuid()
- util.switchUID(uid, None)
- self.assertEqual(self.initgroupsCalls, [])
- self.assertEqual(self.mockos.actions, [])
- warnings = self.flushWarnings([util.switchUID])
- self.assertEqual(len(warnings), 1)
- self.assertIn('tried to drop privileges and setuid %i' % uid,
- warnings[0]['message'])
- self.assertIn('but uid is already %i' % uid, warnings[0]['message'])
-
-
- def test_currentEUID(self):
- """
- If the current euid is the same as the euid passed to L{util.switchUID},
- then initgroups does not get called, but a warning is issued.
- """
- euid = self.mockos.geteuid()
- util.switchUID(euid, None, True)
- self.assertEqual(self.initgroupsCalls, [])
- self.assertEqual(self.mockos.seteuidCalls, [])
- warnings = self.flushWarnings([util.switchUID])
- self.assertEqual(len(warnings), 1)
- self.assertIn('tried to drop privileges and seteuid %i' % euid,
- warnings[0]['message'])
- self.assertIn('but euid is already %i' % euid, warnings[0]['message'])
-
-
-
-class TestMergeFunctionMetadata(unittest.TestCase):
- """
- Tests for L{mergeFunctionMetadata}.
- """
-
- def test_mergedFunctionBehavesLikeMergeTarget(self):
- """
- After merging C{foo}'s data into C{bar}, the returned function behaves
- as if it is C{bar}.
- """
- foo_object = object()
- bar_object = object()
-
- def foo():
- return foo_object
-
- def bar(x, y, (a, b), c=10, *d, **e):
- return bar_object
-
- baz = util.mergeFunctionMetadata(foo, bar)
- self.assertIdentical(baz(1, 2, (3, 4), quux=10), bar_object)
-
-
- def test_moduleIsMerged(self):
- """
- Merging C{foo} into C{bar} returns a function with C{foo}'s
- C{__module__}.
- """
- def foo():
- pass
-
- def bar():
- pass
- bar.__module__ = 'somewhere.else'
-
- baz = util.mergeFunctionMetadata(foo, bar)
- self.assertEqual(baz.__module__, foo.__module__)
-
-
- def test_docstringIsMerged(self):
- """
- Merging C{foo} into C{bar} returns a function with C{foo}'s docstring.
- """
-
- def foo():
- """
- This is foo.
- """
-
- def bar():
- """
- This is bar.
- """
-
- baz = util.mergeFunctionMetadata(foo, bar)
- self.assertEqual(baz.__doc__, foo.__doc__)
-
-
- def test_nameIsMerged(self):
- """
- Merging C{foo} into C{bar} returns a function with C{foo}'s name.
- """
-
- def foo():
- pass
-
- def bar():
- pass
-
- baz = util.mergeFunctionMetadata(foo, bar)
- self.assertEqual(baz.__name__, foo.__name__)
-
-
- def test_instanceDictionaryIsMerged(self):
- """
- Merging C{foo} into C{bar} returns a function with C{bar}'s
- dictionary, updated by C{foo}'s.
- """
-
- def foo():
- pass
- foo.a = 1
- foo.b = 2
-
- def bar():
- pass
- bar.b = 3
- bar.c = 4
-
- baz = util.mergeFunctionMetadata(foo, bar)
- self.assertEqual(foo.a, baz.a)
- self.assertEqual(foo.b, baz.b)
- self.assertEqual(bar.c, baz.c)
-
-
-
-class OrderedDictTest(unittest.TestCase):
- def testOrderedDict(self):
- d = util.OrderedDict()
- d['a'] = 'b'
- d['b'] = 'a'
- d[3] = 12
- d[1234] = 4321
- self.assertEqual(repr(d), "{'a': 'b', 'b': 'a', 3: 12, 1234: 4321}")
- self.assertEqual(d.values(), ['b', 'a', 12, 4321])
- del d[3]
- self.assertEqual(repr(d), "{'a': 'b', 'b': 'a', 1234: 4321}")
- self.assertEqual(d, {'a': 'b', 'b': 'a', 1234:4321})
- self.assertEqual(d.keys(), ['a', 'b', 1234])
- self.assertEqual(list(d.iteritems()),
- [('a', 'b'), ('b','a'), (1234, 4321)])
- item = d.popitem()
- self.assertEqual(item, (1234, 4321))
-
- def testInitialization(self):
- d = util.OrderedDict({'monkey': 'ook',
- 'apple': 'red'})
- self.failUnless(d._order)
-
- d = util.OrderedDict(((1,1),(3,3),(2,2),(0,0)))
- self.assertEqual(repr(d), "{1: 1, 3: 3, 2: 2, 0: 0}")
-
-class InsensitiveDictTest(unittest.TestCase):
- def testPreserve(self):
- InsensitiveDict=util.InsensitiveDict
- dct=InsensitiveDict({'Foo':'bar', 1:2, 'fnz':{1:2}}, preserve=1)
- self.assertEqual(dct['fnz'], {1:2})
- self.assertEqual(dct['foo'], 'bar')
- self.assertEqual(dct.copy(), dct)
- self.assertEqual(dct['foo'], dct.get('Foo'))
- assert 1 in dct and 'foo' in dct
- self.assertEqual(eval(repr(dct)), dct)
- keys=['Foo', 'fnz', 1]
- for x in keys:
- assert x in dct.keys()
- assert (x, dct[x]) in dct.items()
- self.assertEqual(len(keys), len(dct))
- del dct[1]
- del dct['foo']
-
- def testNoPreserve(self):
- InsensitiveDict=util.InsensitiveDict
- dct=InsensitiveDict({'Foo':'bar', 1:2, 'fnz':{1:2}}, preserve=0)
- keys=['foo', 'fnz', 1]
- for x in keys:
- assert x in dct.keys()
- assert (x, dct[x]) in dct.items()
- self.assertEqual(len(keys), len(dct))
- del dct[1]
- del dct['foo']
-
-
-
-
-class PasswordTestingProcessProtocol(ProcessProtocol):
- """
- Write the string C{"secret\n"} to a subprocess and then collect all of
- its output and fire a Deferred with it when the process ends.
- """
- def connectionMade(self):
- self.output = []
- self.transport.write('secret\n')
-
- def childDataReceived(self, fd, output):
- self.output.append((fd, output))
-
- def processEnded(self, reason):
- self.finished.callback((reason, self.output))
-
-
-class GetPasswordTest(unittest.TestCase):
- if not IReactorProcess.providedBy(reactor):
- skip = "Process support required to test getPassword"
-
- def test_stdin(self):
- """
- Making sure getPassword accepts a password from standard input by
- running a child process which uses getPassword to read in a string
- which it then writes it out again. Write a string to the child
- process and then read one and make sure it is the right string.
- """
- p = PasswordTestingProcessProtocol()
- p.finished = Deferred()
- reactor.spawnProcess(
- p,
- sys.executable,
- [sys.executable,
- '-c',
- ('import sys\n'
- 'from twisted.python.util import getPassword\n'
- 'sys.stdout.write(getPassword())\n'
- 'sys.stdout.flush()\n')],
- env={'PYTHONPATH': os.pathsep.join(sys.path)})
-
- def processFinished((reason, output)):
- reason.trap(ProcessDone)
- self.assertIn((1, 'secret'), output)
-
- return p.finished.addCallback(processFinished)
-
-
-
-class SearchUpwardsTest(unittest.TestCase):
- def testSearchupwards(self):
- os.makedirs('searchupwards/a/b/c')
- file('searchupwards/foo.txt', 'w').close()
- file('searchupwards/a/foo.txt', 'w').close()
- file('searchupwards/a/b/c/foo.txt', 'w').close()
- os.mkdir('searchupwards/bar')
- os.mkdir('searchupwards/bam')
- os.mkdir('searchupwards/a/bar')
- os.mkdir('searchupwards/a/b/bam')
- actual=util.searchupwards('searchupwards/a/b/c',
- files=['foo.txt'],
- dirs=['bar', 'bam'])
- expected=os.path.abspath('searchupwards') + os.sep
- self.assertEqual(actual, expected)
- shutil.rmtree('searchupwards')
- actual=util.searchupwards('searchupwards/a/b/c',
- files=['foo.txt'],
- dirs=['bar', 'bam'])
- expected=None
- self.assertEqual(actual, expected)
-
-
-
-class IntervalDifferentialTestCase(unittest.TestCase):
- def testDefault(self):
- d = iter(util.IntervalDifferential([], 10))
- for i in range(100):
- self.assertEqual(d.next(), (10, None))
-
- def testSingle(self):
- d = iter(util.IntervalDifferential([5], 10))
- for i in range(100):
- self.assertEqual(d.next(), (5, 0))
-
- def testPair(self):
- d = iter(util.IntervalDifferential([5, 7], 10))
- for i in range(100):
- self.assertEqual(d.next(), (5, 0))
- self.assertEqual(d.next(), (2, 1))
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (4, 1))
- self.assertEqual(d.next(), (1, 0))
- self.assertEqual(d.next(), (5, 0))
- self.assertEqual(d.next(), (1, 1))
- self.assertEqual(d.next(), (4, 0))
- self.assertEqual(d.next(), (3, 1))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (5, 0))
- self.assertEqual(d.next(), (0, 1))
-
- def testTriple(self):
- d = iter(util.IntervalDifferential([2, 4, 5], 10))
- for i in range(100):
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (0, 1))
- self.assertEqual(d.next(), (1, 2))
- self.assertEqual(d.next(), (1, 0))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (0, 1))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (0, 2))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (0, 1))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (1, 2))
- self.assertEqual(d.next(), (1, 0))
- self.assertEqual(d.next(), (0, 1))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (2, 0))
- self.assertEqual(d.next(), (0, 1))
- self.assertEqual(d.next(), (0, 2))
-
- def testInsert(self):
- d = iter(util.IntervalDifferential([], 10))
- self.assertEqual(d.next(), (10, None))
- d.addInterval(3)
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (3, 0))
- d.addInterval(6)
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (0, 1))
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (0, 1))
-
- def testRemove(self):
- d = iter(util.IntervalDifferential([3, 5], 10))
- self.assertEqual(d.next(), (3, 0))
- self.assertEqual(d.next(), (2, 1))
- self.assertEqual(d.next(), (1, 0))
- d.removeInterval(3)
- self.assertEqual(d.next(), (4, 0))
- self.assertEqual(d.next(), (5, 0))
- d.removeInterval(5)
- self.assertEqual(d.next(), (10, None))
- self.assertRaises(ValueError, d.removeInterval, 10)
-
-
-
-class Record(util.FancyEqMixin):
- """
- Trivial user of L{FancyEqMixin} used by tests.
- """
- compareAttributes = ('a', 'b')
-
- def __init__(self, a, b):
- self.a = a
- self.b = b
-
-
-
-class DifferentRecord(util.FancyEqMixin):
- """
- Trivial user of L{FancyEqMixin} which is not related to L{Record}.
- """
- compareAttributes = ('a', 'b')
-
- def __init__(self, a, b):
- self.a = a
- self.b = b
-
-
-
-class DerivedRecord(Record):
- """
- A class with an inheritance relationship to L{Record}.
- """
-
-
-
-class EqualToEverything(object):
- """
- A class the instances of which consider themselves equal to everything.
- """
- def __eq__(self, other):
- return True
-
-
- def __ne__(self, other):
- return False
-
-
-
-class EqualToNothing(object):
- """
- A class the instances of which consider themselves equal to nothing.
- """
- def __eq__(self, other):
- return False
-
-
- def __ne__(self, other):
- return True
-
-
-
-class EqualityTests(unittest.TestCase):
- """
- Tests for L{FancyEqMixin}.
- """
- def test_identity(self):
- """
- Instances of a class which mixes in L{FancyEqMixin} but which
- defines no comparison attributes compare by identity.
- """
- class Empty(util.FancyEqMixin):
- pass
-
- self.assertFalse(Empty() == Empty())
- self.assertTrue(Empty() != Empty())
- empty = Empty()
- self.assertTrue(empty == empty)
- self.assertFalse(empty != empty)
-
-
- def test_equality(self):
- """
- Instances of a class which mixes in L{FancyEqMixin} should compare
- equal if all of their attributes compare equal. They should not
- compare equal if any of their attributes do not compare equal.
- """
- self.assertTrue(Record(1, 2) == Record(1, 2))
- self.assertFalse(Record(1, 2) == Record(1, 3))
- self.assertFalse(Record(1, 2) == Record(2, 2))
- self.assertFalse(Record(1, 2) == Record(3, 4))
-
-
- def test_unequality(self):
- """
- Unequality between instances of a particular L{record} should be
- defined as the negation of equality.
- """
- self.assertFalse(Record(1, 2) != Record(1, 2))
- self.assertTrue(Record(1, 2) != Record(1, 3))
- self.assertTrue(Record(1, 2) != Record(2, 2))
- self.assertTrue(Record(1, 2) != Record(3, 4))
-
-
- def test_differentClassesEquality(self):
- """
- Instances of different classes which mix in L{FancyEqMixin} should not
- compare equal.
- """
- self.assertFalse(Record(1, 2) == DifferentRecord(1, 2))
-
-
- def test_differentClassesInequality(self):
- """
- Instances of different classes which mix in L{FancyEqMixin} should
- compare unequal.
- """
- self.assertTrue(Record(1, 2) != DifferentRecord(1, 2))
-
-
- def test_inheritedClassesEquality(self):
- """
- An instance of a class which derives from a class which mixes in
- L{FancyEqMixin} should compare equal to an instance of the base class
- if and only if all of their attributes compare equal.
- """
- self.assertTrue(Record(1, 2) == DerivedRecord(1, 2))
- self.assertFalse(Record(1, 2) == DerivedRecord(1, 3))
- self.assertFalse(Record(1, 2) == DerivedRecord(2, 2))
- self.assertFalse(Record(1, 2) == DerivedRecord(3, 4))
-
-
- def test_inheritedClassesInequality(self):
- """
- An instance of a class which derives from a class which mixes in
- L{FancyEqMixin} should compare unequal to an instance of the base
- class if any of their attributes compare unequal.
- """
- self.assertFalse(Record(1, 2) != DerivedRecord(1, 2))
- self.assertTrue(Record(1, 2) != DerivedRecord(1, 3))
- self.assertTrue(Record(1, 2) != DerivedRecord(2, 2))
- self.assertTrue(Record(1, 2) != DerivedRecord(3, 4))
-
-
- def test_rightHandArgumentImplementsEquality(self):
- """
- The right-hand argument to the equality operator is given a chance
- to determine the result of the operation if it is of a type
- unrelated to the L{FancyEqMixin}-based instance on the left-hand
- side.
- """
- self.assertTrue(Record(1, 2) == EqualToEverything())
- self.assertFalse(Record(1, 2) == EqualToNothing())
-
-
- def test_rightHandArgumentImplementsUnequality(self):
- """
- The right-hand argument to the non-equality operator is given a
- chance to determine the result of the operation if it is of a type
- unrelated to the L{FancyEqMixin}-based instance on the left-hand
- side.
- """
- self.assertFalse(Record(1, 2) != EqualToEverything())
- self.assertTrue(Record(1, 2) != EqualToNothing())
-
-
-
-class RunAsEffectiveUserTests(unittest.TestCase):
- """
- Test for the L{util.runAsEffectiveUser} function.
- """
-
- if getattr(os, "geteuid", None) is None:
- skip = "geteuid/seteuid not available"
-
- def setUp(self):
- self.mockos = MockOS()
- self.patch(os, "geteuid", self.mockos.geteuid)
- self.patch(os, "getegid", self.mockos.getegid)
- self.patch(os, "seteuid", self.mockos.seteuid)
- self.patch(os, "setegid", self.mockos.setegid)
-
-
- def _securedFunction(self, startUID, startGID, wantUID, wantGID):
- """
- Check if wanted UID/GID matched start or saved ones.
- """
- self.assertTrue(wantUID == startUID or
- wantUID == self.mockos.seteuidCalls[-1])
- self.assertTrue(wantGID == startGID or
- wantGID == self.mockos.setegidCalls[-1])
-
-
- def test_forwardResult(self):
- """
- L{util.runAsEffectiveUser} forwards the result obtained by calling the
- given function
- """
- result = util.runAsEffectiveUser(0, 0, lambda: 1)
- self.assertEqual(result, 1)
-
-
- def test_takeParameters(self):
- """
- L{util.runAsEffectiveUser} pass the given parameters to the given
- function.
- """
- result = util.runAsEffectiveUser(0, 0, lambda x: 2*x, 3)
- self.assertEqual(result, 6)
-
-
- def test_takesKeyworkArguments(self):
- """
- L{util.runAsEffectiveUser} pass the keyword parameters to the given
- function.
- """
- result = util.runAsEffectiveUser(0, 0, lambda x, y=1, z=1: x*y*z, 2, z=3)
- self.assertEqual(result, 6)
-
-
- def _testUIDGIDSwitch(self, startUID, startGID, wantUID, wantGID,
- expectedUIDSwitches, expectedGIDSwitches):
- """
- Helper method checking the calls to C{os.seteuid} and C{os.setegid}
- made by L{util.runAsEffectiveUser}, when switching from startUID to
- wantUID and from startGID to wantGID.
- """
- self.mockos.euid = startUID
- self.mockos.egid = startGID
- util.runAsEffectiveUser(
- wantUID, wantGID,
- self._securedFunction, startUID, startGID, wantUID, wantGID)
- self.assertEqual(self.mockos.seteuidCalls, expectedUIDSwitches)
- self.assertEqual(self.mockos.setegidCalls, expectedGIDSwitches)
- self.mockos.seteuidCalls = []
- self.mockos.setegidCalls = []
-
-
- def test_root(self):
- """
- Check UID/GID switches when current effective UID is root.
- """
- self._testUIDGIDSwitch(0, 0, 0, 0, [], [])
- self._testUIDGIDSwitch(0, 0, 1, 0, [1, 0], [])
- self._testUIDGIDSwitch(0, 0, 0, 1, [], [1, 0])
- self._testUIDGIDSwitch(0, 0, 1, 1, [1, 0], [1, 0])
-
-
- def test_UID(self):
- """
- Check UID/GID switches when current effective UID is non-root.
- """
- self._testUIDGIDSwitch(1, 0, 0, 0, [0, 1], [])
- self._testUIDGIDSwitch(1, 0, 1, 0, [], [])
- self._testUIDGIDSwitch(1, 0, 1, 1, [0, 1, 0, 1], [1, 0])
- self._testUIDGIDSwitch(1, 0, 2, 1, [0, 2, 0, 1], [1, 0])
-
-
- def test_GID(self):
- """
- Check UID/GID switches when current effective GID is non-root.
- """
- self._testUIDGIDSwitch(0, 1, 0, 0, [], [0, 1])
- self._testUIDGIDSwitch(0, 1, 0, 1, [], [])
- self._testUIDGIDSwitch(0, 1, 1, 1, [1, 0], [])
- self._testUIDGIDSwitch(0, 1, 1, 2, [1, 0], [2, 1])
-
-
- def test_UIDGID(self):
- """
- Check UID/GID switches when current effective UID/GID is non-root.
- """
- self._testUIDGIDSwitch(1, 1, 0, 0, [0, 1], [0, 1])
- self._testUIDGIDSwitch(1, 1, 0, 1, [0, 1], [])
- self._testUIDGIDSwitch(1, 1, 1, 0, [0, 1, 0, 1], [0, 1])
- self._testUIDGIDSwitch(1, 1, 1, 1, [], [])
- self._testUIDGIDSwitch(1, 1, 2, 1, [0, 2, 0, 1], [])
- self._testUIDGIDSwitch(1, 1, 1, 2, [0, 1, 0, 1], [2, 1])
- self._testUIDGIDSwitch(1, 1, 2, 2, [0, 2, 0, 1], [2, 1])
-
-
-
-class UnsignedIDTests(unittest.TestCase):
- """
- Tests for L{util.unsignedID} and L{util.setIDFunction}.
- """
- def setUp(self):
- """
- Save the value of L{util._idFunction} and arrange for it to be restored
- after the test runs.
- """
- self.addCleanup(setattr, util, '_idFunction', util._idFunction)
-
-
- def test_setIDFunction(self):
- """
- L{util.setIDFunction} returns the last value passed to it.
- """
- value = object()
- previous = util.setIDFunction(value)
- result = util.setIDFunction(previous)
- self.assertIdentical(value, result)
-
-
- def test_unsignedID(self):
- """
- L{util.unsignedID} uses the function passed to L{util.setIDFunction} to
- determine the unique integer id of an object and then adjusts it to be
- positive if necessary.
- """
- foo = object()
- bar = object()
-
- # A fake object identity mapping
- objects = {foo: 17, bar: -73}
- def fakeId(obj):
- return objects[obj]
-
- util.setIDFunction(fakeId)
-
- self.assertEqual(util.unsignedID(foo), 17)
- self.assertEqual(util.unsignedID(bar), (sys.maxint + 1) * 2 - 73)
-
-
- def test_defaultIDFunction(self):
- """
- L{util.unsignedID} uses the built in L{id} by default.
- """
- obj = object()
- idValue = id(obj)
- if idValue < 0:
- idValue += (sys.maxint + 1) * 2
-
- self.assertEqual(util.unsignedID(obj), idValue)
-
-
-
-class InitGroupsTests(unittest.TestCase):
- """
- Tests for L{util.initgroups}.
- """
-
- if pwd is None:
- skip = "pwd not available"
-
-
- def setUp(self):
- self.addCleanup(setattr, util, "_c_initgroups", util._c_initgroups)
- self.addCleanup(setattr, util, "setgroups", util.setgroups)
-
-
- def test_initgroupsForceC(self):
- """
- If we fake the presence of the C extension, it's called instead of the
- Python implementation.
- """
- calls = []
- util._c_initgroups = lambda x, y: calls.append((x, y))
- setgroupsCalls = []
- util.setgroups = calls.append
-
- util.initgroups(os.getuid(), 4)
- self.assertEqual(calls, [(pwd.getpwuid(os.getuid())[0], 4)])
- self.assertFalse(setgroupsCalls)
-
-
- def test_initgroupsForcePython(self):
- """
- If we fake the absence of the C extension, the Python implementation is
- called instead, calling C{os.setgroups}.
- """
- util._c_initgroups = None
- calls = []
- util.setgroups = calls.append
- util.initgroups(os.getuid(), os.getgid())
- # Something should be in the calls, we don't really care what
- self.assertTrue(calls)
-
-
- def test_initgroupsInC(self):
- """
- If the C extension is present, it's called instead of the Python
- version. We check that by making sure C{os.setgroups} is not called.
- """
- calls = []
- util.setgroups = calls.append
- try:
- util.initgroups(os.getuid(), os.getgid())
- except OSError:
- pass
- self.assertFalse(calls)
-
-
- if util._c_initgroups is None:
- test_initgroupsInC.skip = "C initgroups not available"
-
-
-class DeprecationTests(unittest.TestCase):
- """
- Tests for deprecations in C{twisted.python.util}.
- """
- def test_getPluginDirs(self):
- """
- L{util.getPluginDirs} is deprecated.
- """
- util.getPluginDirs()
- warnings = self.flushWarnings(offendingFunctions=[
- self.test_getPluginDirs])
- self.assertEqual(
- warnings[0]['message'],
- "twisted.python.util.getPluginDirs is deprecated since Twisted "
- "12.2.")
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(len(warnings), 1)
-
-
- def test_addPluginDir(self):
- """
- L{util.addPluginDir} is deprecated.
- """
- util.addPluginDir()
- warnings = self.flushWarnings(offendingFunctions=[
- self.test_addPluginDir])
- self.assertEqual(
- warnings[0]['message'],
- "twisted.python.util.addPluginDir is deprecated since Twisted "
- "12.2.")
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(len(warnings), 1)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_versions.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_versions.py
deleted file mode 100755
index 79388cfa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_versions.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys
-from cStringIO import StringIO
-
-from twisted.python.versions import getVersionString, IncomparableVersions
-from twisted.python.versions import Version, _inf
-from twisted.python.filepath import FilePath
-
-from twisted.trial import unittest
-
-
-
-VERSION_4_ENTRIES = """\
-<?xml version="1.0" encoding="utf-8"?>
-<wc-entries
- xmlns="svn:">
-<entry
- committed-rev="18210"
- name=""
- committed-date="2006-09-21T04:43:09.542953Z"
- url="svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk/twisted"
- last-author="exarkun"
- kind="dir"
- uuid="bbbe8e31-12d6-0310-92fd-ac37d47ddeeb"
- repos="svn+ssh://svn.twistedmatrix.com/svn/Twisted"
- revision="18211"/>
-</wc-entries>
-"""
-
-
-
-VERSION_8_ENTRIES = """\
-8
-
-dir
-22715
-svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk
-"""
-
-
-VERSION_9_ENTRIES = """\
-9
-
-dir
-22715
-svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk
-"""
-
-
-VERSION_10_ENTRIES = """\
-10
-
-dir
-22715
-svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk
-"""
-
-
-class VersionsTest(unittest.TestCase):
-
- def test_versionComparison(self):
- """
- Versions can be compared for equality and order.
- """
- va = Version("dummy", 1, 0, 0)
- vb = Version("dummy", 0, 1, 0)
- self.failUnless(va > vb)
- self.failUnless(vb < va)
- self.failUnless(va >= vb)
- self.failUnless(vb <= va)
- self.failUnless(va != vb)
- self.failUnless(vb == Version("dummy", 0, 1, 0))
- self.failUnless(vb == vb)
-
- # BREAK IT DOWN@!!
- self.failIf(va < vb)
- self.failIf(vb > va)
- self.failIf(va <= vb)
- self.failIf(vb >= va)
- self.failIf(va == vb)
- self.failIf(vb != Version("dummy", 0, 1, 0))
- self.failIf(vb != vb)
-
-
- def test_comparingPrereleasesWithReleases(self):
- """
- Prereleases are always less than versions without prereleases.
- """
- va = Version("whatever", 1, 0, 0, prerelease=1)
- vb = Version("whatever", 1, 0, 0)
- self.assertTrue(va < vb)
- self.assertFalse(va > vb)
- self.assertNotEquals(vb, va)
-
-
- def test_comparingPrereleases(self):
- """
- The value specified as the prerelease is used in version comparisons.
- """
- va = Version("whatever", 1, 0, 0, prerelease=1)
- vb = Version("whatever", 1, 0, 0, prerelease=2)
- self.assertTrue(va < vb)
- self.assertFalse(va > vb)
- self.assertNotEqual(va, vb)
-
-
- def test_infComparison(self):
- """
- L{_inf} is equal to L{_inf}.
-
- This is a regression test.
- """
- self.assertEqual(_inf, _inf)
-
-
- def testDontAllowBuggyComparisons(self):
- self.assertRaises(IncomparableVersions,
- cmp,
- Version("dummy", 1, 0, 0),
- Version("dumym", 1, 0, 0))
-
-
- def test_repr(self):
- """
- Calling C{repr} on a version returns a human-readable string
- representation of the version.
- """
- self.assertEqual(repr(Version("dummy", 1, 2, 3)),
- "Version('dummy', 1, 2, 3)")
-
-
- def test_reprWithPrerelease(self):
- """
- Calling C{repr} on a version with a prerelease returns a human-readable
- string representation of the version including the prerelease.
- """
- self.assertEqual(repr(Version("dummy", 1, 2, 3, prerelease=4)),
- "Version('dummy', 1, 2, 3, prerelease=4)")
-
-
- def test_str(self):
- """
- Calling C{str} on a version returns a human-readable string
- representation of the version.
- """
- self.assertEqual(str(Version("dummy", 1, 2, 3)),
- "[dummy, version 1.2.3]")
-
-
- def test_strWithPrerelease(self):
- """
- Calling C{str} on a version with a prerelease includes the prerelease.
- """
- self.assertEqual(str(Version("dummy", 1, 0, 0, prerelease=1)),
- "[dummy, version 1.0.0pre1]")
-
-
- def testShort(self):
- self.assertEqual(Version('dummy', 1, 2, 3).short(), '1.2.3')
-
-
- def test_goodSVNEntries_4(self):
- """
- Version should be able to parse an SVN format 4 entries file.
- """
- version = Version("dummy", 1, 0, 0)
- self.assertEqual(
- version._parseSVNEntries_4(StringIO(VERSION_4_ENTRIES)), '18211')
-
-
- def test_goodSVNEntries_8(self):
- """
- Version should be able to parse an SVN format 8 entries file.
- """
- version = Version("dummy", 1, 0, 0)
- self.assertEqual(
- version._parseSVNEntries_8(StringIO(VERSION_8_ENTRIES)), '22715')
-
-
- def test_goodSVNEntries_9(self):
- """
- Version should be able to parse an SVN format 9 entries file.
- """
- version = Version("dummy", 1, 0, 0)
- self.assertEqual(
- version._parseSVNEntries_9(StringIO(VERSION_9_ENTRIES)), '22715')
-
-
- def test_goodSVNEntriesTenPlus(self):
- """
- Version should be able to parse an SVN format 10 entries file.
- """
- version = Version("dummy", 1, 0, 0)
- self.assertEqual(
- version._parseSVNEntriesTenPlus(StringIO(VERSION_10_ENTRIES)), '22715')
-
-
- def test_getVersionString(self):
- """
- L{getVersionString} returns a string with the package name and the
- short version number.
- """
- self.assertEqual(
- 'Twisted 8.0.0', getVersionString(Version('Twisted', 8, 0, 0)))
-
-
- def test_getVersionStringWithPrerelease(self):
- """
- L{getVersionString} includes the prerelease, if any.
- """
- self.assertEqual(
- getVersionString(Version("whatever", 8, 0, 0, prerelease=1)),
- "whatever 8.0.0pre1")
-
-
- def test_base(self):
- """
- The L{base} method returns a very simple representation of the version.
- """
- self.assertEqual(Version("foo", 1, 0, 0).base(), "1.0.0")
-
-
- def test_baseWithPrerelease(self):
- """
- The base version includes 'preX' for versions with prereleases.
- """
- self.assertEqual(Version("foo", 1, 0, 0, prerelease=8).base(),
- "1.0.0pre8")
-
-
-
-class FormatDiscoveryTests(unittest.TestCase):
- """
- Tests which discover the parsing method based on the imported module name.
- """
-
- def setUp(self):
- """
- Create a temporary directory with a package structure in it.
- """
- self.entry = FilePath(self.mktemp())
- self.preTestModules = sys.modules.copy()
- sys.path.append(self.entry.path)
- pkg = self.entry.child("twisted_python_versions_package")
- pkg.makedirs()
- pkg.child("__init__.py").setContent(
- "from twisted.python.versions import Version\n"
- "version = Version('twisted_python_versions_package', 1, 0, 0)\n")
- self.svnEntries = pkg.child(".svn")
- self.svnEntries.makedirs()
-
-
- def tearDown(self):
- """
- Remove the imported modules and sys.path modifications.
- """
- sys.modules.clear()
- sys.modules.update(self.preTestModules)
- sys.path.remove(self.entry.path)
-
-
- def checkSVNFormat(self, formatVersion, entriesText, expectedRevision):
- """
- Check for the given revision being detected after setting the SVN
- entries text and format version of the test directory structure.
- """
- self.svnEntries.child("format").setContent(formatVersion+"\n")
- self.svnEntries.child("entries").setContent(entriesText)
- self.assertEqual(self.getVersion()._getSVNVersion(), expectedRevision)
-
-
- def getVersion(self):
- """
- Import and retrieve the Version object from our dynamically created
- package.
- """
- import twisted_python_versions_package
- return twisted_python_versions_package.version
-
-
- def test_detectVersion4(self):
- """
- Verify that version 4 format file will be properly detected and parsed.
- """
- self.checkSVNFormat("4", VERSION_4_ENTRIES, '18211')
-
-
- def test_detectVersion8(self):
- """
- Verify that version 8 format files will be properly detected and
- parsed.
- """
- self.checkSVNFormat("8", VERSION_8_ENTRIES, '22715')
-
-
- def test_detectVersion9(self):
- """
- Verify that version 9 format files will be properly detected and
- parsed.
- """
- self.checkSVNFormat("9", VERSION_9_ENTRIES, '22715')
-
-
- def test_detectVersion10(self):
- """
- Verify that version 10 format files will be properly detected and
- parsed.
-
- Differing from previous formats, the version 10 format lacks a
- I{format} file and B{only} has the version information on the first
- line of the I{entries} file.
- """
- self.svnEntries.child("entries").setContent(VERSION_10_ENTRIES)
- self.assertEqual(self.getVersion()._getSVNVersion(), '22715')
-
-
- def test_detectUnknownVersion(self):
- """
- Verify that a new version of SVN will result in the revision 'Unknown'.
- """
- self.checkSVNFormat("some-random-new-version", "ooga booga!", 'Unknown')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_win32.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_win32.py
deleted file mode 100755
index e262ea2b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_win32.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-from twisted.python.runtime import platform
-from twisted.python.win32 import cmdLineQuote
-
-
-class CommandLineQuotingTests(unittest.TestCase):
- """
- Tests for L{cmdLineQuote}.
- """
-
- def test_argWithoutSpaces(self):
- """
- Calling C{cmdLineQuote} with an argument with no spaces should
- return the argument unchanged.
- """
- self.assertEqual(cmdLineQuote('an_argument'), 'an_argument')
-
-
- def test_argWithSpaces(self):
- """
- Calling C{cmdLineQuote} with an argument containing spaces should
- return the argument surrounded by quotes.
- """
- self.assertEqual(cmdLineQuote('An Argument'), '"An Argument"')
-
-
- def test_emptyStringArg(self):
- """
- Calling C{cmdLineQuote} with an empty string should return a
- quoted empty string.
- """
- self.assertEqual(cmdLineQuote(''), '""')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zipstream.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zipstream.py
deleted file mode 100755
index b9d9a8a5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zipstream.py
+++ /dev/null
@@ -1,367 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.zipstream}
-"""
-
-import sys
-import random
-import zipfile
-
-from twisted.python.compat import set
-from twisted.python import zipstream, filepath
-from twisted.python.hashlib import md5
-from twisted.trial import unittest
-
-
-class FileEntryMixin:
- """
- File entry classes should behave as file-like objects
- """
- def getFileEntry(self, contents):
- """
- Return an appropriate zip file entry
- """
- filename = self.mktemp()
- z = zipfile.ZipFile(filename, 'w', self.compression)
- z.writestr('content', contents)
- z.close()
- z = zipstream.ChunkingZipFile(filename, 'r')
- return z.readfile('content')
-
-
- def test_isatty(self):
- """
- zip files should not be ttys, so isatty() should be false
- """
- self.assertEqual(self.getFileEntry('').isatty(), False)
-
-
- def test_closed(self):
- """
- The C{closed} attribute should reflect whether C{close()} has been
- called.
- """
- fileEntry = self.getFileEntry('')
- self.assertEqual(fileEntry.closed, False)
- fileEntry.close()
- self.assertEqual(fileEntry.closed, True)
-
-
- def test_readline(self):
- """
- C{readline()} should mirror L{file.readline} and return up to a single
- deliminter.
- """
- fileEntry = self.getFileEntry('hoho\nho')
- self.assertEqual(fileEntry.readline(), 'hoho\n')
- self.assertEqual(fileEntry.readline(), 'ho')
- self.assertEqual(fileEntry.readline(), '')
-
-
- def test_next(self):
- """
- Zip file entries should implement the iterator protocol as files do.
- """
- fileEntry = self.getFileEntry('ho\nhoho')
- self.assertEqual(fileEntry.next(), 'ho\n')
- self.assertEqual(fileEntry.next(), 'hoho')
- self.assertRaises(StopIteration, fileEntry.next)
-
-
- def test_readlines(self):
- """
- C{readlines()} should return a list of all the lines.
- """
- fileEntry = self.getFileEntry('ho\nho\nho')
- self.assertEqual(fileEntry.readlines(), ['ho\n', 'ho\n', 'ho'])
-
-
- def test_iteration(self):
- """
- C{__iter__()} and C{xreadlines()} should return C{self}.
- """
- fileEntry = self.getFileEntry('')
- self.assertIdentical(iter(fileEntry), fileEntry)
- self.assertIdentical(fileEntry.xreadlines(), fileEntry)
-
-
- def test_readWhole(self):
- """
- C{.read()} should read the entire file.
- """
- contents = "Hello, world!"
- entry = self.getFileEntry(contents)
- self.assertEqual(entry.read(), contents)
-
-
- def test_readPartial(self):
- """
- C{.read(num)} should read num bytes from the file.
- """
- contents = "0123456789"
- entry = self.getFileEntry(contents)
- one = entry.read(4)
- two = entry.read(200)
- self.assertEqual(one, "0123")
- self.assertEqual(two, "456789")
-
-
- def test_tell(self):
- """
- C{.tell()} should return the number of bytes that have been read so
- far.
- """
- contents = "x" * 100
- entry = self.getFileEntry(contents)
- entry.read(2)
- self.assertEqual(entry.tell(), 2)
- entry.read(4)
- self.assertEqual(entry.tell(), 6)
-
-
-
-class DeflatedZipFileEntryTest(FileEntryMixin, unittest.TestCase):
- """
- DeflatedZipFileEntry should be file-like
- """
- compression = zipfile.ZIP_DEFLATED
-
-
-
-class ZipFileEntryTest(FileEntryMixin, unittest.TestCase):
- """
- ZipFileEntry should be file-like
- """
- compression = zipfile.ZIP_STORED
-
-
-
-class ZipstreamTest(unittest.TestCase):
- """
- Tests for twisted.python.zipstream
- """
- def setUp(self):
- """
- Creates junk data that can be compressed and a test directory for any
- files that will be created
- """
- self.testdir = filepath.FilePath(self.mktemp())
- self.testdir.makedirs()
- self.unzipdir = self.testdir.child('unzipped')
- self.unzipdir.makedirs()
-
-
- def makeZipFile(self, contents, directory=''):
- """
- Makes a zip file archive containing len(contents) files. Contents
- should be a list of strings, each string being the content of one file.
- """
- zpfilename = self.testdir.child('zipfile.zip').path
- zpfile = zipfile.ZipFile(zpfilename, 'w')
- for i, content in enumerate(contents):
- filename = str(i)
- if directory:
- filename = directory + "/" + filename
- zpfile.writestr(filename, content)
- zpfile.close()
- return zpfilename
-
-
- def test_invalidMode(self):
- """
- A ChunkingZipFile opened in write-mode should not allow .readfile(),
- and raise a RuntimeError instead.
- """
- czf = zipstream.ChunkingZipFile(self.mktemp(), "w")
- self.assertRaises(RuntimeError, czf.readfile, "something")
-
-
- def test_closedArchive(self):
- """
- A closed ChunkingZipFile should raise a L{RuntimeError} when
- .readfile() is invoked.
- """
- czf = zipstream.ChunkingZipFile(self.makeZipFile(["something"]), "r")
- czf.close()
- self.assertRaises(RuntimeError, czf.readfile, "something")
-
-
- def test_invalidHeader(self):
- """
- A zipfile entry with the wrong magic number should raise BadZipfile for
- readfile(), but that should not affect other files in the archive.
- """
- fn = self.makeZipFile(["test contents",
- "more contents"])
- zf = zipfile.ZipFile(fn, "r")
- zeroOffset = zf.getinfo("0").header_offset
- zf.close()
- # Zero out just the one header.
- scribble = file(fn, "r+b")
- scribble.seek(zeroOffset, 0)
- scribble.write(chr(0) * 4)
- scribble.close()
- czf = zipstream.ChunkingZipFile(fn)
- self.assertRaises(zipfile.BadZipfile, czf.readfile, "0")
- self.assertEqual(czf.readfile("1").read(), "more contents")
-
-
- def test_filenameMismatch(self):
- """
- A zipfile entry with a different filename than is found in the central
- directory should raise BadZipfile.
- """
- fn = self.makeZipFile(["test contents",
- "more contents"])
- zf = zipfile.ZipFile(fn, "r")
- info = zf.getinfo("0")
- info.filename = "not zero"
- zf.close()
- scribble = file(fn, "r+b")
- scribble.seek(info.header_offset, 0)
- scribble.write(info.FileHeader())
- scribble.close()
-
- czf = zipstream.ChunkingZipFile(fn)
- self.assertRaises(zipfile.BadZipfile, czf.readfile, "0")
- self.assertEqual(czf.readfile("1").read(), "more contents")
-
-
- if sys.version_info < (2, 5):
- # In python 2.4 and earlier, consistency between the directory and the
- # file header are verified at archive-opening time. In python 2.5
- # (and, presumably, later) it is readzipfile's responsibility.
- message = "Consistency-checking only necessary in 2.5."
- test_invalidHeader.skip = message
- test_filenameMismatch.skip = message
-
-
-
- def test_unsupportedCompression(self):
- """
- A zipfile which describes an unsupported compression mechanism should
- raise BadZipfile.
- """
- fn = self.mktemp()
- zf = zipfile.ZipFile(fn, "w")
- zi = zipfile.ZipInfo("0")
- zf.writestr(zi, "some data")
- # Mangle its compression type in the central directory; can't do this
- # before the writestr call or zipfile will (correctly) tell us not to
- # pass bad compression types :)
- zi.compress_type = 1234
- zf.close()
-
- czf = zipstream.ChunkingZipFile(fn)
- self.assertRaises(zipfile.BadZipfile, czf.readfile, "0")
-
-
- def test_extraData(self):
- """
- readfile() should skip over 'extra' data present in the zip metadata.
- """
- fn = self.mktemp()
- zf = zipfile.ZipFile(fn, 'w')
- zi = zipfile.ZipInfo("0")
- zi.extra = "hello, extra"
- zf.writestr(zi, "the real data")
- zf.close()
- czf = zipstream.ChunkingZipFile(fn)
- self.assertEqual(czf.readfile("0").read(), "the real data")
-
-
- def test_unzipIterChunky(self):
- """
- L{twisted.python.zipstream.unzipIterChunky} returns an iterator which
- must be exhausted to completely unzip the input archive.
- """
- numfiles = 10
- contents = ['This is test file %d!' % i for i in range(numfiles)]
- zpfilename = self.makeZipFile(contents)
- list(zipstream.unzipIterChunky(zpfilename, self.unzipdir.path))
- self.assertEqual(
- set(self.unzipdir.listdir()),
- set(map(str, range(numfiles))))
-
- for child in self.unzipdir.children():
- num = int(child.basename())
- self.assertEqual(child.getContent(), contents[num])
-
-
- def test_unzipIterChunkyDirectory(self):
- """
- The path to which a file is extracted by L{zipstream.unzipIterChunky}
- is determined by joining the C{directory} argument to C{unzip} with the
- path within the archive of the file being extracted.
- """
- numfiles = 10
- contents = ['This is test file %d!' % i for i in range(numfiles)]
- zpfilename = self.makeZipFile(contents, 'foo')
- list(zipstream.unzipIterChunky(zpfilename, self.unzipdir.path))
- self.assertEqual(
- set(self.unzipdir.child('foo').listdir()),
- set(map(str, range(numfiles))))
-
- for child in self.unzipdir.child('foo').children():
- num = int(child.basename())
- self.assertEqual(child.getContent(), contents[num])
-
-
- # XXX these tests are kind of gross and old, but I think unzipIterChunky is
- # kind of a gross function anyway. We should really write an abstract
- # copyTo/moveTo that operates on FilePath and make sure ZipPath can support
- # it, then just deprecate / remove this stuff.
- def _unzipIterChunkyTest(self, compression, chunksize, lower, upper):
- """
- unzipIterChunky should unzip the given number of bytes per iteration.
- """
- junk = ' '.join([str(random.random()) for n in xrange(1000)])
- junkmd5 = md5(junk).hexdigest()
-
- tempdir = filepath.FilePath(self.mktemp())
- tempdir.makedirs()
- zfpath = tempdir.child('bigfile.zip').path
- self._makebigfile(zfpath, compression, junk)
- uziter = zipstream.unzipIterChunky(zfpath, tempdir.path,
- chunksize=chunksize)
- r = uziter.next()
- # test that the number of chunks is in the right ballpark;
- # this could theoretically be any number but statistically it
- # should always be in this range
- approx = lower < r < upper
- self.failUnless(approx)
- for r in uziter:
- pass
- self.assertEqual(r, 0)
- newmd5 = md5(
- tempdir.child("zipstreamjunk").open().read()).hexdigest()
- self.assertEqual(newmd5, junkmd5)
-
- def test_unzipIterChunkyStored(self):
- """
- unzipIterChunky should unzip the given number of bytes per iteration on
- a stored archive.
- """
- self._unzipIterChunkyTest(zipfile.ZIP_STORED, 500, 35, 45)
-
-
- def test_chunkyDeflated(self):
- """
- unzipIterChunky should unzip the given number of bytes per iteration on
- a deflated archive.
- """
- self._unzipIterChunkyTest(zipfile.ZIP_DEFLATED, 972, 23, 27)
-
-
- def _makebigfile(self, filename, compression, junk):
- """
- Create a zip file with the given file name and compression scheme.
- """
- zf = zipfile.ZipFile(filename, 'w', compression)
- for i in range(10):
- fn = 'zipstream%d' % i
- zf.writestr(fn, "")
- zf.writestr('zipstreamjunk', junk)
- zf.close()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zshcomp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zshcomp.py
deleted file mode 100755
index 13865b21..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/test/test_zshcomp.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.python.zshcomp
-"""
-import os
-import os.path
-from cStringIO import StringIO
-
-from twisted.trial import unittest
-from twisted.python import zshcomp, usage
-
-
-
-class ZshcompTestCase(unittest.TestCase):
- """
- Tests for the zsh completion function builder in twisted/python/zshcomp.py
- """
- def test_buildAll(self):
- """
- Build all the completion functions for twisted commands - no errors
- should be raised
- """
- dirname = self.mktemp()
- os.mkdir(dirname)
- skippedCmds = [x[0] for x in zshcomp.makeCompFunctionFiles(dirname)]
-
- # verify a zsh function was created for each twisted command
- for info in zshcomp.generateFor:
- if info[0] in skippedCmds:
- continue
- funcPath = os.path.join(dirname, '_' + info[0])
- self.assertTrue(os.path.exists(funcPath))
-
-
- def test_accumulateMetadata(self):
- """
- The zsh_* variables you can place on Options classes are
- picked up correctly?
- """
- opts = FighterAceExtendedOptions()
- ag = zshcomp.ArgumentsGenerator('dummy_cmd', opts, 'dummy_value')
-
- altArgDescr = FighterAceOptions.zsh_altArgDescr.copy()
- altArgDescr.update(FighterAceExtendedOptions.zsh_altArgDescr)
-
- actionDescr = FighterAceOptions.zsh_actionDescr.copy()
- actionDescr.update(FighterAceExtendedOptions.zsh_actionDescr)
-
- self.assertEqual(ag.altArgDescr, altArgDescr)
- self.assertEqual(ag.actionDescr, actionDescr)
- self.assertEqual(ag.multiUse, FighterAceOptions.zsh_multiUse)
- self.assertEqual(ag.mutuallyExclusive,
- FighterAceOptions.zsh_mutuallyExclusive)
- self.assertEqual(ag.actions, FighterAceOptions.zsh_actions)
- self.assertEqual(ag.extras, FighterAceOptions.zsh_extras)
-
-
- def test_accumulateAdditionalOptions(self):
- """
- We pick up options that are only defined by having an
- appropriately named method on your Options class,
- e.g. def opt_foo(self, foo)
- """
- opts = FighterAceExtendedOptions()
- ag = zshcomp.ArgumentsGenerator('dummy_cmd', opts, 'dummy_value')
-
- self.assertIn('nocrash', ag.optFlags_d)
- self.assertIn('nocrash', ag.optAll_d)
-
- self.assertIn('difficulty', ag.optParams_d)
- self.assertIn('difficulty', ag.optAll_d)
-
-
- def test_verifyZshNames(self):
- """
- Using a parameter/flag name that doesn't exist
- will raise an error
- """
- class TmpOptions(FighterAceExtendedOptions):
- zsh_actions = {'detaill' : 'foo'} # Note typo of detail
-
- opts = TmpOptions()
- self.assertRaises(ValueError, zshcomp.ArgumentsGenerator,
- 'dummy_cmd', opts, 'dummy_value')
-
-
- def test_zshCode(self):
- """
- Generate a completion function, and test the textual output
- against a known correct output
- """
- cmd_name = 'testprog'
- opts = SillyOptions()
- f = StringIO()
- b = zshcomp.Builder(cmd_name, opts, f)
- b.write()
- f.reset()
- self.assertEqual(f.read(), testOutput1)
-
-
- def test_skipBuild(self):
- """
- makeCompFunctionFiles skips building for commands whos
- script module cannot be imported
- """
- generateFor = [('test_cmd', 'no.way.your.gonna.import.this', 'Foo')]
- skips = zshcomp.makeCompFunctionFiles('out_dir', generateFor, {})
- # no exceptions should be raised. hooray.
- self.assertEqual(len(skips), 1)
- self.assertEqual(len(skips[0]), 2)
- self.assertEqual(skips[0][0], 'test_cmd')
- self.assertTrue(isinstance(skips[0][1], ImportError))
-
-
-
-class FighterAceOptions(usage.Options):
- """
- Command-line options for an imaginary "Fighter Ace" game
- """
- optFlags = [['fokker', 'f',
- 'Select the Fokker Dr.I as your dogfighter aircraft'],
- ['albatros', 'a',
- 'Select the Albatros D-III as your dogfighter aircraft'],
- ['spad', 's',
- 'Select the SPAD S.VII as your dogfighter aircraft'],
- ['bristol', 'b',
- 'Select the Bristol Scout as your dogfighter aircraft'],
- ['physics', 'p',
- 'Enable secret Twisted physics engine'],
- ['jam', 'j',
- 'Enable a small chance that your machine guns will jam!'],
- ['verbose', 'v',
- 'Verbose logging (may be specified more than once)'],
- ]
-
- optParameters = [['pilot-name', None, "What's your name, Ace?",
- 'Manfred von Richthofen'],
- ['detail', 'd',
- 'Select the level of rendering detail (1-5)', '3'],
- ]
-
- zsh_altArgDescr = {'physics' : 'Twisted-Physics',
- 'detail' : 'Rendering detail level'}
- zsh_actionDescr = {'detail' : 'Pick your detail'}
- zsh_multiUse = ['verbose']
- zsh_mutuallyExclusive = [['fokker', 'albatros', 'spad', 'bristol']]
- zsh_actions = {'detail' : '(1 2 3 4 5)'}
- zsh_extras = [':saved game file to load:_files']
-
-
-
-class FighterAceExtendedOptions(FighterAceOptions):
- """
- Extend the options and zsh metadata provided by FighterAceOptions. zshcomp
- must accumulate options and metadata from all classes in the hiearchy so
- this is important for testing
- """
- optFlags = [['no-stalls', None,
- 'Turn off the ability to stall your aircraft']]
- optParameters = [['reality-level', None,
- 'Select the level of physics reality (1-5)', '5']]
-
- zsh_altArgDescr = {'no-stalls' : 'Can\'t stall your plane'}
- zsh_actionDescr = {'reality-level' : 'Physics reality level'}
-
-
- def opt_nocrash(self):
- """Select that you can't crash your plane"""
-
-
- def opt_difficulty(self, difficulty):
- """How tough are you? (1-10)"""
-
-
-
-def _accuracyAction():
- return '(1 2 3)'
-
-
-
-class SillyOptions(usage.Options):
- """
- Command-line options for a "silly" program
- """
- optFlags = [['color', 'c', 'Turn on color output'],
- ['gray', 'g', 'Turn on gray-scale output'],
- ['verbose', 'v',
- 'Verbose logging (may be specified more than once)'],
- ]
-
- optParameters = [['optimization', None,
- 'Select the level of optimization (1-5)', '5'],
- ['accuracy', 'a',
- 'Select the level of accuracy (1-3)', '3'],
- ]
-
-
- zsh_altArgDescr = {'color' : 'Color on',
- 'optimization' : 'Optimization level'}
- zsh_actionDescr = {'optimization' : 'Optimization?',
- 'accuracy' : 'Accuracy?'}
- zsh_multiUse = ['verbose']
- zsh_mutuallyExclusive = [['color', 'gray']]
- zsh_actions = {'optimization' : '(1 2 3 4 5)',
- 'accuracy' : _accuracyAction}
- zsh_extras = [':output file:_files']
-
-
-
-testOutput1 = """#compdef testprog
-_arguments -s -A "-*" \\
-':output file:_files' \\
-'(--accuracy)-a[3]:Accuracy?:(1 2 3)' \\
-'(-a)--accuracy=[3]:Accuracy?:(1 2 3)' \\
-'(--gray -g --color)-c[Color on]' \\
-'(--gray -g -c)--color[Color on]' \\
-'(--color -c --gray)-g[Turn on gray-scale output]' \\
-'(--color -c -g)--gray[Turn on gray-scale output]' \\
-'--help[Display this help and exit.]' \\
-'--optimization=[Optimization level]:Optimization?:(1 2 3 4 5)' \\
-'*-v[Verbose logging (may be specified more than once)]' \\
-'*--verbose[Verbose logging (may be specified more than once)]' \\
-'--version[Display Twisted version and exit.]' \\
-&& return 0
-"""
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/text.py
deleted file mode 100755
index 9887e70e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/text.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# -*- test-case-name: twisted.test.test_text -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Miscellany of text-munging functions.
-"""
-
-
-def stringyString(object, indentation=''):
- """
- Expansive string formatting for sequence types.
-
- C{list.__str__} and C{dict.__str__} use C{repr()} to display their
- elements. This function also turns these sequence types
- into strings, but uses C{str()} on their elements instead.
-
- Sequence elements are also displayed on seperate lines, and nested
- sequences have nested indentation.
- """
- braces = ''
- sl = []
-
- if type(object) is dict:
- braces = '{}'
- for key, value in object.items():
- value = stringyString(value, indentation + ' ')
- if isMultiline(value):
- if endsInNewline(value):
- value = value[:-len('\n')]
- sl.append("%s %s:\n%s" % (indentation, key, value))
- else:
- # Oops. Will have to move that indentation.
- sl.append("%s %s: %s" % (indentation, key,
- value[len(indentation) + 3:]))
-
- elif type(object) is tuple or type(object) is list:
- if type(object) is tuple:
- braces = '()'
- else:
- braces = '[]'
-
- for element in object:
- element = stringyString(element, indentation + ' ')
- sl.append(element.rstrip() + ',')
- else:
- sl[:] = map(lambda s, i=indentation: i + s,
- str(object).split('\n'))
-
- if not sl:
- sl.append(indentation)
-
- if braces:
- sl[0] = indentation + braces[0] + sl[0][len(indentation) + 1:]
- sl[-1] = sl[-1] + braces[-1]
-
- s = "\n".join(sl)
-
- if isMultiline(s) and not endsInNewline(s):
- s = s + '\n'
-
- return s
-
-
-def isMultiline(s):
- """
- Returns C{True} if this string has a newline in it.
- """
- return (s.find('\n') != -1)
-
-
-def endsInNewline(s):
- """
- Returns C{True} if this string ends in a newline.
- """
- return (s[-len('\n'):] == '\n')
-
-
-def greedyWrap(inString, width=80):
- """
- Given a string and a column width, return a list of lines.
-
- Caveat: I'm use a stupid greedy word-wrapping
- algorythm. I won't put two spaces at the end
- of a sentence. I don't do full justification.
- And no, I've never even *heard* of hypenation.
- """
-
- outLines = []
-
- #eww, evil hacks to allow paragraphs delimited by two \ns :(
- if inString.find('\n\n') >= 0:
- paragraphs = inString.split('\n\n')
- for para in paragraphs:
- outLines.extend(greedyWrap(para, width) + [''])
- return outLines
- inWords = inString.split()
-
- column = 0
- ptr_line = 0
- while inWords:
- column = column + len(inWords[ptr_line])
- ptr_line = ptr_line + 1
-
- if (column > width):
- if ptr_line == 1:
- # This single word is too long, it will be the whole line.
- pass
- else:
- # We've gone too far, stop the line one word back.
- ptr_line = ptr_line - 1
- (l, inWords) = (inWords[0:ptr_line], inWords[ptr_line:])
- outLines.append(' '.join(l))
-
- ptr_line = 0
- column = 0
- elif not (len(inWords) > ptr_line):
- # Clean up the last bit.
- outLines.append(' '.join(inWords))
- del inWords[:]
- else:
- # Space
- column = column + 1
- # next word
-
- return outLines
-
-
-wordWrap = greedyWrap
-
-
-def removeLeadingBlanks(lines):
- ret = []
- for line in lines:
- if ret or line.strip():
- ret.append(line)
- return ret
-
-
-def removeLeadingTrailingBlanks(s):
- lines = removeLeadingBlanks(s.split('\n'))
- lines.reverse()
- lines = removeLeadingBlanks(lines)
- lines.reverse()
- return '\n'.join(lines)+'\n'
-
-
-def splitQuoted(s):
- """
- Like a string split, but don't break substrings inside quotes.
-
- >>> splitQuoted('the "hairy monkey" likes pie')
- ['the', 'hairy monkey', 'likes', 'pie']
-
- Another one of those "someone must have a better solution for
- this" things. This implementation is a VERY DUMB hack done too
- quickly.
- """
- out = []
- quot = None
- phrase = None
- for word in s.split():
- if phrase is None:
- if word and (word[0] in ("\"", "'")):
- quot = word[0]
- word = word[1:]
- phrase = []
-
- if phrase is None:
- out.append(word)
- else:
- if word and (word[-1] == quot):
- word = word[:-1]
- phrase.append(word)
- out.append(" ".join(phrase))
- phrase = None
- else:
- phrase.append(word)
-
- return out
-
-
-def strFile(p, f, caseSensitive=True):
- """
- Find whether string C{p} occurs in a read()able object C{f}.
-
- @rtype: C{bool}
- """
- buf = ""
- buf_len = max(len(p), 2**2**2**2)
- if not caseSensitive:
- p = p.lower()
- while 1:
- r = f.read(buf_len-len(p))
- if not caseSensitive:
- r = r.lower()
- bytes_read = len(r)
- if bytes_read == 0:
- return False
- l = len(buf)+bytes_read-buf_len
- if l <= 0:
- buf = buf + r
- else:
- buf = buf[l:] + r
- if buf.find(p) != -1:
- return True
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadable.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadable.py
deleted file mode 100755
index adb5b8b7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadable.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# -*- test-case-name: twisted.python.test_threadable -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-A module that will allow your program to be multi-threaded,
-micro-threaded, and single-threaded. Currently microthreads are
-unimplemented. The idea is to abstract away some commonly used
-functionality so that I don't have to special-case it in all programs.
-"""
-
-
-
-from twisted.python import hook
-
-class DummyLock(object):
- """
- Hack to allow locks to be unpickled on an unthreaded system.
- """
-
- def __reduce__(self):
- return (unpickle_lock, ())
-
-def unpickle_lock():
- if threadingmodule is not None:
- return XLock()
- else:
- return DummyLock()
-unpickle_lock.__safe_for_unpickling__ = True
-
-def _synchPre(self, *a, **b):
- if '_threadable_lock' not in self.__dict__:
- _synchLockCreator.acquire()
- if '_threadable_lock' not in self.__dict__:
- self.__dict__['_threadable_lock'] = XLock()
- _synchLockCreator.release()
- self._threadable_lock.acquire()
-
-def _synchPost(self, *a, **b):
- self._threadable_lock.release()
-
-def synchronize(*klasses):
- """Make all methods listed in each class' synchronized attribute synchronized.
-
- The synchronized attribute should be a list of strings, consisting of the
- names of methods that must be synchronized. If we are running in threaded
- mode these methods will be wrapped with a lock.
- """
- if threadmodule is not None:
- for klass in klasses:
- for methodName in klass.synchronized:
- hook.addPre(klass, methodName, _synchPre)
- hook.addPost(klass, methodName, _synchPost)
-
-def init(with_threads=1):
- """Initialize threading.
-
- Don't bother calling this. If it needs to happen, it will happen.
- """
- global threaded, _synchLockCreator, XLock
-
- if with_threads:
- if not threaded:
- if threadmodule is not None:
- threaded = True
-
- class XLock(threadingmodule._RLock, object):
- def __reduce__(self):
- return (unpickle_lock, ())
-
- _synchLockCreator = XLock()
- else:
- raise RuntimeError("Cannot initialize threading, platform lacks thread support")
- else:
- if threaded:
- raise RuntimeError("Cannot uninitialize threads")
- else:
- pass
-
-_dummyID = object()
-def getThreadID():
- if threadmodule is None:
- return _dummyID
- return threadmodule.get_ident()
-
-
-def isInIOThread():
- """Are we in the thread responsable for I/O requests (the event loop)?
- """
- return ioThread == getThreadID()
-
-
-
-def registerAsIOThread():
- """Mark the current thread as responsable for I/O requests.
- """
- global ioThread
- ioThread = getThreadID()
-
-
-ioThread = None
-threaded = False
-
-
-
-try:
- import thread as threadmodule
- import threading as threadingmodule
-except ImportError:
- threadmodule = None
- threadingmodule = None
-else:
- init(True)
-
-
-
-__all__ = ['isInIOThread', 'registerAsIOThread', 'getThreadID', 'XLock']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadpool.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadpool.py
deleted file mode 100755
index 1fa2ed59..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/threadpool.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# -*- test-case-name: twisted.test.test_threadpool -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-twisted.python.threadpool: a pool of threads to which we dispatch tasks.
-
-In most cases you can just use C{reactor.callInThread} and friends
-instead of creating a thread pool directly.
-"""
-
-import Queue
-import threading
-import copy
-
-from twisted.python import log, context, failure
-
-
-WorkerStop = object()
-
-
-class ThreadPool:
- """
- This class (hopefully) generalizes the functionality of a pool of
- threads to which work can be dispatched.
-
- L{callInThread} and L{stop} should only be called from
- a single thread, unless you make a subclass where L{stop} and
- L{_startSomeWorkers} are synchronized.
- """
- min = 5
- max = 20
- joined = False
- started = False
- workers = 0
- name = None
-
- threadFactory = threading.Thread
- currentThread = staticmethod(threading.currentThread)
-
- def __init__(self, minthreads=5, maxthreads=20, name=None):
- """
- Create a new threadpool.
-
- @param minthreads: minimum number of threads in the pool
- @param maxthreads: maximum number of threads in the pool
- """
- assert minthreads >= 0, 'minimum is negative'
- assert minthreads <= maxthreads, 'minimum is greater than maximum'
- self.q = Queue.Queue(0)
- self.min = minthreads
- self.max = maxthreads
- self.name = name
- self.waiters = []
- self.threads = []
- self.working = []
-
-
- def start(self):
- """
- Start the threadpool.
- """
- self.joined = False
- self.started = True
- # Start some threads.
- self.adjustPoolsize()
-
-
- def startAWorker(self):
- self.workers += 1
- name = "PoolThread-%s-%s" % (self.name or id(self), self.workers)
- newThread = self.threadFactory(target=self._worker, name=name)
- self.threads.append(newThread)
- newThread.start()
-
-
- def stopAWorker(self):
- self.q.put(WorkerStop)
- self.workers -= 1
-
-
- def __setstate__(self, state):
- self.__dict__ = state
- ThreadPool.__init__(self, self.min, self.max)
-
-
- def __getstate__(self):
- state = {}
- state['min'] = self.min
- state['max'] = self.max
- return state
-
-
- def _startSomeWorkers(self):
- neededSize = self.q.qsize() + len(self.working)
- # Create enough, but not too many
- while self.workers < min(self.max, neededSize):
- self.startAWorker()
-
-
- def callInThread(self, func, *args, **kw):
- """
- Call a callable object in a separate thread.
-
- @param func: callable object to be called in separate thread
-
- @param *args: positional arguments to be passed to C{func}
-
- @param **kw: keyword args to be passed to C{func}
- """
- self.callInThreadWithCallback(None, func, *args, **kw)
-
-
- def callInThreadWithCallback(self, onResult, func, *args, **kw):
- """
- Call a callable object in a separate thread and call C{onResult}
- with the return value, or a L{twisted.python.failure.Failure}
- if the callable raises an exception.
-
- The callable is allowed to block, but the C{onResult} function
- must not block and should perform as little work as possible.
-
- A typical action for C{onResult} for a threadpool used with a
- Twisted reactor would be to schedule a
- L{twisted.internet.defer.Deferred} to fire in the main
- reactor thread using C{.callFromThread}. Note that C{onResult}
- is called inside the separate thread, not inside the reactor thread.
-
- @param onResult: a callable with the signature C{(success, result)}.
- If the callable returns normally, C{onResult} is called with
- C{(True, result)} where C{result} is the return value of the
- callable. If the callable throws an exception, C{onResult} is
- called with C{(False, failure)}.
-
- Optionally, C{onResult} may be C{None}, in which case it is not
- called at all.
-
- @param func: callable object to be called in separate thread
-
- @param *args: positional arguments to be passed to C{func}
-
- @param **kwargs: keyword arguments to be passed to C{func}
- """
- if self.joined:
- return
- ctx = context.theContextTracker.currentContext().contexts[-1]
- o = (ctx, func, args, kw, onResult)
- self.q.put(o)
- if self.started:
- self._startSomeWorkers()
-
-
- def _worker(self):
- """
- Method used as target of the created threads: retrieve a task to run
- from the threadpool, run it, and proceed to the next task until
- threadpool is stopped.
- """
- ct = self.currentThread()
- o = self.q.get()
- while o is not WorkerStop:
- self.working.append(ct)
- ctx, function, args, kwargs, onResult = o
- del o
-
- try:
- result = context.call(ctx, function, *args, **kwargs)
- success = True
- except:
- success = False
- if onResult is None:
- context.call(ctx, log.err)
- result = None
- else:
- result = failure.Failure()
-
- del function, args, kwargs
-
- self.working.remove(ct)
-
- if onResult is not None:
- try:
- context.call(ctx, onResult, success, result)
- except:
- context.call(ctx, log.err)
-
- del ctx, onResult, result
-
- self.waiters.append(ct)
- o = self.q.get()
- self.waiters.remove(ct)
-
- self.threads.remove(ct)
-
-
- def stop(self):
- """
- Shutdown the threads in the threadpool.
- """
- self.joined = True
- threads = copy.copy(self.threads)
- while self.workers:
- self.q.put(WorkerStop)
- self.workers -= 1
-
- # and let's just make sure
- # FIXME: threads that have died before calling stop() are not joined.
- for thread in threads:
- thread.join()
-
-
- def adjustPoolsize(self, minthreads=None, maxthreads=None):
- if minthreads is None:
- minthreads = self.min
- if maxthreads is None:
- maxthreads = self.max
-
- assert minthreads >= 0, 'minimum is negative'
- assert minthreads <= maxthreads, 'minimum is greater than maximum'
-
- self.min = minthreads
- self.max = maxthreads
- if not self.started:
- return
-
- # Kill of some threads if we have too many.
- while self.workers > self.max:
- self.stopAWorker()
- # Start some threads if we have too few.
- while self.workers < self.min:
- self.startAWorker()
- # Start some threads if there is a need.
- self._startSomeWorkers()
-
-
- def dumpStats(self):
- log.msg('queue: %s' % self.q.queue)
- log.msg('waiters: %s' % self.waiters)
- log.msg('workers: %s' % self.working)
- log.msg('total: %s' % self.threads)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/twisted-completion.zsh b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/twisted-completion.zsh
deleted file mode 100644
index 70cb89ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/twisted-completion.zsh
+++ /dev/null
@@ -1,33 +0,0 @@
-#compdef twistd trial conch cftp tapconvert ckeygen lore pyhtmlizer tap2deb tkconch manhole tap2rpm
-#
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked all
-# over the user's terminal if completing options for a deprecated command.
-# Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/urlpath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/urlpath.py
deleted file mode 100755
index 1c15f099..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/urlpath.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# -*- test-case-name: twisted.test.test_paths -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-import urlparse
-import urllib
-
-class URLPath:
- def __init__(self, scheme='', netloc='localhost', path='',
- query='', fragment=''):
- self.scheme = scheme or 'http'
- self.netloc = netloc
- self.path = path or '/'
- self.query = query
- self.fragment = fragment
-
- _qpathlist = None
- _uqpathlist = None
-
- def pathList(self, unquote=0, copy=1):
- if self._qpathlist is None:
- self._qpathlist = self.path.split('/')
- self._uqpathlist = map(urllib.unquote, self._qpathlist)
- if unquote:
- result = self._uqpathlist
- else:
- result = self._qpathlist
- if copy:
- return result[:]
- else:
- return result
-
- def fromString(klass, st):
- t = urlparse.urlsplit(st)
- u = klass(*t)
- return u
-
- fromString = classmethod(fromString)
-
- def fromRequest(klass, request):
- return klass.fromString(request.prePathURL())
-
- fromRequest = classmethod(fromRequest)
-
- def _pathMod(self, newpathsegs, keepQuery):
- if keepQuery:
- query = self.query
- else:
- query = ''
- return URLPath(self.scheme,
- self.netloc,
- '/'.join(newpathsegs),
- query)
-
- def sibling(self, path, keepQuery=0):
- l = self.pathList()
- l[-1] = path
- return self._pathMod(l, keepQuery)
-
- def child(self, path, keepQuery=0):
- l = self.pathList()
- if l[-1] == '':
- l[-1] = path
- else:
- l.append(path)
- return self._pathMod(l, keepQuery)
-
- def parent(self, keepQuery=0):
- l = self.pathList()
- if l[-1] == '':
- del l[-2]
- else:
- # We are a file, such as http://example.com/foo/bar
- # our parent directory is http://example.com/
- l.pop()
- l[-1] = ''
- return self._pathMod(l, keepQuery)
-
- def here(self, keepQuery=0):
- l = self.pathList()
- if l[-1] != '':
- l[-1] = ''
- return self._pathMod(l, keepQuery)
-
- def click(self, st):
- """Return a path which is the URL where a browser would presumably take
- you if you clicked on a link with an HREF as given.
- """
- scheme, netloc, path, query, fragment = urlparse.urlsplit(st)
- if not scheme:
- scheme = self.scheme
- if not netloc:
- netloc = self.netloc
- if not path:
- path = self.path
- if not query:
- query = self.query
- elif path[0] != '/':
- l = self.pathList()
- l[-1] = path
- path = '/'.join(l)
-
- return URLPath(scheme,
- netloc,
- path,
- query,
- fragment)
-
-
-
- def __str__(self):
- x = urlparse.urlunsplit((
- self.scheme, self.netloc, self.path,
- self.query, self.fragment))
- return x
-
- def __repr__(self):
- return ('URLPath(scheme=%r, netloc=%r, path=%r, query=%r, fragment=%r)'
- % (self.scheme, self.netloc, self.path, self.query, self.fragment))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/usage.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/usage.py
deleted file mode 100755
index 9280ae21..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/usage.py
+++ /dev/null
@@ -1,973 +0,0 @@
-# -*- test-case-name: twisted.test.test_usage -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-twisted.python.usage is a module for parsing/handling the
-command line of your program.
-
-For information on how to use it, see
-U{http://twistedmatrix.com/projects/core/documentation/howto/options.html},
-or doc/core/howto/options.xhtml in your Twisted directory.
-"""
-
-# System Imports
-import os
-import sys
-import getopt
-from os import path
-
-# Sibling Imports
-from twisted.python import reflect, text, util
-
-
-class UsageError(Exception):
- pass
-
-
-error = UsageError
-
-
-class CoerceParameter(object):
- """
- Utility class that can corce a parameter before storing it.
- """
- def __init__(self, options, coerce):
- """
- @param options: parent Options object
- @param coerce: callable used to coerce the value.
- """
- self.options = options
- self.coerce = coerce
- self.doc = getattr(self.coerce, 'coerceDoc', '')
-
- def dispatch(self, parameterName, value):
- """
- When called in dispatch, do the coerce for C{value} and save the
- returned value.
- """
- if value is None:
- raise UsageError("Parameter '%s' requires an argument."
- % (parameterName,))
- try:
- value = self.coerce(value)
- except ValueError, e:
- raise UsageError("Parameter type enforcement failed: %s" % (e,))
-
- self.options.opts[parameterName] = value
-
-
-class Options(dict):
- """
- An option list parser class
-
- C{optFlags} and C{optParameters} are lists of available parameters
- which your program can handle. The difference between the two
- is the 'flags' have an on(1) or off(0) state (off by default)
- whereas 'parameters' have an assigned value, with an optional
- default. (Compare '--verbose' and '--verbosity=2')
-
- optFlags is assigned a list of lists. Each list represents
- a flag parameter, as so::
-
- | optFlags = [['verbose', 'v', 'Makes it tell you what it doing.'],
- | ['quiet', 'q', 'Be vewy vewy quiet.']]
-
- As you can see, the first item is the long option name
- (prefixed with '--' on the command line), followed by the
- short option name (prefixed with '-'), and the description.
- The description is used for the built-in handling of the
- --help switch, which prints a usage summary.
-
- C{optParameters} is much the same, except the list also contains
- a default value::
-
- | optParameters = [['outfile', 'O', 'outfile.log', 'Description...']]
-
- A coerce function can also be specified as the last element: it will be
- called with the argument and should return the value that will be stored
- for the option. This function can have a C{coerceDoc} attribute which
- will be appended to the documentation of the option.
-
- subCommands is a list of 4-tuples of (command name, command shortcut,
- parser class, documentation). If the first non-option argument found is
- one of the given command names, an instance of the given parser class is
- instantiated and given the remainder of the arguments to parse and
- self.opts[command] is set to the command name. For example::
-
- | subCommands = [
- | ['inquisition', 'inquest', InquisitionOptions,
- | 'Perform an inquisition'],
- | ['holyquest', 'quest', HolyQuestOptions,
- | 'Embark upon a holy quest']
- | ]
-
- In this case, C{"<program> holyquest --horseback --for-grail"} will cause
- C{HolyQuestOptions} to be instantiated and asked to parse
- C{['--horseback', '--for-grail']}. Currently, only the first sub-command
- is parsed, and all options following it are passed to its parser. If a
- subcommand is found, the subCommand attribute is set to its name and the
- subOptions attribute is set to the Option instance that parses the
- remaining options. If a subcommand is not given to parseOptions,
- the subCommand attribute will be None. You can also mark one of
- the subCommands to be the default.
-
- | defaultSubCommand = 'holyquest'
-
- In this case, the subCommand attribute will never be None, and
- the subOptions attribute will always be set.
-
- If you want to handle your own options, define a method named
- C{opt_paramname} that takes C{(self, option)} as arguments. C{option}
- will be whatever immediately follows the parameter on the
- command line. Options fully supports the mapping interface, so you
- can do things like C{'self["option"] = val'} in these methods.
-
- Shell tab-completion is supported by this class, for zsh only at present.
- Zsh ships with a stub file ("completion function") which, for Twisted
- commands, performs tab-completion on-the-fly using the support provided
- by this class. The stub file lives in our tree at
- C{twisted/python/twisted-completion.zsh}, and in the Zsh tree at
- C{Completion/Unix/Command/_twisted}.
-
- Tab-completion is based upon the contents of the optFlags and optParameters
- lists. And, optionally, additional metadata may be provided by assigning a
- special attribute, C{compData}, which should be an instance of
- C{Completions}. See that class for details of what can and should be
- included - and see the howto for additional help using these features -
- including how third-parties may take advantage of tab-completion for their
- own commands.
-
- Advanced functionality is covered in the howto documentation,
- available at
- U{http://twistedmatrix.com/projects/core/documentation/howto/options.html},
- or doc/core/howto/options.xhtml in your Twisted directory.
- """
-
- subCommand = None
- defaultSubCommand = None
- parent = None
- completionData = None
- _shellCompFile = sys.stdout # file to use if shell completion is requested
- def __init__(self):
- super(Options, self).__init__()
-
- self.opts = self
- self.defaults = {}
-
- # These are strings/lists we will pass to getopt
- self.longOpt = []
- self.shortOpt = ''
- self.docs = {}
- self.synonyms = {}
- self._dispatch = {}
-
-
- collectors = [
- self._gather_flags,
- self._gather_parameters,
- self._gather_handlers,
- ]
-
- for c in collectors:
- (longOpt, shortOpt, docs, settings, synonyms, dispatch) = c()
- self.longOpt.extend(longOpt)
- self.shortOpt = self.shortOpt + shortOpt
- self.docs.update(docs)
-
- self.opts.update(settings)
- self.defaults.update(settings)
-
- self.synonyms.update(synonyms)
- self._dispatch.update(dispatch)
-
- def __hash__(self):
- """
- Define a custom hash function so that Options instances can be used
- as dictionary keys. This is an internal feature used to implement
- the parser. Do not rely on it in application code.
- """
- return int(id(self) % sys.maxint)
-
- def opt_help(self):
- """
- Display this help and exit.
- """
- print self.__str__()
- sys.exit(0)
-
- def opt_version(self):
- """
- Display Twisted version and exit.
- """
- from twisted import copyright
- print "Twisted version:", copyright.version
- sys.exit(0)
-
- #opt_h = opt_help # this conflicted with existing 'host' options.
-
- def parseOptions(self, options=None):
- """
- The guts of the command-line parser.
- """
-
- if options is None:
- options = sys.argv[1:]
-
- # we really do need to place the shell completion check here, because
- # if we used an opt_shell_completion method then it would be possible
- # for other opt_* methods to be run first, and they could possibly
- # raise validation errors which would result in error output on the
- # terminal of the user performing shell completion. Validation errors
- # would occur quite frequently, in fact, because users often initiate
- # tab-completion while they are editing an unfinished command-line.
- if len(options) > 1 and options[-2] == "--_shell-completion":
- from twisted.python import _shellcomp
- cmdName = path.basename(sys.argv[0])
- _shellcomp.shellComplete(self, cmdName, options,
- self._shellCompFile)
- sys.exit(0)
-
- try:
- opts, args = getopt.getopt(options,
- self.shortOpt, self.longOpt)
- except getopt.error, e:
- raise UsageError(str(e))
-
- for opt, arg in opts:
- if opt[1] == '-':
- opt = opt[2:]
- else:
- opt = opt[1:]
-
- optMangled = opt
- if optMangled not in self.synonyms:
- optMangled = opt.replace("-", "_")
- if optMangled not in self.synonyms:
- raise UsageError("No such option '%s'" % (opt,))
-
- optMangled = self.synonyms[optMangled]
- if isinstance(self._dispatch[optMangled], CoerceParameter):
- self._dispatch[optMangled].dispatch(optMangled, arg)
- else:
- self._dispatch[optMangled](optMangled, arg)
-
- if (getattr(self, 'subCommands', None)
- and (args or self.defaultSubCommand is not None)):
- if not args:
- args = [self.defaultSubCommand]
- sub, rest = args[0], args[1:]
- for (cmd, short, parser, doc) in self.subCommands:
- if sub == cmd or sub == short:
- self.subCommand = cmd
- self.subOptions = parser()
- self.subOptions.parent = self
- self.subOptions.parseOptions(rest)
- break
- else:
- raise UsageError("Unknown command: %s" % sub)
- else:
- try:
- self.parseArgs(*args)
- except TypeError:
- raise UsageError("Wrong number of arguments.")
-
- self.postOptions()
-
- def postOptions(self):
- """
- I am called after the options are parsed.
-
- Override this method in your subclass to do something after
- the options have been parsed and assigned, like validate that
- all options are sane.
- """
-
- def parseArgs(self):
- """
- I am called with any leftover arguments which were not options.
-
- Override me to do something with the remaining arguments on
- the command line, those which were not flags or options. e.g.
- interpret them as a list of files to operate on.
-
- Note that if there more arguments on the command line
- than this method accepts, parseArgs will blow up with
- a getopt.error. This means if you don't override me,
- parseArgs will blow up if I am passed any arguments at
- all!
- """
-
- def _generic_flag(self, flagName, value=None):
- if value not in ('', None):
- raise UsageError("Flag '%s' takes no argument."
- " Not even \"%s\"." % (flagName, value))
-
- self.opts[flagName] = 1
-
- def _gather_flags(self):
- """
- Gather up boolean (flag) options.
- """
-
- longOpt, shortOpt = [], ''
- docs, settings, synonyms, dispatch = {}, {}, {}, {}
-
- flags = []
- reflect.accumulateClassList(self.__class__, 'optFlags', flags)
-
- for flag in flags:
- long, short, doc = util.padTo(3, flag)
- if not long:
- raise ValueError("A flag cannot be without a name.")
-
- docs[long] = doc
- settings[long] = 0
- if short:
- shortOpt = shortOpt + short
- synonyms[short] = long
- longOpt.append(long)
- synonyms[long] = long
- dispatch[long] = self._generic_flag
-
- return longOpt, shortOpt, docs, settings, synonyms, dispatch
-
- def _gather_parameters(self):
- """
- Gather options which take a value.
- """
- longOpt, shortOpt = [], ''
- docs, settings, synonyms, dispatch = {}, {}, {}, {}
-
- parameters = []
-
- reflect.accumulateClassList(self.__class__, 'optParameters',
- parameters)
-
- synonyms = {}
-
- for parameter in parameters:
- long, short, default, doc, paramType = util.padTo(5, parameter)
- if not long:
- raise ValueError("A parameter cannot be without a name.")
-
- docs[long] = doc
- settings[long] = default
- if short:
- shortOpt = shortOpt + short + ':'
- synonyms[short] = long
- longOpt.append(long + '=')
- synonyms[long] = long
- if paramType is not None:
- dispatch[long] = CoerceParameter(self, paramType)
- else:
- dispatch[long] = CoerceParameter(self, str)
-
- return longOpt, shortOpt, docs, settings, synonyms, dispatch
-
-
- def _gather_handlers(self):
- """
- Gather up options with their own handler methods.
-
- This returns a tuple of many values. Amongst those values is a
- synonyms dictionary, mapping all of the possible aliases (C{str})
- for an option to the longest spelling of that option's name
- C({str}).
-
- Another element is a dispatch dictionary, mapping each user-facing
- option name (with - substituted for _) to a callable to handle that
- option.
- """
-
- longOpt, shortOpt = [], ''
- docs, settings, synonyms, dispatch = {}, {}, {}, {}
-
- dct = {}
- reflect.addMethodNamesToDict(self.__class__, dct, "opt_")
-
- for name in dct.keys():
- method = getattr(self, 'opt_'+name)
-
- takesArg = not flagFunction(method, name)
-
- prettyName = name.replace('_', '-')
- doc = getattr(method, '__doc__', None)
- if doc:
- ## Only use the first line.
- #docs[name] = doc.split('\n')[0]
- docs[prettyName] = doc
- else:
- docs[prettyName] = self.docs.get(prettyName)
-
- synonyms[prettyName] = prettyName
-
- # A little slight-of-hand here makes dispatching much easier
- # in parseOptions, as it makes all option-methods have the
- # same signature.
- if takesArg:
- fn = lambda name, value, m=method: m(value)
- else:
- # XXX: This won't raise a TypeError if it's called
- # with a value when it shouldn't be.
- fn = lambda name, value=None, m=method: m()
-
- dispatch[prettyName] = fn
-
- if len(name) == 1:
- shortOpt = shortOpt + name
- if takesArg:
- shortOpt = shortOpt + ':'
- else:
- if takesArg:
- prettyName = prettyName + '='
- longOpt.append(prettyName)
-
- reverse_dct = {}
- # Map synonyms
- for name in dct.keys():
- method = getattr(self, 'opt_' + name)
- if method not in reverse_dct:
- reverse_dct[method] = []
- reverse_dct[method].append(name.replace('_', '-'))
-
- cmpLength = lambda a, b: cmp(len(a), len(b))
-
- for method, names in reverse_dct.items():
- if len(names) < 2:
- continue
- names_ = names[:]
- names_.sort(cmpLength)
- longest = names_.pop()
- for name in names_:
- synonyms[name] = longest
-
- return longOpt, shortOpt, docs, settings, synonyms, dispatch
-
-
- def __str__(self):
- return self.getSynopsis() + '\n' + self.getUsage(width=None)
-
- def getSynopsis(self):
- """
- Returns a string containing a description of these options and how to
- pass them to the executed file.
- """
-
- default = "%s%s" % (path.basename(sys.argv[0]),
- (self.longOpt and " [options]") or '')
- if self.parent is None:
- default = "Usage: %s%s" % (path.basename(sys.argv[0]),
- (self.longOpt and " [options]") or '')
- else:
- default = '%s' % ((self.longOpt and "[options]") or '')
- synopsis = getattr(self, "synopsis", default)
-
- synopsis = synopsis.rstrip()
-
- if self.parent is not None:
- synopsis = ' '.join((self.parent.getSynopsis(),
- self.parent.subCommand, synopsis))
-
- return synopsis
-
- def getUsage(self, width=None):
- # If subOptions exists by now, then there was probably an error while
- # parsing its options.
- if hasattr(self, 'subOptions'):
- return self.subOptions.getUsage(width=width)
-
- if not width:
- width = int(os.environ.get('COLUMNS', '80'))
-
- if hasattr(self, 'subCommands'):
- cmdDicts = []
- for (cmd, short, parser, desc) in self.subCommands:
- cmdDicts.append(
- {'long': cmd,
- 'short': short,
- 'doc': desc,
- 'optType': 'command',
- 'default': None
- })
- chunks = docMakeChunks(cmdDicts, width)
- commands = 'Commands:\n' + ''.join(chunks)
- else:
- commands = ''
-
- longToShort = {}
- for key, value in self.synonyms.items():
- longname = value
- if (key != longname) and (len(key) == 1):
- longToShort[longname] = key
- else:
- if longname not in longToShort:
- longToShort[longname] = None
- else:
- pass
-
- optDicts = []
- for opt in self.longOpt:
- if opt[-1] == '=':
- optType = 'parameter'
- opt = opt[:-1]
- else:
- optType = 'flag'
-
- optDicts.append(
- {'long': opt,
- 'short': longToShort[opt],
- 'doc': self.docs[opt],
- 'optType': optType,
- 'default': self.defaults.get(opt, None),
- 'dispatch': self._dispatch.get(opt, None)
- })
-
- if not (getattr(self, "longdesc", None) is None):
- longdesc = self.longdesc
- else:
- import __main__
- if getattr(__main__, '__doc__', None):
- longdesc = __main__.__doc__
- else:
- longdesc = ''
-
- if longdesc:
- longdesc = ('\n' +
- '\n'.join(text.wordWrap(longdesc, width)).strip()
- + '\n')
-
- if optDicts:
- chunks = docMakeChunks(optDicts, width)
- s = "Options:\n%s" % (''.join(chunks))
- else:
- s = "Options: None\n"
-
- return s + longdesc + commands
-
- #def __repr__(self):
- # XXX: It'd be cool if we could return a succinct representation
- # of which flags and options are set here.
-
-
-_ZSH = 'zsh'
-_BASH = 'bash'
-
-class Completer(object):
- """
- A completion "action" - provides completion possibilities for a particular
- command-line option. For example we might provide the user a fixed list of
- choices, or files/dirs according to a glob.
-
- This class produces no completion matches itself - see the various
- subclasses for specific completion functionality.
- """
- _descr = None
- def __init__(self, descr=None, repeat=False):
- """
- @type descr: C{str}
- @param descr: An optional descriptive string displayed above matches.
-
- @type repeat: C{bool}
- @param repeat: A flag, defaulting to False, indicating whether this
- C{Completer} should repeat - that is, be used to complete more
- than one command-line word. This may ONLY be set to True for
- actions in the C{extraActions} keyword argument to C{Completions}.
- And ONLY if it is the LAST (or only) action in the C{extraActions}
- list.
- """
- if descr is not None:
- self._descr = descr
- self._repeat = repeat
-
-
- def _getRepeatFlag(self):
- if self._repeat:
- return "*"
- else:
- return ""
- _repeatFlag = property(_getRepeatFlag)
-
-
- def _description(self, optName):
- if self._descr is not None:
- return self._descr
- else:
- return optName
-
-
- def _shellCode(self, optName, shellType):
- """
- Fetch a fragment of shell code representing this action which is
- suitable for use by the completion system in _shellcomp.py
-
- @type optName: C{str}
- @param optName: The long name of the option this action is being
- used for.
-
- @type shellType: C{str}
- @param shellType: One of the supported shell constants e.g.
- C{twisted.python.usage._ZSH}
- """
- if shellType == _ZSH:
- return "%s:%s:" % (self._repeatFlag,
- self._description(optName))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteFiles(Completer):
- """
- Completes file names based on a glob pattern
- """
- def __init__(self, globPattern='*', **kw):
- Completer.__init__(self, **kw)
- self._globPattern = globPattern
-
-
- def _description(self, optName):
- if self._descr is not None:
- return "%s (%s)" % (self._descr, self._globPattern)
- else:
- return "%s (%s)" % (optName, self._globPattern)
-
-
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_files -g \"%s\"" % (self._repeatFlag,
- self._description(optName),
- self._globPattern,)
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteDirs(Completer):
- """
- Completes directory names
- """
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_directories" % (self._repeatFlag,
- self._description(optName))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteList(Completer):
- """
- Completes based on a fixed list of words
- """
- def __init__(self, items, **kw):
- Completer.__init__(self, **kw)
- self._items = items
-
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:(%s)" % (self._repeatFlag,
- self._description(optName),
- " ".join(self._items,))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteMultiList(Completer):
- """
- Completes multiple comma-separated items based on a fixed list of words
- """
- def __init__(self, items, **kw):
- Completer.__init__(self, **kw)
- self._items = items
-
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_values -s , '%s' %s" % (self._repeatFlag,
- self._description(optName),
- self._description(optName),
- " ".join(self._items))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteUsernames(Completer):
- """
- Complete usernames
- """
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_users" % (self._repeatFlag,
- self._description(optName))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteGroups(Completer):
- """
- Complete system group names
- """
- _descr = 'group'
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_groups" % (self._repeatFlag,
- self._description(optName))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteHostnames(Completer):
- """
- Complete hostnames
- """
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_hosts" % (self._repeatFlag,
- self._description(optName))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteUserAtHost(Completer):
- """
- A completion action which produces matches in any of these forms::
- <username>
- <hostname>
- <username>@<hostname>
- """
- _descr = 'host | user@host'
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- # Yes this looks insane but it does work. For bonus points
- # add code to grep 'Hostname' lines from ~/.ssh/config
- return ('%s:%s:{_ssh;if compset -P "*@"; '
- 'then _wanted hosts expl "remote host name" _ssh_hosts '
- '&& ret=0 elif compset -S "@*"; then _wanted users '
- 'expl "login name" _ssh_users -S "" && ret=0 '
- 'else if (( $+opt_args[-l] )); then tmp=() '
- 'else tmp=( "users:login name:_ssh_users -qS@" ) fi; '
- '_alternative "hosts:remote host name:_ssh_hosts" "$tmp[@]"'
- ' && ret=0 fi}' % (self._repeatFlag,
- self._description(optName)))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class CompleteNetInterfaces(Completer):
- """
- Complete network interface names
- """
- def _shellCode(self, optName, shellType):
- if shellType == _ZSH:
- return "%s:%s:_net_interfaces" % (self._repeatFlag,
- self._description(optName))
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class Completions(object):
- """
- Extra metadata for the shell tab-completion system.
-
- @type descriptions: C{dict}
- @ivar descriptions: ex. C{{"foo" : "use this description for foo instead"}}
- A dict mapping long option names to alternate descriptions. When this
- variable is defined, the descriptions contained here will override
- those descriptions provided in the optFlags and optParameters
- variables.
-
- @type multiUse: C{list}
- @ivar multiUse: ex. C{ ["foo", "bar"] }
- An iterable containing those long option names which may appear on the
- command line more than once. By default, options will only be completed
- one time.
-
- @type mutuallyExclusive: C{list} of C{tuple}
- @ivar mutuallyExclusive: ex. C{ [("foo", "bar"), ("bar", "baz")] }
- A sequence of sequences, with each sub-sequence containing those long
- option names that are mutually exclusive. That is, those options that
- cannot appear on the command line together.
-
- @type optActions: C{dict}
- @ivar optActions: A dict mapping long option names to shell "actions".
- These actions define what may be completed as the argument to the
- given option. By default, all files/dirs will be completed if no
- action is given. For example::
-
- {"foo" : CompleteFiles("*.py", descr="python files"),
- "bar" : CompleteList(["one", "two", "three"]),
- "colors" : CompleteMultiList(["red", "green", "blue"])}
-
- Callables may instead be given for the values in this dict. The
- callable should accept no arguments, and return a C{Completer}
- instance used as the action in the same way as the literal actions in
- the example above.
-
- As you can see in the example above. The "foo" option will have files
- that end in .py completed when the user presses Tab. The "bar"
- option will have either of the strings "one", "two", or "three"
- completed when the user presses Tab.
-
- "colors" will allow multiple arguments to be completed, seperated by
- commas. The possible arguments are red, green, and blue. Examples::
-
- my_command --foo some-file.foo --colors=red,green
- my_command --colors=green
- my_command --colors=green,blue
-
- Descriptions for the actions may be given with the optional C{descr}
- keyword argument. This is separate from the description of the option
- itself.
-
- Normally Zsh does not show these descriptions unless you have
- "verbose" completion turned on. Turn on verbosity with this in your
- ~/.zshrc::
-
- zstyle ':completion:*' verbose yes
- zstyle ':completion:*:descriptions' format '%B%d%b'
-
- @type extraActions: C{list}
- @ivar extraActions: Extra arguments are those arguments typically
- appearing at the end of the command-line, which are not associated
- with any particular named option. That is, the arguments that are
- given to the parseArgs() method of your usage.Options subclass. For
- example::
- [CompleteFiles(descr="file to read from"),
- Completer(descr="book title")]
-
- In the example above, the 1st non-option argument will be described as
- "file to read from" and all file/dir names will be completed (*). The
- 2nd non-option argument will be described as "book title", but no
- actual completion matches will be produced.
-
- See the various C{Completer} subclasses for other types of things which
- may be tab-completed (users, groups, network interfaces, etc).
-
- Also note the C{repeat=True} flag which may be passed to any of the
- C{Completer} classes. This is set to allow the C{Completer} instance
- to be re-used for subsequent command-line words. See the C{Completer}
- docstring for details.
- """
- def __init__(self, descriptions={}, multiUse=[],
- mutuallyExclusive=[], optActions={}, extraActions=[]):
- self.descriptions = descriptions
- self.multiUse = multiUse
- self.mutuallyExclusive = mutuallyExclusive
- self.optActions = optActions
- self.extraActions = extraActions
-
-
-
-def docMakeChunks(optList, width=80):
- """
- Makes doc chunks for option declarations.
-
- Takes a list of dictionaries, each of which may have one or more
- of the keys 'long', 'short', 'doc', 'default', 'optType'.
-
- Returns a list of strings.
- The strings may be multiple lines,
- all of them end with a newline.
- """
-
- # XXX: sanity check to make sure we have a sane combination of keys.
-
- maxOptLen = 0
- for opt in optList:
- optLen = len(opt.get('long', ''))
- if optLen:
- if opt.get('optType', None) == "parameter":
- # these take up an extra character
- optLen = optLen + 1
- maxOptLen = max(optLen, maxOptLen)
-
- colWidth1 = maxOptLen + len(" -s, -- ")
- colWidth2 = width - colWidth1
- # XXX - impose some sane minimum limit.
- # Then if we don't have enough room for the option and the doc
- # to share one line, they can take turns on alternating lines.
-
- colFiller1 = " " * colWidth1
-
- optChunks = []
- seen = {}
- for opt in optList:
- if opt.get('short', None) in seen or opt.get('long', None) in seen:
- continue
- for x in opt.get('short', None), opt.get('long', None):
- if x is not None:
- seen[x] = 1
-
- optLines = []
- comma = " "
- if opt.get('short', None):
- short = "-%c" % (opt['short'],)
- else:
- short = ''
-
- if opt.get('long', None):
- long = opt['long']
- if opt.get("optType", None) == "parameter":
- long = long + '='
-
- long = "%-*s" % (maxOptLen, long)
- if short:
- comma = ","
- else:
- long = " " * (maxOptLen + len('--'))
-
- if opt.get('optType', None) == 'command':
- column1 = ' %s ' % long
- else:
- column1 = " %2s%c --%s " % (short, comma, long)
-
- if opt.get('doc', ''):
- doc = opt['doc'].strip()
- else:
- doc = ''
-
- if (opt.get("optType", None) == "parameter") \
- and not (opt.get('default', None) is None):
- doc = "%s [default: %s]" % (doc, opt['default'])
-
- if (opt.get("optType", None) == "parameter") \
- and opt.get('dispatch', None) is not None:
- d = opt['dispatch']
- if isinstance(d, CoerceParameter) and d.doc:
- doc = "%s. %s" % (doc, d.doc)
-
- if doc:
- column2_l = text.wordWrap(doc, colWidth2)
- else:
- column2_l = ['']
-
- optLines.append("%s%s\n" % (column1, column2_l.pop(0)))
-
- for line in column2_l:
- optLines.append("%s%s\n" % (colFiller1, line))
-
- optChunks.append(''.join(optLines))
-
- return optChunks
-
-
-def flagFunction(method, name=None):
- reqArgs = method.im_func.func_code.co_argcount
- if reqArgs > 2:
- raise UsageError('Invalid Option function for %s' %
- (name or method.func_name))
- if reqArgs == 2:
- # argName = method.im_func.func_code.co_varnames[1]
- return 0
- return 1
-
-
-def portCoerce(value):
- """
- Coerce a string value to an int port number, and checks the validity.
- """
- value = int(value)
- if value < 0 or value > 65535:
- raise ValueError("Port number not in range: %s" % (value,))
- return value
-portCoerce.coerceDoc = "Must be an int between 0 and 65535."
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/util.py
deleted file mode 100755
index 852043ce..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/util.py
+++ /dev/null
@@ -1,998 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_util -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import os, sys, errno, inspect, warnings
-import types
-try:
- import pwd, grp
-except ImportError:
- pwd = grp = None
-try:
- from os import setgroups, getgroups
-except ImportError:
- setgroups = getgroups = None
-from UserDict import UserDict
-
-
-class InsensitiveDict:
- """Dictionary, that has case-insensitive keys.
-
- Normally keys are retained in their original form when queried with
- .keys() or .items(). If initialized with preserveCase=0, keys are both
- looked up in lowercase and returned in lowercase by .keys() and .items().
- """
- """
- Modified recipe at
- http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66315 originally
- contributed by Sami Hangaslammi.
- """
-
- def __init__(self, dict=None, preserve=1):
- """Create an empty dictionary, or update from 'dict'."""
- self.data = {}
- self.preserve=preserve
- if dict:
- self.update(dict)
-
- def __delitem__(self, key):
- k=self._lowerOrReturn(key)
- del self.data[k]
-
- def _lowerOrReturn(self, key):
- if isinstance(key, str) or isinstance(key, unicode):
- return key.lower()
- else:
- return key
-
- def __getitem__(self, key):
- """Retrieve the value associated with 'key' (in any case)."""
- k = self._lowerOrReturn(key)
- return self.data[k][1]
-
- def __setitem__(self, key, value):
- """Associate 'value' with 'key'. If 'key' already exists, but
- in different case, it will be replaced."""
- k = self._lowerOrReturn(key)
- self.data[k] = (key, value)
-
- def has_key(self, key):
- """Case insensitive test whether 'key' exists."""
- k = self._lowerOrReturn(key)
- return k in self.data
-
- __contains__=has_key
-
- def _doPreserve(self, key):
- if not self.preserve and (isinstance(key, str)
- or isinstance(key, unicode)):
- return key.lower()
- else:
- return key
-
- def keys(self):
- """List of keys in their original case."""
- return list(self.iterkeys())
-
- def values(self):
- """List of values."""
- return list(self.itervalues())
-
- def items(self):
- """List of (key,value) pairs."""
- return list(self.iteritems())
-
- def get(self, key, default=None):
- """Retrieve value associated with 'key' or return default value
- if 'key' doesn't exist."""
- try:
- return self[key]
- except KeyError:
- return default
-
- def setdefault(self, key, default):
- """If 'key' doesn't exists, associate it with the 'default' value.
- Return value associated with 'key'."""
- if not self.has_key(key):
- self[key] = default
- return self[key]
-
- def update(self, dict):
- """Copy (key,value) pairs from 'dict'."""
- for k,v in dict.items():
- self[k] = v
-
- def __repr__(self):
- """String representation of the dictionary."""
- items = ", ".join([("%r: %r" % (k,v)) for k,v in self.items()])
- return "InsensitiveDict({%s})" % items
-
- def iterkeys(self):
- for v in self.data.itervalues():
- yield self._doPreserve(v[0])
-
- def itervalues(self):
- for v in self.data.itervalues():
- yield v[1]
-
- def iteritems(self):
- for (k, v) in self.data.itervalues():
- yield self._doPreserve(k), v
-
- def popitem(self):
- i=self.items()[0]
- del self[i[0]]
- return i
-
- def clear(self):
- for k in self.keys():
- del self[k]
-
- def copy(self):
- return InsensitiveDict(self, self.preserve)
-
- def __len__(self):
- return len(self.data)
-
- def __eq__(self, other):
- for k,v in self.items():
- if not (k in other) or not (other[k]==v):
- return 0
- return len(self)==len(other)
-
-class OrderedDict(UserDict):
- """A UserDict that preserves insert order whenever possible."""
- def __init__(self, dict=None, **kwargs):
- self._order = []
- self.data = {}
- if dict is not None:
- if hasattr(dict,'keys'):
- self.update(dict)
- else:
- for k,v in dict: # sequence
- self[k] = v
- if len(kwargs):
- self.update(kwargs)
- def __repr__(self):
- return '{'+', '.join([('%r: %r' % item) for item in self.items()])+'}'
-
- def __setitem__(self, key, value):
- if not self.has_key(key):
- self._order.append(key)
- UserDict.__setitem__(self, key, value)
-
- def copy(self):
- return self.__class__(self)
-
- def __delitem__(self, key):
- UserDict.__delitem__(self, key)
- self._order.remove(key)
-
- def iteritems(self):
- for item in self._order:
- yield (item, self[item])
-
- def items(self):
- return list(self.iteritems())
-
- def itervalues(self):
- for item in self._order:
- yield self[item]
-
- def values(self):
- return list(self.itervalues())
-
- def iterkeys(self):
- return iter(self._order)
-
- def keys(self):
- return list(self._order)
-
- def popitem(self):
- key = self._order[-1]
- value = self[key]
- del self[key]
- return (key, value)
-
- def setdefault(self, item, default):
- if self.has_key(item):
- return self[item]
- self[item] = default
- return default
-
- def update(self, d):
- for k, v in d.items():
- self[k] = v
-
-def uniquify(lst):
- """Make the elements of a list unique by inserting them into a dictionary.
- This must not change the order of the input lst.
- """
- dct = {}
- result = []
- for k in lst:
- if k not in dct:
- result.append(k)
- dct[k] = 1
- return result
-
-def padTo(n, seq, default=None):
- """
- Pads a sequence out to n elements,
-
- filling in with a default value if it is not long enough.
-
- If the input sequence is longer than n, raises ValueError.
-
- Details, details:
- This returns a new list; it does not extend the original sequence.
- The new list contains the values of the original sequence, not copies.
- """
-
- if len(seq) > n:
- raise ValueError, "%d elements is more than %d." % (len(seq), n)
-
- blank = [default] * n
-
- blank[:len(seq)] = list(seq)
-
- return blank
-
-
-def getPluginDirs():
- warnings.warn(
- "twisted.python.util.getPluginDirs is deprecated since Twisted 12.2.",
- DeprecationWarning, stacklevel=2)
- import twisted
- systemPlugins = os.path.join(os.path.dirname(os.path.dirname(
- os.path.abspath(twisted.__file__))), 'plugins')
- userPlugins = os.path.expanduser("~/TwistedPlugins")
- confPlugins = os.path.expanduser("~/.twisted")
- allPlugins = filter(os.path.isdir, [systemPlugins, userPlugins, confPlugins])
- return allPlugins
-
-
-def addPluginDir():
- warnings.warn(
- "twisted.python.util.addPluginDir is deprecated since Twisted 12.2.",
- DeprecationWarning, stacklevel=2)
- sys.path.extend(getPluginDirs())
-
-
-def sibpath(path, sibling):
- """
- Return the path to a sibling of a file in the filesystem.
-
- This is useful in conjunction with the special C{__file__} attribute
- that Python provides for modules, so modules can load associated
- resource files.
- """
- return os.path.join(os.path.dirname(os.path.abspath(path)), sibling)
-
-
-def _getpass(prompt):
- """
- Helper to turn IOErrors into KeyboardInterrupts.
- """
- import getpass
- try:
- return getpass.getpass(prompt)
- except IOError, e:
- if e.errno == errno.EINTR:
- raise KeyboardInterrupt
- raise
- except EOFError:
- raise KeyboardInterrupt
-
-def getPassword(prompt = 'Password: ', confirm = 0, forceTTY = 0,
- confirmPrompt = 'Confirm password: ',
- mismatchMessage = "Passwords don't match."):
- """Obtain a password by prompting or from stdin.
-
- If stdin is a terminal, prompt for a new password, and confirm (if
- C{confirm} is true) by asking again to make sure the user typed the same
- thing, as keystrokes will not be echoed.
-
- If stdin is not a terminal, and C{forceTTY} is not true, read in a line
- and use it as the password, less the trailing newline, if any. If
- C{forceTTY} is true, attempt to open a tty and prompt for the password
- using it. Raise a RuntimeError if this is not possible.
-
- @returns: C{str}
- """
- isaTTY = hasattr(sys.stdin, 'isatty') and sys.stdin.isatty()
-
- old = None
- try:
- if not isaTTY:
- if forceTTY:
- try:
- old = sys.stdin, sys.stdout
- sys.stdin = sys.stdout = open('/dev/tty', 'r+')
- except:
- raise RuntimeError("Cannot obtain a TTY")
- else:
- password = sys.stdin.readline()
- if password[-1] == '\n':
- password = password[:-1]
- return password
-
- while 1:
- try1 = _getpass(prompt)
- if not confirm:
- return try1
- try2 = _getpass(confirmPrompt)
- if try1 == try2:
- return try1
- else:
- sys.stderr.write(mismatchMessage + "\n")
- finally:
- if old:
- sys.stdin.close()
- sys.stdin, sys.stdout = old
-
-
-def println(*a):
- sys.stdout.write(' '.join(map(str, a))+'\n')
-
-# XXX
-# This does not belong here
-# But where does it belong?
-
-def str_xor(s, b):
- return ''.join([chr(ord(c) ^ b) for c in s])
-
-
-def makeStatBar(width, maxPosition, doneChar = '=', undoneChar = '-', currentChar = '>'):
- """
- Creates a function that will return a string representing a progress bar.
- """
- aValue = width / float(maxPosition)
- def statBar(position, force = 0, last = ['']):
- assert len(last) == 1, "Don't mess with the last parameter."
- done = int(aValue * position)
- toDo = width - done - 2
- result = "[%s%s%s]" % (doneChar * done, currentChar, undoneChar * toDo)
- if force:
- last[0] = result
- return result
- if result == last[0]:
- return ''
- last[0] = result
- return result
-
- statBar.__doc__ = """statBar(position, force = 0) -> '[%s%s%s]'-style progress bar
-
- returned string is %d characters long, and the range goes from 0..%d.
- The 'position' argument is where the '%s' will be drawn. If force is false,
- '' will be returned instead if the resulting progress bar is identical to the
- previously returned progress bar.
-""" % (doneChar * 3, currentChar, undoneChar * 3, width, maxPosition, currentChar)
- return statBar
-
-
-def spewer(frame, s, ignored):
- """
- A trace function for sys.settrace that prints every function or method call.
- """
- from twisted.python import reflect
- if frame.f_locals.has_key('self'):
- se = frame.f_locals['self']
- if hasattr(se, '__class__'):
- k = reflect.qual(se.__class__)
- else:
- k = reflect.qual(type(se))
- print 'method %s of %s at %s' % (
- frame.f_code.co_name, k, id(se)
- )
- else:
- print 'function %s in %s, line %s' % (
- frame.f_code.co_name,
- frame.f_code.co_filename,
- frame.f_lineno)
-
-
-def searchupwards(start, files=[], dirs=[]):
- """
- Walk upwards from start, looking for a directory containing
- all files and directories given as arguments::
- >>> searchupwards('.', ['foo.txt'], ['bar', 'bam'])
-
- If not found, return None
- """
- start=os.path.abspath(start)
- parents=start.split(os.sep)
- exists=os.path.exists; join=os.sep.join; isdir=os.path.isdir
- while len(parents):
- candidate=join(parents)+os.sep
- allpresent=1
- for f in files:
- if not exists("%s%s" % (candidate, f)):
- allpresent=0
- break
- if allpresent:
- for d in dirs:
- if not isdir("%s%s" % (candidate, d)):
- allpresent=0
- break
- if allpresent: return candidate
- parents.pop(-1)
- return None
-
-
-class LineLog:
- """
- A limited-size line-based log, useful for logging line-based
- protocols such as SMTP.
-
- When the log fills up, old entries drop off the end.
- """
- def __init__(self, size=10):
- """
- Create a new log, with size lines of storage (default 10).
- A log size of 0 (or less) means an infinite log.
- """
- if size < 0:
- size = 0
- self.log = [None]*size
- self.size = size
-
- def append(self,line):
- if self.size:
- self.log[:-1] = self.log[1:]
- self.log[-1] = line
- else:
- self.log.append(line)
-
- def str(self):
- return '\n'.join(filter(None,self.log))
-
- def __getitem__(self, item):
- return filter(None,self.log)[item]
-
- def clear(self):
- """Empty the log"""
- self.log = [None]*self.size
-
-
-def raises(exception, f, *args, **kwargs):
- """
- Determine whether the given call raises the given exception.
- """
- try:
- f(*args, **kwargs)
- except exception:
- return 1
- return 0
-
-
-class IntervalDifferential:
- """
- Given a list of intervals, generate the amount of time to sleep between
- "instants".
-
- For example, given 7, 11 and 13, the three (infinite) sequences::
-
- 7 14 21 28 35 ...
- 11 22 33 44 ...
- 13 26 39 52 ...
-
- will be generated, merged, and used to produce::
-
- (7, 0) (4, 1) (2, 2) (1, 0) (7, 0) (1, 1) (4, 2) (2, 0) (5, 1) (2, 0)
-
- New intervals may be added or removed as iteration proceeds using the
- proper methods.
- """
-
- def __init__(self, intervals, default=60):
- """
- @type intervals: C{list} of C{int}, C{long}, or C{float} param
- @param intervals: The intervals between instants.
-
- @type default: C{int}, C{long}, or C{float}
- @param default: The duration to generate if the intervals list
- becomes empty.
- """
- self.intervals = intervals[:]
- self.default = default
-
- def __iter__(self):
- return _IntervalDifferentialIterator(self.intervals, self.default)
-
-
-class _IntervalDifferentialIterator:
- def __init__(self, i, d):
-
- self.intervals = [[e, e, n] for (e, n) in zip(i, range(len(i)))]
- self.default = d
- self.last = 0
-
- def next(self):
- if not self.intervals:
- return (self.default, None)
- last, index = self.intervals[0][0], self.intervals[0][2]
- self.intervals[0][0] += self.intervals[0][1]
- self.intervals.sort()
- result = last - self.last
- self.last = last
- return result, index
-
- def addInterval(self, i):
- if self.intervals:
- delay = self.intervals[0][0] - self.intervals[0][1]
- self.intervals.append([delay + i, i, len(self.intervals)])
- self.intervals.sort()
- else:
- self.intervals.append([i, i, 0])
-
- def removeInterval(self, interval):
- for i in range(len(self.intervals)):
- if self.intervals[i][1] == interval:
- index = self.intervals[i][2]
- del self.intervals[i]
- for i in self.intervals:
- if i[2] > index:
- i[2] -= 1
- return
- raise ValueError, "Specified interval not in IntervalDifferential"
-
-
-class FancyStrMixin:
- """
- Set showAttributes to a sequence of strings naming attributes, OR
- sequences of C{(attributeName, displayName, formatCharacter)}.
- """
- showAttributes = ()
- def __str__(self):
- r = ['<', hasattr(self, 'fancybasename') and self.fancybasename or self.__class__.__name__]
- for attr in self.showAttributes:
- if isinstance(attr, str):
- r.append(' %s=%r' % (attr, getattr(self, attr)))
- else:
- r.append((' %s=' + attr[2]) % (attr[1], getattr(self, attr[0])))
- r.append('>')
- return ''.join(r)
- __repr__ = __str__
-
-
-
-class FancyEqMixin:
- compareAttributes = ()
- def __eq__(self, other):
- if not self.compareAttributes:
- return self is other
- if isinstance(self, other.__class__):
- return (
- [getattr(self, name) for name in self.compareAttributes] ==
- [getattr(other, name) for name in self.compareAttributes])
- return NotImplemented
-
-
- def __ne__(self, other):
- result = self.__eq__(other)
- if result is NotImplemented:
- return result
- return not result
-
-
-
-try:
- from twisted.python._initgroups import initgroups as _c_initgroups
-except ImportError:
- _c_initgroups = None
-
-
-
-if pwd is None or grp is None or setgroups is None or getgroups is None:
- def initgroups(uid, primaryGid):
- """
- Do nothing.
-
- Underlying platform support require to manipulate groups is missing.
- """
-else:
- # Fallback to the inefficient Python version
- def _setgroups_until_success(l):
- while(1):
- # NASTY NASTY HACK (but glibc does it so it must be okay):
- # In case sysconfig didn't give the right answer, find the limit
- # on max groups by just looping, trying to set fewer and fewer
- # groups each time until it succeeds.
- try:
- setgroups(l)
- except ValueError:
- # This exception comes from python itself restricting
- # number of groups allowed.
- if len(l) > 1:
- del l[-1]
- else:
- raise
- except OSError, e:
- if e.errno == errno.EINVAL and len(l) > 1:
- # This comes from the OS saying too many groups
- del l[-1]
- else:
- raise
- else:
- # Success, yay!
- return
-
- def initgroups(uid, primaryGid):
- """
- Initializes the group access list.
-
- If the C extension is present, we're calling it, which in turn calls
- initgroups(3).
-
- If not, this is done by reading the group database /etc/group and using
- all groups of which C{uid} is a member. The additional group
- C{primaryGid} is also added to the list.
-
- If the given user is a member of more than C{NGROUPS}, arbitrary
- groups will be silently discarded to bring the number below that
- limit.
-
- @type uid: C{int}
- @param uid: The UID for which to look up group information.
-
- @type primaryGid: C{int} or C{NoneType}
- @param primaryGid: If provided, an additional GID to include when
- setting the groups.
- """
- if _c_initgroups is not None:
- return _c_initgroups(pwd.getpwuid(uid)[0], primaryGid)
- try:
- # Try to get the maximum number of groups
- max_groups = os.sysconf("SC_NGROUPS_MAX")
- except:
- # No predefined limit
- max_groups = 0
-
- username = pwd.getpwuid(uid)[0]
- l = []
- if primaryGid is not None:
- l.append(primaryGid)
- for groupname, password, gid, userlist in grp.getgrall():
- if username in userlist:
- l.append(gid)
- if len(l) == max_groups:
- break # No more groups, ignore any more
- try:
- _setgroups_until_success(l)
- except OSError, e:
- # We might be able to remove this code now that we
- # don't try to setgid/setuid even when not asked to.
- if e.errno == errno.EPERM:
- for g in getgroups():
- if g not in l:
- raise
- else:
- raise
-
-
-
-def switchUID(uid, gid, euid=False):
- """
- Attempts to switch the uid/euid and gid/egid for the current process.
-
- If C{uid} is the same value as L{os.getuid} (or L{os.geteuid}),
- this function will issue a L{UserWarning} and not raise an exception.
-
- @type uid: C{int} or C{NoneType}
- @param uid: the UID (or EUID) to switch the current process to. This
- parameter will be ignored if the value is C{None}.
-
- @type gid: C{int} or C{NoneType}
- @param gid: the GID (or EGID) to switch the current process to. This
- parameter will be ignored if the value is C{None}.
-
- @type euid: C{bool}
- @param euid: if True, set only effective user-id rather than real user-id.
- (This option has no effect unless the process is running
- as root, in which case it means not to shed all
- privileges, retaining the option to regain privileges
- in cases such as spawning processes. Use with caution.)
- """
- if euid:
- setuid = os.seteuid
- setgid = os.setegid
- getuid = os.geteuid
- else:
- setuid = os.setuid
- setgid = os.setgid
- getuid = os.getuid
- if gid is not None:
- setgid(gid)
- if uid is not None:
- if uid == getuid():
- uidText = (euid and "euid" or "uid")
- actionText = "tried to drop privileges and set%s %s" % (uidText, uid)
- problemText = "%s is already %s" % (uidText, getuid())
- warnings.warn("%s but %s; should we be root? Continuing."
- % (actionText, problemText))
- else:
- initgroups(uid, gid)
- setuid(uid)
-
-
-class SubclassableCStringIO(object):
- """
- A wrapper around cStringIO to allow for subclassing.
- """
- __csio = None
-
- def __init__(self, *a, **kw):
- from cStringIO import StringIO
- self.__csio = StringIO(*a, **kw)
-
- def __iter__(self):
- return self.__csio.__iter__()
-
- def next(self):
- return self.__csio.next()
-
- def close(self):
- return self.__csio.close()
-
- def isatty(self):
- return self.__csio.isatty()
-
- def seek(self, pos, mode=0):
- return self.__csio.seek(pos, mode)
-
- def tell(self):
- return self.__csio.tell()
-
- def read(self, n=-1):
- return self.__csio.read(n)
-
- def readline(self, length=None):
- return self.__csio.readline(length)
-
- def readlines(self, sizehint=0):
- return self.__csio.readlines(sizehint)
-
- def truncate(self, size=None):
- return self.__csio.truncate(size)
-
- def write(self, s):
- return self.__csio.write(s)
-
- def writelines(self, list):
- return self.__csio.writelines(list)
-
- def flush(self):
- return self.__csio.flush()
-
- def getvalue(self):
- return self.__csio.getvalue()
-
-
-
-def untilConcludes(f, *a, **kw):
- while True:
- try:
- return f(*a, **kw)
- except (IOError, OSError), e:
- if e.args[0] == errno.EINTR:
- continue
- raise
-
-_idFunction = id
-
-def setIDFunction(idFunction):
- """
- Change the function used by L{unsignedID} to determine the integer id value
- of an object. This is largely useful for testing to give L{unsignedID}
- deterministic, easily-controlled behavior.
-
- @param idFunction: A function with the signature of L{id}.
- @return: The previous function being used by L{unsignedID}.
- """
- global _idFunction
- oldIDFunction = _idFunction
- _idFunction = idFunction
- return oldIDFunction
-
-
-# A value about twice as large as any Python int, to which negative values
-# from id() will be added, moving them into a range which should begin just
-# above where positive values from id() leave off.
-_HUGEINT = (sys.maxint + 1L) * 2L
-def unsignedID(obj):
- """
- Return the id of an object as an unsigned number so that its hex
- representation makes sense.
-
- This is mostly necessary in Python 2.4 which implements L{id} to sometimes
- return a negative value. Python 2.3 shares this behavior, but also
- implements hex and the %x format specifier to represent negative values as
- though they were positive ones, obscuring the behavior of L{id}. Python
- 2.5's implementation of L{id} always returns positive values.
- """
- rval = _idFunction(obj)
- if rval < 0:
- rval += _HUGEINT
- return rval
-
-
-def mergeFunctionMetadata(f, g):
- """
- Overwrite C{g}'s name and docstring with values from C{f}. Update
- C{g}'s instance dictionary with C{f}'s.
-
- To use this function safely you must use the return value. In Python 2.3,
- L{mergeFunctionMetadata} will create a new function. In later versions of
- Python, C{g} will be mutated and returned.
-
- @return: A function that has C{g}'s behavior and metadata merged from
- C{f}.
- """
- try:
- g.__name__ = f.__name__
- except TypeError:
- try:
- merged = types.FunctionType(
- g.func_code, g.func_globals,
- f.__name__, inspect.getargspec(g)[-1],
- g.func_closure)
- except TypeError:
- pass
- else:
- merged = g
- try:
- merged.__doc__ = f.__doc__
- except (TypeError, AttributeError):
- pass
- try:
- merged.__dict__.update(g.__dict__)
- merged.__dict__.update(f.__dict__)
- except (TypeError, AttributeError):
- pass
- merged.__module__ = f.__module__
- return merged
-
-
-def nameToLabel(mname):
- """
- Convert a string like a variable name into a slightly more human-friendly
- string with spaces and capitalized letters.
-
- @type mname: C{str}
- @param mname: The name to convert to a label. This must be a string
- which could be used as a Python identifier. Strings which do not take
- this form will result in unpredictable behavior.
-
- @rtype: C{str}
- """
- labelList = []
- word = ''
- lastWasUpper = False
- for letter in mname:
- if letter.isupper() == lastWasUpper:
- # Continuing a word.
- word += letter
- else:
- # breaking a word OR beginning a word
- if lastWasUpper:
- # could be either
- if len(word) == 1:
- # keep going
- word += letter
- else:
- # acronym
- # we're processing the lowercase letter after the acronym-then-capital
- lastWord = word[:-1]
- firstLetter = word[-1]
- labelList.append(lastWord)
- word = firstLetter + letter
- else:
- # definitely breaking: lower to upper
- labelList.append(word)
- word = letter
- lastWasUpper = letter.isupper()
- if labelList:
- labelList[0] = labelList[0].capitalize()
- else:
- return mname.capitalize()
- labelList.append(word)
- return ' '.join(labelList)
-
-
-
-def uidFromString(uidString):
- """
- Convert a user identifier, as a string, into an integer UID.
-
- @type uid: C{str}
- @param uid: A string giving the base-ten representation of a UID or the
- name of a user which can be converted to a UID via L{pwd.getpwnam}.
-
- @rtype: C{int}
- @return: The integer UID corresponding to the given string.
-
- @raise ValueError: If the user name is supplied and L{pwd} is not
- available.
- """
- try:
- return int(uidString)
- except ValueError:
- if pwd is None:
- raise
- return pwd.getpwnam(uidString)[2]
-
-
-
-def gidFromString(gidString):
- """
- Convert a group identifier, as a string, into an integer GID.
-
- @type uid: C{str}
- @param uid: A string giving the base-ten representation of a GID or the
- name of a group which can be converted to a GID via L{grp.getgrnam}.
-
- @rtype: C{int}
- @return: The integer GID corresponding to the given string.
-
- @raise ValueError: If the group name is supplied and L{grp} is not
- available.
- """
- try:
- return int(gidString)
- except ValueError:
- if grp is None:
- raise
- return grp.getgrnam(gidString)[2]
-
-
-
-def runAsEffectiveUser(euid, egid, function, *args, **kwargs):
- """
- Run the given function wrapped with seteuid/setegid calls.
-
- This will try to minimize the number of seteuid/setegid calls, comparing
- current and wanted permissions
-
- @param euid: effective UID used to call the function.
- @type euid: C{int}
-
- @type egid: effective GID used to call the function.
- @param egid: C{int}
-
- @param function: the function run with the specific permission.
- @type function: any callable
-
- @param *args: arguments passed to C{function}
- @param **kwargs: keyword arguments passed to C{function}
- """
- uid, gid = os.geteuid(), os.getegid()
- if uid == euid and gid == egid:
- return function(*args, **kwargs)
- else:
- if uid != 0 and (uid != euid or gid != egid):
- os.seteuid(0)
- if gid != egid:
- os.setegid(egid)
- if euid != 0 and (euid != uid or gid != egid):
- os.seteuid(euid)
- try:
- return function(*args, **kwargs)
- finally:
- if euid != 0 and (uid != euid or gid != egid):
- os.seteuid(0)
- if gid != egid:
- os.setegid(gid)
- if uid != 0 and (uid != euid or gid != egid):
- os.seteuid(uid)
-
-
-
-__all__ = [
- "uniquify", "padTo", "getPluginDirs", "addPluginDir", "sibpath",
- "getPassword", "println", "makeStatBar", "OrderedDict",
- "InsensitiveDict", "spewer", "searchupwards", "LineLog",
- "raises", "IntervalDifferential", "FancyStrMixin", "FancyEqMixin",
- "switchUID", "SubclassableCStringIO", "unsignedID", "mergeFunctionMetadata",
- "nameToLabel", "uidFromString", "gidFromString", "runAsEffectiveUser",
-]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/versions.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/versions.py
deleted file mode 100755
index d6f67153..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/versions.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_versions -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Versions for Python packages.
-
-See L{Version}.
-"""
-
-import sys, os
-
-
-class _inf(object):
- """
- An object that is bigger than all other objects.
- """
- def __cmp__(self, other):
- """
- @param other: Another object.
- @type other: any
-
- @return: 0 if other is inf, 1 otherwise.
- @rtype: C{int}
- """
- if other is _inf:
- return 0
- return 1
-
-_inf = _inf()
-
-
-class IncomparableVersions(TypeError):
- """
- Two versions could not be compared.
- """
-
-class Version(object):
- """
- An object that represents a three-part version number.
-
- If running from an svn checkout, include the revision number in
- the version string.
- """
- def __init__(self, package, major, minor, micro, prerelease=None):
- """
- @param package: Name of the package that this is a version of.
- @type package: C{str}
- @param major: The major version number.
- @type major: C{int}
- @param minor: The minor version number.
- @type minor: C{int}
- @param micro: The micro version number.
- @type micro: C{int}
- @param prerelease: The prerelease number.
- @type prerelease: C{int}
- """
- self.package = package
- self.major = major
- self.minor = minor
- self.micro = micro
- self.prerelease = prerelease
-
-
- def short(self):
- """
- Return a string in canonical short version format,
- <major>.<minor>.<micro>[+rSVNVer].
- """
- s = self.base()
- svnver = self._getSVNVersion()
- if svnver:
- s += '+r' + str(svnver)
- return s
-
-
- def base(self):
- """
- Like L{short}, but without the +rSVNVer.
- """
- if self.prerelease is None:
- pre = ""
- else:
- pre = "pre%s" % (self.prerelease,)
- return '%d.%d.%d%s' % (self.major,
- self.minor,
- self.micro,
- pre)
-
-
- def __repr__(self):
- svnver = self._formatSVNVersion()
- if svnver:
- svnver = ' #' + svnver
- if self.prerelease is None:
- prerelease = ""
- else:
- prerelease = ", prerelease=%r" % (self.prerelease,)
- return '%s(%r, %d, %d, %d%s)%s' % (
- self.__class__.__name__,
- self.package,
- self.major,
- self.minor,
- self.micro,
- prerelease,
- svnver)
-
-
- def __str__(self):
- return '[%s, version %s]' % (
- self.package,
- self.short())
-
-
- def __cmp__(self, other):
- """
- Compare two versions, considering major versions, minor versions, micro
- versions, then prereleases.
-
- A version with a prerelease is always less than a version without a
- prerelease. If both versions have prereleases, they will be included in
- the comparison.
-
- @param other: Another version.
- @type other: L{Version}
-
- @return: NotImplemented when the other object is not a Version, or one
- of -1, 0, or 1.
-
- @raise IncomparableVersions: when the package names of the versions
- differ.
- """
- if not isinstance(other, self.__class__):
- return NotImplemented
- if self.package != other.package:
- raise IncomparableVersions("%r != %r"
- % (self.package, other.package))
-
- if self.prerelease is None:
- prerelease = _inf
- else:
- prerelease = self.prerelease
-
- if other.prerelease is None:
- otherpre = _inf
- else:
- otherpre = other.prerelease
-
- x = cmp((self.major,
- self.minor,
- self.micro,
- prerelease),
- (other.major,
- other.minor,
- other.micro,
- otherpre))
- return x
-
-
- def _parseSVNEntries_4(self, entriesFile):
- """
- Given a readable file object which represents a .svn/entries file in
- format version 4, return the revision as a string. We do this by
- reading first XML element in the document that has a 'revision'
- attribute.
- """
- from xml.dom.minidom import parse
- doc = parse(entriesFile).documentElement
- for node in doc.childNodes:
- if hasattr(node, 'getAttribute'):
- rev = node.getAttribute('revision')
- if rev is not None:
- return rev.encode('ascii')
-
-
- def _parseSVNEntries_8(self, entriesFile):
- """
- Given a readable file object which represents a .svn/entries file in
- format version 8, return the revision as a string.
- """
- entriesFile.readline()
- entriesFile.readline()
- entriesFile.readline()
- return entriesFile.readline().strip()
-
-
- # Add handlers for version 9 and 10 formats, which are the same as
- # version 8 as far as revision information is concerned.
- _parseSVNEntries_9 = _parseSVNEntries_8
- _parseSVNEntriesTenPlus = _parseSVNEntries_8
-
-
- def _getSVNVersion(self):
- """
- Figure out the SVN revision number based on the existance of
- <package>/.svn/entries, and its contents. This requires discovering the
- format version from the 'format' file and parsing the entries file
- accordingly.
-
- @return: None or string containing SVN Revision number.
- """
- mod = sys.modules.get(self.package)
- if mod:
- svn = os.path.join(os.path.dirname(mod.__file__), '.svn')
- if not os.path.exists(svn):
- # It's not an svn working copy
- return None
-
- formatFile = os.path.join(svn, 'format')
- if os.path.exists(formatFile):
- # It looks like a less-than-version-10 working copy.
- format = file(formatFile).read().strip()
- parser = getattr(self, '_parseSVNEntries_' + format, None)
- else:
- # It looks like a version-10-or-greater working copy, which
- # has version information in the entries file.
- parser = self._parseSVNEntriesTenPlus
-
- if parser is None:
- return 'Unknown'
-
- entriesFile = os.path.join(svn, 'entries')
- entries = file(entriesFile)
- try:
- try:
- return parser(entries)
- finally:
- entries.close()
- except:
- return 'Unknown'
-
-
- def _formatSVNVersion(self):
- ver = self._getSVNVersion()
- if ver is None:
- return ''
- return ' (SVN r%s)' % (ver,)
-
-
-
-def getVersionString(version):
- """
- Get a friendly string for the given version object.
-
- @param version: A L{Version} object.
- @return: A string containing the package and short version number.
- """
- result = '%s %s' % (version.package, version.short())
- return result
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/win32.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/win32.py
deleted file mode 100755
index cd318ba9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/win32.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_win32 -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Win32 utilities.
-
-See also twisted.python.shortcut.
-
-@var O_BINARY: the 'binary' mode flag on Windows, or 0 on other platforms, so it
- may safely be OR'ed into a mask for os.open.
-"""
-
-import re
-import os
-
-try:
- import win32api
- import win32con
-except ImportError:
- pass
-
-from twisted.python.runtime import platform
-
-# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp
-ERROR_FILE_NOT_FOUND = 2
-ERROR_PATH_NOT_FOUND = 3
-ERROR_INVALID_NAME = 123
-ERROR_DIRECTORY = 267
-
-O_BINARY = getattr(os, "O_BINARY", 0)
-
-class FakeWindowsError(OSError):
- """
- Stand-in for sometimes-builtin exception on platforms for which it
- is missing.
- """
-
-try:
- WindowsError = WindowsError
-except NameError:
- WindowsError = FakeWindowsError
-
-# XXX fix this to use python's builtin _winreg?
-
-def getProgramsMenuPath():
- """Get the path to the Programs menu.
-
- Probably will break on non-US Windows.
-
- @returns: the filesystem location of the common Start Menu->Programs.
- """
- if not platform.isWinNT():
- return "C:\\Windows\\Start Menu\\Programs"
- keyname = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
- hShellFolders = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE,
- keyname, 0, win32con.KEY_READ)
- return win32api.RegQueryValueEx(hShellFolders, 'Common Programs')[0]
-
-
-def getProgramFilesPath():
- """Get the path to the Program Files folder."""
- keyname = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
- currentV = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE,
- keyname, 0, win32con.KEY_READ)
- return win32api.RegQueryValueEx(currentV, 'ProgramFilesDir')[0]
-
-_cmdLineQuoteRe = re.compile(r'(\\*)"')
-_cmdLineQuoteRe2 = re.compile(r'(\\+)\Z')
-def cmdLineQuote(s):
- """
- Internal method for quoting a single command-line argument.
-
- @param s: an unquoted string that you want to quote so that something that
- does cmd.exe-style unquoting will interpret it as a single argument,
- even if it contains spaces.
- @type s: C{str}
-
- @return: a quoted string.
- @rtype: C{str}
- """
- quote = ((" " in s) or ("\t" in s) or ('"' in s) or s == '') and '"' or ''
- return quote + _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s)) + quote
-
-def quoteArguments(arguments):
- """
- Quote an iterable of command-line arguments for passing to CreateProcess or
- a similar API. This allows the list passed to C{reactor.spawnProcess} to
- match the child process's C{sys.argv} properly.
-
- @param arglist: an iterable of C{str}, each unquoted.
-
- @return: a single string, with the given sequence quoted as necessary.
- """
- return ' '.join([cmdLineQuote(a) for a in arguments])
-
-
-class _ErrorFormatter(object):
- """
- Formatter for Windows error messages.
-
- @ivar winError: A callable which takes one integer error number argument
- and returns an L{exceptions.WindowsError} instance for that error (like
- L{ctypes.WinError}).
-
- @ivar formatMessage: A callable which takes one integer error number
- argument and returns a C{str} giving the message for that error (like
- L{win32api.FormatMessage}).
-
- @ivar errorTab: A mapping from integer error numbers to C{str} messages
- which correspond to those erorrs (like L{socket.errorTab}).
- """
- def __init__(self, WinError, FormatMessage, errorTab):
- self.winError = WinError
- self.formatMessage = FormatMessage
- self.errorTab = errorTab
-
- def fromEnvironment(cls):
- """
- Get as many of the platform-specific error translation objects as
- possible and return an instance of C{cls} created with them.
- """
- try:
- from ctypes import WinError
- except ImportError:
- WinError = None
- try:
- from win32api import FormatMessage
- except ImportError:
- FormatMessage = None
- try:
- from socket import errorTab
- except ImportError:
- errorTab = None
- return cls(WinError, FormatMessage, errorTab)
- fromEnvironment = classmethod(fromEnvironment)
-
-
- def formatError(self, errorcode):
- """
- Returns the string associated with a Windows error message, such as the
- ones found in socket.error.
-
- Attempts direct lookup against the win32 API via ctypes and then
- pywin32 if available), then in the error table in the socket module,
- then finally defaulting to C{os.strerror}.
-
- @param errorcode: the Windows error code
- @type errorcode: C{int}
-
- @return: The error message string
- @rtype: C{str}
- """
- if self.winError is not None:
- return self.winError(errorcode).strerror
- if self.formatMessage is not None:
- return self.formatMessage(errorcode)
- if self.errorTab is not None:
- result = self.errorTab.get(errorcode)
- if result is not None:
- return result
- return os.strerror(errorcode)
-
-formatError = _ErrorFormatter.fromEnvironment().formatError
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zippath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zippath.py
deleted file mode 100755
index a82f253b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zippath.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# -*- test-case-name: twisted.test.test_paths.ZipFilePathTestCase -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module contains implementations of IFilePath for zip files.
-
-See the constructor for ZipArchive for use.
-"""
-
-__metaclass__ = type
-
-import os
-import time
-import errno
-
-
-# Python 2.6 includes support for incremental unzipping of zipfiles, and
-# thus obviates the need for ChunkingZipFile.
-import sys
-if sys.version_info[:2] >= (2, 6):
- _USE_ZIPFILE = True
- from zipfile import ZipFile
-else:
- _USE_ZIPFILE = False
- from twisted.python.zipstream import ChunkingZipFile
-
-from twisted.python.filepath import IFilePath, FilePath, AbstractFilePath
-
-from zope.interface import implements
-
-# using FilePath here exclusively rather than os to make sure that we don't do
-# anything OS-path-specific here.
-
-ZIP_PATH_SEP = '/' # In zipfiles, "/" is universally used as the
- # path separator, regardless of platform.
-
-
-class ZipPath(AbstractFilePath):
- """
- I represent a file or directory contained within a zip file.
- """
-
- implements(IFilePath)
-
- sep = ZIP_PATH_SEP
-
- def __init__(self, archive, pathInArchive):
- """
- Don't construct me directly. Use ZipArchive.child().
-
- @param archive: a ZipArchive instance.
-
- @param pathInArchive: a ZIP_PATH_SEP-separated string.
- """
- self.archive = archive
- self.pathInArchive = pathInArchive
- # self.path pretends to be os-specific because that's the way the
- # 'zipimport' module does it.
- self.path = os.path.join(archive.zipfile.filename,
- *(self.pathInArchive.split(ZIP_PATH_SEP)))
-
- def __cmp__(self, other):
- if not isinstance(other, ZipPath):
- return NotImplemented
- return cmp((self.archive, self.pathInArchive),
- (other.archive, other.pathInArchive))
-
-
- def __repr__(self):
- parts = [os.path.abspath(self.archive.path)]
- parts.extend(self.pathInArchive.split(ZIP_PATH_SEP))
- path = os.sep.join(parts)
- return "ZipPath('%s')" % (path.encode('string-escape'),)
-
-
- def parent(self):
- splitup = self.pathInArchive.split(ZIP_PATH_SEP)
- if len(splitup) == 1:
- return self.archive
- return ZipPath(self.archive, ZIP_PATH_SEP.join(splitup[:-1]))
-
-
- def child(self, path):
- """
- Return a new ZipPath representing a path in C{self.archive} which is
- a child of this path.
-
- @note: Requesting the C{".."} (or other special name) child will not
- cause L{InsecurePath} to be raised since these names do not have
- any special meaning inside a zip archive. Be particularly
- careful with the C{path} attribute (if you absolutely must use
- it) as this means it may include special names with special
- meaning outside of the context of a zip archive.
- """
- return ZipPath(self.archive, ZIP_PATH_SEP.join([self.pathInArchive, path]))
-
-
- def sibling(self, path):
- return self.parent().child(path)
-
- # preauthChild = child
-
- def exists(self):
- return self.isdir() or self.isfile()
-
- def isdir(self):
- return self.pathInArchive in self.archive.childmap
-
- def isfile(self):
- return self.pathInArchive in self.archive.zipfile.NameToInfo
-
- def islink(self):
- return False
-
- def listdir(self):
- if self.exists():
- if self.isdir():
- return self.archive.childmap[self.pathInArchive].keys()
- else:
- raise OSError(errno.ENOTDIR, "Leaf zip entry listed")
- else:
- raise OSError(errno.ENOENT, "Non-existent zip entry listed")
-
-
- def splitext(self):
- """
- Return a value similar to that returned by os.path.splitext.
- """
- # This happens to work out because of the fact that we use OS-specific
- # path separators in the constructor to construct our fake 'path'
- # attribute.
- return os.path.splitext(self.path)
-
-
- def basename(self):
- return self.pathInArchive.split(ZIP_PATH_SEP)[-1]
-
- def dirname(self):
- # XXX NOTE: This API isn't a very good idea on filepath, but it's even
- # less meaningful here.
- return self.parent().path
-
- def open(self, mode="r"):
- if _USE_ZIPFILE:
- return self.archive.zipfile.open(self.pathInArchive, mode=mode)
- else:
- # XXX oh man, is this too much hax?
- self.archive.zipfile.mode = mode
- return self.archive.zipfile.readfile(self.pathInArchive)
-
- def changed(self):
- pass
-
- def getsize(self):
- """
- Retrieve this file's size.
-
- @return: file size, in bytes
- """
-
- return self.archive.zipfile.NameToInfo[self.pathInArchive].file_size
-
- def getAccessTime(self):
- """
- Retrieve this file's last access-time. This is the same as the last access
- time for the archive.
-
- @return: a number of seconds since the epoch
- """
- return self.archive.getAccessTime()
-
-
- def getModificationTime(self):
- """
- Retrieve this file's last modification time. This is the time of
- modification recorded in the zipfile.
-
- @return: a number of seconds since the epoch.
- """
- return time.mktime(
- self.archive.zipfile.NameToInfo[self.pathInArchive].date_time
- + (0, 0, 0))
-
-
- def getStatusChangeTime(self):
- """
- Retrieve this file's last modification time. This name is provided for
- compatibility, and returns the same value as getmtime.
-
- @return: a number of seconds since the epoch.
- """
- return self.getModificationTime()
-
-
-
-class ZipArchive(ZipPath):
- """ I am a FilePath-like object which can wrap a zip archive as if it were a
- directory.
- """
- archive = property(lambda self: self)
- def __init__(self, archivePathname):
- """Create a ZipArchive, treating the archive at archivePathname as a zip file.
-
- @param archivePathname: a str, naming a path in the filesystem.
- """
- if _USE_ZIPFILE:
- self.zipfile = ZipFile(archivePathname)
- else:
- self.zipfile = ChunkingZipFile(archivePathname)
- self.path = archivePathname
- self.pathInArchive = ''
- # zipfile is already wasting O(N) memory on cached ZipInfo instances,
- # so there's no sense in trying to do this lazily or intelligently
- self.childmap = {} # map parent: list of children
-
- for name in self.zipfile.namelist():
- name = name.split(ZIP_PATH_SEP)
- for x in range(len(name)):
- child = name[-x]
- parent = ZIP_PATH_SEP.join(name[:-x])
- if parent not in self.childmap:
- self.childmap[parent] = {}
- self.childmap[parent][child] = 1
- parent = ''
-
- def child(self, path):
- """
- Create a ZipPath pointing at a path within the archive.
-
- @param path: a str with no path separators in it, either '/' or the
- system path separator, if it's different.
- """
- return ZipPath(self, path)
-
- def exists(self):
- """
- Returns true if the underlying archive exists.
- """
- return FilePath(self.zipfile.filename).exists()
-
-
- def getAccessTime(self):
- """
- Return the archive file's last access time.
- """
- return FilePath(self.zipfile.filename).getAccessTime()
-
-
- def getModificationTime(self):
- """
- Return the archive file's modification time.
- """
- return FilePath(self.zipfile.filename).getModificationTime()
-
-
- def getStatusChangeTime(self):
- """
- Return the archive file's status change time.
- """
- return FilePath(self.zipfile.filename).getStatusChangeTime()
-
-
- def __repr__(self):
- return 'ZipArchive(%r)' % (os.path.abspath(self.path),)
-
-
-__all__ = ['ZipArchive', 'ZipPath']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zipstream.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zipstream.py
deleted file mode 100755
index 7ce8c126..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zipstream.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_zipstream -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An incremental approach to unzipping files. This allows you to unzip a little
-bit of a file at a time, which means you can report progress as a file unzips.
-"""
-
-import zipfile
-import os.path
-import zlib
-import struct
-
-
-_fileHeaderSize = struct.calcsize(zipfile.structFileHeader)
-
-class ChunkingZipFile(zipfile.ZipFile):
- """
- A C{ZipFile} object which, with L{readfile}, also gives you access to a
- file-like object for each entry.
- """
-
- def readfile(self, name):
- """
- Return file-like object for name.
- """
- if self.mode not in ("r", "a"):
- raise RuntimeError('read() requires mode "r" or "a"')
- if not self.fp:
- raise RuntimeError(
- "Attempt to read ZIP archive that was already closed")
- zinfo = self.getinfo(name)
-
- self.fp.seek(zinfo.header_offset, 0)
-
- fheader = self.fp.read(_fileHeaderSize)
- if fheader[0:4] != zipfile.stringFileHeader:
- raise zipfile.BadZipfile("Bad magic number for file header")
-
- fheader = struct.unpack(zipfile.structFileHeader, fheader)
- fname = self.fp.read(fheader[zipfile._FH_FILENAME_LENGTH])
-
- if fheader[zipfile._FH_EXTRA_FIELD_LENGTH]:
- self.fp.read(fheader[zipfile._FH_EXTRA_FIELD_LENGTH])
-
- if fname != zinfo.orig_filename:
- raise zipfile.BadZipfile(
- 'File name in directory "%s" and header "%s" differ.' % (
- zinfo.orig_filename, fname))
-
- if zinfo.compress_type == zipfile.ZIP_STORED:
- return ZipFileEntry(self, zinfo.compress_size)
- elif zinfo.compress_type == zipfile.ZIP_DEFLATED:
- return DeflatedZipFileEntry(self, zinfo.compress_size)
- else:
- raise zipfile.BadZipfile(
- "Unsupported compression method %d for file %s" %
- (zinfo.compress_type, name))
-
-
-
-class _FileEntry(object):
- """
- Abstract superclass of both compressed and uncompressed variants of
- file-like objects within a zip archive.
-
- @ivar chunkingZipFile: a chunking zip file.
- @type chunkingZipFile: L{ChunkingZipFile}
-
- @ivar length: The number of bytes within the zip file that represent this
- file. (This is the size on disk, not the number of decompressed bytes
- which will result from reading it.)
-
- @ivar fp: the underlying file object (that contains pkzip data). Do not
- touch this, please. It will quite likely move or go away.
-
- @ivar closed: File-like 'closed' attribute; True before this file has been
- closed, False after.
- @type closed: C{bool}
-
- @ivar finished: An older, broken synonym for 'closed'. Do not touch this,
- please.
- @type finished: C{int}
- """
- def __init__(self, chunkingZipFile, length):
- """
- Create a L{_FileEntry} from a L{ChunkingZipFile}.
- """
- self.chunkingZipFile = chunkingZipFile
- self.fp = self.chunkingZipFile.fp
- self.length = length
- self.finished = 0
- self.closed = False
-
-
- def isatty(self):
- """
- Returns false because zip files should not be ttys
- """
- return False
-
-
- def close(self):
- """
- Close self (file-like object)
- """
- self.closed = True
- self.finished = 1
- del self.fp
-
-
- def readline(self):
- """
- Read a line.
- """
- bytes = ""
- for byte in iter(lambda : self.read(1), ""):
- bytes += byte
- if byte == "\n":
- break
- return bytes
-
-
- def next(self):
- """
- Implement next as file does (like readline, except raises StopIteration
- at EOF)
- """
- nextline = self.readline()
- if nextline:
- return nextline
- raise StopIteration()
-
-
- def readlines(self):
- """
- Returns a list of all the lines
- """
- return list(self)
-
-
- def xreadlines(self):
- """
- Returns an iterator (so self)
- """
- return self
-
-
- def __iter__(self):
- """
- Returns an iterator (so self)
- """
- return self
-
-
-
-class ZipFileEntry(_FileEntry):
- """
- File-like object used to read an uncompressed entry in a ZipFile
- """
-
- def __init__(self, chunkingZipFile, length):
- _FileEntry.__init__(self, chunkingZipFile, length)
- self.readBytes = 0
-
-
- def tell(self):
- return self.readBytes
-
-
- def read(self, n=None):
- if n is None:
- n = self.length - self.readBytes
- if n == 0 or self.finished:
- return ''
- data = self.chunkingZipFile.fp.read(
- min(n, self.length - self.readBytes))
- self.readBytes += len(data)
- if self.readBytes == self.length or len(data) < n:
- self.finished = 1
- return data
-
-
-
-class DeflatedZipFileEntry(_FileEntry):
- """
- File-like object used to read a deflated entry in a ZipFile
- """
-
- def __init__(self, chunkingZipFile, length):
- _FileEntry.__init__(self, chunkingZipFile, length)
- self.returnedBytes = 0
- self.readBytes = 0
- self.decomp = zlib.decompressobj(-15)
- self.buffer = ""
-
-
- def tell(self):
- return self.returnedBytes
-
-
- def read(self, n=None):
- if self.finished:
- return ""
- if n is None:
- result = [self.buffer,]
- result.append(
- self.decomp.decompress(
- self.chunkingZipFile.fp.read(
- self.length - self.readBytes)))
- result.append(self.decomp.decompress("Z"))
- result.append(self.decomp.flush())
- self.buffer = ""
- self.finished = 1
- result = "".join(result)
- self.returnedBytes += len(result)
- return result
- else:
- while len(self.buffer) < n:
- data = self.chunkingZipFile.fp.read(
- min(n, 1024, self.length - self.readBytes))
- self.readBytes += len(data)
- if not data:
- result = (self.buffer
- + self.decomp.decompress("Z")
- + self.decomp.flush())
- self.finished = 1
- self.buffer = ""
- self.returnedBytes += len(result)
- return result
- else:
- self.buffer += self.decomp.decompress(data)
- result = self.buffer[:n]
- self.buffer = self.buffer[n:]
- self.returnedBytes += len(result)
- return result
-
-
-
-DIR_BIT = 16
-
-
-def countZipFileChunks(filename, chunksize):
- """
- Predict the number of chunks that will be extracted from the entire
- zipfile, given chunksize blocks.
- """
- totalchunks = 0
- zf = ChunkingZipFile(filename)
- for info in zf.infolist():
- totalchunks += countFileChunks(info, chunksize)
- return totalchunks
-
-
-def countFileChunks(zipinfo, chunksize):
- """
- Count the number of chunks that will result from the given C{ZipInfo}.
-
- @param zipinfo: a C{zipfile.ZipInfo} instance describing an entry in a zip
- archive to be counted.
-
- @return: the number of chunks present in the zip file. (Even an empty file
- counts as one chunk.)
- @rtype: C{int}
- """
- count, extra = divmod(zipinfo.file_size, chunksize)
- if extra > 0:
- count += 1
- return count or 1
-
-
-
-def unzipIterChunky(filename, directory='.', overwrite=0,
- chunksize=4096):
- """
- Return a generator for the zipfile. This implementation will yield after
- every chunksize uncompressed bytes, or at the end of a file, whichever
- comes first.
-
- The value it yields is the number of chunks left to unzip.
- """
- czf = ChunkingZipFile(filename, 'r')
- if not os.path.exists(directory):
- os.makedirs(directory)
- remaining = countZipFileChunks(filename, chunksize)
- names = czf.namelist()
- infos = czf.infolist()
-
- for entry, info in zip(names, infos):
- isdir = info.external_attr & DIR_BIT
- f = os.path.join(directory, entry)
- if isdir:
- # overwrite flag only applies to files
- if not os.path.exists(f):
- os.makedirs(f)
- remaining -= 1
- yield remaining
- else:
- # create the directory the file will be in first,
- # since we can't guarantee it exists
- fdir = os.path.split(f)[0]
- if not os.path.exists(fdir):
- os.makedirs(fdir)
- if overwrite or not os.path.exists(f):
- outfile = file(f, 'wb')
- fp = czf.readfile(entry)
- if info.file_size == 0:
- remaining -= 1
- yield remaining
- while fp.tell() < info.file_size:
- hunk = fp.read(chunksize)
- outfile.write(hunk)
- remaining -= 1
- yield remaining
- outfile.close()
- else:
- remaining -= countFileChunks(info, chunksize)
- yield remaining
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/README.txt b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/README.txt
deleted file mode 100644
index 2a7b1c26..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/README.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-THIS DIRECTORY AND ALL FILES INCLUDED ARE DEPRECATED.
-
-These are the old zsh completion functions for Twisted commands... they used
-to contain full completion functions, but now they've simply been replaced
-by the current "stub" code that delegates completion control to Twisted.
-
-This directory and included files need to remain for several years in order
-to provide backwards-compatibility with an old version of the Twisted
-stub function that was shipped with Zsh.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_cftp b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_cftp
deleted file mode 100644
index e89fcdb1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_cftp
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef cftp
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_ckeygen b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_ckeygen
deleted file mode 100644
index 38050a0d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_ckeygen
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef ckeygen
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_conch b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_conch
deleted file mode 100644
index e3ac3b6b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_conch
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef conch
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_lore b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_lore
deleted file mode 100644
index 8b1c3289..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_lore
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef lore
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_manhole b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_manhole
deleted file mode 100644
index 54ec99f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_manhole
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef manhole
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_mktap b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_mktap
deleted file mode 100644
index 2a08ea4a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_mktap
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef mktap
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_pyhtmlizer b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_pyhtmlizer
deleted file mode 100644
index 2fd2d6d7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_pyhtmlizer
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef pyhtmlizer
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2deb b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2deb
deleted file mode 100644
index b4e08360..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2deb
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef tap2deb
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2rpm b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2rpm
deleted file mode 100644
index 10a083f6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tap2rpm
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef tap2rpm
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tapconvert b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tapconvert
deleted file mode 100644
index 41a0e4da..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tapconvert
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef tapconvert
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkconch b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkconch
deleted file mode 100644
index 3af1f123..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkconch
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef tkconch
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkmktap b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkmktap
deleted file mode 100644
index 0e3bdaaf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_tkmktap
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef tkmktap
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_trial b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_trial
deleted file mode 100644
index b692f44f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_trial
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef trial
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_twistd b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_twistd
deleted file mode 100644
index 171224f9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_twistd
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef twistd
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_websetroot b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_websetroot
deleted file mode 100644
index 58ae5504..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zsh/_websetroot
+++ /dev/null
@@ -1,34 +0,0 @@
-#compdef websetroot
-# This file is deprecated. See README.
-
-# This is the ZSH completion file for Twisted commands. It calls the current
-# command-line with the special "--_shell-completion" option which is handled
-# by twisted.python.usage. t.p.usage then generates zsh code on stdout to
-# handle the completions for this particular command-line.
-#
-# 3rd parties that wish to provide zsh completion for commands that
-# use t.p.usage may copy this file and change the first line to reference
-# the name(s) of their command(s).
-#
-# This file is included in the official Zsh distribution as
-# Completion/Unix/Command/_twisted
-
-# redirect stderr to /dev/null otherwise deprecation warnings may get puked
-# all over the user's terminal if completing options for mktap or other
-# deprecated commands. Redirect stderr to a file to debug errors.
-local cmd output
-cmd=("$words[@]" --_shell-completion zsh:$CURRENT)
-output=$("$cmd[@]" 2>/dev/null)
-
-if [[ $output == "#compdef "* ]]; then
- # Looks like we got a valid completion function - so eval it to produce
- # the completion matches.
- eval $output
-else
- echo "\nCompletion error running command:" ${(qqq)cmd}
- echo -n "If output below is unhelpful you may need to edit this file and "
- echo "redirect stderr to a file."
- echo "Expected completion function, but instead got:"
- echo $output
- return 1
-fi
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zshcomp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zshcomp.py
deleted file mode 100755
index 89389fe7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/zshcomp.py
+++ /dev/null
@@ -1,824 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_zshcomp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-"""
-Rebuild the completion functions for the currently active version of Twisted::
- $ python zshcomp.py -i
-
-This module implements a zsh code generator which generates completion code for
-commands that use twisted.python.usage. This is the stuff that makes pressing
-Tab at the command line work.
-
-Maintainer: Eric Mangold
-
-To build completion functions for your own commands, and not Twisted commands,
-then just do something like this::
-
- o = mymodule.MyOptions()
- f = file('_mycommand', 'w')
- Builder("mycommand", o, f).write()
-
-Then all you have to do is place the generated file somewhere in your
-C{$fpath}, and restart zsh. Note the "site-functions" directory in your
-C{$fpath} where you may install 3rd-party completion functions (like the one
-you're building). Call C{siteFunctionsPath} to locate this directory
-programmatically.
-
-SPECIAL CLASS VARIABLES. You may set these on your usage.Options subclass::
-
- zsh_altArgDescr
- zsh_multiUse
- zsh_mutuallyExclusive
- zsh_actions
- zsh_actionDescr
- zsh_extras
-
-Here is what they mean (with examples)::
-
- zsh_altArgDescr = {"foo":"use this description for foo instead"}
- A dict mapping long option names to alternate descriptions. When this
- variable is present, the descriptions contained here will override
- those descriptions provided in the optFlags and optParameters
- variables.
-
- zsh_multiUse = ["foo", "bar"]
- A sequence containing those long option names which may appear on the
- command line more than once. By default, options will only be completed
- one time.
-
- zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")]
- A sequence of sequences, with each sub-sequence containing those long
- option names that are mutually exclusive. That is, those options that
- cannot appear on the command line together.
-
- zsh_actions = {"foo":'_files -g "*.foo"', "bar":"(one two three)",
- "colors":"_values -s , 'colors to use' red green blue"}
- A dict mapping long option names to Zsh "actions". These actions
- define what will be completed as the argument to the given option. By
- default, all files/dirs will be completed if no action is given.
-
- Callables may instead be given for the values in this dict. The
- callable should accept no arguments, and return a string that will be
- used as the zsh "action" in the same way as the literal strings in the
- examples above.
-
- As you can see in the example above. The "foo" option will have files
- that end in .foo completed when the user presses Tab. The "bar"
- option will have either of the strings "one", "two", or "three"
- completed when the user presses Tab.
-
- "colors" will allow multiple arguments to be completed, seperated by
- commas. The possible arguments are red, green, and blue. Examples::
-
- my_command --foo some-file.foo --colors=red,green
- my_command --colors=green
- my_command --colors=green,blue
-
- Actions may take many forms, and it is beyond the scope of this
- document to illustrate them all. Please refer to the documention for
- the Zsh _arguments function. zshcomp is basically a front-end to Zsh's
- _arguments completion function.
-
- That documentation is available on the zsh web site at this URL:
- U{http://zsh.sunsite.dk/Doc/Release/zsh_19.html#SEC124}
-
- zsh_actionDescr = {"logfile":"log file name", "random":"random seed"}
- A dict mapping long option names to a description for the corresponding
- zsh "action". These descriptions are show above the generated matches
- when the user is doing completions for this option.
-
- Normally Zsh does not show these descriptions unless you have
- "verbose" completion turned on. Turn on verbosity with this in your
- ~/.zshrc::
-
- zstyle ':completion:*' verbose yes
- zstyle ':completion:*:descriptions' format '%B%d%b'
-
- zsh_extras = [":file to read from:action", ":file to write to:action"]
- A sequence of extra arguments that will be passed verbatim to Zsh's
- _arguments completion function. The _arguments function does all the
- hard work of doing command line completions. You can see how zshcomp
- invokes the _arguments call by looking at the generated completion
- files that this module creates.
-
- *** NOTE ***
-
- You will need to use this variable to describe completions for normal
- command line arguments. That is, those arguments that are not
- associated with an option. That is, the arguments that are given to the
- parseArgs method of your usage.Options subclass.
-
- In the example above, the 1st non-option argument will be described as
- "file to read from" and completion options will be generated in
- accordance with the "action". (See above about zsh "actions") The
- 2nd non-option argument will be described as "file to write to" and
- the action will be interpreted likewise.
-
- Things you can put here are all documented under the _arguments
- function here: U{http://zsh.sunsite.dk/Doc/Release/zsh_19.html#SEC124}
-
-Zsh Notes:
-
-To enable advanced completion add something like this to your ~/.zshrc::
-
- autoload -U compinit
- compinit
-
-For some extra verbosity, and general niceness add these lines too::
-
- zstyle ':completion:*' verbose yes
- zstyle ':completion:*:descriptions' format '%B%d%b'
- zstyle ':completion:*:messages' format '%d'
- zstyle ':completion:*:warnings' format 'No matches for: %d'
-
-Have fun!
-"""
-import warnings
-warnings.warn(
- "zshcomp is deprecated as of Twisted 11.1. Shell tab-completion is now "
- "handled by twisted.python.usage.", DeprecationWarning, stacklevel=2)
-
-import itertools, sys, commands, os.path
-
-from twisted.python import reflect, util, usage
-from twisted.application.service import IServiceMaker
-
-
-
-class MyOptions(usage.Options):
- """
- Options for this file
- """
- longdesc = ""
- synopsis = "Usage: python zshcomp.py [--install | -i] | <output directory>"
- optFlags = [["install", "i",
- 'Output files to the "installation" directory ' \
- '(twisted/python/zsh in the currently active ' \
- 'Twisted package)']]
- optParameters = [["directory", "d", None,
- "Output files to this directory"]]
-
-
- def postOptions(self):
- if self['install'] and self['directory']:
- raise usage.UsageError, "Can't have --install and " \
- "--directory at the same time"
- if not self['install'] and not self['directory']:
- raise usage.UsageError, "Not enough arguments"
- if self['directory'] and not os.path.isdir(self['directory']):
- raise usage.UsageError, "%s is not a directory" % self['directory']
-
-
-
-class Builder:
- def __init__(self, cmd_name, options, file):
- """
- @type cmd_name: C{str}
- @param cmd_name: The name of the command
-
- @type options: C{twisted.usage.Options}
- @param options: The C{twisted.usage.Options} instance defined for
- this command
-
- @type file: C{file}
- @param file: The C{file} to write the completion function to
- """
-
- self.cmd_name = cmd_name
- self.options = options
- self.file = file
-
-
- def write(self):
- """
- Write the completion function to the file given to __init__
- @return: C{None}
- """
- # by default, we just write out a single call to _arguments
- self.file.write('#compdef %s\n' % (self.cmd_name,))
- gen = ArgumentsGenerator(self.cmd_name, self.options, self.file)
- gen.write()
-
-
-
-class SubcommandBuilder(Builder):
- """
- Use this builder for commands that have sub-commands. twisted.python.usage
- has the notion of sub-commands that are defined using an entirely seperate
- Options class.
- """
- interface = None
- subcmdLabel = None
-
-
- def write(self):
- """
- Write the completion function to the file given to __init__
- @return: C{None}
- """
- self.file.write('#compdef %s\n' % (self.cmd_name,))
- self.file.write('local _zsh_subcmds_array\n_zsh_subcmds_array=(\n')
- from twisted import plugin as newplugin
- plugins = newplugin.getPlugins(self.interface)
-
- for p in plugins:
- self.file.write('"%s:%s"\n' % (p.tapname, p.description))
- self.file.write(")\n\n")
-
- self.options.__class__.zsh_extras = ['*::subcmd:->subcmd']
- gen = ArgumentsGenerator(self.cmd_name, self.options, self.file)
- gen.write()
-
- self.file.write("""if (( CURRENT == 1 )); then
- _describe "%s" _zsh_subcmds_array && ret=0
-fi
-(( ret )) || return 0
-
-service="$words[1]"
-
-case $service in\n""" % (self.subcmdLabel,))
-
- plugins = newplugin.getPlugins(self.interface)
- for p in plugins:
- self.file.write(p.tapname + ")\n")
- gen = ArgumentsGenerator(p.tapname, p.options(), self.file)
- gen.write()
- self.file.write(";;\n")
- self.file.write("*) _message \"don't know how to" \
- " complete $service\";;\nesac")
-
-
-
-class MktapBuilder(SubcommandBuilder):
- """
- Builder for the mktap command
- """
- interface = IServiceMaker
- subcmdLabel = 'tap to build'
-
-
-
-class TwistdBuilder(SubcommandBuilder):
- """
- Builder for the twistd command
- """
- interface = IServiceMaker
- subcmdLabel = 'service to run'
-
-
-
-class ArgumentsGenerator:
- """
- Generate a call to the zsh _arguments completion function
- based on data in a usage.Options subclass
- """
- def __init__(self, cmd_name, options, file):
- """
- @type cmd_name: C{str}
- @param cmd_name: The name of the command
-
- @type options: C{twisted.usage.Options}
- @param options: The C{twisted.usage.Options} instance defined
- for this command
-
- @type file: C{file}
- @param file: The C{file} to write the completion function to
- """
- self.cmd_name = cmd_name
- self.options = options
- self.file = file
-
- self.altArgDescr = {}
- self.actionDescr = {}
- self.multiUse = []
- self.mutuallyExclusive = []
- self.actions = {}
- self.extras = []
-
- aCL = reflect.accumulateClassList
- aCD = reflect.accumulateClassDict
-
- aCD(options.__class__, 'zsh_altArgDescr', self.altArgDescr)
- aCD(options.__class__, 'zsh_actionDescr', self.actionDescr)
- aCL(options.__class__, 'zsh_multiUse', self.multiUse)
- aCL(options.__class__, 'zsh_mutuallyExclusive',
- self.mutuallyExclusive)
- aCD(options.__class__, 'zsh_actions', self.actions)
- aCL(options.__class__, 'zsh_extras', self.extras)
-
- optFlags = []
- optParams = []
-
- aCL(options.__class__, 'optFlags', optFlags)
- aCL(options.__class__, 'optParameters', optParams)
-
- for i, optList in enumerate(optFlags):
- if len(optList) != 3:
- optFlags[i] = util.padTo(3, optList)
-
- for i, optList in enumerate(optParams):
- if len(optList) != 4:
- optParams[i] = util.padTo(4, optList)
-
-
- self.optFlags = optFlags
- self.optParams = optParams
-
- optParams_d = {}
- for optList in optParams:
- optParams_d[optList[0]] = optList[1:]
- self.optParams_d = optParams_d
-
- optFlags_d = {}
- for optList in optFlags:
- optFlags_d[optList[0]] = optList[1:]
- self.optFlags_d = optFlags_d
-
- optAll_d = {}
- optAll_d.update(optParams_d)
- optAll_d.update(optFlags_d)
- self.optAll_d = optAll_d
-
- self.addAdditionalOptions()
-
- # makes sure none of the zsh_ data structures reference option
- # names that don't exist. (great for catching typos)
- self.verifyZshNames()
-
- self.excludes = self.makeExcludesDict()
-
-
- def write(self):
- """
- Write the zsh completion code to the file given to __init__
- @return: C{None}
- """
- self.writeHeader()
- self.writeExtras()
- self.writeOptions()
- self.writeFooter()
-
-
- def writeHeader(self):
- """
- This is the start of the code that calls _arguments
- @return: C{None}
- """
- self.file.write('_arguments -s -A "-*" \\\n')
-
-
- def writeOptions(self):
- """
- Write out zsh code for each option in this command
- @return: C{None}
- """
- optNames = self.optAll_d.keys()
- optNames.sort()
- for longname in optNames:
- self.writeOpt(longname)
-
-
- def writeExtras(self):
- """
- Write out the "extras" list. These are just passed verbatim to the
- _arguments call
- @return: C{None}
- """
- for s in self.extras:
- self.file.write(escape(s))
- self.file.write(' \\\n')
-
-
- def writeFooter(self):
- """
- Write the last bit of code that finishes the call to _arguments
- @return: C{None}
- """
- self.file.write('&& return 0\n')
-
-
- def verifyZshNames(self):
- """
- Ensure that none of the names given in zsh_* variables are typoed
- @return: C{None}
- @raise ValueError: Raised if unknown option names have been given in
- zsh_* variables
- """
- def err(name):
- raise ValueError, "Unknown option name \"%s\" found while\n" \
- "examining zsh_ attributes for the %s command" % (
- name, self.cmd_name)
-
- for name in itertools.chain(self.altArgDescr, self.actionDescr,
- self.actions, self.multiUse):
- if name not in self.optAll_d:
- err(name)
-
- for seq in self.mutuallyExclusive:
- for name in seq:
- if name not in self.optAll_d:
- err(name)
-
-
- def excludeStr(self, longname, buildShort=False):
- """
- Generate an "exclusion string" for the given option
-
- @type longname: C{str}
- @param longname: The long name of the option
- (i.e. "verbose" instead of "v")
-
- @type buildShort: C{bool}
- @param buildShort: May be True to indicate we're building an excludes
- string for the short option that correspondes to
- the given long opt
-
- @return: The generated C{str}
- """
- if longname in self.excludes:
- exclusions = self.excludes[longname][:]
- else:
- exclusions = []
-
- # if longname isn't a multiUse option (can't appear on the cmd line more
- # than once), then we have to exclude the short option if we're
- # building for the long option, and vice versa.
- if longname not in self.multiUse:
- if buildShort is False:
- short = self.getShortOption(longname)
- if short is not None:
- exclusions.append(short)
- else:
- exclusions.append(longname)
-
- if not exclusions:
- return ''
-
- strings = []
- for optName in exclusions:
- if len(optName) == 1:
- # short option
- strings.append("-" + optName)
- else:
- strings.append("--" + optName)
- return "(%s)" % " ".join(strings)
-
-
- def makeExcludesDict(self):
- """
- @return: A C{dict} that maps each option name appearing in
- self.mutuallyExclusive to a list of those option names that
- is it mutually exclusive with (can't appear on the cmd line with)
- """
-
- #create a mapping of long option name -> single character name
- longToShort = {}
- for optList in itertools.chain(self.optParams, self.optFlags):
- try:
- if optList[1] != None:
- longToShort[optList[0]] = optList[1]
- except IndexError:
- pass
-
- excludes = {}
- for lst in self.mutuallyExclusive:
- for i, longname in enumerate(lst):
- tmp = []
- tmp.extend(lst[:i])
- tmp.extend(lst[i+1:])
- for name in tmp[:]:
- if name in longToShort:
- tmp.append(longToShort[name])
-
- if longname in excludes:
- excludes[longname].extend(tmp)
- else:
- excludes[longname] = tmp
- return excludes
-
-
- def writeOpt(self, longname):
- """
- Write out the zsh code for the given argument. This is just part of the
- one big call to _arguments
-
- @type longname: C{str}
- @param longname: The long name of the option
- (i.e. "verbose" instead of "v")
-
- @return: C{None}
- """
- if longname in self.optFlags_d:
- # It's a flag option. Not one that takes a parameter.
- long_field = "--%s" % longname
- else:
- long_field = "--%s=" % longname
-
- short = self.getShortOption(longname)
- if short != None:
- short_field = "-" + short
- else:
- short_field = ''
-
- descr = self.getDescription(longname)
- descr_field = descr.replace("[", "\[")
- descr_field = descr_field.replace("]", "\]")
- descr_field = '[%s]' % descr_field
-
- if longname in self.actionDescr:
- actionDescr_field = self.actionDescr[longname]
- else:
- actionDescr_field = descr
-
- action_field = self.getAction(longname)
- if longname in self.multiUse:
- multi_field = '*'
- else:
- multi_field = ''
-
- longExclusions_field = self.excludeStr(longname)
-
- if short:
- #we have to write an extra line for the short option if we have one
- shortExclusions_field = self.excludeStr(longname, buildShort=True)
- self.file.write(escape('%s%s%s%s%s' % (shortExclusions_field,
- multi_field, short_field, descr_field, action_field)))
- self.file.write(' \\\n')
-
- self.file.write(escape('%s%s%s%s%s' % (longExclusions_field,
- multi_field, long_field, descr_field, action_field)))
- self.file.write(' \\\n')
-
-
- def getAction(self, longname):
- """
- Return a zsh "action" string for the given argument
- @return: C{str}
- """
- if longname in self.actions:
- if callable(self.actions[longname]):
- action = self.actions[longname]()
- else:
- action = self.actions[longname]
- return ":%s:%s" % (self.getActionDescr(longname), action)
- if longname in self.optParams_d:
- return ':%s:_files' % self.getActionDescr(longname)
- return ''
-
-
- def getActionDescr(self, longname):
- """
- Return the description to be used when this argument is completed
- @return: C{str}
- """
- if longname in self.actionDescr:
- return self.actionDescr[longname]
- else:
- return longname
-
-
- def getDescription(self, longname):
- """
- Return the description to be used for this argument
- @return: C{str}
- """
- #check if we have an alternate descr for this arg, and if so use it
- if longname in self.altArgDescr:
- return self.altArgDescr[longname]
-
- #otherwise we have to get it from the optFlags or optParams
- try:
- descr = self.optFlags_d[longname][1]
- except KeyError:
- try:
- descr = self.optParams_d[longname][2]
- except KeyError:
- descr = None
-
- if descr is not None:
- return descr
-
- # lets try to get it from the opt_foo method doc string if there is one
- longMangled = longname.replace('-', '_') # this is what t.p.usage does
- obj = getattr(self.options, 'opt_%s' % longMangled, None)
- if obj:
- descr = descrFromDoc(obj)
- if descr is not None:
- return descr
-
- return longname # we really ought to have a good description to use
-
-
- def getShortOption(self, longname):
- """
- Return the short option letter or None
- @return: C{str} or C{None}
- """
- optList = self.optAll_d[longname]
- try:
- return optList[0] or None
- except IndexError:
- pass
-
-
- def addAdditionalOptions(self):
- """
- Add additional options to the optFlags and optParams lists.
- These will be defined by 'opt_foo' methods of the Options subclass
- @return: C{None}
- """
- methodsDict = {}
- reflect.accumulateMethods(self.options, methodsDict, 'opt_')
- methodToShort = {}
- for name in methodsDict.copy():
- if len(name) == 1:
- methodToShort[methodsDict[name]] = name
- del methodsDict[name]
-
- for methodName, methodObj in methodsDict.items():
- longname = methodName.replace('_', '-') # t.p.usage does this
- # if this option is already defined by the optFlags or
- # optParameters then we don't want to override that data
- if longname in self.optAll_d:
- continue
-
- descr = self.getDescription(longname)
-
- short = None
- if methodObj in methodToShort:
- short = methodToShort[methodObj]
-
- reqArgs = methodObj.im_func.func_code.co_argcount
- if reqArgs == 2:
- self.optParams.append([longname, short, None, descr])
- self.optParams_d[longname] = [short, None, descr]
- self.optAll_d[longname] = [short, None, descr]
- elif reqArgs == 1:
- self.optFlags.append([longname, short, descr])
- self.optFlags_d[longname] = [short, descr]
- self.optAll_d[longname] = [short, None, descr]
- else:
- raise TypeError, '%r has wrong number ' \
- 'of arguments' % (methodObj,)
-
-
-
-def descrFromDoc(obj):
- """
- Generate an appropriate description from docstring of the given object
- """
- if obj.__doc__ is None:
- return None
-
- lines = obj.__doc__.split("\n")
- descr = None
- try:
- if lines[0] != "" and not lines[0].isspace():
- descr = lines[0].lstrip()
- # skip first line if it's blank
- elif lines[1] != "" and not lines[1].isspace():
- descr = lines[1].lstrip()
- except IndexError:
- pass
- return descr
-
-
-
-def firstLine(s):
- """
- Return the first line of the given string
- """
- try:
- i = s.index('\n')
- return s[:i]
- except ValueError:
- return s
-
-
-
-def escape(str):
- """
- Shell escape the given string
- """
- return commands.mkarg(str)[1:]
-
-
-
-def siteFunctionsPath():
- """
- Return the path to the system-wide site-functions directory or
- C{None} if it cannot be determined
- """
- try:
- cmd = "zsh -f -c 'echo ${(M)fpath:#/*/site-functions}'"
- output = commands.getoutput(cmd)
- if os.path.isdir(output):
- return output
- except:
- pass
-
-
-
-generateFor = [('conch', 'twisted.conch.scripts.conch', 'ClientOptions'),
- ('mktap', 'twisted.scripts.mktap', 'FirstPassOptions'),
- ('trial', 'twisted.scripts.trial', 'Options'),
- ('cftp', 'twisted.conch.scripts.cftp', 'ClientOptions'),
- ('tapconvert', 'twisted.scripts.tapconvert', 'ConvertOptions'),
- ('twistd', 'twisted.scripts.twistd', 'ServerOptions'),
- ('ckeygen', 'twisted.conch.scripts.ckeygen', 'GeneralOptions'),
- ('lore', 'twisted.lore.scripts.lore', 'Options'),
- ('pyhtmlizer', 'twisted.scripts.htmlizer', 'Options'),
- ('tap2deb', 'twisted.scripts.tap2deb', 'MyOptions'),
- ('tkconch', 'twisted.conch.scripts.tkconch', 'GeneralOptions'),
- ('manhole', 'twisted.scripts.manhole', 'MyOptions'),
- ('tap2rpm', 'twisted.scripts.tap2rpm', 'MyOptions'),
- ]
-
-specialBuilders = {'mktap' : MktapBuilder,
- 'twistd' : TwistdBuilder}
-
-
-
-def makeCompFunctionFiles(out_path, generateFor=generateFor,
- specialBuilders=specialBuilders):
- """
- Generate completion function files in the given directory for all
- twisted commands
-
- @type out_path: C{str}
- @param out_path: The path to the directory to generate completion function
- fils in
-
- @param generateFor: Sequence in the form of the 'generateFor' top-level
- variable as defined in this module. Indicates what
- commands to build completion files for.
-
- @param specialBuilders: Sequence in the form of the 'specialBuilders'
- top-level variable as defined in this module.
- Indicates what commands require a special
- Builder class.
-
- @return: C{list} of 2-tuples of the form (cmd_name, error) indicating
- commands that we skipped building completions for. cmd_name
- is the name of the skipped command, and error is the Exception
- that was raised when trying to import the script module.
- Commands are usually skipped due to a missing dependency,
- e.g. Tkinter.
- """
- skips = []
- for cmd_name, module_name, class_name in generateFor:
- if module_name is None:
- # create empty file
- f = _openCmdFile(out_path, cmd_name)
- f.close()
- continue
- try:
- m = __import__('%s' % (module_name,), None, None, (class_name))
- f = _openCmdFile(out_path, cmd_name)
- o = getattr(m, class_name)() # instantiate Options class
-
- if cmd_name in specialBuilders:
- b = specialBuilders[cmd_name](cmd_name, o, f)
- b.write()
- else:
- b = Builder(cmd_name, o, f)
- b.write()
- except Exception, e:
- skips.append( (cmd_name, e) )
- continue
- return skips
-
-
-
-def _openCmdFile(out_path, cmd_name):
- return file(os.path.join(out_path, '_'+cmd_name), 'w')
-
-
-
-def run():
- options = MyOptions()
- try:
- options.parseOptions(sys.argv[1:])
- except usage.UsageError, e:
- print e
- print options.getUsage()
- sys.exit(2)
-
- if options['install']:
- import twisted
- dir = os.path.join(os.path.dirname(twisted.__file__), "python", "zsh")
- skips = makeCompFunctionFiles(dir)
- else:
- skips = makeCompFunctionFiles(options['directory'])
-
- for cmd_name, error in skips:
- sys.stderr.write("zshcomp: Skipped building for %s. Script module " \
- "could not be imported:\n" % (cmd_name,))
- sys.stderr.write(str(error)+'\n')
- if skips:
- sys.exit(3)
-
-
-
-if __name__ == '__main__':
- run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/__init__.py
deleted file mode 100755
index 06b5d4be..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
-Twisted runer: run and monitor processes
-
-Maintainer: Andrew Bennetts
-
-classic inetd(8) support:
-Future Plans: The basic design should be final. There are some bugs that need
-fixing regarding UDP and Sun-RPC support. Perhaps some day xinetd
-compatibility will be added.
-
-procmon:monitor and restart processes
-"""
-
-from twisted.runner._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/_version.py
deleted file mode 100755
index d9ead6c5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.runner', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetd.py
deleted file mode 100755
index 010b89ee..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetd.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-Twisted inetd.
-
-Maintainer: Andrew Bennetts
-
-Future Plans: Bugfixes. Specifically for UDP and Sun-RPC, which don't work
-correctly yet.
-"""
-
-import os
-
-from twisted.internet import process, reactor, fdesc
-from twisted.internet.protocol import Protocol, ServerFactory
-from twisted.protocols import wire
-
-# A dict of known 'internal' services (i.e. those that don't involve spawning
-# another process.
-internalProtocols = {
- 'echo': wire.Echo,
- 'chargen': wire.Chargen,
- 'discard': wire.Discard,
- 'daytime': wire.Daytime,
- 'time': wire.Time,
-}
-
-
-class InetdProtocol(Protocol):
- """Forks a child process on connectionMade, passing the socket as fd 0."""
- def connectionMade(self):
- sockFD = self.transport.fileno()
- childFDs = {0: sockFD, 1: sockFD}
- if self.factory.stderrFile:
- childFDs[2] = self.factory.stderrFile.fileno()
-
- # processes run by inetd expect blocking sockets
- # FIXME: maybe this should be done in process.py? are other uses of
- # Process possibly affected by this?
- fdesc.setBlocking(sockFD)
- if childFDs.has_key(2):
- fdesc.setBlocking(childFDs[2])
-
- service = self.factory.service
- uid = service.user
- gid = service.group
-
- # don't tell Process to change our UID/GID if it's what we
- # already are
- if uid == os.getuid():
- uid = None
- if gid == os.getgid():
- gid = None
-
- process.Process(None, service.program, service.programArgs, os.environ,
- None, None, uid, gid, childFDs)
-
- reactor.removeReader(self.transport)
- reactor.removeWriter(self.transport)
-
-
-class InetdFactory(ServerFactory):
- protocol = InetdProtocol
- stderrFile = None
-
- def __init__(self, service):
- self.service = service
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdconf.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdconf.py
deleted file mode 100755
index f06a2ab6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdconf.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-"""
-Parser for inetd.conf files
-
-Maintainer: Andrew Bennetts
-
-Future Plans: xinetd configuration file support?
-"""
-
-# Various exceptions
-class InvalidConfError(Exception):
- """Invalid configuration file"""
-
-
-class InvalidInetdConfError(InvalidConfError):
- """Invalid inetd.conf file"""
-
-
-class InvalidServicesConfError(InvalidConfError):
- """Invalid services file"""
-
-
-class InvalidRPCServicesConfError(InvalidConfError):
- """Invalid rpc services file"""
-
-
-class UnknownService(Exception):
- """Unknown service name"""
-
-
-class SimpleConfFile:
- """Simple configuration file parser superclass.
-
- Filters out comments and empty lines (which includes lines that only
- contain comments).
-
- To use this class, override parseLine or parseFields.
- """
-
- commentChar = '#'
- defaultFilename = None
-
- def parseFile(self, file=None):
- """Parse a configuration file
-
- If file is None and self.defaultFilename is set, it will open
- defaultFilename and use it.
- """
- if file is None and self.defaultFilename:
- file = open(self.defaultFilename,'r')
-
- for line in file.readlines():
- # Strip out comments
- comment = line.find(self.commentChar)
- if comment != -1:
- line = line[:comment]
-
- # Strip whitespace
- line = line.strip()
-
- # Skip empty lines (and lines which only contain comments)
- if not line:
- continue
-
- self.parseLine(line)
-
- def parseLine(self, line):
- """Override this.
-
- By default, this will split the line on whitespace and call
- self.parseFields (catching any errors).
- """
- try:
- self.parseFields(*line.split())
- except ValueError:
- raise InvalidInetdConfError, 'Invalid line: ' + repr(line)
-
- def parseFields(self, *fields):
- """Override this."""
-
-
-class InetdService:
- """A simple description of an inetd service."""
- name = None
- port = None
- socketType = None
- protocol = None
- wait = None
- user = None
- group = None
- program = None
- programArgs = None
-
- def __init__(self, name, port, socketType, protocol, wait, user, group,
- program, programArgs):
- self.name = name
- self.port = port
- self.socketType = socketType
- self.protocol = protocol
- self.wait = wait
- self.user = user
- self.group = group
- self.program = program
- self.programArgs = programArgs
-
-
-class InetdConf(SimpleConfFile):
- """Configuration parser for a traditional UNIX inetd(8)"""
-
- defaultFilename = '/etc/inetd.conf'
-
- def __init__(self, knownServices=None):
- self.services = []
-
- if knownServices is None:
- knownServices = ServicesConf()
- knownServices.parseFile()
- self.knownServices = knownServices
-
- def parseFields(self, serviceName, socketType, protocol, wait, user,
- program, *programArgs):
- """Parse an inetd.conf file.
-
- Implemented from the description in the Debian inetd.conf man page.
- """
- # Extract user (and optional group)
- user, group = (user.split('.') + [None])[:2]
-
- # Find the port for a service
- port = self.knownServices.services.get((serviceName, protocol), None)
- if not port and not protocol.startswith('rpc/'):
- # FIXME: Should this be discarded/ignored, rather than throwing
- # an exception?
- try:
- port = int(serviceName)
- serviceName = 'unknown'
- except:
- raise UnknownService, "Unknown service: %s (%s)" \
- % (serviceName, protocol)
-
- self.services.append(InetdService(serviceName, port, socketType,
- protocol, wait, user, group, program,
- programArgs))
-
-
-class ServicesConf(SimpleConfFile):
- """/etc/services parser
-
- @ivar services: dict mapping service names to (port, protocol) tuples.
- """
-
- defaultFilename = '/etc/services'
-
- def __init__(self):
- self.services = {}
-
- def parseFields(self, name, portAndProtocol, *aliases):
- try:
- port, protocol = portAndProtocol.split('/')
- port = long(port)
- except:
- raise InvalidServicesConfError, 'Invalid port/protocol:' + \
- repr(portAndProtocol)
-
- self.services[(name, protocol)] = port
- for alias in aliases:
- self.services[(alias, protocol)] = port
-
-
-class RPCServicesConf(SimpleConfFile):
- """/etc/rpc parser
-
- @ivar self.services: dict mapping rpc service names to rpc ports.
- """
-
- defaultFilename = '/etc/rpc'
-
- def __init__(self):
- self.services = {}
-
- def parseFields(self, name, port, *aliases):
- try:
- port = long(port)
- except:
- raise InvalidRPCServicesConfError, 'Invalid port:' + repr(port)
-
- self.services[name] = port
- for alias in aliases:
- self.services[alias] = port
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdtap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdtap.py
deleted file mode 100755
index 3e628779..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/inetdtap.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""
-Twisted inetd TAP support
-
-Maintainer: Andrew Bennetts
-
-Future Plans: more configurability.
-"""
-
-import os, pwd, grp, socket
-
-from twisted.runner import inetd, inetdconf
-from twisted.python import log, usage
-from twisted.internet.protocol import ServerFactory
-from twisted.application import internet, service as appservice
-
-try:
- import portmap
- rpcOk = 1
-except ImportError:
- rpcOk = 0
-
-
-# Protocol map
-protocolDict = {'tcp': socket.IPPROTO_TCP, 'udp': socket.IPPROTO_UDP}
-
-
-class Options(usage.Options):
-
- optParameters = [
- ['rpc', 'r', '/etc/rpc', 'RPC procedure table file'],
- ['file', 'f', '/etc/inetd.conf', 'Service configuration file']
- ]
-
- optFlags = [['nointernal', 'i', "Don't run internal services"]]
-
- compData = usage.Completions(
- optActions={"file": usage.CompleteFiles('*.conf')}
- )
-
-class RPCServer(internet.TCPServer):
-
- def __init__(self, rpcVersions, rpcConf, proto, service):
- internet.TCPServer.__init__(0, ServerFactory())
- self.rpcConf = rpcConf
- self.proto = proto
- self.service = service
-
- def startService(self):
- internet.TCPServer.startService(self)
- import portmap
- portNo = self._port.getHost()[2]
- service = self.service
- for version in rpcVersions:
- portmap.set(self.rpcConf.services[name], version, self.proto,
- portNo)
- inetd.forkPassingFD(service.program, service.programArgs,
- os.environ, service.user, service.group, p)
-
-def makeService(config):
- s = appservice.MultiService()
- conf = inetdconf.InetdConf()
- conf.parseFile(open(config['file']))
-
- rpcConf = inetdconf.RPCServicesConf()
- try:
- rpcConf.parseFile(open(config['rpc']))
- except:
- # We'll survive even if we can't read /etc/rpc
- log.deferr()
-
- for service in conf.services:
- rpc = service.protocol.startswith('rpc/')
- protocol = service.protocol
-
- if rpc and not rpcOk:
- log.msg('Skipping rpc service due to lack of rpc support')
- continue
-
- if rpc:
- # RPC has extra options, so extract that
- protocol = protocol[4:] # trim 'rpc/'
- if not protocolDict.has_key(protocol):
- log.msg('Bad protocol: ' + protocol)
- continue
-
- try:
- name, rpcVersions = service.name.split('/')
- except ValueError:
- log.msg('Bad RPC service/version: ' + service.name)
- continue
-
- if not rpcConf.services.has_key(name):
- log.msg('Unknown RPC service: ' + repr(service.name))
- continue
-
- try:
- if '-' in rpcVersions:
- start, end = map(int, rpcVersions.split('-'))
- rpcVersions = range(start, end+1)
- else:
- rpcVersions = [int(rpcVersions)]
- except ValueError:
- log.msg('Bad RPC versions: ' + str(rpcVersions))
- continue
-
- if (protocol, service.socketType) not in [('tcp', 'stream'),
- ('udp', 'dgram')]:
- log.msg('Skipping unsupported type/protocol: %s/%s'
- % (service.socketType, service.protocol))
- continue
-
- # Convert the username into a uid (if necessary)
- try:
- service.user = int(service.user)
- except ValueError:
- try:
- service.user = pwd.getpwnam(service.user)[2]
- except KeyError:
- log.msg('Unknown user: ' + service.user)
- continue
-
- # Convert the group name into a gid (if necessary)
- if service.group is None:
- # If no group was specified, use the user's primary group
- service.group = pwd.getpwuid(service.user)[3]
- else:
- try:
- service.group = int(service.group)
- except ValueError:
- try:
- service.group = grp.getgrnam(service.group)[2]
- except KeyError:
- log.msg('Unknown group: ' + service.group)
- continue
-
- if service.program == 'internal':
- if config['nointernal']:
- continue
-
- # Internal services can use a standard ServerFactory
- if not inetd.internalProtocols.has_key(service.name):
- log.msg('Unknown internal service: ' + service.name)
- continue
- factory = ServerFactory()
- factory.protocol = inetd.internalProtocols[service.name]
- elif rpc:
- i = RPCServer(rpcVersions, rpcConf, proto, service)
- i.setServiceParent(s)
- continue
- else:
- # Non-internal non-rpc services use InetdFactory
- factory = inetd.InetdFactory(service)
-
- if protocol == 'tcp':
- internet.TCPServer(service.port, factory).setServiceParent(s)
- elif protocol == 'udp':
- raise RuntimeError("not supporting UDP")
- return s
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.c
deleted file mode 100644
index ca0c1c93..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Twisted Matrix Laboratories.
- * See LICENSE for details.
-
- *
- */
-
-/* portmap.c: A simple Python wrapper for pmap_set(3) and pmap_unset(3) */
-
-#include <Python.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h>
-
-static PyObject * portmap_set(PyObject *self, PyObject *args)
-{
- unsigned long program, version;
- int protocol;
- unsigned short port;
-
- if (!PyArg_ParseTuple(args, "llih:set",
- &program, &version, &protocol, &port))
- return NULL;
-
- pmap_unset(program, version);
- pmap_set(program, version, protocol, port);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject * portmap_unset(PyObject *self, PyObject *args)
-{
- unsigned long program, version;
-
- if (!PyArg_ParseTuple(args, "ll:unset",
- &program, &version))
- return NULL;
-
- pmap_unset(program, version);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef PortmapMethods[] = {
- {"set", portmap_set, METH_VARARGS,
- "Set an entry in the portmapper."},
- {"unset", portmap_unset, METH_VARARGS,
- "Unset an entry in the portmapper."},
- {NULL, NULL, 0, NULL}
-};
-
-void initportmap(void)
-{
- (void) Py_InitModule("portmap", PortmapMethods);
-}
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.py
deleted file mode 100755
index 247fc8f8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'portmap.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.so b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.so
deleted file mode 100755
index 5c0d481a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/portmap.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmon.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmon.py
deleted file mode 100755
index 3515995e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmon.py
+++ /dev/null
@@ -1,310 +0,0 @@
-# -*- test-case-name: twisted.runner.test.test_procmon -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support for starting, monitoring, and restarting child process.
-"""
-import warnings
-
-from twisted.python import log
-from twisted.internet import error, protocol, reactor as _reactor
-from twisted.application import service
-from twisted.protocols import basic
-
-class DummyTransport:
-
- disconnecting = 0
-
-transport = DummyTransport()
-
-class LineLogger(basic.LineReceiver):
-
- tag = None
- delimiter = '\n'
-
- def lineReceived(self, line):
- log.msg('[%s] %s' % (self.tag, line))
-
-
-class LoggingProtocol(protocol.ProcessProtocol):
-
- service = None
- name = None
- empty = 1
-
- def connectionMade(self):
- self.output = LineLogger()
- self.output.tag = self.name
- self.output.makeConnection(transport)
-
-
- def outReceived(self, data):
- self.output.dataReceived(data)
- self.empty = data[-1] == '\n'
-
- errReceived = outReceived
-
-
- def processEnded(self, reason):
- if not self.empty:
- self.output.dataReceived('\n')
- self.service.connectionLost(self.name)
-
-
-class ProcessMonitor(service.Service):
- """
- ProcessMonitor runs processes, monitors their progress, and restarts
- them when they die.
-
- The ProcessMonitor will not attempt to restart a process that appears to
- die instantly -- with each "instant" death (less than 1 second, by
- default), it will delay approximately twice as long before restarting
- it. A successful run will reset the counter.
-
- The primary interface is L{addProcess} and L{removeProcess}. When the
- service is running (that is, when the application it is attached to is
- running), adding a process automatically starts it.
-
- Each process has a name. This name string must uniquely identify the
- process. In particular, attempting to add two processes with the same
- name will result in a C{KeyError}.
-
- @type threshold: C{float}
- @ivar threshold: How long a process has to live before the death is
- considered instant, in seconds. The default value is 1 second.
-
- @type killTime: C{float}
- @ivar killTime: How long a process being killed has to get its affairs
- in order before it gets killed with an unmaskable signal. The
- default value is 5 seconds.
-
- @type minRestartDelay: C{float}
- @ivar minRestartDelay: The minimum time (in seconds) to wait before
- attempting to restart a process. Default 1s.
-
- @type maxRestartDelay: C{float}
- @ivar maxRestartDelay: The maximum time (in seconds) to wait before
- attempting to restart a process. Default 3600s (1h).
-
- @type _reactor: L{IReactorProcess} provider
- @ivar _reactor: A provider of L{IReactorProcess} and L{IReactorTime}
- which will be used to spawn processes and register delayed calls.
-
- """
- threshold = 1
- killTime = 5
- minRestartDelay = 1
- maxRestartDelay = 3600
-
-
- def __init__(self, reactor=_reactor):
- self._reactor = reactor
-
- self.processes = {}
- self.protocols = {}
- self.delay = {}
- self.timeStarted = {}
- self.murder = {}
- self.restart = {}
-
-
- def __getstate__(self):
- dct = service.Service.__getstate__(self)
- del dct['_reactor']
- dct['protocols'] = {}
- dct['delay'] = {}
- dct['timeStarted'] = {}
- dct['murder'] = {}
- dct['restart'] = {}
- return dct
-
-
- def addProcess(self, name, args, uid=None, gid=None, env={}):
- """
- Add a new monitored process and start it immediately if the
- L{ProcessMonitor} service is running.
-
- Note that args are passed to the system call, not to the shell. If
- running the shell is desired, the common idiom is to use
- C{ProcessMonitor.addProcess("name", ['/bin/sh', '-c', shell_script])}
-
- @param name: A name for this process. This value must be
- unique across all processes added to this monitor.
- @type name: C{str}
- @param args: The argv sequence for the process to launch.
- @param uid: The user ID to use to run the process. If C{None},
- the current UID is used.
- @type uid: C{int}
- @param gid: The group ID to use to run the process. If C{None},
- the current GID is used.
- @type uid: C{int}
- @param env: The environment to give to the launched process. See
- L{IReactorProcess.spawnProcess}'s C{env} parameter.
- @type env: C{dict}
- @raises: C{KeyError} if a process with the given name already
- exists
- """
- if name in self.processes:
- raise KeyError("remove %s first" % (name,))
- self.processes[name] = args, uid, gid, env
- self.delay[name] = self.minRestartDelay
- if self.running:
- self.startProcess(name)
-
-
- def removeProcess(self, name):
- """
- Stop the named process and remove it from the list of monitored
- processes.
-
- @type name: C{str}
- @param name: A string that uniquely identifies the process.
- """
- self.stopProcess(name)
- del self.processes[name]
-
-
- def startService(self):
- """
- Start all monitored processes.
- """
- service.Service.startService(self)
- for name in self.processes:
- self.startProcess(name)
-
-
- def stopService(self):
- """
- Stop all monitored processes and cancel all scheduled process restarts.
- """
- service.Service.stopService(self)
-
- # Cancel any outstanding restarts
- for name, delayedCall in self.restart.items():
- if delayedCall.active():
- delayedCall.cancel()
-
- for name in self.processes:
- self.stopProcess(name)
-
-
- def connectionLost(self, name):
- """
- Called when a monitored processes exits. If
- L{ProcessMonitor.running} is C{True} (ie the service is started), the
- process will be restarted.
- If the process had been running for more than
- L{ProcessMonitor.threshold} seconds it will be restarted immediately.
- If the process had been running for less than
- L{ProcessMonitor.threshold} seconds, the restart will be delayed and
- each time the process dies before the configured threshold, the restart
- delay will be doubled - up to a maximum delay of maxRestartDelay sec.
-
- @type name: C{str}
- @param name: A string that uniquely identifies the process
- which exited.
- """
- # Cancel the scheduled _forceStopProcess function if the process
- # dies naturally
- if name in self.murder:
- if self.murder[name].active():
- self.murder[name].cancel()
- del self.murder[name]
-
- del self.protocols[name]
-
- if self._reactor.seconds() - self.timeStarted[name] < self.threshold:
- # The process died too fast - backoff
- nextDelay = self.delay[name]
- self.delay[name] = min(self.delay[name] * 2, self.maxRestartDelay)
-
- else:
- # Process had been running for a significant amount of time
- # restart immediately
- nextDelay = 0
- self.delay[name] = self.minRestartDelay
-
- # Schedule a process restart if the service is running
- if self.running and name in self.processes:
- self.restart[name] = self._reactor.callLater(nextDelay,
- self.startProcess,
- name)
-
-
- def startProcess(self, name):
- """
- @param name: The name of the process to be started
- """
- # If a protocol instance already exists, it means the process is
- # already running
- if name in self.protocols:
- return
-
- args, uid, gid, env = self.processes[name]
-
- proto = LoggingProtocol()
- proto.service = self
- proto.name = name
- self.protocols[name] = proto
- self.timeStarted[name] = self._reactor.seconds()
- self._reactor.spawnProcess(proto, args[0], args, uid=uid,
- gid=gid, env=env)
-
-
- def _forceStopProcess(self, proc):
- """
- @param proc: An L{IProcessTransport} provider
- """
- try:
- proc.signalProcess('KILL')
- except error.ProcessExitedAlready:
- pass
-
-
- def stopProcess(self, name):
- """
- @param name: The name of the process to be stopped
- """
- if name not in self.processes:
- raise KeyError('Unrecognized process name: %s' % (name,))
-
- proto = self.protocols.get(name, None)
- if proto is not None:
- proc = proto.transport
- try:
- proc.signalProcess('TERM')
- except error.ProcessExitedAlready:
- pass
- else:
- self.murder[name] = self._reactor.callLater(
- self.killTime,
- self._forceStopProcess, proc)
-
-
- def restartAll(self):
- """
- Restart all processes. This is useful for third party management
- services to allow a user to restart servers because of an outside change
- in circumstances -- for example, a new version of a library is
- installed.
- """
- for name in self.processes:
- self.stopProcess(name)
-
-
- def __repr__(self):
- l = []
- for name, proc in self.processes.items():
- uidgid = ''
- if proc[1] is not None:
- uidgid = str(proc[1])
- if proc[2] is not None:
- uidgid += ':'+str(proc[2])
-
- if uidgid:
- uidgid = '(' + uidgid + ')'
- l.append('%r%s: %r' % (name, uidgid, proc[0]))
- return ('<' + self.__class__.__name__ + ' '
- + ' '.join(l)
- + '>')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmontap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmontap.py
deleted file mode 100755
index c0e72a45..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/procmontap.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- test-case-name: twisted.runner.test.test_procmontap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support for creating a service which runs a process monitor.
-"""
-
-from twisted.python import usage
-from twisted.runner.procmon import ProcessMonitor
-
-
-class Options(usage.Options):
- """
- Define the options accepted by the I{twistd procmon} plugin.
- """
-
- synopsis = "[procmon options] commandline"
-
- optParameters = [["threshold", "t", 1, "How long a process has to live "
- "before the death is considered instant, in seconds.",
- float],
- ["killtime", "k", 5, "How long a process being killed "
- "has to get its affairs in order before it gets killed "
- "with an unmaskable signal.",
- float],
- ["minrestartdelay", "m", 1, "The minimum time (in "
- "seconds) to wait before attempting to restart a "
- "process", float],
- ["maxrestartdelay", "M", 3600, "The maximum time (in "
- "seconds) to wait before attempting to restart a "
- "process", float]]
-
- optFlags = []
-
-
- longdesc = """\
-procmon runs processes, monitors their progress, and restarts them when they
-die.
-
-procmon will not attempt to restart a process that appears to die instantly;
-with each "instant" death (less than 1 second, by default), it will delay
-approximately twice as long before restarting it. A successful run will reset
-the counter.
-
-Eg twistd procmon sleep 10"""
-
- def parseArgs(self, *args):
- """
- Grab the command line that is going to be started and monitored
- """
- self['args'] = args
-
-
- def postOptions(self):
- """
- Check for dependencies.
- """
- if len(self["args"]) < 1:
- raise usage.UsageError("Please specify a process commandline")
-
-
-
-def makeService(config):
- s = ProcessMonitor()
-
- s.threshold = config["threshold"]
- s.killTime = config["killtime"]
- s.minRestartDelay = config["minrestartdelay"]
- s.maxRestartDelay = config["maxrestartdelay"]
-
- s.addProcess(" ".join(config["args"]), config["args"])
- return s
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/__init__.py
deleted file mode 100755
index e6c22ba6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test package for Twisted Runner.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmon.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmon.py
deleted file mode 100755
index d5217a0c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmon.py
+++ /dev/null
@@ -1,477 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.runner.procmon}.
-"""
-
-from twisted.trial import unittest
-from twisted.runner.procmon import LoggingProtocol, ProcessMonitor
-from twisted.internet.error import (ProcessDone, ProcessTerminated,
- ProcessExitedAlready)
-from twisted.internet.task import Clock
-from twisted.python.failure import Failure
-from twisted.test.proto_helpers import MemoryReactor
-
-
-
-class DummyProcess(object):
- """
- An incomplete and fake L{IProcessTransport} implementation for testing how
- L{ProcessMonitor} behaves when its monitored processes exit.
-
- @ivar _terminationDelay: the delay in seconds after which the DummyProcess
- will appear to exit when it receives a TERM signal
- """
-
- pid = 1
- proto = None
-
- _terminationDelay = 1
-
- def __init__(self, reactor, executable, args, environment, path,
- proto, uid=None, gid=None, usePTY=0, childFDs=None):
-
- self.proto = proto
-
- self._reactor = reactor
- self._executable = executable
- self._args = args
- self._environment = environment
- self._path = path
- self._uid = uid
- self._gid = gid
- self._usePTY = usePTY
- self._childFDs = childFDs
-
-
- def signalProcess(self, signalID):
- """
- A partial implementation of signalProcess which can only handle TERM and
- KILL signals.
- - When a TERM signal is given, the dummy process will appear to exit
- after L{DummyProcess._terminationDelay} seconds with exit code 0
- - When a KILL signal is given, the dummy process will appear to exit
- immediately with exit code 1.
-
- @param signalID: The signal name or number to be issued to the process.
- @type signalID: C{str}
- """
- params = {
- "TERM": (self._terminationDelay, 0),
- "KILL": (0, 1)
- }
-
- if self.pid is None:
- raise ProcessExitedAlready()
-
- if signalID in params:
- delay, status = params[signalID]
- self._signalHandler = self._reactor.callLater(
- delay, self.processEnded, status)
-
-
- def processEnded(self, status):
- """
- Deliver the process ended event to C{self.proto}.
- """
- self.pid = None
- statusMap = {
- 0: ProcessDone,
- 1: ProcessTerminated,
- }
- self.proto.processEnded(Failure(statusMap[status](status)))
-
-
-
-class DummyProcessReactor(MemoryReactor, Clock):
- """
- @ivar spawnedProcesses: a list that keeps track of the fake process
- instances built by C{spawnProcess}.
- @type spawnedProcesses: C{list}
- """
- def __init__(self):
- MemoryReactor.__init__(self)
- Clock.__init__(self)
-
- self.spawnedProcesses = []
-
-
- def spawnProcess(self, processProtocol, executable, args=(), env={},
- path=None, uid=None, gid=None, usePTY=0,
- childFDs=None):
- """
- Fake L{reactor.spawnProcess}, that logs all the process
- arguments and returns a L{DummyProcess}.
- """
-
- proc = DummyProcess(self, executable, args, env, path,
- processProtocol, uid, gid, usePTY, childFDs)
- processProtocol.makeConnection(proc)
- self.spawnedProcesses.append(proc)
- return proc
-
-
-
-class ProcmonTests(unittest.TestCase):
- """
- Tests for L{ProcessMonitor}.
- """
-
- def setUp(self):
- """
- Create an L{ProcessMonitor} wrapped around a fake reactor.
- """
- self.reactor = DummyProcessReactor()
- self.pm = ProcessMonitor(reactor=self.reactor)
- self.pm.minRestartDelay = 2
- self.pm.maxRestartDelay = 10
- self.pm.threshold = 10
-
-
- def test_getStateIncludesProcesses(self):
- """
- The list of monitored processes must be included in the pickle state.
- """
- self.pm.addProcess("foo", ["arg1", "arg2"],
- uid=1, gid=2, env={})
- self.assertEqual(self.pm.__getstate__()['processes'],
- {'foo': (['arg1', 'arg2'], 1, 2, {})})
-
-
- def test_getStateExcludesReactor(self):
- """
- The private L{ProcessMonitor._reactor} instance variable should not be
- included in the pickle state.
- """
- self.assertNotIn('_reactor', self.pm.__getstate__())
-
-
- def test_addProcess(self):
- """
- L{ProcessMonitor.addProcess} only starts the named program if
- L{ProcessMonitor.startService} has been called.
- """
- self.pm.addProcess("foo", ["arg1", "arg2"],
- uid=1, gid=2, env={})
- self.assertEqual(self.pm.protocols, {})
- self.assertEqual(self.pm.processes,
- {"foo": (["arg1", "arg2"], 1, 2, {})})
- self.pm.startService()
- self.reactor.advance(0)
- self.assertEqual(self.pm.protocols.keys(), ["foo"])
-
-
- def test_addProcessDuplicateKeyError(self):
- """
- L{ProcessMonitor.addProcess} raises a C{KeyError} if a process with the
- given name already exists.
- """
- self.pm.addProcess("foo", ["arg1", "arg2"],
- uid=1, gid=2, env={})
- self.assertRaises(KeyError, self.pm.addProcess,
- "foo", ["arg1", "arg2"], uid=1, gid=2, env={})
-
-
- def test_addProcessEnv(self):
- """
- L{ProcessMonitor.addProcess} takes an C{env} parameter that is passed to
- L{IReactorProcess.spawnProcess}.
- """
- fakeEnv = {"KEY": "value"}
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"], uid=1, gid=2, env=fakeEnv)
- self.reactor.advance(0)
- self.assertEqual(
- self.reactor.spawnedProcesses[0]._environment, fakeEnv)
-
-
- def test_removeProcess(self):
- """
- L{ProcessMonitor.removeProcess} removes the process from the public
- processes list.
- """
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
- self.assertEqual(len(self.pm.processes), 1)
- self.pm.removeProcess("foo")
- self.assertEqual(len(self.pm.processes), 0)
-
-
- def test_removeProcessUnknownKeyError(self):
- """
- L{ProcessMonitor.removeProcess} raises a C{KeyError} if the given
- process name isn't recognised.
- """
- self.pm.startService()
- self.assertRaises(KeyError, self.pm.removeProcess, "foo")
-
-
- def test_startProcess(self):
- """
- When a process has been started, an instance of L{LoggingProtocol} will
- be added to the L{ProcessMonitor.protocols} dict and the start time of
- the process will be recorded in the L{ProcessMonitor.timeStarted}
- dictionary.
- """
- self.pm.addProcess("foo", ["foo"])
- self.pm.startProcess("foo")
- self.assertIsInstance(self.pm.protocols["foo"], LoggingProtocol)
- self.assertIn("foo", self.pm.timeStarted.keys())
-
-
- def test_startProcessAlreadyStarted(self):
- """
- L{ProcessMonitor.startProcess} silently returns if the named process is
- already started.
- """
- self.pm.addProcess("foo", ["foo"])
- self.pm.startProcess("foo")
- self.assertIdentical(None, self.pm.startProcess("foo"))
-
-
- def test_startProcessUnknownKeyError(self):
- """
- L{ProcessMonitor.startProcess} raises a C{KeyError} if the given
- process name isn't recognised.
- """
- self.assertRaises(KeyError, self.pm.startProcess, "foo")
-
-
- def test_stopProcessNaturalTermination(self):
- """
- L{ProcessMonitor.stopProcess} immediately sends a TERM signal to the
- named process.
- """
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
- self.assertIn("foo", self.pm.protocols)
-
- # Configure fake process to die 1 second after receiving term signal
- timeToDie = self.pm.protocols["foo"].transport._terminationDelay = 1
-
- # Advance the reactor to just before the short lived process threshold
- # and leave enough time for the process to die
- self.reactor.advance(self.pm.threshold)
- # Then signal the process to stop
- self.pm.stopProcess("foo")
-
- # Advance the reactor just enough to give the process time to die and
- # verify that the process restarts
- self.reactor.advance(timeToDie)
-
- # We expect it to be restarted immediately
- self.assertEqual(self.reactor.seconds(),
- self.pm.timeStarted["foo"])
-
-
- def test_stopProcessForcedKill(self):
- """
- L{ProcessMonitor.stopProcess} kills a process which fails to terminate
- naturally within L{ProcessMonitor.killTime} seconds.
- """
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
- self.assertIn("foo", self.pm.protocols)
- self.reactor.advance(self.pm.threshold)
- proc = self.pm.protocols["foo"].transport
- # Arrange for the fake process to live longer than the killTime
- proc._terminationDelay = self.pm.killTime + 1
- self.pm.stopProcess("foo")
- # If process doesn't die before the killTime, procmon should
- # terminate it
- self.reactor.advance(self.pm.killTime - 1)
- self.assertEqual(0.0, self.pm.timeStarted["foo"])
-
- self.reactor.advance(1)
- # We expect it to be immediately restarted
- self.assertEqual(self.reactor.seconds(), self.pm.timeStarted["foo"])
-
-
- def test_stopProcessUnknownKeyError(self):
- """
- L{ProcessMonitor.stopProcess} raises a C{KeyError} if the given process
- name isn't recognised.
- """
- self.assertRaises(KeyError, self.pm.stopProcess, "foo")
-
-
- def test_stopProcessAlreadyStopped(self):
- """
- L{ProcessMonitor.stopProcess} silently returns if the named process
- is already stopped. eg Process has crashed and a restart has been
- rescheduled, but in the meantime, the service is stopped.
- """
- self.pm.addProcess("foo", ["foo"])
- self.assertIdentical(None, self.pm.stopProcess("foo"))
-
-
- def test_connectionLostLongLivedProcess(self):
- """
- L{ProcessMonitor.connectionLost} should immediately restart a process
- if it has been running longer than L{ProcessMonitor.threshold} seconds.
- """
- self.pm.addProcess("foo", ["foo"])
- # Schedule the process to start
- self.pm.startService()
- # advance the reactor to start the process
- self.reactor.advance(0)
- self.assertIn("foo", self.pm.protocols)
- # Long time passes
- self.reactor.advance(self.pm.threshold)
- # Process dies after threshold
- self.pm.protocols["foo"].processEnded(Failure(ProcessDone(0)))
- self.assertNotIn("foo", self.pm.protocols)
- # Process should be restarted immediately
- self.reactor.advance(0)
- self.assertIn("foo", self.pm.protocols)
-
-
- def test_connectionLostMurderCancel(self):
- """
- L{ProcessMonitor.connectionLost} cancels a scheduled process killer and
- deletes the DelayedCall from the L{ProcessMonitor.murder} list.
- """
- self.pm.addProcess("foo", ["foo"])
- # Schedule the process to start
- self.pm.startService()
- # Advance 1s to start the process then ask ProcMon to stop it
- self.reactor.advance(1)
- self.pm.stopProcess("foo")
- # A process killer has been scheduled, delayedCall is active
- self.assertIn("foo", self.pm.murder)
- delayedCall = self.pm.murder["foo"]
- self.assertTrue(delayedCall.active())
- # Advance to the point at which the dummy process exits
- self.reactor.advance(
- self.pm.protocols["foo"].transport._terminationDelay)
- # Now the delayedCall has been cancelled and deleted
- self.assertFalse(delayedCall.active())
- self.assertNotIn("foo", self.pm.murder)
-
-
- def test_connectionLostProtocolDeletion(self):
- """
- L{ProcessMonitor.connectionLost} removes the corresponding
- ProcessProtocol instance from the L{ProcessMonitor.protocols} list.
- """
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
- self.assertIn("foo", self.pm.protocols)
- self.pm.protocols["foo"].transport.signalProcess("KILL")
- self.reactor.advance(
- self.pm.protocols["foo"].transport._terminationDelay)
- self.assertNotIn("foo", self.pm.protocols)
-
-
- def test_connectionLostMinMaxRestartDelay(self):
- """
- L{ProcessMonitor.connectionLost} will wait at least minRestartDelay s
- and at most maxRestartDelay s
- """
- self.pm.minRestartDelay = 2
- self.pm.maxRestartDelay = 3
-
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
-
- self.assertEqual(self.pm.delay["foo"], self.pm.minRestartDelay)
- self.reactor.advance(self.pm.threshold - 1)
- self.pm.protocols["foo"].processEnded(Failure(ProcessDone(0)))
- self.assertEqual(self.pm.delay["foo"], self.pm.maxRestartDelay)
-
-
- def test_connectionLostBackoffDelayDoubles(self):
- """
- L{ProcessMonitor.connectionLost} doubles the restart delay each time
- the process dies too quickly.
- """
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
- self.reactor.advance(self.pm.threshold - 1) #9s
- self.assertIn("foo", self.pm.protocols)
- self.assertEqual(self.pm.delay["foo"], self.pm.minRestartDelay)
- # process dies within the threshold and should not restart immediately
- self.pm.protocols["foo"].processEnded(Failure(ProcessDone(0)))
- self.assertEqual(self.pm.delay["foo"], self.pm.minRestartDelay * 2)
-
-
- def test_startService(self):
- """
- L{ProcessMonitor.startService} starts all monitored processes.
- """
- self.pm.addProcess("foo", ["foo"])
- # Schedule the process to start
- self.pm.startService()
- # advance the reactor to start the process
- self.reactor.advance(0)
- self.assertTrue("foo" in self.pm.protocols)
-
-
- def test_stopService(self):
- """
- L{ProcessMonitor.stopService} should stop all monitored processes.
- """
- self.pm.addProcess("foo", ["foo"])
- self.pm.addProcess("bar", ["bar"])
- # Schedule the process to start
- self.pm.startService()
- # advance the reactor to start the processes
- self.reactor.advance(self.pm.threshold)
- self.assertIn("foo", self.pm.protocols)
- self.assertIn("bar", self.pm.protocols)
-
- self.reactor.advance(1)
-
- self.pm.stopService()
- # Advance to beyond the killTime - all monitored processes
- # should have exited
- self.reactor.advance(self.pm.killTime + 1)
- # The processes shouldn't be restarted
- self.assertEqual({}, self.pm.protocols)
-
-
- def test_stopServiceCancelRestarts(self):
- """
- L{ProcessMonitor.stopService} should cancel any scheduled process
- restarts.
- """
- self.pm.addProcess("foo", ["foo"])
- # Schedule the process to start
- self.pm.startService()
- # advance the reactor to start the processes
- self.reactor.advance(self.pm.threshold)
- self.assertIn("foo", self.pm.protocols)
-
- self.reactor.advance(1)
- # Kill the process early
- self.pm.protocols["foo"].processEnded(Failure(ProcessDone(0)))
- self.assertTrue(self.pm.restart['foo'].active())
- self.pm.stopService()
- # Scheduled restart should have been cancelled
- self.assertFalse(self.pm.restart['foo'].active())
-
-
- def test_stopServiceCleanupScheduledRestarts(self):
- """
- L{ProcessMonitor.stopService} should cancel all scheduled process
- restarts.
- """
- self.pm.threshold = 5
- self.pm.minRestartDelay = 5
- # Start service and add a process (started immediately)
- self.pm.startService()
- self.pm.addProcess("foo", ["foo"])
- # Stop the process after 1s
- self.reactor.advance(1)
- self.pm.stopProcess("foo")
- # Wait 1s for it to exit it will be scheduled to restart 5s later
- self.reactor.advance(1)
- # Meanwhile stop the service
- self.pm.stopService()
- # Advance to beyond the process restart time
- self.reactor.advance(6)
- # The process shouldn't have restarted because stopService has cancelled
- # all pending process restarts.
- self.assertEqual(self.pm.protocols, {})
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmontap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmontap.py
deleted file mode 100755
index de394f4a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/test/test_procmontap.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.runner.procmontap}.
-"""
-
-from twisted.python.usage import UsageError
-from twisted.trial import unittest
-from twisted.runner.procmon import ProcessMonitor
-from twisted.runner import procmontap as tap
-
-
-class ProcessMonitorTapTest(unittest.TestCase):
- """
- Tests for L{twisted.runner.procmontap}'s option parsing and makeService
- method.
- """
-
- def test_commandLineRequired(self):
- """
- The command line arguments must be provided.
- """
- opt = tap.Options()
- self.assertRaises(UsageError, opt.parseOptions, [])
-
-
- def test_threshold(self):
- """
- The threshold option is recognised as a parameter and coerced to
- float.
- """
- opt = tap.Options()
- opt.parseOptions(['--threshold', '7.5', 'foo'])
- self.assertEqual(opt['threshold'], 7.5)
-
-
- def test_killTime(self):
- """
- The killtime option is recognised as a parameter and coerced to float.
- """
- opt = tap.Options()
- opt.parseOptions(['--killtime', '7.5', 'foo'])
- self.assertEqual(opt['killtime'], 7.5)
-
-
- def test_minRestartDelay(self):
- """
- The minrestartdelay option is recognised as a parameter and coerced to
- float.
- """
- opt = tap.Options()
- opt.parseOptions(['--minrestartdelay', '7.5', 'foo'])
- self.assertEqual(opt['minrestartdelay'], 7.5)
-
-
- def test_maxRestartDelay(self):
- """
- The maxrestartdelay option is recognised as a parameter and coerced to
- float.
- """
- opt = tap.Options()
- opt.parseOptions(['--maxrestartdelay', '7.5', 'foo'])
- self.assertEqual(opt['maxrestartdelay'], 7.5)
-
-
- def test_parameterDefaults(self):
- """
- The parameters all have default values
- """
- opt = tap.Options()
- opt.parseOptions(['foo'])
- self.assertEqual(opt['threshold'], 1)
- self.assertEqual(opt['killtime'], 5)
- self.assertEqual(opt['minrestartdelay'], 1)
- self.assertEqual(opt['maxrestartdelay'], 3600)
-
-
- def test_makeService(self):
- """
- The command line gets added as a process to the ProcessMontor.
- """
- opt = tap.Options()
- opt.parseOptions(['ping', '-c', '3', '8.8.8.8'])
- s = tap.makeService(opt)
- self.assertIsInstance(s, ProcessMonitor)
- self.assertIn('ping -c 3 8.8.8.8', s.processes)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/NEWS
deleted file mode 100644
index 8b96c91e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/NEWS
+++ /dev/null
@@ -1,107 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Runner 12.2.0 (2012-08-26)
-==================================
-
-No significant changes have been made for this release.
-
-
-Twisted Runner 12.1.0 (2012-06-02)
-==================================
-
-Deprecations and Removals
--------------------------
- - ProcessMonitor.active, consistencyDelay, and consistency in
- twisted.runner.procmon were deprecated since 10.1 have been
- removed. (#5517)
-
-
-Twisted Runner 12.0.0 (2012-02-10)
-==================================
-
-No significant changes have been made for this release.
-
-
-Twisted Runner 11.1.0 (2011-11-15)
-==================================
-
-No significant changes have been made for this release.
-
-
-Twisted Runner 11.0.0 (2011-04-01)
-==================================
-
-No significant changes have been made for this release.
-
-
-Twisted Runner 10.2.0 (2010-11-29)
-==================================
-
-No significant changes have been made for this release.
-
-
-Twisted Runner 10.1.0 (2010-06-27)
-==================================
-
-Features
---------
- - twistd now has a procmon subcommand plugin - a convenient way to
- monitor and automatically restart another process. (#4356)
-
-Deprecations and Removals
--------------------------
- - twisted.runner.procmon.ProcessMonitor's active, consistency, and
- consistencyDelay attributes are now deprecated. (#1763)
-
-Other
------
- - #3775
-
-
-Twisted Runner 10.0.0 (2010-03-01)
-==================================
-
-Other
------
- - #3961
-
-
-Twisted Runner 9.0.0 (2009-11-24)
-=================================
-
-Features
---------
- - procmon.ProcessMonitor.addProcess now accepts an 'env' parameter which allows
- users to specify the environment in which a process will be run (#3691)
-
-Other
------
- - #3540
-
-
-Runner 8.2.0 (2008-12-16)
-=========================
-
-No interesting changes since Twisted 8.0.
-
-8.0.0 (2008-03-17)
-==================
-
-Misc
-----
- - Remove all "API Stability" markers (#2847)
-
-
-0.2.0 (2006-05-24)
-==================
-
-Fixes
------
- - Fix a bug that broke inetdtap.RPCServer.
- - Misc: #1142
-
-
-0.1.0
-=====
- - Pass *blocking* sockets to subprocesses run by inetd
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/README
deleted file mode 100644
index 124ce0fa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/runner/topfiles/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Twisted Runner 12.2.0
-
-Twisted Runner depends on Twisted.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/__init__.py
deleted file mode 100755
index fcde9682..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Subpackage containing the modules that implement the command line tools.
-
-Note that these are imported by top-level scripts which are intended to be
-invoked directly from a shell.
-"""
-
-from twisted.python.versions import Version
-from twisted.python.deprecate import deprecatedModuleAttribute
-
-
-deprecatedModuleAttribute(
- Version("Twisted", 11, 1, 0),
- "Seek unzipping software outside of Twisted.",
- __name__,
- "tkunzip")
-
-deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "tapconvert has been deprecated.",
- __name__,
- "tapconvert")
-
-del Version, deprecatedModuleAttribute
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistd_unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistd_unix.py
deleted file mode 100755
index 786249bb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistd_unix.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# -*- test-case-name: twisted.test.test_twistd -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import os, errno, sys
-
-from twisted.python import log, syslog, logfile, usage
-from twisted.python.util import switchUID, uidFromString, gidFromString
-from twisted.application import app, service
-from twisted.internet.interfaces import IReactorDaemonize
-from twisted import copyright
-
-
-def _umask(value):
- return int(value, 8)
-
-
-class ServerOptions(app.ServerOptions):
- synopsis = "Usage: twistd [options]"
-
- optFlags = [['nodaemon','n', "don't daemonize, don't use default umask of 0077"],
- ['originalname', None, "Don't try to change the process name"],
- ['syslog', None, "Log to syslog, not to file"],
- ['euid', '',
- "Set only effective user-id rather than real user-id. "
- "(This option has no effect unless the server is running as "
- "root, in which case it means not to shed all privileges "
- "after binding ports, retaining the option to regain "
- "privileges in cases such as spawning processes. "
- "Use with caution.)"],
- ]
-
- optParameters = [
- ['prefix', None,'twisted',
- "use the given prefix when syslogging"],
- ['pidfile','','twistd.pid',
- "Name of the pidfile"],
- ['chroot', None, None,
- 'Chroot to a supplied directory before running'],
- ['uid', 'u', None, "The uid to run as.", uidFromString],
- ['gid', 'g', None, "The gid to run as.", gidFromString],
- ['umask', None, None,
- "The (octal) file creation mask to apply.", _umask],
- ]
-
- compData = usage.Completions(
- optActions={"pidfile": usage.CompleteFiles("*.pid"),
- "chroot": usage.CompleteDirs(descr="chroot directory"),
- "gid": usage.CompleteGroups(descr="gid to run as"),
- "uid": usage.CompleteUsernames(descr="uid to run as"),
- "prefix": usage.Completer(descr="syslog prefix"),
- },
- )
-
- def opt_version(self):
- """Print version information and exit.
- """
- print 'twistd (the Twisted daemon) %s' % copyright.version
- print copyright.copyright
- sys.exit()
-
-
- def postOptions(self):
- app.ServerOptions.postOptions(self)
- if self['pidfile']:
- self['pidfile'] = os.path.abspath(self['pidfile'])
-
-
-def checkPID(pidfile):
- if not pidfile:
- return
- if os.path.exists(pidfile):
- try:
- pid = int(open(pidfile).read())
- except ValueError:
- sys.exit('Pidfile %s contains non-numeric value' % pidfile)
- try:
- os.kill(pid, 0)
- except OSError, why:
- if why[0] == errno.ESRCH:
- # The pid doesnt exists.
- log.msg('Removing stale pidfile %s' % pidfile, isError=True)
- os.remove(pidfile)
- else:
- sys.exit("Can't check status of PID %s from pidfile %s: %s" %
- (pid, pidfile, why[1]))
- else:
- sys.exit("""\
-Another twistd server is running, PID %s\n
-This could either be a previously started instance of your application or a
-different application entirely. To start a new one, either run it in some other
-directory, or use the --pidfile and --logfile parameters to avoid clashes.
-""" % pid)
-
-
-
-class UnixAppLogger(app.AppLogger):
- """
- A logger able to log to syslog, to files, and to stdout.
-
- @ivar _syslog: A flag indicating whether to use syslog instead of file
- logging.
- @type _syslog: C{bool}
-
- @ivar _syslogPrefix: If C{sysLog} is C{True}, the string prefix to use for
- syslog messages.
- @type _syslogPrefix: C{str}
-
- @ivar _nodaemon: A flag indicating the process will not be daemonizing.
- @type _nodaemon: C{bool}
- """
-
- def __init__(self, options):
- app.AppLogger.__init__(self, options)
- self._syslog = options.get("syslog", False)
- self._syslogPrefix = options.get("prefix", "")
- self._nodaemon = options.get("nodaemon", False)
-
-
- def _getLogObserver(self):
- """
- Create and return a suitable log observer for the given configuration.
-
- The observer will go to syslog using the prefix C{_syslogPrefix} if
- C{_syslog} is true. Otherwise, it will go to the file named
- C{_logfilename} or, if C{_nodaemon} is true and C{_logfilename} is
- C{"-"}, to stdout.
-
- @return: An object suitable to be passed to C{log.addObserver}.
- """
- if self._syslog:
- return syslog.SyslogObserver(self._syslogPrefix).emit
-
- if self._logfilename == '-':
- if not self._nodaemon:
- sys.exit('Daemons cannot log to stdout, exiting!')
- logFile = sys.stdout
- elif self._nodaemon and not self._logfilename:
- logFile = sys.stdout
- else:
- if not self._logfilename:
- self._logfilename = 'twistd.log'
- logFile = logfile.LogFile.fromFullPath(self._logfilename)
- try:
- import signal
- except ImportError:
- pass
- else:
- # Override if signal is set to None or SIG_DFL (0)
- if not signal.getsignal(signal.SIGUSR1):
- def rotateLog(signal, frame):
- from twisted.internet import reactor
- reactor.callFromThread(logFile.rotate)
- signal.signal(signal.SIGUSR1, rotateLog)
- return log.FileLogObserver(logFile).emit
-
-
-
-def daemonize(reactor, os):
- """
- Daemonizes the application on Unix. This is done by the usual double
- forking approach.
-
- @see: U{http://code.activestate.com/recipes/278731/}
- @see: W. Richard Stevens, "Advanced Programming in the Unix Environment",
- 1992, Addison-Wesley, ISBN 0-201-56317-7
-
- @param reactor: The reactor in use. If it provides L{IReactorDaemonize},
- its daemonization-related callbacks will be invoked.
-
- @param os: An object like the os module to use to perform the daemonization.
- """
-
- ## If the reactor requires hooks to be called for daemonization, call them.
- ## Currently the only reactor which provides/needs that is KQueueReactor.
- if IReactorDaemonize.providedBy(reactor):
- reactor.beforeDaemonize()
-
- if os.fork(): # launch child and...
- os._exit(0) # kill off parent
- os.setsid()
- if os.fork(): # launch child and...
- os._exit(0) # kill off parent again.
- null = os.open('/dev/null', os.O_RDWR)
- for i in range(3):
- try:
- os.dup2(null, i)
- except OSError, e:
- if e.errno != errno.EBADF:
- raise
- os.close(null)
-
- if IReactorDaemonize.providedBy(reactor):
- reactor.afterDaemonize()
-
-
-
-def launchWithName(name):
- if name and name != sys.argv[0]:
- exe = os.path.realpath(sys.executable)
- log.msg('Changing process name to ' + name)
- os.execv(exe, [name, sys.argv[0], '--originalname'] + sys.argv[1:])
-
-
-
-class UnixApplicationRunner(app.ApplicationRunner):
- """
- An ApplicationRunner which does Unix-specific things, like fork,
- shed privileges, and maintain a PID file.
- """
- loggerFactory = UnixAppLogger
-
- def preApplication(self):
- """
- Do pre-application-creation setup.
- """
- checkPID(self.config['pidfile'])
- self.config['nodaemon'] = (self.config['nodaemon']
- or self.config['debug'])
- self.oldstdout = sys.stdout
- self.oldstderr = sys.stderr
-
-
- def postApplication(self):
- """
- To be called after the application is created: start the
- application and run the reactor. After the reactor stops,
- clean up PID files and such.
- """
- self.startApplication(self.application)
- self.startReactor(None, self.oldstdout, self.oldstderr)
- self.removePID(self.config['pidfile'])
-
-
- def removePID(self, pidfile):
- """
- Remove the specified PID file, if possible. Errors are logged, not
- raised.
-
- @type pidfile: C{str}
- @param pidfile: The path to the PID tracking file.
- """
- if not pidfile:
- return
- try:
- os.unlink(pidfile)
- except OSError, e:
- if e.errno == errno.EACCES or e.errno == errno.EPERM:
- log.msg("Warning: No permission to delete pid file")
- else:
- log.err(e, "Failed to unlink PID file")
- except:
- log.err(None, "Failed to unlink PID file")
-
-
- def setupEnvironment(self, chroot, rundir, nodaemon, umask, pidfile):
- """
- Set the filesystem root, the working directory, and daemonize.
-
- @type chroot: C{str} or L{NoneType}
- @param chroot: If not None, a path to use as the filesystem root (using
- L{os.chroot}).
-
- @type rundir: C{str}
- @param rundir: The path to set as the working directory.
-
- @type nodaemon: C{bool}
- @param nodaemon: A flag which, if set, indicates that daemonization
- should not be done.
-
- @type umask: C{int} or L{NoneType}
- @param umask: The value to which to change the process umask.
-
- @type pidfile: C{str} or L{NoneType}
- @param pidfile: If not C{None}, the path to a file into which to put
- the PID of this process.
- """
- daemon = not nodaemon
-
- if chroot is not None:
- os.chroot(chroot)
- if rundir == '.':
- rundir = '/'
- os.chdir(rundir)
- if daemon and umask is None:
- umask = 077
- if umask is not None:
- os.umask(umask)
- if daemon:
- from twisted.internet import reactor
- daemonize(reactor, os)
- if pidfile:
- f = open(pidfile,'wb')
- f.write(str(os.getpid()))
- f.close()
-
-
- def shedPrivileges(self, euid, uid, gid):
- """
- Change the UID and GID or the EUID and EGID of this process.
-
- @type euid: C{bool}
- @param euid: A flag which, if set, indicates that only the I{effective}
- UID and GID should be set.
-
- @type uid: C{int} or C{NoneType}
- @param uid: If not C{None}, the UID to which to switch.
-
- @type gid: C{int} or C{NoneType}
- @param gid: If not C{None}, the GID to which to switch.
- """
- if uid is not None or gid is not None:
- extra = euid and 'e' or ''
- desc = '%suid/%sgid %s/%s' % (extra, extra, uid, gid)
- try:
- switchUID(uid, gid, euid)
- except OSError:
- log.msg('failed to set %s (are you root?) -- exiting.' % desc)
- sys.exit(1)
- else:
- log.msg('set %s' % desc)
-
-
- def startApplication(self, application):
- """
- Configure global process state based on the given application and run
- the application.
-
- @param application: An object which can be adapted to
- L{service.IProcess} and L{service.IService}.
- """
- process = service.IProcess(application)
- if not self.config['originalname']:
- launchWithName(process.processName)
- self.setupEnvironment(
- self.config['chroot'], self.config['rundir'],
- self.config['nodaemon'], self.config['umask'],
- self.config['pidfile'])
-
- service.IService(application).privilegedStartService()
-
- uid, gid = self.config['uid'], self.config['gid']
- if uid is None:
- uid = process.uid
- if gid is None:
- gid = process.gid
-
- self.shedPrivileges(self.config['euid'], uid, gid)
- app.startApplication(application, not self.config['no_save'])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistw.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistw.py
deleted file mode 100755
index 153b58a9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/_twistw.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# -*- test-case-name: twisted.test.test_twistd -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.python import log
-from twisted.application import app, service, internet
-from twisted import copyright
-import sys, os
-
-
-
-class ServerOptions(app.ServerOptions):
- synopsis = "Usage: twistd [options]"
-
- optFlags = [['nodaemon','n', "(for backwards compatability)."],
- ]
-
- def opt_version(self):
- """Print version information and exit.
- """
- print 'twistd (the Twisted Windows runner) %s' % copyright.version
- print copyright.copyright
- sys.exit()
-
-
-
-class WindowsApplicationRunner(app.ApplicationRunner):
- """
- An ApplicationRunner which avoids unix-specific things. No
- forking, no PID files, no privileges.
- """
-
- def preApplication(self):
- """
- Do pre-application-creation setup.
- """
- self.oldstdout = sys.stdout
- self.oldstderr = sys.stderr
- os.chdir(self.config['rundir'])
-
-
- def postApplication(self):
- """
- Start the application and run the reactor.
- """
- service.IService(self.application).privilegedStartService()
- app.startApplication(self.application, not self.config['no_save'])
- app.startApplication(internet.TimerService(0.1, lambda:None), 0)
- self.startReactor(None, self.oldstdout, self.oldstderr)
- log.msg("Server Shut Down.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/htmlizer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/htmlizer.py
deleted file mode 100755
index 43578094..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/htmlizer.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""HTML pretty-printing for Python source code."""
-
-__version__ = '$Revision: 1.8 $'[11:-2]
-
-from twisted.python import htmlizer, usage
-from twisted import copyright
-
-import os, sys
-
-header = '''<html><head>
-<title>%(title)s</title>
-<meta name=\"Generator\" content="%(generator)s" />
-%(alternate)s
-%(stylesheet)s
-</head>
-<body>
-'''
-footer = """</body>"""
-
-styleLink = '<link rel="stylesheet" href="%s" type="text/css" />'
-alternateLink = '<link rel="alternate" href="%(source)s" type="text/x-python" />'
-
-class Options(usage.Options):
- synopsis = """%s [options] source.py
- """ % (
- os.path.basename(sys.argv[0]),)
-
- optParameters = [
- ('stylesheet', 's', None, "URL of stylesheet to link to."),
- ]
-
- compData = usage.Completions(
- extraActions=[usage.CompleteFiles('*.py', descr='source python file')]
- )
-
- def parseArgs(self, filename):
- self['filename'] = filename
-
-def run():
- options = Options()
- try:
- options.parseOptions()
- except usage.UsageError, e:
- print str(e)
- sys.exit(1)
- filename = options['filename']
- if options.get('stylesheet') is not None:
- stylesheet = styleLink % (options['stylesheet'],)
- else:
- stylesheet = ''
-
- output = open(filename + '.html', 'w')
- try:
- output.write(header % {
- 'title': filename,
- 'generator': 'htmlizer/%s' % (copyright.longversion,),
- 'alternate': alternateLink % {'source': filename},
- 'stylesheet': stylesheet
- })
- htmlizer.filter(open(filename), output,
- htmlizer.SmallerHTMLWriter)
- output.write(footer)
- finally:
- output.close()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/manhole.py
deleted file mode 100755
index 06adffb4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/manhole.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Start a L{twisted.manhole} client.
-"""
-
-import sys
-
-from twisted.python import usage
-
-def run():
- config = MyOptions()
- try:
- config.parseOptions()
- except usage.UsageError, e:
- print str(e)
- print str(config)
- sys.exit(1)
-
- run_gtk2(config)
-
- from twisted.internet import reactor
- reactor.run()
-
-
-def run_gtk2(config):
- # Put these off until after we parse options, so we know what reactor
- # to load.
- from twisted.internet import gtk2reactor
- gtk2reactor.install()
-
- # Put this off until after we parse options, or else gnome eats them.
- sys.argv[:] = ['manhole']
- from twisted.manhole.ui import gtk2manhole
-
- o = config.opts
- defaults = {
- 'host': o['host'],
- 'port': o['port'],
- 'identityName': o['user'],
- 'password': o['password'],
- 'serviceName': o['service'],
- 'perspectiveName': o['perspective']
- }
- w = gtk2manhole.ManholeWindow()
- w.setDefaults(defaults)
- w.login()
-
-
-pbportno = 8787
-
-class MyOptions(usage.Options):
- optParameters=[("user", "u", "guest", "username"),
- ("password", "w", "guest"),
- ("service", "s", "twisted.manhole", "PB Service"),
- ("host", "h", "localhost"),
- ("port", "p", str(pbportno)),
- ("perspective", "P", "",
- "PB Perspective to ask for "
- "(if different than username)")]
-
- compData = usage.Completions(
- optActions={"host": usage.CompleteHostnames(),
- "user": usage.CompleteUsernames()}
- )
-
-if __name__ == '__main__':
- run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2deb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2deb.py
deleted file mode 100755
index 3951adf0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2deb.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-
-import sys, os, string, shutil
-
-from twisted.python import usage
-
-class MyOptions(usage.Options):
- optFlags = [["unsigned", "u"]]
- optParameters = [["tapfile", "t", "twistd.tap"],
- ["maintainer", "m", "", "The maintainer's name and email in a specific format: "
- "'John Doe <johndoe@example.com>'"],
- ["protocol", "p", ""],
- ["description", "e", ""],
- ["long_description", "l", ""],
- ["set-version", "V", "1.0"],
- ["debfile", "d", None],
- ["type", "y", "tap", "type of configuration: 'tap', 'xml, 'source' or 'python' for .tac files"]]
-
- compData = usage.Completions(
- optActions={
- "type": usage.CompleteList(["tap", "xml", "source", "python"]),
- "debfile": usage.CompleteFiles("*.deb")}
- )
-
- def postOptions(self):
- if not self["maintainer"]:
- raise usage.UsageError, "maintainer must be specified."
-
-
-type_dict = {
-'tap': 'file',
-'python': 'python',
-'source': 'source',
-'xml': 'xml',
-}
-
-def save_to_file(file, text):
- f = open(file, 'w')
- f.write(text)
- f.close()
-
-
-def run():
-
- try:
- config = MyOptions()
- config.parseOptions()
- except usage.error, ue:
- sys.exit("%s: %s" % (sys.argv[0], ue))
-
- tap_file = config['tapfile']
- base_tap_file = os.path.basename(config['tapfile'])
- protocol = (config['protocol'] or os.path.splitext(base_tap_file)[0])
- deb_file = config['debfile'] or 'twisted-'+protocol
- version = config['set-version']
- maintainer = config['maintainer']
- description = config['description'] or ('A Twisted-based server for %(protocol)s' %
- vars())
- long_description = config['long_description'] or 'Automatically created by tap2deb'
- twistd_option = type_dict[config['type']]
- date = string.strip(os.popen('822-date').read())
- directory = deb_file + '-' + version
- python_version = '%s.%s' % sys.version_info[:2]
-
- if os.path.exists(os.path.join('.build', directory)):
- os.system('rm -rf %s' % os.path.join('.build', directory))
- os.makedirs(os.path.join('.build', directory, 'debian'))
-
- shutil.copy(tap_file, os.path.join('.build', directory))
-
- save_to_file(os.path.join('.build', directory, 'debian', 'README.Debian'),
- '''This package was auto-generated by tap2deb\n''')
-
- save_to_file(os.path.join('.build', directory, 'debian', 'conffiles'),
- '''\
-/etc/init.d/%(deb_file)s
-/etc/default/%(deb_file)s
-/etc/%(base_tap_file)s
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'default'),
- '''\
-pidfile=/var/run/%(deb_file)s.pid
-rundir=/var/lib/%(deb_file)s/
-file=/etc/%(tap_file)s
-logfile=/var/log/%(deb_file)s.log
- ''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'init.d'),
- '''\
-#!/bin/sh
-
-PATH=/sbin:/bin:/usr/sbin:/usr/bin
-
-pidfile=/var/run/%(deb_file)s.pid \
-rundir=/var/lib/%(deb_file)s/ \
-file=/etc/%(tap_file)s \
-logfile=/var/log/%(deb_file)s.log
-
-[ -r /etc/default/%(deb_file)s ] && . /etc/default/%(deb_file)s
-
-test -x /usr/bin/twistd%(python_version)s || exit 0
-test -r $file || exit 0
-test -r /usr/share/%(deb_file)s/package-installed || exit 0
-
-
-case "$1" in
- start)
- echo -n "Starting %(deb_file)s: twistd"
- start-stop-daemon --start --quiet --exec /usr/bin/twistd%(python_version)s -- \
- --pidfile=$pidfile \
- --rundir=$rundir \
- --%(twistd_option)s=$file \
- --logfile=$logfile
- echo "."
- ;;
-
- stop)
- echo -n "Stopping %(deb_file)s: twistd"
- start-stop-daemon --stop --quiet \
- --pidfile $pidfile
- echo "."
- ;;
-
- restart)
- $0 stop
- $0 start
- ;;
-
- force-reload)
- $0 restart
- ;;
-
- *)
- echo "Usage: /etc/init.d/%(deb_file)s {start|stop|restart|force-reload}" >&2
- exit 1
- ;;
-esac
-
-exit 0
-''' % vars())
-
- os.chmod(os.path.join('.build', directory, 'debian', 'init.d'), 0755)
-
- save_to_file(os.path.join('.build', directory, 'debian', 'postinst'),
- '''\
-#!/bin/sh
-update-rc.d %(deb_file)s defaults >/dev/null
-invoke-rc.d %(deb_file)s start
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'prerm'),
- '''\
-#!/bin/sh
-invoke-rc.d %(deb_file)s stop
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'postrm'),
- '''\
-#!/bin/sh
-if [ "$1" = purge ]; then
- update-rc.d %(deb_file)s remove >/dev/null
-fi
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'changelog'),
- '''\
-%(deb_file)s (%(version)s) unstable; urgency=low
-
- * Created by tap2deb
-
- -- %(maintainer)s %(date)s
-
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'control'),
- '''\
-Source: %(deb_file)s
-Section: net
-Priority: extra
-Maintainer: %(maintainer)s
-Build-Depends-Indep: debhelper
-Standards-Version: 3.5.6
-
-Package: %(deb_file)s
-Architecture: all
-Depends: python%(python_version)s-twisted
-Description: %(description)s
- %(long_description)s
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'copyright'),
- '''\
-This package was auto-debianized by %(maintainer)s on
-%(date)s
-
-It was auto-generated by tap2deb
-
-Upstream Author(s):
-Moshe Zadka <moshez@twistedmatrix.com> -- tap2deb author
-
-Copyright:
-
-Insert copyright here.
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'dirs'),
- '''\
-etc/init.d
-etc/default
-var/lib/%(deb_file)s
-usr/share/doc/%(deb_file)s
-usr/share/%(deb_file)s
-''' % vars())
-
- save_to_file(os.path.join('.build', directory, 'debian', 'rules'),
- '''\
-#!/usr/bin/make -f
-
-export DH_COMPAT=1
-
-build: build-stamp
-build-stamp:
- dh_testdir
- touch build-stamp
-
-clean:
- dh_testdir
- dh_testroot
- rm -f build-stamp install-stamp
- dh_clean
-
-install: install-stamp
-install-stamp: build-stamp
- dh_testdir
- dh_testroot
- dh_clean -k
- dh_installdirs
-
- # Add here commands to install the package into debian/tmp.
- cp %(base_tap_file)s debian/tmp/etc/
- cp debian/init.d debian/tmp/etc/init.d/%(deb_file)s
- cp debian/default debian/tmp/etc/default/%(deb_file)s
- cp debian/copyright debian/tmp/usr/share/doc/%(deb_file)s/
- cp debian/README.Debian debian/tmp/usr/share/doc/%(deb_file)s/
- touch debian/tmp/usr/share/%(deb_file)s/package-installed
- touch install-stamp
-
-binary-arch: build install
-
-binary-indep: build install
- dh_testdir
- dh_testroot
- dh_strip
- dh_compress
- dh_installchangelogs
- dh_fixperms
- dh_installdeb
- dh_shlibdeps
- dh_gencontrol
- dh_md5sums
- dh_builddeb
-
-source diff:
- @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install
-''' % vars())
-
- os.chmod(os.path.join('.build', directory, 'debian', 'rules'), 0755)
-
- os.chdir('.build/%(directory)s' % vars())
- os.system('dpkg-buildpackage -rfakeroot'+ ['', ' -uc -us'][config['unsigned']])
-
-if __name__ == '__main__':
- run()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2rpm.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2rpm.py
deleted file mode 100755
index 30149b7d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tap2rpm.py
+++ /dev/null
@@ -1,331 +0,0 @@
-# -*- test-case-name: twisted.scripts.test.test_tap2rpm -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, os, shutil, time, glob
-import subprocess
-import tempfile
-import tarfile
-from StringIO import StringIO
-import warnings
-
-from twisted.python import usage, log, versions, deprecate
-
-
-#################################
-# data that goes in /etc/inittab
-initFileData = '''\
-#!/bin/sh
-#
-# Startup script for a Twisted service.
-#
-# chkconfig: - 85 15
-# description: Start-up script for the Twisted service "%(tap_file)s".
-
-PATH=/usr/bin:/bin:/usr/sbin:/sbin
-
-pidfile=/var/run/%(rpm_file)s.pid
-rundir=/var/lib/twisted-taps/%(rpm_file)s/
-file=/etc/twisted-taps/%(tap_file)s
-logfile=/var/log/%(rpm_file)s.log
-
-# load init function library
-. /etc/init.d/functions
-
-[ -r /etc/default/%(rpm_file)s ] && . /etc/default/%(rpm_file)s
-
-# check for required files
-if [ ! -x /usr/bin/twistd ]
-then
- echo "$0: Aborting, no /usr/bin/twistd found"
- exit 0
-fi
-if [ ! -r "$file" ]
-then
- echo "$0: Aborting, no file $file found."
- exit 0
-fi
-
-# set up run directory if necessary
-if [ ! -d "${rundir}" ]
-then
- mkdir -p "${rundir}"
-fi
-
-
-case "$1" in
- start)
- echo -n "Starting %(rpm_file)s: twistd"
- daemon twistd \\
- --pidfile=$pidfile \\
- --rundir=$rundir \\
- --%(twistd_option)s=$file \\
- --logfile=$logfile
- status %(rpm_file)s
- ;;
-
- stop)
- echo -n "Stopping %(rpm_file)s: twistd"
- kill `cat "${pidfile}"`
- status %(rpm_file)s
- ;;
-
- restart)
- "${0}" stop
- "${0}" start
- ;;
-
- *)
- echo "Usage: ${0} {start|stop|restart|}" >&2
- exit 1
- ;;
-esac
-
-exit 0
-'''
-
-#######################################
-# the data for creating the spec file
-specFileData = '''\
-Summary: %(description)s
-Name: %(rpm_file)s
-Version: %(version)s
-Release: 1
-License: Unknown
-Group: Networking/Daemons
-Source: %(tarfile_basename)s
-BuildRoot: %%{_tmppath}/%%{name}-%%{version}-root
-Requires: /usr/bin/twistd
-BuildArch: noarch
-
-%%description
-%(long_description)s
-
-%%prep
-%%setup
-%%build
-
-%%install
-[ ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != '/' ] \
- && rm -rf "$RPM_BUILD_ROOT"
-mkdir -p "$RPM_BUILD_ROOT"/etc/twisted-taps
-mkdir -p "$RPM_BUILD_ROOT"/etc/init.d
-mkdir -p "$RPM_BUILD_ROOT"/var/lib/twisted-taps
-cp "%(tap_file)s" "$RPM_BUILD_ROOT"/etc/twisted-taps/
-cp "%(rpm_file)s.init" "$RPM_BUILD_ROOT"/etc/init.d/"%(rpm_file)s"
-
-%%clean
-[ ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != '/' ] \
- && rm -rf "$RPM_BUILD_ROOT"
-
-%%post
-/sbin/chkconfig --add %(rpm_file)s
-/sbin/chkconfig --level 35 %(rpm_file)s
-/etc/init.d/%(rpm_file)s start
-
-%%preun
-/etc/init.d/%(rpm_file)s stop
-/sbin/chkconfig --del %(rpm_file)s
-
-%%files
-%%defattr(-,root,root)
-%%attr(0755,root,root) /etc/init.d/%(rpm_file)s
-%%attr(0660,root,root) /etc/twisted-taps/%(tap_file)s
-
-%%changelog
-* %(date)s %(maintainer)s
-- Created by tap2rpm: %(rpm_file)s (%(version)s)
-'''
-
-###############################
-class MyOptions(usage.Options):
- optFlags = [['quiet', 'q']]
- optParameters = [
- ["tapfile", "t", "twistd.tap"],
- ["maintainer", "m", "tap2rpm"],
- ["protocol", "p", None],
- ["description", "e", None],
- ["long_description", "l",
- "Automatically created by tap2rpm"],
- ["set-version", "V", "1.0"],
- ["rpmfile", "r", None],
- ["type", "y", "tap", "type of configuration: 'tap', 'xml, "
- "'source' or 'python'"],
- ]
-
- compData = usage.Completions(
- optActions={"type": usage.CompleteList(["tap", "xml", "source",
- "python"]),
- "rpmfile": usage.CompleteFiles("*.rpm")}
- )
-
- def postOptions(self):
- """
- Calculate the default values for certain command-line options.
- """
- # Options whose defaults depend on other parameters.
- if self['protocol'] is None:
- base_tapfile = os.path.basename(self['tapfile'])
- self['protocol'] = os.path.splitext(base_tapfile)[0]
- if self['description'] is None:
- self['description'] = "A TCP server for %s" % (self['protocol'],)
- if self['rpmfile'] is None:
- self['rpmfile'] = 'twisted-%s' % (self['protocol'],)
-
- # Values that aren't options, but are calculated from options and are
- # handy to have around.
- self['twistd_option'] = type_dict[self['type']]
- self['release-name'] = '%s-%s' % (self['rpmfile'], self['set-version'])
-
-
- def opt_unsigned(self):
- """
- Generate an unsigned rather than a signed RPM. (DEPRECATED; unsigned
- is the default)
- """
- msg = deprecate.getDeprecationWarningString(
- self.opt_unsigned, versions.Version("Twisted", 12, 1, 0))
- warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
-
- # Maintain the -u short flag
- opt_u = opt_unsigned
-
-
-type_dict = {
- 'tap': 'file',
- 'python': 'python',
- 'source': 'source',
- 'xml': 'xml',
-}
-
-
-
-##########################
-def makeBuildDir():
- """
- Set up the temporary directory for building RPMs.
-
- Returns: buildDir, a randomly-named subdirectory of baseDir.
- """
- tmpDir = tempfile.mkdtemp()
- # set up initial directory contents
- os.makedirs(os.path.join(tmpDir, 'RPMS', 'noarch'))
- os.makedirs(os.path.join(tmpDir, 'SPECS'))
- os.makedirs(os.path.join(tmpDir, 'BUILD'))
- os.makedirs(os.path.join(tmpDir, 'SOURCES'))
- os.makedirs(os.path.join(tmpDir, 'SRPMS'))
-
- log.msg(format="Created RPM build structure in %(path)r",
- path=tmpDir)
- return tmpDir
-
-
-
-def setupBuildFiles(buildDir, config):
- """
- Create files required to build an RPM in the build directory.
- """
- # Create the source tarball in the SOURCES directory.
- tarballName = "%s.tar" % (config['release-name'],)
- tarballPath = os.path.join(buildDir, "SOURCES", tarballName)
- tarballHandle = tarfile.open(tarballPath, "w")
-
- sourceDirInfo = tarfile.TarInfo(config['release-name'])
- sourceDirInfo.type = tarfile.DIRTYPE
- sourceDirInfo.mode = 0755
- tarballHandle.addfile(sourceDirInfo)
-
- tapFileBase = os.path.basename(config['tapfile'])
-
- initFileInfo = tarfile.TarInfo(
- os.path.join(
- config['release-name'],
- '%s.init' % config['rpmfile'],
- )
- )
- initFileInfo.type = tarfile.REGTYPE
- initFileInfo.mode = 0755
- initFileRealData = initFileData % {
- 'tap_file': tapFileBase,
- 'rpm_file': config['release-name'],
- 'twistd_option': config['twistd_option'],
- }
- initFileInfo.size = len(initFileRealData)
- tarballHandle.addfile(initFileInfo, StringIO(initFileRealData))
-
- tapFileHandle = open(config['tapfile'], 'rb')
- tapFileInfo = tarballHandle.gettarinfo(
- arcname=os.path.join(config['release-name'], tapFileBase),
- fileobj=tapFileHandle,
- )
- tapFileInfo.mode = 0644
- tarballHandle.addfile(tapFileInfo, tapFileHandle)
-
- tarballHandle.close()
-
- log.msg(format="Created dummy source tarball %(tarballPath)r",
- tarballPath=tarballPath)
-
- # Create the spec file in the SPECS directory.
- specName = "%s.spec" % (config['release-name'],)
- specPath = os.path.join(buildDir, "SPECS", specName)
- specHandle = open(specPath, "w")
- specFileRealData = specFileData % {
- 'description': config['description'],
- 'rpm_file': config['rpmfile'],
- 'version': config['set-version'],
- 'tarfile_basename': tarballName,
- 'tap_file': tapFileBase,
- 'date': time.strftime('%a %b %d %Y', time.localtime(time.time())),
- 'maintainer': config['maintainer'],
- 'long_description': config['long_description'],
- }
- specHandle.write(specFileRealData)
- specHandle.close()
-
- log.msg(format="Created RPM spec file %(specPath)r",
- specPath=specPath)
-
- return specPath
-
-
-
-def run(options=None):
- # parse options
- try:
- config = MyOptions()
- config.parseOptions(options)
- except usage.error, ue:
- sys.exit("%s: %s" % (sys.argv[0], ue))
-
- # create RPM build environment
- tmpDir = makeBuildDir()
- specPath = setupBuildFiles(tmpDir, config)
-
- # build rpm
- job = subprocess.Popen([
- "rpmbuild",
- "-vv",
- "--define", "_topdir %s" % (tmpDir,),
- "-ba", specPath,
- ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- stdout, _ = job.communicate()
-
- # If there was a problem, show people what it was.
- if job.returncode != 0:
- print stdout
-
- # copy the RPMs to the local directory
- rpmPath = glob.glob(os.path.join(tmpDir, 'RPMS', 'noarch', '*'))[0]
- srpmPath = glob.glob(os.path.join(tmpDir, 'SRPMS', '*'))[0]
- if not config['quiet']:
- print 'Writing "%s"...' % os.path.basename(rpmPath)
- shutil.copy(rpmPath, '.')
- if not config['quiet']:
- print 'Writing "%s"...' % os.path.basename(srpmPath)
- shutil.copy(srpmPath, '.')
-
- # remove the build directory
- shutil.rmtree(tmpDir)
-
- return [os.path.basename(rpmPath), os.path.basename(srpmPath)]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tapconvert.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tapconvert.py
deleted file mode 100755
index 4c994a0a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tapconvert.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, getpass
-
-from twisted.python import usage
-from twisted.application import app
-from twisted.persisted import sob
-
-
-class ConvertOptions(usage.Options):
- synopsis = "Usage: tapconvert [options]"
- optParameters = [
- ['in', 'i', None, "The filename of the tap to read from"],
- ['out', 'o', None, "A filename to write the tap to"],
- ['typein', 'f', 'guess',
- "The format to use; this can be 'guess', 'python', "
- "'pickle', 'xml', or 'source'."],
- ['typeout', 't', 'source',
- "The output format to use; this can be 'pickle', 'xml', or 'source'."],
- ]
-
- optFlags = [
- ['decrypt', 'd', "The specified tap/aos/xml file is encrypted."],
- ['encrypt', 'e', "Encrypt file before writing"]
- ]
-
- compData = usage.Completions(
- optActions={"typein": usage.CompleteList(["guess", "python", "pickle",
- "xml", "source"]),
- "typeout": usage.CompleteList(["pickle", "xml", "source"]),
- "in": usage.CompleteFiles(descr="tap file to read from"),
- "out": usage.CompleteFiles(descr="tap file to write to"),
- }
- )
-
- def postOptions(self):
- if self['in'] is None:
- raise usage.UsageError("%s\nYou must specify the input filename."
- % self)
- if self["typein"] == "guess":
- try:
- self["typein"] = sob.guessType(self["in"])
- except KeyError:
- raise usage.UsageError("Could not guess type for '%s'" %
- self["typein"])
-
-def run():
- options = ConvertOptions()
- try:
- options.parseOptions(sys.argv[1:])
- except usage.UsageError, e:
- print e
- else:
- app.convertStyle(options["in"], options["typein"],
- options.opts['decrypt'] or getpass.getpass('Passphrase: '),
- options["out"], options['typeout'], options["encrypt"])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/__init__.py
deleted file mode 100755
index c04ed1c4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test package for L{twisted.scripts}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_scripts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_scripts.py
deleted file mode 100755
index eeb1d1ac..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_scripts.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the command-line scripts in the top-level I{bin/} directory.
-
-Tests for actual functionality belong elsewhere, written in a way that doesn't
-involve launching child processes.
-"""
-
-from os import devnull, getcwd, chdir
-from sys import executable
-from subprocess import PIPE, Popen
-
-from twisted.trial.unittest import SkipTest, TestCase
-from twisted.python.modules import getModule
-from twisted.python.filepath import FilePath
-from twisted.python.test.test_shellcomp import ZshScriptTestMixin
-
-
-class ScriptTestsMixin:
- """
- Mixin for L{TestCase} subclasses which defines a helper function for testing
- a Twisted-using script.
- """
- bin = getModule("twisted").pathEntry.filePath.child("bin")
-
- def scriptTest(self, name):
- """
- Verify that the given script runs and uses the version of Twisted
- currently being tested.
-
- This only works when running tests against a vcs checkout of Twisted,
- since it relies on the scripts being in the place they are kept in
- version control, and exercises their logic for finding the right version
- of Twisted to use in that situation.
-
- @param name: A path fragment, relative to the I{bin} directory of a
- Twisted source checkout, identifying a script to test.
- @type name: C{str}
-
- @raise SkipTest: if the script is not where it is expected to be.
- """
- script = self.bin.preauthChild(name)
- if not script.exists():
- raise SkipTest(
- "Script tests do not apply to installed configuration.")
-
- from twisted.copyright import version
- scriptVersion = Popen(
- [executable, script.path, '--version'],
- stdout=PIPE, stderr=file(devnull)).stdout.read()
-
- self.assertIn(str(version), scriptVersion)
-
-
-
-class ScriptTests(TestCase, ScriptTestsMixin):
- """
- Tests for the core scripts.
- """
- def test_twistd(self):
- self.scriptTest("twistd")
-
-
- def test_twistdPathInsert(self):
- """
- The twistd script adds the current working directory to sys.path so
- that it's able to import modules from it.
- """
- script = self.bin.child("twistd")
- if not script.exists():
- raise SkipTest(
- "Script tests do not apply to installed configuration.")
- cwd = getcwd()
- self.addCleanup(chdir, cwd)
- testDir = FilePath(self.mktemp())
- testDir.makedirs()
- chdir(testDir.path)
- testDir.child("bar.tac").setContent(
- "import sys\n"
- "print sys.path\n")
- output = Popen(
- [executable, script.path, '-ny', 'bar.tac'],
- stdout=PIPE, stderr=file(devnull)).stdout.read()
- self.assertIn(repr(testDir.path), output)
-
-
- def test_manhole(self):
- self.scriptTest("manhole")
-
-
- def test_trial(self):
- self.scriptTest("trial")
-
-
- def test_trialPathInsert(self):
- """
- The trial script adds the current working directory to sys.path so that
- it's able to import modules from it.
- """
- script = self.bin.child("trial")
- if not script.exists():
- raise SkipTest(
- "Script tests do not apply to installed configuration.")
- cwd = getcwd()
- self.addCleanup(chdir, cwd)
- testDir = FilePath(self.mktemp())
- testDir.makedirs()
- chdir(testDir.path)
- testDir.child("foo.py").setContent("")
- output = Popen(
- [executable, script.path, 'foo'],
- stdout=PIPE, stderr=file(devnull)).stdout.read()
- self.assertIn("PASSED", output)
-
-
- def test_pyhtmlizer(self):
- self.scriptTest("pyhtmlizer")
-
-
- def test_tap2rpm(self):
- self.scriptTest("tap2rpm")
-
-
- def test_tap2deb(self):
- self.scriptTest("tap2deb")
-
-
- def test_tapconvert(self):
- self.scriptTest("tapconvert")
-
-
- def test_deprecatedTkunzip(self):
- """
- The entire L{twisted.scripts.tkunzip} module, part of the old Windows
- installer tool chain, is deprecated.
- """
- from twisted.scripts import tkunzip
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_deprecatedTkunzip])
- self.assertEqual(DeprecationWarning, warnings[0]['category'])
- self.assertEqual(
- "twisted.scripts.tkunzip was deprecated in Twisted 11.1.0: "
- "Seek unzipping software outside of Twisted.",
- warnings[0]['message'])
- self.assertEqual(1, len(warnings))
-
-
- def test_deprecatedTapconvert(self):
- """
- The entire L{twisted.scripts.tapconvert} module is deprecated.
- """
- from twisted.scripts import tapconvert
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_deprecatedTapconvert])
- self.assertEqual(DeprecationWarning, warnings[0]['category'])
- self.assertEqual(
- "twisted.scripts.tapconvert was deprecated in Twisted 12.1.0: "
- "tapconvert has been deprecated.",
- warnings[0]['message'])
- self.assertEqual(1, len(warnings))
-
-
-
-class ZshIntegrationTestCase(TestCase, ZshScriptTestMixin):
- """
- Test that zsh completion functions are generated without error
- """
- generateFor = [('twistd', 'twisted.scripts.twistd.ServerOptions'),
- ('trial', 'twisted.scripts.trial.Options'),
- ('pyhtmlizer', 'twisted.scripts.htmlizer.Options'),
- ('tap2rpm', 'twisted.scripts.tap2rpm.MyOptions'),
- ('tap2deb', 'twisted.scripts.tap2deb.MyOptions'),
- ('tapconvert', 'twisted.scripts.tapconvert.ConvertOptions'),
- ('manhole', 'twisted.scripts.manhole.MyOptions')
- ]
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_tap2rpm.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_tap2rpm.py
deleted file mode 100755
index 509e69cb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/test/test_tap2rpm.py
+++ /dev/null
@@ -1,399 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.scripts.tap2rpm}.
-"""
-import os
-
-from twisted.trial.unittest import TestCase, SkipTest
-from twisted.python import procutils
-from twisted.python import versions
-from twisted.python import deprecate
-from twisted.python.failure import Failure
-from twisted.internet import utils
-from twisted.scripts import tap2rpm
-
-# When we query the RPM metadata, we get back a string we'll have to parse, so
-# we'll use suitably rare delimiter characters to split on. Luckily, ASCII
-# defines some for us!
-RECORD_SEPARATOR = "\x1E"
-UNIT_SEPARATOR = "\x1F"
-
-
-
-def _makeRPMs(tapfile=None, maintainer=None, protocol=None, description=None,
- longDescription=None, setVersion=None, rpmfile=None, type_=None):
- """
- Helper function to invoke tap2rpm with the given parameters.
- """
- args = []
-
- if not tapfile:
- tapfile = "dummy-tap-file"
- handle = open(tapfile, "w")
- handle.write("# Dummy TAP file\n")
- handle.close()
-
- args.extend(["--quiet", "--tapfile", tapfile])
-
- if maintainer:
- args.extend(["--maintainer", maintainer])
- if protocol:
- args.extend(["--protocol", protocol])
- if description:
- args.extend(["--description", description])
- if longDescription:
- args.extend(["--long_description", longDescription])
- if setVersion:
- args.extend(["--set-version", setVersion])
- if rpmfile:
- args.extend(["--rpmfile", rpmfile])
- if type_:
- args.extend(["--type", type_])
-
- return tap2rpm.run(args)
-
-
-
-def _queryRPMTags(rpmfile, taglist):
- """
- Helper function to read the given header tags from the given RPM file.
-
- Returns a Deferred that fires with dictionary mapping a tag name to a list
- of the associated values in the RPM header. If a tag has only a single
- value in the header (like NAME or VERSION), it will be returned as a 1-item
- list.
-
- Run "rpm --querytags" to see what tags can be queried.
- """
-
- # Build a query format string that will return appropriately delimited
- # results. Every field is treated as an array field, so single-value tags
- # like VERSION will be returned as 1-item lists.
- queryFormat = RECORD_SEPARATOR.join([
- "[%%{%s}%s]" % (tag, UNIT_SEPARATOR) for tag in taglist
- ])
-
- def parseTagValues(output):
- res = {}
-
- for tag, values in zip(taglist, output.split(RECORD_SEPARATOR)):
- values = values.strip(UNIT_SEPARATOR).split(UNIT_SEPARATOR)
- res[tag] = values
-
- return res
-
- def checkErrorResult(failure):
- # The current rpm packages on Debian and Ubuntu don't properly set up
- # the RPM database, which causes rpm to print a harmless warning to
- # stderr. Unfortunately, .getProcessOutput() assumes all warnings are
- # catastrophic and panics whenever it sees one.
- #
- # See also:
- # http://twistedmatrix.com/trac/ticket/3292#comment:42
- # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=551669
- # http://rpm.org/ticket/106
-
- failure.trap(IOError)
-
- # Depending on kernel scheduling, we might read the whole error
- # message, or only the first few bytes.
- if str(failure.value).startswith("got stderr: 'error: "):
- newFailure = Failure(SkipTest("rpm is missing its package "
- "database. Run 'sudo rpm -qa > /dev/null' to create one."))
- else:
- # Not the exception we were looking for; we should report the
- # original failure.
- newFailure = failure
-
- # We don't want to raise the exception right away; we want to wait for
- # the process to exit, otherwise we'll get extra useless errors
- # reported.
- d = failure.value.processEnded
- d.addBoth(lambda _: newFailure)
- return d
-
- d = utils.getProcessOutput("rpm",
- ("-q", "--queryformat", queryFormat, "-p", rpmfile))
- d.addCallbacks(parseTagValues, checkErrorResult)
- return d
-
-
-
-class TestTap2RPM(TestCase):
-
-
- def setUp(self):
- return self._checkForRpmbuild()
-
-
- def _checkForRpmbuild(self):
- """
- tap2rpm requires rpmbuild; skip tests if rpmbuild is not present.
- """
- if not procutils.which("rpmbuild"):
- raise SkipTest("rpmbuild must be present to test tap2rpm")
-
-
- def _makeTapFile(self, basename="dummy"):
- """
- Make a temporary .tap file and returns the absolute path.
- """
- path = basename + ".tap"
- handle = open(path, "w")
- handle.write("# Dummy .tap file")
- handle.close()
- return path
-
-
- def _verifyRPMTags(self, rpmfile, **tags):
- """
- Check the given file has the given tags set to the given values.
- """
-
- d = _queryRPMTags(rpmfile, tags.keys())
- d.addCallback(self.assertEqual, tags)
- return d
-
-
- def test_optionDefaults(self):
- """
- Commandline options should default to sensible values.
-
- "sensible" here is defined as "the same values that previous versions
- defaulted to".
- """
- config = tap2rpm.MyOptions()
- config.parseOptions([])
-
- self.assertEqual(config['tapfile'], 'twistd.tap')
- self.assertEqual(config['maintainer'], 'tap2rpm')
- self.assertEqual(config['protocol'], 'twistd')
- self.assertEqual(config['description'], 'A TCP server for twistd')
- self.assertEqual(config['long_description'],
- 'Automatically created by tap2rpm')
- self.assertEqual(config['set-version'], '1.0')
- self.assertEqual(config['rpmfile'], 'twisted-twistd')
- self.assertEqual(config['type'], 'tap')
- self.assertEqual(config['quiet'], False)
- self.assertEqual(config['twistd_option'], 'file')
- self.assertEqual(config['release-name'], 'twisted-twistd-1.0')
-
-
- def test_protocolCalculatedFromTapFile(self):
- """
- The protocol name defaults to a value based on the tapfile value.
- """
- config = tap2rpm.MyOptions()
- config.parseOptions(['--tapfile', 'pancakes.tap'])
-
- self.assertEqual(config['tapfile'], 'pancakes.tap')
- self.assertEqual(config['protocol'], 'pancakes')
-
-
- def test_optionsDefaultToProtocolValue(self):
- """
- Many options default to a value calculated from the protocol name.
- """
- config = tap2rpm.MyOptions()
- config.parseOptions([
- '--tapfile', 'sausages.tap',
- '--protocol', 'eggs',
- ])
-
- self.assertEqual(config['tapfile'], 'sausages.tap')
- self.assertEqual(config['maintainer'], 'tap2rpm')
- self.assertEqual(config['protocol'], 'eggs')
- self.assertEqual(config['description'], 'A TCP server for eggs')
- self.assertEqual(config['long_description'],
- 'Automatically created by tap2rpm')
- self.assertEqual(config['set-version'], '1.0')
- self.assertEqual(config['rpmfile'], 'twisted-eggs')
- self.assertEqual(config['type'], 'tap')
- self.assertEqual(config['quiet'], False)
- self.assertEqual(config['twistd_option'], 'file')
- self.assertEqual(config['release-name'], 'twisted-eggs-1.0')
-
-
- def test_releaseNameDefaultsToRpmfileValue(self):
- """
- The release-name option is calculated from rpmfile and set-version.
- """
- config = tap2rpm.MyOptions()
- config.parseOptions([
- "--rpmfile", "beans",
- "--set-version", "1.2.3",
- ])
-
- self.assertEqual(config['release-name'], 'beans-1.2.3')
-
-
- def test_basicOperation(self):
- """
- Calling tap2rpm should produce an RPM and SRPM with default metadata.
- """
- basename = "frenchtoast"
-
- # Create RPMs based on a TAP file with this name.
- rpm, srpm = _makeRPMs(tapfile=self._makeTapFile(basename))
-
- # Verify the resulting RPMs have the correct tags.
- d = self._verifyRPMTags(rpm,
- NAME=["twisted-%s" % (basename,)],
- VERSION=["1.0"],
- RELEASE=["1"],
- SUMMARY=["A TCP server for %s" % (basename,)],
- DESCRIPTION=["Automatically created by tap2rpm"],
- )
- d.addCallback(lambda _: self._verifyRPMTags(srpm,
- NAME=["twisted-%s" % (basename,)],
- VERSION=["1.0"],
- RELEASE=["1"],
- SUMMARY=["A TCP server for %s" % (basename,)],
- DESCRIPTION=["Automatically created by tap2rpm"],
- ))
-
- return d
-
-
- def test_protocolOverride(self):
- """
- Setting 'protocol' should change the name of the resulting package.
- """
- basename = "acorn"
- protocol = "banana"
-
- # Create RPMs based on a TAP file with this name.
- rpm, srpm = _makeRPMs(tapfile=self._makeTapFile(basename),
- protocol=protocol)
-
- # Verify the resulting RPMs have the correct tags.
- d = self._verifyRPMTags(rpm,
- NAME=["twisted-%s" % (protocol,)],
- SUMMARY=["A TCP server for %s" % (protocol,)],
- )
- d.addCallback(lambda _: self._verifyRPMTags(srpm,
- NAME=["twisted-%s" % (protocol,)],
- SUMMARY=["A TCP server for %s" % (protocol,)],
- ))
-
- return d
-
-
- def test_rpmfileOverride(self):
- """
- Setting 'rpmfile' should change the name of the resulting package.
- """
- basename = "cherry"
- rpmfile = "donut"
-
- # Create RPMs based on a TAP file with this name.
- rpm, srpm = _makeRPMs(tapfile=self._makeTapFile(basename),
- rpmfile=rpmfile)
-
- # Verify the resulting RPMs have the correct tags.
- d = self._verifyRPMTags(rpm,
- NAME=[rpmfile],
- SUMMARY=["A TCP server for %s" % (basename,)],
- )
- d.addCallback(lambda _: self._verifyRPMTags(srpm,
- NAME=[rpmfile],
- SUMMARY=["A TCP server for %s" % (basename,)],
- ))
-
- return d
-
-
- def test_descriptionOverride(self):
- """
- Setting 'description' should change the SUMMARY tag.
- """
- description = "eggplant"
-
- # Create RPMs based on a TAP file with this name.
- rpm, srpm = _makeRPMs(tapfile=self._makeTapFile(),
- description=description)
-
- # Verify the resulting RPMs have the correct tags.
- d = self._verifyRPMTags(rpm,
- SUMMARY=[description],
- )
- d.addCallback(lambda _: self._verifyRPMTags(srpm,
- SUMMARY=[description],
- ))
-
- return d
-
-
- def test_longDescriptionOverride(self):
- """
- Setting 'longDescription' should change the DESCRIPTION tag.
- """
- longDescription = "fig"
-
- # Create RPMs based on a TAP file with this name.
- rpm, srpm = _makeRPMs(tapfile=self._makeTapFile(),
- longDescription=longDescription)
-
- # Verify the resulting RPMs have the correct tags.
- d = self._verifyRPMTags(rpm,
- DESCRIPTION=[longDescription],
- )
- d.addCallback(lambda _: self._verifyRPMTags(srpm,
- DESCRIPTION=[longDescription],
- ))
-
- return d
-
-
- def test_setVersionOverride(self):
- """
- Setting 'setVersion' should change the RPM's version info.
- """
- version = "123.456"
-
- # Create RPMs based on a TAP file with this name.
- rpm, srpm = _makeRPMs(tapfile=self._makeTapFile(),
- setVersion=version)
-
- # Verify the resulting RPMs have the correct tags.
- d = self._verifyRPMTags(rpm,
- VERSION=["123.456"],
- RELEASE=["1"],
- )
- d.addCallback(lambda _: self._verifyRPMTags(srpm,
- VERSION=["123.456"],
- RELEASE=["1"],
- ))
-
- return d
-
-
- def test_tapInOtherDirectory(self):
- """
- tap2rpm handles tapfiles outside the current directory.
- """
- # Make a tapfile outside the current directory.
- tempdir = self.mktemp()
- os.mkdir(tempdir)
- tapfile = self._makeTapFile(os.path.join(tempdir, "bacon"))
-
- # Try and make an RPM from that tapfile.
- _makeRPMs(tapfile=tapfile)
-
-
- def test_unsignedFlagDeprecationWarning(self):
- """
- The 'unsigned' flag in tap2rpm should be deprecated, and its use
- should raise a warning as such.
- """
- config = tap2rpm.MyOptions()
- config.parseOptions(['--unsigned'])
- warnings = self.flushWarnings()
- self.assertEqual(DeprecationWarning, warnings[0]['category'])
- self.assertEqual(
- deprecate.getDeprecationWarningString(
- config.opt_unsigned, versions.Version("Twisted", 12, 1, 0)),
- warnings[0]['message'])
- self.assertEqual(1, len(warnings))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tkunzip.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tkunzip.py
deleted file mode 100755
index e2a4629d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/tkunzip.py
+++ /dev/null
@@ -1,290 +0,0 @@
-# -*- test-case-name: twisted.scripts.test.test_scripts -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Post-install GUI to compile to pyc and unpack twisted doco.
-"""
-
-import sys
-import zipfile
-import py_compile
-
-# we're going to ignore failures to import tkinter and fall back
-# to using the console if the required dll is not found
-
-# Scary kludge to work around tk84.dll bug:
-# https://sourceforge.net/tracker/index.php?func=detail&aid=814654&group_id=5470&atid=105470
-# Without which(): you get a windows missing-dll popup message
-from twisted.python.procutils import which
-tkdll='tk84.dll'
-if which(tkdll) or which('DLLs/%s' % tkdll):
- try:
- import Tkinter
- from Tkinter import *
- from twisted.internet import tksupport
- except ImportError:
- pass
-
-# twisted
-from twisted.internet import reactor, defer
-from twisted.python import failure, log, zipstream, util, usage, log
-# local
-import os.path
-
-class ProgressBar:
- def __init__(self, master=None, orientation="horizontal",
- min=0, max=100, width=100, height=18,
- doLabel=1, appearance="sunken",
- fillColor="blue", background="gray",
- labelColor="yellow", labelFont="Arial",
- labelText="", labelFormat="%d%%",
- value=0, bd=2):
- # preserve various values
- self.master=master
- self.orientation=orientation
- self.min=min
- self.max=max
- self.width=width
- self.height=height
- self.doLabel=doLabel
- self.fillColor=fillColor
- self.labelFont= labelFont
- self.labelColor=labelColor
- self.background=background
- self.labelText=labelText
- self.labelFormat=labelFormat
- self.value=value
- self.frame=Frame(master, relief=appearance, bd=bd)
- self.canvas=Canvas(self.frame, height=height, width=width, bd=0,
- highlightthickness=0, background=background)
- self.scale=self.canvas.create_rectangle(0, 0, width, height,
- fill=fillColor)
- self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
- height / 2, text=labelText,
- anchor="c", fill=labelColor,
- font=self.labelFont)
- self.update()
- self.canvas.pack(side='top', fill='x', expand='no')
-
- def pack(self, *args, **kwargs):
- self.frame.pack(*args, **kwargs)
-
- def updateProgress(self, newValue, newMax=None):
- if newMax:
- self.max = newMax
- self.value = newValue
- self.update()
-
- def update(self):
- # Trim the values to be between min and max
- value=self.value
- if value > self.max:
- value = self.max
- if value < self.min:
- value = self.min
- # Adjust the rectangle
- if self.orientation == "horizontal":
- self.canvas.coords(self.scale, 0, 0,
- float(value) / self.max * self.width, self.height)
- else:
- self.canvas.coords(self.scale, 0,
- self.height - (float(value) /
- self.max*self.height),
- self.width, self.height)
- # Now update the colors
- self.canvas.itemconfig(self.scale, fill=self.fillColor)
- self.canvas.itemconfig(self.label, fill=self.labelColor)
- # And update the label
- if self.doLabel:
- if value:
- if value >= 0:
- pvalue = int((float(value) / float(self.max)) *
- 100.0)
- else:
- pvalue = 0
- self.canvas.itemconfig(self.label, text=self.labelFormat
- % pvalue)
- else:
- self.canvas.itemconfig(self.label, text='')
- else:
- self.canvas.itemconfig(self.label, text=self.labelFormat %
- self.labelText)
- self.canvas.update_idletasks()
-
-
-class Progressor:
- """A base class to make it simple to hook a progress bar up to a process.
- """
- def __init__(self, title, *args, **kwargs):
- self.title=title
- self.stopping=0
- self.bar=None
- self.iterator=None
- self.remaining=1000
-
- def setBar(self, bar, max):
- self.bar=bar
- bar.updateProgress(0, max)
- return self
-
- def setIterator(self, iterator):
- self.iterator=iterator
- return self
-
- def updateBar(self, deferred):
- b=self.bar
- try:
- b.updateProgress(b.max - self.remaining)
- except TclError:
- self.stopping=1
- except:
- deferred.errback(failure.Failure())
-
- def processAll(self, root):
- assert self.bar and self.iterator, "must setBar and setIterator"
- self.root=root
- root.title(self.title)
- d=defer.Deferred()
- d.addErrback(log.err)
- reactor.callLater(0.1, self.processOne, d)
- return d
-
- def processOne(self, deferred):
- if self.stopping:
- deferred.callback(self.root)
- return
-
- try:
- self.remaining=self.iterator.next()
- except StopIteration:
- self.stopping=1
- except:
- deferred.errback(failure.Failure())
-
- if self.remaining%10==0:
- reactor.callLater(0, self.updateBar, deferred)
- if self.remaining%100==0:
- log.msg(self.remaining)
- reactor.callLater(0, self.processOne, deferred)
-
-def compiler(path):
- """A generator for compiling files to .pyc"""
- def justlist(arg, directory, names):
- pynames=[os.path.join(directory, n) for n in names
- if n.endswith('.py')]
- arg.extend(pynames)
- all=[]
- os.path.walk(path, justlist, all)
-
- remaining=len(all)
- i=zip(all, range(remaining-1, -1, -1))
- for f, remaining in i:
- py_compile.compile(f)
- yield remaining
-
-class TkunzipOptions(usage.Options):
- optParameters=[["zipfile", "z", "", "a zipfile"],
- ["ziptargetdir", "t", ".", "where to extract zipfile"],
- ["compiledir", "c", "", "a directory to compile"],
- ]
- optFlags=[["use-console", "C", "show in the console, not graphically"],
- ["shell-exec", "x", """\
-spawn a new console to show output (implies -C)"""],
- ]
-
-def countPys(countl, directory, names):
- sofar=countl[0]
- sofar=sofar+len([f for f in names if f.endswith('.py')])
- countl[0]=sofar
- return sofar
-
-def countPysRecursive(path):
- countl=[0]
- os.path.walk(path, countPys, countl)
- return countl[0]
-
-def run(argv=sys.argv):
- log.startLogging(file('tkunzip.log', 'w'))
- opt=TkunzipOptions()
- try:
- opt.parseOptions(argv[1:])
- except usage.UsageError, e:
- print str(opt)
- print str(e)
- sys.exit(1)
-
- if opt['use-console']:
- # this should come before shell-exec to prevent infinite loop
- return doItConsolicious(opt)
- if opt['shell-exec'] or not 'Tkinter' in sys.modules:
- from distutils import sysconfig
- from twisted.scripts import tkunzip
- myfile=tkunzip.__file__
- exe=os.path.join(sysconfig.get_config_var('prefix'), 'python.exe')
- return os.system('%s %s --use-console %s' % (exe, myfile,
- ' '.join(argv[1:])))
- return doItTkinterly(opt)
-
-def doItConsolicious(opt):
- # reclaim stdout/stderr from log
- sys.stdout = sys.__stdout__
- sys.stderr = sys.__stderr__
- if opt['zipfile']:
- print 'Unpacking documentation...'
- for n in zipstream.unzipIter(opt['zipfile'], opt['ziptargetdir']):
- if n % 100 == 0:
- print n,
- if n % 1000 == 0:
- print
- print 'Done unpacking.'
-
- if opt['compiledir']:
- print 'Compiling to pyc...'
- import compileall
- compileall.compile_dir(opt["compiledir"])
- print 'Done compiling.'
-
-def doItTkinterly(opt):
- root=Tkinter.Tk()
- root.withdraw()
- root.title('One Moment.')
- root.protocol('WM_DELETE_WINDOW', reactor.stop)
- tksupport.install(root)
-
- prog=ProgressBar(root, value=0, labelColor="black", width=200)
- prog.pack()
-
- # callback immediately
- d=defer.succeed(root).addErrback(log.err)
-
- def deiconify(root):
- root.deiconify()
- return root
-
- d.addCallback(deiconify)
-
- if opt['zipfile']:
- uz=Progressor('Unpacking documentation...')
- max=zipstream.countZipFileChunks(opt['zipfile'], 4096)
- uz.setBar(prog, max)
- uz.setIterator(zipstream.unzipIterChunky(opt['zipfile'],
- opt['ziptargetdir']))
- d.addCallback(uz.processAll)
-
- if opt['compiledir']:
- comp=Progressor('Compiling to pyc...')
- comp.setBar(prog, countPysRecursive(opt['compiledir']))
- comp.setIterator(compiler(opt['compiledir']))
- d.addCallback(comp.processAll)
-
- def stop(ignore):
- reactor.stop()
- root.destroy()
- d.addCallback(stop)
-
- reactor.run()
-
-
-if __name__=='__main__':
- run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/trial.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/trial.py
deleted file mode 100755
index 19d6cf3a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/trial.py
+++ /dev/null
@@ -1,371 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_script -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-import sys, os, random, gc, time, warnings
-
-from twisted.internet import defer
-from twisted.application import app
-from twisted.python import usage, reflect, failure
-from twisted.python.filepath import FilePath
-from twisted import plugin
-from twisted.python.util import spewer
-from twisted.python.compat import set
-from twisted.trial import runner, itrial, reporter
-
-
-# Yea, this is stupid. Leave it for for command-line compatibility for a
-# while, though.
-TBFORMAT_MAP = {
- 'plain': 'default',
- 'default': 'default',
- 'emacs': 'brief',
- 'brief': 'brief',
- 'cgitb': 'verbose',
- 'verbose': 'verbose'
- }
-
-
-def _parseLocalVariables(line):
- """
- Accepts a single line in Emacs local variable declaration format and
- returns a dict of all the variables {name: value}.
- Raises ValueError if 'line' is in the wrong format.
-
- See http://www.gnu.org/software/emacs/manual/html_node/File-Variables.html
- """
- paren = '-*-'
- start = line.find(paren) + len(paren)
- end = line.rfind(paren)
- if start == -1 or end == -1:
- raise ValueError("%r not a valid local variable declaration" % (line,))
- items = line[start:end].split(';')
- localVars = {}
- for item in items:
- if len(item.strip()) == 0:
- continue
- split = item.split(':')
- if len(split) != 2:
- raise ValueError("%r contains invalid declaration %r"
- % (line, item))
- localVars[split[0].strip()] = split[1].strip()
- return localVars
-
-
-def loadLocalVariables(filename):
- """
- Accepts a filename and attempts to load the Emacs variable declarations
- from that file, simulating what Emacs does.
-
- See http://www.gnu.org/software/emacs/manual/html_node/File-Variables.html
- """
- f = file(filename, "r")
- lines = [f.readline(), f.readline()]
- f.close()
- for line in lines:
- try:
- return _parseLocalVariables(line)
- except ValueError:
- pass
- return {}
-
-
-def getTestModules(filename):
- testCaseVar = loadLocalVariables(filename).get('test-case-name', None)
- if testCaseVar is None:
- return []
- return testCaseVar.split(',')
-
-
-def isTestFile(filename):
- """
- Returns true if 'filename' looks like a file containing unit tests.
- False otherwise. Doesn't care whether filename exists.
- """
- basename = os.path.basename(filename)
- return (basename.startswith('test_')
- and os.path.splitext(basename)[1] == ('.py'))
-
-
-def _reporterAction():
- return usage.CompleteList([p.longOpt for p in
- plugin.getPlugins(itrial.IReporter)])
-
-class Options(usage.Options, app.ReactorSelectionMixin):
- synopsis = """%s [options] [[file|package|module|TestCase|testmethod]...]
- """ % (os.path.basename(sys.argv[0]),)
-
- longdesc = ("trial loads and executes a suite of unit tests, obtained "
- "from modules, packages and files listed on the command line.")
-
- optFlags = [["help", "h"],
- ["rterrors", "e", "realtime errors, print out tracebacks as "
- "soon as they occur"],
- ["debug", "b", "Run tests in the Python debugger. Will load "
- "'.pdbrc' from current directory if it exists."],
- ["debug-stacktraces", "B", "Report Deferred creation and "
- "callback stack traces"],
- ["nopm", None, "don't automatically jump into debugger for "
- "postmorteming of exceptions"],
- ["dry-run", 'n', "do everything but run the tests"],
- ["force-gc", None, "Have Trial run gc.collect() before and "
- "after each test case."],
- ["profile", None, "Run tests under the Python profiler"],
- ["unclean-warnings", None,
- "Turn dirty reactor errors into warnings"],
- ["until-failure", "u", "Repeat test until it fails"],
- ["no-recurse", "N", "Don't recurse into packages"],
- ['help-reporters', None,
- "Help on available output plugins (reporters)"]
- ]
-
- optParameters = [
- ["logfile", "l", "test.log", "log file name"],
- ["random", "z", None,
- "Run tests in random order using the specified seed"],
- ['temp-directory', None, '_trial_temp',
- 'Path to use as working directory for tests.'],
- ['reporter', None, 'verbose',
- 'The reporter to use for this test run. See --help-reporters for '
- 'more info.']]
-
- compData = usage.Completions(
- optActions={"tbformat": usage.CompleteList(["plain", "emacs", "cgitb"]),
- "reporter": _reporterAction,
- "logfile": usage.CompleteFiles(descr="log file name"),
- "random": usage.Completer(descr="random seed")},
- extraActions=[usage.CompleteFiles(
- "*.py", descr="file | module | package | TestCase | testMethod",
- repeat=True)],
- )
-
- fallbackReporter = reporter.TreeReporter
- tracer = None
-
- def __init__(self):
- self['tests'] = set()
- usage.Options.__init__(self)
-
-
- def coverdir(self):
- """
- Return a L{FilePath} representing the directory into which coverage
- results should be written.
- """
- coverdir = 'coverage'
- result = FilePath(self['temp-directory']).child(coverdir)
- print "Setting coverage directory to %s." % (result.path,)
- return result
-
-
- def opt_coverage(self):
- """
- Generate coverage information in the coverage file in the
- directory specified by the temp-directory option.
- """
- import trace
- self.tracer = trace.Trace(count=1, trace=0)
- sys.settrace(self.tracer.globaltrace)
-
-
- def opt_testmodule(self, filename):
- """
- Filename to grep for test cases (-*- test-case-name)
- """
- # If the filename passed to this parameter looks like a test module
- # we just add that to the test suite.
- #
- # If not, we inspect it for an Emacs buffer local variable called
- # 'test-case-name'. If that variable is declared, we try to add its
- # value to the test suite as a module.
- #
- # This parameter allows automated processes (like Buildbot) to pass
- # a list of files to Trial with the general expectation of "these files,
- # whatever they are, will get tested"
- if not os.path.isfile(filename):
- sys.stderr.write("File %r doesn't exist\n" % (filename,))
- return
- filename = os.path.abspath(filename)
- if isTestFile(filename):
- self['tests'].add(filename)
- else:
- self['tests'].update(getTestModules(filename))
-
-
- def opt_spew(self):
- """
- Print an insanely verbose log of everything that happens. Useful
- when debugging freezes or locks in complex code.
- """
- sys.settrace(spewer)
-
-
- def opt_help_reporters(self):
- synopsis = ("Trial's output can be customized using plugins called "
- "Reporters. You can\nselect any of the following "
- "reporters using --reporter=<foo>\n")
- print synopsis
- for p in plugin.getPlugins(itrial.IReporter):
- print ' ', p.longOpt, '\t', p.description
- print
- sys.exit(0)
-
-
- def opt_disablegc(self):
- """
- Disable the garbage collector
- """
- gc.disable()
-
-
- def opt_tbformat(self, opt):
- """
- Specify the format to display tracebacks with. Valid formats are
- 'plain', 'emacs', and 'cgitb' which uses the nicely verbose stdlib
- cgitb.text function
- """
- try:
- self['tbformat'] = TBFORMAT_MAP[opt]
- except KeyError:
- raise usage.UsageError(
- "tbformat must be 'plain', 'emacs', or 'cgitb'.")
-
-
- def opt_recursionlimit(self, arg):
- """
- see sys.setrecursionlimit()
- """
- try:
- sys.setrecursionlimit(int(arg))
- except (TypeError, ValueError):
- raise usage.UsageError(
- "argument to recursionlimit must be an integer")
-
-
- def opt_random(self, option):
- try:
- self['random'] = long(option)
- except ValueError:
- raise usage.UsageError(
- "Argument to --random must be a positive integer")
- else:
- if self['random'] < 0:
- raise usage.UsageError(
- "Argument to --random must be a positive integer")
- elif self['random'] == 0:
- self['random'] = long(time.time() * 100)
-
-
- def opt_without_module(self, option):
- """
- Fake the lack of the specified modules, separated with commas.
- """
- for module in option.split(","):
- if module in sys.modules:
- warnings.warn("Module '%s' already imported, "
- "disabling anyway." % (module,),
- category=RuntimeWarning)
- sys.modules[module] = None
-
-
- def parseArgs(self, *args):
- self['tests'].update(args)
-
-
- def _loadReporterByName(self, name):
- for p in plugin.getPlugins(itrial.IReporter):
- qual = "%s.%s" % (p.module, p.klass)
- if p.longOpt == name:
- return reflect.namedAny(qual)
- raise usage.UsageError("Only pass names of Reporter plugins to "
- "--reporter. See --help-reporters for "
- "more info.")
-
-
- def postOptions(self):
- # Only load reporters now, as opposed to any earlier, to avoid letting
- # application-defined plugins muck up reactor selecting by importing
- # t.i.reactor and causing the default to be installed.
- self['reporter'] = self._loadReporterByName(self['reporter'])
-
- if 'tbformat' not in self:
- self['tbformat'] = 'default'
- if self['nopm']:
- if not self['debug']:
- raise usage.UsageError("you must specify --debug when using "
- "--nopm ")
- failure.DO_POST_MORTEM = False
-
-
-
-def _initialDebugSetup(config):
- # do this part of debug setup first for easy debugging of import failures
- if config['debug']:
- failure.startDebugMode()
- if config['debug'] or config['debug-stacktraces']:
- defer.setDebugging(True)
-
-
-
-def _getSuite(config):
- loader = _getLoader(config)
- recurse = not config['no-recurse']
- return loader.loadByNames(config['tests'], recurse)
-
-
-
-def _getLoader(config):
- loader = runner.TestLoader()
- if config['random']:
- randomer = random.Random()
- randomer.seed(config['random'])
- loader.sorter = lambda x : randomer.random()
- print 'Running tests shuffled with seed %d\n' % config['random']
- if not config['until-failure']:
- loader.suiteFactory = runner.DestructiveTestSuite
- return loader
-
-
-
-def _makeRunner(config):
- mode = None
- if config['debug']:
- mode = runner.TrialRunner.DEBUG
- if config['dry-run']:
- mode = runner.TrialRunner.DRY_RUN
- return runner.TrialRunner(config['reporter'],
- mode=mode,
- profile=config['profile'],
- logfile=config['logfile'],
- tracebackFormat=config['tbformat'],
- realTimeErrors=config['rterrors'],
- uncleanWarnings=config['unclean-warnings'],
- workingDirectory=config['temp-directory'],
- forceGarbageCollection=config['force-gc'])
-
-
-
-def run():
- if len(sys.argv) == 1:
- sys.argv.append("--help")
- config = Options()
- try:
- config.parseOptions()
- except usage.error, ue:
- raise SystemExit, "%s: %s" % (sys.argv[0], ue)
- _initialDebugSetup(config)
- trialRunner = _makeRunner(config)
- suite = _getSuite(config)
- if config['until-failure']:
- test_result = trialRunner.runUntilFailure(suite)
- else:
- test_result = trialRunner.run(suite)
- if config.tracer:
- sys.settrace(None)
- results = config.tracer.results()
- results.write_results(show_missing=1, summary=False,
- coverdir=config.coverdir().path)
- sys.exit(not test_result.wasSuccessful())
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/twistd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/twistd.py
deleted file mode 100755
index c2b53c71..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/scripts/twistd.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- test-case-name: twisted.test.test_twistd -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The Twisted Daemon: platform-independent interface.
-
-@author: Christopher Armstrong
-"""
-
-from twisted.application import app
-
-from twisted.python.runtime import platformType
-if platformType == "win32":
- from twisted.scripts._twistw import ServerOptions, \
- WindowsApplicationRunner as _SomeApplicationRunner
-else:
- from twisted.scripts._twistd_unix import ServerOptions, \
- UnixApplicationRunner as _SomeApplicationRunner
-
-
-def runApp(config):
- _SomeApplicationRunner(config).run()
-
-
-def run():
- app.run(runApp, ServerOptions)
-
-
-__all__ = ['run', 'runApp']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/__init__.py
deleted file mode 100755
index e38b149a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Spread: Spreadable (Distributed) Computing.
-
-Future Plans: PB, Jelly and Banana need to be optimized.
-
-@author: Glyph Lefkowitz
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py
deleted file mode 100755
index edae9c61..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/banana.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# -*- test-case-name: twisted.test.test_banana -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Banana -- s-exp based protocol.
-
-Future Plans: This module is almost entirely stable. The same caveat applies
-to it as applies to L{twisted.spread.jelly}, however. Read its future plans
-for more details.
-
-@author: Glyph Lefkowitz
-"""
-
-import copy, cStringIO, struct
-
-from twisted.internet import protocol
-from twisted.persisted import styles
-from twisted.python import log
-
-class BananaError(Exception):
- pass
-
-def int2b128(integer, stream):
- if integer == 0:
- stream(chr(0))
- return
- assert integer > 0, "can only encode positive integers"
- while integer:
- stream(chr(integer & 0x7f))
- integer = integer >> 7
-
-
-def b1282int(st):
- """
- Convert an integer represented as a base 128 string into an C{int} or
- C{long}.
-
- @param st: The integer encoded in a string.
- @type st: C{str}
-
- @return: The integer value extracted from the string.
- @rtype: C{int} or C{long}
- """
- e = 1
- i = 0
- for char in st:
- n = ord(char)
- i += (n * e)
- e <<= 7
- return i
-
-
-# delimiter characters.
-LIST = chr(0x80)
-INT = chr(0x81)
-STRING = chr(0x82)
-NEG = chr(0x83)
-FLOAT = chr(0x84)
-# "optional" -- these might be refused by a low-level implementation.
-LONGINT = chr(0x85)
-LONGNEG = chr(0x86)
-# really optional; this is is part of the 'pb' vocabulary
-VOCAB = chr(0x87)
-
-HIGH_BIT_SET = chr(0x80)
-
-def setPrefixLimit(limit):
- """
- Set the limit on the prefix length for all Banana connections
- established after this call.
-
- The prefix length limit determines how many bytes of prefix a banana
- decoder will allow before rejecting a potential object as too large.
-
- @type limit: C{int}
- @param limit: The number of bytes of prefix for banana to allow when
- decoding.
- """
- global _PREFIX_LIMIT
- _PREFIX_LIMIT = limit
-setPrefixLimit(64)
-
-SIZE_LIMIT = 640 * 1024 # 640k is all you'll ever need :-)
-
-class Banana(protocol.Protocol, styles.Ephemeral):
- knownDialects = ["pb", "none"]
-
- prefixLimit = None
- sizeLimit = SIZE_LIMIT
-
- def setPrefixLimit(self, limit):
- """
- Set the prefix limit for decoding done by this protocol instance.
-
- @see: L{setPrefixLimit}
- """
- self.prefixLimit = limit
- self._smallestLongInt = -2 ** (limit * 7) + 1
- self._smallestInt = -2 ** 31
- self._largestInt = 2 ** 31 - 1
- self._largestLongInt = 2 ** (limit * 7) - 1
-
-
- def connectionReady(self):
- """Surrogate for connectionMade
- Called after protocol negotiation.
- """
-
- def _selectDialect(self, dialect):
- self.currentDialect = dialect
- self.connectionReady()
-
- def callExpressionReceived(self, obj):
- if self.currentDialect:
- self.expressionReceived(obj)
- else:
- # this is the first message we've received
- if self.isClient:
- # if I'm a client I have to respond
- for serverVer in obj:
- if serverVer in self.knownDialects:
- self.sendEncoded(serverVer)
- self._selectDialect(serverVer)
- break
- else:
- # I can't speak any of those dialects.
- log.msg("The client doesn't speak any of the protocols "
- "offered by the server: disconnecting.")
- self.transport.loseConnection()
- else:
- if obj in self.knownDialects:
- self._selectDialect(obj)
- else:
- # the client just selected a protocol that I did not suggest.
- log.msg("The client selected a protocol the server didn't "
- "suggest and doesn't know: disconnecting.")
- self.transport.loseConnection()
-
-
- def connectionMade(self):
- self.setPrefixLimit(_PREFIX_LIMIT)
- self.currentDialect = None
- if not self.isClient:
- self.sendEncoded(self.knownDialects)
-
-
- def gotItem(self, item):
- l = self.listStack
- if l:
- l[-1][1].append(item)
- else:
- self.callExpressionReceived(item)
-
- buffer = ''
-
- def dataReceived(self, chunk):
- buffer = self.buffer + chunk
- listStack = self.listStack
- gotItem = self.gotItem
- while buffer:
- assert self.buffer != buffer, "This ain't right: %s %s" % (repr(self.buffer), repr(buffer))
- self.buffer = buffer
- pos = 0
- for ch in buffer:
- if ch >= HIGH_BIT_SET:
- break
- pos = pos + 1
- else:
- if pos > self.prefixLimit:
- raise BananaError("Security precaution: more than %d bytes of prefix" % (self.prefixLimit,))
- return
- num = buffer[:pos]
- typebyte = buffer[pos]
- rest = buffer[pos+1:]
- if len(num) > self.prefixLimit:
- raise BananaError("Security precaution: longer than %d bytes worth of prefix" % (self.prefixLimit,))
- if typebyte == LIST:
- num = b1282int(num)
- if num > SIZE_LIMIT:
- raise BananaError("Security precaution: List too long.")
- listStack.append((num, []))
- buffer = rest
- elif typebyte == STRING:
- num = b1282int(num)
- if num > SIZE_LIMIT:
- raise BananaError("Security precaution: String too long.")
- if len(rest) >= num:
- buffer = rest[num:]
- gotItem(rest[:num])
- else:
- return
- elif typebyte == INT:
- buffer = rest
- num = b1282int(num)
- gotItem(num)
- elif typebyte == LONGINT:
- buffer = rest
- num = b1282int(num)
- gotItem(num)
- elif typebyte == LONGNEG:
- buffer = rest
- num = b1282int(num)
- gotItem(-num)
- elif typebyte == NEG:
- buffer = rest
- num = -b1282int(num)
- gotItem(num)
- elif typebyte == VOCAB:
- buffer = rest
- num = b1282int(num)
- gotItem(self.incomingVocabulary[num])
- elif typebyte == FLOAT:
- if len(rest) >= 8:
- buffer = rest[8:]
- gotItem(struct.unpack("!d", rest[:8])[0])
- else:
- return
- else:
- raise NotImplementedError(("Invalid Type Byte %r" % (typebyte,)))
- while listStack and (len(listStack[-1][1]) == listStack[-1][0]):
- item = listStack.pop()[1]
- gotItem(item)
- self.buffer = ''
-
-
- def expressionReceived(self, lst):
- """Called when an expression (list, string, or int) is received.
- """
- raise NotImplementedError()
-
-
- outgoingVocabulary = {
- # Jelly Data Types
- 'None' : 1,
- 'class' : 2,
- 'dereference' : 3,
- 'reference' : 4,
- 'dictionary' : 5,
- 'function' : 6,
- 'instance' : 7,
- 'list' : 8,
- 'module' : 9,
- 'persistent' : 10,
- 'tuple' : 11,
- 'unpersistable' : 12,
-
- # PB Data Types
- 'copy' : 13,
- 'cache' : 14,
- 'cached' : 15,
- 'remote' : 16,
- 'local' : 17,
- 'lcache' : 18,
-
- # PB Protocol Messages
- 'version' : 19,
- 'login' : 20,
- 'password' : 21,
- 'challenge' : 22,
- 'logged_in' : 23,
- 'not_logged_in' : 24,
- 'cachemessage' : 25,
- 'message' : 26,
- 'answer' : 27,
- 'error' : 28,
- 'decref' : 29,
- 'decache' : 30,
- 'uncache' : 31,
- }
-
- incomingVocabulary = {}
- for k, v in outgoingVocabulary.items():
- incomingVocabulary[v] = k
-
- def __init__(self, isClient=1):
- self.listStack = []
- self.outgoingSymbols = copy.copy(self.outgoingVocabulary)
- self.outgoingSymbolCount = 0
- self.isClient = isClient
-
- def sendEncoded(self, obj):
- io = cStringIO.StringIO()
- self._encode(obj, io.write)
- value = io.getvalue()
- self.transport.write(value)
-
- def _encode(self, obj, write):
- if isinstance(obj, (list, tuple)):
- if len(obj) > SIZE_LIMIT:
- raise BananaError(
- "list/tuple is too long to send (%d)" % (len(obj),))
- int2b128(len(obj), write)
- write(LIST)
- for elem in obj:
- self._encode(elem, write)
- elif isinstance(obj, (int, long)):
- if obj < self._smallestLongInt or obj > self._largestLongInt:
- raise BananaError(
- "int/long is too large to send (%d)" % (obj,))
- if obj < self._smallestInt:
- int2b128(-obj, write)
- write(LONGNEG)
- elif obj < 0:
- int2b128(-obj, write)
- write(NEG)
- elif obj <= self._largestInt:
- int2b128(obj, write)
- write(INT)
- else:
- int2b128(obj, write)
- write(LONGINT)
- elif isinstance(obj, float):
- write(FLOAT)
- write(struct.pack("!d", obj))
- elif isinstance(obj, str):
- # TODO: an API for extending banana...
- if self.currentDialect == "pb" and obj in self.outgoingSymbols:
- symbolID = self.outgoingSymbols[obj]
- int2b128(symbolID, write)
- write(VOCAB)
- else:
- if len(obj) > SIZE_LIMIT:
- raise BananaError(
- "string is too long to send (%d)" % (len(obj),))
- int2b128(len(obj), write)
- write(STRING)
- write(obj)
- else:
- raise BananaError("could not send object: %r" % (obj,))
-
-
-# For use from the interactive interpreter
-_i = Banana()
-_i.connectionMade()
-_i._selectDialect("none")
-
-
-def encode(lst):
- """Encode a list s-expression."""
- io = cStringIO.StringIO()
- _i.transport = io
- _i.sendEncoded(lst)
- return io.getvalue()
-
-
-def decode(st):
- """
- Decode a banana-encoded string.
- """
- l = []
- _i.expressionReceived = l.append
- try:
- _i.dataReceived(st)
- finally:
- _i.buffer = ''
- del _i.expressionReceived
- return l[0]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/flavors.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/flavors.py
deleted file mode 100755
index 61d6b802..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/flavors.py
+++ /dev/null
@@ -1,590 +0,0 @@
-# -*- test-case-name: twisted.test.test_pb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module represents flavors of remotely acessible objects.
-
-Currently this is only objects accessible through Perspective Broker, but will
-hopefully encompass all forms of remote access which can emulate subsets of PB
-(such as XMLRPC or SOAP).
-
-Future Plans: Optimization. Exploitation of new-style object model.
-Optimizations to this module should not affect external-use semantics at all,
-but may have a small impact on users who subclass and override methods.
-
-@author: Glyph Lefkowitz
-"""
-
-# NOTE: this module should NOT import pb; it is supposed to be a module which
-# abstractly defines remotely accessible types. Many of these types expect to
-# be serialized by Jelly, but they ought to be accessible through other
-# mechanisms (like XMLRPC)
-
-# system imports
-import sys
-from zope.interface import implements, Interface
-
-# twisted imports
-from twisted.python import log, reflect
-
-# sibling imports
-from jelly import setUnjellyableForClass, setUnjellyableForClassTree, setUnjellyableFactoryForClass, unjellyableRegistry
-from jelly import Jellyable, Unjellyable, _newDummyLike
-from jelly import setInstanceState, getInstanceState
-
-# compatibility
-setCopierForClass = setUnjellyableForClass
-setCopierForClassTree = setUnjellyableForClassTree
-setFactoryForClass = setUnjellyableFactoryForClass
-copyTags = unjellyableRegistry
-
-copy_atom = "copy"
-cache_atom = "cache"
-cached_atom = "cached"
-remote_atom = "remote"
-
-
-class NoSuchMethod(AttributeError):
- """Raised if there is no such remote method"""
-
-
-class IPBRoot(Interface):
- """Factory for root Referenceable objects for PB servers."""
-
- def rootObject(broker):
- """Return root Referenceable for broker."""
-
-
-class Serializable(Jellyable):
- """An object that can be passed remotely.
-
- I am a style of object which can be serialized by Perspective
- Broker. Objects which wish to be referenceable or copied remotely
- have to subclass Serializable. However, clients of Perspective
- Broker will probably not want to directly subclass Serializable; the
- Flavors of transferable objects are listed below.
-
- What it means to be \"Serializable\" is that an object can be
- passed to or returned from a remote method. Certain basic types
- (dictionaries, lists, tuples, numbers, strings) are serializable by
- default; however, classes need to choose a specific serialization
- style: L{Referenceable}, L{Viewable}, L{Copyable} or L{Cacheable}.
-
- You may also pass C{[lists, dictionaries, tuples]} of L{Serializable}
- instances to or return them from remote methods, as many levels deep
- as you like.
- """
-
- def processUniqueID(self):
- """Return an ID which uniquely represents this object for this process.
-
- By default, this uses the 'id' builtin, but can be overridden to
- indicate that two values are identity-equivalent (such as proxies
- for the same object).
- """
-
- return id(self)
-
-class Referenceable(Serializable):
- perspective = None
- """I am an object sent remotely as a direct reference.
-
- When one of my subclasses is sent as an argument to or returned
- from a remote method call, I will be serialized by default as a
- direct reference.
-
- This means that the peer will be able to call methods on me;
- a method call xxx() from my peer will be resolved to methods
- of the name remote_xxx.
- """
-
- def remoteMessageReceived(self, broker, message, args, kw):
- """A remote message has been received. Dispatch it appropriately.
-
- The default implementation is to dispatch to a method called
- 'remote_messagename' and call it with the same arguments.
- """
- args = broker.unserialize(args)
- kw = broker.unserialize(kw)
- method = getattr(self, "remote_%s" % message, None)
- if method is None:
- raise NoSuchMethod("No such method: remote_%s" % (message,))
- try:
- state = method(*args, **kw)
- except TypeError:
- log.msg("%s didn't accept %s and %s" % (method, args, kw))
- raise
- return broker.serialize(state, self.perspective)
-
- def jellyFor(self, jellier):
- """(internal)
-
- Return a tuple which will be used as the s-expression to
- serialize this to a peer.
- """
-
- return ["remote", jellier.invoker.registerReference(self)]
-
-
-class Root(Referenceable):
- """I provide a root object to L{pb.Broker}s for a L{pb.BrokerFactory}.
-
- When a L{pb.BrokerFactory} produces a L{pb.Broker}, it supplies that
- L{pb.Broker} with an object named \"root\". That object is obtained
- by calling my rootObject method.
- """
-
- implements(IPBRoot)
-
- def rootObject(self, broker):
- """A L{pb.BrokerFactory} is requesting to publish me as a root object.
-
- When a L{pb.BrokerFactory} is sending me as the root object, this
- method will be invoked to allow per-broker versions of an
- object. By default I return myself.
- """
- return self
-
-
-class ViewPoint(Referenceable):
- """
- I act as an indirect reference to an object accessed through a
- L{pb.Perspective}.
-
- Simply put, I combine an object with a perspective so that when a
- peer calls methods on the object I refer to, the method will be
- invoked with that perspective as a first argument, so that it can
- know who is calling it.
-
- While L{Viewable} objects will be converted to ViewPoints by default
- when they are returned from or sent as arguments to a remote
- method, any object may be manually proxied as well. (XXX: Now that
- this class is no longer named C{Proxy}, this is the only occourance
- of the term 'proxied' in this docstring, and may be unclear.)
-
- This can be useful when dealing with L{pb.Perspective}s, L{Copyable}s,
- and L{Cacheable}s. It is legal to implement a method as such on
- a perspective::
-
- | def perspective_getViewPointForOther(self, name):
- | defr = self.service.getPerspectiveRequest(name)
- | defr.addCallbacks(lambda x, self=self: ViewPoint(self, x), log.msg)
- | return defr
-
- This will allow you to have references to Perspective objects in two
- different ways. One is through the initial 'attach' call -- each
- peer will have a L{pb.RemoteReference} to their perspective directly. The
- other is through this method; each peer can get a L{pb.RemoteReference} to
- all other perspectives in the service; but that L{pb.RemoteReference} will
- be to a L{ViewPoint}, not directly to the object.
-
- The practical offshoot of this is that you can implement 2 varieties
- of remotely callable methods on this Perspective; view_xxx and
- C{perspective_xxx}. C{view_xxx} methods will follow the rules for
- ViewPoint methods (see ViewPoint.L{remoteMessageReceived}), and
- C{perspective_xxx} methods will follow the rules for Perspective
- methods.
- """
-
- def __init__(self, perspective, object):
- """Initialize me with a Perspective and an Object.
- """
- self.perspective = perspective
- self.object = object
-
- def processUniqueID(self):
- """Return an ID unique to a proxy for this perspective+object combination.
- """
- return (id(self.perspective), id(self.object))
-
- def remoteMessageReceived(self, broker, message, args, kw):
- """A remote message has been received. Dispatch it appropriately.
-
- The default implementation is to dispatch to a method called
- 'C{view_messagename}' to my Object and call it on my object with
- the same arguments, modified by inserting my Perspective as
- the first argument.
- """
- args = broker.unserialize(args, self.perspective)
- kw = broker.unserialize(kw, self.perspective)
- method = getattr(self.object, "view_%s" % message)
- try:
- state = method(*(self.perspective,)+args, **kw)
- except TypeError:
- log.msg("%s didn't accept %s and %s" % (method, args, kw))
- raise
- rv = broker.serialize(state, self.perspective, method, args, kw)
- return rv
-
-
-class Viewable(Serializable):
- """I will be converted to a L{ViewPoint} when passed to or returned from a remote method.
-
- The beginning of a peer's interaction with a PB Service is always
- through a perspective. However, if a C{perspective_xxx} method returns
- a Viewable, it will be serialized to the peer as a response to that
- method.
- """
-
- def jellyFor(self, jellier):
- """Serialize a L{ViewPoint} for me and the perspective of the given broker.
- """
- return ViewPoint(jellier.invoker.serializingPerspective, self).jellyFor(jellier)
-
-
-
-class Copyable(Serializable):
- """Subclass me to get copied each time you are returned from or passed to a remote method.
-
- When I am returned from or passed to a remote method call, I will be
- converted into data via a set of callbacks (see my methods for more
- info). That data will then be serialized using Jelly, and sent to
- the peer.
-
- The peer will then look up the type to represent this with; see
- L{RemoteCopy} for details.
- """
-
- def getStateToCopy(self):
- """Gather state to send when I am serialized for a peer.
-
- I will default to returning self.__dict__. Override this to
- customize this behavior.
- """
-
- return self.__dict__
-
- def getStateToCopyFor(self, perspective):
- """
- Gather state to send when I am serialized for a particular
- perspective.
-
- I will default to calling L{getStateToCopy}. Override this to
- customize this behavior.
- """
-
- return self.getStateToCopy()
-
- def getTypeToCopy(self):
- """Determine what type tag to send for me.
-
- By default, send the string representation of my class
- (package.module.Class); normally this is adequate, but
- you may override this to change it.
- """
-
- return reflect.qual(self.__class__)
-
- def getTypeToCopyFor(self, perspective):
- """Determine what type tag to send for me.
-
- By default, defer to self.L{getTypeToCopy}() normally this is
- adequate, but you may override this to change it.
- """
-
- return self.getTypeToCopy()
-
- def jellyFor(self, jellier):
- """Assemble type tag and state to copy for this broker.
-
- This will call L{getTypeToCopyFor} and L{getStateToCopy}, and
- return an appropriate s-expression to represent me.
- """
-
- if jellier.invoker is None:
- return getInstanceState(self, jellier)
- p = jellier.invoker.serializingPerspective
- t = self.getTypeToCopyFor(p)
- state = self.getStateToCopyFor(p)
- sxp = jellier.prepare(self)
- sxp.extend([t, jellier.jelly(state)])
- return jellier.preserve(self, sxp)
-
-
-class Cacheable(Copyable):
- """A cached instance.
-
- This means that it's copied; but there is some logic to make sure
- that it's only copied once. Additionally, when state is retrieved,
- it is passed a "proto-reference" to the state as it will exist on
- the client.
-
- XXX: The documentation for this class needs work, but it's the most
- complex part of PB and it is inherently difficult to explain.
- """
-
- def getStateToCacheAndObserveFor(self, perspective, observer):
- """
- Get state to cache on the client and client-cache reference
- to observe locally.
-
- This is similiar to getStateToCopyFor, but it additionally
- passes in a reference to the client-side RemoteCache instance
- that will be created when it is unserialized. This allows
- Cacheable instances to keep their RemoteCaches up to date when
- they change, such that no changes can occur between the point
- at which the state is initially copied and the client receives
- it that are not propogated.
- """
-
- return self.getStateToCopyFor(perspective)
-
- def jellyFor(self, jellier):
- """Return an appropriate tuple to serialize me.
-
- Depending on whether this broker has cached me or not, this may
- return either a full state or a reference to an existing cache.
- """
- if jellier.invoker is None:
- return getInstanceState(self, jellier)
- luid = jellier.invoker.cachedRemotelyAs(self, 1)
- if luid is None:
- luid = jellier.invoker.cacheRemotely(self)
- p = jellier.invoker.serializingPerspective
- type_ = self.getTypeToCopyFor(p)
- observer = RemoteCacheObserver(jellier.invoker, self, p)
- state = self.getStateToCacheAndObserveFor(p, observer)
- l = jellier.prepare(self)
- jstate = jellier.jelly(state)
- l.extend([type_, luid, jstate])
- return jellier.preserve(self, l)
- else:
- return cached_atom, luid
-
- def stoppedObserving(self, perspective, observer):
- """This method is called when a client has stopped observing me.
-
- The 'observer' argument is the same as that passed in to
- getStateToCacheAndObserveFor.
- """
-
-
-
-class RemoteCopy(Unjellyable):
- """I am a remote copy of a Copyable object.
-
- When the state from a L{Copyable} object is received, an instance will
- be created based on the copy tags table (see setUnjellyableForClass) and
- sent the L{setCopyableState} message. I provide a reasonable default
- implementation of that message; subclass me if you wish to serve as
- a copier for remote data.
-
- NOTE: copiers are invoked with no arguments. Do not implement a
- constructor which requires args in a subclass of L{RemoteCopy}!
- """
-
- def setCopyableState(self, state):
- """I will be invoked with the state to copy locally.
-
- 'state' is the data returned from the remote object's
- 'getStateToCopyFor' method, which will often be the remote
- object's dictionary (or a filtered approximation of it depending
- on my peer's perspective).
- """
-
- self.__dict__ = state
-
- def unjellyFor(self, unjellier, jellyList):
- if unjellier.invoker is None:
- return setInstanceState(self, unjellier, jellyList)
- self.setCopyableState(unjellier.unjelly(jellyList[1]))
- return self
-
-
-
-class RemoteCache(RemoteCopy, Serializable):
- """A cache is a local representation of a remote L{Cacheable} object.
-
- This represents the last known state of this object. It may
- also have methods invoked on it -- in order to update caches,
- the cached class generates a L{pb.RemoteReference} to this object as
- it is originally sent.
-
- Much like copy, I will be invoked with no arguments. Do not
- implement a constructor that requires arguments in one of my
- subclasses.
- """
-
- def remoteMessageReceived(self, broker, message, args, kw):
- """A remote message has been received. Dispatch it appropriately.
-
- The default implementation is to dispatch to a method called
- 'C{observe_messagename}' and call it on my with the same arguments.
- """
-
- args = broker.unserialize(args)
- kw = broker.unserialize(kw)
- method = getattr(self, "observe_%s" % message)
- try:
- state = method(*args, **kw)
- except TypeError:
- log.msg("%s didn't accept %s and %s" % (method, args, kw))
- raise
- return broker.serialize(state, None, method, args, kw)
-
- def jellyFor(self, jellier):
- """serialize me (only for the broker I'm for) as the original cached reference
- """
- if jellier.invoker is None:
- return getInstanceState(self, jellier)
- assert jellier.invoker is self.broker, "You cannot exchange cached proxies between brokers."
- return 'lcache', self.luid
-
-
- def unjellyFor(self, unjellier, jellyList):
- if unjellier.invoker is None:
- return setInstanceState(self, unjellier, jellyList)
- self.broker = unjellier.invoker
- self.luid = jellyList[1]
- cProxy = _newDummyLike(self)
- # XXX questionable whether this was a good design idea...
- init = getattr(cProxy, "__init__", None)
- if init:
- init()
- unjellier.invoker.cacheLocally(jellyList[1], self)
- cProxy.setCopyableState(unjellier.unjelly(jellyList[2]))
- # Might have changed due to setCopyableState method; we'll assume that
- # it's bad form to do so afterwards.
- self.__dict__ = cProxy.__dict__
- # chomp, chomp -- some existing code uses "self.__dict__ =", some uses
- # "__dict__.update". This is here in order to handle both cases.
- self.broker = unjellier.invoker
- self.luid = jellyList[1]
- return cProxy
-
-## def __really_del__(self):
-## """Final finalization call, made after all remote references have been lost.
-## """
-
- def __cmp__(self, other):
- """Compare me [to another RemoteCache.
- """
- if isinstance(other, self.__class__):
- return cmp(id(self.__dict__), id(other.__dict__))
- else:
- return cmp(id(self.__dict__), other)
-
- def __hash__(self):
- """Hash me.
- """
- return int(id(self.__dict__) % sys.maxint)
-
- broker = None
- luid = None
-
- def __del__(self):
- """Do distributed reference counting on finalize.
- """
- try:
- # log.msg( ' --- decache: %s %s' % (self, self.luid) )
- if self.broker:
- self.broker.decCacheRef(self.luid)
- except:
- log.deferr()
-
-def unjellyCached(unjellier, unjellyList):
- luid = unjellyList[1]
- cNotProxy = unjellier.invoker.cachedLocallyAs(luid)
- cProxy = _newDummyLike(cNotProxy)
- return cProxy
-
-setUnjellyableForClass("cached", unjellyCached)
-
-def unjellyLCache(unjellier, unjellyList):
- luid = unjellyList[1]
- obj = unjellier.invoker.remotelyCachedForLUID(luid)
- return obj
-
-setUnjellyableForClass("lcache", unjellyLCache)
-
-def unjellyLocal(unjellier, unjellyList):
- obj = unjellier.invoker.localObjectForID(unjellyList[1])
- return obj
-
-setUnjellyableForClass("local", unjellyLocal)
-
-class RemoteCacheMethod:
- """A method on a reference to a L{RemoteCache}.
- """
-
- def __init__(self, name, broker, cached, perspective):
- """(internal) initialize.
- """
- self.name = name
- self.broker = broker
- self.perspective = perspective
- self.cached = cached
-
- def __cmp__(self, other):
- return cmp((self.name, self.broker, self.perspective, self.cached), other)
-
- def __hash__(self):
- return hash((self.name, self.broker, self.perspective, self.cached))
-
- def __call__(self, *args, **kw):
- """(internal) action method.
- """
- cacheID = self.broker.cachedRemotelyAs(self.cached)
- if cacheID is None:
- from pb import ProtocolError
- raise ProtocolError("You can't call a cached method when the object hasn't been given to the peer yet.")
- return self.broker._sendMessage('cache', self.perspective, cacheID, self.name, args, kw)
-
-class RemoteCacheObserver:
- """I am a reverse-reference to the peer's L{RemoteCache}.
-
- I am generated automatically when a cache is serialized. I
- represent a reference to the client's L{RemoteCache} object that
- will represent a particular L{Cacheable}; I am the additional
- object passed to getStateToCacheAndObserveFor.
- """
-
- def __init__(self, broker, cached, perspective):
- """(internal) Initialize me.
-
- @param broker: a L{pb.Broker} instance.
-
- @param cached: a L{Cacheable} instance that this L{RemoteCacheObserver}
- corresponds to.
-
- @param perspective: a reference to the perspective who is observing this.
- """
-
- self.broker = broker
- self.cached = cached
- self.perspective = perspective
-
- def __repr__(self):
- return "<RemoteCacheObserver(%s, %s, %s) at %s>" % (
- self.broker, self.cached, self.perspective, id(self))
-
- def __hash__(self):
- """Generate a hash unique to all L{RemoteCacheObserver}s for this broker/perspective/cached triplet
- """
-
- return ( (hash(self.broker) % 2**10)
- + (hash(self.perspective) % 2**10)
- + (hash(self.cached) % 2**10))
-
- def __cmp__(self, other):
- """Compare me to another L{RemoteCacheObserver}.
- """
-
- return cmp((self.broker, self.perspective, self.cached), other)
-
- def callRemote(self, _name, *args, **kw):
- """(internal) action method.
- """
- cacheID = self.broker.cachedRemotelyAs(self.cached)
- if cacheID is None:
- from pb import ProtocolError
- raise ProtocolError("You can't call a cached method when the "
- "object hasn't been given to the peer yet.")
- return self.broker._sendMessage('cache', self.perspective, cacheID,
- _name, args, kw)
-
- def remoteMethod(self, key):
- """Get a L{pb.RemoteMethod} for this key.
- """
- return RemoteCacheMethod(key, self.broker, self.cached, self.perspective)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/interfaces.py
deleted file mode 100755
index 6d48d002..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/interfaces.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""
-Twisted Spread Interfaces.
-
-This module is unused so far. It's also undecided whether this module
-will remain monolithic.
-"""
-
-from zope.interface import Interface
-
-class IJellyable(Interface):
- def jellyFor(jellier):
- """
- Jelly myself for jellier.
- """
-
-class IUnjellyable(Interface):
- def unjellyFor(jellier, jellyList):
- """
- Unjelly myself for the jellier.
-
- @param jellier: A stateful object which exists for the lifetime of a
- single call to L{unjelly}.
-
- @param jellyList: The C{list} which represents the jellied state of the
- object to be unjellied.
-
- @return: The object which results from unjellying.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/jelly.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/jelly.py
deleted file mode 100755
index 18795304..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/jelly.py
+++ /dev/null
@@ -1,1151 +0,0 @@
-# -*- test-case-name: twisted.test.test_jelly -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-S-expression-based persistence of python objects.
-
-It does something very much like L{Pickle<pickle>}; however, pickle's main goal
-seems to be efficiency (both in space and time); jelly's main goals are
-security, human readability, and portability to other environments.
-
-This is how Jelly converts various objects to s-expressions.
-
-Boolean::
- True --> ['boolean', 'true']
-
-Integer::
- 1 --> 1
-
-List::
- [1, 2] --> ['list', 1, 2]
-
-String::
- \"hello\" --> \"hello\"
-
-Float::
- 2.3 --> 2.3
-
-Dictionary::
- {'a': 1, 'b': 'c'} --> ['dictionary', ['b', 'c'], ['a', 1]]
-
-Module::
- UserString --> ['module', 'UserString']
-
-Class::
- UserString.UserString --> ['class', ['module', 'UserString'], 'UserString']
-
-Function::
- string.join --> ['function', 'join', ['module', 'string']]
-
-Instance: s is an instance of UserString.UserString, with a __dict__
-{'data': 'hello'}::
- [\"UserString.UserString\", ['dictionary', ['data', 'hello']]]
-
-Class Method: UserString.UserString.center::
- ['method', 'center', ['None'], ['class', ['module', 'UserString'],
- 'UserString']]
-
-Instance Method: s.center, where s is an instance of UserString.UserString::
- ['method', 'center', ['instance', ['reference', 1, ['class',
- ['module', 'UserString'], 'UserString']], ['dictionary', ['data', 'd']]],
- ['dereference', 1]]
-
-The C{set} builtin and the C{sets.Set} class are serialized to the same
-thing, and unserialized to C{set} if available, else to C{sets.Set}. It means
-that there's a possibility of type switching in the serialization process. The
-solution is to always use C{set} if possible, and only use C{sets.Set} under
-Python 2.3; this can be accomplished by using L{twisted.python.compat.set}.
-
-The same rule applies for C{frozenset} and C{sets.ImmutableSet}.
-
-@author: Glyph Lefkowitz
-"""
-
-# System Imports
-import pickle
-import types
-import warnings
-from types import StringType
-from types import UnicodeType
-from types import IntType
-from types import TupleType
-from types import ListType
-from types import LongType
-from types import FloatType
-from types import FunctionType
-from types import MethodType
-from types import ModuleType
-from types import DictionaryType
-from types import InstanceType
-from types import NoneType
-from types import ClassType
-import copy
-
-import datetime
-from types import BooleanType
-
-try:
- import decimal
-except ImportError:
- decimal = None
-
-try:
- _set = set
-except NameError:
- _set = None
-
-try:
- # Filter out deprecation warning for Python >= 2.6
- warnings.filterwarnings("ignore", category=DeprecationWarning,
- message="the sets module is deprecated", append=True)
- import sets as _sets
-finally:
- warnings.filters.pop()
-
-
-from zope.interface import implements
-
-# Twisted Imports
-from twisted.python.reflect import namedObject, qual
-from twisted.persisted.crefutil import NotKnown, _Tuple, _InstanceMethod
-from twisted.persisted.crefutil import _DictKeyAndValue, _Dereference
-from twisted.persisted.crefutil import _Container
-from twisted.python.compat import reduce
-
-from twisted.spread.interfaces import IJellyable, IUnjellyable
-
-DictTypes = (DictionaryType,)
-
-None_atom = "None" # N
-# code
-class_atom = "class" # c
-module_atom = "module" # m
-function_atom = "function" # f
-
-# references
-dereference_atom = 'dereference' # D
-persistent_atom = 'persistent' # p
-reference_atom = 'reference' # r
-
-# mutable collections
-dictionary_atom = "dictionary" # d
-list_atom = 'list' # l
-set_atom = 'set'
-
-# immutable collections
-# (assignment to __dict__ and __class__ still might go away!)
-tuple_atom = "tuple" # t
-instance_atom = 'instance' # i
-frozenset_atom = 'frozenset'
-
-
-# errors
-unpersistable_atom = "unpersistable"# u
-unjellyableRegistry = {}
-unjellyableFactoryRegistry = {}
-
-_NO_STATE = object()
-
-def _newInstance(cls, state=_NO_STATE):
- """
- Make a new instance of a class without calling its __init__ method.
- Supports both new- and old-style classes.
-
- @param state: A C{dict} used to update C{inst.__dict__} or C{_NO_STATE}
- to skip this part of initialization.
-
- @return: A new instance of C{cls}.
- """
- if not isinstance(cls, types.ClassType):
- # new-style
- inst = cls.__new__(cls)
-
- if state is not _NO_STATE:
- inst.__dict__.update(state) # Copy 'instance' behaviour
- else:
- if state is not _NO_STATE:
- inst = InstanceType(cls, state)
- else:
- inst = InstanceType(cls)
- return inst
-
-
-
-def _maybeClass(classnamep):
- try:
- object
- except NameError:
- isObject = 0
- else:
- isObject = isinstance(classnamep, type)
- if isinstance(classnamep, ClassType) or isObject:
- return qual(classnamep)
- return classnamep
-
-
-
-def setUnjellyableForClass(classname, unjellyable):
- """
- Set which local class will represent a remote type.
-
- If you have written a Copyable class that you expect your client to be
- receiving, write a local "copy" class to represent it, then call::
-
- jellier.setUnjellyableForClass('module.package.Class', MyCopier).
-
- Call this at the module level immediately after its class
- definition. MyCopier should be a subclass of RemoteCopy.
-
- The classname may be a special tag returned by
- 'Copyable.getTypeToCopyFor' rather than an actual classname.
-
- This call is also for cached classes, since there will be no
- overlap. The rules are the same.
- """
-
- global unjellyableRegistry
- classname = _maybeClass(classname)
- unjellyableRegistry[classname] = unjellyable
- globalSecurity.allowTypes(classname)
-
-
-
-def setUnjellyableFactoryForClass(classname, copyFactory):
- """
- Set the factory to construct a remote instance of a type::
-
- jellier.setUnjellyableFactoryForClass('module.package.Class', MyFactory)
-
- Call this at the module level immediately after its class definition.
- C{copyFactory} should return an instance or subclass of
- L{RemoteCopy<pb.RemoteCopy>}.
-
- Similar to L{setUnjellyableForClass} except it uses a factory instead
- of creating an instance.
- """
-
- global unjellyableFactoryRegistry
- classname = _maybeClass(classname)
- unjellyableFactoryRegistry[classname] = copyFactory
- globalSecurity.allowTypes(classname)
-
-
-
-def setUnjellyableForClassTree(module, baseClass, prefix=None):
- """
- Set all classes in a module derived from C{baseClass} as copiers for
- a corresponding remote class.
-
- When you have a heirarchy of Copyable (or Cacheable) classes on one
- side, and a mirror structure of Copied (or RemoteCache) classes on the
- other, use this to setUnjellyableForClass all your Copieds for the
- Copyables.
-
- Each copyTag (the \"classname\" argument to getTypeToCopyFor, and
- what the Copyable's getTypeToCopyFor returns) is formed from
- adding a prefix to the Copied's class name. The prefix defaults
- to module.__name__. If you wish the copy tag to consist of solely
- the classname, pass the empty string \'\'.
-
- @param module: a module object from which to pull the Copied classes.
- (passing sys.modules[__name__] might be useful)
-
- @param baseClass: the base class from which all your Copied classes derive.
-
- @param prefix: the string prefixed to classnames to form the
- unjellyableRegistry.
- """
- if prefix is None:
- prefix = module.__name__
-
- if prefix:
- prefix = "%s." % prefix
-
- for i in dir(module):
- i_ = getattr(module, i)
- if type(i_) == types.ClassType:
- if issubclass(i_, baseClass):
- setUnjellyableForClass('%s%s' % (prefix, i), i_)
-
-
-
-def getInstanceState(inst, jellier):
- """
- Utility method to default to 'normal' state rules in serialization.
- """
- if hasattr(inst, "__getstate__"):
- state = inst.__getstate__()
- else:
- state = inst.__dict__
- sxp = jellier.prepare(inst)
- sxp.extend([qual(inst.__class__), jellier.jelly(state)])
- return jellier.preserve(inst, sxp)
-
-
-
-def setInstanceState(inst, unjellier, jellyList):
- """
- Utility method to default to 'normal' state rules in unserialization.
- """
- state = unjellier.unjelly(jellyList[1])
- if hasattr(inst, "__setstate__"):
- inst.__setstate__(state)
- else:
- inst.__dict__ = state
- return inst
-
-
-
-class Unpersistable:
- """
- This is an instance of a class that comes back when something couldn't be
- unpersisted.
- """
-
- def __init__(self, reason):
- """
- Initialize an unpersistable object with a descriptive C{reason} string.
- """
- self.reason = reason
-
-
- def __repr__(self):
- return "Unpersistable(%s)" % repr(self.reason)
-
-
-
-class Jellyable:
- """
- Inherit from me to Jelly yourself directly with the `getStateFor'
- convenience method.
- """
- implements(IJellyable)
-
- def getStateFor(self, jellier):
- return self.__dict__
-
-
- def jellyFor(self, jellier):
- """
- @see: L{twisted.spread.interfaces.IJellyable.jellyFor}
- """
- sxp = jellier.prepare(self)
- sxp.extend([
- qual(self.__class__),
- jellier.jelly(self.getStateFor(jellier))])
- return jellier.preserve(self, sxp)
-
-
-
-class Unjellyable:
- """
- Inherit from me to Unjelly yourself directly with the
- C{setStateFor} convenience method.
- """
- implements(IUnjellyable)
-
- def setStateFor(self, unjellier, state):
- self.__dict__ = state
-
-
- def unjellyFor(self, unjellier, jellyList):
- """
- Perform the inverse operation of L{Jellyable.jellyFor}.
-
- @see: L{twisted.spread.interfaces.IUnjellyable.unjellyFor}
- """
- state = unjellier.unjelly(jellyList[1])
- self.setStateFor(unjellier, state)
- return self
-
-
-
-class _Jellier:
- """
- (Internal) This class manages state for a call to jelly()
- """
-
- def __init__(self, taster, persistentStore, invoker):
- """
- Initialize.
- """
- self.taster = taster
- # `preserved' is a dict of previously seen instances.
- self.preserved = {}
- # `cooked' is a dict of previously backreferenced instances to their
- # `ref' lists.
- self.cooked = {}
- self.cooker = {}
- self._ref_id = 1
- self.persistentStore = persistentStore
- self.invoker = invoker
-
-
- def _cook(self, object):
- """
- (internal) Backreference an object.
-
- Notes on this method for the hapless future maintainer: If I've already
- gone through the prepare/preserve cycle on the specified object (it is
- being referenced after the serializer is \"done with\" it, e.g. this
- reference is NOT circular), the copy-in-place of aList is relevant,
- since the list being modified is the actual, pre-existing jelly
- expression that was returned for that object. If not, it's technically
- superfluous, since the value in self.preserved didn't need to be set,
- but the invariant that self.preserved[id(object)] is a list is
- convenient because that means we don't have to test and create it or
- not create it here, creating fewer code-paths. that's why
- self.preserved is always set to a list.
-
- Sorry that this code is so hard to follow, but Python objects are
- tricky to persist correctly. -glyph
- """
- aList = self.preserved[id(object)]
- newList = copy.copy(aList)
- # make a new reference ID
- refid = self._ref_id
- self._ref_id = self._ref_id + 1
- # replace the old list in-place, so that we don't have to track the
- # previous reference to it.
- aList[:] = [reference_atom, refid, newList]
- self.cooked[id(object)] = [dereference_atom, refid]
- return aList
-
-
- def prepare(self, object):
- """
- (internal) Create a list for persisting an object to. This will allow
- backreferences to be made internal to the object. (circular
- references).
-
- The reason this needs to happen is that we don't generate an ID for
- every object, so we won't necessarily know which ID the object will
- have in the future. When it is 'cooked' ( see _cook ), it will be
- assigned an ID, and the temporary placeholder list created here will be
- modified in-place to create an expression that gives this object an ID:
- [reference id# [object-jelly]].
- """
-
- # create a placeholder list to be preserved
- self.preserved[id(object)] = []
- # keep a reference to this object around, so it doesn't disappear!
- # (This isn't always necessary, but for cases where the objects are
- # dynamically generated by __getstate__ or getStateToCopyFor calls, it
- # is; id() will return the same value for a different object if it gets
- # garbage collected. This may be optimized later.)
- self.cooker[id(object)] = object
- return []
-
-
- def preserve(self, object, sexp):
- """
- (internal) Mark an object's persistent list for later referral.
- """
- # if I've been cooked in the meanwhile,
- if id(object) in self.cooked:
- # replace the placeholder empty list with the real one
- self.preserved[id(object)][2] = sexp
- # but give this one back.
- sexp = self.preserved[id(object)]
- else:
- self.preserved[id(object)] = sexp
- return sexp
-
- constantTypes = {types.StringType : 1, types.IntType : 1,
- types.FloatType : 1, types.LongType : 1}
-
-
- def _checkMutable(self,obj):
- objId = id(obj)
- if objId in self.cooked:
- return self.cooked[objId]
- if objId in self.preserved:
- self._cook(obj)
- return self.cooked[objId]
-
-
- def jelly(self, obj):
- if isinstance(obj, Jellyable):
- preRef = self._checkMutable(obj)
- if preRef:
- return preRef
- return obj.jellyFor(self)
- objType = type(obj)
- if self.taster.isTypeAllowed(qual(objType)):
- # "Immutable" Types
- if ((objType is StringType) or
- (objType is IntType) or
- (objType is LongType) or
- (objType is FloatType)):
- return obj
- elif objType is MethodType:
- return ["method",
- obj.im_func.__name__,
- self.jelly(obj.im_self),
- self.jelly(obj.im_class)]
-
- elif UnicodeType and objType is UnicodeType:
- return ['unicode', obj.encode('UTF-8')]
- elif objType is NoneType:
- return ['None']
- elif objType is FunctionType:
- name = obj.__name__
- return ['function', str(pickle.whichmodule(obj, obj.__name__))
- + '.' +
- name]
- elif objType is ModuleType:
- return ['module', obj.__name__]
- elif objType is BooleanType:
- return ['boolean', obj and 'true' or 'false']
- elif objType is datetime.datetime:
- if obj.tzinfo:
- raise NotImplementedError(
- "Currently can't jelly datetime objects with tzinfo")
- return ['datetime', '%s %s %s %s %s %s %s' % (
- obj.year, obj.month, obj.day, obj.hour,
- obj.minute, obj.second, obj.microsecond)]
- elif objType is datetime.time:
- if obj.tzinfo:
- raise NotImplementedError(
- "Currently can't jelly datetime objects with tzinfo")
- return ['time', '%s %s %s %s' % (obj.hour, obj.minute,
- obj.second, obj.microsecond)]
- elif objType is datetime.date:
- return ['date', '%s %s %s' % (obj.year, obj.month, obj.day)]
- elif objType is datetime.timedelta:
- return ['timedelta', '%s %s %s' % (obj.days, obj.seconds,
- obj.microseconds)]
- elif objType is ClassType or issubclass(objType, type):
- return ['class', qual(obj)]
- elif decimal is not None and objType is decimal.Decimal:
- return self.jelly_decimal(obj)
- else:
- preRef = self._checkMutable(obj)
- if preRef:
- return preRef
- # "Mutable" Types
- sxp = self.prepare(obj)
- if objType is ListType:
- sxp.extend(self._jellyIterable(list_atom, obj))
- elif objType is TupleType:
- sxp.extend(self._jellyIterable(tuple_atom, obj))
- elif objType in DictTypes:
- sxp.append(dictionary_atom)
- for key, val in obj.items():
- sxp.append([self.jelly(key), self.jelly(val)])
- elif (_set is not None and objType is set or
- objType is _sets.Set):
- sxp.extend(self._jellyIterable(set_atom, obj))
- elif (_set is not None and objType is frozenset or
- objType is _sets.ImmutableSet):
- sxp.extend(self._jellyIterable(frozenset_atom, obj))
- else:
- className = qual(obj.__class__)
- persistent = None
- if self.persistentStore:
- persistent = self.persistentStore(obj, self)
- if persistent is not None:
- sxp.append(persistent_atom)
- sxp.append(persistent)
- elif self.taster.isClassAllowed(obj.__class__):
- sxp.append(className)
- if hasattr(obj, "__getstate__"):
- state = obj.__getstate__()
- else:
- state = obj.__dict__
- sxp.append(self.jelly(state))
- else:
- self.unpersistable(
- "instance of class %s deemed insecure" %
- qual(obj.__class__), sxp)
- return self.preserve(obj, sxp)
- else:
- if objType is InstanceType:
- raise InsecureJelly("Class not allowed for instance: %s %s" %
- (obj.__class__, obj))
- raise InsecureJelly("Type not allowed for object: %s %s" %
- (objType, obj))
-
-
- def _jellyIterable(self, atom, obj):
- """
- Jelly an iterable object.
-
- @param atom: the identifier atom of the object.
- @type atom: C{str}
-
- @param obj: any iterable object.
- @type obj: C{iterable}
-
- @return: a generator of jellied data.
- @rtype: C{generator}
- """
- yield atom
- for item in obj:
- yield self.jelly(item)
-
-
- def jelly_decimal(self, d):
- """
- Jelly a decimal object.
-
- @param d: a decimal object to serialize.
- @type d: C{decimal.Decimal}
-
- @return: jelly for the decimal object.
- @rtype: C{list}
- """
- sign, guts, exponent = d.as_tuple()
- value = reduce(lambda left, right: left * 10 + right, guts)
- if sign:
- value = -value
- return ['decimal', value, exponent]
-
-
- def unpersistable(self, reason, sxp=None):
- """
- (internal) Returns an sexp: (unpersistable "reason"). Utility method
- for making note that a particular object could not be serialized.
- """
- if sxp is None:
- sxp = []
- sxp.append(unpersistable_atom)
- sxp.append(reason)
- return sxp
-
-
-
-class _Unjellier:
-
- def __init__(self, taster, persistentLoad, invoker):
- self.taster = taster
- self.persistentLoad = persistentLoad
- self.references = {}
- self.postCallbacks = []
- self.invoker = invoker
-
-
- def unjellyFull(self, obj):
- o = self.unjelly(obj)
- for m in self.postCallbacks:
- m()
- return o
-
-
- def unjelly(self, obj):
- if type(obj) is not types.ListType:
- return obj
- jelType = obj[0]
- if not self.taster.isTypeAllowed(jelType):
- raise InsecureJelly(jelType)
- regClass = unjellyableRegistry.get(jelType)
- if regClass is not None:
- if isinstance(regClass, ClassType):
- inst = _Dummy() # XXX chomp, chomp
- inst.__class__ = regClass
- method = inst.unjellyFor
- elif isinstance(regClass, type):
- # regClass.__new__ does not call regClass.__init__
- inst = regClass.__new__(regClass)
- method = inst.unjellyFor
- else:
- method = regClass # this is how it ought to be done
- val = method(self, obj)
- if hasattr(val, 'postUnjelly'):
- self.postCallbacks.append(inst.postUnjelly)
- return val
- regFactory = unjellyableFactoryRegistry.get(jelType)
- if regFactory is not None:
- state = self.unjelly(obj[1])
- inst = regFactory(state)
- if hasattr(inst, 'postUnjelly'):
- self.postCallbacks.append(inst.postUnjelly)
- return inst
- thunk = getattr(self, '_unjelly_%s'%jelType, None)
- if thunk is not None:
- ret = thunk(obj[1:])
- else:
- nameSplit = jelType.split('.')
- modName = '.'.join(nameSplit[:-1])
- if not self.taster.isModuleAllowed(modName):
- raise InsecureJelly(
- "Module %s not allowed (in type %s)." % (modName, jelType))
- clz = namedObject(jelType)
- if not self.taster.isClassAllowed(clz):
- raise InsecureJelly("Class %s not allowed." % jelType)
- if hasattr(clz, "__setstate__"):
- ret = _newInstance(clz)
- state = self.unjelly(obj[1])
- ret.__setstate__(state)
- else:
- state = self.unjelly(obj[1])
- ret = _newInstance(clz, state)
- if hasattr(clz, 'postUnjelly'):
- self.postCallbacks.append(ret.postUnjelly)
- return ret
-
-
- def _unjelly_None(self, exp):
- return None
-
-
- def _unjelly_unicode(self, exp):
- if UnicodeType:
- return unicode(exp[0], "UTF-8")
- else:
- return Unpersistable("Could not unpersist unicode: %s" % (exp[0],))
-
-
- def _unjelly_decimal(self, exp):
- """
- Unjelly decimal objects, if decimal is available. If not, return a
- L{Unpersistable} object instead.
- """
- if decimal is None:
- return Unpersistable(
- "Could not unpersist decimal: %s" % (exp[0] * (10**exp[1]),))
- value = exp[0]
- exponent = exp[1]
- if value < 0:
- sign = 1
- else:
- sign = 0
- guts = decimal.Decimal(value).as_tuple()[1]
- return decimal.Decimal((sign, guts, exponent))
-
-
- def _unjelly_boolean(self, exp):
- if BooleanType:
- assert exp[0] in ('true', 'false')
- return exp[0] == 'true'
- else:
- return Unpersistable("Could not unpersist boolean: %s" % (exp[0],))
-
-
- def _unjelly_datetime(self, exp):
- return datetime.datetime(*map(int, exp[0].split()))
-
-
- def _unjelly_date(self, exp):
- return datetime.date(*map(int, exp[0].split()))
-
-
- def _unjelly_time(self, exp):
- return datetime.time(*map(int, exp[0].split()))
-
-
- def _unjelly_timedelta(self, exp):
- days, seconds, microseconds = map(int, exp[0].split())
- return datetime.timedelta(
- days=days, seconds=seconds, microseconds=microseconds)
-
-
- def unjellyInto(self, obj, loc, jel):
- o = self.unjelly(jel)
- if isinstance(o, NotKnown):
- o.addDependant(obj, loc)
- obj[loc] = o
- return o
-
-
- def _unjelly_dereference(self, lst):
- refid = lst[0]
- x = self.references.get(refid)
- if x is not None:
- return x
- der = _Dereference(refid)
- self.references[refid] = der
- return der
-
-
- def _unjelly_reference(self, lst):
- refid = lst[0]
- exp = lst[1]
- o = self.unjelly(exp)
- ref = self.references.get(refid)
- if (ref is None):
- self.references[refid] = o
- elif isinstance(ref, NotKnown):
- ref.resolveDependants(o)
- self.references[refid] = o
- else:
- assert 0, "Multiple references with same ID!"
- return o
-
-
- def _unjelly_tuple(self, lst):
- l = range(len(lst))
- finished = 1
- for elem in l:
- if isinstance(self.unjellyInto(l, elem, lst[elem]), NotKnown):
- finished = 0
- if finished:
- return tuple(l)
- else:
- return _Tuple(l)
-
-
- def _unjelly_list(self, lst):
- l = range(len(lst))
- for elem in l:
- self.unjellyInto(l, elem, lst[elem])
- return l
-
-
- def _unjellySetOrFrozenset(self, lst, containerType):
- """
- Helper method to unjelly set or frozenset.
-
- @param lst: the content of the set.
- @type lst: C{list}
-
- @param containerType: the type of C{set} to use.
- """
- l = range(len(lst))
- finished = True
- for elem in l:
- data = self.unjellyInto(l, elem, lst[elem])
- if isinstance(data, NotKnown):
- finished = False
- if not finished:
- return _Container(l, containerType)
- else:
- return containerType(l)
-
-
- def _unjelly_set(self, lst):
- """
- Unjelly set using either the C{set} builtin if available, or
- C{sets.Set} as fallback.
- """
- if _set is not None:
- containerType = set
- else:
- containerType = _sets.Set
- return self._unjellySetOrFrozenset(lst, containerType)
-
-
- def _unjelly_frozenset(self, lst):
- """
- Unjelly frozenset using either the C{frozenset} builtin if available,
- or C{sets.ImmutableSet} as fallback.
- """
- if _set is not None:
- containerType = frozenset
- else:
- containerType = _sets.ImmutableSet
- return self._unjellySetOrFrozenset(lst, containerType)
-
-
- def _unjelly_dictionary(self, lst):
- d = {}
- for k, v in lst:
- kvd = _DictKeyAndValue(d)
- self.unjellyInto(kvd, 0, k)
- self.unjellyInto(kvd, 1, v)
- return d
-
-
- def _unjelly_module(self, rest):
- moduleName = rest[0]
- if type(moduleName) != types.StringType:
- raise InsecureJelly(
- "Attempted to unjelly a module with a non-string name.")
- if not self.taster.isModuleAllowed(moduleName):
- raise InsecureJelly(
- "Attempted to unjelly module named %r" % (moduleName,))
- mod = __import__(moduleName, {}, {},"x")
- return mod
-
-
- def _unjelly_class(self, rest):
- clist = rest[0].split('.')
- modName = '.'.join(clist[:-1])
- if not self.taster.isModuleAllowed(modName):
- raise InsecureJelly("module %s not allowed" % modName)
- klaus = namedObject(rest[0])
- objType = type(klaus)
- if objType not in (types.ClassType, types.TypeType):
- raise InsecureJelly(
- "class %r unjellied to something that isn't a class: %r" % (
- rest[0], klaus))
- if not self.taster.isClassAllowed(klaus):
- raise InsecureJelly("class not allowed: %s" % qual(klaus))
- return klaus
-
-
- def _unjelly_function(self, rest):
- modSplit = rest[0].split('.')
- modName = '.'.join(modSplit[:-1])
- if not self.taster.isModuleAllowed(modName):
- raise InsecureJelly("Module not allowed: %s"% modName)
- # XXX do I need an isFunctionAllowed?
- function = namedObject(rest[0])
- return function
-
-
- def _unjelly_persistent(self, rest):
- if self.persistentLoad:
- pload = self.persistentLoad(rest[0], self)
- return pload
- else:
- return Unpersistable("Persistent callback not found")
-
-
- def _unjelly_instance(self, rest):
- clz = self.unjelly(rest[0])
- if type(clz) is not types.ClassType:
- raise InsecureJelly("Instance found with non-class class.")
- if hasattr(clz, "__setstate__"):
- inst = _newInstance(clz, {})
- state = self.unjelly(rest[1])
- inst.__setstate__(state)
- else:
- state = self.unjelly(rest[1])
- inst = _newInstance(clz, state)
- if hasattr(clz, 'postUnjelly'):
- self.postCallbacks.append(inst.postUnjelly)
- return inst
-
-
- def _unjelly_unpersistable(self, rest):
- return Unpersistable("Unpersistable data: %s" % (rest[0],))
-
-
- def _unjelly_method(self, rest):
- """
- (internal) Unjelly a method.
- """
- im_name = rest[0]
- im_self = self.unjelly(rest[1])
- im_class = self.unjelly(rest[2])
- if type(im_class) is not types.ClassType:
- raise InsecureJelly("Method found with non-class class.")
- if im_name in im_class.__dict__:
- if im_self is None:
- im = getattr(im_class, im_name)
- elif isinstance(im_self, NotKnown):
- im = _InstanceMethod(im_name, im_self, im_class)
- else:
- im = MethodType(im_class.__dict__[im_name], im_self, im_class)
- else:
- raise TypeError('instance method changed')
- return im
-
-
-
-class _Dummy:
- """
- (Internal) Dummy class, used for unserializing instances.
- """
-
-
-
-class _DummyNewStyle(object):
- """
- (Internal) Dummy class, used for unserializing instances of new-style
- classes.
- """
-
-
-def _newDummyLike(instance):
- """
- Create a new instance like C{instance}.
-
- The new instance has the same class and instance dictionary as the given
- instance.
-
- @return: The new instance.
- """
- if isinstance(instance.__class__, type):
- # New-style class
- dummy = _DummyNewStyle()
- else:
- # Classic class
- dummy = _Dummy()
- dummy.__class__ = instance.__class__
- dummy.__dict__ = instance.__dict__
- return dummy
-
-
-#### Published Interface.
-
-
-class InsecureJelly(Exception):
- """
- This exception will be raised when a jelly is deemed `insecure'; e.g. it
- contains a type, class, or module disallowed by the specified `taster'
- """
-
-
-
-class DummySecurityOptions:
- """
- DummySecurityOptions() -> insecure security options
- Dummy security options -- this class will allow anything.
- """
-
- def isModuleAllowed(self, moduleName):
- """
- DummySecurityOptions.isModuleAllowed(moduleName) -> boolean
- returns 1 if a module by that name is allowed, 0 otherwise
- """
- return 1
-
-
- def isClassAllowed(self, klass):
- """
- DummySecurityOptions.isClassAllowed(class) -> boolean
- Assumes the module has already been allowed. Returns 1 if the given
- class is allowed, 0 otherwise.
- """
- return 1
-
-
- def isTypeAllowed(self, typeName):
- """
- DummySecurityOptions.isTypeAllowed(typeName) -> boolean
- Returns 1 if the given type is allowed, 0 otherwise.
- """
- return 1
-
-
-
-class SecurityOptions:
- """
- This will by default disallow everything, except for 'none'.
- """
-
- basicTypes = ["dictionary", "list", "tuple",
- "reference", "dereference", "unpersistable",
- "persistent", "long_int", "long", "dict"]
-
- def __init__(self):
- """
- SecurityOptions() initialize.
- """
- # I don't believe any of these types can ever pose a security hazard,
- # except perhaps "reference"...
- self.allowedTypes = {"None": 1,
- "bool": 1,
- "boolean": 1,
- "string": 1,
- "str": 1,
- "int": 1,
- "float": 1,
- "datetime": 1,
- "time": 1,
- "date": 1,
- "timedelta": 1,
- "NoneType": 1}
- if hasattr(types, 'UnicodeType'):
- self.allowedTypes['unicode'] = 1
- if decimal is not None:
- self.allowedTypes['decimal'] = 1
- self.allowedTypes['set'] = 1
- self.allowedTypes['frozenset'] = 1
- self.allowedModules = {}
- self.allowedClasses = {}
-
-
- def allowBasicTypes(self):
- """
- Allow all `basic' types. (Dictionary and list. Int, string, and float
- are implicitly allowed.)
- """
- self.allowTypes(*self.basicTypes)
-
-
- def allowTypes(self, *types):
- """
- SecurityOptions.allowTypes(typeString): Allow a particular type, by its
- name.
- """
- for typ in types:
- if not isinstance(typ, str):
- typ = qual(typ)
- self.allowedTypes[typ] = 1
-
-
- def allowInstancesOf(self, *classes):
- """
- SecurityOptions.allowInstances(klass, klass, ...): allow instances
- of the specified classes
-
- This will also allow the 'instance', 'class' (renamed 'classobj' in
- Python 2.3), and 'module' types, as well as basic types.
- """
- self.allowBasicTypes()
- self.allowTypes("instance", "class", "classobj", "module")
- for klass in classes:
- self.allowTypes(qual(klass))
- self.allowModules(klass.__module__)
- self.allowedClasses[klass] = 1
-
-
- def allowModules(self, *modules):
- """
- SecurityOptions.allowModules(module, module, ...): allow modules by
- name. This will also allow the 'module' type.
- """
- for module in modules:
- if type(module) == types.ModuleType:
- module = module.__name__
- self.allowedModules[module] = 1
-
-
- def isModuleAllowed(self, moduleName):
- """
- SecurityOptions.isModuleAllowed(moduleName) -> boolean
- returns 1 if a module by that name is allowed, 0 otherwise
- """
- return moduleName in self.allowedModules
-
-
- def isClassAllowed(self, klass):
- """
- SecurityOptions.isClassAllowed(class) -> boolean
- Assumes the module has already been allowed. Returns 1 if the given
- class is allowed, 0 otherwise.
- """
- return klass in self.allowedClasses
-
-
- def isTypeAllowed(self, typeName):
- """
- SecurityOptions.isTypeAllowed(typeName) -> boolean
- Returns 1 if the given type is allowed, 0 otherwise.
- """
- return (typeName in self.allowedTypes or '.' in typeName)
-
-
-globalSecurity = SecurityOptions()
-globalSecurity.allowBasicTypes()
-
-
-
-def jelly(object, taster=DummySecurityOptions(), persistentStore=None,
- invoker=None):
- """
- Serialize to s-expression.
-
- Returns a list which is the serialized representation of an object. An
- optional 'taster' argument takes a SecurityOptions and will mark any
- insecure objects as unpersistable rather than serializing them.
- """
- return _Jellier(taster, persistentStore, invoker).jelly(object)
-
-
-
-def unjelly(sexp, taster=DummySecurityOptions(), persistentLoad=None,
- invoker=None):
- """
- Unserialize from s-expression.
-
- Takes an list that was the result from a call to jelly() and unserializes
- an arbitrary object from it. The optional 'taster' argument, an instance
- of SecurityOptions, will cause an InsecureJelly exception to be raised if a
- disallowed type, module, or class attempted to unserialize.
- """
- return _Unjellier(taster, persistentLoad, invoker).unjellyFull(sexp)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/pb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/pb.py
deleted file mode 100755
index 7e9a5b6a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/pb.py
+++ /dev/null
@@ -1,1434 +0,0 @@
-# -*- test-case-name: twisted.test.test_pb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Perspective Broker
-
-\"This isn\'t a professional opinion, but it's probably got enough
-internet to kill you.\" --glyph
-
-Introduction
-============
-
-This is a broker for proxies for and copies of objects. It provides a
-translucent interface layer to those proxies.
-
-The protocol is not opaque, because it provides objects which represent the
-remote proxies and require no context (server references, IDs) to operate on.
-
-It is not transparent because it does I{not} attempt to make remote objects
-behave identically, or even similiarly, to local objects. Method calls are
-invoked asynchronously, and specific rules are applied when serializing
-arguments.
-
-To get started, begin with L{PBClientFactory} and L{PBServerFactory}.
-
-@author: Glyph Lefkowitz
-"""
-
-import random
-import types
-
-from zope.interface import implements, Interface
-
-# Twisted Imports
-from twisted.python import log, failure, reflect
-from twisted.python.hashlib import md5
-from twisted.internet import defer, protocol
-from twisted.cred.portal import Portal
-from twisted.cred.credentials import IAnonymous, ICredentials
-from twisted.cred.credentials import IUsernameHashedPassword, Anonymous
-from twisted.persisted import styles
-from twisted.python.components import registerAdapter
-
-from twisted.spread.interfaces import IJellyable, IUnjellyable
-from twisted.spread.jelly import jelly, unjelly, globalSecurity
-from twisted.spread import banana
-
-from twisted.spread.flavors import Serializable
-from twisted.spread.flavors import Referenceable, NoSuchMethod
-from twisted.spread.flavors import Root, IPBRoot
-from twisted.spread.flavors import ViewPoint
-from twisted.spread.flavors import Viewable
-from twisted.spread.flavors import Copyable
-from twisted.spread.flavors import Jellyable
-from twisted.spread.flavors import Cacheable
-from twisted.spread.flavors import RemoteCopy
-from twisted.spread.flavors import RemoteCache
-from twisted.spread.flavors import RemoteCacheObserver
-from twisted.spread.flavors import copyTags
-
-from twisted.spread.flavors import setUnjellyableForClass
-from twisted.spread.flavors import setUnjellyableFactoryForClass
-from twisted.spread.flavors import setUnjellyableForClassTree
-# These three are backwards compatibility aliases for the previous three.
-# Ultimately they should be deprecated. -exarkun
-from twisted.spread.flavors import setCopierForClass
-from twisted.spread.flavors import setFactoryForClass
-from twisted.spread.flavors import setCopierForClassTree
-
-
-MAX_BROKER_REFS = 1024
-
-portno = 8787
-
-
-
-class ProtocolError(Exception):
- """
- This error is raised when an invalid protocol statement is received.
- """
-
-
-
-class DeadReferenceError(ProtocolError):
- """
- This error is raised when a method is called on a dead reference (one whose
- broker has been disconnected).
- """
-
-
-
-class Error(Exception):
- """
- This error can be raised to generate known error conditions.
-
- When a PB callable method (perspective_, remote_, view_) raises
- this error, it indicates that a traceback should not be printed,
- but instead, the string representation of the exception should be
- sent.
- """
-
-
-
-class RemoteError(Exception):
- """
- This class is used to wrap a string-ified exception from the remote side to
- be able to reraise it. (Raising string exceptions is no longer possible in
- Python 2.6+)
-
- The value of this exception will be a str() representation of the remote
- value.
-
- @ivar remoteType: The full import path of the exception class which was
- raised on the remote end.
- @type remoteType: C{str}
-
- @ivar remoteTraceback: The remote traceback.
- @type remoteTraceback: C{str}
-
- @note: It's not possible to include the remoteTraceback if this exception is
- thrown into a generator. It must be accessed as an attribute.
- """
- def __init__(self, remoteType, value, remoteTraceback):
- Exception.__init__(self, value)
- self.remoteType = remoteType
- self.remoteTraceback = remoteTraceback
-
-
-
-class RemoteMethod:
- """
- This is a translucent reference to a remote message.
- """
- def __init__(self, obj, name):
- """
- Initialize with a L{RemoteReference} and the name of this message.
- """
- self.obj = obj
- self.name = name
-
-
- def __cmp__(self, other):
- return cmp((self.obj, self.name), other)
-
-
- def __hash__(self):
- return hash((self.obj, self.name))
-
-
- def __call__(self, *args, **kw):
- """
- Asynchronously invoke a remote method.
- """
- return self.obj.broker._sendMessage('',self.obj.perspective,
- self.obj.luid, self.name, args, kw)
-
-
-
-class PBConnectionLost(Exception):
- pass
-
-
-
-class IPerspective(Interface):
- """
- per*spec*tive, n. : The relationship of aspects of a subject to each
- other and to a whole: 'a perspective of history'; 'a need to view
- the problem in the proper perspective'.
-
- This is a Perspective Broker-specific wrapper for an avatar. That
- is to say, a PB-published view on to the business logic for the
- system's concept of a 'user'.
-
- The concept of attached/detached is no longer implemented by the
- framework. The realm is expected to implement such semantics if
- needed.
- """
-
- def perspectiveMessageReceived(broker, message, args, kwargs):
- """
- This method is called when a network message is received.
-
- @arg broker: The Perspective Broker.
-
- @type message: str
- @arg message: The name of the method called by the other end.
-
- @type args: list in jelly format
- @arg args: The arguments that were passed by the other end. It
- is recommend that you use the `unserialize' method of the
- broker to decode this.
-
- @type kwargs: dict in jelly format
- @arg kwargs: The keyword arguments that were passed by the
- other end. It is recommended that you use the
- `unserialize' method of the broker to decode this.
-
- @rtype: A jelly list.
- @return: It is recommended that you use the `serialize' method
- of the broker on whatever object you need to return to
- generate the return value.
- """
-
-
-
-class Avatar:
- """
- A default IPerspective implementor.
-
- This class is intended to be subclassed, and a realm should return
- an instance of such a subclass when IPerspective is requested of
- it.
-
- A peer requesting a perspective will receive only a
- L{RemoteReference} to a pb.Avatar. When a method is called on
- that L{RemoteReference}, it will translate to a method on the
- remote perspective named 'perspective_methodname'. (For more
- information on invoking methods on other objects, see
- L{flavors.ViewPoint}.)
- """
-
- implements(IPerspective)
-
- def perspectiveMessageReceived(self, broker, message, args, kw):
- """
- This method is called when a network message is received.
-
- This will call::
-
- self.perspective_%(message)s(*broker.unserialize(args),
- **broker.unserialize(kw))
-
- to handle the method; subclasses of Avatar are expected to
- implement methods using this naming convention.
- """
-
- args = broker.unserialize(args, self)
- kw = broker.unserialize(kw, self)
- method = getattr(self, "perspective_%s" % message)
- try:
- state = method(*args, **kw)
- except TypeError:
- log.msg("%s didn't accept %s and %s" % (method, args, kw))
- raise
- return broker.serialize(state, self, method, args, kw)
-
-
-
-class AsReferenceable(Referenceable):
- """
- A reference directed towards another object.
- """
-
- def __init__(self, object, messageType="remote"):
- self.remoteMessageReceived = getattr(
- object, messageType + "MessageReceived")
-
-
-
-class RemoteReference(Serializable, styles.Ephemeral):
- """
- A translucent reference to a remote object.
-
- I may be a reference to a L{flavors.ViewPoint}, a
- L{flavors.Referenceable}, or an L{IPerspective} implementor (e.g.,
- pb.Avatar). From the client's perspective, it is not possible to
- tell which except by convention.
-
- I am a \"translucent\" reference because although no additional
- bookkeeping overhead is given to the application programmer for
- manipulating a reference, return values are asynchronous.
-
- See also L{twisted.internet.defer}.
-
- @ivar broker: The broker I am obtained through.
- @type broker: L{Broker}
- """
-
- implements(IUnjellyable)
-
- def __init__(self, perspective, broker, luid, doRefCount):
- """(internal) Initialize me with a broker and a locally-unique ID.
-
- The ID is unique only to the particular Perspective Broker
- instance.
- """
- self.luid = luid
- self.broker = broker
- self.doRefCount = doRefCount
- self.perspective = perspective
- self.disconnectCallbacks = []
-
- def notifyOnDisconnect(self, callback):
- """Register a callback to be called if our broker gets disconnected.
-
- This callback will be called with one argument, this instance.
- """
- assert callable(callback)
- self.disconnectCallbacks.append(callback)
- if len(self.disconnectCallbacks) == 1:
- self.broker.notifyOnDisconnect(self._disconnected)
-
- def dontNotifyOnDisconnect(self, callback):
- """Remove a callback that was registered with notifyOnDisconnect."""
- self.disconnectCallbacks.remove(callback)
- if not self.disconnectCallbacks:
- self.broker.dontNotifyOnDisconnect(self._disconnected)
-
- def _disconnected(self):
- """Called if we are disconnected and have callbacks registered."""
- for callback in self.disconnectCallbacks:
- callback(self)
- self.disconnectCallbacks = None
-
- def jellyFor(self, jellier):
- """If I am being sent back to where I came from, serialize as a local backreference.
- """
- if jellier.invoker:
- assert self.broker == jellier.invoker, "Can't send references to brokers other than their own."
- return "local", self.luid
- else:
- return "unpersistable", "References cannot be serialized"
-
- def unjellyFor(self, unjellier, unjellyList):
- self.__init__(unjellier.invoker.unserializingPerspective, unjellier.invoker, unjellyList[1], 1)
- return self
-
- def callRemote(self, _name, *args, **kw):
- """Asynchronously invoke a remote method.
-
- @type _name: C{str}
- @param _name: the name of the remote method to invoke
- @param args: arguments to serialize for the remote function
- @param kw: keyword arguments to serialize for the remote function.
- @rtype: L{twisted.internet.defer.Deferred}
- @returns: a Deferred which will be fired when the result of
- this remote call is received.
- """
- # note that we use '_name' instead of 'name' so the user can call
- # remote methods with 'name' as a keyword parameter, like this:
- # ref.callRemote("getPeopleNamed", count=12, name="Bob")
-
- return self.broker._sendMessage('',self.perspective, self.luid,
- _name, args, kw)
-
- def remoteMethod(self, key):
- """Get a L{RemoteMethod} for this key.
- """
- return RemoteMethod(self, key)
-
- def __cmp__(self,other):
- """Compare me [to another L{RemoteReference}].
- """
- if isinstance(other, RemoteReference):
- if other.broker == self.broker:
- return cmp(self.luid, other.luid)
- return cmp(self.broker, other)
-
- def __hash__(self):
- """Hash me.
- """
- return self.luid
-
- def __del__(self):
- """Do distributed reference counting on finalization.
- """
- if self.doRefCount:
- self.broker.sendDecRef(self.luid)
-
-setUnjellyableForClass("remote", RemoteReference)
-
-class Local:
- """(internal) A reference to a local object.
- """
-
- def __init__(self, object, perspective=None):
- """Initialize.
- """
- self.object = object
- self.perspective = perspective
- self.refcount = 1
-
- def __repr__(self):
- return "<pb.Local %r ref:%s>" % (self.object, self.refcount)
-
- def incref(self):
- """Increment and return my reference count.
- """
- self.refcount = self.refcount + 1
- return self.refcount
-
- def decref(self):
- """Decrement and return my reference count.
- """
- self.refcount = self.refcount - 1
- return self.refcount
-
-
-##
-# Failure
-##
-
-class CopyableFailure(failure.Failure, Copyable):
- """
- A L{flavors.RemoteCopy} and L{flavors.Copyable} version of
- L{twisted.python.failure.Failure} for serialization.
- """
-
- unsafeTracebacks = 0
-
- def getStateToCopy(self):
- """
- Collect state related to the exception which occurred, discarding
- state which cannot reasonably be serialized.
- """
- state = self.__dict__.copy()
- state['tb'] = None
- state['frames'] = []
- state['stack'] = []
- state['value'] = str(self.value) # Exception instance
- if isinstance(self.type, str):
- state['type'] = self.type
- else:
- state['type'] = reflect.qual(self.type) # Exception class
- if self.unsafeTracebacks:
- state['traceback'] = self.getTraceback()
- else:
- state['traceback'] = 'Traceback unavailable\n'
- return state
-
-
-
-class CopiedFailure(RemoteCopy, failure.Failure):
- """
- A L{CopiedFailure} is a L{pb.RemoteCopy} of a L{failure.Failure}
- transfered via PB.
-
- @ivar type: The full import path of the exception class which was raised on
- the remote end.
- @type type: C{str}
-
- @ivar value: A str() representation of the remote value.
- @type value: L{CopiedFailure} or C{str}
-
- @ivar traceback: The remote traceback.
- @type traceback: C{str}
- """
-
- def printTraceback(self, file=None, elideFrameworkCode=0, detail='default'):
- if file is None:
- file = log.logfile
- file.write("Traceback from remote host -- ")
- file.write(self.traceback)
- file.write(self.type + ": " + self.value)
- file.write('\n')
-
-
- def throwExceptionIntoGenerator(self, g):
- """
- Throw the original exception into the given generator, preserving
- traceback information if available. In the case of a L{CopiedFailure}
- where the exception type is a string, a L{pb.RemoteError} is thrown
- instead.
-
- @return: The next value yielded from the generator.
- @raise StopIteration: If there are no more values in the generator.
- @raise RemoteError: The wrapped remote exception.
- """
- return g.throw(RemoteError(self.type, self.value, self.traceback))
-
- printBriefTraceback = printTraceback
- printDetailedTraceback = printTraceback
-
-setUnjellyableForClass(CopyableFailure, CopiedFailure)
-
-
-
-def failure2Copyable(fail, unsafeTracebacks=0):
- f = types.InstanceType(CopyableFailure, fail.__dict__)
- f.unsafeTracebacks = unsafeTracebacks
- return f
-
-
-
-class Broker(banana.Banana):
- """I am a broker for objects.
- """
-
- version = 6
- username = None
- factory = None
-
- def __init__(self, isClient=1, security=globalSecurity):
- banana.Banana.__init__(self, isClient)
- self.disconnected = 0
- self.disconnects = []
- self.failures = []
- self.connects = []
- self.localObjects = {}
- self.security = security
- self.pageProducers = []
- self.currentRequestID = 0
- self.currentLocalID = 0
- self.unserializingPerspective = None
- # Some terms:
- # PUID: process unique ID; return value of id() function. type "int".
- # LUID: locally unique ID; an ID unique to an object mapped over this
- # connection. type "int"
- # GUID: (not used yet) globally unique ID; an ID for an object which
- # may be on a redirected or meta server. Type as yet undecided.
- # Dictionary mapping LUIDs to local objects.
- # set above to allow root object to be assigned before connection is made
- # self.localObjects = {}
- # Dictionary mapping PUIDs to LUIDs.
- self.luids = {}
- # Dictionary mapping LUIDs to local (remotely cached) objects. Remotely
- # cached means that they're objects which originate here, and were
- # copied remotely.
- self.remotelyCachedObjects = {}
- # Dictionary mapping PUIDs to (cached) LUIDs
- self.remotelyCachedLUIDs = {}
- # Dictionary mapping (remote) LUIDs to (locally cached) objects.
- self.locallyCachedObjects = {}
- self.waitingForAnswers = {}
-
- # Mapping from LUIDs to weakref objects with callbacks for performing
- # any local cleanup which may be necessary for the corresponding
- # object once it no longer exists.
- self._localCleanup = {}
-
-
- def resumeProducing(self):
- """Called when the consumer attached to me runs out of buffer.
- """
- # Go backwards over the list so we can remove indexes from it as we go
- for pageridx in xrange(len(self.pageProducers)-1, -1, -1):
- pager = self.pageProducers[pageridx]
- pager.sendNextPage()
- if not pager.stillPaging():
- del self.pageProducers[pageridx]
- if not self.pageProducers:
- self.transport.unregisterProducer()
-
- # Streaming producer methods; not necessary to implement.
- def pauseProducing(self):
- pass
-
- def stopProducing(self):
- pass
-
- def registerPageProducer(self, pager):
- self.pageProducers.append(pager)
- if len(self.pageProducers) == 1:
- self.transport.registerProducer(self, 0)
-
- def expressionReceived(self, sexp):
- """Evaluate an expression as it's received.
- """
- if isinstance(sexp, types.ListType):
- command = sexp[0]
- methodName = "proto_%s" % command
- method = getattr(self, methodName, None)
- if method:
- method(*sexp[1:])
- else:
- self.sendCall("didNotUnderstand", command)
- else:
- raise ProtocolError("Non-list expression received.")
-
-
- def proto_version(self, vnum):
- """Protocol message: (version version-number)
-
- Check to make sure that both ends of the protocol are speaking
- the same version dialect.
- """
-
- if vnum != self.version:
- raise ProtocolError("Version Incompatibility: %s %s" % (self.version, vnum))
-
-
- def sendCall(self, *exp):
- """Utility method to send an expression to the other side of the connection.
- """
- self.sendEncoded(exp)
-
- def proto_didNotUnderstand(self, command):
- """Respond to stock 'C{didNotUnderstand}' message.
-
- Log the command that was not understood and continue. (Note:
- this will probably be changed to close the connection or raise
- an exception in the future.)
- """
- log.msg("Didn't understand command: %r" % command)
-
- def connectionReady(self):
- """Initialize. Called after Banana negotiation is done.
- """
- self.sendCall("version", self.version)
- for notifier in self.connects:
- try:
- notifier()
- except:
- log.deferr()
- self.connects = None
- if self.factory: # in tests we won't have factory
- self.factory.clientConnectionMade(self)
-
- def connectionFailed(self):
- # XXX should never get called anymore? check!
- for notifier in self.failures:
- try:
- notifier()
- except:
- log.deferr()
- self.failures = None
-
- waitingForAnswers = None
-
- def connectionLost(self, reason):
- """The connection was lost.
- """
- self.disconnected = 1
- # nuke potential circular references.
- self.luids = None
- if self.waitingForAnswers:
- for d in self.waitingForAnswers.values():
- try:
- d.errback(failure.Failure(PBConnectionLost(reason)))
- except:
- log.deferr()
- # Assure all Cacheable.stoppedObserving are called
- for lobj in self.remotelyCachedObjects.values():
- cacheable = lobj.object
- perspective = lobj.perspective
- try:
- cacheable.stoppedObserving(perspective, RemoteCacheObserver(self, cacheable, perspective))
- except:
- log.deferr()
- # Loop on a copy to prevent notifiers to mixup
- # the list by calling dontNotifyOnDisconnect
- for notifier in self.disconnects[:]:
- try:
- notifier()
- except:
- log.deferr()
- self.disconnects = None
- self.waitingForAnswers = None
- self.localSecurity = None
- self.remoteSecurity = None
- self.remotelyCachedObjects = None
- self.remotelyCachedLUIDs = None
- self.locallyCachedObjects = None
- self.localObjects = None
-
- def notifyOnDisconnect(self, notifier):
- """Call the given callback when the Broker disconnects."""
- assert callable(notifier)
- self.disconnects.append(notifier)
-
- def notifyOnFail(self, notifier):
- """Call the given callback if the Broker fails to connect."""
- assert callable(notifier)
- self.failures.append(notifier)
-
- def notifyOnConnect(self, notifier):
- """Call the given callback when the Broker connects."""
- assert callable(notifier)
- if self.connects is None:
- try:
- notifier()
- except:
- log.err()
- else:
- self.connects.append(notifier)
-
- def dontNotifyOnDisconnect(self, notifier):
- """Remove a callback from list of disconnect callbacks."""
- try:
- self.disconnects.remove(notifier)
- except ValueError:
- pass
-
- def localObjectForID(self, luid):
- """
- Get a local object for a locally unique ID.
-
- @return: An object previously stored with L{registerReference} or
- C{None} if there is no object which corresponds to the given
- identifier.
- """
- lob = self.localObjects.get(luid)
- if lob is None:
- return
- return lob.object
-
- maxBrokerRefsViolations = 0
-
- def registerReference(self, object):
- """Get an ID for a local object.
-
- Store a persistent reference to a local object and map its id()
- to a generated, session-unique ID and return that ID.
- """
-
- assert object is not None
- puid = object.processUniqueID()
- luid = self.luids.get(puid)
- if luid is None:
- if len(self.localObjects) > MAX_BROKER_REFS:
- self.maxBrokerRefsViolations = self.maxBrokerRefsViolations + 1
- if self.maxBrokerRefsViolations > 3:
- self.transport.loseConnection()
- raise Error("Maximum PB reference count exceeded. "
- "Goodbye.")
- raise Error("Maximum PB reference count exceeded.")
-
- luid = self.newLocalID()
- self.localObjects[luid] = Local(object)
- self.luids[puid] = luid
- else:
- self.localObjects[luid].incref()
- return luid
-
- def setNameForLocal(self, name, object):
- """Store a special (string) ID for this object.
-
- This is how you specify a 'base' set of objects that the remote
- protocol can connect to.
- """
- assert object is not None
- self.localObjects[name] = Local(object)
-
- def remoteForName(self, name):
- """Returns an object from the remote name mapping.
-
- Note that this does not check the validity of the name, only
- creates a translucent reference for it.
- """
- return RemoteReference(None, self, name, 0)
-
- def cachedRemotelyAs(self, instance, incref=0):
- """Returns an ID that says what this instance is cached as remotely, or C{None} if it's not.
- """
-
- puid = instance.processUniqueID()
- luid = self.remotelyCachedLUIDs.get(puid)
- if (luid is not None) and (incref):
- self.remotelyCachedObjects[luid].incref()
- return luid
-
- def remotelyCachedForLUID(self, luid):
- """Returns an instance which is cached remotely, with this LUID.
- """
- return self.remotelyCachedObjects[luid].object
-
- def cacheRemotely(self, instance):
- """
- XXX"""
- puid = instance.processUniqueID()
- luid = self.newLocalID()
- if len(self.remotelyCachedObjects) > MAX_BROKER_REFS:
- self.maxBrokerRefsViolations = self.maxBrokerRefsViolations + 1
- if self.maxBrokerRefsViolations > 3:
- self.transport.loseConnection()
- raise Error("Maximum PB cache count exceeded. "
- "Goodbye.")
- raise Error("Maximum PB cache count exceeded.")
-
- self.remotelyCachedLUIDs[puid] = luid
- # This table may not be necessary -- for now, it's to make sure that no
- # monkey business happens with id(instance)
- self.remotelyCachedObjects[luid] = Local(instance, self.serializingPerspective)
- return luid
-
- def cacheLocally(self, cid, instance):
- """(internal)
-
- Store a non-filled-out cached instance locally.
- """
- self.locallyCachedObjects[cid] = instance
-
- def cachedLocallyAs(self, cid):
- instance = self.locallyCachedObjects[cid]
- return instance
-
- def serialize(self, object, perspective=None, method=None, args=None, kw=None):
- """Jelly an object according to the remote security rules for this broker.
- """
-
- if isinstance(object, defer.Deferred):
- object.addCallbacks(self.serialize, lambda x: x,
- callbackKeywords={
- 'perspective': perspective,
- 'method': method,
- 'args': args,
- 'kw': kw
- })
- return object
-
- # XXX This call is NOT REENTRANT and testing for reentrancy is just
- # crazy, so it likely won't be. Don't ever write methods that call the
- # broker's serialize() method recursively (e.g. sending a method call
- # from within a getState (this causes concurrency problems anyway so
- # you really, really shouldn't do it))
-
- # self.jellier = _NetJellier(self)
- self.serializingPerspective = perspective
- self.jellyMethod = method
- self.jellyArgs = args
- self.jellyKw = kw
- try:
- return jelly(object, self.security, None, self)
- finally:
- self.serializingPerspective = None
- self.jellyMethod = None
- self.jellyArgs = None
- self.jellyKw = None
-
- def unserialize(self, sexp, perspective = None):
- """Unjelly an sexp according to the local security rules for this broker.
- """
-
- self.unserializingPerspective = perspective
- try:
- return unjelly(sexp, self.security, None, self)
- finally:
- self.unserializingPerspective = None
-
- def newLocalID(self):
- """Generate a new LUID.
- """
- self.currentLocalID = self.currentLocalID + 1
- return self.currentLocalID
-
- def newRequestID(self):
- """Generate a new request ID.
- """
- self.currentRequestID = self.currentRequestID + 1
- return self.currentRequestID
-
- def _sendMessage(self, prefix, perspective, objectID, message, args, kw):
- pbc = None
- pbe = None
- answerRequired = 1
- if 'pbcallback' in kw:
- pbc = kw['pbcallback']
- del kw['pbcallback']
- if 'pberrback' in kw:
- pbe = kw['pberrback']
- del kw['pberrback']
- if 'pbanswer' in kw:
- assert (not pbe) and (not pbc), "You can't specify a no-answer requirement."
- answerRequired = kw['pbanswer']
- del kw['pbanswer']
- if self.disconnected:
- raise DeadReferenceError("Calling Stale Broker")
- try:
- netArgs = self.serialize(args, perspective=perspective, method=message)
- netKw = self.serialize(kw, perspective=perspective, method=message)
- except:
- return defer.fail(failure.Failure())
- requestID = self.newRequestID()
- if answerRequired:
- rval = defer.Deferred()
- self.waitingForAnswers[requestID] = rval
- if pbc or pbe:
- log.msg('warning! using deprecated "pbcallback"')
- rval.addCallbacks(pbc, pbe)
- else:
- rval = None
- self.sendCall(prefix+"message", requestID, objectID, message, answerRequired, netArgs, netKw)
- return rval
-
- def proto_message(self, requestID, objectID, message, answerRequired, netArgs, netKw):
- self._recvMessage(self.localObjectForID, requestID, objectID, message, answerRequired, netArgs, netKw)
- def proto_cachemessage(self, requestID, objectID, message, answerRequired, netArgs, netKw):
- self._recvMessage(self.cachedLocallyAs, requestID, objectID, message, answerRequired, netArgs, netKw)
-
- def _recvMessage(self, findObjMethod, requestID, objectID, message, answerRequired, netArgs, netKw):
- """Received a message-send.
-
- Look up message based on object, unserialize the arguments, and
- invoke it with args, and send an 'answer' or 'error' response.
- """
- try:
- object = findObjMethod(objectID)
- if object is None:
- raise Error("Invalid Object ID")
- netResult = object.remoteMessageReceived(self, message, netArgs, netKw)
- except Error, e:
- if answerRequired:
- # If the error is Jellyable or explicitly allowed via our
- # security options, send it back and let the code on the
- # other end deal with unjellying. If it isn't Jellyable,
- # wrap it in a CopyableFailure, which ensures it can be
- # unjellied on the other end. We have to do this because
- # all errors must be sent back.
- if isinstance(e, Jellyable) or self.security.isClassAllowed(e.__class__):
- self._sendError(e, requestID)
- else:
- self._sendError(CopyableFailure(e), requestID)
- except:
- if answerRequired:
- log.msg("Peer will receive following PB traceback:", isError=True)
- f = CopyableFailure()
- self._sendError(f, requestID)
- log.err()
- else:
- if answerRequired:
- if isinstance(netResult, defer.Deferred):
- args = (requestID,)
- netResult.addCallbacks(self._sendAnswer, self._sendFailureOrError,
- callbackArgs=args, errbackArgs=args)
- # XXX Should this be done somewhere else?
- else:
- self._sendAnswer(netResult, requestID)
- ##
- # success
- ##
-
- def _sendAnswer(self, netResult, requestID):
- """(internal) Send an answer to a previously sent message.
- """
- self.sendCall("answer", requestID, netResult)
-
- def proto_answer(self, requestID, netResult):
- """(internal) Got an answer to a previously sent message.
-
- Look up the appropriate callback and call it.
- """
- d = self.waitingForAnswers[requestID]
- del self.waitingForAnswers[requestID]
- d.callback(self.unserialize(netResult))
-
- ##
- # failure
- ##
- def _sendFailureOrError(self, fail, requestID):
- """
- Call L{_sendError} or L{_sendFailure}, depending on whether C{fail}
- represents an L{Error} subclass or not.
- """
- if fail.check(Error) is None:
- self._sendFailure(fail, requestID)
- else:
- self._sendError(fail, requestID)
-
-
- def _sendFailure(self, fail, requestID):
- """Log error and then send it."""
- log.msg("Peer will receive following PB traceback:")
- log.err(fail)
- self._sendError(fail, requestID)
-
- def _sendError(self, fail, requestID):
- """(internal) Send an error for a previously sent message.
- """
- if isinstance(fail, failure.Failure):
- # If the failures value is jellyable or allowed through security,
- # send the value
- if (isinstance(fail.value, Jellyable) or
- self.security.isClassAllowed(fail.value.__class__)):
- fail = fail.value
- elif not isinstance(fail, CopyableFailure):
- fail = failure2Copyable(fail, self.factory.unsafeTracebacks)
- if isinstance(fail, CopyableFailure):
- fail.unsafeTracebacks = self.factory.unsafeTracebacks
- self.sendCall("error", requestID, self.serialize(fail))
-
- def proto_error(self, requestID, fail):
- """(internal) Deal with an error.
- """
- d = self.waitingForAnswers[requestID]
- del self.waitingForAnswers[requestID]
- d.errback(self.unserialize(fail))
-
- ##
- # refcounts
- ##
-
- def sendDecRef(self, objectID):
- """(internal) Send a DECREF directive.
- """
- self.sendCall("decref", objectID)
-
- def proto_decref(self, objectID):
- """(internal) Decrement the reference count of an object.
-
- If the reference count is zero, it will free the reference to this
- object.
- """
- refs = self.localObjects[objectID].decref()
- if refs == 0:
- puid = self.localObjects[objectID].object.processUniqueID()
- del self.luids[puid]
- del self.localObjects[objectID]
- self._localCleanup.pop(puid, lambda: None)()
-
- ##
- # caching
- ##
-
- def decCacheRef(self, objectID):
- """(internal) Send a DECACHE directive.
- """
- self.sendCall("decache", objectID)
-
- def proto_decache(self, objectID):
- """(internal) Decrement the reference count of a cached object.
-
- If the reference count is zero, free the reference, then send an
- 'uncached' directive.
- """
- refs = self.remotelyCachedObjects[objectID].decref()
- # log.msg('decaching: %s #refs: %s' % (objectID, refs))
- if refs == 0:
- lobj = self.remotelyCachedObjects[objectID]
- cacheable = lobj.object
- perspective = lobj.perspective
- # TODO: force_decache needs to be able to force-invalidate a
- # cacheable reference.
- try:
- cacheable.stoppedObserving(perspective, RemoteCacheObserver(self, cacheable, perspective))
- except:
- log.deferr()
- puid = cacheable.processUniqueID()
- del self.remotelyCachedLUIDs[puid]
- del self.remotelyCachedObjects[objectID]
- self.sendCall("uncache", objectID)
-
- def proto_uncache(self, objectID):
- """(internal) Tell the client it is now OK to uncache an object.
- """
- # log.msg("uncaching locally %d" % objectID)
- obj = self.locallyCachedObjects[objectID]
- obj.broker = None
-## def reallyDel(obj=obj):
-## obj.__really_del__()
-## obj.__del__ = reallyDel
- del self.locallyCachedObjects[objectID]
-
-
-
-def respond(challenge, password):
- """Respond to a challenge.
-
- This is useful for challenge/response authentication.
- """
- m = md5()
- m.update(password)
- hashedPassword = m.digest()
- m = md5()
- m.update(hashedPassword)
- m.update(challenge)
- doubleHashedPassword = m.digest()
- return doubleHashedPassword
-
-def challenge():
- """I return some random data."""
- crap = ''
- for x in range(random.randrange(15,25)):
- crap = crap + chr(random.randint(65,90))
- crap = md5(crap).digest()
- return crap
-
-
-class PBClientFactory(protocol.ClientFactory):
- """
- Client factory for PB brokers.
-
- As with all client factories, use with reactor.connectTCP/SSL/etc..
- getPerspective and getRootObject can be called either before or
- after the connect.
- """
-
- protocol = Broker
- unsafeTracebacks = False
-
- def __init__(self, unsafeTracebacks=False, security=globalSecurity):
- """
- @param unsafeTracebacks: if set, tracebacks for exceptions will be sent
- over the wire.
- @type unsafeTracebacks: C{bool}
-
- @param security: security options used by the broker, default to
- C{globalSecurity}.
- @type security: L{twisted.spread.jelly.SecurityOptions}
- """
- self.unsafeTracebacks = unsafeTracebacks
- self.security = security
- self._reset()
-
-
- def buildProtocol(self, addr):
- """
- Build the broker instance, passing the security options to it.
- """
- p = self.protocol(isClient=True, security=self.security)
- p.factory = self
- return p
-
-
- def _reset(self):
- self.rootObjectRequests = [] # list of deferred
- self._broker = None
- self._root = None
-
- def _failAll(self, reason):
- deferreds = self.rootObjectRequests
- self._reset()
- for d in deferreds:
- d.errback(reason)
-
- def clientConnectionFailed(self, connector, reason):
- self._failAll(reason)
-
- def clientConnectionLost(self, connector, reason, reconnecting=0):
- """Reconnecting subclasses should call with reconnecting=1."""
- if reconnecting:
- # any pending requests will go to next connection attempt
- # so we don't fail them.
- self._broker = None
- self._root = None
- else:
- self._failAll(reason)
-
- def clientConnectionMade(self, broker):
- self._broker = broker
- self._root = broker.remoteForName("root")
- ds = self.rootObjectRequests
- self.rootObjectRequests = []
- for d in ds:
- d.callback(self._root)
-
- def getRootObject(self):
- """Get root object of remote PB server.
-
- @return: Deferred of the root object.
- """
- if self._broker and not self._broker.disconnected:
- return defer.succeed(self._root)
- d = defer.Deferred()
- self.rootObjectRequests.append(d)
- return d
-
- def disconnect(self):
- """If the factory is connected, close the connection.
-
- Note that if you set up the factory to reconnect, you will need to
- implement extra logic to prevent automatic reconnection after this
- is called.
- """
- if self._broker:
- self._broker.transport.loseConnection()
-
- def _cbSendUsername(self, root, username, password, client):
- return root.callRemote("login", username).addCallback(
- self._cbResponse, password, client)
-
- def _cbResponse(self, (challenge, challenger), password, client):
- return challenger.callRemote("respond", respond(challenge, password), client)
-
-
- def _cbLoginAnonymous(self, root, client):
- """
- Attempt an anonymous login on the given remote root object.
-
- @type root: L{RemoteReference}
- @param root: The object on which to attempt the login, most likely
- returned by a call to L{PBClientFactory.getRootObject}.
-
- @param client: A jellyable object which will be used as the I{mind}
- parameter for the login attempt.
-
- @rtype: L{Deferred}
- @return: A L{Deferred} which will be called back with a
- L{RemoteReference} to an avatar when anonymous login succeeds, or
- which will errback if anonymous login fails.
- """
- return root.callRemote("loginAnonymous", client)
-
-
- def login(self, credentials, client=None):
- """
- Login and get perspective from remote PB server.
-
- Currently the following credentials are supported::
-
- L{twisted.cred.credentials.IUsernamePassword}
- L{twisted.cred.credentials.IAnonymous}
-
- @rtype: L{Deferred}
- @return: A L{Deferred} which will be called back with a
- L{RemoteReference} for the avatar logged in to, or which will
- errback if login fails.
- """
- d = self.getRootObject()
-
- if IAnonymous.providedBy(credentials):
- d.addCallback(self._cbLoginAnonymous, client)
- else:
- d.addCallback(
- self._cbSendUsername, credentials.username,
- credentials.password, client)
- return d
-
-
-
-class PBServerFactory(protocol.ServerFactory):
- """
- Server factory for perspective broker.
-
- Login is done using a Portal object, whose realm is expected to return
- avatars implementing IPerspective. The credential checkers in the portal
- should accept IUsernameHashedPassword or IUsernameMD5Password.
-
- Alternatively, any object providing or adaptable to L{IPBRoot} can be
- used instead of a portal to provide the root object of the PB server.
- """
-
- unsafeTracebacks = False
-
- # object broker factory
- protocol = Broker
-
- def __init__(self, root, unsafeTracebacks=False, security=globalSecurity):
- """
- @param root: factory providing the root Referenceable used by the broker.
- @type root: object providing or adaptable to L{IPBRoot}.
-
- @param unsafeTracebacks: if set, tracebacks for exceptions will be sent
- over the wire.
- @type unsafeTracebacks: C{bool}
-
- @param security: security options used by the broker, default to
- C{globalSecurity}.
- @type security: L{twisted.spread.jelly.SecurityOptions}
- """
- self.root = IPBRoot(root)
- self.unsafeTracebacks = unsafeTracebacks
- self.security = security
-
-
- def buildProtocol(self, addr):
- """
- Return a Broker attached to the factory (as the service provider).
- """
- proto = self.protocol(isClient=False, security=self.security)
- proto.factory = self
- proto.setNameForLocal("root", self.root.rootObject(proto))
- return proto
-
- def clientConnectionMade(self, protocol):
- # XXX does this method make any sense?
- pass
-
-
-class IUsernameMD5Password(ICredentials):
- """
- I encapsulate a username and a hashed password.
-
- This credential is used for username/password over PB. CredentialCheckers
- which check this kind of credential must store the passwords in plaintext
- form or as a MD5 digest.
-
- @type username: C{str} or C{Deferred}
- @ivar username: The username associated with these credentials.
- """
-
- def checkPassword(password):
- """
- Validate these credentials against the correct password.
-
- @type password: C{str}
- @param password: The correct, plaintext password against which to
- check.
-
- @rtype: C{bool} or L{Deferred}
- @return: C{True} if the credentials represented by this object match the
- given password, C{False} if they do not, or a L{Deferred} which will
- be called back with one of these values.
- """
-
- def checkMD5Password(password):
- """
- Validate these credentials against the correct MD5 digest of the
- password.
-
- @type password: C{str}
- @param password: The correct MD5 digest of a password against which to
- check.
-
- @rtype: C{bool} or L{Deferred}
- @return: C{True} if the credentials represented by this object match the
- given digest, C{False} if they do not, or a L{Deferred} which will
- be called back with one of these values.
- """
-
-
-class _PortalRoot:
- """Root object, used to login to portal."""
-
- implements(IPBRoot)
-
- def __init__(self, portal):
- self.portal = portal
-
- def rootObject(self, broker):
- return _PortalWrapper(self.portal, broker)
-
-registerAdapter(_PortalRoot, Portal, IPBRoot)
-
-
-
-class _JellyableAvatarMixin:
- """
- Helper class for code which deals with avatars which PB must be capable of
- sending to a peer.
- """
- def _cbLogin(self, (interface, avatar, logout)):
- """
- Ensure that the avatar to be returned to the client is jellyable and
- set up disconnection notification to call the realm's logout object.
- """
- if not IJellyable.providedBy(avatar):
- avatar = AsReferenceable(avatar, "perspective")
-
- puid = avatar.processUniqueID()
-
- # only call logout once, whether the connection is dropped (disconnect)
- # or a logout occurs (cleanup), and be careful to drop the reference to
- # it in either case
- logout = [ logout ]
- def maybeLogout():
- if not logout:
- return
- fn = logout[0]
- del logout[0]
- fn()
- self.broker._localCleanup[puid] = maybeLogout
- self.broker.notifyOnDisconnect(maybeLogout)
-
- return avatar
-
-
-
-class _PortalWrapper(Referenceable, _JellyableAvatarMixin):
- """
- Root Referenceable object, used to login to portal.
- """
-
- def __init__(self, portal, broker):
- self.portal = portal
- self.broker = broker
-
-
- def remote_login(self, username):
- """
- Start of username/password login.
- """
- c = challenge()
- return c, _PortalAuthChallenger(self.portal, self.broker, username, c)
-
-
- def remote_loginAnonymous(self, mind):
- """
- Attempt an anonymous login.
-
- @param mind: An object to use as the mind parameter to the portal login
- call (possibly None).
-
- @rtype: L{Deferred}
- @return: A Deferred which will be called back with an avatar when login
- succeeds or which will be errbacked if login fails somehow.
- """
- d = self.portal.login(Anonymous(), mind, IPerspective)
- d.addCallback(self._cbLogin)
- return d
-
-
-
-class _PortalAuthChallenger(Referenceable, _JellyableAvatarMixin):
- """
- Called with response to password challenge.
- """
- implements(IUsernameHashedPassword, IUsernameMD5Password)
-
- def __init__(self, portal, broker, username, challenge):
- self.portal = portal
- self.broker = broker
- self.username = username
- self.challenge = challenge
-
-
- def remote_respond(self, response, mind):
- self.response = response
- d = self.portal.login(self, mind, IPerspective)
- d.addCallback(self._cbLogin)
- return d
-
-
- # IUsernameHashedPassword:
- def checkPassword(self, password):
- return self.checkMD5Password(md5(password).digest())
-
-
- # IUsernameMD5Password
- def checkMD5Password(self, md5Password):
- md = md5()
- md.update(md5Password)
- md.update(self.challenge)
- correct = md.digest()
- return self.response == correct
-
-
-__all__ = [
- # Everything from flavors is exposed publically here.
- 'IPBRoot', 'Serializable', 'Referenceable', 'NoSuchMethod', 'Root',
- 'ViewPoint', 'Viewable', 'Copyable', 'Jellyable', 'Cacheable',
- 'RemoteCopy', 'RemoteCache', 'RemoteCacheObserver', 'copyTags',
- 'setUnjellyableForClass', 'setUnjellyableFactoryForClass',
- 'setUnjellyableForClassTree',
- 'setCopierForClass', 'setFactoryForClass', 'setCopierForClassTree',
-
- 'MAX_BROKER_REFS', 'portno',
-
- 'ProtocolError', 'DeadReferenceError', 'Error', 'PBConnectionLost',
- 'RemoteMethod', 'IPerspective', 'Avatar', 'AsReferenceable',
- 'RemoteReference', 'CopyableFailure', 'CopiedFailure', 'failure2Copyable',
- 'Broker', 'respond', 'challenge', 'PBClientFactory', 'PBServerFactory',
- 'IUsernameMD5Password',
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/publish.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/publish.py
deleted file mode 100755
index 5bc18687..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/publish.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# -*- test-case-name: twisted.test.test_pb -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Persistently cached objects for PB.
-
-Maintainer: Glyph Lefkowitz
-
-Future Plans: None known.
-"""
-
-import time
-
-from twisted.internet import defer
-from twisted.spread import banana, jelly, flavors
-
-
-class Publishable(flavors.Cacheable):
- """An object whose cached state persists across sessions.
- """
- def __init__(self, publishedID):
- self.republish()
- self.publishedID = publishedID
-
- def republish(self):
- """Set the timestamp to current and (TODO) update all observers.
- """
- self.timestamp = time.time()
-
- def view_getStateToPublish(self, perspective):
- '(internal)'
- return self.getStateToPublishFor(perspective)
-
- def getStateToPublishFor(self, perspective):
- """Implement me to special-case your state for a perspective.
- """
- return self.getStateToPublish()
-
- def getStateToPublish(self):
- """Implement me to return state to copy as part of the publish phase.
- """
- raise NotImplementedError("%s.getStateToPublishFor" % self.__class__)
-
- def getStateToCacheAndObserveFor(self, perspective, observer):
- """Get all necessary metadata to keep a clientside cache.
- """
- if perspective:
- pname = perspective.perspectiveName
- sname = perspective.getService().serviceName
- else:
- pname = "None"
- sname = "None"
-
- return {"remote": flavors.ViewPoint(perspective, self),
- "publishedID": self.publishedID,
- "perspective": pname,
- "service": sname,
- "timestamp": self.timestamp}
-
-class RemotePublished(flavors.RemoteCache):
- """The local representation of remote Publishable object.
- """
- isActivated = 0
- _wasCleanWhenLoaded = 0
- def getFileName(self, ext='pub'):
- return ("%s-%s-%s.%s" %
- (self.service, self.perspective, str(self.publishedID), ext))
-
- def setCopyableState(self, state):
- self.__dict__.update(state)
- self._activationListeners = []
- try:
- dataFile = file(self.getFileName(), "rb")
- data = dataFile.read()
- dataFile.close()
- except IOError:
- recent = 0
- else:
- newself = jelly.unjelly(banana.decode(data))
- recent = (newself.timestamp == self.timestamp)
- if recent:
- self._cbGotUpdate(newself.__dict__)
- self._wasCleanWhenLoaded = 1
- else:
- self.remote.callRemote('getStateToPublish').addCallbacks(self._cbGotUpdate)
-
- def __getstate__(self):
- other = self.__dict__.copy()
- # Remove PB-specific attributes
- del other['broker']
- del other['remote']
- del other['luid']
- # remove my own runtime-tracking stuff
- del other['_activationListeners']
- del other['isActivated']
- return other
-
- def _cbGotUpdate(self, newState):
- self.__dict__.update(newState)
- self.isActivated = 1
- # send out notifications
- for listener in self._activationListeners:
- listener(self)
- self._activationListeners = []
- self.activated()
- dataFile = file(self.getFileName(), "wb")
- dataFile.write(banana.encode(jelly.jelly(self)))
- dataFile.close()
-
-
- def activated(self):
- """Implement this method if you want to be notified when your
- publishable subclass is activated.
- """
-
- def callWhenActivated(self, callback):
- """Externally register for notification when this publishable has received all relevant data.
- """
- if self.isActivated:
- callback(self)
- else:
- self._activationListeners.append(callback)
-
-def whenReady(d):
- """
- Wrap a deferred returned from a pb method in another deferred that
- expects a RemotePublished as a result. This will allow you to wait until
- the result is really available.
-
- Idiomatic usage would look like::
-
- publish.whenReady(serverObject.getMeAPublishable()).addCallback(lookAtThePublishable)
- """
- d2 = defer.Deferred()
- d.addCallbacks(_pubReady, d2.errback,
- callbackArgs=(d2,))
- return d2
-
-def _pubReady(result, d2):
- '(internal)'
- result.callWhenActivated(d2.callback)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/__init__.py
deleted file mode 100755
index 56bf7664..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Spread UI: UI utilities for various toolkits connecting to PB.
-"""
-
-# Undeprecating this until someone figures out a real plan for alternatives to spread.ui.
-##import warnings
-##warnings.warn("twisted.spread.ui is deprecated. Please do not use.", DeprecationWarning)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/gtk2util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/gtk2util.py
deleted file mode 100755
index a576388e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/gtk2util.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import gtk
-
-from twisted import copyright
-from twisted.internet import defer
-from twisted.python import failure, log, util
-from twisted.spread import pb
-from twisted.cred.credentials import UsernamePassword
-
-from twisted.internet import error as netError
-
-def login(client=None, **defaults):
- """
- @param host:
- @param port:
- @param identityName:
- @param password:
- @param serviceName:
- @param perspectiveName:
-
- @returntype: Deferred RemoteReference of Perspective
- """
- d = defer.Deferred()
- LoginDialog(client, d, defaults)
- return d
-
-class GladeKeeper:
- """
- @cvar gladefile: The file in which the glade GUI definition is kept.
- @type gladefile: str
-
- @cvar _widgets: Widgets that should be attached to me as attributes.
- @type _widgets: list of strings
- """
-
- gladefile = None
- _widgets = ()
-
- def __init__(self):
- from gtk import glade
- self.glade = glade.XML(self.gladefile)
-
- # mold can go away when we get a newer pygtk (post 1.99.14)
- mold = {}
- for k in dir(self):
- mold[k] = getattr(self, k)
- self.glade.signal_autoconnect(mold)
- self._setWidgets()
-
- def _setWidgets(self):
- get_widget = self.glade.get_widget
- for widgetName in self._widgets:
- setattr(self, "_" + widgetName, get_widget(widgetName))
-
-
-class LoginDialog(GladeKeeper):
- # IdentityConnector host port identityName password
- # requestLogin -> identityWrapper or login failure
- # requestService serviceName perspectiveName client
-
- # window killed
- # cancel button pressed
- # login button activated
-
- fields = ['host','port','identityName','password',
- 'perspectiveName']
-
- _widgets = ("hostEntry", "portEntry", "identityNameEntry", "passwordEntry",
- "perspectiveNameEntry", "statusBar",
- "loginDialog")
-
- _advancedControls = ['perspectiveLabel', 'perspectiveNameEntry',
- 'protocolLabel', 'versionLabel']
-
- gladefile = util.sibpath(__file__, "login2.glade")
-
- _timeoutID = None
-
- def __init__(self, client, deferred, defaults):
- self.client = client
- self.deferredResult = deferred
-
- GladeKeeper.__init__(self)
-
- self.setDefaults(defaults)
- self._loginDialog.show()
-
-
- def setDefaults(self, defaults):
- if not defaults.has_key('port'):
- defaults['port'] = str(pb.portno)
- elif isinstance(defaults['port'], (int, long)):
- defaults['port'] = str(defaults['port'])
-
- for k, v in defaults.iteritems():
- if k in self.fields:
- widget = getattr(self, "_%sEntry" % (k,))
- widget.set_text(v)
-
- def _setWidgets(self):
- GladeKeeper._setWidgets(self)
- self._statusContext = self._statusBar.get_context_id("Login dialog.")
- get_widget = self.glade.get_widget
- get_widget("versionLabel").set_text(copyright.longversion)
- get_widget("protocolLabel").set_text("Protocol PB-%s" %
- (pb.Broker.version,))
-
- def _on_loginDialog_response(self, widget, response):
- handlers = {gtk.RESPONSE_NONE: self._windowClosed,
- gtk.RESPONSE_DELETE_EVENT: self._windowClosed,
- gtk.RESPONSE_OK: self._doLogin,
- gtk.RESPONSE_CANCEL: self._cancelled}
- handler = handlers.get(response)
- if handler is not None:
- handler()
- else:
- log.msg("Unexpected dialog response %r from %s" % (response,
- widget))
-
- def _on_loginDialog_close(self, widget, userdata=None):
- self._windowClosed()
-
- def _on_loginDialog_destroy_event(self, widget, userdata=None):
- self._windowClosed()
-
- def _cancelled(self):
- if not self.deferredResult.called:
- self.deferredResult.errback(netError.UserError("User hit Cancel."))
- self._loginDialog.destroy()
-
- def _windowClosed(self, reason=None):
- if not self.deferredResult.called:
- self.deferredResult.errback(netError.UserError("Window closed."))
-
- def _doLogin(self):
- idParams = {}
-
- idParams['host'] = self._hostEntry.get_text()
- idParams['port'] = self._portEntry.get_text()
- idParams['identityName'] = self._identityNameEntry.get_text()
- idParams['password'] = self._passwordEntry.get_text()
-
- try:
- idParams['port'] = int(idParams['port'])
- except ValueError:
- pass
-
- f = pb.PBClientFactory()
- from twisted.internet import reactor
- reactor.connectTCP(idParams['host'], idParams['port'], f)
- creds = UsernamePassword(idParams['identityName'], idParams['password'])
- d = f.login(creds, self.client)
- def _timeoutLogin():
- self._timeoutID = None
- d.errback(failure.Failure(defer.TimeoutError("Login timed out.")))
- self._timeoutID = reactor.callLater(30, _timeoutLogin)
- d.addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
- self.statusMsg("Contacting server...")
-
- # serviceName = self._serviceNameEntry.get_text()
- # perspectiveName = self._perspectiveNameEntry.get_text()
- # if not perspectiveName:
- # perspectiveName = idParams['identityName']
-
- # d = _identityConnector.requestService(serviceName, perspectiveName,
- # self.client)
- # d.addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
- # setCursor to waiting
-
- def _cbGotPerspective(self, perspective):
- self.statusMsg("Connected to server.")
- if self._timeoutID is not None:
- self._timeoutID.cancel()
- self._timeoutID = None
- self.deferredResult.callback(perspective)
- # clear waiting cursor
- self._loginDialog.destroy()
-
- def _ebFailedLogin(self, reason):
- if isinstance(reason, failure.Failure):
- reason = reason.value
- self.statusMsg(reason)
- if isinstance(reason, (unicode, str)):
- text = reason
- else:
- text = unicode(reason)
- msg = gtk.MessageDialog(self._loginDialog,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- text)
- msg.show_all()
- msg.connect("response", lambda *a: msg.destroy())
-
- # hostname not found
- # host unreachable
- # connection refused
- # authentication failed
- # no such service
- # no such perspective
- # internal server error
-
- def _on_advancedButton_toggled(self, widget, userdata=None):
- active = widget.get_active()
- if active:
- op = "show"
- else:
- op = "hide"
- for widgetName in self._advancedControls:
- widget = self.glade.get_widget(widgetName)
- getattr(widget, op)()
-
- def statusMsg(self, text):
- if not isinstance(text, (unicode, str)):
- text = unicode(text)
- return self._statusBar.push(self._statusContext, text)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/login2.glade b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/login2.glade
deleted file mode 100644
index af8c53da..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/login2.glade
+++ /dev/null
@@ -1,461 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkDialog" id="loginDialog">
- <property name="title" translatable="yes">Login</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">True</property>
- <property name="has_separator">True</property>
- <signal name="response" handler="_on_loginDialog_response" last_modification_time="Sat, 25 Jan 2003 13:52:57 GMT"/>
- <signal name="close" handler="_on_loginDialog_close" last_modification_time="Sat, 25 Jan 2003 13:53:04 GMT"/>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="cancelbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="response_id">-6</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="loginButton">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="response_id">-5</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-ok</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Login</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkStatusbar" id="statusBar">
- <property name="visible">True</property>
- <property name="has_resize_grip">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">6</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="hostLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Host:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.9</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">hostEntry</property>
- <accessibility>
- <atkrelation target="hostEntry" type="label-for"/>
- <atkrelation target="portEntry" type="label-for"/>
- </accessibility>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkEntry" id="hostEntry">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">The name of a host to connect to.</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">localhost</property>
- <property name="has_frame">True</property>
- <property name="invisible_char" translatable="yes">*</property>
- <property name="activates_default">True</property>
- <accessibility>
- <atkrelation target="hostLabel" type="labelled-by"/>
- </accessibility>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="portEntry">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">The number of a port to connect on.</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">8787</property>
- <property name="has_frame">True</property>
- <property name="invisible_char" translatable="yes">*</property>
- <property name="activates_default">True</property>
- <property name="width_chars">5</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="nameLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.9</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">identityNameEntry</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="identityNameEntry">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">An identity to log in as.</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char" translatable="yes">*</property>
- <property name="activates_default">True</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="passwordEntry">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">The Identity's log-in password.</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">False</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char" translatable="yes">*</property>
- <property name="activates_default">True</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="passwordLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Password:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.9</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">passwordEntry</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="perspectiveLabel">
- <property name="label" translatable="yes">Perspective:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.9</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="perspectiveNameEntry">
- <property name="tooltip" translatable="yes">The name of a Perspective to request.</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char" translatable="yes">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="protocolLabel">
- <property name="label" translatable="yes">Insert Protocol Version Here</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="versionLabel">
- <property name="label" translatable="yes">Insert Twisted Version Here</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">1</property>
-
- <child>
- <widget class="GtkToggleButton" id="advancedButton">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Advanced options.</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Advanced &gt;&gt;</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <signal name="toggled" handler="_on_advancedButton_toggled" object="Login" last_modification_time="Sat, 25 Jan 2003 13:47:17 GMT"/>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tktree.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tktree.py
deleted file mode 100755
index 8fbe4624..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tktree.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-What I want it to look like:
-
-+- One
-| \- Two
-| |- Three
-| |- Four
-| +- Five
-| | \- Six
-| |- Seven
-+- Eight
-| \- Nine
-"""
-
-import os
-from Tkinter import *
-
-class Node:
- def __init__(self):
- """
- Do whatever you want here.
- """
- self.item=None
- def getName(self):
- """
- Return the name of this node in the tree.
- """
- pass
- def isExpandable(self):
- """
- Return true if this node is expandable.
- """
- return len(self.getSubNodes())>0
- def getSubNodes(self):
- """
- Return the sub nodes of this node.
- """
- return []
- def gotDoubleClick(self):
- """
- Called when we are double clicked.
- """
- pass
- def updateMe(self):
- """
- Call me when something about me changes, so that my representation
- changes.
- """
- if self.item:
- self.item.update()
-
-class FileNode(Node):
- def __init__(self,name):
- Node.__init__(self)
- self.name=name
- def getName(self):
- return os.path.basename(self.name)
- def isExpandable(self):
- return os.path.isdir(self.name)
- def getSubNodes(self):
- names=map(lambda x,n=self.name:os.path.join(n,x),os.listdir(self.name))
- return map(FileNode,names)
-
-class TreeItem:
- def __init__(self,widget,parent,node):
- self.widget=widget
- self.node=node
- node.item=self
- if self.node.isExpandable():
- self.expand=0
- else:
- self.expand=None
- self.parent=parent
- if parent:
- self.level=self.parent.level+1
- else:
- self.level=0
- self.first=0 # gets set in Tree.expand()
- self.subitems=[]
- def __del__(self):
- del self.node
- del self.widget
- def __repr__(self):
- return "<Item for Node %s at level %s>"%(self.node.getName(),self.level)
- def render(self):
- """
- Override in a subclass.
- """
- raise NotImplementedError
- def update(self):
- self.widget.update(self)
-
-class ListboxTreeItem(TreeItem):
- def render(self):
- start=self.level*"| "
- if self.expand==None and not self.first:
- start=start+"|"
- elif self.expand==0:
- start=start+"L"
- elif self.expand==1:
- start=start+"+"
- else:
- start=start+"\\"
- r=[start+"- "+self.node.getName()]
- if self.expand:
- for i in self.subitems:
- r.extend(i.render())
- return r
-
-class ListboxTree:
- def __init__(self,parent=None,**options):
- self.box=apply(Listbox,[parent],options)
- self.box.bind("<Double-1>",self.flip)
- self.roots=[]
- self.items=[]
- def pack(self,*args,**kw):
- """
- for packing.
- """
- apply(self.box.pack,args,kw)
- def grid(self,*args,**kw):
- """
- for gridding.
- """
- apply(self.box.grid,args,kw)
- def yview(self,*args,**kw):
- """
- for scrolling.
- """
- apply(self.box.yview,args,kw)
- def addRoot(self,node):
- r=ListboxTreeItem(self,None,node)
- self.roots.append(r)
- self.items.append(r)
- self.box.insert(END,r.render()[0])
- return r
- def curselection(self):
- c=self.box.curselection()
- if not c: return
- return self.items[int(c[0])]
- def flip(self,*foo):
- if not self.box.curselection(): return
- item=self.items[int(self.box.curselection()[0])]
- if item.expand==None: return
- if not item.expand:
- self.expand(item)
- else:
- self.close(item)
- item.node.gotDoubleClick()
- def expand(self,item):
- if item.expand or item.expand==None: return
- item.expand=1
- item.subitems=map(lambda x,i=item,s=self:ListboxTreeItem(s,i,x),item.node.getSubNodes())
- if item.subitems:
- item.subitems[0].first=1
- i=self.items.index(item)
- self.items,after=self.items[:i+1],self.items[i+1:]
- self.items=self.items+item.subitems+after
- c=self.items.index(item)
- self.box.delete(c)
- r=item.render()
- for i in r:
- self.box.insert(c,i)
- c=c+1
- def close(self,item):
- if not item.expand: return
- item.expand=0
- length=len(item.subitems)
- for i in item.subitems:
- self.close(i)
- c=self.items.index(item)
- del self.items[c+1:c+1+length]
- for i in range(length+1):
- self.box.delete(c)
- self.box.insert(c,item.render()[0])
- def remove(self,item):
- if item.expand:
- self.close(item)
- c=self.items.index(item)
- del self.items[c]
- if item.parent:
- item.parent.subitems.remove(item)
- self.box.delete(c)
- def update(self,item):
- if item.expand==None:
- c=self.items.index(item)
- self.box.delete(c)
- self.box.insert(c,item.render()[0])
- elif item.expand:
- self.close(item)
- self.expand(item)
-
-if __name__=="__main__":
- tk=Tk()
- s=Scrollbar()
- t=ListboxTree(tk,yscrollcommand=s.set)
- t.pack(side=LEFT,fill=BOTH)
- s.config(command=t.yview)
- s.pack(side=RIGHT,fill=Y)
- t.addRoot(FileNode("C:/"))
- #mainloop()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tkutil.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tkutil.py
deleted file mode 100755
index 2aee67d6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/ui/tkutil.py
+++ /dev/null
@@ -1,397 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""Utilities for building L{PB<twisted.spread.pb>} clients with L{Tkinter}.
-"""
-from Tkinter import *
-from tkSimpleDialog import _QueryString
-from tkFileDialog import _Dialog
-from twisted.spread import pb
-from twisted.internet import reactor
-from twisted import copyright
-
-import string
-
-#normalFont = Font("-adobe-courier-medium-r-normal-*-*-120-*-*-m-*-iso8859-1")
-#boldFont = Font("-adobe-courier-bold-r-normal-*-*-120-*-*-m-*-iso8859-1")
-#errorFont = Font("-adobe-courier-medium-o-normal-*-*-120-*-*-m-*-iso8859-1")
-
-class _QueryPassword(_QueryString):
- def body(self, master):
-
- w = Label(master, text=self.prompt, justify=LEFT)
- w.grid(row=0, padx=5, sticky=W)
-
- self.entry = Entry(master, name="entry",show="*")
- self.entry.grid(row=1, padx=5, sticky=W+E)
-
- if self.initialvalue:
- self.entry.insert(0, self.initialvalue)
- self.entry.select_range(0, END)
-
- return self.entry
-
-def askpassword(title, prompt, **kw):
- '''get a password from the user
-
- @param title: the dialog title
- @param prompt: the label text
- @param **kw: see L{SimpleDialog} class
-
- @returns: a string
- '''
- d = apply(_QueryPassword, (title, prompt), kw)
- return d.result
-
-def grid_setexpand(widget):
- cols,rows=widget.grid_size()
- for i in range(cols):
- widget.columnconfigure(i,weight=1)
- for i in range(rows):
- widget.rowconfigure(i,weight=1)
-
-class CList(Frame):
- def __init__(self,parent,labels,disablesorting=0,**kw):
- Frame.__init__(self,parent)
- self.labels=labels
- self.lists=[]
- self.disablesorting=disablesorting
- kw["exportselection"]=0
- for i in range(len(labels)):
- b=Button(self,text=labels[i],anchor=W,height=1,pady=0)
- b.config(command=lambda s=self,i=i:s.setSort(i))
- b.grid(column=i,row=0,sticky=N+E+W)
- box=apply(Listbox,(self,),kw)
- box.grid(column=i,row=1,sticky=N+E+S+W)
- self.lists.append(box)
- grid_setexpand(self)
- self.rowconfigure(0,weight=0)
- self._callall("bind",'<Button-1>',self.Button1)
- self._callall("bind",'<B1-Motion>',self.Button1)
- self.bind('<Up>',self.UpKey)
- self.bind('<Down>',self.DownKey)
- self.sort=None
-
- def _callall(self,funcname,*args,**kw):
- rets=[]
- for l in self.lists:
- func=getattr(l,funcname)
- ret=apply(func,args,kw)
- if ret!=None: rets.append(ret)
- if rets: return rets
-
- def Button1(self,e):
- index=self.nearest(e.y)
- self.select_clear(0,END)
- self.select_set(index)
- self.activate(index)
- return "break"
-
- def UpKey(self,e):
- index=self.index(ACTIVE)
- if index:
- self.select_clear(0,END)
- self.select_set(index-1)
- return "break"
-
- def DownKey(self,e):
- index=self.index(ACTIVE)
- if index!=self.size()-1:
- self.select_clear(0,END)
- self.select_set(index+1)
- return "break"
-
- def setSort(self,index):
- if self.sort==None:
- self.sort=[index,1]
- elif self.sort[0]==index:
- self.sort[1]=-self.sort[1]
- else:
- self.sort=[index,1]
- self._sort()
-
- def _sort(self):
- if self.disablesorting:
- return
- if self.sort==None:
- return
- ind,direc=self.sort
- li=list(self.get(0,END))
- li.sort(lambda x,y,i=ind,d=direc:d*cmp(x[i],y[i]))
- self.delete(0,END)
- for l in li:
- self._insert(END,l)
- def activate(self,index):
- self._callall("activate",index)
-
- # def bbox(self,index):
- # return self._callall("bbox",index)
-
- def curselection(self):
- return self.lists[0].curselection()
-
- def delete(self,*args):
- apply(self._callall,("delete",)+args)
-
- def get(self,*args):
- bad=apply(self._callall,("get",)+args)
- if len(args)==1:
- return bad
- ret=[]
- for i in range(len(bad[0])):
- r=[]
- for j in range(len(bad)):
- r.append(bad[j][i])
- ret.append(r)
- return ret
-
- def index(self,index):
- return self.lists[0].index(index)
-
- def insert(self,index,items):
- self._insert(index,items)
- self._sort()
-
- def _insert(self,index,items):
- for i in range(len(items)):
- self.lists[i].insert(index,items[i])
-
- def nearest(self,y):
- return self.lists[0].nearest(y)
-
- def see(self,index):
- self._callall("see",index)
-
- def size(self):
- return self.lists[0].size()
-
- def selection_anchor(self,index):
- self._callall("selection_anchor",index)
-
- select_anchor=selection_anchor
-
- def selection_clear(self,*args):
- apply(self._callall,("selection_clear",)+args)
-
- select_clear=selection_clear
-
- def selection_includes(self,index):
- return self.lists[0].select_includes(index)
-
- select_includes=selection_includes
-
- def selection_set(self,*args):
- apply(self._callall,("selection_set",)+args)
-
- select_set=selection_set
-
- def xview(self,*args):
- if not args: return self.lists[0].xview()
- apply(self._callall,("xview",)+args)
-
- def yview(self,*args):
- if not args: return self.lists[0].yview()
- apply(self._callall,("yview",)+args)
-
-class ProgressBar:
- def __init__(self, master=None, orientation="horizontal",
- min=0, max=100, width=100, height=18,
- doLabel=1, appearance="sunken",
- fillColor="blue", background="gray",
- labelColor="yellow", labelFont="Verdana",
- labelText="", labelFormat="%d%%",
- value=0, bd=2):
- # preserve various values
- self.master=master
- self.orientation=orientation
- self.min=min
- self.max=max
- self.width=width
- self.height=height
- self.doLabel=doLabel
- self.fillColor=fillColor
- self.labelFont= labelFont
- self.labelColor=labelColor
- self.background=background
- self.labelText=labelText
- self.labelFormat=labelFormat
- self.value=value
- self.frame=Frame(master, relief=appearance, bd=bd)
- self.canvas=Canvas(self.frame, height=height, width=width, bd=0,
- highlightthickness=0, background=background)
- self.scale=self.canvas.create_rectangle(0, 0, width, height,
- fill=fillColor)
- self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
- height / 2, text=labelText,
- anchor="c", fill=labelColor,
- font=self.labelFont)
- self.update()
- self.canvas.pack(side='top', fill='x', expand='no')
-
- def updateProgress(self, newValue, newMax=None):
- if newMax:
- self.max = newMax
- self.value = newValue
- self.update()
-
- def update(self):
- # Trim the values to be between min and max
- value=self.value
- if value > self.max:
- value = self.max
- if value < self.min:
- value = self.min
- # Adjust the rectangle
- if self.orientation == "horizontal":
- self.canvas.coords(self.scale, 0, 0,
- float(value) / self.max * self.width, self.height)
- else:
- self.canvas.coords(self.scale, 0,
- self.height - (float(value) /
- self.max*self.height),
- self.width, self.height)
- # Now update the colors
- self.canvas.itemconfig(self.scale, fill=self.fillColor)
- self.canvas.itemconfig(self.label, fill=self.labelColor)
- # And update the label
- if self.doLabel:
- if value:
- if value >= 0:
- pvalue = int((float(value) / float(self.max)) *
- 100.0)
- else:
- pvalue = 0
- self.canvas.itemconfig(self.label, text=self.labelFormat
- % pvalue)
- else:
- self.canvas.itemconfig(self.label, text='')
- else:
- self.canvas.itemconfig(self.label, text=self.labelFormat %
- self.labelText)
- self.canvas.update_idletasks()
-
-class DirectoryBrowser(_Dialog):
- command = "tk_chooseDirectory"
-
-def askdirectory(**options):
- "Ask for a directory to save to."
-
- return apply(DirectoryBrowser, (), options).show()
-
-class GenericLogin(Toplevel):
- def __init__(self,callback,buttons):
- Toplevel.__init__(self)
- self.callback=callback
- Label(self,text="Twisted v%s"%copyright.version).grid(column=0,row=0,columnspan=2)
- self.entries={}
- row=1
- for stuff in buttons:
- label,value=stuff[:2]
- if len(stuff)==3:
- dict=stuff[2]
- else: dict={}
- Label(self,text=label+": ").grid(column=0,row=row)
- e=apply(Entry,(self,),dict)
- e.grid(column=1,row=row)
- e.insert(0,value)
- self.entries[label]=e
- row=row+1
- Button(self,text="Login",command=self.doLogin).grid(column=0,row=row)
- Button(self,text="Cancel",command=self.close).grid(column=1,row=row)
- self.protocol('WM_DELETE_WINDOW',self.close)
-
- def close(self):
- self.tk.quit()
- self.destroy()
-
- def doLogin(self):
- values={}
- for k in self.entries.keys():
- values[string.lower(k)]=self.entries[k].get()
- self.callback(values)
- self.destroy()
-
-class Login(Toplevel):
- def __init__(self,
- callback,
- referenced = None,
- initialUser = "guest",
- initialPassword = "guest",
- initialHostname = "localhost",
- initialService = "",
- initialPortno = pb.portno):
- Toplevel.__init__(self)
- version_label = Label(self,text="Twisted v%s" % copyright.version)
- self.pbReferenceable = referenced
- self.pbCallback = callback
- # version_label.show()
- self.username = Entry(self)
- self.password = Entry(self,show='*')
- self.hostname = Entry(self)
- self.service = Entry(self)
- self.port = Entry(self)
-
- self.username.insert(0,initialUser)
- self.password.insert(0,initialPassword)
- self.service.insert(0,initialService)
- self.hostname.insert(0,initialHostname)
- self.port.insert(0,str(initialPortno))
-
- userlbl=Label(self,text="Username:")
- passlbl=Label(self,text="Password:")
- servicelbl=Label(self,text="Service:")
- hostlbl=Label(self,text="Hostname:")
- portlbl=Label(self,text="Port #:")
- self.logvar=StringVar()
- self.logvar.set("Protocol PB-%s"%pb.Broker.version)
- self.logstat = Label(self,textvariable=self.logvar)
- self.okbutton = Button(self,text="Log In", command=self.login)
-
- version_label.grid(column=0,row=0,columnspan=2)
- z=0
- for i in [[userlbl,self.username],
- [passlbl,self.password],
- [hostlbl,self.hostname],
- [servicelbl,self.service],
- [portlbl,self.port]]:
- i[0].grid(column=0,row=z+1)
- i[1].grid(column=1,row=z+1)
- z = z+1
-
- self.logstat.grid(column=0,row=6,columnspan=2)
- self.okbutton.grid(column=0,row=7,columnspan=2)
-
- self.protocol('WM_DELETE_WINDOW',self.tk.quit)
-
- def loginReset(self):
- self.logvar.set("Idle.")
-
- def loginReport(self, txt):
- self.logvar.set(txt)
- self.after(30000, self.loginReset)
-
- def login(self):
- host = self.hostname.get()
- port = self.port.get()
- service = self.service.get()
- try:
- port = int(port)
- except:
- pass
- user = self.username.get()
- pswd = self.password.get()
- pb.connect(host, port, user, pswd, service,
- client=self.pbReferenceable).addCallback(self.pbCallback).addErrback(
- self.couldNotConnect)
-
- def couldNotConnect(self,f):
- self.loginReport("could not connect:"+f.getErrorMessage())
-
-if __name__=="__main__":
- root=Tk()
- o=CList(root,["Username","Online","Auto-Logon","Gateway"])
- o.pack()
- for i in range(0,16,4):
- o.insert(END,[i,i+1,i+2,i+3])
- mainloop()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/util.py
deleted file mode 100755
index 3c529b4e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/spread/util.py
+++ /dev/null
@@ -1,215 +0,0 @@
-# -*- test-case-name: twisted.test.test_pb -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Utility classes for spread.
-"""
-
-from twisted.internet import defer
-from twisted.python.failure import Failure
-from twisted.spread import pb
-from twisted.protocols import basic
-from twisted.internet import interfaces
-
-from zope.interface import implements
-
-
-class LocalMethod:
- def __init__(self, local, name):
- self.local = local
- self.name = name
-
- def __call__(self, *args, **kw):
- return self.local.callRemote(self.name, *args, **kw)
-
-
-class LocalAsRemote:
- """
- A class useful for emulating the effects of remote behavior locally.
- """
- reportAllTracebacks = 1
-
- def callRemote(self, name, *args, **kw):
- """
- Call a specially-designated local method.
-
- self.callRemote('x') will first try to invoke a method named
- sync_x and return its result (which should probably be a
- Deferred). Second, it will look for a method called async_x,
- which will be called and then have its result (or Failure)
- automatically wrapped in a Deferred.
- """
- if hasattr(self, 'sync_'+name):
- return getattr(self, 'sync_'+name)(*args, **kw)
- try:
- method = getattr(self, "async_" + name)
- return defer.succeed(method(*args, **kw))
- except:
- f = Failure()
- if self.reportAllTracebacks:
- f.printTraceback()
- return defer.fail(f)
-
- def remoteMethod(self, name):
- return LocalMethod(self, name)
-
-
-class LocalAsyncForwarder:
- """
- A class useful for forwarding a locally-defined interface.
- """
-
- def __init__(self, forwarded, interfaceClass, failWhenNotImplemented=0):
- assert interfaceClass.providedBy(forwarded)
- self.forwarded = forwarded
- self.interfaceClass = interfaceClass
- self.failWhenNotImplemented = failWhenNotImplemented
-
- def _callMethod(self, method, *args, **kw):
- return getattr(self.forwarded, method)(*args, **kw)
-
- def callRemote(self, method, *args, **kw):
- if self.interfaceClass.queryDescriptionFor(method):
- result = defer.maybeDeferred(self._callMethod, method, *args, **kw)
- return result
- elif self.failWhenNotImplemented:
- return defer.fail(
- Failure(NotImplementedError,
- "No Such Method in Interface: %s" % method))
- else:
- return defer.succeed(None)
-
-
-class Pager:
- """
- I am an object which pages out information.
- """
- def __init__(self, collector, callback=None, *args, **kw):
- """
- Create a pager with a Reference to a remote collector and
- an optional callable to invoke upon completion.
- """
- if callable(callback):
- self.callback = callback
- self.callbackArgs = args
- self.callbackKeyword = kw
- else:
- self.callback = None
- self._stillPaging = 1
- self.collector = collector
- collector.broker.registerPageProducer(self)
-
- def stillPaging(self):
- """
- (internal) Method called by Broker.
- """
- if not self._stillPaging:
- self.collector.callRemote("endedPaging")
- if self.callback is not None:
- self.callback(*self.callbackArgs, **self.callbackKeyword)
- return self._stillPaging
-
- def sendNextPage(self):
- """
- (internal) Method called by Broker.
- """
- self.collector.callRemote("gotPage", self.nextPage())
-
- def nextPage(self):
- """
- Override this to return an object to be sent to my collector.
- """
- raise NotImplementedError()
-
- def stopPaging(self):
- """
- Call this when you're done paging.
- """
- self._stillPaging = 0
-
-
-class StringPager(Pager):
- """
- A simple pager that splits a string into chunks.
- """
- def __init__(self, collector, st, chunkSize=8192, callback=None, *args, **kw):
- self.string = st
- self.pointer = 0
- self.chunkSize = chunkSize
- Pager.__init__(self, collector, callback, *args, **kw)
-
- def nextPage(self):
- val = self.string[self.pointer:self.pointer+self.chunkSize]
- self.pointer += self.chunkSize
- if self.pointer >= len(self.string):
- self.stopPaging()
- return val
-
-
-class FilePager(Pager):
- """
- Reads a file in chunks and sends the chunks as they come.
- """
- implements(interfaces.IConsumer)
-
- def __init__(self, collector, fd, callback=None, *args, **kw):
- self.chunks = []
- Pager.__init__(self, collector, callback, *args, **kw)
- self.startProducing(fd)
-
- def startProducing(self, fd):
- self.deferred = basic.FileSender().beginFileTransfer(fd, self)
- self.deferred.addBoth(lambda x : self.stopPaging())
-
- def registerProducer(self, producer, streaming):
- self.producer = producer
- if not streaming:
- self.producer.resumeProducing()
-
- def unregisterProducer(self):
- self.producer = None
-
- def write(self, chunk):
- self.chunks.append(chunk)
-
- def sendNextPage(self):
- """
- Get the first chunk read and send it to collector.
- """
- if not self.chunks:
- return
- val = self.chunks.pop(0)
- self.producer.resumeProducing()
- self.collector.callRemote("gotPage", val)
-
-
-# Utility paging stuff.
-class CallbackPageCollector(pb.Referenceable):
- """
- I receive pages from the peer. You may instantiate a Pager with a
- remote reference to me. I will call the callback with a list of pages
- once they are all received.
- """
- def __init__(self, callback):
- self.pages = []
- self.callback = callback
-
- def remote_gotPage(self, page):
- self.pages.append(page)
-
- def remote_endedPaging(self):
- self.callback(self.pages)
-
-
-def getAllPages(referenceable, methodName, *args, **kw):
- """
- A utility method that will call a remote method which expects a
- PageCollector as the first argument.
- """
- d = defer.Deferred()
- referenceable.callRemote(methodName, CallbackPageCollector(d.callback), *args, **kw)
- return d
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/__init__.py
deleted file mode 100755
index 37361070..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-
-Twisted TAP: Twisted Application Persistence builders for other Twisted servers.
-
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/ftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/ftp.py
deleted file mode 100755
index 735ab4bd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/ftp.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- test-case-name: twisted.test.test_ftp_options -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-I am the support module for making a ftp server with twistd.
-"""
-
-from twisted.application import internet
-from twisted.cred import portal, checkers, strcred
-from twisted.protocols import ftp
-
-from twisted.python import usage, deprecate, versions
-
-import warnings
-
-
-
-class Options(usage.Options, strcred.AuthOptionMixin):
- synopsis = """[options].
- WARNING: This FTP server is probably INSECURE do not use it.
- """
- optParameters = [
- ["port", "p", "2121", "set the port number"],
- ["root", "r", "/usr/local/ftp", "define the root of the ftp-site."],
- ["userAnonymous", "", "anonymous", "Name of the anonymous user."]
- ]
-
- compData = usage.Completions(
- optActions={"root": usage.CompleteDirs(descr="root of the ftp site")}
- )
-
- longdesc = ''
-
- def __init__(self, *a, **kw):
- usage.Options.__init__(self, *a, **kw)
- self.addChecker(checkers.AllowAnonymousAccess())
-
-
- def opt_password_file(self, filename):
- """
- Specify a file containing username:password login info for
- authenticated connections. (DEPRECATED; see --help-auth instead)
- """
- self['password-file'] = filename
- msg = deprecate.getDeprecationWarningString(
- self.opt_password_file, versions.Version('Twisted', 11, 1, 0))
- warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
- self.addChecker(checkers.FilePasswordDB(filename, cache=True))
-
-
-
-def makeService(config):
- f = ftp.FTPFactory()
-
- r = ftp.FTPRealm(config['root'])
- p = portal.Portal(r, config.get('credCheckers', []))
-
- f.tld = config['root']
- f.userAnonymous = config['userAnonymous']
- f.portal = p
- f.protocol = ftp.FTP
-
- try:
- portno = int(config['port'])
- except KeyError:
- portno = 2121
- return internet.TCPServer(portno, f)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/manhole.py
deleted file mode 100755
index 8d727fae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/manhole.py
+++ /dev/null
@@ -1,54 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-I am the support module for making a manhole server with twistd.
-"""
-
-from twisted.manhole import service
-from twisted.spread import pb
-from twisted.python import usage, util
-from twisted.cred import portal, checkers
-from twisted.application import strports
-import os, sys
-
-class Options(usage.Options):
- synopsis = "[options]"
- optParameters = [
- ["user", "u", "admin", "Name of user to allow to log in"],
- ["port", "p", str(pb.portno), "Port to listen on"],
- ]
-
- optFlags = [
- ["tracebacks", "T", "Allow tracebacks to be sent over the network"],
- ]
-
- compData = usage.Completions(
- optActions={"user": usage.CompleteUsernames()}
- )
-
- def opt_password(self, password):
- """Required. '-' will prompt or read a password from stdin.
- """
- # If standard input is a terminal, I prompt for a password and
- # confirm it. Otherwise, I use the first line from standard
- # input, stripping off a trailing newline if there is one.
- if password in ('', '-'):
- self['password'] = util.getPassword(confirm=1)
- else:
- self['password'] = password
- opt_w = opt_password
-
- def postOptions(self):
- if not self.has_key('password'):
- self.opt_password('-')
-
-def makeService(config):
- port, user, password = config['port'], config['user'], config['password']
- p = portal.Portal(
- service.Realm(service.Service(config["tracebacks"], config.get('namespace'))),
- [checkers.InMemoryUsernamePasswordDatabaseDontUse(**{user: password})]
- )
- return strports.service(port, pb.PBServerFactory(p, config["tracebacks"]))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/portforward.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/portforward.py
deleted file mode 100755
index 2ad3f361..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/portforward.py
+++ /dev/null
@@ -1,27 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support module for making a port forwarder with twistd.
-"""
-from twisted.protocols import portforward
-from twisted.python import usage
-from twisted.application import strports
-
-class Options(usage.Options):
- synopsis = "[options]"
- longdesc = 'Port Forwarder.'
- optParameters = [
- ["port", "p", "6666","Set the port number."],
- ["host", "h", "localhost","Set the host."],
- ["dest_port", "d", 6665,"Set the destination port."],
- ]
-
- compData = usage.Completions(
- optActions={"host": usage.CompleteHostnames()}
- )
-
-def makeService(config):
- f = portforward.ProxyFactory(config['host'], int(config['dest_port']))
- return strports.service(config['port'], f)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/socks.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/socks.py
deleted file mode 100755
index e0780ad2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/socks.py
+++ /dev/null
@@ -1,38 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-I am a support module for making SOCKSv4 servers with twistd.
-"""
-
-from twisted.protocols import socks
-from twisted.python import usage
-from twisted.application import internet
-import sys
-
-class Options(usage.Options):
- synopsis = "[-i <interface>] [-p <port>] [-l <file>]"
- optParameters = [["interface", "i", "127.0.0.1", "local interface to which we listen"],
- ["port", "p", 1080, "Port on which to listen"],
- ["log", "l", None, "file to log connection data to"]]
-
- compData = usage.Completions(
- optActions={"log": usage.CompleteFiles("*.log"),
- "interface": usage.CompleteNetInterfaces()}
- )
-
- longdesc = "Makes a SOCKSv4 server."
-
-def makeService(config):
- if config["interface"] != "127.0.0.1":
- print
- print "WARNING:"
- print " You have chosen to listen on a non-local interface."
- print " This may allow intruders to access your local network"
- print " if you run this on a firewall."
- print
- t = socks.SOCKSv4Factory(config['log'])
- portno = int(config['port'])
- return internet.TCPServer(portno, t, interface=config['interface'])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/telnet.py
deleted file mode 100755
index bc0c8020..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/tap/telnet.py
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Support module for making a telnet server with twistd.
-"""
-
-from twisted.manhole import telnet
-from twisted.python import usage
-from twisted.application import strports
-
-class Options(usage.Options):
- synopsis = "[options]"
- longdesc = "Makes a telnet server to a Python shell."
- optParameters = [
- ["username", "u", "admin","set the login username"],
- ["password", "w", "changeme","set the password"],
- ["port", "p", "4040", "port to listen on"],
- ]
-
- compData = usage.Completions(
- optActions={"username": usage.CompleteUsernames()}
- )
-
-def makeService(config):
- t = telnet.ShellFactory()
- t.username, t.password = config['username'], config['password']
- s = strports.service(config['port'], t)
- t.setService(s)
- return s
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/__init__.py
deleted file mode 100755
index ff5a9d54..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-
-Twisted Test: Unit Tests for Twisted.
-
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/_preamble.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/_preamble.py
deleted file mode 100755
index e3e794ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/_preamble.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# This makes sure Twisted-using child processes used in the test suite import
-# the correct version of Twisted (ie, the version of Twisted under test).
-
-# This is a copy of the bin/_preamble.py script because it's not clear how to
-# use the functionality for both things without having a copy.
-
-import sys, os
-
-path = os.path.abspath(sys.argv[0])
-while os.path.dirname(path) != path:
- if os.path.exists(os.path.join(path, 'twisted', '__init__.py')):
- sys.path.insert(0, path)
- break
- path = os.path.dirname(path)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/crash_test_dummy.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/crash_test_dummy.py
deleted file mode 100755
index 5a30bd40..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/crash_test_dummy.py
+++ /dev/null
@@ -1,34 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.python import components
-from zope.interface import implements, Interface
-
-def foo():
- return 2
-
-class X:
- def __init__(self, x):
- self.x = x
-
- def do(self):
- #print 'X',self.x,'doing!'
- pass
-
-
-class XComponent(components.Componentized):
- pass
-
-class IX(Interface):
- pass
-
-class XA(components.Adapter):
- implements(IX)
-
- def method(self):
- # Kick start :(
- pass
-
-components.registerAdapter(XA, X, IX)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/generator_failure_tests.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/generator_failure_tests.py
deleted file mode 100755
index be1344fc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/generator_failure_tests.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Python 2.5+ test cases for failures thrown into generators.
-"""
-from __future__ import division
-
-import sys
-import traceback
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python.failure import Failure
-from twisted.internet import defer
-
-# Re-implement getDivisionFailure here instead of using the one in
-# test_failure.py in order to avoid creating a cyclic dependency.
-def getDivisionFailure():
- try:
- 1/0
- except:
- f = Failure()
- return f
-
-
-
-class TwoPointFiveFailureTests(TestCase):
-
- def test_inlineCallbacksTracebacks(self):
- """
- inlineCallbacks that re-raise tracebacks into their deferred
- should not lose their tracebacsk.
- """
- f = getDivisionFailure()
- d = defer.Deferred()
- try:
- f.raiseException()
- except:
- d.errback()
-
- failures = []
- def collect_error(result):
- failures.append(result)
-
- def ic(d):
- yield d
- ic = defer.inlineCallbacks(ic)
- ic(d).addErrback(collect_error)
-
- newFailure, = failures
- self.assertEqual(
- traceback.extract_tb(newFailure.getTracebackObject())[-1][-1],
- "1/0"
- )
-
-
- def _throwIntoGenerator(self, f, g):
- try:
- f.throwExceptionIntoGenerator(g)
- except StopIteration:
- pass
- else:
- self.fail("throwExceptionIntoGenerator should have raised "
- "StopIteration")
-
- def test_throwExceptionIntoGenerator(self):
- """
- It should be possible to throw the exception that a Failure
- represents into a generator.
- """
- stuff = []
- def generator():
- try:
- yield
- except:
- stuff.append(sys.exc_info())
- else:
- self.fail("Yield should have yielded exception.")
- g = generator()
- f = getDivisionFailure()
- g.next()
- self._throwIntoGenerator(f, g)
-
- self.assertEqual(stuff[0][0], ZeroDivisionError)
- self.assertTrue(isinstance(stuff[0][1], ZeroDivisionError))
-
- self.assertEqual(traceback.extract_tb(stuff[0][2])[-1][-1], "1/0")
-
-
- def test_findFailureInGenerator(self):
- """
- Within an exception handler, it should be possible to find the
- original Failure that caused the current exception (if it was
- caused by throwExceptionIntoGenerator).
- """
- f = getDivisionFailure()
- f.cleanFailure()
-
- foundFailures = []
- def generator():
- try:
- yield
- except:
- foundFailures.append(Failure._findFailure())
- else:
- self.fail("No exception sent to generator")
-
- g = generator()
- g.next()
- self._throwIntoGenerator(f, g)
-
- self.assertEqual(foundFailures, [f])
-
-
- def test_failureConstructionFindsOriginalFailure(self):
- """
- When a Failure is constructed in the context of an exception
- handler that is handling an exception raised by
- throwExceptionIntoGenerator, the new Failure should be chained to that
- original Failure.
- """
- f = getDivisionFailure()
- f.cleanFailure()
-
- newFailures = []
-
- def generator():
- try:
- yield
- except:
- newFailures.append(Failure())
- else:
- self.fail("No exception sent to generator")
- g = generator()
- g.next()
- self._throwIntoGenerator(f, g)
-
- self.assertEqual(len(newFailures), 1)
- self.assertEqual(newFailures[0].getTraceback(), f.getTraceback())
-
- def test_ambiguousFailureInGenerator(self):
- """
- When a generator reraises a different exception,
- L{Failure._findFailure} inside the generator should find the reraised
- exception rather than original one.
- """
- def generator():
- try:
- try:
- yield
- except:
- [][1]
- except:
- self.assertIsInstance(Failure().value, IndexError)
- g = generator()
- g.next()
- f = getDivisionFailure()
- self._throwIntoGenerator(f, g)
-
- def test_ambiguousFailureFromGenerator(self):
- """
- When a generator reraises a different exception,
- L{Failure._findFailure} above the generator should find the reraised
- exception rather than original one.
- """
- def generator():
- try:
- yield
- except:
- [][1]
- g = generator()
- g.next()
- f = getDivisionFailure()
- try:
- self._throwIntoGenerator(f, g)
- except:
- self.assertIsInstance(Failure().value, IndexError)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/iosim.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/iosim.py
deleted file mode 100755
index afa80f9f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/iosim.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# -*- test-case-name: twisted.test.test_amp.TLSTest -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Utilities and helpers for simulating a network
-"""
-
-import itertools
-
-try:
- from OpenSSL.SSL import Error as NativeOpenSSLError
-except ImportError:
- pass
-
-from zope.interface import implements, directlyProvides
-
-from twisted.python.failure import Failure
-from twisted.internet import error
-from twisted.internet import interfaces
-
-class TLSNegotiation:
- def __init__(self, obj, connectState):
- self.obj = obj
- self.connectState = connectState
- self.sent = False
- self.readyToSend = connectState
-
- def __repr__(self):
- return 'TLSNegotiation(%r)' % (self.obj,)
-
- def pretendToVerify(self, other, tpt):
- # Set the transport problems list here? disconnections?
- # hmmmmm... need some negative path tests.
-
- if not self.obj.iosimVerify(other.obj):
- tpt.disconnectReason = NativeOpenSSLError()
- tpt.loseConnection()
-
-
-class FakeTransport:
- """
- A wrapper around a file-like object to make it behave as a Transport.
-
- This doesn't actually stream the file to the attached protocol,
- and is thus useful mainly as a utility for debugging protocols.
- """
- implements(interfaces.ITransport,
- interfaces.ITLSTransport) # ha ha not really
-
- _nextserial = itertools.count().next
- closed = 0
- disconnecting = 0
- disconnected = 0
- disconnectReason = error.ConnectionDone("Connection done")
- producer = None
- streamingProducer = 0
- tls = None
-
- def __init__(self):
- self.stream = []
- self.serial = self._nextserial()
-
- def __repr__(self):
- return 'FakeTransport<%s,%s,%s>' % (
- self.isServer and 'S' or 'C', self.serial,
- self.protocol.__class__.__name__)
-
- def write(self, data):
- if self.tls is not None:
- self.tlsbuf.append(data)
- else:
- self.stream.append(data)
-
- def _checkProducer(self):
- # Cheating; this is called at "idle" times to allow producers to be
- # found and dealt with
- if self.producer:
- self.producer.resumeProducing()
-
- def registerProducer(self, producer, streaming):
- """From abstract.FileDescriptor
- """
- self.producer = producer
- self.streamingProducer = streaming
- if not streaming:
- producer.resumeProducing()
-
- def unregisterProducer(self):
- self.producer = None
-
- def stopConsuming(self):
- self.unregisterProducer()
- self.loseConnection()
-
- def writeSequence(self, iovec):
- self.write("".join(iovec))
-
- def loseConnection(self):
- self.disconnecting = True
-
- def reportDisconnect(self):
- if self.tls is not None:
- # We were in the middle of negotiating! Must have been a TLS problem.
- err = NativeOpenSSLError()
- else:
- err = self.disconnectReason
- self.protocol.connectionLost(Failure(err))
-
- def getPeer(self):
- # XXX: According to ITransport, this should return an IAddress!
- return 'file', 'file'
-
- def getHost(self):
- # XXX: According to ITransport, this should return an IAddress!
- return 'file'
-
- def resumeProducing(self):
- # Never sends data anyways
- pass
-
- def pauseProducing(self):
- # Never sends data anyways
- pass
-
- def stopProducing(self):
- self.loseConnection()
-
- def startTLS(self, contextFactory, beNormal=True):
- # Nothing's using this feature yet, but startTLS has an undocumented
- # second argument which defaults to true; if set to False, servers will
- # behave like clients and clients will behave like servers.
- connectState = self.isServer ^ beNormal
- self.tls = TLSNegotiation(contextFactory, connectState)
- self.tlsbuf = []
-
- def getOutBuffer(self):
- S = self.stream
- if S:
- self.stream = []
- return ''.join(S)
- elif self.tls is not None:
- if self.tls.readyToSend:
- # Only _send_ the TLS negotiation "packet" if I'm ready to.
- self.tls.sent = True
- return self.tls
- else:
- return None
- else:
- return None
-
- def bufferReceived(self, buf):
- if isinstance(buf, TLSNegotiation):
- assert self.tls is not None # By the time you're receiving a
- # negotiation, you have to have called
- # startTLS already.
- if self.tls.sent:
- self.tls.pretendToVerify(buf, self)
- self.tls = None # we're done with the handshake if we've gotten
- # this far... although maybe it failed...?
- # TLS started! Unbuffer...
- b, self.tlsbuf = self.tlsbuf, None
- self.writeSequence(b)
- directlyProvides(self, interfaces.ISSLTransport)
- else:
- # We haven't sent our own TLS negotiation: time to do that!
- self.tls.readyToSend = True
- else:
- self.protocol.dataReceived(buf)
-
-
-
-def makeFakeClient(c):
- ft = FakeTransport()
- ft.isServer = False
- ft.protocol = c
- return ft
-
-def makeFakeServer(s):
- ft = FakeTransport()
- ft.isServer = True
- ft.protocol = s
- return ft
-
-class IOPump:
- """Utility to pump data between clients and servers for protocol testing.
-
- Perhaps this is a utility worthy of being in protocol.py?
- """
- def __init__(self, client, server, clientIO, serverIO, debug):
- self.client = client
- self.server = server
- self.clientIO = clientIO
- self.serverIO = serverIO
- self.debug = debug
-
- def flush(self, debug=False):
- """Pump until there is no more input or output.
-
- Returns whether any data was moved.
- """
- result = False
- for x in range(1000):
- if self.pump(debug):
- result = True
- else:
- break
- else:
- assert 0, "Too long"
- return result
-
-
- def pump(self, debug=False):
- """Move data back and forth.
-
- Returns whether any data was moved.
- """
- if self.debug or debug:
- print '-- GLUG --'
- sData = self.serverIO.getOutBuffer()
- cData = self.clientIO.getOutBuffer()
- self.clientIO._checkProducer()
- self.serverIO._checkProducer()
- if self.debug or debug:
- print '.'
- # XXX slightly buggy in the face of incremental output
- if cData:
- print 'C: '+repr(cData)
- if sData:
- print 'S: '+repr(sData)
- if cData:
- self.serverIO.bufferReceived(cData)
- if sData:
- self.clientIO.bufferReceived(sData)
- if cData or sData:
- return True
- if (self.serverIO.disconnecting and
- not self.serverIO.disconnected):
- if self.debug or debug:
- print '* C'
- self.serverIO.disconnected = True
- self.clientIO.disconnecting = True
- self.clientIO.reportDisconnect()
- return True
- if self.clientIO.disconnecting and not self.clientIO.disconnected:
- if self.debug or debug:
- print '* S'
- self.clientIO.disconnected = True
- self.serverIO.disconnecting = True
- self.serverIO.reportDisconnect()
- return True
- return False
-
-
-def connectedServerAndClient(ServerClass, ClientClass,
- clientTransportFactory=makeFakeClient,
- serverTransportFactory=makeFakeServer,
- debug=False):
- """Returns a 3-tuple: (client, server, pump)
- """
- c = ClientClass()
- s = ServerClass()
- cio = clientTransportFactory(c)
- sio = serverTransportFactory(s)
- c.makeConnection(cio)
- s.makeConnection(sio)
- pump = IOPump(c, s, cio, sio, debug)
- # kick off server greeting, etc
- pump.flush()
- return c, s, pump
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/mock_win32process.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/mock_win32process.py
deleted file mode 100755
index b70bdca6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/mock_win32process.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This is a mock win32process module.
-
-The purpose of this module is mock process creation for the PID test.
-
-CreateProcess(...) will spawn a process, and always return a PID of 42.
-"""
-
-import win32process
-GetExitCodeProcess = win32process.GetExitCodeProcess
-STARTUPINFO = win32process.STARTUPINFO
-
-STARTF_USESTDHANDLES = win32process.STARTF_USESTDHANDLES
-
-
-def CreateProcess(appName,
- cmdline,
- procSecurity,
- threadSecurity,
- inheritHandles,
- newEnvironment,
- env,
- workingDir,
- startupInfo):
- """
- This function mocks the generated pid aspect of the win32.CreateProcess
- function.
- - the true win32process.CreateProcess is called
- - return values are harvested in a tuple.
- - all return values from createProcess are passed back to the calling
- function except for the pid, the returned pid is hardcoded to 42
- """
-
- hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
- appName,
- cmdline,
- procSecurity,
- threadSecurity,
- inheritHandles,
- newEnvironment,
- env,
- workingDir,
- startupInfo)
- dwPid = 42
- return (hProcess, hThread, dwPid, dwTid)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder1.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder1.py
deleted file mode 100755
index f53e8c7e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder1.py
+++ /dev/null
@@ -1,15 +0,0 @@
-
-class A:
- def a(self):
- return 'a'
-try:
- object
-except NameError:
- pass
-else:
- class B(object, A):
- def b(self):
- return 'b'
-class Inherit(A):
- def a(self):
- return 'c'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder2.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder2.py
deleted file mode 100755
index d2a0d10d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/myrebuilder2.py
+++ /dev/null
@@ -1,16 +0,0 @@
-
-class A:
- def a(self):
- return 'b'
-try:
- object
-except NameError:
- pass
-else:
- class B(A, object):
- def b(self):
- return 'c'
-
-class Inherit(A):
- def a(self):
- return 'd'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_basic.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_basic.py
deleted file mode 100755
index a4c297b8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_basic.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# Don't change the docstring, it's part of the tests
-"""
-I'm a test drop-in. The plugin system's unit tests use me. No one
-else should.
-"""
-
-from zope.interface import classProvides
-
-from twisted.plugin import IPlugin
-from twisted.test.test_plugin import ITestPlugin, ITestPlugin2
-
-
-
-class TestPlugin:
- """
- A plugin used solely for testing purposes.
- """
-
- classProvides(ITestPlugin,
- IPlugin)
-
- def test1():
- pass
- test1 = staticmethod(test1)
-
-
-
-class AnotherTestPlugin:
- """
- Another plugin used solely for testing purposes.
- """
-
- classProvides(ITestPlugin2,
- IPlugin)
-
- def test():
- pass
- test = staticmethod(test)
-
-
-
-class ThirdTestPlugin:
- """
- Another plugin used solely for testing purposes.
- """
-
- classProvides(ITestPlugin2,
- IPlugin)
-
- def test():
- pass
- test = staticmethod(test)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra1.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra1.py
deleted file mode 100755
index 9e4c8d48..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra1.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test plugin used in L{twisted.test.test_plugin}.
-"""
-
-from zope.interface import classProvides
-
-from twisted.plugin import IPlugin
-from twisted.test.test_plugin import ITestPlugin
-
-
-
-class FourthTestPlugin:
- classProvides(ITestPlugin,
- IPlugin)
-
- def test1():
- pass
- test1 = staticmethod(test1)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra2.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra2.py
deleted file mode 100755
index a6b3f09f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/plugin_extra2.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test plugin used in L{twisted.test.test_plugin}.
-"""
-
-from zope.interface import classProvides
-
-from twisted.plugin import IPlugin
-from twisted.test.test_plugin import ITestPlugin
-
-
-
-class FourthTestPlugin:
- classProvides(ITestPlugin,
- IPlugin)
-
- def test1():
- pass
- test1 = staticmethod(test1)
-
-
-
-class FifthTestPlugin:
- """
- More documentation: I hate you.
- """
- classProvides(ITestPlugin,
- IPlugin)
-
- def test1():
- pass
- test1 = staticmethod(test1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_cmdline.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_cmdline.py
deleted file mode 100755
index bd250ded..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_cmdline.py
+++ /dev/null
@@ -1,5 +0,0 @@
-"""Write to stdout the command line args it received, one per line."""
-
-import sys
-for x in sys.argv[1:]:
- print x
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_echoer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_echoer.py
deleted file mode 100755
index 8a7bf6dc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_echoer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""Write back all data it receives."""
-
-import sys
-
-data = sys.stdin.read(1)
-while data:
- sys.stdout.write(data)
- sys.stdout.flush()
- data = sys.stdin.read(1)
-sys.stderr.write("byebye")
-sys.stderr.flush()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_fds.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_fds.py
deleted file mode 100755
index e2273c1d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_fds.py
+++ /dev/null
@@ -1,40 +0,0 @@
-
-"""Write to a handful of file descriptors, to test the childFDs= argument of
-reactor.spawnProcess()
-"""
-
-import os, sys
-
-debug = 0
-
-if debug: stderr = os.fdopen(2, "w")
-
-if debug: print >>stderr, "this is stderr"
-
-abcd = os.read(0, 4)
-if debug: print >>stderr, "read(0):", abcd
-if abcd != "abcd":
- sys.exit(1)
-
-if debug: print >>stderr, "os.write(1, righto)"
-
-os.write(1, "righto")
-
-efgh = os.read(3, 4)
-if debug: print >>stderr, "read(3):", efgh
-if efgh != "efgh":
- sys.exit(2)
-
-if debug: print >>stderr, "os.close(4)"
-os.close(4)
-
-eof = os.read(5, 4)
-if debug: print >>stderr, "read(5):", eof
-if eof != "":
- sys.exit(3)
-
-if debug: print >>stderr, "os.write(1, closed)"
-os.write(1, "closed")
-
-if debug: print >>stderr, "sys.exit(0)"
-sys.exit(0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_linger.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_linger.py
deleted file mode 100755
index a95a8d2f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_linger.py
+++ /dev/null
@@ -1,17 +0,0 @@
-
-"""Write to a file descriptor and then close it, waiting a few seconds before
-quitting. This serves to make sure SIGCHLD is actually being noticed.
-"""
-
-import os, sys, time
-
-print "here is some text"
-time.sleep(1)
-print "goodbye"
-os.close(1)
-os.close(2)
-
-time.sleep(2)
-
-sys.exit(0)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_reader.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_reader.py
deleted file mode 100755
index be37a7c4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_reader.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""Script used by test_process.TestTwoProcesses"""
-
-# run until stdin is closed, then quit
-
-import sys
-
-while 1:
- d = sys.stdin.read()
- if len(d) == 0:
- sys.exit(0)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_signal.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_signal.py
deleted file mode 100755
index f2ff108f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_signal.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import sys, signal
-
-signal.signal(signal.SIGINT, signal.SIG_DFL)
-if getattr(signal, "SIGHUP", None) is not None:
- signal.signal(signal.SIGHUP, signal.SIG_DFL)
-print 'ok, signal us'
-sys.stdin.read()
-sys.exit(1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_stdinreader.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_stdinreader.py
deleted file mode 100755
index f060db4a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_stdinreader.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""Script used by twisted.test.test_process on win32."""
-
-import sys, time, os, msvcrt
-msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
-
-
-sys.stdout.write("out\n")
-sys.stdout.flush()
-sys.stderr.write("err\n")
-sys.stderr.flush()
-
-data = sys.stdin.read()
-
-sys.stdout.write(data)
-sys.stdout.write("\nout\n")
-sys.stderr.write("err\n")
-
-sys.stdout.flush()
-sys.stderr.flush()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tester.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tester.py
deleted file mode 100755
index d9779b19..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tester.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Test program for processes."""
-
-import sys, os
-
-test_file_match = "process_test.log.*"
-test_file = "process_test.log.%d" % os.getpid()
-
-def main():
- f = open(test_file, 'wb')
-
- # stage 1
- bytes = sys.stdin.read(4)
- f.write("one: %r\n" % bytes)
- # stage 2
- sys.stdout.write(bytes)
- sys.stdout.flush()
- os.close(sys.stdout.fileno())
-
- # and a one, and a two, and a...
- bytes = sys.stdin.read(4)
- f.write("two: %r\n" % bytes)
-
- # stage 3
- sys.stderr.write(bytes)
- sys.stderr.flush()
- os.close(sys.stderr.fileno())
-
- # stage 4
- bytes = sys.stdin.read(4)
- f.write("three: %r\n" % bytes)
-
- # exit with status code 23
- sys.exit(23)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tty.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tty.py
deleted file mode 100755
index 9dab6389..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_tty.py
+++ /dev/null
@@ -1,6 +0,0 @@
-"""Test to make sure we can open /dev/tty"""
-
-f = open("/dev/tty", "r+")
-a = f.readline()
-f.write(a)
-f.close()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_twisted.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_twisted.py
deleted file mode 100755
index 20710905..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/process_twisted.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""A process that reads from stdin and out using Twisted."""
-
-### Twisted Preamble
-# This makes sure that users don't have to set up their environment
-# specially in order to run these programs from bin/.
-import sys, os
-pos = os.path.abspath(sys.argv[0]).find(os.sep+'Twisted')
-if pos != -1:
- sys.path.insert(0, os.path.abspath(sys.argv[0])[:pos+8])
-sys.path.insert(0, os.curdir)
-### end of preamble
-
-
-from twisted.python import log
-from zope.interface import implements
-from twisted.internet import interfaces
-
-log.startLogging(sys.stderr)
-
-from twisted.internet import protocol, reactor, stdio
-
-
-class Echo(protocol.Protocol):
- implements(interfaces.IHalfCloseableProtocol)
-
- def connectionMade(self):
- print "connection made"
-
- def dataReceived(self, data):
- self.transport.write(data)
-
- def readConnectionLost(self):
- print "readConnectionLost"
- self.transport.loseConnection()
- def writeConnectionLost(self):
- print "writeConnectionLost"
-
- def connectionLost(self, reason):
- print "connectionLost", reason
- reactor.stop()
-
-stdio.StandardIO(Echo())
-reactor.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/proto_helpers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/proto_helpers.py
deleted file mode 100755
index dd043276..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/proto_helpers.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# -*- test-case-name: twisted.test.test_stringtransport -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Assorted functionality which is commonly useful when writing unit tests.
-"""
-
-from socket import AF_INET, AF_INET6
-from StringIO import StringIO
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import (
- ITransport, IConsumer, IPushProducer, IConnector)
-from twisted.internet.interfaces import (
- IReactorTCP, IReactorSSL, IReactorUNIX, IReactorSocket)
-from twisted.internet.interfaces import IListeningPort
-from twisted.internet.abstract import isIPv6Address
-from twisted.internet.error import UnsupportedAddressFamily
-from twisted.protocols import basic
-from twisted.internet import protocol, error, address
-
-from twisted.internet.address import IPv4Address, UNIXAddress, IPv6Address
-
-
-class AccumulatingProtocol(protocol.Protocol):
- """
- L{AccumulatingProtocol} is an L{IProtocol} implementation which collects
- the data delivered to it and can fire a Deferred when it is connected or
- disconnected.
-
- @ivar made: A flag indicating whether C{connectionMade} has been called.
- @ivar data: A string giving all the data passed to C{dataReceived}.
- @ivar closed: A flag indicated whether C{connectionLost} has been called.
- @ivar closedReason: The value of the I{reason} parameter passed to
- C{connectionLost}.
- @ivar closedDeferred: If set to a L{Deferred}, this will be fired when
- C{connectionLost} is called.
- """
- made = closed = 0
- closedReason = None
-
- closedDeferred = None
-
- data = ""
-
- factory = None
-
- def connectionMade(self):
- self.made = 1
- if (self.factory is not None and
- self.factory.protocolConnectionMade is not None):
- d = self.factory.protocolConnectionMade
- self.factory.protocolConnectionMade = None
- d.callback(self)
-
- def dataReceived(self, data):
- self.data += data
-
- def connectionLost(self, reason):
- self.closed = 1
- self.closedReason = reason
- if self.closedDeferred is not None:
- d, self.closedDeferred = self.closedDeferred, None
- d.callback(None)
-
-
-class LineSendingProtocol(basic.LineReceiver):
- lostConn = False
-
- def __init__(self, lines, start = True):
- self.lines = lines[:]
- self.response = []
- self.start = start
-
- def connectionMade(self):
- if self.start:
- map(self.sendLine, self.lines)
-
- def lineReceived(self, line):
- if not self.start:
- map(self.sendLine, self.lines)
- self.lines = []
- self.response.append(line)
-
- def connectionLost(self, reason):
- self.lostConn = True
-
-
-class FakeDatagramTransport:
- noAddr = object()
-
- def __init__(self):
- self.written = []
-
- def write(self, packet, addr=noAddr):
- self.written.append((packet, addr))
-
-
-class StringTransport:
- """
- A transport implementation which buffers data in memory and keeps track of
- its other state without providing any behavior.
-
- L{StringTransport} has a number of attributes which are not part of any of
- the interfaces it claims to implement. These attributes are provided for
- testing purposes. Implementation code should not use any of these
- attributes; they are not provided by other transports.
-
- @ivar disconnecting: A C{bool} which is C{False} until L{loseConnection} is
- called, then C{True}.
-
- @ivar producer: If a producer is currently registered, C{producer} is a
- reference to it. Otherwise, C{None}.
-
- @ivar streaming: If a producer is currently registered, C{streaming} refers
- to the value of the second parameter passed to C{registerProducer}.
-
- @ivar hostAddr: C{None} or an object which will be returned as the host
- address of this transport. If C{None}, a nasty tuple will be returned
- instead.
-
- @ivar peerAddr: C{None} or an object which will be returned as the peer
- address of this transport. If C{None}, a nasty tuple will be returned
- instead.
-
- @ivar producerState: The state of this L{StringTransport} in its capacity
- as an L{IPushProducer}. One of C{'producing'}, C{'paused'}, or
- C{'stopped'}.
-
- @ivar io: A L{StringIO} which holds the data which has been written to this
- transport since the last call to L{clear}. Use L{value} instead of
- accessing this directly.
- """
- implements(ITransport, IConsumer, IPushProducer)
-
- disconnecting = False
-
- producer = None
- streaming = None
-
- hostAddr = None
- peerAddr = None
-
- producerState = 'producing'
-
- def __init__(self, hostAddress=None, peerAddress=None):
- self.clear()
- if hostAddress is not None:
- self.hostAddr = hostAddress
- if peerAddress is not None:
- self.peerAddr = peerAddress
- self.connected = True
-
- def clear(self):
- """
- Discard all data written to this transport so far.
-
- This is not a transport method. It is intended for tests. Do not use
- it in implementation code.
- """
- self.io = StringIO()
-
-
- def value(self):
- """
- Retrieve all data which has been buffered by this transport.
-
- This is not a transport method. It is intended for tests. Do not use
- it in implementation code.
-
- @return: A C{str} giving all data written to this transport since the
- last call to L{clear}.
- @rtype: C{str}
- """
- return self.io.getvalue()
-
-
- # ITransport
- def write(self, data):
- if isinstance(data, unicode): # no, really, I mean it
- raise TypeError("Data must not be unicode")
- self.io.write(data)
-
-
- def writeSequence(self, data):
- self.io.write(''.join(data))
-
-
- def loseConnection(self):
- """
- Close the connection. Does nothing besides toggle the C{disconnecting}
- instance variable to C{True}.
- """
- self.disconnecting = True
-
-
- def getPeer(self):
- if self.peerAddr is None:
- return address.IPv4Address('TCP', '192.168.1.1', 54321)
- return self.peerAddr
-
-
- def getHost(self):
- if self.hostAddr is None:
- return address.IPv4Address('TCP', '10.0.0.1', 12345)
- return self.hostAddr
-
-
- # IConsumer
- def registerProducer(self, producer, streaming):
- if self.producer is not None:
- raise RuntimeError("Cannot register two producers")
- self.producer = producer
- self.streaming = streaming
-
-
- def unregisterProducer(self):
- if self.producer is None:
- raise RuntimeError(
- "Cannot unregister a producer unless one is registered")
- self.producer = None
- self.streaming = None
-
-
- # IPushProducer
- def _checkState(self):
- if self.disconnecting:
- raise RuntimeError(
- "Cannot resume producing after loseConnection")
- if self.producerState == 'stopped':
- raise RuntimeError("Cannot resume a stopped producer")
-
-
- def pauseProducing(self):
- self._checkState()
- self.producerState = 'paused'
-
-
- def stopProducing(self):
- self.producerState = 'stopped'
-
-
- def resumeProducing(self):
- self._checkState()
- self.producerState = 'producing'
-
-
-
-class StringTransportWithDisconnection(StringTransport):
- def loseConnection(self):
- if self.connected:
- self.connected = False
- self.protocol.connectionLost(error.ConnectionDone("Bye."))
-
-
-
-class StringIOWithoutClosing(StringIO):
- """
- A StringIO that can't be closed.
- """
- def close(self):
- """
- Do nothing.
- """
-
-
-
-class _FakePort(object):
- """
- A fake L{IListeningPort} to be used in tests.
-
- @ivar _hostAddress: The L{IAddress} this L{IListeningPort} is pretending
- to be listening on.
- """
- implements(IListeningPort)
-
- def __init__(self, hostAddress):
- """
- @param hostAddress: An L{IAddress} this L{IListeningPort} should
- pretend to be listening on.
- """
- self._hostAddress = hostAddress
-
-
- def startListening(self):
- """
- Fake L{IListeningPort.startListening} that doesn't do anything.
- """
-
-
- def stopListening(self):
- """
- Fake L{IListeningPort.stopListening} that doesn't do anything.
- """
-
-
- def getHost(self):
- """
- Fake L{IListeningPort.getHost} that returns our L{IAddress}.
- """
- return self._hostAddress
-
-
-
-class _FakeConnector(object):
- """
- A fake L{IConnector} that allows us to inspect if it has been told to stop
- connecting.
-
- @ivar stoppedConnecting: has this connector's
- L{FakeConnector.stopConnecting} method been invoked yet?
-
- @ivar _address: An L{IAddress} provider that represents our destination.
- """
- implements(IConnector)
-
- stoppedConnecting = False
-
- def __init__(self, address):
- """
- @param address: An L{IAddress} provider that represents this
- connector's destination.
- """
- self._address = address
-
-
- def stopConnecting(self):
- """
- Implement L{IConnector.stopConnecting} and set
- L{FakeConnector.stoppedConnecting} to C{True}
- """
- self.stoppedConnecting = True
-
-
- def disconnect(self):
- """
- Implement L{IConnector.disconnect} as a no-op.
- """
-
-
- def connect(self):
- """
- Implement L{IConnector.connect} as a no-op.
- """
-
-
- def getDestination(self):
- """
- Implement L{IConnector.getDestination} to return the C{address} passed
- to C{__init__}.
- """
- return self._address
-
-
-
-class MemoryReactor(object):
- """
- A fake reactor to be used in tests. This reactor doesn't actually do
- much that's useful yet. It accepts TCP connection setup attempts, but
- they will never succeed.
-
- @ivar tcpClients: a list that keeps track of connection attempts (ie, calls
- to C{connectTCP}).
- @type tcpClients: C{list}
-
- @ivar tcpServers: a list that keeps track of server listen attempts (ie, calls
- to C{listenTCP}).
- @type tcpServers: C{list}
-
- @ivar sslClients: a list that keeps track of connection attempts (ie,
- calls to C{connectSSL}).
- @type sslClients: C{list}
-
- @ivar sslServers: a list that keeps track of server listen attempts (ie,
- calls to C{listenSSL}).
- @type sslServers: C{list}
-
- @ivar unixClients: a list that keeps track of connection attempts (ie,
- calls to C{connectUNIX}).
- @type unixClients: C{list}
-
- @ivar unixServers: a list that keeps track of server listen attempts (ie,
- calls to C{listenUNIX}).
- @type unixServers: C{list}
-
- @ivar adoptedPorts: a list that keeps track of server listen attempts (ie,
- calls to C{adoptStreamPort}).
- """
- implements(IReactorTCP, IReactorSSL, IReactorUNIX, IReactorSocket)
-
- def __init__(self):
- """
- Initialize the tracking lists.
- """
- self.tcpClients = []
- self.tcpServers = []
- self.sslClients = []
- self.sslServers = []
- self.unixClients = []
- self.unixServers = []
- self.adoptedPorts = []
-
-
- def adoptStreamPort(self, fileno, addressFamily, factory):
- """
- Fake L{IReactorSocket.adoptStreamPort}, that logs the call and returns
- an L{IListeningPort}.
- """
- if addressFamily == AF_INET:
- addr = IPv4Address('TCP', '0.0.0.0', 1234)
- elif addressFamily == AF_INET6:
- addr = IPv6Address('TCP', '::', 1234)
- else:
- raise UnsupportedAddressFamily()
-
- self.adoptedPorts.append((fileno, addressFamily, factory))
- return _FakePort(addr)
-
-
- def listenTCP(self, port, factory, backlog=50, interface=''):
- """
- Fake L{reactor.listenTCP}, that logs the call and returns an
- L{IListeningPort}.
- """
- self.tcpServers.append((port, factory, backlog, interface))
- if isIPv6Address(interface):
- address = IPv6Address('TCP', interface, port)
- else:
- address = IPv4Address('TCP', '0.0.0.0', port)
- return _FakePort(address)
-
-
- def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):
- """
- Fake L{reactor.connectTCP}, that logs the call and returns an
- L{IConnector}.
- """
- self.tcpClients.append((host, port, factory, timeout, bindAddress))
- if isIPv6Address(host):
- conn = _FakeConnector(IPv6Address('TCP', host, port))
- else:
- conn = _FakeConnector(IPv4Address('TCP', host, port))
- factory.startedConnecting(conn)
- return conn
-
-
- def listenSSL(self, port, factory, contextFactory,
- backlog=50, interface=''):
- """
- Fake L{reactor.listenSSL}, that logs the call and returns an
- L{IListeningPort}.
- """
- self.sslServers.append((port, factory, contextFactory,
- backlog, interface))
- return _FakePort(IPv4Address('TCP', '0.0.0.0', port))
-
-
- def connectSSL(self, host, port, factory, contextFactory,
- timeout=30, bindAddress=None):
- """
- Fake L{reactor.connectSSL}, that logs the call and returns an
- L{IConnector}.
- """
- self.sslClients.append((host, port, factory, contextFactory,
- timeout, bindAddress))
- conn = _FakeConnector(IPv4Address('TCP', host, port))
- factory.startedConnecting(conn)
- return conn
-
-
- def listenUNIX(self, address, factory,
- backlog=50, mode=0666, wantPID=0):
- """
- Fake L{reactor.listenUNIX}, that logs the call and returns an
- L{IListeningPort}.
- """
- self.unixServers.append((address, factory, backlog, mode, wantPID))
- return _FakePort(UNIXAddress(address))
-
-
- def connectUNIX(self, address, factory, timeout=30, checkPID=0):
- """
- Fake L{reactor.connectUNIX}, that logs the call and returns an
- L{IConnector}.
- """
- self.unixClients.append((address, factory, timeout, checkPID))
- conn = _FakeConnector(UNIXAddress(address))
- factory.startedConnecting(conn)
- return conn
-
-
-
-class RaisingMemoryReactor(object):
- """
- A fake reactor to be used in tests. It accepts TCP connection setup
- attempts, but they will fail.
-
- @ivar _listenException: An instance of an L{Exception}
- @ivar _connectException: An instance of an L{Exception}
- """
- implements(IReactorTCP, IReactorSSL, IReactorUNIX, IReactorSocket)
-
- def __init__(self, listenException=None, connectException=None):
- """
- @param listenException: An instance of an L{Exception} to raise when any
- C{listen} method is called.
-
- @param connectException: An instance of an L{Exception} to raise when
- any C{connect} method is called.
- """
- self._listenException = listenException
- self._connectException = connectException
-
-
- def adoptStreamPort(self, fileno, addressFamily, factory):
- """
- Fake L{IReactorSocket.adoptStreamPort}, that raises
- L{self._listenException}.
- """
- raise self._listenException
-
-
- def listenTCP(self, port, factory, backlog=50, interface=''):
- """
- Fake L{reactor.listenTCP}, that raises L{self._listenException}.
- """
- raise self._listenException
-
-
- def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):
- """
- Fake L{reactor.connectTCP}, that raises L{self._connectException}.
- """
- raise self._connectException
-
-
- def listenSSL(self, port, factory, contextFactory,
- backlog=50, interface=''):
- """
- Fake L{reactor.listenSSL}, that raises L{self._listenException}.
- """
- raise self._listenException
-
-
- def connectSSL(self, host, port, factory, contextFactory,
- timeout=30, bindAddress=None):
- """
- Fake L{reactor.connectSSL}, that raises L{self._connectException}.
- """
- raise self._connectException
-
-
- def listenUNIX(self, address, factory,
- backlog=50, mode=0666, wantPID=0):
- """
- Fake L{reactor.listenUNIX}, that raises L{self._listenException}.
- """
- raise self._listenException
-
-
- def connectUNIX(self, address, factory, timeout=30, checkPID=0):
- """
- Fake L{reactor.connectUNIX}, that raises L{self._connectException}.
- """
- raise self._connectException
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.c b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.c
deleted file mode 100644
index b9ba1766..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.c
+++ /dev/null
@@ -1,1443 +0,0 @@
-/* Generated by Cython 0.14.1 on Tue Mar 8 19:41:56 2011 */
-
-#define PY_SSIZE_T_CLEAN
-#include "Python.h"
-#ifndef Py_PYTHON_H
- #error Python headers needed to compile C extensions, please install development version of Python.
-#else
-
-#include <stddef.h> /* For offsetof */
-#ifndef offsetof
-#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
-#endif
-
-#if !defined(WIN32) && !defined(MS_WINDOWS)
- #ifndef __stdcall
- #define __stdcall
- #endif
- #ifndef __cdecl
- #define __cdecl
- #endif
- #ifndef __fastcall
- #define __fastcall
- #endif
-#endif
-
-#ifndef DL_IMPORT
- #define DL_IMPORT(t) t
-#endif
-#ifndef DL_EXPORT
- #define DL_EXPORT(t) t
-#endif
-
-#ifndef PY_LONG_LONG
- #define PY_LONG_LONG LONG_LONG
-#endif
-
-#if PY_VERSION_HEX < 0x02040000
- #define METH_COEXIST 0
- #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
- #define PyDict_Contains(d,o) PySequence_Contains(d,o)
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- typedef int Py_ssize_t;
- #define PY_SSIZE_T_MAX INT_MAX
- #define PY_SSIZE_T_MIN INT_MIN
- #define PY_FORMAT_SIZE_T ""
- #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
- #define PyInt_AsSsize_t(o) PyInt_AsLong(o)
- #define PyNumber_Index(o) PyNumber_Int(o)
- #define PyIndex_Check(o) PyNumber_Check(o)
- #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
- #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
- #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
- #define PyVarObject_HEAD_INIT(type, size) \
- PyObject_HEAD_INIT(type) size,
- #define PyType_Modified(t)
-
- typedef struct {
- void *buf;
- PyObject *obj;
- Py_ssize_t len;
- Py_ssize_t itemsize;
- int readonly;
- int ndim;
- char *format;
- Py_ssize_t *shape;
- Py_ssize_t *strides;
- Py_ssize_t *suboffsets;
- void *internal;
- } Py_buffer;
-
- #define PyBUF_SIMPLE 0
- #define PyBUF_WRITABLE 0x0001
- #define PyBUF_FORMAT 0x0004
- #define PyBUF_ND 0x0008
- #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
- #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
- #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
- #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
- #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
-
-#endif
-
-#if PY_MAJOR_VERSION < 3
- #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-#else
- #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define Py_TPFLAGS_CHECKTYPES 0
- #define Py_TPFLAGS_HAVE_INDEX 0
-#endif
-
-#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
- #define Py_TPFLAGS_HAVE_NEWBUFFER 0
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyBaseString_Type PyUnicode_Type
- #define PyStringObject PyUnicodeObject
- #define PyString_Type PyUnicode_Type
- #define PyString_Check PyUnicode_Check
- #define PyString_CheckExact PyUnicode_CheckExact
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define PyBytesObject PyStringObject
- #define PyBytes_Type PyString_Type
- #define PyBytes_Check PyString_Check
- #define PyBytes_CheckExact PyString_CheckExact
- #define PyBytes_FromString PyString_FromString
- #define PyBytes_FromStringAndSize PyString_FromStringAndSize
- #define PyBytes_FromFormat PyString_FromFormat
- #define PyBytes_DecodeEscape PyString_DecodeEscape
- #define PyBytes_AsString PyString_AsString
- #define PyBytes_AsStringAndSize PyString_AsStringAndSize
- #define PyBytes_Size PyString_Size
- #define PyBytes_AS_STRING PyString_AS_STRING
- #define PyBytes_GET_SIZE PyString_GET_SIZE
- #define PyBytes_Repr PyString_Repr
- #define PyBytes_Concat PyString_Concat
- #define PyBytes_ConcatAndDel PyString_ConcatAndDel
-#endif
-
-#if PY_VERSION_HEX < 0x02060000
- #define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
- #define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
-#endif
-#ifndef PySet_CheckExact
- #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
-#endif
-
-#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
-
-#if PY_MAJOR_VERSION >= 3
- #define PyIntObject PyLongObject
- #define PyInt_Type PyLong_Type
- #define PyInt_Check(op) PyLong_Check(op)
- #define PyInt_CheckExact(op) PyLong_CheckExact(op)
- #define PyInt_FromString PyLong_FromString
- #define PyInt_FromUnicode PyLong_FromUnicode
- #define PyInt_FromLong PyLong_FromLong
- #define PyInt_FromSize_t PyLong_FromSize_t
- #define PyInt_FromSsize_t PyLong_FromSsize_t
- #define PyInt_AsLong PyLong_AsLong
- #define PyInt_AS_LONG PyLong_AS_LONG
- #define PyInt_AsSsize_t PyLong_AsSsize_t
- #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
- #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyBoolObject PyLongObject
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
- #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
- #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
-#else
- #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
- #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
-#endif
-
-#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
- #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
- #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
- #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
-#else
- #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
- #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
- #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
- (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
- (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
- (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
- #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
- #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
-#else
- #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
- #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
- #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
- #define __Pyx_NAMESTR(n) ((char *)(n))
- #define __Pyx_DOCSTR(n) ((char *)(n))
-#else
- #define __Pyx_NAMESTR(n) (n)
- #define __Pyx_DOCSTR(n) (n)
-#endif
-
-#ifdef __cplusplus
-#define __PYX_EXTERN_C extern "C"
-#else
-#define __PYX_EXTERN_C extern
-#endif
-
-#if defined(WIN32) || defined(MS_WINDOWS)
-#define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-#define __PYX_HAVE_API__twisted__test__raiser
-
-#ifdef PYREX_WITHOUT_ASSERTIONS
-#define CYTHON_WITHOUT_ASSERTIONS
-#endif
-
-
-/* inline attribute */
-#ifndef CYTHON_INLINE
- #if defined(__GNUC__)
- #define CYTHON_INLINE __inline__
- #elif defined(_MSC_VER)
- #define CYTHON_INLINE __inline
- #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- #define CYTHON_INLINE inline
- #else
- #define CYTHON_INLINE
- #endif
-#endif
-
-/* unused attribute */
-#ifndef CYTHON_UNUSED
-# if defined(__GNUC__)
-# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-# define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-# define CYTHON_UNUSED
-# endif
-# elif defined(__ICC) || defined(__INTEL_COMPILER)
-# define CYTHON_UNUSED __attribute__ ((__unused__))
-# else
-# define CYTHON_UNUSED
-# endif
-#endif
-
-typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
-
-
-/* Type Conversion Predeclarations */
-
-#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
-#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) PyBytes_AsString(s))
-
-#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
-
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
-
-#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
-
-
-#ifdef __GNUC__
-/* Test for GCC > 2.95 */
-#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
-#define likely(x) __builtin_expect(!!(x), 1)
-#define unlikely(x) __builtin_expect(!!(x), 0)
-#else /* __GNUC__ > 2 ... */
-#define likely(x) (x)
-#define unlikely(x) (x)
-#endif /* __GNUC__ > 2 ... */
-#else /* __GNUC__ */
-#define likely(x) (x)
-#define unlikely(x) (x)
-#endif /* __GNUC__ */
-
-static PyObject *__pyx_m;
-static PyObject *__pyx_b;
-static PyObject *__pyx_empty_tuple;
-static PyObject *__pyx_empty_bytes;
-static int __pyx_lineno;
-static int __pyx_clineno = 0;
-static const char * __pyx_cfilenm= __FILE__;
-static const char *__pyx_filename;
-
-
-static const char *__pyx_f[] = {
- "raiser.pyx",
-};
-
-/* Type declarations */
-
-#ifndef CYTHON_REFNANNY
- #define CYTHON_REFNANNY 0
-#endif
-
-#if CYTHON_REFNANNY
- typedef struct {
- void (*INCREF)(void*, PyObject*, int);
- void (*DECREF)(void*, PyObject*, int);
- void (*GOTREF)(void*, PyObject*, int);
- void (*GIVEREF)(void*, PyObject*, int);
- void* (*SetupContext)(const char*, int, const char*);
- void (*FinishContext)(void**);
- } __Pyx_RefNannyAPIStruct;
- static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
- static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) {
- PyObject *m = NULL, *p = NULL;
- void *r = NULL;
- m = PyImport_ImportModule((char *)modname);
- if (!m) goto end;
- p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
- if (!p) goto end;
- r = PyLong_AsVoidPtr(p);
- end:
- Py_XDECREF(p);
- Py_XDECREF(m);
- return (__Pyx_RefNannyAPIStruct *)r;
- }
- #define __Pyx_RefNannySetupContext(name) void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
- #define __Pyx_RefNannyFinishContext() __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
- #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
- #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
-#else
- #define __Pyx_RefNannySetupContext(name)
- #define __Pyx_RefNannyFinishContext()
- #define __Pyx_INCREF(r) Py_INCREF(r)
- #define __Pyx_DECREF(r) Py_DECREF(r)
- #define __Pyx_GOTREF(r)
- #define __Pyx_GIVEREF(r)
- #define __Pyx_XDECREF(r) Py_XDECREF(r)
-#endif /* CYTHON_REFNANNY */
-#define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0)
-#define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0)
-
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-
-static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
-
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
- PyObject *modname); /*proto*/
-
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
-
-static void __Pyx_AddTraceback(const char *funcname); /*proto*/
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
-/* Module declarations from twisted.test.raiser */
-
-#define __Pyx_MODULE_NAME "twisted.test.raiser"
-static int __pyx_module_is_main_twisted__test__raiser = 0;
-
-/* Implementation of twisted.test.raiser */
-static PyObject *__pyx_builtin_Exception;
-static char __pyx_k_1[] = "This function is intentionally broken";
-static char __pyx_k_3[] = "\nA trivial extension that just raises an exception.\nSee L{twisted.test.test_failure.test_failureConstructionWithMungedStackSucceeds}.\n";
-static char __pyx_k_4[] = "\n A speficic exception only used to be identified in tests.\n ";
-static char __pyx_k_5[] = "twisted.test.raiser";
-static char __pyx_k____main__[] = "__main__";
-static char __pyx_k____test__[] = "__test__";
-static char __pyx_k__Exception[] = "Exception";
-static char __pyx_k__raiseException[] = "raiseException";
-static char __pyx_k__RaiserException[] = "RaiserException";
-static PyObject *__pyx_kp_s_1;
-static PyObject *__pyx_kp_s_4;
-static PyObject *__pyx_n_s_5;
-static PyObject *__pyx_n_s__Exception;
-static PyObject *__pyx_n_s__RaiserException;
-static PyObject *__pyx_n_s____main__;
-static PyObject *__pyx_n_s____test__;
-static PyObject *__pyx_n_s__raiseException;
-static PyObject *__pyx_k_tuple_2;
-
-/* "twisted/test/raiser.pyx":17
- *
- *
- * def raiseException(): # <<<<<<<<<<<<<<
- * """
- * Raise L{RaiserException}.
- */
-
-static PyObject *__pyx_pf_7twisted_4test_6raiser_raiseException(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_7twisted_4test_6raiser_raiseException[] = "\n Raise L{RaiserException}.\n ";
-static PyMethodDef __pyx_mdef_7twisted_4test_6raiser_raiseException = {__Pyx_NAMESTR("raiseException"), (PyCFunction)__pyx_pf_7twisted_4test_6raiser_raiseException, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_7twisted_4test_6raiser_raiseException)};
-static PyObject *__pyx_pf_7twisted_4test_6raiser_raiseException(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
- PyObject *__pyx_r = NULL;
- PyObject *__pyx_t_1 = NULL;
- PyObject *__pyx_t_2 = NULL;
- __Pyx_RefNannySetupContext("raiseException");
- __pyx_self = __pyx_self;
-
- /* "twisted/test/raiser.pyx":21
- * Raise L{RaiserException}.
- * """
- * raise RaiserException("This function is intentionally broken") # <<<<<<<<<<<<<<
- */
- __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__RaiserException); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_2);
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
- __Pyx_Raise(__pyx_t_2, 0, 0);
- __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
- {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
- __pyx_r = Py_None; __Pyx_INCREF(Py_None);
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_AddTraceback("twisted.test.raiser.raiseException");
- __pyx_r = NULL;
- __pyx_L0:;
- __Pyx_XGIVEREF(__pyx_r);
- __Pyx_RefNannyFinishContext();
- return __pyx_r;
-}
-
-static PyMethodDef __pyx_methods[] = {
- {0, 0, 0, 0}
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef __pyx_moduledef = {
- PyModuleDef_HEAD_INIT,
- __Pyx_NAMESTR("raiser"),
- __Pyx_DOCSTR(__pyx_k_3), /* m_doc */
- -1, /* m_size */
- __pyx_methods /* m_methods */,
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL /* m_free */
-};
-#endif
-
-static __Pyx_StringTabEntry __pyx_string_tab[] = {
- {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
- {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
- {&__pyx_n_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 1},
- {&__pyx_n_s__Exception, __pyx_k__Exception, sizeof(__pyx_k__Exception), 0, 0, 1, 1},
- {&__pyx_n_s__RaiserException, __pyx_k__RaiserException, sizeof(__pyx_k__RaiserException), 0, 0, 1, 1},
- {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
- {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
- {&__pyx_n_s__raiseException, __pyx_k__raiseException, sizeof(__pyx_k__raiseException), 0, 0, 1, 1},
- {0, 0, 0, 0, 0, 0, 0}
-};
-static int __Pyx_InitCachedBuiltins(void) {
- __pyx_builtin_Exception = __Pyx_GetName(__pyx_b, __pyx_n_s__Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- return 0;
- __pyx_L1_error:;
- return -1;
-}
-
-static int __Pyx_InitCachedConstants(void) {
- __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants");
-
- /* "twisted/test/raiser.pyx":21
- * Raise L{RaiserException}.
- * """
- * raise RaiserException("This function is intentionally broken") # <<<<<<<<<<<<<<
- */
- __pyx_k_tuple_2 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_2));
- __Pyx_INCREF(((PyObject *)__pyx_kp_s_1));
- PyTuple_SET_ITEM(__pyx_k_tuple_2, 0, ((PyObject *)__pyx_kp_s_1));
- __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_1));
- __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
- __Pyx_RefNannyFinishContext();
- return 0;
- __pyx_L1_error:;
- __Pyx_RefNannyFinishContext();
- return -1;
-}
-
-static int __Pyx_InitGlobals(void) {
- if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- return 0;
- __pyx_L1_error:;
- return -1;
-}
-
-#if PY_MAJOR_VERSION < 3
-PyMODINIT_FUNC initraiser(void); /*proto*/
-PyMODINIT_FUNC initraiser(void)
-#else
-PyMODINIT_FUNC PyInit_raiser(void); /*proto*/
-PyMODINIT_FUNC PyInit_raiser(void)
-#endif
-{
- PyObject *__pyx_t_1 = NULL;
- PyObject *__pyx_t_2 = NULL;
- PyObject *__pyx_t_3 = NULL;
- #if CYTHON_REFNANNY
- void* __pyx_refnanny = NULL;
- __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
- if (!__Pyx_RefNanny) {
- PyErr_Clear();
- __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
- if (!__Pyx_RefNanny)
- Py_FatalError("failed to import 'refnanny' module");
- }
- __pyx_refnanny = __Pyx_RefNanny->SetupContext("PyMODINIT_FUNC PyInit_raiser(void)", __LINE__, __FILE__);
- #endif
- __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- #ifdef __pyx_binding_PyCFunctionType_USED
- if (__pyx_binding_PyCFunctionType_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- #endif
- /*--- Library function declarations ---*/
- /*--- Threads initialization code ---*/
- #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
- #ifdef WITH_THREAD /* Python build with threading support? */
- PyEval_InitThreads();
- #endif
- #endif
- /*--- Module creation code ---*/
- #if PY_MAJOR_VERSION < 3
- __pyx_m = Py_InitModule4(__Pyx_NAMESTR("raiser"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_3), 0, PYTHON_API_VERSION);
- #else
- __pyx_m = PyModule_Create(&__pyx_moduledef);
- #endif
- if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- #if PY_MAJOR_VERSION < 3
- Py_INCREF(__pyx_m);
- #endif
- __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));
- if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- /*--- Initialize various global constants etc. ---*/
- if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- if (__pyx_module_is_main_twisted__test__raiser) {
- if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
- }
- /*--- Builtin init code ---*/
- if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- /*--- Constants init code ---*/
- if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- /*--- Global init code ---*/
- /*--- Function export code ---*/
- /*--- Type init code ---*/
- /*--- Type import code ---*/
- /*--- Function import code ---*/
- /*--- Execution code ---*/
-
- /* "twisted/test/raiser.pyx":11
- *
- *
- * class RaiserException(Exception): # <<<<<<<<<<<<<<
- * """
- * A speficic exception only used to be identified in tests.
- */
- __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_1));
- __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_2));
- __Pyx_INCREF(__pyx_builtin_Exception);
- PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_builtin_Exception);
- __Pyx_GIVEREF(__pyx_builtin_Exception);
- if (PyDict_SetItemString(((PyObject *)__pyx_t_1), "__doc__", ((PyObject *)__pyx_kp_s_4)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_t_3 = __Pyx_CreateClass(((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_1), __pyx_n_s__RaiserException, __pyx_n_s_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__RaiserException, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
- __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-
- /* "twisted/test/raiser.pyx":17
- *
- *
- * def raiseException(): # <<<<<<<<<<<<<<
- * """
- * Raise L{RaiserException}.
- */
- __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7twisted_4test_6raiser_raiseException, NULL, __pyx_n_s_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_1);
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s__raiseException, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "twisted/test/raiser.pyx":1
- * # Copyright (c) Twisted Matrix Laboratories. # <<<<<<<<<<<<<<
- * # See LICENSE for details.
- *
- */
- __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(((PyObject *)__pyx_t_1));
- if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
- goto __pyx_L0;
- __pyx_L1_error:;
- __Pyx_XDECREF(__pyx_t_1);
- __Pyx_XDECREF(__pyx_t_2);
- __Pyx_XDECREF(__pyx_t_3);
- if (__pyx_m) {
- __Pyx_AddTraceback("init twisted.test.raiser");
- Py_DECREF(__pyx_m); __pyx_m = 0;
- } else if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_ImportError, "init twisted.test.raiser");
- }
- __pyx_L0:;
- __Pyx_RefNannyFinishContext();
- #if PY_MAJOR_VERSION < 3
- return;
- #else
- return __pyx_m;
- #endif
-}
-
-/* Runtime support code */
-
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
- PyObject *result;
- result = PyObject_GetAttr(dict, name);
- if (!result)
- PyErr_SetObject(PyExc_NameError, name);
- return result;
-}
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
- PyObject *tmp_type, *tmp_value, *tmp_tb;
- PyThreadState *tstate = PyThreadState_GET();
-
- tmp_type = tstate->curexc_type;
- tmp_value = tstate->curexc_value;
- tmp_tb = tstate->curexc_traceback;
- tstate->curexc_type = type;
- tstate->curexc_value = value;
- tstate->curexc_traceback = tb;
- Py_XDECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
-}
-
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
- PyThreadState *tstate = PyThreadState_GET();
- *type = tstate->curexc_type;
- *value = tstate->curexc_value;
- *tb = tstate->curexc_traceback;
-
- tstate->curexc_type = 0;
- tstate->curexc_value = 0;
- tstate->curexc_traceback = 0;
-}
-
-
-#if PY_MAJOR_VERSION < 3
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
- Py_XINCREF(type);
- Py_XINCREF(value);
- Py_XINCREF(tb);
- /* First, check the traceback argument, replacing None with NULL. */
- if (tb == Py_None) {
- Py_DECREF(tb);
- tb = 0;
- }
- else if (tb != NULL && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto raise_error;
- }
- /* Next, replace a missing value with None */
- if (value == NULL) {
- value = Py_None;
- Py_INCREF(value);
- }
- #if PY_VERSION_HEX < 0x02050000
- if (!PyClass_Check(type))
- #else
- if (!PyType_Check(type))
- #endif
- {
- /* Raising an instance. The value should be a dummy. */
- if (value != Py_None) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto raise_error;
- }
- /* Normalize to raise <class>, <instance> */
- Py_DECREF(value);
- value = type;
- #if PY_VERSION_HEX < 0x02050000
- if (PyInstance_Check(type)) {
- type = (PyObject*) ((PyInstanceObject*)type)->in_class;
- Py_INCREF(type);
- }
- else {
- type = 0;
- PyErr_SetString(PyExc_TypeError,
- "raise: exception must be an old-style class or instance");
- goto raise_error;
- }
- #else
- type = (PyObject*) Py_TYPE(type);
- Py_INCREF(type);
- if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto raise_error;
- }
- #endif
- }
-
- __Pyx_ErrRestore(type, value, tb);
- return;
-raise_error:
- Py_XDECREF(value);
- Py_XDECREF(type);
- Py_XDECREF(tb);
- return;
-}
-
-#else /* Python 3+ */
-
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
- if (tb == Py_None) {
- tb = 0;
- } else if (tb && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto bad;
- }
- if (value == Py_None)
- value = 0;
-
- if (PyExceptionInstance_Check(type)) {
- if (value) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto bad;
- }
- value = type;
- type = (PyObject*) Py_TYPE(value);
- } else if (!PyExceptionClass_Check(type)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto bad;
- }
-
- PyErr_SetObject(type, value);
-
- if (tb) {
- PyThreadState *tstate = PyThreadState_GET();
- PyObject* tmp_tb = tstate->curexc_traceback;
- if (tb != tmp_tb) {
- Py_INCREF(tb);
- tstate->curexc_traceback = tb;
- Py_XDECREF(tmp_tb);
- }
- }
-
-bad:
- return;
-}
-#endif
-
-static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
- PyObject *metaclass;
- /* Default metaclass */
-#if PY_MAJOR_VERSION < 3
- if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
- PyObject *base = PyTuple_GET_ITEM(bases, 0);
- metaclass = PyObject_GetAttrString(base, "__class__");
- if (!metaclass) {
- PyErr_Clear();
- metaclass = (PyObject*) Py_TYPE(base);
- }
- } else {
- metaclass = (PyObject *) &PyClass_Type;
- }
-#else
- if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
- PyObject *base = PyTuple_GET_ITEM(bases, 0);
- metaclass = (PyObject*) Py_TYPE(base);
- } else {
- metaclass = (PyObject *) &PyType_Type;
- }
-#endif
- Py_INCREF(metaclass);
- return metaclass;
-}
-
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
- PyObject *modname) {
- PyObject *result;
- PyObject *metaclass;
-
- if (PyDict_SetItemString(dict, "__module__", modname) < 0)
- return NULL;
-
- /* Python2 __metaclass__ */
- metaclass = PyDict_GetItemString(dict, "__metaclass__");
- if (metaclass) {
- Py_INCREF(metaclass);
- } else {
- metaclass = __Pyx_FindPy2Metaclass(bases);
- }
- result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
- Py_DECREF(metaclass);
- return result;
-}
-
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
- const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned char" :
- "value too large to convert to unsigned char");
- }
- return (unsigned char)-1;
- }
- return (unsigned char)val;
- }
- return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
- const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned short" :
- "value too large to convert to unsigned short");
- }
- return (unsigned short)-1;
- }
- return (unsigned short)val;
- }
- return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
- const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(unsigned int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(unsigned int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to unsigned int" :
- "value too large to convert to unsigned int");
- }
- return (unsigned int)-1;
- }
- return (unsigned int)val;
- }
- return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
- const char neg_one = (char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to char" :
- "value too large to convert to char");
- }
- return (char)-1;
- }
- return (char)val;
- }
- return (char)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
- const short neg_one = (short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to short" :
- "value too large to convert to short");
- }
- return (short)-1;
- }
- return (short)val;
- }
- return (short)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
- const int neg_one = (int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to int" :
- "value too large to convert to int");
- }
- return (int)-1;
- }
- return (int)val;
- }
- return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
- const signed char neg_one = (signed char)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed char) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed char)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed char" :
- "value too large to convert to signed char");
- }
- return (signed char)-1;
- }
- return (signed char)val;
- }
- return (signed char)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
- const signed short neg_one = (signed short)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed short) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed short)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed short" :
- "value too large to convert to signed short");
- }
- return (signed short)-1;
- }
- return (signed short)val;
- }
- return (signed short)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
- const signed int neg_one = (signed int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(signed int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(signed int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to signed int" :
- "value too large to convert to signed int");
- }
- return (signed int)-1;
- }
- return (signed int)val;
- }
- return (signed int)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
- const int neg_one = (int)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
- if (sizeof(int) < sizeof(long)) {
- long val = __Pyx_PyInt_AsLong(x);
- if (unlikely(val != (long)(int)val)) {
- if (!unlikely(val == -1 && PyErr_Occurred())) {
- PyErr_SetString(PyExc_OverflowError,
- (is_unsigned && unlikely(val < 0)) ?
- "can't convert negative value to int" :
- "value too large to convert to int");
- }
- return (int)-1;
- }
- return (int)val;
- }
- return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
- const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
- return (unsigned long)-1;
- }
- return (unsigned long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
- return (unsigned long)-1;
- }
- return PyLong_AsUnsignedLong(x);
- } else {
- return PyLong_AsLong(x);
- }
- } else {
- unsigned long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (unsigned long)-1;
- val = __Pyx_PyInt_AsUnsignedLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
- const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned PY_LONG_LONG");
- return (unsigned PY_LONG_LONG)-1;
- }
- return (unsigned PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned PY_LONG_LONG");
- return (unsigned PY_LONG_LONG)-1;
- }
- return PyLong_AsUnsignedLongLong(x);
- } else {
- return PyLong_AsLongLong(x);
- }
- } else {
- unsigned PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (unsigned PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
- const long neg_one = (long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to long");
- return (long)-1;
- }
- return (long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to long");
- return (long)-1;
- }
- return PyLong_AsUnsignedLong(x);
- } else {
- return PyLong_AsLong(x);
- }
- } else {
- long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (long)-1;
- val = __Pyx_PyInt_AsLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
- const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to PY_LONG_LONG");
- return (PY_LONG_LONG)-1;
- }
- return (PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to PY_LONG_LONG");
- return (PY_LONG_LONG)-1;
- }
- return PyLong_AsUnsignedLongLong(x);
- } else {
- return PyLong_AsLongLong(x);
- }
- } else {
- PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
- const signed long neg_one = (signed long)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed long");
- return (signed long)-1;
- }
- return (signed long)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed long");
- return (signed long)-1;
- }
- return PyLong_AsUnsignedLong(x);
- } else {
- return PyLong_AsLong(x);
- }
- } else {
- signed long val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (signed long)-1;
- val = __Pyx_PyInt_AsSignedLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
- const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
- const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
- if (likely(PyInt_Check(x))) {
- long val = PyInt_AS_LONG(x);
- if (is_unsigned && unlikely(val < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed PY_LONG_LONG");
- return (signed PY_LONG_LONG)-1;
- }
- return (signed PY_LONG_LONG)val;
- } else
-#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
- if (unlikely(Py_SIZE(x) < 0)) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to signed PY_LONG_LONG");
- return (signed PY_LONG_LONG)-1;
- }
- return PyLong_AsUnsignedLongLong(x);
- } else {
- return PyLong_AsLongLong(x);
- }
- } else {
- signed PY_LONG_LONG val;
- PyObject *tmp = __Pyx_PyNumber_Int(x);
- if (!tmp) return (signed PY_LONG_LONG)-1;
- val = __Pyx_PyInt_AsSignedLongLong(tmp);
- Py_DECREF(tmp);
- return val;
- }
-}
-
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-
-static void __Pyx_AddTraceback(const char *funcname) {
- PyObject *py_srcfile = 0;
- PyObject *py_funcname = 0;
- PyObject *py_globals = 0;
- PyCodeObject *py_code = 0;
- PyFrameObject *py_frame = 0;
-
- #if PY_MAJOR_VERSION < 3
- py_srcfile = PyString_FromString(__pyx_filename);
- #else
- py_srcfile = PyUnicode_FromString(__pyx_filename);
- #endif
- if (!py_srcfile) goto bad;
- if (__pyx_clineno) {
- #if PY_MAJOR_VERSION < 3
- py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
- #else
- py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
- #endif
- }
- else {
- #if PY_MAJOR_VERSION < 3
- py_funcname = PyString_FromString(funcname);
- #else
- py_funcname = PyUnicode_FromString(funcname);
- #endif
- }
- if (!py_funcname) goto bad;
- py_globals = PyModule_GetDict(__pyx_m);
- if (!py_globals) goto bad;
- py_code = PyCode_New(
- 0, /*int argcount,*/
- #if PY_MAJOR_VERSION >= 3
- 0, /*int kwonlyargcount,*/
- #endif
- 0, /*int nlocals,*/
- 0, /*int stacksize,*/
- 0, /*int flags,*/
- __pyx_empty_bytes, /*PyObject *code,*/
- __pyx_empty_tuple, /*PyObject *consts,*/
- __pyx_empty_tuple, /*PyObject *names,*/
- __pyx_empty_tuple, /*PyObject *varnames,*/
- __pyx_empty_tuple, /*PyObject *freevars,*/
- __pyx_empty_tuple, /*PyObject *cellvars,*/
- py_srcfile, /*PyObject *filename,*/
- py_funcname, /*PyObject *name,*/
- __pyx_lineno, /*int firstlineno,*/
- __pyx_empty_bytes /*PyObject *lnotab*/
- );
- if (!py_code) goto bad;
- py_frame = PyFrame_New(
- PyThreadState_GET(), /*PyThreadState *tstate,*/
- py_code, /*PyCodeObject *code,*/
- py_globals, /*PyObject *globals,*/
- 0 /*PyObject *locals*/
- );
- if (!py_frame) goto bad;
- py_frame->f_lineno = __pyx_lineno;
- PyTraceBack_Here(py_frame);
-bad:
- Py_XDECREF(py_srcfile);
- Py_XDECREF(py_funcname);
- Py_XDECREF(py_code);
- Py_XDECREF(py_frame);
-}
-
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
- while (t->p) {
- #if PY_MAJOR_VERSION < 3
- if (t->is_unicode) {
- *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
- } else if (t->intern) {
- *t->p = PyString_InternFromString(t->s);
- } else {
- *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
- }
- #else /* Python 3+ has unicode identifiers */
- if (t->is_unicode | t->is_str) {
- if (t->intern) {
- *t->p = PyUnicode_InternFromString(t->s);
- } else if (t->encoding) {
- *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
- } else {
- *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
- }
- } else {
- *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
- }
- #endif
- if (!*t->p)
- return -1;
- ++t;
- }
- return 0;
-}
-
-/* Type Conversion Functions */
-
-static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
- int is_true = x == Py_True;
- if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
- else return PyObject_IsTrue(x);
-}
-
-static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
- PyNumberMethods *m;
- const char *name = NULL;
- PyObject *res = NULL;
-#if PY_VERSION_HEX < 0x03000000
- if (PyInt_Check(x) || PyLong_Check(x))
-#else
- if (PyLong_Check(x))
-#endif
- return Py_INCREF(x), x;
- m = Py_TYPE(x)->tp_as_number;
-#if PY_VERSION_HEX < 0x03000000
- if (m && m->nb_int) {
- name = "int";
- res = PyNumber_Int(x);
- }
- else if (m && m->nb_long) {
- name = "long";
- res = PyNumber_Long(x);
- }
-#else
- if (m && m->nb_int) {
- name = "int";
- res = PyNumber_Long(x);
- }
-#endif
- if (res) {
-#if PY_VERSION_HEX < 0x03000000
- if (!PyInt_Check(res) && !PyLong_Check(res)) {
-#else
- if (!PyLong_Check(res)) {
-#endif
- PyErr_Format(PyExc_TypeError,
- "__%s__ returned non-%s (type %.200s)",
- name, name, Py_TYPE(res)->tp_name);
- Py_DECREF(res);
- return NULL;
- }
- }
- else if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "an integer is required");
- }
- return res;
-}
-
-static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
- Py_ssize_t ival;
- PyObject* x = PyNumber_Index(b);
- if (!x) return -1;
- ival = PyInt_AsSsize_t(x);
- Py_DECREF(x);
- return ival;
-}
-
-static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
-#if PY_VERSION_HEX < 0x02050000
- if (ival <= LONG_MAX)
- return PyInt_FromLong((long)ival);
- else {
- unsigned char *bytes = (unsigned char *) &ival;
- int one = 1; int little = (int)*(unsigned char*)&one;
- return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
- }
-#else
- return PyInt_FromSize_t(ival);
-#endif
-}
-
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
- unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
- if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
- return (size_t)-1;
- } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
- PyErr_SetString(PyExc_OverflowError,
- "value too large to convert to size_t");
- return (size_t)-1;
- }
- return (size_t)val;
-}
-
-
-#endif /* Py_PYTHON_H */
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.py
deleted file mode 100755
index 401ef5be..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'raiser.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.pyx b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.pyx
deleted file mode 100644
index 820540ec..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.pyx
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A trivial extension that just raises an exception.
-See L{twisted.test.test_failure.test_failureConstructionWithMungedStackSucceeds}.
-"""
-
-
-
-class RaiserException(Exception):
- """
- A speficic exception only used to be identified in tests.
- """
-
-
-def raiseException():
- """
- Raise L{RaiserException}.
- """
- raise RaiserException("This function is intentionally broken")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.so b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.so
deleted file mode 100755
index 03adbcd1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/raiser.so
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_IE.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_IE.py
deleted file mode 100755
index 614d9483..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_IE.py
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Helper for a test_reflect test
-
-import idonotexist
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_VE.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_VE.py
deleted file mode 100755
index e19507f2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_VE.py
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Helper for a test_reflect test
-
-raise ValueError("Stuff is broken and things")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_ZDE.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_ZDE.py
deleted file mode 100755
index 0c53583f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/reflect_helper_ZDE.py
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Helper module for a test_reflect test
-
-1//0
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/server.pem b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/server.pem
deleted file mode 100644
index 80ef9dcf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDBjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
-MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
-ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
-cHNAcG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzEL
-MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhv
-c3QxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEB
-BQADSwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
-5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQC
-MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
-MB0GA1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7
-hyNp65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoT
-CE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlw
-dG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3Qx
-LmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6
-BoJuVwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++
-7QGG/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JE
-WUQ9Ho4EzbYCOQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
-5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAQJBAIqm/bz4NA1H++Vx5Ewx
-OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
-ZIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
-nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
-HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNEH+vRWsAYU/gbx+OQB+7VOcBAiEA
-oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE REQUEST-----
-MIIBDTCBuAIBADBTMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQ
-BgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20w
-XDANBgkqhkiG9w0BAQEFAANLADBIAkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5Ad
-NgLzJ1/MfsQQJ7hHVeHmTAjM664V+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABoAAw
-DQYJKoZIhvcNAQEEBQADQQA7uqbrNTjVWpF6By5ZNPvhZ4YdFgkeXFVWi5ao/TaP
-Vq4BG021fJ9nlHRtr4rotpgHDX1rr+iWeHKsx4+5DRSy
------END CERTIFICATE REQUEST-----
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/ssl_helpers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/ssl_helpers.py
deleted file mode 100755
index 5612b254..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/ssl_helpers.py
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.internet import ssl
-from twisted.python.util import sibpath
-
-from OpenSSL import SSL
-
-class ClientTLSContext(ssl.ClientContextFactory):
- isClient = 1
- def getContext(self):
- return SSL.Context(SSL.TLSv1_METHOD)
-
-class ServerTLSContext:
- isClient = 0
-
- def __init__(self, filename = sibpath(__file__, 'server.pem')):
- self.filename = filename
-
- def getContext(self):
- ctx = SSL.Context(SSL.TLSv1_METHOD)
- ctx.use_certificate_file(self.filename)
- ctx.use_privatekey_file(self.filename)
- return ctx
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_consumer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_consumer.py
deleted file mode 100755
index 82543875..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_consumer.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_consumer -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_consumer} to test
-that process transports implement IConsumer properly.
-"""
-
-import sys, _preamble
-
-from twisted.python import log, reflect
-from twisted.internet import stdio, protocol
-from twisted.protocols import basic
-
-def failed(err):
- log.startLogging(sys.stderr)
- log.err(err)
-
-class ConsumerChild(protocol.Protocol):
- def __init__(self, junkPath):
- self.junkPath = junkPath
-
- def connectionMade(self):
- d = basic.FileSender().beginFileTransfer(file(self.junkPath), self.transport)
- d.addErrback(failed)
- d.addCallback(lambda ign: self.transport.loseConnection())
-
-
- def connectionLost(self, reason):
- reactor.stop()
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- from twisted.internet import reactor
- stdio.StandardIO(ConsumerChild(sys.argv[2]))
- reactor.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_halfclose.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_halfclose.py
deleted file mode 100755
index b80a8f99..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_halfclose.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_readConnectionLost -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_readConnectionLost}
-to test that IHalfCloseableProtocol.readConnectionLost works for process
-transports.
-"""
-
-import sys, _preamble
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IHalfCloseableProtocol
-from twisted.internet import stdio, protocol
-from twisted.python import reflect, log
-
-
-class HalfCloseProtocol(protocol.Protocol):
- """
- A protocol to hook up to stdio and observe its transport being
- half-closed. If all goes as expected, C{exitCode} will be set to C{0};
- otherwise it will be set to C{1} to indicate failure.
- """
- implements(IHalfCloseableProtocol)
-
- exitCode = None
-
- def connectionMade(self):
- """
- Signal the parent process that we're ready.
- """
- self.transport.write("x")
-
-
- def readConnectionLost(self):
- """
- This is the desired event. Once it has happened, stop the reactor so
- the process will exit.
- """
- self.exitCode = 0
- reactor.stop()
-
-
- def connectionLost(self, reason):
- """
- This may only be invoked after C{readConnectionLost}. If it happens
- otherwise, mark it as an error and shut down.
- """
- if self.exitCode is None:
- self.exitCode = 1
- log.err(reason, "Unexpected call to connectionLost")
- reactor.stop()
-
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- log.startLogging(file(sys.argv[2], 'w'))
- from twisted.internet import reactor
- protocol = HalfCloseProtocol()
- stdio.StandardIO(protocol)
- reactor.run()
- sys.exit(protocol.exitCode)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_hostpeer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_hostpeer.py
deleted file mode 100755
index 1e6f014a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_hostpeer.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_hostAndPeer -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_hostAndPeer} to test
-that ITransport.getHost() and ITransport.getPeer() work for process transports.
-"""
-
-import sys, _preamble
-
-from twisted.internet import stdio, protocol
-from twisted.python import reflect
-
-class HostPeerChild(protocol.Protocol):
- def connectionMade(self):
- self.transport.write('\n'.join([
- str(self.transport.getHost()),
- str(self.transport.getPeer())]))
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- reactor.stop()
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- from twisted.internet import reactor
- stdio.StandardIO(HostPeerChild())
- reactor.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_lastwrite.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_lastwrite.py
deleted file mode 100755
index 2b70514a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_lastwrite.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_lastWriteReceived -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_lastWriteReceived}
-to test that L{os.write} can be reliably used after
-L{twisted.internet.stdio.StandardIO} has finished.
-"""
-
-import sys, _preamble
-
-from twisted.internet.protocol import Protocol
-from twisted.internet.stdio import StandardIO
-from twisted.python.reflect import namedAny
-
-
-class LastWriteChild(Protocol):
- def __init__(self, reactor, magicString):
- self.reactor = reactor
- self.magicString = magicString
-
-
- def connectionMade(self):
- self.transport.write(self.magicString)
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- self.reactor.stop()
-
-
-
-def main(reactor, magicString):
- p = LastWriteChild(reactor, magicString)
- StandardIO(p)
- reactor.run()
-
-
-
-if __name__ == '__main__':
- namedAny(sys.argv[1]).install()
- from twisted.internet import reactor
- main(reactor, sys.argv[2])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_loseconn.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_loseconn.py
deleted file mode 100755
index 7f95a016..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_loseconn.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_loseConnection -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_loseConnection} to
-test that ITransport.loseConnection() works for process transports.
-"""
-
-import sys, _preamble
-
-from twisted.internet.error import ConnectionDone
-from twisted.internet import stdio, protocol
-from twisted.python import reflect, log
-
-class LoseConnChild(protocol.Protocol):
- exitCode = 0
-
- def connectionMade(self):
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- """
- Check that C{reason} is a L{Failure} wrapping a L{ConnectionDone}
- instance and stop the reactor. If C{reason} is wrong for some reason,
- log something about that in C{self.errorLogFile} and make sure the
- process exits with a non-zero status.
- """
- try:
- try:
- reason.trap(ConnectionDone)
- except:
- log.err(None, "Problem with reason passed to connectionLost")
- self.exitCode = 1
- finally:
- reactor.stop()
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- log.startLogging(file(sys.argv[2], 'w'))
- from twisted.internet import reactor
- protocol = LoseConnChild()
- stdio.StandardIO(protocol)
- reactor.run()
- sys.exit(protocol.exitCode)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_producer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_producer.py
deleted file mode 100755
index 5c0b5010..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_producer.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_producer -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_producer} to test
-that process transports implement IProducer properly.
-"""
-
-import sys, _preamble
-
-from twisted.internet import stdio, protocol
-from twisted.python import log, reflect
-
-class ProducerChild(protocol.Protocol):
- _paused = False
- buf = ''
-
- def connectionLost(self, reason):
- log.msg("*****OVER*****")
- reactor.callLater(1, reactor.stop)
- # reactor.stop()
-
-
- def dataReceived(self, bytes):
- self.buf += bytes
- if self._paused:
- log.startLogging(sys.stderr)
- log.msg("dataReceived while transport paused!")
- self.transport.loseConnection()
- else:
- self.transport.write(bytes)
- if self.buf.endswith('\n0\n'):
- self.transport.loseConnection()
- else:
- self.pause()
-
-
- def pause(self):
- self._paused = True
- self.transport.pauseProducing()
- reactor.callLater(0.01, self.unpause)
-
-
- def unpause(self):
- self._paused = False
- self.transport.resumeProducing()
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- from twisted.internet import reactor
- stdio.StandardIO(ProducerChild())
- reactor.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_write.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_write.py
deleted file mode 100755
index 9f92c943..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_write.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_write -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_write} to test that
-ITransport.write() works for process transports.
-"""
-
-import sys, _preamble
-
-from twisted.internet import stdio, protocol
-from twisted.python import reflect
-
-class WriteChild(protocol.Protocol):
- def connectionMade(self):
- for ch in 'ok!':
- self.transport.write(ch)
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- reactor.stop()
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- from twisted.internet import reactor
- stdio.StandardIO(WriteChild())
- reactor.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_writeseq.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_writeseq.py
deleted file mode 100755
index aeab716c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/stdio_test_writeseq.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- test-case-name: twisted.test.test_stdio.StandardInputOutputTestCase.test_writeSequence -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Main program for the child process run by
-L{twisted.test.test_stdio.StandardInputOutputTestCase.test_writeSequence} to test that
-ITransport.writeSequence() works for process transports.
-"""
-
-import sys, _preamble
-
-from twisted.internet import stdio, protocol
-from twisted.python import reflect
-
-class WriteSequenceChild(protocol.Protocol):
- def connectionMade(self):
- self.transport.writeSequence(list('ok!'))
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- reactor.stop()
-
-
-if __name__ == '__main__':
- reflect.namedAny(sys.argv[1]).install()
- from twisted.internet import reactor
- stdio.StandardIO(WriteSequenceChild())
- reactor.run()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_abstract.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_abstract.py
deleted file mode 100755
index 347e3887..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_abstract.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for generic file descriptor based reactor support code.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.internet.abstract import isIPAddress
-
-
-class AddressTests(TestCase):
- """
- Tests for address-related functionality.
- """
- def test_decimalDotted(self):
- """
- L{isIPAddress} should return C{True} for any decimal dotted
- representation of an IPv4 address.
- """
- self.assertTrue(isIPAddress('0.1.2.3'))
- self.assertTrue(isIPAddress('252.253.254.255'))
-
-
- def test_shortDecimalDotted(self):
- """
- L{isIPAddress} should return C{False} for a dotted decimal
- representation with fewer or more than four octets.
- """
- self.assertFalse(isIPAddress('0'))
- self.assertFalse(isIPAddress('0.1'))
- self.assertFalse(isIPAddress('0.1.2'))
- self.assertFalse(isIPAddress('0.1.2.3.4'))
-
-
- def test_invalidLetters(self):
- """
- L{isIPAddress} should return C{False} for any non-decimal dotted
- representation including letters.
- """
- self.assertFalse(isIPAddress('a.2.3.4'))
- self.assertFalse(isIPAddress('1.b.3.4'))
-
-
- def test_invalidPunctuation(self):
- """
- L{isIPAddress} should return C{False} for a string containing
- strange punctuation.
- """
- self.assertFalse(isIPAddress(','))
- self.assertFalse(isIPAddress('1,2'))
- self.assertFalse(isIPAddress('1,2,3'))
- self.assertFalse(isIPAddress('1.,.3,4'))
-
-
- def test_emptyString(self):
- """
- L{isIPAddress} should return C{False} for the empty string.
- """
- self.assertFalse(isIPAddress(''))
-
-
- def test_invalidNegative(self):
- """
- L{isIPAddress} should return C{False} for negative decimal values.
- """
- self.assertFalse(isIPAddress('-1'))
- self.assertFalse(isIPAddress('1.-2'))
- self.assertFalse(isIPAddress('1.2.-3'))
- self.assertFalse(isIPAddress('1.2.-3.4'))
-
-
- def test_invalidPositive(self):
- """
- L{isIPAddress} should return C{False} for a string containing
- positive decimal values greater than 255.
- """
- self.assertFalse(isIPAddress('256.0.0.0'))
- self.assertFalse(isIPAddress('0.256.0.0'))
- self.assertFalse(isIPAddress('0.0.256.0'))
- self.assertFalse(isIPAddress('0.0.0.256'))
- self.assertFalse(isIPAddress('256.256.256.256'))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_adbapi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_adbapi.py
deleted file mode 100755
index 92ff6011..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_adbapi.py
+++ /dev/null
@@ -1,819 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Tests for twisted.enterprise.adbapi.
-"""
-
-from twisted.trial import unittest
-
-import os, stat
-import types
-
-from twisted.enterprise.adbapi import ConnectionPool, ConnectionLost
-from twisted.enterprise.adbapi import Connection, Transaction
-from twisted.internet import reactor, defer, interfaces
-from twisted.python.failure import Failure
-
-
-simple_table_schema = """
-CREATE TABLE simple (
- x integer
-)
-"""
-
-
-class ADBAPITestBase:
- """Test the asynchronous DB-API code."""
-
- openfun_called = {}
-
- if interfaces.IReactorThreads(reactor, None) is None:
- skip = "ADB-API requires threads, no way to test without them"
-
- def extraSetUp(self):
- """
- Set up the database and create a connection pool pointing at it.
- """
- self.startDB()
- self.dbpool = self.makePool(cp_openfun=self.openfun)
- self.dbpool.start()
-
-
- def tearDown(self):
- d = self.dbpool.runOperation('DROP TABLE simple')
- d.addCallback(lambda res: self.dbpool.close())
- d.addCallback(lambda res: self.stopDB())
- return d
-
- def openfun(self, conn):
- self.openfun_called[conn] = True
-
- def checkOpenfunCalled(self, conn=None):
- if not conn:
- self.failUnless(self.openfun_called)
- else:
- self.failUnless(self.openfun_called.has_key(conn))
-
- def testPool(self):
- d = self.dbpool.runOperation(simple_table_schema)
- if self.test_failures:
- d.addCallback(self._testPool_1_1)
- d.addCallback(self._testPool_1_2)
- d.addCallback(self._testPool_1_3)
- d.addCallback(self._testPool_1_4)
- d.addCallback(lambda res: self.flushLoggedErrors())
- d.addCallback(self._testPool_2)
- d.addCallback(self._testPool_3)
- d.addCallback(self._testPool_4)
- d.addCallback(self._testPool_5)
- d.addCallback(self._testPool_6)
- d.addCallback(self._testPool_7)
- d.addCallback(self._testPool_8)
- d.addCallback(self._testPool_9)
- return d
-
- def _testPool_1_1(self, res):
- d = defer.maybeDeferred(self.dbpool.runQuery, "select * from NOTABLE")
- d.addCallbacks(lambda res: self.fail('no exception'),
- lambda f: None)
- return d
-
- def _testPool_1_2(self, res):
- d = defer.maybeDeferred(self.dbpool.runOperation,
- "deletexxx from NOTABLE")
- d.addCallbacks(lambda res: self.fail('no exception'),
- lambda f: None)
- return d
-
- def _testPool_1_3(self, res):
- d = defer.maybeDeferred(self.dbpool.runInteraction,
- self.bad_interaction)
- d.addCallbacks(lambda res: self.fail('no exception'),
- lambda f: None)
- return d
-
- def _testPool_1_4(self, res):
- d = defer.maybeDeferred(self.dbpool.runWithConnection,
- self.bad_withConnection)
- d.addCallbacks(lambda res: self.fail('no exception'),
- lambda f: None)
- return d
-
- def _testPool_2(self, res):
- # verify simple table is empty
- sql = "select count(1) from simple"
- d = self.dbpool.runQuery(sql)
- def _check(row):
- self.failUnless(int(row[0][0]) == 0, "Interaction not rolled back")
- self.checkOpenfunCalled()
- d.addCallback(_check)
- return d
-
- def _testPool_3(self, res):
- sql = "select count(1) from simple"
- inserts = []
- # add some rows to simple table (runOperation)
- for i in range(self.num_iterations):
- sql = "insert into simple(x) values(%d)" % i
- inserts.append(self.dbpool.runOperation(sql))
- d = defer.gatherResults(inserts)
-
- def _select(res):
- # make sure they were added (runQuery)
- sql = "select x from simple order by x";
- d = self.dbpool.runQuery(sql)
- return d
- d.addCallback(_select)
-
- def _check(rows):
- self.failUnless(len(rows) == self.num_iterations,
- "Wrong number of rows")
- for i in range(self.num_iterations):
- self.failUnless(len(rows[i]) == 1, "Wrong size row")
- self.failUnless(rows[i][0] == i, "Values not returned.")
- d.addCallback(_check)
-
- return d
-
- def _testPool_4(self, res):
- # runInteraction
- d = self.dbpool.runInteraction(self.interaction)
- d.addCallback(lambda res: self.assertEqual(res, "done"))
- return d
-
- def _testPool_5(self, res):
- # withConnection
- d = self.dbpool.runWithConnection(self.withConnection)
- d.addCallback(lambda res: self.assertEqual(res, "done"))
- return d
-
- def _testPool_6(self, res):
- # Test a withConnection cannot be closed
- d = self.dbpool.runWithConnection(self.close_withConnection)
- return d
-
- def _testPool_7(self, res):
- # give the pool a workout
- ds = []
- for i in range(self.num_iterations):
- sql = "select x from simple where x = %d" % i
- ds.append(self.dbpool.runQuery(sql))
- dlist = defer.DeferredList(ds, fireOnOneErrback=True)
- def _check(result):
- for i in range(self.num_iterations):
- self.failUnless(result[i][1][0][0] == i, "Value not returned")
- dlist.addCallback(_check)
- return dlist
-
- def _testPool_8(self, res):
- # now delete everything
- ds = []
- for i in range(self.num_iterations):
- sql = "delete from simple where x = %d" % i
- ds.append(self.dbpool.runOperation(sql))
- dlist = defer.DeferredList(ds, fireOnOneErrback=True)
- return dlist
-
- def _testPool_9(self, res):
- # verify simple table is empty
- sql = "select count(1) from simple"
- d = self.dbpool.runQuery(sql)
- def _check(row):
- self.failUnless(int(row[0][0]) == 0,
- "Didn't successfully delete table contents")
- self.checkConnect()
- d.addCallback(_check)
- return d
-
- def checkConnect(self):
- """Check the connect/disconnect synchronous calls."""
- conn = self.dbpool.connect()
- self.checkOpenfunCalled(conn)
- curs = conn.cursor()
- curs.execute("insert into simple(x) values(1)")
- curs.execute("select x from simple")
- res = curs.fetchall()
- self.assertEqual(len(res), 1)
- self.assertEqual(len(res[0]), 1)
- self.assertEqual(res[0][0], 1)
- curs.execute("delete from simple")
- curs.execute("select x from simple")
- self.assertEqual(len(curs.fetchall()), 0)
- curs.close()
- self.dbpool.disconnect(conn)
-
- def interaction(self, transaction):
- transaction.execute("select x from simple order by x")
- for i in range(self.num_iterations):
- row = transaction.fetchone()
- self.failUnless(len(row) == 1, "Wrong size row")
- self.failUnless(row[0] == i, "Value not returned.")
- # should test this, but gadfly throws an exception instead
- #self.failUnless(transaction.fetchone() is None, "Too many rows")
- return "done"
-
- def bad_interaction(self, transaction):
- if self.can_rollback:
- transaction.execute("insert into simple(x) values(0)")
-
- transaction.execute("select * from NOTABLE")
-
- def withConnection(self, conn):
- curs = conn.cursor()
- try:
- curs.execute("select x from simple order by x")
- for i in range(self.num_iterations):
- row = curs.fetchone()
- self.failUnless(len(row) == 1, "Wrong size row")
- self.failUnless(row[0] == i, "Value not returned.")
- # should test this, but gadfly throws an exception instead
- #self.failUnless(transaction.fetchone() is None, "Too many rows")
- finally:
- curs.close()
- return "done"
-
- def close_withConnection(self, conn):
- conn.close()
-
- def bad_withConnection(self, conn):
- curs = conn.cursor()
- try:
- curs.execute("select * from NOTABLE")
- finally:
- curs.close()
-
-
-class ReconnectTestBase:
- """Test the asynchronous DB-API code with reconnect."""
-
- if interfaces.IReactorThreads(reactor, None) is None:
- skip = "ADB-API requires threads, no way to test without them"
-
- def extraSetUp(self):
- """
- Skip the test if C{good_sql} is unavailable. Otherwise, set up the
- database, create a connection pool pointed at it, and set up a simple
- schema in it.
- """
- if self.good_sql is None:
- raise unittest.SkipTest('no good sql for reconnect test')
- self.startDB()
- self.dbpool = self.makePool(cp_max=1, cp_reconnect=True,
- cp_good_sql=self.good_sql)
- self.dbpool.start()
- return self.dbpool.runOperation(simple_table_schema)
-
-
- def tearDown(self):
- d = self.dbpool.runOperation('DROP TABLE simple')
- d.addCallback(lambda res: self.dbpool.close())
- d.addCallback(lambda res: self.stopDB())
- return d
-
- def testPool(self):
- d = defer.succeed(None)
- d.addCallback(self._testPool_1)
- d.addCallback(self._testPool_2)
- if not self.early_reconnect:
- d.addCallback(self._testPool_3)
- d.addCallback(self._testPool_4)
- d.addCallback(self._testPool_5)
- return d
-
- def _testPool_1(self, res):
- sql = "select count(1) from simple"
- d = self.dbpool.runQuery(sql)
- def _check(row):
- self.failUnless(int(row[0][0]) == 0, "Table not empty")
- d.addCallback(_check)
- return d
-
- def _testPool_2(self, res):
- # reach in and close the connection manually
- self.dbpool.connections.values()[0].close()
-
- def _testPool_3(self, res):
- sql = "select count(1) from simple"
- d = defer.maybeDeferred(self.dbpool.runQuery, sql)
- d.addCallbacks(lambda res: self.fail('no exception'),
- lambda f: None)
- return d
-
- def _testPool_4(self, res):
- sql = "select count(1) from simple"
- d = self.dbpool.runQuery(sql)
- def _check(row):
- self.failUnless(int(row[0][0]) == 0, "Table not empty")
- d.addCallback(_check)
- return d
-
- def _testPool_5(self, res):
- self.flushLoggedErrors()
- sql = "select * from NOTABLE" # bad sql
- d = defer.maybeDeferred(self.dbpool.runQuery, sql)
- d.addCallbacks(lambda res: self.fail('no exception'),
- lambda f: self.failIf(f.check(ConnectionLost)))
- return d
-
-
-class DBTestConnector:
- """A class which knows how to test for the presence of
- and establish a connection to a relational database.
-
- To enable test cases which use a central, system database,
- you must create a database named DB_NAME with a user DB_USER
- and password DB_PASS with full access rights to database DB_NAME.
- """
-
- TEST_PREFIX = None # used for creating new test cases
-
- DB_NAME = "twisted_test"
- DB_USER = 'twisted_test'
- DB_PASS = 'twisted_test'
-
- DB_DIR = None # directory for database storage
-
- nulls_ok = True # nulls supported
- trailing_spaces_ok = True # trailing spaces in strings preserved
- can_rollback = True # rollback supported
- test_failures = True # test bad sql?
- escape_slashes = True # escape \ in sql?
- good_sql = ConnectionPool.good_sql
- early_reconnect = True # cursor() will fail on closed connection
- can_clear = True # can try to clear out tables when starting
-
- num_iterations = 50 # number of iterations for test loops
- # (lower this for slow db's)
-
- def setUp(self):
- self.DB_DIR = self.mktemp()
- os.mkdir(self.DB_DIR)
- if not self.can_connect():
- raise unittest.SkipTest('%s: Cannot access db' % self.TEST_PREFIX)
- return self.extraSetUp()
-
- def can_connect(self):
- """Return true if this database is present on the system
- and can be used in a test."""
- raise NotImplementedError()
-
- def startDB(self):
- """Take any steps needed to bring database up."""
- pass
-
- def stopDB(self):
- """Bring database down, if needed."""
- pass
-
- def makePool(self, **newkw):
- """Create a connection pool with additional keyword arguments."""
- args, kw = self.getPoolArgs()
- kw = kw.copy()
- kw.update(newkw)
- return ConnectionPool(*args, **kw)
-
- def getPoolArgs(self):
- """Return a tuple (args, kw) of list and keyword arguments
- that need to be passed to ConnectionPool to create a connection
- to this database."""
- raise NotImplementedError()
-
-class GadflyConnector(DBTestConnector):
- TEST_PREFIX = 'Gadfly'
-
- nulls_ok = False
- can_rollback = False
- escape_slashes = False
- good_sql = 'select * from simple where 1=0'
-
- num_iterations = 1 # slow
-
- def can_connect(self):
- try: import gadfly
- except: return False
- if not getattr(gadfly, 'connect', None):
- gadfly.connect = gadfly.gadfly
- return True
-
- def startDB(self):
- import gadfly
- conn = gadfly.gadfly()
- conn.startup(self.DB_NAME, self.DB_DIR)
-
- # gadfly seems to want us to create something to get the db going
- cursor = conn.cursor()
- cursor.execute("create table x (x integer)")
- conn.commit()
- conn.close()
-
- def getPoolArgs(self):
- args = ('gadfly', self.DB_NAME, self.DB_DIR)
- kw = {'cp_max': 1}
- return args, kw
-
-class SQLiteConnector(DBTestConnector):
- TEST_PREFIX = 'SQLite'
-
- escape_slashes = False
-
- num_iterations = 1 # slow
-
- def can_connect(self):
- try: import sqlite
- except: return False
- return True
-
- def startDB(self):
- self.database = os.path.join(self.DB_DIR, self.DB_NAME)
- if os.path.exists(self.database):
- os.unlink(self.database)
-
- def getPoolArgs(self):
- args = ('sqlite',)
- kw = {'database': self.database, 'cp_max': 1}
- return args, kw
-
-class PyPgSQLConnector(DBTestConnector):
- TEST_PREFIX = "PyPgSQL"
-
- def can_connect(self):
- try: from pyPgSQL import PgSQL
- except: return False
- try:
- conn = PgSQL.connect(database=self.DB_NAME, user=self.DB_USER,
- password=self.DB_PASS)
- conn.close()
- return True
- except:
- return False
-
- def getPoolArgs(self):
- args = ('pyPgSQL.PgSQL',)
- kw = {'database': self.DB_NAME, 'user': self.DB_USER,
- 'password': self.DB_PASS, 'cp_min': 0}
- return args, kw
-
-class PsycopgConnector(DBTestConnector):
- TEST_PREFIX = 'Psycopg'
-
- def can_connect(self):
- try: import psycopg
- except: return False
- try:
- conn = psycopg.connect(database=self.DB_NAME, user=self.DB_USER,
- password=self.DB_PASS)
- conn.close()
- return True
- except:
- return False
-
- def getPoolArgs(self):
- args = ('psycopg',)
- kw = {'database': self.DB_NAME, 'user': self.DB_USER,
- 'password': self.DB_PASS, 'cp_min': 0}
- return args, kw
-
-class MySQLConnector(DBTestConnector):
- TEST_PREFIX = 'MySQL'
-
- trailing_spaces_ok = False
- can_rollback = False
- early_reconnect = False
-
- def can_connect(self):
- try: import MySQLdb
- except: return False
- try:
- conn = MySQLdb.connect(db=self.DB_NAME, user=self.DB_USER,
- passwd=self.DB_PASS)
- conn.close()
- return True
- except:
- return False
-
- def getPoolArgs(self):
- args = ('MySQLdb',)
- kw = {'db': self.DB_NAME, 'user': self.DB_USER, 'passwd': self.DB_PASS}
- return args, kw
-
-class FirebirdConnector(DBTestConnector):
- TEST_PREFIX = 'Firebird'
-
- test_failures = False # failure testing causes problems
- escape_slashes = False
- good_sql = None # firebird doesn't handle failed sql well
- can_clear = False # firebird is not so good
-
- num_iterations = 5 # slow
-
- def can_connect(self):
- try: import kinterbasdb
- except: return False
- try:
- self.startDB()
- self.stopDB()
- return True
- except:
- return False
-
-
- def startDB(self):
- import kinterbasdb
- self.DB_NAME = os.path.join(self.DB_DIR, DBTestConnector.DB_NAME)
- os.chmod(self.DB_DIR, stat.S_IRWXU + stat.S_IRWXG + stat.S_IRWXO)
- sql = 'create database "%s" user "%s" password "%s"'
- sql %= (self.DB_NAME, self.DB_USER, self.DB_PASS);
- conn = kinterbasdb.create_database(sql)
- conn.close()
-
-
- def getPoolArgs(self):
- args = ('kinterbasdb',)
- kw = {'database': self.DB_NAME, 'host': '127.0.0.1',
- 'user': self.DB_USER, 'password': self.DB_PASS}
- return args, kw
-
- def stopDB(self):
- import kinterbasdb
- conn = kinterbasdb.connect(database=self.DB_NAME,
- host='127.0.0.1', user=self.DB_USER,
- password=self.DB_PASS)
- conn.drop_database()
-
-def makeSQLTests(base, suffix, globals):
- """
- Make a test case for every db connector which can connect.
-
- @param base: Base class for test case. Additional base classes
- will be a DBConnector subclass and unittest.TestCase
- @param suffix: A suffix used to create test case names. Prefixes
- are defined in the DBConnector subclasses.
- """
- connectors = [GadflyConnector, SQLiteConnector, PyPgSQLConnector,
- PsycopgConnector, MySQLConnector, FirebirdConnector]
- for connclass in connectors:
- name = connclass.TEST_PREFIX + suffix
- klass = types.ClassType(name, (connclass, base, unittest.TestCase),
- base.__dict__)
- globals[name] = klass
-
-# GadflyADBAPITestCase SQLiteADBAPITestCase PyPgSQLADBAPITestCase
-# PsycopgADBAPITestCase MySQLADBAPITestCase FirebirdADBAPITestCase
-makeSQLTests(ADBAPITestBase, 'ADBAPITestCase', globals())
-
-# GadflyReconnectTestCase SQLiteReconnectTestCase PyPgSQLReconnectTestCase
-# PsycopgReconnectTestCase MySQLReconnectTestCase FirebirdReconnectTestCase
-makeSQLTests(ReconnectTestBase, 'ReconnectTestCase', globals())
-
-
-
-class FakePool(object):
- """
- A fake L{ConnectionPool} for tests.
-
- @ivar connectionFactory: factory for making connections returned by the
- C{connect} method.
- @type connectionFactory: any callable
- """
- reconnect = True
- noisy = True
-
- def __init__(self, connectionFactory):
- self.connectionFactory = connectionFactory
-
-
- def connect(self):
- """
- Return an instance of C{self.connectionFactory}.
- """
- return self.connectionFactory()
-
-
- def disconnect(self, connection):
- """
- Do nothing.
- """
-
-
-
-class ConnectionTestCase(unittest.TestCase):
- """
- Tests for the L{Connection} class.
- """
-
- def test_rollbackErrorLogged(self):
- """
- If an error happens during rollback, L{ConnectionLost} is raised but
- the original error is logged.
- """
- class ConnectionRollbackRaise(object):
- def rollback(self):
- raise RuntimeError("problem!")
-
- pool = FakePool(ConnectionRollbackRaise)
- connection = Connection(pool)
- self.assertRaises(ConnectionLost, connection.rollback)
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].value.args[0], "problem!")
-
-
-
-class TransactionTestCase(unittest.TestCase):
- """
- Tests for the L{Transaction} class.
- """
-
- def test_reopenLogErrorIfReconnect(self):
- """
- If the cursor creation raises an error in L{Transaction.reopen}, it
- reconnects but log the error occurred.
- """
- class ConnectionCursorRaise(object):
- count = 0
-
- def reconnect(self):
- pass
-
- def cursor(self):
- if self.count == 0:
- self.count += 1
- raise RuntimeError("problem!")
-
- pool = FakePool(None)
- transaction = Transaction(pool, ConnectionCursorRaise())
- transaction.reopen()
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].value.args[0], "problem!")
-
-
-
-class NonThreadPool(object):
- def callInThreadWithCallback(self, onResult, f, *a, **kw):
- success = True
- try:
- result = f(*a, **kw)
- except Exception, e:
- success = False
- result = Failure()
- onResult(success, result)
-
-
-
-class DummyConnectionPool(ConnectionPool):
- """
- A testable L{ConnectionPool};
- """
- threadpool = NonThreadPool()
-
- def __init__(self):
- """
- Don't forward init call.
- """
- self.reactor = reactor
-
-
-
-class EventReactor(object):
- """
- Partial L{IReactorCore} implementation with simple event-related
- methods.
-
- @ivar _running: A C{bool} indicating whether the reactor is pretending
- to have been started already or not.
-
- @ivar triggers: A C{list} of pending system event triggers.
- """
- def __init__(self, running):
- self._running = running
- self.triggers = []
-
-
- def callWhenRunning(self, function):
- if self._running:
- function()
- else:
- return self.addSystemEventTrigger('after', 'startup', function)
-
-
- def addSystemEventTrigger(self, phase, event, trigger):
- handle = (phase, event, trigger)
- self.triggers.append(handle)
- return handle
-
-
- def removeSystemEventTrigger(self, handle):
- self.triggers.remove(handle)
-
-
-
-class ConnectionPoolTestCase(unittest.TestCase):
- """
- Unit tests for L{ConnectionPool}.
- """
-
- def test_runWithConnectionRaiseOriginalError(self):
- """
- If rollback fails, L{ConnectionPool.runWithConnection} raises the
- original exception and log the error of the rollback.
- """
- class ConnectionRollbackRaise(object):
- def __init__(self, pool):
- pass
-
- def rollback(self):
- raise RuntimeError("problem!")
-
- def raisingFunction(connection):
- raise ValueError("foo")
-
- pool = DummyConnectionPool()
- pool.connectionFactory = ConnectionRollbackRaise
- d = pool.runWithConnection(raisingFunction)
- d = self.assertFailure(d, ValueError)
- def cbFailed(ignored):
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].value.args[0], "problem!")
- d.addCallback(cbFailed)
- return d
-
-
- def test_closeLogError(self):
- """
- L{ConnectionPool._close} logs exceptions.
- """
- class ConnectionCloseRaise(object):
- def close(self):
- raise RuntimeError("problem!")
-
- pool = DummyConnectionPool()
- pool._close(ConnectionCloseRaise())
-
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].value.args[0], "problem!")
-
-
- def test_runWithInteractionRaiseOriginalError(self):
- """
- If rollback fails, L{ConnectionPool.runInteraction} raises the
- original exception and log the error of the rollback.
- """
- class ConnectionRollbackRaise(object):
- def __init__(self, pool):
- pass
-
- def rollback(self):
- raise RuntimeError("problem!")
-
- class DummyTransaction(object):
- def __init__(self, pool, connection):
- pass
-
- def raisingFunction(transaction):
- raise ValueError("foo")
-
- pool = DummyConnectionPool()
- pool.connectionFactory = ConnectionRollbackRaise
- pool.transactionFactory = DummyTransaction
-
- d = pool.runInteraction(raisingFunction)
- d = self.assertFailure(d, ValueError)
- def cbFailed(ignored):
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].value.args[0], "problem!")
- d.addCallback(cbFailed)
- return d
-
-
- def test_unstartedClose(self):
- """
- If L{ConnectionPool.close} is called without L{ConnectionPool.start}
- having been called, the pool's startup event is cancelled.
- """
- reactor = EventReactor(False)
- pool = ConnectionPool('twisted.test.test_adbapi', cp_reactor=reactor)
- # There should be a startup trigger waiting.
- self.assertEqual(reactor.triggers, [('after', 'startup', pool._start)])
- pool.close()
- # But not anymore.
- self.assertFalse(reactor.triggers)
-
-
- def test_startedClose(self):
- """
- If L{ConnectionPool.close} is called after it has been started, but
- not by its shutdown trigger, the shutdown trigger is cancelled.
- """
- reactor = EventReactor(True)
- pool = ConnectionPool('twisted.test.test_adbapi', cp_reactor=reactor)
- # There should be a shutdown trigger waiting.
- self.assertEqual(reactor.triggers, [('during', 'shutdown', pool.finalClose)])
- pool.close()
- # But not anymore.
- self.assertFalse(reactor.triggers)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_amp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_amp.py
deleted file mode 100755
index 325af405..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_amp.py
+++ /dev/null
@@ -1,3178 +0,0 @@
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.protocols.amp}.
-"""
-
-import datetime
-import decimal
-
-from zope.interface import implements
-from zope.interface.verify import verifyClass, verifyObject
-
-from twisted.python.util import setIDFunction
-from twisted.python import filepath
-from twisted.python.failure import Failure
-from twisted.protocols import amp
-from twisted.trial import unittest
-from twisted.internet import protocol, defer, error, reactor, interfaces
-from twisted.test import iosim
-from twisted.test.proto_helpers import StringTransport
-
-ssl = None
-try:
- from twisted.internet import ssl
-except ImportError:
- pass
-
-if ssl and not ssl.supported:
- ssl = None
-
-if ssl is None:
- skipSSL = "SSL not available"
-else:
- skipSSL = None
-
-
-class TestProto(protocol.Protocol):
- """
- A trivial protocol for use in testing where a L{Protocol} is expected.
-
- @ivar instanceId: the id of this instance
- @ivar onConnLost: deferred that will fired when the connection is lost
- @ivar dataToSend: data to send on the protocol
- """
-
- instanceCount = 0
-
- def __init__(self, onConnLost, dataToSend):
- self.onConnLost = onConnLost
- self.dataToSend = dataToSend
- self.instanceId = TestProto.instanceCount
- TestProto.instanceCount = TestProto.instanceCount + 1
-
-
- def connectionMade(self):
- self.data = []
- self.transport.write(self.dataToSend)
-
-
- def dataReceived(self, bytes):
- self.data.append(bytes)
-
-
- def connectionLost(self, reason):
- self.onConnLost.callback(self.data)
-
-
- def __repr__(self):
- """
- Custom repr for testing to avoid coupling amp tests with repr from
- L{Protocol}
-
- Returns a string which contains a unique identifier that can be looked
- up using the instanceId property::
-
- <TestProto #3>
- """
- return "<TestProto #%d>" % (self.instanceId,)
-
-
-
-class SimpleSymmetricProtocol(amp.AMP):
-
- def sendHello(self, text):
- return self.callRemoteString(
- "hello",
- hello=text)
-
- def amp_HELLO(self, box):
- return amp.Box(hello=box['hello'])
-
- def amp_HOWDOYOUDO(self, box):
- return amp.QuitBox(howdoyoudo='world')
-
-
-
-class UnfriendlyGreeting(Exception):
- """Greeting was insufficiently kind.
- """
-
-class DeathThreat(Exception):
- """Greeting was insufficiently kind.
- """
-
-class UnknownProtocol(Exception):
- """Asked to switch to the wrong protocol.
- """
-
-
-class TransportPeer(amp.Argument):
- # this serves as some informal documentation for how to get variables from
- # the protocol or your environment and pass them to methods as arguments.
- def retrieve(self, d, name, proto):
- return ''
-
- def fromStringProto(self, notAString, proto):
- return proto.transport.getPeer()
-
- def toBox(self, name, strings, objects, proto):
- return
-
-
-
-class Hello(amp.Command):
-
- commandName = 'hello'
-
- arguments = [('hello', amp.String()),
- ('optional', amp.Boolean(optional=True)),
- ('print', amp.Unicode(optional=True)),
- ('from', TransportPeer(optional=True)),
- ('mixedCase', amp.String(optional=True)),
- ('dash-arg', amp.String(optional=True)),
- ('underscore_arg', amp.String(optional=True))]
-
- response = [('hello', amp.String()),
- ('print', amp.Unicode(optional=True))]
-
- errors = {UnfriendlyGreeting: 'UNFRIENDLY'}
-
- fatalErrors = {DeathThreat: 'DEAD'}
-
-class NoAnswerHello(Hello):
- commandName = Hello.commandName
- requiresAnswer = False
-
-class FutureHello(amp.Command):
- commandName = 'hello'
-
- arguments = [('hello', amp.String()),
- ('optional', amp.Boolean(optional=True)),
- ('print', amp.Unicode(optional=True)),
- ('from', TransportPeer(optional=True)),
- ('bonus', amp.String(optional=True)), # addt'l arguments
- # should generally be
- # added at the end, and
- # be optional...
- ]
-
- response = [('hello', amp.String()),
- ('print', amp.Unicode(optional=True))]
-
- errors = {UnfriendlyGreeting: 'UNFRIENDLY'}
-
-class WTF(amp.Command):
- """
- An example of an invalid command.
- """
-
-
-class BrokenReturn(amp.Command):
- """ An example of a perfectly good command, but the handler is going to return
- None...
- """
-
- commandName = 'broken_return'
-
-class Goodbye(amp.Command):
- # commandName left blank on purpose: this tests implicit command names.
- response = [('goodbye', amp.String())]
- responseType = amp.QuitBox
-
-class Howdoyoudo(amp.Command):
- commandName = 'howdoyoudo'
- # responseType = amp.QuitBox
-
-class WaitForever(amp.Command):
- commandName = 'wait_forever'
-
-class GetList(amp.Command):
- commandName = 'getlist'
- arguments = [('length', amp.Integer())]
- response = [('body', amp.AmpList([('x', amp.Integer())]))]
-
-class DontRejectMe(amp.Command):
- commandName = 'dontrejectme'
- arguments = [
- ('magicWord', amp.Unicode()),
- ('list', amp.AmpList([('name', amp.Unicode())], optional=True)),
- ]
- response = [('response', amp.Unicode())]
-
-class SecuredPing(amp.Command):
- # XXX TODO: actually make this refuse to send over an insecure connection
- response = [('pinged', amp.Boolean())]
-
-class TestSwitchProto(amp.ProtocolSwitchCommand):
- commandName = 'Switch-Proto'
-
- arguments = [
- ('name', amp.String()),
- ]
- errors = {UnknownProtocol: 'UNKNOWN'}
-
-class SingleUseFactory(protocol.ClientFactory):
- def __init__(self, proto):
- self.proto = proto
- self.proto.factory = self
-
- def buildProtocol(self, addr):
- p, self.proto = self.proto, None
- return p
-
- reasonFailed = None
-
- def clientConnectionFailed(self, connector, reason):
- self.reasonFailed = reason
- return
-
-THING_I_DONT_UNDERSTAND = 'gwebol nargo'
-class ThingIDontUnderstandError(Exception):
- pass
-
-class FactoryNotifier(amp.AMP):
- factory = None
- def connectionMade(self):
- if self.factory is not None:
- self.factory.theProto = self
- if hasattr(self.factory, 'onMade'):
- self.factory.onMade.callback(None)
-
- def emitpong(self):
- from twisted.internet.interfaces import ISSLTransport
- if not ISSLTransport.providedBy(self.transport):
- raise DeathThreat("only send secure pings over secure channels")
- return {'pinged': True}
- SecuredPing.responder(emitpong)
-
-
-class SimpleSymmetricCommandProtocol(FactoryNotifier):
- maybeLater = None
- def __init__(self, onConnLost=None):
- amp.AMP.__init__(self)
- self.onConnLost = onConnLost
-
- def sendHello(self, text):
- return self.callRemote(Hello, hello=text)
-
- def sendUnicodeHello(self, text, translation):
- return self.callRemote(Hello, hello=text, Print=translation)
-
- greeted = False
-
- def cmdHello(self, hello, From, optional=None, Print=None,
- mixedCase=None, dash_arg=None, underscore_arg=None):
- assert From == self.transport.getPeer()
- if hello == THING_I_DONT_UNDERSTAND:
- raise ThingIDontUnderstandError()
- if hello.startswith('fuck'):
- raise UnfriendlyGreeting("Don't be a dick.")
- if hello == 'die':
- raise DeathThreat("aieeeeeeeee")
- result = dict(hello=hello)
- if Print is not None:
- result.update(dict(Print=Print))
- self.greeted = True
- return result
- Hello.responder(cmdHello)
-
- def cmdGetlist(self, length):
- return {'body': [dict(x=1)] * length}
- GetList.responder(cmdGetlist)
-
- def okiwont(self, magicWord, list=None):
- if list is None:
- response = u'list omitted'
- else:
- response = u'%s accepted' % (list[0]['name'])
- return dict(response=response)
- DontRejectMe.responder(okiwont)
-
- def waitforit(self):
- self.waiting = defer.Deferred()
- return self.waiting
- WaitForever.responder(waitforit)
-
- def howdo(self):
- return dict(howdoyoudo='world')
- Howdoyoudo.responder(howdo)
-
- def saybye(self):
- return dict(goodbye="everyone")
- Goodbye.responder(saybye)
-
- def switchToTestProtocol(self, fail=False):
- if fail:
- name = 'no-proto'
- else:
- name = 'test-proto'
- p = TestProto(self.onConnLost, SWITCH_CLIENT_DATA)
- return self.callRemote(
- TestSwitchProto,
- SingleUseFactory(p), name=name).addCallback(lambda ign: p)
-
- def switchit(self, name):
- if name == 'test-proto':
- return TestProto(self.onConnLost, SWITCH_SERVER_DATA)
- raise UnknownProtocol(name)
- TestSwitchProto.responder(switchit)
-
- def donothing(self):
- return None
- BrokenReturn.responder(donothing)
-
-
-class DeferredSymmetricCommandProtocol(SimpleSymmetricCommandProtocol):
- def switchit(self, name):
- if name == 'test-proto':
- self.maybeLaterProto = TestProto(self.onConnLost, SWITCH_SERVER_DATA)
- self.maybeLater = defer.Deferred()
- return self.maybeLater
- raise UnknownProtocol(name)
- TestSwitchProto.responder(switchit)
-
-class BadNoAnswerCommandProtocol(SimpleSymmetricCommandProtocol):
- def badResponder(self, hello, From, optional=None, Print=None,
- mixedCase=None, dash_arg=None, underscore_arg=None):
- """
- This responder does nothing and forgets to return a dictionary.
- """
- NoAnswerHello.responder(badResponder)
-
-class NoAnswerCommandProtocol(SimpleSymmetricCommandProtocol):
- def goodNoAnswerResponder(self, hello, From, optional=None, Print=None,
- mixedCase=None, dash_arg=None, underscore_arg=None):
- return dict(hello=hello+"-noanswer")
- NoAnswerHello.responder(goodNoAnswerResponder)
-
-def connectedServerAndClient(ServerClass=SimpleSymmetricProtocol,
- ClientClass=SimpleSymmetricProtocol,
- *a, **kw):
- """Returns a 3-tuple: (client, server, pump)
- """
- return iosim.connectedServerAndClient(
- ServerClass, ClientClass,
- *a, **kw)
-
-class TotallyDumbProtocol(protocol.Protocol):
- buf = ''
- def dataReceived(self, data):
- self.buf += data
-
-class LiteralAmp(amp.AMP):
- def __init__(self):
- self.boxes = []
-
- def ampBoxReceived(self, box):
- self.boxes.append(box)
- return
-
-
-
-class AmpBoxTests(unittest.TestCase):
- """
- Test a few essential properties of AMP boxes, mostly with respect to
- serialization correctness.
- """
-
- def test_serializeStr(self):
- """
- Make sure that strs serialize to strs.
- """
- a = amp.AmpBox(key='value')
- self.assertEqual(type(a.serialize()), str)
-
- def test_serializeUnicodeKeyRaises(self):
- """
- Verify that TypeError is raised when trying to serialize Unicode keys.
- """
- a = amp.AmpBox(**{u'key': 'value'})
- self.assertRaises(TypeError, a.serialize)
-
- def test_serializeUnicodeValueRaises(self):
- """
- Verify that TypeError is raised when trying to serialize Unicode
- values.
- """
- a = amp.AmpBox(key=u'value')
- self.assertRaises(TypeError, a.serialize)
-
-
-
-class ParsingTest(unittest.TestCase):
-
- def test_booleanValues(self):
- """
- Verify that the Boolean parser parses 'True' and 'False', but nothing
- else.
- """
- b = amp.Boolean()
- self.assertEqual(b.fromString("True"), True)
- self.assertEqual(b.fromString("False"), False)
- self.assertRaises(TypeError, b.fromString, "ninja")
- self.assertRaises(TypeError, b.fromString, "true")
- self.assertRaises(TypeError, b.fromString, "TRUE")
- self.assertEqual(b.toString(True), 'True')
- self.assertEqual(b.toString(False), 'False')
-
- def test_pathValueRoundTrip(self):
- """
- Verify the 'Path' argument can parse and emit a file path.
- """
- fp = filepath.FilePath(self.mktemp())
- p = amp.Path()
- s = p.toString(fp)
- v = p.fromString(s)
- self.assertNotIdentical(fp, v) # sanity check
- self.assertEqual(fp, v)
-
-
- def test_sillyEmptyThing(self):
- """
- Test that empty boxes raise an error; they aren't supposed to be sent
- on purpose.
- """
- a = amp.AMP()
- return self.assertRaises(amp.NoEmptyBoxes, a.ampBoxReceived, amp.Box())
-
-
- def test_ParsingRoundTrip(self):
- """
- Verify that various kinds of data make it through the encode/parse
- round-trip unharmed.
- """
- c, s, p = connectedServerAndClient(ClientClass=LiteralAmp,
- ServerClass=LiteralAmp)
-
- SIMPLE = ('simple', 'test')
- CE = ('ceq', ': ')
- CR = ('crtest', 'test\r')
- LF = ('lftest', 'hello\n')
- NEWLINE = ('newline', 'test\r\none\r\ntwo')
- NEWLINE2 = ('newline2', 'test\r\none\r\n two')
- BODYTEST = ('body', 'blah\r\n\r\ntesttest')
-
- testData = [
- [SIMPLE],
- [SIMPLE, BODYTEST],
- [SIMPLE, CE],
- [SIMPLE, CR],
- [SIMPLE, CE, CR, LF],
- [CE, CR, LF],
- [SIMPLE, NEWLINE, CE, NEWLINE2],
- [BODYTEST, SIMPLE, NEWLINE]
- ]
-
- for test in testData:
- jb = amp.Box()
- jb.update(dict(test))
- jb._sendTo(c)
- p.flush()
- self.assertEqual(s.boxes[-1], jb)
-
-
-
-class FakeLocator(object):
- """
- This is a fake implementation of the interface implied by
- L{CommandLocator}.
- """
- def __init__(self):
- """
- Remember the given keyword arguments as a set of responders.
- """
- self.commands = {}
-
-
- def locateResponder(self, commandName):
- """
- Look up and return a function passed as a keyword argument of the given
- name to the constructor.
- """
- return self.commands[commandName]
-
-
-class FakeSender:
- """
- This is a fake implementation of the 'box sender' interface implied by
- L{AMP}.
- """
- def __init__(self):
- """
- Create a fake sender and initialize the list of received boxes and
- unhandled errors.
- """
- self.sentBoxes = []
- self.unhandledErrors = []
- self.expectedErrors = 0
-
-
- def expectError(self):
- """
- Expect one error, so that the test doesn't fail.
- """
- self.expectedErrors += 1
-
-
- def sendBox(self, box):
- """
- Accept a box, but don't do anything.
- """
- self.sentBoxes.append(box)
-
-
- def unhandledError(self, failure):
- """
- Deal with failures by instantly re-raising them for easier debugging.
- """
- self.expectedErrors -= 1
- if self.expectedErrors < 0:
- failure.raiseException()
- else:
- self.unhandledErrors.append(failure)
-
-
-
-class CommandDispatchTests(unittest.TestCase):
- """
- The AMP CommandDispatcher class dispatches converts AMP boxes into commands
- and responses using Command.responder decorator.
-
- Note: Originally, AMP's factoring was such that many tests for this
- functionality are now implemented as full round-trip tests in L{AMPTest}.
- Future tests should be written at this level instead, to ensure API
- compatibility and to provide more granular, readable units of test
- coverage.
- """
-
- def setUp(self):
- """
- Create a dispatcher to use.
- """
- self.locator = FakeLocator()
- self.sender = FakeSender()
- self.dispatcher = amp.BoxDispatcher(self.locator)
- self.dispatcher.startReceivingBoxes(self.sender)
-
-
- def test_receivedAsk(self):
- """
- L{CommandDispatcher.ampBoxReceived} should locate the appropriate
- command in its responder lookup, based on the '_ask' key.
- """
- received = []
- def thunk(box):
- received.append(box)
- return amp.Box({"hello": "goodbye"})
- input = amp.Box(_command="hello",
- _ask="test-command-id",
- hello="world")
- self.locator.commands['hello'] = thunk
- self.dispatcher.ampBoxReceived(input)
- self.assertEqual(received, [input])
-
-
- def test_sendUnhandledError(self):
- """
- L{CommandDispatcher} should relay its unhandled errors in responding to
- boxes to its boxSender.
- """
- err = RuntimeError("something went wrong, oh no")
- self.sender.expectError()
- self.dispatcher.unhandledError(Failure(err))
- self.assertEqual(len(self.sender.unhandledErrors), 1)
- self.assertEqual(self.sender.unhandledErrors[0].value, err)
-
-
- def test_unhandledSerializationError(self):
- """
- Errors during serialization ought to be relayed to the sender's
- unhandledError method.
- """
- err = RuntimeError("something undefined went wrong")
- def thunk(result):
- class BrokenBox(amp.Box):
- def _sendTo(self, proto):
- raise err
- return BrokenBox()
- self.locator.commands['hello'] = thunk
- input = amp.Box(_command="hello",
- _ask="test-command-id",
- hello="world")
- self.sender.expectError()
- self.dispatcher.ampBoxReceived(input)
- self.assertEqual(len(self.sender.unhandledErrors), 1)
- self.assertEqual(self.sender.unhandledErrors[0].value, err)
-
-
- def test_callRemote(self):
- """
- L{CommandDispatcher.callRemote} should emit a properly formatted '_ask'
- box to its boxSender and record an outstanding L{Deferred}. When a
- corresponding '_answer' packet is received, the L{Deferred} should be
- fired, and the results translated via the given L{Command}'s response
- de-serialization.
- """
- D = self.dispatcher.callRemote(Hello, hello='world')
- self.assertEqual(self.sender.sentBoxes,
- [amp.AmpBox(_command="hello",
- _ask="1",
- hello="world")])
- answers = []
- D.addCallback(answers.append)
- self.assertEqual(answers, [])
- self.dispatcher.ampBoxReceived(amp.AmpBox({'hello': "yay",
- 'print': "ignored",
- '_answer': "1"}))
- self.assertEqual(answers, [dict(hello="yay",
- Print=u"ignored")])
-
-
- def _localCallbackErrorLoggingTest(self, callResult):
- """
- Verify that C{callResult} completes with a C{None} result and that an
- unhandled error has been logged.
- """
- finalResult = []
- callResult.addBoth(finalResult.append)
-
- self.assertEqual(1, len(self.sender.unhandledErrors))
- self.assertIsInstance(
- self.sender.unhandledErrors[0].value, ZeroDivisionError)
-
- self.assertEqual([None], finalResult)
-
-
- def test_callRemoteSuccessLocalCallbackErrorLogging(self):
- """
- If the last callback on the L{Deferred} returned by C{callRemote} (added
- by application code calling C{callRemote}) fails, the failure is passed
- to the sender's C{unhandledError} method.
- """
- self.sender.expectError()
-
- callResult = self.dispatcher.callRemote(Hello, hello='world')
- callResult.addCallback(lambda result: 1 // 0)
-
- self.dispatcher.ampBoxReceived(amp.AmpBox({
- 'hello': "yay", 'print': "ignored", '_answer': "1"}))
-
- self._localCallbackErrorLoggingTest(callResult)
-
-
- def test_callRemoteErrorLocalCallbackErrorLogging(self):
- """
- Like L{test_callRemoteSuccessLocalCallbackErrorLogging}, but for the
- case where the L{Deferred} returned by C{callRemote} fails.
- """
- self.sender.expectError()
-
- callResult = self.dispatcher.callRemote(Hello, hello='world')
- callResult.addErrback(lambda result: 1 // 0)
-
- self.dispatcher.ampBoxReceived(amp.AmpBox({
- '_error': '1', '_error_code': 'bugs',
- '_error_description': 'stuff'}))
-
- self._localCallbackErrorLoggingTest(callResult)
-
-
-
-class SimpleGreeting(amp.Command):
- """
- A very simple greeting command that uses a few basic argument types.
- """
- commandName = 'simple'
- arguments = [('greeting', amp.Unicode()),
- ('cookie', amp.Integer())]
- response = [('cookieplus', amp.Integer())]
-
-
-
-class TestLocator(amp.CommandLocator):
- """
- A locator which implements a responder to the 'simple' command.
- """
- def __init__(self):
- self.greetings = []
-
-
- def greetingResponder(self, greeting, cookie):
- self.greetings.append((greeting, cookie))
- return dict(cookieplus=cookie + 3)
- greetingResponder = SimpleGreeting.responder(greetingResponder)
-
-
-
-class OverridingLocator(TestLocator):
- """
- A locator which overrides the responder to the 'simple' command.
- """
-
- def greetingResponder(self, greeting, cookie):
- """
- Return a different cookieplus than L{TestLocator.greetingResponder}.
- """
- self.greetings.append((greeting, cookie))
- return dict(cookieplus=cookie + 4)
- greetingResponder = SimpleGreeting.responder(greetingResponder)
-
-
-
-class InheritingLocator(OverridingLocator):
- """
- This locator should inherit the responder from L{OverridingLocator}.
- """
-
-
-
-class OverrideLocatorAMP(amp.AMP):
- def __init__(self):
- amp.AMP.__init__(self)
- self.customResponder = object()
- self.expectations = {"custom": self.customResponder}
- self.greetings = []
-
-
- def lookupFunction(self, name):
- """
- Override the deprecated lookupFunction function.
- """
- if name in self.expectations:
- result = self.expectations[name]
- return result
- else:
- return super(OverrideLocatorAMP, self).lookupFunction(name)
-
-
- def greetingResponder(self, greeting, cookie):
- self.greetings.append((greeting, cookie))
- return dict(cookieplus=cookie + 3)
- greetingResponder = SimpleGreeting.responder(greetingResponder)
-
-
-
-
-class CommandLocatorTests(unittest.TestCase):
- """
- The CommandLocator should enable users to specify responders to commands as
- functions that take structured objects, annotated with metadata.
- """
-
- def _checkSimpleGreeting(self, locatorClass, expected):
- """
- Check that a locator of type C{locatorClass} finds a responder
- for command named I{simple} and that the found responder answers
- with the C{expected} result to a C{SimpleGreeting<"ni hao", 5>}
- command.
- """
- locator = locatorClass()
- responderCallable = locator.locateResponder("simple")
- result = responderCallable(amp.Box(greeting="ni hao", cookie="5"))
- def done(values):
- self.assertEqual(values, amp.AmpBox(cookieplus=str(expected)))
- return result.addCallback(done)
-
-
- def test_responderDecorator(self):
- """
- A method on a L{CommandLocator} subclass decorated with a L{Command}
- subclass's L{responder} decorator should be returned from
- locateResponder, wrapped in logic to serialize and deserialize its
- arguments.
- """
- return self._checkSimpleGreeting(TestLocator, 8)
-
-
- def test_responderOverriding(self):
- """
- L{CommandLocator} subclasses can override a responder inherited from
- a base class by using the L{Command.responder} decorator to register
- a new responder method.
- """
- return self._checkSimpleGreeting(OverridingLocator, 9)
-
-
- def test_responderInheritance(self):
- """
- Responder lookup follows the same rules as normal method lookup
- rules, particularly with respect to inheritance.
- """
- return self._checkSimpleGreeting(InheritingLocator, 9)
-
-
- def test_lookupFunctionDeprecatedOverride(self):
- """
- Subclasses which override locateResponder under its old name,
- lookupFunction, should have the override invoked instead. (This tests
- an AMP subclass, because in the version of the code that could invoke
- this deprecated code path, there was no L{CommandLocator}.)
- """
- locator = OverrideLocatorAMP()
- customResponderObject = self.assertWarns(
- PendingDeprecationWarning,
- "Override locateResponder, not lookupFunction.",
- __file__, lambda : locator.locateResponder("custom"))
- self.assertEqual(locator.customResponder, customResponderObject)
- # Make sure upcalling works too
- normalResponderObject = self.assertWarns(
- PendingDeprecationWarning,
- "Override locateResponder, not lookupFunction.",
- __file__, lambda : locator.locateResponder("simple"))
- result = normalResponderObject(amp.Box(greeting="ni hao", cookie="5"))
- def done(values):
- self.assertEqual(values, amp.AmpBox(cookieplus='8'))
- return result.addCallback(done)
-
-
- def test_lookupFunctionDeprecatedInvoke(self):
- """
- Invoking locateResponder under its old name, lookupFunction, should
- emit a deprecation warning, but do the same thing.
- """
- locator = TestLocator()
- responderCallable = self.assertWarns(
- PendingDeprecationWarning,
- "Call locateResponder, not lookupFunction.", __file__,
- lambda : locator.lookupFunction("simple"))
- result = responderCallable(amp.Box(greeting="ni hao", cookie="5"))
- def done(values):
- self.assertEqual(values, amp.AmpBox(cookieplus='8'))
- return result.addCallback(done)
-
-
-
-SWITCH_CLIENT_DATA = 'Success!'
-SWITCH_SERVER_DATA = 'No, really. Success.'
-
-
-class BinaryProtocolTests(unittest.TestCase):
- """
- Tests for L{amp.BinaryBoxProtocol}.
-
- @ivar _boxSender: After C{startReceivingBoxes} is called, the L{IBoxSender}
- which was passed to it.
- """
-
- def setUp(self):
- """
- Keep track of all boxes received by this test in its capacity as an
- L{IBoxReceiver} implementor.
- """
- self.boxes = []
- self.data = []
-
-
- def startReceivingBoxes(self, sender):
- """
- Implement L{IBoxReceiver.startReceivingBoxes} to just remember the
- value passed in.
- """
- self._boxSender = sender
-
-
- def ampBoxReceived(self, box):
- """
- A box was received by the protocol.
- """
- self.boxes.append(box)
-
- stopReason = None
- def stopReceivingBoxes(self, reason):
- """
- Record the reason that we stopped receiving boxes.
- """
- self.stopReason = reason
-
-
- # fake ITransport
- def getPeer(self):
- return 'no peer'
-
-
- def getHost(self):
- return 'no host'
-
-
- def write(self, data):
- self.data.append(data)
-
-
- def test_startReceivingBoxes(self):
- """
- When L{amp.BinaryBoxProtocol} is connected to a transport, it calls
- C{startReceivingBoxes} on its L{IBoxReceiver} with itself as the
- L{IBoxSender} parameter.
- """
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(None)
- self.assertIdentical(self._boxSender, protocol)
-
-
- def test_sendBoxInStartReceivingBoxes(self):
- """
- The L{IBoxReceiver} which is started when L{amp.BinaryBoxProtocol} is
- connected to a transport can call C{sendBox} on the L{IBoxSender}
- passed to it before C{startReceivingBoxes} returns and have that box
- sent.
- """
- class SynchronouslySendingReceiver:
- def startReceivingBoxes(self, sender):
- sender.sendBox(amp.Box({'foo': 'bar'}))
-
- transport = StringTransport()
- protocol = amp.BinaryBoxProtocol(SynchronouslySendingReceiver())
- protocol.makeConnection(transport)
- self.assertEqual(
- transport.value(),
- '\x00\x03foo\x00\x03bar\x00\x00')
-
-
- def test_receiveBoxStateMachine(self):
- """
- When a binary box protocol receives:
- * a key
- * a value
- * an empty string
- it should emit a box and send it to its boxReceiver.
- """
- a = amp.BinaryBoxProtocol(self)
- a.stringReceived("hello")
- a.stringReceived("world")
- a.stringReceived("")
- self.assertEqual(self.boxes, [amp.AmpBox(hello="world")])
-
-
- def test_firstBoxFirstKeyExcessiveLength(self):
- """
- L{amp.BinaryBoxProtocol} drops its connection if the length prefix for
- the first a key it receives is larger than 255.
- """
- transport = StringTransport()
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(transport)
- protocol.dataReceived('\x01\x00')
- self.assertTrue(transport.disconnecting)
-
-
- def test_firstBoxSubsequentKeyExcessiveLength(self):
- """
- L{amp.BinaryBoxProtocol} drops its connection if the length prefix for
- a subsequent key in the first box it receives is larger than 255.
- """
- transport = StringTransport()
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(transport)
- protocol.dataReceived('\x00\x01k\x00\x01v')
- self.assertFalse(transport.disconnecting)
- protocol.dataReceived('\x01\x00')
- self.assertTrue(transport.disconnecting)
-
-
- def test_subsequentBoxFirstKeyExcessiveLength(self):
- """
- L{amp.BinaryBoxProtocol} drops its connection if the length prefix for
- the first key in a subsequent box it receives is larger than 255.
- """
- transport = StringTransport()
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(transport)
- protocol.dataReceived('\x00\x01k\x00\x01v\x00\x00')
- self.assertFalse(transport.disconnecting)
- protocol.dataReceived('\x01\x00')
- self.assertTrue(transport.disconnecting)
-
-
- def test_excessiveKeyFailure(self):
- """
- If L{amp.BinaryBoxProtocol} disconnects because it received a key
- length prefix which was too large, the L{IBoxReceiver}'s
- C{stopReceivingBoxes} method is called with a L{TooLong} failure.
- """
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('\x01\x00')
- protocol.connectionLost(
- Failure(error.ConnectionDone("simulated connection done")))
- self.stopReason.trap(amp.TooLong)
- self.assertTrue(self.stopReason.value.isKey)
- self.assertFalse(self.stopReason.value.isLocal)
- self.assertIdentical(self.stopReason.value.value, None)
- self.assertIdentical(self.stopReason.value.keyName, None)
-
-
- def test_unhandledErrorWithTransport(self):
- """
- L{amp.BinaryBoxProtocol.unhandledError} logs the failure passed to it
- and disconnects its transport.
- """
- transport = StringTransport()
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(transport)
- protocol.unhandledError(Failure(RuntimeError("Fake error")))
- self.assertEqual(1, len(self.flushLoggedErrors(RuntimeError)))
- self.assertTrue(transport.disconnecting)
-
-
- def test_unhandledErrorWithoutTransport(self):
- """
- L{amp.BinaryBoxProtocol.unhandledError} completes without error when
- there is no associated transport.
- """
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(StringTransport())
- protocol.connectionLost(Failure(Exception("Simulated")))
- protocol.unhandledError(Failure(RuntimeError("Fake error")))
- self.assertEqual(1, len(self.flushLoggedErrors(RuntimeError)))
-
-
- def test_receiveBoxData(self):
- """
- When a binary box protocol receives the serialized form of an AMP box,
- it should emit a similar box to its boxReceiver.
- """
- a = amp.BinaryBoxProtocol(self)
- a.dataReceived(amp.Box({"testKey": "valueTest",
- "anotherKey": "anotherValue"}).serialize())
- self.assertEqual(self.boxes,
- [amp.Box({"testKey": "valueTest",
- "anotherKey": "anotherValue"})])
-
-
- def test_receiveLongerBoxData(self):
- """
- An L{amp.BinaryBoxProtocol} can receive serialized AMP boxes with
- values of up to (2 ** 16 - 1) bytes.
- """
- length = (2 ** 16 - 1)
- value = 'x' * length
- transport = StringTransport()
- protocol = amp.BinaryBoxProtocol(self)
- protocol.makeConnection(transport)
- protocol.dataReceived(amp.Box({'k': value}).serialize())
- self.assertEqual(self.boxes, [amp.Box({'k': value})])
- self.assertFalse(transport.disconnecting)
-
-
- def test_sendBox(self):
- """
- When a binary box protocol sends a box, it should emit the serialized
- bytes of that box to its transport.
- """
- a = amp.BinaryBoxProtocol(self)
- a.makeConnection(self)
- aBox = amp.Box({"testKey": "valueTest",
- "someData": "hello"})
- a.makeConnection(self)
- a.sendBox(aBox)
- self.assertEqual(''.join(self.data), aBox.serialize())
-
-
- def test_connectionLostStopSendingBoxes(self):
- """
- When a binary box protocol loses its connection, it should notify its
- box receiver that it has stopped receiving boxes.
- """
- a = amp.BinaryBoxProtocol(self)
- a.makeConnection(self)
- connectionFailure = Failure(RuntimeError())
- a.connectionLost(connectionFailure)
- self.assertIdentical(self.stopReason, connectionFailure)
-
-
- def test_protocolSwitch(self):
- """
- L{BinaryBoxProtocol} has the capacity to switch to a different protocol
- on a box boundary. When a protocol is in the process of switching, it
- cannot receive traffic.
- """
- otherProto = TestProto(None, "outgoing data")
- test = self
- class SwitchyReceiver:
- switched = False
- def startReceivingBoxes(self, sender):
- pass
- def ampBoxReceived(self, box):
- test.assertFalse(self.switched,
- "Should only receive one box!")
- self.switched = True
- a._lockForSwitch()
- a._switchTo(otherProto)
- a = amp.BinaryBoxProtocol(SwitchyReceiver())
- anyOldBox = amp.Box({"include": "lots",
- "of": "data"})
- a.makeConnection(self)
- # Include a 0-length box at the beginning of the next protocol's data,
- # to make sure that AMP doesn't eat the data or try to deliver extra
- # boxes either...
- moreThanOneBox = anyOldBox.serialize() + "\x00\x00Hello, world!"
- a.dataReceived(moreThanOneBox)
- self.assertIdentical(otherProto.transport, self)
- self.assertEqual("".join(otherProto.data), "\x00\x00Hello, world!")
- self.assertEqual(self.data, ["outgoing data"])
- a.dataReceived("more data")
- self.assertEqual("".join(otherProto.data),
- "\x00\x00Hello, world!more data")
- self.assertRaises(amp.ProtocolSwitched, a.sendBox, anyOldBox)
-
-
- def test_protocolSwitchEmptyBuffer(self):
- """
- After switching to a different protocol, if no extra bytes beyond
- the switch box were delivered, an empty string is not passed to the
- switched protocol's C{dataReceived} method.
- """
- a = amp.BinaryBoxProtocol(self)
- a.makeConnection(self)
- otherProto = TestProto(None, "")
- a._switchTo(otherProto)
- self.assertEqual(otherProto.data, [])
-
-
- def test_protocolSwitchInvalidStates(self):
- """
- In order to make sure the protocol never gets any invalid data sent
- into the middle of a box, it must be locked for switching before it is
- switched. It can only be unlocked if the switch failed, and attempting
- to send a box while it is locked should raise an exception.
- """
- a = amp.BinaryBoxProtocol(self)
- a.makeConnection(self)
- sampleBox = amp.Box({"some": "data"})
- a._lockForSwitch()
- self.assertRaises(amp.ProtocolSwitched, a.sendBox, sampleBox)
- a._unlockFromSwitch()
- a.sendBox(sampleBox)
- self.assertEqual(''.join(self.data), sampleBox.serialize())
- a._lockForSwitch()
- otherProto = TestProto(None, "outgoing data")
- a._switchTo(otherProto)
- self.assertRaises(amp.ProtocolSwitched, a._unlockFromSwitch)
-
-
- def test_protocolSwitchLoseConnection(self):
- """
- When the protocol is switched, it should notify its nested protocol of
- disconnection.
- """
- class Loser(protocol.Protocol):
- reason = None
- def connectionLost(self, reason):
- self.reason = reason
- connectionLoser = Loser()
- a = amp.BinaryBoxProtocol(self)
- a.makeConnection(self)
- a._lockForSwitch()
- a._switchTo(connectionLoser)
- connectionFailure = Failure(RuntimeError())
- a.connectionLost(connectionFailure)
- self.assertEqual(connectionLoser.reason, connectionFailure)
-
-
- def test_protocolSwitchLoseClientConnection(self):
- """
- When the protocol is switched, it should notify its nested client
- protocol factory of disconnection.
- """
- class ClientLoser:
- reason = None
- def clientConnectionLost(self, connector, reason):
- self.reason = reason
- a = amp.BinaryBoxProtocol(self)
- connectionLoser = protocol.Protocol()
- clientLoser = ClientLoser()
- a.makeConnection(self)
- a._lockForSwitch()
- a._switchTo(connectionLoser, clientLoser)
- connectionFailure = Failure(RuntimeError())
- a.connectionLost(connectionFailure)
- self.assertEqual(clientLoser.reason, connectionFailure)
-
-
-
-class AMPTest(unittest.TestCase):
-
- def test_interfaceDeclarations(self):
- """
- The classes in the amp module ought to implement the interfaces that
- are declared for their benefit.
- """
- for interface, implementation in [(amp.IBoxSender, amp.BinaryBoxProtocol),
- (amp.IBoxReceiver, amp.BoxDispatcher),
- (amp.IResponderLocator, amp.CommandLocator),
- (amp.IResponderLocator, amp.SimpleStringLocator),
- (amp.IBoxSender, amp.AMP),
- (amp.IBoxReceiver, amp.AMP),
- (amp.IResponderLocator, amp.AMP)]:
- self.failUnless(interface.implementedBy(implementation),
- "%s does not implements(%s)" % (implementation, interface))
-
-
- def test_helloWorld(self):
- """
- Verify that a simple command can be sent and its response received with
- the simple low-level string-based API.
- """
- c, s, p = connectedServerAndClient()
- L = []
- HELLO = 'world'
- c.sendHello(HELLO).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
-
-
- def test_wireFormatRoundTrip(self):
- """
- Verify that mixed-case, underscored and dashed arguments are mapped to
- their python names properly.
- """
- c, s, p = connectedServerAndClient()
- L = []
- HELLO = 'world'
- c.sendHello(HELLO).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
-
-
- def test_helloWorldUnicode(self):
- """
- Verify that unicode arguments can be encoded and decoded.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- HELLO = 'world'
- HELLO_UNICODE = 'wor\u1234ld'
- c.sendUnicodeHello(HELLO, HELLO_UNICODE).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
- self.assertEqual(L[0]['Print'], HELLO_UNICODE)
-
-
- def test_callRemoteStringRequiresAnswerFalse(self):
- """
- L{BoxDispatcher.callRemoteString} returns C{None} if C{requiresAnswer}
- is C{False}.
- """
- c, s, p = connectedServerAndClient()
- ret = c.callRemoteString("WTF", requiresAnswer=False)
- self.assertIdentical(ret, None)
-
-
- def test_unknownCommandLow(self):
- """
- Verify that unknown commands using low-level APIs will be rejected with an
- error, but will NOT terminate the connection.
- """
- c, s, p = connectedServerAndClient()
- L = []
- def clearAndAdd(e):
- """
- You can't propagate the error...
- """
- e.trap(amp.UnhandledCommand)
- return "OK"
- c.callRemoteString("WTF").addErrback(clearAndAdd).addCallback(L.append)
- p.flush()
- self.assertEqual(L.pop(), "OK")
- HELLO = 'world'
- c.sendHello(HELLO).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
-
-
- def test_unknownCommandHigh(self):
- """
- Verify that unknown commands using high-level APIs will be rejected with an
- error, but will NOT terminate the connection.
- """
- c, s, p = connectedServerAndClient()
- L = []
- def clearAndAdd(e):
- """
- You can't propagate the error...
- """
- e.trap(amp.UnhandledCommand)
- return "OK"
- c.callRemote(WTF).addErrback(clearAndAdd).addCallback(L.append)
- p.flush()
- self.assertEqual(L.pop(), "OK")
- HELLO = 'world'
- c.sendHello(HELLO).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
-
-
- def test_brokenReturnValue(self):
- """
- It can be very confusing if you write some code which responds to a
- command, but gets the return value wrong. Most commonly you end up
- returning None instead of a dictionary.
-
- Verify that if that happens, the framework logs a useful error.
- """
- L = []
- SimpleSymmetricCommandProtocol().dispatchCommand(
- amp.AmpBox(_command=BrokenReturn.commandName)).addErrback(L.append)
- L[0].trap(amp.BadLocalReturn)
- self.failUnlessIn('None', repr(L[0].value))
-
-
- def test_unknownArgument(self):
- """
- Verify that unknown arguments are ignored, and not passed to a Python
- function which can't accept them.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- HELLO = 'world'
- # c.sendHello(HELLO).addCallback(L.append)
- c.callRemote(FutureHello,
- hello=HELLO,
- bonus="I'm not in the book!").addCallback(
- L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
-
-
- def test_simpleReprs(self):
- """
- Verify that the various Box objects repr properly, for debugging.
- """
- self.assertEqual(type(repr(amp._SwitchBox('a'))), str)
- self.assertEqual(type(repr(amp.QuitBox())), str)
- self.assertEqual(type(repr(amp.AmpBox())), str)
- self.failUnless("AmpBox" in repr(amp.AmpBox()))
-
-
- def test_innerProtocolInRepr(self):
- """
- Verify that L{AMP} objects output their innerProtocol when set.
- """
- otherProto = TestProto(None, "outgoing data")
- a = amp.AMP()
- a.innerProtocol = otherProto
- def fakeID(obj):
- return {a: 0x1234}.get(obj, id(obj))
- self.addCleanup(setIDFunction, setIDFunction(fakeID))
-
- self.assertEqual(
- repr(a), "<AMP inner <TestProto #%d> at 0x1234>" % (
- otherProto.instanceId,))
-
-
- def test_innerProtocolNotInRepr(self):
- """
- Verify that L{AMP} objects do not output 'inner' when no innerProtocol
- is set.
- """
- a = amp.AMP()
- def fakeID(obj):
- return {a: 0x4321}.get(obj, id(obj))
- self.addCleanup(setIDFunction, setIDFunction(fakeID))
- self.assertEqual(repr(a), "<AMP at 0x4321>")
-
-
- def test_simpleSSLRepr(self):
- """
- L{amp._TLSBox.__repr__} returns a string.
- """
- self.assertEqual(type(repr(amp._TLSBox())), str)
-
- test_simpleSSLRepr.skip = skipSSL
-
-
- def test_keyTooLong(self):
- """
- Verify that a key that is too long will immediately raise a synchronous
- exception.
- """
- c, s, p = connectedServerAndClient()
- x = "H" * (0xff+1)
- tl = self.assertRaises(amp.TooLong,
- c.callRemoteString, "Hello",
- **{x: "hi"})
- self.assertTrue(tl.isKey)
- self.assertTrue(tl.isLocal)
- self.assertIdentical(tl.keyName, None)
- self.assertEqual(tl.value, x)
- self.assertIn(str(len(x)), repr(tl))
- self.assertIn("key", repr(tl))
-
-
- def test_valueTooLong(self):
- """
- Verify that attempting to send value longer than 64k will immediately
- raise an exception.
- """
- c, s, p = connectedServerAndClient()
- x = "H" * (0xffff+1)
- tl = self.assertRaises(amp.TooLong, c.sendHello, x)
- p.flush()
- self.failIf(tl.isKey)
- self.failUnless(tl.isLocal)
- self.assertEqual(tl.keyName, 'hello')
- self.failUnlessIdentical(tl.value, x)
- self.failUnless(str(len(x)) in repr(tl))
- self.failUnless("value" in repr(tl))
- self.failUnless('hello' in repr(tl))
-
-
- def test_helloWorldCommand(self):
- """
- Verify that a simple command can be sent and its response received with
- the high-level value parsing API.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- HELLO = 'world'
- c.sendHello(HELLO).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0]['hello'], HELLO)
-
-
- def test_helloErrorHandling(self):
- """
- Verify that if a known error type is raised and handled, it will be
- properly relayed to the other end of the connection and translated into
- an exception, and no error will be logged.
- """
- L=[]
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- HELLO = 'fuck you'
- c.sendHello(HELLO).addErrback(L.append)
- p.flush()
- L[0].trap(UnfriendlyGreeting)
- self.assertEqual(str(L[0].value), "Don't be a dick.")
-
-
- def test_helloFatalErrorHandling(self):
- """
- Verify that if a known, fatal error type is raised and handled, it will
- be properly relayed to the other end of the connection and translated
- into an exception, no error will be logged, and the connection will be
- terminated.
- """
- L=[]
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- HELLO = 'die'
- c.sendHello(HELLO).addErrback(L.append)
- p.flush()
- L.pop().trap(DeathThreat)
- c.sendHello(HELLO).addErrback(L.append)
- p.flush()
- L.pop().trap(error.ConnectionDone)
-
-
-
- def test_helloNoErrorHandling(self):
- """
- Verify that if an unknown error type is raised, it will be relayed to
- the other end of the connection and translated into an exception, it
- will be logged, and then the connection will be dropped.
- """
- L=[]
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- HELLO = THING_I_DONT_UNDERSTAND
- c.sendHello(HELLO).addErrback(L.append)
- p.flush()
- ure = L.pop()
- ure.trap(amp.UnknownRemoteError)
- c.sendHello(HELLO).addErrback(L.append)
- cl = L.pop()
- cl.trap(error.ConnectionDone)
- # The exception should have been logged.
- self.failUnless(self.flushLoggedErrors(ThingIDontUnderstandError))
-
-
-
- def test_lateAnswer(self):
- """
- Verify that a command that does not get answered until after the
- connection terminates will not cause any errors.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- c.callRemote(WaitForever).addErrback(L.append)
- p.flush()
- self.assertEqual(L, [])
- s.transport.loseConnection()
- p.flush()
- L.pop().trap(error.ConnectionDone)
- # Just make sure that it doesn't error...
- s.waiting.callback({})
- return s.waiting
-
-
- def test_requiresNoAnswer(self):
- """
- Verify that a command that requires no answer is run.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- HELLO = 'world'
- c.callRemote(NoAnswerHello, hello=HELLO)
- p.flush()
- self.failUnless(s.greeted)
-
-
- def test_requiresNoAnswerFail(self):
- """
- Verify that commands sent after a failed no-answer request do not complete.
- """
- L=[]
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- HELLO = 'fuck you'
- c.callRemote(NoAnswerHello, hello=HELLO)
- p.flush()
- # This should be logged locally.
- self.failUnless(self.flushLoggedErrors(amp.RemoteAmpError))
- HELLO = 'world'
- c.callRemote(Hello, hello=HELLO).addErrback(L.append)
- p.flush()
- L.pop().trap(error.ConnectionDone)
- self.failIf(s.greeted)
-
-
- def test_noAnswerResponderBadAnswer(self):
- """
- Verify that responders of requiresAnswer=False commands have to return
- a dictionary anyway.
-
- (requiresAnswer is a hint from the _client_ - the server may be called
- upon to answer commands in any case, if the client wants to know when
- they complete.)
- """
- c, s, p = connectedServerAndClient(
- ServerClass=BadNoAnswerCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- c.callRemote(NoAnswerHello, hello="hello")
- p.flush()
- le = self.flushLoggedErrors(amp.BadLocalReturn)
- self.assertEqual(len(le), 1)
-
-
- def test_noAnswerResponderAskedForAnswer(self):
- """
- Verify that responders with requiresAnswer=False will actually respond
- if the client sets requiresAnswer=True. In other words, verify that
- requiresAnswer is a hint honored only by the client.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=NoAnswerCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- c.callRemote(Hello, hello="Hello!").addCallback(L.append)
- p.flush()
- self.assertEqual(len(L), 1)
- self.assertEqual(L, [dict(hello="Hello!-noanswer",
- Print=None)]) # Optional response argument
-
-
- def test_ampListCommand(self):
- """
- Test encoding of an argument that uses the AmpList encoding.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- c.callRemote(GetList, length=10).addCallback(L.append)
- p.flush()
- values = L.pop().get('body')
- self.assertEqual(values, [{'x': 1}] * 10)
-
-
- def test_optionalAmpListOmitted(self):
- """
- Sending a command with an omitted AmpList argument that is
- designated as optional does not raise an InvalidSignature error.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- c.callRemote(DontRejectMe, magicWord=u'please').addCallback(L.append)
- p.flush()
- response = L.pop().get('response')
- self.assertEqual(response, 'list omitted')
-
-
- def test_optionalAmpListPresent(self):
- """
- Sanity check that optional AmpList arguments are processed normally.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
- L = []
- c.callRemote(DontRejectMe, magicWord=u'please',
- list=[{'name': 'foo'}]).addCallback(L.append)
- p.flush()
- response = L.pop().get('response')
- self.assertEqual(response, 'foo accepted')
-
-
- def test_failEarlyOnArgSending(self):
- """
- Verify that if we pass an invalid argument list (omitting an argument),
- an exception will be raised.
- """
- self.assertRaises(amp.InvalidSignature, Hello)
-
-
- def test_doubleProtocolSwitch(self):
- """
- As a debugging aid, a protocol system should raise a
- L{ProtocolSwitched} exception when asked to switch a protocol that is
- already switched.
- """
- serverDeferred = defer.Deferred()
- serverProto = SimpleSymmetricCommandProtocol(serverDeferred)
- clientDeferred = defer.Deferred()
- clientProto = SimpleSymmetricCommandProtocol(clientDeferred)
- c, s, p = connectedServerAndClient(ServerClass=lambda: serverProto,
- ClientClass=lambda: clientProto)
- def switched(result):
- self.assertRaises(amp.ProtocolSwitched, c.switchToTestProtocol)
- self.testSucceeded = True
- c.switchToTestProtocol().addCallback(switched)
- p.flush()
- self.failUnless(self.testSucceeded)
-
-
- def test_protocolSwitch(self, switcher=SimpleSymmetricCommandProtocol,
- spuriousTraffic=False,
- spuriousError=False):
- """
- Verify that it is possible to switch to another protocol mid-connection and
- send data to it successfully.
- """
- self.testSucceeded = False
-
- serverDeferred = defer.Deferred()
- serverProto = switcher(serverDeferred)
- clientDeferred = defer.Deferred()
- clientProto = switcher(clientDeferred)
- c, s, p = connectedServerAndClient(ServerClass=lambda: serverProto,
- ClientClass=lambda: clientProto)
-
- if spuriousTraffic:
- wfdr = [] # remote
- c.callRemote(WaitForever).addErrback(wfdr.append)
- switchDeferred = c.switchToTestProtocol()
- if spuriousTraffic:
- self.assertRaises(amp.ProtocolSwitched, c.sendHello, 'world')
-
- def cbConnsLost(((serverSuccess, serverData),
- (clientSuccess, clientData))):
- self.failUnless(serverSuccess)
- self.failUnless(clientSuccess)
- self.assertEqual(''.join(serverData), SWITCH_CLIENT_DATA)
- self.assertEqual(''.join(clientData), SWITCH_SERVER_DATA)
- self.testSucceeded = True
-
- def cbSwitch(proto):
- return defer.DeferredList(
- [serverDeferred, clientDeferred]).addCallback(cbConnsLost)
-
- switchDeferred.addCallback(cbSwitch)
- p.flush()
- if serverProto.maybeLater is not None:
- serverProto.maybeLater.callback(serverProto.maybeLaterProto)
- p.flush()
- if spuriousTraffic:
- # switch is done here; do this here to make sure that if we're
- # going to corrupt the connection, we do it before it's closed.
- if spuriousError:
- s.waiting.errback(amp.RemoteAmpError(
- "SPURIOUS",
- "Here's some traffic in the form of an error."))
- else:
- s.waiting.callback({})
- p.flush()
- c.transport.loseConnection() # close it
- p.flush()
- self.failUnless(self.testSucceeded)
-
-
- def test_protocolSwitchDeferred(self):
- """
- Verify that protocol-switching even works if the value returned from
- the command that does the switch is deferred.
- """
- return self.test_protocolSwitch(switcher=DeferredSymmetricCommandProtocol)
-
-
- def test_protocolSwitchFail(self, switcher=SimpleSymmetricCommandProtocol):
- """
- Verify that if we try to switch protocols and it fails, the connection
- stays up and we can go back to speaking AMP.
- """
- self.testSucceeded = False
-
- serverDeferred = defer.Deferred()
- serverProto = switcher(serverDeferred)
- clientDeferred = defer.Deferred()
- clientProto = switcher(clientDeferred)
- c, s, p = connectedServerAndClient(ServerClass=lambda: serverProto,
- ClientClass=lambda: clientProto)
- L = []
- c.switchToTestProtocol(fail=True).addErrback(L.append)
- p.flush()
- L.pop().trap(UnknownProtocol)
- self.failIf(self.testSucceeded)
- # It's a known error, so let's send a "hello" on the same connection;
- # it should work.
- c.sendHello('world').addCallback(L.append)
- p.flush()
- self.assertEqual(L.pop()['hello'], 'world')
-
-
- def test_trafficAfterSwitch(self):
- """
- Verify that attempts to send traffic after a switch will not corrupt
- the nested protocol.
- """
- return self.test_protocolSwitch(spuriousTraffic=True)
-
-
- def test_errorAfterSwitch(self):
- """
- Returning an error after a protocol switch should record the underlying
- error.
- """
- return self.test_protocolSwitch(spuriousTraffic=True,
- spuriousError=True)
-
-
- def test_quitBoxQuits(self):
- """
- Verify that commands with a responseType of QuitBox will in fact
- terminate the connection.
- """
- c, s, p = connectedServerAndClient(
- ServerClass=SimpleSymmetricCommandProtocol,
- ClientClass=SimpleSymmetricCommandProtocol)
-
- L = []
- HELLO = 'world'
- GOODBYE = 'everyone'
- c.sendHello(HELLO).addCallback(L.append)
- p.flush()
- self.assertEqual(L.pop()['hello'], HELLO)
- c.callRemote(Goodbye).addCallback(L.append)
- p.flush()
- self.assertEqual(L.pop()['goodbye'], GOODBYE)
- c.sendHello(HELLO).addErrback(L.append)
- L.pop().trap(error.ConnectionDone)
-
-
- def test_basicLiteralEmit(self):
- """
- Verify that the command dictionaries for a callRemoteN look correct
- after being serialized and parsed.
- """
- c, s, p = connectedServerAndClient()
- L = []
- s.ampBoxReceived = L.append
- c.callRemote(Hello, hello='hello test', mixedCase='mixed case arg test',
- dash_arg='x', underscore_arg='y')
- p.flush()
- self.assertEqual(len(L), 1)
- for k, v in [('_command', Hello.commandName),
- ('hello', 'hello test'),
- ('mixedCase', 'mixed case arg test'),
- ('dash-arg', 'x'),
- ('underscore_arg', 'y')]:
- self.assertEqual(L[-1].pop(k), v)
- L[-1].pop('_ask')
- self.assertEqual(L[-1], {})
-
-
- def test_basicStructuredEmit(self):
- """
- Verify that a call similar to basicLiteralEmit's is handled properly with
- high-level quoting and passing to Python methods, and that argument
- names are correctly handled.
- """
- L = []
- class StructuredHello(amp.AMP):
- def h(self, *a, **k):
- L.append((a, k))
- return dict(hello='aaa')
- Hello.responder(h)
- c, s, p = connectedServerAndClient(ServerClass=StructuredHello)
- c.callRemote(Hello, hello='hello test', mixedCase='mixed case arg test',
- dash_arg='x', underscore_arg='y').addCallback(L.append)
- p.flush()
- self.assertEqual(len(L), 2)
- self.assertEqual(L[0],
- ((), dict(
- hello='hello test',
- mixedCase='mixed case arg test',
- dash_arg='x',
- underscore_arg='y',
-
- # XXX - should optional arguments just not be passed?
- # passing None seems a little odd, looking at the way it
- # turns out here... -glyph
- From=('file', 'file'),
- Print=None,
- optional=None,
- )))
- self.assertEqual(L[1], dict(Print=None, hello='aaa'))
-
-class PretendRemoteCertificateAuthority:
- def checkIsPretendRemote(self):
- return True
-
-class IOSimCert:
- verifyCount = 0
-
- def options(self, *ign):
- return self
-
- def iosimVerify(self, otherCert):
- """
- This isn't a real certificate, and wouldn't work on a real socket, but
- iosim specifies a different API so that we don't have to do any crypto
- math to demonstrate that the right functions get called in the right
- places.
- """
- assert otherCert is self
- self.verifyCount += 1
- return True
-
-class OKCert(IOSimCert):
- def options(self, x):
- assert x.checkIsPretendRemote()
- return self
-
-class GrumpyCert(IOSimCert):
- def iosimVerify(self, otherCert):
- self.verifyCount += 1
- return False
-
-class DroppyCert(IOSimCert):
- def __init__(self, toDrop):
- self.toDrop = toDrop
-
- def iosimVerify(self, otherCert):
- self.verifyCount += 1
- self.toDrop.loseConnection()
- return True
-
-class SecurableProto(FactoryNotifier):
-
- factory = None
-
- def verifyFactory(self):
- return [PretendRemoteCertificateAuthority()]
-
- def getTLSVars(self):
- cert = self.certFactory()
- verify = self.verifyFactory()
- return dict(
- tls_localCertificate=cert,
- tls_verifyAuthorities=verify)
- amp.StartTLS.responder(getTLSVars)
-
-
-
-class TLSTest(unittest.TestCase):
- def test_startingTLS(self):
- """
- Verify that starting TLS and succeeding at handshaking sends all the
- notifications to all the right places.
- """
- cli, svr, p = connectedServerAndClient(
- ServerClass=SecurableProto,
- ClientClass=SecurableProto)
-
- okc = OKCert()
- svr.certFactory = lambda : okc
-
- cli.callRemote(
- amp.StartTLS, tls_localCertificate=okc,
- tls_verifyAuthorities=[PretendRemoteCertificateAuthority()])
-
- # let's buffer something to be delivered securely
- L = []
- cli.callRemote(SecuredPing).addCallback(L.append)
- p.flush()
- # once for client once for server
- self.assertEqual(okc.verifyCount, 2)
- L = []
- cli.callRemote(SecuredPing).addCallback(L.append)
- p.flush()
- self.assertEqual(L[0], {'pinged': True})
-
-
- def test_startTooManyTimes(self):
- """
- Verify that the protocol will complain if we attempt to renegotiate TLS,
- which we don't support.
- """
- cli, svr, p = connectedServerAndClient(
- ServerClass=SecurableProto,
- ClientClass=SecurableProto)
-
- okc = OKCert()
- svr.certFactory = lambda : okc
-
- cli.callRemote(amp.StartTLS,
- tls_localCertificate=okc,
- tls_verifyAuthorities=[PretendRemoteCertificateAuthority()])
- p.flush()
- cli.noPeerCertificate = True # this is totally fake
- self.assertRaises(
- amp.OnlyOneTLS,
- cli.callRemote,
- amp.StartTLS,
- tls_localCertificate=okc,
- tls_verifyAuthorities=[PretendRemoteCertificateAuthority()])
-
-
- def test_negotiationFailed(self):
- """
- Verify that starting TLS and failing on both sides at handshaking sends
- notifications to all the right places and terminates the connection.
- """
-
- badCert = GrumpyCert()
-
- cli, svr, p = connectedServerAndClient(
- ServerClass=SecurableProto,
- ClientClass=SecurableProto)
- svr.certFactory = lambda : badCert
-
- cli.callRemote(amp.StartTLS,
- tls_localCertificate=badCert)
-
- p.flush()
- # once for client once for server - but both fail
- self.assertEqual(badCert.verifyCount, 2)
- d = cli.callRemote(SecuredPing)
- p.flush()
- self.assertFailure(d, iosim.NativeOpenSSLError)
-
-
- def test_negotiationFailedByClosing(self):
- """
- Verify that starting TLS and failing by way of a lost connection
- notices that it is probably an SSL problem.
- """
-
- cli, svr, p = connectedServerAndClient(
- ServerClass=SecurableProto,
- ClientClass=SecurableProto)
- droppyCert = DroppyCert(svr.transport)
- svr.certFactory = lambda : droppyCert
-
- cli.callRemote(amp.StartTLS, tls_localCertificate=droppyCert)
-
- p.flush()
-
- self.assertEqual(droppyCert.verifyCount, 2)
-
- d = cli.callRemote(SecuredPing)
- p.flush()
-
- # it might be a good idea to move this exception somewhere more
- # reasonable.
- self.assertFailure(d, error.PeerVerifyError)
-
- skip = skipSSL
-
-
-
-class TLSNotAvailableTest(unittest.TestCase):
- """
- Tests what happened when ssl is not available in current installation.
- """
-
- def setUp(self):
- """
- Disable ssl in amp.
- """
- self.ssl = amp.ssl
- amp.ssl = None
-
-
- def tearDown(self):
- """
- Restore ssl module.
- """
- amp.ssl = self.ssl
-
-
- def test_callRemoteError(self):
- """
- Check that callRemote raises an exception when called with a
- L{amp.StartTLS}.
- """
- cli, svr, p = connectedServerAndClient(
- ServerClass=SecurableProto,
- ClientClass=SecurableProto)
-
- okc = OKCert()
- svr.certFactory = lambda : okc
-
- return self.assertFailure(cli.callRemote(
- amp.StartTLS, tls_localCertificate=okc,
- tls_verifyAuthorities=[PretendRemoteCertificateAuthority()]),
- RuntimeError)
-
-
- def test_messageReceivedError(self):
- """
- When a client with SSL enabled talks to a server without SSL, it
- should return a meaningful error.
- """
- svr = SecurableProto()
- okc = OKCert()
- svr.certFactory = lambda : okc
- box = amp.Box()
- box['_command'] = 'StartTLS'
- box['_ask'] = '1'
- boxes = []
- svr.sendBox = boxes.append
- svr.makeConnection(StringTransport())
- svr.ampBoxReceived(box)
- self.assertEqual(boxes,
- [{'_error_code': 'TLS_ERROR',
- '_error': '1',
- '_error_description': 'TLS not available'}])
-
-
-
-class InheritedError(Exception):
- """
- This error is used to check inheritance.
- """
-
-
-
-class OtherInheritedError(Exception):
- """
- This is a distinct error for checking inheritance.
- """
-
-
-
-class BaseCommand(amp.Command):
- """
- This provides a command that will be subclassed.
- """
- errors = {InheritedError: 'INHERITED_ERROR'}
-
-
-
-class InheritedCommand(BaseCommand):
- """
- This is a command which subclasses another command but does not override
- anything.
- """
-
-
-
-class AddErrorsCommand(BaseCommand):
- """
- This is a command which subclasses another command but adds errors to the
- list.
- """
- arguments = [('other', amp.Boolean())]
- errors = {OtherInheritedError: 'OTHER_INHERITED_ERROR'}
-
-
-
-class NormalCommandProtocol(amp.AMP):
- """
- This is a protocol which responds to L{BaseCommand}, and is used to test
- that inheritance does not interfere with the normal handling of errors.
- """
- def resp(self):
- raise InheritedError()
- BaseCommand.responder(resp)
-
-
-
-class InheritedCommandProtocol(amp.AMP):
- """
- This is a protocol which responds to L{InheritedCommand}, and is used to
- test that inherited commands inherit their bases' errors if they do not
- respond to any of their own.
- """
- def resp(self):
- raise InheritedError()
- InheritedCommand.responder(resp)
-
-
-
-class AddedCommandProtocol(amp.AMP):
- """
- This is a protocol which responds to L{AddErrorsCommand}, and is used to
- test that inherited commands can add their own new types of errors, but
- still respond in the same way to their parents types of errors.
- """
- def resp(self, other):
- if other:
- raise OtherInheritedError()
- else:
- raise InheritedError()
- AddErrorsCommand.responder(resp)
-
-
-
-class CommandInheritanceTests(unittest.TestCase):
- """
- These tests verify that commands inherit error conditions properly.
- """
-
- def errorCheck(self, err, proto, cmd, **kw):
- """
- Check that the appropriate kind of error is raised when a given command
- is sent to a given protocol.
- """
- c, s, p = connectedServerAndClient(ServerClass=proto,
- ClientClass=proto)
- d = c.callRemote(cmd, **kw)
- d2 = self.failUnlessFailure(d, err)
- p.flush()
- return d2
-
-
- def test_basicErrorPropagation(self):
- """
- Verify that errors specified in a superclass are respected normally
- even if it has subclasses.
- """
- return self.errorCheck(
- InheritedError, NormalCommandProtocol, BaseCommand)
-
-
- def test_inheritedErrorPropagation(self):
- """
- Verify that errors specified in a superclass command are propagated to
- its subclasses.
- """
- return self.errorCheck(
- InheritedError, InheritedCommandProtocol, InheritedCommand)
-
-
- def test_inheritedErrorAddition(self):
- """
- Verify that new errors specified in a subclass of an existing command
- are honored even if the superclass defines some errors.
- """
- return self.errorCheck(
- OtherInheritedError, AddedCommandProtocol, AddErrorsCommand, other=True)
-
-
- def test_additionWithOriginalError(self):
- """
- Verify that errors specified in a command's superclass are respected
- even if that command defines new errors itself.
- """
- return self.errorCheck(
- InheritedError, AddedCommandProtocol, AddErrorsCommand, other=False)
-
-
-def _loseAndPass(err, proto):
- # be specific, pass on the error to the client.
- err.trap(error.ConnectionLost, error.ConnectionDone)
- del proto.connectionLost
- proto.connectionLost(err)
-
-
-class LiveFireBase:
- """
- Utility for connected reactor-using tests.
- """
-
- def setUp(self):
- """
- Create an amp server and connect a client to it.
- """
- from twisted.internet import reactor
- self.serverFactory = protocol.ServerFactory()
- self.serverFactory.protocol = self.serverProto
- self.clientFactory = protocol.ClientFactory()
- self.clientFactory.protocol = self.clientProto
- self.clientFactory.onMade = defer.Deferred()
- self.serverFactory.onMade = defer.Deferred()
- self.serverPort = reactor.listenTCP(0, self.serverFactory)
- self.addCleanup(self.serverPort.stopListening)
- self.clientConn = reactor.connectTCP(
- '127.0.0.1', self.serverPort.getHost().port,
- self.clientFactory)
- self.addCleanup(self.clientConn.disconnect)
- def getProtos(rlst):
- self.cli = self.clientFactory.theProto
- self.svr = self.serverFactory.theProto
- dl = defer.DeferredList([self.clientFactory.onMade,
- self.serverFactory.onMade])
- return dl.addCallback(getProtos)
-
- def tearDown(self):
- """
- Cleanup client and server connections, and check the error got at
- C{connectionLost}.
- """
- L = []
- for conn in self.cli, self.svr:
- if conn.transport is not None:
- # depend on amp's function connection-dropping behavior
- d = defer.Deferred().addErrback(_loseAndPass, conn)
- conn.connectionLost = d.errback
- conn.transport.loseConnection()
- L.append(d)
- return defer.gatherResults(L
- ).addErrback(lambda first: first.value.subFailure)
-
-
-def show(x):
- import sys
- sys.stdout.write(x+'\n')
- sys.stdout.flush()
-
-
-def tempSelfSigned():
- from twisted.internet import ssl
-
- sharedDN = ssl.DN(CN='shared')
- key = ssl.KeyPair.generate()
- cr = key.certificateRequest(sharedDN)
- sscrd = key.signCertificateRequest(
- sharedDN, cr, lambda dn: True, 1234567)
- cert = key.newCertificate(sscrd)
- return cert
-
-if ssl is not None:
- tempcert = tempSelfSigned()
-
-
-class LiveFireTLSTestCase(LiveFireBase, unittest.TestCase):
- clientProto = SecurableProto
- serverProto = SecurableProto
- def test_liveFireCustomTLS(self):
- """
- Using real, live TLS, actually negotiate a connection.
-
- This also looks at the 'peerCertificate' attribute's correctness, since
- that's actually loaded using OpenSSL calls, but the main purpose is to
- make sure that we didn't miss anything obvious in iosim about TLS
- negotiations.
- """
-
- cert = tempcert
-
- self.svr.verifyFactory = lambda : [cert]
- self.svr.certFactory = lambda : cert
- # only needed on the server, we specify the client below.
-
- def secured(rslt):
- x = cert.digest()
- def pinged(rslt2):
- # Interesting. OpenSSL won't even _tell_ us about the peer
- # cert until we negotiate. we should be able to do this in
- # 'secured' instead, but it looks like we can't. I think this
- # is a bug somewhere far deeper than here.
- self.assertEqual(x, self.cli.hostCertificate.digest())
- self.assertEqual(x, self.cli.peerCertificate.digest())
- self.assertEqual(x, self.svr.hostCertificate.digest())
- self.assertEqual(x, self.svr.peerCertificate.digest())
- return self.cli.callRemote(SecuredPing).addCallback(pinged)
- return self.cli.callRemote(amp.StartTLS,
- tls_localCertificate=cert,
- tls_verifyAuthorities=[cert]).addCallback(secured)
-
- skip = skipSSL
-
-
-
-class SlightlySmartTLS(SimpleSymmetricCommandProtocol):
- """
- Specific implementation of server side protocol with different
- management of TLS.
- """
- def getTLSVars(self):
- """
- @return: the global C{tempcert} certificate as local certificate.
- """
- return dict(tls_localCertificate=tempcert)
- amp.StartTLS.responder(getTLSVars)
-
-
-class PlainVanillaLiveFire(LiveFireBase, unittest.TestCase):
-
- clientProto = SimpleSymmetricCommandProtocol
- serverProto = SimpleSymmetricCommandProtocol
-
- def test_liveFireDefaultTLS(self):
- """
- Verify that out of the box, we can start TLS to at least encrypt the
- connection, even if we don't have any certificates to use.
- """
- def secured(result):
- return self.cli.callRemote(SecuredPing)
- return self.cli.callRemote(amp.StartTLS).addCallback(secured)
-
- skip = skipSSL
-
-
-
-class WithServerTLSVerification(LiveFireBase, unittest.TestCase):
- clientProto = SimpleSymmetricCommandProtocol
- serverProto = SlightlySmartTLS
-
- def test_anonymousVerifyingClient(self):
- """
- Verify that anonymous clients can verify server certificates.
- """
- def secured(result):
- return self.cli.callRemote(SecuredPing)
- return self.cli.callRemote(amp.StartTLS,
- tls_verifyAuthorities=[tempcert]
- ).addCallback(secured)
-
- skip = skipSSL
-
-
-
-class ProtocolIncludingArgument(amp.Argument):
- """
- An L{amp.Argument} which encodes its parser and serializer
- arguments *including the protocol* into its parsed and serialized
- forms.
- """
-
- def fromStringProto(self, string, protocol):
- """
- Don't decode anything; just return all possible information.
-
- @return: A two-tuple of the input string and the protocol.
- """
- return (string, protocol)
-
- def toStringProto(self, obj, protocol):
- """
- Encode identifying information about L{object} and protocol
- into a string for later verification.
-
- @type obj: L{object}
- @type protocol: L{amp.AMP}
- """
- return "%s:%s" % (id(obj), id(protocol))
-
-
-
-class ProtocolIncludingCommand(amp.Command):
- """
- A command that has argument and response schemas which use
- L{ProtocolIncludingArgument}.
- """
- arguments = [('weird', ProtocolIncludingArgument())]
- response = [('weird', ProtocolIncludingArgument())]
-
-
-
-class MagicSchemaCommand(amp.Command):
- """
- A command which overrides L{parseResponse}, L{parseArguments}, and
- L{makeResponse}.
- """
- def parseResponse(self, strings, protocol):
- """
- Don't do any parsing, just jam the input strings and protocol
- onto the C{protocol.parseResponseArguments} attribute as a
- two-tuple. Return the original strings.
- """
- protocol.parseResponseArguments = (strings, protocol)
- return strings
- parseResponse = classmethod(parseResponse)
-
-
- def parseArguments(cls, strings, protocol):
- """
- Don't do any parsing, just jam the input strings and protocol
- onto the C{protocol.parseArgumentsArguments} attribute as a
- two-tuple. Return the original strings.
- """
- protocol.parseArgumentsArguments = (strings, protocol)
- return strings
- parseArguments = classmethod(parseArguments)
-
-
- def makeArguments(cls, objects, protocol):
- """
- Don't do any serializing, just jam the input strings and protocol
- onto the C{protocol.makeArgumentsArguments} attribute as a
- two-tuple. Return the original strings.
- """
- protocol.makeArgumentsArguments = (objects, protocol)
- return objects
- makeArguments = classmethod(makeArguments)
-
-
-
-class NoNetworkProtocol(amp.AMP):
- """
- An L{amp.AMP} subclass which overrides private methods to avoid
- testing the network. It also provides a responder for
- L{MagicSchemaCommand} that does nothing, so that tests can test
- aspects of the interaction of L{amp.Command}s and L{amp.AMP}.
-
- @ivar parseArgumentsArguments: Arguments that have been passed to any
- L{MagicSchemaCommand}, if L{MagicSchemaCommand} has been handled by
- this protocol.
-
- @ivar parseResponseArguments: Responses that have been returned from a
- L{MagicSchemaCommand}, if L{MagicSchemaCommand} has been handled by
- this protocol.
-
- @ivar makeArgumentsArguments: Arguments that have been serialized by any
- L{MagicSchemaCommand}, if L{MagicSchemaCommand} has been handled by
- this protocol.
- """
- def _sendBoxCommand(self, commandName, strings, requiresAnswer):
- """
- Return a Deferred which fires with the original strings.
- """
- return defer.succeed(strings)
-
- MagicSchemaCommand.responder(lambda s, weird: {})
-
-
-
-class MyBox(dict):
- """
- A unique dict subclass.
- """
-
-
-
-class ProtocolIncludingCommandWithDifferentCommandType(
- ProtocolIncludingCommand):
- """
- A L{ProtocolIncludingCommand} subclass whose commandType is L{MyBox}
- """
- commandType = MyBox
-
-
-
-class CommandTestCase(unittest.TestCase):
- """
- Tests for L{amp.Argument} and L{amp.Command}.
- """
- def test_argumentInterface(self):
- """
- L{Argument} instances provide L{amp.IArgumentType}.
- """
- self.assertTrue(verifyObject(amp.IArgumentType, amp.Argument()))
-
-
- def test_parseResponse(self):
- """
- There should be a class method of Command which accepts a
- mapping of argument names to serialized forms and returns a
- similar mapping whose values have been parsed via the
- Command's response schema.
- """
- protocol = object()
- result = 'whatever'
- strings = {'weird': result}
- self.assertEqual(
- ProtocolIncludingCommand.parseResponse(strings, protocol),
- {'weird': (result, protocol)})
-
-
- def test_callRemoteCallsParseResponse(self):
- """
- Making a remote call on a L{amp.Command} subclass which
- overrides the C{parseResponse} method should call that
- C{parseResponse} method to get the response.
- """
- client = NoNetworkProtocol()
- thingy = "weeoo"
- response = client.callRemote(MagicSchemaCommand, weird=thingy)
- def gotResponse(ign):
- self.assertEqual(client.parseResponseArguments,
- ({"weird": thingy}, client))
- response.addCallback(gotResponse)
- return response
-
-
- def test_parseArguments(self):
- """
- There should be a class method of L{amp.Command} which accepts
- a mapping of argument names to serialized forms and returns a
- similar mapping whose values have been parsed via the
- command's argument schema.
- """
- protocol = object()
- result = 'whatever'
- strings = {'weird': result}
- self.assertEqual(
- ProtocolIncludingCommand.parseArguments(strings, protocol),
- {'weird': (result, protocol)})
-
-
- def test_responderCallsParseArguments(self):
- """
- Making a remote call on a L{amp.Command} subclass which
- overrides the C{parseArguments} method should call that
- C{parseArguments} method to get the arguments.
- """
- protocol = NoNetworkProtocol()
- responder = protocol.locateResponder(MagicSchemaCommand.commandName)
- argument = object()
- response = responder(dict(weird=argument))
- response.addCallback(
- lambda ign: self.assertEqual(protocol.parseArgumentsArguments,
- ({"weird": argument}, protocol)))
- return response
-
-
- def test_makeArguments(self):
- """
- There should be a class method of L{amp.Command} which accepts
- a mapping of argument names to objects and returns a similar
- mapping whose values have been serialized via the command's
- argument schema.
- """
- protocol = object()
- argument = object()
- objects = {'weird': argument}
- self.assertEqual(
- ProtocolIncludingCommand.makeArguments(objects, protocol),
- {'weird': "%d:%d" % (id(argument), id(protocol))})
-
-
- def test_makeArgumentsUsesCommandType(self):
- """
- L{amp.Command.makeArguments}'s return type should be the type
- of the result of L{amp.Command.commandType}.
- """
- protocol = object()
- objects = {"weird": "whatever"}
-
- result = ProtocolIncludingCommandWithDifferentCommandType.makeArguments(
- objects, protocol)
- self.assertIdentical(type(result), MyBox)
-
-
- def test_callRemoteCallsMakeArguments(self):
- """
- Making a remote call on a L{amp.Command} subclass which
- overrides the C{makeArguments} method should call that
- C{makeArguments} method to get the response.
- """
- client = NoNetworkProtocol()
- argument = object()
- response = client.callRemote(MagicSchemaCommand, weird=argument)
- def gotResponse(ign):
- self.assertEqual(client.makeArgumentsArguments,
- ({"weird": argument}, client))
- response.addCallback(gotResponse)
- return response
-
-
- def test_extraArgumentsDisallowed(self):
- """
- L{Command.makeArguments} raises L{amp.InvalidSignature} if the objects
- dictionary passed to it includes a key which does not correspond to the
- Python identifier for a defined argument.
- """
- self.assertRaises(
- amp.InvalidSignature,
- Hello.makeArguments,
- dict(hello="hello", bogusArgument=object()), None)
-
-
- def test_wireSpellingDisallowed(self):
- """
- If a command argument conflicts with a Python keyword, the
- untransformed argument name is not allowed as a key in the dictionary
- passed to L{Command.makeArguments}. If it is supplied,
- L{amp.InvalidSignature} is raised.
-
- This may be a pointless implementation restriction which may be lifted.
- The current behavior is tested to verify that such arguments are not
- silently dropped on the floor (the previous behavior).
- """
- self.assertRaises(
- amp.InvalidSignature,
- Hello.makeArguments,
- dict(hello="required", **{"print": "print value"}),
- None)
-
-
-class ListOfTestsMixin:
- """
- Base class for testing L{ListOf}, a parameterized zero-or-more argument
- type.
-
- @ivar elementType: Subclasses should set this to an L{Argument}
- instance. The tests will make a L{ListOf} using this.
-
- @ivar strings: Subclasses should set this to a dictionary mapping some
- number of keys to the correct serialized form for some example
- values. These should agree with what L{elementType}
- produces/accepts.
-
- @ivar objects: Subclasses should set this to a dictionary with the same
- keys as C{strings} and with values which are the lists which should
- serialize to the values in the C{strings} dictionary.
- """
- def test_toBox(self):
- """
- L{ListOf.toBox} extracts the list of objects from the C{objects}
- dictionary passed to it, using the C{name} key also passed to it,
- serializes each of the elements in that list using the L{Argument}
- instance previously passed to its initializer, combines the serialized
- results, and inserts the result into the C{strings} dictionary using
- the same C{name} key.
- """
- stringList = amp.ListOf(self.elementType)
- strings = amp.AmpBox()
- for key in self.objects:
- stringList.toBox(key, strings, self.objects.copy(), None)
- self.assertEqual(strings, self.strings)
-
-
- def test_fromBox(self):
- """
- L{ListOf.fromBox} reverses the operation performed by L{ListOf.toBox}.
- """
- stringList = amp.ListOf(self.elementType)
- objects = {}
- for key in self.strings:
- stringList.fromBox(key, self.strings.copy(), objects, None)
- self.assertEqual(objects, self.objects)
-
-
-
-class ListOfStringsTests(unittest.TestCase, ListOfTestsMixin):
- """
- Tests for L{ListOf} combined with L{amp.String}.
- """
- elementType = amp.String()
-
- strings = {
- "empty": "",
- "single": "\x00\x03foo",
- "multiple": "\x00\x03bar\x00\x03baz\x00\x04quux"}
-
- objects = {
- "empty": [],
- "single": ["foo"],
- "multiple": ["bar", "baz", "quux"]}
-
-
-class ListOfIntegersTests(unittest.TestCase, ListOfTestsMixin):
- """
- Tests for L{ListOf} combined with L{amp.Integer}.
- """
- elementType = amp.Integer()
-
- huge = (
- 9999999999999999999999999999999999999999999999999999999999 *
- 9999999999999999999999999999999999999999999999999999999999)
-
- strings = {
- "empty": "",
- "single": "\x00\x0210",
- "multiple": "\x00\x011\x00\x0220\x00\x03500",
- "huge": "\x00\x74%d" % (huge,),
- "negative": "\x00\x02-1"}
-
- objects = {
- "empty": [],
- "single": [10],
- "multiple": [1, 20, 500],
- "huge": [huge],
- "negative": [-1]}
-
-
-
-class ListOfUnicodeTests(unittest.TestCase, ListOfTestsMixin):
- """
- Tests for L{ListOf} combined with L{amp.Unicode}.
- """
- elementType = amp.Unicode()
-
- strings = {
- "empty": "",
- "single": "\x00\x03foo",
- "multiple": "\x00\x03\xe2\x98\x83\x00\x05Hello\x00\x05world"}
-
- objects = {
- "empty": [],
- "single": [u"foo"],
- "multiple": [u"\N{SNOWMAN}", u"Hello", u"world"]}
-
-
-
-class ListOfDecimalTests(unittest.TestCase, ListOfTestsMixin):
- """
- Tests for L{ListOf} combined with L{amp.Decimal}.
- """
- elementType = amp.Decimal()
-
- strings = {
- "empty": "",
- "single": "\x00\x031.1",
- "extreme": "\x00\x08Infinity\x00\x09-Infinity",
- "scientist": "\x00\x083.141E+5\x00\x0a0.00003141\x00\x083.141E-7"
- "\x00\x09-3.141E+5\x00\x0b-0.00003141\x00\x09-3.141E-7",
- "engineer": "\x00\x04%s\x00\x06%s" % (
- decimal.Decimal("0e6").to_eng_string(),
- decimal.Decimal("1.5E-9").to_eng_string()),
- }
-
- objects = {
- "empty": [],
- "single": [decimal.Decimal("1.1")],
- "extreme": [
- decimal.Decimal("Infinity"),
- decimal.Decimal("-Infinity"),
- ],
- # exarkun objected to AMP supporting engineering notation because
- # it was redundant, until we realised that 1E6 has less precision
- # than 1000000 and is represented differently. But they compare
- # and even hash equally. There were tears.
- "scientist": [
- decimal.Decimal("3.141E5"),
- decimal.Decimal("3.141e-5"),
- decimal.Decimal("3.141E-7"),
- decimal.Decimal("-3.141e5"),
- decimal.Decimal("-3.141E-5"),
- decimal.Decimal("-3.141e-7"),
- ],
- "engineer": [
- decimal.Decimal("0e6"),
- decimal.Decimal("1.5E-9"),
- ],
- }
-
-
-
-class ListOfDecimalNanTests(unittest.TestCase, ListOfTestsMixin):
- """
- Tests for L{ListOf} combined with L{amp.Decimal} for not-a-number values.
- """
- elementType = amp.Decimal()
-
- strings = {
- "nan": "\x00\x03NaN\x00\x04-NaN\x00\x04sNaN\x00\x05-sNaN",
- }
-
- objects = {
- "nan": [
- decimal.Decimal("NaN"),
- decimal.Decimal("-NaN"),
- decimal.Decimal("sNaN"),
- decimal.Decimal("-sNaN"),
- ]
- }
-
- def test_fromBox(self):
- """
- L{ListOf.fromBox} reverses the operation performed by L{ListOf.toBox}.
- """
- # Helpers. Decimal.is_{qnan,snan,signed}() are new in 2.6 (or 2.5.2,
- # but who's counting).
- def is_qnan(decimal):
- return 'NaN' in str(decimal) and 'sNaN' not in str(decimal)
-
- def is_snan(decimal):
- return 'sNaN' in str(decimal)
-
- def is_signed(decimal):
- return '-' in str(decimal)
-
- # NaN values have unusual equality semantics, so this method is
- # overridden to compare the resulting objects in a way which works with
- # NaNs.
- stringList = amp.ListOf(self.elementType)
- objects = {}
- for key in self.strings:
- stringList.fromBox(key, self.strings.copy(), objects, None)
- n = objects["nan"]
- self.assertTrue(is_qnan(n[0]) and not is_signed(n[0]))
- self.assertTrue(is_qnan(n[1]) and is_signed(n[1]))
- self.assertTrue(is_snan(n[2]) and not is_signed(n[2]))
- self.assertTrue(is_snan(n[3]) and is_signed(n[3]))
-
-
-
-class DecimalTests(unittest.TestCase):
- """
- Tests for L{amp.Decimal}.
- """
- def test_nonDecimal(self):
- """
- L{amp.Decimal.toString} raises L{ValueError} if passed an object which
- is not an instance of C{decimal.Decimal}.
- """
- argument = amp.Decimal()
- self.assertRaises(ValueError, argument.toString, "1.234")
- self.assertRaises(ValueError, argument.toString, 1.234)
- self.assertRaises(ValueError, argument.toString, 1234)
-
-
-
-class ListOfDateTimeTests(unittest.TestCase, ListOfTestsMixin):
- """
- Tests for L{ListOf} combined with L{amp.DateTime}.
- """
- elementType = amp.DateTime()
-
- strings = {
- "christmas":
- "\x00\x202010-12-25T00:00:00.000000-00:00"
- "\x00\x202010-12-25T00:00:00.000000-00:00",
- "christmas in eu": "\x00\x202010-12-25T00:00:00.000000+01:00",
- "christmas in iran": "\x00\x202010-12-25T00:00:00.000000+03:30",
- "christmas in nyc": "\x00\x202010-12-25T00:00:00.000000-05:00",
- "previous tests": "\x00\x202010-12-25T00:00:00.000000+03:19"
- "\x00\x202010-12-25T00:00:00.000000-06:59",
- }
-
- objects = {
- "christmas": [
- datetime.datetime(2010, 12, 25, 0, 0, 0, tzinfo=amp.utc),
- datetime.datetime(2010, 12, 25, 0, 0, 0,
- tzinfo=amp._FixedOffsetTZInfo('+', 0, 0)),
- ],
- "christmas in eu": [
- datetime.datetime(2010, 12, 25, 0, 0, 0,
- tzinfo=amp._FixedOffsetTZInfo('+', 1, 0)),
- ],
- "christmas in iran": [
- datetime.datetime(2010, 12, 25, 0, 0, 0,
- tzinfo=amp._FixedOffsetTZInfo('+', 3, 30)),
- ],
- "christmas in nyc": [
- datetime.datetime(2010, 12, 25, 0, 0, 0,
- tzinfo=amp._FixedOffsetTZInfo('-', 5, 0)),
- ],
- "previous tests": [
- datetime.datetime(2010, 12, 25, 0, 0, 0,
- tzinfo=amp._FixedOffsetTZInfo('+', 3, 19)),
- datetime.datetime(2010, 12, 25, 0, 0, 0,
- tzinfo=amp._FixedOffsetTZInfo('-', 6, 59)),
- ],
- }
-
-
-
-class ListOfOptionalTests(unittest.TestCase):
- """
- Tests to ensure L{ListOf} AMP arguments can be omitted from AMP commands
- via the 'optional' flag.
- """
- def test_requiredArgumentWithNoneValueRaisesTypeError(self):
- """
- L{ListOf.toBox} raises C{TypeError} when passed a value of C{None}
- for the argument.
- """
- stringList = amp.ListOf(amp.Integer())
- self.assertRaises(
- TypeError, stringList.toBox, 'omitted', amp.AmpBox(),
- {'omitted': None}, None)
-
-
- def test_optionalArgumentWithNoneValueOmitted(self):
- """
- L{ListOf.toBox} silently omits serializing any argument with a
- value of C{None} that is designated as optional for the protocol.
- """
- stringList = amp.ListOf(amp.Integer(), optional=True)
- strings = amp.AmpBox()
- stringList.toBox('omitted', strings, {'omitted': None}, None)
- self.assertEqual(strings, {})
-
-
- def test_requiredArgumentWithKeyMissingRaisesKeyError(self):
- """
- L{ListOf.toBox} raises C{KeyError} if the argument's key is not
- present in the objects dictionary.
- """
- stringList = amp.ListOf(amp.Integer())
- self.assertRaises(
- KeyError, stringList.toBox, 'ommited', amp.AmpBox(),
- {'someOtherKey': 0}, None)
-
-
- def test_optionalArgumentWithKeyMissingOmitted(self):
- """
- L{ListOf.toBox} silently omits serializing any argument designated
- as optional whose key is not present in the objects dictionary.
- """
- stringList = amp.ListOf(amp.Integer(), optional=True)
- stringList.toBox('ommited', amp.AmpBox(), {'someOtherKey': 0}, None)
-
-
- def test_omittedOptionalArgumentDeserializesAsNone(self):
- """
- L{ListOf.fromBox} correctly reverses the operation performed by
- L{ListOf.toBox} for optional arguments.
- """
- stringList = amp.ListOf(amp.Integer(), optional=True)
- objects = {}
- stringList.fromBox('omitted', {}, objects, None)
- self.assertEqual(objects, {'omitted': None})
-
-
-
-class UNIXStringTransport(object):
- """
- An in-memory implementation of L{interfaces.IUNIXTransport} which collects
- all data given to it for later inspection.
-
- @ivar _queue: A C{list} of the data which has been given to this transport,
- eg via C{write} or C{sendFileDescriptor}. Elements are two-tuples of a
- string (identifying the destination of the data) and the data itself.
- """
- implements(interfaces.IUNIXTransport)
-
- def __init__(self, descriptorFuzz):
- """
- @param descriptorFuzz: An offset to apply to descriptors.
- @type descriptorFuzz: C{int}
- """
- self._fuzz = descriptorFuzz
- self._queue = []
-
-
- def sendFileDescriptor(self, descriptor):
- self._queue.append((
- 'fileDescriptorReceived', descriptor + self._fuzz))
-
-
- def write(self, data):
- self._queue.append(('dataReceived', data))
-
-
- def writeSequence(self, seq):
- for data in seq:
- self.write(data)
-
-
- def loseConnection(self):
- self._queue.append(('connectionLost', Failure(ConnectionLost())))
-
-
- def getHost(self):
- return UNIXAddress('/tmp/some-path')
-
-
- def getPeer(self):
- return UNIXAddress('/tmp/another-path')
-
-# Minimal evidence that we got the signatures right
-verifyClass(interfaces.ITransport, UNIXStringTransport)
-verifyClass(interfaces.IUNIXTransport, UNIXStringTransport)
-
-
-class DescriptorTests(unittest.TestCase):
- """
- Tests for L{amp.Descriptor}, an argument type for passing a file descriptor
- over an AMP connection over a UNIX domain socket.
- """
- def setUp(self):
- self.fuzz = 3
- self.transport = UNIXStringTransport(descriptorFuzz=self.fuzz)
- self.protocol = amp.BinaryBoxProtocol(
- amp.BoxDispatcher(amp.CommandLocator()))
- self.protocol.makeConnection(self.transport)
-
-
- def test_fromStringProto(self):
- """
- L{Descriptor.fromStringProto} constructs a file descriptor value by
- extracting a previously received file descriptor corresponding to the
- wire value of the argument from the L{_DescriptorExchanger} state of the
- protocol passed to it.
-
- This is a whitebox test which involves direct L{_DescriptorExchanger}
- state inspection.
- """
- argument = amp.Descriptor()
- self.protocol.fileDescriptorReceived(5)
- self.protocol.fileDescriptorReceived(3)
- self.protocol.fileDescriptorReceived(1)
- self.assertEqual(
- 5, argument.fromStringProto("0", self.protocol))
- self.assertEqual(
- 3, argument.fromStringProto("1", self.protocol))
- self.assertEqual(
- 1, argument.fromStringProto("2", self.protocol))
- self.assertEqual({}, self.protocol._descriptors)
-
-
- def test_toStringProto(self):
- """
- To send a file descriptor, L{Descriptor.toStringProto} uses the
- L{IUNIXTransport.sendFileDescriptor} implementation of the transport of
- the protocol passed to it to copy the file descriptor. Each subsequent
- descriptor sent over a particular AMP connection is assigned the next
- integer value, starting from 0. The base ten string representation of
- this value is the byte encoding of the argument.
-
- This is a whitebox test which involves direct L{_DescriptorExchanger}
- state inspection and mutation.
- """
- argument = amp.Descriptor()
- self.assertEqual("0", argument.toStringProto(2, self.protocol))
- self.assertEqual(
- ("fileDescriptorReceived", 2 + self.fuzz), self.transport._queue.pop(0))
- self.assertEqual("1", argument.toStringProto(4, self.protocol))
- self.assertEqual(
- ("fileDescriptorReceived", 4 + self.fuzz), self.transport._queue.pop(0))
- self.assertEqual("2", argument.toStringProto(6, self.protocol))
- self.assertEqual(
- ("fileDescriptorReceived", 6 + self.fuzz), self.transport._queue.pop(0))
- self.assertEqual({}, self.protocol._descriptors)
-
-
- def test_roundTrip(self):
- """
- L{amp.Descriptor.fromBox} can interpret an L{amp.AmpBox} constructed by
- L{amp.Descriptor.toBox} to reconstruct a file descriptor value.
- """
- name = "alpha"
- strings = {}
- descriptor = 17
- sendObjects = {name: descriptor}
-
- argument = amp.Descriptor()
- argument.toBox(name, strings, sendObjects.copy(), self.protocol)
-
- receiver = amp.BinaryBoxProtocol(
- amp.BoxDispatcher(amp.CommandLocator()))
- for event in self.transport._queue:
- getattr(receiver, event[0])(*event[1:])
-
- receiveObjects = {}
- argument.fromBox(name, strings.copy(), receiveObjects, receiver)
-
- # Make sure we got the descriptor. Adjust by fuzz to be more convincing
- # of having gone through L{IUNIXTransport.sendFileDescriptor}, not just
- # converted to a string and then parsed back into an integer.
- self.assertEqual(descriptor + self.fuzz, receiveObjects[name])
-
-
-
-class DateTimeTests(unittest.TestCase):
- """
- Tests for L{amp.DateTime}, L{amp._FixedOffsetTZInfo}, and L{amp.utc}.
- """
- string = '9876-01-23T12:34:56.054321-01:23'
- tzinfo = amp._FixedOffsetTZInfo('-', 1, 23)
- object = datetime.datetime(9876, 1, 23, 12, 34, 56, 54321, tzinfo)
-
- def test_invalidString(self):
- """
- L{amp.DateTime.fromString} raises L{ValueError} when passed a string
- which does not represent a timestamp in the proper format.
- """
- d = amp.DateTime()
- self.assertRaises(ValueError, d.fromString, 'abc')
-
-
- def test_invalidDatetime(self):
- """
- L{amp.DateTime.toString} raises L{ValueError} when passed a naive
- datetime (a datetime with no timezone information).
- """
- d = amp.DateTime()
- self.assertRaises(ValueError, d.toString,
- datetime.datetime(2010, 12, 25, 0, 0, 0))
-
-
- def test_fromString(self):
- """
- L{amp.DateTime.fromString} returns a C{datetime.datetime} with all of
- its fields populated from the string passed to it.
- """
- argument = amp.DateTime()
- value = argument.fromString(self.string)
- self.assertEqual(value, self.object)
-
-
- def test_toString(self):
- """
- L{amp.DateTime.toString} returns a C{str} in the wire format including
- all of the information from the C{datetime.datetime} passed into it,
- including the timezone offset.
- """
- argument = amp.DateTime()
- value = argument.toString(self.object)
- self.assertEqual(value, self.string)
-
-
-
-class FixedOffsetTZInfoTests(unittest.TestCase):
- """
- Tests for L{amp._FixedOffsetTZInfo} and L{amp.utc}.
- """
-
- def test_tzname(self):
- """
- L{amp.utc.tzname} returns C{"+00:00"}.
- """
- self.assertEqual(amp.utc.tzname(None), '+00:00')
-
-
- def test_dst(self):
- """
- L{amp.utc.dst} returns a zero timedelta.
- """
- self.assertEqual(amp.utc.dst(None), datetime.timedelta(0))
-
-
- def test_utcoffset(self):
- """
- L{amp.utc.utcoffset} returns a zero timedelta.
- """
- self.assertEqual(amp.utc.utcoffset(None), datetime.timedelta(0))
-
-
- def test_badSign(self):
- """
- L{amp._FixedOffsetTZInfo} raises L{ValueError} if passed an offset sign
- other than C{'+'} or C{'-'}.
- """
- self.assertRaises(ValueError, amp._FixedOffsetTZInfo, '?', 0, 0)
-
-
-
-if not interfaces.IReactorSSL.providedBy(reactor):
- skipMsg = 'This test case requires SSL support in the reactor'
- TLSTest.skip = skipMsg
- LiveFireTLSTestCase.skip = skipMsg
- PlainVanillaLiveFire.skip = skipMsg
- WithServerTLSVerification.skip = skipMsg
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_application.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_application.py
deleted file mode 100755
index e1ac29fe..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_application.py
+++ /dev/null
@@ -1,878 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.application} and its interaction with
-L{twisted.persisted.sob}.
-"""
-
-import copy, os, pickle
-from StringIO import StringIO
-
-from twisted.trial import unittest, util
-from twisted.application import service, internet, app
-from twisted.persisted import sob
-from twisted.python import usage
-from twisted.internet import interfaces, defer
-from twisted.protocols import wire, basic
-from twisted.internet import protocol, reactor
-from twisted.application import reactors
-from twisted.test.proto_helpers import MemoryReactor
-
-
-class Dummy:
- processName=None
-
-class TestService(unittest.TestCase):
-
- def testName(self):
- s = service.Service()
- s.setName("hello")
- self.assertEqual(s.name, "hello")
-
- def testParent(self):
- s = service.Service()
- p = service.MultiService()
- s.setServiceParent(p)
- self.assertEqual(list(p), [s])
- self.assertEqual(s.parent, p)
-
- def testApplicationAsParent(self):
- s = service.Service()
- p = service.Application("")
- s.setServiceParent(p)
- self.assertEqual(list(service.IServiceCollection(p)), [s])
- self.assertEqual(s.parent, service.IServiceCollection(p))
-
- def testNamedChild(self):
- s = service.Service()
- p = service.MultiService()
- s.setName("hello")
- s.setServiceParent(p)
- self.assertEqual(list(p), [s])
- self.assertEqual(s.parent, p)
- self.assertEqual(p.getServiceNamed("hello"), s)
-
- def testDoublyNamedChild(self):
- s = service.Service()
- p = service.MultiService()
- s.setName("hello")
- s.setServiceParent(p)
- self.failUnlessRaises(RuntimeError, s.setName, "lala")
-
- def testDuplicateNamedChild(self):
- s = service.Service()
- p = service.MultiService()
- s.setName("hello")
- s.setServiceParent(p)
- s = service.Service()
- s.setName("hello")
- self.failUnlessRaises(RuntimeError, s.setServiceParent, p)
-
- def testDisowning(self):
- s = service.Service()
- p = service.MultiService()
- s.setServiceParent(p)
- self.assertEqual(list(p), [s])
- self.assertEqual(s.parent, p)
- s.disownServiceParent()
- self.assertEqual(list(p), [])
- self.assertEqual(s.parent, None)
-
- def testRunning(self):
- s = service.Service()
- self.assert_(not s.running)
- s.startService()
- self.assert_(s.running)
- s.stopService()
- self.assert_(not s.running)
-
- def testRunningChildren1(self):
- s = service.Service()
- p = service.MultiService()
- s.setServiceParent(p)
- self.assert_(not s.running)
- self.assert_(not p.running)
- p.startService()
- self.assert_(s.running)
- self.assert_(p.running)
- p.stopService()
- self.assert_(not s.running)
- self.assert_(not p.running)
-
- def testRunningChildren2(self):
- s = service.Service()
- def checkRunning():
- self.assert_(s.running)
- t = service.Service()
- t.stopService = checkRunning
- t.startService = checkRunning
- p = service.MultiService()
- s.setServiceParent(p)
- t.setServiceParent(p)
- p.startService()
- p.stopService()
-
- def testAddingIntoRunning(self):
- p = service.MultiService()
- p.startService()
- s = service.Service()
- self.assert_(not s.running)
- s.setServiceParent(p)
- self.assert_(s.running)
- s.disownServiceParent()
- self.assert_(not s.running)
-
- def testPrivileged(self):
- s = service.Service()
- def pss():
- s.privilegedStarted = 1
- s.privilegedStartService = pss
- s1 = service.Service()
- p = service.MultiService()
- s.setServiceParent(p)
- s1.setServiceParent(p)
- p.privilegedStartService()
- self.assert_(s.privilegedStarted)
-
- def testCopying(self):
- s = service.Service()
- s.startService()
- s1 = copy.copy(s)
- self.assert_(not s1.running)
- self.assert_(s.running)
-
-
-if hasattr(os, "getuid"):
- curuid = os.getuid()
- curgid = os.getgid()
-else:
- curuid = curgid = 0
-
-
-class TestProcess(unittest.TestCase):
-
- def testID(self):
- p = service.Process(5, 6)
- self.assertEqual(p.uid, 5)
- self.assertEqual(p.gid, 6)
-
- def testDefaults(self):
- p = service.Process(5)
- self.assertEqual(p.uid, 5)
- self.assertEqual(p.gid, None)
- p = service.Process(gid=5)
- self.assertEqual(p.uid, None)
- self.assertEqual(p.gid, 5)
- p = service.Process()
- self.assertEqual(p.uid, None)
- self.assertEqual(p.gid, None)
-
- def testProcessName(self):
- p = service.Process()
- self.assertEqual(p.processName, None)
- p.processName = 'hello'
- self.assertEqual(p.processName, 'hello')
-
-
-class TestInterfaces(unittest.TestCase):
-
- def testService(self):
- self.assert_(service.IService.providedBy(service.Service()))
-
- def testMultiService(self):
- self.assert_(service.IService.providedBy(service.MultiService()))
- self.assert_(service.IServiceCollection.providedBy(service.MultiService()))
-
- def testProcess(self):
- self.assert_(service.IProcess.providedBy(service.Process()))
-
-
-class TestApplication(unittest.TestCase):
-
- def testConstructor(self):
- service.Application("hello")
- service.Application("hello", 5)
- service.Application("hello", 5, 6)
-
- def testProcessComponent(self):
- a = service.Application("hello")
- self.assertEqual(service.IProcess(a).uid, None)
- self.assertEqual(service.IProcess(a).gid, None)
- a = service.Application("hello", 5)
- self.assertEqual(service.IProcess(a).uid, 5)
- self.assertEqual(service.IProcess(a).gid, None)
- a = service.Application("hello", 5, 6)
- self.assertEqual(service.IProcess(a).uid, 5)
- self.assertEqual(service.IProcess(a).gid, 6)
-
- def testServiceComponent(self):
- a = service.Application("hello")
- self.assert_(service.IService(a) is service.IServiceCollection(a))
- self.assertEqual(service.IService(a).name, "hello")
- self.assertEqual(service.IService(a).parent, None)
-
- def testPersistableComponent(self):
- a = service.Application("hello")
- p = sob.IPersistable(a)
- self.assertEqual(p.style, 'pickle')
- self.assertEqual(p.name, 'hello')
- self.assert_(p.original is a)
-
-class TestLoading(unittest.TestCase):
-
- def test_simpleStoreAndLoad(self):
- a = service.Application("hello")
- p = sob.IPersistable(a)
- for style in 'source pickle'.split():
- p.setStyle(style)
- p.save()
- a1 = service.loadApplication("hello.ta"+style[0], style)
- self.assertEqual(service.IService(a1).name, "hello")
- f = open("hello.tac", 'w')
- f.writelines([
- "from twisted.application import service\n",
- "application = service.Application('hello')\n",
- ])
- f.close()
- a1 = service.loadApplication("hello.tac", 'python')
- self.assertEqual(service.IService(a1).name, "hello")
-
-
-
-class TestAppSupport(unittest.TestCase):
-
- def testPassphrase(self):
- self.assertEqual(app.getPassphrase(0), None)
-
- def testLoadApplication(self):
- """
- Test loading an application file in different dump format.
- """
- a = service.Application("hello")
- baseconfig = {'file': None, 'source': None, 'python':None}
- for style in 'source pickle'.split():
- config = baseconfig.copy()
- config[{'pickle': 'file'}.get(style, style)] = 'helloapplication'
- sob.IPersistable(a).setStyle(style)
- sob.IPersistable(a).save(filename='helloapplication')
- a1 = app.getApplication(config, None)
- self.assertEqual(service.IService(a1).name, "hello")
- config = baseconfig.copy()
- config['python'] = 'helloapplication'
- f = open("helloapplication", 'w')
- f.writelines([
- "from twisted.application import service\n",
- "application = service.Application('hello')\n",
- ])
- f.close()
- a1 = app.getApplication(config, None)
- self.assertEqual(service.IService(a1).name, "hello")
-
- def test_convertStyle(self):
- appl = service.Application("lala")
- for instyle in 'source pickle'.split():
- for outstyle in 'source pickle'.split():
- sob.IPersistable(appl).setStyle(instyle)
- sob.IPersistable(appl).save(filename="converttest")
- app.convertStyle("converttest", instyle, None,
- "converttest.out", outstyle, 0)
- appl2 = service.loadApplication("converttest.out", outstyle)
- self.assertEqual(service.IService(appl2).name, "lala")
-
-
- def test_startApplication(self):
- appl = service.Application("lala")
- app.startApplication(appl, 0)
- self.assert_(service.IService(appl).running)
-
-
-class Foo(basic.LineReceiver):
- def connectionMade(self):
- self.transport.write('lalala\r\n')
- def lineReceived(self, line):
- self.factory.line = line
- self.transport.loseConnection()
- def connectionLost(self, reason):
- self.factory.d.callback(self.factory.line)
-
-
-class DummyApp:
- processName = None
- def addService(self, service):
- self.services[service.name] = service
- def removeService(self, service):
- del self.services[service.name]
-
-
-class TimerTarget:
- def __init__(self):
- self.l = []
- def append(self, what):
- self.l.append(what)
-
-class TestEcho(wire.Echo):
- def connectionLost(self, reason):
- self.d.callback(True)
-
-class TestInternet2(unittest.TestCase):
-
- def testTCP(self):
- s = service.MultiService()
- s.startService()
- factory = protocol.ServerFactory()
- factory.protocol = TestEcho
- TestEcho.d = defer.Deferred()
- t = internet.TCPServer(0, factory)
- t.setServiceParent(s)
- num = t._port.getHost().port
- factory = protocol.ClientFactory()
- factory.d = defer.Deferred()
- factory.protocol = Foo
- factory.line = None
- internet.TCPClient('127.0.0.1', num, factory).setServiceParent(s)
- factory.d.addCallback(self.assertEqual, 'lalala')
- factory.d.addCallback(lambda x : s.stopService())
- factory.d.addCallback(lambda x : TestEcho.d)
- return factory.d
-
-
- def test_UDP(self):
- """
- Test L{internet.UDPServer} with a random port: starting the service
- should give it valid port, and stopService should free it so that we
- can start a server on the same port again.
- """
- if not interfaces.IReactorUDP(reactor, None):
- raise unittest.SkipTest("This reactor does not support UDP sockets")
- p = protocol.DatagramProtocol()
- t = internet.UDPServer(0, p)
- t.startService()
- num = t._port.getHost().port
- self.assertNotEquals(num, 0)
- def onStop(ignored):
- t = internet.UDPServer(num, p)
- t.startService()
- return t.stopService()
- return defer.maybeDeferred(t.stopService).addCallback(onStop)
-
-
- def testPrivileged(self):
- factory = protocol.ServerFactory()
- factory.protocol = TestEcho
- TestEcho.d = defer.Deferred()
- t = internet.TCPServer(0, factory)
- t.privileged = 1
- t.privilegedStartService()
- num = t._port.getHost().port
- factory = protocol.ClientFactory()
- factory.d = defer.Deferred()
- factory.protocol = Foo
- factory.line = None
- c = internet.TCPClient('127.0.0.1', num, factory)
- c.startService()
- factory.d.addCallback(self.assertEqual, 'lalala')
- factory.d.addCallback(lambda x : c.stopService())
- factory.d.addCallback(lambda x : t.stopService())
- factory.d.addCallback(lambda x : TestEcho.d)
- return factory.d
-
- def testConnectionGettingRefused(self):
- factory = protocol.ServerFactory()
- factory.protocol = wire.Echo
- t = internet.TCPServer(0, factory)
- t.startService()
- num = t._port.getHost().port
- t.stopService()
- d = defer.Deferred()
- factory = protocol.ClientFactory()
- factory.clientConnectionFailed = lambda *args: d.callback(None)
- c = internet.TCPClient('127.0.0.1', num, factory)
- c.startService()
- return d
-
- def testUNIX(self):
- # FIXME: This test is far too dense. It needs comments.
- # -- spiv, 2004-11-07
- if not interfaces.IReactorUNIX(reactor, None):
- raise unittest.SkipTest, "This reactor does not support UNIX domain sockets"
- s = service.MultiService()
- s.startService()
- factory = protocol.ServerFactory()
- factory.protocol = TestEcho
- TestEcho.d = defer.Deferred()
- t = internet.UNIXServer('echo.skt', factory)
- t.setServiceParent(s)
- factory = protocol.ClientFactory()
- factory.protocol = Foo
- factory.d = defer.Deferred()
- factory.line = None
- internet.UNIXClient('echo.skt', factory).setServiceParent(s)
- factory.d.addCallback(self.assertEqual, 'lalala')
- factory.d.addCallback(lambda x : s.stopService())
- factory.d.addCallback(lambda x : TestEcho.d)
- factory.d.addCallback(self._cbTestUnix, factory, s)
- return factory.d
-
- def _cbTestUnix(self, ignored, factory, s):
- TestEcho.d = defer.Deferred()
- factory.line = None
- factory.d = defer.Deferred()
- s.startService()
- factory.d.addCallback(self.assertEqual, 'lalala')
- factory.d.addCallback(lambda x : s.stopService())
- factory.d.addCallback(lambda x : TestEcho.d)
- return factory.d
-
- def testVolatile(self):
- if not interfaces.IReactorUNIX(reactor, None):
- raise unittest.SkipTest, "This reactor does not support UNIX domain sockets"
- factory = protocol.ServerFactory()
- factory.protocol = wire.Echo
- t = internet.UNIXServer('echo.skt', factory)
- t.startService()
- self.failIfIdentical(t._port, None)
- t1 = copy.copy(t)
- self.assertIdentical(t1._port, None)
- t.stopService()
- self.assertIdentical(t._port, None)
- self.failIf(t.running)
-
- factory = protocol.ClientFactory()
- factory.protocol = wire.Echo
- t = internet.UNIXClient('echo.skt', factory)
- t.startService()
- self.failIfIdentical(t._connection, None)
- t1 = copy.copy(t)
- self.assertIdentical(t1._connection, None)
- t.stopService()
- self.assertIdentical(t._connection, None)
- self.failIf(t.running)
-
- def testStoppingServer(self):
- if not interfaces.IReactorUNIX(reactor, None):
- raise unittest.SkipTest, "This reactor does not support UNIX domain sockets"
- factory = protocol.ServerFactory()
- factory.protocol = wire.Echo
- t = internet.UNIXServer('echo.skt', factory)
- t.startService()
- t.stopService()
- self.failIf(t.running)
- factory = protocol.ClientFactory()
- d = defer.Deferred()
- factory.clientConnectionFailed = lambda *args: d.callback(None)
- reactor.connectUNIX('echo.skt', factory)
- return d
-
- def testPickledTimer(self):
- target = TimerTarget()
- t0 = internet.TimerService(1, target.append, "hello")
- t0.startService()
- s = pickle.dumps(t0)
- t0.stopService()
-
- t = pickle.loads(s)
- self.failIf(t.running)
-
- def testBrokenTimer(self):
- d = defer.Deferred()
- t = internet.TimerService(1, lambda: 1 // 0)
- oldFailed = t._failed
- def _failed(why):
- oldFailed(why)
- d.callback(None)
- t._failed = _failed
- t.startService()
- d.addCallback(lambda x : t.stopService)
- d.addCallback(lambda x : self.assertEqual(
- [ZeroDivisionError],
- [o.value.__class__ for o in self.flushLoggedErrors(ZeroDivisionError)]))
- return d
-
-
- def test_genericServerDeprecated(self):
- """
- Instantiating L{GenericServer} emits a deprecation warning.
- """
- internet.GenericServer()
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_genericServerDeprecated])
- self.assertEqual(
- warnings[0]['message'],
- 'GenericServer was deprecated in Twisted 10.1.')
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(len(warnings), 1)
-
-
- def test_genericClientDeprecated(self):
- """
- Instantiating L{GenericClient} emits a deprecation warning.
- """
- internet.GenericClient()
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_genericClientDeprecated])
- self.assertEqual(
- warnings[0]['message'],
- 'GenericClient was deprecated in Twisted 10.1.')
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(len(warnings), 1)
-
-
- def test_everythingThere(self):
- """
- L{twisted.application.internet} dynamically defines a set of
- L{service.Service} subclasses that in general have corresponding
- reactor.listenXXX or reactor.connectXXX calls.
- """
- trans = 'TCP UNIX SSL UDP UNIXDatagram Multicast'.split()
- for tran in trans[:]:
- if not getattr(interfaces, "IReactor" + tran)(reactor, None):
- trans.remove(tran)
- if interfaces.IReactorArbitrary(reactor, None) is not None:
- trans.insert(0, "Generic")
- for tran in trans:
- for side in 'Server Client'.split():
- if tran == "Multicast" and side == "Client":
- continue
- self.assertTrue(hasattr(internet, tran + side))
- method = getattr(internet, tran + side).method
- prefix = {'Server': 'listen', 'Client': 'connect'}[side]
- self.assertTrue(hasattr(reactor, prefix + method) or
- (prefix == "connect" and method == "UDP"))
- o = getattr(internet, tran + side)()
- self.assertEqual(service.IService(o), o)
- test_everythingThere.suppress = [
- util.suppress(message='GenericServer was deprecated in Twisted 10.1.',
- category=DeprecationWarning),
- util.suppress(message='GenericClient was deprecated in Twisted 10.1.',
- category=DeprecationWarning),
- util.suppress(message='twisted.internet.interfaces.IReactorArbitrary was '
- 'deprecated in Twisted 10.1.0: See IReactorFDSet.')]
-
-
- def test_importAll(self):
- """
- L{twisted.application.internet} dynamically defines L{service.Service}
- subclasses. This test ensures that the subclasses exposed by C{__all__}
- are valid attributes of the module.
- """
- for cls in internet.__all__:
- self.assertTrue(
- hasattr(internet, cls),
- '%s not importable from twisted.application.internet' % (cls,))
-
-
- def test_reactorParametrizationInServer(self):
- """
- L{internet._AbstractServer} supports a C{reactor} keyword argument
- that can be used to parametrize the reactor used to listen for
- connections.
- """
- reactor = MemoryReactor()
-
- factory = object()
- t = internet.TCPServer(1234, factory, reactor=reactor)
- t.startService()
- self.assertEqual(reactor.tcpServers.pop()[:2], (1234, factory))
-
-
- def test_reactorParametrizationInClient(self):
- """
- L{internet._AbstractClient} supports a C{reactor} keyword arguments
- that can be used to parametrize the reactor used to create new client
- connections.
- """
- reactor = MemoryReactor()
-
- factory = protocol.ClientFactory()
- t = internet.TCPClient('127.0.0.1', 1234, factory, reactor=reactor)
- t.startService()
- self.assertEqual(
- reactor.tcpClients.pop()[:3], ('127.0.0.1', 1234, factory))
-
-
- def test_reactorParametrizationInServerMultipleStart(self):
- """
- Like L{test_reactorParametrizationInServer}, but stop and restart the
- service and check that the given reactor is still used.
- """
- reactor = MemoryReactor()
-
- factory = protocol.Factory()
- t = internet.TCPServer(1234, factory, reactor=reactor)
- t.startService()
- self.assertEqual(reactor.tcpServers.pop()[:2], (1234, factory))
- t.stopService()
- t.startService()
- self.assertEqual(reactor.tcpServers.pop()[:2], (1234, factory))
-
-
- def test_reactorParametrizationInClientMultipleStart(self):
- """
- Like L{test_reactorParametrizationInClient}, but stop and restart the
- service and check that the given reactor is still used.
- """
- reactor = MemoryReactor()
-
- factory = protocol.ClientFactory()
- t = internet.TCPClient('127.0.0.1', 1234, factory, reactor=reactor)
- t.startService()
- self.assertEqual(
- reactor.tcpClients.pop()[:3], ('127.0.0.1', 1234, factory))
- t.stopService()
- t.startService()
- self.assertEqual(
- reactor.tcpClients.pop()[:3], ('127.0.0.1', 1234, factory))
-
-
-
-class TestTimerBasic(unittest.TestCase):
-
- def testTimerRuns(self):
- d = defer.Deferred()
- self.t = internet.TimerService(1, d.callback, 'hello')
- self.t.startService()
- d.addCallback(self.assertEqual, 'hello')
- d.addCallback(lambda x : self.t.stopService())
- d.addCallback(lambda x : self.failIf(self.t.running))
- return d
-
- def tearDown(self):
- return self.t.stopService()
-
- def testTimerRestart(self):
- # restart the same TimerService
- d1 = defer.Deferred()
- d2 = defer.Deferred()
- work = [(d2, "bar"), (d1, "foo")]
- def trigger():
- d, arg = work.pop()
- d.callback(arg)
- self.t = internet.TimerService(1, trigger)
- self.t.startService()
- def onFirstResult(result):
- self.assertEqual(result, 'foo')
- return self.t.stopService()
- def onFirstStop(ignored):
- self.failIf(self.t.running)
- self.t.startService()
- return d2
- def onSecondResult(result):
- self.assertEqual(result, 'bar')
- self.t.stopService()
- d1.addCallback(onFirstResult)
- d1.addCallback(onFirstStop)
- d1.addCallback(onSecondResult)
- return d1
-
- def testTimerLoops(self):
- l = []
- def trigger(data, number, d):
- l.append(data)
- if len(l) == number:
- d.callback(l)
- d = defer.Deferred()
- self.t = internet.TimerService(0.01, trigger, "hello", 10, d)
- self.t.startService()
- d.addCallback(self.assertEqual, ['hello'] * 10)
- d.addCallback(lambda x : self.t.stopService())
- return d
-
-
-class FakeReactor(reactors.Reactor):
- """
- A fake reactor with a hooked install method.
- """
-
- def __init__(self, install, *args, **kwargs):
- """
- @param install: any callable that will be used as install method.
- @type install: C{callable}
- """
- reactors.Reactor.__init__(self, *args, **kwargs)
- self.install = install
-
-
-
-class PluggableReactorTestCase(unittest.TestCase):
- """
- Tests for the reactor discovery/inspection APIs.
- """
-
- def setUp(self):
- """
- Override the L{reactors.getPlugins} function, normally bound to
- L{twisted.plugin.getPlugins}, in order to control which
- L{IReactorInstaller} plugins are seen as available.
-
- C{self.pluginResults} can be customized and will be used as the
- result of calls to C{reactors.getPlugins}.
- """
- self.pluginCalls = []
- self.pluginResults = []
- self.originalFunction = reactors.getPlugins
- reactors.getPlugins = self._getPlugins
-
-
- def tearDown(self):
- """
- Restore the original L{reactors.getPlugins}.
- """
- reactors.getPlugins = self.originalFunction
-
-
- def _getPlugins(self, interface, package=None):
- """
- Stand-in for the real getPlugins method which records its arguments
- and returns a fixed result.
- """
- self.pluginCalls.append((interface, package))
- return list(self.pluginResults)
-
-
- def test_getPluginReactorTypes(self):
- """
- Test that reactor plugins are returned from L{getReactorTypes}
- """
- name = 'fakereactortest'
- package = __name__ + '.fakereactor'
- description = 'description'
- self.pluginResults = [reactors.Reactor(name, package, description)]
- reactorTypes = reactors.getReactorTypes()
-
- self.assertEqual(
- self.pluginCalls,
- [(reactors.IReactorInstaller, None)])
-
- for r in reactorTypes:
- if r.shortName == name:
- self.assertEqual(r.description, description)
- break
- else:
- self.fail("Reactor plugin not present in getReactorTypes() result")
-
-
- def test_reactorInstallation(self):
- """
- Test that L{reactors.Reactor.install} loads the correct module and
- calls its install attribute.
- """
- installed = []
- def install():
- installed.append(True)
- installer = FakeReactor(install,
- 'fakereactortest', __name__, 'described')
- installer.install()
- self.assertEqual(installed, [True])
-
-
- def test_installReactor(self):
- """
- Test that the L{reactors.installReactor} function correctly installs
- the specified reactor.
- """
- installed = []
- def install():
- installed.append(True)
- name = 'fakereactortest'
- package = __name__
- description = 'description'
- self.pluginResults = [FakeReactor(install, name, package, description)]
- reactors.installReactor(name)
- self.assertEqual(installed, [True])
-
-
- def test_installNonExistentReactor(self):
- """
- Test that L{reactors.installReactor} raises L{reactors.NoSuchReactor}
- when asked to install a reactor which it cannot find.
- """
- self.pluginResults = []
- self.assertRaises(
- reactors.NoSuchReactor,
- reactors.installReactor, 'somereactor')
-
-
- def test_installNotAvailableReactor(self):
- """
- Test that L{reactors.installReactor} raises an exception when asked to
- install a reactor which doesn't work in this environment.
- """
- def install():
- raise ImportError("Missing foo bar")
- name = 'fakereactortest'
- package = __name__
- description = 'description'
- self.pluginResults = [FakeReactor(install, name, package, description)]
- self.assertRaises(ImportError, reactors.installReactor, name)
-
-
- def test_reactorSelectionMixin(self):
- """
- Test that the reactor selected is installed as soon as possible, ie
- when the option is parsed.
- """
- executed = []
- INSTALL_EVENT = 'reactor installed'
- SUBCOMMAND_EVENT = 'subcommands loaded'
-
- class ReactorSelectionOptions(usage.Options, app.ReactorSelectionMixin):
- def subCommands(self):
- executed.append(SUBCOMMAND_EVENT)
- return [('subcommand', None, lambda: self, 'test subcommand')]
- subCommands = property(subCommands)
-
- def install():
- executed.append(INSTALL_EVENT)
- self.pluginResults = [
- FakeReactor(install, 'fakereactortest', __name__, 'described')
- ]
-
- options = ReactorSelectionOptions()
- options.parseOptions(['--reactor', 'fakereactortest', 'subcommand'])
- self.assertEqual(executed[0], INSTALL_EVENT)
- self.assertEqual(executed.count(INSTALL_EVENT), 1)
- self.assertEqual(options["reactor"], "fakereactortest")
-
-
- def test_reactorSelectionMixinNonExistent(self):
- """
- Test that the usage mixin exits when trying to use a non existent
- reactor (the name not matching to any reactor), giving an error
- message.
- """
- class ReactorSelectionOptions(usage.Options, app.ReactorSelectionMixin):
- pass
- self.pluginResults = []
-
- options = ReactorSelectionOptions()
- options.messageOutput = StringIO()
- e = self.assertRaises(usage.UsageError, options.parseOptions,
- ['--reactor', 'fakereactortest', 'subcommand'])
- self.assertIn("fakereactortest", e.args[0])
- self.assertIn("help-reactors", e.args[0])
-
-
- def test_reactorSelectionMixinNotAvailable(self):
- """
- Test that the usage mixin exits when trying to use a reactor not
- available (the reactor raises an error at installation), giving an
- error message.
- """
- class ReactorSelectionOptions(usage.Options, app.ReactorSelectionMixin):
- pass
- message = "Missing foo bar"
- def install():
- raise ImportError(message)
-
- name = 'fakereactortest'
- package = __name__
- description = 'description'
- self.pluginResults = [FakeReactor(install, name, package, description)]
-
- options = ReactorSelectionOptions()
- options.messageOutput = StringIO()
- e = self.assertRaises(usage.UsageError, options.parseOptions,
- ['--reactor', 'fakereactortest', 'subcommand'])
- self.assertIn(message, e.args[0])
- self.assertIn("help-reactors", e.args[0])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_banana.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_banana.py
deleted file mode 100755
index c4b69de8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_banana.py
+++ /dev/null
@@ -1,278 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import StringIO
-import sys
-
-# Twisted Imports
-from twisted.trial import unittest
-from twisted.spread import banana
-from twisted.python import failure
-from twisted.internet import protocol, main
-
-
-class MathTestCase(unittest.TestCase):
- def testInt2b128(self):
- funkylist = range(0,100) + range(1000,1100) + range(1000000,1000100) + [1024 **10l]
- for i in funkylist:
- x = StringIO.StringIO()
- banana.int2b128(i, x.write)
- v = x.getvalue()
- y = banana.b1282int(v)
- assert y == i, "y = %s; i = %s" % (y,i)
-
-class BananaTestCase(unittest.TestCase):
-
- encClass = banana.Banana
-
- def setUp(self):
- self.io = StringIO.StringIO()
- self.enc = self.encClass()
- self.enc.makeConnection(protocol.FileWrapper(self.io))
- self.enc._selectDialect("none")
- self.enc.expressionReceived = self.putResult
-
- def putResult(self, result):
- self.result = result
-
- def tearDown(self):
- self.enc.connectionLost(failure.Failure(main.CONNECTION_DONE))
- del self.enc
-
- def testString(self):
- self.enc.sendEncoded("hello")
- l = []
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == 'hello'
-
- def test_int(self):
- """
- A positive integer less than 2 ** 32 should round-trip through
- banana without changing value and should come out represented
- as an C{int} (regardless of the type which was encoded).
- """
- for value in (10151, 10151L):
- self.enc.sendEncoded(value)
- self.enc.dataReceived(self.io.getvalue())
- self.assertEqual(self.result, 10151)
- self.assertIsInstance(self.result, int)
-
-
- def test_largeLong(self):
- """
- Integers greater than 2 ** 32 and less than -2 ** 32 should
- round-trip through banana without changing value and should
- come out represented as C{int} instances if the value fits
- into that type on the receiving platform.
- """
- for exp in (32, 64, 128, 256):
- for add in (0, 1):
- m = 2 ** exp + add
- for n in (m, -m-1):
- self.io.truncate(0)
- self.enc.sendEncoded(n)
- self.enc.dataReceived(self.io.getvalue())
- self.assertEqual(self.result, n)
- if n > sys.maxint or n < -sys.maxint - 1:
- self.assertIsInstance(self.result, long)
- else:
- self.assertIsInstance(self.result, int)
-
-
- def _getSmallest(self):
- # How many bytes of prefix our implementation allows
- bytes = self.enc.prefixLimit
- # How many useful bits we can extract from that based on Banana's
- # base-128 representation.
- bits = bytes * 7
- # The largest number we _should_ be able to encode
- largest = 2 ** bits - 1
- # The smallest number we _shouldn't_ be able to encode
- smallest = largest + 1
- return smallest
-
-
- def test_encodeTooLargeLong(self):
- """
- Test that a long above the implementation-specific limit is rejected
- as too large to be encoded.
- """
- smallest = self._getSmallest()
- self.assertRaises(banana.BananaError, self.enc.sendEncoded, smallest)
-
-
- def test_decodeTooLargeLong(self):
- """
- Test that a long above the implementation specific limit is rejected
- as too large to be decoded.
- """
- smallest = self._getSmallest()
- self.enc.setPrefixLimit(self.enc.prefixLimit * 2)
- self.enc.sendEncoded(smallest)
- encoded = self.io.getvalue()
- self.io.truncate(0)
- self.enc.setPrefixLimit(self.enc.prefixLimit // 2)
-
- self.assertRaises(banana.BananaError, self.enc.dataReceived, encoded)
-
-
- def _getLargest(self):
- return -self._getSmallest()
-
-
- def test_encodeTooSmallLong(self):
- """
- Test that a negative long below the implementation-specific limit is
- rejected as too small to be encoded.
- """
- largest = self._getLargest()
- self.assertRaises(banana.BananaError, self.enc.sendEncoded, largest)
-
-
- def test_decodeTooSmallLong(self):
- """
- Test that a negative long below the implementation specific limit is
- rejected as too small to be decoded.
- """
- largest = self._getLargest()
- self.enc.setPrefixLimit(self.enc.prefixLimit * 2)
- self.enc.sendEncoded(largest)
- encoded = self.io.getvalue()
- self.io.truncate(0)
- self.enc.setPrefixLimit(self.enc.prefixLimit // 2)
-
- self.assertRaises(banana.BananaError, self.enc.dataReceived, encoded)
-
-
- def testNegativeLong(self):
- self.enc.sendEncoded(-1015l)
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == -1015l, "should be -1015l, got %s" % self.result
-
- def testInteger(self):
- self.enc.sendEncoded(1015)
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == 1015, "should be 1015, got %s" % self.result
-
- def testNegative(self):
- self.enc.sendEncoded(-1015)
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == -1015, "should be -1015, got %s" % self.result
-
- def testFloat(self):
- self.enc.sendEncoded(1015.)
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == 1015.
-
- def testList(self):
- foo = [1, 2, [3, 4], [30.5, 40.2], 5, ["six", "seven", ["eight", 9]], [10], []]
- self.enc.sendEncoded(foo)
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == foo, "%s!=%s" % (repr(self.result), repr(self.result))
-
- def testPartial(self):
- foo = [1, 2, [3, 4], [30.5, 40.2], 5,
- ["six", "seven", ["eight", 9]], [10],
- # TODO: currently the C implementation's a bit buggy...
- sys.maxint * 3l, sys.maxint * 2l, sys.maxint * -2l]
- self.enc.sendEncoded(foo)
- for byte in self.io.getvalue():
- self.enc.dataReceived(byte)
- assert self.result == foo, "%s!=%s" % (repr(self.result), repr(foo))
-
- def feed(self, data):
- for byte in data:
- self.enc.dataReceived(byte)
- def testOversizedList(self):
- data = '\x02\x01\x01\x01\x01\x80'
- # list(size=0x0101010102, about 4.3e9)
- self.failUnlessRaises(banana.BananaError, self.feed, data)
- def testOversizedString(self):
- data = '\x02\x01\x01\x01\x01\x82'
- # string(size=0x0101010102, about 4.3e9)
- self.failUnlessRaises(banana.BananaError, self.feed, data)
-
- def testCrashString(self):
- crashString = '\x00\x00\x00\x00\x04\x80'
- # string(size=0x0400000000, about 17.2e9)
-
- # cBanana would fold that into a 32-bit 'int', then try to allocate
- # a list with PyList_New(). cBanana ignored the NULL return value,
- # so it would segfault when trying to free the imaginary list.
-
- # This variant doesn't segfault straight out in my environment.
- # Instead, it takes up large amounts of CPU and memory...
- #crashString = '\x00\x00\x00\x00\x01\x80'
- # print repr(crashString)
- #self.failUnlessRaises(Exception, self.enc.dataReceived, crashString)
- try:
- # should now raise MemoryError
- self.enc.dataReceived(crashString)
- except banana.BananaError:
- pass
-
- def testCrashNegativeLong(self):
- # There was a bug in cBanana which relied on negating a negative integer
- # always giving a postive result, but for the lowest possible number in
- # 2s-complement arithmetic, that's not true, i.e.
- # long x = -2147483648;
- # long y = -x;
- # x == y; /* true! */
- # (assuming 32-bit longs)
- self.enc.sendEncoded(-2147483648)
- self.enc.dataReceived(self.io.getvalue())
- assert self.result == -2147483648, "should be -2147483648, got %s" % self.result
-
-
- def test_sizedIntegerTypes(self):
- """
- Test that integers below the maximum C{INT} token size cutoff are
- serialized as C{INT} or C{NEG} and that larger integers are
- serialized as C{LONGINT} or C{LONGNEG}.
- """
- def encoded(n):
- self.io.seek(0)
- self.io.truncate()
- self.enc.sendEncoded(n)
- return self.io.getvalue()
-
- baseIntIn = +2147483647
- baseNegIn = -2147483648
-
- baseIntOut = '\x7f\x7f\x7f\x07\x81'
- self.assertEqual(encoded(baseIntIn - 2), '\x7d' + baseIntOut)
- self.assertEqual(encoded(baseIntIn - 1), '\x7e' + baseIntOut)
- self.assertEqual(encoded(baseIntIn - 0), '\x7f' + baseIntOut)
-
- baseLongIntOut = '\x00\x00\x00\x08\x85'
- self.assertEqual(encoded(baseIntIn + 1), '\x00' + baseLongIntOut)
- self.assertEqual(encoded(baseIntIn + 2), '\x01' + baseLongIntOut)
- self.assertEqual(encoded(baseIntIn + 3), '\x02' + baseLongIntOut)
-
- baseNegOut = '\x7f\x7f\x7f\x07\x83'
- self.assertEqual(encoded(baseNegIn + 2), '\x7e' + baseNegOut)
- self.assertEqual(encoded(baseNegIn + 1), '\x7f' + baseNegOut)
- self.assertEqual(encoded(baseNegIn + 0), '\x00\x00\x00\x00\x08\x83')
-
- baseLongNegOut = '\x00\x00\x00\x08\x86'
- self.assertEqual(encoded(baseNegIn - 1), '\x01' + baseLongNegOut)
- self.assertEqual(encoded(baseNegIn - 2), '\x02' + baseLongNegOut)
- self.assertEqual(encoded(baseNegIn - 3), '\x03' + baseLongNegOut)
-
-
-
-class GlobalCoderTests(unittest.TestCase):
- """
- Tests for the free functions L{banana.encode} and L{banana.decode}.
- """
- def test_statelessDecode(self):
- """
- Test that state doesn't carry over between calls to L{banana.decode}.
- """
- # Banana encoding of 2 ** 449
- undecodable = '\x7f' * 65 + '\x85'
- self.assertRaises(banana.BananaError, banana.decode, undecodable)
-
- # Banana encoding of 1
- decodable = '\x01\x81'
- self.assertEqual(banana.decode(decodable), 1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_compat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_compat.py
deleted file mode 100755
index ee8a7bae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_compat.py
+++ /dev/null
@@ -1,252 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Tests for L{twisted.python.compat}.
-"""
-
-import os, tempfile, types, socket
-
-from twisted.trial import unittest
-
-from twisted.python.filepath import FilePath
-from twisted.python.compat import set, frozenset, reduce, execfile
-
-
-
-class IterableCounter:
- def __init__(self, lim=0):
- self.lim = lim
- self.i = -1
-
- def __iter__(self):
- return self
-
- def next(self):
- self.i += 1
- if self.i >= self.lim:
- raise StopIteration
- return self.i
-
-class CompatTestCase(unittest.TestCase):
- def testDict(self):
- d1 = {'a': 'b'}
- d2 = dict(d1)
- self.assertEqual(d1, d2)
- d1['a'] = 'c'
- self.assertNotEquals(d1, d2)
- d2 = dict(d1.items())
- self.assertEqual(d1, d2)
-
- def testBool(self):
- self.assertEqual(bool('hi'), True)
- self.assertEqual(bool(True), True)
- self.assertEqual(bool(''), False)
- self.assertEqual(bool(False), False)
-
- def testIteration(self):
- lst1, lst2 = range(10), []
-
- for i in iter(lst1):
- lst2.append(i)
- self.assertEqual(lst1, lst2)
- del lst2[:]
-
- try:
- iterable = iter(lst1)
- while 1:
- lst2.append(iterable.next())
- except StopIteration:
- pass
- self.assertEqual(lst1, lst2)
- del lst2[:]
-
- for i in iter(IterableCounter(10)):
- lst2.append(i)
- self.assertEqual(lst1, lst2)
- del lst2[:]
-
- try:
- iterable = iter(IterableCounter(10))
- while 1:
- lst2.append(iterable.next())
- except StopIteration:
- pass
- self.assertEqual(lst1, lst2)
- del lst2[:]
-
- for i in iter(IterableCounter(20).next, 10):
- lst2.append(i)
- self.assertEqual(lst1, lst2)
-
- def testIsinstance(self):
- """
- The current object is an instance of
- unittest.TestCase.
- """
- self.assertTrue(isinstance(self, unittest.TestCase))
-
-
- def testStrip(self):
- self.assertEqual(' x '.lstrip(' '), 'x ')
- self.assertEqual(' x x'.lstrip(' '), 'x x')
- self.assertEqual(' x '.rstrip(' '), ' x')
- self.assertEqual('x x '.rstrip(' '), 'x x')
-
- self.assertEqual('\t x '.lstrip('\t '), 'x ')
- self.assertEqual(' \tx x'.lstrip('\t '), 'x x')
- self.assertEqual(' x\t '.rstrip(' \t'), ' x')
- self.assertEqual('x x \t'.rstrip(' \t'), 'x x')
-
- self.assertEqual('\t x '.strip('\t '), 'x')
- self.assertEqual(' \tx x'.strip('\t '), 'x x')
- self.assertEqual(' x\t '.strip(' \t'), 'x')
- self.assertEqual('x x \t'.strip(' \t'), 'x x')
-
- def testNToP(self):
- from twisted.python.compat import inet_ntop
-
- f = lambda a: inet_ntop(socket.AF_INET6, a)
- g = lambda a: inet_ntop(socket.AF_INET, a)
-
- self.assertEqual('::', f('\x00' * 16))
- self.assertEqual('::1', f('\x00' * 15 + '\x01'))
- self.assertEqual(
- 'aef:b01:506:1001:ffff:9997:55:170',
- f('\x0a\xef\x0b\x01\x05\x06\x10\x01\xff\xff\x99\x97\x00\x55\x01\x70'))
-
- self.assertEqual('1.0.1.0', g('\x01\x00\x01\x00'))
- self.assertEqual('170.85.170.85', g('\xaa\x55\xaa\x55'))
- self.assertEqual('255.255.255.255', g('\xff\xff\xff\xff'))
-
- self.assertEqual('100::', f('\x01' + '\x00' * 15))
- self.assertEqual('100::1', f('\x01' + '\x00' * 14 + '\x01'))
-
- def testPToN(self):
- from twisted.python.compat import inet_pton
-
- f = lambda a: inet_pton(socket.AF_INET6, a)
- g = lambda a: inet_pton(socket.AF_INET, a)
-
- self.assertEqual('\x00\x00\x00\x00', g('0.0.0.0'))
- self.assertEqual('\xff\x00\xff\x00', g('255.0.255.0'))
- self.assertEqual('\xaa\xaa\xaa\xaa', g('170.170.170.170'))
-
- self.assertEqual('\x00' * 16, f('::'))
- self.assertEqual('\x00' * 16, f('0::0'))
- self.assertEqual('\x00\x01' + '\x00' * 14, f('1::'))
- self.assertEqual(
- '\x45\xef\x76\xcb\x00\x1a\x56\xef\xaf\xeb\x0b\xac\x19\x24\xae\xae',
- f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae'))
-
- self.assertEqual('\x00' * 14 + '\x00\x01', f('::1'))
- self.assertEqual('\x00' * 12 + '\x01\x02\x03\x04', f('::1.2.3.4'))
- self.assertEqual(
- '\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x01\x02\x03\xff',
- f('1:2:3:4:5:6:1.2.3.255'))
-
- for badaddr in ['1:2:3:4:5:6:7:8:', ':1:2:3:4:5:6:7:8', '1::2::3',
- '1:::3', ':::', '1:2', '::1.2', '1.2.3.4::',
- 'abcd:1.2.3.4:abcd:abcd:abcd:abcd:abcd',
- '1234:1.2.3.4:1234:1234:1234:1234:1234:1234',
- '1.2.3.4']:
- self.assertRaises(ValueError, f, badaddr)
-
- def test_set(self):
- """
- L{set} should behave like the expected set interface.
- """
- a = set()
- a.add('b')
- a.add('c')
- a.add('a')
- b = list(a)
- b.sort()
- self.assertEqual(b, ['a', 'b', 'c'])
- a.remove('b')
- b = list(a)
- b.sort()
- self.assertEqual(b, ['a', 'c'])
-
- a.discard('d')
-
- b = set(['r', 's'])
- d = a.union(b)
- b = list(d)
- b.sort()
- self.assertEqual(b, ['a', 'c', 'r', 's'])
-
-
- def test_frozenset(self):
- """
- L{frozenset} should behave like the expected frozenset interface.
- """
- a = frozenset(['a', 'b'])
- self.assertRaises(AttributeError, getattr, a, "add")
- self.assertEqual(sorted(a), ['a', 'b'])
-
- b = frozenset(['r', 's'])
- d = a.union(b)
- b = list(d)
- b.sort()
- self.assertEqual(b, ['a', 'b', 'r', 's'])
-
-
- def test_reduce(self):
- """
- L{reduce} should behave like the builtin reduce.
- """
- self.assertEqual(15, reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]))
- self.assertEqual(16, reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 1))
-
-
-
-class ExecfileCompatTestCase(unittest.TestCase):
- """
- Tests for the Python 3-friendly L{execfile} implementation.
- """
-
- def writeScript(self, content):
- """
- Write L{content} to a new temporary file, returning the L{FilePath}
- for the new file.
- """
- script = FilePath(self.mktemp())
- script.setContent(content.encode("ascii"))
- return script
-
-
- def test_execfileGlobals(self):
- """
- L{execfile} executes the specified file in the given global namespace.
- """
- script = self.writeScript("foo += 1\n")
- globalNamespace = {"foo": 1}
- execfile(script.path, globalNamespace)
- self.assertEqual(2, globalNamespace["foo"])
-
-
- def test_execfileGlobalsAndLocals(self):
- """
- L{execfile} executes the specified file in the given global and local
- namespaces.
- """
- script = self.writeScript("foo += 1\n")
- globalNamespace = {"foo": 10}
- localNamespace = {"foo": 20}
- execfile(script.path, globalNamespace, localNamespace)
- self.assertEqual(10, globalNamespace["foo"])
- self.assertEqual(21, localNamespace["foo"])
-
-
- def test_execfileUniversalNewlines(self):
- """
- L{execfile} reads in the specified file using universal newlines so
- that scripts written on one platform will work on another.
- """
- for lineEnding in "\n", "\r", "\r\n":
- script = self.writeScript("foo = 'okay'" + lineEnding)
- globalNamespace = {"foo": None}
- execfile(script.path, globalNamespace)
- self.assertEqual("okay", globalNamespace["foo"])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_context.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_context.py
deleted file mode 100755
index c8d25f73..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_context.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python import context
-
-class ContextTest(TestCase):
-
- def testBasicContext(self):
- self.assertEqual(context.get("x"), None)
- self.assertEqual(context.call({"x": "y"}, context.get, "x"), "y")
- self.assertEqual(context.get("x"), None)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_cooperator.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_cooperator.py
deleted file mode 100755
index 260ce033..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_cooperator.py
+++ /dev/null
@@ -1,669 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-This module contains tests for L{twisted.internet.task.Cooperator} and
-related functionality.
-"""
-
-from twisted.internet import reactor, defer, task
-from twisted.trial import unittest
-
-
-
-class FakeDelayedCall(object):
- """
- Fake delayed call which lets us simulate the scheduler.
- """
- def __init__(self, func):
- """
- A function to run, later.
- """
- self.func = func
- self.cancelled = False
-
-
- def cancel(self):
- """
- Don't run my function later.
- """
- self.cancelled = True
-
-
-
-class FakeScheduler(object):
- """
- A fake scheduler for testing against.
- """
- def __init__(self):
- """
- Create a fake scheduler with a list of work to do.
- """
- self.work = []
-
-
- def __call__(self, thunk):
- """
- Schedule a unit of work to be done later.
- """
- unit = FakeDelayedCall(thunk)
- self.work.append(unit)
- return unit
-
-
- def pump(self):
- """
- Do all of the work that is currently available to be done.
- """
- work, self.work = self.work, []
- for unit in work:
- if not unit.cancelled:
- unit.func()
-
-
-
-class TestCooperator(unittest.TestCase):
- RESULT = 'done'
-
- def ebIter(self, err):
- err.trap(task.SchedulerStopped)
- return self.RESULT
-
-
- def cbIter(self, ign):
- self.fail()
-
-
- def testStoppedRejectsNewTasks(self):
- """
- Test that Cooperators refuse new tasks when they have been stopped.
- """
- def testwith(stuff):
- c = task.Cooperator()
- c.stop()
- d = c.coiterate(iter(()), stuff)
- d.addCallback(self.cbIter)
- d.addErrback(self.ebIter)
- return d.addCallback(lambda result:
- self.assertEqual(result, self.RESULT))
- return testwith(None).addCallback(lambda ign: testwith(defer.Deferred()))
-
-
- def testStopRunning(self):
- """
- Test that a running iterator will not run to completion when the
- cooperator is stopped.
- """
- c = task.Cooperator()
- def myiter():
- for myiter.value in range(3):
- yield myiter.value
- myiter.value = -1
- d = c.coiterate(myiter())
- d.addCallback(self.cbIter)
- d.addErrback(self.ebIter)
- c.stop()
- def doasserts(result):
- self.assertEqual(result, self.RESULT)
- self.assertEqual(myiter.value, -1)
- d.addCallback(doasserts)
- return d
-
-
- def testStopOutstanding(self):
- """
- An iterator run with L{Cooperator.coiterate} paused on a L{Deferred}
- yielded by that iterator will fire its own L{Deferred} (the one
- returned by C{coiterate}) when L{Cooperator.stop} is called.
- """
- testControlD = defer.Deferred()
- outstandingD = defer.Deferred()
- def myiter():
- reactor.callLater(0, testControlD.callback, None)
- yield outstandingD
- self.fail()
- c = task.Cooperator()
- d = c.coiterate(myiter())
- def stopAndGo(ign):
- c.stop()
- outstandingD.callback('arglebargle')
-
- testControlD.addCallback(stopAndGo)
- d.addCallback(self.cbIter)
- d.addErrback(self.ebIter)
-
- return d.addCallback(
- lambda result: self.assertEqual(result, self.RESULT))
-
-
- def testUnexpectedError(self):
- c = task.Cooperator()
- def myiter():
- if 0:
- yield None
- else:
- raise RuntimeError()
- d = c.coiterate(myiter())
- return self.assertFailure(d, RuntimeError)
-
-
- def testUnexpectedErrorActuallyLater(self):
- def myiter():
- D = defer.Deferred()
- reactor.callLater(0, D.errback, RuntimeError())
- yield D
-
- c = task.Cooperator()
- d = c.coiterate(myiter())
- return self.assertFailure(d, RuntimeError)
-
-
- def testUnexpectedErrorNotActuallyLater(self):
- def myiter():
- yield defer.fail(RuntimeError())
-
- c = task.Cooperator()
- d = c.coiterate(myiter())
- return self.assertFailure(d, RuntimeError)
-
-
- def testCooperation(self):
- L = []
- def myiter(things):
- for th in things:
- L.append(th)
- yield None
-
- groupsOfThings = ['abc', (1, 2, 3), 'def', (4, 5, 6)]
-
- c = task.Cooperator()
- tasks = []
- for stuff in groupsOfThings:
- tasks.append(c.coiterate(myiter(stuff)))
-
- return defer.DeferredList(tasks).addCallback(
- lambda ign: self.assertEqual(tuple(L), sum(zip(*groupsOfThings), ())))
-
-
- def testResourceExhaustion(self):
- output = []
- def myiter():
- for i in range(100):
- output.append(i)
- if i == 9:
- _TPF.stopped = True
- yield i
-
- class _TPF:
- stopped = False
- def __call__(self):
- return self.stopped
-
- c = task.Cooperator(terminationPredicateFactory=_TPF)
- c.coiterate(myiter()).addErrback(self.ebIter)
- c._delayedCall.cancel()
- # testing a private method because only the test case will ever care
- # about this, so we have to carefully clean up after ourselves.
- c._tick()
- c.stop()
- self.failUnless(_TPF.stopped)
- self.assertEqual(output, range(10))
-
-
- def testCallbackReCoiterate(self):
- """
- If a callback to a deferred returned by coiterate calls coiterate on
- the same Cooperator, we should make sure to only do the minimal amount
- of scheduling work. (This test was added to demonstrate a specific bug
- that was found while writing the scheduler.)
- """
- calls = []
-
- class FakeCall:
- def __init__(self, func):
- self.func = func
-
- def __repr__(self):
- return '<FakeCall %r>' % (self.func,)
-
- def sched(f):
- self.failIf(calls, repr(calls))
- calls.append(FakeCall(f))
- return calls[-1]
-
- c = task.Cooperator(scheduler=sched, terminationPredicateFactory=lambda: lambda: True)
- d = c.coiterate(iter(()))
-
- done = []
- def anotherTask(ign):
- c.coiterate(iter(())).addBoth(done.append)
-
- d.addCallback(anotherTask)
-
- work = 0
- while not done:
- work += 1
- while calls:
- calls.pop(0).func()
- work += 1
- if work > 50:
- self.fail("Cooperator took too long")
-
-
- def test_removingLastTaskStopsScheduledCall(self):
- """
- If the last task in a Cooperator is removed, the scheduled call for
- the next tick is cancelled, since it is no longer necessary.
-
- This behavior is useful for tests that want to assert they have left
- no reactor state behind when they're done.
- """
- calls = [None]
- def sched(f):
- calls[0] = FakeDelayedCall(f)
- return calls[0]
- coop = task.Cooperator(scheduler=sched)
-
- # Add two task; this should schedule the tick:
- task1 = coop.cooperate(iter([1, 2]))
- task2 = coop.cooperate(iter([1, 2]))
- self.assertEqual(calls[0].func, coop._tick)
-
- # Remove first task; scheduled call should still be going:
- task1.stop()
- self.assertEqual(calls[0].cancelled, False)
- self.assertEqual(coop._delayedCall, calls[0])
-
- # Remove second task; scheduled call should be cancelled:
- task2.stop()
- self.assertEqual(calls[0].cancelled, True)
- self.assertEqual(coop._delayedCall, None)
-
- # Add another task; scheduled call will be recreated:
- task3 = coop.cooperate(iter([1, 2]))
- self.assertEqual(calls[0].cancelled, False)
- self.assertEqual(coop._delayedCall, calls[0])
-
-
-
-class UnhandledException(Exception):
- """
- An exception that should go unhandled.
- """
-
-
-
-class AliasTests(unittest.TestCase):
- """
- Integration test to verify that the global singleton aliases do what
- they're supposed to.
- """
-
- def test_cooperate(self):
- """
- L{twisted.internet.task.cooperate} ought to run the generator that it is
- """
- d = defer.Deferred()
- def doit():
- yield 1
- yield 2
- yield 3
- d.callback("yay")
- it = doit()
- theTask = task.cooperate(it)
- self.assertIn(theTask, task._theCooperator._tasks)
- return d
-
-
-
-class RunStateTests(unittest.TestCase):
- """
- Tests to verify the behavior of L{CooperativeTask.pause},
- L{CooperativeTask.resume}, L{CooperativeTask.stop}, exhausting the
- underlying iterator, and their interactions with each other.
- """
-
- def setUp(self):
- """
- Create a cooperator with a fake scheduler and a termination predicate
- that ensures only one unit of work will take place per tick.
- """
- self._doDeferNext = False
- self._doStopNext = False
- self._doDieNext = False
- self.work = []
- self.scheduler = FakeScheduler()
- self.cooperator = task.Cooperator(
- scheduler=self.scheduler,
- # Always stop after one iteration of work (return a function which
- # returns a function which always returns True)
- terminationPredicateFactory=lambda: lambda: True)
- self.task = self.cooperator.cooperate(self.worker())
- self.cooperator.start()
-
-
- def worker(self):
- """
- This is a sample generator which yields Deferreds when we are testing
- deferral and an ascending integer count otherwise.
- """
- i = 0
- while True:
- i += 1
- if self._doDeferNext:
- self._doDeferNext = False
- d = defer.Deferred()
- self.work.append(d)
- yield d
- elif self._doStopNext:
- return
- elif self._doDieNext:
- raise UnhandledException()
- else:
- self.work.append(i)
- yield i
-
-
- def tearDown(self):
- """
- Drop references to interesting parts of the fixture to allow Deferred
- errors to be noticed when things start failing.
- """
- del self.task
- del self.scheduler
-
-
- def deferNext(self):
- """
- Defer the next result from my worker iterator.
- """
- self._doDeferNext = True
-
-
- def stopNext(self):
- """
- Make the next result from my worker iterator be completion (raising
- StopIteration).
- """
- self._doStopNext = True
-
-
- def dieNext(self):
- """
- Make the next result from my worker iterator be raising an
- L{UnhandledException}.
- """
- def ignoreUnhandled(failure):
- failure.trap(UnhandledException)
- return None
- self._doDieNext = True
-
-
- def test_pauseResume(self):
- """
- Cooperators should stop running their tasks when they're paused, and
- start again when they're resumed.
- """
- # first, sanity check
- self.scheduler.pump()
- self.assertEqual(self.work, [1])
- self.scheduler.pump()
- self.assertEqual(self.work, [1, 2])
-
- # OK, now for real
- self.task.pause()
- self.scheduler.pump()
- self.assertEqual(self.work, [1, 2])
- self.task.resume()
- # Resuming itself shoult not do any work
- self.assertEqual(self.work, [1, 2])
- self.scheduler.pump()
- # But when the scheduler rolls around again...
- self.assertEqual(self.work, [1, 2, 3])
-
-
- def test_resumeNotPaused(self):
- """
- L{CooperativeTask.resume} should raise a L{TaskNotPaused} exception if
- it was not paused; e.g. if L{CooperativeTask.pause} was not invoked
- more times than L{CooperativeTask.resume} on that object.
- """
- self.assertRaises(task.NotPaused, self.task.resume)
- self.task.pause()
- self.task.resume()
- self.assertRaises(task.NotPaused, self.task.resume)
-
-
- def test_pauseTwice(self):
- """
- Pauses on tasks should behave like a stack. If a task is paused twice,
- it needs to be resumed twice.
- """
- # pause once
- self.task.pause()
- self.scheduler.pump()
- self.assertEqual(self.work, [])
- # pause twice
- self.task.pause()
- self.scheduler.pump()
- self.assertEqual(self.work, [])
- # resume once (it shouldn't)
- self.task.resume()
- self.scheduler.pump()
- self.assertEqual(self.work, [])
- # resume twice (now it should go)
- self.task.resume()
- self.scheduler.pump()
- self.assertEqual(self.work, [1])
-
-
- def test_pauseWhileDeferred(self):
- """
- C{pause()}ing a task while it is waiting on an outstanding
- L{defer.Deferred} should put the task into a state where the
- outstanding L{defer.Deferred} must be called back I{and} the task is
- C{resume}d before it will continue processing.
- """
- self.deferNext()
- self.scheduler.pump()
- self.assertEqual(len(self.work), 1)
- self.failUnless(isinstance(self.work[0], defer.Deferred))
- self.scheduler.pump()
- self.assertEqual(len(self.work), 1)
- self.task.pause()
- self.scheduler.pump()
- self.assertEqual(len(self.work), 1)
- self.task.resume()
- self.scheduler.pump()
- self.assertEqual(len(self.work), 1)
- self.work[0].callback("STUFF!")
- self.scheduler.pump()
- self.assertEqual(len(self.work), 2)
- self.assertEqual(self.work[1], 2)
-
-
- def test_whenDone(self):
- """
- L{CooperativeTask.whenDone} returns a Deferred which fires when the
- Cooperator's iterator is exhausted. It returns a new Deferred each
- time it is called; callbacks added to other invocations will not modify
- the value that subsequent invocations will fire with.
- """
-
- deferred1 = self.task.whenDone()
- deferred2 = self.task.whenDone()
- results1 = []
- results2 = []
- final1 = []
- final2 = []
-
- def callbackOne(result):
- results1.append(result)
- return 1
-
- def callbackTwo(result):
- results2.append(result)
- return 2
-
- deferred1.addCallback(callbackOne)
- deferred2.addCallback(callbackTwo)
-
- deferred1.addCallback(final1.append)
- deferred2.addCallback(final2.append)
-
- # exhaust the task iterator
- # callbacks fire
- self.stopNext()
- self.scheduler.pump()
-
- self.assertEqual(len(results1), 1)
- self.assertEqual(len(results2), 1)
-
- self.assertIdentical(results1[0], self.task._iterator)
- self.assertIdentical(results2[0], self.task._iterator)
-
- self.assertEqual(final1, [1])
- self.assertEqual(final2, [2])
-
-
- def test_whenDoneError(self):
- """
- L{CooperativeTask.whenDone} returns a L{defer.Deferred} that will fail
- when the iterable's C{next} method raises an exception, with that
- exception.
- """
- deferred1 = self.task.whenDone()
- results = []
- deferred1.addErrback(results.append)
- self.dieNext()
- self.scheduler.pump()
- self.assertEqual(len(results), 1)
- self.assertEqual(results[0].check(UnhandledException), UnhandledException)
-
-
- def test_whenDoneStop(self):
- """
- L{CooperativeTask.whenDone} returns a L{defer.Deferred} that fails with
- L{TaskStopped} when the C{stop} method is called on that
- L{CooperativeTask}.
- """
- deferred1 = self.task.whenDone()
- errors = []
- deferred1.addErrback(errors.append)
- self.task.stop()
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].check(task.TaskStopped), task.TaskStopped)
-
-
- def test_whenDoneAlreadyDone(self):
- """
- L{CooperativeTask.whenDone} will return a L{defer.Deferred} that will
- succeed immediately if its iterator has already completed.
- """
- self.stopNext()
- self.scheduler.pump()
- results = []
- self.task.whenDone().addCallback(results.append)
- self.assertEqual(results, [self.task._iterator])
-
-
- def test_stopStops(self):
- """
- C{stop()}ping a task should cause it to be removed from the run just as
- C{pause()}ing, with the distinction that C{resume()} will raise a
- L{TaskStopped} exception.
- """
- self.task.stop()
- self.scheduler.pump()
- self.assertEqual(len(self.work), 0)
- self.assertRaises(task.TaskStopped, self.task.stop)
- self.assertRaises(task.TaskStopped, self.task.pause)
- # Sanity check - it's still not scheduled, is it?
- self.scheduler.pump()
- self.assertEqual(self.work, [])
-
-
- def test_pauseStopResume(self):
- """
- C{resume()}ing a paused, stopped task should be a no-op; it should not
- raise an exception, because it's paused, but neither should it actually
- do more work from the task.
- """
- self.task.pause()
- self.task.stop()
- self.task.resume()
- self.scheduler.pump()
- self.assertEqual(self.work, [])
-
-
- def test_stopDeferred(self):
- """
- As a corrolary of the interaction of C{pause()} and C{unpause()},
- C{stop()}ping a task which is waiting on a L{Deferred} should cause the
- task to gracefully shut down, meaning that it should not be unpaused
- when the deferred fires.
- """
- self.deferNext()
- self.scheduler.pump()
- d = self.work.pop()
- self.assertEqual(self.task._pauseCount, 1)
- results = []
- d.addBoth(results.append)
- self.scheduler.pump()
- self.task.stop()
- self.scheduler.pump()
- d.callback(7)
- self.scheduler.pump()
- # Let's make sure that Deferred doesn't come out fried with an
- # unhandled error that will be logged. The value is None, rather than
- # our test value, 7, because this Deferred is returned to and consumed
- # by the cooperator code. Its callback therefore has no contract.
- self.assertEqual(results, [None])
- # But more importantly, no further work should have happened.
- self.assertEqual(self.work, [])
-
-
- def test_stopExhausted(self):
- """
- C{stop()}ping a L{CooperativeTask} whose iterator has been exhausted
- should raise L{TaskDone}.
- """
- self.stopNext()
- self.scheduler.pump()
- self.assertRaises(task.TaskDone, self.task.stop)
-
-
- def test_stopErrored(self):
- """
- C{stop()}ping a L{CooperativeTask} whose iterator has encountered an
- error should raise L{TaskFailed}.
- """
- self.dieNext()
- self.scheduler.pump()
- self.assertRaises(task.TaskFailed, self.task.stop)
-
-
- def test_stopCooperatorReentrancy(self):
- """
- If a callback of a L{Deferred} from L{CooperativeTask.whenDone} calls
- C{Cooperator.stop} on its L{CooperativeTask._cooperator}, the
- L{Cooperator} will stop, but the L{CooperativeTask} whose callback is
- calling C{stop} should already be considered 'stopped' by the time the
- callback is running, and therefore removed from the
- L{CoooperativeTask}.
- """
- callbackPhases = []
- def stopit(result):
- callbackPhases.append(result)
- self.cooperator.stop()
- # "done" here is a sanity check to make sure that we get all the
- # way through the callback; i.e. stop() shouldn't be raising an
- # exception due to the stopped-ness of our main task.
- callbackPhases.append("done")
- self.task.whenDone().addCallback(stopit)
- self.stopNext()
- self.scheduler.pump()
- self.assertEqual(callbackPhases, [self.task._iterator, "done"])
-
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defer.py
deleted file mode 100755
index 1b113462..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defer.py
+++ /dev/null
@@ -1,2002 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for defer module.
-"""
-
-import gc, traceback
-
-from twisted.trial import unittest
-from twisted.internet import reactor, defer
-from twisted.internet.task import Clock
-from twisted.python import failure, log
-from twisted.python.util import unsignedID
-
-class GenericError(Exception):
- pass
-
-
-
-class DeferredTestCase(unittest.TestCase):
-
- def setUp(self):
- self.callbackResults = None
- self.errbackResults = None
- self.callback2Results = None
- # Restore the debug flag to its original state when done.
- self.addCleanup(defer.setDebugging, defer.getDebugging())
-
- def _callback(self, *args, **kw):
- self.callbackResults = args, kw
- return args[0]
-
- def _callback2(self, *args, **kw):
- self.callback2Results = args, kw
-
- def _errback(self, *args, **kw):
- self.errbackResults = args, kw
-
- def testCallbackWithoutArgs(self):
- deferred = defer.Deferred()
- deferred.addCallback(self._callback)
- deferred.callback("hello")
- self.assertEqual(self.errbackResults, None)
- self.assertEqual(self.callbackResults, (('hello',), {}))
-
- def testCallbackWithArgs(self):
- deferred = defer.Deferred()
- deferred.addCallback(self._callback, "world")
- deferred.callback("hello")
- self.assertEqual(self.errbackResults, None)
- self.assertEqual(self.callbackResults, (('hello', 'world'), {}))
-
- def testCallbackWithKwArgs(self):
- deferred = defer.Deferred()
- deferred.addCallback(self._callback, world="world")
- deferred.callback("hello")
- self.assertEqual(self.errbackResults, None)
- self.assertEqual(self.callbackResults,
- (('hello',), {'world': 'world'}))
-
- def testTwoCallbacks(self):
- deferred = defer.Deferred()
- deferred.addCallback(self._callback)
- deferred.addCallback(self._callback2)
- deferred.callback("hello")
- self.assertEqual(self.errbackResults, None)
- self.assertEqual(self.callbackResults,
- (('hello',), {}))
- self.assertEqual(self.callback2Results,
- (('hello',), {}))
-
- def testDeferredList(self):
- defr1 = defer.Deferred()
- defr2 = defer.Deferred()
- defr3 = defer.Deferred()
- dl = defer.DeferredList([defr1, defr2, defr3])
- result = []
- def cb(resultList, result=result):
- result.extend(resultList)
- def catch(err):
- return None
- dl.addCallbacks(cb, cb)
- defr1.callback("1")
- defr2.addErrback(catch)
- # "catch" is added to eat the GenericError that will be passed on by
- # the DeferredList's callback on defr2. If left unhandled, the
- # Failure object would cause a log.err() warning about "Unhandled
- # error in Deferred". Twisted's pyunit watches for log.err calls and
- # treats them as failures. So "catch" must eat the error to prevent
- # it from flunking the test.
- defr2.errback(GenericError("2"))
- defr3.callback("3")
- self.assertEqual([result[0],
- #result[1][1] is now a Failure instead of an Exception
- (result[1][0], str(result[1][1].value)),
- result[2]],
-
- [(defer.SUCCESS, "1"),
- (defer.FAILURE, "2"),
- (defer.SUCCESS, "3")])
-
- def testEmptyDeferredList(self):
- result = []
- def cb(resultList, result=result):
- result.append(resultList)
-
- dl = defer.DeferredList([])
- dl.addCallbacks(cb)
- self.assertEqual(result, [[]])
-
- result[:] = []
- dl = defer.DeferredList([], fireOnOneCallback=1)
- dl.addCallbacks(cb)
- self.assertEqual(result, [])
-
- def testDeferredListFireOnOneError(self):
- defr1 = defer.Deferred()
- defr2 = defer.Deferred()
- defr3 = defer.Deferred()
- dl = defer.DeferredList([defr1, defr2, defr3], fireOnOneErrback=1)
- result = []
- dl.addErrback(result.append)
-
- # consume errors after they pass through the DeferredList (to avoid
- # 'Unhandled error in Deferred'.
- def catch(err):
- return None
- defr2.addErrback(catch)
-
- # fire one Deferred's callback, no result yet
- defr1.callback("1")
- self.assertEqual(result, [])
-
- # fire one Deferred's errback -- now we have a result
- defr2.errback(GenericError("from def2"))
- self.assertEqual(len(result), 1)
-
- # extract the result from the list
- aFailure = result[0]
-
- # the type of the failure is a FirstError
- self.failUnless(issubclass(aFailure.type, defer.FirstError),
- 'issubclass(aFailure.type, defer.FirstError) failed: '
- "failure's type is %r" % (aFailure.type,)
- )
-
- firstError = aFailure.value
-
- # check that the GenericError("2") from the deferred at index 1
- # (defr2) is intact inside failure.value
- self.assertEqual(firstError.subFailure.type, GenericError)
- self.assertEqual(firstError.subFailure.value.args, ("from def2",))
- self.assertEqual(firstError.index, 1)
-
-
- def testDeferredListDontConsumeErrors(self):
- d1 = defer.Deferred()
- dl = defer.DeferredList([d1])
-
- errorTrap = []
- d1.addErrback(errorTrap.append)
-
- result = []
- dl.addCallback(result.append)
-
- d1.errback(GenericError('Bang'))
- self.assertEqual('Bang', errorTrap[0].value.args[0])
- self.assertEqual(1, len(result))
- self.assertEqual('Bang', result[0][0][1].value.args[0])
-
- def testDeferredListConsumeErrors(self):
- d1 = defer.Deferred()
- dl = defer.DeferredList([d1], consumeErrors=True)
-
- errorTrap = []
- d1.addErrback(errorTrap.append)
-
- result = []
- dl.addCallback(result.append)
-
- d1.errback(GenericError('Bang'))
- self.assertEqual([], errorTrap)
- self.assertEqual(1, len(result))
- self.assertEqual('Bang', result[0][0][1].value.args[0])
-
- def testDeferredListFireOnOneErrorWithAlreadyFiredDeferreds(self):
- # Create some deferreds, and errback one
- d1 = defer.Deferred()
- d2 = defer.Deferred()
- d1.errback(GenericError('Bang'))
-
- # *Then* build the DeferredList, with fireOnOneErrback=True
- dl = defer.DeferredList([d1, d2], fireOnOneErrback=True)
- result = []
- dl.addErrback(result.append)
- self.assertEqual(1, len(result))
-
- d1.addErrback(lambda e: None) # Swallow error
-
- def testDeferredListWithAlreadyFiredDeferreds(self):
- # Create some deferreds, and err one, call the other
- d1 = defer.Deferred()
- d2 = defer.Deferred()
- d1.errback(GenericError('Bang'))
- d2.callback(2)
-
- # *Then* build the DeferredList
- dl = defer.DeferredList([d1, d2])
-
- result = []
- dl.addCallback(result.append)
-
- self.assertEqual(1, len(result))
-
- d1.addErrback(lambda e: None) # Swallow error
-
-
- def testImmediateSuccess(self):
- l = []
- d = defer.succeed("success")
- d.addCallback(l.append)
- self.assertEqual(l, ["success"])
-
-
- def testImmediateFailure(self):
- l = []
- d = defer.fail(GenericError("fail"))
- d.addErrback(l.append)
- self.assertEqual(str(l[0].value), "fail")
-
- def testPausedFailure(self):
- l = []
- d = defer.fail(GenericError("fail"))
- d.pause()
- d.addErrback(l.append)
- self.assertEqual(l, [])
- d.unpause()
- self.assertEqual(str(l[0].value), "fail")
-
- def testCallbackErrors(self):
- l = []
- d = defer.Deferred().addCallback(lambda _: 1 // 0).addErrback(l.append)
- d.callback(1)
- self.assert_(isinstance(l[0].value, ZeroDivisionError))
- l = []
- d = defer.Deferred().addCallback(
- lambda _: failure.Failure(ZeroDivisionError())).addErrback(l.append)
- d.callback(1)
- self.assert_(isinstance(l[0].value, ZeroDivisionError))
-
- def testUnpauseBeforeCallback(self):
- d = defer.Deferred()
- d.pause()
- d.addCallback(self._callback)
- d.unpause()
-
- def testReturnDeferred(self):
- d = defer.Deferred()
- d2 = defer.Deferred()
- d2.pause()
- d.addCallback(lambda r, d2=d2: d2)
- d.addCallback(self._callback)
- d.callback(1)
- assert self.callbackResults is None, "Should not have been called yet."
- d2.callback(2)
- assert self.callbackResults is None, "Still should not have been called yet."
- d2.unpause()
- assert self.callbackResults[0][0] == 2, "Result should have been from second deferred:%s" % (self.callbackResults,)
-
-
- def test_chainedPausedDeferredWithResult(self):
- """
- When a paused Deferred with a result is returned from a callback on
- another Deferred, the other Deferred is chained to the first and waits
- for it to be unpaused.
- """
- expected = object()
- paused = defer.Deferred()
- paused.callback(expected)
- paused.pause()
- chained = defer.Deferred()
- chained.addCallback(lambda ignored: paused)
- chained.callback(None)
-
- result = []
- chained.addCallback(result.append)
- self.assertEqual(result, [])
- paused.unpause()
- self.assertEqual(result, [expected])
-
-
- def test_pausedDeferredChained(self):
- """
- A paused Deferred encountered while pushing a result forward through a
- chain does not prevent earlier Deferreds from continuing to execute
- their callbacks.
- """
- first = defer.Deferred()
- second = defer.Deferred()
- first.addCallback(lambda ignored: second)
- first.callback(None)
- first.pause()
- second.callback(None)
- result = []
- second.addCallback(result.append)
- self.assertEqual(result, [None])
-
-
- def test_gatherResults(self):
- # test successful list of deferreds
- l = []
- defer.gatherResults([defer.succeed(1), defer.succeed(2)]).addCallback(l.append)
- self.assertEqual(l, [[1, 2]])
- # test failing list of deferreds
- l = []
- dl = [defer.succeed(1), defer.fail(ValueError)]
- defer.gatherResults(dl).addErrback(l.append)
- self.assertEqual(len(l), 1)
- self.assert_(isinstance(l[0], failure.Failure))
- # get rid of error
- dl[1].addErrback(lambda e: 1)
-
-
- def test_gatherResultsWithConsumeErrors(self):
- """
- If a L{Deferred} in the list passed to L{gatherResults} fires with a
- failure and C{consumerErrors} is C{True}, the failure is converted to a
- C{None} result on that L{Deferred}.
- """
- # test successful list of deferreds
- dgood = defer.succeed(1)
- dbad = defer.fail(RuntimeError("oh noes"))
- d = defer.gatherResults([dgood, dbad], consumeErrors=True)
- unconsumedErrors = []
- dbad.addErrback(unconsumedErrors.append)
- gatheredErrors = []
- d.addErrback(gatheredErrors.append)
-
- self.assertEqual((len(unconsumedErrors), len(gatheredErrors)),
- (0, 1))
- self.assertIsInstance(gatheredErrors[0].value, defer.FirstError)
- firstError = gatheredErrors[0].value.subFailure
- self.assertIsInstance(firstError.value, RuntimeError)
-
-
- def test_maybeDeferredSync(self):
- """
- L{defer.maybeDeferred} should retrieve the result of a synchronous
- function and pass it to its resulting L{defer.Deferred}.
- """
- S, E = [], []
- d = defer.maybeDeferred((lambda x: x + 5), 10)
- d.addCallbacks(S.append, E.append)
- self.assertEqual(E, [])
- self.assertEqual(S, [15])
- return d
-
-
- def test_maybeDeferredSyncError(self):
- """
- L{defer.maybeDeferred} should catch exception raised by a synchronous
- function and errback its resulting L{defer.Deferred} with it.
- """
- S, E = [], []
- try:
- '10' + 5
- except TypeError, e:
- expected = str(e)
- d = defer.maybeDeferred((lambda x: x + 5), '10')
- d.addCallbacks(S.append, E.append)
- self.assertEqual(S, [])
- self.assertEqual(len(E), 1)
- self.assertEqual(str(E[0].value), expected)
- return d
-
-
- def test_maybeDeferredAsync(self):
- """
- L{defer.maybeDeferred} should let L{defer.Deferred} instance pass by
- so that original result is the same.
- """
- d = defer.Deferred()
- d2 = defer.maybeDeferred(lambda: d)
- d.callback('Success')
- return d2.addCallback(self.assertEqual, 'Success')
-
-
- def test_maybeDeferredAsyncError(self):
- """
- L{defer.maybeDeferred} should let L{defer.Deferred} instance pass by
- so that L{failure.Failure} returned by the original instance is the
- same.
- """
- d = defer.Deferred()
- d2 = defer.maybeDeferred(lambda: d)
- d.errback(failure.Failure(RuntimeError()))
- return self.assertFailure(d2, RuntimeError)
-
-
- def test_innerCallbacksPreserved(self):
- """
- When a L{Deferred} encounters a result which is another L{Deferred}
- which is waiting on a third L{Deferred}, the middle L{Deferred}'s
- callbacks are executed after the third L{Deferred} fires and before the
- first receives a result.
- """
- results = []
- failures = []
- inner = defer.Deferred()
- def cb(result):
- results.append(('start-of-cb', result))
- d = defer.succeed('inner')
- def firstCallback(result):
- results.append(('firstCallback', 'inner'))
- return inner
- def secondCallback(result):
- results.append(('secondCallback', result))
- return result * 2
- d.addCallback(firstCallback).addCallback(secondCallback)
- d.addErrback(failures.append)
- return d
- outer = defer.succeed('outer')
- outer.addCallback(cb)
- inner.callback('orange')
- outer.addCallback(results.append)
- inner.addErrback(failures.append)
- outer.addErrback(failures.append)
- self.assertEqual([], failures)
- self.assertEqual(
- results,
- [('start-of-cb', 'outer'),
- ('firstCallback', 'inner'),
- ('secondCallback', 'orange'),
- 'orangeorange'])
-
-
- def test_continueCallbackNotFirst(self):
- """
- The continue callback of a L{Deferred} waiting for another L{Deferred}
- is not necessarily the first one. This is somewhat a whitebox test
- checking that we search for that callback among the whole list of
- callbacks.
- """
- results = []
- failures = []
- a = defer.Deferred()
-
- def cb(result):
- results.append(('cb', result))
- d = defer.Deferred()
-
- def firstCallback(ignored):
- results.append(('firstCallback', ignored))
- return defer.gatherResults([a])
-
- def secondCallback(result):
- results.append(('secondCallback', result))
-
- d.addCallback(firstCallback)
- d.addCallback(secondCallback)
- d.addErrback(failures.append)
- d.callback(None)
- return d
-
- outer = defer.succeed('outer')
- outer.addCallback(cb)
- outer.addErrback(failures.append)
- self.assertEqual([('cb', 'outer'), ('firstCallback', None)], results)
- a.callback('withers')
- self.assertEqual([], failures)
- self.assertEqual(
- results,
- [('cb', 'outer'),
- ('firstCallback', None),
- ('secondCallback', ['withers'])])
-
-
- def test_callbackOrderPreserved(self):
- """
- A callback added to a L{Deferred} after a previous callback attached
- another L{Deferred} as a result is run after the callbacks of the other
- L{Deferred} are run.
- """
- results = []
- failures = []
- a = defer.Deferred()
-
- def cb(result):
- results.append(('cb', result))
- d = defer.Deferred()
-
- def firstCallback(ignored):
- results.append(('firstCallback', ignored))
- return defer.gatherResults([a])
-
- def secondCallback(result):
- results.append(('secondCallback', result))
-
- d.addCallback(firstCallback)
- d.addCallback(secondCallback)
- d.addErrback(failures.append)
- d.callback(None)
- return d
-
- outer = defer.Deferred()
- outer.addCallback(cb)
- outer.addCallback(lambda x: results.append('final'))
- outer.addErrback(failures.append)
- outer.callback('outer')
- self.assertEqual([('cb', 'outer'), ('firstCallback', None)], results)
- a.callback('withers')
- self.assertEqual([], failures)
- self.assertEqual(
- results,
- [('cb', 'outer'),
- ('firstCallback', None),
- ('secondCallback', ['withers']), 'final'])
-
-
- def test_reentrantRunCallbacks(self):
- """
- A callback added to a L{Deferred} by a callback on that L{Deferred}
- should be added to the end of the callback chain.
- """
- deferred = defer.Deferred()
- called = []
- def callback3(result):
- called.append(3)
- def callback2(result):
- called.append(2)
- def callback1(result):
- called.append(1)
- deferred.addCallback(callback3)
- deferred.addCallback(callback1)
- deferred.addCallback(callback2)
- deferred.callback(None)
- self.assertEqual(called, [1, 2, 3])
-
-
- def test_nonReentrantCallbacks(self):
- """
- A callback added to a L{Deferred} by a callback on that L{Deferred}
- should not be executed until the running callback returns.
- """
- deferred = defer.Deferred()
- called = []
- def callback2(result):
- called.append(2)
- def callback1(result):
- called.append(1)
- deferred.addCallback(callback2)
- self.assertEqual(called, [1])
- deferred.addCallback(callback1)
- deferred.callback(None)
- self.assertEqual(called, [1, 2])
-
-
- def test_reentrantRunCallbacksWithFailure(self):
- """
- After an exception is raised by a callback which was added to a
- L{Deferred} by a callback on that L{Deferred}, the L{Deferred} should
- call the first errback with a L{Failure} wrapping that exception.
- """
- exceptionMessage = "callback raised exception"
- deferred = defer.Deferred()
- def callback2(result):
- raise Exception(exceptionMessage)
- def callback1(result):
- deferred.addCallback(callback2)
- deferred.addCallback(callback1)
- deferred.callback(None)
- self.assertFailure(deferred, Exception)
- def cbFailed(exception):
- self.assertEqual(exception.args, (exceptionMessage,))
- deferred.addCallback(cbFailed)
- return deferred
-
-
- def test_synchronousImplicitChain(self):
- """
- If a first L{Deferred} with a result is returned from a callback on a
- second L{Deferred}, the result of the second L{Deferred} becomes the
- result of the first L{Deferred} and the result of the first L{Deferred}
- becomes C{None}.
- """
- result = object()
- first = defer.succeed(result)
- second = defer.Deferred()
- second.addCallback(lambda ign: first)
- second.callback(None)
-
- results = []
- first.addCallback(results.append)
- self.assertIdentical(results[0], None)
- second.addCallback(results.append)
- self.assertIdentical(results[1], result)
-
-
- def test_asynchronousImplicitChain(self):
- """
- If a first L{Deferred} without a result is returned from a callback on
- a second L{Deferred}, the result of the second L{Deferred} becomes the
- result of the first L{Deferred} as soon as the first L{Deferred} has
- one and the result of the first L{Deferred} becomes C{None}.
- """
- first = defer.Deferred()
- second = defer.Deferred()
- second.addCallback(lambda ign: first)
- second.callback(None)
-
- firstResult = []
- first.addCallback(firstResult.append)
- secondResult = []
- second.addCallback(secondResult.append)
-
- self.assertEqual(firstResult, [])
- self.assertEqual(secondResult, [])
-
- result = object()
- first.callback(result)
-
- self.assertEqual(firstResult, [None])
- self.assertEqual(secondResult, [result])
-
-
- def test_synchronousImplicitErrorChain(self):
- """
- If a first L{Deferred} with a L{Failure} result is returned from a
- callback on a second L{Deferred}, the first L{Deferred}'s result is
- converted to L{None} and no unhandled error is logged when it is
- garbage collected.
- """
- first = defer.fail(RuntimeError("First Deferred's Failure"))
- second = defer.Deferred()
- second.addCallback(lambda ign, first=first: first)
- self.assertFailure(second, RuntimeError)
- second.callback(None)
- firstResult = []
- first.addCallback(firstResult.append)
- self.assertIdentical(firstResult[0], None)
- return second
-
-
- def test_asynchronousImplicitErrorChain(self):
- """
- Let C{a} and C{b} be two L{Deferred}s.
-
- If C{a} has no result and is returned from a callback on C{b} then when
- C{a} fails, C{b}'s result becomes the L{Failure} that was C{a}'s result,
- the result of C{a} becomes C{None} so that no unhandled error is logged
- when it is garbage collected.
- """
- first = defer.Deferred()
- second = defer.Deferred()
- second.addCallback(lambda ign: first)
- second.callback(None)
- self.assertFailure(second, RuntimeError)
-
- firstResult = []
- first.addCallback(firstResult.append)
- secondResult = []
- second.addCallback(secondResult.append)
-
- self.assertEqual(firstResult, [])
- self.assertEqual(secondResult, [])
-
- first.errback(RuntimeError("First Deferred's Failure"))
-
- self.assertEqual(firstResult, [None])
- self.assertEqual(len(secondResult), 1)
-
-
- def test_doubleAsynchronousImplicitChaining(self):
- """
- L{Deferred} chaining is transitive.
-
- In other words, let A, B, and C be Deferreds. If C is returned from a
- callback on B and B is returned from a callback on A then when C fires,
- A fires.
- """
- first = defer.Deferred()
- second = defer.Deferred()
- second.addCallback(lambda ign: first)
- third = defer.Deferred()
- third.addCallback(lambda ign: second)
-
- thirdResult = []
- third.addCallback(thirdResult.append)
-
- result = object()
- # After this, second is waiting for first to tell it to continue.
- second.callback(None)
- # And after this, third is waiting for second to tell it to continue.
- third.callback(None)
-
- # Still waiting
- self.assertEqual(thirdResult, [])
-
- # This will tell second to continue which will tell third to continue.
- first.callback(result)
-
- self.assertEqual(thirdResult, [result])
-
-
- def test_nestedAsynchronousChainedDeferreds(self):
- """
- L{Deferred}s can have callbacks that themselves return L{Deferred}s.
- When these "inner" L{Deferred}s fire (even asynchronously), the
- callback chain continues.
- """
- results = []
- failures = []
-
- # A Deferred returned in the inner callback.
- inner = defer.Deferred()
-
- def cb(result):
- results.append(('start-of-cb', result))
- d = defer.succeed('inner')
-
- def firstCallback(result):
- results.append(('firstCallback', 'inner'))
- # Return a Deferred that definitely has not fired yet, so we
- # can fire the Deferreds out of order.
- return inner
-
- def secondCallback(result):
- results.append(('secondCallback', result))
- return result * 2
-
- d.addCallback(firstCallback).addCallback(secondCallback)
- d.addErrback(failures.append)
- return d
-
- # Create a synchronous Deferred that has a callback 'cb' that returns
- # a Deferred 'd' that has fired but is now waiting on an unfired
- # Deferred 'inner'.
- outer = defer.succeed('outer')
- outer.addCallback(cb)
- outer.addCallback(results.append)
- # At this point, the callback 'cb' has been entered, and the first
- # callback of 'd' has been called.
- self.assertEqual(
- results, [('start-of-cb', 'outer'), ('firstCallback', 'inner')])
-
- # Once the inner Deferred is fired, processing of the outer Deferred's
- # callback chain continues.
- inner.callback('orange')
-
- # Make sure there are no errors.
- inner.addErrback(failures.append)
- outer.addErrback(failures.append)
- self.assertEqual(
- [], failures, "Got errbacks but wasn't expecting any.")
-
- self.assertEqual(
- results,
- [('start-of-cb', 'outer'),
- ('firstCallback', 'inner'),
- ('secondCallback', 'orange'),
- 'orangeorange'])
-
-
- def test_nestedAsynchronousChainedDeferredsWithExtraCallbacks(self):
- """
- L{Deferred}s can have callbacks that themselves return L{Deferred}s.
- These L{Deferred}s can have other callbacks added before they are
- returned, which subtly changes the callback chain. When these "inner"
- L{Deferred}s fire (even asynchronously), the outer callback chain
- continues.
- """
- results = []
- failures = []
-
- # A Deferred returned in the inner callback after a callback is
- # added explicitly and directly to it.
- inner = defer.Deferred()
-
- def cb(result):
- results.append(('start-of-cb', result))
- d = defer.succeed('inner')
-
- def firstCallback(ignored):
- results.append(('firstCallback', ignored))
- # Return a Deferred that definitely has not fired yet with a
- # result-transforming callback so we can fire the Deferreds
- # out of order and see how the callback affects the ultimate
- # results.
- return inner.addCallback(lambda x: [x])
-
- def secondCallback(result):
- results.append(('secondCallback', result))
- return result * 2
-
- d.addCallback(firstCallback)
- d.addCallback(secondCallback)
- d.addErrback(failures.append)
- return d
-
- # Create a synchronous Deferred that has a callback 'cb' that returns
- # a Deferred 'd' that has fired but is now waiting on an unfired
- # Deferred 'inner'.
- outer = defer.succeed('outer')
- outer.addCallback(cb)
- outer.addCallback(results.append)
- # At this point, the callback 'cb' has been entered, and the first
- # callback of 'd' has been called.
- self.assertEqual(
- results, [('start-of-cb', 'outer'), ('firstCallback', 'inner')])
-
- # Once the inner Deferred is fired, processing of the outer Deferred's
- # callback chain continues.
- inner.callback('withers')
-
- # Make sure there are no errors.
- outer.addErrback(failures.append)
- inner.addErrback(failures.append)
- self.assertEqual(
- [], failures, "Got errbacks but wasn't expecting any.")
-
- self.assertEqual(
- results,
- [('start-of-cb', 'outer'),
- ('firstCallback', 'inner'),
- ('secondCallback', ['withers']),
- ['withers', 'withers']])
-
-
- def test_chainDeferredRecordsExplicitChain(self):
- """
- When we chain a L{Deferred}, that chaining is recorded explicitly.
- """
- a = defer.Deferred()
- b = defer.Deferred()
- b.chainDeferred(a)
- self.assertIdentical(a._chainedTo, b)
-
-
- def test_explicitChainClearedWhenResolved(self):
- """
- Any recorded chaining is cleared once the chaining is resolved, since
- it no longer exists.
-
- In other words, if one L{Deferred} is recorded as depending on the
- result of another, and I{that} L{Deferred} has fired, then the
- dependency is resolved and we no longer benefit from recording it.
- """
- a = defer.Deferred()
- b = defer.Deferred()
- b.chainDeferred(a)
- b.callback(None)
- self.assertIdentical(a._chainedTo, None)
-
-
- def test_chainDeferredRecordsImplicitChain(self):
- """
- We can chain L{Deferred}s implicitly by adding callbacks that return
- L{Deferred}s. When this chaining happens, we record it explicitly as
- soon as we can find out about it.
- """
- a = defer.Deferred()
- b = defer.Deferred()
- a.addCallback(lambda ignored: b)
- a.callback(None)
- self.assertIdentical(a._chainedTo, b)
-
-
- def test_repr(self):
- """
- The C{repr()} of a L{Deferred} contains the class name and a
- representation of the internal Python ID.
- """
- d = defer.Deferred()
- address = hex(unsignedID(d))
- self.assertEqual(
- repr(d), '<Deferred at %s>' % (address,))
-
-
- def test_reprWithResult(self):
- """
- If a L{Deferred} has been fired, then its C{repr()} contains its
- result.
- """
- d = defer.Deferred()
- d.callback('orange')
- self.assertEqual(
- repr(d), "<Deferred at %s current result: 'orange'>" % (
- hex(unsignedID(d))))
-
-
- def test_reprWithChaining(self):
- """
- If a L{Deferred} C{a} has been fired, but is waiting on another
- L{Deferred} C{b} that appears in its callback chain, then C{repr(a)}
- says that it is waiting on C{b}.
- """
- a = defer.Deferred()
- b = defer.Deferred()
- b.chainDeferred(a)
- self.assertEqual(
- repr(a), "<Deferred at %s waiting on Deferred at %s>" % (
- hex(unsignedID(a)), hex(unsignedID(b))))
-
-
- def test_boundedStackDepth(self):
- """
- The depth of the call stack does not grow as more L{Deferred} instances
- are chained together.
- """
- def chainDeferreds(howMany):
- stack = []
- def recordStackDepth(ignored):
- stack.append(len(traceback.extract_stack()))
-
- top = defer.Deferred()
- innerDeferreds = [defer.Deferred() for ignored in range(howMany)]
- originalInners = innerDeferreds[:]
- last = defer.Deferred()
-
- inner = innerDeferreds.pop()
- top.addCallback(lambda ign, inner=inner: inner)
- top.addCallback(recordStackDepth)
-
- while innerDeferreds:
- newInner = innerDeferreds.pop()
- inner.addCallback(lambda ign, inner=newInner: inner)
- inner = newInner
- inner.addCallback(lambda ign: last)
-
- top.callback(None)
- for inner in originalInners:
- inner.callback(None)
-
- # Sanity check - the record callback is not intended to have
- # fired yet.
- self.assertEqual(stack, [])
-
- # Now fire the last thing and return the stack depth at which the
- # callback was invoked.
- last.callback(None)
- return stack[0]
-
- # Callbacks should be invoked at the same stack depth regardless of
- # how many Deferreds are chained.
- self.assertEqual(chainDeferreds(1), chainDeferreds(2))
-
-
- def test_resultOfDeferredResultOfDeferredOfFiredDeferredCalled(self):
- """
- Given three Deferreds, one chained to the next chained to the next,
- callbacks on the middle Deferred which are added after the chain is
- created are called once the last Deferred fires.
-
- This is more of a regression-style test. It doesn't exercise any
- particular code path through the current implementation of Deferred, but
- it does exercise a broken codepath through one of the variations of the
- implementation proposed as a resolution to ticket #411.
- """
- first = defer.Deferred()
- second = defer.Deferred()
- third = defer.Deferred()
- first.addCallback(lambda ignored: second)
- second.addCallback(lambda ignored: third)
- second.callback(None)
- first.callback(None)
- third.callback(None)
- L = []
- second.addCallback(L.append)
- self.assertEqual(L, [None])
-
-
- def test_errbackWithNoArgsNoDebug(self):
- """
- C{Deferred.errback()} creates a failure from the current Python
- exception. When Deferred.debug is not set no globals or locals are
- captured in that failure.
- """
- defer.setDebugging(False)
- d = defer.Deferred()
- l = []
- exc = GenericError("Bang")
- try:
- raise exc
- except:
- d.errback()
- d.addErrback(l.append)
- fail = l[0]
- self.assertEqual(fail.value, exc)
- localz, globalz = fail.frames[0][-2:]
- self.assertEqual([], localz)
- self.assertEqual([], globalz)
-
-
- def test_errbackWithNoArgs(self):
- """
- C{Deferred.errback()} creates a failure from the current Python
- exception. When Deferred.debug is set globals and locals are captured
- in that failure.
- """
- defer.setDebugging(True)
- d = defer.Deferred()
- l = []
- exc = GenericError("Bang")
- try:
- raise exc
- except:
- d.errback()
- d.addErrback(l.append)
- fail = l[0]
- self.assertEqual(fail.value, exc)
- localz, globalz = fail.frames[0][-2:]
- self.assertNotEquals([], localz)
- self.assertNotEquals([], globalz)
-
-
- def test_errorInCallbackDoesNotCaptureVars(self):
- """
- An error raised by a callback creates a Failure. The Failure captures
- locals and globals if and only if C{Deferred.debug} is set.
- """
- d = defer.Deferred()
- d.callback(None)
- defer.setDebugging(False)
- def raiseError(ignored):
- raise GenericError("Bang")
- d.addCallback(raiseError)
- l = []
- d.addErrback(l.append)
- fail = l[0]
- localz, globalz = fail.frames[0][-2:]
- self.assertEqual([], localz)
- self.assertEqual([], globalz)
-
-
- def test_errorInCallbackCapturesVarsWhenDebugging(self):
- """
- An error raised by a callback creates a Failure. The Failure captures
- locals and globals if and only if C{Deferred.debug} is set.
- """
- d = defer.Deferred()
- d.callback(None)
- defer.setDebugging(True)
- def raiseError(ignored):
- raise GenericError("Bang")
- d.addCallback(raiseError)
- l = []
- d.addErrback(l.append)
- fail = l[0]
- localz, globalz = fail.frames[0][-2:]
- self.assertNotEquals([], localz)
- self.assertNotEquals([], globalz)
-
-
-
-class FirstErrorTests(unittest.TestCase):
- """
- Tests for L{FirstError}.
- """
- def test_repr(self):
- """
- The repr of a L{FirstError} instance includes the repr of the value of
- the sub-failure and the index which corresponds to the L{FirstError}.
- """
- exc = ValueError("some text")
- try:
- raise exc
- except:
- f = failure.Failure()
-
- error = defer.FirstError(f, 3)
- self.assertEqual(
- repr(error),
- "FirstError[#3, %s]" % (repr(exc),))
-
-
- def test_str(self):
- """
- The str of a L{FirstError} instance includes the str of the
- sub-failure and the index which corresponds to the L{FirstError}.
- """
- exc = ValueError("some text")
- try:
- raise exc
- except:
- f = failure.Failure()
-
- error = defer.FirstError(f, 5)
- self.assertEqual(
- str(error),
- "FirstError[#5, %s]" % (str(f),))
-
-
- def test_comparison(self):
- """
- L{FirstError} instances compare equal to each other if and only if
- their failure and index compare equal. L{FirstError} instances do not
- compare equal to instances of other types.
- """
- try:
- 1 // 0
- except:
- firstFailure = failure.Failure()
-
- one = defer.FirstError(firstFailure, 13)
- anotherOne = defer.FirstError(firstFailure, 13)
-
- try:
- raise ValueError("bar")
- except:
- secondFailure = failure.Failure()
-
- another = defer.FirstError(secondFailure, 9)
-
- self.assertTrue(one == anotherOne)
- self.assertFalse(one == another)
- self.assertTrue(one != another)
- self.assertFalse(one != anotherOne)
-
- self.assertFalse(one == 10)
-
-
-
-class AlreadyCalledTestCase(unittest.TestCase):
- def setUp(self):
- self._deferredWasDebugging = defer.getDebugging()
- defer.setDebugging(True)
-
- def tearDown(self):
- defer.setDebugging(self._deferredWasDebugging)
-
- def _callback(self, *args, **kw):
- pass
- def _errback(self, *args, **kw):
- pass
-
- def _call_1(self, d):
- d.callback("hello")
- def _call_2(self, d):
- d.callback("twice")
- def _err_1(self, d):
- d.errback(failure.Failure(RuntimeError()))
- def _err_2(self, d):
- d.errback(failure.Failure(RuntimeError()))
-
- def testAlreadyCalled_CC(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._call_1(d)
- self.failUnlessRaises(defer.AlreadyCalledError, self._call_2, d)
-
- def testAlreadyCalled_CE(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._call_1(d)
- self.failUnlessRaises(defer.AlreadyCalledError, self._err_2, d)
-
- def testAlreadyCalled_EE(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._err_1(d)
- self.failUnlessRaises(defer.AlreadyCalledError, self._err_2, d)
-
- def testAlreadyCalled_EC(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._err_1(d)
- self.failUnlessRaises(defer.AlreadyCalledError, self._call_2, d)
-
-
- def _count(self, linetype, func, lines, expected):
- count = 0
- for line in lines:
- if (line.startswith(' %s:' % linetype) and
- line.endswith(' %s' % func)):
- count += 1
- self.failUnless(count == expected)
-
- def _check(self, e, caller, invoker1, invoker2):
- # make sure the debugging information is vaguely correct
- lines = e.args[0].split("\n")
- # the creator should list the creator (testAlreadyCalledDebug) but not
- # _call_1 or _call_2 or other invokers
- self._count('C', caller, lines, 1)
- self._count('C', '_call_1', lines, 0)
- self._count('C', '_call_2', lines, 0)
- self._count('C', '_err_1', lines, 0)
- self._count('C', '_err_2', lines, 0)
- # invoker should list the first invoker but not the second
- self._count('I', invoker1, lines, 1)
- self._count('I', invoker2, lines, 0)
-
- def testAlreadyCalledDebug_CC(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._call_1(d)
- try:
- self._call_2(d)
- except defer.AlreadyCalledError, e:
- self._check(e, "testAlreadyCalledDebug_CC", "_call_1", "_call_2")
- else:
- self.fail("second callback failed to raise AlreadyCalledError")
-
- def testAlreadyCalledDebug_CE(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._call_1(d)
- try:
- self._err_2(d)
- except defer.AlreadyCalledError, e:
- self._check(e, "testAlreadyCalledDebug_CE", "_call_1", "_err_2")
- else:
- self.fail("second errback failed to raise AlreadyCalledError")
-
- def testAlreadyCalledDebug_EC(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._err_1(d)
- try:
- self._call_2(d)
- except defer.AlreadyCalledError, e:
- self._check(e, "testAlreadyCalledDebug_EC", "_err_1", "_call_2")
- else:
- self.fail("second callback failed to raise AlreadyCalledError")
-
- def testAlreadyCalledDebug_EE(self):
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._err_1(d)
- try:
- self._err_2(d)
- except defer.AlreadyCalledError, e:
- self._check(e, "testAlreadyCalledDebug_EE", "_err_1", "_err_2")
- else:
- self.fail("second errback failed to raise AlreadyCalledError")
-
- def testNoDebugging(self):
- defer.setDebugging(False)
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- self._call_1(d)
- try:
- self._call_2(d)
- except defer.AlreadyCalledError, e:
- self.failIf(e.args)
- else:
- self.fail("second callback failed to raise AlreadyCalledError")
-
-
- def testSwitchDebugging(self):
- # Make sure Deferreds can deal with debug state flipping
- # around randomly. This is covering a particular fixed bug.
- defer.setDebugging(False)
- d = defer.Deferred()
- d.addBoth(lambda ign: None)
- defer.setDebugging(True)
- d.callback(None)
-
- defer.setDebugging(False)
- d = defer.Deferred()
- d.callback(None)
- defer.setDebugging(True)
- d.addBoth(lambda ign: None)
-
-
-
-class DeferredCancellerTest(unittest.TestCase):
- def setUp(self):
- self.callbackResults = None
- self.errbackResults = None
- self.callback2Results = None
- self.cancellerCallCount = 0
-
-
- def tearDown(self):
- # Sanity check that the canceller was called at most once.
- self.assertTrue(self.cancellerCallCount in (0, 1))
-
-
- def _callback(self, data):
- self.callbackResults = data
- return data
-
-
- def _callback2(self, data):
- self.callback2Results = data
-
-
- def _errback(self, data):
- self.errbackResults = data
-
-
- def test_noCanceller(self):
- """
- A L{defer.Deferred} without a canceller must errback with a
- L{defer.CancelledError} and not callback.
- """
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
- self.assertEqual(self.callbackResults, None)
-
-
- def test_raisesAfterCancelAndCallback(self):
- """
- A L{defer.Deferred} without a canceller, when cancelled must allow
- a single extra call to callback, and raise
- L{defer.AlreadyCalledError} if callbacked or errbacked thereafter.
- """
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
-
- # A single extra callback should be swallowed.
- d.callback(None)
-
- # But a second call to callback or errback is not.
- self.assertRaises(defer.AlreadyCalledError, d.callback, None)
- self.assertRaises(defer.AlreadyCalledError, d.errback, Exception())
-
-
- def test_raisesAfterCancelAndErrback(self):
- """
- A L{defer.Deferred} without a canceller, when cancelled must allow
- a single extra call to errback, and raise
- L{defer.AlreadyCalledError} if callbacked or errbacked thereafter.
- """
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
-
- # A single extra errback should be swallowed.
- d.errback(Exception())
-
- # But a second call to callback or errback is not.
- self.assertRaises(defer.AlreadyCalledError, d.callback, None)
- self.assertRaises(defer.AlreadyCalledError, d.errback, Exception())
-
-
- def test_noCancellerMultipleCancelsAfterCancelAndCallback(self):
- """
- A L{Deferred} without a canceller, when cancelled and then
- callbacked, ignores multiple cancels thereafter.
- """
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- currentFailure = self.errbackResults
- # One callback will be ignored
- d.callback(None)
- # Cancel should have no effect.
- d.cancel()
- self.assertIdentical(currentFailure, self.errbackResults)
-
-
- def test_noCancellerMultipleCancelsAfterCancelAndErrback(self):
- """
- A L{defer.Deferred} without a canceller, when cancelled and then
- errbacked, ignores multiple cancels thereafter.
- """
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
- currentFailure = self.errbackResults
- # One errback will be ignored
- d.errback(GenericError())
- # I.e., we should still have a CancelledError.
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
- d.cancel()
- self.assertIdentical(currentFailure, self.errbackResults)
-
-
- def test_noCancellerMultipleCancel(self):
- """
- Calling cancel multiple times on a deferred with no canceller
- results in a L{defer.CancelledError}. Subsequent calls to cancel
- do not cause an error.
- """
- d = defer.Deferred()
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
- currentFailure = self.errbackResults
- d.cancel()
- self.assertIdentical(currentFailure, self.errbackResults)
-
-
- def test_cancellerMultipleCancel(self):
- """
- Verify that calling cancel multiple times on a deferred with a
- canceller that does not errback results in a
- L{defer.CancelledError} and that subsequent calls to cancel do not
- cause an error and that after all that, the canceller was only
- called once.
- """
- def cancel(d):
- self.cancellerCallCount += 1
-
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
- currentFailure = self.errbackResults
- d.cancel()
- self.assertIdentical(currentFailure, self.errbackResults)
- self.assertEqual(self.cancellerCallCount, 1)
-
-
- def test_simpleCanceller(self):
- """
- Verify that a L{defer.Deferred} calls its specified canceller when
- it is cancelled, and that further call/errbacks raise
- L{defer.AlreadyCalledError}.
- """
- def cancel(d):
- self.cancellerCallCount += 1
-
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.cancellerCallCount, 1)
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
-
- # Test that further call/errbacks are *not* swallowed
- self.assertRaises(defer.AlreadyCalledError, d.callback, None)
- self.assertRaises(defer.AlreadyCalledError, d.errback, Exception())
-
-
- def test_cancellerArg(self):
- """
- Verify that a canceller is given the correct deferred argument.
- """
- def cancel(d1):
- self.assertIdentical(d1, d)
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
-
-
- def test_cancelAfterCallback(self):
- """
- Test that cancelling a deferred after it has been callbacked does
- not cause an error.
- """
- def cancel(d):
- self.cancellerCallCount += 1
- d.errback(GenericError())
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.callback('biff!')
- d.cancel()
- self.assertEqual(self.cancellerCallCount, 0)
- self.assertEqual(self.errbackResults, None)
- self.assertEqual(self.callbackResults, 'biff!')
-
-
- def test_cancelAfterErrback(self):
- """
- Test that cancelling a L{Deferred} after it has been errbacked does
- not result in a L{defer.CancelledError}.
- """
- def cancel(d):
- self.cancellerCallCount += 1
- d.errback(GenericError())
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.errback(GenericError())
- d.cancel()
- self.assertEqual(self.cancellerCallCount, 0)
- self.assertEqual(self.errbackResults.type, GenericError)
- self.assertEqual(self.callbackResults, None)
-
-
- def test_cancellerThatErrbacks(self):
- """
- Test a canceller which errbacks its deferred.
- """
- def cancel(d):
- self.cancellerCallCount += 1
- d.errback(GenericError())
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.cancellerCallCount, 1)
- self.assertEqual(self.errbackResults.type, GenericError)
-
-
- def test_cancellerThatCallbacks(self):
- """
- Test a canceller which calls its deferred.
- """
- def cancel(d):
- self.cancellerCallCount += 1
- d.callback('hello!')
- d = defer.Deferred(canceller=cancel)
- d.addCallbacks(self._callback, self._errback)
- d.cancel()
- self.assertEqual(self.cancellerCallCount, 1)
- self.assertEqual(self.callbackResults, 'hello!')
- self.assertEqual(self.errbackResults, None)
-
-
- def test_cancelNestedDeferred(self):
- """
- Verify that a Deferred, a, which is waiting on another Deferred, b,
- returned from one of its callbacks, will propagate
- L{defer.CancelledError} when a is cancelled.
- """
- def innerCancel(d):
- self.cancellerCallCount += 1
- def cancel(d):
- self.assert_(False)
-
- b = defer.Deferred(canceller=innerCancel)
- a = defer.Deferred(canceller=cancel)
- a.callback(None)
- a.addCallback(lambda data: b)
- a.cancel()
- a.addCallbacks(self._callback, self._errback)
- # The cancel count should be one (the cancellation done by B)
- self.assertEqual(self.cancellerCallCount, 1)
- # B's canceller didn't errback, so defer.py will have called errback
- # with a CancelledError.
- self.assertEqual(self.errbackResults.type, defer.CancelledError)
-
-
-
-class LogTestCase(unittest.TestCase):
- """
- Test logging of unhandled errors.
- """
-
- def setUp(self):
- """
- Add a custom observer to observer logging.
- """
- self.c = []
- log.addObserver(self.c.append)
-
- def tearDown(self):
- """
- Remove the observer.
- """
- log.removeObserver(self.c.append)
-
-
- def _loggedErrors(self):
- return [e for e in self.c if e["isError"]]
-
-
- def _check(self):
- """
- Check the output of the log observer to see if the error is present.
- """
- c2 = self._loggedErrors()
- self.assertEqual(len(c2), 2)
- c2[1]["failure"].trap(ZeroDivisionError)
- self.flushLoggedErrors(ZeroDivisionError)
-
- def test_errorLog(self):
- """
- Verify that when a L{Deferred} with no references to it is fired,
- and its final result (the one not handled by any callback) is an
- exception, that exception will be logged immediately.
- """
- defer.Deferred().addCallback(lambda x: 1 // 0).callback(1)
- gc.collect()
- self._check()
-
- def test_errorLogWithInnerFrameRef(self):
- """
- Same as L{test_errorLog}, but with an inner frame.
- """
- def _subErrorLogWithInnerFrameRef():
- d = defer.Deferred()
- d.addCallback(lambda x: 1 // 0)
- d.callback(1)
-
- _subErrorLogWithInnerFrameRef()
- gc.collect()
- self._check()
-
- def test_errorLogWithInnerFrameCycle(self):
- """
- Same as L{test_errorLogWithInnerFrameRef}, plus create a cycle.
- """
- def _subErrorLogWithInnerFrameCycle():
- d = defer.Deferred()
- d.addCallback(lambda x, d=d: 1 // 0)
- d._d = d
- d.callback(1)
-
- _subErrorLogWithInnerFrameCycle()
- gc.collect()
- self._check()
-
-
- def test_chainedErrorCleanup(self):
- """
- If one Deferred with an error result is returned from a callback on
- another Deferred, when the first Deferred is garbage collected it does
- not log its error.
- """
- d = defer.Deferred()
- d.addCallback(lambda ign: defer.fail(RuntimeError("zoop")))
- d.callback(None)
-
- # Sanity check - this isn't too interesting, but we do want the original
- # Deferred to have gotten the failure.
- results = []
- errors = []
- d.addCallbacks(results.append, errors.append)
- self.assertEqual(results, [])
- self.assertEqual(len(errors), 1)
- errors[0].trap(Exception)
-
- # Get rid of any references we might have to the inner Deferred (none of
- # these should really refer to it, but we're just being safe).
- del results, errors, d
- # Force a collection cycle so that there's a chance for an error to be
- # logged, if it's going to be logged.
- gc.collect()
- # And make sure it is not.
- self.assertEqual(self._loggedErrors(), [])
-
-
- def test_errorClearedByChaining(self):
- """
- If a Deferred with a failure result has an errback which chains it to
- another Deferred, the initial failure is cleared by the errback so it is
- not logged.
- """
- # Start off with a Deferred with a failure for a result
- bad = defer.fail(Exception("oh no"))
- good = defer.Deferred()
- # Give it a callback that chains it to another Deferred
- bad.addErrback(lambda ignored: good)
- # That's all, clean it up. No Deferred here still has a failure result,
- # so nothing should be logged.
- good = bad = None
- gc.collect()
- self.assertEqual(self._loggedErrors(), [])
-
-
-
-class DeferredTestCaseII(unittest.TestCase):
- def setUp(self):
- self.callbackRan = 0
-
- def testDeferredListEmpty(self):
- """Testing empty DeferredList."""
- dl = defer.DeferredList([])
- dl.addCallback(self.cb_empty)
-
- def cb_empty(self, res):
- self.callbackRan = 1
- self.assertEqual([], res)
-
- def tearDown(self):
- self.failUnless(self.callbackRan, "Callback was never run.")
-
-class OtherPrimitives(unittest.TestCase):
- def _incr(self, result):
- self.counter += 1
-
- def setUp(self):
- self.counter = 0
-
- def testLock(self):
- lock = defer.DeferredLock()
- lock.acquire().addCallback(self._incr)
- self.failUnless(lock.locked)
- self.assertEqual(self.counter, 1)
-
- lock.acquire().addCallback(self._incr)
- self.failUnless(lock.locked)
- self.assertEqual(self.counter, 1)
-
- lock.release()
- self.failUnless(lock.locked)
- self.assertEqual(self.counter, 2)
-
- lock.release()
- self.failIf(lock.locked)
- self.assertEqual(self.counter, 2)
-
- self.assertRaises(TypeError, lock.run)
-
- firstUnique = object()
- secondUnique = object()
-
- controlDeferred = defer.Deferred()
- def helper(self, b):
- self.b = b
- return controlDeferred
-
- resultDeferred = lock.run(helper, self=self, b=firstUnique)
- self.failUnless(lock.locked)
- self.assertEqual(self.b, firstUnique)
-
- resultDeferred.addCallback(lambda x: setattr(self, 'result', x))
-
- lock.acquire().addCallback(self._incr)
- self.failUnless(lock.locked)
- self.assertEqual(self.counter, 2)
-
- controlDeferred.callback(secondUnique)
- self.assertEqual(self.result, secondUnique)
- self.failUnless(lock.locked)
- self.assertEqual(self.counter, 3)
-
- d = lock.acquire().addBoth(lambda x: setattr(self, 'result', x))
- d.cancel()
- self.assertEqual(self.result.type, defer.CancelledError)
-
- lock.release()
- self.failIf(lock.locked)
-
-
- def test_cancelLockAfterAcquired(self):
- """
- When canceling a L{Deferred} from a L{DeferredLock} that already
- has the lock, the cancel should have no effect.
- """
- def _failOnErrback(_):
- self.fail("Unexpected errback call!")
- lock = defer.DeferredLock()
- d = lock.acquire()
- d.addErrback(_failOnErrback)
- d.cancel()
-
-
- def test_cancelLockBeforeAcquired(self):
- """
- When canceling a L{Deferred} from a L{DeferredLock} that does not
- yet have the lock (i.e., the L{Deferred} has not fired), the cancel
- should cause a L{defer.CancelledError} failure.
- """
- lock = defer.DeferredLock()
- lock.acquire()
- d = lock.acquire()
- self.assertFailure(d, defer.CancelledError)
- d.cancel()
-
-
- def testSemaphore(self):
- N = 13
- sem = defer.DeferredSemaphore(N)
-
- controlDeferred = defer.Deferred()
- def helper(self, arg):
- self.arg = arg
- return controlDeferred
-
- results = []
- uniqueObject = object()
- resultDeferred = sem.run(helper, self=self, arg=uniqueObject)
- resultDeferred.addCallback(results.append)
- resultDeferred.addCallback(self._incr)
- self.assertEqual(results, [])
- self.assertEqual(self.arg, uniqueObject)
- controlDeferred.callback(None)
- self.assertEqual(results.pop(), None)
- self.assertEqual(self.counter, 1)
-
- self.counter = 0
- for i in range(1, 1 + N):
- sem.acquire().addCallback(self._incr)
- self.assertEqual(self.counter, i)
-
-
- success = []
- def fail(r):
- success.append(False)
- def succeed(r):
- success.append(True)
- d = sem.acquire().addCallbacks(fail, succeed)
- d.cancel()
- self.assertEqual(success, [True])
-
- sem.acquire().addCallback(self._incr)
- self.assertEqual(self.counter, N)
-
- sem.release()
- self.assertEqual(self.counter, N + 1)
-
- for i in range(1, 1 + N):
- sem.release()
- self.assertEqual(self.counter, N + 1)
-
-
- def test_semaphoreInvalidTokens(self):
- """
- If the token count passed to L{DeferredSemaphore} is less than one
- then L{ValueError} is raised.
- """
- self.assertRaises(ValueError, defer.DeferredSemaphore, 0)
- self.assertRaises(ValueError, defer.DeferredSemaphore, -1)
-
-
- def test_cancelSemaphoreAfterAcquired(self):
- """
- When canceling a L{Deferred} from a L{DeferredSemaphore} that
- already has the semaphore, the cancel should have no effect.
- """
- def _failOnErrback(_):
- self.fail("Unexpected errback call!")
-
- sem = defer.DeferredSemaphore(1)
- d = sem.acquire()
- d.addErrback(_failOnErrback)
- d.cancel()
-
-
- def test_cancelSemaphoreBeforeAcquired(self):
- """
- When canceling a L{Deferred} from a L{DeferredSemaphore} that does
- not yet have the semaphore (i.e., the L{Deferred} has not fired),
- the cancel should cause a L{defer.CancelledError} failure.
- """
- sem = defer.DeferredSemaphore(1)
- sem.acquire()
- d = sem.acquire()
- self.assertFailure(d, defer.CancelledError)
- d.cancel()
- return d
-
-
- def testQueue(self):
- N, M = 2, 2
- queue = defer.DeferredQueue(N, M)
-
- gotten = []
-
- for i in range(M):
- queue.get().addCallback(gotten.append)
- self.assertRaises(defer.QueueUnderflow, queue.get)
-
- for i in range(M):
- queue.put(i)
- self.assertEqual(gotten, range(i + 1))
- for i in range(N):
- queue.put(N + i)
- self.assertEqual(gotten, range(M))
- self.assertRaises(defer.QueueOverflow, queue.put, None)
-
- gotten = []
- for i in range(N):
- queue.get().addCallback(gotten.append)
- self.assertEqual(gotten, range(N, N + i + 1))
-
- queue = defer.DeferredQueue()
- gotten = []
- for i in range(N):
- queue.get().addCallback(gotten.append)
- for i in range(N):
- queue.put(i)
- self.assertEqual(gotten, range(N))
-
- queue = defer.DeferredQueue(size=0)
- self.assertRaises(defer.QueueOverflow, queue.put, None)
-
- queue = defer.DeferredQueue(backlog=0)
- self.assertRaises(defer.QueueUnderflow, queue.get)
-
-
- def test_cancelQueueAfterSynchronousGet(self):
- """
- When canceling a L{Deferred} from a L{DeferredQueue} that already has
- a result, the cancel should have no effect.
- """
- def _failOnErrback(_):
- self.fail("Unexpected errback call!")
-
- queue = defer.DeferredQueue()
- d = queue.get()
- d.addErrback(_failOnErrback)
- queue.put(None)
- d.cancel()
-
-
- def test_cancelQueueAfterGet(self):
- """
- When canceling a L{Deferred} from a L{DeferredQueue} that does not
- have a result (i.e., the L{Deferred} has not fired), the cancel
- causes a L{defer.CancelledError} failure. If the queue has a result
- later on, it doesn't try to fire the deferred.
- """
- queue = defer.DeferredQueue()
- d = queue.get()
- self.assertFailure(d, defer.CancelledError)
- d.cancel()
- def cb(ignore):
- # If the deferred is still linked with the deferred queue, it will
- # fail with an AlreadyCalledError
- queue.put(None)
- return queue.get().addCallback(self.assertIdentical, None)
- return d.addCallback(cb)
-
-
-
-class DeferredFilesystemLockTestCase(unittest.TestCase):
- """
- Test the behavior of L{DeferredFilesystemLock}
- """
- def setUp(self):
- self.clock = Clock()
- self.lock = defer.DeferredFilesystemLock(self.mktemp(),
- scheduler=self.clock)
-
-
- def test_waitUntilLockedWithNoLock(self):
- """
- Test that the lock can be acquired when no lock is held
- """
- d = self.lock.deferUntilLocked(timeout=1)
-
- return d
-
-
- def test_waitUntilLockedWithTimeoutLocked(self):
- """
- Test that the lock can not be acquired when the lock is held
- for longer than the timeout.
- """
- self.failUnless(self.lock.lock())
-
- d = self.lock.deferUntilLocked(timeout=5.5)
- self.assertFailure(d, defer.TimeoutError)
-
- self.clock.pump([1] * 10)
-
- return d
-
-
- def test_waitUntilLockedWithTimeoutUnlocked(self):
- """
- Test that a lock can be acquired while a lock is held
- but the lock is unlocked before our timeout.
- """
- def onTimeout(f):
- f.trap(defer.TimeoutError)
- self.fail("Should not have timed out")
-
- self.failUnless(self.lock.lock())
-
- self.clock.callLater(1, self.lock.unlock)
- d = self.lock.deferUntilLocked(timeout=10)
- d.addErrback(onTimeout)
-
- self.clock.pump([1] * 10)
-
- return d
-
-
- def test_defaultScheduler(self):
- """
- Test that the default scheduler is set up properly.
- """
- lock = defer.DeferredFilesystemLock(self.mktemp())
-
- self.assertEqual(lock._scheduler, reactor)
-
-
- def test_concurrentUsage(self):
- """
- Test that an appropriate exception is raised when attempting
- to use deferUntilLocked concurrently.
- """
- self.lock.lock()
- self.clock.callLater(1, self.lock.unlock)
-
- d = self.lock.deferUntilLocked()
- d2 = self.lock.deferUntilLocked()
-
- self.assertFailure(d2, defer.AlreadyTryingToLockError)
-
- self.clock.advance(1)
-
- return d
-
-
- def test_multipleUsages(self):
- """
- Test that a DeferredFilesystemLock can be used multiple times
- """
- def lockAquired(ign):
- self.lock.unlock()
- d = self.lock.deferUntilLocked()
- return d
-
- self.lock.lock()
- self.clock.callLater(1, self.lock.unlock)
-
- d = self.lock.deferUntilLocked()
- d.addCallback(lockAquired)
-
- self.clock.advance(1)
-
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defgen.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defgen.py
deleted file mode 100755
index 2d792ae9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_defgen.py
+++ /dev/null
@@ -1,314 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.defer.deferredGenerator} and related APIs.
-"""
-
-import sys
-
-from twisted.internet import reactor
-
-from twisted.trial import unittest
-
-from twisted.internet.defer import waitForDeferred, deferredGenerator, Deferred
-from twisted.internet import defer
-
-def getThing():
- d = Deferred()
- reactor.callLater(0, d.callback, "hi")
- return d
-
-def getOwie():
- d = Deferred()
- def CRAP():
- d.errback(ZeroDivisionError('OMG'))
- reactor.callLater(0, CRAP)
- return d
-
-# NOTE: most of the tests in DeferredGeneratorTests are duplicated
-# with slightly different syntax for the InlineCallbacksTests below.
-
-class TerminalException(Exception):
- pass
-
-class BaseDefgenTests:
- """
- This class sets up a bunch of test cases which will test both
- deferredGenerator and inlineCallbacks based generators. The subclasses
- DeferredGeneratorTests and InlineCallbacksTests each provide the actual
- generator implementations tested.
- """
-
- def testBasics(self):
- """
- Test that a normal deferredGenerator works. Tests yielding a
- deferred which callbacks, as well as a deferred errbacks. Also
- ensures returning a final value works.
- """
-
- return self._genBasics().addCallback(self.assertEqual, 'WOOSH')
-
- def testBuggy(self):
- """
- Ensure that a buggy generator properly signals a Failure
- condition on result deferred.
- """
- return self.assertFailure(self._genBuggy(), ZeroDivisionError)
-
- def testNothing(self):
- """Test that a generator which never yields results in None."""
-
- return self._genNothing().addCallback(self.assertEqual, None)
-
- def testHandledTerminalFailure(self):
- """
- Create a Deferred Generator which yields a Deferred which fails and
- handles the exception which results. Assert that the Deferred
- Generator does not errback its Deferred.
- """
- return self._genHandledTerminalFailure().addCallback(self.assertEqual, None)
-
- def testHandledTerminalAsyncFailure(self):
- """
- Just like testHandledTerminalFailure, only with a Deferred which fires
- asynchronously with an error.
- """
- d = defer.Deferred()
- deferredGeneratorResultDeferred = self._genHandledTerminalAsyncFailure(d)
- d.errback(TerminalException("Handled Terminal Failure"))
- return deferredGeneratorResultDeferred.addCallback(
- self.assertEqual, None)
-
- def testStackUsage(self):
- """
- Make sure we don't blow the stack when yielding immediately
- available deferreds.
- """
- return self._genStackUsage().addCallback(self.assertEqual, 0)
-
- def testStackUsage2(self):
- """
- Make sure we don't blow the stack when yielding immediately
- available values.
- """
- return self._genStackUsage2().addCallback(self.assertEqual, 0)
-
-
-
-
-class DeferredGeneratorTests(BaseDefgenTests, unittest.TestCase):
-
- # First provide all the generator impls necessary for BaseDefgenTests
- def _genBasics(self):
-
- x = waitForDeferred(getThing())
- yield x
- x = x.getResult()
-
- self.assertEqual(x, "hi")
-
- ow = waitForDeferred(getOwie())
- yield ow
- try:
- ow.getResult()
- except ZeroDivisionError, e:
- self.assertEqual(str(e), 'OMG')
- yield "WOOSH"
- return
- _genBasics = deferredGenerator(_genBasics)
-
- def _genBuggy(self):
- yield waitForDeferred(getThing())
- 1//0
- _genBuggy = deferredGenerator(_genBuggy)
-
-
- def _genNothing(self):
- if 0: yield 1
- _genNothing = deferredGenerator(_genNothing)
-
- def _genHandledTerminalFailure(self):
- x = waitForDeferred(defer.fail(TerminalException("Handled Terminal Failure")))
- yield x
- try:
- x.getResult()
- except TerminalException:
- pass
- _genHandledTerminalFailure = deferredGenerator(_genHandledTerminalFailure)
-
-
- def _genHandledTerminalAsyncFailure(self, d):
- x = waitForDeferred(d)
- yield x
- try:
- x.getResult()
- except TerminalException:
- pass
- _genHandledTerminalAsyncFailure = deferredGenerator(_genHandledTerminalAsyncFailure)
-
-
- def _genStackUsage(self):
- for x in range(5000):
- # Test with yielding a deferred
- x = waitForDeferred(defer.succeed(1))
- yield x
- x = x.getResult()
- yield 0
- _genStackUsage = deferredGenerator(_genStackUsage)
-
- def _genStackUsage2(self):
- for x in range(5000):
- # Test with yielding a random value
- yield 1
- yield 0
- _genStackUsage2 = deferredGenerator(_genStackUsage2)
-
- # Tests unique to deferredGenerator
-
- def testDeferredYielding(self):
- """
- Ensure that yielding a Deferred directly is trapped as an
- error.
- """
- # See the comment _deferGenerator about d.callback(Deferred).
- def _genDeferred():
- yield getThing()
- _genDeferred = deferredGenerator(_genDeferred)
-
- return self.assertFailure(_genDeferred(), TypeError)
-
-
-
-## This has to be in a string so the new yield syntax doesn't cause a
-## syntax error in Python 2.4 and before.
-inlineCallbacksTestsSource = '''
-from twisted.internet.defer import inlineCallbacks, returnValue
-
-class InlineCallbacksTests(BaseDefgenTests, unittest.TestCase):
- # First provide all the generator impls necessary for BaseDefgenTests
-
- def _genBasics(self):
-
- x = yield getThing()
-
- self.assertEqual(x, "hi")
-
- try:
- ow = yield getOwie()
- except ZeroDivisionError, e:
- self.assertEqual(str(e), 'OMG')
- returnValue("WOOSH")
- _genBasics = inlineCallbacks(_genBasics)
-
- def _genBuggy(self):
- yield getThing()
- 1/0
- _genBuggy = inlineCallbacks(_genBuggy)
-
-
- def _genNothing(self):
- if 0: yield 1
- _genNothing = inlineCallbacks(_genNothing)
-
-
- def _genHandledTerminalFailure(self):
- try:
- x = yield defer.fail(TerminalException("Handled Terminal Failure"))
- except TerminalException:
- pass
- _genHandledTerminalFailure = inlineCallbacks(_genHandledTerminalFailure)
-
-
- def _genHandledTerminalAsyncFailure(self, d):
- try:
- x = yield d
- except TerminalException:
- pass
- _genHandledTerminalAsyncFailure = inlineCallbacks(
- _genHandledTerminalAsyncFailure)
-
-
- def _genStackUsage(self):
- for x in range(5000):
- # Test with yielding a deferred
- x = yield defer.succeed(1)
- returnValue(0)
- _genStackUsage = inlineCallbacks(_genStackUsage)
-
- def _genStackUsage2(self):
- for x in range(5000):
- # Test with yielding a random value
- yield 1
- returnValue(0)
- _genStackUsage2 = inlineCallbacks(_genStackUsage2)
-
- # Tests unique to inlineCallbacks
-
- def testYieldNonDeferrred(self):
- """
- Ensure that yielding a non-deferred passes it back as the
- result of the yield expression.
- """
- def _test():
- x = yield 5
- returnValue(5)
- _test = inlineCallbacks(_test)
-
- return _test().addCallback(self.assertEqual, 5)
-
- def testReturnNoValue(self):
- """Ensure a standard python return results in a None result."""
- def _noReturn():
- yield 5
- return
- _noReturn = inlineCallbacks(_noReturn)
-
- return _noReturn().addCallback(self.assertEqual, None)
-
- def testReturnValue(self):
- """Ensure that returnValue works."""
- def _return():
- yield 5
- returnValue(6)
- _return = inlineCallbacks(_return)
-
- return _return().addCallback(self.assertEqual, 6)
-
-
- def test_nonGeneratorReturn(self):
- """
- Ensure that C{TypeError} with a message about L{inlineCallbacks} is
- raised when a non-generator returns something other than a generator.
- """
- def _noYield():
- return 5
- _noYield = inlineCallbacks(_noYield)
-
- self.assertIn("inlineCallbacks",
- str(self.assertRaises(TypeError, _noYield)))
-
-
- def test_nonGeneratorReturnValue(self):
- """
- Ensure that C{TypeError} with a message about L{inlineCallbacks} is
- raised when a non-generator calls L{returnValue}.
- """
- def _noYield():
- returnValue(5)
- _noYield = inlineCallbacks(_noYield)
-
- self.assertIn("inlineCallbacks",
- str(self.assertRaises(TypeError, _noYield)))
-
-'''
-
-if sys.version_info > (2, 5):
- # Load tests
- exec inlineCallbacksTestsSource
-else:
- # Make a placeholder test case
- class InlineCallbacksTests(unittest.TestCase):
- skip = "defer.defgen doesn't run on python < 2.5."
- def test_everything(self):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dict.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dict.py
deleted file mode 100755
index 3ebb67e2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dict.py
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.trial import unittest
-from twisted.protocols import dict
-
-paramString = "\"This is a dqstring \\w\\i\\t\\h boring stuff like: \\\"\" and t\\hes\\\"e are a\\to\\ms"
-goodparams = ["This is a dqstring with boring stuff like: \"", "and", "thes\"e", "are", "atoms"]
-
-class ParamTest(unittest.TestCase):
- def testParseParam(self):
- """Testing command response handling"""
- params = []
- rest = paramString
- while 1:
- (param, rest) = dict.parseParam(rest)
- if param == None:
- break
- params.append(param)
- self.assertEqual(params, goodparams)#, "DictClient.parseParam returns unexpected results")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_digestauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_digestauth.py
deleted file mode 100755
index 41368a02..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_digestauth.py
+++ /dev/null
@@ -1,671 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.cred._digest} and the associated bits in
-L{twisted.cred.credentials}.
-"""
-
-from zope.interface.verify import verifyObject
-from twisted.trial.unittest import TestCase
-from twisted.python.hashlib import md5, sha1
-from twisted.internet.address import IPv4Address
-from twisted.cred.error import LoginFailed
-from twisted.cred.credentials import calcHA1, calcHA2, IUsernameDigestHash
-from twisted.cred.credentials import calcResponse, DigestCredentialFactory
-
-def b64encode(s):
- return s.encode('base64').strip()
-
-
-class FakeDigestCredentialFactory(DigestCredentialFactory):
- """
- A Fake Digest Credential Factory that generates a predictable
- nonce and opaque
- """
- def __init__(self, *args, **kwargs):
- super(FakeDigestCredentialFactory, self).__init__(*args, **kwargs)
- self.privateKey = "0"
-
-
- def _generateNonce(self):
- """
- Generate a static nonce
- """
- return '178288758716122392881254770685'
-
-
- def _getTime(self):
- """
- Return a stable time
- """
- return 0
-
-
-
-class DigestAuthTests(TestCase):
- """
- L{TestCase} mixin class which defines a number of tests for
- L{DigestCredentialFactory}. Because this mixin defines C{setUp}, it
- must be inherited before L{TestCase}.
- """
- def setUp(self):
- """
- Create a DigestCredentialFactory for testing
- """
- self.username = "foobar"
- self.password = "bazquux"
- self.realm = "test realm"
- self.algorithm = "md5"
- self.cnonce = "29fc54aa1641c6fa0e151419361c8f23"
- self.qop = "auth"
- self.uri = "/write/"
- self.clientAddress = IPv4Address('TCP', '10.2.3.4', 43125)
- self.method = 'GET'
- self.credentialFactory = DigestCredentialFactory(
- self.algorithm, self.realm)
-
-
- def test_MD5HashA1(self, _algorithm='md5', _hash=md5):
- """
- L{calcHA1} accepts the C{'md5'} algorithm and returns an MD5 hash of
- its parameters, excluding the nonce and cnonce.
- """
- nonce = 'abc123xyz'
- hashA1 = calcHA1(_algorithm, self.username, self.realm, self.password,
- nonce, self.cnonce)
- a1 = '%s:%s:%s' % (self.username, self.realm, self.password)
- expected = _hash(a1).hexdigest()
- self.assertEqual(hashA1, expected)
-
-
- def test_MD5SessionHashA1(self):
- """
- L{calcHA1} accepts the C{'md5-sess'} algorithm and returns an MD5 hash
- of its parameters, including the nonce and cnonce.
- """
- nonce = 'xyz321abc'
- hashA1 = calcHA1('md5-sess', self.username, self.realm, self.password,
- nonce, self.cnonce)
- a1 = '%s:%s:%s' % (self.username, self.realm, self.password)
- ha1 = md5(a1).digest()
- a1 = '%s:%s:%s' % (ha1, nonce, self.cnonce)
- expected = md5(a1).hexdigest()
- self.assertEqual(hashA1, expected)
-
-
- def test_SHAHashA1(self):
- """
- L{calcHA1} accepts the C{'sha'} algorithm and returns a SHA hash of its
- parameters, excluding the nonce and cnonce.
- """
- self.test_MD5HashA1('sha', sha1)
-
-
- def test_MD5HashA2Auth(self, _algorithm='md5', _hash=md5):
- """
- L{calcHA2} accepts the C{'md5'} algorithm and returns an MD5 hash of
- its arguments, excluding the entity hash for QOP other than
- C{'auth-int'}.
- """
- method = 'GET'
- hashA2 = calcHA2(_algorithm, method, self.uri, 'auth', None)
- a2 = '%s:%s' % (method, self.uri)
- expected = _hash(a2).hexdigest()
- self.assertEqual(hashA2, expected)
-
-
- def test_MD5HashA2AuthInt(self, _algorithm='md5', _hash=md5):
- """
- L{calcHA2} accepts the C{'md5'} algorithm and returns an MD5 hash of
- its arguments, including the entity hash for QOP of C{'auth-int'}.
- """
- method = 'GET'
- hentity = 'foobarbaz'
- hashA2 = calcHA2(_algorithm, method, self.uri, 'auth-int', hentity)
- a2 = '%s:%s:%s' % (method, self.uri, hentity)
- expected = _hash(a2).hexdigest()
- self.assertEqual(hashA2, expected)
-
-
- def test_MD5SessHashA2Auth(self):
- """
- L{calcHA2} accepts the C{'md5-sess'} algorithm and QOP of C{'auth'} and
- returns the same value as it does for the C{'md5'} algorithm.
- """
- self.test_MD5HashA2Auth('md5-sess')
-
-
- def test_MD5SessHashA2AuthInt(self):
- """
- L{calcHA2} accepts the C{'md5-sess'} algorithm and QOP of C{'auth-int'}
- and returns the same value as it does for the C{'md5'} algorithm.
- """
- self.test_MD5HashA2AuthInt('md5-sess')
-
-
- def test_SHAHashA2Auth(self):
- """
- L{calcHA2} accepts the C{'sha'} algorithm and returns a SHA hash of
- its arguments, excluding the entity hash for QOP other than
- C{'auth-int'}.
- """
- self.test_MD5HashA2Auth('sha', sha1)
-
-
- def test_SHAHashA2AuthInt(self):
- """
- L{calcHA2} accepts the C{'sha'} algorithm and returns a SHA hash of
- its arguments, including the entity hash for QOP of C{'auth-int'}.
- """
- self.test_MD5HashA2AuthInt('sha', sha1)
-
-
- def test_MD5HashResponse(self, _algorithm='md5', _hash=md5):
- """
- L{calcResponse} accepts the C{'md5'} algorithm and returns an MD5 hash
- of its parameters, excluding the nonce count, client nonce, and QoP
- value if the nonce count and client nonce are C{None}
- """
- hashA1 = 'abc123'
- hashA2 = '789xyz'
- nonce = 'lmnopq'
-
- response = '%s:%s:%s' % (hashA1, nonce, hashA2)
- expected = _hash(response).hexdigest()
-
- digest = calcResponse(hashA1, hashA2, _algorithm, nonce, None, None,
- None)
- self.assertEqual(expected, digest)
-
-
- def test_MD5SessionHashResponse(self):
- """
- L{calcResponse} accepts the C{'md5-sess'} algorithm and returns an MD5
- hash of its parameters, excluding the nonce count, client nonce, and
- QoP value if the nonce count and client nonce are C{None}
- """
- self.test_MD5HashResponse('md5-sess')
-
-
- def test_SHAHashResponse(self):
- """
- L{calcResponse} accepts the C{'sha'} algorithm and returns a SHA hash
- of its parameters, excluding the nonce count, client nonce, and QoP
- value if the nonce count and client nonce are C{None}
- """
- self.test_MD5HashResponse('sha', sha1)
-
-
- def test_MD5HashResponseExtra(self, _algorithm='md5', _hash=md5):
- """
- L{calcResponse} accepts the C{'md5'} algorithm and returns an MD5 hash
- of its parameters, including the nonce count, client nonce, and QoP
- value if they are specified.
- """
- hashA1 = 'abc123'
- hashA2 = '789xyz'
- nonce = 'lmnopq'
- nonceCount = '00000004'
- clientNonce = 'abcxyz123'
- qop = 'auth'
-
- response = '%s:%s:%s:%s:%s:%s' % (
- hashA1, nonce, nonceCount, clientNonce, qop, hashA2)
- expected = _hash(response).hexdigest()
-
- digest = calcResponse(
- hashA1, hashA2, _algorithm, nonce, nonceCount, clientNonce, qop)
- self.assertEqual(expected, digest)
-
-
- def test_MD5SessionHashResponseExtra(self):
- """
- L{calcResponse} accepts the C{'md5-sess'} algorithm and returns an MD5
- hash of its parameters, including the nonce count, client nonce, and
- QoP value if they are specified.
- """
- self.test_MD5HashResponseExtra('md5-sess')
-
-
- def test_SHAHashResponseExtra(self):
- """
- L{calcResponse} accepts the C{'sha'} algorithm and returns a SHA hash
- of its parameters, including the nonce count, client nonce, and QoP
- value if they are specified.
- """
- self.test_MD5HashResponseExtra('sha', sha1)
-
-
- def formatResponse(self, quotes=True, **kw):
- """
- Format all given keyword arguments and their values suitably for use as
- the value of an HTTP header.
-
- @types quotes: C{bool}
- @param quotes: A flag indicating whether to quote the values of each
- field in the response.
-
- @param **kw: Keywords and C{str} values which will be treated as field
- name/value pairs to include in the result.
-
- @rtype: C{str}
- @return: The given fields formatted for use as an HTTP header value.
- """
- if 'username' not in kw:
- kw['username'] = self.username
- if 'realm' not in kw:
- kw['realm'] = self.realm
- if 'algorithm' not in kw:
- kw['algorithm'] = self.algorithm
- if 'qop' not in kw:
- kw['qop'] = self.qop
- if 'cnonce' not in kw:
- kw['cnonce'] = self.cnonce
- if 'uri' not in kw:
- kw['uri'] = self.uri
- if quotes:
- quote = '"'
- else:
- quote = ''
- return ', '.join([
- '%s=%s%s%s' % (k, quote, v, quote)
- for (k, v)
- in kw.iteritems()
- if v is not None])
-
-
- def getDigestResponse(self, challenge, ncount):
- """
- Calculate the response for the given challenge
- """
- nonce = challenge.get('nonce')
- algo = challenge.get('algorithm').lower()
- qop = challenge.get('qop')
-
- ha1 = calcHA1(
- algo, self.username, self.realm, self.password, nonce, self.cnonce)
- ha2 = calcHA2(algo, "GET", self.uri, qop, None)
- expected = calcResponse(ha1, ha2, algo, nonce, ncount, self.cnonce, qop)
- return expected
-
-
- def test_response(self, quotes=True):
- """
- L{DigestCredentialFactory.decode} accepts a digest challenge response
- and parses it into an L{IUsernameHashedPassword} provider.
- """
- challenge = self.credentialFactory.getChallenge(self.clientAddress.host)
-
- nc = "00000001"
- clientResponse = self.formatResponse(
- quotes=quotes,
- nonce=challenge['nonce'],
- response=self.getDigestResponse(challenge, nc),
- nc=nc,
- opaque=challenge['opaque'])
- creds = self.credentialFactory.decode(
- clientResponse, self.method, self.clientAddress.host)
- self.assertTrue(creds.checkPassword(self.password))
- self.assertFalse(creds.checkPassword(self.password + 'wrong'))
-
-
- def test_responseWithoutQuotes(self):
- """
- L{DigestCredentialFactory.decode} accepts a digest challenge response
- which does not quote the values of its fields and parses it into an
- L{IUsernameHashedPassword} provider in the same way it would a
- response which included quoted field values.
- """
- self.test_response(False)
-
-
- def test_caseInsensitiveAlgorithm(self):
- """
- The case of the algorithm value in the response is ignored when
- checking the credentials.
- """
- self.algorithm = 'MD5'
- self.test_response()
-
-
- def test_md5DefaultAlgorithm(self):
- """
- The algorithm defaults to MD5 if it is not supplied in the response.
- """
- self.algorithm = None
- self.test_response()
-
-
- def test_responseWithoutClientIP(self):
- """
- L{DigestCredentialFactory.decode} accepts a digest challenge response
- even if the client address it is passed is C{None}.
- """
- challenge = self.credentialFactory.getChallenge(None)
-
- nc = "00000001"
- clientResponse = self.formatResponse(
- nonce=challenge['nonce'],
- response=self.getDigestResponse(challenge, nc),
- nc=nc,
- opaque=challenge['opaque'])
- creds = self.credentialFactory.decode(clientResponse, self.method, None)
- self.assertTrue(creds.checkPassword(self.password))
- self.assertFalse(creds.checkPassword(self.password + 'wrong'))
-
-
- def test_multiResponse(self):
- """
- L{DigestCredentialFactory.decode} handles multiple responses to a
- single challenge.
- """
- challenge = self.credentialFactory.getChallenge(self.clientAddress.host)
-
- nc = "00000001"
- clientResponse = self.formatResponse(
- nonce=challenge['nonce'],
- response=self.getDigestResponse(challenge, nc),
- nc=nc,
- opaque=challenge['opaque'])
-
- creds = self.credentialFactory.decode(clientResponse, self.method,
- self.clientAddress.host)
- self.assertTrue(creds.checkPassword(self.password))
- self.assertFalse(creds.checkPassword(self.password + 'wrong'))
-
- nc = "00000002"
- clientResponse = self.formatResponse(
- nonce=challenge['nonce'],
- response=self.getDigestResponse(challenge, nc),
- nc=nc,
- opaque=challenge['opaque'])
-
- creds = self.credentialFactory.decode(clientResponse, self.method,
- self.clientAddress.host)
- self.assertTrue(creds.checkPassword(self.password))
- self.assertFalse(creds.checkPassword(self.password + 'wrong'))
-
-
- def test_failsWithDifferentMethod(self):
- """
- L{DigestCredentialFactory.decode} returns an L{IUsernameHashedPassword}
- provider which rejects a correct password for the given user if the
- challenge response request is made using a different HTTP method than
- was used to request the initial challenge.
- """
- challenge = self.credentialFactory.getChallenge(self.clientAddress.host)
-
- nc = "00000001"
- clientResponse = self.formatResponse(
- nonce=challenge['nonce'],
- response=self.getDigestResponse(challenge, nc),
- nc=nc,
- opaque=challenge['opaque'])
- creds = self.credentialFactory.decode(clientResponse, 'POST',
- self.clientAddress.host)
- self.assertFalse(creds.checkPassword(self.password))
- self.assertFalse(creds.checkPassword(self.password + 'wrong'))
-
-
- def test_noUsername(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
- has no username field or if the username field is empty.
- """
- # Check for no username
- e = self.assertRaises(
- LoginFailed,
- self.credentialFactory.decode,
- self.formatResponse(username=None),
- self.method, self.clientAddress.host)
- self.assertEqual(str(e), "Invalid response, no username given.")
-
- # Check for an empty username
- e = self.assertRaises(
- LoginFailed,
- self.credentialFactory.decode,
- self.formatResponse(username=""),
- self.method, self.clientAddress.host)
- self.assertEqual(str(e), "Invalid response, no username given.")
-
-
- def test_noNonce(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
- has no nonce.
- """
- e = self.assertRaises(
- LoginFailed,
- self.credentialFactory.decode,
- self.formatResponse(opaque="abc123"),
- self.method, self.clientAddress.host)
- self.assertEqual(str(e), "Invalid response, no nonce given.")
-
-
- def test_noOpaque(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
- has no opaque.
- """
- e = self.assertRaises(
- LoginFailed,
- self.credentialFactory.decode,
- self.formatResponse(),
- self.method, self.clientAddress.host)
- self.assertEqual(str(e), "Invalid response, no opaque given.")
-
-
- def test_checkHash(self):
- """
- L{DigestCredentialFactory.decode} returns an L{IUsernameDigestHash}
- provider which can verify a hash of the form 'username:realm:password'.
- """
- challenge = self.credentialFactory.getChallenge(self.clientAddress.host)
-
- nc = "00000001"
- clientResponse = self.formatResponse(
- nonce=challenge['nonce'],
- response=self.getDigestResponse(challenge, nc),
- nc=nc,
- opaque=challenge['opaque'])
-
- creds = self.credentialFactory.decode(clientResponse, self.method,
- self.clientAddress.host)
- self.assertTrue(verifyObject(IUsernameDigestHash, creds))
-
- cleartext = '%s:%s:%s' % (self.username, self.realm, self.password)
- hash = md5(cleartext)
- self.assertTrue(creds.checkHash(hash.hexdigest()))
- hash.update('wrong')
- self.assertFalse(creds.checkHash(hash.hexdigest()))
-
-
- def test_invalidOpaque(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
- value does not contain all the required parts.
- """
- credentialFactory = FakeDigestCredentialFactory(self.algorithm,
- self.realm)
- challenge = credentialFactory.getChallenge(self.clientAddress.host)
-
- exc = self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- 'badOpaque',
- challenge['nonce'],
- self.clientAddress.host)
- self.assertEqual(str(exc), 'Invalid response, invalid opaque value')
-
- badOpaque = 'foo-' + b64encode('nonce,clientip')
-
- exc = self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- badOpaque,
- challenge['nonce'],
- self.clientAddress.host)
- self.assertEqual(str(exc), 'Invalid response, invalid opaque value')
-
- exc = self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- '',
- challenge['nonce'],
- self.clientAddress.host)
- self.assertEqual(str(exc), 'Invalid response, invalid opaque value')
-
- badOpaque = (
- 'foo-' + b64encode('%s,%s,foobar' % (
- challenge['nonce'],
- self.clientAddress.host)))
- exc = self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- badOpaque,
- challenge['nonce'],
- self.clientAddress.host)
- self.assertEqual(
- str(exc), 'Invalid response, invalid opaque/time values')
-
-
- def test_incompatibleNonce(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} when the given
- nonce from the response does not match the nonce encoded in the opaque.
- """
- credentialFactory = FakeDigestCredentialFactory(self.algorithm, self.realm)
- challenge = credentialFactory.getChallenge(self.clientAddress.host)
-
- badNonceOpaque = credentialFactory._generateOpaque(
- '1234567890',
- self.clientAddress.host)
-
- exc = self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- badNonceOpaque,
- challenge['nonce'],
- self.clientAddress.host)
- self.assertEqual(
- str(exc),
- 'Invalid response, incompatible opaque/nonce values')
-
- exc = self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- badNonceOpaque,
- '',
- self.clientAddress.host)
- self.assertEqual(
- str(exc),
- 'Invalid response, incompatible opaque/nonce values')
-
-
- def test_incompatibleClientIP(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} when the
- request comes from a client IP other than what is encoded in the
- opaque.
- """
- credentialFactory = FakeDigestCredentialFactory(self.algorithm, self.realm)
- challenge = credentialFactory.getChallenge(self.clientAddress.host)
-
- badAddress = '10.0.0.1'
- # Sanity check
- self.assertNotEqual(self.clientAddress.host, badAddress)
-
- badNonceOpaque = credentialFactory._generateOpaque(
- challenge['nonce'], badAddress)
-
- self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- badNonceOpaque,
- challenge['nonce'],
- self.clientAddress.host)
-
-
- def test_oldNonce(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} when the given
- opaque is older than C{DigestCredentialFactory.CHALLENGE_LIFETIME_SECS}
- """
- credentialFactory = FakeDigestCredentialFactory(self.algorithm,
- self.realm)
- challenge = credentialFactory.getChallenge(self.clientAddress.host)
-
- key = '%s,%s,%s' % (challenge['nonce'],
- self.clientAddress.host,
- '-137876876')
- digest = md5(key + credentialFactory.privateKey).hexdigest()
- ekey = b64encode(key)
-
- oldNonceOpaque = '%s-%s' % (digest, ekey.strip('\n'))
-
- self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- oldNonceOpaque,
- challenge['nonce'],
- self.clientAddress.host)
-
-
- def test_mismatchedOpaqueChecksum(self):
- """
- L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
- checksum fails verification.
- """
- credentialFactory = FakeDigestCredentialFactory(self.algorithm,
- self.realm)
- challenge = credentialFactory.getChallenge(self.clientAddress.host)
-
- key = '%s,%s,%s' % (challenge['nonce'],
- self.clientAddress.host,
- '0')
-
- digest = md5(key + 'this is not the right pkey').hexdigest()
- badChecksum = '%s-%s' % (digest, b64encode(key))
-
- self.assertRaises(
- LoginFailed,
- credentialFactory._verifyOpaque,
- badChecksum,
- challenge['nonce'],
- self.clientAddress.host)
-
-
- def test_incompatibleCalcHA1Options(self):
- """
- L{calcHA1} raises L{TypeError} when any of the pszUsername, pszRealm,
- or pszPassword arguments are specified with the preHA1 keyword
- argument.
- """
- arguments = (
- ("user", "realm", "password", "preHA1"),
- (None, "realm", None, "preHA1"),
- (None, None, "password", "preHA1"),
- )
-
- for pszUsername, pszRealm, pszPassword, preHA1 in arguments:
- self.assertRaises(
- TypeError,
- calcHA1,
- "md5",
- pszUsername,
- pszRealm,
- pszPassword,
- "nonce",
- "cnonce",
- preHA1=preHA1)
-
-
- def test_noNewlineOpaque(self):
- """
- L{DigestCredentialFactory._generateOpaque} returns a value without
- newlines, regardless of the length of the nonce.
- """
- opaque = self.credentialFactory._generateOpaque(
- "long nonce " * 10, None)
- self.assertNotIn('\n', opaque)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dirdbm.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dirdbm.py
deleted file mode 100755
index 8bd240f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_dirdbm.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for dirdbm module.
-"""
-
-import os, shutil, glob
-
-from twisted.trial import unittest
-from twisted.persisted import dirdbm
-
-
-
-class DirDbmTestCase(unittest.TestCase):
-
- def setUp(self):
- self.path = self.mktemp()
- self.dbm = dirdbm.open(self.path)
- self.items = (('abc', 'foo'), ('/lalal', '\000\001'), ('\000\012', 'baz'))
-
-
- def testAll(self):
- k = "//==".decode("base64")
- self.dbm[k] = "a"
- self.dbm[k] = "a"
- self.assertEqual(self.dbm[k], "a")
-
-
- def testRebuildInteraction(self):
- from twisted.persisted import dirdbm
- from twisted.python import rebuild
-
- s = dirdbm.Shelf('dirdbm.rebuild.test')
- s['key'] = 'value'
- rebuild.rebuild(dirdbm)
- # print s['key']
-
-
- def testDbm(self):
- d = self.dbm
-
- # insert keys
- keys = []
- values = set()
- for k, v in self.items:
- d[k] = v
- keys.append(k)
- values.add(v)
- keys.sort()
-
- # check they exist
- for k, v in self.items:
- assert d.has_key(k), "has_key() failed"
- assert d[k] == v, "database has wrong value"
-
- # check non existent key
- try:
- d["XXX"]
- except KeyError:
- pass
- else:
- assert 0, "didn't raise KeyError on non-existent key"
-
- # check keys(), values() and items()
- dbkeys = list(d.keys())
- dbvalues = set(d.values())
- dbitems = set(d.items())
- dbkeys.sort()
- items = set(self.items)
- assert keys == dbkeys, ".keys() output didn't match: %s != %s" % (repr(keys), repr(dbkeys))
- assert values == dbvalues, ".values() output didn't match: %s != %s" % (repr(values), repr(dbvalues))
- assert items == dbitems, "items() didn't match: %s != %s" % (repr(items), repr(dbitems))
-
- copyPath = self.mktemp()
- d2 = d.copyTo(copyPath)
-
- copykeys = list(d.keys())
- copyvalues = set(d.values())
- copyitems = set(d.items())
- copykeys.sort()
-
- assert dbkeys == copykeys, ".copyTo().keys() didn't match: %s != %s" % (repr(dbkeys), repr(copykeys))
- assert dbvalues == copyvalues, ".copyTo().values() didn't match: %s != %s" % (repr(dbvalues), repr(copyvalues))
- assert dbitems == copyitems, ".copyTo().items() didn't match: %s != %s" % (repr(dbkeys), repr(copyitems))
-
- d2.clear()
- assert len(d2.keys()) == len(d2.values()) == len(d2.items()) == 0, ".clear() failed"
- shutil.rmtree(copyPath)
-
- # delete items
- for k, v in self.items:
- del d[k]
- assert not d.has_key(k), "has_key() even though we deleted it"
- assert len(d.keys()) == 0, "database has keys"
- assert len(d.values()) == 0, "database has values"
- assert len(d.items()) == 0, "database has items"
-
-
- def testModificationTime(self):
- import time
- # the mtime value for files comes from a different place than the
- # gettimeofday() system call. On linux, gettimeofday() can be
- # slightly ahead (due to clock drift which gettimeofday() takes into
- # account but which open()/write()/close() do not), and if we are
- # close to the edge of the next second, time.time() can give a value
- # which is larger than the mtime which results from a subsequent
- # write(). I consider this a kernel bug, but it is beyond the scope
- # of this test. Thus we keep the range of acceptability to 3 seconds time.
- # -warner
- self.dbm["k"] = "v"
- self.assert_(abs(time.time() - self.dbm.getModificationTime("k")) <= 3)
-
-
- def testRecovery(self):
- """DirDBM: test recovery from directory after a faked crash"""
- k = self.dbm._encode("key1")
- f = open(os.path.join(self.path, k + ".rpl"), "wb")
- f.write("value")
- f.close()
-
- k2 = self.dbm._encode("key2")
- f = open(os.path.join(self.path, k2), "wb")
- f.write("correct")
- f.close()
- f = open(os.path.join(self.path, k2 + ".rpl"), "wb")
- f.write("wrong")
- f.close()
-
- f = open(os.path.join(self.path, "aa.new"), "wb")
- f.write("deleted")
- f.close()
-
- dbm = dirdbm.DirDBM(self.path)
- assert dbm["key1"] == "value"
- assert dbm["key2"] == "correct"
- assert not glob.glob(os.path.join(self.path, "*.new"))
- assert not glob.glob(os.path.join(self.path, "*.rpl"))
-
-
- def test_nonStringKeys(self):
- """
- L{dirdbm.DirDBM} operations only support string keys: other types
- should raise a C{AssertionError}. This really ought to be a
- C{TypeError}, but it'll stay like this for backward compatibility.
- """
- self.assertRaises(AssertionError, self.dbm.__setitem__, 2, "3")
- try:
- self.assertRaises(AssertionError, self.dbm.__setitem__, "2", 3)
- except unittest.FailTest:
- # dirdbm.Shelf.__setitem__ supports non-string values
- self.assertIsInstance(self.dbm, dirdbm.Shelf)
- self.assertRaises(AssertionError, self.dbm.__getitem__, 2)
- self.assertRaises(AssertionError, self.dbm.__delitem__, 2)
- self.assertRaises(AssertionError, self.dbm.has_key, 2)
- self.assertRaises(AssertionError, self.dbm.__contains__, 2)
- self.assertRaises(AssertionError, self.dbm.getModificationTime, 2)
-
-
-
-class ShelfTestCase(DirDbmTestCase):
-
- def setUp(self):
- self.path = self.mktemp()
- self.dbm = dirdbm.Shelf(self.path)
- self.items = (('abc', 'foo'), ('/lalal', '\000\001'), ('\000\012', 'baz'),
- ('int', 12), ('float', 12.0), ('tuple', (None, 12)))
-
-
-testCases = [DirDbmTestCase, ShelfTestCase]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_doc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_doc.py
deleted file mode 100755
index 795fd872..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_doc.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import inspect, glob
-from os import path
-
-from twisted.trial import unittest
-from twisted.python import reflect
-from twisted.python.modules import getModule
-
-
-
-def errorInFile(f, line=17, name=''):
- """
- Return a filename formatted so emacs will recognize it as an error point
-
- @param line: Line number in file. Defaults to 17 because that's about how
- long the copyright headers are.
- """
- return '%s:%d:%s' % (f, line, name)
- # return 'File "%s", line %d, in %s' % (f, line, name)
-
-
-class DocCoverage(unittest.TestCase):
- """
- Looking for docstrings in all modules and packages.
- """
- def setUp(self):
- self.packageNames = []
- for mod in getModule('twisted').walkModules():
- if mod.isPackage():
- self.packageNames.append(mod.name)
-
-
- def testModules(self):
- """
- Looking for docstrings in all modules.
- """
- docless = []
- for packageName in self.packageNames:
- if packageName in ('twisted.test',):
- # because some stuff in here behaves oddly when imported
- continue
- try:
- package = reflect.namedModule(packageName)
- except ImportError, e:
- # This is testing doc coverage, not importability.
- # (Really, I don't want to deal with the fact that I don't
- # have pyserial installed.)
- # print e
- pass
- else:
- docless.extend(self.modulesInPackage(packageName, package))
- self.failIf(docless, "No docstrings in module files:\n"
- "%s" % ('\n'.join(map(errorInFile, docless)),))
-
-
- def modulesInPackage(self, packageName, package):
- docless = []
- directory = path.dirname(package.__file__)
- for modfile in glob.glob(path.join(directory, '*.py')):
- moduleName = inspect.getmodulename(modfile)
- if moduleName == '__init__':
- # These are tested by test_packages.
- continue
- elif moduleName in ('spelunk_gnome','gtkmanhole'):
- # argh special case pygtk evil argh. How does epydoc deal
- # with this?
- continue
- try:
- module = reflect.namedModule('.'.join([packageName,
- moduleName]))
- except Exception, e:
- # print moduleName, "misbehaved:", e
- pass
- else:
- if not inspect.getdoc(module):
- docless.append(modfile)
- return docless
-
-
- def testPackages(self):
- """
- Looking for docstrings in all packages.
- """
- docless = []
- for packageName in self.packageNames:
- try:
- package = reflect.namedModule(packageName)
- except Exception, e:
- # This is testing doc coverage, not importability.
- # (Really, I don't want to deal with the fact that I don't
- # have pyserial installed.)
- # print e
- pass
- else:
- if not inspect.getdoc(package):
- docless.append(package.__file__.replace('.pyc','.py'))
- self.failIf(docless, "No docstrings for package files\n"
- "%s" % ('\n'.join(map(errorInFile, docless),)))
-
-
- # This test takes a while and doesn't come close to passing. :(
- testModules.skip = "Activate me when you feel like writing docstrings, and fixing GTK crashing bugs."
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_epoll.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_epoll.py
deleted file mode 100755
index b96e06f4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_epoll.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for epoll wrapper.
-"""
-
-import socket, errno, time
-
-from twisted.trial import unittest
-from twisted.python.util import untilConcludes
-
-try:
- from twisted.python import _epoll
-except ImportError:
- _epoll = None
-
-
-class EPoll(unittest.TestCase):
- """
- Tests for the low-level epoll bindings.
- """
- def setUp(self):
- """
- Create a listening server port and a list with which to keep track
- of created sockets.
- """
- self.serverSocket = socket.socket()
- self.serverSocket.bind(('127.0.0.1', 0))
- self.serverSocket.listen(1)
- self.connections = [self.serverSocket]
-
-
- def tearDown(self):
- """
- Close any sockets which were opened by the test.
- """
- for skt in self.connections:
- skt.close()
-
-
- def _connectedPair(self):
- """
- Return the two sockets which make up a new TCP connection.
- """
- client = socket.socket()
- client.setblocking(False)
- try:
- client.connect(('127.0.0.1', self.serverSocket.getsockname()[1]))
- except socket.error, e:
- self.assertEqual(e.args[0], errno.EINPROGRESS)
- else:
- raise unittest.FailTest("Connect should have raised EINPROGRESS")
- server, addr = self.serverSocket.accept()
-
- self.connections.extend((client, server))
- return client, server
-
-
- def test_create(self):
- """
- Test the creation of an epoll object.
- """
- try:
- p = _epoll.epoll(16)
- except OSError, e:
- raise unittest.FailTest(str(e))
- else:
- p.close()
-
-
- def test_badCreate(self):
- """
- Test that attempting to create an epoll object with some random
- objects raises a TypeError.
- """
- self.assertRaises(TypeError, _epoll.epoll, 1, 2, 3)
- self.assertRaises(TypeError, _epoll.epoll, 'foo')
- self.assertRaises(TypeError, _epoll.epoll, None)
- self.assertRaises(TypeError, _epoll.epoll, ())
- self.assertRaises(TypeError, _epoll.epoll, ['foo'])
- self.assertRaises(TypeError, _epoll.epoll, {})
-
-
- def test_add(self):
- """
- Test adding a socket to an epoll object.
- """
- server, client = self._connectedPair()
-
- p = _epoll.epoll(2)
- try:
- p._control(_epoll.CTL_ADD, server.fileno(), _epoll.IN | _epoll.OUT)
- p._control(_epoll.CTL_ADD, client.fileno(), _epoll.IN | _epoll.OUT)
- finally:
- p.close()
-
-
- def test_controlAndWait(self):
- """
- Test waiting on an epoll object which has had some sockets added to
- it.
- """
- client, server = self._connectedPair()
-
- p = _epoll.epoll(16)
- p._control(_epoll.CTL_ADD, client.fileno(), _epoll.IN | _epoll.OUT |
- _epoll.ET)
- p._control(_epoll.CTL_ADD, server.fileno(), _epoll.IN | _epoll.OUT |
- _epoll.ET)
-
- now = time.time()
- events = untilConcludes(p.wait, 4, 1000)
- then = time.time()
- self.failIf(then - now > 0.01)
-
- events.sort()
- expected = [(client.fileno(), _epoll.OUT),
- (server.fileno(), _epoll.OUT)]
- expected.sort()
-
- self.assertEqual(events, expected)
-
- now = time.time()
- events = untilConcludes(p.wait, 4, 200)
- then = time.time()
- self.failUnless(then - now > 0.1)
- self.failIf(events)
-
- client.send("Hello!")
- server.send("world!!!")
-
- now = time.time()
- events = untilConcludes(p.wait, 4, 1000)
- then = time.time()
- self.failIf(then - now > 0.01)
-
- events.sort()
- expected = [(client.fileno(), _epoll.IN | _epoll.OUT),
- (server.fileno(), _epoll.IN | _epoll.OUT)]
- expected.sort()
-
- self.assertEqual(events, expected)
-
-if _epoll is None:
- EPoll.skip = "_epoll module unavailable"
-else:
- try:
- e = _epoll.epoll(16)
- except IOError, exc:
- if exc.errno == errno.ENOSYS:
- del exc
- EPoll.skip = "epoll support missing from platform"
- else:
- raise
- else:
- e.close()
- del e
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_error.py
deleted file mode 100755
index 3dbbe894..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_error.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.trial import unittest
-from twisted.internet import error
-import socket
-
-class TestStringification(unittest.TestCase):
- """Test that the exceptions have useful stringifications.
- """
-
- listOfTests = [
- #(output, exception[, args[, kwargs]]),
-
- ("An error occurred binding to an interface.",
- error.BindError),
-
- ("An error occurred binding to an interface: foo.",
- error.BindError, ['foo']),
-
- ("An error occurred binding to an interface: foo bar.",
- error.BindError, ['foo', 'bar']),
-
- ("Couldn't listen on eth0:4242: Foo.",
- error.CannotListenError,
- ('eth0', 4242, socket.error('Foo'))),
-
- ("Message is too long to send.",
- error.MessageLengthError),
-
- ("Message is too long to send: foo bar.",
- error.MessageLengthError, ['foo', 'bar']),
-
- ("DNS lookup failed.",
- error.DNSLookupError),
-
- ("DNS lookup failed: foo bar.",
- error.DNSLookupError, ['foo', 'bar']),
-
- ("An error occurred while connecting.",
- error.ConnectError),
-
- ("An error occurred while connecting: someOsError.",
- error.ConnectError, ['someOsError']),
-
- ("An error occurred while connecting: foo.",
- error.ConnectError, [], {'string': 'foo'}),
-
- ("An error occurred while connecting: someOsError: foo.",
- error.ConnectError, ['someOsError', 'foo']),
-
- ("Couldn't bind.",
- error.ConnectBindError),
-
- ("Couldn't bind: someOsError.",
- error.ConnectBindError, ['someOsError']),
-
- ("Couldn't bind: someOsError: foo.",
- error.ConnectBindError, ['someOsError', 'foo']),
-
- ("Hostname couldn't be looked up.",
- error.UnknownHostError),
-
- ("No route to host.",
- error.NoRouteError),
-
- ("Connection was refused by other side.",
- error.ConnectionRefusedError),
-
- ("TCP connection timed out.",
- error.TCPTimedOutError),
-
- ("File used for UNIX socket is no good.",
- error.BadFileError),
-
- ("Service name given as port is unknown.",
- error.ServiceNameUnknownError),
-
- ("User aborted connection.",
- error.UserError),
-
- ("User timeout caused connection failure.",
- error.TimeoutError),
-
- ("An SSL error occurred.",
- error.SSLError),
-
- ("Connection to the other side was lost in a non-clean fashion.",
- error.ConnectionLost),
-
- ("Connection to the other side was lost in a non-clean fashion: foo bar.",
- error.ConnectionLost, ['foo', 'bar']),
-
- ("Connection was closed cleanly.",
- error.ConnectionDone),
-
- ("Connection was closed cleanly: foo bar.",
- error.ConnectionDone, ['foo', 'bar']),
-
- ("Uh.", #TODO nice docstring, you've got there.
- error.ConnectionFdescWentAway),
-
- ("Tried to cancel an already-called event.",
- error.AlreadyCalled),
-
- ("Tried to cancel an already-called event: foo bar.",
- error.AlreadyCalled, ['foo', 'bar']),
-
- ("Tried to cancel an already-cancelled event.",
- error.AlreadyCancelled),
-
- ("A process has ended without apparent errors: process finished with exit code 0.",
- error.ProcessDone,
- [None]),
-
- ("A process has ended with a probable error condition: process ended.",
- error.ProcessTerminated),
-
- ("A process has ended with a probable error condition: process ended with exit code 42.",
- error.ProcessTerminated,
- [],
- {'exitCode': 42}),
-
- ("A process has ended with a probable error condition: process ended by signal SIGBUS.",
- error.ProcessTerminated,
- [],
- {'signal': 'SIGBUS'}),
-
- ("The Connector was not connecting when it was asked to stop connecting.",
- error.NotConnectingError),
-
- ("The Port was not listening when it was asked to stop listening.",
- error.NotListeningError),
-
- ]
-
- def testThemAll(self):
- for entry in self.listOfTests:
- output = entry[0]
- exception = entry[1]
- try:
- args = entry[2]
- except IndexError:
- args = ()
- try:
- kwargs = entry[3]
- except IndexError:
- kwargs = {}
-
- self.assertEqual(
- str(exception(*args, **kwargs)),
- output)
-
-
- def test_connectionLostSubclassOfConnectionClosed(self):
- """
- L{error.ConnectionClosed} is a superclass of L{error.ConnectionLost}.
- """
- self.assertTrue(issubclass(error.ConnectionLost,
- error.ConnectionClosed))
-
-
- def test_connectionDoneSubclassOfConnectionClosed(self):
- """
- L{error.ConnectionClosed} is a superclass of L{error.ConnectionDone}.
- """
- self.assertTrue(issubclass(error.ConnectionDone,
- error.ConnectionClosed))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_explorer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_explorer.py
deleted file mode 100755
index 2b8fcf08..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_explorer.py
+++ /dev/null
@@ -1,236 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test cases for explorer
-"""
-
-from twisted.trial import unittest
-
-from twisted.manhole import explorer
-
-import types
-
-"""
-# Tests:
-
- Get an ObjectLink. Browse ObjectLink.identifier. Is it the same?
-
- Watch Object. Make sure an ObjectLink is received when:
- Call a method.
- Set an attribute.
-
- Have an Object with a setattr class. Watch it.
- Do both the navite setattr and the watcher get called?
-
- Sequences with circular references. Does it blow up?
-"""
-
-class SomeDohickey:
- def __init__(self, *a):
- self.__dict__['args'] = a
-
- def bip(self):
- return self.args
-
-
-class TestBrowser(unittest.TestCase):
- def setUp(self):
- self.pool = explorer.explorerPool
- self.pool.clear()
- self.testThing = ["How many stairs must a man climb down?",
- SomeDohickey(42)]
-
- def test_chain(self):
- "Following a chain of Explorers."
- xplorer = self.pool.getExplorer(self.testThing, 'testThing')
- self.assertEqual(xplorer.id, id(self.testThing))
- self.assertEqual(xplorer.identifier, 'testThing')
-
- dxplorer = xplorer.get_elements()[1]
- self.assertEqual(dxplorer.id, id(self.testThing[1]))
-
-class Watcher:
- zero = 0
- def __init__(self):
- self.links = []
-
- def receiveBrowserObject(self, olink):
- self.links.append(olink)
-
- def setZero(self):
- self.zero = len(self.links)
-
- def len(self):
- return len(self.links) - self.zero
-
-
-class SetattrDohickey:
- def __setattr__(self, k, v):
- v = list(str(v))
- v.reverse()
- self.__dict__[k] = ''.join(v)
-
-class MiddleMan(SomeDohickey, SetattrDohickey):
- pass
-
-# class TestWatch(unittest.TestCase):
-class FIXME_Watch:
- def setUp(self):
- self.globalNS = globals().copy()
- self.localNS = {}
- self.browser = explorer.ObjectBrowser(self.globalNS, self.localNS)
- self.watcher = Watcher()
-
- def test_setAttrPlain(self):
- "Triggering a watcher response by setting an attribute."
-
- testThing = SomeDohickey('pencil')
- self.browser.watchObject(testThing, 'testThing',
- self.watcher.receiveBrowserObject)
- self.watcher.setZero()
-
- testThing.someAttr = 'someValue'
-
- self.assertEqual(testThing.someAttr, 'someValue')
- self.failUnless(self.watcher.len())
- olink = self.watcher.links[-1]
- self.assertEqual(olink.id, id(testThing))
-
- def test_setAttrChain(self):
- "Setting an attribute on a watched object that has __setattr__"
- testThing = MiddleMan('pencil')
-
- self.browser.watchObject(testThing, 'testThing',
- self.watcher.receiveBrowserObject)
- self.watcher.setZero()
-
- testThing.someAttr = 'ZORT'
-
- self.assertEqual(testThing.someAttr, 'TROZ')
- self.failUnless(self.watcher.len())
- olink = self.watcher.links[-1]
- self.assertEqual(olink.id, id(testThing))
-
-
- def test_method(self):
- "Triggering a watcher response by invoking a method."
-
- for testThing in (SomeDohickey('pencil'), MiddleMan('pencil')):
- self.browser.watchObject(testThing, 'testThing',
- self.watcher.receiveBrowserObject)
- self.watcher.setZero()
-
- rval = testThing.bip()
- self.assertEqual(rval, ('pencil',))
-
- self.failUnless(self.watcher.len())
- olink = self.watcher.links[-1]
- self.assertEqual(olink.id, id(testThing))
-
-
-def function_noArgs():
- "A function which accepts no arguments at all."
- return
-
-def function_simple(a, b, c):
- "A function which accepts several arguments."
- return a, b, c
-
-def function_variable(*a, **kw):
- "A function which accepts a variable number of args and keywords."
- return a, kw
-
-def function_crazy((alpha, beta), c, d=range(4), **kw):
- "A function with a mad crazy signature."
- return alpha, beta, c, d, kw
-
-class TestBrowseFunction(unittest.TestCase):
-
- def setUp(self):
- self.pool = explorer.explorerPool
- self.pool.clear()
-
- def test_sanity(self):
- """Basic checks for browse_function.
-
- Was the proper type returned? Does it have the right name and ID?
- """
- for f_name in ('function_noArgs', 'function_simple',
- 'function_variable', 'function_crazy'):
- f = eval(f_name)
-
- xplorer = self.pool.getExplorer(f, f_name)
-
- self.assertEqual(xplorer.id, id(f))
-
- self.failUnless(isinstance(xplorer, explorer.ExplorerFunction))
-
- self.assertEqual(xplorer.name, f_name)
-
- def test_signature_noArgs(self):
- """Testing zero-argument function signature.
- """
-
- xplorer = self.pool.getExplorer(function_noArgs, 'function_noArgs')
-
- self.assertEqual(len(xplorer.signature), 0)
-
- def test_signature_simple(self):
- """Testing simple function signature.
- """
-
- xplorer = self.pool.getExplorer(function_simple, 'function_simple')
-
- expected_signature = ('a','b','c')
-
- self.assertEqual(xplorer.signature.name, expected_signature)
-
- def test_signature_variable(self):
- """Testing variable-argument function signature.
- """
-
- xplorer = self.pool.getExplorer(function_variable,
- 'function_variable')
-
- expected_names = ('a','kw')
- signature = xplorer.signature
-
- self.assertEqual(signature.name, expected_names)
- self.failUnless(signature.is_varlist(0))
- self.failUnless(signature.is_keyword(1))
-
- def test_signature_crazy(self):
- """Testing function with crazy signature.
- """
- xplorer = self.pool.getExplorer(function_crazy, 'function_crazy')
-
- signature = xplorer.signature
-
- expected_signature = [{'name': 'c'},
- {'name': 'd',
- 'default': range(4)},
- {'name': 'kw',
- 'keywords': 1}]
-
- # The name of the first argument seems to be indecipherable,
- # but make sure it has one (and no default).
- self.failUnless(signature.get_name(0))
- self.failUnless(not signature.get_default(0)[0])
-
- self.assertEqual(signature.get_name(1), 'c')
-
- # Get a list of values from a list of ExplorerImmutables.
- arg_2_default = map(lambda l: l.value,
- signature.get_default(2)[1].get_elements())
-
- self.assertEqual(signature.get_name(2), 'd')
- self.assertEqual(arg_2_default, range(4))
-
- self.assertEqual(signature.get_name(3), 'kw')
- self.failUnless(signature.is_keyword(3))
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_factories.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_factories.py
deleted file mode 100755
index 8ffb4da5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_factories.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test code for basic Factory classes.
-"""
-
-import pickle
-
-from twisted.trial.unittest import TestCase
-
-from twisted.internet import reactor, defer
-from twisted.internet.task import Clock
-from twisted.internet.protocol import Factory, ReconnectingClientFactory
-from twisted.protocols.basic import Int16StringReceiver
-
-
-
-class In(Int16StringReceiver):
- def __init__(self):
- self.msgs = {}
-
- def connectionMade(self):
- self.factory.connections += 1
-
- def stringReceived(self, msg):
- n, msg = pickle.loads(msg)
- self.msgs[n] = msg
- self.sendString(pickle.dumps(n))
-
- def connectionLost(self, reason):
- self.factory.allMessages.append(self.msgs)
- if len(self.factory.allMessages) >= self.factory.goal:
- self.factory.d.callback(None)
-
-
-
-class Out(Int16StringReceiver):
- msgs = dict([(x, 'X' * x) for x in range(10)])
-
- def __init__(self):
- self.msgs = Out.msgs.copy()
-
- def connectionMade(self):
- for i in self.msgs.keys():
- self.sendString(pickle.dumps( (i, self.msgs[i])))
-
- def stringReceived(self, msg):
- n = pickle.loads(msg)
- del self.msgs[n]
- if not self.msgs:
- self.transport.loseConnection()
- self.factory.howManyTimes -= 1
- if self.factory.howManyTimes <= 0:
- self.factory.stopTrying()
-
-
-
-class FakeConnector(object):
- """
- A fake connector class, to be used to mock connections failed or lost.
- """
-
- def stopConnecting(self):
- pass
-
-
- def connect(self):
- pass
-
-
-
-class ReconnectingFactoryTestCase(TestCase):
- """
- Tests for L{ReconnectingClientFactory}.
- """
-
- def testStopTrying(self):
- f = Factory()
- f.protocol = In
- f.connections = 0
- f.allMessages = []
- f.goal = 2
- f.d = defer.Deferred()
-
- c = ReconnectingClientFactory()
- c.initialDelay = c.delay = 0.2
- c.protocol = Out
- c.howManyTimes = 2
-
- port = reactor.listenTCP(0, f)
- self.addCleanup(port.stopListening)
- PORT = port.getHost().port
- reactor.connectTCP('127.0.0.1', PORT, c)
-
- f.d.addCallback(self._testStopTrying_1, f, c)
- return f.d
- testStopTrying.timeout = 10
-
-
- def _testStopTrying_1(self, res, f, c):
- self.assertEqual(len(f.allMessages), 2,
- "not enough messages -- %s" % f.allMessages)
- self.assertEqual(f.connections, 2,
- "Number of successful connections incorrect %d" %
- f.connections)
- self.assertEqual(f.allMessages, [Out.msgs] * 2)
- self.failIf(c.continueTrying, "stopTrying never called or ineffective")
-
-
- def test_stopTryingDoesNotReconnect(self):
- """
- Calling stopTrying on a L{ReconnectingClientFactory} doesn't attempt a
- retry on any active connector.
- """
- class FactoryAwareFakeConnector(FakeConnector):
- attemptedRetry = False
-
- def stopConnecting(self):
- """
- Behave as though an ongoing connection attempt has now
- failed, and notify the factory of this.
- """
- f.clientConnectionFailed(self, None)
-
- def connect(self):
- """
- Record an attempt to reconnect, since this is what we
- are trying to avoid.
- """
- self.attemptedRetry = True
-
- f = ReconnectingClientFactory()
- f.clock = Clock()
-
- # simulate an active connection - stopConnecting on this connector should
- # be triggered when we call stopTrying
- f.connector = FactoryAwareFakeConnector()
- f.stopTrying()
-
- # make sure we never attempted to retry
- self.assertFalse(f.connector.attemptedRetry)
- self.assertFalse(f.clock.getDelayedCalls())
-
-
- def test_serializeUnused(self):
- """
- A L{ReconnectingClientFactory} which hasn't been used for anything
- can be pickled and unpickled and end up with the same state.
- """
- original = ReconnectingClientFactory()
- reconstituted = pickle.loads(pickle.dumps(original))
- self.assertEqual(original.__dict__, reconstituted.__dict__)
-
-
- def test_serializeWithClock(self):
- """
- The clock attribute of L{ReconnectingClientFactory} is not serialized,
- and the restored value sets it to the default value, the reactor.
- """
- clock = Clock()
- original = ReconnectingClientFactory()
- original.clock = clock
- reconstituted = pickle.loads(pickle.dumps(original))
- self.assertIdentical(reconstituted.clock, None)
-
-
- def test_deserializationResetsParameters(self):
- """
- A L{ReconnectingClientFactory} which is unpickled does not have an
- L{IConnector} and has its reconnecting timing parameters reset to their
- initial values.
- """
- factory = ReconnectingClientFactory()
- factory.clientConnectionFailed(FakeConnector(), None)
- self.addCleanup(factory.stopTrying)
-
- serialized = pickle.dumps(factory)
- unserialized = pickle.loads(serialized)
- self.assertEqual(unserialized.connector, None)
- self.assertEqual(unserialized._callID, None)
- self.assertEqual(unserialized.retries, 0)
- self.assertEqual(unserialized.delay, factory.initialDelay)
- self.assertEqual(unserialized.continueTrying, True)
-
-
- def test_parametrizedClock(self):
- """
- The clock used by L{ReconnectingClientFactory} can be parametrized, so
- that one can cleanly test reconnections.
- """
- clock = Clock()
- factory = ReconnectingClientFactory()
- factory.clock = clock
-
- factory.clientConnectionLost(FakeConnector(), None)
- self.assertEqual(len(clock.calls), 1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_failure.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_failure.py
deleted file mode 100755
index 3963f8c1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_failure.py
+++ /dev/null
@@ -1,595 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for failure module.
-"""
-from __future__ import division
-
-import re
-import sys
-import StringIO
-import traceback
-import pdb
-
-from twisted.trial import unittest, util
-
-from twisted.python import failure
-
-try:
- from twisted.test import raiser
-except ImportError:
- raiser = None
-
-
-def getDivisionFailure(*args, **kwargs):
- """
- Make a C{Failure} of a divide-by-zero error.
-
- @param args: Any C{*args} are passed to Failure's constructor.
- @param kwargs: Any C{**kwargs} are passed to Failure's constructor.
- """
- try:
- 1/0
- except:
- f = failure.Failure(*args, **kwargs)
- return f
-
-
-class FailureTestCase(unittest.TestCase):
-
- def testFailAndTrap(self):
- """Trapping a failure."""
- try:
- raise NotImplementedError('test')
- except:
- f = failure.Failure()
- error = f.trap(SystemExit, RuntimeError)
- self.assertEqual(error, RuntimeError)
- self.assertEqual(f.type, NotImplementedError)
-
-
- def test_notTrapped(self):
- """Making sure trap doesn't trap what it shouldn't."""
- try:
- raise ValueError()
- except:
- f = failure.Failure()
- self.assertRaises(failure.Failure, f.trap, OverflowError)
-
-
- def assertStartsWith(self, s, prefix):
- """
- Assert that s starts with a particular prefix.
- """
- self.assertTrue(s.startswith(prefix),
- '%r is not the start of %r' % (prefix, s))
-
-
- def test_printingSmokeTest(self):
- """
- None of the print* methods fail when called.
- """
- f = getDivisionFailure()
- out = StringIO.StringIO()
- f.printDetailedTraceback(out)
- self.assertStartsWith(out.getvalue(), '*--- Failure')
- out = StringIO.StringIO()
- f.printBriefTraceback(out)
- self.assertStartsWith(out.getvalue(), 'Traceback')
- out = StringIO.StringIO()
- f.printTraceback(out)
- self.assertStartsWith(out.getvalue(), 'Traceback')
-
-
- def test_printingCapturedVarsSmokeTest(self):
- """
- None of the print* methods fail when called on a L{Failure} constructed
- with C{captureVars=True}.
-
- Local variables on the stack can be seen in the detailed traceback.
- """
- exampleLocalVar = 'xyzzy'
- f = getDivisionFailure(captureVars=True)
- out = StringIO.StringIO()
- f.printDetailedTraceback(out)
- self.assertStartsWith(out.getvalue(), '*--- Failure')
- self.assertNotEqual(None, re.search('exampleLocalVar.*xyzzy',
- out.getvalue()))
- out = StringIO.StringIO()
- f.printBriefTraceback(out)
- self.assertStartsWith(out.getvalue(), 'Traceback')
- out = StringIO.StringIO()
- f.printTraceback(out)
- self.assertStartsWith(out.getvalue(), 'Traceback')
-
-
- def test_printingCapturedVarsCleanedSmokeTest(self):
- """
- C{printDetailedTraceback} includes information about local variables on
- the stack after C{cleanFailure} has been called.
- """
- exampleLocalVar = 'xyzzy'
- f = getDivisionFailure(captureVars=True)
- f.cleanFailure()
- out = StringIO.StringIO()
- f.printDetailedTraceback(out)
- self.assertNotEqual(None, re.search('exampleLocalVar.*xyzzy',
- out.getvalue()))
-
-
- def test_printingNoVars(self):
- """
- Calling C{Failure()} with no arguments does not capture any locals or
- globals, so L{printDetailedTraceback} cannot show them in its output.
- """
- out = StringIO.StringIO()
- f = getDivisionFailure()
- f.printDetailedTraceback(out)
- # There should be no variables in the detailed output. Variables are
- # printed on lines with 2 leading spaces.
- linesWithVars = [line for line in out.getvalue().splitlines()
- if line.startswith(' ')]
- self.assertEqual([], linesWithVars)
- self.assertSubstring(
- 'Capture of Locals and Globals disabled', out.getvalue())
-
-
- def test_printingCaptureVars(self):
- """
- Calling C{Failure(captureVars=True)} captures the locals and globals
- for its stack frames, so L{printDetailedTraceback} will show them in
- its output.
- """
- out = StringIO.StringIO()
- f = getDivisionFailure(captureVars=True)
- f.printDetailedTraceback(out)
- # Variables are printed on lines with 2 leading spaces.
- linesWithVars = [line for line in out.getvalue().splitlines()
- if line.startswith(' ')]
- self.assertNotEqual([], linesWithVars)
-
-
- def testExplictPass(self):
- e = RuntimeError()
- f = failure.Failure(e)
- f.trap(RuntimeError)
- self.assertEqual(f.value, e)
-
-
- def _getInnermostFrameLine(self, f):
- try:
- f.raiseException()
- except ZeroDivisionError:
- tb = traceback.extract_tb(sys.exc_info()[2])
- return tb[-1][-1]
- else:
- raise Exception(
- "f.raiseException() didn't raise ZeroDivisionError!?")
-
-
- def testRaiseExceptionWithTB(self):
- f = getDivisionFailure()
- innerline = self._getInnermostFrameLine(f)
- self.assertEqual(innerline, '1/0')
-
-
- def testLackOfTB(self):
- f = getDivisionFailure()
- f.cleanFailure()
- innerline = self._getInnermostFrameLine(f)
- self.assertEqual(innerline, '1/0')
-
- testLackOfTB.todo = "the traceback is not preserved, exarkun said he'll try to fix this! god knows how"
-
-
- _stringException = "bugger off"
- def _getStringFailure(self):
- try:
- raise self._stringException
- except:
- f = failure.Failure()
- return f
-
-
- def test_raiseStringExceptions(self):
- # String exceptions used to totally bugged f.raiseException
- f = self._getStringFailure()
- try:
- f.raiseException()
- except:
- self.assertEqual(sys.exc_info()[0], self._stringException)
- else:
- raise AssertionError("Should have raised")
- test_raiseStringExceptions.suppress = [
- util.suppress(message='raising a string exception is deprecated')]
-
-
- def test_printStringExceptions(self):
- """
- L{Failure.printTraceback} should write out stack and exception
- information, even for string exceptions.
- """
- failure = self._getStringFailure()
- output = StringIO.StringIO()
- failure.printTraceback(file=output)
- lines = output.getvalue().splitlines()
- # The last line should be the value of the raised string
- self.assertEqual(lines[-1], self._stringException)
-
- test_printStringExceptions.suppress = [
- util.suppress(message='raising a string exception is deprecated')]
-
- if sys.version_info[:2] >= (2, 6):
- skipMsg = ("String exceptions aren't supported anymore starting "
- "Python 2.6")
- test_raiseStringExceptions.skip = skipMsg
- test_printStringExceptions.skip = skipMsg
-
-
- def testConstructionFails(self):
- """
- Creating a Failure with no arguments causes it to try to discover the
- current interpreter exception state. If no such state exists, creating
- the Failure should raise a synchronous exception.
- """
- self.assertRaises(failure.NoCurrentExceptionError, failure.Failure)
-
-
- def test_getTracebackObject(self):
- """
- If the C{Failure} has not been cleaned, then C{getTracebackObject}
- returns the traceback object that captured in its constructor.
- """
- f = getDivisionFailure()
- self.assertEqual(f.getTracebackObject(), f.tb)
-
-
- def test_getTracebackObjectFromCaptureVars(self):
- """
- C{captureVars=True} has no effect on the result of
- C{getTracebackObject}.
- """
- try:
- 1/0
- except ZeroDivisionError:
- noVarsFailure = failure.Failure()
- varsFailure = failure.Failure(captureVars=True)
- self.assertEqual(noVarsFailure.getTracebackObject(), varsFailure.tb)
-
-
- def test_getTracebackObjectFromClean(self):
- """
- If the Failure has been cleaned, then C{getTracebackObject} returns an
- object that looks the same to L{traceback.extract_tb}.
- """
- f = getDivisionFailure()
- expected = traceback.extract_tb(f.getTracebackObject())
- f.cleanFailure()
- observed = traceback.extract_tb(f.getTracebackObject())
- self.assertNotEqual(None, expected)
- self.assertEqual(expected, observed)
-
-
- def test_getTracebackObjectFromCaptureVarsAndClean(self):
- """
- If the Failure was created with captureVars, then C{getTracebackObject}
- returns an object that looks the same to L{traceback.extract_tb}.
- """
- f = getDivisionFailure(captureVars=True)
- expected = traceback.extract_tb(f.getTracebackObject())
- f.cleanFailure()
- observed = traceback.extract_tb(f.getTracebackObject())
- self.assertEqual(expected, observed)
-
-
- def test_getTracebackObjectWithoutTraceback(self):
- """
- L{failure.Failure}s need not be constructed with traceback objects. If
- a C{Failure} has no traceback information at all, C{getTracebackObject}
- just returns None.
-
- None is a good value, because traceback.extract_tb(None) -> [].
- """
- f = failure.Failure(Exception("some error"))
- self.assertEqual(f.getTracebackObject(), None)
-
-
-
-class BrokenStr(Exception):
- """
- An exception class the instances of which cannot be presented as strings via
- C{str}.
- """
- def __str__(self):
- # Could raise something else, but there's no point as yet.
- raise self
-
-
-
-class BrokenExceptionMetaclass(type):
- """
- A metaclass for an exception type which cannot be presented as a string via
- C{str}.
- """
- def __str__(self):
- raise ValueError("You cannot make a string out of me.")
-
-
-
-class BrokenExceptionType(Exception, object):
- """
- The aforementioned exception type which cnanot be presented as a string via
- C{str}.
- """
- __metaclass__ = BrokenExceptionMetaclass
-
-
-
-class GetTracebackTests(unittest.TestCase):
- """
- Tests for L{Failure.getTraceback}.
- """
- def _brokenValueTest(self, detail):
- """
- Construct a L{Failure} with an exception that raises an exception from
- its C{__str__} method and then call C{getTraceback} with the specified
- detail and verify that it returns a string.
- """
- x = BrokenStr()
- f = failure.Failure(x)
- traceback = f.getTraceback(detail=detail)
- self.assertIsInstance(traceback, str)
-
-
- def test_brokenValueBriefDetail(self):
- """
- A L{Failure} might wrap an exception with a C{__str__} method which
- raises an exception. In this case, calling C{getTraceback} on the
- failure with the C{"brief"} detail does not raise an exception.
- """
- self._brokenValueTest("brief")
-
-
- def test_brokenValueDefaultDetail(self):
- """
- Like test_brokenValueBriefDetail, but for the C{"default"} detail case.
- """
- self._brokenValueTest("default")
-
-
- def test_brokenValueVerboseDetail(self):
- """
- Like test_brokenValueBriefDetail, but for the C{"default"} detail case.
- """
- self._brokenValueTest("verbose")
-
-
- def _brokenTypeTest(self, detail):
- """
- Construct a L{Failure} with an exception type that raises an exception
- from its C{__str__} method and then call C{getTraceback} with the
- specified detail and verify that it returns a string.
- """
- f = failure.Failure(BrokenExceptionType())
- traceback = f.getTraceback(detail=detail)
- self.assertIsInstance(traceback, str)
-
-
- def test_brokenTypeBriefDetail(self):
- """
- A L{Failure} might wrap an exception the type object of which has a
- C{__str__} method which raises an exception. In this case, calling
- C{getTraceback} on the failure with the C{"brief"} detail does not raise
- an exception.
- """
- self._brokenTypeTest("brief")
-
-
- def test_brokenTypeDefaultDetail(self):
- """
- Like test_brokenTypeBriefDetail, but for the C{"default"} detail case.
- """
- self._brokenTypeTest("default")
-
-
- def test_brokenTypeVerboseDetail(self):
- """
- Like test_brokenTypeBriefDetail, but for the C{"verbose"} detail case.
- """
- self._brokenTypeTest("verbose")
-
-
-
-class FindFailureTests(unittest.TestCase):
- """
- Tests for functionality related to L{Failure._findFailure}.
- """
-
- def test_findNoFailureInExceptionHandler(self):
- """
- Within an exception handler, _findFailure should return
- C{None} in case no Failure is associated with the current
- exception.
- """
- try:
- 1/0
- except:
- self.assertEqual(failure.Failure._findFailure(), None)
- else:
- self.fail("No exception raised from 1/0!?")
-
-
- def test_findNoFailure(self):
- """
- Outside of an exception handler, _findFailure should return None.
- """
- self.assertEqual(sys.exc_info()[-1], None) #environment sanity check
- self.assertEqual(failure.Failure._findFailure(), None)
-
-
- def test_findFailure(self):
- """
- Within an exception handler, it should be possible to find the
- original Failure that caused the current exception (if it was
- caused by raiseException).
- """
- f = getDivisionFailure()
- f.cleanFailure()
- try:
- f.raiseException()
- except:
- self.assertEqual(failure.Failure._findFailure(), f)
- else:
- self.fail("No exception raised from raiseException!?")
-
-
- def test_failureConstructionFindsOriginalFailure(self):
- """
- When a Failure is constructed in the context of an exception
- handler that is handling an exception raised by
- raiseException, the new Failure should be chained to that
- original Failure.
- """
- f = getDivisionFailure()
- f.cleanFailure()
- try:
- f.raiseException()
- except:
- newF = failure.Failure()
- self.assertEqual(f.getTraceback(), newF.getTraceback())
- else:
- self.fail("No exception raised from raiseException!?")
-
-
- def test_failureConstructionWithMungedStackSucceeds(self):
- """
- Pyrex and Cython are known to insert fake stack frames so as to give
- more Python-like tracebacks. These stack frames with empty code objects
- should not break extraction of the exception.
- """
- try:
- raiser.raiseException()
- except raiser.RaiserException:
- f = failure.Failure()
- self.assertTrue(f.check(raiser.RaiserException))
- else:
- self.fail("No exception raised from extension?!")
-
-
- if raiser is None:
- skipMsg = "raiser extension not available"
- test_failureConstructionWithMungedStackSucceeds.skip = skipMsg
-
-
-
-class TestFormattableTraceback(unittest.TestCase):
- """
- Whitebox tests that show that L{failure._Traceback} constructs objects that
- can be used by L{traceback.extract_tb}.
-
- If the objects can be used by L{traceback.extract_tb}, then they can be
- formatted using L{traceback.format_tb} and friends.
- """
-
- def test_singleFrame(self):
- """
- A C{_Traceback} object constructed with a single frame should be able
- to be passed to L{traceback.extract_tb}, and we should get a singleton
- list containing a (filename, lineno, methodname, line) tuple.
- """
- tb = failure._Traceback([['method', 'filename.py', 123, {}, {}]])
- # Note that we don't need to test that extract_tb correctly extracts
- # the line's contents. In this case, since filename.py doesn't exist,
- # it will just use None.
- self.assertEqual(traceback.extract_tb(tb),
- [('filename.py', 123, 'method', None)])
-
-
- def test_manyFrames(self):
- """
- A C{_Traceback} object constructed with multiple frames should be able
- to be passed to L{traceback.extract_tb}, and we should get a list
- containing a tuple for each frame.
- """
- tb = failure._Traceback([
- ['method1', 'filename.py', 123, {}, {}],
- ['method2', 'filename.py', 235, {}, {}]])
- self.assertEqual(traceback.extract_tb(tb),
- [('filename.py', 123, 'method1', None),
- ('filename.py', 235, 'method2', None)])
-
-
-
-class TestFrameAttributes(unittest.TestCase):
- """
- _Frame objects should possess some basic attributes that qualify them as
- fake python Frame objects.
- """
-
- def test_fakeFrameAttributes(self):
- """
- L{_Frame} instances have the C{f_globals} and C{f_locals} attributes
- bound to C{dict} instance. They also have the C{f_code} attribute
- bound to something like a code object.
- """
- frame = failure._Frame("dummyname", "dummyfilename")
- self.assertIsInstance(frame.f_globals, dict)
- self.assertIsInstance(frame.f_locals, dict)
- self.assertIsInstance(frame.f_code, failure._Code)
-
-
-
-class TestDebugMode(unittest.TestCase):
- """
- Failure's debug mode should allow jumping into the debugger.
- """
-
- def setUp(self):
- """
- Override pdb.post_mortem so we can make sure it's called.
- """
- # Make sure any changes we make are reversed:
- post_mortem = pdb.post_mortem
- origInit = failure.Failure.__dict__['__init__']
- def restore():
- pdb.post_mortem = post_mortem
- failure.Failure.__dict__['__init__'] = origInit
- self.addCleanup(restore)
-
- self.result = []
- pdb.post_mortem = self.result.append
- failure.startDebugMode()
-
-
- def test_regularFailure(self):
- """
- If startDebugMode() is called, calling Failure() will first call
- pdb.post_mortem with the traceback.
- """
- try:
- 1/0
- except:
- typ, exc, tb = sys.exc_info()
- f = failure.Failure()
- self.assertEqual(self.result, [tb])
- self.assertEqual(f.captureVars, False)
-
-
- def test_captureVars(self):
- """
- If startDebugMode() is called, passing captureVars to Failure() will
- not blow up.
- """
- try:
- 1/0
- except:
- typ, exc, tb = sys.exc_info()
- f = failure.Failure(captureVars=True)
- self.assertEqual(self.result, [tb])
- self.assertEqual(f.captureVars, True)
-
-
-
-if sys.version_info[:2] >= (2, 5):
- from twisted.test.generator_failure_tests import TwoPointFiveFailureTests
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_fdesc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_fdesc.py
deleted file mode 100755
index 285b9cc3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_fdesc.py
+++ /dev/null
@@ -1,235 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.fdesc}.
-"""
-
-import os, sys
-import errno
-
-try:
- import fcntl
-except ImportError:
- skip = "not supported on this platform"
-else:
- from twisted.internet import fdesc
-
-from twisted.python.util import untilConcludes
-from twisted.trial import unittest
-
-
-class ReadWriteTestCase(unittest.TestCase):
- """
- Tests for fdesc.readFromFD, fdesc.writeToFD.
- """
-
- def setUp(self):
- """
- Create two non-blocking pipes that can be used in tests.
- """
- self.r, self.w = os.pipe()
- fdesc.setNonBlocking(self.r)
- fdesc.setNonBlocking(self.w)
-
-
- def tearDown(self):
- """
- Close pipes.
- """
- try:
- os.close(self.w)
- except OSError:
- pass
- try:
- os.close(self.r)
- except OSError:
- pass
-
-
- def write(self, d):
- """
- Write data to the pipe.
- """
- return fdesc.writeToFD(self.w, d)
-
-
- def read(self):
- """
- Read data from the pipe.
- """
- l = []
- res = fdesc.readFromFD(self.r, l.append)
- if res is None:
- if l:
- return l[0]
- else:
- return ""
- else:
- return res
-
-
- def test_writeAndRead(self):
- """
- Test that the number of bytes L{fdesc.writeToFD} reports as written
- with its return value are seen by L{fdesc.readFromFD}.
- """
- n = self.write("hello")
- self.failUnless(n > 0)
- s = self.read()
- self.assertEqual(len(s), n)
- self.assertEqual("hello"[:n], s)
-
-
- def test_writeAndReadLarge(self):
- """
- Similar to L{test_writeAndRead}, but use a much larger string to verify
- the behavior for that case.
- """
- orig = "0123456879" * 10000
- written = self.write(orig)
- self.failUnless(written > 0)
- result = []
- resultlength = 0
- i = 0
- while resultlength < written or i < 50:
- result.append(self.read())
- resultlength += len(result[-1])
- # Increment a counter to be sure we'll exit at some point
- i += 1
- result = "".join(result)
- self.assertEqual(len(result), written)
- self.assertEqual(orig[:written], result)
-
-
- def test_readFromEmpty(self):
- """
- Verify that reading from a file descriptor with no data does not raise
- an exception and does not result in the callback function being called.
- """
- l = []
- result = fdesc.readFromFD(self.r, l.append)
- self.assertEqual(l, [])
- self.assertEqual(result, None)
-
-
- def test_readFromCleanClose(self):
- """
- Test that using L{fdesc.readFromFD} on a cleanly closed file descriptor
- returns a connection done indicator.
- """
- os.close(self.w)
- self.assertEqual(self.read(), fdesc.CONNECTION_DONE)
-
-
- def test_writeToClosed(self):
- """
- Verify that writing with L{fdesc.writeToFD} when the read end is closed
- results in a connection lost indicator.
- """
- os.close(self.r)
- self.assertEqual(self.write("s"), fdesc.CONNECTION_LOST)
-
-
- def test_readFromInvalid(self):
- """
- Verify that reading with L{fdesc.readFromFD} when the read end is
- closed results in a connection lost indicator.
- """
- os.close(self.r)
- self.assertEqual(self.read(), fdesc.CONNECTION_LOST)
-
-
- def test_writeToInvalid(self):
- """
- Verify that writing with L{fdesc.writeToFD} when the write end is
- closed results in a connection lost indicator.
- """
- os.close(self.w)
- self.assertEqual(self.write("s"), fdesc.CONNECTION_LOST)
-
-
- def test_writeErrors(self):
- """
- Test error path for L{fdesc.writeTod}.
- """
- oldOsWrite = os.write
- def eagainWrite(fd, data):
- err = OSError()
- err.errno = errno.EAGAIN
- raise err
- os.write = eagainWrite
- try:
- self.assertEqual(self.write("s"), 0)
- finally:
- os.write = oldOsWrite
-
- def eintrWrite(fd, data):
- err = OSError()
- err.errno = errno.EINTR
- raise err
- os.write = eintrWrite
- try:
- self.assertEqual(self.write("s"), 0)
- finally:
- os.write = oldOsWrite
-
-
-
-class CloseOnExecTests(unittest.TestCase):
- """
- Tests for L{fdesc._setCloseOnExec} and L{fdesc._unsetCloseOnExec}.
- """
- program = '''
-import os, errno
-try:
- os.write(%d, 'lul')
-except OSError, e:
- if e.errno == errno.EBADF:
- os._exit(0)
- os._exit(5)
-except:
- os._exit(10)
-else:
- os._exit(20)
-'''
-
- def _execWithFileDescriptor(self, fObj):
- pid = os.fork()
- if pid == 0:
- try:
- os.execv(sys.executable, [sys.executable, '-c', self.program % (fObj.fileno(),)])
- except:
- import traceback
- traceback.print_exc()
- os._exit(30)
- else:
- # On Linux wait(2) doesn't seem ever able to fail with EINTR but
- # POSIX seems to allow it and on OS X it happens quite a lot.
- return untilConcludes(os.waitpid, pid, 0)[1]
-
-
- def test_setCloseOnExec(self):
- """
- A file descriptor passed to L{fdesc._setCloseOnExec} is not inherited
- by a new process image created with one of the exec family of
- functions.
- """
- fObj = file(self.mktemp(), 'w')
- fdesc._setCloseOnExec(fObj.fileno())
- status = self._execWithFileDescriptor(fObj)
- self.assertTrue(os.WIFEXITED(status))
- self.assertEqual(os.WEXITSTATUS(status), 0)
-
-
- def test_unsetCloseOnExec(self):
- """
- A file descriptor passed to L{fdesc._unsetCloseOnExec} is inherited by
- a new process image created with one of the exec family of functions.
- """
- fObj = file(self.mktemp(), 'w')
- fdesc._setCloseOnExec(fObj.fileno())
- fdesc._unsetCloseOnExec(fObj.fileno())
- status = self._execWithFileDescriptor(fObj)
- self.assertTrue(os.WIFEXITED(status))
- self.assertEqual(os.WEXITSTATUS(status), 20)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_finger.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_finger.py
deleted file mode 100755
index c0c2e090..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_finger.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.protocols.finger}.
-"""
-
-from twisted.trial import unittest
-from twisted.protocols import finger
-from twisted.test.proto_helpers import StringTransport
-
-
-class FingerTestCase(unittest.TestCase):
- """
- Tests for L{finger.Finger}.
- """
- def setUp(self):
- """
- Create and connect a L{finger.Finger} instance.
- """
- self.transport = StringTransport()
- self.protocol = finger.Finger()
- self.protocol.makeConnection(self.transport)
-
-
- def test_simple(self):
- """
- When L{finger.Finger} receives a CR LF terminated line, it responds
- with the default user status message - that no such user exists.
- """
- self.protocol.dataReceived("moshez\r\n")
- self.assertEqual(
- self.transport.value(),
- "Login: moshez\nNo such user\n")
-
-
- def test_simpleW(self):
- """
- The behavior for a query which begins with C{"/w"} is the same as the
- behavior for one which does not. The user is reported as not existing.
- """
- self.protocol.dataReceived("/w moshez\r\n")
- self.assertEqual(
- self.transport.value(),
- "Login: moshez\nNo such user\n")
-
-
- def test_forwarding(self):
- """
- When L{finger.Finger} receives a request for a remote user, it responds
- with a message rejecting the request.
- """
- self.protocol.dataReceived("moshez@example.com\r\n")
- self.assertEqual(
- self.transport.value(),
- "Finger forwarding service denied\n")
-
-
- def test_list(self):
- """
- When L{finger.Finger} receives a blank line, it responds with a message
- rejecting the request for all online users.
- """
- self.protocol.dataReceived("\r\n")
- self.assertEqual(
- self.transport.value(),
- "Finger online list denied\n")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_formmethod.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_formmethod.py
deleted file mode 100755
index 845c4e29..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_formmethod.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test cases for formmethod module.
-"""
-
-from twisted.trial import unittest
-
-from twisted.python import formmethod
-
-
-class ArgumentTestCase(unittest.TestCase):
-
- def argTest(self, argKlass, testPairs, badValues, *args, **kwargs):
- arg = argKlass("name", *args, **kwargs)
- for val, result in testPairs:
- self.assertEqual(arg.coerce(val), result)
- for val in badValues:
- self.assertRaises(formmethod.InputError, arg.coerce, val)
-
-
- def test_argument(self):
- """
- Test that corce correctly raises NotImplementedError.
- """
- arg = formmethod.Argument("name")
- self.assertRaises(NotImplementedError, arg.coerce, "")
-
-
- def testString(self):
- self.argTest(formmethod.String, [("a", "a"), (1, "1"), ("", "")], ())
- self.argTest(formmethod.String, [("ab", "ab"), ("abc", "abc")], ("2", ""), min=2)
- self.argTest(formmethod.String, [("ab", "ab"), ("a", "a")], ("223213", "345x"), max=3)
- self.argTest(formmethod.String, [("ab", "ab"), ("add", "add")], ("223213", "x"), min=2, max=3)
-
- def testInt(self):
- self.argTest(formmethod.Integer, [("3", 3), ("-2", -2), ("", None)], ("q", "2.3"))
- self.argTest(formmethod.Integer, [("3", 3), ("-2", -2)], ("q", "2.3", ""), allowNone=0)
-
- def testFloat(self):
- self.argTest(formmethod.Float, [("3", 3.0), ("-2.3", -2.3), ("", None)], ("q", "2.3z"))
- self.argTest(formmethod.Float, [("3", 3.0), ("-2.3", -2.3)], ("q", "2.3z", ""),
- allowNone=0)
-
- def testChoice(self):
- choices = [("a", "apple", "an apple"),
- ("b", "banana", "ook")]
- self.argTest(formmethod.Choice, [("a", "apple"), ("b", "banana")],
- ("c", 1), choices=choices)
-
- def testFlags(self):
- flags = [("a", "apple", "an apple"),
- ("b", "banana", "ook")]
- self.argTest(formmethod.Flags,
- [(["a"], ["apple"]), (["b", "a"], ["banana", "apple"])],
- (["a", "c"], ["fdfs"]),
- flags=flags)
-
- def testBoolean(self):
- tests = [("yes", 1), ("", 0), ("False", 0), ("no", 0)]
- self.argTest(formmethod.Boolean, tests, ())
-
-
- def test_file(self):
- """
- Test the correctness of the coerce function.
- """
- arg = formmethod.File("name", allowNone=0)
- self.assertEqual(arg.coerce("something"), "something")
- self.assertRaises(formmethod.InputError, arg.coerce, None)
- arg2 = formmethod.File("name")
- self.assertEqual(arg2.coerce(None), None)
-
-
- def testDate(self):
- goodTests = {
- ("2002", "12", "21"): (2002, 12, 21),
- ("1996", "2", "29"): (1996, 2, 29),
- ("", "", ""): None,
- }.items()
- badTests = [("2002", "2", "29"), ("xx", "2", "3"),
- ("2002", "13", "1"), ("1999", "12","32"),
- ("2002", "1"), ("2002", "2", "3", "4")]
- self.argTest(formmethod.Date, goodTests, badTests)
-
- def testRangedInteger(self):
- goodTests = {"0": 0, "12": 12, "3": 3}.items()
- badTests = ["-1", "x", "13", "-2000", "3.4"]
- self.argTest(formmethod.IntegerRange, goodTests, badTests, 0, 12)
-
- def testVerifiedPassword(self):
- goodTests = {("foo", "foo"): "foo", ("ab", "ab"): "ab"}.items()
- badTests = [("ab", "a"), ("12345", "12345"), ("", ""), ("a", "a"), ("a",), ("a", "a", "a")]
- self.argTest(formmethod.VerifiedPassword, goodTests, badTests, min=2, max=4)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp.py
deleted file mode 100755
index 23ffcbaa..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp.py
+++ /dev/null
@@ -1,3111 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-FTP tests.
-"""
-
-import os
-import errno
-from StringIO import StringIO
-import getpass
-
-from zope.interface import implements
-from zope.interface.verify import verifyClass
-
-from twisted.trial import unittest, util
-from twisted.python.randbytes import insecureRandom
-from twisted.cred.portal import IRealm
-from twisted.protocols import basic
-from twisted.internet import reactor, task, protocol, defer, error
-from twisted.internet.interfaces import IConsumer
-from twisted.cred.error import UnauthorizedLogin
-from twisted.cred import portal, checkers, credentials
-from twisted.python import failure, filepath, runtime
-from twisted.test import proto_helpers
-
-from twisted.protocols import ftp, loopback
-
-
-_changeDirectorySuppression = util.suppress(
- category=DeprecationWarning,
- message=(
- r"FTPClient\.changeDirectory is deprecated in Twisted 8\.2 and "
- r"newer\. Use FTPClient\.cwd instead\."))
-
-if runtime.platform.isWindows():
- nonPOSIXSkip = "Cannot run on Windows"
-else:
- nonPOSIXSkip = None
-
-
-class Dummy(basic.LineReceiver):
- logname = None
- def __init__(self):
- self.lines = []
- self.rawData = []
- def connectionMade(self):
- self.f = self.factory # to save typing in pdb :-)
- def lineReceived(self,line):
- self.lines.append(line)
- def rawDataReceived(self, data):
- self.rawData.append(data)
- def lineLengthExceeded(self, line):
- pass
-
-
-class _BufferingProtocol(protocol.Protocol):
- def connectionMade(self):
- self.buffer = ''
- self.d = defer.Deferred()
- def dataReceived(self, data):
- self.buffer += data
- def connectionLost(self, reason):
- self.d.callback(self)
-
-
-
-class FTPServerTestCase(unittest.TestCase):
- """
- Simple tests for an FTP server with the default settings.
-
- @ivar clientFactory: class used as ftp client.
- """
- clientFactory = ftp.FTPClientBasic
- userAnonymous = "anonymous"
-
- def setUp(self):
- # Create a directory
- self.directory = self.mktemp()
- os.mkdir(self.directory)
- self.dirPath = filepath.FilePath(self.directory)
-
- # Start the server
- p = portal.Portal(ftp.FTPRealm(
- anonymousRoot=self.directory,
- userHome=self.directory,
- ))
- p.registerChecker(checkers.AllowAnonymousAccess(),
- credentials.IAnonymous)
-
- users_checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- self.username = "test-user"
- self.password = "test-password"
- users_checker.addUser(self.username, self.password)
- p.registerChecker(users_checker, credentials.IUsernamePassword)
-
- self.factory = ftp.FTPFactory(portal=p,
- userAnonymous=self.userAnonymous)
- port = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
-
- # Hook the server's buildProtocol to make the protocol instance
- # accessible to tests.
- buildProtocol = self.factory.buildProtocol
- d1 = defer.Deferred()
- def _rememberProtocolInstance(addr):
- # Done hooking this.
- del self.factory.buildProtocol
-
- protocol = buildProtocol(addr)
- self.serverProtocol = protocol.wrappedProtocol
- def cleanupServer():
- if self.serverProtocol.transport is not None:
- self.serverProtocol.transport.loseConnection()
- self.addCleanup(cleanupServer)
- d1.callback(None)
- return protocol
- self.factory.buildProtocol = _rememberProtocolInstance
-
- # Connect a client to it
- portNum = port.getHost().port
- clientCreator = protocol.ClientCreator(reactor, self.clientFactory)
- d2 = clientCreator.connectTCP("127.0.0.1", portNum)
- def gotClient(client):
- self.client = client
- self.addCleanup(self.client.transport.loseConnection)
- d2.addCallback(gotClient)
- return defer.gatherResults([d1, d2])
-
- def assertCommandResponse(self, command, expectedResponseLines,
- chainDeferred=None):
- """Asserts that a sending an FTP command receives the expected
- response.
-
- Returns a Deferred. Optionally accepts a deferred to chain its actions
- to.
- """
- if chainDeferred is None:
- chainDeferred = defer.succeed(None)
-
- def queueCommand(ignored):
- d = self.client.queueStringCommand(command)
- def gotResponse(responseLines):
- self.assertEqual(expectedResponseLines, responseLines)
- return d.addCallback(gotResponse)
- return chainDeferred.addCallback(queueCommand)
-
- def assertCommandFailed(self, command, expectedResponse=None,
- chainDeferred=None):
- if chainDeferred is None:
- chainDeferred = defer.succeed(None)
-
- def queueCommand(ignored):
- return self.client.queueStringCommand(command)
- chainDeferred.addCallback(queueCommand)
- self.assertFailure(chainDeferred, ftp.CommandFailed)
- def failed(exception):
- if expectedResponse is not None:
- self.assertEqual(
- expectedResponse, exception.args[0])
- return chainDeferred.addCallback(failed)
-
- def _anonymousLogin(self):
- d = self.assertCommandResponse(
- 'USER anonymous',
- ['331 Guest login ok, type your email address as password.'])
- return self.assertCommandResponse(
- 'PASS test@twistedmatrix.com',
- ['230 Anonymous login ok, access restrictions apply.'],
- chainDeferred=d)
-
- def _userLogin(self):
- """Authenticates the FTP client using the test account."""
- d = self.assertCommandResponse(
- 'USER %s' % (self.username),
- ['331 Password required for %s.' % (self.username)])
- return self.assertCommandResponse(
- 'PASS %s' % (self.password),
- ['230 User logged in, proceed'],
- chainDeferred=d)
-
-
-class FTPAnonymousTestCase(FTPServerTestCase):
- """
- Simple tests for an FTP server with different anonymous username.
- The new anonymous username used in this test case is "guest"
- """
- userAnonymous = "guest"
-
- def test_anonymousLogin(self):
- """
- Tests whether the changing of the anonymous username is working or not.
- The FTP server should not comply about the need of password for the
- username 'guest', letting it login as anonymous asking just an email
- address as password.
- """
- d = self.assertCommandResponse(
- 'USER guest',
- ['331 Guest login ok, type your email address as password.'])
- return self.assertCommandResponse(
- 'PASS test@twistedmatrix.com',
- ['230 Anonymous login ok, access restrictions apply.'],
- chainDeferred=d)
-
-
-
-class BasicFTPServerTestCase(FTPServerTestCase):
- def testNotLoggedInReply(self):
- """When not logged in, all commands other than USER and PASS should
- get NOT_LOGGED_IN errors.
- """
- commandList = ['CDUP', 'CWD', 'LIST', 'MODE', 'PASV',
- 'PWD', 'RETR', 'STRU', 'SYST', 'TYPE']
-
- # Issue commands, check responses
- def checkResponse(exception):
- failureResponseLines = exception.args[0]
- self.failUnless(failureResponseLines[-1].startswith("530"),
- "Response didn't start with 530: %r"
- % (failureResponseLines[-1],))
- deferreds = []
- for command in commandList:
- deferred = self.client.queueStringCommand(command)
- self.assertFailure(deferred, ftp.CommandFailed)
- deferred.addCallback(checkResponse)
- deferreds.append(deferred)
- return defer.DeferredList(deferreds, fireOnOneErrback=True)
-
- def testPASSBeforeUSER(self):
- """Issuing PASS before USER should give an error."""
- return self.assertCommandFailed(
- 'PASS foo',
- ["503 Incorrect sequence of commands: "
- "USER required before PASS"])
-
- def testNoParamsForUSER(self):
- """Issuing USER without a username is a syntax error."""
- return self.assertCommandFailed(
- 'USER',
- ['500 Syntax error: USER requires an argument.'])
-
- def testNoParamsForPASS(self):
- """Issuing PASS without a password is a syntax error."""
- d = self.client.queueStringCommand('USER foo')
- return self.assertCommandFailed(
- 'PASS',
- ['500 Syntax error: PASS requires an argument.'],
- chainDeferred=d)
-
- def testAnonymousLogin(self):
- return self._anonymousLogin()
-
- def testQuit(self):
- """Issuing QUIT should return a 221 message."""
- d = self._anonymousLogin()
- return self.assertCommandResponse(
- 'QUIT',
- ['221 Goodbye.'],
- chainDeferred=d)
-
- def testAnonymousLoginDenied(self):
- # Reconfigure the server to disallow anonymous access, and to have an
- # IUsernamePassword checker that always rejects.
- self.factory.allowAnonymous = False
- denyAlwaysChecker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- self.factory.portal.registerChecker(denyAlwaysChecker,
- credentials.IUsernamePassword)
-
- # Same response code as allowAnonymous=True, but different text.
- d = self.assertCommandResponse(
- 'USER anonymous',
- ['331 Password required for anonymous.'])
-
- # It will be denied. No-one can login.
- d = self.assertCommandFailed(
- 'PASS test@twistedmatrix.com',
- ['530 Sorry, Authentication failed.'],
- chainDeferred=d)
-
- # It's not just saying that. You aren't logged in.
- d = self.assertCommandFailed(
- 'PWD',
- ['530 Please login with USER and PASS.'],
- chainDeferred=d)
- return d
-
-
- def test_anonymousWriteDenied(self):
- """
- When an anonymous user attempts to edit the server-side filesystem, they
- will receive a 550 error with a descriptive message.
- """
- d = self._anonymousLogin()
- return self.assertCommandFailed(
- 'MKD newdir',
- ['550 Anonymous users are forbidden to change the filesystem'],
- chainDeferred=d)
-
-
- def testUnknownCommand(self):
- d = self._anonymousLogin()
- return self.assertCommandFailed(
- 'GIBBERISH',
- ["502 Command 'GIBBERISH' not implemented"],
- chainDeferred=d)
-
- def testRETRBeforePORT(self):
- d = self._anonymousLogin()
- return self.assertCommandFailed(
- 'RETR foo',
- ["503 Incorrect sequence of commands: "
- "PORT or PASV required before RETR"],
- chainDeferred=d)
-
- def testSTORBeforePORT(self):
- d = self._anonymousLogin()
- return self.assertCommandFailed(
- 'STOR foo',
- ["503 Incorrect sequence of commands: "
- "PORT or PASV required before STOR"],
- chainDeferred=d)
-
- def testBadCommandArgs(self):
- d = self._anonymousLogin()
- self.assertCommandFailed(
- 'MODE z',
- ["504 Not implemented for parameter 'z'."],
- chainDeferred=d)
- self.assertCommandFailed(
- 'STRU I',
- ["504 Not implemented for parameter 'I'."],
- chainDeferred=d)
- return d
-
- def testDecodeHostPort(self):
- self.assertEqual(ftp.decodeHostPort('25,234,129,22,100,23'),
- ('25.234.129.22', 25623))
- nums = range(6)
- for i in range(6):
- badValue = list(nums)
- badValue[i] = 256
- s = ','.join(map(str, badValue))
- self.assertRaises(ValueError, ftp.decodeHostPort, s)
-
- def testPASV(self):
- # Login
- wfd = defer.waitForDeferred(self._anonymousLogin())
- yield wfd
- wfd.getResult()
-
- # Issue a PASV command, and extract the host and port from the response
- pasvCmd = defer.waitForDeferred(self.client.queueStringCommand('PASV'))
- yield pasvCmd
- responseLines = pasvCmd.getResult()
- host, port = ftp.decodeHostPort(responseLines[-1][4:])
-
- # Make sure the server is listening on the port it claims to be
- self.assertEqual(port, self.serverProtocol.dtpPort.getHost().port)
-
- # Semi-reasonable way to force cleanup
- self.serverProtocol.transport.loseConnection()
- testPASV = defer.deferredGenerator(testPASV)
-
- def test_SYST(self):
- """SYST command will always return UNIX Type: L8"""
- d = self._anonymousLogin()
- self.assertCommandResponse('SYST', ["215 UNIX Type: L8"],
- chainDeferred=d)
- return d
-
- def test_RNFRandRNTO(self):
- """
- Sending the RNFR command followed by RNTO, with valid filenames, will
- perform a successful rename operation.
- """
- # Create user home folder with a 'foo' file.
- self.dirPath.child(self.username).createDirectory()
- self.dirPath.child(self.username).child('foo').touch()
-
- d = self._userLogin()
- self.assertCommandResponse(
- 'RNFR foo',
- ["350 Requested file action pending further information."],
- chainDeferred=d)
- self.assertCommandResponse(
- 'RNTO bar',
- ["250 Requested File Action Completed OK"],
- chainDeferred=d)
-
- def check_rename(result):
- self.assertTrue(
- self.dirPath.child(self.username).child('bar').exists())
- return result
-
- d.addCallback(check_rename)
- return d
-
- def test_RNFRwithoutRNTO(self):
- """
- Sending the RNFR command followed by any command other than RNTO
- should return an error informing users that RNFR should be followed
- by RNTO.
- """
- d = self._anonymousLogin()
- self.assertCommandResponse(
- 'RNFR foo',
- ["350 Requested file action pending further information."],
- chainDeferred=d)
- self.assertCommandFailed(
- 'OTHER don-tcare',
- ["503 Incorrect sequence of commands: RNTO required after RNFR"],
- chainDeferred=d)
- return d
-
- def test_portRangeForwardError(self):
- """
- Exceptions other than L{error.CannotListenError} which are raised by
- C{listenFactory} should be raised to the caller of L{FTP.getDTPPort}.
- """
- def listenFactory(portNumber, factory):
- raise RuntimeError()
- self.serverProtocol.listenFactory = listenFactory
-
- self.assertRaises(RuntimeError, self.serverProtocol.getDTPPort,
- protocol.Factory())
-
-
- def test_portRange(self):
- """
- L{FTP.passivePortRange} should determine the ports which
- L{FTP.getDTPPort} attempts to bind. If no port from that iterator can
- be bound, L{error.CannotListenError} should be raised, otherwise the
- first successful result from L{FTP.listenFactory} should be returned.
- """
- def listenFactory(portNumber, factory):
- if portNumber in (22032, 22033, 22034):
- raise error.CannotListenError('localhost', portNumber, 'error')
- return portNumber
- self.serverProtocol.listenFactory = listenFactory
-
- port = self.serverProtocol.getDTPPort(protocol.Factory())
- self.assertEqual(port, 0)
-
- self.serverProtocol.passivePortRange = xrange(22032, 65536)
- port = self.serverProtocol.getDTPPort(protocol.Factory())
- self.assertEqual(port, 22035)
-
- self.serverProtocol.passivePortRange = xrange(22032, 22035)
- self.assertRaises(error.CannotListenError,
- self.serverProtocol.getDTPPort,
- protocol.Factory())
-
-
- def test_portRangeInheritedFromFactory(self):
- """
- The L{FTP} instances created by L{ftp.FTPFactory.buildProtocol} have
- their C{passivePortRange} attribute set to the same object the
- factory's C{passivePortRange} attribute is set to.
- """
- portRange = xrange(2017, 2031)
- self.factory.passivePortRange = portRange
- protocol = self.factory.buildProtocol(None)
- self.assertEqual(portRange, protocol.wrappedProtocol.passivePortRange)
-
-
-
-class FTPServerTestCaseAdvancedClient(FTPServerTestCase):
- """
- Test FTP server with the L{ftp.FTPClient} class.
- """
- clientFactory = ftp.FTPClient
-
- def test_anonymousSTOR(self):
- """
- Try to make an STOR as anonymous, and check that we got a permission
- denied error.
- """
- def eb(res):
- res.trap(ftp.CommandFailed)
- self.assertEqual(res.value.args[0][0],
- '550 foo: Permission denied.')
- d1, d2 = self.client.storeFile('foo')
- d2.addErrback(eb)
- return defer.gatherResults([d1, d2])
-
-
- def test_STORwriteError(self):
- """
- Any errors during writing a file inside a STOR should be returned to
- the client.
- """
- # Make a failing file writer.
- class FailingFileWriter(ftp._FileWriter):
- def receive(self):
- return defer.fail(ftp.IsNotADirectoryError("blah"))
-
- def failingSTOR(a, b):
- return defer.succeed(FailingFileWriter(None))
-
- # Monkey patch the shell so it returns a file writer that will
- # fail.
- self.patch(ftp.FTPAnonymousShell, 'openForWriting', failingSTOR)
-
- def eb(res):
- self.flushLoggedErrors()
- res.trap(ftp.CommandFailed)
- self.assertEqual(
- res.value.args[0][0],
- "550 Cannot rmd, blah is not a directory")
- d1, d2 = self.client.storeFile('failing_file')
- d2.addErrback(eb)
- return defer.gatherResults([d1, d2])
-
- def test_RETRreadError(self):
- """
- Any errors during reading a file inside a RETR should be returned to
- the client.
- """
- # Make a failing file reading.
- class FailingFileReader(ftp._FileReader):
- def send(self, consumer):
- return defer.fail(ftp.IsADirectoryError("blah"))
-
- def failingRETR(a, b):
- return defer.succeed(FailingFileReader(None))
-
- # Monkey patch the shell so it returns a file reader that will
- # fail.
- self.patch(ftp.FTPAnonymousShell, 'openForReading', failingRETR)
-
- def check_response(failure):
- self.flushLoggedErrors()
- failure.trap(ftp.CommandFailed)
- self.assertEqual(
- failure.value.args[0][0],
- "125 Data connection already open, starting transfer")
- self.assertEqual(
- failure.value.args[0][1],
- "550 blah: is a directory")
-
- proto = _BufferingProtocol()
- d = self.client.retrieveFile('failing_file', proto)
- d.addErrback(check_response)
- return d
-
-
-class FTPServerPasvDataConnectionTestCase(FTPServerTestCase):
- def _makeDataConnection(self, ignored=None):
- # Establish a passive data connection (i.e. client connecting to
- # server).
- d = self.client.queueStringCommand('PASV')
- def gotPASV(responseLines):
- host, port = ftp.decodeHostPort(responseLines[-1][4:])
- cc = protocol.ClientCreator(reactor, _BufferingProtocol)
- return cc.connectTCP('127.0.0.1', port)
- return d.addCallback(gotPASV)
-
- def _download(self, command, chainDeferred=None):
- if chainDeferred is None:
- chainDeferred = defer.succeed(None)
-
- chainDeferred.addCallback(self._makeDataConnection)
- def queueCommand(downloader):
- # wait for the command to return, and the download connection to be
- # closed.
- d1 = self.client.queueStringCommand(command)
- d2 = downloader.d
- return defer.gatherResults([d1, d2])
- chainDeferred.addCallback(queueCommand)
-
- def downloadDone((ignored, downloader)):
- return downloader.buffer
- return chainDeferred.addCallback(downloadDone)
-
- def testEmptyLIST(self):
- # Login
- d = self._anonymousLogin()
-
- # No files, so the file listing should be empty
- self._download('LIST', chainDeferred=d)
- def checkEmpty(result):
- self.assertEqual('', result)
- return d.addCallback(checkEmpty)
-
- def testTwoDirLIST(self):
- # Make some directories
- os.mkdir(os.path.join(self.directory, 'foo'))
- os.mkdir(os.path.join(self.directory, 'bar'))
-
- # Login
- d = self._anonymousLogin()
-
- # We expect 2 lines because there are two files.
- self._download('LIST', chainDeferred=d)
- def checkDownload(download):
- self.assertEqual(2, len(download[:-2].split('\r\n')))
- d.addCallback(checkDownload)
-
- # Download a names-only listing.
- self._download('NLST ', chainDeferred=d)
- def checkDownload(download):
- filenames = download[:-2].split('\r\n')
- filenames.sort()
- self.assertEqual(['bar', 'foo'], filenames)
- d.addCallback(checkDownload)
-
- # Download a listing of the 'foo' subdirectory. 'foo' has no files, so
- # the file listing should be empty.
- self._download('LIST foo', chainDeferred=d)
- def checkDownload(download):
- self.assertEqual('', download)
- d.addCallback(checkDownload)
-
- # Change the current working directory to 'foo'.
- def chdir(ignored):
- return self.client.queueStringCommand('CWD foo')
- d.addCallback(chdir)
-
- # Download a listing from within 'foo', and again it should be empty,
- # because LIST uses the working directory by default.
- self._download('LIST', chainDeferred=d)
- def checkDownload(download):
- self.assertEqual('', download)
- return d.addCallback(checkDownload)
-
- def testManyLargeDownloads(self):
- # Login
- d = self._anonymousLogin()
-
- # Download a range of different size files
- for size in range(100000, 110000, 500):
- fObj = file(os.path.join(self.directory, '%d.txt' % (size,)), 'wb')
- fObj.write('x' * size)
- fObj.close()
-
- self._download('RETR %d.txt' % (size,), chainDeferred=d)
- def checkDownload(download, size=size):
- self.assertEqual(size, len(download))
- d.addCallback(checkDownload)
- return d
-
-
- def test_downloadFolder(self):
- """
- When RETR is called for a folder, it will fail complaining that
- the path is a folder.
- """
- # Make a directory in the current working directory
- self.dirPath.child('foo').createDirectory()
- # Login
- d = self._anonymousLogin()
- d.addCallback(self._makeDataConnection)
-
- def retrFolder(downloader):
- downloader.transport.loseConnection()
- deferred = self.client.queueStringCommand('RETR foo')
- return deferred
- d.addCallback(retrFolder)
-
- def failOnSuccess(result):
- raise AssertionError('Downloading a folder should not succeed.')
- d.addCallback(failOnSuccess)
-
- def checkError(failure):
- failure.trap(ftp.CommandFailed)
- self.assertEqual(
- ['550 foo: is a directory'], failure.value.message)
- current_errors = self.flushLoggedErrors()
- self.assertEqual(
- 0, len(current_errors),
- 'No errors should be logged while downloading a folder.')
- d.addErrback(checkError)
- return d
-
-
- def test_NLSTEmpty(self):
- """
- NLST with no argument returns the directory listing for the current
- working directory.
- """
- # Login
- d = self._anonymousLogin()
-
- # Touch a file in the current working directory
- self.dirPath.child('test.txt').touch()
- # Make a directory in the current working directory
- self.dirPath.child('foo').createDirectory()
-
- self._download('NLST ', chainDeferred=d)
- def checkDownload(download):
- filenames = download[:-2].split('\r\n')
- filenames.sort()
- self.assertEqual(['foo', 'test.txt'], filenames)
- return d.addCallback(checkDownload)
-
-
- def test_NLSTNonexistent(self):
- """
- NLST on a non-existent file/directory returns nothing.
- """
- # Login
- d = self._anonymousLogin()
-
- self._download('NLST nonexistent.txt', chainDeferred=d)
- def checkDownload(download):
- self.assertEqual('', download)
- return d.addCallback(checkDownload)
-
-
- def test_NLSTOnPathToFile(self):
- """
- NLST on an existent file returns only the path to that file.
- """
- # Login
- d = self._anonymousLogin()
-
- # Touch a file in the current working directory
- self.dirPath.child('test.txt').touch()
-
- self._download('NLST test.txt', chainDeferred=d)
- def checkDownload(download):
- filenames = download[:-2].split('\r\n')
- self.assertEqual(['test.txt'], filenames)
- return d.addCallback(checkDownload)
-
-
-
-class FTPServerPortDataConnectionTestCase(FTPServerPasvDataConnectionTestCase):
- def setUp(self):
- self.dataPorts = []
- return FTPServerPasvDataConnectionTestCase.setUp(self)
-
- def _makeDataConnection(self, ignored=None):
- # Establish an active data connection (i.e. server connecting to
- # client).
- deferred = defer.Deferred()
- class DataFactory(protocol.ServerFactory):
- protocol = _BufferingProtocol
- def buildProtocol(self, addr):
- p = protocol.ServerFactory.buildProtocol(self, addr)
- reactor.callLater(0, deferred.callback, p)
- return p
- dataPort = reactor.listenTCP(0, DataFactory(), interface='127.0.0.1')
- self.dataPorts.append(dataPort)
- cmd = 'PORT ' + ftp.encodeHostPort('127.0.0.1', dataPort.getHost().port)
- self.client.queueStringCommand(cmd)
- return deferred
-
- def tearDown(self):
- l = [defer.maybeDeferred(port.stopListening) for port in self.dataPorts]
- d = defer.maybeDeferred(
- FTPServerPasvDataConnectionTestCase.tearDown, self)
- l.append(d)
- return defer.DeferredList(l, fireOnOneErrback=True)
-
- def testPORTCannotConnect(self):
- # Login
- d = self._anonymousLogin()
-
- # Listen on a port, and immediately stop listening as a way to find a
- # port number that is definitely closed.
- def loggedIn(ignored):
- port = reactor.listenTCP(0, protocol.Factory(),
- interface='127.0.0.1')
- portNum = port.getHost().port
- d = port.stopListening()
- d.addCallback(lambda _: portNum)
- return d
- d.addCallback(loggedIn)
-
- # Tell the server to connect to that port with a PORT command, and
- # verify that it fails with the right error.
- def gotPortNum(portNum):
- return self.assertCommandFailed(
- 'PORT ' + ftp.encodeHostPort('127.0.0.1', portNum),
- ["425 Can't open data connection."])
- return d.addCallback(gotPortNum)
-
-
-
-class DTPFactoryTests(unittest.TestCase):
- """
- Tests for L{ftp.DTPFactory}.
- """
- def setUp(self):
- """
- Create a fake protocol interpreter and a L{ftp.DTPFactory} instance to
- test.
- """
- self.reactor = task.Clock()
-
- class ProtocolInterpreter(object):
- dtpInstance = None
-
- self.protocolInterpreter = ProtocolInterpreter()
- self.factory = ftp.DTPFactory(
- self.protocolInterpreter, None, self.reactor)
-
-
- def test_setTimeout(self):
- """
- L{ftp.DTPFactory.setTimeout} uses the reactor passed to its initializer
- to set up a timed event to time out the DTP setup after the specified
- number of seconds.
- """
- # Make sure the factory's deferred fails with the right exception, and
- # make it so we can tell exactly when it fires.
- finished = []
- d = self.assertFailure(self.factory.deferred, ftp.PortConnectionError)
- d.addCallback(finished.append)
-
- self.factory.setTimeout(6)
-
- # Advance the clock almost to the timeout
- self.reactor.advance(5)
-
- # Nothing should have happened yet.
- self.assertFalse(finished)
-
- # Advance it to the configured timeout.
- self.reactor.advance(1)
-
- # Now the Deferred should have failed with TimeoutError.
- self.assertTrue(finished)
-
- # There should also be no calls left in the reactor.
- self.assertFalse(self.reactor.calls)
-
-
- def test_buildProtocolOnce(self):
- """
- A L{ftp.DTPFactory} instance's C{buildProtocol} method can be used once
- to create a L{ftp.DTP} instance.
- """
- protocol = self.factory.buildProtocol(None)
- self.assertIsInstance(protocol, ftp.DTP)
-
- # A subsequent call returns None.
- self.assertIdentical(self.factory.buildProtocol(None), None)
-
-
- def test_timeoutAfterConnection(self):
- """
- If a timeout has been set up using L{ftp.DTPFactory.setTimeout}, it is
- cancelled by L{ftp.DTPFactory.buildProtocol}.
- """
- self.factory.setTimeout(10)
- protocol = self.factory.buildProtocol(None)
- # Make sure the call is no longer active.
- self.assertFalse(self.reactor.calls)
-
-
- def test_connectionAfterTimeout(self):
- """
- If L{ftp.DTPFactory.buildProtocol} is called after the timeout
- specified by L{ftp.DTPFactory.setTimeout} has elapsed, C{None} is
- returned.
- """
- # Handle the error so it doesn't get logged.
- d = self.assertFailure(self.factory.deferred, ftp.PortConnectionError)
-
- # Set up the timeout and then cause it to elapse so the Deferred does
- # fail.
- self.factory.setTimeout(10)
- self.reactor.advance(10)
-
- # Try to get a protocol - we should not be able to.
- self.assertIdentical(self.factory.buildProtocol(None), None)
-
- # Make sure the Deferred is doing the right thing.
- return d
-
-
- def test_timeoutAfterConnectionFailed(self):
- """
- L{ftp.DTPFactory.deferred} fails with L{PortConnectionError} when
- L{ftp.DTPFactory.clientConnectionFailed} is called. If the timeout
- specified with L{ftp.DTPFactory.setTimeout} expires after that, nothing
- additional happens.
- """
- finished = []
- d = self.assertFailure(self.factory.deferred, ftp.PortConnectionError)
- d.addCallback(finished.append)
-
- self.factory.setTimeout(10)
- self.assertFalse(finished)
- self.factory.clientConnectionFailed(None, None)
- self.assertTrue(finished)
- self.reactor.advance(10)
- return d
-
-
- def test_connectionFailedAfterTimeout(self):
- """
- If L{ftp.DTPFactory.clientConnectionFailed} is called after the timeout
- specified by L{ftp.DTPFactory.setTimeout} has elapsed, nothing beyond
- the normal timeout before happens.
- """
- # Handle the error so it doesn't get logged.
- d = self.assertFailure(self.factory.deferred, ftp.PortConnectionError)
-
- # Set up the timeout and then cause it to elapse so the Deferred does
- # fail.
- self.factory.setTimeout(10)
- self.reactor.advance(10)
-
- # Now fail the connection attempt. This should do nothing. In
- # particular, it should not raise an exception.
- self.factory.clientConnectionFailed(None, defer.TimeoutError("foo"))
-
- # Give the Deferred to trial so it can make sure it did what we
- # expected.
- return d
-
-
-
-# -- Client Tests -----------------------------------------------------------
-
-class PrintLines(protocol.Protocol):
- """Helper class used by FTPFileListingTests."""
-
- def __init__(self, lines):
- self._lines = lines
-
- def connectionMade(self):
- for line in self._lines:
- self.transport.write(line + "\r\n")
- self.transport.loseConnection()
-
-
-class MyFTPFileListProtocol(ftp.FTPFileListProtocol):
- def __init__(self):
- self.other = []
- ftp.FTPFileListProtocol.__init__(self)
-
- def unknownLine(self, line):
- self.other.append(line)
-
-
-class FTPFileListingTests(unittest.TestCase):
- def getFilesForLines(self, lines):
- fileList = MyFTPFileListProtocol()
- d = loopback.loopbackAsync(PrintLines(lines), fileList)
- d.addCallback(lambda _: (fileList.files, fileList.other))
- return d
-
- def testOneLine(self):
- # This example line taken from the docstring for FTPFileListProtocol
- line = '-rw-r--r-- 1 root other 531 Jan 29 03:26 README'
- def check(((file,), other)):
- self.failIf(other, 'unexpect unparsable lines: %s' % repr(other))
- self.failUnless(file['filetype'] == '-', 'misparsed fileitem')
- self.failUnless(file['perms'] == 'rw-r--r--', 'misparsed perms')
- self.failUnless(file['owner'] == 'root', 'misparsed fileitem')
- self.failUnless(file['group'] == 'other', 'misparsed fileitem')
- self.failUnless(file['size'] == 531, 'misparsed fileitem')
- self.failUnless(file['date'] == 'Jan 29 03:26', 'misparsed fileitem')
- self.failUnless(file['filename'] == 'README', 'misparsed fileitem')
- self.failUnless(file['nlinks'] == 1, 'misparsed nlinks')
- self.failIf(file['linktarget'], 'misparsed linktarget')
- return self.getFilesForLines([line]).addCallback(check)
-
- def testVariantLines(self):
- line1 = 'drw-r--r-- 2 root other 531 Jan 9 2003 A'
- line2 = 'lrw-r--r-- 1 root other 1 Jan 29 03:26 B -> A'
- line3 = 'woohoo! '
- def check(((file1, file2), (other,))):
- self.failUnless(other == 'woohoo! \r', 'incorrect other line')
- # file 1
- self.failUnless(file1['filetype'] == 'd', 'misparsed fileitem')
- self.failUnless(file1['perms'] == 'rw-r--r--', 'misparsed perms')
- self.failUnless(file1['owner'] == 'root', 'misparsed owner')
- self.failUnless(file1['group'] == 'other', 'misparsed group')
- self.failUnless(file1['size'] == 531, 'misparsed size')
- self.failUnless(file1['date'] == 'Jan 9 2003', 'misparsed date')
- self.failUnless(file1['filename'] == 'A', 'misparsed filename')
- self.failUnless(file1['nlinks'] == 2, 'misparsed nlinks')
- self.failIf(file1['linktarget'], 'misparsed linktarget')
- # file 2
- self.failUnless(file2['filetype'] == 'l', 'misparsed fileitem')
- self.failUnless(file2['perms'] == 'rw-r--r--', 'misparsed perms')
- self.failUnless(file2['owner'] == 'root', 'misparsed owner')
- self.failUnless(file2['group'] == 'other', 'misparsed group')
- self.failUnless(file2['size'] == 1, 'misparsed size')
- self.failUnless(file2['date'] == 'Jan 29 03:26', 'misparsed date')
- self.failUnless(file2['filename'] == 'B', 'misparsed filename')
- self.failUnless(file2['nlinks'] == 1, 'misparsed nlinks')
- self.failUnless(file2['linktarget'] == 'A', 'misparsed linktarget')
- return self.getFilesForLines([line1, line2, line3]).addCallback(check)
-
- def testUnknownLine(self):
- def check((files, others)):
- self.failIf(files, 'unexpected file entries')
- self.failUnless(others == ['ABC\r', 'not a file\r'],
- 'incorrect unparsable lines: %s' % repr(others))
- return self.getFilesForLines(['ABC', 'not a file']).addCallback(check)
-
- def testYear(self):
- # This example derived from bug description in issue 514.
- fileList = ftp.FTPFileListProtocol()
- exampleLine = (
- '-rw-r--r-- 1 root other 531 Jan 29 2003 README\n')
- class PrintLine(protocol.Protocol):
- def connectionMade(self):
- self.transport.write(exampleLine)
- self.transport.loseConnection()
-
- def check(ignored):
- file = fileList.files[0]
- self.failUnless(file['size'] == 531, 'misparsed fileitem')
- self.failUnless(file['date'] == 'Jan 29 2003', 'misparsed fileitem')
- self.failUnless(file['filename'] == 'README', 'misparsed fileitem')
-
- d = loopback.loopbackAsync(PrintLine(), fileList)
- return d.addCallback(check)
-
-
-class FTPClientTests(unittest.TestCase):
-
- def testFailedRETR(self):
- f = protocol.Factory()
- f.noisy = 0
- port = reactor.listenTCP(0, f, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
- portNum = port.getHost().port
- # This test data derived from a bug report by ranty on #twisted
- responses = ['220 ready, dude (vsFTPd 1.0.0: beat me, break me)',
- # USER anonymous
- '331 Please specify the password.',
- # PASS twisted@twistedmatrix.com
- '230 Login successful. Have fun.',
- # TYPE I
- '200 Binary it is, then.',
- # PASV
- '227 Entering Passive Mode (127,0,0,1,%d,%d)' %
- (portNum >> 8, portNum & 0xff),
- # RETR /file/that/doesnt/exist
- '550 Failed to open file.']
- f.buildProtocol = lambda addr: PrintLines(responses)
-
- client = ftp.FTPClient(passive=1)
- cc = protocol.ClientCreator(reactor, ftp.FTPClient, passive=1)
- d = cc.connectTCP('127.0.0.1', portNum)
- def gotClient(client):
- p = protocol.Protocol()
- return client.retrieveFile('/file/that/doesnt/exist', p)
- d.addCallback(gotClient)
- return self.assertFailure(d, ftp.CommandFailed)
-
- def test_errbacksUponDisconnect(self):
- """
- Test the ftp command errbacks when a connection lost happens during
- the operation.
- """
- ftpClient = ftp.FTPClient()
- tr = proto_helpers.StringTransportWithDisconnection()
- ftpClient.makeConnection(tr)
- tr.protocol = ftpClient
- d = ftpClient.list('some path', Dummy())
- m = []
- def _eb(failure):
- m.append(failure)
- return None
- d.addErrback(_eb)
- from twisted.internet.main import CONNECTION_LOST
- ftpClient.connectionLost(failure.Failure(CONNECTION_LOST))
- self.failUnless(m, m)
- return d
-
-
-
-class FTPClientTestCase(unittest.TestCase):
- """
- Test advanced FTP client commands.
- """
- def setUp(self):
- """
- Create a FTP client and connect it to fake transport.
- """
- self.client = ftp.FTPClient()
- self.transport = proto_helpers.StringTransportWithDisconnection()
- self.client.makeConnection(self.transport)
- self.transport.protocol = self.client
-
-
- def tearDown(self):
- """
- Deliver disconnection notification to the client so that it can
- perform any cleanup which may be required.
- """
- self.client.connectionLost(error.ConnectionLost())
-
-
- def _testLogin(self):
- """
- Test the login part.
- """
- self.assertEqual(self.transport.value(), '')
- self.client.lineReceived(
- '331 Guest login ok, type your email address as password.')
- self.assertEqual(self.transport.value(), 'USER anonymous\r\n')
- self.transport.clear()
- self.client.lineReceived(
- '230 Anonymous login ok, access restrictions apply.')
- self.assertEqual(self.transport.value(), 'TYPE I\r\n')
- self.transport.clear()
- self.client.lineReceived('200 Type set to I.')
-
-
- def test_CDUP(self):
- """
- Test the CDUP command.
-
- L{ftp.FTPClient.cdup} should return a Deferred which fires with a
- sequence of one element which is the string the server sent
- indicating that the command was executed successfully.
-
- (XXX - This is a bad API)
- """
- def cbCdup(res):
- self.assertEqual(res[0], '250 Requested File Action Completed OK')
-
- self._testLogin()
- d = self.client.cdup().addCallback(cbCdup)
- self.assertEqual(self.transport.value(), 'CDUP\r\n')
- self.transport.clear()
- self.client.lineReceived('250 Requested File Action Completed OK')
- return d
-
-
- def test_failedCDUP(self):
- """
- Test L{ftp.FTPClient.cdup}'s handling of a failed CDUP command.
-
- When the CDUP command fails, the returned Deferred should errback
- with L{ftp.CommandFailed}.
- """
- self._testLogin()
- d = self.client.cdup()
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'CDUP\r\n')
- self.transport.clear()
- self.client.lineReceived('550 ..: No such file or directory')
- return d
-
-
- def test_PWD(self):
- """
- Test the PWD command.
-
- L{ftp.FTPClient.pwd} should return a Deferred which fires with a
- sequence of one element which is a string representing the current
- working directory on the server.
-
- (XXX - This is a bad API)
- """
- def cbPwd(res):
- self.assertEqual(ftp.parsePWDResponse(res[0]), "/bar/baz")
-
- self._testLogin()
- d = self.client.pwd().addCallback(cbPwd)
- self.assertEqual(self.transport.value(), 'PWD\r\n')
- self.client.lineReceived('257 "/bar/baz"')
- return d
-
-
- def test_failedPWD(self):
- """
- Test a failure in PWD command.
-
- When the PWD command fails, the returned Deferred should errback
- with L{ftp.CommandFailed}.
- """
- self._testLogin()
- d = self.client.pwd()
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PWD\r\n')
- self.client.lineReceived('550 /bar/baz: No such file or directory')
- return d
-
-
- def test_CWD(self):
- """
- Test the CWD command.
-
- L{ftp.FTPClient.cwd} should return a Deferred which fires with a
- sequence of one element which is the string the server sent
- indicating that the command was executed successfully.
-
- (XXX - This is a bad API)
- """
- def cbCwd(res):
- self.assertEqual(res[0], '250 Requested File Action Completed OK')
-
- self._testLogin()
- d = self.client.cwd("bar/foo").addCallback(cbCwd)
- self.assertEqual(self.transport.value(), 'CWD bar/foo\r\n')
- self.client.lineReceived('250 Requested File Action Completed OK')
- return d
-
-
- def test_failedCWD(self):
- """
- Test a failure in CWD command.
-
- When the PWD command fails, the returned Deferred should errback
- with L{ftp.CommandFailed}.
- """
- self._testLogin()
- d = self.client.cwd("bar/foo")
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'CWD bar/foo\r\n')
- self.client.lineReceived('550 bar/foo: No such file or directory')
- return d
-
-
- def test_passiveRETR(self):
- """
- Test the RETR command in passive mode: get a file and verify its
- content.
-
- L{ftp.FTPClient.retrieveFile} should return a Deferred which fires
- with the protocol instance passed to it after the download has
- completed.
-
- (XXX - This API should be based on producers and consumers)
- """
- def cbRetr(res, proto):
- self.assertEqual(proto.buffer, 'x' * 1000)
-
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- proto.dataReceived("x" * 1000)
- proto.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- proto = _BufferingProtocol()
- d = self.client.retrieveFile("spam", proto)
- d.addCallback(cbRetr, proto)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'RETR spam\r\n')
- self.transport.clear()
- self.client.lineReceived('226 Transfer Complete.')
- return d
-
-
- def test_RETR(self):
- """
- Test the RETR command in non-passive mode.
-
- Like L{test_passiveRETR} but in the configuration where the server
- establishes the data connection to the client, rather than the other
- way around.
- """
- self.client.passive = False
-
- def generatePort(portCmd):
- portCmd.text = 'PORT %s' % (ftp.encodeHostPort('127.0.0.1', 9876),)
- portCmd.protocol.makeConnection(proto_helpers.StringTransport())
- portCmd.protocol.dataReceived("x" * 1000)
- portCmd.protocol.connectionLost(
- failure.Failure(error.ConnectionDone("")))
-
- def cbRetr(res, proto):
- self.assertEqual(proto.buffer, 'x' * 1000)
-
- self.client.generatePortCommand = generatePort
- self._testLogin()
- proto = _BufferingProtocol()
- d = self.client.retrieveFile("spam", proto)
- d.addCallback(cbRetr, proto)
- self.assertEqual(self.transport.value(), 'PORT %s\r\n' %
- (ftp.encodeHostPort('127.0.0.1', 9876),))
- self.transport.clear()
- self.client.lineReceived('200 PORT OK')
- self.assertEqual(self.transport.value(), 'RETR spam\r\n')
- self.transport.clear()
- self.client.lineReceived('226 Transfer Complete.')
- return d
-
-
- def test_failedRETR(self):
- """
- Try to RETR an unexisting file.
-
- L{ftp.FTPClient.retrieveFile} should return a Deferred which
- errbacks with L{ftp.CommandFailed} if the server indicates the file
- cannot be transferred for some reason.
- """
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- proto.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- proto = _BufferingProtocol()
- d = self.client.retrieveFile("spam", proto)
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'RETR spam\r\n')
- self.transport.clear()
- self.client.lineReceived('550 spam: No such file or directory')
- return d
-
-
- def test_lostRETR(self):
- """
- Try a RETR, but disconnect during the transfer.
- L{ftp.FTPClient.retrieveFile} should return a Deferred which
- errbacks with L{ftp.ConnectionLost)
- """
- self.client.passive = False
-
- l = []
- def generatePort(portCmd):
- portCmd.text = 'PORT %s' % (ftp.encodeHostPort('127.0.0.1', 9876),)
- tr = proto_helpers.StringTransportWithDisconnection()
- portCmd.protocol.makeConnection(tr)
- tr.protocol = portCmd.protocol
- portCmd.protocol.dataReceived("x" * 500)
- l.append(tr)
-
- self.client.generatePortCommand = generatePort
- self._testLogin()
- proto = _BufferingProtocol()
- d = self.client.retrieveFile("spam", proto)
- self.assertEqual(self.transport.value(), 'PORT %s\r\n' %
- (ftp.encodeHostPort('127.0.0.1', 9876),))
- self.transport.clear()
- self.client.lineReceived('200 PORT OK')
- self.assertEqual(self.transport.value(), 'RETR spam\r\n')
-
- self.assert_(l)
- l[0].loseConnection()
- self.transport.loseConnection()
- self.assertFailure(d, ftp.ConnectionLost)
- return d
-
-
- def test_passiveSTOR(self):
- """
- Test the STOR command: send a file and verify its content.
-
- L{ftp.FTPClient.storeFile} should return a two-tuple of Deferreds.
- The first of which should fire with a protocol instance when the
- data connection has been established and is responsible for sending
- the contents of the file. The second of which should fire when the
- upload has completed, the data connection has been closed, and the
- server has acknowledged receipt of the file.
-
- (XXX - storeFile should take a producer as an argument, instead, and
- only return a Deferred which fires when the upload has succeeded or
- failed).
- """
- tr = proto_helpers.StringTransport()
- def cbStore(sender):
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- sender.transport.write("x" * 1000)
- sender.finish()
- sender.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- def cbFinish(ign):
- self.assertEqual(tr.value(), "x" * 1000)
-
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(tr)
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- d1, d2 = self.client.storeFile("spam")
- d1.addCallback(cbStore)
- d2.addCallback(cbFinish)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'STOR spam\r\n')
- self.transport.clear()
- self.client.lineReceived('226 Transfer Complete.')
- return defer.gatherResults([d1, d2])
-
-
- def test_failedSTOR(self):
- """
- Test a failure in the STOR command.
-
- If the server does not acknowledge successful receipt of the
- uploaded file, the second Deferred returned by
- L{ftp.FTPClient.storeFile} should errback with L{ftp.CommandFailed}.
- """
- tr = proto_helpers.StringTransport()
- def cbStore(sender):
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- sender.transport.write("x" * 1000)
- sender.finish()
- sender.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(tr)
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- d1, d2 = self.client.storeFile("spam")
- d1.addCallback(cbStore)
- self.assertFailure(d2, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'STOR spam\r\n')
- self.transport.clear()
- self.client.lineReceived(
- '426 Transfer aborted. Data connection closed.')
- return defer.gatherResults([d1, d2])
-
-
- def test_STOR(self):
- """
- Test the STOR command in non-passive mode.
-
- Like L{test_passiveSTOR} but in the configuration where the server
- establishes the data connection to the client, rather than the other
- way around.
- """
- tr = proto_helpers.StringTransport()
- self.client.passive = False
- def generatePort(portCmd):
- portCmd.text = 'PORT %s' % ftp.encodeHostPort('127.0.0.1', 9876)
- portCmd.protocol.makeConnection(tr)
-
- def cbStore(sender):
- self.assertEqual(self.transport.value(), 'PORT %s\r\n' %
- (ftp.encodeHostPort('127.0.0.1', 9876),))
- self.transport.clear()
- self.client.lineReceived('200 PORT OK')
- self.assertEqual(self.transport.value(), 'STOR spam\r\n')
- self.transport.clear()
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- sender.transport.write("x" * 1000)
- sender.finish()
- sender.connectionLost(failure.Failure(error.ConnectionDone("")))
- self.client.lineReceived('226 Transfer Complete.')
-
- def cbFinish(ign):
- self.assertEqual(tr.value(), "x" * 1000)
-
- self.client.generatePortCommand = generatePort
- self._testLogin()
- d1, d2 = self.client.storeFile("spam")
- d1.addCallback(cbStore)
- d2.addCallback(cbFinish)
- return defer.gatherResults([d1, d2])
-
-
- def test_passiveLIST(self):
- """
- Test the LIST command.
-
- L{ftp.FTPClient.list} should return a Deferred which fires with a
- protocol instance which was passed to list after the command has
- succeeded.
-
- (XXX - This is a very unfortunate API; if my understanding is
- correct, the results are always at least line-oriented, so allowing
- a per-line parser function to be specified would make this simpler,
- but a default implementation should really be provided which knows
- how to deal with all the formats used in real servers, so
- application developers never have to care about this insanity. It
- would also be nice to either get back a Deferred of a list of
- filenames or to be able to consume the files as they are received
- (which the current API does allow, but in a somewhat inconvenient
- fashion) -exarkun)
- """
- def cbList(res, fileList):
- fls = [f["filename"] for f in fileList.files]
- expected = ["foo", "bar", "baz"]
- expected.sort()
- fls.sort()
- self.assertEqual(fls, expected)
-
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- sending = [
- '-rw-r--r-- 0 spam egg 100 Oct 10 2006 foo\r\n',
- '-rw-r--r-- 3 spam egg 100 Oct 10 2006 bar\r\n',
- '-rw-r--r-- 4 spam egg 100 Oct 10 2006 baz\r\n',
- ]
- for i in sending:
- proto.dataReceived(i)
- proto.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- fileList = ftp.FTPFileListProtocol()
- d = self.client.list('foo/bar', fileList).addCallback(cbList, fileList)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'LIST foo/bar\r\n')
- self.client.lineReceived('226 Transfer Complete.')
- return d
-
-
- def test_LIST(self):
- """
- Test the LIST command in non-passive mode.
-
- Like L{test_passiveLIST} but in the configuration where the server
- establishes the data connection to the client, rather than the other
- way around.
- """
- self.client.passive = False
- def generatePort(portCmd):
- portCmd.text = 'PORT %s' % (ftp.encodeHostPort('127.0.0.1', 9876),)
- portCmd.protocol.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- sending = [
- '-rw-r--r-- 0 spam egg 100 Oct 10 2006 foo\r\n',
- '-rw-r--r-- 3 spam egg 100 Oct 10 2006 bar\r\n',
- '-rw-r--r-- 4 spam egg 100 Oct 10 2006 baz\r\n',
- ]
- for i in sending:
- portCmd.protocol.dataReceived(i)
- portCmd.protocol.connectionLost(
- failure.Failure(error.ConnectionDone("")))
-
- def cbList(res, fileList):
- fls = [f["filename"] for f in fileList.files]
- expected = ["foo", "bar", "baz"]
- expected.sort()
- fls.sort()
- self.assertEqual(fls, expected)
-
- self.client.generatePortCommand = generatePort
- self._testLogin()
- fileList = ftp.FTPFileListProtocol()
- d = self.client.list('foo/bar', fileList).addCallback(cbList, fileList)
- self.assertEqual(self.transport.value(), 'PORT %s\r\n' %
- (ftp.encodeHostPort('127.0.0.1', 9876),))
- self.transport.clear()
- self.client.lineReceived('200 PORT OK')
- self.assertEqual(self.transport.value(), 'LIST foo/bar\r\n')
- self.transport.clear()
- self.client.lineReceived('226 Transfer Complete.')
- return d
-
-
- def test_failedLIST(self):
- """
- Test a failure in LIST command.
-
- L{ftp.FTPClient.list} should return a Deferred which fails with
- L{ftp.CommandFailed} if the server indicates the indicated path is
- invalid for some reason.
- """
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- proto.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- fileList = ftp.FTPFileListProtocol()
- d = self.client.list('foo/bar', fileList)
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'LIST foo/bar\r\n')
- self.client.lineReceived('550 foo/bar: No such file or directory')
- return d
-
-
- def test_NLST(self):
- """
- Test the NLST command in non-passive mode.
-
- L{ftp.FTPClient.nlst} should return a Deferred which fires with a
- list of filenames when the list command has completed.
- """
- self.client.passive = False
- def generatePort(portCmd):
- portCmd.text = 'PORT %s' % (ftp.encodeHostPort('127.0.0.1', 9876),)
- portCmd.protocol.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- portCmd.protocol.dataReceived('foo\r\n')
- portCmd.protocol.dataReceived('bar\r\n')
- portCmd.protocol.dataReceived('baz\r\n')
- portCmd.protocol.connectionLost(
- failure.Failure(error.ConnectionDone("")))
-
- def cbList(res, proto):
- fls = proto.buffer.splitlines()
- expected = ["foo", "bar", "baz"]
- expected.sort()
- fls.sort()
- self.assertEqual(fls, expected)
-
- self.client.generatePortCommand = generatePort
- self._testLogin()
- lstproto = _BufferingProtocol()
- d = self.client.nlst('foo/bar', lstproto).addCallback(cbList, lstproto)
- self.assertEqual(self.transport.value(), 'PORT %s\r\n' %
- (ftp.encodeHostPort('127.0.0.1', 9876),))
- self.transport.clear()
- self.client.lineReceived('200 PORT OK')
- self.assertEqual(self.transport.value(), 'NLST foo/bar\r\n')
- self.client.lineReceived('226 Transfer Complete.')
- return d
-
-
- def test_passiveNLST(self):
- """
- Test the NLST command.
-
- Like L{test_passiveNLST} but in the configuration where the server
- establishes the data connection to the client, rather than the other
- way around.
- """
- def cbList(res, proto):
- fls = proto.buffer.splitlines()
- expected = ["foo", "bar", "baz"]
- expected.sort()
- fls.sort()
- self.assertEqual(fls, expected)
-
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(proto_helpers.StringTransport())
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- proto.dataReceived('foo\r\n')
- proto.dataReceived('bar\r\n')
- proto.dataReceived('baz\r\n')
- proto.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- lstproto = _BufferingProtocol()
- d = self.client.nlst('foo/bar', lstproto).addCallback(cbList, lstproto)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'NLST foo/bar\r\n')
- self.client.lineReceived('226 Transfer Complete.')
- return d
-
-
- def test_failedNLST(self):
- """
- Test a failure in NLST command.
-
- L{ftp.FTPClient.nlst} should return a Deferred which fails with
- L{ftp.CommandFailed} if the server indicates the indicated path is
- invalid for some reason.
- """
- tr = proto_helpers.StringTransport()
- def cbConnect(host, port, factory):
- self.assertEqual(host, '127.0.0.1')
- self.assertEqual(port, 12345)
- proto = factory.buildProtocol((host, port))
- proto.makeConnection(tr)
- self.client.lineReceived(
- '150 File status okay; about to open data connection.')
- proto.connectionLost(failure.Failure(error.ConnectionDone("")))
-
- self.client.connectFactory = cbConnect
- self._testLogin()
- lstproto = _BufferingProtocol()
- d = self.client.nlst('foo/bar', lstproto)
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PASV\r\n')
- self.transport.clear()
- self.client.lineReceived('227 Entering Passive Mode (%s).' %
- (ftp.encodeHostPort('127.0.0.1', 12345),))
- self.assertEqual(self.transport.value(), 'NLST foo/bar\r\n')
- self.client.lineReceived('550 foo/bar: No such file or directory')
- return d
-
-
- def test_changeDirectoryDeprecated(self):
- """
- L{ftp.FTPClient.changeDirectory} is deprecated and the direct caller of
- it is warned of this.
- """
- self._testLogin()
- d = self.assertWarns(
- DeprecationWarning,
- "FTPClient.changeDirectory is deprecated in Twisted 8.2 and "
- "newer. Use FTPClient.cwd instead.",
- __file__,
- lambda: self.client.changeDirectory('.'))
- # This is necessary to make the Deferred fire. The Deferred needs
- # to fire so that tearDown doesn't cause it to errback and fail this
- # or (more likely) a later test.
- self.client.lineReceived('250 success')
- return d
-
-
- def test_changeDirectory(self):
- """
- Test the changeDirectory method.
-
- L{ftp.FTPClient.changeDirectory} should return a Deferred which fires
- with True if succeeded.
- """
- def cbCd(res):
- self.assertEqual(res, True)
-
- self._testLogin()
- d = self.client.changeDirectory("bar/foo").addCallback(cbCd)
- self.assertEqual(self.transport.value(), 'CWD bar/foo\r\n')
- self.client.lineReceived('250 Requested File Action Completed OK')
- return d
- test_changeDirectory.suppress = [_changeDirectorySuppression]
-
-
- def test_failedChangeDirectory(self):
- """
- Test a failure in the changeDirectory method.
-
- The behaviour here is the same as a failed CWD.
- """
- self._testLogin()
- d = self.client.changeDirectory("bar/foo")
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'CWD bar/foo\r\n')
- self.client.lineReceived('550 bar/foo: No such file or directory')
- return d
- test_failedChangeDirectory.suppress = [_changeDirectorySuppression]
-
-
- def test_strangeFailedChangeDirectory(self):
- """
- Test a strange failure in changeDirectory method.
-
- L{ftp.FTPClient.changeDirectory} is stricter than CWD as it checks
- code 250 for success.
- """
- self._testLogin()
- d = self.client.changeDirectory("bar/foo")
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'CWD bar/foo\r\n')
- self.client.lineReceived('252 I do what I want !')
- return d
- test_strangeFailedChangeDirectory.suppress = [_changeDirectorySuppression]
-
-
- def test_renameFromTo(self):
- """
- L{ftp.FTPClient.rename} issues I{RNTO} and I{RNFR} commands and returns
- a L{Deferred} which fires when a file has successfully been renamed.
- """
- self._testLogin()
-
- d = self.client.rename("/spam", "/ham")
- self.assertEqual(self.transport.value(), 'RNFR /spam\r\n')
- self.transport.clear()
-
- fromResponse = (
- '350 Requested file action pending further information.\r\n')
- self.client.lineReceived(fromResponse)
- self.assertEqual(self.transport.value(), 'RNTO /ham\r\n')
- toResponse = (
- '250 Requested File Action Completed OK')
- self.client.lineReceived(toResponse)
-
- d.addCallback(self.assertEqual, ([fromResponse], [toResponse]))
- return d
-
-
- def test_renameFromToEscapesPaths(self):
- """
- L{ftp.FTPClient.rename} issues I{RNTO} and I{RNFR} commands with paths
- escaped according to U{http://cr.yp.to/ftp/filesystem.html}.
- """
- self._testLogin()
-
- fromFile = "/foo/ba\nr/baz"
- toFile = "/qu\nux"
- self.client.rename(fromFile, toFile)
- self.client.lineReceived("350 ")
- self.client.lineReceived("250 ")
- self.assertEqual(
- self.transport.value(),
- "RNFR /foo/ba\x00r/baz\r\n"
- "RNTO /qu\x00ux\r\n")
-
-
- def test_renameFromToFailingOnFirstError(self):
- """
- The L{Deferred} returned by L{ftp.FTPClient.rename} is errbacked with
- L{CommandFailed} if the I{RNFR} command receives an error response code
- (for example, because the file does not exist).
- """
- self._testLogin()
-
- d = self.client.rename("/spam", "/ham")
- self.assertEqual(self.transport.value(), 'RNFR /spam\r\n')
- self.transport.clear()
-
- self.client.lineReceived('550 Requested file unavailable.\r\n')
- # The RNTO should not execute since the RNFR failed.
- self.assertEqual(self.transport.value(), '')
-
- return self.assertFailure(d, ftp.CommandFailed)
-
-
- def test_renameFromToFailingOnRenameTo(self):
- """
- The L{Deferred} returned by L{ftp.FTPClient.rename} is errbacked with
- L{CommandFailed} if the I{RNTO} command receives an error response code
- (for example, because the destination directory does not exist).
- """
- self._testLogin()
-
- d = self.client.rename("/spam", "/ham")
- self.assertEqual(self.transport.value(), 'RNFR /spam\r\n')
- self.transport.clear()
-
- self.client.lineReceived('350 Requested file action pending further information.\r\n')
- self.assertEqual(self.transport.value(), 'RNTO /ham\r\n')
- self.client.lineReceived('550 Requested file unavailable.\r\n')
- return self.assertFailure(d, ftp.CommandFailed)
-
-
- def test_makeDirectory(self):
- """
- L{ftp.FTPClient.makeDirectory} issues a I{MKD} command and returns a
- L{Deferred} which is called back with the server's response if the
- directory is created.
- """
- self._testLogin()
-
- d = self.client.makeDirectory("/spam")
- self.assertEqual(self.transport.value(), 'MKD /spam\r\n')
- self.client.lineReceived('257 "/spam" created.')
- return d.addCallback(self.assertEqual, ['257 "/spam" created.'])
-
-
- def test_makeDirectoryPathEscape(self):
- """
- L{ftp.FTPClient.makeDirectory} escapes the path name it sends according
- to U{http://cr.yp.to/ftp/filesystem.html}.
- """
- self._testLogin()
- d = self.client.makeDirectory("/sp\nam")
- self.assertEqual(self.transport.value(), 'MKD /sp\x00am\r\n')
- # This is necessary to make the Deferred fire. The Deferred needs
- # to fire so that tearDown doesn't cause it to errback and fail this
- # or (more likely) a later test.
- self.client.lineReceived('257 win')
- return d
-
-
- def test_failedMakeDirectory(self):
- """
- L{ftp.FTPClient.makeDirectory} returns a L{Deferred} which is errbacked
- with L{CommandFailed} if the server returns an error response code.
- """
- self._testLogin()
-
- d = self.client.makeDirectory("/spam")
- self.assertEqual(self.transport.value(), 'MKD /spam\r\n')
- self.client.lineReceived('550 PERMISSION DENIED')
- return self.assertFailure(d, ftp.CommandFailed)
-
-
- def test_getDirectory(self):
- """
- Test the getDirectory method.
-
- L{ftp.FTPClient.getDirectory} should return a Deferred which fires with
- the current directory on the server. It wraps PWD command.
- """
- def cbGet(res):
- self.assertEqual(res, "/bar/baz")
-
- self._testLogin()
- d = self.client.getDirectory().addCallback(cbGet)
- self.assertEqual(self.transport.value(), 'PWD\r\n')
- self.client.lineReceived('257 "/bar/baz"')
- return d
-
-
- def test_failedGetDirectory(self):
- """
- Test a failure in getDirectory method.
-
- The behaviour should be the same as PWD.
- """
- self._testLogin()
- d = self.client.getDirectory()
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PWD\r\n')
- self.client.lineReceived('550 /bar/baz: No such file or directory')
- return d
-
-
- def test_anotherFailedGetDirectory(self):
- """
- Test a different failure in getDirectory method.
-
- The response should be quoted to be parsed, so it returns an error
- otherwise.
- """
- self._testLogin()
- d = self.client.getDirectory()
- self.assertFailure(d, ftp.CommandFailed)
- self.assertEqual(self.transport.value(), 'PWD\r\n')
- self.client.lineReceived('257 /bar/baz')
- return d
-
-
- def test_removeFile(self):
- """
- L{ftp.FTPClient.removeFile} sends a I{DELE} command to the server for
- the indicated file and returns a Deferred which fires after the server
- sends a 250 response code.
- """
- self._testLogin()
- d = self.client.removeFile("/tmp/test")
- self.assertEqual(self.transport.value(), 'DELE /tmp/test\r\n')
- response = '250 Requested file action okay, completed.'
- self.client.lineReceived(response)
- return d.addCallback(self.assertEqual, [response])
-
-
- def test_failedRemoveFile(self):
- """
- If the server returns a response code other than 250 in response to a
- I{DELE} sent by L{ftp.FTPClient.removeFile}, the L{Deferred} returned
- by C{removeFile} is errbacked with a L{Failure} wrapping a
- L{CommandFailed}.
- """
- self._testLogin()
- d = self.client.removeFile("/tmp/test")
- self.assertEqual(self.transport.value(), 'DELE /tmp/test\r\n')
- response = '501 Syntax error in parameters or arguments.'
- self.client.lineReceived(response)
- d = self.assertFailure(d, ftp.CommandFailed)
- d.addCallback(lambda exc: self.assertEqual(exc.args, ([response],)))
- return d
-
-
- def test_unparsableRemoveFileResponse(self):
- """
- If the server returns a response line which cannot be parsed, the
- L{Deferred} returned by L{ftp.FTPClient.removeFile} is errbacked with a
- L{BadResponse} containing the response.
- """
- self._testLogin()
- d = self.client.removeFile("/tmp/test")
- response = '765 blah blah blah'
- self.client.lineReceived(response)
- d = self.assertFailure(d, ftp.BadResponse)
- d.addCallback(lambda exc: self.assertEqual(exc.args, ([response],)))
- return d
-
-
- def test_multilineRemoveFileResponse(self):
- """
- If the server returns multiple response lines, the L{Deferred} returned
- by L{ftp.FTPClient.removeFile} is still fired with a true value if the
- ultimate response code is 250.
- """
- self._testLogin()
- d = self.client.removeFile("/tmp/test")
- response = ['250-perhaps a progress report',
- '250 okay']
- map(self.client.lineReceived, response)
- return d.addCallback(self.assertTrue)
-
-
- def test_removeDirectory(self):
- """
- L{ftp.FTPClient.removeDirectory} sends a I{RMD} command to the server
- for the indicated directory and returns a Deferred which fires after
- the server sends a 250 response code.
- """
- self._testLogin()
- d = self.client.removeDirectory('/tmp/test')
- self.assertEqual(self.transport.value(), 'RMD /tmp/test\r\n')
- response = '250 Requested file action okay, completed.'
- self.client.lineReceived(response)
- return d.addCallback(self.assertEqual, [response])
-
-
- def test_failedRemoveDirectory(self):
- """
- If the server returns a response code other than 250 in response to a
- I{RMD} sent by L{ftp.FTPClient.removeDirectory}, the L{Deferred}
- returned by C{removeDirectory} is errbacked with a L{Failure} wrapping
- a L{CommandFailed}.
- """
- self._testLogin()
- d = self.client.removeDirectory("/tmp/test")
- self.assertEqual(self.transport.value(), 'RMD /tmp/test\r\n')
- response = '501 Syntax error in parameters or arguments.'
- self.client.lineReceived(response)
- d = self.assertFailure(d, ftp.CommandFailed)
- d.addCallback(lambda exc: self.assertEqual(exc.args, ([response],)))
- return d
-
-
- def test_unparsableRemoveDirectoryResponse(self):
- """
- If the server returns a response line which cannot be parsed, the
- L{Deferred} returned by L{ftp.FTPClient.removeDirectory} is errbacked
- with a L{BadResponse} containing the response.
- """
- self._testLogin()
- d = self.client.removeDirectory("/tmp/test")
- response = '765 blah blah blah'
- self.client.lineReceived(response)
- d = self.assertFailure(d, ftp.BadResponse)
- d.addCallback(lambda exc: self.assertEqual(exc.args, ([response],)))
- return d
-
-
- def test_multilineRemoveDirectoryResponse(self):
- """
- If the server returns multiple response lines, the L{Deferred} returned
- by L{ftp.FTPClient.removeDirectory} is still fired with a true value
- if the ultimate response code is 250.
- """
- self._testLogin()
- d = self.client.removeDirectory("/tmp/test")
- response = ['250-perhaps a progress report',
- '250 okay']
- map(self.client.lineReceived, response)
- return d.addCallback(self.assertTrue)
-
-
-
-class FTPClientBasicTests(unittest.TestCase):
-
- def testGreeting(self):
- # The first response is captured as a greeting.
- ftpClient = ftp.FTPClientBasic()
- ftpClient.lineReceived('220 Imaginary FTP.')
- self.assertEqual(['220 Imaginary FTP.'], ftpClient.greeting)
-
- def testResponseWithNoMessage(self):
- # Responses with no message are still valid, i.e. three digits followed
- # by a space is complete response.
- ftpClient = ftp.FTPClientBasic()
- ftpClient.lineReceived('220 ')
- self.assertEqual(['220 '], ftpClient.greeting)
-
- def testMultilineResponse(self):
- ftpClient = ftp.FTPClientBasic()
- ftpClient.transport = proto_helpers.StringTransport()
- ftpClient.lineReceived('220 Imaginary FTP.')
-
- # Queue (and send) a dummy command, and set up a callback to capture the
- # result
- deferred = ftpClient.queueStringCommand('BLAH')
- result = []
- deferred.addCallback(result.append)
- deferred.addErrback(self.fail)
-
- # Send the first line of a multiline response.
- ftpClient.lineReceived('210-First line.')
- self.assertEqual([], result)
-
- # Send a second line, again prefixed with "nnn-".
- ftpClient.lineReceived('123-Second line.')
- self.assertEqual([], result)
-
- # Send a plain line of text, no prefix.
- ftpClient.lineReceived('Just some text.')
- self.assertEqual([], result)
-
- # Now send a short (less than 4 chars) line.
- ftpClient.lineReceived('Hi')
- self.assertEqual([], result)
-
- # Now send an empty line.
- ftpClient.lineReceived('')
- self.assertEqual([], result)
-
- # And a line with 3 digits in it, and nothing else.
- ftpClient.lineReceived('321')
- self.assertEqual([], result)
-
- # Now finish it.
- ftpClient.lineReceived('210 Done.')
- self.assertEqual(
- ['210-First line.',
- '123-Second line.',
- 'Just some text.',
- 'Hi',
- '',
- '321',
- '210 Done.'], result[0])
-
-
- def test_noPasswordGiven(self):
- """
- Passing None as the password avoids sending the PASS command.
- """
- # Create a client, and give it a greeting.
- ftpClient = ftp.FTPClientBasic()
- ftpClient.transport = proto_helpers.StringTransport()
- ftpClient.lineReceived('220 Welcome to Imaginary FTP.')
-
- # Queue a login with no password
- ftpClient.queueLogin('bob', None)
- self.assertEqual('USER bob\r\n', ftpClient.transport.value())
-
- # Clear the test buffer, acknowledge the USER command.
- ftpClient.transport.clear()
- ftpClient.lineReceived('200 Hello bob.')
-
- # The client shouldn't have sent anything more (i.e. it shouldn't have
- # sent a PASS command).
- self.assertEqual('', ftpClient.transport.value())
-
-
- def test_noPasswordNeeded(self):
- """
- Receiving a 230 response to USER prevents PASS from being sent.
- """
- # Create a client, and give it a greeting.
- ftpClient = ftp.FTPClientBasic()
- ftpClient.transport = proto_helpers.StringTransport()
- ftpClient.lineReceived('220 Welcome to Imaginary FTP.')
-
- # Queue a login with no password
- ftpClient.queueLogin('bob', 'secret')
- self.assertEqual('USER bob\r\n', ftpClient.transport.value())
-
- # Clear the test buffer, acknowledge the USER command with a 230
- # response code.
- ftpClient.transport.clear()
- ftpClient.lineReceived('230 Hello bob. No password needed.')
-
- # The client shouldn't have sent anything more (i.e. it shouldn't have
- # sent a PASS command).
- self.assertEqual('', ftpClient.transport.value())
-
-
-
-class PathHandling(unittest.TestCase):
- def testNormalizer(self):
- for inp, outp in [('a', ['a']),
- ('/a', ['a']),
- ('/', []),
- ('a/b/c', ['a', 'b', 'c']),
- ('/a/b/c', ['a', 'b', 'c']),
- ('/a/', ['a']),
- ('a/', ['a'])]:
- self.assertEqual(ftp.toSegments([], inp), outp)
-
- for inp, outp in [('b', ['a', 'b']),
- ('b/', ['a', 'b']),
- ('/b', ['b']),
- ('/b/', ['b']),
- ('b/c', ['a', 'b', 'c']),
- ('b/c/', ['a', 'b', 'c']),
- ('/b/c', ['b', 'c']),
- ('/b/c/', ['b', 'c'])]:
- self.assertEqual(ftp.toSegments(['a'], inp), outp)
-
- for inp, outp in [('//', []),
- ('//a', ['a']),
- ('a//', ['a']),
- ('a//b', ['a', 'b'])]:
- self.assertEqual(ftp.toSegments([], inp), outp)
-
- for inp, outp in [('//', []),
- ('//b', ['b']),
- ('b//c', ['a', 'b', 'c'])]:
- self.assertEqual(ftp.toSegments(['a'], inp), outp)
-
- for inp, outp in [('..', []),
- ('../', []),
- ('a/..', ['x']),
- ('/a/..', []),
- ('/a/b/..', ['a']),
- ('/a/b/../', ['a']),
- ('/a/b/../c', ['a', 'c']),
- ('/a/b/../c/', ['a', 'c']),
- ('/a/b/../../c', ['c']),
- ('/a/b/../../c/', ['c']),
- ('/a/b/../../c/..', []),
- ('/a/b/../../c/../', [])]:
- self.assertEqual(ftp.toSegments(['x'], inp), outp)
-
- for inp in ['..', '../', 'a/../..', 'a/../../',
- '/..', '/../', '/a/../..', '/a/../../',
- '/a/b/../../..']:
- self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp)
-
- for inp in ['../..', '../../', '../a/../..']:
- self.assertRaises(ftp.InvalidPath, ftp.toSegments, ['x'], inp)
-
-
-class BaseFTPRealmTests(unittest.TestCase):
- """
- Tests for L{ftp.BaseFTPRealm}, a base class to help define L{IFTPShell}
- realms with different user home directory policies.
- """
- def test_interface(self):
- """
- L{ftp.BaseFTPRealm} implements L{IRealm}.
- """
- self.assertTrue(verifyClass(IRealm, ftp.BaseFTPRealm))
-
-
- def test_getHomeDirectory(self):
- """
- L{ftp.BaseFTPRealm} calls its C{getHomeDirectory} method with the
- avatarId being requested to determine the home directory for that
- avatar.
- """
- result = filepath.FilePath(self.mktemp())
- avatars = []
- class TestRealm(ftp.BaseFTPRealm):
- def getHomeDirectory(self, avatarId):
- avatars.append(avatarId)
- return result
-
- realm = TestRealm(self.mktemp())
- iface, avatar, logout = realm.requestAvatar(
- "alice@example.com", None, ftp.IFTPShell)
- self.assertIsInstance(avatar, ftp.FTPShell)
- self.assertEqual(avatar.filesystemRoot, result)
-
-
- def test_anonymous(self):
- """
- L{ftp.BaseFTPRealm} returns an L{ftp.FTPAnonymousShell} instance for
- anonymous avatar requests.
- """
- anonymous = self.mktemp()
- realm = ftp.BaseFTPRealm(anonymous)
- iface, avatar, logout = realm.requestAvatar(
- checkers.ANONYMOUS, None, ftp.IFTPShell)
- self.assertIsInstance(avatar, ftp.FTPAnonymousShell)
- self.assertEqual(avatar.filesystemRoot, filepath.FilePath(anonymous))
-
-
- def test_notImplemented(self):
- """
- L{ftp.BaseFTPRealm.getHomeDirectory} should be overridden by a subclass
- and raises L{NotImplementedError} if it is not.
- """
- realm = ftp.BaseFTPRealm(self.mktemp())
- self.assertRaises(NotImplementedError, realm.getHomeDirectory, object())
-
-
-
-class FTPRealmTestCase(unittest.TestCase):
- """
- Tests for L{ftp.FTPRealm}.
- """
- def test_getHomeDirectory(self):
- """
- L{ftp.FTPRealm} accepts an extra directory to its initializer and treats
- the avatarId passed to L{ftp.FTPRealm.getHomeDirectory} as a single path
- segment to construct a child of that directory.
- """
- base = '/path/to/home'
- realm = ftp.FTPRealm(self.mktemp(), base)
- home = realm.getHomeDirectory('alice@example.com')
- self.assertEqual(
- filepath.FilePath(base).child('alice@example.com'), home)
-
-
- def test_defaultHomeDirectory(self):
- """
- If no extra directory is passed to L{ftp.FTPRealm}, it uses C{"/home"}
- as the base directory containing all user home directories.
- """
- realm = ftp.FTPRealm(self.mktemp())
- home = realm.getHomeDirectory('alice@example.com')
- self.assertEqual(filepath.FilePath('/home/alice@example.com'), home)
-
-
-
-class SystemFTPRealmTests(unittest.TestCase):
- """
- Tests for L{ftp.SystemFTPRealm}.
- """
- skip = nonPOSIXSkip
-
- def test_getHomeDirectory(self):
- """
- L{ftp.SystemFTPRealm.getHomeDirectory} treats the avatarId passed to it
- as a username in the underlying platform and returns that account's home
- directory.
- """
- # Try to pick a username that will have a home directory.
- user = getpass.getuser()
-
- # Try to find their home directory in a different way than used by the
- # implementation. Maybe this is silly and can only introduce spurious
- # failures due to system-specific configurations.
- import pwd
- expected = pwd.getpwnam(user).pw_dir
-
- realm = ftp.SystemFTPRealm(self.mktemp())
- home = realm.getHomeDirectory(user)
- self.assertEqual(home, filepath.FilePath(expected))
-
-
- def test_noSuchUser(self):
- """
- L{ftp.SystemFTPRealm.getHomeDirectory} raises L{UnauthorizedLogin} when
- passed a username which has no corresponding home directory in the
- system's accounts database.
- """
- user = insecureRandom(4).encode('hex')
- realm = ftp.SystemFTPRealm(self.mktemp())
- self.assertRaises(UnauthorizedLogin, realm.getHomeDirectory, user)
-
-
-
-class ErrnoToFailureTestCase(unittest.TestCase):
- """
- Tests for L{ftp.errnoToFailure} errno checking.
- """
-
- def test_notFound(self):
- """
- C{errno.ENOENT} should be translated to L{ftp.FileNotFoundError}.
- """
- d = ftp.errnoToFailure(errno.ENOENT, "foo")
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_permissionDenied(self):
- """
- C{errno.EPERM} should be translated to L{ftp.PermissionDeniedError}.
- """
- d = ftp.errnoToFailure(errno.EPERM, "foo")
- return self.assertFailure(d, ftp.PermissionDeniedError)
-
-
- def test_accessDenied(self):
- """
- C{errno.EACCES} should be translated to L{ftp.PermissionDeniedError}.
- """
- d = ftp.errnoToFailure(errno.EACCES, "foo")
- return self.assertFailure(d, ftp.PermissionDeniedError)
-
-
- def test_notDirectory(self):
- """
- C{errno.ENOTDIR} should be translated to L{ftp.IsNotADirectoryError}.
- """
- d = ftp.errnoToFailure(errno.ENOTDIR, "foo")
- return self.assertFailure(d, ftp.IsNotADirectoryError)
-
-
- def test_fileExists(self):
- """
- C{errno.EEXIST} should be translated to L{ftp.FileExistsError}.
- """
- d = ftp.errnoToFailure(errno.EEXIST, "foo")
- return self.assertFailure(d, ftp.FileExistsError)
-
-
- def test_isDirectory(self):
- """
- C{errno.EISDIR} should be translated to L{ftp.IsADirectoryError}.
- """
- d = ftp.errnoToFailure(errno.EISDIR, "foo")
- return self.assertFailure(d, ftp.IsADirectoryError)
-
-
- def test_passThrough(self):
- """
- If an unknown errno is passed to L{ftp.errnoToFailure}, it should let
- the originating exception pass through.
- """
- try:
- raise RuntimeError("bar")
- except:
- d = ftp.errnoToFailure(-1, "foo")
- return self.assertFailure(d, RuntimeError)
-
-
-
-class AnonymousFTPShellTestCase(unittest.TestCase):
- """
- Test anynomous shell properties.
- """
-
- def test_anonymousWrite(self):
- """
- Check that L{ftp.FTPAnonymousShell} returns an error when trying to
- open it in write mode.
- """
- shell = ftp.FTPAnonymousShell('')
- d = shell.openForWriting(('foo',))
- self.assertFailure(d, ftp.PermissionDeniedError)
- return d
-
-
-
-class IFTPShellTestsMixin:
- """
- Generic tests for the C{IFTPShell} interface.
- """
-
- def directoryExists(self, path):
- """
- Test if the directory exists at C{path}.
-
- @param path: the relative path to check.
- @type path: C{str}.
-
- @return: C{True} if C{path} exists and is a directory, C{False} if
- it's not the case
- @rtype: C{bool}
- """
- raise NotImplementedError()
-
-
- def createDirectory(self, path):
- """
- Create a directory in C{path}.
-
- @param path: the relative path of the directory to create, with one
- segment.
- @type path: C{str}
- """
- raise NotImplementedError()
-
-
- def fileExists(self, path):
- """
- Test if the file exists at C{path}.
-
- @param path: the relative path to check.
- @type path: C{str}.
-
- @return: C{True} if C{path} exists and is a file, C{False} if it's not
- the case.
- @rtype: C{bool}
- """
- raise NotImplementedError()
-
-
- def createFile(self, path, fileContent=''):
- """
- Create a file named C{path} with some content.
-
- @param path: the relative path of the file to create, without
- directory.
- @type path: C{str}
-
- @param fileContent: the content of the file.
- @type fileContent: C{str}
- """
- raise NotImplementedError()
-
-
- def test_createDirectory(self):
- """
- C{directoryExists} should report correctly about directory existence,
- and C{createDirectory} should create a directory detectable by
- C{directoryExists}.
- """
- self.assertFalse(self.directoryExists('bar'))
- self.createDirectory('bar')
- self.assertTrue(self.directoryExists('bar'))
-
-
- def test_createFile(self):
- """
- C{fileExists} should report correctly about file existence, and
- C{createFile} should create a file detectable by C{fileExists}.
- """
- self.assertFalse(self.fileExists('file.txt'))
- self.createFile('file.txt')
- self.assertTrue(self.fileExists('file.txt'))
-
-
- def test_makeDirectory(self):
- """
- Create a directory and check it ends in the filesystem.
- """
- d = self.shell.makeDirectory(('foo',))
- def cb(result):
- self.assertTrue(self.directoryExists('foo'))
- return d.addCallback(cb)
-
-
- def test_makeDirectoryError(self):
- """
- Creating a directory that already exists should fail with a
- C{ftp.FileExistsError}.
- """
- self.createDirectory('foo')
- d = self.shell.makeDirectory(('foo',))
- return self.assertFailure(d, ftp.FileExistsError)
-
-
- def test_removeDirectory(self):
- """
- Try to remove a directory and check it's removed from the filesystem.
- """
- self.createDirectory('bar')
- d = self.shell.removeDirectory(('bar',))
- def cb(result):
- self.assertFalse(self.directoryExists('bar'))
- return d.addCallback(cb)
-
-
- def test_removeDirectoryOnFile(self):
- """
- removeDirectory should not work in file and fail with a
- C{ftp.IsNotADirectoryError}.
- """
- self.createFile('file.txt')
- d = self.shell.removeDirectory(('file.txt',))
- return self.assertFailure(d, ftp.IsNotADirectoryError)
-
-
- def test_removeNotExistingDirectory(self):
- """
- Removing directory that doesn't exist should fail with a
- C{ftp.FileNotFoundError}.
- """
- d = self.shell.removeDirectory(('bar',))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_removeFile(self):
- """
- Try to remove a file and check it's removed from the filesystem.
- """
- self.createFile('file.txt')
- d = self.shell.removeFile(('file.txt',))
- def cb(res):
- self.assertFalse(self.fileExists('file.txt'))
- d.addCallback(cb)
- return d
-
-
- def test_removeFileOnDirectory(self):
- """
- removeFile should not work on directory.
- """
- self.createDirectory('ned')
- d = self.shell.removeFile(('ned',))
- return self.assertFailure(d, ftp.IsADirectoryError)
-
-
- def test_removeNotExistingFile(self):
- """
- Try to remove a non existent file, and check it raises a
- L{ftp.FileNotFoundError}.
- """
- d = self.shell.removeFile(('foo',))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_list(self):
- """
- Check the output of the list method.
- """
- self.createDirectory('ned')
- self.createFile('file.txt')
- d = self.shell.list(('.',))
- def cb(l):
- l.sort()
- self.assertEqual(l,
- [('file.txt', []), ('ned', [])])
- return d.addCallback(cb)
-
-
- def test_listWithStat(self):
- """
- Check the output of list with asked stats.
- """
- self.createDirectory('ned')
- self.createFile('file.txt')
- d = self.shell.list(('.',), ('size', 'permissions',))
- def cb(l):
- l.sort()
- self.assertEqual(len(l), 2)
- self.assertEqual(l[0][0], 'file.txt')
- self.assertEqual(l[1][0], 'ned')
- # Size and permissions are reported differently between platforms
- # so just check they are present
- self.assertEqual(len(l[0][1]), 2)
- self.assertEqual(len(l[1][1]), 2)
- return d.addCallback(cb)
-
-
- def test_listWithInvalidStat(self):
- """
- Querying an invalid stat should result to a C{AttributeError}.
- """
- self.createDirectory('ned')
- d = self.shell.list(('.',), ('size', 'whateverstat',))
- return self.assertFailure(d, AttributeError)
-
-
- def test_listFile(self):
- """
- Check the output of the list method on a file.
- """
- self.createFile('file.txt')
- d = self.shell.list(('file.txt',))
- def cb(l):
- l.sort()
- self.assertEqual(l,
- [('file.txt', [])])
- return d.addCallback(cb)
-
-
- def test_listNotExistingDirectory(self):
- """
- list on a directory that doesn't exist should fail with a
- L{ftp.FileNotFoundError}.
- """
- d = self.shell.list(('foo',))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_access(self):
- """
- Try to access a resource.
- """
- self.createDirectory('ned')
- d = self.shell.access(('ned',))
- return d
-
-
- def test_accessNotFound(self):
- """
- access should fail on a resource that doesn't exist.
- """
- d = self.shell.access(('foo',))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_openForReading(self):
- """
- Check that openForReading returns an object providing C{ftp.IReadFile}.
- """
- self.createFile('file.txt')
- d = self.shell.openForReading(('file.txt',))
- def cb(res):
- self.assertTrue(ftp.IReadFile.providedBy(res))
- d.addCallback(cb)
- return d
-
-
- def test_openForReadingNotFound(self):
- """
- openForReading should fail with a C{ftp.FileNotFoundError} on a file
- that doesn't exist.
- """
- d = self.shell.openForReading(('ned',))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_openForReadingOnDirectory(self):
- """
- openForReading should not work on directory.
- """
- self.createDirectory('ned')
- d = self.shell.openForReading(('ned',))
- return self.assertFailure(d, ftp.IsADirectoryError)
-
-
- def test_openForWriting(self):
- """
- Check that openForWriting returns an object providing C{ftp.IWriteFile}.
- """
- d = self.shell.openForWriting(('foo',))
- def cb1(res):
- self.assertTrue(ftp.IWriteFile.providedBy(res))
- return res.receive().addCallback(cb2)
- def cb2(res):
- self.assertTrue(IConsumer.providedBy(res))
- d.addCallback(cb1)
- return d
-
-
- def test_openForWritingExistingDirectory(self):
- """
- openForWriting should not be able to open a directory that already
- exists.
- """
- self.createDirectory('ned')
- d = self.shell.openForWriting(('ned',))
- return self.assertFailure(d, ftp.IsADirectoryError)
-
-
- def test_openForWritingInNotExistingDirectory(self):
- """
- openForWring should fail with a L{ftp.FileNotFoundError} if you specify
- a file in a directory that doesn't exist.
- """
- self.createDirectory('ned')
- d = self.shell.openForWriting(('ned', 'idonotexist', 'foo'))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_statFile(self):
- """
- Check the output of the stat method on a file.
- """
- fileContent = 'wobble\n'
- self.createFile('file.txt', fileContent)
- d = self.shell.stat(('file.txt',), ('size', 'directory'))
- def cb(res):
- self.assertEqual(res[0], len(fileContent))
- self.assertFalse(res[1])
- d.addCallback(cb)
- return d
-
-
- def test_statDirectory(self):
- """
- Check the output of the stat method on a directory.
- """
- self.createDirectory('ned')
- d = self.shell.stat(('ned',), ('size', 'directory'))
- def cb(res):
- self.assertTrue(res[1])
- d.addCallback(cb)
- return d
-
-
- def test_statOwnerGroup(self):
- """
- Check the owner and groups stats.
- """
- self.createDirectory('ned')
- d = self.shell.stat(('ned',), ('owner', 'group'))
- def cb(res):
- self.assertEqual(len(res), 2)
- d.addCallback(cb)
- return d
-
-
- def test_statNotExisting(self):
- """
- stat should fail with L{ftp.FileNotFoundError} on a file that doesn't
- exist.
- """
- d = self.shell.stat(('foo',), ('size', 'directory'))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
- def test_invalidStat(self):
- """
- Querying an invalid stat should result to a C{AttributeError}.
- """
- self.createDirectory('ned')
- d = self.shell.stat(('ned',), ('size', 'whateverstat'))
- return self.assertFailure(d, AttributeError)
-
-
- def test_rename(self):
- """
- Try to rename a directory.
- """
- self.createDirectory('ned')
- d = self.shell.rename(('ned',), ('foo',))
- def cb(res):
- self.assertTrue(self.directoryExists('foo'))
- self.assertFalse(self.directoryExists('ned'))
- return d.addCallback(cb)
-
-
- def test_renameNotExisting(self):
- """
- Renaming a directory that doesn't exist should fail with
- L{ftp.FileNotFoundError}.
- """
- d = self.shell.rename(('foo',), ('bar',))
- return self.assertFailure(d, ftp.FileNotFoundError)
-
-
-
-class FTPShellTestCase(unittest.TestCase, IFTPShellTestsMixin):
- """
- Tests for the C{ftp.FTPShell} object.
- """
-
- def setUp(self):
- """
- Create a root directory and instantiate a shell.
- """
- self.root = filepath.FilePath(self.mktemp())
- self.root.createDirectory()
- self.shell = ftp.FTPShell(self.root)
-
-
- def directoryExists(self, path):
- """
- Test if the directory exists at C{path}.
- """
- return self.root.child(path).isdir()
-
-
- def createDirectory(self, path):
- """
- Create a directory in C{path}.
- """
- return self.root.child(path).createDirectory()
-
-
- def fileExists(self, path):
- """
- Test if the file exists at C{path}.
- """
- return self.root.child(path).isfile()
-
-
- def createFile(self, path, fileContent=''):
- """
- Create a file named C{path} with some content.
- """
- return self.root.child(path).setContent(fileContent)
-
-
-
-class TestConsumer(object):
- """
- A simple consumer for tests. It only works with non-streaming producers.
-
- @ivar producer: an object providing
- L{twisted.internet.interfaces.IPullProducer}.
- """
-
- implements(IConsumer)
- producer = None
-
- def registerProducer(self, producer, streaming):
- """
- Simple register of producer, checks that no register has happened
- before.
- """
- assert self.producer is None
- self.buffer = []
- self.producer = producer
- self.producer.resumeProducing()
-
-
- def unregisterProducer(self):
- """
- Unregister the producer, it should be done after a register.
- """
- assert self.producer is not None
- self.producer = None
-
-
- def write(self, data):
- """
- Save the data received.
- """
- self.buffer.append(data)
- self.producer.resumeProducing()
-
-
-
-class TestProducer(object):
- """
- A dumb producer.
- """
-
- def __init__(self, toProduce, consumer):
- """
- @param toProduce: data to write
- @type toProduce: C{str}
- @param consumer: the consumer of data.
- @type consumer: C{IConsumer}
- """
- self.toProduce = toProduce
- self.consumer = consumer
-
-
- def start(self):
- """
- Send the data to consume.
- """
- self.consumer.write(self.toProduce)
-
-
-
-class IReadWriteTestsMixin:
- """
- Generic tests for the C{IReadFile} and C{IWriteFile} interfaces.
- """
-
- def getFileReader(self, content):
- """
- Return an object providing C{IReadFile}, ready to send data C{content}.
- """
- raise NotImplementedError()
-
-
- def getFileWriter(self):
- """
- Return an object providing C{IWriteFile}, ready to receive data.
- """
- raise NotImplementedError()
-
-
- def getFileContent(self):
- """
- Return the content of the file used.
- """
- raise NotImplementedError()
-
-
- def test_read(self):
- """
- Test L{ftp.IReadFile}: the implementation should have a send method
- returning a C{Deferred} which fires when all the data has been sent
- to the consumer, and the data should be correctly send to the consumer.
- """
- content = 'wobble\n'
- consumer = TestConsumer()
- def cbGet(reader):
- return reader.send(consumer).addCallback(cbSend)
- def cbSend(res):
- self.assertEqual("".join(consumer.buffer), content)
- return self.getFileReader(content).addCallback(cbGet)
-
-
- def test_write(self):
- """
- Test L{ftp.IWriteFile}: the implementation should have a receive
- method returning a C{Deferred} which fires with a consumer ready to
- receive data to be written. It should also have a close() method that
- returns a Deferred.
- """
- content = 'elbbow\n'
- def cbGet(writer):
- return writer.receive().addCallback(cbReceive, writer)
- def cbReceive(consumer, writer):
- producer = TestProducer(content, consumer)
- consumer.registerProducer(None, True)
- producer.start()
- consumer.unregisterProducer()
- return writer.close().addCallback(cbClose)
- def cbClose(ignored):
- self.assertEqual(self.getFileContent(), content)
- return self.getFileWriter().addCallback(cbGet)
-
-
-
-class FTPReadWriteTestCase(unittest.TestCase, IReadWriteTestsMixin):
- """
- Tests for C{ftp._FileReader} and C{ftp._FileWriter}, the objects returned
- by the shell in C{openForReading}/C{openForWriting}.
- """
-
- def setUp(self):
- """
- Create a temporary file used later.
- """
- self.root = filepath.FilePath(self.mktemp())
- self.root.createDirectory()
- self.shell = ftp.FTPShell(self.root)
- self.filename = "file.txt"
-
-
- def getFileReader(self, content):
- """
- Return a C{ftp._FileReader} instance with a file opened for reading.
- """
- self.root.child(self.filename).setContent(content)
- return self.shell.openForReading((self.filename,))
-
-
- def getFileWriter(self):
- """
- Return a C{ftp._FileWriter} instance with a file opened for writing.
- """
- return self.shell.openForWriting((self.filename,))
-
-
- def getFileContent(self):
- """
- Return the content of the temporary file.
- """
- return self.root.child(self.filename).getContent()
-
-
-class CloseTestWriter:
- implements(ftp.IWriteFile)
- closeStarted = False
- def receive(self):
- self.s = StringIO()
- fc = ftp.FileConsumer(self.s)
- return defer.succeed(fc)
- def close(self):
- self.closeStarted = True
- return self.d
-
-class CloseTestShell:
- def openForWriting(self, segs):
- return defer.succeed(self.writer)
-
-class FTPCloseTest(unittest.TestCase):
- """Tests that the server invokes IWriteFile.close"""
-
- def test_write(self):
- """Confirm that FTP uploads (i.e. ftp_STOR) correctly call and wait
- upon the IWriteFile object's close() method"""
- f = ftp.FTP()
- f.workingDirectory = ["root"]
- f.shell = CloseTestShell()
- f.shell.writer = CloseTestWriter()
- f.shell.writer.d = defer.Deferred()
- f.factory = ftp.FTPFactory()
- f.factory.timeOut = None
- f.makeConnection(StringIO())
-
- di = ftp.DTP()
- di.factory = ftp.DTPFactory(f)
- f.dtpInstance = di
- di.makeConnection(None)#
-
- stor_done = []
- d = f.ftp_STOR("path")
- d.addCallback(stor_done.append)
- # the writer is still receiving data
- self.assertFalse(f.shell.writer.closeStarted, "close() called early")
- di.dataReceived("some data here")
- self.assertFalse(f.shell.writer.closeStarted, "close() called early")
- di.connectionLost("reason is ignored")
- # now we should be waiting in close()
- self.assertTrue(f.shell.writer.closeStarted, "close() not called")
- self.assertFalse(stor_done)
- f.shell.writer.d.callback("allow close() to finish")
- self.assertTrue(stor_done)
-
- return d # just in case an errback occurred
-
-
-
-class FTPResponseCodeTests(unittest.TestCase):
- """
- Tests relating directly to response codes.
- """
- def test_unique(self):
- """
- All of the response code globals (for example C{RESTART_MARKER_REPLY} or
- C{USR_NAME_OK_NEED_PASS}) have unique values and are present in the
- C{RESPONSE} dictionary.
- """
- allValues = set(ftp.RESPONSE)
- seenValues = set()
-
- for key, value in vars(ftp).items():
- if isinstance(value, str) and key.isupper():
- self.assertIn(
- value, allValues,
- "Code %r with value %r missing from RESPONSE dict" % (
- key, value))
- self.assertNotIn(
- value, seenValues,
- "Duplicate code %r with value %r" % (key, value))
- seenValues.add(value)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp_options.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp_options.py
deleted file mode 100755
index e668502c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ftp_options.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.tap.ftp}.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.cred import credentials, error
-from twisted.tap.ftp import Options
-from twisted.python import versions
-from twisted.python.filepath import FilePath
-
-
-
-class FTPOptionsTestCase(TestCase):
- """
- Tests for the command line option parser used for C{twistd ftp}.
- """
-
- usernamePassword = ('iamuser', 'thisispassword')
-
- def setUp(self):
- """
- Create a file with two users.
- """
- self.filename = self.mktemp()
- f = FilePath(self.filename)
- f.setContent(':'.join(self.usernamePassword))
- self.options = Options()
-
-
- def test_passwordfileDeprecation(self):
- """
- The C{--password-file} option will emit a warning stating that
- said option is deprecated.
- """
- self.callDeprecated(
- versions.Version("Twisted", 11, 1, 0),
- self.options.opt_password_file, self.filename)
-
-
- def test_authAdded(self):
- """
- The C{--auth} command-line option will add a checker to the list of
- checkers
- """
- numCheckers = len(self.options['credCheckers'])
- self.options.parseOptions(['--auth', 'file:' + self.filename])
- self.assertEqual(len(self.options['credCheckers']), numCheckers + 1)
-
-
- def test_authFailure(self):
- """
- The checker created by the C{--auth} command-line option returns a
- L{Deferred} that fails with L{UnauthorizedLogin} when
- presented with credentials that are unknown to that checker.
- """
- self.options.parseOptions(['--auth', 'file:' + self.filename])
- checker = self.options['credCheckers'][-1]
- invalid = credentials.UsernamePassword(self.usernamePassword[0], 'fake')
- return (checker.requestAvatarId(invalid)
- .addCallbacks(
- lambda ignore: self.fail("Wrong password should raise error"),
- lambda err: err.trap(error.UnauthorizedLogin)))
-
-
- def test_authSuccess(self):
- """
- The checker created by the C{--auth} command-line option returns a
- L{Deferred} that returns the avatar id when presented with credentials
- that are known to that checker.
- """
- self.options.parseOptions(['--auth', 'file:' + self.filename])
- checker = self.options['credCheckers'][-1]
- correct = credentials.UsernamePassword(*self.usernamePassword)
- return checker.requestAvatarId(correct).addCallback(
- lambda username: self.assertEqual(username, correct.username)
- )
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_hook.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_hook.py
deleted file mode 100755
index 7d17f76b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_hook.py
+++ /dev/null
@@ -1,150 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test cases for twisted.hook module.
-"""
-
-from twisted.python import hook
-from twisted.trial import unittest
-
-class BaseClass:
- """
- dummy class to help in testing.
- """
- def __init__(self):
- """
- dummy initializer
- """
- self.calledBasePre = 0
- self.calledBasePost = 0
- self.calledBase = 0
-
- def func(self, a, b):
- """
- dummy method
- """
- assert a == 1
- assert b == 2
- self.calledBase = self.calledBase + 1
-
-
-class SubClass(BaseClass):
- """
- another dummy class
- """
- def __init__(self):
- """
- another dummy initializer
- """
- BaseClass.__init__(self)
- self.calledSubPre = 0
- self.calledSubPost = 0
- self.calledSub = 0
-
- def func(self, a, b):
- """
- another dummy function
- """
- assert a == 1
- assert b == 2
- BaseClass.func(self, a, b)
- self.calledSub = self.calledSub + 1
-
-_clean_BaseClass = BaseClass.__dict__.copy()
-_clean_SubClass = SubClass.__dict__.copy()
-
-def basePre(base, a, b):
- """
- a pre-hook for the base class
- """
- base.calledBasePre = base.calledBasePre + 1
-
-def basePost(base, a, b):
- """
- a post-hook for the base class
- """
- base.calledBasePost = base.calledBasePost + 1
-
-def subPre(sub, a, b):
- """
- a pre-hook for the subclass
- """
- sub.calledSubPre = sub.calledSubPre + 1
-
-def subPost(sub, a, b):
- """
- a post-hook for the subclass
- """
- sub.calledSubPost = sub.calledSubPost + 1
-
-class HookTestCase(unittest.TestCase):
- """
- test case to make sure hooks are called
- """
- def setUp(self):
- """Make sure we have clean versions of our classes."""
- BaseClass.__dict__.clear()
- BaseClass.__dict__.update(_clean_BaseClass)
- SubClass.__dict__.clear()
- SubClass.__dict__.update(_clean_SubClass)
-
- def testBaseHook(self):
- """make sure that the base class's hook is called reliably
- """
- base = BaseClass()
- self.assertEqual(base.calledBase, 0)
- self.assertEqual(base.calledBasePre, 0)
- base.func(1,2)
- self.assertEqual(base.calledBase, 1)
- self.assertEqual(base.calledBasePre, 0)
- hook.addPre(BaseClass, "func", basePre)
- base.func(1, b=2)
- self.assertEqual(base.calledBase, 2)
- self.assertEqual(base.calledBasePre, 1)
- hook.addPost(BaseClass, "func", basePost)
- base.func(1, b=2)
- self.assertEqual(base.calledBasePost, 1)
- self.assertEqual(base.calledBase, 3)
- self.assertEqual(base.calledBasePre, 2)
- hook.removePre(BaseClass, "func", basePre)
- hook.removePost(BaseClass, "func", basePost)
- base.func(1, b=2)
- self.assertEqual(base.calledBasePost, 1)
- self.assertEqual(base.calledBase, 4)
- self.assertEqual(base.calledBasePre, 2)
-
- def testSubHook(self):
- """test interactions between base-class hooks and subclass hooks
- """
- sub = SubClass()
- self.assertEqual(sub.calledSub, 0)
- self.assertEqual(sub.calledBase, 0)
- sub.func(1, b=2)
- self.assertEqual(sub.calledSub, 1)
- self.assertEqual(sub.calledBase, 1)
- hook.addPre(SubClass, 'func', subPre)
- self.assertEqual(sub.calledSub, 1)
- self.assertEqual(sub.calledBase, 1)
- self.assertEqual(sub.calledSubPre, 0)
- self.assertEqual(sub.calledBasePre, 0)
- sub.func(1, b=2)
- self.assertEqual(sub.calledSub, 2)
- self.assertEqual(sub.calledBase, 2)
- self.assertEqual(sub.calledSubPre, 1)
- self.assertEqual(sub.calledBasePre, 0)
- # let the pain begin
- hook.addPre(BaseClass, 'func', basePre)
- BaseClass.func(sub, 1, b=2)
- # sub.func(1, b=2)
- self.assertEqual(sub.calledBase, 3)
- self.assertEqual(sub.calledBasePre, 1, str(sub.calledBasePre))
- sub.func(1, b=2)
- self.assertEqual(sub.calledBasePre, 2)
- self.assertEqual(sub.calledBase, 4)
- self.assertEqual(sub.calledSubPre, 2)
- self.assertEqual(sub.calledSub, 3)
-
-testCases = [HookTestCase]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_htb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_htb.py
deleted file mode 100755
index ee4cc27e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_htb.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# -*- Python -*-
-
-__version__ = '$Revision: 1.3 $'[11:-2]
-
-from twisted.trial import unittest
-from twisted.protocols import htb
-
-class DummyClock:
- time = 0
- def set(self, when):
- self.time = when
-
- def __call__(self):
- return self.time
-
-class SomeBucket(htb.Bucket):
- maxburst = 100
- rate = 2
-
-class TestBucketBase(unittest.TestCase):
- def setUp(self):
- self._realTimeFunc = htb.time
- self.clock = DummyClock()
- htb.time = self.clock
-
- def tearDown(self):
- htb.time = self._realTimeFunc
-
-class TestBucket(TestBucketBase):
- def testBucketSize(self):
- """Testing the size of the bucket."""
- b = SomeBucket()
- fit = b.add(1000)
- self.assertEqual(100, fit)
-
- def testBucketDrain(self):
- """Testing the bucket's drain rate."""
- b = SomeBucket()
- fit = b.add(1000)
- self.clock.set(10)
- fit = b.add(1000)
- self.assertEqual(20, fit)
-
- def test_bucketEmpty(self):
- """
- L{htb.Bucket.drip} returns C{True} if the bucket is empty after that drip.
- """
- b = SomeBucket()
- b.add(20)
- self.clock.set(9)
- empty = b.drip()
- self.assertFalse(empty)
- self.clock.set(10)
- empty = b.drip()
- self.assertTrue(empty)
-
-class TestBucketNesting(TestBucketBase):
- def setUp(self):
- TestBucketBase.setUp(self)
- self.parent = SomeBucket()
- self.child1 = SomeBucket(self.parent)
- self.child2 = SomeBucket(self.parent)
-
- def testBucketParentSize(self):
- # Use up most of the parent bucket.
- self.child1.add(90)
- fit = self.child2.add(90)
- self.assertEqual(10, fit)
-
- def testBucketParentRate(self):
- # Make the parent bucket drain slower.
- self.parent.rate = 1
- # Fill both child1 and parent.
- self.child1.add(100)
- self.clock.set(10)
- fit = self.child1.add(100)
- # How much room was there? The child bucket would have had 20,
- # but the parent bucket only ten (so no, it wouldn't make too much
- # sense to have a child bucket draining faster than its parent in a real
- # application.)
- self.assertEqual(10, fit)
-
-
-# TODO: Test the Transport stuff?
-
-from test_pcp import DummyConsumer
-
-class ConsumerShaperTest(TestBucketBase):
- def setUp(self):
- TestBucketBase.setUp(self)
- self.underlying = DummyConsumer()
- self.bucket = SomeBucket()
- self.shaped = htb.ShapedConsumer(self.underlying, self.bucket)
-
- def testRate(self):
- # Start off with a full bucket, so the burst-size dosen't factor in
- # to the calculations.
- delta_t = 10
- self.bucket.add(100)
- self.shaped.write("x" * 100)
- self.clock.set(delta_t)
- self.shaped.resumeProducing()
- self.assertEqual(len(self.underlying.getvalue()),
- delta_t * self.bucket.rate)
-
- def testBucketRefs(self):
- self.assertEqual(self.bucket._refcount, 1)
- self.shaped.stopProducing()
- self.assertEqual(self.bucket._refcount, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ident.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ident.py
deleted file mode 100755
index 9f69322d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ident.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test cases for twisted.protocols.ident module.
-"""
-
-import struct
-
-from twisted.protocols import ident
-from twisted.python import failure
-from twisted.internet import error
-from twisted.internet import defer
-
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport
-
-
-
-class ClassParserTestCase(unittest.TestCase):
- """
- Test parsing of ident responses.
- """
-
- def setUp(self):
- """
- Create a ident client used in tests.
- """
- self.client = ident.IdentClient()
-
-
- def test_indentError(self):
- """
- 'UNKNOWN-ERROR' error should map to the L{ident.IdentError} exception.
- """
- d = defer.Deferred()
- self.client.queries.append((d, 123, 456))
- self.client.lineReceived('123, 456 : ERROR : UNKNOWN-ERROR')
- return self.assertFailure(d, ident.IdentError)
-
-
- def test_noUSerError(self):
- """
- 'NO-USER' error should map to the L{ident.NoUser} exception.
- """
- d = defer.Deferred()
- self.client.queries.append((d, 234, 456))
- self.client.lineReceived('234, 456 : ERROR : NO-USER')
- return self.assertFailure(d, ident.NoUser)
-
-
- def test_invalidPortError(self):
- """
- 'INVALID-PORT' error should map to the L{ident.InvalidPort} exception.
- """
- d = defer.Deferred()
- self.client.queries.append((d, 345, 567))
- self.client.lineReceived('345, 567 : ERROR : INVALID-PORT')
- return self.assertFailure(d, ident.InvalidPort)
-
-
- def test_hiddenUserError(self):
- """
- 'HIDDEN-USER' error should map to the L{ident.HiddenUser} exception.
- """
- d = defer.Deferred()
- self.client.queries.append((d, 567, 789))
- self.client.lineReceived('567, 789 : ERROR : HIDDEN-USER')
- return self.assertFailure(d, ident.HiddenUser)
-
-
- def test_lostConnection(self):
- """
- A pending query which failed because of a ConnectionLost should
- receive an L{ident.IdentError}.
- """
- d = defer.Deferred()
- self.client.queries.append((d, 765, 432))
- self.client.connectionLost(failure.Failure(error.ConnectionLost()))
- return self.assertFailure(d, ident.IdentError)
-
-
-
-class TestIdentServer(ident.IdentServer):
- def lookup(self, serverAddress, clientAddress):
- return self.resultValue
-
-
-class TestErrorIdentServer(ident.IdentServer):
- def lookup(self, serverAddress, clientAddress):
- raise self.exceptionType()
-
-
-class NewException(RuntimeError):
- pass
-
-
-class ServerParserTestCase(unittest.TestCase):
- def testErrors(self):
- p = TestErrorIdentServer()
- p.makeConnection(StringTransport())
- L = []
- p.sendLine = L.append
-
- p.exceptionType = ident.IdentError
- p.lineReceived('123, 345')
- self.assertEqual(L[0], '123, 345 : ERROR : UNKNOWN-ERROR')
-
- p.exceptionType = ident.NoUser
- p.lineReceived('432, 210')
- self.assertEqual(L[1], '432, 210 : ERROR : NO-USER')
-
- p.exceptionType = ident.InvalidPort
- p.lineReceived('987, 654')
- self.assertEqual(L[2], '987, 654 : ERROR : INVALID-PORT')
-
- p.exceptionType = ident.HiddenUser
- p.lineReceived('756, 827')
- self.assertEqual(L[3], '756, 827 : ERROR : HIDDEN-USER')
-
- p.exceptionType = NewException
- p.lineReceived('987, 789')
- self.assertEqual(L[4], '987, 789 : ERROR : UNKNOWN-ERROR')
- errs = self.flushLoggedErrors(NewException)
- self.assertEqual(len(errs), 1)
-
- for port in -1, 0, 65536, 65537:
- del L[:]
- p.lineReceived('%d, 5' % (port,))
- p.lineReceived('5, %d' % (port,))
- self.assertEqual(
- L, ['%d, 5 : ERROR : INVALID-PORT' % (port,),
- '5, %d : ERROR : INVALID-PORT' % (port,)])
-
- def testSuccess(self):
- p = TestIdentServer()
- p.makeConnection(StringTransport())
- L = []
- p.sendLine = L.append
-
- p.resultValue = ('SYS', 'USER')
- p.lineReceived('123, 456')
- self.assertEqual(L[0], '123, 456 : USERID : SYS : USER')
-
-
-if struct.pack('=L', 1)[0] == '\x01':
- _addr1 = '0100007F'
- _addr2 = '04030201'
-else:
- _addr1 = '7F000001'
- _addr2 = '01020304'
-
-
-class ProcMixinTestCase(unittest.TestCase):
- line = ('4: %s:0019 %s:02FA 0A 00000000:00000000 '
- '00:00000000 00000000 0 0 10927 1 f72a5b80 '
- '3000 0 0 2 -1') % (_addr1, _addr2)
-
- def testDottedQuadFromHexString(self):
- p = ident.ProcServerMixin()
- self.assertEqual(p.dottedQuadFromHexString(_addr1), '127.0.0.1')
-
- def testUnpackAddress(self):
- p = ident.ProcServerMixin()
- self.assertEqual(p.unpackAddress(_addr1 + ':0277'),
- ('127.0.0.1', 631))
-
- def testLineParser(self):
- p = ident.ProcServerMixin()
- self.assertEqual(
- p.parseLine(self.line),
- (('127.0.0.1', 25), ('1.2.3.4', 762), 0))
-
- def testExistingAddress(self):
- username = []
- p = ident.ProcServerMixin()
- p.entries = lambda: iter([self.line])
- p.getUsername = lambda uid: (username.append(uid), 'root')[1]
- self.assertEqual(
- p.lookup(('127.0.0.1', 25), ('1.2.3.4', 762)),
- (p.SYSTEM_NAME, 'root'))
- self.assertEqual(username, [0])
-
- def testNonExistingAddress(self):
- p = ident.ProcServerMixin()
- p.entries = lambda: iter([self.line])
- self.assertRaises(ident.NoUser, p.lookup, ('127.0.0.1', 26),
- ('1.2.3.4', 762))
- self.assertRaises(ident.NoUser, p.lookup, ('127.0.0.1', 25),
- ('1.2.3.5', 762))
- self.assertRaises(ident.NoUser, p.lookup, ('127.0.0.1', 25),
- ('1.2.3.4', 763))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_import.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_import.py
deleted file mode 100755
index 821b9bfc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_import.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-from twisted.python.runtime import platformType
-
-
-class AtLeastImportTestCase(unittest.TestCase):
- """
- I test that there are no syntax errors which will not allow importing.
- """
-
- failureException = ImportError
-
- def test_misc(self):
- """
- Test importing other miscellaneous modules.
- """
- from twisted import copyright
-
- def test_persisted(self):
- """
- Test importing persisted.
- """
- from twisted.persisted import dirdbm
- from twisted.persisted import styles
-
- def test_internet(self):
- """
- Test importing internet.
- """
- from twisted.internet import tcp
- from twisted.internet import main
- from twisted.internet import abstract
- from twisted.internet import udp
- from twisted.internet import protocol
- from twisted.internet import defer
-
- def test_unix(self):
- """
- Test internet modules for unix.
- """
- from twisted.internet import stdio
- from twisted.internet import process
- from twisted.internet import unix
-
- if platformType != "posix":
- test_unix.skip = "UNIX-only modules"
-
- def test_spread(self):
- """
- Test importing spreadables.
- """
- from twisted.spread import pb
- from twisted.spread import jelly
- from twisted.spread import banana
- from twisted.spread import flavors
-
- def test_twistedPython(self):
- """
- Test importing C{twisted.python}.
- """
- from twisted.python import hook
- from twisted.python import log
- from twisted.python import reflect
- from twisted.python import usage
-
- def test_protocols(self):
- """
- Test importing protocols.
- """
- from twisted.protocols import basic
- from twisted.protocols import ftp
- from twisted.protocols import telnet
- from twisted.protocols import policies
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_internet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_internet.py
deleted file mode 100755
index 0e14bb4f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_internet.py
+++ /dev/null
@@ -1,1396 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for lots of functionality provided by L{twisted.internet}.
-"""
-
-import os
-import sys
-import time
-
-from twisted.trial import unittest
-from twisted.internet import reactor, protocol, error, abstract, defer
-from twisted.internet import interfaces, base
-
-try:
- from twisted.internet import ssl
-except ImportError:
- ssl = None
-if ssl and not ssl.supported:
- ssl = None
-
-from twisted.internet.defer import Deferred, maybeDeferred
-from twisted.python import util, runtime
-
-
-
-class ThreePhaseEventTests(unittest.TestCase):
- """
- Tests for the private implementation helpers for system event triggers.
- """
- def setUp(self):
- """
- Create a trigger, an argument, and an event to be used by tests.
- """
- self.trigger = lambda x: None
- self.arg = object()
- self.event = base._ThreePhaseEvent()
-
-
- def test_addInvalidPhase(self):
- """
- L{_ThreePhaseEvent.addTrigger} should raise L{KeyError} when called
- with an invalid phase.
- """
- self.assertRaises(
- KeyError,
- self.event.addTrigger, 'xxx', self.trigger, self.arg)
-
-
- def test_addBeforeTrigger(self):
- """
- L{_ThreePhaseEvent.addTrigger} should accept C{'before'} as a phase, a
- callable, and some arguments and add the callable with the arguments to
- the before list.
- """
- self.event.addTrigger('before', self.trigger, self.arg)
- self.assertEqual(
- self.event.before,
- [(self.trigger, (self.arg,), {})])
-
-
- def test_addDuringTrigger(self):
- """
- L{_ThreePhaseEvent.addTrigger} should accept C{'during'} as a phase, a
- callable, and some arguments and add the callable with the arguments to
- the during list.
- """
- self.event.addTrigger('during', self.trigger, self.arg)
- self.assertEqual(
- self.event.during,
- [(self.trigger, (self.arg,), {})])
-
-
- def test_addAfterTrigger(self):
- """
- L{_ThreePhaseEvent.addTrigger} should accept C{'after'} as a phase, a
- callable, and some arguments and add the callable with the arguments to
- the after list.
- """
- self.event.addTrigger('after', self.trigger, self.arg)
- self.assertEqual(
- self.event.after,
- [(self.trigger, (self.arg,), {})])
-
-
- def test_removeTrigger(self):
- """
- L{_ThreePhaseEvent.removeTrigger} should accept an opaque object
- previously returned by L{_ThreePhaseEvent.addTrigger} and remove the
- associated trigger.
- """
- handle = self.event.addTrigger('before', self.trigger, self.arg)
- self.event.removeTrigger(handle)
- self.assertEqual(self.event.before, [])
-
-
- def test_removeNonexistentTrigger(self):
- """
- L{_ThreePhaseEvent.removeTrigger} should raise L{ValueError} when given
- an object not previously returned by L{_ThreePhaseEvent.addTrigger}.
- """
- self.assertRaises(ValueError, self.event.removeTrigger, object())
-
-
- def test_removeRemovedTrigger(self):
- """
- L{_ThreePhaseEvent.removeTrigger} should raise L{ValueError} the second
- time it is called with an object returned by
- L{_ThreePhaseEvent.addTrigger}.
- """
- handle = self.event.addTrigger('before', self.trigger, self.arg)
- self.event.removeTrigger(handle)
- self.assertRaises(ValueError, self.event.removeTrigger, handle)
-
-
- def test_removeAlmostValidTrigger(self):
- """
- L{_ThreePhaseEvent.removeTrigger} should raise L{ValueError} if it is
- given a trigger handle which resembles a valid trigger handle aside
- from its phase being incorrect.
- """
- self.assertRaises(
- KeyError,
- self.event.removeTrigger, ('xxx', self.trigger, (self.arg,), {}))
-
-
- def test_fireEvent(self):
- """
- L{_ThreePhaseEvent.fireEvent} should call I{before}, I{during}, and
- I{after} phase triggers in that order.
- """
- events = []
- self.event.addTrigger('after', events.append, ('first', 'after'))
- self.event.addTrigger('during', events.append, ('first', 'during'))
- self.event.addTrigger('before', events.append, ('first', 'before'))
- self.event.addTrigger('before', events.append, ('second', 'before'))
- self.event.addTrigger('during', events.append, ('second', 'during'))
- self.event.addTrigger('after', events.append, ('second', 'after'))
-
- self.assertEqual(events, [])
- self.event.fireEvent()
- self.assertEqual(events,
- [('first', 'before'), ('second', 'before'),
- ('first', 'during'), ('second', 'during'),
- ('first', 'after'), ('second', 'after')])
-
-
- def test_asynchronousBefore(self):
- """
- L{_ThreePhaseEvent.fireEvent} should wait for any L{Deferred} returned
- by a I{before} phase trigger before proceeding to I{during} events.
- """
- events = []
- beforeResult = Deferred()
- self.event.addTrigger('before', lambda: beforeResult)
- self.event.addTrigger('during', events.append, 'during')
- self.event.addTrigger('after', events.append, 'after')
-
- self.assertEqual(events, [])
- self.event.fireEvent()
- self.assertEqual(events, [])
- beforeResult.callback(None)
- self.assertEqual(events, ['during', 'after'])
-
-
- def test_beforeTriggerException(self):
- """
- If a before-phase trigger raises a synchronous exception, it should be
- logged and the remaining triggers should be run.
- """
- events = []
-
- class DummyException(Exception):
- pass
-
- def raisingTrigger():
- raise DummyException()
-
- self.event.addTrigger('before', raisingTrigger)
- self.event.addTrigger('before', events.append, 'before')
- self.event.addTrigger('during', events.append, 'during')
- self.event.fireEvent()
- self.assertEqual(events, ['before', 'during'])
- errors = self.flushLoggedErrors(DummyException)
- self.assertEqual(len(errors), 1)
-
-
- def test_duringTriggerException(self):
- """
- If a during-phase trigger raises a synchronous exception, it should be
- logged and the remaining triggers should be run.
- """
- events = []
-
- class DummyException(Exception):
- pass
-
- def raisingTrigger():
- raise DummyException()
-
- self.event.addTrigger('during', raisingTrigger)
- self.event.addTrigger('during', events.append, 'during')
- self.event.addTrigger('after', events.append, 'after')
- self.event.fireEvent()
- self.assertEqual(events, ['during', 'after'])
- errors = self.flushLoggedErrors(DummyException)
- self.assertEqual(len(errors), 1)
-
-
- def test_synchronousRemoveAlreadyExecutedBefore(self):
- """
- If a before-phase trigger tries to remove another before-phase trigger
- which has already run, a warning should be emitted.
- """
- events = []
-
- def removeTrigger():
- self.event.removeTrigger(beforeHandle)
-
- beforeHandle = self.event.addTrigger('before', events.append, ('first', 'before'))
- self.event.addTrigger('before', removeTrigger)
- self.event.addTrigger('before', events.append, ('second', 'before'))
- self.assertWarns(
- DeprecationWarning,
- "Removing already-fired system event triggers will raise an "
- "exception in a future version of Twisted.",
- __file__,
- self.event.fireEvent)
- self.assertEqual(events, [('first', 'before'), ('second', 'before')])
-
-
- def test_synchronousRemovePendingBefore(self):
- """
- If a before-phase trigger removes another before-phase trigger which
- has not yet run, the removed trigger should not be run.
- """
- events = []
- self.event.addTrigger(
- 'before', lambda: self.event.removeTrigger(beforeHandle))
- beforeHandle = self.event.addTrigger(
- 'before', events.append, ('first', 'before'))
- self.event.addTrigger('before', events.append, ('second', 'before'))
- self.event.fireEvent()
- self.assertEqual(events, [('second', 'before')])
-
-
- def test_synchronousBeforeRemovesDuring(self):
- """
- If a before-phase trigger removes a during-phase trigger, the
- during-phase trigger should not be run.
- """
- events = []
- self.event.addTrigger(
- 'before', lambda: self.event.removeTrigger(duringHandle))
- duringHandle = self.event.addTrigger('during', events.append, 'during')
- self.event.addTrigger('after', events.append, 'after')
- self.event.fireEvent()
- self.assertEqual(events, ['after'])
-
-
- def test_asynchronousBeforeRemovesDuring(self):
- """
- If a before-phase trigger returns a L{Deferred} and later removes a
- during-phase trigger before the L{Deferred} fires, the during-phase
- trigger should not be run.
- """
- events = []
- beforeResult = Deferred()
- self.event.addTrigger('before', lambda: beforeResult)
- duringHandle = self.event.addTrigger('during', events.append, 'during')
- self.event.addTrigger('after', events.append, 'after')
- self.event.fireEvent()
- self.event.removeTrigger(duringHandle)
- beforeResult.callback(None)
- self.assertEqual(events, ['after'])
-
-
- def test_synchronousBeforeRemovesConspicuouslySimilarDuring(self):
- """
- If a before-phase trigger removes a during-phase trigger which is
- identical to an already-executed before-phase trigger aside from their
- phases, no warning should be emitted and the during-phase trigger
- should not be run.
- """
- events = []
- def trigger():
- events.append('trigger')
- self.event.addTrigger('before', trigger)
- self.event.addTrigger(
- 'before', lambda: self.event.removeTrigger(duringTrigger))
- duringTrigger = self.event.addTrigger('during', trigger)
- self.event.fireEvent()
- self.assertEqual(events, ['trigger'])
-
-
- def test_synchronousRemovePendingDuring(self):
- """
- If a during-phase trigger removes another during-phase trigger which
- has not yet run, the removed trigger should not be run.
- """
- events = []
- self.event.addTrigger(
- 'during', lambda: self.event.removeTrigger(duringHandle))
- duringHandle = self.event.addTrigger(
- 'during', events.append, ('first', 'during'))
- self.event.addTrigger(
- 'during', events.append, ('second', 'during'))
- self.event.fireEvent()
- self.assertEqual(events, [('second', 'during')])
-
-
- def test_triggersRunOnce(self):
- """
- A trigger should only be called on the first call to
- L{_ThreePhaseEvent.fireEvent}.
- """
- events = []
- self.event.addTrigger('before', events.append, 'before')
- self.event.addTrigger('during', events.append, 'during')
- self.event.addTrigger('after', events.append, 'after')
- self.event.fireEvent()
- self.event.fireEvent()
- self.assertEqual(events, ['before', 'during', 'after'])
-
-
- def test_finishedBeforeTriggersCleared(self):
- """
- The temporary list L{_ThreePhaseEvent.finishedBefore} should be emptied
- and the state reset to C{'BASE'} before the first during-phase trigger
- executes.
- """
- events = []
- def duringTrigger():
- events.append('during')
- self.assertEqual(self.event.finishedBefore, [])
- self.assertEqual(self.event.state, 'BASE')
- self.event.addTrigger('before', events.append, 'before')
- self.event.addTrigger('during', duringTrigger)
- self.event.fireEvent()
- self.assertEqual(events, ['before', 'during'])
-
-
-
-class SystemEventTestCase(unittest.TestCase):
- """
- Tests for the reactor's implementation of the C{fireSystemEvent},
- C{addSystemEventTrigger}, and C{removeSystemEventTrigger} methods of the
- L{IReactorCore} interface.
-
- @ivar triggers: A list of the handles to triggers which have been added to
- the reactor.
- """
- def setUp(self):
- """
- Create an empty list in which to store trigger handles.
- """
- self.triggers = []
-
-
- def tearDown(self):
- """
- Remove all remaining triggers from the reactor.
- """
- while self.triggers:
- trigger = self.triggers.pop()
- try:
- reactor.removeSystemEventTrigger(trigger)
- except (ValueError, KeyError):
- pass
-
-
- def addTrigger(self, event, phase, func):
- """
- Add a trigger to the reactor and remember it in C{self.triggers}.
- """
- t = reactor.addSystemEventTrigger(event, phase, func)
- self.triggers.append(t)
- return t
-
-
- def removeTrigger(self, trigger):
- """
- Remove a trigger by its handle from the reactor and from
- C{self.triggers}.
- """
- reactor.removeSystemEventTrigger(trigger)
- self.triggers.remove(trigger)
-
-
- def _addSystemEventTriggerTest(self, phase):
- eventType = 'test'
- events = []
- def trigger():
- events.append(None)
- self.addTrigger(phase, eventType, trigger)
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, [None])
-
-
- def test_beforePhase(self):
- """
- L{IReactorCore.addSystemEventTrigger} should accept the C{'before'}
- phase and not call the given object until the right event is fired.
- """
- self._addSystemEventTriggerTest('before')
-
-
- def test_duringPhase(self):
- """
- L{IReactorCore.addSystemEventTrigger} should accept the C{'during'}
- phase and not call the given object until the right event is fired.
- """
- self._addSystemEventTriggerTest('during')
-
-
- def test_afterPhase(self):
- """
- L{IReactorCore.addSystemEventTrigger} should accept the C{'after'}
- phase and not call the given object until the right event is fired.
- """
- self._addSystemEventTriggerTest('after')
-
-
- def test_unknownPhase(self):
- """
- L{IReactorCore.addSystemEventTrigger} should reject phases other than
- C{'before'}, C{'during'}, or C{'after'}.
- """
- eventType = 'test'
- self.assertRaises(
- KeyError, self.addTrigger, 'xxx', eventType, lambda: None)
-
-
- def test_beforePreceedsDuring(self):
- """
- L{IReactorCore.addSystemEventTrigger} should call triggers added to the
- C{'before'} phase before it calls triggers added to the C{'during'}
- phase.
- """
- eventType = 'test'
- events = []
- def beforeTrigger():
- events.append('before')
- def duringTrigger():
- events.append('during')
- self.addTrigger('before', eventType, beforeTrigger)
- self.addTrigger('during', eventType, duringTrigger)
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, ['before', 'during'])
-
-
- def test_duringPreceedsAfter(self):
- """
- L{IReactorCore.addSystemEventTrigger} should call triggers added to the
- C{'during'} phase before it calls triggers added to the C{'after'}
- phase.
- """
- eventType = 'test'
- events = []
- def duringTrigger():
- events.append('during')
- def afterTrigger():
- events.append('after')
- self.addTrigger('during', eventType, duringTrigger)
- self.addTrigger('after', eventType, afterTrigger)
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, ['during', 'after'])
-
-
- def test_beforeReturnsDeferred(self):
- """
- If a trigger added to the C{'before'} phase of an event returns a
- L{Deferred}, the C{'during'} phase should be delayed until it is called
- back.
- """
- triggerDeferred = Deferred()
- eventType = 'test'
- events = []
- def beforeTrigger():
- return triggerDeferred
- def duringTrigger():
- events.append('during')
- self.addTrigger('before', eventType, beforeTrigger)
- self.addTrigger('during', eventType, duringTrigger)
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, [])
- triggerDeferred.callback(None)
- self.assertEqual(events, ['during'])
-
-
- def test_multipleBeforeReturnDeferred(self):
- """
- If more than one trigger added to the C{'before'} phase of an event
- return L{Deferred}s, the C{'during'} phase should be delayed until they
- are all called back.
- """
- firstDeferred = Deferred()
- secondDeferred = Deferred()
- eventType = 'test'
- events = []
- def firstBeforeTrigger():
- return firstDeferred
- def secondBeforeTrigger():
- return secondDeferred
- def duringTrigger():
- events.append('during')
- self.addTrigger('before', eventType, firstBeforeTrigger)
- self.addTrigger('before', eventType, secondBeforeTrigger)
- self.addTrigger('during', eventType, duringTrigger)
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, [])
- firstDeferred.callback(None)
- self.assertEqual(events, [])
- secondDeferred.callback(None)
- self.assertEqual(events, ['during'])
-
-
- def test_subsequentBeforeTriggerFiresPriorBeforeDeferred(self):
- """
- If a trigger added to the C{'before'} phase of an event calls back a
- L{Deferred} returned by an earlier trigger in the C{'before'} phase of
- the same event, the remaining C{'before'} triggers for that event
- should be run and any further L{Deferred}s waited on before proceeding
- to the C{'during'} events.
- """
- eventType = 'test'
- events = []
- firstDeferred = Deferred()
- secondDeferred = Deferred()
- def firstBeforeTrigger():
- return firstDeferred
- def secondBeforeTrigger():
- firstDeferred.callback(None)
- def thirdBeforeTrigger():
- events.append('before')
- return secondDeferred
- def duringTrigger():
- events.append('during')
- self.addTrigger('before', eventType, firstBeforeTrigger)
- self.addTrigger('before', eventType, secondBeforeTrigger)
- self.addTrigger('before', eventType, thirdBeforeTrigger)
- self.addTrigger('during', eventType, duringTrigger)
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, ['before'])
- secondDeferred.callback(None)
- self.assertEqual(events, ['before', 'during'])
-
-
- def test_removeSystemEventTrigger(self):
- """
- A trigger removed with L{IReactorCore.removeSystemEventTrigger} should
- not be called when the event fires.
- """
- eventType = 'test'
- events = []
- def firstBeforeTrigger():
- events.append('first')
- def secondBeforeTrigger():
- events.append('second')
- self.addTrigger('before', eventType, firstBeforeTrigger)
- self.removeTrigger(
- self.addTrigger('before', eventType, secondBeforeTrigger))
- self.assertEqual(events, [])
- reactor.fireSystemEvent(eventType)
- self.assertEqual(events, ['first'])
-
-
- def test_removeNonExistentSystemEventTrigger(self):
- """
- Passing an object to L{IReactorCore.removeSystemEventTrigger} which was
- not returned by a previous call to
- L{IReactorCore.addSystemEventTrigger} or which has already been passed
- to C{removeSystemEventTrigger} should result in L{TypeError},
- L{KeyError}, or L{ValueError} being raised.
- """
- b = self.addTrigger('during', 'test', lambda: None)
- self.removeTrigger(b)
- self.assertRaises(
- TypeError, reactor.removeSystemEventTrigger, None)
- self.assertRaises(
- ValueError, reactor.removeSystemEventTrigger, b)
- self.assertRaises(
- KeyError,
- reactor.removeSystemEventTrigger,
- (b[0], ('xxx',) + b[1][1:]))
-
-
- def test_interactionBetweenDifferentEvents(self):
- """
- L{IReactorCore.fireSystemEvent} should behave the same way for a
- particular system event regardless of whether Deferreds are being
- waited on for a different system event.
- """
- events = []
-
- firstEvent = 'first-event'
- firstDeferred = Deferred()
- def beforeFirstEvent():
- events.append(('before', 'first'))
- return firstDeferred
- def afterFirstEvent():
- events.append(('after', 'first'))
-
- secondEvent = 'second-event'
- secondDeferred = Deferred()
- def beforeSecondEvent():
- events.append(('before', 'second'))
- return secondDeferred
- def afterSecondEvent():
- events.append(('after', 'second'))
-
- self.addTrigger('before', firstEvent, beforeFirstEvent)
- self.addTrigger('after', firstEvent, afterFirstEvent)
- self.addTrigger('before', secondEvent, beforeSecondEvent)
- self.addTrigger('after', secondEvent, afterSecondEvent)
-
- self.assertEqual(events, [])
-
- # After this, firstEvent should be stuck before 'during' waiting for
- # firstDeferred.
- reactor.fireSystemEvent(firstEvent)
- self.assertEqual(events, [('before', 'first')])
-
- # After this, secondEvent should be stuck before 'during' waiting for
- # secondDeferred.
- reactor.fireSystemEvent(secondEvent)
- self.assertEqual(events, [('before', 'first'), ('before', 'second')])
-
- # After this, firstEvent should have finished completely, but
- # secondEvent should be at the same place.
- firstDeferred.callback(None)
- self.assertEqual(events, [('before', 'first'), ('before', 'second'),
- ('after', 'first')])
-
- # After this, secondEvent should have finished completely.
- secondDeferred.callback(None)
- self.assertEqual(events, [('before', 'first'), ('before', 'second'),
- ('after', 'first'), ('after', 'second')])
-
-
-
-class TimeTestCase(unittest.TestCase):
- """
- Tests for the IReactorTime part of the reactor.
- """
-
-
- def test_seconds(self):
- """
- L{twisted.internet.reactor.seconds} should return something
- like a number.
-
- 1. This test specifically does not assert any relation to the
- "system time" as returned by L{time.time} or
- L{twisted.python.runtime.seconds}, because at some point we
- may find a better option for scheduling calls than
- wallclock-time.
- 2. This test *also* does not assert anything about the type of
- the result, because operations may not return ints or
- floats: For example, datetime-datetime == timedelta(0).
- """
- now = reactor.seconds()
- self.assertEqual(now-now+now, now)
-
-
- def test_callLaterUsesReactorSecondsInDelayedCall(self):
- """
- L{reactor.callLater} should use the reactor's seconds factory
- to produce the time at which the DelayedCall will be called.
- """
- oseconds = reactor.seconds
- reactor.seconds = lambda: 100
- try:
- call = reactor.callLater(5, lambda: None)
- self.assertEqual(call.getTime(), 105)
- finally:
- reactor.seconds = oseconds
-
-
- def test_callLaterUsesReactorSecondsAsDelayedCallSecondsFactory(self):
- """
- L{reactor.callLater} should propagate its own seconds factory
- to the DelayedCall to use as its own seconds factory.
- """
- oseconds = reactor.seconds
- reactor.seconds = lambda: 100
- try:
- call = reactor.callLater(5, lambda: None)
- self.assertEqual(call.seconds(), 100)
- finally:
- reactor.seconds = oseconds
-
-
- def test_callLater(self):
- """
- Test that a DelayedCall really calls the function it is
- supposed to call.
- """
- d = Deferred()
- reactor.callLater(0, d.callback, None)
- d.addCallback(self.assertEqual, None)
- return d
-
-
- def test_cancelDelayedCall(self):
- """
- Test that when a DelayedCall is cancelled it does not run.
- """
- called = []
- def function():
- called.append(None)
- call = reactor.callLater(0, function)
- call.cancel()
-
- # Schedule a call in two "iterations" to check to make sure that the
- # above call never ran.
- d = Deferred()
- def check():
- try:
- self.assertEqual(called, [])
- except:
- d.errback()
- else:
- d.callback(None)
- reactor.callLater(0, reactor.callLater, 0, check)
- return d
-
-
- def test_cancelCancelledDelayedCall(self):
- """
- Test that cancelling a DelayedCall which has already been cancelled
- raises the appropriate exception.
- """
- call = reactor.callLater(0, lambda: None)
- call.cancel()
- self.assertRaises(error.AlreadyCancelled, call.cancel)
-
-
- def test_cancelCalledDelayedCallSynchronous(self):
- """
- Test that cancelling a DelayedCall in the DelayedCall's function as
- that function is being invoked by the DelayedCall raises the
- appropriate exception.
- """
- d = Deferred()
- def later():
- try:
- self.assertRaises(error.AlreadyCalled, call.cancel)
- except:
- d.errback()
- else:
- d.callback(None)
- call = reactor.callLater(0, later)
- return d
-
-
- def test_cancelCalledDelayedCallAsynchronous(self):
- """
- Test that cancelling a DelayedCall after it has run its function
- raises the appropriate exception.
- """
- d = Deferred()
- def check():
- try:
- self.assertRaises(error.AlreadyCalled, call.cancel)
- except:
- d.errback()
- else:
- d.callback(None)
- def later():
- reactor.callLater(0, check)
- call = reactor.callLater(0, later)
- return d
-
-
- def testCallLaterTime(self):
- d = reactor.callLater(10, lambda: None)
- try:
- self.failUnless(d.getTime() - (time.time() + 10) < 1)
- finally:
- d.cancel()
-
- def testCallLaterOrder(self):
- l = []
- l2 = []
- def f(x):
- l.append(x)
- def f2(x):
- l2.append(x)
- def done():
- self.assertEqual(l, range(20))
- def done2():
- self.assertEqual(l2, range(10))
-
- for n in range(10):
- reactor.callLater(0, f, n)
- for n in range(10):
- reactor.callLater(0, f, n+10)
- reactor.callLater(0.1, f2, n)
-
- reactor.callLater(0, done)
- reactor.callLater(0.1, done2)
- d = Deferred()
- reactor.callLater(0.2, d.callback, None)
- return d
-
- testCallLaterOrder.todo = "See bug 1396"
- testCallLaterOrder.skip = "Trial bug, todo doesn't work! See bug 1397"
- def testCallLaterOrder2(self):
- # This time destroy the clock resolution so that it fails reliably
- # even on systems that don't have a crappy clock resolution.
-
- def seconds():
- return int(time.time())
-
- base_original = base.seconds
- runtime_original = runtime.seconds
- base.seconds = seconds
- runtime.seconds = seconds
-
- def cleanup(x):
- runtime.seconds = runtime_original
- base.seconds = base_original
- return x
- return maybeDeferred(self.testCallLaterOrder).addBoth(cleanup)
-
- testCallLaterOrder2.todo = "See bug 1396"
- testCallLaterOrder2.skip = "Trial bug, todo doesn't work! See bug 1397"
-
- def testDelayedCallStringification(self):
- # Mostly just make sure str() isn't going to raise anything for
- # DelayedCalls within reason.
- dc = reactor.callLater(0, lambda x, y: None, 'x', y=10)
- str(dc)
- dc.reset(5)
- str(dc)
- dc.cancel()
- str(dc)
-
- dc = reactor.callLater(0, lambda: None, x=[({'hello': u'world'}, 10j), reactor], *range(10))
- str(dc)
- dc.cancel()
- str(dc)
-
- def calledBack(ignored):
- str(dc)
- d = Deferred().addCallback(calledBack)
- dc = reactor.callLater(0, d.callback, None)
- str(dc)
- return d
-
-
- def testDelayedCallSecondsOverride(self):
- """
- Test that the C{seconds} argument to DelayedCall gets used instead of
- the default timing function, if it is not None.
- """
- def seconds():
- return 10
- dc = base.DelayedCall(5, lambda: None, (), {}, lambda dc: None,
- lambda dc: None, seconds)
- self.assertEqual(dc.getTime(), 5)
- dc.reset(3)
- self.assertEqual(dc.getTime(), 13)
-
-
-class CallFromThreadTests(unittest.TestCase):
- def testWakeUp(self):
- # Make sure other threads can wake up the reactor
- d = Deferred()
- def wake():
- time.sleep(0.1)
- # callFromThread will call wakeUp for us
- reactor.callFromThread(d.callback, None)
- reactor.callInThread(wake)
- return d
-
- if interfaces.IReactorThreads(reactor, None) is None:
- testWakeUp.skip = "Nothing to wake up for without thread support"
-
- def _stopCallFromThreadCallback(self):
- self.stopped = True
-
- def _callFromThreadCallback(self, d):
- reactor.callFromThread(self._callFromThreadCallback2, d)
- reactor.callLater(0, self._stopCallFromThreadCallback)
-
- def _callFromThreadCallback2(self, d):
- try:
- self.assert_(self.stopped)
- except:
- # Send the error to the deferred
- d.errback()
- else:
- d.callback(None)
-
- def testCallFromThreadStops(self):
- """
- Ensure that callFromThread from inside a callFromThread
- callback doesn't sit in an infinite loop and lets other
- things happen too.
- """
- self.stopped = False
- d = defer.Deferred()
- reactor.callFromThread(self._callFromThreadCallback, d)
- return d
-
-
-class DelayedTestCase(unittest.TestCase):
- def setUp(self):
- self.finished = 0
- self.counter = 0
- self.timers = {}
- self.deferred = defer.Deferred()
-
- def tearDown(self):
- for t in self.timers.values():
- t.cancel()
-
- def checkTimers(self):
- l1 = self.timers.values()
- l2 = list(reactor.getDelayedCalls())
-
- # There should be at least the calls we put in. There may be other
- # calls that are none of our business and that we should ignore,
- # though.
-
- missing = []
- for dc in l1:
- if dc not in l2:
- missing.append(dc)
- if missing:
- self.finished = 1
- self.failIf(missing, "Should have been missing no calls, instead was missing " + repr(missing))
-
- def callback(self, tag):
- del self.timers[tag]
- self.checkTimers()
-
- def addCallback(self, tag):
- self.callback(tag)
- self.addTimer(15, self.callback)
-
- def done(self, tag):
- self.finished = 1
- self.callback(tag)
- self.deferred.callback(None)
-
- def addTimer(self, when, callback):
- self.timers[self.counter] = reactor.callLater(when * 0.01, callback,
- self.counter)
- self.counter += 1
- self.checkTimers()
-
- def testGetDelayedCalls(self):
- if not hasattr(reactor, "getDelayedCalls"):
- return
- # This is not a race because we don't do anything which might call
- # the reactor until we have all the timers set up. If we did, this
- # test might fail on slow systems.
- self.checkTimers()
- self.addTimer(35, self.done)
- self.addTimer(20, self.callback)
- self.addTimer(30, self.callback)
- which = self.counter
- self.addTimer(29, self.callback)
- self.addTimer(25, self.addCallback)
- self.addTimer(26, self.callback)
-
- self.timers[which].cancel()
- del self.timers[which]
- self.checkTimers()
-
- self.deferred.addCallback(lambda x : self.checkTimers())
- return self.deferred
-
-
- def test_active(self):
- """
- L{IDelayedCall.active} returns False once the call has run.
- """
- dcall = reactor.callLater(0.01, self.deferred.callback, True)
- self.assertEqual(dcall.active(), True)
-
- def checkDeferredCall(success):
- self.assertEqual(dcall.active(), False)
- return success
-
- self.deferred.addCallback(checkDeferredCall)
-
- return self.deferred
-
-
-
-resolve_helper = """
-import %(reactor)s
-%(reactor)s.install()
-from twisted.internet import reactor
-
-class Foo:
- def __init__(self):
- reactor.callWhenRunning(self.start)
- self.timer = reactor.callLater(3, self.failed)
- def start(self):
- reactor.resolve('localhost').addBoth(self.done)
- def done(self, res):
- print 'done', res
- reactor.stop()
- def failed(self):
- print 'failed'
- self.timer = None
- reactor.stop()
-f = Foo()
-reactor.run()
-"""
-
-class ChildResolveProtocol(protocol.ProcessProtocol):
- def __init__(self, onCompletion):
- self.onCompletion = onCompletion
-
- def connectionMade(self):
- self.output = []
- self.error = []
-
- def outReceived(self, out):
- self.output.append(out)
-
- def errReceived(self, err):
- self.error.append(err)
-
- def processEnded(self, reason):
- self.onCompletion.callback((reason, self.output, self.error))
- self.onCompletion = None
-
-
-class Resolve(unittest.TestCase):
- def testChildResolve(self):
- # I've seen problems with reactor.run under gtk2reactor. Spawn a
- # child which just does reactor.resolve after the reactor has
- # started, fail if it does not complete in a timely fashion.
- helperPath = os.path.abspath(self.mktemp())
- helperFile = open(helperPath, 'w')
-
- # Eeueuuggg
- reactorName = reactor.__module__
-
- helperFile.write(resolve_helper % {'reactor': reactorName})
- helperFile.close()
-
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
-
- helperDeferred = Deferred()
- helperProto = ChildResolveProtocol(helperDeferred)
-
- reactor.spawnProcess(helperProto, sys.executable, ("python", "-u", helperPath), env)
-
- def cbFinished((reason, output, error)):
- # If the output is "done 127.0.0.1\n" we don't really care what
- # else happened.
- output = ''.join(output)
- if output != 'done 127.0.0.1\n':
- self.fail((
- "The child process failed to produce the desired results:\n"
- " Reason for termination was: %r\n"
- " Output stream was: %r\n"
- " Error stream was: %r\n") % (reason.getErrorMessage(), output, ''.join(error)))
-
- helperDeferred.addCallback(cbFinished)
- return helperDeferred
-
-if not interfaces.IReactorProcess(reactor, None):
- Resolve.skip = "cannot run test: reactor doesn't support IReactorProcess"
-
-
-
-class CallFromThreadTestCase(unittest.TestCase):
- """
- Task scheduling from threads tests.
- """
- if interfaces.IReactorThreads(reactor, None) is None:
- skip = "Nothing to test without thread support"
-
- def setUp(self):
- self.counter = 0
- self.deferred = Deferred()
-
-
- def schedule(self, *args, **kwargs):
- """
- Override in subclasses.
- """
- reactor.callFromThread(*args, **kwargs)
-
-
- def test_lotsOfThreadsAreScheduledCorrectly(self):
- """
- L{IReactorThreads.callFromThread} can be used to schedule a large
- number of calls in the reactor thread.
- """
- def addAndMaybeFinish():
- self.counter += 1
- if self.counter == 100:
- self.deferred.callback(True)
-
- for i in xrange(100):
- self.schedule(addAndMaybeFinish)
-
- return self.deferred
-
-
- def test_threadsAreRunInScheduledOrder(self):
- """
- Callbacks should be invoked in the order they were scheduled.
- """
- order = []
-
- def check(_):
- self.assertEqual(order, [1, 2, 3])
-
- self.deferred.addCallback(check)
- self.schedule(order.append, 1)
- self.schedule(order.append, 2)
- self.schedule(order.append, 3)
- self.schedule(reactor.callFromThread, self.deferred.callback, None)
-
- return self.deferred
-
-
- def test_scheduledThreadsNotRunUntilReactorRuns(self):
- """
- Scheduled tasks should not be run until the reactor starts running.
- """
- def incAndFinish():
- self.counter = 1
- self.deferred.callback(True)
- self.schedule(incAndFinish)
-
- # Callback shouldn't have fired yet.
- self.assertEqual(self.counter, 0)
-
- return self.deferred
-
-
-
-class MyProtocol(protocol.Protocol):
- """
- Sample protocol.
- """
-
-class MyFactory(protocol.Factory):
- """
- Sample factory.
- """
-
- protocol = MyProtocol
-
-
-class ProtocolTestCase(unittest.TestCase):
-
- def testFactory(self):
- factory = MyFactory()
- protocol = factory.buildProtocol(None)
- self.assertEqual(protocol.factory, factory)
- self.assert_( isinstance(protocol, factory.protocol) )
-
-
-class DummyProducer(object):
- """
- Very uninteresting producer implementation used by tests to ensure the
- right methods are called by the consumer with which it is registered.
-
- @type events: C{list} of C{str}
- @ivar events: The producer/consumer related events which have happened to
- this producer. Strings in this list may be C{'resume'}, C{'stop'}, or
- C{'pause'}. Elements are added as they occur.
- """
-
- def __init__(self):
- self.events = []
-
-
- def resumeProducing(self):
- self.events.append('resume')
-
-
- def stopProducing(self):
- self.events.append('stop')
-
-
- def pauseProducing(self):
- self.events.append('pause')
-
-
-
-class SillyDescriptor(abstract.FileDescriptor):
- """
- A descriptor whose data buffer gets filled very fast.
-
- Useful for testing FileDescriptor's IConsumer interface, since
- the data buffer fills as soon as at least four characters are
- written to it, and gets emptied in a single doWrite() cycle.
- """
- bufferSize = 3
- connected = True
-
- def writeSomeData(self, data):
- """
- Always write all data.
- """
- return len(data)
-
-
- def startWriting(self):
- """
- Do nothing: bypass the reactor.
- """
- stopWriting = startWriting
-
-
-
-class ReentrantProducer(DummyProducer):
- """
- Similar to L{DummyProducer}, but with a resumeProducing method which calls
- back into an L{IConsumer} method of the consumer against which it is
- registered.
-
- @ivar consumer: The consumer with which this producer has been or will
- be registered.
-
- @ivar methodName: The name of the method to call on the consumer inside
- C{resumeProducing}.
-
- @ivar methodArgs: The arguments to pass to the consumer method invoked in
- C{resumeProducing}.
- """
- def __init__(self, consumer, methodName, *methodArgs):
- super(ReentrantProducer, self).__init__()
- self.consumer = consumer
- self.methodName = methodName
- self.methodArgs = methodArgs
-
-
- def resumeProducing(self):
- super(ReentrantProducer, self).resumeProducing()
- getattr(self.consumer, self.methodName)(*self.methodArgs)
-
-
-
-class TestProducer(unittest.TestCase):
- """
- Test abstract.FileDescriptor's consumer interface.
- """
- def test_doubleProducer(self):
- """
- Verify that registering a non-streaming producer invokes its
- resumeProducing() method and that you can only register one producer
- at a time.
- """
- fd = abstract.FileDescriptor()
- fd.connected = 1
- dp = DummyProducer()
- fd.registerProducer(dp, 0)
- self.assertEqual(dp.events, ['resume'])
- self.assertRaises(RuntimeError, fd.registerProducer, DummyProducer(), 0)
-
-
- def test_unconnectedFileDescriptor(self):
- """
- Verify that registering a producer when the connection has already
- been closed invokes its stopProducing() method.
- """
- fd = abstract.FileDescriptor()
- fd.disconnected = 1
- dp = DummyProducer()
- fd.registerProducer(dp, 0)
- self.assertEqual(dp.events, ['stop'])
-
-
- def _dontPausePullConsumerTest(self, methodName):
- descriptor = SillyDescriptor()
- producer = DummyProducer()
- descriptor.registerProducer(producer, streaming=False)
- self.assertEqual(producer.events, ['resume'])
- del producer.events[:]
-
- # Fill up the descriptor's write buffer so we can observe whether or
- # not it pauses its producer in that case.
- getattr(descriptor, methodName)('1234')
-
- self.assertEqual(producer.events, [])
-
-
- def test_dontPausePullConsumerOnWrite(self):
- """
- Verify that FileDescriptor does not call producer.pauseProducing() on a
- non-streaming pull producer in response to a L{IConsumer.write} call
- which results in a full write buffer. Issue #2286.
- """
- return self._dontPausePullConsumerTest('write')
-
-
- def test_dontPausePullConsumerOnWriteSequence(self):
- """
- Like L{test_dontPausePullConsumerOnWrite}, but for a call to
- C{writeSequence} rather than L{IConsumer.write}.
-
- C{writeSequence} is not part of L{IConsumer}, but
- L{abstract.FileDescriptor} has supported consumery behavior in response
- to calls to L{writeSequence} forever.
- """
- return self._dontPausePullConsumerTest('writeSequence')
-
-
- def _reentrantStreamingProducerTest(self, methodName):
- descriptor = SillyDescriptor()
- producer = ReentrantProducer(descriptor, methodName, 'spam')
- descriptor.registerProducer(producer, streaming=True)
-
- # Start things off by filling up the descriptor's buffer so it will
- # pause its producer.
- getattr(descriptor, methodName)('spam')
-
- # Sanity check - make sure that worked.
- self.assertEqual(producer.events, ['pause'])
- del producer.events[:]
-
- # After one call to doWrite, the buffer has been emptied so the
- # FileDescriptor should resume its producer. That will result in an
- # immediate call to FileDescriptor.write which will again fill the
- # buffer and result in the producer being paused.
- descriptor.doWrite()
- self.assertEqual(producer.events, ['resume', 'pause'])
- del producer.events[:]
-
- # After a second call to doWrite, the exact same thing should have
- # happened. Prior to the bugfix for which this test was written,
- # FileDescriptor would have incorrectly believed its producer was
- # already resumed (it was paused) and so not resume it again.
- descriptor.doWrite()
- self.assertEqual(producer.events, ['resume', 'pause'])
-
-
- def test_reentrantStreamingProducerUsingWrite(self):
- """
- Verify that FileDescriptor tracks producer's paused state correctly.
- Issue #811, fixed in revision r12857.
- """
- return self._reentrantStreamingProducerTest('write')
-
-
- def test_reentrantStreamingProducerUsingWriteSequence(self):
- """
- Like L{test_reentrantStreamingProducerUsingWrite}, but for calls to
- C{writeSequence}.
-
- C{writeSequence} is B{not} part of L{IConsumer}, however
- C{abstract.FileDescriptor} has supported consumery behavior in response
- to calls to C{writeSequence} forever.
- """
- return self._reentrantStreamingProducerTest('writeSequence')
-
-
-
-class PortStringification(unittest.TestCase):
- if interfaces.IReactorTCP(reactor, None) is not None:
- def testTCP(self):
- p = reactor.listenTCP(0, protocol.ServerFactory())
- portNo = p.getHost().port
- self.assertNotEqual(str(p).find(str(portNo)), -1,
- "%d not found in %s" % (portNo, p))
- return p.stopListening()
-
- if interfaces.IReactorUDP(reactor, None) is not None:
- def testUDP(self):
- p = reactor.listenUDP(0, protocol.DatagramProtocol())
- portNo = p.getHost().port
- self.assertNotEqual(str(p).find(str(portNo)), -1,
- "%d not found in %s" % (portNo, p))
- return p.stopListening()
-
- if interfaces.IReactorSSL(reactor, None) is not None and ssl:
- def testSSL(self, ssl=ssl):
- pem = util.sibpath(__file__, 'server.pem')
- p = reactor.listenSSL(0, protocol.ServerFactory(), ssl.DefaultOpenSSLContextFactory(pem, pem))
- portNo = p.getHost().port
- self.assertNotEqual(str(p).find(str(portNo)), -1,
- "%d not found in %s" % (portNo, p))
- return p.stopListening()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_iutils.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_iutils.py
deleted file mode 100755
index d89ab567..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_iutils.py
+++ /dev/null
@@ -1,296 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test running processes with the APIs in L{twisted.internet.utils}.
-"""
-
-import warnings, os, stat, sys, signal
-
-from twisted.python.runtime import platform
-from twisted.trial import unittest
-from twisted.internet import error, reactor, utils, interfaces
-
-
-class ProcessUtilsTests(unittest.TestCase):
- """
- Test running a process using L{getProcessOutput}, L{getProcessValue}, and
- L{getProcessOutputAndValue}.
- """
-
- if interfaces.IReactorProcess(reactor, None) is None:
- skip = "reactor doesn't implement IReactorProcess"
-
- output = None
- value = None
- exe = sys.executable
-
- def makeSourceFile(self, sourceLines):
- """
- Write the given list of lines to a text file and return the absolute
- path to it.
- """
- script = self.mktemp()
- scriptFile = file(script, 'wt')
- scriptFile.write(os.linesep.join(sourceLines) + os.linesep)
- scriptFile.close()
- return os.path.abspath(script)
-
-
- def test_output(self):
- """
- L{getProcessOutput} returns a L{Deferred} which fires with the complete
- output of the process it runs after that process exits.
- """
- scriptFile = self.makeSourceFile([
- "import sys",
- "for s in 'hello world\\n':",
- " sys.stdout.write(s)",
- " sys.stdout.flush()"])
- d = utils.getProcessOutput(self.exe, ['-u', scriptFile])
- return d.addCallback(self.assertEqual, "hello world\n")
-
-
- def test_outputWithErrorIgnored(self):
- """
- The L{Deferred} returned by L{getProcessOutput} is fired with an
- L{IOError} L{Failure} if the child process writes to stderr.
- """
- # make sure stderr raises an error normally
- scriptFile = self.makeSourceFile([
- 'import sys',
- 'sys.stderr.write("hello world\\n")'
- ])
-
- d = utils.getProcessOutput(self.exe, ['-u', scriptFile])
- d = self.assertFailure(d, IOError)
- def cbFailed(err):
- return self.assertFailure(err.processEnded, error.ProcessDone)
- d.addCallback(cbFailed)
- return d
-
-
- def test_outputWithErrorCollected(self):
- """
- If a C{True} value is supplied for the C{errortoo} parameter to
- L{getProcessOutput}, the returned L{Deferred} fires with the child's
- stderr output as well as its stdout output.
- """
- scriptFile = self.makeSourceFile([
- 'import sys',
- # Write the same value to both because ordering isn't guaranteed so
- # this simplifies the test.
- 'sys.stdout.write("foo")',
- 'sys.stdout.flush()',
- 'sys.stderr.write("foo")',
- 'sys.stderr.flush()'])
-
- d = utils.getProcessOutput(self.exe, ['-u', scriptFile], errortoo=True)
- return d.addCallback(self.assertEqual, "foofoo")
-
-
- def test_value(self):
- """
- The L{Deferred} returned by L{getProcessValue} is fired with the exit
- status of the child process.
- """
- scriptFile = self.makeSourceFile(["raise SystemExit(1)"])
-
- d = utils.getProcessValue(self.exe, ['-u', scriptFile])
- return d.addCallback(self.assertEqual, 1)
-
-
- def test_outputAndValue(self):
- """
- The L{Deferred} returned by L{getProcessOutputAndValue} fires with a
- three-tuple, the elements of which give the data written to the child's
- stdout, the data written to the child's stderr, and the exit status of
- the child.
- """
- exe = sys.executable
- scriptFile = self.makeSourceFile([
- "import sys",
- "sys.stdout.write('hello world!\\n')",
- "sys.stderr.write('goodbye world!\\n')",
- "sys.exit(1)"
- ])
-
- def gotOutputAndValue((out, err, code)):
- self.assertEqual(out, "hello world!\n")
- self.assertEqual(err, "goodbye world!" + os.linesep)
- self.assertEqual(code, 1)
- d = utils.getProcessOutputAndValue(self.exe, ["-u", scriptFile])
- return d.addCallback(gotOutputAndValue)
-
-
- def test_outputSignal(self):
- """
- If the child process exits because of a signal, the L{Deferred}
- returned by L{getProcessOutputAndValue} fires a L{Failure} of a tuple
- containing the the child's stdout, stderr, and the signal which caused
- it to exit.
- """
- # Use SIGKILL here because it's guaranteed to be delivered. Using
- # SIGHUP might not work in, e.g., a buildbot slave run under the
- # 'nohup' command.
- scriptFile = self.makeSourceFile([
- "import sys, os, signal",
- "sys.stdout.write('stdout bytes\\n')",
- "sys.stderr.write('stderr bytes\\n')",
- "sys.stdout.flush()",
- "sys.stderr.flush()",
- "os.kill(os.getpid(), signal.SIGKILL)"])
-
- def gotOutputAndValue((out, err, sig)):
- self.assertEqual(out, "stdout bytes\n")
- self.assertEqual(err, "stderr bytes\n")
- self.assertEqual(sig, signal.SIGKILL)
-
- d = utils.getProcessOutputAndValue(self.exe, ['-u', scriptFile])
- d = self.assertFailure(d, tuple)
- return d.addCallback(gotOutputAndValue)
-
- if platform.isWindows():
- test_outputSignal.skip = "Windows doesn't have real signals."
-
-
- def _pathTest(self, utilFunc, check):
- dir = os.path.abspath(self.mktemp())
- os.makedirs(dir)
- scriptFile = self.makeSourceFile([
- "import os, sys",
- "sys.stdout.write(os.getcwd())"])
- d = utilFunc(self.exe, ['-u', scriptFile], path=dir)
- d.addCallback(check, dir)
- return d
-
-
- def test_getProcessOutputPath(self):
- """
- L{getProcessOutput} runs the given command with the working directory
- given by the C{path} parameter.
- """
- return self._pathTest(utils.getProcessOutput, self.assertEqual)
-
-
- def test_getProcessValuePath(self):
- """
- L{getProcessValue} runs the given command with the working directory
- given by the C{path} parameter.
- """
- def check(result, ignored):
- self.assertEqual(result, 0)
- return self._pathTest(utils.getProcessValue, check)
-
-
- def test_getProcessOutputAndValuePath(self):
- """
- L{getProcessOutputAndValue} runs the given command with the working
- directory given by the C{path} parameter.
- """
- def check((out, err, status), dir):
- self.assertEqual(out, dir)
- self.assertEqual(status, 0)
- return self._pathTest(utils.getProcessOutputAndValue, check)
-
-
- def _defaultPathTest(self, utilFunc, check):
- # Make another directory to mess around with.
- dir = os.path.abspath(self.mktemp())
- os.makedirs(dir)
-
- scriptFile = self.makeSourceFile([
- "import os, sys, stat",
- # Fix the permissions so we can report the working directory.
- # On OS X (and maybe elsewhere), os.getcwd() fails with EACCES
- # if +x is missing from the working directory.
- "os.chmod(%r, stat.S_IXUSR)" % (dir,),
- "sys.stdout.write(os.getcwd())"])
-
- # Switch to it, but make sure we switch back
- self.addCleanup(os.chdir, os.getcwd())
- os.chdir(dir)
-
- # Get rid of all its permissions, but make sure they get cleaned up
- # later, because otherwise it might be hard to delete the trial
- # temporary directory.
- self.addCleanup(
- os.chmod, dir, stat.S_IMODE(os.stat('.').st_mode))
- os.chmod(dir, 0)
-
- d = utilFunc(self.exe, ['-u', scriptFile])
- d.addCallback(check, dir)
- return d
-
-
- def test_getProcessOutputDefaultPath(self):
- """
- If no value is supplied for the C{path} parameter, L{getProcessOutput}
- runs the given command in the same working directory as the parent
- process and succeeds even if the current working directory is not
- accessible.
- """
- return self._defaultPathTest(utils.getProcessOutput, self.assertEqual)
-
-
- def test_getProcessValueDefaultPath(self):
- """
- If no value is supplied for the C{path} parameter, L{getProcessValue}
- runs the given command in the same working directory as the parent
- process and succeeds even if the current working directory is not
- accessible.
- """
- def check(result, ignored):
- self.assertEqual(result, 0)
- return self._defaultPathTest(utils.getProcessValue, check)
-
-
- def test_getProcessOutputAndValueDefaultPath(self):
- """
- If no value is supplied for the C{path} parameter,
- L{getProcessOutputAndValue} runs the given command in the same working
- directory as the parent process and succeeds even if the current
- working directory is not accessible.
- """
- def check((out, err, status), dir):
- self.assertEqual(out, dir)
- self.assertEqual(status, 0)
- return self._defaultPathTest(
- utils.getProcessOutputAndValue, check)
-
-
-
-class WarningSuppression(unittest.TestCase):
- def setUp(self):
- self.warnings = []
- self.originalshow = warnings.showwarning
- warnings.showwarning = self.showwarning
-
-
- def tearDown(self):
- warnings.showwarning = self.originalshow
-
-
- def showwarning(self, *a, **kw):
- self.warnings.append((a, kw))
-
-
- def testSuppressWarnings(self):
- def f(msg):
- warnings.warn(msg)
- g = utils.suppressWarnings(f, (('ignore',), dict(message="This is message")))
-
- # Start off with a sanity check - calling the original function
- # should emit the warning.
- f("Sanity check message")
- self.assertEqual(len(self.warnings), 1)
-
- # Now that that's out of the way, call the wrapped function, and
- # make sure no new warnings show up.
- g("This is message")
- self.assertEqual(len(self.warnings), 1)
-
- # Finally, emit another warning which should not be ignored, and
- # make sure it is not.
- g("Unignored message")
- self.assertEqual(len(self.warnings), 2)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_jelly.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_jelly.py
deleted file mode 100755
index 132e05f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_jelly.py
+++ /dev/null
@@ -1,671 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for L{jelly} object serialization.
-"""
-
-import datetime
-
-try:
- import decimal
-except ImportError:
- decimal = None
-
-from twisted.spread import jelly, pb
-from twisted.python.compat import set, frozenset
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport
-
-
-class TestNode(object, jelly.Jellyable):
- """
- An object to test jellyfying of new style class instances.
- """
- classAttr = 4
-
- def __init__(self, parent=None):
- if parent:
- self.id = parent.id + 1
- parent.children.append(self)
- else:
- self.id = 1
- self.parent = parent
- self.children = []
-
-
-
-class A:
- """
- Dummy class.
- """
-
- def amethod(self):
- """
- Method tp be used in serialization tests.
- """
-
-
-
-def afunc(self):
- """
- A dummy function to test function serialization.
- """
-
-
-
-class B:
- """
- Dummy class.
- """
-
- def bmethod(self):
- """
- Method to be used in serialization tests.
- """
-
-
-
-class C:
- """
- Dummy class.
- """
-
- def cmethod(self):
- """
- Method to be used in serialization tests.
- """
-
-
-
-class D(object):
- """
- Dummy new-style class.
- """
-
-
-
-class E(object):
- """
- Dummy new-style class with slots.
- """
-
- __slots__ = ("x", "y")
-
- def __init__(self, x=None, y=None):
- self.x = x
- self.y = y
-
-
- def __getstate__(self):
- return {"x" : self.x, "y" : self.y}
-
-
- def __setstate__(self, state):
- self.x = state["x"]
- self.y = state["y"]
-
-
-
-class SimpleJellyTest:
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
- def isTheSameAs(self, other):
- return self.__dict__ == other.__dict__
-
-
-
-class JellyTestCase(unittest.TestCase):
- """
- Testcases for L{jelly} module serialization.
-
- @cvar decimalData: serialized version of decimal data, to be used in tests.
- @type decimalData: C{list}
- """
-
- def _testSecurity(self, inputList, atom):
- """
- Helper test method to test security options for a type.
-
- @param inputList: a sample input for the type.
- @param inputList: C{list}
-
- @param atom: atom identifier for the type.
- @type atom: C{str}
- """
- c = jelly.jelly(inputList)
- taster = jelly.SecurityOptions()
- taster.allowBasicTypes()
- # By default, it should succeed
- jelly.unjelly(c, taster)
- taster.allowedTypes.pop(atom)
- # But it should raise an exception when disallowed
- self.assertRaises(jelly.InsecureJelly, jelly.unjelly, c, taster)
-
-
- def test_methodSelfIdentity(self):
- a = A()
- b = B()
- a.bmethod = b.bmethod
- b.a = a
- im_ = jelly.unjelly(jelly.jelly(b)).a.bmethod
- self.assertEqual(im_.im_class, im_.im_self.__class__)
-
-
- def test_methodsNotSelfIdentity(self):
- """
- If a class change after an instance has been created, L{jelly.unjelly}
- shoud raise a C{TypeError} when trying to unjelly the instance.
- """
- a = A()
- b = B()
- c = C()
- a.bmethod = c.cmethod
- b.a = a
- savecmethod = C.cmethod
- del C.cmethod
- try:
- self.assertRaises(TypeError, jelly.unjelly, jelly.jelly(b))
- finally:
- C.cmethod = savecmethod
-
-
- def test_newStyle(self):
- n = D()
- n.x = 1
- n2 = D()
- n.n2 = n2
- n.n3 = n2
- c = jelly.jelly(n)
- m = jelly.unjelly(c)
- self.assertIsInstance(m, D)
- self.assertIdentical(m.n2, m.n3)
-
-
- def test_newStyleWithSlots(self):
- """
- A class defined with I{slots} can be jellied and unjellied with the
- values for its attributes preserved.
- """
- n = E()
- n.x = 1
- c = jelly.jelly(n)
- m = jelly.unjelly(c)
- self.assertIsInstance(m, E)
- self.assertEqual(n.x, 1)
-
-
- def test_typeOldStyle(self):
- """
- Test that an old style class type can be jellied and unjellied
- to the original type.
- """
- t = [C]
- r = jelly.unjelly(jelly.jelly(t))
- self.assertEqual(t, r)
-
-
- def test_typeNewStyle(self):
- """
- Test that a new style class type can be jellied and unjellied
- to the original type.
- """
- t = [D]
- r = jelly.unjelly(jelly.jelly(t))
- self.assertEqual(t, r)
-
-
- def test_typeBuiltin(self):
- """
- Test that a builtin type can be jellied and unjellied to the original
- type.
- """
- t = [str]
- r = jelly.unjelly(jelly.jelly(t))
- self.assertEqual(t, r)
-
-
- def test_dateTime(self):
- dtn = datetime.datetime.now()
- dtd = datetime.datetime.now() - dtn
- input = [dtn, dtd]
- c = jelly.jelly(input)
- output = jelly.unjelly(c)
- self.assertEqual(input, output)
- self.assertNotIdentical(input, output)
-
-
- def test_decimal(self):
- """
- Jellying L{decimal.Decimal} instances and then unjellying the result
- should produce objects which represent the values of the original
- inputs.
- """
- inputList = [decimal.Decimal('9.95'),
- decimal.Decimal(0),
- decimal.Decimal(123456),
- decimal.Decimal('-78.901')]
- c = jelly.jelly(inputList)
- output = jelly.unjelly(c)
- self.assertEqual(inputList, output)
- self.assertNotIdentical(inputList, output)
-
-
- decimalData = ['list', ['decimal', 995, -2], ['decimal', 0, 0],
- ['decimal', 123456, 0], ['decimal', -78901, -3]]
-
-
- def test_decimalUnjelly(self):
- """
- Unjellying the s-expressions produced by jelly for L{decimal.Decimal}
- instances should result in L{decimal.Decimal} instances with the values
- represented by the s-expressions.
-
- This test also verifies that C{self.decimalData} contains valid jellied
- data. This is important since L{test_decimalMissing} re-uses
- C{self.decimalData} and is expected to be unable to produce
- L{decimal.Decimal} instances even though the s-expression correctly
- represents a list of them.
- """
- expected = [decimal.Decimal('9.95'),
- decimal.Decimal(0),
- decimal.Decimal(123456),
- decimal.Decimal('-78.901')]
- output = jelly.unjelly(self.decimalData)
- self.assertEqual(output, expected)
-
-
- def test_decimalMissing(self):
- """
- If decimal is unavailable on the unjelly side, L{jelly.unjelly} should
- gracefully return L{jelly.Unpersistable} objects.
- """
- self.patch(jelly, 'decimal', None)
- output = jelly.unjelly(self.decimalData)
- self.assertEqual(len(output), 4)
- for i in range(4):
- self.assertIsInstance(output[i], jelly.Unpersistable)
- self.assertEqual(output[0].reason,
- "Could not unpersist decimal: 9.95")
- self.assertEqual(output[1].reason,
- "Could not unpersist decimal: 0")
- self.assertEqual(output[2].reason,
- "Could not unpersist decimal: 123456")
- self.assertEqual(output[3].reason,
- "Could not unpersist decimal: -78.901")
-
-
- def test_decimalSecurity(self):
- """
- By default, C{decimal} objects should be allowed by
- L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
- L{jelly.InsecureJelly} when trying to unjelly it.
- """
- inputList = [decimal.Decimal('9.95')]
- self._testSecurity(inputList, "decimal")
-
- if decimal is None:
- skipReason = "decimal not available"
- test_decimal.skip = skipReason
- test_decimalUnjelly.skip = skipReason
- test_decimalSecurity.skip = skipReason
-
-
- def test_set(self):
- """
- Jellying C{set} instances and then unjellying the result
- should produce objects which represent the values of the original
- inputs.
- """
- inputList = [set([1, 2, 3])]
- output = jelly.unjelly(jelly.jelly(inputList))
- self.assertEqual(inputList, output)
- self.assertNotIdentical(inputList, output)
-
-
- def test_frozenset(self):
- """
- Jellying C{frozenset} instances and then unjellying the result
- should produce objects which represent the values of the original
- inputs.
- """
- inputList = [frozenset([1, 2, 3])]
- output = jelly.unjelly(jelly.jelly(inputList))
- self.assertEqual(inputList, output)
- self.assertNotIdentical(inputList, output)
-
-
- def test_setSecurity(self):
- """
- By default, C{set} objects should be allowed by
- L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
- L{jelly.InsecureJelly} when trying to unjelly it.
- """
- inputList = [set([1, 2, 3])]
- self._testSecurity(inputList, "set")
-
-
- def test_frozensetSecurity(self):
- """
- By default, C{frozenset} objects should be allowed by
- L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
- L{jelly.InsecureJelly} when trying to unjelly it.
- """
- inputList = [frozenset([1, 2, 3])]
- self._testSecurity(inputList, "frozenset")
-
-
- def test_oldSets(self):
- """
- Test jellying C{sets.Set}: it should serialize to the same thing as
- C{set} jelly, and be unjellied as C{set} if available.
- """
- inputList = [jelly._sets.Set([1, 2, 3])]
- inputJelly = jelly.jelly(inputList)
- self.assertEqual(inputJelly, jelly.jelly([set([1, 2, 3])]))
- output = jelly.unjelly(inputJelly)
- # Even if the class is different, it should coerce to the same list
- self.assertEqual(list(inputList[0]), list(output[0]))
- if set is jelly._sets.Set:
- self.assertIsInstance(output[0], jelly._sets.Set)
- else:
- self.assertIsInstance(output[0], set)
-
-
- def test_oldImmutableSets(self):
- """
- Test jellying C{sets.ImmutableSet}: it should serialize to the same
- thing as C{frozenset} jelly, and be unjellied as C{frozenset} if
- available.
- """
- inputList = [jelly._sets.ImmutableSet([1, 2, 3])]
- inputJelly = jelly.jelly(inputList)
- self.assertEqual(inputJelly, jelly.jelly([frozenset([1, 2, 3])]))
- output = jelly.unjelly(inputJelly)
- # Even if the class is different, it should coerce to the same list
- self.assertEqual(list(inputList[0]), list(output[0]))
- if frozenset is jelly._sets.ImmutableSet:
- self.assertIsInstance(output[0], jelly._sets.ImmutableSet)
- else:
- self.assertIsInstance(output[0], frozenset)
-
-
- def test_simple(self):
- """
- Simplest test case.
- """
- self.failUnless(SimpleJellyTest('a', 'b').isTheSameAs(
- SimpleJellyTest('a', 'b')))
- a = SimpleJellyTest(1, 2)
- cereal = jelly.jelly(a)
- b = jelly.unjelly(cereal)
- self.failUnless(a.isTheSameAs(b))
-
-
- def test_identity(self):
- """
- Test to make sure that objects retain identity properly.
- """
- x = []
- y = (x)
- x.append(y)
- x.append(y)
- self.assertIdentical(x[0], x[1])
- self.assertIdentical(x[0][0], x)
- s = jelly.jelly(x)
- z = jelly.unjelly(s)
- self.assertIdentical(z[0], z[1])
- self.assertIdentical(z[0][0], z)
-
-
- def test_unicode(self):
- x = unicode('blah')
- y = jelly.unjelly(jelly.jelly(x))
- self.assertEqual(x, y)
- self.assertEqual(type(x), type(y))
-
-
- def test_stressReferences(self):
- reref = []
- toplevelTuple = ({'list': reref}, reref)
- reref.append(toplevelTuple)
- s = jelly.jelly(toplevelTuple)
- z = jelly.unjelly(s)
- self.assertIdentical(z[0]['list'], z[1])
- self.assertIdentical(z[0]['list'][0], z)
-
-
- def test_moreReferences(self):
- a = []
- t = (a,)
- a.append((t,))
- s = jelly.jelly(t)
- z = jelly.unjelly(s)
- self.assertIdentical(z[0][0][0], z)
-
-
- def test_typeSecurity(self):
- """
- Test for type-level security of serialization.
- """
- taster = jelly.SecurityOptions()
- dct = jelly.jelly({})
- self.assertRaises(jelly.InsecureJelly, jelly.unjelly, dct, taster)
-
-
- def test_newStyleClasses(self):
- j = jelly.jelly(D)
- uj = jelly.unjelly(D)
- self.assertIdentical(D, uj)
-
-
- def test_lotsaTypes(self):
- """
- Test for all types currently supported in jelly
- """
- a = A()
- jelly.unjelly(jelly.jelly(a))
- jelly.unjelly(jelly.jelly(a.amethod))
- items = [afunc, [1, 2, 3], not bool(1), bool(1), 'test', 20.3,
- (1, 2, 3), None, A, unittest, {'a': 1}, A.amethod]
- for i in items:
- self.assertEqual(i, jelly.unjelly(jelly.jelly(i)))
-
-
- def test_setState(self):
- global TupleState
- class TupleState:
- def __init__(self, other):
- self.other = other
- def __getstate__(self):
- return (self.other,)
- def __setstate__(self, state):
- self.other = state[0]
- def __hash__(self):
- return hash(self.other)
- a = A()
- t1 = TupleState(a)
- t2 = TupleState(a)
- t3 = TupleState((t1, t2))
- d = {t1: t1, t2: t2, t3: t3, "t3": t3}
- t3prime = jelly.unjelly(jelly.jelly(d))["t3"]
- self.assertIdentical(t3prime.other[0].other, t3prime.other[1].other)
-
-
- def test_classSecurity(self):
- """
- Test for class-level security of serialization.
- """
- taster = jelly.SecurityOptions()
- taster.allowInstancesOf(A, B)
- a = A()
- b = B()
- c = C()
- # add a little complexity to the data
- a.b = b
- a.c = c
- # and a backreference
- a.x = b
- b.c = c
- # first, a friendly insecure serialization
- friendly = jelly.jelly(a, taster)
- x = jelly.unjelly(friendly, taster)
- self.assertIsInstance(x.c, jelly.Unpersistable)
- # now, a malicious one
- mean = jelly.jelly(a)
- self.assertRaises(jelly.InsecureJelly, jelly.unjelly, mean, taster)
- self.assertIdentical(x.x, x.b, "Identity mismatch")
- # test class serialization
- friendly = jelly.jelly(A, taster)
- x = jelly.unjelly(friendly, taster)
- self.assertIdentical(x, A, "A came back: %s" % x)
-
-
- def test_unjellyable(self):
- """
- Test that if Unjellyable is used to deserialize a jellied object,
- state comes out right.
- """
- class JellyableTestClass(jelly.Jellyable):
- pass
- jelly.setUnjellyableForClass(JellyableTestClass, jelly.Unjellyable)
- input = JellyableTestClass()
- input.attribute = 'value'
- output = jelly.unjelly(jelly.jelly(input))
- self.assertEqual(output.attribute, 'value')
- self.assertIsInstance(output, jelly.Unjellyable)
-
-
- def test_persistentStorage(self):
- perst = [{}, 1]
- def persistentStore(obj, jel, perst = perst):
- perst[1] = perst[1] + 1
- perst[0][perst[1]] = obj
- return str(perst[1])
-
- def persistentLoad(pidstr, unj, perst = perst):
- pid = int(pidstr)
- return perst[0][pid]
-
- a = SimpleJellyTest(1, 2)
- b = SimpleJellyTest(3, 4)
- c = SimpleJellyTest(5, 6)
-
- a.b = b
- a.c = c
- c.b = b
-
- jel = jelly.jelly(a, persistentStore = persistentStore)
- x = jelly.unjelly(jel, persistentLoad = persistentLoad)
-
- self.assertIdentical(x.b, x.c.b)
- self.failUnless(perst[0], "persistentStore was not called.")
- self.assertIdentical(x.b, a.b, "Persistent storage identity failure.")
-
-
- def test_newStyleClassesAttributes(self):
- n = TestNode()
- n1 = TestNode(n)
- n11 = TestNode(n1)
- n2 = TestNode(n)
- # Jelly it
- jel = jelly.jelly(n)
- m = jelly.unjelly(jel)
- # Check that it has been restored ok
- self._check_newstyle(n, m)
-
-
- def _check_newstyle(self, a, b):
- self.assertEqual(a.id, b.id)
- self.assertEqual(a.classAttr, 4)
- self.assertEqual(b.classAttr, 4)
- self.assertEqual(len(a.children), len(b.children))
- for x, y in zip(a.children, b.children):
- self._check_newstyle(x, y)
-
-
- def test_referenceable(self):
- """
- A L{pb.Referenceable} instance jellies to a structure which unjellies to
- a L{pb.RemoteReference}. The C{RemoteReference} has a I{luid} that
- matches up with the local object key in the L{pb.Broker} which sent the
- L{Referenceable}.
- """
- ref = pb.Referenceable()
- jellyBroker = pb.Broker()
- jellyBroker.makeConnection(StringTransport())
- j = jelly.jelly(ref, invoker=jellyBroker)
-
- unjellyBroker = pb.Broker()
- unjellyBroker.makeConnection(StringTransport())
-
- uj = jelly.unjelly(j, invoker=unjellyBroker)
- self.assertIn(uj.luid, jellyBroker.localObjects)
-
-
-
-class ClassA(pb.Copyable, pb.RemoteCopy):
- def __init__(self):
- self.ref = ClassB(self)
-
-
-
-class ClassB(pb.Copyable, pb.RemoteCopy):
- def __init__(self, ref):
- self.ref = ref
-
-
-
-class CircularReferenceTestCase(unittest.TestCase):
- """
- Tests for circular references handling in the jelly/unjelly process.
- """
-
- def test_simpleCircle(self):
- jelly.setUnjellyableForClass(ClassA, ClassA)
- jelly.setUnjellyableForClass(ClassB, ClassB)
- a = jelly.unjelly(jelly.jelly(ClassA()))
- self.assertIdentical(a.ref.ref, a,
- "Identity not preserved in circular reference")
-
-
- def test_circleWithInvoker(self):
- class DummyInvokerClass:
- pass
- dummyInvoker = DummyInvokerClass()
- dummyInvoker.serializingPerspective = None
- a0 = ClassA()
- jelly.setUnjellyableForClass(ClassA, ClassA)
- jelly.setUnjellyableForClass(ClassB, ClassB)
- j = jelly.jelly(a0, invoker=dummyInvoker)
- a1 = jelly.unjelly(j)
- self.failUnlessIdentical(a1.ref.ref, a1,
- "Identity not preserved in circular reference")
-
-
- def test_set(self):
- """
- Check that a C{set} can contain a circular reference and be serialized
- and unserialized without losing the reference.
- """
- s = set()
- a = SimpleJellyTest(s, None)
- s.add(a)
- res = jelly.unjelly(jelly.jelly(a))
- self.assertIsInstance(res.x, set)
- self.assertEqual(list(res.x), [res])
-
-
- def test_frozenset(self):
- """
- Check that a C{frozenset} can contain a circular reference and be
- serializeserialized without losing the reference.
- """
- a = SimpleJellyTest(None, None)
- s = frozenset([a])
- a.x = s
- res = jelly.unjelly(jelly.jelly(a))
- self.assertIsInstance(res.x, frozenset)
- self.assertEqual(list(res.x), [res])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_lockfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_lockfile.py
deleted file mode 100755
index 41cfb659..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_lockfile.py
+++ /dev/null
@@ -1,445 +0,0 @@
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.lockfile}.
-"""
-
-import os, errno
-
-from twisted.trial import unittest
-from twisted.python import lockfile
-from twisted.python.runtime import platform
-
-skipKill = None
-if platform.isWindows():
- try:
- from win32api import OpenProcess
- import pywintypes
- except ImportError:
- skipKill = ("On windows, lockfile.kill is not implemented in the "
- "absence of win32api and/or pywintypes.")
-
-class UtilTests(unittest.TestCase):
- """
- Tests for the helper functions used to implement L{FilesystemLock}.
- """
- def test_symlinkEEXIST(self):
- """
- L{lockfile.symlink} raises L{OSError} with C{errno} set to L{EEXIST}
- when an attempt is made to create a symlink which already exists.
- """
- name = self.mktemp()
- lockfile.symlink('foo', name)
- exc = self.assertRaises(OSError, lockfile.symlink, 'foo', name)
- self.assertEqual(exc.errno, errno.EEXIST)
-
-
- def test_symlinkEIOWindows(self):
- """
- L{lockfile.symlink} raises L{OSError} with C{errno} set to L{EIO} when
- the underlying L{rename} call fails with L{EIO}.
-
- Renaming a file on Windows may fail if the target of the rename is in
- the process of being deleted (directory deletion appears not to be
- atomic).
- """
- name = self.mktemp()
- def fakeRename(src, dst):
- raise IOError(errno.EIO, None)
- self.patch(lockfile, 'rename', fakeRename)
- exc = self.assertRaises(IOError, lockfile.symlink, name, "foo")
- self.assertEqual(exc.errno, errno.EIO)
- if not platform.isWindows():
- test_symlinkEIOWindows.skip = (
- "special rename EIO handling only necessary and correct on "
- "Windows.")
-
-
- def test_readlinkENOENT(self):
- """
- L{lockfile.readlink} raises L{OSError} with C{errno} set to L{ENOENT}
- when an attempt is made to read a symlink which does not exist.
- """
- name = self.mktemp()
- exc = self.assertRaises(OSError, lockfile.readlink, name)
- self.assertEqual(exc.errno, errno.ENOENT)
-
-
- def test_readlinkEACCESWindows(self):
- """
- L{lockfile.readlink} raises L{OSError} with C{errno} set to L{EACCES}
- on Windows when the underlying file open attempt fails with C{EACCES}.
-
- Opening a file on Windows may fail if the path is inside a directory
- which is in the process of being deleted (directory deletion appears
- not to be atomic).
- """
- name = self.mktemp()
- def fakeOpen(path, mode):
- raise IOError(errno.EACCES, None)
- self.patch(lockfile, '_open', fakeOpen)
- exc = self.assertRaises(IOError, lockfile.readlink, name)
- self.assertEqual(exc.errno, errno.EACCES)
- if not platform.isWindows():
- test_readlinkEACCESWindows.skip = (
- "special readlink EACCES handling only necessary and correct on "
- "Windows.")
-
-
- def test_kill(self):
- """
- L{lockfile.kill} returns without error if passed the PID of a
- process which exists and signal C{0}.
- """
- lockfile.kill(os.getpid(), 0)
- test_kill.skip = skipKill
-
-
- def test_killESRCH(self):
- """
- L{lockfile.kill} raises L{OSError} with errno of L{ESRCH} if
- passed a PID which does not correspond to any process.
- """
- # Hopefully there is no process with PID 2 ** 31 - 1
- exc = self.assertRaises(OSError, lockfile.kill, 2 ** 31 - 1, 0)
- self.assertEqual(exc.errno, errno.ESRCH)
- test_killESRCH.skip = skipKill
-
-
- def test_noKillCall(self):
- """
- Verify that when L{lockfile.kill} does end up as None (e.g. on Windows
- without pywin32), it doesn't end up being called and raising a
- L{TypeError}.
- """
- self.patch(lockfile, "kill", None)
- fl = lockfile.FilesystemLock(self.mktemp())
- fl.lock()
- self.assertFalse(fl.lock())
-
-
-
-class LockingTestCase(unittest.TestCase):
- def _symlinkErrorTest(self, errno):
- def fakeSymlink(source, dest):
- raise OSError(errno, None)
- self.patch(lockfile, 'symlink', fakeSymlink)
-
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- exc = self.assertRaises(OSError, lock.lock)
- self.assertEqual(exc.errno, errno)
-
-
- def test_symlinkError(self):
- """
- An exception raised by C{symlink} other than C{EEXIST} is passed up to
- the caller of L{FilesystemLock.lock}.
- """
- self._symlinkErrorTest(errno.ENOSYS)
-
-
- def test_symlinkErrorPOSIX(self):
- """
- An L{OSError} raised by C{symlink} on a POSIX platform with an errno of
- C{EACCES} or C{EIO} is passed to the caller of L{FilesystemLock.lock}.
-
- On POSIX, unlike on Windows, these are unexpected errors which cannot
- be handled by L{FilesystemLock}.
- """
- self._symlinkErrorTest(errno.EACCES)
- self._symlinkErrorTest(errno.EIO)
- if platform.isWindows():
- test_symlinkErrorPOSIX.skip = (
- "POSIX-specific error propagation not expected on Windows.")
-
-
- def test_cleanlyAcquire(self):
- """
- If the lock has never been held, it can be acquired and the C{clean}
- and C{locked} attributes are set to C{True}.
- """
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- self.assertTrue(lock.lock())
- self.assertTrue(lock.clean)
- self.assertTrue(lock.locked)
-
-
- def test_cleanlyRelease(self):
- """
- If a lock is released cleanly, it can be re-acquired and the C{clean}
- and C{locked} attributes are set to C{True}.
- """
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- self.assertTrue(lock.lock())
- lock.unlock()
- self.assertFalse(lock.locked)
-
- lock = lockfile.FilesystemLock(lockf)
- self.assertTrue(lock.lock())
- self.assertTrue(lock.clean)
- self.assertTrue(lock.locked)
-
-
- def test_cannotLockLocked(self):
- """
- If a lock is currently locked, it cannot be locked again.
- """
- lockf = self.mktemp()
- firstLock = lockfile.FilesystemLock(lockf)
- self.assertTrue(firstLock.lock())
-
- secondLock = lockfile.FilesystemLock(lockf)
- self.assertFalse(secondLock.lock())
- self.assertFalse(secondLock.locked)
-
-
- def test_uncleanlyAcquire(self):
- """
- If a lock was held by a process which no longer exists, it can be
- acquired, the C{clean} attribute is set to C{False}, and the
- C{locked} attribute is set to C{True}.
- """
- owner = 12345
-
- def fakeKill(pid, signal):
- if signal != 0:
- raise OSError(errno.EPERM, None)
- if pid == owner:
- raise OSError(errno.ESRCH, None)
-
- lockf = self.mktemp()
- self.patch(lockfile, 'kill', fakeKill)
- lockfile.symlink(str(owner), lockf)
-
- lock = lockfile.FilesystemLock(lockf)
- self.assertTrue(lock.lock())
- self.assertFalse(lock.clean)
- self.assertTrue(lock.locked)
-
- self.assertEqual(lockfile.readlink(lockf), str(os.getpid()))
-
-
- def test_lockReleasedBeforeCheck(self):
- """
- If the lock is initially held but then released before it can be
- examined to determine if the process which held it still exists, it is
- acquired and the C{clean} and C{locked} attributes are set to C{True}.
- """
- def fakeReadlink(name):
- # Pretend to be another process releasing the lock.
- lockfile.rmlink(lockf)
- # Fall back to the real implementation of readlink.
- readlinkPatch.restore()
- return lockfile.readlink(name)
- readlinkPatch = self.patch(lockfile, 'readlink', fakeReadlink)
-
- def fakeKill(pid, signal):
- if signal != 0:
- raise OSError(errno.EPERM, None)
- if pid == 43125:
- raise OSError(errno.ESRCH, None)
- self.patch(lockfile, 'kill', fakeKill)
-
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- lockfile.symlink(str(43125), lockf)
- self.assertTrue(lock.lock())
- self.assertTrue(lock.clean)
- self.assertTrue(lock.locked)
-
-
- def test_lockReleasedDuringAcquireSymlink(self):
- """
- If the lock is released while an attempt is made to acquire
- it, the lock attempt fails and C{FilesystemLock.lock} returns
- C{False}. This can happen on Windows when L{lockfile.symlink}
- fails with L{IOError} of C{EIO} because another process is in
- the middle of a call to L{os.rmdir} (implemented in terms of
- RemoveDirectory) which is not atomic.
- """
- def fakeSymlink(src, dst):
- # While another process id doing os.rmdir which the Windows
- # implementation of rmlink does, a rename call will fail with EIO.
- raise OSError(errno.EIO, None)
-
- self.patch(lockfile, 'symlink', fakeSymlink)
-
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- self.assertFalse(lock.lock())
- self.assertFalse(lock.locked)
- if not platform.isWindows():
- test_lockReleasedDuringAcquireSymlink.skip = (
- "special rename EIO handling only necessary and correct on "
- "Windows.")
-
-
- def test_lockReleasedDuringAcquireReadlink(self):
- """
- If the lock is initially held but is released while an attempt
- is made to acquire it, the lock attempt fails and
- L{FilesystemLock.lock} returns C{False}.
- """
- def fakeReadlink(name):
- # While another process is doing os.rmdir which the
- # Windows implementation of rmlink does, a readlink call
- # will fail with EACCES.
- raise IOError(errno.EACCES, None)
- readlinkPatch = self.patch(lockfile, 'readlink', fakeReadlink)
-
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- lockfile.symlink(str(43125), lockf)
- self.assertFalse(lock.lock())
- self.assertFalse(lock.locked)
- if not platform.isWindows():
- test_lockReleasedDuringAcquireReadlink.skip = (
- "special readlink EACCES handling only necessary and correct on "
- "Windows.")
-
-
- def _readlinkErrorTest(self, exceptionType, errno):
- def fakeReadlink(name):
- raise exceptionType(errno, None)
- self.patch(lockfile, 'readlink', fakeReadlink)
-
- lockf = self.mktemp()
-
- # Make it appear locked so it has to use readlink
- lockfile.symlink(str(43125), lockf)
-
- lock = lockfile.FilesystemLock(lockf)
- exc = self.assertRaises(exceptionType, lock.lock)
- self.assertEqual(exc.errno, errno)
- self.assertFalse(lock.locked)
-
-
- def test_readlinkError(self):
- """
- An exception raised by C{readlink} other than C{ENOENT} is passed up to
- the caller of L{FilesystemLock.lock}.
- """
- self._readlinkErrorTest(OSError, errno.ENOSYS)
- self._readlinkErrorTest(IOError, errno.ENOSYS)
-
-
- def test_readlinkErrorPOSIX(self):
- """
- Any L{IOError} raised by C{readlink} on a POSIX platform passed to the
- caller of L{FilesystemLock.lock}.
-
- On POSIX, unlike on Windows, these are unexpected errors which cannot
- be handled by L{FilesystemLock}.
- """
- self._readlinkErrorTest(IOError, errno.ENOSYS)
- self._readlinkErrorTest(IOError, errno.EACCES)
- if platform.isWindows():
- test_readlinkErrorPOSIX.skip = (
- "POSIX-specific error propagation not expected on Windows.")
-
-
- def test_lockCleanedUpConcurrently(self):
- """
- If a second process cleans up the lock after a first one checks the
- lock and finds that no process is holding it, the first process does
- not fail when it tries to clean up the lock.
- """
- def fakeRmlink(name):
- rmlinkPatch.restore()
- # Pretend to be another process cleaning up the lock.
- lockfile.rmlink(lockf)
- # Fall back to the real implementation of rmlink.
- return lockfile.rmlink(name)
- rmlinkPatch = self.patch(lockfile, 'rmlink', fakeRmlink)
-
- def fakeKill(pid, signal):
- if signal != 0:
- raise OSError(errno.EPERM, None)
- if pid == 43125:
- raise OSError(errno.ESRCH, None)
- self.patch(lockfile, 'kill', fakeKill)
-
- lockf = self.mktemp()
- lock = lockfile.FilesystemLock(lockf)
- lockfile.symlink(str(43125), lockf)
- self.assertTrue(lock.lock())
- self.assertTrue(lock.clean)
- self.assertTrue(lock.locked)
-
-
- def test_rmlinkError(self):
- """
- An exception raised by L{rmlink} other than C{ENOENT} is passed up
- to the caller of L{FilesystemLock.lock}.
- """
- def fakeRmlink(name):
- raise OSError(errno.ENOSYS, None)
- self.patch(lockfile, 'rmlink', fakeRmlink)
-
- def fakeKill(pid, signal):
- if signal != 0:
- raise OSError(errno.EPERM, None)
- if pid == 43125:
- raise OSError(errno.ESRCH, None)
- self.patch(lockfile, 'kill', fakeKill)
-
- lockf = self.mktemp()
-
- # Make it appear locked so it has to use readlink
- lockfile.symlink(str(43125), lockf)
-
- lock = lockfile.FilesystemLock(lockf)
- exc = self.assertRaises(OSError, lock.lock)
- self.assertEqual(exc.errno, errno.ENOSYS)
- self.assertFalse(lock.locked)
-
-
- def test_killError(self):
- """
- If L{kill} raises an exception other than L{OSError} with errno set to
- C{ESRCH}, the exception is passed up to the caller of
- L{FilesystemLock.lock}.
- """
- def fakeKill(pid, signal):
- raise OSError(errno.EPERM, None)
- self.patch(lockfile, 'kill', fakeKill)
-
- lockf = self.mktemp()
-
- # Make it appear locked so it has to use readlink
- lockfile.symlink(str(43125), lockf)
-
- lock = lockfile.FilesystemLock(lockf)
- exc = self.assertRaises(OSError, lock.lock)
- self.assertEqual(exc.errno, errno.EPERM)
- self.assertFalse(lock.locked)
-
-
- def test_unlockOther(self):
- """
- L{FilesystemLock.unlock} raises L{ValueError} if called for a lock
- which is held by a different process.
- """
- lockf = self.mktemp()
- lockfile.symlink(str(os.getpid() + 1), lockf)
- lock = lockfile.FilesystemLock(lockf)
- self.assertRaises(ValueError, lock.unlock)
-
-
- def test_isLocked(self):
- """
- L{isLocked} returns C{True} if the named lock is currently locked,
- C{False} otherwise.
- """
- lockf = self.mktemp()
- self.assertFalse(lockfile.isLocked(lockf))
- lock = lockfile.FilesystemLock(lockf)
- self.assertTrue(lock.lock())
- self.assertTrue(lockfile.isLocked(lockf))
- lock.unlock()
- self.assertFalse(lockfile.isLocked(lockf))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_log.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_log.py
deleted file mode 100755
index 8c9a44a3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_log.py
+++ /dev/null
@@ -1,773 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.log}.
-"""
-
-import os, sys, time, logging, warnings, calendar
-from cStringIO import StringIO
-
-from twisted.trial import unittest
-
-from twisted.python import log, failure
-
-
-class FakeWarning(Warning):
- """
- A unique L{Warning} subclass used by tests for interactions of
- L{twisted.python.log} with the L{warnings} module.
- """
-
-
-
-class LogTest(unittest.TestCase):
-
- def setUp(self):
- self.catcher = []
- self.observer = self.catcher.append
- log.addObserver(self.observer)
- self.addCleanup(log.removeObserver, self.observer)
-
-
- def testObservation(self):
- catcher = self.catcher
- log.msg("test", testShouldCatch=True)
- i = catcher.pop()
- self.assertEqual(i["message"][0], "test")
- self.assertEqual(i["testShouldCatch"], True)
- self.assertIn("time", i)
- self.assertEqual(len(catcher), 0)
-
-
- def testContext(self):
- catcher = self.catcher
- log.callWithContext({"subsystem": "not the default",
- "subsubsystem": "a",
- "other": "c"},
- log.callWithContext,
- {"subsubsystem": "b"}, log.msg, "foo", other="d")
- i = catcher.pop()
- self.assertEqual(i['subsubsystem'], 'b')
- self.assertEqual(i['subsystem'], 'not the default')
- self.assertEqual(i['other'], 'd')
- self.assertEqual(i['message'][0], 'foo')
-
- def testErrors(self):
- for e, ig in [("hello world","hello world"),
- (KeyError(), KeyError),
- (failure.Failure(RuntimeError()), RuntimeError)]:
- log.err(e)
- i = self.catcher.pop()
- self.assertEqual(i['isError'], 1)
- self.flushLoggedErrors(ig)
-
- def testErrorsWithWhy(self):
- for e, ig in [("hello world","hello world"),
- (KeyError(), KeyError),
- (failure.Failure(RuntimeError()), RuntimeError)]:
- log.err(e, 'foobar')
- i = self.catcher.pop()
- self.assertEqual(i['isError'], 1)
- self.assertEqual(i['why'], 'foobar')
- self.flushLoggedErrors(ig)
-
-
- def test_erroneousErrors(self):
- """
- Exceptions raised by log observers are logged but the observer which
- raised the exception remains registered with the publisher. These
- exceptions do not prevent the event from being sent to other observers
- registered with the publisher.
- """
- L1 = []
- L2 = []
- def broken(events):
- 1 // 0
-
- for observer in [L1.append, broken, L2.append]:
- log.addObserver(observer)
- self.addCleanup(log.removeObserver, observer)
-
- for i in xrange(3):
- # Reset the lists for simpler comparison.
- L1[:] = []
- L2[:] = []
-
- # Send out the event which will break one of the observers.
- log.msg("Howdy, y'all.")
-
- # The broken observer should have caused this to be logged.
- excs = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(excs), 1)
-
- # Both other observers should have seen the message.
- self.assertEqual(len(L1), 2)
- self.assertEqual(len(L2), 2)
-
- # The order is slightly wrong here. The first event should be
- # delivered to all observers; then, errors should be delivered.
- self.assertEqual(L1[1]['message'], ("Howdy, y'all.",))
- self.assertEqual(L2[0]['message'], ("Howdy, y'all.",))
-
-
- def test_doubleErrorDoesNotRemoveObserver(self):
- """
- If logging causes an error, make sure that if logging the fact that
- logging failed also causes an error, the log observer is not removed.
- """
- events = []
- errors = []
- publisher = log.LogPublisher()
-
- class FailingObserver(object):
- calls = 0
- def log(self, msg, **kwargs):
- # First call raises RuntimeError:
- self.calls += 1
- if self.calls < 2:
- raise RuntimeError("Failure #%s" % (self.calls,))
- else:
- events.append(msg)
-
- observer = FailingObserver()
- publisher.addObserver(observer.log)
- self.assertEqual(publisher.observers, [observer.log])
-
- try:
- # When observer throws, the publisher attempts to log the fact by
- # calling self._err()... which also fails with recursion error:
- oldError = publisher._err
-
- def failingErr(failure, why, **kwargs):
- errors.append(failure.value)
- raise RuntimeError("Fake recursion error")
-
- publisher._err = failingErr
- publisher.msg("error in first observer")
- finally:
- publisher._err = oldError
- # Observer should still exist; we do this in finally since before
- # bug was fixed the test would fail due to uncaught exception, so
- # we want failing assert too in that case:
- self.assertEqual(publisher.observers, [observer.log])
-
- # The next message should succeed:
- publisher.msg("but this should succeed")
-
- self.assertEqual(observer.calls, 2)
- self.assertEqual(len(events), 1)
- self.assertEqual(events[0]['message'], ("but this should succeed",))
- self.assertEqual(len(errors), 1)
- self.assertIsInstance(errors[0], RuntimeError)
-
-
- def test_showwarning(self):
- """
- L{twisted.python.log.showwarning} emits the warning as a message
- to the Twisted logging system.
- """
- publisher = log.LogPublisher()
- publisher.addObserver(self.observer)
-
- publisher.showwarning(
- FakeWarning("unique warning message"), FakeWarning,
- "warning-filename.py", 27)
- event = self.catcher.pop()
- self.assertEqual(
- event['format'] % event,
- 'warning-filename.py:27: twisted.test.test_log.FakeWarning: '
- 'unique warning message')
- self.assertEqual(self.catcher, [])
-
- # Python 2.6 requires that any function used to override the
- # warnings.showwarning API accept a "line" parameter or a
- # deprecation warning is emitted.
- publisher.showwarning(
- FakeWarning("unique warning message"), FakeWarning,
- "warning-filename.py", 27, line=object())
- event = self.catcher.pop()
- self.assertEqual(
- event['format'] % event,
- 'warning-filename.py:27: twisted.test.test_log.FakeWarning: '
- 'unique warning message')
- self.assertEqual(self.catcher, [])
-
-
- def test_warningToFile(self):
- """
- L{twisted.python.log.showwarning} passes warnings with an explicit file
- target on to the underlying Python warning system.
- """
- message = "another unique message"
- category = FakeWarning
- filename = "warning-filename.py"
- lineno = 31
-
- output = StringIO()
- log.showwarning(message, category, filename, lineno, file=output)
-
- self.assertEqual(
- output.getvalue(),
- warnings.formatwarning(message, category, filename, lineno))
-
- # In Python 2.6, warnings.showwarning accepts a "line" argument which
- # gives the source line the warning message is to include.
- if sys.version_info >= (2, 6):
- line = "hello world"
- output = StringIO()
- log.showwarning(message, category, filename, lineno, file=output,
- line=line)
-
- self.assertEqual(
- output.getvalue(),
- warnings.formatwarning(message, category, filename, lineno,
- line))
-
-
- def test_publisherReportsBrokenObserversPrivately(self):
- """
- Log publisher does not use the global L{log.err} when reporting broken
- observers.
- """
- errors = []
- def logError(eventDict):
- if eventDict.get("isError"):
- errors.append(eventDict["failure"].value)
-
- def fail(eventDict):
- raise RuntimeError("test_publisherLocalyReportsBrokenObservers")
-
- publisher = log.LogPublisher()
- publisher.addObserver(logError)
- publisher.addObserver(fail)
-
- publisher.msg("Hello!")
- self.assertEqual(publisher.observers, [logError, fail])
- self.assertEqual(len(errors), 1)
- self.assertIsInstance(errors[0], RuntimeError)
-
-
-
-class FakeFile(list):
- def write(self, bytes):
- self.append(bytes)
-
- def flush(self):
- pass
-
-class EvilStr:
- def __str__(self):
- 1//0
-
-class EvilRepr:
- def __str__(self):
- return "Happy Evil Repr"
- def __repr__(self):
- 1//0
-
-class EvilReprStr(EvilStr, EvilRepr):
- pass
-
-class LogPublisherTestCaseMixin:
- def setUp(self):
- """
- Add a log observer which records log events in C{self.out}. Also,
- make sure the default string encoding is ASCII so that
- L{testSingleUnicode} can test the behavior of logging unencodable
- unicode messages.
- """
- self.out = FakeFile()
- self.lp = log.LogPublisher()
- self.flo = log.FileLogObserver(self.out)
- self.lp.addObserver(self.flo.emit)
-
- try:
- str(u'\N{VULGAR FRACTION ONE HALF}')
- except UnicodeEncodeError:
- # This is the behavior we want - don't change anything.
- self._origEncoding = None
- else:
- reload(sys)
- self._origEncoding = sys.getdefaultencoding()
- sys.setdefaultencoding('ascii')
-
-
- def tearDown(self):
- """
- Verify that everything written to the fake file C{self.out} was a
- C{str}. Also, restore the default string encoding to its previous
- setting, if it was modified by L{setUp}.
- """
- for chunk in self.out:
- self.failUnless(isinstance(chunk, str), "%r was not a string" % (chunk,))
-
- if self._origEncoding is not None:
- sys.setdefaultencoding(self._origEncoding)
- del sys.setdefaultencoding
-
-
-
-class LogPublisherTestCase(LogPublisherTestCaseMixin, unittest.TestCase):
- def testSingleString(self):
- self.lp.msg("Hello, world.")
- self.assertEqual(len(self.out), 1)
-
-
- def testMultipleString(self):
- # Test some stupid behavior that will be deprecated real soon.
- # If you are reading this and trying to learn how the logging
- # system works, *do not use this feature*.
- self.lp.msg("Hello, ", "world.")
- self.assertEqual(len(self.out), 1)
-
-
- def testSingleUnicode(self):
- self.lp.msg(u"Hello, \N{VULGAR FRACTION ONE HALF} world.")
- self.assertEqual(len(self.out), 1)
- self.assertIn('with str error', self.out[0])
- self.assertIn('UnicodeEncodeError', self.out[0])
-
-
-
-class FileObserverTestCase(LogPublisherTestCaseMixin, unittest.TestCase):
- def test_getTimezoneOffset(self):
- """
- Attempt to verify that L{FileLogObserver.getTimezoneOffset} returns
- correct values for the current C{TZ} environment setting. Do this
- by setting C{TZ} to various well-known values and asserting that the
- reported offset is correct.
- """
- localDaylightTuple = (2006, 6, 30, 0, 0, 0, 4, 181, 1)
- utcDaylightTimestamp = time.mktime(localDaylightTuple)
- localStandardTuple = (2007, 1, 31, 0, 0, 0, 2, 31, 0)
- utcStandardTimestamp = time.mktime(localStandardTuple)
-
- originalTimezone = os.environ.get('TZ', None)
- try:
- # Test something west of UTC
- os.environ['TZ'] = 'America/New_York'
- time.tzset()
- self.assertEqual(
- self.flo.getTimezoneOffset(utcDaylightTimestamp),
- 14400)
- self.assertEqual(
- self.flo.getTimezoneOffset(utcStandardTimestamp),
- 18000)
-
- # Test something east of UTC
- os.environ['TZ'] = 'Europe/Berlin'
- time.tzset()
- self.assertEqual(
- self.flo.getTimezoneOffset(utcDaylightTimestamp),
- -7200)
- self.assertEqual(
- self.flo.getTimezoneOffset(utcStandardTimestamp),
- -3600)
-
- # Test a timezone that doesn't have DST
- os.environ['TZ'] = 'Africa/Johannesburg'
- time.tzset()
- self.assertEqual(
- self.flo.getTimezoneOffset(utcDaylightTimestamp),
- -7200)
- self.assertEqual(
- self.flo.getTimezoneOffset(utcStandardTimestamp),
- -7200)
- finally:
- if originalTimezone is None:
- del os.environ['TZ']
- else:
- os.environ['TZ'] = originalTimezone
- time.tzset()
- if getattr(time, 'tzset', None) is None:
- test_getTimezoneOffset.skip = (
- "Platform cannot change timezone, cannot verify correct offsets "
- "in well-known timezones.")
-
-
- def test_timeFormatting(self):
- """
- Test the method of L{FileLogObserver} which turns a timestamp into a
- human-readable string.
- """
- when = calendar.timegm((2001, 2, 3, 4, 5, 6, 7, 8, 0))
-
- # Pretend to be in US/Eastern for a moment
- self.flo.getTimezoneOffset = lambda when: 18000
- self.assertEqual(self.flo.formatTime(when), '2001-02-02 23:05:06-0500')
-
- # Okay now we're in Eastern Europe somewhere
- self.flo.getTimezoneOffset = lambda when: -3600
- self.assertEqual(self.flo.formatTime(when), '2001-02-03 05:05:06+0100')
-
- # And off in the Pacific or someplace like that
- self.flo.getTimezoneOffset = lambda when: -39600
- self.assertEqual(self.flo.formatTime(when), '2001-02-03 15:05:06+1100')
-
- # One of those weird places with a half-hour offset timezone
- self.flo.getTimezoneOffset = lambda when: 5400
- self.assertEqual(self.flo.formatTime(when), '2001-02-03 02:35:06-0130')
-
- # Half-hour offset in the other direction
- self.flo.getTimezoneOffset = lambda when: -5400
- self.assertEqual(self.flo.formatTime(when), '2001-02-03 05:35:06+0130')
-
- # Test an offset which is between 0 and 60 minutes to make sure the
- # sign comes out properly in that case.
- self.flo.getTimezoneOffset = lambda when: 1800
- self.assertEqual(self.flo.formatTime(when), '2001-02-03 03:35:06-0030')
-
- # Test an offset between 0 and 60 minutes in the other direction.
- self.flo.getTimezoneOffset = lambda when: -1800
- self.assertEqual(self.flo.formatTime(when), '2001-02-03 04:35:06+0030')
-
- # If a strftime-format string is present on the logger, it should
- # use that instead. Note we don't assert anything about day, hour
- # or minute because we cannot easily control what time.strftime()
- # thinks the local timezone is.
- self.flo.timeFormat = '%Y %m'
- self.assertEqual(self.flo.formatTime(when), '2001 02')
-
-
- def test_loggingAnObjectWithBroken__str__(self):
- #HELLO, MCFLY
- self.lp.msg(EvilStr())
- self.assertEqual(len(self.out), 1)
- # Logging system shouldn't need to crap itself for this trivial case
- self.assertNotIn('UNFORMATTABLE', self.out[0])
-
-
- def test_formattingAnObjectWithBroken__str__(self):
- self.lp.msg(format='%(blat)s', blat=EvilStr())
- self.assertEqual(len(self.out), 1)
- self.assertIn('Invalid format string or unformattable object', self.out[0])
-
-
- def test_brokenSystem__str__(self):
- self.lp.msg('huh', system=EvilStr())
- self.assertEqual(len(self.out), 1)
- self.assertIn('Invalid format string or unformattable object', self.out[0])
-
-
- def test_formattingAnObjectWithBroken__repr__Indirect(self):
- self.lp.msg(format='%(blat)s', blat=[EvilRepr()])
- self.assertEqual(len(self.out), 1)
- self.assertIn('UNFORMATTABLE OBJECT', self.out[0])
-
-
- def test_systemWithBroker__repr__Indirect(self):
- self.lp.msg('huh', system=[EvilRepr()])
- self.assertEqual(len(self.out), 1)
- self.assertIn('UNFORMATTABLE OBJECT', self.out[0])
-
-
- def test_simpleBrokenFormat(self):
- self.lp.msg(format='hooj %s %s', blat=1)
- self.assertEqual(len(self.out), 1)
- self.assertIn('Invalid format string or unformattable object', self.out[0])
-
-
- def test_ridiculousFormat(self):
- self.lp.msg(format=42, blat=1)
- self.assertEqual(len(self.out), 1)
- self.assertIn('Invalid format string or unformattable object', self.out[0])
-
-
- def test_evilFormat__repr__And__str__(self):
- self.lp.msg(format=EvilReprStr(), blat=1)
- self.assertEqual(len(self.out), 1)
- self.assertIn('PATHOLOGICAL', self.out[0])
-
-
- def test_strangeEventDict(self):
- """
- This kind of eventDict used to fail silently, so test it does.
- """
- self.lp.msg(message='', isError=False)
- self.assertEqual(len(self.out), 0)
-
-
- def test_startLogging(self):
- """
- startLogging() installs FileLogObserver and overrides sys.stdout and
- sys.stderr.
- """
- # When done with test, reset stdout and stderr to current values:
- origStdout, origStderr = sys.stdout, sys.stderr
- self.addCleanup(setattr, sys, 'stdout', sys.stdout)
- self.addCleanup(setattr, sys, 'stderr', sys.stderr)
- fakeFile = StringIO()
- observer = log.startLogging(fakeFile)
- self.addCleanup(observer.stop)
- log.msg("Hello!")
- self.assertIn("Hello!", fakeFile.getvalue())
- self.assertIsInstance(sys.stdout, log.StdioOnnaStick)
- self.assertEqual(sys.stdout.isError, False)
- self.assertEqual(sys.stdout.encoding,
- origStdout.encoding or sys.getdefaultencoding())
- self.assertIsInstance(sys.stderr, log.StdioOnnaStick)
- self.assertEqual(sys.stderr.isError, True)
- self.assertEqual(sys.stderr.encoding,
- origStderr.encoding or sys.getdefaultencoding())
-
-
- def test_startLoggingTwice(self):
- """
- There are some obscure error conditions that can occur when logging is
- started twice. See http://twistedmatrix.com/trac/ticket/3289 for more
- information.
- """
- # The bug is particular to the way that the t.p.log 'global' function
- # handle stdout. If we use our own stream, the error doesn't occur. If
- # we use our own LogPublisher, the error doesn't occur.
- sys.stdout = StringIO()
- self.addCleanup(setattr, sys, 'stdout', sys.stdout)
- self.addCleanup(setattr, sys, 'stderr', sys.stderr)
-
- def showError(eventDict):
- if eventDict['isError']:
- sys.__stdout__.write(eventDict['failure'].getTraceback())
-
- log.addObserver(showError)
- self.addCleanup(log.removeObserver, showError)
- observer = log.startLogging(sys.stdout)
- self.addCleanup(observer.stop)
- # At this point, we expect that sys.stdout is a StdioOnnaStick object.
- self.assertIsInstance(sys.stdout, log.StdioOnnaStick)
- fakeStdout = sys.stdout
- observer = log.startLogging(sys.stdout)
- self.assertIdentical(sys.stdout, fakeStdout)
-
-
-class PythonLoggingObserverTestCase(unittest.TestCase):
- """
- Test the bridge with python logging module.
- """
- def setUp(self):
- self.out = StringIO()
-
- rootLogger = logging.getLogger("")
- self.originalLevel = rootLogger.getEffectiveLevel()
- rootLogger.setLevel(logging.DEBUG)
- self.hdlr = logging.StreamHandler(self.out)
- fmt = logging.Formatter(logging.BASIC_FORMAT)
- self.hdlr.setFormatter(fmt)
- rootLogger.addHandler(self.hdlr)
-
- self.lp = log.LogPublisher()
- self.obs = log.PythonLoggingObserver()
- self.lp.addObserver(self.obs.emit)
-
- def tearDown(self):
- rootLogger = logging.getLogger("")
- rootLogger.removeHandler(self.hdlr)
- rootLogger.setLevel(self.originalLevel)
- logging.shutdown()
-
- def test_singleString(self):
- """
- Test simple output, and default log level.
- """
- self.lp.msg("Hello, world.")
- self.assertIn("Hello, world.", self.out.getvalue())
- self.assertIn("INFO", self.out.getvalue())
-
- def test_errorString(self):
- """
- Test error output.
- """
- self.lp.msg(failure=failure.Failure(ValueError("That is bad.")), isError=True)
- self.assertIn("ERROR", self.out.getvalue())
-
- def test_formatString(self):
- """
- Test logging with a format.
- """
- self.lp.msg(format="%(bar)s oo %(foo)s", bar="Hello", foo="world")
- self.assertIn("Hello oo world", self.out.getvalue())
-
- def test_customLevel(self):
- """
- Test the logLevel keyword for customizing level used.
- """
- self.lp.msg("Spam egg.", logLevel=logging.DEBUG)
- self.assertIn("Spam egg.", self.out.getvalue())
- self.assertIn("DEBUG", self.out.getvalue())
- self.out.reset()
- self.lp.msg("Foo bar.", logLevel=logging.WARNING)
- self.assertIn("Foo bar.", self.out.getvalue())
- self.assertIn("WARNING", self.out.getvalue())
-
- def test_strangeEventDict(self):
- """
- Verify that an event dictionary which is not an error and has an empty
- message isn't recorded.
- """
- self.lp.msg(message='', isError=False)
- self.assertEqual(self.out.getvalue(), '')
-
-
-class PythonLoggingIntegrationTestCase(unittest.TestCase):
- """
- Test integration of python logging bridge.
- """
- def test_startStopObserver(self):
- """
- Test that start and stop methods of the observer actually register
- and unregister to the log system.
- """
- oldAddObserver = log.addObserver
- oldRemoveObserver = log.removeObserver
- l = []
- try:
- log.addObserver = l.append
- log.removeObserver = l.remove
- obs = log.PythonLoggingObserver()
- obs.start()
- self.assertEqual(l[0], obs.emit)
- obs.stop()
- self.assertEqual(len(l), 0)
- finally:
- log.addObserver = oldAddObserver
- log.removeObserver = oldRemoveObserver
-
- def test_inheritance(self):
- """
- Test that we can inherit L{log.PythonLoggingObserver} and use super:
- that's basically a validation that L{log.PythonLoggingObserver} is
- new-style class.
- """
- class MyObserver(log.PythonLoggingObserver):
- def emit(self, eventDict):
- super(MyObserver, self).emit(eventDict)
- obs = MyObserver()
- l = []
- oldEmit = log.PythonLoggingObserver.emit
- try:
- log.PythonLoggingObserver.emit = l.append
- obs.emit('foo')
- self.assertEqual(len(l), 1)
- finally:
- log.PythonLoggingObserver.emit = oldEmit
-
-
-class DefaultObserverTestCase(unittest.TestCase):
- """
- Test the default observer.
- """
-
- def test_failureLogger(self):
- """
- The reason argument passed to log.err() appears in the report
- generated by DefaultObserver.
- """
- from StringIO import StringIO
-
- obs = log.DefaultObserver()
- obs.stderr = StringIO()
- obs.start()
-
- reason = "The reason."
- log.err(Exception(), reason)
- errors = self.flushLoggedErrors()
-
- self.assertSubstring(reason, obs.stderr.getvalue())
- self.assertEqual(len(errors), 1)
-
- obs.stop()
-
-
-
-class StdioOnnaStickTestCase(unittest.TestCase):
- """
- StdioOnnaStick should act like the normal sys.stdout object.
- """
-
- def setUp(self):
- self.resultLogs = []
- log.addObserver(self.resultLogs.append)
-
-
- def tearDown(self):
- log.removeObserver(self.resultLogs.append)
-
-
- def getLogMessages(self):
- return ["".join(d['message']) for d in self.resultLogs]
-
-
- def test_write(self):
- """
- Writing to a StdioOnnaStick instance results in Twisted log messages.
-
- Log messages are generated every time a '\n' is encountered.
- """
- stdio = log.StdioOnnaStick()
- stdio.write("Hello there\nThis is a test")
- self.assertEqual(self.getLogMessages(), ["Hello there"])
- stdio.write("!\n")
- self.assertEqual(self.getLogMessages(), ["Hello there", "This is a test!"])
-
-
- def test_metadata(self):
- """
- The log messages written by StdioOnnaStick have printed=1 keyword, and
- by default are not errors.
- """
- stdio = log.StdioOnnaStick()
- stdio.write("hello\n")
- self.assertEqual(self.resultLogs[0]['isError'], False)
- self.assertEqual(self.resultLogs[0]['printed'], True)
-
-
- def test_writeLines(self):
- """
- Writing lines to a StdioOnnaStick results in Twisted log messages.
- """
- stdio = log.StdioOnnaStick()
- stdio.writelines(["log 1", "log 2"])
- self.assertEqual(self.getLogMessages(), ["log 1", "log 2"])
-
-
- def test_print(self):
- """
- When StdioOnnaStick is set as sys.stdout, prints become log messages.
- """
- oldStdout = sys.stdout
- sys.stdout = log.StdioOnnaStick()
- self.addCleanup(setattr, sys, "stdout", oldStdout)
- print "This",
- print "is a test"
- self.assertEqual(self.getLogMessages(), ["This is a test"])
-
-
- def test_error(self):
- """
- StdioOnnaStick created with isError=True log messages as errors.
- """
- stdio = log.StdioOnnaStick(isError=True)
- stdio.write("log 1\n")
- self.assertEqual(self.resultLogs[0]['isError'], True)
-
-
- def test_unicode(self):
- """
- StdioOnnaStick converts unicode prints to strings, in order to be
- compatible with the normal stdout/stderr objects.
- """
- unicodeString = u"Hello, \N{VULGAR FRACTION ONE HALF} world."
- stdio = log.StdioOnnaStick(encoding="utf-8")
- self.assertEqual(stdio.encoding, "utf-8")
- stdio.write(unicodeString + u"\n")
- stdio.writelines([u"Also, " + unicodeString])
- oldStdout = sys.stdout
- sys.stdout = stdio
- self.addCleanup(setattr, sys, "stdout", oldStdout)
- # This should go to the log, utf-8 encoded too:
- print unicodeString
- self.assertEqual(self.getLogMessages(),
- [unicodeString.encode("utf-8"),
- (u"Also, " + unicodeString).encode("utf-8"),
- unicodeString.encode("utf-8")])
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_logfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_logfile.py
deleted file mode 100755
index e7db238c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_logfile.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import os, time, stat, errno
-
-from twisted.trial import unittest
-from twisted.python import logfile, runtime
-
-
-class LogFileTestCase(unittest.TestCase):
- """
- Test the rotating log file.
- """
-
- def setUp(self):
- self.dir = self.mktemp()
- os.makedirs(self.dir)
- self.name = "test.log"
- self.path = os.path.join(self.dir, self.name)
-
-
- def tearDown(self):
- """
- Restore back write rights on created paths: if tests modified the
- rights, that will allow the paths to be removed easily afterwards.
- """
- os.chmod(self.dir, 0777)
- if os.path.exists(self.path):
- os.chmod(self.path, 0777)
-
-
- def testWriting(self):
- log = logfile.LogFile(self.name, self.dir)
- log.write("123")
- log.write("456")
- log.flush()
- log.write("7890")
- log.close()
-
- f = open(self.path, "r")
- self.assertEqual(f.read(), "1234567890")
- f.close()
-
- def testRotation(self):
- # this logfile should rotate every 10 bytes
- log = logfile.LogFile(self.name, self.dir, rotateLength=10)
-
- # test automatic rotation
- log.write("123")
- log.write("4567890")
- log.write("1" * 11)
- self.assert_(os.path.exists("%s.1" % self.path))
- self.assert_(not os.path.exists("%s.2" % self.path))
- log.write('')
- self.assert_(os.path.exists("%s.1" % self.path))
- self.assert_(os.path.exists("%s.2" % self.path))
- self.assert_(not os.path.exists("%s.3" % self.path))
- log.write("3")
- self.assert_(not os.path.exists("%s.3" % self.path))
-
- # test manual rotation
- log.rotate()
- self.assert_(os.path.exists("%s.3" % self.path))
- self.assert_(not os.path.exists("%s.4" % self.path))
- log.close()
-
- self.assertEqual(log.listLogs(), [1, 2, 3])
-
- def testAppend(self):
- log = logfile.LogFile(self.name, self.dir)
- log.write("0123456789")
- log.close()
-
- log = logfile.LogFile(self.name, self.dir)
- self.assertEqual(log.size, 10)
- self.assertEqual(log._file.tell(), log.size)
- log.write("abc")
- self.assertEqual(log.size, 13)
- self.assertEqual(log._file.tell(), log.size)
- f = log._file
- f.seek(0, 0)
- self.assertEqual(f.read(), "0123456789abc")
- log.close()
-
- def testLogReader(self):
- log = logfile.LogFile(self.name, self.dir)
- log.write("abc\n")
- log.write("def\n")
- log.rotate()
- log.write("ghi\n")
- log.flush()
-
- # check reading logs
- self.assertEqual(log.listLogs(), [1])
- reader = log.getCurrentLog()
- reader._file.seek(0)
- self.assertEqual(reader.readLines(), ["ghi\n"])
- self.assertEqual(reader.readLines(), [])
- reader.close()
- reader = log.getLog(1)
- self.assertEqual(reader.readLines(), ["abc\n", "def\n"])
- self.assertEqual(reader.readLines(), [])
- reader.close()
-
- # check getting illegal log readers
- self.assertRaises(ValueError, log.getLog, 2)
- self.assertRaises(TypeError, log.getLog, "1")
-
- # check that log numbers are higher for older logs
- log.rotate()
- self.assertEqual(log.listLogs(), [1, 2])
- reader = log.getLog(1)
- reader._file.seek(0)
- self.assertEqual(reader.readLines(), ["ghi\n"])
- self.assertEqual(reader.readLines(), [])
- reader.close()
- reader = log.getLog(2)
- self.assertEqual(reader.readLines(), ["abc\n", "def\n"])
- self.assertEqual(reader.readLines(), [])
- reader.close()
-
- def testModePreservation(self):
- """
- Check rotated files have same permissions as original.
- """
- f = open(self.path, "w").close()
- os.chmod(self.path, 0707)
- mode = os.stat(self.path)[stat.ST_MODE]
- log = logfile.LogFile(self.name, self.dir)
- log.write("abc")
- log.rotate()
- self.assertEqual(mode, os.stat(self.path)[stat.ST_MODE])
-
-
- def test_noPermission(self):
- """
- Check it keeps working when permission on dir changes.
- """
- log = logfile.LogFile(self.name, self.dir)
- log.write("abc")
-
- # change permissions so rotation would fail
- os.chmod(self.dir, 0555)
-
- # if this succeeds, chmod doesn't restrict us, so we can't
- # do the test
- try:
- f = open(os.path.join(self.dir,"xxx"), "w")
- except (OSError, IOError):
- pass
- else:
- f.close()
- return
-
- log.rotate() # this should not fail
-
- log.write("def")
- log.flush()
-
- f = log._file
- self.assertEqual(f.tell(), 6)
- f.seek(0, 0)
- self.assertEqual(f.read(), "abcdef")
- log.close()
-
-
- def test_maxNumberOfLog(self):
- """
- Test it respect the limit on the number of files when maxRotatedFiles
- is not None.
- """
- log = logfile.LogFile(self.name, self.dir, rotateLength=10,
- maxRotatedFiles=3)
- log.write("1" * 11)
- log.write("2" * 11)
- self.failUnless(os.path.exists("%s.1" % self.path))
-
- log.write("3" * 11)
- self.failUnless(os.path.exists("%s.2" % self.path))
-
- log.write("4" * 11)
- self.failUnless(os.path.exists("%s.3" % self.path))
- self.assertEqual(file("%s.3" % self.path).read(), "1" * 11)
-
- log.write("5" * 11)
- self.assertEqual(file("%s.3" % self.path).read(), "2" * 11)
- self.failUnless(not os.path.exists("%s.4" % self.path))
-
- def test_fromFullPath(self):
- """
- Test the fromFullPath method.
- """
- log1 = logfile.LogFile(self.name, self.dir, 10, defaultMode=0777)
- log2 = logfile.LogFile.fromFullPath(self.path, 10, defaultMode=0777)
- self.assertEqual(log1.name, log2.name)
- self.assertEqual(os.path.abspath(log1.path), log2.path)
- self.assertEqual(log1.rotateLength, log2.rotateLength)
- self.assertEqual(log1.defaultMode, log2.defaultMode)
-
- def test_defaultPermissions(self):
- """
- Test the default permission of the log file: if the file exist, it
- should keep the permission.
- """
- f = file(self.path, "w")
- os.chmod(self.path, 0707)
- currentMode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
- f.close()
- log1 = logfile.LogFile(self.name, self.dir)
- self.assertEqual(stat.S_IMODE(os.stat(self.path)[stat.ST_MODE]),
- currentMode)
-
-
- def test_specifiedPermissions(self):
- """
- Test specifying the permissions used on the log file.
- """
- log1 = logfile.LogFile(self.name, self.dir, defaultMode=0066)
- mode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
- if runtime.platform.isWindows():
- # The only thing we can get here is global read-only
- self.assertEqual(mode, 0444)
- else:
- self.assertEqual(mode, 0066)
-
-
- def test_reopen(self):
- """
- L{logfile.LogFile.reopen} allows to rename the currently used file and
- make L{logfile.LogFile} create a new file.
- """
- log1 = logfile.LogFile(self.name, self.dir)
- log1.write("hello1")
- savePath = os.path.join(self.dir, "save.log")
- os.rename(self.path, savePath)
- log1.reopen()
- log1.write("hello2")
- log1.close()
-
- f = open(self.path, "r")
- self.assertEqual(f.read(), "hello2")
- f.close()
- f = open(savePath, "r")
- self.assertEqual(f.read(), "hello1")
- f.close()
-
- if runtime.platform.isWindows():
- test_reopen.skip = "Can't test reopen on Windows"
-
-
- def test_nonExistentDir(self):
- """
- Specifying an invalid directory to L{LogFile} raises C{IOError}.
- """
- e = self.assertRaises(
- IOError, logfile.LogFile, self.name, 'this_dir_does_not_exist')
- self.assertEqual(e.errno, errno.ENOENT)
-
-
-
-class RiggedDailyLogFile(logfile.DailyLogFile):
- _clock = 0.0
-
- def _openFile(self):
- logfile.DailyLogFile._openFile(self)
- # rig the date to match _clock, not mtime
- self.lastDate = self.toDate()
-
- def toDate(self, *args):
- if args:
- return time.gmtime(*args)[:3]
- return time.gmtime(self._clock)[:3]
-
-class DailyLogFileTestCase(unittest.TestCase):
- """
- Test rotating log file.
- """
-
- def setUp(self):
- self.dir = self.mktemp()
- os.makedirs(self.dir)
- self.name = "testdaily.log"
- self.path = os.path.join(self.dir, self.name)
-
-
- def testWriting(self):
- log = RiggedDailyLogFile(self.name, self.dir)
- log.write("123")
- log.write("456")
- log.flush()
- log.write("7890")
- log.close()
-
- f = open(self.path, "r")
- self.assertEqual(f.read(), "1234567890")
- f.close()
-
- def testRotation(self):
- # this logfile should rotate every 10 bytes
- log = RiggedDailyLogFile(self.name, self.dir)
- days = [(self.path + '.' + log.suffix(day * 86400)) for day in range(3)]
-
- # test automatic rotation
- log._clock = 0.0 # 1970/01/01 00:00.00
- log.write("123")
- log._clock = 43200 # 1970/01/01 12:00.00
- log.write("4567890")
- log._clock = 86400 # 1970/01/02 00:00.00
- log.write("1" * 11)
- self.assert_(os.path.exists(days[0]))
- self.assert_(not os.path.exists(days[1]))
- log._clock = 172800 # 1970/01/03 00:00.00
- log.write('')
- self.assert_(os.path.exists(days[0]))
- self.assert_(os.path.exists(days[1]))
- self.assert_(not os.path.exists(days[2]))
- log._clock = 259199 # 1970/01/03 23:59.59
- log.write("3")
- self.assert_(not os.path.exists(days[2]))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_loopback.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_loopback.py
deleted file mode 100755
index f09908fb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_loopback.py
+++ /dev/null
@@ -1,419 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test case for L{twisted.protocols.loopback}.
-"""
-
-from zope.interface import implements
-
-from twisted.trial import unittest
-from twisted.trial.util import suppress as SUPPRESS
-from twisted.protocols import basic, loopback
-from twisted.internet import defer
-from twisted.internet.protocol import Protocol
-from twisted.internet.defer import Deferred
-from twisted.internet.interfaces import IAddress, IPushProducer, IPullProducer
-from twisted.internet import reactor, interfaces
-
-
-class SimpleProtocol(basic.LineReceiver):
- def __init__(self):
- self.conn = defer.Deferred()
- self.lines = []
- self.connLost = []
-
- def connectionMade(self):
- self.conn.callback(None)
-
- def lineReceived(self, line):
- self.lines.append(line)
-
- def connectionLost(self, reason):
- self.connLost.append(reason)
-
-
-class DoomProtocol(SimpleProtocol):
- i = 0
- def lineReceived(self, line):
- self.i += 1
- if self.i < 4:
- # by this point we should have connection closed,
- # but just in case we didn't we won't ever send 'Hello 4'
- self.sendLine("Hello %d" % self.i)
- SimpleProtocol.lineReceived(self, line)
- if self.lines[-1] == "Hello 3":
- self.transport.loseConnection()
-
-
-class LoopbackTestCaseMixin:
- def testRegularFunction(self):
- s = SimpleProtocol()
- c = SimpleProtocol()
-
- def sendALine(result):
- s.sendLine("THIS IS LINE ONE!")
- s.transport.loseConnection()
- s.conn.addCallback(sendALine)
-
- def check(ignored):
- self.assertEqual(c.lines, ["THIS IS LINE ONE!"])
- self.assertEqual(len(s.connLost), 1)
- self.assertEqual(len(c.connLost), 1)
- d = defer.maybeDeferred(self.loopbackFunc, s, c)
- d.addCallback(check)
- return d
-
- def testSneakyHiddenDoom(self):
- s = DoomProtocol()
- c = DoomProtocol()
-
- def sendALine(result):
- s.sendLine("DOOM LINE")
- s.conn.addCallback(sendALine)
-
- def check(ignored):
- self.assertEqual(s.lines, ['Hello 1', 'Hello 2', 'Hello 3'])
- self.assertEqual(c.lines, ['DOOM LINE', 'Hello 1', 'Hello 2', 'Hello 3'])
- self.assertEqual(len(s.connLost), 1)
- self.assertEqual(len(c.connLost), 1)
- d = defer.maybeDeferred(self.loopbackFunc, s, c)
- d.addCallback(check)
- return d
-
-
-
-class LoopbackAsyncTestCase(LoopbackTestCaseMixin, unittest.TestCase):
- loopbackFunc = staticmethod(loopback.loopbackAsync)
-
-
- def test_makeConnection(self):
- """
- Test that the client and server protocol both have makeConnection
- invoked on them by loopbackAsync.
- """
- class TestProtocol(Protocol):
- transport = None
- def makeConnection(self, transport):
- self.transport = transport
-
- server = TestProtocol()
- client = TestProtocol()
- loopback.loopbackAsync(server, client)
- self.failIfEqual(client.transport, None)
- self.failIfEqual(server.transport, None)
-
-
- def _hostpeertest(self, get, testServer):
- """
- Test one of the permutations of client/server host/peer.
- """
- class TestProtocol(Protocol):
- def makeConnection(self, transport):
- Protocol.makeConnection(self, transport)
- self.onConnection.callback(transport)
-
- if testServer:
- server = TestProtocol()
- d = server.onConnection = Deferred()
- client = Protocol()
- else:
- server = Protocol()
- client = TestProtocol()
- d = client.onConnection = Deferred()
-
- loopback.loopbackAsync(server, client)
-
- def connected(transport):
- host = getattr(transport, get)()
- self.failUnless(IAddress.providedBy(host))
-
- return d.addCallback(connected)
-
-
- def test_serverHost(self):
- """
- Test that the server gets a transport with a properly functioning
- implementation of L{ITransport.getHost}.
- """
- return self._hostpeertest("getHost", True)
-
-
- def test_serverPeer(self):
- """
- Like C{test_serverHost} but for L{ITransport.getPeer}
- """
- return self._hostpeertest("getPeer", True)
-
-
- def test_clientHost(self, get="getHost"):
- """
- Test that the client gets a transport with a properly functioning
- implementation of L{ITransport.getHost}.
- """
- return self._hostpeertest("getHost", False)
-
-
- def test_clientPeer(self):
- """
- Like C{test_clientHost} but for L{ITransport.getPeer}.
- """
- return self._hostpeertest("getPeer", False)
-
-
- def _greetingtest(self, write, testServer):
- """
- Test one of the permutations of write/writeSequence client/server.
- """
- class GreeteeProtocol(Protocol):
- bytes = ""
- def dataReceived(self, bytes):
- self.bytes += bytes
- if self.bytes == "bytes":
- self.received.callback(None)
-
- class GreeterProtocol(Protocol):
- def connectionMade(self):
- getattr(self.transport, write)("bytes")
-
- if testServer:
- server = GreeterProtocol()
- client = GreeteeProtocol()
- d = client.received = Deferred()
- else:
- server = GreeteeProtocol()
- d = server.received = Deferred()
- client = GreeterProtocol()
-
- loopback.loopbackAsync(server, client)
- return d
-
-
- def test_clientGreeting(self):
- """
- Test that on a connection where the client speaks first, the server
- receives the bytes sent by the client.
- """
- return self._greetingtest("write", False)
-
-
- def test_clientGreetingSequence(self):
- """
- Like C{test_clientGreeting}, but use C{writeSequence} instead of
- C{write} to issue the greeting.
- """
- return self._greetingtest("writeSequence", False)
-
-
- def test_serverGreeting(self, write="write"):
- """
- Test that on a connection where the server speaks first, the client
- receives the bytes sent by the server.
- """
- return self._greetingtest("write", True)
-
-
- def test_serverGreetingSequence(self):
- """
- Like C{test_serverGreeting}, but use C{writeSequence} instead of
- C{write} to issue the greeting.
- """
- return self._greetingtest("writeSequence", True)
-
-
- def _producertest(self, producerClass):
- toProduce = map(str, range(0, 10))
-
- class ProducingProtocol(Protocol):
- def connectionMade(self):
- self.producer = producerClass(list(toProduce))
- self.producer.start(self.transport)
-
- class ReceivingProtocol(Protocol):
- bytes = ""
- def dataReceived(self, bytes):
- self.bytes += bytes
- if self.bytes == ''.join(toProduce):
- self.received.callback((client, server))
-
- server = ProducingProtocol()
- client = ReceivingProtocol()
- client.received = Deferred()
-
- loopback.loopbackAsync(server, client)
- return client.received
-
-
- def test_pushProducer(self):
- """
- Test a push producer registered against a loopback transport.
- """
- class PushProducer(object):
- implements(IPushProducer)
- resumed = False
-
- def __init__(self, toProduce):
- self.toProduce = toProduce
-
- def resumeProducing(self):
- self.resumed = True
-
- def start(self, consumer):
- self.consumer = consumer
- consumer.registerProducer(self, True)
- self._produceAndSchedule()
-
- def _produceAndSchedule(self):
- if self.toProduce:
- self.consumer.write(self.toProduce.pop(0))
- reactor.callLater(0, self._produceAndSchedule)
- else:
- self.consumer.unregisterProducer()
- d = self._producertest(PushProducer)
-
- def finished((client, server)):
- self.failIf(
- server.producer.resumed,
- "Streaming producer should not have been resumed.")
- d.addCallback(finished)
- return d
-
-
- def test_pullProducer(self):
- """
- Test a pull producer registered against a loopback transport.
- """
- class PullProducer(object):
- implements(IPullProducer)
-
- def __init__(self, toProduce):
- self.toProduce = toProduce
-
- def start(self, consumer):
- self.consumer = consumer
- self.consumer.registerProducer(self, False)
-
- def resumeProducing(self):
- self.consumer.write(self.toProduce.pop(0))
- if not self.toProduce:
- self.consumer.unregisterProducer()
- return self._producertest(PullProducer)
-
-
- def test_writeNotReentrant(self):
- """
- L{loopback.loopbackAsync} does not call a protocol's C{dataReceived}
- method while that protocol's transport's C{write} method is higher up
- on the stack.
- """
- class Server(Protocol):
- def dataReceived(self, bytes):
- self.transport.write("bytes")
-
- class Client(Protocol):
- ready = False
-
- def connectionMade(self):
- reactor.callLater(0, self.go)
-
- def go(self):
- self.transport.write("foo")
- self.ready = True
-
- def dataReceived(self, bytes):
- self.wasReady = self.ready
- self.transport.loseConnection()
-
-
- server = Server()
- client = Client()
- d = loopback.loopbackAsync(client, server)
- def cbFinished(ignored):
- self.assertTrue(client.wasReady)
- d.addCallback(cbFinished)
- return d
-
-
- def test_pumpPolicy(self):
- """
- The callable passed as the value for the C{pumpPolicy} parameter to
- L{loopbackAsync} is called with a L{_LoopbackQueue} of pending bytes
- and a protocol to which they should be delivered.
- """
- pumpCalls = []
- def dummyPolicy(queue, target):
- bytes = []
- while queue:
- bytes.append(queue.get())
- pumpCalls.append((target, bytes))
-
- client = Protocol()
- server = Protocol()
-
- finished = loopback.loopbackAsync(server, client, dummyPolicy)
- self.assertEqual(pumpCalls, [])
-
- client.transport.write("foo")
- client.transport.write("bar")
- server.transport.write("baz")
- server.transport.write("quux")
- server.transport.loseConnection()
-
- def cbComplete(ignored):
- self.assertEqual(
- pumpCalls,
- # The order here is somewhat arbitrary. The implementation
- # happens to always deliver data to the client first.
- [(client, ["baz", "quux", None]),
- (server, ["foo", "bar"])])
- finished.addCallback(cbComplete)
- return finished
-
-
- def test_identityPumpPolicy(self):
- """
- L{identityPumpPolicy} is a pump policy which calls the target's
- C{dataReceived} method one for each string in the queue passed to it.
- """
- bytes = []
- client = Protocol()
- client.dataReceived = bytes.append
- queue = loopback._LoopbackQueue()
- queue.put("foo")
- queue.put("bar")
- queue.put(None)
-
- loopback.identityPumpPolicy(queue, client)
-
- self.assertEqual(bytes, ["foo", "bar"])
-
-
- def test_collapsingPumpPolicy(self):
- """
- L{collapsingPumpPolicy} is a pump policy which calls the target's
- C{dataReceived} only once with all of the strings in the queue passed
- to it joined together.
- """
- bytes = []
- client = Protocol()
- client.dataReceived = bytes.append
- queue = loopback._LoopbackQueue()
- queue.put("foo")
- queue.put("bar")
- queue.put(None)
-
- loopback.collapsingPumpPolicy(queue, client)
-
- self.assertEqual(bytes, ["foobar"])
-
-
-
-class LoopbackTCPTestCase(LoopbackTestCaseMixin, unittest.TestCase):
- loopbackFunc = staticmethod(loopback.loopbackTCP)
-
-
-class LoopbackUNIXTestCase(LoopbackTestCaseMixin, unittest.TestCase):
- loopbackFunc = staticmethod(loopback.loopbackUNIX)
-
- if interfaces.IReactorUNIX(reactor, None) is None:
- skip = "Current reactor does not support UNIX sockets"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_manhole.py
deleted file mode 100755
index fa7d0c75..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_manhole.py
+++ /dev/null
@@ -1,75 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.trial import unittest
-from twisted.manhole import service
-from twisted.spread.util import LocalAsRemote
-
-class Dummy:
- pass
-
-class DummyTransport:
- def getHost(self):
- return 'INET', '127.0.0.1', 0
-
-class DummyManholeClient(LocalAsRemote):
- zero = 0
- broker = Dummy()
- broker.transport = DummyTransport()
-
- def __init__(self):
- self.messages = []
-
- def console(self, messages):
- self.messages.extend(messages)
-
- def receiveExplorer(self, xplorer):
- pass
-
- def setZero(self):
- self.zero = len(self.messages)
-
- def getMessages(self):
- return self.messages[self.zero:]
-
- # local interface
- sync_console = console
- sync_receiveExplorer = receiveExplorer
- sync_setZero = setZero
- sync_getMessages = getMessages
-
-class ManholeTest(unittest.TestCase):
- """Various tests for the manhole service.
-
- Both the the importIdentity and importMain tests are known to fail
- when the __name__ in the manhole namespace is set to certain
- values.
- """
- def setUp(self):
- self.service = service.Service()
- self.p = service.Perspective(self.service)
- self.client = DummyManholeClient()
- self.p.attached(self.client, None)
-
- def test_importIdentity(self):
- """Making sure imported module is the same as one previously loaded.
- """
- self.p.perspective_do("from twisted.manhole import service")
- self.client.setZero()
- self.p.perspective_do("int(service is sys.modules['twisted.manhole.service'])")
- msg = self.client.getMessages()[0]
- self.assertEqual(msg, ('result',"1\n"))
-
- def test_importMain(self):
- """Trying to import __main__"""
- self.client.setZero()
- self.p.perspective_do("import __main__")
- if self.client.getMessages():
- msg = self.client.getMessages()[0]
- if msg[0] in ("exception","stderr"):
- self.fail(msg[1])
-
-#if __name__=='__main__':
-# unittest.main()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_memcache.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_memcache.py
deleted file mode 100755
index 7c25e981..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_memcache.py
+++ /dev/null
@@ -1,663 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test the memcache client protocol.
-"""
-
-from twisted.internet.error import ConnectionDone
-
-from twisted.protocols.memcache import MemCacheProtocol, NoSuchCommand
-from twisted.protocols.memcache import ClientError, ServerError
-
-from twisted.trial.unittest import TestCase
-from twisted.test.proto_helpers import StringTransportWithDisconnection
-from twisted.internet.task import Clock
-from twisted.internet.defer import Deferred, gatherResults, TimeoutError
-from twisted.internet.defer import DeferredList
-
-
-
-class CommandMixin:
- """
- Setup and tests for basic invocation of L{MemCacheProtocol} commands.
- """
-
- def _test(self, d, send, recv, result):
- """
- Helper test method to test the resulting C{Deferred} of a
- L{MemCacheProtocol} command.
- """
- raise NotImplementedError()
-
-
- def test_get(self):
- """
- L{MemCacheProtocol.get} returns a L{Deferred} which is called back with
- the value and the flag associated with the given key if the server
- returns a successful result.
- """
- return self._test(self.proto.get("foo"), "get foo\r\n",
- "VALUE foo 0 3\r\nbar\r\nEND\r\n", (0, "bar"))
-
-
- def test_emptyGet(self):
- """
- Test getting a non-available key: it succeeds but return C{None} as
- value and C{0} as flag.
- """
- return self._test(self.proto.get("foo"), "get foo\r\n",
- "END\r\n", (0, None))
-
-
- def test_getMultiple(self):
- """
- L{MemCacheProtocol.getMultiple} returns a L{Deferred} which is called
- back with a dictionary of flag, value for each given key.
- """
- return self._test(self.proto.getMultiple(['foo', 'cow']),
- "get foo cow\r\n",
- "VALUE foo 0 3\r\nbar\r\nVALUE cow 0 7\r\nchicken\r\nEND\r\n",
- {'cow': (0, 'chicken'), 'foo': (0, 'bar')})
-
-
- def test_getMultipleWithEmpty(self):
- """
- When L{MemCacheProtocol.getMultiple} is called with non-available keys,
- the corresponding tuples are (0, None).
- """
- return self._test(self.proto.getMultiple(['foo', 'cow']),
- "get foo cow\r\n",
- "VALUE cow 1 3\r\nbar\r\nEND\r\n",
- {'cow': (1, 'bar'), 'foo': (0, None)})
-
-
- def test_set(self):
- """
- L{MemCacheProtocol.set} returns a L{Deferred} which is called back with
- C{True} when the operation succeeds.
- """
- return self._test(self.proto.set("foo", "bar"),
- "set foo 0 0 3\r\nbar\r\n", "STORED\r\n", True)
-
-
- def test_add(self):
- """
- L{MemCacheProtocol.add} returns a L{Deferred} which is called back with
- C{True} when the operation succeeds.
- """
- return self._test(self.proto.add("foo", "bar"),
- "add foo 0 0 3\r\nbar\r\n", "STORED\r\n", True)
-
-
- def test_replace(self):
- """
- L{MemCacheProtocol.replace} returns a L{Deferred} which is called back
- with C{True} when the operation succeeds.
- """
- return self._test(self.proto.replace("foo", "bar"),
- "replace foo 0 0 3\r\nbar\r\n", "STORED\r\n", True)
-
-
- def test_errorAdd(self):
- """
- Test an erroneous add: if a L{MemCacheProtocol.add} is called but the
- key already exists on the server, it returns a B{NOT STORED} answer,
- which calls back the resulting L{Deferred} with C{False}.
- """
- return self._test(self.proto.add("foo", "bar"),
- "add foo 0 0 3\r\nbar\r\n", "NOT STORED\r\n", False)
-
-
- def test_errorReplace(self):
- """
- Test an erroneous replace: if a L{MemCacheProtocol.replace} is called
- but the key doesn't exist on the server, it returns a B{NOT STORED}
- answer, which calls back the resulting L{Deferred} with C{False}.
- """
- return self._test(self.proto.replace("foo", "bar"),
- "replace foo 0 0 3\r\nbar\r\n", "NOT STORED\r\n", False)
-
-
- def test_delete(self):
- """
- L{MemCacheProtocol.delete} returns a L{Deferred} which is called back
- with C{True} when the server notifies a success.
- """
- return self._test(self.proto.delete("bar"), "delete bar\r\n",
- "DELETED\r\n", True)
-
-
- def test_errorDelete(self):
- """
- Test a error during a delete: if key doesn't exist on the server, it
- returns a B{NOT FOUND} answer which calls back the resulting L{Deferred}
- with C{False}.
- """
- return self._test(self.proto.delete("bar"), "delete bar\r\n",
- "NOT FOUND\r\n", False)
-
-
- def test_increment(self):
- """
- Test incrementing a variable: L{MemCacheProtocol.increment} returns a
- L{Deferred} which is called back with the incremented value of the
- given key.
- """
- return self._test(self.proto.increment("foo"), "incr foo 1\r\n",
- "4\r\n", 4)
-
-
- def test_decrement(self):
- """
- Test decrementing a variable: L{MemCacheProtocol.decrement} returns a
- L{Deferred} which is called back with the decremented value of the
- given key.
- """
- return self._test(
- self.proto.decrement("foo"), "decr foo 1\r\n", "5\r\n", 5)
-
-
- def test_incrementVal(self):
- """
- L{MemCacheProtocol.increment} takes an optional argument C{value} which
- replaces the default value of 1 when specified.
- """
- return self._test(self.proto.increment("foo", 8), "incr foo 8\r\n",
- "4\r\n", 4)
-
-
- def test_decrementVal(self):
- """
- L{MemCacheProtocol.decrement} takes an optional argument C{value} which
- replaces the default value of 1 when specified.
- """
- return self._test(self.proto.decrement("foo", 3), "decr foo 3\r\n",
- "5\r\n", 5)
-
-
- def test_stats(self):
- """
- Test retrieving server statistics via the L{MemCacheProtocol.stats}
- command: it parses the data sent by the server and calls back the
- resulting L{Deferred} with a dictionary of the received statistics.
- """
- return self._test(self.proto.stats(), "stats\r\n",
- "STAT foo bar\r\nSTAT egg spam\r\nEND\r\n",
- {"foo": "bar", "egg": "spam"})
-
-
- def test_statsWithArgument(self):
- """
- L{MemCacheProtocol.stats} takes an optional C{str} argument which,
- if specified, is sent along with the I{STAT} command. The I{STAT}
- responses from the server are parsed as key/value pairs and returned
- as a C{dict} (as in the case where the argument is not specified).
- """
- return self._test(self.proto.stats("blah"), "stats blah\r\n",
- "STAT foo bar\r\nSTAT egg spam\r\nEND\r\n",
- {"foo": "bar", "egg": "spam"})
-
-
- def test_version(self):
- """
- Test version retrieval via the L{MemCacheProtocol.version} command: it
- returns a L{Deferred} which is called back with the version sent by the
- server.
- """
- return self._test(self.proto.version(), "version\r\n",
- "VERSION 1.1\r\n", "1.1")
-
-
- def test_flushAll(self):
- """
- L{MemCacheProtocol.flushAll} returns a L{Deferred} which is called back
- with C{True} if the server acknowledges success.
- """
- return self._test(self.proto.flushAll(), "flush_all\r\n",
- "OK\r\n", True)
-
-
-
-class MemCacheTestCase(CommandMixin, TestCase):
- """
- Test client protocol class L{MemCacheProtocol}.
- """
-
- def setUp(self):
- """
- Create a memcache client, connect it to a string protocol, and make it
- use a deterministic clock.
- """
- self.proto = MemCacheProtocol()
- self.clock = Clock()
- self.proto.callLater = self.clock.callLater
- self.transport = StringTransportWithDisconnection()
- self.transport.protocol = self.proto
- self.proto.makeConnection(self.transport)
-
-
- def _test(self, d, send, recv, result):
- """
- Implementation of C{_test} which checks that the command sends C{send}
- data, and that upon reception of C{recv} the result is C{result}.
-
- @param d: the resulting deferred from the memcache command.
- @type d: C{Deferred}
-
- @param send: the expected data to be sent.
- @type send: C{str}
-
- @param recv: the data to simulate as reception.
- @type recv: C{str}
-
- @param result: the expected result.
- @type result: C{any}
- """
- def cb(res):
- self.assertEqual(res, result)
- self.assertEqual(self.transport.value(), send)
- d.addCallback(cb)
- self.proto.dataReceived(recv)
- return d
-
-
- def test_invalidGetResponse(self):
- """
- If the value returned doesn't match the expected key of the current
- C{get} command, an error is raised in L{MemCacheProtocol.dataReceived}.
- """
- self.proto.get("foo")
- s = "spamegg"
- self.assertRaises(RuntimeError,
- self.proto.dataReceived,
- "VALUE bar 0 %s\r\n%s\r\nEND\r\n" % (len(s), s))
-
-
- def test_invalidMultipleGetResponse(self):
- """
- If the value returned doesn't match one the expected keys of the
- current multiple C{get} command, an error is raised error in
- L{MemCacheProtocol.dataReceived}.
- """
- self.proto.getMultiple(["foo", "bar"])
- s = "spamegg"
- self.assertRaises(RuntimeError,
- self.proto.dataReceived,
- "VALUE egg 0 %s\r\n%s\r\nEND\r\n" % (len(s), s))
-
-
- def test_timeOut(self):
- """
- Test the timeout on outgoing requests: when timeout is detected, all
- current commands fail with a L{TimeoutError}, and the connection is
- closed.
- """
- d1 = self.proto.get("foo")
- d2 = self.proto.get("bar")
- d3 = Deferred()
- self.proto.connectionLost = d3.callback
-
- self.clock.advance(self.proto.persistentTimeOut)
- self.assertFailure(d1, TimeoutError)
- self.assertFailure(d2, TimeoutError)
- def checkMessage(error):
- self.assertEqual(str(error), "Connection timeout")
- d1.addCallback(checkMessage)
- return gatherResults([d1, d2, d3])
-
-
- def test_timeoutRemoved(self):
- """
- When a request gets a response, no pending timeout call remains around.
- """
- d = self.proto.get("foo")
-
- self.clock.advance(self.proto.persistentTimeOut - 1)
- self.proto.dataReceived("VALUE foo 0 3\r\nbar\r\nEND\r\n")
-
- def check(result):
- self.assertEqual(result, (0, "bar"))
- self.assertEqual(len(self.clock.calls), 0)
- d.addCallback(check)
- return d
-
-
- def test_timeOutRaw(self):
- """
- Test the timeout when raw mode was started: the timeout is not reset
- until all the data has been received, so we can have a L{TimeoutError}
- when waiting for raw data.
- """
- d1 = self.proto.get("foo")
- d2 = Deferred()
- self.proto.connectionLost = d2.callback
-
- self.proto.dataReceived("VALUE foo 0 10\r\n12345")
- self.clock.advance(self.proto.persistentTimeOut)
- self.assertFailure(d1, TimeoutError)
- return gatherResults([d1, d2])
-
-
- def test_timeOutStat(self):
- """
- Test the timeout when stat command has started: the timeout is not
- reset until the final B{END} is received.
- """
- d1 = self.proto.stats()
- d2 = Deferred()
- self.proto.connectionLost = d2.callback
-
- self.proto.dataReceived("STAT foo bar\r\n")
- self.clock.advance(self.proto.persistentTimeOut)
- self.assertFailure(d1, TimeoutError)
- return gatherResults([d1, d2])
-
-
- def test_timeoutPipelining(self):
- """
- When two requests are sent, a timeout call remains around for the
- second request, and its timeout time is correct.
- """
- d1 = self.proto.get("foo")
- d2 = self.proto.get("bar")
- d3 = Deferred()
- self.proto.connectionLost = d3.callback
-
- self.clock.advance(self.proto.persistentTimeOut - 1)
- self.proto.dataReceived("VALUE foo 0 3\r\nbar\r\nEND\r\n")
-
- def check(result):
- self.assertEqual(result, (0, "bar"))
- self.assertEqual(len(self.clock.calls), 1)
- for i in range(self.proto.persistentTimeOut):
- self.clock.advance(1)
- return self.assertFailure(d2, TimeoutError).addCallback(checkTime)
- def checkTime(ignored):
- # Check that the timeout happened C{self.proto.persistentTimeOut}
- # after the last response
- self.assertEqual(
- self.clock.seconds(), 2 * self.proto.persistentTimeOut - 1)
- d1.addCallback(check)
- return d1
-
-
- def test_timeoutNotReset(self):
- """
- Check that timeout is not resetted for every command, but keep the
- timeout from the first command without response.
- """
- d1 = self.proto.get("foo")
- d3 = Deferred()
- self.proto.connectionLost = d3.callback
-
- self.clock.advance(self.proto.persistentTimeOut - 1)
- d2 = self.proto.get("bar")
- self.clock.advance(1)
- self.assertFailure(d1, TimeoutError)
- self.assertFailure(d2, TimeoutError)
- return gatherResults([d1, d2, d3])
-
-
- def test_timeoutCleanDeferreds(self):
- """
- C{timeoutConnection} cleans the list of commands that it fires with
- C{TimeoutError}: C{connectionLost} doesn't try to fire them again, but
- sets the disconnected state so that future commands fail with a
- C{RuntimeError}.
- """
- d1 = self.proto.get("foo")
- self.clock.advance(self.proto.persistentTimeOut)
- self.assertFailure(d1, TimeoutError)
- d2 = self.proto.get("bar")
- self.assertFailure(d2, RuntimeError)
- return gatherResults([d1, d2])
-
-
- def test_connectionLost(self):
- """
- When disconnection occurs while commands are still outstanding, the
- commands fail.
- """
- d1 = self.proto.get("foo")
- d2 = self.proto.get("bar")
- self.transport.loseConnection()
- done = DeferredList([d1, d2], consumeErrors=True)
- def checkFailures(results):
- for success, result in results:
- self.assertFalse(success)
- result.trap(ConnectionDone)
- return done.addCallback(checkFailures)
-
-
- def test_tooLongKey(self):
- """
- An error is raised when trying to use a too long key: the called
- command returns a L{Deferred} which fails with a L{ClientError}.
- """
- d1 = self.assertFailure(self.proto.set("a" * 500, "bar"), ClientError)
- d2 = self.assertFailure(self.proto.increment("a" * 500), ClientError)
- d3 = self.assertFailure(self.proto.get("a" * 500), ClientError)
- d4 = self.assertFailure(
- self.proto.append("a" * 500, "bar"), ClientError)
- d5 = self.assertFailure(
- self.proto.prepend("a" * 500, "bar"), ClientError)
- d6 = self.assertFailure(
- self.proto.getMultiple(["foo", "a" * 500]), ClientError)
- return gatherResults([d1, d2, d3, d4, d5, d6])
-
-
- def test_invalidCommand(self):
- """
- When an unknown command is sent directly (not through public API), the
- server answers with an B{ERROR} token, and the command fails with
- L{NoSuchCommand}.
- """
- d = self.proto._set("egg", "foo", "bar", 0, 0, "")
- self.assertEqual(self.transport.value(), "egg foo 0 0 3\r\nbar\r\n")
- self.assertFailure(d, NoSuchCommand)
- self.proto.dataReceived("ERROR\r\n")
- return d
-
-
- def test_clientError(self):
- """
- Test the L{ClientError} error: when the server sends a B{CLIENT_ERROR}
- token, the originating command fails with L{ClientError}, and the error
- contains the text sent by the server.
- """
- a = "eggspamm"
- d = self.proto.set("foo", a)
- self.assertEqual(self.transport.value(),
- "set foo 0 0 8\r\neggspamm\r\n")
- self.assertFailure(d, ClientError)
- def check(err):
- self.assertEqual(str(err), "We don't like egg and spam")
- d.addCallback(check)
- self.proto.dataReceived("CLIENT_ERROR We don't like egg and spam\r\n")
- return d
-
-
- def test_serverError(self):
- """
- Test the L{ServerError} error: when the server sends a B{SERVER_ERROR}
- token, the originating command fails with L{ServerError}, and the error
- contains the text sent by the server.
- """
- a = "eggspamm"
- d = self.proto.set("foo", a)
- self.assertEqual(self.transport.value(),
- "set foo 0 0 8\r\neggspamm\r\n")
- self.assertFailure(d, ServerError)
- def check(err):
- self.assertEqual(str(err), "zomg")
- d.addCallback(check)
- self.proto.dataReceived("SERVER_ERROR zomg\r\n")
- return d
-
-
- def test_unicodeKey(self):
- """
- Using a non-string key as argument to commands raises an error.
- """
- d1 = self.assertFailure(self.proto.set(u"foo", "bar"), ClientError)
- d2 = self.assertFailure(self.proto.increment(u"egg"), ClientError)
- d3 = self.assertFailure(self.proto.get(1), ClientError)
- d4 = self.assertFailure(self.proto.delete(u"bar"), ClientError)
- d5 = self.assertFailure(self.proto.append(u"foo", "bar"), ClientError)
- d6 = self.assertFailure(self.proto.prepend(u"foo", "bar"), ClientError)
- d7 = self.assertFailure(
- self.proto.getMultiple(["egg", 1]), ClientError)
- return gatherResults([d1, d2, d3, d4, d5, d6, d7])
-
-
- def test_unicodeValue(self):
- """
- Using a non-string value raises an error.
- """
- return self.assertFailure(self.proto.set("foo", u"bar"), ClientError)
-
-
- def test_pipelining(self):
- """
- Multiple requests can be sent subsequently to the server, and the
- protocol orders the responses correctly and dispatch to the
- corresponding client command.
- """
- d1 = self.proto.get("foo")
- d1.addCallback(self.assertEqual, (0, "bar"))
- d2 = self.proto.set("bar", "spamspamspam")
- d2.addCallback(self.assertEqual, True)
- d3 = self.proto.get("egg")
- d3.addCallback(self.assertEqual, (0, "spam"))
- self.assertEqual(self.transport.value(),
- "get foo\r\nset bar 0 0 12\r\nspamspamspam\r\nget egg\r\n")
- self.proto.dataReceived("VALUE foo 0 3\r\nbar\r\nEND\r\n"
- "STORED\r\n"
- "VALUE egg 0 4\r\nspam\r\nEND\r\n")
- return gatherResults([d1, d2, d3])
-
-
- def test_getInChunks(self):
- """
- If the value retrieved by a C{get} arrive in chunks, the protocol
- is able to reconstruct it and to produce the good value.
- """
- d = self.proto.get("foo")
- d.addCallback(self.assertEqual, (0, "0123456789"))
- self.assertEqual(self.transport.value(), "get foo\r\n")
- self.proto.dataReceived("VALUE foo 0 10\r\n0123456")
- self.proto.dataReceived("789")
- self.proto.dataReceived("\r\nEND")
- self.proto.dataReceived("\r\n")
- return d
-
-
- def test_append(self):
- """
- L{MemCacheProtocol.append} behaves like a L{MemCacheProtocol.set}
- method: it returns a L{Deferred} which is called back with C{True} when
- the operation succeeds.
- """
- return self._test(self.proto.append("foo", "bar"),
- "append foo 0 0 3\r\nbar\r\n", "STORED\r\n", True)
-
-
- def test_prepend(self):
- """
- L{MemCacheProtocol.prepend} behaves like a L{MemCacheProtocol.set}
- method: it returns a L{Deferred} which is called back with C{True} when
- the operation succeeds.
- """
- return self._test(self.proto.prepend("foo", "bar"),
- "prepend foo 0 0 3\r\nbar\r\n", "STORED\r\n", True)
-
-
- def test_gets(self):
- """
- L{MemCacheProtocol.get} handles an additional cas result when
- C{withIdentifier} is C{True} and forward it in the resulting
- L{Deferred}.
- """
- return self._test(self.proto.get("foo", True), "gets foo\r\n",
- "VALUE foo 0 3 1234\r\nbar\r\nEND\r\n", (0, "1234", "bar"))
-
-
- def test_emptyGets(self):
- """
- Test getting a non-available key with gets: it succeeds but return
- C{None} as value, C{0} as flag and an empty cas value.
- """
- return self._test(self.proto.get("foo", True), "gets foo\r\n",
- "END\r\n", (0, "", None))
-
-
- def test_getsMultiple(self):
- """
- L{MemCacheProtocol.getMultiple} handles an additional cas field in the
- returned tuples if C{withIdentifier} is C{True}.
- """
- return self._test(self.proto.getMultiple(["foo", "bar"], True),
- "gets foo bar\r\n",
- "VALUE foo 0 3 1234\r\negg\r\nVALUE bar 0 4 2345\r\nspam\r\nEND\r\n",
- {'bar': (0, '2345', 'spam'), 'foo': (0, '1234', 'egg')})
-
-
- def test_getsMultipleWithEmpty(self):
- """
- When getting a non-available key with L{MemCacheProtocol.getMultiple}
- when C{withIdentifier} is C{True}, the other keys are retrieved
- correctly, and the non-available key gets a tuple of C{0} as flag,
- C{None} as value, and an empty cas value.
- """
- return self._test(self.proto.getMultiple(["foo", "bar"], True),
- "gets foo bar\r\n",
- "VALUE foo 0 3 1234\r\negg\r\nEND\r\n",
- {'bar': (0, '', None), 'foo': (0, '1234', 'egg')})
-
-
- def test_checkAndSet(self):
- """
- L{MemCacheProtocol.checkAndSet} passes an additional cas identifier
- that the server handles to check if the data has to be updated.
- """
- return self._test(self.proto.checkAndSet("foo", "bar", cas="1234"),
- "cas foo 0 0 3 1234\r\nbar\r\n", "STORED\r\n", True)
-
-
- def test_casUnknowKey(self):
- """
- When L{MemCacheProtocol.checkAndSet} response is C{EXISTS}, the
- resulting L{Deferred} fires with C{False}.
- """
- return self._test(self.proto.checkAndSet("foo", "bar", cas="1234"),
- "cas foo 0 0 3 1234\r\nbar\r\n", "EXISTS\r\n", False)
-
-
-
-class CommandFailureTests(CommandMixin, TestCase):
- """
- Tests for correct failure of commands on a disconnected
- L{MemCacheProtocol}.
- """
-
- def setUp(self):
- """
- Create a disconnected memcache client, using a deterministic clock.
- """
- self.proto = MemCacheProtocol()
- self.clock = Clock()
- self.proto.callLater = self.clock.callLater
- self.transport = StringTransportWithDisconnection()
- self.transport.protocol = self.proto
- self.proto.makeConnection(self.transport)
- self.transport.loseConnection()
-
-
- def _test(self, d, send, recv, result):
- """
- Implementation of C{_test} which checks that the command fails with
- C{RuntimeError} because the transport is disconnected. All the
- parameters except C{d} are ignored.
- """
- return self.assertFailure(d, RuntimeError)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_modules.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_modules.py
deleted file mode 100755
index 4b74f0d0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_modules.py
+++ /dev/null
@@ -1,478 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for twisted.python.modules, abstract access to imported or importable
-objects.
-"""
-
-import sys
-import itertools
-import zipfile
-import compileall
-
-import twisted
-from twisted.trial.unittest import TestCase
-
-from twisted.python import modules
-from twisted.python.filepath import FilePath
-from twisted.python.reflect import namedAny
-
-from twisted.python.test.modules_helpers import TwistedModulesTestCase
-from twisted.test.test_paths import zipit
-
-
-
-class BasicTests(TwistedModulesTestCase):
-
- def test_namespacedPackages(self):
- """
- Duplicate packages are not yielded when iterating over namespace
- packages.
- """
- # Force pkgutil to be loaded already, since the probe package being
- # created depends on it, and the replaceSysPath call below will make
- # pretty much everything unimportable.
- __import__('pkgutil')
-
- namespaceBoilerplate = (
- 'import pkgutil; '
- '__path__ = pkgutil.extend_path(__path__, __name__)')
-
- # Create two temporary directories with packages:
- #
- # entry:
- # test_package/
- # __init__.py
- # nested_package/
- # __init__.py
- # module.py
- #
- # anotherEntry:
- # test_package/
- # __init__.py
- # nested_package/
- # __init__.py
- # module2.py
- #
- # test_package and test_package.nested_package are namespace packages,
- # and when both of these are in sys.path, test_package.nested_package
- # should become a virtual package containing both "module" and
- # "module2"
-
- entry = self.pathEntryWithOnePackage()
- testPackagePath = entry.child('test_package')
- testPackagePath.child('__init__.py').setContent(namespaceBoilerplate)
-
- nestedEntry = testPackagePath.child('nested_package')
- nestedEntry.makedirs()
- nestedEntry.child('__init__.py').setContent(namespaceBoilerplate)
- nestedEntry.child('module.py').setContent('')
-
- anotherEntry = self.pathEntryWithOnePackage()
- anotherPackagePath = anotherEntry.child('test_package')
- anotherPackagePath.child('__init__.py').setContent(namespaceBoilerplate)
-
- anotherNestedEntry = anotherPackagePath.child('nested_package')
- anotherNestedEntry.makedirs()
- anotherNestedEntry.child('__init__.py').setContent(namespaceBoilerplate)
- anotherNestedEntry.child('module2.py').setContent('')
-
- self.replaceSysPath([entry.path, anotherEntry.path])
-
- module = modules.getModule('test_package')
-
- # We have to use importPackages=True in order to resolve the namespace
- # packages, so we remove the imported packages from sys.modules after
- # walking
- try:
- walkedNames = [
- mod.name for mod in module.walkModules(importPackages=True)]
- finally:
- for module in sys.modules.keys():
- if module.startswith('test_package'):
- del sys.modules[module]
-
- expected = [
- 'test_package',
- 'test_package.nested_package',
- 'test_package.nested_package.module',
- 'test_package.nested_package.module2',
- ]
-
- self.assertEqual(walkedNames, expected)
-
-
- def test_unimportablePackageGetItem(self):
- """
- If a package has been explicitly forbidden from importing by setting a
- C{None} key in sys.modules under its name,
- L{modules.PythonPath.__getitem__} should still be able to retrieve an
- unloaded L{modules.PythonModule} for that package.
- """
- shouldNotLoad = []
- path = modules.PythonPath(sysPath=[self.pathEntryWithOnePackage().path],
- moduleLoader=shouldNotLoad.append,
- importerCache={},
- sysPathHooks={},
- moduleDict={'test_package': None})
- self.assertEqual(shouldNotLoad, [])
- self.assertEqual(path['test_package'].isLoaded(), False)
-
-
- def test_unimportablePackageWalkModules(self):
- """
- If a package has been explicitly forbidden from importing by setting a
- C{None} key in sys.modules under its name, L{modules.walkModules} should
- still be able to retrieve an unloaded L{modules.PythonModule} for that
- package.
- """
- existentPath = self.pathEntryWithOnePackage()
- self.replaceSysPath([existentPath.path])
- self.replaceSysModules({"test_package": None})
-
- walked = list(modules.walkModules())
- self.assertEqual([m.name for m in walked],
- ["test_package"])
- self.assertEqual(walked[0].isLoaded(), False)
-
-
- def test_nonexistentPaths(self):
- """
- Verify that L{modules.walkModules} ignores entries in sys.path which
- do not exist in the filesystem.
- """
- existentPath = self.pathEntryWithOnePackage()
-
- nonexistentPath = FilePath(self.mktemp())
- self.failIf(nonexistentPath.exists())
-
- self.replaceSysPath([existentPath.path])
-
- expected = [modules.getModule("test_package")]
-
- beforeModules = list(modules.walkModules())
- sys.path.append(nonexistentPath.path)
- afterModules = list(modules.walkModules())
-
- self.assertEqual(beforeModules, expected)
- self.assertEqual(afterModules, expected)
-
-
- def test_nonDirectoryPaths(self):
- """
- Verify that L{modules.walkModules} ignores entries in sys.path which
- refer to regular files in the filesystem.
- """
- existentPath = self.pathEntryWithOnePackage()
-
- nonDirectoryPath = FilePath(self.mktemp())
- self.failIf(nonDirectoryPath.exists())
- nonDirectoryPath.setContent("zip file or whatever\n")
-
- self.replaceSysPath([existentPath.path])
-
- beforeModules = list(modules.walkModules())
- sys.path.append(nonDirectoryPath.path)
- afterModules = list(modules.walkModules())
-
- self.assertEqual(beforeModules, afterModules)
-
-
- def test_twistedShowsUp(self):
- """
- Scrounge around in the top-level module namespace and make sure that
- Twisted shows up, and that the module thusly obtained is the same as
- the module that we find when we look for it explicitly by name.
- """
- self.assertEqual(modules.getModule('twisted'),
- self.findByIteration("twisted"))
-
-
- def test_dottedNames(self):
- """
- Verify that the walkModules APIs will give us back subpackages, not just
- subpackages.
- """
- self.assertEqual(
- modules.getModule('twisted.python'),
- self.findByIteration("twisted.python",
- where=modules.getModule('twisted')))
-
-
- def test_onlyTopModules(self):
- """
- Verify that the iterModules API will only return top-level modules and
- packages, not submodules or subpackages.
- """
- for module in modules.iterModules():
- self.failIf(
- '.' in module.name,
- "no nested modules should be returned from iterModules: %r"
- % (module.filePath))
-
-
- def test_loadPackagesAndModules(self):
- """
- Verify that we can locate and load packages, modules, submodules, and
- subpackages.
- """
- for n in ['os',
- 'twisted',
- 'twisted.python',
- 'twisted.python.reflect']:
- m = namedAny(n)
- self.failUnlessIdentical(
- modules.getModule(n).load(),
- m)
- self.failUnlessIdentical(
- self.findByIteration(n).load(),
- m)
-
-
- def test_pathEntriesOnPath(self):
- """
- Verify that path entries discovered via module loading are, in fact, on
- sys.path somewhere.
- """
- for n in ['os',
- 'twisted',
- 'twisted.python',
- 'twisted.python.reflect']:
- self.failUnlessIn(
- modules.getModule(n).pathEntry.filePath.path,
- sys.path)
-
-
- def test_alwaysPreferPy(self):
- """
- Verify that .py files will always be preferred to .pyc files, regardless of
- directory listing order.
- """
- mypath = FilePath(self.mktemp())
- mypath.createDirectory()
- pp = modules.PythonPath(sysPath=[mypath.path])
- originalSmartPath = pp._smartPath
- def _evilSmartPath(pathName):
- o = originalSmartPath(pathName)
- originalChildren = o.children
- def evilChildren():
- # normally this order is random; let's make sure it always
- # comes up .pyc-first.
- x = originalChildren()
- x.sort()
- x.reverse()
- return x
- o.children = evilChildren
- return o
- mypath.child("abcd.py").setContent('\n')
- compileall.compile_dir(mypath.path, quiet=True)
- # sanity check
- self.assertEqual(len(mypath.children()), 2)
- pp._smartPath = _evilSmartPath
- self.assertEqual(pp['abcd'].filePath,
- mypath.child('abcd.py'))
-
-
- def test_packageMissingPath(self):
- """
- A package can delete its __path__ for some reasons,
- C{modules.PythonPath} should be able to deal with it.
- """
- mypath = FilePath(self.mktemp())
- mypath.createDirectory()
- pp = modules.PythonPath(sysPath=[mypath.path])
- subpath = mypath.child("abcd")
- subpath.createDirectory()
- subpath.child("__init__.py").setContent('del __path__\n')
- sys.path.append(mypath.path)
- __import__("abcd")
- try:
- l = list(pp.walkModules())
- self.assertEqual(len(l), 1)
- self.assertEqual(l[0].name, 'abcd')
- finally:
- del sys.modules['abcd']
- sys.path.remove(mypath.path)
-
-
-
-class PathModificationTest(TwistedModulesTestCase):
- """
- These tests share setup/cleanup behavior of creating a dummy package and
- stuffing some code in it.
- """
-
- _serialnum = itertools.count().next # used to generate serial numbers for
- # package names.
-
- def setUp(self):
- self.pathExtensionName = self.mktemp()
- self.pathExtension = FilePath(self.pathExtensionName)
- self.pathExtension.createDirectory()
- self.packageName = "pyspacetests%d" % (self._serialnum(),)
- self.packagePath = self.pathExtension.child(self.packageName)
- self.packagePath.createDirectory()
- self.packagePath.child("__init__.py").setContent("")
- self.packagePath.child("a.py").setContent("")
- self.packagePath.child("b.py").setContent("")
- self.packagePath.child("c__init__.py").setContent("")
- self.pathSetUp = False
-
-
- def _setupSysPath(self):
- assert not self.pathSetUp
- self.pathSetUp = True
- sys.path.append(self.pathExtensionName)
-
-
- def _underUnderPathTest(self, doImport=True):
- moddir2 = self.mktemp()
- fpmd = FilePath(moddir2)
- fpmd.createDirectory()
- fpmd.child("foozle.py").setContent("x = 123\n")
- self.packagePath.child("__init__.py").setContent(
- "__path__.append(%r)\n" % (moddir2,))
- # Cut here
- self._setupSysPath()
- modinfo = modules.getModule(self.packageName)
- self.assertEqual(
- self.findByIteration(self.packageName+".foozle", modinfo,
- importPackages=doImport),
- modinfo['foozle'])
- self.assertEqual(modinfo['foozle'].load().x, 123)
-
-
- def test_underUnderPathAlreadyImported(self):
- """
- Verify that iterModules will honor the __path__ of already-loaded packages.
- """
- self._underUnderPathTest()
-
-
- def test_underUnderPathNotAlreadyImported(self):
- """
- Verify that iterModules will honor the __path__ of already-loaded packages.
- """
- self._underUnderPathTest(False)
-
-
- test_underUnderPathNotAlreadyImported.todo = (
- "This may be impossible but it sure would be nice.")
-
-
- def _listModules(self):
- pkginfo = modules.getModule(self.packageName)
- nfni = [modinfo.name.split(".")[-1] for modinfo in
- pkginfo.iterModules()]
- nfni.sort()
- self.assertEqual(nfni, ['a', 'b', 'c__init__'])
-
-
- def test_listingModules(self):
- """
- Make sure the module list comes back as we expect from iterModules on a
- package, whether zipped or not.
- """
- self._setupSysPath()
- self._listModules()
-
-
- def test_listingModulesAlreadyImported(self):
- """
- Make sure the module list comes back as we expect from iterModules on a
- package, whether zipped or not, even if the package has already been
- imported.
- """
- self._setupSysPath()
- namedAny(self.packageName)
- self._listModules()
-
-
- def tearDown(self):
- # Intentionally using 'assert' here, this is not a test assertion, this
- # is just an "oh fuck what is going ON" assertion. -glyph
- if self.pathSetUp:
- HORK = "path cleanup failed: don't be surprised if other tests break"
- assert sys.path.pop() is self.pathExtensionName, HORK+", 1"
- assert self.pathExtensionName not in sys.path, HORK+", 2"
-
-
-
-class RebindingTest(PathModificationTest):
- """
- These tests verify that the default path interrogation API works properly
- even when sys.path has been rebound to a different object.
- """
- def _setupSysPath(self):
- assert not self.pathSetUp
- self.pathSetUp = True
- self.savedSysPath = sys.path
- sys.path = sys.path[:]
- sys.path.append(self.pathExtensionName)
-
-
- def tearDown(self):
- """
- Clean up sys.path by re-binding our original object.
- """
- if self.pathSetUp:
- sys.path = self.savedSysPath
-
-
-
-class ZipPathModificationTest(PathModificationTest):
- def _setupSysPath(self):
- assert not self.pathSetUp
- zipit(self.pathExtensionName, self.pathExtensionName+'.zip')
- self.pathExtensionName += '.zip'
- assert zipfile.is_zipfile(self.pathExtensionName)
- PathModificationTest._setupSysPath(self)
-
-
-class PythonPathTestCase(TestCase):
- """
- Tests for the class which provides the implementation for all of the
- public API of L{twisted.python.modules}, L{PythonPath}.
- """
- def test_unhandledImporter(self):
- """
- Make sure that the behavior when encountering an unknown importer
- type is not catastrophic failure.
- """
- class SecretImporter(object):
- pass
-
- def hook(name):
- return SecretImporter()
-
- syspath = ['example/path']
- sysmodules = {}
- syshooks = [hook]
- syscache = {}
- def sysloader(name):
- return None
- space = modules.PythonPath(
- syspath, sysmodules, syshooks, syscache, sysloader)
- entries = list(space.iterEntries())
- self.assertEqual(len(entries), 1)
- self.assertRaises(KeyError, lambda: entries[0]['module'])
-
-
- def test_inconsistentImporterCache(self):
- """
- If the path a module loaded with L{PythonPath.__getitem__} is not
- present in the path importer cache, a warning is emitted, but the
- L{PythonModule} is returned as usual.
- """
- space = modules.PythonPath([], sys.modules, [], {})
- thisModule = space[__name__]
- warnings = self.flushWarnings([self.test_inconsistentImporterCache])
- self.assertEqual(warnings[0]['category'], UserWarning)
- self.assertEqual(
- warnings[0]['message'],
- FilePath(twisted.__file__).parent().dirname() +
- " (for module " + __name__ + ") not in path importer cache "
- "(PEP 302 violation - check your local configuration).")
- self.assertEqual(len(warnings), 1)
- self.assertEqual(thisModule.name, __name__)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_monkey.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_monkey.py
deleted file mode 100755
index e31f0202..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_monkey.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.monkey}.
-"""
-
-from twisted.trial import unittest
-from twisted.python.monkey import MonkeyPatcher
-
-
-class TestObj:
- def __init__(self):
- self.foo = 'foo value'
- self.bar = 'bar value'
- self.baz = 'baz value'
-
-
-class MonkeyPatcherTest(unittest.TestCase):
- """
- Tests for L{MonkeyPatcher} monkey-patching class.
- """
-
- def setUp(self):
- self.testObject = TestObj()
- self.originalObject = TestObj()
- self.monkeyPatcher = MonkeyPatcher()
-
-
- def test_empty(self):
- """
- A monkey patcher without patches shouldn't change a thing.
- """
- self.monkeyPatcher.patch()
-
- # We can't assert that all state is unchanged, but at least we can
- # check our test object.
- self.assertEqual(self.originalObject.foo, self.testObject.foo)
- self.assertEqual(self.originalObject.bar, self.testObject.bar)
- self.assertEqual(self.originalObject.baz, self.testObject.baz)
-
-
- def test_constructWithPatches(self):
- """
- Constructing a L{MonkeyPatcher} with patches should add all of the
- given patches to the patch list.
- """
- patcher = MonkeyPatcher((self.testObject, 'foo', 'haha'),
- (self.testObject, 'bar', 'hehe'))
- patcher.patch()
- self.assertEqual('haha', self.testObject.foo)
- self.assertEqual('hehe', self.testObject.bar)
- self.assertEqual(self.originalObject.baz, self.testObject.baz)
-
-
- def test_patchExisting(self):
- """
- Patching an attribute that exists sets it to the value defined in the
- patch.
- """
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
- self.monkeyPatcher.patch()
- self.assertEqual(self.testObject.foo, 'haha')
-
-
- def test_patchNonExisting(self):
- """
- Patching a non-existing attribute fails with an C{AttributeError}.
- """
- self.monkeyPatcher.addPatch(self.testObject, 'nowhere',
- 'blow up please')
- self.assertRaises(AttributeError, self.monkeyPatcher.patch)
-
-
- def test_patchAlreadyPatched(self):
- """
- Adding a patch for an object and attribute that already have a patch
- overrides the existing patch.
- """
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'blah')
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'BLAH')
- self.monkeyPatcher.patch()
- self.assertEqual(self.testObject.foo, 'BLAH')
- self.monkeyPatcher.restore()
- self.assertEqual(self.testObject.foo, self.originalObject.foo)
-
-
- def test_restoreTwiceIsANoOp(self):
- """
- Restoring an already-restored monkey patch is a no-op.
- """
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'blah')
- self.monkeyPatcher.patch()
- self.monkeyPatcher.restore()
- self.assertEqual(self.testObject.foo, self.originalObject.foo)
- self.monkeyPatcher.restore()
- self.assertEqual(self.testObject.foo, self.originalObject.foo)
-
-
- def test_runWithPatchesDecoration(self):
- """
- runWithPatches should run the given callable, passing in all arguments
- and keyword arguments, and return the return value of the callable.
- """
- log = []
-
- def f(a, b, c=None):
- log.append((a, b, c))
- return 'foo'
-
- result = self.monkeyPatcher.runWithPatches(f, 1, 2, c=10)
- self.assertEqual('foo', result)
- self.assertEqual([(1, 2, 10)], log)
-
-
- def test_repeatedRunWithPatches(self):
- """
- We should be able to call the same function with runWithPatches more
- than once. All patches should apply for each call.
- """
- def f():
- return (self.testObject.foo, self.testObject.bar,
- self.testObject.baz)
-
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
- result = self.monkeyPatcher.runWithPatches(f)
- self.assertEqual(
- ('haha', self.originalObject.bar, self.originalObject.baz), result)
- result = self.monkeyPatcher.runWithPatches(f)
- self.assertEqual(
- ('haha', self.originalObject.bar, self.originalObject.baz),
- result)
-
-
- def test_runWithPatchesRestores(self):
- """
- C{runWithPatches} should restore the original values after the function
- has executed.
- """
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
- self.assertEqual(self.originalObject.foo, self.testObject.foo)
- self.monkeyPatcher.runWithPatches(lambda: None)
- self.assertEqual(self.originalObject.foo, self.testObject.foo)
-
-
- def test_runWithPatchesRestoresOnException(self):
- """
- Test runWithPatches restores the original values even when the function
- raises an exception.
- """
- def _():
- self.assertEqual(self.testObject.foo, 'haha')
- self.assertEqual(self.testObject.bar, 'blahblah')
- raise RuntimeError("Something went wrong!")
-
- self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
- self.monkeyPatcher.addPatch(self.testObject, 'bar', 'blahblah')
-
- self.assertRaises(RuntimeError, self.monkeyPatcher.runWithPatches, _)
- self.assertEqual(self.testObject.foo, self.originalObject.foo)
- self.assertEqual(self.testObject.bar, self.originalObject.bar)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_newcred.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_newcred.py
deleted file mode 100755
index 01660cdc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_newcred.py
+++ /dev/null
@@ -1,445 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.cred}, now with 30% more starch.
-"""
-
-
-import hmac
-from zope.interface import implements, Interface
-
-from twisted.trial import unittest
-from twisted.cred import portal, checkers, credentials, error
-from twisted.python import components
-from twisted.internet import defer
-from twisted.internet.defer import deferredGenerator as dG, waitForDeferred as wFD
-
-try:
- from crypt import crypt
-except ImportError:
- crypt = None
-
-try:
- from twisted.cred.pamauth import callIntoPAM
-except ImportError:
- pamauth = None
-else:
- from twisted.cred import pamauth
-
-
-class ITestable(Interface):
- pass
-
-class TestAvatar:
- def __init__(self, name):
- self.name = name
- self.loggedIn = False
- self.loggedOut = False
-
- def login(self):
- assert not self.loggedIn
- self.loggedIn = True
-
- def logout(self):
- self.loggedOut = True
-
-class Testable(components.Adapter):
- implements(ITestable)
-
-# components.Interface(TestAvatar).adaptWith(Testable, ITestable)
-
-components.registerAdapter(Testable, TestAvatar, ITestable)
-
-class IDerivedCredentials(credentials.IUsernamePassword):
- pass
-
-class DerivedCredentials(object):
- implements(IDerivedCredentials, ITestable)
-
- def __init__(self, username, password):
- self.username = username
- self.password = password
-
- def checkPassword(self, password):
- return password == self.password
-
-
-class TestRealm:
- implements(portal.IRealm)
- def __init__(self):
- self.avatars = {}
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if avatarId in self.avatars:
- avatar = self.avatars[avatarId]
- else:
- avatar = TestAvatar(avatarId)
- self.avatars[avatarId] = avatar
- avatar.login()
- return (interfaces[0], interfaces[0](avatar),
- avatar.logout)
-
-class NewCredTest(unittest.TestCase):
- def setUp(self):
- r = self.realm = TestRealm()
- p = self.portal = portal.Portal(r)
- up = self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- up.addUser("bob", "hello")
- p.registerChecker(up)
-
- def testListCheckers(self):
- expected = [credentials.IUsernamePassword, credentials.IUsernameHashedPassword]
- got = self.portal.listCredentialsInterfaces()
- expected.sort()
- got.sort()
- self.assertEqual(got, expected)
-
- def testBasicLogin(self):
- l = []; f = []
- self.portal.login(credentials.UsernamePassword("bob", "hello"),
- self, ITestable).addCallback(
- l.append).addErrback(f.append)
- if f:
- raise f[0]
- # print l[0].getBriefTraceback()
- iface, impl, logout = l[0]
- # whitebox
- self.assertEqual(iface, ITestable)
- self.failUnless(iface.providedBy(impl),
- "%s does not implement %s" % (impl, iface))
- # greybox
- self.failUnless(impl.original.loggedIn)
- self.failUnless(not impl.original.loggedOut)
- logout()
- self.failUnless(impl.original.loggedOut)
-
- def test_derivedInterface(self):
- """
- Login with credentials implementing an interface inheriting from an
- interface registered with a checker (but not itself registered).
- """
- l = []
- f = []
- self.portal.login(DerivedCredentials("bob", "hello"), self, ITestable
- ).addCallback(l.append
- ).addErrback(f.append)
- if f:
- raise f[0]
- iface, impl, logout = l[0]
- # whitebox
- self.assertEqual(iface, ITestable)
- self.failUnless(iface.providedBy(impl),
- "%s does not implement %s" % (impl, iface))
- # greybox
- self.failUnless(impl.original.loggedIn)
- self.failUnless(not impl.original.loggedOut)
- logout()
- self.failUnless(impl.original.loggedOut)
-
- def testFailedLogin(self):
- l = []
- self.portal.login(credentials.UsernamePassword("bob", "h3llo"),
- self, ITestable).addErrback(
- lambda x: x.trap(error.UnauthorizedLogin)).addCallback(l.append)
- self.failUnless(l)
- self.assertEqual(error.UnauthorizedLogin, l[0])
-
- def testFailedLoginName(self):
- l = []
- self.portal.login(credentials.UsernamePassword("jay", "hello"),
- self, ITestable).addErrback(
- lambda x: x.trap(error.UnauthorizedLogin)).addCallback(l.append)
- self.failUnless(l)
- self.assertEqual(error.UnauthorizedLogin, l[0])
-
-
-class CramMD5CredentialsTestCase(unittest.TestCase):
- def testIdempotentChallenge(self):
- c = credentials.CramMD5Credentials()
- chal = c.getChallenge()
- self.assertEqual(chal, c.getChallenge())
-
- def testCheckPassword(self):
- c = credentials.CramMD5Credentials()
- chal = c.getChallenge()
- c.response = hmac.HMAC('secret', chal).hexdigest()
- self.failUnless(c.checkPassword('secret'))
-
- def testWrongPassword(self):
- c = credentials.CramMD5Credentials()
- self.failIf(c.checkPassword('secret'))
-
-class OnDiskDatabaseTestCase(unittest.TestCase):
- users = [
- ('user1', 'pass1'),
- ('user2', 'pass2'),
- ('user3', 'pass3'),
- ]
-
-
- def testUserLookup(self):
- dbfile = self.mktemp()
- db = checkers.FilePasswordDB(dbfile)
- f = file(dbfile, 'w')
- for (u, p) in self.users:
- f.write('%s:%s\n' % (u, p))
- f.close()
-
- for (u, p) in self.users:
- self.failUnlessRaises(KeyError, db.getUser, u.upper())
- self.assertEqual(db.getUser(u), (u, p))
-
- def testCaseInSensitivity(self):
- dbfile = self.mktemp()
- db = checkers.FilePasswordDB(dbfile, caseSensitive=0)
- f = file(dbfile, 'w')
- for (u, p) in self.users:
- f.write('%s:%s\n' % (u, p))
- f.close()
-
- for (u, p) in self.users:
- self.assertEqual(db.getUser(u.upper()), (u, p))
-
- def testRequestAvatarId(self):
- dbfile = self.mktemp()
- db = checkers.FilePasswordDB(dbfile, caseSensitive=0)
- f = file(dbfile, 'w')
- for (u, p) in self.users:
- f.write('%s:%s\n' % (u, p))
- f.close()
- creds = [credentials.UsernamePassword(u, p) for u, p in self.users]
- d = defer.gatherResults(
- [defer.maybeDeferred(db.requestAvatarId, c) for c in creds])
- d.addCallback(self.assertEqual, [u for u, p in self.users])
- return d
-
- def testRequestAvatarId_hashed(self):
- dbfile = self.mktemp()
- db = checkers.FilePasswordDB(dbfile, caseSensitive=0)
- f = file(dbfile, 'w')
- for (u, p) in self.users:
- f.write('%s:%s\n' % (u, p))
- f.close()
- creds = [credentials.UsernameHashedPassword(u, p) for u, p in self.users]
- d = defer.gatherResults(
- [defer.maybeDeferred(db.requestAvatarId, c) for c in creds])
- d.addCallback(self.assertEqual, [u for u, p in self.users])
- return d
-
-
-
-class HashedPasswordOnDiskDatabaseTestCase(unittest.TestCase):
- users = [
- ('user1', 'pass1'),
- ('user2', 'pass2'),
- ('user3', 'pass3'),
- ]
-
-
- def hash(self, u, p, s):
- return crypt(p, s)
-
- def setUp(self):
- dbfile = self.mktemp()
- self.db = checkers.FilePasswordDB(dbfile, hash=self.hash)
- f = file(dbfile, 'w')
- for (u, p) in self.users:
- f.write('%s:%s\n' % (u, crypt(p, u[:2])))
- f.close()
- r = TestRealm()
- self.port = portal.Portal(r)
- self.port.registerChecker(self.db)
-
- def testGoodCredentials(self):
- goodCreds = [credentials.UsernamePassword(u, p) for u, p in self.users]
- d = defer.gatherResults([self.db.requestAvatarId(c) for c in goodCreds])
- d.addCallback(self.assertEqual, [u for u, p in self.users])
- return d
-
- def testGoodCredentials_login(self):
- goodCreds = [credentials.UsernamePassword(u, p) for u, p in self.users]
- d = defer.gatherResults([self.port.login(c, None, ITestable)
- for c in goodCreds])
- d.addCallback(lambda x: [a.original.name for i, a, l in x])
- d.addCallback(self.assertEqual, [u for u, p in self.users])
- return d
-
- def testBadCredentials(self):
- badCreds = [credentials.UsernamePassword(u, 'wrong password')
- for u, p in self.users]
- d = defer.DeferredList([self.port.login(c, None, ITestable)
- for c in badCreds], consumeErrors=True)
- d.addCallback(self._assertFailures, error.UnauthorizedLogin)
- return d
-
- def testHashedCredentials(self):
- hashedCreds = [credentials.UsernameHashedPassword(u, crypt(p, u[:2]))
- for u, p in self.users]
- d = defer.DeferredList([self.port.login(c, None, ITestable)
- for c in hashedCreds], consumeErrors=True)
- d.addCallback(self._assertFailures, error.UnhandledCredentials)
- return d
-
- def _assertFailures(self, failures, *expectedFailures):
- for flag, failure in failures:
- self.assertEqual(flag, defer.FAILURE)
- failure.trap(*expectedFailures)
- return None
-
- if crypt is None:
- skip = "crypt module not available"
-
-class PluggableAuthenticationModulesTest(unittest.TestCase):
-
- def setUp(self):
- """
- Replace L{pamauth.callIntoPAM} with a dummy implementation with
- easily-controlled behavior.
- """
- self._oldCallIntoPAM = pamauth.callIntoPAM
- pamauth.callIntoPAM = self.callIntoPAM
-
-
- def tearDown(self):
- """
- Restore the original value of L{pamauth.callIntoPAM}.
- """
- pamauth.callIntoPAM = self._oldCallIntoPAM
-
-
- def callIntoPAM(self, service, user, conv):
- if service != 'Twisted':
- raise error.UnauthorizedLogin('bad service: %s' % service)
- if user != 'testuser':
- raise error.UnauthorizedLogin('bad username: %s' % user)
- questions = [
- (1, "Password"),
- (2, "Message w/ Input"),
- (3, "Message w/o Input"),
- ]
- replies = conv(questions)
- if replies != [
- ("password", 0),
- ("entry", 0),
- ("", 0)
- ]:
- raise error.UnauthorizedLogin('bad conversion: %s' % repr(replies))
- return 1
-
- def _makeConv(self, d):
- def conv(questions):
- return defer.succeed([(d[t], 0) for t, q in questions])
- return conv
-
- def testRequestAvatarId(self):
- db = checkers.PluggableAuthenticationModulesChecker()
- conv = self._makeConv({1:'password', 2:'entry', 3:''})
- creds = credentials.PluggableAuthenticationModules('testuser',
- conv)
- d = db.requestAvatarId(creds)
- d.addCallback(self.assertEqual, 'testuser')
- return d
-
- def testBadCredentials(self):
- db = checkers.PluggableAuthenticationModulesChecker()
- conv = self._makeConv({1:'', 2:'', 3:''})
- creds = credentials.PluggableAuthenticationModules('testuser',
- conv)
- d = db.requestAvatarId(creds)
- self.assertFailure(d, error.UnauthorizedLogin)
- return d
-
- def testBadUsername(self):
- db = checkers.PluggableAuthenticationModulesChecker()
- conv = self._makeConv({1:'password', 2:'entry', 3:''})
- creds = credentials.PluggableAuthenticationModules('baduser',
- conv)
- d = db.requestAvatarId(creds)
- self.assertFailure(d, error.UnauthorizedLogin)
- return d
-
- if not pamauth:
- skip = "Can't run without PyPAM"
-
-class CheckersMixin:
- def testPositive(self):
- for chk in self.getCheckers():
- for (cred, avatarId) in self.getGoodCredentials():
- r = wFD(chk.requestAvatarId(cred))
- yield r
- self.assertEqual(r.getResult(), avatarId)
- testPositive = dG(testPositive)
-
- def testNegative(self):
- for chk in self.getCheckers():
- for cred in self.getBadCredentials():
- r = wFD(chk.requestAvatarId(cred))
- yield r
- self.assertRaises(error.UnauthorizedLogin, r.getResult)
- testNegative = dG(testNegative)
-
-class HashlessFilePasswordDBMixin:
- credClass = credentials.UsernamePassword
- diskHash = None
- networkHash = staticmethod(lambda x: x)
-
- _validCredentials = [
- ('user1', 'password1'),
- ('user2', 'password2'),
- ('user3', 'password3')]
-
- def getGoodCredentials(self):
- for u, p in self._validCredentials:
- yield self.credClass(u, self.networkHash(p)), u
-
- def getBadCredentials(self):
- for u, p in [('user1', 'password3'),
- ('user2', 'password1'),
- ('bloof', 'blarf')]:
- yield self.credClass(u, self.networkHash(p))
-
- def getCheckers(self):
- diskHash = self.diskHash or (lambda x: x)
- hashCheck = self.diskHash and (lambda username, password, stored: self.diskHash(password))
-
- for cache in True, False:
- fn = self.mktemp()
- fObj = file(fn, 'w')
- for u, p in self._validCredentials:
- fObj.write('%s:%s\n' % (u, diskHash(p)))
- fObj.close()
- yield checkers.FilePasswordDB(fn, cache=cache, hash=hashCheck)
-
- fn = self.mktemp()
- fObj = file(fn, 'w')
- for u, p in self._validCredentials:
- fObj.write('%s dingle dongle %s\n' % (diskHash(p), u))
- fObj.close()
- yield checkers.FilePasswordDB(fn, ' ', 3, 0, cache=cache, hash=hashCheck)
-
- fn = self.mktemp()
- fObj = file(fn, 'w')
- for u, p in self._validCredentials:
- fObj.write('zip,zap,%s,zup,%s\n' % (u.title(), diskHash(p)))
- fObj.close()
- yield checkers.FilePasswordDB(fn, ',', 2, 4, False, cache=cache, hash=hashCheck)
-
-class LocallyHashedFilePasswordDBMixin(HashlessFilePasswordDBMixin):
- diskHash = staticmethod(lambda x: x.encode('hex'))
-
-class NetworkHashedFilePasswordDBMixin(HashlessFilePasswordDBMixin):
- networkHash = staticmethod(lambda x: x.encode('hex'))
- class credClass(credentials.UsernameHashedPassword):
- def checkPassword(self, password):
- return self.hashed.decode('hex') == password
-
-class HashlessFilePasswordDBCheckerTestCase(HashlessFilePasswordDBMixin, CheckersMixin, unittest.TestCase):
- pass
-
-class LocallyHashedFilePasswordDBCheckerTestCase(LocallyHashedFilePasswordDBMixin, CheckersMixin, unittest.TestCase):
- pass
-
-class NetworkHashedFilePasswordDBCheckerTestCase(NetworkHashedFilePasswordDBMixin, CheckersMixin, unittest.TestCase):
- pass
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_nmea.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_nmea.py
deleted file mode 100755
index 9c4afbc9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_nmea.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Test cases for the NMEA GPS protocol"""
-
-import StringIO
-
-from twisted.trial import unittest
-from twisted.internet import reactor, protocol
-from twisted.python import reflect
-
-from twisted.protocols.gps import nmea
-
-class StringIOWithNoClose(StringIO.StringIO):
- def close(self):
- pass
-
-class ResultHarvester:
- def __init__(self):
- self.results = []
-
- def __call__(self, *args):
- self.results.append(args)
-
- def performTest(self, function, *args, **kwargs):
- l = len(self.results)
- try:
- function(*args, **kwargs)
- except Exception, e:
- self.results.append(e)
- if l == len(self.results):
- self.results.append(NotImplementedError())
-
-class NMEATester(nmea.NMEAReceiver):
- ignore_invalid_sentence = 0
- ignore_checksum_mismatch = 0
- ignore_unknown_sentencetypes = 0
- convert_dates_before_y2k = 1
-
- def connectionMade(self):
- self.resultHarvester = ResultHarvester()
- for fn in reflect.prefixedMethodNames(self.__class__, 'decode_'):
- setattr(self, 'handle_' + fn, self.resultHarvester)
-
-class NMEAReceiverTestCase(unittest.TestCase):
- messages = (
- # fix - signal acquired
- "$GPGGA,231713.0,3910.413,N,07641.994,W,1,05,1.35,00044,M,-033,M,,*69",
- # fix - signal not acquired
- "$GPGGA,235947.000,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,,,,0000*00",
- # junk
- "lkjasdfkl!@#(*$!@(*#(ASDkfjasdfLMASDCVKAW!@#($)!(@#)(*",
- # fix - signal acquired (invalid checksum)
- "$GPGGA,231713.0,3910.413,N,07641.994,W,1,05,1.35,00044,M,-033,M,,*68",
- # invalid sentence
- "$GPGGX,231713.0,3910.413,N,07641.994,W,1,05,1.35,00044,M,-033,M,,*68",
- # position acquired
- "$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D",
- # position not acquired
- "$GPGLL,0000.0000,N,00000.0000,E,235947.000,V*2D",
- # active satellites (no fix)
- "$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30",
- # active satellites
- "$GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A",
- # positiontime (no fix)
- "$GPRMC,235947.000,V,0000.0000,N,00000.0000,E,,,041299,,*1D",
- # positiontime
- "$GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25",
- # course over ground (no fix - not implemented)
- "$GPVTG,,T,,M,,N,,K*4E",
- # course over ground (not implemented)
- "$GPVTG,89.68,T,,M,0.00,N,0.0,K*5F",
- )
- results = (
- (83833.0, 39.17355, -76.6999, nmea.POSFIX_SPS, 5, 1.35, (44.0, 'M'), (-33.0, 'M'), None),
- (86387.0, 0.0, 0.0, 0, 0, 0.0, (0.0, 'M'), None, None),
- nmea.InvalidSentence(),
- nmea.InvalidChecksum(),
- nmea.InvalidSentence(),
- (-42.842648333333337, 147.30847333333332, 33724.999000000003, 1),
- (0.0, 0.0, 86387.0, 0),
- ((None, None, None, None, None, None, None, None, None, None, None, None), (nmea.MODE_AUTO, nmea.MODE_NOFIX), 0.0, 0.0, 0.0),
- ((1, 20, 19, 13, None, None, None, None, None, None, None, None), (nmea.MODE_AUTO, nmea.MODE_3D), 40.4, 24.4, 32.2),
- (0.0, 0.0, None, None, 86387.0, (1999, 12, 4), None),
- (-42.842648333333337, 147.30847333333332, 0.0, 89.68, 33724.999, (2000, 12, 21), None),
- NotImplementedError(),
- NotImplementedError(),
- )
- def testGPSMessages(self):
- dummy = NMEATester()
- dummy.makeConnection(protocol.FileWrapper(StringIOWithNoClose()))
- for line in self.messages:
- dummy.resultHarvester.performTest(dummy.lineReceived, line)
- def munge(myTuple):
- if type(myTuple) != type(()):
- return
- newTuple = []
- for v in myTuple:
- if type(v) == type(1.1):
- v = float(int(v * 10000.0)) * 0.0001
- newTuple.append(v)
- return tuple(newTuple)
- for (message, expectedResult, actualResult) in zip(self.messages, self.results, dummy.resultHarvester.results):
- expectedResult = munge(expectedResult)
- actualResult = munge(actualResult)
- if isinstance(expectedResult, Exception):
- if isinstance(actualResult, Exception):
- self.assertEqual(expectedResult.__class__, actualResult.__class__, "\nInput:\n%s\nExpected:\n%s.%s\nResults:\n%s.%s\n" % (message, expectedResult.__class__.__module__, expectedResult.__class__.__name__, actualResult.__class__.__module__, actualResult.__class__.__name__))
- else:
- self.assertEqual(1, 0, "\nInput:\n%s\nExpected:\n%s.%s\nResults:\n%r\n" % (message, expectedResult.__class__.__module__, expectedResult.__class__.__name__, actualResult))
- else:
- self.assertEqual(expectedResult, actualResult, "\nInput:\n%s\nExpected: %r\nResults: %r\n" % (message, expectedResult, actualResult))
-
-testCases = [NMEAReceiverTestCase]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_paths.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_paths.py
deleted file mode 100755
index f2761df7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_paths.py
+++ /dev/null
@@ -1,1622 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases covering L{twisted.python.filepath} and L{twisted.python.zippath}.
-"""
-
-import os, time, pickle, errno, zipfile, stat
-
-from twisted.python.compat import set
-from twisted.python.win32 import WindowsError, ERROR_DIRECTORY
-from twisted.python import filepath
-from twisted.python.zippath import ZipArchive
-from twisted.python.runtime import platform
-
-from twisted.trial import unittest
-
-from zope.interface.verify import verifyObject
-
-
-class AbstractFilePathTestCase(unittest.TestCase):
-
- f1content = "file 1"
- f2content = "file 2"
-
-
- def _mkpath(self, *p):
- x = os.path.abspath(os.path.join(self.cmn, *p))
- self.all.append(x)
- return x
-
-
- def subdir(self, *dirname):
- os.mkdir(self._mkpath(*dirname))
-
-
- def subfile(self, *dirname):
- return open(self._mkpath(*dirname), "wb")
-
-
- def setUp(self):
- self.now = time.time()
- cmn = self.cmn = os.path.abspath(self.mktemp())
- self.all = [cmn]
- os.mkdir(cmn)
- self.subdir("sub1")
- f = self.subfile("file1")
- f.write(self.f1content)
- f.close()
- f = self.subfile("sub1", "file2")
- f.write(self.f2content)
- f.close()
- self.subdir('sub3')
- f = self.subfile("sub3", "file3.ext1")
- f.close()
- f = self.subfile("sub3", "file3.ext2")
- f.close()
- f = self.subfile("sub3", "file3.ext3")
- f.close()
- self.path = filepath.FilePath(cmn)
- self.root = filepath.FilePath("/")
-
-
- def test_segmentsFromPositive(self):
- """
- Verify that the segments between two paths are correctly identified.
- """
- self.assertEqual(
- self.path.child("a").child("b").child("c").segmentsFrom(self.path),
- ["a", "b", "c"])
-
- def test_segmentsFromNegative(self):
- """
- Verify that segmentsFrom notices when the ancestor isn't an ancestor.
- """
- self.assertRaises(
- ValueError,
- self.path.child("a").child("b").child("c").segmentsFrom,
- self.path.child("d").child("c").child("e"))
-
-
- def test_walk(self):
- """
- Verify that walking the path gives the same result as the known file
- hierarchy.
- """
- x = [foo.path for foo in self.path.walk()]
- self.assertEqual(set(x), set(self.all))
-
-
- def test_parents(self):
- """
- L{FilePath.parents()} should return an iterator of every ancestor of
- the L{FilePath} in question.
- """
- L = []
- pathobj = self.path.child("a").child("b").child("c")
- fullpath = pathobj.path
- lastpath = fullpath
- thispath = os.path.dirname(fullpath)
- while lastpath != self.root.path:
- L.append(thispath)
- lastpath = thispath
- thispath = os.path.dirname(thispath)
- self.assertEqual([x.path for x in pathobj.parents()], L)
-
-
- def test_validSubdir(self):
- """
- Verify that a valid subdirectory will show up as a directory, but not as a
- file, not as a symlink, and be listable.
- """
- sub1 = self.path.child('sub1')
- self.failUnless(sub1.exists(),
- "This directory does exist.")
- self.failUnless(sub1.isdir(),
- "It's a directory.")
- self.failUnless(not sub1.isfile(),
- "It's a directory.")
- self.failUnless(not sub1.islink(),
- "It's a directory.")
- self.assertEqual(sub1.listdir(),
- ['file2'])
-
-
- def test_invalidSubdir(self):
- """
- Verify that a subdirectory that doesn't exist is reported as such.
- """
- sub2 = self.path.child('sub2')
- self.failIf(sub2.exists(),
- "This directory does not exist.")
-
- def test_validFiles(self):
- """
- Make sure that we can read existent non-empty files.
- """
- f1 = self.path.child('file1')
- self.assertEqual(f1.open().read(), self.f1content)
- f2 = self.path.child('sub1').child('file2')
- self.assertEqual(f2.open().read(), self.f2content)
-
-
- def test_multipleChildSegments(self):
- """
- C{fp.descendant([a, b, c])} returns the same L{FilePath} as is returned
- by C{fp.child(a).child(b).child(c)}.
- """
- multiple = self.path.descendant(['a', 'b', 'c'])
- single = self.path.child('a').child('b').child('c')
- self.assertEqual(multiple, single)
-
-
- def test_dictionaryKeys(self):
- """
- Verify that path instances are usable as dictionary keys.
- """
- f1 = self.path.child('file1')
- f1prime = self.path.child('file1')
- f2 = self.path.child('file2')
- dictoid = {}
- dictoid[f1] = 3
- dictoid[f1prime] = 4
- self.assertEqual(dictoid[f1], 4)
- self.assertEqual(dictoid.keys(), [f1])
- self.assertIdentical(dictoid.keys()[0], f1)
- self.assertNotIdentical(dictoid.keys()[0], f1prime) # sanity check
- dictoid[f2] = 5
- self.assertEqual(dictoid[f2], 5)
- self.assertEqual(len(dictoid), 2)
-
-
- def test_dictionaryKeyWithString(self):
- """
- Verify that path instances are usable as dictionary keys which do not clash
- with their string counterparts.
- """
- f1 = self.path.child('file1')
- dictoid = {f1: 'hello'}
- dictoid[f1.path] = 'goodbye'
- self.assertEqual(len(dictoid), 2)
-
-
- def test_childrenNonexistentError(self):
- """
- Verify that children raises the appropriate exception for non-existent
- directories.
- """
- self.assertRaises(filepath.UnlistableError,
- self.path.child('not real').children)
-
- def test_childrenNotDirectoryError(self):
- """
- Verify that listdir raises the appropriate exception for attempting to list
- a file rather than a directory.
- """
- self.assertRaises(filepath.UnlistableError,
- self.path.child('file1').children)
-
-
- def test_newTimesAreFloats(self):
- """
- Verify that all times returned from the various new time functions are ints
- (and hopefully therefore 'high precision').
- """
- for p in self.path, self.path.child('file1'):
- self.assertEqual(type(p.getAccessTime()), float)
- self.assertEqual(type(p.getModificationTime()), float)
- self.assertEqual(type(p.getStatusChangeTime()), float)
-
-
- def test_oldTimesAreInts(self):
- """
- Verify that all times returned from the various time functions are
- integers, for compatibility.
- """
- for p in self.path, self.path.child('file1'):
- self.assertEqual(type(p.getatime()), int)
- self.assertEqual(type(p.getmtime()), int)
- self.assertEqual(type(p.getctime()), int)
-
-
-
-class FakeWindowsPath(filepath.FilePath):
- """
- A test version of FilePath which overrides listdir to raise L{WindowsError}.
- """
-
- def listdir(self):
- """
- @raise WindowsError: always.
- """
- raise WindowsError(
- ERROR_DIRECTORY,
- "A directory's validness was called into question")
-
-
-class ListingCompatibilityTests(unittest.TestCase):
- """
- These tests verify compatibility with legacy behavior of directory listing.
- """
-
- def test_windowsErrorExcept(self):
- """
- Verify that when a WindowsError is raised from listdir, catching
- WindowsError works.
- """
- fwp = FakeWindowsPath(self.mktemp())
- self.assertRaises(filepath.UnlistableError, fwp.children)
- self.assertRaises(WindowsError, fwp.children)
-
-
- def test_alwaysCatchOSError(self):
- """
- Verify that in the normal case where a directory does not exist, we will
- get an OSError.
- """
- fp = filepath.FilePath(self.mktemp())
- self.assertRaises(OSError, fp.children)
-
-
- def test_keepOriginalAttributes(self):
- """
- Verify that the Unlistable exception raised will preserve the attributes of
- the previously-raised exception.
- """
- fp = filepath.FilePath(self.mktemp())
- ose = self.assertRaises(OSError, fp.children)
- d1 = ose.__dict__.keys()
- d1.remove('originalException')
- d2 = ose.originalException.__dict__.keys()
- d1.sort()
- d2.sort()
- self.assertEqual(d1, d2)
-
-
-
-def zipit(dirname, zfname):
- """
- Create a zipfile on zfname, containing the contents of dirname'
- """
- zf = zipfile.ZipFile(zfname, "w")
- for root, ignored, files, in os.walk(dirname):
- for fname in files:
- fspath = os.path.join(root, fname)
- arcpath = os.path.join(root, fname)[len(dirname)+1:]
- # print fspath, '=>', arcpath
- zf.write(fspath, arcpath)
- zf.close()
-
-
-
-class ZipFilePathTestCase(AbstractFilePathTestCase):
- """
- Test various L{ZipPath} path manipulations as well as reprs for L{ZipPath}
- and L{ZipArchive}.
- """
- def setUp(self):
- AbstractFilePathTestCase.setUp(self)
- zipit(self.cmn, self.cmn + '.zip')
- self.path = ZipArchive(self.cmn + '.zip')
- self.root = self.path
- self.all = [x.replace(self.cmn, self.cmn + '.zip') for x in self.all]
-
-
- def test_verifyObject(self):
- """
- ZipPaths implement IFilePath.
- """
-
- self.assertTrue(verifyObject(filepath.IFilePath, self.path))
-
-
- def test_zipPathRepr(self):
- """
- Make sure that invoking ZipPath's repr prints the correct class name
- and an absolute path to the zip file.
- """
- child = self.path.child("foo")
- pathRepr = "ZipPath(%r)" % (
- os.path.abspath(self.cmn + ".zip" + os.sep + 'foo'),)
-
- # Check for an absolute path
- self.assertEqual(repr(child), pathRepr)
-
- # Create a path to the file rooted in the current working directory
- relativeCommon = self.cmn.replace(os.getcwd() + os.sep, "", 1) + ".zip"
- relpath = ZipArchive(relativeCommon)
- child = relpath.child("foo")
-
- # Check using a path without the cwd prepended
- self.assertEqual(repr(child), pathRepr)
-
-
- def test_zipPathReprParentDirSegment(self):
- """
- The repr of a ZipPath with C{".."} in the internal part of its path
- includes the C{".."} rather than applying the usual parent directory
- meaning.
- """
- child = self.path.child("foo").child("..").child("bar")
- pathRepr = "ZipPath(%r)" % (
- self.cmn + ".zip" + os.sep.join(["", "foo", "..", "bar"]))
- self.assertEqual(repr(child), pathRepr)
-
-
- def test_zipPathReprEscaping(self):
- """
- Bytes in the ZipPath path which have special meaning in Python
- string literals are escaped in the ZipPath repr.
- """
- child = self.path.child("'")
- path = self.cmn + ".zip" + os.sep.join(["", "'"])
- pathRepr = "ZipPath('%s')" % (path.encode('string-escape'),)
- self.assertEqual(repr(child), pathRepr)
-
-
- def test_zipArchiveRepr(self):
- """
- Make sure that invoking ZipArchive's repr prints the correct class
- name and an absolute path to the zip file.
- """
- pathRepr = 'ZipArchive(%r)' % (os.path.abspath(self.cmn + '.zip'),)
-
- # Check for an absolute path
- self.assertEqual(repr(self.path), pathRepr)
-
- # Create a path to the file rooted in the current working directory
- relativeCommon = self.cmn.replace(os.getcwd() + os.sep, "", 1) + ".zip"
- relpath = ZipArchive(relativeCommon)
-
- # Check using a path without the cwd prepended
- self.assertEqual(repr(relpath), pathRepr)
-
-
-
-class ExplodingFile:
- """
- A C{file}-alike which raises exceptions from its I/O methods and keeps track
- of whether it has been closed.
-
- @ivar closed: A C{bool} which is C{False} until C{close} is called, then it
- is C{True}.
- """
- closed = False
-
- def read(self, n=0):
- """
- @raise IOError: Always raised.
- """
- raise IOError()
-
-
- def write(self, what):
- """
- @raise IOError: Always raised.
- """
- raise IOError()
-
-
- def close(self):
- """
- Mark the file as having been closed.
- """
- self.closed = True
-
-
-
-class TrackingFilePath(filepath.FilePath):
- """
- A subclass of L{filepath.FilePath} which maintains a list of all other paths
- created by clonePath.
-
- @ivar trackingList: A list of all paths created by this path via
- C{clonePath} (which also includes paths created by methods like
- C{parent}, C{sibling}, C{child}, etc (and all paths subsequently created
- by those paths, etc).
-
- @type trackingList: C{list} of L{TrackingFilePath}
-
- @ivar openedFiles: A list of all file objects opened by this
- L{TrackingFilePath} or any other L{TrackingFilePath} in C{trackingList}.
-
- @type openedFiles: C{list} of C{file}
- """
-
- def __init__(self, path, alwaysCreate=False, trackingList=None):
- filepath.FilePath.__init__(self, path, alwaysCreate)
- if trackingList is None:
- trackingList = []
- self.trackingList = trackingList
- self.openedFiles = []
-
-
- def open(self, *a, **k):
- """
- Override 'open' to track all files opened by this path.
- """
- f = filepath.FilePath.open(self, *a, **k)
- self.openedFiles.append(f)
- return f
-
-
- def openedPaths(self):
- """
- Return a list of all L{TrackingFilePath}s associated with this
- L{TrackingFilePath} that have had their C{open()} method called.
- """
- return [path for path in self.trackingList if path.openedFiles]
-
-
- def clonePath(self, name):
- """
- Override L{filepath.FilePath.clonePath} to give the new path a reference
- to the same tracking list.
- """
- clone = TrackingFilePath(name, trackingList=self.trackingList)
- self.trackingList.append(clone)
- return clone
-
-
-
-class ExplodingFilePath(filepath.FilePath):
- """
- A specialized L{FilePath} which always returns an instance of
- L{ExplodingFile} from its C{open} method.
-
- @ivar fp: The L{ExplodingFile} instance most recently returned from the
- C{open} method.
- """
-
- def __init__(self, pathName, originalExploder=None):
- """
- Initialize an L{ExplodingFilePath} with a name and a reference to the
-
- @param pathName: The path name as passed to L{filepath.FilePath}.
- @type pathName: C{str}
-
- @param originalExploder: The L{ExplodingFilePath} to associate opened
- files with.
- @type originalExploder: L{ExplodingFilePath}
- """
- filepath.FilePath.__init__(self, pathName)
- if originalExploder is None:
- originalExploder = self
- self._originalExploder = originalExploder
-
-
- def open(self, mode=None):
- """
- Create, save, and return a new C{ExplodingFile}.
-
- @param mode: Present for signature compatibility. Ignored.
-
- @return: A new C{ExplodingFile}.
- """
- f = self._originalExploder.fp = ExplodingFile()
- return f
-
-
- def clonePath(self, name):
- return ExplodingFilePath(name, self._originalExploder)
-
-
-
-class PermissionsTestCase(unittest.TestCase):
- """
- Test Permissions and RWX classes
- """
-
- def assertNotUnequal(self, first, second, msg=None):
- """
- Tests that C{first} != C{second} is false. This method tests the
- __ne__ method, as opposed to L{assertEqual} (C{first} == C{second}),
- which tests the __eq__ method.
-
- Note: this should really be part of trial
- """
- if first != second:
- if msg is None:
- msg = '';
- if len(msg) > 0:
- msg += '\n'
- raise self.failureException(
- '%snot not unequal (__ne__ not implemented correctly):'
- '\na = %s\nb = %s\n'
- % (msg, pformat(first), pformat(second)))
- return first
-
-
- def test_rwxFromBools(self):
- """
- L{RWX}'s constructor takes a set of booleans
- """
- for r in (True, False):
- for w in (True, False):
- for x in (True, False):
- rwx = filepath.RWX(r, w, x)
- self.assertEqual(rwx.read, r)
- self.assertEqual(rwx.write, w)
- self.assertEqual(rwx.execute, x)
- rwx = filepath.RWX(True, True, True)
- self.assertTrue(rwx.read and rwx.write and rwx.execute)
-
-
- def test_rwxEqNe(self):
- """
- L{RWX}'s created with the same booleans are equivalent. If booleans
- are different, they are not equal.
- """
- for r in (True, False):
- for w in (True, False):
- for x in (True, False):
- self.assertEqual(filepath.RWX(r, w, x),
- filepath.RWX(r, w, x))
- self.assertNotUnequal(filepath.RWX(r, w, x),
- filepath.RWX(r, w, x))
- self.assertNotEqual(filepath.RWX(True, True, True),
- filepath.RWX(True, True, False))
- self.assertNotEqual(3, filepath.RWX(True, True, True))
-
-
- def test_rwxShorthand(self):
- """
- L{RWX}'s shorthand string should be 'rwx' if read, write, and execute
- permission bits are true. If any of those permissions bits are false,
- the character is replaced by a '-'.
- """
-
- def getChar(val, letter):
- if val:
- return letter
- return '-'
-
- for r in (True, False):
- for w in (True, False):
- for x in (True, False):
- rwx = filepath.RWX(r, w, x)
- self.assertEqual(rwx.shorthand(),
- getChar(r, 'r') +
- getChar(w, 'w') +
- getChar(x, 'x'))
- self.assertEqual(filepath.RWX(True, False, True).shorthand(), "r-x")
-
-
- def test_permissionsFromStat(self):
- """
- L{Permissions}'s constructor takes a valid permissions bitmask and
- parsaes it to produce the correct set of boolean permissions.
- """
- def _rwxFromStat(statModeInt, who):
- def getPermissionBit(what, who):
- return (statModeInt &
- getattr(stat, "S_I%s%s" % (what, who))) > 0
- return filepath.RWX(*[getPermissionBit(what, who) for what in
- ('R', 'W', 'X')])
-
- for u in range(0, 8):
- for g in range(0, 8):
- for o in range(0, 8):
- chmodString = "%d%d%d" % (u, g, o)
- chmodVal = int(chmodString, 8)
- perm = filepath.Permissions(chmodVal)
- self.assertEqual(perm.user,
- _rwxFromStat(chmodVal, "USR"),
- "%s: got user: %s" %
- (chmodString, perm.user))
- self.assertEqual(perm.group,
- _rwxFromStat(chmodVal, "GRP"),
- "%s: got group: %s" %
- (chmodString, perm.group))
- self.assertEqual(perm.other,
- _rwxFromStat(chmodVal, "OTH"),
- "%s: got other: %s" %
- (chmodString, perm.other))
- perm = filepath.Permissions(0777)
- for who in ("user", "group", "other"):
- for what in ("read", "write", "execute"):
- self.assertTrue(getattr(getattr(perm, who), what))
-
-
- def test_permissionsEq(self):
- """
- Two L{Permissions}'s that are created with the same bitmask
- are equivalent
- """
- self.assertEqual(filepath.Permissions(0777),
- filepath.Permissions(0777))
- self.assertNotUnequal(filepath.Permissions(0777),
- filepath.Permissions(0777))
- self.assertNotEqual(filepath.Permissions(0777),
- filepath.Permissions(0700))
- self.assertNotEqual(3, filepath.Permissions(0777))
-
-
- def test_permissionsShorthand(self):
- """
- L{Permissions}'s shorthand string is the RWX shorthand string for its
- user permission bits, group permission bits, and other permission bits
- concatenated together, without a space.
- """
- for u in range(0, 8):
- for g in range(0, 8):
- for o in range(0, 8):
- perm = filepath.Permissions(eval("0%d%d%d" % (u, g, o)))
- self.assertEqual(perm.shorthand(),
- ''.join(x.shorthand() for x in (
- perm.user, perm.group, perm.other)))
- self.assertEqual(filepath.Permissions(0770).shorthand(), "rwxrwx---")
-
-
-
-class FilePathTestCase(AbstractFilePathTestCase):
- """
- Test various L{FilePath} path manipulations.
- """
-
-
- def test_verifyObject(self):
- """
- FilePaths implement IFilePath.
- """
-
- self.assertTrue(verifyObject(filepath.IFilePath, self.path))
-
-
- def test_chmod(self):
- """
- L{FilePath.chmod} modifies the permissions of
- the passed file as expected (using C{os.stat} to check). We use some
- basic modes that should work everywhere (even on Windows).
- """
- for mode in (0555, 0777):
- self.path.child("sub1").chmod(mode)
- self.assertEqual(
- stat.S_IMODE(os.stat(self.path.child("sub1").path).st_mode),
- mode)
-
-
- def symlink(self, target, name):
- """
- Create a symbolic link named C{name} pointing at C{target}.
-
- @type target: C{str}
- @type name: C{str}
- @raise SkipTest: raised if symbolic links are not supported on the
- host platform.
- """
- if getattr(os, 'symlink', None) is None:
- raise unittest.SkipTest(
- "Platform does not support symbolic links.")
- os.symlink(target, name)
-
-
- def createLinks(self):
- """
- Create several symbolic links to files and directories.
- """
- subdir = self.path.child("sub1")
- self.symlink(subdir.path, self._mkpath("sub1.link"))
- self.symlink(subdir.child("file2").path, self._mkpath("file2.link"))
- self.symlink(subdir.child("file2").path,
- self._mkpath("sub1", "sub1.file2.link"))
-
-
- def test_realpathSymlink(self):
- """
- L{FilePath.realpath} returns the path of the ultimate target of a
- symlink.
- """
- self.createLinks()
- self.symlink(self.path.child("file2.link").path,
- self.path.child("link.link").path)
- self.assertEqual(self.path.child("link.link").realpath(),
- self.path.child("sub1").child("file2"))
-
-
- def test_realpathCyclicalSymlink(self):
- """
- L{FilePath.realpath} raises L{filepath.LinkError} if the path is a
- symbolic link which is part of a cycle.
- """
- self.symlink(self.path.child("link1").path, self.path.child("link2").path)
- self.symlink(self.path.child("link2").path, self.path.child("link1").path)
- self.assertRaises(filepath.LinkError,
- self.path.child("link2").realpath)
-
-
- def test_realpathNoSymlink(self):
- """
- L{FilePath.realpath} returns the path itself if the path is not a
- symbolic link.
- """
- self.assertEqual(self.path.child("sub1").realpath(),
- self.path.child("sub1"))
-
-
- def test_walkCyclicalSymlink(self):
- """
- Verify that walking a path with a cyclical symlink raises an error
- """
- self.createLinks()
- self.symlink(self.path.child("sub1").path,
- self.path.child("sub1").child("sub1.loopylink").path)
- def iterateOverPath():
- return [foo.path for foo in self.path.walk()]
- self.assertRaises(filepath.LinkError, iterateOverPath)
-
-
- def test_walkObeysDescendWithCyclicalSymlinks(self):
- """
- Verify that, after making a path with cyclical symlinks, when the
- supplied C{descend} predicate returns C{False}, the target is not
- traversed, as if it was a simple symlink.
- """
- self.createLinks()
- # we create cyclical symlinks
- self.symlink(self.path.child("sub1").path,
- self.path.child("sub1").child("sub1.loopylink").path)
- def noSymLinks(path):
- return not path.islink()
- def iterateOverPath():
- return [foo.path for foo in self.path.walk(descend=noSymLinks)]
- self.assertTrue(iterateOverPath())
-
-
- def test_walkObeysDescend(self):
- """
- Verify that when the supplied C{descend} predicate returns C{False},
- the target is not traversed.
- """
- self.createLinks()
- def noSymLinks(path):
- return not path.islink()
- x = [foo.path for foo in self.path.walk(descend=noSymLinks)]
- self.assertEqual(set(x), set(self.all))
-
-
- def test_getAndSet(self):
- content = 'newcontent'
- self.path.child('new').setContent(content)
- newcontent = self.path.child('new').getContent()
- self.assertEqual(content, newcontent)
- content = 'content'
- self.path.child('new').setContent(content, '.tmp')
- newcontent = self.path.child('new').getContent()
- self.assertEqual(content, newcontent)
-
-
- def test_getContentFileClosing(self):
- """
- If reading from the underlying file raises an exception,
- L{FilePath.getContent} raises that exception after closing the file.
- """
- fp = ExplodingFilePath("")
- self.assertRaises(IOError, fp.getContent)
- self.assertTrue(fp.fp.closed)
-
-
- def test_setContentFileClosing(self):
- """
- If writing to the underlying file raises an exception,
- L{FilePath.setContent} raises that exception after closing the file.
- """
- fp = ExplodingFilePath("")
- self.assertRaises(IOError, fp.setContent, "blah")
- self.assertTrue(fp.fp.closed)
-
-
- def test_setContentNameCollision(self):
- """
- L{FilePath.setContent} will use a different temporary filename on each
- invocation, so that multiple processes, threads, or reentrant
- invocations will not collide with each other.
- """
- fp = TrackingFilePath(self.mktemp())
- fp.setContent("alpha")
- fp.setContent("beta")
-
- # Sanity check: setContent should only open one derivative path each
- # time to store the temporary file.
- openedSiblings = fp.openedPaths()
- self.assertEqual(len(openedSiblings), 2)
- self.assertNotEquals(openedSiblings[0], openedSiblings[1])
-
-
- def test_setContentExtension(self):
- """
- L{FilePath.setContent} creates temporary files with a user-supplied
- extension, so that if it is somehow interrupted while writing them, the
- file that it leaves behind will be identifiable.
- """
- fp = TrackingFilePath(self.mktemp())
- fp.setContent("hello")
- opened = fp.openedPaths()
- self.assertEqual(len(opened), 1)
- self.assertTrue(opened[0].basename().endswith(".new"),
- "%s does not end with default '.new' extension" % (
- opened[0].basename()))
- fp.setContent("goodbye", "-something-else")
- opened = fp.openedPaths()
- self.assertEqual(len(opened), 2)
- self.assertTrue(opened[1].basename().endswith("-something-else"),
- "%s does not end with -something-else extension" % (
- opened[1].basename()))
-
-
- def test_symbolicLink(self):
- """
- Verify the behavior of the C{isLink} method against links and
- non-links. Also check that the symbolic link shares the directory
- property with its target.
- """
- s4 = self.path.child("sub4")
- s3 = self.path.child("sub3")
- self.symlink(s3.path, s4.path)
- self.assertTrue(s4.islink())
- self.assertFalse(s3.islink())
- self.assertTrue(s4.isdir())
- self.assertTrue(s3.isdir())
-
-
- def test_linkTo(self):
- """
- Verify that symlink creates a valid symlink that is both a link and a
- file if its target is a file, or a directory if its target is a
- directory.
- """
- targetLinks = [
- (self.path.child("sub2"), self.path.child("sub2.link")),
- (self.path.child("sub2").child("file3.ext1"),
- self.path.child("file3.ext1.link"))
- ]
- for target, link in targetLinks:
- target.linkTo(link)
- self.assertTrue(link.islink(), "This is a link")
- self.assertEqual(target.isdir(), link.isdir())
- self.assertEqual(target.isfile(), link.isfile())
-
-
- def test_linkToErrors(self):
- """
- Verify C{linkTo} fails in the following case:
- - the target is in a directory that doesn't exist
- - the target already exists
- """
- self.assertRaises(OSError, self.path.child("file1").linkTo,
- self.path.child('nosub').child('file1'))
- self.assertRaises(OSError, self.path.child("file1").linkTo,
- self.path.child('sub1').child('file2'))
-
-
- if not getattr(os, "symlink", None):
- skipMsg = "Your platform does not support symbolic links."
- test_symbolicLink.skip = skipMsg
- test_linkTo.skip = skipMsg
- test_linkToErrors.skip = skipMsg
-
-
- def testMultiExt(self):
- f3 = self.path.child('sub3').child('file3')
- exts = '.foo','.bar', 'ext1','ext2','ext3'
- self.failIf(f3.siblingExtensionSearch(*exts))
- f3e = f3.siblingExtension(".foo")
- f3e.touch()
- self.failIf(not f3.siblingExtensionSearch(*exts).exists())
- self.failIf(not f3.siblingExtensionSearch('*').exists())
- f3e.remove()
- self.failIf(f3.siblingExtensionSearch(*exts))
-
- def testPreauthChild(self):
- fp = filepath.FilePath('.')
- fp.preauthChild('foo/bar')
- self.assertRaises(filepath.InsecurePath, fp.child, '/foo')
-
- def testStatCache(self):
- p = self.path.child('stattest')
- p.touch()
- self.assertEqual(p.getsize(), 0)
- self.assertEqual(abs(p.getmtime() - time.time()) // 20, 0)
- self.assertEqual(abs(p.getctime() - time.time()) // 20, 0)
- self.assertEqual(abs(p.getatime() - time.time()) // 20, 0)
- self.assertEqual(p.exists(), True)
- self.assertEqual(p.exists(), True)
- # OOB removal: FilePath.remove() will automatically restat
- os.remove(p.path)
- # test caching
- self.assertEqual(p.exists(), True)
- p.restat(reraise=False)
- self.assertEqual(p.exists(), False)
- self.assertEqual(p.islink(), False)
- self.assertEqual(p.isdir(), False)
- self.assertEqual(p.isfile(), False)
-
- def testPersist(self):
- newpath = pickle.loads(pickle.dumps(self.path))
- self.assertEqual(self.path.__class__, newpath.__class__)
- self.assertEqual(self.path.path, newpath.path)
-
- def testInsecureUNIX(self):
- self.assertRaises(filepath.InsecurePath, self.path.child, "..")
- self.assertRaises(filepath.InsecurePath, self.path.child, "/etc")
- self.assertRaises(filepath.InsecurePath, self.path.child, "../..")
-
- def testInsecureWin32(self):
- self.assertRaises(filepath.InsecurePath, self.path.child, r"..\..")
- self.assertRaises(filepath.InsecurePath, self.path.child, r"C:randomfile")
-
- if platform.getType() != 'win32':
- testInsecureWin32.skip = "Test will run only on Windows."
-
- def testInsecureWin32Whacky(self):
- """
- Windows has 'special' filenames like NUL and CON and COM1 and LPR
- and PRN and ... god knows what else. They can be located anywhere in
- the filesystem. For obvious reasons, we do not wish to normally permit
- access to these.
- """
- self.assertRaises(filepath.InsecurePath, self.path.child, "CON")
- self.assertRaises(filepath.InsecurePath, self.path.child, "C:CON")
- self.assertRaises(filepath.InsecurePath, self.path.child, r"C:\CON")
-
- if platform.getType() != 'win32':
- testInsecureWin32Whacky.skip = "Test will run only on Windows."
-
- def testComparison(self):
- self.assertEqual(filepath.FilePath('a'),
- filepath.FilePath('a'))
- self.failUnless(filepath.FilePath('z') >
- filepath.FilePath('a'))
- self.failUnless(filepath.FilePath('z') >=
- filepath.FilePath('a'))
- self.failUnless(filepath.FilePath('a') >=
- filepath.FilePath('a'))
- self.failUnless(filepath.FilePath('a') <=
- filepath.FilePath('a'))
- self.failUnless(filepath.FilePath('a') <
- filepath.FilePath('z'))
- self.failUnless(filepath.FilePath('a') <=
- filepath.FilePath('z'))
- self.failUnless(filepath.FilePath('a') !=
- filepath.FilePath('z'))
- self.failUnless(filepath.FilePath('z') !=
- filepath.FilePath('a'))
-
- self.failIf(filepath.FilePath('z') !=
- filepath.FilePath('z'))
-
-
- def test_descendantOnly(self):
- """
- If C{".."} is in the sequence passed to L{FilePath.descendant},
- L{InsecurePath} is raised.
- """
- self.assertRaises(
- filepath.InsecurePath, self.path.descendant, ['a', '..'])
-
-
- def testSibling(self):
- p = self.path.child('sibling_start')
- ts = p.sibling('sibling_test')
- self.assertEqual(ts.dirname(), p.dirname())
- self.assertEqual(ts.basename(), 'sibling_test')
- ts.createDirectory()
- self.assertIn(ts, self.path.children())
-
- def testTemporarySibling(self):
- ts = self.path.temporarySibling()
- self.assertEqual(ts.dirname(), self.path.dirname())
- self.assertNotIn(ts.basename(), self.path.listdir())
- ts.createDirectory()
- self.assertIn(ts, self.path.parent().children())
-
-
- def test_temporarySiblingExtension(self):
- """
- If L{FilePath.temporarySibling} is given an extension argument, it will
- produce path objects with that extension appended to their names.
- """
- testExtension = ".test-extension"
- ts = self.path.temporarySibling(testExtension)
- self.assertTrue(ts.basename().endswith(testExtension),
- "%s does not end with %s" % (
- ts.basename(), testExtension))
-
-
- def test_removeDirectory(self):
- """
- L{FilePath.remove} on a L{FilePath} that refers to a directory will
- recursively delete its contents.
- """
- self.path.remove()
- self.failIf(self.path.exists())
-
-
- def test_removeWithSymlink(self):
- """
- For a path which is a symbolic link, L{FilePath.remove} just deletes
- the link, not the target.
- """
- link = self.path.child("sub1.link")
- # setUp creates the sub1 child
- self.symlink(self.path.child("sub1").path, link.path)
- link.remove()
- self.assertFalse(link.exists())
- self.assertTrue(self.path.child("sub1").exists())
-
-
- def test_copyToDirectory(self):
- """
- L{FilePath.copyTo} makes a copy of all the contents of the directory
- named by that L{FilePath} if it is able to do so.
- """
- oldPaths = list(self.path.walk()) # Record initial state
- fp = filepath.FilePath(self.mktemp())
- self.path.copyTo(fp)
- self.path.remove()
- fp.copyTo(self.path)
- newPaths = list(self.path.walk()) # Record double-copy state
- newPaths.sort()
- oldPaths.sort()
- self.assertEqual(newPaths, oldPaths)
-
-
- def test_copyToMissingDestFileClosing(self):
- """
- If an exception is raised while L{FilePath.copyTo} is trying to open
- source file to read from, the destination file is closed and the
- exception is raised to the caller of L{FilePath.copyTo}.
- """
- nosuch = self.path.child("nothere")
- # Make it look like something to copy, even though it doesn't exist.
- # This could happen if the file is deleted between the isfile check and
- # the file actually being opened.
- nosuch.isfile = lambda: True
-
- # We won't get as far as writing to this file, but it's still useful for
- # tracking whether we closed it.
- destination = ExplodingFilePath(self.mktemp())
-
- self.assertRaises(IOError, nosuch.copyTo, destination)
- self.assertTrue(destination.fp.closed)
-
-
- def test_copyToFileClosing(self):
- """
- If an exception is raised while L{FilePath.copyTo} is copying bytes
- between two regular files, the source and destination files are closed
- and the exception propagates to the caller of L{FilePath.copyTo}.
- """
- destination = ExplodingFilePath(self.mktemp())
- source = ExplodingFilePath(__file__)
- self.assertRaises(IOError, source.copyTo, destination)
- self.assertTrue(source.fp.closed)
- self.assertTrue(destination.fp.closed)
-
-
- def test_copyToDirectoryItself(self):
- """
- L{FilePath.copyTo} fails with an OSError or IOError (depending on
- platform, as it propagates errors from open() and write()) when
- attempting to copy a directory to a child of itself.
- """
- self.assertRaises((OSError, IOError),
- self.path.copyTo, self.path.child('file1'))
-
-
- def test_copyToWithSymlink(self):
- """
- Verify that copying with followLinks=True copies symlink targets
- instead of symlinks
- """
- self.symlink(self.path.child("sub1").path,
- self.path.child("link1").path)
- fp = filepath.FilePath(self.mktemp())
- self.path.copyTo(fp)
- self.assertFalse(fp.child("link1").islink())
- self.assertEqual([x.basename() for x in fp.child("sub1").children()],
- [x.basename() for x in fp.child("link1").children()])
-
-
- def test_copyToWithoutSymlink(self):
- """
- Verify that copying with followLinks=False copies symlinks as symlinks
- """
- self.symlink("sub1", self.path.child("link1").path)
- fp = filepath.FilePath(self.mktemp())
- self.path.copyTo(fp, followLinks=False)
- self.assertTrue(fp.child("link1").islink())
- self.assertEqual(os.readlink(self.path.child("link1").path),
- os.readlink(fp.child("link1").path))
-
-
- def test_copyToMissingSource(self):
- """
- If the source path is missing, L{FilePath.copyTo} raises L{OSError}.
- """
- path = filepath.FilePath(self.mktemp())
- exc = self.assertRaises(OSError, path.copyTo, 'some other path')
- self.assertEqual(exc.errno, errno.ENOENT)
-
-
- def test_moveTo(self):
- """
- Verify that moving an entire directory results into another directory
- with the same content.
- """
- oldPaths = list(self.path.walk()) # Record initial state
- fp = filepath.FilePath(self.mktemp())
- self.path.moveTo(fp)
- fp.moveTo(self.path)
- newPaths = list(self.path.walk()) # Record double-move state
- newPaths.sort()
- oldPaths.sort()
- self.assertEqual(newPaths, oldPaths)
-
-
- def test_moveToExistsCache(self):
- """
- A L{FilePath} that has been moved aside with L{FilePath.moveTo} no
- longer registers as existing. Its previously non-existent target
- exists, though, as it was created by the call to C{moveTo}.
- """
- fp = filepath.FilePath(self.mktemp())
- fp2 = filepath.FilePath(self.mktemp())
- fp.touch()
-
- # Both a sanity check (make sure the file status looks right) and an
- # enticement for stat-caching logic to kick in and remember that these
- # exist / don't exist.
- self.assertEqual(fp.exists(), True)
- self.assertEqual(fp2.exists(), False)
-
- fp.moveTo(fp2)
- self.assertEqual(fp.exists(), False)
- self.assertEqual(fp2.exists(), True)
-
-
- def test_moveToExistsCacheCrossMount(self):
- """
- The assertion of test_moveToExistsCache should hold in the case of a
- cross-mount move.
- """
- self.setUpFaultyRename()
- self.test_moveToExistsCache()
-
-
- def test_moveToSizeCache(self, hook=lambda : None):
- """
- L{FilePath.moveTo} clears its destination's status cache, such that
- calls to L{FilePath.getsize} after the call to C{moveTo} will report the
- new size, not the old one.
-
- This is a separate test from C{test_moveToExistsCache} because it is
- intended to cover the fact that the destination's cache is dropped;
- test_moveToExistsCache doesn't cover this case because (currently) a
- file that doesn't exist yet does not cache the fact of its non-
- existence.
- """
- fp = filepath.FilePath(self.mktemp())
- fp2 = filepath.FilePath(self.mktemp())
- fp.setContent("1234")
- fp2.setContent("1234567890")
- hook()
-
- # Sanity check / kick off caching.
- self.assertEqual(fp.getsize(), 4)
- self.assertEqual(fp2.getsize(), 10)
- # Actually attempting to replace a file on Windows would fail with
- # ERROR_ALREADY_EXISTS, but we don't need to test that, just the cached
- # metadata, so, delete the file ...
- os.remove(fp2.path)
- # ... but don't clear the status cache, as fp2.remove() would.
- self.assertEqual(fp2.getsize(), 10)
-
- fp.moveTo(fp2)
- self.assertEqual(fp2.getsize(), 4)
-
-
- def test_moveToSizeCacheCrossMount(self):
- """
- The assertion of test_moveToSizeCache should hold in the case of a
- cross-mount move.
- """
- self.test_moveToSizeCache(hook=self.setUpFaultyRename)
-
-
- def test_moveToError(self):
- """
- Verify error behavior of moveTo: it should raises one of OSError or
- IOError if you want to move a path into one of its child. It's simply
- the error raised by the underlying rename system call.
- """
- self.assertRaises((OSError, IOError), self.path.moveTo, self.path.child('file1'))
-
-
- def setUpFaultyRename(self):
- """
- Set up a C{os.rename} that will fail with L{errno.EXDEV} on first call.
- This is used to simulate a cross-device rename failure.
-
- @return: a list of pair (src, dest) of calls to C{os.rename}
- @rtype: C{list} of C{tuple}
- """
- invokedWith = []
- def faultyRename(src, dest):
- invokedWith.append((src, dest))
- if len(invokedWith) == 1:
- raise OSError(errno.EXDEV, 'Test-induced failure simulating '
- 'cross-device rename failure')
- return originalRename(src, dest)
-
- originalRename = os.rename
- self.patch(os, "rename", faultyRename)
- return invokedWith
-
-
- def test_crossMountMoveTo(self):
- """
- C{moveTo} should be able to handle C{EXDEV} error raised by
- C{os.rename} when trying to move a file on a different mounted
- filesystem.
- """
- invokedWith = self.setUpFaultyRename()
- # Bit of a whitebox test - force os.rename, which moveTo tries
- # before falling back to a slower method, to fail, forcing moveTo to
- # use the slower behavior.
- self.test_moveTo()
- # A bit of a sanity check for this whitebox test - if our rename
- # was never invoked, the test has probably fallen into disrepair!
- self.assertTrue(invokedWith)
-
-
- def test_crossMountMoveToWithSymlink(self):
- """
- By default, when moving a symlink, it should follow the link and
- actually copy the content of the linked node.
- """
- invokedWith = self.setUpFaultyRename()
- f2 = self.path.child('file2')
- f3 = self.path.child('file3')
- self.symlink(self.path.child('file1').path, f2.path)
- f2.moveTo(f3)
- self.assertFalse(f3.islink())
- self.assertEqual(f3.getContent(), 'file 1')
- self.assertTrue(invokedWith)
-
-
- def test_crossMountMoveToWithoutSymlink(self):
- """
- Verify that moveTo called with followLinks=False actually create
- another symlink.
- """
- invokedWith = self.setUpFaultyRename()
- f2 = self.path.child('file2')
- f3 = self.path.child('file3')
- self.symlink(self.path.child('file1').path, f2.path)
- f2.moveTo(f3, followLinks=False)
- self.assertTrue(f3.islink())
- self.assertEqual(f3.getContent(), 'file 1')
- self.assertTrue(invokedWith)
-
-
- def test_createBinaryMode(self):
- """
- L{FilePath.create} should always open (and write to) files in binary
- mode; line-feed octets should be unmodified.
-
- (While this test should pass on all platforms, it is only really
- interesting on platforms which have the concept of binary mode, i.e.
- Windows platforms.)
- """
- path = filepath.FilePath(self.mktemp())
- f = path.create()
- self.failUnless("b" in f.mode)
- f.write("\n")
- f.close()
- read = open(path.path, "rb").read()
- self.assertEqual(read, "\n")
-
-
- def testOpen(self):
- # Opening a file for reading when it does not already exist is an error
- nonexistent = self.path.child('nonexistent')
- e = self.assertRaises(IOError, nonexistent.open)
- self.assertEqual(e.errno, errno.ENOENT)
-
- # Opening a file for writing when it does not exist is okay
- writer = self.path.child('writer')
- f = writer.open('w')
- f.write('abc\ndef')
- f.close()
-
- # Make sure those bytes ended up there - and test opening a file for
- # reading when it does exist at the same time
- f = writer.open()
- self.assertEqual(f.read(), 'abc\ndef')
- f.close()
-
- # Re-opening that file in write mode should erase whatever was there.
- f = writer.open('w')
- f.close()
- f = writer.open()
- self.assertEqual(f.read(), '')
- f.close()
-
- # Put some bytes in a file so we can test that appending does not
- # destroy them.
- appender = self.path.child('appender')
- f = appender.open('w')
- f.write('abc')
- f.close()
-
- f = appender.open('a')
- f.write('def')
- f.close()
-
- f = appender.open('r')
- self.assertEqual(f.read(), 'abcdef')
- f.close()
-
- # read/write should let us do both without erasing those bytes
- f = appender.open('r+')
- self.assertEqual(f.read(), 'abcdef')
- # ANSI C *requires* an fseek or an fgetpos between an fread and an
- # fwrite or an fwrite and a fread. We can't reliable get Python to
- # invoke fgetpos, so we seek to a 0 byte offset from the current
- # position instead. Also, Python sucks for making this seek
- # relative to 1 instead of a symbolic constant representing the
- # current file position.
- f.seek(0, 1)
- # Put in some new bytes for us to test for later.
- f.write('ghi')
- f.close()
-
- # Make sure those new bytes really showed up
- f = appender.open('r')
- self.assertEqual(f.read(), 'abcdefghi')
- f.close()
-
- # write/read should let us do both, but erase anything that's there
- # already.
- f = appender.open('w+')
- self.assertEqual(f.read(), '')
- f.seek(0, 1) # Don't forget this!
- f.write('123')
- f.close()
-
- # super append mode should let us read and write and also position the
- # cursor at the end of the file, without erasing everything.
- f = appender.open('a+')
-
- # The order of these lines may seem surprising, but it is necessary.
- # The cursor is not at the end of the file until after the first write.
- f.write('456')
- f.seek(0, 1) # Asinine.
- self.assertEqual(f.read(), '')
-
- f.seek(0, 0)
- self.assertEqual(f.read(), '123456')
- f.close()
-
- # Opening a file exclusively must fail if that file exists already.
- nonexistent.requireCreate(True)
- nonexistent.open('w').close()
- existent = nonexistent
- del nonexistent
- self.assertRaises((OSError, IOError), existent.open)
-
-
- def test_openWithExplicitBinaryMode(self):
- """
- Due to a bug in Python 2.7 on Windows including multiple 'b'
- characters in the mode passed to the built-in open() will cause an
- error. FilePath.open() ensures that only a single 'b' character is
- included in the mode passed to the built-in open().
-
- See http://bugs.python.org/issue7686 for details about the bug.
- """
- writer = self.path.child('explicit-binary')
- file = writer.open('wb')
- file.write('abc\ndef')
- file.close()
- self.assertTrue(writer.exists)
-
-
- def test_openWithRedundantExplicitBinaryModes(self):
- """
- Due to a bug in Python 2.7 on Windows including multiple 'b'
- characters in the mode passed to the built-in open() will cause an
- error. No matter how many 'b' modes are specified, FilePath.open()
- ensures that only a single 'b' character is included in the mode
- passed to the built-in open().
-
- See http://bugs.python.org/issue7686 for details about the bug.
- """
- writer = self.path.child('multiple-binary')
- file = writer.open('wbb')
- file.write('abc\ndef')
- file.close()
- self.assertTrue(writer.exists)
-
-
- def test_existsCache(self):
- """
- Check that C{filepath.FilePath.exists} correctly restat the object if
- an operation has occurred in the mean time.
- """
- fp = filepath.FilePath(self.mktemp())
- self.assertEqual(fp.exists(), False)
-
- fp.makedirs()
- self.assertEqual(fp.exists(), True)
-
-
- def test_changed(self):
- """
- L{FilePath.changed} indicates that the L{FilePath} has changed, but does
- not re-read the status information from the filesystem until it is
- queried again via another method, such as C{getsize}.
- """
- fp = filepath.FilePath(self.mktemp())
- fp.setContent("12345")
- self.assertEqual(fp.getsize(), 5)
-
- # Someone else comes along and changes the file.
- fObj = open(fp.path, 'wb')
- fObj.write("12345678")
- fObj.close()
-
- # Sanity check for caching: size should still be 5.
- self.assertEqual(fp.getsize(), 5)
- fp.changed()
-
- # This path should look like we don't know what status it's in, not that
- # we know that it didn't exist when last we checked.
- self.assertEqual(fp.statinfo, None)
- self.assertEqual(fp.getsize(), 8)
-
-
- def test_getPermissions_POSIX(self):
- """
- Getting permissions for a file returns a L{Permissions} object for
- POSIX platforms (which supports separate user, group, and other
- permissions bits.
- """
- for mode in (0777, 0700):
- self.path.child("sub1").chmod(mode)
- self.assertEqual(self.path.child("sub1").getPermissions(),
- filepath.Permissions(mode))
- self.path.child("sub1").chmod(0764) #sanity check
- self.assertEqual(self.path.child("sub1").getPermissions().shorthand(),
- "rwxrw-r--")
-
-
- def test_getPermissions_Windows(self):
- """
- Getting permissions for a file returns a L{Permissions} object in
- Windows. Windows requires a different test, because user permissions
- = group permissions = other permissions. Also, chmod may not be able
- to set the execute bit, so we are skipping tests that set the execute
- bit.
- """
- for mode in (0777, 0555):
- self.path.child("sub1").chmod(mode)
- self.assertEqual(self.path.child("sub1").getPermissions(),
- filepath.Permissions(mode))
- self.path.child("sub1").chmod(0511) #sanity check to make sure that
- # user=group=other permissions
- self.assertEqual(self.path.child("sub1").getPermissions().shorthand(),
- "r-xr-xr-x")
-
-
- def test_whetherBlockOrSocket(self):
- """
- Ensure that a file is not a block or socket
- """
- self.assertFalse(self.path.isBlockDevice())
- self.assertFalse(self.path.isSocket())
-
-
- def test_statinfoBitsNotImplementedInWindows(self):
- """
- Verify that certain file stats are not available on Windows
- """
- self.assertRaises(NotImplementedError, self.path.getInodeNumber)
- self.assertRaises(NotImplementedError, self.path.getDevice)
- self.assertRaises(NotImplementedError, self.path.getNumberOfHardLinks)
- self.assertRaises(NotImplementedError, self.path.getUserID)
- self.assertRaises(NotImplementedError, self.path.getGroupID)
-
-
- def test_statinfoBitsAreNumbers(self):
- """
- Verify that file inode/device/nlinks/uid/gid stats are numbers in
- a POSIX environment
- """
- c = self.path.child('file1')
- for p in self.path, c:
- self.assertIsInstance(p.getInodeNumber(), long)
- self.assertIsInstance(p.getDevice(), long)
- self.assertIsInstance(p.getNumberOfHardLinks(), int)
- self.assertIsInstance(p.getUserID(), int)
- self.assertIsInstance(p.getGroupID(), int)
- self.assertEqual(self.path.getUserID(), c.getUserID())
- self.assertEqual(self.path.getGroupID(), c.getGroupID())
-
-
- def test_statinfoNumbersAreValid(self):
- """
- Verify that the right numbers come back from the right accessor methods
- for file inode/device/nlinks/uid/gid (in a POSIX environment)
- """
- # specify fake statinfo information
- class FakeStat:
- st_ino = 200
- st_dev = 300
- st_nlink = 400
- st_uid = 500
- st_gid = 600
-
- # monkey patch in a fake restat method for self.path
- fake = FakeStat()
- def fakeRestat(*args, **kwargs):
- self.path.statinfo = fake
- self.path.restat = fakeRestat
-
- # ensure that restat will need to be called to get values
- self.path.statinfo = None
-
- self.assertEqual(self.path.getInodeNumber(), fake.st_ino)
- self.assertEqual(self.path.getDevice(), fake.st_dev)
- self.assertEqual(self.path.getNumberOfHardLinks(), fake.st_nlink)
- self.assertEqual(self.path.getUserID(), fake.st_uid)
- self.assertEqual(self.path.getGroupID(), fake.st_gid)
-
-
- if platform.isWindows():
- test_statinfoBitsAreNumbers.skip = True
- test_statinfoNumbersAreValid.skip = True
- test_getPermissions_POSIX.skip = True
- else:
- test_statinfoBitsNotImplementedInWindows.skip = "Test will run only on Windows."
- test_getPermissions_Windows.skip = "Test will run only on Windows."
-
-
-
-from twisted.python import urlpath
-
-class URLPathTestCase(unittest.TestCase):
- def setUp(self):
- self.path = urlpath.URLPath.fromString("http://example.com/foo/bar?yes=no&no=yes#footer")
-
- def testStringConversion(self):
- self.assertEqual(str(self.path), "http://example.com/foo/bar?yes=no&no=yes#footer")
-
- def testChildString(self):
- self.assertEqual(str(self.path.child('hello')), "http://example.com/foo/bar/hello")
- self.assertEqual(str(self.path.child('hello').child('')), "http://example.com/foo/bar/hello/")
-
- def testSiblingString(self):
- self.assertEqual(str(self.path.sibling('baz')), 'http://example.com/foo/baz')
-
- # The sibling of http://example.com/foo/bar/
- # is http://example.comf/foo/bar/baz
- # because really we are constructing a sibling of
- # http://example.com/foo/bar/index.html
- self.assertEqual(str(self.path.child('').sibling('baz')), 'http://example.com/foo/bar/baz')
-
- def testParentString(self):
- # parent should be equivalent to '..'
- # 'foo' is the current directory, '/' is the parent directory
- self.assertEqual(str(self.path.parent()), 'http://example.com/')
- self.assertEqual(str(self.path.child('').parent()), 'http://example.com/foo/')
- self.assertEqual(str(self.path.child('baz').parent()), 'http://example.com/foo/')
- self.assertEqual(str(self.path.parent().parent().parent().parent().parent()), 'http://example.com/')
-
- def testHereString(self):
- # here should be equivalent to '.'
- self.assertEqual(str(self.path.here()), 'http://example.com/foo/')
- self.assertEqual(str(self.path.child('').here()), 'http://example.com/foo/bar/')
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pb.py
deleted file mode 100755
index 4616708f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pb.py
+++ /dev/null
@@ -1,1846 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for Perspective Broker module.
-
-TODO: update protocol level tests to use new connection API, leaving
-only specific tests for old API.
-"""
-
-# issue1195 TODOs: replace pump.pump() with something involving Deferreds.
-# Clean up warning suppression.
-
-import sys, os, time, gc, weakref
-
-from cStringIO import StringIO
-from zope.interface import implements, Interface
-
-from twisted.trial import unittest
-from twisted.spread import pb, util, publish, jelly
-from twisted.internet import protocol, main, reactor
-from twisted.internet.error import ConnectionRefusedError
-from twisted.internet.defer import Deferred, gatherResults, succeed
-from twisted.protocols.policies import WrappingFactory
-from twisted.python import failure, log
-from twisted.cred.error import UnauthorizedLogin, UnhandledCredentials
-from twisted.cred import portal, checkers, credentials
-
-
-class Dummy(pb.Viewable):
- def view_doNothing(self, user):
- if isinstance(user, DummyPerspective):
- return 'hello world!'
- else:
- return 'goodbye, cruel world!'
-
-
-class DummyPerspective(pb.Avatar):
- """
- An L{IPerspective} avatar which will be used in some tests.
- """
- def perspective_getDummyViewPoint(self):
- return Dummy()
-
-
-
-class DummyRealm(object):
- implements(portal.IRealm)
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- for iface in interfaces:
- if iface is pb.IPerspective:
- return iface, DummyPerspective(avatarId), lambda: None
-
-
-class IOPump:
- """
- Utility to pump data between clients and servers for protocol testing.
-
- Perhaps this is a utility worthy of being in protocol.py?
- """
- def __init__(self, client, server, clientIO, serverIO):
- self.client = client
- self.server = server
- self.clientIO = clientIO
- self.serverIO = serverIO
-
-
- def flush(self):
- """
- Pump until there is no more input or output or until L{stop} is called.
- This does not run any timers, so don't use it with any code that calls
- reactor.callLater.
- """
- # failsafe timeout
- self._stop = False
- timeout = time.time() + 5
- while not self._stop and self.pump():
- if time.time() > timeout:
- return
-
-
- def stop(self):
- """
- Stop a running L{flush} operation, even if data remains to be
- transferred.
- """
- self._stop = True
-
-
- def pump(self):
- """
- Move data back and forth.
-
- Returns whether any data was moved.
- """
- self.clientIO.seek(0)
- self.serverIO.seek(0)
- cData = self.clientIO.read()
- sData = self.serverIO.read()
- self.clientIO.seek(0)
- self.serverIO.seek(0)
- self.clientIO.truncate()
- self.serverIO.truncate()
- self.client.transport._checkProducer()
- self.server.transport._checkProducer()
- for byte in cData:
- self.server.dataReceived(byte)
- for byte in sData:
- self.client.dataReceived(byte)
- if cData or sData:
- return 1
- else:
- return 0
-
-
-
-def connectedServerAndClient(realm=None):
- """
- Connect a client and server L{Broker} together with an L{IOPump}
-
- @param realm: realm to use, defaulting to a L{DummyRealm}
-
- @returns: a 3-tuple (client, server, pump).
- """
- realm = realm or DummyRealm()
- clientBroker = pb.Broker()
- checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(guest='guest')
- factory = pb.PBServerFactory(portal.Portal(realm, [checker]))
- serverBroker = factory.buildProtocol(('127.0.0.1',))
-
- clientTransport = StringIO()
- serverTransport = StringIO()
- clientBroker.makeConnection(protocol.FileWrapper(clientTransport))
- serverBroker.makeConnection(protocol.FileWrapper(serverTransport))
- pump = IOPump(clientBroker, serverBroker, clientTransport, serverTransport)
- # Challenge-response authentication:
- pump.flush()
- return clientBroker, serverBroker, pump
-
-
-class SimpleRemote(pb.Referenceable):
- def remote_thunk(self, arg):
- self.arg = arg
- return arg + 1
-
- def remote_knuth(self, arg):
- raise Exception()
-
-
-class NestedRemote(pb.Referenceable):
- def remote_getSimple(self):
- return SimpleRemote()
-
-
-class SimpleCopy(pb.Copyable):
- def __init__(self):
- self.x = 1
- self.y = {"Hello":"World"}
- self.z = ['test']
-
-
-class SimpleLocalCopy(pb.RemoteCopy):
- pass
-
-pb.setUnjellyableForClass(SimpleCopy, SimpleLocalCopy)
-
-
-class SimpleFactoryCopy(pb.Copyable):
- """
- @cvar allIDs: hold every created instances of this class.
- @type allIDs: C{dict}
- """
- allIDs = {}
- def __init__(self, id):
- self.id = id
- SimpleFactoryCopy.allIDs[id] = self
-
-
-def createFactoryCopy(state):
- """
- Factory of L{SimpleFactoryCopy}, getting a created instance given the
- C{id} found in C{state}.
- """
- stateId = state.get("id", None)
- if stateId is None:
- raise RuntimeError("factory copy state has no 'id' member %s" %
- (repr(state),))
- if not stateId in SimpleFactoryCopy.allIDs:
- raise RuntimeError("factory class has no ID: %s" %
- (SimpleFactoryCopy.allIDs,))
- inst = SimpleFactoryCopy.allIDs[stateId]
- if not inst:
- raise RuntimeError("factory method found no object with id")
- return inst
-
-pb.setUnjellyableFactoryForClass(SimpleFactoryCopy, createFactoryCopy)
-
-
-class NestedCopy(pb.Referenceable):
- def remote_getCopy(self):
- return SimpleCopy()
-
- def remote_getFactory(self, value):
- return SimpleFactoryCopy(value)
-
-
-
-class SimpleCache(pb.Cacheable):
- def __init___(self):
- self.x = 1
- self.y = {"Hello":"World"}
- self.z = ['test']
-
-
-class NestedComplicatedCache(pb.Referenceable):
- def __init__(self):
- self.c = VeryVeryComplicatedCacheable()
-
- def remote_getCache(self):
- return self.c
-
-
-class VeryVeryComplicatedCacheable(pb.Cacheable):
- def __init__(self):
- self.x = 1
- self.y = 2
- self.foo = 3
-
- def setFoo4(self):
- self.foo = 4
- self.observer.callRemote('foo',4)
-
- def getStateToCacheAndObserveFor(self, perspective, observer):
- self.observer = observer
- return {"x": self.x,
- "y": self.y,
- "foo": self.foo}
-
- def stoppedObserving(self, perspective, observer):
- log.msg("stopped observing")
- observer.callRemote("end")
- if observer == self.observer:
- self.observer = None
-
-
-class RatherBaroqueCache(pb.RemoteCache):
- def observe_foo(self, newFoo):
- self.foo = newFoo
-
- def observe_end(self):
- log.msg("the end of things")
-
-pb.setUnjellyableForClass(VeryVeryComplicatedCacheable, RatherBaroqueCache)
-
-
-class SimpleLocalCache(pb.RemoteCache):
- def setCopyableState(self, state):
- self.__dict__.update(state)
-
- def checkMethod(self):
- return self.check
-
- def checkSelf(self):
- return self
-
- def check(self):
- return 1
-
-pb.setUnjellyableForClass(SimpleCache, SimpleLocalCache)
-
-
-class NestedCache(pb.Referenceable):
- def __init__(self):
- self.x = SimpleCache()
-
- def remote_getCache(self):
- return [self.x,self.x]
-
- def remote_putCache(self, cache):
- return (self.x is cache)
-
-
-class Observable(pb.Referenceable):
- def __init__(self):
- self.observers = []
-
- def remote_observe(self, obs):
- self.observers.append(obs)
-
- def remote_unobserve(self, obs):
- self.observers.remove(obs)
-
- def notify(self, obj):
- for observer in self.observers:
- observer.callRemote('notify', self, obj)
-
-
-class DeferredRemote(pb.Referenceable):
- def __init__(self):
- self.run = 0
-
- def runMe(self, arg):
- self.run = arg
- return arg + 1
-
- def dontRunMe(self, arg):
- assert 0, "shouldn't have been run!"
-
- def remote_doItLater(self):
- """
- Return a L{Deferred} to be fired on client side. When fired,
- C{self.runMe} is called.
- """
- d = Deferred()
- d.addCallbacks(self.runMe, self.dontRunMe)
- self.d = d
- return d
-
-
-class Observer(pb.Referenceable):
- notified = 0
- obj = None
- def remote_notify(self, other, obj):
- self.obj = obj
- self.notified = self.notified + 1
- other.callRemote('unobserve',self)
-
-
-class NewStyleCopy(pb.Copyable, pb.RemoteCopy, object):
- def __init__(self, s):
- self.s = s
-pb.setUnjellyableForClass(NewStyleCopy, NewStyleCopy)
-
-
-class NewStyleCopy2(pb.Copyable, pb.RemoteCopy, object):
- allocated = 0
- initialized = 0
- value = 1
-
- def __new__(self):
- NewStyleCopy2.allocated += 1
- inst = object.__new__(self)
- inst.value = 2
- return inst
-
- def __init__(self):
- NewStyleCopy2.initialized += 1
-
-pb.setUnjellyableForClass(NewStyleCopy2, NewStyleCopy2)
-
-
-class NewStyleCacheCopy(pb.Cacheable, pb.RemoteCache, object):
- def getStateToCacheAndObserveFor(self, perspective, observer):
- return self.__dict__
-
-pb.setUnjellyableForClass(NewStyleCacheCopy, NewStyleCacheCopy)
-
-
-class Echoer(pb.Root):
- def remote_echo(self, st):
- return st
-
-
-class CachedReturner(pb.Root):
- def __init__(self, cache):
- self.cache = cache
- def remote_giveMeCache(self, st):
- return self.cache
-
-
-class NewStyleTestCase(unittest.TestCase):
- def setUp(self):
- """
- Create a pb server using L{Echoer} protocol and connect a client to it.
- """
- self.serverFactory = pb.PBServerFactory(Echoer())
- self.wrapper = WrappingFactory(self.serverFactory)
- self.server = reactor.listenTCP(0, self.wrapper)
- clientFactory = pb.PBClientFactory()
- reactor.connectTCP("localhost", self.server.getHost().port,
- clientFactory)
- def gotRoot(ref):
- self.ref = ref
- return clientFactory.getRootObject().addCallback(gotRoot)
-
-
- def tearDown(self):
- """
- Close client and server connections, reset values of L{NewStyleCopy2}
- class variables.
- """
- NewStyleCopy2.allocated = 0
- NewStyleCopy2.initialized = 0
- NewStyleCopy2.value = 1
- self.ref.broker.transport.loseConnection()
- # Disconnect any server-side connections too.
- for proto in self.wrapper.protocols:
- proto.transport.loseConnection()
- return self.server.stopListening()
-
- def test_newStyle(self):
- """
- Create a new style object, send it over the wire, and check the result.
- """
- orig = NewStyleCopy("value")
- d = self.ref.callRemote("echo", orig)
- def cb(res):
- self.failUnless(isinstance(res, NewStyleCopy))
- self.assertEqual(res.s, "value")
- self.failIf(res is orig) # no cheating :)
- d.addCallback(cb)
- return d
-
- def test_alloc(self):
- """
- Send a new style object and check the number of allocations.
- """
- orig = NewStyleCopy2()
- self.assertEqual(NewStyleCopy2.allocated, 1)
- self.assertEqual(NewStyleCopy2.initialized, 1)
- d = self.ref.callRemote("echo", orig)
- def cb(res):
- # receiving the response creates a third one on the way back
- self.failUnless(isinstance(res, NewStyleCopy2))
- self.assertEqual(res.value, 2)
- self.assertEqual(NewStyleCopy2.allocated, 3)
- self.assertEqual(NewStyleCopy2.initialized, 1)
- self.failIf(res is orig) # no cheating :)
- # sending the object creates a second one on the far side
- d.addCallback(cb)
- return d
-
-
-
-class ConnectionNotifyServerFactory(pb.PBServerFactory):
- """
- A server factory which stores the last connection and fires a
- L{Deferred} on connection made. This factory can handle only one
- client connection.
-
- @ivar protocolInstance: the last protocol instance.
- @type protocolInstance: C{pb.Broker}
-
- @ivar connectionMade: the deferred fired upon connection.
- @type connectionMade: C{Deferred}
- """
- protocolInstance = None
-
- def __init__(self, root):
- """
- Initialize the factory.
- """
- pb.PBServerFactory.__init__(self, root)
- self.connectionMade = Deferred()
-
-
- def clientConnectionMade(self, protocol):
- """
- Store the protocol and fire the connection deferred.
- """
- self.protocolInstance = protocol
- d, self.connectionMade = self.connectionMade, None
- if d is not None:
- d.callback(None)
-
-
-
-class NewStyleCachedTestCase(unittest.TestCase):
- def setUp(self):
- """
- Create a pb server using L{CachedReturner} protocol and connect a
- client to it.
- """
- self.orig = NewStyleCacheCopy()
- self.orig.s = "value"
- self.server = reactor.listenTCP(0,
- ConnectionNotifyServerFactory(CachedReturner(self.orig)))
- clientFactory = pb.PBClientFactory()
- reactor.connectTCP("localhost", self.server.getHost().port,
- clientFactory)
- def gotRoot(ref):
- self.ref = ref
- d1 = clientFactory.getRootObject().addCallback(gotRoot)
- d2 = self.server.factory.connectionMade
- return gatherResults([d1, d2])
-
-
- def tearDown(self):
- """
- Close client and server connections.
- """
- self.server.factory.protocolInstance.transport.loseConnection()
- self.ref.broker.transport.loseConnection()
- return self.server.stopListening()
-
-
- def test_newStyleCache(self):
- """
- A new-style cacheable object can be retrieved and re-retrieved over a
- single connection. The value of an attribute of the cacheable can be
- accessed on the receiving side.
- """
- d = self.ref.callRemote("giveMeCache", self.orig)
- def cb(res, again):
- self.assertIsInstance(res, NewStyleCacheCopy)
- self.assertEqual("value", res.s)
- # no cheating :)
- self.assertNotIdentical(self.orig, res)
-
- if again:
- # Save a reference so it stays alive for the rest of this test
- self.res = res
- # And ask for it again to exercise the special re-jelly logic in
- # Cacheable.
- return self.ref.callRemote("giveMeCache", self.orig)
- d.addCallback(cb, True)
- d.addCallback(cb, False)
- return d
-
-
-
-class BrokerTestCase(unittest.TestCase):
- thunkResult = None
-
- def tearDown(self):
- try:
- # from RemotePublished.getFileName
- os.unlink('None-None-TESTING.pub')
- except OSError:
- pass
-
- def thunkErrorBad(self, error):
- self.fail("This should cause a return value, not %s" % (error,))
-
- def thunkResultGood(self, result):
- self.thunkResult = result
-
- def thunkErrorGood(self, tb):
- pass
-
- def thunkResultBad(self, result):
- self.fail("This should cause an error, not %s" % (result,))
-
- def test_reference(self):
- c, s, pump = connectedServerAndClient()
-
- class X(pb.Referenceable):
- def remote_catch(self,arg):
- self.caught = arg
-
- class Y(pb.Referenceable):
- def remote_throw(self, a, b):
- a.callRemote('catch', b)
-
- s.setNameForLocal("y", Y())
- y = c.remoteForName("y")
- x = X()
- z = X()
- y.callRemote('throw', x, z)
- pump.pump()
- pump.pump()
- pump.pump()
- self.assertIdentical(x.caught, z, "X should have caught Z")
-
- # make sure references to remote methods are equals
- self.assertEqual(y.remoteMethod('throw'), y.remoteMethod('throw'))
-
- def test_result(self):
- c, s, pump = connectedServerAndClient()
- for x, y in (c, s), (s, c):
- # test reflexivity
- foo = SimpleRemote()
- x.setNameForLocal("foo", foo)
- bar = y.remoteForName("foo")
- self.expectedThunkResult = 8
- bar.callRemote('thunk',self.expectedThunkResult - 1
- ).addCallbacks(self.thunkResultGood, self.thunkErrorBad)
- # Send question.
- pump.pump()
- # Send response.
- pump.pump()
- # Shouldn't require any more pumping than that...
- self.assertEqual(self.thunkResult, self.expectedThunkResult,
- "result wasn't received.")
-
- def refcountResult(self, result):
- self.nestedRemote = result
-
- def test_tooManyRefs(self):
- l = []
- e = []
- c, s, pump = connectedServerAndClient()
- foo = NestedRemote()
- s.setNameForLocal("foo", foo)
- x = c.remoteForName("foo")
- for igno in xrange(pb.MAX_BROKER_REFS + 10):
- if s.transport.closed or c.transport.closed:
- break
- x.callRemote("getSimple").addCallbacks(l.append, e.append)
- pump.pump()
- expected = (pb.MAX_BROKER_REFS - 1)
- self.assertTrue(s.transport.closed, "transport was not closed")
- self.assertEqual(len(l), expected,
- "expected %s got %s" % (expected, len(l)))
-
- def test_copy(self):
- c, s, pump = connectedServerAndClient()
- foo = NestedCopy()
- s.setNameForLocal("foo", foo)
- x = c.remoteForName("foo")
- x.callRemote('getCopy'
- ).addCallbacks(self.thunkResultGood, self.thunkErrorBad)
- pump.pump()
- pump.pump()
- self.assertEqual(self.thunkResult.x, 1)
- self.assertEqual(self.thunkResult.y['Hello'], 'World')
- self.assertEqual(self.thunkResult.z[0], 'test')
-
- def test_observe(self):
- c, s, pump = connectedServerAndClient()
-
- # this is really testing the comparison between remote objects, to make
- # sure that you can *UN*observe when you have an observer architecture.
- a = Observable()
- b = Observer()
- s.setNameForLocal("a", a)
- ra = c.remoteForName("a")
- ra.callRemote('observe',b)
- pump.pump()
- a.notify(1)
- pump.pump()
- pump.pump()
- a.notify(10)
- pump.pump()
- pump.pump()
- self.assertNotIdentical(b.obj, None, "didn't notify")
- self.assertEqual(b.obj, 1, 'notified too much')
-
- def test_defer(self):
- c, s, pump = connectedServerAndClient()
- d = DeferredRemote()
- s.setNameForLocal("d", d)
- e = c.remoteForName("d")
- pump.pump(); pump.pump()
- results = []
- e.callRemote('doItLater').addCallback(results.append)
- pump.pump(); pump.pump()
- self.assertFalse(d.run, "Deferred method run too early.")
- d.d.callback(5)
- self.assertEqual(d.run, 5, "Deferred method run too late.")
- pump.pump(); pump.pump()
- self.assertEqual(results[0], 6, "Incorrect result.")
-
-
- def test_refcount(self):
- c, s, pump = connectedServerAndClient()
- foo = NestedRemote()
- s.setNameForLocal("foo", foo)
- bar = c.remoteForName("foo")
- bar.callRemote('getSimple'
- ).addCallbacks(self.refcountResult, self.thunkErrorBad)
-
- # send question
- pump.pump()
- # send response
- pump.pump()
-
- # delving into internal structures here, because GC is sort of
- # inherently internal.
- rluid = self.nestedRemote.luid
- self.assertIn(rluid, s.localObjects)
- del self.nestedRemote
- # nudge the gc
- if sys.hexversion >= 0x2000000:
- gc.collect()
- # try to nudge the GC even if we can't really
- pump.pump()
- pump.pump()
- pump.pump()
- self.assertNotIn(rluid, s.localObjects)
-
- def test_cache(self):
- c, s, pump = connectedServerAndClient()
- obj = NestedCache()
- obj2 = NestedComplicatedCache()
- vcc = obj2.c
- s.setNameForLocal("obj", obj)
- s.setNameForLocal("xxx", obj2)
- o2 = c.remoteForName("obj")
- o3 = c.remoteForName("xxx")
- coll = []
- o2.callRemote("getCache"
- ).addCallback(coll.append).addErrback(coll.append)
- o2.callRemote("getCache"
- ).addCallback(coll.append).addErrback(coll.append)
- complex = []
- o3.callRemote("getCache").addCallback(complex.append)
- o3.callRemote("getCache").addCallback(complex.append)
- pump.flush()
- # `worst things first'
- self.assertEqual(complex[0].x, 1)
- self.assertEqual(complex[0].y, 2)
- self.assertEqual(complex[0].foo, 3)
-
- vcc.setFoo4()
- pump.flush()
- self.assertEqual(complex[0].foo, 4)
- self.assertEqual(len(coll), 2)
- cp = coll[0][0]
- self.assertIdentical(cp.checkMethod().im_self, cp,
- "potential refcounting issue")
- self.assertIdentical(cp.checkSelf(), cp,
- "other potential refcounting issue")
- col2 = []
- o2.callRemote('putCache',cp).addCallback(col2.append)
- pump.flush()
- # The objects were the same (testing lcache identity)
- self.assertTrue(col2[0])
- # test equality of references to methods
- self.assertEqual(o2.remoteMethod("getCache"),
- o2.remoteMethod("getCache"))
-
- # now, refcounting (similiar to testRefCount)
- luid = cp.luid
- baroqueLuid = complex[0].luid
- self.assertIn(luid, s.remotelyCachedObjects,
- "remote cache doesn't have it")
- del coll
- del cp
- pump.flush()
- del complex
- del col2
- # extra nudge...
- pump.flush()
- # del vcc.observer
- # nudge the gc
- if sys.hexversion >= 0x2000000:
- gc.collect()
- # try to nudge the GC even if we can't really
- pump.flush()
- # The GC is done with it.
- self.assertNotIn(luid, s.remotelyCachedObjects,
- "Server still had it after GC")
- self.assertNotIn(luid, c.locallyCachedObjects,
- "Client still had it after GC")
- self.assertNotIn(baroqueLuid, s.remotelyCachedObjects,
- "Server still had complex after GC")
- self.assertNotIn(baroqueLuid, c.locallyCachedObjects,
- "Client still had complex after GC")
- self.assertIdentical(vcc.observer, None, "observer was not removed")
-
- def test_publishable(self):
- try:
- os.unlink('None-None-TESTING.pub') # from RemotePublished.getFileName
- except OSError:
- pass # Sometimes it's not there.
- c, s, pump = connectedServerAndClient()
- foo = GetPublisher()
- # foo.pub.timestamp = 1.0
- s.setNameForLocal("foo", foo)
- bar = c.remoteForName("foo")
- accum = []
- bar.callRemote('getPub').addCallbacks(accum.append, self.thunkErrorBad)
- pump.flush()
- obj = accum.pop()
- self.assertEqual(obj.activateCalled, 1)
- self.assertEqual(obj.isActivated, 1)
- self.assertEqual(obj.yayIGotPublished, 1)
- # timestamp's dirty, we don't have a cache file
- self.assertEqual(obj._wasCleanWhenLoaded, 0)
- c, s, pump = connectedServerAndClient()
- s.setNameForLocal("foo", foo)
- bar = c.remoteForName("foo")
- bar.callRemote('getPub').addCallbacks(accum.append, self.thunkErrorBad)
- pump.flush()
- obj = accum.pop()
- # timestamp's clean, our cache file is up-to-date
- self.assertEqual(obj._wasCleanWhenLoaded, 1)
-
- def gotCopy(self, val):
- self.thunkResult = val.id
-
-
- def test_factoryCopy(self):
- c, s, pump = connectedServerAndClient()
- ID = 99
- obj = NestedCopy()
- s.setNameForLocal("foo", obj)
- x = c.remoteForName("foo")
- x.callRemote('getFactory', ID
- ).addCallbacks(self.gotCopy, self.thunkResultBad)
- pump.pump()
- pump.pump()
- pump.pump()
- self.assertEqual(self.thunkResult, ID,
- "ID not correct on factory object %s" % (self.thunkResult,))
-
-
-bigString = "helloworld" * 50
-
-callbackArgs = None
-callbackKeyword = None
-
-def finishedCallback(*args, **kw):
- global callbackArgs, callbackKeyword
- callbackArgs = args
- callbackKeyword = kw
-
-
-class Pagerizer(pb.Referenceable):
- def __init__(self, callback, *args, **kw):
- self.callback, self.args, self.kw = callback, args, kw
-
- def remote_getPages(self, collector):
- util.StringPager(collector, bigString, 100,
- self.callback, *self.args, **self.kw)
- self.args = self.kw = None
-
-
-class FilePagerizer(pb.Referenceable):
- pager = None
-
- def __init__(self, filename, callback, *args, **kw):
- self.filename = filename
- self.callback, self.args, self.kw = callback, args, kw
-
- def remote_getPages(self, collector):
- self.pager = util.FilePager(collector, file(self.filename),
- self.callback, *self.args, **self.kw)
- self.args = self.kw = None
-
-
-
-class PagingTestCase(unittest.TestCase):
- """
- Test pb objects sending data by pages.
- """
-
- def setUp(self):
- """
- Create a file used to test L{util.FilePager}.
- """
- self.filename = self.mktemp()
- fd = file(self.filename, 'w')
- fd.write(bigString)
- fd.close()
-
-
- def test_pagingWithCallback(self):
- """
- Test L{util.StringPager}, passing a callback to fire when all pages
- are sent.
- """
- c, s, pump = connectedServerAndClient()
- s.setNameForLocal("foo", Pagerizer(finishedCallback, 'hello', value=10))
- x = c.remoteForName("foo")
- l = []
- util.getAllPages(x, "getPages").addCallback(l.append)
- while not l:
- pump.pump()
- self.assertEqual(''.join(l[0]), bigString,
- "Pages received not equal to pages sent!")
- self.assertEqual(callbackArgs, ('hello',),
- "Completed callback not invoked")
- self.assertEqual(callbackKeyword, {'value': 10},
- "Completed callback not invoked")
-
-
- def test_pagingWithoutCallback(self):
- """
- Test L{util.StringPager} without a callback.
- """
- c, s, pump = connectedServerAndClient()
- s.setNameForLocal("foo", Pagerizer(None))
- x = c.remoteForName("foo")
- l = []
- util.getAllPages(x, "getPages").addCallback(l.append)
- while not l:
- pump.pump()
- self.assertEqual(''.join(l[0]), bigString,
- "Pages received not equal to pages sent!")
-
-
- def test_emptyFilePaging(self):
- """
- Test L{util.FilePager}, sending an empty file.
- """
- filenameEmpty = self.mktemp()
- fd = file(filenameEmpty, 'w')
- fd.close()
- c, s, pump = connectedServerAndClient()
- pagerizer = FilePagerizer(filenameEmpty, None)
- s.setNameForLocal("bar", pagerizer)
- x = c.remoteForName("bar")
- l = []
- util.getAllPages(x, "getPages").addCallback(l.append)
- ttl = 10
- while not l and ttl > 0:
- pump.pump()
- ttl -= 1
- if not ttl:
- self.fail('getAllPages timed out')
- self.assertEqual(''.join(l[0]), '',
- "Pages received not equal to pages sent!")
-
-
- def test_filePagingWithCallback(self):
- """
- Test L{util.FilePager}, passing a callback to fire when all pages
- are sent, and verify that the pager doesn't keep chunks in memory.
- """
- c, s, pump = connectedServerAndClient()
- pagerizer = FilePagerizer(self.filename, finishedCallback,
- 'frodo', value = 9)
- s.setNameForLocal("bar", pagerizer)
- x = c.remoteForName("bar")
- l = []
- util.getAllPages(x, "getPages").addCallback(l.append)
- while not l:
- pump.pump()
- self.assertEqual(''.join(l[0]), bigString,
- "Pages received not equal to pages sent!")
- self.assertEqual(callbackArgs, ('frodo',),
- "Completed callback not invoked")
- self.assertEqual(callbackKeyword, {'value': 9},
- "Completed callback not invoked")
- self.assertEqual(pagerizer.pager.chunks, [])
-
-
- def test_filePagingWithoutCallback(self):
- """
- Test L{util.FilePager} without a callback.
- """
- c, s, pump = connectedServerAndClient()
- pagerizer = FilePagerizer(self.filename, None)
- s.setNameForLocal("bar", pagerizer)
- x = c.remoteForName("bar")
- l = []
- util.getAllPages(x, "getPages").addCallback(l.append)
- while not l:
- pump.pump()
- self.assertEqual(''.join(l[0]), bigString,
- "Pages received not equal to pages sent!")
- self.assertEqual(pagerizer.pager.chunks, [])
-
-
-
-class DumbPublishable(publish.Publishable):
- def getStateToPublish(self):
- return {"yayIGotPublished": 1}
-
-
-class DumbPub(publish.RemotePublished):
- def activated(self):
- self.activateCalled = 1
-
-
-class GetPublisher(pb.Referenceable):
- def __init__(self):
- self.pub = DumbPublishable("TESTING")
-
- def remote_getPub(self):
- return self.pub
-
-
-pb.setUnjellyableForClass(DumbPublishable, DumbPub)
-
-class DisconnectionTestCase(unittest.TestCase):
- """
- Test disconnection callbacks.
- """
-
- def error(self, *args):
- raise RuntimeError("I shouldn't have been called: %s" % (args,))
-
-
- def gotDisconnected(self):
- """
- Called on broker disconnect.
- """
- self.gotCallback = 1
-
- def objectDisconnected(self, o):
- """
- Called on RemoteReference disconnect.
- """
- self.assertEqual(o, self.remoteObject)
- self.objectCallback = 1
-
- def test_badSerialization(self):
- c, s, pump = connectedServerAndClient()
- pump.pump()
- s.setNameForLocal("o", BadCopySet())
- g = c.remoteForName("o")
- l = []
- g.callRemote("setBadCopy", BadCopyable()).addErrback(l.append)
- pump.flush()
- self.assertEqual(len(l), 1)
-
- def test_disconnection(self):
- c, s, pump = connectedServerAndClient()
- pump.pump()
- s.setNameForLocal("o", SimpleRemote())
-
- # get a client reference to server object
- r = c.remoteForName("o")
- pump.pump()
- pump.pump()
- pump.pump()
-
- # register and then unregister disconnect callbacks
- # making sure they get unregistered
- c.notifyOnDisconnect(self.error)
- self.assertIn(self.error, c.disconnects)
- c.dontNotifyOnDisconnect(self.error)
- self.assertNotIn(self.error, c.disconnects)
-
- r.notifyOnDisconnect(self.error)
- self.assertIn(r._disconnected, c.disconnects)
- self.assertIn(self.error, r.disconnectCallbacks)
- r.dontNotifyOnDisconnect(self.error)
- self.assertNotIn(r._disconnected, c.disconnects)
- self.assertNotIn(self.error, r.disconnectCallbacks)
-
- # register disconnect callbacks
- c.notifyOnDisconnect(self.gotDisconnected)
- r.notifyOnDisconnect(self.objectDisconnected)
- self.remoteObject = r
-
- # disconnect
- c.connectionLost(failure.Failure(main.CONNECTION_DONE))
- self.assertTrue(self.gotCallback)
- self.assertTrue(self.objectCallback)
-
-
-class FreakOut(Exception):
- pass
-
-
-class BadCopyable(pb.Copyable):
- def getStateToCopyFor(self, p):
- raise FreakOut()
-
-
-class BadCopySet(pb.Referenceable):
- def remote_setBadCopy(self, bc):
- return None
-
-
-class LocalRemoteTest(util.LocalAsRemote):
- reportAllTracebacks = 0
-
- def sync_add1(self, x):
- return x + 1
-
- def async_add(self, x=0, y=1):
- return x + y
-
- def async_fail(self):
- raise RuntimeError()
-
-
-
-class MyPerspective(pb.Avatar):
- """
- @ivar loggedIn: set to C{True} when the avatar is logged in.
- @type loggedIn: C{bool}
-
- @ivar loggedOut: set to C{True} when the avatar is logged out.
- @type loggedOut: C{bool}
- """
- implements(pb.IPerspective)
-
- loggedIn = loggedOut = False
-
- def __init__(self, avatarId):
- self.avatarId = avatarId
-
-
- def perspective_getAvatarId(self):
- """
- Return the avatar identifier which was used to access this avatar.
- """
- return self.avatarId
-
-
- def perspective_getViewPoint(self):
- return MyView()
-
-
- def perspective_add(self, a, b):
- """
- Add the given objects and return the result. This is a method
- unavailable on L{Echoer}, so it can only be invoked by authenticated
- users who received their avatar from L{TestRealm}.
- """
- return a + b
-
-
- def logout(self):
- self.loggedOut = True
-
-
-
-class TestRealm(object):
- """
- A realm which repeatedly gives out a single instance of L{MyPerspective}
- for non-anonymous logins and which gives out a new instance of L{Echoer}
- for each anonymous login.
-
- @ivar lastPerspective: The L{MyPerspective} most recently created and
- returned from C{requestAvatar}.
-
- @ivar perspectiveFactory: A one-argument callable which will be used to
- create avatars to be returned from C{requestAvatar}.
- """
- perspectiveFactory = MyPerspective
-
- lastPerspective = None
-
- def requestAvatar(self, avatarId, mind, interface):
- """
- Verify that the mind and interface supplied have the expected values
- (this should really be done somewhere else, like inside a test method)
- and return an avatar appropriate for the given identifier.
- """
- assert interface == pb.IPerspective
- assert mind == "BRAINS!"
- if avatarId is checkers.ANONYMOUS:
- return pb.IPerspective, Echoer(), lambda: None
- else:
- self.lastPerspective = self.perspectiveFactory(avatarId)
- self.lastPerspective.loggedIn = True
- return (
- pb.IPerspective, self.lastPerspective,
- self.lastPerspective.logout)
-
-
-
-class MyView(pb.Viewable):
-
- def view_check(self, user):
- return isinstance(user, MyPerspective)
-
-
-
-class LeakyRealm(TestRealm):
- """
- A realm which hangs onto a reference to the mind object in its logout
- function.
- """
- def __init__(self, mindEater):
- """
- Create a L{LeakyRealm}.
-
- @param mindEater: a callable that will be called with the C{mind}
- object when it is available
- """
- self._mindEater = mindEater
-
-
- def requestAvatar(self, avatarId, mind, interface):
- self._mindEater(mind)
- persp = self.perspectiveFactory(avatarId)
- return (pb.IPerspective, persp, lambda : (mind, persp.logout()))
-
-
-
-class NewCredLeakTests(unittest.TestCase):
- """
- Tests to try to trigger memory leaks.
- """
- def test_logoutLeak(self):
- """
- The server does not leak a reference when the client disconnects
- suddenly, even if the cred logout function forms a reference cycle with
- the perspective.
- """
- # keep a weak reference to the mind object, which we can verify later
- # evaluates to None, thereby ensuring the reference leak is fixed.
- self.mindRef = None
- def setMindRef(mind):
- self.mindRef = weakref.ref(mind)
-
- clientBroker, serverBroker, pump = connectedServerAndClient(
- LeakyRealm(setMindRef))
-
- # log in from the client
- connectionBroken = []
- root = clientBroker.remoteForName("root")
- d = root.callRemote("login", 'guest')
- def cbResponse((challenge, challenger)):
- mind = SimpleRemote()
- return challenger.callRemote("respond",
- pb.respond(challenge, 'guest'), mind)
- d.addCallback(cbResponse)
- def connectionLost(_):
- pump.stop() # don't try to pump data anymore - it won't work
- connectionBroken.append(1)
- serverBroker.connectionLost(failure.Failure(RuntimeError("boom")))
- d.addCallback(connectionLost)
-
- # flush out the response and connectionLost
- pump.flush()
- self.assertEqual(connectionBroken, [1])
-
- # and check for lingering references - requestAvatar sets mindRef
- # to a weakref to the mind; this object should be gc'd, and thus
- # the ref should return None
- gc.collect()
- self.assertEqual(self.mindRef(), None)
-
-
-
-class NewCredTestCase(unittest.TestCase):
- """
- Tests related to the L{twisted.cred} support in PB.
- """
- def setUp(self):
- """
- Create a portal with no checkers and wrap it around a simple test
- realm. Set up a PB server on a TCP port which serves perspectives
- using that portal.
- """
- self.realm = TestRealm()
- self.portal = portal.Portal(self.realm)
- self.factory = ConnectionNotifyServerFactory(self.portal)
- self.port = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
- self.portno = self.port.getHost().port
-
-
- def tearDown(self):
- """
- Shut down the TCP port created by L{setUp}.
- """
- return self.port.stopListening()
-
-
- def getFactoryAndRootObject(self, clientFactory=pb.PBClientFactory):
- """
- Create a connection to the test server.
-
- @param clientFactory: the factory class used to create the connection.
-
- @return: a tuple (C{factory}, C{deferred}), where factory is an
- instance of C{clientFactory} and C{deferred} the L{Deferred} firing
- with the PB root object.
- """
- factory = clientFactory()
- rootObjDeferred = factory.getRootObject()
- connector = reactor.connectTCP('127.0.0.1', self.portno, factory)
- self.addCleanup(connector.disconnect)
- return factory, rootObjDeferred
-
-
- def test_getRootObject(self):
- """
- Assert only that L{PBClientFactory.getRootObject}'s Deferred fires with
- a L{RemoteReference}.
- """
- factory, rootObjDeferred = self.getFactoryAndRootObject()
-
- def gotRootObject(rootObj):
- self.assertIsInstance(rootObj, pb.RemoteReference)
- disconnectedDeferred = Deferred()
- rootObj.notifyOnDisconnect(disconnectedDeferred.callback)
- factory.disconnect()
- return disconnectedDeferred
-
- return rootObjDeferred.addCallback(gotRootObject)
-
-
- def test_deadReferenceError(self):
- """
- Test that when a connection is lost, calling a method on a
- RemoteReference obtained from it raises DeadReferenceError.
- """
- factory, rootObjDeferred = self.getFactoryAndRootObject()
-
- def gotRootObject(rootObj):
- disconnectedDeferred = Deferred()
- rootObj.notifyOnDisconnect(disconnectedDeferred.callback)
-
- def lostConnection(ign):
- self.assertRaises(
- pb.DeadReferenceError,
- rootObj.callRemote, 'method')
-
- disconnectedDeferred.addCallback(lostConnection)
- factory.disconnect()
- return disconnectedDeferred
-
- return rootObjDeferred.addCallback(gotRootObject)
-
-
- def test_clientConnectionLost(self):
- """
- Test that if the L{reconnecting} flag is passed with a True value then
- a remote call made from a disconnection notification callback gets a
- result successfully.
- """
- class ReconnectOnce(pb.PBClientFactory):
- reconnectedAlready = False
- def clientConnectionLost(self, connector, reason):
- reconnecting = not self.reconnectedAlready
- self.reconnectedAlready = True
- if reconnecting:
- connector.connect()
- return pb.PBClientFactory.clientConnectionLost(
- self, connector, reason, reconnecting)
-
- factory, rootObjDeferred = self.getFactoryAndRootObject(ReconnectOnce)
-
- def gotRootObject(rootObj):
- self.assertIsInstance(rootObj, pb.RemoteReference)
-
- d = Deferred()
- rootObj.notifyOnDisconnect(d.callback)
- factory.disconnect()
-
- def disconnected(ign):
- d = factory.getRootObject()
-
- def gotAnotherRootObject(anotherRootObj):
- self.assertIsInstance(anotherRootObj, pb.RemoteReference)
-
- d = Deferred()
- anotherRootObj.notifyOnDisconnect(d.callback)
- factory.disconnect()
- return d
- return d.addCallback(gotAnotherRootObject)
- return d.addCallback(disconnected)
- return rootObjDeferred.addCallback(gotRootObject)
-
-
- def test_immediateClose(self):
- """
- Test that if a Broker loses its connection without receiving any bytes,
- it doesn't raise any exceptions or log any errors.
- """
- serverProto = self.factory.buildProtocol(('127.0.0.1', 12345))
- serverProto.makeConnection(protocol.FileWrapper(StringIO()))
- serverProto.connectionLost(failure.Failure(main.CONNECTION_DONE))
-
-
- def test_loginConnectionRefused(self):
- """
- L{PBClientFactory.login} returns a L{Deferred} which is errbacked
- with the L{ConnectionRefusedError} if the underlying connection is
- refused.
- """
- clientFactory = pb.PBClientFactory()
- loginDeferred = clientFactory.login(
- credentials.UsernamePassword("foo", "bar"))
- clientFactory.clientConnectionFailed(
- None,
- failure.Failure(
- ConnectionRefusedError("Test simulated refused connection")))
- return self.assertFailure(loginDeferred, ConnectionRefusedError)
-
-
- def _disconnect(self, ignore, factory):
- """
- Helper method disconnecting the given client factory and returning a
- C{Deferred} that will fire when the server connection has noticed the
- disconnection.
- """
- disconnectedDeferred = Deferred()
- self.factory.protocolInstance.notifyOnDisconnect(
- lambda: disconnectedDeferred.callback(None))
- factory.disconnect()
- return disconnectedDeferred
-
-
- def test_loginLogout(self):
- """
- Test that login can be performed with IUsernamePassword credentials and
- that when the connection is dropped the avatar is logged out.
- """
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass'))
- factory = pb.PBClientFactory()
- creds = credentials.UsernamePassword("user", "pass")
-
- # NOTE: real code probably won't need anything where we have the
- # "BRAINS!" argument, passing None is fine. We just do it here to
- # test that it is being passed. It is used to give additional info to
- # the realm to aid perspective creation, if you don't need that,
- # ignore it.
- mind = "BRAINS!"
-
- d = factory.login(creds, mind)
- def cbLogin(perspective):
- self.assertTrue(self.realm.lastPerspective.loggedIn)
- self.assertIsInstance(perspective, pb.RemoteReference)
- return self._disconnect(None, factory)
- d.addCallback(cbLogin)
-
- def cbLogout(ignored):
- self.assertTrue(self.realm.lastPerspective.loggedOut)
- d.addCallback(cbLogout)
-
- connector = reactor.connectTCP("127.0.0.1", self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_logoutAfterDecref(self):
- """
- If a L{RemoteReference} to an L{IPerspective} avatar is decrefed and
- there remain no other references to the avatar on the server, the
- avatar is garbage collected and the logout method called.
- """
- loggedOut = Deferred()
-
- class EventPerspective(pb.Avatar):
- """
- An avatar which fires a Deferred when it is logged out.
- """
- def __init__(self, avatarId):
- pass
-
- def logout(self):
- loggedOut.callback(None)
-
- self.realm.perspectiveFactory = EventPerspective
-
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(foo='bar'))
- factory = pb.PBClientFactory()
- d = factory.login(
- credentials.UsernamePassword('foo', 'bar'), "BRAINS!")
- def cbLoggedIn(avatar):
- # Just wait for the logout to happen, as it should since the
- # reference to the avatar will shortly no longer exists.
- return loggedOut
- d.addCallback(cbLoggedIn)
- def cbLoggedOut(ignored):
- # Verify that the server broker's _localCleanup dict isn't growing
- # without bound.
- self.assertEqual(self.factory.protocolInstance._localCleanup, {})
- d.addCallback(cbLoggedOut)
- d.addCallback(self._disconnect, factory)
- connector = reactor.connectTCP("127.0.0.1", self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_concurrentLogin(self):
- """
- Two different correct login attempts can be made on the same root
- object at the same time and produce two different resulting avatars.
- """
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(
- foo='bar', baz='quux'))
- factory = pb.PBClientFactory()
-
- firstLogin = factory.login(
- credentials.UsernamePassword('foo', 'bar'), "BRAINS!")
- secondLogin = factory.login(
- credentials.UsernamePassword('baz', 'quux'), "BRAINS!")
- d = gatherResults([firstLogin, secondLogin])
- def cbLoggedIn((first, second)):
- return gatherResults([
- first.callRemote('getAvatarId'),
- second.callRemote('getAvatarId')])
- d.addCallback(cbLoggedIn)
- def cbAvatarIds((first, second)):
- self.assertEqual(first, 'foo')
- self.assertEqual(second, 'baz')
- d.addCallback(cbAvatarIds)
- d.addCallback(self._disconnect, factory)
-
- connector = reactor.connectTCP('127.0.0.1', self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_badUsernamePasswordLogin(self):
- """
- Test that a login attempt with an invalid user or invalid password
- fails in the appropriate way.
- """
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass'))
- factory = pb.PBClientFactory()
-
- firstLogin = factory.login(
- credentials.UsernamePassword('nosuchuser', 'pass'))
- secondLogin = factory.login(
- credentials.UsernamePassword('user', 'wrongpass'))
-
- self.assertFailure(firstLogin, UnauthorizedLogin)
- self.assertFailure(secondLogin, UnauthorizedLogin)
- d = gatherResults([firstLogin, secondLogin])
-
- def cleanup(ignore):
- errors = self.flushLoggedErrors(UnauthorizedLogin)
- self.assertEqual(len(errors), 2)
- return self._disconnect(None, factory)
- d.addCallback(cleanup)
-
- connector = reactor.connectTCP("127.0.0.1", self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_anonymousLogin(self):
- """
- Verify that a PB server using a portal configured with an checker which
- allows IAnonymous credentials can be logged into using IAnonymous
- credentials.
- """
- self.portal.registerChecker(checkers.AllowAnonymousAccess())
- factory = pb.PBClientFactory()
- d = factory.login(credentials.Anonymous(), "BRAINS!")
-
- def cbLoggedIn(perspective):
- return perspective.callRemote('echo', 123)
- d.addCallback(cbLoggedIn)
-
- d.addCallback(self.assertEqual, 123)
-
- d.addCallback(self._disconnect, factory)
-
- connector = reactor.connectTCP("127.0.0.1", self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_anonymousLoginNotPermitted(self):
- """
- Verify that without an anonymous checker set up, anonymous login is
- rejected.
- """
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass'))
- factory = pb.PBClientFactory()
- d = factory.login(credentials.Anonymous(), "BRAINS!")
- self.assertFailure(d, UnhandledCredentials)
-
- def cleanup(ignore):
- errors = self.flushLoggedErrors(UnhandledCredentials)
- self.assertEqual(len(errors), 1)
- return self._disconnect(None, factory)
- d.addCallback(cleanup)
-
- connector = reactor.connectTCP('127.0.0.1', self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_anonymousLoginWithMultipleCheckers(self):
- """
- Like L{test_anonymousLogin} but against a portal with a checker for
- both IAnonymous and IUsernamePassword.
- """
- self.portal.registerChecker(checkers.AllowAnonymousAccess())
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass'))
- factory = pb.PBClientFactory()
- d = factory.login(credentials.Anonymous(), "BRAINS!")
-
- def cbLogin(perspective):
- return perspective.callRemote('echo', 123)
- d.addCallback(cbLogin)
-
- d.addCallback(self.assertEqual, 123)
-
- d.addCallback(self._disconnect, factory)
-
- connector = reactor.connectTCP('127.0.0.1', self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_authenticatedLoginWithMultipleCheckers(self):
- """
- Like L{test_anonymousLoginWithMultipleCheckers} but check that
- username/password authentication works.
- """
- self.portal.registerChecker(checkers.AllowAnonymousAccess())
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass'))
- factory = pb.PBClientFactory()
- d = factory.login(
- credentials.UsernamePassword('user', 'pass'), "BRAINS!")
-
- def cbLogin(perspective):
- return perspective.callRemote('add', 100, 23)
- d.addCallback(cbLogin)
-
- d.addCallback(self.assertEqual, 123)
-
- d.addCallback(self._disconnect, factory)
-
- connector = reactor.connectTCP('127.0.0.1', self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
- def test_view(self):
- """
- Verify that a viewpoint can be retrieved after authenticating with
- cred.
- """
- self.portal.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass'))
- factory = pb.PBClientFactory()
- d = factory.login(
- credentials.UsernamePassword("user", "pass"), "BRAINS!")
-
- def cbLogin(perspective):
- return perspective.callRemote("getViewPoint")
- d.addCallback(cbLogin)
-
- def cbView(viewpoint):
- return viewpoint.callRemote("check")
- d.addCallback(cbView)
-
- d.addCallback(self.assertTrue)
-
- d.addCallback(self._disconnect, factory)
-
- connector = reactor.connectTCP("127.0.0.1", self.portno, factory)
- self.addCleanup(connector.disconnect)
- return d
-
-
-
-class NonSubclassingPerspective:
- implements(pb.IPerspective)
-
- def __init__(self, avatarId):
- pass
-
- # IPerspective implementation
- def perspectiveMessageReceived(self, broker, message, args, kwargs):
- args = broker.unserialize(args, self)
- kwargs = broker.unserialize(kwargs, self)
- return broker.serialize((message, args, kwargs))
-
- # Methods required by TestRealm
- def logout(self):
- self.loggedOut = True
-
-
-
-class NSPTestCase(unittest.TestCase):
- """
- Tests for authentication against a realm where the L{IPerspective}
- implementation is not a subclass of L{Avatar}.
- """
- def setUp(self):
- self.realm = TestRealm()
- self.realm.perspectiveFactory = NonSubclassingPerspective
- self.portal = portal.Portal(self.realm)
- self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- self.checker.addUser("user", "pass")
- self.portal.registerChecker(self.checker)
- self.factory = WrappingFactory(pb.PBServerFactory(self.portal))
- self.port = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
- self.addCleanup(self.port.stopListening)
- self.portno = self.port.getHost().port
-
-
- def test_NSP(self):
- """
- An L{IPerspective} implementation which does not subclass
- L{Avatar} can expose remote methods for the client to call.
- """
- factory = pb.PBClientFactory()
- d = factory.login(credentials.UsernamePassword('user', 'pass'),
- "BRAINS!")
- reactor.connectTCP('127.0.0.1', self.portno, factory)
- d.addCallback(lambda p: p.callRemote('ANYTHING', 'here', bar='baz'))
- d.addCallback(self.assertEqual,
- ('ANYTHING', ('here',), {'bar': 'baz'}))
- def cleanup(ignored):
- factory.disconnect()
- for p in self.factory.protocols:
- p.transport.loseConnection()
- d.addCallback(cleanup)
- return d
-
-
-
-class IForwarded(Interface):
- """
- Interface used for testing L{util.LocalAsyncForwarder}.
- """
-
- def forwardMe():
- """
- Simple synchronous method.
- """
-
- def forwardDeferred():
- """
- Simple asynchronous method.
- """
-
-
-class Forwarded:
- """
- Test implementation of L{IForwarded}.
-
- @ivar forwarded: set if C{forwardMe} is called.
- @type forwarded: C{bool}
- @ivar unforwarded: set if C{dontForwardMe} is called.
- @type unforwarded: C{bool}
- """
- implements(IForwarded)
- forwarded = False
- unforwarded = False
-
- def forwardMe(self):
- """
- Set a local flag to test afterwards.
- """
- self.forwarded = True
-
- def dontForwardMe(self):
- """
- Set a local flag to test afterwards. This should not be called as it's
- not in the interface.
- """
- self.unforwarded = True
-
- def forwardDeferred(self):
- """
- Asynchronously return C{True}.
- """
- return succeed(True)
-
-
-class SpreadUtilTestCase(unittest.TestCase):
- """
- Tests for L{twisted.spread.util}.
- """
-
- def test_sync(self):
- """
- Call a synchronous method of a L{util.LocalAsRemote} object and check
- the result.
- """
- o = LocalRemoteTest()
- self.assertEqual(o.callRemote("add1", 2), 3)
-
- def test_async(self):
- """
- Call an asynchronous method of a L{util.LocalAsRemote} object and check
- the result.
- """
- o = LocalRemoteTest()
- o = LocalRemoteTest()
- d = o.callRemote("add", 2, y=4)
- self.assertIsInstance(d, Deferred)
- d.addCallback(self.assertEqual, 6)
- return d
-
- def test_asyncFail(self):
- """
- Test a asynchronous failure on a remote method call.
- """
- o = LocalRemoteTest()
- d = o.callRemote("fail")
- def eb(f):
- self.assertTrue(isinstance(f, failure.Failure))
- f.trap(RuntimeError)
- d.addCallbacks(lambda res: self.fail("supposed to fail"), eb)
- return d
-
- def test_remoteMethod(self):
- """
- Test the C{remoteMethod} facility of L{util.LocalAsRemote}.
- """
- o = LocalRemoteTest()
- m = o.remoteMethod("add1")
- self.assertEqual(m(3), 4)
-
- def test_localAsyncForwarder(self):
- """
- Test a call to L{util.LocalAsyncForwarder} using L{Forwarded} local
- object.
- """
- f = Forwarded()
- lf = util.LocalAsyncForwarder(f, IForwarded)
- lf.callRemote("forwardMe")
- self.assertTrue(f.forwarded)
- lf.callRemote("dontForwardMe")
- self.assertFalse(f.unforwarded)
- rr = lf.callRemote("forwardDeferred")
- l = []
- rr.addCallback(l.append)
- self.assertEqual(l[0], 1)
-
-
-
-class PBWithSecurityOptionsTest(unittest.TestCase):
- """
- Test security customization.
- """
-
- def test_clientDefaultSecurityOptions(self):
- """
- By default, client broker should use C{jelly.globalSecurity} as
- security settings.
- """
- factory = pb.PBClientFactory()
- broker = factory.buildProtocol(None)
- self.assertIdentical(broker.security, jelly.globalSecurity)
-
-
- def test_serverDefaultSecurityOptions(self):
- """
- By default, server broker should use C{jelly.globalSecurity} as
- security settings.
- """
- factory = pb.PBServerFactory(Echoer())
- broker = factory.buildProtocol(None)
- self.assertIdentical(broker.security, jelly.globalSecurity)
-
-
- def test_clientSecurityCustomization(self):
- """
- Check that the security settings are passed from the client factory to
- the broker object.
- """
- security = jelly.SecurityOptions()
- factory = pb.PBClientFactory(security=security)
- broker = factory.buildProtocol(None)
- self.assertIdentical(broker.security, security)
-
-
- def test_serverSecurityCustomization(self):
- """
- Check that the security settings are passed from the server factory to
- the broker object.
- """
- security = jelly.SecurityOptions()
- factory = pb.PBServerFactory(Echoer(), security=security)
- broker = factory.buildProtocol(None)
- self.assertIdentical(broker.security, security)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pbfailure.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pbfailure.py
deleted file mode 100755
index 91cd6ba2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pbfailure.py
+++ /dev/null
@@ -1,475 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for error handling in PB.
-"""
-
-import sys
-from StringIO import StringIO
-
-from twisted.trial import unittest
-
-from twisted.spread import pb, flavors, jelly
-from twisted.internet import reactor, defer
-from twisted.python import log
-
-##
-# test exceptions
-##
-class AsynchronousException(Exception):
- """
- Helper used to test remote methods which return Deferreds which fail with
- exceptions which are not L{pb.Error} subclasses.
- """
-
-
-class SynchronousException(Exception):
- """
- Helper used to test remote methods which raise exceptions which are not
- L{pb.Error} subclasses.
- """
-
-
-class AsynchronousError(pb.Error):
- """
- Helper used to test remote methods which return Deferreds which fail with
- exceptions which are L{pb.Error} subclasses.
- """
-
-
-class SynchronousError(pb.Error):
- """
- Helper used to test remote methods which raise exceptions which are
- L{pb.Error} subclasses.
- """
-
-
-#class JellyError(flavors.Jellyable, pb.Error): pass
-class JellyError(flavors.Jellyable, pb.Error, pb.RemoteCopy):
- pass
-
-
-class SecurityError(pb.Error, pb.RemoteCopy):
- pass
-
-pb.setUnjellyableForClass(JellyError, JellyError)
-pb.setUnjellyableForClass(SecurityError, SecurityError)
-pb.globalSecurity.allowInstancesOf(SecurityError)
-
-
-####
-# server-side
-####
-class SimpleRoot(pb.Root):
- def remote_asynchronousException(self):
- """
- Fail asynchronously with a non-pb.Error exception.
- """
- return defer.fail(AsynchronousException("remote asynchronous exception"))
-
- def remote_synchronousException(self):
- """
- Fail synchronously with a non-pb.Error exception.
- """
- raise SynchronousException("remote synchronous exception")
-
- def remote_asynchronousError(self):
- """
- Fail asynchronously with a pb.Error exception.
- """
- return defer.fail(AsynchronousError("remote asynchronous error"))
-
- def remote_synchronousError(self):
- """
- Fail synchronously with a pb.Error exception.
- """
- raise SynchronousError("remote synchronous error")
-
- def remote_unknownError(self):
- """
- Fail with error that is not known to client.
- """
- class UnknownError(pb.Error):
- pass
- raise UnknownError("I'm not known to client!")
-
- def remote_jelly(self):
- self.raiseJelly()
-
- def remote_security(self):
- self.raiseSecurity()
-
- def remote_deferredJelly(self):
- d = defer.Deferred()
- d.addCallback(self.raiseJelly)
- d.callback(None)
- return d
-
- def remote_deferredSecurity(self):
- d = defer.Deferred()
- d.addCallback(self.raiseSecurity)
- d.callback(None)
- return d
-
- def raiseJelly(self, results=None):
- raise JellyError("I'm jellyable!")
-
- def raiseSecurity(self, results=None):
- raise SecurityError("I'm secure!")
-
-
-
-class SaveProtocolServerFactory(pb.PBServerFactory):
- """
- A L{pb.PBServerFactory} that saves the latest connected client in
- C{protocolInstance}.
- """
- protocolInstance = None
-
- def clientConnectionMade(self, protocol):
- """
- Keep track of the given protocol.
- """
- self.protocolInstance = protocol
-
-
-
-class PBConnTestCase(unittest.TestCase):
- unsafeTracebacks = 0
-
- def setUp(self):
- self._setUpServer()
- self._setUpClient()
-
- def _setUpServer(self):
- self.serverFactory = SaveProtocolServerFactory(SimpleRoot())
- self.serverFactory.unsafeTracebacks = self.unsafeTracebacks
- self.serverPort = reactor.listenTCP(0, self.serverFactory, interface="127.0.0.1")
-
- def _setUpClient(self):
- portNo = self.serverPort.getHost().port
- self.clientFactory = pb.PBClientFactory()
- self.clientConnector = reactor.connectTCP("127.0.0.1", portNo, self.clientFactory)
-
- def tearDown(self):
- if self.serverFactory.protocolInstance is not None:
- self.serverFactory.protocolInstance.transport.loseConnection()
- return defer.gatherResults([
- self._tearDownServer(),
- self._tearDownClient()])
-
- def _tearDownServer(self):
- return defer.maybeDeferred(self.serverPort.stopListening)
-
- def _tearDownClient(self):
- self.clientConnector.disconnect()
- return defer.succeed(None)
-
-
-
-class PBFailureTest(PBConnTestCase):
- compare = unittest.TestCase.assertEqual
-
-
- def _exceptionTest(self, method, exceptionType, flush):
- def eb(err):
- err.trap(exceptionType)
- self.compare(err.traceback, "Traceback unavailable\n")
- if flush:
- errs = self.flushLoggedErrors(exceptionType)
- self.assertEqual(len(errs), 1)
- return (err.type, err.value, err.traceback)
- d = self.clientFactory.getRootObject()
- def gotRootObject(root):
- d = root.callRemote(method)
- d.addErrback(eb)
- return d
- d.addCallback(gotRootObject)
- return d
-
-
- def test_asynchronousException(self):
- """
- Test that a Deferred returned by a remote method which already has a
- Failure correctly has that error passed back to the calling side.
- """
- return self._exceptionTest(
- 'asynchronousException', AsynchronousException, True)
-
-
- def test_synchronousException(self):
- """
- Like L{test_asynchronousException}, but for a method which raises an
- exception synchronously.
- """
- return self._exceptionTest(
- 'synchronousException', SynchronousException, True)
-
-
- def test_asynchronousError(self):
- """
- Like L{test_asynchronousException}, but for a method which returns a
- Deferred failing with an L{pb.Error} subclass.
- """
- return self._exceptionTest(
- 'asynchronousError', AsynchronousError, False)
-
-
- def test_synchronousError(self):
- """
- Like L{test_asynchronousError}, but for a method which synchronously
- raises a L{pb.Error} subclass.
- """
- return self._exceptionTest(
- 'synchronousError', SynchronousError, False)
-
-
- def _success(self, result, expectedResult):
- self.assertEqual(result, expectedResult)
- return result
-
-
- def _addFailingCallbacks(self, remoteCall, expectedResult, eb):
- remoteCall.addCallbacks(self._success, eb,
- callbackArgs=(expectedResult,))
- return remoteCall
-
-
- def _testImpl(self, method, expected, eb, exc=None):
- """
- Call the given remote method and attach the given errback to the
- resulting Deferred. If C{exc} is not None, also assert that one
- exception of that type was logged.
- """
- rootDeferred = self.clientFactory.getRootObject()
- def gotRootObj(obj):
- failureDeferred = self._addFailingCallbacks(obj.callRemote(method), expected, eb)
- if exc is not None:
- def gotFailure(err):
- self.assertEqual(len(self.flushLoggedErrors(exc)), 1)
- return err
- failureDeferred.addBoth(gotFailure)
- return failureDeferred
- rootDeferred.addCallback(gotRootObj)
- return rootDeferred
-
-
- def test_jellyFailure(self):
- """
- Test that an exception which is a subclass of L{pb.Error} has more
- information passed across the network to the calling side.
- """
- def failureJelly(fail):
- fail.trap(JellyError)
- self.failIf(isinstance(fail.type, str))
- self.failUnless(isinstance(fail.value, fail.type))
- return 43
- return self._testImpl('jelly', 43, failureJelly)
-
-
- def test_deferredJellyFailure(self):
- """
- Test that a Deferred which fails with a L{pb.Error} is treated in
- the same way as a synchronously raised L{pb.Error}.
- """
- def failureDeferredJelly(fail):
- fail.trap(JellyError)
- self.failIf(isinstance(fail.type, str))
- self.failUnless(isinstance(fail.value, fail.type))
- return 430
- return self._testImpl('deferredJelly', 430, failureDeferredJelly)
-
-
- def test_unjellyableFailure(self):
- """
- An non-jellyable L{pb.Error} subclass raised by a remote method is
- turned into a Failure with a type set to the FQPN of the exception
- type.
- """
- def failureUnjellyable(fail):
- self.assertEqual(
- fail.type, 'twisted.test.test_pbfailure.SynchronousError')
- return 431
- return self._testImpl('synchronousError', 431, failureUnjellyable)
-
-
- def test_unknownFailure(self):
- """
- Test that an exception which is a subclass of L{pb.Error} but not
- known on the client side has its type set properly.
- """
- def failureUnknown(fail):
- self.assertEqual(
- fail.type, 'twisted.test.test_pbfailure.UnknownError')
- return 4310
- return self._testImpl('unknownError', 4310, failureUnknown)
-
-
- def test_securityFailure(self):
- """
- Test that even if an exception is not explicitly jellyable (by being
- a L{pb.Jellyable} subclass), as long as it is an L{pb.Error}
- subclass it receives the same special treatment.
- """
- def failureSecurity(fail):
- fail.trap(SecurityError)
- self.failIf(isinstance(fail.type, str))
- self.failUnless(isinstance(fail.value, fail.type))
- return 4300
- return self._testImpl('security', 4300, failureSecurity)
-
-
- def test_deferredSecurity(self):
- """
- Test that a Deferred which fails with a L{pb.Error} which is not
- also a L{pb.Jellyable} is treated in the same way as a synchronously
- raised exception of the same type.
- """
- def failureDeferredSecurity(fail):
- fail.trap(SecurityError)
- self.failIf(isinstance(fail.type, str))
- self.failUnless(isinstance(fail.value, fail.type))
- return 43000
- return self._testImpl('deferredSecurity', 43000, failureDeferredSecurity)
-
-
- def test_noSuchMethodFailure(self):
- """
- Test that attempting to call a method which is not defined correctly
- results in an AttributeError on the calling side.
- """
- def failureNoSuch(fail):
- fail.trap(pb.NoSuchMethod)
- self.compare(fail.traceback, "Traceback unavailable\n")
- return 42000
- return self._testImpl('nosuch', 42000, failureNoSuch, AttributeError)
-
-
- def test_copiedFailureLogging(self):
- """
- Test that a copied failure received from a PB call can be logged
- locally.
-
- Note: this test needs some serious help: all it really tests is that
- log.err(copiedFailure) doesn't raise an exception.
- """
- d = self.clientFactory.getRootObject()
-
- def connected(rootObj):
- return rootObj.callRemote('synchronousException')
- d.addCallback(connected)
-
- def exception(failure):
- log.err(failure)
- errs = self.flushLoggedErrors(SynchronousException)
- self.assertEqual(len(errs), 2)
- d.addErrback(exception)
-
- return d
-
-
- def test_throwExceptionIntoGenerator(self):
- """
- L{pb.CopiedFailure.throwExceptionIntoGenerator} will throw a
- L{RemoteError} into the given paused generator at the point where it
- last yielded.
- """
- original = pb.CopyableFailure(AttributeError("foo"))
- copy = jelly.unjelly(jelly.jelly(original, invoker=DummyInvoker()))
- exception = []
- def generatorFunc():
- try:
- yield None
- except pb.RemoteError, exc:
- exception.append(exc)
- else:
- self.fail("RemoteError not raised")
- gen = generatorFunc()
- gen.send(None)
- self.assertRaises(StopIteration, copy.throwExceptionIntoGenerator, gen)
- self.assertEqual(len(exception), 1)
- exc = exception[0]
- self.assertEqual(exc.remoteType, "exceptions.AttributeError")
- self.assertEqual(exc.args, ("foo",))
- self.assertEqual(exc.remoteTraceback, 'Traceback unavailable\n')
-
- if sys.version_info[:2] < (2, 5):
- test_throwExceptionIntoGenerator.skip = (
- "throwExceptionIntoGenerator is not supported in Python < 2.5")
-
-
-
-class PBFailureTestUnsafe(PBFailureTest):
- compare = unittest.TestCase.failIfEquals
- unsafeTracebacks = 1
-
-
-
-class DummyInvoker(object):
- """
- A behaviorless object to be used as the invoker parameter to
- L{jelly.jelly}.
- """
- serializingPerspective = None
-
-
-
-class FailureJellyingTests(unittest.TestCase):
- """
- Tests for the interaction of jelly and failures.
- """
- def test_unjelliedFailureCheck(self):
- """
- An unjellied L{CopyableFailure} has a check method which behaves the
- same way as the original L{CopyableFailure}'s check method.
- """
- original = pb.CopyableFailure(ZeroDivisionError())
- self.assertIdentical(
- original.check(ZeroDivisionError), ZeroDivisionError)
- self.assertIdentical(original.check(ArithmeticError), ArithmeticError)
- copied = jelly.unjelly(jelly.jelly(original, invoker=DummyInvoker()))
- self.assertIdentical(
- copied.check(ZeroDivisionError), ZeroDivisionError)
- self.assertIdentical(copied.check(ArithmeticError), ArithmeticError)
-
-
- def test_twiceUnjelliedFailureCheck(self):
- """
- The object which results from jellying a L{CopyableFailure}, unjellying
- the result, creating a new L{CopyableFailure} from the result of that,
- jellying it, and finally unjellying the result of that has a check
- method which behaves the same way as the original L{CopyableFailure}'s
- check method.
- """
- original = pb.CopyableFailure(ZeroDivisionError())
- self.assertIdentical(
- original.check(ZeroDivisionError), ZeroDivisionError)
- self.assertIdentical(original.check(ArithmeticError), ArithmeticError)
- copiedOnce = jelly.unjelly(
- jelly.jelly(original, invoker=DummyInvoker()))
- derivative = pb.CopyableFailure(copiedOnce)
- copiedTwice = jelly.unjelly(
- jelly.jelly(derivative, invoker=DummyInvoker()))
- self.assertIdentical(
- copiedTwice.check(ZeroDivisionError), ZeroDivisionError)
- self.assertIdentical(
- copiedTwice.check(ArithmeticError), ArithmeticError)
-
-
- def test_printTracebackIncludesValue(self):
- """
- When L{CopiedFailure.printTraceback} is used to print a copied failure
- which was unjellied from a L{CopyableFailure} with C{unsafeTracebacks}
- set to C{False}, the string representation of the exception value is
- included in the output.
- """
- original = pb.CopyableFailure(Exception("some reason"))
- copied = jelly.unjelly(jelly.jelly(original, invoker=DummyInvoker()))
- output = StringIO()
- copied.printTraceback(output)
- self.assertEqual(
- "Traceback from remote host -- Traceback unavailable\n"
- "exceptions.Exception: some reason\n",
- output.getvalue())
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pcp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pcp.py
deleted file mode 100755
index 71de8bbc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_pcp.py
+++ /dev/null
@@ -1,368 +0,0 @@
-# -*- Python -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-__version__ = '$Revision: 1.5 $'[11:-2]
-
-from StringIO import StringIO
-from twisted.trial import unittest
-from twisted.protocols import pcp
-
-# Goal:
-
-# Take a Protocol instance. Own all outgoing data - anything that
-# would go to p.transport.write. Own all incoming data - anything
-# that comes to p.dataReceived.
-
-# I need:
-# Something with the AbstractFileDescriptor interface.
-# That is:
-# - acts as a Transport
-# - has a method write()
-# - which buffers
-# - acts as a Consumer
-# - has a registerProducer, unRegisterProducer
-# - tells the Producer to back off (pauseProducing) when its buffer is full.
-# - tells the Producer to resumeProducing when its buffer is not so full.
-# - acts as a Producer
-# - calls registerProducer
-# - calls write() on consumers
-# - honors requests to pause/resume producing
-# - honors stopProducing, and passes it along to upstream Producers
-
-
-class DummyTransport:
- """A dumb transport to wrap around."""
-
- def __init__(self):
- self._writes = []
-
- def write(self, data):
- self._writes.append(data)
-
- def getvalue(self):
- return ''.join(self._writes)
-
-class DummyProducer:
- resumed = False
- stopped = False
- paused = False
-
- def __init__(self, consumer):
- self.consumer = consumer
-
- def resumeProducing(self):
- self.resumed = True
- self.paused = False
-
- def pauseProducing(self):
- self.paused = True
-
- def stopProducing(self):
- self.stopped = True
-
-
-class DummyConsumer(DummyTransport):
- producer = None
- finished = False
- unregistered = True
-
- def registerProducer(self, producer, streaming):
- self.producer = (producer, streaming)
-
- def unregisterProducer(self):
- self.unregistered = True
-
- def finish(self):
- self.finished = True
-
-class TransportInterfaceTest(unittest.TestCase):
- proxyClass = pcp.BasicProducerConsumerProxy
-
- def setUp(self):
- self.underlying = DummyConsumer()
- self.transport = self.proxyClass(self.underlying)
-
- def testWrite(self):
- self.transport.write("some bytes")
-
-class ConsumerInterfaceTest:
- """Test ProducerConsumerProxy as a Consumer.
-
- Normally we have ProducingServer -> ConsumingTransport.
-
- If I am to go between (Server -> Shaper -> Transport), I have to
- play the role of Consumer convincingly for the ProducingServer.
- """
-
- def setUp(self):
- self.underlying = DummyConsumer()
- self.consumer = self.proxyClass(self.underlying)
- self.producer = DummyProducer(self.consumer)
-
- def testRegisterPush(self):
- self.consumer.registerProducer(self.producer, True)
- ## Consumer should NOT have called PushProducer.resumeProducing
- self.failIf(self.producer.resumed)
-
- ## I'm I'm just a proxy, should I only do resumeProducing when
- ## I get poked myself?
- #def testRegisterPull(self):
- # self.consumer.registerProducer(self.producer, False)
- # ## Consumer SHOULD have called PushProducer.resumeProducing
- # self.failUnless(self.producer.resumed)
-
- def testUnregister(self):
- self.consumer.registerProducer(self.producer, False)
- self.consumer.unregisterProducer()
- # Now when the consumer would ordinarily want more data, it
- # shouldn't ask producer for it.
- # The most succinct way to trigger "want more data" is to proxy for
- # a PullProducer and have someone ask me for data.
- self.producer.resumed = False
- self.consumer.resumeProducing()
- self.failIf(self.producer.resumed)
-
- def testFinish(self):
- self.consumer.registerProducer(self.producer, False)
- self.consumer.finish()
- # I guess finish should behave like unregister?
- self.producer.resumed = False
- self.consumer.resumeProducing()
- self.failIf(self.producer.resumed)
-
-
-class ProducerInterfaceTest:
- """Test ProducerConsumerProxy as a Producer.
-
- Normally we have ProducingServer -> ConsumingTransport.
-
- If I am to go between (Server -> Shaper -> Transport), I have to
- play the role of Producer convincingly for the ConsumingTransport.
- """
-
- def setUp(self):
- self.consumer = DummyConsumer()
- self.producer = self.proxyClass(self.consumer)
-
- def testRegistersProducer(self):
- self.assertEqual(self.consumer.producer[0], self.producer)
-
- def testPause(self):
- self.producer.pauseProducing()
- self.producer.write("yakkity yak")
- self.failIf(self.consumer.getvalue(),
- "Paused producer should not have sent data.")
-
- def testResume(self):
- self.producer.pauseProducing()
- self.producer.resumeProducing()
- self.producer.write("yakkity yak")
- self.assertEqual(self.consumer.getvalue(), "yakkity yak")
-
- def testResumeNoEmptyWrite(self):
- self.producer.pauseProducing()
- self.producer.resumeProducing()
- self.assertEqual(len(self.consumer._writes), 0,
- "Resume triggered an empty write.")
-
- def testResumeBuffer(self):
- self.producer.pauseProducing()
- self.producer.write("buffer this")
- self.producer.resumeProducing()
- self.assertEqual(self.consumer.getvalue(), "buffer this")
-
- def testStop(self):
- self.producer.stopProducing()
- self.producer.write("yakkity yak")
- self.failIf(self.consumer.getvalue(),
- "Stopped producer should not have sent data.")
-
-
-class PCP_ConsumerInterfaceTest(ConsumerInterfaceTest, unittest.TestCase):
- proxyClass = pcp.BasicProducerConsumerProxy
-
-class PCPII_ConsumerInterfaceTest(ConsumerInterfaceTest, unittest.TestCase):
- proxyClass = pcp.ProducerConsumerProxy
-
-class PCP_ProducerInterfaceTest(ProducerInterfaceTest, unittest.TestCase):
- proxyClass = pcp.BasicProducerConsumerProxy
-
-class PCPII_ProducerInterfaceTest(ProducerInterfaceTest, unittest.TestCase):
- proxyClass = pcp.ProducerConsumerProxy
-
-class ProducerProxyTest(unittest.TestCase):
- """Producer methods on me should be relayed to the Producer I proxy.
- """
- proxyClass = pcp.BasicProducerConsumerProxy
-
- def setUp(self):
- self.proxy = self.proxyClass(None)
- self.parentProducer = DummyProducer(self.proxy)
- self.proxy.registerProducer(self.parentProducer, True)
-
- def testStop(self):
- self.proxy.stopProducing()
- self.failUnless(self.parentProducer.stopped)
-
-
-class ConsumerProxyTest(unittest.TestCase):
- """Consumer methods on me should be relayed to the Consumer I proxy.
- """
- proxyClass = pcp.BasicProducerConsumerProxy
-
- def setUp(self):
- self.underlying = DummyConsumer()
- self.consumer = self.proxyClass(self.underlying)
-
- def testWrite(self):
- # NOTE: This test only valid for streaming (Push) systems.
- self.consumer.write("some bytes")
- self.assertEqual(self.underlying.getvalue(), "some bytes")
-
- def testFinish(self):
- self.consumer.finish()
- self.failUnless(self.underlying.finished)
-
- def testUnregister(self):
- self.consumer.unregisterProducer()
- self.failUnless(self.underlying.unregistered)
-
-
-class PullProducerTest:
- def setUp(self):
- self.underlying = DummyConsumer()
- self.proxy = self.proxyClass(self.underlying)
- self.parentProducer = DummyProducer(self.proxy)
- self.proxy.registerProducer(self.parentProducer, True)
-
- def testHoldWrites(self):
- self.proxy.write("hello")
- # Consumer should get no data before it says resumeProducing.
- self.failIf(self.underlying.getvalue(),
- "Pulling Consumer got data before it pulled.")
-
- def testPull(self):
- self.proxy.write("hello")
- self.proxy.resumeProducing()
- self.assertEqual(self.underlying.getvalue(), "hello")
-
- def testMergeWrites(self):
- self.proxy.write("hello ")
- self.proxy.write("sunshine")
- self.proxy.resumeProducing()
- nwrites = len(self.underlying._writes)
- self.assertEqual(nwrites, 1, "Pull resulted in %d writes instead "
- "of 1." % (nwrites,))
- self.assertEqual(self.underlying.getvalue(), "hello sunshine")
-
-
- def testLateWrite(self):
- # consumer sends its initial pull before we have data
- self.proxy.resumeProducing()
- self.proxy.write("data")
- # This data should answer that pull request.
- self.assertEqual(self.underlying.getvalue(), "data")
-
-class PCP_PullProducerTest(PullProducerTest, unittest.TestCase):
- class proxyClass(pcp.BasicProducerConsumerProxy):
- iAmStreaming = False
-
-class PCPII_PullProducerTest(PullProducerTest, unittest.TestCase):
- class proxyClass(pcp.ProducerConsumerProxy):
- iAmStreaming = False
-
-# Buffering!
-
-class BufferedConsumerTest(unittest.TestCase):
- """As a consumer, ask the producer to pause after too much data."""
-
- proxyClass = pcp.ProducerConsumerProxy
-
- def setUp(self):
- self.underlying = DummyConsumer()
- self.proxy = self.proxyClass(self.underlying)
- self.proxy.bufferSize = 100
-
- self.parentProducer = DummyProducer(self.proxy)
- self.proxy.registerProducer(self.parentProducer, True)
-
- def testRegisterPull(self):
- self.proxy.registerProducer(self.parentProducer, False)
- ## Consumer SHOULD have called PushProducer.resumeProducing
- self.failUnless(self.parentProducer.resumed)
-
- def testPauseIntercept(self):
- self.proxy.pauseProducing()
- self.failIf(self.parentProducer.paused)
-
- def testResumeIntercept(self):
- self.proxy.pauseProducing()
- self.proxy.resumeProducing()
- # With a streaming producer, just because the proxy was resumed is
- # not necessarily a reason to resume the parent producer. The state
- # of the buffer should decide that.
- self.failIf(self.parentProducer.resumed)
-
- def testTriggerPause(self):
- """Make sure I say \"when.\""""
-
- # Pause the proxy so data sent to it builds up in its buffer.
- self.proxy.pauseProducing()
- self.failIf(self.parentProducer.paused, "don't pause yet")
- self.proxy.write("x" * 51)
- self.failIf(self.parentProducer.paused, "don't pause yet")
- self.proxy.write("x" * 51)
- self.failUnless(self.parentProducer.paused)
-
- def testTriggerResume(self):
- """Make sure I resumeProducing when my buffer empties."""
- self.proxy.pauseProducing()
- self.proxy.write("x" * 102)
- self.failUnless(self.parentProducer.paused, "should be paused")
- self.proxy.resumeProducing()
- # Resuming should have emptied my buffer, so I should tell my
- # parent to resume too.
- self.failIf(self.parentProducer.paused,
- "Producer should have resumed.")
- self.failIf(self.proxy.producerPaused)
-
-class BufferedPullTests(unittest.TestCase):
- class proxyClass(pcp.ProducerConsumerProxy):
- iAmStreaming = False
-
- def _writeSomeData(self, data):
- pcp.ProducerConsumerProxy._writeSomeData(self, data[:100])
- return min(len(data), 100)
-
- def setUp(self):
- self.underlying = DummyConsumer()
- self.proxy = self.proxyClass(self.underlying)
- self.proxy.bufferSize = 100
-
- self.parentProducer = DummyProducer(self.proxy)
- self.proxy.registerProducer(self.parentProducer, False)
-
- def testResumePull(self):
- # If proxy has no data to send on resumeProducing, it had better pull
- # some from its PullProducer.
- self.parentProducer.resumed = False
- self.proxy.resumeProducing()
- self.failUnless(self.parentProducer.resumed)
-
- def testLateWriteBuffering(self):
- # consumer sends its initial pull before we have data
- self.proxy.resumeProducing()
- self.proxy.write("datum" * 21)
- # This data should answer that pull request.
- self.assertEqual(self.underlying.getvalue(), "datum" * 20)
- # but there should be some left over
- self.assertEqual(self.proxy._buffer, ["datum"])
-
-
-# TODO:
-# test that web request finishing bug (when we weren't proxying
-# unregisterProducer but were proxying finish, web file transfers
-# would hang on the last block.)
-# test what happens if writeSomeBytes decided to write zero bytes.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_persisted.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_persisted.py
deleted file mode 100755
index 4a80791b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_persisted.py
+++ /dev/null
@@ -1,377 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-# System Imports
-import sys
-
-from twisted.trial import unittest
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-# Twisted Imports
-from twisted.persisted import styles, aot, crefutil
-
-
-class VersionTestCase(unittest.TestCase):
- def testNullVersionUpgrade(self):
- global NullVersioned
- class NullVersioned:
- ok = 0
- pkcl = pickle.dumps(NullVersioned())
- class NullVersioned(styles.Versioned):
- persistenceVersion = 1
- def upgradeToVersion1(self):
- self.ok = 1
- mnv = pickle.loads(pkcl)
- styles.doUpgrade()
- assert mnv.ok, "initial upgrade not run!"
-
- def testVersionUpgrade(self):
- global MyVersioned
- class MyVersioned(styles.Versioned):
- persistenceVersion = 2
- persistenceForgets = ['garbagedata']
- v3 = 0
- v4 = 0
-
- def __init__(self):
- self.somedata = 'xxx'
- self.garbagedata = lambda q: 'cant persist'
-
- def upgradeToVersion3(self):
- self.v3 += 1
-
- def upgradeToVersion4(self):
- self.v4 += 1
- mv = MyVersioned()
- assert not (mv.v3 or mv.v4), "hasn't been upgraded yet"
- pickl = pickle.dumps(mv)
- MyVersioned.persistenceVersion = 4
- obj = pickle.loads(pickl)
- styles.doUpgrade()
- assert obj.v3, "didn't do version 3 upgrade"
- assert obj.v4, "didn't do version 4 upgrade"
- pickl = pickle.dumps(obj)
- obj = pickle.loads(pickl)
- styles.doUpgrade()
- assert obj.v3 == 1, "upgraded unnecessarily"
- assert obj.v4 == 1, "upgraded unnecessarily"
-
- def testNonIdentityHash(self):
- global ClassWithCustomHash
- class ClassWithCustomHash(styles.Versioned):
- def __init__(self, unique, hash):
- self.unique = unique
- self.hash = hash
- def __hash__(self):
- return self.hash
-
- v1 = ClassWithCustomHash('v1', 0)
- v2 = ClassWithCustomHash('v2', 0)
-
- pkl = pickle.dumps((v1, v2))
- del v1, v2
- ClassWithCustomHash.persistenceVersion = 1
- ClassWithCustomHash.upgradeToVersion1 = lambda self: setattr(self, 'upgraded', True)
- v1, v2 = pickle.loads(pkl)
- styles.doUpgrade()
- self.assertEqual(v1.unique, 'v1')
- self.assertEqual(v2.unique, 'v2')
- self.failUnless(v1.upgraded)
- self.failUnless(v2.upgraded)
-
- def testUpgradeDeserializesObjectsRequiringUpgrade(self):
- global ToyClassA, ToyClassB
- class ToyClassA(styles.Versioned):
- pass
- class ToyClassB(styles.Versioned):
- pass
- x = ToyClassA()
- y = ToyClassB()
- pklA, pklB = pickle.dumps(x), pickle.dumps(y)
- del x, y
- ToyClassA.persistenceVersion = 1
- def upgradeToVersion1(self):
- self.y = pickle.loads(pklB)
- styles.doUpgrade()
- ToyClassA.upgradeToVersion1 = upgradeToVersion1
- ToyClassB.persistenceVersion = 1
- ToyClassB.upgradeToVersion1 = lambda self: setattr(self, 'upgraded', True)
-
- x = pickle.loads(pklA)
- styles.doUpgrade()
- self.failUnless(x.y.upgraded)
-
-
-
-class VersionedSubClass(styles.Versioned):
- pass
-
-
-
-class SecondVersionedSubClass(styles.Versioned):
- pass
-
-
-
-class VersionedSubSubClass(VersionedSubClass):
- pass
-
-
-
-class VersionedDiamondSubClass(VersionedSubSubClass, SecondVersionedSubClass):
- pass
-
-
-
-class AybabtuTests(unittest.TestCase):
- """
- L{styles._aybabtu} gets all of classes in the inheritance hierarchy of its
- argument that are strictly between L{Versioned} and the class itself.
- """
-
- def test_aybabtuStrictEmpty(self):
- """
- L{styles._aybabtu} of L{Versioned} itself is an empty list.
- """
- self.assertEqual(styles._aybabtu(styles.Versioned), [])
-
-
- def test_aybabtuStrictSubclass(self):
- """
- There are no classes I{between} L{VersionedSubClass} and L{Versioned},
- so L{styles._aybabtu} returns an empty list.
- """
- self.assertEqual(styles._aybabtu(VersionedSubClass), [])
-
-
- def test_aybabtuSubsubclass(self):
- """
- With a sub-sub-class of L{Versioned}, L{styles._aybabtu} returns a list
- containing the intervening subclass.
- """
- self.assertEqual(styles._aybabtu(VersionedSubSubClass),
- [VersionedSubClass])
-
-
- def test_aybabtuStrict(self):
- """
- For a diamond-shaped inheritance graph, L{styles._aybabtu} returns a
- list containing I{both} intermediate subclasses.
- """
- self.assertEqual(
- styles._aybabtu(VersionedDiamondSubClass),
- [VersionedSubSubClass, VersionedSubClass, SecondVersionedSubClass])
-
-
-
-class MyEphemeral(styles.Ephemeral):
-
- def __init__(self, x):
- self.x = x
-
-
-class EphemeralTestCase(unittest.TestCase):
-
- def testEphemeral(self):
- o = MyEphemeral(3)
- self.assertEqual(o.__class__, MyEphemeral)
- self.assertEqual(o.x, 3)
-
- pickl = pickle.dumps(o)
- o = pickle.loads(pickl)
-
- self.assertEqual(o.__class__, styles.Ephemeral)
- self.assert_(not hasattr(o, 'x'))
-
-
-class Pickleable:
-
- def __init__(self, x):
- self.x = x
-
- def getX(self):
- return self.x
-
-class A:
- """
- dummy class
- """
- def amethod(self):
- pass
-
-class B:
- """
- dummy class
- """
- def bmethod(self):
- pass
-
-def funktion():
- pass
-
-class PicklingTestCase(unittest.TestCase):
- """Test pickling of extra object types."""
-
- def testModule(self):
- pickl = pickle.dumps(styles)
- o = pickle.loads(pickl)
- self.assertEqual(o, styles)
-
- def testClassMethod(self):
- pickl = pickle.dumps(Pickleable.getX)
- o = pickle.loads(pickl)
- self.assertEqual(o, Pickleable.getX)
-
- def testInstanceMethod(self):
- obj = Pickleable(4)
- pickl = pickle.dumps(obj.getX)
- o = pickle.loads(pickl)
- self.assertEqual(o(), 4)
- self.assertEqual(type(o), type(obj.getX))
-
- def testStringIO(self):
- f = StringIO.StringIO()
- f.write("abc")
- pickl = pickle.dumps(f)
- o = pickle.loads(pickl)
- self.assertEqual(type(o), type(f))
- self.assertEqual(f.getvalue(), "abc")
-
-
-class EvilSourceror:
- def __init__(self, x):
- self.a = self
- self.a.b = self
- self.a.b.c = x
-
-class NonDictState:
- def __getstate__(self):
- return self.state
- def __setstate__(self, state):
- self.state = state
-
-class AOTTestCase(unittest.TestCase):
- def testSimpleTypes(self):
- obj = (1, 2.0, 3j, True, slice(1, 2, 3), 'hello', u'world', sys.maxint + 1, None, Ellipsis)
- rtObj = aot.unjellyFromSource(aot.jellyToSource(obj))
- self.assertEqual(obj, rtObj)
-
- def testMethodSelfIdentity(self):
- a = A()
- b = B()
- a.bmethod = b.bmethod
- b.a = a
- im_ = aot.unjellyFromSource(aot.jellyToSource(b)).a.bmethod
- self.assertEqual(im_.im_class, im_.im_self.__class__)
-
-
- def test_methodNotSelfIdentity(self):
- """
- If a class change after an instance has been created,
- L{aot.unjellyFromSource} shoud raise a C{TypeError} when trying to
- unjelly the instance.
- """
- a = A()
- b = B()
- a.bmethod = b.bmethod
- b.a = a
- savedbmethod = B.bmethod
- del B.bmethod
- try:
- self.assertRaises(TypeError, aot.unjellyFromSource,
- aot.jellyToSource(b))
- finally:
- B.bmethod = savedbmethod
-
-
- def test_unsupportedType(self):
- """
- L{aot.jellyToSource} should raise a C{TypeError} when trying to jelly
- an unknown type.
- """
- try:
- set
- except:
- from sets import Set as set
- self.assertRaises(TypeError, aot.jellyToSource, set())
-
-
- def testBasicIdentity(self):
- # Anyone wanting to make this datastructure more complex, and thus this
- # test more comprehensive, is welcome to do so.
- aj = aot.AOTJellier().jellyToAO
- d = {'hello': 'world', "method": aj}
- l = [1, 2, 3,
- "he\tllo\n\n\"x world!",
- u"goodbye \n\t\u1010 world!",
- 1, 1.0, 100 ** 100l, unittest, aot.AOTJellier, d,
- funktion
- ]
- t = tuple(l)
- l.append(l)
- l.append(t)
- l.append(t)
- uj = aot.unjellyFromSource(aot.jellyToSource([l, l]))
- assert uj[0] is uj[1]
- assert uj[1][0:5] == l[0:5]
-
-
- def testNonDictState(self):
- a = NonDictState()
- a.state = "meringue!"
- assert aot.unjellyFromSource(aot.jellyToSource(a)).state == a.state
-
- def testCopyReg(self):
- s = "foo_bar"
- sio = StringIO.StringIO()
- sio.write(s)
- uj = aot.unjellyFromSource(aot.jellyToSource(sio))
- # print repr(uj.__dict__)
- assert uj.getvalue() == s
-
- def testFunkyReferences(self):
- o = EvilSourceror(EvilSourceror([]))
- j1 = aot.jellyToAOT(o)
- oj = aot.unjellyFromAOT(j1)
-
- assert oj.a is oj
- assert oj.a.b is oj.b
- assert oj.c is not oj.c.c
-
-
-class CrefUtilTestCase(unittest.TestCase):
- """
- Tests for L{crefutil}.
- """
-
- def test_dictUnknownKey(self):
- """
- L{crefutil._DictKeyAndValue} only support keys C{0} and C{1}.
- """
- d = crefutil._DictKeyAndValue({})
- self.assertRaises(RuntimeError, d.__setitem__, 2, 3)
-
-
- def test_deferSetMultipleTimes(self):
- """
- L{crefutil._Defer} can be assigned a key only one time.
- """
- d = crefutil._Defer()
- d[0] = 1
- self.assertRaises(RuntimeError, d.__setitem__, 0, 1)
-
-
-
-testCases = [VersionTestCase, EphemeralTestCase, PicklingTestCase]
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_plugin.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_plugin.py
deleted file mode 100755
index c33ecf1c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_plugin.py
+++ /dev/null
@@ -1,719 +0,0 @@
-# Copyright (c) 2005 Divmod, Inc.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for Twisted plugin system.
-"""
-
-import sys, errno, os, time
-import compileall
-
-from zope.interface import Interface
-
-from twisted.trial import unittest
-from twisted.python.log import textFromEventDict, addObserver, removeObserver
-from twisted.python.filepath import FilePath
-from twisted.python.util import mergeFunctionMetadata
-
-from twisted import plugin
-
-
-
-class ITestPlugin(Interface):
- """
- A plugin for use by the plugin system's unit tests.
-
- Do not use this.
- """
-
-
-
-class ITestPlugin2(Interface):
- """
- See L{ITestPlugin}.
- """
-
-
-
-class PluginTestCase(unittest.TestCase):
- """
- Tests which verify the behavior of the current, active Twisted plugins
- directory.
- """
-
- def setUp(self):
- """
- Save C{sys.path} and C{sys.modules}, and create a package for tests.
- """
- self.originalPath = sys.path[:]
- self.savedModules = sys.modules.copy()
-
- self.root = FilePath(self.mktemp())
- self.root.createDirectory()
- self.package = self.root.child('mypackage')
- self.package.createDirectory()
- self.package.child('__init__.py').setContent("")
-
- FilePath(__file__).sibling('plugin_basic.py'
- ).copyTo(self.package.child('testplugin.py'))
-
- self.originalPlugin = "testplugin"
-
- sys.path.insert(0, self.root.path)
- import mypackage
- self.module = mypackage
-
-
- def tearDown(self):
- """
- Restore C{sys.path} and C{sys.modules} to their original values.
- """
- sys.path[:] = self.originalPath
- sys.modules.clear()
- sys.modules.update(self.savedModules)
-
-
- def _unimportPythonModule(self, module, deleteSource=False):
- modulePath = module.__name__.split('.')
- packageName = '.'.join(modulePath[:-1])
- moduleName = modulePath[-1]
-
- delattr(sys.modules[packageName], moduleName)
- del sys.modules[module.__name__]
- for ext in ['c', 'o'] + (deleteSource and [''] or []):
- try:
- os.remove(module.__file__ + ext)
- except OSError, ose:
- if ose.errno != errno.ENOENT:
- raise
-
-
- def _clearCache(self):
- """
- Remove the plugins B{droping.cache} file.
- """
- self.package.child('dropin.cache').remove()
-
-
- def _withCacheness(meth):
- """
- This is a paranoid test wrapper, that calls C{meth} 2 times, clear the
- cache, and calls it 2 other times. It's supposed to ensure that the
- plugin system behaves correctly no matter what the state of the cache
- is.
- """
- def wrapped(self):
- meth(self)
- meth(self)
- self._clearCache()
- meth(self)
- meth(self)
- return mergeFunctionMetadata(meth, wrapped)
-
-
- def test_cache(self):
- """
- Check that the cache returned by L{plugin.getCache} hold the plugin
- B{testplugin}, and that this plugin has the properties we expect:
- provide L{TestPlugin}, has the good name and description, and can be
- loaded successfully.
- """
- cache = plugin.getCache(self.module)
-
- dropin = cache[self.originalPlugin]
- self.assertEqual(dropin.moduleName,
- 'mypackage.%s' % (self.originalPlugin,))
- self.assertIn("I'm a test drop-in.", dropin.description)
-
- # Note, not the preferred way to get a plugin by its interface.
- p1 = [p for p in dropin.plugins if ITestPlugin in p.provided][0]
- self.assertIdentical(p1.dropin, dropin)
- self.assertEqual(p1.name, "TestPlugin")
-
- # Check the content of the description comes from the plugin module
- # docstring
- self.assertEqual(
- p1.description.strip(),
- "A plugin used solely for testing purposes.")
- self.assertEqual(p1.provided, [ITestPlugin, plugin.IPlugin])
- realPlugin = p1.load()
- # The plugin should match the class present in sys.modules
- self.assertIdentical(
- realPlugin,
- sys.modules['mypackage.%s' % (self.originalPlugin,)].TestPlugin)
-
- # And it should also match if we import it classicly
- import mypackage.testplugin as tp
- self.assertIdentical(realPlugin, tp.TestPlugin)
-
- test_cache = _withCacheness(test_cache)
-
-
- def test_plugins(self):
- """
- L{plugin.getPlugins} should return the list of plugins matching the
- specified interface (here, L{ITestPlugin2}), and these plugins
- should be instances of classes with a C{test} method, to be sure
- L{plugin.getPlugins} load classes correctly.
- """
- plugins = list(plugin.getPlugins(ITestPlugin2, self.module))
-
- self.assertEqual(len(plugins), 2)
-
- names = ['AnotherTestPlugin', 'ThirdTestPlugin']
- for p in plugins:
- names.remove(p.__name__)
- p.test()
-
- test_plugins = _withCacheness(test_plugins)
-
-
- def test_detectNewFiles(self):
- """
- Check that L{plugin.getPlugins} is able to detect plugins added at
- runtime.
- """
- FilePath(__file__).sibling('plugin_extra1.py'
- ).copyTo(self.package.child('pluginextra.py'))
- try:
- # Check that the current situation is clean
- self.failIfIn('mypackage.pluginextra', sys.modules)
- self.failIf(hasattr(sys.modules['mypackage'], 'pluginextra'),
- "mypackage still has pluginextra module")
-
- plgs = list(plugin.getPlugins(ITestPlugin, self.module))
-
- # We should find 2 plugins: the one in testplugin, and the one in
- # pluginextra
- self.assertEqual(len(plgs), 2)
-
- names = ['TestPlugin', 'FourthTestPlugin']
- for p in plgs:
- names.remove(p.__name__)
- p.test1()
- finally:
- self._unimportPythonModule(
- sys.modules['mypackage.pluginextra'],
- True)
-
- test_detectNewFiles = _withCacheness(test_detectNewFiles)
-
-
- def test_detectFilesChanged(self):
- """
- Check that if the content of a plugin change, L{plugin.getPlugins} is
- able to detect the new plugins added.
- """
- FilePath(__file__).sibling('plugin_extra1.py'
- ).copyTo(self.package.child('pluginextra.py'))
- try:
- plgs = list(plugin.getPlugins(ITestPlugin, self.module))
- # Sanity check
- self.assertEqual(len(plgs), 2)
-
- FilePath(__file__).sibling('plugin_extra2.py'
- ).copyTo(self.package.child('pluginextra.py'))
-
- # Fake out Python.
- self._unimportPythonModule(sys.modules['mypackage.pluginextra'])
-
- # Make sure additions are noticed
- plgs = list(plugin.getPlugins(ITestPlugin, self.module))
-
- self.assertEqual(len(plgs), 3)
-
- names = ['TestPlugin', 'FourthTestPlugin', 'FifthTestPlugin']
- for p in plgs:
- names.remove(p.__name__)
- p.test1()
- finally:
- self._unimportPythonModule(
- sys.modules['mypackage.pluginextra'],
- True)
-
- test_detectFilesChanged = _withCacheness(test_detectFilesChanged)
-
-
- def test_detectFilesRemoved(self):
- """
- Check that when a dropin file is removed, L{plugin.getPlugins} doesn't
- return it anymore.
- """
- FilePath(__file__).sibling('plugin_extra1.py'
- ).copyTo(self.package.child('pluginextra.py'))
- try:
- # Generate a cache with pluginextra in it.
- list(plugin.getPlugins(ITestPlugin, self.module))
-
- finally:
- self._unimportPythonModule(
- sys.modules['mypackage.pluginextra'],
- True)
- plgs = list(plugin.getPlugins(ITestPlugin, self.module))
- self.assertEqual(1, len(plgs))
-
- test_detectFilesRemoved = _withCacheness(test_detectFilesRemoved)
-
-
- def test_nonexistentPathEntry(self):
- """
- Test that getCache skips over any entries in a plugin package's
- C{__path__} which do not exist.
- """
- path = self.mktemp()
- self.failIf(os.path.exists(path))
- # Add the test directory to the plugins path
- self.module.__path__.append(path)
- try:
- plgs = list(plugin.getPlugins(ITestPlugin, self.module))
- self.assertEqual(len(plgs), 1)
- finally:
- self.module.__path__.remove(path)
-
- test_nonexistentPathEntry = _withCacheness(test_nonexistentPathEntry)
-
-
- def test_nonDirectoryChildEntry(self):
- """
- Test that getCache skips over any entries in a plugin package's
- C{__path__} which refer to children of paths which are not directories.
- """
- path = FilePath(self.mktemp())
- self.failIf(path.exists())
- path.touch()
- child = path.child("test_package").path
- self.module.__path__.append(child)
- try:
- plgs = list(plugin.getPlugins(ITestPlugin, self.module))
- self.assertEqual(len(plgs), 1)
- finally:
- self.module.__path__.remove(child)
-
- test_nonDirectoryChildEntry = _withCacheness(test_nonDirectoryChildEntry)
-
-
- def test_deployedMode(self):
- """
- The C{dropin.cache} file may not be writable: the cache should still be
- attainable, but an error should be logged to show that the cache
- couldn't be updated.
- """
- # Generate the cache
- plugin.getCache(self.module)
-
- cachepath = self.package.child('dropin.cache')
-
- # Add a new plugin
- FilePath(__file__).sibling('plugin_extra1.py'
- ).copyTo(self.package.child('pluginextra.py'))
-
- os.chmod(self.package.path, 0500)
- # Change the right of dropin.cache too for windows
- os.chmod(cachepath.path, 0400)
- self.addCleanup(os.chmod, self.package.path, 0700)
- self.addCleanup(os.chmod, cachepath.path, 0700)
-
- # Start observing log events to see the warning
- events = []
- addObserver(events.append)
- self.addCleanup(removeObserver, events.append)
-
- cache = plugin.getCache(self.module)
- # The new plugin should be reported
- self.assertIn('pluginextra', cache)
- self.assertIn(self.originalPlugin, cache)
-
- # Make sure something was logged about the cache.
- expected = "Unable to write to plugin cache %s: error number %d" % (
- cachepath.path, errno.EPERM)
- for event in events:
- if expected in textFromEventDict(event):
- break
- else:
- self.fail(
- "Did not observe unwriteable cache warning in log "
- "events: %r" % (events,))
-
-
-
-# This is something like the Twisted plugins file.
-pluginInitFile = """
-from twisted.plugin import pluginPackagePaths
-__path__.extend(pluginPackagePaths(__name__))
-__all__ = []
-"""
-
-def pluginFileContents(name):
- return (
- "from zope.interface import classProvides\n"
- "from twisted.plugin import IPlugin\n"
- "from twisted.test.test_plugin import ITestPlugin\n"
- "\n"
- "class %s(object):\n"
- " classProvides(IPlugin, ITestPlugin)\n") % (name,)
-
-
-def _createPluginDummy(entrypath, pluginContent, real, pluginModule):
- """
- Create a plugindummy package.
- """
- entrypath.createDirectory()
- pkg = entrypath.child('plugindummy')
- pkg.createDirectory()
- if real:
- pkg.child('__init__.py').setContent('')
- plugs = pkg.child('plugins')
- plugs.createDirectory()
- if real:
- plugs.child('__init__.py').setContent(pluginInitFile)
- plugs.child(pluginModule + '.py').setContent(pluginContent)
- return plugs
-
-
-
-class DeveloperSetupTests(unittest.TestCase):
- """
- These tests verify things about the plugin system without actually
- interacting with the deployed 'twisted.plugins' package, instead creating a
- temporary package.
- """
-
- def setUp(self):
- """
- Create a complex environment with multiple entries on sys.path, akin to
- a developer's environment who has a development (trunk) checkout of
- Twisted, a system installed version of Twisted (for their operating
- system's tools) and a project which provides Twisted plugins.
- """
- self.savedPath = sys.path[:]
- self.savedModules = sys.modules.copy()
- self.fakeRoot = FilePath(self.mktemp())
- self.fakeRoot.createDirectory()
- self.systemPath = self.fakeRoot.child('system_path')
- self.devPath = self.fakeRoot.child('development_path')
- self.appPath = self.fakeRoot.child('application_path')
- self.systemPackage = _createPluginDummy(
- self.systemPath, pluginFileContents('system'),
- True, 'plugindummy_builtin')
- self.devPackage = _createPluginDummy(
- self.devPath, pluginFileContents('dev'),
- True, 'plugindummy_builtin')
- self.appPackage = _createPluginDummy(
- self.appPath, pluginFileContents('app'),
- False, 'plugindummy_app')
-
- # Now we're going to do the system installation.
- sys.path.extend([x.path for x in [self.systemPath,
- self.appPath]])
- # Run all the way through the plugins list to cause the
- # L{plugin.getPlugins} generator to write cache files for the system
- # installation.
- self.getAllPlugins()
- self.sysplug = self.systemPath.child('plugindummy').child('plugins')
- self.syscache = self.sysplug.child('dropin.cache')
- # Make sure there's a nice big difference in modification times so that
- # we won't re-build the system cache.
- now = time.time()
- os.utime(
- self.sysplug.child('plugindummy_builtin.py').path,
- (now - 5000,) * 2)
- os.utime(self.syscache.path, (now - 2000,) * 2)
- # For extra realism, let's make sure that the system path is no longer
- # writable.
- self.lockSystem()
- self.resetEnvironment()
-
-
- def lockSystem(self):
- """
- Lock the system directories, as if they were unwritable by this user.
- """
- os.chmod(self.sysplug.path, 0555)
- os.chmod(self.syscache.path, 0555)
-
-
- def unlockSystem(self):
- """
- Unlock the system directories, as if they were writable by this user.
- """
- os.chmod(self.sysplug.path, 0777)
- os.chmod(self.syscache.path, 0777)
-
-
- def getAllPlugins(self):
- """
- Get all the plugins loadable from our dummy package, and return their
- short names.
- """
- # Import the module we just added to our path. (Local scope because
- # this package doesn't exist outside of this test.)
- import plugindummy.plugins
- x = list(plugin.getPlugins(ITestPlugin, plugindummy.plugins))
- return [plug.__name__ for plug in x]
-
-
- def resetEnvironment(self):
- """
- Change the environment to what it should be just as the test is
- starting.
- """
- self.unsetEnvironment()
- sys.path.extend([x.path for x in [self.devPath,
- self.systemPath,
- self.appPath]])
-
- def unsetEnvironment(self):
- """
- Change the Python environment back to what it was before the test was
- started.
- """
- sys.modules.clear()
- sys.modules.update(self.savedModules)
- sys.path[:] = self.savedPath
-
-
- def tearDown(self):
- """
- Reset the Python environment to what it was before this test ran, and
- restore permissions on files which were marked read-only so that the
- directory may be cleanly cleaned up.
- """
- self.unsetEnvironment()
- # Normally we wouldn't "clean up" the filesystem like this (leaving
- # things for post-test inspection), but if we left the permissions the
- # way they were, we'd be leaving files around that the buildbots
- # couldn't delete, and that would be bad.
- self.unlockSystem()
-
-
- def test_developmentPluginAvailability(self):
- """
- Plugins added in the development path should be loadable, even when
- the (now non-importable) system path contains its own idea of the
- list of plugins for a package. Inversely, plugins added in the
- system path should not be available.
- """
- # Run 3 times: uncached, cached, and then cached again to make sure we
- # didn't overwrite / corrupt the cache on the cached try.
- for x in range(3):
- names = self.getAllPlugins()
- names.sort()
- self.assertEqual(names, ['app', 'dev'])
-
-
- def test_freshPyReplacesStalePyc(self):
- """
- Verify that if a stale .pyc file on the PYTHONPATH is replaced by a
- fresh .py file, the plugins in the new .py are picked up rather than
- the stale .pyc, even if the .pyc is still around.
- """
- mypath = self.appPackage.child("stale.py")
- mypath.setContent(pluginFileContents('one'))
- # Make it super stale
- x = time.time() - 1000
- os.utime(mypath.path, (x, x))
- pyc = mypath.sibling('stale.pyc')
- # compile it
- compileall.compile_dir(self.appPackage.path, quiet=1)
- os.utime(pyc.path, (x, x))
- # Eliminate the other option.
- mypath.remove()
- # Make sure it's the .pyc path getting cached.
- self.resetEnvironment()
- # Sanity check.
- self.assertIn('one', self.getAllPlugins())
- self.failIfIn('two', self.getAllPlugins())
- self.resetEnvironment()
- mypath.setContent(pluginFileContents('two'))
- self.failIfIn('one', self.getAllPlugins())
- self.assertIn('two', self.getAllPlugins())
-
-
- def test_newPluginsOnReadOnlyPath(self):
- """
- Verify that a failure to write the dropin.cache file on a read-only
- path will not affect the list of plugins returned.
-
- Note: this test should pass on both Linux and Windows, but may not
- provide useful coverage on Windows due to the different meaning of
- "read-only directory".
- """
- self.unlockSystem()
- self.sysplug.child('newstuff.py').setContent(pluginFileContents('one'))
- self.lockSystem()
-
- # Take the developer path out, so that the system plugins are actually
- # examined.
- sys.path.remove(self.devPath.path)
-
- # Start observing log events to see the warning
- events = []
- addObserver(events.append)
- self.addCleanup(removeObserver, events.append)
-
- self.assertIn('one', self.getAllPlugins())
-
- # Make sure something was logged about the cache.
- expected = "Unable to write to plugin cache %s: error number %d" % (
- self.syscache.path, errno.EPERM)
- for event in events:
- if expected in textFromEventDict(event):
- break
- else:
- self.fail(
- "Did not observe unwriteable cache warning in log "
- "events: %r" % (events,))
-
-
-
-class AdjacentPackageTests(unittest.TestCase):
- """
- Tests for the behavior of the plugin system when there are multiple
- installed copies of the package containing the plugins being loaded.
- """
-
- def setUp(self):
- """
- Save the elements of C{sys.path} and the items of C{sys.modules}.
- """
- self.originalPath = sys.path[:]
- self.savedModules = sys.modules.copy()
-
-
- def tearDown(self):
- """
- Restore C{sys.path} and C{sys.modules} to their original values.
- """
- sys.path[:] = self.originalPath
- sys.modules.clear()
- sys.modules.update(self.savedModules)
-
-
- def createDummyPackage(self, root, name, pluginName):
- """
- Create a directory containing a Python package named I{dummy} with a
- I{plugins} subpackage.
-
- @type root: L{FilePath}
- @param root: The directory in which to create the hierarchy.
-
- @type name: C{str}
- @param name: The name of the directory to create which will contain
- the package.
-
- @type pluginName: C{str}
- @param pluginName: The name of a module to create in the
- I{dummy.plugins} package.
-
- @rtype: L{FilePath}
- @return: The directory which was created to contain the I{dummy}
- package.
- """
- directory = root.child(name)
- package = directory.child('dummy')
- package.makedirs()
- package.child('__init__.py').setContent('')
- plugins = package.child('plugins')
- plugins.makedirs()
- plugins.child('__init__.py').setContent(pluginInitFile)
- pluginModule = plugins.child(pluginName + '.py')
- pluginModule.setContent(pluginFileContents(name))
- return directory
-
-
- def test_hiddenPackageSamePluginModuleNameObscured(self):
- """
- Only plugins from the first package in sys.path should be returned by
- getPlugins in the case where there are two Python packages by the same
- name installed, each with a plugin module by a single name.
- """
- root = FilePath(self.mktemp())
- root.makedirs()
-
- firstDirectory = self.createDummyPackage(root, 'first', 'someplugin')
- secondDirectory = self.createDummyPackage(root, 'second', 'someplugin')
-
- sys.path.append(firstDirectory.path)
- sys.path.append(secondDirectory.path)
-
- import dummy.plugins
-
- plugins = list(plugin.getPlugins(ITestPlugin, dummy.plugins))
- self.assertEqual(['first'], [p.__name__ for p in plugins])
-
-
- def test_hiddenPackageDifferentPluginModuleNameObscured(self):
- """
- Plugins from the first package in sys.path should be returned by
- getPlugins in the case where there are two Python packages by the same
- name installed, each with a plugin module by a different name.
- """
- root = FilePath(self.mktemp())
- root.makedirs()
-
- firstDirectory = self.createDummyPackage(root, 'first', 'thisplugin')
- secondDirectory = self.createDummyPackage(root, 'second', 'thatplugin')
-
- sys.path.append(firstDirectory.path)
- sys.path.append(secondDirectory.path)
-
- import dummy.plugins
-
- plugins = list(plugin.getPlugins(ITestPlugin, dummy.plugins))
- self.assertEqual(['first'], [p.__name__ for p in plugins])
-
-
-
-class PackagePathTests(unittest.TestCase):
- """
- Tests for L{plugin.pluginPackagePaths} which constructs search paths for
- plugin packages.
- """
-
- def setUp(self):
- """
- Save the elements of C{sys.path}.
- """
- self.originalPath = sys.path[:]
-
-
- def tearDown(self):
- """
- Restore C{sys.path} to its original value.
- """
- sys.path[:] = self.originalPath
-
-
- def test_pluginDirectories(self):
- """
- L{plugin.pluginPackagePaths} should return a list containing each
- directory in C{sys.path} with a suffix based on the supplied package
- name.
- """
- foo = FilePath('foo')
- bar = FilePath('bar')
- sys.path = [foo.path, bar.path]
- self.assertEqual(
- plugin.pluginPackagePaths('dummy.plugins'),
- [foo.child('dummy').child('plugins').path,
- bar.child('dummy').child('plugins').path])
-
-
- def test_pluginPackagesExcluded(self):
- """
- L{plugin.pluginPackagePaths} should exclude directories which are
- Python packages. The only allowed plugin package (the only one
- associated with a I{dummy} package which Python will allow to be
- imported) will already be known to the caller of
- L{plugin.pluginPackagePaths} and will most commonly already be in
- the C{__path__} they are about to mutate.
- """
- root = FilePath(self.mktemp())
- foo = root.child('foo').child('dummy').child('plugins')
- foo.makedirs()
- foo.child('__init__.py').setContent('')
- sys.path = [root.child('foo').path, root.child('bar').path]
- self.assertEqual(
- plugin.pluginPackagePaths('dummy.plugins'),
- [root.child('bar').child('dummy').child('plugins').path])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_policies.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_policies.py
deleted file mode 100755
index 3cdf0967..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_policies.py
+++ /dev/null
@@ -1,736 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test code for policies.
-"""
-
-from zope.interface import Interface, implements, implementedBy
-
-from StringIO import StringIO
-
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport
-from twisted.test.proto_helpers import StringTransportWithDisconnection
-
-from twisted.internet import protocol, reactor, address, defer, task
-from twisted.protocols import policies
-
-
-
-class SimpleProtocol(protocol.Protocol):
-
- connected = disconnected = 0
- buffer = ""
-
- def __init__(self):
- self.dConnected = defer.Deferred()
- self.dDisconnected = defer.Deferred()
-
- def connectionMade(self):
- self.connected = 1
- self.dConnected.callback('')
-
- def connectionLost(self, reason):
- self.disconnected = 1
- self.dDisconnected.callback('')
-
- def dataReceived(self, data):
- self.buffer += data
-
-
-
-class SillyFactory(protocol.ClientFactory):
-
- def __init__(self, p):
- self.p = p
-
- def buildProtocol(self, addr):
- return self.p
-
-
-class EchoProtocol(protocol.Protocol):
- paused = False
-
- def pauseProducing(self):
- self.paused = True
-
- def resumeProducing(self):
- self.paused = False
-
- def stopProducing(self):
- pass
-
- def dataReceived(self, data):
- self.transport.write(data)
-
-
-
-class Server(protocol.ServerFactory):
- """
- A simple server factory using L{EchoProtocol}.
- """
- protocol = EchoProtocol
-
-
-
-class TestableThrottlingFactory(policies.ThrottlingFactory):
- """
- L{policies.ThrottlingFactory} using a L{task.Clock} for tests.
- """
-
- def __init__(self, clock, *args, **kwargs):
- """
- @param clock: object providing a callLater method that can be used
- for tests.
- @type clock: C{task.Clock} or alike.
- """
- policies.ThrottlingFactory.__init__(self, *args, **kwargs)
- self.clock = clock
-
-
- def callLater(self, period, func):
- """
- Forward to the testable clock.
- """
- return self.clock.callLater(period, func)
-
-
-
-class TestableTimeoutFactory(policies.TimeoutFactory):
- """
- L{policies.TimeoutFactory} using a L{task.Clock} for tests.
- """
-
- def __init__(self, clock, *args, **kwargs):
- """
- @param clock: object providing a callLater method that can be used
- for tests.
- @type clock: C{task.Clock} or alike.
- """
- policies.TimeoutFactory.__init__(self, *args, **kwargs)
- self.clock = clock
-
-
- def callLater(self, period, func):
- """
- Forward to the testable clock.
- """
- return self.clock.callLater(period, func)
-
-
-
-class WrapperTestCase(unittest.TestCase):
- """
- Tests for L{WrappingFactory} and L{ProtocolWrapper}.
- """
- def test_protocolFactoryAttribute(self):
- """
- Make sure protocol.factory is the wrapped factory, not the wrapping
- factory.
- """
- f = Server()
- wf = policies.WrappingFactory(f)
- p = wf.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 35))
- self.assertIdentical(p.wrappedProtocol.factory, f)
-
-
- def test_transportInterfaces(self):
- """
- The transport wrapper passed to the wrapped protocol's
- C{makeConnection} provides the same interfaces as are provided by the
- original transport.
- """
- class IStubTransport(Interface):
- pass
-
- class StubTransport:
- implements(IStubTransport)
-
- # Looking up what ProtocolWrapper implements also mutates the class.
- # It adds __implemented__ and __providedBy__ attributes to it. These
- # prevent __getattr__ from causing the IStubTransport.providedBy call
- # below from returning True. If, by accident, nothing else causes
- # these attributes to be added to ProtocolWrapper, the test will pass,
- # but the interface will only be provided until something does trigger
- # their addition. So we just trigger it right now to be sure.
- implementedBy(policies.ProtocolWrapper)
-
- proto = protocol.Protocol()
- wrapper = policies.ProtocolWrapper(policies.WrappingFactory(None), proto)
-
- wrapper.makeConnection(StubTransport())
- self.assertTrue(IStubTransport.providedBy(proto.transport))
-
-
- def test_factoryLogPrefix(self):
- """
- L{WrappingFactory.logPrefix} is customized to mention both the original
- factory and the wrapping factory.
- """
- server = Server()
- factory = policies.WrappingFactory(server)
- self.assertEqual("Server (WrappingFactory)", factory.logPrefix())
-
-
- def test_factoryLogPrefixFallback(self):
- """
- If the wrapped factory doesn't have a L{logPrefix} method,
- L{WrappingFactory.logPrefix} falls back to the factory class name.
- """
- class NoFactory(object):
- pass
-
- server = NoFactory()
- factory = policies.WrappingFactory(server)
- self.assertEqual("NoFactory (WrappingFactory)", factory.logPrefix())
-
-
- def test_protocolLogPrefix(self):
- """
- L{ProtocolWrapper.logPrefix} is customized to mention both the original
- protocol and the wrapper.
- """
- server = Server()
- factory = policies.WrappingFactory(server)
- protocol = factory.buildProtocol(
- address.IPv4Address('TCP', '127.0.0.1', 35))
- self.assertEqual("EchoProtocol (ProtocolWrapper)",
- protocol.logPrefix())
-
-
- def test_protocolLogPrefixFallback(self):
- """
- If the wrapped protocol doesn't have a L{logPrefix} method,
- L{ProtocolWrapper.logPrefix} falls back to the protocol class name.
- """
- class NoProtocol(object):
- pass
-
- server = Server()
- server.protocol = NoProtocol
- factory = policies.WrappingFactory(server)
- protocol = factory.buildProtocol(
- address.IPv4Address('TCP', '127.0.0.1', 35))
- self.assertEqual("NoProtocol (ProtocolWrapper)",
- protocol.logPrefix())
-
-
-
-class WrappingFactory(policies.WrappingFactory):
- protocol = lambda s, f, p: p
-
- def startFactory(self):
- policies.WrappingFactory.startFactory(self)
- self.deferred.callback(None)
-
-
-
-class ThrottlingTestCase(unittest.TestCase):
- """
- Tests for L{policies.ThrottlingFactory}.
- """
-
- def test_limit(self):
- """
- Full test using a custom server limiting number of connections.
- """
- server = Server()
- c1, c2, c3, c4 = [SimpleProtocol() for i in range(4)]
- tServer = policies.ThrottlingFactory(server, 2)
- wrapTServer = WrappingFactory(tServer)
- wrapTServer.deferred = defer.Deferred()
-
- # Start listening
- p = reactor.listenTCP(0, wrapTServer, interface="127.0.0.1")
- n = p.getHost().port
-
- def _connect123(results):
- reactor.connectTCP("127.0.0.1", n, SillyFactory(c1))
- c1.dConnected.addCallback(
- lambda r: reactor.connectTCP("127.0.0.1", n, SillyFactory(c2)))
- c2.dConnected.addCallback(
- lambda r: reactor.connectTCP("127.0.0.1", n, SillyFactory(c3)))
- return c3.dDisconnected
-
- def _check123(results):
- self.assertEqual([c.connected for c in c1, c2, c3], [1, 1, 1])
- self.assertEqual([c.disconnected for c in c1, c2, c3], [0, 0, 1])
- self.assertEqual(len(tServer.protocols.keys()), 2)
- return results
-
- def _lose1(results):
- # disconnect one protocol and now another should be able to connect
- c1.transport.loseConnection()
- return c1.dDisconnected
-
- def _connect4(results):
- reactor.connectTCP("127.0.0.1", n, SillyFactory(c4))
- return c4.dConnected
-
- def _check4(results):
- self.assertEqual(c4.connected, 1)
- self.assertEqual(c4.disconnected, 0)
- return results
-
- def _cleanup(results):
- for c in c2, c4:
- c.transport.loseConnection()
- return defer.DeferredList([
- defer.maybeDeferred(p.stopListening),
- c2.dDisconnected,
- c4.dDisconnected])
-
- wrapTServer.deferred.addCallback(_connect123)
- wrapTServer.deferred.addCallback(_check123)
- wrapTServer.deferred.addCallback(_lose1)
- wrapTServer.deferred.addCallback(_connect4)
- wrapTServer.deferred.addCallback(_check4)
- wrapTServer.deferred.addCallback(_cleanup)
- return wrapTServer.deferred
-
-
- def test_writeLimit(self):
- """
- Check the writeLimit parameter: write data, and check for the pause
- status.
- """
- server = Server()
- tServer = TestableThrottlingFactory(task.Clock(), server, writeLimit=10)
- port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0))
- tr = StringTransportWithDisconnection()
- tr.protocol = port
- port.makeConnection(tr)
- port.producer = port.wrappedProtocol
-
- port.dataReceived("0123456789")
- port.dataReceived("abcdefghij")
- self.assertEqual(tr.value(), "0123456789abcdefghij")
- self.assertEqual(tServer.writtenThisSecond, 20)
- self.assertFalse(port.wrappedProtocol.paused)
-
- # at this point server should've written 20 bytes, 10 bytes
- # above the limit so writing should be paused around 1 second
- # from 'now', and resumed a second after that
- tServer.clock.advance(1.05)
- self.assertEqual(tServer.writtenThisSecond, 0)
- self.assertTrue(port.wrappedProtocol.paused)
-
- tServer.clock.advance(1.05)
- self.assertEqual(tServer.writtenThisSecond, 0)
- self.assertFalse(port.wrappedProtocol.paused)
-
-
- def test_readLimit(self):
- """
- Check the readLimit parameter: read data and check for the pause
- status.
- """
- server = Server()
- tServer = TestableThrottlingFactory(task.Clock(), server, readLimit=10)
- port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0))
- tr = StringTransportWithDisconnection()
- tr.protocol = port
- port.makeConnection(tr)
-
- port.dataReceived("0123456789")
- port.dataReceived("abcdefghij")
- self.assertEqual(tr.value(), "0123456789abcdefghij")
- self.assertEqual(tServer.readThisSecond, 20)
-
- tServer.clock.advance(1.05)
- self.assertEqual(tServer.readThisSecond, 0)
- self.assertEqual(tr.producerState, 'paused')
-
- tServer.clock.advance(1.05)
- self.assertEqual(tServer.readThisSecond, 0)
- self.assertEqual(tr.producerState, 'producing')
-
- tr.clear()
- port.dataReceived("0123456789")
- port.dataReceived("abcdefghij")
- self.assertEqual(tr.value(), "0123456789abcdefghij")
- self.assertEqual(tServer.readThisSecond, 20)
-
- tServer.clock.advance(1.05)
- self.assertEqual(tServer.readThisSecond, 0)
- self.assertEqual(tr.producerState, 'paused')
-
- tServer.clock.advance(1.05)
- self.assertEqual(tServer.readThisSecond, 0)
- self.assertEqual(tr.producerState, 'producing')
-
-
-
-class TimeoutTestCase(unittest.TestCase):
- """
- Tests for L{policies.TimeoutFactory}.
- """
-
- def setUp(self):
- """
- Create a testable, deterministic clock, and a set of
- server factory/protocol/transport.
- """
- self.clock = task.Clock()
- wrappedFactory = protocol.ServerFactory()
- wrappedFactory.protocol = SimpleProtocol
- self.factory = TestableTimeoutFactory(self.clock, wrappedFactory, 3)
- self.proto = self.factory.buildProtocol(
- address.IPv4Address('TCP', '127.0.0.1', 12345))
- self.transport = StringTransportWithDisconnection()
- self.transport.protocol = self.proto
- self.proto.makeConnection(self.transport)
-
-
- def test_timeout(self):
- """
- Make sure that when a TimeoutFactory accepts a connection, it will
- time out that connection if no data is read or written within the
- timeout period.
- """
- # Let almost 3 time units pass
- self.clock.pump([0.0, 0.5, 1.0, 1.0, 0.4])
- self.failIf(self.proto.wrappedProtocol.disconnected)
-
- # Now let the timer elapse
- self.clock.pump([0.0, 0.2])
- self.failUnless(self.proto.wrappedProtocol.disconnected)
-
-
- def test_sendAvoidsTimeout(self):
- """
- Make sure that writing data to a transport from a protocol
- constructed by a TimeoutFactory resets the timeout countdown.
- """
- # Let half the countdown period elapse
- self.clock.pump([0.0, 0.5, 1.0])
- self.failIf(self.proto.wrappedProtocol.disconnected)
-
- # Send some data (self.proto is the /real/ proto's transport, so this
- # is the write that gets called)
- self.proto.write('bytes bytes bytes')
-
- # More time passes, putting us past the original timeout
- self.clock.pump([0.0, 1.0, 1.0])
- self.failIf(self.proto.wrappedProtocol.disconnected)
-
- # Make sure writeSequence delays timeout as well
- self.proto.writeSequence(['bytes'] * 3)
-
- # Tick tock
- self.clock.pump([0.0, 1.0, 1.0])
- self.failIf(self.proto.wrappedProtocol.disconnected)
-
- # Don't write anything more, just let the timeout expire
- self.clock.pump([0.0, 2.0])
- self.failUnless(self.proto.wrappedProtocol.disconnected)
-
-
- def test_receiveAvoidsTimeout(self):
- """
- Make sure that receiving data also resets the timeout countdown.
- """
- # Let half the countdown period elapse
- self.clock.pump([0.0, 1.0, 0.5])
- self.failIf(self.proto.wrappedProtocol.disconnected)
-
- # Some bytes arrive, they should reset the counter
- self.proto.dataReceived('bytes bytes bytes')
-
- # We pass the original timeout
- self.clock.pump([0.0, 1.0, 1.0])
- self.failIf(self.proto.wrappedProtocol.disconnected)
-
- # Nothing more arrives though, the new timeout deadline is passed,
- # the connection should be dropped.
- self.clock.pump([0.0, 1.0, 1.0])
- self.failUnless(self.proto.wrappedProtocol.disconnected)
-
-
-
-class TimeoutTester(protocol.Protocol, policies.TimeoutMixin):
- """
- A testable protocol with timeout facility.
-
- @ivar timedOut: set to C{True} if a timeout has been detected.
- @type timedOut: C{bool}
- """
- timeOut = 3
- timedOut = False
-
- def __init__(self, clock):
- """
- Initialize the protocol with a C{task.Clock} object.
- """
- self.clock = clock
-
-
- def connectionMade(self):
- """
- Upon connection, set the timeout.
- """
- self.setTimeout(self.timeOut)
-
-
- def dataReceived(self, data):
- """
- Reset the timeout on data.
- """
- self.resetTimeout()
- protocol.Protocol.dataReceived(self, data)
-
-
- def connectionLost(self, reason=None):
- """
- On connection lost, cancel all timeout operations.
- """
- self.setTimeout(None)
-
-
- def timeoutConnection(self):
- """
- Flags the timedOut variable to indicate the timeout of the connection.
- """
- self.timedOut = True
-
-
- def callLater(self, timeout, func, *args, **kwargs):
- """
- Override callLater to use the deterministic clock.
- """
- return self.clock.callLater(timeout, func, *args, **kwargs)
-
-
-
-class TestTimeout(unittest.TestCase):
- """
- Tests for L{policies.TimeoutMixin}.
- """
-
- def setUp(self):
- """
- Create a testable, deterministic clock and a C{TimeoutTester} instance.
- """
- self.clock = task.Clock()
- self.proto = TimeoutTester(self.clock)
-
-
- def test_overriddenCallLater(self):
- """
- Test that the callLater of the clock is used instead of
- C{reactor.callLater}.
- """
- self.proto.setTimeout(10)
- self.assertEqual(len(self.clock.calls), 1)
-
-
- def test_timeout(self):
- """
- Check that the protocol does timeout at the time specified by its
- C{timeOut} attribute.
- """
- self.proto.makeConnection(StringTransport())
-
- # timeOut value is 3
- self.clock.pump([0, 0.5, 1.0, 1.0])
- self.failIf(self.proto.timedOut)
- self.clock.pump([0, 1.0])
- self.failUnless(self.proto.timedOut)
-
-
- def test_noTimeout(self):
- """
- Check that receiving data is delaying the timeout of the connection.
- """
- self.proto.makeConnection(StringTransport())
-
- self.clock.pump([0, 0.5, 1.0, 1.0])
- self.failIf(self.proto.timedOut)
- self.proto.dataReceived('hello there')
- self.clock.pump([0, 1.0, 1.0, 0.5])
- self.failIf(self.proto.timedOut)
- self.clock.pump([0, 1.0])
- self.failUnless(self.proto.timedOut)
-
-
- def test_resetTimeout(self):
- """
- Check that setting a new value for timeout cancel the previous value
- and install a new timeout.
- """
- self.proto.timeOut = None
- self.proto.makeConnection(StringTransport())
-
- self.proto.setTimeout(1)
- self.assertEqual(self.proto.timeOut, 1)
-
- self.clock.pump([0, 0.9])
- self.failIf(self.proto.timedOut)
- self.clock.pump([0, 0.2])
- self.failUnless(self.proto.timedOut)
-
-
- def test_cancelTimeout(self):
- """
- Setting the timeout to C{None} cancel any timeout operations.
- """
- self.proto.timeOut = 5
- self.proto.makeConnection(StringTransport())
-
- self.proto.setTimeout(None)
- self.assertEqual(self.proto.timeOut, None)
-
- self.clock.pump([0, 5, 5, 5])
- self.failIf(self.proto.timedOut)
-
-
- def test_return(self):
- """
- setTimeout should return the value of the previous timeout.
- """
- self.proto.timeOut = 5
-
- self.assertEqual(self.proto.setTimeout(10), 5)
- self.assertEqual(self.proto.setTimeout(None), 10)
- self.assertEqual(self.proto.setTimeout(1), None)
- self.assertEqual(self.proto.timeOut, 1)
-
- # Clean up the DelayedCall
- self.proto.setTimeout(None)
-
-
-
-class LimitTotalConnectionsFactoryTestCase(unittest.TestCase):
- """Tests for policies.LimitTotalConnectionsFactory"""
- def testConnectionCounting(self):
- # Make a basic factory
- factory = policies.LimitTotalConnectionsFactory()
- factory.protocol = protocol.Protocol
-
- # connectionCount starts at zero
- self.assertEqual(0, factory.connectionCount)
-
- # connectionCount increments as connections are made
- p1 = factory.buildProtocol(None)
- self.assertEqual(1, factory.connectionCount)
- p2 = factory.buildProtocol(None)
- self.assertEqual(2, factory.connectionCount)
-
- # and decrements as they are lost
- p1.connectionLost(None)
- self.assertEqual(1, factory.connectionCount)
- p2.connectionLost(None)
- self.assertEqual(0, factory.connectionCount)
-
- def testConnectionLimiting(self):
- # Make a basic factory with a connection limit of 1
- factory = policies.LimitTotalConnectionsFactory()
- factory.protocol = protocol.Protocol
- factory.connectionLimit = 1
-
- # Make a connection
- p = factory.buildProtocol(None)
- self.assertNotEqual(None, p)
- self.assertEqual(1, factory.connectionCount)
-
- # Try to make a second connection, which will exceed the connection
- # limit. This should return None, because overflowProtocol is None.
- self.assertEqual(None, factory.buildProtocol(None))
- self.assertEqual(1, factory.connectionCount)
-
- # Define an overflow protocol
- class OverflowProtocol(protocol.Protocol):
- def connectionMade(self):
- factory.overflowed = True
- factory.overflowProtocol = OverflowProtocol
- factory.overflowed = False
-
- # Try to make a second connection again, now that we have an overflow
- # protocol. Note that overflow connections count towards the connection
- # count.
- op = factory.buildProtocol(None)
- op.makeConnection(None) # to trigger connectionMade
- self.assertEqual(True, factory.overflowed)
- self.assertEqual(2, factory.connectionCount)
-
- # Close the connections.
- p.connectionLost(None)
- self.assertEqual(1, factory.connectionCount)
- op.connectionLost(None)
- self.assertEqual(0, factory.connectionCount)
-
-
-class WriteSequenceEchoProtocol(EchoProtocol):
- def dataReceived(self, bytes):
- if bytes.find('vector!') != -1:
- self.transport.writeSequence([bytes])
- else:
- EchoProtocol.dataReceived(self, bytes)
-
-class TestLoggingFactory(policies.TrafficLoggingFactory):
- openFile = None
- def open(self, name):
- assert self.openFile is None, "open() called too many times"
- self.openFile = StringIO()
- return self.openFile
-
-
-
-class LoggingFactoryTestCase(unittest.TestCase):
- """
- Tests for L{policies.TrafficLoggingFactory}.
- """
-
- def test_thingsGetLogged(self):
- """
- Check the output produced by L{policies.TrafficLoggingFactory}.
- """
- wrappedFactory = Server()
- wrappedFactory.protocol = WriteSequenceEchoProtocol
- t = StringTransportWithDisconnection()
- f = TestLoggingFactory(wrappedFactory, 'test')
- p = f.buildProtocol(('1.2.3.4', 5678))
- t.protocol = p
- p.makeConnection(t)
-
- v = f.openFile.getvalue()
- self.failUnless('*' in v, "* not found in %r" % (v,))
- self.failIf(t.value())
-
- p.dataReceived('here are some bytes')
-
- v = f.openFile.getvalue()
- self.assertIn("C 1: 'here are some bytes'", v)
- self.assertIn("S 1: 'here are some bytes'", v)
- self.assertEqual(t.value(), 'here are some bytes')
-
- t.clear()
- p.dataReceived('prepare for vector! to the extreme')
- v = f.openFile.getvalue()
- self.assertIn("SV 1: ['prepare for vector! to the extreme']", v)
- self.assertEqual(t.value(), 'prepare for vector! to the extreme')
-
- p.loseConnection()
-
- v = f.openFile.getvalue()
- self.assertIn('ConnectionDone', v)
-
-
- def test_counter(self):
- """
- Test counter management with the resetCounter method.
- """
- wrappedFactory = Server()
- f = TestLoggingFactory(wrappedFactory, 'test')
- self.assertEqual(f._counter, 0)
- f.buildProtocol(('1.2.3.4', 5678))
- self.assertEqual(f._counter, 1)
- # Reset log file
- f.openFile = None
- f.buildProtocol(('1.2.3.4', 5679))
- self.assertEqual(f._counter, 2)
-
- f.resetCounter()
- self.assertEqual(f._counter, 0)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_postfix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_postfix.py
deleted file mode 100755
index 0f80a461..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_postfix.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.protocols.postfix module.
-"""
-
-from twisted.trial import unittest
-from twisted.protocols import postfix
-from twisted.test.proto_helpers import StringTransport
-
-
-class PostfixTCPMapQuoteTestCase(unittest.TestCase):
- data = [
- # (raw, quoted, [aliasQuotedForms]),
- ('foo', 'foo'),
- ('foo bar', 'foo%20bar'),
- ('foo\tbar', 'foo%09bar'),
- ('foo\nbar', 'foo%0Abar', 'foo%0abar'),
- ('foo\r\nbar', 'foo%0D%0Abar', 'foo%0D%0abar', 'foo%0d%0Abar', 'foo%0d%0abar'),
- ('foo ', 'foo%20'),
- (' foo', '%20foo'),
- ]
-
- def testData(self):
- for entry in self.data:
- raw = entry[0]
- quoted = entry[1:]
-
- self.assertEqual(postfix.quote(raw), quoted[0])
- for q in quoted:
- self.assertEqual(postfix.unquote(q), raw)
-
-class PostfixTCPMapServerTestCase:
- data = {
- # 'key': 'value',
- }
-
- chat = [
- # (input, expected_output),
- ]
-
- def test_chat(self):
- """
- Test that I{get} and I{put} commands are responded to correctly by
- L{postfix.PostfixTCPMapServer} when its factory is an instance of
- L{postifx.PostfixTCPMapDictServerFactory}.
- """
- factory = postfix.PostfixTCPMapDictServerFactory(self.data)
- transport = StringTransport()
-
- protocol = postfix.PostfixTCPMapServer()
- protocol.service = factory
- protocol.factory = factory
- protocol.makeConnection(transport)
-
- for input, expected_output in self.chat:
- protocol.lineReceived(input)
- self.assertEqual(
- transport.value(), expected_output,
- 'For %r, expected %r but got %r' % (
- input, expected_output, transport.value()))
- transport.clear()
- protocol.setTimeout(None)
-
-
- def test_deferredChat(self):
- """
- Test that I{get} and I{put} commands are responded to correctly by
- L{postfix.PostfixTCPMapServer} when its factory is an instance of
- L{postifx.PostfixTCPMapDeferringDictServerFactory}.
- """
- factory = postfix.PostfixTCPMapDeferringDictServerFactory(self.data)
- transport = StringTransport()
-
- protocol = postfix.PostfixTCPMapServer()
- protocol.service = factory
- protocol.factory = factory
- protocol.makeConnection(transport)
-
- for input, expected_output in self.chat:
- protocol.lineReceived(input)
- self.assertEqual(
- transport.value(), expected_output,
- 'For %r, expected %r but got %r' % (
- input, expected_output, transport.value()))
- transport.clear()
- protocol.setTimeout(None)
-
-
-
-class Valid(PostfixTCPMapServerTestCase, unittest.TestCase):
- data = {
- 'foo': 'ThisIs Foo',
- 'bar': ' bar really is found\r\n',
- }
- chat = [
- ('get', "400 Command 'get' takes 1 parameters.\n"),
- ('get foo bar', "500 \n"),
- ('put', "400 Command 'put' takes 2 parameters.\n"),
- ('put foo', "400 Command 'put' takes 2 parameters.\n"),
- ('put foo bar baz', "500 put is not implemented yet.\n"),
- ('put foo bar', '500 put is not implemented yet.\n'),
- ('get foo', '200 ThisIs%20Foo\n'),
- ('get bar', '200 %20bar%20really%20is%20found%0D%0A\n'),
- ('get baz', '500 \n'),
- ('foo', '400 unknown command\n'),
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_process.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_process.py
deleted file mode 100755
index 9d766cb7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_process.py
+++ /dev/null
@@ -1,2561 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test running processes.
-"""
-
-import gzip
-import os
-import sys
-import signal
-import StringIO
-import errno
-import gc
-import stat
-import operator
-try:
- import fcntl
-except ImportError:
- fcntl = process = None
-else:
- from twisted.internet import process
-
-
-from zope.interface.verify import verifyObject
-
-from twisted.python.log import msg
-from twisted.internet import reactor, protocol, error, interfaces, defer
-from twisted.trial import unittest
-from twisted.python import util, runtime, procutils
-from twisted.python.compat import set
-
-
-
-class StubProcessProtocol(protocol.ProcessProtocol):
- """
- ProcessProtocol counter-implementation: all methods on this class raise an
- exception, so instances of this may be used to verify that only certain
- methods are called.
- """
- def outReceived(self, data):
- raise NotImplementedError()
-
- def errReceived(self, data):
- raise NotImplementedError()
-
- def inConnectionLost(self):
- raise NotImplementedError()
-
- def outConnectionLost(self):
- raise NotImplementedError()
-
- def errConnectionLost(self):
- raise NotImplementedError()
-
-
-
-class ProcessProtocolTests(unittest.TestCase):
- """
- Tests for behavior provided by the process protocol base class,
- L{protocol.ProcessProtocol}.
- """
- def test_interface(self):
- """
- L{ProcessProtocol} implements L{IProcessProtocol}.
- """
- verifyObject(interfaces.IProcessProtocol, protocol.ProcessProtocol())
-
-
- def test_outReceived(self):
- """
- Verify that when stdout is delivered to
- L{ProcessProtocol.childDataReceived}, it is forwarded to
- L{ProcessProtocol.outReceived}.
- """
- received = []
- class OutProtocol(StubProcessProtocol):
- def outReceived(self, data):
- received.append(data)
-
- bytes = "bytes"
- p = OutProtocol()
- p.childDataReceived(1, bytes)
- self.assertEqual(received, [bytes])
-
-
- def test_errReceived(self):
- """
- Similar to L{test_outReceived}, but for stderr.
- """
- received = []
- class ErrProtocol(StubProcessProtocol):
- def errReceived(self, data):
- received.append(data)
-
- bytes = "bytes"
- p = ErrProtocol()
- p.childDataReceived(2, bytes)
- self.assertEqual(received, [bytes])
-
-
- def test_inConnectionLost(self):
- """
- Verify that when stdin close notification is delivered to
- L{ProcessProtocol.childConnectionLost}, it is forwarded to
- L{ProcessProtocol.inConnectionLost}.
- """
- lost = []
- class InLostProtocol(StubProcessProtocol):
- def inConnectionLost(self):
- lost.append(None)
-
- p = InLostProtocol()
- p.childConnectionLost(0)
- self.assertEqual(lost, [None])
-
-
- def test_outConnectionLost(self):
- """
- Similar to L{test_inConnectionLost}, but for stdout.
- """
- lost = []
- class OutLostProtocol(StubProcessProtocol):
- def outConnectionLost(self):
- lost.append(None)
-
- p = OutLostProtocol()
- p.childConnectionLost(1)
- self.assertEqual(lost, [None])
-
-
- def test_errConnectionLost(self):
- """
- Similar to L{test_inConnectionLost}, but for stderr.
- """
- lost = []
- class ErrLostProtocol(StubProcessProtocol):
- def errConnectionLost(self):
- lost.append(None)
-
- p = ErrLostProtocol()
- p.childConnectionLost(2)
- self.assertEqual(lost, [None])
-
-
-
-class TrivialProcessProtocol(protocol.ProcessProtocol):
- """
- Simple process protocol for tests purpose.
-
- @ivar outData: data received from stdin
- @ivar errData: data received from stderr
- """
-
- def __init__(self, d):
- """
- Create the deferred that will be fired at the end, and initialize
- data structures.
- """
- self.deferred = d
- self.outData = []
- self.errData = []
-
- def processEnded(self, reason):
- self.reason = reason
- self.deferred.callback(None)
-
- def outReceived(self, data):
- self.outData.append(data)
-
- def errReceived(self, data):
- self.errData.append(data)
-
-
-class TestProcessProtocol(protocol.ProcessProtocol):
-
- def connectionMade(self):
- self.stages = [1]
- self.data = ''
- self.err = ''
- self.transport.write("abcd")
-
- def childDataReceived(self, childFD, data):
- """
- Override and disable the dispatch provided by the base class to ensure
- that it is really this method which is being called, and the transport
- is not going directly to L{outReceived} or L{errReceived}.
- """
- if childFD == 1:
- self.data += data
- elif childFD == 2:
- self.err += data
-
-
- def childConnectionLost(self, childFD):
- """
- Similarly to L{childDataReceived}, disable the automatic dispatch
- provided by the base implementation to verify that the transport is
- calling this method directly.
- """
- if childFD == 1:
- self.stages.append(2)
- if self.data != "abcd":
- raise RuntimeError(
- "Data was %r instead of 'abcd'" % (self.data,))
- self.transport.write("1234")
- elif childFD == 2:
- self.stages.append(3)
- if self.err != "1234":
- raise RuntimeError(
- "Err was %r instead of '1234'" % (self.err,))
- self.transport.write("abcd")
- self.stages.append(4)
- elif childFD == 0:
- self.stages.append(5)
-
- def processEnded(self, reason):
- self.reason = reason
- self.deferred.callback(None)
-
-
-class EchoProtocol(protocol.ProcessProtocol):
-
- s = "1234567" * 1001
- n = 10
- finished = 0
-
- failure = None
-
- def __init__(self, onEnded):
- self.onEnded = onEnded
- self.count = 0
-
- def connectionMade(self):
- assert self.n > 2
- for i in range(self.n - 2):
- self.transport.write(self.s)
- # test writeSequence
- self.transport.writeSequence([self.s, self.s])
- self.buffer = self.s * self.n
-
- def outReceived(self, data):
- if buffer(self.buffer, self.count, len(data)) != buffer(data):
- self.failure = ("wrong bytes received", data, self.count)
- self.transport.closeStdin()
- else:
- self.count += len(data)
- if self.count == len(self.buffer):
- self.transport.closeStdin()
-
- def processEnded(self, reason):
- self.finished = 1
- if not reason.check(error.ProcessDone):
- self.failure = "process didn't terminate normally: " + str(reason)
- self.onEnded.callback(self)
-
-
-
-class SignalProtocol(protocol.ProcessProtocol):
- """
- A process protocol that sends a signal when data is first received.
-
- @ivar deferred: deferred firing on C{processEnded}.
- @type deferred: L{defer.Deferred}
-
- @ivar signal: the signal to send to the process.
- @type signal: C{str}
-
- @ivar signaled: A flag tracking whether the signal has been sent to the
- child or not yet. C{False} until it is sent, then C{True}.
- @type signaled: C{bool}
- """
-
- def __init__(self, deferred, sig):
- self.deferred = deferred
- self.signal = sig
- self.signaled = False
-
-
- def outReceived(self, data):
- """
- Handle the first output from the child process (which indicates it
- is set up and ready to receive the signal) by sending the signal to
- it. Also log all output to help with debugging.
- """
- msg("Received %r from child stdout" % (data,))
- if not self.signaled:
- self.signaled = True
- self.transport.signalProcess(self.signal)
-
-
- def errReceived(self, data):
- """
- Log all data received from the child's stderr to help with
- debugging.
- """
- msg("Received %r from child stderr" % (data,))
-
-
- def processEnded(self, reason):
- """
- Callback C{self.deferred} with C{None} if C{reason} is a
- L{error.ProcessTerminated} failure with C{exitCode} set to C{None},
- C{signal} set to C{self.signal}, and C{status} holding the status code
- of the exited process. Otherwise, errback with a C{ValueError}
- describing the problem.
- """
- msg("Child exited: %r" % (reason.getTraceback(),))
- if not reason.check(error.ProcessTerminated):
- return self.deferred.errback(
- ValueError("wrong termination: %s" % (reason,)))
- v = reason.value
- if isinstance(self.signal, str):
- signalValue = getattr(signal, 'SIG' + self.signal)
- else:
- signalValue = self.signal
- if v.exitCode is not None:
- return self.deferred.errback(
- ValueError("SIG%s: exitCode is %s, not None" %
- (self.signal, v.exitCode)))
- if v.signal != signalValue:
- return self.deferred.errback(
- ValueError("SIG%s: .signal was %s, wanted %s" %
- (self.signal, v.signal, signalValue)))
- if os.WTERMSIG(v.status) != signalValue:
- return self.deferred.errback(
- ValueError('SIG%s: %s' % (self.signal, os.WTERMSIG(v.status))))
- self.deferred.callback(None)
-
-
-
-class TestManyProcessProtocol(TestProcessProtocol):
- def __init__(self):
- self.deferred = defer.Deferred()
-
- def processEnded(self, reason):
- self.reason = reason
- if reason.check(error.ProcessDone):
- self.deferred.callback(None)
- else:
- self.deferred.errback(reason)
-
-
-
-class UtilityProcessProtocol(protocol.ProcessProtocol):
- """
- Helper class for launching a Python process and getting a result from it.
-
- @ivar program: A string giving a Python program for the child process to
- run.
- """
- program = None
-
- def run(cls, reactor, argv, env):
- """
- Run a Python process connected to a new instance of this protocol
- class. Return the protocol instance.
-
- The Python process is given C{self.program} on the command line to
- execute, in addition to anything specified by C{argv}. C{env} is
- the complete environment.
- """
- exe = sys.executable
- self = cls()
- reactor.spawnProcess(
- self, exe, [exe, "-c", self.program] + argv, env=env)
- return self
- run = classmethod(run)
-
-
- def __init__(self):
- self.bytes = []
- self.requests = []
-
-
- def parseChunks(self, bytes):
- """
- Called with all bytes received on stdout when the process exits.
- """
- raise NotImplementedError()
-
-
- def getResult(self):
- """
- Return a Deferred which will fire with the result of L{parseChunks}
- when the child process exits.
- """
- d = defer.Deferred()
- self.requests.append(d)
- return d
-
-
- def _fireResultDeferreds(self, result):
- """
- Callback all Deferreds returned up until now by L{getResult}
- with the given result object.
- """
- requests = self.requests
- self.requests = None
- for d in requests:
- d.callback(result)
-
-
- def outReceived(self, bytes):
- """
- Accumulate output from the child process in a list.
- """
- self.bytes.append(bytes)
-
-
- def processEnded(self, reason):
- """
- Handle process termination by parsing all received output and firing
- any waiting Deferreds.
- """
- self._fireResultDeferreds(self.parseChunks(self.bytes))
-
-
-
-
-class GetArgumentVector(UtilityProcessProtocol):
- """
- Protocol which will read a serialized argv from a process and
- expose it to interested parties.
- """
- program = (
- "from sys import stdout, argv\n"
- "stdout.write(chr(0).join(argv))\n"
- "stdout.flush()\n")
-
- def parseChunks(self, chunks):
- """
- Parse the output from the process to which this protocol was
- connected, which is a single unterminated line of \\0-separated
- strings giving the argv of that process. Return this as a list of
- str objects.
- """
- return ''.join(chunks).split('\0')
-
-
-
-class GetEnvironmentDictionary(UtilityProcessProtocol):
- """
- Protocol which will read a serialized environment dict from a process
- and expose it to interested parties.
- """
- program = (
- "from sys import stdout\n"
- "from os import environ\n"
- "items = environ.iteritems()\n"
- "stdout.write(chr(0).join([k + chr(0) + v for k, v in items]))\n"
- "stdout.flush()\n")
-
- def parseChunks(self, chunks):
- """
- Parse the output from the process to which this protocol was
- connected, which is a single unterminated line of \\0-separated
- strings giving key value pairs of the environment from that process.
- Return this as a dictionary.
- """
- environString = ''.join(chunks)
- if not environString:
- return {}
- environ = iter(environString.split('\0'))
- d = {}
- while 1:
- try:
- k = environ.next()
- except StopIteration:
- break
- else:
- v = environ.next()
- d[k] = v
- return d
-
-
-
-class ProcessTestCase(unittest.TestCase):
- """Test running a process."""
-
- usePTY = False
-
- def testStdio(self):
- """twisted.internet.stdio test."""
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_twisted.py")
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- env = {"PYTHONPATH": os.pathsep.join(sys.path)}
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=env,
- path=None, usePTY=self.usePTY)
- p.transport.write("hello, world")
- p.transport.write("abc")
- p.transport.write("123")
- p.transport.closeStdin()
-
- def processEnded(ign):
- self.assertEqual(p.outF.getvalue(), "hello, worldabc123",
- "Output follows:\n"
- "%s\n"
- "Error message from process_twisted follows:\n"
- "%s\n" % (p.outF.getvalue(), p.errF.getvalue()))
- return d.addCallback(processEnded)
-
-
- def test_unsetPid(self):
- """
- Test if pid is None/non-None before/after process termination. This
- reuses process_echoer.py to get a process that blocks on stdin.
- """
- finished = defer.Deferred()
- p = TrivialProcessProtocol(finished)
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_echoer.py")
- procTrans = reactor.spawnProcess(p, exe,
- [exe, scriptPath], env=None)
- self.failUnless(procTrans.pid)
-
- def afterProcessEnd(ignored):
- self.assertEqual(procTrans.pid, None)
-
- p.transport.closeStdin()
- return finished.addCallback(afterProcessEnd)
-
-
- def test_process(self):
- """
- Test running a process: check its output, it exitCode, some property of
- signalProcess.
- """
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_tester.py")
- d = defer.Deferred()
- p = TestProcessProtocol()
- p.deferred = d
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=None)
- def check(ignored):
- self.assertEqual(p.stages, [1, 2, 3, 4, 5])
- f = p.reason
- f.trap(error.ProcessTerminated)
- self.assertEqual(f.value.exitCode, 23)
- # would .signal be available on non-posix?
- # self.assertEqual(f.value.signal, None)
- self.assertRaises(
- error.ProcessExitedAlready, p.transport.signalProcess, 'INT')
- try:
- import process_tester, glob
- for f in glob.glob(process_tester.test_file_match):
- os.remove(f)
- except:
- pass
- d.addCallback(check)
- return d
-
- def testManyProcesses(self):
-
- def _check(results, protocols):
- for p in protocols:
- self.assertEqual(p.stages, [1, 2, 3, 4, 5], "[%d] stages = %s" % (id(p.transport), str(p.stages)))
- # test status code
- f = p.reason
- f.trap(error.ProcessTerminated)
- self.assertEqual(f.value.exitCode, 23)
-
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_tester.py")
- args = [exe, "-u", scriptPath]
- protocols = []
- deferreds = []
-
- for i in xrange(50):
- p = TestManyProcessProtocol()
- protocols.append(p)
- reactor.spawnProcess(p, exe, args, env=None)
- deferreds.append(p.deferred)
-
- deferredList = defer.DeferredList(deferreds, consumeErrors=True)
- deferredList.addCallback(_check, protocols)
- return deferredList
-
-
- def test_echo(self):
- """
- A spawning a subprocess which echoes its stdin to its stdout via
- C{reactor.spawnProcess} will result in that echoed output being
- delivered to outReceived.
- """
- finished = defer.Deferred()
- p = EchoProtocol(finished)
-
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_echoer.py")
- reactor.spawnProcess(p, exe, [exe, scriptPath], env=None)
-
- def asserts(ignored):
- self.failIf(p.failure, p.failure)
- self.failUnless(hasattr(p, 'buffer'))
- self.assertEqual(len(''.join(p.buffer)), len(p.s * p.n))
-
- def takedownProcess(err):
- p.transport.closeStdin()
- return err
-
- return finished.addCallback(asserts).addErrback(takedownProcess)
-
-
- def testCommandLine(self):
- args = [r'a\"b ', r'a\b ', r' a\\"b', r' a\\b', r'"foo bar" "', '\tab', '"\\', 'a"b', "a'b"]
- pyExe = sys.executable
- scriptPath = util.sibpath(__file__, "process_cmdline.py")
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- reactor.spawnProcess(p, pyExe, [pyExe, "-u", scriptPath]+args, env=None,
- path=None)
-
- def processEnded(ign):
- self.assertEqual(p.errF.getvalue(), "")
- recvdArgs = p.outF.getvalue().splitlines()
- self.assertEqual(recvdArgs, args)
- return d.addCallback(processEnded)
-
-
- def test_wrongArguments(self):
- """
- Test invalid arguments to spawnProcess: arguments and environment
- must only contains string or unicode, and not null bytes.
- """
- exe = sys.executable
- p = protocol.ProcessProtocol()
-
- badEnvs = [
- {"foo": 2},
- {"foo": "egg\0a"},
- {3: "bar"},
- {"bar\0foo": "bar"}]
-
- badArgs = [
- [exe, 2],
- "spam",
- [exe, "foo\0bar"]]
-
- # Sanity check - this will fail for people who have mucked with
- # their site configuration in a stupid way, but there's nothing we
- # can do about that.
- badUnicode = u'\N{SNOWMAN}'
- try:
- badUnicode.encode(sys.getdefaultencoding())
- except UnicodeEncodeError:
- # Okay, that unicode doesn't encode, put it in as a bad environment
- # key.
- badEnvs.append({badUnicode: 'value for bad unicode key'})
- badEnvs.append({'key for bad unicode value': badUnicode})
- badArgs.append([exe, badUnicode])
- else:
- # It _did_ encode. Most likely, Gtk2 is being used and the
- # default system encoding is UTF-8, which can encode anything.
- # In any case, if implicit unicode -> str conversion works for
- # that string, we can't test that TypeError gets raised instead,
- # so just leave it off.
- pass
-
- for env in badEnvs:
- self.assertRaises(
- TypeError,
- reactor.spawnProcess, p, exe, [exe, "-c", ""], env=env)
-
- for args in badArgs:
- self.assertRaises(
- TypeError,
- reactor.spawnProcess, p, exe, args, env=None)
-
-
- # Use upper-case so that the environment key test uses an upper case
- # name: some versions of Windows only support upper case environment
- # variable names, and I think Python (as of 2.5) doesn't use the right
- # syscall for lowercase or mixed case names to work anyway.
- okayUnicode = u"UNICODE"
- encodedValue = "UNICODE"
-
- def _deprecatedUnicodeSupportTest(self, processProtocolClass, argv=[], env={}):
- """
- Check that a deprecation warning is emitted when passing unicode to
- spawnProcess for an argv value or an environment key or value.
- Check that the warning is of the right type, has the right message,
- and refers to the correct file. Unfortunately, don't check that the
- line number is correct, because that is too hard for me to figure
- out.
-
- @param processProtocolClass: A L{UtilityProcessProtocol} subclass
- which will be instantiated to communicate with the child process.
-
- @param argv: The argv argument to spawnProcess.
-
- @param env: The env argument to spawnProcess.
-
- @return: A Deferred which fires when the test is complete.
- """
- # Sanity to check to make sure we can actually encode this unicode
- # with the default system encoding. This may be excessively
- # paranoid. -exarkun
- self.assertEqual(
- self.okayUnicode.encode(sys.getdefaultencoding()),
- self.encodedValue)
-
- p = self.assertWarns(DeprecationWarning,
- "Argument strings and environment keys/values passed to "
- "reactor.spawnProcess should be str, not unicode.", __file__,
- processProtocolClass.run, reactor, argv, env)
- return p.getResult()
-
-
- def test_deprecatedUnicodeArgvSupport(self):
- """
- Test that a unicode string passed for an argument value is allowed
- if it can be encoded with the default system encoding, but that a
- deprecation warning is emitted.
- """
- d = self._deprecatedUnicodeSupportTest(GetArgumentVector, argv=[self.okayUnicode])
- def gotArgVector(argv):
- self.assertEqual(argv, ['-c', self.encodedValue])
- d.addCallback(gotArgVector)
- return d
-
-
- def test_deprecatedUnicodeEnvKeySupport(self):
- """
- Test that a unicode string passed for the key of the environment
- dictionary is allowed if it can be encoded with the default system
- encoding, but that a deprecation warning is emitted.
- """
- d = self._deprecatedUnicodeSupportTest(
- GetEnvironmentDictionary, env={self.okayUnicode: self.encodedValue})
- def gotEnvironment(environ):
- self.assertEqual(environ[self.encodedValue], self.encodedValue)
- d.addCallback(gotEnvironment)
- return d
-
-
- def test_deprecatedUnicodeEnvValueSupport(self):
- """
- Test that a unicode string passed for the value of the environment
- dictionary is allowed if it can be encoded with the default system
- encoding, but that a deprecation warning is emitted.
- """
- d = self._deprecatedUnicodeSupportTest(
- GetEnvironmentDictionary, env={self.encodedValue: self.okayUnicode})
- def gotEnvironment(environ):
- # On Windows, the environment contains more things than we
- # specified, so only make sure that at least the key we wanted
- # is there, rather than testing the dictionary for exact
- # equality.
- self.assertEqual(environ[self.encodedValue], self.encodedValue)
- d.addCallback(gotEnvironment)
- return d
-
-
-
-class TwoProcessProtocol(protocol.ProcessProtocol):
- num = -1
- finished = 0
- def __init__(self):
- self.deferred = defer.Deferred()
- def outReceived(self, data):
- pass
- def processEnded(self, reason):
- self.finished = 1
- self.deferred.callback(None)
-
-class TestTwoProcessesBase:
- def setUp(self):
- self.processes = [None, None]
- self.pp = [None, None]
- self.done = 0
- self.verbose = 0
-
- def createProcesses(self, usePTY=0):
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_reader.py")
- for num in (0,1):
- self.pp[num] = TwoProcessProtocol()
- self.pp[num].num = num
- p = reactor.spawnProcess(self.pp[num],
- exe, [exe, "-u", scriptPath], env=None,
- usePTY=usePTY)
- self.processes[num] = p
-
- def close(self, num):
- if self.verbose: print "closing stdin [%d]" % num
- p = self.processes[num]
- pp = self.pp[num]
- self.failIf(pp.finished, "Process finished too early")
- p.loseConnection()
- if self.verbose: print self.pp[0].finished, self.pp[1].finished
-
- def _onClose(self):
- return defer.gatherResults([ p.deferred for p in self.pp ])
-
- def testClose(self):
- if self.verbose: print "starting processes"
- self.createProcesses()
- reactor.callLater(1, self.close, 0)
- reactor.callLater(2, self.close, 1)
- return self._onClose()
-
-class TestTwoProcessesNonPosix(TestTwoProcessesBase, unittest.TestCase):
- pass
-
-class TestTwoProcessesPosix(TestTwoProcessesBase, unittest.TestCase):
- def tearDown(self):
- for pp, pr in zip(self.pp, self.processes):
- if not pp.finished:
- try:
- os.kill(pr.pid, signal.SIGTERM)
- except OSError:
- # If the test failed the process may already be dead
- # The error here is only noise
- pass
- return self._onClose()
-
- def kill(self, num):
- if self.verbose: print "kill [%d] with SIGTERM" % num
- p = self.processes[num]
- pp = self.pp[num]
- self.failIf(pp.finished, "Process finished too early")
- os.kill(p.pid, signal.SIGTERM)
- if self.verbose: print self.pp[0].finished, self.pp[1].finished
-
- def testKill(self):
- if self.verbose: print "starting processes"
- self.createProcesses(usePTY=0)
- reactor.callLater(1, self.kill, 0)
- reactor.callLater(2, self.kill, 1)
- return self._onClose()
-
- def testClosePty(self):
- if self.verbose: print "starting processes"
- self.createProcesses(usePTY=1)
- reactor.callLater(1, self.close, 0)
- reactor.callLater(2, self.close, 1)
- return self._onClose()
-
- def testKillPty(self):
- if self.verbose: print "starting processes"
- self.createProcesses(usePTY=1)
- reactor.callLater(1, self.kill, 0)
- reactor.callLater(2, self.kill, 1)
- return self._onClose()
-
-class FDChecker(protocol.ProcessProtocol):
- state = 0
- data = ""
- failed = None
-
- def __init__(self, d):
- self.deferred = d
-
- def fail(self, why):
- self.failed = why
- self.deferred.callback(None)
-
- def connectionMade(self):
- self.transport.writeToChild(0, "abcd")
- self.state = 1
-
- def childDataReceived(self, childFD, data):
- if self.state == 1:
- if childFD != 1:
- self.fail("read '%s' on fd %d (not 1) during state 1" \
- % (childFD, data))
- return
- self.data += data
- #print "len", len(self.data)
- if len(self.data) == 6:
- if self.data != "righto":
- self.fail("got '%s' on fd1, expected 'righto'" \
- % self.data)
- return
- self.data = ""
- self.state = 2
- #print "state2", self.state
- self.transport.writeToChild(3, "efgh")
- return
- if self.state == 2:
- self.fail("read '%s' on fd %s during state 2" % (childFD, data))
- return
- if self.state == 3:
- if childFD != 1:
- self.fail("read '%s' on fd %s (not 1) during state 3" \
- % (childFD, data))
- return
- self.data += data
- if len(self.data) == 6:
- if self.data != "closed":
- self.fail("got '%s' on fd1, expected 'closed'" \
- % self.data)
- return
- self.state = 4
- return
- if self.state == 4:
- self.fail("read '%s' on fd %s during state 4" % (childFD, data))
- return
-
- def childConnectionLost(self, childFD):
- if self.state == 1:
- self.fail("got connectionLost(%d) during state 1" % childFD)
- return
- if self.state == 2:
- if childFD != 4:
- self.fail("got connectionLost(%d) (not 4) during state 2" \
- % childFD)
- return
- self.state = 3
- self.transport.closeChildFD(5)
- return
-
- def processEnded(self, status):
- rc = status.value.exitCode
- if self.state != 4:
- self.fail("processEnded early, rc %d" % rc)
- return
- if status.value.signal != None:
- self.fail("processEnded with signal %s" % status.value.signal)
- return
- if rc != 0:
- self.fail("processEnded with rc %d" % rc)
- return
- self.deferred.callback(None)
-
-
-class FDTest(unittest.TestCase):
-
- def testFD(self):
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_fds.py")
- d = defer.Deferred()
- p = FDChecker(d)
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=None,
- path=None,
- childFDs={0:"w", 1:"r", 2:2,
- 3:"w", 4:"r", 5:"w"})
- d.addCallback(lambda x : self.failIf(p.failed, p.failed))
- return d
-
- def testLinger(self):
- # See what happens when all the pipes close before the process
- # actually stops. This test *requires* SIGCHLD catching to work,
- # as there is no other way to find out the process is done.
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_linger.py")
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=None,
- path=None,
- childFDs={1:"r", 2:2},
- )
- def processEnded(ign):
- self.assertEqual(p.outF.getvalue(),
- "here is some text\ngoodbye\n")
- return d.addCallback(processEnded)
-
-
-
-class Accumulator(protocol.ProcessProtocol):
- """Accumulate data from a process."""
-
- closed = 0
- endedDeferred = None
-
- def connectionMade(self):
- self.outF = StringIO.StringIO()
- self.errF = StringIO.StringIO()
-
- def outReceived(self, d):
- self.outF.write(d)
-
- def errReceived(self, d):
- self.errF.write(d)
-
- def outConnectionLost(self):
- pass
-
- def errConnectionLost(self):
- pass
-
- def processEnded(self, reason):
- self.closed = 1
- if self.endedDeferred is not None:
- d, self.endedDeferred = self.endedDeferred, None
- d.callback(None)
-
-
-class PosixProcessBase:
- """
- Test running processes.
- """
- usePTY = False
-
- def getCommand(self, commandName):
- """
- Return the path of the shell command named C{commandName}, looking at
- common locations.
- """
- if os.path.exists('/bin/%s' % (commandName,)):
- cmd = '/bin/%s' % (commandName,)
- elif os.path.exists('/usr/bin/%s' % (commandName,)):
- cmd = '/usr/bin/%s' % (commandName,)
- else:
- raise RuntimeError(
- "%s not found in /bin or /usr/bin" % (commandName,))
- return cmd
-
- def testNormalTermination(self):
- cmd = self.getCommand('true')
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- reactor.spawnProcess(p, cmd, ['true'], env=None,
- usePTY=self.usePTY)
- def check(ignored):
- p.reason.trap(error.ProcessDone)
- self.assertEqual(p.reason.value.exitCode, 0)
- self.assertEqual(p.reason.value.signal, None)
- d.addCallback(check)
- return d
-
-
- def test_abnormalTermination(self):
- """
- When a process terminates with a system exit code set to 1,
- C{processEnded} is called with a L{error.ProcessTerminated} error,
- the C{exitCode} attribute reflecting the system exit code.
- """
- exe = sys.executable
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- reactor.spawnProcess(p, exe, [exe, '-c', 'import sys; sys.exit(1)'],
- env=None, usePTY=self.usePTY)
-
- def check(ignored):
- p.reason.trap(error.ProcessTerminated)
- self.assertEqual(p.reason.value.exitCode, 1)
- self.assertEqual(p.reason.value.signal, None)
- d.addCallback(check)
- return d
-
-
- def _testSignal(self, sig):
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_signal.py")
- d = defer.Deferred()
- p = SignalProtocol(d, sig)
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=None,
- usePTY=self.usePTY)
- return d
-
-
- def test_signalHUP(self):
- """
- Sending the SIGHUP signal to a running process interrupts it, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} set to C{None} and the C{signal} attribute set to
- C{signal.SIGHUP}. C{os.WTERMSIG} can also be used on the C{status}
- attribute to extract the signal value.
- """
- return self._testSignal('HUP')
-
-
- def test_signalINT(self):
- """
- Sending the SIGINT signal to a running process interrupts it, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} set to C{None} and the C{signal} attribute set to
- C{signal.SIGINT}. C{os.WTERMSIG} can also be used on the C{status}
- attribute to extract the signal value.
- """
- return self._testSignal('INT')
-
-
- def test_signalKILL(self):
- """
- Sending the SIGKILL signal to a running process interrupts it, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} set to C{None} and the C{signal} attribute set to
- C{signal.SIGKILL}. C{os.WTERMSIG} can also be used on the C{status}
- attribute to extract the signal value.
- """
- return self._testSignal('KILL')
-
-
- def test_signalTERM(self):
- """
- Sending the SIGTERM signal to a running process interrupts it, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} set to C{None} and the C{signal} attribute set to
- C{signal.SIGTERM}. C{os.WTERMSIG} can also be used on the C{status}
- attribute to extract the signal value.
- """
- return self._testSignal('TERM')
-
-
- def test_childSignalHandling(self):
- """
- The disposition of signals which are ignored in the parent
- process is reset to the default behavior for the child
- process.
- """
- # Somewhat arbitrarily select SIGUSR1 here. It satisfies our
- # requirements that:
- # - The interpreter not fiddle around with the handler
- # behind our backs at startup time (this disqualifies
- # signals like SIGINT and SIGPIPE).
- # - The default behavior is to exit.
- #
- # This lets us send the signal to the child and then verify
- # that it exits with a status code indicating that it was
- # indeed the signal which caused it to exit.
- which = signal.SIGUSR1
-
- # Ignore the signal in the parent (and make sure we clean it
- # up).
- handler = signal.signal(which, signal.SIG_IGN)
- self.addCleanup(signal.signal, signal.SIGUSR1, handler)
-
- # Now do the test.
- return self._testSignal(signal.SIGUSR1)
-
-
- def test_executionError(self):
- """
- Raise an error during execvpe to check error management.
- """
- cmd = self.getCommand('false')
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- def buggyexecvpe(command, args, environment):
- raise RuntimeError("Ouch")
- oldexecvpe = os.execvpe
- os.execvpe = buggyexecvpe
- try:
- reactor.spawnProcess(p, cmd, ['false'], env=None,
- usePTY=self.usePTY)
-
- def check(ignored):
- errData = "".join(p.errData + p.outData)
- self.assertIn("Upon execvpe", errData)
- self.assertIn("Ouch", errData)
- d.addCallback(check)
- finally:
- os.execvpe = oldexecvpe
- return d
-
-
- def test_errorInProcessEnded(self):
- """
- The handler which reaps a process is removed when the process is
- reaped, even if the protocol's C{processEnded} method raises an
- exception.
- """
- connected = defer.Deferred()
- ended = defer.Deferred()
-
- # This script runs until we disconnect its transport.
- pythonExecutable = sys.executable
- scriptPath = util.sibpath(__file__, "process_echoer.py")
-
- class ErrorInProcessEnded(protocol.ProcessProtocol):
- """
- A protocol that raises an error in C{processEnded}.
- """
- def makeConnection(self, transport):
- connected.callback(transport)
-
- def processEnded(self, reason):
- reactor.callLater(0, ended.callback, None)
- raise RuntimeError("Deliberate error")
-
- # Launch the process.
- reactor.spawnProcess(
- ErrorInProcessEnded(), pythonExecutable,
- [pythonExecutable, scriptPath],
- env=None, path=None)
-
- pid = []
- def cbConnected(transport):
- pid.append(transport.pid)
- # There's now a reap process handler registered.
- self.assertIn(transport.pid, process.reapProcessHandlers)
-
- # Kill the process cleanly, triggering an error in the protocol.
- transport.loseConnection()
- connected.addCallback(cbConnected)
-
- def checkTerminated(ignored):
- # The exception was logged.
- excs = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(excs), 1)
- # The process is no longer scheduled for reaping.
- self.assertNotIn(pid[0], process.reapProcessHandlers)
- ended.addCallback(checkTerminated)
-
- return ended
-
-
-
-class MockSignal(object):
- """
- Neuter L{signal.signal}, but pass other attributes unscathed
- """
- def signal(self, sig, action):
- return signal.getsignal(sig)
-
- def __getattr__(self, attr):
- return getattr(signal, attr)
-
-
-class MockOS(object):
- """
- The mock OS: overwrite L{os}, L{fcntl} and {sys} functions with fake ones.
-
- @ivar exited: set to True when C{_exit} is called.
- @type exited: C{bool}
-
- @ivar O_RDWR: dumb value faking C{os.O_RDWR}.
- @type O_RDWR: C{int}
-
- @ivar O_NOCTTY: dumb value faking C{os.O_NOCTTY}.
- @type O_NOCTTY: C{int}
-
- @ivar WNOHANG: dumb value faking C{os.WNOHANG}.
- @type WNOHANG: C{int}
-
- @ivar raiseFork: if not C{None}, subsequent calls to fork will raise this
- object.
- @type raiseFork: C{NoneType} or C{Exception}
-
- @ivar raiseExec: if set, subsequent calls to execvpe will raise an error.
- @type raiseExec: C{bool}
-
- @ivar fdio: fake file object returned by calls to fdopen.
- @type fdio: C{StringIO.StringIO}
-
- @ivar actions: hold names of some actions executed by the object, in order
- of execution.
-
- @type actions: C{list} of C{str}
-
- @ivar closed: keep track of the file descriptor closed.
- @param closed: C{list} of C{int}
-
- @ivar child: whether fork return for the child or the parent.
- @type child: C{bool}
-
- @ivar pipeCount: count the number of time that C{os.pipe} has been called.
- @type pipeCount: C{int}
-
- @ivar raiseWaitPid: if set, subsequent calls to waitpid will raise
- the error specified.
- @type raiseWaitPid: C{None} or a class
-
- @ivar waitChild: if set, subsequent calls to waitpid will return it.
- @type waitChild: C{None} or a tuple
-
- @ivar euid: the uid returned by the fake C{os.geteuid}
- @type euid: C{int}
-
- @ivar egid: the gid returned by the fake C{os.getegid}
- @type egid: C{int}
-
- @ivar seteuidCalls: stored results of C{os.seteuid} calls.
- @type seteuidCalls: C{list}
-
- @ivar setegidCalls: stored results of C{os.setegid} calls.
- @type setegidCalls: C{list}
-
- @ivar path: the path returned by C{os.path.expanduser}.
- @type path: C{str}
-
- @ivar raiseKill: if set, subsequent call to kill will raise the error
- specified.
- @type raiseKill: C{None} or an exception instance.
- """
- exited = False
- raiseExec = False
- fdio = None
- child = True
- raiseWaitPid = None
- raiseFork = None
- waitChild = None
- euid = 0
- egid = 0
- path = None
- raiseKill = None
-
- def __init__(self):
- """
- Initialize data structures.
- """
- self.actions = []
- self.closed = []
- self.pipeCount = 0
- self.O_RDWR = -1
- self.O_NOCTTY = -2
- self.WNOHANG = -4
- self.WEXITSTATUS = lambda x: 0
- self.WIFEXITED = lambda x: 1
- self.seteuidCalls = []
- self.setegidCalls = []
-
-
- def open(self, dev, flags):
- """
- Fake C{os.open}. Return a non fd number to be sure it's not used
- elsewhere.
- """
- return -3
-
-
- def fstat(self, fd):
- """
- Fake C{os.fstat}. Return a C{os.stat_result} filled with garbage.
- """
- return os.stat_result((0,) * 10)
-
-
- def fdopen(self, fd, flag):
- """
- Fake C{os.fdopen}. Return a StringIO object whose content can be tested
- later via C{self.fdio}.
- """
- self.fdio = StringIO.StringIO()
- return self.fdio
-
-
- def setsid(self):
- """
- Fake C{os.setsid}. Do nothing.
- """
-
-
- def fork(self):
- """
- Fake C{os.fork}. Save the action in C{self.actions}, and return 0 if
- C{self.child} is set, or a dumb number.
- """
- self.actions.append(('fork', gc.isenabled()))
- if self.raiseFork is not None:
- raise self.raiseFork
- elif self.child:
- # Child result is 0
- return 0
- else:
- return 21
-
-
- def close(self, fd):
- """
- Fake C{os.close}, saving the closed fd in C{self.closed}.
- """
- self.closed.append(fd)
-
-
- def dup2(self, fd1, fd2):
- """
- Fake C{os.dup2}. Do nothing.
- """
-
-
- def write(self, fd, data):
- """
- Fake C{os.write}. Do nothing.
- """
-
-
- def execvpe(self, command, args, env):
- """
- Fake C{os.execvpe}. Save the action, and raise an error if
- C{self.raiseExec} is set.
- """
- self.actions.append('exec')
- if self.raiseExec:
- raise RuntimeError("Bar")
-
-
- def pipe(self):
- """
- Fake C{os.pipe}. Return non fd numbers to be sure it's not used
- elsewhere, and increment C{self.pipeCount}. This is used to uniquify
- the result.
- """
- self.pipeCount += 1
- return - 2 * self.pipeCount + 1, - 2 * self.pipeCount
-
-
- def ttyname(self, fd):
- """
- Fake C{os.ttyname}. Return a dumb string.
- """
- return "foo"
-
-
- def _exit(self, code):
- """
- Fake C{os._exit}. Save the action, set the C{self.exited} flag, and
- raise C{SystemError}.
- """
- self.actions.append('exit')
- self.exited = True
- # Don't forget to raise an error, or you'll end up in parent
- # code path.
- raise SystemError()
-
-
- def ioctl(self, fd, flags, arg):
- """
- Override C{fcntl.ioctl}. Do nothing.
- """
-
-
- def setNonBlocking(self, fd):
- """
- Override C{fdesc.setNonBlocking}. Do nothing.
- """
-
-
- def waitpid(self, pid, options):
- """
- Override C{os.waitpid}. Return values meaning that the child process
- has exited, save executed action.
- """
- self.actions.append('waitpid')
- if self.raiseWaitPid is not None:
- raise self.raiseWaitPid
- if self.waitChild is not None:
- return self.waitChild
- return 1, 0
-
-
- def settrace(self, arg):
- """
- Override C{sys.settrace} to keep coverage working.
- """
-
-
- def getgid(self):
- """
- Override C{os.getgid}. Return a dumb number.
- """
- return 1235
-
-
- def getuid(self):
- """
- Override C{os.getuid}. Return a dumb number.
- """
- return 1237
-
-
- def setuid(self, val):
- """
- Override C{os.setuid}. Do nothing.
- """
- self.actions.append(('setuid', val))
-
-
- def setgid(self, val):
- """
- Override C{os.setgid}. Do nothing.
- """
- self.actions.append(('setgid', val))
-
-
- def setregid(self, val1, val2):
- """
- Override C{os.setregid}. Do nothing.
- """
- self.actions.append(('setregid', val1, val2))
-
-
- def setreuid(self, val1, val2):
- """
- Override C{os.setreuid}. Save the action.
- """
- self.actions.append(('setreuid', val1, val2))
-
-
- def switchUID(self, uid, gid):
- """
- Override C{util.switchuid}. Save the action.
- """
- self.actions.append(('switchuid', uid, gid))
-
-
- def openpty(self):
- """
- Override C{pty.openpty}, returning fake file descriptors.
- """
- return -12, -13
-
-
- def geteuid(self):
- """
- Mock C{os.geteuid}, returning C{self.euid} instead.
- """
- return self.euid
-
-
- def getegid(self):
- """
- Mock C{os.getegid}, returning C{self.egid} instead.
- """
- return self.egid
-
-
- def seteuid(self, egid):
- """
- Mock C{os.seteuid}, store result.
- """
- self.seteuidCalls.append(egid)
-
-
- def setegid(self, egid):
- """
- Mock C{os.setegid}, store result.
- """
- self.setegidCalls.append(egid)
-
-
- def expanduser(self, path):
- """
- Mock C{os.path.expanduser}.
- """
- return self.path
-
-
- def getpwnam(self, user):
- """
- Mock C{pwd.getpwnam}.
- """
- return 0, 0, 1, 2
-
-
- def listdir(self, path):
- """
- Override C{os.listdir}, returning fake contents of '/dev/fd'
- """
- return "-1", "-2"
-
-
- def kill(self, pid, signalID):
- """
- Override C{os.kill}: save the action and raise C{self.raiseKill} if
- specified.
- """
- self.actions.append(('kill', pid, signalID))
- if self.raiseKill is not None:
- raise self.raiseKill
-
-
-
-if process is not None:
- class DumbProcessWriter(process.ProcessWriter):
- """
- A fake L{process.ProcessWriter} used for tests.
- """
-
- def startReading(self):
- """
- Here's the faking: don't do anything here.
- """
-
-
-
- class DumbProcessReader(process.ProcessReader):
- """
- A fake L{process.ProcessReader} used for tests.
- """
-
- def startReading(self):
- """
- Here's the faking: don't do anything here.
- """
-
-
-
- class DumbPTYProcess(process.PTYProcess):
- """
- A fake L{process.PTYProcess} used for tests.
- """
-
- def startReading(self):
- """
- Here's the faking: don't do anything here.
- """
-
-
-
-class MockProcessTestCase(unittest.TestCase):
- """
- Mock a process runner to test forked child code path.
- """
- if process is None:
- skip = "twisted.internet.process is never used on Windows"
-
- def setUp(self):
- """
- Replace L{process} os, fcntl, sys, switchUID, fdesc and pty modules
- with the mock class L{MockOS}.
- """
- if gc.isenabled():
- self.addCleanup(gc.enable)
- else:
- self.addCleanup(gc.disable)
- self.mockos = MockOS()
- self.mockos.euid = 1236
- self.mockos.egid = 1234
- self.patch(process, "os", self.mockos)
- self.patch(process, "fcntl", self.mockos)
- self.patch(process, "sys", self.mockos)
- self.patch(process, "switchUID", self.mockos.switchUID)
- self.patch(process, "fdesc", self.mockos)
- self.patch(process.Process, "processReaderFactory", DumbProcessReader)
- self.patch(process.Process, "processWriterFactory", DumbProcessWriter)
- self.patch(process, "pty", self.mockos)
-
- self.mocksig = MockSignal()
- self.patch(process, "signal", self.mocksig)
-
-
- def tearDown(self):
- """
- Reset processes registered for reap.
- """
- process.reapProcessHandlers = {}
-
-
- def test_mockFork(self):
- """
- Test a classic spawnProcess. Check the path of the client code:
- fork, exec, exit.
- """
- gc.enable()
-
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- try:
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False)
- except SystemError:
- self.assert_(self.mockos.exited)
- self.assertEqual(
- self.mockos.actions, [("fork", False), "exec", "exit"])
- else:
- self.fail("Should not be here")
-
- # It should leave the garbage collector disabled.
- self.assertFalse(gc.isenabled())
-
-
- def _mockForkInParentTest(self):
- """
- Assert that in the main process, spawnProcess disables the garbage
- collector, calls fork, closes the pipe file descriptors it created for
- the child process, and calls waitpid.
- """
- self.mockos.child = False
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False)
- # It should close the first read pipe, and the 2 last write pipes
- self.assertEqual(set(self.mockos.closed), set([-1, -4, -6]))
- self.assertEqual(self.mockos.actions, [("fork", False), "waitpid"])
-
-
- def test_mockForkInParentGarbageCollectorEnabled(self):
- """
- The garbage collector should be enabled when L{reactor.spawnProcess}
- returns if it was initially enabled.
-
- @see L{_mockForkInParentTest}
- """
- gc.enable()
- self._mockForkInParentTest()
- self.assertTrue(gc.isenabled())
-
-
- def test_mockForkInParentGarbageCollectorDisabled(self):
- """
- The garbage collector should be disabled when L{reactor.spawnProcess}
- returns if it was initially disabled.
-
- @see L{_mockForkInParentTest}
- """
- gc.disable()
- self._mockForkInParentTest()
- self.assertFalse(gc.isenabled())
-
-
- def test_mockForkTTY(self):
- """
- Test a TTY spawnProcess: check the path of the client code:
- fork, exec, exit.
- """
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- try:
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=True)
- except SystemError:
- self.assert_(self.mockos.exited)
- self.assertEqual(
- self.mockos.actions, [("fork", False), "exec", "exit"])
- else:
- self.fail("Should not be here")
-
-
- def _mockWithForkError(self):
- """
- Assert that if the fork call fails, no other process setup calls are
- made and that spawnProcess raises the exception fork raised.
- """
- self.mockos.raiseFork = OSError(errno.EAGAIN, None)
- protocol = TrivialProcessProtocol(None)
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None)
- self.assertEqual(self.mockos.actions, [("fork", False)])
-
-
- def test_mockWithForkErrorGarbageCollectorEnabled(self):
- """
- The garbage collector should be enabled when L{reactor.spawnProcess}
- raises because L{os.fork} raised, if it was initially enabled.
- """
- gc.enable()
- self._mockWithForkError()
- self.assertTrue(gc.isenabled())
-
-
- def test_mockWithForkErrorGarbageCollectorDisabled(self):
- """
- The garbage collector should be disabled when
- L{reactor.spawnProcess} raises because L{os.fork} raised, if it was
- initially disabled.
- """
- gc.disable()
- self._mockWithForkError()
- self.assertFalse(gc.isenabled())
-
-
- def test_mockForkErrorCloseFDs(self):
- """
- When C{os.fork} raises an exception, the file descriptors created
- before are closed and don't leak.
- """
- self._mockWithForkError()
- self.assertEqual(set(self.mockos.closed), set([-1, -4, -6, -2, -3, -5]))
-
-
- def test_mockForkErrorGivenFDs(self):
- """
- When C{os.forks} raises an exception and that file descriptors have
- been specified with the C{childFDs} arguments of
- L{reactor.spawnProcess}, they are not closed.
- """
- self.mockos.raiseFork = OSError(errno.EAGAIN, None)
- protocol = TrivialProcessProtocol(None)
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None,
- childFDs={0: -10, 1: -11, 2: -13})
- self.assertEqual(self.mockos.actions, [("fork", False)])
- self.assertEqual(self.mockos.closed, [])
-
- # We can also put "r" or "w" to let twisted create the pipes
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None,
- childFDs={0: "r", 1: -11, 2: -13})
- self.assertEqual(set(self.mockos.closed), set([-1, -2]))
-
-
- def test_mockForkErrorClosePTY(self):
- """
- When C{os.fork} raises an exception, the file descriptors created by
- C{pty.openpty} are closed and don't leak, when C{usePTY} is set to
- C{True}.
- """
- self.mockos.raiseFork = OSError(errno.EAGAIN, None)
- protocol = TrivialProcessProtocol(None)
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None,
- usePTY=True)
- self.assertEqual(self.mockos.actions, [("fork", False)])
- self.assertEqual(set(self.mockos.closed), set([-12, -13]))
-
-
- def test_mockForkErrorPTYGivenFDs(self):
- """
- If a tuple is passed to C{usePTY} to specify slave and master file
- descriptors and that C{os.fork} raises an exception, these file
- descriptors aren't closed.
- """
- self.mockos.raiseFork = OSError(errno.EAGAIN, None)
- protocol = TrivialProcessProtocol(None)
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None,
- usePTY=(-20, -21, 'foo'))
- self.assertEqual(self.mockos.actions, [("fork", False)])
- self.assertEqual(self.mockos.closed, [])
-
-
- def test_mockWithExecError(self):
- """
- Spawn a process but simulate an error during execution in the client
- path: C{os.execvpe} raises an error. It should close all the standard
- fds, try to print the error encountered, and exit cleanly.
- """
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- self.mockos.raiseExec = True
- try:
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False)
- except SystemError:
- self.assert_(self.mockos.exited)
- self.assertEqual(
- self.mockos.actions, [("fork", False), "exec", "exit"])
- # Check that fd have been closed
- self.assertIn(0, self.mockos.closed)
- self.assertIn(1, self.mockos.closed)
- self.assertIn(2, self.mockos.closed)
- # Check content of traceback
- self.assertIn("RuntimeError: Bar", self.mockos.fdio.getvalue())
- else:
- self.fail("Should not be here")
-
-
- def test_mockSetUid(self):
- """
- Try creating a process with setting its uid: it's almost the same path
- as the standard path, but with a C{switchUID} call before the exec.
- """
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- try:
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False, uid=8080)
- except SystemError:
- self.assert_(self.mockos.exited)
- self.assertEqual(self.mockos.actions,
- [('setuid', 0), ('setgid', 0), ('fork', False),
- ('switchuid', 8080, 1234), 'exec', 'exit'])
- else:
- self.fail("Should not be here")
-
-
- def test_mockSetUidInParent(self):
- """
- Try creating a process with setting its uid, in the parent path: it
- should switch to root before fork, then restore initial uid/gids.
- """
- self.mockos.child = False
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False, uid=8080)
- self.assertEqual(self.mockos.actions,
- [('setuid', 0), ('setgid', 0), ('fork', False),
- ('setregid', 1235, 1234), ('setreuid', 1237, 1236), 'waitpid'])
-
-
- def test_mockPTYSetUid(self):
- """
- Try creating a PTY process with setting its uid: it's almost the same
- path as the standard path, but with a C{switchUID} call before the
- exec.
- """
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- try:
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=True, uid=8081)
- except SystemError:
- self.assert_(self.mockos.exited)
- self.assertEqual(self.mockos.actions,
- [('setuid', 0), ('setgid', 0), ('fork', False),
- ('switchuid', 8081, 1234), 'exec', 'exit'])
- else:
- self.fail("Should not be here")
-
-
- def test_mockPTYSetUidInParent(self):
- """
- Try creating a PTY process with setting its uid, in the parent path: it
- should switch to root before fork, then restore initial uid/gids.
- """
- self.mockos.child = False
- cmd = '/mock/ouch'
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- oldPTYProcess = process.PTYProcess
- try:
- process.PTYProcess = DumbPTYProcess
- reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=True, uid=8080)
- finally:
- process.PTYProcess = oldPTYProcess
- self.assertEqual(self.mockos.actions,
- [('setuid', 0), ('setgid', 0), ('fork', False),
- ('setregid', 1235, 1234), ('setreuid', 1237, 1236), 'waitpid'])
-
-
- def test_mockWithWaitError(self):
- """
- Test that reapProcess logs errors raised.
- """
- self.mockos.child = False
- cmd = '/mock/ouch'
- self.mockos.waitChild = (0, 0)
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- proc = reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False)
- self.assertEqual(self.mockos.actions, [("fork", False), "waitpid"])
-
- self.mockos.raiseWaitPid = OSError()
- proc.reapProcess()
- errors = self.flushLoggedErrors()
- self.assertEqual(len(errors), 1)
- errors[0].trap(OSError)
-
-
- def test_mockErrorECHILDInReapProcess(self):
- """
- Test that reapProcess doesn't log anything when waitpid raises a
- C{OSError} with errno C{ECHILD}.
- """
- self.mockos.child = False
- cmd = '/mock/ouch'
- self.mockos.waitChild = (0, 0)
-
- d = defer.Deferred()
- p = TrivialProcessProtocol(d)
- proc = reactor.spawnProcess(p, cmd, ['ouch'], env=None,
- usePTY=False)
- self.assertEqual(self.mockos.actions, [("fork", False), "waitpid"])
-
- self.mockos.raiseWaitPid = OSError()
- self.mockos.raiseWaitPid.errno = errno.ECHILD
- # This should not produce any errors
- proc.reapProcess()
-
-
- def test_mockErrorInPipe(self):
- """
- If C{os.pipe} raises an exception after some pipes where created, the
- created pipes are closed and don't leak.
- """
- pipes = [-1, -2, -3, -4]
- def pipe():
- try:
- return pipes.pop(0), pipes.pop(0)
- except IndexError:
- raise OSError()
- self.mockos.pipe = pipe
- protocol = TrivialProcessProtocol(None)
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None)
- self.assertEqual(self.mockos.actions, [])
- self.assertEqual(set(self.mockos.closed), set([-4, -3, -2, -1]))
-
-
- def test_mockErrorInForkRestoreUID(self):
- """
- If C{os.fork} raises an exception and a UID change has been made, the
- previous UID and GID are restored.
- """
- self.mockos.raiseFork = OSError(errno.EAGAIN, None)
- protocol = TrivialProcessProtocol(None)
- self.assertRaises(OSError, reactor.spawnProcess, protocol, None,
- uid=8080)
- self.assertEqual(self.mockos.actions,
- [('setuid', 0), ('setgid', 0), ("fork", False),
- ('setregid', 1235, 1234), ('setreuid', 1237, 1236)])
-
-
- def test_kill(self):
- """
- L{process.Process.signalProcess} calls C{os.kill} translating the given
- signal string to the PID.
- """
- self.mockos.child = False
- self.mockos.waitChild = (0, 0)
- cmd = '/mock/ouch'
- p = TrivialProcessProtocol(None)
- proc = reactor.spawnProcess(p, cmd, ['ouch'], env=None, usePTY=False)
- proc.signalProcess("KILL")
- self.assertEqual(self.mockos.actions,
- [('fork', False), 'waitpid', ('kill', 21, signal.SIGKILL)])
-
-
- def test_killExited(self):
- """
- L{process.Process.signalProcess} raises L{error.ProcessExitedAlready}
- if the process has exited.
- """
- self.mockos.child = False
- cmd = '/mock/ouch'
- p = TrivialProcessProtocol(None)
- proc = reactor.spawnProcess(p, cmd, ['ouch'], env=None, usePTY=False)
- # We didn't specify a waitpid value, so the waitpid call in
- # registerReapProcessHandler has already reaped the process
- self.assertRaises(error.ProcessExitedAlready,
- proc.signalProcess, "KILL")
-
-
- def test_killExitedButNotDetected(self):
- """
- L{process.Process.signalProcess} raises L{error.ProcessExitedAlready}
- if the process has exited but that twisted hasn't seen it (for example,
- if the process has been waited outside of twisted): C{os.kill} then
- raise C{OSError} with C{errno.ESRCH} as errno.
- """
- self.mockos.child = False
- self.mockos.waitChild = (0, 0)
- cmd = '/mock/ouch'
- p = TrivialProcessProtocol(None)
- proc = reactor.spawnProcess(p, cmd, ['ouch'], env=None, usePTY=False)
- self.mockos.raiseKill = OSError(errno.ESRCH, "Not found")
- self.assertRaises(error.ProcessExitedAlready,
- proc.signalProcess, "KILL")
-
-
- def test_killErrorInKill(self):
- """
- L{process.Process.signalProcess} doesn't mask C{OSError} exceptions if
- the errno is different from C{errno.ESRCH}.
- """
- self.mockos.child = False
- self.mockos.waitChild = (0, 0)
- cmd = '/mock/ouch'
- p = TrivialProcessProtocol(None)
- proc = reactor.spawnProcess(p, cmd, ['ouch'], env=None, usePTY=False)
- self.mockos.raiseKill = OSError(errno.EINVAL, "Invalid signal")
- err = self.assertRaises(OSError,
- proc.signalProcess, "KILL")
- self.assertEquals(err.errno, errno.EINVAL)
-
-
-
-class PosixProcessTestCase(unittest.TestCase, PosixProcessBase):
- # add two non-pty test cases
-
- def test_stderr(self):
- """
- Bytes written to stderr by the spawned process are passed to the
- C{errReceived} callback on the C{ProcessProtocol} passed to
- C{spawnProcess}.
- """
- cmd = sys.executable
-
- value = "42"
-
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- reactor.spawnProcess(p, cmd,
- [cmd, "-c",
- "import sys; sys.stderr.write('%s')" % (value,)],
- env=None, path="/tmp",
- usePTY=self.usePTY)
-
- def processEnded(ign):
- self.assertEqual(value, p.errF.getvalue())
- return d.addCallback(processEnded)
-
-
- def testProcess(self):
- cmd = self.getCommand('gzip')
- s = "there's no place like home!\n" * 3
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- reactor.spawnProcess(p, cmd, [cmd, "-c"], env=None, path="/tmp",
- usePTY=self.usePTY)
- p.transport.write(s)
- p.transport.closeStdin()
-
- def processEnded(ign):
- f = p.outF
- f.seek(0, 0)
- gf = gzip.GzipFile(fileobj=f)
- self.assertEqual(gf.read(), s)
- return d.addCallback(processEnded)
-
-
-
-class PosixProcessTestCasePTY(unittest.TestCase, PosixProcessBase):
- """
- Just like PosixProcessTestCase, but use ptys instead of pipes.
- """
- usePTY = True
- # PTYs only offer one input and one output. What still makes sense?
- # testNormalTermination
- # test_abnormalTermination
- # testSignal
- # testProcess, but not without p.transport.closeStdin
- # might be solveable: TODO: add test if so
-
- def testOpeningTTY(self):
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_tty.py")
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=None,
- path=None, usePTY=self.usePTY)
- p.transport.write("hello world!\n")
-
- def processEnded(ign):
- self.assertRaises(
- error.ProcessExitedAlready, p.transport.signalProcess, 'HUP')
- self.assertEqual(
- p.outF.getvalue(),
- "hello world!\r\nhello world!\r\n",
- "Error message from process_tty follows:\n\n%s\n\n" % p.outF.getvalue())
- return d.addCallback(processEnded)
-
-
- def testBadArgs(self):
- pyExe = sys.executable
- pyArgs = [pyExe, "-u", "-c", "print 'hello'"]
- p = Accumulator()
- self.assertRaises(ValueError, reactor.spawnProcess, p, pyExe, pyArgs,
- usePTY=1, childFDs={1:'r'})
-
-
-
-class Win32SignalProtocol(SignalProtocol):
- """
- A win32-specific process protocol that handles C{processEnded}
- differently: processes should exit with exit code 1.
- """
-
- def processEnded(self, reason):
- """
- Callback C{self.deferred} with C{None} if C{reason} is a
- L{error.ProcessTerminated} failure with C{exitCode} set to 1.
- Otherwise, errback with a C{ValueError} describing the problem.
- """
- if not reason.check(error.ProcessTerminated):
- return self.deferred.errback(
- ValueError("wrong termination: %s" % (reason,)))
- v = reason.value
- if v.exitCode != 1:
- return self.deferred.errback(
- ValueError("Wrong exit code: %s" % (reason.exitCode,)))
- self.deferred.callback(None)
-
-
-
-class Win32ProcessTestCase(unittest.TestCase):
- """
- Test process programs that are packaged with twisted.
- """
-
- def testStdinReader(self):
- pyExe = sys.executable
- scriptPath = util.sibpath(__file__, "process_stdinreader.py")
- p = Accumulator()
- d = p.endedDeferred = defer.Deferred()
- reactor.spawnProcess(p, pyExe, [pyExe, "-u", scriptPath], env=None,
- path=None)
- p.transport.write("hello, world")
- p.transport.closeStdin()
-
- def processEnded(ign):
- self.assertEqual(p.errF.getvalue(), "err\nerr\n")
- self.assertEqual(p.outF.getvalue(), "out\nhello, world\nout\n")
- return d.addCallback(processEnded)
-
-
- def testBadArgs(self):
- pyExe = sys.executable
- pyArgs = [pyExe, "-u", "-c", "print 'hello'"]
- p = Accumulator()
- self.assertRaises(ValueError,
- reactor.spawnProcess, p, pyExe, pyArgs, uid=1)
- self.assertRaises(ValueError,
- reactor.spawnProcess, p, pyExe, pyArgs, gid=1)
- self.assertRaises(ValueError,
- reactor.spawnProcess, p, pyExe, pyArgs, usePTY=1)
- self.assertRaises(ValueError,
- reactor.spawnProcess, p, pyExe, pyArgs, childFDs={1:'r'})
-
-
- def _testSignal(self, sig):
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_signal.py")
- d = defer.Deferred()
- p = Win32SignalProtocol(d, sig)
- reactor.spawnProcess(p, exe, [exe, "-u", scriptPath], env=None)
- return d
-
-
- def test_signalTERM(self):
- """
- Sending the SIGTERM signal terminates a created process, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} attribute set to 1.
- """
- return self._testSignal('TERM')
-
-
- def test_signalINT(self):
- """
- Sending the SIGINT signal terminates a created process, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} attribute set to 1.
- """
- return self._testSignal('INT')
-
-
- def test_signalKILL(self):
- """
- Sending the SIGKILL signal terminates a created process, and
- C{processEnded} is called with a L{error.ProcessTerminated} instance
- with the C{exitCode} attribute set to 1.
- """
- return self._testSignal('KILL')
-
-
- def test_closeHandles(self):
- """
- The win32 handles should be properly closed when the process exits.
- """
- import win32api
-
- connected = defer.Deferred()
- ended = defer.Deferred()
-
- class SimpleProtocol(protocol.ProcessProtocol):
- """
- A protocol that fires deferreds when connected and disconnected.
- """
- def makeConnection(self, transport):
- connected.callback(transport)
-
- def processEnded(self, reason):
- ended.callback(None)
-
- p = SimpleProtocol()
-
- pyExe = sys.executable
- pyArgs = [pyExe, "-u", "-c", "print 'hello'"]
- proc = reactor.spawnProcess(p, pyExe, pyArgs)
-
- def cbConnected(transport):
- self.assertIdentical(transport, proc)
- # perform a basic validity test on the handles
- win32api.GetHandleInformation(proc.hProcess)
- win32api.GetHandleInformation(proc.hThread)
- # And save their values for later
- self.hProcess = proc.hProcess
- self.hThread = proc.hThread
- connected.addCallback(cbConnected)
-
- def checkTerminated(ignored):
- # The attributes on the process object must be reset...
- self.assertIdentical(proc.pid, None)
- self.assertIdentical(proc.hProcess, None)
- self.assertIdentical(proc.hThread, None)
- # ...and the handles must be closed.
- self.assertRaises(win32api.error,
- win32api.GetHandleInformation, self.hProcess)
- self.assertRaises(win32api.error,
- win32api.GetHandleInformation, self.hThread)
- ended.addCallback(checkTerminated)
-
- return defer.gatherResults([connected, ended])
-
-
-
-class Win32UnicodeEnvironmentTest(unittest.TestCase):
- """
- Tests for Unicode environment on Windows
- """
- goodKey = u'UNICODE'
- goodValue = u'UNICODE'
-
- def test_encodableUnicodeEnvironment(self):
- """
- Test C{os.environ} (inherited by every subprocess on Windows) that
- contains an ascii-encodable Unicode string. This is different from
- passing Unicode environment explicitly to spawnProcess (which is not
- supported).
- """
- os.environ[self.goodKey] = self.goodValue
- self.addCleanup(operator.delitem, os.environ, self.goodKey)
-
- p = GetEnvironmentDictionary.run(reactor, [], {})
- def gotEnvironment(environ):
- self.assertEqual(
- environ[self.goodKey.encode('ascii')],
- self.goodValue.encode('ascii'))
- return p.getResult().addCallback(gotEnvironment)
-
-
-
-class Dumbwin32procPidTest(unittest.TestCase):
- """
- Simple test for the pid attribute of Process on win32.
- """
-
- def test_pid(self):
- """
- Launch process with mock win32process. The only mock aspect of this
- module is that the pid of the process created will always be 42.
- """
- from twisted.internet import _dumbwin32proc
- from twisted.test import mock_win32process
- self.patch(_dumbwin32proc, "win32process", mock_win32process)
- exe = sys.executable
- scriptPath = util.sibpath(__file__, "process_cmdline.py")
-
- d = defer.Deferred()
- processProto = TrivialProcessProtocol(d)
- comspec = str(os.environ["COMSPEC"])
- cmd = [comspec, "/c", exe, scriptPath]
-
- p = _dumbwin32proc.Process(reactor,
- processProto,
- None,
- cmd,
- {},
- None)
- self.assertEqual(42, p.pid)
- self.assertEqual("<Process pid=42>", repr(p))
-
- def pidCompleteCb(result):
- self.assertEqual(None, p.pid)
- return d.addCallback(pidCompleteCb)
-
-
-
-class UtilTestCase(unittest.TestCase):
- """
- Tests for process-related helper functions (currently only
- L{procutils.which}.
- """
- def setUp(self):
- """
- Create several directories and files, some of which are executable
- and some of which are not. Save the current PATH setting.
- """
- j = os.path.join
-
- base = self.mktemp()
-
- self.foo = j(base, "foo")
- self.baz = j(base, "baz")
- self.foobar = j(self.foo, "bar")
- self.foobaz = j(self.foo, "baz")
- self.bazfoo = j(self.baz, "foo")
- self.bazbar = j(self.baz, "bar")
-
- for d in self.foobar, self.foobaz, self.bazfoo, self.bazbar:
- os.makedirs(d)
-
- for name, mode in [(j(self.foobaz, "executable"), 0700),
- (j(self.foo, "executable"), 0700),
- (j(self.bazfoo, "executable"), 0700),
- (j(self.bazfoo, "executable.bin"), 0700),
- (j(self.bazbar, "executable"), 0)]:
- f = file(name, "w")
- f.close()
- os.chmod(name, mode)
-
- self.oldPath = os.environ.get('PATH', None)
- os.environ['PATH'] = os.pathsep.join((
- self.foobar, self.foobaz, self.bazfoo, self.bazbar))
-
-
- def tearDown(self):
- """
- Restore the saved PATH setting, and set all created files readable
- again so that they can be deleted easily.
- """
- os.chmod(os.path.join(self.bazbar, "executable"), stat.S_IWUSR)
- if self.oldPath is None:
- try:
- del os.environ['PATH']
- except KeyError:
- pass
- else:
- os.environ['PATH'] = self.oldPath
-
-
- def test_whichWithoutPATH(self):
- """
- Test that if C{os.environ} does not have a C{'PATH'} key,
- L{procutils.which} returns an empty list.
- """
- del os.environ['PATH']
- self.assertEqual(procutils.which("executable"), [])
-
-
- def testWhich(self):
- j = os.path.join
- paths = procutils.which("executable")
- expectedPaths = [j(self.foobaz, "executable"),
- j(self.bazfoo, "executable")]
- if runtime.platform.isWindows():
- expectedPaths.append(j(self.bazbar, "executable"))
- self.assertEqual(paths, expectedPaths)
-
-
- def testWhichPathExt(self):
- j = os.path.join
- old = os.environ.get('PATHEXT', None)
- os.environ['PATHEXT'] = os.pathsep.join(('.bin', '.exe', '.sh'))
- try:
- paths = procutils.which("executable")
- finally:
- if old is None:
- del os.environ['PATHEXT']
- else:
- os.environ['PATHEXT'] = old
- expectedPaths = [j(self.foobaz, "executable"),
- j(self.bazfoo, "executable"),
- j(self.bazfoo, "executable.bin")]
- if runtime.platform.isWindows():
- expectedPaths.append(j(self.bazbar, "executable"))
- self.assertEqual(paths, expectedPaths)
-
-
-
-class ClosingPipesProcessProtocol(protocol.ProcessProtocol):
- output = ''
- errput = ''
-
- def __init__(self, outOrErr):
- self.deferred = defer.Deferred()
- self.outOrErr = outOrErr
-
- def processEnded(self, reason):
- self.deferred.callback(reason)
-
- def outReceived(self, data):
- self.output += data
-
- def errReceived(self, data):
- self.errput += data
-
-
-
-class ClosingPipes(unittest.TestCase):
-
- def doit(self, fd):
- """
- Create a child process and close one of its output descriptors using
- L{IProcessTransport.closeStdout} or L{IProcessTransport.closeStderr}.
- Return a L{Deferred} which fires after verifying that the descriptor was
- really closed.
- """
- p = ClosingPipesProcessProtocol(True)
- self.assertFailure(p.deferred, error.ProcessTerminated)
- p.deferred.addCallback(self._endProcess, p)
- reactor.spawnProcess(
- p, sys.executable, [
- sys.executable, '-u', '-c',
- 'raw_input()\n'
- 'import sys, os, time\n'
- # Give the system a bit of time to notice the closed
- # descriptor. Another option would be to poll() for HUP
- # instead of relying on an os.write to fail with SIGPIPE.
- # However, that wouldn't work on OS X (or Windows?).
- 'for i in range(1000):\n'
- ' os.write(%d, "foo\\n")\n'
- ' time.sleep(0.01)\n'
- 'sys.exit(42)\n' % (fd,)
- ],
- env=None)
-
- if fd == 1:
- p.transport.closeStdout()
- elif fd == 2:
- p.transport.closeStderr()
- else:
- raise RuntimeError
-
- # Give the close time to propagate
- p.transport.write('go\n')
-
- # make the buggy case not hang
- p.transport.closeStdin()
- return p.deferred
-
-
- def _endProcess(self, reason, p):
- """
- Check that a failed write prevented the process from getting to its
- custom exit code.
- """
- # child must not get past that write without raising
- self.assertNotEquals(
- reason.exitCode, 42, 'process reason was %r' % reason)
- self.assertEqual(p.output, '')
- return p.errput
-
-
- def test_stdout(self):
- """
- ProcessProtocol.transport.closeStdout actually closes the pipe.
- """
- d = self.doit(1)
- def _check(errput):
- self.assertIn('OSError', errput)
- if runtime.platform.getType() != 'win32':
- self.assertIn('Broken pipe', errput)
- d.addCallback(_check)
- return d
-
-
- def test_stderr(self):
- """
- ProcessProtocol.transport.closeStderr actually closes the pipe.
- """
- d = self.doit(2)
- def _check(errput):
- # there should be no stderr open, so nothing for it to
- # write the error to.
- self.assertEqual(errput, '')
- d.addCallback(_check)
- return d
-
-
-skipMessage = "wrong platform or reactor doesn't support IReactorProcess"
-if (runtime.platform.getType() != 'posix') or (not interfaces.IReactorProcess(reactor, None)):
- PosixProcessTestCase.skip = skipMessage
- PosixProcessTestCasePTY.skip = skipMessage
- TestTwoProcessesPosix.skip = skipMessage
- FDTest.skip = skipMessage
-
-if (runtime.platform.getType() != 'win32') or (not interfaces.IReactorProcess(reactor, None)):
- Win32ProcessTestCase.skip = skipMessage
- TestTwoProcessesNonPosix.skip = skipMessage
- Dumbwin32procPidTest.skip = skipMessage
- Win32UnicodeEnvironmentTest.skip = skipMessage
-
-if not interfaces.IReactorProcess(reactor, None):
- ProcessTestCase.skip = skipMessage
- ClosingPipes.skip = skipMessage
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_protocols.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_protocols.py
deleted file mode 100755
index db12d3c3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_protocols.py
+++ /dev/null
@@ -1,1260 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.protocols package.
-"""
-
-import struct
-
-from zope.interface.verify import verifyObject
-
-from twisted.trial import unittest
-from twisted.protocols import basic, wire, portforward
-from twisted.internet import reactor, protocol, defer, task, error, address
-from twisted.internet.interfaces import IProtocolFactory, ILoggingContext
-from twisted.test import proto_helpers
-
-
-class LineTester(basic.LineReceiver):
- """
- A line receiver that parses data received and make actions on some tokens.
-
- @type delimiter: C{str}
- @ivar delimiter: character used between received lines.
- @type MAX_LENGTH: C{int}
- @ivar MAX_LENGTH: size of a line when C{lineLengthExceeded} will be called.
- @type clock: L{twisted.internet.task.Clock}
- @ivar clock: clock simulating reactor callLater. Pass it to constructor if
- you want to use the pause/rawpause functionalities.
- """
-
- delimiter = '\n'
- MAX_LENGTH = 64
-
- def __init__(self, clock=None):
- """
- If given, use a clock to make callLater calls.
- """
- self.clock = clock
-
-
- def connectionMade(self):
- """
- Create/clean data received on connection.
- """
- self.received = []
-
-
- def lineReceived(self, line):
- """
- Receive line and make some action for some tokens: pause, rawpause,
- stop, len, produce, unproduce.
- """
- self.received.append(line)
- if line == '':
- self.setRawMode()
- elif line == 'pause':
- self.pauseProducing()
- self.clock.callLater(0, self.resumeProducing)
- elif line == 'rawpause':
- self.pauseProducing()
- self.setRawMode()
- self.received.append('')
- self.clock.callLater(0, self.resumeProducing)
- elif line == 'stop':
- self.stopProducing()
- elif line[:4] == 'len ':
- self.length = int(line[4:])
- elif line.startswith('produce'):
- self.transport.registerProducer(self, False)
- elif line.startswith('unproduce'):
- self.transport.unregisterProducer()
-
-
- def rawDataReceived(self, data):
- """
- Read raw data, until the quantity specified by a previous 'len' line is
- reached.
- """
- data, rest = data[:self.length], data[self.length:]
- self.length = self.length - len(data)
- self.received[-1] = self.received[-1] + data
- if self.length == 0:
- self.setLineMode(rest)
-
-
- def lineLengthExceeded(self, line):
- """
- Adjust line mode when long lines received.
- """
- if len(line) > self.MAX_LENGTH + 1:
- self.setLineMode(line[self.MAX_LENGTH + 1:])
-
-
-
-class LineOnlyTester(basic.LineOnlyReceiver):
- """
- A buffering line only receiver.
- """
- delimiter = '\n'
- MAX_LENGTH = 64
-
- def connectionMade(self):
- """
- Create/clean data received on connection.
- """
- self.received = []
-
-
- def lineReceived(self, line):
- """
- Save received data.
- """
- self.received.append(line)
-
-
-
-class FactoryTests(unittest.TestCase):
- """
- Tests for L{protocol.Factory}.
- """
- def test_interfaces(self):
- """
- L{protocol.Factory} instances provide both L{IProtocolFactory} and
- L{ILoggingContext}.
- """
- factory = protocol.Factory()
- self.assertTrue(verifyObject(IProtocolFactory, factory))
- self.assertTrue(verifyObject(ILoggingContext, factory))
-
-
- def test_logPrefix(self):
- """
- L{protocol.Factory.logPrefix} returns the name of the factory class.
- """
- class SomeKindOfFactory(protocol.Factory):
- pass
-
- self.assertEqual("SomeKindOfFactory", SomeKindOfFactory().logPrefix())
-
-
-
-class WireTestCase(unittest.TestCase):
- """
- Test wire protocols.
- """
-
- def test_echo(self):
- """
- Test wire.Echo protocol: send some data and check it send it back.
- """
- t = proto_helpers.StringTransport()
- a = wire.Echo()
- a.makeConnection(t)
- a.dataReceived("hello")
- a.dataReceived("world")
- a.dataReceived("how")
- a.dataReceived("are")
- a.dataReceived("you")
- self.assertEqual(t.value(), "helloworldhowareyou")
-
-
- def test_who(self):
- """
- Test wire.Who protocol.
- """
- t = proto_helpers.StringTransport()
- a = wire.Who()
- a.makeConnection(t)
- self.assertEqual(t.value(), "root\r\n")
-
-
- def test_QOTD(self):
- """
- Test wire.QOTD protocol.
- """
- t = proto_helpers.StringTransport()
- a = wire.QOTD()
- a.makeConnection(t)
- self.assertEqual(t.value(),
- "An apple a day keeps the doctor away.\r\n")
-
-
- def test_discard(self):
- """
- Test wire.Discard protocol.
- """
- t = proto_helpers.StringTransport()
- a = wire.Discard()
- a.makeConnection(t)
- a.dataReceived("hello")
- a.dataReceived("world")
- a.dataReceived("how")
- a.dataReceived("are")
- a.dataReceived("you")
- self.assertEqual(t.value(), "")
-
-
-
-class LineReceiverTestCase(unittest.TestCase):
- """
- Test LineReceiver, using the C{LineTester} wrapper.
- """
- buffer = '''\
-len 10
-
-0123456789len 5
-
-1234
-len 20
-foo 123
-
-0123456789
-012345678len 0
-foo 5
-
-1234567890123456789012345678901234567890123456789012345678901234567890
-len 1
-
-a'''
-
- output = ['len 10', '0123456789', 'len 5', '1234\n',
- 'len 20', 'foo 123', '0123456789\n012345678',
- 'len 0', 'foo 5', '', '67890', 'len 1', 'a']
-
- def testBuffer(self):
- """
- Test buffering for different packet size, checking received matches
- expected data.
- """
- for packet_size in range(1, 10):
- t = proto_helpers.StringIOWithoutClosing()
- a = LineTester()
- a.makeConnection(protocol.FileWrapper(t))
- for i in range(len(self.buffer) // packet_size + 1):
- s = self.buffer[i*packet_size:(i+1)*packet_size]
- a.dataReceived(s)
- self.assertEqual(self.output, a.received)
-
-
- pause_buf = 'twiddle1\ntwiddle2\npause\ntwiddle3\n'
-
- pause_output1 = ['twiddle1', 'twiddle2', 'pause']
- pause_output2 = pause_output1+['twiddle3']
-
-
- def test_pausing(self):
- """
- Test pause inside data receiving. It uses fake clock to see if
- pausing/resuming work.
- """
- for packet_size in range(1, 10):
- t = proto_helpers.StringIOWithoutClosing()
- clock = task.Clock()
- a = LineTester(clock)
- a.makeConnection(protocol.FileWrapper(t))
- for i in range(len(self.pause_buf) // packet_size + 1):
- s = self.pause_buf[i*packet_size:(i+1)*packet_size]
- a.dataReceived(s)
- self.assertEqual(self.pause_output1, a.received)
- clock.advance(0)
- self.assertEqual(self.pause_output2, a.received)
-
- rawpause_buf = 'twiddle1\ntwiddle2\nlen 5\nrawpause\n12345twiddle3\n'
-
- rawpause_output1 = ['twiddle1', 'twiddle2', 'len 5', 'rawpause', '']
- rawpause_output2 = ['twiddle1', 'twiddle2', 'len 5', 'rawpause', '12345',
- 'twiddle3']
-
-
- def test_rawPausing(self):
- """
- Test pause inside raw date receiving.
- """
- for packet_size in range(1, 10):
- t = proto_helpers.StringIOWithoutClosing()
- clock = task.Clock()
- a = LineTester(clock)
- a.makeConnection(protocol.FileWrapper(t))
- for i in range(len(self.rawpause_buf) // packet_size + 1):
- s = self.rawpause_buf[i*packet_size:(i+1)*packet_size]
- a.dataReceived(s)
- self.assertEqual(self.rawpause_output1, a.received)
- clock.advance(0)
- self.assertEqual(self.rawpause_output2, a.received)
-
- stop_buf = 'twiddle1\ntwiddle2\nstop\nmore\nstuff\n'
-
- stop_output = ['twiddle1', 'twiddle2', 'stop']
-
-
- def test_stopProducing(self):
- """
- Test stop inside producing.
- """
- for packet_size in range(1, 10):
- t = proto_helpers.StringIOWithoutClosing()
- a = LineTester()
- a.makeConnection(protocol.FileWrapper(t))
- for i in range(len(self.stop_buf) // packet_size + 1):
- s = self.stop_buf[i*packet_size:(i+1)*packet_size]
- a.dataReceived(s)
- self.assertEqual(self.stop_output, a.received)
-
-
- def test_lineReceiverAsProducer(self):
- """
- Test produce/unproduce in receiving.
- """
- a = LineTester()
- t = proto_helpers.StringIOWithoutClosing()
- a.makeConnection(protocol.FileWrapper(t))
- a.dataReceived('produce\nhello world\nunproduce\ngoodbye\n')
- self.assertEqual(a.received,
- ['produce', 'hello world', 'unproduce', 'goodbye'])
-
-
- def test_clearLineBuffer(self):
- """
- L{LineReceiver.clearLineBuffer} removes all buffered data and returns
- it as a C{str} and can be called from beneath C{dataReceived}.
- """
- class ClearingReceiver(basic.LineReceiver):
- def lineReceived(self, line):
- self.line = line
- self.rest = self.clearLineBuffer()
-
- protocol = ClearingReceiver()
- protocol.dataReceived('foo\r\nbar\r\nbaz')
- self.assertEqual(protocol.line, 'foo')
- self.assertEqual(protocol.rest, 'bar\r\nbaz')
-
- # Deliver another line to make sure the previously buffered data is
- # really gone.
- protocol.dataReceived('quux\r\n')
- self.assertEqual(protocol.line, 'quux')
- self.assertEqual(protocol.rest, '')
-
-
-
-class LineOnlyReceiverTestCase(unittest.TestCase):
- """
- Test line only receiveer.
- """
- buffer = """foo
- bleakness
- desolation
- plastic forks
- """
-
- def test_buffer(self):
- """
- Test buffering over line protocol: data received should match buffer.
- """
- t = proto_helpers.StringTransport()
- a = LineOnlyTester()
- a.makeConnection(t)
- for c in self.buffer:
- a.dataReceived(c)
- self.assertEqual(a.received, self.buffer.split('\n')[:-1])
-
-
- def test_lineTooLong(self):
- """
- Test sending a line too long: it should close the connection.
- """
- t = proto_helpers.StringTransport()
- a = LineOnlyTester()
- a.makeConnection(t)
- res = a.dataReceived('x'*200)
- self.assertIsInstance(res, error.ConnectionLost)
-
-
-
-class TestMixin:
-
- def connectionMade(self):
- self.received = []
-
-
- def stringReceived(self, s):
- self.received.append(s)
-
- MAX_LENGTH = 50
- closed = 0
-
-
- def connectionLost(self, reason):
- self.closed = 1
-
-
-
-class TestNetstring(TestMixin, basic.NetstringReceiver):
-
- def stringReceived(self, s):
- self.received.append(s)
- self.transport.write(s)
-
-
-
-class LPTestCaseMixin:
-
- illegalStrings = []
- protocol = None
-
-
- def getProtocol(self):
- """
- Return a new instance of C{self.protocol} connected to a new instance
- of L{proto_helpers.StringTransport}.
- """
- t = proto_helpers.StringTransport()
- a = self.protocol()
- a.makeConnection(t)
- return a
-
-
- def test_illegal(self):
- """
- Assert that illegal strings cause the transport to be closed.
- """
- for s in self.illegalStrings:
- r = self.getProtocol()
- for c in s:
- r.dataReceived(c)
- self.assertTrue(r.transport.disconnecting)
-
-
-
-class NetstringReceiverTestCase(unittest.TestCase, LPTestCaseMixin):
-
- strings = ['hello', 'world', 'how', 'are', 'you123', ':today', "a"*515]
-
- illegalStrings = [
- '9999999999999999999999', 'abc', '4:abcde',
- '51:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab,',]
-
- protocol = TestNetstring
-
- def setUp(self):
- self.transport = proto_helpers.StringTransport()
- self.netstringReceiver = TestNetstring()
- self.netstringReceiver.makeConnection(self.transport)
-
-
- def test_buffer(self):
- """
- Strings can be received in chunks of different lengths.
- """
- for packet_size in range(1, 10):
- t = proto_helpers.StringTransport()
- a = TestNetstring()
- a.MAX_LENGTH = 699
- a.makeConnection(t)
- for s in self.strings:
- a.sendString(s)
- out = t.value()
- for i in range(len(out) // packet_size + 1):
- s = out[i*packet_size:(i+1)*packet_size]
- if s:
- a.dataReceived(s)
- self.assertEqual(a.received, self.strings)
-
-
- def test_sendNonStrings(self):
- """
- L{basic.NetstringReceiver.sendString} will send objects that are not
- strings by sending their string representation according to str().
- """
- nonStrings = [ [], { 1 : 'a', 2 : 'b' }, ['a', 'b', 'c'], 673,
- (12, "fine", "and", "you?") ]
- a = TestNetstring()
- t = proto_helpers.StringTransport()
- a.MAX_LENGTH = 100
- a.makeConnection(t)
- for s in nonStrings:
- a.sendString(s)
- out = t.value()
- t.clear()
- length = out[:out.find(":")]
- data = out[out.find(":") + 1:-1] #[:-1] to ignore the trailing ","
- self.assertEqual(int(length), len(str(s)))
- self.assertEqual(data, str(s))
-
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_sendNonStrings])
- self.assertEqual(len(warnings), 5)
- self.assertEqual(
- warnings[0]["message"],
- "Data passed to sendString() must be a string. Non-string support "
- "is deprecated since Twisted 10.0")
- self.assertEqual(
- warnings[0]['category'],
- DeprecationWarning)
-
-
- def test_receiveEmptyNetstring(self):
- """
- Empty netstrings (with length '0') can be received.
- """
- self.netstringReceiver.dataReceived("0:,")
- self.assertEqual(self.netstringReceiver.received, [""])
-
-
- def test_receiveOneCharacter(self):
- """
- One-character netstrings can be received.
- """
- self.netstringReceiver.dataReceived("1:a,")
- self.assertEqual(self.netstringReceiver.received, ["a"])
-
-
- def test_receiveTwoCharacters(self):
- """
- Two-character netstrings can be received.
- """
- self.netstringReceiver.dataReceived("2:ab,")
- self.assertEqual(self.netstringReceiver.received, ["ab"])
-
-
- def test_receiveNestedNetstring(self):
- """
- Netstrings with embedded netstrings. This test makes sure that
- the parser does not become confused about the ',' and ':'
- characters appearing inside the data portion of the netstring.
- """
- self.netstringReceiver.dataReceived("4:1:a,,")
- self.assertEqual(self.netstringReceiver.received, ["1:a,"])
-
-
- def test_moreDataThanSpecified(self):
- """
- Netstrings containing more data than expected are refused.
- """
- self.netstringReceiver.dataReceived("2:aaa,")
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_moreDataThanSpecifiedBorderCase(self):
- """
- Netstrings that should be empty according to their length
- specification are refused if they contain data.
- """
- self.netstringReceiver.dataReceived("0:a,")
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_missingNumber(self):
- """
- Netstrings without leading digits that specify the length
- are refused.
- """
- self.netstringReceiver.dataReceived(":aaa,")
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_missingColon(self):
- """
- Netstrings without a colon between length specification and
- data are refused.
- """
- self.netstringReceiver.dataReceived("3aaa,")
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_missingNumberAndColon(self):
- """
- Netstrings that have no leading digits nor a colon are
- refused.
- """
- self.netstringReceiver.dataReceived("aaa,")
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_onlyData(self):
- """
- Netstrings consisting only of data are refused.
- """
- self.netstringReceiver.dataReceived("aaa")
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_receiveNetstringPortions_1(self):
- """
- Netstrings can be received in two portions.
- """
- self.netstringReceiver.dataReceived("4:aa")
- self.netstringReceiver.dataReceived("aa,")
- self.assertEqual(self.netstringReceiver.received, ["aaaa"])
- self.assertTrue(self.netstringReceiver._payloadComplete())
-
-
- def test_receiveNetstringPortions_2(self):
- """
- Netstrings can be received in more than two portions, even if
- the length specification is split across two portions.
- """
- for part in ["1", "0:01234", "56789", ","]:
- self.netstringReceiver.dataReceived(part)
- self.assertEqual(self.netstringReceiver.received, ["0123456789"])
-
-
- def test_receiveNetstringPortions_3(self):
- """
- Netstrings can be received one character at a time.
- """
- for part in "2:ab,":
- self.netstringReceiver.dataReceived(part)
- self.assertEqual(self.netstringReceiver.received, ["ab"])
-
-
- def test_receiveTwoNetstrings(self):
- """
- A stream of two netstrings can be received in two portions,
- where the first portion contains the complete first netstring
- and the length specification of the second netstring.
- """
- self.netstringReceiver.dataReceived("1:a,1")
- self.assertTrue(self.netstringReceiver._payloadComplete())
- self.assertEqual(self.netstringReceiver.received, ["a"])
- self.netstringReceiver.dataReceived(":b,")
- self.assertEqual(self.netstringReceiver.received, ["a", "b"])
-
-
- def test_maxReceiveLimit(self):
- """
- Netstrings with a length specification exceeding the specified
- C{MAX_LENGTH} are refused.
- """
- tooLong = self.netstringReceiver.MAX_LENGTH + 1
- self.netstringReceiver.dataReceived("%s:%s" %
- (tooLong, "a" * tooLong))
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_consumeLength(self):
- """
- C{_consumeLength} returns the expected length of the
- netstring, including the trailing comma.
- """
- self.netstringReceiver._remainingData = "12:"
- self.netstringReceiver._consumeLength()
- self.assertEqual(self.netstringReceiver._expectedPayloadSize, 13)
-
-
- def test_consumeLengthBorderCase1(self):
- """
- C{_consumeLength} works as expected if the length specification
- contains the value of C{MAX_LENGTH} (border case).
- """
- self.netstringReceiver._remainingData = "12:"
- self.netstringReceiver.MAX_LENGTH = 12
- self.netstringReceiver._consumeLength()
- self.assertEqual(self.netstringReceiver._expectedPayloadSize, 13)
-
-
- def test_consumeLengthBorderCase2(self):
- """
- C{_consumeLength} raises a L{basic.NetstringParseError} if
- the length specification exceeds the value of C{MAX_LENGTH}
- by 1 (border case).
- """
- self.netstringReceiver._remainingData = "12:"
- self.netstringReceiver.MAX_LENGTH = 11
- self.assertRaises(basic.NetstringParseError,
- self.netstringReceiver._consumeLength)
-
-
- def test_consumeLengthBorderCase3(self):
- """
- C{_consumeLength} raises a L{basic.NetstringParseError} if
- the length specification exceeds the value of C{MAX_LENGTH}
- by more than 1.
- """
- self.netstringReceiver._remainingData = "1000:"
- self.netstringReceiver.MAX_LENGTH = 11
- self.assertRaises(basic.NetstringParseError,
- self.netstringReceiver._consumeLength)
-
-
- def test_deprecatedModuleAttributes(self):
- """
- Accessing one of the old module attributes used by the
- NetstringReceiver parser emits a deprecation warning.
- """
- basic.LENGTH, basic.DATA, basic.COMMA, basic.NUMBER
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_deprecatedModuleAttributes])
-
- self.assertEqual(len(warnings), 4)
- for warning in warnings:
- self.assertEqual(warning['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- ("twisted.protocols.basic.LENGTH was deprecated in Twisted 10.2.0: "
- "NetstringReceiver parser state is private."))
- self.assertEqual(
- warnings[1]['message'],
- ("twisted.protocols.basic.DATA was deprecated in Twisted 10.2.0: "
- "NetstringReceiver parser state is private."))
- self.assertEqual(
- warnings[2]['message'],
- ("twisted.protocols.basic.COMMA was deprecated in Twisted 10.2.0: "
- "NetstringReceiver parser state is private."))
- self.assertEqual(
- warnings[3]['message'],
- ("twisted.protocols.basic.NUMBER was deprecated in Twisted 10.2.0: "
- "NetstringReceiver parser state is private."))
-
-
-
-class IntNTestCaseMixin(LPTestCaseMixin):
- """
- TestCase mixin for int-prefixed protocols.
- """
-
- protocol = None
- strings = None
- illegalStrings = None
- partialStrings = None
-
- def test_receive(self):
- """
- Test receiving data find the same data send.
- """
- r = self.getProtocol()
- for s in self.strings:
- for c in struct.pack(r.structFormat,len(s)) + s:
- r.dataReceived(c)
- self.assertEqual(r.received, self.strings)
-
-
- def test_partial(self):
- """
- Send partial data, nothing should be definitely received.
- """
- for s in self.partialStrings:
- r = self.getProtocol()
- for c in s:
- r.dataReceived(c)
- self.assertEqual(r.received, [])
-
-
- def test_send(self):
- """
- Test sending data over protocol.
- """
- r = self.getProtocol()
- r.sendString("b" * 16)
- self.assertEqual(r.transport.value(),
- struct.pack(r.structFormat, 16) + "b" * 16)
-
-
- def test_lengthLimitExceeded(self):
- """
- When a length prefix is received which is greater than the protocol's
- C{MAX_LENGTH} attribute, the C{lengthLimitExceeded} method is called
- with the received length prefix.
- """
- length = []
- r = self.getProtocol()
- r.lengthLimitExceeded = length.append
- r.MAX_LENGTH = 10
- r.dataReceived(struct.pack(r.structFormat, 11))
- self.assertEqual(length, [11])
-
-
- def test_longStringNotDelivered(self):
- """
- If a length prefix for a string longer than C{MAX_LENGTH} is delivered
- to C{dataReceived} at the same time as the entire string, the string is
- not passed to C{stringReceived}.
- """
- r = self.getProtocol()
- r.MAX_LENGTH = 10
- r.dataReceived(
- struct.pack(r.structFormat, 11) + 'x' * 11)
- self.assertEqual(r.received, [])
-
-
-
-class RecvdAttributeMixin(object):
- """
- Mixin defining tests for string receiving protocols with a C{recvd}
- attribute which should be settable by application code, to be combined with
- L{IntNTestCaseMixin} on a L{TestCase} subclass
- """
-
- def makeMessage(self, protocol, data):
- """
- Return C{data} prefixed with message length in C{protocol.structFormat}
- form.
- """
- return struct.pack(protocol.structFormat, len(data)) + data
-
-
- def test_recvdContainsRemainingData(self):
- """
- In stringReceived, recvd contains the remaining data that was passed to
- dataReceived that was not part of the current message.
- """
- result = []
- r = self.getProtocol()
- def stringReceived(receivedString):
- result.append(r.recvd)
- r.stringReceived = stringReceived
- completeMessage = (struct.pack(r.structFormat, 5) + ('a' * 5))
- incompleteMessage = (struct.pack(r.structFormat, 5) + ('b' * 4))
- # Receive a complete message, followed by an incomplete one
- r.dataReceived(completeMessage + incompleteMessage)
- self.assertEquals(result, [incompleteMessage])
-
-
- def test_recvdChanged(self):
- """
- In stringReceived, if recvd is changed, messages should be parsed from
- it rather than the input to dataReceived.
- """
- r = self.getProtocol()
- result = []
- payloadC = 'c' * 5
- messageC = self.makeMessage(r, payloadC)
- def stringReceived(receivedString):
- if not result:
- r.recvd = messageC
- result.append(receivedString)
- r.stringReceived = stringReceived
- payloadA = 'a' * 5
- payloadB = 'b' * 5
- messageA = self.makeMessage(r, payloadA)
- messageB = self.makeMessage(r, payloadB)
- r.dataReceived(messageA + messageB)
- self.assertEquals(result, [payloadA, payloadC])
-
-
- def test_switching(self):
- """
- Data already parsed by L{IntNStringReceiver.dataReceived} is not
- reparsed if C{stringReceived} consumes some of the
- L{IntNStringReceiver.recvd} buffer.
- """
- proto = self.getProtocol()
- mix = []
- SWITCH = "\x00\x00\x00\x00"
- for s in self.strings:
- mix.append(self.makeMessage(proto, s))
- mix.append(SWITCH)
-
- result = []
- def stringReceived(receivedString):
- result.append(receivedString)
- proto.recvd = proto.recvd[len(SWITCH):]
-
- proto.stringReceived = stringReceived
- proto.dataReceived("".join(mix))
- # Just another byte, to trigger processing of anything that might have
- # been left in the buffer (should be nothing).
- proto.dataReceived("\x01")
- self.assertEqual(result, self.strings)
- # And verify that another way
- self.assertEqual(proto.recvd, "\x01")
-
-
- def test_recvdInLengthLimitExceeded(self):
- """
- The L{IntNStringReceiver.recvd} buffer contains all data not yet
- processed by L{IntNStringReceiver.dataReceived} if the
- C{lengthLimitExceeded} event occurs.
- """
- proto = self.getProtocol()
- DATA = "too long"
- proto.MAX_LENGTH = len(DATA) - 1
- message = self.makeMessage(proto, DATA)
-
- result = []
- def lengthLimitExceeded(length):
- result.append(length)
- result.append(proto.recvd)
-
- proto.lengthLimitExceeded = lengthLimitExceeded
- proto.dataReceived(message)
- self.assertEqual(result[0], len(DATA))
- self.assertEqual(result[1], message)
-
-
-
-class TestInt32(TestMixin, basic.Int32StringReceiver):
- """
- A L{basic.Int32StringReceiver} storing received strings in an array.
-
- @ivar received: array holding received strings.
- """
-
-
-
-class Int32TestCase(unittest.TestCase, IntNTestCaseMixin, RecvdAttributeMixin):
- """
- Test case for int32-prefixed protocol
- """
- protocol = TestInt32
- strings = ["a", "b" * 16]
- illegalStrings = ["\x10\x00\x00\x00aaaaaa"]
- partialStrings = ["\x00\x00\x00", "hello there", ""]
-
- def test_data(self):
- """
- Test specific behavior of the 32-bits length.
- """
- r = self.getProtocol()
- r.sendString("foo")
- self.assertEqual(r.transport.value(), "\x00\x00\x00\x03foo")
- r.dataReceived("\x00\x00\x00\x04ubar")
- self.assertEqual(r.received, ["ubar"])
-
-
-
-class TestInt16(TestMixin, basic.Int16StringReceiver):
- """
- A L{basic.Int16StringReceiver} storing received strings in an array.
-
- @ivar received: array holding received strings.
- """
-
-
-
-class Int16TestCase(unittest.TestCase, IntNTestCaseMixin, RecvdAttributeMixin):
- """
- Test case for int16-prefixed protocol
- """
- protocol = TestInt16
- strings = ["a", "b" * 16]
- illegalStrings = ["\x10\x00aaaaaa"]
- partialStrings = ["\x00", "hello there", ""]
-
- def test_data(self):
- """
- Test specific behavior of the 16-bits length.
- """
- r = self.getProtocol()
- r.sendString("foo")
- self.assertEqual(r.transport.value(), "\x00\x03foo")
- r.dataReceived("\x00\x04ubar")
- self.assertEqual(r.received, ["ubar"])
-
-
- def test_tooLongSend(self):
- """
- Send too much data: that should cause an error.
- """
- r = self.getProtocol()
- tooSend = "b" * (2**(r.prefixLength*8) + 1)
- self.assertRaises(AssertionError, r.sendString, tooSend)
-
-
-
-class NewStyleTestInt16(TestInt16, object):
- """
- A new-style class version of TestInt16
- """
-
-
-
-class NewStyleInt16TestCase(Int16TestCase):
- """
- This test case verifies that IntNStringReceiver still works when inherited
- by a new-style class.
- """
- protocol = NewStyleTestInt16
-
-
-
-class TestInt8(TestMixin, basic.Int8StringReceiver):
- """
- A L{basic.Int8StringReceiver} storing received strings in an array.
-
- @ivar received: array holding received strings.
- """
-
-
-
-class Int8TestCase(unittest.TestCase, IntNTestCaseMixin, RecvdAttributeMixin):
- """
- Test case for int8-prefixed protocol
- """
- protocol = TestInt8
- strings = ["a", "b" * 16]
- illegalStrings = ["\x00\x00aaaaaa"]
- partialStrings = ["\x08", "dzadz", ""]
-
-
- def test_data(self):
- """
- Test specific behavior of the 8-bits length.
- """
- r = self.getProtocol()
- r.sendString("foo")
- self.assertEqual(r.transport.value(), "\x03foo")
- r.dataReceived("\x04ubar")
- self.assertEqual(r.received, ["ubar"])
-
-
- def test_tooLongSend(self):
- """
- Send too much data: that should cause an error.
- """
- r = self.getProtocol()
- tooSend = "b" * (2**(r.prefixLength*8) + 1)
- self.assertRaises(AssertionError, r.sendString, tooSend)
-
-
-
-class OnlyProducerTransport(object):
- # Transport which isn't really a transport, just looks like one to
- # someone not looking very hard.
-
- paused = False
- disconnecting = False
-
- def __init__(self):
- self.data = []
-
-
- def pauseProducing(self):
- self.paused = True
-
-
- def resumeProducing(self):
- self.paused = False
-
-
- def write(self, bytes):
- self.data.append(bytes)
-
-
-
-class ConsumingProtocol(basic.LineReceiver):
- # Protocol that really, really doesn't want any more bytes.
-
- def lineReceived(self, line):
- self.transport.write(line)
- self.pauseProducing()
-
-
-
-class ProducerTestCase(unittest.TestCase):
-
- def testPauseResume(self):
- p = ConsumingProtocol()
- t = OnlyProducerTransport()
- p.makeConnection(t)
-
- p.dataReceived('hello, ')
- self.failIf(t.data)
- self.failIf(t.paused)
- self.failIf(p.paused)
-
- p.dataReceived('world\r\n')
-
- self.assertEqual(t.data, ['hello, world'])
- self.failUnless(t.paused)
- self.failUnless(p.paused)
-
- p.resumeProducing()
-
- self.failIf(t.paused)
- self.failIf(p.paused)
-
- p.dataReceived('hello\r\nworld\r\n')
-
- self.assertEqual(t.data, ['hello, world', 'hello'])
- self.failUnless(t.paused)
- self.failUnless(p.paused)
-
- p.resumeProducing()
- p.dataReceived('goodbye\r\n')
-
- self.assertEqual(t.data, ['hello, world', 'hello', 'world'])
- self.failUnless(t.paused)
- self.failUnless(p.paused)
-
- p.resumeProducing()
-
- self.assertEqual(t.data, ['hello, world', 'hello', 'world', 'goodbye'])
- self.failUnless(t.paused)
- self.failUnless(p.paused)
-
- p.resumeProducing()
-
- self.assertEqual(t.data, ['hello, world', 'hello', 'world', 'goodbye'])
- self.failIf(t.paused)
- self.failIf(p.paused)
-
-
-
-class TestableProxyClientFactory(portforward.ProxyClientFactory):
- """
- Test proxy client factory that keeps the last created protocol instance.
-
- @ivar protoInstance: the last instance of the protocol.
- @type protoInstance: L{portforward.ProxyClient}
- """
-
- def buildProtocol(self, addr):
- """
- Create the protocol instance and keeps track of it.
- """
- proto = portforward.ProxyClientFactory.buildProtocol(self, addr)
- self.protoInstance = proto
- return proto
-
-
-
-class TestableProxyFactory(portforward.ProxyFactory):
- """
- Test proxy factory that keeps the last created protocol instance.
-
- @ivar protoInstance: the last instance of the protocol.
- @type protoInstance: L{portforward.ProxyServer}
-
- @ivar clientFactoryInstance: client factory used by C{protoInstance} to
- create forward connections.
- @type clientFactoryInstance: L{TestableProxyClientFactory}
- """
-
- def buildProtocol(self, addr):
- """
- Create the protocol instance, keeps track of it, and makes it use
- C{clientFactoryInstance} as client factory.
- """
- proto = portforward.ProxyFactory.buildProtocol(self, addr)
- self.clientFactoryInstance = TestableProxyClientFactory()
- # Force the use of this specific instance
- proto.clientProtocolFactory = lambda: self.clientFactoryInstance
- self.protoInstance = proto
- return proto
-
-
-
-class Portforwarding(unittest.TestCase):
- """
- Test port forwarding.
- """
-
- def setUp(self):
- self.serverProtocol = wire.Echo()
- self.clientProtocol = protocol.Protocol()
- self.openPorts = []
-
-
- def tearDown(self):
- try:
- self.proxyServerFactory.protoInstance.transport.loseConnection()
- except AttributeError:
- pass
- try:
- pi = self.proxyServerFactory.clientFactoryInstance.protoInstance
- pi.transport.loseConnection()
- except AttributeError:
- pass
- try:
- self.clientProtocol.transport.loseConnection()
- except AttributeError:
- pass
- try:
- self.serverProtocol.transport.loseConnection()
- except AttributeError:
- pass
- return defer.gatherResults(
- [defer.maybeDeferred(p.stopListening) for p in self.openPorts])
-
-
- def test_portforward(self):
- """
- Test port forwarding through Echo protocol.
- """
- realServerFactory = protocol.ServerFactory()
- realServerFactory.protocol = lambda: self.serverProtocol
- realServerPort = reactor.listenTCP(0, realServerFactory,
- interface='127.0.0.1')
- self.openPorts.append(realServerPort)
- self.proxyServerFactory = TestableProxyFactory('127.0.0.1',
- realServerPort.getHost().port)
- proxyServerPort = reactor.listenTCP(0, self.proxyServerFactory,
- interface='127.0.0.1')
- self.openPorts.append(proxyServerPort)
-
- nBytes = 1000
- received = []
- d = defer.Deferred()
-
- def testDataReceived(data):
- received.extend(data)
- if len(received) >= nBytes:
- self.assertEqual(''.join(received), 'x' * nBytes)
- d.callback(None)
-
- self.clientProtocol.dataReceived = testDataReceived
-
- def testConnectionMade():
- self.clientProtocol.transport.write('x' * nBytes)
-
- self.clientProtocol.connectionMade = testConnectionMade
-
- clientFactory = protocol.ClientFactory()
- clientFactory.protocol = lambda: self.clientProtocol
-
- reactor.connectTCP(
- '127.0.0.1', proxyServerPort.getHost().port, clientFactory)
-
- return d
-
-
- def test_registerProducers(self):
- """
- The proxy client registers itself as a producer of the proxy server and
- vice versa.
- """
- # create a ProxyServer instance
- addr = address.IPv4Address('TCP', '127.0.0.1', 0)
- server = portforward.ProxyFactory('127.0.0.1', 0).buildProtocol(addr)
-
- # set the reactor for this test
- reactor = proto_helpers.MemoryReactor()
- server.reactor = reactor
-
- # make the connection
- serverTransport = proto_helpers.StringTransport()
- server.makeConnection(serverTransport)
-
- # check that the ProxyClientFactory is connecting to the backend
- self.assertEqual(len(reactor.tcpClients), 1)
- # get the factory instance and check it's the one we expect
- host, port, clientFactory, timeout, _ = reactor.tcpClients[0]
- self.assertIsInstance(clientFactory, portforward.ProxyClientFactory)
-
- # Connect it
- client = clientFactory.buildProtocol(addr)
- clientTransport = proto_helpers.StringTransport()
- client.makeConnection(clientTransport)
-
- # check that the producers are registered
- self.assertIdentical(clientTransport.producer, serverTransport)
- self.assertIdentical(serverTransport.producer, clientTransport)
- # check the streaming attribute in both transports
- self.assertTrue(clientTransport.streaming)
- self.assertTrue(serverTransport.streaming)
-
-
-
-class StringTransportTestCase(unittest.TestCase):
- """
- Test L{proto_helpers.StringTransport} helper behaviour.
- """
-
- def test_noUnicode(self):
- """
- Test that L{proto_helpers.StringTransport} doesn't accept unicode data.
- """
- s = proto_helpers.StringTransport()
- self.assertRaises(TypeError, s.write, u'foo')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_randbytes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_randbytes.py
deleted file mode 100755
index cb0997c6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_randbytes.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for L{twisted.python.randbytes}.
-"""
-
-import os
-
-from twisted.trial import unittest
-from twisted.python import randbytes
-
-
-
-class SecureRandomTestCaseBase(object):
- """
- Base class for secureRandom test cases.
- """
-
- def _check(self, source):
- """
- The given random bytes source should return the number of bytes
- requested each time it is called and should probably not return the
- same bytes on two consecutive calls (although this is a perfectly
- legitimate occurrence and rejecting it may generate a spurious failure
- -- maybe we'll get lucky and the heat death with come first).
- """
- for nbytes in range(17, 25):
- s = source(nbytes)
- self.assertEqual(len(s), nbytes)
- s2 = source(nbytes)
- self.assertEqual(len(s2), nbytes)
- # This is crude but hey
- self.assertNotEquals(s2, s)
-
-
-
-class SecureRandomTestCase(SecureRandomTestCaseBase, unittest.TestCase):
- """
- Test secureRandom under normal conditions.
- """
-
- def test_normal(self):
- """
- L{randbytes.secureRandom} should return a string of the requested
- length and make some effort to make its result otherwise unpredictable.
- """
- self._check(randbytes.secureRandom)
-
-
-
-class ConditionalSecureRandomTestCase(SecureRandomTestCaseBase,
- unittest.TestCase):
- """
- Test random sources one by one, then remove it to.
- """
-
- def setUp(self):
- """
- Create a L{randbytes.RandomFactory} to use in the tests.
- """
- self.factory = randbytes.RandomFactory()
-
-
- def errorFactory(self, nbytes):
- """
- A factory raising an error when a source is not available.
- """
- raise randbytes.SourceNotAvailable()
-
-
- def test_osUrandom(self):
- """
- L{RandomFactory._osUrandom} should work as a random source whenever
- L{os.urandom} is available.
- """
- self._check(self.factory._osUrandom)
-
-
- def test_withoutAnything(self):
- """
- Remove all secure sources and assert it raises a failure. Then try the
- fallback parameter.
- """
- self.factory._osUrandom = self.errorFactory
- self.assertRaises(randbytes.SecureRandomNotAvailable,
- self.factory.secureRandom, 18)
- def wrapper():
- return self.factory.secureRandom(18, fallback=True)
- s = self.assertWarns(
- RuntimeWarning,
- "urandom unavailable - "
- "proceeding with non-cryptographically secure random source",
- __file__,
- wrapper)
- self.assertEqual(len(s), 18)
-
-
-
-class RandomTestCaseBase(SecureRandomTestCaseBase, unittest.TestCase):
- """
- 'Normal' random test cases.
- """
-
- def test_normal(self):
- """
- Test basic case.
- """
- self._check(randbytes.insecureRandom)
-
-
- def test_withoutGetrandbits(self):
- """
- Test C{insecureRandom} without C{random.getrandbits}.
- """
- factory = randbytes.RandomFactory()
- factory.getrandbits = None
- self._check(factory.insecureRandom)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_rebuild.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_rebuild.py
deleted file mode 100755
index dfeca9d1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_rebuild.py
+++ /dev/null
@@ -1,252 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-import sys, os
-import types
-
-from twisted.trial import unittest
-from twisted.python import rebuild
-
-import crash_test_dummy
-f = crash_test_dummy.foo
-
-class Foo: pass
-class Bar(Foo): pass
-class Baz(object): pass
-class Buz(Bar, Baz): pass
-
-class HashRaisesRuntimeError:
- """
- Things that don't hash (raise an Exception) should be ignored by the
- rebuilder.
-
- @ivar hashCalled: C{bool} set to True when __hash__ is called.
- """
- def __init__(self):
- self.hashCalled = False
-
- def __hash__(self):
- self.hashCalled = True
- raise RuntimeError('not a TypeError!')
-
-
-
-unhashableObject = None # set in test_hashException
-
-
-
-class RebuildTestCase(unittest.TestCase):
- """
- Simple testcase for rebuilding, to at least exercise the code.
- """
- def setUp(self):
- self.libPath = self.mktemp()
- os.mkdir(self.libPath)
- self.fakelibPath = os.path.join(self.libPath, 'twisted_rebuild_fakelib')
- os.mkdir(self.fakelibPath)
- file(os.path.join(self.fakelibPath, '__init__.py'), 'w').close()
- sys.path.insert(0, self.libPath)
-
- def tearDown(self):
- sys.path.remove(self.libPath)
-
- def testFileRebuild(self):
- from twisted.python.util import sibpath
- import shutil, time
- shutil.copyfile(sibpath(__file__, "myrebuilder1.py"),
- os.path.join(self.fakelibPath, "myrebuilder.py"))
- from twisted_rebuild_fakelib import myrebuilder
- a = myrebuilder.A()
- try:
- object
- except NameError:
- pass
- else:
- from twisted.test import test_rebuild
- b = myrebuilder.B()
- class C(myrebuilder.B):
- pass
- test_rebuild.C = C
- c = C()
- i = myrebuilder.Inherit()
- self.assertEqual(a.a(), 'a')
- # necessary because the file has not "changed" if a second has not gone
- # by in unix. This sucks, but it's not often that you'll be doing more
- # than one reload per second.
- time.sleep(1.1)
- shutil.copyfile(sibpath(__file__, "myrebuilder2.py"),
- os.path.join(self.fakelibPath, "myrebuilder.py"))
- rebuild.rebuild(myrebuilder)
- try:
- object
- except NameError:
- pass
- else:
- b2 = myrebuilder.B()
- self.assertEqual(b2.b(), 'c')
- self.assertEqual(b.b(), 'c')
- self.assertEqual(i.a(), 'd')
- self.assertEqual(a.a(), 'b')
- # more work to be done on new-style classes
- # self.assertEqual(c.b(), 'c')
-
- def testRebuild(self):
- """
- Rebuilding an unchanged module.
- """
- # This test would actually pass if rebuild was a no-op, but it
- # ensures rebuild doesn't break stuff while being a less
- # complex test than testFileRebuild.
-
- x = crash_test_dummy.X('a')
-
- rebuild.rebuild(crash_test_dummy, doLog=False)
- # Instance rebuilding is triggered by attribute access.
- x.do()
- self.failUnlessIdentical(x.__class__, crash_test_dummy.X)
-
- self.failUnlessIdentical(f, crash_test_dummy.foo)
-
- def testComponentInteraction(self):
- x = crash_test_dummy.XComponent()
- x.setAdapter(crash_test_dummy.IX, crash_test_dummy.XA)
- oldComponent = x.getComponent(crash_test_dummy.IX)
- rebuild.rebuild(crash_test_dummy, 0)
- newComponent = x.getComponent(crash_test_dummy.IX)
-
- newComponent.method()
-
- self.assertEqual(newComponent.__class__, crash_test_dummy.XA)
-
- # Test that a duplicate registerAdapter is not allowed
- from twisted.python import components
- self.failUnlessRaises(ValueError, components.registerAdapter,
- crash_test_dummy.XA, crash_test_dummy.X,
- crash_test_dummy.IX)
-
- def testUpdateInstance(self):
- global Foo, Buz
-
- b = Buz()
-
- class Foo:
- def foo(self):
- pass
- class Buz(Bar, Baz):
- x = 10
-
- rebuild.updateInstance(b)
- assert hasattr(b, 'foo'), "Missing method on rebuilt instance"
- assert hasattr(b, 'x'), "Missing class attribute on rebuilt instance"
-
- def testBananaInteraction(self):
- from twisted.python import rebuild
- from twisted.spread import banana
- rebuild.latestClass(banana.Banana)
-
-
- def test_hashException(self):
- """
- Rebuilding something that has a __hash__ that raises a non-TypeError
- shouldn't cause rebuild to die.
- """
- global unhashableObject
- unhashableObject = HashRaisesRuntimeError()
- def _cleanup():
- global unhashableObject
- unhashableObject = None
- self.addCleanup(_cleanup)
- rebuild.rebuild(rebuild)
- self.assertEqual(unhashableObject.hashCalled, True)
-
-
-
-class NewStyleTestCase(unittest.TestCase):
- """
- Tests for rebuilding new-style classes of various sorts.
- """
- def setUp(self):
- self.m = types.ModuleType('whipping')
- sys.modules['whipping'] = self.m
-
-
- def tearDown(self):
- del sys.modules['whipping']
- del self.m
-
-
- def test_slots(self):
- """
- Try to rebuild a new style class with slots defined.
- """
- classDefinition = (
- "class SlottedClass(object):\n"
- " __slots__ = ['a']\n")
-
- exec classDefinition in self.m.__dict__
- inst = self.m.SlottedClass()
- inst.a = 7
- exec classDefinition in self.m.__dict__
- rebuild.updateInstance(inst)
- self.assertEqual(inst.a, 7)
- self.assertIdentical(type(inst), self.m.SlottedClass)
-
- if sys.version_info < (2, 6):
- test_slots.skip = "__class__ assignment for class with slots is only available starting Python 2.6"
-
-
- def test_errorSlots(self):
- """
- Try to rebuild a new style class with slots defined: this should fail.
- """
- classDefinition = (
- "class SlottedClass(object):\n"
- " __slots__ = ['a']\n")
-
- exec classDefinition in self.m.__dict__
- inst = self.m.SlottedClass()
- inst.a = 7
- exec classDefinition in self.m.__dict__
- self.assertRaises(rebuild.RebuildError, rebuild.updateInstance, inst)
-
- if sys.version_info >= (2, 6):
- test_errorSlots.skip = "__class__ assignment for class with slots should work starting Python 2.6"
-
-
- def test_typeSubclass(self):
- """
- Try to rebuild a base type subclass.
- """
- classDefinition = (
- "class ListSubclass(list):\n"
- " pass\n")
-
- exec classDefinition in self.m.__dict__
- inst = self.m.ListSubclass()
- inst.append(2)
- exec classDefinition in self.m.__dict__
- rebuild.updateInstance(inst)
- self.assertEqual(inst[0], 2)
- self.assertIdentical(type(inst), self.m.ListSubclass)
-
-
- def test_instanceSlots(self):
- """
- Test that when rebuilding an instance with a __slots__ attribute, it
- fails accurately instead of giving a L{rebuild.RebuildError}.
- """
- classDefinition = (
- "class NotSlottedClass(object):\n"
- " pass\n")
-
- exec classDefinition in self.m.__dict__
- inst = self.m.NotSlottedClass()
- inst.__slots__ = ['a']
- classDefinition = (
- "class NotSlottedClass:\n"
- " pass\n")
- exec classDefinition in self.m.__dict__
- # Moving from new-style class to old-style should fail.
- self.assertRaises(TypeError, rebuild.updateInstance, inst)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_reflect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_reflect.py
deleted file mode 100755
index 68274ef3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_reflect.py
+++ /dev/null
@@ -1,873 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.reflect module.
-"""
-
-import weakref, os
-try:
- from ihooks import ModuleImporter
-except ImportError:
- ModuleImporter = None
-
-try:
- from collections import deque
-except ImportError:
- deque = None
-
-from twisted.trial import unittest
-from twisted.python import reflect, util
-from twisted.python.versions import Version
-
-
-
-class SettableTest(unittest.TestCase):
- def setUp(self):
- self.setter = reflect.Settable()
-
- def tearDown(self):
- del self.setter
-
- def testSet(self):
- self.setter(a=1, b=2)
- self.assertEqual(self.setter.a, 1)
- self.assertEqual(self.setter.b, 2)
-
-
-
-class AccessorTester(reflect.Accessor):
-
- def set_x(self, x):
- self.y = x
- self.reallySet('x', x)
-
-
- def get_z(self):
- self.q = 1
- return 1
-
-
- def del_z(self):
- self.reallyDel("q")
-
-
-
-class PropertyAccessorTester(reflect.PropertyAccessor):
- """
- Test class to check L{reflect.PropertyAccessor} functionalities.
- """
- r = 0
-
- def set_r(self, r):
- self.s = r
-
-
- def set_x(self, x):
- self.y = x
- self.reallySet('x', x)
-
-
- def get_z(self):
- self.q = 1
- return 1
-
-
- def del_z(self):
- self.reallyDel("q")
-
-
-
-class AccessorTest(unittest.TestCase):
- def setUp(self):
- self.tester = AccessorTester()
-
- def testSet(self):
- self.tester.x = 1
- self.assertEqual(self.tester.x, 1)
- self.assertEqual(self.tester.y, 1)
-
- def testGet(self):
- self.assertEqual(self.tester.z, 1)
- self.assertEqual(self.tester.q, 1)
-
- def testDel(self):
- self.tester.z
- self.assertEqual(self.tester.q, 1)
- del self.tester.z
- self.assertEqual(hasattr(self.tester, "q"), 0)
- self.tester.x = 1
- del self.tester.x
- self.assertEqual(hasattr(self.tester, "x"), 0)
-
-
-
-class PropertyAccessorTest(AccessorTest):
- """
- Tests for L{reflect.PropertyAccessor}, using L{PropertyAccessorTester}.
- """
-
- def setUp(self):
- self.tester = PropertyAccessorTester()
-
-
- def test_setWithDefaultValue(self):
- """
- If an attribute is present in the class, it can be retrieved by
- default.
- """
- self.assertEqual(self.tester.r, 0)
- self.tester.r = 1
- self.assertEqual(self.tester.r, 0)
- self.assertEqual(self.tester.s, 1)
-
-
- def test_getValueInDict(self):
- """
- The attribute value can be overriden by directly modifying the value in
- C{__dict__}.
- """
- self.tester.__dict__["r"] = 10
- self.assertEqual(self.tester.r, 10)
-
-
- def test_notYetInDict(self):
- """
- If a getter is defined on an attribute but without any default value,
- it raises C{AttributeError} when trying to access it.
- """
- self.assertRaises(AttributeError, getattr, self.tester, "x")
-
-
-
-class LookupsTestCase(unittest.TestCase):
- """
- Tests for L{namedClass}, L{namedModule}, and L{namedAny}.
- """
-
- def test_namedClassLookup(self):
- """
- L{namedClass} should return the class object for the name it is passed.
- """
- self.assertIdentical(
- reflect.namedClass("twisted.python.reflect.Summer"),
- reflect.Summer)
-
-
- def test_namedModuleLookup(self):
- """
- L{namedModule} should return the module object for the name it is
- passed.
- """
- self.assertIdentical(
- reflect.namedModule("twisted.python.reflect"), reflect)
-
-
- def test_namedAnyPackageLookup(self):
- """
- L{namedAny} should return the package object for the name it is passed.
- """
- import twisted.python
- self.assertIdentical(
- reflect.namedAny("twisted.python"), twisted.python)
-
- def test_namedAnyModuleLookup(self):
- """
- L{namedAny} should return the module object for the name it is passed.
- """
- self.assertIdentical(
- reflect.namedAny("twisted.python.reflect"), reflect)
-
-
- def test_namedAnyClassLookup(self):
- """
- L{namedAny} should return the class object for the name it is passed.
- """
- self.assertIdentical(
- reflect.namedAny("twisted.python.reflect.Summer"), reflect.Summer)
-
-
- def test_namedAnyAttributeLookup(self):
- """
- L{namedAny} should return the object an attribute of a non-module,
- non-package object is bound to for the name it is passed.
- """
- # Note - not assertEqual because unbound method lookup creates a new
- # object every time. This is a foolishness of Python's object
- # implementation, not a bug in Twisted.
- self.assertEqual(
- reflect.namedAny("twisted.python.reflect.Summer.reallySet"),
- reflect.Summer.reallySet)
-
-
- def test_namedAnySecondAttributeLookup(self):
- """
- L{namedAny} should return the object an attribute of an object which
- itself was an attribute of a non-module, non-package object is bound to
- for the name it is passed.
- """
- self.assertIdentical(
- reflect.namedAny(
- "twisted.python.reflect.Summer.reallySet.__doc__"),
- reflect.Summer.reallySet.__doc__)
-
-
- def test_importExceptions(self):
- """
- Exceptions raised by modules which L{namedAny} causes to be imported
- should pass through L{namedAny} to the caller.
- """
- self.assertRaises(
- ZeroDivisionError,
- reflect.namedAny, "twisted.test.reflect_helper_ZDE")
- # Make sure that this behavior is *consistent* for 2.3, where there is
- # no post-failed-import cleanup
- self.assertRaises(
- ZeroDivisionError,
- reflect.namedAny, "twisted.test.reflect_helper_ZDE")
- self.assertRaises(
- ValueError,
- reflect.namedAny, "twisted.test.reflect_helper_VE")
- # Modules which themselves raise ImportError when imported should result in an ImportError
- self.assertRaises(
- ImportError,
- reflect.namedAny, "twisted.test.reflect_helper_IE")
-
-
- def test_attributeExceptions(self):
- """
- If segments on the end of a fully-qualified Python name represents
- attributes which aren't actually present on the object represented by
- the earlier segments, L{namedAny} should raise an L{AttributeError}.
- """
- self.assertRaises(
- AttributeError,
- reflect.namedAny, "twisted.nosuchmoduleintheworld")
- # ImportError behaves somewhat differently between "import
- # extant.nonextant" and "import extant.nonextant.nonextant", so test
- # the latter as well.
- self.assertRaises(
- AttributeError,
- reflect.namedAny, "twisted.nosuch.modulein.theworld")
- self.assertRaises(
- AttributeError,
- reflect.namedAny, "twisted.python.reflect.Summer.nosuchattributeintheworld")
-
-
- def test_invalidNames(self):
- """
- Passing a name which isn't a fully-qualified Python name to L{namedAny}
- should result in one of the following exceptions:
- - L{InvalidName}: the name is not a dot-separated list of Python objects
- - L{ObjectNotFound}: the object doesn't exist
- - L{ModuleNotFound}: the object doesn't exist and there is only one
- component in the name
- """
- err = self.assertRaises(reflect.ModuleNotFound, reflect.namedAny,
- 'nosuchmoduleintheworld')
- self.assertEqual(str(err), "No module named 'nosuchmoduleintheworld'")
-
- # This is a dot-separated list, but it isn't valid!
- err = self.assertRaises(reflect.ObjectNotFound, reflect.namedAny,
- "@#$@(#.!@(#!@#")
- self.assertEqual(str(err), "'@#$@(#.!@(#!@#' does not name an object")
-
- err = self.assertRaises(reflect.ObjectNotFound, reflect.namedAny,
- "tcelfer.nohtyp.detsiwt")
- self.assertEqual(
- str(err),
- "'tcelfer.nohtyp.detsiwt' does not name an object")
-
- err = self.assertRaises(reflect.InvalidName, reflect.namedAny, '')
- self.assertEqual(str(err), 'Empty module name')
-
- for invalidName in ['.twisted', 'twisted.', 'twisted..python']:
- err = self.assertRaises(
- reflect.InvalidName, reflect.namedAny, invalidName)
- self.assertEqual(
- str(err),
- "name must be a string giving a '.'-separated list of Python "
- "identifiers, not %r" % (invalidName,))
-
-
-
-class ImportHooksLookupTests(LookupsTestCase):
- """
- Tests for lookup methods in the presence of L{ihooks}-style import hooks.
- Runs all of the tests from L{LookupsTestCase} after installing a custom
- import hook.
- """
- if ModuleImporter == None:
- skip = "ihooks not available"
-
- def setUp(self):
- """
- Perturb the normal import behavior subtly by installing an import
- hook. No custom behavior is provided, but this adds some extra
- frames to the call stack, which L{namedAny} must be able to account
- for.
- """
- self.importer = ModuleImporter()
- self.importer.install()
-
-
- def tearDown(self):
- """
- Uninstall the custom import hook.
- """
- self.importer.uninstall()
-
-
-
-class ObjectGrep(unittest.TestCase):
- def test_dictionary(self):
- """
- Test references search through a dictionnary, as a key or as a value.
- """
- o = object()
- d1 = {None: o}
- d2 = {o: None}
-
- self.assertIn("[None]", reflect.objgrep(d1, o, reflect.isSame))
- self.assertIn("{None}", reflect.objgrep(d2, o, reflect.isSame))
-
- def test_list(self):
- """
- Test references search through a list.
- """
- o = object()
- L = [None, o]
-
- self.assertIn("[1]", reflect.objgrep(L, o, reflect.isSame))
-
- def test_tuple(self):
- """
- Test references search through a tuple.
- """
- o = object()
- T = (o, None)
-
- self.assertIn("[0]", reflect.objgrep(T, o, reflect.isSame))
-
- def test_instance(self):
- """
- Test references search through an object attribute.
- """
- class Dummy:
- pass
- o = object()
- d = Dummy()
- d.o = o
-
- self.assertIn(".o", reflect.objgrep(d, o, reflect.isSame))
-
- def test_weakref(self):
- """
- Test references search through a weakref object.
- """
- class Dummy:
- pass
- o = Dummy()
- w1 = weakref.ref(o)
-
- self.assertIn("()", reflect.objgrep(w1, o, reflect.isSame))
-
- def test_boundMethod(self):
- """
- Test references search through method special attributes.
- """
- class Dummy:
- def dummy(self):
- pass
- o = Dummy()
- m = o.dummy
-
- self.assertIn(".im_self", reflect.objgrep(m, m.im_self, reflect.isSame))
- self.assertIn(".im_class", reflect.objgrep(m, m.im_class, reflect.isSame))
- self.assertIn(".im_func", reflect.objgrep(m, m.im_func, reflect.isSame))
-
- def test_everything(self):
- """
- Test references search using complex set of objects.
- """
- class Dummy:
- def method(self):
- pass
-
- o = Dummy()
- D1 = {(): "baz", None: "Quux", o: "Foosh"}
- L = [None, (), D1, 3]
- T = (L, {}, Dummy())
- D2 = {0: "foo", 1: "bar", 2: T}
- i = Dummy()
- i.attr = D2
- m = i.method
- w = weakref.ref(m)
-
- self.assertIn("().im_self.attr[2][0][2]{'Foosh'}", reflect.objgrep(w, o, reflect.isSame))
-
- def test_depthLimit(self):
- """
- Test the depth of references search.
- """
- a = []
- b = [a]
- c = [a, b]
- d = [a, c]
-
- self.assertEqual(['[0]'], reflect.objgrep(d, a, reflect.isSame, maxDepth=1))
- self.assertEqual(['[0]', '[1][0]'], reflect.objgrep(d, a, reflect.isSame, maxDepth=2))
- self.assertEqual(['[0]', '[1][0]', '[1][1][0]'], reflect.objgrep(d, a, reflect.isSame, maxDepth=3))
-
- def test_deque(self):
- """
- Test references search through a deque object. Only for Python > 2.3.
- """
- o = object()
- D = deque()
- D.append(None)
- D.append(o)
-
- self.assertIn("[1]", reflect.objgrep(D, o, reflect.isSame))
-
- if deque is None:
- test_deque.skip = "Deque not available"
-
-
-class GetClass(unittest.TestCase):
- def testOld(self):
- class OldClass:
- pass
- old = OldClass()
- self.assertIn(reflect.getClass(OldClass).__name__, ('class', 'classobj'))
- self.assertEqual(reflect.getClass(old).__name__, 'OldClass')
-
- def testNew(self):
- class NewClass(object):
- pass
- new = NewClass()
- self.assertEqual(reflect.getClass(NewClass).__name__, 'type')
- self.assertEqual(reflect.getClass(new).__name__, 'NewClass')
-
-
-
-class Breakable(object):
-
- breakRepr = False
- breakStr = False
-
- def __str__(self):
- if self.breakStr:
- raise RuntimeError("str!")
- else:
- return '<Breakable>'
-
- def __repr__(self):
- if self.breakRepr:
- raise RuntimeError("repr!")
- else:
- return 'Breakable()'
-
-
-
-class BrokenType(Breakable, type):
- breakName = False
-
- def get___name__(self):
- if self.breakName:
- raise RuntimeError("no name")
- return 'BrokenType'
- __name__ = property(get___name__)
-
-
-
-class BTBase(Breakable):
- __metaclass__ = BrokenType
- breakRepr = True
- breakStr = True
-
-
-
-class NoClassAttr(Breakable):
- __class__ = property(lambda x: x.not_class)
-
-
-
-class SafeRepr(unittest.TestCase):
- """
- Tests for L{reflect.safe_repr} function.
- """
-
- def test_workingRepr(self):
- """
- L{reflect.safe_repr} produces the same output as C{repr} on a working
- object.
- """
- x = [1, 2, 3]
- self.assertEqual(reflect.safe_repr(x), repr(x))
-
-
- def test_brokenRepr(self):
- """
- L{reflect.safe_repr} returns a string with class name, address, and
- traceback when the repr call failed.
- """
- b = Breakable()
- b.breakRepr = True
- bRepr = reflect.safe_repr(b)
- self.assertIn("Breakable instance at 0x", bRepr)
- # Check that the file is in the repr, but without the extension as it
- # can be .py/.pyc
- self.assertIn(os.path.splitext(__file__)[0], bRepr)
- self.assertIn("RuntimeError: repr!", bRepr)
-
-
- def test_brokenStr(self):
- """
- L{reflect.safe_repr} isn't affected by a broken C{__str__} method.
- """
- b = Breakable()
- b.breakStr = True
- self.assertEqual(reflect.safe_repr(b), repr(b))
-
-
- def test_brokenClassRepr(self):
- class X(BTBase):
- breakRepr = True
- reflect.safe_repr(X)
- reflect.safe_repr(X())
-
-
- def test_unsignedID(self):
- """
- L{unsignedID} is used to print ID of the object in case of error, not
- standard ID value which can be negative.
- """
- class X(BTBase):
- breakRepr = True
-
- ids = {X: 100}
- def fakeID(obj):
- try:
- return ids[obj]
- except (TypeError, KeyError):
- return id(obj)
- self.addCleanup(util.setIDFunction, util.setIDFunction(fakeID))
-
- xRepr = reflect.safe_repr(X)
- self.assertIn("0x64", xRepr)
-
-
- def test_brokenClassStr(self):
- class X(BTBase):
- breakStr = True
- reflect.safe_repr(X)
- reflect.safe_repr(X())
-
-
- def test_brokenClassAttribute(self):
- """
- If an object raises an exception when accessing its C{__class__}
- attribute, L{reflect.safe_repr} uses C{type} to retrieve the class
- object.
- """
- b = NoClassAttr()
- b.breakRepr = True
- bRepr = reflect.safe_repr(b)
- self.assertIn("NoClassAttr instance at 0x", bRepr)
- self.assertIn(os.path.splitext(__file__)[0], bRepr)
- self.assertIn("RuntimeError: repr!", bRepr)
-
-
- def test_brokenClassNameAttribute(self):
- """
- If a class raises an exception when accessing its C{__name__} attribute
- B{and} when calling its C{__str__} implementation, L{reflect.safe_repr}
- returns 'BROKEN CLASS' instead of the class name.
- """
- class X(BTBase):
- breakName = True
- xRepr = reflect.safe_repr(X())
- self.assertIn("<BROKEN CLASS AT 0x", xRepr)
- self.assertIn(os.path.splitext(__file__)[0], xRepr)
- self.assertIn("RuntimeError: repr!", xRepr)
-
-
-
-class SafeStr(unittest.TestCase):
- """
- Tests for L{reflect.safe_str} function.
- """
-
- def test_workingStr(self):
- x = [1, 2, 3]
- self.assertEqual(reflect.safe_str(x), str(x))
-
-
- def test_brokenStr(self):
- b = Breakable()
- b.breakStr = True
- reflect.safe_str(b)
-
-
- def test_brokenRepr(self):
- b = Breakable()
- b.breakRepr = True
- reflect.safe_str(b)
-
-
- def test_brokenClassStr(self):
- class X(BTBase):
- breakStr = True
- reflect.safe_str(X)
- reflect.safe_str(X())
-
-
- def test_brokenClassRepr(self):
- class X(BTBase):
- breakRepr = True
- reflect.safe_str(X)
- reflect.safe_str(X())
-
-
- def test_brokenClassAttribute(self):
- """
- If an object raises an exception when accessing its C{__class__}
- attribute, L{reflect.safe_str} uses C{type} to retrieve the class
- object.
- """
- b = NoClassAttr()
- b.breakStr = True
- bStr = reflect.safe_str(b)
- self.assertIn("NoClassAttr instance at 0x", bStr)
- self.assertIn(os.path.splitext(__file__)[0], bStr)
- self.assertIn("RuntimeError: str!", bStr)
-
-
- def test_brokenClassNameAttribute(self):
- """
- If a class raises an exception when accessing its C{__name__} attribute
- B{and} when calling its C{__str__} implementation, L{reflect.safe_str}
- returns 'BROKEN CLASS' instead of the class name.
- """
- class X(BTBase):
- breakName = True
- xStr = reflect.safe_str(X())
- self.assertIn("<BROKEN CLASS AT 0x", xStr)
- self.assertIn(os.path.splitext(__file__)[0], xStr)
- self.assertIn("RuntimeError: str!", xStr)
-
-
-
-class FilenameToModule(unittest.TestCase):
- """
- Test L{reflect.filenameToModuleName} detection.
- """
- def test_directory(self):
- """
- Tests it finds good name for directories/packages.
- """
- module = reflect.filenameToModuleName(os.path.join('twisted', 'test'))
- self.assertEqual(module, 'test')
- module = reflect.filenameToModuleName(os.path.join('twisted', 'test')
- + os.path.sep)
- self.assertEqual(module, 'test')
-
- def test_file(self):
- """
- Test it finds good name for files.
- """
- module = reflect.filenameToModuleName(
- os.path.join('twisted', 'test', 'test_reflect.py'))
- self.assertEqual(module, 'test_reflect')
-
-
-
-class FullyQualifiedNameTests(unittest.TestCase):
- """
- Test for L{reflect.fullyQualifiedName}.
- """
-
- def _checkFullyQualifiedName(self, obj, expected):
- """
- Helper to check that fully qualified name of C{obj} results to
- C{expected}.
- """
- self.assertEqual(
- reflect.fullyQualifiedName(obj), expected)
-
-
- def test_package(self):
- """
- L{reflect.fullyQualifiedName} returns the full name of a package and
- a subpackage.
- """
- import twisted
- self._checkFullyQualifiedName(twisted, 'twisted')
- import twisted.python
- self._checkFullyQualifiedName(twisted.python, 'twisted.python')
-
-
- def test_module(self):
- """
- L{reflect.fullyQualifiedName} returns the name of a module inside a a
- package.
- """
- self._checkFullyQualifiedName(reflect, 'twisted.python.reflect')
- import twisted.trial.unittest
- self._checkFullyQualifiedName(twisted.trial.unittest,
- 'twisted.trial.unittest')
-
-
- def test_class(self):
- """
- L{reflect.fullyQualifiedName} returns the name of a class and its
- module.
- """
- self._checkFullyQualifiedName(reflect.Settable,
- 'twisted.python.reflect.Settable')
-
-
- def test_function(self):
- """
- L{reflect.fullyQualifiedName} returns the name of a function inside its
- module.
- """
- self._checkFullyQualifiedName(reflect.fullyQualifiedName,
- "twisted.python.reflect.fullyQualifiedName")
-
-
- def test_boundMethod(self):
- """
- L{reflect.fullyQualifiedName} returns the name of a bound method inside
- its class and its module.
- """
- self._checkFullyQualifiedName(
- reflect.PropertyAccessor().reallyDel,
- "twisted.python.reflect.PropertyAccessor.reallyDel")
-
-
- def test_unboundMethod(self):
- """
- L{reflect.fullyQualifiedName} returns the name of an unbound method
- inside its class and its module.
- """
- self._checkFullyQualifiedName(
- reflect.PropertyAccessor.reallyDel,
- "twisted.python.reflect.PropertyAccessor.reallyDel")
-
-
-
-class DeprecationTestCase(unittest.TestCase):
- """
- Test deprecations in twisted.python.reflect
- """
-
- def test_allYourBase(self):
- """
- Test deprecation of L{reflect.allYourBase}. See #5481 for removal.
- """
- self.callDeprecated(
- (Version("Twisted", 11, 0, 0), "inspect.getmro"),
- reflect.allYourBase, DeprecationTestCase)
-
-
- def test_accumulateBases(self):
- """
- Test deprecation of L{reflect.accumulateBases}. See #5481 for removal.
- """
- l = []
- self.callDeprecated(
- (Version("Twisted", 11, 0, 0), "inspect.getmro"),
- reflect.accumulateBases, DeprecationTestCase, l, None)
-
-
- def lookForDeprecationWarning(self, testMethod, attributeName, warningMsg):
- """
- Test deprecation of attribute 'reflect.attributeName' by calling
- 'reflect.testMethod' and verifying the warning message
- 'reflect.warningMsg'
-
- @param testMethod: Name of the offending function to be used with
- flushWarnings
- @type testmethod: C{str}
-
- @param attributeName: Name of attribute to be checked for deprecation
- @type attributeName: C{str}
-
- @param warningMsg: Deprecation warning message
- @type warningMsg: C{str}
- """
- warningsShown = self.flushWarnings([testMethod])
- self.assertEqual(len(warningsShown), 1)
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(
- warningsShown[0]['message'],
- "twisted.python.reflect." + attributeName + " "
- "was deprecated in Twisted 12.1.0: " + warningMsg + ".")
-
-
- def test_settable(self):
- """
- Test deprecation of L{reflect.Settable}.
- """
- reflect.Settable()
- self.lookForDeprecationWarning(
- self.test_settable, "Settable",
- "Settable is old and untested. Please write your own version of this "
- "functionality if you need it")
-
-
- def test_accessorType(self):
- """
- Test deprecation of L{reflect.AccessorType}.
- """
- reflect.AccessorType(' ', ( ), { })
- self.lookForDeprecationWarning(
- self.test_accessorType, "AccessorType",
- "AccessorType is old and untested. Please write your own version of "
- "this functionality if you need it")
-
-
- def test_propertyAccessor(self):
- """
- Test deprecation of L{reflect.PropertyAccessor}.
- """
- reflect.PropertyAccessor()
- self.lookForDeprecationWarning(
- self.test_propertyAccessor, "PropertyAccessor",
- "PropertyAccessor is old and untested. Please write your own "
- "version of this functionality if you need it")
-
-
- def test_accessor(self):
- """
- Test deprecation of L{reflect.Accessor}.
- """
- reflect.Accessor()
- self.lookForDeprecationWarning(
- self.test_accessor, "Accessor",
- "Accessor is an implementation for Python 2.1 which is no longer "
- "supported by Twisted")
-
-
- def test_originalAccessor(self):
- """
- Test deprecation of L{reflect.OriginalAccessor}.
- """
- reflect.OriginalAccessor()
- self.lookForDeprecationWarning(
- self.test_originalAccessor, "OriginalAccessor",
- "OriginalAccessor is a reference to class "
- "twisted.python.reflect.Accessor which is deprecated")
-
-
- def test_summer(self):
- """
- Test deprecation of L{reflect.Summer}.
- """
- reflect.Summer()
- self.lookForDeprecationWarning(
- self.test_summer, "Summer",
- "Summer is a child class of twisted.python.reflect.Accessor which "
- "is deprecated")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_roots.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_roots.py
deleted file mode 100755
index c9fd39ef..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_roots.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-from twisted.python import roots
-import types
-
-class RootsTest(unittest.TestCase):
-
- def testExceptions(self):
- request = roots.Request()
- try:
- request.write("blah")
- except NotImplementedError:
- pass
- else:
- self.fail()
- try:
- request.finish()
- except NotImplementedError:
- pass
- else:
- self.fail()
-
- def testCollection(self):
- collection = roots.Collection()
- collection.putEntity("x", 'test')
- self.assertEqual(collection.getStaticEntity("x"),
- 'test')
- collection.delEntity("x")
- self.assertEqual(collection.getStaticEntity('x'),
- None)
- try:
- collection.storeEntity("x", None)
- except NotImplementedError:
- pass
- else:
- self.fail()
- try:
- collection.removeEntity("x", None)
- except NotImplementedError:
- pass
- else:
- self.fail()
-
- def testConstrained(self):
- class const(roots.Constrained):
- def nameConstraint(self, name):
- return (name == 'x')
- c = const()
- self.assertEqual(c.putEntity('x', 'test'), None)
- self.failUnlessRaises(roots.ConstraintViolation,
- c.putEntity, 'y', 'test')
-
-
- def testHomogenous(self):
- h = roots.Homogenous()
- h.entityType = types.IntType
- h.putEntity('a', 1)
- self.assertEqual(h.getStaticEntity('a'),1 )
- self.failUnlessRaises(roots.ConstraintViolation,
- h.putEntity, 'x', 'y')
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_shortcut.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_shortcut.py
deleted file mode 100755
index fdcb7753..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_shortcut.py
+++ /dev/null
@@ -1,26 +0,0 @@
-"""Test win32 shortcut script
-"""
-
-from twisted.trial import unittest
-
-import os
-if os.name == 'nt':
-
- skipWindowsNopywin32 = None
- try:
- from twisted.python import shortcut
- except ImportError:
- skipWindowsNopywin32 = ("On windows, twisted.python.shortcut is not "
- "available in the absence of win32com.")
- import os.path
- import sys
-
- class ShortcutTest(unittest.TestCase):
- def testCreate(self):
- s1=shortcut.Shortcut("test_shortcut.py")
- tempname=self.mktemp() + '.lnk'
- s1.save(tempname)
- self.assert_(os.path.exists(tempname))
- sc=shortcut.open(tempname)
- self.assert_(sc.GetPath(0)[0].endswith('test_shortcut.py'))
- ShortcutTest.skip = skipWindowsNopywin32
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sip.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sip.py
deleted file mode 100755
index 73f09d49..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sip.py
+++ /dev/null
@@ -1,984 +0,0 @@
-# -*- test-case-name: twisted.test.test_sip -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Session Initialization Protocol tests."""
-
-from twisted.trial import unittest, util
-from twisted.protocols import sip
-from twisted.internet import defer, reactor, utils
-from twisted.python.versions import Version
-
-from twisted.test import proto_helpers
-
-from twisted import cred
-import twisted.cred.portal
-import twisted.cred.checkers
-
-from zope.interface import implements
-
-
-# request, prefixed by random CRLFs
-request1 = "\n\r\n\n\r" + """\
-INVITE sip:foo SIP/2.0
-From: mo
-To: joe
-Content-Length: 4
-
-abcd""".replace("\n", "\r\n")
-
-# request, no content-length
-request2 = """INVITE sip:foo SIP/2.0
-From: mo
-To: joe
-
-1234""".replace("\n", "\r\n")
-
-# request, with garbage after
-request3 = """INVITE sip:foo SIP/2.0
-From: mo
-To: joe
-Content-Length: 4
-
-1234
-
-lalalal""".replace("\n", "\r\n")
-
-# three requests
-request4 = """INVITE sip:foo SIP/2.0
-From: mo
-To: joe
-Content-Length: 0
-
-INVITE sip:loop SIP/2.0
-From: foo
-To: bar
-Content-Length: 4
-
-abcdINVITE sip:loop SIP/2.0
-From: foo
-To: bar
-Content-Length: 4
-
-1234""".replace("\n", "\r\n")
-
-# response, no content
-response1 = """SIP/2.0 200 OK
-From: foo
-To:bar
-Content-Length: 0
-
-""".replace("\n", "\r\n")
-
-# short header version
-request_short = """\
-INVITE sip:foo SIP/2.0
-f: mo
-t: joe
-l: 4
-
-abcd""".replace("\n", "\r\n")
-
-request_natted = """\
-INVITE sip:foo SIP/2.0
-Via: SIP/2.0/UDP 10.0.0.1:5060;rport
-
-""".replace("\n", "\r\n")
-
-# multiline headers (example from RFC 3621).
-response_multiline = """\
-SIP/2.0 200 OK
-Via: SIP/2.0/UDP server10.biloxi.com
- ;branch=z9hG4bKnashds8;received=192.0.2.3
-Via: SIP/2.0/UDP bigbox3.site3.atlanta.com
- ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
-Via: SIP/2.0/UDP pc33.atlanta.com
- ;branch=z9hG4bK776asdhds ;received=192.0.2.1
-To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
-From: Alice <sip:alice@atlanta.com>;tag=1928301774
-Call-ID: a84b4c76e66710@pc33.atlanta.com
-CSeq: 314159 INVITE
-Contact: <sip:bob@192.0.2.4>
-Content-Type: application/sdp
-Content-Length: 0
-\n""".replace("\n", "\r\n")
-
-class TestRealm:
- def requestAvatar(self, avatarId, mind, *interfaces):
- return sip.IContact, None, lambda: None
-
-class MessageParsingTestCase(unittest.TestCase):
- def setUp(self):
- self.l = []
- self.parser = sip.MessagesParser(self.l.append)
-
- def feedMessage(self, message):
- self.parser.dataReceived(message)
- self.parser.dataDone()
-
- def validateMessage(self, m, method, uri, headers, body):
- """Validate Requests."""
- self.assertEqual(m.method, method)
- self.assertEqual(m.uri.toString(), uri)
- self.assertEqual(m.headers, headers)
- self.assertEqual(m.body, body)
- self.assertEqual(m.finished, 1)
-
- def testSimple(self):
- l = self.l
- self.feedMessage(request1)
- self.assertEqual(len(l), 1)
- self.validateMessage(
- l[0], "INVITE", "sip:foo",
- {"from": ["mo"], "to": ["joe"], "content-length": ["4"]},
- "abcd")
-
- def testTwoMessages(self):
- l = self.l
- self.feedMessage(request1)
- self.feedMessage(request2)
- self.assertEqual(len(l), 2)
- self.validateMessage(
- l[0], "INVITE", "sip:foo",
- {"from": ["mo"], "to": ["joe"], "content-length": ["4"]},
- "abcd")
- self.validateMessage(l[1], "INVITE", "sip:foo",
- {"from": ["mo"], "to": ["joe"]},
- "1234")
-
- def testGarbage(self):
- l = self.l
- self.feedMessage(request3)
- self.assertEqual(len(l), 1)
- self.validateMessage(
- l[0], "INVITE", "sip:foo",
- {"from": ["mo"], "to": ["joe"], "content-length": ["4"]},
- "1234")
-
- def testThreeInOne(self):
- l = self.l
- self.feedMessage(request4)
- self.assertEqual(len(l), 3)
- self.validateMessage(
- l[0], "INVITE", "sip:foo",
- {"from": ["mo"], "to": ["joe"], "content-length": ["0"]},
- "")
- self.validateMessage(
- l[1], "INVITE", "sip:loop",
- {"from": ["foo"], "to": ["bar"], "content-length": ["4"]},
- "abcd")
- self.validateMessage(
- l[2], "INVITE", "sip:loop",
- {"from": ["foo"], "to": ["bar"], "content-length": ["4"]},
- "1234")
-
- def testShort(self):
- l = self.l
- self.feedMessage(request_short)
- self.assertEqual(len(l), 1)
- self.validateMessage(
- l[0], "INVITE", "sip:foo",
- {"from": ["mo"], "to": ["joe"], "content-length": ["4"]},
- "abcd")
-
- def testSimpleResponse(self):
- l = self.l
- self.feedMessage(response1)
- self.assertEqual(len(l), 1)
- m = l[0]
- self.assertEqual(m.code, 200)
- self.assertEqual(m.phrase, "OK")
- self.assertEqual(
- m.headers,
- {"from": ["foo"], "to": ["bar"], "content-length": ["0"]})
- self.assertEqual(m.body, "")
- self.assertEqual(m.finished, 1)
-
-
- def test_multiLine(self):
- """
- A header may be split across multiple lines. Subsequent lines begin
- with C{" "} or C{"\\t"}.
- """
- l = self.l
- self.feedMessage(response_multiline)
- self.assertEquals(len(l), 1)
- m = l[0]
- self.assertEquals(
- m.headers['via'][0],
- "SIP/2.0/UDP server10.biloxi.com;"
- "branch=z9hG4bKnashds8;received=192.0.2.3")
- self.assertEquals(
- m.headers['via'][1],
- "SIP/2.0/UDP bigbox3.site3.atlanta.com;"
- "branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2")
- self.assertEquals(
- m.headers['via'][2],
- "SIP/2.0/UDP pc33.atlanta.com;"
- "branch=z9hG4bK776asdhds ;received=192.0.2.1")
-
-
-
-class MessageParsingTestCase2(MessageParsingTestCase):
- """Same as base class, but feed data char by char."""
-
- def feedMessage(self, message):
- for c in message:
- self.parser.dataReceived(c)
- self.parser.dataDone()
-
-
-class MakeMessageTestCase(unittest.TestCase):
-
- def testRequest(self):
- r = sip.Request("INVITE", "sip:foo")
- r.addHeader("foo", "bar")
- self.assertEqual(
- r.toString(),
- "INVITE sip:foo SIP/2.0\r\nFoo: bar\r\n\r\n")
-
- def testResponse(self):
- r = sip.Response(200, "OK")
- r.addHeader("foo", "bar")
- r.addHeader("Content-Length", "4")
- r.bodyDataReceived("1234")
- self.assertEqual(
- r.toString(),
- "SIP/2.0 200 OK\r\nFoo: bar\r\nContent-Length: 4\r\n\r\n1234")
-
- def testStatusCode(self):
- r = sip.Response(200)
- self.assertEqual(r.toString(), "SIP/2.0 200 OK\r\n\r\n")
-
-
-class ViaTestCase(unittest.TestCase):
-
- def checkRoundtrip(self, v):
- s = v.toString()
- self.assertEqual(s, sip.parseViaHeader(s).toString())
-
- def testExtraWhitespace(self):
- v1 = sip.parseViaHeader('SIP/2.0/UDP 192.168.1.1:5060')
- v2 = sip.parseViaHeader('SIP/2.0/UDP 192.168.1.1:5060')
- self.assertEqual(v1.transport, v2.transport)
- self.assertEqual(v1.host, v2.host)
- self.assertEqual(v1.port, v2.port)
-
- def test_complex(self):
- """
- Test parsing a Via header with one of everything.
- """
- s = ("SIP/2.0/UDP first.example.com:4000;ttl=16;maddr=224.2.0.1"
- " ;branch=a7c6a8dlze (Example)")
- v = sip.parseViaHeader(s)
- self.assertEqual(v.transport, "UDP")
- self.assertEqual(v.host, "first.example.com")
- self.assertEqual(v.port, 4000)
- self.assertEqual(v.rport, None)
- self.assertEqual(v.rportValue, None)
- self.assertEqual(v.rportRequested, False)
- self.assertEqual(v.ttl, 16)
- self.assertEqual(v.maddr, "224.2.0.1")
- self.assertEqual(v.branch, "a7c6a8dlze")
- self.assertEqual(v.hidden, 0)
- self.assertEqual(v.toString(),
- "SIP/2.0/UDP first.example.com:4000"
- ";ttl=16;branch=a7c6a8dlze;maddr=224.2.0.1")
- self.checkRoundtrip(v)
-
- def test_simple(self):
- """
- Test parsing a simple Via header.
- """
- s = "SIP/2.0/UDP example.com;hidden"
- v = sip.parseViaHeader(s)
- self.assertEqual(v.transport, "UDP")
- self.assertEqual(v.host, "example.com")
- self.assertEqual(v.port, 5060)
- self.assertEqual(v.rport, None)
- self.assertEqual(v.rportValue, None)
- self.assertEqual(v.rportRequested, False)
- self.assertEqual(v.ttl, None)
- self.assertEqual(v.maddr, None)
- self.assertEqual(v.branch, None)
- self.assertEqual(v.hidden, True)
- self.assertEqual(v.toString(),
- "SIP/2.0/UDP example.com:5060;hidden")
- self.checkRoundtrip(v)
-
- def testSimpler(self):
- v = sip.Via("example.com")
- self.checkRoundtrip(v)
-
-
- def test_deprecatedRPort(self):
- """
- Setting rport to True is deprecated, but still produces a Via header
- with the expected properties.
- """
- v = sip.Via("foo.bar", rport=True)
-
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_deprecatedRPort])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(
- warnings[0]['message'],
- 'rport=True is deprecated since Twisted 9.0.')
- self.assertEqual(
- warnings[0]['category'],
- DeprecationWarning)
-
- self.assertEqual(v.toString(), "SIP/2.0/UDP foo.bar:5060;rport")
- self.assertEqual(v.rport, True)
- self.assertEqual(v.rportRequested, True)
- self.assertEqual(v.rportValue, None)
-
-
- def test_rport(self):
- """
- An rport setting of None should insert the parameter with no value.
- """
- v = sip.Via("foo.bar", rport=None)
- self.assertEqual(v.toString(), "SIP/2.0/UDP foo.bar:5060;rport")
- self.assertEqual(v.rportRequested, True)
- self.assertEqual(v.rportValue, None)
-
-
- def test_rportValue(self):
- """
- An rport numeric setting should insert the parameter with the number
- value given.
- """
- v = sip.Via("foo.bar", rport=1)
- self.assertEqual(v.toString(), "SIP/2.0/UDP foo.bar:5060;rport=1")
- self.assertEqual(v.rportRequested, False)
- self.assertEqual(v.rportValue, 1)
- self.assertEqual(v.rport, 1)
-
-
- def testNAT(self):
- s = "SIP/2.0/UDP 10.0.0.1:5060;received=22.13.1.5;rport=12345"
- v = sip.parseViaHeader(s)
- self.assertEqual(v.transport, "UDP")
- self.assertEqual(v.host, "10.0.0.1")
- self.assertEqual(v.port, 5060)
- self.assertEqual(v.received, "22.13.1.5")
- self.assertEqual(v.rport, 12345)
-
- self.assertNotEquals(v.toString().find("rport=12345"), -1)
-
-
- def test_unknownParams(self):
- """
- Parsing and serializing Via headers with unknown parameters should work.
- """
- s = "SIP/2.0/UDP example.com:5060;branch=a12345b;bogus;pie=delicious"
- v = sip.parseViaHeader(s)
- self.assertEqual(v.toString(), s)
-
-
-
-class URLTestCase(unittest.TestCase):
-
- def testRoundtrip(self):
- for url in [
- "sip:j.doe@big.com",
- "sip:j.doe:secret@big.com;transport=tcp",
- "sip:j.doe@big.com?subject=project",
- "sip:example.com",
- ]:
- self.assertEqual(sip.parseURL(url).toString(), url)
-
- def testComplex(self):
- s = ("sip:user:pass@hosta:123;transport=udp;user=phone;method=foo;"
- "ttl=12;maddr=1.2.3.4;blah;goo=bar?a=b&c=d")
- url = sip.parseURL(s)
- for k, v in [("username", "user"), ("password", "pass"),
- ("host", "hosta"), ("port", 123),
- ("transport", "udp"), ("usertype", "phone"),
- ("method", "foo"), ("ttl", 12),
- ("maddr", "1.2.3.4"), ("other", ["blah", "goo=bar"]),
- ("headers", {"a": "b", "c": "d"})]:
- self.assertEqual(getattr(url, k), v)
-
-
-class ParseTestCase(unittest.TestCase):
-
- def testParseAddress(self):
- for address, name, urls, params in [
- ('"A. G. Bell" <sip:foo@example.com>',
- "A. G. Bell", "sip:foo@example.com", {}),
- ("Anon <sip:foo@example.com>", "Anon", "sip:foo@example.com", {}),
- ("sip:foo@example.com", "", "sip:foo@example.com", {}),
- ("<sip:foo@example.com>", "", "sip:foo@example.com", {}),
- ("foo <sip:foo@example.com>;tag=bar;foo=baz", "foo",
- "sip:foo@example.com", {"tag": "bar", "foo": "baz"}),
- ]:
- gname, gurl, gparams = sip.parseAddress(address)
- self.assertEqual(name, gname)
- self.assertEqual(gurl.toString(), urls)
- self.assertEqual(gparams, params)
-
-
-class DummyLocator:
- implements(sip.ILocator)
- def getAddress(self, logicalURL):
- return defer.succeed(sip.URL("server.com", port=5060))
-
-class FailingLocator:
- implements(sip.ILocator)
- def getAddress(self, logicalURL):
- return defer.fail(LookupError())
-
-
-class ProxyTestCase(unittest.TestCase):
-
- def setUp(self):
- self.proxy = sip.Proxy("127.0.0.1")
- self.proxy.locator = DummyLocator()
- self.sent = []
- self.proxy.sendMessage = lambda dest, msg: self.sent.append((dest, msg))
-
- def testRequestForward(self):
- r = sip.Request("INVITE", "sip:foo")
- r.addHeader("via", sip.Via("1.2.3.4").toString())
- r.addHeader("via", sip.Via("1.2.3.5").toString())
- r.addHeader("foo", "bar")
- r.addHeader("to", "<sip:joe@server.com>")
- r.addHeader("contact", "<sip:joe@1.2.3.5>")
- self.proxy.datagramReceived(r.toString(), ("1.2.3.4", 5060))
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual(dest.port, 5060)
- self.assertEqual(dest.host, "server.com")
- self.assertEqual(m.uri.toString(), "sip:foo")
- self.assertEqual(m.method, "INVITE")
- self.assertEqual(m.headers["via"],
- ["SIP/2.0/UDP 127.0.0.1:5060",
- "SIP/2.0/UDP 1.2.3.4:5060",
- "SIP/2.0/UDP 1.2.3.5:5060"])
-
-
- def testReceivedRequestForward(self):
- r = sip.Request("INVITE", "sip:foo")
- r.addHeader("via", sip.Via("1.2.3.4").toString())
- r.addHeader("foo", "bar")
- r.addHeader("to", "<sip:joe@server.com>")
- r.addHeader("contact", "<sip:joe@1.2.3.4>")
- self.proxy.datagramReceived(r.toString(), ("1.1.1.1", 5060))
- dest, m = self.sent[0]
- self.assertEqual(m.headers["via"],
- ["SIP/2.0/UDP 127.0.0.1:5060",
- "SIP/2.0/UDP 1.2.3.4:5060;received=1.1.1.1"])
-
-
- def testResponseWrongVia(self):
- # first via must match proxy's address
- r = sip.Response(200)
- r.addHeader("via", sip.Via("foo.com").toString())
- self.proxy.datagramReceived(r.toString(), ("1.1.1.1", 5060))
- self.assertEqual(len(self.sent), 0)
-
- def testResponseForward(self):
- r = sip.Response(200)
- r.addHeader("via", sip.Via("127.0.0.1").toString())
- r.addHeader("via", sip.Via("client.com", port=1234).toString())
- self.proxy.datagramReceived(r.toString(), ("1.1.1.1", 5060))
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual((dest.host, dest.port), ("client.com", 1234))
- self.assertEqual(m.code, 200)
- self.assertEqual(m.headers["via"], ["SIP/2.0/UDP client.com:1234"])
-
- def testReceivedResponseForward(self):
- r = sip.Response(200)
- r.addHeader("via", sip.Via("127.0.0.1").toString())
- r.addHeader(
- "via",
- sip.Via("10.0.0.1", received="client.com").toString())
- self.proxy.datagramReceived(r.toString(), ("1.1.1.1", 5060))
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual((dest.host, dest.port), ("client.com", 5060))
-
- def testResponseToUs(self):
- r = sip.Response(200)
- r.addHeader("via", sip.Via("127.0.0.1").toString())
- l = []
- self.proxy.gotResponse = lambda *a: l.append(a)
- self.proxy.datagramReceived(r.toString(), ("1.1.1.1", 5060))
- self.assertEqual(len(l), 1)
- m, addr = l[0]
- self.assertEqual(len(m.headers.get("via", [])), 0)
- self.assertEqual(m.code, 200)
-
- def testLoop(self):
- r = sip.Request("INVITE", "sip:foo")
- r.addHeader("via", sip.Via("1.2.3.4").toString())
- r.addHeader("via", sip.Via("127.0.0.1").toString())
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
- self.assertEqual(self.sent, [])
-
- def testCantForwardRequest(self):
- r = sip.Request("INVITE", "sip:foo")
- r.addHeader("via", sip.Via("1.2.3.4").toString())
- r.addHeader("to", "<sip:joe@server.com>")
- self.proxy.locator = FailingLocator()
- self.proxy.datagramReceived(r.toString(), ("1.2.3.4", 5060))
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual((dest.host, dest.port), ("1.2.3.4", 5060))
- self.assertEqual(m.code, 404)
- self.assertEqual(m.headers["via"], ["SIP/2.0/UDP 1.2.3.4:5060"])
-
- def testCantForwardResponse(self):
- pass
-
- #testCantForwardResponse.skip = "not implemented yet"
-
-
-class RegistrationTestCase(unittest.TestCase):
-
- def setUp(self):
- self.proxy = sip.RegisterProxy(host="127.0.0.1")
- self.registry = sip.InMemoryRegistry("bell.example.com")
- self.proxy.registry = self.proxy.locator = self.registry
- self.sent = []
- self.proxy.sendMessage = lambda dest, msg: self.sent.append((dest, msg))
- setUp = utils.suppressWarnings(setUp,
- util.suppress(category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestAuthorizer was deprecated'))
-
- def tearDown(self):
- for d, uri in self.registry.users.values():
- d.cancel()
- del self.proxy
-
- def register(self):
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "sip:joe@client.com:1234")
- r.addHeader("via", sip.Via("client.com").toString())
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
-
- def unregister(self):
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "*")
- r.addHeader("via", sip.Via("client.com").toString())
- r.addHeader("expires", "0")
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
-
- def testRegister(self):
- self.register()
- dest, m = self.sent[0]
- self.assertEqual((dest.host, dest.port), ("client.com", 5060))
- self.assertEqual(m.code, 200)
- self.assertEqual(m.headers["via"], ["SIP/2.0/UDP client.com:5060"])
- self.assertEqual(m.headers["to"], ["sip:joe@bell.example.com"])
- self.assertEqual(m.headers["contact"], ["sip:joe@client.com:5060"])
- self.failUnless(
- int(m.headers["expires"][0]) in (3600, 3601, 3599, 3598))
- self.assertEqual(len(self.registry.users), 1)
- dc, uri = self.registry.users["joe"]
- self.assertEqual(uri.toString(), "sip:joe@client.com:5060")
- d = self.proxy.locator.getAddress(sip.URL(username="joe",
- host="bell.example.com"))
- d.addCallback(lambda desturl : (desturl.host, desturl.port))
- d.addCallback(self.assertEqual, ('client.com', 5060))
- return d
-
- def testUnregister(self):
- self.register()
- self.unregister()
- dest, m = self.sent[1]
- self.assertEqual((dest.host, dest.port), ("client.com", 5060))
- self.assertEqual(m.code, 200)
- self.assertEqual(m.headers["via"], ["SIP/2.0/UDP client.com:5060"])
- self.assertEqual(m.headers["to"], ["sip:joe@bell.example.com"])
- self.assertEqual(m.headers["contact"], ["sip:joe@client.com:5060"])
- self.assertEqual(m.headers["expires"], ["0"])
- self.assertEqual(self.registry.users, {})
-
-
- def addPortal(self):
- r = TestRealm()
- p = cred.portal.Portal(r)
- c = cred.checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser('userXname@127.0.0.1', 'passXword')
- p.registerChecker(c)
- self.proxy.portal = p
-
- def testFailedAuthentication(self):
- self.addPortal()
- self.register()
-
- self.assertEqual(len(self.registry.users), 0)
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual(m.code, 401)
-
-
- def test_basicAuthentication(self):
- """
- Test that registration with basic authentication suceeds.
- """
- self.addPortal()
- self.proxy.authorizers = self.proxy.authorizers.copy()
- self.proxy.authorizers['basic'] = sip.BasicAuthorizer()
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_basicAuthentication])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(
- warnings[0]['message'],
- "twisted.protocols.sip.BasicAuthorizer was deprecated in "
- "Twisted 9.0.0")
- self.assertEqual(
- warnings[0]['category'],
- DeprecationWarning)
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "sip:joe@client.com:1234")
- r.addHeader("via", sip.Via("client.com").toString())
- r.addHeader("authorization",
- "Basic " + "userXname:passXword".encode('base64'))
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
-
- self.assertEqual(len(self.registry.users), 1)
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual(m.code, 200)
-
-
- def test_failedBasicAuthentication(self):
- """
- Failed registration with basic authentication results in an
- unauthorized error response.
- """
- self.addPortal()
- self.proxy.authorizers = self.proxy.authorizers.copy()
- self.proxy.authorizers['basic'] = sip.BasicAuthorizer()
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_failedBasicAuthentication])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(
- warnings[0]['message'],
- "twisted.protocols.sip.BasicAuthorizer was deprecated in "
- "Twisted 9.0.0")
- self.assertEqual(
- warnings[0]['category'],
- DeprecationWarning)
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "sip:joe@client.com:1234")
- r.addHeader("via", sip.Via("client.com").toString())
- r.addHeader(
- "authorization", "Basic " + "userXname:password".encode('base64'))
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
-
- self.assertEqual(len(self.registry.users), 0)
- self.assertEqual(len(self.sent), 1)
- dest, m = self.sent[0]
- self.assertEqual(m.code, 401)
-
-
- def testWrongDomainRegister(self):
- r = sip.Request("REGISTER", "sip:wrong.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "sip:joe@client.com:1234")
- r.addHeader("via", sip.Via("client.com").toString())
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
- self.assertEqual(len(self.sent), 0)
-
- def testWrongToDomainRegister(self):
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@foo.com")
- r.addHeader("contact", "sip:joe@client.com:1234")
- r.addHeader("via", sip.Via("client.com").toString())
- self.proxy.datagramReceived(r.toString(), ("client.com", 5060))
- self.assertEqual(len(self.sent), 0)
-
- def testWrongDomainLookup(self):
- self.register()
- url = sip.URL(username="joe", host="foo.com")
- d = self.proxy.locator.getAddress(url)
- self.assertFailure(d, LookupError)
- return d
-
- def testNoContactLookup(self):
- self.register()
- url = sip.URL(username="jane", host="bell.example.com")
- d = self.proxy.locator.getAddress(url)
- self.assertFailure(d, LookupError)
- return d
-
-
-class Client(sip.Base):
-
- def __init__(self):
- sip.Base.__init__(self)
- self.received = []
- self.deferred = defer.Deferred()
-
- def handle_response(self, response, addr):
- self.received.append(response)
- self.deferred.callback(self.received)
-
-
-class LiveTest(unittest.TestCase):
-
- def setUp(self):
- self.proxy = sip.RegisterProxy(host="127.0.0.1")
- self.registry = sip.InMemoryRegistry("bell.example.com")
- self.proxy.registry = self.proxy.locator = self.registry
- self.serverPort = reactor.listenUDP(
- 0, self.proxy, interface="127.0.0.1")
- self.client = Client()
- self.clientPort = reactor.listenUDP(
- 0, self.client, interface="127.0.0.1")
- self.serverAddress = (self.serverPort.getHost().host,
- self.serverPort.getHost().port)
- setUp = utils.suppressWarnings(setUp,
- util.suppress(category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestAuthorizer was deprecated'))
-
- def tearDown(self):
- for d, uri in self.registry.users.values():
- d.cancel()
- d1 = defer.maybeDeferred(self.clientPort.stopListening)
- d2 = defer.maybeDeferred(self.serverPort.stopListening)
- return defer.gatherResults([d1, d2])
-
- def testRegister(self):
- p = self.clientPort.getHost().port
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "sip:joe@127.0.0.1:%d" % p)
- r.addHeader("via", sip.Via("127.0.0.1", port=p).toString())
- self.client.sendMessage(
- sip.URL(host="127.0.0.1", port=self.serverAddress[1]), r)
- d = self.client.deferred
- def check(received):
- self.assertEqual(len(received), 1)
- r = received[0]
- self.assertEqual(r.code, 200)
- d.addCallback(check)
- return d
-
- def test_amoralRPort(self):
- """
- rport is allowed without a value, apparently because server
- implementors might be too stupid to check the received port
- against 5060 and see if they're equal, and because client
- implementors might be too stupid to bind to port 5060, or set a
- value on the rport parameter they send if they bind to another
- port.
- """
- p = self.clientPort.getHost().port
- r = sip.Request("REGISTER", "sip:bell.example.com")
- r.addHeader("to", "sip:joe@bell.example.com")
- r.addHeader("contact", "sip:joe@127.0.0.1:%d" % p)
- r.addHeader("via", sip.Via("127.0.0.1", port=p, rport=True).toString())
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_amoralRPort])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(
- warnings[0]['message'],
- 'rport=True is deprecated since Twisted 9.0.')
- self.assertEqual(
- warnings[0]['category'],
- DeprecationWarning)
- self.client.sendMessage(sip.URL(host="127.0.0.1",
- port=self.serverAddress[1]),
- r)
- d = self.client.deferred
- def check(received):
- self.assertEqual(len(received), 1)
- r = received[0]
- self.assertEqual(r.code, 200)
- d.addCallback(check)
- return d
-
-
-
-registerRequest = """
-REGISTER sip:intarweb.us SIP/2.0\r
-Via: SIP/2.0/UDP 192.168.1.100:50609\r
-From: <sip:exarkun@intarweb.us:50609>\r
-To: <sip:exarkun@intarweb.us:50609>\r
-Contact: "exarkun" <sip:exarkun@192.168.1.100:50609>\r
-Call-ID: 94E7E5DAF39111D791C6000393764646@intarweb.us\r
-CSeq: 9898 REGISTER\r
-Expires: 500\r
-User-Agent: X-Lite build 1061\r
-Content-Length: 0\r
-\r
-"""
-
-challengeResponse = """\
-SIP/2.0 401 Unauthorized\r
-Via: SIP/2.0/UDP 192.168.1.100:50609;received=127.0.0.1;rport=5632\r
-To: <sip:exarkun@intarweb.us:50609>\r
-From: <sip:exarkun@intarweb.us:50609>\r
-Call-ID: 94E7E5DAF39111D791C6000393764646@intarweb.us\r
-CSeq: 9898 REGISTER\r
-WWW-Authenticate: Digest nonce="92956076410767313901322208775",opaque="1674186428",qop-options="auth",algorithm="MD5",realm="intarweb.us"\r
-\r
-"""
-
-authRequest = """\
-REGISTER sip:intarweb.us SIP/2.0\r
-Via: SIP/2.0/UDP 192.168.1.100:50609\r
-From: <sip:exarkun@intarweb.us:50609>\r
-To: <sip:exarkun@intarweb.us:50609>\r
-Contact: "exarkun" <sip:exarkun@192.168.1.100:50609>\r
-Call-ID: 94E7E5DAF39111D791C6000393764646@intarweb.us\r
-CSeq: 9899 REGISTER\r
-Expires: 500\r
-Authorization: Digest username="exarkun",realm="intarweb.us",nonce="92956076410767313901322208775",response="4a47980eea31694f997369214292374b",uri="sip:intarweb.us",algorithm=MD5,opaque="1674186428"\r
-User-Agent: X-Lite build 1061\r
-Content-Length: 0\r
-\r
-"""
-
-okResponse = """\
-SIP/2.0 200 OK\r
-Via: SIP/2.0/UDP 192.168.1.100:50609;received=127.0.0.1;rport=5632\r
-To: <sip:exarkun@intarweb.us:50609>\r
-From: <sip:exarkun@intarweb.us:50609>\r
-Call-ID: 94E7E5DAF39111D791C6000393764646@intarweb.us\r
-CSeq: 9899 REGISTER\r
-Contact: sip:exarkun@127.0.0.1:5632\r
-Expires: 3600\r
-Content-Length: 0\r
-\r
-"""
-
-class FakeDigestAuthorizer(sip.DigestAuthorizer):
- def generateNonce(self):
- return '92956076410767313901322208775'
- def generateOpaque(self):
- return '1674186428'
-
-
-class FakeRegistry(sip.InMemoryRegistry):
- """Make sure expiration is always seen to be 3600.
-
- Otherwise slow reactors fail tests incorrectly.
- """
-
- def _cbReg(self, reg):
- if 3600 < reg.secondsToExpiry or reg.secondsToExpiry < 3598:
- raise RuntimeError(
- "bad seconds to expire: %s" % reg.secondsToExpiry)
- reg.secondsToExpiry = 3600
- return reg
-
- def getRegistrationInfo(self, uri):
- d = sip.InMemoryRegistry.getRegistrationInfo(self, uri)
- return d.addCallback(self._cbReg)
-
- def registerAddress(self, domainURL, logicalURL, physicalURL):
- d = sip.InMemoryRegistry.registerAddress(
- self, domainURL, logicalURL, physicalURL)
- return d.addCallback(self._cbReg)
-
-class AuthorizationTestCase(unittest.TestCase):
- def setUp(self):
- self.proxy = sip.RegisterProxy(host="intarweb.us")
- self.proxy.authorizers = self.proxy.authorizers.copy()
- self.proxy.authorizers['digest'] = FakeDigestAuthorizer()
-
- self.registry = FakeRegistry("intarweb.us")
- self.proxy.registry = self.proxy.locator = self.registry
- self.transport = proto_helpers.FakeDatagramTransport()
- self.proxy.transport = self.transport
-
- r = TestRealm()
- p = cred.portal.Portal(r)
- c = cred.checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser('exarkun@intarweb.us', 'password')
- p.registerChecker(c)
- self.proxy.portal = p
- setUp = utils.suppressWarnings(setUp,
- util.suppress(category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestAuthorizer was deprecated'))
-
- def tearDown(self):
- for d, uri in self.registry.users.values():
- d.cancel()
- del self.proxy
-
- def testChallenge(self):
- self.proxy.datagramReceived(registerRequest, ("127.0.0.1", 5632))
-
- self.assertEqual(
- self.transport.written[-1],
- ((challengeResponse, ("127.0.0.1", 5632)))
- )
- self.transport.written = []
-
- self.proxy.datagramReceived(authRequest, ("127.0.0.1", 5632))
-
- self.assertEqual(
- self.transport.written[-1],
- ((okResponse, ("127.0.0.1", 5632)))
- )
- testChallenge.suppress = [
- util.suppress(
- category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestAuthorizer was deprecated'),
- util.suppress(
- category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestedCredentials was deprecated'),
- util.suppress(
- category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestCalcHA1 was deprecated'),
- util.suppress(
- category=DeprecationWarning,
- message=r'twisted.protocols.sip.DigestCalcResponse was deprecated')]
-
-
-
-class DeprecationTests(unittest.TestCase):
- """
- Tests for deprecation of obsolete components of L{twisted.protocols.sip}.
- """
-
- def test_deprecatedDigestCalcHA1(self):
- """
- L{sip.DigestCalcHA1} is deprecated.
- """
- self.callDeprecated(Version("Twisted", 9, 0, 0),
- sip.DigestCalcHA1, '', '', '', '', '', '')
-
-
- def test_deprecatedDigestCalcResponse(self):
- """
- L{sip.DigestCalcResponse} is deprecated.
- """
- self.callDeprecated(Version("Twisted", 9, 0, 0),
- sip.DigestCalcResponse, '', '', '', '', '', '', '',
- '')
-
- def test_deprecatedBasicAuthorizer(self):
- """
- L{sip.BasicAuthorizer} is deprecated.
- """
- self.callDeprecated(Version("Twisted", 9, 0, 0), sip.BasicAuthorizer)
-
-
- def test_deprecatedDigestAuthorizer(self):
- """
- L{sip.DigestAuthorizer} is deprecated.
- """
- self.callDeprecated(Version("Twisted", 9, 0, 0), sip.DigestAuthorizer)
-
-
- def test_deprecatedDigestedCredentials(self):
- """
- L{sip.DigestedCredentials} is deprecated.
- """
- self.callDeprecated(Version("Twisted", 9, 0, 0),
- sip.DigestedCredentials, '', {}, {})
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sob.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sob.py
deleted file mode 100755
index 76c33a89..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sob.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-import sys, os
-
-try:
- import Crypto.Cipher.AES
-except ImportError:
- Crypto = None
-
-from twisted.trial import unittest
-from twisted.persisted import sob
-from twisted.python import components
-
-class Dummy(components.Componentized):
- pass
-
-objects = [
-1,
-"hello",
-(1, "hello"),
-[1, "hello"],
-{1:"hello"},
-]
-
-class FakeModule(object):
- pass
-
-class PersistTestCase(unittest.TestCase):
- def testStyles(self):
- for o in objects:
- p = sob.Persistent(o, '')
- for style in 'source pickle'.split():
- p.setStyle(style)
- p.save(filename='persisttest.'+style)
- o1 = sob.load('persisttest.'+style, style)
- self.assertEqual(o, o1)
-
- def testStylesBeingSet(self):
- o = Dummy()
- o.foo = 5
- o.setComponent(sob.IPersistable, sob.Persistent(o, 'lala'))
- for style in 'source pickle'.split():
- sob.IPersistable(o).setStyle(style)
- sob.IPersistable(o).save(filename='lala.'+style)
- o1 = sob.load('lala.'+style, style)
- self.assertEqual(o.foo, o1.foo)
- self.assertEqual(sob.IPersistable(o1).style, style)
-
-
- def testNames(self):
- o = [1,2,3]
- p = sob.Persistent(o, 'object')
- for style in 'source pickle'.split():
- p.setStyle(style)
- p.save()
- o1 = sob.load('object.ta'+style[0], style)
- self.assertEqual(o, o1)
- for tag in 'lala lolo'.split():
- p.save(tag)
- o1 = sob.load('object-'+tag+'.ta'+style[0], style)
- self.assertEqual(o, o1)
-
- def testEncryptedStyles(self):
- for o in objects:
- phrase='once I was the king of spain'
- p = sob.Persistent(o, '')
- for style in 'source pickle'.split():
- p.setStyle(style)
- p.save(filename='epersisttest.'+style, passphrase=phrase)
- o1 = sob.load('epersisttest.'+style, style, phrase)
- self.assertEqual(o, o1)
- if Crypto is None:
- testEncryptedStyles.skip = "PyCrypto required for encrypted config"
-
- def testPython(self):
- f = open("persisttest.python", 'w')
- f.write('foo=[1,2,3] ')
- f.close()
- o = sob.loadValueFromFile('persisttest.python', 'foo')
- self.assertEqual(o, [1,2,3])
-
- def testEncryptedPython(self):
- phrase='once I was the king of spain'
- f = open("epersisttest.python", 'w')
- f.write(
- sob._encrypt(phrase, 'foo=[1,2,3]'))
- f.close()
- o = sob.loadValueFromFile('epersisttest.python', 'foo', phrase)
- self.assertEqual(o, [1,2,3])
- if Crypto is None:
- testEncryptedPython.skip = "PyCrypto required for encrypted config"
-
- def testTypeGuesser(self):
- self.assertRaises(KeyError, sob.guessType, "file.blah")
- self.assertEqual('python', sob.guessType("file.py"))
- self.assertEqual('python', sob.guessType("file.tac"))
- self.assertEqual('python', sob.guessType("file.etac"))
- self.assertEqual('pickle', sob.guessType("file.tap"))
- self.assertEqual('pickle', sob.guessType("file.etap"))
- self.assertEqual('source', sob.guessType("file.tas"))
- self.assertEqual('source', sob.guessType("file.etas"))
-
- def testEverythingEphemeralGetattr(self):
- """
- Verify that _EverythingEphermal.__getattr__ works.
- """
- self.fakeMain.testMainModGetattr = 1
-
- dirname = self.mktemp()
- os.mkdir(dirname)
-
- filename = os.path.join(dirname, 'persisttest.ee_getattr')
-
- f = file(filename, 'w')
- f.write('import __main__\n')
- f.write('if __main__.testMainModGetattr != 1: raise AssertionError\n')
- f.write('app = None\n')
- f.close()
-
- sob.load(filename, 'source')
-
- def testEverythingEphemeralSetattr(self):
- """
- Verify that _EverythingEphemeral.__setattr__ won't affect __main__.
- """
- self.fakeMain.testMainModSetattr = 1
-
- dirname = self.mktemp()
- os.mkdir(dirname)
-
- filename = os.path.join(dirname, 'persisttest.ee_setattr')
- f = file(filename, 'w')
- f.write('import __main__\n')
- f.write('__main__.testMainModSetattr = 2\n')
- f.write('app = None\n')
- f.close()
-
- sob.load(filename, 'source')
-
- self.assertEqual(self.fakeMain.testMainModSetattr, 1)
-
- def testEverythingEphemeralException(self):
- """
- Test that an exception during load() won't cause _EE to mask __main__
- """
- dirname = self.mktemp()
- os.mkdir(dirname)
- filename = os.path.join(dirname, 'persisttest.ee_exception')
-
- f = file(filename, 'w')
- f.write('raise ValueError\n')
- f.close()
-
- self.assertRaises(ValueError, sob.load, filename, 'source')
- self.assertEqual(type(sys.modules['__main__']), FakeModule)
-
- def setUp(self):
- """
- Replace the __main__ module with a fake one, so that it can be mutated
- in tests
- """
- self.realMain = sys.modules['__main__']
- self.fakeMain = sys.modules['__main__'] = FakeModule()
-
- def tearDown(self):
- """
- Restore __main__ to its original value
- """
- sys.modules['__main__'] = self.realMain
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_socks.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_socks.py
deleted file mode 100755
index ebcb8431..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_socks.py
+++ /dev/null
@@ -1,498 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.protocol.socks}, an implementation of the SOCKSv4 and
-SOCKSv4a protocols.
-"""
-
-import struct, socket
-
-from twisted.trial import unittest
-from twisted.test import proto_helpers
-from twisted.internet import defer, address, reactor
-from twisted.internet.error import DNSLookupError
-from twisted.protocols import socks
-
-
-class StringTCPTransport(proto_helpers.StringTransport):
- stringTCPTransport_closing = False
- peer = None
-
- def getPeer(self):
- return self.peer
-
- def getHost(self):
- return address.IPv4Address('TCP', '2.3.4.5', 42)
-
- def loseConnection(self):
- self.stringTCPTransport_closing = True
-
-
-
-class FakeResolverReactor:
- """
- Bare-bones reactor with deterministic behavior for the resolve method.
- """
- def __init__(self, names):
- """
- @type names: C{dict} containing C{str} keys and C{str} values.
- @param names: A hostname to IP address mapping. The IP addresses are
- stringified dotted quads.
- """
- self.names = names
-
-
- def resolve(self, hostname):
- """
- Resolve a hostname by looking it up in the C{names} dictionary.
- """
- try:
- return defer.succeed(self.names[hostname])
- except KeyError:
- return defer.fail(
- DNSLookupError("FakeResolverReactor couldn't find " + hostname))
-
-
-
-class SOCKSv4Driver(socks.SOCKSv4):
- # last SOCKSv4Outgoing instantiated
- driver_outgoing = None
-
- # last SOCKSv4IncomingFactory instantiated
- driver_listen = None
-
- def connectClass(self, host, port, klass, *args):
- # fake it
- proto = klass(*args)
- proto.transport = StringTCPTransport()
- proto.transport.peer = address.IPv4Address('TCP', host, port)
- proto.connectionMade()
- self.driver_outgoing = proto
- return defer.succeed(proto)
-
- def listenClass(self, port, klass, *args):
- # fake it
- factory = klass(*args)
- self.driver_listen = factory
- if port == 0:
- port = 1234
- return defer.succeed(('6.7.8.9', port))
-
-
-
-class Connect(unittest.TestCase):
- """
- Tests for SOCKS and SOCKSv4a connect requests using the L{SOCKSv4} protocol.
- """
- def setUp(self):
- self.sock = SOCKSv4Driver()
- self.sock.transport = StringTCPTransport()
- self.sock.connectionMade()
- self.sock.reactor = FakeResolverReactor({"localhost":"127.0.0.1"})
-
-
- def tearDown(self):
- outgoing = self.sock.driver_outgoing
- if outgoing is not None:
- self.assert_(outgoing.transport.stringTCPTransport_closing,
- "Outgoing SOCKS connections need to be closed.")
-
-
- def test_simple(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 1, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 90, 34)
- + socket.inet_aton('1.2.3.4'))
- self.assert_(not self.sock.transport.stringTCPTransport_closing)
- self.assert_(self.sock.driver_outgoing is not None)
-
- # pass some data through
- self.sock.dataReceived('hello, world')
- self.assertEqual(self.sock.driver_outgoing.transport.value(),
- 'hello, world')
-
- # the other way around
- self.sock.driver_outgoing.dataReceived('hi there')
- self.assertEqual(self.sock.transport.value(), 'hi there')
-
- self.sock.connectionLost('fake reason')
-
-
- def test_socks4aSuccessfulResolution(self):
- """
- If the destination IP address has zeros for the first three octets and
- non-zero for the fourth octet, the client is attempting a v4a
- connection. A hostname is specified after the user ID string and the
- server connects to the address that hostname resolves to.
-
- @see: U{http://en.wikipedia.org/wiki/SOCKS#SOCKS_4a_protocol}
- """
- # send the domain name "localhost" to be resolved
- clientRequest = (
- struct.pack('!BBH', 4, 1, 34)
- + socket.inet_aton('0.0.0.1')
- + 'fooBAZ\0'
- + 'localhost\0')
-
- # Deliver the bytes one by one to exercise the protocol's buffering
- # logic. FakeResolverReactor's resolve method is invoked to "resolve"
- # the hostname.
- for byte in clientRequest:
- self.sock.dataReceived(byte)
-
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # Verify that the server responded with the address which will be
- # connected to.
- self.assertEqual(
- sent,
- struct.pack('!BBH', 0, 90, 34) + socket.inet_aton('127.0.0.1'))
- self.assertFalse(self.sock.transport.stringTCPTransport_closing)
- self.assertNotIdentical(self.sock.driver_outgoing, None)
-
- # Pass some data through and verify it is forwarded to the outgoing
- # connection.
- self.sock.dataReceived('hello, world')
- self.assertEqual(
- self.sock.driver_outgoing.transport.value(), 'hello, world')
-
- # Deliver some data from the output connection and verify it is
- # passed along to the incoming side.
- self.sock.driver_outgoing.dataReceived('hi there')
- self.assertEqual(self.sock.transport.value(), 'hi there')
-
- self.sock.connectionLost('fake reason')
-
-
- def test_socks4aFailedResolution(self):
- """
- Failed hostname resolution on a SOCKSv4a packet results in a 91 error
- response and the connection getting closed.
- """
- # send the domain name "failinghost" to be resolved
- clientRequest = (
- struct.pack('!BBH', 4, 1, 34)
- + socket.inet_aton('0.0.0.1')
- + 'fooBAZ\0'
- + 'failinghost\0')
-
- # Deliver the bytes one by one to exercise the protocol's buffering
- # logic. FakeResolverReactor's resolve method is invoked to "resolve"
- # the hostname.
- for byte in clientRequest:
- self.sock.dataReceived(byte)
-
- # Verify that the server responds with a 91 error.
- sent = self.sock.transport.value()
- self.assertEqual(
- sent,
- struct.pack('!BBH', 0, 91, 0) + socket.inet_aton('0.0.0.0'))
-
- # A failed resolution causes the transport to drop the connection.
- self.assertTrue(self.sock.transport.stringTCPTransport_closing)
- self.assertIdentical(self.sock.driver_outgoing, None)
-
-
- def test_accessDenied(self):
- self.sock.authorize = lambda code, server, port, user: 0
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 1, 4242)
- + socket.inet_aton('10.2.3.4')
- + 'fooBAR'
- + '\0')
- self.assertEqual(self.sock.transport.value(),
- struct.pack('!BBH', 0, 91, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assert_(self.sock.transport.stringTCPTransport_closing)
- self.assertIdentical(self.sock.driver_outgoing, None)
-
-
- def test_eofRemote(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 1, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # pass some data through
- self.sock.dataReceived('hello, world')
- self.assertEqual(self.sock.driver_outgoing.transport.value(),
- 'hello, world')
-
- # now close it from the server side
- self.sock.driver_outgoing.transport.loseConnection()
- self.sock.driver_outgoing.connectionLost('fake reason')
-
-
- def test_eofLocal(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 1, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # pass some data through
- self.sock.dataReceived('hello, world')
- self.assertEqual(self.sock.driver_outgoing.transport.value(),
- 'hello, world')
-
- # now close it from the client side
- self.sock.connectionLost('fake reason')
-
-
-
-class Bind(unittest.TestCase):
- """
- Tests for SOCKS and SOCKSv4a bind requests using the L{SOCKSv4} protocol.
- """
- def setUp(self):
- self.sock = SOCKSv4Driver()
- self.sock.transport = StringTCPTransport()
- self.sock.connectionMade()
- self.sock.reactor = FakeResolverReactor({"localhost":"127.0.0.1"})
-
-## def tearDown(self):
-## # TODO ensure the listen port is closed
-## listen = self.sock.driver_listen
-## if listen is not None:
-## self.assert_(incoming.transport.stringTCPTransport_closing,
-## "Incoming SOCKS connections need to be closed.")
-
- def test_simple(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 2, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 90, 1234)
- + socket.inet_aton('6.7.8.9'))
- self.assert_(not self.sock.transport.stringTCPTransport_closing)
- self.assert_(self.sock.driver_listen is not None)
-
- # connect
- incoming = self.sock.driver_listen.buildProtocol(('1.2.3.4', 5345))
- self.assertNotIdentical(incoming, None)
- incoming.transport = StringTCPTransport()
- incoming.connectionMade()
-
- # now we should have the second reply packet
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 90, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assert_(not self.sock.transport.stringTCPTransport_closing)
-
- # pass some data through
- self.sock.dataReceived('hello, world')
- self.assertEqual(incoming.transport.value(),
- 'hello, world')
-
- # the other way around
- incoming.dataReceived('hi there')
- self.assertEqual(self.sock.transport.value(), 'hi there')
-
- self.sock.connectionLost('fake reason')
-
-
- def test_socks4a(self):
- """
- If the destination IP address has zeros for the first three octets and
- non-zero for the fourth octet, the client is attempting a v4a
- connection. A hostname is specified after the user ID string and the
- server connects to the address that hostname resolves to.
-
- @see: U{http://en.wikipedia.org/wiki/SOCKS#SOCKS_4a_protocol}
- """
- # send the domain name "localhost" to be resolved
- clientRequest = (
- struct.pack('!BBH', 4, 2, 34)
- + socket.inet_aton('0.0.0.1')
- + 'fooBAZ\0'
- + 'localhost\0')
-
- # Deliver the bytes one by one to exercise the protocol's buffering
- # logic. FakeResolverReactor's resolve method is invoked to "resolve"
- # the hostname.
- for byte in clientRequest:
- self.sock.dataReceived(byte)
-
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # Verify that the server responded with the address which will be
- # connected to.
- self.assertEqual(
- sent,
- struct.pack('!BBH', 0, 90, 1234) + socket.inet_aton('6.7.8.9'))
- self.assertFalse(self.sock.transport.stringTCPTransport_closing)
- self.assertNotIdentical(self.sock.driver_listen, None)
-
- # connect
- incoming = self.sock.driver_listen.buildProtocol(('127.0.0.1', 5345))
- self.assertNotIdentical(incoming, None)
- incoming.transport = StringTCPTransport()
- incoming.connectionMade()
-
- # now we should have the second reply packet
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 90, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assertNotIdentical(
- self.sock.transport.stringTCPTransport_closing, None)
-
- # Deliver some data from the output connection and verify it is
- # passed along to the incoming side.
- self.sock.dataReceived('hi there')
- self.assertEqual(incoming.transport.value(), 'hi there')
-
- # the other way around
- incoming.dataReceived('hi there')
- self.assertEqual(self.sock.transport.value(), 'hi there')
-
- self.sock.connectionLost('fake reason')
-
-
- def test_socks4aFailedResolution(self):
- """
- Failed hostname resolution on a SOCKSv4a packet results in a 91 error
- response and the connection getting closed.
- """
- # send the domain name "failinghost" to be resolved
- clientRequest = (
- struct.pack('!BBH', 4, 2, 34)
- + socket.inet_aton('0.0.0.1')
- + 'fooBAZ\0'
- + 'failinghost\0')
-
- # Deliver the bytes one by one to exercise the protocol's buffering
- # logic. FakeResolverReactor's resolve method is invoked to "resolve"
- # the hostname.
- for byte in clientRequest:
- self.sock.dataReceived(byte)
-
- # Verify that the server responds with a 91 error.
- sent = self.sock.transport.value()
- self.assertEqual(
- sent,
- struct.pack('!BBH', 0, 91, 0) + socket.inet_aton('0.0.0.0'))
-
- # A failed resolution causes the transport to drop the connection.
- self.assertTrue(self.sock.transport.stringTCPTransport_closing)
- self.assertIdentical(self.sock.driver_outgoing, None)
-
-
- def test_accessDenied(self):
- self.sock.authorize = lambda code, server, port, user: 0
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 2, 4242)
- + socket.inet_aton('10.2.3.4')
- + 'fooBAR'
- + '\0')
- self.assertEqual(self.sock.transport.value(),
- struct.pack('!BBH', 0, 91, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assert_(self.sock.transport.stringTCPTransport_closing)
- self.assertIdentical(self.sock.driver_listen, None)
-
- def test_eofRemote(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 2, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # connect
- incoming = self.sock.driver_listen.buildProtocol(('1.2.3.4', 5345))
- self.assertNotIdentical(incoming, None)
- incoming.transport = StringTCPTransport()
- incoming.connectionMade()
-
- # now we should have the second reply packet
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 90, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assert_(not self.sock.transport.stringTCPTransport_closing)
-
- # pass some data through
- self.sock.dataReceived('hello, world')
- self.assertEqual(incoming.transport.value(),
- 'hello, world')
-
- # now close it from the server side
- incoming.transport.loseConnection()
- incoming.connectionLost('fake reason')
-
- def test_eofLocal(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 2, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # connect
- incoming = self.sock.driver_listen.buildProtocol(('1.2.3.4', 5345))
- self.assertNotIdentical(incoming, None)
- incoming.transport = StringTCPTransport()
- incoming.connectionMade()
-
- # now we should have the second reply packet
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 90, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assert_(not self.sock.transport.stringTCPTransport_closing)
-
- # pass some data through
- self.sock.dataReceived('hello, world')
- self.assertEqual(incoming.transport.value(),
- 'hello, world')
-
- # now close it from the client side
- self.sock.connectionLost('fake reason')
-
- def test_badSource(self):
- self.sock.dataReceived(
- struct.pack('!BBH', 4, 2, 34)
- + socket.inet_aton('1.2.3.4')
- + 'fooBAR'
- + '\0')
- sent = self.sock.transport.value()
- self.sock.transport.clear()
-
- # connect from WRONG address
- incoming = self.sock.driver_listen.buildProtocol(('1.6.6.6', 666))
- self.assertIdentical(incoming, None)
-
- # Now we should have the second reply packet and it should
- # be a failure. The connection should be closing.
- sent = self.sock.transport.value()
- self.sock.transport.clear()
- self.assertEqual(sent,
- struct.pack('!BBH', 0, 91, 0)
- + socket.inet_aton('0.0.0.0'))
- self.assert_(self.sock.transport.stringTCPTransport_closing)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ssl.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ssl.py
deleted file mode 100755
index 6d1a3ec7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_ssl.py
+++ /dev/null
@@ -1,726 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for twisted SSL support.
-"""
-
-from twisted.trial import unittest
-from twisted.internet import protocol, reactor, interfaces, defer
-from twisted.internet.error import ConnectionDone
-from twisted.protocols import basic
-from twisted.python import util
-from twisted.python.runtime import platform
-from twisted.test.test_tcp import ProperlyCloseFilesMixin
-
-import os, errno
-
-try:
- from OpenSSL import SSL, crypto
- from twisted.internet import ssl
- from twisted.test.ssl_helpers import ClientTLSContext
-except ImportError:
- def _noSSL():
- # ugh, make pyflakes happy.
- global SSL
- global ssl
- SSL = ssl = None
- _noSSL()
-
-try:
- from twisted.protocols import tls as newTLS
-except ImportError:
- # Assuming SSL exists, we're using old version in reactor (i.e. non-protocol)
- newTLS = None
-
-certPath = util.sibpath(__file__, "server.pem")
-
-
-
-class UnintelligentProtocol(basic.LineReceiver):
- """
- @ivar deferred: a deferred that will fire at connection lost.
- @type deferred: L{defer.Deferred}
-
- @cvar pretext: text sent before TLS is set up.
- @type pretext: C{str}
-
- @cvar posttext: text sent after TLS is set up.
- @type posttext: C{str}
- """
- pretext = [
- "first line",
- "last thing before tls starts",
- "STARTTLS"]
-
- posttext = [
- "first thing after tls started",
- "last thing ever"]
-
- def __init__(self):
- self.deferred = defer.Deferred()
-
-
- def connectionMade(self):
- for l in self.pretext:
- self.sendLine(l)
-
-
- def lineReceived(self, line):
- if line == "READY":
- self.transport.startTLS(ClientTLSContext(), self.factory.client)
- for l in self.posttext:
- self.sendLine(l)
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- self.deferred.callback(None)
-
-
-
-class LineCollector(basic.LineReceiver):
- """
- @ivar deferred: a deferred that will fire at connection lost.
- @type deferred: L{defer.Deferred}
-
- @ivar doTLS: whether the protocol is initiate TLS or not.
- @type doTLS: C{bool}
-
- @ivar fillBuffer: if set to True, it will send lots of data once
- C{STARTTLS} is received.
- @type fillBuffer: C{bool}
- """
-
- def __init__(self, doTLS, fillBuffer=False):
- self.doTLS = doTLS
- self.fillBuffer = fillBuffer
- self.deferred = defer.Deferred()
-
-
- def connectionMade(self):
- self.factory.rawdata = ''
- self.factory.lines = []
-
-
- def lineReceived(self, line):
- self.factory.lines.append(line)
- if line == 'STARTTLS':
- if self.fillBuffer:
- for x in range(500):
- self.sendLine('X' * 1000)
- self.sendLine('READY')
- if self.doTLS:
- ctx = ServerTLSContext(
- privateKeyFileName=certPath,
- certificateFileName=certPath,
- )
- self.transport.startTLS(ctx, self.factory.server)
- else:
- self.setRawMode()
-
-
- def rawDataReceived(self, data):
- self.factory.rawdata += data
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- self.deferred.callback(None)
-
-
-
-class SingleLineServerProtocol(protocol.Protocol):
- """
- A protocol that sends a single line of data at C{connectionMade}.
- """
-
- def connectionMade(self):
- self.transport.write("+OK <some crap>\r\n")
- self.transport.getPeerCertificate()
-
-
-
-class RecordingClientProtocol(protocol.Protocol):
- """
- @ivar deferred: a deferred that will fire with first received content.
- @type deferred: L{defer.Deferred}
- """
-
- def __init__(self):
- self.deferred = defer.Deferred()
-
-
- def connectionMade(self):
- self.transport.getPeerCertificate()
-
-
- def dataReceived(self, data):
- self.deferred.callback(data)
-
-
-
-class ImmediatelyDisconnectingProtocol(protocol.Protocol):
- """
- A protocol that disconnect immediately on connection. It fires the
- C{connectionDisconnected} deferred of its factory on connetion lost.
- """
-
- def connectionMade(self):
- self.transport.loseConnection()
-
-
- def connectionLost(self, reason):
- self.factory.connectionDisconnected.callback(None)
-
-
-
-def generateCertificateObjects(organization, organizationalUnit):
- """
- Create a certificate for given C{organization} and C{organizationalUnit}.
-
- @return: a tuple of (key, request, certificate) objects.
- """
- pkey = crypto.PKey()
- pkey.generate_key(crypto.TYPE_RSA, 512)
- req = crypto.X509Req()
- subject = req.get_subject()
- subject.O = organization
- subject.OU = organizationalUnit
- req.set_pubkey(pkey)
- req.sign(pkey, "md5")
-
- # Here comes the actual certificate
- cert = crypto.X509()
- cert.set_serial_number(1)
- cert.gmtime_adj_notBefore(0)
- cert.gmtime_adj_notAfter(60) # Testing certificates need not be long lived
- cert.set_issuer(req.get_subject())
- cert.set_subject(req.get_subject())
- cert.set_pubkey(req.get_pubkey())
- cert.sign(pkey, "md5")
-
- return pkey, req, cert
-
-
-
-def generateCertificateFiles(basename, organization, organizationalUnit):
- """
- Create certificate files key, req and cert prefixed by C{basename} for
- given C{organization} and C{organizationalUnit}.
- """
- pkey, req, cert = generateCertificateObjects(organization, organizationalUnit)
-
- for ext, obj, dumpFunc in [
- ('key', pkey, crypto.dump_privatekey),
- ('req', req, crypto.dump_certificate_request),
- ('cert', cert, crypto.dump_certificate)]:
- fName = os.extsep.join((basename, ext))
- fObj = file(fName, 'w')
- fObj.write(dumpFunc(crypto.FILETYPE_PEM, obj))
- fObj.close()
-
-
-
-class ContextGeneratingMixin:
- """
- Offer methods to create L{ssl.DefaultOpenSSLContextFactory} for both client
- and server.
-
- @ivar clientBase: prefix of client certificate files.
- @type clientBase: C{str}
-
- @ivar serverBase: prefix of server certificate files.
- @type serverBase: C{str}
-
- @ivar clientCtxFactory: a generated context factory to be used in
- C{reactor.connectSSL}.
- @type clientCtxFactory: L{ssl.DefaultOpenSSLContextFactory}
-
- @ivar serverCtxFactory: a generated context factory to be used in
- C{reactor.listenSSL}.
- @type serverCtxFactory: L{ssl.DefaultOpenSSLContextFactory}
- """
-
- def makeContextFactory(self, org, orgUnit, *args, **kwArgs):
- base = self.mktemp()
- generateCertificateFiles(base, org, orgUnit)
- serverCtxFactory = ssl.DefaultOpenSSLContextFactory(
- os.extsep.join((base, 'key')),
- os.extsep.join((base, 'cert')),
- *args, **kwArgs)
-
- return base, serverCtxFactory
-
-
- def setupServerAndClient(self, clientArgs, clientKwArgs, serverArgs,
- serverKwArgs):
- self.clientBase, self.clientCtxFactory = self.makeContextFactory(
- *clientArgs, **clientKwArgs)
- self.serverBase, self.serverCtxFactory = self.makeContextFactory(
- *serverArgs, **serverKwArgs)
-
-
-
-if SSL is not None:
- class ServerTLSContext(ssl.DefaultOpenSSLContextFactory):
- """
- A context factory with a default method set to L{SSL.TLSv1_METHOD}.
- """
- isClient = False
-
- def __init__(self, *args, **kw):
- kw['sslmethod'] = SSL.TLSv1_METHOD
- ssl.DefaultOpenSSLContextFactory.__init__(self, *args, **kw)
-
-
-
-class StolenTCPTestCase(ProperlyCloseFilesMixin, unittest.TestCase):
- """
- For SSL transports, test many of the same things which are tested for
- TCP transports.
- """
-
- def createServer(self, address, portNumber, factory):
- """
- Create an SSL server with a certificate using L{IReactorSSL.listenSSL}.
- """
- cert = ssl.PrivateCertificate.loadPEM(file(certPath).read())
- contextFactory = cert.options()
- return reactor.listenSSL(
- portNumber, factory, contextFactory, interface=address)
-
-
- def connectClient(self, address, portNumber, clientCreator):
- """
- Create an SSL client using L{IReactorSSL.connectSSL}.
- """
- contextFactory = ssl.CertificateOptions()
- return clientCreator.connectSSL(address, portNumber, contextFactory)
-
-
- def getHandleExceptionType(self):
- """
- Return L{SSL.Error} as the expected error type which will be raised by
- a write to the L{OpenSSL.SSL.Connection} object after it has been
- closed.
- """
- return SSL.Error
-
-
- def getHandleErrorCode(self):
- """
- Return the argument L{SSL.Error} will be constructed with for this
- case. This is basically just a random OpenSSL implementation detail.
- It would be better if this test worked in a way which did not require
- this.
- """
- # Windows 2000 SP 4 and Windows XP SP 2 give back WSAENOTSOCK for
- # SSL.Connection.write for some reason. The twisted.protocols.tls
- # implementation of IReactorSSL doesn't suffer from this imprecation,
- # though, since it is isolated from the Windows I/O layer (I suppose?).
-
- # If test_properlyCloseFiles waited for the SSL handshake to complete
- # and performed an orderly shutdown, then this would probably be a
- # little less weird: writing to a shutdown SSL connection has a more
- # well-defined failure mode (or at least it should).
-
- # So figure out if twisted.protocols.tls is in use. If it can be
- # imported, it should be.
- try:
- import twisted.protocols.tls
- except ImportError:
- # It isn't available, so we expect WSAENOTSOCK if we're on Windows.
- if platform.getType() == 'win32':
- return errno.WSAENOTSOCK
-
- # Otherwise, we expect an error about how we tried to write to a
- # shutdown connection. This is terribly implementation-specific.
- return [('SSL routines', 'SSL_write', 'protocol is shutdown')]
-
-
-
-class TLSTestCase(unittest.TestCase):
- """
- Tests for startTLS support.
-
- @ivar fillBuffer: forwarded to L{LineCollector.fillBuffer}
- @type fillBuffer: C{bool}
- """
- fillBuffer = False
-
- clientProto = None
- serverProto = None
-
-
- def tearDown(self):
- if self.clientProto.transport is not None:
- self.clientProto.transport.loseConnection()
- if self.serverProto.transport is not None:
- self.serverProto.transport.loseConnection()
-
-
- def _runTest(self, clientProto, serverProto, clientIsServer=False):
- """
- Helper method to run TLS tests.
-
- @param clientProto: protocol instance attached to the client
- connection.
- @param serverProto: protocol instance attached to the server
- connection.
- @param clientIsServer: flag indicated if client should initiate
- startTLS instead of server.
-
- @return: a L{defer.Deferred} that will fire when both connections are
- lost.
- """
- self.clientProto = clientProto
- cf = self.clientFactory = protocol.ClientFactory()
- cf.protocol = lambda: clientProto
- if clientIsServer:
- cf.server = False
- else:
- cf.client = True
-
- self.serverProto = serverProto
- sf = self.serverFactory = protocol.ServerFactory()
- sf.protocol = lambda: serverProto
- if clientIsServer:
- sf.client = False
- else:
- sf.server = True
-
- port = reactor.listenTCP(0, sf, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
-
- reactor.connectTCP('127.0.0.1', port.getHost().port, cf)
-
- return defer.gatherResults([clientProto.deferred, serverProto.deferred])
-
-
- def test_TLS(self):
- """
- Test for server and client startTLS: client should received data both
- before and after the startTLS.
- """
- def check(ignore):
- self.assertEqual(
- self.serverFactory.lines,
- UnintelligentProtocol.pretext + UnintelligentProtocol.posttext
- )
- d = self._runTest(UnintelligentProtocol(),
- LineCollector(True, self.fillBuffer))
- return d.addCallback(check)
-
-
- def test_unTLS(self):
- """
- Test for server startTLS not followed by a startTLS in client: the data
- received after server startTLS should be received as raw.
- """
- def check(ignored):
- self.assertEqual(
- self.serverFactory.lines,
- UnintelligentProtocol.pretext
- )
- self.failUnless(self.serverFactory.rawdata,
- "No encrypted bytes received")
- d = self._runTest(UnintelligentProtocol(),
- LineCollector(False, self.fillBuffer))
- return d.addCallback(check)
-
-
- def test_backwardsTLS(self):
- """
- Test startTLS first initiated by client.
- """
- def check(ignored):
- self.assertEqual(
- self.clientFactory.lines,
- UnintelligentProtocol.pretext + UnintelligentProtocol.posttext
- )
- d = self._runTest(LineCollector(True, self.fillBuffer),
- UnintelligentProtocol(), True)
- return d.addCallback(check)
-
-
-
-class SpammyTLSTestCase(TLSTestCase):
- """
- Test TLS features with bytes sitting in the out buffer.
- """
- fillBuffer = True
-
-
-
-class BufferingTestCase(unittest.TestCase):
- serverProto = None
- clientProto = None
-
-
- def tearDown(self):
- if self.serverProto.transport is not None:
- self.serverProto.transport.loseConnection()
- if self.clientProto.transport is not None:
- self.clientProto.transport.loseConnection()
-
-
- def test_openSSLBuffering(self):
- serverProto = self.serverProto = SingleLineServerProtocol()
- clientProto = self.clientProto = RecordingClientProtocol()
-
- server = protocol.ServerFactory()
- client = self.client = protocol.ClientFactory()
-
- server.protocol = lambda: serverProto
- client.protocol = lambda: clientProto
-
- sCTX = ssl.DefaultOpenSSLContextFactory(certPath, certPath)
- cCTX = ssl.ClientContextFactory()
-
- port = reactor.listenSSL(0, server, sCTX, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
-
- reactor.connectSSL('127.0.0.1', port.getHost().port, client, cCTX)
-
- return clientProto.deferred.addCallback(
- self.assertEqual, "+OK <some crap>\r\n")
-
-
-
-class ConnectionLostTestCase(unittest.TestCase, ContextGeneratingMixin):
- """
- SSL connection closing tests.
- """
-
- def testImmediateDisconnect(self):
- org = "twisted.test.test_ssl"
- self.setupServerAndClient(
- (org, org + ", client"), {},
- (org, org + ", server"), {})
-
- # Set up a server, connect to it with a client, which should work since our verifiers
- # allow anything, then disconnect.
- serverProtocolFactory = protocol.ServerFactory()
- serverProtocolFactory.protocol = protocol.Protocol
- self.serverPort = serverPort = reactor.listenSSL(0,
- serverProtocolFactory, self.serverCtxFactory)
-
- clientProtocolFactory = protocol.ClientFactory()
- clientProtocolFactory.protocol = ImmediatelyDisconnectingProtocol
- clientProtocolFactory.connectionDisconnected = defer.Deferred()
- clientConnector = reactor.connectSSL('127.0.0.1',
- serverPort.getHost().port, clientProtocolFactory, self.clientCtxFactory)
-
- return clientProtocolFactory.connectionDisconnected.addCallback(
- lambda ignoredResult: self.serverPort.stopListening())
-
-
- def test_bothSidesLoseConnection(self):
- """
- Both sides of SSL connection close connection; the connections should
- close cleanly, and only after the underlying TCP connection has
- disconnected.
- """
- class CloseAfterHandshake(protocol.Protocol):
- def __init__(self):
- self.done = defer.Deferred()
-
- def connectionMade(self):
- self.transport.write("a")
-
- def dataReceived(self, data):
- # If we got data, handshake is over:
- self.transport.loseConnection()
-
- def connectionLost(self2, reason):
- self2.done.errback(reason)
- del self2.done
-
- org = "twisted.test.test_ssl"
- self.setupServerAndClient(
- (org, org + ", client"), {},
- (org, org + ", server"), {})
-
- serverProtocol = CloseAfterHandshake()
- serverProtocolFactory = protocol.ServerFactory()
- serverProtocolFactory.protocol = lambda: serverProtocol
- serverPort = reactor.listenSSL(0,
- serverProtocolFactory, self.serverCtxFactory)
- self.addCleanup(serverPort.stopListening)
-
- clientProtocol = CloseAfterHandshake()
- clientProtocolFactory = protocol.ClientFactory()
- clientProtocolFactory.protocol = lambda: clientProtocol
- clientConnector = reactor.connectSSL('127.0.0.1',
- serverPort.getHost().port, clientProtocolFactory, self.clientCtxFactory)
-
- def checkResult(failure):
- failure.trap(ConnectionDone)
- return defer.gatherResults(
- [clientProtocol.done.addErrback(checkResult),
- serverProtocol.done.addErrback(checkResult)])
-
- if newTLS is None:
- test_bothSidesLoseConnection.skip = "Old SSL code doesn't always close cleanly."
-
-
- def testFailedVerify(self):
- org = "twisted.test.test_ssl"
- self.setupServerAndClient(
- (org, org + ", client"), {},
- (org, org + ", server"), {})
-
- def verify(*a):
- return False
- self.clientCtxFactory.getContext().set_verify(SSL.VERIFY_PEER, verify)
-
- serverConnLost = defer.Deferred()
- serverProtocol = protocol.Protocol()
- serverProtocol.connectionLost = serverConnLost.callback
- serverProtocolFactory = protocol.ServerFactory()
- serverProtocolFactory.protocol = lambda: serverProtocol
- self.serverPort = serverPort = reactor.listenSSL(0,
- serverProtocolFactory, self.serverCtxFactory)
-
- clientConnLost = defer.Deferred()
- clientProtocol = protocol.Protocol()
- clientProtocol.connectionLost = clientConnLost.callback
- clientProtocolFactory = protocol.ClientFactory()
- clientProtocolFactory.protocol = lambda: clientProtocol
- clientConnector = reactor.connectSSL('127.0.0.1',
- serverPort.getHost().port, clientProtocolFactory, self.clientCtxFactory)
-
- dl = defer.DeferredList([serverConnLost, clientConnLost], consumeErrors=True)
- return dl.addCallback(self._cbLostConns)
-
-
- def _cbLostConns(self, results):
- (sSuccess, sResult), (cSuccess, cResult) = results
-
- self.failIf(sSuccess)
- self.failIf(cSuccess)
-
- acceptableErrors = [SSL.Error]
-
- # Rather than getting a verification failure on Windows, we are getting
- # a connection failure. Without something like sslverify proxying
- # in-between we can't fix up the platform's errors, so let's just
- # specifically say it is only OK in this one case to keep the tests
- # passing. Normally we'd like to be as strict as possible here, so
- # we're not going to allow this to report errors incorrectly on any
- # other platforms.
-
- if platform.isWindows():
- from twisted.internet.error import ConnectionLost
- acceptableErrors.append(ConnectionLost)
-
- sResult.trap(*acceptableErrors)
- cResult.trap(*acceptableErrors)
-
- return self.serverPort.stopListening()
-
-
-
-class FakeContext:
- """
- L{OpenSSL.SSL.Context} double which can more easily be inspected.
- """
- def __init__(self, method):
- self._method = method
- self._options = 0
-
-
- def set_options(self, options):
- self._options |= options
-
-
- def use_certificate_file(self, fileName):
- pass
-
-
- def use_privatekey_file(self, fileName):
- pass
-
-
-
-class DefaultOpenSSLContextFactoryTests(unittest.TestCase):
- """
- Tests for L{ssl.DefaultOpenSSLContextFactory}.
- """
- def setUp(self):
- # pyOpenSSL Context objects aren't introspectable enough. Pass in
- # an alternate context factory so we can inspect what is done to it.
- self.contextFactory = ssl.DefaultOpenSSLContextFactory(
- certPath, certPath, _contextFactory=FakeContext)
- self.context = self.contextFactory.getContext()
-
-
- def test_method(self):
- """
- L{ssl.DefaultOpenSSLContextFactory.getContext} returns an SSL context
- which can use SSLv3 or TLSv1 but not SSLv2.
- """
- # SSLv23_METHOD allows SSLv2, SSLv3, or TLSv1
- self.assertEqual(self.context._method, SSL.SSLv23_METHOD)
-
- # And OP_NO_SSLv2 disables the SSLv2 support.
- self.assertTrue(self.context._options & SSL.OP_NO_SSLv2)
-
- # Make sure SSLv3 and TLSv1 aren't disabled though.
- self.assertFalse(self.context._options & SSL.OP_NO_SSLv3)
- self.assertFalse(self.context._options & SSL.OP_NO_TLSv1)
-
-
- def test_missingCertificateFile(self):
- """
- Instantiating L{ssl.DefaultOpenSSLContextFactory} with a certificate
- filename which does not identify an existing file results in the
- initializer raising L{OpenSSL.SSL.Error}.
- """
- self.assertRaises(
- SSL.Error,
- ssl.DefaultOpenSSLContextFactory, certPath, self.mktemp())
-
-
- def test_missingPrivateKeyFile(self):
- """
- Instantiating L{ssl.DefaultOpenSSLContextFactory} with a private key
- filename which does not identify an existing file results in the
- initializer raising L{OpenSSL.SSL.Error}.
- """
- self.assertRaises(
- SSL.Error,
- ssl.DefaultOpenSSLContextFactory, self.mktemp(), certPath)
-
-
-
-class ClientContextFactoryTests(unittest.TestCase):
- """
- Tests for L{ssl.ClientContextFactory}.
- """
- def setUp(self):
- self.contextFactory = ssl.ClientContextFactory()
- self.contextFactory._contextFactory = FakeContext
- self.context = self.contextFactory.getContext()
-
-
- def test_method(self):
- """
- L{ssl.ClientContextFactory.getContext} returns a context which can use
- SSLv3 or TLSv1 but not SSLv2.
- """
- self.assertEqual(self.context._method, SSL.SSLv23_METHOD)
- self.assertTrue(self.context._options & SSL.OP_NO_SSLv2)
- self.assertFalse(self.context._options & SSL.OP_NO_SSLv3)
- self.assertFalse(self.context._options & SSL.OP_NO_TLSv1)
-
-
-
-if interfaces.IReactorSSL(reactor, None) is None:
- for tCase in [StolenTCPTestCase, TLSTestCase, SpammyTLSTestCase,
- BufferingTestCase, ConnectionLostTestCase,
- DefaultOpenSSLContextFactoryTests,
- ClientContextFactoryTests]:
- tCase.skip = "Reactor does not support SSL, cannot run SSL tests"
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sslverify.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sslverify.py
deleted file mode 100755
index ac9eaa85..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_sslverify.py
+++ /dev/null
@@ -1,558 +0,0 @@
-# Copyright 2005 Divmod, Inc. See LICENSE file for details
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet._sslverify}.
-"""
-
-import itertools
-
-try:
- from OpenSSL import SSL
- from OpenSSL.crypto import PKey, X509, X509Req
- from OpenSSL.crypto import TYPE_RSA
- from twisted.internet import _sslverify as sslverify
-except ImportError:
- pass
-
-from twisted.trial import unittest
-from twisted.internet import protocol, defer, reactor
-from twisted.python.reflect import objgrep, isSame
-from twisted.python import log
-
-from twisted.internet.error import CertificateError, ConnectionLost
-from twisted.internet import interfaces
-
-
-# A couple of static PEM-format certificates to be used by various tests.
-A_HOST_CERTIFICATE_PEM = """
------BEGIN CERTIFICATE-----
- MIIC2jCCAkMCAjA5MA0GCSqGSIb3DQEBBAUAMIG0MQswCQYDVQQGEwJVUzEiMCAG
- A1UEAxMZZXhhbXBsZS50d2lzdGVkbWF0cml4LmNvbTEPMA0GA1UEBxMGQm9zdG9u
- MRwwGgYDVQQKExNUd2lzdGVkIE1hdHJpeCBMYWJzMRYwFAYDVQQIEw1NYXNzYWNo
- dXNldHRzMScwJQYJKoZIhvcNAQkBFhhub2JvZHlAdHdpc3RlZG1hdHJpeC5jb20x
- ETAPBgNVBAsTCFNlY3VyaXR5MB4XDTA2MDgxNjAxMDEwOFoXDTA3MDgxNjAxMDEw
- OFowgbQxCzAJBgNVBAYTAlVTMSIwIAYDVQQDExlleGFtcGxlLnR3aXN0ZWRtYXRy
- aXguY29tMQ8wDQYDVQQHEwZCb3N0b24xHDAaBgNVBAoTE1R3aXN0ZWQgTWF0cml4
- IExhYnMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxJzAlBgkqhkiG9w0BCQEWGG5v
- Ym9keUB0d2lzdGVkbWF0cml4LmNvbTERMA8GA1UECxMIU2VjdXJpdHkwgZ8wDQYJ
- KoZIhvcNAQEBBQADgY0AMIGJAoGBAMzH8CDF/U91y/bdbdbJKnLgnyvQ9Ig9ZNZp
- 8hpsu4huil60zF03+Lexg2l1FIfURScjBuaJMR6HiMYTMjhzLuByRZ17KW4wYkGi
- KXstz03VIKy4Tjc+v4aXFI4XdRw10gGMGQlGGscXF/RSoN84VoDKBfOMWdXeConJ
- VyC4w3iJAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAviMT4lBoxOgQy32LIgZ4lVCj
- JNOiZYg8GMQ6y0ugp86X80UjOvkGtNf/R7YgED/giKRN/q/XJiLJDEhzknkocwmO
- S+4b2XpiaZYxRyKWwL221O7CGmtWYyZl2+92YYmmCiNzWQPfP6BOMlfax0AGLHls
- fXzCWdG0O/3Lk2SRM0I=
------END CERTIFICATE-----
-"""
-
-A_PEER_CERTIFICATE_PEM = """
------BEGIN CERTIFICATE-----
- MIIC3jCCAkcCAjA6MA0GCSqGSIb3DQEBBAUAMIG2MQswCQYDVQQGEwJVUzEiMCAG
- A1UEAxMZZXhhbXBsZS50d2lzdGVkbWF0cml4LmNvbTEPMA0GA1UEBxMGQm9zdG9u
- MRwwGgYDVQQKExNUd2lzdGVkIE1hdHJpeCBMYWJzMRYwFAYDVQQIEw1NYXNzYWNo
- dXNldHRzMSkwJwYJKoZIhvcNAQkBFhpzb21lYm9keUB0d2lzdGVkbWF0cml4LmNv
- bTERMA8GA1UECxMIU2VjdXJpdHkwHhcNMDYwODE2MDEwMTU2WhcNMDcwODE2MDEw
- MTU2WjCBtjELMAkGA1UEBhMCVVMxIjAgBgNVBAMTGWV4YW1wbGUudHdpc3RlZG1h
- dHJpeC5jb20xDzANBgNVBAcTBkJvc3RvbjEcMBoGA1UEChMTVHdpc3RlZCBNYXRy
- aXggTGFiczEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czEpMCcGCSqGSIb3DQEJARYa
- c29tZWJvZHlAdHdpc3RlZG1hdHJpeC5jb20xETAPBgNVBAsTCFNlY3VyaXR5MIGf
- MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnm+WBlgFNbMlHehib9ePGGDXF+Nz4
- CjGuUmVBaXCRCiVjg3kSDecwqfb0fqTksBZ+oQ1UBjMcSh7OcvFXJZnUesBikGWE
- JE4V8Bjh+RmbJ1ZAlUPZ40bAkww0OpyIRAGMvKG+4yLFTO4WDxKmfDcrOb6ID8WJ
- e1u+i3XGkIf/5QIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAD4Oukm3YYkhedUepBEA
- vvXIQhVDqL7mk6OqYdXmNj6R7ZMC8WWvGZxrzDI1bZuB+4aIxxd1FXC3UOHiR/xg
- i9cDl1y8P/qRp4aEBNF6rI0D4AxTbfnHQx4ERDAOShJdYZs/2zifPJ6va6YvrEyr
- yqDtGhklsWW3ZwBzEh5VEOUp
------END CERTIFICATE-----
-"""
-
-
-
-counter = itertools.count().next
-def makeCertificate(**kw):
- keypair = PKey()
- keypair.generate_key(TYPE_RSA, 512)
-
- certificate = X509()
- certificate.gmtime_adj_notBefore(0)
- certificate.gmtime_adj_notAfter(60 * 60 * 24 * 365) # One year
- for xname in certificate.get_issuer(), certificate.get_subject():
- for (k, v) in kw.items():
- setattr(xname, k, v)
-
- certificate.set_serial_number(counter())
- certificate.set_pubkey(keypair)
- certificate.sign(keypair, "md5")
-
- return keypair, certificate
-
-
-
-class DataCallbackProtocol(protocol.Protocol):
- def dataReceived(self, data):
- d, self.factory.onData = self.factory.onData, None
- if d is not None:
- d.callback(data)
-
- def connectionLost(self, reason):
- d, self.factory.onLost = self.factory.onLost, None
- if d is not None:
- d.errback(reason)
-
-class WritingProtocol(protocol.Protocol):
- byte = 'x'
- def connectionMade(self):
- self.transport.write(self.byte)
-
- def connectionLost(self, reason):
- self.factory.onLost.errback(reason)
-
-
-class OpenSSLOptions(unittest.TestCase):
- serverPort = clientConn = None
- onServerLost = onClientLost = None
-
- sKey = None
- sCert = None
- cKey = None
- cCert = None
-
- def setUp(self):
- """
- Create class variables of client and server certificates.
- """
- self.sKey, self.sCert = makeCertificate(
- O="Server Test Certificate",
- CN="server")
- self.cKey, self.cCert = makeCertificate(
- O="Client Test Certificate",
- CN="client")
-
- def tearDown(self):
- if self.serverPort is not None:
- self.serverPort.stopListening()
- if self.clientConn is not None:
- self.clientConn.disconnect()
-
- L = []
- if self.onServerLost is not None:
- L.append(self.onServerLost)
- if self.onClientLost is not None:
- L.append(self.onClientLost)
-
- return defer.DeferredList(L, consumeErrors=True)
-
- def loopback(self, serverCertOpts, clientCertOpts,
- onServerLost=None, onClientLost=None, onData=None):
- if onServerLost is None:
- self.onServerLost = onServerLost = defer.Deferred()
- if onClientLost is None:
- self.onClientLost = onClientLost = defer.Deferred()
- if onData is None:
- onData = defer.Deferred()
-
- serverFactory = protocol.ServerFactory()
- serverFactory.protocol = DataCallbackProtocol
- serverFactory.onLost = onServerLost
- serverFactory.onData = onData
-
- clientFactory = protocol.ClientFactory()
- clientFactory.protocol = WritingProtocol
- clientFactory.onLost = onClientLost
-
- self.serverPort = reactor.listenSSL(0, serverFactory, serverCertOpts)
- self.clientConn = reactor.connectSSL('127.0.0.1',
- self.serverPort.getHost().port, clientFactory, clientCertOpts)
-
- def test_abbreviatingDistinguishedNames(self):
- """
- Check that abbreviations used in certificates correctly map to
- complete names.
- """
- self.assertEqual(
- sslverify.DN(CN='a', OU='hello'),
- sslverify.DistinguishedName(commonName='a',
- organizationalUnitName='hello'))
- self.assertNotEquals(
- sslverify.DN(CN='a', OU='hello'),
- sslverify.DN(CN='a', OU='hello', emailAddress='xxx'))
- dn = sslverify.DN(CN='abcdefg')
- self.assertRaises(AttributeError, setattr, dn, 'Cn', 'x')
- self.assertEqual(dn.CN, dn.commonName)
- dn.CN = 'bcdefga'
- self.assertEqual(dn.CN, dn.commonName)
-
-
- def testInspectDistinguishedName(self):
- n = sslverify.DN(commonName='common name',
- organizationName='organization name',
- organizationalUnitName='organizational unit name',
- localityName='locality name',
- stateOrProvinceName='state or province name',
- countryName='country name',
- emailAddress='email address')
- s = n.inspect()
- for k in [
- 'common name',
- 'organization name',
- 'organizational unit name',
- 'locality name',
- 'state or province name',
- 'country name',
- 'email address']:
- self.assertIn(k, s, "%r was not in inspect output." % (k,))
- self.assertIn(k.title(), s, "%r was not in inspect output." % (k,))
-
-
- def testInspectDistinguishedNameWithoutAllFields(self):
- n = sslverify.DN(localityName='locality name')
- s = n.inspect()
- for k in [
- 'common name',
- 'organization name',
- 'organizational unit name',
- 'state or province name',
- 'country name',
- 'email address']:
- self.assertNotIn(k, s, "%r was in inspect output." % (k,))
- self.assertNotIn(k.title(), s, "%r was in inspect output." % (k,))
- self.assertIn('locality name', s)
- self.assertIn('Locality Name', s)
-
-
- def test_inspectCertificate(self):
- """
- Test that the C{inspect} method of L{sslverify.Certificate} returns
- a human-readable string containing some basic information about the
- certificate.
- """
- c = sslverify.Certificate.loadPEM(A_HOST_CERTIFICATE_PEM)
- self.assertEqual(
- c.inspect().split('\n'),
- ["Certificate For Subject:",
- " Common Name: example.twistedmatrix.com",
- " Country Name: US",
- " Email Address: nobody@twistedmatrix.com",
- " Locality Name: Boston",
- " Organization Name: Twisted Matrix Labs",
- " Organizational Unit Name: Security",
- " State Or Province Name: Massachusetts",
- "",
- "Issuer:",
- " Common Name: example.twistedmatrix.com",
- " Country Name: US",
- " Email Address: nobody@twistedmatrix.com",
- " Locality Name: Boston",
- " Organization Name: Twisted Matrix Labs",
- " Organizational Unit Name: Security",
- " State Or Province Name: Massachusetts",
- "",
- "Serial Number: 12345",
- "Digest: C4:96:11:00:30:C3:EC:EE:A3:55:AA:ED:8C:84:85:18",
- "Public Key with Hash: ff33994c80812aa95a79cdb85362d054"])
-
-
- def test_certificateOptionsSerialization(self):
- """
- Test that __setstate__(__getstate__()) round-trips properly.
- """
- firstOpts = sslverify.OpenSSLCertificateOptions(
- privateKey=self.sKey,
- certificate=self.sCert,
- method=SSL.SSLv3_METHOD,
- verify=True,
- caCerts=[self.sCert],
- verifyDepth=2,
- requireCertificate=False,
- verifyOnce=False,
- enableSingleUseKeys=False,
- enableSessions=False,
- fixBrokenPeers=True,
- enableSessionTickets=True)
- context = firstOpts.getContext()
- state = firstOpts.__getstate__()
-
- # The context shouldn't be in the state to serialize
- self.failIf(objgrep(state, context, isSame),
- objgrep(state, context, isSame))
-
- opts = sslverify.OpenSSLCertificateOptions()
- opts.__setstate__(state)
- self.assertEqual(opts.privateKey, self.sKey)
- self.assertEqual(opts.certificate, self.sCert)
- self.assertEqual(opts.method, SSL.SSLv3_METHOD)
- self.assertEqual(opts.verify, True)
- self.assertEqual(opts.caCerts, [self.sCert])
- self.assertEqual(opts.verifyDepth, 2)
- self.assertEqual(opts.requireCertificate, False)
- self.assertEqual(opts.verifyOnce, False)
- self.assertEqual(opts.enableSingleUseKeys, False)
- self.assertEqual(opts.enableSessions, False)
- self.assertEqual(opts.fixBrokenPeers, True)
- self.assertEqual(opts.enableSessionTickets, True)
-
-
- def test_certificateOptionsSessionTickets(self):
- """
- Enabling session tickets should not set the OP_NO_TICKET option.
- """
- opts = sslverify.OpenSSLCertificateOptions(enableSessionTickets=True)
- ctx = opts.getContext()
- self.assertEqual(0, ctx.set_options(0) & 0x00004000)
-
-
- def test_certificateOptionsSessionTicketsDisabled(self):
- """
- Enabling session tickets should set the OP_NO_TICKET option.
- """
- opts = sslverify.OpenSSLCertificateOptions(enableSessionTickets=False)
- ctx = opts.getContext()
- self.assertEqual(0x00004000, ctx.set_options(0) & 0x00004000)
-
-
- def test_allowedAnonymousClientConnection(self):
- """
- Check that anonymous connections are allowed when certificates aren't
- required on the server.
- """
- onData = defer.Deferred()
- self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey,
- certificate=self.sCert, requireCertificate=False),
- sslverify.OpenSSLCertificateOptions(
- requireCertificate=False),
- onData=onData)
-
- return onData.addCallback(
- lambda result: self.assertEqual(result, WritingProtocol.byte))
-
- def test_refusedAnonymousClientConnection(self):
- """
- Check that anonymous connections are refused when certificates are
- required on the server.
- """
- onServerLost = defer.Deferred()
- onClientLost = defer.Deferred()
- self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey,
- certificate=self.sCert, verify=True,
- caCerts=[self.sCert], requireCertificate=True),
- sslverify.OpenSSLCertificateOptions(
- requireCertificate=False),
- onServerLost=onServerLost,
- onClientLost=onClientLost)
-
- d = defer.DeferredList([onClientLost, onServerLost],
- consumeErrors=True)
-
-
- def afterLost(((cSuccess, cResult), (sSuccess, sResult))):
-
- self.failIf(cSuccess)
- self.failIf(sSuccess)
- # Win32 fails to report the SSL Error, and report a connection lost
- # instead: there is a race condition so that's not totally
- # surprising (see ticket #2877 in the tracker)
- self.assertIsInstance(cResult.value, (SSL.Error, ConnectionLost))
- self.assertIsInstance(sResult.value, SSL.Error)
-
- return d.addCallback(afterLost)
-
- def test_failedCertificateVerification(self):
- """
- Check that connecting with a certificate not accepted by the server CA
- fails.
- """
- onServerLost = defer.Deferred()
- onClientLost = defer.Deferred()
- self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey,
- certificate=self.sCert, verify=False,
- requireCertificate=False),
- sslverify.OpenSSLCertificateOptions(verify=True,
- requireCertificate=False, caCerts=[self.cCert]),
- onServerLost=onServerLost,
- onClientLost=onClientLost)
-
- d = defer.DeferredList([onClientLost, onServerLost],
- consumeErrors=True)
- def afterLost(((cSuccess, cResult), (sSuccess, sResult))):
-
- self.failIf(cSuccess)
- self.failIf(sSuccess)
-
- return d.addCallback(afterLost)
-
- def test_successfulCertificateVerification(self):
- """
- Test a successful connection with client certificate validation on
- server side.
- """
- onData = defer.Deferred()
- self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey,
- certificate=self.sCert, verify=False,
- requireCertificate=False),
- sslverify.OpenSSLCertificateOptions(verify=True,
- requireCertificate=True, caCerts=[self.sCert]),
- onData=onData)
-
- return onData.addCallback(
- lambda result: self.assertEqual(result, WritingProtocol.byte))
-
- def test_successfulSymmetricSelfSignedCertificateVerification(self):
- """
- Test a successful connection with validation on both server and client
- sides.
- """
- onData = defer.Deferred()
- self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey,
- certificate=self.sCert, verify=True,
- requireCertificate=True, caCerts=[self.cCert]),
- sslverify.OpenSSLCertificateOptions(privateKey=self.cKey,
- certificate=self.cCert, verify=True,
- requireCertificate=True, caCerts=[self.sCert]),
- onData=onData)
-
- return onData.addCallback(
- lambda result: self.assertEqual(result, WritingProtocol.byte))
-
- def test_verification(self):
- """
- Check certificates verification building custom certificates data.
- """
- clientDN = sslverify.DistinguishedName(commonName='client')
- clientKey = sslverify.KeyPair.generate()
- clientCertReq = clientKey.certificateRequest(clientDN)
-
- serverDN = sslverify.DistinguishedName(commonName='server')
- serverKey = sslverify.KeyPair.generate()
- serverCertReq = serverKey.certificateRequest(serverDN)
-
- clientSelfCertReq = clientKey.certificateRequest(clientDN)
- clientSelfCertData = clientKey.signCertificateRequest(
- clientDN, clientSelfCertReq, lambda dn: True, 132)
- clientSelfCert = clientKey.newCertificate(clientSelfCertData)
-
- serverSelfCertReq = serverKey.certificateRequest(serverDN)
- serverSelfCertData = serverKey.signCertificateRequest(
- serverDN, serverSelfCertReq, lambda dn: True, 516)
- serverSelfCert = serverKey.newCertificate(serverSelfCertData)
-
- clientCertData = serverKey.signCertificateRequest(
- serverDN, clientCertReq, lambda dn: True, 7)
- clientCert = clientKey.newCertificate(clientCertData)
-
- serverCertData = clientKey.signCertificateRequest(
- clientDN, serverCertReq, lambda dn: True, 42)
- serverCert = serverKey.newCertificate(serverCertData)
-
- onData = defer.Deferred()
-
- serverOpts = serverCert.options(serverSelfCert)
- clientOpts = clientCert.options(clientSelfCert)
-
- self.loopback(serverOpts,
- clientOpts,
- onData=onData)
-
- return onData.addCallback(
- lambda result: self.assertEqual(result, WritingProtocol.byte))
-
-
-
-if interfaces.IReactorSSL(reactor, None) is None:
- OpenSSLOptions.skip = "Reactor does not support SSL, cannot run SSL tests"
-
-
-
-class _NotSSLTransport:
- def getHandle(self):
- return self
-
-class _MaybeSSLTransport:
- def getHandle(self):
- return self
-
- def get_peer_certificate(self):
- return None
-
- def get_host_certificate(self):
- return None
-
-
-class _ActualSSLTransport:
- def getHandle(self):
- return self
-
- def get_host_certificate(self):
- return sslverify.Certificate.loadPEM(A_HOST_CERTIFICATE_PEM).original
-
- def get_peer_certificate(self):
- return sslverify.Certificate.loadPEM(A_PEER_CERTIFICATE_PEM).original
-
-
-class Constructors(unittest.TestCase):
- def test_peerFromNonSSLTransport(self):
- """
- Verify that peerFromTransport raises an exception if the transport
- passed is not actually an SSL transport.
- """
- x = self.assertRaises(CertificateError,
- sslverify.Certificate.peerFromTransport,
- _NotSSLTransport())
- self.failUnless(str(x).startswith("non-TLS"))
-
- def test_peerFromBlankSSLTransport(self):
- """
- Verify that peerFromTransport raises an exception if the transport
- passed is an SSL transport, but doesn't have a peer certificate.
- """
- x = self.assertRaises(CertificateError,
- sslverify.Certificate.peerFromTransport,
- _MaybeSSLTransport())
- self.failUnless(str(x).startswith("TLS"))
-
- def test_hostFromNonSSLTransport(self):
- """
- Verify that hostFromTransport raises an exception if the transport
- passed is not actually an SSL transport.
- """
- x = self.assertRaises(CertificateError,
- sslverify.Certificate.hostFromTransport,
- _NotSSLTransport())
- self.failUnless(str(x).startswith("non-TLS"))
-
- def test_hostFromBlankSSLTransport(self):
- """
- Verify that hostFromTransport raises an exception if the transport
- passed is an SSL transport, but doesn't have a host certificate.
- """
- x = self.assertRaises(CertificateError,
- sslverify.Certificate.hostFromTransport,
- _MaybeSSLTransport())
- self.failUnless(str(x).startswith("TLS"))
-
-
- def test_hostFromSSLTransport(self):
- """
- Verify that hostFromTransport successfully creates the correct
- certificate if passed a valid SSL transport.
- """
- self.assertEqual(
- sslverify.Certificate.hostFromTransport(
- _ActualSSLTransport()).serialNumber(),
- 12345)
-
- def test_peerFromSSLTransport(self):
- """
- Verify that peerFromTransport successfully creates the correct
- certificate if passed a valid SSL transport.
- """
- self.assertEqual(
- sslverify.Certificate.peerFromTransport(
- _ActualSSLTransport()).serialNumber(),
- 12346)
-
-
-
-if interfaces.IReactorSSL(reactor, None) is None:
- Constructors.skip = "Reactor does not support SSL, cannot run SSL tests"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stateful.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stateful.py
deleted file mode 100755
index 365bfacd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stateful.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test cases for twisted.protocols.stateful
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.test import test_protocols
-from twisted.protocols.stateful import StatefulProtocol
-
-from struct import pack, unpack, calcsize
-
-
-class MyInt32StringReceiver(StatefulProtocol):
- """
- A stateful Int32StringReceiver.
- """
- MAX_LENGTH = 99999
- structFormat = "!I"
- prefixLength = calcsize(structFormat)
-
- def getInitialState(self):
- return self._getHeader, 4
-
- def lengthLimitExceeded(self, length):
- self.transport.loseConnection()
-
- def _getHeader(self, msg):
- length, = unpack("!i", msg)
- if length > self.MAX_LENGTH:
- self.lengthLimitExceeded(length)
- return
- return self._getString, length
-
- def _getString(self, msg):
- self.stringReceived(msg)
- return self._getHeader, 4
-
- def stringReceived(self, msg):
- """
- Override this.
- """
- raise NotImplementedError
-
- def sendString(self, data):
- """
- Send an int32-prefixed string to the other end of the connection.
- """
- self.transport.write(pack(self.structFormat, len(data)) + data)
-
-
-class TestInt32(MyInt32StringReceiver):
- def connectionMade(self):
- self.received = []
-
- def stringReceived(self, s):
- self.received.append(s)
-
- MAX_LENGTH = 50
- closed = 0
-
- def connectionLost(self, reason):
- self.closed = 1
-
-
-class Int32TestCase(TestCase, test_protocols.IntNTestCaseMixin):
- protocol = TestInt32
- strings = ["a", "b" * 16]
- illegalStrings = ["\x10\x00\x00\x00aaaaaa"]
- partialStrings = ["\x00\x00\x00", "hello there", ""]
-
- def test_bigReceive(self):
- r = self.getProtocol()
- big = ""
- for s in self.strings * 4:
- big += pack("!i", len(s)) + s
- r.dataReceived(big)
- self.assertEqual(r.received, self.strings * 4)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stdio.py
deleted file mode 100755
index 3da754c6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stdio.py
+++ /dev/null
@@ -1,371 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.internet.stdio}.
-"""
-
-import os, sys, itertools
-
-from twisted.trial import unittest
-from twisted.python import filepath, log
-from twisted.python.runtime import platform
-from twisted.internet import error, defer, protocol, stdio, reactor
-from twisted.test.test_tcp import ConnectionLostNotifyingProtocol
-
-
-# A short string which is intended to appear here and nowhere else,
-# particularly not in any random garbage output CPython unavoidable
-# generates (such as in warning text and so forth). This is searched
-# for in the output from stdio_test_lastwrite.py and if it is found at
-# the end, the functionality works.
-UNIQUE_LAST_WRITE_STRING = 'xyz123abc Twisted is great!'
-
-skipWindowsNopywin32 = None
-if platform.isWindows():
- try:
- import win32process
- except ImportError:
- skipWindowsNopywin32 = ("On windows, spawnProcess is not available "
- "in the absence of win32process.")
-
-
-class StandardIOTestProcessProtocol(protocol.ProcessProtocol):
- """
- Test helper for collecting output from a child process and notifying
- something when it exits.
-
- @ivar onConnection: A L{defer.Deferred} which will be called back with
- C{None} when the connection to the child process is established.
-
- @ivar onCompletion: A L{defer.Deferred} which will be errbacked with the
- failure associated with the child process exiting when it exits.
-
- @ivar onDataReceived: A L{defer.Deferred} which will be called back with
- this instance whenever C{childDataReceived} is called, or C{None} to
- suppress these callbacks.
-
- @ivar data: A C{dict} mapping file descriptors to strings containing all
- bytes received from the child process on each file descriptor.
- """
- onDataReceived = None
-
- def __init__(self):
- self.onConnection = defer.Deferred()
- self.onCompletion = defer.Deferred()
- self.data = {}
-
-
- def connectionMade(self):
- self.onConnection.callback(None)
-
-
- def childDataReceived(self, name, bytes):
- """
- Record all bytes received from the child process in the C{data}
- dictionary. Fire C{onDataReceived} if it is not C{None}.
- """
- self.data[name] = self.data.get(name, '') + bytes
- if self.onDataReceived is not None:
- d, self.onDataReceived = self.onDataReceived, None
- d.callback(self)
-
-
- def processEnded(self, reason):
- self.onCompletion.callback(reason)
-
-
-
-class StandardInputOutputTestCase(unittest.TestCase):
-
- skip = skipWindowsNopywin32
-
- def _spawnProcess(self, proto, sibling, *args, **kw):
- """
- Launch a child Python process and communicate with it using the
- given ProcessProtocol.
-
- @param proto: A L{ProcessProtocol} instance which will be connected
- to the child process.
-
- @param sibling: The basename of a file containing the Python program
- to run in the child process.
-
- @param *args: strings which will be passed to the child process on
- the command line as C{argv[2:]}.
-
- @param **kw: additional arguments to pass to L{reactor.spawnProcess}.
-
- @return: The L{IProcessTransport} provider for the spawned process.
- """
- import twisted
- subenv = dict(os.environ)
- subenv['PYTHONPATH'] = os.pathsep.join(
- [os.path.abspath(
- os.path.dirname(os.path.dirname(twisted.__file__))),
- subenv.get('PYTHONPATH', '')
- ])
- args = [sys.executable,
- filepath.FilePath(__file__).sibling(sibling).path,
- reactor.__class__.__module__] + list(args)
- return reactor.spawnProcess(
- proto,
- sys.executable,
- args,
- env=subenv,
- **kw)
-
-
- def _requireFailure(self, d, callback):
- def cb(result):
- self.fail("Process terminated with non-Failure: %r" % (result,))
- def eb(err):
- return callback(err)
- return d.addCallbacks(cb, eb)
-
-
- def test_loseConnection(self):
- """
- Verify that a protocol connected to L{StandardIO} can disconnect
- itself using C{transport.loseConnection}.
- """
- errorLogFile = self.mktemp()
- log.msg("Child process logging to " + errorLogFile)
- p = StandardIOTestProcessProtocol()
- d = p.onCompletion
- self._spawnProcess(p, 'stdio_test_loseconn.py', errorLogFile)
-
- def processEnded(reason):
- # Copy the child's log to ours so it's more visible.
- for line in file(errorLogFile):
- log.msg("Child logged: " + line.rstrip())
-
- self.failIfIn(1, p.data)
- reason.trap(error.ProcessDone)
- return self._requireFailure(d, processEnded)
-
-
- def test_readConnectionLost(self):
- """
- When stdin is closed and the protocol connected to it implements
- L{IHalfCloseableProtocol}, the protocol's C{readConnectionLost} method
- is called.
- """
- errorLogFile = self.mktemp()
- log.msg("Child process logging to " + errorLogFile)
- p = StandardIOTestProcessProtocol()
- p.onDataReceived = defer.Deferred()
-
- def cbBytes(ignored):
- d = p.onCompletion
- p.transport.closeStdin()
- return d
- p.onDataReceived.addCallback(cbBytes)
-
- def processEnded(reason):
- reason.trap(error.ProcessDone)
- d = self._requireFailure(p.onDataReceived, processEnded)
-
- self._spawnProcess(
- p, 'stdio_test_halfclose.py', errorLogFile)
- return d
-
-
- def test_lastWriteReceived(self):
- """
- Verify that a write made directly to stdout using L{os.write}
- after StandardIO has finished is reliably received by the
- process reading that stdout.
- """
- p = StandardIOTestProcessProtocol()
-
- # Note: the OS X bug which prompted the addition of this test
- # is an apparent race condition involving non-blocking PTYs.
- # Delaying the parent process significantly increases the
- # likelihood of the race going the wrong way. If you need to
- # fiddle with this code at all, uncommenting the next line
- # will likely make your life much easier. It is commented out
- # because it makes the test quite slow.
-
- # p.onConnection.addCallback(lambda ign: __import__('time').sleep(5))
-
- try:
- self._spawnProcess(
- p, 'stdio_test_lastwrite.py', UNIQUE_LAST_WRITE_STRING,
- usePTY=True)
- except ValueError, e:
- # Some platforms don't work with usePTY=True
- raise unittest.SkipTest(str(e))
-
- def processEnded(reason):
- """
- Asserts that the parent received the bytes written by the child
- immediately after the child starts.
- """
- self.assertTrue(
- p.data[1].endswith(UNIQUE_LAST_WRITE_STRING),
- "Received %r from child, did not find expected bytes." % (
- p.data,))
- reason.trap(error.ProcessDone)
- return self._requireFailure(p.onCompletion, processEnded)
-
-
- def test_hostAndPeer(self):
- """
- Verify that the transport of a protocol connected to L{StandardIO}
- has C{getHost} and C{getPeer} methods.
- """
- p = StandardIOTestProcessProtocol()
- d = p.onCompletion
- self._spawnProcess(p, 'stdio_test_hostpeer.py')
-
- def processEnded(reason):
- host, peer = p.data[1].splitlines()
- self.failUnless(host)
- self.failUnless(peer)
- reason.trap(error.ProcessDone)
- return self._requireFailure(d, processEnded)
-
-
- def test_write(self):
- """
- Verify that the C{write} method of the transport of a protocol
- connected to L{StandardIO} sends bytes to standard out.
- """
- p = StandardIOTestProcessProtocol()
- d = p.onCompletion
-
- self._spawnProcess(p, 'stdio_test_write.py')
-
- def processEnded(reason):
- self.assertEqual(p.data[1], 'ok!')
- reason.trap(error.ProcessDone)
- return self._requireFailure(d, processEnded)
-
-
- def test_writeSequence(self):
- """
- Verify that the C{writeSequence} method of the transport of a
- protocol connected to L{StandardIO} sends bytes to standard out.
- """
- p = StandardIOTestProcessProtocol()
- d = p.onCompletion
-
- self._spawnProcess(p, 'stdio_test_writeseq.py')
-
- def processEnded(reason):
- self.assertEqual(p.data[1], 'ok!')
- reason.trap(error.ProcessDone)
- return self._requireFailure(d, processEnded)
-
-
- def _junkPath(self):
- junkPath = self.mktemp()
- junkFile = file(junkPath, 'w')
- for i in xrange(1024):
- junkFile.write(str(i) + '\n')
- junkFile.close()
- return junkPath
-
-
- def test_producer(self):
- """
- Verify that the transport of a protocol connected to L{StandardIO}
- is a working L{IProducer} provider.
- """
- p = StandardIOTestProcessProtocol()
- d = p.onCompletion
-
- written = []
- toWrite = range(100)
-
- def connectionMade(ign):
- if toWrite:
- written.append(str(toWrite.pop()) + "\n")
- proc.write(written[-1])
- reactor.callLater(0.01, connectionMade, None)
-
- proc = self._spawnProcess(p, 'stdio_test_producer.py')
-
- p.onConnection.addCallback(connectionMade)
-
- def processEnded(reason):
- self.assertEqual(p.data[1], ''.join(written))
- self.failIf(toWrite, "Connection lost with %d writes left to go." % (len(toWrite),))
- reason.trap(error.ProcessDone)
- return self._requireFailure(d, processEnded)
-
-
- def test_consumer(self):
- """
- Verify that the transport of a protocol connected to L{StandardIO}
- is a working L{IConsumer} provider.
- """
- p = StandardIOTestProcessProtocol()
- d = p.onCompletion
-
- junkPath = self._junkPath()
-
- self._spawnProcess(p, 'stdio_test_consumer.py', junkPath)
-
- def processEnded(reason):
- self.assertEqual(p.data[1], file(junkPath).read())
- reason.trap(error.ProcessDone)
- return self._requireFailure(d, processEnded)
-
-
- def test_normalFileStandardOut(self):
- """
- If L{StandardIO} is created with a file descriptor which refers to a
- normal file (ie, a file from the filesystem), L{StandardIO.write}
- writes bytes to that file. In particular, it does not immediately
- consider the file closed or call its protocol's C{connectionLost}
- method.
- """
- onConnLost = defer.Deferred()
- proto = ConnectionLostNotifyingProtocol(onConnLost)
- path = filepath.FilePath(self.mktemp())
- self.normal = normal = path.open('w')
- self.addCleanup(normal.close)
-
- kwargs = dict(stdout=normal.fileno())
- if not platform.isWindows():
- # Make a fake stdin so that StandardIO doesn't mess with the *real*
- # stdin.
- r, w = os.pipe()
- self.addCleanup(os.close, r)
- self.addCleanup(os.close, w)
- kwargs['stdin'] = r
- connection = stdio.StandardIO(proto, **kwargs)
-
- # The reactor needs to spin a bit before it might have incorrectly
- # decided stdout is closed. Use this counter to keep track of how
- # much we've let it spin. If it closes before we expected, this
- # counter will have a value that's too small and we'll know.
- howMany = 5
- count = itertools.count()
-
- def spin():
- for value in count:
- if value == howMany:
- connection.loseConnection()
- return
- connection.write(str(value))
- break
- reactor.callLater(0, spin)
- reactor.callLater(0, spin)
-
- # Once the connection is lost, make sure the counter is at the
- # appropriate value.
- def cbLost(reason):
- self.assertEqual(count.next(), howMany + 1)
- self.assertEqual(
- path.getContent(),
- ''.join(map(str, range(howMany))))
- onConnLost.addCallback(cbLost)
- return onConnLost
-
- if platform.isWindows():
- test_normalFileStandardOut.skip = (
- "StandardIO does not accept stdout as an argument to Windows. "
- "Testing redirection to a file is therefore harder.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strcred.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strcred.py
deleted file mode 100755
index 7233a58e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strcred.py
+++ /dev/null
@@ -1,657 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.cred.strcred}.
-"""
-
-import os
-import StringIO
-
-from twisted import plugin
-from twisted.trial import unittest
-from twisted.cred import credentials, checkers, error, strcred
-from twisted.plugins import cred_file, cred_anonymous
-from twisted.python import usage
-from twisted.python.filepath import FilePath
-from twisted.python.fakepwd import UserDatabase
-
-try:
- import crypt
-except ImportError:
- crypt = None
-
-try:
- import pwd
-except ImportError:
- pwd = None
-
-try:
- import spwd
-except ImportError:
- spwd = None
-
-
-
-def getInvalidAuthType():
- """
- Helper method to produce an auth type that doesn't exist.
- """
- invalidAuthType = 'ThisPluginDoesNotExist'
- while (invalidAuthType in
- [factory.authType for factory in strcred.findCheckerFactories()]):
- invalidAuthType += '_'
- return invalidAuthType
-
-
-
-class TestPublicAPI(unittest.TestCase):
-
- def test_emptyDescription(self):
- """
- Test that the description string cannot be empty.
- """
- iat = getInvalidAuthType()
- self.assertRaises(strcred.InvalidAuthType, strcred.makeChecker, iat)
- self.assertRaises(
- strcred.InvalidAuthType, strcred.findCheckerFactory, iat)
-
-
- def test_invalidAuthType(self):
- """
- Test that an unrecognized auth type raises an exception.
- """
- iat = getInvalidAuthType()
- self.assertRaises(strcred.InvalidAuthType, strcred.makeChecker, iat)
- self.assertRaises(
- strcred.InvalidAuthType, strcred.findCheckerFactory, iat)
-
-
-
-class TestStrcredFunctions(unittest.TestCase):
-
- def test_findCheckerFactories(self):
- """
- Test that findCheckerFactories returns all available plugins.
- """
- availablePlugins = list(strcred.findCheckerFactories())
- for plg in plugin.getPlugins(strcred.ICheckerFactory):
- self.assertIn(plg, availablePlugins)
-
-
- def test_findCheckerFactory(self):
- """
- Test that findCheckerFactory returns the first plugin
- available for a given authentication type.
- """
- self.assertIdentical(strcred.findCheckerFactory('file'),
- cred_file.theFileCheckerFactory)
-
-
-
-class TestMemoryChecker(unittest.TestCase):
-
- def setUp(self):
- self.admin = credentials.UsernamePassword('admin', 'asdf')
- self.alice = credentials.UsernamePassword('alice', 'foo')
- self.badPass = credentials.UsernamePassword('alice', 'foobar')
- self.badUser = credentials.UsernamePassword('x', 'yz')
- self.checker = strcred.makeChecker('memory:admin:asdf:alice:foo')
-
-
- def test_isChecker(self):
- """
- Verifies that strcred.makeChecker('memory') returns an object
- that implements the L{ICredentialsChecker} interface.
- """
- self.assertTrue(checkers.ICredentialsChecker.providedBy(self.checker))
- self.assertIn(credentials.IUsernamePassword,
- self.checker.credentialInterfaces)
-
-
- def test_badFormatArgString(self):
- """
- Test that an argument string which does not contain user:pass
- pairs (i.e., an odd number of ':' characters) raises an exception.
- """
- self.assertRaises(strcred.InvalidAuthArgumentString,
- strcred.makeChecker, 'memory:a:b:c')
-
-
- def test_memoryCheckerSucceeds(self):
- """
- Test that the checker works with valid credentials.
- """
- def _gotAvatar(username):
- self.assertEqual(username, self.admin.username)
- return (self.checker
- .requestAvatarId(self.admin)
- .addCallback(_gotAvatar))
-
-
- def test_memoryCheckerFailsUsername(self):
- """
- Test that the checker fails with an invalid username.
- """
- return self.assertFailure(self.checker.requestAvatarId(self.badUser),
- error.UnauthorizedLogin)
-
-
- def test_memoryCheckerFailsPassword(self):
- """
- Test that the checker fails with an invalid password.
- """
- return self.assertFailure(self.checker.requestAvatarId(self.badPass),
- error.UnauthorizedLogin)
-
-
-
-class TestAnonymousChecker(unittest.TestCase):
-
- def test_isChecker(self):
- """
- Verifies that strcred.makeChecker('anonymous') returns an object
- that implements the L{ICredentialsChecker} interface.
- """
- checker = strcred.makeChecker('anonymous')
- self.assertTrue(checkers.ICredentialsChecker.providedBy(checker))
- self.assertIn(credentials.IAnonymous, checker.credentialInterfaces)
-
-
- def testAnonymousAccessSucceeds(self):
- """
- Test that we can log in anonymously using this checker.
- """
- checker = strcred.makeChecker('anonymous')
- request = checker.requestAvatarId(credentials.Anonymous())
- def _gotAvatar(avatar):
- self.assertIdentical(checkers.ANONYMOUS, avatar)
- return request.addCallback(_gotAvatar)
-
-
-
-class TestUnixChecker(unittest.TestCase):
- users = {
- 'admin': 'asdf',
- 'alice': 'foo',
- }
-
-
- def _spwd(self, username):
- return (username, crypt.crypt(self.users[username], 'F/'),
- 0, 0, 99999, 7, -1, -1, -1)
-
-
- def setUp(self):
- self.admin = credentials.UsernamePassword('admin', 'asdf')
- self.alice = credentials.UsernamePassword('alice', 'foo')
- self.badPass = credentials.UsernamePassword('alice', 'foobar')
- self.badUser = credentials.UsernamePassword('x', 'yz')
- self.checker = strcred.makeChecker('unix')
-
- # Hack around the pwd and spwd modules, since we can't really
- # go about reading your /etc/passwd or /etc/shadow files
- if pwd:
- database = UserDatabase()
- for username, password in self.users.items():
- database.addUser(
- username, crypt.crypt(password, 'F/'),
- 1000, 1000, username, '/home/' + username, '/bin/sh')
- self.patch(pwd, 'getpwnam', database.getpwnam)
- if spwd:
- self._spwd_getspnam = spwd.getspnam
- spwd.getspnam = self._spwd
-
-
- def tearDown(self):
- if spwd:
- spwd.getspnam = self._spwd_getspnam
-
-
- def test_isChecker(self):
- """
- Verifies that strcred.makeChecker('unix') returns an object
- that implements the L{ICredentialsChecker} interface.
- """
- self.assertTrue(checkers.ICredentialsChecker.providedBy(self.checker))
- self.assertIn(credentials.IUsernamePassword,
- self.checker.credentialInterfaces)
-
-
- def test_unixCheckerSucceeds(self):
- """
- Test that the checker works with valid credentials.
- """
- def _gotAvatar(username):
- self.assertEqual(username, self.admin.username)
- return (self.checker
- .requestAvatarId(self.admin)
- .addCallback(_gotAvatar))
-
-
- def test_unixCheckerFailsUsername(self):
- """
- Test that the checker fails with an invalid username.
- """
- return self.assertFailure(self.checker.requestAvatarId(self.badUser),
- error.UnauthorizedLogin)
-
-
- def test_unixCheckerFailsPassword(self):
- """
- Test that the checker fails with an invalid password.
- """
- return self.assertFailure(self.checker.requestAvatarId(self.badPass),
- error.UnauthorizedLogin)
-
-
- if None in (pwd, spwd, crypt):
- availability = []
- for module, name in ((pwd, "pwd"), (spwd, "swpd"), (crypt, "crypt")):
- if module is None:
- availability += [name]
- for method in (test_unixCheckerSucceeds,
- test_unixCheckerFailsUsername,
- test_unixCheckerFailsPassword):
- method.skip = ("Required module(s) are unavailable: " +
- ", ".join(availability))
-
-
-
-class TestFileDBChecker(unittest.TestCase):
- """
- Test for the --auth=file:... file checker.
- """
-
- def setUp(self):
- self.admin = credentials.UsernamePassword('admin', 'asdf')
- self.alice = credentials.UsernamePassword('alice', 'foo')
- self.badPass = credentials.UsernamePassword('alice', 'foobar')
- self.badUser = credentials.UsernamePassword('x', 'yz')
- self.filename = self.mktemp()
- FilePath(self.filename).setContent('admin:asdf\nalice:foo\n')
- self.checker = strcred.makeChecker('file:' + self.filename)
-
-
- def _fakeFilename(self):
- filename = '/DoesNotExist'
- while os.path.exists(filename):
- filename += '_'
- return filename
-
-
- def test_isChecker(self):
- """
- Verifies that strcred.makeChecker('memory') returns an object
- that implements the L{ICredentialsChecker} interface.
- """
- self.assertTrue(checkers.ICredentialsChecker.providedBy(self.checker))
- self.assertIn(credentials.IUsernamePassword,
- self.checker.credentialInterfaces)
-
-
- def test_fileCheckerSucceeds(self):
- """
- Test that the checker works with valid credentials.
- """
- def _gotAvatar(username):
- self.assertEqual(username, self.admin.username)
- return (self.checker
- .requestAvatarId(self.admin)
- .addCallback(_gotAvatar))
-
-
- def test_fileCheckerFailsUsername(self):
- """
- Test that the checker fails with an invalid username.
- """
- return self.assertFailure(self.checker.requestAvatarId(self.badUser),
- error.UnauthorizedLogin)
-
-
- def test_fileCheckerFailsPassword(self):
- """
- Test that the checker fails with an invalid password.
- """
- return self.assertFailure(self.checker.requestAvatarId(self.badPass),
- error.UnauthorizedLogin)
-
-
- def test_failsWithEmptyFilename(self):
- """
- Test that an empty filename raises an error.
- """
- self.assertRaises(ValueError, strcred.makeChecker, 'file')
- self.assertRaises(ValueError, strcred.makeChecker, 'file:')
-
-
- def test_warnWithBadFilename(self):
- """
- When the file auth plugin is given a file that doesn't exist, it
- should produce a warning.
- """
- oldOutput = cred_file.theFileCheckerFactory.errorOutput
- newOutput = StringIO.StringIO()
- cred_file.theFileCheckerFactory.errorOutput = newOutput
- checker = strcred.makeChecker('file:' + self._fakeFilename())
- cred_file.theFileCheckerFactory.errorOutput = oldOutput
- self.assertIn(cred_file.invalidFileWarning, newOutput.getvalue())
-
-
-
-class TestSSHChecker(unittest.TestCase):
- """
- Tests for the --auth=sshkey:... checker. The majority of the tests for the
- ssh public key database checker are in
- L{twisted.conch.test.test_checkers.SSHPublicKeyDatabaseTestCase}.
- """
-
- try:
- import Crypto
- import pyasn1
- except ImportError:
- skip = "PyCrypto is not available"
-
-
- def test_isChecker(self):
- """
- Verifies that strcred.makeChecker('sshkey') returns an object
- that implements the L{ICredentialsChecker} interface.
- """
- sshChecker = strcred.makeChecker('sshkey')
- self.assertTrue(checkers.ICredentialsChecker.providedBy(sshChecker))
- self.assertIn(
- credentials.ISSHPrivateKey, sshChecker.credentialInterfaces)
-
-
-
-class DummyOptions(usage.Options, strcred.AuthOptionMixin):
- """
- Simple options for testing L{strcred.AuthOptionMixin}.
- """
-
-
-
-class TestCheckerOptions(unittest.TestCase):
-
- def test_createsList(self):
- """
- Test that the --auth command line creates a list in the
- Options instance and appends values to it.
- """
- options = DummyOptions()
- options.parseOptions(['--auth', 'memory'])
- self.assertEqual(len(options['credCheckers']), 1)
- options = DummyOptions()
- options.parseOptions(['--auth', 'memory', '--auth', 'memory'])
- self.assertEqual(len(options['credCheckers']), 2)
-
-
- def test_invalidAuthError(self):
- """
- Test that the --auth command line raises an exception when it
- gets a parameter it doesn't understand.
- """
- options = DummyOptions()
- # If someone adds a 'ThisPluginDoesNotExist' then this unit
- # test should still run.
- invalidParameter = getInvalidAuthType()
- self.assertRaises(
- usage.UsageError,
- options.parseOptions, ['--auth', invalidParameter])
- self.assertRaises(
- usage.UsageError,
- options.parseOptions, ['--help-auth-type', invalidParameter])
-
-
- def test_createsDictionary(self):
- """
- Test that the --auth command line creates a dictionary
- mapping supported interfaces to the list of credentials
- checkers that support it.
- """
- options = DummyOptions()
- options.parseOptions(['--auth', 'memory', '--auth', 'anonymous'])
- chd = options['credInterfaces']
- self.assertEqual(len(chd[credentials.IAnonymous]), 1)
- self.assertEqual(len(chd[credentials.IUsernamePassword]), 1)
- chdAnonymous = chd[credentials.IAnonymous][0]
- chdUserPass = chd[credentials.IUsernamePassword][0]
- self.assertTrue(checkers.ICredentialsChecker.providedBy(chdAnonymous))
- self.assertTrue(checkers.ICredentialsChecker.providedBy(chdUserPass))
- self.assertIn(credentials.IAnonymous,
- chdAnonymous.credentialInterfaces)
- self.assertIn(credentials.IUsernamePassword,
- chdUserPass.credentialInterfaces)
-
-
- def test_credInterfacesProvidesLists(self):
- """
- Test that when two --auth arguments are passed along which
- support the same interface, a list with both is created.
- """
- options = DummyOptions()
- options.parseOptions(['--auth', 'memory', '--auth', 'unix'])
- self.assertEqual(
- options['credCheckers'],
- options['credInterfaces'][credentials.IUsernamePassword])
-
-
- def test_listDoesNotDisplayDuplicates(self):
- """
- Test that the list for --help-auth does not duplicate items.
- """
- authTypes = []
- options = DummyOptions()
- for cf in options._checkerFactoriesForOptHelpAuth():
- self.assertNotIn(cf.authType, authTypes)
- authTypes.append(cf.authType)
-
-
- def test_displaysListCorrectly(self):
- """
- Test that the --help-auth argument correctly displays all
- available authentication plugins, then exits.
- """
- newStdout = StringIO.StringIO()
- options = DummyOptions()
- options.authOutput = newStdout
- self.assertRaises(SystemExit, options.parseOptions, ['--help-auth'])
- for checkerFactory in strcred.findCheckerFactories():
- self.assertIn(checkerFactory.authType, newStdout.getvalue())
-
-
- def test_displaysHelpCorrectly(self):
- """
- Test that the --help-auth-for argument will correctly display
- the help file for a particular authentication plugin.
- """
- newStdout = StringIO.StringIO()
- options = DummyOptions()
- options.authOutput = newStdout
- self.assertRaises(
- SystemExit, options.parseOptions, ['--help-auth-type', 'file'])
- for line in cred_file.theFileCheckerFactory.authHelp:
- if line.strip():
- self.assertIn(line.strip(), newStdout.getvalue())
-
-
- def test_unexpectedException(self):
- """
- When the checker specified by --auth raises an unexpected error, it
- should be caught and re-raised within a L{usage.UsageError}.
- """
- options = DummyOptions()
- err = self.assertRaises(usage.UsageError, options.parseOptions,
- ['--auth', 'file'])
- self.assertEqual(str(err),
- "Unexpected error: 'file' requires a filename")
-
-
-
-class OptionsForUsernamePassword(usage.Options, strcred.AuthOptionMixin):
- supportedInterfaces = (credentials.IUsernamePassword,)
-
-
-
-class OptionsForUsernameHashedPassword(usage.Options, strcred.AuthOptionMixin):
- supportedInterfaces = (credentials.IUsernameHashedPassword,)
-
-
-
-class OptionsSupportsAllInterfaces(usage.Options, strcred.AuthOptionMixin):
- supportedInterfaces = None
-
-
-
-class OptionsSupportsNoInterfaces(usage.Options, strcred.AuthOptionMixin):
- supportedInterfaces = []
-
-
-
-class TestLimitingInterfaces(unittest.TestCase):
- """
- Tests functionality that allows an application to limit the
- credential interfaces it can support. For the purposes of this
- test, we use IUsernameHashedPassword, although this will never
- really be used by the command line.
-
- (I have, to date, not thought of a half-decent way for a user to
- specify a hash algorithm via the command-line. Nor do I think it's
- very useful.)
-
- I should note that, at first, this test is counter-intuitive,
- because we're using the checker with a pre-defined hash function
- as the 'bad' checker. See the documentation for
- L{twisted.cred.checkers.FilePasswordDB.hash} for more details.
- """
-
- def setUp(self):
- self.filename = self.mktemp()
- file(self.filename, 'w').write('admin:asdf\nalice:foo\n')
- self.goodChecker = checkers.FilePasswordDB(self.filename)
- self.badChecker = checkers.FilePasswordDB(
- self.filename, hash=self._hash)
- self.anonChecker = checkers.AllowAnonymousAccess()
-
-
- def _hash(self, networkUsername, networkPassword, storedPassword):
- """
- A dumb hash that doesn't really do anything.
- """
- return networkPassword
-
-
- def test_supportsInterface(self):
- """
- Test that the supportsInterface method behaves appropriately.
- """
- options = OptionsForUsernamePassword()
- self.assertTrue(
- options.supportsInterface(credentials.IUsernamePassword))
- self.assertFalse(
- options.supportsInterface(credentials.IAnonymous))
- self.assertRaises(
- strcred.UnsupportedInterfaces, options.addChecker,
- self.anonChecker)
-
-
- def test_supportsAllInterfaces(self):
- """
- Test that the supportsInterface method behaves appropriately
- when the supportedInterfaces attribute is None.
- """
- options = OptionsSupportsAllInterfaces()
- self.assertTrue(
- options.supportsInterface(credentials.IUsernamePassword))
- self.assertTrue(
- options.supportsInterface(credentials.IAnonymous))
-
-
- def test_supportsCheckerFactory(self):
- """
- Test that the supportsCheckerFactory method behaves appropriately.
- """
- options = OptionsForUsernamePassword()
- fileCF = cred_file.theFileCheckerFactory
- anonCF = cred_anonymous.theAnonymousCheckerFactory
- self.assertTrue(options.supportsCheckerFactory(fileCF))
- self.assertFalse(options.supportsCheckerFactory(anonCF))
-
-
- def test_canAddSupportedChecker(self):
- """
- Test that when addChecker is called with a checker that
- implements at least one of the interfaces our application
- supports, it is successful.
- """
- options = OptionsForUsernamePassword()
- options.addChecker(self.goodChecker)
- iface = options.supportedInterfaces[0]
- # Test that we did get IUsernamePassword
- self.assertIdentical(
- options['credInterfaces'][iface][0], self.goodChecker)
- self.assertIdentical(options['credCheckers'][0], self.goodChecker)
- # Test that we didn't get IUsernameHashedPassword
- self.assertEqual(len(options['credInterfaces'][iface]), 1)
- self.assertEqual(len(options['credCheckers']), 1)
-
-
- def test_failOnAddingUnsupportedChecker(self):
- """
- Test that when addChecker is called with a checker that does
- not implement any supported interfaces, it fails.
- """
- options = OptionsForUsernameHashedPassword()
- self.assertRaises(strcred.UnsupportedInterfaces,
- options.addChecker, self.badChecker)
-
-
- def test_unsupportedInterfaceError(self):
- """
- Test that the --auth command line raises an exception when it
- gets a checker we don't support.
- """
- options = OptionsSupportsNoInterfaces()
- authType = cred_anonymous.theAnonymousCheckerFactory.authType
- self.assertRaises(
- usage.UsageError,
- options.parseOptions, ['--auth', authType])
-
-
- def test_helpAuthLimitsOutput(self):
- """
- Test that --help-auth will only list checkers that purport to
- supply at least one of the credential interfaces our
- application can use.
- """
- options = OptionsForUsernamePassword()
- for factory in options._checkerFactoriesForOptHelpAuth():
- invalid = True
- for interface in factory.credentialInterfaces:
- if options.supportsInterface(interface):
- invalid = False
- if invalid:
- raise strcred.UnsupportedInterfaces()
-
-
- def test_helpAuthTypeLimitsOutput(self):
- """
- Test that --help-auth-type will display a warning if you get
- help for an authType that does not supply at least one of the
- credential interfaces our application can use.
- """
- options = OptionsForUsernamePassword()
- # Find an interface that we can use for our test
- invalidFactory = None
- for factory in strcred.findCheckerFactories():
- if not options.supportsCheckerFactory(factory):
- invalidFactory = factory
- break
- self.assertNotIdentical(invalidFactory, None)
- # Capture output and make sure the warning is there
- newStdout = StringIO.StringIO()
- options.authOutput = newStdout
- self.assertRaises(SystemExit, options.parseOptions,
- ['--help-auth-type', 'anonymous'])
- self.assertIn(strcred.notSupportedWarning, newStdout.getvalue())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strerror.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strerror.py
deleted file mode 100755
index ce140511..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strerror.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test strerror
-"""
-
-import socket
-import os
-
-from twisted.trial.unittest import TestCase
-from twisted.internet.tcp import ECONNABORTED
-from twisted.python.win32 import _ErrorFormatter, formatError
-from twisted.python.runtime import platform
-
-
-class _MyWindowsException(OSError):
- """
- An exception type like L{ctypes.WinError}, but available on all platforms.
- """
-
-
-
-class ErrorFormatingTestCase(TestCase):
- """
- Tests for C{_ErrorFormatter.formatError}.
- """
- probeErrorCode = ECONNABORTED
- probeMessage = "correct message value"
-
- def test_strerrorFormatting(self):
- """
- L{_ErrorFormatter.formatError} should use L{os.strerror} to format
- error messages if it is constructed without any better mechanism.
- """
- formatter = _ErrorFormatter(None, None, None)
- message = formatter.formatError(self.probeErrorCode)
- self.assertEqual(message, os.strerror(self.probeErrorCode))
-
-
- def test_emptyErrorTab(self):
- """
- L{_ErrorFormatter.formatError} should use L{os.strerror} to format
- error messages if it is constructed with only an error tab which does
- not contain the error code it is called with.
- """
- error = 1
- # Sanity check
- self.assertNotEqual(self.probeErrorCode, error)
- formatter = _ErrorFormatter(None, None, {error: 'wrong message'})
- message = formatter.formatError(self.probeErrorCode)
- self.assertEqual(message, os.strerror(self.probeErrorCode))
-
-
- def test_errorTab(self):
- """
- L{_ErrorFormatter.formatError} should use C{errorTab} if it is supplied
- and contains the requested error code.
- """
- formatter = _ErrorFormatter(
- None, None, {self.probeErrorCode: self.probeMessage})
- message = formatter.formatError(self.probeErrorCode)
- self.assertEqual(message, self.probeMessage)
-
-
- def test_formatMessage(self):
- """
- L{_ErrorFormatter.formatError} should return the return value of
- C{formatMessage} if it is supplied.
- """
- formatCalls = []
- def formatMessage(errorCode):
- formatCalls.append(errorCode)
- return self.probeMessage
- formatter = _ErrorFormatter(
- None, formatMessage, {self.probeErrorCode: 'wrong message'})
- message = formatter.formatError(self.probeErrorCode)
- self.assertEqual(message, self.probeMessage)
- self.assertEqual(formatCalls, [self.probeErrorCode])
-
-
- def test_winError(self):
- """
- L{_ErrorFormatter.formatError} should return the message argument from
- the exception L{winError} returns, if L{winError} is supplied.
- """
- winCalls = []
- def winError(errorCode):
- winCalls.append(errorCode)
- return _MyWindowsException(errorCode, self.probeMessage)
- formatter = _ErrorFormatter(
- winError,
- lambda error: 'formatMessage: wrong message',
- {self.probeErrorCode: 'errorTab: wrong message'})
- message = formatter.formatError(self.probeErrorCode)
- self.assertEqual(message, self.probeMessage)
-
-
- def test_fromEnvironment(self):
- """
- L{_ErrorFormatter.fromEnvironment} should create an L{_ErrorFormatter}
- instance with attributes populated from available modules.
- """
- formatter = _ErrorFormatter.fromEnvironment()
-
- if formatter.winError is not None:
- from ctypes import WinError
- self.assertEqual(
- formatter.formatError(self.probeErrorCode),
- WinError(self.probeErrorCode).strerror)
- formatter.winError = None
-
- if formatter.formatMessage is not None:
- from win32api import FormatMessage
- self.assertEqual(
- formatter.formatError(self.probeErrorCode),
- FormatMessage(self.probeErrorCode))
- formatter.formatMessage = None
-
- if formatter.errorTab is not None:
- from socket import errorTab
- self.assertEqual(
- formatter.formatError(self.probeErrorCode),
- errorTab[self.probeErrorCode])
-
- if platform.getType() != "win32":
- test_fromEnvironment.skip = "Test will run only on Windows."
-
-
- def test_correctLookups(self):
- """
- Given an known-good errno, make sure that formatMessage gives results
- matching either C{socket.errorTab}, C{ctypes.WinError}, or
- C{win32api.FormatMessage}.
- """
- acceptable = [socket.errorTab[ECONNABORTED]]
- try:
- from ctypes import WinError
- acceptable.append(WinError(ECONNABORTED).strerror)
- except ImportError:
- pass
- try:
- from win32api import FormatMessage
- acceptable.append(FormatMessage(ECONNABORTED))
- except ImportError:
- pass
-
- self.assertIn(formatError(ECONNABORTED), acceptable)
-
- if platform.getType() != "win32":
- test_correctLookups.skip = "Test will run only on Windows."
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stringtransport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stringtransport.py
deleted file mode 100755
index ca120982..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_stringtransport.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.test.proto_helpers}.
-"""
-
-from zope.interface.verify import verifyObject
-
-from twisted.internet.interfaces import (ITransport, IPushProducer, IConsumer,
- IReactorTCP, IReactorSSL, IReactorUNIX, IAddress, IListeningPort,
- IConnector)
-from twisted.internet.address import IPv4Address
-from twisted.trial.unittest import TestCase
-from twisted.test.proto_helpers import (StringTransport, MemoryReactor,
- RaisingMemoryReactor)
-from twisted.internet.protocol import ClientFactory, Factory
-
-
-class StringTransportTests(TestCase):
- """
- Tests for L{twisted.test.proto_helpers.StringTransport}.
- """
- def setUp(self):
- self.transport = StringTransport()
-
-
- def test_interfaces(self):
- """
- L{StringTransport} instances provide L{ITransport}, L{IPushProducer},
- and L{IConsumer}.
- """
- self.assertTrue(verifyObject(ITransport, self.transport))
- self.assertTrue(verifyObject(IPushProducer, self.transport))
- self.assertTrue(verifyObject(IConsumer, self.transport))
-
-
- def test_registerProducer(self):
- """
- L{StringTransport.registerProducer} records the arguments supplied to
- it as instance attributes.
- """
- producer = object()
- streaming = object()
- self.transport.registerProducer(producer, streaming)
- self.assertIdentical(self.transport.producer, producer)
- self.assertIdentical(self.transport.streaming, streaming)
-
-
- def test_disallowedRegisterProducer(self):
- """
- L{StringTransport.registerProducer} raises L{RuntimeError} if a
- producer is already registered.
- """
- producer = object()
- self.transport.registerProducer(producer, True)
- self.assertRaises(
- RuntimeError, self.transport.registerProducer, object(), False)
- self.assertIdentical(self.transport.producer, producer)
- self.assertTrue(self.transport.streaming)
-
-
- def test_unregisterProducer(self):
- """
- L{StringTransport.unregisterProducer} causes the transport to forget
- about the registered producer and makes it possible to register a new
- one.
- """
- oldProducer = object()
- newProducer = object()
- self.transport.registerProducer(oldProducer, False)
- self.transport.unregisterProducer()
- self.assertIdentical(self.transport.producer, None)
- self.transport.registerProducer(newProducer, True)
- self.assertIdentical(self.transport.producer, newProducer)
- self.assertTrue(self.transport.streaming)
-
-
- def test_invalidUnregisterProducer(self):
- """
- L{StringTransport.unregisterProducer} raises L{RuntimeError} if called
- when no producer is registered.
- """
- self.assertRaises(RuntimeError, self.transport.unregisterProducer)
-
-
- def test_initialProducerState(self):
- """
- L{StringTransport.producerState} is initially C{'producing'}.
- """
- self.assertEqual(self.transport.producerState, 'producing')
-
-
- def test_pauseProducing(self):
- """
- L{StringTransport.pauseProducing} changes the C{producerState} of the
- transport to C{'paused'}.
- """
- self.transport.pauseProducing()
- self.assertEqual(self.transport.producerState, 'paused')
-
-
- def test_resumeProducing(self):
- """
- L{StringTransport.resumeProducing} changes the C{producerState} of the
- transport to C{'producing'}.
- """
- self.transport.pauseProducing()
- self.transport.resumeProducing()
- self.assertEqual(self.transport.producerState, 'producing')
-
-
- def test_stopProducing(self):
- """
- L{StringTransport.stopProducing} changes the C{'producerState'} of the
- transport to C{'stopped'}.
- """
- self.transport.stopProducing()
- self.assertEqual(self.transport.producerState, 'stopped')
-
-
- def test_stoppedTransportCannotPause(self):
- """
- L{StringTransport.pauseProducing} raises L{RuntimeError} if the
- transport has been stopped.
- """
- self.transport.stopProducing()
- self.assertRaises(RuntimeError, self.transport.pauseProducing)
-
-
- def test_stoppedTransportCannotResume(self):
- """
- L{StringTransport.resumeProducing} raises L{RuntimeError} if the
- transport has been stopped.
- """
- self.transport.stopProducing()
- self.assertRaises(RuntimeError, self.transport.resumeProducing)
-
-
- def test_disconnectingTransportCannotPause(self):
- """
- L{StringTransport.pauseProducing} raises L{RuntimeError} if the
- transport is being disconnected.
- """
- self.transport.loseConnection()
- self.assertRaises(RuntimeError, self.transport.pauseProducing)
-
-
- def test_disconnectingTransportCannotResume(self):
- """
- L{StringTransport.resumeProducing} raises L{RuntimeError} if the
- transport is being disconnected.
- """
- self.transport.loseConnection()
- self.assertRaises(RuntimeError, self.transport.resumeProducing)
-
-
- def test_loseConnectionSetsDisconnecting(self):
- """
- L{StringTransport.loseConnection} toggles the C{disconnecting} instance
- variable to C{True}.
- """
- self.assertFalse(self.transport.disconnecting)
- self.transport.loseConnection()
- self.assertTrue(self.transport.disconnecting)
-
-
- def test_specifiedHostAddress(self):
- """
- If a host address is passed to L{StringTransport.__init__}, that
- value is returned from L{StringTransport.getHost}.
- """
- address = object()
- self.assertIdentical(StringTransport(address).getHost(), address)
-
-
- def test_specifiedPeerAddress(self):
- """
- If a peer address is passed to L{StringTransport.__init__}, that
- value is returned from L{StringTransport.getPeer}.
- """
- address = object()
- self.assertIdentical(
- StringTransport(peerAddress=address).getPeer(), address)
-
-
- def test_defaultHostAddress(self):
- """
- If no host address is passed to L{StringTransport.__init__}, an
- L{IPv4Address} is returned from L{StringTransport.getHost}.
- """
- address = StringTransport().getHost()
- self.assertIsInstance(address, IPv4Address)
-
-
- def test_defaultPeerAddress(self):
- """
- If no peer address is passed to L{StringTransport.__init__}, an
- L{IPv4Address} is returned from L{StringTransport.getPeer}.
- """
- address = StringTransport().getPeer()
- self.assertIsInstance(address, IPv4Address)
-
-
-
-class ReactorTests(TestCase):
- """
- Tests for L{MemoryReactor} and L{RaisingMemoryReactor}.
- """
-
- def test_memoryReactorProvides(self):
- """
- L{MemoryReactor} provides all of the attributes described by the
- interfaces it advertises.
- """
- memoryReactor = MemoryReactor()
- verifyObject(IReactorTCP, memoryReactor)
- verifyObject(IReactorSSL, memoryReactor)
- verifyObject(IReactorUNIX, memoryReactor)
-
-
- def test_raisingReactorProvides(self):
- """
- L{RaisingMemoryReactor} provides all of the attributes described by the
- interfaces it advertises.
- """
- raisingReactor = RaisingMemoryReactor()
- verifyObject(IReactorTCP, raisingReactor)
- verifyObject(IReactorSSL, raisingReactor)
- verifyObject(IReactorUNIX, raisingReactor)
-
-
- def test_connectDestination(self):
- """
- L{MemoryReactor.connectTCP}, L{MemoryReactor.connectSSL}, and
- L{MemoryReactor.connectUNIX} will return an L{IConnector} whose
- C{getDestination} method returns an L{IAddress} with attributes which
- reflect the values passed.
- """
- memoryReactor = MemoryReactor()
- for connector in [memoryReactor.connectTCP(
- "test.example.com", 8321, ClientFactory()),
- memoryReactor.connectSSL(
- "test.example.com", 8321, ClientFactory(),
- None)]:
- verifyObject(IConnector, connector)
- address = connector.getDestination()
- verifyObject(IAddress, address)
- self.assertEqual(address.host, "test.example.com")
- self.assertEqual(address.port, 8321)
- connector = memoryReactor.connectUNIX("/fake/path", ClientFactory())
- verifyObject(IConnector, connector)
- address = connector.getDestination()
- verifyObject(IAddress, address)
- self.assertEqual(address.name, "/fake/path")
-
-
- def test_listenDefaultHost(self):
- """
- L{MemoryReactor.listenTCP}, L{MemoryReactor.listenSSL} and
- L{MemoryReactor.listenUNIX} will return an L{IListeningPort} whose
- C{getHost} method returns an L{IAddress}; C{listenTCP} and C{listenSSL}
- will have a default host of C{'0.0.0.0'}, and a port that reflects the
- value passed, and C{listenUNIX} will have a name that reflects the path
- passed.
- """
- memoryReactor = MemoryReactor()
- for port in [memoryReactor.listenTCP(8242, Factory()),
- memoryReactor.listenSSL(8242, Factory(), None)]:
- verifyObject(IListeningPort, port)
- address = port.getHost()
- verifyObject(IAddress, address)
- self.assertEqual(address.host, '0.0.0.0')
- self.assertEqual(address.port, 8242)
- port = memoryReactor.listenUNIX("/path/to/socket", Factory())
- verifyObject(IListeningPort, port)
- address = port.getHost()
- verifyObject(IAddress, address)
- self.assertEqual(address.name, "/path/to/socket")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strports.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strports.py
deleted file mode 100755
index fd081ecd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_strports.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.application.strports}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.application import strports
-from twisted.application import internet
-from twisted.internet.test.test_endpoints import ParserTestCase
-from twisted.internet.protocol import Factory
-from twisted.internet.endpoints import TCP4ServerEndpoint, UNIXServerEndpoint
-
-
-
-class DeprecatedParseTestCase(ParserTestCase):
- """
- L{strports.parse} is deprecated. It's an alias for a method that is now
- private in L{twisted.internet.endpoints}.
- """
-
- def parse(self, *a, **kw):
- result = strports.parse(*a, **kw)
- warnings = self.flushWarnings([self.parse])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(
- warnings[0]['message'],
- "twisted.application.strports.parse was deprecated "
- "in Twisted 10.2.0: in favor of twisted.internet.endpoints.serverFromString")
- return result
-
-
- def test_simpleNumeric(self):
- """
- Base numeric ports should be parsed as TCP.
- """
- self.assertEqual(self.parse('80', self.f),
- ('TCP', (80, self.f), {'interface':'', 'backlog':50}))
-
-
- def test_allKeywords(self):
- """
- A collection of keyword arguments with no prefixed type, like 'port=80',
- will be parsed as keyword arguments to 'tcp'.
- """
- self.assertEqual(self.parse('port=80', self.f),
- ('TCP', (80, self.f), {'interface':'', 'backlog':50}))
-
-
-
-class ServiceTestCase(TestCase):
- """
- Tests for L{strports.service}.
- """
-
- def test_service(self):
- """
- L{strports.service} returns a L{StreamServerEndpointService}
- constructed with an endpoint produced from
- L{endpoint.serverFromString}, using the same syntax.
- """
- reactor = object() # the cake is a lie
- aFactory = Factory()
- aGoodPort = 1337
- svc = strports.service(
- 'tcp:'+str(aGoodPort), aFactory, reactor=reactor)
- self.assertIsInstance(svc, internet.StreamServerEndpointService)
-
- # See twisted.application.test.test_internet.TestEndpointService.
- # test_synchronousRaiseRaisesSynchronously
- self.assertEqual(svc._raiseSynchronously, True)
- self.assertIsInstance(svc.endpoint, TCP4ServerEndpoint)
- # Maybe we should implement equality for endpoints.
- self.assertEqual(svc.endpoint._port, aGoodPort)
- self.assertIdentical(svc.factory, aFactory)
- self.assertIdentical(svc.endpoint._reactor, reactor)
-
-
- def test_serviceDefaultReactor(self):
- """
- L{strports.service} will use the default reactor when none is provided
- as an argument.
- """
- from twisted.internet import reactor as globalReactor
- aService = strports.service("tcp:80", None)
- self.assertIdentical(aService.endpoint._reactor, globalReactor)
-
-
- def test_serviceDeprecatedDefault(self):
- """
- L{strports.service} still accepts a 'default' argument, which will
- affect the parsing of 'default' (i.e. 'not containing a colon')
- endpoint descriptions, but this behavior is deprecated.
- """
- svc = strports.service("8080", None, "unix")
- self.assertIsInstance(svc.endpoint, UNIXServerEndpoint)
- warnings = self.flushWarnings([self.test_serviceDeprecatedDefault])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "The 'default' parameter was deprecated in Twisted 10.2.0. "
- "Use qualified endpoint descriptions; for example, 'tcp:8080'.")
- self.assertEqual(len(warnings), 1)
-
- # Almost the same case, but slightly tricky - explicitly passing the old
- # default value, None, also must trigger a deprecation warning.
- svc = strports.service("tcp:8080", None, None)
- self.assertIsInstance(svc.endpoint, TCP4ServerEndpoint)
- warnings = self.flushWarnings([self.test_serviceDeprecatedDefault])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "The 'default' parameter was deprecated in Twisted 10.2.0.")
- self.assertEqual(len(warnings), 1)
-
-
- def test_serviceDeprecatedUnqualified(self):
- """
- Unqualified strport descriptions, i.e. "8080", are deprecated.
- """
- svc = strports.service("8080", None)
- self.assertIsInstance(svc.endpoint, TCP4ServerEndpoint)
- warnings = self.flushWarnings(
- [self.test_serviceDeprecatedUnqualified])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "Unqualified strport description passed to 'service'."
- "Use qualified endpoint descriptions; for example, 'tcp:8080'.")
- self.assertEqual(len(warnings), 1)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_task.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_task.py
deleted file mode 100755
index 75be888f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_task.py
+++ /dev/null
@@ -1,739 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.python.compat import set
-
-from twisted.trial import unittest
-
-from twisted.internet import interfaces, task, reactor, defer, error
-
-# Be compatible with any jerks who used our private stuff
-Clock = task.Clock
-
-from twisted.python import failure
-
-
-class TestableLoopingCall(task.LoopingCall):
- def __init__(self, clock, *a, **kw):
- super(TestableLoopingCall, self).__init__(*a, **kw)
- self.clock = clock
-
-
-
-class TestException(Exception):
- pass
-
-
-
-class ClockTestCase(unittest.TestCase):
- """
- Test the non-wallclock based clock implementation.
- """
- def testSeconds(self):
- """
- Test that the L{seconds} method of the fake clock returns fake time.
- """
- c = task.Clock()
- self.assertEqual(c.seconds(), 0)
-
-
- def testCallLater(self):
- """
- Test that calls can be scheduled for later with the fake clock and
- hands back an L{IDelayedCall}.
- """
- c = task.Clock()
- call = c.callLater(1, lambda a, b: None, 1, b=2)
- self.failUnless(interfaces.IDelayedCall.providedBy(call))
- self.assertEqual(call.getTime(), 1)
- self.failUnless(call.active())
-
-
- def testCallLaterCancelled(self):
- """
- Test that calls can be cancelled.
- """
- c = task.Clock()
- call = c.callLater(1, lambda a, b: None, 1, b=2)
- call.cancel()
- self.failIf(call.active())
-
-
- def test_callLaterOrdering(self):
- """
- Test that the DelayedCall returned is not one previously
- created.
- """
- c = task.Clock()
- call1 = c.callLater(10, lambda a, b: None, 1, b=2)
- call2 = c.callLater(1, lambda a, b: None, 3, b=4)
- self.failIf(call1 is call2)
-
-
- def testAdvance(self):
- """
- Test that advancing the clock will fire some calls.
- """
- events = []
- c = task.Clock()
- call = c.callLater(2, lambda: events.append(None))
- c.advance(1)
- self.assertEqual(events, [])
- c.advance(1)
- self.assertEqual(events, [None])
- self.failIf(call.active())
-
-
- def testAdvanceCancel(self):
- """
- Test attemping to cancel the call in a callback.
-
- AlreadyCalled should be raised, not for example a ValueError from
- removing the call from Clock.calls. This requires call.called to be
- set before the callback is called.
- """
- c = task.Clock()
- def cb():
- self.assertRaises(error.AlreadyCalled, call.cancel)
- call = c.callLater(1, cb)
- c.advance(1)
-
-
- def testCallLaterDelayed(self):
- """
- Test that calls can be delayed.
- """
- events = []
- c = task.Clock()
- call = c.callLater(1, lambda a, b: events.append((a, b)), 1, b=2)
- call.delay(1)
- self.assertEqual(call.getTime(), 2)
- c.advance(1.5)
- self.assertEqual(events, [])
- c.advance(1.0)
- self.assertEqual(events, [(1, 2)])
-
-
- def testCallLaterResetLater(self):
- """
- Test that calls can have their time reset to a later time.
- """
- events = []
- c = task.Clock()
- call = c.callLater(2, lambda a, b: events.append((a, b)), 1, b=2)
- c.advance(1)
- call.reset(3)
- self.assertEqual(call.getTime(), 4)
- c.advance(2)
- self.assertEqual(events, [])
- c.advance(1)
- self.assertEqual(events, [(1, 2)])
-
-
- def testCallLaterResetSooner(self):
- """
- Test that calls can have their time reset to an earlier time.
- """
- events = []
- c = task.Clock()
- call = c.callLater(4, lambda a, b: events.append((a, b)), 1, b=2)
- call.reset(3)
- self.assertEqual(call.getTime(), 3)
- c.advance(3)
- self.assertEqual(events, [(1, 2)])
-
-
- def test_getDelayedCalls(self):
- """
- Test that we can get a list of all delayed calls
- """
- c = task.Clock()
- call = c.callLater(1, lambda x: None)
- call2 = c.callLater(2, lambda x: None)
-
- calls = c.getDelayedCalls()
-
- self.assertEqual(set([call, call2]), set(calls))
-
-
- def test_getDelayedCallsEmpty(self):
- """
- Test that we get an empty list from getDelayedCalls on a newly
- constructed Clock.
- """
- c = task.Clock()
- self.assertEqual(c.getDelayedCalls(), [])
-
-
- def test_providesIReactorTime(self):
- c = task.Clock()
- self.failUnless(interfaces.IReactorTime.providedBy(c),
- "Clock does not provide IReactorTime")
-
-
- def test_callLaterKeepsCallsOrdered(self):
- """
- The order of calls scheduled by L{task.Clock.callLater} is honored when
- adding a new call via calling L{task.Clock.callLater} again.
-
- For example, if L{task.Clock.callLater} is invoked with a callable "A"
- and a time t0, and then the L{IDelayedCall} which results from that is
- C{reset} to a later time t2 which is greater than t0, and I{then}
- L{task.Clock.callLater} is invoked again with a callable "B", and time
- t1 which is less than t2 but greater than t0, "B" will be invoked before
- "A".
- """
- result = []
- expected = [('b', 2.0), ('a', 3.0)]
- clock = task.Clock()
- logtime = lambda n: result.append((n, clock.seconds()))
-
- call_a = clock.callLater(1.0, logtime, "a")
- call_a.reset(3.0)
- clock.callLater(2.0, logtime, "b")
-
- clock.pump([1]*3)
- self.assertEqual(result, expected)
-
-
- def test_callLaterResetKeepsCallsOrdered(self):
- """
- The order of calls scheduled by L{task.Clock.callLater} is honored when
- re-scheduling an existing call via L{IDelayedCall.reset} on the result
- of a previous call to C{callLater}.
-
- For example, if L{task.Clock.callLater} is invoked with a callable "A"
- and a time t0, and then L{task.Clock.callLater} is invoked again with a
- callable "B", and time t1 greater than t0, and finally the
- L{IDelayedCall} for "A" is C{reset} to a later time, t2, which is
- greater than t1, "B" will be invoked before "A".
- """
- result = []
- expected = [('b', 2.0), ('a', 3.0)]
- clock = task.Clock()
- logtime = lambda n: result.append((n, clock.seconds()))
-
- call_a = clock.callLater(1.0, logtime, "a")
- clock.callLater(2.0, logtime, "b")
- call_a.reset(3.0)
-
- clock.pump([1]*3)
- self.assertEqual(result, expected)
-
-
- def test_callLaterResetInsideCallKeepsCallsOrdered(self):
- """
- The order of calls scheduled by L{task.Clock.callLater} is honored when
- re-scheduling an existing call via L{IDelayedCall.reset} on the result
- of a previous call to C{callLater}, even when that call to C{reset}
- occurs within the callable scheduled by C{callLater} itself.
- """
- result = []
- expected = [('c', 3.0), ('b', 4.0)]
- clock = task.Clock()
- logtime = lambda n: result.append((n, clock.seconds()))
-
- call_b = clock.callLater(2.0, logtime, "b")
- def a():
- call_b.reset(3.0)
-
- clock.callLater(1.0, a)
- clock.callLater(3.0, logtime, "c")
-
- clock.pump([0.5] * 10)
- self.assertEqual(result, expected)
-
-
-
-class LoopTestCase(unittest.TestCase):
- """
- Tests for L{task.LoopingCall} based on a fake L{IReactorTime}
- implementation.
- """
- def test_defaultClock(self):
- """
- L{LoopingCall}'s default clock should be the reactor.
- """
- call = task.LoopingCall(lambda: None)
- self.assertEqual(call.clock, reactor)
-
-
- def test_callbackTimeSkips(self):
- """
- When more time than the defined interval passes during the execution
- of a callback, L{LoopingCall} should schedule the next call for the
- next interval which is still in the future.
- """
- times = []
- callDuration = None
- clock = task.Clock()
- def aCallback():
- times.append(clock.seconds())
- clock.advance(callDuration)
- call = task.LoopingCall(aCallback)
- call.clock = clock
-
- # Start a LoopingCall with a 0.5 second increment, and immediately call
- # the callable.
- callDuration = 2
- call.start(0.5)
-
- # Verify that the callable was called, and since it was immediate, with
- # no skips.
- self.assertEqual(times, [0])
-
- # The callback should have advanced the clock by the callDuration.
- self.assertEqual(clock.seconds(), callDuration)
-
- # An iteration should have occurred at 2, but since 2 is the present
- # and not the future, it is skipped.
-
- clock.advance(0)
- self.assertEqual(times, [0])
-
- # 2.5 is in the future, and is not skipped.
- callDuration = 1
- clock.advance(0.5)
- self.assertEqual(times, [0, 2.5])
- self.assertEqual(clock.seconds(), 3.5)
-
- # Another iteration should have occurred, but it is again the
- # present and not the future, so it is skipped as well.
- clock.advance(0)
- self.assertEqual(times, [0, 2.5])
-
- # 4 is in the future, and is not skipped.
- callDuration = 0
- clock.advance(0.5)
- self.assertEqual(times, [0, 2.5, 4])
- self.assertEqual(clock.seconds(), 4)
-
-
- def test_reactorTimeSkips(self):
- """
- When more time than the defined interval passes between when
- L{LoopingCall} schedules itself to run again and when it actually
- runs again, it should schedule the next call for the next interval
- which is still in the future.
- """
- times = []
- clock = task.Clock()
- def aCallback():
- times.append(clock.seconds())
-
- # Start a LoopingCall that tracks the time passed, with a 0.5 second
- # increment.
- call = task.LoopingCall(aCallback)
- call.clock = clock
- call.start(0.5)
-
- # Initially, no time should have passed!
- self.assertEqual(times, [0])
-
- # Advance the clock by 2 seconds (2 seconds should have passed)
- clock.advance(2)
- self.assertEqual(times, [0, 2])
-
- # Advance the clock by 1 second (3 total should have passed)
- clock.advance(1)
- self.assertEqual(times, [0, 2, 3])
-
- # Advance the clock by 0 seconds (this should have no effect!)
- clock.advance(0)
- self.assertEqual(times, [0, 2, 3])
-
-
- def test_reactorTimeCountSkips(self):
- """
- When L{LoopingCall} schedules itself to run again, if more than the
- specified interval has passed, it should schedule the next call for the
- next interval which is still in the future. If it was created
- using L{LoopingCall.withCount}, a positional argument will be
- inserted at the beginning of the argument list, indicating the number
- of calls that should have been made.
- """
- times = []
- clock = task.Clock()
- def aCallback(numCalls):
- times.append((clock.seconds(), numCalls))
-
- # Start a LoopingCall that tracks the time passed, and the number of
- # skips, with a 0.5 second increment.
- call = task.LoopingCall.withCount(aCallback)
- call.clock = clock
- INTERVAL = 0.5
- REALISTIC_DELAY = 0.01
- call.start(INTERVAL)
-
- # Initially, no seconds should have passed, and one calls should have
- # been made.
- self.assertEqual(times, [(0, 1)])
-
- # After the interval (plus a small delay, to account for the time that
- # the reactor takes to wake up and process the LoopingCall), we should
- # still have only made one call.
- clock.advance(INTERVAL + REALISTIC_DELAY)
- self.assertEqual(times, [(0, 1), (INTERVAL + REALISTIC_DELAY, 1)])
-
- # After advancing the clock by three intervals (plus a small delay to
- # account for the reactor), we should have skipped two calls; one less
- # than the number of intervals which have completely elapsed. Along
- # with the call we did actually make, the final number of calls is 3.
- clock.advance((3 * INTERVAL) + REALISTIC_DELAY)
- self.assertEqual(times,
- [(0, 1), (INTERVAL + REALISTIC_DELAY, 1),
- ((4 * INTERVAL) + (2 * REALISTIC_DELAY), 3)])
-
- # Advancing the clock by 0 seconds should not cause any changes!
- clock.advance(0)
- self.assertEqual(times,
- [(0, 1), (INTERVAL + REALISTIC_DELAY, 1),
- ((4 * INTERVAL) + (2 * REALISTIC_DELAY), 3)])
-
-
- def test_countLengthyIntervalCounts(self):
- """
- L{LoopingCall.withCount} counts only calls that were expected to be
- made. So, if more than one, but less than two intervals pass between
- invocations, it won't increase the count above 1. For example, a
- L{LoopingCall} with interval T expects to be invoked at T, 2T, 3T, etc.
- However, the reactor takes some time to get around to calling it, so in
- practice it will be called at T+something, 2T+something, 3T+something;
- and due to other things going on in the reactor, "something" is
- variable. It won't increase the count unless "something" is greater
- than T. So if the L{LoopingCall} is invoked at T, 2.75T, and 3T,
- the count has not increased, even though the distance between
- invocation 1 and invocation 2 is 1.75T.
- """
- times = []
- clock = task.Clock()
- def aCallback(count):
- times.append((clock.seconds(), count))
-
- # Start a LoopingCall that tracks the time passed, and the number of
- # calls, with a 0.5 second increment.
- call = task.LoopingCall.withCount(aCallback)
- call.clock = clock
- INTERVAL = 0.5
- REALISTIC_DELAY = 0.01
- call.start(INTERVAL)
- self.assertEqual(times.pop(), (0, 1))
-
- # About one interval... So far, so good
- clock.advance(INTERVAL + REALISTIC_DELAY)
- self.assertEqual(times.pop(), (INTERVAL + REALISTIC_DELAY, 1))
-
- # Oh no, something delayed us for a while.
- clock.advance(INTERVAL * 1.75)
- self.assertEqual(times.pop(), ((2.75 * INTERVAL) + REALISTIC_DELAY, 1))
-
- # Back on track! We got invoked when we expected this time.
- clock.advance(INTERVAL * 0.25)
- self.assertEqual(times.pop(), ((3.0 * INTERVAL) + REALISTIC_DELAY, 1))
-
-
- def testBasicFunction(self):
- # Arrange to have time advanced enough so that our function is
- # called a few times.
- # Only need to go to 2.5 to get 3 calls, since the first call
- # happens before any time has elapsed.
- timings = [0.05, 0.1, 0.1]
-
- clock = task.Clock()
-
- L = []
- def foo(a, b, c=None, d=None):
- L.append((a, b, c, d))
-
- lc = TestableLoopingCall(clock, foo, "a", "b", d="d")
- D = lc.start(0.1)
-
- theResult = []
- def saveResult(result):
- theResult.append(result)
- D.addCallback(saveResult)
-
- clock.pump(timings)
-
- self.assertEqual(len(L), 3,
- "got %d iterations, not 3" % (len(L),))
-
- for (a, b, c, d) in L:
- self.assertEqual(a, "a")
- self.assertEqual(b, "b")
- self.assertEqual(c, None)
- self.assertEqual(d, "d")
-
- lc.stop()
- self.assertIdentical(theResult[0], lc)
-
- # Make sure it isn't planning to do anything further.
- self.failIf(clock.calls)
-
-
- def testDelayedStart(self):
- timings = [0.05, 0.1, 0.1]
-
- clock = task.Clock()
-
- L = []
- lc = TestableLoopingCall(clock, L.append, None)
- d = lc.start(0.1, now=False)
-
- theResult = []
- def saveResult(result):
- theResult.append(result)
- d.addCallback(saveResult)
-
- clock.pump(timings)
-
- self.assertEqual(len(L), 2,
- "got %d iterations, not 2" % (len(L),))
- lc.stop()
- self.assertIdentical(theResult[0], lc)
-
- self.failIf(clock.calls)
-
-
- def testBadDelay(self):
- lc = task.LoopingCall(lambda: None)
- self.assertRaises(ValueError, lc.start, -1)
-
-
- # Make sure that LoopingCall.stop() prevents any subsequent calls.
- def _stoppingTest(self, delay):
- ran = []
- def foo():
- ran.append(None)
-
- clock = task.Clock()
- lc = TestableLoopingCall(clock, foo)
- lc.start(delay, now=False)
- lc.stop()
- self.failIf(ran)
- self.failIf(clock.calls)
-
-
- def testStopAtOnce(self):
- return self._stoppingTest(0)
-
-
- def testStoppingBeforeDelayedStart(self):
- return self._stoppingTest(10)
-
-
- def test_reset(self):
- """
- Test that L{LoopingCall} can be reset.
- """
- ran = []
- def foo():
- ran.append(None)
-
- c = task.Clock()
- lc = TestableLoopingCall(c, foo)
- lc.start(2, now=False)
- c.advance(1)
- lc.reset()
- c.advance(1)
- self.assertEqual(ran, [])
- c.advance(1)
- self.assertEqual(ran, [None])
-
-
-
-class ReactorLoopTestCase(unittest.TestCase):
- # Slightly inferior tests which exercise interactions with an actual
- # reactor.
- def testFailure(self):
- def foo(x):
- raise TestException(x)
-
- lc = task.LoopingCall(foo, "bar")
- return self.assertFailure(lc.start(0.1), TestException)
-
-
- def testFailAndStop(self):
- def foo(x):
- lc.stop()
- raise TestException(x)
-
- lc = task.LoopingCall(foo, "bar")
- return self.assertFailure(lc.start(0.1), TestException)
-
-
- def testEveryIteration(self):
- ran = []
-
- def foo():
- ran.append(None)
- if len(ran) > 5:
- lc.stop()
-
- lc = task.LoopingCall(foo)
- d = lc.start(0)
- def stopped(ign):
- self.assertEqual(len(ran), 6)
- return d.addCallback(stopped)
-
-
- def testStopAtOnceLater(self):
- # Ensure that even when LoopingCall.stop() is called from a
- # reactor callback, it still prevents any subsequent calls.
- d = defer.Deferred()
- def foo():
- d.errback(failure.DefaultException(
- "This task also should never get called."))
- self._lc = task.LoopingCall(foo)
- self._lc.start(1, now=False)
- reactor.callLater(0, self._callback_for_testStopAtOnceLater, d)
- return d
-
-
- def _callback_for_testStopAtOnceLater(self, d):
- self._lc.stop()
- reactor.callLater(0, d.callback, "success")
-
- def testWaitDeferred(self):
- # Tests if the callable isn't scheduled again before the returned
- # deferred has fired.
- timings = [0.2, 0.8]
- clock = task.Clock()
-
- def foo():
- d = defer.Deferred()
- d.addCallback(lambda _: lc.stop())
- clock.callLater(1, d.callback, None)
- return d
-
- lc = TestableLoopingCall(clock, foo)
- lc.start(0.2)
- clock.pump(timings)
- self.failIf(clock.calls)
-
- def testFailurePropagation(self):
- # Tests if the failure of the errback of the deferred returned by the
- # callable is propagated to the lc errback.
- #
- # To make sure this test does not hang trial when LoopingCall does not
- # wait for the callable's deferred, it also checks there are no
- # calls in the clock's callLater queue.
- timings = [0.3]
- clock = task.Clock()
-
- def foo():
- d = defer.Deferred()
- clock.callLater(0.3, d.errback, TestException())
- return d
-
- lc = TestableLoopingCall(clock, foo)
- d = lc.start(1)
- self.assertFailure(d, TestException)
-
- clock.pump(timings)
- self.failIf(clock.calls)
- return d
-
-
- def test_deferredWithCount(self):
- """
- In the case that the function passed to L{LoopingCall.withCount}
- returns a deferred, which does not fire before the next interval
- elapses, the function should not be run again. And if a function call
- is skipped in this fashion, the appropriate count should be
- provided.
- """
- testClock = task.Clock()
- d = defer.Deferred()
- deferredCounts = []
-
- def countTracker(possibleCount):
- # Keep a list of call counts
- deferredCounts.append(possibleCount)
- # Return a deferred, but only on the first request
- if len(deferredCounts) == 1:
- return d
- else:
- return None
-
- # Start a looping call for our countTracker function
- # Set the increment to 0.2, and do not call the function on startup.
- lc = task.LoopingCall.withCount(countTracker)
- lc.clock = testClock
- d = lc.start(0.2, now=False)
-
- # Confirm that nothing has happened yet.
- self.assertEqual(deferredCounts, [])
-
- # Advance the clock by 0.2 and then 0.4;
- testClock.pump([0.2, 0.4])
- # We should now have exactly one count (of 1 call)
- self.assertEqual(len(deferredCounts), 1)
-
- # Fire the deferred, and advance the clock by another 0.2
- d.callback(None)
- testClock.pump([0.2])
- # We should now have exactly 2 counts...
- self.assertEqual(len(deferredCounts), 2)
- # The first count should be 1 (one call)
- # The second count should be 3 (calls were missed at about 0.6 and 0.8)
- self.assertEqual(deferredCounts, [1, 3])
-
-
-
-class DeferLaterTests(unittest.TestCase):
- """
- Tests for L{task.deferLater}.
- """
- def test_callback(self):
- """
- The L{Deferred} returned by L{task.deferLater} is called back after
- the specified delay with the result of the function passed in.
- """
- results = []
- flag = object()
- def callable(foo, bar):
- results.append((foo, bar))
- return flag
-
- clock = task.Clock()
- d = task.deferLater(clock, 3, callable, 'foo', bar='bar')
- d.addCallback(self.assertIdentical, flag)
- clock.advance(2)
- self.assertEqual(results, [])
- clock.advance(1)
- self.assertEqual(results, [('foo', 'bar')])
- return d
-
-
- def test_errback(self):
- """
- The L{Deferred} returned by L{task.deferLater} is errbacked if the
- supplied function raises an exception.
- """
- def callable():
- raise TestException()
-
- clock = task.Clock()
- d = task.deferLater(clock, 1, callable)
- clock.advance(1)
- return self.assertFailure(d, TestException)
-
-
- def test_cancel(self):
- """
- The L{Deferred} returned by L{task.deferLater} can be
- cancelled to prevent the call from actually being performed.
- """
- called = []
- clock = task.Clock()
- d = task.deferLater(clock, 1, called.append, None)
- d.cancel()
- def cbCancelled(ignored):
- # Make sure there are no calls outstanding.
- self.assertEqual([], clock.getDelayedCalls())
- # And make sure the call didn't somehow happen already.
- self.assertFalse(called)
- self.assertFailure(d, defer.CancelledError)
- d.addCallback(cbCancelled)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp.py
deleted file mode 100755
index aac88881..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp.py
+++ /dev/null
@@ -1,1820 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorTCP}.
-"""
-
-import socket, random, errno
-
-from zope.interface import implements
-
-from twisted.trial import unittest
-
-from twisted.python.log import msg
-from twisted.internet import protocol, reactor, defer, interfaces
-from twisted.internet import error
-from twisted.internet.address import IPv4Address
-from twisted.internet.interfaces import IHalfCloseableProtocol, IPullProducer
-from twisted.protocols import policies
-from twisted.test.proto_helpers import AccumulatingProtocol
-
-
-def loopUntil(predicate, interval=0):
- """
- Poor excuse for an event notification helper. This polls a condition and
- calls back a Deferred when it is seen to be true.
-
- Do not use this function.
- """
- from twisted.internet import task
- d = defer.Deferred()
- def check():
- res = predicate()
- if res:
- d.callback(res)
- call = task.LoopingCall(check)
- def stop(result):
- call.stop()
- return result
- d.addCallback(stop)
- d2 = call.start(interval)
- d2.addErrback(d.errback)
- return d
-
-
-
-class ClosingProtocol(protocol.Protocol):
-
- def connectionMade(self):
- msg("ClosingProtocol.connectionMade")
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- msg("ClosingProtocol.connectionLost")
- reason.trap(error.ConnectionDone)
-
-
-
-class ClosingFactory(protocol.ServerFactory):
- """
- Factory that closes port immediately.
- """
-
- _cleanerUpper = None
-
- def buildProtocol(self, conn):
- self._cleanerUpper = self.port.stopListening()
- return ClosingProtocol()
-
-
- def cleanUp(self):
- """
- Clean-up for tests to wait for the port to stop listening.
- """
- if self._cleanerUpper is None:
- return self.port.stopListening()
- return self._cleanerUpper
-
-
-
-class MyProtocolFactoryMixin(object):
- """
- Mixin for factories which create L{AccumulatingProtocol} instances.
-
- @type protocolFactory: no-argument callable
- @ivar protocolFactory: Factory for protocols - takes the place of the
- typical C{protocol} attribute of factories (but that name is used by
- this class for something else).
-
- @type protocolConnectionMade: L{NoneType} or L{defer.Deferred}
- @ivar protocolConnectionMade: When an instance of L{AccumulatingProtocol}
- is connected, if this is not C{None}, the L{Deferred} will be called
- back with the protocol instance and the attribute set to C{None}.
-
- @type protocolConnectionLost: L{NoneType} or L{defer.Deferred}
- @ivar protocolConnectionLost: When an instance of L{AccumulatingProtocol}
- is created, this will be set as its C{closedDeferred} attribute and
- then this attribute will be set to C{None} so the L{defer.Deferred} is
- not used by more than one protocol.
-
- @ivar protocol: The most recently created L{AccumulatingProtocol} instance
- which was returned from C{buildProtocol}.
-
- @type called: C{int}
- @ivar called: A counter which is incremented each time C{buildProtocol}
- is called.
-
- @ivar peerAddresses: A C{list} of the addresses passed to C{buildProtocol}.
- """
- protocolFactory = AccumulatingProtocol
-
- protocolConnectionMade = None
- protocolConnectionLost = None
- protocol = None
- called = 0
-
- def __init__(self):
- self.peerAddresses = []
-
-
- def buildProtocol(self, addr):
- """
- Create a L{AccumulatingProtocol} and set it up to be able to perform
- callbacks.
- """
- self.peerAddresses.append(addr)
- self.called += 1
- p = self.protocolFactory()
- p.factory = self
- p.closedDeferred = self.protocolConnectionLost
- self.protocolConnectionLost = None
- self.protocol = p
- return p
-
-
-
-class MyServerFactory(MyProtocolFactoryMixin, protocol.ServerFactory):
- """
- Server factory which creates L{AccumulatingProtocol} instances.
- """
-
-
-
-class MyClientFactory(MyProtocolFactoryMixin, protocol.ClientFactory):
- """
- Client factory which creates L{AccumulatingProtocol} instances.
- """
- failed = 0
- stopped = 0
-
- def __init__(self):
- MyProtocolFactoryMixin.__init__(self)
- self.deferred = defer.Deferred()
- self.failDeferred = defer.Deferred()
-
- def clientConnectionFailed(self, connector, reason):
- self.failed = 1
- self.reason = reason
- self.failDeferred.callback(None)
-
- def clientConnectionLost(self, connector, reason):
- self.lostReason = reason
- self.deferred.callback(None)
-
- def stopFactory(self):
- self.stopped = 1
-
-
-
-class ListeningTestCase(unittest.TestCase):
-
- def test_listen(self):
- """
- L{IReactorTCP.listenTCP} returns an object which provides
- L{IListeningPort}.
- """
- f = MyServerFactory()
- p1 = reactor.listenTCP(0, f, interface="127.0.0.1")
- self.addCleanup(p1.stopListening)
- self.failUnless(interfaces.IListeningPort.providedBy(p1))
-
-
- def testStopListening(self):
- """
- The L{IListeningPort} returned by L{IReactorTCP.listenTCP} can be
- stopped with its C{stopListening} method. After the L{Deferred} it
- (optionally) returns has been called back, the port number can be bound
- to a new server.
- """
- f = MyServerFactory()
- port = reactor.listenTCP(0, f, interface="127.0.0.1")
- n = port.getHost().port
-
- def cbStopListening(ignored):
- # Make sure we can rebind the port right away
- port = reactor.listenTCP(n, f, interface="127.0.0.1")
- return port.stopListening()
-
- d = defer.maybeDeferred(port.stopListening)
- d.addCallback(cbStopListening)
- return d
-
-
- def testNumberedInterface(self):
- f = MyServerFactory()
- # listen only on the loopback interface
- p1 = reactor.listenTCP(0, f, interface='127.0.0.1')
- return p1.stopListening()
-
- def testPortRepr(self):
- f = MyServerFactory()
- p = reactor.listenTCP(0, f)
- portNo = str(p.getHost().port)
- self.failIf(repr(p).find(portNo) == -1)
- def stoppedListening(ign):
- self.failIf(repr(p).find(portNo) != -1)
- d = defer.maybeDeferred(p.stopListening)
- return d.addCallback(stoppedListening)
-
-
- def test_serverRepr(self):
- """
- Check that the repr string of the server transport get the good port
- number if the server listens on 0.
- """
- server = MyServerFactory()
- serverConnMade = server.protocolConnectionMade = defer.Deferred()
- port = reactor.listenTCP(0, server)
- self.addCleanup(port.stopListening)
-
- client = MyClientFactory()
- clientConnMade = client.protocolConnectionMade = defer.Deferred()
- connector = reactor.connectTCP("127.0.0.1",
- port.getHost().port, client)
- self.addCleanup(connector.disconnect)
- def check((serverProto, clientProto)):
- portNumber = port.getHost().port
- self.assertEqual(
- repr(serverProto.transport),
- "<AccumulatingProtocol #0 on %s>" % (portNumber,))
- serverProto.transport.loseConnection()
- clientProto.transport.loseConnection()
- return defer.gatherResults([serverConnMade, clientConnMade]
- ).addCallback(check)
-
-
- def test_restartListening(self):
- """
- Stop and then try to restart a L{tcp.Port}: after a restart, the
- server should be able to handle client connections.
- """
- serverFactory = MyServerFactory()
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
-
- def cbStopListening(ignored):
- port.startListening()
-
- client = MyClientFactory()
- serverFactory.protocolConnectionMade = defer.Deferred()
- client.protocolConnectionMade = defer.Deferred()
- connector = reactor.connectTCP("127.0.0.1",
- port.getHost().port, client)
- self.addCleanup(connector.disconnect)
- return defer.gatherResults([serverFactory.protocolConnectionMade,
- client.protocolConnectionMade]
- ).addCallback(close)
-
- def close((serverProto, clientProto)):
- clientProto.transport.loseConnection()
- serverProto.transport.loseConnection()
-
- d = defer.maybeDeferred(port.stopListening)
- d.addCallback(cbStopListening)
- return d
-
-
- def test_exceptInStop(self):
- """
- If the server factory raises an exception in C{stopFactory}, the
- deferred returned by L{tcp.Port.stopListening} should fail with the
- corresponding error.
- """
- serverFactory = MyServerFactory()
- def raiseException():
- raise RuntimeError("An error")
- serverFactory.stopFactory = raiseException
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
-
- return self.assertFailure(port.stopListening(), RuntimeError)
-
-
- def test_restartAfterExcept(self):
- """
- Even if the server factory raise an exception in C{stopFactory}, the
- corresponding C{tcp.Port} instance should be in a sane state and can
- be restarted.
- """
- serverFactory = MyServerFactory()
- def raiseException():
- raise RuntimeError("An error")
- serverFactory.stopFactory = raiseException
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
-
- def cbStopListening(ignored):
- del serverFactory.stopFactory
- port.startListening()
-
- client = MyClientFactory()
- serverFactory.protocolConnectionMade = defer.Deferred()
- client.protocolConnectionMade = defer.Deferred()
- connector = reactor.connectTCP("127.0.0.1",
- port.getHost().port, client)
- self.addCleanup(connector.disconnect)
- return defer.gatherResults([serverFactory.protocolConnectionMade,
- client.protocolConnectionMade]
- ).addCallback(close)
-
- def close((serverProto, clientProto)):
- clientProto.transport.loseConnection()
- serverProto.transport.loseConnection()
-
- return self.assertFailure(port.stopListening(), RuntimeError
- ).addCallback(cbStopListening)
-
-
- def test_directConnectionLostCall(self):
- """
- If C{connectionLost} is called directly on a port object, it succeeds
- (and doesn't expect the presence of a C{deferred} attribute).
-
- C{connectionLost} is called by L{reactor.disconnectAll} at shutdown.
- """
- serverFactory = MyServerFactory()
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
- portNumber = port.getHost().port
- port.connectionLost(None)
-
- client = MyClientFactory()
- serverFactory.protocolConnectionMade = defer.Deferred()
- client.protocolConnectionMade = defer.Deferred()
- reactor.connectTCP("127.0.0.1", portNumber, client)
- def check(ign):
- client.reason.trap(error.ConnectionRefusedError)
- return client.failDeferred.addCallback(check)
-
-
- def test_exceptInConnectionLostCall(self):
- """
- If C{connectionLost} is called directory on a port object and that the
- server factory raises an exception in C{stopFactory}, the exception is
- passed through to the caller.
-
- C{connectionLost} is called by L{reactor.disconnectAll} at shutdown.
- """
- serverFactory = MyServerFactory()
- def raiseException():
- raise RuntimeError("An error")
- serverFactory.stopFactory = raiseException
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
- self.assertRaises(RuntimeError, port.connectionLost, None)
-
-
-
-def callWithSpew(f):
- from twisted.python.util import spewerWithLinenums as spewer
- import sys
- sys.settrace(spewer)
- try:
- f()
- finally:
- sys.settrace(None)
-
-class LoopbackTestCase(unittest.TestCase):
- """
- Test loopback connections.
- """
- def test_closePortInProtocolFactory(self):
- """
- A port created with L{IReactorTCP.listenTCP} can be connected to with
- L{IReactorTCP.connectTCP}.
- """
- f = ClosingFactory()
- port = reactor.listenTCP(0, f, interface="127.0.0.1")
- f.port = port
- self.addCleanup(f.cleanUp)
- portNumber = port.getHost().port
- clientF = MyClientFactory()
- reactor.connectTCP("127.0.0.1", portNumber, clientF)
- def check(x):
- self.assertTrue(clientF.protocol.made)
- self.assertTrue(port.disconnected)
- clientF.lostReason.trap(error.ConnectionDone)
- return clientF.deferred.addCallback(check)
-
- def _trapCnxDone(self, obj):
- getattr(obj, 'trap', lambda x: None)(error.ConnectionDone)
-
-
- def _connectedClientAndServerTest(self, callback):
- """
- Invoke the given callback with a client protocol and a server protocol
- which have been connected to each other.
- """
- serverFactory = MyServerFactory()
- serverConnMade = defer.Deferred()
- serverFactory.protocolConnectionMade = serverConnMade
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
-
- portNumber = port.getHost().port
- clientF = MyClientFactory()
- clientConnMade = defer.Deferred()
- clientF.protocolConnectionMade = clientConnMade
- reactor.connectTCP("127.0.0.1", portNumber, clientF)
-
- connsMade = defer.gatherResults([serverConnMade, clientConnMade])
- def connected((serverProtocol, clientProtocol)):
- callback(serverProtocol, clientProtocol)
- serverProtocol.transport.loseConnection()
- clientProtocol.transport.loseConnection()
- connsMade.addCallback(connected)
- return connsMade
-
-
- def test_tcpNoDelay(self):
- """
- The transport of a protocol connected with L{IReactorTCP.connectTCP} or
- L{IReactor.TCP.listenTCP} can have its I{TCP_NODELAY} state inspected
- and manipulated with L{ITCPTransport.getTcpNoDelay} and
- L{ITCPTransport.setTcpNoDelay}.
- """
- def check(serverProtocol, clientProtocol):
- for p in [serverProtocol, clientProtocol]:
- transport = p.transport
- self.assertEqual(transport.getTcpNoDelay(), 0)
- transport.setTcpNoDelay(1)
- self.assertEqual(transport.getTcpNoDelay(), 1)
- transport.setTcpNoDelay(0)
- self.assertEqual(transport.getTcpNoDelay(), 0)
- return self._connectedClientAndServerTest(check)
-
-
- def test_tcpKeepAlive(self):
- """
- The transport of a protocol connected with L{IReactorTCP.connectTCP} or
- L{IReactor.TCP.listenTCP} can have its I{SO_KEEPALIVE} state inspected
- and manipulated with L{ITCPTransport.getTcpKeepAlive} and
- L{ITCPTransport.setTcpKeepAlive}.
- """
- def check(serverProtocol, clientProtocol):
- for p in [serverProtocol, clientProtocol]:
- transport = p.transport
- self.assertEqual(transport.getTcpKeepAlive(), 0)
- transport.setTcpKeepAlive(1)
- self.assertEqual(transport.getTcpKeepAlive(), 1)
- transport.setTcpKeepAlive(0)
- self.assertEqual(transport.getTcpKeepAlive(), 0)
- return self._connectedClientAndServerTest(check)
-
-
- def testFailing(self):
- clientF = MyClientFactory()
- # XXX we assume no one is listening on TCP port 69
- reactor.connectTCP("127.0.0.1", 69, clientF, timeout=5)
- def check(ignored):
- clientF.reason.trap(error.ConnectionRefusedError)
- return clientF.failDeferred.addCallback(check)
-
-
- def test_connectionRefusedErrorNumber(self):
- """
- Assert that the error number of the ConnectionRefusedError is
- ECONNREFUSED, and not some other socket related error.
- """
-
- # Bind a number of ports in the operating system. We will attempt
- # to connect to these in turn immediately after closing them, in the
- # hopes that no one else has bound them in the mean time. Any
- # connection which succeeds is ignored and causes us to move on to
- # the next port. As soon as a connection attempt fails, we move on
- # to making an assertion about how it failed. If they all succeed,
- # the test will fail.
-
- # It would be nice to have a simpler, reliable way to cause a
- # connection failure from the platform.
- #
- # On Linux (2.6.15), connecting to port 0 always fails. FreeBSD
- # (5.4) rejects the connection attempt with EADDRNOTAVAIL.
- #
- # On FreeBSD (5.4), listening on a port and then repeatedly
- # connecting to it without ever accepting any connections eventually
- # leads to an ECONNREFUSED. On Linux (2.6.15), a seemingly
- # unbounded number of connections succeed.
-
- serverSockets = []
- for i in xrange(10):
- serverSocket = socket.socket()
- serverSocket.bind(('127.0.0.1', 0))
- serverSocket.listen(1)
- serverSockets.append(serverSocket)
- random.shuffle(serverSockets)
-
- clientCreator = protocol.ClientCreator(reactor, protocol.Protocol)
-
- def tryConnectFailure():
- def connected(proto):
- """
- Darn. Kill it and try again, if there are any tries left.
- """
- proto.transport.loseConnection()
- if serverSockets:
- return tryConnectFailure()
- self.fail("Could not fail to connect - could not test errno for that case.")
-
- serverSocket = serverSockets.pop()
- serverHost, serverPort = serverSocket.getsockname()
- serverSocket.close()
-
- connectDeferred = clientCreator.connectTCP(serverHost, serverPort)
- connectDeferred.addCallback(connected)
- return connectDeferred
-
- refusedDeferred = tryConnectFailure()
- self.assertFailure(refusedDeferred, error.ConnectionRefusedError)
- def connRefused(exc):
- self.assertEqual(exc.osError, errno.ECONNREFUSED)
- refusedDeferred.addCallback(connRefused)
- def cleanup(passthrough):
- while serverSockets:
- serverSockets.pop().close()
- return passthrough
- refusedDeferred.addBoth(cleanup)
- return refusedDeferred
-
-
- def test_connectByServiceFail(self):
- """
- Connecting to a named service which does not exist raises
- L{error.ServiceNameUnknownError}.
- """
- self.assertRaises(
- error.ServiceNameUnknownError,
- reactor.connectTCP,
- "127.0.0.1", "thisbetternotexist", MyClientFactory())
-
-
- def test_connectByService(self):
- """
- L{IReactorTCP.connectTCP} accepts the name of a service instead of a
- port number and connects to the port number associated with that
- service, as defined by L{socket.getservbyname}.
- """
- serverFactory = MyServerFactory()
- serverConnMade = defer.Deferred()
- serverFactory.protocolConnectionMade = serverConnMade
- port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
- self.addCleanup(port.stopListening)
- portNumber = port.getHost().port
- clientFactory = MyClientFactory()
- clientConnMade = defer.Deferred()
- clientFactory.protocolConnectionMade = clientConnMade
-
- def fakeGetServicePortByName(serviceName, protocolName):
- if serviceName == 'http' and protocolName == 'tcp':
- return portNumber
- return 10
- self.patch(socket, 'getservbyname', fakeGetServicePortByName)
-
- reactor.connectTCP('127.0.0.1', 'http', clientFactory)
-
- connMade = defer.gatherResults([serverConnMade, clientConnMade])
- def connected((serverProtocol, clientProtocol)):
- self.assertTrue(
- serverFactory.called,
- "Server factory was not called upon to build a protocol.")
- serverProtocol.transport.loseConnection()
- clientProtocol.transport.loseConnection()
- connMade.addCallback(connected)
- return connMade
-
-
-class StartStopFactory(protocol.Factory):
-
- started = 0
- stopped = 0
-
- def startFactory(self):
- if self.started or self.stopped:
- raise RuntimeError
- self.started = 1
-
- def stopFactory(self):
- if not self.started or self.stopped:
- raise RuntimeError
- self.stopped = 1
-
-
-class ClientStartStopFactory(MyClientFactory):
-
- started = 0
- stopped = 0
-
- def __init__(self, *a, **kw):
- MyClientFactory.__init__(self, *a, **kw)
- self.whenStopped = defer.Deferred()
-
- def startFactory(self):
- if self.started or self.stopped:
- raise RuntimeError
- self.started = 1
-
- def stopFactory(self):
- if not self.started or self.stopped:
- raise RuntimeError
- self.stopped = 1
- self.whenStopped.callback(True)
-
-
-class FactoryTestCase(unittest.TestCase):
- """Tests for factories."""
-
- def test_serverStartStop(self):
- """
- The factory passed to L{IReactorTCP.listenTCP} should be started only
- when it transitions from being used on no ports to being used on one
- port and should be stopped only when it transitions from being used on
- one port to being used on no ports.
- """
- # Note - this test doesn't need to use listenTCP. It is exercising
- # logic implemented in Factory.doStart and Factory.doStop, so it could
- # just call that directly. Some other test can make sure that
- # listenTCP and stopListening correctly call doStart and
- # doStop. -exarkun
-
- f = StartStopFactory()
-
- # listen on port
- p1 = reactor.listenTCP(0, f, interface='127.0.0.1')
- self.addCleanup(p1.stopListening)
-
- self.assertEqual((f.started, f.stopped), (1, 0))
-
- # listen on two more ports
- p2 = reactor.listenTCP(0, f, interface='127.0.0.1')
- p3 = reactor.listenTCP(0, f, interface='127.0.0.1')
-
- self.assertEqual((f.started, f.stopped), (1, 0))
-
- # close two ports
- d1 = defer.maybeDeferred(p1.stopListening)
- d2 = defer.maybeDeferred(p2.stopListening)
- closedDeferred = defer.gatherResults([d1, d2])
- def cbClosed(ignored):
- self.assertEqual((f.started, f.stopped), (1, 0))
- # Close the last port
- return p3.stopListening()
- closedDeferred.addCallback(cbClosed)
-
- def cbClosedAll(ignored):
- self.assertEqual((f.started, f.stopped), (1, 1))
- closedDeferred.addCallback(cbClosedAll)
- return closedDeferred
-
-
- def test_clientStartStop(self):
- """
- The factory passed to L{IReactorTCP.connectTCP} should be started when
- the connection attempt starts and stopped when it is over.
- """
- f = ClosingFactory()
- p = reactor.listenTCP(0, f, interface="127.0.0.1")
- f.port = p
- self.addCleanup(f.cleanUp)
- portNumber = p.getHost().port
-
- factory = ClientStartStopFactory()
- reactor.connectTCP("127.0.0.1", portNumber, factory)
- self.assertTrue(factory.started)
- return loopUntil(lambda: factory.stopped)
-
-
-
-class CannotBindTestCase(unittest.TestCase):
- """
- Tests for correct behavior when a reactor cannot bind to the required TCP
- port.
- """
-
- def test_cannotBind(self):
- """
- L{IReactorTCP.listenTCP} raises L{error.CannotListenError} if the
- address to listen on is already in use.
- """
- f = MyServerFactory()
-
- p1 = reactor.listenTCP(0, f, interface='127.0.0.1')
- self.addCleanup(p1.stopListening)
- n = p1.getHost().port
- dest = p1.getHost()
- self.assertEqual(dest.type, "TCP")
- self.assertEqual(dest.host, "127.0.0.1")
- self.assertEqual(dest.port, n)
-
- # make sure new listen raises error
- self.assertRaises(error.CannotListenError,
- reactor.listenTCP, n, f, interface='127.0.0.1')
-
-
-
- def _fireWhenDoneFunc(self, d, f):
- """Returns closure that when called calls f and then callbacks d.
- """
- from twisted.python import util as tputil
- def newf(*args, **kw):
- rtn = f(*args, **kw)
- d.callback('')
- return rtn
- return tputil.mergeFunctionMetadata(f, newf)
-
-
- def test_clientBind(self):
- """
- L{IReactorTCP.connectTCP} calls C{Factory.clientConnectionFailed} with
- L{error.ConnectBindError} if the bind address specified is already in
- use.
- """
- theDeferred = defer.Deferred()
- sf = MyServerFactory()
- sf.startFactory = self._fireWhenDoneFunc(theDeferred, sf.startFactory)
- p = reactor.listenTCP(0, sf, interface="127.0.0.1")
- self.addCleanup(p.stopListening)
-
- def _connect1(results):
- d = defer.Deferred()
- cf1 = MyClientFactory()
- cf1.buildProtocol = self._fireWhenDoneFunc(d, cf1.buildProtocol)
- reactor.connectTCP("127.0.0.1", p.getHost().port, cf1,
- bindAddress=("127.0.0.1", 0))
- d.addCallback(_conmade, cf1)
- return d
-
- def _conmade(results, cf1):
- d = defer.Deferred()
- cf1.protocol.connectionMade = self._fireWhenDoneFunc(
- d, cf1.protocol.connectionMade)
- d.addCallback(_check1connect2, cf1)
- return d
-
- def _check1connect2(results, cf1):
- self.assertEqual(cf1.protocol.made, 1)
-
- d1 = defer.Deferred()
- d2 = defer.Deferred()
- port = cf1.protocol.transport.getHost().port
- cf2 = MyClientFactory()
- cf2.clientConnectionFailed = self._fireWhenDoneFunc(
- d1, cf2.clientConnectionFailed)
- cf2.stopFactory = self._fireWhenDoneFunc(d2, cf2.stopFactory)
- reactor.connectTCP("127.0.0.1", p.getHost().port, cf2,
- bindAddress=("127.0.0.1", port))
- d1.addCallback(_check2failed, cf1, cf2)
- d2.addCallback(_check2stopped, cf1, cf2)
- dl = defer.DeferredList([d1, d2])
- dl.addCallback(_stop, cf1, cf2)
- return dl
-
- def _check2failed(results, cf1, cf2):
- self.assertEqual(cf2.failed, 1)
- cf2.reason.trap(error.ConnectBindError)
- self.assertTrue(cf2.reason.check(error.ConnectBindError))
- return results
-
- def _check2stopped(results, cf1, cf2):
- self.assertEqual(cf2.stopped, 1)
- return results
-
- def _stop(results, cf1, cf2):
- d = defer.Deferred()
- d.addCallback(_check1cleanup, cf1)
- cf1.stopFactory = self._fireWhenDoneFunc(d, cf1.stopFactory)
- cf1.protocol.transport.loseConnection()
- return d
-
- def _check1cleanup(results, cf1):
- self.assertEqual(cf1.stopped, 1)
-
- theDeferred.addCallback(_connect1)
- return theDeferred
-
-
-
-class MyOtherClientFactory(protocol.ClientFactory):
- def buildProtocol(self, address):
- self.address = address
- self.protocol = AccumulatingProtocol()
- return self.protocol
-
-
-
-class LocalRemoteAddressTestCase(unittest.TestCase):
- """
- Tests for correct getHost/getPeer values and that the correct address is
- passed to buildProtocol.
- """
- def test_hostAddress(self):
- """
- L{IListeningPort.getHost} returns the same address as a client
- connection's L{ITCPTransport.getPeer}.
- """
- serverFactory = MyServerFactory()
- serverFactory.protocolConnectionLost = defer.Deferred()
- serverConnectionLost = serverFactory.protocolConnectionLost
- port = reactor.listenTCP(0, serverFactory, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
- n = port.getHost().port
-
- clientFactory = MyClientFactory()
- onConnection = clientFactory.protocolConnectionMade = defer.Deferred()
- connector = reactor.connectTCP('127.0.0.1', n, clientFactory)
-
- def check(ignored):
- self.assertEqual([port.getHost()], clientFactory.peerAddresses)
- self.assertEqual(
- port.getHost(), clientFactory.protocol.transport.getPeer())
- onConnection.addCallback(check)
-
- def cleanup(ignored):
- # Clean up the client explicitly here so that tear down of
- # the server side of the connection begins, then wait for
- # the server side to actually disconnect.
- connector.disconnect()
- return serverConnectionLost
- onConnection.addCallback(cleanup)
-
- return onConnection
-
-
-
-class WriterProtocol(protocol.Protocol):
- def connectionMade(self):
- # use everything ITransport claims to provide. If something here
- # fails, the exception will be written to the log, but it will not
- # directly flunk the test. The test will fail when maximum number of
- # iterations have passed and the writer's factory.done has not yet
- # been set.
- self.transport.write("Hello Cleveland!\n")
- seq = ["Goodbye", " cruel", " world", "\n"]
- self.transport.writeSequence(seq)
- peer = self.transport.getPeer()
- if peer.type != "TCP":
- print "getPeer returned non-TCP socket:", peer
- self.factory.problem = 1
- us = self.transport.getHost()
- if us.type != "TCP":
- print "getHost returned non-TCP socket:", us
- self.factory.problem = 1
- self.factory.done = 1
-
- self.transport.loseConnection()
-
-class ReaderProtocol(protocol.Protocol):
- def dataReceived(self, data):
- self.factory.data += data
- def connectionLost(self, reason):
- self.factory.done = 1
-
-class WriterClientFactory(protocol.ClientFactory):
- def __init__(self):
- self.done = 0
- self.data = ""
- def buildProtocol(self, addr):
- p = ReaderProtocol()
- p.factory = self
- self.protocol = p
- return p
-
-class WriteDataTestCase(unittest.TestCase):
- """
- Test that connected TCP sockets can actually write data. Try to exercise
- the entire ITransport interface.
- """
-
- def test_writer(self):
- """
- L{ITCPTransport.write} and L{ITCPTransport.writeSequence} send bytes to
- the other end of the connection.
- """
- f = protocol.Factory()
- f.protocol = WriterProtocol
- f.done = 0
- f.problem = 0
- wrappedF = WiredFactory(f)
- p = reactor.listenTCP(0, wrappedF, interface="127.0.0.1")
- self.addCleanup(p.stopListening)
- n = p.getHost().port
- clientF = WriterClientFactory()
- wrappedClientF = WiredFactory(clientF)
- reactor.connectTCP("127.0.0.1", n, wrappedClientF)
-
- def check(ignored):
- self.failUnless(f.done, "writer didn't finish, it probably died")
- self.failUnless(f.problem == 0, "writer indicated an error")
- self.failUnless(clientF.done,
- "client didn't see connection dropped")
- expected = "".join(["Hello Cleveland!\n",
- "Goodbye", " cruel", " world", "\n"])
- self.failUnless(clientF.data == expected,
- "client didn't receive all the data it expected")
- d = defer.gatherResults([wrappedF.onDisconnect,
- wrappedClientF.onDisconnect])
- return d.addCallback(check)
-
-
- def test_writeAfterShutdownWithoutReading(self):
- """
- A TCP transport which is written to after the connection has been shut
- down should notify its protocol that the connection has been lost, even
- if the TCP transport is not actively being monitored for read events
- (ie, pauseProducing was called on it).
- """
- # This is an unpleasant thing. Generally tests shouldn't skip or
- # run based on the name of the reactor being used (most tests
- # shouldn't care _at all_ what reactor is being used, in fact). The
- # Gtk reactor cannot pass this test, though, because it fails to
- # implement IReactorTCP entirely correctly. Gtk is quite old at
- # this point, so it's more likely that gtkreactor will be deprecated
- # and removed rather than fixed to handle this case correctly.
- # Since this is a pre-existing (and very long-standing) issue with
- # the Gtk reactor, there's no reason for it to prevent this test
- # being added to exercise the other reactors, for which the behavior
- # was also untested but at least works correctly (now). See #2833
- # for information on the status of gtkreactor.
- if reactor.__class__.__name__ == 'IOCPReactor':
- raise unittest.SkipTest(
- "iocpreactor does not, in fact, stop reading immediately after "
- "pauseProducing is called. This results in a bonus disconnection "
- "notification. Under some circumstances, it might be possible to "
- "not receive this notifications (specifically, pauseProducing, "
- "deliver some data, proceed with this test).")
- if reactor.__class__.__name__ == 'GtkReactor':
- raise unittest.SkipTest(
- "gtkreactor does not implement unclean disconnection "
- "notification correctly. This might more properly be "
- "a todo, but due to technical limitations it cannot be.")
-
- # Called back after the protocol for the client side of the connection
- # has paused its transport, preventing it from reading, therefore
- # preventing it from noticing the disconnection before the rest of the
- # actions which are necessary to trigger the case this test is for have
- # been taken.
- clientPaused = defer.Deferred()
-
- # Called back when the protocol for the server side of the connection
- # has received connection lost notification.
- serverLost = defer.Deferred()
-
- class Disconnecter(protocol.Protocol):
- """
- Protocol for the server side of the connection which disconnects
- itself in a callback on clientPaused and publishes notification
- when its connection is actually lost.
- """
- def connectionMade(self):
- """
- Set up a callback on clientPaused to lose the connection.
- """
- msg('Disconnector.connectionMade')
- def disconnect(ignored):
- msg('Disconnector.connectionMade disconnect')
- self.transport.loseConnection()
- msg('loseConnection called')
- clientPaused.addCallback(disconnect)
-
- def connectionLost(self, reason):
- """
- Notify observers that the server side of the connection has
- ended.
- """
- msg('Disconnecter.connectionLost')
- serverLost.callback(None)
- msg('serverLost called back')
-
- # Create the server port to which a connection will be made.
- server = protocol.ServerFactory()
- server.protocol = Disconnecter
- port = reactor.listenTCP(0, server, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
- addr = port.getHost()
-
- class Infinite(object):
- """
- A producer which will write to its consumer as long as
- resumeProducing is called.
-
- @ivar consumer: The L{IConsumer} which will be written to.
- """
- implements(IPullProducer)
-
- def __init__(self, consumer):
- self.consumer = consumer
-
- def resumeProducing(self):
- msg('Infinite.resumeProducing')
- self.consumer.write('x')
- msg('Infinite.resumeProducing wrote to consumer')
-
- def stopProducing(self):
- msg('Infinite.stopProducing')
-
-
- class UnreadingWriter(protocol.Protocol):
- """
- Trivial protocol which pauses its transport immediately and then
- writes some bytes to it.
- """
- def connectionMade(self):
- msg('UnreadingWriter.connectionMade')
- self.transport.pauseProducing()
- clientPaused.callback(None)
- msg('clientPaused called back')
- def write(ignored):
- msg('UnreadingWriter.connectionMade write')
- # This needs to be enough bytes to spill over into the
- # userspace Twisted send buffer - if it all fits into
- # the kernel, Twisted won't even poll for OUT events,
- # which means it won't poll for any events at all, so
- # the disconnection is never noticed. This is due to
- # #1662. When #1662 is fixed, this test will likely
- # need to be adjusted, otherwise connection lost
- # notification will happen too soon and the test will
- # probably begin to fail with ConnectionDone instead of
- # ConnectionLost (in any case, it will no longer be
- # entirely correct).
- producer = Infinite(self.transport)
- msg('UnreadingWriter.connectionMade write created producer')
- self.transport.registerProducer(producer, False)
- msg('UnreadingWriter.connectionMade write registered producer')
- serverLost.addCallback(write)
-
- # Create the client and initiate the connection
- client = MyClientFactory()
- client.protocolFactory = UnreadingWriter
- clientConnectionLost = client.deferred
- def cbClientLost(ignored):
- msg('cbClientLost')
- return client.lostReason
- clientConnectionLost.addCallback(cbClientLost)
- msg('Connecting to %s:%s' % (addr.host, addr.port))
- reactor.connectTCP(addr.host, addr.port, client)
-
- # By the end of the test, the client should have received notification
- # of unclean disconnection.
- msg('Returning Deferred')
- return self.assertFailure(clientConnectionLost, error.ConnectionLost)
-
-
-
-class ConnectionLosingProtocol(protocol.Protocol):
- def connectionMade(self):
- self.transport.write("1")
- self.transport.loseConnection()
- self.master._connectionMade()
- self.master.ports.append(self.transport)
-
-
-
-class NoopProtocol(protocol.Protocol):
- def connectionMade(self):
- self.d = defer.Deferred()
- self.master.serverConns.append(self.d)
-
- def connectionLost(self, reason):
- self.d.callback(True)
-
-
-
-class ConnectionLostNotifyingProtocol(protocol.Protocol):
- """
- Protocol which fires a Deferred which was previously passed to
- its initializer when the connection is lost.
-
- @ivar onConnectionLost: The L{Deferred} which will be fired in
- C{connectionLost}.
-
- @ivar lostConnectionReason: C{None} until the connection is lost, then a
- reference to the reason passed to C{connectionLost}.
- """
- def __init__(self, onConnectionLost):
- self.lostConnectionReason = None
- self.onConnectionLost = onConnectionLost
-
-
- def connectionLost(self, reason):
- self.lostConnectionReason = reason
- self.onConnectionLost.callback(self)
-
-
-
-class HandleSavingProtocol(ConnectionLostNotifyingProtocol):
- """
- Protocol which grabs the platform-specific socket handle and
- saves it as an attribute on itself when the connection is
- established.
- """
- def makeConnection(self, transport):
- """
- Save the platform-specific socket handle for future
- introspection.
- """
- self.handle = transport.getHandle()
- return protocol.Protocol.makeConnection(self, transport)
-
-
-
-class ProperlyCloseFilesMixin:
- """
- Tests for platform resources properly being cleaned up.
- """
- def createServer(self, address, portNumber, factory):
- """
- Bind a server port to which connections will be made. The server
- should use the given protocol factory.
-
- @return: The L{IListeningPort} for the server created.
- """
- raise NotImplementedError()
-
-
- def connectClient(self, address, portNumber, clientCreator):
- """
- Establish a connection to the given address using the given
- L{ClientCreator} instance.
-
- @return: A Deferred which will fire with the connected protocol instance.
- """
- raise NotImplementedError()
-
-
- def getHandleExceptionType(self):
- """
- Return the exception class which will be raised when an operation is
- attempted on a closed platform handle.
- """
- raise NotImplementedError()
-
-
- def getHandleErrorCode(self):
- """
- Return the errno expected to result from writing to a closed
- platform socket handle.
- """
- # These platforms have been seen to give EBADF:
- #
- # Linux 2.4.26, Linux 2.6.15, OS X 10.4, FreeBSD 5.4
- # Windows 2000 SP 4, Windows XP SP 2
- return errno.EBADF
-
-
- def test_properlyCloseFiles(self):
- """
- Test that lost connections properly have their underlying socket
- resources cleaned up.
- """
- onServerConnectionLost = defer.Deferred()
- serverFactory = protocol.ServerFactory()
- serverFactory.protocol = lambda: ConnectionLostNotifyingProtocol(
- onServerConnectionLost)
- serverPort = self.createServer('127.0.0.1', 0, serverFactory)
-
- onClientConnectionLost = defer.Deferred()
- serverAddr = serverPort.getHost()
- clientCreator = protocol.ClientCreator(
- reactor, lambda: HandleSavingProtocol(onClientConnectionLost))
- clientDeferred = self.connectClient(
- serverAddr.host, serverAddr.port, clientCreator)
-
- def clientConnected(client):
- """
- Disconnect the client. Return a Deferred which fires when both
- the client and the server have received disconnect notification.
- """
- client.transport.write(
- 'some bytes to make sure the connection is set up')
- client.transport.loseConnection()
- return defer.gatherResults([
- onClientConnectionLost, onServerConnectionLost])
- clientDeferred.addCallback(clientConnected)
-
- def clientDisconnected((client, server)):
- """
- Verify that the underlying platform socket handle has been
- cleaned up.
- """
- client.lostConnectionReason.trap(error.ConnectionClosed)
- server.lostConnectionReason.trap(error.ConnectionClosed)
- expectedErrorCode = self.getHandleErrorCode()
- err = self.assertRaises(
- self.getHandleExceptionType(), client.handle.send, 'bytes')
- self.assertEqual(err.args[0], expectedErrorCode)
- clientDeferred.addCallback(clientDisconnected)
-
- def cleanup(passthrough):
- """
- Shut down the server port. Return a Deferred which fires when
- this has completed.
- """
- result = defer.maybeDeferred(serverPort.stopListening)
- result.addCallback(lambda ign: passthrough)
- return result
- clientDeferred.addBoth(cleanup)
-
- return clientDeferred
-
-
-
-class ProperlyCloseFilesTestCase(unittest.TestCase, ProperlyCloseFilesMixin):
- """
- Test that the sockets created by L{IReactorTCP.connectTCP} are cleaned up
- when the connection they are associated with is closed.
- """
- def createServer(self, address, portNumber, factory):
- """
- Create a TCP server using L{IReactorTCP.listenTCP}.
- """
- return reactor.listenTCP(portNumber, factory, interface=address)
-
-
- def connectClient(self, address, portNumber, clientCreator):
- """
- Create a TCP client using L{IReactorTCP.connectTCP}.
- """
- return clientCreator.connectTCP(address, portNumber)
-
-
- def getHandleExceptionType(self):
- """
- Return L{socket.error} as the expected error type which will be
- raised by a write to the low-level socket object after it has been
- closed.
- """
- return socket.error
-
-
-
-class WiredForDeferreds(policies.ProtocolWrapper):
- def __init__(self, factory, wrappedProtocol):
- policies.ProtocolWrapper.__init__(self, factory, wrappedProtocol)
-
- def connectionMade(self):
- policies.ProtocolWrapper.connectionMade(self)
- self.factory.onConnect.callback(None)
-
- def connectionLost(self, reason):
- policies.ProtocolWrapper.connectionLost(self, reason)
- self.factory.onDisconnect.callback(None)
-
-
-
-class WiredFactory(policies.WrappingFactory):
- protocol = WiredForDeferreds
-
- def __init__(self, wrappedFactory):
- policies.WrappingFactory.__init__(self, wrappedFactory)
- self.onConnect = defer.Deferred()
- self.onDisconnect = defer.Deferred()
-
-
-
-class AddressTestCase(unittest.TestCase):
- """
- Tests for address-related interactions with client and server protocols.
- """
- def setUp(self):
- """
- Create a port and connected client/server pair which can be used
- to test factory behavior related to addresses.
-
- @return: A L{defer.Deferred} which will be called back when both the
- client and server protocols have received their connection made
- callback.
- """
- class RememberingWrapper(protocol.ClientFactory):
- """
- Simple wrapper factory which records the addresses which are
- passed to its L{buildProtocol} method and delegates actual
- protocol creation to another factory.
-
- @ivar addresses: A list of the objects passed to buildProtocol.
- @ivar factory: The wrapped factory to which protocol creation is
- delegated.
- """
- def __init__(self, factory):
- self.addresses = []
- self.factory = factory
-
- # Only bother to pass on buildProtocol calls to the wrapped
- # factory - doStart, doStop, etc aren't necessary for this test
- # to pass.
- def buildProtocol(self, addr):
- """
- Append the given address to C{self.addresses} and forward
- the call to C{self.factory}.
- """
- self.addresses.append(addr)
- return self.factory.buildProtocol(addr)
-
- # Make a server which we can receive connection and disconnection
- # notification for, and which will record the address passed to its
- # buildProtocol.
- self.server = MyServerFactory()
- self.serverConnMade = self.server.protocolConnectionMade = defer.Deferred()
- self.serverConnLost = self.server.protocolConnectionLost = defer.Deferred()
- # RememberingWrapper is a ClientFactory, but ClientFactory is-a
- # ServerFactory, so this is okay.
- self.serverWrapper = RememberingWrapper(self.server)
-
- # Do something similar for a client.
- self.client = MyClientFactory()
- self.clientConnMade = self.client.protocolConnectionMade = defer.Deferred()
- self.clientConnLost = self.client.protocolConnectionLost = defer.Deferred()
- self.clientWrapper = RememberingWrapper(self.client)
-
- self.port = reactor.listenTCP(0, self.serverWrapper, interface='127.0.0.1')
- self.connector = reactor.connectTCP(
- self.port.getHost().host, self.port.getHost().port, self.clientWrapper)
-
- return defer.gatherResults([self.serverConnMade, self.clientConnMade])
-
-
- def tearDown(self):
- """
- Disconnect the client/server pair and shutdown the port created in
- L{setUp}.
- """
- self.connector.disconnect()
- return defer.gatherResults([
- self.serverConnLost, self.clientConnLost,
- defer.maybeDeferred(self.port.stopListening)])
-
-
- def test_buildProtocolClient(self):
- """
- L{ClientFactory.buildProtocol} should be invoked with the address of
- the server to which a connection has been established, which should
- be the same as the address reported by the C{getHost} method of the
- transport of the server protocol and as the C{getPeer} method of the
- transport of the client protocol.
- """
- serverHost = self.server.protocol.transport.getHost()
- clientPeer = self.client.protocol.transport.getPeer()
-
- self.assertEqual(
- self.clientWrapper.addresses,
- [IPv4Address('TCP', serverHost.host, serverHost.port)])
- self.assertEqual(
- self.clientWrapper.addresses,
- [IPv4Address('TCP', clientPeer.host, clientPeer.port)])
-
-
-
-class LargeBufferWriterProtocol(protocol.Protocol):
-
- # Win32 sockets cannot handle single huge chunks of bytes. Write one
- # massive string to make sure Twisted deals with this fact.
-
- def connectionMade(self):
- # write 60MB
- self.transport.write('X'*self.factory.len)
- self.factory.done = 1
- self.transport.loseConnection()
-
-class LargeBufferReaderProtocol(protocol.Protocol):
- def dataReceived(self, data):
- self.factory.len += len(data)
- def connectionLost(self, reason):
- self.factory.done = 1
-
-class LargeBufferReaderClientFactory(protocol.ClientFactory):
- def __init__(self):
- self.done = 0
- self.len = 0
- def buildProtocol(self, addr):
- p = LargeBufferReaderProtocol()
- p.factory = self
- self.protocol = p
- return p
-
-
-class FireOnClose(policies.ProtocolWrapper):
- """A wrapper around a protocol that makes it fire a deferred when
- connectionLost is called.
- """
- def connectionLost(self, reason):
- policies.ProtocolWrapper.connectionLost(self, reason)
- self.factory.deferred.callback(None)
-
-
-class FireOnCloseFactory(policies.WrappingFactory):
- protocol = FireOnClose
-
- def __init__(self, wrappedFactory):
- policies.WrappingFactory.__init__(self, wrappedFactory)
- self.deferred = defer.Deferred()
-
-
-class LargeBufferTestCase(unittest.TestCase):
- """Test that buffering large amounts of data works.
- """
-
- datalen = 60*1024*1024
- def testWriter(self):
- f = protocol.Factory()
- f.protocol = LargeBufferWriterProtocol
- f.done = 0
- f.problem = 0
- f.len = self.datalen
- wrappedF = FireOnCloseFactory(f)
- p = reactor.listenTCP(0, wrappedF, interface="127.0.0.1")
- self.addCleanup(p.stopListening)
- n = p.getHost().port
- clientF = LargeBufferReaderClientFactory()
- wrappedClientF = FireOnCloseFactory(clientF)
- reactor.connectTCP("127.0.0.1", n, wrappedClientF)
-
- d = defer.gatherResults([wrappedF.deferred, wrappedClientF.deferred])
- def check(ignored):
- self.failUnless(f.done, "writer didn't finish, it probably died")
- self.failUnless(clientF.len == self.datalen,
- "client didn't receive all the data it expected "
- "(%d != %d)" % (clientF.len, self.datalen))
- self.failUnless(clientF.done,
- "client didn't see connection dropped")
- return d.addCallback(check)
-
-
-class MyHCProtocol(AccumulatingProtocol):
-
- implements(IHalfCloseableProtocol)
-
- readHalfClosed = False
- writeHalfClosed = False
-
- def readConnectionLost(self):
- self.readHalfClosed = True
- # Invoke notification logic from the base class to simplify testing.
- if self.writeHalfClosed:
- self.connectionLost(None)
-
- def writeConnectionLost(self):
- self.writeHalfClosed = True
- # Invoke notification logic from the base class to simplify testing.
- if self.readHalfClosed:
- self.connectionLost(None)
-
-
-class MyHCFactory(protocol.ServerFactory):
-
- called = 0
- protocolConnectionMade = None
-
- def buildProtocol(self, addr):
- self.called += 1
- p = MyHCProtocol()
- p.factory = self
- self.protocol = p
- return p
-
-
-class HalfCloseTestCase(unittest.TestCase):
- """Test half-closing connections."""
-
- def setUp(self):
- self.f = f = MyHCFactory()
- self.p = p = reactor.listenTCP(0, f, interface="127.0.0.1")
- self.addCleanup(p.stopListening)
- d = loopUntil(lambda :p.connected)
-
- self.cf = protocol.ClientCreator(reactor, MyHCProtocol)
-
- d.addCallback(lambda _: self.cf.connectTCP(p.getHost().host,
- p.getHost().port))
- d.addCallback(self._setUp)
- return d
-
- def _setUp(self, client):
- self.client = client
- self.clientProtoConnectionLost = self.client.closedDeferred = defer.Deferred()
- self.assertEqual(self.client.transport.connected, 1)
- # Wait for the server to notice there is a connection, too.
- return loopUntil(lambda: getattr(self.f, 'protocol', None) is not None)
-
- def tearDown(self):
- self.assertEqual(self.client.closed, 0)
- self.client.transport.loseConnection()
- d = defer.maybeDeferred(self.p.stopListening)
- d.addCallback(lambda ign: self.clientProtoConnectionLost)
- d.addCallback(self._tearDown)
- return d
-
- def _tearDown(self, ignored):
- self.assertEqual(self.client.closed, 1)
- # because we did half-close, the server also needs to
- # closed explicitly.
- self.assertEqual(self.f.protocol.closed, 0)
- d = defer.Deferred()
- def _connectionLost(reason):
- self.f.protocol.closed = 1
- d.callback(None)
- self.f.protocol.connectionLost = _connectionLost
- self.f.protocol.transport.loseConnection()
- d.addCallback(lambda x:self.assertEqual(self.f.protocol.closed, 1))
- return d
-
- def testCloseWriteCloser(self):
- client = self.client
- f = self.f
- t = client.transport
-
- t.write("hello")
- d = loopUntil(lambda :len(t._tempDataBuffer) == 0)
- def loseWrite(ignored):
- t.loseWriteConnection()
- return loopUntil(lambda :t._writeDisconnected)
- def check(ignored):
- self.assertEqual(client.closed, False)
- self.assertEqual(client.writeHalfClosed, True)
- self.assertEqual(client.readHalfClosed, False)
- return loopUntil(lambda :f.protocol.readHalfClosed)
- def write(ignored):
- w = client.transport.write
- w(" world")
- w("lalala fooled you")
- self.assertEqual(0, len(client.transport._tempDataBuffer))
- self.assertEqual(f.protocol.data, "hello")
- self.assertEqual(f.protocol.closed, False)
- self.assertEqual(f.protocol.readHalfClosed, True)
- return d.addCallback(loseWrite).addCallback(check).addCallback(write)
-
- def testWriteCloseNotification(self):
- f = self.f
- f.protocol.transport.loseWriteConnection()
-
- d = defer.gatherResults([
- loopUntil(lambda :f.protocol.writeHalfClosed),
- loopUntil(lambda :self.client.readHalfClosed)])
- d.addCallback(lambda _: self.assertEqual(
- f.protocol.readHalfClosed, False))
- return d
-
-
-class HalfClose2TestCase(unittest.TestCase):
-
- def setUp(self):
- self.f = f = MyServerFactory()
- self.f.protocolConnectionMade = defer.Deferred()
- self.p = p = reactor.listenTCP(0, f, interface="127.0.0.1")
-
- # XXX we don't test server side yet since we don't do it yet
- d = protocol.ClientCreator(reactor, AccumulatingProtocol).connectTCP(
- p.getHost().host, p.getHost().port)
- d.addCallback(self._gotClient)
- return d
-
- def _gotClient(self, client):
- self.client = client
- # Now wait for the server to catch up - it doesn't matter if this
- # Deferred has already fired and gone away, in that case we'll
- # return None and not wait at all, which is precisely correct.
- return self.f.protocolConnectionMade
-
- def tearDown(self):
- self.client.transport.loseConnection()
- return self.p.stopListening()
-
- def testNoNotification(self):
- """
- TCP protocols support half-close connections, but not all of them
- support being notified of write closes. In this case, test that
- half-closing the connection causes the peer's connection to be
- closed.
- """
- self.client.transport.write("hello")
- self.client.transport.loseWriteConnection()
- self.f.protocol.closedDeferred = d = defer.Deferred()
- self.client.closedDeferred = d2 = defer.Deferred()
- d.addCallback(lambda x:
- self.assertEqual(self.f.protocol.data, 'hello'))
- d.addCallback(lambda x: self.assertEqual(self.f.protocol.closed, True))
- return defer.gatherResults([d, d2])
-
- def testShutdownException(self):
- """
- If the other side has already closed its connection,
- loseWriteConnection should pass silently.
- """
- self.f.protocol.transport.loseConnection()
- self.client.transport.write("X")
- self.client.transport.loseWriteConnection()
- self.f.protocol.closedDeferred = d = defer.Deferred()
- self.client.closedDeferred = d2 = defer.Deferred()
- d.addCallback(lambda x:
- self.assertEqual(self.f.protocol.closed, True))
- return defer.gatherResults([d, d2])
-
-
-class HalfCloseBuggyApplicationTests(unittest.TestCase):
- """
- Test half-closing connections where notification code has bugs.
- """
-
- def setUp(self):
- """
- Set up a server and connect a client to it. Return a Deferred which
- only fires once this is done.
- """
- self.serverFactory = MyHCFactory()
- self.serverFactory.protocolConnectionMade = defer.Deferred()
- self.port = reactor.listenTCP(
- 0, self.serverFactory, interface="127.0.0.1")
- self.addCleanup(self.port.stopListening)
- addr = self.port.getHost()
- creator = protocol.ClientCreator(reactor, MyHCProtocol)
- clientDeferred = creator.connectTCP(addr.host, addr.port)
- def setClient(clientProtocol):
- self.clientProtocol = clientProtocol
- clientDeferred.addCallback(setClient)
- return defer.gatherResults([
- self.serverFactory.protocolConnectionMade,
- clientDeferred])
-
-
- def aBug(self, *args):
- """
- Fake implementation of a callback which illegally raises an
- exception.
- """
- raise RuntimeError("ONO I AM BUGGY CODE")
-
-
- def _notificationRaisesTest(self):
- """
- Helper for testing that an exception is logged by the time the
- client protocol loses its connection.
- """
- closed = self.clientProtocol.closedDeferred = defer.Deferred()
- self.clientProtocol.transport.loseWriteConnection()
- def check(ignored):
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
- closed.addCallback(check)
- return closed
-
-
- def test_readNotificationRaises(self):
- """
- If C{readConnectionLost} raises an exception when the transport
- calls it to notify the protocol of that event, the exception should
- be logged and the protocol should be disconnected completely.
- """
- self.serverFactory.protocol.readConnectionLost = self.aBug
- return self._notificationRaisesTest()
-
-
- def test_writeNotificationRaises(self):
- """
- If C{writeConnectionLost} raises an exception when the transport
- calls it to notify the protocol of that event, the exception should
- be logged and the protocol should be disconnected completely.
- """
- self.clientProtocol.writeConnectionLost = self.aBug
- return self._notificationRaisesTest()
-
-
-
-class LogTestCase(unittest.TestCase):
- """
- Test logging facility of TCP base classes.
- """
-
- def test_logstrClientSetup(self):
- """
- Check that the log customization of the client transport happens
- once the client is connected.
- """
- server = MyServerFactory()
-
- client = MyClientFactory()
- client.protocolConnectionMade = defer.Deferred()
-
- port = reactor.listenTCP(0, server, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
-
- connector = reactor.connectTCP(
- port.getHost().host, port.getHost().port, client)
- self.addCleanup(connector.disconnect)
-
- # It should still have the default value
- self.assertEqual(connector.transport.logstr,
- "Uninitialized")
-
- def cb(ign):
- self.assertEqual(connector.transport.logstr,
- "AccumulatingProtocol,client")
- client.protocolConnectionMade.addCallback(cb)
- return client.protocolConnectionMade
-
-
-
-class PauseProducingTestCase(unittest.TestCase):
- """
- Test some behaviors of pausing the production of a transport.
- """
-
- def test_pauseProducingInConnectionMade(self):
- """
- In C{connectionMade} of a client protocol, C{pauseProducing} used to be
- ignored: this test is here to ensure it's not ignored.
- """
- server = MyServerFactory()
-
- client = MyClientFactory()
- client.protocolConnectionMade = defer.Deferred()
-
- port = reactor.listenTCP(0, server, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
-
- connector = reactor.connectTCP(
- port.getHost().host, port.getHost().port, client)
- self.addCleanup(connector.disconnect)
-
- def checkInConnectionMade(proto):
- tr = proto.transport
- # The transport should already be monitored
- self.assertIn(tr, reactor.getReaders() +
- reactor.getWriters())
- proto.transport.pauseProducing()
- self.assertNotIn(tr, reactor.getReaders() +
- reactor.getWriters())
- d = defer.Deferred()
- d.addCallback(checkAfterConnectionMade)
- reactor.callLater(0, d.callback, proto)
- return d
- def checkAfterConnectionMade(proto):
- tr = proto.transport
- # The transport should still not be monitored
- self.assertNotIn(tr, reactor.getReaders() +
- reactor.getWriters())
- client.protocolConnectionMade.addCallback(checkInConnectionMade)
- return client.protocolConnectionMade
-
- if not interfaces.IReactorFDSet.providedBy(reactor):
- test_pauseProducingInConnectionMade.skip = "Reactor not providing IReactorFDSet"
-
-
-
-class CallBackOrderTestCase(unittest.TestCase):
- """
- Test the order of reactor callbacks
- """
-
- def test_loseOrder(self):
- """
- Check that Protocol.connectionLost is called before factory's
- clientConnectionLost
- """
- server = MyServerFactory()
- server.protocolConnectionMade = (defer.Deferred()
- .addCallback(lambda proto: self.addCleanup(
- proto.transport.loseConnection)))
-
- client = MyClientFactory()
- client.protocolConnectionLost = defer.Deferred()
- client.protocolConnectionMade = defer.Deferred()
-
- def _cbCM(res):
- """
- protocol.connectionMade callback
- """
- reactor.callLater(0, client.protocol.transport.loseConnection)
-
- client.protocolConnectionMade.addCallback(_cbCM)
-
- port = reactor.listenTCP(0, server, interface='127.0.0.1')
- self.addCleanup(port.stopListening)
-
- connector = reactor.connectTCP(
- port.getHost().host, port.getHost().port, client)
- self.addCleanup(connector.disconnect)
-
- def _cbCCL(res):
- """
- factory.clientConnectionLost callback
- """
- return 'CCL'
-
- def _cbCL(res):
- """
- protocol.connectionLost callback
- """
- return 'CL'
-
- def _cbGather(res):
- self.assertEqual(res, ['CL', 'CCL'])
-
- d = defer.gatherResults([
- client.protocolConnectionLost.addCallback(_cbCL),
- client.deferred.addCallback(_cbCCL)])
- return d.addCallback(_cbGather)
-
-
-
-try:
- import resource
-except ImportError:
- pass
-else:
- numRounds = resource.getrlimit(resource.RLIMIT_NOFILE)[0] + 10
- ProperlyCloseFilesTestCase.numberRounds = numRounds
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp_internals.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp_internals.py
deleted file mode 100755
index aa7aeac8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tcp_internals.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Whitebox tests for TCP APIs.
-"""
-
-import errno, socket, os
-
-try:
- import resource
-except ImportError:
- resource = None
-
-from twisted.trial.unittest import TestCase
-
-from twisted.python import log
-from twisted.internet.tcp import ECONNABORTED, ENOMEM, ENFILE, EMFILE, ENOBUFS, EINPROGRESS, Port
-from twisted.internet.protocol import ServerFactory
-from twisted.python.runtime import platform
-from twisted.internet.defer import maybeDeferred, gatherResults
-from twisted.internet import reactor, interfaces
-
-
-class PlatformAssumptionsTestCase(TestCase):
- """
- Test assumptions about platform behaviors.
- """
- socketLimit = 8192
-
- def setUp(self):
- self.openSockets = []
- if resource is not None:
- # On some buggy platforms we might leak FDs, and the test will
- # fail creating the initial two sockets we *do* want to
- # succeed. So, we make the soft limit the current number of fds
- # plus two more (for the two sockets we want to succeed). If we've
- # leaked too many fds for that to work, there's nothing we can
- # do.
- from twisted.internet.process import _listOpenFDs
- newLimit = len(_listOpenFDs()) + 2
- self.originalFileLimit = resource.getrlimit(resource.RLIMIT_NOFILE)
- resource.setrlimit(resource.RLIMIT_NOFILE, (newLimit, self.originalFileLimit[1]))
- self.socketLimit = newLimit + 100
-
-
- def tearDown(self):
- while self.openSockets:
- self.openSockets.pop().close()
- if resource is not None:
- # OS X implicitly lowers the hard limit in the setrlimit call
- # above. Retrieve the new hard limit to pass in to this
- # setrlimit call, so that it doesn't give us a permission denied
- # error.
- currentHardLimit = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
- newSoftLimit = min(self.originalFileLimit[0], currentHardLimit)
- resource.setrlimit(resource.RLIMIT_NOFILE, (newSoftLimit, currentHardLimit))
-
-
- def socket(self):
- """
- Create and return a new socket object, also tracking it so it can be
- closed in the test tear down.
- """
- s = socket.socket()
- self.openSockets.append(s)
- return s
-
-
- def test_acceptOutOfFiles(self):
- """
- Test that the platform accept(2) call fails with either L{EMFILE} or
- L{ENOBUFS} when there are too many file descriptors open.
- """
- # Make a server to which to connect
- port = self.socket()
- port.bind(('127.0.0.1', 0))
- serverPortNumber = port.getsockname()[1]
- port.listen(5)
-
- # Make a client to use to connect to the server
- client = self.socket()
- client.setblocking(False)
-
- # Use up all the rest of the file descriptors.
- for i in xrange(self.socketLimit):
- try:
- self.socket()
- except socket.error, e:
- if e.args[0] in (EMFILE, ENOBUFS):
- # The desired state has been achieved.
- break
- else:
- # Some unexpected error occurred.
- raise
- else:
- self.fail("Could provoke neither EMFILE nor ENOBUFS from platform.")
-
- # Non-blocking connect is supposed to fail, but this is not true
- # everywhere (e.g. freeBSD)
- self.assertIn(client.connect_ex(('127.0.0.1', serverPortNumber)),
- (0, EINPROGRESS))
-
- # Make sure that the accept call fails in the way we expect.
- exc = self.assertRaises(socket.error, port.accept)
- self.assertIn(exc.args[0], (EMFILE, ENOBUFS))
- if platform.getType() == "win32":
- test_acceptOutOfFiles.skip = (
- "Windows requires an unacceptably large amount of resources to "
- "provoke this behavior in the naive manner.")
-
-
-
-class SelectReactorTestCase(TestCase):
- """
- Tests for select-specific failure conditions.
- """
-
- def setUp(self):
- self.ports = []
- self.messages = []
- log.addObserver(self.messages.append)
-
-
- def tearDown(self):
- log.removeObserver(self.messages.append)
- return gatherResults([
- maybeDeferred(p.stopListening)
- for p in self.ports])
-
-
- def port(self, portNumber, factory, interface):
- """
- Create, start, and return a new L{Port}, also tracking it so it can
- be stopped in the test tear down.
- """
- p = Port(portNumber, factory, interface=interface)
- p.startListening()
- self.ports.append(p)
- return p
-
-
- def _acceptFailureTest(self, socketErrorNumber):
- """
- Test behavior in the face of an exception from C{accept(2)}.
-
- On any exception which indicates the platform is unable or unwilling
- to allocate further resources to us, the existing port should remain
- listening, a message should be logged, and the exception should not
- propagate outward from doRead.
-
- @param socketErrorNumber: The errno to simulate from accept.
- """
- class FakeSocket(object):
- """
- Pretend to be a socket in an overloaded system.
- """
- def accept(self):
- raise socket.error(
- socketErrorNumber, os.strerror(socketErrorNumber))
-
- factory = ServerFactory()
- port = self.port(0, factory, interface='127.0.0.1')
- originalSocket = port.socket
- try:
- port.socket = FakeSocket()
-
- port.doRead()
-
- expectedFormat = "Could not accept new connection (%s)"
- expectedErrorCode = errno.errorcode[socketErrorNumber]
- expectedMessage = expectedFormat % (expectedErrorCode,)
- for msg in self.messages:
- if msg.get('message') == (expectedMessage,):
- break
- else:
- self.fail("Log event for failed accept not found in "
- "%r" % (self.messages,))
- finally:
- port.socket = originalSocket
-
-
- def test_tooManyFilesFromAccept(self):
- """
- C{accept(2)} can fail with C{EMFILE} when there are too many open file
- descriptors in the process. Test that this doesn't negatively impact
- any other existing connections.
-
- C{EMFILE} mainly occurs on Linux when the open file rlimit is
- encountered.
- """
- return self._acceptFailureTest(EMFILE)
-
-
- def test_noBufferSpaceFromAccept(self):
- """
- Similar to L{test_tooManyFilesFromAccept}, but test the case where
- C{accept(2)} fails with C{ENOBUFS}.
-
- This mainly occurs on Windows and FreeBSD, but may be possible on
- Linux and other platforms as well.
- """
- return self._acceptFailureTest(ENOBUFS)
-
-
- def test_connectionAbortedFromAccept(self):
- """
- Similar to L{test_tooManyFilesFromAccept}, but test the case where
- C{accept(2)} fails with C{ECONNABORTED}.
-
- It is not clear whether this is actually possible for TCP
- connections on modern versions of Linux.
- """
- return self._acceptFailureTest(ECONNABORTED)
-
-
- def test_noFilesFromAccept(self):
- """
- Similar to L{test_tooManyFilesFromAccept}, but test the case where
- C{accept(2)} fails with C{ENFILE}.
-
- This can occur on Linux when the system has exhausted (!) its supply
- of inodes.
- """
- return self._acceptFailureTest(ENFILE)
- if platform.getType() == 'win32':
- test_noFilesFromAccept.skip = "Windows accept(2) cannot generate ENFILE"
-
-
- def test_noMemoryFromAccept(self):
- """
- Similar to L{test_tooManyFilesFromAccept}, but test the case where
- C{accept(2)} fails with C{ENOMEM}.
-
- On Linux at least, this can sensibly occur, even in a Python program
- (which eats memory like no ones business), when memory has become
- fragmented or low memory has been filled (d_alloc calls
- kmem_cache_alloc calls kmalloc - kmalloc only allocates out of low
- memory).
- """
- return self._acceptFailureTest(ENOMEM)
- if platform.getType() == 'win32':
- test_noMemoryFromAccept.skip = "Windows accept(2) cannot generate ENOMEM"
-
-if not interfaces.IReactorFDSet.providedBy(reactor):
- skipMsg = 'This test only applies to reactors that implement IReactorFDset'
- PlatformAssumptionsTestCase.skip = skipMsg
- SelectReactorTestCase.skip = skipMsg
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_text.py
deleted file mode 100755
index 4b2d38cf..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_text.py
+++ /dev/null
@@ -1,242 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.text}.
-"""
-
-from cStringIO import StringIO
-
-from twisted.trial import unittest
-from twisted.python import text
-
-
-sampleText = \
-"""Every attempt to employ mathematical methods in the study of chemical
-questions must be considered profoundly irrational and contrary to the
-spirit of chemistry ... If mathematical analysis should ever hold a
-prominent place in chemistry - an aberration which is happily almost
-impossible - it would occasion a rapid and widespread degeneration of that
-science.
-
- -- Auguste Comte, Philosophie Positive, Paris, 1838
-"""
-
-
-class WrapTest(unittest.TestCase):
- """
- Tests for L{text.greedyWrap}.
- """
- def setUp(self):
- self.lineWidth = 72
- self.sampleSplitText = sampleText.split()
- self.output = text.wordWrap(sampleText, self.lineWidth)
-
-
- def test_wordCount(self):
- """
- Compare the number of words.
- """
- words = []
- for line in self.output:
- words.extend(line.split())
- wordCount = len(words)
- sampleTextWordCount = len(self.sampleSplitText)
-
- self.assertEqual(wordCount, sampleTextWordCount)
-
-
- def test_wordMatch(self):
- """
- Compare the lists of words.
- """
- words = []
- for line in self.output:
- words.extend(line.split())
-
- # Using assertEqual here prints out some
- # rather too long lists.
- self.failUnless(self.sampleSplitText == words)
-
-
- def test_lineLength(self):
- """
- Check the length of the lines.
- """
- failures = []
- for line in self.output:
- if not len(line) <= self.lineWidth:
- failures.append(len(line))
-
- if failures:
- self.fail("%d of %d lines were too long.\n"
- "%d < %s" % (len(failures), len(self.output),
- self.lineWidth, failures))
-
- def test_doubleNewline(self):
- """
- Allow paragraphs delimited by two \ns.
- """
- sampleText = "et\n\nphone\nhome."
- result = text.wordWrap(sampleText, self.lineWidth)
- self.assertEqual(result, ["et", "", "phone home.", ""])
-
-
-
-class LineTest(unittest.TestCase):
- """
- Tests for L{isMultiline} and L{endsInNewline}.
- """
- def test_isMultiline(self):
- """
- L{text.isMultiline} returns C{True} if the string has a newline in it.
- """
- s = 'This code\n "breaks."'
- m = text.isMultiline(s)
- self.assertTrue(m)
-
- s = 'This code does not "break."'
- m = text.isMultiline(s)
- self.assertFalse(m)
-
-
- def test_endsInNewline(self):
- """
- L{text.endsInNewline} returns C{True} if the string ends in a newline.
- """
- s = 'newline\n'
- m = text.endsInNewline(s)
- self.assertTrue(m)
-
- s = 'oldline'
- m = text.endsInNewline(s)
- self.assertFalse(m)
-
-
-
-class StringyStringTest(unittest.TestCase):
- """
- Tests for L{text.stringyString}.
- """
- def test_tuple(self):
- """
- Tuple elements are displayed on separate lines.
- """
- s = ('a', 'b')
- m = text.stringyString(s)
- self.assertEqual(m, '(a,\n b,)\n')
-
-
- def test_dict(self):
- """
- Dicts elements are displayed using C{str()}.
- """
- s = {'a': 0}
- m = text.stringyString(s)
- self.assertEqual(m, '{a: 0}')
-
-
- def test_list(self):
- """
- List elements are displayed on separate lines using C{str()}.
- """
- s = ['a', 'b']
- m = text.stringyString(s)
- self.assertEqual(m, '[a,\n b,]\n')
-
-
-
-class SplitTest(unittest.TestCase):
- """
- Tests for L{text.splitQuoted}.
- """
- def test_oneWord(self):
- """
- Splitting strings with one-word phrases.
- """
- s = 'This code "works."'
- r = text.splitQuoted(s)
- self.assertEqual(['This', 'code', 'works.'], r)
-
-
- def test_multiWord(self):
- s = 'The "hairy monkey" likes pie.'
- r = text.splitQuoted(s)
- self.assertEqual(['The', 'hairy monkey', 'likes', 'pie.'], r)
-
- # Some of the many tests that would fail:
-
- #def test_preserveWhitespace(self):
- # phrase = '"MANY SPACES"'
- # s = 'With %s between.' % (phrase,)
- # r = text.splitQuoted(s)
- # self.assertEqual(['With', phrase, 'between.'], r)
-
- #def test_escapedSpace(self):
- # s = r"One\ Phrase"
- # r = text.splitQuoted(s)
- # self.assertEqual(["One Phrase"], r)
-
-
-
-class StrFileTest(unittest.TestCase):
- def setUp(self):
- self.io = StringIO("this is a test string")
-
- def tearDown(self):
- pass
-
- def test_1_f(self):
- self.assertEqual(False, text.strFile("x", self.io))
-
- def test_1_1(self):
- self.assertEqual(True, text.strFile("t", self.io))
-
- def test_1_2(self):
- self.assertEqual(True, text.strFile("h", self.io))
-
- def test_1_3(self):
- self.assertEqual(True, text.strFile("i", self.io))
-
- def test_1_4(self):
- self.assertEqual(True, text.strFile("s", self.io))
-
- def test_1_5(self):
- self.assertEqual(True, text.strFile("n", self.io))
-
- def test_1_6(self):
- self.assertEqual(True, text.strFile("g", self.io))
-
- def test_3_1(self):
- self.assertEqual(True, text.strFile("thi", self.io))
-
- def test_3_2(self):
- self.assertEqual(True, text.strFile("his", self.io))
-
- def test_3_3(self):
- self.assertEqual(True, text.strFile("is ", self.io))
-
- def test_3_4(self):
- self.assertEqual(True, text.strFile("ing", self.io))
-
- def test_3_f(self):
- self.assertEqual(False, text.strFile("bla", self.io))
-
- def test_large_1(self):
- self.assertEqual(True, text.strFile("this is a test", self.io))
-
- def test_large_2(self):
- self.assertEqual(True, text.strFile("is a test string", self.io))
-
- def test_large_f(self):
- self.assertEqual(False, text.strFile("ds jhfsa k fdas", self.io))
-
- def test_overlarge_f(self):
- self.assertEqual(False, text.strFile("djhsakj dhsa fkhsa s,mdbnfsauiw bndasdf hreew", self.io))
-
- def test_self(self):
- self.assertEqual(True, text.strFile("this is a test string", self.io))
-
- def test_insensitive(self):
- self.assertEqual(True, text.strFile("ThIs is A test STRING", self.io, False))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadable.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadable.py
deleted file mode 100755
index f23515ad..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadable.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, pickle
-
-try:
- import threading
-except ImportError:
- threading = None
-
-from twisted.trial import unittest
-from twisted.python import threadable
-from twisted.internet import defer, reactor
-
-class TestObject:
- synchronized = ['aMethod']
-
- x = -1
- y = 1
-
- def aMethod(self):
- for i in xrange(10):
- self.x, self.y = self.y, self.x
- self.z = self.x + self.y
- assert self.z == 0, "z == %d, not 0 as expected" % (self.z,)
-
-threadable.synchronize(TestObject)
-
-class SynchronizationTestCase(unittest.TestCase):
- def setUp(self):
- """
- Reduce the CPython check interval so that thread switches happen much
- more often, hopefully exercising more possible race conditions. Also,
- delay actual test startup until the reactor has been started.
- """
- if hasattr(sys, 'getcheckinterval'):
- self.addCleanup(sys.setcheckinterval, sys.getcheckinterval())
- sys.setcheckinterval(7)
- # XXX This is a trial hack. We need to make sure the reactor
- # actually *starts* for isInIOThread() to have a meaningful result.
- # Returning a Deferred here should force that to happen, if it has
- # not happened already. In the future, this should not be
- # necessary.
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
- return d
-
-
- def testIsInIOThread(self):
- foreignResult = []
- t = threading.Thread(target=lambda: foreignResult.append(threadable.isInIOThread()))
- t.start()
- t.join()
- self.failIf(foreignResult[0], "Non-IO thread reported as IO thread")
- self.failUnless(threadable.isInIOThread(), "IO thread reported as not IO thread")
-
-
- def testThreadedSynchronization(self):
- o = TestObject()
-
- errors = []
-
- def callMethodLots():
- try:
- for i in xrange(1000):
- o.aMethod()
- except AssertionError, e:
- errors.append(str(e))
-
- threads = []
- for x in range(5):
- t = threading.Thread(target=callMethodLots)
- threads.append(t)
- t.start()
-
- for t in threads:
- t.join()
-
- if errors:
- raise unittest.FailTest(errors)
-
- def testUnthreadedSynchronization(self):
- o = TestObject()
- for i in xrange(1000):
- o.aMethod()
-
-class SerializationTestCase(unittest.TestCase):
- def testPickling(self):
- lock = threadable.XLock()
- lockType = type(lock)
- lockPickle = pickle.dumps(lock)
- newLock = pickle.loads(lockPickle)
- self.failUnless(isinstance(newLock, lockType))
-
- def testUnpickling(self):
- lockPickle = 'ctwisted.python.threadable\nunpickle_lock\np0\n(tp1\nRp2\n.'
- lock = pickle.loads(lockPickle)
- newPickle = pickle.dumps(lock, 2)
- newLock = pickle.loads(newPickle)
-
-if threading is None:
- SynchronizationTestCase.testThreadedSynchronization.skip = "Platform lacks thread support"
- SerializationTestCase.testPickling.skip = "Platform lacks thread support"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadpool.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadpool.py
deleted file mode 100755
index 3b1ff83f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threadpool.py
+++ /dev/null
@@ -1,526 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.threadpool}
-"""
-
-import pickle, time, weakref, gc, threading
-
-from twisted.trial import unittest
-from twisted.python import threadpool, threadable, failure, context
-from twisted.internet import reactor
-from twisted.internet.defer import Deferred
-
-#
-# See the end of this module for the remainder of the imports.
-#
-
-class Synchronization(object):
- failures = 0
-
- def __init__(self, N, waiting):
- self.N = N
- self.waiting = waiting
- self.lock = threading.Lock()
- self.runs = []
-
- def run(self):
- # This is the testy part: this is supposed to be invoked
- # serially from multiple threads. If that is actually the
- # case, we will never fail to acquire this lock. If it is
- # *not* the case, we might get here while someone else is
- # holding the lock.
- if self.lock.acquire(False):
- if not len(self.runs) % 5:
- time.sleep(0.0002) # Constant selected based on
- # empirical data to maximize the
- # chance of a quick failure if this
- # code is broken.
- self.lock.release()
- else:
- self.failures += 1
-
- # This is just the only way I can think of to wake up the test
- # method. It doesn't actually have anything to do with the
- # test.
- self.lock.acquire()
- self.runs.append(None)
- if len(self.runs) == self.N:
- self.waiting.release()
- self.lock.release()
-
- synchronized = ["run"]
-threadable.synchronize(Synchronization)
-
-
-
-class ThreadPoolTestCase(unittest.TestCase):
- """
- Test threadpools.
- """
- def _waitForLock(self, lock):
- for i in xrange(1000000):
- if lock.acquire(False):
- break
- time.sleep(1e-5)
- else:
- self.fail("A long time passed without succeeding")
-
-
- def test_attributes(self):
- """
- L{ThreadPool.min} and L{ThreadPool.max} are set to the values passed to
- L{ThreadPool.__init__}.
- """
- pool = threadpool.ThreadPool(12, 22)
- self.assertEqual(pool.min, 12)
- self.assertEqual(pool.max, 22)
-
-
- def test_start(self):
- """
- L{ThreadPool.start} creates the minimum number of threads specified.
- """
- pool = threadpool.ThreadPool(0, 5)
- pool.start()
- self.addCleanup(pool.stop)
- self.assertEqual(len(pool.threads), 0)
-
- pool = threadpool.ThreadPool(3, 10)
- self.assertEqual(len(pool.threads), 0)
- pool.start()
- self.addCleanup(pool.stop)
- self.assertEqual(len(pool.threads), 3)
-
-
- def test_threadCreationArguments(self):
- """
- Test that creating threads in the threadpool with application-level
- objects as arguments doesn't results in those objects never being
- freed, with the thread maintaining a reference to them as long as it
- exists.
- """
- tp = threadpool.ThreadPool(0, 1)
- tp.start()
- self.addCleanup(tp.stop)
-
- # Sanity check - no threads should have been started yet.
- self.assertEqual(tp.threads, [])
-
- # Here's our function
- def worker(arg):
- pass
- # weakref needs an object subclass
- class Dumb(object):
- pass
- # And here's the unique object
- unique = Dumb()
-
- workerRef = weakref.ref(worker)
- uniqueRef = weakref.ref(unique)
-
- # Put some work in
- tp.callInThread(worker, unique)
-
- # Add an event to wait completion
- event = threading.Event()
- tp.callInThread(event.set)
- event.wait(self.getTimeout())
-
- del worker
- del unique
- gc.collect()
- self.assertEqual(uniqueRef(), None)
- self.assertEqual(workerRef(), None)
-
-
- def test_threadCreationArgumentsCallInThreadWithCallback(self):
- """
- As C{test_threadCreationArguments} above, but for
- callInThreadWithCallback.
- """
-
- tp = threadpool.ThreadPool(0, 1)
- tp.start()
- self.addCleanup(tp.stop)
-
- # Sanity check - no threads should have been started yet.
- self.assertEqual(tp.threads, [])
-
- # this holds references obtained in onResult
- refdict = {} # name -> ref value
-
- onResultWait = threading.Event()
- onResultDone = threading.Event()
-
- resultRef = []
-
- # result callback
- def onResult(success, result):
- onResultWait.wait(self.getTimeout())
- refdict['workerRef'] = workerRef()
- refdict['uniqueRef'] = uniqueRef()
- onResultDone.set()
- resultRef.append(weakref.ref(result))
-
- # Here's our function
- def worker(arg, test):
- return Dumb()
-
- # weakref needs an object subclass
- class Dumb(object):
- pass
-
- # And here's the unique object
- unique = Dumb()
-
- onResultRef = weakref.ref(onResult)
- workerRef = weakref.ref(worker)
- uniqueRef = weakref.ref(unique)
-
- # Put some work in
- tp.callInThreadWithCallback(onResult, worker, unique, test=unique)
-
- del worker
- del unique
- gc.collect()
-
- # let onResult collect the refs
- onResultWait.set()
- # wait for onResult
- onResultDone.wait(self.getTimeout())
-
- self.assertEqual(uniqueRef(), None)
- self.assertEqual(workerRef(), None)
-
- # XXX There's a race right here - has onResult in the worker thread
- # returned and the locals in _worker holding it and the result been
- # deleted yet?
-
- del onResult
- gc.collect()
- self.assertEqual(onResultRef(), None)
- self.assertEqual(resultRef[0](), None)
-
-
- def test_persistence(self):
- """
- Threadpools can be pickled and unpickled, which should preserve the
- number of threads and other parameters.
- """
- pool = threadpool.ThreadPool(7, 20)
-
- self.assertEqual(pool.min, 7)
- self.assertEqual(pool.max, 20)
-
- # check that unpickled threadpool has same number of threads
- copy = pickle.loads(pickle.dumps(pool))
-
- self.assertEqual(copy.min, 7)
- self.assertEqual(copy.max, 20)
-
-
- def _threadpoolTest(self, method):
- """
- Test synchronization of calls made with C{method}, which should be
- one of the mechanisms of the threadpool to execute work in threads.
- """
- # This is a schizophrenic test: it seems to be trying to test
- # both the callInThread()/dispatch() behavior of the ThreadPool as well
- # as the serialization behavior of threadable.synchronize(). It
- # would probably make more sense as two much simpler tests.
- N = 10
-
- tp = threadpool.ThreadPool()
- tp.start()
- self.addCleanup(tp.stop)
-
- waiting = threading.Lock()
- waiting.acquire()
- actor = Synchronization(N, waiting)
-
- for i in xrange(N):
- method(tp, actor)
-
- self._waitForLock(waiting)
-
- self.failIf(actor.failures, "run() re-entered %d times" %
- (actor.failures,))
-
-
- def test_callInThread(self):
- """
- Call C{_threadpoolTest} with C{callInThread}.
- """
- return self._threadpoolTest(
- lambda tp, actor: tp.callInThread(actor.run))
-
-
- def test_callInThreadException(self):
- """
- L{ThreadPool.callInThread} logs exceptions raised by the callable it
- is passed.
- """
- class NewError(Exception):
- pass
-
- def raiseError():
- raise NewError()
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThread(raiseError)
- tp.start()
- tp.stop()
-
- errors = self.flushLoggedErrors(NewError)
- self.assertEqual(len(errors), 1)
-
-
- def test_callInThreadWithCallback(self):
- """
- L{ThreadPool.callInThreadWithCallback} calls C{onResult} with a
- two-tuple of C{(True, result)} where C{result} is the value returned
- by the callable supplied.
- """
- waiter = threading.Lock()
- waiter.acquire()
-
- results = []
-
- def onResult(success, result):
- waiter.release()
- results.append(success)
- results.append(result)
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThreadWithCallback(onResult, lambda : "test")
- tp.start()
-
- try:
- self._waitForLock(waiter)
- finally:
- tp.stop()
-
- self.assertTrue(results[0])
- self.assertEqual(results[1], "test")
-
-
- def test_callInThreadWithCallbackExceptionInCallback(self):
- """
- L{ThreadPool.callInThreadWithCallback} calls C{onResult} with a
- two-tuple of C{(False, failure)} where C{failure} represents the
- exception raised by the callable supplied.
- """
- class NewError(Exception):
- pass
-
- def raiseError():
- raise NewError()
-
- waiter = threading.Lock()
- waiter.acquire()
-
- results = []
-
- def onResult(success, result):
- waiter.release()
- results.append(success)
- results.append(result)
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThreadWithCallback(onResult, raiseError)
- tp.start()
-
- try:
- self._waitForLock(waiter)
- finally:
- tp.stop()
-
- self.assertFalse(results[0])
- self.assertTrue(isinstance(results[1], failure.Failure))
- self.assertTrue(issubclass(results[1].type, NewError))
-
-
- def test_callInThreadWithCallbackExceptionInOnResult(self):
- """
- L{ThreadPool.callInThreadWithCallback} logs the exception raised by
- C{onResult}.
- """
- class NewError(Exception):
- pass
-
- waiter = threading.Lock()
- waiter.acquire()
-
- results = []
-
- def onResult(success, result):
- results.append(success)
- results.append(result)
- raise NewError()
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThreadWithCallback(onResult, lambda : None)
- tp.callInThread(waiter.release)
- tp.start()
-
- try:
- self._waitForLock(waiter)
- finally:
- tp.stop()
-
- errors = self.flushLoggedErrors(NewError)
- self.assertEqual(len(errors), 1)
-
- self.assertTrue(results[0])
- self.assertEqual(results[1], None)
-
-
- def test_callbackThread(self):
- """
- L{ThreadPool.callInThreadWithCallback} calls the function it is
- given and the C{onResult} callback in the same thread.
- """
- threadIds = []
-
- import thread
-
- event = threading.Event()
-
- def onResult(success, result):
- threadIds.append(thread.get_ident())
- event.set()
-
- def func():
- threadIds.append(thread.get_ident())
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThreadWithCallback(onResult, func)
- tp.start()
- self.addCleanup(tp.stop)
-
- event.wait(self.getTimeout())
- self.assertEqual(len(threadIds), 2)
- self.assertEqual(threadIds[0], threadIds[1])
-
-
- def test_callbackContext(self):
- """
- The context L{ThreadPool.callInThreadWithCallback} is invoked in is
- shared by the context the callable and C{onResult} callback are
- invoked in.
- """
- myctx = context.theContextTracker.currentContext().contexts[-1]
- myctx['testing'] = 'this must be present'
-
- contexts = []
-
- event = threading.Event()
-
- def onResult(success, result):
- ctx = context.theContextTracker.currentContext().contexts[-1]
- contexts.append(ctx)
- event.set()
-
- def func():
- ctx = context.theContextTracker.currentContext().contexts[-1]
- contexts.append(ctx)
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThreadWithCallback(onResult, func)
- tp.start()
- self.addCleanup(tp.stop)
-
- event.wait(self.getTimeout())
-
- self.assertEqual(len(contexts), 2)
- self.assertEqual(myctx, contexts[0])
- self.assertEqual(myctx, contexts[1])
-
-
- def test_existingWork(self):
- """
- Work added to the threadpool before its start should be executed once
- the threadpool is started: this is ensured by trying to release a lock
- previously acquired.
- """
- waiter = threading.Lock()
- waiter.acquire()
-
- tp = threadpool.ThreadPool(0, 1)
- tp.callInThread(waiter.release) # before start()
- tp.start()
-
- try:
- self._waitForLock(waiter)
- finally:
- tp.stop()
-
-
-
-class RaceConditionTestCase(unittest.TestCase):
- def setUp(self):
- self.event = threading.Event()
- self.threadpool = threadpool.ThreadPool(0, 10)
- self.threadpool.start()
-
-
- def tearDown(self):
- del self.event
- self.threadpool.stop()
- del self.threadpool
-
-
- def test_synchronization(self):
- """
- Test a race condition: ensure that actions run in the pool synchronize
- with actions run in the main thread.
- """
- timeout = self.getTimeout()
- self.threadpool.callInThread(self.event.set)
- self.event.wait(timeout)
- self.event.clear()
- for i in range(3):
- self.threadpool.callInThread(self.event.wait)
- self.threadpool.callInThread(self.event.set)
- self.event.wait(timeout)
- if not self.event.isSet():
- self.event.set()
- self.fail("Actions not synchronized")
-
-
- def test_singleThread(self):
- """
- The submission of a new job to a thread pool in response to the
- C{onResult} callback does not cause a new thread to be added to the
- thread pool.
-
- This requires that the thread which calls C{onResult} to have first
- marked itself as available so that when the new job is queued, that
- thread may be considered to run it. This is desirable so that when
- only N jobs are ever being executed in the thread pool at once only
- N threads will ever be created.
- """
- # Ensure no threads running
- self.assertEqual(self.threadpool.workers, 0)
-
- loopDeferred = Deferred()
-
- def onResult(success, counter):
- reactor.callFromThread(submit, counter)
-
- def submit(counter):
- if counter:
- self.threadpool.callInThreadWithCallback(
- onResult, lambda: counter - 1)
- else:
- loopDeferred.callback(None)
-
- def cbLoop(ignored):
- # Ensure there is only one thread running.
- self.assertEqual(self.threadpool.workers, 1)
-
- loopDeferred.addCallback(cbLoop)
- submit(10)
- return loopDeferred
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threads.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threads.py
deleted file mode 100755
index 0b218a39..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_threads.py
+++ /dev/null
@@ -1,412 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Test methods in twisted.internet.threads and reactor thread APIs.
-"""
-
-import sys, os, time
-
-from twisted.trial import unittest
-
-from twisted.internet import reactor, defer, interfaces, threads, protocol, error
-from twisted.python import failure, threadable, log, threadpool
-
-
-
-class ReactorThreadsTestCase(unittest.TestCase):
- """
- Tests for the reactor threading API.
- """
-
- def test_suggestThreadPoolSize(self):
- """
- Try to change maximum number of threads.
- """
- reactor.suggestThreadPoolSize(34)
- self.assertEqual(reactor.threadpool.max, 34)
- reactor.suggestThreadPoolSize(4)
- self.assertEqual(reactor.threadpool.max, 4)
-
-
- def _waitForThread(self):
- """
- The reactor's threadpool is only available when the reactor is running,
- so to have a sane behavior during the tests we make a dummy
- L{threads.deferToThread} call.
- """
- return threads.deferToThread(time.sleep, 0)
-
-
- def test_callInThread(self):
- """
- Test callInThread functionality: set a C{threading.Event}, and check
- that it's not in the main thread.
- """
- def cb(ign):
- waiter = threading.Event()
- result = []
- def threadedFunc():
- result.append(threadable.isInIOThread())
- waiter.set()
-
- reactor.callInThread(threadedFunc)
- waiter.wait(120)
- if not waiter.isSet():
- self.fail("Timed out waiting for event.")
- else:
- self.assertEqual(result, [False])
- return self._waitForThread().addCallback(cb)
-
-
- def test_callFromThread(self):
- """
- Test callFromThread functionality: from the main thread, and from
- another thread.
- """
- def cb(ign):
- firedByReactorThread = defer.Deferred()
- firedByOtherThread = defer.Deferred()
-
- def threadedFunc():
- reactor.callFromThread(firedByOtherThread.callback, None)
-
- reactor.callInThread(threadedFunc)
- reactor.callFromThread(firedByReactorThread.callback, None)
-
- return defer.DeferredList(
- [firedByReactorThread, firedByOtherThread],
- fireOnOneErrback=True)
- return self._waitForThread().addCallback(cb)
-
-
- def test_wakerOverflow(self):
- """
- Try to make an overflow on the reactor waker using callFromThread.
- """
- def cb(ign):
- self.failure = None
- waiter = threading.Event()
- def threadedFunction():
- # Hopefully a hundred thousand queued calls is enough to
- # trigger the error condition
- for i in xrange(100000):
- try:
- reactor.callFromThread(lambda: None)
- except:
- self.failure = failure.Failure()
- break
- waiter.set()
- reactor.callInThread(threadedFunction)
- waiter.wait(120)
- if not waiter.isSet():
- self.fail("Timed out waiting for event")
- if self.failure is not None:
- return defer.fail(self.failure)
- return self._waitForThread().addCallback(cb)
-
- def _testBlockingCallFromThread(self, reactorFunc):
- """
- Utility method to test L{threads.blockingCallFromThread}.
- """
- waiter = threading.Event()
- results = []
- errors = []
- def cb1(ign):
- def threadedFunc():
- try:
- r = threads.blockingCallFromThread(reactor, reactorFunc)
- except Exception, e:
- errors.append(e)
- else:
- results.append(r)
- waiter.set()
-
- reactor.callInThread(threadedFunc)
- return threads.deferToThread(waiter.wait, self.getTimeout())
-
- def cb2(ign):
- if not waiter.isSet():
- self.fail("Timed out waiting for event")
- return results, errors
-
- return self._waitForThread().addCallback(cb1).addBoth(cb2)
-
- def test_blockingCallFromThread(self):
- """
- Test blockingCallFromThread facility: create a thread, call a function
- in the reactor using L{threads.blockingCallFromThread}, and verify the
- result returned.
- """
- def reactorFunc():
- return defer.succeed("foo")
- def cb(res):
- self.assertEqual(res[0][0], "foo")
-
- return self._testBlockingCallFromThread(reactorFunc).addCallback(cb)
-
- def test_asyncBlockingCallFromThread(self):
- """
- Test blockingCallFromThread as above, but be sure the resulting
- Deferred is not already fired.
- """
- def reactorFunc():
- d = defer.Deferred()
- reactor.callLater(0.1, d.callback, "egg")
- return d
- def cb(res):
- self.assertEqual(res[0][0], "egg")
-
- return self._testBlockingCallFromThread(reactorFunc).addCallback(cb)
-
- def test_errorBlockingCallFromThread(self):
- """
- Test error report for blockingCallFromThread.
- """
- def reactorFunc():
- return defer.fail(RuntimeError("bar"))
- def cb(res):
- self.assert_(isinstance(res[1][0], RuntimeError))
- self.assertEqual(res[1][0].args[0], "bar")
-
- return self._testBlockingCallFromThread(reactorFunc).addCallback(cb)
-
- def test_asyncErrorBlockingCallFromThread(self):
- """
- Test error report for blockingCallFromThread as above, but be sure the
- resulting Deferred is not already fired.
- """
- def reactorFunc():
- d = defer.Deferred()
- reactor.callLater(0.1, d.errback, RuntimeError("spam"))
- return d
- def cb(res):
- self.assert_(isinstance(res[1][0], RuntimeError))
- self.assertEqual(res[1][0].args[0], "spam")
-
- return self._testBlockingCallFromThread(reactorFunc).addCallback(cb)
-
-
-class Counter:
- index = 0
- problem = 0
-
- def add(self):
- """A non thread-safe method."""
- next = self.index + 1
- # another thread could jump in here and increment self.index on us
- if next != self.index + 1:
- self.problem = 1
- raise ValueError
- # or here, same issue but we wouldn't catch it. We'd overwrite
- # their results, and the index will have lost a count. If
- # several threads get in here, we will actually make the count
- # go backwards when we overwrite it.
- self.index = next
-
-
-
-class DeferredResultTestCase(unittest.TestCase):
- """
- Test twisted.internet.threads.
- """
-
- def setUp(self):
- reactor.suggestThreadPoolSize(8)
-
-
- def tearDown(self):
- reactor.suggestThreadPoolSize(0)
-
-
- def testCallMultiple(self):
- L = []
- N = 10
- d = defer.Deferred()
-
- def finished():
- self.assertEqual(L, range(N))
- d.callback(None)
-
- threads.callMultipleInThread([
- (L.append, (i,), {}) for i in xrange(N)
- ] + [(reactor.callFromThread, (finished,), {})])
- return d
-
-
- def test_deferredResult(self):
- """
- L{threads.deferToThread} executes the function passed, and correctly
- handles the positional and keyword arguments given.
- """
- d = threads.deferToThread(lambda x, y=5: x + y, 3, y=4)
- d.addCallback(self.assertEqual, 7)
- return d
-
-
- def test_deferredFailure(self):
- """
- Check that L{threads.deferToThread} return a failure object
- with an appropriate exception instance when the called
- function raises an exception.
- """
- class NewError(Exception):
- pass
- def raiseError():
- raise NewError()
- d = threads.deferToThread(raiseError)
- return self.assertFailure(d, NewError)
-
-
- def test_deferredFailureAfterSuccess(self):
- """
- Check that a successfull L{threads.deferToThread} followed by a one
- that raises an exception correctly result as a failure.
- """
- # set up a condition that causes cReactor to hang. These conditions
- # can also be set by other tests when the full test suite is run in
- # alphabetical order (test_flow.FlowTest.testThreaded followed by
- # test_internet.ReactorCoreTestCase.testStop, to be precise). By
- # setting them up explicitly here, we can reproduce the hang in a
- # single precise test case instead of depending upon side effects of
- # other tests.
- #
- # alas, this test appears to flunk the default reactor too
-
- d = threads.deferToThread(lambda: None)
- d.addCallback(lambda ign: threads.deferToThread(lambda: 1//0))
- return self.assertFailure(d, ZeroDivisionError)
-
-
-
-class DeferToThreadPoolTestCase(unittest.TestCase):
- """
- Test L{twisted.internet.threads.deferToThreadPool}.
- """
-
- def setUp(self):
- self.tp = threadpool.ThreadPool(0, 8)
- self.tp.start()
-
-
- def tearDown(self):
- self.tp.stop()
-
-
- def test_deferredResult(self):
- """
- L{threads.deferToThreadPool} executes the function passed, and
- correctly handles the positional and keyword arguments given.
- """
- d = threads.deferToThreadPool(reactor, self.tp,
- lambda x, y=5: x + y, 3, y=4)
- d.addCallback(self.assertEqual, 7)
- return d
-
-
- def test_deferredFailure(self):
- """
- Check that L{threads.deferToThreadPool} return a failure object with an
- appropriate exception instance when the called function raises an
- exception.
- """
- class NewError(Exception):
- pass
- def raiseError():
- raise NewError()
- d = threads.deferToThreadPool(reactor, self.tp, raiseError)
- return self.assertFailure(d, NewError)
-
-
-
-_callBeforeStartupProgram = """
-import time
-import %(reactor)s
-%(reactor)s.install()
-
-from twisted.internet import reactor
-
-def threadedCall():
- print 'threaded call'
-
-reactor.callInThread(threadedCall)
-
-# Spin very briefly to try to give the thread a chance to run, if it
-# is going to. Is there a better way to achieve this behavior?
-for i in xrange(100):
- time.sleep(0.0)
-"""
-
-
-class ThreadStartupProcessProtocol(protocol.ProcessProtocol):
- def __init__(self, finished):
- self.finished = finished
- self.out = []
- self.err = []
-
- def outReceived(self, out):
- self.out.append(out)
-
- def errReceived(self, err):
- self.err.append(err)
-
- def processEnded(self, reason):
- self.finished.callback((self.out, self.err, reason))
-
-
-
-class StartupBehaviorTestCase(unittest.TestCase):
- """
- Test cases for the behavior of the reactor threadpool near startup
- boundary conditions.
-
- In particular, this asserts that no threaded calls are attempted
- until the reactor starts up, that calls attempted before it starts
- are in fact executed once it has started, and that in both cases,
- the reactor properly cleans itself up (which is tested for
- somewhat implicitly, by requiring a child process be able to exit,
- something it cannot do unless the threadpool has been properly
- torn down).
- """
-
-
- def testCallBeforeStartupUnexecuted(self):
- progname = self.mktemp()
- progfile = file(progname, 'w')
- progfile.write(_callBeforeStartupProgram % {'reactor': reactor.__module__})
- progfile.close()
-
- def programFinished((out, err, reason)):
- if reason.check(error.ProcessTerminated):
- self.fail("Process did not exit cleanly (out: %s err: %s)" % (out, err))
-
- if err:
- log.msg("Unexpected output on standard error: %s" % (err,))
- self.failIf(out, "Expected no output, instead received:\n%s" % (out,))
-
- def programTimeout(err):
- err.trap(error.TimeoutError)
- proto.signalProcess('KILL')
- return err
-
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
- d = defer.Deferred().addCallbacks(programFinished, programTimeout)
- proto = ThreadStartupProcessProtocol(d)
- reactor.spawnProcess(proto, sys.executable, ('python', progname), env)
- return d
-
-
-
-if interfaces.IReactorThreads(reactor, None) is None:
- for cls in (ReactorThreadsTestCase,
- DeferredResultTestCase,
- StartupBehaviorTestCase):
- cls.skip = "No thread support, nothing to test here."
-else:
- import threading
-
-if interfaces.IReactorProcess(reactor, None) is None:
- for cls in (StartupBehaviorTestCase,):
- cls.skip = "No process support, cannot run subprocess thread tests."
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tpfile.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tpfile.py
deleted file mode 100755
index 655a166e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_tpfile.py
+++ /dev/null
@@ -1,52 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.trial import unittest
-from twisted.protocols import loopback
-from twisted.protocols import basic
-from twisted.internet import protocol, abstract
-
-import StringIO
-
-class BufferingServer(protocol.Protocol):
- buffer = ''
- def dataReceived(self, data):
- self.buffer += data
-
-class FileSendingClient(protocol.Protocol):
- def __init__(self, f):
- self.f = f
-
- def connectionMade(self):
- s = basic.FileSender()
- d = s.beginFileTransfer(self.f, self.transport, lambda x: x)
- d.addCallback(lambda r: self.transport.loseConnection())
-
-class FileSenderTestCase(unittest.TestCase):
- def testSendingFile(self):
- testStr = 'xyz' * 100 + 'abc' * 100 + '123' * 100
- s = BufferingServer()
- c = FileSendingClient(StringIO.StringIO(testStr))
-
- d = loopback.loopbackTCP(s, c)
- d.addCallback(lambda x : self.assertEqual(s.buffer, testStr))
- return d
-
- def testSendingEmptyFile(self):
- fileSender = basic.FileSender()
- consumer = abstract.FileDescriptor()
- consumer.connected = 1
- emptyFile = StringIO.StringIO('')
-
- d = fileSender.beginFileTransfer(emptyFile, consumer, lambda x: x)
-
- # The producer will be immediately exhausted, and so immediately
- # unregistered
- self.assertEqual(consumer.producer, None)
-
- # Which means the Deferred from FileSender should have been called
- self.failUnless(d.called,
- 'producer unregistered with deferred being called')
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_twistd.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_twistd.py
deleted file mode 100755
index d8ae6880..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_twistd.py
+++ /dev/null
@@ -1,1549 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.application.app} and L{twisted.scripts.twistd}.
-"""
-
-import signal, inspect, errno
-
-import os, sys, StringIO
-
-try:
- import pwd, grp
-except ImportError:
- pwd = grp = None
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.trial import unittest
-from twisted.test.test_process import MockOS
-
-from twisted import plugin
-from twisted.application.service import IServiceMaker
-from twisted.application import service, app, reactors
-from twisted.scripts import twistd
-from twisted.python import log
-from twisted.python.usage import UsageError
-from twisted.python.log import ILogObserver
-from twisted.python.versions import Version
-from twisted.python.components import Componentized
-from twisted.internet.defer import Deferred
-from twisted.internet.interfaces import IReactorDaemonize
-from twisted.python.fakepwd import UserDatabase
-
-try:
- from twisted.python import syslog
-except ImportError:
- syslog = None
-
-try:
- from twisted.scripts import _twistd_unix
-except ImportError:
- _twistd_unix = None
-else:
- from twisted.scripts._twistd_unix import UnixApplicationRunner
- from twisted.scripts._twistd_unix import UnixAppLogger
-
-try:
- import profile
-except ImportError:
- profile = None
-
-try:
- import hotshot
- import hotshot.stats
-except (ImportError, SystemExit):
- # For some reasons, hotshot.stats seems to raise SystemExit on some
- # distributions, probably when considered non-free. See the import of
- # this module in twisted.application.app for more details.
- hotshot = None
-
-try:
- import pstats
- import cProfile
-except ImportError:
- cProfile = None
-
-if getattr(os, 'setuid', None) is None:
- setuidSkip = "Platform does not support --uid/--gid twistd options."
-else:
- setuidSkip = None
-
-
-def patchUserDatabase(patch, user, uid, group, gid):
- """
- Patch L{pwd.getpwnam} so that it behaves as though only one user exists
- and patch L{grp.getgrnam} so that it behaves as though only one group
- exists.
-
- @param patch: A function like L{TestCase.patch} which will be used to
- install the fake implementations.
-
- @type user: C{str}
- @param user: The name of the single user which will exist.
-
- @type uid: C{int}
- @param uid: The UID of the single user which will exist.
-
- @type group: C{str}
- @param group: The name of the single user which will exist.
-
- @type gid: C{int}
- @param gid: The GID of the single group which will exist.
- """
- # Try not to be an unverified fake, but try not to depend on quirks of
- # the system either (eg, run as a process with a uid and gid which
- # equal each other, and so doesn't reliably test that uid is used where
- # uid should be used and gid is used where gid should be used). -exarkun
- pwent = pwd.getpwuid(os.getuid())
- grent = grp.getgrgid(os.getgid())
-
- database = UserDatabase()
- database.addUser(
- user, pwent.pw_passwd, uid, pwent.pw_gid,
- pwent.pw_gecos, pwent.pw_dir, pwent.pw_shell)
-
- def getgrnam(name):
- result = list(grent)
- result[result.index(grent.gr_name)] = group
- result[result.index(grent.gr_gid)] = gid
- result = tuple(result)
- return {group: result}[name]
-
- patch(pwd, "getpwnam", database.getpwnam)
- patch(grp, "getgrnam", getgrnam)
-
-
-
-class MockServiceMaker(object):
- """
- A non-implementation of L{twisted.application.service.IServiceMaker}.
- """
- tapname = 'ueoa'
-
- def makeService(self, options):
- """
- Take a L{usage.Options} instance and return a
- L{service.IService} provider.
- """
- self.options = options
- self.service = service.Service()
- return self.service
-
-
-
-class CrippledAppLogger(app.AppLogger):
- """
- @see: CrippledApplicationRunner.
- """
-
- def start(self, application):
- pass
-
-
-
-class CrippledApplicationRunner(twistd._SomeApplicationRunner):
- """
- An application runner that cripples the platform-specific runner and
- nasty side-effect-having code so that we can use it without actually
- running any environment-affecting code.
- """
- loggerFactory = CrippledAppLogger
-
- def preApplication(self):
- pass
-
-
- def postApplication(self):
- pass
-
-
-
-class ServerOptionsTest(unittest.TestCase):
- """
- Non-platform-specific tests for the pltaform-specific ServerOptions class.
- """
- def test_subCommands(self):
- """
- subCommands is built from IServiceMaker plugins, and is sorted
- alphabetically.
- """
- class FakePlugin(object):
- def __init__(self, name):
- self.tapname = name
- self._options = 'options for ' + name
- self.description = 'description of ' + name
-
- def options(self):
- return self._options
-
- apple = FakePlugin('apple')
- banana = FakePlugin('banana')
- coconut = FakePlugin('coconut')
- donut = FakePlugin('donut')
-
- def getPlugins(interface):
- self.assertEqual(interface, IServiceMaker)
- yield coconut
- yield banana
- yield donut
- yield apple
-
- config = twistd.ServerOptions()
- self.assertEqual(config._getPlugins, plugin.getPlugins)
- config._getPlugins = getPlugins
-
- # "subCommands is a list of 4-tuples of (command name, command
- # shortcut, parser class, documentation)."
- subCommands = config.subCommands
- expectedOrder = [apple, banana, coconut, donut]
-
- for subCommand, expectedCommand in zip(subCommands, expectedOrder):
- name, shortcut, parserClass, documentation = subCommand
- self.assertEqual(name, expectedCommand.tapname)
- self.assertEqual(shortcut, None)
- self.assertEqual(parserClass(), expectedCommand._options),
- self.assertEqual(documentation, expectedCommand.description)
-
-
- def test_sortedReactorHelp(self):
- """
- Reactor names are listed alphabetically by I{--help-reactors}.
- """
- class FakeReactorInstaller(object):
- def __init__(self, name):
- self.shortName = 'name of ' + name
- self.description = 'description of ' + name
-
- apple = FakeReactorInstaller('apple')
- banana = FakeReactorInstaller('banana')
- coconut = FakeReactorInstaller('coconut')
- donut = FakeReactorInstaller('donut')
-
- def getReactorTypes():
- yield coconut
- yield banana
- yield donut
- yield apple
-
- config = twistd.ServerOptions()
- self.assertEqual(config._getReactorTypes, reactors.getReactorTypes)
- config._getReactorTypes = getReactorTypes
- config.messageOutput = StringIO.StringIO()
-
- self.assertRaises(SystemExit, config.parseOptions, ['--help-reactors'])
- helpOutput = config.messageOutput.getvalue()
- indexes = []
- for reactor in apple, banana, coconut, donut:
- def getIndex(s):
- self.assertIn(s, helpOutput)
- indexes.append(helpOutput.index(s))
-
- getIndex(reactor.shortName)
- getIndex(reactor.description)
-
- self.assertEqual(
- indexes, sorted(indexes),
- 'reactor descriptions were not in alphabetical order: %r' % (
- helpOutput,))
-
-
- def test_postOptionsSubCommandCausesNoSave(self):
- """
- postOptions should set no_save to True when a subcommand is used.
- """
- config = twistd.ServerOptions()
- config.subCommand = 'ueoa'
- config.postOptions()
- self.assertEqual(config['no_save'], True)
-
-
- def test_postOptionsNoSubCommandSavesAsUsual(self):
- """
- If no sub command is used, postOptions should not touch no_save.
- """
- config = twistd.ServerOptions()
- config.postOptions()
- self.assertEqual(config['no_save'], False)
-
-
- def test_listAllProfilers(self):
- """
- All the profilers that can be used in L{app.AppProfiler} are listed in
- the help output.
- """
- config = twistd.ServerOptions()
- helpOutput = str(config)
- for profiler in app.AppProfiler.profilers:
- self.assertIn(profiler, helpOutput)
-
-
- def test_defaultUmask(self):
- """
- The default value for the C{umask} option is C{None}.
- """
- config = twistd.ServerOptions()
- self.assertEqual(config['umask'], None)
-
-
- def test_umask(self):
- """
- The value given for the C{umask} option is parsed as an octal integer
- literal.
- """
- config = twistd.ServerOptions()
- config.parseOptions(['--umask', '123'])
- self.assertEqual(config['umask'], 83)
- config.parseOptions(['--umask', '0123'])
- self.assertEqual(config['umask'], 83)
-
-
- def test_invalidUmask(self):
- """
- If a value is given for the C{umask} option which cannot be parsed as
- an integer, L{UsageError} is raised by L{ServerOptions.parseOptions}.
- """
- config = twistd.ServerOptions()
- self.assertRaises(UsageError, config.parseOptions, ['--umask', 'abcdef'])
-
- if _twistd_unix is None:
- msg = "twistd unix not available"
- test_defaultUmask.skip = test_umask.skip = test_invalidUmask.skip = msg
-
-
- def test_unimportableConfiguredLogObserver(self):
- """
- C{--logger} with an unimportable module raises a L{UsageError}.
- """
- config = twistd.ServerOptions()
- e = self.assertRaises(UsageError, config.parseOptions,
- ['--logger', 'no.such.module.I.hope'])
- self.assertTrue(e.args[0].startswith(
- "Logger 'no.such.module.I.hope' could not be imported: "
- "'no.such.module.I.hope' does not name an object"))
- self.assertNotIn('\n', e.args[0])
-
-
- def test_badAttributeWithConfiguredLogObserver(self):
- """
- C{--logger} with a non-existent object raises a L{UsageError}.
- """
- config = twistd.ServerOptions()
- e = self.assertRaises(UsageError, config.parseOptions,
- ["--logger", "twisted.test.test_twistd.FOOBAR"])
- self.assertTrue(e.args[0].startswith(
- "Logger 'twisted.test.test_twistd.FOOBAR' could not be "
- "imported: 'module' object has no attribute 'FOOBAR'"))
- self.assertNotIn('\n', e.args[0])
-
-
-
-class TapFileTest(unittest.TestCase):
- """
- Test twistd-related functionality that requires a tap file on disk.
- """
-
- def setUp(self):
- """
- Create a trivial Application and put it in a tap file on disk.
- """
- self.tapfile = self.mktemp()
- f = file(self.tapfile, 'wb')
- pickle.dump(service.Application("Hi!"), f)
- f.close()
-
-
- def test_createOrGetApplicationWithTapFile(self):
- """
- Ensure that the createOrGetApplication call that 'twistd -f foo.tap'
- makes will load the Application out of foo.tap.
- """
- config = twistd.ServerOptions()
- config.parseOptions(['-f', self.tapfile])
- application = CrippledApplicationRunner(config).createOrGetApplication()
- self.assertEqual(service.IService(application).name, 'Hi!')
-
-
-
-class TestLoggerFactory(object):
- """
- A logger factory for L{TestApplicationRunner}.
- """
-
- def __init__(self, runner):
- self.runner = runner
-
-
- def start(self, application):
- """
- Save the logging start on the C{runner} instance.
- """
- self.runner.order.append("log")
- self.runner.hadApplicationLogObserver = hasattr(self.runner,
- 'application')
-
-
- def stop(self):
- """
- Don't log anything.
- """
-
-
-
-class TestApplicationRunner(app.ApplicationRunner):
- """
- An ApplicationRunner which tracks the environment in which its methods are
- called.
- """
-
- def __init__(self, options):
- app.ApplicationRunner.__init__(self, options)
- self.order = []
- self.logger = TestLoggerFactory(self)
-
-
- def preApplication(self):
- self.order.append("pre")
- self.hadApplicationPreApplication = hasattr(self, 'application')
-
-
- def postApplication(self):
- self.order.append("post")
- self.hadApplicationPostApplication = hasattr(self, 'application')
-
-
-
-class ApplicationRunnerTest(unittest.TestCase):
- """
- Non-platform-specific tests for the platform-specific ApplicationRunner.
- """
- def setUp(self):
- config = twistd.ServerOptions()
- self.serviceMaker = MockServiceMaker()
- # Set up a config object like it's been parsed with a subcommand
- config.loadedPlugins = {'test_command': self.serviceMaker}
- config.subOptions = object()
- config.subCommand = 'test_command'
- self.config = config
-
-
- def test_applicationRunnerGetsCorrectApplication(self):
- """
- Ensure that a twistd plugin gets used in appropriate ways: it
- is passed its Options instance, and the service it returns is
- added to the application.
- """
- arunner = CrippledApplicationRunner(self.config)
- arunner.run()
-
- self.assertIdentical(
- self.serviceMaker.options, self.config.subOptions,
- "ServiceMaker.makeService needs to be passed the correct "
- "sub Command object.")
- self.assertIdentical(
- self.serviceMaker.service,
- service.IService(arunner.application).services[0],
- "ServiceMaker.makeService's result needs to be set as a child "
- "of the Application.")
-
-
- def test_preAndPostApplication(self):
- """
- Test thet preApplication and postApplication methods are
- called by ApplicationRunner.run() when appropriate.
- """
- s = TestApplicationRunner(self.config)
- s.run()
- self.assertFalse(s.hadApplicationPreApplication)
- self.assertTrue(s.hadApplicationPostApplication)
- self.assertTrue(s.hadApplicationLogObserver)
- self.assertEqual(s.order, ["pre", "log", "post"])
-
-
- def _applicationStartsWithConfiguredID(self, argv, uid, gid):
- """
- Assert that given a particular command line, an application is started
- as a particular UID/GID.
-
- @param argv: A list of strings giving the options to parse.
- @param uid: An integer giving the expected UID.
- @param gid: An integer giving the expected GID.
- """
- self.config.parseOptions(argv)
-
- events = []
- class FakeUnixApplicationRunner(twistd._SomeApplicationRunner):
- def setupEnvironment(self, chroot, rundir, nodaemon, umask,
- pidfile):
- events.append('environment')
-
- def shedPrivileges(self, euid, uid, gid):
- events.append(('privileges', euid, uid, gid))
-
- def startReactor(self, reactor, oldstdout, oldstderr):
- events.append('reactor')
-
- def removePID(self, pidfile):
- pass
-
-
- class FakeService(object):
- implements(service.IService, service.IProcess)
-
- processName = None
- uid = None
- gid = None
-
- def setName(self, name):
- pass
-
- def setServiceParent(self, parent):
- pass
-
- def disownServiceParent(self):
- pass
-
- def privilegedStartService(self):
- events.append('privilegedStartService')
-
- def startService(self):
- events.append('startService')
-
- def stopService(self):
- pass
-
- application = FakeService()
- verifyObject(service.IService, application)
- verifyObject(service.IProcess, application)
-
- runner = FakeUnixApplicationRunner(self.config)
- runner.preApplication()
- runner.application = application
- runner.postApplication()
-
- self.assertEqual(
- events,
- ['environment', 'privilegedStartService',
- ('privileges', False, uid, gid), 'startService', 'reactor'])
-
-
- def test_applicationStartsWithConfiguredNumericIDs(self):
- """
- L{postApplication} should change the UID and GID to the values
- specified as numeric strings by the configuration after running
- L{service.IService.privilegedStartService} and before running
- L{service.IService.startService}.
- """
- uid = 1234
- gid = 4321
- self._applicationStartsWithConfiguredID(
- ["--uid", str(uid), "--gid", str(gid)], uid, gid)
- test_applicationStartsWithConfiguredNumericIDs.skip = setuidSkip
-
-
- def test_applicationStartsWithConfiguredNameIDs(self):
- """
- L{postApplication} should change the UID and GID to the values
- specified as user and group names by the configuration after running
- L{service.IService.privilegedStartService} and before running
- L{service.IService.startService}.
- """
- user = "foo"
- uid = 1234
- group = "bar"
- gid = 4321
- patchUserDatabase(self.patch, user, uid, group, gid)
- self._applicationStartsWithConfiguredID(
- ["--uid", user, "--gid", group], uid, gid)
- test_applicationStartsWithConfiguredNameIDs.skip = setuidSkip
-
-
- def test_startReactorRunsTheReactor(self):
- """
- L{startReactor} calls L{reactor.run}.
- """
- reactor = DummyReactor()
- runner = app.ApplicationRunner({
- "profile": False,
- "profiler": "profile",
- "debug": False})
- runner.startReactor(reactor, None, None)
- self.assertTrue(
- reactor.called, "startReactor did not call reactor.run()")
-
-
-
-class UnixApplicationRunnerSetupEnvironmentTests(unittest.TestCase):
- """
- Tests for L{UnixApplicationRunner.setupEnvironment}.
-
- @ivar root: The root of the filesystem, or C{unset} if none has been
- specified with a call to L{os.chroot} (patched for this TestCase with
- L{UnixApplicationRunnerSetupEnvironmentTests.chroot ).
-
- @ivar cwd: The current working directory of the process, or C{unset} if
- none has been specified with a call to L{os.chdir} (patched for this
- TestCase with L{UnixApplicationRunnerSetupEnvironmentTests.chdir).
-
- @ivar mask: The current file creation mask of the process, or C{unset} if
- none has been specified with a call to L{os.umask} (patched for this
- TestCase with L{UnixApplicationRunnerSetupEnvironmentTests.umask).
-
- @ivar daemon: A boolean indicating whether daemonization has been performed
- by a call to L{_twistd_unix.daemonize} (patched for this TestCase with
- L{UnixApplicationRunnerSetupEnvironmentTests.
- """
- if _twistd_unix is None:
- skip = "twistd unix not available"
-
- unset = object()
-
- def setUp(self):
- self.root = self.unset
- self.cwd = self.unset
- self.mask = self.unset
- self.daemon = False
- self.pid = os.getpid()
- self.patch(os, 'chroot', lambda path: setattr(self, 'root', path))
- self.patch(os, 'chdir', lambda path: setattr(self, 'cwd', path))
- self.patch(os, 'umask', lambda mask: setattr(self, 'mask', mask))
- self.patch(_twistd_unix, "daemonize", self.daemonize)
- self.runner = UnixApplicationRunner({})
-
-
- def daemonize(self, reactor, os):
- """
- Indicate that daemonization has happened and change the PID so that the
- value written to the pidfile can be tested in the daemonization case.
- """
- self.daemon = True
- self.patch(os, 'getpid', lambda: self.pid + 1)
-
-
- def test_chroot(self):
- """
- L{UnixApplicationRunner.setupEnvironment} changes the root of the
- filesystem if passed a non-C{None} value for the C{chroot} parameter.
- """
- self.runner.setupEnvironment("/foo/bar", ".", True, None, None)
- self.assertEqual(self.root, "/foo/bar")
-
-
- def test_noChroot(self):
- """
- L{UnixApplicationRunner.setupEnvironment} does not change the root of
- the filesystem if passed C{None} for the C{chroot} parameter.
- """
- self.runner.setupEnvironment(None, ".", True, None, None)
- self.assertIdentical(self.root, self.unset)
-
-
- def test_changeWorkingDirectory(self):
- """
- L{UnixApplicationRunner.setupEnvironment} changes the working directory
- of the process to the path given for the C{rundir} parameter.
- """
- self.runner.setupEnvironment(None, "/foo/bar", True, None, None)
- self.assertEqual(self.cwd, "/foo/bar")
-
-
- def test_daemonize(self):
- """
- L{UnixApplicationRunner.setupEnvironment} daemonizes the process if
- C{False} is passed for the C{nodaemon} parameter.
- """
- self.runner.setupEnvironment(None, ".", False, None, None)
- self.assertTrue(self.daemon)
-
-
- def test_noDaemonize(self):
- """
- L{UnixApplicationRunner.setupEnvironment} does not daemonize the
- process if C{True} is passed for the C{nodaemon} parameter.
- """
- self.runner.setupEnvironment(None, ".", True, None, None)
- self.assertFalse(self.daemon)
-
-
- def test_nonDaemonPIDFile(self):
- """
- L{UnixApplicationRunner.setupEnvironment} writes the process's PID to
- the file specified by the C{pidfile} parameter.
- """
- pidfile = self.mktemp()
- self.runner.setupEnvironment(None, ".", True, None, pidfile)
- fObj = file(pidfile)
- pid = int(fObj.read())
- fObj.close()
- self.assertEqual(pid, self.pid)
-
-
- def test_daemonPIDFile(self):
- """
- L{UnixApplicationRunner.setupEnvironment} writes the daemonized
- process's PID to the file specified by the C{pidfile} parameter if
- C{nodaemon} is C{False}.
- """
- pidfile = self.mktemp()
- self.runner.setupEnvironment(None, ".", False, None, pidfile)
- fObj = file(pidfile)
- pid = int(fObj.read())
- fObj.close()
- self.assertEqual(pid, self.pid + 1)
-
-
- def test_umask(self):
- """
- L{UnixApplicationRunner.setupEnvironment} changes the process umask to
- the value specified by the C{umask} parameter.
- """
- self.runner.setupEnvironment(None, ".", False, 123, None)
- self.assertEqual(self.mask, 123)
-
-
- def test_noDaemonizeNoUmask(self):
- """
- L{UnixApplicationRunner.setupEnvironment} doesn't change the process
- umask if C{None} is passed for the C{umask} parameter and C{True} is
- passed for the C{nodaemon} parameter.
- """
- self.runner.setupEnvironment(None, ".", True, None, None)
- self.assertIdentical(self.mask, self.unset)
-
-
- def test_daemonizedNoUmask(self):
- """
- L{UnixApplicationRunner.setupEnvironment} changes the process umask to
- C{0077} if C{None} is passed for the C{umask} parameter and C{False} is
- passed for the C{nodaemon} parameter.
- """
- self.runner.setupEnvironment(None, ".", False, None, None)
- self.assertEqual(self.mask, 0077)
-
-
-
-class UnixApplicationRunnerStartApplicationTests(unittest.TestCase):
- """
- Tests for L{UnixApplicationRunner.startApplication}.
- """
- if _twistd_unix is None:
- skip = "twistd unix not available"
-
- def test_setupEnvironment(self):
- """
- L{UnixApplicationRunner.startApplication} calls
- L{UnixApplicationRunner.setupEnvironment} with the chroot, rundir,
- nodaemon, umask, and pidfile parameters from the configuration it is
- constructed with.
- """
- options = twistd.ServerOptions()
- options.parseOptions([
- '--nodaemon',
- '--umask', '0070',
- '--chroot', '/foo/chroot',
- '--rundir', '/foo/rundir',
- '--pidfile', '/foo/pidfile'])
- application = service.Application("test_setupEnvironment")
- self.runner = UnixApplicationRunner(options)
-
- args = []
- def fakeSetupEnvironment(self, chroot, rundir, nodaemon, umask, pidfile):
- args.extend((chroot, rundir, nodaemon, umask, pidfile))
-
- # Sanity check
- self.assertEqual(
- inspect.getargspec(self.runner.setupEnvironment),
- inspect.getargspec(fakeSetupEnvironment))
-
- self.patch(UnixApplicationRunner, 'setupEnvironment', fakeSetupEnvironment)
- self.patch(UnixApplicationRunner, 'shedPrivileges', lambda *a, **kw: None)
- self.patch(app, 'startApplication', lambda *a, **kw: None)
- self.runner.startApplication(application)
-
- self.assertEqual(
- args,
- ['/foo/chroot', '/foo/rundir', True, 56, '/foo/pidfile'])
-
-
-
-class UnixApplicationRunnerRemovePID(unittest.TestCase):
- """
- Tests for L{UnixApplicationRunner.removePID}.
- """
- if _twistd_unix is None:
- skip = "twistd unix not available"
-
-
- def test_removePID(self):
- """
- L{UnixApplicationRunner.removePID} deletes the file the name of
- which is passed to it.
- """
- runner = UnixApplicationRunner({})
- path = self.mktemp()
- os.makedirs(path)
- pidfile = os.path.join(path, "foo.pid")
- file(pidfile, "w").close()
- runner.removePID(pidfile)
- self.assertFalse(os.path.exists(pidfile))
-
-
- def test_removePIDErrors(self):
- """
- Calling L{UnixApplicationRunner.removePID} with a non-existent filename logs
- an OSError.
- """
- runner = UnixApplicationRunner({})
- runner.removePID("fakepid")
- errors = self.flushLoggedErrors(OSError)
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0].value.errno, errno.ENOENT)
-
-
-
-class FakeNonDaemonizingReactor(object):
- """
- A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize} methods,
- but not announcing this, and logging whether the methods have been called.
-
- @ivar _beforeDaemonizeCalled: if C{beforeDaemonize} has been called or not.
- @type _beforeDaemonizeCalled: C{bool}
- @ivar _afterDaemonizeCalled: if C{afterDaemonize} has been called or not.
- @type _afterDaemonizeCalled: C{bool}
- """
-
- def __init__(self):
- self._beforeDaemonizeCalled = False
- self._afterDaemonizeCalled = False
-
- def beforeDaemonize(self):
- self._beforeDaemonizeCalled = True
-
- def afterDaemonize(self):
- self._afterDaemonizeCalled = True
-
-
-
-class FakeDaemonizingReactor(FakeNonDaemonizingReactor):
- """
- A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize} methods,
- announcing this, and logging whether the methods have been called.
- """
-
- implements(IReactorDaemonize)
-
-
-
-class ReactorDaemonizationTests(unittest.TestCase):
- """
- Tests for L{_twistd_unix.daemonize} and L{IReactorDaemonize}.
- """
- if _twistd_unix is None:
- skip = "twistd unix not available"
-
-
- def test_daemonizationHooksCalled(self):
- """
- L{_twistd_unix.daemonize} indeed calls
- L{IReactorDaemonize.beforeDaemonize} and
- L{IReactorDaemonize.afterDaemonize} if the reactor implements
- L{IReactorDaemonize}.
- """
- reactor = FakeDaemonizingReactor()
- os = MockOS()
- _twistd_unix.daemonize(reactor, os)
- self.assertTrue(reactor._beforeDaemonizeCalled)
- self.assertTrue(reactor._afterDaemonizeCalled)
-
-
- def test_daemonizationHooksNotCalled(self):
- """
- L{_twistd_unix.daemonize} does NOT call
- L{IReactorDaemonize.beforeDaemonize} or
- L{IReactorDaemonize.afterDaemonize} if the reactor does NOT
- implement L{IReactorDaemonize}.
- """
- reactor = FakeNonDaemonizingReactor()
- os = MockOS()
- _twistd_unix.daemonize(reactor, os)
- self.assertFalse(reactor._beforeDaemonizeCalled)
- self.assertFalse(reactor._afterDaemonizeCalled)
-
-
-
-class DummyReactor(object):
- """
- A dummy reactor, only providing a C{run} method and checking that it
- has been called.
-
- @ivar called: if C{run} has been called or not.
- @type called: C{bool}
- """
- called = False
-
- def run(self):
- """
- A fake run method, checking that it's been called one and only time.
- """
- if self.called:
- raise RuntimeError("Already called")
- self.called = True
-
-
-
-class AppProfilingTestCase(unittest.TestCase):
- """
- Tests for L{app.AppProfiler}.
- """
-
- def test_profile(self):
- """
- L{app.ProfileRunner.run} should call the C{run} method of the reactor
- and save profile data in the specified file.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "profile"
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- profiler.run(reactor)
-
- self.assertTrue(reactor.called)
- data = file(config["profile"]).read()
- self.assertIn("DummyReactor.run", data)
- self.assertIn("function calls", data)
-
- if profile is None:
- test_profile.skip = "profile module not available"
-
-
- def _testStats(self, statsClass, profile):
- out = StringIO.StringIO()
-
- # Patch before creating the pstats, because pstats binds self.stream to
- # sys.stdout early in 2.5 and newer.
- stdout = self.patch(sys, 'stdout', out)
-
- # If pstats.Stats can load the data and then reformat it, then the
- # right thing probably happened.
- stats = statsClass(profile)
- stats.print_stats()
- stdout.restore()
-
- data = out.getvalue()
- self.assertIn("function calls", data)
- self.assertIn("(run)", data)
-
-
- def test_profileSaveStats(self):
- """
- With the C{savestats} option specified, L{app.ProfileRunner.run}
- should save the raw stats object instead of a summary output.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "profile"
- config["savestats"] = True
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- profiler.run(reactor)
-
- self.assertTrue(reactor.called)
- self._testStats(pstats.Stats, config['profile'])
-
- if profile is None:
- test_profileSaveStats.skip = "profile module not available"
-
-
- def test_withoutProfile(self):
- """
- When the C{profile} module is not present, L{app.ProfilerRunner.run}
- should raise a C{SystemExit} exception.
- """
- savedModules = sys.modules.copy()
-
- config = twistd.ServerOptions()
- config["profiler"] = "profile"
- profiler = app.AppProfiler(config)
-
- sys.modules["profile"] = None
- try:
- self.assertRaises(SystemExit, profiler.run, None)
- finally:
- sys.modules.clear()
- sys.modules.update(savedModules)
-
-
- def test_profilePrintStatsError(self):
- """
- When an error happens during the print of the stats, C{sys.stdout}
- should be restored to its initial value.
- """
- class ErroneousProfile(profile.Profile):
- def print_stats(self):
- raise RuntimeError("Boom")
- self.patch(profile, "Profile", ErroneousProfile)
-
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "profile"
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- oldStdout = sys.stdout
- self.assertRaises(RuntimeError, profiler.run, reactor)
- self.assertIdentical(sys.stdout, oldStdout)
-
- if profile is None:
- test_profilePrintStatsError.skip = "profile module not available"
-
-
- def test_hotshot(self):
- """
- L{app.HotshotRunner.run} should call the C{run} method of the reactor
- and save profile data in the specified file.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "hotshot"
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- profiler.run(reactor)
-
- self.assertTrue(reactor.called)
- data = file(config["profile"]).read()
- self.assertIn("run", data)
- self.assertIn("function calls", data)
-
- if hotshot is None:
- test_hotshot.skip = "hotshot module not available"
-
-
- def test_hotshotSaveStats(self):
- """
- With the C{savestats} option specified, L{app.HotshotRunner.run} should
- save the raw stats object instead of a summary output.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "hotshot"
- config["savestats"] = True
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- profiler.run(reactor)
-
- self.assertTrue(reactor.called)
- self._testStats(hotshot.stats.load, config['profile'])
-
- if hotshot is None:
- test_hotshotSaveStats.skip = "hotshot module not available"
-
-
- def test_withoutHotshot(self):
- """
- When the C{hotshot} module is not present, L{app.HotshotRunner.run}
- should raise a C{SystemExit} exception and log the C{ImportError}.
- """
- savedModules = sys.modules.copy()
- sys.modules["hotshot"] = None
-
- config = twistd.ServerOptions()
- config["profiler"] = "hotshot"
- profiler = app.AppProfiler(config)
- try:
- self.assertRaises(SystemExit, profiler.run, None)
- finally:
- sys.modules.clear()
- sys.modules.update(savedModules)
-
-
- def test_hotshotPrintStatsError(self):
- """
- When an error happens while printing the stats, C{sys.stdout}
- should be restored to its initial value.
- """
- class ErroneousStats(pstats.Stats):
- def print_stats(self):
- raise RuntimeError("Boom")
- self.patch(pstats, "Stats", ErroneousStats)
-
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "hotshot"
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- oldStdout = sys.stdout
- self.assertRaises(RuntimeError, profiler.run, reactor)
- self.assertIdentical(sys.stdout, oldStdout)
-
- if hotshot is None:
- test_hotshotPrintStatsError.skip = "hotshot module not available"
-
-
- def test_cProfile(self):
- """
- L{app.CProfileRunner.run} should call the C{run} method of the
- reactor and save profile data in the specified file.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "cProfile"
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- profiler.run(reactor)
-
- self.assertTrue(reactor.called)
- data = file(config["profile"]).read()
- self.assertIn("run", data)
- self.assertIn("function calls", data)
-
- if cProfile is None:
- test_cProfile.skip = "cProfile module not available"
-
-
- def test_cProfileSaveStats(self):
- """
- With the C{savestats} option specified,
- L{app.CProfileRunner.run} should save the raw stats object
- instead of a summary output.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "cProfile"
- config["savestats"] = True
- profiler = app.AppProfiler(config)
- reactor = DummyReactor()
-
- profiler.run(reactor)
-
- self.assertTrue(reactor.called)
- self._testStats(pstats.Stats, config['profile'])
-
- if cProfile is None:
- test_cProfileSaveStats.skip = "cProfile module not available"
-
-
- def test_withoutCProfile(self):
- """
- When the C{cProfile} module is not present,
- L{app.CProfileRunner.run} should raise a C{SystemExit}
- exception and log the C{ImportError}.
- """
- savedModules = sys.modules.copy()
- sys.modules["cProfile"] = None
-
- config = twistd.ServerOptions()
- config["profiler"] = "cProfile"
- profiler = app.AppProfiler(config)
- try:
- self.assertRaises(SystemExit, profiler.run, None)
- finally:
- sys.modules.clear()
- sys.modules.update(savedModules)
-
-
- def test_unknownProfiler(self):
- """
- Check that L{app.AppProfiler} raises L{SystemExit} when given an
- unknown profiler name.
- """
- config = twistd.ServerOptions()
- config["profile"] = self.mktemp()
- config["profiler"] = "foobar"
-
- error = self.assertRaises(SystemExit, app.AppProfiler, config)
- self.assertEqual(str(error), "Unsupported profiler name: foobar")
-
-
- def test_defaultProfiler(self):
- """
- L{app.Profiler} defaults to the hotshot profiler if not specified.
- """
- profiler = app.AppProfiler({})
- self.assertEqual(profiler.profiler, "hotshot")
-
-
- def test_profilerNameCaseInsentive(self):
- """
- The case of the profiler name passed to L{app.AppProfiler} is not
- relevant.
- """
- profiler = app.AppProfiler({"profiler": "HotShot"})
- self.assertEqual(profiler.profiler, "hotshot")
-
-
-
-def _patchFileLogObserver(patch):
- """
- Patch L{log.FileLogObserver} to record every call and keep a reference to
- the passed log file for tests.
-
- @param patch: a callback for patching (usually L{unittest.TestCase.patch}).
-
- @return: the list that keeps track of the log files.
- @rtype: C{list}
- """
- logFiles = []
- oldFileLobObserver = log.FileLogObserver
- def FileLogObserver(logFile):
- logFiles.append(logFile)
- return oldFileLobObserver(logFile)
- patch(log, 'FileLogObserver', FileLogObserver)
- return logFiles
-
-
-
-def _setupSyslog(testCase):
- """
- Make fake syslog, and return list to which prefix and then log
- messages will be appended if it is used.
- """
- logMessages = []
- class fakesyslogobserver(object):
- def __init__(self, prefix):
- logMessages.append(prefix)
- def emit(self, eventDict):
- logMessages.append(eventDict)
- testCase.patch(syslog, "SyslogObserver", fakesyslogobserver)
- return logMessages
-
-
-
-class AppLoggerTestCase(unittest.TestCase):
- """
- Tests for L{app.AppLogger}.
-
- @ivar observers: list of observers installed during the tests.
- @type observers: C{list}
- """
-
- def setUp(self):
- """
- Override L{log.addObserver} so that we can trace the observers
- installed in C{self.observers}.
- """
- self.observers = []
- def startLoggingWithObserver(observer):
- self.observers.append(observer)
- log.addObserver(observer)
- self.patch(log, 'startLoggingWithObserver', startLoggingWithObserver)
-
-
- def tearDown(self):
- """
- Remove all installed observers.
- """
- for observer in self.observers:
- log.removeObserver(observer)
-
-
- def _checkObserver(self, logs):
- """
- Ensure that initial C{twistd} logs are written to the given list.
-
- @type logs: C{list}
- @param logs: The list whose C{append} method was specified as the
- initial log observer.
- """
- self.assertEqual(self.observers, [logs.append])
- self.assertIn("starting up", logs[0]["message"][0])
- self.assertIn("reactor class", logs[1]["message"][0])
-
-
- def test_start(self):
- """
- L{app.AppLogger.start} calls L{log.addObserver}, and then writes some
- messages about twistd and the reactor.
- """
- logger = app.AppLogger({})
- observer = []
- logger._getLogObserver = lambda: observer.append
- logger.start(Componentized())
- self._checkObserver(observer)
-
-
- def test_startUsesApplicationLogObserver(self):
- """
- When the L{ILogObserver} component is available on the application,
- that object will be used as the log observer instead of constructing a
- new one.
- """
- application = Componentized()
- logs = []
- application.setComponent(ILogObserver, logs.append)
- logger = app.AppLogger({})
- logger.start(application)
- self._checkObserver(logs)
-
-
- def _setupConfiguredLogger(self, application, extraLogArgs={},
- appLogger=app.AppLogger):
- """
- Set up an AppLogger which exercises the C{logger} configuration option.
-
- @type application: L{Componentized}
- @param application: The L{Application} object to pass to
- L{app.AppLogger.start}.
- @type extraLogArgs: C{dict}
- @param extraLogArgs: extra values to pass to AppLogger.
- @type appLogger: L{AppLogger} class, or a subclass
- @param appLogger: factory for L{AppLogger} instances.
-
- @rtype: C{list}
- @return: The logs accumulated by the log observer.
- """
- logs = []
- logArgs = {"logger": lambda: logs.append}
- logArgs.update(extraLogArgs)
- logger = appLogger(logArgs)
- logger.start(application)
- return logs
-
-
- def test_startUsesConfiguredLogObserver(self):
- """
- When the C{logger} key is specified in the configuration dictionary
- (i.e., when C{--logger} is passed to twistd), the initial log observer
- will be the log observer returned from the callable which the value
- refers to in FQPN form.
- """
- application = Componentized()
- self._checkObserver(self._setupConfiguredLogger(application))
-
-
- def test_configuredLogObserverBeatsComponent(self):
- """
- C{--logger} takes precedence over a ILogObserver component set on
- Application.
- """
- nonlogs = []
- application = Componentized()
- application.setComponent(ILogObserver, nonlogs.append)
- self._checkObserver(self._setupConfiguredLogger(application))
- self.assertEqual(nonlogs, [])
-
-
- def test_configuredLogObserverBeatsSyslog(self):
- """
- C{--logger} takes precedence over a C{--syslog} command line
- argument.
- """
- logs = _setupSyslog(self)
- application = Componentized()
- self._checkObserver(self._setupConfiguredLogger(application,
- {"syslog": True},
- UnixAppLogger))
- self.assertEqual(logs, [])
-
- if _twistd_unix is None or syslog is None:
- test_configuredLogObserverBeatsSyslog.skip = "Not on POSIX, or syslog not available."
-
-
- def test_configuredLogObserverBeatsLogfile(self):
- """
- C{--logger} takes precedence over a C{--logfile} command line
- argument.
- """
- application = Componentized()
- path = self.mktemp()
- self._checkObserver(self._setupConfiguredLogger(application,
- {"logfile": "path"}))
- self.assertFalse(os.path.exists(path))
-
-
- def test_getLogObserverStdout(self):
- """
- When logfile is empty or set to C{-}, L{app.AppLogger._getLogObserver}
- returns a log observer pointing at C{sys.stdout}.
- """
- logger = app.AppLogger({"logfile": "-"})
- logFiles = _patchFileLogObserver(self.patch)
-
- observer = logger._getLogObserver()
-
- self.assertEqual(len(logFiles), 1)
- self.assertIdentical(logFiles[0], sys.stdout)
-
- logger = app.AppLogger({"logfile": ""})
- observer = logger._getLogObserver()
-
- self.assertEqual(len(logFiles), 2)
- self.assertIdentical(logFiles[1], sys.stdout)
-
-
- def test_getLogObserverFile(self):
- """
- When passing the C{logfile} option, L{app.AppLogger._getLogObserver}
- returns a log observer pointing at the specified path.
- """
- logFiles = _patchFileLogObserver(self.patch)
- filename = self.mktemp()
- logger = app.AppLogger({"logfile": filename})
-
- observer = logger._getLogObserver()
-
- self.assertEqual(len(logFiles), 1)
- self.assertEqual(logFiles[0].path,
- os.path.abspath(filename))
-
-
- def test_stop(self):
- """
- L{app.AppLogger.stop} removes the observer created in C{start}, and
- reinitialize its C{_observer} so that if C{stop} is called several
- times it doesn't break.
- """
- removed = []
- observer = object()
- def remove(observer):
- removed.append(observer)
- self.patch(log, 'removeObserver', remove)
- logger = app.AppLogger({})
- logger._observer = observer
- logger.stop()
- self.assertEqual(removed, [observer])
- logger.stop()
- self.assertEqual(removed, [observer])
- self.assertIdentical(logger._observer, None)
-
-
-
-class UnixAppLoggerTestCase(unittest.TestCase):
- """
- Tests for L{UnixAppLogger}.
-
- @ivar signals: list of signal handlers installed.
- @type signals: C{list}
- """
- if _twistd_unix is None:
- skip = "twistd unix not available"
-
- def setUp(self):
- """
- Fake C{signal.signal} for not installing the handlers but saving them
- in C{self.signals}.
- """
- self.signals = []
- def fakeSignal(sig, f):
- self.signals.append((sig, f))
- self.patch(signal, "signal", fakeSignal)
-
-
- def test_getLogObserverStdout(self):
- """
- When non-daemonized and C{logfile} is empty or set to C{-},
- L{UnixAppLogger._getLogObserver} returns a log observer pointing at
- C{sys.stdout}.
- """
- logFiles = _patchFileLogObserver(self.patch)
-
- logger = UnixAppLogger({"logfile": "-", "nodaemon": True})
- observer = logger._getLogObserver()
- self.assertEqual(len(logFiles), 1)
- self.assertIdentical(logFiles[0], sys.stdout)
-
- logger = UnixAppLogger({"logfile": "", "nodaemon": True})
- observer = logger._getLogObserver()
- self.assertEqual(len(logFiles), 2)
- self.assertIdentical(logFiles[1], sys.stdout)
-
-
- def test_getLogObserverStdoutDaemon(self):
- """
- When daemonized and C{logfile} is set to C{-},
- L{UnixAppLogger._getLogObserver} raises C{SystemExit}.
- """
- logger = UnixAppLogger({"logfile": "-", "nodaemon": False})
- error = self.assertRaises(SystemExit, logger._getLogObserver)
- self.assertEqual(str(error), "Daemons cannot log to stdout, exiting!")
-
-
- def test_getLogObserverFile(self):
- """
- When C{logfile} contains a file name, L{app.AppLogger._getLogObserver}
- returns a log observer pointing at the specified path, and a signal
- handler rotating the log is installed.
- """
- logFiles = _patchFileLogObserver(self.patch)
- filename = self.mktemp()
- logger = UnixAppLogger({"logfile": filename})
- observer = logger._getLogObserver()
-
- self.assertEqual(len(logFiles), 1)
- self.assertEqual(logFiles[0].path,
- os.path.abspath(filename))
-
- self.assertEqual(len(self.signals), 1)
- self.assertEqual(self.signals[0][0], signal.SIGUSR1)
-
- d = Deferred()
- def rotate():
- d.callback(None)
- logFiles[0].rotate = rotate
-
- rotateLog = self.signals[0][1]
- rotateLog(None, None)
- return d
-
-
- def test_getLogObserverDontOverrideSignalHandler(self):
- """
- If a signal handler is already installed,
- L{UnixAppLogger._getLogObserver} doesn't override it.
- """
- def fakeGetSignal(sig):
- self.assertEqual(sig, signal.SIGUSR1)
- return object()
- self.patch(signal, "getsignal", fakeGetSignal)
- filename = self.mktemp()
- logger = UnixAppLogger({"logfile": filename})
- observer = logger._getLogObserver()
-
- self.assertEqual(self.signals, [])
-
-
- def test_getLogObserverDefaultFile(self):
- """
- When daemonized and C{logfile} is empty, the observer returned by
- L{UnixAppLogger._getLogObserver} points at C{twistd.log} in the current
- directory.
- """
- logFiles = _patchFileLogObserver(self.patch)
- logger = UnixAppLogger({"logfile": "", "nodaemon": False})
- observer = logger._getLogObserver()
-
- self.assertEqual(len(logFiles), 1)
- self.assertEqual(logFiles[0].path,
- os.path.abspath("twistd.log"))
-
-
- def test_getLogObserverSyslog(self):
- """
- If C{syslog} is set to C{True}, L{UnixAppLogger._getLogObserver} starts
- a L{syslog.SyslogObserver} with given C{prefix}.
- """
- logs = _setupSyslog(self)
- logger = UnixAppLogger({"syslog": True, "prefix": "test-prefix"})
- observer = logger._getLogObserver()
- self.assertEqual(logs, ["test-prefix"])
- observer({"a": "b"})
- self.assertEqual(logs, ["test-prefix", {"a": "b"}])
-
- if syslog is None:
- test_getLogObserverSyslog.skip = "Syslog not available"
-
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_udp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_udp.py
deleted file mode 100755
index 92ebceca..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_udp.py
+++ /dev/null
@@ -1,721 +0,0 @@
-# -*- test-case-name: twisted.test.test_udp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorUDP} and L{IReactorMulticast}.
-"""
-
-from twisted.trial import unittest
-
-from twisted.internet.defer import Deferred, gatherResults, maybeDeferred
-from twisted.internet import protocol, reactor, error, defer, interfaces, udp
-from twisted.python import runtime
-
-
-class Mixin:
-
- started = 0
- stopped = 0
-
- startedDeferred = None
-
- def __init__(self):
- self.packets = []
-
- def startProtocol(self):
- self.started = 1
- if self.startedDeferred is not None:
- d, self.startedDeferred = self.startedDeferred, None
- d.callback(None)
-
- def stopProtocol(self):
- self.stopped = 1
-
-
-class Server(Mixin, protocol.DatagramProtocol):
- packetReceived = None
- refused = 0
-
-
- def datagramReceived(self, data, addr):
- self.packets.append((data, addr))
- if self.packetReceived is not None:
- d, self.packetReceived = self.packetReceived, None
- d.callback(None)
-
-
-
-class Client(Mixin, protocol.ConnectedDatagramProtocol):
-
- packetReceived = None
- refused = 0
-
- def datagramReceived(self, data):
- self.packets.append(data)
- if self.packetReceived is not None:
- d, self.packetReceived = self.packetReceived, None
- d.callback(None)
-
- def connectionFailed(self, failure):
- if self.startedDeferred is not None:
- d, self.startedDeferred = self.startedDeferred, None
- d.errback(failure)
- self.failure = failure
-
- def connectionRefused(self):
- if self.startedDeferred is not None:
- d, self.startedDeferred = self.startedDeferred, None
- d.errback(error.ConnectionRefusedError("yup"))
- self.refused = 1
-
-
-class GoodClient(Server):
-
- def connectionRefused(self):
- if self.startedDeferred is not None:
- d, self.startedDeferred = self.startedDeferred, None
- d.errback(error.ConnectionRefusedError("yup"))
- self.refused = 1
-
-
-
-class BadClientError(Exception):
- """
- Raised by BadClient at the end of every datagramReceived call to try and
- screw stuff up.
- """
-
-
-
-class BadClient(protocol.DatagramProtocol):
- """
- A DatagramProtocol which always raises an exception from datagramReceived.
- Used to test error handling behavior in the reactor for that method.
- """
- d = None
-
- def setDeferred(self, d):
- """
- Set the Deferred which will be called back when datagramReceived is
- called.
- """
- self.d = d
-
-
- def datagramReceived(self, bytes, addr):
- if self.d is not None:
- d, self.d = self.d, None
- d.callback(bytes)
- raise BadClientError("Application code is very buggy!")
-
-
-
-class UDPTestCase(unittest.TestCase):
-
- def test_oldAddress(self):
- """
- The C{type} of the host address of a listening L{DatagramProtocol}'s
- transport is C{"UDP"}.
- """
- server = Server()
- d = server.startedDeferred = defer.Deferred()
- p = reactor.listenUDP(0, server, interface="127.0.0.1")
- def cbStarted(ignored):
- addr = p.getHost()
- self.assertEqual(addr.type, 'UDP')
- return p.stopListening()
- return d.addCallback(cbStarted)
-
-
- def test_startStop(self):
- """
- The L{DatagramProtocol}'s C{startProtocol} and C{stopProtocol}
- methods are called when its transports starts and stops listening,
- respectively.
- """
- server = Server()
- d = server.startedDeferred = defer.Deferred()
- port1 = reactor.listenUDP(0, server, interface="127.0.0.1")
- def cbStarted(ignored):
- self.assertEqual(server.started, 1)
- self.assertEqual(server.stopped, 0)
- return port1.stopListening()
- def cbStopped(ignored):
- self.assertEqual(server.stopped, 1)
- return d.addCallback(cbStarted).addCallback(cbStopped)
-
-
- def test_rebind(self):
- """
- Re-listening with the same L{DatagramProtocol} re-invokes the
- C{startProtocol} callback.
- """
- server = Server()
- d = server.startedDeferred = defer.Deferred()
- p = reactor.listenUDP(0, server, interface="127.0.0.1")
-
- def cbStarted(ignored, port):
- return port.stopListening()
-
- def cbStopped(ignored):
- d = server.startedDeferred = defer.Deferred()
- p = reactor.listenUDP(0, server, interface="127.0.0.1")
- return d.addCallback(cbStarted, p)
-
- return d.addCallback(cbStarted, p)
-
-
- def test_bindError(self):
- """
- A L{CannotListenError} exception is raised when attempting to bind a
- second protocol instance to an already bound port
- """
- server = Server()
- d = server.startedDeferred = defer.Deferred()
- port = reactor.listenUDP(0, server, interface='127.0.0.1')
-
- def cbStarted(ignored):
- self.assertEqual(port.getHost(), server.transport.getHost())
- server2 = Server()
- self.assertRaises(
- error.CannotListenError,
- reactor.listenUDP, port.getHost().port, server2,
- interface='127.0.0.1')
- d.addCallback(cbStarted)
-
- def cbFinished(ignored):
- return port.stopListening()
- d.addCallback(cbFinished)
- return d
-
-
- def test_sendPackets(self):
- """
- Datagrams can be sent with the transport's C{write} method and
- received via the C{datagramReceived} callback method.
- """
- server = Server()
- serverStarted = server.startedDeferred = defer.Deferred()
- port1 = reactor.listenUDP(0, server, interface="127.0.0.1")
-
- client = GoodClient()
- clientStarted = client.startedDeferred = defer.Deferred()
-
- def cbServerStarted(ignored):
- self.port2 = reactor.listenUDP(0, client, interface="127.0.0.1")
- return clientStarted
-
- d = serverStarted.addCallback(cbServerStarted)
-
- def cbClientStarted(ignored):
- client.transport.connect("127.0.0.1",
- server.transport.getHost().port)
- cAddr = client.transport.getHost()
- sAddr = server.transport.getHost()
-
- serverSend = client.packetReceived = defer.Deferred()
- server.transport.write("hello", (cAddr.host, cAddr.port))
-
- clientWrites = [
- ("a",),
- ("b", None),
- ("c", (sAddr.host, sAddr.port))]
-
- def cbClientSend(ignored):
- if clientWrites:
- nextClientWrite = server.packetReceived = defer.Deferred()
- nextClientWrite.addCallback(cbClientSend)
- client.transport.write(*clientWrites.pop(0))
- return nextClientWrite
-
- # No one will ever call .errback on either of these Deferreds,
- # but there is a non-trivial amount of test code which might
- # cause them to fail somehow. So fireOnOneErrback=True.
- return defer.DeferredList([
- cbClientSend(None),
- serverSend],
- fireOnOneErrback=True)
-
- d.addCallback(cbClientStarted)
-
- def cbSendsFinished(ignored):
- cAddr = client.transport.getHost()
- sAddr = server.transport.getHost()
- self.assertEqual(
- client.packets,
- [("hello", (sAddr.host, sAddr.port))])
- clientAddr = (cAddr.host, cAddr.port)
- self.assertEqual(
- server.packets,
- [("a", clientAddr),
- ("b", clientAddr),
- ("c", clientAddr)])
-
- d.addCallback(cbSendsFinished)
-
- def cbFinished(ignored):
- return defer.DeferredList([
- defer.maybeDeferred(port1.stopListening),
- defer.maybeDeferred(self.port2.stopListening)],
- fireOnOneErrback=True)
-
- d.addCallback(cbFinished)
- return d
-
-
- def test_connectionRefused(self):
- """
- A L{ConnectionRefusedError} exception is raised when a connection
- attempt is actively refused by the other end.
-
- Note: This test assumes no one is listening on port 80 UDP.
- """
- client = GoodClient()
- clientStarted = client.startedDeferred = defer.Deferred()
- port = reactor.listenUDP(0, client, interface="127.0.0.1")
-
- server = Server()
- serverStarted = server.startedDeferred = defer.Deferred()
- port2 = reactor.listenUDP(0, server, interface="127.0.0.1")
-
- d = defer.DeferredList(
- [clientStarted, serverStarted],
- fireOnOneErrback=True)
-
- def cbStarted(ignored):
- connectionRefused = client.startedDeferred = defer.Deferred()
- client.transport.connect("127.0.0.1", 80)
-
- for i in range(10):
- client.transport.write(str(i))
- server.transport.write(str(i), ("127.0.0.1", 80))
-
- return self.assertFailure(
- connectionRefused,
- error.ConnectionRefusedError)
-
- d.addCallback(cbStarted)
-
- def cbFinished(ignored):
- return defer.DeferredList([
- defer.maybeDeferred(port.stopListening),
- defer.maybeDeferred(port2.stopListening)],
- fireOnOneErrback=True)
-
- d.addCallback(cbFinished)
- return d
-
-
- def test_badConnect(self):
- """
- A call to the transport's connect method fails with a L{ValueError}
- when a non-IP address is passed as the host value.
-
- A call to a transport's connect method fails with a L{RuntimeError}
- when the transport is already connected.
- """
- client = GoodClient()
- port = reactor.listenUDP(0, client, interface="127.0.0.1")
- self.assertRaises(ValueError, client.transport.connect,
- "localhost", 80)
- client.transport.connect("127.0.0.1", 80)
- self.assertRaises(RuntimeError, client.transport.connect,
- "127.0.0.1", 80)
- return port.stopListening()
-
-
-
- def test_datagramReceivedError(self):
- """
- When datagramReceived raises an exception it is logged but the port
- is not disconnected.
- """
- finalDeferred = defer.Deferred()
-
- def cbCompleted(ign):
- """
- Flush the exceptions which the reactor should have logged and make
- sure they're actually there.
- """
- errs = self.flushLoggedErrors(BadClientError)
- self.assertEqual(len(errs), 2, "Incorrectly found %d errors, expected 2" % (len(errs),))
- finalDeferred.addCallback(cbCompleted)
-
- client = BadClient()
- port = reactor.listenUDP(0, client, interface='127.0.0.1')
-
- def cbCleanup(result):
- """
- Disconnect the port we started and pass on whatever was given to us
- in case it was a Failure.
- """
- return defer.maybeDeferred(port.stopListening).addBoth(lambda ign: result)
- finalDeferred.addBoth(cbCleanup)
-
- addr = port.getHost()
-
- # UDP is not reliable. Try to send as many as 60 packets before giving
- # up. Conceivably, all sixty could be lost, but they probably won't be
- # unless all UDP traffic is being dropped, and then the rest of these
- # UDP tests will likely fail as well. Ideally, this test (and probably
- # others) wouldn't even use actual UDP traffic: instead, they would
- # stub out the socket with a fake one which could be made to behave in
- # whatever way the test desires. Unfortunately, this is hard because
- # of differences in various reactor implementations.
- attempts = range(60)
- succeededAttempts = []
-
- def makeAttempt():
- """
- Send one packet to the listening BadClient. Set up a 0.1 second
- timeout to do re-transmits in case the packet is dropped. When two
- packets have been received by the BadClient, stop sending and let
- the finalDeferred's callbacks do some assertions.
- """
- if not attempts:
- try:
- self.fail("Not enough packets received")
- except:
- finalDeferred.errback()
-
- self.failIfIdentical(client.transport, None, "UDP Protocol lost its transport")
-
- packet = str(attempts.pop(0))
- packetDeferred = defer.Deferred()
- client.setDeferred(packetDeferred)
- client.transport.write(packet, (addr.host, addr.port))
-
- def cbPacketReceived(packet):
- """
- A packet arrived. Cancel the timeout for it, record it, and
- maybe finish the test.
- """
- timeoutCall.cancel()
- succeededAttempts.append(packet)
- if len(succeededAttempts) == 2:
- # The second error has not yet been logged, since the
- # exception which causes it hasn't even been raised yet.
- # Give the datagramReceived call a chance to finish, then
- # let the test finish asserting things.
- reactor.callLater(0, finalDeferred.callback, None)
- else:
- makeAttempt()
-
- def ebPacketTimeout(err):
- """
- The packet wasn't received quickly enough. Try sending another
- one. It doesn't matter if the packet for which this was the
- timeout eventually arrives: makeAttempt throws away the
- Deferred on which this function is the errback, so when
- datagramReceived callbacks, so it won't be on this Deferred, so
- it won't raise an AlreadyCalledError.
- """
- makeAttempt()
-
- packetDeferred.addCallbacks(cbPacketReceived, ebPacketTimeout)
- packetDeferred.addErrback(finalDeferred.errback)
-
- timeoutCall = reactor.callLater(
- 0.1, packetDeferred.errback,
- error.TimeoutError(
- "Timed out in testDatagramReceivedError"))
-
- makeAttempt()
- return finalDeferred
-
-
- def test_portRepr(self):
- """
- The port number being listened on can be found in the string
- returned from calling repr() on L{twisted.internet.udp.Port}.
- """
- client = GoodClient()
- p = reactor.listenUDP(0, client)
- portNo = str(p.getHost().port)
- self.failIf(repr(p).find(portNo) == -1)
- def stoppedListening(ign):
- self.failIf(repr(p).find(portNo) != -1)
- d = defer.maybeDeferred(p.stopListening)
- d.addCallback(stoppedListening)
- return d
-
-
- def test_NoWarningOnBroadcast(self):
- """
- C{'<broadcast>'} is an alternative way to say C{'255.255.255.255'}
- ({socket.gethostbyname("<broadcast>")} returns C{'255.255.255.255'}),
- so because it becomes a valid IP address, no deprecation warning about
- passing hostnames to L{twisted.internet.udp.Port.write} needs to be
- emitted by C{write()} in this case.
- """
- class fakeSocket:
- def sendto(self, foo, bar):
- pass
-
- p = udp.Port(0, Server())
- p.socket = fakeSocket()
- p.write("test", ("<broadcast>", 1234))
-
- warnings = self.flushWarnings([self.test_NoWarningOnBroadcast])
- self.assertEqual(len(warnings), 0)
-
-
-
-class ReactorShutdownInteraction(unittest.TestCase):
- """Test reactor shutdown interaction"""
-
- def setUp(self):
- """Start a UDP port"""
- self.server = Server()
- self.port = reactor.listenUDP(0, self.server, interface='127.0.0.1')
-
- def tearDown(self):
- """Stop the UDP port"""
- return self.port.stopListening()
-
- def testShutdownFromDatagramReceived(self):
- """Test reactor shutdown while in a recvfrom() loop"""
-
- # udp.Port's doRead calls recvfrom() in a loop, as an optimization.
- # It is important this loop terminate under various conditions.
- # Previously, if datagramReceived synchronously invoked
- # reactor.stop(), under certain reactors, the Port's socket would
- # synchronously disappear, causing an AttributeError inside that
- # loop. This was mishandled, causing the loop to spin forever.
- # This test is primarily to ensure that the loop never spins
- # forever.
-
- finished = defer.Deferred()
- pr = self.server.packetReceived = defer.Deferred()
-
- def pktRece(ignored):
- # Simulate reactor.stop() behavior :(
- self.server.transport.connectionLost()
- # Then delay this Deferred chain until the protocol has been
- # disconnected, as the reactor should do in an error condition
- # such as we are inducing. This is very much a whitebox test.
- reactor.callLater(0, finished.callback, None)
- pr.addCallback(pktRece)
-
- def flushErrors(ignored):
- # We are breaking abstraction and calling private APIs, any
- # number of horrible errors might occur. As long as the reactor
- # doesn't hang, this test is satisfied. (There may be room for
- # another, stricter test.)
- self.flushLoggedErrors()
- finished.addCallback(flushErrors)
- self.server.transport.write('\0' * 64, ('127.0.0.1',
- self.server.transport.getHost().port))
- return finished
-
-
-
-class MulticastTestCase(unittest.TestCase):
-
- def setUp(self):
- self.server = Server()
- self.client = Client()
- # multicast won't work if we listen over loopback, apparently
- self.port1 = reactor.listenMulticast(0, self.server)
- self.port2 = reactor.listenMulticast(0, self.client)
- self.client.transport.connect(
- "127.0.0.1", self.server.transport.getHost().port)
-
-
- def tearDown(self):
- return gatherResults([
- maybeDeferred(self.port1.stopListening),
- maybeDeferred(self.port2.stopListening)])
-
-
- def testTTL(self):
- for o in self.client, self.server:
- self.assertEqual(o.transport.getTTL(), 1)
- o.transport.setTTL(2)
- self.assertEqual(o.transport.getTTL(), 2)
-
-
- def test_loopback(self):
- """
- Test that after loopback mode has been set, multicast packets are
- delivered to their sender.
- """
- self.assertEqual(self.server.transport.getLoopbackMode(), 1)
- addr = self.server.transport.getHost()
- joined = self.server.transport.joinGroup("225.0.0.250")
-
- def cbJoined(ignored):
- d = self.server.packetReceived = Deferred()
- self.server.transport.write("hello", ("225.0.0.250", addr.port))
- return d
- joined.addCallback(cbJoined)
-
- def cbPacket(ignored):
- self.assertEqual(len(self.server.packets), 1)
- self.server.transport.setLoopbackMode(0)
- self.assertEqual(self.server.transport.getLoopbackMode(), 0)
- self.server.transport.write("hello", ("225.0.0.250", addr.port))
-
- # This is fairly lame.
- d = Deferred()
- reactor.callLater(0, d.callback, None)
- return d
- joined.addCallback(cbPacket)
-
- def cbNoPacket(ignored):
- self.assertEqual(len(self.server.packets), 1)
- joined.addCallback(cbNoPacket)
-
- return joined
-
-
- def test_interface(self):
- """
- Test C{getOutgoingInterface} and C{setOutgoingInterface}.
- """
- self.assertEqual(
- self.client.transport.getOutgoingInterface(), "0.0.0.0")
- self.assertEqual(
- self.server.transport.getOutgoingInterface(), "0.0.0.0")
-
- d1 = self.client.transport.setOutgoingInterface("127.0.0.1")
- d2 = self.server.transport.setOutgoingInterface("127.0.0.1")
- result = gatherResults([d1, d2])
-
- def cbInterfaces(ignored):
- self.assertEqual(
- self.client.transport.getOutgoingInterface(), "127.0.0.1")
- self.assertEqual(
- self.server.transport.getOutgoingInterface(), "127.0.0.1")
- result.addCallback(cbInterfaces)
- return result
-
-
- def test_joinLeave(self):
- """
- Test that multicast a group can be joined and left.
- """
- d = self.client.transport.joinGroup("225.0.0.250")
-
- def clientJoined(ignored):
- return self.client.transport.leaveGroup("225.0.0.250")
- d.addCallback(clientJoined)
-
- def clientLeft(ignored):
- return self.server.transport.joinGroup("225.0.0.250")
- d.addCallback(clientLeft)
-
- def serverJoined(ignored):
- return self.server.transport.leaveGroup("225.0.0.250")
- d.addCallback(serverJoined)
-
- return d
-
-
- def test_joinFailure(self):
- """
- Test that an attempt to join an address which is not a multicast
- address fails with L{error.MulticastJoinError}.
- """
- # 127.0.0.1 is not a multicast address, so joining it should fail.
- return self.assertFailure(
- self.client.transport.joinGroup("127.0.0.1"),
- error.MulticastJoinError)
- if runtime.platform.isWindows() and not runtime.platform.isVista():
- test_joinFailure.todo = "Windows' multicast is wonky"
-
-
- def test_multicast(self):
- """
- Test that a multicast group can be joined and messages sent to and
- received from it.
- """
- c = Server()
- p = reactor.listenMulticast(0, c)
- addr = self.server.transport.getHost()
-
- joined = self.server.transport.joinGroup("225.0.0.250")
-
- def cbJoined(ignored):
- d = self.server.packetReceived = Deferred()
- c.transport.write("hello world", ("225.0.0.250", addr.port))
- return d
- joined.addCallback(cbJoined)
-
- def cbPacket(ignored):
- self.assertEqual(self.server.packets[0][0], "hello world")
- joined.addCallback(cbPacket)
-
- def cleanup(passthrough):
- result = maybeDeferred(p.stopListening)
- result.addCallback(lambda ign: passthrough)
- return result
- joined.addCallback(cleanup)
-
- return joined
-
-
- def test_multiListen(self):
- """
- Test that multiple sockets can listen on the same multicast port and
- that they both receive multicast messages directed to that address.
- """
- firstClient = Server()
- firstPort = reactor.listenMulticast(
- 0, firstClient, listenMultiple=True)
-
- portno = firstPort.getHost().port
-
- secondClient = Server()
- secondPort = reactor.listenMulticast(
- portno, secondClient, listenMultiple=True)
-
- theGroup = "225.0.0.250"
- joined = gatherResults([self.server.transport.joinGroup(theGroup),
- firstPort.joinGroup(theGroup),
- secondPort.joinGroup(theGroup)])
-
-
- def serverJoined(ignored):
- d1 = firstClient.packetReceived = Deferred()
- d2 = secondClient.packetReceived = Deferred()
- firstClient.transport.write("hello world", (theGroup, portno))
- return gatherResults([d1, d2])
- joined.addCallback(serverJoined)
-
- def gotPackets(ignored):
- self.assertEqual(firstClient.packets[0][0], "hello world")
- self.assertEqual(secondClient.packets[0][0], "hello world")
- joined.addCallback(gotPackets)
-
- def cleanup(passthrough):
- result = gatherResults([
- maybeDeferred(firstPort.stopListening),
- maybeDeferred(secondPort.stopListening)])
- result.addCallback(lambda ign: passthrough)
- return result
- joined.addBoth(cleanup)
- return joined
- if runtime.platform.isWindows():
- test_multiListen.skip = ("on non-linux platforms it appears multiple "
- "processes can listen, but not multiple sockets "
- "in same process?")
-
-
-if not interfaces.IReactorUDP(reactor, None):
- UDPTestCase.skip = "This reactor does not support UDP"
- ReactorShutdownInteraction.skip = "This reactor does not support UDP"
-if not interfaces.IReactorMulticast(reactor, None):
- MulticastTestCase.skip = "This reactor does not support multicast"
-
-def checkForLinux22():
- import os
- if os.path.exists("/proc/version"):
- s = open("/proc/version").read()
- if s.startswith("Linux version"):
- s = s.split()[2]
- if s.split(".")[:2] == ["2", "2"]:
- f = MulticastTestCase.testInterface.im_func
- f.todo = "figure out why this fails in linux 2.2"
-checkForLinux22()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_unix.py
deleted file mode 100755
index 863f6658..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_unix.py
+++ /dev/null
@@ -1,405 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for implementations of L{IReactorUNIX} and L{IReactorUNIXDatagram}.
-"""
-
-import stat, os, sys, types
-import socket
-
-from twisted.internet import interfaces, reactor, protocol, error, address, defer, utils
-from twisted.python import lockfile
-from twisted.trial import unittest
-
-from twisted.test.test_tcp import MyServerFactory, MyClientFactory
-
-
-class FailedConnectionClientFactory(protocol.ClientFactory):
- def __init__(self, onFail):
- self.onFail = onFail
-
- def clientConnectionFailed(self, connector, reason):
- self.onFail.errback(reason)
-
-
-
-class UnixSocketTestCase(unittest.TestCase):
- """
- Test unix sockets.
- """
- def test_peerBind(self):
- """
- The address passed to the server factory's C{buildProtocol} method and
- the address returned by the connected protocol's transport's C{getPeer}
- method match the address the client socket is bound to.
- """
- filename = self.mktemp()
- peername = self.mktemp()
- serverFactory = MyServerFactory()
- connMade = serverFactory.protocolConnectionMade = defer.Deferred()
- unixPort = reactor.listenUNIX(filename, serverFactory)
- self.addCleanup(unixPort.stopListening)
- unixSocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.addCleanup(unixSocket.close)
- unixSocket.bind(peername)
- unixSocket.connect(filename)
- def cbConnMade(proto):
- expected = address.UNIXAddress(peername)
- self.assertEqual(serverFactory.peerAddresses, [expected])
- self.assertEqual(proto.transport.getPeer(), expected)
- connMade.addCallback(cbConnMade)
- return connMade
-
-
- def test_dumber(self):
- """
- L{IReactorUNIX.connectUNIX} can be used to connect a client to a server
- started with L{IReactorUNIX.listenUNIX}.
- """
- filename = self.mktemp()
- serverFactory = MyServerFactory()
- serverConnMade = defer.Deferred()
- serverFactory.protocolConnectionMade = serverConnMade
- unixPort = reactor.listenUNIX(filename, serverFactory)
- self.addCleanup(unixPort.stopListening)
- clientFactory = MyClientFactory()
- clientConnMade = defer.Deferred()
- clientFactory.protocolConnectionMade = clientConnMade
- c = reactor.connectUNIX(filename, clientFactory)
- d = defer.gatherResults([serverConnMade, clientConnMade])
- def allConnected((serverProtocol, clientProtocol)):
-
- # Incidental assertion which may or may not be redundant with some
- # other test. This probably deserves its own test method.
- self.assertEqual(clientFactory.peerAddresses,
- [address.UNIXAddress(filename)])
-
- clientProtocol.transport.loseConnection()
- serverProtocol.transport.loseConnection()
- d.addCallback(allConnected)
- return d
-
-
- def test_pidFile(self):
- """
- A lockfile is created and locked when L{IReactorUNIX.listenUNIX} is
- called and released when the Deferred returned by the L{IListeningPort}
- provider's C{stopListening} method is called back.
- """
- filename = self.mktemp()
- serverFactory = MyServerFactory()
- serverConnMade = defer.Deferred()
- serverFactory.protocolConnectionMade = serverConnMade
- unixPort = reactor.listenUNIX(filename, serverFactory, wantPID=True)
- self.assertTrue(lockfile.isLocked(filename + ".lock"))
-
- # XXX This part would test something about the checkPID parameter, but
- # it doesn't actually. It should be rewritten to test the several
- # different possible behaviors. -exarkun
- clientFactory = MyClientFactory()
- clientConnMade = defer.Deferred()
- clientFactory.protocolConnectionMade = clientConnMade
- c = reactor.connectUNIX(filename, clientFactory, checkPID=1)
-
- d = defer.gatherResults([serverConnMade, clientConnMade])
- def _portStuff((serverProtocol, clientProto)):
-
- # Incidental assertion which may or may not be redundant with some
- # other test. This probably deserves its own test method.
- self.assertEqual(clientFactory.peerAddresses,
- [address.UNIXAddress(filename)])
-
- clientProto.transport.loseConnection()
- serverProtocol.transport.loseConnection()
- return unixPort.stopListening()
- d.addCallback(_portStuff)
-
- def _check(ignored):
- self.failIf(lockfile.isLocked(filename + ".lock"), 'locked')
- d.addCallback(_check)
- return d
-
-
- def test_socketLocking(self):
- """
- L{IReactorUNIX.listenUNIX} raises L{error.CannotListenError} if passed
- the name of a file on which a server is already listening.
- """
- filename = self.mktemp()
- serverFactory = MyServerFactory()
- unixPort = reactor.listenUNIX(filename, serverFactory, wantPID=True)
-
- self.assertRaises(
- error.CannotListenError,
- reactor.listenUNIX, filename, serverFactory, wantPID=True)
-
- def stoppedListening(ign):
- unixPort = reactor.listenUNIX(filename, serverFactory, wantPID=True)
- return unixPort.stopListening()
-
- return unixPort.stopListening().addCallback(stoppedListening)
-
-
- def _uncleanSocketTest(self, callback):
- self.filename = self.mktemp()
- source = ("from twisted.internet import protocol, reactor\n"
- "reactor.listenUNIX(%r, protocol.ServerFactory(), wantPID=True)\n") % (self.filename,)
- env = {'PYTHONPATH': os.pathsep.join(sys.path)}
-
- d = utils.getProcessValue(sys.executable, ("-u", "-c", source), env=env)
- d.addCallback(callback)
- return d
-
-
- def test_uncleanServerSocketLocking(self):
- """
- If passed C{True} for the C{wantPID} parameter, a server can be started
- listening with L{IReactorUNIX.listenUNIX} when passed the name of a
- file on which a previous server which has not exited cleanly has been
- listening using the C{wantPID} option.
- """
- def ranStupidChild(ign):
- # If this next call succeeds, our lock handling is correct.
- p = reactor.listenUNIX(self.filename, MyServerFactory(), wantPID=True)
- return p.stopListening()
- return self._uncleanSocketTest(ranStupidChild)
-
-
- def test_connectToUncleanServer(self):
- """
- If passed C{True} for the C{checkPID} parameter, a client connection
- attempt made with L{IReactorUNIX.connectUNIX} fails with
- L{error.BadFileError}.
- """
- def ranStupidChild(ign):
- d = defer.Deferred()
- f = FailedConnectionClientFactory(d)
- c = reactor.connectUNIX(self.filename, f, checkPID=True)
- return self.assertFailure(d, error.BadFileError)
- return self._uncleanSocketTest(ranStupidChild)
-
-
- def _reprTest(self, serverFactory, factoryName):
- """
- Test the C{__str__} and C{__repr__} implementations of a UNIX port when
- used with the given factory.
- """
- filename = self.mktemp()
- unixPort = reactor.listenUNIX(filename, serverFactory)
-
- connectedString = "<%s on %r>" % (factoryName, filename)
- self.assertEqual(repr(unixPort), connectedString)
- self.assertEqual(str(unixPort), connectedString)
-
- d = defer.maybeDeferred(unixPort.stopListening)
- def stoppedListening(ign):
- unconnectedString = "<%s (not listening)>" % (factoryName,)
- self.assertEqual(repr(unixPort), unconnectedString)
- self.assertEqual(str(unixPort), unconnectedString)
- d.addCallback(stoppedListening)
- return d
-
-
- def test_reprWithClassicFactory(self):
- """
- The two string representations of the L{IListeningPort} returned by
- L{IReactorUNIX.listenUNIX} contains the name of the classic factory
- class being used and the filename on which the port is listening or
- indicates that the port is not listening.
- """
- class ClassicFactory:
- def doStart(self):
- pass
-
- def doStop(self):
- pass
-
- # Sanity check
- self.assertIsInstance(ClassicFactory, types.ClassType)
-
- return self._reprTest(
- ClassicFactory(), "twisted.test.test_unix.ClassicFactory")
-
-
- def test_reprWithNewStyleFactory(self):
- """
- The two string representations of the L{IListeningPort} returned by
- L{IReactorUNIX.listenUNIX} contains the name of the new-style factory
- class being used and the filename on which the port is listening or
- indicates that the port is not listening.
- """
- class NewStyleFactory(object):
- def doStart(self):
- pass
-
- def doStop(self):
- pass
-
- # Sanity check
- self.assertIsInstance(NewStyleFactory, type)
-
- return self._reprTest(
- NewStyleFactory(), "twisted.test.test_unix.NewStyleFactory")
-
-
-
-class ClientProto(protocol.ConnectedDatagramProtocol):
- started = stopped = False
- gotback = None
-
- def __init__(self):
- self.deferredStarted = defer.Deferred()
- self.deferredGotBack = defer.Deferred()
-
- def stopProtocol(self):
- self.stopped = True
-
- def startProtocol(self):
- self.started = True
- self.deferredStarted.callback(None)
-
- def datagramReceived(self, data):
- self.gotback = data
- self.deferredGotBack.callback(None)
-
-class ServerProto(protocol.DatagramProtocol):
- started = stopped = False
- gotwhat = gotfrom = None
-
- def __init__(self):
- self.deferredStarted = defer.Deferred()
- self.deferredGotWhat = defer.Deferred()
-
- def stopProtocol(self):
- self.stopped = True
-
- def startProtocol(self):
- self.started = True
- self.deferredStarted.callback(None)
-
- def datagramReceived(self, data, addr):
- self.gotfrom = addr
- self.transport.write("hi back", addr)
- self.gotwhat = data
- self.deferredGotWhat.callback(None)
-
-
-
-class DatagramUnixSocketTestCase(unittest.TestCase):
- """
- Test datagram UNIX sockets.
- """
- def test_exchange(self):
- """
- Test that a datagram can be sent to and received by a server and vice
- versa.
- """
- clientaddr = self.mktemp()
- serveraddr = self.mktemp()
- sp = ServerProto()
- cp = ClientProto()
- s = reactor.listenUNIXDatagram(serveraddr, sp)
- self.addCleanup(s.stopListening)
- c = reactor.connectUNIXDatagram(serveraddr, cp, bindAddress=clientaddr)
- self.addCleanup(c.stopListening)
-
- d = defer.gatherResults([sp.deferredStarted, cp.deferredStarted])
- def write(ignored):
- cp.transport.write("hi")
- return defer.gatherResults([sp.deferredGotWhat,
- cp.deferredGotBack])
-
- def _cbTestExchange(ignored):
- self.assertEqual("hi", sp.gotwhat)
- self.assertEqual(clientaddr, sp.gotfrom)
- self.assertEqual("hi back", cp.gotback)
-
- d.addCallback(write)
- d.addCallback(_cbTestExchange)
- return d
-
-
- def test_cannotListen(self):
- """
- L{IReactorUNIXDatagram.listenUNIXDatagram} raises
- L{error.CannotListenError} if the unix socket specified is already in
- use.
- """
- addr = self.mktemp()
- p = ServerProto()
- s = reactor.listenUNIXDatagram(addr, p)
- self.failUnlessRaises(error.CannotListenError, reactor.listenUNIXDatagram, addr, p)
- s.stopListening()
- os.unlink(addr)
-
- # test connecting to bound and connected (somewhere else) address
-
- def _reprTest(self, serverProto, protocolName):
- """
- Test the C{__str__} and C{__repr__} implementations of a UNIX datagram
- port when used with the given protocol.
- """
- filename = self.mktemp()
- unixPort = reactor.listenUNIXDatagram(filename, serverProto)
-
- connectedString = "<%s on %r>" % (protocolName, filename)
- self.assertEqual(repr(unixPort), connectedString)
- self.assertEqual(str(unixPort), connectedString)
-
- stopDeferred = defer.maybeDeferred(unixPort.stopListening)
- def stoppedListening(ign):
- unconnectedString = "<%s (not listening)>" % (protocolName,)
- self.assertEqual(repr(unixPort), unconnectedString)
- self.assertEqual(str(unixPort), unconnectedString)
- stopDeferred.addCallback(stoppedListening)
- return stopDeferred
-
-
- def test_reprWithClassicProtocol(self):
- """
- The two string representations of the L{IListeningPort} returned by
- L{IReactorUNIXDatagram.listenUNIXDatagram} contains the name of the
- classic protocol class being used and the filename on which the port is
- listening or indicates that the port is not listening.
- """
- class ClassicProtocol:
- def makeConnection(self, transport):
- pass
-
- def doStop(self):
- pass
-
- # Sanity check
- self.assertIsInstance(ClassicProtocol, types.ClassType)
-
- return self._reprTest(
- ClassicProtocol(), "twisted.test.test_unix.ClassicProtocol")
-
-
- def test_reprWithNewStyleProtocol(self):
- """
- The two string representations of the L{IListeningPort} returned by
- L{IReactorUNIXDatagram.listenUNIXDatagram} contains the name of the
- new-style protocol class being used and the filename on which the port
- is listening or indicates that the port is not listening.
- """
- class NewStyleProtocol(object):
- def makeConnection(self, transport):
- pass
-
- def doStop(self):
- pass
-
- # Sanity check
- self.assertIsInstance(NewStyleProtocol, type)
-
- return self._reprTest(
- NewStyleProtocol(), "twisted.test.test_unix.NewStyleProtocol")
-
-
-
-if not interfaces.IReactorUNIX(reactor, None):
- UnixSocketTestCase.skip = "This reactor does not support UNIX domain sockets"
-if not interfaces.IReactorUNIXDatagram(reactor, None):
- DatagramUnixSocketTestCase.skip = "This reactor does not support UNIX datagram sockets"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_usage.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_usage.py
deleted file mode 100755
index 5a20f017..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/test_usage.py
+++ /dev/null
@@ -1,584 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.python.usage}, a command line option parsing library.
-"""
-
-from twisted.trial import unittest
-from twisted.python import usage
-
-
-class WellBehaved(usage.Options):
- optParameters = [['long', 'w', 'default', 'and a docstring'],
- ['another', 'n', 'no docstring'],
- ['longonly', None, 'noshort'],
- ['shortless', None, 'except',
- 'this one got docstring'],
- ]
- optFlags = [['aflag', 'f',
- """
-
- flagallicious docstringness for this here
-
- """],
- ['flout', 'o'],
- ]
-
- def opt_myflag(self):
- self.opts['myflag'] = "PONY!"
-
-
- def opt_myparam(self, value):
- self.opts['myparam'] = "%s WITH A PONY!" % (value,)
-
-
-
-class ParseCorrectnessTest(unittest.TestCase):
- """
- Test Options.parseArgs for correct values under good conditions.
- """
- def setUp(self):
- """
- Instantiate and parseOptions a well-behaved Options class.
- """
-
- self.niceArgV = ("--long Alpha -n Beta "
- "--shortless Gamma -f --myflag "
- "--myparam Tofu").split()
-
- self.nice = WellBehaved()
-
- self.nice.parseOptions(self.niceArgV)
-
- def test_checkParameters(self):
- """
- Checking that parameters have correct values.
- """
- self.assertEqual(self.nice.opts['long'], "Alpha")
- self.assertEqual(self.nice.opts['another'], "Beta")
- self.assertEqual(self.nice.opts['longonly'], "noshort")
- self.assertEqual(self.nice.opts['shortless'], "Gamma")
-
- def test_checkFlags(self):
- """
- Checking that flags have correct values.
- """
- self.assertEqual(self.nice.opts['aflag'], 1)
- self.assertEqual(self.nice.opts['flout'], 0)
-
- def test_checkCustoms(self):
- """
- Checking that custom flags and parameters have correct values.
- """
- self.assertEqual(self.nice.opts['myflag'], "PONY!")
- self.assertEqual(self.nice.opts['myparam'], "Tofu WITH A PONY!")
-
-
-
-class TypedOptions(usage.Options):
- optParameters = [
- ['fooint', None, 392, 'Foo int', int],
- ['foofloat', None, 4.23, 'Foo float', float],
- ['eggint', None, None, 'Egg int without default', int],
- ['eggfloat', None, None, 'Egg float without default', float],
- ]
-
- def opt_under_score(self, value):
- """
- This option has an underscore in its name to exercise the _ to -
- translation.
- """
- self.underscoreValue = value
- opt_u = opt_under_score
-
-
-
-class TypedTestCase(unittest.TestCase):
- """
- Test Options.parseArgs for options with forced types.
- """
- def setUp(self):
- self.usage = TypedOptions()
-
- def test_defaultValues(self):
- """
- Test parsing of default values.
- """
- argV = []
- self.usage.parseOptions(argV)
- self.assertEqual(self.usage.opts['fooint'], 392)
- self.assert_(isinstance(self.usage.opts['fooint'], int))
- self.assertEqual(self.usage.opts['foofloat'], 4.23)
- self.assert_(isinstance(self.usage.opts['foofloat'], float))
- self.assertEqual(self.usage.opts['eggint'], None)
- self.assertEqual(self.usage.opts['eggfloat'], None)
-
-
- def test_parsingValues(self):
- """
- Test basic parsing of int and float values.
- """
- argV = ("--fooint 912 --foofloat -823.1 "
- "--eggint 32 --eggfloat 21").split()
- self.usage.parseOptions(argV)
- self.assertEqual(self.usage.opts['fooint'], 912)
- self.assert_(isinstance(self.usage.opts['fooint'], int))
- self.assertEqual(self.usage.opts['foofloat'], -823.1)
- self.assert_(isinstance(self.usage.opts['foofloat'], float))
- self.assertEqual(self.usage.opts['eggint'], 32)
- self.assert_(isinstance(self.usage.opts['eggint'], int))
- self.assertEqual(self.usage.opts['eggfloat'], 21.)
- self.assert_(isinstance(self.usage.opts['eggfloat'], float))
-
-
- def test_underscoreOption(self):
- """
- A dash in an option name is translated to an underscore before being
- dispatched to a handler.
- """
- self.usage.parseOptions(['--under-score', 'foo'])
- self.assertEqual(self.usage.underscoreValue, 'foo')
-
-
- def test_underscoreOptionAlias(self):
- """
- An option name with a dash in it can have an alias.
- """
- self.usage.parseOptions(['-u', 'bar'])
- self.assertEqual(self.usage.underscoreValue, 'bar')
-
-
- def test_invalidValues(self):
- """
- Check that passing wrong values raises an error.
- """
- argV = "--fooint egg".split()
- self.assertRaises(usage.UsageError, self.usage.parseOptions, argV)
-
-
-
-class WrongTypedOptions(usage.Options):
- optParameters = [
- ['barwrong', None, None, 'Bar with wrong coerce', 'he']
- ]
-
-
-class WeirdCallableOptions(usage.Options):
- def _bar(value):
- raise RuntimeError("Ouch")
- def _foo(value):
- raise ValueError("Yay")
- optParameters = [
- ['barwrong', None, None, 'Bar with strange callable', _bar],
- ['foowrong', None, None, 'Foo with strange callable', _foo]
- ]
-
-
-class WrongTypedTestCase(unittest.TestCase):
- """
- Test Options.parseArgs for wrong coerce options.
- """
- def test_nonCallable(self):
- """
- Check that using a non callable type fails.
- """
- us = WrongTypedOptions()
- argV = "--barwrong egg".split()
- self.assertRaises(TypeError, us.parseOptions, argV)
-
- def test_notCalledInDefault(self):
- """
- Test that the coerce functions are not called if no values are
- provided.
- """
- us = WeirdCallableOptions()
- argV = []
- us.parseOptions(argV)
-
- def test_weirdCallable(self):
- """
- Test what happens when coerce functions raise errors.
- """
- us = WeirdCallableOptions()
- argV = "--foowrong blah".split()
- # ValueError is swallowed as UsageError
- e = self.assertRaises(usage.UsageError, us.parseOptions, argV)
- self.assertEqual(str(e), "Parameter type enforcement failed: Yay")
-
- us = WeirdCallableOptions()
- argV = "--barwrong blah".split()
- # RuntimeError is not swallowed
- self.assertRaises(RuntimeError, us.parseOptions, argV)
-
-
-class OutputTest(unittest.TestCase):
- def test_uppercasing(self):
- """
- Error output case adjustment does not mangle options
- """
- opt = WellBehaved()
- e = self.assertRaises(usage.UsageError,
- opt.parseOptions, ['-Z'])
- self.assertEqual(str(e), 'option -Z not recognized')
-
-
-class InquisitionOptions(usage.Options):
- optFlags = [
- ('expect', 'e'),
- ]
- optParameters = [
- ('torture-device', 't',
- 'comfy-chair',
- 'set preferred torture device'),
- ]
-
-
-class HolyQuestOptions(usage.Options):
- optFlags = [('horseback', 'h',
- 'use a horse'),
- ('for-grail', 'g'),
- ]
-
-
-class SubCommandOptions(usage.Options):
- optFlags = [('europian-swallow', None,
- 'set default swallow type to Europian'),
- ]
- subCommands = [
- ('inquisition', 'inquest', InquisitionOptions,
- 'Perform an inquisition'),
- ('holyquest', 'quest', HolyQuestOptions,
- 'Embark upon a holy quest'),
- ]
-
-
-class SubCommandTest(unittest.TestCase):
-
- def test_simpleSubcommand(self):
- o = SubCommandOptions()
- o.parseOptions(['--europian-swallow', 'inquisition'])
- self.assertEqual(o['europian-swallow'], True)
- self.assertEqual(o.subCommand, 'inquisition')
- self.failUnless(isinstance(o.subOptions, InquisitionOptions))
- self.assertEqual(o.subOptions['expect'], False)
- self.assertEqual(o.subOptions['torture-device'], 'comfy-chair')
-
- def test_subcommandWithFlagsAndOptions(self):
- o = SubCommandOptions()
- o.parseOptions(['inquisition', '--expect', '--torture-device=feather'])
- self.assertEqual(o['europian-swallow'], False)
- self.assertEqual(o.subCommand, 'inquisition')
- self.failUnless(isinstance(o.subOptions, InquisitionOptions))
- self.assertEqual(o.subOptions['expect'], True)
- self.assertEqual(o.subOptions['torture-device'], 'feather')
-
- def test_subcommandAliasWithFlagsAndOptions(self):
- o = SubCommandOptions()
- o.parseOptions(['inquest', '--expect', '--torture-device=feather'])
- self.assertEqual(o['europian-swallow'], False)
- self.assertEqual(o.subCommand, 'inquisition')
- self.failUnless(isinstance(o.subOptions, InquisitionOptions))
- self.assertEqual(o.subOptions['expect'], True)
- self.assertEqual(o.subOptions['torture-device'], 'feather')
-
- def test_anotherSubcommandWithFlagsAndOptions(self):
- o = SubCommandOptions()
- o.parseOptions(['holyquest', '--for-grail'])
- self.assertEqual(o['europian-swallow'], False)
- self.assertEqual(o.subCommand, 'holyquest')
- self.failUnless(isinstance(o.subOptions, HolyQuestOptions))
- self.assertEqual(o.subOptions['horseback'], False)
- self.assertEqual(o.subOptions['for-grail'], True)
-
- def test_noSubcommand(self):
- o = SubCommandOptions()
- o.parseOptions(['--europian-swallow'])
- self.assertEqual(o['europian-swallow'], True)
- self.assertEqual(o.subCommand, None)
- self.failIf(hasattr(o, 'subOptions'))
-
- def test_defaultSubcommand(self):
- o = SubCommandOptions()
- o.defaultSubCommand = 'inquest'
- o.parseOptions(['--europian-swallow'])
- self.assertEqual(o['europian-swallow'], True)
- self.assertEqual(o.subCommand, 'inquisition')
- self.failUnless(isinstance(o.subOptions, InquisitionOptions))
- self.assertEqual(o.subOptions['expect'], False)
- self.assertEqual(o.subOptions['torture-device'], 'comfy-chair')
-
- def test_subCommandParseOptionsHasParent(self):
- class SubOpt(usage.Options):
- def parseOptions(self, *a, **kw):
- self.sawParent = self.parent
- usage.Options.parseOptions(self, *a, **kw)
- class Opt(usage.Options):
- subCommands = [
- ('foo', 'f', SubOpt, 'bar'),
- ]
- o = Opt()
- o.parseOptions(['foo'])
- self.failUnless(hasattr(o.subOptions, 'sawParent'))
- self.assertEqual(o.subOptions.sawParent , o)
-
- def test_subCommandInTwoPlaces(self):
- """
- The .parent pointer is correct even when the same Options class is
- used twice.
- """
- class SubOpt(usage.Options):
- pass
- class OptFoo(usage.Options):
- subCommands = [
- ('foo', 'f', SubOpt, 'quux'),
- ]
- class OptBar(usage.Options):
- subCommands = [
- ('bar', 'b', SubOpt, 'quux'),
- ]
- oFoo = OptFoo()
- oFoo.parseOptions(['foo'])
- oBar=OptBar()
- oBar.parseOptions(['bar'])
- self.failUnless(hasattr(oFoo.subOptions, 'parent'))
- self.failUnless(hasattr(oBar.subOptions, 'parent'))
- self.failUnlessIdentical(oFoo.subOptions.parent, oFoo)
- self.failUnlessIdentical(oBar.subOptions.parent, oBar)
-
-
-class HelpStringTest(unittest.TestCase):
- def setUp(self):
- """
- Instantiate a well-behaved Options class.
- """
-
- self.niceArgV = ("--long Alpha -n Beta "
- "--shortless Gamma -f --myflag "
- "--myparam Tofu").split()
-
- self.nice = WellBehaved()
-
- def test_noGoBoom(self):
- """
- __str__ shouldn't go boom.
- """
- try:
- self.nice.__str__()
- except Exception, e:
- self.fail(e)
-
- def test_whitespaceStripFlagsAndParameters(self):
- """
- Extra whitespace in flag and parameters docs is stripped.
- """
- # We test this by making sure aflag and it's help string are on the
- # same line.
- lines = [s for s in str(self.nice).splitlines() if s.find("aflag")>=0]
- self.failUnless(len(lines) > 0)
- self.failUnless(lines[0].find("flagallicious") >= 0)
-
-
-class PortCoerceTestCase(unittest.TestCase):
- """
- Test the behavior of L{usage.portCoerce}.
- """
- def test_validCoerce(self):
- """
- Test the answers with valid input.
- """
- self.assertEqual(0, usage.portCoerce("0"))
- self.assertEqual(3210, usage.portCoerce("3210"))
- self.assertEqual(65535, usage.portCoerce("65535"))
-
- def test_errorCoerce(self):
- """
- Test error path.
- """
- self.assertRaises(ValueError, usage.portCoerce, "")
- self.assertRaises(ValueError, usage.portCoerce, "-21")
- self.assertRaises(ValueError, usage.portCoerce, "212189")
- self.assertRaises(ValueError, usage.portCoerce, "foo")
-
-
-
-class ZshCompleterTestCase(unittest.TestCase):
- """
- Test the behavior of the various L{twisted.usage.Completer} classes
- for producing output usable by zsh tab-completion system.
- """
- def test_completer(self):
- """
- Completer produces zsh shell-code that produces no completion matches.
- """
- c = usage.Completer()
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option:')
-
- c = usage.Completer(descr='some action', repeat=True)
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, '*:some action:')
-
-
- def test_files(self):
- """
- CompleteFiles produces zsh shell-code that completes file names
- according to a glob.
- """
- c = usage.CompleteFiles()
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option (*):_files -g "*"')
-
- c = usage.CompleteFiles('*.py')
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option (*.py):_files -g "*.py"')
-
- c = usage.CompleteFiles('*.py', descr="some action", repeat=True)
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, '*:some action (*.py):_files -g "*.py"')
-
-
- def test_dirs(self):
- """
- CompleteDirs produces zsh shell-code that completes directory names.
- """
- c = usage.CompleteDirs()
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option:_directories')
-
- c = usage.CompleteDirs(descr="some action", repeat=True)
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, '*:some action:_directories')
-
-
- def test_list(self):
- """
- CompleteList produces zsh shell-code that completes words from a fixed
- list of possibilities.
- """
- c = usage.CompleteList('ABC')
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option:(A B C)')
-
- c = usage.CompleteList(['1', '2', '3'])
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option:(1 2 3)')
-
- c = usage.CompleteList(['1', '2', '3'], descr='some action',
- repeat=True)
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, '*:some action:(1 2 3)')
-
-
- def test_multiList(self):
- """
- CompleteMultiList produces zsh shell-code that completes multiple
- comma-separated words from a fixed list of possibilities.
- """
- c = usage.CompleteMultiList('ABC')
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option:_values -s , \'some-option\' A B C')
-
- c = usage.CompleteMultiList(['1','2','3'])
- got = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(got, ':some-option:_values -s , \'some-option\' 1 2 3')
-
- c = usage.CompleteMultiList(['1','2','3'], descr='some action',
- repeat=True)
- got = c._shellCode('some-option', usage._ZSH)
- expected = '*:some action:_values -s , \'some action\' 1 2 3'
- self.assertEqual(got, expected)
-
-
- def test_usernames(self):
- """
- CompleteUsernames produces zsh shell-code that completes system
- usernames.
- """
- c = usage.CompleteUsernames()
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, ':some-option:_users')
-
- c = usage.CompleteUsernames(descr='some action', repeat=True)
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, '*:some action:_users')
-
-
- def test_groups(self):
- """
- CompleteGroups produces zsh shell-code that completes system group
- names.
- """
- c = usage.CompleteGroups()
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, ':group:_groups')
-
- c = usage.CompleteGroups(descr='some action', repeat=True)
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, '*:some action:_groups')
-
-
- def test_hostnames(self):
- """
- CompleteHostnames produces zsh shell-code that completes hostnames.
- """
- c = usage.CompleteHostnames()
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, ':some-option:_hosts')
-
- c = usage.CompleteHostnames(descr='some action', repeat=True)
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, '*:some action:_hosts')
-
-
- def test_userAtHost(self):
- """
- CompleteUserAtHost produces zsh shell-code that completes hostnames or
- a word of the form <username>@<hostname>.
- """
- c = usage.CompleteUserAtHost()
- out = c._shellCode('some-option', usage._ZSH)
- self.assertTrue(out.startswith(':host | user@host:'))
-
- c = usage.CompleteUserAtHost(descr='some action', repeat=True)
- out = c._shellCode('some-option', usage._ZSH)
- self.assertTrue(out.startswith('*:some action:'))
-
-
- def test_netInterfaces(self):
- """
- CompleteNetInterfaces produces zsh shell-code that completes system
- network interface names.
- """
- c = usage.CompleteNetInterfaces()
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, ':some-option:_net_interfaces')
-
- c = usage.CompleteNetInterfaces(descr='some action', repeat=True)
- out = c._shellCode('some-option', usage._ZSH)
- self.assertEqual(out, '*:some action:_net_interfaces')
-
-
-
-class CompleterNotImplementedTestCase(unittest.TestCase):
- """
- Using an unknown shell constant with the various Completer() classes
- should raise NotImplementedError
- """
- def test_unknownShell(self):
- """
- Using an unknown shellType should raise NotImplementedError
- """
- classes = [usage.Completer, usage.CompleteFiles,
- usage.CompleteDirs, usage.CompleteList,
- usage.CompleteMultiList, usage.CompleteUsernames,
- usage.CompleteGroups, usage.CompleteHostnames,
- usage.CompleteUserAtHost, usage.CompleteNetInterfaces]
-
- for cls in classes:
- try:
- action = cls()
- except:
- action = cls(None)
- self.assertRaises(NotImplementedError, action._shellCode,
- None, "bad_shell_type")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/testutils.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/testutils.py
deleted file mode 100755
index a310ea21..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/test/testutils.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from cStringIO import StringIO
-from twisted.internet.protocol import FileWrapper
-
-class IOPump:
- """Utility to pump data between clients and servers for protocol testing.
-
- Perhaps this is a utility worthy of being in protocol.py?
- """
- def __init__(self, client, server, clientIO, serverIO):
- self.client = client
- self.server = server
- self.clientIO = clientIO
- self.serverIO = serverIO
-
- def flush(self):
- "Pump until there is no more input or output."
- while self.pump():
- pass
-
- def pump(self):
- """Move data back and forth.
-
- Returns whether any data was moved.
- """
- self.clientIO.seek(0)
- self.serverIO.seek(0)
- cData = self.clientIO.read()
- sData = self.serverIO.read()
- self.clientIO.seek(0)
- self.serverIO.seek(0)
- self.clientIO.truncate()
- self.serverIO.truncate()
- for byte in cData:
- self.server.dataReceived(byte)
- for byte in sData:
- self.client.dataReceived(byte)
- if cData or sData:
- return 1
- else:
- return 0
-
-
-def returnConnected(server, client):
- """Take two Protocol instances and connect them.
- """
- cio = StringIO()
- sio = StringIO()
- client.makeConnection(FileWrapper(cio))
- server.makeConnection(FileWrapper(sio))
- pump = IOPump(client, server, cio, sio)
- # Challenge-response authentication:
- pump.flush()
- # Uh...
- pump.flush()
- return pump
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/CREDITS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/CREDITS
deleted file mode 100644
index a4eeecef..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/CREDITS
+++ /dev/null
@@ -1,60 +0,0 @@
-The Matrix
-
-- Glyph "Glyph" Lefkowitz <glyph@twistedmatrix.com>
- electric violin
-- Sean "Riley" Riley <sean@twistedmatrix.com>
- grand piano
-- Allen "Dash" Short <washort@twistedmatrix.com>
- vocals and guitar
-- Christopher "Radix" Armstrong <radix@twistedmatrix.com>
- percussion
-- Paul "z3p" Swartz <z3p@twistedmatrix.com>
- oboe
-- Jürgen "snibril" Hermann <jh@twistedmatrix.com>
- synthesizer
-- Moshe "vertical" Zadka <moshez@twistedmatrix.com>
- accordion
-- Benjamin Bruheim <grolgh@online.no>
- kazoo
-- Travis B. "Nafai" Hartwell <nafai@twistedmatrix.com>
- keyboards
-- Itamar "itamar" Shtull-Trauring <twisted@itamarst.org>
- alto recorder
-- Andrew "spiv" Bennetts <andrew@puzzling.org>
- glockenspiel
-- Kevin "Acapnotic" Turner <acapnotic@twistedmatrix.com>
- trombone
-- Donovan "fzZzy" Preston <dp@twistedmatrix.com>
- bass and harmonium
-- Jp "exarkun" Calderone <exarkun@twistedmatrix.com>
- geopolitical sociographic dissonance engine
-- Gavin "skreech" Cooper <coop@coopweb.org>
- torque wrench
-- Jonathan "jml" Lange <jml@twistedmatrix.com>
- pipe organ
-- Bob "etrepum" Ippolito <bob@redivi.com>
- low frequency oscillator
-- Pavel "PenguinOfDoom" Pergamenshchik <ppergame@gmail.com>
- electronic balalaika
-- Jonathan D. "slyphon" Simms <slyphon@twistedmatrix.com>
- theramin and drums
-- Brian "warner" Warner <warner@twistedmatrix.com>
- hertzian field renderer
-- Mary Gardiner <mary-twisted@puzzling.org>
- krummhorn
-- Eric "teratorn" Mangold <teratorn@twistedmatrix.com>
- serpentine bassoon
-- Tommi "Tv" Virtanen <tv@twistedmatrix.com>
- didgeridoo
-- Justin "justinj" Johnson <justinj@twistedmatrix.com>
- bass mandolin
-- Ralph "ralphm" Meijer <twisted@ralphm.ik.nu>
- vocals and timbales
-- David "dreid" Reid <dreid@dreid.org>
- banjo
-
-Extras
-
-- Jerry Hebert <jerry@cynics.org>
-- Nick Moffit <nick@zork.org>
-- Jeremy Fincher
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/ChangeLog.Old b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/ChangeLog.Old
deleted file mode 100644
index 30594b20..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/ChangeLog.Old
+++ /dev/null
@@ -1,3888 +0,0 @@
-2005-03-12 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/scripts/mktap.py, twisted/scripts/twistd.py,
- twisted/application/app.py: Changed UID and GID defaults for Process
- to None. Changed mktap behavior to not specify UID and GID if they
- are not given on the command line. Changed application startup to
- not change UID or GID if they are not given. Changed twistd to add
- UID and GID setting command line arguments.
-
-2005-02-10 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/defer.py: DeferredLock, DeferredSemaphore, and
- DeferredQueue added.
-
- * twisted/test/test_defer.py: Tests for above mentioned three new
- classes.
-
-2004-11-27 Brian Warner <warner@lothar.com>
-
- * util.py (SignalStateManager.save): don't save signal handlers
- for SIGKILL and SIGSTOP, since we can't set them anyway.
- Python2.4c1 raises an error when you try.
-
-2004-11-07 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_internet.py: correctly check for SSL support.
- Improve timeout for testCallLater and testGetDelayedCalls to avoid
- spurious failures on slow test systems. Close sockets in
- PortStringification to fix trial warnings.
-
- * twisted/internet/ssl.py: add a comment describing the correct
- way to import twisted.internet.ssl (since it might partially fail
- if OpenSSL is not available)
-
-2004-11-06 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/trial/assertions.py: assertRaises/failUnlessRaises now
- returns the caught exception to allow tests to inspect the contents.
-
-2004-11-02 Brian Warner <warner@lothar.com>
-
- * loopback.py (loopbackTCP): use trial's spinWhile and spinUntil
- primitives instead of doing reactor.iterate() ourselves. Make sure
- to wait for everything before finishing.
-
-2004-10-26 Cory Dodt <corydodt@twistedmatrix.com>
-
- * twisted/python/{which,process}.py,
- twisted/test/{test_wprocess,wprocess_for_testing}.py,
- twisted/internet/{default,error,wprocess,process}.py: back out
- wprocess due to test failures in wprocess and new trial. Resolves
- issue 760.
-
-2004-10-24 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * TCP: Half-close of write and read for TCP connections, including
- protocol notification for protocols that implement
- IHalfCloseableProtocol.
-
-2004-10-07 Jp Calderone <exarkun@twistedmatrix.com>
-
- * Transports: Add a maximum to the number of bytes that will be
- held in the write buffer even after they have been sent. This
- puts a maximum on the cost of writing faster than the network
- can accommodate.
-
-2004-10-06 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * Transports: New TCP/SSL/etc. buffering algorithm. All writes are
- now stored until next iteration before being written, and many
- small writes are not expensive.
-
-2004-09-30 Brian Warner <warner@lothar.com>
-
- * glib2reactor.py: new reactor that uses just glib2, not gtk2.
- This one doesn't require a DISPLAY, and cannot be used for GUI
- apps.
-
- * gtk2reactor.py: import gobject *after* pygtk.require, to make
- sure we get the same versions of both
-
-2004-09-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/internet/defer.py: Add deferredGenerator and
- waitForDeferred. This lets you write kinda-sorta
- synchronous-looking code that uses Deferreds. See the
- waitForDeferred docstring.
-
-2004-09-11 Cory Dodt <corydodt@twistedmatrix.com>
-
- * twisted/python/{which,process}.py,
- twisted/test/{test_wprocess,wprocess_for_testing}.py,
- twisted/internet/{default,error,wprocess,process}.py: merge the
- "wprocess" branch which uses Trent Mick's process.py to enable
- spawnProcess in the default reactor on Windows
-
-2004-08-24 Brian Warner <warner@lothar.com>
-
- * twisted/application/internet.py (TimerService): make it possible
- to restart a stopped TimerService. Threw out a lot of (apparently)
- unnecessary code in the process. Make sure it gets pickled in a
- not-running state too.
- * twisted/test/test_application.py (TestInternet2.testTimer): test
- the changes, and update the way the test peeks inside TimerService
-
-2004-07-18 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/internet/utils.py: By passing errortoo=1, you can get
- stderr from getProcessOutput
-
-2004-07-18 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/unix.py: if the utmp module is available, record
- user logins/logouts into utmp/wtmp.
-
-2004-06-25 Paul Swartz <z3p@twistedmatrix.com>
- * twisted/conch/checkers.py: Use functionality of crypt module instead
- of an external module.
-
-2004-06-25 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/spread/banana.py: Disabled automatic import and use of
- cBanana. PB will now use the pure-Python version of banana unless
- cBanana is manually installed by the application.
-
-2004-06-12 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/client: added -r flag to reconnect to the server if
- the connection is lost (closes 623).
-
-2004-06-06 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: test open callback and
- connect/disconnect.
-
- * twisted/enterprise/adbapi.py: add open callback support
- and disconnect() method. Issue 480.
-
-2004-06-05 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/adbapi.py: Don't log sql exceptions (issue 631).
- Remove deprecated api.
-
- * twisted/news/database.py: do not use adbapi.Augmentation
-
-2004-06-03 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/gtk2reactor.py: The choice between glib event
- loop and gtk+ event loop is determined by argument at reactor
- install time.
-
-2004-05-31 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/sqlreflector.py: don't use Augmentation
-
- * twisted/enterprise/populate.sql: remove
-
- * twisted/enterprise/schema.sql: remove
-
- * twisted/enterprise/row.py: remove deprecated classes
-
- * twisted/enterprise/dbgadgets.py: remove
-
- * twisted/enterprise/dbcred.py: remove
-
- * twisted/test/test_enterprise.py: Fix Firebird test case.
-
-2004-05-21 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/gtk2reactor.py: use glib event loop directly
- instead of gtk2's event loop if possible.
-
-2004-05-04 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted.news, twisted.protocols.nntp: Moved back into trunk
- pending an alternate split-up strategy.
-
-2004-05-04 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted.internet.reactor.listenUDP: transport.write() on UDP
- ports no longer supports unresolved hostnames (though deprecated
- support still exists).
-
-2004-4-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/lore/nevowlore.py, twisted/plugins.tml: Added Nevow
- support for lore. See docstring of twisted.lore.nevowlore.
-
-2004-4-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted.news, twisted.protocols.nntp: Moved into a third party
- package. Deprecated backwards-compatibility exists by importing
- from the third-party package if available.
-
-2004-4-11 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted.conch: refactored the Conch client to separate connecting
- to a server from user authentication from client-specific actions.
-
-2004-03-23 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted.protocols.http: Small optimisation to HTTP implementation.
- This changes return value of toChunk to a tuple of strings, rather
- than one string.
-
-2004-4-3 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted.python.lockfile: added lockfile support, based on
- liblockfile.
- * twisted.internet.unix.Port: added a wantPID kwarg. If True, it
- checks for and gets a lockfile for the UNIX socket.
- * twisted.internet.unix.Connector: added a checkPID kwarg. If True,
- it checks that the lockfile for the socket is current.
-
-2004-03-23 Pavel Pergamenshchik <pp64@cornell.edu>
-
- * twisted.internet.iocp: Support for Windows IO Completion Ports.
- Use with "--reactor=iocp" parameter to twistd or trial.
-
-2004-03-20 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted.internet: getHost(), getPeer(), buildProtocol() etc.
- all use address objects from twisted.internet.address.
-
- * twisted/internet/udp.py: Connected UDP support is now part of
- the standard listenUDP-resulting UDP transport using a connect()
- method.
-
-2004-03-18 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/application/internet.py: Changed TimerService to
- log errors from the function it calls.
-
- * twisted/application/test_application.py: Added test case
- for logging of exceptions from functions TimerService calls.
-
-2004-03-07 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.2.1alpha1.
-
-2004-03-03 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/web/server.py: Fix UnsupportedMethod so that users'
- allowedMethods are actually honored.
-
- * twisted/web/resource.py: (Resource.render) If the resource has
- an 'allowedMethods' attribute, pass it to UnsupportedMethod.
-
-2004-02-27 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/internet/defer.py: Add consumeErrors flag to DeferredList.
- This takes care of the most common use-case for the recently
- deprecated addDeferred method.
-
-2004-02-28 Dave Peticolas <dave@krondo.com>
-
- * setup.py: install tap2rpm as a bin script
-
- * twisted/test/test_enterprise.py: Test Firebird db. Fix typos.
-
-2004-02-27 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/internet/defer.py: Deprecated DeferredList.addDeferred. It
- isn't as useful as it looks, and can have surprising behaviour.
-
-2004-02-25 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/protocols/dns.py: Fixed a bug in TCP support: It
- wouldn't process any messages after the first, causing AXFR
- queries to be totally broken (in addition to other problems in the
- implementation of AXFR).
-
- * twisted/names/client.py: Fixed the AXFR client (lookupZone),
- thanks to DJB's wonderful documentation of the horribleness of
- DNS.
-
-2004-02-25 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.2.0 final! Same as rc3.
-
-2004-02-24 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.2.0rc3 (same as rc2, with cBanana bug
- fixed).
-
-2004-02-19 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/application/service.py (IService.disownServiceParent)
- (IServiceCollection.removeService): These may return Deferred if they
- have asynchronous side effects.
-
-2004-02-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.2.0rc2. Brown-paper bag release bug.
-
-2004-02-17 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.2.0rc1.
-
-2004-02-13 Brian Warner <warner@lothar.com>
-
- * doc/howto/faq.xhtml: add entry on transport.getPeer()
-
-2004-01-31 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.2alpha2 (problem with Debian packaging).
-
-2004-01-30 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.2alpha1.
-
-2004-01-23 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/scripts/trial.py: trial now supports a --coverage
- option, requiring Python 2.3.3. Give it a directory name (relative
- to _trial_temp) to put code-coverage info in. It uses the stdlib
- 'trace' module.
-
-2004-01-21 Pavel Pergamenshchik <pp64@cornell.edu>
-
- * twisted/protocols/stateful.py: A new way to write protocols!
- Current state is encoded as a pair (func, len). As soon as len
- of data arrives, func is called with that amount of data. New
- state is returned from func.
- * twisted/test/test_stateful.py: Tests and an example, an
- Int32StringReceiver implementation.
-
-2004-01-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/web/resource.py: The default render method of Resource
- now supports delegating to methods of the form "render_*" where
- "*" is the HTTP method that was used to make the
- request. Examples: request_GET, request_HEAD, request_CONNECT, and
- so on. This won't break any existing code - when people want to
- use the better API, they can stop overriding 'render' and instead
- override individual render_* methods.
-
-2004-01-13 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/soap.py: Beginning of client SOAP support.
-
-2004-01-10 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/protocols/ftp.py: Added support for partial downloads
- and uploads to FTPClient (see the offset parameter of retrieveFile).
-
-2004-01-09 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: Add IMessageCopier interface to allow
- for optimized implementations of message copying.
-
-2004-01-06 Brian Warner <warner@lothar.com>
-
- * twisted/internet/default.py (PosixReactorBase.spawnProcess): add
- a 'childFDs' argument which allows the child's file descriptors to
- be arbitrarily mapped to parent FDs or pipes. This allows you to
- set up additional pipes into the child (say for a GPG passphrase
- or separate status information).
-
- * twisted/internet/process.py (Process): add childFDs, split out
- ProcessReader and ProcessWriter (so that Process itself is no
- longer also reading stdout).
-
- * twisted/internet/protocol.py (ProcessProtocol): add new
- childDataReceived and childConnectionLost methods, which default
- to invoking the old methods for backwards compatibility
-
- * twisted/test/test_process.py (FDTest): add test for childFDs
- mapping. Also add timeouts to most tests, and make all
- reactor.iterate() loops wait 10ms between iterations to avoid
- spamming the CPU quite so badly. Closes issue435.
- * twisted/test/process_fds.py: new child process for FDTest
-
- * doc/howto/process.xhtml: document childFDs argument, add example
-
-2004-01-04 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/gladereactor.py: logs all network traffic for
- TCP/SSL/Unix sockets, allowing traffic to be displayed.
-
-2004-01-04 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: test deleting rows not in cache
-
- * twisted/enterprise/reflector.py: deleted rows don't have to be
- in cache
-
- * doc/examples/row_example.py: use KeyFactory from row_util
-
- * doc/examples/row_util.py: add KeyFactory
-
-2003-12-31 Brian Warner <warner@lothar.com>
-
- * twisted/internet/defer.py (Deferred.setTimeout): if the Deferred
- has already been called, don't bother with the timeout. This
- happens when trial.util.deferredResult is used with a timeout
- argument and the Deferred was created by defer.succeed().
- * twisted/test/test_defer.py
- (DeferredTestCase.testImmediateSuccess2): test for same
-
-2003-12-31 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/ident.py: Client and server ident implementation
- * twisted/test/test_ident.py: Test cases for ident protocol
-
-2003-12-29 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/spread/pb.py: Changed PBServerFactory to use "protocol"
- instance attribute for Broker creation.
-
-2003-12-26 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/server.py: display of tracebacks on web pages can
- now be disabled by setting displayTracebacks to False on the Site
- or by using applicable tap option. Woven does not yet use
- this attribute.
-
-2003-12-23 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/client.py: if Host header is passed, use that
- instead of extracting from request URL.
-
-2003-12-14 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: Frederico Di Gregorio's patch
- adding a psycopg test case.
-
-2003-12-09 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.1, based on rc4.
-
-2003-12-06 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/wxreactor.py: Added experimental wxPython reactor,
- which seems to work better than the twisted.internet.wxsupport.
-
-2003-12-05 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/ssh/filetransfer.py, session.py: added SFTPv3 support
- to the Conch server.
-
-2003-12-04 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.1rc4, based on rc2. rc3 never happened!
-
-2003-12-04 Brian Warner <warner@lothar.com>
-
- * twisted/persisted/sob.py (Persistent): fix misspelled class name,
- add compatibility binding to "Persistant" (sic).
-
- * twisted/test/test_sob.py: use Persistent
- * twisted/application/service.py (Application): use Persistent
-
-2003-12-03 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: Added support for the
- IDLE command (RFC 2177).
-
-2003-12-03 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/python/log.py: Added exception handling to
- log publishing code. Observers which raise exceptions
- will now be removed from the observer list.
-
-2003-12-02 Jp Calderone <exarkun@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.1rc3.
-
-2003-12-01 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.1rc2 (from CVS HEAD).
-
-2003-12-01 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/python/runtime.py: Added seconds method to Platform
- class.
-
- * twisted/internet/base.py, twisted/internet/task.py: Changed
- use of time.time() to use Platform.seconds() instead.
-
-2003-11-24 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/abstract.py: Changed FileDescriptor's
- registerProducer method to immediately call the given producer's
- stopProducing method if the FileDescriptor is in the process of
- or has finished disconnecting.
-
-2003-11-24 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: Fix incorrect behavior of closing the
- mailbox in response to an EXPUNGE command.
-
-2003-11-21 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/trial/runner.py: Added missing calls to setUpClass and
- tearDownClass in SingletonRunner.
-
-2003-11-21 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.1rc1.
-
-2003-11-20 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: Fixed incorrect generation of
- INTERNALDATE information.
-
-2003-11-20 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/abstract.py: Added an assert to
- FileDescriptor.resumeProducing to prevent it from being
- called when the transport is no longer connected.
-
-2003-11-20 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/tasks.py: LoopingCall added.
-
-2003-10-14 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/tasks.py: Deprecated scheduling API removed.
-
-2003-11-18 Jonathan Simms <jonathan@embassynetworks.com>
-
- * twisted/protocols/ftp.py: refactored to add cred support,
- pipelining, security.
- * twisted/test/test_ftp.py: tests for the new ftp
-
-2003-11-18 Sam Jordan <sam@twistedmatrix.com>
-
- * twisted/protocols/msn.py: support for MSNP8
- * doc/examples/msn_example.py: small msn example
-
-2003-11-13 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/ssh/agent.py: support for the OpenSSH agent protocol
- * twisted/conch/ssh/connection.py: fix broken channel retrieval code
- * twisted/conch/ssh/userauth.py: refactoring to allow use of the agent
- * twisted/conch/ssj/transport.py: fix intermittent test failure
- * twisted/internet/protocol.py: add UNIX socket support to
- ClientCreator
- * twisted/scripts/conch.py: use the key agent if available, also
- agent forwarding
-
-2003-11-07 Brian Warner <warner@lothar.com>
-
- * twisted/application/app.py (getApplication): provide a more
- constructive error message when a .tac file doesn't define
- 'application'. Closes issue387.
-
-2003-11-01 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/ssh/common.py: use GMPy for faster math if it's
- available
-
-2003-10-24 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.0 final. Same codebase as rc2.
-
-2003-10-24 Brian Warner <warner@lothar.com>
-
- * doc/howto/test-standard.xhtml: Add section on how to clean up.
-
- * twisted/test/test_conch.py: improve post-test cleanup. Addresses
- problems seen in issue343.
-
- * twisted/internet/base.py (ReactorBase.callLater): prefix
- "internal" parameter names with an underscore, to avoid colliding
- with named parameters in the user's callback invocation. Closes
- issue347.
- (ReactorBase.addSystemEventTrigger)
- (ReactorBase.callWhenRunning)
- (ReactorBase.callInThread): same
- * doc/howto/coding-standard.xhtml (Callback Arguments): explain why
-
-2003-10-22 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.0rc2.
-
-2003-10-21 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/lore/tree.py, twisted/lore/lint.py,
- doc/howto/stylesheet.css: add a plain 'listing' class, for file
- listings that aren't python source or HTML. This has slightly changed
- the classes in the generated HTML, so custom stylesheets may need
- updating.
-
-2003-10-16 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.0alpha3.
-
-2003-10-16 Brian Warner <warner@lothar.com>
-
- * doc/howto/pb-cred.xhtml: update for newcred. Closes issue172.
-
-2003-10-15 Brian Warner <warner@lothar.com>
-
- * twisted/internet/base.py: add optional debug code, enabled with
- base.DelayedCall.debug=True . If active, the call stack which
- invoked reactor.callLater will be recorded in each DelayedCall. If
- an exception happens when the timer function is run, the creator
- stack will be logged in addition to the usual log.deferr().
-
- * twisted/internet/defer.py: add some optional debug code, enabled
- with defer.Deferred.debug=True . If active, it will record a stack
- trace when the Deferred is created, and another when it is first
- invoked. AlreadyCalledErrors will be given these two stack traces,
- making it slightly easier to find the source of the problem.
-
-2003-10-15 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.0alpha2 (alpha1 was dead in the water).
-
-2003-10-15 Brian Warner <warner@lothar.com>
-
- * setup.py: remove cReactor/ to the sandbox. Closes issue318.
-
-2003-10-14 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/static.py: registry no longer has support for
- getting services based on their interfaces.
-
-2003-10-14 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.1.0alpha1.
-
-2003-10-13 Bob Ippolito <bob@redivi.com>
-
- * doc/howto/choosing-reactor.xhtml:
- Added cfreactor/Cocoa information.
-
- * doc/examples/cocoaDemo:
- Removed, replaced by doc/examples/Cocoa cfreactor demos.
-
- * doc/examples/Cocoa:
- Moved from sandbox/etrepum/examples/PyObjC, cleaned up.
-
- * twisted/internet/cfsupport, twisted/internet/cfreactor.py:
- Moved from sandbox/etrepum, cleaned up.
-
- * twisted/application/app.py:
- Added 'cf' -> twisted.internet.cfreactor to reactorTypes
-
- * setup.py:
- sys.platform=='darwin' - build cfsupport, do not build cReactor.
-
- * INSTALL:
- Changed URL of pimp repository to shorter version.
-
-2003-10-12 Jp Calderone <exarkun@twistedmatrix.com>
-
- * bin/tktwistd, twisted/scripts/tktwistd.py, doc/man/tktwistd.1:
- Removed.
-
-2003-10-12 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/spread/pb.py: Perspective Broker no longer sends
- detailed tracebacks over the wire unless the "unsafeTracebacks"
- attribute is set of the factory.
-
-2003-10-02 Jp Calderone <exarkun@twistedmatrix.com>
-
- * setup.py, twisted/test/test_dir.py, twisted/python/_c_dir.c:
- Removed _c_dir extension module for portability and maintenance
- reasons.
-
-2003-10-03 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/spread/util.py twisted/test/test_spread.py: Fix issue
- 286
-
-2003-10-01 Brian Warner <warner@lothar.com>
-
- * twisted/web/client.py (HTTPDownloader): accept either a filename
- or a file-like object (it must respond to .write and .close, and
- partial requests will not be used with file-like objects). errback
- the deferred if an IOError occurs in .open, .write. or .close,
- usually something like "permission denied" or "file system full".
- Closes issue234.
- * twisted/test/test_webclient.py (WebClientTestCase.write): verify
- that the errback gets called
-
- * twisted/scripts/trial.py (run): add --until-failure option to
- re-run the test until something fails. Closes issue87.
-
-2003-09-30 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_conch.py (testOurServerOpenSSHClient): replace
- reactor.run() with .iterate calls: when using .run, exceptions in
- the server cause a hang.
-
-2003-9-29 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/tap/procmon.py twisted/plugins.tml: remove procmon
- tap. It was crufty and hard to port properly to new application.
-
-2003-09-29 Brian Warner <warner@lothar.com>
-
- * twisted/scripts/trial.py (Options.opt_reactor): make trial
- accept the same reactor-name abbreviations as twistd does. Closes
- issue69.
- (top): add test-case-name tag
-
- * doc/man/trial.1: document the change
-
-2003-09-28 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.8alpha3.
-
-2003-09-27 Cory Dodt <corydodt@yahoo.com>
-
- * win32/main.aap win32/pyx.x-foo.iss.template win32/README.win32:
- Be nice to people who don't install Python for "All Users" on win32.
-
-2003-9-18 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/application/strports.py twisted/test/test_strports.py:
- New API/mini-language for defining ports
-
-2003-9-18 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/spider.py: removed, it was unmaintained.
-
-2003-09-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/names/authority.py twisted/test/test_names.py
- twisted/protocols/dns.py: Client and server support for TTLs on
- all records. All Record_* types now take a ttl= keyword
- argument. You can pass the ttl= argument to all the record classes
- in your pyzones, too.
-
-2003-09-19 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/application/__init__.py twisted/application/app.py
- twisted/application/compat.py twisted/application/internet.py
- twisted/application/service.py twisted/scripts/twistd.py
- twisted/scripts/twistw.py twisted/scripts/mktap.py
- twisted/scripts/tapconvert.py bin/twistw: Update to new-style
- applications.
-
-2003-09-19 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/names/client.py: Instantiation of theResolver global made
- lazy. As a result importing it directly will now fail if it has not
- yet been created. It should not be used directly anymore; instead,
- use the module-scope lookup methods, or instantiate your own
- resolver.
-
- * twisted/mail/relaymanager.py: Instantiation of MXCalculator made
- lazy.
-
-2003-09-18 Stephen Thorne <stephen@thorne.id.au>
-
- * twisted/web/distrib.py: Removed dependancy on twisted.web.widgets, and
- instead using woven.
-
-2003-09-18 Stephen Thorne <stephen@thorne.id.au>
-
- * doc/howto/woven-reference.html: Added this new documentation file.
- * doc/howto/index.html: Added woven-reference to index
- * admin/: Added woven-reference.tex to book.tex
-
-2003-09-18 Stephen Thorne <stephen@thorne.id.au>
-
- * twisted/web/woven/widgets.py: Stop the 'Option' widget from having a
- name="" attribute. Closes issue255.
-
-2003-09-16 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.8alpha1.
-
- * .: Releasing Twisted 1.0.8alpha2 (Fixed Debian packages).
-
-2003-09-13 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7 (no code changes since 1.0.7rc1).
-
- * twisted/web/vhost.py: Un-gobble the path segment that a vhost eats
- when the resource we're wrapping isLeaf. Potentially closes issue125.
-
-2003-09-12 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/microdom.py: lenient mode correctly handles <script>
- tags with CDATA or comments protecting the code (closes issue #231).
-
-2003-09-10 Tommi Virtanen <tv@twistedmatrix.com>
-
- * HTTPS support for XML-RPC and web clients (closes issue #236).
-
-2003-08-29 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7rc1.
-
-2003-09-12 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/spread/pb.py: new cred support for Perspective Broker.
-
-2003-08-26 Dave Peticolas <dave@krondo.com>
-
- * doc/howto/xmlrpc.html: document sub-handler and introspection
-
- * twisted/test/test_xmlrpc.py: test introspection support
-
- * twisted/web/xmlrpc.py: implement sub-handlers and introspection
- support
-
-2003-08-23 Brian Warner <warner@lothar.com>
-
- * twisted/internet/gtk2reactor.py: force timeout values to be
- integers, because recent pygtk's complain when they get floats
-
-2003-08-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7alpha5.
-
-2003-08-18 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: Remove support code for old versions
- of IMailbox.fetch(); also change the interface once again (no
- backwards compat this time) to require sequence numbers to be
- returned, not just whatever the MessageSet spit out.
-
-2003-08-16 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_import.py: update for enterprise
-
- * twisted/enterprise/sqlreflector.py: use dbpool directly
-
- * twisted/enterprise/row.py: deprecate KeyFactory and StatementBatch
-
- * twisted/enterprise/dbpassport.py: remove
-
- * twisted/enterprise/dbgadgets.py: deprecate all
-
- * twisted/enterprise/dbcred.py: deprecate all
-
- * twisted/enterprise/adbapi.py: deprecate Augmentation. deprecate
- crufty bits of ConnectionPool API.
-
-2003-08-11 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/sqlreflector.py: fix docs
-
-2003-08-08 Donovan Preston <dp@twistedmatrix.com>
-
- * Added getAllPatterns API to Widget, which returns all nodes
- which have the given pattern name.
-
- * Refactored List widget to use getAllPatterns, so you can have
- more than one listHeader, listFooter, and emptyList node.
-
-2003-08-08 Dave Peticolas <dave@krondo.com>
-
- * twisted/internet/base.py: remove unused internal function.
-
- * twisted/internet/gladereactor.py: remove unused internal function.
- clean up imports.
-
-2003-08-07 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7alpha4.
-
-2003-08-06 Donovan Preston <dp@twistedmatrix.com>
-
- * Major woven optimizations.
-
- * Removal of inspect-based hacks allowing backwards compatibility
- with the old IModel interface. All your IModel methods should take
- the request as the first argument now.
-
- * Default to non-case-preserving when importing Woven templates,
- and case-insensitive microdom. If you are using getPattern or
- getAttribute in any of your woven code, you will have to make sure
- to pass all lowercase strings.
-
- * Removal of __eq__ magic methods in microdom. This was just
- slowing woven down far too much, since without it python can
- use identity when looking for a node in replaceChild. This means
- you will have to explicitly use the isEqualToDocument or
- isEqualToNode call if you are testing for the equality of microdom
- nodes.
-
- * Removal of usage of hasAttribute, getAttribute, removeAttribute
- from woven for a speed gain at the expense of tying woven slightly
- closer to microdom. Nobody will notice.
-
- * Improved getPattern semantics thanks to a patch by Rich
- Cavenaugh. getPattern will now not look for a pattern below any
- nodes which have model= or view= directives on them.
-
-2003-08-04 Dave Peticolas <dave@krondo.com>
-
- * twisted/python/usage.py: use parameter docs if handler
- method has none. fixes bug displaying trial help.
-
-2003-07-31 Brian Warner <warner@lothar.com>
-
- * twisted/python/filepath.py (FilePath.__getstate__): allow
- FilePath objects to survive unpersisting.
-
-2003-07-30 Brian Warner <warner@lothar.com>
-
- * doc/howto/faq.html: mention spawnProcess vs. os.environ
-
- * doc/howto/test-standard.html: document usage of .todo and .skip
-
-2003-07-28 Brian Warner <warner@lothar.com>
-
- * twisted/python/_c_dir.c: hush compiler warning
-
- * setup.py: add twisted.xish
-
-2003-07-28 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/spread/pb.py (PBClientFactory): a new, superior API for
- starting PB connections. Create a factory, do a
- reactor.connectTCP/SSL() etc., then factory.getPerspective().
-
-2003-07-27 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: enable tests that depend on
- cp_min and cp_max
-
- * twisted/enterprise/adbapi.py: use threadpool to handle cp_min and
- cp_max arguments
-
- * twisted/test/test_threadpool.py: test existing work
-
- * twisted/python/threadpool.py: check for existing work in start()
-
-2003-07-25 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: The fetch method of the IMailbox
- interface has been changed to accept only a MessageSet and a uid
- argument and to return an IMessage implementor.
-
-2003-07-24 Brian Warner <warner@lothar.com>
-
- * twisted/internet/cReactor/cDelayedCall.c: implement .active and
- .getTime methods
-
- * twisted/test/test_internet.py (InterfaceTestCase.wake): remove
- reactor.initThreads() call. This is a private method which is
- triggered internally by the current reactor when threadable.init
- is called. It does not need to be called independently, and not
- all reactors implement this particular method.
-
- * twisted/test/test_threads.py: shuffle test cases, add timeouts
- to avoid hanging tests. Added (disabled) test to trigger cReactor
- hang (but unfortunately it fails under the default reactor)
-
-2003-07-23 Dave Peticolas <dave@krondo.com>
-
- * twisted/internet/threads.py: avoid top-level reactor import
-
-2003-07-23 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/imap4.py: The fetch method of the IMailbox
- interface has been changed to accept a list of (non-string)
- objects representing the requested message parts. Less knowledge
- of the IMAP4 protocol should be required to properly implement
- the interface.
-
-2003-07-23 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: more tests
-
-2003-07-21 Dave Peticolas <dave@krondo.com>
-
- * twisted/internet/base.py: implement callWhenRunning
-
- * twisted/internet/interfaces.py: add callWhenRunning API
-
- * twisted/test/test_pop3.py: string in string only works in 2.3
-
-2003-07-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7alpha3 (for form and twisted.names
- updates mentioned below).
-
-2003-07-19 Ying Li <cyli@ai.mit.edu>
-
- * twisted/web/woven/form.py: Changed form widgets so that if the
- template already has the widget coded, merges the template widget
- with the model widget (sets default values, etc.).
-
- * twisted/web/woven/form.py, twisted/python/formmethod.py: Can
- format layout of checkgroups and radiogroups into tables, rows, or
- columns.
-
- * twisted/web/woven/form.py, twisted/python/formmethod.py: Added
- file input widget (unable to retrieve filename or file type - have
- to ask for that separately).
-
-2003-07-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/protocols/dns.py, twisted/names: Twisted Names can now
- return the `authoritative' bit. All of the resolvers in
- twisted/names/authority.py now set it.
-
-2003-07-17 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7alpha2 (Debian packages should be
- correct now)
-
-2003-07-17 Dave Peticolas <dave@krondo.com>
-
- * doc/howto/components.html: methods in interfaces do have self
- parameters
-
-2003-07-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/web/client.py: Added a `timeout' keyword argument to
- getPage; If the web page takes longer than `timeout' to fetch,
- defer.TimeoutError is errbacked.
-
- * twisted/web/server.py, twisted/protocols/http.py: add `timeout'
- argument to HTTPFactory and Site to specify how long to allow
- connections to sit without communication before disconnecting
- them.
-
-2003-07-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.7alpha1.
-
-2003-07-17 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/smtp.py: Address class changed to provide a
- default domain for addresses missing a domain part.
-
-2003-07-16 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/protocols/sux.py: In beExtremelyLenient mode, all data
- in script elements is considered plain text and will not be parsed
- for tags or entity references.
-
-2003-07-15 Dave Peticolas <dave@krondo.com>
-
- * twisted/persisted/styles.py: better debugging output
- for Ephemeral
-
-2003-07-14 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/cred/checkers.py, twisted/cred/credentials.py:
- CramMD5Credentials and OnDiskUsernamePasswordDatabase added;
- IUsernameHashedPassword also created for use by protocols that
- do not receive plaintext passwords over the network.
-
- * twisted/mail/, twisted/protocols/smtp.py: Addition of alias
- support and authenticated ESMTP connections. Several interfaces
- changed, but deprecation warnings and backwards compatibility code
- has been put in place to ease the change.
-
-2003-07-12 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/web/util.py: Add a new ChildRedirector that, when placed
- at /foo to redirect to /bar, will also redirect /foo/abc to
- /bar/abc.
-
- * twisted/web/scripts.py: Fixed ResourceScriptWrapper so that you
- can now .putChild on the resource you create in an .rpy file that
- is wrapped with this class.
-
-2003-07-06 Paul Swartz <z3p@twistedmatrix.com>
- * twisted/conch/[checkers,credentials,pamauth].py,
- twisted/conch/ssh/userauth.py, twisted/tap/conch.py: made PAM
- work again as an authentication.
-
-2003-07-05 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: more tests. Add mysql test.
-
-2003-07-05 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/soap.py: Now requires SOAPpy v0.10.1, allow subclasses
- to determine method publishing strategy.
-
-2004-07-05 Jp Calderone <exarkun@twistedmatrix.com>
-
- * bin/mailmail, doc/man/mailmail.1, twisted/scripts/mailmail.py:
- sendmail replacement
-
-2003-07-04 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: add sqlite. more tests.
- Add Postgres test.
-
- * twisted/enterprise/util.py: fix bug in getKeyColumn
-
- * twisted/enterprise/sqlreflector.py: clean up imports
-
- * twisted/enterprise/row.py: clean up imports
-
- * twisted/enterprise/reflector.py: clean up imports
-
-2004-07-04 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/python/dir.c: Wrapper around opendir(3), readdir(3),
- and scandir(3) for use by twisted.python.plugins.
-
-2003-07-03 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/news/database.py: NewsShelf.articleRequest() and
- NewsShelf.bodyRequest() now expected to return a file-like object
- in the last position of its returned three-tuple. The old API
- is still supported, but deprecated.
-
-2003-07-03 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_enterprise.py: add gadfly test
-
- * twisted/web/woven/input.py: remove excess newline.
-
- * twisted/trial/unittest.py: take out unused methodPrefix var
-
- * twisted/enterprise/adbapi.py: accept 'noisy' kw arg. persist
- noisy, min, and max args. just warn about non-dbapi db libs.
-
- * twisted/enterprise/reflector.py: fix spelling
-
- * twisted/enterprise/sqlreflector.py 80 columns, don't addToCache
- in insertRow
-
- * twisted/enterprise/xmlreflector.py: 80 columns
-
-2003-07-01 Brian Warner <warner@lothar.com>
-
- * sandbox/warner/fusd_twisted.py: experimental glue code for FUSD,
- a system for implementing Linux device drivers in userspace
-
-2003-06-27 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.6rc3. Fixed a security bug in
- twisted.web.
-
- * .: Releasing Twisted 1.0.6rc4. One more twisted.web bug.
-
- * .: Releasing Twisted 1.0.6.
-
-2003-06-26 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.6rc1.
-
- * .: Releasing Twisted 1.0.6rc2. Pop3 had failing tests.
-
-2003-06-26 Clark C. Evans <cce@twistedmatrix.com>
-
- * twisted/flow/*.py: Moved Flow from the sandbox to
- twisted.flow. The callback is dead. Long live the callback!
-
-2003-06-26 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/pop3.py: POP3.authenticateUserXYZ no longer
- returns a Mailbox object. It now returns a 3-tuple. See
- twisted.cred.portal.Portal.login for more details about the return
- value.
-
-2003-06-24 Brian Warner <warner@lothar.com>
-
- * doc/howto/upgrading.html: Explain Versioned and rebuild()
-
-2003-06-23 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/scripts/trial.py twisted/trial/reporter.py
- doc/man/trial.1:
-
- Added a --tbformat={plain,emacs} option to trial. Now the default
- is to show the regular python traceback; if you want tracebacks
- that look like compiler output for emacs, use --tbformat=emacs.
-
-2003-06-23 Cory Dodt <corydodt@yahoo.com>
-
- * twisted/python/util.py twisted/web/microdom.py
- twisted/test/test_{util,xml}.py: preserveCase and caseInsensitive
- work on attribute names as well as element names.
-
-2003-06-22 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/defer.py: Changed maybeDeferred API from
- maybeDeferred(deferred, f, *args, **kw) to maybeDeferred(f, *args,
- **kw).
-
-2003-06-19 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/{checkers,credentials,realm}.py,
- twisted/conch/ssh/userauth.py: Moved the Conch user authentication
- code to use the new version of Cred.
-
-2003-06-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.6alpha3. There was a problem in
- twisted.python.compat that was breaking the documentation
- building. It is now fixed.
-
-2003-06-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.6alpha2.
-
-2003-06-16 Donovan Preston <dp@twistedmatrix.com>
-
- * twisted/web/woven/{controller,view,widgets}.py: Cleaned up the
- output of Woven so it never leaves any woven-specific attributes
- on the output HTML. Also, id attributes are not set on every
- node with a View unless you are using LivePage.
-
-2003-06-11 Brian Warner <warner@lothar.com>
-
- * doc/howto/cvs-dev.html: add "Working from CVS" hints
-
-2003-06-10 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/protocol.py: connection refused errors for
- connected datagram protocols (connectUDP) are indicated using
- callback, ConnectedDatagramProtocol.connectionRefused, rather
- than an exception as before.
-
-2003-06-09 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/trial/{unittest,runner}.py: Added setUpClass and
- tearDownClass methods and invocations to twisted.trial. Implement
- those methods in your TestCases if you want to manage resources on
- a per-class level.
-
-2003-06-09 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/mail/relay.py: Default relaying rule change from all
- local and all non-INET connections to all local and all UNIX
- connections.
-
-2003-06-08 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/interfaces.py: Added ITLSTransport interface,
- subclassing ITCPTransport and adding one method - startTLS()
-
- * twisted/internet/tcp.py: Connector class made to implement
- ITLSTransport if TLS is available.
-
-2003-06-05 Brian Warner <warner@lothar.com>
-
- * twisted/conch/ssh/transport.py (ssh_KEX_DH_GEX_INIT): don't use
- small values for DH parameter 'y'. openssh rejects these because they
- make it trivial to reconstruct the shared secret. This caused a test
- failure about 1024 times out of every 65536.
-
- * twisted/test/test_dirdbm.py (DirDbmTestCase.testModificationTime):
- dodge a kernel bug that lets mtime get skewed from time(), causing
- an occasional test failure
-
-2003-06-03 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/__init__.py twisted/internet/app.py
- * twisted/internet/unix.py twisted/internet/tcp.py
- * twisted/manhole/ui/gtk2manhole.py twisted/protocols/dns.py
- * twisted/protocols/smtp.py twisted/protocols/sux.py
- * twisted/protocols/imap4.py twisted/protocols/sip.py
- * twisted/protocols/htb.py twisted/protocols/pcp.py
- * twisted/python/formmethod.py twisted/python/reflect.py
- * twisted/python/util.py twisted/python/components.py
- * twisted/spread/jelly.py twisted/spread/newjelly.py
- * twisted/test/test_components.py twisted/test/test_rebuild.py
- * twisted/test/test_trial.py twisted/test/test_world.py
- * twisted/test/test_setup.py twisted/test/test_newjelly.py
- * twisted/test/test_compat.py twisted/test/test_pcp.py
- * twisted/test/test_log.py twisted/web/microdom.py
- * twisted/web/woven/page.py twisted/popsicle/mailsicle.py
- * twisted/trial/remote.py twisted/trial/unittest.py
- * twisted/world/allocator.py twisted/world/compound.py
- * twisted/world/database.py twisted/world/storable.py
- * twisted/world/structfile.py twisted/world/typemap.py:
-
- Remove direct usage of twisted.python.compat; Modify __builtin__
- module to include forward-compatibility hacks.
-
-2003-05-30 Brian Warner <warner@lothar.com>
-
- * twisted/conch/ssh/keys.py (signData_dsa): Force DSS signature
- blobs to be 20 bytes long. About 1% of the time, the sig numbers
- would come out small and fit into 19 bytes, which would result in
- an invalid signature.
- * twisted/test/test_conch.py: remove special hacked test case used
- to find that invalid-signature problem.
-
-2003-05-29 Brian Warner <warner@lothar.com>
-
- * twisted/python/formmethod.py: this module needs False from compat
-
- * twisted/internet/process.py (ProcessWriter.writeSomeData):
- Accomodate Mac OS-X, which sometimes raises OSError(EAGAIN)
- instead of IOError(EAGAIN) when the pipe is full.
-
-2003-05-27 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_process.py (EchoProtocol): try to close
- occasional test failure. Do transport.closeStdin() instead of
- loseConnection() because the child still has data to write (to
- stderr). Closing all three streams takes away its voice, forces it
- to exit with an error, and is probably causing problems.
-
- * twisted/test/test_factories.py (testStopTrying): stop test after
- 5 seconds rather than 2000 iterations. Some reactors iterate at
- different rates.
-
-2003-05-24 Brian Warner <warner@lothar.com>
-
- * twisted/scripts/trial.py (Options.opt_testmodule): ignore
- deleted files, recognize twisted/test/* files as test cases
-
-2003-05-22 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_newjelly.py (JellyTestCase.testUnicode): make
- sure unicode strings don't mutate into plain ones
-
-2003-05-21 Brian Warner <warner@lothar.com>
-
- * twisted/internet/tcp.py (Connection.getTcpKeepAlive): Add
- functions to control SO_KEEPALIVE bit on TCP sockets.
- * twisted/internet/interfaces.py (ITCPTransport): ditto
- * twisted/test/test_tcp.py (LoopbackTestCase.testTcpKeepAlive):
- test it
-
- * doc/howto/test-standard.html: document test-case-name format
-
- * doc/howto/coding-standard.html: encourage test-case-name tags
-
- * twisted/protocols/htb.py, twisted/protocols/irc.py,
- twisted/protocols/pcp.py, twisted/python/text.py,
- twisted/spread/pb.py, twisted/trial/remote.py: clean up
- test-case-name tags
-
- * twisted/scripts/trial.py (Options.opt_testmodule): try to handle
- test-case-name tags the same way emacs does
-
-2003-05-21 Christopher Armstrong <radix@twistedmatrix.com>
-
- * bin/coil, doc/man/coil.1, doc/man/index.html: removed. Coil
- isn't being maintained, pending a total rewrite.
-
-2003-05-20 Brian Warner <warner@lothar.com>
-
- * twisted/python/reflect.py (namedAny): re-raise ImportErrors that
- happen inside the module being imported, instead of assuming that
- it means the module doesn't exist.
-
-2003-05-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/web/server.py: Added two new methods to Request objects:
- rememberRootURL and getRootURL. Calling rememberRootURL will store
- the already-processed part of the URL on the request, and calling
- getRootURL will return it. This is so you can more easily link to
- disparate parts of your web application.
-
- * twisted/web/woven/{page,widgets}.py: Updated Woven to take
- advantage of previously-mentioned Request changes. You can now say
- `appRoot = True' in the Page subclass that is instantiated by your
- .rpy (for example), and then use a RootRelativeLink widget
- (exactly the same way you use a Link widget) to get a link
- relative to your root .rpy.
-
-2003-05-16 Brian Warner <warner@lothar.com>
-
- * twisted/scripts/trial.py: catch failures during import of test
- modules named on the command line too.
-
- * twisted/trial/unittest.py (TestSuite.addModule): catch all failures
- during import so that syntax errors in test files don't prevent
- other tests from being run.
-
- * twisted/trial/reporter.py (TextReporter): handle both Failures
- and exception tuples in import errors. Emit the messages before the
- last summary line so that test-result parsers can still find the
- pass/fail counts.
-
- * doc/howto/faq.html: Add note about Ephemeral in the
- import-from-self twistd entry.
-
-2003-05-13 Brian Warner <warner@lothar.com>
-
- * twisted/trial/runner.py: sort tests by name within a TestCase
-
-2003-05-13 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/internet/{default,internet}.py: Add an `active' method to
- DelayedCall, which returns True if it hasn't been called or
- cancelled.
-
-2003-05-13 Jonathan Lange <jml@twistedmatrix.com>
-
- * twisted/trial/unittest.py twisted/scripts/trial.py
- doc/man/trial.1: Add --recurse option to make trial search within
- sub-packages for test modules.
-
-2003-5-12 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/lore/default.py twisted/lore/latex.py
- twisted/lore/lint.py twisted/lore/math.py twisted/lore/tree.py
- twisted/lore/lmath.py twisted/lore/slides.py:
- Added indexing support to LaTeX and lint, and made sure the
- config dictionary is passed to the tree processors [this is an
- API change which might have effect on Lore extensions!]. Rename
- math to lmath, to avoid some corner-case bugs where it gets mixed
- with the Python standard module "math".
-
-2003-05-11 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.6alpha1. There was a problem
- with file descriptors in 1.0.5; some debugging information
- has been added to this release. The problem should be fixed
- by alpha2.
-
-2003-05-08 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.5 (same code-base as rc2).
-
-2003-05-08 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/world: Added an object database to Twisted. This is
- still highly experimental!
-
-2003-5-6 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/trial/reporter.py twisted/scripts/trial.py: Add --timing
- option to make the reporter output wall-clock time.
-
-2003-05-05 Brian Warner <warner@lothar.com>
-
- * setup.py (setup_args): s/licence/license/, preferred in python-2.3
-
-2003-05-05 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 1.0.5rc1.
-
- * .: Releasing Twisted 1.0.5rc2 (only a Debian build problem fixed).
-
-2003-05-05 Brian Warner <warner@lothar.com>
-
- * twisted/trial/reporter.py: remove ResultTypes, it doesn't really
- accomplish its goal
-
- * twisted/trial/unittest.py: move log.startKeepingErrors() from
- top-level to TestSuite.run(). This fixes the problem of errors
- being eaten by code which imports unittest for other reasons (like
- to use trial.remote reporting)
-
-2003-05-04 Brian Warner <warner@lothar.com>
-
- * twisted/trial/reporter.py (ResultTypes): export legal values for
- Reporter.reportResults() so remote reporters know what to expect
-
-2003-05-03 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/tcp.py, twisted/internet/ssl.py: TLS support
- added to TCP connections; startTLS() method added to transport
- objects to switch from unencrypted to encrypted mode.
-
-2003-05-02 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/protocol.py: Added continueTrying attribute to
- ReconnectingClientFactory, and increased the number of states where
- stopTrying() will actually stop further connection attempts.
-
-2003-05-01 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_trial.py: handle new trial layout
- * twisted/trial/runner.py (runTest): utility function to help
- test_trial
- * twisted/trial/util.py (extract_tb): handle new trial layout,
- ignore the right framework functions.
-
-2003-05-01 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/python/context.py: call-stack context tree.
-
- * twisted/python/components.py: support interface-to-interface
- adapatation, IFoo(o) syntax for adaptation, context-based
- registries and more.
-
- * twisted/python/log.py: Totally rewritten logging system.
-
-2003-05-01 Brian Warner <warner@lothar.com>
-
- * twisted/internet/gtk2reactor.py (Gtk2Reactor._doReadOrWrite):
- add Anthony's cached-Failure speedup to gtk2 too.
-
-2003-05-01 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/tcp.py, twisted/internet/default.py: cache
- Failures whose contents are always identical. Speeds up lost
- connections considerably.
-
- * twisted/python/failure.py: If you pass only an exception object
- to Failure(), a stack will not be constructed. Speeds up Failure
- creation in certain common cases where traceback printing isn't
- required.
-
-2003-04-29 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_process.py: make all child processes inherit
- their parent's environment
-
- * twisted/web/resource.py, twisted/python/roots.py: add
- test-case-name tag
-
- * twisted/web/resource.py (IResource)
- twisted/spread/refpath.py (PathReferenceAcquisitionContext.getIndex)
- twisted/python/roots.py (Collection.getEntity): appease pychecker
-
-2003-04-27 Jp Calderone <exarkun@twistedmatrix.com>
-
- * doc/examples/bananabench.py, twisted/internet/utils.py,
- twisted/mail/bounce.py, twisted/persisted/styles.py,
- twisted/python/log.py, twisted/python/reflect.py,
- twisted/spread/pb.py, twisted/test/test_banana.py,
- twisted/test/test_iutils.py, twisted/test/test_persisted.py,
- twisted/test/test_process.py, twisted/web/domhelpers.py,
- twisted/web/script.py, twisted/web/server.py, twisted/web/test.py:
- Change the usage of cStringIO to fallback to StringIO if the former
- is not available.
-
- * twisted/im/gtkaccount.py, twisted/internet/app.py,
- twisted/mail/relay.py, twisted/mail/relaymanager.py,
- twisted/persisted/journal/base.py, twisted/persisted/dirdbm.py,
- twisted/scripts/conch.py, twisted/scripts/tapconvert.py,
- twisted/scripts/twistd.py, twisted/scripts/websetroot.py,
- twisted/test/test_mvc.py, twisted/test/test_persisted.py,
- twisted/web/woven/template.py, twisted/web/woven/view.py,
- twisted/popsicle/picklesicle.py: Change the usage of cPickle to
- fallback to pickle if the former is not available.
-
- * doc/howto/coding-standard.html: Document the way to use extension
- versions of modules for which there is a pure-python equivalent.
-
-2003-04-26 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/adbapi.py: commit successful _runQuery calls
- instead of rolling back
-
-2003-04-23 Brian Warner <warner@lothar.com>
-
- * doc/howto/telnet.html: Update example from twisted-0.15.5(!) to
- 1.0.4
-
- * twisted/protocols/loopback.py: use reactor.iterate(0.01) so the
- tests hammer the CPU slightly less
-
- * twisted/test/test_trial.py (LoopbackTests.testError): .type is a
- string
- * twisted/trial/remote.py (JellyReporter.reportResults): stringify
- .type and .value from Failures before jellying them.
-
- * twisted/internet/base.py (ReactorBase.suggestThreadPoolSize):
- don't let suggestThreadPoolSize(0) be the only reason threads are
- initialized.
-
- * twisted/python/log.py (err): always log Failures to the logfile. If
- we're doing _keepErrors, then also add them to _keptErrors.
-
- * twisted/trial/unittest.py (TestSuite.runOneTest): only do
- reportResults once per test. Handle reactor.threadpool being None.
-
-2003-04-22 Bob Ippolito <bob@redivi.com>
-
- * twisted/python/compat.py: Complete iter implementation with
- __getitem__ hack for 2.1. dict now supports the full 2.3 featureset.
-
- * twisted/test/test_compat.py: Tests for compat module, so we know if
- it works or not now ;)
-
-2003-04-22 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/lore/latex.py: Handle cross-references and labels slightly
- better, so that e.g. man/lore.html and howto/lore.html don't generate
- conflicting labels. Also, emit \loreref{...} instead of \pageref{...}
- -- this isn't a standard LaTeX command, see admin/book.tex for an
- example definition. In HTML generation, all relative hrefs in <a>
- tags are now munged from .html to .xhtml, unless class="absolute".
-
-2003-04-21 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/interfaces.py: Added getServiceNamed, addService,
- and removeService to IServiceCollection.
-
-2003-04-21 Brian Warner <warner@lothar.com>
-
- * twisted/web/woven/*.py: add test-case-name tags
-
-2003-04-21 Bob Ippolito <bob@redivi.com>
-
- * twisted/web/static.py (File, DirectoryListing): DirectoryListing
- now gets the directory listing from File.listNames, and no longer
- calls os.listdir directly (unless a directory listing is not
- specified in the DirectoryListing constructor).
-
-2003-04-19 Brian Warner <warner@lothar.com>
-
- * twisted/trial/remote.py (JellyReporter.cleanResults): handle
- strings as testClass/method to unbreak tests
-
- * twisted/trial/remote.py (JellyReporter.reportResults): send only
- name of testClass/method to remote reporter, not whole class and
- method. Also add .taster hook to DecodeReport to let users specify
- their own security options.
-
-2003-04-17 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * .: Release 1.0.4 Final.
-
-2003-04-16 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * .: Release 1.0.4rc1.
-
-2003-04-15 Jp Calderone <exarkun@twistedmatrix.com>
-
- * admin/accepttests, admin/accepttests.py: Acceptance tests
- turned into a Python module with no unguarded top-level code,
- to make running acceptance tests selectively possible.
-
-2003-04-14 Brian Warner <warner@lothar.com>
-
- * twisted/python/threadable.py (init):
- * twisted/spread/newjelly.py (SecurityOptions.allowBasicTypes):
- * twisted/spread/jelly.py (SecurityOptions.allowBasicTypes):
- Remove old apply() calls.
-
- * twisted/spread/flavors.py (Copyable.jellyFor): Use proper
- jellier .prepare/.preserve dance when .invoker is non-None. This
- fixes jellying of circular references when passed through PB
- connections.
-
- * twisted/test/test_newjelly.py: add test case that sets .invoker
- to verify that code path too
-
-2003-04-14 Jonathan Lange <jml@ids.org.au>
-
- * twisted/web/woven/controller.py (Controller): now, if getChild
- cannot find the requested child, it will ask getDynamicChild -- a
- method like getChild, but designed to be overriden by users.
-
-2003-04-13 Bob Ippolito <bob@redivi.com>
-
- * twisted/internet/app.py (DependentMultiService): a MultiService
- to start services in insert order and stop them in reverse. Uses
- chained deferreds to ensure that if a startService or stopService
- returns a deferred, then the next service in the queue will wait
- until its dependency has finished.
-
-2003-04-12 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_process.py (PosixProcessTestCasePTY): skip
- testStdio, testStderr, and testProcess. PTYs do not have separate
- stdout/stderr, so the tests just aren't relevant. testProcess
- might be, but it requires support for closing the write side
- separately from the read side, and I don't think our processPTY
- can do that quite yet.
-
- * twisted/test/test_tcp.py (LocalRemoteAddressTestCase): iterate
- harder. some systems might not connect to localhost before
- iterate() is called, flunking the test
-
- * twisted/test/test_process.py: only install SIGCHLD handler if the
- reactor offers a hook for it.
-
- * twisted/test/test_policies.py (ThrottlingTestCase.doIterations):
- add more iterations to accomodate reactors that do less IO per pass
-
- * twisted/test/process_signal.py: reset SIGHUP to default handler,
- fixes test failures in a 'nohup' environment
-
- * twisted/test/test_process.py (PosixProcessTestCasePTY): remove
- testClosePty.todo now that it works
- (SignalProtocol.processEnded): Improve testSignal error messages
-
- * twisted/internet/process.py (PTYProcess.connectionLost): Treat
- PTYs more like sockets: loseConnection sets .disconnecting and
- lets the write pipe drain, then the PTY is closed in
- connectionLost.
-
-2003-04-12 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/plugins.tml, twisted/tap/ssh.py, twisted/tap/conch.py: moved
- the conch server from 'mktap ssh' to 'mktap conch'.
-
-2003-04-12 Brian Warner <warner@lothar.com>
-
- * twisted/internet/gtk2reactor.py (Gtk2Reactor.doIteration): don't
- process *all* events before exiting: lots of IO (like test cases which
- do connect()s from inside connectionMade) will keep us from surfacing
- from reactor.iterate(), causing a lockup.
- * twisted/internet/gtkreactor.py (GtkReactor.doIteration): same. Use
- the same code as gtk2reactor with minor gtk1-vs-gtk2 variations.
-
-2003-04-11 Brian Warner <warner@lothar.com>
-
- * twisted/internet/gtk2reactor.py (Gtk2Reactor.doIteration): use
- timers to match the behavior of select()-based reactors.
- reactor.iterate(delay) is thus defined to return after 'delay'
- seconds, or earlier if something woke it up (like IO, or timers
- expiring).
-
-2003-04-11 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/defer.py: Added new, experimental function,
- "maybeDeferred". API is subject to change.
-
-2003-04-11 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/scripts/mktap.py: Sped up --debug and --progress by
- introducing a two-pass option parser.
-
-2003-04-11 Brian Warner <warner@lothar.com>
-
- * twisted/internet/gtk2reactor.py: major fixes. Use different
- POLLIN/OUT flags to robustly work around pygtk bug, change
- callback() to behave more like pollreactor (since gtk uses poll
- internally). doIteration now calls gtk.main_iteration in a
- non-blocking way. Attempt to emulate doIteration(delay!=0) by
- using time.sleep().
-
- * twisted/internet/gtkreactor.py: same fixes as for gtk2reactor.
- Instead of a pygtk bug we've got the limited gtk_input_add API,
- which hides POLLHUP/POLLERR, so detecting closed fds might not be
- as reliable.
-
-2003-04-11 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/lore:
- Added a "lore-slides" plugin, with HTML, Magicpoint and Prosper output
- targets. It's still a bit rough, but functional.
-
-2003-04-10 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * .: Release 1.0.4alpha2.
-
-2003-04-09 Brian Warner <warner@lothar.com>
-
- * twisted/scripts/trial.py (Options.opt_reactor): install reactor
- before parseArgs() does an import and installs the default one
-
- * twisted/internet/process.py: fix typo,
- s/registerReapProccessHandler/registerReapProcessHandler)/
-
-2003-04-09 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/base.py: Change the sort order of DelayedCalls
- and remove them from the end of the list instead of the beginning.
- This changes O(n) complexity to O(1) complexity.
-
-2003-04-09 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_jelly.py, test_newjelly: Test cleanup.
- Parameterize the jelly module used by the tests, make test_jelly a
- subclass of test_newjelly using a different jelly module: tests
- should now be unified. Also change tests to use proper trial
- self.failUnless() methods instead of bare assert().
-
-2003-04-09 Bob Ippolito <bob@redivi.com>
-
- * twisted/python/util.py (OrderedDict): added a UserDict subclass
- that preserves insert order (for __repr__, items, values, keys).
-
- * twisted/internet/app.py (Application, _AbstractServiceCollection):
- Preserve service order, start services in order, stop them in reverse.
-
-2003-04-09 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted/protocols/ftp.py (FTPClient):
- Added STOR support to FTPClient, as well as support for using
- Producers or Consumers instead of Protocols for uploading/downloading.
- * twisted/protocols/policies.py (TimeoutWrapper):
- Added a timeout policy that can be used to automatically disconnect
- inactive connections.
-
-2003-04-07 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_banana.py (BananaTestCase): add Acapnotic's
- crash-cBanana test case, and some others.
-
- * twisted/spread/banana.py (Pynana.dataReceived): add 640k limit on
- lists/tuples, parameterize the limit into banana.SIZE_LIMIT, define
- and use BananaError on all problems. Impose 640k limit on outbound
- lists/tuples/strings to catch problems on transmit side too.
-
- * twisted/spread/cBanana.c (cBanana_dataReceived): check malloc()
- return values to avoid segfault from oversized lists. Impose 640k
- limit on length of incoming lists. Raise BananaError on these
- checks instead of the previously-unreachable
- cBanana.'cBanana.error' exception.
-
- * twisted/test/test_process.py (TwoProcessProtocol): add test to make
- sure killing one process doesn't take out a second one
- (PosixProcessTestCasePTY): add variant that sets usePTY=1
-
-2003-04-06 Brian Warner <warner@lothar.com>
-
- * twisted/trial/{unittest.py,remote.py}, twisted/test/test_trial.py:
- Collapse most reportFoo methods into a single reportResults() that
- takes a resultType parameter. This anticipates the addition of .todo
- test-case flags that will add two more resultTypes.
- * twisted/trial/unittest.py: Add .todo flags: creates EXPECTED_FAILURE
- and UNEXPECTED_SUCCESS resultTypes. Like .skip, the .todo can be
- added either to the TestCase object or as a method attribute.
-
-2003-04-04 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/scripts/trial.py: Now takes whatever you throw at it on
- the command line, be it a filename, or a dotted python name for a
- package, module, TestCase, or test method; you no longer need to
- use the -pmcfM switches (unless you really want to).
-
- * twisted/protocols/htb.py: Egress traffic shaping for Consumers
- and Transports, using Heirarchial Token Buckets, patterened after
- Martin Devera's Hierarchical Token Bucket traffic shaper for the
- Linux kernel.
-
- * doc/examples/shaper.py: Demonstration of shaping traffic on a
- web server.
-
- * twisted/protocols/pcp.py: Producer/Consumer proxy, for when you
- wish to install yourself between a Producer and a Consumer and
- subvert the flow of data.
-
-2003-04-04 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/web/microdom.py: parseXML and parseXMLString functions
- that are setup to use the correct settings for strict XML parsing
- and manipulation.
-
-2003-03-31 Brian Warner <warner@lothar.com>
-
- * twisted/trial/unittest.py: use SkipTest's argument as a reason
- and display it in the test results instead of the traceback. Allow
- test methods and TestCase classes to define a .skip attribute
- instead of raising SkipTest.
-
-2003-03-31 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/trial/remote.py: machine-readable trial output to allow
- for the test runner and the results Reporter to be in seperate
- processes.
-
-2003-03-15 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/app.py: Renamed "factory" argument to
- Application.listenUDP() to "proto"
-
-2003-03-13 Tommi Virtanen <tv@twistedmatrix.com>
-
- * twisted/tap/procmon.py, twisted/plugins.tml: support for mktapping
- ProcessMonitors.
-
-2003-03-11 Bob Ippolito <bob@redivi.com>
-
- * twisted/internet/: Replaced apply() in non-deprecated
- twisted.internet modules with Direct Function Calls per
- recommendation from PEP 290.
-
- * twisted/web/client.py: HTTPPageGetter will now write
- self.factory.postdata to the transport after the headers if the
- attribute is present and is not None. The factories, getPage and
- downloadPage now accept keyword arguments for method, postdata,
- and headers. A Content-Length header will be automatically provided
- for the given postdata if one isn't already present. Note that
- postdata is passed through raw; it is the user's responsibility to
- provide a Content-Type header and preformatted postdata. This change
- should be backwards compatible.
-
-2003-03-05 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/: reactor.run() now accepts a keyword
- argument, installSignalHandlers, indicating if signal handlers
- should be installed.
-
-2003-03-04 Tommi Virtanen <tv@twistedmatrix.com>
-
- * twisted/scripts/mktap.py, twisted/internet/app.py: mktap now
- accepts --uid=0 and --gid=0 to really mean root, has command line
- help for --uid=/--gid=, and understands user and group names in
- addition to numbers.
-
-2003-03-04 Tommi Virtanen <tv@twistedmatrix.com>
-
- * twisted/scripts/tap2deb.py, doc/man/tap2deb.1: Option --version=
- collided with global options, renamed to --set-version=.
-
-2003-03-01 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/scripts/twistd.py: Added --report-profile flag to twistd
- daemon.
-
-2003-02-24 Brian Warner <warner@lothar.com>
-
- * twisted/internet/tcp.py, base.py: set FD_CLOEXEC on all new
- sockets (if available), so they will be closed when spawnProcess
- does its fork-and-exec.
-
-2003-02-23 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/scripts/manhole.py: 1.4 manhole now defaults to using a
- GTK2 client where available. Start manhole with the "--toolkit gtk1"
- parameter if you want the old one back.
-
-2003-2-19 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/monitor.py: Monitor web sites.
-
-2003-2-20 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/internet/{app,default,interface,unix}.py: Add 'mode' argument
- to the listenUNIX interface, which sets the filesystem mode for the
- socket.
-
-2003-2-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Release 1.0.4alpha1.
-
-2003-2-18 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/server.py twisted/protocols/http.py: Add a way for
- resources (and other interested parties) to know when a request has
- finished, for normal or abnormal reasons.
-
-2003-02-17 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/scripts/conch.py: Added experimental support for connection
- caching, where if a connection is already available to a server, the
- client will multiplex another session over the existing connection,
- rather that creating a new one.
-
-2003-02-16 Jp Calderone <exarkun@twistedmatrix.com>
-
- * doc/examples/echoserv.py: Rewrote main code to not create a .tap
- file (examples should be simple, and demonstrate as few things as
- possible each).
-
- * doc/examples/echoclient.py: Added UDP echo protocol
- implementation; it is unused by default, but easily enabled.
-
-2003-02-16 Cory Dodt <corydodt@yahoo.com>
-
- * twisted/lore/{latex,default}.py: provide a --config book option
- to Lore, for producing book-level documents from an index page.
-
-2003-02-15 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/scripts/mktap.py, twisted/scripts/twistd.py: Added the
- --appname and --originalname parameters, respectively.
-
- * twisted/doc/man/mktap.py, twisted/doc/man/twistd.py: Documented
- the above two new parameters.
-
-2003-02-12 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/python/text.py (docstringLStrip): 1.6 This will be going
- away in favor of inspect.getdoc.
-
-2003-02-11 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/im/interfaces.py (IAccount): 1.4 New instance attribute:
- "client". Also, added methods getGroup and getPerson.
-
- * twisted/im/basechat.py (ChatUI.getPerson, .getGroup): 1.7 No
- longer accept a Class parameter. The class of the person/group is
- determined by the account they are obtained through.
-
- * twisted/im/basesupport.py (AbstractPerson, AbstractGroup): 1.15
- Hold a reference to account, not client. Also, lose the "chatui"
- parameter -- this may require follow-up.
- (AbstractAccount.__setstate__): 1.15 remove this method. (Why
- was self.port = int(self.port) in __setstate__?)
- (AbstractAccount): 1.15 implement getGroup and getPerson here,
- using _groupFactory and _personFactory factory attributes.
-
- * twisted/im/gtkchat.py (GtkChatClientUI.getPerson, .getGroup): 1.15
- follow ChatUI interface changes.
-
-2003-02-09 Brian Warner <warner@lothar.com>
-
- * twisted/internet/error.py (ProcessDone,ProcessTerminated):
- * twisted/internet/process.py (Process.maybeCallProcessEnded,
- * twisted/internet/process.py (PTYProcess.maybeCallProcessEnded,
- record the signal that killed the process in .signal, set .signal
- to None if the process died of natural causes, set .exitCode to None
- if the process died of a signal.
- * twisted/test/test_process.py: verify .signal, .exitCode are set
- to None when they ought to be, verify signal-death is reported with
- ProcessTerminated and not ProcessDone
-
- * ChangeLog: Set add-log-time-format to iso8601.
-
-2003-02-09 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.3rc1.
-
-2003-02-08 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/tap/mail.py twisted/mail/tap.py twisted/plugins.tml:
- Moved from tap to mail, trying to thin down twisted.tap a little.
-
-2003-02-07 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/lore/default.py twisted/lore/tree.py twisted/lore/latex.py
- twisted/lore/man2lore.py twisted/lore/math.py
- twisted/scripts/html2latex.py twisted/scripts/generatelore.py
- twisted/scripts/hlint.py twisted/scripts/lore.py bin/lore
- bin/generatelore bin/hlint bin/html2latex twisted/plugins.tml:
- refactor lore to be cleaner, more usable and more extendible.
- Removed old scripts, and combined them into one plugin-based script
- which supports Lore, Math-Lore and Man pages and converts to
- LaTeX, HTML and (man pages) to Lore.
-
-2003-02-06 Bob Ippolito <bob@redivi.com>
-
- * twisted/protocols/smtp.py: sendEmail supports multipartboundary
- keyword argument, which is useful for doing HTML emails if passed
- "alternative" as opposed to the default "mixed". Uses 7bit
- encoding for mime types that start with 'text', base64 otherwise.
-
-2003-02-04 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/app.py: listenUNIX and unlistenUNIX methods added
- to Application class. These should be used in place of listenTCP
- and unlistenTCP when UNIX sockets are desired. The old,
- undocumented behavior no longer works! Also added connectUDP and
- unlistenUDP to Application.
-
-2003-01-31 Cory Dodt <corydodt@yahoo.com>
-
- * twisted/lore/latex.py: Don't treat comments like text nodes, just
- drop them.
-
-2003-01-30 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/default.py
- twisted/internet/base.py
- twisted/internet/tcp.py
- twisted/internet/ssl.py
- twisted/internet/udp.py
- twisted/internet/unix.py
-
- Refactor of many internal classes, including Clients and
- Connectors. UNIX socket functionality moved out of the TCP classes
- and into a new module, unix.py, and implementation of IReactorUNIX
- by PosixReactorBase made conditional on platform UNIX socket
- support. Redundant inheritance cruft removed from various classes.
-
- * twisted/internet/app.py: listenWith, unlistenWith, and connectWith
- methods added to Application.
-
- * twisted/internet/interfaces.py: IReactorArbitrary added.
-
-2003-01-30 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/manhole/service.py (IManholeClient.console): 1.35
- exception messages now use a Failure.
- (IManholeClient.listCapabilities): 1.35 Method to describe what
- capabilities a client has, i.e. "I can receive Failures for
- exceptions."
-
-2003-01-29 Donovan Preston <dp@twistedmatrix.com>
-
- * twisted/web/woven/controller.py
- twisted/web/woven/template.py
- twisted/web/woven/view.py
- twisted/web/woven/widgets.py Major woven codepath cleanup
-
- * Uses a flat list of outstanding DOM nodes instead of
- recursion to keep track of where Woven is in the page
- rendering process
-
- * Removes View's dependency on DOMTemplate as a base
- class, in preparation for deprecation of DOMTemplate
- (all of the same semantics are now directly implemented
- in View). As a result, View has no base classes, making
- the inheritance chain cleaner.
-
- * Stores the namespace stacks (model, view, and controller
- name lookup chain) in the View directly, and each widget
- gets an immutable reference to it's position in the lookup
- chain when it is created, making re-rendering Widgets more
- reliable
-
- * Represents the namespace stacks as a cons-like tuple
- structure instead of mutable python lists, reducing
- confusion and list-copying; instead of copying the current
- stack lists each time a Widget is created, it just gets a
- reference to the current tuples for each of the stacks
-
-2003-01-29 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.2 Final.
-
- * .: Releasing 1.0.3alpha1. Release Often :-D
-
-2003-01-29 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/internet/abstract.py (FileDescriptor.__init__): 1.36
- Ephemeral.
-
- * twisted/internet/tcp.py (Port.__getstate__): 1.100 As an
- Ephemeral, this needs no __getstate__.
-
-2003-01-27 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/spread/ui/gtk2util.py (login): Perspective Broker login
- dialog for GTK+ version 2.
-
-2003-01-26 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.2rc1.
-
- * .: Releasing 1.0.2rc2 (rc1 was dead in the water; hlint bug now
- fixed).
-
- * .: Releasing 1.0.2rc3 (rc2 was dead in the water;
- twisted.lore.latex bug now fixed)
-
-2003-01-26 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/im/interfaces.py (IClient.__init__): 1.3 Accept a
- logonDeferred parameter. The client should call this back when
- it is successfully logged in.
-
- * twisted/im/basesupport.py
- (AbstractClientMixin.registerAsAccountClient): 1.13 Gone.
- chatui.registerAccountClient is called in AbstractAccount.logOn
- instead.
-
-2003-01-22 Dave Peticolas <dave@krondo.com>
-
- * twisted/web/xmlrpc.py: add docstring for Proxy. handle
- serialization errors. check for empty deferred on connectionLost.
-
- * twisted/test/test_internet.py: make sure wakeUp actually works
-
-2003-01-21 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/internet/defer.py: added utility method for
- getting result of list of Deferreds as simple list.
-
-2003-1-20 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/interfaces.py: type argument removed from
- IReactorCore.resolve method. IReactorPluggableResolver interface
- added.
-
- * twisted/internet/base.py: IReactorPluggable added to
- ReactorBase.__implements__ and ReactorBase.installResolver added.
-
-2003-1-18 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/trial/unittest.py twisted/scripts/trial.py: adding --summary
-
-2003-01-15 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.2alpha3.
-
-2003-01-13 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.2alpha2.
-
-2003-01-11 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/protocols/shoutcast.py: add client support for
- Shoutcast MP3 streaming protocol.
-
-2003-01-10 Itamar Shtull-Trauring <itamar@itamarst.org>
-
- * twisted/scripts/twistd.py: in debug mode, jump into debugger for any
- logged exception.
-
-2003-01-10 Dave Peticolas <dave@krondo.com>
-
- * twisted/trial/unittest.py: enable test cruft checking
-
- * twisted/test/test_policies.py: cleanup timers
-
- * twisted/protocols/policies.py: start/stop bandwidth timers as needed
-
- * twisted/test/test_internet.py: cleanup timers
-
- * twisted/test/test_woven.py: expire sessions to clean up timers
-
- * twisted/web/woven/guard.py: stop timer when session expires
-
-2003-1-9 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/google.py: Search google for best matches
-
-2003-01-09 Dave Peticolas <dave@krondo.com>
-
- * twisted/protocols/http.py: start/stop log timer as needed
-
-2003-01-08 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_smtp.py: cleanup timers after test
-
- * twisted/trial/unittest.py: keep errors that are logged and
- submit them as test failures when tests are finished.
-
- * twisted/python/log.py: if errors are being kept, don't print
- them
-
-2003-1-8 Moshe Zadka <moshez@twistedmatrix.com>
-
- * doc/man/trial.1 twisted/scripts/trial.py: Add -l/--logfile argument
- to allow giving a log file.
-
- * twisted/trial/unittest.py: add SkipTest exception, which tests can
- raise in their various test* method to skip a test which is not
- excpected to pass.
-
-2003-01-08 Jonathan M. Lange <jml@mumak.net>
-
- * twisted/trial/*, bin/trial, twisted/scripts/trial.py,
- doc/man/trial.1: Added 'trial', a new unit testing framework for
- Twisted.
-
- * twisted/test/test_*, admin/runtests: Moved existing tests over to
- trial.
-
-2003-01-06 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/python/microdom.py: Added beExtremelyLenient mode (for
- parsing "tag soup"). While this isn't quite as lenient as Mozilla
- or IE's code (it will, for example, translate
- <div><i><b>foo</i>bar</b></div> to <div><i><b>foo</b></i>bar</div>
- ) I am still rather proud of the wide range of complete garbage
- that it will mangle into at least reasonably similar XHTML-esque
- documents.
-
-2003-01-05 Brian Warner <warner@lothar.com>
-
- * twisted/internet/cReactor/*, setup.py: Implement getDelayedCalls for
- cReactor. Create cDelayedCall class, implement .cancel(), .reset(),
- and .delay() for them.
-
-2003-01-03 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/python/components.py: Fix bug due to interaction between
- Componentized subclasses and twisted.python.rebuild.rebuild()
-
- * twisted/python/reflect.py: Removed backwards compatability hack
- for deprecated name twisted.protocols.telnet.ShellFactory and empty
- oldModules dictionary.
-
-2003-01-02 Brian Warner <warner@lothar.com>
-
- * twisted/test/test_internet.py (DelayedTestCase): add test
- coverage for IReactorTime.getDelayedCalls
-
-2002-12-30 Brian Warner <warner@lothar.com>
-
- * pyunit/unittest.py (TestCase.__call__): clean the reactor between
- tests: cancel any leftover reactor.callLater() timers. This helps
- to keep deferred failures isolated to the test that caused them.
-
-2002-12-30 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/*: added docstrings to most conch classes and functions
-
-2002-12-30 Brian Warner <warner@lothar.com>
-
- * twisted/spread/pb.py (Broker.connectionLost): clear localObjects
- too, to break a circular reference involving AuthServs that could
- keep the Broker (and any outstanding pb.Referenceables) alive
- forever.
-
-2002-12-29 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/python/compat.py: Single module where all compatability
- code for supporting old Python versions should be placed.
-
-2002-12-28 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/web/woven/guard.py: Newer, better wrappers for
- authentication and session management. In particular a nice
- feature of this new code is automatic negotiation with browsers on
- whether cookies are enabled or not.
-
-2002-12-27 Paul Swartz <z3p@twistedmatrix.com>
-
- * bin/tkconch: initial commit of tkconch, a SSH client using Tkinter
- as a terminal emulator. puts up a menu to configure when run without
- arguments.
-
- * twisted/conch/ui: moved ansi.py and tkvt100.py to t.c.ui so they are
- away from the purely conch stuff.
-
-2002-12-25 Christmas Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.2alpha1 - Merry Christmas!
-
-2002-12-25 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/dict.py: dict client protocol implementation
- from Pavel "Pahan" Pergamenshchik (<pp64@cornell.edu>)
-
-2002-12-23 Jp Calderone <exarkun@twistedmatrix.com>
-
- * doc/examples/testdns.py and doc/examples/dns-service.py added as
- simple example of how to use new DNS client API.
-
-2002-12-23 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/xmlrpc.py: added XML RPC client support
-
-2002-12-22 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/ssh/keys.py, twisted/conch/ssh/asn1.py: support for
- writing public and private keys.
-
- * bin/ckeygen: new script to create public/private key pairs
-
-2002-12-22 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/protocols/dns.py: Support for AFSDB, RP, and SRV RRs
- added.
-
-2002-12-18 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/persisted/dirdbm.py: copyTo and clear methods added
- to DirDBM class
-
-2002-12-18 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/ssh/connection.py, twisted/test/test_conch: fixes to
- work on Python 2.1.
-
- * twisted/internet/process.py: usePTY now can be an optional tuple of
- (masterfd, slavefd, ttyname).
-
-2002-12-18 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/rewrite.py: it works now, even when used as a rootish
- resource. Also, the request.path is massaged.
-
-2002-12-13 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/util.py: support numeric type
-
-2002-12-13 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/client.py: add 301/302 support
-
-2002-12-13 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_ftp.py: give client time to start up (fixes
- one test for gtk/gtk2 reactors)
-
- * twisted/protocols/ftp.py: ftp client in passive mode should not
- close data until both command and protocol are finished. (fixes
- one test in gtk/gtk2 reactors)
-
- * twisted/internet/gtkreactor.py: remove redundant code
-
- * twisted/internet/gtk2reactor.py: remove redundant code
-
- * twisted/internet/abstract.py: fix spelling in documentation
-
-2002-12-12 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_jelly.py: test class serialization
-
- * twisted/spread/jelly.py: join module names with '.' in
- _unjelly_class
-
-2002-12-12 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/pamauth.py: added, gives support for authentication
- using PAM.
-
- * twisted/conch/*: support for the keyboard-interactive authentication
- method which uses PAM.
-
-2002-12-12 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/python/log.py: add setStdout, set logfile to NullFile by
- default.
-
-2002-12-11 Donovan Preston <dp@twistedmatrix.com>
-
- * Added new woven example, Hello World.
-
- * Updated woven howto to talk about Hello World. TODO: Finish refactoring
- woven quotes example, then write more advanced woven howtos on writing
- Widgets and InputHandlers.
-
-2002-12-11 Paul Swartz <z3p@twistedmatix.com>
-
- * twisted/conch/*: enabled 'exec' on the server, disabled core dumps,
- and some fixes
-
-2002-12-10 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/*: many fixes to conch server, now works and can run
- as root.
-
- * twisted/conh/ssh/session.py: fix root exploit where a python shell was
- left acessable to anyone.
-
-2002-12-10 Cory Dodt <corydodt@yahoo.com>
-
- * t/scripts/postinstall.py: new. Create shortcut icons on win32.
-
- * twisted-post-install.py: new. Runs t/scripts/postinstall.py
-
- * setup.py: copy twisted-post-install.py during install_scripts
-
-2002-12-09 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/internet/app.py: actually set the euid/egid if users ask
-
-2002-12-09 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_conch.py: wait for ssh process to finish
-
- * twisted/scripts/postinstall.py: fix indentation
-
- * twisted/conch/identity.py: fix indentation
-
-2002-12-09 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/conch/ssh/transport.py: don't accept host keys by default
- because it's a huge security hole.
-
-2002-12-09 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/util.py: handle None as null
-
- * twisted/internet/interfaces.py: add missing 'self' argument
-
-2002-12-08 Dave Peticolas <dave@krondo.com>
-
- * pyunit/unittest.py: add missing 'self.' prefix to data member
- reference
-
- * twisted/enterprise/util.py: make sure quoted values are strings
- (fixes bug storing boolean types)
-
-2002-12-06 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_internet.py: flush error to prevent failure
- with non-destructive DeferredLists.
-
- * twisted/test/test_ftp.py: flush FTPErrors to prevent failures
- with non-destructive DeferredLists.
-
- * twisted/test/test_defer.py: catch the errors to prevent failure
- with non-destructive DeferredLists
-
- * twisted/enterprise/util.py: add some postgres types. boolean
- types need to be quoted. remove unused selectSQL variable.
-
-2002-12-05 Dave Peticolas <dave@krondo.com>
-
- * twisted/enterprise/sqlreflector.py: fix some sql escaping
- bugs. allow subclasses to override escaping semantics.
-
- * twisted/enterprise/util.py: allow quote function's string escape
- routine to be overridden with a keyword argument.
-
-2002-12-5 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/python/plugin.py: fixed a bug that got the wrong plugins.tml
- if the package was installed in two different places
-
- * twisted/inetd/*, twisted/runner/*: moved inetd to runner, to live in
- harmony with procmon
-
-2002-12-04 Dave Peticolas <dave@krondo.com>
-
- * twisted/test/test_policies.py: Take the start time timestamp
- immediately before creating the ThrottlingFactory, since the
- factory starts timing when it is created.
-
- * admin/runtests: Add a 'gtk2' test type to use the gtk2reactor
- for the test suite.
-
-2002-12-2 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/client.py: web client
-
-2002-11-30 Paul Swartz <z3p@twistedmatrix.com>
-
- * Summary of Conch changes: An actual client (bin/conch) which is
- mostly compatible with the OpenSSH client. An optional C module to
- speed up some of the math operations. A bunch of other stuff has
- changed too, but it's hard to summarize a month of work.
-
-2002-11-24 Donovan Preston <dp@twistedmatrix.com>
-
- * twisted/web/woven/*: Added the beginnings of a general framework for
- asynchronously updating portions of woven pages that have already been
- sent to the browser. Added controller.LiveController, page.LivePage,
- and utils.ILivePage to contain code for dealing with keeping Views alive
- for as long as the user is still looking at a page and has a live
- Session object on the server; code for responding to model changed
- notifications, rerendering Views that depend on those models that have
- changed; code for sending these rerendered views as html fragments to
- the browser; and javascript code to mutate the DOM of the live page
- with the updated HTML. Mozilla only for the moment; ie to come soon.
-
- * twisted/web/woven/widgets.py: Added API for attaching Python functions
- to widgets that fire when a given javascript event occurs in the
- browser.
- Widget.addEventHandler(self, eventName, handler, *args) and
- Widget.onEvent(self, request, eventName, *args). The default onEvent
- will dispatch to event handlers registered with addEventHandler.
-
-2002-11-24 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.1.
-
-2002-11-23 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/names/client.py, twisted/names/server.py: Client and
- server domain name APIs
-
- * twisted/tap/dns.py: 'mktap dns'
-
-2002-11-23 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/scripts/twistd.py twisted/python/syslog.py: Add syslog support
-
-2002-11-23 Kevin Turner <acapnotic@twistedmatrix.com>, Sam Jordan <sam@twistedmatrix.com>
-
- * twisted/protocols/irc.py (IRCClient.dccResume, dccAcceptResume):
- Methods for mIRC-style resumed file transfers.
- (IRCClient.dccDoSend, IRCClient.dccDoResume)
- (IRCClient.dccDoAcceptResume, IRCClient.dccDoChat): These are for
- clients to override to make DCC things happen.
- (IRCClient.dcc_SEND, dcc_ACCEPT, dcc_RESUME, dcc_CHAT)
- (IRCClient.ctcpQuery_DCC): Refactored to dispatch to dcc_* methods.
- (DccFileReceiveBasic.__init__): takes a resumeOffset
-
-2002-11-20 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing 1.0.1rc1
-
-2002-11-16 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * Multicast UDP socket support in most reactors.
-
-2002-11-11 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * .: Releasing 1.0.1alpha4
-
- * .: Releasing 1.0.1alpha3
-
-2002-11-10 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * .: Releasing 1.0.1alpha2
-
- * twisted/web/static.py, twisted/tap/web.py: Changed 'mktap web'
- to use --ignore-ext .ext so that you can assign order to the
- extensions you want to ignore, and not accidentally catch bad
- extensions.
-
-2002-11-04 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/internet/tksupport.py: new, better Tkinter integration.
- Unlike before, run the reactor as usual, do *not* call Tkinter's
- mainloop() yourself.
-
-2002-10-25 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/domhelpers.py twisted/python/domhelpers.py
- twisted/lore/tree.py twisted/web/woven/widgets.py: Moved domhelpers
- to twisted.web, and add to it all the generic dom-query functions
- from twisted.lore.tree
-
- * twisted/scripts/generatelore.py twisted/scripts/html2latex.py
- bin/html2latex bin/generatelore twisted/lore/__init__.py
- twisted/lore/latex.py twisted/lore/tree.py: Add the document generation
- Twisted uses internally to the public interface.
-
- * twisted/python/htmlizer.py: a Python->HTML colouriser
-
-2002-10-23 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/web/soap.py: experimental SOAP support, using SOAPpy.
- See doc/examples/soap.py for sample usage.
-
-2002-10-22 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/python/log.py: Two new features.
- 1) a stupid `debug' method that simply prefixes a message with "debug"
- and indents it so it's easier to distinguish from normal messages.
- This can eventually log to some magic "debug channel", once we have
- that implemented.
-
- 2) implemented a custom warning handler; now warnings look sexy.
- (the hackish overriding of warnings.showwarning is the recommended way
- to do so, according to the library reference.)
-
-2002-10-22 Moshe Zadka <moshez@twistedmatrix.com>
-
- * setup.py: conditionalize cReactor on threads support too. This
- is somewhat of a hack as it it done currently, but it's only necessary
- on weird OSes like NetBSD. I assume any UNIX with thread support has
- pthreads.
-
- * twisted/internet/tksupport.py: tunable reactor iterate delay
- parameter [by Jp Calderone]
-
-2002-10-17 Moshe Zadka <moshez@twistedmatrix.com>
-
- * bin/websetroot twisted/scripts/websetroot.py: Added a program to set
- the root of a web server after the tap exists
-
-2002-10-14 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/vhost.py: add a virtual host monster to support twisted
- sites behind a reverse proxy
-
- * twisted/tap/web.py twisted/web/script.py
- doc/man/mktap.1: adding an option to have a resource script as the root
-
-2002-10-13 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/internet/utils.py twisted/internet/process.py
- twisted/internet/interfaces.py twisted/internet/default.py: Moved
- utility functions into twisted.internet.utils
-
-2002-10-12 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/internet/process.py twisted/internet/interfaces.py
- twisted/internet/default.py: Add utility method to get output of
- programs.
-
-2002-10-11 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/internet/wxsupport.py: improved responsiveness of wxPython
- GUI (50 FPS instead of 10 FPS).
-
-2002-10-08 Brian Warner <warner@twistedmatrix.com>
-
- * doc/howto: Added PB/cred and Application docs, updated Manhole
- and Process docs. Moved Manhole from "Administrators" section to
- "Developers" section.
-
-2002-10-10 Moshe Zadka <moshez@twistedmatrix.com>
-
- * .: Releasing 0.99.4
-
-2002-10-07 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * .: Release 0.99.4rc1
-
- * twisted/protocols/http.py: backed out changes to HTTP that
- broke 0.99.3 twisted.web.distrib.
-
-2002-10-7 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/script.py: Add ResourceTemplate which uses PTL for
- creation of resources.
-
-2002-10-7 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/tap/web.py: It is now possibly to add processors via
- the command line
-
-
-2002-10-04 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twistd: when running in debug mode (-b), sending a SIGINT signal
- to the process will drop into the debugger prompt.
-
-2002-10-5 Moshe Zadka <moshez@twistedmatrix.com>
-
- * .: Releasing 0.99.3
-
-2002-10-01 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/protocols/http.py: Fixed many bugs in protocol parsing,
- found by new unit tests.
-
-2002-9-30 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/protocols/sux.py twisted/web/microdom.py: Made is possible
- to sanely handle parse errors
-
-2002-09-26 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/internet/app.py (_AbstractServiceCollection.removeService):
- (MultiService.removeService): inverse of addService
- (ApplicationService.disownServiceParent): inverse of setServiceParent
-
-2002-9-27 Moshe Zadka <moshez@twistedmatrix.com>
-
- * .: Releasing 0.99.2
-
-2002-09-26 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/web/microdom.py: Better string formatting of XML
- elements is now available, to aid with debugging of web.woven
- (among other applications).
-
-2002-09-25 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/tap/manhole.py: mktap manhole will now prompt for a
- password or accept one from stdin if one is not provided on the
- command line.
-
-2002-09-25 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * bin/tapconvert: made sure tapconvert program gets installed.
-
-2002-09-24 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/web/resource.py (Resource.wasModifiedSince): revoked,
- not adding this after all. Instead,
-
- * twisted/protocols/http.py (Request.setLastModified)
- (Request.setETag): these methods to set cache validation headers
- for the request will return http.CACHED if the request is
- conditional and this setting causes the condition to fail.
-
-2002-9-24 Moshe Zadka <moshez@twistedmatrix.com>
-
- * .: Releasing 0.99.2rc2
-
-2002-9-23 Donovan Preston <dp@twistedmatrix.com>
-
- * Renaming domtemplate/domwidgets/dominput/wmvc to Woven
- Woven - The Web Object Visualization Environment
-
- * Created package twisted/web/woven
-
- * Renamed domtemplate to template, domwidgets to widgets,
- and dominput to input
-
- * Refactored wmvc into three modules, model, view, and controller
-
-2002-9-23 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/spread/pb.py: add getObjectAtSSL, refactored into
- getObjectRetreiver so more transports can be easily supported
-
-2002-09-21 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/protocols/http.py (Request.setLastModified): Use
- setLastModified to set a timestamp on a http.Request object, and
- it will add a Last-Modified header to the outgoing reply.
-
- * twisted/web/resource.py (Resource.wasModifiedSince): companion
- method, override this to get sensible handling of
- If-Modified-Since conditional requests.
-
-2002-09-21 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/web/static.py, twisted/web/script.py: Previously, it was
- not possible to use the same xmlmvc application (directory full
- of files and all) to interface to separate instances in the same
- server, without a considerable amount of hassle. We have
- introduced a new "Registry" object which is passed to all .rpy
- and .epy scripts as "registry" in the namespace. This is a
- componentized, so it can be used to associate different
- components for the same interface for different File instances
- which represent the same underlying directory.
-
-2002-09-20 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/web/microdom.py: You can now specify tags that the
- parser will automatically close if they are not closed
- immediately. This is to support output from HTML editors which
- will not output XML, but still have a predictable
- almost-but-not-quite XML structure. Specifically it has been
- tested with Mozilla Composer.
-
-2002-9-20 Moshe Zadka <moshez@twistedmatrix.com>
-
- * Documenting for others
-
- * setup.py: now setup.py can function as a module
-
- * twisted/enterprise/xmlreflector.py: deprintified
-
- * twisted/internet/abstract.py, twisted/internet/fdesc.py,
- twisted/internet/app.py, twisted/internet/gtkreactor.py,
- twisted/internet/main.py, twisted/internet/protocol.py,
- twisted/internet/ssl.py, twisted/internet/tksupport.py,
- twisted/internet/pollreactor.py, twisted/internet/defer.py:
- added and modified __all__
-
- * twisted/internet/base.py: changed ReactorBase's __name__, added
- __all__
-
- * twisted/internet/default.py, twisted/internet/error.py,
- twisted/internet/process.py,
- twisted/internet/win32eventreactor.py: reaping all processes on
- SIGCHLD, changes in process's API
-
- * twisted/python/components.py: added Adapter and setComponent
-
- * twisted/python/log.py: logging several strings works
-
- * twisted/python/reflect.py: fixed namedModule() to handle packages
-
- * twisted/web/dom*.py: added submodels, moved to microdom, removed
- unsafe code
-
- * twisted/python/mvc.py: changed submodel support, added ListModel,
- Wrapper
-
- * twisted/web/microdom.py: minidom compat fixes
-
-2002-9-20 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted/internet/error.py twisted/internet/process.py:
- ProcessEnded -> ProcessTerminated/ProcessDone. Now it is possible
- to read off the error code.
-
-2002-9-19 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/scripts/twistd.py: Added ability to chroot. Moved directory
- change to after loading of application.
-
-2002-9-19 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/*: changed print to log.msg
-
- * bin/* twisted/scripts/*.py: move code from bin/ to modules
-
- * twisted/inetd/*.py: inetd server in twisted
-
- * twisted/protocols/sux.py twisted/web/microdom.py: XML parsing
-
- * twisted/conch/*.py: better logging and protocol support
-
- * twisted/cred/*.py: deprecation fixes
-
- * twisted/internet/app.py: add encryption
-
- * twisted/internet/base.py: fix deprecation, add DelayedCall,
- move to connect* from client*
-
- * twisted/internet/error.py: errno mapping works on more platforms,
- AlreadyCalled, AlreadyCancelled errors
-
- * twisted/internet/gtkreactor.py: try requiring gtk1.2, timeout->idle
-
- * twisted/internet/interfaces.py: added IDelayedCall IProcessTransports
-
- * twisted/internet/javareactor.py: using failure, better dealing with
- connection losing, new connect* API
-
- * twisted/internet/process.py: dealing better with ending
-
- * twisted/internet/protocol.py: factories have a "noisy" attribute,
- added ReconnectingClientFactory BaseProtocol
-
- * twisted/internet/ptypro.py: fixed traceback
-
- * twisted/internet/reactor.py: better guessing of default
-
- * twisted/internet/tcp.py: failure
-
- * twisted/internet/win32eventreactor.py: update to new API, support GUI
-
- * twisted/manhole/service.py: fix deprecation
-
- * twisted/news/database.py: fix to be 2.1 compat., generating
- message-id, bytes, lines, date headers, improved storage
-
- * twisted/news/news.py: UsenetClientFactory, UsenetServerFactory
-
- * twisted/persisted/marmalade.py: use twisted.web.microdom
-
- * twisted/protocols/ftp.py: dito, data port uses new client API
-
- * twisted/protocols/http.py: StringTransport instead of StringIO
-
- * twisted/protocols/irc.py: stricter parsing, avoid flooding
-
- * twisted/protocols/loopback.py: new reactor API, loopback over UNIX
- sockets
-
- * twisted/protocols/nntp.py: more lenient parsing, more protocol support
-
- * twisted/protocols/oscar.py: new reactor API
-
- * twisted/python/components.py: fix setAdapter add removeComponent
-
- * twisted/python/failure.py: cleanFailure
-
- * twisted/python/log.py: can now log multiple strings in one go
-
- * twisted/python/logfile.py: fixed rotation
-
- * twisted/python/rebuild.py: better 2.2 support
-
- * twisted/python/util.py: getPassword
-
- * twisted/scripts/mktap.py: better --help, --type, encryption
-
- * twisted/spread/*.py: removed deprecation warnings
-
- * twisted/spread/util.py: improved Pager
-
- * twisted/tap/news.py: works saner now
-
- * twisted/tap/ssh.py: can specify authorizer
-
- * twisted/tap/words.py: can bind services to specific interfaces
-
- * twisted/web/distrib.py: now works on java too
-
- * twisted/web/domtemplate.py: improved cache
-
- * twisted/web/error.py: ForbiddenResource
-
- * twisted/web/html.py: lower-case tags
-
- * twisted/web/server.py: use components
-
- * twisted/web/static.py: added .flac, .ogg, properly 404/403,
- lower-case tags
-
- * twisted/web/twcgi.py: fixed for new process API
-
- * twisted/web/widgets.py: lower-case tags
-
- * twisted/web/xmlrpc.py: new abstraction for long running xml-rpc
- commands, add __all__
-
- * twisted/words/ircservice.py: new connectionLost API
-
- * twisted/words/service.py: refactoring and error handling
-
- * twisted/words/tendril.py: lots of fixes, it works now
-
-2002-09-17 Donovan Preston <dp@twistedmatrix.com>
-
- * Added better error reporting to WebMVC. To do this, I had to
- remove the use of "class" and "id" attributes on nodes as
- synonyms for "model", "view", and "controller". Overloading
- these attributes for three purposes, not to mention their
- usage by JavaScript and CSS, was just far too error-prone.
-
-2002-09-09 Andrew Bennetts <spiv@twistedmatrix.com>
-
- * twisted.inetd: An inetd(8) replacement. TCP support should be
- complete, but UDP and Sun-RPC support is still buggy. This was
- mainly written as a proof-of-concept for how to do a forking
- super-server with Twisted, but is already usable.
-
-2002-08-30 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.1rc4. There was a bug in the acquisition
- code, as well as a typo in TwistedQuotes.
-
-2002-08-29 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.1rc3. A bug in the release script
- left .pyc files in the tarball.
-
-2002-08-29 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.1rc2. There was a bug with circular
- imports between modules in twisted.python.
-
-2002-08-28 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.1rc1.
-
-2002-08-27 Donovan Preston <dp@twistedmatrix.com>
-
- * twisted.web.domtemplate: Look up templates in the directory of
- the module containing the DOMTemplate doing the lookup before
- going along with regular acquisition.
-
-2002-08-27 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.*: Lots of minor fixes to make JavaReactor work again.
-
-2002-08-26 Andrew Bennetts <andrew-twisted@puzzling.org>
-
- * twisted.python.logfile: Added the ability to disable log
- rotation if logRotation is None.
-
-2002-08-22 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted.news: Added a decent RDBM storage backend.
-
-2002-08-21 Paul Swartz <z3p@twistedmatrix.com>
-
- * doc/howto/process.html: Process documentation, too!
-
-2002-08-20 Paul Swartz <z3p@twistedmatrix.com>
-
- * doc/howto/clients.html: Client-writing documentation.
-
-2002-08-20 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted.protocols.nntp: More protocol implemented: SLAVE, XPATH,
- XINDEX, XROVER, TAKETHIS, and CHECK.
-
-2002-08-19 Christopher Armstrong <radix@twistedmatrix.com>
-
- * bin, twisted.scripts.*: Migrated all bin/* scripts'
- implementations to twisted/scripts. This means win32 users will
- finally have access to all of the twisted scripts through .bat
- files!
-
-2002-08-19 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted.news, twisted.protocols.nntp: Additional RFC977 support:
- HELP and IHAVE implemented.
-
-2002-08-19 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted.internet.{process,win32eventreactor,etc}: New and
- hopefully final Process API, and improved Win32 GUI support.
-
-2002-08-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Everything: Got rid of almost all usage of the `print' statement
- as well as any usage of stdout. This will make it easier to
- redirect boring log output and still write to stdout in your
- scripts.
-
-2002-08-18 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.0 final. No changes since rc9.
-
-2002-08-17 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.0rc8, with a fix to tap2deb and
- slightly updated options documentation.
-
- * Releasing Twisted 0.99.0rc9 with fixes to release-twisted
- and doc/howto/options.html.
-
-2002-08-16 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.0rc6, with some fixes to setup.py
- * Releasing Twisted 0.99.0rc7, __init__.py fixes.
-
-2002-08-15 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.0rc5, with some one severe bug-fix and
- a few smaller ones.
-
-2002-08-14 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.99.0rc1! ON THE WAY TO 1.0, BABY!
- * Releasing Twisted 0.99.0rc2! Sorry, typoed the version number in
- copyright.py
- * Releasing Twisted 0.99.0rc3! I HATE TAGGING!
- * Releasing Twisted 0.99.0rc4, some very minor errors fixed.
-
-2002-08-14 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.internet, twisted.cred: Applications and Authorizers are
- now completely decoupled, save for a tiny backwards-compatibility.
-
-2002-08-10 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted.internet.defer, twisted.python.failure: Changes to
- Deferred and Failure to make errbacks more consistent. error
- callbacks are now *guaranteed* to be passed a Failure instance,
- no matter what was passed to Deferred.errback().
-
-2002-08-07 Jp Calderone <exarkun@twistedmatrix.com>
-
- * twisted.python.usage: New "subcommands" feature for
- usage.Options: Now, you can have nested commands
- (`cvs commit'-style) for your usage.Options programs.
-
-2002-08-04 Bruce Mitchener <bruce@twistedmatrix.com>
-
- * twisted.internet: New `writeSequence' method on transport
- objects: This can increase efficiency as compared to `write`ing
- concatenated strings, by copying less data in memory.
-
-2002-08-02 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.cred.service, twisted.internet.app: Application/Service
- refactor: These two things should be less dependant on each other,
- now.
-
-2002-07-31 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.issues: After weeks of hacking in the secret (Austin,
- TX) hideout with Allen Short, twisted.issues, the successor to
- Twisted Bugs, is born. Featuring a paranoia-inducing chat-bot
- interface!
-
-2002-07-30 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted.internet.kqueue: Thanks to Matt Campbell, we now have a
- new FreeBSD KQueue Reactor.
-
-2002-07-27 Christopher Armstrong <radix@twistedmatrix.com>
-
- * doc/fun/Twisted.Quotes: Added our seekrut Twisted.Quotes file to
- Twisted proper.
-
-2002-07-26 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.spread: "Paging" for PB: this is an abstraction for
- sending big streams of data across a PB connection.
-
-
-2002-07-23 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted.internet: Rewrite of client APIs. `reactor.clientXXX'
- methods are now deprecated. See new reactor.connect*
- documentation. Also Application-level client methods have been
- reworked, see the Application documentation.
-
-2002-07-23 Bryce Wilcox-O'Hearn <zooko@twistedmatrix.com>
-
- * twisted.zoot: Application-level implementation of Gnutella.
-
-2002-07-21 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.im, bin/im: GUI improvements to t-im, and renamed
- bin/t-im to bin/im (and get rid of old twisted.words client).
-
-2002-07-15 Bryce Wilcox-O'Hearn <zooko@twistedmatrix.com>
-
- * twisted.protocols.gnutella: Twisted now has an implementation of
- the Gnutella protocol.
-
-2002-07-15 Sean Riley <sean@twistedmatrix.com>
-
- * twisted.sister: Now featuring distributed login.
-
-2002-07-15 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted.conch: A new implementation of ssh2, bringing Twisted
- one step closer to being a complete replacement of all unix
- services ;-)
-
-2002-07-14 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.19.0! It's exactly the same as rc4.
-
-2002-07-13 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.19.0rc4. All Known Issues in the README have
- been fixed. This will hopefully be the last release candidate for
- 0.19.0.
-
-2002-07-07 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.19.0rc3.
-
-2002-07-07 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.19.0rc2.
-
-2002-07-07 Christopher Armstrong <radix@twistedmatrix.com>
-
- * Releasing Twisted 0.19.0rc1.
-
-2002-07-07 Keith Zaback <krz@twistedmatrix.com>
-
- * twisted.internet.cReactor: A new poll-based reactor written in
- C. This is still very experimental and incomplete.
-
-2002-07-07 Donovan Preston <dp@twistedmatrix.com>
-
- * twisted.web.dom*: Better support in domtemplate/domwidgets etc
- for Deferreds and Widgets. Also deprecated getTemplateMethods
- method in favor of automatically looking up methods on the class
- based on the attributes found in the template. There are some
- minimal docs already, and better ones coming soon.
-
-2002-06-26 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.internet.process,interfaces,default: Process now
- supports SetUID: there are new UID/GID arguments to the process
- spawning methods/constructors.
-
-2002-06-22 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted.protocols.oscar: totally rewrote OSCAR protocol
- implementation.
-
-2002-06-18 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.internet.defer: Deprecated the arm method of Deferred
- objects: the replacement is a pair of methods, pause and
- unpause. After the pause method is called, it is guaranteed that
- no call/errbacks will be called (at least) until unpause is
- called.
-
-2002-06-10 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/persisted/aot.py, bin/twistd,mktap, twisted/internet/app.py:
-
- AOT (Abstract Object Tree) experimental source-persistence
- mechanism. This is a more-concise, easier-to-edit alternative to
- Twisted's XML persistence, for people who know how to edit Python
- code. Also added appropriate options to mktap and twistd to
- load/save .tas (Twisted Application Source) files.
-
- I will be working on making the formatting better, soon, but it's
- workable for now.
-
-2002-06-08 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted.internet, twisted.tap.web: Add a --https and related
- options to 'mktap web'; web is now much more SSL-friendly.
-
-
-2002-06-02 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted.internet: changed protocol factory interface - it now has
- doStop and doStart which are called in reactors, not app.Application.
- This turns start/stopFactory into an implementation-specific feature,
- and also ensures they are only called once.
-
-2002-06-01 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 0.18.0
-
-2002-05-31 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/coil/plugins/portforward.py, twisted/tap/portforward.py:
- Forgot to add these before rc1 :-) You can use the portforwarder
- with Coil and mktap again (previously "stupidproxy")
-
- * twisted/web/static.py: Fixed a bunch of bugs related to redirection
- for directories.
-
- * .: Releasing Twisted 0.18.0rc2
-
-2002-05-30 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * Twisted no longer barfs when the Python XML packages aren't available.
-
-2002-05-29 Christopher Armstrong <radix@twistedmatrix.com>
-
- * .: Releasing Twisted 0.18.0rc1
-
-2002-05-25 Christopher Armstrong <radix@twistedmatrix.com>
-
- * twisted/spread/pb.py, twisted/internet/defer.py,
- twisted/python/failure.py, etc:
-
- Perspective broker now supports Failures! This should make writing
- robust PB clients *much* easier. What this means is that errbacks will
- recieve instances of t.python.failure.Failure instead of just strings
- containing the traceback -- so you can easily .trap() particular
- errors and handle them appropriately.
-
-2002-05-24 Itamar Shtull-Trauring, Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted.mail cleanups:
-
- * basic bounce support.
-
- * removed telnet from mail tap
-
- * mail domains now receive service in __init__
-
- * split file system stuff into Queue (renamed from
- MessageCollection)
-
- * Put a Queue in service
-
- * twisted/protocol/smtp.py: changed SMTPClient API so that it returns
- a file for the message content, instead of a string.
-
-2002-05-23 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * Twisted applications can now be persisted to XML files (.tax) with
- the --xml option -- this is pretty verbose and needs some optimizations.
-
-2002-05-22 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/persisted/marmalade.py: Marmalade: Jelly, with just a hint
- of bitterness. An XML object serialization module designed so
- people can hand-edit persisted objects (like Twisted Applications).
-
-2002-05-21 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/internet/gtkreactor.py: GTK+ support for win32; input_add
- is not supported in win32 and had to be worked around.
-
-2002-05-20 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/pythor/defer.py, twisted/protocols/protocol.py,
- twisted/internet/defer.py, twisted/internet/protocol.py:
-
- Moved defer and protocol to twisted.internet to straighten
- out dependancies.
-
-2002-05-18 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/metrics, twisted/forum: Metrics and Forum are no longer
- a part of Twisted proper; They are now in different CVS modules, and
- will be released separately.
-
-2002-05-15 Andrew Bennetts <andrew-twisted@puzzling.org>
-
- * twisted/protocols/ftp.py: Small fixes to FTPClient that have
- changed the interface slightly -- return values from callbacks
- are now consistent for active and passive FTP. Have a look at
- doc/examples/ftpclient.py for details.
-
-2002-05-12 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * doc/specifications/banana.html: Documentation of the Banana protocol.
-
-2002-05-06 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/im/gtkchat.py: Some more UI improvements to InstanceMessenger:
- Nicks are now colorful (each nick is hashed to get a color) and
- messages now have timestamps.
-
-2002-05-04 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * Reactor Refactor! Pretty much all of the twisted.internet.* classes
- are being depracated in favor of a single, central class called the
- "reactor". Interfaces are defined in twisted.internet.interfaces.
- For a much more descriptive comment about this change, see
- http://twistedmatrix.com/pipermail/twisted-commits/2002-May/002104.html.
-
-2002-05-04 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/spread/pb.py: There is now some resource limiting in PB.
- Clients can now have the number of references to an object limited.
-
-2002-04-29 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/im/*: Refactored Twisted InstanceMessenger to seperate GUI
- and logic. Also improved the UI a bit.
-
-2002-04-28 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/protocols/http.py: log hits using extended log format
- and make web taps logfile configurable.
-
-2002-04-26 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/lumberjack/logfile.py: reversed order of rotated
- logs - higer numbers are now older.
-
-2002-04-24 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * doc/examples/ircLogBot.py: We now have a sample IRC bot that logs
- all messages to a file.
-
-2002-04-24 Itamar Shtull-Trauring <twisted@itamarst.org>
-
- * twisted/python/components.py: Twisted's interfaces are now
- more like Zope's - __implements__ is an Interface subclass
- or a tuple (or tuple of tuples). Additonally, an instance can
- implement an interface even if its class doesn't have an
- __implements__.
-
-2002-04-22 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/python/usage.py: Minor niceties for usage.Options:
- You can now look up the options of an Options object with
- optObj['optName'], and you if you define opt_* methods with
- underscores in them, using dashes on the command line will work.
-
-2002-04-21 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/scripts/mktap.py: No more --manhole* options, use
- '--append=my.tap manhole' now.
-
-2002-04-20 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.17.4.
-
- * twisted/internet/tcp.py: Make unix domain sockets *really*
- world-accessible, rather than just accessible by "other".
-
-2002-04-19 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/web/{server,twcgi}.py: Fixed POST bug in distributed
- web servers.
-
-2002-04-19 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.17.3.
-
-2002-04-19 Glyph Lefkowitz <carmstro@twistedmatrix.com>
-
- * twisted/web/distrib.py: Fix a bug where static.File transfers
- over a distributed-web connection would not finish up properly.
-
-2002-04-18 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.17.2.
-
-2002-04-18 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/news: A news server and NNTP protocol support courtesy of
- exarkun. Another step towards Twisted implementations of EVERYTHING
- IN THE WORLD!
-
-2002-04-17 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/spread/pb.py: Errors during jelly serialization used to
- just blow up; now they more properly return a Deferred Failure. This
- will make hangs in PB apps (most notably distributed web) less common.
-
-2002-04-17 Donovan Preston <dp@twistedmatrix.com>
-
- * Major changes to the capabilities of the static web server, in an
- attempt to be able to use Twisted instead of Zope at work; my plan is to
- capture many of the conveniences of Zope without the implicitness and
- complexity that comes with working around implicit behavior when it fails.
-
- 1) .trp and .rpy support in the static web server:
- Very simple handlers to allow you to easily add Resource objects
- dynamically to a running server, by merely changing files on the
- filesystem.
- An .rpy file will be executed, and if a "resource" variable exists upon the
- execution's completion, it will be returned.
- A .trp file (twisted resource pickle) will be unpickled and returned. An
- object unpickled from a .trp should either implement IResource itself,
- or have a registered adapter in twisted.python.components.
-
- 2) Acquisition:
- As resources are being looked up by repeated calls to getChild, this
- change creates instances of
- twisted.spread.refpath.PathReferenceAcquisitionContext and puts
- them in the request as "request.pathRef"
- Any method that has an instance of the request can then climb up
- the parent tree using "request.pathRef['parentRef']['parentRef']
- PathReferenceAcquisitionContext instances can be dereferenced to the
- actual object using getObject
- Convenience method: "locate" returns a PathReference to first place
- in the parent heirarchy a name is seen
- Convenience method: "acquire" somewhat like Zope acquisition;
- mostly untested, may need fixes
-
- 3) DOM-based templating system:
- A new templating system that allows python scripts to use the DOM
- to manipulate the HTML node tree. Loosely based on Enhydra.
- Subclasses of twisted.web.domtemplate.DOMTemplate can override
- the templateFile attribute and the getTemplateMethods method;
- ultimately, while templateFile is being parsed, the methods
- specified will be called with instances of xml.dom.mindom.Node
- as the first parameter, allowing the python code to manipulate
- (see twisted.web.blog for an example)
-
-2002-04-17 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/web/static.py, twisted/tap/web.py: Added a new feature
- that allows requests for /foo to return /foo.extension, which is
- disabled by default. If you want a --static webserver that
- uses this feature, use 'mktap web --static <dir> --allow_ignore_ext'.
-
- * twisted/tap/web.py: Also switched --static to --path; it doesn't
- make sense to call something that automatically executes cgis, epys,
- rpys, php, etc., "static". :-)
-
-2002-04-14 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * HTTP 1.1 now supports persistent and pipelined connections.
-
- User-visible API changes:
- - Request.content is now a file-like object, instead of a string.
- - Functions that incorrectly used Request.received instead of
- Request.getAllHeaders() will break.
- - sendHeader, finishHeaders, sendStatus are all hidden now.
-
-2002-04-12 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/coil/plugins/tendril.py (TendrilConfigurator): New coil
- configurator for words.tendril.
-
-2002-04-10 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.17.0
-
-2002-04-10 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/bugs: Gone. Separate plugin package.
- * twisted/eco: Gone. The king is dead. Long live the king!
- (eco is no longer going to be developed, Pyrex has obviated it.)
-
-2002-04-10 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/protocols/irc.py: Some fix-ups to IRCClient and
- DccFileReceive, from Joe Jordan (psy).
-
-2002-04-10 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/reality: Gone. This is now in a completely separate plugin
- package.
-
-2002-04-09 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * win32 process support seems to *finally* be working correctly. Many
- thanks to Drew Whitehouse for help with testing and debugging.
-
-2002-04-08 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * coil refactored yet again, this time to use components and adapters.
- The design is now much cleaner.
-
-2002-04-08 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * twisted/spread/jelly.py: Refactored jelly to provide (a) more
- sane, language-portable API for efficient extensibility and (b)
- final version of "wire" protocol. This should be very close to
- the last wire-protocol-breaking change to PB before
- standardization happens.
-
-2002-04-04 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * Removed __getattr__ backwards compatibility in PB
-
-2002-04-03 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/python/usage.py, twisted/test/test_usage.py, bin/mktap, twisted/tap/*.py:
- Made the usage.Options interface better -- options are now stored in the
- 'opts' dict. This is backwards compatible, and I added a deprecation warning.
-
-2002-04-01 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.16.0.
-
-2002-03-29 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * Added Qt event loop support, written by Sirtaj Singh Kang and
- Aleksandar Erkalovic.
-
-2002-03-29 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * Added a 'coil' command for configuring TAP files
-
-2002-03-15 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * XML-RPC published methods can now return Deferreds, and Twisted
- will Do The Right Thing.
-
-2002-03-13 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * Refactored coil, the configuration mechanism for Twisted.
- See twisted.coil and twisted.coil.plugins for examples of how
- to use the new interface. Chris Armstrong did some UI improvements
- for coil as well.
-
- * Checked in win32 Process support, and fixed win32 event loop.
-
-2002-03-11 Glyph Lefkowitz <glyph@janus.twistedmatrix.com>
-
- * More robust shutdown sequence for default mainloop (other
- mainloops should follow suit, but they didn't implement shutdown
- callbacks properly before anyway...). This allows for shutdown
- callbacks to continue using the main loop.
-
-2002-03-09 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * Automatic log rotation for twistd. In addition, sending SIGUSR1
- to twistd will rotate the log.
-
-2002-03-07 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.15.5.
-
-2002-03-06 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * twisted/web/html.py: Got rid of html.Interface. This was a really
- old, really deprecated API.
-
-2002-03-06 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/web/widgets.py: Deprecated usage of Gadget.addFile(path)
- and replaced it with Gadget.putPath(path, pathname). This is
- a lot more flexible.
-
-2002-03-05 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/internet/win32.py: New win32 event loop, written by
- Andrew Bennetts.
-
- * twisted/tap/*: Changed the interface for creating tap modules - use
- a method called updateApplication instead of getPorts. this
- is a much more generic and useful mechanism.
-
- * twisted/internet/task.py: Fixed a bug where the schedular wasn't
- installed in some cases.
-
-2002-03-04 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/web/server.py: authorizer.Unauthorized->util.Unauthorized
- (leftovers from removing .passport references.)
-
- * twisted/names/dns.py: Added support for TTL.
-
-2002-03-02 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.15.4.
-
-2002-03-02 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/words/ircservice.py: Send End-Of-MOTD message --
- some clients rely on this for automatic joining of channels
- and whatnot.
-
-2002-03-02 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/names/dns.py: Fixed bugs in DNS client
-
-2002-03-01 Moshe Zadka <moshez@twistedmatrix.com>
-
- * twisted/protocols/dns.py: Can now correctly serialize answers
-
- * twisted/names/dns.py: Can now do simple serving of domains
-
- * twisted/internet/stupid.py: Removed spurious debugging print
-
-2002-02-28 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing 0.15.3.
-
-2002-02-27 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/mail/*, twisted/plugins.tml: The Mail server is now
- COILable.
-
- * bin/twistd: security fix: use a secure umask (077, rather than 0)
- for twistd.pid.
-
-2002-02-26 Allen Short <washort@twistedmatrix.com>
-
- * twisted/eco/eco.py, twisted/eco/sexpy.py: ECO now supports
- backquoting and macros.
-
-2002-02-26 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/protocols/ftp.py, twisted/plugins.tml: Made the FTP
- server COILable!
-
-2002-02-26 Benjamin Bruheim <phed@twistedmatrix.com>
-
- * twisted/web/distrib.py: Fixed a win32-compatibility bug.
-
-2002-02-24 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/protocols/socks.py: Made SOCKSv4 coilable, and fixed a
- bug so it'd work with Mozilla.
-
-2002-02-24 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * .: Releasing Twisted 0.15.2.
-
-2002-02-24 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * setup.py: Added plugins.tml and instancemessenger.glade installs
- so mktap and t-im work in a 'setup.py install' install.
-
- * debian/rules: Install plugins.tml so mktap works in debian installs.
-
- * doc/man/mktap.1, twistd.1: Updated the man pages to be more accurate.
-
-2002-02-24 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * bin/mktap: Better error reporting when we don't find
- the plugins files.
-
- * bin/twistd: Print out the *real* usage description rather than
- barfing when we get bad command line arguments.
-
-2002-02-24 Moshe Zadka <moshez@twistedmatrix.com>
-
- * debian/rules: Install the instancemessenger.glade file, so IM
- will work in debian installs.
-
-2002-02-24 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/protocols/oscar.py, socks.py, toc.py: Fixed a security
- hole in TOC where clients could call any method on the server.
-
-2002-02-23 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/tap/coil.py: There is now a tap-creator for COIL.
-
- * twisted/internet/stupidproxy.py: Now with COILability!
-
-2002-02-23 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * bin/mktap: mktap now uses Plugins instead of searching through
- twisted.tap. Yay for unified configuration systems!
-
-
-2002-02-22 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/im, twisted/words: t-im can now do topic setting (words
- only), fixed the Group Metadata-setting interface in the service.
-
-2002-02-22 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * twisted/manhole: COIL can now load Plugins.
-
-2002-02-21 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * twisted.spread.pb: Changed remote method invocations to be
- called through .callRemote rather than implicitly by getattr, and
- added LocalAsRemote utility class for emulating remote behavior.
-
-2002-02-21 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted.protocols.ftp: Fixed a lot of serious bugs.
-
-2002-02-20 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted.protocols.telnet: the python shell now supports
- multi-line commands and can be configured using coil.
-
-2002-02-13 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted.lumberjack: a log rotation and viewing service.
- Currently only log rotation is supported.
-
-2002-02-12 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/words/ircservice.py (IRCChatter.irc_AWAY): Fix bug
- where you can never come back from being away (at least using
- epic4). Closes: #%d
-
-2002-02-11 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/web/widgets.py: Changed Gadget.page to Gadget.pageFactory
- for clarity (this is backwards-compatible).
-
-2002-02-10 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/spread/jelly.py:
- * twisted/spread/banana.py:
- * twisted/spread/pb.py: fixed bugs found by pychecker, got rid
- of __ping__ method support, and added 'local_' methods to
- RemoteReference
-
- * twisted/persisted/styles.py: pychecker bug fixes
-
-2002-02-09 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * bin/eco: Created a command-line interpreter for ECO.
-
- * doc/man/eco.1: man page for bin/eco
-
-2002-02-09 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/eco/eco.py: Reverted evaluator state back to functional-ness
- :) And added functions (anonymous and global), and broke various
- interfaces
-
-2002-02-09 Allen Short <washort@twistedmatrix.com>
-
- * twisted/eco/eco.py: Refactored evaluator into a class, improved
- python-function argument signatures, and added and/or/not functions.
-
-2002-02-08 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/words/service.py, ircservice.py: Fixed annoying PING
- bug, and added /topic support.
-
-2002-02-08 Glyph Lefkowitz <glyph@twistedmatrix.com>
-
- * twisted/eco: Initial prototype of ECO, the Elegant C Overlay
- macro engine.
-
-2002-02-02 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/im/ircsupport.py: Added support for the IRC protocol
- to IM.
-
-2002-02-02 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/python/deferred.py: added Deferred.addErrback, so now
- it's easy to attach errbacks to deferreds when you don't care
- about plain results.
-
- * twisted/im/chat.py, twisted/im/pbsupport.py: added support for
- displaying topics.
-
-2002-02-02 Paul Swartz <z3p@twistedmatrix.com>
-
- * SOCKSv4 support: there is now a protocols.socks, which contains
- support for SOCKSv4, a TCP proxying protocol. mktap also has
- support for the new protocol.
-
-2002-02-02 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/words/ircservice.py (IRCChatter.receiveDirectMessage),
- (IRCChatter.receiveGroupMessage),
- (IRCChatter.irc_PRIVMSG): Added CTCP ACTION <-> emote translation
-
-2002-02-01 Paul Swartz <z3p@twistedmatrix.com>
-
- * twisted/im/tocsupport.py: Added support for most of the TOC
- protocol to IM.
-
-
-2002-02-01 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/im/*.py: added metadata/emote support to IM. "/me foo"
- now triggers a backwards-compatible emote.
-
-
-2002-01-30 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * twisted/internet/tcp.py: Fixed the bug where startFactory() would
- get called twice.
-
-2002-01-30 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/im: a new client for twisted.words (and eventually
- much more) based on GTK+ and Glade. This is mainly glyph's
- code, but I organized it for him to check in.
-
- * twisted/words/service.py: metadata support for words messages
- (only {'style': 'emote'} is standardized as of yet)
-
-2002-01-29 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * Added hook to tcp.Port and ssl.Port for limiting acceptable
- connections - approveConnection(socket, addr).
-
-2002-01-27 Chris Armstrong <carmstro@twistedmatrix.com>
-
- * twisted/words/ircservice.py: You can now change the topic
- of a channel with '/msg channelName topic <topic>' - note that
- 'channelName' does *not* include the '#'.
-
-2002-01-23 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * Incompatible change to PB: all remote methods now return
- Deferreds. This doesn't break code in as many places as possible,
- but the connection methods now work differently and have different
- signatures.
-
- * Incompatible change to Banana: Banana now really supports floats
- and long integers. This involved removing some nasty hackery that
- was previously part of the protocol spec, so you'll need to
- upgrade.
-
- * Added a feature to Jelly: Jelly now supports unicode strings.
-
- * Improved Twisted.Forums considerably: still needs work, but it's
- growing into an example of what you can do with a Twisted.Web
- application.
-
- * Added Twisted.Web.Webpassport -- generic mechanism for web-based
- login to arbitrary services. This in conjunction with some code
- in Forum that uses it.
-
- * Incompatible change in Enterprise: all query methods now return
- Deferreds, as well as take arguments in an order which makes it
- possible to pass arbitrary argument lists for using the database's
- formatting characters rather than python's.
-
-2002-01-15 Glyph Lefkowitz <glyph@zelda.twistedmatrix.com>
-
- * twisted/internet/passport.py: (and friends) Retrieval of
- perspectives is now asynchronous, hooray (this took way too long)!
- Perspectives may now be stored in external data sources. Lurching
- slowly towards a stable API for the Passport system, along with
- Sean's recent commits of tools to manipulate it.
-
-2002-01-14 Kevin Turner <acapnotic@twistedmatrix.com>
-
- * twisted/python/explorer.py: reimplementated. So it's better.
- And yes, I broke the API.
-
- * twisted/manhole/ui/spelunk_gnome.py: Less duplication of visages,
- and they're draggable now too.
-
-2002-01-13 Itamar Shtull-Trauring <itamarst@twistedmatrix.com>
-
- * Changed twisted.enterprise.adabi so operations can accept lists
- of arguments. This allows us to use the database adaptor's native
- SQL quoting ability instead of either doing it ourselves, or the
- *current* way twisted does it (not doing it at all, AFAICT!).
-
- cursor.execute("INSERT INTO foo VALUES (%s, %d), "it's magic", 12)
-
- Problem is that different adaptors may have different codes for
- quoting.
-
- * First go at database for twisted.bugs. I hate RDBMS. I hate web.
-
---- 0.13.0 Release ---
-
-# Local Variables:
-# add-log-time-format: add-log-iso8601-time-string
-# End:
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/NEWS
deleted file mode 100644
index e0f7e219..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/NEWS
+++ /dev/null
@@ -1,1809 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Core 12.2.0 (2012-08-26)
-================================
-
-Features
---------
- - twisted.protocols.sip.MessageParser now handles multiline headers.
- (#2198)
- - twisted.internet.endpoints now provides StandardIOEndpoint, a
- Standard I/O endpoint. (#4697)
- - If a FTPCmdError occurs during twisted.protocols.ftp.FTP.ftp_RETR
- sending the file (i.e. it is raised by the IReadFile.send method it
- invokes), then it will use that to return an error to the client
- rather than necessarily sending a 426 CNX_CLOSED_TXFR_ABORTED
- error. (#4913)
- - twisted.internet.interfaces.IReactorSocket.adoptStreamConnection is
- implemented by some reactors as a way to add an existing
- established connection to them. (#5570)
- - twisted.internet.endpoints now provides TCP6ServerEndpoint, an IPv6
- TCP server endpoint. (#5694)
- - twisted.internet.endpoints now provides TCP6ClientEndpoint, an IPv6
- TCP client endpoint. (#5695)
- - twisted.internet.endpoints.serverFromString, the endpoint string
- description feature, can now be used to create IPv6 TCP servers.
- (#5699)
- - twisted.internet.endpoints.serverFromString, the endpoint string
- description feature, can now be used to create servers that run on
- Standard I/O. (#5729)
- - twisted.trial.unittest now offers SynchronousTestCase, a test case
- base class that provides usability improvements but not reactor-
- based testing features. (#5853)
-
-Bugfixes
---------
- - twisted.internet.Process.signalProcess now catches ESRCH raised by
- os.kill call and raises ProcessExitedAlready instead. (#2420)
- - TLSMemoryBIOProtocol (and therefore all SSL transports if pyOpenSSL
- >= 0.10) now provides the interfaces already provided by the
- underlying transport. (#5182)
-
-Deprecations and Removals
--------------------------
- - Python 2.5 is no longer supported. (#5553)
- - The --extra option of trial, deprecated since 11.0, is removed now.
- (#3374)
- - addPluginDir and getPluginDirs in twisted.python.util are
- deprecated now. (#4533)
- - twisted.trial.runner.DocTestCase, deprecated in Twisted 8.0, has
- been removed. (#5554)
- - startKeepingErrors, flushErrors, ignoreErrors, and clearIgnores in
- twisted.python.log (deprecated since Twisted 2.5) are removed now.
- (#5765)
- - unzip, unzipIter, and countZipFileEntries in
- twisted.python.zipstream (deprecated in Twisted 11.0) are removed
- now. (#5766)
- - twisted.test.time_helpers, deprecated since Twisted 10.0, has been
- removed. (#5820)
-
-Other
------
- - #4244, #4532, #4930, #4999, #5129, #5138, #5385, #5521, #5655,
- #5674, #5679, #5687, #5688, #5689, #5692, #5707, #5734, #5736,
- #5745, #5746, #5747, #5749, #5784, #5816, #5817, #5818, #5819,
- #5830, #5857, #5858, #5859, #5869, #5632
-
-
-Twisted Core 12.1.0 (2012-06-02)
-================================
-
-Features
---------
- - The kqueue reactor has been revived. (#1918)
- - twisted.python.filepath now provides IFilePath, an interface for
- file path objects. (#2176)
- - New gtk3 and gobject-introspection reactors have been added.
- (#4558)
- - gtk and glib reactors now run I/O and scheduled events with lower
- priority, to ensure the UI stays responsive. (#5067)
- - IReactorTCP.connectTCP() can now accept IPv6 address literals
- (although not hostnames) in order to support connecting to IPv6
- hosts. (#5085)
- - twisted.internet.interfaces.IReactorSocket, a new interface, is now
- supported by some reactors to listen on sockets set up by external
- software (eg systemd or launchd). (#5248)
- - twisted.internet.endpoints.clientFromString now also supports
- strings in the form of tcp:example.com:80 and ssl:example.com:4321
- (#5358)
- - twisted.python.constants.Flags now provides a way to define
- collections of flags for bitvector-type uses. (#5384)
- - The epoll(7)-based reactor is now the default reactor on Linux.
- (#5478)
- - twisted.python.runtime.platform.isLinux can be used to check if
- Twisted is running on Linux. (#5491)
- - twisted.internet.endpoints.serverFromString now recognizes a
- "systemd" endpoint type, for listening on a server port inherited
- from systemd. (#5575)
- - Connections created using twisted.internet.interfaces.IReactorUNIX
- now support sending and receiving file descriptors between
- different processes. (#5615)
- - twisted.internet.endpoints.clientFromString now supports UNIX
- client endpoint strings with the path argument specified like
- "unix:/foo/bar" in addition to the old style, "unix:path=/foo/bar".
- (#5640)
- - twisted.protocols.amp.Descriptor is a new AMP argument type which
- supports passing file descriptors as AMP command arguments over
- UNIX connections. (#5650)
-
-Bugfixes
---------
- - twisted.internet.abstract.FileDescriptor implements
- twisted.internet.interfaces.IPushProducer instead of
- twisted.internet.interfaces.IProducer.
- twisted.internet.iocpreactor.abstract.FileHandle implements
- twisted.internet.interfaces.IPushProducer instead of
- twisted.internet.interfaces.IProducer. (#4386)
- - The epoll reactor now supports reading/writing to regular files on
- stdin/stdout. (#4429)
- - Calling .cancel() on any Twisted-provided client endpoint
- (TCP4ClientEndpoint, UNIXClientEndpoint, SSL4ClientEndpoint) now
- works as documented, rather than logging an AlreadyCalledError.
- (#4710)
- - A leak of OVERLAPPED structures in some IOCP error cases has been
- fixed. (#5372)
- - twisted.internet._pollingfile._PollableWritePipe now checks for
- outgoing unicode data in write() and writeSequence() instead of
- checkWork(). (#5412)
-
-Improved Documentation
-----------------------
- - "Working from Twisted's Subversion repository" links to UQDS and
- Combinator are now updated. (#5545)
- - Added tkinterdemo.py, an example of Tkinter integration. (#5631)
-
-Deprecations and Removals
--------------------------
- - The 'unsigned' flag to twisted.scripts.tap2rpm.MyOptions is now
- deprecated. (#4086)
- - Removed the unreachable _fileUrandom method from
- twisted.python.randbytes.RandomFactory. (#4530)
- - twisted.persisted.journal is removed, deprecated since Twisted
- 11.0. (#4805)
- - Support for pyOpenSSL 0.9 and older is now deprecated. pyOpenSSL
- 0.10 or newer will soon be required in order to use Twisted's SSL
- features. (#4974)
- - backwardsCompatImplements and fixClassImplements are removed from
- twisted.python.components, deprecated in 2006. (#5034)
- - twisted.python.reflect.macro was removed, deprecated since Twisted
- 8.2. (#5035)
- - twisted.python.text.docstringLStrip, deprecated since Twisted
- 10.2.0, has been removed (#5036)
- - Removed the deprecated dispatch and dispatchWithCallback methods
- from twisted.python.threadpool.ThreadPool (deprecated since 8.0)
- (#5037)
- - twisted.scripts.tapconvert is now deprecated. (#5038)
- - twisted.python.reflect's Settable, AccessorType, PropertyAccessor,
- Accessor, OriginalAccessor and Summer are now deprecated. (#5451)
- - twisted.python.threadpool.ThreadSafeList (deprecated in 10.1) is
- removed. (#5473)
- - twisted.application.app.initialLog, deprecated since Twisted 8.2.0,
- has been removed. (#5480)
- - twisted.spread.refpath was deleted, deprecated since Twisted 9.0.
- (#5482)
- - twisted.python.otp, deprecated since 9.0, is removed. (#5493)
- - Removed `dsu`, `moduleMovedForSplit`, and `dict` from
- twisted.python.util (deprecated since 10.2) (#5516)
-
-Other
------
- - #2723, #3114, #3398, #4388, #4489, #5055, #5116, #5242, #5380,
- #5392, #5447, #5457, #5484, #5489, #5492, #5494, #5512, #5523,
- #5558, #5572, #5583, #5593, #5620, #5621, #5623, #5625, #5637,
- #5652, #5653, #5656, #5657, #5660, #5673
-
-
-Twisted Core 12.0.0 (2012-02-10)
-================================
-
-Features
---------
- - The interface argument to IReactorTCP.listenTCP may now be an IPv6
- address literal, allowing the creation of IPv6 TCP servers. (#5084)
- - twisted.python.constants.Names now provides a way to define
- collections of named constants, similar to the "enum type" feature
- of C or Java. (#5382)
- - twisted.python.constants.Values now provides a way to define
- collections of named constants with arbitrary values. (#5383)
-
-Bugfixes
---------
- - Fixed an obscure case where connectionLost wasn't called on the
- protocol when using half-close. (#3037)
- - UDP ports handle socket errors better on Windows. (#3396)
- - When idle, the gtk2 and glib2 reactors no longer wake up 10 times a
- second. (#4376)
- - Prevent a rare situation involving TLS transports, where a producer
- may be erroneously left unpaused. (#5347)
- - twisted.internet.iocpreactor.iocpsupport now has fewer 64-bit
- compile warnings. (#5373)
- - The GTK2 reactor is now more responsive on Windows. (#5396)
- - TLS transports now correctly handle producer registration after the
- connection has been lost. (#5439)
- - twisted.protocols.htb.Bucket now empties properly with a non-zero
- drip rate. (#5448)
- - IReactorSSL and ITCPTransport.startTLS now synchronously propagate
- errors from the getContext method of context factories, instead of
- being capturing them and logging them as unhandled. (#5449)
-
-Improved Documentation
-----------------------
- - The multicast documentation has been expanded. (#4262)
- - twisted.internet.defer.Deferred now documents more return values.
- (#5399)
- - Show a better starting page at
- http://twistedmatrix.com/documents/current (#5429)
-
-Deprecations and Removals
--------------------------
- - Remove the deprecated module twisted.enterprise.reflector. (#4108)
- - Removed the deprecated module twisted.enterprise.row. (#4109)
- - Remove the deprecated module twisted.enterprise.sqlreflector.
- (#4110)
- - Removed the deprecated module twisted.enterprise.util, as well as
- twisted.enterprise.adbapi.safe. (#4111)
- - Python 2.4 is no longer supported on any platform. (#5060)
- - Removed printTraceback and noOperation from twisted.spread.pb,
- deprecated since Twisted 8.2. (#5370)
-
-Other
------
- - #1712, #2725, #5284, #5325, #5331, #5362, #5364, #5371, #5407,
- #5427, #5430, #5431, #5440, #5441
-
-
-Twisted Core 11.1.0 (2011-11-15)
-================================
-
-Features
---------
- - TCP and TLS transports now support abortConnection() which, unlike
- loseConnection(), always closes the connection immediately. (#78)
- - Failures received over PB when tracebacks are disabled now display
- the wrapped exception value when they are printed. (#581)
- - twistd now has a --logger option, allowing the use of custom log
- observers. (#638)
- - The default reactor is now poll(2) on platforms that support it.
- (#2234)
- - twisted.internet.defer.inlineCallbacks(f) now raises TypeError when
- f returns something other than a generator or uses returnValue as a
- non-generator. (#2501)
- - twisted.python.usage.Options now supports performing Zsh tab-
- completion on demand. Tab-completion for Twisted commands is
- supported out-of-the-box on any recent zsh release. Third-party
- commands may take advantage of zsh completion by copying the
- provided stub file. (#3078)
- - twisted.protocols.portforward now uses flow control between its
- client and server connections to avoid having to buffer an
- unbounded amount of data when one connection is slower than the
- other. (#3350)
- - On Windows, the select, IOCP, and Gtk2 reactors now implement
- IReactorWin32Events (most notably adding support for serial ports
- to these reactors). (#4862)
- - twisted.python.failure.Failure no longer captures the state of
- locals and globals of all stack frames by default, because it is
- expensive to do and rarely used. You can pass captureVars=True to
- Failure's constructor if you want to capture this data. (#5011)
- - twisted.web.client now supports automatic content-decoding via
- twisted.web.client.ContentDecoderAgent, gzip being supported for
- now. (#5053)
- - Protocols may now implement ILoggingContext to customize their
- logging prefix. twisted.protocols.policies.ProtocolWrapper and the
- endpoints wrapper now take advantage of this feature to ensure the
- application protocol is still reflected in logs. (#5062)
- - AMP's raw message-parsing performance was increased by
- approximately 12%. (#5075)
- - Twisted is now installable on PyPy, because some incompatible C
- extensions are no longer built. (#5158)
- - twisted.internet.defer.gatherResults now accepts a consumeErrors
- parameter, with the same meaning as the corresponding argument for
- DeferredList. (#5159)
- - Added RMD (remove directory) support to the FTP client. (#5259)
- - Server factories may now implement ILoggingContext to customize the
- name that is logged when the reactor uses one to start listening on
- a port. (#5292)
- - The implementations of ITransport.writeSequence will now raise
- TypeError if passed unicode strings. (#3896)
- - iocp reactor now operates correctly on 64 bit Python runtimes.
- (#4669)
- - twistd ftp now supports the cred plugin. (#4752)
- - twisted.python.filepath.FilePath now has an API to retrieve the
- permissions of the underlying file, and two methods to determine
- whether it is a block device or a socket. (#4813)
- - twisted.trial.unittest.TestCase is now compatible with Python 2.7's
- assertDictEqual method. (#5291)
-
-Bugfixes
---------
- - The IOCP reactor now does not try to erroneously pause non-
- streaming producers. (#745)
- - Unicode print statements no longer blow up when using Twisted's
- logging system. (#1990)
- - Process transports on Windows now support the `writeToChild` method
- (but only for stdin). (#2838)
- - Zsh tab-completion of Twisted commands no longer relies on
- statically generated files, but instead generates results on-the-
- fly - ensuring accurate tab-completion for the version of Twisted
- actually in use. (#3078)
- - LogPublishers don't use the global log publisher for reporting
- broken observers anymore. (#3307)
- - trial and twistd now add the current directory to sys.path even
- when running as root or on Windows. mktap, tapconvert, and
- pyhtmlizer no longer add the current directory to sys.path. (#3526)
- - twisted.internet.win32eventreactor now stops immediately if
- reactor.stop() is called from an IWriteDescriptor.doWrite
- implementation instead of delaying shutdown for an arbitrary period
- of time. (#3824)
- - twisted.python.log now handles RuntimeErrors more gracefully, and
- always restores log observers after an exception is raised. (#4379)
- - twisted.spread now supports updating new-style RemoteCache
- instances. (#4447)
- - twisted.spread.pb.CopiedFailure will no longer be thrown into a
- generator as a (deprecated) string exception but as a
- twisted.spread.pb.RemoteException. (#4520)
- - trial now gracefully handles the presence of objects in sys.modules
- which respond to attributes being set on them by modifying
- sys.modules. (#4748)
- - twisted.python.deprecate.deprecatedModuleAttribute no longer
- spuriously warns twice when used to deprecate a module within a
- package. This should make it easier to write unit tests for
- deprecated modules. (#4806)
- - When pyOpenSSL 0.10 or newer is available, SSL support now uses
- Twisted for all I/O and only relies on OpenSSL for cryptography,
- avoiding a number of tricky, potentially broken edge cases. (#4854)
- - IStreamClientEndpointStringParser.parseStreamClient now correctly
- describes how it will be called by clientFromString (#4956)
- - twisted.internet.defer.Deferreds are 10 times faster at handling
- exceptions raised from callbacks, except when setDebugging(True)
- has been called. (#5011)
- - twisted.python.filepath.FilePath.copyTo now raises OSError(ENOENT)
- if the source path being copied does not exist. (#5017)
- - twisted.python.modules now supports iterating over namespace
- packages without yielding duplicates. (#5030)
- - reactor.spawnProcess now uses the resource module to guess the
- maximum possible open file descriptor when /dev/fd exists but gives
- incorrect results. (#5052)
- - The memory BIO TLS/SSL implementation now supports producers
- correctly. (#5063)
- - twisted.spread.pb.Broker no longer creates an uncollectable
- reference cycle when the logout callback holds a reference to the
- client mind object. (#5079)
- - twisted.protocols.tls, and SSL/TLS support in general, now do clean
- TLS close alerts when disconnecting. (#5118)
- - twisted.persisted.styles no longer uses the deprecated allYourBase
- function (#5193)
- - Stream client endpoints now start (doStart) and stop (doStop) the
- factory passed to the connect method, instead of a different
- implementation-detail factory. (#5278)
- - SSL ports now consistently report themselves as SSL rather than TCP
- when logging their close message. (#5292)
- - Serial ports now deliver connectionLost to the protocol when
- closed. (#3690)
- - win32eventreactor now behaves better in certain rare cases in which
- it previously would have failed to deliver connection lost
- notification to a protocol. (#5233)
-
-Improved Documentation
-----------------------
- - Test driven development with Twisted and Trial is now documented in
- a how-to. (#2443)
- - A new howto-style document covering twisted.protocols.amp has been
- added. (#3476)
- - Added sample implementation of a Twisted push producer/consumer
- system. (#3835)
- - The "Deferred in Depth" tutorial now includes accurate output for
- the deferred_ex2.py example. (#3941)
- - The server howto now covers the Factory.buildProtocol method.
- (#4761)
- - The testing standard and the trial tutorial now recommend the
- `assertEqual` form of assertions rather than the `assertEquals` to
- coincide with the standard library unittest's preference. (#4989)
- - twisted.python.filepath.FilePath's methods now have more complete
- API documentation (docstrings). (#5027)
- - The Clients howto now uses buildProtocol more explicitly, hopefully
- making it easier to understand where Protocol instances come from.
- (#5044)
-
-Deprecations and Removals
--------------------------
- - twisted.internet.interfaces.IFinishableConsumer is now deprecated.
- (#2661)
- - twisted.python.zshcomp is now deprecated in favor of the tab-
- completion system in twisted.python.usage (#3078)
- - The unzip and unzipIter functions in twisted.python.zipstream are
- now deprecated. (#3666)
- - Options.optStrings, deprecated for 7 years, has been removed. Use
- Options.optParameters instead. (#4552)
- - Removed the deprecated twisted.python.dispatch module. (#5023)
- - Removed the twisted.runner.procutils module that was deprecated in
- Twisted 2.3. (#5049)
- - Removed twisted.trial.runner.DocTestSuite, deprecated in Twisted
- 8.0. (#5111)
- - twisted.scripts.tkunzip is now deprecated. (#5140)
- - Deprecated option --password-file in twistd ftp (#4752)
- - mktap, deprecated since Twisted 8.0, has been removed. (#5293)
-
-Other
------
- - #1946, #2562, #2674, #3074, #3077, #3776, #4227, #4539, #4587,
- #4619, #4624, #4629, #4683, #4690, #4702, #4778, #4944, #4945,
- #4949, #4952, #4957, #4979, #4980, #4987, #4990, #4994, #4995,
- #4997, #5003, #5008, #5009, #5012, #5019, #5042, #5046, #5051,
- #5065, #5083, #5088, #5089, #5090, #5101, #5108, #5109, #5112,
- #5114, #5125, #5128, #5131, #5136, #5139, #5144, #5146, #5147,
- #5156, #5160, #5165, #5191, #5205, #5215, #5217, #5218, #5223,
- #5243, #5244, #5250, #5254, #5261, #5266, #5273, #5299, #5301,
- #5302, #5304, #5308, #5311, #5321, #5322, #5327, #5328, #5332,
- #5336
-
-
-Twisted Core 11.0.0 (2011-04-01)
-================================
-
-Features
---------
- - The reactor is not restartable, but it would previously fail to
- complain. Now, when you restart an unrestartable reactor, you get
- an exception. (#2066)
- - twisted.plugin now only emits a short log message, rather than a
- full traceback, if there is a problem writing out the dropin cache
- file. (#2409)
- - Added a 'replacement' parameter to the
- 'twisted.python.deprecate.deprecated' decorator. This allows
- deprecations to unambiguously specify what they have been
- deprecated in favor of. (#3047)
- - Added access methods to FilePath for FilePath.statinfo's st_ino,
- st_dev, st_nlink, st_uid, and st_gid fields. This is in
- preparation for the deprecation of FilePath.statinfo. (#4712)
- - IPv4Address and UNIXAddress now have a __hash__ method. (#4783)
- - twisted.protocols.ftp.FTP.ftp_STOR now catches `FTPCmdError`s
- raised by the file writer, and returns the error back to the
- client. (#4909)
-
-Bugfixes
---------
- - twistd will no longer fail if a non-root user passes --uid 'myuid'
- as a command-line argument. Instead, it will emit an error message.
- (#3172)
- - IOCPReactor now sends immediate completions to the main loop
- (#3233)
- - trial can now load test methods from multiple classes, even if the
- methods all happen to be inherited from the same base class.
- (#3383)
- - twisted.web.server will now produce a correct Allow header when a
- particular render_FOO method is missing. (#3678)
- - HEAD requests made to resources whose HEAD handling defaults to
- calling render_GET now always receive a response with no body.
- (#3684)
- - trial now loads decorated test methods whether or not the decorator
- preserves the original method name. (#3909)
- - t.p.amp.AmpBox.serialize will now correctly consistently complain
- when being fed Unicode. (#3931)
- - twisted.internet.wxreactor now supports stopping more reliably.
- (#3948)
- - reactor.spawnProcess on Windows can now handle ASCII-encodable
- Unicode strings in the system environment (#3964)
- - When C-extensions are not complied for twisted, on python2.4, skip
- a test in twisted.internet.test.test_process that may hang due to a
- SIGCHLD related problem. Running 'python setup.py build_ext
- --inplace' will compile the extension and cause the test to both
- run and pass. (#4331)
- - twisted.python.logfile.LogFile now raises a descriptive exception
- when passed a log directoy which does not exist. (#4701)
- - Fixed a bug where Inotify will fail to add a filepatch to watchlist
- after it has been added/ignored previously. (#4708)
- - IPv4Address and UNIXAddress object comparison operators fixed
- (#4817)
- - twisted.internet.task.Clock now sorts the list of pending calls
- before and after processing each call (#4823)
- - ConnectionLost is now in twisted.internet.error.__all__ instead of
- twisted.words.protocols.jabber.xmlstream.__all__. (#4856)
- - twisted.internet.process now detects the most appropriate mechanism
- to use for detecting the open file descriptors on a system, getting
- Twisted working on FreeBSD even when fdescfs is not mounted.
- (#4881)
- - twisted.words.services referenced nonexistent
- twisted.words.protocols.irc.IRC_NOSUCHCHANNEL. This has been fixed.
- Related code has also received test cases. (#4915)
-
-Improved Documentation
-----------------------
- - The INSTALL file now lists all of Twisted's dependencies. (#967)
- - Added the stopService and startService methods to all finger
- example files. (#3375)
- - Missing reactor.run() calls were added in the UDP and client howto
- documents. (#3834)
- - The maxRetries attribute of
- twisted.internet.protocols.RetryingClientFactory now has API
- documentation. (#4618)
- - Lore docs pointed to a template that no longer existed, this has
- been fixed. (#4682)
- - The `servers` argument to `twisted.names.client.createResolver` now
- has more complete API documentation. (#4713)
- - Linked to the Twisted endpoints tutorial from the Twisted core
- howto list. (#4773)
- - The Endpoints howto now links to the API documentation. (#4774)
- - The Quotes howto is now more clear in its PYTHONPATH setup
- instructions. (#4785)
- - The API documentation for DeferredList's fireOnOneCallback
- parameter now gives the correct order of the elements of the result
- tuple. (#4882)
-
-Deprecations and Removals
--------------------------
- - returning a value other than None from IProtocol.dataReceived was
- deprecated (#2491)
- - Deprecated the --extra option in trial. (#3372)
- - twisted.protocols._c_urlarg has been removed. (#4162)
- - Remove the --report-profile option for twistd, deprecated since
- 2007. (#4236)
- - Deprecated twisted.persisted.journal. This library is no longer
- maintained. (#4298)
- - Removed twisted.protocols.loopback.loopback, which has been
- deprecated since Twisted 2.5. (#4547)
- - __getitem__ __getslice__ and __eq__ (tuple comparison, indexing)
- removed from twisted.internet.address.IPv4Address and
- twisted.internet.address.UNIXAddress classes UNIXAddress and
- IPv4Address properties _bwHack are now deprecated in
- twisted.internet.address (#4817)
- - twisted.python.reflect.allYourBase is now no longer used, replaced
- with inspect.getmro (#4928)
- - allYourBase and accumulateBases are now deprecated in favor of
- inspect.getmro. (#4946)
-
-Other
------
- - #555, #1982, #2618, #2665, #2666, #4035, #4247, #4567, #4636,
- #4717, #4733, #4750, #4821, #4842, #4846, #4853, #4857, #4858,
- #4863, #4864, #4865, #4866, #4867, #4868, #4869, #4870, #4871,
- #4872, #4873, #4874, #4875, #4876, #4877, #4878, #4879, #4905,
- #4906, #4908, #4934, #4955, #4960
-
-
-Twisted Core 10.2.0 (2010-11-29)
-================================
-
-Features
---------
- - twisted.internet.cfreactor has been significantly improved. It now
- runs, and passes, the test suite. Many, many bugs in it have been
- fixed, including several segfaults, as it now uses PyObjC and
- longer requires C code in Twisted. (#1833)
- - twisted.protocols.ftp.FTPRealm now accepts a parameter to override
- "/home" as the container for user directories. The new
- BaseFTPRealm class in the same module also allows easy
- implementation of custom user directory schemes. (#2179)
- - twisted.python.filepath.FilePath and twisted.python.zippath.ZipPath
- now have a descendant method to simplify code which calls the child
- method repeatedly. (#3169)
- - twisted.python.failure._Frame objects now support fake f_locals
- attribute. (#4045)
- - twisted.internet.endpoints now has 'serverFromString' and
- 'clientFromString' APIs for constructing endpoints from descriptive
- strings. (#4473)
- - The default trial reporter now combines reporting of tests with the
- same result to shorten its summary output. (#4487)
- - The new class twisted.protocols.ftp.SystemFTPRealm implements an
- FTP realm which uses system accounts to select home directories.
- (#4494)
- - twisted.internet.reactor.spawnProcess now wastes less time trying
- to close non-existent file descriptors on POSIX platforms. (#4522)
- - twisted.internet.win32eventreactor now declares that it implements
- a new twisted.internet.interfaces.IReactorWin32Events interface.
- (#4523)
- - twisted.application.service.IProcess now documents its attributes
- using zope.interface.Attribute. (#4534)
- - twisted.application.app.ReactorSelectionMixin now saves the value
- of the --reactor option in the "reactor" key of the options object.
- (#4563)
- - twisted.internet.endpoints.serverFromString and clientFromString,
- and therefore also twisted.application.strports.service, now
- support plugins, so third parties may implement their own endpoint
- types. (#4695)
-
-Bugfixes
---------
- - twisted.internet.defer.Deferred now handles chains iteratively
- instead of recursively, preventing RuntimeError due to excessive
- recursion when handling long Deferred chains. (#411)
- - twisted.internet.cfreactor now works with trial. (#2556)
- - twisted.enterprise.adbapi.ConnectionPool.close may now be called
- even if the connection pool has not yet been started. This will
- prevent the pool from ever starting. (#2680)
- - twisted.protocols.basic.NetstringReceiver raises
- NetstringParseErrors for invalid netstrings now. It handles empty
- netstrings ("0:,") correctly, and the performance for receiving
- netstrings has been improved. (#4378)
- - reactor.listenUDP now returns an object which declares that it
- implements IListeningPort. (#4462)
- - twisted.python.randbytes no longer uses PyCrypto as a secure random
- number source (since it is not one). (#4468)
- - twisted.internet.main.installReactor now blocks installation of
- another reactor when using python -O (#4476)
- - twisted.python.deprecate.deprecatedModuleAttribute now emits only
- one warning when used to deprecate a package attribute which is a
- module. (#4492)
- - The "brief" mode of twisted.python.failure.Failure.getTraceback now
- handles exceptions raised by the underlying exception's __str__
- method. (#4501)
- - twisted.words.xish.domish now correctly parses XML with namespaces
- which include whitespace. (#4503)
- - twisted.names.authority.FileAuthority now generates correct
- negative caching hints, marks its referral NS RRs as non-
- authoritative, and correctly generates referrals for ALL_RECORDS
- requests. (#4513)
- - twisted.internet.test.reactormixins.ReactorBuilder's attribute
- `requiredInterface` (which should an interface) is now
- `requiredInterfaces` (a list of interfaces) as originally described
- per the documentation. (#4527)
- - twisted.python.zippath.ZipPath.__repr__ now correctly formats paths
- with ".." in them (by including it). (#4535)
- - twisted.names.hosts.searchFileFor has been fixed against
- refcounting dependency. (#4540)
- - The POSIX process transports now declare that they implement
- IProcessTransport. (#4585)
- - Twisted can now be built with the LLVM clang compiler, with
- 'CC=clang python setup.py build'. C code that caused errors with
- this compiler has been removed. (#4652)
- - trial now puts coverage data in the path specified by --temp-
- directory, even if that option comes after --coverage on the
- command line. (#4657)
- - The unregisterProducer method of connection-oriented transports
- will now cause the connection to be closed if there was a prior
- call to loseConnection. (#4719)
- - Fixed an issue where the new StreamServerEndpointService didn't log
- listen errors. (This was a bug not present in any previous
- releases, as this class is new.) (#4731)
-
-Improved Documentation
-----------------------
- - The trial man page now documents the meaning of the final line of
- output of the default reporter. (#1384)
- - The API documentation for twisted.internet.defer.DeferredList now
- goes into more depth about the effects each of the __init__ flags
- that class accepts. (#3595)
- - There is now narrative documentation for the endpoints APIs, in the
- 'endpoints' core howto, as well as modifications to the 'writing
- clients' and 'writing servers' core howto documents to indicate
- that endpoints are now the preferred style of listening and
- connecting. (#4478)
- - trial's man page now documents the --disablegc option in more
- detail. (#4511)
- - trial's coverage output format is now documented in the trial man
- page. (#4512)
- - Broken links and spelling errors in the finger tutorial are now
- fixed. (#4516)
- - twisted.internet.threads.blockingCallFromThread's docstring is now
- explicit about Deferred support. (#4517)
- - twisted.python.zippath.ZipPath.child now documents its handling of
- ".." (which is not special, making it different from
- FilePath.child). (#4535)
- - The API docs for twisted.internet.defer.Deferred now cover several
- more of its (less interesting) attributes. (#4538)
- - LineReceiver, NetstringReceiver, and IntNStringReceiver from
- twisted.protocols.basic now have improved API documentation for
- read callbacks and write methods. (#4542)
- - Tidied up the Twisted Conch documentation for easier conversion.
- (#4566)
- - Use correct Twisted version for when cancellation was introduced in
- the Deferred docstring. (#4614)
- - The logging howto is now more clear about how the standard library
- logging module and twisted.python.log can be integrated. (#4642)
- - The finger tutorial still had references to .tap files. This
- reference has now been removed. The documentation clarifies
- "finger.tap" is a module and not a filename. (#4679)
- - The finger tutorial had a broken link to the
- twisted.application.service.Service class, which is now fixed.
- Additionally, a minor typo ('verison') was fixed. (#4681)
- - twisted.protocols.policies.TimeoutMixin now has clearer API
- documentation. (#4684)
-
-Deprecations and Removals
--------------------------
- - twisted.internet.defer.Deferred.setTimeout has been removed, after
- being deprecated since Twisted 2.0. (#1702)
- - twisted.internet.interfaces.IReactorTime.cancelCallLater
- (deprecated since 2007) and
- twisted.internet.interfaces.base.ReactorBase.cancelCallLater
- (deprecated since 2002) have been removed. (#4076)
- - Removed twisted.cred.util.py, which has been deprecated since
- Twisted 8.3. (#4107)
- - twisted.python.text.docstringLStrip was deprecated. (#4328)
- - The module attributes `LENGTH`, `DATA`, `COMMA`, and `NUMBER` of
- twisted.protocols.basic (previously used by `NetstringReceiver`)
- are now deprecated. (#4541)
- - twisted.protocols.basic.SafeNetstringReceiver, deprecated since
- 2001 (before Twisted 2.0), was removed. (#4546)
- - twisted.python.threadable.whenThreaded, deprecated since Twisted
- 2.2.0, has been removed. (#4550)
- - twisted.python.timeoutqueue, deprecated since Twisted 8.0, has been
- removed. (#4551)
- - iocpreactor transports can no longer be pickled. (#4617)
-
-Other
------
- - #4300, #4475, #4477, #4504, #4556, #4562, #4564, #4569, #4608,
- #4616, #4617, #4626, #4630, #4650, #4705
-
-
-Twisted Core 10.1.0 (2010-06-27)
-================================
-
-Features
---------
- - Add linux inotify support, allowing monitoring of file system
- events. (#972)
- - Deferreds now support cancellation. (#990)
- - Added new "endpoint" interfaces in twisted.internet.interfaces,
- which abstractly describe stream transport endpoints which can be
- listened on or connected to. Implementations for TCP and SSL
- clients and servers are present in twisted.internet.endpoints.
- Notably, client endpoints' connect() methods return cancellable
- Deferreds, so code written to use them can bypass the awkward
- "ClientFactory.clientConnectionFailed" and
- "Connector.stopConnecting" methods, and handle errbacks from or
- cancel the returned deferred, respectively. (#1442)
- - twisted.protocols.amp.Integer's documentation now clarifies that
- integers of arbitrary size are supported and that the wire format
- is a base-10 representation. (#2650)
- - twisted.protocols.amp now includes support for transferring
- timestamps (amp.DateTime) and decimal values (amp.Decimal). (#2651)
- - twisted.protocol.ftp.IWriteFile now has a close() method, which can
- return a Deferred. Previously a STOR command would finish
- immediately upon the receipt of the last byte of the uploaded file.
- With close(), the backend can delay the finish until it has
- performed some other slow action (like storing the data to a
- virtual filesystem). (#3462)
- - FilePath now calls os.stat() only when new status information is
- required, rather than immediately when anything changes. For some
- applications this may result in fewer stat() calls. Additionally,
- FilePath has a new method, 'changed', which applications may use to
- indicate that the FilePath may have been changed on disk and
- therefore the next status information request must fetch a new
- stat result. This is useful if external systems, such as C
- libraries, may have changed files that Twisted applications are
- referencing via a FilePath. (#4130)
- - Documentation improvements are now summarized in the NEWS file.
- (#4224)
- - twisted.internet.task.deferLater now returns a cancellable
- Deferred. (#4318)
- - The connect methods of twisted.internet.protocol.ClientCreator now
- return cancellable Deferreds. (#4329)
- - twisted.spread.pb now has documentation covering some of its
- limitations. (#4402)
- - twisted.spread.jelly now supports jellying and unjellying classes
- defined with slots if they also implement __getstate__ and
- __setstate__. (#4430)
- - twisted.protocols.amp.ListOf arguments can now be specified as
- optional. (#4474)
-
-Bugfixes
---------
- - On POSIX platforms, reactors now support child processes in a way
- which doesn't cause other syscalls to sometimes fail with EINTR (if
- running on Python 2.6 or if Twisted's extension modules have been
- built). (#733)
- - Substrings are escaped before being passed to a regular expression
- for searching to ensure that they don't get interpreted as part of
- the expression. (#1893)
- - twisted.internet.stdio now supports stdout being redirected to a
- normal file (except when using epollreactor). (#2259)
- - (#2367)
- - The tap2rpm script now works with modern versions of RPM. (#3292)
- - twisted.python.modules.walkModules will now handle packages
- explicitly precluded from importing by a None placed in
- sys.modules. (#3419)
- - ConnectedDatagramPort now uses stopListening when a connection
- fails instead of the deprecated loseConnection. (#3425)
- - twisted.python.filepath.FilePath.setContent is now safe for
- multiple processes to use concurrently. (#3694)
- - The mode argument to the methods of
- twisted.internet.interfaces.IReactorUNIX is no longer deprecated.
- (#4078)
- - Do not include blacklisted projects when generating NEWS. (#4190)
- - When generating NEWS for a project that had no significant changes,
- include a section for that project and say that there were no
- interesting changes. (#4191)
- - Redundant 'b' mode is no longer passed to calls to FilePath.open
- and FilePath.open itself now corrects the mode when multiple 'b'
- characters are present, ensuring only one instance of 'b' is
- provided, as a workaround for http://bugs.python.org/issue7686.
- (#4207)
- - HTML tags inside <pre> tags in the code snippets are now escaped.
- (#4336)
- - twisted.protocols.amp.CommandLocator now allows subclasses to
- override responders inherited from base classes. (#4343)
- - Fix a bunch of small but important defects in the INSTALL, README
- and so forth. (#4346)
- - The poll, epoll, glib2, and gtk2 reactors now all support half-
- close in the twisted.internet.stdio.StandardIO transport. (#4352)
- - twisted.application.internet no longer generates an extra and
- invalid entry in its __all__ list for the nonexistent
- MulticastClient. (#4373)
- - Choosing a reactor documentation now says that only the select-
- based reactor is a truly cross-platform reactor. (#4384)
- - twisted.python.filepath.FilePath now no longer leaves files open,
- to be closed by the garbage collector, when an exception is raised
- in the implementation of setContent, getContent, or copyTo. (#4400)
- - twisted.test.proto_helpers.StringTransport's getHost and getPeer
- methods now return IPv4Address instances by default. (#4401)
- - twisted.protocols.amp.BinaryBoxProtocol will no longer deliver an
- empty string to a switched-to protocol's dataReceived method when
- the BinaryBoxProtocol's buffer happened to be empty at the time of
- the protocol switch. (#4405)
- - IReactorUNIX.listenUNIX implementations now support abstract
- namespace sockets on Linux. (#4421)
- - Files opened with FilePath.create() (and therefore also files
- opened via FilePath.open() on a path with alwaysCreate=True) will
- now be opened in binary mode as advertised, so that they will
- behave portably across platforms. (#4453)
- - The subunit reporter now correctly reports import errors as errors,
- rather than by crashing with an unrelated error. (#4496)
-
-Improved Documentation
-----------------------
- - The finger tutorial example which introduces services now avoids
- double-starting the loop to re-read its users file. (#4420)
- - twisted.internet.defer.Deferred.callback's docstring now mentions
- the implicit chaining feature. (#4439)
- - doc/core/howto/listing/pb/chatclient.py can now actually send a
- group message. (#4459)
-
-Deprecations and Removals
--------------------------
- - twisted.internet.interfaces.IReactorArbitrary,
- twisted.application.internet.GenericServer, and
- twisted.application.internet.GenericClient are now deprecated.
- (#367)
- - twisted.internet.gtkreactor is now deprecated. (#2833)
- - twisted.trial.util.findObject has been deprecated. (#3108)
- - twisted.python.threadpool.ThreadSafeList is deprecated and Jython
- platform detection in Twisted core removed (#3725)
- - twisted.internet.interfaces.IUDPConnectedTransport has been removed
- (deprecated since Twisted 9.0). (#4077)
- - Removed twisted.application.app.runWithProfiler, which has been
- deprecated since Twisted 8.0. (#4090)
- - Removed twisted.application.app.runWithHotshot, which has been
- deprecated since Twisted 8.0. (#4091)
- - Removed twisted.application.app.ApplicationRunner.startLogging,
- which has been deprecated (doesn't say since when), as well as
- support for the legacy
- twisted.application.app.ApplicationRunner.getLogObserver method.
- (#4092)
- - twisted.application.app.reportProfile has been removed. (#4093)
- - twisted.application.app.getLogFile has been removed. (#4094)
- - Removed twisted.cred.util.py, which has been deprecated since
- Twisted 8.3. (#4107)
- - twisted.python.util.dsu is now deprecated. (#4339)
- - In twisted.trial.util: FailureError, DirtyReactorWarning,
- DirtyReactorError, and PendingTimedCallsError, which have all been
- deprecated since Twisted 8.0, have been removed. (#4505)
-
-Other
------
- - #1363, #1742, #3170, #3359, #3431, #3738, #4088, #4206, #4221,
- #4239, #4257, #4272, #4274, #4287, #4291, #4293, #4309, #4316,
- #4319, #4324, #4332, #4335, #4348, #4358, #4394, #4399, #4409,
- #4418, #4443, #4449, #4479, #4485, #4486, #4497
-
-
-Twisted Core 10.0.0 (2010-03-01)
-================================
-
-Features
---------
- - The twistd man page now has a SIGNALS section. (#689)
-
- - reactor.spawnProcess now will not emit a PotentialZombieWarning
- when called before reactor.run, and there will be no potential for
- zombie processes in this case. (#2078)
-
- - High-throughput applications based on Perspective Broker should now
- run noticably faster thanks to the use of a more efficient decoding
- function in Twisted Spread. (#2310)
-
- - Documentation for trac-post-commit-hook functionality in svn-dev
- policy. (#3867)
-
- - twisted.protocols.socks.SOCKSv4 now supports the SOCKSv4a protocol.
- (#3886)
-
- - Trial can now output test results according to the subunit
- protocol, as long as Subunit is installed (see
- https://launchpad.net/subunit). (#4004)
-
- - twisted.protocols.amp now provides a ListOf argument type which can
- be composed with some other argument types to create a zero or more
- element sequence of that type. (#4116)
-
- - If returnValue is invoked outside of a function decorated with
- @inlineCallbacks, but causes a function thusly decorated to exit, a
- DeprecationWarning will be emitted explaining this potentially
- confusing behavior. In a future release, this will cause an
- exception. (#4157)
-
- - twisted.python.logfile.BaseLogFile now has a reopen method allowing
- you to use an external logrotate mechanism. (#4255)
-
-Bugfixes
---------
- - FTP.ftp_NLST now handles requests on invalid paths in a way
- consistent with RFC 959. (#1342)
-
- - twisted.python.util.initgroups now calls the low-level C initgroups
- by default if available: the python version can create lots of I/O
- with certain authentication setup to retrieve all the necessary
- information. (#3226)
-
- - startLogging now does nothing on subsequent invocations, thus
- fixing a terrible infinite recursion bug that's only on edge case.
- (#3289)
-
- - Stringify non-string data to NetstringReceiver.sendString before
- calculating the length so that the calculated length is equal to
- the actual length of the transported data. (#3299)
-
- - twisted.python.win32.cmdLineQuote now correctly quotes empty
- strings arguments (#3876)
-
- - Change the behavior of the Gtk2Reactor to register only one source
- watch for each file descriptor, instead of one for reading and one
- for writing. In particular, it fixes a bug with Glib under Windows
- where we failed to notify when a client is connected. (#3925)
-
- - Twisted Trial no longer crashes if it can't remove an old
- _trial_temp directory. (#4020)
-
- - The optional _c_urlarg extension now handles unquote("") correctly
- on platforms where malloc(0) returns NULL, such as AIX. It also
- compiles with less warnings. (#4142)
-
- - On POSIX, child processes created with reactor.spawnProcess will no
- longer automatically ignore the signals which the parent process
- has set to be ignored. (#4199)
-
- - All SOCKSv4a tests now use a dummy reactor with a deterministic
- resolve method. (#4275)
-
- - Prevent extraneous server, date and content-type headers in proxy
- responses. (#4277)
-
-Deprecations and Removals
--------------------------
- - twisted.internet.error.PotentialZombieWarning is now deprecated.
- (#2078)
-
- - twisted.test.time_helpers is now deprecated. (#3719)
-
- - The deprecated connectUDP method of IReactorUDP has now been
- removed. (#4075)
-
- - twisted.trial.unittest.TestCase now ignores the previously
- deprecated setUpClass and tearDownClass methods. (#4175)
-
-Other
------
- - #917, #2406, #2481, #2608, #2689, #2884, #3056, #3082, #3199,
- #3480, #3592, #3718, #3935, #4066, #4083, #4154, #4166, #4169,
- #4176, #4183, #4186, #4188, #4189, #4194, #4201, #4204, #4209,
- #4222, #4234, #4235, #4238, #4240, #4245, #4251, #4264, #4268,
- #4269, #4282
-
-
-Twisted Core 9.0.0 (2009-11-24)
-===============================
-
-Features
---------
- - LineReceiver.clearLineBuffer now returns the bytes that it cleared (#3573)
- - twisted.protocols.amp now raises InvalidSignature when bad arguments are
- passed to Command.makeArguments (#2808)
- - IArgumentType was added to represent an existing but previously unspecified
- interface in amp (#3468)
- - Obscure python tricks have been removed from the finger tutorials (#2110)
- - The digest auth implementations in twisted.web and twisted.protocolos.sip
- have been merged together in twisted.cred (#3575)
- - FilePath and ZipPath now has a parents() method which iterates up all of its
- parents (#3588)
- - reactors which support threads now have a getThreadPool method (#3591)
- - The MemCache client implementation now allows arguments to the "stats"
- command (#3661)
- - The MemCache client now has a getMultiple method which allows fetching of
- multiple values (#3171)
- - twisted.spread.jelly can now unserialize some new-style classes (#2950)
- - twisted.protocols.loopback.loopbackAsync now accepts a parameter to control
- the data passed between client and server (#3820)
- - The IOCP reactor now supports SSL (#593)
- - Tasks in a twisted.internet.task.Cooperator can now be paused, resumed, and
- cancelled (#2712)
- - AmpList arguments can now be made optional (#3891)
- - The syslog output observer now supports log levels (#3300)
- - LoopingCall now supports reporting the number of intervals missed if it
- isn't able to schedule calls fast enough (#3671)
-
-Fixes
------
- - The deprecated md5 and sha modules are no longer used if the stdlib hashlib
- module is available (#2763)
- - An obscure deadlock involving waking up the reactor within signal handlers
- in particular threads was fixed (#1997)
- - The passivePortRange attribute of FTPFactory is now honored (#3593)
- - TestCase.flushWarnings now flushes warnings even if they were produced by a
- file that was renamed since it was byte compiled (#3598)
- - Some internal file descriptors are now marked as close-on-exec, so these will
- no longer be leaked to child processes (#3576)
- - twisted.python.zipstream now correctly extracts the first file in a directory
- as a file, and not an empty directory (#3625)
- - proxyForInterface now returns classes which correctly *implement* interfaces
- rather than *providing* them (#3646)
- - SIP Via header parameters should now be correctly generated (#2194)
- - The Deferred returned by stopListening would sometimes previously never fire
- if an exception was raised by the underlying file descriptor's connectionLost
- method. Now the Deferred will fire with a failure (#3654)
- - The command-line tool "manhole" should now work with newer versions of pygtk
- (#2464)
- - When a DefaultOpenSSLContextFactory is instantiated with invalid parameters,
- it will now raise an exception immediately instead of waiting for the first
- connection (#3700)
- - Twisted command line scripts should now work when installed in a virtualenv
- (#3750)
- - Trial will no longer delete temp directories which it did not create (#3481)
- - Processes started on Windows should now be cleaned up properly in more cases
- (#3893)
- - Certain misbehaving importers will no longer cause twisted.python.modules
- (and thus trial) to raise an exception, but rather issue a warning (#3913)
- - MemCache client protocol methods will now fail when the transport has been
- disconnected (#3643)
- - In the AMP method callRemoteString, the requiresAnswer parameter is now
- honored (#3999)
- - Spawning a "script" (a file which starts with a #! line) on Windows running
- Python 2.6 will now work instead of raising an exception about file mode
- "ru" (#3567)
- - FilePath's walk method now calls its "descend" parameter even on the first
- level of children, instead of only on grandchildren. This allows for better
- symlink cycle detection (#3911)
- - Attempting to write unicode data to process pipes on Windows will no longer
- result in arbitrarily encoded messages being written to the pipe, but instead
- will immediately raise an error (#3930)
- - The various twisted command line utilities will no longer print
- ModuleType.__doc__ when Twisted was installed with setuptools (#4030)
- - A Failure object will now be passed to connectionLost on stdio connections
- on Windows, instead of an Exception object (#3922)
-
-Deprecations and Removals
--------------------------
- - twisted.persisted.marmalade was deleted after a long period of deprecation
- (#876)
- - Some remaining references to the long-gone plugins.tml system were removed
- (#3246)
- - SSLv2 is now disabled by default, but it can be re-enabled explicitly
- (#3330)
- - twisted.python.plugin has been removed (#1911)
- - reactor.run will now raise a ReactorAlreadyRunning exception when it is
- called reentrantly instead of warning a DeprecationWarning (#1785)
- - twisted.spread.refpath is now deprecated because it is unmaintained,
- untested, and has dubious value (#3723)
- - The unused --quiet flag has been removed from the twistd command (#3003)
-
-Other
------
- - #3545, #3490, #3544, #3537, #3455, #3315, #2281, #3564, #3570, #3571, #3486,
- #3241, #3599, #3220, #1522, #3611, #3596, #3606, #3609, #3602, #3637, #3647,
- #3632, #3675, #3673, #3686, #2217, #3685, #3688, #2456, #506, #3635, #2153,
- #3581, #3708, #3714, #3717, #3698, #3747, #3704, #3707, #3713, #3720, #3692,
- #3376, #3652, #3695, #3735, #3786, #3783, #3699, #3340, #3810, #3822, #3817,
- #3791, #3859, #2459, #3677, #3883, #3894, #3861, #3822, #3852, #3875, #2722,
- #3768, #3914, #3885, #2719, #3905, #3942, #2820, #3990, #3954, #1627, #2326,
- #2972, #3253, #3937, #4058, #1200, #3639, #4079, #4063, #4050
-
-
-Core 8.2.0 (2008-12-16)
-=======================
-
-Features
---------
- - Reactors are slowly but surely becoming more isolated, thus improving
- testability (#3198)
- - FilePath has gained a realpath method, and FilePath.walk no longer infinitely
- recurses in the case of a symlink causing a self-recursing filesystem tree
- (#3098)
- - FilePath's moveTo and copyTo methods now have an option to disable following
- of symlinks (#3105)
- - Private APIs are now included in the API documentation (#3268)
- - hotshot is now the default profiler for the twistd --profile parameter and
- using cProfile is now documented (#3355, #3356)
- - Process protocols can now implement a processExited method, which is
- distinct from processEnded in that it is called immediately when the child
- has died, instead of waiting for all the file descriptors to be closed
- (#1291)
- - twistd now has a --umask option (#966, #3024)
- - A new deferToThreadPool function exists in twisted.internet.threads (#2845)
- - There is now an example of writing an FTP server in examples/ftpserver.py
- (#1579)
- - A new runAsEffectiveUser function has been added to twisted.python.util
- (#2607)
- - twisted.internet.utils.getProcessOutput now offers a mechanism for
- waiting for the process to actually end, in the event of data received on
- stderr (#3239)
- - A fullyQualifiedName function has been added to twisted.python.reflect
- (#3254)
- - strports now defaults to managing access to a UNIX socket with a lock;
- lockfile=0 can be included in the strports specifier to disable this
- behavior (#2295)
- - FTPClient now has a 'rename' method (#3335)
- - FTPClient now has a 'makeDirectory' method (#3500)
- - FTPClient now has a 'removeFile' method (#3491)
- - flushWarnings, A new Trial method for testing warnings, has been added
- (#3487, #3427, #3506)
- - The log observer can now be configured in .tac files (#3534)
-
-Fixes
------
- - TLS Session Tickets are now disabled by default, allowing connections to
- certain servers which hang when an empty session ticket is received (like
- GTalk) (#3463)
- - twisted.enterprise.adbapi.ConnectionPool's noisy attribute now defaults to
- False, as documented (#1806)
- - Error handling and logging in adbapi is now much improved (#3244)
- - TCP listeners can now be restarted (#2913)
- - Doctests can now be rerun with trial's --until-failure option (#2713)
- - Some memory leaks have been fixed in trial's --until-failure
- implementation (#3119, #3269)
- - Trial's summary reporter now prints correct runtime information and handles
- the case of 0 tests (#3184)
- - Trial and any other user of the 'namedAny' function now has better error
- reporting in the case of invalid module names (#3259)
- - Multiple instances of trial can now run in parallel in the same directory
- by creating _trial_temp directories with an incremental suffix (#2338)
- - Trial's failUnlessWarns method now works on Python 2.6 (#3223)
- - twisted.python.log now hooks into the warnings system in a way compatible
- with Python 2.6 (#3211)
- - The GTK2 reactor is now better supported on Windows, but still not passing
- the entire test suite (#3203)
- - low-level failure handling in spawnProcess has been improved and no longer
- leaks file descriptors (#2305, #1410)
- - Perspective Broker avatars now have their logout functions called in more
- cases (#392)
- - Log observers which raise exceptions are no longer removed (#1069)
- - transport.getPeer now always includes an IP address in the Address returned
- instead of a hostname (#3059)
- - Functions in twisted.internet.utils which spawn processes now avoid calling
- chdir in the case where no working directory is passed, to avoid some
- obscure permission errors (#3159)
- - twisted.spread.publish.Publishable no longer corrupts line endings on
- Windows (#2327)
- - SelectReactor now properly detects when a TLS/TCP connection has been
- disconnected (#3218)
- - twisted.python.lockfile no longer raises an EEXIST OSError and is much
- better supported on Windows (#3367)
- - When ITLSTransport.startTLS is called while there is data in the write
- buffer, TLS negotiation will now be delayed instead of the method raising
- an exception (#686)
- - The userAnonymous argument to FTPFactory is now honored (#3390)
- - twisted.python.modules no longer tries to "fix" sys.modules after an import
- error, which was just causing problems (#3388)
- - setup.py no longer attempts to build extension modules when run with Jython
- (#3410)
- - AMP boxes can now be sent in IBoxReceiver.startReceivingBoxes (#3477)
- - AMP connections are closed as soon as a key length larger than 255 is
- received (#3478)
- - Log events with timezone offsets between -1 and -59 minutes are now
- correctly reported as negative (#3515)
-
-Deprecations and Removals
--------------------------
- - Trial's setUpClass and tearDownClass methods are now deprecated (#2903)
- - problemsFromTransport has been removed in favor of the argument passed to
- connectionLost (#2874)
- - The mode parameter to methods of IReactorUNIX and IReactorUNIXDatagram are
- deprecated in favor of applications taking other security precautions, since
- the mode of a Unix socket is often not respected (#1068)
- - Index access on instances of twisted.internet.defer.FirstError has been
- removed in favor of the subFailure attribute (#3298)
- - The 'changeDirectory' method of FTPClient has been deprecated in favor of
- the 'cwd' method (#3491)
-
-Other
------
-
- - #3202, #2869, #3225, #2955, #3237, #3196, #2355, #2881, #3054, #2374, #2918,
- #3210, #3052, #3267, #3288, #2985, #3295, #3297, #2512, #3302, #1222, #2631,
- #3306, #3116, #3215, #1489, #3319, #3320, #3321, #1255, #2169, #3182, #3323,
- #3301, #3318, #3029, #3338, #3346, #1144, #3173, #3165, #685, #3357, #2582,
- #3370, #2438, #1253, #637, #1971, #2208, #979, #1790, #1888, #1882, #1793,
- #754, #1890, #1931, #1246, #1025, #3177, #2496, #2567, #3400, #2213, #2027,
- #3415, #1262, #3422, #2500, #3414, #3045, #3111, #2974, #2947, #3222, #2878,
- #3402, #2909, #3423, #1328, #1852, #3382, #3393, #2029, #3489, #1853, #2026,
- #2375, #3502, #3482, #3504, #3505, #3507, #2605, #3519, #3520, #3121, #3484,
- #3439, #3216, #3511, #3524, #3521, #3197, #2486, #2449, #2748, #3381, #3236,
- #671
-
-
-8.1.0 (2008-05-18)
-==================
-
-Features
---------
-
- - twisted.internet.error.ConnectionClosed is a new exception which is the
- superclass of ConnectionLost and ConnectionDone (#3137)
- - Trial's CPU and memory performance should be better now (#3034)
- - twisted.python.filepath.FilePath now has a chmod method (#3124)
-
-Fixes
------
-
- - Some reactor re-entrancy regressions were fixed (#3146, #3168)
- - A regression was fixed whereby constructing a Failure for an exception and
- traceback raised out of a Pyrex extension would fail (#3132)
- - CopyableFailures in PB can again be created from CopiedFailures (#3174)
- - FilePath.remove, when called on a FilePath representing a symlink to a
- directory, no longer removes the contents of the targeted directory, and
- instead removes the symlink (#3097)
- - FilePath now has a linkTo method for creating new symlinks (#3122)
- - The docstring for Trial's addCleanup method now correctly specifies when
- cleanup functions are run (#3131)
- - assertWarns now deals better with multiple identical warnings (#2904)
- - Various windows installer bugs were fixed (#3115, #3144, #3150, #3151, #3164)
- - API links in the howto documentation have been corrected (#3130)
- - The Win32 Process transport object now has a pid attribute (#1836)
- - A doc bug in the twistd plugin howto which would inevitably lead to
- confusion was fixed (#3183)
- - A regression breaking IOCP introduced after the last release was fixed
- (#3200)
-
-
-Deprecations and Removals
--------------------------
-
- - mktap is now fully deprecated, and will emit DeprecationWarnings when used
- (#3127)
-
-Other
------
- - #3079, #3118, #3120, #3145, #3069, #3149, #3186, #3208, #2762
-
-
-8.0.1 (2008-03-26)
-==================
-
-Fixes
------
- - README no longer refers to obsolete trial command line option
- - twistd no longer causes a bizarre DeprecationWarning about mktap
-
-
-8.0.0 (2008-03-17)
-==================
-
-Features
---------
-
- - The IOCP reactor has had many changes and is now greatly improved
- (#1760, #3055)
- - The main Twisted distribution is now easy_installable (#1286, #3110)
- - twistd can now profile with cProfile (#2469)
- - twisted.internet.defer contains a DeferredFilesystemLock which gives a
- Deferred interface to lock file acquisition (#2180)
- - twisted.python.modules is a new system for representing and manipulating
- module paths (i.e. sys.path) (#1951)
- - twisted.internet.fdesc now contains a writeToFD function, along with other
- minor fixes (#2419)
- - twisted.python.usage now allows optional type enforcement (#739)
- - The reactor now has a blockingCallFromThread method for non-reactor threads
- to use to wait for a reactor-scheduled call to return a result (#1042, #3030)
- - Exceptions raised inside of inlineCallbacks-using functions now have a
- better chance of coming with a meaningful traceback (#2639, #2803)
- - twisted.python.randbytes now contains code for generating secure random
- bytes (#2685)
- - The classes in twisted.application.internet now accept a reactor parameter
- for specifying the reactor to use for underlying calls to allow for better
- testability (#2937)
- - LoopingCall now allows you to specify the reactor to use to schedule new
- calls, allowing much better testing techniques (#2633, #2634)
- - twisted.internet.task.deferLater is a new API for scheduling calls and
- getting deferreds which are fired with their results (#1875)
- - objgrep now knows how to search through deque objects (#2323)
- - twisted.python.log now contains a Twisted log observer which can forward
- messages to the Python logging system (#1351)
- - Log files now include seconds in the timestamps (#867)
- - It is now possible to limit the number of log files to create during log
- rotation (#1095)
- - The interface required by the log context system is now documented as
- ILoggingContext, and abstract.FileDescriptor now declares that it implements
- it (#1272)
- - There is now an example cred checker that uses a database via adbapi (#460)
- - The epoll reactor is now documented in the choosing-reactors howto (#2539)
- - There were improvements to the client howto (#222)
- - Int8Receiver was added (#2315)
- - Various refactorings to AMP introduced better testability and public
- interfaces (#2657, #2667, #2656, #2664, #2810)
- - twisted.protocol.policies.TrafficLoggingFactory now has a resetCounter
- method (#2757)
- - The FTP client can be told which port range within which to bind passive
- transfer ports (#1904)
- - twisted.protocols.memcache contains a new asynchronous memcache client
- (#2506, #2957)
- - PB now supports anonymous login (#439, #2312)
- - twisted.spread.jelly now supports decimal objects (#2920)
- - twisted.spread.jelly now supports all forms of sets (#2958)
- - There is now an interface describing the API that process protocols must
- provide (#3020)
- - Trial reporting to core unittest TestResult objects has been improved (#2495)
- - Trial's TestCase now has an addCleanup method which allows easy setup of
- tear-down code (#2610, #2899)
- - Trial's TestCase now has an assertIsInstance method (#2749)
- - Trial's memory footprint and speed are greatly improved (#2275)
- - At the end of trial runs, "PASSED" and "FAILED" messages are now colorized
- (#2856)
- - Tests which leave global state around in the reactor will now fail in
- trial. A new option, --unclean-warnings, will convert these errors back into
- warnings (#2091)
- - Trial now has a --without-module command line for testing code in an
- environment that lacks a particular Python module (#1795)
- - Error reporting of failed assertEquals assertions now has much nicer
- formatting (#2893)
- - Trial now has methods for monkey-patching (#2598)
- - Trial now has an ITestCase (#2898, #1950)
- - The trial reporter API now has a 'done' method which is called at the end of
- a test run (#2883)
- - TestCase now has an assertWarns method which allows testing that functions
- emit warnings (#2626, #2703)
- - There are now no string exceptions in the entire Twisted code base (#2063)
- - There is now a system for specifying credentials checkers with a string
- (#2570)
-
-Fixes
------
-
- - Some tests which were asserting the value of stderr have been changed
- because Python uncontrollably writes bytes to stderr (#2405)
- - Log files handle time zones with DST better (#2404)
- - Subprocesses using PTYs on OS X that are handled by Twisted will now be able
- to more reliably write the final bytes before they exit, allowing Twisted
- code to more reliably receive them (#2371, #2858)
- - Trial unit test reporting has been improved (#1901)
- - The kqueue reactor handles connection failures better (#2172)
- - It's now possible to run "trial foo/bar/" without an exception: trailing
- slashes no longer cause problems (#2005)
- - cred portals now better deal with implementations of inherited interfaces
- (#2523)
- - FTP error handling has been improved (#1160, 1107)
- - Trial behaves better with respect to file locking on Windows (#2482)
- - The FTP server now gives a better error when STOR is attempted during an
- anonymous session (#1575)
- - Trial now behaves better with tests that use the reactor's threadpool (#1832)
- - twisted.python.reload now behaves better with new-style objects (#2297)
- - LogFile's defaultMode parameter is now better implemented, preventing
- potential security exploits (#2586)
- - A minor obscure leak in thread pools was corrected (#1134)
- - twisted.internet.task.Clock now returns the correct DelayedCall from
- callLater, instead of returning the one scheduled for the furthest in the
- future (#2691)
- - twisted.spread.util.FilePager no longer unnecessarily buffers data in
- memory (#1843, 2321)
- - Asking for twistd or trial to use an unavailable reactor no longer prints a
- traceback (#2457)
- - System event triggers have fewer obscure bugs (#2509)
- - Plugin discovery code is much better behaved, allowing multiple
- installations of a package with plugins (#2339, #2769)
- - Process and PTYProcess have been merged and some minor bugs have been fixed
- (#2341)
- - The reactor has less global state (#2545)
- - Failure can now correctly represent and format errors caused by string
- exceptions (#2830)
- - The epoll reactor now has better error handling which now avoids the bug
- causing 100% CPU usage in some cases (#2809)
- - Errors raised during trial setUp or tearDown methods are now handled better
- (#2837)
- - A problem when deferred callbacks add new callbacks to the deferred that
- they are a callback of was fixed (#2849)
- - Log messages that are emitted during connectionMade now have the protocol
- prefix correctly set (#2813)
- - The string representation of a TCP Server connection now contains the actual
- port that it's bound to when it was configured to listen on port 0 (#2826)
- - There is better reporting of error codes for TCP failures on Windows (#2425)
- - Process spawning has been made slightly more robust by disabling garbage
- collection temporarily immediately after forking so that finalizers cannot
- be executed in an unexpected environment (#2483)
- - namedAny now detects import errors better (#698)
- - Many fixes and improvements to the twisted.python.zipstream module have
- been made (#2996)
- - FilePager no longer blows up on empty files (#3023)
- - twisted.python.util.FancyEqMixin has been improved to cooperate with objects
- of other types (#2944)
- - twisted.python.FilePath.exists now restats to prevent incorrect result
- (#2896)
- - twisted.python.util.mergeFunctionMetadata now also merges the __module__
- attribute (#3049)
- - It is now possible to call transport.pauseProducing within connectionMade on
- TCP transports without it being ignored (#1780)
- - twisted.python.versions now understands new SVN metadata format for fetching
- the SVN revision number (#3058)
- - It's now possible to use reactor.callWhenRunning(reactor.stop) on gtk2 and
- glib2 reactors (#3011)
-
-Deprecations and removals
--------------------------
- - twisted.python.timeoutqueue is now deprecated (#2536)
- - twisted.enterprise.row and twisted.enterprise.reflector are now deprecated
- (#2387)
- - twisted.enterprise.util is now deprecated (#3022)
- - The dispatch and dispatchWithCallback methods of ThreadPool are now
- deprecated (#2684)
- - Starting the same reactor multiple times is now deprecated (#1785)
- - The visit method of various test classes in trial has been deprecated (#2897)
- - The --report-profile option to twistd and twisted.python.dxprofile are
- deprecated (#2908)
- - The upDownError method of Trial reporters is deprecated (#2883)
-
-Other
------
-
- - #2396, #2211, #1921, #2378, #2247, #1603, #2463, #2530, #2426, #2356, #2574,
- - #1844, #2575, #2655, #2640, #2670, #2688, #2543, #2743, #2744, #2745, #2746,
- - #2742, #2741, #1730, #2831, #2216, #1192, #2848, #2767, #1220, #2727, #2643,
- - #2669, #2866, #2867, #1879, #2766, #2855, #2547, #2857, #2862, #1264, #2735,
- - #942, #2885, #2739, #2901, #2928, #2954, #2906, #2925, #2942, #2894, #2793,
- - #2761, #2977, #2968, #2895, #3000, #2990, #2919, #2969, #2921, #3005, #421,
- - #3031, #2940, #1181, #2783, #1049, #3053, #2847, #2941, #2876, #2886, #3086,
- - #3095, #3109
-
-
-2.5.0 (2006-12-29)
-==================
-
-Twisted 2.5.0 is a major feature release, with several interesting new
-developments and a great number of bug fixes. Some of the highlights
-follow.
-
- * AMP, the Asynchronous Messaging Protocol, was introduced. AMP is
- a protocol which provides request/response semantics over a
- persistent connection in a very simple and extensible manner.
-
- * An Epoll-based reactor was added, which can be used with twistd or
- trial by passing "-r epoll" on the command line. This may improve
- performance of certain high-traffic network applications.
-
- * The 'twistd' command can now accept sub-commands which name an
- application to run. For example, 'twistd web --path .' will start a
- web server serving files out of the current directory. This
- functionality is meant to replace the old way of doing things with
- 'mktap' and 'twistd -f'.
-
- * Python 2.5 is now supported. Previous releases of Twisted were
- broken by changes in the release of Python 2.5.
-
- * 'inlineCallbacks' was added, which allows taking advantage of the
- new 'yield' expression syntax in Python 2.5 to avoid writing
- callbacks for Deferreds.
-
-In addition to these changes, there are many other minor features and
-a large number of bug fixes.
-
-Features
---------
- - log.err can now take a second argument for specifying information
- about an error (#1399)
- - A time-simulating test helper class, twisted.internet.task.Clock,
- was added (#1757)
- - Trial docstring improvements were made (#1604, #2133)
- - New SSL features were added to twisted.internet.ssl, such as client
- validation (#302)
- - Python 2.5 is now supported (#1867)
- - Trial's assertFailure now provides more information on failure (#1869)
- - Trial can now be run on tests within a zipfile (#1940)
- - AMP, a new simple protocol for asynchronous messaging, was added (#1715)
- - Trial's colorful reporter now works on win32 (#1646)
- - Trial test modules may now dynamically construct TestSuites (#1638, #2165)
- - twistd can now make use of plugins to run applications (#1922, #2013)
- - Twisted now works with the latest (unreleased) zope.interface (#2160)
- - An epoll-based reactor, epollreactor, was added. It is selectable
- with the -r options to twistd and trial (#1953)
- - twistd and trial now use the plugin system to find reactors which
- can be selected (#719)
- - twisted.internet.defer.inlineCallbacks was added. It takes
- advantage of Python 2.5's generators to offer a way to deal with
- Deferreds without callbacks (#2100)
-
-Fixes
------
- - Traceback formatting in Trial was improved (#1454, #1610)
- - twisted.python.filepath.FilePath.islink now actually returns True when
- appropriate (#1773)
- - twisted.plugin now no longer raises spurious errors (#926)
- - twisted.pb Cacheables may now be new-style classes (#1324)
- - FileDescriptor now deals with producers in a more
- interface-compliant and robust manner (#2286, #811)
- - "setup.py build" and other setup.py commands which don't actually
- install the software now work (#1835)
- - wxreactor has had various fixes (#1235, #1574, #1688)
-
-Deprecations and Removals
--------------------------
- - The old twisted.cred API (Perspectives, Identities and such) was
- removed (#1440)
- - twisted.spread.newjelly was removed (#1831)
- - Various deprecated things in twisted.python.components were
- removed: Interface, MetaInterface, getAdapterClass, and
- getAdapterClassWithInheritance (#1636)
- - twisted.enterprise.xmlreflector was removed (#661)
- - mktap is slowly on its way out, now that twistd supports plugins. It
- is not yet officially deprecated (#2013)
- - tkmktap was removed, because it wasn't working anyway (#2020)
- - reactor.iterate calls made inside of a Trial test case are
- deprecated (#2090)
- - twisted.internet.qtreactor was removed: It has been moved to a
- separate project. See http://twistedmatrix.com/trac/wiki/QTReactor
- (#2130, #2137)
- - threadedselectreactor is now not a directly usable reactor; it is
- only meant to help in writing other reactors (#2126)
- - twisted.python.reflect.funcinfo is deprecated (#2079)
- - twisted.spread.sturdy, which was already completely broken, was
- removed (#2299)
-
-
-Other
------
-The following changes are minor or closely related to other changes.
-
- - #1783, #1786, #1788, #1648, #1734, #1609, #1800, #1818,
- #1629, #1829, #491, #1816, #1824, #1855, #1797, #1637, #1371,
- #1892, #1887, #1897, #1563, #1741, #1943, #1952, #1276,
- #1837, #1726, #1963, #1965, #1973, #1976, #1991, #1936, #1113,
- #630, #2002, #2040, #2044, #1617, #2045, #2055, #2056, #2022,
- #2052, #1552, #1999, #1507, #2054, #1970, #1968, #662, #1910,
- #1694, #1999, #1409, #2150, #2127, #2155, #1983, #2014, #2222,
- #1067, #2136, #2065, #1430, #2173, #2212, #1871, #2147, #1199,
- #2273, #428, #992, #815, #2024, #2292, #2125, #2139, #2291, #2174,
- #2306, #2228, #2309, #2319, #2317, #2313, #2154, #1985, #1201
-
-
-2.4.0 (2006-05-21)
-==================
-
-Features
---------
- - twisted.internet.task.Cooperator (Added along with #1701).
-
-Fixes
------
- - Errors in UDP protocols no longer unbind the UDP port (#1695).
- - Misc: #1717, #1705, #1563, #1719, #1721, #1722, #1728.
-
-
-2.3.0 (2006-05-14)
-==================
-
-Features
---------
- - twisted-dev-mode's F9 now uses trial's --testmodule feature, rather than
- trying to guess what tests to run. This will break files using the "-x"
- test-case-name hack (just use a comma separated list instead).
- - API Documentation improvements.
- - A new Producer/Consumer guide (#53)
- - Better-defined error behavior in IReactorMulticast (#1578)
- - IOCP Multicast support (#1500)
- - Improved STDIO support on Windows. (#1553)
- - LoopingCall supports Deferreds such that it will wait until a
- Deferred has fired before rescheduling the next call (#1487)
- - Added twisted.python.versions.Version, a structured representation
- of Version information, including support for SVN revision numbers
- (#1663)
-
-Fixes
------
-
- - Many trial fixes, as usual
- - All API documentation is now correctly formatted as epytext (#1545)
- - twisted.python.filepath.FilePath.__repr__ is safer.
- - Fix trial's "until-failure" mode. (#1453)
- - deferredGenerator now no longer causes handled exceptions (or
- results) to propagate to the resulting Deferred (#1709).
- - Misc: #1483, #1495, #1503, #1532, #1539, #1559, #1509, #1538,
- #1571, #1331, #1561, #737, #1562, #1573, #1594, #1607, #1407, #1615,
- #1645, #1634, #1620, #1664, #1666, #1650, #1670, #1675, #1692, #1710,
- #1668.
-
-Deprecations
-------------
-
- - Removal of already-deprecated trial APIs: the assertions module,
- util.deferredResult, util.deferredError, util.fireWhenDoneFunc,
- util.spinUntil, util.spinWhile, util.extract_tb,
- util.format_exception, util.suppress_warnings, unittest.wait,
- util.wait
- - The backwards compatibility layer of twisted.python.components
- (e.g., backwardsCompatImplements, fixClassImplements, etc) has been
- disabled. The functions still exist, but do nothing as to not break
- user code outright (#1511)
- - Deprecate the usage of the 'default' argument as a keyword argument
- in Interface.__call__. Passing a second positional argument to
- specify the default return value of the adaptation is still
- supported.
-
-
-2.2.0 (2006-02-12)
-==================
-
-Features
---------
- - Twisted no longer works with Python 2.2
- - FTP server supports more clients
- - Process support on Windows
- - twisted.internet.stdio improved (including Windows support!)
- - Trial:
- - Continued Trial refactoring
- - Default trial reporter is verbose black&white when color isn't supported
- - Deferreds returned in trial tests that don't fire before the
- unittest timeout now have their errback fired with a TimeoutError
- - raising SkipTest in setUp and setUpClass skips tests
- - Test suites are failed if there are import errors
-
-Fixes
------
- - iocpreactor fixes
- - Threadpool fixes
- - Fixed infinite loops in datagramReceived edge cases
- - Issues resolved: 654, 773, 998, 1005, 1008, 1116, 1123, 1198, 1221,
- 1232, 1233, 1236, 1240, 1244, 1258, 1263, 1265, 1266, 1271, 1275,
- 1293, 1294, 1298, 1308, 1316, 1317, 1321, 1341, 1344, 1353, 1359,
- 1372, 1374, 1377, 1379, 1380, 1385, 1388, 1389, 1413, 1422, 1426,
- 1434, 1435, 1448, 1449, 1456
-
-Deprecations
-------------
- - Trial:
- - spinWhile and spinUntil
- - util.wait
- - extract_tb and format_exception
- - util.suppressWarnings
- - runReactor is gone
-
-
-2.1.0 (2005-11-06)
-==================
-
-Features
---------
- - threadedselectreactor, a reactor which potentially makes
- integration with foreign event loops much simpler.
- - major improvements to twisted.conch.insults, including many new widgets.
- - adbapi ConnectionPools now have 'runWithConnection' which is
- similar to runInteraction but gives you a connection object instead of
- a transaction. [975]
- - __file__ is now usable in tac files
- - twisted.cred.pamauth now contains a PAM checker (moved from twisted.conch)
- - twisted.protocols.policies.LimitTotalConnectionsFactory now exists,
- which does as the name suggests
- - twisted.protocols.ident now uses /proc/net/tcp on Linux [233]
- - trial now recurses packages by default (a la the old -R parameter)
- - (PB) Calling a remote method that doesn't exist now raises
- NoSuchMethod instead of AttributeError.
-
-Fixes
------
- - FTP client and server improvements
- - Trial improvements: The code is now much simpler, and more stable.
- - twisted.protocols.basic.FileSender now works with empty files
- - Twisted should now be much more usable on Pythons without thread support.
- - minor improvements to process code in win32eventreactor
- - twistd -y (--python) now implies -o (--nosave). [539]
- - improved lockfile handling especially with respect to unix sockets.
- - deferredGenerator now no longer overuses the stack, which sometimes
- caused stack overflows.
- - Failure.raiseException now at least always raises the correct Exception.
- - minor improvements to serialport code
-
-Deprecations
-------------
- - twisted.python.componts.getAdapter. Use IFoo(o) instead.
- - Adapter persistence (IFoo(x, persist=True)). Just don't use it.
- - log.debug. It was equivalent to log.msg(), just use that.
- - twisted.protocols.telnet. twisted.conch.telnet replaces it.
- - Setting a trial reporter using a flag to 'trial'. Instead of 'trial
- --bwverbose', for example, use 'trial --reporter=bwverbose'.
- - trial --coverage will become a flag in Twisted 2.2.
- - passing a fully-qualified python name to --reporter is
- deprecated. Pass only names of Reporter plugins.
- - trial --psyco.
- - trial -R (--recurse) is now the default, so passing it is deprecated.
- - trial --reporter-args. Use the plugin system to do this sort of thing.
- - trial.assertions.assertionMethod and trial.unittest.assertionMethod
- are both deprecated. Use instance methods on TestCases instead.
- - trial's deferredResult, deferredError, and wait functions. Return
- Deferreds from your test methods instead of using them.
- - Raising unittest.SkipTest with no arguments. Give a reason for your skip.
- - The Failure returned from a gatherResults and DeferredList is now
- of type FirstError instead of a tuple of (Exception, index). It
- supports a firstError[idx] syntax but that is deprecated. Use
- firstError.subFailure and firstError.index instead.
- - whenThreaded now simply calls the passed function synchronously.
-
-2.0.1 (2005-05-09)
-===================
-Minor bug fix release.
-
-SVN rev (file) - [bug number] description
------------------------------------------
-13307 (twisted/topfiles/README) - Mention support for python 2.4, too
-13324 (twisted/internet/defer.py) - [947] Fix DeferredQueue backlog/size limit.
-13354 (twisted/plugins/__init__.py) - Correct maintainer address.
-13355 (twisted/test/test_defer.py) - improvements to DeferredQueue test case
-13387 (setup.py) - add news to list of subprojects to install
-13332 (twisted/internet/posixbase.py) - Fix spelling error
-13366 (twisted/internet/qtreactor.py) - [957] [954] reactor.iterate fixes
-13368 (twisted/test/test_internet.py) - Fix DelayedCall test case
-13422 (twisted/internet/posixbase.py) - Remove log from _Win32Waker creation.
-13437 (twisted/plugin.py) - [958] Only write cache if there were changes.
-13666 (twisted/internet/gtkreactor.py,gtk2reactor.py) - Don't run callbacks
- until the reactor is actually up and running
-13748 (twisted/internet/gtk2reactor.py) - [552] [994] Initialize threading properly.
-
-
-2.0.0 (2005-03-25)
-==================
-
-Major new features
-------------------
- - Replaced home-grown components system with zope.interface.
- - Split Twisted into multiple pieces.
- - Relicensed: Now under the MIT license, rather than LGPL.
- - Python 2.4 compatibility fixes
- - Major efficiency improvements in TCP buffering algorithm.
- - Major efficiency improvements in reactor.callLater/DelayedCall.
- - Half-close support for TCP/SSL. (loseWriteConnection).
-
-Miscellaneous features/fixes
-----------------------------
- - New plugin system: twisted.plugin
- - Better debugging support. Control-C will break you into PDB.
- - The twistd command has --uid --gid command line arguments.
- - *Incompatibility: mktap defaults to not change UID/GID, instead of saving
- the invoking user's UID/GID.
- - Removed some functions that were deprecated since Twisted 1.0.
- - ZSH tab-completion for twisted commands.
-
- - More correct daemonization in twistd.
- - twisted.python.log: do not close the log because of invalid format string.
- - Disabled automatic import of cBanana.
- - Boolean support for twisted.persisted.marmalade.
- - Refactor of plugin and application HOWTO documentation
- - Async HOWTO expanded greatly.
- - twisted.python.usage outputs the actual defaults, not passed in values.
-
-twisted.trial
--------------
- - Rewritten, a bunch of bugs fixed, a few more added.
-
-twisted.internet
-----------------
- - Multi-listen UDP multicast support
- - protocol.ClientCreator has a connectSSL.
- - defer.deferredGenerator: allows you to write Deferred code w/o callbacks.
- - Deferred.setTimeout is now deprecated.
- - New defer.DeferredLock/DeferredSemaphore/DeferredQueue.
- - Add utils.getProcessOutputAndValue to get stdout/err/value.
-
- - Default DNS resolver is now non-blocking.
- - Increased default TCP accept backlog from 5 to 50.
- - Make buffering large amounts of TCP data work on Windows.
- - Fixed SSL disconnect to not wait for remote host. Fixes issue with firefox.
- - Separate state for Deferred finalization so that GC-loops preventing
- finalization don't occur.
- - Many Process bugfixes
- - Processes spawned on windows can successfully use sockets
- - gtk2reactor can optionally use glib event loop instead of gtk
- - gtk2reactor notifies gobject to initialize thread support
- - Fix registering a streaming producer on a transport.
- - Close client sockets explicitly after failed connections.
- - ReconnectingClientFactory now continues attempting to reconnect after all
- errors, not just those which are not UserErrors.
-
-twisted.protocols
------------------
- - Portforward doesn't start reading from a client until a connection is made.
- - Bugfixes in twisted.protocols.loopback
- - Improve speed of twisted.protocols.LineReceiver.
- - LineReceiver implements IProducer. (stop/pause/resumeProducing)
- - SOCKSv4 properly closes connections
-
-twisted.enterprise
-------------------
- - Add "new connection" callback to adbapi.ConnectionPool to allow for
- custom db connection setup (cp_openfun)
- - adbapi.ConnectionPool automatic reconnection support
- - Don't log exceptions extraneously
-
-
-1.3.0 (2004-05-14)
-==================
-
-- Address objects for IPv4 and Unix addresses throughout twisted.internet.
-- Improved connected UDP APIs.
-- Refactored SSH client support.
-- Initial implementation of Windows I/O Completion Ports event loop.
-- Bug fixes and feature enhancements.
-- Nevow support for Lore (so your Lore documents can use Nevow directives).
-- This is the last release before Twisted begins splitting up.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/README
deleted file mode 100644
index 9d7027cc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/topfiles/README
+++ /dev/null
@@ -1,14 +0,0 @@
-Twisted Core 12.2.0
-===================
-
-Twisted Core makes up the core parts of Twisted, including:
-
- * Networking support (twisted.internet)
- * Trial, the unit testing framework (twisted.trial)
- * AMP, the Asynchronous Messaging Protocol (twisted.protocols.amp)
- * Twisted Spread, a remote object system (twisted.spread)
- * Utility code (twisted.python)
- * Basic abstractions that multiple subprojects use
- (twisted.cred, twisted.application, twisted.plugin)
- * Database connectivity support (twisted.enterprise)
- * A few basic protocols and protocol abstractions (twisted.protocols)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/__init__.py
deleted file mode 100755
index ad9423c1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/__init__.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-# Maintainer: Jonathan Lange
-
-"""
-Asynchronous unit testing framework.
-
-Trial extends Python's builtin C{unittest} to provide support for asynchronous
-tests.
-
-Maintainer: Jonathan Lange
-
-Trial strives to be compatible with other Python xUnit testing frameworks.
-"Compatibility" is a difficult things to define. In practice, it means that:
-
- - L{twisted.trial.unittest.TestCase} objects should be able to be used by
- other test runners without those runners requiring special support for
- Trial tests.
-
- - Tests that subclass the standard library C{TestCase} and don't do anything
- "too weird" should be able to be discoverable and runnable by the Trial
- test runner without the authors of those tests having to jump through
- hoops.
-
- - Tests that implement the interface provided by the standard library
- C{TestCase} should be runnable by the Trial runner.
-
- - The Trial test runner and Trial L{unittest.TestCase} objects ought to be
- able to use standard library C{TestResult} objects, and third party
- C{TestResult} objects based on the standard library.
-
-This list is not necessarily exhaustive -- compatibility is hard to define.
-Contributors who discover more helpful ways of defining compatibility are
-encouraged to update this document.
-
-
-Examples:
-
-B{Timeouts} for tests should be implemented in the runner. If this is done,
-then timeouts could work for third-party TestCase objects as well as for
-L{twisted.trial.unittest.TestCase} objects. Further, Twisted C{TestCase}
-objects will run in other runners without timing out.
-See U{http://twistedmatrix.com/trac/ticket/2675}.
-
-Running tests in a temporary directory should be a feature of the test case,
-because often tests themselves rely on this behaviour. If the feature is
-implemented in the runner, then tests will change behaviour (possibly
-breaking) when run in a different test runner. Further, many tests don't even
-care about the filesystem.
-See U{http://twistedmatrix.com/trac/ticket/2916}.
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/itrial.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/itrial.py
deleted file mode 100755
index d92884c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/itrial.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Interfaces for Trial.
-
-Maintainer: Jonathan Lange
-"""
-
-import zope.interface as zi
-from zope.interface import Attribute
-
-
-class ITestCase(zi.Interface):
- """
- The interface that a test case must implement in order to be used in Trial.
- """
-
- failureException = zi.Attribute(
- "The exception class that is raised by failed assertions")
-
-
- def __call__(result):
- """
- Run the test. Should always do exactly the same thing as run().
- """
-
-
- def countTestCases():
- """
- Return the number of tests in this test case. Usually 1.
- """
-
-
- def id():
- """
- Return a unique identifier for the test, usually the fully-qualified
- Python name.
- """
-
-
- def run(result):
- """
- Run the test, storing the results in C{result}.
-
- @param result: A L{TestResult}.
- """
-
-
- def shortDescription():
- """
- Return a short description of the test.
- """
-
-
-
-class IReporter(zi.Interface):
- """
- I report results from a run of a test suite.
- """
-
- stream = zi.Attribute(
- "Deprecated in Twisted 8.0. "
- "The io-stream that this reporter will write to")
- tbformat = zi.Attribute("Either 'default', 'brief', or 'verbose'")
- args = zi.Attribute(
- "Additional string argument passed from the command line")
- shouldStop = zi.Attribute(
- """
- A boolean indicating that this reporter would like the test run to stop.
- """)
- separator = Attribute(
- "Deprecated in Twisted 8.0. "
- "A value which will occasionally be passed to the L{write} method.")
- testsRun = Attribute(
- """
- The number of tests that seem to have been run according to this
- reporter.
- """)
-
-
- def startTest(method):
- """
- Report the beginning of a run of a single test method.
-
- @param method: an object that is adaptable to ITestMethod
- """
-
-
- def stopTest(method):
- """
- Report the status of a single test method
-
- @param method: an object that is adaptable to ITestMethod
- """
-
-
- def startSuite(name):
- """
- Deprecated in Twisted 8.0.
-
- Suites which wish to appear in reporter output should call this
- before running their tests.
- """
-
-
- def endSuite(name):
- """
- Deprecated in Twisted 8.0.
-
- Called at the end of a suite, if and only if that suite has called
- C{startSuite}.
- """
-
-
- def cleanupErrors(errs):
- """
- Deprecated in Twisted 8.0.
-
- Called when the reactor has been left in a 'dirty' state
-
- @param errs: a list of L{twisted.python.failure.Failure}s
- """
-
-
- def upDownError(userMeth, warn=True, printStatus=True):
- """
- Deprecated in Twisted 8.0.
-
- Called when an error occurs in a setUp* or tearDown* method
-
- @param warn: indicates whether or not the reporter should emit a
- warning about the error
- @type warn: Boolean
- @param printStatus: indicates whether or not the reporter should
- print the name of the method and the status
- message appropriate for the type of error
- @type printStatus: Boolean
- """
-
-
- def addSuccess(test):
- """
- Record that test passed.
- """
-
-
- def addError(test, error):
- """
- Record that a test has raised an unexpected exception.
-
- @param test: The test that has raised an error.
- @param error: The error that the test raised. It will either be a
- three-tuple in the style of C{sys.exc_info()} or a
- L{Failure<twisted.python.failure.Failure>} object.
- """
-
-
- def addFailure(test, failure):
- """
- Record that a test has failed with the given failure.
-
- @param test: The test that has failed.
- @param failure: The failure that the test failed with. It will
- either be a three-tuple in the style of C{sys.exc_info()}
- or a L{Failure<twisted.python.failure.Failure>} object.
- """
-
-
- def addExpectedFailure(test, failure, todo):
- """
- Record that the given test failed, and was expected to do so.
-
- @type test: L{pyunit.TestCase}
- @param test: The test which this is about.
- @type error: L{failure.Failure}
- @param error: The error which this test failed with.
- @type todo: L{unittest.Todo}
- @param todo: The reason for the test's TODO status.
- """
-
-
- def addUnexpectedSuccess(test, todo):
- """
- Record that the given test failed, and was expected to do so.
-
- @type test: L{pyunit.TestCase}
- @param test: The test which this is about.
- @type todo: L{unittest.Todo}
- @param todo: The reason for the test's TODO status.
- """
-
-
- def addSkip(test, reason):
- """
- Record that a test has been skipped for the given reason.
-
- @param test: The test that has been skipped.
- @param reason: An object that the test case has specified as the reason
- for skipping the test.
- """
-
-
- def printSummary():
- """
- Deprecated in Twisted 8.0, use L{done} instead.
-
- Present a summary of the test results.
- """
-
-
- def printErrors():
- """
- Deprecated in Twisted 8.0, use L{done} instead.
-
- Present the errors that have occured during the test run. This method
- will be called after all tests have been run.
- """
-
-
- def write(string):
- """
- Deprecated in Twisted 8.0, use L{done} instead.
-
- Display a string to the user, without appending a new line.
- """
-
-
- def writeln(string):
- """
- Deprecated in Twisted 8.0, use L{done} instead.
-
- Display a string to the user, appending a new line.
- """
-
- def wasSuccessful():
- """
- Return a boolean indicating whether all test results that were reported
- to this reporter were successful or not.
- """
-
-
- def done():
- """
- Called when the test run is complete.
-
- This gives the result object an opportunity to display a summary of
- information to the user. Once you have called C{done} on an
- L{IReporter} object, you should assume that the L{IReporter} object is
- no longer usable.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/reporter.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/reporter.py
deleted file mode 100755
index 27067f8b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/reporter.py
+++ /dev/null
@@ -1,1245 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_reporter -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-# Maintainer: Jonathan Lange
-
-"""
-Defines classes that handle the results of tests.
-"""
-
-import sys, os
-import time
-import warnings
-
-from twisted.python.compat import set
-from twisted.python import reflect, log
-from twisted.python.components import proxyForInterface
-from twisted.python.failure import Failure
-from twisted.python.util import OrderedDict, untilConcludes
-from twisted.trial import itrial, util
-
-try:
- from subunit import TestProtocolClient
-except ImportError:
- TestProtocolClient = None
-from zope.interface import implements
-
-pyunit = __import__('unittest')
-
-
-class BrokenTestCaseWarning(Warning):
- """
- Emitted as a warning when an exception occurs in one of setUp or tearDown.
- """
-
-
-class SafeStream(object):
- """
- Wraps a stream object so that all C{write} calls are wrapped in
- L{untilConcludes}.
- """
-
- def __init__(self, original):
- self.original = original
-
- def __getattr__(self, name):
- return getattr(self.original, name)
-
- def write(self, *a, **kw):
- return untilConcludes(self.original.write, *a, **kw)
-
-
-class TestResult(pyunit.TestResult, object):
- """
- Accumulates the results of several L{twisted.trial.unittest.TestCase}s.
-
- @ivar successes: count the number of successes achieved by the test run.
- @type successes: C{int}
- """
- implements(itrial.IReporter)
-
- def __init__(self):
- super(TestResult, self).__init__()
- self.skips = []
- self.expectedFailures = []
- self.unexpectedSuccesses = []
- self.successes = 0
- self._timings = []
-
- def __repr__(self):
- return ('<%s run=%d errors=%d failures=%d todos=%d dones=%d skips=%d>'
- % (reflect.qual(self.__class__), self.testsRun,
- len(self.errors), len(self.failures),
- len(self.expectedFailures), len(self.skips),
- len(self.unexpectedSuccesses)))
-
- def _getTime(self):
- return time.time()
-
- def _getFailure(self, error):
- """
- Convert a C{sys.exc_info()}-style tuple to a L{Failure}, if necessary.
- """
- if isinstance(error, tuple):
- return Failure(error[1], error[0], error[2])
- return error
-
- def startTest(self, test):
- """
- This must be called before the given test is commenced.
-
- @type test: L{pyunit.TestCase}
- """
- super(TestResult, self).startTest(test)
- self._testStarted = self._getTime()
-
- def stopTest(self, test):
- """
- This must be called after the given test is completed.
-
- @type test: L{pyunit.TestCase}
- """
- super(TestResult, self).stopTest(test)
- self._lastTime = self._getTime() - self._testStarted
-
- def addFailure(self, test, fail):
- """
- Report a failed assertion for the given test.
-
- @type test: L{pyunit.TestCase}
- @type fail: L{Failure} or L{tuple}
- """
- self.failures.append((test, self._getFailure(fail)))
-
- def addError(self, test, error):
- """
- Report an error that occurred while running the given test.
-
- @type test: L{pyunit.TestCase}
- @type error: L{Failure} or L{tuple}
- """
- self.errors.append((test, self._getFailure(error)))
-
- def addSkip(self, test, reason):
- """
- Report that the given test was skipped.
-
- In Trial, tests can be 'skipped'. Tests are skipped mostly because there
- is some platform or configuration issue that prevents them from being
- run correctly.
-
- @type test: L{pyunit.TestCase}
- @type reason: L{str}
- """
- self.skips.append((test, reason))
-
- def addUnexpectedSuccess(self, test, todo):
- """Report that the given test succeeded against expectations.
-
- In Trial, tests can be marked 'todo'. That is, they are expected to fail.
- When a test that is expected to fail instead succeeds, it should call
- this method to report the unexpected success.
-
- @type test: L{pyunit.TestCase}
- @type todo: L{unittest.Todo}
- """
- # XXX - 'todo' should just be a string
- self.unexpectedSuccesses.append((test, todo))
-
- def addExpectedFailure(self, test, error, todo):
- """Report that the given test failed, and was expected to do so.
-
- In Trial, tests can be marked 'todo'. That is, they are expected to fail.
-
- @type test: L{pyunit.TestCase}
- @type error: L{Failure}
- @type todo: L{unittest.Todo}
- """
- # XXX - 'todo' should just be a string
- self.expectedFailures.append((test, error, todo))
-
- def addSuccess(self, test):
- """Report that the given test succeeded.
-
- @type test: L{pyunit.TestCase}
- """
- self.successes += 1
-
- def upDownError(self, method, error, warn, printStatus):
- warnings.warn("upDownError is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=3)
-
- def cleanupErrors(self, errs):
- """Report an error that occurred during the cleanup between tests.
- """
- warnings.warn("Cleanup errors are actual errors. Use addError. "
- "Deprecated in Twisted 8.0",
- category=DeprecationWarning, stacklevel=2)
-
- def startSuite(self, name):
- warnings.warn("startSuite deprecated in Twisted 8.0",
- category=DeprecationWarning, stacklevel=2)
-
- def endSuite(self, name):
- warnings.warn("endSuite deprecated in Twisted 8.0",
- category=DeprecationWarning, stacklevel=2)
-
-
- def done(self):
- """
- The test suite has finished running.
- """
-
-
-
-class TestResultDecorator(proxyForInterface(itrial.IReporter,
- "_originalReporter")):
- """
- Base class for TestResult decorators.
-
- @ivar _originalReporter: The wrapped instance of reporter.
- @type _originalReporter: A provider of L{itrial.IReporter}
- """
-
- implements(itrial.IReporter)
-
-
-
-class UncleanWarningsReporterWrapper(TestResultDecorator):
- """
- A wrapper for a reporter that converts L{util.DirtyReactorAggregateError}s
- to warnings.
- """
- implements(itrial.IReporter)
-
- def addError(self, test, error):
- """
- If the error is a L{util.DirtyReactorAggregateError}, instead of
- reporting it as a normal error, throw a warning.
- """
-
- if (isinstance(error, Failure)
- and error.check(util.DirtyReactorAggregateError)):
- warnings.warn(error.getErrorMessage())
- else:
- self._originalReporter.addError(test, error)
-
-
-
-class _AdaptedReporter(TestResultDecorator):
- """
- TestResult decorator that makes sure that addError only gets tests that
- have been adapted with a particular test adapter.
- """
-
- def __init__(self, original, testAdapter):
- """
- Construct an L{_AdaptedReporter}.
-
- @param original: An {itrial.IReporter}.
- @param testAdapter: A callable that returns an L{itrial.ITestCase}.
- """
- TestResultDecorator.__init__(self, original)
- self.testAdapter = testAdapter
-
-
- def addError(self, test, error):
- """
- See L{itrial.IReporter}.
- """
- test = self.testAdapter(test)
- return self._originalReporter.addError(test, error)
-
-
- def addExpectedFailure(self, test, failure, todo):
- """
- See L{itrial.IReporter}.
- """
- return self._originalReporter.addExpectedFailure(
- self.testAdapter(test), failure, todo)
-
-
- def addFailure(self, test, failure):
- """
- See L{itrial.IReporter}.
- """
- test = self.testAdapter(test)
- return self._originalReporter.addFailure(test, failure)
-
-
- def addSkip(self, test, skip):
- """
- See L{itrial.IReporter}.
- """
- test = self.testAdapter(test)
- return self._originalReporter.addSkip(test, skip)
-
-
- def addUnexpectedSuccess(self, test, todo):
- """
- See L{itrial.IReporter}.
- """
- test = self.testAdapter(test)
- return self._originalReporter.addUnexpectedSuccess(test, todo)
-
-
- def startTest(self, test):
- """
- See L{itrial.IReporter}.
- """
- return self._originalReporter.startTest(self.testAdapter(test))
-
-
- def stopTest(self, test):
- """
- See L{itrial.IReporter}.
- """
- return self._originalReporter.stopTest(self.testAdapter(test))
-
-
-
-class Reporter(TestResult):
- """
- A basic L{TestResult} with support for writing to a stream.
-
- @ivar _startTime: The time when the first test was started. It defaults to
- C{None}, which means that no test was actually launched.
- @type _startTime: C{float} or C{NoneType}
-
- @ivar _warningCache: A C{set} of tuples of warning message (file, line,
- text, category) which have already been written to the output stream
- during the currently executing test. This is used to avoid writing
- duplicates of the same warning to the output stream.
- @type _warningCache: C{set}
-
- @ivar _publisher: The log publisher which will be observed for warning
- events.
- @type _publisher: L{LogPublisher} (or another type sufficiently similar)
- """
-
- implements(itrial.IReporter)
-
- _separator = '-' * 79
- _doubleSeparator = '=' * 79
-
- def __init__(self, stream=sys.stdout, tbformat='default', realtime=False,
- publisher=None):
- super(Reporter, self).__init__()
- self._stream = SafeStream(stream)
- self.tbformat = tbformat
- self.realtime = realtime
- self._startTime = None
- self._warningCache = set()
-
- # Start observing log events so as to be able to report warnings.
- self._publisher = publisher
- if publisher is not None:
- publisher.addObserver(self._observeWarnings)
-
-
- def _observeWarnings(self, event):
- """
- Observe warning events and write them to C{self._stream}.
-
- This method is a log observer which will be registered with
- C{self._publisher.addObserver}.
-
- @param event: A C{dict} from the logging system. If it has a
- C{'warning'} key, a logged warning will be extracted from it and
- possibly written to C{self.stream}.
- """
- if 'warning' in event:
- key = (event['filename'], event['lineno'],
- event['category'].split('.')[-1],
- str(event['warning']))
- if key not in self._warningCache:
- self._warningCache.add(key)
- self._stream.write('%s:%s: %s: %s\n' % key)
-
-
- def stream(self):
- warnings.warn("stream is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=2)
- return self._stream
- stream = property(stream)
-
-
- def separator(self):
- warnings.warn("separator is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=2)
- return self._separator
- separator = property(separator)
-
-
- def startTest(self, test):
- """
- Called when a test begins to run. Records the time when it was first
- called and resets the warning cache.
-
- @param test: L{ITestCase}
- """
- super(Reporter, self).startTest(test)
- if self._startTime is None:
- self._startTime = self._getTime()
- self._warningCache = set()
-
-
- def addFailure(self, test, fail):
- """
- Called when a test fails. If L{realtime} is set, then it prints the
- error to the stream.
-
- @param test: L{ITestCase} that failed.
- @param fail: L{failure.Failure} containing the error.
- """
- super(Reporter, self).addFailure(test, fail)
- if self.realtime:
- fail = self.failures[-1][1] # guarantee it's a Failure
- self._write(self._formatFailureTraceback(fail))
-
-
- def addError(self, test, error):
- """
- Called when a test raises an error. If L{realtime} is set, then it
- prints the error to the stream.
-
- @param test: L{ITestCase} that raised the error.
- @param error: L{failure.Failure} containing the error.
- """
- error = self._getFailure(error)
- super(Reporter, self).addError(test, error)
- if self.realtime:
- error = self.errors[-1][1] # guarantee it's a Failure
- self._write(self._formatFailureTraceback(error))
-
-
- def write(self, format, *args):
- warnings.warn("write is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=2)
- self._write(format, *args)
-
-
- def _write(self, format, *args):
- """
- Safely write to the reporter's stream.
-
- @param format: A format string to write.
- @param *args: The arguments for the format string.
- """
- s = str(format)
- assert isinstance(s, type(''))
- if args:
- self._stream.write(s % args)
- else:
- self._stream.write(s)
- untilConcludes(self._stream.flush)
-
-
- def writeln(self, format, *args):
- warnings.warn("writeln is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=2)
- self._writeln(format, *args)
-
-
- def _writeln(self, format, *args):
- """
- Safely write a line to the reporter's stream. Newline is appended to
- the format string.
-
- @param format: A format string to write.
- @param *args: The arguments for the format string.
- """
- self._write(format, *args)
- self._write('\n')
-
-
- def upDownError(self, method, error, warn, printStatus):
- super(Reporter, self).upDownError(method, error, warn, printStatus)
- if warn:
- tbStr = self._formatFailureTraceback(error)
- log.msg(tbStr)
- msg = ("caught exception in %s, your TestCase is broken\n\n%s"
- % (method, tbStr))
- warnings.warn(msg, BrokenTestCaseWarning, stacklevel=2)
-
-
- def cleanupErrors(self, errs):
- super(Reporter, self).cleanupErrors(errs)
- warnings.warn("%s\n%s" % ("REACTOR UNCLEAN! traceback(s) follow: ",
- self._formatFailureTraceback(errs)),
- BrokenTestCaseWarning)
-
-
- def _trimFrames(self, frames):
- # when a SynchronousTestCase method fails synchronously, the stack looks
- # like this:
- # [0]: SynchronousTestCase._run
- # [1]: utils.runWithWarningsSuppressed
- # [2:-2]: code in the test method which failed
- # [-1]: unittst.fail
-
- # when a TestCase method fails synchronously, the stack looks like this:
- # [0]: defer.maybeDeferred()
- # [1]: utils.runWithWarningsSuppressed()
- # [2:-2]: code in the test method which failed
- # [-1]: unittest.fail
-
- # when a method fails inside a Deferred (i.e., when the test method
- # returns a Deferred, and that Deferred's errback fires), the stack
- # captured inside the resulting Failure looks like this:
- # [0]: defer.Deferred._runCallbacks
- # [1:-2]: code in the testmethod which failed
- # [-1]: unittest.fail
-
- # as a result, we want to trim either [maybeDeferred,runWWS] or
- # [Deferred._runCallbacks] or [SynchronousTestCase._run] from the front,
- # and trim the [unittest.fail] from the end.
-
- # There is also another case, when the test method is badly defined and
- # contains extra arguments.
-
- newFrames = list(frames)
-
- if len(frames) < 2:
- return newFrames
-
- firstMethod = newFrames[0][0]
- firstFile = os.path.splitext(os.path.basename(newFrames[0][1]))[0]
-
- secondMethod = newFrames[1][0]
- secondFile = os.path.splitext(os.path.basename(newFrames[1][1]))[0]
-
- supp = ("runWithWarningsSuppressed", "utils")
- syncCase = (("_run", "unittest"), supp)
- asyncCase = (("maybeDeferred", "defer"), supp)
-
- twoFrames = ((firstMethod, firstFile), (secondMethod, secondFile))
- if twoFrames in [syncCase, asyncCase]:
- newFrames = newFrames[2:]
- elif (firstMethod, firstFile) == ("_runCallbacks", "defer"):
- newFrames = newFrames[1:]
-
- if not newFrames:
- # The method fails before getting called, probably an argument problem
- return newFrames
-
- last = newFrames[-1]
- if (last[0].startswith('fail')
- and os.path.splitext(os.path.basename(last[1]))[0] == 'unittest'):
- newFrames = newFrames[:-1]
-
- return newFrames
-
-
- def _formatFailureTraceback(self, fail):
- if isinstance(fail, str):
- return fail.rstrip() + '\n'
- fail.frames, frames = self._trimFrames(fail.frames), fail.frames
- result = fail.getTraceback(detail=self.tbformat, elideFrameworkCode=True)
- fail.frames = frames
- return result
-
-
- def _groupResults(self, results, formatter):
- """
- Group tests together based on their results.
-
- @param results: An iterable of tuples of two or more elements. The
- first element of each tuple is a test case. The remaining
- elements describe the outcome of that test case.
-
- @param formatter: A callable which turns a test case result into a
- string. The elements after the first of the tuples in
- C{results} will be passed as positional arguments to
- C{formatter}.
-
- @return: A C{list} of two-tuples. The first element of each tuple
- is a unique string describing one result from at least one of
- the test cases in C{results}. The second element is a list of
- the test cases which had that result.
- """
- groups = OrderedDict()
- for content in results:
- case = content[0]
- outcome = content[1:]
- key = formatter(*outcome)
- groups.setdefault(key, []).append(case)
- return groups.items()
-
-
- def _printResults(self, flavor, errors, formatter):
- """
- Print a group of errors to the stream.
-
- @param flavor: A string indicating the kind of error (e.g. 'TODO').
- @param errors: A list of errors, often L{failure.Failure}s, but
- sometimes 'todo' errors.
- @param formatter: A callable that knows how to format the errors.
- """
- for reason, cases in self._groupResults(errors, formatter):
- self._writeln(self._doubleSeparator)
- self._writeln(flavor)
- self._write(reason)
- self._writeln('')
- for case in cases:
- self._writeln(case.id())
-
-
- def _printExpectedFailure(self, error, todo):
- return 'Reason: %r\n%s' % (todo.reason,
- self._formatFailureTraceback(error))
-
-
- def _printUnexpectedSuccess(self, todo):
- ret = 'Reason: %r\n' % (todo.reason,)
- if todo.errors:
- ret += 'Expected errors: %s\n' % (', '.join(todo.errors),)
- return ret
-
-
- def printErrors(self):
- """
- Print all of the non-success results in full to the stream.
- """
- warnings.warn("printErrors is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=2)
- self._printErrors()
-
-
- def _printErrors(self):
- """
- Print all of the non-success results to the stream in full.
- """
- self._write('\n')
- self._printResults('[SKIPPED]', self.skips, lambda x : '%s\n' % x)
- self._printResults('[TODO]', self.expectedFailures,
- self._printExpectedFailure)
- self._printResults('[FAIL]', self.failures,
- self._formatFailureTraceback)
- self._printResults('[ERROR]', self.errors,
- self._formatFailureTraceback)
- self._printResults('[SUCCESS!?!]', self.unexpectedSuccesses,
- self._printUnexpectedSuccess)
-
-
- def _getSummary(self):
- """
- Return a formatted count of tests status results.
- """
- summaries = []
- for stat in ("skips", "expectedFailures", "failures", "errors",
- "unexpectedSuccesses"):
- num = len(getattr(self, stat))
- if num:
- summaries.append('%s=%d' % (stat, num))
- if self.successes:
- summaries.append('successes=%d' % (self.successes,))
- summary = (summaries and ' ('+', '.join(summaries)+')') or ''
- return summary
-
-
- def printSummary(self):
- """
- Print a line summarising the test results to the stream.
- """
- warnings.warn("printSummary is deprecated in Twisted 8.0.",
- category=DeprecationWarning, stacklevel=2)
- self._printSummary()
-
-
- def _printSummary(self):
- """
- Print a line summarising the test results to the stream.
- """
- summary = self._getSummary()
- if self.wasSuccessful():
- status = "PASSED"
- else:
- status = "FAILED"
- self._write("%s%s\n", status, summary)
-
-
- def done(self):
- """
- Summarize the result of the test run.
-
- The summary includes a report of all of the errors, todos, skips and
- so forth that occurred during the run. It also includes the number of
- tests that were run and how long it took to run them (not including
- load time).
-
- Expects that L{_printErrors}, L{_writeln}, L{_write}, L{_printSummary}
- and L{_separator} are all implemented.
- """
- if self._publisher is not None:
- self._publisher.removeObserver(self._observeWarnings)
- self._printErrors()
- self._writeln(self._separator)
- if self._startTime is not None:
- self._writeln('Ran %d tests in %.3fs', self.testsRun,
- time.time() - self._startTime)
- self._write('\n')
- self._printSummary()
-
-
-
-class MinimalReporter(Reporter):
- """
- A minimalist reporter that prints only a summary of the test result, in
- the form of (timeTaken, #tests, #tests, #errors, #failures, #skips).
- """
-
- def _printErrors(self):
- """
- Don't print a detailed summary of errors. We only care about the
- counts.
- """
-
-
- def _printSummary(self):
- """
- Print out a one-line summary of the form:
- '%(runtime) %(number_of_tests) %(number_of_tests) %(num_errors)
- %(num_failures) %(num_skips)'
- """
- numTests = self.testsRun
- if self._startTime is not None:
- timing = self._getTime() - self._startTime
- else:
- timing = 0
- t = (timing, numTests, numTests,
- len(self.errors), len(self.failures), len(self.skips))
- self._writeln(' '.join(map(str, t)))
-
-
-
-class TextReporter(Reporter):
- """
- Simple reporter that prints a single character for each test as it runs,
- along with the standard Trial summary text.
- """
-
- def addSuccess(self, test):
- super(TextReporter, self).addSuccess(test)
- self._write('.')
-
-
- def addError(self, *args):
- super(TextReporter, self).addError(*args)
- self._write('E')
-
-
- def addFailure(self, *args):
- super(TextReporter, self).addFailure(*args)
- self._write('F')
-
-
- def addSkip(self, *args):
- super(TextReporter, self).addSkip(*args)
- self._write('S')
-
-
- def addExpectedFailure(self, *args):
- super(TextReporter, self).addExpectedFailure(*args)
- self._write('T')
-
-
- def addUnexpectedSuccess(self, *args):
- super(TextReporter, self).addUnexpectedSuccess(*args)
- self._write('!')
-
-
-
-class VerboseTextReporter(Reporter):
- """
- A verbose reporter that prints the name of each test as it is running.
-
- Each line is printed with the name of the test, followed by the result of
- that test.
- """
-
- # This is actually the bwverbose option
-
- def startTest(self, tm):
- self._write('%s ... ', tm.id())
- super(VerboseTextReporter, self).startTest(tm)
-
-
- def addSuccess(self, test):
- super(VerboseTextReporter, self).addSuccess(test)
- self._write('[OK]')
-
-
- def addError(self, *args):
- super(VerboseTextReporter, self).addError(*args)
- self._write('[ERROR]')
-
-
- def addFailure(self, *args):
- super(VerboseTextReporter, self).addFailure(*args)
- self._write('[FAILURE]')
-
-
- def addSkip(self, *args):
- super(VerboseTextReporter, self).addSkip(*args)
- self._write('[SKIPPED]')
-
-
- def addExpectedFailure(self, *args):
- super(VerboseTextReporter, self).addExpectedFailure(*args)
- self._write('[TODO]')
-
-
- def addUnexpectedSuccess(self, *args):
- super(VerboseTextReporter, self).addUnexpectedSuccess(*args)
- self._write('[SUCCESS!?!]')
-
-
- def stopTest(self, test):
- super(VerboseTextReporter, self).stopTest(test)
- self._write('\n')
-
-
-
-class TimingTextReporter(VerboseTextReporter):
- """
- Prints out each test as it is running, followed by the time taken for each
- test to run.
- """
-
- def stopTest(self, method):
- """
- Mark the test as stopped, and write the time it took to run the test
- to the stream.
- """
- super(TimingTextReporter, self).stopTest(method)
- self._write("(%.03f secs)\n" % self._lastTime)
-
-
-
-class _AnsiColorizer(object):
- """
- A colorizer is an object that loosely wraps around a stream, allowing
- callers to write text to the stream in a particular color.
-
- Colorizer classes must implement C{supported()} and C{write(text, color)}.
- """
- _colors = dict(black=30, red=31, green=32, yellow=33,
- blue=34, magenta=35, cyan=36, white=37)
-
- def __init__(self, stream):
- self.stream = stream
-
- def supported(cls, stream=sys.stdout):
- """
- A class method that returns True if the current platform supports
- coloring terminal output using this method. Returns False otherwise.
- """
- if not stream.isatty():
- return False # auto color only on TTYs
- try:
- import curses
- except ImportError:
- return False
- else:
- try:
- try:
- return curses.tigetnum("colors") > 2
- except curses.error:
- curses.setupterm()
- return curses.tigetnum("colors") > 2
- except:
- # guess false in case of error
- return False
- supported = classmethod(supported)
-
- def write(self, text, color):
- """
- Write the given text to the stream in the given color.
-
- @param text: Text to be written to the stream.
-
- @param color: A string label for a color. e.g. 'red', 'white'.
- """
- color = self._colors[color]
- self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text))
-
-
-class _Win32Colorizer(object):
- """
- See _AnsiColorizer docstring.
- """
- def __init__(self, stream):
- from win32console import GetStdHandle, STD_OUTPUT_HANDLE, \
- FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \
- FOREGROUND_INTENSITY
- red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN,
- FOREGROUND_BLUE, FOREGROUND_INTENSITY)
- self.stream = stream
- self.screenBuffer = GetStdHandle(STD_OUTPUT_HANDLE)
- self._colors = {
- 'normal': red | green | blue,
- 'red': red | bold,
- 'green': green | bold,
- 'blue': blue | bold,
- 'yellow': red | green | bold,
- 'magenta': red | blue | bold,
- 'cyan': green | blue | bold,
- 'white': red | green | blue | bold
- }
-
- def supported(cls, stream=sys.stdout):
- try:
- import win32console
- screenBuffer = win32console.GetStdHandle(
- win32console.STD_OUTPUT_HANDLE)
- except ImportError:
- return False
- import pywintypes
- try:
- screenBuffer.SetConsoleTextAttribute(
- win32console.FOREGROUND_RED |
- win32console.FOREGROUND_GREEN |
- win32console.FOREGROUND_BLUE)
- except pywintypes.error:
- return False
- else:
- return True
- supported = classmethod(supported)
-
- def write(self, text, color):
- color = self._colors[color]
- self.screenBuffer.SetConsoleTextAttribute(color)
- self.stream.write(text)
- self.screenBuffer.SetConsoleTextAttribute(self._colors['normal'])
-
-
-class _NullColorizer(object):
- """
- See _AnsiColorizer docstring.
- """
- def __init__(self, stream):
- self.stream = stream
-
- def supported(cls, stream=sys.stdout):
- return True
- supported = classmethod(supported)
-
- def write(self, text, color):
- self.stream.write(text)
-
-
-
-class SubunitReporter(object):
- """
- Reports test output via Subunit.
-
- @ivar _subunit: The subunit protocol client that we are wrapping.
-
- @ivar _successful: An internal variable, used to track whether we have
- received only successful results.
-
- @since: 10.0
- """
- implements(itrial.IReporter)
-
-
- def __init__(self, stream=sys.stdout, tbformat='default',
- realtime=False, publisher=None):
- """
- Construct a L{SubunitReporter}.
-
- @param stream: A file-like object representing the stream to print
- output to. Defaults to stdout.
- @param tbformat: The format for tracebacks. Ignored, since subunit
- always uses Python's standard format.
- @param realtime: Whether or not to print exceptions in the middle
- of the test results. Ignored, since subunit always does this.
- @param publisher: The log publisher which will be preserved for
- reporting events. Ignored, as it's not relevant to subunit.
- """
- if TestProtocolClient is None:
- raise Exception("Subunit not available")
- self._subunit = TestProtocolClient(stream)
- self._successful = True
-
-
- def done(self):
- """
- Record that the entire test suite run is finished.
-
- We do nothing, since a summary clause is irrelevant to the subunit
- protocol.
- """
- pass
-
-
- def shouldStop(self):
- """
- Whether or not the test runner should stop running tests.
- """
- return self._subunit.shouldStop
- shouldStop = property(shouldStop)
-
-
- def stop(self):
- """
- Signal that the test runner should stop running tests.
- """
- return self._subunit.stop()
-
-
- def wasSuccessful(self):
- """
- Has the test run been successful so far?
-
- @return: C{True} if we have received no reports of errors or failures,
- C{False} otherwise.
- """
- # Subunit has a bug in its implementation of wasSuccessful, see
- # https://bugs.edge.launchpad.net/subunit/+bug/491090, so we can't
- # simply forward it on.
- return self._successful
-
-
- def startTest(self, test):
- """
- Record that C{test} has started.
- """
- return self._subunit.startTest(test)
-
-
- def stopTest(self, test):
- """
- Record that C{test} has completed.
- """
- return self._subunit.stopTest(test)
-
-
- def addSuccess(self, test):
- """
- Record that C{test} was successful.
- """
- return self._subunit.addSuccess(test)
-
-
- def addSkip(self, test, reason):
- """
- Record that C{test} was skipped for C{reason}.
-
- Some versions of subunit don't have support for addSkip. In those
- cases, the skip is reported as a success.
-
- @param test: A unittest-compatible C{TestCase}.
- @param reason: The reason for it being skipped. The C{str()} of this
- object will be included in the subunit output stream.
- """
- addSkip = getattr(self._subunit, 'addSkip', None)
- if addSkip is None:
- self.addSuccess(test)
- else:
- self._subunit.addSkip(test, reason)
-
-
- def addError(self, test, err):
- """
- Record that C{test} failed with an unexpected error C{err}.
-
- Also marks the run as being unsuccessful, causing
- L{SubunitReporter.wasSuccessful} to return C{False}.
- """
- self._successful = False
- return self._subunit.addError(
- test, util.excInfoOrFailureToExcInfo(err))
-
-
- def addFailure(self, test, err):
- """
- Record that C{test} failed an assertion with the error C{err}.
-
- Also marks the run as being unsuccessful, causing
- L{SubunitReporter.wasSuccessful} to return C{False}.
- """
- self._successful = False
- return self._subunit.addFailure(
- test, util.excInfoOrFailureToExcInfo(err))
-
-
- def addExpectedFailure(self, test, failure, todo):
- """
- Record an expected failure from a test.
-
- Some versions of subunit do not implement this. For those versions, we
- record a success.
- """
- failure = util.excInfoOrFailureToExcInfo(failure)
- addExpectedFailure = getattr(self._subunit, 'addExpectedFailure', None)
- if addExpectedFailure is None:
- self.addSuccess(test)
- else:
- addExpectedFailure(test, failure)
-
-
- def addUnexpectedSuccess(self, test, todo):
- """
- Record an unexpected success.
-
- Since subunit has no way of expressing this concept, we record a
- success on the subunit stream.
- """
- # Not represented in pyunit/subunit.
- self.addSuccess(test)
-
-
-
-class TreeReporter(Reporter):
- """
- Print out the tests in the form a tree.
-
- Tests are indented according to which class and module they belong.
- Results are printed in ANSI color.
- """
-
- currentLine = ''
- indent = ' '
- columns = 79
-
- FAILURE = 'red'
- ERROR = 'red'
- TODO = 'blue'
- SKIP = 'blue'
- TODONE = 'red'
- SUCCESS = 'green'
-
- def __init__(self, stream=sys.stdout, *args, **kwargs):
- super(TreeReporter, self).__init__(stream, *args, **kwargs)
- self._lastTest = []
- for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]:
- if colorizer.supported(stream):
- self._colorizer = colorizer(stream)
- break
-
- def getDescription(self, test):
- """
- Return the name of the method which 'test' represents. This is
- what gets displayed in the leaves of the tree.
-
- e.g. getDescription(TestCase('test_foo')) ==> test_foo
- """
- return test.id().split('.')[-1]
-
- def addSuccess(self, test):
- super(TreeReporter, self).addSuccess(test)
- self.endLine('[OK]', self.SUCCESS)
-
- def addError(self, *args):
- super(TreeReporter, self).addError(*args)
- self.endLine('[ERROR]', self.ERROR)
-
- def addFailure(self, *args):
- super(TreeReporter, self).addFailure(*args)
- self.endLine('[FAIL]', self.FAILURE)
-
- def addSkip(self, *args):
- super(TreeReporter, self).addSkip(*args)
- self.endLine('[SKIPPED]', self.SKIP)
-
- def addExpectedFailure(self, *args):
- super(TreeReporter, self).addExpectedFailure(*args)
- self.endLine('[TODO]', self.TODO)
-
- def addUnexpectedSuccess(self, *args):
- super(TreeReporter, self).addUnexpectedSuccess(*args)
- self.endLine('[SUCCESS!?!]', self.TODONE)
-
- def _write(self, format, *args):
- if args:
- format = format % args
- self.currentLine = format
- super(TreeReporter, self)._write(self.currentLine)
-
-
- def _getPreludeSegments(self, testID):
- """
- Return a list of all non-leaf segments to display in the tree.
-
- Normally this is the module and class name.
- """
- segments = testID.split('.')[:-1]
- if len(segments) == 0:
- return segments
- segments = [
- seg for seg in '.'.join(segments[:-1]), segments[-1]
- if len(seg) > 0]
- return segments
-
-
- def _testPrelude(self, testID):
- """
- Write the name of the test to the stream, indenting it appropriately.
-
- If the test is the first test in a new 'branch' of the tree, also
- write all of the parents in that branch.
- """
- segments = self._getPreludeSegments(testID)
- indentLevel = 0
- for seg in segments:
- if indentLevel < len(self._lastTest):
- if seg != self._lastTest[indentLevel]:
- self._write('%s%s\n' % (self.indent * indentLevel, seg))
- else:
- self._write('%s%s\n' % (self.indent * indentLevel, seg))
- indentLevel += 1
- self._lastTest = segments
-
-
- def cleanupErrors(self, errs):
- self._colorizer.write(' cleanup errors', self.ERROR)
- self.endLine('[ERROR]', self.ERROR)
- super(TreeReporter, self).cleanupErrors(errs)
-
- def upDownError(self, method, error, warn, printStatus):
- self._colorizer.write(" %s" % method, self.ERROR)
- if printStatus:
- self.endLine('[ERROR]', self.ERROR)
- super(TreeReporter, self).upDownError(method, error, warn, printStatus)
-
- def startTest(self, test):
- """
- Called when C{test} starts. Writes the tests name to the stream using
- a tree format.
- """
- self._testPrelude(test.id())
- self._write('%s%s ... ' % (self.indent * (len(self._lastTest)),
- self.getDescription(test)))
- super(TreeReporter, self).startTest(test)
-
-
- def endLine(self, message, color):
- """
- Print 'message' in the given color.
-
- @param message: A string message, usually '[OK]' or something similar.
- @param color: A string color, 'red', 'green' and so forth.
- """
- spaces = ' ' * (self.columns - len(self.currentLine) - len(message))
- super(TreeReporter, self)._write(spaces)
- self._colorizer.write(message, color)
- super(TreeReporter, self)._write("\n")
-
-
- def _printSummary(self):
- """
- Print a line summarising the test results to the stream, and color the
- status result.
- """
- summary = self._getSummary()
- if self.wasSuccessful():
- status = "PASSED"
- color = self.SUCCESS
- else:
- status = "FAILED"
- color = self.FAILURE
- self._colorizer.write(status, color)
- self._write("%s\n", summary)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/runner.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/runner.py
deleted file mode 100755
index 68663b5e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/runner.py
+++ /dev/null
@@ -1,861 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_runner -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A miscellany of code used to run Trial tests.
-
-Maintainer: Jonathan Lange
-"""
-
-__all__ = [
- 'suiteVisit', 'TestSuite',
-
- 'DestructiveTestSuite', 'DryRunVisitor',
- 'ErrorHolder', 'LoggedSuite', 'PyUnitTestCase',
- 'TestHolder', 'TestLoader', 'TrialRunner', 'TrialSuite',
-
- 'filenameToModule', 'isPackage', 'isPackageDirectory', 'isTestCase',
- 'name', 'samefile', 'NOT_IN_TEST',
- ]
-
-import pdb
-import os, types, warnings, sys, inspect, imp
-import doctest, time
-
-from twisted.python import reflect, log, failure, modules, filepath
-from twisted.python.compat import set
-
-from twisted.internet import defer
-from twisted.trial import util, unittest
-from twisted.trial.itrial import ITestCase
-from twisted.trial.reporter import UncleanWarningsReporterWrapper
-
-# These are imported so that they remain in the public API for t.trial.runner
-from twisted.trial.unittest import suiteVisit, TestSuite
-
-from zope.interface import implements
-
-pyunit = __import__('unittest')
-
-
-
-def isPackage(module):
- """Given an object return True if the object looks like a package"""
- if not isinstance(module, types.ModuleType):
- return False
- basename = os.path.splitext(os.path.basename(module.__file__))[0]
- return basename == '__init__'
-
-
-def isPackageDirectory(dirname):
- """Is the directory at path 'dirname' a Python package directory?
- Returns the name of the __init__ file (it may have a weird extension)
- if dirname is a package directory. Otherwise, returns False"""
- for ext in zip(*imp.get_suffixes())[0]:
- initFile = '__init__' + ext
- if os.path.exists(os.path.join(dirname, initFile)):
- return initFile
- return False
-
-
-def samefile(filename1, filename2):
- """
- A hacky implementation of C{os.path.samefile}. Used by L{filenameToModule}
- when the platform doesn't provide C{os.path.samefile}. Do not use this.
- """
- return os.path.abspath(filename1) == os.path.abspath(filename2)
-
-
-def filenameToModule(fn):
- """
- Given a filename, do whatever possible to return a module object matching
- that file.
-
- If the file in question is a module in Python path, properly import and
- return that module. Otherwise, load the source manually.
-
- @param fn: A filename.
- @return: A module object.
- @raise ValueError: If C{fn} does not exist.
- """
- if not os.path.exists(fn):
- raise ValueError("%r doesn't exist" % (fn,))
- try:
- ret = reflect.namedAny(reflect.filenameToModuleName(fn))
- except (ValueError, AttributeError):
- # Couldn't find module. The file 'fn' is not in PYTHONPATH
- return _importFromFile(fn)
- # ensure that the loaded module matches the file
- retFile = os.path.splitext(ret.__file__)[0] + '.py'
- # not all platforms (e.g. win32) have os.path.samefile
- same = getattr(os.path, 'samefile', samefile)
- if os.path.isfile(fn) and not same(fn, retFile):
- del sys.modules[ret.__name__]
- ret = _importFromFile(fn)
- return ret
-
-
-def _importFromFile(fn, moduleName=None):
- fn = _resolveDirectory(fn)
- if not moduleName:
- moduleName = os.path.splitext(os.path.split(fn)[-1])[0]
- if moduleName in sys.modules:
- return sys.modules[moduleName]
- fd = open(fn, 'r')
- try:
- module = imp.load_source(moduleName, fn, fd)
- finally:
- fd.close()
- return module
-
-
-def _resolveDirectory(fn):
- if os.path.isdir(fn):
- initFile = isPackageDirectory(fn)
- if initFile:
- fn = os.path.join(fn, initFile)
- else:
- raise ValueError('%r is not a package directory' % (fn,))
- return fn
-
-
-def _getMethodNameInClass(method):
- """
- Find the attribute name on the method's class which refers to the method.
-
- For some methods, notably decorators which have not had __name__ set correctly:
-
- getattr(method.im_class, method.__name__) != method
- """
- if getattr(method.im_class, method.__name__, object()) != method:
- for alias in dir(method.im_class):
- if getattr(method.im_class, alias, object()) == method:
- return alias
- return method.__name__
-
-
-class DestructiveTestSuite(TestSuite):
- """
- A test suite which remove the tests once run, to minimize memory usage.
- """
-
- def run(self, result):
- """
- Almost the same as L{TestSuite.run}, but with C{self._tests} being
- empty at the end.
- """
- while self._tests:
- if result.shouldStop:
- break
- test = self._tests.pop(0)
- test(result)
- return result
-
-
-
-# When an error occurs outside of any test, the user will see this string
-# in place of a test's name.
-NOT_IN_TEST = "<not in test>"
-
-
-
-class LoggedSuite(TestSuite):
- """
- Any errors logged in this suite will be reported to the L{TestResult}
- object.
- """
-
- def run(self, result):
- """
- Run the suite, storing all errors in C{result}. If an error is logged
- while no tests are running, then it will be added as an error to
- C{result}.
-
- @param result: A L{TestResult} object.
- """
- observer = unittest._logObserver
- observer._add()
- super(LoggedSuite, self).run(result)
- observer._remove()
- for error in observer.getErrors():
- result.addError(TestHolder(NOT_IN_TEST), error)
- observer.flushErrors()
-
-
-
-class PyUnitTestCase(object):
- """
- DEPRECATED in Twisted 8.0.
-
- This class decorates the pyunit.TestCase class, mainly to work around the
- differences between unittest in Python 2.3, 2.4, and 2.5. These
- differences are::
-
- - The way doctest unittests describe themselves
- - Where the implementation of TestCase.run is (used to be in __call__)
- - Where the test method name is kept (mangled-private or non-mangled
- private variable)
-
- It also implements visit, which we like.
- """
-
- def __init__(self, test):
- warnings.warn("Deprecated in Twisted 8.0.",
- category=DeprecationWarning)
- self._test = test
- test.id = self.id
-
- def id(self):
- cls = self._test.__class__
- tmn = getattr(self._test, '_TestCase__testMethodName', None)
- if tmn is None:
- # python2.5's 'unittest' module is more sensible; but different.
- tmn = self._test._testMethodName
- return (cls.__module__ + '.' + cls.__name__ + '.' +
- tmn)
-
- def __repr__(self):
- return 'PyUnitTestCase<%r>'%(self.id(),)
-
- def __call__(self, results):
- return self._test(results)
-
-
- def visit(self, visitor):
- """
- Call the given visitor with the original, standard library, test case
- that C{self} wraps. See L{unittest.TestCase.visit}.
-
- Deprecated in Twisted 8.0.
- """
- warnings.warn("Test visitors deprecated in Twisted 8.0",
- category=DeprecationWarning)
- visitor(self._test)
-
-
- def __getattr__(self, name):
- return getattr(self._test, name)
-
-
-
-class TrialSuite(TestSuite):
- """
- Suite to wrap around every single test in a C{trial} run. Used internally
- by Trial to set up things necessary for Trial tests to work, regardless of
- what context they are run in.
- """
-
- def __init__(self, tests=()):
- suite = LoggedSuite(tests)
- super(TrialSuite, self).__init__([suite])
-
-
- def _bail(self):
- from twisted.internet import reactor
- d = defer.Deferred()
- reactor.addSystemEventTrigger('after', 'shutdown',
- lambda: d.callback(None))
- reactor.fireSystemEvent('shutdown') # radix's suggestion
- # As long as TestCase does crap stuff with the reactor we need to
- # manually shutdown the reactor here, and that requires util.wait
- # :(
- # so that the shutdown event completes
- unittest.TestCase('mktemp')._wait(d)
-
- def run(self, result):
- try:
- TestSuite.run(self, result)
- finally:
- self._bail()
-
-
-def name(thing):
- """
- @param thing: an object from modules (instance of PythonModule,
- PythonAttribute), a TestCase subclass, or an instance of a TestCase.
- """
- if isTestCase(thing):
- # TestCase subclass
- theName = reflect.qual(thing)
- else:
- # thing from trial, or thing from modules.
- # this monstrosity exists so that modules' objects do not have to
- # implement id(). -jml
- try:
- theName = thing.id()
- except AttributeError:
- theName = thing.name
- return theName
-
-
-def isTestCase(obj):
- """
- @return: C{True} if C{obj} is a class that contains test cases, C{False}
- otherwise. Used to find all the tests in a module.
- """
- try:
- return issubclass(obj, pyunit.TestCase)
- except TypeError:
- return False
-
-
-
-class TestHolder(object):
- """
- Placeholder for a L{TestCase} inside a reporter. As far as a L{TestResult}
- is concerned, this looks exactly like a unit test.
- """
-
- implements(ITestCase)
-
- failureException = None
-
- def __init__(self, description):
- """
- @param description: A string to be displayed L{TestResult}.
- """
- self.description = description
-
-
- def __call__(self, result):
- return self.run(result)
-
-
- def id(self):
- return self.description
-
-
- def countTestCases(self):
- return 0
-
-
- def run(self, result):
- """
- This test is just a placeholder. Run the test successfully.
-
- @param result: The C{TestResult} to store the results in.
- @type result: L{twisted.trial.itrial.ITestResult}.
- """
- result.startTest(self)
- result.addSuccess(self)
- result.stopTest(self)
-
-
- def shortDescription(self):
- return self.description
-
-
-
-class ErrorHolder(TestHolder):
- """
- Used to insert arbitrary errors into a test suite run. Provides enough
- methods to look like a C{TestCase}, however, when it is run, it simply adds
- an error to the C{TestResult}. The most common use-case is for when a
- module fails to import.
- """
-
- def __init__(self, description, error):
- """
- @param description: A string used by C{TestResult}s to identify this
- error. Generally, this is the name of a module that failed to import.
-
- @param error: The error to be added to the result. Can be an `exc_info`
- tuple or a L{twisted.python.failure.Failure}.
- """
- super(ErrorHolder, self).__init__(description)
- self.error = util.excInfoOrFailureToExcInfo(error)
-
-
- def __repr__(self):
- return "<ErrorHolder description=%r error=%s%s>" % (
- # Format the exception type and arguments explicitly, as exception
- # objects do not have nice looking string formats on Python 2.4.
- self.description, self.error[0].__name__, self.error[1].args)
-
-
- def run(self, result):
- """
- Run the test, reporting the error.
-
- @param result: The C{TestResult} to store the results in.
- @type result: L{twisted.trial.itrial.ITestResult}.
- """
- result.startTest(self)
- result.addError(self, self.error)
- result.stopTest(self)
-
-
- def visit(self, visitor):
- """
- See L{unittest.TestCase.visit}.
- """
- visitor(self)
-
-
-
-class TestLoader(object):
- """
- I find tests inside function, modules, files -- whatever -- then return
- them wrapped inside a Test (either a L{TestSuite} or a L{TestCase}).
-
- @ivar methodPrefix: A string prefix. C{TestLoader} will assume that all the
- methods in a class that begin with C{methodPrefix} are test cases.
-
- @ivar modulePrefix: A string prefix. Every module in a package that begins
- with C{modulePrefix} is considered a module full of tests.
-
- @ivar forceGarbageCollection: A flag applied to each C{TestCase} loaded.
- See L{unittest.TestCase} for more information.
-
- @ivar sorter: A key function used to sort C{TestCase}s, test classes,
- modules and packages.
-
- @ivar suiteFactory: A callable which is passed a list of tests (which
- themselves may be suites of tests). Must return a test suite.
- """
-
- methodPrefix = 'test'
- modulePrefix = 'test_'
-
- def __init__(self):
- self.suiteFactory = TestSuite
- self.sorter = name
- self._importErrors = []
-
- def sort(self, xs):
- """
- Sort the given things using L{sorter}.
-
- @param xs: A list of test cases, class or modules.
- """
- return sorted(xs, key=self.sorter)
-
- def findTestClasses(self, module):
- """Given a module, return all Trial test classes"""
- classes = []
- for name, val in inspect.getmembers(module):
- if isTestCase(val):
- classes.append(val)
- return self.sort(classes)
-
- def findByName(self, name):
- """
- Return a Python object given a string describing it.
-
- @param name: a string which may be either a filename or a
- fully-qualified Python name.
-
- @return: If C{name} is a filename, return the module. If C{name} is a
- fully-qualified Python name, return the object it refers to.
- """
- if os.path.exists(name):
- return filenameToModule(name)
- return reflect.namedAny(name)
-
- def loadModule(self, module):
- """
- Return a test suite with all the tests from a module.
-
- Included are TestCase subclasses and doctests listed in the module's
- __doctests__ module. If that's not good for you, put a function named
- either C{testSuite} or C{test_suite} in your module that returns a
- TestSuite, and I'll use the results of that instead.
-
- If C{testSuite} and C{test_suite} are both present, then I'll use
- C{testSuite}.
- """
- ## XXX - should I add an optional parameter to disable the check for
- ## a custom suite.
- ## OR, should I add another method
- if not isinstance(module, types.ModuleType):
- raise TypeError("%r is not a module" % (module,))
- if hasattr(module, 'testSuite'):
- return module.testSuite()
- elif hasattr(module, 'test_suite'):
- return module.test_suite()
- suite = self.suiteFactory()
- for testClass in self.findTestClasses(module):
- suite.addTest(self.loadClass(testClass))
- if not hasattr(module, '__doctests__'):
- return suite
- docSuite = self.suiteFactory()
- for doctest in module.__doctests__:
- docSuite.addTest(self.loadDoctests(doctest))
- return self.suiteFactory([suite, docSuite])
- loadTestsFromModule = loadModule
-
- def loadClass(self, klass):
- """
- Given a class which contains test cases, return a sorted list of
- C{TestCase} instances.
- """
- if not (isinstance(klass, type) or isinstance(klass, types.ClassType)):
- raise TypeError("%r is not a class" % (klass,))
- if not isTestCase(klass):
- raise ValueError("%r is not a test case" % (klass,))
- names = self.getTestCaseNames(klass)
- tests = self.sort([self._makeCase(klass, self.methodPrefix+name)
- for name in names])
- return self.suiteFactory(tests)
- loadTestsFromTestCase = loadClass
-
- def getTestCaseNames(self, klass):
- """
- Given a class that contains C{TestCase}s, return a list of names of
- methods that probably contain tests.
- """
- return reflect.prefixedMethodNames(klass, self.methodPrefix)
-
- def loadMethod(self, method):
- """
- Given a method of a C{TestCase} that represents a test, return a
- C{TestCase} instance for that test.
- """
- if not isinstance(method, types.MethodType):
- raise TypeError("%r not a method" % (method,))
- return self._makeCase(method.im_class, _getMethodNameInClass(method))
-
- def _makeCase(self, klass, methodName):
- return klass(methodName)
-
- def loadPackage(self, package, recurse=False):
- """
- Load tests from a module object representing a package, and return a
- TestSuite containing those tests.
-
- Tests are only loaded from modules whose name begins with 'test_'
- (or whatever C{modulePrefix} is set to).
-
- @param package: a types.ModuleType object (or reasonable facsimilie
- obtained by importing) which may contain tests.
-
- @param recurse: A boolean. If True, inspect modules within packages
- within the given package (and so on), otherwise, only inspect modules
- in the package itself.
-
- @raise: TypeError if 'package' is not a package.
-
- @return: a TestSuite created with my suiteFactory, containing all the
- tests.
- """
- if not isPackage(package):
- raise TypeError("%r is not a package" % (package,))
- pkgobj = modules.getModule(package.__name__)
- if recurse:
- discovery = pkgobj.walkModules()
- else:
- discovery = pkgobj.iterModules()
- discovered = []
- for disco in discovery:
- if disco.name.split(".")[-1].startswith(self.modulePrefix):
- discovered.append(disco)
- suite = self.suiteFactory()
- for modinfo in self.sort(discovered):
- try:
- module = modinfo.load()
- except:
- thingToAdd = ErrorHolder(modinfo.name, failure.Failure())
- else:
- thingToAdd = self.loadModule(module)
- suite.addTest(thingToAdd)
- return suite
-
- def loadDoctests(self, module):
- """
- Return a suite of tests for all the doctests defined in C{module}.
-
- @param module: A module object or a module name.
- """
- if isinstance(module, str):
- try:
- module = reflect.namedAny(module)
- except:
- return ErrorHolder(module, failure.Failure())
- if not inspect.ismodule(module):
- warnings.warn("trial only supports doctesting modules")
- return
- extraArgs = {}
- if sys.version_info > (2, 4):
- # Work around Python issue2604: DocTestCase.tearDown clobbers globs
- def saveGlobals(test):
- """
- Save C{test.globs} and replace it with a copy so that if
- necessary, the original will be available for the next test
- run.
- """
- test._savedGlobals = getattr(test, '_savedGlobals', test.globs)
- test.globs = test._savedGlobals.copy()
- extraArgs['setUp'] = saveGlobals
- return doctest.DocTestSuite(module, **extraArgs)
-
- def loadAnything(self, thing, recurse=False):
- """
- Given a Python object, return whatever tests that are in it. Whatever
- 'in' might mean.
-
- @param thing: A Python object. A module, method, class or package.
- @param recurse: Whether or not to look in subpackages of packages.
- Defaults to False.
-
- @return: A C{TestCase} or C{TestSuite}.
- """
- if isinstance(thing, types.ModuleType):
- if isPackage(thing):
- return self.loadPackage(thing, recurse)
- return self.loadModule(thing)
- elif isinstance(thing, types.ClassType):
- return self.loadClass(thing)
- elif isinstance(thing, type):
- return self.loadClass(thing)
- elif isinstance(thing, types.MethodType):
- return self.loadMethod(thing)
- raise TypeError("No loader for %r. Unrecognized type" % (thing,))
-
- def loadByName(self, name, recurse=False):
- """
- Given a string representing a Python object, return whatever tests
- are in that object.
-
- If C{name} is somehow inaccessible (e.g. the module can't be imported,
- there is no Python object with that name etc) then return an
- L{ErrorHolder}.
-
- @param name: The fully-qualified name of a Python object.
- """
- try:
- thing = self.findByName(name)
- except:
- return ErrorHolder(name, failure.Failure())
- return self.loadAnything(thing, recurse)
- loadTestsFromName = loadByName
-
- def loadByNames(self, names, recurse=False):
- """
- Construct a TestSuite containing all the tests found in 'names', where
- names is a list of fully qualified python names and/or filenames. The
- suite returned will have no duplicate tests, even if the same object
- is named twice.
- """
- things = []
- errors = []
- for name in names:
- try:
- things.append(self.findByName(name))
- except:
- errors.append(ErrorHolder(name, failure.Failure()))
- suites = [self.loadAnything(thing, recurse)
- for thing in self._uniqueTests(things)]
- suites.extend(errors)
- return self.suiteFactory(suites)
-
-
- def _uniqueTests(self, things):
- """
- Gather unique suite objects from loaded things. This will guarantee
- uniqueness of inherited methods on TestCases which would otherwise hash
- to same value and collapse to one test unexpectedly if using simpler
- means: e.g. set().
- """
- entries = []
- for thing in things:
- if isinstance(thing, types.MethodType):
- entries.append((thing, thing.im_class))
- else:
- entries.append((thing,))
- return [entry[0] for entry in set(entries)]
-
-
-
-class DryRunVisitor(object):
- """
- A visitor that makes a reporter think that every test visited has run
- successfully.
- """
-
- def __init__(self, reporter):
- """
- @param reporter: A C{TestResult} object.
- """
- self.reporter = reporter
-
-
- def markSuccessful(self, testCase):
- """
- Convince the reporter that this test has been run successfully.
- """
- self.reporter.startTest(testCase)
- self.reporter.addSuccess(testCase)
- self.reporter.stopTest(testCase)
-
-
-
-class TrialRunner(object):
- """
- A specialised runner that the trial front end uses.
- """
-
- DEBUG = 'debug'
- DRY_RUN = 'dry-run'
-
- def _getDebugger(self):
- dbg = pdb.Pdb()
- try:
- import readline
- except ImportError:
- print "readline module not available"
- sys.exc_clear()
- for path in ('.pdbrc', 'pdbrc'):
- if os.path.exists(path):
- try:
- rcFile = file(path, 'r')
- except IOError:
- sys.exc_clear()
- else:
- dbg.rcLines.extend(rcFile.readlines())
- return dbg
-
-
- def _setUpTestdir(self):
- self._tearDownLogFile()
- currentDir = os.getcwd()
- base = filepath.FilePath(self.workingDirectory)
- testdir, self._testDirLock = util._unusedTestDirectory(base)
- os.chdir(testdir.path)
- return currentDir
-
-
- def _tearDownTestdir(self, oldDir):
- os.chdir(oldDir)
- self._testDirLock.unlock()
-
-
- _log = log
- def _makeResult(self):
- reporter = self.reporterFactory(self.stream, self.tbformat,
- self.rterrors, self._log)
- if self.uncleanWarnings:
- reporter = UncleanWarningsReporterWrapper(reporter)
- return reporter
-
- def __init__(self, reporterFactory,
- mode=None,
- logfile='test.log',
- stream=sys.stdout,
- profile=False,
- tracebackFormat='default',
- realTimeErrors=False,
- uncleanWarnings=False,
- workingDirectory=None,
- forceGarbageCollection=False):
- self.reporterFactory = reporterFactory
- self.logfile = logfile
- self.mode = mode
- self.stream = stream
- self.tbformat = tracebackFormat
- self.rterrors = realTimeErrors
- self.uncleanWarnings = uncleanWarnings
- self._result = None
- self.workingDirectory = workingDirectory or '_trial_temp'
- self._logFileObserver = None
- self._logFileObject = None
- self._forceGarbageCollection = forceGarbageCollection
- if profile:
- self.run = util.profiled(self.run, 'profile.data')
-
- def _tearDownLogFile(self):
- if self._logFileObserver is not None:
- log.removeObserver(self._logFileObserver.emit)
- self._logFileObserver = None
- if self._logFileObject is not None:
- self._logFileObject.close()
- self._logFileObject = None
-
- def _setUpLogFile(self):
- self._tearDownLogFile()
- if self.logfile == '-':
- logFile = sys.stdout
- else:
- logFile = file(self.logfile, 'a')
- self._logFileObject = logFile
- self._logFileObserver = log.FileLogObserver(logFile)
- log.startLoggingWithObserver(self._logFileObserver.emit, 0)
-
-
- def run(self, test):
- """
- Run the test or suite and return a result object.
- """
- test = unittest.decorate(test, ITestCase)
- if self._forceGarbageCollection:
- test = unittest.decorate(
- test, unittest._ForceGarbageCollectionDecorator)
- return self._runWithoutDecoration(test)
-
-
- def _runWithoutDecoration(self, test):
- """
- Private helper that runs the given test but doesn't decorate it.
- """
- result = self._makeResult()
- # decorate the suite with reactor cleanup and log starting
- # This should move out of the runner and be presumed to be
- # present
- suite = TrialSuite([test])
- startTime = time.time()
- if self.mode == self.DRY_RUN:
- for single in unittest._iterateTests(suite):
- result.startTest(single)
- result.addSuccess(single)
- result.stopTest(single)
- else:
- if self.mode == self.DEBUG:
- # open question - should this be self.debug() instead.
- debugger = self._getDebugger()
- run = lambda: debugger.runcall(suite.run, result)
- else:
- run = lambda: suite.run(result)
-
- oldDir = self._setUpTestdir()
- try:
- self._setUpLogFile()
- run()
- finally:
- self._tearDownLogFile()
- self._tearDownTestdir(oldDir)
-
- endTime = time.time()
- done = getattr(result, 'done', None)
- if done is None:
- warnings.warn(
- "%s should implement done() but doesn't. Falling back to "
- "printErrors() and friends." % reflect.qual(result.__class__),
- category=DeprecationWarning, stacklevel=3)
- result.printErrors()
- result.writeln(result.separator)
- result.writeln('Ran %d tests in %.3fs', result.testsRun,
- endTime - startTime)
- result.write('\n')
- result.printSummary()
- else:
- result.done()
- return result
-
-
- def runUntilFailure(self, test):
- """
- Repeatedly run C{test} until it fails.
- """
- count = 0
- while True:
- count += 1
- self.stream.write("Test Pass %d\n" % (count,))
- if count == 1:
- result = self.run(test)
- else:
- result = self._runWithoutDecoration(test)
- if result.testsRun == 0:
- break
- if not result.wasSuccessful():
- break
- return result
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/__init__.py
deleted file mode 100755
index e2395372..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""unittesting framework tests"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/detests.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/detests.py
deleted file mode 100755
index cc08821f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/detests.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for Deferred handling by L{twisted.trial.unittest.TestCase}.
-"""
-
-from twisted.trial import unittest
-from twisted.internet import defer, threads, reactor
-
-
-class DeferredSetUpOK(unittest.TestCase):
- def setUp(self):
- d = defer.succeed('value')
- d.addCallback(self._cb_setUpCalled)
- return d
-
- def _cb_setUpCalled(self, ignored):
- self._setUpCalled = True
-
- def test_ok(self):
- self.failUnless(self._setUpCalled)
-
-
-class DeferredSetUpFail(unittest.TestCase):
- testCalled = False
-
- def setUp(self):
- return defer.fail(unittest.FailTest('i fail'))
-
- def test_ok(self):
- DeferredSetUpFail.testCalled = True
- self.fail("I should not get called")
-
-
-class DeferredSetUpCallbackFail(unittest.TestCase):
- testCalled = False
-
- def setUp(self):
- d = defer.succeed('value')
- d.addCallback(self._cb_setUpCalled)
- return d
-
- def _cb_setUpCalled(self, ignored):
- self.fail('deliberate failure')
-
- def test_ok(self):
- DeferredSetUpCallbackFail.testCalled = True
-
-
-class DeferredSetUpError(unittest.TestCase):
- testCalled = False
-
- def setUp(self):
- return defer.fail(RuntimeError('deliberate error'))
-
- def test_ok(self):
- DeferredSetUpError.testCalled = True
-
-
-class DeferredSetUpNeverFire(unittest.TestCase):
- testCalled = False
-
- def setUp(self):
- return defer.Deferred()
-
- def test_ok(self):
- DeferredSetUpNeverFire.testCalled = True
-
-
-class DeferredSetUpSkip(unittest.TestCase):
- testCalled = False
-
- def setUp(self):
- d = defer.succeed('value')
- d.addCallback(self._cb1)
- return d
-
- def _cb1(self, ignored):
- raise unittest.SkipTest("skip me")
-
- def test_ok(self):
- DeferredSetUpSkip.testCalled = True
-
-
-class DeferredTests(unittest.TestCase):
- touched = False
-
- def _cb_fail(self, reason):
- self.fail(reason)
-
- def _cb_error(self, reason):
- raise RuntimeError(reason)
-
- def _cb_skip(self, reason):
- raise unittest.SkipTest(reason)
-
- def _touchClass(self, ignored):
- self.__class__.touched = True
-
- def setUp(self):
- self.__class__.touched = False
-
- def test_pass(self):
- return defer.succeed('success')
-
- def test_passGenerated(self):
- self._touchClass(None)
- yield None
- test_passGenerated = defer.deferredGenerator(test_passGenerated)
-
- def test_fail(self):
- return defer.fail(self.failureException('I fail'))
-
- def test_failureInCallback(self):
- d = defer.succeed('fail')
- d.addCallback(self._cb_fail)
- return d
-
- def test_errorInCallback(self):
- d = defer.succeed('error')
- d.addCallback(self._cb_error)
- return d
-
- def test_skip(self):
- d = defer.succeed('skip')
- d.addCallback(self._cb_skip)
- d.addCallback(self._touchClass)
- return d
-
- def test_thread(self):
- return threads.deferToThread(lambda : None)
-
- def test_expectedFailure(self):
- d = defer.succeed('todo')
- d.addCallback(self._cb_error)
- return d
- test_expectedFailure.todo = "Expected failure"
-
-
-class TimeoutTests(unittest.TestCase):
- timedOut = None
-
- def test_pass(self):
- d = defer.Deferred()
- reactor.callLater(0, d.callback, 'hoorj!')
- return d
- test_pass.timeout = 2
-
- def test_passDefault(self):
- # test default timeout
- d = defer.Deferred()
- reactor.callLater(0, d.callback, 'hoorj!')
- return d
-
- def test_timeout(self):
- return defer.Deferred()
- test_timeout.timeout = 0.1
-
- def test_timeoutZero(self):
- return defer.Deferred()
- test_timeoutZero.timeout = 0
-
- def test_expectedFailure(self):
- return defer.Deferred()
- test_expectedFailure.timeout = 0.1
- test_expectedFailure.todo = "i will get it right, eventually"
-
- def test_skip(self):
- return defer.Deferred()
- test_skip.timeout = 0.1
- test_skip.skip = "i will get it right, eventually"
-
- def test_errorPropagation(self):
- def timedOut(err):
- self.__class__.timedOut = err
- return err
- d = defer.Deferred()
- d.addErrback(timedOut)
- return d
- test_errorPropagation.timeout = 0.1
-
- def test_calledButNeverCallback(self):
- d = defer.Deferred()
- def neverFire(r):
- return defer.Deferred()
- d.addCallback(neverFire)
- d.callback(1)
- return d
- test_calledButNeverCallback.timeout = 0.1
-
-
-class TestClassTimeoutAttribute(unittest.TestCase):
- timeout = 0.2
-
- def setUp(self):
- self.d = defer.Deferred()
-
- def testMethod(self):
- self.methodCalled = True
- return self.d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/erroneous.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/erroneous.py
deleted file mode 100755
index 6c0f8408..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/erroneous.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_tests -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Definitions of test cases with various interesting error-related behaviors, to
-be used by test modules to exercise different features of trial's test runner.
-
-See the L{twisted.trial.test.test_tests} module docstring for details about how
-this code is arranged.
-"""
-
-from __future__ import division
-
-from twisted.trial import unittest, util
-from twisted.internet import reactor, protocol, defer
-
-
-class FoolishError(Exception):
- pass
-
-
-
-class FailureInSetUpMixin(object):
- def setUp(self):
- raise FoolishError, "I am a broken setUp method"
-
- def test_noop(self):
- pass
-
-
-
-class SynchronousTestFailureInSetUp(
- FailureInSetUpMixin, unittest.SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTestFailureInSetUp(
- FailureInSetUpMixin, unittest.TestCase):
- pass
-
-
-
-class FailureInTearDownMixin(object):
- def tearDown(self):
- raise FoolishError, "I am a broken tearDown method"
-
- def test_noop(self):
- pass
-
-
-
-class SynchronousTestFailureInTearDown(
- FailureInTearDownMixin, unittest.SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTestFailureInTearDown(
- FailureInTearDownMixin, unittest.TestCase):
- pass
-
-
-
-class TestRegularFail(unittest.SynchronousTestCase):
- def test_fail(self):
- self.fail("I fail")
-
- def test_subfail(self):
- self.subroutine()
-
- def subroutine(self):
- self.fail("I fail inside")
-
-class TestFailureInDeferredChain(unittest.TestCase):
- def test_fail(self):
- d = defer.Deferred()
- d.addCallback(self._later)
- reactor.callLater(0, d.callback, None)
- return d
- def _later(self, res):
- self.fail("I fail later")
-
-
-
-class ErrorTest(unittest.SynchronousTestCase):
- """
- A test case which has a L{test_foo} which will raise an error.
-
- @ivar ran: boolean indicating whether L{test_foo} has been run.
- """
- ran = False
-
- def test_foo(self):
- """
- Set C{self.ran} to True and raise a C{ZeroDivisionError}
- """
- self.ran = True
- 1/0
-
-
-
-class TestSkipTestCase(unittest.SynchronousTestCase):
- pass
-
-TestSkipTestCase.skip = "skipping this test"
-
-
-class DelayedCall(unittest.TestCase):
- hiddenExceptionMsg = "something blew up"
-
- def go(self):
- raise RuntimeError(self.hiddenExceptionMsg)
-
- def testHiddenException(self):
- """
- What happens if an error is raised in a DelayedCall and an error is
- also raised in the test?
-
- L{test_reporter.TestErrorReporting.testHiddenException} checks that
- both errors get reported.
-
- Note that this behaviour is deprecated. A B{real} test would return a
- Deferred that got triggered by the callLater. This would guarantee the
- delayed call error gets reported.
- """
- reactor.callLater(0, self.go)
- reactor.iterate(0.01)
- self.fail("Deliberate failure to mask the hidden exception")
- testHiddenException.suppress = [util.suppress(
- message=r'reactor\.iterate cannot be used.*',
- category=DeprecationWarning)]
-
-
-class ReactorCleanupTests(unittest.TestCase):
- def test_leftoverPendingCalls(self):
- def _():
- print 'foo!'
- reactor.callLater(10000.0, _)
-
-class SocketOpenTest(unittest.TestCase):
- def test_socketsLeftOpen(self):
- f = protocol.Factory()
- f.protocol = protocol.Protocol
- reactor.listenTCP(0, f)
-
-class TimingOutDeferred(unittest.TestCase):
- def test_alpha(self):
- pass
-
- def test_deferredThatNeverFires(self):
- self.methodCalled = True
- d = defer.Deferred()
- return d
-
- def test_omega(self):
- pass
-
-
-def unexpectedException(self):
- """i will raise an unexpected exception...
- ... *CAUSE THAT'S THE KINDA GUY I AM*
-
- >>> 1/0
- """
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite.py
deleted file mode 100755
index 89ad1629..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2006 Twisted Matrix Laboratories. See LICENSE for details
-
-"""
-Mock test module that contains a C{test_suite} method. L{runner.TestLoader}
-should load the tests from the C{test_suite}, not from the C{Foo} C{TestCase}.
-
-See {twisted.trial.test.test_loader.LoaderTest.test_loadModuleWith_test_suite}.
-"""
-
-
-from twisted.trial import unittest, runner
-
-class Foo(unittest.TestCase):
- def test_foo(self):
- pass
-
-
-def test_suite():
- ts = runner.TestSuite()
- ts.name = "MyCustomSuite"
- return ts
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite2.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite2.py
deleted file mode 100755
index 6d05457e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite2.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2006 Twisted Matrix Laboratories. See LICENSE for details
-
-"""
-Mock test module that contains a C{testSuite} method. L{runner.TestLoader}
-should load the tests from the C{testSuite}, not from the C{Foo} C{TestCase}.
-
-See L{twisted.trial.test.test_loader.LoaderTest.test_loadModuleWith_testSuite}.
-"""
-
-
-from twisted.trial import unittest, runner
-
-class Foo(unittest.TestCase):
- def test_foo(self):
- pass
-
-
-def testSuite():
- ts = runner.TestSuite()
- ts.name = "MyCustomSuite"
- return ts
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite3.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite3.py
deleted file mode 100755
index c5b89d47..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockcustomsuite3.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (c) 2006 Twisted Matrix Laboratories. See LICENSE for details
-
-"""
-Mock test module that contains both a C{test_suite} and a C{testSuite} method.
-L{runner.TestLoader} should load the tests from the C{testSuite}, not from the
-C{Foo} C{TestCase} nor from the C{test_suite} method.
-
-See {twisted.trial.test.test_loader.LoaderTest.test_loadModuleWithBothCustom}.
-"""
-
-
-from twisted.trial import unittest, runner
-
-class Foo(unittest.TestCase):
- def test_foo(self):
- pass
-
-
-def test_suite():
- ts = runner.TestSuite()
- ts.name = "test_suite"
- return ts
-
-
-def testSuite():
- ts = runner.TestSuite()
- ts.name = "testSuite"
- return ts
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockdoctest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockdoctest.py
deleted file mode 100755
index 85beaddd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/mockdoctest.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# this module is a trivial class with doctests and a __test__ attribute
-# to test trial's doctest support with python2.4
-from __future__ import division
-
-class Counter(object):
- """a simple counter object for testing trial's doctest support
-
- >>> c = Counter()
- >>> c.value()
- 0
- >>> c += 3
- >>> c.value()
- 3
- >>> c.incr()
- >>> c.value() == 4
- True
- >>> c == 4
- True
- >>> c != 9
- True
-
- """
- _count = 0
-
- def __init__(self, initialValue=0, maxval=None):
- self._count = initialValue
- self.maxval = maxval
-
- def __iadd__(self, other):
- """add other to my value and return self
-
- >>> c = Counter(100)
- >>> c += 333
- >>> c == 433
- True
- """
- if self.maxval is not None and ((self._count + other) > self.maxval):
- raise ValueError, "sorry, counter got too big"
- else:
- self._count += other
- return self
-
- def __eq__(self, other):
- """equality operator, compare other to my value()
-
- >>> c = Counter()
- >>> c == 0
- True
- >>> c += 10
- >>> c.incr()
- >>> c == 10 # fail this test on purpose
- True
-
- """
- return self._count == other
-
- def __ne__(self, other):
- """inequality operator
-
- >>> c = Counter()
- >>> c != 10
- True
- """
- return not self.__eq__(other)
-
- def incr(self):
- """increment my value by 1
-
- >>> from twisted.trial.test.mockdoctest import Counter
- >>> c = Counter(10, 11)
- >>> c.incr()
- >>> c.value() == 11
- True
- >>> c.incr()
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- File "twisted/trial/test/mockdoctest.py", line 51, in incr
- self.__iadd__(1)
- File "twisted/trial/test/mockdoctest.py", line 39, in __iadd__
- raise ValueError, "sorry, counter got too big"
- ValueError: sorry, counter got too big
- """
- self.__iadd__(1)
-
- def value(self):
- """return this counter's value
-
- >>> c = Counter(555)
- >>> c.value() == 555
- True
- """
- return self._count
-
- def unexpectedException(self):
- """i will raise an unexpected exception...
- ... *CAUSE THAT'S THE KINDA GUY I AM*
-
- >>> 1/0
- """
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduleself.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduleself.py
deleted file mode 100755
index 1f87c823..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduleself.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- test-case-name: twisted.trial.test.moduleself -*-
-from twisted.trial import unittest
-
-class Foo(unittest.TestCase):
-
- def testFoo(self):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduletest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduletest.py
deleted file mode 100755
index c5e1d701..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/moduletest.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_test_visitor -*-
-
-# fodder for test_script, which parses files for emacs local variable
-# declarations. This one is supposed to have:
-# test-case-name: twisted.trial.test.test_test_visitor.
-# in the first line
-# The class declaration is irrelevant
-
-class Foo(object):
- pass
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/notpython b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/notpython
deleted file mode 100644
index 311485ce..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/notpython
+++ /dev/null
@@ -1,2 +0,0 @@
-
-this isn't python
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/novars.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/novars.py
deleted file mode 100755
index 93bc03df..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/novars.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# fodder for test_script, which parses files for emacs local variable
-# declarations. This one is supposed to have none.
-# The class declaration is irrelevant
-
-class Bar(object):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/packages.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/packages.py
deleted file mode 100755
index 7a183645..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/packages.py
+++ /dev/null
@@ -1,156 +0,0 @@
-import sys, os
-from twisted.trial import unittest
-
-testModule = """
-from twisted.trial import unittest
-
-class FooTest(unittest.TestCase):
- def testFoo(self):
- pass
-"""
-
-dosModule = testModule.replace('\n', '\r\n')
-
-
-testSample = """
-'''This module is used by test_loader to test the Trial test loading
-functionality. Do NOT change the number of tests in this module.
-Do NOT change the names the tests in this module.
-'''
-
-import unittest as pyunit
-from twisted.trial import unittest
-
-class FooTest(unittest.TestCase):
- def test_foo(self):
- pass
-
- def test_bar(self):
- pass
-
-
-class PyunitTest(pyunit.TestCase):
- def test_foo(self):
- pass
-
- def test_bar(self):
- pass
-
-
-class NotATest(object):
- def test_foo(self):
- pass
-
-
-class AlphabetTest(unittest.TestCase):
- def test_a(self):
- pass
-
- def test_b(self):
- pass
-
- def test_c(self):
- pass
-"""
-
-testInheritanceSample = """
-'''This module is used by test_loader to test the Trial test loading
-functionality. Do NOT change the number of tests in this module.
-Do NOT change the names the tests in this module.
-'''
-
-from twisted.trial import unittest
-
-class X(object):
-
- def test_foo(self):
- pass
-
-class A(unittest.TestCase, X):
- pass
-
-class B(unittest.TestCase, X):
- pass
-
-"""
-
-class PackageTest(unittest.TestCase):
- files = [
- ('badpackage/__init__.py', 'frotz\n'),
- ('badpackage/test_module.py', ''),
- ('package2/__init__.py', ''),
- ('package2/test_module.py', 'import frotz\n'),
- ('package/__init__.py', ''),
- ('package/frotz.py', 'frotz\n'),
- ('package/test_bad_module.py',
- 'raise ZeroDivisionError("fake error")'),
- ('package/test_dos_module.py', dosModule),
- ('package/test_import_module.py', 'import frotz'),
- ('package/test_module.py', testModule),
- ('goodpackage/__init__.py', ''),
- ('goodpackage/test_sample.py', testSample),
- ('goodpackage/sub/__init__.py', ''),
- ('goodpackage/sub/test_sample.py', testSample),
- ('inheritancepackage/__init__.py', ''),
- ('inheritancepackage/test_x.py', testInheritanceSample),
- ]
-
- def _toModuleName(self, filename):
- name = os.path.splitext(filename)[0]
- segs = name.split('/')
- if segs[-1] == '__init__':
- segs = segs[:-1]
- return '.'.join(segs)
-
- def getModules(self):
- return map(self._toModuleName, zip(*self.files)[0])
-
- def cleanUpModules(self):
- modules = self.getModules()
- modules.sort()
- modules.reverse()
- for module in modules:
- try:
- del sys.modules[module]
- except KeyError:
- pass
-
- def createFiles(self, files, parentDir='.'):
- for filename, contents in self.files:
- filename = os.path.join(parentDir, filename)
- self._createDirectory(filename)
- fd = open(filename, 'w')
- fd.write(contents)
- fd.close()
-
- def _createDirectory(self, filename):
- directory = os.path.dirname(filename)
- if not os.path.exists(directory):
- os.makedirs(directory)
-
- def setUp(self, parentDir=None):
- if parentDir is None:
- parentDir = self.mktemp()
- self.parent = parentDir
- self.createFiles(self.files, parentDir)
-
- def tearDown(self):
- self.cleanUpModules()
-
-class SysPathManglingTest(PackageTest):
- def setUp(self, parent=None):
- self.oldPath = sys.path[:]
- self.newPath = sys.path[:]
- if parent is None:
- parent = self.mktemp()
- PackageTest.setUp(self, parent)
- self.newPath.append(self.parent)
- self.mangleSysPath(self.newPath)
-
- def tearDown(self):
- PackageTest.tearDown(self)
- self.mangleSysPath(self.oldPath)
-
- def mangleSysPath(self, pathVar):
- sys.path[:] = pathVar
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/sample.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/sample.py
deleted file mode 100755
index d8644197..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/sample.py
+++ /dev/null
@@ -1,108 +0,0 @@
-"""This module is used by test_loader to test the Trial test loading
-functionality. Do NOT change the number of tests in this module. Do NOT change
-the names the tests in this module.
-"""
-
-import unittest as pyunit
-from twisted.trial import unittest
-from twisted.python.util import mergeFunctionMetadata
-
-
-
-class FooTest(unittest.TestCase):
-
-
- def test_foo(self):
- pass
-
-
- def test_bar(self):
- pass
-
-
-
-def badDecorator(fn):
- """
- Decorate a function without preserving the name of the original function.
- Always return a function with the same name.
- """
- def nameCollision(*args, **kwargs):
- return fn(*args, **kwargs)
- return nameCollision
-
-
-
-def goodDecorator(fn):
- """
- Decorate a function and preserve the original name.
- """
- def nameCollision(*args, **kwargs):
- return fn(*args, **kwargs)
- return mergeFunctionMetadata(fn, nameCollision)
-
-
-
-class DecorationTest(unittest.TestCase):
- def test_badDecorator(self):
- """
- This test method is decorated in a way that gives it a confusing name
- that collides with another method.
- """
- test_badDecorator = badDecorator(test_badDecorator)
-
-
- def test_goodDecorator(self):
- """
- This test method is decorated in a way that preserves its name.
- """
- test_goodDecorator = goodDecorator(test_goodDecorator)
-
-
- def renamedDecorator(self):
- """
- This is secretly a test method and will be decorated and then renamed so
- test discovery can find it.
- """
- test_renamedDecorator = goodDecorator(renamedDecorator)
-
-
- def nameCollision(self):
- """
- This isn't a test, it's just here to collide with tests.
- """
-
-
-
-class PyunitTest(pyunit.TestCase):
-
-
- def test_foo(self):
- pass
-
-
- def test_bar(self):
- pass
-
-
-
-class NotATest(object):
-
-
- def test_foo(self):
- pass
-
-
-
-class AlphabetTest(unittest.TestCase):
-
-
- def test_a(self):
- pass
-
-
- def test_b(self):
- pass
-
-
- def test_c(self):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/scripttest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/scripttest.py
deleted file mode 100755
index 267c1892..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/scripttest.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-# -*- test-case-name: twisted.trial.test.test_test_visitor,twisted.trial.test.test_class -*-
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# fodder for test_script, which parses files for emacs local variable
-# declarations. This one is supposed to have:
-# test-case-name: twisted.trial.test.test_test_visitor
-# in the second line
-# The class declaration is irrelevant
-
-class Foo(object):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/skipping.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/skipping.py
deleted file mode 100755
index 66a075c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/skipping.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_tests -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Definitions of test cases with various interesting behaviors, to be used by
-L{twisted.trial.test.test_tests} and other test modules to exercise different
-features of trial's test runner.
-
-See the L{twisted.trial.test.test_tests} module docstring for details about how
-this code is arranged.
-"""
-
-from twisted.trial.unittest import (
- SynchronousTestCase, TestCase, SkipTest, FailTest)
-
-
-class SkippingMixin(object):
- def test_skip1(self):
- raise SkipTest('skip1')
-
- def test_skip2(self):
- raise RuntimeError("I should not get raised")
- test_skip2.skip = 'skip2'
-
- def test_skip3(self):
- self.fail('I should not fail')
- test_skip3.skip = 'skip3'
-
-
-
-class SynchronousSkipping(SkippingMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousSkipping(SkippingMixin, TestCase):
- pass
-
-
-
-class SkippingSetUpMixin(object):
- def setUp(self):
- raise SkipTest('skipSetUp')
-
- def test_1(self):
- pass
-
- def test_2(self):
- pass
-
-
-class SynchronousSkippingSetUp(SkippingSetUpMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousSkippingSetUp(SkippingSetUpMixin, TestCase):
- pass
-
-
-
-class DeprecatedReasonlessSkipMixin(object):
- def test_1(self):
- raise SkipTest()
-
-
-
-class SynchronousDeprecatedReasonlessSkip(
- DeprecatedReasonlessSkipMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousDeprecatedReasonlessSkip(
- DeprecatedReasonlessSkipMixin, TestCase):
- pass
-
-
-
-class SkippedClassMixin(object):
- skip = 'class'
- def setUp(self):
- self.__class__._setUpRan = True
- def test_skip1(self):
- raise SkipTest('skip1')
- def test_skip2(self):
- raise RuntimeError("Ought to skip me")
- test_skip2.skip = 'skip2'
- def test_skip3(self):
- pass
- def test_skip4(self):
- raise RuntimeError("Skip me too")
-
-
-
-class SynchronousSkippedClass(SkippedClassMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousSkippedClass(SkippedClassMixin, TestCase):
- pass
-
-
-
-class TodoMixin(object):
- def test_todo1(self):
- self.fail("deliberate failure")
- test_todo1.todo = "todo1"
-
- def test_todo2(self):
- raise RuntimeError("deliberate error")
- test_todo2.todo = "todo2"
-
- def test_todo3(self):
- """unexpected success"""
- test_todo3.todo = 'todo3'
-
-
-
-
-class SynchronousTodo(TodoMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTodo(TodoMixin, TestCase):
- pass
-
-
-
-class SetUpTodoMixin(object):
- def setUp(self):
- raise RuntimeError("deliberate error")
-
- def test_todo1(self):
- pass
- test_todo1.todo = "setUp todo1"
-
-
-
-class SynchronousSetUpTodo(SetUpTodoMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousSetUpTodo(SetUpTodoMixin, TestCase):
- pass
-
-
-
-class TearDownTodoMixin(object):
- def tearDown(self):
- raise RuntimeError("deliberate error")
-
- def test_todo1(self):
- pass
- test_todo1.todo = "tearDown todo1"
-
-
-
-class SynchronousTearDownTodo(TearDownTodoMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTearDownTodo(TearDownTodoMixin, TestCase):
- pass
-
-
-
-class TodoClassMixin(object):
- todo = "class"
- def test_todo1(self):
- pass
- test_todo1.todo = "method"
- def test_todo2(self):
- pass
- def test_todo3(self):
- self.fail("Deliberate Failure")
- test_todo3.todo = "method"
- def test_todo4(self):
- self.fail("Deliberate Failure")
-
-
-
-class SynchronousTodoClass(TodoClassMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTodoClass(TodoClassMixin, TestCase):
- pass
-
-
-
-class StrictTodoMixin(object):
- def test_todo1(self):
- raise RuntimeError("expected failure")
- test_todo1.todo = (RuntimeError, "todo1")
-
- def test_todo2(self):
- raise RuntimeError("expected failure")
- test_todo2.todo = ((RuntimeError, OSError), "todo2")
-
- def test_todo3(self):
- raise RuntimeError("we had no idea!")
- test_todo3.todo = (OSError, "todo3")
-
- def test_todo4(self):
- raise RuntimeError("we had no idea!")
- test_todo4.todo = ((OSError, SyntaxError), "todo4")
-
- def test_todo5(self):
- self.fail("deliberate failure")
- test_todo5.todo = (FailTest, "todo5")
-
- def test_todo6(self):
- self.fail("deliberate failure")
- test_todo6.todo = (RuntimeError, "todo6")
-
- def test_todo7(self):
- pass
- test_todo7.todo = (RuntimeError, "todo7")
-
-
-
-class SynchronousStrictTodo(StrictTodoMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousStrictTodo(StrictTodoMixin, TestCase):
- pass
-
-
-
-class AddCleanupMixin(object):
- def setUp(self):
- self.log = ['setUp']
-
- def brokenSetUp(self):
- self.log = ['setUp']
- raise RuntimeError("Deliberate failure")
-
- def skippingSetUp(self):
- self.log = ['setUp']
- raise SkipTest("Don't do this")
-
- def append(self, thing):
- self.log.append(thing)
-
- def tearDown(self):
- self.log.append('tearDown')
-
- def runTest(self):
- self.log.append('runTest')
-
-
-
-class SynchronousAddCleanup(AddCleanupMixin, SynchronousTestCase):
- pass
-
-
-
-class AsynchronousAddCleanup(AddCleanupMixin, TestCase):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/suppression.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/suppression.py
deleted file mode 100755
index 2b87afcd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/suppression.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_tests -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases used to make sure that warning supression works at the module,
-method, and class levels.
-
-See the L{twisted.trial.test.test_tests} module docstring for details about how
-this code is arranged.
-"""
-
-import warnings
-
-from twisted.trial import unittest, util
-
-
-
-METHOD_WARNING_MSG = "method warning message"
-CLASS_WARNING_MSG = "class warning message"
-MODULE_WARNING_MSG = "module warning message"
-
-class MethodWarning(Warning):
- pass
-
-class ClassWarning(Warning):
- pass
-
-class ModuleWarning(Warning):
- pass
-
-class EmitMixin:
- def _emit(self):
- warnings.warn(METHOD_WARNING_MSG, MethodWarning)
- warnings.warn(CLASS_WARNING_MSG, ClassWarning)
- warnings.warn(MODULE_WARNING_MSG, ModuleWarning)
-
-
-class SuppressionMixin(EmitMixin):
- suppress = [util.suppress(message=CLASS_WARNING_MSG)]
-
- def testSuppressMethod(self):
- self._emit()
- testSuppressMethod.suppress = [util.suppress(message=METHOD_WARNING_MSG)]
-
- def testSuppressClass(self):
- self._emit()
-
- def testOverrideSuppressClass(self):
- self._emit()
- testOverrideSuppressClass.suppress = []
-
-
-
-class SynchronousTestSuppression(SuppressionMixin, unittest.SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTestSuppression(SuppressionMixin, unittest.TestCase):
- pass
-
-
-
-class SetUpSuppressionMixin(object):
- def setUp(self):
- self._emit()
-
-
-
-class SynchronousTestSetUpSuppression(SetUpSuppressionMixin, SynchronousTestSuppression):
- pass
-
-
-
-class AsynchronousTestSetUpSuppression(SetUpSuppressionMixin, AsynchronousTestSuppression):
- pass
-
-
-
-class TearDownSuppressionMixin(object):
- def tearDown(self):
- self._emit()
-
-
-
-class SynchronousTestTearDownSuppression(TearDownSuppressionMixin, SynchronousTestSuppression):
- pass
-
-
-
-class AsynchronousTestTearDownSuppression(TearDownSuppressionMixin, AsynchronousTestSuppression):
- pass
-
-
-
-class TestSuppression2Mixin(EmitMixin):
- def testSuppressModule(self):
- self._emit()
-
-
-
-class SynchronousTestSuppression2(TestSuppression2Mixin, unittest.SynchronousTestCase):
- pass
-
-
-
-class AsynchronousTestSuppression2(TestSuppression2Mixin, unittest.TestCase):
- pass
-
-
-suppress = [util.suppress(message=MODULE_WARNING_MSG)]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_assertions.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_assertions.py
deleted file mode 100755
index a9490e03..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_assertions.py
+++ /dev/null
@@ -1,1026 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for assertions provided by C{SynchronousTestCase} and C{TestCase},
-provided by L{twisted.trial.unittest}.
-
-L{TestFailureTests} demonstrates that L{SynchronousTestCase.fail} works, so that
-is the only method on C{twisted.trial.unittest.SynchronousTestCase} that is
-initially assumed to work. The test classes are arranged so that the methods
-demonstrated to work earlier in the file are used by those later in the file
-(even though the runner will probably not run the tests in this order).
-"""
-
-from __future__ import division
-
-import warnings
-from pprint import pformat
-import unittest as pyunit
-
-from twisted.python import reflect, failure
-from twisted.python.deprecate import deprecated, getVersionString
-from twisted.python.versions import Version
-from twisted.internet import defer
-from twisted.trial import unittest, runner, reporter
-
-class MockEquality(object):
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return "MockEquality(%s)" % (self.name,)
-
- def __eq__(self, other):
- if not hasattr(other, 'name'):
- raise ValueError("%r not comparable to %r" % (other, self))
- return self.name[0] == other.name[0]
-
-
-class TestFailureTests(pyunit.TestCase):
- """
- Tests for the most basic functionality of L{SynchronousTestCase}, for
- failing tests.
-
- This class contains tests to demonstrate that L{SynchronousTestCase.fail}
- can be used to fail a test, and that that failure is reflected in the test
- result object. This should be sufficient functionality so that further
- tests can be built on L{SynchronousTestCase} instead of
- L{unittest.TestCase}. This depends on L{unittest.TestCase} working.
- """
- class FailingTest(unittest.SynchronousTestCase):
- def test_fails(self):
- self.fail("This test fails.")
-
-
- def setUp(self):
- """
- Load a suite of one test which can be used to exercise the failure
- handling behavior.
- """
- components = [
- __name__, self.__class__.__name__, self.FailingTest.__name__]
- self.loader = pyunit.TestLoader()
- self.suite = self.loader.loadTestsFromName(".".join(components))
- self.test = list(self.suite)[0]
-
-
- def test_fail(self):
- """
- L{SynchronousTestCase.fail} raises
- L{SynchronousTestCase.failureException} with the given argument.
- """
- try:
- self.test.fail("failed")
- except self.test.failureException as result:
- self.assertEqual("failed", str(result))
- else:
- self.fail(
- "SynchronousTestCase.fail method did not raise "
- "SynchronousTestCase.failureException")
-
-
- def test_failingExceptionFails(self):
- """
- When a test method raises L{SynchronousTestCase.failureException}, the test is
- marked as having failed on the L{TestResult}.
- """
- result = pyunit.TestResult()
- self.suite.run(result)
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.errors, [])
- self.assertEqual(len(result.failures), 1)
- self.assertEqual(result.failures[0][0], self.test)
-
-
-
-class AssertFalseTests(unittest.SynchronousTestCase):
- """
- Tests for L{SynchronousTestCase}'s C{assertFalse} and C{failIf} assertion
- methods.
-
- This is pretty paranoid. Still, a certain paranoia is healthy if you
- are testing a unit testing framework.
-
- @note: As of 11.2, C{assertFalse} is preferred over C{failIf}.
- """
- def _assertFalseFalse(self, method):
- """
- Perform the positive case test for C{failIf} or C{assertFalse}.
-
- @param method: The test method to test.
- """
- for notTrue in [0, 0.0, False, None, (), []]:
- result = method(notTrue, "failed on %r" % (notTrue,))
- if result != notTrue:
- self.fail("Did not return argument %r" % (notTrue,))
-
-
- def _assertFalseTrue(self, method):
- """
- Perform the negative case test for C{failIf} or C{assertFalse}.
-
- @param method: The test method to test.
- """
- for true in [1, True, 'cat', [1,2], (3,4)]:
- try:
- method(true, "failed on %r" % (true,))
- except self.failureException, e:
- if str(e) != "failed on %r" % (true,):
- self.fail("Raised incorrect exception on %r: %r" % (true, e))
- else:
- self.fail("Call to failIf(%r) didn't fail" % (true,))
-
-
- def test_failIfFalse(self):
- """
- L{SynchronousTestCase.failIf} returns its argument if its argument is
- not considered true.
- """
- self._assertFalseFalse(self.failIf)
-
-
- def test_assertFalseFalse(self):
- """
- L{SynchronousTestCase.assertFalse} returns its argument if its argument
- is not considered true.
- """
- self._assertFalseFalse(self.assertFalse)
-
-
- def test_failIfTrue(self):
- """
- L{SynchronousTestCase.failIf} raises
- L{SynchronousTestCase.failureException} if its argument is considered
- true.
- """
- self._assertFalseTrue(self.failIf)
-
-
- def test_assertFalseTrue(self):
- """
- L{SynchronousTestCase.assertFalse} raises
- L{SynchronousTestCase.failureException} if its argument is considered
- true.
- """
- self._assertFalseTrue(self.assertFalse)
-
-
-
-class AssertTrueTests(unittest.SynchronousTestCase):
- """
- Tests for L{SynchronousTestCase}'s C{assertTrue} and C{failUnless} assertion
- methods.
-
- This is pretty paranoid. Still, a certain paranoia is healthy if you
- are testing a unit testing framework.
-
- @note: As of 11.2, C{assertTrue} is preferred over C{failUnless}.
- """
- def _assertTrueFalse(self, method):
- """
- Perform the negative case test for C{assertTrue} and C{failUnless}.
-
- @param method: The test method to test.
- """
- for notTrue in [0, 0.0, False, None, (), []]:
- try:
- method(notTrue, "failed on %r" % (notTrue,))
- except self.failureException, e:
- if str(e) != "failed on %r" % (notTrue,):
- self.fail(
- "Raised incorrect exception on %r: %r" % (notTrue, e))
- else:
- self.fail(
- "Call to %s(%r) didn't fail" % (method.__name__, notTrue,))
-
-
- def _assertTrueTrue(self, method):
- """
- Perform the positive case test for C{assertTrue} and C{failUnless}.
-
- @param method: The test method to test.
- """
- for true in [1, True, 'cat', [1,2], (3,4)]:
- result = method(true, "failed on %r" % (true,))
- if result != true:
- self.fail("Did not return argument %r" % (true,))
-
-
- def test_assertTrueFalse(self):
- """
- L{SynchronousTestCase.assertTrue} raises
- L{SynchronousTestCase.failureException} if its argument is not
- considered true.
- """
- self._assertTrueFalse(self.assertTrue)
-
-
- def test_failUnlessFalse(self):
- """
- L{SynchronousTestCase.failUnless} raises
- L{SynchronousTestCase.failureException} if its argument is not
- considered true.
- """
- self._assertTrueFalse(self.failUnless)
-
-
- def test_assertTrueTrue(self):
- """
- L{SynchronousTestCase.assertTrue} returns its argument if its argument
- is considered true.
- """
- self._assertTrueTrue(self.assertTrue)
-
-
- def test_failUnlessTrue(self):
- """
- L{SynchronousTestCase.failUnless} returns its argument if its argument
- is considered true.
- """
- self._assertTrueTrue(self.failUnless)
-
-
-
-class TestSynchronousAssertions(unittest.SynchronousTestCase):
- """
- Tests for L{SynchronousTestCase}'s assertion methods. That is, failUnless*,
- failIf*, assert* (not covered by other more specific test classes).
-
- Note: As of 11.2, assertEqual is preferred over the failUnlessEqual(s)
- variants. Tests have been modified to reflect this preference.
-
- This is pretty paranoid. Still, a certain paranoia is healthy if you are
- testing a unit testing framework.
- """
- def _testEqualPair(self, first, second):
- x = self.assertEqual(first, second)
- if x != first:
- self.fail("assertEqual should return first parameter")
-
-
- def _testUnequalPair(self, first, second):
- try:
- self.assertEqual(first, second)
- except self.failureException, e:
- expected = 'not equal:\na = %s\nb = %s\n' % (
- pformat(first), pformat(second))
- if str(e) != expected:
- self.fail("Expected: %r; Got: %s" % (expected, str(e)))
- else:
- self.fail("Call to assertEqual(%r, %r) didn't fail"
- % (first, second))
-
-
- def test_assertEqual_basic(self):
- self._testEqualPair('cat', 'cat')
- self._testUnequalPair('cat', 'dog')
- self._testEqualPair([1], [1])
- self._testUnequalPair([1], 'orange')
-
-
- def test_assertEqual_custom(self):
- x = MockEquality('first')
- y = MockEquality('second')
- z = MockEquality('fecund')
- self._testEqualPair(x, x)
- self._testEqualPair(x, z)
- self._testUnequalPair(x, y)
- self._testUnequalPair(y, z)
-
-
- def test_assertEqualMessage(self):
- """
- When a message is passed to L{assertEqual}, it is included in the
- error message.
- """
- exception = self.assertRaises(
- self.failureException, self.assertEqual,
- 'foo', 'bar', 'message')
- self.assertEqual(
- str(exception),
- "message\nnot equal:\na = 'foo'\nb = 'bar'\n")
-
-
- def test_assertEqualNoneMessage(self):
- """
- If a message is specified as C{None}, it is not included in the error
- message of L{assertEqual}.
- """
- exception = self.assertRaises(
- self.failureException, self.assertEqual, 'foo', 'bar', None)
- self.assertEqual(str(exception), "not equal:\na = 'foo'\nb = 'bar'\n")
-
-
- def test_assertEqual_incomparable(self):
- apple = MockEquality('apple')
- orange = ['orange']
- try:
- self.assertEqual(apple, orange)
- except self.failureException:
- self.fail("Fail raised when ValueError ought to have been raised.")
- except ValueError:
- # good. error not swallowed
- pass
- else:
- self.fail("Comparing %r and %r should have raised an exception"
- % (apple, orange))
-
-
- def _raiseError(self, error):
- raise error
-
- def test_failUnlessRaises_expected(self):
- x = self.failUnlessRaises(ValueError, self._raiseError, ValueError)
- self.failUnless(isinstance(x, ValueError),
- "Expect failUnlessRaises to return instance of raised "
- "exception.")
-
- def test_failUnlessRaises_unexpected(self):
- try:
- self.failUnlessRaises(ValueError, self._raiseError, TypeError)
- except TypeError:
- self.fail("failUnlessRaises shouldn't re-raise unexpected "
- "exceptions")
- except self.failureException:
- # what we expect
- pass
- else:
- self.fail("Expected exception wasn't raised. Should have failed")
-
- def test_failUnlessRaises_noException(self):
- try:
- self.failUnlessRaises(ValueError, lambda : None)
- except self.failureException, e:
- self.assertEqual(str(e),
- 'ValueError not raised (None returned)')
- else:
- self.fail("Exception not raised. Should have failed")
-
- def test_failUnlessRaises_failureException(self):
- x = self.failUnlessRaises(self.failureException, self._raiseError,
- self.failureException)
- self.failUnless(isinstance(x, self.failureException),
- "Expected %r instance to be returned"
- % (self.failureException,))
- try:
- x = self.failUnlessRaises(self.failureException, self._raiseError,
- ValueError)
- except self.failureException:
- # what we expect
- pass
- else:
- self.fail("Should have raised exception")
-
- def test_failIfEqual_basic(self):
- x, y, z = [1], [2], [1]
- ret = self.failIfEqual(x, y)
- self.assertEqual(ret, x,
- "failIfEqual should return first parameter")
- self.failUnlessRaises(self.failureException,
- self.failIfEqual, x, x)
- self.failUnlessRaises(self.failureException,
- self.failIfEqual, x, z)
-
- def test_failIfEqual_customEq(self):
- x = MockEquality('first')
- y = MockEquality('second')
- z = MockEquality('fecund')
- ret = self.failIfEqual(x, y)
- self.assertEqual(ret, x,
- "failIfEqual should return first parameter")
- self.failUnlessRaises(self.failureException,
- self.failIfEqual, x, x)
- # test when __ne__ is not defined
- self.failIfEqual(x, z, "__ne__ not defined, so not equal")
-
-
- def test_failIfIdenticalPositive(self):
- """
- C{failIfIdentical} returns its first argument if its first and second
- arguments are not the same object.
- """
- x = object()
- y = object()
- result = self.failIfIdentical(x, y)
- self.assertEqual(x, result)
-
-
- def test_failIfIdenticalNegative(self):
- """
- C{failIfIdentical} raises C{failureException} if its first and second
- arguments are the same object.
- """
- x = object()
- self.failUnlessRaises(self.failureException,
- self.failIfIdentical, x, x)
-
-
- def test_failUnlessIdentical(self):
- x, y, z = [1], [1], [2]
- ret = self.failUnlessIdentical(x, x)
- self.assertEqual(ret, x,
- 'failUnlessIdentical should return first '
- 'parameter')
- self.failUnlessRaises(self.failureException,
- self.failUnlessIdentical, x, y)
- self.failUnlessRaises(self.failureException,
- self.failUnlessIdentical, x, z)
-
- def test_failUnlessApproximates(self):
- x, y, z = 1.0, 1.1, 1.2
- self.failUnlessApproximates(x, x, 0.2)
- ret = self.failUnlessApproximates(x, y, 0.2)
- self.assertEqual(ret, x, "failUnlessApproximates should return "
- "first parameter")
- self.failUnlessRaises(self.failureException,
- self.failUnlessApproximates, x, z, 0.1)
- self.failUnlessRaises(self.failureException,
- self.failUnlessApproximates, x, y, 0.1)
-
- def test_failUnlessAlmostEqual(self):
- precision = 5
- x = 8.000001
- y = 8.00001
- z = 8.000002
- self.failUnlessAlmostEqual(x, x, precision)
- ret = self.failUnlessAlmostEqual(x, z, precision)
- self.assertEqual(ret, x, "failUnlessAlmostEqual should return "
- "first parameter (%r, %r)" % (ret, x))
- self.failUnlessRaises(self.failureException,
- self.failUnlessAlmostEqual, x, y, precision)
-
- def test_failIfAlmostEqual(self):
- precision = 5
- x = 8.000001
- y = 8.00001
- z = 8.000002
- ret = self.failIfAlmostEqual(x, y, precision)
- self.assertEqual(ret, x, "failIfAlmostEqual should return "
- "first parameter (%r, %r)" % (ret, x))
- self.failUnlessRaises(self.failureException,
- self.failIfAlmostEqual, x, x, precision)
- self.failUnlessRaises(self.failureException,
- self.failIfAlmostEqual, x, z, precision)
-
- def test_failUnlessSubstring(self):
- x = "cat"
- y = "the dog sat"
- z = "the cat sat"
- self.failUnlessSubstring(x, x)
- ret = self.failUnlessSubstring(x, z)
- self.assertEqual(ret, x, 'should return first parameter')
- self.failUnlessRaises(self.failureException,
- self.failUnlessSubstring, x, y)
- self.failUnlessRaises(self.failureException,
- self.failUnlessSubstring, z, x)
-
- def test_failIfSubstring(self):
- x = "cat"
- y = "the dog sat"
- z = "the cat sat"
- self.failIfSubstring(z, x)
- ret = self.failIfSubstring(x, y)
- self.assertEqual(ret, x, 'should return first parameter')
- self.failUnlessRaises(self.failureException,
- self.failIfSubstring, x, x)
- self.failUnlessRaises(self.failureException,
- self.failIfSubstring, x, z)
-
-
- def test_assertIsInstance(self):
- """
- Test a true condition of assertIsInstance.
- """
- A = type('A', (object,), {})
- a = A()
- self.assertIsInstance(a, A)
-
-
- def test_assertIsInstanceMultipleClasses(self):
- """
- Test a true condition of assertIsInstance with multiple classes.
- """
- A = type('A', (object,), {})
- B = type('B', (object,), {})
- a = A()
- self.assertIsInstance(a, (A, B))
-
-
- def test_assertIsInstanceError(self):
- """
- Test an error with assertIsInstance.
- """
- A = type('A', (object,), {})
- B = type('B', (object,), {})
- a = A()
- self.assertRaises(self.failureException, self.assertIsInstance, a, B)
-
-
- def test_assertIsInstanceErrorMultipleClasses(self):
- """
- Test an error with assertIsInstance and multiple classes.
- """
- A = type('A', (object,), {})
- B = type('B', (object,), {})
- C = type('C', (object,), {})
- a = A()
- self.assertRaises(self.failureException, self.assertIsInstance, a, (B, C))
-
-
- def test_assertIsInstanceCustomMessage(self):
- """
- If L{TestCase.assertIsInstance} is passed a custom message as its 3rd
- argument, the message is included in the failure exception raised when
- the assertion fails.
- """
- exc = self.assertRaises(
- self.failureException,
- self.assertIsInstance, 3, str, "Silly assertion")
- self.assertIn("Silly assertion", str(exc))
-
-
- def test_assertNotIsInstance(self):
- """
- Test a true condition of assertNotIsInstance.
- """
- A = type('A', (object,), {})
- B = type('B', (object,), {})
- a = A()
- self.assertNotIsInstance(a, B)
-
-
- def test_assertNotIsInstanceMultipleClasses(self):
- """
- Test a true condition of assertNotIsInstance and multiple classes.
- """
- A = type('A', (object,), {})
- B = type('B', (object,), {})
- C = type('C', (object,), {})
- a = A()
- self.assertNotIsInstance(a, (B, C))
-
-
- def test_assertNotIsInstanceError(self):
- """
- Test an error with assertNotIsInstance.
- """
- A = type('A', (object,), {})
- a = A()
- error = self.assertRaises(self.failureException,
- self.assertNotIsInstance, a, A)
- self.assertEqual(str(error), "%r is an instance of %s" % (a, A))
-
-
- def test_assertNotIsInstanceErrorMultipleClasses(self):
- """
- Test an error with assertNotIsInstance and multiple classes.
- """
- A = type('A', (object,), {})
- B = type('B', (object,), {})
- a = A()
- self.assertRaises(self.failureException, self.assertNotIsInstance, a, (A, B))
-
-
- def test_assertDictEqual(self):
- """
- L{twisted.trial.unittest.TestCase} supports the C{assertDictEqual}
- method inherited from the standard library in Python 2.7.
- """
- self.assertDictEqual({'a': 1}, {'a': 1})
- if getattr(unittest.SynchronousTestCase, 'assertDictEqual', None) is None:
- test_assertDictEqual.skip = (
- "assertDictEqual is not available on this version of Python")
-
-
-
-class TestAsynchronousAssertions(unittest.TestCase):
- """
- Tests for L{TestCase}'s asynchronous extensions to L{SynchronousTestCase}.
- That is, assertFailure.
- """
- def test_assertFailure(self):
- d = defer.maybeDeferred(lambda: 1/0)
- return self.assertFailure(d, ZeroDivisionError)
-
-
- def test_assertFailure_wrongException(self):
- d = defer.maybeDeferred(lambda: 1/0)
- self.assertFailure(d, OverflowError)
- d.addCallbacks(lambda x: self.fail('Should have failed'),
- lambda x: x.trap(self.failureException))
- return d
-
-
- def test_assertFailure_noException(self):
- d = defer.succeed(None)
- self.assertFailure(d, ZeroDivisionError)
- d.addCallbacks(lambda x: self.fail('Should have failed'),
- lambda x: x.trap(self.failureException))
- return d
-
-
- def test_assertFailure_moreInfo(self):
- """
- In the case of assertFailure failing, check that we get lots of
- information about the exception that was raised.
- """
- try:
- 1/0
- except ZeroDivisionError:
- f = failure.Failure()
- d = defer.fail(f)
- d = self.assertFailure(d, RuntimeError)
- d.addErrback(self._checkInfo, f)
- return d
-
-
- def _checkInfo(self, assertionFailure, f):
- assert assertionFailure.check(self.failureException)
- output = assertionFailure.getErrorMessage()
- self.assertIn(f.getErrorMessage(), output)
- self.assertIn(f.getBriefTraceback(), output)
-
-
- def test_assertFailure_masked(self):
- """
- A single wrong assertFailure should fail the whole test.
- """
- class ExampleFailure(Exception):
- pass
-
- class TC(unittest.TestCase):
- failureException = ExampleFailure
- def test_assertFailure(self):
- d = defer.maybeDeferred(lambda: 1/0)
- self.assertFailure(d, OverflowError)
- self.assertFailure(d, ZeroDivisionError)
- return d
-
- test = TC('test_assertFailure')
- result = reporter.TestResult()
- test.run(result)
- self.assertEqual(1, len(result.failures))
-
-
-class WarningAssertionTests(unittest.SynchronousTestCase):
- def test_assertWarns(self):
- """
- Test basic assertWarns report.
- """
- def deprecated(a):
- warnings.warn("Woo deprecated", category=DeprecationWarning)
- return a
- r = self.assertWarns(DeprecationWarning, "Woo deprecated", __file__,
- deprecated, 123)
- self.assertEqual(r, 123)
-
-
- def test_assertWarnsRegistryClean(self):
- """
- Test that assertWarns cleans the warning registry, so the warning is
- not swallowed the second time.
- """
- def deprecated(a):
- warnings.warn("Woo deprecated", category=DeprecationWarning)
- return a
- r1 = self.assertWarns(DeprecationWarning, "Woo deprecated", __file__,
- deprecated, 123)
- self.assertEqual(r1, 123)
- # The warning should be raised again
- r2 = self.assertWarns(DeprecationWarning, "Woo deprecated", __file__,
- deprecated, 321)
- self.assertEqual(r2, 321)
-
-
- def test_assertWarnsError(self):
- """
- Test assertWarns failure when no warning is generated.
- """
- def normal(a):
- return a
- self.assertRaises(self.failureException,
- self.assertWarns, DeprecationWarning, "Woo deprecated", __file__,
- normal, 123)
-
-
- def test_assertWarnsWrongCategory(self):
- """
- Test assertWarns failure when the category is wrong.
- """
- def deprecated(a):
- warnings.warn("Foo deprecated", category=DeprecationWarning)
- return a
- self.assertRaises(self.failureException,
- self.assertWarns, UserWarning, "Foo deprecated", __file__,
- deprecated, 123)
-
-
- def test_assertWarnsWrongMessage(self):
- """
- Test assertWarns failure when the message is wrong.
- """
- def deprecated(a):
- warnings.warn("Foo deprecated", category=DeprecationWarning)
- return a
- self.assertRaises(self.failureException,
- self.assertWarns, DeprecationWarning, "Bar deprecated", __file__,
- deprecated, 123)
-
-
- def test_assertWarnsWrongFile(self):
- """
- If the warning emitted by a function refers to a different file than is
- passed to C{assertWarns}, C{failureException} is raised.
- """
- def deprecated(a):
- # stacklevel=2 points at the direct caller of the function. The
- # way assertRaises is invoked below, the direct caller will be
- # something somewhere in trial, not something in this file. In
- # Python 2.5 and earlier, stacklevel of 0 resulted in a warning
- # pointing to the warnings module itself. Starting in Python 2.6,
- # stacklevel of 0 and 1 both result in a warning pointing to *this*
- # file, presumably due to the fact that the warn function is
- # implemented in C and has no convenient Python
- # filename/linenumber.
- warnings.warn(
- "Foo deprecated", category=DeprecationWarning, stacklevel=2)
- self.assertRaises(
- self.failureException,
- # Since the direct caller isn't in this file, try to assert that
- # the warning *does* point to this file, so that assertWarns raises
- # an exception.
- self.assertWarns, DeprecationWarning, "Foo deprecated", __file__,
- deprecated, 123)
-
- def test_assertWarnsOnClass(self):
- """
- Test assertWarns works when creating a class instance.
- """
- class Warn:
- def __init__(self):
- warnings.warn("Do not call me", category=RuntimeWarning)
- r = self.assertWarns(RuntimeWarning, "Do not call me", __file__,
- Warn)
- self.assertTrue(isinstance(r, Warn))
- r = self.assertWarns(RuntimeWarning, "Do not call me", __file__,
- Warn)
- self.assertTrue(isinstance(r, Warn))
-
-
- def test_assertWarnsOnMethod(self):
- """
- Test assertWarns works when used on an instance method.
- """
- class Warn:
- def deprecated(self, a):
- warnings.warn("Bar deprecated", category=DeprecationWarning)
- return a
- w = Warn()
- r = self.assertWarns(DeprecationWarning, "Bar deprecated", __file__,
- w.deprecated, 321)
- self.assertEqual(r, 321)
- r = self.assertWarns(DeprecationWarning, "Bar deprecated", __file__,
- w.deprecated, 321)
- self.assertEqual(r, 321)
-
-
- def test_assertWarnsOnCall(self):
- """
- Test assertWarns works on instance with C{__call__} method.
- """
- class Warn:
- def __call__(self, a):
- warnings.warn("Egg deprecated", category=DeprecationWarning)
- return a
- w = Warn()
- r = self.assertWarns(DeprecationWarning, "Egg deprecated", __file__,
- w, 321)
- self.assertEqual(r, 321)
- r = self.assertWarns(DeprecationWarning, "Egg deprecated", __file__,
- w, 321)
- self.assertEqual(r, 321)
-
-
- def test_assertWarnsFilter(self):
- """
- Test assertWarns on a warning filterd by default.
- """
- def deprecated(a):
- warnings.warn("Woo deprecated", category=PendingDeprecationWarning)
- return a
- r = self.assertWarns(PendingDeprecationWarning, "Woo deprecated",
- __file__, deprecated, 123)
- self.assertEqual(r, 123)
-
-
- def test_assertWarnsMultipleWarnings(self):
- """
- C{assertWarns} does not raise an exception if the function it is passed
- triggers the same warning more than once.
- """
- def deprecated():
- warnings.warn("Woo deprecated", category=PendingDeprecationWarning)
- def f():
- deprecated()
- deprecated()
- self.assertWarns(
- PendingDeprecationWarning, "Woo deprecated", __file__, f)
-
-
- def test_assertWarnsDifferentWarnings(self):
- """
- For now, assertWarns is unable to handle multiple different warnings,
- so it should raise an exception if it's the case.
- """
- def deprecated(a):
- warnings.warn("Woo deprecated", category=DeprecationWarning)
- warnings.warn("Another one", category=PendingDeprecationWarning)
- e = self.assertRaises(self.failureException,
- self.assertWarns, DeprecationWarning, "Woo deprecated",
- __file__, deprecated, 123)
- self.assertEqual(str(e), "Can't handle different warnings")
-
-
- def test_assertWarnsAfterUnassertedWarning(self):
- """
- Warnings emitted before L{TestCase.assertWarns} is called do not get
- flushed and do not alter the behavior of L{TestCase.assertWarns}.
- """
- class TheWarning(Warning):
- pass
-
- def f(message):
- warnings.warn(message, category=TheWarning)
- f("foo")
- self.assertWarns(TheWarning, "bar", __file__, f, "bar")
- [warning] = self.flushWarnings([f])
- self.assertEqual(warning['message'], "foo")
-
-
-
-class TestAssertionNames(unittest.SynchronousTestCase):
- """
- Tests for consistency of naming within TestCase assertion methods
- """
- def _getAsserts(self):
- dct = {}
- reflect.accumulateMethods(self, dct, 'assert')
- return [ dct[k] for k in dct if not k.startswith('Not') and k != '_' ]
-
- def _name(self, x):
- return x.__name__
-
-
- def test_failUnlessMatchesAssert(self):
- """
- The C{failUnless*} test methods are a subset of the C{assert*} test
- methods. This is intended to ensure that methods using the
- I{failUnless} naming scheme are not added without corresponding methods
- using the I{assert} naming scheme. The I{assert} naming scheme is
- preferred, and new I{assert}-prefixed methods may be added without
- corresponding I{failUnless}-prefixed methods.
- """
- asserts = set(self._getAsserts())
- failUnlesses = set(reflect.prefixedMethods(self, 'failUnless'))
- self.assertEqual(
- failUnlesses, asserts.intersection(failUnlesses))
-
-
- def test_failIf_matches_assertNot(self):
- asserts = reflect.prefixedMethods(unittest.SynchronousTestCase, 'assertNot')
- failIfs = reflect.prefixedMethods(unittest.SynchronousTestCase, 'failIf')
- self.assertEqual(sorted(asserts, key=self._name),
- sorted(failIfs, key=self._name))
-
- def test_equalSpelling(self):
- for name, value in vars(self).items():
- if not callable(value):
- continue
- if name.endswith('Equal'):
- self.failUnless(hasattr(self, name+'s'),
- "%s but no %ss" % (name, name))
- self.assertEqual(value, getattr(self, name+'s'))
- if name.endswith('Equals'):
- self.failUnless(hasattr(self, name[:-1]),
- "%s but no %s" % (name, name[:-1]))
- self.assertEqual(value, getattr(self, name[:-1]))
-
-
-class TestCallDeprecated(unittest.SynchronousTestCase):
- """
- Test use of the L{SynchronousTestCase.callDeprecated} method with version objects.
- """
-
- version = Version('Twisted', 8, 0, 0)
-
- def test_callDeprecatedSuppressesWarning(self):
- """
- callDeprecated calls a deprecated callable, suppressing the
- deprecation warning.
- """
- self.callDeprecated(self.version, oldMethod, 'foo')
- self.assertEqual(
- self.flushWarnings(), [], "No warnings should be shown")
-
-
- def test_callDeprecatedCallsFunction(self):
- """
- L{callDeprecated} actually calls the callable passed to it, and
- forwards the result.
- """
- result = self.callDeprecated(self.version, oldMethod, 'foo')
- self.assertEqual('foo', result)
-
-
- def test_failsWithoutDeprecation(self):
- """
- L{callDeprecated} raises a test failure if the callable is not
- deprecated.
- """
- def notDeprecated():
- pass
- exception = self.assertRaises(
- self.failureException,
- self.callDeprecated, self.version, notDeprecated)
- self.assertEqual(
- "%r is not deprecated." % notDeprecated, str(exception))
-
-
- def test_failsWithIncorrectDeprecation(self):
- """
- callDeprecated raises a test failure if the callable was deprecated
- at a different version to the one expected.
- """
- differentVersion = Version('Foo', 1, 2, 3)
- exception = self.assertRaises(
- self.failureException,
- self.callDeprecated,
- differentVersion, oldMethod, 'foo')
- self.assertIn(getVersionString(self.version), str(exception))
- self.assertIn(getVersionString(differentVersion), str(exception))
-
-
- def test_nestedDeprecation(self):
- """
- L{callDeprecated} ignores all deprecations apart from the first.
-
- Multiple warnings are generated when a deprecated function calls
- another deprecated function. The first warning is the one generated by
- the explicitly called function. That's the warning that we care about.
- """
- differentVersion = Version('Foo', 1, 2, 3)
-
- def nestedDeprecation(*args):
- return oldMethod(*args)
- nestedDeprecation = deprecated(differentVersion)(nestedDeprecation)
-
- self.callDeprecated(differentVersion, nestedDeprecation, 24)
-
- # The oldMethod deprecation should have been emitted too, not captured
- # by callDeprecated. Flush it now to make sure it did happen and to
- # prevent it from showing up on stdout.
- warningsShown = self.flushWarnings()
- self.assertEqual(len(warningsShown), 1)
-
-
- def test_callDeprecationWithMessage(self):
- """
- L{callDeprecated} can take a message argument used to check the warning
- emitted.
- """
- self.callDeprecated((self.version, "newMethod"),
- oldMethodReplaced, 1)
-
-
- def test_callDeprecationWithWrongMessage(self):
- """
- If the message passed to L{callDeprecated} doesn't match,
- L{callDeprecated} raises a test failure.
- """
- exception = self.assertRaises(
- self.failureException,
- self.callDeprecated,
- (self.version, "something.wrong"),
- oldMethodReplaced, 1)
- self.assertIn(getVersionString(self.version), str(exception))
- self.assertIn("please use newMethod instead", str(exception))
-
-
-
-
-@deprecated(TestCallDeprecated.version)
-def oldMethod(x):
- """
- Deprecated method for testing.
- """
- return x
-
-
-@deprecated(TestCallDeprecated.version, replacement="newMethod")
-def oldMethodReplaced(x):
- """
- Another deprecated method, which has been deprecated in favor of the
- mythical 'newMethod'.
- """
- return 2 * x
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_deferred.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_deferred.py
deleted file mode 100755
index 5ecc8ce1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_deferred.py
+++ /dev/null
@@ -1,220 +0,0 @@
-from twisted.internet import defer
-from twisted.trial import unittest
-from twisted.trial import runner, reporter, util
-from twisted.trial.test import detests
-
-
-class TestSetUp(unittest.TestCase):
- def _loadSuite(self, klass):
- loader = runner.TestLoader()
- r = reporter.TestResult()
- s = loader.loadClass(klass)
- return r, s
-
- def test_success(self):
- result, suite = self._loadSuite(detests.DeferredSetUpOK)
- suite(result)
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
-
- def test_fail(self):
- self.failIf(detests.DeferredSetUpFail.testCalled)
- result, suite = self._loadSuite(detests.DeferredSetUpFail)
- suite(result)
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 0)
- self.assertEqual(len(result.errors), 1)
- self.failIf(detests.DeferredSetUpFail.testCalled)
-
- def test_callbackFail(self):
- self.failIf(detests.DeferredSetUpCallbackFail.testCalled)
- result, suite = self._loadSuite(detests.DeferredSetUpCallbackFail)
- suite(result)
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 0)
- self.assertEqual(len(result.errors), 1)
- self.failIf(detests.DeferredSetUpCallbackFail.testCalled)
-
- def test_error(self):
- self.failIf(detests.DeferredSetUpError.testCalled)
- result, suite = self._loadSuite(detests.DeferredSetUpError)
- suite(result)
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 0)
- self.assertEqual(len(result.errors), 1)
- self.failIf(detests.DeferredSetUpError.testCalled)
-
- def test_skip(self):
- self.failIf(detests.DeferredSetUpSkip.testCalled)
- result, suite = self._loadSuite(detests.DeferredSetUpSkip)
- suite(result)
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 0)
- self.assertEqual(len(result.errors), 0)
- self.assertEqual(len(result.skips), 1)
- self.failIf(detests.DeferredSetUpSkip.testCalled)
-
-
-class TestNeverFire(unittest.TestCase):
- def setUp(self):
- self._oldTimeout = util.DEFAULT_TIMEOUT_DURATION
- util.DEFAULT_TIMEOUT_DURATION = 0.1
-
- def tearDown(self):
- util.DEFAULT_TIMEOUT_DURATION = self._oldTimeout
-
- def _loadSuite(self, klass):
- loader = runner.TestLoader()
- r = reporter.TestResult()
- s = loader.loadClass(klass)
- return r, s
-
- def test_setUp(self):
- self.failIf(detests.DeferredSetUpNeverFire.testCalled)
- result, suite = self._loadSuite(detests.DeferredSetUpNeverFire)
- suite(result)
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 0)
- self.assertEqual(len(result.errors), 1)
- self.failIf(detests.DeferredSetUpNeverFire.testCalled)
- self.failUnless(result.errors[0][1].check(defer.TimeoutError))
-
-
-class TestTester(unittest.TestCase):
- def getTest(self, name):
- raise NotImplementedError("must override me")
-
- def runTest(self, name):
- result = reporter.TestResult()
- self.getTest(name).run(result)
- return result
-
-
-class TestDeferred(TestTester):
- def getTest(self, name):
- return detests.DeferredTests(name)
-
- def test_pass(self):
- result = self.runTest('test_pass')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
-
- def test_passGenerated(self):
- result = self.runTest('test_passGenerated')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.failUnless(detests.DeferredTests.touched)
-
- def test_fail(self):
- result = self.runTest('test_fail')
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 1)
-
- def test_failureInCallback(self):
- result = self.runTest('test_failureInCallback')
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 1)
-
- def test_errorInCallback(self):
- result = self.runTest('test_errorInCallback')
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.errors), 1)
-
- def test_skip(self):
- result = self.runTest('test_skip')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.skips), 1)
- self.failIf(detests.DeferredTests.touched)
-
- def test_todo(self):
- result = self.runTest('test_expectedFailure')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.errors), 0)
- self.assertEqual(len(result.failures), 0)
- self.assertEqual(len(result.expectedFailures), 1)
-
- def test_thread(self):
- result = self.runTest('test_thread')
- self.assertEqual(result.testsRun, 1)
- self.failUnless(result.wasSuccessful(), result.errors)
-
-
-class TestTimeout(TestTester):
- def getTest(self, name):
- return detests.TimeoutTests(name)
-
- def _wasTimeout(self, error):
- self.assertEqual(error.check(defer.TimeoutError),
- defer.TimeoutError)
-
- def test_pass(self):
- result = self.runTest('test_pass')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
-
- def test_passDefault(self):
- result = self.runTest('test_passDefault')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
-
- def test_timeout(self):
- result = self.runTest('test_timeout')
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.errors), 1)
- self._wasTimeout(result.errors[0][1])
-
- def test_timeoutZero(self):
- result = self.runTest('test_timeoutZero')
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.errors), 1)
- self._wasTimeout(result.errors[0][1])
-
- def test_skip(self):
- result = self.runTest('test_skip')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.skips), 1)
-
- def test_todo(self):
- result = self.runTest('test_expectedFailure')
- self.failUnless(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.expectedFailures), 1)
- self._wasTimeout(result.expectedFailures[0][1])
-
- def test_errorPropagation(self):
- result = self.runTest('test_errorPropagation')
- self.failIf(result.wasSuccessful())
- self.assertEqual(result.testsRun, 1)
- self._wasTimeout(detests.TimeoutTests.timedOut)
-
- def test_classTimeout(self):
- loader = runner.TestLoader()
- suite = loader.loadClass(detests.TestClassTimeoutAttribute)
- result = reporter.TestResult()
- suite.run(result)
- self.assertEqual(len(result.errors), 1)
- self._wasTimeout(result.errors[0][1])
-
- def test_callbackReturnsNonCallingDeferred(self):
- #hacky timeout
- # raises KeyboardInterrupt because Trial sucks
- from twisted.internet import reactor
- call = reactor.callLater(2, reactor.crash)
- result = self.runTest('test_calledButNeverCallback')
- if call.active():
- call.cancel()
- self.failIf(result.wasSuccessful())
- self._wasTimeout(result.errors[0][1])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_doctest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_doctest.py
deleted file mode 100755
index 4506bed1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_doctest.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test Twisted's doctest support.
-"""
-
-from twisted.trial import itrial, runner, unittest, reporter
-from twisted.trial.test import mockdoctest
-
-
-class TestRunners(unittest.TestCase):
- """
- Tests for Twisted's doctest support.
- """
-
- def test_id(self):
- """
- Check that the id() of the doctests' case object contains the FQPN of
- the actual tests. We need this because id() has weird behaviour w/
- doctest in Python 2.3.
- """
- loader = runner.TestLoader()
- suite = loader.loadDoctests(mockdoctest)
- idPrefix = 'twisted.trial.test.mockdoctest.Counter'
- for test in suite._tests:
- self.assertIn(idPrefix, itrial.ITestCase(test).id())
-
-
- def test_basicTrialIntegration(self):
- """
- L{loadDoctests} loads all of the doctests in the given module.
- """
- loader = runner.TestLoader()
- suite = loader.loadDoctests(mockdoctest)
- self.assertEqual(7, suite.countTestCases())
-
-
- def _testRun(self, suite):
- """
- Run C{suite} and check the result.
- """
- result = reporter.TestResult()
- suite.run(result)
- self.assertEqual(5, result.successes)
- # doctest reports failures as errors in 2.3
- self.assertEqual(2, len(result.errors) + len(result.failures))
-
-
- def test_expectedResults(self, count=1):
- """
- Trial can correctly run doctests with its xUnit test APIs.
- """
- suite = runner.TestLoader().loadDoctests(mockdoctest)
- self._testRun(suite)
-
-
- def test_repeatable(self):
- """
- Doctests should be runnable repeatably.
- """
- suite = runner.TestLoader().loadDoctests(mockdoctest)
- self._testRun(suite)
- self._testRun(suite)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_keyboard.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_keyboard.py
deleted file mode 100755
index c5471a5e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_keyboard.py
+++ /dev/null
@@ -1,113 +0,0 @@
-import StringIO
-from twisted.trial import unittest
-from twisted.trial import reporter, runner
-
-
-class TrialTest(unittest.TestCase):
- def setUp(self):
- self.output = StringIO.StringIO()
- self.reporter = reporter.TestResult()
- self.loader = runner.TestLoader()
-
-
-class TestInterruptInTest(TrialTest):
- class InterruptedTest(unittest.TestCase):
- def test_02_raiseInterrupt(self):
- raise KeyboardInterrupt
-
- def test_01_doNothing(self):
- pass
-
- def test_03_doNothing(self):
- TestInterruptInTest.test_03_doNothing_run = True
-
- def setUp(self):
- super(TestInterruptInTest, self).setUp()
- self.suite = self.loader.loadClass(TestInterruptInTest.InterruptedTest)
- TestInterruptInTest.test_03_doNothing_run = None
-
- def test_setUpOK(self):
- self.assertEqual(3, self.suite.countTestCases())
- self.assertEqual(0, self.reporter.testsRun)
- self.failIf(self.reporter.shouldStop)
-
- def test_interruptInTest(self):
- runner.TrialSuite([self.suite]).run(self.reporter)
- self.failUnless(self.reporter.shouldStop)
- self.assertEqual(2, self.reporter.testsRun)
- self.failIf(TestInterruptInTest.test_03_doNothing_run,
- "test_03_doNothing ran.")
-
-
-class TestInterruptInSetUp(TrialTest):
- testsRun = 0
-
- class InterruptedTest(unittest.TestCase):
- def setUp(self):
- if TestInterruptInSetUp.testsRun > 0:
- raise KeyboardInterrupt
-
- def test_01(self):
- TestInterruptInSetUp.testsRun += 1
-
- def test_02(self):
- TestInterruptInSetUp.testsRun += 1
- TestInterruptInSetUp.test_02_run = True
-
- def setUp(self):
- super(TestInterruptInSetUp, self).setUp()
- self.suite = self.loader.loadClass(
- TestInterruptInSetUp.InterruptedTest)
- TestInterruptInSetUp.test_02_run = False
- TestInterruptInSetUp.testsRun = 0
-
- def test_setUpOK(self):
- self.assertEqual(0, TestInterruptInSetUp.testsRun)
- self.assertEqual(2, self.suite.countTestCases())
- self.assertEqual(0, self.reporter.testsRun)
- self.failIf(self.reporter.shouldStop)
-
- def test_interruptInSetUp(self):
- runner.TrialSuite([self.suite]).run(self.reporter)
- self.failUnless(self.reporter.shouldStop)
- self.assertEqual(2, self.reporter.testsRun)
- self.failIf(TestInterruptInSetUp.test_02_run,
- "test_02 ran")
-
-
-class TestInterruptInTearDown(TrialTest):
- testsRun = 0
-
- class InterruptedTest(unittest.TestCase):
- def tearDown(self):
- if TestInterruptInTearDown.testsRun > 0:
- raise KeyboardInterrupt
-
- def test_01(self):
- TestInterruptInTearDown.testsRun += 1
-
- def test_02(self):
- TestInterruptInTearDown.testsRun += 1
- TestInterruptInTearDown.test_02_run = True
-
- def setUp(self):
- super(TestInterruptInTearDown, self).setUp()
- self.suite = self.loader.loadClass(
- TestInterruptInTearDown.InterruptedTest)
- TestInterruptInTearDown.testsRun = 0
- TestInterruptInTearDown.test_02_run = False
-
- def test_setUpOK(self):
- self.assertEqual(0, TestInterruptInTearDown.testsRun)
- self.assertEqual(2, self.suite.countTestCases())
- self.assertEqual(0, self.reporter.testsRun)
- self.failIf(self.reporter.shouldStop)
-
- def test_interruptInTearDown(self):
- runner.TrialSuite([self.suite]).run(self.reporter)
- self.assertEqual(1, self.reporter.testsRun)
- self.failUnless(self.reporter.shouldStop)
- self.failIf(TestInterruptInTearDown.test_02_run,
- "test_02 ran")
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_loader.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_loader.py
deleted file mode 100755
index f08588e2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_loader.py
+++ /dev/null
@@ -1,611 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for loading tests by name.
-"""
-
-import os
-import shutil
-import sys
-
-from twisted.python import util
-from twisted.python.hashlib import md5
-from twisted.trial.test import packages
-from twisted.trial import runner, reporter, unittest
-from twisted.trial.itrial import ITestCase
-
-from twisted.python.modules import getModule
-
-
-
-def testNames(tests):
- """
- Return the id of each test within the given test suite or case.
- """
- names = []
- for test in unittest._iterateTests(tests):
- names.append(test.id())
- return names
-
-
-
-class FinderTest(packages.PackageTest):
- def setUp(self):
- packages.PackageTest.setUp(self)
- self.loader = runner.TestLoader()
-
- def tearDown(self):
- packages.PackageTest.tearDown(self)
-
- def test_findPackage(self):
- sample1 = self.loader.findByName('twisted')
- import twisted as sample2
- self.assertEqual(sample1, sample2)
-
- def test_findModule(self):
- sample1 = self.loader.findByName('twisted.trial.test.sample')
- import sample as sample2
- self.assertEqual(sample1, sample2)
-
- def test_findFile(self):
- path = util.sibpath(__file__, 'sample.py')
- sample1 = self.loader.findByName(path)
- import sample as sample2
- self.assertEqual(sample1, sample2)
-
- def test_findObject(self):
- sample1 = self.loader.findByName('twisted.trial.test.sample.FooTest')
- import sample
- self.assertEqual(sample.FooTest, sample1)
-
- def test_findNonModule(self):
- self.failUnlessRaises(AttributeError,
- self.loader.findByName,
- 'twisted.trial.test.nonexistent')
-
- def test_findNonPackage(self):
- self.failUnlessRaises(ValueError,
- self.loader.findByName,
- 'nonextant')
-
- def test_findNonFile(self):
- path = util.sibpath(__file__, 'nonexistent.py')
- self.failUnlessRaises(ValueError, self.loader.findByName, path)
-
-
-
-class FileTest(packages.SysPathManglingTest):
- """
- Tests for L{runner.filenameToModule}.
- """
- def test_notFile(self):
- self.failUnlessRaises(ValueError,
- runner.filenameToModule, 'doesntexist')
-
- def test_moduleInPath(self):
- sample1 = runner.filenameToModule(util.sibpath(__file__, 'sample.py'))
- import sample as sample2
- self.assertEqual(sample2, sample1)
-
-
- def test_moduleNotInPath(self):
- """
- If passed the path to a file containing the implementation of a
- module within a package which is not on the import path,
- L{runner.filenameToModule} returns a module object loosely
- resembling the module defined by that file anyway.
- """
- # "test_sample" isn't actually the name of this module. However,
- # filenameToModule can't seem to figure that out. So clean up this
- # mis-named module. It would be better if this weren't necessary
- # and filenameToModule either didn't exist or added a correctly
- # named module to sys.modules.
- self.addCleanup(sys.modules.pop, 'test_sample', None)
-
- self.mangleSysPath(self.oldPath)
- sample1 = runner.filenameToModule(
- os.path.join(self.parent, 'goodpackage', 'test_sample.py'))
- self.mangleSysPath(self.newPath)
- from goodpackage import test_sample as sample2
- self.assertEqual(os.path.splitext(sample2.__file__)[0],
- os.path.splitext(sample1.__file__)[0])
-
-
- def test_packageInPath(self):
- package1 = runner.filenameToModule(os.path.join(self.parent,
- 'goodpackage'))
- import goodpackage
- self.assertEqual(goodpackage, package1)
-
-
- def test_packageNotInPath(self):
- """
- If passed the path to a directory which represents a package which
- is not on the import path, L{runner.filenameToModule} returns a
- module object loosely resembling the package defined by that
- directory anyway.
- """
- # "__init__" isn't actually the name of the package! However,
- # filenameToModule is pretty stupid and decides that is its name
- # after all. Make sure it gets cleaned up. See the comment in
- # test_moduleNotInPath for possible courses of action related to
- # this.
- self.addCleanup(sys.modules.pop, "__init__")
-
- self.mangleSysPath(self.oldPath)
- package1 = runner.filenameToModule(
- os.path.join(self.parent, 'goodpackage'))
- self.mangleSysPath(self.newPath)
- import goodpackage
- self.assertEqual(os.path.splitext(goodpackage.__file__)[0],
- os.path.splitext(package1.__file__)[0])
-
-
- def test_directoryNotPackage(self):
- self.failUnlessRaises(ValueError, runner.filenameToModule,
- util.sibpath(__file__, 'directory'))
-
- def test_filenameNotPython(self):
- self.failUnlessRaises(ValueError, runner.filenameToModule,
- util.sibpath(__file__, 'notpython.py'))
-
- def test_filenameMatchesPackage(self):
- filename = os.path.join(self.parent, 'goodpackage.py')
- fd = open(filename, 'w')
- fd.write(packages.testModule)
- fd.close()
- try:
- module = runner.filenameToModule(filename)
- self.assertEqual(filename, module.__file__)
- finally:
- os.remove(filename)
-
- def test_directory(self):
- """
- Test loader against a filesystem directory. It should handle
- 'path' and 'path/' the same way.
- """
- path = util.sibpath(__file__, 'goodDirectory')
- os.mkdir(path)
- f = file(os.path.join(path, '__init__.py'), "w")
- f.close()
- try:
- module = runner.filenameToModule(path)
- self.assert_(module.__name__.endswith('goodDirectory'))
- module = runner.filenameToModule(path + os.path.sep)
- self.assert_(module.__name__.endswith('goodDirectory'))
- finally:
- shutil.rmtree(path)
-
-
-
-class LoaderTest(packages.SysPathManglingTest):
- """
- Tests for L{trial.TestLoader}.
- """
-
- def setUp(self):
- self.loader = runner.TestLoader()
- packages.SysPathManglingTest.setUp(self)
-
-
- def test_sortCases(self):
- import sample
- suite = self.loader.loadClass(sample.AlphabetTest)
- self.assertEqual(['test_a', 'test_b', 'test_c'],
- [test._testMethodName for test in suite._tests])
- newOrder = ['test_b', 'test_c', 'test_a']
- sortDict = dict(zip(newOrder, range(3)))
- self.loader.sorter = lambda x : sortDict.get(x.shortDescription(), -1)
- suite = self.loader.loadClass(sample.AlphabetTest)
- self.assertEqual(newOrder,
- [test._testMethodName for test in suite._tests])
-
-
- def test_loadMethod(self):
- import sample
- suite = self.loader.loadMethod(sample.FooTest.test_foo)
- self.assertEqual(1, suite.countTestCases())
- self.assertEqual('test_foo', suite._testMethodName)
-
-
- def test_loadFailingMethod(self):
- # test added for issue1353
- import erroneous
- suite = self.loader.loadMethod(erroneous.TestRegularFail.test_fail)
- result = reporter.TestResult()
- suite.run(result)
- self.assertEqual(result.testsRun, 1)
- self.assertEqual(len(result.failures), 1)
-
-
- def test_loadNonMethod(self):
- import sample
- self.failUnlessRaises(TypeError, self.loader.loadMethod, sample)
- self.failUnlessRaises(TypeError,
- self.loader.loadMethod, sample.FooTest)
- self.failUnlessRaises(TypeError, self.loader.loadMethod, "string")
- self.failUnlessRaises(TypeError,
- self.loader.loadMethod, ('foo', 'bar'))
-
-
- def test_loadBadDecorator(self):
- """
- A decorated test method for which the decorator has failed to set the
- method's __name__ correctly is loaded and its name in the class scope
- discovered.
- """
- import sample
- suite = self.loader.loadMethod(sample.DecorationTest.test_badDecorator)
- self.assertEqual(1, suite.countTestCases())
- self.assertEqual('test_badDecorator', suite._testMethodName)
-
-
- def test_loadGoodDecorator(self):
- """
- A decorated test method for which the decorator has set the method's
- __name__ correctly is loaded and the only name by which it goes is used.
- """
- import sample
- suite = self.loader.loadMethod(
- sample.DecorationTest.test_goodDecorator)
- self.assertEqual(1, suite.countTestCases())
- self.assertEqual('test_goodDecorator', suite._testMethodName)
-
-
- def test_loadRenamedDecorator(self):
- """
- Load a decorated method which has been copied to a new name inside the
- class. Thus its __name__ and its key in the class's __dict__ no
- longer match.
- """
- import sample
- suite = self.loader.loadMethod(
- sample.DecorationTest.test_renamedDecorator)
- self.assertEqual(1, suite.countTestCases())
- self.assertEqual('test_renamedDecorator', suite._testMethodName)
-
-
- def test_loadClass(self):
- import sample
- suite = self.loader.loadClass(sample.FooTest)
- self.assertEqual(2, suite.countTestCases())
- self.assertEqual(['test_bar', 'test_foo'],
- [test._testMethodName for test in suite._tests])
-
-
- def test_loadNonClass(self):
- import sample
- self.failUnlessRaises(TypeError, self.loader.loadClass, sample)
- self.failUnlessRaises(TypeError,
- self.loader.loadClass, sample.FooTest.test_foo)
- self.failUnlessRaises(TypeError, self.loader.loadClass, "string")
- self.failUnlessRaises(TypeError,
- self.loader.loadClass, ('foo', 'bar'))
-
-
- def test_loadNonTestCase(self):
- import sample
- self.failUnlessRaises(ValueError, self.loader.loadClass,
- sample.NotATest)
-
-
- def test_loadModule(self):
- import sample
- suite = self.loader.loadModule(sample)
- self.assertEqual(10, suite.countTestCases())
-
-
- def test_loadNonModule(self):
- import sample
- self.failUnlessRaises(TypeError,
- self.loader.loadModule, sample.FooTest)
- self.failUnlessRaises(TypeError,
- self.loader.loadModule, sample.FooTest.test_foo)
- self.failUnlessRaises(TypeError, self.loader.loadModule, "string")
- self.failUnlessRaises(TypeError,
- self.loader.loadModule, ('foo', 'bar'))
-
-
- def test_loadPackage(self):
- import goodpackage
- suite = self.loader.loadPackage(goodpackage)
- self.assertEqual(7, suite.countTestCases())
-
-
- def test_loadNonPackage(self):
- import sample
- self.failUnlessRaises(TypeError,
- self.loader.loadPackage, sample.FooTest)
- self.failUnlessRaises(TypeError,
- self.loader.loadPackage, sample.FooTest.test_foo)
- self.failUnlessRaises(TypeError, self.loader.loadPackage, "string")
- self.failUnlessRaises(TypeError,
- self.loader.loadPackage, ('foo', 'bar'))
-
-
- def test_loadModuleAsPackage(self):
- import sample
- ## XXX -- should this instead raise a ValueError? -- jml
- self.failUnlessRaises(TypeError, self.loader.loadPackage, sample)
-
-
- def test_loadPackageRecursive(self):
- import goodpackage
- suite = self.loader.loadPackage(goodpackage, recurse=True)
- self.assertEqual(14, suite.countTestCases())
-
-
- def test_loadAnythingOnModule(self):
- import sample
- suite = self.loader.loadAnything(sample)
- self.assertEqual(sample.__name__,
- suite._tests[0]._tests[0].__class__.__module__)
-
-
- def test_loadAnythingOnClass(self):
- import sample
- suite = self.loader.loadAnything(sample.FooTest)
- self.assertEqual(2, suite.countTestCases())
-
-
- def test_loadAnythingOnMethod(self):
- import sample
- suite = self.loader.loadAnything(sample.FooTest.test_foo)
- self.assertEqual(1, suite.countTestCases())
-
-
- def test_loadAnythingOnPackage(self):
- import goodpackage
- suite = self.loader.loadAnything(goodpackage)
- self.failUnless(isinstance(suite, self.loader.suiteFactory))
- self.assertEqual(7, suite.countTestCases())
-
-
- def test_loadAnythingOnPackageRecursive(self):
- import goodpackage
- suite = self.loader.loadAnything(goodpackage, recurse=True)
- self.failUnless(isinstance(suite, self.loader.suiteFactory))
- self.assertEqual(14, suite.countTestCases())
-
-
- def test_loadAnythingOnString(self):
- # the important thing about this test is not the string-iness
- # but the non-handledness.
- self.failUnlessRaises(TypeError,
- self.loader.loadAnything, "goodpackage")
-
-
- def test_importErrors(self):
- import package
- suite = self.loader.loadPackage(package, recurse=True)
- result = reporter.Reporter()
- suite.run(result)
- self.assertEqual(False, result.wasSuccessful())
- self.assertEqual(2, len(result.errors))
- errors = [test.id() for test, error in result.errors]
- errors.sort()
- self.assertEqual(errors, ['package.test_bad_module',
- 'package.test_import_module'])
-
-
- def test_differentInstances(self):
- """
- L{TestLoader.loadClass} returns a suite with each test method
- represented by a different instances of the L{TestCase} they are
- defined on.
- """
- class DistinctInstances(unittest.TestCase):
- def test_1(self):
- self.first = 'test1Run'
-
- def test_2(self):
- self.assertFalse(hasattr(self, 'first'))
-
- suite = self.loader.loadClass(DistinctInstances)
- result = reporter.Reporter()
- suite.run(result)
- self.assertTrue(result.wasSuccessful())
-
-
- def test_loadModuleWith_test_suite(self):
- """
- Check that C{test_suite} is used when present and other L{TestCase}s are
- not included.
- """
- from twisted.trial.test import mockcustomsuite
- suite = self.loader.loadModule(mockcustomsuite)
- self.assertEqual(0, suite.countTestCases())
- self.assertEqual("MyCustomSuite", getattr(suite, 'name', None))
-
-
- def test_loadModuleWith_testSuite(self):
- """
- Check that C{testSuite} is used when present and other L{TestCase}s are
- not included.
- """
- from twisted.trial.test import mockcustomsuite2
- suite = self.loader.loadModule(mockcustomsuite2)
- self.assertEqual(0, suite.countTestCases())
- self.assertEqual("MyCustomSuite", getattr(suite, 'name', None))
-
-
- def test_loadModuleWithBothCustom(self):
- """
- Check that if C{testSuite} and C{test_suite} are both present in a
- module then C{testSuite} gets priority.
- """
- from twisted.trial.test import mockcustomsuite3
- suite = self.loader.loadModule(mockcustomsuite3)
- self.assertEqual('testSuite', getattr(suite, 'name', None))
-
-
- def test_customLoadRaisesAttributeError(self):
- """
- Make sure that any C{AttributeError}s raised by C{testSuite} are not
- swallowed by L{TestLoader}.
- """
- def testSuite():
- raise AttributeError('should be reraised')
- from twisted.trial.test import mockcustomsuite2
- mockcustomsuite2.testSuite, original = (testSuite,
- mockcustomsuite2.testSuite)
- try:
- self.assertRaises(AttributeError, self.loader.loadModule,
- mockcustomsuite2)
- finally:
- mockcustomsuite2.testSuite = original
-
-
- # XXX - duplicated and modified from test_script
- def assertSuitesEqual(self, test1, test2):
- names1 = testNames(test1)
- names2 = testNames(test2)
- names1.sort()
- names2.sort()
- self.assertEqual(names1, names2)
-
-
- def test_loadByNamesDuplicate(self):
- """
- Check that loadByNames ignores duplicate names
- """
- module = 'twisted.trial.test.test_test_visitor'
- suite1 = self.loader.loadByNames([module, module], True)
- suite2 = self.loader.loadByName(module, True)
- self.assertSuitesEqual(suite1, suite2)
-
-
- def test_loadDifferentNames(self):
- """
- Check that loadByNames loads all the names that it is given
- """
- modules = ['goodpackage', 'package.test_module']
- suite1 = self.loader.loadByNames(modules)
- suite2 = runner.TestSuite(map(self.loader.loadByName, modules))
- self.assertSuitesEqual(suite1, suite2)
-
- def test_loadInheritedMethods(self):
- """
- Check that test methods names which are inherited from are all
- loaded rather than just one.
- """
- methods = ['inheritancepackage.test_x.A.test_foo',
- 'inheritancepackage.test_x.B.test_foo']
- suite1 = self.loader.loadByNames(methods)
- suite2 = runner.TestSuite(map(self.loader.loadByName, methods))
- self.assertSuitesEqual(suite1, suite2)
-
-
-
-class ZipLoadingTest(LoaderTest):
- def setUp(self):
- from twisted.test.test_paths import zipit
- LoaderTest.setUp(self)
- zipit(self.parent, self.parent+'.zip')
- self.parent += '.zip'
- self.mangleSysPath(self.oldPath+[self.parent])
-
-
-
-class PackageOrderingTest(packages.SysPathManglingTest):
- if sys.version_info < (2, 4):
- skip = (
- "Python 2.3 import semantics make this behavior incorrect on that "
- "version of Python as well as difficult to test. The second "
- "import of a package which raised an exception the first time it "
- "was imported will succeed on Python 2.3, whereas it will fail on "
- "later versions of Python. Trial does not account for this, so "
- "this test fails with inconsistencies between the expected and "
- "the received loader errors.")
-
- def setUp(self):
- self.loader = runner.TestLoader()
- self.topDir = self.mktemp()
- parent = os.path.join(self.topDir, "uberpackage")
- os.makedirs(parent)
- file(os.path.join(parent, "__init__.py"), "wb").close()
- packages.SysPathManglingTest.setUp(self, parent)
- self.mangleSysPath(self.oldPath + [self.topDir])
-
- def _trialSortAlgorithm(self, sorter):
- """
- Right now, halfway by accident, trial sorts like this:
-
- 1. all modules are grouped together in one list and sorted.
-
- 2. within each module, the classes are grouped together in one list
- and sorted.
-
- 3. finally within each class, each test method is grouped together
- in a list and sorted.
-
- This attempts to return a sorted list of testable thingies following
- those rules, so that we can compare the behavior of loadPackage.
-
- The things that show as 'cases' are errors from modules which failed to
- import, and test methods. Let's gather all those together.
- """
- pkg = getModule('uberpackage')
- testModules = []
- for testModule in pkg.walkModules():
- if testModule.name.split(".")[-1].startswith("test_"):
- testModules.append(testModule)
- sortedModules = sorted(testModules, key=sorter) # ONE
- for modinfo in sortedModules:
- # Now let's find all the classes.
- module = modinfo.load(None)
- if module is None:
- yield modinfo
- else:
- testClasses = []
- for attrib in modinfo.iterAttributes():
- if runner.isTestCase(attrib.load()):
- testClasses.append(attrib)
- sortedClasses = sorted(testClasses, key=sorter) # TWO
- for clsinfo in sortedClasses:
- testMethods = []
- for attr in clsinfo.iterAttributes():
- if attr.name.split(".")[-1].startswith('test'):
- testMethods.append(attr)
- sortedMethods = sorted(testMethods, key=sorter) # THREE
- for methinfo in sortedMethods:
- yield methinfo
-
-
- def loadSortedPackages(self, sorter=runner.name):
- """
- Verify that packages are loaded in the correct order.
- """
- import uberpackage
- self.loader.sorter = sorter
- suite = self.loader.loadPackage(uberpackage, recurse=True)
- # XXX: Work around strange, unexplained Zope crap.
- # jml, 2007-11-15.
- suite = unittest.decorate(suite, ITestCase)
- resultingTests = list(unittest._iterateTests(suite))
- manifest = list(self._trialSortAlgorithm(sorter))
- for number, (manifestTest, actualTest) in enumerate(
- zip(manifest, resultingTests)):
- self.assertEqual(
- manifestTest.name, actualTest.id(),
- "#%d: %s != %s" %
- (number, manifestTest.name, actualTest.id()))
- self.assertEqual(len(manifest), len(resultingTests))
-
-
- def test_sortPackagesDefaultOrder(self):
- self.loadSortedPackages()
-
-
- def test_sortPackagesSillyOrder(self):
- def sillySorter(s):
- # This has to work on fully-qualified class names and class
- # objects, which is silly, but it's the "spec", such as it is.
-# if isinstance(s, type) or isinstance(s, types.ClassType):
-# return s.__module__+'.'+s.__name__
- n = runner.name(s)
- d = md5(n).hexdigest()
- return d
- self.loadSortedPackages(sillySorter)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_log.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_log.py
deleted file mode 100755
index a2865506..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_log.py
+++ /dev/null
@@ -1,235 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test the interaction between trial and errors logged during test run.
-"""
-from __future__ import division
-
-import time
-
-from twisted.internet import reactor, task
-from twisted.python import failure, log
-from twisted.trial import unittest, reporter
-
-
-def makeFailure():
- """
- Return a new, realistic failure.
- """
- try:
- 1/0
- except ZeroDivisionError:
- f = failure.Failure()
- return f
-
-
-
-class Mask(object):
- """
- Hide C{MockTest}s from Trial's automatic test finder.
- """
- class FailureLoggingMixin(object):
- def test_silent(self):
- """
- Don't log any errors.
- """
-
- def test_single(self):
- """
- Log a single error.
- """
- log.err(makeFailure())
-
- def test_double(self):
- """
- Log two errors.
- """
- log.err(makeFailure())
- log.err(makeFailure())
-
-
- class SynchronousFailureLogging(FailureLoggingMixin, unittest.SynchronousTestCase):
- pass
-
-
- class AsynchronousFailureLogging(FailureLoggingMixin, unittest.TestCase):
- def test_inCallback(self):
- """
- Log an error in an asynchronous callback.
- """
- return task.deferLater(reactor, 0, lambda: log.err(makeFailure()))
-
-
-
-class TestObserver(unittest.SynchronousTestCase):
- """
- Tests for L{unittest._LogObserver}, a helper for the implementation of
- L{SynchronousTestCase.flushLoggedErrors}.
- """
- def setUp(self):
- self.result = reporter.TestResult()
- self.observer = unittest._LogObserver()
-
-
- def test_msg(self):
- """
- Test that a standard log message doesn't go anywhere near the result.
- """
- self.observer.gotEvent({'message': ('some message',),
- 'time': time.time(), 'isError': 0,
- 'system': '-'})
- self.assertEqual(self.observer.getErrors(), [])
-
-
- def test_error(self):
- """
- Test that an observed error gets added to the result
- """
- f = makeFailure()
- self.observer.gotEvent({'message': (),
- 'time': time.time(), 'isError': 1,
- 'system': '-', 'failure': f,
- 'why': None})
- self.assertEqual(self.observer.getErrors(), [f])
-
-
- def test_flush(self):
- """
- Check that flushing the observer with no args removes all errors.
- """
- self.test_error()
- flushed = self.observer.flushErrors()
- self.assertEqual(self.observer.getErrors(), [])
- self.assertEqual(len(flushed), 1)
- self.assertTrue(flushed[0].check(ZeroDivisionError))
-
-
- def _makeRuntimeFailure(self):
- return failure.Failure(RuntimeError('test error'))
-
-
- def test_flushByType(self):
- """
- Check that flushing the observer remove all failures of the given type.
- """
- self.test_error() # log a ZeroDivisionError to the observer
- f = self._makeRuntimeFailure()
- self.observer.gotEvent(dict(message=(), time=time.time(), isError=1,
- system='-', failure=f, why=None))
- flushed = self.observer.flushErrors(ZeroDivisionError)
- self.assertEqual(self.observer.getErrors(), [f])
- self.assertEqual(len(flushed), 1)
- self.assertTrue(flushed[0].check(ZeroDivisionError))
-
-
- def test_ignoreErrors(self):
- """
- Check that C{_ignoreErrors} actually causes errors to be ignored.
- """
- self.observer._ignoreErrors(ZeroDivisionError)
- f = makeFailure()
- self.observer.gotEvent({'message': (),
- 'time': time.time(), 'isError': 1,
- 'system': '-', 'failure': f,
- 'why': None})
- self.assertEqual(self.observer.getErrors(), [])
-
-
- def test_clearIgnores(self):
- """
- Check that C{_clearIgnores} ensures that previously ignored errors
- get captured.
- """
- self.observer._ignoreErrors(ZeroDivisionError)
- self.observer._clearIgnores()
- f = makeFailure()
- self.observer.gotEvent({'message': (),
- 'time': time.time(), 'isError': 1,
- 'system': '-', 'failure': f,
- 'why': None})
- self.assertEqual(self.observer.getErrors(), [f])
-
-
-
-class LogErrorsMixin(object):
- """
- High-level tests demonstrating the expected behaviour of logged errors
- during tests.
- """
-
- def setUp(self):
- self.result = reporter.TestResult()
-
- def tearDown(self):
- self.flushLoggedErrors(ZeroDivisionError)
-
-
- def test_singleError(self):
- """
- Test that a logged error gets reported as a test error.
- """
- test = self.MockTest('test_single')
- test(self.result)
- self.assertEqual(len(self.result.errors), 1)
- self.assertTrue(self.result.errors[0][1].check(ZeroDivisionError),
- self.result.errors[0][1])
- self.assertEqual(0, self.result.successes)
-
-
- def test_twoErrors(self):
- """
- Test that when two errors get logged, they both get reported as test
- errors.
- """
- test = self.MockTest('test_double')
- test(self.result)
- self.assertEqual(len(self.result.errors), 2)
- self.assertEqual(0, self.result.successes)
-
-
- def test_errorsIsolated(self):
- """
- Check that an error logged in one test doesn't fail the next test.
- """
- t1 = self.MockTest('test_single')
- t2 = self.MockTest('test_silent')
- t1(self.result)
- t2(self.result)
- self.assertEqual(len(self.result.errors), 1)
- self.assertEqual(self.result.errors[0][0], t1)
- self.assertEqual(1, self.result.successes)
-
-
- def test_boundedObservers(self):
- """
- There are no extra log observers after a test runs.
- """
- # XXX trial is *all about* global log state. It should really be fixed.
- observer = unittest._LogObserver()
- self.patch(unittest, '_logObserver', observer)
- observers = log.theLogPublisher.observers[:]
- test = self.MockTest()
- test(self.result)
- self.assertEqual(observers, log.theLogPublisher.observers)
-
-
-
-class SynchronousLogErrorsTests(LogErrorsMixin, unittest.SynchronousTestCase):
- MockTest = Mask.SynchronousFailureLogging
-
-
-
-class AsynchronousLogErrorsTests(LogErrorsMixin, unittest.TestCase):
- MockTest = Mask.AsynchronousFailureLogging
-
- def test_inCallback(self):
- """
- Test that errors logged in callbacks get reported as test errors.
- """
- test = self.MockTest('test_inCallback')
- test(self.result)
- self.assertEqual(len(self.result.errors), 1)
- self.assertTrue(self.result.errors[0][1].check(ZeroDivisionError),
- self.result.errors[0][1])
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_output.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_output.py
deleted file mode 100755
index bedde9e2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_output.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the output generated by trial.
-"""
-
-import os, StringIO
-
-from twisted.scripts import trial
-from twisted.trial import runner
-from twisted.trial.test import packages
-
-
-def runTrial(*args):
- from twisted.trial import reporter
- config = trial.Options()
- config.parseOptions(args)
- output = StringIO.StringIO()
- myRunner = runner.TrialRunner(
- reporter.VerboseTextReporter,
- stream=output,
- workingDirectory=config['temp-directory'])
- suite = trial._getSuite(config)
- result = myRunner.run(suite)
- return output.getvalue()
-
-
-class TestImportErrors(packages.SysPathManglingTest):
- """Actually run trial as if on the command line and check that the output
- is what we expect.
- """
-
- debug = False
- parent = "_testImportErrors"
- def runTrial(self, *args):
- return runTrial('--temp-directory', self.mktemp(), *args)
-
- def _print(self, stuff):
- print stuff
- return stuff
-
- def failUnlessIn(self, container, containee, *args, **kwargs):
- # redefined to be useful in callbacks
- super(TestImportErrors, self).failUnlessIn(
- containee, container, *args, **kwargs)
- return container
-
- def failIfIn(self, container, containee, *args, **kwargs):
- # redefined to be useful in callbacks
- super(TestImportErrors, self).failIfIn(
- containee, container, *args, **kwargs)
- return container
-
- def test_trialRun(self):
- self.runTrial()
-
- def test_nonexistentModule(self):
- d = self.runTrial('twisted.doesntexist')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, 'twisted.doesntexist')
- return d
-
- def test_nonexistentPackage(self):
- d = self.runTrial('doesntexist')
- self.failUnlessIn(d, 'doesntexist')
- self.failUnlessIn(d, 'ModuleNotFound')
- self.failUnlessIn(d, '[ERROR]')
- return d
-
- def test_nonexistentPackageWithModule(self):
- d = self.runTrial('doesntexist.barney')
- self.failUnlessIn(d, 'doesntexist.barney')
- self.failUnlessIn(d, 'ObjectNotFound')
- self.failUnlessIn(d, '[ERROR]')
- return d
-
- def test_badpackage(self):
- d = self.runTrial('badpackage')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, 'badpackage')
- self.failIfIn(d, 'IOError')
- return d
-
- def test_moduleInBadpackage(self):
- d = self.runTrial('badpackage.test_module')
- self.failUnlessIn(d, "[ERROR]")
- self.failUnlessIn(d, "badpackage.test_module")
- self.failIfIn(d, 'IOError')
- return d
-
- def test_badmodule(self):
- d = self.runTrial('package.test_bad_module')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, 'package.test_bad_module')
- self.failIfIn(d, 'IOError')
- self.failIfIn(d, '<module ')
- return d
-
- def test_badimport(self):
- d = self.runTrial('package.test_import_module')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, 'package.test_import_module')
- self.failIfIn(d, 'IOError')
- self.failIfIn(d, '<module ')
- return d
-
- def test_recurseImport(self):
- d = self.runTrial('package')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, 'test_bad_module')
- self.failUnlessIn(d, 'test_import_module')
- self.failIfIn(d, '<module ')
- self.failIfIn(d, 'IOError')
- return d
-
- def test_recurseImportErrors(self):
- d = self.runTrial('package2')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, 'package2')
- self.failUnlessIn(d, 'test_module')
- self.failUnlessIn(d, "No module named frotz")
- self.failIfIn(d, '<module ')
- self.failIfIn(d, 'IOError')
- return d
-
- def test_nonRecurseImportErrors(self):
- d = self.runTrial('-N', 'package2')
- self.failUnlessIn(d, '[ERROR]')
- self.failUnlessIn(d, "No module named frotz")
- self.failIfIn(d, '<module ')
- return d
-
- def test_regularRun(self):
- d = self.runTrial('package.test_module')
- self.failIfIn(d, '[ERROR]')
- self.failIfIn(d, 'IOError')
- self.failUnlessIn(d, 'OK')
- self.failUnlessIn(d, 'PASSED (successes=1)')
- return d
-
- def test_filename(self):
- self.mangleSysPath(self.oldPath)
- d = self.runTrial(
- os.path.join(self.parent, 'package', 'test_module.py'))
- self.failIfIn(d, '[ERROR]')
- self.failIfIn(d, 'IOError')
- self.failUnlessIn(d, 'OK')
- self.failUnlessIn(d, 'PASSED (successes=1)')
- return d
-
- def test_dosFile(self):
- ## XXX -- not really an output test, more of a script test
- self.mangleSysPath(self.oldPath)
- d = self.runTrial(
- os.path.join(self.parent,
- 'package', 'test_dos_module.py'))
- self.failIfIn(d, '[ERROR]')
- self.failIfIn(d, 'IOError')
- self.failUnlessIn(d, 'OK')
- self.failUnlessIn(d, 'PASSED (successes=1)')
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_plugins.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_plugins.py
deleted file mode 100755
index e1ec6aa7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_plugins.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-# Maintainer: Jonathan Lange
-
-"""
-Tests for L{twisted.plugins.twisted_trial}.
-"""
-
-from twisted.plugin import getPlugins
-from twisted.trial import unittest
-from twisted.trial.itrial import IReporter
-
-
-class TestPlugins(unittest.TestCase):
- """
- Tests for Trial's reporter plugins.
- """
-
- def getPluginsByLongOption(self, longOption):
- """
- Return the Trial reporter plugin with the given long option.
-
- If more than one is found, raise ValueError. If none are found, raise
- IndexError.
- """
- plugins = [
- plugin for plugin in getPlugins(IReporter)
- if plugin.longOpt == longOption]
- if len(plugins) > 1:
- raise ValueError(
- "More than one plugin found with long option %r: %r"
- % (longOption, plugins))
- return plugins[0]
-
-
- def test_subunitPlugin(self):
- """
- One of the reporter plugins is the subunit reporter plugin.
- """
- subunitPlugin = self.getPluginsByLongOption('subunit')
- self.assertEqual('Subunit Reporter', subunitPlugin.name)
- self.assertEqual('twisted.trial.reporter', subunitPlugin.module)
- self.assertEqual('subunit', subunitPlugin.longOpt)
- self.assertIdentical(None, subunitPlugin.shortOpt)
- self.assertEqual('SubunitReporter', subunitPlugin.klass)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_pyunitcompat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_pyunitcompat.py
deleted file mode 100755
index 7b851541..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_pyunitcompat.py
+++ /dev/null
@@ -1,222 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-# Maintainer: Jonathan Lange
-from __future__ import division
-
-import sys
-import traceback
-
-from zope.interface import implements
-
-from twisted.python import reflect
-from twisted.python.failure import Failure
-from twisted.trial import util
-from twisted.trial.unittest import TestCase, PyUnitResultAdapter
-from twisted.trial.itrial import IReporter, ITestCase
-from twisted.trial.test import erroneous
-
-pyunit = __import__('unittest')
-
-
-class TestPyUnitTestCase(TestCase):
-
- class PyUnitTest(pyunit.TestCase):
-
- def test_pass(self):
- pass
-
-
- def setUp(self):
- self.original = self.PyUnitTest('test_pass')
- self.test = ITestCase(self.original)
-
-
- def test_visit(self):
- """
- Trial assumes that test cases implement visit().
- """
- log = []
- def visitor(test):
- log.append(test)
- self.test.visit(visitor)
- self.assertEqual(log, [self.test])
- test_visit.suppress = [
- util.suppress(category=DeprecationWarning,
- message="Test visitors deprecated in Twisted 8.0")]
-
-
- def test_callable(self):
- """
- Tests must be callable in order to be used with Python's unittest.py.
- """
- self.assertTrue(callable(self.test),
- "%r is not callable." % (self.test,))
-
-
-class TestPyUnitResult(TestCase):
- """
- Tests to show that PyUnitResultAdapter wraps TestResult objects from the
- standard library 'unittest' module in such a way as to make them usable and
- useful from Trial.
- """
-
- def test_dontUseAdapterWhenReporterProvidesIReporter(self):
- """
- The L{PyUnitResultAdapter} is only used when the result passed to
- C{run} does *not* provide L{IReporter}.
- """
- class StubReporter(object):
- """
- A reporter which records data about calls made to it.
-
- @ivar errors: Errors passed to L{addError}.
- @ivar failures: Failures passed to L{addFailure}.
- """
-
- implements(IReporter)
-
- def __init__(self):
- self.errors = []
- self.failures = []
-
- def startTest(self, test):
- """
- Do nothing.
- """
-
- def stopTest(self, test):
- """
- Do nothing.
- """
-
- def addError(self, test, error):
- """
- Record the error.
- """
- self.errors.append(error)
-
- test = erroneous.ErrorTest("test_foo")
- result = StubReporter()
- test.run(result)
- self.assertIsInstance(result.errors[0], Failure)
-
-
- def test_success(self):
- class SuccessTest(TestCase):
- ran = False
- def test_foo(s):
- s.ran = True
- test = SuccessTest('test_foo')
- result = pyunit.TestResult()
- test.run(result)
-
- self.failUnless(test.ran)
- self.assertEqual(1, result.testsRun)
- self.failUnless(result.wasSuccessful())
-
- def test_failure(self):
- class FailureTest(TestCase):
- ran = False
- def test_foo(s):
- s.ran = True
- s.fail('boom!')
- test = FailureTest('test_foo')
- result = pyunit.TestResult()
- test.run(result)
-
- self.failUnless(test.ran)
- self.assertEqual(1, result.testsRun)
- self.assertEqual(1, len(result.failures))
- self.failIf(result.wasSuccessful())
-
- def test_error(self):
- test = erroneous.ErrorTest('test_foo')
- result = pyunit.TestResult()
- test.run(result)
-
- self.failUnless(test.ran)
- self.assertEqual(1, result.testsRun)
- self.assertEqual(1, len(result.errors))
- self.failIf(result.wasSuccessful())
-
- def test_setUpError(self):
- class ErrorTest(TestCase):
- ran = False
- def setUp(self):
- 1/0
- def test_foo(s):
- s.ran = True
- test = ErrorTest('test_foo')
- result = pyunit.TestResult()
- test.run(result)
-
- self.failIf(test.ran)
- self.assertEqual(1, result.testsRun)
- self.assertEqual(1, len(result.errors))
- self.failIf(result.wasSuccessful())
-
- def test_tracebackFromFailure(self):
- """
- Errors added through the L{PyUnitResultAdapter} have the same traceback
- information as if there were no adapter at all.
- """
- try:
- 1/0
- except ZeroDivisionError:
- exc_info = sys.exc_info()
- f = Failure()
- pyresult = pyunit.TestResult()
- result = PyUnitResultAdapter(pyresult)
- result.addError(self, f)
- self.assertEqual(pyresult.errors[0][1],
- ''.join(traceback.format_exception(*exc_info)))
-
-
- def test_traceback(self):
- """
- As test_tracebackFromFailure, but covering more code.
- """
- class ErrorTest(TestCase):
- exc_info = None
- def test_foo(self):
- try:
- 1/0
- except ZeroDivisionError:
- self.exc_info = sys.exc_info()
- raise
- test = ErrorTest('test_foo')
- result = pyunit.TestResult()
- test.run(result)
-
- # We can't test that the tracebacks are equal, because Trial's
- # machinery inserts a few extra frames on the top and we don't really
- # want to trim them off without an extremely good reason.
- #
- # So, we just test that the result's stack ends with the the
- # exception's stack.
-
- expected_stack = ''.join(traceback.format_tb(test.exc_info[2]))
- observed_stack = '\n'.join(result.errors[0][1].splitlines()[:-1])
-
- self.assertEqual(expected_stack.strip(),
- observed_stack[-len(expected_stack):].strip())
-
-
- def test_tracebackFromCleanFailure(self):
- """
- Errors added through the L{PyUnitResultAdapter} have the same
- traceback information as if there were no adapter at all, even
- if the Failure that held the information has been cleaned.
- """
- try:
- 1/0
- except ZeroDivisionError:
- exc_info = sys.exc_info()
- f = Failure()
- f.cleanFailure()
- pyresult = pyunit.TestResult()
- result = PyUnitResultAdapter(pyresult)
- result.addError(self, f)
- self.assertEqual(pyresult.errors[0][1],
- ''.join(traceback.format_exception(*exc_info)))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_reporter.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_reporter.py
deleted file mode 100755
index e5bf848b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_reporter.py
+++ /dev/null
@@ -1,1650 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-# Maintainer: Jonathan Lange
-
-"""
-Tests for L{twisted.trial.reporter}.
-"""
-from __future__ import division
-
-import errno, sys, os, re, StringIO
-from inspect import getmro
-
-from twisted.internet.utils import suppressWarnings
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.trial import itrial, unittest, runner, reporter, util
-from twisted.trial.reporter import UncleanWarningsReporterWrapper
-from twisted.trial.test import erroneous
-from twisted.trial.unittest import makeTodo, SkipTest, Todo
-from twisted.trial.test import sample
-
-
-class BrokenStream(object):
- """
- Stream-ish object that raises a signal interrupt error. We use this to make
- sure that Trial still manages to write what it needs to write.
- """
- written = False
- flushed = False
-
- def __init__(self, fObj):
- self.fObj = fObj
-
- def write(self, s):
- if self.written:
- return self.fObj.write(s)
- self.written = True
- raise IOError(errno.EINTR, "Interrupted write")
-
- def flush(self):
- if self.flushed:
- return self.fObj.flush()
- self.flushed = True
- raise IOError(errno.EINTR, "Interrupted flush")
-
-
-class StringTest(unittest.TestCase):
- def stringComparison(self, expect, output):
- output = filter(None, output)
- self.failUnless(len(expect) <= len(output),
- "Must have more observed than expected"
- "lines %d < %d" % (len(output), len(expect)))
- REGEX_PATTERN_TYPE = type(re.compile(''))
- for line_number, (exp, out) in enumerate(zip(expect, output)):
- if exp is None:
- continue
- elif isinstance(exp, str):
- self.assertSubstring(exp, out, "Line %d: %r not in %r"
- % (line_number, exp, out))
- elif isinstance(exp, REGEX_PATTERN_TYPE):
- self.failUnless(exp.match(out),
- "Line %d: %r did not match string %r"
- % (line_number, exp.pattern, out))
- else:
- raise TypeError("don't know what to do with object %r"
- % (exp,))
-
-
-class TestTestResult(unittest.TestCase):
- def setUp(self):
- self.result = reporter.TestResult()
-
- def test_pyunitAddError(self):
- # pyunit passes an exc_info tuple directly to addError
- try:
- raise RuntimeError('foo')
- except RuntimeError, excValue:
- self.result.addError(self, sys.exc_info())
- failure = self.result.errors[0][1]
- self.assertEqual(excValue, failure.value)
- self.assertEqual(RuntimeError, failure.type)
-
- def test_pyunitAddFailure(self):
- # pyunit passes an exc_info tuple directly to addFailure
- try:
- raise self.failureException('foo')
- except self.failureException, excValue:
- self.result.addFailure(self, sys.exc_info())
- failure = self.result.failures[0][1]
- self.assertEqual(excValue, failure.value)
- self.assertEqual(self.failureException, failure.type)
-
-
-class TestReporterRealtime(TestTestResult):
- def setUp(self):
- output = StringIO.StringIO()
- self.result = reporter.Reporter(output, realtime=True)
-
-
-class TestErrorReporting(StringTest):
- doubleSeparator = re.compile(r'^=+$')
-
- def setUp(self):
- self.loader = runner.TestLoader()
- self.output = StringIO.StringIO()
- self.result = reporter.Reporter(self.output)
-
- def getOutput(self, suite):
- result = self.getResult(suite)
- result.done()
- return self.output.getvalue()
-
- def getResult(self, suite):
- suite.run(self.result)
- return self.result
-
- def test_formatErroredMethod(self):
- """
- A test method which runs and has an error recorded against it is
- reported in the output stream with the I{ERROR} tag along with a summary
- of what error was reported and the ID of the test.
- """
- cls = erroneous.SynchronousTestFailureInSetUp
- suite = self.loader.loadClass(cls)
- output = self.getOutput(suite).splitlines()
- match = [
- self.doubleSeparator,
- '[ERROR]',
- 'Traceback (most recent call last):',
- re.compile(r'^\s+File .*erroneous\.py., line \d+, in setUp$'),
- re.compile(r'^\s+raise FoolishError, '
- r'.I am a broken setUp method.$'),
- ('twisted.trial.test.erroneous.FoolishError: '
- 'I am a broken setUp method'),
- '%s.%s.test_noop' % (cls.__module__, cls.__name__)]
- self.stringComparison(match, output)
-
-
- def test_formatFailedMethod(self):
- """
- A test method which runs and has a failure recorded against it is
- reported in the output stream with the I{FAIL} tag along with a summary
- of what failure was reported and the ID of the test.
- """
- suite = self.loader.loadMethod(erroneous.TestRegularFail.test_fail)
- output = self.getOutput(suite).splitlines()
- match = [
- self.doubleSeparator,
- '[FAIL]',
- 'Traceback (most recent call last):',
- re.compile(r'^\s+File .*erroneous\.py., line \d+, in test_fail$'),
- re.compile(r'^\s+self\.fail\("I fail"\)$'),
- 'twisted.trial.unittest.FailTest: I fail',
- 'twisted.trial.test.erroneous.TestRegularFail.test_fail',
- ]
- self.stringComparison(match, output)
-
-
- def test_doctestError(self):
- """
- A problem encountered while running a doctest is reported in the output
- stream with a I{FAIL} or I{ERROR} tag along with a summary of what
- problem was encountered and the ID of the test.
- """
- from twisted.trial.test import erroneous
- suite = unittest.decorate(
- self.loader.loadDoctests(erroneous), itrial.ITestCase)
- output = self.getOutput(suite)
- path = 'twisted.trial.test.erroneous.unexpectedException'
- for substring in ['1/0', 'ZeroDivisionError',
- 'Exception raised:', path]:
- self.assertSubstring(substring, output)
- self.failUnless(re.search('Fail(ed|ure in) example:', output),
- "Couldn't match 'Failure in example: ' "
- "or 'Failed example: '")
- expect = [self.doubleSeparator,
- re.compile(r'\[(ERROR|FAIL)\]')]
- self.stringComparison(expect, output.splitlines())
-
-
- def test_hiddenException(self):
- """
- Check that errors in C{DelayedCall}s get reported, even if the
- test already has a failure.
-
- Only really necessary for testing the deprecated style of tests that
- use iterate() directly. See
- L{erroneous.DelayedCall.testHiddenException} for more details.
- """
- test = erroneous.DelayedCall('testHiddenException')
- output = self.getOutput(test).splitlines()
- match = [
- self.doubleSeparator,
- '[FAIL]',
- 'Traceback (most recent call last):',
- re.compile(r'^\s+File .*erroneous\.py., line \d+, in '
- 'testHiddenException$'),
- re.compile(r'^\s+self\.fail\("Deliberate failure to mask the '
- 'hidden exception"\)$'),
- 'twisted.trial.unittest.FailTest: '
- 'Deliberate failure to mask the hidden exception',
- 'twisted.trial.test.erroneous.DelayedCall.testHiddenException',
- self.doubleSeparator,
- '[ERROR]',
- 'Traceback (most recent call last):',
- re.compile(r'^\s+File .* in runUntilCurrent'),
- re.compile(r'^\s+.*'),
- re.compile('^\s+File .*erroneous\.py", line \d+, in go'),
- re.compile('^\s+raise RuntimeError\(self.hiddenExceptionMsg\)'),
- 'exceptions.RuntimeError: something blew up',
- 'twisted.trial.test.erroneous.DelayedCall.testHiddenException',
- ]
- self.stringComparison(match, output)
-
-
-
-class TestUncleanWarningWrapperErrorReporting(TestErrorReporting):
- """
- Tests that the L{UncleanWarningsReporterWrapper} can sufficiently proxy
- IReporter failure and error reporting methods to a L{reporter.Reporter}.
- """
- def setUp(self):
- self.loader = runner.TestLoader()
- self.output = StringIO.StringIO()
- self.result = UncleanWarningsReporterWrapper(
- reporter.Reporter(self.output))
-
-
-
-class TracebackHandling(unittest.TestCase):
- def getErrorFrames(self, test):
- stream = StringIO.StringIO()
- result = reporter.Reporter(stream)
- test.run(result)
- bads = result.failures + result.errors
- assert len(bads) == 1
- assert bads[0][0] == test
- return result._trimFrames(bads[0][1].frames)
-
- def checkFrames(self, observedFrames, expectedFrames):
- for observed, expected in zip(observedFrames, expectedFrames):
- self.assertEqual(observed[0], expected[0])
- observedSegs = os.path.splitext(observed[1])[0].split(os.sep)
- expectedSegs = expected[1].split('/')
- self.assertEqual(observedSegs[-len(expectedSegs):],
- expectedSegs)
- self.assertEqual(len(observedFrames), len(expectedFrames))
-
- def test_basic(self):
- test = erroneous.TestRegularFail('test_fail')
- frames = self.getErrorFrames(test)
- self.checkFrames(frames,
- [('test_fail', 'twisted/trial/test/erroneous')])
-
- def test_subroutine(self):
- test = erroneous.TestRegularFail('test_subfail')
- frames = self.getErrorFrames(test)
- self.checkFrames(frames,
- [('test_subfail', 'twisted/trial/test/erroneous'),
- ('subroutine', 'twisted/trial/test/erroneous')])
-
- def test_deferred(self):
- test = erroneous.TestFailureInDeferredChain('test_fail')
- frames = self.getErrorFrames(test)
- self.checkFrames(frames,
- [('_later', 'twisted/trial/test/erroneous')])
-
- def test_noFrames(self):
- result = reporter.Reporter(None)
- self.assertEqual([], result._trimFrames([]))
-
- def test_oneFrame(self):
- result = reporter.Reporter(None)
- self.assertEqual(['fake frame'], result._trimFrames(['fake frame']))
-
-
-class FormatFailures(StringTest):
- def setUp(self):
- try:
- raise RuntimeError('foo')
- except RuntimeError:
- self.f = Failure()
- self.f.frames = [
- ['foo', 'foo/bar.py', 5, [('x', 5)], [('y', 'orange')]],
- ['qux', 'foo/bar.py', 10, [('a', 'two')], [('b', 'MCMXCIX')]]
- ]
- self.stream = StringIO.StringIO()
- self.result = reporter.Reporter(self.stream)
-
- def test_formatDefault(self):
- tb = self.result._formatFailureTraceback(self.f)
- self.stringComparison([
- 'Traceback (most recent call last):',
- ' File "foo/bar.py", line 5, in foo',
- re.compile(r'^\s*$'),
- ' File "foo/bar.py", line 10, in qux',
- re.compile(r'^\s*$'),
- 'RuntimeError: foo'], tb.splitlines())
-
- def test_formatString(self):
- tb = '''
- File "twisted/trial/unittest.py", line 256, in failUnlessSubstring
- return self.failUnlessIn(substring, astring, msg)
-exceptions.TypeError: iterable argument required
-
-'''
- expected = '''
- File "twisted/trial/unittest.py", line 256, in failUnlessSubstring
- return self.failUnlessIn(substring, astring, msg)
-exceptions.TypeError: iterable argument required
-'''
- formatted = self.result._formatFailureTraceback(tb)
- self.assertEqual(expected, formatted)
-
- def test_mutation(self):
- frames = self.f.frames[:]
- # The call shouldn't mutate the frames.
- self.result._formatFailureTraceback(self.f)
- self.assertEqual(self.f.frames, frames)
-
-
-class PyunitTestNames(unittest.TestCase):
- def setUp(self):
- self.stream = StringIO.StringIO()
- self.test = sample.PyunitTest('test_foo')
-
- def test_verboseReporter(self):
- result = reporter.VerboseTextReporter(self.stream)
- result.startTest(self.test)
- output = self.stream.getvalue()
- self.assertEqual(
- output, 'twisted.trial.test.sample.PyunitTest.test_foo ... ')
-
- def test_treeReporter(self):
- result = reporter.TreeReporter(self.stream)
- result.startTest(self.test)
- output = self.stream.getvalue()
- output = output.splitlines()[-1].strip()
- self.assertEqual(output, result.getDescription(self.test) + ' ...')
-
- def test_getDescription(self):
- result = reporter.TreeReporter(self.stream)
- output = result.getDescription(self.test)
- self.assertEqual(output, 'test_foo')
-
-
- def test_minimalReporter(self):
- """
- The summary of L{reporter.MinimalReporter} is a simple list of numbers,
- indicating how many tests ran, how many failed etc.
-
- The numbers represents:
- * the run time of the tests
- * the number of tests run, printed 2 times for legacy reasons
- * the number of errors
- * the number of failures
- * the number of skips
- """
- result = reporter.MinimalReporter(self.stream)
- self.test.run(result)
- result._printSummary()
- output = self.stream.getvalue().strip().split(' ')
- self.assertEqual(output[1:], ['1', '1', '0', '0', '0'])
-
-
- def test_minimalReporterTime(self):
- """
- L{reporter.MinimalReporter} reports the time to run the tests as first
- data in its output.
- """
- times = [1.0, 1.2, 1.5, 1.9]
- result = reporter.MinimalReporter(self.stream)
- result._getTime = lambda: times.pop(0)
- self.test.run(result)
- result._printSummary()
- output = self.stream.getvalue().strip().split(' ')
- timer = output[0]
- self.assertEqual(timer, "0.7")
-
-
- def test_emptyMinimalReporter(self):
- """
- The summary of L{reporter.MinimalReporter} is a list of zeroes when no
- test is actually run.
- """
- result = reporter.MinimalReporter(self.stream)
- result._printSummary()
- output = self.stream.getvalue().strip().split(' ')
- self.assertEqual(output, ['0', '0', '0', '0', '0', '0'])
-
-
-
-class TestDirtyReactor(unittest.TestCase):
- """
- The trial script has an option to treat L{DirtyReactorAggregateError}s as
- warnings, as a migration tool for test authors. It causes a wrapper to be
- placed around reporters that replaces L{DirtyReactorAggregatErrors} with
- warnings.
- """
-
- def setUp(self):
- self.dirtyError = Failure(
- util.DirtyReactorAggregateError(['foo'], ['bar']))
- self.output = StringIO.StringIO()
- self.test = TestDirtyReactor('test_errorByDefault')
-
-
- def test_errorByDefault(self):
- """
- L{DirtyReactorAggregateError}s are reported as errors with the default
- Reporter.
- """
- result = reporter.Reporter(stream=self.output)
- result.addError(self.test, self.dirtyError)
- self.assertEqual(len(result.errors), 1)
- self.assertEqual(result.errors[0][1], self.dirtyError)
-
-
- def test_warningsEnabled(self):
- """
- L{DirtyReactorAggregateError}s are reported as warnings when using
- the L{UncleanWarningsReporterWrapper}.
- """
- result = UncleanWarningsReporterWrapper(
- reporter.Reporter(stream=self.output))
- self.assertWarns(UserWarning, self.dirtyError.getErrorMessage(),
- reporter.__file__,
- result.addError, self.test, self.dirtyError)
-
-
- def test_warningsMaskErrors(self):
- """
- L{DirtyReactorAggregateError}s are I{not} reported as errors if the
- L{UncleanWarningsReporterWrapper} is used.
- """
- result = UncleanWarningsReporterWrapper(
- reporter.Reporter(stream=self.output))
- self.assertWarns(UserWarning, self.dirtyError.getErrorMessage(),
- reporter.__file__,
- result.addError, self.test, self.dirtyError)
- self.assertEqual(result._originalReporter.errors, [])
-
-
- def test_dealsWithThreeTuples(self):
- """
- Some annoying stuff can pass three-tuples to addError instead of
- Failures (like PyUnit). The wrapper, of course, handles this case,
- since it is a part of L{twisted.trial.itrial.IReporter}! But it does
- not convert L{DirtyReactorAggregateError} to warnings in this case,
- because nobody should be passing those in the form of three-tuples.
- """
- result = UncleanWarningsReporterWrapper(
- reporter.Reporter(stream=self.output))
- result.addError(self.test,
- (self.dirtyError.type, self.dirtyError.value, None))
- self.assertEqual(len(result._originalReporter.errors), 1)
- self.assertEqual(result._originalReporter.errors[0][1].type,
- self.dirtyError.type)
- self.assertEqual(result._originalReporter.errors[0][1].value,
- self.dirtyError.value)
-
-
-
-class TrialTestNames(unittest.TestCase):
-
- def setUp(self):
- self.stream = StringIO.StringIO()
- self.test = sample.FooTest('test_foo')
-
- def test_verboseReporter(self):
- result = reporter.VerboseTextReporter(self.stream)
- result.startTest(self.test)
- output = self.stream.getvalue()
- self.assertEqual(output, self.test.id() + ' ... ')
-
- def test_treeReporter(self):
- result = reporter.TreeReporter(self.stream)
- result.startTest(self.test)
- output = self.stream.getvalue()
- output = output.splitlines()[-1].strip()
- self.assertEqual(output, result.getDescription(self.test) + ' ...')
-
- def test_treeReporterWithDocstrings(self):
- """A docstring"""
- result = reporter.TreeReporter(self.stream)
- self.assertEqual(result.getDescription(self),
- 'test_treeReporterWithDocstrings')
-
- def test_getDescription(self):
- result = reporter.TreeReporter(self.stream)
- output = result.getDescription(self.test)
- self.assertEqual(output, "test_foo")
-
-
-class TestSkip(unittest.TestCase):
- """
- Tests for L{reporter.Reporter}'s handling of skips.
- """
- def setUp(self):
- self.stream = StringIO.StringIO()
- self.result = reporter.Reporter(self.stream)
- self.test = sample.FooTest('test_foo')
-
- def _getSkips(self, result):
- """
- Get the number of skips that happened to a reporter.
- """
- return len(result.skips)
-
- def test_accumulation(self):
- self.result.addSkip(self.test, 'some reason')
- self.assertEqual(self._getSkips(self.result), 1)
-
- def test_success(self):
- self.result.addSkip(self.test, 'some reason')
- self.assertEqual(True, self.result.wasSuccessful())
-
-
- def test_summary(self):
- """
- The summary of a successful run with skips indicates that the test
- suite passed and includes the number of skips.
- """
- self.result.addSkip(self.test, 'some reason')
- self.result.done()
- output = self.stream.getvalue().splitlines()[-1]
- prefix = 'PASSED '
- self.failUnless(output.startswith(prefix))
- self.assertEqual(output[len(prefix):].strip(), '(skips=1)')
-
-
- def test_basicErrors(self):
- """
- The output at the end of a test run with skips includes the reasons
- for skipping those tests.
- """
- self.result.addSkip(self.test, 'some reason')
- self.result.done()
- output = self.stream.getvalue().splitlines()[3]
- self.assertEqual(output.strip(), 'some reason')
-
-
- def test_booleanSkip(self):
- """
- Tests can be skipped without specifying a reason by setting the 'skip'
- attribute to True. When this happens, the test output includes 'True'
- as the reason.
- """
- self.result.addSkip(self.test, True)
- self.result.done()
- output = self.stream.getvalue().splitlines()[3]
- self.assertEqual(output, 'True')
-
-
- def test_exceptionSkip(self):
- """
- Skips can be raised as errors. When this happens, the error is
- included in the summary at the end of the test suite.
- """
- try:
- 1/0
- except Exception, e:
- error = e
- self.result.addSkip(self.test, error)
- self.result.done()
- output = '\n'.join(self.stream.getvalue().splitlines()[3:5]).strip()
- self.assertEqual(output, str(e))
-
-
-class UncleanWarningSkipTest(TestSkip):
- """
- Tests for skips on a L{reporter.Reporter} wrapped by an
- L{UncleanWarningsReporterWrapper}.
- """
- def setUp(self):
- TestSkip.setUp(self)
- self.result = UncleanWarningsReporterWrapper(self.result)
-
- def _getSkips(self, result):
- """
- Get the number of skips that happened to a reporter inside of an
- unclean warnings reporter wrapper.
- """
- return len(result._originalReporter.skips)
-
-
-
-class TodoTest(unittest.TestCase):
- """
- Tests for L{reporter.Reporter}'s handling of todos.
- """
-
- def setUp(self):
- self.stream = StringIO.StringIO()
- self.result = reporter.Reporter(self.stream)
- self.test = sample.FooTest('test_foo')
-
-
- def _getTodos(self, result):
- """
- Get the number of todos that happened to a reporter.
- """
- return len(result.expectedFailures)
-
-
- def _getUnexpectedSuccesses(self, result):
- """
- Get the number of unexpected successes that happened to a reporter.
- """
- return len(result.unexpectedSuccesses)
-
-
- def test_accumulation(self):
- """
- L{reporter.Reporter} accumulates the expected failures that it
- is notified of.
- """
- self.result.addExpectedFailure(self.test, Failure(Exception()),
- makeTodo('todo!'))
- self.assertEqual(self._getTodos(self.result), 1)
-
-
- def test_success(self):
- """
- A test run is still successful even if there are expected failures.
- """
- self.result.addExpectedFailure(self.test, Failure(Exception()),
- makeTodo('todo!'))
- self.assertEqual(True, self.result.wasSuccessful())
-
-
- def test_unexpectedSuccess(self):
- """
- A test which is marked as todo but succeeds will have an unexpected
- success reported to its result. A test run is still successful even
- when this happens.
- """
- self.result.addUnexpectedSuccess(self.test, makeTodo("Heya!"))
- self.assertEqual(True, self.result.wasSuccessful())
- self.assertEqual(self._getUnexpectedSuccesses(self.result), 1)
-
-
- def test_summary(self):
- """
- The reporter's C{printSummary} method should print the number of
- expected failures that occured.
- """
- self.result.addExpectedFailure(self.test, Failure(Exception()),
- makeTodo('some reason'))
- self.result.done()
- output = self.stream.getvalue().splitlines()[-1]
- prefix = 'PASSED '
- self.failUnless(output.startswith(prefix))
- self.assertEqual(output[len(prefix):].strip(),
- '(expectedFailures=1)')
-
-
- def test_basicErrors(self):
- """
- The reporter's L{printErrors} method should include the value of the
- Todo.
- """
- self.result.addExpectedFailure(self.test, Failure(Exception()),
- makeTodo('some reason'))
- self.result.done()
- output = self.stream.getvalue().splitlines()[3].strip()
- self.assertEqual(output, "Reason: 'some reason'")
-
-
- def test_booleanTodo(self):
- """
- Booleans CAN'T be used as the value of a todo. Maybe this sucks. This
- is a test for current behavior, not a requirement.
- """
- self.result.addExpectedFailure(self.test, Failure(Exception()),
- makeTodo(True))
- self.assertRaises(Exception, self.result.done)
-
-
- def test_exceptionTodo(self):
- """
- The exception for expected failures should be shown in the
- C{printErrors} output.
- """
- try:
- 1/0
- except Exception, e:
- error = e
- self.result.addExpectedFailure(self.test, Failure(error),
- makeTodo("todo!"))
- self.result.done()
- output = '\n'.join(self.stream.getvalue().splitlines()[3:]).strip()
- self.assertTrue(str(e) in output)
-
-
-
-class UncleanWarningTodoTest(TodoTest):
- """
- Tests for L{UncleanWarningsReporterWrapper}'s handling of todos.
- """
-
- def setUp(self):
- TodoTest.setUp(self)
- self.result = UncleanWarningsReporterWrapper(self.result)
-
-
- def _getTodos(self, result):
- """
- Get the number of todos that happened to a reporter inside of an
- unclean warnings reporter wrapper.
- """
- return len(result._originalReporter.expectedFailures)
-
-
- def _getUnexpectedSuccesses(self, result):
- """
- Get the number of unexpected successes that happened to a reporter
- inside of an unclean warnings reporter wrapper.
- """
- return len(result._originalReporter.unexpectedSuccesses)
-
-
-
-class MockColorizer:
- """
- Used by TestTreeReporter to make sure that output is colored correctly.
- """
-
- def __init__(self, stream):
- self.log = []
-
-
- def write(self, text, color):
- self.log.append((color, text))
-
-
-
-class TestTreeReporter(unittest.TestCase):
- def setUp(self):
- self.test = sample.FooTest('test_foo')
- self.stream = StringIO.StringIO()
- self.result = reporter.TreeReporter(self.stream)
- self.result._colorizer = MockColorizer(self.stream)
- self.log = self.result._colorizer.log
-
- def makeError(self):
- try:
- 1/0
- except ZeroDivisionError:
- f = Failure()
- return f
-
- def test_cleanupError(self):
- """
- Run cleanupErrors and check that the output is correct, and colored
- correctly.
- """
- f = self.makeError()
- self.result.cleanupErrors(f)
- color, text = self.log[0]
- self.assertEqual(color.strip(), self.result.ERROR)
- self.assertEqual(text.strip(), 'cleanup errors')
- color, text = self.log[1]
- self.assertEqual(color.strip(), self.result.ERROR)
- self.assertEqual(text.strip(), '[ERROR]')
- test_cleanupError = suppressWarnings(
- test_cleanupError,
- util.suppress(category=reporter.BrokenTestCaseWarning),
- util.suppress(category=DeprecationWarning))
-
-
- def test_upDownError(self):
- """
- Run upDownError and check that the output is correct and colored
- correctly.
- """
- self.result.upDownError("method", None, None, False)
- color, text = self.log[0]
- self.assertEqual(color.strip(), self.result.ERROR)
- self.assertEqual(text.strip(), 'method')
- test_upDownError = suppressWarnings(
- test_upDownError,
- util.suppress(category=DeprecationWarning,
- message="upDownError is deprecated in Twisted 8.0."))
-
-
- def test_summaryColoredSuccess(self):
- """
- The summary in case of success should have a good count of successes
- and be colored properly.
- """
- self.result.addSuccess(self.test)
- self.result.done()
- self.assertEqual(self.log[1], (self.result.SUCCESS, 'PASSED'))
- self.assertEqual(
- self.stream.getvalue().splitlines()[-1].strip(), "(successes=1)")
-
-
- def test_summaryColoredFailure(self):
- """
- The summary in case of failure should have a good count of errors
- and be colored properly.
- """
- try:
- raise RuntimeError('foo')
- except RuntimeError:
- self.result.addError(self, sys.exc_info())
- self.result.done()
- self.assertEqual(self.log[1], (self.result.FAILURE, 'FAILED'))
- self.assertEqual(
- self.stream.getvalue().splitlines()[-1].strip(), "(errors=1)")
-
-
- def test_getPrelude(self):
- """
- The tree needs to get the segments of the test ID that correspond
- to the module and class that it belongs to.
- """
- self.assertEqual(
- ['foo.bar', 'baz'],
- self.result._getPreludeSegments('foo.bar.baz.qux'))
- self.assertEqual(
- ['foo', 'bar'],
- self.result._getPreludeSegments('foo.bar.baz'))
- self.assertEqual(
- ['foo'],
- self.result._getPreludeSegments('foo.bar'))
- self.assertEqual([], self.result._getPreludeSegments('foo'))
-
-
- def test_groupResults(self):
- """
- If two different tests have the same error, L{Reporter._groupResults}
- includes them together in one of the tuples in the list it returns.
- """
- try:
- raise RuntimeError('foo')
- except RuntimeError:
- self.result.addError(self, sys.exc_info())
- self.result.addError(self.test, sys.exc_info())
- try:
- raise RuntimeError('bar')
- except RuntimeError:
- extra = sample.FooTest('test_bar')
- self.result.addError(extra, sys.exc_info())
- self.result.done()
- grouped = self.result._groupResults(
- self.result.errors, self.result._formatFailureTraceback)
- self.assertEqual(grouped[0][1], [self, self.test])
- self.assertEqual(grouped[1][1], [extra])
-
-
- def test_printResults(self):
- """
- L{Reporter._printResults} uses the results list and formatter callable
- passed to it to produce groups of results to write to its output stream.
- """
- def formatter(n):
- return str(n) + '\n'
- first = sample.FooTest('test_foo')
- second = sample.FooTest('test_bar')
- third = sample.PyunitTest('test_foo')
- self.result._printResults(
- 'FOO', [(first, 1), (second, 1), (third, 2)], formatter)
- self.assertEqual(
- self.stream.getvalue(),
- "%(double separator)s\n"
- "FOO\n"
- "1\n"
- "\n"
- "%(first)s\n"
- "%(second)s\n"
- "%(double separator)s\n"
- "FOO\n"
- "2\n"
- "\n"
- "%(third)s\n" % {
- 'double separator': self.result._doubleSeparator,
- 'first': first.id(),
- 'second': second.id(),
- 'third': third.id(),
- })
-
-
-
-class TestReporterInterface(unittest.TestCase):
- """
- Tests for the bare interface of a trial reporter.
-
- Subclass this test case and provide a different 'resultFactory' to test
- that a particular reporter implementation will work with the rest of
- Trial.
-
- @cvar resultFactory: A callable that returns a reporter to be tested. The
- callable must take the same parameters as L{reporter.Reporter}.
- """
-
- resultFactory = reporter.Reporter
-
- def setUp(self):
- self.test = sample.FooTest('test_foo')
- self.stream = StringIO.StringIO()
- self.publisher = log.LogPublisher()
- self.result = self.resultFactory(self.stream, publisher=self.publisher)
-
-
- def test_shouldStopInitiallyFalse(self):
- """
- shouldStop is False to begin with.
- """
- self.assertEqual(False, self.result.shouldStop)
-
-
- def test_shouldStopTrueAfterStop(self):
- """
- shouldStop becomes True soon as someone calls stop().
- """
- self.result.stop()
- self.assertEqual(True, self.result.shouldStop)
-
-
- def test_wasSuccessfulInitiallyTrue(self):
- """
- wasSuccessful() is True when there have been no results reported.
- """
- self.assertEqual(True, self.result.wasSuccessful())
-
-
- def test_wasSuccessfulTrueAfterSuccesses(self):
- """
- wasSuccessful() is True when there have been only successes, False
- otherwise.
- """
- self.result.addSuccess(self.test)
- self.assertEqual(True, self.result.wasSuccessful())
-
-
- def test_wasSuccessfulFalseAfterErrors(self):
- """
- wasSuccessful() becomes False after errors have been reported.
- """
- try:
- 1 / 0
- except ZeroDivisionError:
- self.result.addError(self.test, sys.exc_info())
- self.assertEqual(False, self.result.wasSuccessful())
-
-
- def test_wasSuccessfulFalseAfterFailures(self):
- """
- wasSuccessful() becomes False after failures have been reported.
- """
- try:
- self.fail("foo")
- except self.failureException:
- self.result.addFailure(self.test, sys.exc_info())
- self.assertEqual(False, self.result.wasSuccessful())
-
-
-
-class TestReporter(TestReporterInterface):
- """
- Tests for the base L{reporter.Reporter} class.
- """
-
- def setUp(self):
- TestReporterInterface.setUp(self)
- self._timer = 0
- self.result._getTime = self._getTime
-
-
- def _getTime(self):
- self._timer += 1
- return self._timer
-
-
- def test_startStop(self):
- self.result.startTest(self.test)
- self.result.stopTest(self.test)
- self.assertTrue(self.result._lastTime > 0)
- self.assertEqual(self.result.testsRun, 1)
- self.assertEqual(self.result.wasSuccessful(), True)
-
-
- def test_brokenStream(self):
- """
- Test that the reporter safely writes to its stream.
- """
- result = self.resultFactory(stream=BrokenStream(self.stream))
- result._writeln("Hello")
- self.assertEqual(self.stream.getvalue(), 'Hello\n')
- self.stream.truncate(0)
- result._writeln("Hello %s!", 'World')
- self.assertEqual(self.stream.getvalue(), 'Hello World!\n')
-
-
- def test_printErrorsDeprecated(self):
- """
- L{IReporter.printErrors} was deprecated in Twisted 8.0.
- """
- def f():
- self.result.printErrors()
- self.assertWarns(
- DeprecationWarning, "printErrors is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_printSummaryDeprecated(self):
- """
- L{IReporter.printSummary} was deprecated in Twisted 8.0.
- """
- def f():
- self.result.printSummary()
- self.assertWarns(
- DeprecationWarning, "printSummary is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_writeDeprecated(self):
- """
- L{IReporter.write} was deprecated in Twisted 8.0.
- """
- def f():
- self.result.write("")
- self.assertWarns(
- DeprecationWarning, "write is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_writelnDeprecated(self):
- """
- L{IReporter.writeln} was deprecated in Twisted 8.0.
- """
- def f():
- self.result.writeln("")
- self.assertWarns(
- DeprecationWarning, "writeln is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_separatorDeprecated(self):
- """
- L{IReporter.separator} was deprecated in Twisted 8.0.
- """
- def f():
- return self.result.separator
- self.assertWarns(
- DeprecationWarning, "separator is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_streamDeprecated(self):
- """
- L{IReporter.stream} was deprecated in Twisted 8.0.
- """
- def f():
- return self.result.stream
- self.assertWarns(
- DeprecationWarning, "stream is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_upDownErrorDeprecated(self):
- """
- L{IReporter.upDownError} was deprecated in Twisted 8.0.
- """
- def f():
- self.result.upDownError(None, None, None, None)
- self.assertWarns(
- DeprecationWarning, "upDownError is deprecated in Twisted 8.0.",
- __file__, f)
-
-
- def test_warning(self):
- """
- L{reporter.Reporter} observes warnings emitted by the Twisted log
- system and writes them to its output stream.
- """
- message = RuntimeWarning("some warning text")
- category = 'exceptions.RuntimeWarning'
- filename = "path/to/some/file.py"
- lineno = 71
- self.publisher.msg(
- warning=message, category=category,
- filename=filename, lineno=lineno)
- self.assertEqual(
- self.stream.getvalue(),
- "%s:%d: %s: %s\n" % (
- filename, lineno, category.split('.')[-1], message))
-
-
- def test_duplicateWarningSuppressed(self):
- """
- A warning emitted twice within a single test is only written to the
- stream once.
- """
- # Emit the warning and assert that it shows up
- self.test_warning()
- # Emit the warning again and assert that the stream still only has one
- # warning on it.
- self.test_warning()
-
-
- def test_warningEmittedForNewTest(self):
- """
- A warning emitted again after a new test has started is written to the
- stream again.
- """
- test = self.__class__('test_warningEmittedForNewTest')
- self.result.startTest(test)
-
- # Clear whatever startTest wrote to the stream
- self.stream.seek(0)
- self.stream.truncate()
-
- # Emit a warning (and incidentally, assert that it was emitted)
- self.test_warning()
-
- # Clean up from the first warning to simplify the rest of the
- # assertions.
- self.stream.seek(0)
- self.stream.truncate()
-
- # Stop the first test and start another one (it just happens to be the
- # same one, but that doesn't matter)
- self.result.stopTest(test)
- self.result.startTest(test)
-
- # Clean up the stopTest/startTest output
- self.stream.seek(0)
- self.stream.truncate()
-
- # Emit the warning again and make sure it shows up
- self.test_warning()
-
-
- def test_stopObserving(self):
- """
- L{reporter.Reporter} stops observing log events when its C{done} method
- is called.
- """
- self.result.done()
- self.stream.seek(0)
- self.stream.truncate()
- self.publisher.msg(
- warning=RuntimeWarning("some message"),
- category='exceptions.RuntimeWarning',
- filename="file/name.py", lineno=17)
- self.assertEqual(self.stream.getvalue(), "")
-
-
-
-class TestSafeStream(unittest.TestCase):
- def test_safe(self):
- """
- Test that L{reporter.SafeStream} successfully write to its original
- stream even if an interrupt happens during the write.
- """
- stream = StringIO.StringIO()
- broken = BrokenStream(stream)
- safe = reporter.SafeStream(broken)
- safe.write("Hello")
- self.assertEqual(stream.getvalue(), "Hello")
-
-
-
-class TestSubunitReporter(TestReporterInterface):
- """
- Tests for the subunit reporter.
-
- This just tests that the subunit reporter implements the basic interface.
- """
-
- resultFactory = reporter.SubunitReporter
-
-
- def setUp(self):
- if reporter.TestProtocolClient is None:
- raise SkipTest(
- "Subunit not installed, cannot test SubunitReporter")
- TestReporterInterface.setUp(self)
-
-
- def assertForwardsToSubunit(self, methodName, *args, **kwargs):
- """
- Assert that 'methodName' on L{SubunitReporter} forwards to the
- equivalent method on subunit.
-
- Checks that the return value from subunit is returned from the
- L{SubunitReporter} and that the reporter writes the same data to its
- stream as subunit does to its own.
-
- Assumes that the method on subunit has the same name as the method on
- L{SubunitReporter}.
- """
- stream = StringIO.StringIO()
- subunitClient = reporter.TestProtocolClient(stream)
- subunitReturn = getattr(subunitClient, methodName)(*args, **kwargs)
- subunitOutput = stream.getvalue()
- reporterReturn = getattr(self.result, methodName)(*args, **kwargs)
- self.assertEqual(subunitReturn, reporterReturn)
- self.assertEqual(subunitOutput, self.stream.getvalue())
-
-
- def removeMethod(self, klass, methodName):
- """
- Remove 'methodName' from 'klass'.
-
- If 'klass' does not have a method named 'methodName', then
- 'removeMethod' succeeds silently.
-
- If 'klass' does have a method named 'methodName', then it is removed
- using delattr. Also, methods of the same name are removed from all
- base classes of 'klass', thus removing the method entirely.
-
- @param klass: The class to remove the method from.
- @param methodName: The name of the method to remove.
- """
- method = getattr(klass, methodName, None)
- if method is None:
- return
- for base in getmro(klass):
- try:
- delattr(base, methodName)
- except (AttributeError, TypeError):
- break
- else:
- self.addCleanup(setattr, base, methodName, method)
-
-
- def test_subunitWithoutAddExpectedFailureInstalled(self):
- """
- Some versions of subunit don't have "addExpectedFailure". For these
- versions, we report expected failures as successes.
- """
- self.removeMethod(reporter.TestProtocolClient, 'addExpectedFailure')
- try:
- 1 / 0
- except ZeroDivisionError:
- self.result.addExpectedFailure(self.test, sys.exc_info(), "todo")
- expectedFailureOutput = self.stream.getvalue()
- self.stream.truncate(0)
- self.result.addSuccess(self.test)
- successOutput = self.stream.getvalue()
- self.assertEqual(successOutput, expectedFailureOutput)
-
-
- def test_subunitWithoutAddSkipInstalled(self):
- """
- Some versions of subunit don't have "addSkip". For these versions, we
- report skips as successes.
- """
- self.removeMethod(reporter.TestProtocolClient, 'addSkip')
- self.result.addSkip(self.test, "reason")
- skipOutput = self.stream.getvalue()
- self.stream.truncate(0)
- self.result.addSuccess(self.test)
- successOutput = self.stream.getvalue()
- self.assertEqual(successOutput, skipOutput)
-
-
- def test_addExpectedFailurePassedThrough(self):
- """
- Some versions of subunit have "addExpectedFailure". For these
- versions, when we call 'addExpectedFailure' on the test result, we
- pass the error and test through to the subunit client.
- """
- addExpectedFailureCalls = []
- def addExpectedFailure(test, error):
- addExpectedFailureCalls.append((test, error))
-
- # Provide our own addExpectedFailure, whether or not the locally
- # installed subunit has addExpectedFailure.
- self.result._subunit.addExpectedFailure = addExpectedFailure
- try:
- 1 / 0
- except ZeroDivisionError:
- exc_info = sys.exc_info()
- self.result.addExpectedFailure(self.test, exc_info, 'todo')
- self.assertEqual(addExpectedFailureCalls, [(self.test, exc_info)])
-
-
- def test_addSkipSendsSubunitAddSkip(self):
- """
- Some versions of subunit have "addSkip". For these versions, when we
- call 'addSkip' on the test result, we pass the test and reason through
- to the subunit client.
- """
- addSkipCalls = []
- def addSkip(test, reason):
- addSkipCalls.append((test, reason))
-
- # Provide our own addSkip, whether or not the locally-installed
- # subunit has addSkip.
- self.result._subunit.addSkip = addSkip
- self.result.addSkip(self.test, 'reason')
- self.assertEqual(addSkipCalls, [(self.test, 'reason')])
-
-
- def test_doneDoesNothing(self):
- """
- The subunit reporter doesn't need to print out a summary -- the stream
- of results is everything. Thus, done() does nothing.
- """
- self.result.done()
- self.assertEqual('', self.stream.getvalue())
-
-
- def test_startTestSendsSubunitStartTest(self):
- """
- SubunitReporter.startTest() sends the subunit 'startTest' message.
- """
- self.assertForwardsToSubunit('startTest', self.test)
-
-
- def test_stopTestSendsSubunitStopTest(self):
- """
- SubunitReporter.stopTest() sends the subunit 'stopTest' message.
- """
- self.assertForwardsToSubunit('stopTest', self.test)
-
-
- def test_addSuccessSendsSubunitAddSuccess(self):
- """
- SubunitReporter.addSuccess() sends the subunit 'addSuccess' message.
- """
- self.assertForwardsToSubunit('addSuccess', self.test)
-
-
- def test_addErrorSendsSubunitAddError(self):
- """
- SubunitReporter.addError() sends the subunit 'addError' message.
- """
- try:
- 1 / 0
- except ZeroDivisionError:
- error = sys.exc_info()
- self.assertForwardsToSubunit('addError', self.test, error)
-
-
- def test_addFailureSendsSubunitAddFailure(self):
- """
- SubunitReporter.addFailure() sends the subunit 'addFailure' message.
- """
- try:
- self.fail('hello')
- except self.failureException:
- failure = sys.exc_info()
- self.assertForwardsToSubunit('addFailure', self.test, failure)
-
-
- def test_addUnexpectedSuccessSendsSubunitAddSuccess(self):
- """
- SubunitReporter.addFailure() sends the subunit 'addSuccess' message,
- since subunit doesn't model unexpected success.
- """
- stream = StringIO.StringIO()
- subunitClient = reporter.TestProtocolClient(stream)
- subunitClient.addSuccess(self.test)
- subunitOutput = stream.getvalue()
- self.result.addUnexpectedSuccess(self.test, 'todo')
- self.assertEqual(subunitOutput, self.stream.getvalue())
-
-
- def test_loadTimeErrors(self):
- """
- Load-time errors are reported like normal errors.
- """
- test = runner.TestLoader().loadByName('doesntexist')
- test.run(self.result)
- output = self.stream.getvalue()
- # Just check that 'doesntexist' is in the output, rather than
- # assembling the expected stack trace.
- self.assertIn('doesntexist', output)
-
-
-
-class TestSubunitReporterNotInstalled(unittest.TestCase):
- """
- Test behaviour when the subunit reporter is not installed.
- """
-
- def test_subunitNotInstalled(self):
- """
- If subunit is not installed, TestProtocolClient will be None, and
- SubunitReporter will raise an error when you try to construct it.
- """
- stream = StringIO.StringIO()
- self.patch(reporter, 'TestProtocolClient', None)
- e = self.assertRaises(Exception, reporter.SubunitReporter, stream)
- self.assertEqual("Subunit not available", str(e))
-
-
-
-class TestTimingReporter(TestReporter):
- resultFactory = reporter.TimingTextReporter
-
-
-
-class LoggingReporter(reporter.Reporter):
- """
- Simple reporter that stores the last test that was passed to it.
- """
-
- def __init__(self, *args, **kwargs):
- reporter.Reporter.__init__(self, *args, **kwargs)
- self.test = None
-
- def addError(self, test, error):
- self.test = test
-
- def addExpectedFailure(self, test, failure, todo):
- self.test = test
-
- def addFailure(self, test, failure):
- self.test = test
-
- def addSkip(self, test, skip):
- self.test = test
-
- def addUnexpectedSuccess(self, test, todo):
- self.test = test
-
- def startTest(self, test):
- self.test = test
-
- def stopTest(self, test):
- self.test = test
-
-
-
-class TestAdaptedReporter(unittest.TestCase):
- """
- L{reporter._AdaptedReporter} is a reporter wrapper that wraps all of the
- tests it receives before passing them on to the original reporter.
- """
-
- def setUp(self):
- self.wrappedResult = self.getWrappedResult()
-
-
- def _testAdapter(self, test):
- return test.id()
-
-
- def assertWrapped(self, wrappedResult, test):
- self.assertEqual(wrappedResult._originalReporter.test, self._testAdapter(test))
-
-
- def getFailure(self, exceptionInstance):
- """
- Return a L{Failure} from raising the given exception.
-
- @param exceptionInstance: The exception to raise.
- @return: L{Failure}
- """
- try:
- raise exceptionInstance
- except:
- return Failure()
-
-
- def getWrappedResult(self):
- result = LoggingReporter()
- return reporter._AdaptedReporter(result, self._testAdapter)
-
-
- def test_addError(self):
- """
- C{addError} wraps its test with the provided adapter.
- """
- self.wrappedResult.addError(self, self.getFailure(RuntimeError()))
- self.assertWrapped(self.wrappedResult, self)
-
-
- def test_addFailure(self):
- """
- C{addFailure} wraps its test with the provided adapter.
- """
- self.wrappedResult.addFailure(self, self.getFailure(AssertionError()))
- self.assertWrapped(self.wrappedResult, self)
-
-
- def test_addSkip(self):
- """
- C{addSkip} wraps its test with the provided adapter.
- """
- self.wrappedResult.addSkip(self, self.getFailure(SkipTest('no reason')))
- self.assertWrapped(self.wrappedResult, self)
-
-
- def test_startTest(self):
- """
- C{startTest} wraps its test with the provided adapter.
- """
- self.wrappedResult.startTest(self)
- self.assertWrapped(self.wrappedResult, self)
-
-
- def test_stopTest(self):
- """
- C{stopTest} wraps its test with the provided adapter.
- """
- self.wrappedResult.stopTest(self)
- self.assertWrapped(self.wrappedResult, self)
-
-
- def test_addExpectedFailure(self):
- """
- C{addExpectedFailure} wraps its test with the provided adapter.
- """
- self.wrappedResult.addExpectedFailure(
- self, self.getFailure(RuntimeError()), Todo("no reason"))
- self.assertWrapped(self.wrappedResult, self)
-
-
- def test_addUnexpectedSuccess(self):
- """
- C{addUnexpectedSuccess} wraps its test with the provided adapter.
- """
- self.wrappedResult.addUnexpectedSuccess(self, Todo("no reason"))
- self.assertWrapped(self.wrappedResult, self)
-
-
-
-class FakeStream(object):
- """
- A fake stream which C{isatty} method returns some predictable.
-
- @ivar tty: returned value of C{isatty}.
- @type tty: C{bool}
- """
-
- def __init__(self, tty=True):
- self.tty = tty
-
-
- def isatty(self):
- return self.tty
-
-
-
-class AnsiColorizerTests(unittest.TestCase):
- """
- Tests for L{reporter._AnsiColorizer}.
- """
-
- def setUp(self):
- self.savedModules = sys.modules.copy()
-
-
- def tearDown(self):
- sys.modules.clear()
- sys.modules.update(self.savedModules)
-
-
- def test_supportedStdOutTTY(self):
- """
- L{reporter._AnsiColorizer.supported} returns C{False} if the given
- stream is not a TTY.
- """
- self.assertFalse(reporter._AnsiColorizer.supported(FakeStream(False)))
-
-
- def test_supportedNoCurses(self):
- """
- L{reporter._AnsiColorizer.supported} returns C{False} if the curses
- module can't be imported.
- """
- sys.modules['curses'] = None
- self.assertFalse(reporter._AnsiColorizer.supported(FakeStream()))
-
-
- def test_supportedSetupTerm(self):
- """
- L{reporter._AnsiColorizer.supported} returns C{True} if
- C{curses.tigetnum} returns more than 2 supported colors. It only tries
- to call C{curses.setupterm} if C{curses.tigetnum} previously failed
- with a C{curses.error}.
- """
- class fakecurses(object):
- error = RuntimeError
- setUp = 0
-
- def setupterm(self):
- self.setUp += 1
-
- def tigetnum(self, value):
- if self.setUp:
- return 3
- else:
- raise self.error()
-
- sys.modules['curses'] = fakecurses()
- self.assertTrue(reporter._AnsiColorizer.supported(FakeStream()))
- self.assertTrue(reporter._AnsiColorizer.supported(FakeStream()))
-
- self.assertEqual(sys.modules['curses'].setUp, 1)
-
-
- def test_supportedTigetNumWrongError(self):
- """
- L{reporter._AnsiColorizer.supported} returns C{False} and doesn't try
- to call C{curses.setupterm} if C{curses.tigetnum} returns something
- different than C{curses.error}.
- """
- class fakecurses(object):
- error = RuntimeError
-
- def tigetnum(self, value):
- raise ValueError()
-
- sys.modules['curses'] = fakecurses()
- self.assertFalse(reporter._AnsiColorizer.supported(FakeStream()))
-
-
- def test_supportedTigetNumNotEnoughColor(self):
- """
- L{reporter._AnsiColorizer.supported} returns C{False} if
- C{curses.tigetnum} returns less than 2 supported colors.
- """
- class fakecurses(object):
- error = RuntimeError
-
- def tigetnum(self, value):
- return 1
-
- sys.modules['curses'] = fakecurses()
- self.assertFalse(reporter._AnsiColorizer.supported(FakeStream()))
-
-
- def test_supportedTigetNumErrors(self):
- """
- L{reporter._AnsiColorizer.supported} returns C{False} if
- C{curses.tigetnum} raises an error, and calls C{curses.setupterm} once.
- """
- class fakecurses(object):
- error = RuntimeError
- setUp = 0
-
- def setupterm(self):
- self.setUp += 1
-
- def tigetnum(self, value):
- raise self.error()
-
- sys.modules['curses'] = fakecurses()
- self.assertFalse(reporter._AnsiColorizer.supported(FakeStream()))
- self.assertEqual(sys.modules['curses'].setUp, 1)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_runner.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_runner.py
deleted file mode 100755
index 12fcc866..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_runner.py
+++ /dev/null
@@ -1,1034 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-# Maintainer: Jonathan Lange
-# Author: Robert Collins
-
-
-import StringIO, os, sys
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.trial.itrial import IReporter, ITestCase
-from twisted.trial import unittest, runner, reporter, util
-from twisted.python import failure, log, reflect, filepath
-from twisted.python.filepath import FilePath
-from twisted.scripts import trial
-from twisted.plugins import twisted_trial
-from twisted import plugin
-from twisted.internet import defer
-
-
-pyunit = __import__('unittest')
-
-
-class CapturingDebugger(object):
-
- def __init__(self):
- self._calls = []
-
- def runcall(self, *args, **kwargs):
- self._calls.append('runcall')
- args[0](*args[1:], **kwargs)
-
-
-
-class CapturingReporter(object):
- """
- Reporter that keeps a log of all actions performed on it.
- """
-
- implements(IReporter)
-
- stream = None
- tbformat = None
- args = None
- separator = None
- testsRun = None
-
- def __init__(self, stream=None, tbformat=None, rterrors=None,
- publisher=None):
- """
- Create a capturing reporter.
- """
- self._calls = []
- self.shouldStop = False
- self._stream = stream
- self._tbformat = tbformat
- self._rterrors = rterrors
- self._publisher = publisher
-
-
- def startTest(self, method):
- """
- Report the beginning of a run of a single test method
- @param method: an object that is adaptable to ITestMethod
- """
- self._calls.append('startTest')
-
-
- def stopTest(self, method):
- """
- Report the status of a single test method
- @param method: an object that is adaptable to ITestMethod
- """
- self._calls.append('stopTest')
-
-
- def cleanupErrors(self, errs):
- """called when the reactor has been left in a 'dirty' state
- @param errs: a list of L{twisted.python.failure.Failure}s
- """
- self._calls.append('cleanupError')
-
-
- def addSuccess(self, test):
- self._calls.append('addSuccess')
-
-
- def done(self):
- """
- Do nothing. These tests don't care about done.
- """
-
-
-
-class TrialRunnerTestsMixin:
- """
- Mixin defining tests for L{runner.TrialRunner}.
- """
- def tearDown(self):
- self.runner._tearDownLogFile()
-
-
- def test_empty(self):
- """
- Empty test method, used by the other tests.
- """
-
-
- def _getObservers(self):
- return log.theLogPublisher.observers
-
-
- def test_addObservers(self):
- """
- Any log system observers L{TrialRunner.run} adds are removed by the
- time it returns.
- """
- originalCount = len(self._getObservers())
- self.runner.run(self.test)
- newCount = len(self._getObservers())
- self.assertEqual(newCount, originalCount)
-
-
- def test_logFileAlwaysActive(self):
- """
- Test that a new file is opened on each run.
- """
- oldSetUpLogFile = self.runner._setUpLogFile
- l = []
- def setUpLogFile():
- oldSetUpLogFile()
- l.append(self.runner._logFileObserver)
- self.runner._setUpLogFile = setUpLogFile
- self.runner.run(self.test)
- self.runner.run(self.test)
- self.assertEqual(len(l), 2)
- self.failIf(l[0] is l[1], "Should have created a new file observer")
-
-
- def test_logFileGetsClosed(self):
- """
- Test that file created is closed during the run.
- """
- oldSetUpLogFile = self.runner._setUpLogFile
- l = []
- def setUpLogFile():
- oldSetUpLogFile()
- l.append(self.runner._logFileObject)
- self.runner._setUpLogFile = setUpLogFile
- self.runner.run(self.test)
- self.assertEqual(len(l), 1)
- self.failUnless(l[0].closed)
-
-
-
-class TestTrialRunner(TrialRunnerTestsMixin, unittest.TestCase):
- """
- Tests for L{runner.TrialRunner} with the feature to turn unclean errors
- into warnings disabled.
- """
- def setUp(self):
- self.stream = StringIO.StringIO()
- self.runner = runner.TrialRunner(CapturingReporter, stream=self.stream)
- self.test = TestTrialRunner('test_empty')
-
-
- def test_publisher(self):
- """
- The reporter constructed by L{runner.TrialRunner} is passed
- L{twisted.python.log} as the value for the C{publisher} parameter.
- """
- result = self.runner._makeResult()
- self.assertIdentical(result._publisher, log)
-
-
-
-class TrialRunnerWithUncleanWarningsReporter(TrialRunnerTestsMixin,
- unittest.TestCase):
- """
- Tests for the TrialRunner's interaction with an unclean-error suppressing
- reporter.
- """
-
- def setUp(self):
- self.stream = StringIO.StringIO()
- self.runner = runner.TrialRunner(CapturingReporter, stream=self.stream,
- uncleanWarnings=True)
- self.test = TestTrialRunner('test_empty')
-
-
-
-class DryRunMixin(object):
-
- suppress = [util.suppress(
- category=DeprecationWarning,
- message="Test visitors deprecated in Twisted 8.0")]
-
-
- def setUp(self):
- self.log = []
- self.stream = StringIO.StringIO()
- self.runner = runner.TrialRunner(CapturingReporter,
- runner.TrialRunner.DRY_RUN,
- stream=self.stream)
- self.makeTestFixtures()
-
-
- def makeTestFixtures(self):
- """
- Set C{self.test} and C{self.suite}, where C{self.suite} is an empty
- TestSuite.
- """
-
-
- def test_empty(self):
- """
- If there are no tests, the reporter should not receive any events to
- report.
- """
- result = self.runner.run(runner.TestSuite())
- self.assertEqual(result._calls, [])
-
-
- def test_singleCaseReporting(self):
- """
- If we are running a single test, check the reporter starts, passes and
- then stops the test during a dry run.
- """
- result = self.runner.run(self.test)
- self.assertEqual(result._calls, ['startTest', 'addSuccess', 'stopTest'])
-
-
- def test_testsNotRun(self):
- """
- When we are doing a dry run, the tests should not actually be run.
- """
- self.runner.run(self.test)
- self.assertEqual(self.log, [])
-
-
-
-class DryRunTest(DryRunMixin, unittest.TestCase):
- """
- Check that 'dry run' mode works well with Trial tests.
- """
- def makeTestFixtures(self):
- class MockTest(unittest.TestCase):
- def test_foo(test):
- self.log.append('test_foo')
- self.test = MockTest('test_foo')
- self.suite = runner.TestSuite()
-
-
-
-class PyUnitDryRunTest(DryRunMixin, unittest.TestCase):
- """
- Check that 'dry run' mode works well with stdlib unittest tests.
- """
- def makeTestFixtures(self):
- class PyunitCase(pyunit.TestCase):
- def test_foo(self):
- pass
- self.test = PyunitCase('test_foo')
- self.suite = pyunit.TestSuite()
-
-
-
-class TestRunner(unittest.TestCase):
- def setUp(self):
- self.config = trial.Options()
- # whitebox hack a reporter in, because plugins are CACHED and will
- # only reload if the FILE gets changed.
-
- parts = reflect.qual(CapturingReporter).split('.')
- package = '.'.join(parts[:-1])
- klass = parts[-1]
- plugins = [twisted_trial._Reporter(
- "Test Helper Reporter",
- package,
- description="Utility for unit testing.",
- longOpt="capturing",
- shortOpt=None,
- klass=klass)]
-
-
- # XXX There should really be a general way to hook the plugin system
- # for tests.
- def getPlugins(iface, *a, **kw):
- self.assertEqual(iface, IReporter)
- return plugins + list(self.original(iface, *a, **kw))
-
- self.original = plugin.getPlugins
- plugin.getPlugins = getPlugins
-
- self.standardReport = ['startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest',
- 'startTest', 'addSuccess', 'stopTest']
-
-
- def tearDown(self):
- plugin.getPlugins = self.original
-
-
- def parseOptions(self, args):
- self.config.parseOptions(args)
-
-
- def getRunner(self):
- r = trial._makeRunner(self.config)
- r.stream = StringIO.StringIO()
- # XXX The runner should always take care of cleaning this up itself.
- # It's not clear why this is necessary. The runner always tears down
- # its log file.
- self.addCleanup(r._tearDownLogFile)
- # XXX The runner should always take care of cleaning this up itself as
- # well. It's necessary because TrialRunner._setUpTestdir might raise
- # an exception preventing Reporter.done from being run, leaving the
- # observer added by Reporter.__init__ still present in the system.
- # Something better needs to happen inside
- # TrialRunner._runWithoutDecoration to remove the need for this cludge.
- r._log = log.LogPublisher()
- return r
-
-
- def test_runner_can_get_reporter(self):
- self.parseOptions([])
- result = self.config['reporter']
- runner = self.getRunner()
- self.assertEqual(result, runner._makeResult().__class__)
-
-
- def test_runner_get_result(self):
- self.parseOptions([])
- runner = self.getRunner()
- result = runner._makeResult()
- self.assertEqual(result.__class__, self.config['reporter'])
-
-
- def test_uncleanWarningsOffByDefault(self):
- """
- By default Trial sets the 'uncleanWarnings' option on the runner to
- False. This means that dirty reactor errors will be reported as
- errors. See L{test_reporter.TestDirtyReactor}.
- """
- self.parseOptions([])
- runner = self.getRunner()
- self.assertNotIsInstance(runner._makeResult(),
- reporter.UncleanWarningsReporterWrapper)
-
-
- def test_getsUncleanWarnings(self):
- """
- Specifying '--unclean-warnings' on the trial command line will cause
- reporters to be wrapped in a device which converts unclean errors to
- warnings. See L{test_reporter.TestDirtyReactor} for implications.
- """
- self.parseOptions(['--unclean-warnings'])
- runner = self.getRunner()
- self.assertIsInstance(runner._makeResult(),
- reporter.UncleanWarningsReporterWrapper)
-
-
- def test_runner_working_directory(self):
- self.parseOptions(['--temp-directory', 'some_path'])
- runner = self.getRunner()
- self.assertEqual(runner.workingDirectory, 'some_path')
-
-
- def test_concurrentImplicitWorkingDirectory(self):
- """
- If no working directory is explicitly specified and the default
- working directory is in use by another runner, L{TrialRunner.run}
- selects a different default working directory to use.
- """
- self.parseOptions([])
-
- # Make sure we end up with the same working directory after this test
- # as we had before it.
- self.addCleanup(os.chdir, os.getcwd())
-
- # Make a new directory and change into it. This isolates us from state
- # that other tests might have dumped into this process's temp
- # directory.
- runDirectory = FilePath(self.mktemp())
- runDirectory.makedirs()
- os.chdir(runDirectory.path)
-
- firstRunner = self.getRunner()
- secondRunner = self.getRunner()
-
- where = {}
-
- class ConcurrentCase(unittest.TestCase):
- def test_first(self):
- """
- Start a second test run which will have a default working
- directory which is the same as the working directory of the
- test run already in progress.
- """
- # Change the working directory to the value it had before this
- # test suite was started.
- where['concurrent'] = subsequentDirectory = os.getcwd()
- os.chdir(runDirectory.path)
- self.addCleanup(os.chdir, subsequentDirectory)
-
- secondRunner.run(ConcurrentCase('test_second'))
-
- def test_second(self):
- """
- Record the working directory for later analysis.
- """
- where['record'] = os.getcwd()
-
- result = firstRunner.run(ConcurrentCase('test_first'))
- bad = result.errors + result.failures
- if bad:
- self.fail(bad[0][1])
- self.assertEqual(
- where, {
- 'concurrent': runDirectory.child('_trial_temp').path,
- 'record': runDirectory.child('_trial_temp-1').path})
-
-
- def test_concurrentExplicitWorkingDirectory(self):
- """
- If a working directory which is already in use is explicitly specified,
- L{TrialRunner.run} raises L{_WorkingDirectoryBusy}.
- """
- self.parseOptions(['--temp-directory', os.path.abspath(self.mktemp())])
-
- initialDirectory = os.getcwd()
- self.addCleanup(os.chdir, initialDirectory)
-
- firstRunner = self.getRunner()
- secondRunner = self.getRunner()
-
- class ConcurrentCase(unittest.TestCase):
- def test_concurrent(self):
- """
- Try to start another runner in the same working directory and
- assert that it raises L{_WorkingDirectoryBusy}.
- """
- self.assertRaises(
- util._WorkingDirectoryBusy,
- secondRunner.run, ConcurrentCase('test_failure'))
-
- def test_failure(self):
- """
- Should not be called, always fails.
- """
- self.fail("test_failure should never be called.")
-
- result = firstRunner.run(ConcurrentCase('test_concurrent'))
- bad = result.errors + result.failures
- if bad:
- self.fail(bad[0][1])
-
-
- def test_runner_normal(self):
- self.parseOptions(['--temp-directory', self.mktemp(),
- '--reporter', 'capturing',
- 'twisted.trial.test.sample'])
- my_runner = self.getRunner()
- loader = runner.TestLoader()
- suite = loader.loadByName('twisted.trial.test.sample', True)
- result = my_runner.run(suite)
- self.assertEqual(self.standardReport, result._calls)
-
-
- def test_runner_debug(self):
- self.parseOptions(['--reporter', 'capturing',
- '--debug', 'twisted.trial.test.sample'])
- my_runner = self.getRunner()
- debugger = CapturingDebugger()
- def get_debugger():
- return debugger
- my_runner._getDebugger = get_debugger
- loader = runner.TestLoader()
- suite = loader.loadByName('twisted.trial.test.sample', True)
- result = my_runner.run(suite)
- self.assertEqual(self.standardReport, result._calls)
- self.assertEqual(['runcall'], debugger._calls)
-
-
-
-class RemoveSafelyTests(unittest.TestCase):
- """
- Tests for L{_removeSafely}.
- """
- def test_removeSafelyNoTrialMarker(self):
- """
- If a path doesn't contain a node named C{"_trial_marker"}, that path is
- not removed by L{runner._removeSafely} and a L{runner._NoTrialMarker}
- exception is raised instead.
- """
- directory = self.mktemp()
- os.mkdir(directory)
- dirPath = filepath.FilePath(directory)
- self.assertRaises(util._NoTrialMarker, util._removeSafely, dirPath)
-
-
- def test_removeSafelyRemoveFailsMoveSucceeds(self):
- """
- If an L{OSError} is raised while removing a path in
- L{runner._removeSafely}, an attempt is made to move the path to a new
- name.
- """
- def dummyRemove():
- """
- Raise an C{OSError} to emulate the branch of L{runner._removeSafely}
- in which path removal fails.
- """
- raise OSError()
-
- # Patch stdout so we can check the print statements in _removeSafely
- out = StringIO.StringIO()
- self.patch(sys, 'stdout', out)
-
- # Set up a trial directory with a _trial_marker
- directory = self.mktemp()
- os.mkdir(directory)
- dirPath = filepath.FilePath(directory)
- dirPath.child('_trial_marker').touch()
- # Ensure that path.remove() raises an OSError
- dirPath.remove = dummyRemove
-
- util._removeSafely(dirPath)
- self.assertIn("could not remove FilePath", out.getvalue())
-
-
- def test_removeSafelyRemoveFailsMoveFails(self):
- """
- If an L{OSError} is raised while removing a path in
- L{runner._removeSafely}, an attempt is made to move the path to a new
- name. If that attempt fails, the L{OSError} is re-raised.
- """
- def dummyRemove():
- """
- Raise an C{OSError} to emulate the branch of L{runner._removeSafely}
- in which path removal fails.
- """
- raise OSError("path removal failed")
-
- def dummyMoveTo(path):
- """
- Raise an C{OSError} to emulate the branch of L{runner._removeSafely}
- in which path movement fails.
- """
- raise OSError("path movement failed")
-
- # Patch stdout so we can check the print statements in _removeSafely
- out = StringIO.StringIO()
- self.patch(sys, 'stdout', out)
-
- # Set up a trial directory with a _trial_marker
- directory = self.mktemp()
- os.mkdir(directory)
- dirPath = filepath.FilePath(directory)
- dirPath.child('_trial_marker').touch()
-
- # Ensure that path.remove() and path.moveTo() both raise OSErrors
- dirPath.remove = dummyRemove
- dirPath.moveTo = dummyMoveTo
-
- error = self.assertRaises(OSError, util._removeSafely, dirPath)
- self.assertEqual(str(error), "path movement failed")
- self.assertIn("could not remove FilePath", out.getvalue())
-
-
-
-class TestTrialSuite(unittest.TestCase):
-
- def test_imports(self):
- # FIXME, HTF do you test the reactor can be cleaned up ?!!!
- from twisted.trial.runner import TrialSuite
-
-
-
-
-class TestUntilFailure(unittest.TestCase):
- class FailAfter(unittest.TestCase):
- """
- A test case that fails when run 3 times in a row.
- """
- count = []
- def test_foo(self):
- self.count.append(None)
- if len(self.count) == 3:
- self.fail('Count reached 3')
-
-
- def setUp(self):
- TestUntilFailure.FailAfter.count = []
- self.test = TestUntilFailure.FailAfter('test_foo')
- self.stream = StringIO.StringIO()
- self.runner = runner.TrialRunner(reporter.Reporter, stream=self.stream)
-
-
- def test_runUntilFailure(self):
- """
- Test that the runUntilFailure method of the runner actually fail after
- a few runs.
- """
- result = self.runner.runUntilFailure(self.test)
- self.assertEqual(result.testsRun, 1)
- self.failIf(result.wasSuccessful())
- self.assertEqual(self._getFailures(result), 1)
-
-
- def _getFailures(self, result):
- """
- Get the number of failures that were reported to a result.
- """
- return len(result.failures)
-
-
- def test_runUntilFailureDecorate(self):
- """
- C{runUntilFailure} doesn't decorate the tests uselessly: it does it one
- time when run starts, but not at each turn.
- """
- decorated = []
- def decorate(test, interface):
- decorated.append((test, interface))
- return test
- self.patch(unittest, "decorate", decorate)
- result = self.runner.runUntilFailure(self.test)
- self.assertEqual(result.testsRun, 1)
-
- self.assertEqual(len(decorated), 1)
- self.assertEqual(decorated, [(self.test, ITestCase)])
-
-
- def test_runUntilFailureForceGCDecorate(self):
- """
- C{runUntilFailure} applies the force-gc decoration after the standard
- L{ITestCase} decoration, but only one time.
- """
- decorated = []
- def decorate(test, interface):
- decorated.append((test, interface))
- return test
- self.patch(unittest, "decorate", decorate)
- self.runner._forceGarbageCollection = True
- result = self.runner.runUntilFailure(self.test)
- self.assertEqual(result.testsRun, 1)
-
- self.assertEqual(len(decorated), 2)
- self.assertEqual(decorated,
- [(self.test, ITestCase),
- (self.test, unittest._ForceGarbageCollectionDecorator)])
-
-
-
-class UncleanUntilFailureTests(TestUntilFailure):
- """
- Test that the run-until-failure feature works correctly with the unclean
- error suppressor.
- """
-
- def setUp(self):
- TestUntilFailure.setUp(self)
- self.runner = runner.TrialRunner(reporter.Reporter, stream=self.stream,
- uncleanWarnings=True)
-
- def _getFailures(self, result):
- """
- Get the number of failures that were reported to a result that
- is wrapped in an UncleanFailureWrapper.
- """
- return len(result._originalReporter.failures)
-
-
-
-class BreakingSuite(runner.TestSuite):
- """
- A L{TestSuite} that logs an error when it is run.
- """
-
- def run(self, result):
- try:
- raise RuntimeError("error that occurs outside of a test")
- except RuntimeError:
- log.err(failure.Failure())
-
-
-
-class TestLoggedErrors(unittest.TestCase):
- """
- It is possible for an error generated by a test to be logged I{outside} of
- any test. The log observers constructed by L{TestCase} won't catch these
- errors. Here we try to generate such errors and ensure they are reported to
- a L{TestResult} object.
- """
-
- def tearDown(self):
- self.flushLoggedErrors(RuntimeError)
-
-
- def test_construct(self):
- """
- Check that we can construct a L{runner.LoggedSuite} and that it
- starts empty.
- """
- suite = runner.LoggedSuite()
- self.assertEqual(suite.countTestCases(), 0)
-
-
- def test_capturesError(self):
- """
- Chek that a L{LoggedSuite} reports any logged errors to its result.
- """
- result = reporter.TestResult()
- suite = runner.LoggedSuite([BreakingSuite()])
- suite.run(result)
- self.assertEqual(len(result.errors), 1)
- self.assertEqual(result.errors[0][0].id(), runner.NOT_IN_TEST)
- self.failUnless(result.errors[0][1].check(RuntimeError))
-
-
-
-class TestTestHolder(unittest.TestCase):
-
- def setUp(self):
- self.description = "description"
- self.holder = runner.TestHolder(self.description)
-
-
- def test_holder(self):
- """
- Check that L{runner.TestHolder} takes a description as a parameter
- and that this description is returned by the C{id} and
- C{shortDescription} methods.
- """
- self.assertEqual(self.holder.id(), self.description)
- self.assertEqual(self.holder.shortDescription(), self.description)
-
-
- def test_holderImplementsITestCase(self):
- """
- L{runner.TestHolder} implements L{ITestCase}.
- """
- self.assertIdentical(self.holder, ITestCase(self.holder))
- self.assertTrue(
- verifyObject(ITestCase, self.holder),
- "%r claims to provide %r but does not do so correctly."
- % (self.holder, ITestCase))
-
-
- def test_runsWithStandardResult(self):
- """
- A L{runner.TestHolder} can run against the standard Python
- C{TestResult}.
- """
- result = pyunit.TestResult()
- self.holder.run(result)
- self.assertTrue(result.wasSuccessful())
- self.assertEqual(1, result.testsRun)
-
-
-
-class ErrorHolderTestsMixin(object):
- """
- This mixin defines test methods which can be applied to a
- L{runner.ErrorHolder} constructed with either a L{Failure} or a
- C{exc_info}-style tuple.
-
- Subclass this and implement C{setUp} to create C{self.holder} referring to a
- L{runner.ErrorHolder} instance and C{self.error} referring to a L{Failure}
- which the holder holds.
- """
- exceptionForTests = ZeroDivisionError('integer division or modulo by zero')
-
- class TestResultStub(object):
- """
- Stub for L{TestResult}.
- """
- def __init__(self):
- self.errors = []
-
- def startTest(self, test):
- pass
-
- def stopTest(self, test):
- pass
-
- def addError(self, test, error):
- self.errors.append((test, error))
-
-
- def test_runsWithStandardResult(self):
- """
- A L{runner.ErrorHolder} can run against the standard Python
- C{TestResult}.
- """
- result = pyunit.TestResult()
- self.holder.run(result)
- self.assertFalse(result.wasSuccessful())
- self.assertEqual(1, result.testsRun)
-
-
- def test_run(self):
- """
- L{runner.ErrorHolder} adds an error to the result when run.
- """
- self.holder.run(self.result)
- self.assertEqual(
- self.result.errors,
- [(self.holder, (self.error.type, self.error.value, self.error.tb))])
-
-
- def test_call(self):
- """
- L{runner.ErrorHolder} adds an error to the result when called.
- """
- self.holder(self.result)
- self.assertEqual(
- self.result.errors,
- [(self.holder, (self.error.type, self.error.value, self.error.tb))])
-
-
- def test_countTestCases(self):
- """
- L{runner.ErrorHolder.countTestCases} always returns 0.
- """
- self.assertEqual(self.holder.countTestCases(), 0)
-
-
- def test_repr(self):
- """
- L{runner.ErrorHolder.__repr__} returns a string describing the error it
- holds.
- """
- self.assertEqual(repr(self.holder),
- "<ErrorHolder description='description' "
- "error=ZeroDivisionError('integer division or modulo by zero',)>")
-
-
-
-class FailureHoldingErrorHolderTests(ErrorHolderTestsMixin, TestTestHolder):
- """
- Tests for L{runner.ErrorHolder} behaving similarly to L{runner.TestHolder}
- when constructed with a L{Failure} representing its error.
- """
- def setUp(self):
- self.description = "description"
- # make a real Failure so we can construct ErrorHolder()
- try:
- raise self.exceptionForTests
- except ZeroDivisionError:
- self.error = failure.Failure()
- self.holder = runner.ErrorHolder(self.description, self.error)
- self.result = self.TestResultStub()
-
-
-
-class ExcInfoHoldingErrorHolderTests(ErrorHolderTestsMixin, TestTestHolder):
- """
- Tests for L{runner.ErrorHolder} behaving similarly to L{runner.TestHolder}
- when constructed with a C{exc_info}-style tuple representing its error.
- """
- def setUp(self):
- self.description = "description"
- # make a real Failure so we can construct ErrorHolder()
- try:
- raise self.exceptionForTests
- except ZeroDivisionError:
- exceptionInfo = sys.exc_info()
- self.error = failure.Failure()
- self.holder = runner.ErrorHolder(self.description, exceptionInfo)
- self.result = self.TestResultStub()
-
-
-
-class TestMalformedMethod(unittest.TestCase):
- """
- Test that trial manages when test methods don't have correct signatures.
- """
- class ContainMalformed(unittest.TestCase):
- """
- This TestCase holds malformed test methods that trial should handle.
- """
- def test_foo(self, blah):
- pass
- def test_bar():
- pass
- test_spam = defer.deferredGenerator(test_bar)
-
- def _test(self, method):
- """
- Wrapper for one of the test method of L{ContainMalformed}.
- """
- stream = StringIO.StringIO()
- trialRunner = runner.TrialRunner(reporter.Reporter, stream=stream)
- test = TestMalformedMethod.ContainMalformed(method)
- result = trialRunner.run(test)
- self.assertEqual(result.testsRun, 1)
- self.failIf(result.wasSuccessful())
- self.assertEqual(len(result.errors), 1)
-
- def test_extraArg(self):
- """
- Test when the method has extra (useless) arguments.
- """
- self._test('test_foo')
-
- def test_noArg(self):
- """
- Test when the method doesn't have even self as argument.
- """
- self._test('test_bar')
-
- def test_decorated(self):
- """
- Test a decorated method also fails.
- """
- self._test('test_spam')
-
-
-
-class DestructiveTestSuiteTestCase(unittest.TestCase):
- """
- Test for L{runner.DestructiveTestSuite}.
- """
-
- def test_basic(self):
- """
- Thes destructive test suite should run the tests normally.
- """
- called = []
- class MockTest(unittest.TestCase):
- def test_foo(test):
- called.append(True)
- test = MockTest('test_foo')
- result = reporter.TestResult()
- suite = runner.DestructiveTestSuite([test])
- self.assertEqual(called, [])
- suite.run(result)
- self.assertEqual(called, [True])
- self.assertEqual(suite.countTestCases(), 0)
-
-
- def test_shouldStop(self):
- """
- Test the C{shouldStop} management: raising a C{KeyboardInterrupt} must
- interrupt the suite.
- """
- called = []
- class MockTest(unittest.TestCase):
- def test_foo1(test):
- called.append(1)
- def test_foo2(test):
- raise KeyboardInterrupt()
- def test_foo3(test):
- called.append(2)
- result = reporter.TestResult()
- loader = runner.TestLoader()
- loader.suiteFactory = runner.DestructiveTestSuite
- suite = loader.loadClass(MockTest)
- self.assertEqual(called, [])
- suite.run(result)
- self.assertEqual(called, [1])
- # The last test shouldn't have been run
- self.assertEqual(suite.countTestCases(), 1)
-
-
- def test_cleanup(self):
- """
- Checks that the test suite cleanups its tests during the run, so that
- it ends empty.
- """
- class MockTest(unittest.TestCase):
- def test_foo(test):
- pass
- test = MockTest('test_foo')
- result = reporter.TestResult()
- suite = runner.DestructiveTestSuite([test])
- self.assertEqual(suite.countTestCases(), 1)
- suite.run(result)
- self.assertEqual(suite.countTestCases(), 0)
-
-
-
-class TestRunnerDeprecation(unittest.TestCase):
-
- class FakeReporter(reporter.Reporter):
- """
- Fake reporter that does *not* implement done() but *does* implement
- printErrors, separator, printSummary, stream, write and writeln
- without deprecations.
- """
-
- done = None
- separator = None
- stream = None
-
- def printErrors(self, *args):
- pass
-
- def printSummary(self, *args):
- pass
-
- def write(self, *args):
- pass
-
- def writeln(self, *args):
- pass
-
-
- def test_reporterDeprecations(self):
- """
- The runner emits a warning if it is using a result that doesn't
- implement 'done'.
- """
- trialRunner = runner.TrialRunner(None)
- result = self.FakeReporter()
- trialRunner._makeResult = lambda: result
- def f():
- # We have to use a pyunit test, otherwise we'll get deprecation
- # warnings about using iterate() in a test.
- trialRunner.run(pyunit.TestCase('id'))
- self.assertWarns(
- DeprecationWarning,
- "%s should implement done() but doesn't. Falling back to "
- "printErrors() and friends." % reflect.qual(result.__class__),
- __file__, f)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_script.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_script.py
deleted file mode 100755
index a8d489d5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_script.py
+++ /dev/null
@@ -1,443 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import gc
-import StringIO, sys, types
-
-from twisted.trial import unittest, runner
-from twisted.scripts import trial
-from twisted.python import util
-from twisted.python.compat import set
-from twisted.python.filepath import FilePath
-
-from twisted.trial.test.test_loader import testNames
-
-pyunit = __import__('unittest')
-
-
-def sibpath(filename):
- """
- For finding files in twisted/trial/test
- """
- return util.sibpath(__file__, filename)
-
-
-
-class ForceGarbageCollection(unittest.TestCase):
- """
- Tests for the --force-gc option.
- """
-
- def setUp(self):
- self.config = trial.Options()
- self.log = []
- self.patch(gc, 'collect', self.collect)
- test = pyunit.FunctionTestCase(self.simpleTest)
- self.test = runner.TestSuite([test, test])
-
-
- def simpleTest(self):
- """
- A simple test method that records that it was run.
- """
- self.log.append('test')
-
-
- def collect(self):
- """
- A replacement for gc.collect that logs calls to itself.
- """
- self.log.append('collect')
-
-
- def makeRunner(self):
- """
- Return a L{runner.TrialRunner} object that is safe to use in tests.
- """
- runner = trial._makeRunner(self.config)
- runner.stream = StringIO.StringIO()
- return runner
-
-
- def test_forceGc(self):
- """
- Passing the --force-gc option to the trial script forces the garbage
- collector to run before and after each test.
- """
- self.config['force-gc'] = True
- self.config.postOptions()
- runner = self.makeRunner()
- runner.run(self.test)
- self.assertEqual(self.log, ['collect', 'test', 'collect',
- 'collect', 'test', 'collect'])
-
-
- def test_unforceGc(self):
- """
- By default, no garbage collection is forced.
- """
- self.config.postOptions()
- runner = self.makeRunner()
- runner.run(self.test)
- self.assertEqual(self.log, ['test', 'test'])
-
-
-
-class TestSuiteUsed(unittest.TestCase):
- """
- Check the category of tests suite used by the loader.
- """
-
- def setUp(self):
- """
- Create a trial configuration object.
- """
- self.config = trial.Options()
-
-
- def test_defaultSuite(self):
- """
- By default, the loader should use L{runner.DestructiveTestSuite}
- """
- loader = trial._getLoader(self.config)
- self.assertEqual(loader.suiteFactory, runner.DestructiveTestSuite)
-
-
- def test_untilFailureSuite(self):
- """
- The C{until-failure} configuration uses the L{runner.TestSuite} to keep
- instances alive across runs.
- """
- self.config['until-failure'] = True
- loader = trial._getLoader(self.config)
- self.assertEqual(loader.suiteFactory, runner.TestSuite)
-
-
-
-class TestModuleTest(unittest.TestCase):
- def setUp(self):
- self.config = trial.Options()
-
- def tearDown(self):
- self.config = None
-
- def test_testNames(self):
- """
- Check that the testNames helper method accurately collects the
- names of tests in suite.
- """
- self.assertEqual(testNames(self), [self.id()])
-
- def assertSuitesEqual(self, test1, names):
- loader = runner.TestLoader()
- names1 = testNames(test1)
- names2 = testNames(runner.TestSuite(map(loader.loadByName, names)))
- names1.sort()
- names2.sort()
- self.assertEqual(names1, names2)
-
- def test_baseState(self):
- self.assertEqual(0, len(self.config['tests']))
-
- def test_testmoduleOnModule(self):
- """
- Check that --testmodule loads a suite which contains the tests
- referred to in test-case-name inside its parameter.
- """
- self.config.opt_testmodule(sibpath('moduletest.py'))
- self.assertSuitesEqual(trial._getSuite(self.config),
- ['twisted.trial.test.test_test_visitor'])
-
- def test_testmoduleTwice(self):
- """
- When the same module is specified with two --testmodule flags, it
- should only appear once in the suite.
- """
- self.config.opt_testmodule(sibpath('moduletest.py'))
- self.config.opt_testmodule(sibpath('moduletest.py'))
- self.assertSuitesEqual(trial._getSuite(self.config),
- ['twisted.trial.test.test_test_visitor'])
-
- def test_testmoduleOnSourceAndTarget(self):
- """
- If --testmodule is specified twice, once for module A and once for
- a module which refers to module A, then make sure module A is only
- added once.
- """
- self.config.opt_testmodule(sibpath('moduletest.py'))
- self.config.opt_testmodule(sibpath('test_test_visitor.py'))
- self.assertSuitesEqual(trial._getSuite(self.config),
- ['twisted.trial.test.test_test_visitor'])
-
- def test_testmoduleOnSelfModule(self):
- """
- When given a module that refers to *itself* in the test-case-name
- variable, check that --testmodule only adds the tests once.
- """
- self.config.opt_testmodule(sibpath('moduleself.py'))
- self.assertSuitesEqual(trial._getSuite(self.config),
- ['twisted.trial.test.moduleself'])
-
- def test_testmoduleOnScript(self):
- """
- Check that --testmodule loads tests referred to in test-case-name
- buffer variables.
- """
- self.config.opt_testmodule(sibpath('scripttest.py'))
- self.assertSuitesEqual(trial._getSuite(self.config),
- ['twisted.trial.test.test_test_visitor',
- 'twisted.trial.test.test_class'])
-
- def test_testmoduleOnNonexistentFile(self):
- """
- Check that --testmodule displays a meaningful error message when
- passed a non-existent filename.
- """
- buffy = StringIO.StringIO()
- stderr, sys.stderr = sys.stderr, buffy
- filename = 'test_thisbetternoteverexist.py'
- try:
- self.config.opt_testmodule(filename)
- self.assertEqual(0, len(self.config['tests']))
- self.assertEqual("File %r doesn't exist\n" % (filename,),
- buffy.getvalue())
- finally:
- sys.stderr = stderr
-
- def test_testmoduleOnEmptyVars(self):
- """
- Check that --testmodule adds no tests to the suite for modules
- which lack test-case-name buffer variables.
- """
- self.config.opt_testmodule(sibpath('novars.py'))
- self.assertEqual(0, len(self.config['tests']))
-
- def test_testmoduleOnModuleName(self):
- """
- Check that --testmodule does *not* support module names as arguments
- and that it displays a meaningful error message.
- """
- buffy = StringIO.StringIO()
- stderr, sys.stderr = sys.stderr, buffy
- moduleName = 'twisted.trial.test.test_script'
- try:
- self.config.opt_testmodule(moduleName)
- self.assertEqual(0, len(self.config['tests']))
- self.assertEqual("File %r doesn't exist\n" % (moduleName,),
- buffy.getvalue())
- finally:
- sys.stderr = stderr
-
- def test_parseLocalVariable(self):
- declaration = '-*- test-case-name: twisted.trial.test.test_tests -*-'
- localVars = trial._parseLocalVariables(declaration)
- self.assertEqual({'test-case-name':
- 'twisted.trial.test.test_tests'},
- localVars)
-
- def test_trailingSemicolon(self):
- declaration = '-*- test-case-name: twisted.trial.test.test_tests; -*-'
- localVars = trial._parseLocalVariables(declaration)
- self.assertEqual({'test-case-name':
- 'twisted.trial.test.test_tests'},
- localVars)
-
- def test_parseLocalVariables(self):
- declaration = ('-*- test-case-name: twisted.trial.test.test_tests; '
- 'foo: bar -*-')
- localVars = trial._parseLocalVariables(declaration)
- self.assertEqual({'test-case-name':
- 'twisted.trial.test.test_tests',
- 'foo': 'bar'},
- localVars)
-
- def test_surroundingGuff(self):
- declaration = ('## -*- test-case-name: '
- 'twisted.trial.test.test_tests -*- #')
- localVars = trial._parseLocalVariables(declaration)
- self.assertEqual({'test-case-name':
- 'twisted.trial.test.test_tests'},
- localVars)
-
- def test_invalidLine(self):
- self.failUnlessRaises(ValueError, trial._parseLocalVariables,
- 'foo')
-
- def test_invalidDeclaration(self):
- self.failUnlessRaises(ValueError, trial._parseLocalVariables,
- '-*- foo -*-')
- self.failUnlessRaises(ValueError, trial._parseLocalVariables,
- '-*- foo: bar; qux -*-')
- self.failUnlessRaises(ValueError, trial._parseLocalVariables,
- '-*- foo: bar: baz; qux: qax -*-')
-
- def test_variablesFromFile(self):
- localVars = trial.loadLocalVariables(sibpath('moduletest.py'))
- self.assertEqual({'test-case-name':
- 'twisted.trial.test.test_test_visitor'},
- localVars)
-
- def test_noVariablesInFile(self):
- localVars = trial.loadLocalVariables(sibpath('novars.py'))
- self.assertEqual({}, localVars)
-
- def test_variablesFromScript(self):
- localVars = trial.loadLocalVariables(sibpath('scripttest.py'))
- self.assertEqual(
- {'test-case-name': ('twisted.trial.test.test_test_visitor,'
- 'twisted.trial.test.test_class')},
- localVars)
-
- def test_getTestModules(self):
- modules = trial.getTestModules(sibpath('moduletest.py'))
- self.assertEqual(modules, ['twisted.trial.test.test_test_visitor'])
-
- def test_getTestModules_noVars(self):
- modules = trial.getTestModules(sibpath('novars.py'))
- self.assertEqual(len(modules), 0)
-
- def test_getTestModules_multiple(self):
- modules = trial.getTestModules(sibpath('scripttest.py'))
- self.assertEqual(set(modules),
- set(['twisted.trial.test.test_test_visitor',
- 'twisted.trial.test.test_class']))
-
- def test_looksLikeTestModule(self):
- for filename in ['test_script.py', 'twisted/trial/test/test_script.py']:
- self.failUnless(trial.isTestFile(filename),
- "%r should be a test file" % (filename,))
- for filename in ['twisted/trial/test/moduletest.py',
- sibpath('scripttest.py'), sibpath('test_foo.bat')]:
- self.failIf(trial.isTestFile(filename),
- "%r should *not* be a test file" % (filename,))
-
-
-class WithoutModuleTests(unittest.TestCase):
- """
- Test the C{without-module} flag.
- """
-
- def setUp(self):
- """
- Create a L{trial.Options} object to be used in the tests, and save
- C{sys.modules}.
- """
- self.config = trial.Options()
- self.savedModules = dict(sys.modules)
-
-
- def tearDown(self):
- """
- Restore C{sys.modules}.
- """
- for module in ('imaplib', 'smtplib'):
- if module in self.savedModules:
- sys.modules[module] = self.savedModules[module]
- else:
- sys.modules.pop(module, None)
-
-
- def _checkSMTP(self):
- """
- Try to import the C{smtplib} module, and return it.
- """
- import smtplib
- return smtplib
-
-
- def _checkIMAP(self):
- """
- Try to import the C{imaplib} module, and return it.
- """
- import imaplib
- return imaplib
-
-
- def test_disableOneModule(self):
- """
- Check that after disabling a module, it can't be imported anymore.
- """
- self.config.parseOptions(["--without-module", "smtplib"])
- self.assertRaises(ImportError, self._checkSMTP)
- # Restore sys.modules
- del sys.modules["smtplib"]
- # Then the function should succeed
- self.assertIsInstance(self._checkSMTP(), types.ModuleType)
-
-
- def test_disableMultipleModules(self):
- """
- Check that several modules can be disabled at once.
- """
- self.config.parseOptions(["--without-module", "smtplib,imaplib"])
- self.assertRaises(ImportError, self._checkSMTP)
- self.assertRaises(ImportError, self._checkIMAP)
- # Restore sys.modules
- del sys.modules["smtplib"]
- del sys.modules["imaplib"]
- # Then the functions should succeed
- self.assertIsInstance(self._checkSMTP(), types.ModuleType)
- self.assertIsInstance(self._checkIMAP(), types.ModuleType)
-
-
- def test_disableAlreadyImportedModule(self):
- """
- Disabling an already imported module should produce a warning.
- """
- self.assertIsInstance(self._checkSMTP(), types.ModuleType)
- self.assertWarns(RuntimeWarning,
- "Module 'smtplib' already imported, disabling anyway.",
- trial.__file__,
- self.config.parseOptions, ["--without-module", "smtplib"])
- self.assertRaises(ImportError, self._checkSMTP)
-
-
-
-class CoverageTests(unittest.TestCase):
- """
- Tests for the I{coverage} option.
- """
- if getattr(sys, 'gettrace', None) is None:
- skip = (
- "Cannot test trace hook installation without inspection API.")
-
- def setUp(self):
- """
- Arrange for the current trace hook to be restored when the
- test is complete.
- """
- self.addCleanup(sys.settrace, sys.gettrace())
-
-
- def test_tracerInstalled(self):
- """
- L{trial.Options} handles C{"--coverage"} by installing a trace
- hook to record coverage information.
- """
- options = trial.Options()
- options.parseOptions(["--coverage"])
- self.assertEqual(sys.gettrace(), options.tracer.globaltrace)
-
-
- def test_coverdirDefault(self):
- """
- L{trial.Options.coverdir} returns a L{FilePath} based on the default
- for the I{temp-directory} option if that option is not specified.
- """
- options = trial.Options()
- self.assertEqual(
- options.coverdir(),
- FilePath(".").descendant([options["temp-directory"], "coverage"]))
-
-
- def test_coverdirOverridden(self):
- """
- If a value is specified for the I{temp-directory} option,
- L{trial.Options.coverdir} returns a child of that path.
- """
- path = self.mktemp()
- options = trial.Options()
- options.parseOptions(["--temp-directory", path])
- self.assertEqual(
- options.coverdir(), FilePath(path).child("coverage"))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_test_visitor.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_test_visitor.py
deleted file mode 100755
index b5c3484e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_test_visitor.py
+++ /dev/null
@@ -1,82 +0,0 @@
-from twisted.trial import unittest
-from twisted.trial.runner import TestSuite, suiteVisit
-
-pyunit = __import__('unittest')
-
-
-
-class MockVisitor(object):
- def __init__(self):
- self.calls = []
-
-
- def __call__(self, testCase):
- self.calls.append(testCase)
-
-
-
-class TestTestVisitor(unittest.TestCase):
- def setUp(self):
- self.visitor = MockVisitor()
-
-
- def test_visitCase(self):
- """
- Test that C{visit} works for a single test case.
- """
- testCase = TestTestVisitor('test_visitCase')
- testCase.visit(self.visitor)
- self.assertEqual(self.visitor.calls, [testCase])
-
-
- def test_visitSuite(self):
- """
- Test that C{visit} hits all tests in a suite.
- """
- tests = [TestTestVisitor('test_visitCase'),
- TestTestVisitor('test_visitSuite')]
- testSuite = TestSuite(tests)
- testSuite.visit(self.visitor)
- self.assertEqual(self.visitor.calls, tests)
-
-
- def test_visitEmptySuite(self):
- """
- Test that C{visit} on an empty suite hits nothing.
- """
- TestSuite().visit(self.visitor)
- self.assertEqual(self.visitor.calls, [])
-
-
- def test_visitNestedSuite(self):
- """
- Test that C{visit} recurses through suites.
- """
- tests = [TestTestVisitor('test_visitCase'),
- TestTestVisitor('test_visitSuite')]
- testSuite = TestSuite([TestSuite([test]) for test in tests])
- testSuite.visit(self.visitor)
- self.assertEqual(self.visitor.calls, tests)
-
-
- def test_visitPyunitSuite(self):
- """
- Test that C{suiteVisit} visits stdlib unittest suites
- """
- test = TestTestVisitor('test_visitPyunitSuite')
- suite = pyunit.TestSuite([test])
- suiteVisit(suite, self.visitor)
- self.assertEqual(self.visitor.calls, [test])
-
-
- def test_visitPyunitCase(self):
- """
- Test that a stdlib test case in a suite gets visited.
- """
- class PyunitCase(pyunit.TestCase):
- def test_foo(self):
- pass
- test = PyunitCase('test_foo')
- TestSuite([test]).visit(self.visitor)
- self.assertEqual(
- [call.id() for call in self.visitor.calls], [test.id()])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_testcase.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_testcase.py
deleted file mode 100755
index 4b24f3a1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_testcase.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Direct unit tests for L{twisted.trial.unittest.SynchronousTestCase} and
-L{twisted.trial.unittest.TestCase}.
-"""
-
-from twisted.trial.unittest import SynchronousTestCase, TestCase
-
-
-class TestCaseMixin(object):
- """
- L{TestCase} tests.
- """
- def setUp(self):
- """
- Create a couple instances of C{MyTestCase}, each for the same test
- method, to be used in the test methods of this class.
- """
- self.first = self.MyTestCase('test_1')
- self.second = self.MyTestCase('test_1')
-
-
- def test_equality(self):
- """
- In order for one test method to be runnable twice, two TestCase
- instances with the same test method name must not compare as equal.
- """
- self.assertTrue(self.first == self.first)
- self.assertTrue(self.first != self.second)
- self.assertFalse(self.first == self.second)
-
-
- def test_hashability(self):
- """
- In order for one test method to be runnable twice, two TestCase
- instances with the same test method name should not have the same
- hash value.
- """
- container = {}
- container[self.first] = None
- container[self.second] = None
- self.assertEqual(len(container), 2)
-
-
-
-class SynchronousTestCaseTests(TestCaseMixin, SynchronousTestCase):
- class MyTestCase(SynchronousTestCase):
- """
- Some test methods which can be used to test behaviors of
- L{SynchronousTestCase}.
- """
- def test_1(self):
- pass
-
-
-
-# Yes, subclass SynchronousTestCase again. There are no interesting behaviors
-# of self being tested below, only of self.MyTestCase.
-class AsynchronousTestCaseTests(TestCaseMixin, SynchronousTestCase):
- class MyTestCase(TestCase):
- """
- Some test methods which can be used to test behaviors of
- L{TestCase}.
- """
- def test_1(self):
- pass
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_tests.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_tests.py
deleted file mode 100755
index 8192544d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_tests.py
+++ /dev/null
@@ -1,1379 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the behaviour of unit tests.
-
-Many tests in this module follow a simple pattern. A mixin is defined which
-includes test methods for a certain feature. The mixin is inherited from twice,
-once by a class also inheriting from SynchronousTestCase and once from a class
-inheriting from TestCase. These two subclasses are named like
-I{SynchronousFooTests} and I{AsynchronousFooTests}, where I{Foo} is related to
-the name of the mixin.
-
-This pattern allows the same tests to be applied to the two base test case
-classes trial provides, ensuring their behavior is the same.
-
-Most new tests should be added in this pattern. Tests for functionality which
-is intentionally only provided by TestCase, not SynchronousTestCase, is excepted
-of course.
-"""
-
-import gc, StringIO, sys, weakref
-
-from twisted.internet import defer, reactor
-from twisted.trial import unittest, runner, reporter, util
-from twisted.trial.test import erroneous, suppression
-from twisted.trial.test.test_reporter import LoggingReporter
-
-
-class ResultsTestMixin(object):
- """
- Provide useful APIs for test cases that are about test cases.
- """
- def loadSuite(self, suite):
- """
- Load tests from the given test case class and create a new reporter to
- use for running it.
- """
- self.loader = runner.TestLoader()
- self.suite = self.loader.loadClass(suite)
- self.reporter = reporter.TestResult()
-
-
- def test_setUp(self):
- self.failUnless(self.reporter.wasSuccessful())
- self.assertEqual(self.reporter.errors, [])
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(self.reporter.skips, [])
-
-
- def assertCount(self, numTests):
- self.assertEqual(self.suite.countTestCases(), numTests)
- self.suite(self.reporter)
- self.assertEqual(self.reporter.testsRun, numTests)
-
-
-
-class SuccessMixin(object):
- """
- Tests for the reporting of successful tests.
- """
- def setUp(self):
- self.result = reporter.TestResult()
-
-
- def test_successful(self):
- """
- A successful test, used by other tests.
- """
-
-
- def assertSuccessful(self, test, result):
- self.assertEqual(result.successes, 1)
- self.assertEqual(result.failures, [])
- self.assertEqual(result.errors, [])
- self.assertEqual(result.expectedFailures, [])
- self.assertEqual(result.unexpectedSuccesses, [])
- self.assertEqual(result.skips, [])
-
-
- def test_successfulIsReported(self):
- """
- Test that when a successful test is run, it is reported as a success,
- and not as any other kind of result.
- """
- test = self.__class__('test_successful')
- test.run(self.result)
- self.assertSuccessful(test, self.result)
-
-
- def test_defaultIsSuccessful(self):
- """
- The test case type can be instantiated with no arguments, run, and
- reported as being successful.
- """
- test = self.__class__()
- test.run(self.result)
- self.assertSuccessful(test, self.result)
-
-
- def test_noReference(self):
- """
- Test that no reference is kept on a successful test.
- """
- test = self.__class__('test_successful')
- ref = weakref.ref(test)
- test.run(self.result)
- self.assertSuccessful(test, self.result)
- del test
- gc.collect()
- self.assertIdentical(ref(), None)
-
-
-
-class SynchronousSuccessTests(SuccessMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
-
-
-
-class AsynchronousSuccessTests(SuccessMixin, unittest.TestCase):
- """
- See module docstring.
- """
-
-
-
-class SkipMethodsMixin(ResultsTestMixin):
- """
- Tests for the reporting of skipping tests.
- """
- def setUp(self):
- self.loadSuite(self.Skipping)
-
-
- def test_counting(self):
- self.assertCount(3)
-
-
- def test_results(self):
- """
- Running a suite in which all methods are individually set to skip
- produces a successful result with no recorded errors or failures, all
- the skipped methods recorded as skips, and no methods recorded as
- successes.
- """
- self.suite(self.reporter)
- self.assertTrue(self.reporter.wasSuccessful())
- self.assertEqual(self.reporter.errors, [])
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(len(self.reporter.skips), 3)
- self.assertEqual(self.reporter.successes, 0)
-
-
- def test_setUp(self):
- """
- Running a suite in which all methods are skipped by C{setUp} raising
- L{SkipTest} produces a successful result with no recorded errors or
- failures, all skipped methods recorded as skips, and no methods recorded
- as successes.
- """
- self.loadSuite(self.SkippingSetUp)
- self.suite(self.reporter)
- self.assertTrue(self.reporter.wasSuccessful())
- self.assertEqual(self.reporter.errors, [])
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(len(self.reporter.skips), 2)
- self.assertEqual(self.reporter.successes, 0)
-
-
- def test_reasons(self):
- self.suite(self.reporter)
- prefix = 'test_'
- # whiteboxing reporter
- for test, reason in self.reporter.skips:
- self.assertEqual(test.shortDescription()[len(prefix):],
- str(reason))
-
-
- def test_deprecatedSkipWithoutReason(self):
- """
- If a test method raises L{SkipTest} with no reason, a deprecation
- warning is emitted.
- """
- self.loadSuite(self.DeprecatedReasonlessSkip)
- self.suite(self.reporter)
- warnings = self.flushWarnings([
- self.DeprecatedReasonlessSkip.test_1])
- self.assertEqual(1, len(warnings))
- self.assertEqual(DeprecationWarning, warnings[0]['category'])
- self.assertEqual(
- "Do not raise unittest.SkipTest with no arguments! Give a reason "
- "for skipping tests!",
- warnings[0]['message'])
-
-
-
-class SynchronousSkipMethodTests(SkipMethodsMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- SynchronousSkipping as Skipping,
- SynchronousSkippingSetUp as SkippingSetUp,
- SynchronousDeprecatedReasonlessSkip as DeprecatedReasonlessSkip)
-
-
-
-class AsynchronousSkipMethodTests(SkipMethodsMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- AsynchronousSkipping as Skipping,
- AsynchronousSkippingSetUp as SkippingSetUp,
- AsynchronousDeprecatedReasonlessSkip as DeprecatedReasonlessSkip)
-
-
-
-
-class SkipClassesMixin(ResultsTestMixin):
- """
- Test the class skipping features of L{twisted.trial.unittest.TestCase}.
- """
- def setUp(self):
- self.loadSuite(self.SkippedClass)
- self.SkippedClass._setUpRan = False
-
-
- def test_counting(self):
- """
- Skipped test methods still contribute to the total test count.
- """
- self.assertCount(4)
-
-
- def test_setUpRan(self):
- """
- The C{setUp} method is not called if the class is set to skip.
- """
- self.suite(self.reporter)
- self.assertFalse(self.SkippedClass._setUpRan)
-
-
- def test_results(self):
- """
- Skipped test methods don't cause C{wasSuccessful} to return C{False},
- nor do they contribute to the C{errors} or C{failures} of the reporter,
- or to the count of successes. They do, however, add elements to the
- reporter's C{skips} list.
- """
- self.suite(self.reporter)
- self.assertTrue(self.reporter.wasSuccessful())
- self.assertEqual(self.reporter.errors, [])
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(len(self.reporter.skips), 4)
- self.assertEqual(self.reporter.successes, 0)
-
-
- def test_reasons(self):
- """
- Test methods which raise L{unittest.SkipTest} or have their C{skip}
- attribute set to something are skipped.
- """
- self.suite(self.reporter)
- expectedReasons = ['class', 'skip2', 'class', 'class']
- # whitebox reporter
- reasonsGiven = [reason for test, reason in self.reporter.skips]
- self.assertEqual(expectedReasons, reasonsGiven)
-
-
-
-class SynchronousSkipClassTests(SkipClassesMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- SynchronousSkippedClass as SkippedClass)
-
-
-
-class AsynchronousSkipClassTests(SkipClassesMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- AsynchronousSkippedClass as SkippedClass)
-
-
-
-class TodoMixin(ResultsTestMixin):
- """
- Tests for the individual test method I{expected failure} features of
- L{twisted.trial.unittest.TestCase}.
- """
- def setUp(self):
- self.loadSuite(self.Todo)
-
-
- def test_counting(self):
- self.assertCount(3)
-
-
- def test_results(self):
- """
- Running a suite in which all methods are individually marked as expected
- to fail produces a successful result with no recorded errors, failures,
- or skips, all methods which fail and were expected to fail recorded as
- C{expectedFailures}, and all methods which pass but which were expected
- to fail recorded as C{unexpectedSuccesses}. Additionally, no tests are
- recorded as successes.
- """
- self.suite(self.reporter)
- self.assertTrue(self.reporter.wasSuccessful())
- self.assertEqual(self.reporter.errors, [])
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(self.reporter.skips, [])
- self.assertEqual(len(self.reporter.expectedFailures), 2)
- self.assertEqual(len(self.reporter.unexpectedSuccesses), 1)
- self.assertEqual(self.reporter.successes, 0)
-
-
- def test_expectedFailures(self):
- self.suite(self.reporter)
- expectedReasons = ['todo1', 'todo2']
- reasonsGiven = [ r.reason
- for t, e, r in self.reporter.expectedFailures ]
- self.assertEqual(expectedReasons, reasonsGiven)
-
-
- def test_unexpectedSuccesses(self):
- self.suite(self.reporter)
- expectedReasons = ['todo3']
- reasonsGiven = [ r.reason
- for t, r in self.reporter.unexpectedSuccesses ]
- self.assertEqual(expectedReasons, reasonsGiven)
-
-
- def test_expectedSetUpFailure(self):
- """
- C{setUp} is excluded from the failure expectation defined by a C{todo}
- attribute on a test method.
- """
- self.loadSuite(self.SetUpTodo)
- self.suite(self.reporter)
- self.assertFalse(self.reporter.wasSuccessful())
- self.assertEqual(len(self.reporter.errors), 1)
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(self.reporter.skips, [])
- self.assertEqual(len(self.reporter.expectedFailures), 0)
- self.assertEqual(len(self.reporter.unexpectedSuccesses), 0)
- self.assertEqual(self.reporter.successes, 0)
-
-
- def test_expectedTearDownFailure(self):
- """
- C{tearDown} is excluded from the failure expectation defined by a C{todo}
- attribute on a test method.
- """
- self.loadSuite(self.TearDownTodo)
- self.suite(self.reporter)
- self.assertFalse(self.reporter.wasSuccessful())
- self.assertEqual(len(self.reporter.errors), 1)
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(self.reporter.skips, [])
- self.assertEqual(len(self.reporter.expectedFailures), 0)
- # This seems strange, since tearDown raised an exception. However, the
- # test method did complete without error. The tearDown error is
- # reflected in the errors list, checked above.
- self.assertEqual(len(self.reporter.unexpectedSuccesses), 1)
- self.assertEqual(self.reporter.successes, 0)
-
-
-
-class SynchronousTodoTests(TodoMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- SynchronousTodo as Todo,
- SynchronousSetUpTodo as SetUpTodo,
- SynchronousTearDownTodo as TearDownTodo)
-
-
-
-class AsynchronousTodoTests(TodoMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- AsynchronousTodo as Todo,
- AsynchronousSetUpTodo as SetUpTodo,
- AsynchronousTearDownTodo as TearDownTodo)
-
-
-
-class ClassTodoMixin(ResultsTestMixin):
- """
- Tests for the class-wide I{expected failure} features of
- L{twisted.trial.unittest.TestCase}.
- """
- def setUp(self):
- self.loadSuite(self.TodoClass)
-
- def test_counting(self):
- self.assertCount(4)
-
-
- def test_results(self):
- """
- Running a suite in which an entire class is marked as expected to fail
- produces a successful result with no recorded errors, failures, or
- skips, all methods which fail and were expected to fail recorded as
- C{expectedFailures}, and all methods which pass but which were expected
- to fail recorded as C{unexpectedSuccesses}. Additionally, no tests are
- recorded as successes.
- """
- self.suite(self.reporter)
- self.assertTrue(self.reporter.wasSuccessful())
- self.assertEqual(self.reporter.errors, [])
- self.assertEqual(self.reporter.failures, [])
- self.assertEqual(self.reporter.skips, [])
- self.assertEqual(len(self.reporter.expectedFailures), 2)
- self.assertEqual(len(self.reporter.unexpectedSuccesses), 2)
- self.assertEqual(self.reporter.successes, 0)
-
-
- def test_expectedFailures(self):
- self.suite(self.reporter)
- expectedReasons = ['method', 'class']
- reasonsGiven = [ r.reason
- for t, e, r in self.reporter.expectedFailures ]
- self.assertEqual(expectedReasons, reasonsGiven)
-
- def test_unexpectedSuccesses(self):
- self.suite(self.reporter)
- expectedReasons = ['method', 'class']
- reasonsGiven = [ r.reason
- for t, r in self.reporter.unexpectedSuccesses ]
- self.assertEqual(expectedReasons, reasonsGiven)
-
-
-
-class SynchronousClassTodoTests(ClassTodoMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- SynchronousTodoClass as TodoClass)
-
-
-
-class AsynchronousClassTodoTests(ClassTodoMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- AsynchronousTodoClass as TodoClass)
-
-
-
-class StrictTodoMixin(ResultsTestMixin):
- """
- Tests for the I{expected failure} features of
- L{twisted.trial.unittest.TestCase} in which the exact failure which is
- expected is indicated.
- """
- def setUp(self):
- self.loadSuite(self.StrictTodo)
-
- def test_counting(self):
- self.assertCount(7)
-
-
- def test_results(self):
- """
- A test method which is marked as expected to fail with a particular
- exception is only counted as an expected failure if it does fail with
- that exception, not if it fails with some other exception.
- """
- self.suite(self.reporter)
- self.assertFalse(self.reporter.wasSuccessful())
- self.assertEqual(len(self.reporter.errors), 2)
- self.assertEqual(len(self.reporter.failures), 1)
- self.assertEqual(len(self.reporter.expectedFailures), 3)
- self.assertEqual(len(self.reporter.unexpectedSuccesses), 1)
- self.assertEqual(self.reporter.successes, 0)
- self.assertEqual(self.reporter.skips, [])
-
-
- def test_expectedFailures(self):
- self.suite(self.reporter)
- expectedReasons = ['todo1', 'todo2', 'todo5']
- reasonsGotten = [ r.reason
- for t, e, r in self.reporter.expectedFailures ]
- self.assertEqual(expectedReasons, reasonsGotten)
-
-
- def test_unexpectedSuccesses(self):
- self.suite(self.reporter)
- expectedReasons = [([RuntimeError], 'todo7')]
- reasonsGotten = [ (r.errors, r.reason)
- for t, r in self.reporter.unexpectedSuccesses ]
- self.assertEqual(expectedReasons, reasonsGotten)
-
-
-
-class SynchronousStrictTodoTests(StrictTodoMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- SynchronousStrictTodo as StrictTodo)
-
-
-
-class AsynchronousStrictTodoTests(StrictTodoMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import (
- AsynchronousStrictTodo as StrictTodo)
-
-
-
-class TestReactorCleanup(unittest.TestCase):
- """
- Tests for cleanup and reporting of reactor event sources left behind by test
- methods.
- """
-
- def setUp(self):
- self.result = reporter.Reporter(StringIO.StringIO())
- self.loader = runner.TestLoader()
-
-
- def testLeftoverSockets(self):
- """
- Trial reports a L{util.DirtyReactorAggregateError} if a test leaves
- sockets behind.
- """
- suite = self.loader.loadMethod(
- erroneous.SocketOpenTest.test_socketsLeftOpen)
- suite.run(self.result)
- self.failIf(self.result.wasSuccessful())
- # socket cleanup happens at end of class's tests.
- # all the tests in the class are successful, even if the suite
- # fails
- self.assertEqual(self.result.successes, 1)
- failure = self.result.errors[0][1]
- self.failUnless(failure.check(util.DirtyReactorAggregateError))
-
-
- def testLeftoverPendingCalls(self):
- """
- Trial reports a L{util.DirtyReactorAggregateError} and fails the test
- if a test leaves a L{DelayedCall} hanging.
- """
- suite = erroneous.ReactorCleanupTests('test_leftoverPendingCalls')
- suite.run(self.result)
- self.failIf(self.result.wasSuccessful())
- failure = self.result.errors[0][1]
- self.assertEqual(self.result.successes, 0)
- self.failUnless(failure.check(util.DirtyReactorAggregateError))
-
-
-
-class FixtureMixin(object):
- """
- Tests for broken fixture helper methods (e.g. setUp, tearDown).
- """
-
- def setUp(self):
- self.reporter = reporter.Reporter()
- self.loader = runner.TestLoader()
-
-
- def test_brokenSetUp(self):
- """
- When setUp fails, the error is recorded in the result object.
- """
- suite = self.loader.loadClass(self.TestFailureInSetUp)
- suite.run(self.reporter)
- self.assertTrue(len(self.reporter.errors) > 0)
- self.assertIsInstance(
- self.reporter.errors[0][1].value, erroneous.FoolishError)
- self.assertEqual(0, self.reporter.successes)
-
-
- def test_brokenTearDown(self):
- """
- When tearDown fails, the error is recorded in the result object.
- """
- suite = self.loader.loadClass(self.TestFailureInTearDown)
- suite.run(self.reporter)
- errors = self.reporter.errors
- self.assertTrue(len(errors) > 0)
- self.assertIsInstance(errors[0][1].value, erroneous.FoolishError)
- self.assertEqual(0, self.reporter.successes)
-
-
-
-class SynchronousFixtureTest(FixtureMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.erroneous import (
- SynchronousTestFailureInSetUp as TestFailureInSetUp,
- SynchronousTestFailureInTearDown as TestFailureInTearDown)
-
-
-
-class AsynchronousFixtureTest(FixtureMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.erroneous import (
- AsynchronousTestFailureInSetUp as TestFailureInSetUp,
- AsynchronousTestFailureInTearDown as TestFailureInTearDown)
-
-
-
-class SuppressionMixin(object):
- """
- Tests for the warning suppression features of
- L{twisted.trial.unittest.SynchronousTestCase}.
- """
- def runTests(self, suite):
- suite.run(reporter.TestResult())
-
-
- def setUp(self):
- self.loader = runner.TestLoader()
-
-
- def _assertWarnings(self, warnings, which):
- """
- Assert that a certain number of warnings with certain messages were
- emitted in a certain order.
-
- @param warnings: A list of emitted warnings, as returned by
- C{flushWarnings}.
-
- @param which: A list of strings giving warning messages that should
- appear in C{warnings}.
-
- @raise self.failureException: If the warning messages given by C{which}
- do not match the messages in the warning information in C{warnings},
- or if they do not appear in the same order.
- """
- self.assertEqual(
- [warning['message'] for warning in warnings],
- which)
-
-
- def test_setUpSuppression(self):
- """
- Suppressions defined by the test method being run are applied to any
- warnings emitted while running the C{setUp} fixture.
- """
- self.runTests(
- self.loader.loadMethod(
- self.TestSetUpSuppression.testSuppressMethod))
- warningsShown = self.flushWarnings([
- self.TestSetUpSuppression._emit])
- self._assertWarnings(
- warningsShown,
- [suppression.CLASS_WARNING_MSG, suppression.MODULE_WARNING_MSG,
- suppression.CLASS_WARNING_MSG, suppression.MODULE_WARNING_MSG])
-
-
- def test_tearDownSuppression(self):
- """
- Suppressions defined by the test method being run are applied to any
- warnings emitted while running the C{tearDown} fixture.
- """
- self.runTests(
- self.loader.loadMethod(
- self.TestTearDownSuppression.testSuppressMethod))
- warningsShown = self.flushWarnings([
- self.TestTearDownSuppression._emit])
- self._assertWarnings(
- warningsShown,
- [suppression.CLASS_WARNING_MSG, suppression.MODULE_WARNING_MSG,
- suppression.CLASS_WARNING_MSG, suppression.MODULE_WARNING_MSG])
-
-
- def test_suppressMethod(self):
- """
- A suppression set on a test method prevents warnings emitted by that
- test method which the suppression matches from being emitted.
- """
- self.runTests(self.loader.loadMethod(
- self.TestSuppression.testSuppressMethod))
- warningsShown = self.flushWarnings([
- self.TestSuppression._emit])
- self._assertWarnings(
- warningsShown,
- [suppression.CLASS_WARNING_MSG, suppression.MODULE_WARNING_MSG])
-
-
- def test_suppressClass(self):
- """
- A suppression set on a L{SynchronousTestCase} subclass prevents warnings
- emitted by any test methods defined on that class which match the
- suppression from being emitted.
- """
- self.runTests(self.loader.loadMethod(
- self.TestSuppression.testSuppressClass))
- warningsShown = self.flushWarnings([
- self.TestSuppression._emit])
- self.assertEqual(
- warningsShown[0]['message'], suppression.METHOD_WARNING_MSG)
- self.assertEqual(
- warningsShown[1]['message'], suppression.MODULE_WARNING_MSG)
- self.assertEqual(len(warningsShown), 2)
-
-
- def test_suppressModule(self):
- """
- A suppression set on a module prevents warnings emitted by any test
- mewthods defined in that module which match the suppression from being
- emitted.
- """
- self.runTests(self.loader.loadMethod(
- self.TestSuppression2.testSuppressModule))
- warningsShown = self.flushWarnings([
- self.TestSuppression._emit])
- self.assertEqual(
- warningsShown[0]['message'], suppression.METHOD_WARNING_MSG)
- self.assertEqual(
- warningsShown[1]['message'], suppression.CLASS_WARNING_MSG)
- self.assertEqual(len(warningsShown), 2)
-
-
- def test_overrideSuppressClass(self):
- """
- The suppression set on a test method completely overrides a suppression
- with wider scope; if it does not match a warning emitted by that test
- method, the warning is emitted, even if a wider suppression matches.
- """
- case = self.loader.loadMethod(
- self.TestSuppression.testOverrideSuppressClass)
- self.runTests(case)
- warningsShown = self.flushWarnings([
- self.TestSuppression._emit])
- self.assertEqual(
- warningsShown[0]['message'], suppression.METHOD_WARNING_MSG)
- self.assertEqual(
- warningsShown[1]['message'], suppression.CLASS_WARNING_MSG)
- self.assertEqual(
- warningsShown[2]['message'], suppression.MODULE_WARNING_MSG)
- self.assertEqual(len(warningsShown), 3)
-
-
-
-class SynchronousSuppressionTest(SuppressionMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.suppression import (
- SynchronousTestSetUpSuppression as TestSetUpSuppression,
- SynchronousTestTearDownSuppression as TestTearDownSuppression,
- SynchronousTestSuppression as TestSuppression,
- SynchronousTestSuppression2 as TestSuppression2)
-
-
-
-class AsynchronousSuppressionTest(SuppressionMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.suppression import (
- AsynchronousTestSetUpSuppression as TestSetUpSuppression,
- AsynchronousTestTearDownSuppression as TestTearDownSuppression,
- AsynchronousTestSuppression as TestSuppression,
- AsynchronousTestSuppression2 as TestSuppression2)
-
-
-
-class GCMixin:
- """
- I provide a few mock tests that log setUp, tearDown, test execution and
- garbage collection. I'm used to test whether gc.collect gets called.
- """
-
- class BasicTest(unittest.TestCase):
- def setUp(self):
- self._log('setUp')
- def test_foo(self):
- self._log('test')
- def tearDown(self):
- self._log('tearDown')
-
- class ClassTest(unittest.TestCase):
- def test_1(self):
- self._log('test1')
- def test_2(self):
- self._log('test2')
-
- def _log(self, msg):
- self._collectCalled.append(msg)
-
- def collect(self):
- """Fake gc.collect"""
- self._log('collect')
-
- def setUp(self):
- self._collectCalled = []
- self.BasicTest._log = self.ClassTest._log = self._log
- self._oldCollect = gc.collect
- gc.collect = self.collect
-
- def tearDown(self):
- gc.collect = self._oldCollect
-
-
-
-class TestGarbageCollectionDefault(GCMixin, unittest.SynchronousTestCase):
-
- def test_collectNotDefault(self):
- """
- By default, tests should not force garbage collection.
- """
- test = self.BasicTest('test_foo')
- result = reporter.TestResult()
- test.run(result)
- self.assertEqual(self._collectCalled, ['setUp', 'test', 'tearDown'])
-
-
-
-class TestGarbageCollection(GCMixin, unittest.SynchronousTestCase):
-
- def test_collectCalled(self):
- """
- test gc.collect is called before and after each test.
- """
- test = TestGarbageCollection.BasicTest('test_foo')
- test = unittest._ForceGarbageCollectionDecorator(test)
- result = reporter.TestResult()
- test.run(result)
- self.assertEqual(
- self._collectCalled,
- ['collect', 'setUp', 'test', 'tearDown', 'collect'])
-
-
-
-class TestUnhandledDeferred(unittest.TestCase):
-
- def setUp(self):
- from twisted.trial.test import weird
- # test_unhandledDeferred creates a cycle. we need explicit control of gc
- gc.disable()
- self.test1 = unittest._ForceGarbageCollectionDecorator(
- weird.TestBleeding('test_unhandledDeferred'))
-
- def test_isReported(self):
- """
- Forcing garbage collection should cause unhandled Deferreds to be
- reported as errors.
- """
- result = reporter.TestResult()
- self.test1(result)
- self.assertEqual(len(result.errors), 1,
- 'Unhandled deferred passed without notice')
-
- def test_doesntBleed(self):
- """
- Forcing garbage collection in the test should mean that there are
- no unreachable cycles immediately after the test completes.
- """
- result = reporter.TestResult()
- self.test1(result)
- self.flushLoggedErrors() # test1 logs errors that get caught be us.
- # test1 created unreachable cycle.
- # it & all others should have been collected by now.
- n = gc.collect()
- self.assertEqual(n, 0, 'unreachable cycle still existed')
- # check that last gc.collect didn't log more errors
- x = self.flushLoggedErrors()
- self.assertEqual(len(x), 0, 'Errors logged after gc.collect')
-
- def tearDown(self):
- gc.collect()
- gc.enable()
- self.flushLoggedErrors()
-
-
-
-class AddCleanupMixin(object):
- """
- Test the addCleanup method of TestCase.
- """
- def setUp(self):
- super(AddCleanupMixin, self).setUp()
- self.result = reporter.TestResult()
- self.test = self.AddCleanup()
-
-
- def test_addCleanupCalledIfSetUpFails(self):
- """
- Callables added with C{addCleanup} are run even if setUp fails.
- """
- self.test.setUp = self.test.brokenSetUp
- self.test.addCleanup(self.test.append, 'foo')
- self.test.run(self.result)
- self.assertEqual(['setUp', 'foo'], self.test.log)
-
-
- def test_addCleanupCalledIfSetUpSkips(self):
- """
- Callables added with C{addCleanup} are run even if setUp raises
- L{SkipTest}. This allows test authors to reliably provide clean up
- code using C{addCleanup}.
- """
- self.test.setUp = self.test.skippingSetUp
- self.test.addCleanup(self.test.append, 'foo')
- self.test.run(self.result)
- self.assertEqual(['setUp', 'foo'], self.test.log)
-
-
- def test_addCleanupCalledInReverseOrder(self):
- """
- Callables added with C{addCleanup} should be called before C{tearDown}
- in reverse order of addition.
- """
- self.test.addCleanup(self.test.append, "foo")
- self.test.addCleanup(self.test.append, 'bar')
- self.test.run(self.result)
- self.assertEqual(['setUp', 'runTest', 'bar', 'foo', 'tearDown'],
- self.test.log)
-
-
- def test_errorInCleanupIsCaptured(self):
- """
- Errors raised in cleanup functions should be treated like errors in
- C{tearDown}. They should be added as errors and fail the test. Skips,
- todos and failures are all treated as errors.
- """
- self.test.addCleanup(self.test.fail, 'foo')
- self.test.run(self.result)
- self.failIf(self.result.wasSuccessful())
- self.assertEqual(1, len(self.result.errors))
- [(test, error)] = self.result.errors
- self.assertEqual(test, self.test)
- self.assertEqual(error.getErrorMessage(), 'foo')
-
-
- def test_cleanupsContinueRunningAfterError(self):
- """
- If a cleanup raises an error then that does not stop the other
- cleanups from being run.
- """
- self.test.addCleanup(self.test.append, 'foo')
- self.test.addCleanup(self.test.fail, 'bar')
- self.test.run(self.result)
- self.assertEqual(['setUp', 'runTest', 'foo', 'tearDown'],
- self.test.log)
- self.assertEqual(1, len(self.result.errors))
- [(test, error)] = self.result.errors
- self.assertEqual(test, self.test)
- self.assertEqual(error.getErrorMessage(), 'bar')
-
-
- def test_multipleErrorsReported(self):
- """
- If more than one cleanup fails, then the test should fail with more
- than one error.
- """
- self.test.addCleanup(self.test.fail, 'foo')
- self.test.addCleanup(self.test.fail, 'bar')
- self.test.run(self.result)
- self.assertEqual(['setUp', 'runTest', 'tearDown'],
- self.test.log)
- self.assertEqual(2, len(self.result.errors))
- [(test1, error1), (test2, error2)] = self.result.errors
- self.assertEqual(test1, self.test)
- self.assertEqual(test2, self.test)
- self.assertEqual(error1.getErrorMessage(), 'bar')
- self.assertEqual(error2.getErrorMessage(), 'foo')
-
-
-
-class SynchronousAddCleanupTests(AddCleanupMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import SynchronousAddCleanup as AddCleanup
-
-
-
-class AsynchronousAddCleanupTests(AddCleanupMixin, unittest.TestCase):
- """
- See module docstring.
- """
- from twisted.trial.test.skipping import AsynchronousAddCleanup as AddCleanup
-
- def test_addCleanupWaitsForDeferreds(self):
- """
- If an added callable returns a L{Deferred}, then the test should wait
- until that L{Deferred} has fired before running the next cleanup
- method.
- """
- def cleanup(message):
- d = defer.Deferred()
- reactor.callLater(0, d.callback, message)
- return d.addCallback(self.test.append)
- self.test.addCleanup(self.test.append, 'foo')
- self.test.addCleanup(cleanup, 'bar')
- self.test.run(self.result)
- self.assertEqual(['setUp', 'runTest', 'bar', 'foo', 'tearDown'],
- self.test.log)
-
-
-
-class SuiteClearingMixin(object):
- """
- Tests for our extension that allows us to clear out a L{TestSuite}.
- """
- def test_clearSuite(self):
- """
- Calling L{unittest._clearSuite} on a populated L{TestSuite} removes
- all tests.
- """
- suite = unittest.TestSuite()
- suite.addTest(self.TestCase())
- # Double check that the test suite actually has something in it.
- self.assertEqual(1, suite.countTestCases())
- unittest._clearSuite(suite)
- self.assertEqual(0, suite.countTestCases())
-
-
- def test_clearPyunitSuite(self):
- """
- Calling L{unittest._clearSuite} on a populated standard library
- L{TestSuite} removes all tests.
-
- This test is important since C{_clearSuite} operates by mutating
- internal variables.
- """
- pyunit = __import__('unittest')
- suite = pyunit.TestSuite()
- suite.addTest(self.TestCase())
- # Double check that the test suite actually has something in it.
- self.assertEqual(1, suite.countTestCases())
- unittest._clearSuite(suite)
- self.assertEqual(0, suite.countTestCases())
-
-
-
-class SynchronousSuiteClearingTests(SuiteClearingMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- TestCase = unittest.SynchronousTestCase
-
-
-
-class AsynchronousSuiteClearingTests(SuiteClearingMixin, unittest.TestCase):
- """
- See module docstring.
- """
- TestCase = unittest.TestCase
-
-
-
-class TestDecoratorMixin(object):
- """
- Tests for our test decoration features.
- """
- def assertTestsEqual(self, observed, expected):
- """
- Assert that the given decorated tests are equal.
- """
- self.assertEqual(observed.__class__, expected.__class__,
- "Different class")
- observedOriginal = getattr(observed, '_originalTest', None)
- expectedOriginal = getattr(expected, '_originalTest', None)
- self.assertIdentical(observedOriginal, expectedOriginal)
- if observedOriginal is expectedOriginal is None:
- self.assertIdentical(observed, expected)
-
-
- def assertSuitesEqual(self, observed, expected):
- """
- Assert that the given test suites with decorated tests are equal.
- """
- self.assertEqual(observed.__class__, expected.__class__,
- "Different class")
- self.assertEqual(len(observed._tests), len(expected._tests),
- "Different number of tests.")
- for observedTest, expectedTest in zip(observed._tests,
- expected._tests):
- if getattr(observedTest, '_tests', None) is not None:
- self.assertSuitesEqual(observedTest, expectedTest)
- else:
- self.assertTestsEqual(observedTest, expectedTest)
-
-
- def test_usesAdaptedReporterWithRun(self):
- """
- For decorated tests, C{run} uses a result adapter that preserves the
- test decoration for calls to C{addError}, C{startTest} and the like.
-
- See L{reporter._AdaptedReporter}.
- """
- test = self.TestCase()
- decoratedTest = unittest.TestDecorator(test)
- result = LoggingReporter()
- decoratedTest.run(result)
- self.assertTestsEqual(result.test, decoratedTest)
-
-
- def test_usesAdaptedReporterWithCall(self):
- """
- For decorated tests, C{__call__} uses a result adapter that preserves
- the test decoration for calls to C{addError}, C{startTest} and the
- like.
-
- See L{reporter._AdaptedReporter}.
- """
- test = self.TestCase()
- decoratedTest = unittest.TestDecorator(test)
- result = LoggingReporter()
- decoratedTest(result)
- self.assertTestsEqual(result.test, decoratedTest)
-
-
- def test_decorateSingleTest(self):
- """
- Calling L{decorate} on a single test case returns the test case
- decorated with the provided decorator.
- """
- test = self.TestCase()
- decoratedTest = unittest.decorate(test, unittest.TestDecorator)
- self.assertTestsEqual(unittest.TestDecorator(test), decoratedTest)
-
-
- def test_decorateTestSuite(self):
- """
- Calling L{decorate} on a test suite will return a test suite with
- each test decorated with the provided decorator.
- """
- test = self.TestCase()
- suite = unittest.TestSuite([test])
- decoratedTest = unittest.decorate(suite, unittest.TestDecorator)
- self.assertSuitesEqual(
- decoratedTest, unittest.TestSuite([unittest.TestDecorator(test)]))
-
-
- def test_decorateInPlaceMutatesOriginal(self):
- """
- Calling L{decorate} on a test suite will mutate the original suite.
- """
- test = self.TestCase()
- suite = unittest.TestSuite([test])
- decoratedTest = unittest.decorate(
- suite, unittest.TestDecorator)
- self.assertSuitesEqual(
- decoratedTest, unittest.TestSuite([unittest.TestDecorator(test)]))
- self.assertSuitesEqual(
- suite, unittest.TestSuite([unittest.TestDecorator(test)]))
-
-
- def test_decorateTestSuiteReferences(self):
- """
- When decorating a test suite in-place, the number of references to the
- test objects in that test suite should stay the same.
-
- Previously, L{unittest.decorate} recreated a test suite, so the
- original suite kept references to the test objects. This test is here
- to ensure the problem doesn't reappear again.
- """
- getrefcount = getattr(sys, 'getrefcount', None)
- if getrefcount is None:
- raise unittest.SkipTest(
- "getrefcount not supported on this platform")
- test = self.TestCase()
- suite = unittest.TestSuite([test])
- count1 = getrefcount(test)
- decoratedTest = unittest.decorate(suite, unittest.TestDecorator)
- count2 = getrefcount(test)
- self.assertEqual(count1, count2)
-
-
- def test_decorateNestedTestSuite(self):
- """
- Calling L{decorate} on a test suite with nested suites will return a
- test suite that maintains the same structure, but with all tests
- decorated.
- """
- test = self.TestCase()
- suite = unittest.TestSuite([unittest.TestSuite([test])])
- decoratedTest = unittest.decorate(suite, unittest.TestDecorator)
- expected = unittest.TestSuite(
- [unittest.TestSuite([unittest.TestDecorator(test)])])
- self.assertSuitesEqual(decoratedTest, expected)
-
-
- def test_decorateDecoratedSuite(self):
- """
- Calling L{decorate} on a test suite with already-decorated tests
- decorates all of the tests in the suite again.
- """
- test = self.TestCase()
- decoratedTest = unittest.decorate(test, unittest.TestDecorator)
- redecoratedTest = unittest.decorate(decoratedTest,
- unittest.TestDecorator)
- self.assertTestsEqual(redecoratedTest,
- unittest.TestDecorator(decoratedTest))
-
-
- def test_decoratePreservesSuite(self):
- """
- Tests can be in non-standard suites. L{decorate} preserves the
- non-standard suites when it decorates the tests.
- """
- test = self.TestCase()
- suite = runner.DestructiveTestSuite([test])
- decorated = unittest.decorate(suite, unittest.TestDecorator)
- self.assertSuitesEqual(
- decorated,
- runner.DestructiveTestSuite([unittest.TestDecorator(test)]))
-
-
-
-class SynchronousTestDecoratorTests(TestDecoratorMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- TestCase = unittest.SynchronousTestCase
-
-
-
-class AsynchronousTestDecoratorTests(TestDecoratorMixin, unittest.TestCase):
- """
- See module docstring.
- """
- TestCase = unittest.TestCase
-
-
-
-class MonkeyPatchMixin(object):
- """
- Tests for the patch() helper method in L{unittest.TestCase}.
- """
- def setUp(self):
- self.originalValue = 'original'
- self.patchedValue = 'patched'
- self.objectToPatch = self.originalValue
- self.test = self.TestCase()
-
-
- def test_patch(self):
- """
- Calling C{patch()} on a test monkey patches the specified object and
- attribute.
- """
- self.test.patch(self, 'objectToPatch', self.patchedValue)
- self.assertEqual(self.objectToPatch, self.patchedValue)
-
-
- def test_patchRestoredAfterRun(self):
- """
- Any monkey patches introduced by a test using C{patch()} are reverted
- after the test has run.
- """
- self.test.patch(self, 'objectToPatch', self.patchedValue)
- self.test.run(reporter.Reporter())
- self.assertEqual(self.objectToPatch, self.originalValue)
-
-
- def test_revertDuringTest(self):
- """
- C{patch()} return a L{monkey.MonkeyPatcher} object that can be used to
- restore the original values before the end of the test.
- """
- patch = self.test.patch(self, 'objectToPatch', self.patchedValue)
- patch.restore()
- self.assertEqual(self.objectToPatch, self.originalValue)
-
-
- def test_revertAndRepatch(self):
- """
- The returned L{monkey.MonkeyPatcher} object can re-apply the patch
- during the test run.
- """
- patch = self.test.patch(self, 'objectToPatch', self.patchedValue)
- patch.restore()
- patch.patch()
- self.assertEqual(self.objectToPatch, self.patchedValue)
-
-
- def test_successivePatches(self):
- """
- Successive patches are applied and reverted just like a single patch.
- """
- self.test.patch(self, 'objectToPatch', self.patchedValue)
- self.assertEqual(self.objectToPatch, self.patchedValue)
- self.test.patch(self, 'objectToPatch', 'second value')
- self.assertEqual(self.objectToPatch, 'second value')
- self.test.run(reporter.Reporter())
- self.assertEqual(self.objectToPatch, self.originalValue)
-
-
-
-class SynchronousMonkeyPatchTests(MonkeyPatchMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- TestCase = unittest.SynchronousTestCase
-
-
-
-class AsynchronousMonkeyPatchTests(MonkeyPatchMixin, unittest.TestCase):
- """
- See module docstring.
- """
- TestCase = unittest.TestCase
-
-
-
-class IterateTestsMixin(object):
- """
- L{_iterateTests} returns a list of all test cases in a test suite or test
- case.
- """
- def test_iterateTestCase(self):
- """
- L{_iterateTests} on a single test case returns a list containing that
- test case.
- """
- test = self.TestCase()
- self.assertEqual([test], list(unittest._iterateTests(test)))
-
-
- def test_iterateSingletonTestSuite(self):
- """
- L{_iterateTests} on a test suite that contains a single test case
- returns a list containing that test case.
- """
- test = self.TestCase()
- suite = runner.TestSuite([test])
- self.assertEqual([test], list(unittest._iterateTests(suite)))
-
-
- def test_iterateNestedTestSuite(self):
- """
- L{_iterateTests} returns tests that are in nested test suites.
- """
- test = self.TestCase()
- suite = runner.TestSuite([runner.TestSuite([test])])
- self.assertEqual([test], list(unittest._iterateTests(suite)))
-
-
- def test_iterateIsLeftToRightDepthFirst(self):
- """
- L{_iterateTests} returns tests in left-to-right, depth-first order.
- """
- test = self.TestCase()
- suite = runner.TestSuite([runner.TestSuite([test]), self])
- self.assertEqual([test, self], list(unittest._iterateTests(suite)))
-
-
-
-class SynchronousIterateTestsTests(IterateTestsMixin, unittest.SynchronousTestCase):
- """
- See module docstring.
- """
- TestCase = unittest.SynchronousTestCase
-
-
-
-class AsynchronousIterateTestsTests(IterateTestsMixin, unittest.TestCase):
- """
- See module docstring.
- """
- TestCase = unittest.TestCase
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_util.py
deleted file mode 100755
index 9421c812..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_util.py
+++ /dev/null
@@ -1,584 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-
-"""
-Tests for L{twisted.trial.util}
-"""
-
-import os
-
-from zope.interface import implements
-
-from twisted.internet.interfaces import IProcessTransport
-from twisted.internet import defer
-from twisted.internet.base import DelayedCall
-
-from twisted.trial.unittest import SynchronousTestCase, TestCase
-from twisted.trial import util
-from twisted.trial.util import DirtyReactorAggregateError, _Janitor
-from twisted.trial.test import packages, suppression
-
-
-
-class TestMktemp(SynchronousTestCase):
- """
- Tests for L{TestCase.mktemp}, a helper function for creating temporary file
- or directory names.
- """
- def test_name(self):
- """
- The path name returned by C{mktemp} is directly beneath a directory
- which identifies the test method which created the name.
- """
- name = self.mktemp()
- dirs = os.path.dirname(name).split(os.sep)[:-1]
- self.assertEqual(
- dirs, ['twisted.trial.test.test_util', 'TestMktemp', 'test_name'])
-
-
- def test_unique(self):
- """
- Repeated calls to C{mktemp} return different values.
- """
- name = self.mktemp()
- self.assertNotEqual(name, self.mktemp())
-
-
- def test_created(self):
- """
- The directory part of the path name returned by C{mktemp} exists.
- """
- name = self.mktemp()
- dirname = os.path.dirname(name)
- self.assertTrue(os.path.exists(dirname))
- self.assertFalse(os.path.exists(name))
-
-
- def test_location(self):
- """
- The path returned by C{mktemp} is beneath the current working directory.
- """
- path = os.path.abspath(self.mktemp())
- self.assertTrue(path.startswith(os.getcwd()))
-
-
-
-class TestIntrospection(SynchronousTestCase):
- def test_containers(self):
- """
- When pased a test case, L{util.getPythonContainers} returns a list
- including the test case and the module the test case is defined in.
- """
- parents = util.getPythonContainers(
- suppression.SynchronousTestSuppression2.testSuppressModule)
- expected = [suppression.SynchronousTestSuppression2, suppression]
- for a, b in zip(parents, expected):
- self.assertEqual(a, b)
-
-
-
-class TestFindObject(packages.SysPathManglingTest):
- """
- Tests for L{twisted.trial.util.findObject}
- """
-
- def test_deprecation(self):
- """
- Calling L{findObject} results in a deprecation warning
- """
- util.findObject('')
- warningsShown = self.flushWarnings()
- self.assertEqual(len(warningsShown), 1)
- self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
- self.assertEqual(warningsShown[0]['message'],
- "twisted.trial.util.findObject was deprecated "
- "in Twisted 10.1.0: Please use "
- "twisted.python.reflect.namedAny instead.")
-
-
- def test_importPackage(self):
- package1 = util.findObject('package')
- import package as package2
- self.assertEqual(package1, (True, package2))
-
- def test_importModule(self):
- test_sample2 = util.findObject('goodpackage.test_sample')
- from goodpackage import test_sample
- self.assertEqual((True, test_sample), test_sample2)
-
- def test_importError(self):
- self.failUnlessRaises(ZeroDivisionError,
- util.findObject, 'package.test_bad_module')
-
- def test_sophisticatedImportError(self):
- self.failUnlessRaises(ImportError,
- util.findObject, 'package2.test_module')
-
- def test_importNonexistentPackage(self):
- self.assertEqual(util.findObject('doesntexist')[0], False)
-
- def test_findNonexistentModule(self):
- self.assertEqual(util.findObject('package.doesntexist')[0], False)
-
- def test_findNonexistentObject(self):
- self.assertEqual(util.findObject(
- 'goodpackage.test_sample.doesnt')[0], False)
- self.assertEqual(util.findObject(
- 'goodpackage.test_sample.AlphabetTest.doesntexist')[0], False)
-
- def test_findObjectExist(self):
- alpha1 = util.findObject('goodpackage.test_sample.AlphabetTest')
- from goodpackage import test_sample
- self.assertEqual(alpha1, (True, test_sample.AlphabetTest))
-
-
-
-class TestRunSequentially(TestCase):
- """
- Sometimes it is useful to be able to run an arbitrary list of callables,
- one after the other.
-
- When some of those callables can return Deferreds, things become complex.
- """
-
- def test_emptyList(self):
- """
- When asked to run an empty list of callables, runSequentially returns a
- successful Deferred that fires an empty list.
- """
- d = util._runSequentially([])
- d.addCallback(self.assertEqual, [])
- return d
-
-
- def test_singleSynchronousSuccess(self):
- """
- When given a callable that succeeds without returning a Deferred,
- include the return value in the results list, tagged with a SUCCESS
- flag.
- """
- d = util._runSequentially([lambda: None])
- d.addCallback(self.assertEqual, [(defer.SUCCESS, None)])
- return d
-
-
- def test_singleSynchronousFailure(self):
- """
- When given a callable that raises an exception, include a Failure for
- that exception in the results list, tagged with a FAILURE flag.
- """
- d = util._runSequentially([lambda: self.fail('foo')])
- def check(results):
- [(flag, fail)] = results
- fail.trap(self.failureException)
- self.assertEqual(fail.getErrorMessage(), 'foo')
- self.assertEqual(flag, defer.FAILURE)
- return d.addCallback(check)
-
-
- def test_singleAsynchronousSuccess(self):
- """
- When given a callable that returns a successful Deferred, include the
- result of the Deferred in the results list, tagged with a SUCCESS flag.
- """
- d = util._runSequentially([lambda: defer.succeed(None)])
- d.addCallback(self.assertEqual, [(defer.SUCCESS, None)])
- return d
-
-
- def test_singleAsynchronousFailure(self):
- """
- When given a callable that returns a failing Deferred, include the
- failure the results list, tagged with a FAILURE flag.
- """
- d = util._runSequentially([lambda: defer.fail(ValueError('foo'))])
- def check(results):
- [(flag, fail)] = results
- fail.trap(ValueError)
- self.assertEqual(fail.getErrorMessage(), 'foo')
- self.assertEqual(flag, defer.FAILURE)
- return d.addCallback(check)
-
-
- def test_callablesCalledInOrder(self):
- """
- Check that the callables are called in the given order, one after the
- other.
- """
- log = []
- deferreds = []
-
- def append(value):
- d = defer.Deferred()
- log.append(value)
- deferreds.append(d)
- return d
-
- d = util._runSequentially([lambda: append('foo'),
- lambda: append('bar')])
-
- # runSequentially should wait until the Deferred has fired before
- # running the second callable.
- self.assertEqual(log, ['foo'])
- deferreds[-1].callback(None)
- self.assertEqual(log, ['foo', 'bar'])
-
- # Because returning created Deferreds makes jml happy.
- deferreds[-1].callback(None)
- return d
-
-
- def test_continuesAfterError(self):
- """
- If one of the callables raises an error, then runSequentially continues
- to run the remaining callables.
- """
- d = util._runSequentially([lambda: self.fail('foo'), lambda: 'bar'])
- def check(results):
- [(flag1, fail), (flag2, result)] = results
- fail.trap(self.failureException)
- self.assertEqual(flag1, defer.FAILURE)
- self.assertEqual(fail.getErrorMessage(), 'foo')
- self.assertEqual(flag2, defer.SUCCESS)
- self.assertEqual(result, 'bar')
- return d.addCallback(check)
-
-
- def test_stopOnFirstError(self):
- """
- If the C{stopOnFirstError} option is passed to C{runSequentially}, then
- no further callables are called after the first exception is raised.
- """
- d = util._runSequentially([lambda: self.fail('foo'), lambda: 'bar'],
- stopOnFirstError=True)
- def check(results):
- [(flag1, fail)] = results
- fail.trap(self.failureException)
- self.assertEqual(flag1, defer.FAILURE)
- self.assertEqual(fail.getErrorMessage(), 'foo')
- return d.addCallback(check)
-
-
- def test_stripFlags(self):
- """
- If the C{stripFlags} option is passed to C{runSequentially} then the
- SUCCESS / FAILURE flags are stripped from the output. Instead, the
- Deferred fires a flat list of results containing only the results and
- failures.
- """
- d = util._runSequentially([lambda: self.fail('foo'), lambda: 'bar'],
- stripFlags=True)
- def check(results):
- [fail, result] = results
- fail.trap(self.failureException)
- self.assertEqual(fail.getErrorMessage(), 'foo')
- self.assertEqual(result, 'bar')
- return d.addCallback(check)
- test_stripFlags.todo = "YAGNI"
-
-
-
-class DirtyReactorAggregateErrorTest(SynchronousTestCase):
- """
- Tests for the L{DirtyReactorAggregateError}.
- """
-
- def test_formatDelayedCall(self):
- """
- Delayed calls are formatted nicely.
- """
- error = DirtyReactorAggregateError(["Foo", "bar"])
- self.assertEqual(str(error),
- """\
-Reactor was unclean.
-DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
-Foo
-bar""")
-
-
- def test_formatSelectables(self):
- """
- Selectables are formatted nicely.
- """
- error = DirtyReactorAggregateError([], ["selectable 1", "selectable 2"])
- self.assertEqual(str(error),
- """\
-Reactor was unclean.
-Selectables:
-selectable 1
-selectable 2""")
-
-
- def test_formatDelayedCallsAndSelectables(self):
- """
- Both delayed calls and selectables can appear in the same error.
- """
- error = DirtyReactorAggregateError(["bleck", "Boozo"],
- ["Sel1", "Sel2"])
- self.assertEqual(str(error),
- """\
-Reactor was unclean.
-DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
-bleck
-Boozo
-Selectables:
-Sel1
-Sel2""")
-
-
-
-class StubReactor(object):
- """
- A reactor stub which contains enough functionality to be used with the
- L{_Janitor}.
-
- @ivar iterations: A list of the arguments passed to L{iterate}.
- @ivar removeAllCalled: Number of times that L{removeAll} was called.
- @ivar selectables: The value that will be returned from L{removeAll}.
- @ivar delayedCalls: The value to return from L{getDelayedCalls}.
- """
-
- def __init__(self, delayedCalls, selectables=None):
- """
- @param delayedCalls: See L{StubReactor.delayedCalls}.
- @param selectables: See L{StubReactor.selectables}.
- """
- self.delayedCalls = delayedCalls
- self.iterations = []
- self.removeAllCalled = 0
- if not selectables:
- selectables = []
- self.selectables = selectables
-
-
- def iterate(self, timeout=None):
- """
- Increment C{self.iterations}.
- """
- self.iterations.append(timeout)
-
-
- def getDelayedCalls(self):
- """
- Return C{self.delayedCalls}.
- """
- return self.delayedCalls
-
-
- def removeAll(self):
- """
- Increment C{self.removeAllCalled} and return C{self.selectables}.
- """
- self.removeAllCalled += 1
- return self.selectables
-
-
-
-class StubErrorReporter(object):
- """
- A subset of L{twisted.trial.itrial.IReporter} which records L{addError}
- calls.
-
- @ivar errors: List of two-tuples of (test, error) which were passed to
- L{addError}.
- """
-
- def __init__(self):
- self.errors = []
-
-
- def addError(self, test, error):
- """
- Record parameters in C{self.errors}.
- """
- self.errors.append((test, error))
-
-
-
-class JanitorTests(SynchronousTestCase):
- """
- Tests for L{_Janitor}!
- """
-
- def test_cleanPendingSpinsReactor(self):
- """
- During pending-call cleanup, the reactor will be spun twice with an
- instant timeout. This is not a requirement, it is only a test for
- current behavior. Hopefully Trial will eventually not do this kind of
- reactor stuff.
- """
- reactor = StubReactor([])
- jan = _Janitor(None, None, reactor=reactor)
- jan._cleanPending()
- self.assertEqual(reactor.iterations, [0, 0])
-
-
- def test_cleanPendingCancelsCalls(self):
- """
- During pending-call cleanup, the janitor cancels pending timed calls.
- """
- def func():
- return "Lulz"
- cancelled = []
- delayedCall = DelayedCall(300, func, (), {},
- cancelled.append, lambda x: None)
- reactor = StubReactor([delayedCall])
- jan = _Janitor(None, None, reactor=reactor)
- jan._cleanPending()
- self.assertEqual(cancelled, [delayedCall])
-
-
- def test_cleanPendingReturnsDelayedCallStrings(self):
- """
- The Janitor produces string representations of delayed calls from the
- delayed call cleanup method. It gets the string representations
- *before* cancelling the calls; this is important because cancelling the
- call removes critical debugging information from the string
- representation.
- """
- delayedCall = DelayedCall(300, lambda: None, (), {},
- lambda x: None, lambda x: None,
- seconds=lambda: 0)
- delayedCallString = str(delayedCall)
- reactor = StubReactor([delayedCall])
- jan = _Janitor(None, None, reactor=reactor)
- strings = jan._cleanPending()
- self.assertEqual(strings, [delayedCallString])
-
-
- def test_cleanReactorRemovesSelectables(self):
- """
- The Janitor will remove selectables during reactor cleanup.
- """
- reactor = StubReactor([])
- jan = _Janitor(None, None, reactor=reactor)
- jan._cleanReactor()
- self.assertEqual(reactor.removeAllCalled, 1)
-
-
- def test_cleanReactorKillsProcesses(self):
- """
- The Janitor will kill processes during reactor cleanup.
- """
- class StubProcessTransport(object):
- """
- A stub L{IProcessTransport} provider which records signals.
- @ivar signals: The signals passed to L{signalProcess}.
- """
- implements(IProcessTransport)
-
- def __init__(self):
- self.signals = []
-
- def signalProcess(self, signal):
- """
- Append C{signal} to C{self.signals}.
- """
- self.signals.append(signal)
-
- pt = StubProcessTransport()
- reactor = StubReactor([], [pt])
- jan = _Janitor(None, None, reactor=reactor)
- jan._cleanReactor()
- self.assertEqual(pt.signals, ["KILL"])
-
-
- def test_cleanReactorReturnsSelectableStrings(self):
- """
- The Janitor returns string representations of the selectables that it
- cleaned up from the reactor cleanup method.
- """
- class Selectable(object):
- """
- A stub Selectable which only has an interesting string
- representation.
- """
- def __repr__(self):
- return "(SELECTABLE!)"
-
- reactor = StubReactor([], [Selectable()])
- jan = _Janitor(None, None, reactor=reactor)
- self.assertEqual(jan._cleanReactor(), ["(SELECTABLE!)"])
-
-
- def test_postCaseCleanupNoErrors(self):
- """
- The post-case cleanup method will return True and not call C{addError}
- on the result if there are no pending calls.
- """
- reactor = StubReactor([])
- test = object()
- reporter = StubErrorReporter()
- jan = _Janitor(test, reporter, reactor=reactor)
- self.assertTrue(jan.postCaseCleanup())
- self.assertEqual(reporter.errors, [])
-
-
- def test_postCaseCleanupWithErrors(self):
- """
- The post-case cleanup method will return False and call C{addError} on
- the result with a L{DirtyReactorAggregateError} Failure if there are
- pending calls.
- """
- delayedCall = DelayedCall(300, lambda: None, (), {},
- lambda x: None, lambda x: None,
- seconds=lambda: 0)
- delayedCallString = str(delayedCall)
- reactor = StubReactor([delayedCall], [])
- test = object()
- reporter = StubErrorReporter()
- jan = _Janitor(test, reporter, reactor=reactor)
- self.assertFalse(jan.postCaseCleanup())
- self.assertEqual(len(reporter.errors), 1)
- self.assertEqual(reporter.errors[0][1].value.delayedCalls,
- [delayedCallString])
-
-
- def test_postClassCleanupNoErrors(self):
- """
- The post-class cleanup method will not call C{addError} on the result
- if there are no pending calls or selectables.
- """
- reactor = StubReactor([])
- test = object()
- reporter = StubErrorReporter()
- jan = _Janitor(test, reporter, reactor=reactor)
- jan.postClassCleanup()
- self.assertEqual(reporter.errors, [])
-
-
- def test_postClassCleanupWithPendingCallErrors(self):
- """
- The post-class cleanup method call C{addError} on the result with a
- L{DirtyReactorAggregateError} Failure if there are pending calls.
- """
- delayedCall = DelayedCall(300, lambda: None, (), {},
- lambda x: None, lambda x: None,
- seconds=lambda: 0)
- delayedCallString = str(delayedCall)
- reactor = StubReactor([delayedCall], [])
- test = object()
- reporter = StubErrorReporter()
- jan = _Janitor(test, reporter, reactor=reactor)
- jan.postClassCleanup()
- self.assertEqual(len(reporter.errors), 1)
- self.assertEqual(reporter.errors[0][1].value.delayedCalls,
- [delayedCallString])
-
-
- def test_postClassCleanupWithSelectableErrors(self):
- """
- The post-class cleanup method call C{addError} on the result with a
- L{DirtyReactorAggregateError} Failure if there are selectables.
- """
- selectable = "SELECTABLE HERE"
- reactor = StubReactor([], [selectable])
- test = object()
- reporter = StubErrorReporter()
- jan = _Janitor(test, reporter, reactor=reactor)
- jan.postClassCleanup()
- self.assertEqual(len(reporter.errors), 1)
- self.assertEqual(reporter.errors[0][1].value.selectables,
- [repr(selectable)])
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_warning.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_warning.py
deleted file mode 100755
index 9ad16528..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/test_warning.py
+++ /dev/null
@@ -1,472 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for Trial's interaction with the Python warning system.
-"""
-
-import sys, warnings
-from StringIO import StringIO
-
-from twisted.python.filepath import FilePath
-from twisted.trial.unittest import (
- SynchronousTestCase, _collectWarnings, _setWarningRegistryToNone)
-from twisted.trial.reporter import TestResult
-
-class Mask(object):
- """
- Hide a test case definition from trial's automatic discovery mechanism.
- """
- class MockTests(SynchronousTestCase):
- """
- A test case which is used by L{FlushWarningsTests} to verify behavior
- which cannot be verified by code inside a single test method.
- """
- message = "some warning text"
- category = UserWarning
-
- def test_unflushed(self):
- """
- Generate a warning and don't flush it.
- """
- warnings.warn(self.message, self.category)
-
-
- def test_flushed(self):
- """
- Generate a warning and flush it.
- """
- warnings.warn(self.message, self.category)
- self.assertEqual(len(self.flushWarnings()), 1)
-
-
-
-class FlushWarningsTests(SynchronousTestCase):
- """
- Tests for C{flushWarnings}, an API for examining the warnings
- emitted so far in a test.
- """
-
- def assertDictSubset(self, set, subset):
- """
- Assert that all the keys present in C{subset} are also present in
- C{set} and that the corresponding values are equal.
- """
- for k, v in subset.iteritems():
- self.assertEqual(set[k], v)
-
-
- def assertDictSubsets(self, sets, subsets):
- """
- For each pair of corresponding elements in C{sets} and C{subsets},
- assert that the element from C{subsets} is a subset of the element from
- C{sets}.
- """
- self.assertEqual(len(sets), len(subsets))
- for a, b in zip(sets, subsets):
- self.assertDictSubset(a, b)
-
-
- def test_none(self):
- """
- If no warnings are emitted by a test, C{flushWarnings} returns an empty
- list.
- """
- self.assertEqual(self.flushWarnings(), [])
-
-
- def test_several(self):
- """
- If several warnings are emitted by a test, C{flushWarnings} returns a
- list containing all of them.
- """
- firstMessage = "first warning message"
- firstCategory = UserWarning
- warnings.warn(message=firstMessage, category=firstCategory)
-
- secondMessage = "second warning message"
- secondCategory = RuntimeWarning
- warnings.warn(message=secondMessage, category=secondCategory)
-
- self.assertDictSubsets(
- self.flushWarnings(),
- [{'category': firstCategory, 'message': firstMessage},
- {'category': secondCategory, 'message': secondMessage}])
-
-
- def test_repeated(self):
- """
- The same warning triggered twice from the same place is included twice
- in the list returned by C{flushWarnings}.
- """
- message = "the message"
- category = RuntimeWarning
- for i in range(2):
- warnings.warn(message=message, category=category)
-
- self.assertDictSubsets(
- self.flushWarnings(),
- [{'category': category, 'message': message}] * 2)
-
-
- def test_cleared(self):
- """
- After a particular warning event has been returned by C{flushWarnings},
- it is not returned by subsequent calls.
- """
- message = "the message"
- category = RuntimeWarning
- warnings.warn(message=message, category=category)
- self.assertDictSubsets(
- self.flushWarnings(),
- [{'category': category, 'message': message}])
- self.assertEqual(self.flushWarnings(), [])
-
-
- def test_unflushed(self):
- """
- Any warnings emitted by a test which are not flushed are emitted to the
- Python warning system.
- """
- result = TestResult()
- case = Mask.MockTests('test_unflushed')
- case.run(result)
- warningsShown = self.flushWarnings([Mask.MockTests.test_unflushed])
- self.assertEqual(warningsShown[0]['message'], 'some warning text')
- self.assertIdentical(warningsShown[0]['category'], UserWarning)
-
- where = case.test_unflushed.im_func.func_code
- filename = where.co_filename
- # If someone edits MockTests.test_unflushed, the value added to
- # firstlineno might need to change.
- lineno = where.co_firstlineno + 4
-
- self.assertEqual(warningsShown[0]['filename'], filename)
- self.assertEqual(warningsShown[0]['lineno'], lineno)
-
- self.assertEqual(len(warningsShown), 1)
-
-
- def test_flushed(self):
- """
- Any warnings emitted by a test which are flushed are not emitted to the
- Python warning system.
- """
- result = TestResult()
- case = Mask.MockTests('test_flushed')
- output = StringIO()
- monkey = self.patch(sys, 'stdout', output)
- case.run(result)
- monkey.restore()
- self.assertEqual(output.getvalue(), "")
-
-
- def test_warningsConfiguredAsErrors(self):
- """
- If a warnings filter has been installed which turns warnings into
- exceptions, tests have an error added to the reporter for them for each
- unflushed warning.
- """
- class CustomWarning(Warning):
- pass
-
- result = TestResult()
- case = Mask.MockTests('test_unflushed')
- case.category = CustomWarning
-
- originalWarnings = warnings.filters[:]
- try:
- warnings.simplefilter('error')
- case.run(result)
- self.assertEqual(len(result.errors), 1)
- self.assertIdentical(result.errors[0][0], case)
- result.errors[0][1].trap(CustomWarning)
- finally:
- warnings.filters[:] = originalWarnings
-
-
- def test_flushedWarningsConfiguredAsErrors(self):
- """
- If a warnings filter has been installed which turns warnings into
- exceptions, tests which emit those warnings but flush them do not have
- an error added to the reporter.
- """
- class CustomWarning(Warning):
- pass
-
- result = TestResult()
- case = Mask.MockTests('test_flushed')
- case.category = CustomWarning
-
- originalWarnings = warnings.filters[:]
- try:
- warnings.simplefilter('error')
- case.run(result)
- self.assertEqual(result.errors, [])
- finally:
- warnings.filters[:] = originalWarnings
-
-
- def test_multipleFlushes(self):
- """
- Any warnings emitted after a call to C{flushWarnings} can be flushed by
- another call to C{flushWarnings}.
- """
- warnings.warn("first message")
- self.assertEqual(len(self.flushWarnings()), 1)
- warnings.warn("second message")
- self.assertEqual(len(self.flushWarnings()), 1)
-
-
- def test_filterOnOffendingFunction(self):
- """
- The list returned by C{flushWarnings} includes only those
- warnings which refer to the source of the function passed as the value
- for C{offendingFunction}, if a value is passed for that parameter.
- """
- firstMessage = "first warning text"
- firstCategory = UserWarning
- def one():
- warnings.warn(firstMessage, firstCategory, stacklevel=1)
-
- secondMessage = "some text"
- secondCategory = RuntimeWarning
- def two():
- warnings.warn(secondMessage, secondCategory, stacklevel=1)
-
- one()
- two()
-
- self.assertDictSubsets(
- self.flushWarnings(offendingFunctions=[one]),
- [{'category': firstCategory, 'message': firstMessage}])
- self.assertDictSubsets(
- self.flushWarnings(offendingFunctions=[two]),
- [{'category': secondCategory, 'message': secondMessage}])
-
-
- def test_functionBoundaries(self):
- """
- Verify that warnings emitted at the very edges of a function are still
- determined to be emitted from that function.
- """
- def warner():
- warnings.warn("first line warning")
- warnings.warn("internal line warning")
- warnings.warn("last line warning")
-
- warner()
- self.assertEqual(
- len(self.flushWarnings(offendingFunctions=[warner])), 3)
-
-
- def test_invalidFilter(self):
- """
- If an object which is neither a function nor a method is included in the
- C{offendingFunctions} list, C{flushWarnings} raises L{ValueError}. Such
- a call flushes no warnings.
- """
- warnings.warn("oh no")
- self.assertRaises(ValueError, self.flushWarnings, [None])
- self.assertEqual(len(self.flushWarnings()), 1)
-
-
- def test_missingSource(self):
- """
- Warnings emitted by a function the source code of which is not
- available can still be flushed.
- """
- package = FilePath(self.mktemp()).child('twisted_private_helper')
- package.makedirs()
- package.child('__init__.py').setContent('')
- package.child('missingsourcefile.py').setContent('''
-import warnings
-def foo():
- warnings.warn("oh no")
-''')
- sys.path.insert(0, package.parent().path)
- self.addCleanup(sys.path.remove, package.parent().path)
- from twisted_private_helper import missingsourcefile
- self.addCleanup(sys.modules.pop, 'twisted_private_helper')
- self.addCleanup(sys.modules.pop, missingsourcefile.__name__)
- package.child('missingsourcefile.py').remove()
-
- missingsourcefile.foo()
- self.assertEqual(len(self.flushWarnings([missingsourcefile.foo])), 1)
-
-
- def test_renamedSource(self):
- """
- Warnings emitted by a function defined in a file which has been renamed
- since it was initially compiled can still be flushed.
-
- This is testing the code which specifically supports working around the
- unfortunate behavior of CPython to write a .py source file name into
- the .pyc files it generates and then trust that it is correct in
- various places. If source files are renamed, .pyc files may not be
- regenerated, but they will contain incorrect filenames.
- """
- package = FilePath(self.mktemp()).child('twisted_private_helper')
- package.makedirs()
- package.child('__init__.py').setContent('')
- package.child('module.py').setContent('''
-import warnings
-def foo():
- warnings.warn("oh no")
-''')
- sys.path.insert(0, package.parent().path)
- self.addCleanup(sys.path.remove, package.parent().path)
-
- # Import it to cause pycs to be generated
- from twisted_private_helper import module
-
- # Clean up the state resulting from that import; we're not going to use
- # this module, so it should go away.
- del sys.modules['twisted_private_helper']
- del sys.modules[module.__name__]
-
- # Rename the source directory
- package.moveTo(package.sibling('twisted_renamed_helper'))
-
- # Import the newly renamed version
- from twisted_renamed_helper import module
- self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
- self.addCleanup(sys.modules.pop, module.__name__)
-
- # Generate the warning
- module.foo()
-
- # Flush it
- self.assertEqual(len(self.flushWarnings([module.foo])), 1)
-
-
-
-class FakeWarning(Warning):
- pass
-
-
-
-class CollectWarningsTests(SynchronousTestCase):
- """
- Tests for L{_collectWarnings}.
- """
- def test_callsObserver(self):
- """
- L{_collectWarnings} calls the observer with each emitted warning.
- """
- firstMessage = "dummy calls observer warning"
- secondMessage = firstMessage[::-1]
- events = []
- def f():
- events.append('call')
- warnings.warn(firstMessage)
- warnings.warn(secondMessage)
- events.append('returning')
-
- _collectWarnings(events.append, f)
-
- self.assertEqual(events[0], 'call')
- self.assertEqual(events[1].message, firstMessage)
- self.assertEqual(events[2].message, secondMessage)
- self.assertEqual(events[3], 'returning')
- self.assertEqual(len(events), 4)
-
-
- def test_suppresses(self):
- """
- Any warnings emitted by a call to a function passed to
- L{_collectWarnings} are not actually emitted to the warning system.
- """
- output = StringIO()
- self.patch(sys, 'stdout', output)
- _collectWarnings(lambda x: None, warnings.warn, "text")
- self.assertEqual(output.getvalue(), "")
-
-
- def test_callsFunction(self):
- """
- L{_collectWarnings} returns the result of calling the callable passed to
- it with the parameters given.
- """
- arguments = []
- value = object()
-
- def f(*args, **kwargs):
- arguments.append((args, kwargs))
- return value
-
- result = _collectWarnings(lambda x: None, f, 1, 'a', b=2, c='d')
- self.assertEqual(arguments, [((1, 'a'), {'b': 2, 'c': 'd'})])
- self.assertIdentical(result, value)
-
-
- def test_duplicateWarningCollected(self):
- """
- Subsequent emissions of a warning from a particular source site can be
- collected by L{_collectWarnings}. In particular, the per-module
- emitted-warning cache should be bypassed (I{__warningregistry__}).
- """
- # Make sure the worst case is tested: if __warningregistry__ isn't in a
- # module's globals, then the warning system will add it and start using
- # it to avoid emitting duplicate warnings. Delete __warningregistry__
- # to ensure that even modules which are first imported as a test is
- # running still interact properly with the warning system.
- global __warningregistry__
- del __warningregistry__
-
- def f():
- warnings.warn("foo")
- warnings.simplefilter('default')
- f()
- events = []
- _collectWarnings(events.append, f)
- self.assertEqual(len(events), 1)
- self.assertEqual(events[0].message, "foo")
- self.assertEqual(len(self.flushWarnings()), 1)
-
-
- def test_immutableObject(self):
- """
- L{_collectWarnings}'s behavior is not altered by the presence of an
- object which cannot have attributes set on it as a value in
- C{sys.modules}.
- """
- key = object()
- sys.modules[key] = key
- self.addCleanup(sys.modules.pop, key)
- self.test_duplicateWarningCollected()
-
-
- def test_setWarningRegistryChangeWhileIterating(self):
- """
- If the dictionary passed to L{_setWarningRegistryToNone} changes size
- partway through the process, C{_setWarningRegistryToNone} continues to
- set C{__warningregistry__} to C{None} on the rest of the values anyway.
-
-
- This might be caused by C{sys.modules} containing something that's not
- really a module and imports things on setattr. py.test does this, as
- does L{twisted.python.deprecate.deprecatedModuleAttribute}.
- """
- d = {}
-
- class A(object):
- def __init__(self, key):
- self.__dict__['_key'] = key
-
- def __setattr__(self, value, item):
- d[self._key] = None
-
- key1 = object()
- key2 = object()
- d[key1] = A(key2)
-
- key3 = object()
- key4 = object()
- d[key3] = A(key4)
-
- _setWarningRegistryToNone(d)
-
- # If both key2 and key4 were added, then both A instanced were
- # processed.
- self.assertEqual(set([key1, key2, key3, key4]), set(d.keys()))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/weird.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/weird.py
deleted file mode 100755
index 3533f56a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/test/weird.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from __future__ import division
-
-from twisted.trial import unittest
-from twisted.internet import defer
-
-# Used in test_tests.TestUnhandledDeferred
-
-class TestBleeding(unittest.TestCase):
- """This test creates an unhandled Deferred and leaves it in a cycle.
-
- The Deferred is left in a cycle so that the garbage collector won't pick it
- up immediately. We were having some problems where unhandled Deferreds in
- one test were failing random other tests. (See #1507, #1213)
- """
- def test_unhandledDeferred(self):
- try:
- 1/0
- except ZeroDivisionError:
- f = defer.fail()
- # these two lines create the cycle. don't remove them
- l = [f]
- l.append(l)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/unittest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/unittest.py
deleted file mode 100755
index 6e8427c6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/unittest.py
+++ /dev/null
@@ -1,1778 +0,0 @@
-# -*- test-case-name: twisted.trial.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Things likely to be used by writers of unit tests.
-
-Maintainer: Jonathan Lange
-"""
-
-
-import doctest, inspect
-import os, warnings, sys, tempfile, gc, types
-from pprint import pformat
-from dis import findlinestarts as _findlinestarts
-
-from twisted.internet import defer, utils
-from twisted.python import components, failure, log, monkey
-from twisted.python.deprecate import (
- getDeprecationWarningString, warnAboutFunction)
-
-from twisted.trial import itrial, reporter, util
-
-pyunit = __import__('unittest')
-
-from zope.interface import implements
-
-
-
-class SkipTest(Exception):
- """
- Raise this (with a reason) to skip the current test. You may also set
- method.skip to a reason string to skip it, or set class.skip to skip the
- entire TestCase.
- """
-
-
-class FailTest(AssertionError):
- """Raised to indicate the current test has failed to pass."""
-
-
-class Todo(object):
- """
- Internal object used to mark a L{TestCase} as 'todo'. Tests marked 'todo'
- are reported differently in Trial L{TestResult}s. If todo'd tests fail,
- they do not fail the suite and the errors are reported in a separate
- category. If todo'd tests succeed, Trial L{TestResult}s will report an
- unexpected success.
- """
-
- def __init__(self, reason, errors=None):
- """
- @param reason: A string explaining why the test is marked 'todo'
-
- @param errors: An iterable of exception types that the test is
- expected to raise. If one of these errors is raised by the test, it
- will be trapped. Raising any other kind of error will fail the test.
- If C{None} is passed, then all errors will be trapped.
- """
- self.reason = reason
- self.errors = errors
-
- def __repr__(self):
- return "<Todo reason=%r errors=%r>" % (self.reason, self.errors)
-
- def expected(self, failure):
- """
- @param failure: A L{twisted.python.failure.Failure}.
-
- @return: C{True} if C{failure} is expected, C{False} otherwise.
- """
- if self.errors is None:
- return True
- for error in self.errors:
- if failure.check(error):
- return True
- return False
-
-
-def makeTodo(value):
- """
- Return a L{Todo} object built from C{value}.
-
- If C{value} is a string, return a Todo that expects any exception with
- C{value} as a reason. If C{value} is a tuple, the second element is used
- as the reason and the first element as the excepted error(s).
-
- @param value: A string or a tuple of C{(errors, reason)}, where C{errors}
- is either a single exception class or an iterable of exception classes.
-
- @return: A L{Todo} object.
- """
- if isinstance(value, str):
- return Todo(reason=value)
- if isinstance(value, tuple):
- errors, reason = value
- try:
- errors = list(errors)
- except TypeError:
- errors = [errors]
- return Todo(reason=reason, errors=errors)
-
-
-
-class _Warning(object):
- """
- A L{_Warning} instance represents one warning emitted through the Python
- warning system (L{warnings}). This is used to insulate callers of
- L{_collectWarnings} from changes to the Python warnings system which might
- otherwise require changes to the warning objects that function passes to
- the observer object it accepts.
-
- @ivar message: The string which was passed as the message parameter to
- L{warnings.warn}.
-
- @ivar category: The L{Warning} subclass which was passed as the category
- parameter to L{warnings.warn}.
-
- @ivar filename: The name of the file containing the definition of the code
- object which was C{stacklevel} frames above the call to
- L{warnings.warn}, where C{stacklevel} is the value of the C{stacklevel}
- parameter passed to L{warnings.warn}.
-
- @ivar lineno: The source line associated with the active instruction of the
- code object object which was C{stacklevel} frames above the call to
- L{warnings.warn}, where C{stacklevel} is the value of the C{stacklevel}
- parameter passed to L{warnings.warn}.
- """
- def __init__(self, message, category, filename, lineno):
- self.message = message
- self.category = category
- self.filename = filename
- self.lineno = lineno
-
-
-def _setWarningRegistryToNone(modules):
- """
- Disable the per-module cache for every module found in C{modules}, typically
- C{sys.modules}.
-
- @param modules: Dictionary of modules, typically sys.module dict
- """
- for v in modules.values():
- if v is not None:
- try:
- v.__warningregistry__ = None
- except:
- # Don't specify a particular exception type to handle in case
- # some wacky object raises some wacky exception in response to
- # the setattr attempt.
- pass
-
-
-def _collectWarnings(observeWarning, f, *args, **kwargs):
- """
- Call C{f} with C{args} positional arguments and C{kwargs} keyword arguments
- and collect all warnings which are emitted as a result in a list.
-
- @param observeWarning: A callable which will be invoked with a L{_Warning}
- instance each time a warning is emitted.
-
- @return: The return value of C{f(*args, **kwargs)}.
- """
- def showWarning(message, category, filename, lineno, file=None, line=None):
- assert isinstance(message, Warning)
- observeWarning(_Warning(
- message.args[0], category, filename, lineno))
-
- # Disable the per-module cache for every module otherwise if the warning
- # which the caller is expecting us to collect was already emitted it won't
- # be re-emitted by the call to f which happens below.
- _setWarningRegistryToNone(sys.modules)
-
- origFilters = warnings.filters[:]
- origShow = warnings.showwarning
- warnings.simplefilter('always')
- try:
- warnings.showwarning = showWarning
- result = f(*args, **kwargs)
- finally:
- warnings.filters[:] = origFilters
- warnings.showwarning = origShow
- return result
-
-
-
-class _Assertions(pyunit.TestCase, object):
- """
- Replaces many of the built-in TestCase assertions. In general, these
- assertions provide better error messages and are easier to use in
- callbacks. Also provides new assertions such as L{failUnlessFailure}.
-
- Although the tests are defined as 'failIf*' and 'failUnless*', they can
- also be called as 'assertNot*' and 'assert*'.
- """
-
- def fail(self, msg=None):
- """
- Absolutely fail the test. Do not pass go, do not collect $200.
-
- @param msg: the message that will be displayed as the reason for the
- failure
- """
- raise self.failureException(msg)
-
- def failIf(self, condition, msg=None):
- """
- Fail the test if C{condition} evaluates to True.
-
- @param condition: any object that defines __nonzero__
- """
- if condition:
- raise self.failureException(msg)
- return condition
- assertNot = assertFalse = failUnlessFalse = failIf
-
- def failUnless(self, condition, msg=None):
- """
- Fail the test if C{condition} evaluates to False.
-
- @param condition: any object that defines __nonzero__
- """
- if not condition:
- raise self.failureException(msg)
- return condition
- assert_ = assertTrue = failUnlessTrue = failUnless
-
- def failUnlessRaises(self, exception, f, *args, **kwargs):
- """
- Fail the test unless calling the function C{f} with the given
- C{args} and C{kwargs} raises C{exception}. The failure will report
- the traceback and call stack of the unexpected exception.
-
- @param exception: exception type that is to be expected
- @param f: the function to call
-
- @return: The raised exception instance, if it is of the given type.
- @raise self.failureException: Raised if the function call does
- not raise an exception or if it raises an exception of a
- different type.
- """
- try:
- result = f(*args, **kwargs)
- except exception, inst:
- return inst
- except:
- raise self.failureException('%s raised instead of %s:\n %s'
- % (sys.exc_info()[0],
- exception.__name__,
- failure.Failure().getTraceback()))
- else:
- raise self.failureException('%s not raised (%r returned)'
- % (exception.__name__, result))
- assertRaises = failUnlessRaises
-
-
- def assertEqual(self, first, second, msg=''):
- """
- Fail the test if C{first} and C{second} are not equal.
-
- @param msg: A string describing the failure that's included in the
- exception.
- """
- if not first == second:
- if msg is None:
- msg = ''
- if len(msg) > 0:
- msg += '\n'
- raise self.failureException(
- '%snot equal:\na = %s\nb = %s\n'
- % (msg, pformat(first), pformat(second)))
- return first
- failUnlessEqual = failUnlessEquals = assertEquals = assertEqual
-
-
- def failUnlessIdentical(self, first, second, msg=None):
- """
- Fail the test if C{first} is not C{second}. This is an
- obect-identity-equality test, not an object equality
- (i.e. C{__eq__}) test.
-
- @param msg: if msg is None, then the failure message will be
- '%r is not %r' % (first, second)
- """
- if first is not second:
- raise self.failureException(msg or '%r is not %r' % (first, second))
- return first
- assertIdentical = failUnlessIdentical
-
- def failIfIdentical(self, first, second, msg=None):
- """
- Fail the test if C{first} is C{second}. This is an
- obect-identity-equality test, not an object equality
- (i.e. C{__eq__}) test.
-
- @param msg: if msg is None, then the failure message will be
- '%r is %r' % (first, second)
- """
- if first is second:
- raise self.failureException(msg or '%r is %r' % (first, second))
- return first
- assertNotIdentical = failIfIdentical
-
- def failIfEqual(self, first, second, msg=None):
- """
- Fail the test if C{first} == C{second}.
-
- @param msg: if msg is None, then the failure message will be
- '%r == %r' % (first, second)
- """
- if not first != second:
- raise self.failureException(msg or '%r == %r' % (first, second))
- return first
- assertNotEqual = assertNotEquals = failIfEquals = failIfEqual
-
- def failUnlessIn(self, containee, container, msg=None):
- """
- Fail the test if C{containee} is not found in C{container}.
-
- @param containee: the value that should be in C{container}
- @param container: a sequence type, or in the case of a mapping type,
- will follow semantics of 'if key in dict.keys()'
- @param msg: if msg is None, then the failure message will be
- '%r not in %r' % (first, second)
- """
- if containee not in container:
- raise self.failureException(msg or "%r not in %r"
- % (containee, container))
- return containee
- assertIn = failUnlessIn
-
- def failIfIn(self, containee, container, msg=None):
- """
- Fail the test if C{containee} is found in C{container}.
-
- @param containee: the value that should not be in C{container}
- @param container: a sequence type, or in the case of a mapping type,
- will follow semantics of 'if key in dict.keys()'
- @param msg: if msg is None, then the failure message will be
- '%r in %r' % (first, second)
- """
- if containee in container:
- raise self.failureException(msg or "%r in %r"
- % (containee, container))
- return containee
- assertNotIn = failIfIn
-
- def failIfAlmostEqual(self, first, second, places=7, msg=None):
- """
- Fail if the two objects are equal as determined by their
- difference rounded to the given number of decimal places
- (default 7) and comparing to zero.
-
- @note: decimal places (from zero) is usually not the same
- as significant digits (measured from the most
- signficant digit).
-
- @note: included for compatiblity with PyUnit test cases
- """
- if round(second-first, places) == 0:
- raise self.failureException(msg or '%r == %r within %r places'
- % (first, second, places))
- return first
- assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
- failIfAlmostEquals = failIfAlmostEqual
-
- def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
- """
- Fail if the two objects are unequal as determined by their
- difference rounded to the given number of decimal places
- (default 7) and comparing to zero.
-
- @note: decimal places (from zero) is usually not the same
- as significant digits (measured from the most
- signficant digit).
-
- @note: included for compatiblity with PyUnit test cases
- """
- if round(second-first, places) != 0:
- raise self.failureException(msg or '%r != %r within %r places'
- % (first, second, places))
- return first
- assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
- failUnlessAlmostEquals = failUnlessAlmostEqual
-
- def failUnlessApproximates(self, first, second, tolerance, msg=None):
- """
- Fail if C{first} - C{second} > C{tolerance}
-
- @param msg: if msg is None, then the failure message will be
- '%r ~== %r' % (first, second)
- """
- if abs(first - second) > tolerance:
- raise self.failureException(msg or "%s ~== %s" % (first, second))
- return first
- assertApproximates = failUnlessApproximates
-
- def failUnlessFailure(self, deferred, *expectedFailures):
- """
- Fail if C{deferred} does not errback with one of C{expectedFailures}.
- Returns the original Deferred with callbacks added. You will need
- to return this Deferred from your test case.
- """
- def _cb(ignore):
- raise self.failureException(
- "did not catch an error, instead got %r" % (ignore,))
-
- def _eb(failure):
- if failure.check(*expectedFailures):
- return failure.value
- else:
- output = ('\nExpected: %r\nGot:\n%s'
- % (expectedFailures, str(failure)))
- raise self.failureException(output)
- return deferred.addCallbacks(_cb, _eb)
- assertFailure = failUnlessFailure
-
- def failUnlessSubstring(self, substring, astring, msg=None):
- """
- Fail if C{substring} does not exist within C{astring}.
- """
- return self.failUnlessIn(substring, astring, msg)
- assertSubstring = failUnlessSubstring
-
- def failIfSubstring(self, substring, astring, msg=None):
- """
- Fail if C{astring} contains C{substring}.
- """
- return self.failIfIn(substring, astring, msg)
- assertNotSubstring = failIfSubstring
-
- def failUnlessWarns(self, category, message, filename, f,
- *args, **kwargs):
- """
- Fail if the given function doesn't generate the specified warning when
- called. It calls the function, checks the warning, and forwards the
- result of the function if everything is fine.
-
- @param category: the category of the warning to check.
- @param message: the output message of the warning to check.
- @param filename: the filename where the warning should come from.
- @param f: the function which is supposed to generate the warning.
- @type f: any callable.
- @param args: the arguments to C{f}.
- @param kwargs: the keywords arguments to C{f}.
-
- @return: the result of the original function C{f}.
- """
- warningsShown = []
- result = _collectWarnings(warningsShown.append, f, *args, **kwargs)
-
- if not warningsShown:
- self.fail("No warnings emitted")
- first = warningsShown[0]
- for other in warningsShown[1:]:
- if ((other.message, other.category)
- != (first.message, first.category)):
- self.fail("Can't handle different warnings")
- self.assertEqual(first.message, message)
- self.assertIdentical(first.category, category)
-
- # Use starts with because of .pyc/.pyo issues.
- self.failUnless(
- filename.startswith(first.filename),
- 'Warning in %r, expected %r' % (first.filename, filename))
-
- # It would be nice to be able to check the line number as well, but
- # different configurations actually end up reporting different line
- # numbers (generally the variation is only 1 line, but that's enough
- # to fail the test erroneously...).
- # self.assertEqual(lineno, xxx)
-
- return result
- assertWarns = failUnlessWarns
-
- def failUnlessIsInstance(self, instance, classOrTuple, message=None):
- """
- Fail if C{instance} is not an instance of the given class or of
- one of the given classes.
-
- @param instance: the object to test the type (first argument of the
- C{isinstance} call).
- @type instance: any.
- @param classOrTuple: the class or classes to test against (second
- argument of the C{isinstance} call).
- @type classOrTuple: class, type, or tuple.
-
- @param message: Custom text to include in the exception text if the
- assertion fails.
- """
- if not isinstance(instance, classOrTuple):
- if message is None:
- suffix = ""
- else:
- suffix = ": " + message
- self.fail("%r is not an instance of %s%s" % (
- instance, classOrTuple, suffix))
- assertIsInstance = failUnlessIsInstance
-
- def failIfIsInstance(self, instance, classOrTuple):
- """
- Fail if C{instance} is not an instance of the given class or of
- one of the given classes.
-
- @param instance: the object to test the type (first argument of the
- C{isinstance} call).
- @type instance: any.
- @param classOrTuple: the class or classes to test against (second
- argument of the C{isinstance} call).
- @type classOrTuple: class, type, or tuple.
- """
- if isinstance(instance, classOrTuple):
- self.fail("%r is an instance of %s" % (instance, classOrTuple))
- assertNotIsInstance = failIfIsInstance
-
-
-class _LogObserver(object):
- """
- Observes the Twisted logs and catches any errors.
-
- @ivar _errors: A C{list} of L{Failure} instances which were received as
- error events from the Twisted logging system.
-
- @ivar _added: A C{int} giving the number of times C{_add} has been called
- less the number of times C{_remove} has been called; used to only add
- this observer to the Twisted logging since once, regardless of the
- number of calls to the add method.
-
- @ivar _ignored: A C{list} of exception types which will not be recorded.
- """
-
- def __init__(self):
- self._errors = []
- self._added = 0
- self._ignored = []
-
-
- def _add(self):
- if self._added == 0:
- log.addObserver(self.gotEvent)
- self._added += 1
-
-
- def _remove(self):
- self._added -= 1
- if self._added == 0:
- log.removeObserver(self.gotEvent)
-
-
- def _ignoreErrors(self, *errorTypes):
- """
- Do not store any errors with any of the given types.
- """
- self._ignored.extend(errorTypes)
-
-
- def _clearIgnores(self):
- """
- Stop ignoring any errors we might currently be ignoring.
- """
- self._ignored = []
-
-
- def flushErrors(self, *errorTypes):
- """
- Flush errors from the list of caught errors. If no arguments are
- specified, remove all errors. If arguments are specified, only remove
- errors of those types from the stored list.
- """
- if errorTypes:
- flushed = []
- remainder = []
- for f in self._errors:
- if f.check(*errorTypes):
- flushed.append(f)
- else:
- remainder.append(f)
- self._errors = remainder
- else:
- flushed = self._errors
- self._errors = []
- return flushed
-
-
- def getErrors(self):
- """
- Return a list of errors caught by this observer.
- """
- return self._errors
-
-
- def gotEvent(self, event):
- """
- The actual observer method. Called whenever a message is logged.
-
- @param event: A dictionary containing the log message. Actual
- structure undocumented (see source for L{twisted.python.log}).
- """
- if event.get('isError', False) and 'failure' in event:
- f = event['failure']
- if len(self._ignored) == 0 or not f.check(*self._ignored):
- self._errors.append(f)
-
-
-
-_logObserver = _LogObserver()
-
-_wait_is_running = []
-
-
-class SynchronousTestCase(_Assertions):
- """
- A unit test. The atom of the unit testing universe.
-
- This class extends C{unittest.TestCase} from the standard library. A number
- of convenient testing helpers are added, including logging and warning
- integration, monkey-patching support, and more.
-
- To write a unit test, subclass C{SynchronousTestCase} and define a method
- (say, 'test_foo') on the subclass. To run the test, instantiate your
- subclass with the name of the method, and call L{run} on the instance,
- passing a L{TestResult} object.
-
- The C{trial} script will automatically find any C{SynchronousTestCase}
- subclasses defined in modules beginning with 'test_' and construct test
- cases for all methods beginning with 'test'.
-
- If an error is logged during the test run, the test will fail with an
- error. See L{log.err}.
-
- @ivar failureException: An exception class, defaulting to C{FailTest}. If
- the test method raises this exception, it will be reported as a failure,
- rather than an exception. All of the assertion methods raise this if the
- assertion fails.
-
- @ivar skip: C{None} or a string explaining why this test is to be
- skipped. If defined, the test will not be run. Instead, it will be
- reported to the result object as 'skipped' (if the C{TestResult} supports
- skipping).
-
- @ivar todo: C{None}, a string or a tuple of C{(errors, reason)} where
- C{errors} is either an exception class or an iterable of exception
- classes, and C{reason} is a string. See L{Todo} or L{makeTodo} for more
- information.
-
- @ivar suppress: C{None} or a list of tuples of C{(args, kwargs)} to be
- passed to C{warnings.filterwarnings}. Use these to suppress warnings
- raised in a test. Useful for testing deprecated code. See also
- L{util.suppress}.
- """
- failureException = FailTest
-
- def __init__(self, methodName='runTest'):
- super(SynchronousTestCase, self).__init__(methodName)
- self._passed = False
- self._cleanups = []
- self._testMethodName = methodName
- testMethod = getattr(self, methodName)
- self._parents = [testMethod, self]
- self._parents.extend(util.getPythonContainers(testMethod))
-
-
- if sys.version_info >= (2, 6):
- # Override the comparison defined by the base TestCase which considers
- # instances of the same class with the same _testMethodName to be
- # equal. Since trial puts TestCase instances into a set, that
- # definition of comparison makes it impossible to run the same test
- # method twice. Most likely, trial should stop using a set to hold
- # tests, but until it does, this is necessary on Python 2.6. Only
- # __eq__ and __ne__ are required here, not __hash__, since the
- # inherited __hash__ is compatible with these equality semantics. A
- # different __hash__ might be slightly more efficient (by reducing
- # collisions), but who cares? -exarkun
- def __eq__(self, other):
- return self is other
-
- def __ne__(self, other):
- return self is not other
-
-
- def shortDescription(self):
- desc = super(SynchronousTestCase, self).shortDescription()
- if desc is None:
- return self._testMethodName
- return desc
-
-
- def getSkip(self):
- """
- Return the skip reason set on this test, if any is set. Checks on the
- instance first, then the class, then the module, then packages. As
- soon as it finds something with a C{skip} attribute, returns that.
- Returns C{None} if it cannot find anything. See L{TestCase} docstring
- for more details.
- """
- return util.acquireAttribute(self._parents, 'skip', None)
-
-
- def getTodo(self):
- """
- Return a L{Todo} object if the test is marked todo. Checks on the
- instance first, then the class, then the module, then packages. As
- soon as it finds something with a C{todo} attribute, returns that.
- Returns C{None} if it cannot find anything. See L{TestCase} docstring
- for more details.
- """
- todo = util.acquireAttribute(self._parents, 'todo', None)
- if todo is None:
- return None
- return makeTodo(todo)
-
-
- def runTest(self):
- """
- If no C{methodName} argument is passed to the constructor, L{run} will
- treat this method as the thing with the actual test inside.
- """
-
-
- def run(self, result):
- """
- Run the test case, storing the results in C{result}.
-
- First runs C{setUp} on self, then runs the test method (defined in the
- constructor), then runs C{tearDown}. As with the standard library
- L{unittest.TestCase}, the return value of these methods is disregarded.
- In particular, returning a L{Deferred} has no special additional
- consequences.
-
- @param result: A L{TestResult} object.
- """
- log.msg("--> %s <--" % (self.id()))
- new_result = itrial.IReporter(result, None)
- if new_result is None:
- result = PyUnitResultAdapter(result)
- else:
- result = new_result
- result.startTest(self)
- if self.getSkip(): # don't run test methods that are marked as .skip
- result.addSkip(self, self.getSkip())
- result.stopTest(self)
- return
-
- self._passed = False
- self._warnings = []
-
- self._installObserver()
- # All the code inside _runFixturesAndTest will be run such that warnings
- # emitted by it will be collected and retrievable by flushWarnings.
- _collectWarnings(self._warnings.append, self._runFixturesAndTest, result)
-
- # Any collected warnings which the test method didn't flush get
- # re-emitted so they'll be logged or show up on stdout or whatever.
- for w in self.flushWarnings():
- try:
- warnings.warn_explicit(**w)
- except:
- result.addError(self, failure.Failure())
-
- result.stopTest(self)
-
-
- def addCleanup(self, f, *args, **kwargs):
- """
- Add the given function to a list of functions to be called after the
- test has run, but before C{tearDown}.
-
- Functions will be run in reverse order of being added. This helps
- ensure that tear down complements set up.
-
- As with all aspects of L{SynchronousTestCase}, Deferreds are not
- supported in cleanup functions.
- """
- self._cleanups.append((f, args, kwargs))
-
-
- def patch(self, obj, attribute, value):
- """
- Monkey patch an object for the duration of the test.
-
- The monkey patch will be reverted at the end of the test using the
- L{addCleanup} mechanism.
-
- The L{MonkeyPatcher} is returned so that users can restore and
- re-apply the monkey patch within their tests.
-
- @param obj: The object to monkey patch.
- @param attribute: The name of the attribute to change.
- @param value: The value to set the attribute to.
- @return: A L{monkey.MonkeyPatcher} object.
- """
- monkeyPatch = monkey.MonkeyPatcher((obj, attribute, value))
- monkeyPatch.patch()
- self.addCleanup(monkeyPatch.restore)
- return monkeyPatch
-
-
- def flushLoggedErrors(self, *errorTypes):
- """
- Remove stored errors received from the log.
-
- C{TestCase} stores each error logged during the run of the test and
- reports them as errors during the cleanup phase (after C{tearDown}).
-
- @param *errorTypes: If unspecifed, flush all errors. Otherwise, only
- flush errors that match the given types.
-
- @return: A list of failures that have been removed.
- """
- return self._observer.flushErrors(*errorTypes)
-
-
- def flushWarnings(self, offendingFunctions=None):
- """
- Remove stored warnings from the list of captured warnings and return
- them.
-
- @param offendingFunctions: If C{None}, all warnings issued during the
- currently running test will be flushed. Otherwise, only warnings
- which I{point} to a function included in this list will be flushed.
- All warnings include a filename and source line number; if these
- parts of a warning point to a source line which is part of a
- function, then the warning I{points} to that function.
- @type offendingFunctions: C{NoneType} or L{list} of functions or methods.
-
- @raise ValueError: If C{offendingFunctions} is not C{None} and includes
- an object which is not a L{types.FunctionType} or
- L{types.MethodType} instance.
-
- @return: A C{list}, each element of which is a C{dict} giving
- information about one warning which was flushed by this call. The
- keys of each C{dict} are:
-
- - C{'message'}: The string which was passed as the I{message}
- parameter to L{warnings.warn}.
-
- - C{'category'}: The warning subclass which was passed as the
- I{category} parameter to L{warnings.warn}.
-
- - C{'filename'}: The name of the file containing the definition
- of the code object which was C{stacklevel} frames above the
- call to L{warnings.warn}, where C{stacklevel} is the value of
- the C{stacklevel} parameter passed to L{warnings.warn}.
-
- - C{'lineno'}: The source line associated with the active
- instruction of the code object object which was C{stacklevel}
- frames above the call to L{warnings.warn}, where
- C{stacklevel} is the value of the C{stacklevel} parameter
- passed to L{warnings.warn}.
- """
- if offendingFunctions is None:
- toFlush = self._warnings[:]
- self._warnings[:] = []
- else:
- toFlush = []
- for aWarning in self._warnings:
- for aFunction in offendingFunctions:
- if not isinstance(aFunction, (
- types.FunctionType, types.MethodType)):
- raise ValueError("%r is not a function or method" % (
- aFunction,))
-
- # inspect.getabsfile(aFunction) sometimes returns a
- # filename which disagrees with the filename the warning
- # system generates. This seems to be because a
- # function's code object doesn't deal with source files
- # being renamed. inspect.getabsfile(module) seems
- # better (or at least agrees with the warning system
- # more often), and does some normalization for us which
- # is desirable. inspect.getmodule() is attractive, but
- # somewhat broken in Python < 2.6. See Python bug 4845.
- aModule = sys.modules[aFunction.__module__]
- filename = inspect.getabsfile(aModule)
-
- if filename != os.path.normcase(aWarning.filename):
- continue
- lineStarts = list(_findlinestarts(aFunction.func_code))
- first = lineStarts[0][1]
- last = lineStarts[-1][1]
- if not (first <= aWarning.lineno <= last):
- continue
- # The warning points to this function, flush it and move on
- # to the next warning.
- toFlush.append(aWarning)
- break
- # Remove everything which is being flushed.
- map(self._warnings.remove, toFlush)
-
- return [
- {'message': w.message, 'category': w.category,
- 'filename': w.filename, 'lineno': w.lineno}
- for w in toFlush]
-
-
- def callDeprecated(self, version, f, *args, **kwargs):
- """
- Call a function that should have been deprecated at a specific version
- and in favor of a specific alternative, and assert that it was thusly
- deprecated.
-
- @param version: A 2-sequence of (since, replacement), where C{since} is
- a the first L{version<twisted.python.versions.Version>} that C{f}
- should have been deprecated since, and C{replacement} is a suggested
- replacement for the deprecated functionality, as described by
- L{twisted.python.deprecate.deprecated}. If there is no suggested
- replacement, this parameter may also be simply a
- L{version<twisted.python.versions.Version>} by itself.
-
- @param f: The deprecated function to call.
-
- @param args: The arguments to pass to C{f}.
-
- @param kwargs: The keyword arguments to pass to C{f}.
-
- @return: Whatever C{f} returns.
-
- @raise: Whatever C{f} raises. If any exception is
- raised by C{f}, though, no assertions will be made about emitted
- deprecations.
-
- @raise FailTest: if no warnings were emitted by C{f}, or if the
- L{DeprecationWarning} emitted did not produce the canonical
- please-use-something-else message that is standard for Twisted
- deprecations according to the given version and replacement.
- """
- result = f(*args, **kwargs)
- warningsShown = self.flushWarnings([self.callDeprecated])
- try:
- info = list(version)
- except TypeError:
- since = version
- replacement = None
- else:
- [since, replacement] = info
-
- if len(warningsShown) == 0:
- self.fail('%r is not deprecated.' % (f,))
-
- observedWarning = warningsShown[0]['message']
- expectedWarning = getDeprecationWarningString(
- f, since, replacement=replacement)
- self.assertEqual(expectedWarning, observedWarning)
-
- return result
-
-
- def mktemp(self):
- """
- Returns a unique name that may be used as either a temporary directory
- or filename.
-
- @note: you must call os.mkdir on the value returned from this method if
- you wish to use it as a directory!
- """
- MAX_FILENAME = 32 # some platforms limit lengths of filenames
- base = os.path.join(self.__class__.__module__[:MAX_FILENAME],
- self.__class__.__name__[:MAX_FILENAME],
- self._testMethodName[:MAX_FILENAME])
- if not os.path.exists(base):
- os.makedirs(base)
- dirname = tempfile.mkdtemp('', '', base)
- return os.path.join(dirname, 'temp')
-
-
- def _getSuppress(self):
- """
- Returns any warning suppressions set for this test. Checks on the
- instance first, then the class, then the module, then packages. As
- soon as it finds something with a C{suppress} attribute, returns that.
- Returns any empty list (i.e. suppress no warnings) if it cannot find
- anything. See L{TestCase} docstring for more details.
- """
- return util.acquireAttribute(self._parents, 'suppress', [])
-
-
- def _getSkipReason(self, method, skip):
- """
- Return the reason to use for skipping a test method.
-
- @param method: The method which produced the skip.
- @param skip: A L{SkipTest} instance raised by C{method}.
- """
- if len(skip.args) > 0:
- return skip.args[0]
-
- warnAboutFunction(
- method,
- "Do not raise unittest.SkipTest with no arguments! Give a reason "
- "for skipping tests!")
- return skip
-
-
- def _run(self, suppress, todo, method, result):
- """
- Run a single method, either a test method or fixture.
-
- @param suppress: Any warnings to suppress, as defined by the C{suppress}
- attribute on this method, test case, or the module it is defined in.
-
- @param todo: Any expected failure or failures, as defined by the C{todo}
- attribute on this method, test case, or the module it is defined in.
-
- @param method: The method to run.
-
- @param result: The TestResult instance to which to report results.
-
- @return: C{True} if the method fails and no further method/fixture calls
- should be made, C{False} otherwise.
- """
- try:
- # XXX runWithWarningsSuppressed is from twisted.internet, involves
- # Deferreds, we need a synchronous-only version probably.
- utils.runWithWarningsSuppressed(suppress, method)
- except SkipTest as e:
- result.addSkip(self, self._getSkipReason(method, e))
- except:
- reason = failure.Failure()
- if todo is None or not todo.expected(reason):
- if reason.check(self.failureException):
- addResult = result.addFailure
- else:
- addResult = result.addError
- addResult(self, reason)
- else:
- result.addExpectedFailure(self, reason, todo)
- else:
- return False
- return True
-
-
- def _runFixturesAndTest(self, result):
- """
- Run C{setUp}, a test method, test cleanups, and C{tearDown}.
-
- @param result: The TestResult instance to which to report results.
- """
- suppress = self._getSuppress()
- try:
- if self._run(suppress, None, self.setUp, result):
- return
-
- todo = self.getTodo()
- method = getattr(self, self._testMethodName)
- if self._run(suppress, todo, method, result):
- return
- finally:
- self._runCleanups(result)
-
- if todo:
- result.addUnexpectedSuccess(self, todo)
-
- if self._run(suppress, None, self.tearDown, result):
- return
-
- passed = True
- for error in self._observer.getErrors():
- result.addError(self, error)
- passed = False
- self._observer.flushErrors()
- self._removeObserver()
-
- if passed and not todo:
- result.addSuccess(self)
-
-
- def _runCleanups(self, result):
- """
- Synchronously run any cleanups which have been added.
- """
- while len(self._cleanups) > 0:
- f, args, kwargs = self._cleanups.pop()
- try:
- f(*args, **kwargs)
- except:
- f = failure.Failure()
- result.addError(self, f)
-
-
- def _installObserver(self):
- self._observer = _logObserver
- self._observer._add()
-
-
- def _removeObserver(self):
- self._observer._remove()
-
-
-
-class TestCase(SynchronousTestCase):
- """
- A unit test. The atom of the unit testing universe.
-
- This class extends L{SynchronousTestCase} which extends C{unittest.TestCase}
- from the standard library. The main feature is the ability to return
- C{Deferred}s from tests and fixture methods and to have the suite wait for
- those C{Deferred}s to fire.
-
- @ivar timeout: A real number of seconds. If set, the test will
- raise an error if it takes longer than C{timeout} seconds.
- If not set, util.DEFAULT_TIMEOUT_DURATION is used.
- """
- implements(itrial.ITestCase)
-
- def __init__(self, methodName='runTest'):
- """
- Construct an asynchronous test case for C{methodName}.
-
- @param methodName: The name of a method on C{self}. This method should
- be a unit test. That is, it should be a short method that calls some of
- the assert* methods. If C{methodName} is unspecified, L{runTest} will
- be used as the test method. This is mostly useful for testing Trial.
- """
- super(TestCase, self).__init__(methodName)
-
-
- def _run(self, methodName, result):
- from twisted.internet import reactor
- timeout = self.getTimeout()
- def onTimeout(d):
- e = defer.TimeoutError("%r (%s) still running at %s secs"
- % (self, methodName, timeout))
- f = failure.Failure(e)
- # try to errback the deferred that the test returns (for no gorram
- # reason) (see issue1005 and test_errorPropagation in
- # test_deferred)
- try:
- d.errback(f)
- except defer.AlreadyCalledError:
- # if the deferred has been called already but the *back chain
- # is still unfinished, crash the reactor and report timeout
- # error ourself.
- reactor.crash()
- self._timedOut = True # see self._wait
- todo = self.getTodo()
- if todo is not None and todo.expected(f):
- result.addExpectedFailure(self, f, todo)
- else:
- result.addError(self, f)
- onTimeout = utils.suppressWarnings(
- onTimeout, util.suppress(category=DeprecationWarning))
- method = getattr(self, methodName)
- d = defer.maybeDeferred(
- utils.runWithWarningsSuppressed, self._getSuppress(), method)
- call = reactor.callLater(timeout, onTimeout, d)
- d.addBoth(lambda x : call.active() and call.cancel() or x)
- return d
-
-
- def __call__(self, *args, **kwargs):
- return self.run(*args, **kwargs)
-
-
- def deferSetUp(self, ignored, result):
- d = self._run('setUp', result)
- d.addCallbacks(self.deferTestMethod, self._ebDeferSetUp,
- callbackArgs=(result,),
- errbackArgs=(result,))
- return d
-
-
- def _ebDeferSetUp(self, failure, result):
- if failure.check(SkipTest):
- result.addSkip(self, self._getSkipReason(self.setUp, failure.value))
- else:
- result.addError(self, failure)
- if failure.check(KeyboardInterrupt):
- result.stop()
- return self.deferRunCleanups(None, result)
-
-
- def deferTestMethod(self, ignored, result):
- d = self._run(self._testMethodName, result)
- d.addCallbacks(self._cbDeferTestMethod, self._ebDeferTestMethod,
- callbackArgs=(result,),
- errbackArgs=(result,))
- d.addBoth(self.deferRunCleanups, result)
- d.addBoth(self.deferTearDown, result)
- return d
-
-
- def _cbDeferTestMethod(self, ignored, result):
- if self.getTodo() is not None:
- result.addUnexpectedSuccess(self, self.getTodo())
- else:
- self._passed = True
- return ignored
-
-
- def _ebDeferTestMethod(self, f, result):
- todo = self.getTodo()
- if todo is not None and todo.expected(f):
- result.addExpectedFailure(self, f, todo)
- elif f.check(self.failureException, FailTest):
- result.addFailure(self, f)
- elif f.check(KeyboardInterrupt):
- result.addError(self, f)
- result.stop()
- elif f.check(SkipTest):
- result.addSkip(
- self,
- self._getSkipReason(getattr(self, self._testMethodName), f.value))
- else:
- result.addError(self, f)
-
-
- def deferTearDown(self, ignored, result):
- d = self._run('tearDown', result)
- d.addErrback(self._ebDeferTearDown, result)
- return d
-
-
- def _ebDeferTearDown(self, failure, result):
- result.addError(self, failure)
- if failure.check(KeyboardInterrupt):
- result.stop()
- self._passed = False
-
-
- def deferRunCleanups(self, ignored, result):
- """
- Run any scheduled cleanups and report errors (if any to the result
- object.
- """
- d = self._runCleanups()
- d.addCallback(self._cbDeferRunCleanups, result)
- return d
-
-
- def _cbDeferRunCleanups(self, cleanupResults, result):
- for flag, failure in cleanupResults:
- if flag == defer.FAILURE:
- result.addError(self, failure)
- if failure.check(KeyboardInterrupt):
- result.stop()
- self._passed = False
-
-
- def _cleanUp(self, result):
- try:
- clean = util._Janitor(self, result).postCaseCleanup()
- if not clean:
- self._passed = False
- except:
- result.addError(self, failure.Failure())
- self._passed = False
- for error in self._observer.getErrors():
- result.addError(self, error)
- self._passed = False
- self.flushLoggedErrors()
- self._removeObserver()
- if self._passed:
- result.addSuccess(self)
-
-
- def _classCleanUp(self, result):
- try:
- util._Janitor(self, result).postClassCleanup()
- except:
- result.addError(self, failure.Failure())
-
-
- def _makeReactorMethod(self, name):
- """
- Create a method which wraps the reactor method C{name}. The new
- method issues a deprecation warning and calls the original.
- """
- def _(*a, **kw):
- warnings.warn("reactor.%s cannot be used inside unit tests. "
- "In the future, using %s will fail the test and may "
- "crash or hang the test run."
- % (name, name),
- stacklevel=2, category=DeprecationWarning)
- return self._reactorMethods[name](*a, **kw)
- return _
-
-
- def _deprecateReactor(self, reactor):
- """
- Deprecate C{iterate}, C{crash} and C{stop} on C{reactor}. That is,
- each method is wrapped in a function that issues a deprecation
- warning, then calls the original.
-
- @param reactor: The Twisted reactor.
- """
- self._reactorMethods = {}
- for name in ['crash', 'iterate', 'stop']:
- self._reactorMethods[name] = getattr(reactor, name)
- setattr(reactor, name, self._makeReactorMethod(name))
-
-
- def _undeprecateReactor(self, reactor):
- """
- Restore the deprecated reactor methods. Undoes what
- L{_deprecateReactor} did.
-
- @param reactor: The Twisted reactor.
- """
- for name, method in self._reactorMethods.iteritems():
- setattr(reactor, name, method)
- self._reactorMethods = {}
-
-
- def _runCleanups(self):
- """
- Run the cleanups added with L{addCleanup} in order.
-
- @return: A C{Deferred} that fires when all cleanups are run.
- """
- def _makeFunction(f, args, kwargs):
- return lambda: f(*args, **kwargs)
- callables = []
- while len(self._cleanups) > 0:
- f, args, kwargs = self._cleanups.pop()
- callables.append(_makeFunction(f, args, kwargs))
- return util._runSequentially(callables)
-
-
- def _runFixturesAndTest(self, result):
- """
- Really run C{setUp}, the test method, and C{tearDown}. Any of these may
- return L{Deferred}s. After they complete, do some reactor cleanup.
-
- @param result: A L{TestResult} object.
- """
- from twisted.internet import reactor
- self._deprecateReactor(reactor)
- self._timedOut = False
- try:
- d = self.deferSetUp(None, result)
- try:
- self._wait(d)
- finally:
- self._cleanUp(result)
- self._classCleanUp(result)
- finally:
- self._undeprecateReactor(reactor)
-
-
- def addCleanup(self, f, *args, **kwargs):
- """
- Extend the base cleanup feature with support for cleanup functions which
- return Deferreds.
-
- If the function C{f} returns a Deferred, C{TestCase} will wait until the
- Deferred has fired before proceeding to the next function.
- """
- return super(TestCase, self).addCleanup(f, *args, **kwargs)
-
-
- def getSuppress(self):
- return self._getSuppress()
-
-
- def getTimeout(self):
- """
- Returns the timeout value set on this test. Checks on the instance
- first, then the class, then the module, then packages. As soon as it
- finds something with a C{timeout} attribute, returns that. Returns
- L{util.DEFAULT_TIMEOUT_DURATION} if it cannot find anything. See
- L{TestCase} docstring for more details.
- """
- timeout = util.acquireAttribute(self._parents, 'timeout',
- util.DEFAULT_TIMEOUT_DURATION)
- try:
- return float(timeout)
- except (ValueError, TypeError):
- # XXX -- this is here because sometimes people will have methods
- # called 'timeout', or set timeout to 'orange', or something
- # Particularly, test_news.NewsTestCase and ReactorCoreTestCase
- # both do this.
- warnings.warn("'timeout' attribute needs to be a number.",
- category=DeprecationWarning)
- return util.DEFAULT_TIMEOUT_DURATION
-
-
- def visit(self, visitor):
- """
- Visit this test case. Call C{visitor} with C{self} as a parameter.
-
- Deprecated in Twisted 8.0.
-
- @param visitor: A callable which expects a single parameter: a test
- case.
-
- @return: None
- """
- warnings.warn("Test visitors deprecated in Twisted 8.0",
- category=DeprecationWarning)
- visitor(self)
-
-
- def _wait(self, d, running=_wait_is_running):
- """Take a Deferred that only ever callbacks. Block until it happens.
- """
- from twisted.internet import reactor
- if running:
- raise RuntimeError("_wait is not reentrant")
-
- results = []
- def append(any):
- if results is not None:
- results.append(any)
- def crash(ign):
- if results is not None:
- reactor.crash()
- crash = utils.suppressWarnings(
- crash, util.suppress(message=r'reactor\.crash cannot be used.*',
- category=DeprecationWarning))
- def stop():
- reactor.crash()
- stop = utils.suppressWarnings(
- stop, util.suppress(message=r'reactor\.crash cannot be used.*',
- category=DeprecationWarning))
-
- running.append(None)
- try:
- d.addBoth(append)
- if results:
- # d might have already been fired, in which case append is
- # called synchronously. Avoid any reactor stuff.
- return
- d.addBoth(crash)
- reactor.stop = stop
- try:
- reactor.run()
- finally:
- del reactor.stop
-
- # If the reactor was crashed elsewhere due to a timeout, hopefully
- # that crasher also reported an error. Just return.
- # _timedOut is most likely to be set when d has fired but hasn't
- # completed its callback chain (see self._run)
- if results or self._timedOut: #defined in run() and _run()
- return
-
- # If the timeout didn't happen, and we didn't get a result or
- # a failure, then the user probably aborted the test, so let's
- # just raise KeyboardInterrupt.
-
- # FIXME: imagine this:
- # web/test/test_webclient.py:
- # exc = self.assertRaises(error.Error, wait, method(url))
- #
- # wait() will raise KeyboardInterrupt, and assertRaises will
- # swallow it. Therefore, wait() raising KeyboardInterrupt is
- # insufficient to stop trial. A suggested solution is to have
- # this code set a "stop trial" flag, or otherwise notify trial
- # that it should really try to stop as soon as possible.
- raise KeyboardInterrupt()
- finally:
- results = None
- running.pop()
-
-
-
-class UnsupportedTrialFeature(Exception):
- """A feature of twisted.trial was used that pyunit cannot support."""
-
-
-
-class PyUnitResultAdapter(object):
- """
- Wrap a C{TestResult} from the standard library's C{unittest} so that it
- supports the extended result types from Trial, and also supports
- L{twisted.python.failure.Failure}s being passed to L{addError} and
- L{addFailure}.
- """
-
- def __init__(self, original):
- """
- @param original: A C{TestResult} instance from C{unittest}.
- """
- self.original = original
-
- def _exc_info(self, err):
- return util.excInfoOrFailureToExcInfo(err)
-
- def startTest(self, method):
- self.original.startTest(method)
-
- def stopTest(self, method):
- self.original.stopTest(method)
-
- def addFailure(self, test, fail):
- self.original.addFailure(test, self._exc_info(fail))
-
- def addError(self, test, error):
- self.original.addError(test, self._exc_info(error))
-
- def _unsupported(self, test, feature, info):
- self.original.addFailure(
- test,
- (UnsupportedTrialFeature,
- UnsupportedTrialFeature(feature, info),
- None))
-
- def addSkip(self, test, reason):
- """
- Report the skip as a failure.
- """
- self._unsupported(test, 'skip', reason)
-
- def addUnexpectedSuccess(self, test, todo):
- """
- Report the unexpected success as a failure.
- """
- self._unsupported(test, 'unexpected success', todo)
-
- def addExpectedFailure(self, test, error):
- """
- Report the expected failure (i.e. todo) as a failure.
- """
- self._unsupported(test, 'expected failure', error)
-
- def addSuccess(self, test):
- self.original.addSuccess(test)
-
- def upDownError(self, method, error, warn, printStatus):
- pass
-
-
-
-def suiteVisit(suite, visitor):
- """
- Visit each test in C{suite} with C{visitor}.
-
- Deprecated in Twisted 8.0.
-
- @param visitor: A callable which takes a single argument, the L{TestCase}
- instance to visit.
- @return: None
- """
- warnings.warn("Test visitors deprecated in Twisted 8.0",
- category=DeprecationWarning)
- for case in suite._tests:
- visit = getattr(case, 'visit', None)
- if visit is not None:
- visit(visitor)
- elif isinstance(case, pyunit.TestCase):
- case = itrial.ITestCase(case)
- case.visit(visitor)
- elif isinstance(case, pyunit.TestSuite):
- suiteVisit(case, visitor)
- else:
- case.visit(visitor)
-
-
-
-class TestSuite(pyunit.TestSuite):
- """
- Extend the standard library's C{TestSuite} with support for the visitor
- pattern and a consistently overrideable C{run} method.
- """
-
- visit = suiteVisit
-
- def __call__(self, result):
- return self.run(result)
-
-
- def run(self, result):
- """
- Call C{run} on every member of the suite.
- """
- # we implement this because Python 2.3 unittest defines this code
- # in __call__, whereas 2.4 defines the code in run.
- for test in self._tests:
- if result.shouldStop:
- break
- test(result)
- return result
-
-
-
-class TestDecorator(components.proxyForInterface(itrial.ITestCase,
- "_originalTest")):
- """
- Decorator for test cases.
-
- @param _originalTest: The wrapped instance of test.
- @type _originalTest: A provider of L{itrial.ITestCase}
- """
-
- implements(itrial.ITestCase)
-
-
- def __call__(self, result):
- """
- Run the unit test.
-
- @param result: A TestResult object.
- """
- return self.run(result)
-
-
- def run(self, result):
- """
- Run the unit test.
-
- @param result: A TestResult object.
- """
- return self._originalTest.run(
- reporter._AdaptedReporter(result, self.__class__))
-
-
-
-def _clearSuite(suite):
- """
- Clear all tests from C{suite}.
-
- This messes with the internals of C{suite}. In particular, it assumes that
- the suite keeps all of its tests in a list in an instance variable called
- C{_tests}.
- """
- suite._tests = []
-
-
-def decorate(test, decorator):
- """
- Decorate all test cases in C{test} with C{decorator}.
-
- C{test} can be a test case or a test suite. If it is a test suite, then the
- structure of the suite is preserved.
-
- L{decorate} tries to preserve the class of the test suites it finds, but
- assumes the presence of the C{_tests} attribute on the suite.
-
- @param test: The C{TestCase} or C{TestSuite} to decorate.
-
- @param decorator: A unary callable used to decorate C{TestCase}s.
-
- @return: A decorated C{TestCase} or a C{TestSuite} containing decorated
- C{TestCase}s.
- """
-
- try:
- tests = iter(test)
- except TypeError:
- return decorator(test)
-
- # At this point, we know that 'test' is a test suite.
- _clearSuite(test)
-
- for case in tests:
- test.addTest(decorate(case, decorator))
- return test
-
-
-
-class _PyUnitTestCaseAdapter(TestDecorator):
- """
- Adapt from pyunit.TestCase to ITestCase.
- """
-
-
- def visit(self, visitor):
- """
- Deprecated in Twisted 8.0.
- """
- warnings.warn("Test visitors deprecated in Twisted 8.0",
- category=DeprecationWarning)
- visitor(self)
-
-
-
-class _BrokenIDTestCaseAdapter(_PyUnitTestCaseAdapter):
- """
- Adapter for pyunit-style C{TestCase} subclasses that have undesirable id()
- methods. That is L{pyunit.FunctionTestCase} and L{pyunit.DocTestCase}.
- """
-
- def id(self):
- """
- Return the fully-qualified Python name of the doctest.
- """
- testID = self._originalTest.shortDescription()
- if testID is not None:
- return testID
- return self._originalTest.id()
-
-
-
-class _ForceGarbageCollectionDecorator(TestDecorator):
- """
- Forces garbage collection to be run before and after the test. Any errors
- logged during the post-test collection are added to the test result as
- errors.
- """
-
- def run(self, result):
- gc.collect()
- TestDecorator.run(self, result)
- _logObserver._add()
- gc.collect()
- for error in _logObserver.getErrors():
- result.addError(self, error)
- _logObserver.flushErrors()
- _logObserver._remove()
-
-
-components.registerAdapter(
- _PyUnitTestCaseAdapter, pyunit.TestCase, itrial.ITestCase)
-
-
-components.registerAdapter(
- _BrokenIDTestCaseAdapter, pyunit.FunctionTestCase, itrial.ITestCase)
-
-
-_docTestCase = getattr(doctest, 'DocTestCase', None)
-if _docTestCase:
- components.registerAdapter(
- _BrokenIDTestCaseAdapter, _docTestCase, itrial.ITestCase)
-
-
-def _iterateTests(testSuiteOrCase):
- """
- Iterate through all of the test cases in C{testSuiteOrCase}.
- """
- try:
- suite = iter(testSuiteOrCase)
- except TypeError:
- yield testSuiteOrCase
- else:
- for test in suite:
- for subtest in _iterateTests(test):
- yield subtest
-
-
-
-# Support for Python 2.3
-try:
- iter(pyunit.TestSuite())
-except TypeError:
- # Python 2.3's TestSuite doesn't support iteration. Let's monkey patch it!
- def __iter__(self):
- return iter(self._tests)
- pyunit.TestSuite.__iter__ = __iter__
-
-
-
-class _SubTestCase(TestCase):
- def __init__(self):
- TestCase.__init__(self, 'run')
-
-_inst = _SubTestCase()
-
-def _deprecate(name):
- """
- Internal method used to deprecate top-level assertions. Do not use this.
- """
- def _(*args, **kwargs):
- warnings.warn("unittest.%s is deprecated. Instead use the %r "
- "method on unittest.TestCase" % (name, name),
- stacklevel=2, category=DeprecationWarning)
- return getattr(_inst, name)(*args, **kwargs)
- return _
-
-
-_assertions = ['fail', 'failUnlessEqual', 'failIfEqual', 'failIfEquals',
- 'failUnless', 'failUnlessIdentical', 'failUnlessIn',
- 'failIfIdentical', 'failIfIn', 'failIf',
- 'failUnlessAlmostEqual', 'failIfAlmostEqual',
- 'failUnlessRaises', 'assertApproximates',
- 'assertFailure', 'failUnlessSubstring', 'failIfSubstring',
- 'assertAlmostEqual', 'assertAlmostEquals',
- 'assertNotAlmostEqual', 'assertNotAlmostEquals', 'assertEqual',
- 'assertEquals', 'assertNotEqual', 'assertNotEquals',
- 'assertRaises', 'assert_', 'assertIdentical',
- 'assertNotIdentical', 'assertIn', 'assertNotIn',
- 'failUnlessFailure', 'assertSubstring', 'assertNotSubstring']
-
-
-for methodName in _assertions:
- globals()[methodName] = _deprecate(methodName)
-del methodName
-
-
-__all__ = ['SynchronousTestCase', 'TestCase', 'FailTest', 'SkipTest']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/util.py
deleted file mode 100755
index 90d4437f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/trial/util.py
+++ /dev/null
@@ -1,430 +0,0 @@
-# -*- test-case-name: twisted.trial.test.test_util -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-
-"""
-A collection of utility functions and classes, used internally by Trial.
-
-This code is for Trial's internal use. Do NOT use this code if you are writing
-tests. It is subject to change at the Trial maintainer's whim. There is
-nothing here in this module for you to use unless you are maintaining Trial.
-
-Any non-Trial Twisted code that uses this module will be shot.
-
-Maintainer: Jonathan Lange
-"""
-
-import traceback, sys
-from random import randrange
-
-from twisted.internet import defer, utils, interfaces
-from twisted.python.failure import Failure
-from twisted.python import deprecate, versions
-from twisted.python.lockfile import FilesystemLock
-from twisted.python.filepath import FilePath
-
-DEFAULT_TIMEOUT = object()
-DEFAULT_TIMEOUT_DURATION = 120.0
-
-
-
-class DirtyReactorAggregateError(Exception):
- """
- Passed to L{twisted.trial.itrial.IReporter.addError} when the reactor is
- left in an unclean state after a test.
-
- @ivar delayedCalls: The L{DelayedCall} objects which weren't cleaned up.
- @ivar selectables: The selectables which weren't cleaned up.
- """
-
- def __init__(self, delayedCalls, selectables=None):
- self.delayedCalls = delayedCalls
- self.selectables = selectables
-
- def __str__(self):
- """
- Return a multi-line message describing all of the unclean state.
- """
- msg = "Reactor was unclean."
- if self.delayedCalls:
- msg += ("\nDelayedCalls: (set "
- "twisted.internet.base.DelayedCall.debug = True to "
- "debug)\n")
- msg += "\n".join(map(str, self.delayedCalls))
- if self.selectables:
- msg += "\nSelectables:\n"
- msg += "\n".join(map(str, self.selectables))
- return msg
-
-
-
-class _Janitor(object):
- """
- The guy that cleans up after you.
-
- @ivar test: The L{TestCase} to report errors about.
- @ivar result: The L{IReporter} to report errors to.
- @ivar reactor: The reactor to use. If None, the global reactor
- will be used.
- """
- def __init__(self, test, result, reactor=None):
- """
- @param test: See L{_Janitor.test}.
- @param result: See L{_Janitor.result}.
- @param reactor: See L{_Janitor.reactor}.
- """
- self.test = test
- self.result = result
- self.reactor = reactor
-
-
- def postCaseCleanup(self):
- """
- Called by L{unittest.TestCase} after a test to catch any logged errors
- or pending L{DelayedCall}s.
- """
- calls = self._cleanPending()
- if calls:
- aggregate = DirtyReactorAggregateError(calls)
- self.result.addError(self.test, Failure(aggregate))
- return False
- return True
-
-
- def postClassCleanup(self):
- """
- Called by L{unittest.TestCase} after the last test in a C{TestCase}
- subclass. Ensures the reactor is clean by murdering the threadpool,
- catching any pending L{DelayedCall}s, open sockets etc.
- """
- selectables = self._cleanReactor()
- calls = self._cleanPending()
- if selectables or calls:
- aggregate = DirtyReactorAggregateError(calls, selectables)
- self.result.addError(self.test, Failure(aggregate))
- self._cleanThreads()
-
-
- def _getReactor(self):
- """
- Get either the passed-in reactor or the global reactor.
- """
- if self.reactor is not None:
- reactor = self.reactor
- else:
- from twisted.internet import reactor
- return reactor
-
-
- def _cleanPending(self):
- """
- Cancel all pending calls and return their string representations.
- """
- reactor = self._getReactor()
-
- # flush short-range timers
- reactor.iterate(0)
- reactor.iterate(0)
-
- delayedCallStrings = []
- for p in reactor.getDelayedCalls():
- if p.active():
- delayedString = str(p)
- p.cancel()
- else:
- print "WEIRDNESS! pending timed call not active!"
- delayedCallStrings.append(delayedString)
- return delayedCallStrings
- _cleanPending = utils.suppressWarnings(
- _cleanPending, (('ignore',), {'category': DeprecationWarning,
- 'message':
- r'reactor\.iterate cannot be used.*'}))
-
- def _cleanThreads(self):
- reactor = self._getReactor()
- if interfaces.IReactorThreads.providedBy(reactor):
- if reactor.threadpool is not None:
- # Stop the threadpool now so that a new one is created.
- # This improves test isolation somewhat (although this is a
- # post class cleanup hook, so it's only isolating classes
- # from each other, not methods from each other).
- reactor._stopThreadPool()
-
- def _cleanReactor(self):
- """
- Remove all selectables from the reactor, kill any of them that were
- processes, and return their string representation.
- """
- reactor = self._getReactor()
- selectableStrings = []
- for sel in reactor.removeAll():
- if interfaces.IProcessTransport.providedBy(sel):
- sel.signalProcess('KILL')
- selectableStrings.append(repr(sel))
- return selectableStrings
-
-
-def excInfoOrFailureToExcInfo(err):
- """
- Coerce a Failure to an _exc_info, if err is a Failure.
-
- @param err: Either a tuple such as returned by L{sys.exc_info} or a
- L{Failure} object.
- @return: A tuple like the one returned by L{sys.exc_info}. e.g.
- C{exception_type, exception_object, traceback_object}.
- """
- if isinstance(err, Failure):
- # Unwrap the Failure into a exc_info tuple.
- err = (err.type, err.value, err.getTracebackObject())
- return err
-
-
-def suppress(action='ignore', **kwarg):
- """
- Sets up the .suppress tuple properly, pass options to this method as you
- would the stdlib warnings.filterwarnings()
-
- So, to use this with a .suppress magic attribute you would do the
- following:
-
- >>> from twisted.trial import unittest, util
- >>> import warnings
- >>>
- >>> class TestFoo(unittest.TestCase):
- ... def testFooBar(self):
- ... warnings.warn("i am deprecated", DeprecationWarning)
- ... testFooBar.suppress = [util.suppress(message='i am deprecated')]
- ...
- >>>
-
- Note that as with the todo and timeout attributes: the module level
- attribute acts as a default for the class attribute which acts as a default
- for the method attribute. The suppress attribute can be overridden at any
- level by specifying C{.suppress = []}
- """
- return ((action,), kwarg)
-
-
-def profiled(f, outputFile):
- def _(*args, **kwargs):
- if sys.version_info[0:2] != (2, 4):
- import profile
- prof = profile.Profile()
- try:
- result = prof.runcall(f, *args, **kwargs)
- prof.dump_stats(outputFile)
- except SystemExit:
- pass
- prof.print_stats()
- return result
- else: # use hotshot, profile is broken in 2.4
- import hotshot.stats
- prof = hotshot.Profile(outputFile)
- try:
- return prof.runcall(f, *args, **kwargs)
- finally:
- stats = hotshot.stats.load(outputFile)
- stats.strip_dirs()
- stats.sort_stats('cum') # 'time'
- stats.print_stats(100)
- return _
-
-
-def getPythonContainers(meth):
- """Walk up the Python tree from method 'meth', finding its class, its module
- and all containing packages."""
- containers = []
- containers.append(meth.im_class)
- moduleName = meth.im_class.__module__
- while moduleName is not None:
- module = sys.modules.get(moduleName, None)
- if module is None:
- module = __import__(moduleName)
- containers.append(module)
- moduleName = getattr(module, '__module__', None)
- return containers
-
-
-_DEFAULT = object()
-def acquireAttribute(objects, attr, default=_DEFAULT):
- """Go through the list 'objects' sequentially until we find one which has
- attribute 'attr', then return the value of that attribute. If not found,
- return 'default' if set, otherwise, raise AttributeError. """
- for obj in objects:
- if hasattr(obj, attr):
- return getattr(obj, attr)
- if default is not _DEFAULT:
- return default
- raise AttributeError('attribute %r not found in %r' % (attr, objects))
-
-
-
-deprecate.deprecatedModuleAttribute(
- versions.Version("Twisted", 10, 1, 0),
- "Please use twisted.python.reflect.namedAny instead.",
- __name__, "findObject")
-
-
-
-def findObject(name):
- """Get a fully-named package, module, module-global object or attribute.
- Forked from twisted.python.reflect.namedAny.
-
- Returns a tuple of (bool, obj). If bool is True, the named object exists
- and is returned as obj. If bool is False, the named object does not exist
- and the value of obj is unspecified.
- """
- names = name.split('.')
- topLevelPackage = None
- moduleNames = names[:]
- while not topLevelPackage:
- trialname = '.'.join(moduleNames)
- if len(trialname) == 0:
- return (False, None)
- try:
- topLevelPackage = __import__(trialname)
- except ImportError:
- # if the ImportError happened in the module being imported,
- # this is a failure that should be handed to our caller.
- # count stack frames to tell the difference.
- exc_info = sys.exc_info()
- if len(traceback.extract_tb(exc_info[2])) > 1:
- try:
- # Clean up garbage left in sys.modules.
- del sys.modules[trialname]
- except KeyError:
- # Python 2.4 has fixed this. Yay!
- pass
- raise exc_info[0], exc_info[1], exc_info[2]
- moduleNames.pop()
- obj = topLevelPackage
- for n in names[1:]:
- try:
- obj = getattr(obj, n)
- except AttributeError:
- return (False, obj)
- return (True, obj)
-
-
-
-def _runSequentially(callables, stopOnFirstError=False):
- """
- Run the given callables one after the other. If a callable returns a
- Deferred, wait until it has finished before running the next callable.
-
- @param callables: An iterable of callables that take no parameters.
-
- @param stopOnFirstError: If True, then stop running callables as soon as
- one raises an exception or fires an errback. False by default.
-
- @return: A L{Deferred} that fires a list of C{(flag, value)} tuples. Each
- tuple will be either C{(SUCCESS, <return value>)} or C{(FAILURE,
- <Failure>)}.
- """
- results = []
- for f in callables:
- d = defer.maybeDeferred(f)
- thing = defer.waitForDeferred(d)
- yield thing
- try:
- results.append((defer.SUCCESS, thing.getResult()))
- except:
- results.append((defer.FAILURE, Failure()))
- if stopOnFirstError:
- break
- yield results
-_runSequentially = defer.deferredGenerator(_runSequentially)
-
-
-
-class _NoTrialMarker(Exception):
- """
- No trial marker file could be found.
-
- Raised when trial attempts to remove a trial temporary working directory
- that does not contain a marker file.
- """
-
-
-
-def _removeSafely(path):
- """
- Safely remove a path, recursively.
-
- If C{path} does not contain a node named C{_trial_marker}, a
- L{_NoTrialmarker} exception is raised and the path is not removed.
- """
- if not path.child('_trial_marker').exists():
- raise _NoTrialMarker(
- '%r is not a trial temporary path, refusing to remove it'
- % (path,))
- try:
- path.remove()
- except OSError, e:
- print ("could not remove %r, caught OSError [Errno %s]: %s"
- % (path, e.errno, e.strerror))
- try:
- newPath = FilePath('_trial_temp_old%s' % (randrange(1000000),))
- path.moveTo(newPath)
- except OSError, e:
- print ("could not rename path, caught OSError [Errno %s]: %s"
- % (e.errno,e.strerror))
- raise
-
-
-
-class _WorkingDirectoryBusy(Exception):
- """
- A working directory was specified to the runner, but another test run is
- currently using that directory.
- """
-
-
-
-def _unusedTestDirectory(base):
- """
- Find an unused directory named similarly to C{base}.
-
- Once a directory is found, it will be locked and a marker dropped into it to
- identify it as a trial temporary directory.
-
- @param base: A template path for the discovery process. If this path
- exactly cannot be used, a path which varies only in a suffix of the
- basename will be used instead.
- @type base: L{FilePath}
-
- @return: A two-tuple. The first element is a L{FilePath} representing the
- directory which was found and created. The second element is a locked
- L{FilesystemLock}. Another call to C{_unusedTestDirectory} will not be
- able to reused the the same name until the lock is released, either
- explicitly or by this process exiting.
- """
- counter = 0
- while True:
- if counter:
- testdir = base.sibling('%s-%d' % (base.basename(), counter))
- else:
- testdir = base
-
- testDirLock = FilesystemLock(testdir.path + '.lock')
- if testDirLock.lock():
- # It is not in use
- if testdir.exists():
- # It exists though - delete it
- _removeSafely(testdir)
-
- # Create it anew and mark it as ours so the next _removeSafely on it
- # succeeds.
- testdir.makedirs()
- testdir.child('_trial_marker').setContent('')
- return testdir, testDirLock
- else:
- # It is in use
- if base.basename() == '_trial_temp':
- counter += 1
- else:
- raise _WorkingDirectoryBusy()
-
-
-__all__ = ['excInfoOrFailureToExcInfo', 'suppress']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/__init__.py
deleted file mode 100755
index 3de93da6..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- test-case-name: twisted.web.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Twisted Web: a L{web server<twisted.web.server>} (including an
-L{HTTP implementation<twisted.web.http>} and a
-L{resource model<twisted.web.resource>}) and
-a L{web client<twisted.web.client>}.
-"""
-
-from twisted.web._version import version
-
-__version__ = version.short()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/__init__.py
deleted file mode 100755
index 6a588700..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_httpauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-HTTP header-based authentication migrated from web2
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/basic.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/basic.py
deleted file mode 100755
index 8b588fb4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/basic.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_httpauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-HTTP BASIC authentication.
-
-@see: U{http://tools.ietf.org/html/rfc1945}
-@see: U{http://tools.ietf.org/html/rfc2616}
-@see: U{http://tools.ietf.org/html/rfc2617}
-"""
-
-import binascii
-
-from zope.interface import implements
-
-from twisted.cred import credentials, error
-from twisted.web.iweb import ICredentialFactory
-
-
-class BasicCredentialFactory(object):
- """
- Credential Factory for HTTP Basic Authentication
-
- @type authenticationRealm: C{str}
- @ivar authenticationRealm: The HTTP authentication realm which will be issued in
- challenges.
- """
- implements(ICredentialFactory)
-
- scheme = 'basic'
-
- def __init__(self, authenticationRealm):
- self.authenticationRealm = authenticationRealm
-
-
- def getChallenge(self, request):
- """
- Return a challenge including the HTTP authentication realm with which
- this factory was created.
- """
- return {'realm': self.authenticationRealm}
-
-
- def decode(self, response, request):
- """
- Parse the base64-encoded, colon-separated username and password into a
- L{credentials.UsernamePassword} instance.
- """
- try:
- creds = binascii.a2b_base64(response + '===')
- except binascii.Error:
- raise error.LoginFailed('Invalid credentials')
-
- creds = creds.split(':', 1)
- if len(creds) == 2:
- return credentials.UsernamePassword(*creds)
- else:
- raise error.LoginFailed('Invalid credentials')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/digest.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/digest.py
deleted file mode 100755
index 90ebf201..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/digest.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_httpauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation of RFC2617: HTTP Digest Authentication
-
-@see: U{http://www.faqs.org/rfcs/rfc2617.html}
-"""
-
-from zope.interface import implements
-from twisted.cred import credentials
-from twisted.web.iweb import ICredentialFactory
-
-class DigestCredentialFactory(object):
- """
- Wrapper for L{digest.DigestCredentialFactory} that implements the
- L{ICredentialFactory} interface.
- """
- implements(ICredentialFactory)
-
- scheme = 'digest'
-
- def __init__(self, algorithm, authenticationRealm):
- """
- Create the digest credential factory that this object wraps.
- """
- self.digest = credentials.DigestCredentialFactory(algorithm,
- authenticationRealm)
-
-
- def getChallenge(self, request):
- """
- Generate the challenge for use in the WWW-Authenticate header
-
- @param request: The L{IRequest} to with access was denied and for the
- response to which this challenge is being generated.
-
- @return: The C{dict} that can be used to generate a WWW-Authenticate
- header.
- """
- return self.digest.getChallenge(request.getClientIP())
-
-
- def decode(self, response, request):
- """
- Create a L{twisted.cred.digest.DigestedCredentials} object from the
- given response and request.
-
- @see: L{ICredentialFactory.decode}
- """
- return self.digest.decode(response,
- request.method,
- request.getClientIP())
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py
deleted file mode 100755
index 29f479ef..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_httpauth -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A guard implementation which supports HTTP header-based authentication
-schemes.
-
-If no I{Authorization} header is supplied, an anonymous login will be
-attempted by using a L{Anonymous} credentials object. If such a header is
-supplied and does not contain allowed credentials, or if anonymous login is
-denied, a 401 will be sent in the response along with I{WWW-Authenticate}
-headers for each of the allowed authentication schemes.
-"""
-
-from zope.interface import implements
-
-from twisted.python import log
-from twisted.python.components import proxyForInterface
-from twisted.web.resource import IResource, ErrorPage
-from twisted.web import util
-from twisted.cred import error
-from twisted.cred.credentials import Anonymous
-
-
-class UnauthorizedResource(object):
- """
- Simple IResource to escape Resource dispatch
- """
- implements(IResource)
- isLeaf = True
-
-
- def __init__(self, factories):
- self._credentialFactories = factories
-
-
- def render(self, request):
- """
- Send www-authenticate headers to the client
- """
- def generateWWWAuthenticate(scheme, challenge):
- l = []
- for k,v in challenge.iteritems():
- l.append("%s=%s" % (k, quoteString(v)))
- return "%s %s" % (scheme, ", ".join(l))
-
- def quoteString(s):
- return '"%s"' % (s.replace('\\', '\\\\').replace('"', '\\"'),)
-
- request.setResponseCode(401)
- for fact in self._credentialFactories:
- challenge = fact.getChallenge(request)
- request.responseHeaders.addRawHeader(
- 'www-authenticate',
- generateWWWAuthenticate(fact.scheme, challenge))
- if request.method == 'HEAD':
- return ''
- return 'Unauthorized'
-
-
- def getChildWithDefault(self, path, request):
- """
- Disable resource dispatch
- """
- return self
-
-
-
-class HTTPAuthSessionWrapper(object):
- """
- Wrap a portal, enforcing supported header-based authentication schemes.
-
- @ivar _portal: The L{Portal} which will be used to retrieve L{IResource}
- avatars.
-
- @ivar _credentialFactories: A list of L{ICredentialFactory} providers which
- will be used to decode I{Authorization} headers into L{ICredentials}
- providers.
- """
- implements(IResource)
- isLeaf = False
-
- def __init__(self, portal, credentialFactories):
- """
- Initialize a session wrapper
-
- @type portal: C{Portal}
- @param portal: The portal that will authenticate the remote client
-
- @type credentialFactories: C{Iterable}
- @param credentialFactories: The portal that will authenticate the
- remote client based on one submitted C{ICredentialFactory}
- """
- self._portal = portal
- self._credentialFactories = credentialFactories
-
-
- def _authorizedResource(self, request):
- """
- Get the L{IResource} which the given request is authorized to receive.
- If the proper authorization headers are present, the resource will be
- requested from the portal. If not, an anonymous login attempt will be
- made.
- """
- authheader = request.getHeader('authorization')
- if not authheader:
- return util.DeferredResource(self._login(Anonymous()))
-
- factory, respString = self._selectParseHeader(authheader)
- if factory is None:
- return UnauthorizedResource(self._credentialFactories)
- try:
- credentials = factory.decode(respString, request)
- except error.LoginFailed:
- return UnauthorizedResource(self._credentialFactories)
- except:
- log.err(None, "Unexpected failure from credentials factory")
- return ErrorPage(500, None, None)
- else:
- return util.DeferredResource(self._login(credentials))
-
-
- def render(self, request):
- """
- Find the L{IResource} avatar suitable for the given request, if
- possible, and render it. Otherwise, perhaps render an error page
- requiring authorization or describing an internal server failure.
- """
- return self._authorizedResource(request).render(request)
-
-
- def getChildWithDefault(self, path, request):
- """
- Inspect the Authorization HTTP header, and return a deferred which,
- when fired after successful authentication, will return an authorized
- C{Avatar}. On authentication failure, an C{UnauthorizedResource} will
- be returned, essentially halting further dispatch on the wrapped
- resource and all children
- """
- # Don't consume any segments of the request - this class should be
- # transparent!
- request.postpath.insert(0, request.prepath.pop())
- return self._authorizedResource(request)
-
-
- def _login(self, credentials):
- """
- Get the L{IResource} avatar for the given credentials.
-
- @return: A L{Deferred} which will be called back with an L{IResource}
- avatar or which will errback if authentication fails.
- """
- d = self._portal.login(credentials, None, IResource)
- d.addCallbacks(self._loginSucceeded, self._loginFailed)
- return d
-
-
- def _loginSucceeded(self, (interface, avatar, logout)):
- """
- Handle login success by wrapping the resulting L{IResource} avatar
- so that the C{logout} callback will be invoked when rendering is
- complete.
- """
- class ResourceWrapper(proxyForInterface(IResource, 'resource')):
- """
- Wrap an L{IResource} so that whenever it or a child of it
- completes rendering, the cred logout hook will be invoked.
-
- An assumption is made here that exactly one L{IResource} from
- among C{avatar} and all of its children will be rendered. If
- more than one is rendered, C{logout} will be invoked multiple
- times and probably earlier than desired.
- """
- def getChildWithDefault(self, name, request):
- """
- Pass through the lookup to the wrapped resource, wrapping
- the result in L{ResourceWrapper} to ensure C{logout} is
- called when rendering of the child is complete.
- """
- return ResourceWrapper(self.resource.getChildWithDefault(name, request))
-
- def render(self, request):
- """
- Hook into response generation so that when rendering has
- finished completely (with or without error), C{logout} is
- called.
- """
- request.notifyFinish().addBoth(lambda ign: logout())
- return super(ResourceWrapper, self).render(request)
-
- return ResourceWrapper(avatar)
-
-
- def _loginFailed(self, result):
- """
- Handle login failure by presenting either another challenge (for
- expected authentication/authorization-related failures) or a server
- error page (for anything else).
- """
- if result.check(error.Unauthorized, error.LoginFailed):
- return UnauthorizedResource(self._credentialFactories)
- else:
- log.err(
- result,
- "HTTPAuthSessionWrapper.getChildWithDefault encountered "
- "unexpected error")
- return ErrorPage(500, None, None)
-
-
- def _selectParseHeader(self, header):
- """
- Choose an C{ICredentialFactory} from C{_credentialFactories}
- suitable to use to decode the given I{Authenticate} header.
-
- @return: A two-tuple of a factory and the remaining portion of the
- header value to be decoded or a two-tuple of C{None} if no
- factory can decode the header value.
- """
- elements = header.split(' ')
- scheme = elements[0].lower()
- for fact in self._credentialFactories:
- if fact.scheme == scheme:
- return (fact, ' '.join(elements[1:]))
- return (None, None)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_element.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_element.py
deleted file mode 100755
index 3c15b3b4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_element.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_template -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from zope.interface import implements
-
-from twisted.web.iweb import IRenderable
-
-from twisted.web.error import MissingRenderMethod, UnexposedMethodError
-from twisted.web.error import MissingTemplateLoader
-
-
-class Expose(object):
- """
- Helper for exposing methods for various uses using a simple decorator-style
- callable.
-
- Instances of this class can be called with one or more functions as
- positional arguments. The names of these functions will be added to a list
- on the class object of which they are methods.
-
- @ivar attributeName: The attribute with which exposed methods will be
- tracked.
- """
- def __init__(self, doc=None):
- self.doc = doc
-
-
- def __call__(self, *funcObjs):
- """
- Add one or more functions to the set of exposed functions.
-
- This is a way to declare something about a class definition, similar to
- L{zope.interface.implements}. Use it like this::
-
- magic = Expose('perform extra magic')
- class Foo(Bar):
- def twiddle(self, x, y):
- ...
- def frob(self, a, b):
- ...
- magic(twiddle, frob)
-
- Later you can query the object::
-
- aFoo = Foo()
- magic.get(aFoo, 'twiddle')(x=1, y=2)
-
- The call to C{get} will fail if the name it is given has not been
- exposed using C{magic}.
-
- @param funcObjs: One or more function objects which will be exposed to
- the client.
-
- @return: The first of C{funcObjs}.
- """
- if not funcObjs:
- raise TypeError("expose() takes at least 1 argument (0 given)")
- for fObj in funcObjs:
- fObj.exposedThrough = getattr(fObj, 'exposedThrough', [])
- fObj.exposedThrough.append(self)
- return funcObjs[0]
-
-
- _nodefault = object()
- def get(self, instance, methodName, default=_nodefault):
- """
- Retrieve an exposed method with the given name from the given instance.
-
- @raise UnexposedMethodError: Raised if C{default} is not specified and
- there is no exposed method with the given name.
-
- @return: A callable object for the named method assigned to the given
- instance.
- """
- method = getattr(instance, methodName, None)
- exposedThrough = getattr(method, 'exposedThrough', [])
- if self not in exposedThrough:
- if default is self._nodefault:
- raise UnexposedMethodError(self, methodName)
- return default
- return method
-
-
- @classmethod
- def _withDocumentation(cls, thunk):
- """
- Slight hack to make users of this class appear to have a docstring to
- documentation generators, by defining them with a decorator. (This hack
- should be removed when epydoc can be convinced to use some other method
- for documenting.)
- """
- return cls(thunk.__doc__)
-
-
-# Avoid exposing the ugly, private classmethod name in the docs. Luckily this
-# namespace is private already so this doesn't leak further.
-exposer = Expose._withDocumentation
-
-@exposer
-def renderer():
- """
- Decorate with L{renderer} to use methods as template render directives.
-
- For example::
-
- class Foo(Element):
- @renderer
- def twiddle(self, request, tag):
- return tag('Hello, world.')
-
- <div xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">
- <span t:render="twiddle" />
- </div>
-
- Will result in this final output::
-
- <div>
- <span>Hello, world.</span>
- </div>
- """
-
-
-
-class Element(object):
- """
- Base for classes which can render part of a page.
-
- An Element is a renderer that can be embedded in a stan document and can
- hook its template (from the loader) up to render methods.
-
- An Element might be used to encapsulate the rendering of a complex piece of
- data which is to be displayed in multiple different contexts. The Element
- allows the rendering logic to be easily re-used in different ways.
-
- Element returns render methods which are registered using
- L{twisted.web.element.renderer}. For example::
-
- class Menu(Element):
- @renderer
- def items(self, request, tag):
- ....
-
- Render methods are invoked with two arguments: first, the
- L{twisted.web.http.Request} being served and second, the tag object which
- "invoked" the render method.
-
- @type loader: L{ITemplateLoader} provider
- @ivar loader: The factory which will be used to load documents to
- return from C{render}.
- """
- implements(IRenderable)
- loader = None
-
- def __init__(self, loader=None):
- if loader is not None:
- self.loader = loader
-
-
- def lookupRenderMethod(self, name):
- """
- Look up and return the named render method.
- """
- method = renderer.get(self, name, None)
- if method is None:
- raise MissingRenderMethod(self, name)
- return method
-
-
- def render(self, request):
- """
- Implement L{IRenderable} to allow one L{Element} to be embedded in
- another's template or rendering output.
-
- (This will simply load the template from the C{loader}; when used in a
- template, the flattening engine will keep track of this object
- separately as the object to lookup renderers on and call
- L{Element.renderer} to look them up. The resulting object from this
- method is not directly associated with this L{Element}.)
- """
- loader = self.loader
- if loader is None:
- raise MissingTemplateLoader(self)
- return loader.load()
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_flatten.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_flatten.py
deleted file mode 100755
index bfdc7766..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_flatten.py
+++ /dev/null
@@ -1,314 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_flatten -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Context-free flattener/serializer for rendering Python objects, possibly
-complex or arbitrarily nested, as strings.
-
-"""
-
-from cStringIO import StringIO
-from sys import exc_info
-from types import GeneratorType
-from traceback import extract_tb
-from twisted.internet.defer import Deferred
-from twisted.web.error import UnfilledSlot, UnsupportedType, FlattenerError
-
-from twisted.web.iweb import IRenderable
-from twisted.web._stan import (
- Tag, slot, voidElements, Comment, CDATA, CharRef)
-
-
-
-def escapedData(data, inAttribute):
- """
- Escape a string for inclusion in a document.
-
- @type data: C{str} or C{unicode}
- @param data: The string to escape.
-
- @type inAttribute: C{bool}
- @param inAttribute: A flag which, if set, indicates that the string should
- be quoted for use as the value of an XML tag value.
-
- @rtype: C{str}
- @return: The quoted form of C{data}. If C{data} is unicode, return a utf-8
- encoded string.
- """
- if isinstance(data, unicode):
- data = data.encode('utf-8')
- data = data.replace('&', '&amp;'
- ).replace('<', '&lt;'
- ).replace('>', '&gt;')
- if inAttribute:
- data = data.replace('"', '&quot;')
- return data
-
-
-def escapedCDATA(data):
- """
- Escape CDATA for inclusion in a document.
-
- @type data: C{str} or C{unicode}
- @param data: The string to escape.
-
- @rtype: C{str}
- @return: The quoted form of C{data}. If C{data} is unicode, return a utf-8
- encoded string.
- """
- if isinstance(data, unicode):
- data = data.encode('utf-8')
- return data.replace(']]>', ']]]]><![CDATA[>')
-
-
-def escapedComment(data):
- """
- Escape a comment for inclusion in a document.
-
- @type data: C{str} or C{unicode}
- @param data: The string to escape.
-
- @rtype: C{str}
- @return: The quoted form of C{data}. If C{data} is unicode, return a utf-8
- encoded string.
- """
- if isinstance(data, unicode):
- data = data.encode('utf-8')
- data = data.replace('--', '- - ').replace('>', '&gt;')
- if data and data[-1] == '-':
- data += ' '
- return data
-
-
-def _getSlotValue(name, slotData, default=None):
- """
- Find the value of the named slot in the given stack of slot data.
- """
- for slotFrame in slotData[::-1]:
- if slotFrame is not None and name in slotFrame:
- return slotFrame[name]
- else:
- if default is not None:
- return default
- raise UnfilledSlot(name)
-
-
-def _flattenElement(request, root, slotData, renderFactory, inAttribute):
- """
- Make C{root} slightly more flat by yielding all its immediate contents
- as strings, deferreds or generators that are recursive calls to itself.
-
- @param request: A request object which will be passed to
- L{IRenderable.render}.
-
- @param root: An object to be made flatter. This may be of type C{unicode},
- C{str}, L{slot}, L{Tag}, L{URL}, L{tuple}, L{list}, L{GeneratorType},
- L{Deferred}, or an object that implements L{IRenderable}.
-
- @param slotData: A C{list} of C{dict} mapping C{str} slot names to data
- with which those slots will be replaced.
-
- @param renderFactory: If not C{None}, An object that provides L{IRenderable}.
-
- @param inAttribute: A flag which, if set, indicates that C{str} and
- C{unicode} instances encountered must be quoted as for XML tag
- attribute values.
-
- @return: An iterator which yields C{str}, L{Deferred}, and more iterators
- of the same type.
- """
-
- if isinstance(root, (str, unicode)):
- yield escapedData(root, inAttribute)
- elif isinstance(root, slot):
- slotValue = _getSlotValue(root.name, slotData, root.default)
- yield _flattenElement(request, slotValue, slotData, renderFactory,
- inAttribute)
- elif isinstance(root, CDATA):
- yield '<![CDATA['
- yield escapedCDATA(root.data)
- yield ']]>'
- elif isinstance(root, Comment):
- yield '<!--'
- yield escapedComment(root.data)
- yield '-->'
- elif isinstance(root, Tag):
- slotData.append(root.slotData)
- if root.render is not None:
- rendererName = root.render
- rootClone = root.clone(False)
- rootClone.render = None
- renderMethod = renderFactory.lookupRenderMethod(rendererName)
- result = renderMethod(request, rootClone)
- yield _flattenElement(request, result, slotData, renderFactory,
- False)
- slotData.pop()
- return
-
- if not root.tagName:
- yield _flattenElement(request, root.children, slotData, renderFactory, False)
- return
-
- yield '<'
- if isinstance(root.tagName, unicode):
- tagName = root.tagName.encode('ascii')
- else:
- tagName = str(root.tagName)
- yield tagName
- for k, v in root.attributes.iteritems():
- if isinstance(k, unicode):
- k = k.encode('ascii')
- yield ' ' + k + '="'
- yield _flattenElement(request, v, slotData, renderFactory, True)
- yield '"'
- if root.children or tagName not in voidElements:
- yield '>'
- yield _flattenElement(request, root.children, slotData, renderFactory, False)
- yield '</' + tagName + '>'
- else:
- yield ' />'
-
- elif isinstance(root, (tuple, list, GeneratorType)):
- for element in root:
- yield _flattenElement(request, element, slotData, renderFactory,
- inAttribute)
- elif isinstance(root, CharRef):
- yield '&#%d;' % (root.ordinal,)
- elif isinstance(root, Deferred):
- yield root.addCallback(
- lambda result: (result, _flattenElement(request, result, slotData,
- renderFactory, inAttribute)))
- elif IRenderable.providedBy(root):
- result = root.render(request)
- yield _flattenElement(request, result, slotData, root, inAttribute)
- else:
- raise UnsupportedType(root)
-
-
-def _flattenTree(request, root):
- """
- Make C{root} into an iterable of C{str} and L{Deferred} by doing a
- depth first traversal of the tree.
-
- @param request: A request object which will be passed to
- L{IRenderable.render}.
-
- @param root: An object to be made flatter. This may be of type C{unicode},
- C{str}, L{slot}, L{Tag}, L{tuple}, L{list}, L{GeneratorType},
- L{Deferred}, or something providing L{IRenderable}.
-
- @return: An iterator which yields objects of type C{str} and L{Deferred}.
- A L{Deferred} is only yielded when one is encountered in the process of
- flattening C{root}. The returned iterator must not be iterated again
- until the L{Deferred} is called back.
- """
- stack = [_flattenElement(request, root, [], None, False)]
- while stack:
- try:
- # In Python 2.5, after an exception, a generator's gi_frame is
- # None.
- frame = stack[-1].gi_frame
- element = stack[-1].next()
- except StopIteration:
- stack.pop()
- except Exception, e:
- stack.pop()
- roots = []
- for generator in stack:
- roots.append(generator.gi_frame.f_locals['root'])
- roots.append(frame.f_locals['root'])
- raise FlattenerError(e, roots, extract_tb(exc_info()[2]))
- else:
- if type(element) is str:
- yield element
- elif isinstance(element, Deferred):
- def cbx((original, toFlatten)):
- stack.append(toFlatten)
- return original
- yield element.addCallback(cbx)
- else:
- stack.append(element)
-
-
-def _writeFlattenedData(state, write, result):
- """
- Take strings from an iterator and pass them to a writer function.
-
- @param state: An iterator of C{str} and L{Deferred}. C{str} instances will
- be passed to C{write}. L{Deferred} instances will be waited on before
- resuming iteration of C{state}.
-
- @param write: A callable which will be invoked with each C{str}
- produced by iterating C{state}.
-
- @param result: A L{Deferred} which will be called back when C{state} has
- been completely flattened into C{write} or which will be errbacked if
- an exception in a generator passed to C{state} or an errback from a
- L{Deferred} from state occurs.
-
- @return: C{None}
- """
- while True:
- try:
- element = state.next()
- except StopIteration:
- result.callback(None)
- except:
- result.errback()
- else:
- if type(element) is str:
- write(element)
- continue
- else:
- def cby(original):
- _writeFlattenedData(state, write, result)
- return original
- element.addCallbacks(cby, result.errback)
- break
-
-
-def flatten(request, root, write):
- """
- Incrementally write out a string representation of C{root} using C{write}.
-
- In order to create a string representation, C{root} will be decomposed into
- simpler objects which will themselves be decomposed and so on until strings
- or objects which can easily be converted to strings are encountered.
-
- @param request: A request object which will be passed to the C{render}
- method of any L{IRenderable} provider which is encountered.
-
- @param root: An object to be made flatter. This may be of type C{unicode},
- C{str}, L{slot}, L{Tag}, L{tuple}, L{list}, L{GeneratorType},
- L{Deferred}, or something that provides L{IRenderable}.
-
- @param write: A callable which will be invoked with each C{str}
- produced by flattening C{root}.
-
- @return: A L{Deferred} which will be called back when C{root} has
- been completely flattened into C{write} or which will be errbacked if
- an unexpected exception occurs.
- """
- result = Deferred()
- state = _flattenTree(request, root)
- _writeFlattenedData(state, write, result)
- return result
-
-
-def flattenString(request, root):
- """
- Collate a string representation of C{root} into a single string.
-
- This is basically gluing L{flatten} to a C{StringIO} and returning the
- results. See L{flatten} for the exact meanings of C{request} and
- C{root}.
-
- @return: A L{Deferred} which will be called back with a single string as
- its result when C{root} has been completely flattened into C{write} or
- which will be errbacked if an unexpected exception occurs.
- """
- io = StringIO()
- d = flatten(request, root, io.write)
- d.addCallback(lambda _: io.getvalue())
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_newclient.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_newclient.py
deleted file mode 100755
index 431e0298..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_newclient.py
+++ /dev/null
@@ -1,1502 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_newclient -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An U{HTTP 1.1<http://www.w3.org/Protocols/rfc2616/rfc2616.html>} client.
-
-The way to use the functionality provided by this module is to:
-
- - Connect a L{HTTP11ClientProtocol} to an HTTP server
- - Create a L{Request} with the appropriate data
- - Pass the request to L{HTTP11ClientProtocol.request}
- - The returned Deferred will fire with a L{Response} object
- - Create a L{IProtocol} provider which can handle the response body
- - Connect it to the response with L{Response.deliverBody}
- - When the protocol's C{connectionLost} method is called, the response is
- complete. See L{Response.deliverBody} for details.
-
-Various other classes in this module support this usage:
-
- - HTTPParser is the basic HTTP parser. It can handle the parts of HTTP which
- are symmetric between requests and responses.
-
- - HTTPClientParser extends HTTPParser to handle response-specific parts of
- HTTP. One instance is created for each request to parse the corresponding
- response.
-"""
-
-__metaclass__ = type
-
-from zope.interface import implements
-
-from twisted.python import log
-from twisted.python.reflect import fullyQualifiedName
-from twisted.python.failure import Failure
-from twisted.python.compat import set
-from twisted.internet.interfaces import IConsumer, IPushProducer
-from twisted.internet.error import ConnectionDone
-from twisted.internet.defer import Deferred, succeed, fail, maybeDeferred
-from twisted.internet.protocol import Protocol
-from twisted.protocols.basic import LineReceiver
-from twisted.web.iweb import UNKNOWN_LENGTH, IResponse
-from twisted.web.http_headers import Headers
-from twisted.web.http import NO_CONTENT, NOT_MODIFIED
-from twisted.web.http import _DataLoss, PotentialDataLoss
-from twisted.web.http import _IdentityTransferDecoder, _ChunkedTransferDecoder
-
-# States HTTPParser can be in
-STATUS = 'STATUS'
-HEADER = 'HEADER'
-BODY = 'BODY'
-DONE = 'DONE'
-
-
-class BadHeaders(Exception):
- """
- Headers passed to L{Request} were in some way invalid.
- """
-
-
-
-class ExcessWrite(Exception):
- """
- The body L{IBodyProducer} for a request tried to write data after
- indicating it had finished writing data.
- """
-
-
-class ParseError(Exception):
- """
- Some received data could not be parsed.
-
- @ivar data: The string which could not be parsed.
- """
- def __init__(self, reason, data):
- Exception.__init__(self, reason, data)
- self.data = data
-
-
-
-class BadResponseVersion(ParseError):
- """
- The version string in a status line was unparsable.
- """
-
-
-
-class _WrapperException(Exception):
- """
- L{_WrapperException} is the base exception type for exceptions which
- include one or more other exceptions as the low-level causes.
-
- @ivar reasons: A list of exceptions. See subclass documentation for more
- details.
- """
- def __init__(self, reasons):
- Exception.__init__(self, reasons)
- self.reasons = reasons
-
-
-
-class RequestGenerationFailed(_WrapperException):
- """
- There was an error while creating the bytes which make up a request.
-
- @ivar reasons: A C{list} of one or more L{Failure} instances giving the
- reasons the request generation was considered to have failed.
- """
-
-
-
-class RequestTransmissionFailed(_WrapperException):
- """
- There was an error while sending the bytes which make up a request.
-
- @ivar reasons: A C{list} of one or more L{Failure} instances giving the
- reasons the request transmission was considered to have failed.
- """
-
-
-
-class ConnectionAborted(Exception):
- """
- The connection was explicitly aborted by application code.
- """
-
-
-
-class WrongBodyLength(Exception):
- """
- An L{IBodyProducer} declared the number of bytes it was going to
- produce (via its C{length} attribute) and then produced a different number
- of bytes.
- """
-
-
-
-class ResponseDone(Exception):
- """
- L{ResponseDone} may be passed to L{IProtocol.connectionLost} on the
- protocol passed to L{Response.deliverBody} and indicates that the entire
- response has been delivered.
- """
-
-
-
-class ResponseFailed(_WrapperException):
- """
- L{ResponseFailed} indicates that all of the response to a request was not
- received for some reason.
-
- @ivar reasons: A C{list} of one or more L{Failure} instances giving the
- reasons the response was considered to have failed.
-
- @ivar response: If specified, the L{Response} received from the server (and
- in particular the status code and the headers).
- """
-
- def __init__(self, reasons, response=None):
- _WrapperException.__init__(self, reasons)
- self.response = response
-
-
-
-class ResponseNeverReceived(ResponseFailed):
- """
- A L{ResponseFailed} that knows no response bytes at all have been received.
- """
-
-
-
-class RequestNotSent(Exception):
- """
- L{RequestNotSent} indicates that an attempt was made to issue a request but
- for reasons unrelated to the details of the request itself, the request
- could not be sent. For example, this may indicate that an attempt was made
- to send a request using a protocol which is no longer connected to a
- server.
- """
-
-
-
-def _callAppFunction(function):
- """
- Call C{function}. If it raises an exception, log it with a minimal
- description of the source.
-
- @return: C{None}
- """
- try:
- function()
- except:
- log.err(None, "Unexpected exception from %s" % (
- fullyQualifiedName(function),))
-
-
-
-class HTTPParser(LineReceiver):
- """
- L{HTTPParser} handles the parsing side of HTTP processing. With a suitable
- subclass, it can parse either the client side or the server side of the
- connection.
-
- @ivar headers: All of the non-connection control message headers yet
- received.
-
- @ivar state: State indicator for the response parsing state machine. One
- of C{STATUS}, C{HEADER}, C{BODY}, C{DONE}.
-
- @ivar _partialHeader: C{None} or a C{list} of the lines of a multiline
- header while that header is being received.
- """
-
- # NOTE: According to HTTP spec, we're supposed to eat the
- # 'Proxy-Authenticate' and 'Proxy-Authorization' headers also, but that
- # doesn't sound like a good idea to me, because it makes it impossible to
- # have a non-authenticating transparent proxy in front of an authenticating
- # proxy. An authenticating proxy can eat them itself. -jknight
- #
- # Further, quoting
- # http://homepages.tesco.net/J.deBoynePollard/FGA/web-proxy-connection-header.html
- # regarding the 'Proxy-Connection' header:
- #
- # The Proxy-Connection: header is a mistake in how some web browsers
- # use HTTP. Its name is the result of a false analogy. It is not a
- # standard part of the protocol. There is a different standard
- # protocol mechanism for doing what it does. And its existence
- # imposes a requirement upon HTTP servers such that no proxy HTTP
- # server can be standards-conforming in practice.
- #
- # -exarkun
-
- # Some servers (like http://news.ycombinator.com/) return status lines and
- # HTTP headers delimited by \n instead of \r\n.
- delimiter = '\n'
-
- CONNECTION_CONTROL_HEADERS = set([
- 'content-length', 'connection', 'keep-alive', 'te', 'trailers',
- 'transfer-encoding', 'upgrade', 'proxy-connection'])
-
- def connectionMade(self):
- self.headers = Headers()
- self.connHeaders = Headers()
- self.state = STATUS
- self._partialHeader = None
-
-
- def switchToBodyMode(self, decoder):
- """
- Switch to body parsing mode - interpret any more bytes delivered as
- part of the message body and deliver them to the given decoder.
- """
- if self.state == BODY:
- raise RuntimeError("already in body mode")
-
- self.bodyDecoder = decoder
- self.state = BODY
- self.setRawMode()
-
-
- def lineReceived(self, line):
- """
- Handle one line from a response.
- """
- # Handle the normal CR LF case.
- if line[-1:] == '\r':
- line = line[:-1]
-
- if self.state == STATUS:
- self.statusReceived(line)
- self.state = HEADER
- elif self.state == HEADER:
- if not line or line[0] not in ' \t':
- if self._partialHeader is not None:
- header = ''.join(self._partialHeader)
- name, value = header.split(':', 1)
- value = value.strip()
- self.headerReceived(name, value)
- if not line:
- # Empty line means the header section is over.
- self.allHeadersReceived()
- else:
- # Line not beginning with LWS is another header.
- self._partialHeader = [line]
- else:
- # A line beginning with LWS is a continuation of a header
- # begun on a previous line.
- self._partialHeader.append(line)
-
-
- def rawDataReceived(self, data):
- """
- Pass data from the message body to the body decoder object.
- """
- self.bodyDecoder.dataReceived(data)
-
-
- def isConnectionControlHeader(self, name):
- """
- Return C{True} if the given lower-cased name is the name of a
- connection control header (rather than an entity header).
-
- According to RFC 2616, section 14.10, the tokens in the Connection
- header are probably relevant here. However, I am not sure what the
- practical consequences of either implementing or ignoring that are.
- So I leave it unimplemented for the time being.
- """
- return name in self.CONNECTION_CONTROL_HEADERS
-
-
- def statusReceived(self, status):
- """
- Callback invoked whenever the first line of a new message is received.
- Override this.
-
- @param status: The first line of an HTTP request or response message
- without trailing I{CR LF}.
- @type status: C{str}
- """
-
-
- def headerReceived(self, name, value):
- """
- Store the given header in C{self.headers}.
- """
- name = name.lower()
- if self.isConnectionControlHeader(name):
- headers = self.connHeaders
- else:
- headers = self.headers
- headers.addRawHeader(name, value)
-
-
- def allHeadersReceived(self):
- """
- Callback invoked after the last header is passed to C{headerReceived}.
- Override this to change to the C{BODY} or C{DONE} state.
- """
- self.switchToBodyMode(None)
-
-
-
-class HTTPClientParser(HTTPParser):
- """
- An HTTP parser which only handles HTTP responses.
-
- @ivar request: The request with which the expected response is associated.
- @type request: L{Request}
-
- @ivar NO_BODY_CODES: A C{set} of response codes which B{MUST NOT} have a
- body.
-
- @ivar finisher: A callable to invoke when this response is fully parsed.
-
- @ivar _responseDeferred: A L{Deferred} which will be called back with the
- response when all headers in the response have been received.
- Thereafter, C{None}.
-
- @ivar _everReceivedData: C{True} if any bytes have been received.
- """
- NO_BODY_CODES = set([NO_CONTENT, NOT_MODIFIED])
-
- _transferDecoders = {
- 'chunked': _ChunkedTransferDecoder,
- }
-
- bodyDecoder = None
-
- def __init__(self, request, finisher):
- self.request = request
- self.finisher = finisher
- self._responseDeferred = Deferred()
- self._everReceivedData = False
-
-
- def dataReceived(self, data):
- """
- Override so that we know if any response has been received.
- """
- self._everReceivedData = True
- HTTPParser.dataReceived(self, data)
-
-
- def parseVersion(self, strversion):
- """
- Parse version strings of the form Protocol '/' Major '.' Minor. E.g.
- 'HTTP/1.1'. Returns (protocol, major, minor). Will raise ValueError
- on bad syntax.
- """
- try:
- proto, strnumber = strversion.split('/')
- major, minor = strnumber.split('.')
- major, minor = int(major), int(minor)
- except ValueError, e:
- raise BadResponseVersion(str(e), strversion)
- if major < 0 or minor < 0:
- raise BadResponseVersion("version may not be negative", strversion)
- return (proto, major, minor)
-
-
- def statusReceived(self, status):
- """
- Parse the status line into its components and create a response object
- to keep track of this response's state.
- """
- parts = status.split(' ', 2)
- if len(parts) != 3:
- raise ParseError("wrong number of parts", status)
-
- try:
- statusCode = int(parts[1])
- except ValueError:
- raise ParseError("non-integer status code", status)
-
- self.response = Response(
- self.parseVersion(parts[0]),
- statusCode,
- parts[2],
- self.headers,
- self.transport)
-
-
- def _finished(self, rest):
- """
- Called to indicate that an entire response has been received. No more
- bytes will be interpreted by this L{HTTPClientParser}. Extra bytes are
- passed up and the state of this L{HTTPClientParser} is set to I{DONE}.
-
- @param rest: A C{str} giving any extra bytes delivered to this
- L{HTTPClientParser} which are not part of the response being
- parsed.
- """
- self.state = DONE
- self.finisher(rest)
-
-
- def isConnectionControlHeader(self, name):
- """
- Content-Length in the response to a HEAD request is an entity header,
- not a connection control header.
- """
- if self.request.method == 'HEAD' and name == 'content-length':
- return False
- return HTTPParser.isConnectionControlHeader(self, name)
-
-
- def allHeadersReceived(self):
- """
- Figure out how long the response body is going to be by examining
- headers and stuff.
- """
- if (self.response.code in self.NO_BODY_CODES
- or self.request.method == 'HEAD'):
- self.response.length = 0
- self._finished(self.clearLineBuffer())
- else:
- transferEncodingHeaders = self.connHeaders.getRawHeaders(
- 'transfer-encoding')
- if transferEncodingHeaders:
-
- # This could be a KeyError. However, that would mean we do not
- # know how to decode the response body, so failing the request
- # is as good a behavior as any. Perhaps someday we will want
- # to normalize/document/test this specifically, but failing
- # seems fine to me for now.
- transferDecoder = self._transferDecoders[transferEncodingHeaders[0].lower()]
-
- # If anyone ever invents a transfer encoding other than
- # chunked (yea right), and that transfer encoding can predict
- # the length of the response body, it might be sensible to
- # allow the transfer decoder to set the response object's
- # length attribute.
- else:
- contentLengthHeaders = self.connHeaders.getRawHeaders('content-length')
- if contentLengthHeaders is None:
- contentLength = None
- elif len(contentLengthHeaders) == 1:
- contentLength = int(contentLengthHeaders[0])
- self.response.length = contentLength
- else:
- # "HTTP Message Splitting" or "HTTP Response Smuggling"
- # potentially happening. Or it's just a buggy server.
- raise ValueError(
- "Too many Content-Length headers; response is invalid")
-
- if contentLength == 0:
- self._finished(self.clearLineBuffer())
- transferDecoder = None
- else:
- transferDecoder = lambda x, y: _IdentityTransferDecoder(
- contentLength, x, y)
-
- if transferDecoder is None:
- self.response._bodyDataFinished()
- else:
- # Make sure as little data as possible from the response body
- # gets delivered to the response object until the response
- # object actually indicates it is ready to handle bytes
- # (probably because an application gave it a way to interpret
- # them).
- self.transport.pauseProducing()
- self.switchToBodyMode(transferDecoder(
- self.response._bodyDataReceived,
- self._finished))
-
- # This must be last. If it were first, then application code might
- # change some state (for example, registering a protocol to receive the
- # response body). Then the pauseProducing above would be wrong since
- # the response is ready for bytes and nothing else would ever resume
- # the transport.
- self._responseDeferred.callback(self.response)
- del self._responseDeferred
-
-
- def connectionLost(self, reason):
- if self.bodyDecoder is not None:
- try:
- try:
- self.bodyDecoder.noMoreData()
- except PotentialDataLoss:
- self.response._bodyDataFinished(Failure())
- except _DataLoss:
- self.response._bodyDataFinished(
- Failure(ResponseFailed([reason, Failure()],
- self.response)))
- else:
- self.response._bodyDataFinished()
- except:
- # Handle exceptions from both the except suites and the else
- # suite. Those functions really shouldn't raise exceptions,
- # but maybe there's some buggy application code somewhere
- # making things difficult.
- log.err()
- elif self.state != DONE:
- if self._everReceivedData:
- exceptionClass = ResponseFailed
- else:
- exceptionClass = ResponseNeverReceived
- self._responseDeferred.errback(Failure(exceptionClass([reason])))
- del self._responseDeferred
-
-
-
-class Request:
- """
- A L{Request} instance describes an HTTP request to be sent to an HTTP
- server.
-
- @ivar method: The HTTP method to for this request, ex: 'GET', 'HEAD',
- 'POST', etc.
- @type method: C{str}
-
- @ivar uri: The relative URI of the resource to request. For example,
- C{'/foo/bar?baz=quux'}.
- @type uri: C{str}
-
- @ivar headers: Headers to be sent to the server. It is important to
- note that this object does not create any implicit headers. So it
- is up to the HTTP Client to add required headers such as 'Host'.
- @type headers: L{twisted.web.http_headers.Headers}
-
- @ivar bodyProducer: C{None} or an L{IBodyProducer} provider which
- produces the content body to send to the remote HTTP server.
-
- @ivar persistent: Set to C{True} when you use HTTP persistent connection.
- @type persistent: C{bool}
- """
- def __init__(self, method, uri, headers, bodyProducer, persistent=False):
- self.method = method
- self.uri = uri
- self.headers = headers
- self.bodyProducer = bodyProducer
- self.persistent = persistent
-
-
- def _writeHeaders(self, transport, TEorCL):
- hosts = self.headers.getRawHeaders('host', ())
- if len(hosts) != 1:
- raise BadHeaders("Exactly one Host header required")
-
- # In the future, having the protocol version be a parameter to this
- # method would probably be good. It would be nice if this method
- # weren't limited to issueing HTTP/1.1 requests.
- requestLines = []
- requestLines.append(
- '%s %s HTTP/1.1\r\n' % (self.method, self.uri))
- if not self.persistent:
- requestLines.append('Connection: close\r\n')
- if TEorCL is not None:
- requestLines.append(TEorCL)
- for name, values in self.headers.getAllRawHeaders():
- requestLines.extend(['%s: %s\r\n' % (name, v) for v in values])
- requestLines.append('\r\n')
- transport.writeSequence(requestLines)
-
-
- def _writeToChunked(self, transport):
- """
- Write this request to the given transport using chunked
- transfer-encoding to frame the body.
- """
- self._writeHeaders(transport, 'Transfer-Encoding: chunked\r\n')
- encoder = ChunkedEncoder(transport)
- encoder.registerProducer(self.bodyProducer, True)
- d = self.bodyProducer.startProducing(encoder)
-
- def cbProduced(ignored):
- encoder.unregisterProducer()
- def ebProduced(err):
- encoder._allowNoMoreWrites()
- # Don't call the encoder's unregisterProducer because it will write
- # a zero-length chunk. This would indicate to the server that the
- # request body is complete. There was an error, though, so we
- # don't want to do that.
- transport.unregisterProducer()
- return err
- d.addCallbacks(cbProduced, ebProduced)
- return d
-
-
- def _writeToContentLength(self, transport):
- """
- Write this request to the given transport using content-length to frame
- the body.
- """
- self._writeHeaders(
- transport,
- 'Content-Length: %d\r\n' % (self.bodyProducer.length,))
-
- # This Deferred is used to signal an error in the data written to the
- # encoder below. It can only errback and it will only do so before too
- # many bytes have been written to the encoder and before the producer
- # Deferred fires.
- finishedConsuming = Deferred()
-
- # This makes sure the producer writes the correct number of bytes for
- # the request body.
- encoder = LengthEnforcingConsumer(
- self.bodyProducer, transport, finishedConsuming)
-
- transport.registerProducer(self.bodyProducer, True)
-
- finishedProducing = self.bodyProducer.startProducing(encoder)
-
- def combine(consuming, producing):
- # This Deferred is returned and will be fired when the first of
- # consuming or producing fires.
- ultimate = Deferred()
-
- # Keep track of what has happened so far. This initially
- # contains None, then an integer uniquely identifying what
- # sequence of events happened. See the callbacks and errbacks
- # defined below for the meaning of each value.
- state = [None]
-
- def ebConsuming(err):
- if state == [None]:
- # The consuming Deferred failed first. This means the
- # overall writeTo Deferred is going to errback now. The
- # producing Deferred should not fire later (because the
- # consumer should have called stopProducing on the
- # producer), but if it does, a callback will be ignored
- # and an errback will be logged.
- state[0] = 1
- ultimate.errback(err)
- else:
- # The consuming Deferred errbacked after the producing
- # Deferred fired. This really shouldn't ever happen.
- # If it does, I goofed. Log the error anyway, just so
- # there's a chance someone might notice and complain.
- log.err(
- err,
- "Buggy state machine in %r/[%d]: "
- "ebConsuming called" % (self, state[0]))
-
- def cbProducing(result):
- if state == [None]:
- # The producing Deferred succeeded first. Nothing will
- # ever happen to the consuming Deferred. Tell the
- # encoder we're done so it can check what the producer
- # wrote and make sure it was right.
- state[0] = 2
- try:
- encoder._noMoreWritesExpected()
- except:
- # Fail the overall writeTo Deferred - something the
- # producer did was wrong.
- ultimate.errback()
- else:
- # Success - succeed the overall writeTo Deferred.
- ultimate.callback(None)
- # Otherwise, the consuming Deferred already errbacked. The
- # producing Deferred wasn't supposed to fire, but it did
- # anyway. It's buggy, but there's not really anything to be
- # done about it. Just ignore this result.
-
- def ebProducing(err):
- if state == [None]:
- # The producing Deferred failed first. This means the
- # overall writeTo Deferred is going to errback now.
- # Tell the encoder that we're done so it knows to reject
- # further writes from the producer (which should not
- # happen, but the producer may be buggy).
- state[0] = 3
- encoder._allowNoMoreWrites()
- ultimate.errback(err)
- else:
- # The producing Deferred failed after the consuming
- # Deferred failed. It shouldn't have, so it's buggy.
- # Log the exception in case anyone who can fix the code
- # is watching.
- log.err(err, "Producer is buggy")
-
- consuming.addErrback(ebConsuming)
- producing.addCallbacks(cbProducing, ebProducing)
-
- return ultimate
-
- d = combine(finishedConsuming, finishedProducing)
- def f(passthrough):
- # Regardless of what happens with the overall Deferred, once it
- # fires, the producer registered way up above the definition of
- # combine should be unregistered.
- transport.unregisterProducer()
- return passthrough
- d.addBoth(f)
- return d
-
-
- def writeTo(self, transport):
- """
- Format this L{Request} as an HTTP/1.1 request and write it to the given
- transport. If bodyProducer is not None, it will be associated with an
- L{IConsumer}.
-
- @return: A L{Deferred} which fires with C{None} when the request has
- been completely written to the transport or with a L{Failure} if
- there is any problem generating the request bytes.
- """
- if self.bodyProducer is not None:
- if self.bodyProducer.length is UNKNOWN_LENGTH:
- return self._writeToChunked(transport)
- else:
- return self._writeToContentLength(transport)
- else:
- self._writeHeaders(transport, None)
- return succeed(None)
-
-
- def stopWriting(self):
- """
- Stop writing this request to the transport. This can only be called
- after C{writeTo} and before the L{Deferred} returned by C{writeTo}
- fires. It should cancel any asynchronous task started by C{writeTo}.
- The L{Deferred} returned by C{writeTo} need not be fired if this method
- is called.
- """
- # If bodyProducer is None, then the Deferred returned by writeTo has
- # fired already and this method cannot be called.
- _callAppFunction(self.bodyProducer.stopProducing)
-
-
-
-class LengthEnforcingConsumer:
- """
- An L{IConsumer} proxy which enforces an exact length requirement on the
- total data written to it.
-
- @ivar _length: The number of bytes remaining to be written.
-
- @ivar _producer: The L{IBodyProducer} which is writing to this
- consumer.
-
- @ivar _consumer: The consumer to which at most C{_length} bytes will be
- forwarded.
-
- @ivar _finished: A L{Deferred} which will be fired with a L{Failure} if too
- many bytes are written to this consumer.
- """
- def __init__(self, producer, consumer, finished):
- self._length = producer.length
- self._producer = producer
- self._consumer = consumer
- self._finished = finished
-
-
- def _allowNoMoreWrites(self):
- """
- Indicate that no additional writes are allowed. Attempts to write
- after calling this method will be met with an exception.
- """
- self._finished = None
-
-
- def write(self, bytes):
- """
- Write C{bytes} to the underlying consumer unless
- C{_noMoreWritesExpected} has been called or there are/have been too
- many bytes.
- """
- if self._finished is None:
- # No writes are supposed to happen any more. Try to convince the
- # calling code to stop calling this method by calling its
- # stopProducing method and then throwing an exception at it. This
- # exception isn't documented as part of the API because you're
- # never supposed to expect it: only buggy code will ever receive
- # it.
- self._producer.stopProducing()
- raise ExcessWrite()
-
- if len(bytes) <= self._length:
- self._length -= len(bytes)
- self._consumer.write(bytes)
- else:
- # No synchronous exception is raised in *this* error path because
- # we still have _finished which we can use to report the error to a
- # better place than the direct caller of this method (some
- # arbitrary application code).
- _callAppFunction(self._producer.stopProducing)
- self._finished.errback(WrongBodyLength("too many bytes written"))
- self._allowNoMoreWrites()
-
-
- def _noMoreWritesExpected(self):
- """
- Called to indicate no more bytes will be written to this consumer.
- Check to see that the correct number have been written.
-
- @raise WrongBodyLength: If not enough bytes have been written.
- """
- if self._finished is not None:
- self._allowNoMoreWrites()
- if self._length:
- raise WrongBodyLength("too few bytes written")
-
-
-
-def makeStatefulDispatcher(name, template):
- """
- Given a I{dispatch} name and a function, return a function which can be
- used as a method and which, when called, will call another method defined
- on the instance and return the result. The other method which is called is
- determined by the value of the C{_state} attribute of the instance.
-
- @param name: A string which is used to construct the name of the subsidiary
- method to invoke. The subsidiary method is named like C{'_%s_%s' %
- (name, _state)}.
-
- @param template: A function object which is used to give the returned
- function a docstring.
-
- @return: The dispatcher function.
- """
- def dispatcher(self, *args, **kwargs):
- func = getattr(self, '_' + name + '_' + self._state, None)
- if func is None:
- raise RuntimeError(
- "%r has no %s method in state %s" % (self, name, self._state))
- return func(*args, **kwargs)
- dispatcher.__doc__ = template.__doc__
- return dispatcher
-
-
-
-class Response:
- """
- A L{Response} instance describes an HTTP response received from an HTTP
- server.
-
- L{Response} should not be subclassed or instantiated.
-
- @ivar _transport: The transport which is delivering this response.
-
- @ivar _bodyProtocol: The L{IProtocol} provider to which the body is
- delivered. C{None} before one has been registered with
- C{deliverBody}.
-
- @ivar _bodyBuffer: A C{list} of the strings passed to C{bodyDataReceived}
- before C{deliverBody} is called. C{None} afterwards.
-
- @ivar _state: Indicates what state this L{Response} instance is in,
- particularly with respect to delivering bytes from the response body
- to an application-suppled protocol object. This may be one of
- C{'INITIAL'}, C{'CONNECTED'}, C{'DEFERRED_CLOSE'}, or C{'FINISHED'},
- with the following meanings:
-
- - INITIAL: This is the state L{Response} objects start in. No
- protocol has yet been provided and the underlying transport may
- still have bytes to deliver to it.
-
- - DEFERRED_CLOSE: If the underlying transport indicates all bytes
- have been delivered but no application-provided protocol is yet
- available, the L{Response} moves to this state. Data is
- buffered and waiting for a protocol to be delivered to.
-
- - CONNECTED: If a protocol is provided when the state is INITIAL,
- the L{Response} moves to this state. Any buffered data is
- delivered and any data which arrives from the transport
- subsequently is given directly to the protocol.
-
- - FINISHED: If a protocol is provided in the DEFERRED_CLOSE state,
- the L{Response} moves to this state after delivering all
- buffered data to the protocol. Otherwise, if the L{Response} is
- in the CONNECTED state, if the transport indicates there is no
- more data, the L{Response} moves to this state. Nothing else
- can happen once the L{Response} is in this state.
- """
- implements(IResponse)
-
- length = UNKNOWN_LENGTH
-
- _bodyProtocol = None
- _bodyFinished = False
-
- def __init__(self, version, code, phrase, headers, _transport):
- self.version = version
- self.code = code
- self.phrase = phrase
- self.headers = headers
- self._transport = _transport
- self._bodyBuffer = []
- self._state = 'INITIAL'
-
-
- def deliverBody(self, protocol):
- """
- Dispatch the given L{IProtocol} depending of the current state of the
- response.
- """
- deliverBody = makeStatefulDispatcher('deliverBody', deliverBody)
-
-
- def _deliverBody_INITIAL(self, protocol):
- """
- Deliver any buffered data to C{protocol} and prepare to deliver any
- future data to it. Move to the C{'CONNECTED'} state.
- """
- # Now that there's a protocol to consume the body, resume the
- # transport. It was previously paused by HTTPClientParser to avoid
- # reading too much data before it could be handled.
- self._transport.resumeProducing()
-
- protocol.makeConnection(self._transport)
- self._bodyProtocol = protocol
- for data in self._bodyBuffer:
- self._bodyProtocol.dataReceived(data)
- self._bodyBuffer = None
- self._state = 'CONNECTED'
-
-
- def _deliverBody_CONNECTED(self, protocol):
- """
- It is invalid to attempt to deliver data to a protocol when it is
- already being delivered to another protocol.
- """
- raise RuntimeError(
- "Response already has protocol %r, cannot deliverBody "
- "again" % (self._bodyProtocol,))
-
-
- def _deliverBody_DEFERRED_CLOSE(self, protocol):
- """
- Deliver any buffered data to C{protocol} and then disconnect the
- protocol. Move to the C{'FINISHED'} state.
- """
- # Unlike _deliverBody_INITIAL, there is no need to resume the
- # transport here because all of the response data has been received
- # already. Some higher level code may want to resume the transport if
- # that code expects further data to be received over it.
-
- protocol.makeConnection(self._transport)
-
- for data in self._bodyBuffer:
- protocol.dataReceived(data)
- self._bodyBuffer = None
- protocol.connectionLost(self._reason)
- self._state = 'FINISHED'
-
-
- def _deliverBody_FINISHED(self, protocol):
- """
- It is invalid to attempt to deliver data to a protocol after the
- response body has been delivered to another protocol.
- """
- raise RuntimeError(
- "Response already finished, cannot deliverBody now.")
-
-
- def _bodyDataReceived(self, data):
- """
- Called by HTTPClientParser with chunks of data from the response body.
- They will be buffered or delivered to the protocol passed to
- deliverBody.
- """
- _bodyDataReceived = makeStatefulDispatcher('bodyDataReceived',
- _bodyDataReceived)
-
-
- def _bodyDataReceived_INITIAL(self, data):
- """
- Buffer any data received for later delivery to a protocol passed to
- C{deliverBody}.
-
- Little or no data should be buffered by this method, since the
- transport has been paused and will not be resumed until a protocol
- is supplied.
- """
- self._bodyBuffer.append(data)
-
-
- def _bodyDataReceived_CONNECTED(self, data):
- """
- Deliver any data received to the protocol to which this L{Response}
- is connected.
- """
- self._bodyProtocol.dataReceived(data)
-
-
- def _bodyDataReceived_DEFERRED_CLOSE(self, data):
- """
- It is invalid for data to be delivered after it has been indicated
- that the response body has been completely delivered.
- """
- raise RuntimeError("Cannot receive body data after _bodyDataFinished")
-
-
- def _bodyDataReceived_FINISHED(self, data):
- """
- It is invalid for data to be delivered after the response body has
- been delivered to a protocol.
- """
- raise RuntimeError("Cannot receive body data after protocol disconnected")
-
-
- def _bodyDataFinished(self, reason=None):
- """
- Called by HTTPClientParser when no more body data is available. If the
- optional reason is supplied, this indicates a problem or potential
- problem receiving all of the response body.
- """
- _bodyDataFinished = makeStatefulDispatcher('bodyDataFinished',
- _bodyDataFinished)
-
-
- def _bodyDataFinished_INITIAL(self, reason=None):
- """
- Move to the C{'DEFERRED_CLOSE'} state to wait for a protocol to
- which to deliver the response body.
- """
- self._state = 'DEFERRED_CLOSE'
- if reason is None:
- reason = Failure(ResponseDone("Response body fully received"))
- self._reason = reason
-
-
- def _bodyDataFinished_CONNECTED(self, reason=None):
- """
- Disconnect the protocol and move to the C{'FINISHED'} state.
- """
- if reason is None:
- reason = Failure(ResponseDone("Response body fully received"))
- self._bodyProtocol.connectionLost(reason)
- self._bodyProtocol = None
- self._state = 'FINISHED'
-
-
- def _bodyDataFinished_DEFERRED_CLOSE(self):
- """
- It is invalid to attempt to notify the L{Response} of the end of the
- response body data more than once.
- """
- raise RuntimeError("Cannot finish body data more than once")
-
-
- def _bodyDataFinished_FINISHED(self):
- """
- It is invalid to attempt to notify the L{Response} of the end of the
- response body data more than once.
- """
- raise RuntimeError("Cannot finish body data after protocol disconnected")
-
-
-
-class ChunkedEncoder:
- """
- Helper object which exposes L{IConsumer} on top of L{HTTP11ClientProtocol}
- for streaming request bodies to the server.
- """
- implements(IConsumer)
-
- def __init__(self, transport):
- self.transport = transport
-
-
- def _allowNoMoreWrites(self):
- """
- Indicate that no additional writes are allowed. Attempts to write
- after calling this method will be met with an exception.
- """
- self.transport = None
-
-
- def registerProducer(self, producer, streaming):
- """
- Register the given producer with C{self.transport}.
- """
- self.transport.registerProducer(producer, streaming)
-
-
- def write(self, data):
- """
- Write the given request body bytes to the transport using chunked
- encoding.
-
- @type data: C{str}
- """
- if self.transport is None:
- raise ExcessWrite()
- self.transport.writeSequence(("%x\r\n" % len(data), data, "\r\n"))
-
-
- def unregisterProducer(self):
- """
- Indicate that the request body is complete and finish the request.
- """
- self.write('')
- self.transport.unregisterProducer()
- self._allowNoMoreWrites()
-
-
-
-class TransportProxyProducer:
- """
- An L{IPushProducer} implementation which wraps another such thing and
- proxies calls to it until it is told to stop.
-
- @ivar _producer: The wrapped L{IPushProducer} provider or C{None} after
- this proxy has been stopped.
- """
- implements(IPushProducer)
-
- # LineReceiver uses this undocumented attribute of transports to decide
- # when to stop calling lineReceived or rawDataReceived (if it finds it to
- # be true, it doesn't bother to deliver any more data). Set disconnecting
- # to False here and never change it to true so that all data is always
- # delivered to us and so that LineReceiver doesn't fail with an
- # AttributeError.
- disconnecting = False
-
- def __init__(self, producer):
- self._producer = producer
-
-
- def _stopProxying(self):
- """
- Stop forwarding calls of L{IPushProducer} methods to the underlying
- L{IPushProvider} provider.
- """
- self._producer = None
-
-
- def stopProducing(self):
- """
- Proxy the stoppage to the underlying producer, unless this proxy has
- been stopped.
- """
- if self._producer is not None:
- self._producer.stopProducing()
-
-
- def resumeProducing(self):
- """
- Proxy the resumption to the underlying producer, unless this proxy has
- been stopped.
- """
- if self._producer is not None:
- self._producer.resumeProducing()
-
-
- def pauseProducing(self):
- """
- Proxy the pause to the underlying producer, unless this proxy has been
- stopped.
- """
- if self._producer is not None:
- self._producer.pauseProducing()
-
-
-
-class HTTP11ClientProtocol(Protocol):
- """
- L{HTTP11ClientProtocol} is an implementation of the HTTP 1.1 client
- protocol. It supports as few features as possible.
-
- @ivar _parser: After a request is issued, the L{HTTPClientParser} to
- which received data making up the response to that request is
- delivered.
-
- @ivar _finishedRequest: After a request is issued, the L{Deferred} which
- will fire when a L{Response} object corresponding to that request is
- available. This allows L{HTTP11ClientProtocol} to fail the request
- if there is a connection or parsing problem.
-
- @ivar _currentRequest: After a request is issued, the L{Request}
- instance used to make that request. This allows
- L{HTTP11ClientProtocol} to stop request generation if necessary (for
- example, if the connection is lost).
-
- @ivar _transportProxy: After a request is issued, the
- L{TransportProxyProducer} to which C{_parser} is connected. This
- allows C{_parser} to pause and resume the transport in a way which
- L{HTTP11ClientProtocol} can exert some control over.
-
- @ivar _responseDeferred: After a request is issued, the L{Deferred} from
- C{_parser} which will fire with a L{Response} when one has been
- received. This is eventually chained with C{_finishedRequest}, but
- only in certain cases to avoid double firing that Deferred.
-
- @ivar _state: Indicates what state this L{HTTP11ClientProtocol} instance
- is in with respect to transmission of a request and reception of a
- response. This may be one of the following strings:
-
- - QUIESCENT: This is the state L{HTTP11ClientProtocol} instances
- start in. Nothing is happening: no request is being sent and no
- response is being received or expected.
-
- - TRANSMITTING: When a request is made (via L{request}), the
- instance moves to this state. L{Request.writeTo} has been used
- to start to send a request but it has not yet finished.
-
- - TRANSMITTING_AFTER_RECEIVING_RESPONSE: The server has returned a
- complete response but the request has not yet been fully sent
- yet. The instance will remain in this state until the request
- is fully sent.
-
- - GENERATION_FAILED: There was an error while the request. The
- request was not fully sent to the network.
-
- - WAITING: The request was fully sent to the network. The
- instance is now waiting for the response to be fully received.
-
- - ABORTING: Application code has requested that the HTTP connection
- be aborted.
-
- - CONNECTION_LOST: The connection has been lost.
-
- @ivar _abortDeferreds: A list of C{Deferred} instances that will fire when
- the connection is lost.
- """
- _state = 'QUIESCENT'
- _parser = None
- _finishedRequest = None
- _currentRequest = None
- _transportProxy = None
- _responseDeferred = None
-
-
- def __init__(self, quiescentCallback=lambda c: None):
- self._quiescentCallback = quiescentCallback
- self._abortDeferreds = []
-
-
- @property
- def state(self):
- return self._state
-
-
- def request(self, request):
- """
- Issue C{request} over C{self.transport} and return a L{Deferred} which
- will fire with a L{Response} instance or an error.
-
- @param request: The object defining the parameters of the request to
- issue.
- @type request: L{Request}
-
- @rtype: L{Deferred}
- @return: The deferred may errback with L{RequestGenerationFailed} if
- the request was not fully written to the transport due to a local
- error. It may errback with L{RequestTransmissionFailed} if it was
- not fully written to the transport due to a network error. It may
- errback with L{ResponseFailed} if the request was sent (not
- necessarily received) but some or all of the response was lost. It
- may errback with L{RequestNotSent} if it is not possible to send
- any more requests using this L{HTTP11ClientProtocol}.
- """
- if self._state != 'QUIESCENT':
- return fail(RequestNotSent())
-
- self._state = 'TRANSMITTING'
- _requestDeferred = maybeDeferred(request.writeTo, self.transport)
- self._finishedRequest = Deferred()
-
- # Keep track of the Request object in case we need to call stopWriting
- # on it.
- self._currentRequest = request
-
- self._transportProxy = TransportProxyProducer(self.transport)
- self._parser = HTTPClientParser(request, self._finishResponse)
- self._parser.makeConnection(self._transportProxy)
- self._responseDeferred = self._parser._responseDeferred
-
- def cbRequestWrotten(ignored):
- if self._state == 'TRANSMITTING':
- self._state = 'WAITING'
- self._responseDeferred.chainDeferred(self._finishedRequest)
-
- def ebRequestWriting(err):
- if self._state == 'TRANSMITTING':
- self._state = 'GENERATION_FAILED'
- self.transport.loseConnection()
- self._finishedRequest.errback(
- Failure(RequestGenerationFailed([err])))
- else:
- log.err(err, 'Error writing request, but not in valid state '
- 'to finalize request: %s' % self._state)
-
- _requestDeferred.addCallbacks(cbRequestWrotten, ebRequestWriting)
-
- return self._finishedRequest
-
-
- def _finishResponse(self, rest):
- """
- Called by an L{HTTPClientParser} to indicate that it has parsed a
- complete response.
-
- @param rest: A C{str} giving any trailing bytes which were given to
- the L{HTTPClientParser} which were not part of the response it
- was parsing.
- """
- _finishResponse = makeStatefulDispatcher('finishResponse', _finishResponse)
-
-
- def _finishResponse_WAITING(self, rest):
- # Currently the rest parameter is ignored. Don't forget to use it if
- # we ever add support for pipelining. And maybe check what trailers
- # mean.
- if self._state == 'WAITING':
- self._state = 'QUIESCENT'
- else:
- # The server sent the entire response before we could send the
- # whole request. That sucks. Oh well. Fire the request()
- # Deferred with the response. But first, make sure that if the
- # request does ever finish being written that it won't try to fire
- # that Deferred.
- self._state = 'TRANSMITTING_AFTER_RECEIVING_RESPONSE'
- self._responseDeferred.chainDeferred(self._finishedRequest)
-
- # This will happen if we're being called due to connection being lost;
- # if so, no need to disconnect parser again, or to call
- # _quiescentCallback.
- if self._parser is None:
- return
-
- reason = ConnectionDone("synthetic!")
- connHeaders = self._parser.connHeaders.getRawHeaders('connection', ())
- if (('close' in connHeaders) or self._state != "QUIESCENT" or
- not self._currentRequest.persistent):
- self._giveUp(Failure(reason))
- else:
- # We call the quiescent callback first, to ensure connection gets
- # added back to connection pool before we finish the request.
- try:
- self._quiescentCallback(self)
- except:
- # If callback throws exception, just log it and disconnect;
- # keeping persistent connections around is an optimisation:
- log.err()
- self.transport.loseConnection()
- self._disconnectParser(reason)
-
-
- _finishResponse_TRANSMITTING = _finishResponse_WAITING
-
-
- def _disconnectParser(self, reason):
- """
- If there is still a parser, call its C{connectionLost} method with the
- given reason. If there is not, do nothing.
-
- @type reason: L{Failure}
- """
- if self._parser is not None:
- parser = self._parser
- self._parser = None
- self._currentRequest = None
- self._finishedRequest = None
- self._responseDeferred = None
-
- # The parser is no longer allowed to do anything to the real
- # transport. Stop proxying from the parser's transport to the real
- # transport before telling the parser it's done so that it can't do
- # anything.
- self._transportProxy._stopProxying()
- self._transportProxy = None
- parser.connectionLost(reason)
-
-
- def _giveUp(self, reason):
- """
- Lose the underlying connection and disconnect the parser with the given
- L{Failure}.
-
- Use this method instead of calling the transport's loseConnection
- method directly otherwise random things will break.
- """
- self.transport.loseConnection()
- self._disconnectParser(reason)
-
-
- def dataReceived(self, bytes):
- """
- Handle some stuff from some place.
- """
- try:
- self._parser.dataReceived(bytes)
- except:
- self._giveUp(Failure())
-
-
- def connectionLost(self, reason):
- """
- The underlying transport went away. If appropriate, notify the parser
- object.
- """
- connectionLost = makeStatefulDispatcher('connectionLost', connectionLost)
-
-
- def _connectionLost_QUIESCENT(self, reason):
- """
- Nothing is currently happening. Move to the C{'CONNECTION_LOST'}
- state but otherwise do nothing.
- """
- self._state = 'CONNECTION_LOST'
-
-
- def _connectionLost_GENERATION_FAILED(self, reason):
- """
- The connection was in an inconsistent state. Move to the
- C{'CONNECTION_LOST'} state but otherwise do nothing.
- """
- self._state = 'CONNECTION_LOST'
-
-
- def _connectionLost_TRANSMITTING(self, reason):
- """
- Fail the L{Deferred} for the current request, notify the request
- object that it does not need to continue transmitting itself, and
- move to the C{'CONNECTION_LOST'} state.
- """
- self._state = 'CONNECTION_LOST'
- self._finishedRequest.errback(
- Failure(RequestTransmissionFailed([reason])))
- del self._finishedRequest
-
- # Tell the request that it should stop bothering now.
- self._currentRequest.stopWriting()
-
-
- def _connectionLost_TRANSMITTING_AFTER_RECEIVING_RESPONSE(self, reason):
- """
- Move to the C{'CONNECTION_LOST'} state.
- """
- self._state = 'CONNECTION_LOST'
-
-
- def _connectionLost_WAITING(self, reason):
- """
- Disconnect the response parser so that it can propagate the event as
- necessary (for example, to call an application protocol's
- C{connectionLost} method, or to fail a request L{Deferred}) and move
- to the C{'CONNECTION_LOST'} state.
- """
- self._disconnectParser(reason)
- self._state = 'CONNECTION_LOST'
-
-
- def _connectionLost_ABORTING(self, reason):
- """
- Disconnect the response parser with a L{ConnectionAborted} failure, and
- move to the C{'CONNECTION_LOST'} state.
- """
- self._disconnectParser(Failure(ConnectionAborted()))
- self._state = 'CONNECTION_LOST'
- for d in self._abortDeferreds:
- d.callback(None)
- self._abortDeferreds = []
-
-
- def abort(self):
- """
- Close the connection and cause all outstanding L{request} L{Deferred}s
- to fire with an error.
- """
- if self._state == "CONNECTION_LOST":
- return succeed(None)
- self.transport.loseConnection()
- self._state = 'ABORTING'
- d = Deferred()
- self._abortDeferreds.append(d)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_stan.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_stan.py
deleted file mode 100755
index 004761f8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_stan.py
+++ /dev/null
@@ -1,325 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_stan -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An s-expression-like syntax for expressing xml in pure python.
-
-Stan tags allow you to build XML documents using Python.
-
-Stan is a DOM, or Document Object Model, implemented using basic Python types
-and functions called "flatteners". A flattener is a function that knows how to
-turn an object of a specific type into something that is closer to an HTML
-string. Stan differs from the W3C DOM by not being as cumbersome and heavy
-weight. Since the object model is built using simple python types such as lists,
-strings, and dictionaries, the API is simpler and constructing a DOM less
-cumbersome.
-
-@var voidElements: the names of HTML 'U{void
- elements<http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#void-elements>}';
- those which can't have contents and can therefore be self-closing in the
- output.
-"""
-
-
-class slot(object):
- """
- Marker for markup insertion in a template.
-
- @type name: C{str}
- @ivar name: The name of this slot. The key which must be used in
- L{Tag.fillSlots} to fill it.
-
- @type children: C{list}
- @ivar children: The L{Tag} objects included in this L{slot}'s template.
-
- @type default: anything flattenable, or C{NoneType}
- @ivar default: The default contents of this slot, if it is left unfilled.
- If this is C{None}, an L{UnfilledSlot} will be raised, rather than
- C{None} actually being used.
-
- @type filename: C{str} or C{NoneType}
- @ivar filename: The name of the XML file from which this tag was parsed.
- If it was not parsed from an XML file, C{None}.
-
- @type lineNumber: C{int} or C{NoneType}
- @ivar lineNumber: The line number on which this tag was encountered in the
- XML file from which it was parsed. If it was not parsed from an XML
- file, C{None}.
-
- @type columnNumber: C{int} or C{NoneType}
- @ivar columnNumber: The column number at which this tag was encountered in
- the XML file from which it was parsed. If it was not parsed from an
- XML file, C{None}.
- """
-
- def __init__(self, name, default=None, filename=None, lineNumber=None,
- columnNumber=None):
- self.name = name
- self.children = []
- self.default = default
- self.filename = filename
- self.lineNumber = lineNumber
- self.columnNumber = columnNumber
-
-
- def __repr__(self):
- return "slot(%r)" % (self.name,)
-
-
-
-class Tag(object):
- """
- A L{Tag} represents an XML tags with a tag name, attributes, and children.
- A L{Tag} can be constructed using the special L{twisted.web.template.tags}
- object, or it may be constructed directly with a tag name. L{Tag}s have a
- special method, C{__call__}, which makes representing trees of XML natural
- using pure python syntax.
-
- @ivar tagName: The name of the represented element. For a tag like
- C{<div></div>}, this would be C{"div"}.
- @type tagName: C{str}
-
- @ivar attributes: The attributes of the element.
- @type attributes: C{dict} mapping C{str} to renderable objects.
-
- @ivar children: The child L{Tag}s of this C{Tag}.
- @type children: C{list} of renderable objects.
-
- @ivar render: The name of the render method to use for this L{Tag}. This
- name will be looked up at render time by the
- L{twisted.web.template.Element} doing the rendering, via
- L{twisted.web.template.Element.lookupRenderMethod}, to determine which
- method to call.
- @type render: C{str}
-
- @type filename: C{str} or C{NoneType}
- @ivar filename: The name of the XML file from which this tag was parsed.
- If it was not parsed from an XML file, C{None}.
-
- @type lineNumber: C{int} or C{NoneType}
- @ivar lineNumber: The line number on which this tag was encountered in the
- XML file from which it was parsed. If it was not parsed from an XML
- file, C{None}.
-
- @type columnNumber: C{int} or C{NoneType}
- @ivar columnNumber: The column number at which this tag was encountered in
- the XML file from which it was parsed. If it was not parsed from an
- XML file, C{None}.
-
- @type slotData: C{dict} or C{NoneType}
- @ivar slotData: The data which can fill slots. If present, a dictionary
- mapping slot names to renderable values. The values in this dict might
- be anything that can be present as the child of a L{Tag}; strings,
- lists, L{Tag}s, generators, etc.
- """
-
- slotData = None
- filename = None
- lineNumber = None
- columnNumber = None
-
- def __init__(self, tagName, attributes=None, children=None, render=None,
- filename=None, lineNumber=None, columnNumber=None):
- self.tagName = tagName
- self.render = render
- if attributes is None:
- self.attributes = {}
- else:
- self.attributes = attributes
- if children is None:
- self.children = []
- else:
- self.children = children
- if filename is not None:
- self.filename = filename
- if lineNumber is not None:
- self.lineNumber = lineNumber
- if columnNumber is not None:
- self.columnNumber = columnNumber
-
-
- def fillSlots(self, **slots):
- """
- Remember the slots provided at this position in the DOM.
-
- During the rendering of children of this node, slots with names in
- C{slots} will be rendered as their corresponding values.
-
- @return: C{self}. This enables the idiom C{return tag.fillSlots(...)} in
- renderers.
- """
- if self.slotData is None:
- self.slotData = {}
- self.slotData.update(slots)
- return self
-
-
- def __call__(self, *children, **kw):
- """
- Add children and change attributes on this tag.
-
- This is implemented using __call__ because it then allows the natural
- syntax::
-
- table(tr1, tr2, width="100%", height="50%", border="1")
-
- Children may be other tag instances, strings, functions, or any other
- object which has a registered flatten.
-
- Attributes may be 'transparent' tag instances (so that
- C{a(href=transparent(data="foo", render=myhrefrenderer))} works),
- strings, functions, or any other object which has a registered
- flattener.
-
- If the attribute is a python keyword, such as 'class', you can add an
- underscore to the name, like 'class_'.
-
- There is one special keyword argument, 'render', which will be used as
- the name of the renderer and saved as the 'render' attribute of this
- instance, rather than the DOM 'render' attribute in the attributes
- dictionary.
- """
- self.children.extend(children)
-
- for k, v in kw.iteritems():
- if k[-1] == '_':
- k = k[:-1]
-
- if k == 'render':
- self.render = v
- else:
- self.attributes[k] = v
- return self
-
-
- def _clone(self, obj, deep):
- """
- Clone an arbitrary object; used by L{Tag.clone}.
-
- @param obj: an object with a clone method, a list or tuple, or something
- which should be immutable.
-
- @param deep: whether to continue cloning child objects; i.e. the
- contents of lists, the sub-tags within a tag.
-
- @return: a clone of C{obj}.
- """
- if hasattr(obj, 'clone'):
- return obj.clone(deep)
- elif isinstance(obj, (list, tuple)):
- return [self._clone(x, deep) for x in obj]
- else:
- return obj
-
-
- def clone(self, deep=True):
- """
- Return a clone of this tag. If deep is True, clone all of this tag's
- children. Otherwise, just shallow copy the children list without copying
- the children themselves.
- """
- if deep:
- newchildren = [self._clone(x, True) for x in self.children]
- else:
- newchildren = self.children[:]
- newattrs = self.attributes.copy()
- for key in newattrs:
- newattrs[key] = self._clone(newattrs[key], True)
-
- newslotdata = None
- if self.slotData:
- newslotdata = self.slotData.copy()
- for key in newslotdata:
- newslotdata[key] = self._clone(newslotdata[key], True)
-
- newtag = Tag(
- self.tagName,
- attributes=newattrs,
- children=newchildren,
- render=self.render,
- filename=self.filename,
- lineNumber=self.lineNumber,
- columnNumber=self.columnNumber)
- newtag.slotData = newslotdata
-
- return newtag
-
-
- def clear(self):
- """
- Clear any existing children from this tag.
- """
- self.children = []
- return self
-
-
- def __repr__(self):
- rstr = ''
- if self.attributes:
- rstr += ', attributes=%r' % self.attributes
- if self.children:
- rstr += ', children=%r' % self.children
- return "Tag(%r%s)" % (self.tagName, rstr)
-
-
-
-voidElements = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param', 'area',
- 'input', 'col', 'basefont', 'isindex', 'frame', 'command',
- 'embed', 'keygen', 'source', 'track', 'wbs')
-
-
-class CDATA(object):
- """
- A C{<![CDATA[]]>} block from a template. Given a separate representation in
- the DOM so that they may be round-tripped through rendering without losing
- information.
-
- @ivar data: The data between "C{<![CDATA[}" and "C{]]>}".
- @type data: C{unicode}
- """
- def __init__(self, data):
- self.data = data
-
-
- def __repr__(self):
- return 'CDATA(%r)' % (self.data,)
-
-
-
-class Comment(object):
- """
- A C{<!-- -->} comment from a template. Given a separate representation in
- the DOM so that they may be round-tripped through rendering without losing
- information.
-
- @ivar data: The data between "C{<!--}" and "C{-->}".
- @type data: C{unicode}
- """
-
- def __init__(self, data):
- self.data = data
-
-
- def __repr__(self):
- return 'Comment(%r)' % (self.data,)
-
-
-
-class CharRef(object):
- """
- A numeric character reference. Given a separate representation in the DOM
- so that non-ASCII characters may be output as pure ASCII.
-
- @ivar ordinal: The ordinal value of the unicode character to which this is
- object refers.
- @type ordinal: C{int}
-
- @since: 12.0
- """
- def __init__(self, ordinal):
- self.ordinal = ordinal
-
-
- def __repr__(self):
- return "CharRef(%d)" % (self.ordinal,)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_version.py
deleted file mode 100755
index ca4f34f3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.web', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/client.py
deleted file mode 100755
index 246eea6e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/client.py
+++ /dev/null
@@ -1,1600 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_webclient -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-HTTP client.
-"""
-
-import os, types
-from urlparse import urlunparse
-from urllib import splithost, splittype
-import zlib
-
-from zope.interface import implements
-
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.web import http
-from twisted.internet import defer, protocol, task, reactor
-from twisted.internet.interfaces import IProtocol
-from twisted.internet.endpoints import TCP4ClientEndpoint, SSL4ClientEndpoint
-from twisted.python import failure
-from twisted.python.util import InsensitiveDict
-from twisted.python.components import proxyForInterface
-from twisted.web import error
-from twisted.web.iweb import UNKNOWN_LENGTH, IBodyProducer, IResponse
-from twisted.web.http_headers import Headers
-from twisted.python.compat import set
-
-
-class PartialDownloadError(error.Error):
- """
- Page was only partially downloaded, we got disconnected in middle.
-
- @ivar response: All of the response body which was downloaded.
- """
-
-
-class HTTPPageGetter(http.HTTPClient):
- """
- Gets a resource via HTTP, then quits.
-
- Typically used with L{HTTPClientFactory}. Note that this class does not, by
- itself, do anything with the response. If you want to download a resource
- into a file, use L{HTTPPageDownloader} instead.
-
- @ivar _completelyDone: A boolean indicating whether any further requests are
- necessary after this one completes in order to provide a result to
- C{self.factory.deferred}. If it is C{False}, then a redirect is going
- to be followed. Otherwise, this protocol's connection is the last one
- before firing the result Deferred. This is used to make sure the result
- Deferred is only fired after the connection is cleaned up.
- """
-
- quietLoss = 0
- followRedirect = True
- failed = 0
-
- _completelyDone = True
-
- _specialHeaders = set(('host', 'user-agent', 'cookie', 'content-length'))
-
- def connectionMade(self):
- method = getattr(self.factory, 'method', 'GET')
- self.sendCommand(method, self.factory.path)
- if self.factory.scheme == 'http' and self.factory.port != 80:
- host = '%s:%s' % (self.factory.host, self.factory.port)
- elif self.factory.scheme == 'https' and self.factory.port != 443:
- host = '%s:%s' % (self.factory.host, self.factory.port)
- else:
- host = self.factory.host
- self.sendHeader('Host', self.factory.headers.get("host", host))
- self.sendHeader('User-Agent', self.factory.agent)
- data = getattr(self.factory, 'postdata', None)
- if data is not None:
- self.sendHeader("Content-Length", str(len(data)))
-
- cookieData = []
- for (key, value) in self.factory.headers.items():
- if key.lower() not in self._specialHeaders:
- # we calculated it on our own
- self.sendHeader(key, value)
- if key.lower() == 'cookie':
- cookieData.append(value)
- for cookie, cookval in self.factory.cookies.items():
- cookieData.append('%s=%s' % (cookie, cookval))
- if cookieData:
- self.sendHeader('Cookie', '; '.join(cookieData))
- self.endHeaders()
- self.headers = {}
-
- if data is not None:
- self.transport.write(data)
-
- def handleHeader(self, key, value):
- """
- Called every time a header is received. Stores the header information
- as key-value pairs in the C{headers} attribute.
-
- @type key: C{str}
- @param key: An HTTP header field name.
-
- @type value: C{str}
- @param value: An HTTP header field value.
- """
- key = key.lower()
- l = self.headers.setdefault(key, [])
- l.append(value)
-
- def handleStatus(self, version, status, message):
- self.version, self.status, self.message = version, status, message
- self.factory.gotStatus(version, status, message)
-
- def handleEndHeaders(self):
- self.factory.gotHeaders(self.headers)
- m = getattr(self, 'handleStatus_'+self.status, self.handleStatusDefault)
- m()
-
- def handleStatus_200(self):
- pass
-
- handleStatus_201 = lambda self: self.handleStatus_200()
- handleStatus_202 = lambda self: self.handleStatus_200()
-
- def handleStatusDefault(self):
- self.failed = 1
-
- def handleStatus_301(self):
- l = self.headers.get('location')
- if not l:
- self.handleStatusDefault()
- return
- url = l[0]
- if self.followRedirect:
- scheme, host, port, path = \
- _parse(url, defaultPort=self.transport.getPeer().port)
-
- self.factory._redirectCount += 1
- if self.factory._redirectCount >= self.factory.redirectLimit:
- err = error.InfiniteRedirection(
- self.status,
- 'Infinite redirection detected',
- location=url)
- self.factory.noPage(failure.Failure(err))
- self.quietLoss = True
- self.transport.loseConnection()
- return
-
- self._completelyDone = False
- self.factory.setURL(url)
-
- if self.factory.scheme == 'https':
- from twisted.internet import ssl
- contextFactory = ssl.ClientContextFactory()
- reactor.connectSSL(self.factory.host, self.factory.port,
- self.factory, contextFactory)
- else:
- reactor.connectTCP(self.factory.host, self.factory.port,
- self.factory)
- else:
- self.handleStatusDefault()
- self.factory.noPage(
- failure.Failure(
- error.PageRedirect(
- self.status, self.message, location = url)))
- self.quietLoss = True
- self.transport.loseConnection()
-
- def handleStatus_302(self):
- if self.afterFoundGet:
- self.handleStatus_303()
- else:
- self.handleStatus_301()
-
-
- def handleStatus_303(self):
- self.factory.method = 'GET'
- self.handleStatus_301()
-
-
- def connectionLost(self, reason):
- """
- When the connection used to issue the HTTP request is closed, notify the
- factory if we have not already, so it can produce a result.
- """
- if not self.quietLoss:
- http.HTTPClient.connectionLost(self, reason)
- self.factory.noPage(reason)
- if self._completelyDone:
- # Only if we think we're completely done do we tell the factory that
- # we're "disconnected". This way when we're following redirects,
- # only the last protocol used will fire the _disconnectedDeferred.
- self.factory._disconnectedDeferred.callback(None)
-
-
- def handleResponse(self, response):
- if self.quietLoss:
- return
- if self.failed:
- self.factory.noPage(
- failure.Failure(
- error.Error(
- self.status, self.message, response)))
- if self.factory.method == 'HEAD':
- # Callback with empty string, since there is never a response
- # body for HEAD requests.
- self.factory.page('')
- elif self.length != None and self.length != 0:
- self.factory.noPage(failure.Failure(
- PartialDownloadError(self.status, self.message, response)))
- else:
- self.factory.page(response)
- # server might be stupid and not close connection. admittedly
- # the fact we do only one request per connection is also
- # stupid...
- self.transport.loseConnection()
-
- def timeout(self):
- self.quietLoss = True
- self.transport.loseConnection()
- self.factory.noPage(defer.TimeoutError("Getting %s took longer than %s seconds." % (self.factory.url, self.factory.timeout)))
-
-
-class HTTPPageDownloader(HTTPPageGetter):
-
- transmittingPage = 0
-
- def handleStatus_200(self, partialContent=0):
- HTTPPageGetter.handleStatus_200(self)
- self.transmittingPage = 1
- self.factory.pageStart(partialContent)
-
- def handleStatus_206(self):
- self.handleStatus_200(partialContent=1)
-
- def handleResponsePart(self, data):
- if self.transmittingPage:
- self.factory.pagePart(data)
-
- def handleResponseEnd(self):
- if self.length:
- self.transmittingPage = 0
- self.factory.noPage(
- failure.Failure(
- PartialDownloadError(self.status)))
- if self.transmittingPage:
- self.factory.pageEnd()
- self.transmittingPage = 0
- if self.failed:
- self.factory.noPage(
- failure.Failure(
- error.Error(
- self.status, self.message, None)))
- self.transport.loseConnection()
-
-
-class HTTPClientFactory(protocol.ClientFactory):
- """Download a given URL.
-
- @type deferred: Deferred
- @ivar deferred: A Deferred that will fire when the content has
- been retrieved. Once this is fired, the ivars `status', `version',
- and `message' will be set.
-
- @type status: str
- @ivar status: The status of the response.
-
- @type version: str
- @ivar version: The version of the response.
-
- @type message: str
- @ivar message: The text message returned with the status.
-
- @type response_headers: dict
- @ivar response_headers: The headers that were specified in the
- response from the server.
-
- @type method: str
- @ivar method: The HTTP method to use in the request. This should be one of
- OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, or CONNECT (case
- matters). Other values may be specified if the server being contacted
- supports them.
-
- @type redirectLimit: int
- @ivar redirectLimit: The maximum number of HTTP redirects that can occur
- before it is assumed that the redirection is endless.
-
- @type afterFoundGet: C{bool}
- @ivar afterFoundGet: Deviate from the HTTP 1.1 RFC by handling redirects
- the same way as most web browsers; if the request method is POST and a
- 302 status is encountered, the redirect is followed with a GET method
-
- @type _redirectCount: int
- @ivar _redirectCount: The current number of HTTP redirects encountered.
-
- @ivar _disconnectedDeferred: A L{Deferred} which only fires after the last
- connection associated with the request (redirects may cause multiple
- connections to be required) has closed. The result Deferred will only
- fire after this Deferred, so that callers can be assured that there are
- no more event sources in the reactor once they get the result.
- """
-
- protocol = HTTPPageGetter
-
- url = None
- scheme = None
- host = ''
- port = None
- path = None
-
- def __init__(self, url, method='GET', postdata=None, headers=None,
- agent="Twisted PageGetter", timeout=0, cookies=None,
- followRedirect=True, redirectLimit=20,
- afterFoundGet=False):
- self.followRedirect = followRedirect
- self.redirectLimit = redirectLimit
- self._redirectCount = 0
- self.timeout = timeout
- self.agent = agent
- self.afterFoundGet = afterFoundGet
- if cookies is None:
- cookies = {}
- self.cookies = cookies
- if headers is not None:
- self.headers = InsensitiveDict(headers)
- else:
- self.headers = InsensitiveDict()
- if postdata is not None:
- self.headers.setdefault('Content-Length', len(postdata))
- # just in case a broken http/1.1 decides to keep connection alive
- self.headers.setdefault("connection", "close")
- self.postdata = postdata
- self.method = method
-
- self.setURL(url)
-
- self.waiting = 1
- self._disconnectedDeferred = defer.Deferred()
- self.deferred = defer.Deferred()
- # Make sure the first callback on the result Deferred pauses the
- # callback chain until the request connection is closed.
- self.deferred.addBoth(self._waitForDisconnect)
- self.response_headers = None
-
-
- def _waitForDisconnect(self, passthrough):
- """
- Chain onto the _disconnectedDeferred, preserving C{passthrough}, so that
- the result is only available after the associated connection has been
- closed.
- """
- self._disconnectedDeferred.addCallback(lambda ignored: passthrough)
- return self._disconnectedDeferred
-
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.url)
-
- def setURL(self, url):
- self.url = url
- scheme, host, port, path = _parse(url)
- if scheme and host:
- self.scheme = scheme
- self.host = host
- self.port = port
- self.path = path
-
- def buildProtocol(self, addr):
- p = protocol.ClientFactory.buildProtocol(self, addr)
- p.followRedirect = self.followRedirect
- p.afterFoundGet = self.afterFoundGet
- if self.timeout:
- timeoutCall = reactor.callLater(self.timeout, p.timeout)
- self.deferred.addBoth(self._cancelTimeout, timeoutCall)
- return p
-
- def _cancelTimeout(self, result, timeoutCall):
- if timeoutCall.active():
- timeoutCall.cancel()
- return result
-
- def gotHeaders(self, headers):
- self.response_headers = headers
- if 'set-cookie' in headers:
- for cookie in headers['set-cookie']:
- cookparts = cookie.split(';')
- cook = cookparts[0]
- cook.lstrip()
- k, v = cook.split('=', 1)
- self.cookies[k.lstrip()] = v.lstrip()
-
- def gotStatus(self, version, status, message):
- self.version, self.status, self.message = version, status, message
-
- def page(self, page):
- if self.waiting:
- self.waiting = 0
- self.deferred.callback(page)
-
- def noPage(self, reason):
- if self.waiting:
- self.waiting = 0
- self.deferred.errback(reason)
-
- def clientConnectionFailed(self, _, reason):
- """
- When a connection attempt fails, the request cannot be issued. If no
- result has yet been provided to the result Deferred, provide the
- connection failure reason as an error result.
- """
- if self.waiting:
- self.waiting = 0
- # If the connection attempt failed, there is nothing more to
- # disconnect, so just fire that Deferred now.
- self._disconnectedDeferred.callback(None)
- self.deferred.errback(reason)
-
-
-
-class HTTPDownloader(HTTPClientFactory):
- """Download to a file."""
-
- protocol = HTTPPageDownloader
- value = None
-
- def __init__(self, url, fileOrName,
- method='GET', postdata=None, headers=None,
- agent="Twisted client", supportPartial=0,
- timeout=0, cookies=None, followRedirect=1,
- redirectLimit=20, afterFoundGet=False):
- self.requestedPartial = 0
- if isinstance(fileOrName, types.StringTypes):
- self.fileName = fileOrName
- self.file = None
- if supportPartial and os.path.exists(self.fileName):
- fileLength = os.path.getsize(self.fileName)
- if fileLength:
- self.requestedPartial = fileLength
- if headers == None:
- headers = {}
- headers["range"] = "bytes=%d-" % fileLength
- else:
- self.file = fileOrName
- HTTPClientFactory.__init__(
- self, url, method=method, postdata=postdata, headers=headers,
- agent=agent, timeout=timeout, cookies=cookies,
- followRedirect=followRedirect, redirectLimit=redirectLimit,
- afterFoundGet=afterFoundGet)
-
-
- def gotHeaders(self, headers):
- HTTPClientFactory.gotHeaders(self, headers)
- if self.requestedPartial:
- contentRange = headers.get("content-range", None)
- if not contentRange:
- # server doesn't support partial requests, oh well
- self.requestedPartial = 0
- return
- start, end, realLength = http.parseContentRange(contentRange[0])
- if start != self.requestedPartial:
- # server is acting wierdly
- self.requestedPartial = 0
-
-
- def openFile(self, partialContent):
- if partialContent:
- file = open(self.fileName, 'rb+')
- file.seek(0, 2)
- else:
- file = open(self.fileName, 'wb')
- return file
-
- def pageStart(self, partialContent):
- """Called on page download start.
-
- @param partialContent: tells us if the download is partial download we requested.
- """
- if partialContent and not self.requestedPartial:
- raise ValueError, "we shouldn't get partial content response if we didn't want it!"
- if self.waiting:
- try:
- if not self.file:
- self.file = self.openFile(partialContent)
- except IOError:
- #raise
- self.deferred.errback(failure.Failure())
-
- def pagePart(self, data):
- if not self.file:
- return
- try:
- self.file.write(data)
- except IOError:
- #raise
- self.file = None
- self.deferred.errback(failure.Failure())
-
-
- def noPage(self, reason):
- """
- Close the storage file and errback the waiting L{Deferred} with the
- given reason.
- """
- if self.waiting:
- self.waiting = 0
- if self.file:
- try:
- self.file.close()
- except:
- log.err(None, "Error closing HTTPDownloader file")
- self.deferred.errback(reason)
-
-
- def pageEnd(self):
- self.waiting = 0
- if not self.file:
- return
- try:
- self.file.close()
- except IOError:
- self.deferred.errback(failure.Failure())
- return
- self.deferred.callback(self.value)
-
-
-
-class _URL(tuple):
- """
- A parsed URL.
-
- At some point this should be replaced with a better URL implementation.
- """
- def __new__(self, scheme, host, port, path):
- return tuple.__new__(_URL, (scheme, host, port, path))
-
-
- def __init__(self, scheme, host, port, path):
- self.scheme = scheme
- self.host = host
- self.port = port
- self.path = path
-
-
-def _parse(url, defaultPort=None):
- """
- Split the given URL into the scheme, host, port, and path.
-
- @type url: C{str}
- @param url: An URL to parse.
-
- @type defaultPort: C{int} or C{None}
- @param defaultPort: An alternate value to use as the port if the URL does
- not include one.
-
- @return: A four-tuple of the scheme, host, port, and path of the URL. All
- of these are C{str} instances except for port, which is an C{int}.
- """
- url = url.strip()
- parsed = http.urlparse(url)
- scheme = parsed[0]
- path = urlunparse(('', '') + parsed[2:])
-
- if defaultPort is None:
- if scheme == 'https':
- defaultPort = 443
- else:
- defaultPort = 80
-
- host, port = parsed[1], defaultPort
- if ':' in host:
- host, port = host.split(':')
- try:
- port = int(port)
- except ValueError:
- port = defaultPort
-
- if path == '':
- path = '/'
-
- return _URL(scheme, host, port, path)
-
-
-def _makeGetterFactory(url, factoryFactory, contextFactory=None,
- *args, **kwargs):
- """
- Create and connect an HTTP page getting factory.
-
- Any additional positional or keyword arguments are used when calling
- C{factoryFactory}.
-
- @param factoryFactory: Factory factory that is called with C{url}, C{args}
- and C{kwargs} to produce the getter
-
- @param contextFactory: Context factory to use when creating a secure
- connection, defaulting to C{None}
-
- @return: The factory created by C{factoryFactory}
- """
- scheme, host, port, path = _parse(url)
- factory = factoryFactory(url, *args, **kwargs)
- if scheme == 'https':
- from twisted.internet import ssl
- if contextFactory is None:
- contextFactory = ssl.ClientContextFactory()
- reactor.connectSSL(host, port, factory, contextFactory)
- else:
- reactor.connectTCP(host, port, factory)
- return factory
-
-
-def getPage(url, contextFactory=None, *args, **kwargs):
- """
- Download a web page as a string.
-
- Download a page. Return a deferred, which will callback with a
- page (as a string) or errback with a description of the error.
-
- See L{HTTPClientFactory} to see what extra arguments can be passed.
- """
- return _makeGetterFactory(
- url,
- HTTPClientFactory,
- contextFactory=contextFactory,
- *args, **kwargs).deferred
-
-
-def downloadPage(url, file, contextFactory=None, *args, **kwargs):
- """
- Download a web page to a file.
-
- @param file: path to file on filesystem, or file-like object.
-
- See HTTPDownloader to see what extra args can be passed.
- """
- factoryFactory = lambda url, *a, **kw: HTTPDownloader(url, file, *a, **kw)
- return _makeGetterFactory(
- url,
- factoryFactory,
- contextFactory=contextFactory,
- *args, **kwargs).deferred
-
-
-# The code which follows is based on the new HTTP client implementation. It
-# should be significantly better than anything above, though it is not yet
-# feature equivalent.
-
-from twisted.web.error import SchemeNotSupported
-from twisted.web._newclient import Request, Response, HTTP11ClientProtocol
-from twisted.web._newclient import ResponseDone, ResponseFailed
-from twisted.web._newclient import RequestNotSent, RequestTransmissionFailed
-from twisted.web._newclient import ResponseNeverReceived
-
-try:
- from twisted.internet.ssl import ClientContextFactory
-except ImportError:
- class WebClientContextFactory(object):
- """
- A web context factory which doesn't work because the necessary SSL
- support is missing.
- """
- def getContext(self, hostname, port):
- raise NotImplementedError("SSL support unavailable")
-else:
- class WebClientContextFactory(ClientContextFactory):
- """
- A web context factory which ignores the hostname and port and does no
- certificate verification.
- """
- def getContext(self, hostname, port):
- return ClientContextFactory.getContext(self)
-
-
-
-class _WebToNormalContextFactory(object):
- """
- Adapt a web context factory to a normal context factory.
-
- @ivar _webContext: A web context factory which accepts a hostname and port
- number to its C{getContext} method.
-
- @ivar _hostname: The hostname which will be passed to
- C{_webContext.getContext}.
-
- @ivar _port: The port number which will be passed to
- C{_webContext.getContext}.
- """
- def __init__(self, webContext, hostname, port):
- self._webContext = webContext
- self._hostname = hostname
- self._port = port
-
-
- def getContext(self):
- """
- Called the wrapped web context factory's C{getContext} method with a
- hostname and port number and return the resulting context object.
- """
- return self._webContext.getContext(self._hostname, self._port)
-
-
-
-class FileBodyProducer(object):
- """
- L{FileBodyProducer} produces bytes from an input file object incrementally
- and writes them to a consumer.
-
- Since file-like objects cannot be read from in an event-driven manner,
- L{FileBodyProducer} uses a L{Cooperator} instance to schedule reads from
- the file. This process is also paused and resumed based on notifications
- from the L{IConsumer} provider being written to.
-
- The file is closed after it has been read, or if the producer is stopped
- early.
-
- @ivar _inputFile: Any file-like object, bytes read from which will be
- written to a consumer.
-
- @ivar _cooperate: A method like L{Cooperator.cooperate} which is used to
- schedule all reads.
-
- @ivar _readSize: The number of bytes to read from C{_inputFile} at a time.
- """
- implements(IBodyProducer)
-
- # Python 2.4 doesn't have these symbolic constants
- _SEEK_SET = getattr(os, 'SEEK_SET', 0)
- _SEEK_END = getattr(os, 'SEEK_END', 2)
-
- def __init__(self, inputFile, cooperator=task, readSize=2 ** 16):
- self._inputFile = inputFile
- self._cooperate = cooperator.cooperate
- self._readSize = readSize
- self.length = self._determineLength(inputFile)
-
-
- def _determineLength(self, fObj):
- """
- Determine how many bytes can be read out of C{fObj} (assuming it is not
- modified from this point on). If the determination cannot be made,
- return C{UNKNOWN_LENGTH}.
- """
- try:
- seek = fObj.seek
- tell = fObj.tell
- except AttributeError:
- return UNKNOWN_LENGTH
- originalPosition = tell()
- seek(0, self._SEEK_END)
- end = tell()
- seek(originalPosition, self._SEEK_SET)
- return end - originalPosition
-
-
- def stopProducing(self):
- """
- Permanently stop writing bytes from the file to the consumer by
- stopping the underlying L{CooperativeTask}.
- """
- self._inputFile.close()
- self._task.stop()
-
-
- def startProducing(self, consumer):
- """
- Start a cooperative task which will read bytes from the input file and
- write them to C{consumer}. Return a L{Deferred} which fires after all
- bytes have been written.
-
- @param consumer: Any L{IConsumer} provider
- """
- self._task = self._cooperate(self._writeloop(consumer))
- d = self._task.whenDone()
- def maybeStopped(reason):
- # IBodyProducer.startProducing's Deferred isn't support to fire if
- # stopProducing is called.
- reason.trap(task.TaskStopped)
- return defer.Deferred()
- d.addCallbacks(lambda ignored: None, maybeStopped)
- return d
-
-
- def _writeloop(self, consumer):
- """
- Return an iterator which reads one chunk of bytes from the input file
- and writes them to the consumer for each time it is iterated.
- """
- while True:
- bytes = self._inputFile.read(self._readSize)
- if not bytes:
- self._inputFile.close()
- break
- consumer.write(bytes)
- yield None
-
-
- def pauseProducing(self):
- """
- Temporarily suspend copying bytes from the input file to the consumer
- by pausing the L{CooperativeTask} which drives that activity.
- """
- self._task.pause()
-
-
- def resumeProducing(self):
- """
- Undo the effects of a previous C{pauseProducing} and resume copying
- bytes to the consumer by resuming the L{CooperativeTask} which drives
- the write activity.
- """
- self._task.resume()
-
-
-
-class _HTTP11ClientFactory(protocol.Factory):
- """
- A factory for L{HTTP11ClientProtocol}, used by L{HTTPConnectionPool}.
-
- @ivar _quiescentCallback: The quiescent callback to be passed to protocol
- instances, used to return them to the connection pool.
-
- @since: 11.1
- """
- def __init__(self, quiescentCallback):
- self._quiescentCallback = quiescentCallback
-
-
- def buildProtocol(self, addr):
- return HTTP11ClientProtocol(self._quiescentCallback)
-
-
-
-class _RetryingHTTP11ClientProtocol(object):
- """
- A wrapper for L{HTTP11ClientProtocol} that automatically retries requests.
-
- @ivar _clientProtocol: The underlying L{HTTP11ClientProtocol}.
-
- @ivar _newConnection: A callable that creates a new connection for a
- retry.
- """
-
- def __init__(self, clientProtocol, newConnection):
- self._clientProtocol = clientProtocol
- self._newConnection = newConnection
-
-
- def _shouldRetry(self, method, exception, bodyProducer):
- """
- Indicate whether request should be retried.
-
- Only returns C{True} if method is idempotent, no response was
- received, and no body was sent. The latter requirement may be relaxed
- in the future, and PUT added to approved method list.
- """
- if method not in ("GET", "HEAD", "OPTIONS", "DELETE", "TRACE"):
- return False
- if not isinstance(exception, (RequestNotSent, RequestTransmissionFailed,
- ResponseNeverReceived)):
- return False
- if bodyProducer is not None:
- return False
- return True
-
-
- def request(self, request):
- """
- Do a request, and retry once (with a new connection) it it fails in
- a retryable manner.
-
- @param request: A L{Request} instance that will be requested using the
- wrapped protocol.
- """
- d = self._clientProtocol.request(request)
-
- def failed(reason):
- if self._shouldRetry(request.method, reason.value,
- request.bodyProducer):
- return self._newConnection().addCallback(
- lambda connection: connection.request(request))
- else:
- return reason
- d.addErrback(failed)
- return d
-
-
-
-class HTTPConnectionPool(object):
- """
- A pool of persistent HTTP connections.
-
- Features:
- - Cached connections will eventually time out.
- - Limits on maximum number of persistent connections.
-
- Connections are stored using keys, which should be chosen such that any
- connections stored under a given key can be used interchangeably.
-
- Failed requests done using previously cached connections will be retried
- once if they use an idempotent method (e.g. GET), in case the HTTP server
- timed them out.
-
- @ivar persistent: Boolean indicating whether connections should be
- persistent. Connections are persistent by default.
-
- @ivar maxPersistentPerHost: The maximum number of cached persistent
- connections for a C{host:port} destination.
- @type maxPersistentPerHost: C{int}
-
- @ivar cachedConnectionTimeout: Number of seconds a cached persistent
- connection will stay open before disconnecting.
-
- @ivar retryAutomatically: C{boolean} indicating whether idempotent
- requests should be retried once if no response was received.
-
- @ivar _factory: The factory used to connect to the proxy.
-
- @ivar _connections: Map (scheme, host, port) to lists of
- L{HTTP11ClientProtocol} instances.
-
- @ivar _timeouts: Map L{HTTP11ClientProtocol} instances to a
- C{IDelayedCall} instance of their timeout.
-
- @since: 12.1
- """
-
- _factory = _HTTP11ClientFactory
- maxPersistentPerHost = 2
- cachedConnectionTimeout = 240
- retryAutomatically = True
-
- def __init__(self, reactor, persistent=True):
- self._reactor = reactor
- self.persistent = persistent
- self._connections = {}
- self._timeouts = {}
-
-
- def getConnection(self, key, endpoint):
- """
- Retrieve a connection, either new or cached, to be used for a HTTP
- request.
-
- If a cached connection is returned, it will not be used for other
- requests until it is put back (which will happen automatically), since
- we do not support pipelined requests. If no cached connection is
- available, the passed in endpoint is used to create the connection.
-
- If the connection doesn't disconnect at the end of its request, it
- will be returned to this pool automatically. As such, only a single
- request should be sent using the returned connection.
-
- @param key: A unique key identifying connections that can be used
- interchangeably.
-
- @param endpoint: An endpoint that can be used to open a new connection
- if no cached connection is available.
-
- @return: A C{Deferred} that will fire with a L{HTTP11ClientProtocol}
- (or a wrapper) that can be used to send a single HTTP request.
- """
- # Try to get cached version:
- connections = self._connections.get(key)
- while connections:
- connection = connections.pop(0)
- # Cancel timeout:
- self._timeouts[connection].cancel()
- del self._timeouts[connection]
- if connection.state == "QUIESCENT":
- if self.retryAutomatically:
- newConnection = lambda: self._newConnection(key, endpoint)
- connection = _RetryingHTTP11ClientProtocol(
- connection, newConnection)
- return defer.succeed(connection)
-
- return self._newConnection(key, endpoint)
-
-
- def _newConnection(self, key, endpoint):
- """
- Create a new connection.
-
- This implements the new connection code path for L{getConnection}.
- """
- def quiescentCallback(protocol):
- self._putConnection(key, protocol)
- factory = self._factory(quiescentCallback)
- return endpoint.connect(factory)
-
-
- def _removeConnection(self, key, connection):
- """
- Remove a connection from the cache and disconnect it.
- """
- connection.transport.loseConnection()
- self._connections[key].remove(connection)
- del self._timeouts[connection]
-
-
- def _putConnection(self, key, connection):
- """
- Return a persistent connection to the pool. This will be called by
- L{HTTP11ClientProtocol} when the connection becomes quiescent.
- """
- if connection.state != "QUIESCENT":
- # Log with traceback for debugging purposes:
- try:
- raise RuntimeError(
- "BUG: Non-quiescent protocol added to connection pool.")
- except:
- log.err()
- return
- connections = self._connections.setdefault(key, [])
- if len(connections) == self.maxPersistentPerHost:
- dropped = connections.pop(0)
- dropped.transport.loseConnection()
- self._timeouts[dropped].cancel()
- del self._timeouts[dropped]
- connections.append(connection)
- cid = self._reactor.callLater(self.cachedConnectionTimeout,
- self._removeConnection,
- key, connection)
- self._timeouts[connection] = cid
-
-
- def closeCachedConnections(self):
- """
- Close all persistent connections and remove them from the pool.
-
- @return: L{defer.Deferred} that fires when all connections have been
- closed.
- """
- results = []
- for protocols in self._connections.itervalues():
- for p in protocols:
- results.append(p.abort())
- self._connections = {}
- for dc in self._timeouts.values():
- dc.cancel()
- self._timeouts = {}
- return defer.gatherResults(results).addCallback(lambda ign: None)
-
-
-
-class _AgentBase(object):
- """
- Base class offering common facilities for L{Agent}-type classes.
-
- @ivar _reactor: The C{IReactorTime} implementation which will be used by
- the pool, and perhaps by subclasses as well.
-
- @ivar _pool: The L{HTTPConnectionPool} used to manage HTTP connections.
- """
-
- def __init__(self, reactor, pool):
- if pool is None:
- pool = HTTPConnectionPool(reactor, False)
- self._reactor = reactor
- self._pool = pool
-
-
- def _computeHostValue(self, scheme, host, port):
- """
- Compute the string to use for the value of the I{Host} header, based on
- the given scheme, host name, and port number.
- """
- if (scheme, port) in (('http', 80), ('https', 443)):
- return host
- return '%s:%d' % (host, port)
-
-
- def _requestWithEndpoint(self, key, endpoint, method, parsedURI,
- headers, bodyProducer, requestPath):
- """
- Issue a new request, given the endpoint and the path sent as part of
- the request.
- """
- # Create minimal headers, if necessary:
- if headers is None:
- headers = Headers()
- if not headers.hasHeader('host'):
- headers = headers.copy()
- headers.addRawHeader(
- 'host', self._computeHostValue(parsedURI.scheme, parsedURI.host,
- parsedURI.port))
-
- d = self._pool.getConnection(key, endpoint)
- def cbConnected(proto):
- return proto.request(
- Request(method, requestPath, headers, bodyProducer,
- persistent=self._pool.persistent))
- d.addCallback(cbConnected)
- return d
-
-
-
-class Agent(_AgentBase):
- """
- L{Agent} is a very basic HTTP client. It supports I{HTTP} and I{HTTPS}
- scheme URIs (but performs no certificate checking by default).
-
- @param pool: A L{HTTPConnectionPool} instance, or C{None}, in which case a
- non-persistent L{HTTPConnectionPool} instance will be created.
-
- @ivar _contextFactory: A web context factory which will be used to create
- SSL context objects for any SSL connections the agent needs to make.
-
- @ivar _connectTimeout: If not C{None}, the timeout passed to C{connectTCP}
- or C{connectSSL} for specifying the connection timeout.
-
- @ivar _bindAddress: If not C{None}, the address passed to C{connectTCP} or
- C{connectSSL} for specifying the local address to bind to.
-
- @since: 9.0
- """
-
- def __init__(self, reactor, contextFactory=WebClientContextFactory(),
- connectTimeout=None, bindAddress=None,
- pool=None):
- _AgentBase.__init__(self, reactor, pool)
- self._contextFactory = contextFactory
- self._connectTimeout = connectTimeout
- self._bindAddress = bindAddress
-
-
- def _wrapContextFactory(self, host, port):
- """
- Create and return a normal context factory wrapped around
- C{self._contextFactory} in such a way that C{self._contextFactory} will
- have the host and port information passed to it.
-
- @param host: A C{str} giving the hostname which will be connected to in
- order to issue a request.
-
- @param port: An C{int} giving the port number the connection will be
- on.
-
- @return: A context factory suitable to be passed to
- C{reactor.connectSSL}.
- """
- return _WebToNormalContextFactory(self._contextFactory, host, port)
-
-
- def _getEndpoint(self, scheme, host, port):
- """
- Get an endpoint for the given host and port, using a transport
- selected based on scheme.
-
- @param scheme: A string like C{'http'} or C{'https'} (the only two
- supported values) to use to determine how to establish the
- connection.
-
- @param host: A C{str} giving the hostname which will be connected to in
- order to issue a request.
-
- @param port: An C{int} giving the port number the connection will be
- on.
-
- @return: An endpoint which can be used to connect to given address.
- """
- kwargs = {}
- if self._connectTimeout is not None:
- kwargs['timeout'] = self._connectTimeout
- kwargs['bindAddress'] = self._bindAddress
- if scheme == 'http':
- return TCP4ClientEndpoint(self._reactor, host, port, **kwargs)
- elif scheme == 'https':
- return SSL4ClientEndpoint(self._reactor, host, port,
- self._wrapContextFactory(host, port),
- **kwargs)
- else:
- raise SchemeNotSupported("Unsupported scheme: %r" % (scheme,))
-
-
- def request(self, method, uri, headers=None, bodyProducer=None):
- """
- Issue a new request.
-
- @param method: The request method to send.
- @type method: C{str}
-
- @param uri: The request URI send.
- @type uri: C{str}
-
- @param headers: The request headers to send. If no I{Host} header is
- included, one will be added based on the request URI.
- @type headers: L{Headers}
-
- @param bodyProducer: An object which will produce the request body or,
- if the request body is to be empty, L{None}.
- @type bodyProducer: L{IBodyProducer} provider
-
- @return: A L{Deferred} which fires with the result of the request (a
- L{twisted.web.iweb.IResponse} provider), or fails if there is a
- problem setting up a connection over which to issue the request.
- It may also fail with L{SchemeNotSupported} if the scheme of the
- given URI is not supported.
- @rtype: L{Deferred}
- """
- parsedURI = _parse(uri)
- try:
- endpoint = self._getEndpoint(parsedURI.scheme, parsedURI.host,
- parsedURI.port)
- except SchemeNotSupported:
- return defer.fail(Failure())
- key = (parsedURI.scheme, parsedURI.host, parsedURI.port)
- return self._requestWithEndpoint(key, endpoint, method, parsedURI,
- headers, bodyProducer, parsedURI.path)
-
-
-
-class ProxyAgent(_AgentBase):
- """
- An HTTP agent able to cross HTTP proxies.
-
- @ivar _proxyEndpoint: The endpoint used to connect to the proxy.
-
- @since: 11.1
- """
-
- def __init__(self, endpoint, reactor=None, pool=None):
- if reactor is None:
- from twisted.internet import reactor
- _AgentBase.__init__(self, reactor, pool)
- self._proxyEndpoint = endpoint
-
-
- def request(self, method, uri, headers=None, bodyProducer=None):
- """
- Issue a new request via the configured proxy.
- """
- # Cache *all* connections under the same key, since we are only
- # connecting to a single destination, the proxy:
- key = ("http-proxy", self._proxyEndpoint)
-
- # To support proxying HTTPS via CONNECT, we will use key
- # ("http-proxy-CONNECT", scheme, host, port), and an endpoint that
- # wraps _proxyEndpoint with an additional callback to do the CONNECT.
- return self._requestWithEndpoint(key, self._proxyEndpoint, method,
- _parse(uri), headers, bodyProducer,
- uri)
-
-
-
-class _FakeUrllib2Request(object):
- """
- A fake C{urllib2.Request} object for C{cookielib} to work with.
-
- @see: U{http://docs.python.org/library/urllib2.html#request-objects}
-
- @type uri: C{str}
- @ivar uri: Request URI.
-
- @type headers: L{twisted.web.http_headers.Headers}
- @ivar headers: Request headers.
-
- @type type: C{str}
- @ivar type: The scheme of the URI.
-
- @type host: C{str}
- @ivar host: The host[:port] of the URI.
-
- @since: 11.1
- """
- def __init__(self, uri):
- self.uri = uri
- self.headers = Headers()
- self.type, rest = splittype(self.uri)
- self.host, rest = splithost(rest)
-
-
- def has_header(self, header):
- return self.headers.hasHeader(header)
-
-
- def add_unredirected_header(self, name, value):
- self.headers.addRawHeader(name, value)
-
-
- def get_full_url(self):
- return self.uri
-
-
- def get_header(self, name, default=None):
- headers = self.headers.getRawHeaders(name, default)
- if headers is not None:
- return headers[0]
- return None
-
-
- def get_host(self):
- return self.host
-
-
- def get_type(self):
- return self.type
-
-
- def is_unverifiable(self):
- # In theory this shouldn't be hardcoded.
- return False
-
-
-
-class _FakeUrllib2Response(object):
- """
- A fake C{urllib2.Response} object for C{cookielib} to work with.
-
- @type response: C{twisted.web.iweb.IResponse}
- @ivar response: Underlying Twisted Web response.
-
- @since: 11.1
- """
- def __init__(self, response):
- self.response = response
-
-
- def info(self):
- class _Meta(object):
- def getheaders(zelf, name):
- return self.response.headers.getRawHeaders(name, [])
- return _Meta()
-
-
-
-class CookieAgent(object):
- """
- L{CookieAgent} extends the basic L{Agent} to add RFC-compliant
- handling of HTTP cookies. Cookies are written to and extracted
- from a C{cookielib.CookieJar} instance.
-
- The same cookie jar instance will be used for any requests through this
- agent, mutating it whenever a I{Set-Cookie} header appears in a response.
-
- @type _agent: L{twisted.web.client.Agent}
- @ivar _agent: Underlying Twisted Web agent to issue requests through.
-
- @type cookieJar: C{cookielib.CookieJar}
- @ivar cookieJar: Initialized cookie jar to read cookies from and store
- cookies to.
-
- @since: 11.1
- """
- def __init__(self, agent, cookieJar):
- self._agent = agent
- self.cookieJar = cookieJar
-
-
- def request(self, method, uri, headers=None, bodyProducer=None):
- """
- Issue a new request to the wrapped L{Agent}.
-
- Send a I{Cookie} header if a cookie for C{uri} is stored in
- L{CookieAgent.cookieJar}. Cookies are automatically extracted and
- stored from requests.
-
- If a C{'cookie'} header appears in C{headers} it will override the
- automatic cookie header obtained from the cookie jar.
-
- @see: L{Agent.request}
- """
- if headers is None:
- headers = Headers()
- lastRequest = _FakeUrllib2Request(uri)
- # Setting a cookie header explicitly will disable automatic request
- # cookies.
- if not headers.hasHeader('cookie'):
- self.cookieJar.add_cookie_header(lastRequest)
- cookieHeader = lastRequest.get_header('Cookie', None)
- if cookieHeader is not None:
- headers = headers.copy()
- headers.addRawHeader('cookie', cookieHeader)
-
- d = self._agent.request(method, uri, headers, bodyProducer)
- d.addCallback(self._extractCookies, lastRequest)
- return d
-
-
- def _extractCookies(self, response, request):
- """
- Extract response cookies and store them in the cookie jar.
-
- @type response: L{twisted.web.iweb.IResponse}
- @param response: Twisted Web response.
-
- @param request: A urllib2 compatible request object.
- """
- resp = _FakeUrllib2Response(response)
- self.cookieJar.extract_cookies(resp, request)
- return response
-
-
-
-class GzipDecoder(proxyForInterface(IResponse)):
- """
- A wrapper for a L{Response} instance which handles gzip'ed body.
-
- @ivar original: The original L{Response} object.
-
- @since: 11.1
- """
-
- def __init__(self, response):
- self.original = response
- self.length = UNKNOWN_LENGTH
-
-
- def deliverBody(self, protocol):
- """
- Override C{deliverBody} to wrap the given C{protocol} with
- L{_GzipProtocol}.
- """
- self.original.deliverBody(_GzipProtocol(protocol, self.original))
-
-
-
-class _GzipProtocol(proxyForInterface(IProtocol)):
- """
- A L{Protocol} implementation which wraps another one, transparently
- decompressing received data.
-
- @ivar _zlibDecompress: A zlib decompress object used to decompress the data
- stream.
-
- @ivar _response: A reference to the original response, in case of errors.
-
- @since: 11.1
- """
-
- def __init__(self, protocol, response):
- self.original = protocol
- self._response = response
- self._zlibDecompress = zlib.decompressobj(16 + zlib.MAX_WBITS)
-
-
- def dataReceived(self, data):
- """
- Decompress C{data} with the zlib decompressor, forwarding the raw data
- to the original protocol.
- """
- try:
- rawData = self._zlibDecompress.decompress(data)
- except zlib.error:
- raise ResponseFailed([failure.Failure()], self._response)
- if rawData:
- self.original.dataReceived(rawData)
-
-
- def connectionLost(self, reason):
- """
- Forward the connection lost event, flushing remaining data from the
- decompressor if any.
- """
- try:
- rawData = self._zlibDecompress.flush()
- except zlib.error:
- raise ResponseFailed([reason, failure.Failure()], self._response)
- if rawData:
- self.original.dataReceived(rawData)
- self.original.connectionLost(reason)
-
-
-
-class ContentDecoderAgent(object):
- """
- An L{Agent} wrapper to handle encoded content.
-
- It takes care of declaring the support for content in the
- I{Accept-Encoding} header, and automatically decompresses the received data
- if it's effectively using compression.
-
- @param decoders: A list or tuple of (name, decoder) objects. The name
- declares which decoding the decoder supports, and the decoder must
- return a response object when called/instantiated. For example,
- C{(('gzip', GzipDecoder))}. The order determines how the decoders are
- going to be advertized to the server.
-
- @since: 11.1
- """
-
- def __init__(self, agent, decoders):
- self._agent = agent
- self._decoders = dict(decoders)
- self._supported = ','.join([decoder[0] for decoder in decoders])
-
-
- def request(self, method, uri, headers=None, bodyProducer=None):
- """
- Send a client request which declares supporting compressed content.
-
- @see: L{Agent.request}.
- """
- if headers is None:
- headers = Headers()
- else:
- headers = headers.copy()
- headers.addRawHeader('accept-encoding', self._supported)
- deferred = self._agent.request(method, uri, headers, bodyProducer)
- return deferred.addCallback(self._handleResponse)
-
-
- def _handleResponse(self, response):
- """
- Check if the response is encoded, and wrap it to handle decompression.
- """
- contentEncodingHeaders = response.headers.getRawHeaders(
- 'content-encoding', [])
- contentEncodingHeaders = ','.join(contentEncodingHeaders).split(',')
- while contentEncodingHeaders:
- name = contentEncodingHeaders.pop().strip()
- decoder = self._decoders.get(name)
- if decoder is not None:
- response = decoder(response)
- else:
- # Add it back
- contentEncodingHeaders.append(name)
- break
- if contentEncodingHeaders:
- response.headers.setRawHeaders(
- 'content-encoding', [','.join(contentEncodingHeaders)])
- else:
- response.headers.removeHeader('content-encoding')
- return response
-
-
-
-class RedirectAgent(object):
- """
- An L{Agent} wrapper which handles HTTP redirects.
-
- The implementation is rather strict: 301 and 302 behaves like 307, not
- redirecting automatically on methods different from C{GET} and C{HEAD}.
-
- @param redirectLimit: The maximum number of times the agent is allowed to
- follow redirects before failing with a L{error.InfiniteRedirection}.
-
- @since: 11.1
- """
-
- def __init__(self, agent, redirectLimit=20):
- self._agent = agent
- self._redirectLimit = redirectLimit
-
-
- def request(self, method, uri, headers=None, bodyProducer=None):
- """
- Send a client request following HTTP redirects.
-
- @see: L{Agent.request}.
- """
- deferred = self._agent.request(method, uri, headers, bodyProducer)
- return deferred.addCallback(
- self._handleResponse, method, uri, headers, 0)
-
-
- def _handleRedirect(self, response, method, uri, headers, redirectCount):
- """
- Handle a redirect response, checking the number of redirects already
- followed, and extracting the location header fields.
- """
- if redirectCount >= self._redirectLimit:
- err = error.InfiniteRedirection(
- response.code,
- 'Infinite redirection detected',
- location=uri)
- raise ResponseFailed([failure.Failure(err)], response)
- locationHeaders = response.headers.getRawHeaders('location', [])
- if not locationHeaders:
- err = error.RedirectWithNoLocation(
- response.code, 'No location header field', uri)
- raise ResponseFailed([failure.Failure(err)], response)
- location = locationHeaders[0]
- deferred = self._agent.request(method, location, headers)
- return deferred.addCallback(
- self._handleResponse, method, uri, headers, redirectCount + 1)
-
-
- def _handleResponse(self, response, method, uri, headers, redirectCount):
- """
- Handle the response, making another request if it indicates a redirect.
- """
- if response.code in (http.MOVED_PERMANENTLY, http.FOUND,
- http.TEMPORARY_REDIRECT):
- if method not in ('GET', 'HEAD'):
- err = error.PageRedirect(response.code, location=uri)
- raise ResponseFailed([failure.Failure(err)], response)
- return self._handleRedirect(response, method, uri, headers,
- redirectCount)
- elif response.code == http.SEE_OTHER:
- return self._handleRedirect(response, 'GET', uri, headers,
- redirectCount)
- return response
-
-
-
-__all__ = [
- 'PartialDownloadError', 'HTTPPageGetter', 'HTTPPageDownloader',
- 'HTTPClientFactory', 'HTTPDownloader', 'getPage', 'downloadPage',
- 'ResponseDone', 'Response', 'ResponseFailed', 'Agent', 'CookieAgent',
- 'ProxyAgent', 'ContentDecoderAgent', 'GzipDecoder', 'RedirectAgent',
- 'HTTPConnectionPool']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/demo.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/demo.py
deleted file mode 100755
index b8475f02..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/demo.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-I am a simple test resource.
-"""
-
-from twisted.web import static
-
-
-class Test(static.Data):
- isLeaf = True
- def __init__(self):
- static.Data.__init__(
- self,
- """
- <html>
- <head><title>Twisted Web Demo</title><head>
- <body>
- Hello! This is a Twisted Web test page.
- </body>
- </html>
- """,
- "text/html")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/distrib.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/distrib.py
deleted file mode 100755
index 830675b8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/distrib.py
+++ /dev/null
@@ -1,373 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_distrib -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Distributed web servers.
-
-This is going to have to be refactored so that argument parsing is done
-by each subprocess and not by the main web server (i.e. GET, POST etc.).
-"""
-
-# System Imports
-import types, os, copy, cStringIO
-try:
- import pwd
-except ImportError:
- pwd = None
-
-from xml.dom.minidom import Element, Text
-
-# Twisted Imports
-from twisted.spread import pb
-from twisted.spread.banana import SIZE_LIMIT
-from twisted.web import http, resource, server, html, static
-from twisted.web.http_headers import Headers
-from twisted.python import log
-from twisted.persisted import styles
-from twisted.internet import address, reactor
-
-
-class _ReferenceableProducerWrapper(pb.Referenceable):
- def __init__(self, producer):
- self.producer = producer
-
- def remote_resumeProducing(self):
- self.producer.resumeProducing()
-
- def remote_pauseProducing(self):
- self.producer.pauseProducing()
-
- def remote_stopProducing(self):
- self.producer.stopProducing()
-
-
-class Request(pb.RemoteCopy, server.Request):
- """
- A request which was received by a L{ResourceSubscription} and sent via
- PB to a distributed node.
- """
- def setCopyableState(self, state):
- """
- Initialize this L{twisted.web.distrib.Request} based on the copied
- state so that it closely resembles a L{twisted.web.server.Request}.
- """
- for k in 'host', 'client':
- tup = state[k]
- addrdesc = {'INET': 'TCP', 'UNIX': 'UNIX'}[tup[0]]
- addr = {'TCP': lambda: address.IPv4Address(addrdesc,
- tup[1], tup[2]),
- 'UNIX': lambda: address.UNIXAddress(tup[1])}[addrdesc]()
- state[k] = addr
- state['requestHeaders'] = Headers(dict(state['requestHeaders']))
- pb.RemoteCopy.setCopyableState(self, state)
- # Emulate the local request interface --
- self.content = cStringIO.StringIO(self.content_data)
- self.finish = self.remote.remoteMethod('finish')
- self.setHeader = self.remote.remoteMethod('setHeader')
- self.addCookie = self.remote.remoteMethod('addCookie')
- self.setETag = self.remote.remoteMethod('setETag')
- self.setResponseCode = self.remote.remoteMethod('setResponseCode')
- self.setLastModified = self.remote.remoteMethod('setLastModified')
-
- # To avoid failing if a resource tries to write a very long string
- # all at once, this one will be handled slightly differently.
- self._write = self.remote.remoteMethod('write')
-
-
- def write(self, bytes):
- """
- Write the given bytes to the response body.
-
- @param bytes: The bytes to write. If this is longer than 640k, it
- will be split up into smaller pieces.
- """
- start = 0
- end = SIZE_LIMIT
- while True:
- self._write(bytes[start:end])
- start += SIZE_LIMIT
- end += SIZE_LIMIT
- if start >= len(bytes):
- break
-
-
- def registerProducer(self, producer, streaming):
- self.remote.callRemote("registerProducer",
- _ReferenceableProducerWrapper(producer),
- streaming).addErrback(self.fail)
-
- def unregisterProducer(self):
- self.remote.callRemote("unregisterProducer").addErrback(self.fail)
-
- def fail(self, failure):
- log.err(failure)
-
-
-pb.setUnjellyableForClass(server.Request, Request)
-
-class Issue:
- def __init__(self, request):
- self.request = request
-
- def finished(self, result):
- if result != server.NOT_DONE_YET:
- assert isinstance(result, types.StringType),\
- "return value not a string"
- self.request.write(result)
- self.request.finish()
-
- def failed(self, failure):
- #XXX: Argh. FIXME.
- failure = str(failure)
- self.request.write(
- resource.ErrorPage(http.INTERNAL_SERVER_ERROR,
- "Server Connection Lost",
- "Connection to distributed server lost:" +
- html.PRE(failure)).
- render(self.request))
- self.request.finish()
- log.msg(failure)
-
-
-class ResourceSubscription(resource.Resource):
- isLeaf = 1
- waiting = 0
- def __init__(self, host, port):
- resource.Resource.__init__(self)
- self.host = host
- self.port = port
- self.pending = []
- self.publisher = None
-
- def __getstate__(self):
- """Get persistent state for this ResourceSubscription.
- """
- # When I unserialize,
- state = copy.copy(self.__dict__)
- # Publisher won't be connected...
- state['publisher'] = None
- # I won't be making a connection
- state['waiting'] = 0
- # There will be no pending requests.
- state['pending'] = []
- return state
-
- def connected(self, publisher):
- """I've connected to a publisher; I'll now send all my requests.
- """
- log.msg('connected to publisher')
- publisher.broker.notifyOnDisconnect(self.booted)
- self.publisher = publisher
- self.waiting = 0
- for request in self.pending:
- self.render(request)
- self.pending = []
-
- def notConnected(self, msg):
- """I can't connect to a publisher; I'll now reply to all pending
- requests.
- """
- log.msg("could not connect to distributed web service: %s" % msg)
- self.waiting = 0
- self.publisher = None
- for request in self.pending:
- request.write("Unable to connect to distributed server.")
- request.finish()
- self.pending = []
-
- def booted(self):
- self.notConnected("connection dropped")
-
- def render(self, request):
- """Render this request, from my server.
-
- This will always be asynchronous, and therefore return NOT_DONE_YET.
- It spins off a request to the pb client, and either adds it to the list
- of pending issues or requests it immediately, depending on if the
- client is already connected.
- """
- if not self.publisher:
- self.pending.append(request)
- if not self.waiting:
- self.waiting = 1
- bf = pb.PBClientFactory()
- timeout = 10
- if self.host == "unix":
- reactor.connectUNIX(self.port, bf, timeout)
- else:
- reactor.connectTCP(self.host, self.port, bf, timeout)
- d = bf.getRootObject()
- d.addCallbacks(self.connected, self.notConnected)
-
- else:
- i = Issue(request)
- self.publisher.callRemote('request', request).addCallbacks(i.finished, i.failed)
- return server.NOT_DONE_YET
-
-
-
-class ResourcePublisher(pb.Root, styles.Versioned):
- """
- L{ResourcePublisher} exposes a remote API which can be used to respond
- to request.
-
- @ivar site: The site which will be used for resource lookup.
- @type site: L{twisted.web.server.Site}
- """
- def __init__(self, site):
- self.site = site
-
- persistenceVersion = 2
-
- def upgradeToVersion2(self):
- self.application.authorizer.removeIdentity("web")
- del self.application.services[self.serviceName]
- del self.serviceName
- del self.application
- del self.perspectiveName
-
- def getPerspectiveNamed(self, name):
- return self
-
-
- def remote_request(self, request):
- """
- Look up the resource for the given request and render it.
- """
- res = self.site.getResourceFor(request)
- log.msg( request )
- result = res.render(request)
- if result is not server.NOT_DONE_YET:
- request.write(result)
- request.finish()
- return server.NOT_DONE_YET
-
-
-
-class UserDirectory(resource.Resource):
- """
- A resource which lists available user resources and serves them as
- children.
-
- @ivar _pwd: An object like L{pwd} which is used to enumerate users and
- their home directories.
- """
-
- userDirName = 'public_html'
- userSocketName = '.twistd-web-pb'
-
- template = """
-<html>
- <head>
- <title>twisted.web.distrib.UserDirectory</title>
- <style>
-
- a
- {
- font-family: Lucida, Verdana, Helvetica, Arial, sans-serif;
- color: #369;
- text-decoration: none;
- }
-
- th
- {
- font-family: Lucida, Verdana, Helvetica, Arial, sans-serif;
- font-weight: bold;
- text-decoration: none;
- text-align: left;
- }
-
- pre, code
- {
- font-family: "Courier New", Courier, monospace;
- }
-
- p, body, td, ol, ul, menu, blockquote, div
- {
- font-family: Lucida, Verdana, Helvetica, Arial, sans-serif;
- color: #000;
- }
- </style>
- </head>
-
- <body>
- <h1>twisted.web.distrib.UserDirectory</h1>
-
- %(users)s
-</body>
-</html>
-"""
-
- def __init__(self, userDatabase=None):
- resource.Resource.__init__(self)
- if userDatabase is None:
- userDatabase = pwd
- self._pwd = userDatabase
-
-
- def _users(self):
- """
- Return a list of two-tuples giving links to user resources and text to
- associate with those links.
- """
- users = []
- for user in self._pwd.getpwall():
- name, passwd, uid, gid, gecos, dir, shell = user
- realname = gecos.split(',')[0]
- if not realname:
- realname = name
- if os.path.exists(os.path.join(dir, self.userDirName)):
- users.append((name, realname + ' (file)'))
- twistdsock = os.path.join(dir, self.userSocketName)
- if os.path.exists(twistdsock):
- linkName = name + '.twistd'
- users.append((linkName, realname + ' (twistd)'))
- return users
-
-
- def render_GET(self, request):
- """
- Render as HTML a listing of all known users with links to their
- personal resources.
- """
- listing = Element('ul')
- for link, text in self._users():
- linkElement = Element('a')
- linkElement.setAttribute('href', link + '/')
- textNode = Text()
- textNode.data = text
- linkElement.appendChild(textNode)
- item = Element('li')
- item.appendChild(linkElement)
- listing.appendChild(item)
- return self.template % {'users': listing.toxml()}
-
-
- def getChild(self, name, request):
- if name == '':
- return self
-
- td = '.twistd'
-
- if name[-len(td):] == td:
- username = name[:-len(td)]
- sub = 1
- else:
- username = name
- sub = 0
- try:
- pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell \
- = self._pwd.getpwnam(username)
- except KeyError:
- return resource.NoResource()
- if sub:
- twistdsock = os.path.join(pw_dir, self.userSocketName)
- rs = ResourceSubscription('unix',twistdsock)
- self.putChild(name, rs)
- return rs
- else:
- path = os.path.join(pw_dir, self.userDirName)
- if not os.path.exists(path):
- return resource.NoResource()
- return static.File(path)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/domhelpers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/domhelpers.py
deleted file mode 100755
index e6f1b514..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/domhelpers.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_domhelpers -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A library for performing interesting tasks with DOM objects.
-"""
-
-import StringIO
-
-from twisted.web import microdom
-from twisted.web.microdom import getElementsByTagName, escape, unescape
-
-
-class NodeLookupError(Exception):
- pass
-
-
-def substitute(request, node, subs):
- """
- Look through the given node's children for strings, and
- attempt to do string substitution with the given parameter.
- """
- for child in node.childNodes:
- if hasattr(child, 'nodeValue') and child.nodeValue:
- child.replaceData(0, len(child.nodeValue), child.nodeValue % subs)
- substitute(request, child, subs)
-
-def _get(node, nodeId, nodeAttrs=('id','class','model','pattern')):
- """
- (internal) Get a node with the specified C{nodeId} as any of the C{class},
- C{id} or C{pattern} attributes.
- """
-
- if hasattr(node, 'hasAttributes') and node.hasAttributes():
- for nodeAttr in nodeAttrs:
- if (str (node.getAttribute(nodeAttr)) == nodeId):
- return node
- if node.hasChildNodes():
- if hasattr(node.childNodes, 'length'):
- length = node.childNodes.length
- else:
- length = len(node.childNodes)
- for childNum in range(length):
- result = _get(node.childNodes[childNum], nodeId)
- if result: return result
-
-def get(node, nodeId):
- """
- Get a node with the specified C{nodeId} as any of the C{class},
- C{id} or C{pattern} attributes. If there is no such node, raise
- L{NodeLookupError}.
- """
- result = _get(node, nodeId)
- if result: return result
- raise NodeLookupError, nodeId
-
-def getIfExists(node, nodeId):
- """
- Get a node with the specified C{nodeId} as any of the C{class},
- C{id} or C{pattern} attributes. If there is no such node, return
- C{None}.
- """
- return _get(node, nodeId)
-
-def getAndClear(node, nodeId):
- """Get a node with the specified C{nodeId} as any of the C{class},
- C{id} or C{pattern} attributes. If there is no such node, raise
- L{NodeLookupError}. Remove all child nodes before returning.
- """
- result = get(node, nodeId)
- if result:
- clearNode(result)
- return result
-
-def clearNode(node):
- """
- Remove all children from the given node.
- """
- node.childNodes[:] = []
-
-def locateNodes(nodeList, key, value, noNesting=1):
- """
- Find subnodes in the given node where the given attribute
- has the given value.
- """
- returnList = []
- if not isinstance(nodeList, type([])):
- return locateNodes(nodeList.childNodes, key, value, noNesting)
- for childNode in nodeList:
- if not hasattr(childNode, 'getAttribute'):
- continue
- if str(childNode.getAttribute(key)) == value:
- returnList.append(childNode)
- if noNesting:
- continue
- returnList.extend(locateNodes(childNode, key, value, noNesting))
- return returnList
-
-def superSetAttribute(node, key, value):
- if not hasattr(node, 'setAttribute'): return
- node.setAttribute(key, value)
- if node.hasChildNodes():
- for child in node.childNodes:
- superSetAttribute(child, key, value)
-
-def superPrependAttribute(node, key, value):
- if not hasattr(node, 'setAttribute'): return
- old = node.getAttribute(key)
- if old:
- node.setAttribute(key, value+'/'+old)
- else:
- node.setAttribute(key, value)
- if node.hasChildNodes():
- for child in node.childNodes:
- superPrependAttribute(child, key, value)
-
-def superAppendAttribute(node, key, value):
- if not hasattr(node, 'setAttribute'): return
- old = node.getAttribute(key)
- if old:
- node.setAttribute(key, old + '/' + value)
- else:
- node.setAttribute(key, value)
- if node.hasChildNodes():
- for child in node.childNodes:
- superAppendAttribute(child, key, value)
-
-def gatherTextNodes(iNode, dounescape=0, joinWith=""):
- """Visit each child node and collect its text data, if any, into a string.
-For example::
- >>> doc=microdom.parseString('<a>1<b>2<c>3</c>4</b></a>')
- >>> gatherTextNodes(doc.documentElement)
- '1234'
-With dounescape=1, also convert entities back into normal characters.
-@return: the gathered nodes as a single string
-@rtype: str
-"""
- gathered=[]
- gathered_append=gathered.append
- slice=[iNode]
- while len(slice)>0:
- c=slice.pop(0)
- if hasattr(c, 'nodeValue') and c.nodeValue is not None:
- if dounescape:
- val=unescape(c.nodeValue)
- else:
- val=c.nodeValue
- gathered_append(val)
- slice[:0]=c.childNodes
- return joinWith.join(gathered)
-
-class RawText(microdom.Text):
- """This is an evil and horrible speed hack. Basically, if you have a big
- chunk of XML that you want to insert into the DOM, but you don't want to
- incur the cost of parsing it, you can construct one of these and insert it
- into the DOM. This will most certainly only work with microdom as the API
- for converting nodes to xml is different in every DOM implementation.
-
- This could be improved by making this class a Lazy parser, so if you
- inserted this into the DOM and then later actually tried to mutate this
- node, it would be parsed then.
- """
-
- def writexml(self, writer, indent="", addindent="", newl="", strip=0, nsprefixes=None, namespace=None):
- writer.write("%s%s%s" % (indent, self.data, newl))
-
-def findNodes(parent, matcher, accum=None):
- if accum is None:
- accum = []
- if not parent.hasChildNodes():
- return accum
- for child in parent.childNodes:
- # print child, child.nodeType, child.nodeName
- if matcher(child):
- accum.append(child)
- findNodes(child, matcher, accum)
- return accum
-
-
-def findNodesShallowOnMatch(parent, matcher, recurseMatcher, accum=None):
- if accum is None:
- accum = []
- if not parent.hasChildNodes():
- return accum
- for child in parent.childNodes:
- # print child, child.nodeType, child.nodeName
- if matcher(child):
- accum.append(child)
- if recurseMatcher(child):
- findNodesShallowOnMatch(child, matcher, recurseMatcher, accum)
- return accum
-
-def findNodesShallow(parent, matcher, accum=None):
- if accum is None:
- accum = []
- if not parent.hasChildNodes():
- return accum
- for child in parent.childNodes:
- if matcher(child):
- accum.append(child)
- else:
- findNodes(child, matcher, accum)
- return accum
-
-
-def findElementsWithAttributeShallow(parent, attribute):
- """
- Return an iterable of the elements which are direct children of C{parent}
- and which have the C{attribute} attribute.
- """
- return findNodesShallow(parent,
- lambda n: getattr(n, 'tagName', None) is not None and
- n.hasAttribute(attribute))
-
-
-def findElements(parent, matcher):
- """
- Return an iterable of the elements which are children of C{parent} for
- which the predicate C{matcher} returns true.
- """
- return findNodes(
- parent,
- lambda n, matcher=matcher: getattr(n, 'tagName', None) is not None and
- matcher(n))
-
-def findElementsWithAttribute(parent, attribute, value=None):
- if value:
- return findElements(
- parent,
- lambda n, attribute=attribute, value=value:
- n.hasAttribute(attribute) and n.getAttribute(attribute) == value)
- else:
- return findElements(
- parent,
- lambda n, attribute=attribute: n.hasAttribute(attribute))
-
-
-def findNodesNamed(parent, name):
- return findNodes(parent, lambda n, name=name: n.nodeName == name)
-
-
-def writeNodeData(node, oldio):
- for subnode in node.childNodes:
- if hasattr(subnode, 'data'):
- oldio.write(subnode.data)
- else:
- writeNodeData(subnode, oldio)
-
-
-def getNodeText(node):
- oldio = StringIO.StringIO()
- writeNodeData(node, oldio)
- return oldio.getvalue()
-
-
-def getParents(node):
- l = []
- while node:
- l.append(node)
- node = node.parentNode
- return l
-
-def namedChildren(parent, nodeName):
- """namedChildren(parent, nodeName) -> children (not descendants) of parent
- that have tagName == nodeName
- """
- return [n for n in parent.childNodes if getattr(n, 'tagName', '')==nodeName]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/error.py
deleted file mode 100755
index 2fa8b43c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/error.py
+++ /dev/null
@@ -1,381 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_error -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Exception definitions for L{twisted.web}.
-"""
-
-import operator
-
-from twisted.web import http
-
-
-class Error(Exception):
- """
- A basic HTTP error.
-
- @type status: C{str}
- @ivar status: Refers to an HTTP status code, for example L{http.NOT_FOUND}.
-
- @type message: C{str}
- @param message: A short error message, for example "NOT FOUND".
-
- @type response: C{str}
- @ivar response: A complete HTML document for an error page.
- """
- def __init__(self, code, message=None, response=None):
- """
- Initializes a basic exception.
-
- @type code: C{str}
- @param code: Refers to an HTTP status code, for example
- L{http.NOT_FOUND}. If no C{message} is given, C{code} is mapped to a
- descriptive string that is used instead.
-
- @type message: C{str}
- @param message: A short error message, for example "NOT FOUND".
-
- @type response: C{str}
- @param response: A complete HTML document for an error page.
- """
- if not message:
- try:
- message = http.responses.get(int(code))
- except ValueError:
- # If code wasn't a stringified int, can't map the
- # status code to a descriptive string so keep message
- # unchanged.
- pass
-
- Exception.__init__(self, code, message, response)
- self.status = code
- self.message = message
- self.response = response
-
-
- def __str__(self):
- return '%s %s' % (self[0], self[1])
-
-
-
-class PageRedirect(Error):
- """
- A request resulted in an HTTP redirect.
-
- @type location: C{str}
- @ivar location: The location of the redirect which was not followed.
- """
- def __init__(self, code, message=None, response=None, location=None):
- """
- Initializes a page redirect exception.
-
- @type code: C{str}
- @param code: Refers to an HTTP status code, for example
- L{http.NOT_FOUND}. If no C{message} is given, C{code} is mapped to a
- descriptive string that is used instead.
-
- @type message: C{str}
- @param message: A short error message, for example "NOT FOUND".
-
- @type response: C{str}
- @param response: A complete HTML document for an error page.
-
- @type location: C{str}
- @param location: The location response-header field value. It is an
- absolute URI used to redirect the receiver to a location other than
- the Request-URI so the request can be completed.
- """
- if not message:
- try:
- message = http.responses.get(int(code))
- except ValueError:
- # If code wasn't a stringified int, can't map the
- # status code to a descriptive string so keep message
- # unchanged.
- pass
-
- if location and message:
- message = "%s to %s" % (message, location)
-
- Error.__init__(self, code, message, response)
- self.location = location
-
-
-
-class InfiniteRedirection(Error):
- """
- HTTP redirection is occurring endlessly.
-
- @type location: C{str}
- @ivar location: The first URL in the series of redirections which was
- not followed.
- """
- def __init__(self, code, message=None, response=None, location=None):
- """
- Initializes an infinite redirection exception.
-
- @type code: C{str}
- @param code: Refers to an HTTP status code, for example
- L{http.NOT_FOUND}. If no C{message} is given, C{code} is mapped to a
- descriptive string that is used instead.
-
- @type message: C{str}
- @param message: A short error message, for example "NOT FOUND".
-
- @type response: C{str}
- @param response: A complete HTML document for an error page.
-
- @type location: C{str}
- @param location: The location response-header field value. It is an
- absolute URI used to redirect the receiver to a location other than
- the Request-URI so the request can be completed.
- """
- if not message:
- try:
- message = http.responses.get(int(code))
- except ValueError:
- # If code wasn't a stringified int, can't map the
- # status code to a descriptive string so keep message
- # unchanged.
- pass
-
- if location and message:
- message = "%s to %s" % (message, location)
-
- Error.__init__(self, code, message, response)
- self.location = location
-
-
-
-class RedirectWithNoLocation(Error):
- """
- Exception passed to L{ResponseFailed} if we got a redirect without a
- C{Location} header field.
-
- @since: 11.1
- """
-
- def __init__(self, code, message, uri):
- """
- Initializes a page redirect exception when no location is given.
-
- @type code: C{str}
- @param code: Refers to an HTTP status code, for example
- L{http.NOT_FOUND}. If no C{message} is given, C{code} is mapped to
- a descriptive string that is used instead.
-
- @type message: C{str}
- @param message: A short error message.
-
- @type uri: C{str}
- @param uri: The URI which failed to give a proper location header
- field.
- """
- message = "%s to %s" % (message, uri)
-
- Error.__init__(self, code, message)
- self.uri = uri
-
-
-
-class UnsupportedMethod(Exception):
- """
- Raised by a resource when faced with a strange request method.
-
- RFC 2616 (HTTP 1.1) gives us two choices when faced with this situtation:
- If the type of request is known to us, but not allowed for the requested
- resource, respond with NOT_ALLOWED. Otherwise, if the request is something
- we don't know how to deal with in any case, respond with NOT_IMPLEMENTED.
-
- When this exception is raised by a Resource's render method, the server
- will make the appropriate response.
-
- This exception's first argument MUST be a sequence of the methods the
- resource *does* support.
- """
-
- allowedMethods = ()
-
- def __init__(self, allowedMethods, *args):
- Exception.__init__(self, allowedMethods, *args)
- self.allowedMethods = allowedMethods
-
- if not operator.isSequenceType(allowedMethods):
- why = "but my first argument is not a sequence."
- s = ("First argument must be a sequence of"
- " supported methods, %s" % (why,))
- raise TypeError, s
-
-
-
-class SchemeNotSupported(Exception):
- """
- The scheme of a URI was not one of the supported values.
- """
-
-
-
-class RenderError(Exception):
- """
- Base exception class for all errors which can occur during template
- rendering.
- """
-
-
-
-class MissingRenderMethod(RenderError):
- """
- Tried to use a render method which does not exist.
-
- @ivar element: The element which did not have the render method.
- @ivar renderName: The name of the renderer which could not be found.
- """
- def __init__(self, element, renderName):
- RenderError.__init__(self, element, renderName)
- self.element = element
- self.renderName = renderName
-
-
- def __repr__(self):
- return '%r: %r had no render method named %r' % (
- self.__class__.__name__, self.element, self.renderName)
-
-
-
-class MissingTemplateLoader(RenderError):
- """
- L{MissingTemplateLoader} is raised when trying to render an Element without
- a template loader, i.e. a C{loader} attribute.
-
- @ivar element: The Element which did not have a document factory.
- """
- def __init__(self, element):
- RenderError.__init__(self, element)
- self.element = element
-
-
- def __repr__(self):
- return '%r: %r had no loader' % (self.__class__.__name__,
- self.element)
-
-
-
-class UnexposedMethodError(Exception):
- """
- Raised on any attempt to get a method which has not been exposed.
- """
-
-
-
-class UnfilledSlot(Exception):
- """
- During flattening, a slot with no associated data was encountered.
- """
-
-
-
-class UnsupportedType(Exception):
- """
- During flattening, an object of a type which cannot be flattened was
- encountered.
- """
-
-
-
-class FlattenerError(Exception):
- """
- An error occurred while flattening an object.
-
- @ivar _roots: A list of the objects on the flattener's stack at the time
- the unflattenable object was encountered. The first element is least
- deeply nested object and the last element is the most deeply nested.
- """
- def __init__(self, exception, roots, traceback):
- self._exception = exception
- self._roots = roots
- self._traceback = traceback
- Exception.__init__(self, exception, roots, traceback)
-
-
- def _formatRoot(self, obj):
- """
- Convert an object from C{self._roots} to a string suitable for
- inclusion in a render-traceback (like a normal Python traceback, but
- can include "frame" source locations which are not in Python source
- files).
-
- @param obj: Any object which can be a render step I{root}.
- Typically, L{Tag}s, strings, and other simple Python types.
-
- @return: A string representation of C{obj}.
- @rtype: L{str}
- """
- # There's a circular dependency between this class and 'Tag', although
- # only for an isinstance() check.
- from twisted.web.template import Tag
- if isinstance(obj, (str, unicode)):
- # It's somewhat unlikely that there will ever be a str in the roots
- # list. However, something like a MemoryError during a str.replace
- # call (eg, replacing " with &quot;) could possibly cause this.
- # Likewise, UTF-8 encoding a unicode string to a byte string might
- # fail like this.
- if len(obj) > 40:
- if isinstance(obj, str):
- prefix = 1
- else:
- prefix = 2
- return repr(obj[:20])[:-1] + '<...>' + repr(obj[-20:])[prefix:]
- else:
- return repr(obj)
- elif isinstance(obj, Tag):
- if obj.filename is None:
- return 'Tag <' + obj.tagName + '>'
- else:
- return "File \"%s\", line %d, column %d, in \"%s\"" % (
- obj.filename, obj.lineNumber,
- obj.columnNumber, obj.tagName)
- else:
- return repr(obj)
-
-
- def __repr__(self):
- """
- Present a string representation which includes a template traceback, so
- we can tell where this error occurred in the template, as well as in
- Python.
- """
- # Avoid importing things unnecessarily until we actually need them;
- # since this is an 'error' module we should be extra paranoid about
- # that.
- from traceback import format_list
- if self._roots:
- roots = ' ' + '\n '.join([
- self._formatRoot(r) for r in self._roots]) + '\n'
- else:
- roots = ''
- if self._traceback:
- traceback = '\n'.join([
- line
- for entry in format_list(self._traceback)
- for line in entry.splitlines()]) + '\n'
- else:
- traceback = ''
- return (
- 'Exception while flattening:\n' +
- roots + traceback +
- self._exception.__class__.__name__ + ': ' +
- str(self._exception) + '\n')
-
-
- def __str__(self):
- return repr(self)
-
-
-
-__all__ = [
- 'Error', 'PageRedirect', 'InfiniteRedirection', 'RenderError',
- 'MissingRenderMethod', 'MissingTemplateLoader', 'UnexposedMethodError',
- 'UnfilledSlot', 'UnsupportedType', 'FlattenerError',
- 'RedirectWithNoLocation'
-]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/failure.xhtml b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/failure.xhtml
deleted file mode 100644
index 1e88a3ab..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/failure.xhtml
+++ /dev/null
@@ -1,71 +0,0 @@
-<div xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">
- <style type="text/css">
- div.error {
- color: red;
- font-family: Verdana, Arial, helvetica, sans-serif;
- font-weight: bold;
- }
-
- div {
- font-family: Verdana, Arial, helvetica, sans-serif;
- }
-
- div.stackTrace {
- }
-
- div.frame {
- padding: 1em;
- background: white;
- border-bottom: thin black dashed;
- }
-
- div.frame:first-child {
- padding: 1em;
- background: white;
- border-top: thin black dashed;
- border-bottom: thin black dashed;
- }
-
- div.location {
- }
-
- span.function {
- font-weight: bold;
- font-family: "Courier New", courier, monospace;
- }
-
- div.snippet {
- margin-bottom: 0.5em;
- margin-left: 1em;
- background: #FFFFDD;
- }
-
- div.snippetHighlightLine {
- color: red;
- }
-
- span.code {
- font-family: "Courier New", courier, monospace;
- }
- </style>
-
- <div class="error">
- <span t:render="type" />: <span t:render="value" />
- </div>
- <div class="stackTrace" t:render="traceback">
- <div class="frame" t:render="frames">
- <div class="location">
- <span t:render="filename" />:<span t:render="lineNumber" /> in <span class="function" t:render="function" />
- </div>
- <div class="snippet" t:render="source">
- <div t:render="sourceLines">
- <span class="lineno" t:render="lineNumber" />
- <code class="code" t:render="sourceLine" />
- </div>
- </div>
- </div>
- </div>
- <div class="error">
- <span t:render="type" />: <span t:render="value" />
- </div>
-</div>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/guard.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/guard.py
deleted file mode 100755
index f3bb4d79..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/guard.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Resource traversal integration with L{twisted.cred} to allow for
-authentication and authorization of HTTP requests.
-"""
-
-# Expose HTTP authentication classes here.
-from twisted.web._auth.wrapper import HTTPAuthSessionWrapper
-from twisted.web._auth.basic import BasicCredentialFactory
-from twisted.web._auth.digest import DigestCredentialFactory
-
-__all__ = [
- "HTTPAuthSessionWrapper",
-
- "BasicCredentialFactory", "DigestCredentialFactory"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/html.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/html.py
deleted file mode 100755
index 6a97d8c0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/html.py
+++ /dev/null
@@ -1,49 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""I hold HTML generation helpers.
-"""
-
-from twisted.python import log
-#t.w imports
-from twisted.web import resource
-
-import traceback, string
-
-from cStringIO import StringIO
-from microdom import escape
-
-def PRE(text):
- "Wrap <pre> tags around some text and HTML-escape it."
- return "<pre>"+escape(text)+"</pre>"
-
-def UL(lst):
- io = StringIO()
- io.write("<ul>\n")
- for el in lst:
- io.write("<li> %s</li>\n" % el)
- io.write("</ul>")
- return io.getvalue()
-
-def linkList(lst):
- io = StringIO()
- io.write("<ul>\n")
- for hr, el in lst:
- io.write('<li> <a href="%s">%s</a></li>\n' % (hr, el))
- io.write("</ul>")
- return io.getvalue()
-
-def output(func, *args, **kw):
- """output(func, *args, **kw) -> html string
- Either return the result of a function (which presumably returns an
- HTML-legal string) or a sparse HTMLized error message and a message
- in the server log.
- """
- try:
- return func(*args, **kw)
- except:
- log.msg("Error calling %r:" % (func,))
- log.err()
- return PRE("An error occurred.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http.py
deleted file mode 100755
index 77d878b7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http.py
+++ /dev/null
@@ -1,1818 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_http -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-HyperText Transfer Protocol implementation.
-
-This is the basic server-side protocol implementation used by the Twisted
-Web server. It can parse HTTP 1.0 requests and supports many HTTP 1.1
-features as well. Additionally, some functionality implemented here is
-also useful for HTTP clients (such as the chunked encoding parser).
-"""
-
-# system imports
-from cStringIO import StringIO
-import tempfile
-import base64, binascii
-import cgi
-import socket
-import math
-import time
-import calendar
-import warnings
-import os
-from urlparse import urlparse as _urlparse
-
-from zope.interface import implements
-
-# twisted imports
-from twisted.internet import interfaces, reactor, protocol, address
-from twisted.internet.defer import Deferred
-from twisted.protocols import policies, basic
-from twisted.python import log
-from urllib import unquote
-
-from twisted.web.http_headers import _DictHeaders, Headers
-
-protocol_version = "HTTP/1.1"
-
-_CONTINUE = 100
-SWITCHING = 101
-
-OK = 200
-CREATED = 201
-ACCEPTED = 202
-NON_AUTHORITATIVE_INFORMATION = 203
-NO_CONTENT = 204
-RESET_CONTENT = 205
-PARTIAL_CONTENT = 206
-MULTI_STATUS = 207
-
-MULTIPLE_CHOICE = 300
-MOVED_PERMANENTLY = 301
-FOUND = 302
-SEE_OTHER = 303
-NOT_MODIFIED = 304
-USE_PROXY = 305
-TEMPORARY_REDIRECT = 307
-
-BAD_REQUEST = 400
-UNAUTHORIZED = 401
-PAYMENT_REQUIRED = 402
-FORBIDDEN = 403
-NOT_FOUND = 404
-NOT_ALLOWED = 405
-NOT_ACCEPTABLE = 406
-PROXY_AUTH_REQUIRED = 407
-REQUEST_TIMEOUT = 408
-CONFLICT = 409
-GONE = 410
-LENGTH_REQUIRED = 411
-PRECONDITION_FAILED = 412
-REQUEST_ENTITY_TOO_LARGE = 413
-REQUEST_URI_TOO_LONG = 414
-UNSUPPORTED_MEDIA_TYPE = 415
-REQUESTED_RANGE_NOT_SATISFIABLE = 416
-EXPECTATION_FAILED = 417
-
-INTERNAL_SERVER_ERROR = 500
-NOT_IMPLEMENTED = 501
-BAD_GATEWAY = 502
-SERVICE_UNAVAILABLE = 503
-GATEWAY_TIMEOUT = 504
-HTTP_VERSION_NOT_SUPPORTED = 505
-INSUFFICIENT_STORAGE_SPACE = 507
-NOT_EXTENDED = 510
-
-RESPONSES = {
- # 100
- _CONTINUE: "Continue",
- SWITCHING: "Switching Protocols",
-
- # 200
- OK: "OK",
- CREATED: "Created",
- ACCEPTED: "Accepted",
- NON_AUTHORITATIVE_INFORMATION: "Non-Authoritative Information",
- NO_CONTENT: "No Content",
- RESET_CONTENT: "Reset Content.",
- PARTIAL_CONTENT: "Partial Content",
- MULTI_STATUS: "Multi-Status",
-
- # 300
- MULTIPLE_CHOICE: "Multiple Choices",
- MOVED_PERMANENTLY: "Moved Permanently",
- FOUND: "Found",
- SEE_OTHER: "See Other",
- NOT_MODIFIED: "Not Modified",
- USE_PROXY: "Use Proxy",
- # 306 not defined??
- TEMPORARY_REDIRECT: "Temporary Redirect",
-
- # 400
- BAD_REQUEST: "Bad Request",
- UNAUTHORIZED: "Unauthorized",
- PAYMENT_REQUIRED: "Payment Required",
- FORBIDDEN: "Forbidden",
- NOT_FOUND: "Not Found",
- NOT_ALLOWED: "Method Not Allowed",
- NOT_ACCEPTABLE: "Not Acceptable",
- PROXY_AUTH_REQUIRED: "Proxy Authentication Required",
- REQUEST_TIMEOUT: "Request Time-out",
- CONFLICT: "Conflict",
- GONE: "Gone",
- LENGTH_REQUIRED: "Length Required",
- PRECONDITION_FAILED: "Precondition Failed",
- REQUEST_ENTITY_TOO_LARGE: "Request Entity Too Large",
- REQUEST_URI_TOO_LONG: "Request-URI Too Long",
- UNSUPPORTED_MEDIA_TYPE: "Unsupported Media Type",
- REQUESTED_RANGE_NOT_SATISFIABLE: "Requested Range not satisfiable",
- EXPECTATION_FAILED: "Expectation Failed",
-
- # 500
- INTERNAL_SERVER_ERROR: "Internal Server Error",
- NOT_IMPLEMENTED: "Not Implemented",
- BAD_GATEWAY: "Bad Gateway",
- SERVICE_UNAVAILABLE: "Service Unavailable",
- GATEWAY_TIMEOUT: "Gateway Time-out",
- HTTP_VERSION_NOT_SUPPORTED: "HTTP Version not supported",
- INSUFFICIENT_STORAGE_SPACE: "Insufficient Storage Space",
- NOT_EXTENDED: "Not Extended"
- }
-
-CACHED = """Magic constant returned by http.Request methods to set cache
-validation headers when the request is conditional and the value fails
-the condition."""
-
-# backwards compatability
-responses = RESPONSES
-
-
-# datetime parsing and formatting
-weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-monthname = [None,
- 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-weekdayname_lower = [name.lower() for name in weekdayname]
-monthname_lower = [name and name.lower() for name in monthname]
-
-def urlparse(url):
- """
- Parse an URL into six components.
-
- This is similar to L{urlparse.urlparse}, but rejects C{unicode} input
- and always produces C{str} output.
-
- @type url: C{str}
-
- @raise TypeError: The given url was a C{unicode} string instead of a
- C{str}.
-
- @rtype: six-tuple of str
- @return: The scheme, net location, path, params, query string, and fragment
- of the URL.
- """
- if isinstance(url, unicode):
- raise TypeError("url must be str, not unicode")
- scheme, netloc, path, params, query, fragment = _urlparse(url)
- if isinstance(scheme, unicode):
- scheme = scheme.encode('ascii')
- netloc = netloc.encode('ascii')
- path = path.encode('ascii')
- query = query.encode('ascii')
- fragment = fragment.encode('ascii')
- return scheme, netloc, path, params, query, fragment
-
-
-def parse_qs(qs, keep_blank_values=0, strict_parsing=0, unquote=unquote):
- """
- like cgi.parse_qs, only with custom unquote function
- """
- d = {}
- items = [s2 for s1 in qs.split("&") for s2 in s1.split(";")]
- for item in items:
- try:
- k, v = item.split("=", 1)
- except ValueError:
- if strict_parsing:
- raise
- continue
- if v or keep_blank_values:
- k = unquote(k.replace("+", " "))
- v = unquote(v.replace("+", " "))
- if k in d:
- d[k].append(v)
- else:
- d[k] = [v]
- return d
-
-def datetimeToString(msSinceEpoch=None):
- """
- Convert seconds since epoch to HTTP datetime string.
- """
- if msSinceEpoch == None:
- msSinceEpoch = time.time()
- year, month, day, hh, mm, ss, wd, y, z = time.gmtime(msSinceEpoch)
- s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
- weekdayname[wd],
- day, monthname[month], year,
- hh, mm, ss)
- return s
-
-def datetimeToLogString(msSinceEpoch=None):
- """
- Convert seconds since epoch to log datetime string.
- """
- if msSinceEpoch == None:
- msSinceEpoch = time.time()
- year, month, day, hh, mm, ss, wd, y, z = time.gmtime(msSinceEpoch)
- s = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- day, monthname[month], year,
- hh, mm, ss)
- return s
-
-def timegm(year, month, day, hour, minute, second):
- """
- Convert time tuple in GMT to seconds since epoch, GMT
- """
- EPOCH = 1970
- if year < EPOCH:
- raise ValueError("Years prior to %d not supported" % (EPOCH,))
- assert 1 <= month <= 12
- days = 365*(year-EPOCH) + calendar.leapdays(EPOCH, year)
- for i in range(1, month):
- days = days + calendar.mdays[i]
- if month > 2 and calendar.isleap(year):
- days = days + 1
- days = days + day - 1
- hours = days*24 + hour
- minutes = hours*60 + minute
- seconds = minutes*60 + second
- return seconds
-
-def stringToDatetime(dateString):
- """
- Convert an HTTP date string (one of three formats) to seconds since epoch.
- """
- parts = dateString.split()
-
- if not parts[0][0:3].lower() in weekdayname_lower:
- # Weekday is stupid. Might have been omitted.
- try:
- return stringToDatetime("Sun, "+dateString)
- except ValueError:
- # Guess not.
- pass
-
- partlen = len(parts)
- if (partlen == 5 or partlen == 6) and parts[1].isdigit():
- # 1st date format: Sun, 06 Nov 1994 08:49:37 GMT
- # (Note: "GMT" is literal, not a variable timezone)
- # (also handles without "GMT")
- # This is the normal format
- day = parts[1]
- month = parts[2]
- year = parts[3]
- time = parts[4]
- elif (partlen == 3 or partlen == 4) and parts[1].find('-') != -1:
- # 2nd date format: Sunday, 06-Nov-94 08:49:37 GMT
- # (Note: "GMT" is literal, not a variable timezone)
- # (also handles without without "GMT")
- # Two digit year, yucko.
- day, month, year = parts[1].split('-')
- time = parts[2]
- year=int(year)
- if year < 69:
- year = year + 2000
- elif year < 100:
- year = year + 1900
- elif len(parts) == 5:
- # 3rd date format: Sun Nov 6 08:49:37 1994
- # ANSI C asctime() format.
- day = parts[2]
- month = parts[1]
- year = parts[4]
- time = parts[3]
- else:
- raise ValueError("Unknown datetime format %r" % dateString)
-
- day = int(day)
- month = int(monthname_lower.index(month.lower()))
- year = int(year)
- hour, min, sec = map(int, time.split(':'))
- return int(timegm(year, month, day, hour, min, sec))
-
-def toChunk(data):
- """
- Convert string to a chunk.
-
- @returns: a tuple of strings representing the chunked encoding of data
- """
- return ("%x\r\n" % len(data), data, "\r\n")
-
-def fromChunk(data):
- """
- Convert chunk to string.
-
- @returns: tuple (result, remaining), may raise ValueError.
- """
- prefix, rest = data.split('\r\n', 1)
- length = int(prefix, 16)
- if length < 0:
- raise ValueError("Chunk length must be >= 0, not %d" % (length,))
- if not rest[length:length + 2] == '\r\n':
- raise ValueError, "chunk must end with CRLF"
- return rest[:length], rest[length + 2:]
-
-
-def parseContentRange(header):
- """
- Parse a content-range header into (start, end, realLength).
-
- realLength might be None if real length is not known ('*').
- """
- kind, other = header.strip().split()
- if kind.lower() != "bytes":
- raise ValueError, "a range of type %r is not supported"
- startend, realLength = other.split("/")
- start, end = map(int, startend.split("-"))
- if realLength == "*":
- realLength = None
- else:
- realLength = int(realLength)
- return (start, end, realLength)
-
-
-
-class StringTransport:
- """
- I am a StringIO wrapper that conforms for the transport API. I support
- the `writeSequence' method.
- """
- def __init__(self):
- self.s = StringIO()
- def writeSequence(self, seq):
- self.s.write(''.join(seq))
- def __getattr__(self, attr):
- return getattr(self.__dict__['s'], attr)
-
-
-class HTTPClient(basic.LineReceiver):
- """
- A client for HTTP 1.0.
-
- Notes:
- You probably want to send a 'Host' header with the name of the site you're
- connecting to, in order to not break name based virtual hosting.
-
- @ivar length: The length of the request body in bytes.
- @type length: C{int}
-
- @ivar firstLine: Are we waiting for the first header line?
- @type firstLine: C{bool}
-
- @ivar __buffer: The buffer that stores the response to the HTTP request.
- @type __buffer: A C{StringIO} object.
-
- @ivar _header: Part or all of an HTTP request header.
- @type _header: C{str}
- """
- length = None
- firstLine = True
- __buffer = None
- _header = ""
-
- def sendCommand(self, command, path):
- self.transport.write('%s %s HTTP/1.0\r\n' % (command, path))
-
- def sendHeader(self, name, value):
- self.transport.write('%s: %s\r\n' % (name, value))
-
- def endHeaders(self):
- self.transport.write('\r\n')
-
-
- def extractHeader(self, header):
- """
- Given a complete HTTP header, extract the field name and value and
- process the header.
-
- @param header: a complete HTTP request header of the form
- 'field-name: value'.
- @type header: C{str}
- """
- key, val = header.split(':', 1)
- val = val.lstrip()
- self.handleHeader(key, val)
- if key.lower() == 'content-length':
- self.length = int(val)
-
-
- def lineReceived(self, line):
- """
- Parse the status line and headers for an HTTP request.
-
- @param line: Part of an HTTP request header. Request bodies are parsed
- in L{rawDataReceived}.
- @type line: C{str}
- """
- if self.firstLine:
- self.firstLine = False
- l = line.split(None, 2)
- version = l[0]
- status = l[1]
- try:
- message = l[2]
- except IndexError:
- # sometimes there is no message
- message = ""
- self.handleStatus(version, status, message)
- return
- if not line:
- if self._header != "":
- # Only extract headers if there are any
- self.extractHeader(self._header)
- self.__buffer = StringIO()
- self.handleEndHeaders()
- self.setRawMode()
- return
-
- if line.startswith('\t') or line.startswith(' '):
- # This line is part of a multiline header. According to RFC 822, in
- # "unfolding" multiline headers you do not strip the leading
- # whitespace on the continuing line.
- self._header = self._header + line
- elif self._header:
- # This line starts a new header, so process the previous one.
- self.extractHeader(self._header)
- self._header = line
- else: # First header
- self._header = line
-
-
- def connectionLost(self, reason):
- self.handleResponseEnd()
-
- def handleResponseEnd(self):
- """
- The response has been completely received.
-
- This callback may be invoked more than once per request.
- """
- if self.__buffer is not None:
- b = self.__buffer.getvalue()
- self.__buffer = None
- self.handleResponse(b)
-
- def handleResponsePart(self, data):
- self.__buffer.write(data)
-
- def connectionMade(self):
- pass
-
- def handleStatus(self, version, status, message):
- """
- Called when the status-line is received.
-
- @param version: e.g. 'HTTP/1.0'
- @param status: e.g. '200'
- @type status: C{str}
- @param message: e.g. 'OK'
- """
-
- def handleHeader(self, key, val):
- """
- Called every time a header is received.
- """
-
- def handleEndHeaders(self):
- """
- Called when all headers have been received.
- """
-
-
- def rawDataReceived(self, data):
- if self.length is not None:
- data, rest = data[:self.length], data[self.length:]
- self.length -= len(data)
- else:
- rest = ''
- self.handleResponsePart(data)
- if self.length == 0:
- self.handleResponseEnd()
- self.setLineMode(rest)
-
-
-
-# response codes that must have empty bodies
-NO_BODY_CODES = (204, 304)
-
-class Request:
- """
- A HTTP request.
-
- Subclasses should override the process() method to determine how
- the request will be processed.
-
- @ivar method: The HTTP method that was used.
- @ivar uri: The full URI that was requested (includes arguments).
- @ivar path: The path only (arguments not included).
- @ivar args: All of the arguments, including URL and POST arguments.
- @type args: A mapping of strings (the argument names) to lists of values.
- i.e., ?foo=bar&foo=baz&quux=spam results in
- {'foo': ['bar', 'baz'], 'quux': ['spam']}.
-
- @type requestHeaders: L{http_headers.Headers}
- @ivar requestHeaders: All received HTTP request headers.
-
- @ivar received_headers: Backwards-compatibility access to
- C{requestHeaders}. Use C{requestHeaders} instead. C{received_headers}
- behaves mostly like a C{dict} and does not provide access to all header
- values.
-
- @type responseHeaders: L{http_headers.Headers}
- @ivar responseHeaders: All HTTP response headers to be sent.
-
- @ivar headers: Backwards-compatibility access to C{responseHeaders}. Use
- C{responseHeaders} instead. C{headers} behaves mostly like a C{dict}
- and does not provide access to all header values nor does it allow
- multiple values for one header to be set.
-
- @ivar notifications: A C{list} of L{Deferred}s which are waiting for
- notification that the response to this request has been finished
- (successfully or with an error). Don't use this attribute directly,
- instead use the L{Request.notifyFinish} method.
-
- @ivar _disconnected: A flag which is C{False} until the connection over
- which this request was received is closed and which is C{True} after
- that.
- @type _disconnected: C{bool}
- """
- implements(interfaces.IConsumer)
-
- producer = None
- finished = 0
- code = OK
- code_message = RESPONSES[OK]
- method = "(no method yet)"
- clientproto = "(no clientproto yet)"
- uri = "(no uri yet)"
- startedWriting = 0
- chunked = 0
- sentLength = 0 # content-length of response, or total bytes sent via chunking
- etag = None
- lastModified = None
- args = None
- path = None
- content = None
- _forceSSL = 0
- _disconnected = False
-
- def __init__(self, channel, queued):
- """
- @param channel: the channel we're connected to.
- @param queued: are we in the request queue, or can we start writing to
- the transport?
- """
- self.notifications = []
- self.channel = channel
- self.queued = queued
- self.requestHeaders = Headers()
- self.received_cookies = {}
- self.responseHeaders = Headers()
- self.cookies = [] # outgoing cookies
-
- if queued:
- self.transport = StringTransport()
- else:
- self.transport = self.channel.transport
-
-
- def __setattr__(self, name, value):
- """
- Support assignment of C{dict} instances to C{received_headers} for
- backwards-compatibility.
- """
- if name == 'received_headers':
- # A property would be nice, but Request is classic.
- self.requestHeaders = headers = Headers()
- for k, v in value.iteritems():
- headers.setRawHeaders(k, [v])
- elif name == 'requestHeaders':
- self.__dict__[name] = value
- self.__dict__['received_headers'] = _DictHeaders(value)
- elif name == 'headers':
- self.responseHeaders = headers = Headers()
- for k, v in value.iteritems():
- headers.setRawHeaders(k, [v])
- elif name == 'responseHeaders':
- self.__dict__[name] = value
- self.__dict__['headers'] = _DictHeaders(value)
- else:
- self.__dict__[name] = value
-
-
- def _cleanup(self):
- """
- Called when have finished responding and are no longer queued.
- """
- if self.producer:
- log.err(RuntimeError("Producer was not unregistered for %s" % self.uri))
- self.unregisterProducer()
- self.channel.requestDone(self)
- del self.channel
- try:
- self.content.close()
- except OSError:
- # win32 suckiness, no idea why it does this
- pass
- del self.content
- for d in self.notifications:
- d.callback(None)
- self.notifications = []
-
- # methods for channel - end users should not use these
-
- def noLongerQueued(self):
- """
- Notify the object that it is no longer queued.
-
- We start writing whatever data we have to the transport, etc.
-
- This method is not intended for users.
- """
- if not self.queued:
- raise RuntimeError, "noLongerQueued() got called unnecessarily."
-
- self.queued = 0
-
- # set transport to real one and send any buffer data
- data = self.transport.getvalue()
- self.transport = self.channel.transport
- if data:
- self.transport.write(data)
-
- # if we have producer, register it with transport
- if (self.producer is not None) and not self.finished:
- self.transport.registerProducer(self.producer, self.streamingProducer)
-
- # if we're finished, clean up
- if self.finished:
- self._cleanup()
-
- def gotLength(self, length):
- """
- Called when HTTP channel got length of content in this request.
-
- This method is not intended for users.
-
- @param length: The length of the request body, as indicated by the
- request headers. C{None} if the request headers do not indicate a
- length.
- """
- if length is not None and length < 100000:
- self.content = StringIO()
- else:
- self.content = tempfile.TemporaryFile()
-
-
- def parseCookies(self):
- """
- Parse cookie headers.
-
- This method is not intended for users.
- """
- cookieheaders = self.requestHeaders.getRawHeaders("cookie")
-
- if cookieheaders is None:
- return
-
- for cookietxt in cookieheaders:
- if cookietxt:
- for cook in cookietxt.split(';'):
- cook = cook.lstrip()
- try:
- k, v = cook.split('=', 1)
- self.received_cookies[k] = v
- except ValueError:
- pass
-
-
- def handleContentChunk(self, data):
- """
- Write a chunk of data.
-
- This method is not intended for users.
- """
- self.content.write(data)
-
-
- def requestReceived(self, command, path, version):
- """
- Called by channel when all data has been received.
-
- This method is not intended for users.
-
- @type command: C{str}
- @param command: The HTTP verb of this request. This has the case
- supplied by the client (eg, it maybe "get" rather than "GET").
-
- @type path: C{str}
- @param path: The URI of this request.
-
- @type version: C{str}
- @param version: The HTTP version of this request.
- """
- self.content.seek(0,0)
- self.args = {}
- self.stack = []
-
- self.method, self.uri = command, path
- self.clientproto = version
- x = self.uri.split('?', 1)
-
- if len(x) == 1:
- self.path = self.uri
- else:
- self.path, argstring = x
- self.args = parse_qs(argstring, 1)
-
- # cache the client and server information, we'll need this later to be
- # serialized and sent with the request so CGIs will work remotely
- self.client = self.channel.transport.getPeer()
- self.host = self.channel.transport.getHost()
-
- # Argument processing
- args = self.args
- ctype = self.requestHeaders.getRawHeaders('content-type')
- if ctype is not None:
- ctype = ctype[0]
-
- if self.method == "POST" and ctype:
- mfd = 'multipart/form-data'
- key, pdict = cgi.parse_header(ctype)
- if key == 'application/x-www-form-urlencoded':
- args.update(parse_qs(self.content.read(), 1))
- elif key == mfd:
- try:
- args.update(cgi.parse_multipart(self.content, pdict))
- except KeyError, e:
- if e.args[0] == 'content-disposition':
- # Parse_multipart can't cope with missing
- # content-dispostion headers in multipart/form-data
- # parts, so we catch the exception and tell the client
- # it was a bad request.
- self.channel.transport.write(
- "HTTP/1.1 400 Bad Request\r\n\r\n")
- self.channel.transport.loseConnection()
- return
- raise
- self.content.seek(0, 0)
-
- self.process()
-
-
- def __repr__(self):
- return '<%s %s %s>'% (self.method, self.uri, self.clientproto)
-
- def process(self):
- """
- Override in subclasses.
-
- This method is not intended for users.
- """
- pass
-
-
- # consumer interface
-
- def registerProducer(self, producer, streaming):
- """
- Register a producer.
- """
- if self.producer:
- raise ValueError, "registering producer %s before previous one (%s) was unregistered" % (producer, self.producer)
-
- self.streamingProducer = streaming
- self.producer = producer
-
- if self.queued:
- if streaming:
- producer.pauseProducing()
- else:
- self.transport.registerProducer(producer, streaming)
-
- def unregisterProducer(self):
- """
- Unregister the producer.
- """
- if not self.queued:
- self.transport.unregisterProducer()
- self.producer = None
-
- # private http response methods
-
- def _sendError(self, code, resp=''):
- self.transport.write('%s %s %s\r\n\r\n' % (self.clientproto, code, resp))
-
-
- # The following is the public interface that people should be
- # writing to.
- def getHeader(self, key):
- """
- Get an HTTP request header.
-
- @type key: C{str}
- @param key: The name of the header to get the value of.
-
- @rtype: C{str} or C{NoneType}
- @return: The value of the specified header, or C{None} if that header
- was not present in the request.
- """
- value = self.requestHeaders.getRawHeaders(key)
- if value is not None:
- return value[-1]
-
-
- def getCookie(self, key):
- """
- Get a cookie that was sent from the network.
- """
- return self.received_cookies.get(key)
-
-
- def notifyFinish(self):
- """
- Notify when the response to this request has finished.
-
- @rtype: L{Deferred}
-
- @return: A L{Deferred} which will be triggered when the request is
- finished -- with a C{None} value if the request finishes
- successfully or with an error if the request is interrupted by an
- error (for example, the client closing the connection prematurely).
- """
- self.notifications.append(Deferred())
- return self.notifications[-1]
-
-
- def finish(self):
- """
- Indicate that all response data has been written to this L{Request}.
- """
- if self._disconnected:
- raise RuntimeError(
- "Request.finish called on a request after its connection was lost; "
- "use Request.notifyFinish to keep track of this.")
- if self.finished:
- warnings.warn("Warning! request.finish called twice.", stacklevel=2)
- return
-
- if not self.startedWriting:
- # write headers
- self.write('')
-
- if self.chunked:
- # write last chunk and closing CRLF
- self.transport.write("0\r\n\r\n")
-
- # log request
- if hasattr(self.channel, "factory"):
- self.channel.factory.log(self)
-
- self.finished = 1
- if not self.queued:
- self._cleanup()
-
-
- def write(self, data):
- """
- Write some data as a result of an HTTP request. The first
- time this is called, it writes out response data.
-
- @type data: C{str}
- @param data: Some bytes to be sent as part of the response body.
- """
- if self.finished:
- raise RuntimeError('Request.write called on a request after '
- 'Request.finish was called.')
- if not self.startedWriting:
- self.startedWriting = 1
- version = self.clientproto
- l = []
- l.append('%s %s %s\r\n' % (version, self.code,
- self.code_message))
- # if we don't have a content length, we send data in
- # chunked mode, so that we can support pipelining in
- # persistent connections.
- if ((version == "HTTP/1.1") and
- (self.responseHeaders.getRawHeaders('content-length') is None) and
- self.method != "HEAD" and self.code not in NO_BODY_CODES):
- l.append("%s: %s\r\n" % ('Transfer-Encoding', 'chunked'))
- self.chunked = 1
-
- if self.lastModified is not None:
- if self.responseHeaders.hasHeader('last-modified'):
- log.msg("Warning: last-modified specified both in"
- " header list and lastModified attribute.")
- else:
- self.responseHeaders.setRawHeaders(
- 'last-modified',
- [datetimeToString(self.lastModified)])
-
- if self.etag is not None:
- self.responseHeaders.setRawHeaders('ETag', [self.etag])
-
- for name, values in self.responseHeaders.getAllRawHeaders():
- for value in values:
- l.append("%s: %s\r\n" % (name, value))
-
- for cookie in self.cookies:
- l.append('%s: %s\r\n' % ("Set-Cookie", cookie))
-
- l.append("\r\n")
-
- self.transport.writeSequence(l)
-
- # if this is a "HEAD" request, we shouldn't return any data
- if self.method == "HEAD":
- self.write = lambda data: None
- return
-
- # for certain result codes, we should never return any data
- if self.code in NO_BODY_CODES:
- self.write = lambda data: None
- return
-
- self.sentLength = self.sentLength + len(data)
- if data:
- if self.chunked:
- self.transport.writeSequence(toChunk(data))
- else:
- self.transport.write(data)
-
- def addCookie(self, k, v, expires=None, domain=None, path=None, max_age=None, comment=None, secure=None):
- """
- Set an outgoing HTTP cookie.
-
- In general, you should consider using sessions instead of cookies, see
- L{twisted.web.server.Request.getSession} and the
- L{twisted.web.server.Session} class for details.
- """
- cookie = '%s=%s' % (k, v)
- if expires is not None:
- cookie = cookie +"; Expires=%s" % expires
- if domain is not None:
- cookie = cookie +"; Domain=%s" % domain
- if path is not None:
- cookie = cookie +"; Path=%s" % path
- if max_age is not None:
- cookie = cookie +"; Max-Age=%s" % max_age
- if comment is not None:
- cookie = cookie +"; Comment=%s" % comment
- if secure:
- cookie = cookie +"; Secure"
- self.cookies.append(cookie)
-
- def setResponseCode(self, code, message=None):
- """
- Set the HTTP response code.
- """
- if not isinstance(code, (int, long)):
- raise TypeError("HTTP response code must be int or long")
- self.code = code
- if message:
- self.code_message = message
- else:
- self.code_message = RESPONSES.get(code, "Unknown Status")
-
-
- def setHeader(self, name, value):
- """
- Set an HTTP response header. Overrides any previously set values for
- this header.
-
- @type name: C{str}
- @param name: The name of the header for which to set the value.
-
- @type value: C{str}
- @param value: The value to set for the named header.
- """
- self.responseHeaders.setRawHeaders(name, [value])
-
-
- def redirect(self, url):
- """
- Utility function that does a redirect.
-
- The request should have finish() called after this.
- """
- self.setResponseCode(FOUND)
- self.setHeader("location", url)
-
-
- def setLastModified(self, when):
- """
- Set the C{Last-Modified} time for the response to this request.
-
- If I am called more than once, I ignore attempts to set
- Last-Modified earlier, only replacing the Last-Modified time
- if it is to a later value.
-
- If I am a conditional request, I may modify my response code
- to L{NOT_MODIFIED} if appropriate for the time given.
-
- @param when: The last time the resource being returned was
- modified, in seconds since the epoch.
- @type when: number
- @return: If I am a C{If-Modified-Since} conditional request and
- the time given is not newer than the condition, I return
- L{http.CACHED<CACHED>} to indicate that you should write no
- body. Otherwise, I return a false value.
- """
- # time.time() may be a float, but the HTTP-date strings are
- # only good for whole seconds.
- when = long(math.ceil(when))
- if (not self.lastModified) or (self.lastModified < when):
- self.lastModified = when
-
- modifiedSince = self.getHeader('if-modified-since')
- if modifiedSince:
- firstPart = modifiedSince.split(';', 1)[0]
- try:
- modifiedSince = stringToDatetime(firstPart)
- except ValueError:
- return None
- if modifiedSince >= when:
- self.setResponseCode(NOT_MODIFIED)
- return CACHED
- return None
-
- def setETag(self, etag):
- """
- Set an C{entity tag} for the outgoing response.
-
- That's \"entity tag\" as in the HTTP/1.1 C{ETag} header, \"used
- for comparing two or more entities from the same requested
- resource.\"
-
- If I am a conditional request, I may modify my response code
- to L{NOT_MODIFIED} or L{PRECONDITION_FAILED}, if appropriate
- for the tag given.
-
- @param etag: The entity tag for the resource being returned.
- @type etag: string
- @return: If I am a C{If-None-Match} conditional request and
- the tag matches one in the request, I return
- L{http.CACHED<CACHED>} to indicate that you should write
- no body. Otherwise, I return a false value.
- """
- if etag:
- self.etag = etag
-
- tags = self.getHeader("if-none-match")
- if tags:
- tags = tags.split()
- if (etag in tags) or ('*' in tags):
- self.setResponseCode(((self.method in ("HEAD", "GET"))
- and NOT_MODIFIED)
- or PRECONDITION_FAILED)
- return CACHED
- return None
-
-
- def getAllHeaders(self):
- """
- Return dictionary mapping the names of all received headers to the last
- value received for each.
-
- Since this method does not return all header information,
- C{self.requestHeaders.getAllRawHeaders()} may be preferred.
- """
- headers = {}
- for k, v in self.requestHeaders.getAllRawHeaders():
- headers[k.lower()] = v[-1]
- return headers
-
-
- def getRequestHostname(self):
- """
- Get the hostname that the user passed in to the request.
-
- This will either use the Host: header (if it is available) or the
- host we are listening on if the header is unavailable.
-
- @returns: the requested hostname
- @rtype: C{str}
- """
- # XXX This method probably has no unit tests. I changed it a ton and
- # nothing failed.
- host = self.getHeader('host')
- if host:
- return host.split(':', 1)[0]
- return self.getHost().host
-
-
- def getHost(self):
- """
- Get my originally requesting transport's host.
-
- Don't rely on the 'transport' attribute, since Request objects may be
- copied remotely. For information on this method's return value, see
- twisted.internet.tcp.Port.
- """
- return self.host
-
- def setHost(self, host, port, ssl=0):
- """
- Change the host and port the request thinks it's using.
-
- This method is useful for working with reverse HTTP proxies (e.g.
- both Squid and Apache's mod_proxy can do this), when the address
- the HTTP client is using is different than the one we're listening on.
-
- For example, Apache may be listening on https://www.example.com, and then
- forwarding requests to http://localhost:8080, but we don't want HTML produced
- by Twisted to say 'http://localhost:8080', they should say 'https://www.example.com',
- so we do::
-
- request.setHost('www.example.com', 443, ssl=1)
-
- @type host: C{str}
- @param host: The value to which to change the host header.
-
- @type ssl: C{bool}
- @param ssl: A flag which, if C{True}, indicates that the request is
- considered secure (if C{True}, L{isSecure} will return C{True}).
- """
- self._forceSSL = ssl # set first so isSecure will work
- if self.isSecure():
- default = 443
- else:
- default = 80
- if port == default:
- hostHeader = host
- else:
- hostHeader = '%s:%d' % (host, port)
- self.requestHeaders.setRawHeaders("host", [hostHeader])
- self.host = address.IPv4Address("TCP", host, port)
-
-
- def getClientIP(self):
- """
- Return the IP address of the client who submitted this request.
-
- @returns: the client IP address
- @rtype: C{str}
- """
- if isinstance(self.client, address.IPv4Address):
- return self.client.host
- else:
- return None
-
- def isSecure(self):
- """
- Return True if this request is using a secure transport.
-
- Normally this method returns True if this request's HTTPChannel
- instance is using a transport that implements ISSLTransport.
-
- This will also return True if setHost() has been called
- with ssl=True.
-
- @returns: True if this request is secure
- @rtype: C{bool}
- """
- if self._forceSSL:
- return True
- transport = getattr(getattr(self, 'channel', None), 'transport', None)
- if interfaces.ISSLTransport(transport, None) is not None:
- return True
- return False
-
- def _authorize(self):
- # Authorization, (mostly) per the RFC
- try:
- authh = self.getHeader("Authorization")
- if not authh:
- self.user = self.password = ''
- return
- bas, upw = authh.split()
- if bas.lower() != "basic":
- raise ValueError
- upw = base64.decodestring(upw)
- self.user, self.password = upw.split(':', 1)
- except (binascii.Error, ValueError):
- self.user = self.password = ""
- except:
- log.err()
- self.user = self.password = ""
-
- def getUser(self):
- """
- Return the HTTP user sent with this request, if any.
-
- If no user was supplied, return the empty string.
-
- @returns: the HTTP user, if any
- @rtype: C{str}
- """
- try:
- return self.user
- except:
- pass
- self._authorize()
- return self.user
-
- def getPassword(self):
- """
- Return the HTTP password sent with this request, if any.
-
- If no password was supplied, return the empty string.
-
- @returns: the HTTP password, if any
- @rtype: C{str}
- """
- try:
- return self.password
- except:
- pass
- self._authorize()
- return self.password
-
- def getClient(self):
- if self.client.type != 'TCP':
- return None
- host = self.client.host
- try:
- name, names, addresses = socket.gethostbyaddr(host)
- except socket.error:
- return host
- names.insert(0, name)
- for name in names:
- if '.' in name:
- return name
- return names[0]
-
-
- def connectionLost(self, reason):
- """
- There is no longer a connection for this request to respond over.
- Clean up anything which can't be useful anymore.
- """
- self._disconnected = True
- self.channel = None
- if self.content is not None:
- self.content.close()
- for d in self.notifications:
- d.errback(reason)
- self.notifications = []
-
-
-
-class _DataLoss(Exception):
- """
- L{_DataLoss} indicates that not all of a message body was received. This
- is only one of several possible exceptions which may indicate that data
- was lost. Because of this, it should not be checked for by
- specifically; any unexpected exception should be treated as having
- caused data loss.
- """
-
-
-
-class PotentialDataLoss(Exception):
- """
- L{PotentialDataLoss} may be raised by a transfer encoding decoder's
- C{noMoreData} method to indicate that it cannot be determined if the
- entire response body has been delivered. This only occurs when making
- requests to HTTP servers which do not set I{Content-Length} or a
- I{Transfer-Encoding} in the response because in this case the end of the
- response is indicated by the connection being closed, an event which may
- also be due to a transient network problem or other error.
- """
-
-
-
-class _IdentityTransferDecoder(object):
- """
- Protocol for accumulating bytes up to a specified length. This handles the
- case where no I{Transfer-Encoding} is specified.
-
- @ivar contentLength: Counter keeping track of how many more bytes there are
- to receive.
-
- @ivar dataCallback: A one-argument callable which will be invoked each
- time application data is received.
-
- @ivar finishCallback: A one-argument callable which will be invoked when
- the terminal chunk is received. It will be invoked with all bytes
- which were delivered to this protocol which came after the terminal
- chunk.
- """
- def __init__(self, contentLength, dataCallback, finishCallback):
- self.contentLength = contentLength
- self.dataCallback = dataCallback
- self.finishCallback = finishCallback
-
-
- def dataReceived(self, data):
- """
- Interpret the next chunk of bytes received. Either deliver them to the
- data callback or invoke the finish callback if enough bytes have been
- received.
-
- @raise RuntimeError: If the finish callback has already been invoked
- during a previous call to this methood.
- """
- if self.dataCallback is None:
- raise RuntimeError(
- "_IdentityTransferDecoder cannot decode data after finishing")
-
- if self.contentLength is None:
- self.dataCallback(data)
- elif len(data) < self.contentLength:
- self.contentLength -= len(data)
- self.dataCallback(data)
- else:
- # Make the state consistent before invoking any code belonging to
- # anyone else in case noMoreData ends up being called beneath this
- # stack frame.
- contentLength = self.contentLength
- dataCallback = self.dataCallback
- finishCallback = self.finishCallback
- self.dataCallback = self.finishCallback = None
- self.contentLength = 0
-
- dataCallback(data[:contentLength])
- finishCallback(data[contentLength:])
-
-
- def noMoreData(self):
- """
- All data which will be delivered to this decoder has been. Check to
- make sure as much data as was expected has been received.
-
- @raise PotentialDataLoss: If the content length is unknown.
- @raise _DataLoss: If the content length is known and fewer than that
- many bytes have been delivered.
-
- @return: C{None}
- """
- finishCallback = self.finishCallback
- self.dataCallback = self.finishCallback = None
- if self.contentLength is None:
- finishCallback('')
- raise PotentialDataLoss()
- elif self.contentLength != 0:
- raise _DataLoss()
-
-
-
-class _ChunkedTransferDecoder(object):
- """
- Protocol for decoding I{chunked} Transfer-Encoding, as defined by RFC 2616,
- section 3.6.1. This protocol can interpret the contents of a request or
- response body which uses the I{chunked} Transfer-Encoding. It cannot
- interpret any of the rest of the HTTP protocol.
-
- It may make sense for _ChunkedTransferDecoder to be an actual IProtocol
- implementation. Currently, the only user of this class will only ever
- call dataReceived on it. However, it might be an improvement if the
- user could connect this to a transport and deliver connection lost
- notification. This way, `dataCallback` becomes `self.transport.write`
- and perhaps `finishCallback` becomes `self.transport.loseConnection()`
- (although I'm not sure where the extra data goes in that case). This
- could also allow this object to indicate to the receiver of data that
- the stream was not completely received, an error case which should be
- noticed. -exarkun
-
- @ivar dataCallback: A one-argument callable which will be invoked each
- time application data is received.
-
- @ivar finishCallback: A one-argument callable which will be invoked when
- the terminal chunk is received. It will be invoked with all bytes
- which were delivered to this protocol which came after the terminal
- chunk.
-
- @ivar length: Counter keeping track of how many more bytes in a chunk there
- are to receive.
-
- @ivar state: One of C{'CHUNK_LENGTH'}, C{'CRLF'}, C{'TRAILER'},
- C{'BODY'}, or C{'FINISHED'}. For C{'CHUNK_LENGTH'}, data for the
- chunk length line is currently being read. For C{'CRLF'}, the CR LF
- pair which follows each chunk is being read. For C{'TRAILER'}, the CR
- LF pair which follows the terminal 0-length chunk is currently being
- read. For C{'BODY'}, the contents of a chunk are being read. For
- C{'FINISHED'}, the last chunk has been completely read and no more
- input is valid.
- """
- state = 'CHUNK_LENGTH'
-
- def __init__(self, dataCallback, finishCallback):
- self.dataCallback = dataCallback
- self.finishCallback = finishCallback
- self._buffer = ''
-
- def _dataReceived_CHUNK_LENGTH(self, data):
- if '\r\n' in data:
- line, rest = data.split('\r\n', 1)
- parts = line.split(';')
- self.length = int(parts[0], 16)
- if self.length == 0:
- self.state = 'TRAILER'
- else:
- self.state = 'BODY'
- return rest
- else:
- self._buffer = data
- return ''
-
- def _dataReceived_CRLF(self, data):
- if data.startswith('\r\n'):
- self.state = 'CHUNK_LENGTH'
- return data[2:]
- else:
- self._buffer = data
- return ''
-
- def _dataReceived_TRAILER(self, data):
- if data.startswith('\r\n'):
- data = data[2:]
- self.state = 'FINISHED'
- self.finishCallback(data)
- else:
- self._buffer = data
- return ''
-
- def _dataReceived_BODY(self, data):
- if len(data) >= self.length:
- chunk, data = data[:self.length], data[self.length:]
- self.dataCallback(chunk)
- self.state = 'CRLF'
- return data
- elif len(data) < self.length:
- self.length -= len(data)
- self.dataCallback(data)
- return ''
-
- def _dataReceived_FINISHED(self, data):
- raise RuntimeError(
- "_ChunkedTransferDecoder.dataReceived called after last "
- "chunk was processed")
-
-
- def dataReceived(self, data):
- """
- Interpret data from a request or response body which uses the
- I{chunked} Transfer-Encoding.
- """
- data = self._buffer + data
- self._buffer = ''
- while data:
- data = getattr(self, '_dataReceived_%s' % (self.state,))(data)
-
-
- def noMoreData(self):
- """
- Verify that all data has been received. If it has not been, raise
- L{_DataLoss}.
- """
- if self.state != 'FINISHED':
- raise _DataLoss(
- "Chunked decoder in %r state, still expecting more data to "
- "get to 'FINISHED' state." % (self.state,))
-
-
-
-class HTTPChannel(basic.LineReceiver, policies.TimeoutMixin):
- """
- A receiver for HTTP requests.
-
- @ivar _transferDecoder: C{None} or an instance of
- L{_ChunkedTransferDecoder} if the request body uses the I{chunked}
- Transfer-Encoding.
- """
-
- maxHeaders = 500 # max number of headers allowed per request
-
- length = 0
- persistent = 1
- __header = ''
- __first_line = 1
- __content = None
-
- # set in instances or subclasses
- requestFactory = Request
-
- _savedTimeOut = None
- _receivedHeaderCount = 0
-
- def __init__(self):
- # the request queue
- self.requests = []
- self._transferDecoder = None
-
-
- def connectionMade(self):
- self.setTimeout(self.timeOut)
-
- def lineReceived(self, line):
- self.resetTimeout()
-
- if self.__first_line:
- # if this connection is not persistent, drop any data which
- # the client (illegally) sent after the last request.
- if not self.persistent:
- self.dataReceived = self.lineReceived = lambda *args: None
- return
-
- # IE sends an extraneous empty line (\r\n) after a POST request;
- # eat up such a line, but only ONCE
- if not line and self.__first_line == 1:
- self.__first_line = 2
- return
-
- # create a new Request object
- request = self.requestFactory(self, len(self.requests))
- self.requests.append(request)
-
- self.__first_line = 0
- parts = line.split()
- if len(parts) != 3:
- self.transport.write("HTTP/1.1 400 Bad Request\r\n\r\n")
- self.transport.loseConnection()
- return
- command, request, version = parts
- self._command = command
- self._path = request
- self._version = version
- elif line == '':
- if self.__header:
- self.headerReceived(self.__header)
- self.__header = ''
- self.allHeadersReceived()
- if self.length == 0:
- self.allContentReceived()
- else:
- self.setRawMode()
- elif line[0] in ' \t':
- self.__header = self.__header+'\n'+line
- else:
- if self.__header:
- self.headerReceived(self.__header)
- self.__header = line
-
-
- def _finishRequestBody(self, data):
- self.allContentReceived()
- self.setLineMode(data)
-
-
- def headerReceived(self, line):
- """
- Do pre-processing (for content-length) and store this header away.
- Enforce the per-request header limit.
-
- @type line: C{str}
- @param line: A line from the header section of a request, excluding the
- line delimiter.
- """
- header, data = line.split(':', 1)
- header = header.lower()
- data = data.strip()
- if header == 'content-length':
- self.length = int(data)
- self._transferDecoder = _IdentityTransferDecoder(
- self.length, self.requests[-1].handleContentChunk, self._finishRequestBody)
- elif header == 'transfer-encoding' and data.lower() == 'chunked':
- self.length = None
- self._transferDecoder = _ChunkedTransferDecoder(
- self.requests[-1].handleContentChunk, self._finishRequestBody)
- reqHeaders = self.requests[-1].requestHeaders
- values = reqHeaders.getRawHeaders(header)
- if values is not None:
- values.append(data)
- else:
- reqHeaders.setRawHeaders(header, [data])
-
- self._receivedHeaderCount += 1
- if self._receivedHeaderCount > self.maxHeaders:
- self.transport.write("HTTP/1.1 400 Bad Request\r\n\r\n")
- self.transport.loseConnection()
-
-
- def allContentReceived(self):
- command = self._command
- path = self._path
- version = self._version
-
- # reset ALL state variables, so we don't interfere with next request
- self.length = 0
- self._receivedHeaderCount = 0
- self.__first_line = 1
- self._transferDecoder = None
- del self._command, self._path, self._version
-
- # Disable the idle timeout, in case this request takes a long
- # time to finish generating output.
- if self.timeOut:
- self._savedTimeOut = self.setTimeout(None)
-
- req = self.requests[-1]
- req.requestReceived(command, path, version)
-
- def rawDataReceived(self, data):
- self.resetTimeout()
- self._transferDecoder.dataReceived(data)
-
-
- def allHeadersReceived(self):
- req = self.requests[-1]
- req.parseCookies()
- self.persistent = self.checkPersistence(req, self._version)
- req.gotLength(self.length)
- # Handle 'Expect: 100-continue' with automated 100 response code,
- # a simplistic implementation of RFC 2686 8.2.3:
- expectContinue = req.requestHeaders.getRawHeaders('expect')
- if (expectContinue and expectContinue[0].lower() == '100-continue' and
- self._version == 'HTTP/1.1'):
- req.transport.write("HTTP/1.1 100 Continue\r\n\r\n")
-
-
- def checkPersistence(self, request, version):
- """
- Check if the channel should close or not.
-
- @param request: The request most recently received over this channel
- against which checks will be made to determine if this connection
- can remain open after a matching response is returned.
-
- @type version: C{str}
- @param version: The version of the request.
-
- @rtype: C{bool}
- @return: A flag which, if C{True}, indicates that this connection may
- remain open to receive another request; if C{False}, the connection
- must be closed in order to indicate the completion of the response
- to C{request}.
- """
- connection = request.requestHeaders.getRawHeaders('connection')
- if connection:
- tokens = map(str.lower, connection[0].split(' '))
- else:
- tokens = []
-
- # HTTP 1.0 persistent connection support is currently disabled,
- # since we need a way to disable pipelining. HTTP 1.0 can't do
- # pipelining since we can't know in advance if we'll have a
- # content-length header, if we don't have the header we need to close the
- # connection. In HTTP 1.1 this is not an issue since we use chunked
- # encoding if content-length is not available.
-
- #if version == "HTTP/1.0":
- # if 'keep-alive' in tokens:
- # request.setHeader('connection', 'Keep-Alive')
- # return 1
- # else:
- # return 0
- if version == "HTTP/1.1":
- if 'close' in tokens:
- request.responseHeaders.setRawHeaders('connection', ['close'])
- return False
- else:
- return True
- else:
- return False
-
-
- def requestDone(self, request):
- """
- Called by first request in queue when it is done.
- """
- if request != self.requests[0]: raise TypeError
- del self.requests[0]
-
- if self.persistent:
- # notify next request it can start writing
- if self.requests:
- self.requests[0].noLongerQueued()
- else:
- if self._savedTimeOut:
- self.setTimeout(self._savedTimeOut)
- else:
- self.transport.loseConnection()
-
- def timeoutConnection(self):
- log.msg("Timing out client: %s" % str(self.transport.getPeer()))
- policies.TimeoutMixin.timeoutConnection(self)
-
- def connectionLost(self, reason):
- self.setTimeout(None)
- for request in self.requests:
- request.connectionLost(reason)
-
-
-class HTTPFactory(protocol.ServerFactory):
- """
- Factory for HTTP server.
-
- @ivar _logDateTime: A cached datetime string for log messages, updated by
- C{_logDateTimeCall}.
- @type _logDateTime: L{str}
-
- @ivar _logDateTimeCall: A delayed call for the next update to the cached log
- datetime string.
- @type _logDateTimeCall: L{IDelayedCall} provided
- """
-
- protocol = HTTPChannel
-
- logPath = None
-
- timeOut = 60 * 60 * 12
-
- def __init__(self, logPath=None, timeout=60*60*12):
- if logPath is not None:
- logPath = os.path.abspath(logPath)
- self.logPath = logPath
- self.timeOut = timeout
-
- # For storing the cached log datetime and the callback to update it
- self._logDateTime = None
- self._logDateTimeCall = None
-
-
- def _updateLogDateTime(self):
- """
- Update log datetime periodically, so we aren't always recalculating it.
- """
- self._logDateTime = datetimeToLogString()
- self._logDateTimeCall = reactor.callLater(1, self._updateLogDateTime)
-
-
- def buildProtocol(self, addr):
- p = protocol.ServerFactory.buildProtocol(self, addr)
- # timeOut needs to be on the Protocol instance cause
- # TimeoutMixin expects it there
- p.timeOut = self.timeOut
- return p
-
-
- def startFactory(self):
- """
- Set up request logging if necessary.
- """
- if self._logDateTimeCall is None:
- self._updateLogDateTime()
-
- if self.logPath:
- self.logFile = self._openLogFile(self.logPath)
- else:
- self.logFile = log.logfile
-
-
- def stopFactory(self):
- if hasattr(self, "logFile"):
- if self.logFile != log.logfile:
- self.logFile.close()
- del self.logFile
-
- if self._logDateTimeCall is not None and self._logDateTimeCall.active():
- self._logDateTimeCall.cancel()
- self._logDateTimeCall = None
-
-
- def _openLogFile(self, path):
- """
- Override in subclasses, e.g. to use twisted.python.logfile.
- """
- f = open(path, "a", 1)
- return f
-
- def _escape(self, s):
- # pain in the ass. Return a string like python repr, but always
- # escaped as if surrounding quotes were "".
- r = repr(s)
- if r[0] == "'":
- return r[1:-1].replace('"', '\\"').replace("\\'", "'")
- return r[1:-1]
-
- def log(self, request):
- """
- Log a request's result to the logfile, by default in combined log format.
- """
- if hasattr(self, "logFile"):
- line = '%s - - %s "%s" %d %s "%s" "%s"\n' % (
- request.getClientIP(),
- # request.getUser() or "-", # the remote user is almost never important
- self._logDateTime,
- '%s %s %s' % (self._escape(request.method),
- self._escape(request.uri),
- self._escape(request.clientproto)),
- request.code,
- request.sentLength or "-",
- self._escape(request.getHeader("referer") or "-"),
- self._escape(request.getHeader("user-agent") or "-"))
- self.logFile.write(line)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http_headers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http_headers.py
deleted file mode 100755
index f0d85997..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/http_headers.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_http_headers
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An API for storing HTTP header names and values.
-"""
-
-
-from UserDict import DictMixin
-
-
-def _dashCapitalize(name):
- """
- Return a string which is capitalized using '-' as a word separator.
-
- @param name: The name of the header to capitalize.
- @type name: str
-
- @return: The given header capitalized using '-' as a word separator.
- @rtype: str
- """
- return '-'.join([word.capitalize() for word in name.split('-')])
-
-
-
-class _DictHeaders(DictMixin):
- """
- A C{dict}-like wrapper around L{Headers} to provide backwards compatibility
- for L{Request.received_headers} and L{Request.headers} which used to be
- plain C{dict} instances.
-
- @type _headers: L{Headers}
- @ivar _headers: The real header storage object.
- """
- def __init__(self, headers):
- self._headers = headers
-
-
- def __getitem__(self, key):
- """
- Return the last value for header of C{key}.
- """
- if self._headers.hasHeader(key):
- return self._headers.getRawHeaders(key)[-1]
- raise KeyError(key)
-
-
- def __setitem__(self, key, value):
- """
- Set the given header.
- """
- self._headers.setRawHeaders(key, [value])
-
-
- def __delitem__(self, key):
- """
- Delete the given header.
- """
- if self._headers.hasHeader(key):
- self._headers.removeHeader(key)
- else:
- raise KeyError(key)
-
-
- def keys(self):
- """
- Return a list of all header names.
- """
- return [k.lower() for k, v in self._headers.getAllRawHeaders()]
-
-
- def copy(self):
- """
- Return a C{dict} mapping each header name to the last corresponding
- header value.
- """
- return dict(self.items())
-
-
- # Python 2.3 DictMixin.setdefault is defined so as not to have a default
- # for the value parameter. This is necessary to make this setdefault look
- # like dict.setdefault on Python 2.3. -exarkun
- def setdefault(self, name, value=None):
- """
- Retrieve the last value for the given header name. If there are no
- values present for that header, set the value to C{value} and return
- that instead. Note that C{None} is the default for C{value} for
- backwards compatibility, but header values may only be of type C{str}.
- """
- return DictMixin.setdefault(self, name, value)
-
-
- # The remaining methods are only for efficiency. The same behavior
- # should remain even if they are removed. For details, see
- # <http://docs.python.org/lib/module-UserDict.html>.
- # -exarkun
- def __contains__(self, name):
- """
- Return C{True} if the named header is present, C{False} otherwise.
- """
- return self._headers.getRawHeaders(name) is not None
-
-
- def __iter__(self):
- """
- Return an iterator of the lowercase name of each header present.
- """
- for k, v in self._headers.getAllRawHeaders():
- yield k.lower()
-
-
- def iteritems(self):
- """
- Return an iterable of two-tuples of each lower-case header name and the
- last value for that header.
- """
- for k, v in self._headers.getAllRawHeaders():
- yield k.lower(), v[-1]
-
-
-
-class Headers(object):
- """
- This class stores the HTTP headers as both a parsed representation
- and the raw string representation. It converts between the two on
- demand.
-
- @cvar _caseMappings: A C{dict} that maps lowercase header names
- to their canonicalized representation.
-
- @ivar _rawHeaders: A C{dict} mapping header names as C{str} to C{lists} of
- header values as C{str}.
- """
- _caseMappings = {
- 'content-md5': 'Content-MD5',
- 'dnt': 'DNT',
- 'etag': 'ETag',
- 'p3p': 'P3P',
- 'te': 'TE',
- 'www-authenticate': 'WWW-Authenticate',
- 'x-xss-protection': 'X-XSS-Protection'}
-
- def __init__(self, rawHeaders=None):
- self._rawHeaders = {}
- if rawHeaders is not None:
- for name, values in rawHeaders.iteritems():
- self.setRawHeaders(name, values[:])
-
-
- def __repr__(self):
- """
- Return a string fully describing the headers set on this object.
- """
- return '%s(%r)' % (self.__class__.__name__, self._rawHeaders,)
-
-
- def __cmp__(self, other):
- """
- Define L{Headers} instances as being equal to each other if they have
- the same raw headers.
- """
- if isinstance(other, Headers):
- return cmp(self._rawHeaders, other._rawHeaders)
- return NotImplemented
-
-
- def copy(self):
- """
- Return a copy of itself with the same headers set.
- """
- return self.__class__(self._rawHeaders)
-
-
- def hasHeader(self, name):
- """
- Check for the existence of a given header.
-
- @type name: C{str}
- @param name: The name of the HTTP header to check for.
-
- @rtype: C{bool}
- @return: C{True} if the header exists, otherwise C{False}.
- """
- return name.lower() in self._rawHeaders
-
-
- def removeHeader(self, name):
- """
- Remove the named header from this header object.
-
- @type name: C{str}
- @param name: The name of the HTTP header to remove.
-
- @return: C{None}
- """
- self._rawHeaders.pop(name.lower(), None)
-
-
- def setRawHeaders(self, name, values):
- """
- Sets the raw representation of the given header.
-
- @type name: C{str}
- @param name: The name of the HTTP header to set the values for.
-
- @type values: C{list}
- @param values: A list of strings each one being a header value of
- the given name.
-
- @return: C{None}
- """
- if not isinstance(values, list):
- raise TypeError("Header entry %r should be list but found "
- "instance of %r instead" % (name, type(values)))
- self._rawHeaders[name.lower()] = values
-
-
- def addRawHeader(self, name, value):
- """
- Add a new raw value for the given header.
-
- @type name: C{str}
- @param name: The name of the header for which to set the value.
-
- @type value: C{str}
- @param value: The value to set for the named header.
- """
- values = self.getRawHeaders(name)
- if values is None:
- self.setRawHeaders(name, [value])
- else:
- values.append(value)
-
-
- def getRawHeaders(self, name, default=None):
- """
- Returns a list of headers matching the given name as the raw string
- given.
-
- @type name: C{str}
- @param name: The name of the HTTP header to get the values of.
-
- @param default: The value to return if no header with the given C{name}
- exists.
-
- @rtype: C{list}
- @return: A C{list} of values for the given header.
- """
- return self._rawHeaders.get(name.lower(), default)
-
-
- def getAllRawHeaders(self):
- """
- Return an iterator of key, value pairs of all headers contained in this
- object, as strings. The keys are capitalized in canonical
- capitalization.
- """
- for k, v in self._rawHeaders.iteritems():
- yield self._canonicalNameCaps(k), v
-
-
- def _canonicalNameCaps(self, name):
- """
- Return the canonical name for the given header.
-
- @type name: C{str}
- @param name: The all-lowercase header name to capitalize in its
- canonical form.
-
- @rtype: C{str}
- @return: The canonical name of the header.
- """
- return self._caseMappings.get(name, _dashCapitalize(name))
-
-
-__all__ = ['Headers']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/iweb.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/iweb.py
deleted file mode 100755
index 6effd915..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/iweb.py
+++ /dev/null
@@ -1,526 +0,0 @@
-# -*- test-case-name: twisted.web.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Interface definitions for L{twisted.web}.
-
-@var UNKNOWN_LENGTH: An opaque object which may be used as the value of
- L{IBodyProducer.length} to indicate that the length of the entity
- body is not known in advance.
-"""
-
-from zope.interface import Interface, Attribute
-
-from twisted.internet.interfaces import IPushProducer
-from twisted.cred.credentials import IUsernameDigestHash
-
-
-class IRequest(Interface):
- """
- An HTTP request.
-
- @since: 9.0
- """
-
- method = Attribute("A C{str} giving the HTTP method that was used.")
- uri = Attribute(
- "A C{str} giving the full encoded URI which was requested (including "
- "query arguments).")
- path = Attribute(
- "A C{str} giving the encoded query path of the request URI.")
- args = Attribute(
- "A mapping of decoded query argument names as C{str} to "
- "corresponding query argument values as C{list}s of C{str}. "
- "For example, for a URI with C{'foo=bar&foo=baz&quux=spam'} "
- "for its query part, C{args} will be C{{'foo': ['bar', 'baz'], "
- "'quux': ['spam']}}.")
-
- received_headers = Attribute(
- "Backwards-compatibility access to C{requestHeaders}. Use "
- "C{requestHeaders} instead. C{received_headers} behaves mostly "
- "like a C{dict} and does not provide access to all header values.")
-
- requestHeaders = Attribute(
- "A L{http_headers.Headers} instance giving all received HTTP request "
- "headers.")
-
- headers = Attribute(
- "Backwards-compatibility access to C{responseHeaders}. Use"
- "C{responseHeaders} instead. C{headers} behaves mostly like a "
- "C{dict} and does not provide access to all header values nor "
- "does it allow multiple values for one header to be set.")
-
- responseHeaders = Attribute(
- "A L{http_headers.Headers} instance holding all HTTP response "
- "headers to be sent.")
-
- def getHeader(key):
- """
- Get an HTTP request header.
-
- @type key: C{str}
- @param key: The name of the header to get the value of.
-
- @rtype: C{str} or C{NoneType}
- @return: The value of the specified header, or C{None} if that header
- was not present in the request.
- """
-
-
- def getCookie(key):
- """
- Get a cookie that was sent from the network.
- """
-
-
- def getAllHeaders():
- """
- Return dictionary mapping the names of all received headers to the last
- value received for each.
-
- Since this method does not return all header information,
- C{requestHeaders.getAllRawHeaders()} may be preferred.
- """
-
-
- def getRequestHostname():
- """
- Get the hostname that the user passed in to the request.
-
- This will either use the Host: header (if it is available) or the
- host we are listening on if the header is unavailable.
-
- @returns: the requested hostname
- @rtype: C{str}
- """
-
-
- def getHost():
- """
- Get my originally requesting transport's host.
-
- @return: An L{IAddress}.
- """
-
-
- def getClientIP():
- """
- Return the IP address of the client who submitted this request.
-
- @returns: the client IP address or C{None} if the request was submitted
- over a transport where IP addresses do not make sense.
- @rtype: C{str} or L{NoneType}
- """
-
-
- def getClient():
- """
- Return the hostname of the IP address of the client who submitted this
- request, if possible.
-
- This method is B{deprecated}. See L{getClientIP} instead.
-
- @rtype: L{NoneType} or L{str}
- @return: The canonical hostname of the client, as determined by
- performing a name lookup on the IP address of the client.
- """
-
-
- def getUser():
- """
- Return the HTTP user sent with this request, if any.
-
- If no user was supplied, return the empty string.
-
- @returns: the HTTP user, if any
- @rtype: C{str}
- """
-
-
- def getPassword():
- """
- Return the HTTP password sent with this request, if any.
-
- If no password was supplied, return the empty string.
-
- @returns: the HTTP password, if any
- @rtype: C{str}
- """
-
-
- def isSecure():
- """
- Return True if this request is using a secure transport.
-
- Normally this method returns True if this request's HTTPChannel
- instance is using a transport that implements ISSLTransport.
-
- This will also return True if setHost() has been called
- with ssl=True.
-
- @returns: True if this request is secure
- @rtype: C{bool}
- """
-
-
- def getSession(sessionInterface=None):
- """
- Look up the session associated with this request or create a new one if
- there is not one.
-
- @return: The L{Session} instance identified by the session cookie in
- the request, or the C{sessionInterface} component of that session
- if C{sessionInterface} is specified.
- """
-
-
- def URLPath():
- """
- @return: A L{URLPath} instance which identifies the URL for which this
- request is.
- """
-
-
- def prePathURL():
- """
- @return: At any time during resource traversal, a L{str} giving an
- absolute URL to the most nested resource which has yet been
- reached.
- """
-
-
- def rememberRootURL():
- """
- Remember the currently-processed part of the URL for later
- recalling.
- """
-
-
- def getRootURL():
- """
- Get a previously-remembered URL.
- """
-
-
- # Methods for outgoing response
- def finish():
- """
- Indicate that the response to this request is complete.
- """
-
-
- def write(data):
- """
- Write some data to the body of the response to this request. Response
- headers are written the first time this method is called, after which
- new response headers may not be added.
- """
-
-
- def addCookie(k, v, expires=None, domain=None, path=None, max_age=None, comment=None, secure=None):
- """
- Set an outgoing HTTP cookie.
-
- In general, you should consider using sessions instead of cookies, see
- L{twisted.web.server.Request.getSession} and the
- L{twisted.web.server.Session} class for details.
- """
-
-
- def setResponseCode(code, message=None):
- """
- Set the HTTP response code.
- """
-
-
- def setHeader(k, v):
- """
- Set an HTTP response header. Overrides any previously set values for
- this header.
-
- @type name: C{str}
- @param name: The name of the header for which to set the value.
-
- @type value: C{str}
- @param value: The value to set for the named header.
- """
-
-
- def redirect(url):
- """
- Utility function that does a redirect.
-
- The request should have finish() called after this.
- """
-
-
- def setLastModified(when):
- """
- Set the C{Last-Modified} time for the response to this request.
-
- If I am called more than once, I ignore attempts to set Last-Modified
- earlier, only replacing the Last-Modified time if it is to a later
- value.
-
- If I am a conditional request, I may modify my response code to
- L{NOT_MODIFIED} if appropriate for the time given.
-
- @param when: The last time the resource being returned was modified, in
- seconds since the epoch.
- @type when: C{int}, C{long} or C{float}
-
- @return: If I am a C{If-Modified-Since} conditional request and the
- time given is not newer than the condition, I return
- L{http.CACHED<CACHED>} to indicate that you should write no body.
- Otherwise, I return a false value.
- """
-
-
- def setETag(etag):
- """
- Set an C{entity tag} for the outgoing response.
-
- That's "entity tag" as in the HTTP/1.1 C{ETag} header, "used for
- comparing two or more entities from the same requested resource."
-
- If I am a conditional request, I may modify my response code to
- L{NOT_MODIFIED} or L{PRECONDITION_FAILED}, if appropriate for the tag
- given.
-
- @param etag: The entity tag for the resource being returned.
- @type etag: C{str}
- @return: If I am a C{If-None-Match} conditional request and the tag
- matches one in the request, I return L{http.CACHED<CACHED>} to
- indicate that you should write no body. Otherwise, I return a
- false value.
- """
-
-
- def setHost(host, port, ssl=0):
- """
- Change the host and port the request thinks it's using.
-
- This method is useful for working with reverse HTTP proxies (e.g. both
- Squid and Apache's mod_proxy can do this), when the address the HTTP
- client is using is different than the one we're listening on.
-
- For example, Apache may be listening on https://www.example.com, and
- then forwarding requests to http://localhost:8080, but we don't want
- HTML produced by Twisted to say 'http://localhost:8080', they should
- say 'https://www.example.com', so we do::
-
- request.setHost('www.example.com', 443, ssl=1)
- """
-
-
-
-class ICredentialFactory(Interface):
- """
- A credential factory defines a way to generate a particular kind of
- authentication challenge and a way to interpret the responses to these
- challenges. It creates L{ICredentials} providers from responses. These
- objects will be used with L{twisted.cred} to authenticate an authorize
- requests.
- """
- scheme = Attribute(
- "A C{str} giving the name of the authentication scheme with which "
- "this factory is associated. For example, C{'basic'} or C{'digest'}.")
-
-
- def getChallenge(request):
- """
- Generate a new challenge to be sent to a client.
-
- @type peer: L{twisted.web.http.Request}
- @param peer: The request the response to which this challenge will be
- included.
-
- @rtype: C{dict}
- @return: A mapping from C{str} challenge fields to associated C{str}
- values.
- """
-
-
- def decode(response, request):
- """
- Create a credentials object from the given response.
-
- @type response: C{str}
- @param response: scheme specific response string
-
- @type request: L{twisted.web.http.Request}
- @param request: The request being processed (from which the response
- was taken).
-
- @raise twisted.cred.error.LoginFailed: If the response is invalid.
-
- @rtype: L{twisted.cred.credentials.ICredentials} provider
- @return: The credentials represented by the given response.
- """
-
-
-
-class IBodyProducer(IPushProducer):
- """
- Objects which provide L{IBodyProducer} write bytes to an object which
- provides L{IConsumer} by calling its C{write} method repeatedly.
-
- L{IBodyProducer} providers may start producing as soon as they have
- an L{IConsumer} provider. That is, they should not wait for a
- C{resumeProducing} call to begin writing data.
-
- L{IConsumer.unregisterProducer} must not be called. Instead, the
- L{Deferred} returned from C{startProducing} must be fired when all bytes
- have been written.
-
- L{IConsumer.write} may synchronously invoke any of C{pauseProducing},
- C{resumeProducing}, or C{stopProducing}. These methods must be implemented
- with this in mind.
-
- @since: 9.0
- """
-
- # Despite the restrictions above and the additional requirements of
- # stopProducing documented below, this interface still needs to be an
- # IPushProducer subclass. Providers of it will be passed to IConsumer
- # providers which only know about IPushProducer and IPullProducer, not
- # about this interface. This interface needs to remain close enough to one
- # of those interfaces for consumers to work with it.
-
- length = Attribute(
- """
- C{length} is a C{int} indicating how many bytes in total this
- L{IBodyProducer} will write to the consumer or L{UNKNOWN_LENGTH}
- if this is not known in advance.
- """)
-
- def startProducing(consumer):
- """
- Start producing to the given L{IConsumer} provider.
-
- @return: A L{Deferred} which fires with C{None} when all bytes have
- been produced or with a L{Failure} if there is any problem before
- all bytes have been produced.
- """
-
-
- def stopProducing():
- """
- In addition to the standard behavior of L{IProducer.stopProducing}
- (stop producing data), make sure the L{Deferred} returned by
- C{startProducing} is never fired.
- """
-
-
-
-class IRenderable(Interface):
- """
- An L{IRenderable} is an object that may be rendered by the
- L{twisted.web.template} templating system.
- """
-
- def lookupRenderMethod(name):
- """
- Look up and return the render method associated with the given name.
-
- @type name: C{str}
- @param name: The value of a render directive encountered in the
- document returned by a call to L{IRenderable.render}.
-
- @return: A two-argument callable which will be invoked with the request
- being responded to and the tag object on which the render directive
- was encountered.
- """
-
-
- def render(request):
- """
- Get the document for this L{IRenderable}.
-
- @type request: L{IRequest} provider or L{NoneType}
- @param request: The request in response to which this method is being
- invoked.
-
- @return: An object which can be flattened.
- """
-
-
-
-class ITemplateLoader(Interface):
- """
- A loader for templates; something usable as a value for
- L{twisted.web.template.Element}'s C{loader} attribute.
- """
-
- def load():
- """
- Load a template suitable for rendering.
-
- @return: a C{list} of C{list}s, C{unicode} objects, C{Element}s and
- other L{IRenderable} providers.
- """
-
-
-
-class IResponse(Interface):
- """
- An object representing an HTTP response received from an HTTP server.
-
- @since: 11.1
- """
-
- version = Attribute(
- "A three-tuple describing the protocol and protocol version "
- "of the response. The first element is of type C{str}, the second "
- "and third are of type C{int}. For example, C{('HTTP', 1, 1)}.")
-
-
- code = Attribute("The HTTP status code of this response, as a C{int}.")
-
-
- phrase = Attribute(
- "The HTTP reason phrase of this response, as a C{str}.")
-
-
- headers = Attribute("The HTTP response L{Headers} of this response.")
-
-
- length = Attribute(
- "The C{int} number of bytes expected to be in the body of this "
- "response or L{UNKNOWN_LENGTH} if the server did not indicate how "
- "many bytes to expect. For I{HEAD} responses, this will be 0; if "
- "the response includes a I{Content-Length} header, it will be "
- "available in C{headers}.")
-
-
- def deliverBody(protocol):
- """
- Register an L{IProtocol} provider to receive the response body.
-
- The protocol will be connected to a transport which provides
- L{IPushProducer}. The protocol's C{connectionLost} method will be
- called with:
-
- - ResponseDone, which indicates that all bytes from the response
- have been successfully delivered.
-
- - PotentialDataLoss, which indicates that it cannot be determined
- if the entire response body has been delivered. This only occurs
- when making requests to HTTP servers which do not set
- I{Content-Length} or a I{Transfer-Encoding} in the response.
-
- - ResponseFailed, which indicates that some bytes from the response
- were lost. The C{reasons} attribute of the exception may provide
- more specific indications as to why.
- """
-
-
-
-UNKNOWN_LENGTH = u"twisted.web.iweb.UNKNOWN_LENGTH"
-
-__all__ = [
- "IUsernameDigestHash", "ICredentialFactory", "IRequest",
- "IBodyProducer", "IRenderable", "IResponse",
-
- "UNKNOWN_LENGTH"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/microdom.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/microdom.py
deleted file mode 100755
index ca356120..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/microdom.py
+++ /dev/null
@@ -1,1028 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_xml -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Micro Document Object Model: a partial DOM implementation with SUX.
-
-This is an implementation of what we consider to be the useful subset of the
-DOM. The chief advantage of this library is that, not being burdened with
-standards compliance, it can remain very stable between versions. We can also
-implement utility 'pythonic' ways to access and mutate the XML tree.
-
-Since this has not subjected to a serious trial by fire, it is not recommended
-to use this outside of Twisted applications. However, it seems to work just
-fine for the documentation generator, which parses a fairly representative
-sample of XML.
-
-Microdom mainly focuses on working with HTML and XHTML.
-"""
-
-# System Imports
-import re
-from cStringIO import StringIO
-
-# create NodeList class
-from types import ListType as NodeList
-from types import StringTypes, UnicodeType
-
-# Twisted Imports
-from twisted.web.sux import XMLParser, ParseError
-from twisted.python.util import InsensitiveDict
-
-
-def getElementsByTagName(iNode, name):
- """
- Return a list of all child elements of C{iNode} with a name matching
- C{name}.
-
- Note that this implementation does not conform to the DOM Level 1 Core
- specification because it may return C{iNode}.
-
- @param iNode: An element at which to begin searching. If C{iNode} has a
- name matching C{name}, it will be included in the result.
-
- @param name: A C{str} giving the name of the elements to return.
-
- @return: A C{list} of direct or indirect child elements of C{iNode} with
- the name C{name}. This may include C{iNode}.
- """
- matches = []
- matches_append = matches.append # faster lookup. don't do this at home
- slice = [iNode]
- while len(slice)>0:
- c = slice.pop(0)
- if c.nodeName == name:
- matches_append(c)
- slice[:0] = c.childNodes
- return matches
-
-
-
-def getElementsByTagNameNoCase(iNode, name):
- name = name.lower()
- matches = []
- matches_append = matches.append
- slice=[iNode]
- while len(slice)>0:
- c = slice.pop(0)
- if c.nodeName.lower() == name:
- matches_append(c)
- slice[:0] = c.childNodes
- return matches
-
-# order is important
-HTML_ESCAPE_CHARS = (('&', '&amp;'), # don't add any entities before this one
- ('<', '&lt;'),
- ('>', '&gt;'),
- ('"', '&quot;'))
-REV_HTML_ESCAPE_CHARS = list(HTML_ESCAPE_CHARS)
-REV_HTML_ESCAPE_CHARS.reverse()
-
-XML_ESCAPE_CHARS = HTML_ESCAPE_CHARS + (("'", '&apos;'),)
-REV_XML_ESCAPE_CHARS = list(XML_ESCAPE_CHARS)
-REV_XML_ESCAPE_CHARS.reverse()
-
-def unescape(text, chars=REV_HTML_ESCAPE_CHARS):
- "Perform the exact opposite of 'escape'."
- for s, h in chars:
- text = text.replace(h, s)
- return text
-
-def escape(text, chars=HTML_ESCAPE_CHARS):
- "Escape a few XML special chars with XML entities."
- for s, h in chars:
- text = text.replace(s, h)
- return text
-
-
-class MismatchedTags(Exception):
-
- def __init__(self, filename, expect, got, endLine, endCol, begLine, begCol):
- (self.filename, self.expect, self.got, self.begLine, self.begCol, self.endLine,
- self.endCol) = filename, expect, got, begLine, begCol, endLine, endCol
-
- def __str__(self):
- return ("expected </%s>, got </%s> line: %s col: %s, began line: %s col: %s"
- % (self.expect, self.got, self.endLine, self.endCol, self.begLine,
- self.begCol))
-
-
-class Node(object):
- nodeName = "Node"
-
- def __init__(self, parentNode=None):
- self.parentNode = parentNode
- self.childNodes = []
-
- def isEqualToNode(self, other):
- """
- Compare this node to C{other}. If the nodes have the same number of
- children and corresponding children are equal to each other, return
- C{True}, otherwise return C{False}.
-
- @type other: L{Node}
- @rtype: C{bool}
- """
- if len(self.childNodes) != len(other.childNodes):
- return False
- for a, b in zip(self.childNodes, other.childNodes):
- if not a.isEqualToNode(b):
- return False
- return True
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- raise NotImplementedError()
-
- def toxml(self, indent='', addindent='', newl='', strip=0, nsprefixes={},
- namespace=''):
- s = StringIO()
- self.writexml(s, indent, addindent, newl, strip, nsprefixes, namespace)
- rv = s.getvalue()
- return rv
-
- def writeprettyxml(self, stream, indent='', addindent=' ', newl='\n', strip=0):
- return self.writexml(stream, indent, addindent, newl, strip)
-
- def toprettyxml(self, indent='', addindent=' ', newl='\n', strip=0):
- return self.toxml(indent, addindent, newl, strip)
-
- def cloneNode(self, deep=0, parent=None):
- raise NotImplementedError()
-
- def hasChildNodes(self):
- if self.childNodes:
- return 1
- else:
- return 0
-
-
- def appendChild(self, child):
- """
- Make the given L{Node} the last child of this node.
-
- @param child: The L{Node} which will become a child of this node.
-
- @raise TypeError: If C{child} is not a C{Node} instance.
- """
- if not isinstance(child, Node):
- raise TypeError("expected Node instance")
- self.childNodes.append(child)
- child.parentNode = self
-
-
- def insertBefore(self, new, ref):
- """
- Make the given L{Node} C{new} a child of this node which comes before
- the L{Node} C{ref}.
-
- @param new: A L{Node} which will become a child of this node.
-
- @param ref: A L{Node} which is already a child of this node which
- C{new} will be inserted before.
-
- @raise TypeError: If C{new} or C{ref} is not a C{Node} instance.
-
- @return: C{new}
- """
- if not isinstance(new, Node) or not isinstance(ref, Node):
- raise TypeError("expected Node instance")
- i = self.childNodes.index(ref)
- new.parentNode = self
- self.childNodes.insert(i, new)
- return new
-
-
- def removeChild(self, child):
- """
- Remove the given L{Node} from this node's children.
-
- @param child: A L{Node} which is a child of this node which will no
- longer be a child of this node after this method is called.
-
- @raise TypeError: If C{child} is not a C{Node} instance.
-
- @return: C{child}
- """
- if not isinstance(child, Node):
- raise TypeError("expected Node instance")
- if child in self.childNodes:
- self.childNodes.remove(child)
- child.parentNode = None
- return child
-
- def replaceChild(self, newChild, oldChild):
- """
- Replace a L{Node} which is already a child of this node with a
- different node.
-
- @param newChild: A L{Node} which will be made a child of this node.
-
- @param oldChild: A L{Node} which is a child of this node which will
- give up its position to C{newChild}.
-
- @raise TypeError: If C{newChild} or C{oldChild} is not a C{Node}
- instance.
-
- @raise ValueError: If C{oldChild} is not a child of this C{Node}.
- """
- if not isinstance(newChild, Node) or not isinstance(oldChild, Node):
- raise TypeError("expected Node instance")
- if oldChild.parentNode is not self:
- raise ValueError("oldChild is not a child of this node")
- self.childNodes[self.childNodes.index(oldChild)] = newChild
- oldChild.parentNode = None
- newChild.parentNode = self
-
-
- def lastChild(self):
- return self.childNodes[-1]
-
-
- def firstChild(self):
- if len(self.childNodes):
- return self.childNodes[0]
- return None
-
- #def get_ownerDocument(self):
- # """This doesn't really get the owner document; microdom nodes
- # don't even have one necessarily. This gets the root node,
- # which is usually what you really meant.
- # *NOT DOM COMPLIANT.*
- # """
- # node=self
- # while (node.parentNode): node=node.parentNode
- # return node
- #ownerDocument=node.get_ownerDocument()
- # leaving commented for discussion; see also domhelpers.getParents(node)
-
-class Document(Node):
-
- def __init__(self, documentElement=None):
- Node.__init__(self)
- if documentElement:
- self.appendChild(documentElement)
-
- def cloneNode(self, deep=0, parent=None):
- d = Document()
- d.doctype = self.doctype
- if deep:
- newEl = self.documentElement.cloneNode(1, self)
- else:
- newEl = self.documentElement
- d.appendChild(newEl)
- return d
-
- doctype = None
-
- def isEqualToDocument(self, n):
- return (self.doctype == n.doctype) and Node.isEqualToNode(self, n)
- isEqualToNode = isEqualToDocument
-
- def get_documentElement(self):
- return self.childNodes[0]
- documentElement=property(get_documentElement)
-
- def appendChild(self, child):
- """
- Make the given L{Node} the I{document element} of this L{Document}.
-
- @param child: The L{Node} to make into this L{Document}'s document
- element.
-
- @raise ValueError: If this document already has a document element.
- """
- if self.childNodes:
- raise ValueError("Only one element per document.")
- Node.appendChild(self, child)
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- stream.write('<?xml version="1.0"?>' + newl)
- if self.doctype:
- stream.write("<!DOCTYPE "+self.doctype+">" + newl)
- self.documentElement.writexml(stream, indent, addindent, newl, strip,
- nsprefixes, namespace)
-
- # of dubious utility (?)
- def createElement(self, name, **kw):
- return Element(name, **kw)
-
- def createTextNode(self, text):
- return Text(text)
-
- def createComment(self, text):
- return Comment(text)
-
- def getElementsByTagName(self, name):
- if self.documentElement.caseInsensitive:
- return getElementsByTagNameNoCase(self, name)
- return getElementsByTagName(self, name)
-
- def getElementById(self, id):
- childNodes = self.childNodes[:]
- while childNodes:
- node = childNodes.pop(0)
- if node.childNodes:
- childNodes.extend(node.childNodes)
- if hasattr(node, 'getAttribute') and node.getAttribute("id") == id:
- return node
-
-
-class EntityReference(Node):
-
- def __init__(self, eref, parentNode=None):
- Node.__init__(self, parentNode)
- self.eref = eref
- self.nodeValue = self.data = "&" + eref + ";"
-
- def isEqualToEntityReference(self, n):
- if not isinstance(n, EntityReference):
- return 0
- return (self.eref == n.eref) and (self.nodeValue == n.nodeValue)
- isEqualToNode = isEqualToEntityReference
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- stream.write(self.nodeValue)
-
- def cloneNode(self, deep=0, parent=None):
- return EntityReference(self.eref, parent)
-
-
-class CharacterData(Node):
-
- def __init__(self, data, parentNode=None):
- Node.__init__(self, parentNode)
- self.value = self.data = self.nodeValue = data
-
- def isEqualToCharacterData(self, n):
- return self.value == n.value
- isEqualToNode = isEqualToCharacterData
-
-
-class Comment(CharacterData):
- """A comment node."""
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- val=self.data
- if isinstance(val, UnicodeType):
- val=val.encode('utf8')
- stream.write("<!--%s-->" % val)
-
- def cloneNode(self, deep=0, parent=None):
- return Comment(self.nodeValue, parent)
-
-
-class Text(CharacterData):
-
- def __init__(self, data, parentNode=None, raw=0):
- CharacterData.__init__(self, data, parentNode)
- self.raw = raw
-
-
- def isEqualToNode(self, other):
- """
- Compare this text to C{text}. If the underlying values and the C{raw}
- flag are the same, return C{True}, otherwise return C{False}.
- """
- return (
- CharacterData.isEqualToNode(self, other) and
- self.raw == other.raw)
-
-
- def cloneNode(self, deep=0, parent=None):
- return Text(self.nodeValue, parent, self.raw)
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- if self.raw:
- val = self.nodeValue
- if not isinstance(val, StringTypes):
- val = str(self.nodeValue)
- else:
- v = self.nodeValue
- if not isinstance(v, StringTypes):
- v = str(v)
- if strip:
- v = ' '.join(v.split())
- val = escape(v)
- if isinstance(val, UnicodeType):
- val = val.encode('utf8')
- stream.write(val)
-
- def __repr__(self):
- return "Text(%s" % repr(self.nodeValue) + ')'
-
-
-class CDATASection(CharacterData):
- def cloneNode(self, deep=0, parent=None):
- return CDATASection(self.nodeValue, parent)
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- stream.write("<![CDATA[")
- stream.write(self.nodeValue)
- stream.write("]]>")
-
-def _genprefix():
- i = 0
- while True:
- yield 'p' + str(i)
- i = i + 1
-genprefix = _genprefix().next
-
-class _Attr(CharacterData):
- "Support class for getAttributeNode."
-
-class Element(Node):
-
- preserveCase = 0
- caseInsensitive = 1
- nsprefixes = None
-
- def __init__(self, tagName, attributes=None, parentNode=None,
- filename=None, markpos=None,
- caseInsensitive=1, preserveCase=0,
- namespace=None):
- Node.__init__(self, parentNode)
- self.preserveCase = preserveCase or not caseInsensitive
- self.caseInsensitive = caseInsensitive
- if not preserveCase:
- tagName = tagName.lower()
- if attributes is None:
- self.attributes = {}
- else:
- self.attributes = attributes
- for k, v in self.attributes.items():
- self.attributes[k] = unescape(v)
-
- if caseInsensitive:
- self.attributes = InsensitiveDict(self.attributes,
- preserve=preserveCase)
-
- self.endTagName = self.nodeName = self.tagName = tagName
- self._filename = filename
- self._markpos = markpos
- self.namespace = namespace
-
- def addPrefixes(self, pfxs):
- if self.nsprefixes is None:
- self.nsprefixes = pfxs
- else:
- self.nsprefixes.update(pfxs)
-
- def endTag(self, endTagName):
- if not self.preserveCase:
- endTagName = endTagName.lower()
- self.endTagName = endTagName
-
- def isEqualToElement(self, n):
- if self.caseInsensitive:
- return ((self.attributes == n.attributes)
- and (self.nodeName.lower() == n.nodeName.lower()))
- return (self.attributes == n.attributes) and (self.nodeName == n.nodeName)
-
-
- def isEqualToNode(self, other):
- """
- Compare this element to C{other}. If the C{nodeName}, C{namespace},
- C{attributes}, and C{childNodes} are all the same, return C{True},
- otherwise return C{False}.
- """
- return (
- self.nodeName.lower() == other.nodeName.lower() and
- self.namespace == other.namespace and
- self.attributes == other.attributes and
- Node.isEqualToNode(self, other))
-
-
- def cloneNode(self, deep=0, parent=None):
- clone = Element(
- self.tagName, parentNode=parent, namespace=self.namespace,
- preserveCase=self.preserveCase, caseInsensitive=self.caseInsensitive)
- clone.attributes.update(self.attributes)
- if deep:
- clone.childNodes = [child.cloneNode(1, clone) for child in self.childNodes]
- else:
- clone.childNodes = []
- return clone
-
- def getElementsByTagName(self, name):
- if self.caseInsensitive:
- return getElementsByTagNameNoCase(self, name)
- return getElementsByTagName(self, name)
-
- def hasAttributes(self):
- return 1
-
- def getAttribute(self, name, default=None):
- return self.attributes.get(name, default)
-
- def getAttributeNS(self, ns, name, default=None):
- nsk = (ns, name)
- if self.attributes.has_key(nsk):
- return self.attributes[nsk]
- if ns == self.namespace:
- return self.attributes.get(name, default)
- return default
-
- def getAttributeNode(self, name):
- return _Attr(self.getAttribute(name), self)
-
- def setAttribute(self, name, attr):
- self.attributes[name] = attr
-
- def removeAttribute(self, name):
- if name in self.attributes:
- del self.attributes[name]
-
- def hasAttribute(self, name):
- return name in self.attributes
-
-
- def writexml(self, stream, indent='', addindent='', newl='', strip=0,
- nsprefixes={}, namespace=''):
- """
- Serialize this L{Element} to the given stream.
-
- @param stream: A file-like object to which this L{Element} will be
- written.
-
- @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to
- prefixes as C{str}. This defines the prefixes which are already in
- scope in the document at the point at which this L{Element} exists.
- This is essentially an implementation detail for namespace support.
- Applications should not try to use it.
-
- @param namespace: The namespace URI as a C{str} which is the default at
- the point in the document at which this L{Element} exists. This is
- essentially an implementation detail for namespace support.
- Applications should not try to use it.
- """
- # write beginning
- ALLOWSINGLETON = ('img', 'br', 'hr', 'base', 'meta', 'link', 'param',
- 'area', 'input', 'col', 'basefont', 'isindex',
- 'frame')
- BLOCKELEMENTS = ('html', 'head', 'body', 'noscript', 'ins', 'del',
- 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'script',
- 'ul', 'ol', 'dl', 'pre', 'hr', 'blockquote',
- 'address', 'p', 'div', 'fieldset', 'table', 'tr',
- 'form', 'object', 'fieldset', 'applet', 'map')
- FORMATNICELY = ('tr', 'ul', 'ol', 'head')
-
- # this should never be necessary unless people start
- # changing .tagName on the fly(?)
- if not self.preserveCase:
- self.endTagName = self.tagName
- w = stream.write
- if self.nsprefixes:
- newprefixes = self.nsprefixes.copy()
- for ns in nsprefixes.keys():
- if ns in newprefixes:
- del newprefixes[ns]
- else:
- newprefixes = {}
-
- begin = ['<']
- if self.tagName in BLOCKELEMENTS:
- begin = [newl, indent] + begin
- bext = begin.extend
- writeattr = lambda _atr, _val: bext((' ', _atr, '="', escape(_val), '"'))
-
- # Make a local for tracking what end tag will be used. If namespace
- # prefixes are involved, this will be changed to account for that
- # before it's actually used.
- endTagName = self.endTagName
-
- if namespace != self.namespace and self.namespace is not None:
- # If the current default namespace is not the namespace of this tag
- # (and this tag has a namespace at all) then we'll write out
- # something related to namespaces.
- if self.namespace in nsprefixes:
- # This tag's namespace already has a prefix bound to it. Use
- # that prefix.
- prefix = nsprefixes[self.namespace]
- bext(prefix + ':' + self.tagName)
- # Also make sure we use it for the end tag.
- endTagName = prefix + ':' + self.endTagName
- else:
- # This tag's namespace has no prefix bound to it. Change the
- # default namespace to this tag's namespace so we don't need
- # prefixes. Alternatively, we could add a new prefix binding.
- # I'm not sure why the code was written one way rather than the
- # other. -exarkun
- bext(self.tagName)
- writeattr("xmlns", self.namespace)
- # The default namespace just changed. Make sure any children
- # know about this.
- namespace = self.namespace
- else:
- # This tag has no namespace or its namespace is already the default
- # namespace. Nothing extra to do here.
- bext(self.tagName)
-
- j = ''.join
- for attr, val in self.attributes.iteritems():
- if isinstance(attr, tuple):
- ns, key = attr
- if nsprefixes.has_key(ns):
- prefix = nsprefixes[ns]
- else:
- prefix = genprefix()
- newprefixes[ns] = prefix
- assert val is not None
- writeattr(prefix+':'+key,val)
- else:
- assert val is not None
- writeattr(attr, val)
- if newprefixes:
- for ns, prefix in newprefixes.iteritems():
- if prefix:
- writeattr('xmlns:'+prefix, ns)
- newprefixes.update(nsprefixes)
- downprefixes = newprefixes
- else:
- downprefixes = nsprefixes
- w(j(begin))
- if self.childNodes:
- w(">")
- newindent = indent + addindent
- for child in self.childNodes:
- if self.tagName in BLOCKELEMENTS and \
- self.tagName in FORMATNICELY:
- w(j((newl, newindent)))
- child.writexml(stream, newindent, addindent, newl, strip,
- downprefixes, namespace)
- if self.tagName in BLOCKELEMENTS:
- w(j((newl, indent)))
- w(j(('</', endTagName, '>')))
- elif self.tagName.lower() not in ALLOWSINGLETON:
- w(j(('></', endTagName, '>')))
- else:
- w(" />")
-
-
- def __repr__(self):
- rep = "Element(%s" % repr(self.nodeName)
- if self.attributes:
- rep += ", attributes=%r" % (self.attributes,)
- if self._filename:
- rep += ", filename=%r" % (self._filename,)
- if self._markpos:
- rep += ", markpos=%r" % (self._markpos,)
- return rep + ')'
-
- def __str__(self):
- rep = "<" + self.nodeName
- if self._filename or self._markpos:
- rep += " ("
- if self._filename:
- rep += repr(self._filename)
- if self._markpos:
- rep += " line %s column %s" % self._markpos
- if self._filename or self._markpos:
- rep += ")"
- for item in self.attributes.items():
- rep += " %s=%r" % item
- if self.hasChildNodes():
- rep += " >...</%s>" % self.nodeName
- else:
- rep += " />"
- return rep
-
-def _unescapeDict(d):
- dd = {}
- for k, v in d.items():
- dd[k] = unescape(v)
- return dd
-
-def _reverseDict(d):
- dd = {}
- for k, v in d.items():
- dd[v]=k
- return dd
-
-class MicroDOMParser(XMLParser):
-
- # <dash> glyph: a quick scan thru the DTD says BODY, AREA, LINK, IMG, HR,
- # P, DT, DD, LI, INPUT, OPTION, THEAD, TFOOT, TBODY, COLGROUP, COL, TR, TH,
- # TD, HEAD, BASE, META, HTML all have optional closing tags
-
- soonClosers = 'area link br img hr input base meta'.split()
- laterClosers = {'p': ['p', 'dt'],
- 'dt': ['dt','dd'],
- 'dd': ['dt', 'dd'],
- 'li': ['li'],
- 'tbody': ['thead', 'tfoot', 'tbody'],
- 'thead': ['thead', 'tfoot', 'tbody'],
- 'tfoot': ['thead', 'tfoot', 'tbody'],
- 'colgroup': ['colgroup'],
- 'col': ['col'],
- 'tr': ['tr'],
- 'td': ['td'],
- 'th': ['th'],
- 'head': ['body'],
- 'title': ['head', 'body'], # this looks wrong...
- 'option': ['option'],
- }
-
-
- def __init__(self, beExtremelyLenient=0, caseInsensitive=1, preserveCase=0,
- soonClosers=soonClosers, laterClosers=laterClosers):
- self.elementstack = []
- d = {'xmlns': 'xmlns', '': None}
- dr = _reverseDict(d)
- self.nsstack = [(d,None,dr)]
- self.documents = []
- self._mddoctype = None
- self.beExtremelyLenient = beExtremelyLenient
- self.caseInsensitive = caseInsensitive
- self.preserveCase = preserveCase or not caseInsensitive
- self.soonClosers = soonClosers
- self.laterClosers = laterClosers
- # self.indentlevel = 0
-
- def shouldPreserveSpace(self):
- for edx in xrange(len(self.elementstack)):
- el = self.elementstack[-edx]
- if el.tagName == 'pre' or el.getAttribute("xml:space", '') == 'preserve':
- return 1
- return 0
-
- def _getparent(self):
- if self.elementstack:
- return self.elementstack[-1]
- else:
- return None
-
- COMMENT = re.compile(r"\s*/[/*]\s*")
-
- def _fixScriptElement(self, el):
- # this deals with case where there is comment or CDATA inside
- # <script> tag and we want to do the right thing with it
- if not self.beExtremelyLenient or not len(el.childNodes) == 1:
- return
- c = el.firstChild()
- if isinstance(c, Text):
- # deal with nasty people who do stuff like:
- # <script> // <!--
- # x = 1;
- # // --></script>
- # tidy does this, for example.
- prefix = ""
- oldvalue = c.value
- match = self.COMMENT.match(oldvalue)
- if match:
- prefix = match.group()
- oldvalue = oldvalue[len(prefix):]
-
- # now see if contents are actual node and comment or CDATA
- try:
- e = parseString("<a>%s</a>" % oldvalue).childNodes[0]
- except (ParseError, MismatchedTags):
- return
- if len(e.childNodes) != 1:
- return
- e = e.firstChild()
- if isinstance(e, (CDATASection, Comment)):
- el.childNodes = []
- if prefix:
- el.childNodes.append(Text(prefix))
- el.childNodes.append(e)
-
- def gotDoctype(self, doctype):
- self._mddoctype = doctype
-
- def gotTagStart(self, name, attributes):
- # print ' '*self.indentlevel, 'start tag',name
- # self.indentlevel += 1
- parent = self._getparent()
- if (self.beExtremelyLenient and isinstance(parent, Element)):
- parentName = parent.tagName
- myName = name
- if self.caseInsensitive:
- parentName = parentName.lower()
- myName = myName.lower()
- if myName in self.laterClosers.get(parentName, []):
- self.gotTagEnd(parent.tagName)
- parent = self._getparent()
- attributes = _unescapeDict(attributes)
- namespaces = self.nsstack[-1][0]
- newspaces = {}
- for k, v in attributes.items():
- if k.startswith('xmlns'):
- spacenames = k.split(':',1)
- if len(spacenames) == 2:
- newspaces[spacenames[1]] = v
- else:
- newspaces[''] = v
- del attributes[k]
- if newspaces:
- namespaces = namespaces.copy()
- namespaces.update(newspaces)
- for k, v in attributes.items():
- ksplit = k.split(':', 1)
- if len(ksplit) == 2:
- pfx, tv = ksplit
- if pfx != 'xml' and pfx in namespaces:
- attributes[namespaces[pfx], tv] = v
- del attributes[k]
- el = Element(name, attributes, parent,
- self.filename, self.saveMark(),
- caseInsensitive=self.caseInsensitive,
- preserveCase=self.preserveCase,
- namespace=namespaces.get(''))
- revspaces = _reverseDict(newspaces)
- el.addPrefixes(revspaces)
-
- if newspaces:
- rscopy = self.nsstack[-1][2].copy()
- rscopy.update(revspaces)
- self.nsstack.append((namespaces, el, rscopy))
- self.elementstack.append(el)
- if parent:
- parent.appendChild(el)
- if (self.beExtremelyLenient and el.tagName in self.soonClosers):
- self.gotTagEnd(name)
-
- def _gotStandalone(self, factory, data):
- parent = self._getparent()
- te = factory(data, parent)
- if parent:
- parent.appendChild(te)
- elif self.beExtremelyLenient:
- self.documents.append(te)
-
- def gotText(self, data):
- if data.strip() or self.shouldPreserveSpace():
- self._gotStandalone(Text, data)
-
- def gotComment(self, data):
- self._gotStandalone(Comment, data)
-
- def gotEntityReference(self, entityRef):
- self._gotStandalone(EntityReference, entityRef)
-
- def gotCData(self, cdata):
- self._gotStandalone(CDATASection, cdata)
-
- def gotTagEnd(self, name):
- # print ' '*self.indentlevel, 'end tag',name
- # self.indentlevel -= 1
- if not self.elementstack:
- if self.beExtremelyLenient:
- return
- raise MismatchedTags(*((self.filename, "NOTHING", name)
- +self.saveMark()+(0,0)))
- el = self.elementstack.pop()
- pfxdix = self.nsstack[-1][2]
- if self.nsstack[-1][1] is el:
- nstuple = self.nsstack.pop()
- else:
- nstuple = None
- if self.caseInsensitive:
- tn = el.tagName.lower()
- cname = name.lower()
- else:
- tn = el.tagName
- cname = name
-
- nsplit = name.split(':',1)
- if len(nsplit) == 2:
- pfx, newname = nsplit
- ns = pfxdix.get(pfx,None)
- if ns is not None:
- if el.namespace != ns:
- if not self.beExtremelyLenient:
- raise MismatchedTags(*((self.filename, el.tagName, name)
- +self.saveMark()+el._markpos))
- if not (tn == cname):
- if self.beExtremelyLenient:
- if self.elementstack:
- lastEl = self.elementstack[0]
- for idx in xrange(len(self.elementstack)):
- if self.elementstack[-(idx+1)].tagName == cname:
- self.elementstack[-(idx+1)].endTag(name)
- break
- else:
- # this was a garbage close tag; wait for a real one
- self.elementstack.append(el)
- if nstuple is not None:
- self.nsstack.append(nstuple)
- return
- del self.elementstack[-(idx+1):]
- if not self.elementstack:
- self.documents.append(lastEl)
- return
- else:
- raise MismatchedTags(*((self.filename, el.tagName, name)
- +self.saveMark()+el._markpos))
- el.endTag(name)
- if not self.elementstack:
- self.documents.append(el)
- if self.beExtremelyLenient and el.tagName == "script":
- self._fixScriptElement(el)
-
- def connectionLost(self, reason):
- XMLParser.connectionLost(self, reason) # This can cause more events!
- if self.elementstack:
- if self.beExtremelyLenient:
- self.documents.append(self.elementstack[0])
- else:
- raise MismatchedTags(*((self.filename, self.elementstack[-1],
- "END_OF_FILE")
- +self.saveMark()
- +self.elementstack[-1]._markpos))
-
-
-def parse(readable, *args, **kwargs):
- """Parse HTML or XML readable."""
- if not hasattr(readable, "read"):
- readable = open(readable, "rb")
- mdp = MicroDOMParser(*args, **kwargs)
- mdp.filename = getattr(readable, "name", "<xmlfile />")
- mdp.makeConnection(None)
- if hasattr(readable,"getvalue"):
- mdp.dataReceived(readable.getvalue())
- else:
- r = readable.read(1024)
- while r:
- mdp.dataReceived(r)
- r = readable.read(1024)
- mdp.connectionLost(None)
-
- if not mdp.documents:
- raise ParseError(mdp.filename, 0, 0, "No top-level Nodes in document")
-
- if mdp.beExtremelyLenient:
- if len(mdp.documents) == 1:
- d = mdp.documents[0]
- if not isinstance(d, Element):
- el = Element("html")
- el.appendChild(d)
- d = el
- else:
- d = Element("html")
- for child in mdp.documents:
- d.appendChild(child)
- else:
- d = mdp.documents[0]
- doc = Document(d)
- doc.doctype = mdp._mddoctype
- return doc
-
-def parseString(st, *args, **kw):
- if isinstance(st, UnicodeType):
- # this isn't particularly ideal, but it does work.
- return parse(StringIO(st.encode('UTF-16')), *args, **kw)
- return parse(StringIO(st), *args, **kw)
-
-
-def parseXML(readable):
- """Parse an XML readable object."""
- return parse(readable, caseInsensitive=0, preserveCase=1)
-
-
-def parseXMLString(st):
- """Parse an XML readable object."""
- return parseString(st, caseInsensitive=0, preserveCase=1)
-
-
-# Utility
-
-class lmx:
- """Easy creation of XML."""
-
- def __init__(self, node='div'):
- if isinstance(node, StringTypes):
- node = Element(node)
- self.node = node
-
- def __getattr__(self, name):
- if name[0] == '_':
- raise AttributeError("no private attrs")
- return lambda **kw: self.add(name,**kw)
-
- def __setitem__(self, key, val):
- self.node.setAttribute(key, val)
-
- def __getitem__(self, key):
- return self.node.getAttribute(key)
-
- def text(self, txt, raw=0):
- nn = Text(txt, raw=raw)
- self.node.appendChild(nn)
- return self
-
- def add(self, tagName, **kw):
- newNode = Element(tagName, caseInsensitive=0, preserveCase=0)
- self.node.appendChild(newNode)
- xf = lmx(newNode)
- for k, v in kw.items():
- if k[0] == '_':
- k = k[1:]
- xf[k]=v
- return xf
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/proxy.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/proxy.py
deleted file mode 100755
index 68bce7db..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/proxy.py
+++ /dev/null
@@ -1,303 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_proxy -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Simplistic HTTP proxy support.
-
-This comes in two main variants - the Proxy and the ReverseProxy.
-
-When a Proxy is in use, a browser trying to connect to a server (say,
-www.yahoo.com) will be intercepted by the Proxy, and the proxy will covertly
-connect to the server, and return the result.
-
-When a ReverseProxy is in use, the client connects directly to the ReverseProxy
-(say, www.yahoo.com) which farms off the request to one of a pool of servers,
-and returns the result.
-
-Normally, a Proxy is used on the client end of an Internet connection, while a
-ReverseProxy is used on the server end.
-"""
-
-import urlparse
-from urllib import quote as urlquote
-
-from twisted.internet import reactor
-from twisted.internet.protocol import ClientFactory
-from twisted.web.resource import Resource
-from twisted.web.server import NOT_DONE_YET
-from twisted.web.http import HTTPClient, Request, HTTPChannel
-
-
-
-class ProxyClient(HTTPClient):
- """
- Used by ProxyClientFactory to implement a simple web proxy.
-
- @ivar _finished: A flag which indicates whether or not the original request
- has been finished yet.
- """
- _finished = False
-
- def __init__(self, command, rest, version, headers, data, father):
- self.father = father
- self.command = command
- self.rest = rest
- if "proxy-connection" in headers:
- del headers["proxy-connection"]
- headers["connection"] = "close"
- headers.pop('keep-alive', None)
- self.headers = headers
- self.data = data
-
-
- def connectionMade(self):
- self.sendCommand(self.command, self.rest)
- for header, value in self.headers.items():
- self.sendHeader(header, value)
- self.endHeaders()
- self.transport.write(self.data)
-
-
- def handleStatus(self, version, code, message):
- self.father.setResponseCode(int(code), message)
-
-
- def handleHeader(self, key, value):
- # t.web.server.Request sets default values for these headers in its
- # 'process' method. When these headers are received from the remote
- # server, they ought to override the defaults, rather than append to
- # them.
- if key.lower() in ['server', 'date', 'content-type']:
- self.father.responseHeaders.setRawHeaders(key, [value])
- else:
- self.father.responseHeaders.addRawHeader(key, value)
-
-
- def handleResponsePart(self, buffer):
- self.father.write(buffer)
-
-
- def handleResponseEnd(self):
- """
- Finish the original request, indicating that the response has been
- completely written to it, and disconnect the outgoing transport.
- """
- if not self._finished:
- self._finished = True
- self.father.finish()
- self.transport.loseConnection()
-
-
-
-class ProxyClientFactory(ClientFactory):
- """
- Used by ProxyRequest to implement a simple web proxy.
- """
-
- protocol = ProxyClient
-
-
- def __init__(self, command, rest, version, headers, data, father):
- self.father = father
- self.command = command
- self.rest = rest
- self.headers = headers
- self.data = data
- self.version = version
-
-
- def buildProtocol(self, addr):
- return self.protocol(self.command, self.rest, self.version,
- self.headers, self.data, self.father)
-
-
- def clientConnectionFailed(self, connector, reason):
- """
- Report a connection failure in a response to the incoming request as
- an error.
- """
- self.father.setResponseCode(501, "Gateway error")
- self.father.responseHeaders.addRawHeader("Content-Type", "text/html")
- self.father.write("<H1>Could not connect</H1>")
- self.father.finish()
-
-
-
-class ProxyRequest(Request):
- """
- Used by Proxy to implement a simple web proxy.
-
- @ivar reactor: the reactor used to create connections.
- @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
- """
-
- protocols = {'http': ProxyClientFactory}
- ports = {'http': 80}
-
- def __init__(self, channel, queued, reactor=reactor):
- Request.__init__(self, channel, queued)
- self.reactor = reactor
-
-
- def process(self):
- parsed = urlparse.urlparse(self.uri)
- protocol = parsed[0]
- host = parsed[1]
- port = self.ports[protocol]
- if ':' in host:
- host, port = host.split(':')
- port = int(port)
- rest = urlparse.urlunparse(('', '') + parsed[2:])
- if not rest:
- rest = rest + '/'
- class_ = self.protocols[protocol]
- headers = self.getAllHeaders().copy()
- if 'host' not in headers:
- headers['host'] = host
- self.content.seek(0, 0)
- s = self.content.read()
- clientFactory = class_(self.method, rest, self.clientproto, headers,
- s, self)
- self.reactor.connectTCP(host, port, clientFactory)
-
-
-
-class Proxy(HTTPChannel):
- """
- This class implements a simple web proxy.
-
- Since it inherits from L{twisted.web.http.HTTPChannel}, to use it you
- should do something like this::
-
- from twisted.web import http
- f = http.HTTPFactory()
- f.protocol = Proxy
-
- Make the HTTPFactory a listener on a port as per usual, and you have
- a fully-functioning web proxy!
- """
-
- requestFactory = ProxyRequest
-
-
-
-class ReverseProxyRequest(Request):
- """
- Used by ReverseProxy to implement a simple reverse proxy.
-
- @ivar proxyClientFactoryClass: a proxy client factory class, used to create
- new connections.
- @type proxyClientFactoryClass: L{ClientFactory}
-
- @ivar reactor: the reactor used to create connections.
- @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
- """
-
- proxyClientFactoryClass = ProxyClientFactory
-
- def __init__(self, channel, queued, reactor=reactor):
- Request.__init__(self, channel, queued)
- self.reactor = reactor
-
-
- def process(self):
- """
- Handle this request by connecting to the proxied server and forwarding
- it there, then forwarding the response back as the response to this
- request.
- """
- self.received_headers['host'] = self.factory.host
- clientFactory = self.proxyClientFactoryClass(
- self.method, self.uri, self.clientproto, self.getAllHeaders(),
- self.content.read(), self)
- self.reactor.connectTCP(self.factory.host, self.factory.port,
- clientFactory)
-
-
-
-class ReverseProxy(HTTPChannel):
- """
- Implements a simple reverse proxy.
-
- For details of usage, see the file examples/reverse-proxy.py.
- """
-
- requestFactory = ReverseProxyRequest
-
-
-
-class ReverseProxyResource(Resource):
- """
- Resource that renders the results gotten from another server
-
- Put this resource in the tree to cause everything below it to be relayed
- to a different server.
-
- @ivar proxyClientFactoryClass: a proxy client factory class, used to create
- new connections.
- @type proxyClientFactoryClass: L{ClientFactory}
-
- @ivar reactor: the reactor used to create connections.
- @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
- """
-
- proxyClientFactoryClass = ProxyClientFactory
-
-
- def __init__(self, host, port, path, reactor=reactor):
- """
- @param host: the host of the web server to proxy.
- @type host: C{str}
-
- @param port: the port of the web server to proxy.
- @type port: C{port}
-
- @param path: the base path to fetch data from. Note that you shouldn't
- put any trailing slashes in it, it will be added automatically in
- request. For example, if you put B{/foo}, a request on B{/bar} will
- be proxied to B{/foo/bar}. Any required encoding of special
- characters (such as " " or "/") should have been done already.
-
- @type path: C{str}
- """
- Resource.__init__(self)
- self.host = host
- self.port = port
- self.path = path
- self.reactor = reactor
-
-
- def getChild(self, path, request):
- """
- Create and return a proxy resource with the same proxy configuration
- as this one, except that its path also contains the segment given by
- C{path} at the end.
- """
- return ReverseProxyResource(
- self.host, self.port, self.path + '/' + urlquote(path, safe=""),
- self.reactor)
-
-
- def render(self, request):
- """
- Render a request by forwarding it to the proxied server.
- """
- # RFC 2616 tells us that we can omit the port if it's the default port,
- # but we have to provide it otherwise
- if self.port == 80:
- host = self.host
- else:
- host = "%s:%d" % (self.host, self.port)
- request.received_headers['host'] = host
- request.content.seek(0, 0)
- qs = urlparse.urlparse(request.uri)[4]
- if qs:
- rest = self.path + '?' + qs
- else:
- rest = self.path
- clientFactory = self.proxyClientFactoryClass(
- request.method, rest, request.clientproto,
- request.getAllHeaders(), request.content.read(), request)
- self.reactor.connectTCP(self.host, self.port, clientFactory)
- return NOT_DONE_YET
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/resource.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/resource.py
deleted file mode 100755
index bf76ce2e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/resource.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_web -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Implementation of the lowest-level Resource class.
-"""
-
-import warnings
-
-from zope.interface import Attribute, implements, Interface
-
-from twisted.python.reflect import prefixedMethodNames
-from twisted.web import http
-
-
-class IResource(Interface):
- """
- A web resource.
- """
-
- isLeaf = Attribute(
- """
- Signal if this IResource implementor is a "leaf node" or not. If True,
- getChildWithDefault will not be called on this Resource.
- """)
-
- def getChildWithDefault(name, request):
- """
- Return a child with the given name for the given request.
- This is the external interface used by the Resource publishing
- machinery. If implementing IResource without subclassing
- Resource, it must be provided. However, if subclassing Resource,
- getChild overridden instead.
- """
-
- def putChild(path, child):
- """
- Put a child IResource implementor at the given path.
- """
-
- def render(request):
- """
- Render a request. This is called on the leaf resource for
- a request. Render must return either a string, which will
- be sent to the browser as the HTML for the request, or
- server.NOT_DONE_YET. If NOT_DONE_YET is returned,
- at some point later (in a Deferred callback, usually)
- call request.write("<html>") to write data to the request,
- and request.finish() to send the data to the browser.
-
- L{twisted.web.error.UnsupportedMethod} can be raised if the
- HTTP verb requested is not supported by this resource.
- """
-
-
-
-def getChildForRequest(resource, request):
- """
- Traverse resource tree to find who will handle the request.
- """
- while request.postpath and not resource.isLeaf:
- pathElement = request.postpath.pop(0)
- request.prepath.append(pathElement)
- resource = resource.getChildWithDefault(pathElement, request)
- return resource
-
-
-
-class Resource:
- """
- I define a web-accessible resource.
-
- I serve 2 main purposes; one is to provide a standard representation for
- what HTTP specification calls an 'entity', and the other is to provide an
- abstract directory structure for URL retrieval.
- """
-
- implements(IResource)
-
- entityType = IResource
-
- server = None
-
- def __init__(self):
- """Initialize.
- """
- self.children = {}
-
- isLeaf = 0
-
- ### Abstract Collection Interface
-
- def listStaticNames(self):
- return self.children.keys()
-
- def listStaticEntities(self):
- return self.children.items()
-
- def listNames(self):
- return self.listStaticNames() + self.listDynamicNames()
-
- def listEntities(self):
- return self.listStaticEntities() + self.listDynamicEntities()
-
- def listDynamicNames(self):
- return []
-
- def listDynamicEntities(self, request=None):
- return []
-
- def getStaticEntity(self, name):
- return self.children.get(name)
-
- def getDynamicEntity(self, name, request):
- if not self.children.has_key(name):
- return self.getChild(name, request)
- else:
- return None
-
- def delEntity(self, name):
- del self.children[name]
-
- def reallyPutEntity(self, name, entity):
- self.children[name] = entity
-
- # Concrete HTTP interface
-
- def getChild(self, path, request):
- """
- Retrieve a 'child' resource from me.
-
- Implement this to create dynamic resource generation -- resources which
- are always available may be registered with self.putChild().
-
- This will not be called if the class-level variable 'isLeaf' is set in
- your subclass; instead, the 'postpath' attribute of the request will be
- left as a list of the remaining path elements.
-
- For example, the URL /foo/bar/baz will normally be::
-
- | site.resource.getChild('foo').getChild('bar').getChild('baz').
-
- However, if the resource returned by 'bar' has isLeaf set to true, then
- the getChild call will never be made on it.
-
- @param path: a string, describing the child
-
- @param request: a twisted.web.server.Request specifying meta-information
- about the request that is being made for this child.
- """
- return NoResource("No such child resource.")
-
-
- def getChildWithDefault(self, path, request):
- """
- Retrieve a static or dynamically generated child resource from me.
-
- First checks if a resource was added manually by putChild, and then
- call getChild to check for dynamic resources. Only override if you want
- to affect behaviour of all child lookups, rather than just dynamic
- ones.
-
- This will check to see if I have a pre-registered child resource of the
- given name, and call getChild if I do not.
- """
- if path in self.children:
- return self.children[path]
- return self.getChild(path, request)
-
-
- def getChildForRequest(self, request):
- warnings.warn("Please use module level getChildForRequest.", DeprecationWarning, 2)
- return getChildForRequest(self, request)
-
-
- def putChild(self, path, child):
- """
- Register a static child.
-
- You almost certainly don't want '/' in your path. If you
- intended to have the root of a folder, e.g. /foo/, you want
- path to be ''.
- """
- self.children[path] = child
- child.server = self.server
-
-
- def render(self, request):
- """
- Render a given resource. See L{IResource}'s render method.
-
- I delegate to methods of self with the form 'render_METHOD'
- where METHOD is the HTTP that was used to make the
- request. Examples: render_GET, render_HEAD, render_POST, and
- so on. Generally you should implement those methods instead of
- overriding this one.
-
- render_METHOD methods are expected to return a string which
- will be the rendered page, unless the return value is
- twisted.web.server.NOT_DONE_YET, in which case it is this
- class's responsibility to write the results to
- request.write(data), then call request.finish().
-
- Old code that overrides render() directly is likewise expected
- to return a string or NOT_DONE_YET.
- """
- m = getattr(self, 'render_' + request.method, None)
- if not m:
- # This needs to be here until the deprecated subclasses of the
- # below three error resources in twisted.web.error are removed.
- from twisted.web.error import UnsupportedMethod
- allowedMethods = (getattr(self, 'allowedMethods', 0) or
- _computeAllowedMethods(self))
- raise UnsupportedMethod(allowedMethods)
- return m(request)
-
-
- def render_HEAD(self, request):
- """
- Default handling of HEAD method.
-
- I just return self.render_GET(request). When method is HEAD,
- the framework will handle this correctly.
- """
- return self.render_GET(request)
-
-
-
-def _computeAllowedMethods(resource):
- """
- Compute the allowed methods on a C{Resource} based on defined render_FOO
- methods. Used when raising C{UnsupportedMethod} but C{Resource} does
- not define C{allowedMethods} attribute.
- """
- allowedMethods = []
- for name in prefixedMethodNames(resource.__class__, "render_"):
- allowedMethods.append(name)
- return allowedMethods
-
-
-
-class ErrorPage(Resource):
- """
- L{ErrorPage} is a resource which responds with a particular
- (parameterized) status and a body consisting of HTML containing some
- descriptive text. This is useful for rendering simple error pages.
-
- @ivar template: A C{str} which will have a dictionary interpolated into
- it to generate the response body. The dictionary has the following
- keys:
-
- - C{"code"}: The status code passed to L{ErrorPage.__init__}.
- - C{"brief"}: The brief description passed to L{ErrorPage.__init__}.
- - C{"detail"}: The detailed description passed to
- L{ErrorPage.__init__}.
-
- @ivar code: An integer status code which will be used for the response.
- @ivar brief: A short string which will be included in the response body.
- @ivar detail: A longer string which will be included in the response body.
- """
-
- template = """
-<html>
- <head><title>%(code)s - %(brief)s</title></head>
- <body>
- <h1>%(brief)s</h1>
- <p>%(detail)s</p>
- </body>
-</html>
-"""
-
- def __init__(self, status, brief, detail):
- Resource.__init__(self)
- self.code = status
- self.brief = brief
- self.detail = detail
-
-
- def render(self, request):
- request.setResponseCode(self.code)
- request.setHeader("content-type", "text/html; charset=utf-8")
- return self.template % dict(
- code=self.code,
- brief=self.brief,
- detail=self.detail)
-
-
- def getChild(self, chnam, request):
- return self
-
-
-
-class NoResource(ErrorPage):
- """
- L{NoResource} is a specialization of L{ErrorPage} which returns the HTTP
- response code I{NOT FOUND}.
- """
- def __init__(self, message="Sorry. No luck finding that resource."):
- ErrorPage.__init__(self, http.NOT_FOUND,
- "No Such Resource",
- message)
-
-
-
-class ForbiddenResource(ErrorPage):
- """
- L{ForbiddenResource} is a specialization of L{ErrorPage} which returns the
- I{FORBIDDEN} HTTP response code.
- """
- def __init__(self, message="Sorry, resource is forbidden."):
- ErrorPage.__init__(self, http.FORBIDDEN,
- "Forbidden Resource",
- message)
-
-
-__all__ = [
- 'IResource', 'getChildForRequest',
- 'Resource', 'ErrorPage', 'NoResource', 'ForbiddenResource']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/rewrite.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/rewrite.py
deleted file mode 100755
index b5366b4e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/rewrite.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-from twisted.web import resource
-
-class RewriterResource(resource.Resource):
-
- def __init__(self, orig, *rewriteRules):
- resource.Resource.__init__(self)
- self.resource = orig
- self.rewriteRules = list(rewriteRules)
-
- def _rewrite(self, request):
- for rewriteRule in self.rewriteRules:
- rewriteRule(request)
-
- def getChild(self, path, request):
- request.postpath.insert(0, path)
- request.prepath.pop()
- self._rewrite(request)
- path = request.postpath.pop(0)
- request.prepath.append(path)
- return self.resource.getChildWithDefault(path, request)
-
- def render(self, request):
- self._rewrite(request)
- return self.resource.render(request)
-
-
-def tildeToUsers(request):
- if request.postpath and request.postpath[0][:1]=='~':
- request.postpath[:1] = ['users', request.postpath[0][1:]]
- request.path = '/'+'/'.join(request.prepath+request.postpath)
-
-def alias(aliasPath, sourcePath):
- """
- I am not a very good aliaser. But I'm the best I can be. If I'm
- aliasing to a Resource that generates links, and it uses any parts
- of request.prepath to do so, the links will not be relative to the
- aliased path, but rather to the aliased-to path. That I can't
- alias static.File directory listings that nicely. However, I can
- still be useful, as many resources will play nice.
- """
- sourcePath = sourcePath.split('/')
- aliasPath = aliasPath.split('/')
- def rewriter(request):
- if request.postpath[:len(aliasPath)] == aliasPath:
- after = request.postpath[len(aliasPath):]
- request.postpath = sourcePath + after
- request.path = '/'+'/'.join(request.prepath+request.postpath)
- return rewriter
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/script.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/script.py
deleted file mode 100755
index 1b50105c..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/script.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_script -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-I contain PythonScript, which is a very simple python script resource.
-"""
-
-import os, traceback
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-from twisted import copyright
-from twisted.python.compat import execfile
-from twisted.web import http, server, static, resource, html
-
-
-rpyNoResource = """<p>You forgot to assign to the variable "resource" in your script. For example:</p>
-<pre>
-# MyCoolWebApp.rpy
-
-import mygreatresource
-
-resource = mygreatresource.MyGreatResource()
-</pre>
-"""
-
-class AlreadyCached(Exception):
- """This exception is raised when a path has already been cached.
- """
-
-class CacheScanner:
- def __init__(self, path, registry):
- self.path = path
- self.registry = registry
- self.doCache = 0
-
- def cache(self):
- c = self.registry.getCachedPath(self.path)
- if c is not None:
- raise AlreadyCached(c)
- self.recache()
-
- def recache(self):
- self.doCache = 1
-
-noRsrc = resource.ErrorPage(500, "Whoops! Internal Error", rpyNoResource)
-
-def ResourceScript(path, registry):
- """
- I am a normal py file which must define a 'resource' global, which should
- be an instance of (a subclass of) web.resource.Resource; it will be
- renderred.
- """
- cs = CacheScanner(path, registry)
- glob = {'__file__': path,
- 'resource': noRsrc,
- 'registry': registry,
- 'cache': cs.cache,
- 'recache': cs.recache}
- try:
- execfile(path, glob, glob)
- except AlreadyCached, ac:
- return ac.args[0]
- rsrc = glob['resource']
- if cs.doCache and rsrc is not noRsrc:
- registry.cachePath(path, rsrc)
- return rsrc
-
-def ResourceTemplate(path, registry):
- from quixote import ptl_compile
-
- glob = {'__file__': path,
- 'resource': resource.ErrorPage(500, "Whoops! Internal Error",
- rpyNoResource),
- 'registry': registry}
-
- e = ptl_compile.compile_template(open(path), path)
- exec e in glob
- return glob['resource']
-
-
-class ResourceScriptWrapper(resource.Resource):
-
- def __init__(self, path, registry=None):
- resource.Resource.__init__(self)
- self.path = path
- self.registry = registry or static.Registry()
-
- def render(self, request):
- res = ResourceScript(self.path, self.registry)
- return res.render(request)
-
- def getChildWithDefault(self, path, request):
- res = ResourceScript(self.path, self.registry)
- return res.getChildWithDefault(path, request)
-
-
-
-class ResourceScriptDirectory(resource.Resource):
- """
- L{ResourceScriptDirectory} is a resource which serves scripts from a
- filesystem directory. File children of a L{ResourceScriptDirectory} will
- be served using L{ResourceScript}. Directory children will be served using
- another L{ResourceScriptDirectory}.
-
- @ivar path: A C{str} giving the filesystem path in which children will be
- looked up.
-
- @ivar registry: A L{static.Registry} instance which will be used to decide
- how to interpret scripts found as children of this resource.
- """
- def __init__(self, pathname, registry=None):
- resource.Resource.__init__(self)
- self.path = pathname
- self.registry = registry or static.Registry()
-
- def getChild(self, path, request):
- fn = os.path.join(self.path, path)
-
- if os.path.isdir(fn):
- return ResourceScriptDirectory(fn, self.registry)
- if os.path.exists(fn):
- return ResourceScript(fn, self.registry)
- return resource.NoResource()
-
- def render(self, request):
- return resource.NoResource().render(request)
-
-
-class PythonScript(resource.Resource):
- """I am an extremely simple dynamic resource; an embedded python script.
-
- This will execute a file (usually of the extension '.epy') as Python code,
- internal to the webserver.
- """
- isLeaf = 1
- def __init__(self, filename, registry):
- """Initialize me with a script name.
- """
- self.filename = filename
- self.registry = registry
-
- def render(self, request):
- """Render me to a web client.
-
- Load my file, execute it in a special namespace (with 'request' and
- '__file__' global vars) and finish the request. Output to the web-page
- will NOT be handled with print - standard output goes to the log - but
- with request.write.
- """
- request.setHeader("x-powered-by","Twisted/%s" % copyright.version)
- namespace = {'request': request,
- '__file__': self.filename,
- 'registry': self.registry}
- try:
- execfile(self.filename, namespace, namespace)
- except IOError, e:
- if e.errno == 2: #file not found
- request.setResponseCode(http.NOT_FOUND)
- request.write(resource.NoResource("File not found.").render(request))
- except:
- io = StringIO.StringIO()
- traceback.print_exc(file=io)
- request.write(html.PRE(io.getvalue()))
- request.finish()
- return server.NOT_DONE_YET
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/server.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/server.py
deleted file mode 100755
index d03bec66..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/server.py
+++ /dev/null
@@ -1,592 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_web -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-This is a web-server which integrates with the twisted.internet
-infrastructure.
-"""
-
-# System Imports
-
-import warnings
-import string
-import types
-import copy
-import os
-from urllib import quote
-
-from zope.interface import implements
-
-from urllib import unquote
-
-#some useful constants
-NOT_DONE_YET = 1
-
-# Twisted Imports
-from twisted.spread import pb
-from twisted.internet import address, task
-from twisted.web import iweb, http
-from twisted.python import log, reflect, failure, components
-from twisted import copyright
-from twisted.web import util as webutil, resource
-from twisted.web.error import UnsupportedMethod
-from twisted.web.microdom import escape
-
-from twisted.python.versions import Version
-from twisted.python.deprecate import deprecatedModuleAttribute
-
-
-__all__ = [
- 'supportedMethods',
- 'Request',
- 'Session',
- 'Site',
- 'version',
- 'NOT_DONE_YET'
-]
-
-
-# backwards compatability
-deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "Please use twisted.web.http.datetimeToString instead",
- "twisted.web.server",
- "date_time_string")
-deprecatedModuleAttribute(
- Version("Twisted", 12, 1, 0),
- "Please use twisted.web.http.stringToDatetime instead",
- "twisted.web.server",
- "string_date_time")
-date_time_string = http.datetimeToString
-string_date_time = http.stringToDatetime
-
-# Support for other methods may be implemented on a per-resource basis.
-supportedMethods = ('GET', 'HEAD', 'POST')
-
-
-def _addressToTuple(addr):
- if isinstance(addr, address.IPv4Address):
- return ('INET', addr.host, addr.port)
- elif isinstance(addr, address.UNIXAddress):
- return ('UNIX', addr.name)
- else:
- return tuple(addr)
-
-class Request(pb.Copyable, http.Request, components.Componentized):
- """
- An HTTP request.
-
- @ivar defaultContentType: A C{str} giving the default I{Content-Type} value
- to send in responses if no other value is set. C{None} disables the
- default.
- """
- implements(iweb.IRequest)
-
- defaultContentType = "text/html"
-
- site = None
- appRootURL = None
- __pychecker__ = 'unusednames=issuer'
- _inFakeHead = False
-
- def __init__(self, *args, **kw):
- http.Request.__init__(self, *args, **kw)
- components.Componentized.__init__(self)
-
- def getStateToCopyFor(self, issuer):
- x = self.__dict__.copy()
- del x['transport']
- # XXX refactor this attribute out; it's from protocol
- # del x['server']
- del x['channel']
- del x['content']
- del x['site']
- self.content.seek(0, 0)
- x['content_data'] = self.content.read()
- x['remote'] = pb.ViewPoint(issuer, self)
-
- # Address objects aren't jellyable
- x['host'] = _addressToTuple(x['host'])
- x['client'] = _addressToTuple(x['client'])
-
- # Header objects also aren't jellyable.
- x['requestHeaders'] = list(x['requestHeaders'].getAllRawHeaders())
-
- return x
-
- # HTML generation helpers
-
- def sibLink(self, name):
- "Return the text that links to a sibling of the requested resource."
- if self.postpath:
- return (len(self.postpath)*"../") + name
- else:
- return name
-
- def childLink(self, name):
- "Return the text that links to a child of the requested resource."
- lpp = len(self.postpath)
- if lpp > 1:
- return ((lpp-1)*"../") + name
- elif lpp == 1:
- return name
- else: # lpp == 0
- if len(self.prepath) and self.prepath[-1]:
- return self.prepath[-1] + '/' + name
- else:
- return name
-
- def process(self):
- "Process a request."
-
- # get site from channel
- self.site = self.channel.site
-
- # set various default headers
- self.setHeader('server', version)
- self.setHeader('date', http.datetimeToString())
-
- # Resource Identification
- self.prepath = []
- self.postpath = map(unquote, string.split(self.path[1:], '/'))
- try:
- resrc = self.site.getResourceFor(self)
- self.render(resrc)
- except:
- self.processingFailed(failure.Failure())
-
- def write(self, data):
- """
- Write data to the transport (if not responding to a HEAD request).
-
- @param data: A string to write to the response.
- """
- if not self.startedWriting:
- # Before doing the first write, check to see if a default
- # Content-Type header should be supplied.
- modified = self.code != http.NOT_MODIFIED
- contentType = self.responseHeaders.getRawHeaders('content-type')
- if modified and contentType is None and self.defaultContentType is not None:
- self.responseHeaders.setRawHeaders(
- 'content-type', [self.defaultContentType])
-
- # Only let the write happen if we're not generating a HEAD response by
- # faking out the request method. Note, if we are doing that,
- # startedWriting will never be true, and the above logic may run
- # multiple times. It will only actually change the responseHeaders once
- # though, so it's still okay.
- if not self._inFakeHead:
- http.Request.write(self, data)
-
-
- def render(self, resrc):
- """
- Ask a resource to render itself.
-
- @param resrc: a L{twisted.web.resource.IResource}.
- """
- try:
- body = resrc.render(self)
- except UnsupportedMethod, e:
- allowedMethods = e.allowedMethods
- if (self.method == "HEAD") and ("GET" in allowedMethods):
- # We must support HEAD (RFC 2616, 5.1.1). If the
- # resource doesn't, fake it by giving the resource
- # a 'GET' request and then return only the headers,
- # not the body.
- log.msg("Using GET to fake a HEAD request for %s" %
- (resrc,))
- self.method = "GET"
- self._inFakeHead = True
- body = resrc.render(self)
-
- if body is NOT_DONE_YET:
- log.msg("Tried to fake a HEAD request for %s, but "
- "it got away from me." % resrc)
- # Oh well, I guess we won't include the content length.
- else:
- self.setHeader('content-length', str(len(body)))
-
- self._inFakeHead = False
- self.method = "HEAD"
- self.write('')
- self.finish()
- return
-
- if self.method in (supportedMethods):
- # We MUST include an Allow header
- # (RFC 2616, 10.4.6 and 14.7)
- self.setHeader('Allow', ', '.join(allowedMethods))
- s = ('''Your browser approached me (at %(URI)s) with'''
- ''' the method "%(method)s". I only allow'''
- ''' the method%(plural)s %(allowed)s here.''' % {
- 'URI': escape(self.uri),
- 'method': self.method,
- 'plural': ((len(allowedMethods) > 1) and 's') or '',
- 'allowed': string.join(allowedMethods, ', ')
- })
- epage = resource.ErrorPage(http.NOT_ALLOWED,
- "Method Not Allowed", s)
- body = epage.render(self)
- else:
- epage = resource.ErrorPage(
- http.NOT_IMPLEMENTED, "Huh?",
- "I don't know how to treat a %s request." %
- (escape(self.method),))
- body = epage.render(self)
- # end except UnsupportedMethod
-
- if body == NOT_DONE_YET:
- return
- if type(body) is not types.StringType:
- body = resource.ErrorPage(
- http.INTERNAL_SERVER_ERROR,
- "Request did not return a string",
- "Request: " + html.PRE(reflect.safe_repr(self)) + "<br />" +
- "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "<br />" +
- "Value: " + html.PRE(reflect.safe_repr(body))).render(self)
-
- if self.method == "HEAD":
- if len(body) > 0:
- # This is a Bad Thing (RFC 2616, 9.4)
- log.msg("Warning: HEAD request %s for resource %s is"
- " returning a message body."
- " I think I'll eat it."
- % (self, resrc))
- self.setHeader('content-length', str(len(body)))
- self.write('')
- else:
- self.setHeader('content-length', str(len(body)))
- self.write(body)
- self.finish()
-
- def processingFailed(self, reason):
- log.err(reason)
- if self.site.displayTracebacks:
- body = ("<html><head><title>web.Server Traceback (most recent call last)</title></head>"
- "<body><b>web.Server Traceback (most recent call last):</b>\n\n"
- "%s\n\n</body></html>\n"
- % webutil.formatFailure(reason))
- else:
- body = ("<html><head><title>Processing Failed</title></head><body>"
- "<b>Processing Failed</b></body></html>")
-
- self.setResponseCode(http.INTERNAL_SERVER_ERROR)
- self.setHeader('content-type',"text/html")
- self.setHeader('content-length', str(len(body)))
- self.write(body)
- self.finish()
- return reason
-
- def view_write(self, issuer, data):
- """Remote version of write; same interface.
- """
- self.write(data)
-
- def view_finish(self, issuer):
- """Remote version of finish; same interface.
- """
- self.finish()
-
- def view_addCookie(self, issuer, k, v, **kwargs):
- """Remote version of addCookie; same interface.
- """
- self.addCookie(k, v, **kwargs)
-
- def view_setHeader(self, issuer, k, v):
- """Remote version of setHeader; same interface.
- """
- self.setHeader(k, v)
-
- def view_setLastModified(self, issuer, when):
- """Remote version of setLastModified; same interface.
- """
- self.setLastModified(when)
-
- def view_setETag(self, issuer, tag):
- """Remote version of setETag; same interface.
- """
- self.setETag(tag)
-
-
- def view_setResponseCode(self, issuer, code, message=None):
- """
- Remote version of setResponseCode; same interface.
- """
- self.setResponseCode(code, message)
-
-
- def view_registerProducer(self, issuer, producer, streaming):
- """Remote version of registerProducer; same interface.
- (requires a remote producer.)
- """
- self.registerProducer(_RemoteProducerWrapper(producer), streaming)
-
- def view_unregisterProducer(self, issuer):
- self.unregisterProducer()
-
- ### these calls remain local
-
- session = None
-
- def getSession(self, sessionInterface = None):
- # Session management
- if not self.session:
- cookiename = string.join(['TWISTED_SESSION'] + self.sitepath, "_")
- sessionCookie = self.getCookie(cookiename)
- if sessionCookie:
- try:
- self.session = self.site.getSession(sessionCookie)
- except KeyError:
- pass
- # if it still hasn't been set, fix it up.
- if not self.session:
- self.session = self.site.makeSession()
- self.addCookie(cookiename, self.session.uid, path='/')
- self.session.touch()
- if sessionInterface:
- return self.session.getComponent(sessionInterface)
- return self.session
-
- def _prePathURL(self, prepath):
- port = self.getHost().port
- if self.isSecure():
- default = 443
- else:
- default = 80
- if port == default:
- hostport = ''
- else:
- hostport = ':%d' % port
- return 'http%s://%s%s/%s' % (
- self.isSecure() and 's' or '',
- self.getRequestHostname(),
- hostport,
- '/'.join([quote(segment, safe='') for segment in prepath]))
-
- def prePathURL(self):
- return self._prePathURL(self.prepath)
-
- def URLPath(self):
- from twisted.python import urlpath
- return urlpath.URLPath.fromRequest(self)
-
- def rememberRootURL(self):
- """
- Remember the currently-processed part of the URL for later
- recalling.
- """
- url = self._prePathURL(self.prepath[:-1])
- self.appRootURL = url
-
- def getRootURL(self):
- """
- Get a previously-remembered URL.
- """
- return self.appRootURL
-
-
-class _RemoteProducerWrapper:
- def __init__(self, remote):
- self.resumeProducing = remote.remoteMethod("resumeProducing")
- self.pauseProducing = remote.remoteMethod("pauseProducing")
- self.stopProducing = remote.remoteMethod("stopProducing")
-
-
-class Session(components.Componentized):
- """
- A user's session with a system.
-
- This utility class contains no functionality, but is used to
- represent a session.
-
- @ivar _reactor: An object providing L{IReactorTime} to use for scheduling
- expiration.
- @ivar sessionTimeout: timeout of a session, in seconds.
- @ivar loopFactory: Deprecated in Twisted 9.0. Does nothing. Do not use.
- """
- sessionTimeout = 900
- loopFactory = task.LoopingCall
-
- _expireCall = None
-
- def __init__(self, site, uid, reactor=None):
- """
- Initialize a session with a unique ID for that session.
- """
- components.Componentized.__init__(self)
-
- if reactor is None:
- from twisted.internet import reactor
- self._reactor = reactor
-
- self.site = site
- self.uid = uid
- self.expireCallbacks = []
- self.touch()
- self.sessionNamespaces = {}
-
-
- def startCheckingExpiration(self, lifetime=None):
- """
- Start expiration tracking.
-
- @param lifetime: Ignored; deprecated.
-
- @return: C{None}
- """
- if lifetime is not None:
- warnings.warn(
- "The lifetime parameter to startCheckingExpiration is "
- "deprecated since Twisted 9.0. See Session.sessionTimeout "
- "instead.", DeprecationWarning, stacklevel=2)
- self._expireCall = self._reactor.callLater(
- self.sessionTimeout, self.expire)
-
-
- def notifyOnExpire(self, callback):
- """
- Call this callback when the session expires or logs out.
- """
- self.expireCallbacks.append(callback)
-
-
- def expire(self):
- """
- Expire/logout of the session.
- """
- del self.site.sessions[self.uid]
- for c in self.expireCallbacks:
- c()
- self.expireCallbacks = []
- if self._expireCall and self._expireCall.active():
- self._expireCall.cancel()
- # Break reference cycle.
- self._expireCall = None
-
-
- def touch(self):
- """
- Notify session modification.
- """
- self.lastModified = self._reactor.seconds()
- if self._expireCall is not None:
- self._expireCall.reset(self.sessionTimeout)
-
-
- def checkExpired(self):
- """
- Deprecated; does nothing.
- """
- warnings.warn(
- "Session.checkExpired is deprecated since Twisted 9.0; sessions "
- "check themselves now, you don't need to.",
- stacklevel=2, category=DeprecationWarning)
-
-
-version = "TwistedWeb/%s" % copyright.version
-
-
-class Site(http.HTTPFactory):
- """
- A web site: manage log, sessions, and resources.
-
- @ivar counter: increment value used for generating unique sessions ID.
- @ivar requestFactory: factory creating requests objects. Default to
- L{Request}.
- @ivar displayTracebacks: if set, Twisted internal errors are displayed on
- rendered pages. Default to C{True}.
- @ivar sessionFactory: factory for sessions objects. Default to L{Session}.
- @ivar sessionCheckTime: Deprecated. See L{Session.sessionTimeout} instead.
- """
- counter = 0
- requestFactory = Request
- displayTracebacks = True
- sessionFactory = Session
- sessionCheckTime = 1800
-
- def __init__(self, resource, logPath=None, timeout=60*60*12):
- """
- Initialize.
- """
- http.HTTPFactory.__init__(self, logPath=logPath, timeout=timeout)
- self.sessions = {}
- self.resource = resource
-
- def _openLogFile(self, path):
- from twisted.python import logfile
- return logfile.LogFile(os.path.basename(path), os.path.dirname(path))
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['sessions'] = {}
- return d
-
- def _mkuid(self):
- """
- (internal) Generate an opaque, unique ID for a user's session.
- """
- from twisted.python.hashlib import md5
- import random
- self.counter = self.counter + 1
- return md5("%s_%s" % (str(random.random()) , str(self.counter))).hexdigest()
-
- def makeSession(self):
- """
- Generate a new Session instance, and store it for future reference.
- """
- uid = self._mkuid()
- session = self.sessions[uid] = self.sessionFactory(self, uid)
- session.startCheckingExpiration()
- return session
-
- def getSession(self, uid):
- """
- Get a previously generated session, by its unique ID.
- This raises a KeyError if the session is not found.
- """
- return self.sessions[uid]
-
- def buildProtocol(self, addr):
- """
- Generate a channel attached to this site.
- """
- channel = http.HTTPFactory.buildProtocol(self, addr)
- channel.requestFactory = self.requestFactory
- channel.site = self
- return channel
-
- isLeaf = 0
-
- def render(self, request):
- """
- Redirect because a Site is always a directory.
- """
- request.redirect(request.prePathURL() + '/')
- request.finish()
-
- def getChildWithDefault(self, pathEl, request):
- """
- Emulate a resource's getChild method.
- """
- request.site = self
- return self.resource.getChildWithDefault(pathEl, request)
-
- def getResourceFor(self, request):
- """
- Get a resource for a request.
-
- This iterates through the resource heirarchy, calling
- getChildWithDefault on each resource it finds for a path element,
- stopping when it hits an element where isLeaf is true.
- """
- request.site = self
- # Sitepath is used to determine cookie names between distributed
- # servers and disconnected sites.
- request.sitepath = copy.copy(request.prepath)
- return resource.getChildForRequest(self.resource, request)
-
-
-import html
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/soap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/soap.py
deleted file mode 100755
index 1ca747b2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/soap.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_soap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-SOAP support for twisted.web.
-
-Requires SOAPpy 0.10.1 or later.
-
-Maintainer: Itamar Shtull-Trauring
-
-Future plans:
-SOAPContext support of some kind.
-Pluggable method lookup policies.
-"""
-
-# SOAPpy
-import SOAPpy
-
-# twisted imports
-from twisted.web import server, resource, client
-from twisted.internet import defer
-
-
-class SOAPPublisher(resource.Resource):
- """Publish SOAP methods.
-
- By default, publish methods beginning with 'soap_'. If the method
- has an attribute 'useKeywords', it well get the arguments passed
- as keyword args.
- """
-
- isLeaf = 1
-
- # override to change the encoding used for responses
- encoding = "UTF-8"
-
- def lookupFunction(self, functionName):
- """Lookup published SOAP function.
-
- Override in subclasses. Default behaviour - publish methods
- starting with soap_.
-
- @return: callable or None if not found.
- """
- return getattr(self, "soap_%s" % functionName, None)
-
- def render(self, request):
- """Handle a SOAP command."""
- data = request.content.read()
-
- p, header, body, attrs = SOAPpy.parseSOAPRPC(data, 1, 1, 1)
-
- methodName, args, kwargs, ns = p._name, p._aslist, p._asdict, p._ns
-
- # deal with changes in SOAPpy 0.11
- if callable(args):
- args = args()
- if callable(kwargs):
- kwargs = kwargs()
-
- function = self.lookupFunction(methodName)
-
- if not function:
- self._methodNotFound(request, methodName)
- return server.NOT_DONE_YET
- else:
- if hasattr(function, "useKeywords"):
- keywords = {}
- for k, v in kwargs.items():
- keywords[str(k)] = v
- d = defer.maybeDeferred(function, **keywords)
- else:
- d = defer.maybeDeferred(function, *args)
-
- d.addCallback(self._gotResult, request, methodName)
- d.addErrback(self._gotError, request, methodName)
- return server.NOT_DONE_YET
-
- def _methodNotFound(self, request, methodName):
- response = SOAPpy.buildSOAP(SOAPpy.faultType("%s:Client" %
- SOAPpy.NS.ENV_T, "Method %s not found" % methodName),
- encoding=self.encoding)
- self._sendResponse(request, response, status=500)
-
- def _gotResult(self, result, request, methodName):
- if not isinstance(result, SOAPpy.voidType):
- result = {"Result": result}
- response = SOAPpy.buildSOAP(kw={'%sResponse' % methodName: result},
- encoding=self.encoding)
- self._sendResponse(request, response)
-
- def _gotError(self, failure, request, methodName):
- e = failure.value
- if isinstance(e, SOAPpy.faultType):
- fault = e
- else:
- fault = SOAPpy.faultType("%s:Server" % SOAPpy.NS.ENV_T,
- "Method %s failed." % methodName)
- response = SOAPpy.buildSOAP(fault, encoding=self.encoding)
- self._sendResponse(request, response, status=500)
-
- def _sendResponse(self, request, response, status=200):
- request.setResponseCode(status)
-
- if self.encoding is not None:
- mimeType = 'text/xml; charset="%s"' % self.encoding
- else:
- mimeType = "text/xml"
- request.setHeader("Content-type", mimeType)
- request.setHeader("Content-length", str(len(response)))
- request.write(response)
- request.finish()
-
-
-class Proxy:
- """A Proxy for making remote SOAP calls.
-
- Pass the URL of the remote SOAP server to the constructor.
-
- Use proxy.callRemote('foobar', 1, 2) to call remote method
- 'foobar' with args 1 and 2, proxy.callRemote('foobar', x=1)
- will call foobar with named argument 'x'.
- """
-
- # at some point this should have encoding etc. kwargs
- def __init__(self, url, namespace=None, header=None):
- self.url = url
- self.namespace = namespace
- self.header = header
-
- def _cbGotResult(self, result):
- result = SOAPpy.parseSOAPRPC(result)
- if hasattr(result, 'Result'):
- return result.Result
- elif len(result) == 1:
- ## SOAPpy 0.11.6 wraps the return results in a containing structure.
- ## This check added to make Proxy behaviour emulate SOAPProxy, which
- ## flattens the structure by default.
- ## This behaviour is OK because even singleton lists are wrapped in
- ## another singleton structType, which is almost always useless.
- return result[0]
- else:
- return result
-
- def callRemote(self, method, *args, **kwargs):
- payload = SOAPpy.buildSOAP(args=args, kw=kwargs, method=method,
- header=self.header, namespace=self.namespace)
- return client.getPage(self.url, postdata=payload, method="POST",
- headers={'content-type': 'text/xml',
- 'SOAPAction': method}
- ).addCallback(self._cbGotResult)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/static.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/static.py
deleted file mode 100755
index 05fd7d98..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/static.py
+++ /dev/null
@@ -1,1033 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_static -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Static resources for L{twisted.web}.
-"""
-from __future__ import division
-
-import os
-import warnings
-import urllib
-import itertools
-import cgi
-import time
-
-from zope.interface import implements
-
-from twisted.web import server
-from twisted.web import resource
-from twisted.web import http
-from twisted.web.util import redirectTo
-
-from twisted.python import components, filepath, log
-from twisted.internet import abstract, interfaces
-from twisted.persisted import styles
-from twisted.python.util import InsensitiveDict
-from twisted.python.runtime import platformType
-
-
-dangerousPathError = resource.NoResource("Invalid request URL.")
-
-def isDangerous(path):
- return path == '..' or '/' in path or os.sep in path
-
-
-class Data(resource.Resource):
- """
- This is a static, in-memory resource.
- """
-
- def __init__(self, data, type):
- resource.Resource.__init__(self)
- self.data = data
- self.type = type
-
-
- def render_GET(self, request):
- request.setHeader("content-type", self.type)
- request.setHeader("content-length", str(len(self.data)))
- if request.method == "HEAD":
- return ''
- return self.data
- render_HEAD = render_GET
-
-
-def addSlash(request):
- qs = ''
- qindex = request.uri.find('?')
- if qindex != -1:
- qs = request.uri[qindex:]
-
- return "http%s://%s%s/%s" % (
- request.isSecure() and 's' or '',
- request.getHeader("host"),
- (request.uri.split('?')[0]),
- qs)
-
-class Redirect(resource.Resource):
- def __init__(self, request):
- resource.Resource.__init__(self)
- self.url = addSlash(request)
-
- def render(self, request):
- return redirectTo(self.url, request)
-
-
-class Registry(components.Componentized, styles.Versioned):
- """
- I am a Componentized object that will be made available to internal Twisted
- file-based dynamic web content such as .rpy and .epy scripts.
- """
-
- def __init__(self):
- components.Componentized.__init__(self)
- self._pathCache = {}
-
- persistenceVersion = 1
-
- def upgradeToVersion1(self):
- self._pathCache = {}
-
- def cachePath(self, path, rsrc):
- self._pathCache[path] = rsrc
-
- def getCachedPath(self, path):
- return self._pathCache.get(path)
-
-
-def loadMimeTypes(mimetype_locations=['/etc/mime.types']):
- """
- Multiple file locations containing mime-types can be passed as a list.
- The files will be sourced in that order, overriding mime-types from the
- files sourced beforehand, but only if a new entry explicitly overrides
- the current entry.
- """
- import mimetypes
- # Grab Python's built-in mimetypes dictionary.
- contentTypes = mimetypes.types_map
- # Update Python's semi-erroneous dictionary with a few of the
- # usual suspects.
- contentTypes.update(
- {
- '.conf': 'text/plain',
- '.diff': 'text/plain',
- '.exe': 'application/x-executable',
- '.flac': 'audio/x-flac',
- '.java': 'text/plain',
- '.ogg': 'application/ogg',
- '.oz': 'text/x-oz',
- '.swf': 'application/x-shockwave-flash',
- '.tgz': 'application/x-gtar',
- '.wml': 'text/vnd.wap.wml',
- '.xul': 'application/vnd.mozilla.xul+xml',
- '.py': 'text/plain',
- '.patch': 'text/plain',
- }
- )
- # Users can override these mime-types by loading them out configuration
- # files (this defaults to ['/etc/mime.types']).
- for location in mimetype_locations:
- if os.path.exists(location):
- more = mimetypes.read_mime_types(location)
- if more is not None:
- contentTypes.update(more)
-
- return contentTypes
-
-def getTypeAndEncoding(filename, types, encodings, defaultType):
- p, ext = os.path.splitext(filename)
- ext = ext.lower()
- if ext in encodings:
- enc = encodings[ext]
- ext = os.path.splitext(p)[1].lower()
- else:
- enc = None
- type = types.get(ext, defaultType)
- return type, enc
-
-
-
-class File(resource.Resource, styles.Versioned, filepath.FilePath):
- """
- File is a resource that represents a plain non-interpreted file
- (although it can look for an extension like .rpy or .cgi and hand the
- file to a processor for interpretation if you wish). Its constructor
- takes a file path.
-
- Alternatively, you can give a directory path to the constructor. In this
- case the resource will represent that directory, and its children will
- be files underneath that directory. This provides access to an entire
- filesystem tree with a single Resource.
-
- If you map the URL 'http://server/FILE' to a resource created as
- File('/tmp'), then http://server/FILE/ will return an HTML-formatted
- listing of the /tmp/ directory, and http://server/FILE/foo/bar.html will
- return the contents of /tmp/foo/bar.html .
-
- @cvar childNotFound: L{Resource} used to render 404 Not Found error pages.
- """
-
- contentTypes = loadMimeTypes()
-
- contentEncodings = {
- ".gz" : "gzip",
- ".bz2": "bzip2"
- }
-
- processors = {}
-
- indexNames = ["index", "index.html", "index.htm", "index.rpy"]
-
- type = None
-
- ### Versioning
-
- persistenceVersion = 6
-
- def upgradeToVersion6(self):
- self.ignoredExts = []
- if self.allowExt:
- self.ignoreExt("*")
- del self.allowExt
-
-
- def upgradeToVersion5(self):
- if not isinstance(self.registry, Registry):
- self.registry = Registry()
-
-
- def upgradeToVersion4(self):
- if not hasattr(self, 'registry'):
- self.registry = {}
-
-
- def upgradeToVersion3(self):
- if not hasattr(self, 'allowExt'):
- self.allowExt = 0
-
-
- def upgradeToVersion2(self):
- self.defaultType = "text/html"
-
-
- def upgradeToVersion1(self):
- if hasattr(self, 'indexName'):
- self.indexNames = [self.indexName]
- del self.indexName
-
-
- def __init__(self, path, defaultType="text/html", ignoredExts=(), registry=None, allowExt=0):
- """
- Create a file with the given path.
-
- @param path: The filename of the file from which this L{File} will
- serve data.
- @type path: C{str}
-
- @param defaultType: A I{major/minor}-style MIME type specifier
- indicating the I{Content-Type} with which this L{File}'s data
- will be served if a MIME type cannot be determined based on
- C{path}'s extension.
- @type defaultType: C{str}
-
- @param ignoredExts: A sequence giving the extensions of paths in the
- filesystem which will be ignored for the purposes of child
- lookup. For example, if C{ignoredExts} is C{(".bar",)} and
- C{path} is a directory containing a file named C{"foo.bar"}, a
- request for the C{"foo"} child of this resource will succeed
- with a L{File} pointing to C{"foo.bar"}.
-
- @param registry: The registry object being used to handle this
- request. If C{None}, one will be created.
- @type registry: L{Registry}
-
- @param allowExt: Ignored parameter, only present for backwards
- compatibility. Do not pass a value for this parameter.
- """
- resource.Resource.__init__(self)
- filepath.FilePath.__init__(self, path)
- self.defaultType = defaultType
- if ignoredExts in (0, 1) or allowExt:
- warnings.warn("ignoredExts should receive a list, not a boolean")
- if ignoredExts or allowExt:
- self.ignoredExts = ['*']
- else:
- self.ignoredExts = []
- else:
- self.ignoredExts = list(ignoredExts)
- self.registry = registry or Registry()
-
-
- def ignoreExt(self, ext):
- """Ignore the given extension.
-
- Serve file.ext if file is requested
- """
- self.ignoredExts.append(ext)
-
- childNotFound = resource.NoResource("File not found.")
-
- def directoryListing(self):
- return DirectoryLister(self.path,
- self.listNames(),
- self.contentTypes,
- self.contentEncodings,
- self.defaultType)
-
-
- def getChild(self, path, request):
- """
- If this L{File}'s path refers to a directory, return a L{File}
- referring to the file named C{path} in that directory.
-
- If C{path} is the empty string, return a L{DirectoryLister} instead.
- """
- self.restat(reraise=False)
-
- if not self.isdir():
- return self.childNotFound
-
- if path:
- try:
- fpath = self.child(path)
- except filepath.InsecurePath:
- return self.childNotFound
- else:
- fpath = self.childSearchPreauth(*self.indexNames)
- if fpath is None:
- return self.directoryListing()
-
- if not fpath.exists():
- fpath = fpath.siblingExtensionSearch(*self.ignoredExts)
- if fpath is None:
- return self.childNotFound
-
- if platformType == "win32":
- # don't want .RPY to be different than .rpy, since that would allow
- # source disclosure.
- processor = InsensitiveDict(self.processors).get(fpath.splitext()[1])
- else:
- processor = self.processors.get(fpath.splitext()[1])
- if processor:
- return resource.IResource(processor(fpath.path, self.registry))
- return self.createSimilarFile(fpath.path)
-
-
- # methods to allow subclasses to e.g. decrypt files on the fly:
- def openForReading(self):
- """Open a file and return it."""
- return self.open()
-
-
- def getFileSize(self):
- """Return file size."""
- return self.getsize()
-
-
- def _parseRangeHeader(self, range):
- """
- Parse the value of a Range header into (start, stop) pairs.
-
- In a given pair, either of start or stop can be None, signifying that
- no value was provided, but not both.
-
- @return: A list C{[(start, stop)]} of pairs of length at least one.
-
- @raise ValueError: if the header is syntactically invalid or if the
- Bytes-Unit is anything other than 'bytes'.
- """
- try:
- kind, value = range.split('=', 1)
- except ValueError:
- raise ValueError("Missing '=' separator")
- kind = kind.strip()
- if kind != 'bytes':
- raise ValueError("Unsupported Bytes-Unit: %r" % (kind,))
- unparsedRanges = filter(None, map(str.strip, value.split(',')))
- parsedRanges = []
- for byteRange in unparsedRanges:
- try:
- start, end = byteRange.split('-', 1)
- except ValueError:
- raise ValueError("Invalid Byte-Range: %r" % (byteRange,))
- if start:
- try:
- start = int(start)
- except ValueError:
- raise ValueError("Invalid Byte-Range: %r" % (byteRange,))
- else:
- start = None
- if end:
- try:
- end = int(end)
- except ValueError:
- raise ValueError("Invalid Byte-Range: %r" % (byteRange,))
- else:
- end = None
- if start is not None:
- if end is not None and start > end:
- # Start must be less than or equal to end or it is invalid.
- raise ValueError("Invalid Byte-Range: %r" % (byteRange,))
- elif end is None:
- # One or both of start and end must be specified. Omitting
- # both is invalid.
- raise ValueError("Invalid Byte-Range: %r" % (byteRange,))
- parsedRanges.append((start, end))
- return parsedRanges
-
-
- def _rangeToOffsetAndSize(self, start, end):
- """
- Convert a start and end from a Range header to an offset and size.
-
- This method checks that the resulting range overlaps with the resource
- being served (and so has the value of C{getFileSize()} as an indirect
- input).
-
- Either but not both of start or end can be C{None}:
-
- - Omitted start means that the end value is actually a start value
- relative to the end of the resource.
-
- - Omitted end means the end of the resource should be the end of
- the range.
-
- End is interpreted as inclusive, as per RFC 2616.
-
- If this range doesn't overlap with any of this resource, C{(0, 0)} is
- returned, which is not otherwise a value return value.
-
- @param start: The start value from the header, or C{None} if one was
- not present.
- @param end: The end value from the header, or C{None} if one was not
- present.
- @return: C{(offset, size)} where offset is how far into this resource
- this resource the range begins and size is how long the range is,
- or C{(0, 0)} if the range does not overlap this resource.
- """
- size = self.getFileSize()
- if start is None:
- start = size - end
- end = size
- elif end is None:
- end = size
- elif end < size:
- end += 1
- elif end > size:
- end = size
- if start >= size:
- start = end = 0
- return start, (end - start)
-
-
- def _contentRange(self, offset, size):
- """
- Return a string suitable for the value of a Content-Range header for a
- range with the given offset and size.
-
- The offset and size are not sanity checked in any way.
-
- @param offset: How far into this resource the range begins.
- @param size: How long the range is.
- @return: The value as appropriate for the value of a Content-Range
- header.
- """
- return 'bytes %d-%d/%d' % (
- offset, offset + size - 1, self.getFileSize())
-
-
- def _doSingleRangeRequest(self, request, (start, end)):
- """
- Set up the response for Range headers that specify a single range.
-
- This method checks if the request is satisfiable and sets the response
- code and Content-Range header appropriately. The return value
- indicates which part of the resource to return.
-
- @param request: The Request object.
- @param start: The start of the byte range as specified by the header.
- @param end: The end of the byte range as specified by the header. At
- most one of C{start} and C{end} may be C{None}.
- @return: A 2-tuple of the offset and size of the range to return.
- offset == size == 0 indicates that the request is not satisfiable.
- """
- offset, size = self._rangeToOffsetAndSize(start, end)
- if offset == size == 0:
- # This range doesn't overlap with any of this resource, so the
- # request is unsatisfiable.
- request.setResponseCode(http.REQUESTED_RANGE_NOT_SATISFIABLE)
- request.setHeader(
- 'content-range', 'bytes */%d' % (self.getFileSize(),))
- else:
- request.setResponseCode(http.PARTIAL_CONTENT)
- request.setHeader(
- 'content-range', self._contentRange(offset, size))
- return offset, size
-
-
- def _doMultipleRangeRequest(self, request, byteRanges):
- """
- Set up the response for Range headers that specify a single range.
-
- This method checks if the request is satisfiable and sets the response
- code and Content-Type and Content-Length headers appropriately. The
- return value, which is a little complicated, indicates which parts of
- the resource to return and the boundaries that should separate the
- parts.
-
- In detail, the return value is a tuple rangeInfo C{rangeInfo} is a
- list of 3-tuples C{(partSeparator, partOffset, partSize)}. The
- response to this request should be, for each element of C{rangeInfo},
- C{partSeparator} followed by C{partSize} bytes of the resource
- starting at C{partOffset}. Each C{partSeparator} includes the
- MIME-style boundary and the part-specific Content-type and
- Content-range headers. It is convenient to return the separator as a
- concrete string from this method, becasue this method needs to compute
- the number of bytes that will make up the response to be able to set
- the Content-Length header of the response accurately.
-
- @param request: The Request object.
- @param byteRanges: A list of C{(start, end)} values as specified by
- the header. For each range, at most one of C{start} and C{end}
- may be C{None}.
- @return: See above.
- """
- matchingRangeFound = False
- rangeInfo = []
- contentLength = 0
- boundary = "%x%x" % (int(time.time()*1000000), os.getpid())
- if self.type:
- contentType = self.type
- else:
- contentType = 'bytes' # It's what Apache does...
- for start, end in byteRanges:
- partOffset, partSize = self._rangeToOffsetAndSize(start, end)
- if partOffset == partSize == 0:
- continue
- contentLength += partSize
- matchingRangeFound = True
- partContentRange = self._contentRange(partOffset, partSize)
- partSeparator = (
- "\r\n"
- "--%s\r\n"
- "Content-type: %s\r\n"
- "Content-range: %s\r\n"
- "\r\n") % (boundary, contentType, partContentRange)
- contentLength += len(partSeparator)
- rangeInfo.append((partSeparator, partOffset, partSize))
- if not matchingRangeFound:
- request.setResponseCode(http.REQUESTED_RANGE_NOT_SATISFIABLE)
- request.setHeader(
- 'content-length', '0')
- request.setHeader(
- 'content-range', 'bytes */%d' % (self.getFileSize(),))
- return [], ''
- finalBoundary = "\r\n--" + boundary + "--\r\n"
- rangeInfo.append((finalBoundary, 0, 0))
- request.setResponseCode(http.PARTIAL_CONTENT)
- request.setHeader(
- 'content-type', 'multipart/byteranges; boundary="%s"' % (boundary,))
- request.setHeader(
- 'content-length', contentLength + len(finalBoundary))
- return rangeInfo
-
-
- def _setContentHeaders(self, request, size=None):
- """
- Set the Content-length and Content-type headers for this request.
-
- This method is not appropriate for requests for multiple byte ranges;
- L{_doMultipleRangeRequest} will set these headers in that case.
-
- @param request: The L{Request} object.
- @param size: The size of the response. If not specified, default to
- C{self.getFileSize()}.
- """
- if size is None:
- size = self.getFileSize()
- request.setHeader('content-length', str(size))
- if self.type:
- request.setHeader('content-type', self.type)
- if self.encoding:
- request.setHeader('content-encoding', self.encoding)
-
-
- def makeProducer(self, request, fileForReading):
- """
- Make a L{StaticProducer} that will produce the body of this response.
-
- This method will also set the response code and Content-* headers.
-
- @param request: The L{Request} object.
- @param fileForReading: The file object containing the resource.
- @return: A L{StaticProducer}. Calling C{.start()} on this will begin
- producing the response.
- """
- byteRange = request.getHeader('range')
- if byteRange is None:
- self._setContentHeaders(request)
- request.setResponseCode(http.OK)
- return NoRangeStaticProducer(request, fileForReading)
- try:
- parsedRanges = self._parseRangeHeader(byteRange)
- except ValueError:
- log.msg("Ignoring malformed Range header %r" % (byteRange,))
- self._setContentHeaders(request)
- request.setResponseCode(http.OK)
- return NoRangeStaticProducer(request, fileForReading)
-
- if len(parsedRanges) == 1:
- offset, size = self._doSingleRangeRequest(
- request, parsedRanges[0])
- self._setContentHeaders(request, size)
- return SingleRangeStaticProducer(
- request, fileForReading, offset, size)
- else:
- rangeInfo = self._doMultipleRangeRequest(request, parsedRanges)
- return MultipleRangeStaticProducer(
- request, fileForReading, rangeInfo)
-
-
- def render_GET(self, request):
- """
- Begin sending the contents of this L{File} (or a subset of the
- contents, based on the 'range' header) to the given request.
- """
- self.restat(False)
-
- if self.type is None:
- self.type, self.encoding = getTypeAndEncoding(self.basename(),
- self.contentTypes,
- self.contentEncodings,
- self.defaultType)
-
- if not self.exists():
- return self.childNotFound.render(request)
-
- if self.isdir():
- return self.redirect(request)
-
- request.setHeader('accept-ranges', 'bytes')
-
- try:
- fileForReading = self.openForReading()
- except IOError, e:
- import errno
- if e[0] == errno.EACCES:
- return resource.ForbiddenResource().render(request)
- else:
- raise
-
- if request.setLastModified(self.getmtime()) is http.CACHED:
- return ''
-
-
- producer = self.makeProducer(request, fileForReading)
-
- if request.method == 'HEAD':
- return ''
-
- producer.start()
- # and make sure the connection doesn't get closed
- return server.NOT_DONE_YET
- render_HEAD = render_GET
-
-
- def redirect(self, request):
- return redirectTo(addSlash(request), request)
-
-
- def listNames(self):
- if not self.isdir():
- return []
- directory = self.listdir()
- directory.sort()
- return directory
-
- def listEntities(self):
- return map(lambda fileName, self=self: self.createSimilarFile(os.path.join(self.path, fileName)), self.listNames())
-
-
- def createSimilarFile(self, path):
- f = self.__class__(path, self.defaultType, self.ignoredExts, self.registry)
- # refactoring by steps, here - constructor should almost certainly take these
- f.processors = self.processors
- f.indexNames = self.indexNames[:]
- f.childNotFound = self.childNotFound
- return f
-
-
-
-class StaticProducer(object):
- """
- Superclass for classes that implement the business of producing.
-
- @ivar request: The L{IRequest} to write the contents of the file to.
- @ivar fileObject: The file the contents of which to write to the request.
- """
-
- implements(interfaces.IPullProducer)
-
- bufferSize = abstract.FileDescriptor.bufferSize
-
-
- def __init__(self, request, fileObject):
- """
- Initialize the instance.
- """
- self.request = request
- self.fileObject = fileObject
-
-
- def start(self):
- raise NotImplementedError(self.start)
-
-
- def resumeProducing(self):
- raise NotImplementedError(self.resumeProducing)
-
-
- def stopProducing(self):
- """
- Stop producing data.
-
- L{IPullProducer.stopProducing} is called when our consumer has died,
- and subclasses also call this method when they are done producing
- data.
- """
- self.fileObject.close()
- self.request = None
-
-
-
-class NoRangeStaticProducer(StaticProducer):
- """
- A L{StaticProducer} that writes the entire file to the request.
- """
-
- def start(self):
- self.request.registerProducer(self, False)
-
-
- def resumeProducing(self):
- if not self.request:
- return
- data = self.fileObject.read(self.bufferSize)
- if data:
- # this .write will spin the reactor, calling .doWrite and then
- # .resumeProducing again, so be prepared for a re-entrant call
- self.request.write(data)
- else:
- self.request.unregisterProducer()
- self.request.finish()
- self.stopProducing()
-
-
-
-class SingleRangeStaticProducer(StaticProducer):
- """
- A L{StaticProducer} that writes a single chunk of a file to the request.
- """
-
- def __init__(self, request, fileObject, offset, size):
- """
- Initialize the instance.
-
- @param request: See L{StaticProducer}.
- @param fileObject: See L{StaticProducer}.
- @param offset: The offset into the file of the chunk to be written.
- @param size: The size of the chunk to write.
- """
- StaticProducer.__init__(self, request, fileObject)
- self.offset = offset
- self.size = size
-
-
- def start(self):
- self.fileObject.seek(self.offset)
- self.bytesWritten = 0
- self.request.registerProducer(self, 0)
-
-
- def resumeProducing(self):
- if not self.request:
- return
- data = self.fileObject.read(
- min(self.bufferSize, self.size - self.bytesWritten))
- if data:
- self.bytesWritten += len(data)
- # this .write will spin the reactor, calling .doWrite and then
- # .resumeProducing again, so be prepared for a re-entrant call
- self.request.write(data)
- if self.request and self.bytesWritten == self.size:
- self.request.unregisterProducer()
- self.request.finish()
- self.stopProducing()
-
-
-
-class MultipleRangeStaticProducer(StaticProducer):
- """
- A L{StaticProducer} that writes several chunks of a file to the request.
- """
-
- def __init__(self, request, fileObject, rangeInfo):
- """
- Initialize the instance.
-
- @param request: See L{StaticProducer}.
- @param fileObject: See L{StaticProducer}.
- @param rangeInfo: A list of tuples C{[(boundary, offset, size)]}
- where:
- - C{boundary} will be written to the request first.
- - C{offset} the offset into the file of chunk to write.
- - C{size} the size of the chunk to write.
- """
- StaticProducer.__init__(self, request, fileObject)
- self.rangeInfo = rangeInfo
-
-
- def start(self):
- self.rangeIter = iter(self.rangeInfo)
- self._nextRange()
- self.request.registerProducer(self, 0)
-
-
- def _nextRange(self):
- self.partBoundary, partOffset, self._partSize = self.rangeIter.next()
- self._partBytesWritten = 0
- self.fileObject.seek(partOffset)
-
-
- def resumeProducing(self):
- if not self.request:
- return
- data = []
- dataLength = 0
- done = False
- while dataLength < self.bufferSize:
- if self.partBoundary:
- dataLength += len(self.partBoundary)
- data.append(self.partBoundary)
- self.partBoundary = None
- p = self.fileObject.read(
- min(self.bufferSize - dataLength,
- self._partSize - self._partBytesWritten))
- self._partBytesWritten += len(p)
- dataLength += len(p)
- data.append(p)
- if self.request and self._partBytesWritten == self._partSize:
- try:
- self._nextRange()
- except StopIteration:
- done = True
- break
- self.request.write(''.join(data))
- if done:
- self.request.unregisterProducer()
- self.request.finish()
- self.request = None
-
-
-
-class ASISProcessor(resource.Resource):
- """
- Serve files exactly as responses without generating a status-line or any
- headers. Inspired by Apache's mod_asis.
- """
-
- def __init__(self, path, registry=None):
- resource.Resource.__init__(self)
- self.path = path
- self.registry = registry or Registry()
-
-
- def render(self, request):
- request.startedWriting = 1
- res = File(self.path, registry=self.registry)
- return res.render(request)
-
-
-
-def formatFileSize(size):
- """
- Format the given file size in bytes to human readable format.
- """
- if size < 1024:
- return '%iB' % size
- elif size < (1024 ** 2):
- return '%iK' % (size / 1024)
- elif size < (1024 ** 3):
- return '%iM' % (size / (1024 ** 2))
- else:
- return '%iG' % (size / (1024 ** 3))
-
-
-
-class DirectoryLister(resource.Resource):
- """
- Print the content of a directory.
-
- @ivar template: page template used to render the content of the directory.
- It must contain the format keys B{header} and B{tableContent}.
- @type template: C{str}
-
- @ivar linePattern: template used to render one line in the listing table.
- It must contain the format keys B{class}, B{href}, B{text}, B{size},
- B{type} and B{encoding}.
- @type linePattern: C{str}
-
- @ivar contentEncodings: a mapping of extensions to encoding types.
- @type contentEncodings: C{dict}
-
- @ivar defaultType: default type used when no mimetype is detected.
- @type defaultType: C{str}
-
- @ivar dirs: filtered content of C{path}, if the whole content should not be
- displayed (default to C{None}, which means the actual content of
- C{path} is printed).
- @type dirs: C{NoneType} or C{list}
-
- @ivar path: directory which content should be listed.
- @type path: C{str}
- """
-
- template = """<html>
-<head>
-<title>%(header)s</title>
-<style>
-.even-dir { background-color: #efe0ef }
-.even { background-color: #eee }
-.odd-dir {background-color: #f0d0ef }
-.odd { background-color: #dedede }
-.icon { text-align: center }
-.listing {
- margin-left: auto;
- margin-right: auto;
- width: 50%%;
- padding: 0.1em;
- }
-
-body { border: 0; padding: 0; margin: 0; background-color: #efefef; }
-h1 {padding: 0.1em; background-color: #777; color: white; border-bottom: thin white dashed;}
-
-</style>
-</head>
-
-<body>
-<h1>%(header)s</h1>
-
-<table>
- <thead>
- <tr>
- <th>Filename</th>
- <th>Size</th>
- <th>Content type</th>
- <th>Content encoding</th>
- </tr>
- </thead>
- <tbody>
-%(tableContent)s
- </tbody>
-</table>
-
-</body>
-</html>
-"""
-
- linePattern = """<tr class="%(class)s">
- <td><a href="%(href)s">%(text)s</a></td>
- <td>%(size)s</td>
- <td>%(type)s</td>
- <td>%(encoding)s</td>
-</tr>
-"""
-
- def __init__(self, pathname, dirs=None,
- contentTypes=File.contentTypes,
- contentEncodings=File.contentEncodings,
- defaultType='text/html'):
- resource.Resource.__init__(self)
- self.contentTypes = contentTypes
- self.contentEncodings = contentEncodings
- self.defaultType = defaultType
- # dirs allows usage of the File to specify what gets listed
- self.dirs = dirs
- self.path = pathname
-
-
- def _getFilesAndDirectories(self, directory):
- """
- Helper returning files and directories in given directory listing, with
- attributes to be used to build a table content with
- C{self.linePattern}.
-
- @return: tuple of (directories, files)
- @rtype: C{tuple} of C{list}
- """
- files = []
- dirs = []
- for path in directory:
- url = urllib.quote(path, "/")
- escapedPath = cgi.escape(path)
- if os.path.isdir(os.path.join(self.path, path)):
- url = url + '/'
- dirs.append({'text': escapedPath + "/", 'href': url,
- 'size': '', 'type': '[Directory]',
- 'encoding': ''})
- else:
- mimetype, encoding = getTypeAndEncoding(path, self.contentTypes,
- self.contentEncodings,
- self.defaultType)
- try:
- size = os.stat(os.path.join(self.path, path)).st_size
- except OSError:
- continue
- files.append({
- 'text': escapedPath, "href": url,
- 'type': '[%s]' % mimetype,
- 'encoding': (encoding and '[%s]' % encoding or ''),
- 'size': formatFileSize(size)})
- return dirs, files
-
-
- def _buildTableContent(self, elements):
- """
- Build a table content using C{self.linePattern} and giving elements odd
- and even classes.
- """
- tableContent = []
- rowClasses = itertools.cycle(['odd', 'even'])
- for element, rowClass in zip(elements, rowClasses):
- element["class"] = rowClass
- tableContent.append(self.linePattern % element)
- return tableContent
-
-
- def render(self, request):
- """
- Render a listing of the content of C{self.path}.
- """
- request.setHeader("content-type", "text/html; charset=utf-8")
- if self.dirs is None:
- directory = os.listdir(self.path)
- directory.sort()
- else:
- directory = self.dirs
-
- dirs, files = self._getFilesAndDirectories(directory)
-
- tableContent = "".join(self._buildTableContent(dirs + files))
-
- header = "Directory listing for %s" % (
- cgi.escape(urllib.unquote(request.uri)),)
-
- return self.template % {"header": header, "tableContent": tableContent}
-
-
- def __repr__(self):
- return '<DirectoryLister of %r>' % self.path
-
- __str__ = __repr__
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/sux.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/sux.py
deleted file mode 100755
index d5ddc4f3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/sux.py
+++ /dev/null
@@ -1,636 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_xml -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-*S*mall, *U*ncomplicated *X*ML.
-
-This is a very simple implementation of XML/HTML as a network
-protocol. It is not at all clever. Its main features are that it
-does not:
-
- - support namespaces
- - mung mnemonic entity references
- - validate
- - perform *any* external actions (such as fetching URLs or writing files)
- under *any* circumstances
- - has lots and lots of horrible hacks for supporting broken HTML (as an
- option, they're not on by default).
-"""
-
-from twisted.internet.protocol import Protocol
-from twisted.python.reflect import prefixedMethodNames
-
-
-
-# Elements of the three-tuples in the state table.
-BEGIN_HANDLER = 0
-DO_HANDLER = 1
-END_HANDLER = 2
-
-identChars = '.-_:'
-lenientIdentChars = identChars + ';+#/%~'
-
-def nop(*args, **kw):
- "Do nothing."
-
-
-def unionlist(*args):
- l = []
- for x in args:
- l.extend(x)
- d = dict([(x, 1) for x in l])
- return d.keys()
-
-
-def zipfndict(*args, **kw):
- default = kw.get('default', nop)
- d = {}
- for key in unionlist(*[fndict.keys() for fndict in args]):
- d[key] = tuple([x.get(key, default) for x in args])
- return d
-
-
-def prefixedMethodClassDict(clazz, prefix):
- return dict([(name, getattr(clazz, prefix + name)) for name in prefixedMethodNames(clazz, prefix)])
-
-
-def prefixedMethodObjDict(obj, prefix):
- return dict([(name, getattr(obj, prefix + name)) for name in prefixedMethodNames(obj.__class__, prefix)])
-
-
-class ParseError(Exception):
-
- def __init__(self, filename, line, col, message):
- self.filename = filename
- self.line = line
- self.col = col
- self.message = message
-
- def __str__(self):
- return "%s:%s:%s: %s" % (self.filename, self.line, self.col,
- self.message)
-
-class XMLParser(Protocol):
-
- state = None
- encodings = None
- filename = "<xml />"
- beExtremelyLenient = 0
- _prepend = None
-
- # _leadingBodyData will sometimes be set before switching to the
- # 'bodydata' state, when we "accidentally" read a byte of bodydata
- # in a different state.
- _leadingBodyData = None
-
- def connectionMade(self):
- self.lineno = 1
- self.colno = 0
- self.encodings = []
-
- def saveMark(self):
- '''Get the line number and column of the last character parsed'''
- # This gets replaced during dataReceived, restored afterwards
- return (self.lineno, self.colno)
-
- def _parseError(self, message):
- raise ParseError(*((self.filename,)+self.saveMark()+(message,)))
-
- def _buildStateTable(self):
- '''Return a dictionary of begin, do, end state function tuples'''
- # _buildStateTable leaves something to be desired but it does what it
- # does.. probably slowly, so I'm doing some evil caching so it doesn't
- # get called more than once per class.
- stateTable = getattr(self.__class__, '__stateTable', None)
- if stateTable is None:
- stateTable = self.__class__.__stateTable = zipfndict(
- *[prefixedMethodObjDict(self, prefix)
- for prefix in ('begin_', 'do_', 'end_')])
- return stateTable
-
- def _decode(self, data):
- if 'UTF-16' in self.encodings or 'UCS-2' in self.encodings:
- assert not len(data) & 1, 'UTF-16 must come in pairs for now'
- if self._prepend:
- data = self._prepend + data
- for encoding in self.encodings:
- data = unicode(data, encoding)
- return data
-
- def maybeBodyData(self):
- if self.endtag:
- return 'bodydata'
-
- # Get ready for fun! We're going to allow
- # <script>if (foo < bar)</script> to work!
- # We do this by making everything between <script> and
- # </script> a Text
- # BUT <script src="foo"> will be special-cased to do regular,
- # lenient behavior, because those may not have </script>
- # -radix
-
- if (self.tagName == 'script' and 'src' not in self.tagAttributes):
- # we do this ourselves rather than having begin_waitforendscript
- # becuase that can get called multiple times and we don't want
- # bodydata to get reset other than the first time.
- self.begin_bodydata(None)
- return 'waitforendscript'
- return 'bodydata'
-
-
-
- def dataReceived(self, data):
- stateTable = self._buildStateTable()
- if not self.state:
- # all UTF-16 starts with this string
- if data.startswith('\xff\xfe'):
- self._prepend = '\xff\xfe'
- self.encodings.append('UTF-16')
- data = data[2:]
- elif data.startswith('\xfe\xff'):
- self._prepend = '\xfe\xff'
- self.encodings.append('UTF-16')
- data = data[2:]
- self.state = 'begin'
- if self.encodings:
- data = self._decode(data)
- # bring state, lineno, colno into local scope
- lineno, colno = self.lineno, self.colno
- curState = self.state
- # replace saveMark with a nested scope function
- _saveMark = self.saveMark
- def saveMark():
- return (lineno, colno)
- self.saveMark = saveMark
- # fetch functions from the stateTable
- beginFn, doFn, endFn = stateTable[curState]
- try:
- for byte in data:
- # do newline stuff
- if byte == '\n':
- lineno += 1
- colno = 0
- else:
- colno += 1
- newState = doFn(byte)
- if newState is not None and newState != curState:
- # this is the endFn from the previous state
- endFn()
- curState = newState
- beginFn, doFn, endFn = stateTable[curState]
- beginFn(byte)
- finally:
- self.saveMark = _saveMark
- self.lineno, self.colno = lineno, colno
- # state doesn't make sense if there's an exception..
- self.state = curState
-
-
- def connectionLost(self, reason):
- """
- End the last state we were in.
- """
- stateTable = self._buildStateTable()
- stateTable[self.state][END_HANDLER]()
-
-
- # state methods
-
- def do_begin(self, byte):
- if byte.isspace():
- return
- if byte != '<':
- if self.beExtremelyLenient:
- self._leadingBodyData = byte
- return 'bodydata'
- self._parseError("First char of document [%r] wasn't <" % (byte,))
- return 'tagstart'
-
- def begin_comment(self, byte):
- self.commentbuf = ''
-
- def do_comment(self, byte):
- self.commentbuf += byte
- if self.commentbuf.endswith('-->'):
- self.gotComment(self.commentbuf[:-3])
- return 'bodydata'
-
- def begin_tagstart(self, byte):
- self.tagName = '' # name of the tag
- self.tagAttributes = {} # attributes of the tag
- self.termtag = 0 # is the tag self-terminating
- self.endtag = 0
-
- def do_tagstart(self, byte):
- if byte.isalnum() or byte in identChars:
- self.tagName += byte
- if self.tagName == '!--':
- return 'comment'
- elif byte.isspace():
- if self.tagName:
- if self.endtag:
- # properly strict thing to do here is probably to only
- # accept whitespace
- return 'waitforgt'
- return 'attrs'
- else:
- self._parseError("Whitespace before tag-name")
- elif byte == '>':
- if self.endtag:
- self.gotTagEnd(self.tagName)
- return 'bodydata'
- else:
- self.gotTagStart(self.tagName, {})
- return (not self.beExtremelyLenient) and 'bodydata' or self.maybeBodyData()
- elif byte == '/':
- if self.tagName:
- return 'afterslash'
- else:
- self.endtag = 1
- elif byte in '!?':
- if self.tagName:
- if not self.beExtremelyLenient:
- self._parseError("Invalid character in tag-name")
- else:
- self.tagName += byte
- self.termtag = 1
- elif byte == '[':
- if self.tagName == '!':
- return 'expectcdata'
- else:
- self._parseError("Invalid '[' in tag-name")
- else:
- if self.beExtremelyLenient:
- self.bodydata = '<'
- return 'unentity'
- self._parseError('Invalid tag character: %r'% byte)
-
- def begin_unentity(self, byte):
- self.bodydata += byte
-
- def do_unentity(self, byte):
- self.bodydata += byte
- return 'bodydata'
-
- def end_unentity(self):
- self.gotText(self.bodydata)
-
- def begin_expectcdata(self, byte):
- self.cdatabuf = byte
-
- def do_expectcdata(self, byte):
- self.cdatabuf += byte
- cdb = self.cdatabuf
- cd = '[CDATA['
- if len(cd) > len(cdb):
- if cd.startswith(cdb):
- return
- elif self.beExtremelyLenient:
- ## WHAT THE CRAP!? MSWord9 generates HTML that includes these
- ## bizarre <![if !foo]> <![endif]> chunks, so I've gotta ignore
- ## 'em as best I can. this should really be a separate parse
- ## state but I don't even have any idea what these _are_.
- return 'waitforgt'
- else:
- self._parseError("Mal-formed CDATA header")
- if cd == cdb:
- self.cdatabuf = ''
- return 'cdata'
- self._parseError("Mal-formed CDATA header")
-
- def do_cdata(self, byte):
- self.cdatabuf += byte
- if self.cdatabuf.endswith("]]>"):
- self.cdatabuf = self.cdatabuf[:-3]
- return 'bodydata'
-
- def end_cdata(self):
- self.gotCData(self.cdatabuf)
- self.cdatabuf = ''
-
- def do_attrs(self, byte):
- if byte.isalnum() or byte in identChars:
- # XXX FIXME really handle !DOCTYPE at some point
- if self.tagName == '!DOCTYPE':
- return 'doctype'
- if self.tagName[0] in '!?':
- return 'waitforgt'
- return 'attrname'
- elif byte.isspace():
- return
- elif byte == '>':
- self.gotTagStart(self.tagName, self.tagAttributes)
- return (not self.beExtremelyLenient) and 'bodydata' or self.maybeBodyData()
- elif byte == '/':
- return 'afterslash'
- elif self.beExtremelyLenient:
- # discard and move on? Only case I've seen of this so far was:
- # <foo bar="baz"">
- return
- self._parseError("Unexpected character: %r" % byte)
-
- def begin_doctype(self, byte):
- self.doctype = byte
-
- def do_doctype(self, byte):
- if byte == '>':
- return 'bodydata'
- self.doctype += byte
-
- def end_doctype(self):
- self.gotDoctype(self.doctype)
- self.doctype = None
-
- def do_waitforgt(self, byte):
- if byte == '>':
- if self.endtag or not self.beExtremelyLenient:
- return 'bodydata'
- return self.maybeBodyData()
-
- def begin_attrname(self, byte):
- self.attrname = byte
- self._attrname_termtag = 0
-
- def do_attrname(self, byte):
- if byte.isalnum() or byte in identChars:
- self.attrname += byte
- return
- elif byte == '=':
- return 'beforeattrval'
- elif byte.isspace():
- return 'beforeeq'
- elif self.beExtremelyLenient:
- if byte in '"\'':
- return 'attrval'
- if byte in lenientIdentChars or byte.isalnum():
- self.attrname += byte
- return
- if byte == '/':
- self._attrname_termtag = 1
- return
- if byte == '>':
- self.attrval = 'True'
- self.tagAttributes[self.attrname] = self.attrval
- self.gotTagStart(self.tagName, self.tagAttributes)
- if self._attrname_termtag:
- self.gotTagEnd(self.tagName)
- return 'bodydata'
- return self.maybeBodyData()
- # something is really broken. let's leave this attribute where it
- # is and move on to the next thing
- return
- self._parseError("Invalid attribute name: %r %r" % (self.attrname, byte))
-
- def do_beforeattrval(self, byte):
- if byte in '"\'':
- return 'attrval'
- elif byte.isspace():
- return
- elif self.beExtremelyLenient:
- if byte in lenientIdentChars or byte.isalnum():
- return 'messyattr'
- if byte == '>':
- self.attrval = 'True'
- self.tagAttributes[self.attrname] = self.attrval
- self.gotTagStart(self.tagName, self.tagAttributes)
- return self.maybeBodyData()
- if byte == '\\':
- # I saw this in actual HTML once:
- # <font size=\"3\"><sup>SM</sup></font>
- return
- self._parseError("Invalid initial attribute value: %r; Attribute values must be quoted." % byte)
-
- attrname = ''
- attrval = ''
-
- def begin_beforeeq(self,byte):
- self._beforeeq_termtag = 0
-
- def do_beforeeq(self, byte):
- if byte == '=':
- return 'beforeattrval'
- elif byte.isspace():
- return
- elif self.beExtremelyLenient:
- if byte.isalnum() or byte in identChars:
- self.attrval = 'True'
- self.tagAttributes[self.attrname] = self.attrval
- return 'attrname'
- elif byte == '>':
- self.attrval = 'True'
- self.tagAttributes[self.attrname] = self.attrval
- self.gotTagStart(self.tagName, self.tagAttributes)
- if self._beforeeq_termtag:
- self.gotTagEnd(self.tagName)
- return 'bodydata'
- return self.maybeBodyData()
- elif byte == '/':
- self._beforeeq_termtag = 1
- return
- self._parseError("Invalid attribute")
-
- def begin_attrval(self, byte):
- self.quotetype = byte
- self.attrval = ''
-
- def do_attrval(self, byte):
- if byte == self.quotetype:
- return 'attrs'
- self.attrval += byte
-
- def end_attrval(self):
- self.tagAttributes[self.attrname] = self.attrval
- self.attrname = self.attrval = ''
-
- def begin_messyattr(self, byte):
- self.attrval = byte
-
- def do_messyattr(self, byte):
- if byte.isspace():
- return 'attrs'
- elif byte == '>':
- endTag = 0
- if self.attrval.endswith('/'):
- endTag = 1
- self.attrval = self.attrval[:-1]
- self.tagAttributes[self.attrname] = self.attrval
- self.gotTagStart(self.tagName, self.tagAttributes)
- if endTag:
- self.gotTagEnd(self.tagName)
- return 'bodydata'
- return self.maybeBodyData()
- else:
- self.attrval += byte
-
- def end_messyattr(self):
- if self.attrval:
- self.tagAttributes[self.attrname] = self.attrval
-
- def begin_afterslash(self, byte):
- self._after_slash_closed = 0
-
- def do_afterslash(self, byte):
- # this state is only after a self-terminating slash, e.g. <foo/>
- if self._after_slash_closed:
- self._parseError("Mal-formed")#XXX When does this happen??
- if byte != '>':
- if self.beExtremelyLenient:
- return
- else:
- self._parseError("No data allowed after '/'")
- self._after_slash_closed = 1
- self.gotTagStart(self.tagName, self.tagAttributes)
- self.gotTagEnd(self.tagName)
- # don't need maybeBodyData here because there better not be
- # any javascript code after a <script/>... we'll see :(
- return 'bodydata'
-
- def begin_bodydata(self, byte):
- if self._leadingBodyData:
- self.bodydata = self._leadingBodyData
- del self._leadingBodyData
- else:
- self.bodydata = ''
-
- def do_bodydata(self, byte):
- if byte == '<':
- return 'tagstart'
- if byte == '&':
- return 'entityref'
- self.bodydata += byte
-
- def end_bodydata(self):
- self.gotText(self.bodydata)
- self.bodydata = ''
-
- def do_waitforendscript(self, byte):
- if byte == '<':
- return 'waitscriptendtag'
- self.bodydata += byte
-
- def begin_waitscriptendtag(self, byte):
- self.temptagdata = ''
- self.tagName = ''
- self.endtag = 0
-
- def do_waitscriptendtag(self, byte):
- # 1 enforce / as first byte read
- # 2 enforce following bytes to be subset of "script" until
- # tagName == "script"
- # 2a when that happens, gotText(self.bodydata) and gotTagEnd(self.tagName)
- # 3 spaces can happen anywhere, they're ignored
- # e.g. < / script >
- # 4 anything else causes all data I've read to be moved to the
- # bodydata, and switch back to waitforendscript state
-
- # If it turns out this _isn't_ a </script>, we need to
- # remember all the data we've been through so we can append it
- # to bodydata
- self.temptagdata += byte
-
- # 1
- if byte == '/':
- self.endtag = True
- elif not self.endtag:
- self.bodydata += "<" + self.temptagdata
- return 'waitforendscript'
- # 2
- elif byte.isalnum() or byte in identChars:
- self.tagName += byte
- if not 'script'.startswith(self.tagName):
- self.bodydata += "<" + self.temptagdata
- return 'waitforendscript'
- elif self.tagName == 'script':
- self.gotText(self.bodydata)
- self.gotTagEnd(self.tagName)
- return 'waitforgt'
- # 3
- elif byte.isspace():
- return 'waitscriptendtag'
- # 4
- else:
- self.bodydata += "<" + self.temptagdata
- return 'waitforendscript'
-
-
- def begin_entityref(self, byte):
- self.erefbuf = ''
- self.erefextra = '' # extra bit for lenient mode
-
- def do_entityref(self, byte):
- if byte.isspace() or byte == "<":
- if self.beExtremelyLenient:
- # '&foo' probably was '&amp;foo'
- if self.erefbuf and self.erefbuf != "amp":
- self.erefextra = self.erefbuf
- self.erefbuf = "amp"
- if byte == "<":
- return "tagstart"
- else:
- self.erefextra += byte
- return 'spacebodydata'
- self._parseError("Bad entity reference")
- elif byte != ';':
- self.erefbuf += byte
- else:
- return 'bodydata'
-
- def end_entityref(self):
- self.gotEntityReference(self.erefbuf)
-
- # hacky support for space after & in entityref in beExtremelyLenient
- # state should only happen in that case
- def begin_spacebodydata(self, byte):
- self.bodydata = self.erefextra
- self.erefextra = None
- do_spacebodydata = do_bodydata
- end_spacebodydata = end_bodydata
-
- # Sorta SAX-ish API
-
- def gotTagStart(self, name, attributes):
- '''Encountered an opening tag.
-
- Default behaviour is to print.'''
- print 'begin', name, attributes
-
- def gotText(self, data):
- '''Encountered text
-
- Default behaviour is to print.'''
- print 'text:', repr(data)
-
- def gotEntityReference(self, entityRef):
- '''Encountered mnemonic entity reference
-
- Default behaviour is to print.'''
- print 'entityRef: &%s;' % entityRef
-
- def gotComment(self, comment):
- '''Encountered comment.
-
- Default behaviour is to ignore.'''
- pass
-
- def gotCData(self, cdata):
- '''Encountered CDATA
-
- Default behaviour is to call the gotText method'''
- self.gotText(cdata)
-
- def gotDoctype(self, doctype):
- """Encountered DOCTYPE
-
- This is really grotty: it basically just gives you everything between
- '<!DOCTYPE' and '>' as an argument.
- """
- print '!DOCTYPE', repr(doctype)
-
- def gotTagEnd(self, name):
- '''Encountered closing tag
-
- Default behaviour is to print.'''
- print 'end', name
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/tap.py
deleted file mode 100755
index addcba12..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/tap.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Support for creating a service which runs a web server.
-"""
-
-import os
-
-# Twisted Imports
-from twisted.web import server, static, twcgi, script, demo, distrib, wsgi
-from twisted.internet import interfaces, reactor
-from twisted.python import usage, reflect, threadpool
-from twisted.spread import pb
-from twisted.application import internet, service, strports
-
-
-class Options(usage.Options):
- """
- Define the options accepted by the I{twistd web} plugin.
- """
- synopsis = "[web options]"
-
- optParameters = [["port", "p", None, "strports description of the port to "
- "start the server on."],
- ["logfile", "l", None, "Path to web CLF (Combined Log Format) log file."],
- ["https", None, None, "Port to listen on for Secure HTTP."],
- ["certificate", "c", "server.pem", "SSL certificate to use for HTTPS. "],
- ["privkey", "k", "server.pem", "SSL certificate to use for HTTPS."],
- ]
-
- optFlags = [["personal", "",
- "Instead of generating a webserver, generate a "
- "ResourcePublisher which listens on the port given by "
- "--port, or ~/%s " % (distrib.UserDirectory.userSocketName,) +
- "if --port is not specified."],
- ["notracebacks", "n", "Do not display tracebacks in broken web pages. " +
- "Displaying tracebacks to users may be security risk!"],
- ]
-
- compData = usage.Completions(
- optActions={"logfile" : usage.CompleteFiles("*.log"),
- "certificate" : usage.CompleteFiles("*.pem"),
- "privkey" : usage.CompleteFiles("*.pem")}
- )
-
- longdesc = """\
-This starts a webserver. If you specify no arguments, it will be a
-demo webserver that has the Test class from twisted.web.demo in it."""
-
- def __init__(self):
- usage.Options.__init__(self)
- self['indexes'] = []
- self['root'] = None
-
-
- def opt_index(self, indexName):
- """
- Add the name of a file used to check for directory indexes.
- [default: index, index.html]
- """
- self['indexes'].append(indexName)
-
- opt_i = opt_index
-
-
- def opt_user(self):
- """
- Makes a server with ~/public_html and ~/.twistd-web-pb support for
- users.
- """
- self['root'] = distrib.UserDirectory()
-
- opt_u = opt_user
-
-
- def opt_path(self, path):
- """
- <path> is either a specific file or a directory to be set as the root
- of the web server. Use this if you have a directory full of HTML, cgi,
- epy, or rpy files or any other files that you want to be served up raw.
- """
- self['root'] = static.File(os.path.abspath(path))
- self['root'].processors = {
- '.cgi': twcgi.CGIScript,
- '.epy': script.PythonScript,
- '.rpy': script.ResourceScript,
- }
-
-
- def opt_processor(self, proc):
- """
- `ext=class' where `class' is added as a Processor for files ending
- with `ext'.
- """
- if not isinstance(self['root'], static.File):
- raise usage.UsageError("You can only use --processor after --path.")
- ext, klass = proc.split('=', 1)
- self['root'].processors[ext] = reflect.namedClass(klass)
-
-
- def opt_class(self, className):
- """
- Create a Resource subclass with a zero-argument constructor.
- """
- classObj = reflect.namedClass(className)
- self['root'] = classObj()
-
-
- def opt_resource_script(self, name):
- """
- An .rpy file to be used as the root resource of the webserver.
- """
- self['root'] = script.ResourceScriptWrapper(name)
-
-
- def opt_wsgi(self, name):
- """
- The FQPN of a WSGI application object to serve as the root resource of
- the webserver.
- """
- pool = threadpool.ThreadPool()
- reactor.callWhenRunning(pool.start)
- reactor.addSystemEventTrigger('after', 'shutdown', pool.stop)
- try:
- application = reflect.namedAny(name)
- except (AttributeError, ValueError):
- raise usage.UsageError("No such WSGI application: %r" % (name,))
- self['root'] = wsgi.WSGIResource(reactor, pool, application)
-
-
- def opt_mime_type(self, defaultType):
- """
- Specify the default mime-type for static files.
- """
- if not isinstance(self['root'], static.File):
- raise usage.UsageError("You can only use --mime_type after --path.")
- self['root'].defaultType = defaultType
- opt_m = opt_mime_type
-
-
- def opt_allow_ignore_ext(self):
- """
- Specify whether or not a request for 'foo' should return 'foo.ext'
- """
- if not isinstance(self['root'], static.File):
- raise usage.UsageError("You can only use --allow_ignore_ext "
- "after --path.")
- self['root'].ignoreExt('*')
-
-
- def opt_ignore_ext(self, ext):
- """
- Specify an extension to ignore. These will be processed in order.
- """
- if not isinstance(self['root'], static.File):
- raise usage.UsageError("You can only use --ignore_ext "
- "after --path.")
- self['root'].ignoreExt(ext)
-
-
- def postOptions(self):
- """
- Set up conditional defaults and check for dependencies.
-
- If SSL is not available but an HTTPS server was configured, raise a
- L{UsageError} indicating that this is not possible.
-
- If no server port was supplied, select a default appropriate for the
- other options supplied.
- """
- if self['https']:
- try:
- from twisted.internet.ssl import DefaultOpenSSLContextFactory
- except ImportError:
- raise usage.UsageError("SSL support not installed")
- if self['port'] is None:
- if self['personal']:
- path = os.path.expanduser(
- os.path.join('~', distrib.UserDirectory.userSocketName))
- self['port'] = 'unix:' + path
- else:
- self['port'] = 'tcp:8080'
-
-
-
-def makePersonalServerFactory(site):
- """
- Create and return a factory which will respond to I{distrib} requests
- against the given site.
-
- @type site: L{twisted.web.server.Site}
- @rtype: L{twisted.internet.protocol.Factory}
- """
- return pb.PBServerFactory(distrib.ResourcePublisher(site))
-
-
-
-def makeService(config):
- s = service.MultiService()
- if config['root']:
- root = config['root']
- if config['indexes']:
- config['root'].indexNames = config['indexes']
- else:
- # This really ought to be web.Admin or something
- root = demo.Test()
-
- if isinstance(root, static.File):
- root.registry.setComponent(interfaces.IServiceCollection, s)
-
- if config['logfile']:
- site = server.Site(root, logPath=config['logfile'])
- else:
- site = server.Site(root)
-
- site.displayTracebacks = not config["notracebacks"]
-
- if config['personal']:
- personal = strports.service(
- config['port'], makePersonalServerFactory(site))
- personal.setServiceParent(s)
- else:
- if config['https']:
- from twisted.internet.ssl import DefaultOpenSSLContextFactory
- i = internet.SSLServer(int(config['https']), site,
- DefaultOpenSSLContextFactory(config['privkey'],
- config['certificate']))
- i.setServiceParent(s)
- strports.service(config['port'], site).setServiceParent(s)
-
- return s
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/template.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/template.py
deleted file mode 100755
index 224a1921..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/template.py
+++ /dev/null
@@ -1,566 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_template -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-HTML rendering for twisted.web.
-
-@var VALID_HTML_TAG_NAMES: A list of recognized HTML tag names, used by the
- L{tag} object.
-
-@var TEMPLATE_NAMESPACE: The XML namespace used to identify attributes and
- elements used by the templating system, which should be removed from the
- final output document.
-
-@var tags: A convenience object which can produce L{Tag} objects on demand via
- attribute access. For example: C{tags.div} is equivalent to C{Tag("div")}.
- Tags not specified in L{VALID_HTML_TAG_NAMES} will result in an
- L{AttributeError}.
-"""
-
-__all__ = [
- 'TEMPLATE_NAMESPACE', 'VALID_HTML_TAG_NAMES', 'Element', 'TagLoader',
- 'XMLString', 'XMLFile', 'renderer', 'flatten', 'flattenString', 'tags',
- 'Comment', 'CDATA', 'Tag', 'slot', 'CharRef', 'renderElement'
- ]
-
-import warnings
-from zope.interface import implements
-
-from cStringIO import StringIO
-from xml.sax import make_parser, handler
-
-from twisted.web._stan import Tag, slot, Comment, CDATA, CharRef
-from twisted.python.filepath import FilePath
-
-TEMPLATE_NAMESPACE = 'http://twistedmatrix.com/ns/twisted.web.template/0.1'
-
-from twisted.web.iweb import ITemplateLoader
-from twisted.python import log
-
-# Go read the definition of NOT_DONE_YET. For lulz. This is totally
-# equivalent. And this turns out to be necessary, because trying to import
-# NOT_DONE_YET in this module causes a circular import which we cannot escape
-# from. From which we cannot escape. Etc. glyph is okay with this solution for
-# now, and so am I, as long as this comment stays to explain to future
-# maintainers what it means. ~ C.
-#
-# See http://twistedmatrix.com/trac/ticket/5557 for progress on fixing this.
-NOT_DONE_YET = 1
-
-class _NSContext(object):
- """
- A mapping from XML namespaces onto their prefixes in the document.
- """
-
- def __init__(self, parent=None):
- """
- Pull out the parent's namespaces, if there's no parent then default to
- XML.
- """
- self.parent = parent
- if parent is not None:
- self.nss = dict(parent.nss)
- else:
- self.nss = {'http://www.w3.org/XML/1998/namespace':'xml'}
-
-
- def get(self, k, d=None):
- """
- Get a prefix for a namespace.
-
- @param d: The default prefix value.
- """
- return self.nss.get(k, d)
-
-
- def __setitem__(self, k, v):
- """
- Proxy through to setting the prefix for the namespace.
- """
- self.nss.__setitem__(k, v)
-
-
- def __getitem__(self, k):
- """
- Proxy through to getting the prefix for the namespace.
- """
- return self.nss.__getitem__(k)
-
-
-
-class _ToStan(handler.ContentHandler, handler.EntityResolver):
- """
- A SAX parser which converts an XML document to the Twisted STAN
- Document Object Model.
- """
-
- def __init__(self, sourceFilename):
- """
- @param sourceFilename: the filename to load the XML out of.
- """
- self.sourceFilename = sourceFilename
- self.prefixMap = _NSContext()
- self.inCDATA = False
-
-
- def setDocumentLocator(self, locator):
- """
- Set the document locator, which knows about line and character numbers.
- """
- self.locator = locator
-
-
- def startDocument(self):
- """
- Initialise the document.
- """
- self.document = []
- self.current = self.document
- self.stack = []
- self.xmlnsAttrs = []
-
-
- def endDocument(self):
- """
- Document ended.
- """
-
-
- def processingInstruction(self, target, data):
- """
- Processing instructions are ignored.
- """
-
-
- def startPrefixMapping(self, prefix, uri):
- """
- Set up the prefix mapping, which maps fully qualified namespace URIs
- onto namespace prefixes.
-
- This gets called before startElementNS whenever an C{xmlns} attribute
- is seen.
- """
-
- self.prefixMap = _NSContext(self.prefixMap)
- self.prefixMap[uri] = prefix
-
- # Ignore the template namespace; we'll replace those during parsing.
- if uri == TEMPLATE_NAMESPACE:
- return
-
- # Add to a list that will be applied once we have the element.
- if prefix is None:
- self.xmlnsAttrs.append(('xmlns',uri))
- else:
- self.xmlnsAttrs.append(('xmlns:%s'%prefix,uri))
-
-
- def endPrefixMapping(self, prefix):
- """
- "Pops the stack" on the prefix mapping.
-
- Gets called after endElementNS.
- """
- self.prefixMap = self.prefixMap.parent
-
-
- def startElementNS(self, namespaceAndName, qname, attrs):
- """
- Gets called when we encounter a new xmlns attribute.
-
- @param namespaceAndName: a (namespace, name) tuple, where name
- determines which type of action to take, if the namespace matches
- L{TEMPLATE_NAMESPACE}.
- @param qname: ignored.
- @param attrs: attributes on the element being started.
- """
-
- filename = self.sourceFilename
- lineNumber = self.locator.getLineNumber()
- columnNumber = self.locator.getColumnNumber()
-
- ns, name = namespaceAndName
- if ns == TEMPLATE_NAMESPACE:
- if name == 'transparent':
- name = ''
- elif name == 'slot':
- try:
- # Try to get the default value for the slot
- default = attrs[(None, 'default')]
- except KeyError:
- # If there wasn't one, then use None to indicate no
- # default.
- default = None
- el = slot(
- attrs[(None, 'name')], default=default,
- filename=filename, lineNumber=lineNumber,
- columnNumber=columnNumber)
- self.stack.append(el)
- self.current.append(el)
- self.current = el.children
- return
-
- render = None
-
- attrs = dict(attrs)
- for k, v in attrs.items():
- attrNS, justTheName = k
- if attrNS != TEMPLATE_NAMESPACE:
- continue
- if justTheName == 'render':
- render = v
- del attrs[k]
-
- # nonTemplateAttrs is a dictionary mapping attributes that are *not* in
- # TEMPLATE_NAMESPACE to their values. Those in TEMPLATE_NAMESPACE were
- # just removed from 'attrs' in the loop immediately above. The key in
- # nonTemplateAttrs is either simply the attribute name (if it was not
- # specified as having a namespace in the template) or prefix:name,
- # preserving the xml namespace prefix given in the document.
-
- nonTemplateAttrs = {}
- for (attrNs, attrName), v in attrs.items():
- nsPrefix = self.prefixMap.get(attrNs)
- if nsPrefix is None:
- attrKey = attrName
- else:
- attrKey = '%s:%s' % (nsPrefix, attrName)
- nonTemplateAttrs[attrKey] = v
-
- if ns == TEMPLATE_NAMESPACE and name == 'attr':
- if not self.stack:
- # TODO: define a better exception for this?
- raise AssertionError(
- '<{%s}attr> as top-level element' % (TEMPLATE_NAMESPACE,))
- if 'name' not in nonTemplateAttrs:
- # TODO: same here
- raise AssertionError(
- '<{%s}attr> requires a name attribute' % (TEMPLATE_NAMESPACE,))
- el = Tag('', render=render, filename=filename,
- lineNumber=lineNumber, columnNumber=columnNumber)
- self.stack[-1].attributes[nonTemplateAttrs['name']] = el
- self.stack.append(el)
- self.current = el.children
- return
-
- # Apply any xmlns attributes
- if self.xmlnsAttrs:
- nonTemplateAttrs.update(dict(self.xmlnsAttrs))
- self.xmlnsAttrs = []
-
- # Add the prefix that was used in the parsed template for non-template
- # namespaces (which will not be consumed anyway).
- if ns != TEMPLATE_NAMESPACE and ns is not None:
- prefix = self.prefixMap[ns]
- if prefix is not None:
- name = '%s:%s' % (self.prefixMap[ns],name)
- el = Tag(
- name, attributes=dict(nonTemplateAttrs), render=render,
- filename=filename, lineNumber=lineNumber,
- columnNumber=columnNumber)
- self.stack.append(el)
- self.current.append(el)
- self.current = el.children
-
-
- def characters(self, ch):
- """
- Called when we receive some characters. CDATA characters get passed
- through as is.
-
- @type ch: C{string}
- """
- if self.inCDATA:
- self.stack[-1].append(ch)
- return
- self.current.append(ch)
-
-
- def endElementNS(self, name, qname):
- """
- A namespace tag is closed. Pop the stack, if there's anything left in
- it, otherwise return to the document's namespace.
- """
- self.stack.pop()
- if self.stack:
- self.current = self.stack[-1].children
- else:
- self.current = self.document
-
-
- def startDTD(self, name, publicId, systemId):
- """
- DTDs are ignored.
- """
-
-
- def endDTD(self, *args):
- """
- DTDs are ignored.
- """
-
-
- def startCDATA(self):
- """
- We're starting to be in a CDATA element, make a note of this.
- """
- self.inCDATA = True
- self.stack.append([])
-
-
- def endCDATA(self):
- """
- We're no longer in a CDATA element. Collect up the characters we've
- parsed and put them in a new CDATA object.
- """
- self.inCDATA = False
- comment = ''.join(self.stack.pop())
- self.current.append(CDATA(comment))
-
-
- def comment(self, content):
- """
- Add an XML comment which we've encountered.
- """
- self.current.append(Comment(content))
-
-
-
-def _flatsaxParse(fl):
- """
- Perform a SAX parse of an XML document with the _ToStan class.
-
- @param fl: The XML document to be parsed.
- @type fl: A file object or filename.
-
- @return: a C{list} of Stan objects.
- """
- parser = make_parser()
- parser.setFeature(handler.feature_validation, 0)
- parser.setFeature(handler.feature_namespaces, 1)
- parser.setFeature(handler.feature_external_ges, 0)
- parser.setFeature(handler.feature_external_pes, 0)
-
- s = _ToStan(getattr(fl, "name", None))
- parser.setContentHandler(s)
- parser.setEntityResolver(s)
- parser.setProperty(handler.property_lexical_handler, s)
-
- parser.parse(fl)
-
- return s.document
-
-
-class TagLoader(object):
- """
- An L{ITemplateLoader} that loads existing L{IRenderable} providers.
-
- @ivar tag: The object which will be loaded.
- @type tag: An L{IRenderable} provider.
- """
- implements(ITemplateLoader)
-
- def __init__(self, tag):
- """
- @param tag: The object which will be loaded.
- @type tag: An L{IRenderable} provider.
- """
- self.tag = tag
-
-
- def load(self):
- return [self.tag]
-
-
-
-class XMLString(object):
- """
- An L{ITemplateLoader} that loads and parses XML from a string.
-
- @ivar _loadedTemplate: The loaded document.
- @type _loadedTemplate: a C{list} of Stan objects.
- """
- implements(ITemplateLoader)
-
- def __init__(self, s):
- """
- Run the parser on a StringIO copy of the string.
-
- @param s: The string from which to load the XML.
- @type s: C{str}
- """
- self._loadedTemplate = _flatsaxParse(StringIO(s))
-
-
- def load(self):
- """
- Return the document.
-
- @return: the loaded document.
- @rtype: a C{list} of Stan objects.
- """
- return self._loadedTemplate
-
-
-
-class XMLFile(object):
- """
- An L{ITemplateLoader} that loads and parses XML from a file.
-
- @ivar _loadedTemplate: The loaded document, or C{None}, if not loaded.
- @type _loadedTemplate: a C{list} of Stan objects, or C{None}.
-
- @ivar _path: The L{FilePath}, file object, or filename that is being
- loaded from.
- """
- implements(ITemplateLoader)
-
- def __init__(self, path):
- """
- Run the parser on a file.
-
- @param path: The file from which to load the XML.
- @type path: L{FilePath}
- """
- if not isinstance(path, FilePath):
- warnings.warn(
- "Passing filenames or file objects to XMLFile is deprecated "
- "since Twisted 12.1. Pass a FilePath instead.",
- category=DeprecationWarning, stacklevel=2)
- self._loadedTemplate = None
- self._path = path
-
-
- def _loadDoc(self):
- """
- Read and parse the XML.
-
- @return: the loaded document.
- @rtype: a C{list} of Stan objects.
- """
- if not isinstance(self._path, FilePath):
- return _flatsaxParse(self._path)
- else:
- f = self._path.open('r')
- try:
- return _flatsaxParse(f)
- finally:
- f.close()
-
-
- def __repr__(self):
- return '<XMLFile of %r>' % (self._path,)
-
-
- def load(self):
- """
- Return the document, first loading it if necessary.
-
- @return: the loaded document.
- @rtype: a C{list} of Stan objects.
- """
- if self._loadedTemplate is None:
- self._loadedTemplate = self._loadDoc()
- return self._loadedTemplate
-
-
-
-# Last updated October 2011, using W3Schools as a reference. Link:
-# http://www.w3schools.com/html5/html5_reference.asp
-# Note that <xmp> is explicitly omitted; its semantics do not work with
-# t.w.template and it is officially deprecated.
-VALID_HTML_TAG_NAMES = set([
- 'a', 'abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside',
- 'audio', 'b', 'base', 'basefont', 'bdi', 'bdo', 'big', 'blockquote',
- 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code',
- 'col', 'colgroup', 'command', 'datalist', 'dd', 'del', 'details', 'dfn',
- 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption',
- 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3',
- 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe',
- 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'legend',
- 'li', 'link', 'map', 'mark', 'menu', 'meta', 'meter', 'nav', 'noframes',
- 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param',
- 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script',
- 'section', 'select', 'small', 'source', 'span', 'strike', 'strong',
- 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea',
- 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'tt', 'u', 'ul', 'var',
- 'video', 'wbr',
-])
-
-
-
-class _TagFactory(object):
- """
- A factory for L{Tag} objects; the implementation of the L{tags} object.
-
- This allows for the syntactic convenience of C{from twisted.web.html import
- tags; tags.a(href="linked-page.html")}, where 'a' can be basically any HTML
- tag.
-
- The class is not exposed publicly because you only ever need one of these,
- and we already made it for you.
-
- @see: L{tags}
- """
- def __getattr__(self, tagName):
- if tagName == 'transparent':
- return Tag('')
- # allow for E.del as E.del_
- tagName = tagName.rstrip('_')
- if tagName not in VALID_HTML_TAG_NAMES:
- raise AttributeError('unknown tag %r' % (tagName,))
- return Tag(tagName)
-
-
-
-tags = _TagFactory()
-
-
-
-def renderElement(request, element,
- doctype='<!DOCTYPE html>', _failElement=None):
- """
- Render an element or other C{IRenderable}.
-
- @param request: The C{Request} being rendered to.
- @param element: An C{IRenderable} which will be rendered.
- @param doctype: A C{str} which will be written as the first line of
- the request, or C{None} to disable writing of a doctype. The C{string}
- should not include a trailing newline and will default to the HTML5
- doctype C{'<!DOCTYPE html>'}.
-
- @returns: NOT_DONE_YET
-
- @since: 12.1
- """
- if doctype is not None:
- request.write(doctype)
- request.write('\n')
-
- if _failElement is None:
- _failElement = twisted.web.util.FailureElement
-
- d = flatten(request, element, request.write)
-
- def eb(failure):
- log.err(failure, "An error occurred while rendering the response.")
- if request.site.displayTracebacks:
- return flatten(request, _failElement(failure), request.write)
- else:
- request.write(
- ('<div style="font-size:800%;'
- 'background-color:#FFF;'
- 'color:#F00'
- '">An error occurred while rendering the response.</div>'))
-
- d.addErrback(eb)
- d.addBoth(lambda _: request.finish())
- return NOT_DONE_YET
-
-
-
-from twisted.web._element import Element, renderer
-from twisted.web._flatten import flatten, flattenString
-import twisted.web.util
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/__init__.py
deleted file mode 100755
index cdbb14e0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web}.
-"""
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/_util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/_util.py
deleted file mode 100755
index 6117b728..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/_util.py
+++ /dev/null
@@ -1,77 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-General helpers for L{twisted.web} unit tests.
-"""
-
-from twisted.internet.defer import succeed
-from twisted.web import server
-from twisted.trial.unittest import TestCase
-from twisted.python.failure import Failure
-from twisted.web._flatten import flattenString
-from twisted.web.error import FlattenerError
-
-
-def _render(resource, request):
- result = resource.render(request)
- if isinstance(result, str):
- request.write(result)
- request.finish()
- return succeed(None)
- elif result is server.NOT_DONE_YET:
- if request.finished:
- return succeed(None)
- else:
- return request.notifyFinish()
- else:
- raise ValueError("Unexpected return value: %r" % (result,))
-
-
-
-class FlattenTestCase(TestCase):
- """
- A test case that assists with testing L{twisted.web._flatten}.
- """
- def assertFlattensTo(self, root, target):
- """
- Assert that a root element, when flattened, is equal to a string.
- """
- d = flattenString(None, root)
- d.addCallback(lambda s: self.assertEqual(s, target))
- return d
-
-
- def assertFlattensImmediately(self, root, target):
- """
- Assert that a root element, when flattened, is equal to a string, and
- performs no asynchronus Deferred anything.
-
- This version is more convenient in tests which wish to make multiple
- assertions about flattening, since it can be called multiple times
- without having to add multiple callbacks.
- """
- results = []
- it = self.assertFlattensTo(root, target)
- it.addBoth(results.append)
- # Do our best to clean it up if something goes wrong.
- self.addCleanup(it.cancel)
- if not results:
- self.fail("Rendering did not complete immediately.")
- result = results[0]
- if isinstance(result, Failure):
- result.raiseException()
-
-
- def assertFlatteningRaises(self, root, exn):
- """
- Assert flattening a root element raises a particular exception.
- """
- d = self.assertFailure(self.assertFlattensTo(root, ''), FlattenerError)
- d.addCallback(lambda exc: self.assertIsInstance(exc._exception, exn))
- return d
-
-
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_cgi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_cgi.py
deleted file mode 100755
index db63211e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_cgi.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.twcgi}.
-"""
-
-import sys, os
-
-from twisted.trial import unittest
-from twisted.internet import reactor, interfaces, error
-from twisted.python import util, failure
-from twisted.web.http import NOT_FOUND, INTERNAL_SERVER_ERROR
-from twisted.web import client, twcgi, server, resource
-from twisted.web.test._util import _render
-from twisted.web.test.test_web import DummyRequest
-
-DUMMY_CGI = '''\
-print "Header: OK"
-print
-print "cgi output"
-'''
-
-DUAL_HEADER_CGI = '''\
-print "Header: spam"
-print "Header: eggs"
-print
-print "cgi output"
-'''
-
-SPECIAL_HEADER_CGI = '''\
-print "Server: monkeys"
-print "Date: last year"
-print
-print "cgi output"
-'''
-
-READINPUT_CGI = '''\
-# this is an example of a correctly-written CGI script which reads a body
-# from stdin, which only reads env['CONTENT_LENGTH'] bytes.
-
-import os, sys
-
-body_length = int(os.environ.get('CONTENT_LENGTH',0))
-indata = sys.stdin.read(body_length)
-print "Header: OK"
-print
-print "readinput ok"
-'''
-
-READALLINPUT_CGI = '''\
-# this is an example of the typical (incorrect) CGI script which expects
-# the server to close stdin when the body of the request is complete.
-# A correct CGI should only read env['CONTENT_LENGTH'] bytes.
-
-import sys
-
-indata = sys.stdin.read()
-print "Header: OK"
-print
-print "readallinput ok"
-'''
-
-NO_DUPLICATE_CONTENT_TYPE_HEADER_CGI = '''\
-print "content-type: text/cgi-duplicate-test"
-print
-print "cgi output"
-'''
-
-class PythonScript(twcgi.FilteredScript):
- filter = sys.executable
-
-class CGI(unittest.TestCase):
- """
- Tests for L{twcgi.FilteredScript}.
- """
-
- if not interfaces.IReactorProcess.providedBy(reactor):
- skip = "CGI tests require a functional reactor.spawnProcess()"
-
- def startServer(self, cgi):
- root = resource.Resource()
- cgipath = util.sibpath(__file__, cgi)
- root.putChild("cgi", PythonScript(cgipath))
- site = server.Site(root)
- self.p = reactor.listenTCP(0, site)
- return self.p.getHost().port
-
- def tearDown(self):
- if self.p:
- return self.p.stopListening()
-
-
- def writeCGI(self, source):
- cgiFilename = os.path.abspath(self.mktemp())
- cgiFile = file(cgiFilename, 'wt')
- cgiFile.write(source)
- cgiFile.close()
- return cgiFilename
-
-
- def testCGI(self):
- cgiFilename = self.writeCGI(DUMMY_CGI)
-
- portnum = self.startServer(cgiFilename)
- d = client.getPage("http://localhost:%d/cgi" % portnum)
- d.addCallback(self._testCGI_1)
- return d
-
-
- def _testCGI_1(self, res):
- self.assertEqual(res, "cgi output" + os.linesep)
-
-
- def test_protectedServerAndDate(self):
- """
- If the CGI script emits a I{Server} or I{Date} header, these are
- ignored.
- """
- cgiFilename = self.writeCGI(SPECIAL_HEADER_CGI)
-
- portnum = self.startServer(cgiFilename)
- url = "http://localhost:%d/cgi" % (portnum,)
- factory = client.HTTPClientFactory(url)
- reactor.connectTCP('localhost', portnum, factory)
- def checkResponse(ignored):
- self.assertNotIn('monkeys', factory.response_headers['server'])
- self.assertNotIn('last year', factory.response_headers['date'])
- factory.deferred.addCallback(checkResponse)
- return factory.deferred
-
-
- def test_noDuplicateContentTypeHeaders(self):
- """
- If the CGI script emits a I{content-type} header, make sure that the
- server doesn't add an additional (duplicate) one, as per ticket 4786.
- """
- cgiFilename = self.writeCGI(NO_DUPLICATE_CONTENT_TYPE_HEADER_CGI)
-
- portnum = self.startServer(cgiFilename)
- url = "http://localhost:%d/cgi" % (portnum,)
- factory = client.HTTPClientFactory(url)
- reactor.connectTCP('localhost', portnum, factory)
- def checkResponse(ignored):
- self.assertEqual(
- factory.response_headers['content-type'], ['text/cgi-duplicate-test'])
- factory.deferred.addCallback(checkResponse)
- return factory.deferred
-
-
- def test_duplicateHeaderCGI(self):
- """
- If a CGI script emits two instances of the same header, both are sent in
- the response.
- """
- cgiFilename = self.writeCGI(DUAL_HEADER_CGI)
-
- portnum = self.startServer(cgiFilename)
- url = "http://localhost:%d/cgi" % (portnum,)
- factory = client.HTTPClientFactory(url)
- reactor.connectTCP('localhost', portnum, factory)
- def checkResponse(ignored):
- self.assertEqual(
- factory.response_headers['header'], ['spam', 'eggs'])
- factory.deferred.addCallback(checkResponse)
- return factory.deferred
-
-
- def testReadEmptyInput(self):
- cgiFilename = os.path.abspath(self.mktemp())
- cgiFile = file(cgiFilename, 'wt')
- cgiFile.write(READINPUT_CGI)
- cgiFile.close()
-
- portnum = self.startServer(cgiFilename)
- d = client.getPage("http://localhost:%d/cgi" % portnum)
- d.addCallback(self._testReadEmptyInput_1)
- return d
- testReadEmptyInput.timeout = 5
- def _testReadEmptyInput_1(self, res):
- self.assertEqual(res, "readinput ok%s" % os.linesep)
-
- def testReadInput(self):
- cgiFilename = os.path.abspath(self.mktemp())
- cgiFile = file(cgiFilename, 'wt')
- cgiFile.write(READINPUT_CGI)
- cgiFile.close()
-
- portnum = self.startServer(cgiFilename)
- d = client.getPage("http://localhost:%d/cgi" % portnum,
- method="POST",
- postdata="Here is your stdin")
- d.addCallback(self._testReadInput_1)
- return d
- testReadInput.timeout = 5
- def _testReadInput_1(self, res):
- self.assertEqual(res, "readinput ok%s" % os.linesep)
-
-
- def testReadAllInput(self):
- cgiFilename = os.path.abspath(self.mktemp())
- cgiFile = file(cgiFilename, 'wt')
- cgiFile.write(READALLINPUT_CGI)
- cgiFile.close()
-
- portnum = self.startServer(cgiFilename)
- d = client.getPage("http://localhost:%d/cgi" % portnum,
- method="POST",
- postdata="Here is your stdin")
- d.addCallback(self._testReadAllInput_1)
- return d
- testReadAllInput.timeout = 5
- def _testReadAllInput_1(self, res):
- self.assertEqual(res, "readallinput ok%s" % os.linesep)
-
-
-
-class CGIDirectoryTests(unittest.TestCase):
- """
- Tests for L{twcgi.CGIDirectory}.
- """
- def test_render(self):
- """
- L{twcgi.CGIDirectory.render} sets the HTTP response code to I{NOT
- FOUND}.
- """
- resource = twcgi.CGIDirectory(self.mktemp())
- request = DummyRequest([''])
- d = _render(resource, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
-
-
- def test_notFoundChild(self):
- """
- L{twcgi.CGIDirectory.getChild} returns a resource which renders an
- response with the HTTP I{NOT FOUND} status code if the indicated child
- does not exist as an entry in the directory used to initialized the
- L{twcgi.CGIDirectory}.
- """
- path = self.mktemp()
- os.makedirs(path)
- resource = twcgi.CGIDirectory(path)
- request = DummyRequest(['foo'])
- child = resource.getChild("foo", request)
- d = _render(child, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
-
-
-
-class CGIProcessProtocolTests(unittest.TestCase):
- """
- Tests for L{twcgi.CGIProcessProtocol}.
- """
- def test_prematureEndOfHeaders(self):
- """
- If the process communicating with L{CGIProcessProtocol} ends before
- finishing writing out headers, the response has I{INTERNAL SERVER
- ERROR} as its status code.
- """
- request = DummyRequest([''])
- protocol = twcgi.CGIProcessProtocol(request)
- protocol.processEnded(failure.Failure(error.ProcessTerminated()))
- self.assertEqual(request.responseCode, INTERNAL_SERVER_ERROR)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_distrib.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_distrib.py
deleted file mode 100755
index c6e2ae30..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_distrib.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.distrib}.
-"""
-
-from os.path import abspath
-from xml.dom.minidom import parseString
-try:
- import pwd
-except ImportError:
- pwd = None
-
-from zope.interface.verify import verifyObject
-
-from twisted.python import log, filepath
-from twisted.internet import reactor, defer
-from twisted.trial import unittest
-from twisted.spread import pb
-from twisted.spread.banana import SIZE_LIMIT
-from twisted.web import http, distrib, client, resource, static, server
-from twisted.web.test.test_web import DummyRequest
-from twisted.web.test._util import _render
-from twisted.test import proto_helpers
-
-
-class MySite(server.Site):
- pass
-
-
-class PBServerFactory(pb.PBServerFactory):
- """
- A PB server factory which keeps track of the most recent protocol it
- created.
-
- @ivar proto: L{None} or the L{Broker} instance most recently returned
- from C{buildProtocol}.
- """
- proto = None
-
- def buildProtocol(self, addr):
- self.proto = pb.PBServerFactory.buildProtocol(self, addr)
- return self.proto
-
-
-
-class DistribTest(unittest.TestCase):
- port1 = None
- port2 = None
- sub = None
- f1 = None
-
- def tearDown(self):
- """
- Clean up all the event sources left behind by either directly by
- test methods or indirectly via some distrib API.
- """
- dl = [defer.Deferred(), defer.Deferred()]
- if self.f1 is not None and self.f1.proto is not None:
- self.f1.proto.notifyOnDisconnect(lambda: dl[0].callback(None))
- else:
- dl[0].callback(None)
- if self.sub is not None and self.sub.publisher is not None:
- self.sub.publisher.broker.notifyOnDisconnect(
- lambda: dl[1].callback(None))
- self.sub.publisher.broker.transport.loseConnection()
- else:
- dl[1].callback(None)
- if self.port1 is not None:
- dl.append(self.port1.stopListening())
- if self.port2 is not None:
- dl.append(self.port2.stopListening())
- return defer.gatherResults(dl)
-
-
- def testDistrib(self):
- # site1 is the publisher
- r1 = resource.Resource()
- r1.putChild("there", static.Data("root", "text/plain"))
- site1 = server.Site(r1)
- self.f1 = PBServerFactory(distrib.ResourcePublisher(site1))
- self.port1 = reactor.listenTCP(0, self.f1)
- self.sub = distrib.ResourceSubscription("127.0.0.1",
- self.port1.getHost().port)
- r2 = resource.Resource()
- r2.putChild("here", self.sub)
- f2 = MySite(r2)
- self.port2 = reactor.listenTCP(0, f2)
- d = client.getPage("http://127.0.0.1:%d/here/there" % \
- self.port2.getHost().port)
- d.addCallback(self.assertEqual, 'root')
- return d
-
-
- def _setupDistribServer(self, child):
- """
- Set up a resource on a distrib site using L{ResourcePublisher}.
-
- @param child: The resource to publish using distrib.
-
- @return: A tuple consisting of the host and port on which to contact
- the created site.
- """
- distribRoot = resource.Resource()
- distribRoot.putChild("child", child)
- distribSite = server.Site(distribRoot)
- self.f1 = distribFactory = PBServerFactory(
- distrib.ResourcePublisher(distribSite))
- distribPort = reactor.listenTCP(
- 0, distribFactory, interface="127.0.0.1")
- self.addCleanup(distribPort.stopListening)
- addr = distribPort.getHost()
-
- self.sub = mainRoot = distrib.ResourceSubscription(
- addr.host, addr.port)
- mainSite = server.Site(mainRoot)
- mainPort = reactor.listenTCP(0, mainSite, interface="127.0.0.1")
- self.addCleanup(mainPort.stopListening)
- mainAddr = mainPort.getHost()
-
- return mainPort, mainAddr
-
-
- def _requestTest(self, child, **kwargs):
- """
- Set up a resource on a distrib site using L{ResourcePublisher} and
- then retrieve it from a L{ResourceSubscription} via an HTTP client.
-
- @param child: The resource to publish using distrib.
- @param **kwargs: Extra keyword arguments to pass to L{getPage} when
- requesting the resource.
-
- @return: A L{Deferred} which fires with the result of the request.
- """
- mainPort, mainAddr = self._setupDistribServer(child)
- return client.getPage("http://%s:%s/child" % (
- mainAddr.host, mainAddr.port), **kwargs)
-
-
- def _requestAgentTest(self, child, **kwargs):
- """
- Set up a resource on a distrib site using L{ResourcePublisher} and
- then retrieve it from a L{ResourceSubscription} via an HTTP client.
-
- @param child: The resource to publish using distrib.
- @param **kwargs: Extra keyword arguments to pass to L{Agent.request} when
- requesting the resource.
-
- @return: A L{Deferred} which fires with a tuple consisting of a
- L{twisted.test.proto_helpers.AccumulatingProtocol} containing the
- body of the response and an L{IResponse} with the response itself.
- """
- mainPort, mainAddr = self._setupDistribServer(child)
-
- d = client.Agent(reactor).request("GET", "http://%s:%s/child" % (
- mainAddr.host, mainAddr.port), **kwargs)
-
- def cbCollectBody(response):
- protocol = proto_helpers.AccumulatingProtocol()
- response.deliverBody(protocol)
- d = protocol.closedDeferred = defer.Deferred()
- d.addCallback(lambda _: (protocol, response))
- return d
- d.addCallback(cbCollectBody)
- return d
-
-
- def test_requestHeaders(self):
- """
- The request headers are available on the request object passed to a
- distributed resource's C{render} method.
- """
- requestHeaders = {}
-
- class ReportRequestHeaders(resource.Resource):
- def render(self, request):
- requestHeaders.update(dict(
- request.requestHeaders.getAllRawHeaders()))
- return ""
-
- request = self._requestTest(
- ReportRequestHeaders(), headers={'foo': 'bar'})
- def cbRequested(result):
- self.assertEqual(requestHeaders['Foo'], ['bar'])
- request.addCallback(cbRequested)
- return request
-
-
- def test_requestResponseCode(self):
- """
- The response code can be set by the request object passed to a
- distributed resource's C{render} method.
- """
- class SetResponseCode(resource.Resource):
- def render(self, request):
- request.setResponseCode(200)
- return ""
-
- request = self._requestAgentTest(SetResponseCode())
- def cbRequested(result):
- self.assertEqual(result[0].data, "")
- self.assertEqual(result[1].code, 200)
- self.assertEqual(result[1].phrase, "OK")
- request.addCallback(cbRequested)
- return request
-
-
- def test_requestResponseCodeMessage(self):
- """
- The response code and message can be set by the request object passed to
- a distributed resource's C{render} method.
- """
- class SetResponseCode(resource.Resource):
- def render(self, request):
- request.setResponseCode(200, "some-message")
- return ""
-
- request = self._requestAgentTest(SetResponseCode())
- def cbRequested(result):
- self.assertEqual(result[0].data, "")
- self.assertEqual(result[1].code, 200)
- self.assertEqual(result[1].phrase, "some-message")
- request.addCallback(cbRequested)
- return request
-
-
- def test_largeWrite(self):
- """
- If a string longer than the Banana size limit is passed to the
- L{distrib.Request} passed to the remote resource, it is broken into
- smaller strings to be transported over the PB connection.
- """
- class LargeWrite(resource.Resource):
- def render(self, request):
- request.write('x' * SIZE_LIMIT + 'y')
- request.finish()
- return server.NOT_DONE_YET
-
- request = self._requestTest(LargeWrite())
- request.addCallback(self.assertEqual, 'x' * SIZE_LIMIT + 'y')
- return request
-
-
- def test_largeReturn(self):
- """
- Like L{test_largeWrite}, but for the case where C{render} returns a
- long string rather than explicitly passing it to L{Request.write}.
- """
- class LargeReturn(resource.Resource):
- def render(self, request):
- return 'x' * SIZE_LIMIT + 'y'
-
- request = self._requestTest(LargeReturn())
- request.addCallback(self.assertEqual, 'x' * SIZE_LIMIT + 'y')
- return request
-
-
- def test_connectionLost(self):
- """
- If there is an error issuing the request to the remote publisher, an
- error response is returned.
- """
- # Using pb.Root as a publisher will cause request calls to fail with an
- # error every time. Just what we want to test.
- self.f1 = serverFactory = PBServerFactory(pb.Root())
- self.port1 = serverPort = reactor.listenTCP(0, serverFactory)
-
- self.sub = subscription = distrib.ResourceSubscription(
- "127.0.0.1", serverPort.getHost().port)
- request = DummyRequest([''])
- d = _render(subscription, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, 500)
- # This is the error we caused the request to fail with. It should
- # have been logged.
- self.assertEqual(len(self.flushLoggedErrors(pb.NoSuchMethod)), 1)
- d.addCallback(cbRendered)
- return d
-
-
-
-class _PasswordDatabase:
- def __init__(self, users):
- self._users = users
-
-
- def getpwall(self):
- return iter(self._users)
-
-
- def getpwnam(self, username):
- for user in self._users:
- if user[0] == username:
- return user
- raise KeyError()
-
-
-
-class UserDirectoryTests(unittest.TestCase):
- """
- Tests for L{UserDirectory}, a resource for listing all user resources
- available on a system.
- """
- def setUp(self):
- self.alice = ('alice', 'x', 123, 456, 'Alice,,,', self.mktemp(), '/bin/sh')
- self.bob = ('bob', 'x', 234, 567, 'Bob,,,', self.mktemp(), '/bin/sh')
- self.database = _PasswordDatabase([self.alice, self.bob])
- self.directory = distrib.UserDirectory(self.database)
-
-
- def test_interface(self):
- """
- L{UserDirectory} instances provide L{resource.IResource}.
- """
- self.assertTrue(verifyObject(resource.IResource, self.directory))
-
-
- def _404Test(self, name):
- """
- Verify that requesting the C{name} child of C{self.directory} results
- in a 404 response.
- """
- request = DummyRequest([name])
- result = self.directory.getChild(name, request)
- d = _render(result, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, 404)
- d.addCallback(cbRendered)
- return d
-
-
- def test_getInvalidUser(self):
- """
- L{UserDirectory.getChild} returns a resource which renders a 404
- response when passed a string which does not correspond to any known
- user.
- """
- return self._404Test('carol')
-
-
- def test_getUserWithoutResource(self):
- """
- L{UserDirectory.getChild} returns a resource which renders a 404
- response when passed a string which corresponds to a known user who has
- neither a user directory nor a user distrib socket.
- """
- return self._404Test('alice')
-
-
- def test_getPublicHTMLChild(self):
- """
- L{UserDirectory.getChild} returns a L{static.File} instance when passed
- the name of a user with a home directory containing a I{public_html}
- directory.
- """
- home = filepath.FilePath(self.bob[-2])
- public_html = home.child('public_html')
- public_html.makedirs()
- request = DummyRequest(['bob'])
- result = self.directory.getChild('bob', request)
- self.assertIsInstance(result, static.File)
- self.assertEqual(result.path, public_html.path)
-
-
- def test_getDistribChild(self):
- """
- L{UserDirectory.getChild} returns a L{ResourceSubscription} instance
- when passed the name of a user suffixed with C{".twistd"} who has a
- home directory containing a I{.twistd-web-pb} socket.
- """
- home = filepath.FilePath(self.bob[-2])
- home.makedirs()
- web = home.child('.twistd-web-pb')
- request = DummyRequest(['bob'])
- result = self.directory.getChild('bob.twistd', request)
- self.assertIsInstance(result, distrib.ResourceSubscription)
- self.assertEqual(result.host, 'unix')
- self.assertEqual(abspath(result.port), web.path)
-
-
- def test_invalidMethod(self):
- """
- L{UserDirectory.render} raises L{UnsupportedMethod} in response to a
- non-I{GET} request.
- """
- request = DummyRequest([''])
- request.method = 'POST'
- self.assertRaises(
- server.UnsupportedMethod, self.directory.render, request)
-
-
- def test_render(self):
- """
- L{UserDirectory} renders a list of links to available user content
- in response to a I{GET} request.
- """
- public_html = filepath.FilePath(self.alice[-2]).child('public_html')
- public_html.makedirs()
- web = filepath.FilePath(self.bob[-2])
- web.makedirs()
- # This really only works if it's a unix socket, but the implementation
- # doesn't currently check for that. It probably should someday, and
- # then skip users with non-sockets.
- web.child('.twistd-web-pb').setContent("")
-
- request = DummyRequest([''])
- result = _render(self.directory, request)
- def cbRendered(ignored):
- document = parseString(''.join(request.written))
-
- # Each user should have an li with a link to their page.
- [alice, bob] = document.getElementsByTagName('li')
- self.assertEqual(alice.firstChild.tagName, 'a')
- self.assertEqual(alice.firstChild.getAttribute('href'), 'alice/')
- self.assertEqual(alice.firstChild.firstChild.data, 'Alice (file)')
- self.assertEqual(bob.firstChild.tagName, 'a')
- self.assertEqual(bob.firstChild.getAttribute('href'), 'bob.twistd/')
- self.assertEqual(bob.firstChild.firstChild.data, 'Bob (twistd)')
-
- result.addCallback(cbRendered)
- return result
-
-
- def test_passwordDatabase(self):
- """
- If L{UserDirectory} is instantiated with no arguments, it uses the
- L{pwd} module as its password database.
- """
- directory = distrib.UserDirectory()
- self.assertIdentical(directory._pwd, pwd)
- if pwd is None:
- test_passwordDatabase.skip = "pwd module required"
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_domhelpers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_domhelpers.py
deleted file mode 100755
index b0083746..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_domhelpers.py
+++ /dev/null
@@ -1,306 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_domhelpers -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Specific tests for (some of) the methods in L{twisted.web.domhelpers}.
-"""
-
-from xml.dom import minidom
-
-from twisted.trial.unittest import TestCase
-
-from twisted.web import microdom
-
-from twisted.web import domhelpers
-
-
-class DOMHelpersTestsMixin:
- """
- A mixin for L{TestCase} subclasses which defines test methods for
- domhelpers functionality based on a DOM creation function provided by a
- subclass.
- """
- dom = None
-
- def test_getElementsByTagName(self):
- doc1 = self.dom.parseString('<foo/>')
- actual=domhelpers.getElementsByTagName(doc1, 'foo')[0].nodeName
- expected='foo'
- self.assertEqual(actual, expected)
- el1=doc1.documentElement
- actual=domhelpers.getElementsByTagName(el1, 'foo')[0].nodeName
- self.assertEqual(actual, expected)
-
- doc2_xml='<a><foo in="a"/><b><foo in="b"/></b><c><foo in="c"/></c><foo in="d"/><foo in="ef"/><g><foo in="g"/><h><foo in="h"/></h></g></a>'
- doc2 = self.dom.parseString(doc2_xml)
- tag_list=domhelpers.getElementsByTagName(doc2, 'foo')
- actual=''.join([node.getAttribute('in') for node in tag_list])
- expected='abcdefgh'
- self.assertEqual(actual, expected)
- el2=doc2.documentElement
- tag_list=domhelpers.getElementsByTagName(el2, 'foo')
- actual=''.join([node.getAttribute('in') for node in tag_list])
- self.assertEqual(actual, expected)
-
- doc3_xml='''
-<a><foo in="a"/>
- <b><foo in="b"/>
- <d><foo in="d"/>
- <g><foo in="g"/></g>
- <h><foo in="h"/></h>
- </d>
- <e><foo in="e"/>
- <i><foo in="i"/></i>
- </e>
- </b>
- <c><foo in="c"/>
- <f><foo in="f"/>
- <j><foo in="j"/></j>
- </f>
- </c>
-</a>'''
- doc3 = self.dom.parseString(doc3_xml)
- tag_list=domhelpers.getElementsByTagName(doc3, 'foo')
- actual=''.join([node.getAttribute('in') for node in tag_list])
- expected='abdgheicfj'
- self.assertEqual(actual, expected)
- el3=doc3.documentElement
- tag_list=domhelpers.getElementsByTagName(el3, 'foo')
- actual=''.join([node.getAttribute('in') for node in tag_list])
- self.assertEqual(actual, expected)
-
- doc4_xml='<foo><bar></bar><baz><foo/></baz></foo>'
- doc4 = self.dom.parseString(doc4_xml)
- actual=domhelpers.getElementsByTagName(doc4, 'foo')
- root=doc4.documentElement
- expected=[root, root.childNodes[-1].childNodes[0]]
- self.assertEqual(actual, expected)
- actual=domhelpers.getElementsByTagName(root, 'foo')
- self.assertEqual(actual, expected)
-
-
- def test_gatherTextNodes(self):
- doc1 = self.dom.parseString('<a>foo</a>')
- actual=domhelpers.gatherTextNodes(doc1)
- expected='foo'
- self.assertEqual(actual, expected)
- actual=domhelpers.gatherTextNodes(doc1.documentElement)
- self.assertEqual(actual, expected)
-
- doc2_xml='<a>a<b>b</b><c>c</c>def<g>g<h>h</h></g></a>'
- doc2 = self.dom.parseString(doc2_xml)
- actual=domhelpers.gatherTextNodes(doc2)
- expected='abcdefgh'
- self.assertEqual(actual, expected)
- actual=domhelpers.gatherTextNodes(doc2.documentElement)
- self.assertEqual(actual, expected)
-
- doc3_xml=('<a>a<b>b<d>d<g>g</g><h>h</h></d><e>e<i>i</i></e></b>' +
- '<c>c<f>f<j>j</j></f></c></a>')
- doc3 = self.dom.parseString(doc3_xml)
- actual=domhelpers.gatherTextNodes(doc3)
- expected='abdgheicfj'
- self.assertEqual(actual, expected)
- actual=domhelpers.gatherTextNodes(doc3.documentElement)
- self.assertEqual(actual, expected)
-
- def test_clearNode(self):
- doc1 = self.dom.parseString('<a><b><c><d/></c></b></a>')
- a_node=doc1.documentElement
- domhelpers.clearNode(a_node)
- self.assertEqual(
- a_node.toxml(),
- self.dom.Element('a').toxml())
-
- doc2 = self.dom.parseString('<a><b><c><d/></c></b></a>')
- b_node=doc2.documentElement.childNodes[0]
- domhelpers.clearNode(b_node)
- actual=doc2.documentElement.toxml()
- expected = self.dom.Element('a')
- expected.appendChild(self.dom.Element('b'))
- self.assertEqual(actual, expected.toxml())
-
-
- def test_get(self):
- doc1 = self.dom.parseString('<a><b id="bar"/><c class="foo"/></a>')
- node=domhelpers.get(doc1, "foo")
- actual=node.toxml()
- expected = self.dom.Element('c')
- expected.setAttribute('class', 'foo')
- self.assertEqual(actual, expected.toxml())
-
- node=domhelpers.get(doc1, "bar")
- actual=node.toxml()
- expected = self.dom.Element('b')
- expected.setAttribute('id', 'bar')
- self.assertEqual(actual, expected.toxml())
-
- self.assertRaises(domhelpers.NodeLookupError,
- domhelpers.get,
- doc1,
- "pzork")
-
- def test_getIfExists(self):
- doc1 = self.dom.parseString('<a><b id="bar"/><c class="foo"/></a>')
- node=domhelpers.getIfExists(doc1, "foo")
- actual=node.toxml()
- expected = self.dom.Element('c')
- expected.setAttribute('class', 'foo')
- self.assertEqual(actual, expected.toxml())
-
- node=domhelpers.getIfExists(doc1, "pzork")
- self.assertIdentical(node, None)
-
-
- def test_getAndClear(self):
- doc1 = self.dom.parseString('<a><b id="foo"><c></c></b></a>')
- node=domhelpers.getAndClear(doc1, "foo")
- actual=node.toxml()
- expected = self.dom.Element('b')
- expected.setAttribute('id', 'foo')
- self.assertEqual(actual, expected.toxml())
-
-
- def test_locateNodes(self):
- doc1 = self.dom.parseString('<a><b foo="olive"><c foo="olive"/></b><d foo="poopy"/></a>')
- node_list=domhelpers.locateNodes(
- doc1.childNodes, 'foo', 'olive', noNesting=1)
- actual=''.join([node.toxml() for node in node_list])
- expected = self.dom.Element('b')
- expected.setAttribute('foo', 'olive')
- c = self.dom.Element('c')
- c.setAttribute('foo', 'olive')
- expected.appendChild(c)
-
- self.assertEqual(actual, expected.toxml())
-
- node_list=domhelpers.locateNodes(
- doc1.childNodes, 'foo', 'olive', noNesting=0)
- actual=''.join([node.toxml() for node in node_list])
- self.assertEqual(actual, expected.toxml() + c.toxml())
-
-
- def test_getParents(self):
- doc1 = self.dom.parseString('<a><b><c><d/></c><e/></b><f/></a>')
- node_list = domhelpers.getParents(
- doc1.childNodes[0].childNodes[0].childNodes[0])
- actual = ''.join([node.tagName for node in node_list
- if hasattr(node, 'tagName')])
- self.assertEqual(actual, 'cba')
-
-
- def test_findElementsWithAttribute(self):
- doc1 = self.dom.parseString('<a foo="1"><b foo="2"/><c foo="1"/><d/></a>')
- node_list = domhelpers.findElementsWithAttribute(doc1, 'foo')
- actual = ''.join([node.tagName for node in node_list])
- self.assertEqual(actual, 'abc')
-
- node_list = domhelpers.findElementsWithAttribute(doc1, 'foo', '1')
- actual = ''.join([node.tagName for node in node_list])
- self.assertEqual(actual, 'ac')
-
-
- def test_findNodesNamed(self):
- doc1 = self.dom.parseString('<doc><foo/><bar/><foo>a</foo></doc>')
- node_list = domhelpers.findNodesNamed(doc1, 'foo')
- actual = len(node_list)
- self.assertEqual(actual, 2)
-
- # NOT SURE WHAT THESE ARE SUPPOSED TO DO..
- # def test_RawText FIXME
- # def test_superSetAttribute FIXME
- # def test_superPrependAttribute FIXME
- # def test_superAppendAttribute FIXME
- # def test_substitute FIXME
-
- def test_escape(self):
- j='this string " contains many & characters> xml< won\'t like'
- expected='this string &quot; contains many &amp; characters&gt; xml&lt; won\'t like'
- self.assertEqual(domhelpers.escape(j), expected)
-
- def test_unescape(self):
- j='this string &quot; has &&amp; entities &gt; &lt; and some characters xml won\'t like<'
- expected='this string " has && entities > < and some characters xml won\'t like<'
- self.assertEqual(domhelpers.unescape(j), expected)
-
-
- def test_getNodeText(self):
- """
- L{getNodeText} returns the concatenation of all the text data at or
- beneath the node passed to it.
- """
- node = self.dom.parseString('<foo><bar>baz</bar><bar>quux</bar></foo>')
- self.assertEqual(domhelpers.getNodeText(node), "bazquux")
-
-
-
-class MicroDOMHelpersTests(DOMHelpersTestsMixin, TestCase):
- dom = microdom
-
- def test_gatherTextNodesDropsWhitespace(self):
- """
- Microdom discards whitespace-only text nodes, so L{gatherTextNodes}
- returns only the text from nodes which had non-whitespace characters.
- """
- doc4_xml='''<html>
- <head>
- </head>
- <body>
- stuff
- </body>
-</html>
-'''
- doc4 = self.dom.parseString(doc4_xml)
- actual = domhelpers.gatherTextNodes(doc4)
- expected = '\n stuff\n '
- self.assertEqual(actual, expected)
- actual = domhelpers.gatherTextNodes(doc4.documentElement)
- self.assertEqual(actual, expected)
-
-
- def test_textEntitiesNotDecoded(self):
- """
- Microdom does not decode entities in text nodes.
- """
- doc5_xml='<x>Souffl&amp;</x>'
- doc5 = self.dom.parseString(doc5_xml)
- actual=domhelpers.gatherTextNodes(doc5)
- expected='Souffl&amp;'
- self.assertEqual(actual, expected)
- actual=domhelpers.gatherTextNodes(doc5.documentElement)
- self.assertEqual(actual, expected)
-
-
-
-class MiniDOMHelpersTests(DOMHelpersTestsMixin, TestCase):
- dom = minidom
-
- def test_textEntitiesDecoded(self):
- """
- Minidom does decode entities in text nodes.
- """
- doc5_xml='<x>Souffl&amp;</x>'
- doc5 = self.dom.parseString(doc5_xml)
- actual=domhelpers.gatherTextNodes(doc5)
- expected='Souffl&'
- self.assertEqual(actual, expected)
- actual=domhelpers.gatherTextNodes(doc5.documentElement)
- self.assertEqual(actual, expected)
-
-
- def test_getNodeUnicodeText(self):
- """
- L{domhelpers.getNodeText} returns a C{unicode} string when text
- nodes are represented in the DOM with unicode, whether or not there
- are non-ASCII characters present.
- """
- node = self.dom.parseString("<foo>bar</foo>")
- text = domhelpers.getNodeText(node)
- self.assertEqual(text, u"bar")
- self.assertIsInstance(text, unicode)
-
- node = self.dom.parseString(u"<foo>\N{SNOWMAN}</foo>".encode('utf-8'))
- text = domhelpers.getNodeText(node)
- self.assertEqual(text, u"\N{SNOWMAN}")
- self.assertIsInstance(text, unicode)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_error.py
deleted file mode 100755
index 4daa7d90..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_error.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-HTTP errors.
-"""
-
-from twisted.trial import unittest
-from twisted.web import error
-
-class ErrorTestCase(unittest.TestCase):
- """
- Tests for how L{Error} attributes are initialized.
- """
- def test_noMessageValidStatus(self):
- """
- If no C{message} argument is passed to the L{Error} constructor and the
- C{code} argument is a valid HTTP status code, C{code} is mapped to a
- descriptive string to which C{message} is assigned.
- """
- e = error.Error("200")
- self.assertEqual(e.message, "OK")
-
-
- def test_noMessageInvalidStatus(self):
- """
- If no C{message} argument is passed to the L{Error} constructor and
- C{code} isn't a valid HTTP status code, C{message} stays C{None}.
- """
- e = error.Error("InvalidCode")
- self.assertEqual(e.message, None)
-
-
- def test_messageExists(self):
- """
- If a C{message} argument is passed to the L{Error} constructor, the
- C{message} isn't affected by the value of C{status}.
- """
- e = error.Error("200", "My own message")
- self.assertEqual(e.message, "My own message")
-
-
-
-class PageRedirectTestCase(unittest.TestCase):
- """
- Tests for how L{PageRedirect} attributes are initialized.
- """
- def test_noMessageValidStatus(self):
- """
- If no C{message} argument is passed to the L{PageRedirect} constructor
- and the C{code} argument is a valid HTTP status code, C{code} is mapped
- to a descriptive string to which C{message} is assigned.
- """
- e = error.PageRedirect("200", location="/foo")
- self.assertEqual(e.message, "OK to /foo")
-
-
- def test_noMessageValidStatusNoLocation(self):
- """
- If no C{message} argument is passed to the L{PageRedirect} constructor
- and C{location} is also empty and the C{code} argument is a valid HTTP
- status code, C{code} is mapped to a descriptive string to which
- C{message} is assigned without trying to include an empty location.
- """
- e = error.PageRedirect("200")
- self.assertEqual(e.message, "OK")
-
-
- def test_noMessageInvalidStatusLocationExists(self):
- """
- If no C{message} argument is passed to the L{PageRedirect} constructor
- and C{code} isn't a valid HTTP status code, C{message} stays C{None}.
- """
- e = error.PageRedirect("InvalidCode", location="/foo")
- self.assertEqual(e.message, None)
-
-
- def test_messageExistsLocationExists(self):
- """
- If a C{message} argument is passed to the L{PageRedirect} constructor,
- the C{message} isn't affected by the value of C{status}.
- """
- e = error.PageRedirect("200", "My own message", location="/foo")
- self.assertEqual(e.message, "My own message to /foo")
-
-
- def test_messageExistsNoLocation(self):
- """
- If a C{message} argument is passed to the L{PageRedirect} constructor
- and no location is provided, C{message} doesn't try to include the empty
- location.
- """
- e = error.PageRedirect("200", "My own message")
- self.assertEqual(e.message, "My own message")
-
-
-
-class InfiniteRedirectionTestCase(unittest.TestCase):
- """
- Tests for how L{InfiniteRedirection} attributes are initialized.
- """
- def test_noMessageValidStatus(self):
- """
- If no C{message} argument is passed to the L{InfiniteRedirection}
- constructor and the C{code} argument is a valid HTTP status code,
- C{code} is mapped to a descriptive string to which C{message} is
- assigned.
- """
- e = error.InfiniteRedirection("200", location="/foo")
- self.assertEqual(e.message, "OK to /foo")
-
-
- def test_noMessageValidStatusNoLocation(self):
- """
- If no C{message} argument is passed to the L{InfiniteRedirection}
- constructor and C{location} is also empty and the C{code} argument is a
- valid HTTP status code, C{code} is mapped to a descriptive string to
- which C{message} is assigned without trying to include an empty
- location.
- """
- e = error.InfiniteRedirection("200")
- self.assertEqual(e.message, "OK")
-
-
- def test_noMessageInvalidStatusLocationExists(self):
- """
- If no C{message} argument is passed to the L{InfiniteRedirection}
- constructor and C{code} isn't a valid HTTP status code, C{message} stays
- C{None}.
- """
- e = error.InfiniteRedirection("InvalidCode", location="/foo")
- self.assertEqual(e.message, None)
-
-
- def test_messageExistsLocationExists(self):
- """
- If a C{message} argument is passed to the L{InfiniteRedirection}
- constructor, the C{message} isn't affected by the value of C{status}.
- """
- e = error.InfiniteRedirection("200", "My own message", location="/foo")
- self.assertEqual(e.message, "My own message to /foo")
-
-
- def test_messageExistsNoLocation(self):
- """
- If a C{message} argument is passed to the L{InfiniteRedirection}
- constructor and no location is provided, C{message} doesn't try to
- include the empty location.
- """
- e = error.InfiniteRedirection("200", "My own message")
- self.assertEqual(e.message, "My own message")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_flatten.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_flatten.py
deleted file mode 100755
index c843a613..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_flatten.py
+++ /dev/null
@@ -1,348 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys
-import traceback
-
-from zope.interface import implements
-
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import succeed, gatherResults
-from twisted.web._stan import Tag
-from twisted.web._flatten import flattenString
-from twisted.web.error import UnfilledSlot, UnsupportedType, FlattenerError
-from twisted.web.template import tags, Comment, CDATA, CharRef, slot
-from twisted.web.iweb import IRenderable
-from twisted.web.test._util import FlattenTestCase
-
-
-class TestSerialization(FlattenTestCase):
- """
- Tests for flattening various things.
- """
- def test_nestedTags(self):
- """
- Test that nested tags flatten correctly.
- """
- return self.assertFlattensTo(
- tags.html(tags.body('42'), hi='there'),
- '<html hi="there"><body>42</body></html>')
-
-
- def test_serializeString(self):
- """
- Test that strings will be flattened and escaped correctly.
- """
- return gatherResults([
- self.assertFlattensTo('one', 'one'),
- self.assertFlattensTo('<abc&&>123', '&lt;abc&amp;&amp;&gt;123'),
- ])
-
-
- def test_serializeSelfClosingTags(self):
- """
- Test that some tags are normally written out as self-closing tags.
- """
- return self.assertFlattensTo(tags.img(src='test'), '<img src="test" />')
-
-
- def test_serializeComment(self):
- """
- Test that comments are correctly flattened and escaped.
- """
- return self.assertFlattensTo(Comment('foo bar'), '<!--foo bar-->'),
-
-
- def test_commentEscaping(self):
- """
- The data in a L{Comment} is escaped and mangled in the flattened output
- so that the result is a legal SGML and XML comment.
-
- SGML comment syntax is complicated and hard to use. This rule is more
- restrictive, and more compatible:
-
- Comments start with <!-- and end with --> and never contain -- or >.
-
- Also by XML syntax, a comment may not end with '-'.
-
- @see: U{http://www.w3.org/TR/REC-xml/#sec-comments}
- """
- def verifyComment(c):
- self.assertTrue(
- c.startswith('<!--'),
- "%r does not start with the comment prefix" % (c,))
- self.assertTrue(
- c.endswith('-->'),
- "%r does not end with the comment suffix" % (c,))
- # If it is shorter than 7, then the prefix and suffix overlap
- # illegally.
- self.assertTrue(
- len(c) >= 7,
- "%r is too short to be a legal comment" % (c,))
- content = c[4:-3]
- self.assertNotIn('--', content)
- self.assertNotIn('>', content)
- if content:
- self.assertNotEqual(content[-1], '-')
-
- results = []
- for c in [
- '',
- 'foo---bar',
- 'foo---bar-',
- 'foo>bar',
- 'foo-->bar',
- '----------------',
- ]:
- d = flattenString(None, Comment(c))
- d.addCallback(verifyComment)
- results.append(d)
- return gatherResults(results)
-
-
- def test_serializeCDATA(self):
- """
- Test that CDATA is correctly flattened and escaped.
- """
- return gatherResults([
- self.assertFlattensTo(CDATA('foo bar'), '<![CDATA[foo bar]]>'),
- self.assertFlattensTo(
- CDATA('foo ]]> bar'),
- '<![CDATA[foo ]]]]><![CDATA[> bar]]>'),
- ])
-
-
- def test_serializeUnicode(self):
- """
- Test that unicode is encoded correctly in the appropriate places, and
- raises an error when it occurs in inappropriate place.
- """
- snowman = u'\N{SNOWMAN}'
- return gatherResults([
- self.assertFlattensTo(snowman, '\xe2\x98\x83'),
- self.assertFlattensTo(tags.p(snowman), '<p>\xe2\x98\x83</p>'),
- self.assertFlattensTo(Comment(snowman), '<!--\xe2\x98\x83-->'),
- self.assertFlattensTo(CDATA(snowman), '<![CDATA[\xe2\x98\x83]]>'),
- self.assertFlatteningRaises(
- Tag(snowman), UnicodeEncodeError),
- self.assertFlatteningRaises(
- Tag('p', attributes={snowman: ''}), UnicodeEncodeError),
- ])
-
-
- def test_serializeCharRef(self):
- """
- A character reference is flattened to a string using the I{&#NNNN;}
- syntax.
- """
- ref = CharRef(ord(u"\N{SNOWMAN}"))
- return self.assertFlattensTo(ref, "&#9731;")
-
-
- def test_serializeDeferred(self):
- """
- Test that a deferred is substituted with the current value in the
- callback chain when flattened.
- """
- return self.assertFlattensTo(succeed('two'), 'two')
-
-
- def test_serializeSameDeferredTwice(self):
- """
- Test that the same deferred can be flattened twice.
- """
- d = succeed('three')
- return gatherResults([
- self.assertFlattensTo(d, 'three'),
- self.assertFlattensTo(d, 'three'),
- ])
-
-
- def test_serializeIRenderable(self):
- """
- Test that flattening respects all of the IRenderable interface.
- """
- class FakeElement(object):
- implements(IRenderable)
- def render(ign,ored):
- return tags.p(
- 'hello, ',
- tags.transparent(render='test'), ' - ',
- tags.transparent(render='test'))
- def lookupRenderMethod(ign, name):
- self.assertEqual(name, 'test')
- return lambda ign, node: node('world')
-
- return gatherResults([
- self.assertFlattensTo(FakeElement(), '<p>hello, world - world</p>'),
- ])
-
-
- def test_serializeSlots(self):
- """
- Test that flattening a slot will use the slot value from the tag.
- """
- t1 = tags.p(slot('test'))
- t2 = t1.clone()
- t2.fillSlots(test='hello, world')
- return gatherResults([
- self.assertFlatteningRaises(t1, UnfilledSlot),
- self.assertFlattensTo(t2, '<p>hello, world</p>'),
- ])
-
-
- def test_serializeDeferredSlots(self):
- """
- Test that a slot with a deferred as its value will be flattened using
- the value from the deferred.
- """
- t = tags.p(slot('test'))
- t.fillSlots(test=succeed(tags.em('four>')))
- return self.assertFlattensTo(t, '<p><em>four&gt;</em></p>')
-
-
- def test_unknownTypeRaises(self):
- """
- Test that flattening an unknown type of thing raises an exception.
- """
- return self.assertFlatteningRaises(None, UnsupportedType)
-
-
-# Use the co_filename mechanism (instead of the __file__ mechanism) because
-# it is the mechanism traceback formatting uses. The two do not necessarily
-# agree with each other. This requires a code object compiled in this file.
-# The easiest way to get a code object is with a new function. I'll use a
-# lambda to avoid adding anything else to this namespace. The result will
-# be a string which agrees with the one the traceback module will put into a
-# traceback for frames associated with functions defined in this file.
-
-HERE = (lambda: None).func_code.co_filename
-
-
-class FlattenerErrorTests(TestCase):
- """
- Tests for L{FlattenerError}.
- """
-
- def test_string(self):
- """
- If a L{FlattenerError} is created with a string root, up to around 40
- bytes from that string are included in the string representation of the
- exception.
- """
- self.assertEqual(
- str(FlattenerError(RuntimeError("reason"), ['abc123xyz'], [])),
- "Exception while flattening:\n"
- " 'abc123xyz'\n"
- "RuntimeError: reason\n")
- self.assertEqual(
- str(FlattenerError(
- RuntimeError("reason"), ['0123456789' * 10], [])),
- "Exception while flattening:\n"
- " '01234567890123456789<...>01234567890123456789'\n"
- "RuntimeError: reason\n")
-
-
- def test_unicode(self):
- """
- If a L{FlattenerError} is created with a unicode root, up to around 40
- characters from that string are included in the string representation
- of the exception.
- """
- self.assertEqual(
- str(FlattenerError(
- RuntimeError("reason"), [u'abc\N{SNOWMAN}xyz'], [])),
- "Exception while flattening:\n"
- " u'abc\\u2603xyz'\n" # Codepoint for SNOWMAN
- "RuntimeError: reason\n")
- self.assertEqual(
- str(FlattenerError(
- RuntimeError("reason"), [u'01234567\N{SNOWMAN}9' * 10],
- [])),
- "Exception while flattening:\n"
- " u'01234567\\u2603901234567\\u26039<...>01234567\\u2603901234567"
- "\\u26039'\n"
- "RuntimeError: reason\n")
-
-
- def test_renderable(self):
- """
- If a L{FlattenerError} is created with an L{IRenderable} provider root,
- the repr of that object is included in the string representation of the
- exception.
- """
- class Renderable(object):
- implements(IRenderable)
-
- def __repr__(self):
- return "renderable repr"
-
- self.assertEqual(
- str(FlattenerError(
- RuntimeError("reason"), [Renderable()], [])),
- "Exception while flattening:\n"
- " renderable repr\n"
- "RuntimeError: reason\n")
-
-
- def test_tag(self):
- """
- If a L{FlattenerError} is created with a L{Tag} instance with source
- location information, the source location is included in the string
- representation of the exception.
- """
- tag = Tag(
- 'div', filename='/foo/filename.xhtml', lineNumber=17, columnNumber=12)
-
- self.assertEqual(
- str(FlattenerError(RuntimeError("reason"), [tag], [])),
- "Exception while flattening:\n"
- " File \"/foo/filename.xhtml\", line 17, column 12, in \"div\"\n"
- "RuntimeError: reason\n")
-
-
- def test_tagWithoutLocation(self):
- """
- If a L{FlattenerError} is created with a L{Tag} instance without source
- location information, only the tagName is included in the string
- representation of the exception.
- """
- self.assertEqual(
- str(FlattenerError(RuntimeError("reason"), [Tag('span')], [])),
- "Exception while flattening:\n"
- " Tag <span>\n"
- "RuntimeError: reason\n")
-
-
- def test_traceback(self):
- """
- If a L{FlattenerError} is created with traceback frames, they are
- included in the string representation of the exception.
- """
- # Try to be realistic in creating the data passed in for the traceback
- # frames.
- def f():
- g()
- def g():
- raise RuntimeError("reason")
-
- try:
- f()
- except RuntimeError, exc:
- # Get the traceback, minus the info for *this* frame
- tbinfo = traceback.extract_tb(sys.exc_info()[2])[1:]
- else:
- self.fail("f() must raise RuntimeError")
-
- self.assertEqual(
- str(FlattenerError(exc, [], tbinfo)),
- "Exception while flattening:\n"
- " File \"%s\", line %d, in f\n"
- " g()\n"
- " File \"%s\", line %d, in g\n"
- " raise RuntimeError(\"reason\")\n"
- "RuntimeError: reason\n" % (
- HERE, f.func_code.co_firstlineno + 1,
- HERE, g.func_code.co_firstlineno + 1))
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http.py
deleted file mode 100755
index 959acfa5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http.py
+++ /dev/null
@@ -1,1663 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test HTTP support.
-"""
-
-from urlparse import urlparse, urlunsplit, clear_cache
-import random, urllib, cgi
-
-from twisted.python.compat import set
-from twisted.python.failure import Failure
-from twisted.trial import unittest
-from twisted.trial.unittest import TestCase
-from twisted.web import http, http_headers
-from twisted.web.http import PotentialDataLoss, _DataLoss
-from twisted.web.http import _IdentityTransferDecoder
-from twisted.protocols import loopback
-from twisted.internet.task import Clock
-from twisted.internet.error import ConnectionLost
-from twisted.test.proto_helpers import StringTransport
-from twisted.test.test_internet import DummyProducer
-from twisted.web.test.test_web import DummyChannel
-
-
-class DateTimeTest(unittest.TestCase):
- """Test date parsing functions."""
-
- def testRoundtrip(self):
- for i in range(10000):
- time = random.randint(0, 2000000000)
- timestr = http.datetimeToString(time)
- time2 = http.stringToDatetime(timestr)
- self.assertEqual(time, time2)
-
-
-class DummyHTTPHandler(http.Request):
-
- def process(self):
- self.content.seek(0, 0)
- data = self.content.read()
- length = self.getHeader('content-length')
- request = "'''\n"+str(length)+"\n"+data+"'''\n"
- self.setResponseCode(200)
- self.setHeader("Request", self.uri)
- self.setHeader("Command", self.method)
- self.setHeader("Version", self.clientproto)
- self.setHeader("Content-Length", len(request))
- self.write(request)
- self.finish()
-
-
-class LoopbackHTTPClient(http.HTTPClient):
-
- def connectionMade(self):
- self.sendCommand("GET", "/foo/bar")
- self.sendHeader("Content-Length", 10)
- self.endHeaders()
- self.transport.write("0123456789")
-
-
-class ResponseTestMixin(object):
- """
- A mixin that provides a simple means of comparing an actual response string
- to an expected response string by performing the minimal parsing.
- """
-
- def assertResponseEquals(self, responses, expected):
- """
- Assert that the C{responses} matches the C{expected} responses.
-
- @type responses: C{str}
- @param responses: The bytes sent in response to one or more requests.
-
- @type expected: C{list} of C{tuple} of C{str}
- @param expected: The expected values for the responses. Each tuple
- element of the list represents one response. Each string element
- of the tuple is a full header line without delimiter, except for
- the last element which gives the full response body.
- """
- for response in expected:
- expectedHeaders, expectedContent = response[:-1], response[-1]
- headers, rest = responses.split('\r\n\r\n', 1)
- headers = headers.splitlines()
- self.assertEqual(set(headers), set(expectedHeaders))
- content = rest[:len(expectedContent)]
- responses = rest[len(expectedContent):]
- self.assertEqual(content, expectedContent)
-
-
-
-class HTTP1_0TestCase(unittest.TestCase, ResponseTestMixin):
- requests = (
- "GET / HTTP/1.0\r\n"
- "\r\n"
- "GET / HTTP/1.1\r\n"
- "Accept: text/html\r\n"
- "\r\n")
-
- expected_response = [
- ("HTTP/1.0 200 OK",
- "Request: /",
- "Command: GET",
- "Version: HTTP/1.0",
- "Content-Length: 13",
- "'''\nNone\n'''\n")]
-
- def test_buffer(self):
- """
- Send requests over a channel and check responses match what is expected.
- """
- b = StringTransport()
- a = http.HTTPChannel()
- a.requestFactory = DummyHTTPHandler
- a.makeConnection(b)
- # one byte at a time, to stress it.
- for byte in self.requests:
- a.dataReceived(byte)
- a.connectionLost(IOError("all one"))
- value = b.value()
- self.assertResponseEquals(value, self.expected_response)
-
-
- def test_requestBodyTimeout(self):
- """
- L{HTTPChannel} resets its timeout whenever data from a request body is
- delivered to it.
- """
- clock = Clock()
- transport = StringTransport()
- protocol = http.HTTPChannel()
- protocol.timeOut = 100
- protocol.callLater = clock.callLater
- protocol.makeConnection(transport)
- protocol.dataReceived('POST / HTTP/1.0\r\nContent-Length: 2\r\n\r\n')
- clock.advance(99)
- self.assertFalse(transport.disconnecting)
- protocol.dataReceived('x')
- clock.advance(99)
- self.assertFalse(transport.disconnecting)
- protocol.dataReceived('x')
- self.assertEqual(len(protocol.requests), 1)
-
-
-
-class HTTP1_1TestCase(HTTP1_0TestCase):
-
- requests = (
- "GET / HTTP/1.1\r\n"
- "Accept: text/html\r\n"
- "\r\n"
- "POST / HTTP/1.1\r\n"
- "Content-Length: 10\r\n"
- "\r\n"
- "0123456789POST / HTTP/1.1\r\n"
- "Content-Length: 10\r\n"
- "\r\n"
- "0123456789HEAD / HTTP/1.1\r\n"
- "\r\n")
-
- expected_response = [
- ("HTTP/1.1 200 OK",
- "Request: /",
- "Command: GET",
- "Version: HTTP/1.1",
- "Content-Length: 13",
- "'''\nNone\n'''\n"),
- ("HTTP/1.1 200 OK",
- "Request: /",
- "Command: POST",
- "Version: HTTP/1.1",
- "Content-Length: 21",
- "'''\n10\n0123456789'''\n"),
- ("HTTP/1.1 200 OK",
- "Request: /",
- "Command: POST",
- "Version: HTTP/1.1",
- "Content-Length: 21",
- "'''\n10\n0123456789'''\n"),
- ("HTTP/1.1 200 OK",
- "Request: /",
- "Command: HEAD",
- "Version: HTTP/1.1",
- "Content-Length: 13",
- "")]
-
-
-
-class HTTP1_1_close_TestCase(HTTP1_0TestCase):
-
- requests = (
- "GET / HTTP/1.1\r\n"
- "Accept: text/html\r\n"
- "Connection: close\r\n"
- "\r\n"
- "GET / HTTP/1.0\r\n"
- "\r\n")
-
- expected_response = [
- ("HTTP/1.1 200 OK",
- "Connection: close",
- "Request: /",
- "Command: GET",
- "Version: HTTP/1.1",
- "Content-Length: 13",
- "'''\nNone\n'''\n")]
-
-
-
-class HTTP0_9TestCase(HTTP1_0TestCase):
-
- requests = (
- "GET /\r\n")
-
- expected_response = "HTTP/1.1 400 Bad Request\r\n\r\n"
-
-
- def assertResponseEquals(self, response, expectedResponse):
- self.assertEqual(response, expectedResponse)
-
-
-class HTTPLoopbackTestCase(unittest.TestCase):
-
- expectedHeaders = {'request' : '/foo/bar',
- 'command' : 'GET',
- 'version' : 'HTTP/1.0',
- 'content-length' : '21'}
- numHeaders = 0
- gotStatus = 0
- gotResponse = 0
- gotEndHeaders = 0
-
- def _handleStatus(self, version, status, message):
- self.gotStatus = 1
- self.assertEqual(version, "HTTP/1.0")
- self.assertEqual(status, "200")
-
- def _handleResponse(self, data):
- self.gotResponse = 1
- self.assertEqual(data, "'''\n10\n0123456789'''\n")
-
- def _handleHeader(self, key, value):
- self.numHeaders = self.numHeaders + 1
- self.assertEqual(self.expectedHeaders[key.lower()], value)
-
- def _handleEndHeaders(self):
- self.gotEndHeaders = 1
- self.assertEqual(self.numHeaders, 4)
-
- def testLoopback(self):
- server = http.HTTPChannel()
- server.requestFactory = DummyHTTPHandler
- client = LoopbackHTTPClient()
- client.handleResponse = self._handleResponse
- client.handleHeader = self._handleHeader
- client.handleEndHeaders = self._handleEndHeaders
- client.handleStatus = self._handleStatus
- d = loopback.loopbackAsync(server, client)
- d.addCallback(self._cbTestLoopback)
- return d
-
- def _cbTestLoopback(self, ignored):
- if not (self.gotStatus and self.gotResponse and self.gotEndHeaders):
- raise RuntimeError(
- "didn't got all callbacks %s"
- % [self.gotStatus, self.gotResponse, self.gotEndHeaders])
- del self.gotEndHeaders
- del self.gotResponse
- del self.gotStatus
- del self.numHeaders
-
-
-
-def _prequest(**headers):
- """
- Make a request with the given request headers for the persistence tests.
- """
- request = http.Request(DummyChannel(), None)
- for k, v in headers.iteritems():
- request.requestHeaders.setRawHeaders(k, v)
- return request
-
-
-class PersistenceTestCase(unittest.TestCase):
- """
- Tests for persistent HTTP connections.
- """
-
- ptests = [#(PRequest(connection="Keep-Alive"), "HTTP/1.0", 1, {'connection' : 'Keep-Alive'}),
- (_prequest(), "HTTP/1.0", 0, {'connection': None}),
- (_prequest(connection=["close"]), "HTTP/1.1", 0, {'connection' : ['close']}),
- (_prequest(), "HTTP/1.1", 1, {'connection': None}),
- (_prequest(), "HTTP/0.9", 0, {'connection': None}),
- ]
-
-
- def testAlgorithm(self):
- c = http.HTTPChannel()
- for req, version, correctResult, resultHeaders in self.ptests:
- result = c.checkPersistence(req, version)
- self.assertEqual(result, correctResult)
- for header in resultHeaders.keys():
- self.assertEqual(req.responseHeaders.getRawHeaders(header, None), resultHeaders[header])
-
-
-
-class IdentityTransferEncodingTests(TestCase):
- """
- Tests for L{_IdentityTransferDecoder}.
- """
- def setUp(self):
- """
- Create an L{_IdentityTransferDecoder} with callbacks hooked up so that
- calls to them can be inspected.
- """
- self.data = []
- self.finish = []
- self.contentLength = 10
- self.decoder = _IdentityTransferDecoder(
- self.contentLength, self.data.append, self.finish.append)
-
-
- def test_exactAmountReceived(self):
- """
- If L{_IdentityTransferDecoder.dataReceived} is called with a string
- with length equal to the content length passed to
- L{_IdentityTransferDecoder}'s initializer, the data callback is invoked
- with that string and the finish callback is invoked with a zero-length
- string.
- """
- self.decoder.dataReceived('x' * self.contentLength)
- self.assertEqual(self.data, ['x' * self.contentLength])
- self.assertEqual(self.finish, [''])
-
-
- def test_shortStrings(self):
- """
- If L{_IdentityTransferDecoder.dataReceived} is called multiple times
- with strings which, when concatenated, are as long as the content
- length provided, the data callback is invoked with each string and the
- finish callback is invoked only after the second call.
- """
- self.decoder.dataReceived('x')
- self.assertEqual(self.data, ['x'])
- self.assertEqual(self.finish, [])
- self.decoder.dataReceived('y' * (self.contentLength - 1))
- self.assertEqual(self.data, ['x', 'y' * (self.contentLength - 1)])
- self.assertEqual(self.finish, [''])
-
-
- def test_longString(self):
- """
- If L{_IdentityTransferDecoder.dataReceived} is called with a string
- with length greater than the provided content length, only the prefix
- of that string up to the content length is passed to the data callback
- and the remainder is passed to the finish callback.
- """
- self.decoder.dataReceived('x' * self.contentLength + 'y')
- self.assertEqual(self.data, ['x' * self.contentLength])
- self.assertEqual(self.finish, ['y'])
-
-
- def test_rejectDataAfterFinished(self):
- """
- If data is passed to L{_IdentityTransferDecoder.dataReceived} after the
- finish callback has been invoked, L{RuntimeError} is raised.
- """
- failures = []
- def finish(bytes):
- try:
- decoder.dataReceived('foo')
- except:
- failures.append(Failure())
- decoder = _IdentityTransferDecoder(5, self.data.append, finish)
- decoder.dataReceived('x' * 4)
- self.assertEqual(failures, [])
- decoder.dataReceived('y')
- failures[0].trap(RuntimeError)
- self.assertEqual(
- str(failures[0].value),
- "_IdentityTransferDecoder cannot decode data after finishing")
-
-
- def test_unknownContentLength(self):
- """
- If L{_IdentityTransferDecoder} is constructed with C{None} for the
- content length, it passes all data delivered to it through to the data
- callback.
- """
- data = []
- finish = []
- decoder = _IdentityTransferDecoder(None, data.append, finish.append)
- decoder.dataReceived('x')
- self.assertEqual(data, ['x'])
- decoder.dataReceived('y')
- self.assertEqual(data, ['x', 'y'])
- self.assertEqual(finish, [])
-
-
- def _verifyCallbacksUnreferenced(self, decoder):
- """
- Check the decoder's data and finish callbacks and make sure they are
- None in order to help avoid references cycles.
- """
- self.assertIdentical(decoder.dataCallback, None)
- self.assertIdentical(decoder.finishCallback, None)
-
-
- def test_earlyConnectionLose(self):
- """
- L{_IdentityTransferDecoder.noMoreData} raises L{_DataLoss} if it is
- called and the content length is known but not enough bytes have been
- delivered.
- """
- self.decoder.dataReceived('x' * (self.contentLength - 1))
- self.assertRaises(_DataLoss, self.decoder.noMoreData)
- self._verifyCallbacksUnreferenced(self.decoder)
-
-
- def test_unknownContentLengthConnectionLose(self):
- """
- L{_IdentityTransferDecoder.noMoreData} calls the finish callback and
- raises L{PotentialDataLoss} if it is called and the content length is
- unknown.
- """
- body = []
- finished = []
- decoder = _IdentityTransferDecoder(None, body.append, finished.append)
- self.assertRaises(PotentialDataLoss, decoder.noMoreData)
- self.assertEqual(body, [])
- self.assertEqual(finished, [''])
- self._verifyCallbacksUnreferenced(decoder)
-
-
- def test_finishedConnectionLose(self):
- """
- L{_IdentityTransferDecoder.noMoreData} does not raise any exception if
- it is called when the content length is known and that many bytes have
- been delivered.
- """
- self.decoder.dataReceived('x' * self.contentLength)
- self.decoder.noMoreData()
- self._verifyCallbacksUnreferenced(self.decoder)
-
-
-
-class ChunkedTransferEncodingTests(unittest.TestCase):
- """
- Tests for L{_ChunkedTransferDecoder}, which turns a byte stream encoded
- using HTTP I{chunked} C{Transfer-Encoding} back into the original byte
- stream.
- """
- def test_decoding(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} decodes chunked-encoded data
- and passes the result to the specified callback.
- """
- L = []
- p = http._ChunkedTransferDecoder(L.append, None)
- p.dataReceived('3\r\nabc\r\n5\r\n12345\r\n')
- p.dataReceived('a\r\n0123456789\r\n')
- self.assertEqual(L, ['abc', '12345', '0123456789'])
-
-
- def test_short(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} decodes chunks broken up and
- delivered in multiple calls.
- """
- L = []
- finished = []
- p = http._ChunkedTransferDecoder(L.append, finished.append)
- for s in '3\r\nabc\r\n5\r\n12345\r\n0\r\n\r\n':
- p.dataReceived(s)
- self.assertEqual(L, ['a', 'b', 'c', '1', '2', '3', '4', '5'])
- self.assertEqual(finished, [''])
-
-
- def test_newlines(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} doesn't treat CR LF pairs
- embedded in chunk bodies specially.
- """
- L = []
- p = http._ChunkedTransferDecoder(L.append, None)
- p.dataReceived('2\r\n\r\n\r\n')
- self.assertEqual(L, ['\r\n'])
-
-
- def test_extensions(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} disregards chunk-extension
- fields.
- """
- L = []
- p = http._ChunkedTransferDecoder(L.append, None)
- p.dataReceived('3; x-foo=bar\r\nabc\r\n')
- self.assertEqual(L, ['abc'])
-
-
- def test_finish(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} interprets a zero-length
- chunk as the end of the chunked data stream and calls the completion
- callback.
- """
- finished = []
- p = http._ChunkedTransferDecoder(None, finished.append)
- p.dataReceived('0\r\n\r\n')
- self.assertEqual(finished, [''])
-
-
- def test_extra(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} passes any bytes which come
- after the terminating zero-length chunk to the completion callback.
- """
- finished = []
- p = http._ChunkedTransferDecoder(None, finished.append)
- p.dataReceived('0\r\n\r\nhello')
- self.assertEqual(finished, ['hello'])
-
-
- def test_afterFinished(self):
- """
- L{_ChunkedTransferDecoder.dataReceived} raises L{RuntimeError} if it
- is called after it has seen the last chunk.
- """
- p = http._ChunkedTransferDecoder(None, lambda bytes: None)
- p.dataReceived('0\r\n\r\n')
- self.assertRaises(RuntimeError, p.dataReceived, 'hello')
-
-
- def test_earlyConnectionLose(self):
- """
- L{_ChunkedTransferDecoder.noMoreData} raises L{_DataLoss} if it is
- called and the end of the last trailer has not yet been received.
- """
- parser = http._ChunkedTransferDecoder(None, lambda bytes: None)
- parser.dataReceived('0\r\n\r')
- exc = self.assertRaises(_DataLoss, parser.noMoreData)
- self.assertEqual(
- str(exc),
- "Chunked decoder in 'TRAILER' state, still expecting more data "
- "to get to 'FINISHED' state.")
-
-
- def test_finishedConnectionLose(self):
- """
- L{_ChunkedTransferDecoder.noMoreData} does not raise any exception if
- it is called after the terminal zero length chunk is received.
- """
- parser = http._ChunkedTransferDecoder(None, lambda bytes: None)
- parser.dataReceived('0\r\n\r\n')
- parser.noMoreData()
-
-
- def test_reentrantFinishedNoMoreData(self):
- """
- L{_ChunkedTransferDecoder.noMoreData} can be called from the finished
- callback without raising an exception.
- """
- errors = []
- successes = []
- def finished(extra):
- try:
- parser.noMoreData()
- except:
- errors.append(Failure())
- else:
- successes.append(True)
- parser = http._ChunkedTransferDecoder(None, finished)
- parser.dataReceived('0\r\n\r\n')
- self.assertEqual(errors, [])
- self.assertEqual(successes, [True])
-
-
-
-class ChunkingTestCase(unittest.TestCase):
-
- strings = ["abcv", "", "fdfsd423", "Ffasfas\r\n",
- "523523\n\rfsdf", "4234"]
-
- def testChunks(self):
- for s in self.strings:
- self.assertEqual((s, ''), http.fromChunk(''.join(http.toChunk(s))))
- self.assertRaises(ValueError, http.fromChunk, '-5\r\nmalformed!\r\n')
-
- def testConcatenatedChunks(self):
- chunked = ''.join([''.join(http.toChunk(t)) for t in self.strings])
- result = []
- buffer = ""
- for c in chunked:
- buffer = buffer + c
- try:
- data, buffer = http.fromChunk(buffer)
- result.append(data)
- except ValueError:
- pass
- self.assertEqual(result, self.strings)
-
-
-
-class ParsingTestCase(unittest.TestCase):
- """
- Tests for protocol parsing in L{HTTPChannel}.
- """
- def runRequest(self, httpRequest, requestClass, success=1):
- httpRequest = httpRequest.replace("\n", "\r\n")
- b = StringTransport()
- a = http.HTTPChannel()
- a.requestFactory = requestClass
- a.makeConnection(b)
- # one byte at a time, to stress it.
- for byte in httpRequest:
- if a.transport.disconnecting:
- break
- a.dataReceived(byte)
- a.connectionLost(IOError("all done"))
- if success:
- self.assertEqual(self.didRequest, 1)
- del self.didRequest
- else:
- self.assert_(not hasattr(self, "didRequest"))
- return a
-
-
- def test_basicAuth(self):
- """
- L{HTTPChannel} provides username and password information supplied in
- an I{Authorization} header to the L{Request} which makes it available
- via its C{getUser} and C{getPassword} methods.
- """
- testcase = self
- class Request(http.Request):
- l = []
- def process(self):
- testcase.assertEqual(self.getUser(), self.l[0])
- testcase.assertEqual(self.getPassword(), self.l[1])
- for u, p in [("foo", "bar"), ("hello", "there:z")]:
- Request.l[:] = [u, p]
- s = "%s:%s" % (u, p)
- f = "GET / HTTP/1.0\nAuthorization: Basic %s\n\n" % (s.encode("base64").strip(), )
- self.runRequest(f, Request, 0)
-
-
- def test_headers(self):
- """
- Headers received by L{HTTPChannel} in a request are made available to
- the L{Request}.
- """
- processed = []
- class MyRequest(http.Request):
- def process(self):
- processed.append(self)
- self.finish()
-
- requestLines = [
- "GET / HTTP/1.0",
- "Foo: bar",
- "baz: Quux",
- "baz: quux",
- "",
- ""]
-
- self.runRequest('\n'.join(requestLines), MyRequest, 0)
- [request] = processed
- self.assertEqual(
- request.requestHeaders.getRawHeaders('foo'), ['bar'])
- self.assertEqual(
- request.requestHeaders.getRawHeaders('bAz'), ['Quux', 'quux'])
-
-
- def test_tooManyHeaders(self):
- """
- L{HTTPChannel} enforces a limit of C{HTTPChannel.maxHeaders} on the
- number of headers received per request.
- """
- processed = []
- class MyRequest(http.Request):
- def process(self):
- processed.append(self)
-
- requestLines = ["GET / HTTP/1.0"]
- for i in range(http.HTTPChannel.maxHeaders + 2):
- requestLines.append("%s: foo" % (i,))
- requestLines.extend(["", ""])
-
- channel = self.runRequest("\n".join(requestLines), MyRequest, 0)
- self.assertEqual(processed, [])
- self.assertEqual(
- channel.transport.value(),
- "HTTP/1.1 400 Bad Request\r\n\r\n")
-
-
- def test_headerLimitPerRequest(self):
- """
- L{HTTPChannel} enforces the limit of C{HTTPChannel.maxHeaders} per
- request so that headers received in an earlier request do not count
- towards the limit when processing a later request.
- """
- processed = []
- class MyRequest(http.Request):
- def process(self):
- processed.append(self)
- self.finish()
-
- self.patch(http.HTTPChannel, 'maxHeaders', 1)
- requestLines = [
- "GET / HTTP/1.1",
- "Foo: bar",
- "",
- "",
- "GET / HTTP/1.1",
- "Bar: baz",
- "",
- ""]
-
- channel = self.runRequest("\n".join(requestLines), MyRequest, 0)
- [first, second] = processed
- self.assertEqual(first.getHeader('foo'), 'bar')
- self.assertEqual(second.getHeader('bar'), 'baz')
- self.assertEqual(
- channel.transport.value(),
- 'HTTP/1.1 200 OK\r\n'
- 'Transfer-Encoding: chunked\r\n'
- '\r\n'
- '0\r\n'
- '\r\n'
- 'HTTP/1.1 200 OK\r\n'
- 'Transfer-Encoding: chunked\r\n'
- '\r\n'
- '0\r\n'
- '\r\n')
-
-
- def testCookies(self):
- """
- Test cookies parsing and reading.
- """
- httpRequest = '''\
-GET / HTTP/1.0
-Cookie: rabbit="eat carrot"; ninja=secret; spam="hey 1=1!"
-
-'''
- testcase = self
-
- class MyRequest(http.Request):
- def process(self):
- testcase.assertEqual(self.getCookie('rabbit'), '"eat carrot"')
- testcase.assertEqual(self.getCookie('ninja'), 'secret')
- testcase.assertEqual(self.getCookie('spam'), '"hey 1=1!"')
- testcase.didRequest = 1
- self.finish()
-
- self.runRequest(httpRequest, MyRequest)
-
- def testGET(self):
- httpRequest = '''\
-GET /?key=value&multiple=two+words&multiple=more%20words&empty= HTTP/1.0
-
-'''
- testcase = self
- class MyRequest(http.Request):
- def process(self):
- testcase.assertEqual(self.method, "GET")
- testcase.assertEqual(self.args["key"], ["value"])
- testcase.assertEqual(self.args["empty"], [""])
- testcase.assertEqual(self.args["multiple"], ["two words", "more words"])
- testcase.didRequest = 1
- self.finish()
-
- self.runRequest(httpRequest, MyRequest)
-
-
- def test_extraQuestionMark(self):
- """
- While only a single '?' is allowed in an URL, several other servers
- allow several and pass all after the first through as part of the
- query arguments. Test that we emulate this behavior.
- """
- httpRequest = 'GET /foo?bar=?&baz=quux HTTP/1.0\n\n'
-
- testcase = self
- class MyRequest(http.Request):
- def process(self):
- testcase.assertEqual(self.method, 'GET')
- testcase.assertEqual(self.path, '/foo')
- testcase.assertEqual(self.args['bar'], ['?'])
- testcase.assertEqual(self.args['baz'], ['quux'])
- testcase.didRequest = 1
- self.finish()
-
- self.runRequest(httpRequest, MyRequest)
-
-
- def test_formPOSTRequest(self):
- """
- The request body of a I{POST} request with a I{Content-Type} header
- of I{application/x-www-form-urlencoded} is parsed according to that
- content type and made available in the C{args} attribute of the
- request object. The original bytes of the request may still be read
- from the C{content} attribute.
- """
- query = 'key=value&multiple=two+words&multiple=more%20words&empty='
- httpRequest = '''\
-POST / HTTP/1.0
-Content-Length: %d
-Content-Type: application/x-www-form-urlencoded
-
-%s''' % (len(query), query)
-
- testcase = self
- class MyRequest(http.Request):
- def process(self):
- testcase.assertEqual(self.method, "POST")
- testcase.assertEqual(self.args["key"], ["value"])
- testcase.assertEqual(self.args["empty"], [""])
- testcase.assertEqual(self.args["multiple"], ["two words", "more words"])
-
- # Reading from the content file-like must produce the entire
- # request body.
- testcase.assertEqual(self.content.read(), query)
- testcase.didRequest = 1
- self.finish()
-
- self.runRequest(httpRequest, MyRequest)
-
- def testMissingContentDisposition(self):
- req = '''\
-POST / HTTP/1.0
-Content-Type: multipart/form-data; boundary=AaB03x
-Content-Length: 103
-
---AaB03x
-Content-Type: text/plain
-Content-Transfer-Encoding: quoted-printable
-
-abasdfg
---AaB03x--
-'''
- self.runRequest(req, http.Request, success=False)
-
- def test_chunkedEncoding(self):
- """
- If a request uses the I{chunked} transfer encoding, the request body is
- decoded accordingly before it is made available on the request.
- """
- httpRequest = '''\
-GET / HTTP/1.0
-Content-Type: text/plain
-Transfer-Encoding: chunked
-
-6
-Hello,
-14
- spam,eggs spam spam
-0
-
-'''
- testcase = self
- class MyRequest(http.Request):
- def process(self):
- # The tempfile API used to create content returns an
- # instance of a different type depending on what platform
- # we're running on. The point here is to verify that the
- # request body is in a file that's on the filesystem.
- # Having a fileno method that returns an int is a somewhat
- # close approximation of this. -exarkun
- testcase.assertIsInstance(self.content.fileno(), int)
- testcase.assertEqual(self.method, 'GET')
- testcase.assertEqual(self.path, '/')
- content = self.content.read()
- testcase.assertEqual(content, 'Hello, spam,eggs spam spam')
- testcase.assertIdentical(self.channel._transferDecoder, None)
- testcase.didRequest = 1
- self.finish()
-
- self.runRequest(httpRequest, MyRequest)
-
-
-
-class QueryArgumentsTestCase(unittest.TestCase):
- def testParseqs(self):
- self.assertEqual(cgi.parse_qs("a=b&d=c;+=f"),
- http.parse_qs("a=b&d=c;+=f"))
- self.failUnlessRaises(ValueError, http.parse_qs, "blah",
- strict_parsing = 1)
- self.assertEqual(cgi.parse_qs("a=&b=c", keep_blank_values = 1),
- http.parse_qs("a=&b=c", keep_blank_values = 1))
- self.assertEqual(cgi.parse_qs("a=&b=c"),
- http.parse_qs("a=&b=c"))
-
-
- def test_urlparse(self):
- """
- For a given URL, L{http.urlparse} should behave the same as
- L{urlparse}, except it should always return C{str}, never C{unicode}.
- """
- def urls():
- for scheme in ('http', 'https'):
- for host in ('example.com',):
- for port in (None, 100):
- for path in ('', 'path'):
- if port is not None:
- host = host + ':' + str(port)
- yield urlunsplit((scheme, host, path, '', ''))
-
-
- def assertSameParsing(url, decode):
- """
- Verify that C{url} is parsed into the same objects by both
- L{http.urlparse} and L{urlparse}.
- """
- urlToStandardImplementation = url
- if decode:
- urlToStandardImplementation = url.decode('ascii')
- standardResult = urlparse(urlToStandardImplementation)
- scheme, netloc, path, params, query, fragment = http.urlparse(url)
- self.assertEqual(
- (scheme, netloc, path, params, query, fragment),
- standardResult)
- self.assertTrue(isinstance(scheme, str))
- self.assertTrue(isinstance(netloc, str))
- self.assertTrue(isinstance(path, str))
- self.assertTrue(isinstance(params, str))
- self.assertTrue(isinstance(query, str))
- self.assertTrue(isinstance(fragment, str))
-
- # With caching, unicode then str
- clear_cache()
- for url in urls():
- assertSameParsing(url, True)
- assertSameParsing(url, False)
-
- # With caching, str then unicode
- clear_cache()
- for url in urls():
- assertSameParsing(url, False)
- assertSameParsing(url, True)
-
- # Without caching
- for url in urls():
- clear_cache()
- assertSameParsing(url, True)
- clear_cache()
- assertSameParsing(url, False)
-
-
- def test_urlparseRejectsUnicode(self):
- """
- L{http.urlparse} should reject unicode input early.
- """
- self.assertRaises(TypeError, http.urlparse, u'http://example.org/path')
-
-
-
-class ClientDriver(http.HTTPClient):
- def handleStatus(self, version, status, message):
- self.version = version
- self.status = status
- self.message = message
-
-class ClientStatusParsing(unittest.TestCase):
- def testBaseline(self):
- c = ClientDriver()
- c.lineReceived('HTTP/1.0 201 foo')
- self.assertEqual(c.version, 'HTTP/1.0')
- self.assertEqual(c.status, '201')
- self.assertEqual(c.message, 'foo')
-
- def testNoMessage(self):
- c = ClientDriver()
- c.lineReceived('HTTP/1.0 201')
- self.assertEqual(c.version, 'HTTP/1.0')
- self.assertEqual(c.status, '201')
- self.assertEqual(c.message, '')
-
- def testNoMessage_trailingSpace(self):
- c = ClientDriver()
- c.lineReceived('HTTP/1.0 201 ')
- self.assertEqual(c.version, 'HTTP/1.0')
- self.assertEqual(c.status, '201')
- self.assertEqual(c.message, '')
-
-
-
-class RequestTests(unittest.TestCase, ResponseTestMixin):
- """
- Tests for L{http.Request}
- """
- def _compatHeadersTest(self, oldName, newName):
- """
- Verify that each of two different attributes which are associated with
- the same state properly reflect changes made through the other.
-
- This is used to test that the C{headers}/C{responseHeaders} and
- C{received_headers}/C{requestHeaders} pairs interact properly.
- """
- req = http.Request(DummyChannel(), None)
- getattr(req, newName).setRawHeaders("test", ["lemur"])
- self.assertEqual(getattr(req, oldName)["test"], "lemur")
- setattr(req, oldName, {"foo": "bar"})
- self.assertEqual(
- list(getattr(req, newName).getAllRawHeaders()),
- [("Foo", ["bar"])])
- setattr(req, newName, http_headers.Headers())
- self.assertEqual(getattr(req, oldName), {})
-
-
- def test_received_headers(self):
- """
- L{Request.received_headers} is a backwards compatible API which
- accesses and allows mutation of the state at L{Request.requestHeaders}.
- """
- self._compatHeadersTest('received_headers', 'requestHeaders')
-
-
- def test_headers(self):
- """
- L{Request.headers} is a backwards compatible API which accesses and
- allows mutation of the state at L{Request.responseHeaders}.
- """
- self._compatHeadersTest('headers', 'responseHeaders')
-
-
- def test_getHeader(self):
- """
- L{http.Request.getHeader} returns the value of the named request
- header.
- """
- req = http.Request(DummyChannel(), None)
- req.requestHeaders.setRawHeaders("test", ["lemur"])
- self.assertEqual(req.getHeader("test"), "lemur")
-
-
- def test_getHeaderReceivedMultiples(self):
- """
- When there are multiple values for a single request header,
- L{http.Request.getHeader} returns the last value.
- """
- req = http.Request(DummyChannel(), None)
- req.requestHeaders.setRawHeaders("test", ["lemur", "panda"])
- self.assertEqual(req.getHeader("test"), "panda")
-
-
- def test_getHeaderNotFound(self):
- """
- L{http.Request.getHeader} returns C{None} when asked for the value of a
- request header which is not present.
- """
- req = http.Request(DummyChannel(), None)
- self.assertEqual(req.getHeader("test"), None)
-
-
- def test_getAllHeaders(self):
- """
- L{http.Request.getAllheaders} returns a C{dict} mapping all request
- header names to their corresponding values.
- """
- req = http.Request(DummyChannel(), None)
- req.requestHeaders.setRawHeaders("test", ["lemur"])
- self.assertEqual(req.getAllHeaders(), {"test": "lemur"})
-
-
- def test_getAllHeadersNoHeaders(self):
- """
- L{http.Request.getAllHeaders} returns an empty C{dict} if there are no
- request headers.
- """
- req = http.Request(DummyChannel(), None)
- self.assertEqual(req.getAllHeaders(), {})
-
-
- def test_getAllHeadersMultipleHeaders(self):
- """
- When there are multiple values for a single request header,
- L{http.Request.getAllHeaders} returns only the last value.
- """
- req = http.Request(DummyChannel(), None)
- req.requestHeaders.setRawHeaders("test", ["lemur", "panda"])
- self.assertEqual(req.getAllHeaders(), {"test": "panda"})
-
-
- def test_setResponseCode(self):
- """
- L{http.Request.setResponseCode} takes a status code and causes it to be
- used as the response status.
- """
- channel = DummyChannel()
- req = http.Request(channel, None)
- req.setResponseCode(201)
- req.write('')
- self.assertEqual(
- channel.transport.written.getvalue().splitlines()[0],
- '%s 201 Created' % (req.clientproto,))
-
-
- def test_setResponseCodeAndMessage(self):
- """
- L{http.Request.setResponseCode} takes a status code and a message and
- causes them to be used as the response status.
- """
- channel = DummyChannel()
- req = http.Request(channel, None)
- req.setResponseCode(202, "happily accepted")
- req.write('')
- self.assertEqual(
- channel.transport.written.getvalue().splitlines()[0],
- '%s 202 happily accepted' % (req.clientproto,))
-
-
- def test_setResponseCodeAcceptsIntegers(self):
- """
- L{http.Request.setResponseCode} accepts C{int} or C{long} for the code
- parameter and raises L{TypeError} if passed anything else.
- """
- req = http.Request(DummyChannel(), None)
- req.setResponseCode(1)
- req.setResponseCode(1L)
- self.assertRaises(TypeError, req.setResponseCode, "1")
-
-
- def test_setHost(self):
- """
- L{http.Request.setHost} sets the value of the host request header.
- The port should not be added because it is the default.
- """
- req = http.Request(DummyChannel(), None)
- req.setHost("example.com", 80)
- self.assertEqual(
- req.requestHeaders.getRawHeaders("host"), ["example.com"])
-
-
- def test_setHostSSL(self):
- """
- L{http.Request.setHost} sets the value of the host request header.
- The port should not be added because it is the default.
- """
- d = DummyChannel()
- d.transport = DummyChannel.SSL()
- req = http.Request(d, None)
- req.setHost("example.com", 443)
- self.assertEqual(
- req.requestHeaders.getRawHeaders("host"), ["example.com"])
-
-
- def test_setHostNonDefaultPort(self):
- """
- L{http.Request.setHost} sets the value of the host request header.
- The port should be added because it is not the default.
- """
- req = http.Request(DummyChannel(), None)
- req.setHost("example.com", 81)
- self.assertEqual(
- req.requestHeaders.getRawHeaders("host"), ["example.com:81"])
-
-
- def test_setHostSSLNonDefaultPort(self):
- """
- L{http.Request.setHost} sets the value of the host request header.
- The port should be added because it is not the default.
- """
- d = DummyChannel()
- d.transport = DummyChannel.SSL()
- req = http.Request(d, None)
- req.setHost("example.com", 81)
- self.assertEqual(
- req.requestHeaders.getRawHeaders("host"), ["example.com:81"])
-
-
- def test_setHeader(self):
- """
- L{http.Request.setHeader} sets the value of the given response header.
- """
- req = http.Request(DummyChannel(), None)
- req.setHeader("test", "lemur")
- self.assertEqual(req.responseHeaders.getRawHeaders("test"), ["lemur"])
-
-
- def test_firstWrite(self):
- """
- For an HTTP 1.0 request, L{http.Request.write} sends an HTTP 1.0
- Response-Line and whatever response headers are set.
- """
- req = http.Request(DummyChannel(), None)
- trans = StringTransport()
-
- req.transport = trans
-
- req.setResponseCode(200)
- req.clientproto = "HTTP/1.0"
- req.responseHeaders.setRawHeaders("test", ["lemur"])
- req.write('Hello')
-
- self.assertResponseEquals(
- trans.value(),
- [("HTTP/1.0 200 OK",
- "Test: lemur",
- "Hello")])
-
-
- def test_firstWriteHTTP11Chunked(self):
- """
- For an HTTP 1.1 request, L{http.Request.write} sends an HTTP 1.1
- Response-Line, whatever response headers are set, and uses chunked
- encoding for the response body.
- """
- req = http.Request(DummyChannel(), None)
- trans = StringTransport()
-
- req.transport = trans
-
- req.setResponseCode(200)
- req.clientproto = "HTTP/1.1"
- req.responseHeaders.setRawHeaders("test", ["lemur"])
- req.write('Hello')
- req.write('World!')
-
- self.assertResponseEquals(
- trans.value(),
- [("HTTP/1.1 200 OK",
- "Test: lemur",
- "Transfer-Encoding: chunked",
- "5\r\nHello\r\n6\r\nWorld!\r\n")])
-
-
- def test_firstWriteLastModified(self):
- """
- For an HTTP 1.0 request for a resource with a known last modified time,
- L{http.Request.write} sends an HTTP Response-Line, whatever response
- headers are set, and a last-modified header with that time.
- """
- req = http.Request(DummyChannel(), None)
- trans = StringTransport()
-
- req.transport = trans
-
- req.setResponseCode(200)
- req.clientproto = "HTTP/1.0"
- req.lastModified = 0
- req.responseHeaders.setRawHeaders("test", ["lemur"])
- req.write('Hello')
-
- self.assertResponseEquals(
- trans.value(),
- [("HTTP/1.0 200 OK",
- "Test: lemur",
- "Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT",
- "Hello")])
-
-
- def test_parseCookies(self):
- """
- L{http.Request.parseCookies} extracts cookies from C{requestHeaders}
- and adds them to C{received_cookies}.
- """
- req = http.Request(DummyChannel(), None)
- req.requestHeaders.setRawHeaders(
- "cookie", ['test="lemur"; test2="panda"'])
- req.parseCookies()
- self.assertEqual(req.received_cookies, {"test": '"lemur"',
- "test2": '"panda"'})
-
-
- def test_parseCookiesMultipleHeaders(self):
- """
- L{http.Request.parseCookies} can extract cookies from multiple Cookie
- headers.
- """
- req = http.Request(DummyChannel(), None)
- req.requestHeaders.setRawHeaders(
- "cookie", ['test="lemur"', 'test2="panda"'])
- req.parseCookies()
- self.assertEqual(req.received_cookies, {"test": '"lemur"',
- "test2": '"panda"'})
-
-
- def test_connectionLost(self):
- """
- L{http.Request.connectionLost} closes L{Request.content} and drops the
- reference to the L{HTTPChannel} to assist with garbage collection.
- """
- req = http.Request(DummyChannel(), None)
-
- # Cause Request.content to be created at all.
- req.gotLength(10)
-
- # Grab a reference to content in case the Request drops it later on.
- content = req.content
-
- # Put some bytes into it
- req.handleContentChunk("hello")
-
- # Then something goes wrong and content should get closed.
- req.connectionLost(Failure(ConnectionLost("Finished")))
- self.assertTrue(content.closed)
- self.assertIdentical(req.channel, None)
-
-
- def test_registerProducerTwiceFails(self):
- """
- Calling L{Request.registerProducer} when a producer is already
- registered raises ValueError.
- """
- req = http.Request(DummyChannel(), None)
- req.registerProducer(DummyProducer(), True)
- self.assertRaises(
- ValueError, req.registerProducer, DummyProducer(), True)
-
-
- def test_registerProducerWhenQueuedPausesPushProducer(self):
- """
- Calling L{Request.registerProducer} with an IPushProducer when the
- request is queued pauses the producer.
- """
- req = http.Request(DummyChannel(), True)
- producer = DummyProducer()
- req.registerProducer(producer, True)
- self.assertEqual(['pause'], producer.events)
-
-
- def test_registerProducerWhenQueuedDoesntPausePullProducer(self):
- """
- Calling L{Request.registerProducer} with an IPullProducer when the
- request is queued does not pause the producer, because it doesn't make
- sense to pause a pull producer.
- """
- req = http.Request(DummyChannel(), True)
- producer = DummyProducer()
- req.registerProducer(producer, False)
- self.assertEqual([], producer.events)
-
-
- def test_registerProducerWhenQueuedDoesntRegisterPushProducer(self):
- """
- Calling L{Request.registerProducer} with an IPushProducer when the
- request is queued does not register the producer on the request's
- transport.
- """
- self.assertIdentical(
- None, getattr(http.StringTransport, 'registerProducer', None),
- "StringTransport cannot implement registerProducer for this test "
- "to be valid.")
- req = http.Request(DummyChannel(), True)
- producer = DummyProducer()
- req.registerProducer(producer, True)
- # This is a roundabout assertion: http.StringTransport doesn't
- # implement registerProducer, so Request.registerProducer can't have
- # tried to call registerProducer on the transport.
- self.assertIsInstance(req.transport, http.StringTransport)
-
-
- def test_registerProducerWhenQueuedDoesntRegisterPullProducer(self):
- """
- Calling L{Request.registerProducer} with an IPullProducer when the
- request is queued does not register the producer on the request's
- transport.
- """
- self.assertIdentical(
- None, getattr(http.StringTransport, 'registerProducer', None),
- "StringTransport cannot implement registerProducer for this test "
- "to be valid.")
- req = http.Request(DummyChannel(), True)
- producer = DummyProducer()
- req.registerProducer(producer, False)
- # This is a roundabout assertion: http.StringTransport doesn't
- # implement registerProducer, so Request.registerProducer can't have
- # tried to call registerProducer on the transport.
- self.assertIsInstance(req.transport, http.StringTransport)
-
-
- def test_registerProducerWhenNotQueuedRegistersPushProducer(self):
- """
- Calling L{Request.registerProducer} with an IPushProducer when the
- request is not queued registers the producer as a push producer on the
- request's transport.
- """
- req = http.Request(DummyChannel(), False)
- producer = DummyProducer()
- req.registerProducer(producer, True)
- self.assertEqual([(producer, True)], req.transport.producers)
-
-
- def test_registerProducerWhenNotQueuedRegistersPullProducer(self):
- """
- Calling L{Request.registerProducer} with an IPullProducer when the
- request is not queued registers the producer as a pull producer on the
- request's transport.
- """
- req = http.Request(DummyChannel(), False)
- producer = DummyProducer()
- req.registerProducer(producer, False)
- self.assertEqual([(producer, False)], req.transport.producers)
-
-
- def test_connectionLostNotification(self):
- """
- L{Request.connectionLost} triggers all finish notification Deferreds
- and cleans up per-request state.
- """
- d = DummyChannel()
- request = http.Request(d, True)
- finished = request.notifyFinish()
- request.connectionLost(Failure(ConnectionLost("Connection done")))
- self.assertIdentical(request.channel, None)
- return self.assertFailure(finished, ConnectionLost)
-
-
- def test_finishNotification(self):
- """
- L{Request.finish} triggers all finish notification Deferreds.
- """
- request = http.Request(DummyChannel(), False)
- finished = request.notifyFinish()
- # Force the request to have a non-None content attribute. This is
- # probably a bug in Request.
- request.gotLength(1)
- request.finish()
- return finished
-
-
- def test_writeAfterFinish(self):
- """
- Calling L{Request.write} after L{Request.finish} has been called results
- in a L{RuntimeError} being raised.
- """
- request = http.Request(DummyChannel(), False)
- finished = request.notifyFinish()
- # Force the request to have a non-None content attribute. This is
- # probably a bug in Request.
- request.gotLength(1)
- request.write('foobar')
- request.finish()
- self.assertRaises(RuntimeError, request.write, 'foobar')
- return finished
-
-
- def test_finishAfterConnectionLost(self):
- """
- Calling L{Request.finish} after L{Request.connectionLost} has been
- called results in a L{RuntimeError} being raised.
- """
- channel = DummyChannel()
- transport = channel.transport
- req = http.Request(channel, False)
- req.connectionLost(Failure(ConnectionLost("The end.")))
- self.assertRaises(RuntimeError, req.finish)
-
-
-
-class MultilineHeadersTestCase(unittest.TestCase):
- """
- Tests to exercise handling of multiline headers by L{HTTPClient}. RFCs 1945
- (HTTP 1.0) and 2616 (HTTP 1.1) state that HTTP message header fields can
- span multiple lines if each extra line is preceded by at least one space or
- horizontal tab.
- """
- def setUp(self):
- """
- Initialize variables used to verify that the header-processing functions
- are getting called.
- """
- self.handleHeaderCalled = False
- self.handleEndHeadersCalled = False
-
- # Dictionary of sample complete HTTP header key/value pairs, including
- # multiline headers.
- expectedHeaders = {'Content-Length': '10',
- 'X-Multiline' : 'line-0\tline-1',
- 'X-Multiline2' : 'line-2 line-3'}
-
- def ourHandleHeader(self, key, val):
- """
- Dummy implementation of L{HTTPClient.handleHeader}.
- """
- self.handleHeaderCalled = True
- self.assertEqual(val, self.expectedHeaders[key])
-
-
- def ourHandleEndHeaders(self):
- """
- Dummy implementation of L{HTTPClient.handleEndHeaders}.
- """
- self.handleEndHeadersCalled = True
-
-
- def test_extractHeader(self):
- """
- A header isn't processed by L{HTTPClient.extractHeader} until it is
- confirmed in L{HTTPClient.lineReceived} that the header has been
- received completely.
- """
- c = ClientDriver()
- c.handleHeader = self.ourHandleHeader
- c.handleEndHeaders = self.ourHandleEndHeaders
-
- c.lineReceived('HTTP/1.0 201')
- c.lineReceived('Content-Length: 10')
- self.assertIdentical(c.length, None)
- self.assertFalse(self.handleHeaderCalled)
- self.assertFalse(self.handleEndHeadersCalled)
-
- # Signal end of headers.
- c.lineReceived('')
- self.assertTrue(self.handleHeaderCalled)
- self.assertTrue(self.handleEndHeadersCalled)
-
- self.assertEqual(c.length, 10)
-
-
- def test_noHeaders(self):
- """
- An HTTP request with no headers will not cause any calls to
- L{handleHeader} but will cause L{handleEndHeaders} to be called on
- L{HTTPClient} subclasses.
- """
- c = ClientDriver()
- c.handleHeader = self.ourHandleHeader
- c.handleEndHeaders = self.ourHandleEndHeaders
- c.lineReceived('HTTP/1.0 201')
-
- # Signal end of headers.
- c.lineReceived('')
- self.assertFalse(self.handleHeaderCalled)
- self.assertTrue(self.handleEndHeadersCalled)
-
- self.assertEqual(c.version, 'HTTP/1.0')
- self.assertEqual(c.status, '201')
-
-
- def test_multilineHeaders(self):
- """
- L{HTTPClient} parses multiline headers by buffering header lines until
- an empty line or a line that does not start with whitespace hits
- lineReceived, confirming that the header has been received completely.
- """
- c = ClientDriver()
- c.handleHeader = self.ourHandleHeader
- c.handleEndHeaders = self.ourHandleEndHeaders
-
- c.lineReceived('HTTP/1.0 201')
- c.lineReceived('X-Multiline: line-0')
- self.assertFalse(self.handleHeaderCalled)
- # Start continuing line with a tab.
- c.lineReceived('\tline-1')
- c.lineReceived('X-Multiline2: line-2')
- # The previous header must be complete, so now it can be processed.
- self.assertTrue(self.handleHeaderCalled)
- # Start continuing line with a space.
- c.lineReceived(' line-3')
- c.lineReceived('Content-Length: 10')
-
- # Signal end of headers.
- c.lineReceived('')
- self.assertTrue(self.handleEndHeadersCalled)
-
- self.assertEqual(c.version, 'HTTP/1.0')
- self.assertEqual(c.status, '201')
- self.assertEqual(c.length, 10)
-
-
-
-class Expect100ContinueServerTests(unittest.TestCase):
- """
- Test that the HTTP server handles 'Expect: 100-continue' header correctly.
-
- The tests in this class all assume a simplistic behavior where user code
- cannot choose to deny a request. Once ticket #288 is implemented and user
- code can run before the body of a POST is processed this should be
- extended to support overriding this behavior.
- """
-
- def test_HTTP10(self):
- """
- HTTP/1.0 requests do not get 100-continue returned, even if 'Expect:
- 100-continue' is included (RFC 2616 10.1.1).
- """
- transport = StringTransport()
- channel = http.HTTPChannel()
- channel.requestFactory = DummyHTTPHandler
- channel.makeConnection(transport)
- channel.dataReceived("GET / HTTP/1.0\r\n")
- channel.dataReceived("Host: www.example.com\r\n")
- channel.dataReceived("Content-Length: 3\r\n")
- channel.dataReceived("Expect: 100-continue\r\n")
- channel.dataReceived("\r\n")
- self.assertEqual(transport.value(), "")
- channel.dataReceived("abc")
- self.assertEqual(transport.value(),
- "HTTP/1.0 200 OK\r\n"
- "Command: GET\r\n"
- "Content-Length: 13\r\n"
- "Version: HTTP/1.0\r\n"
- "Request: /\r\n\r\n'''\n3\nabc'''\n")
-
-
- def test_expect100ContinueHeader(self):
- """
- If a HTTP/1.1 client sends a 'Expect: 100-continue' header, the server
- responds with a 100 response code before handling the request body, if
- any. The normal resource rendering code will then be called, which
- will send an additional response code.
- """
- transport = StringTransport()
- channel = http.HTTPChannel()
- channel.requestFactory = DummyHTTPHandler
- channel.makeConnection(transport)
- channel.dataReceived("GET / HTTP/1.1\r\n")
- channel.dataReceived("Host: www.example.com\r\n")
- channel.dataReceived("Expect: 100-continue\r\n")
- channel.dataReceived("Content-Length: 3\r\n")
- # The 100 continue response is not sent until all headers are
- # received:
- self.assertEqual(transport.value(), "")
- channel.dataReceived("\r\n")
- # The 100 continue response is sent *before* the body is even
- # received:
- self.assertEqual(transport.value(), "HTTP/1.1 100 Continue\r\n\r\n")
- channel.dataReceived("abc")
- self.assertEqual(transport.value(),
- "HTTP/1.1 100 Continue\r\n\r\n"
- "HTTP/1.1 200 OK\r\n"
- "Command: GET\r\n"
- "Content-Length: 13\r\n"
- "Version: HTTP/1.1\r\n"
- "Request: /\r\n\r\n'''\n3\nabc'''\n")
-
-
- def test_expect100ContinueWithPipelining(self):
- """
- If a HTTP/1.1 client sends a 'Expect: 100-continue' header, followed
- by another pipelined request, the 100 response does not interfere with
- the response to the second request.
- """
- transport = StringTransport()
- channel = http.HTTPChannel()
- channel.requestFactory = DummyHTTPHandler
- channel.makeConnection(transport)
- channel.dataReceived(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
- "Expect: 100-continue\r\n"
- "Content-Length: 3\r\n"
- "\r\nabc"
- "POST /foo HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
- "Content-Length: 4\r\n"
- "\r\ndefg")
- self.assertEqual(transport.value(),
- "HTTP/1.1 100 Continue\r\n\r\n"
- "HTTP/1.1 200 OK\r\n"
- "Command: GET\r\n"
- "Content-Length: 13\r\n"
- "Version: HTTP/1.1\r\n"
- "Request: /\r\n\r\n"
- "'''\n3\nabc'''\n"
- "HTTP/1.1 200 OK\r\n"
- "Command: POST\r\n"
- "Content-Length: 14\r\n"
- "Version: HTTP/1.1\r\n"
- "Request: /foo\r\n\r\n"
- "'''\n4\ndefg'''\n")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http_headers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http_headers.py
deleted file mode 100755
index 7ca1bc82..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_http_headers.py
+++ /dev/null
@@ -1,616 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.http_headers}.
-"""
-
-import sys
-
-from twisted.python.compat import set
-from twisted.trial.unittest import TestCase
-from twisted.web.http_headers import _DictHeaders, Headers
-
-
-class HeadersTests(TestCase):
- """
- Tests for L{Headers}.
- """
- def test_initializer(self):
- """
- The header values passed to L{Headers.__init__} can be retrieved via
- L{Headers.getRawHeaders}.
- """
- h = Headers({'Foo': ['bar']})
- self.assertEqual(h.getRawHeaders('foo'), ['bar'])
-
-
- def test_setRawHeaders(self):
- """
- L{Headers.setRawHeaders} sets the header values for the given
- header name to the sequence of string values.
- """
- rawValue = ["value1", "value2"]
- h = Headers()
- h.setRawHeaders("test", rawValue)
- self.assertTrue(h.hasHeader("test"))
- self.assertTrue(h.hasHeader("Test"))
- self.assertEqual(h.getRawHeaders("test"), rawValue)
-
-
- def test_rawHeadersTypeChecking(self):
- """
- L{Headers.setRawHeaders} requires values to be of type list.
- """
- h = Headers()
- self.assertRaises(TypeError, h.setRawHeaders, {'Foo': 'bar'})
-
-
- def test_addRawHeader(self):
- """
- L{Headers.addRawHeader} adds a new value for a given header.
- """
- h = Headers()
- h.addRawHeader("test", "lemur")
- self.assertEqual(h.getRawHeaders("test"), ["lemur"])
- h.addRawHeader("test", "panda")
- self.assertEqual(h.getRawHeaders("test"), ["lemur", "panda"])
-
-
- def test_getRawHeadersNoDefault(self):
- """
- L{Headers.getRawHeaders} returns C{None} if the header is not found and
- no default is specified.
- """
- self.assertIdentical(Headers().getRawHeaders("test"), None)
-
-
- def test_getRawHeadersDefaultValue(self):
- """
- L{Headers.getRawHeaders} returns the specified default value when no
- header is found.
- """
- h = Headers()
- default = object()
- self.assertIdentical(h.getRawHeaders("test", default), default)
-
-
- def test_getRawHeaders(self):
- """
- L{Headers.getRawHeaders} returns the values which have been set for a
- given header.
- """
- h = Headers()
- h.setRawHeaders("test", ["lemur"])
- self.assertEqual(h.getRawHeaders("test"), ["lemur"])
- self.assertEqual(h.getRawHeaders("Test"), ["lemur"])
-
-
- def test_hasHeaderTrue(self):
- """
- Check that L{Headers.hasHeader} returns C{True} when the given header
- is found.
- """
- h = Headers()
- h.setRawHeaders("test", ["lemur"])
- self.assertTrue(h.hasHeader("test"))
- self.assertTrue(h.hasHeader("Test"))
-
-
- def test_hasHeaderFalse(self):
- """
- L{Headers.hasHeader} returns C{False} when the given header is not
- found.
- """
- self.assertFalse(Headers().hasHeader("test"))
-
-
- def test_removeHeader(self):
- """
- Check that L{Headers.removeHeader} removes the given header.
- """
- h = Headers()
-
- h.setRawHeaders("foo", ["lemur"])
- self.assertTrue(h.hasHeader("foo"))
- h.removeHeader("foo")
- self.assertFalse(h.hasHeader("foo"))
-
- h.setRawHeaders("bar", ["panda"])
- self.assertTrue(h.hasHeader("bar"))
- h.removeHeader("Bar")
- self.assertFalse(h.hasHeader("bar"))
-
-
- def test_removeHeaderDoesntExist(self):
- """
- L{Headers.removeHeader} is a no-operation when the specified header is
- not found.
- """
- h = Headers()
- h.removeHeader("test")
- self.assertEqual(list(h.getAllRawHeaders()), [])
-
-
- def test_canonicalNameCaps(self):
- """
- L{Headers._canonicalNameCaps} returns the canonical capitalization for
- the given header.
- """
- h = Headers()
- self.assertEqual(h._canonicalNameCaps("test"), "Test")
- self.assertEqual(h._canonicalNameCaps("test-stuff"), "Test-Stuff")
- self.assertEqual(h._canonicalNameCaps("content-md5"), "Content-MD5")
- self.assertEqual(h._canonicalNameCaps("dnt"), "DNT")
- self.assertEqual(h._canonicalNameCaps("etag"), "ETag")
- self.assertEqual(h._canonicalNameCaps("p3p"), "P3P")
- self.assertEqual(h._canonicalNameCaps("te"), "TE")
- self.assertEqual(h._canonicalNameCaps("www-authenticate"),
- "WWW-Authenticate")
- self.assertEqual(h._canonicalNameCaps("x-xss-protection"),
- "X-XSS-Protection")
-
-
- def test_getAllRawHeaders(self):
- """
- L{Headers.getAllRawHeaders} returns an iterable of (k, v) pairs, where
- C{k} is the canonicalized representation of the header name, and C{v}
- is a sequence of values.
- """
- h = Headers()
- h.setRawHeaders("test", ["lemurs"])
- h.setRawHeaders("www-authenticate", ["basic aksljdlk="])
-
- allHeaders = set([(k, tuple(v)) for k, v in h.getAllRawHeaders()])
-
- self.assertEqual(allHeaders,
- set([("WWW-Authenticate", ("basic aksljdlk=",)),
- ("Test", ("lemurs",))]))
-
-
- def test_headersComparison(self):
- """
- A L{Headers} instance compares equal to itself and to another
- L{Headers} instance with the same values.
- """
- first = Headers()
- first.setRawHeaders("foo", ["panda"])
- second = Headers()
- second.setRawHeaders("foo", ["panda"])
- third = Headers()
- third.setRawHeaders("foo", ["lemur", "panda"])
- self.assertEqual(first, first)
- self.assertEqual(first, second)
- self.assertNotEqual(first, third)
-
-
- def test_otherComparison(self):
- """
- An instance of L{Headers} does not compare equal to other unrelated
- objects.
- """
- h = Headers()
- self.assertNotEqual(h, ())
- self.assertNotEqual(h, object())
- self.assertNotEqual(h, "foo")
-
-
- def test_repr(self):
- """
- The L{repr} of a L{Headers} instance shows the names and values of all
- the headers it contains.
- """
- self.assertEqual(
- repr(Headers({"foo": ["bar", "baz"]})),
- "Headers({'foo': ['bar', 'baz']})")
-
-
- def test_subclassRepr(self):
- """
- The L{repr} of an instance of a subclass of L{Headers} uses the name
- of the subclass instead of the string C{"Headers"}.
- """
- class FunnyHeaders(Headers):
- pass
- self.assertEqual(
- repr(FunnyHeaders({"foo": ["bar", "baz"]})),
- "FunnyHeaders({'foo': ['bar', 'baz']})")
-
-
- def test_copy(self):
- """
- L{Headers.copy} creates a new independant copy of an existing
- L{Headers} instance, allowing future modifications without impacts
- between the copies.
- """
- h = Headers()
- h.setRawHeaders('test', ['foo'])
- i = h.copy()
- self.assertEqual(i.getRawHeaders('test'), ['foo'])
- h.addRawHeader('test', 'bar')
- self.assertEqual(i.getRawHeaders('test'), ['foo'])
- i.addRawHeader('test', 'baz')
- self.assertEqual(h.getRawHeaders('test'), ['foo', 'bar'])
-
-
-
-class HeaderDictTests(TestCase):
- """
- Tests for the backwards compatible C{dict} interface for L{Headers}
- provided by L{_DictHeaders}.
- """
- def headers(self, **kw):
- """
- Create a L{Headers} instance populated with the header name/values
- specified by C{kw} and a L{_DictHeaders} wrapped around it and return
- them both.
- """
- h = Headers()
- for k, v in kw.iteritems():
- h.setRawHeaders(k, v)
- return h, _DictHeaders(h)
-
-
- def test_getItem(self):
- """
- L{_DictHeaders.__getitem__} returns a single header for the given name.
- """
- headers, wrapper = self.headers(test=["lemur"])
- self.assertEqual(wrapper["test"], "lemur")
-
-
- def test_getItemMultiple(self):
- """
- L{_DictHeaders.__getitem__} returns only the last header value for a
- given name.
- """
- headers, wrapper = self.headers(test=["lemur", "panda"])
- self.assertEqual(wrapper["test"], "panda")
-
-
- def test_getItemMissing(self):
- """
- L{_DictHeaders.__getitem__} raises L{KeyError} if called with a header
- which is not present.
- """
- headers, wrapper = self.headers()
- exc = self.assertRaises(KeyError, wrapper.__getitem__, "test")
- self.assertEqual(exc.args, ("test",))
-
-
- def test_iteration(self):
- """
- L{_DictHeaders.__iter__} returns an iterator the elements of which
- are the lowercase name of each header present.
- """
- headers, wrapper = self.headers(foo=["lemur", "panda"], bar=["baz"])
- self.assertEqual(set(list(wrapper)), set(["foo", "bar"]))
-
-
- def test_length(self):
- """
- L{_DictHeaders.__len__} returns the number of headers present.
- """
- headers, wrapper = self.headers()
- self.assertEqual(len(wrapper), 0)
- headers.setRawHeaders("foo", ["bar"])
- self.assertEqual(len(wrapper), 1)
- headers.setRawHeaders("test", ["lemur", "panda"])
- self.assertEqual(len(wrapper), 2)
-
-
- def test_setItem(self):
- """
- L{_DictHeaders.__setitem__} sets a single header value for the given
- name.
- """
- headers, wrapper = self.headers()
- wrapper["test"] = "lemur"
- self.assertEqual(headers.getRawHeaders("test"), ["lemur"])
-
-
- def test_setItemOverwrites(self):
- """
- L{_DictHeaders.__setitem__} will replace any previous header values for
- the given name.
- """
- headers, wrapper = self.headers(test=["lemur", "panda"])
- wrapper["test"] = "lemur"
- self.assertEqual(headers.getRawHeaders("test"), ["lemur"])
-
-
- def test_delItem(self):
- """
- L{_DictHeaders.__delitem__} will remove the header values for the given
- name.
- """
- headers, wrapper = self.headers(test=["lemur"])
- del wrapper["test"]
- self.assertFalse(headers.hasHeader("test"))
-
-
- def test_delItemMissing(self):
- """
- L{_DictHeaders.__delitem__} will raise L{KeyError} if the given name is
- not present.
- """
- headers, wrapper = self.headers()
- exc = self.assertRaises(KeyError, wrapper.__delitem__, "test")
- self.assertEqual(exc.args, ("test",))
-
-
- def test_keys(self, _method='keys', _requireList=True):
- """
- L{_DictHeaders.keys} will return a list of all present header names.
- """
- headers, wrapper = self.headers(test=["lemur"], foo=["bar"])
- keys = getattr(wrapper, _method)()
- if _requireList:
- self.assertIsInstance(keys, list)
- self.assertEqual(set(keys), set(["foo", "test"]))
-
-
- def test_iterkeys(self):
- """
- L{_DictHeaders.iterkeys} will return all present header names.
- """
- self.test_keys('iterkeys', False)
-
-
- def test_values(self, _method='values', _requireList=True):
- """
- L{_DictHeaders.values} will return a list of all present header values,
- returning only the last value for headers with more than one.
- """
- headers, wrapper = self.headers(foo=["lemur"], bar=["marmot", "panda"])
- values = getattr(wrapper, _method)()
- if _requireList:
- self.assertIsInstance(values, list)
- self.assertEqual(set(values), set(["lemur", "panda"]))
-
-
- def test_itervalues(self):
- """
- L{_DictHeaders.itervalues} will return all present header values,
- returning only the last value for headers with more than one.
- """
- self.test_values('itervalues', False)
-
-
- def test_items(self, _method='items', _requireList=True):
- """
- L{_DictHeaders.items} will return a list of all present header names
- and values as tuples, returning only the last value for headers with
- more than one.
- """
- headers, wrapper = self.headers(foo=["lemur"], bar=["marmot", "panda"])
- items = getattr(wrapper, _method)()
- if _requireList:
- self.assertIsInstance(items, list)
- self.assertEqual(set(items), set([("foo", "lemur"), ("bar", "panda")]))
-
-
- def test_iteritems(self):
- """
- L{_DictHeaders.iteritems} will return all present header names and
- values as tuples, returning only the last value for headers with more
- than one.
- """
- self.test_items('iteritems', False)
-
-
- def test_clear(self):
- """
- L{_DictHeaders.clear} will remove all headers.
- """
- headers, wrapper = self.headers(foo=["lemur"], bar=["panda"])
- wrapper.clear()
- self.assertEqual(list(headers.getAllRawHeaders()), [])
-
-
- def test_copy(self):
- """
- L{_DictHeaders.copy} will return a C{dict} with all the same headers
- and the last value for each.
- """
- headers, wrapper = self.headers(foo=["lemur", "panda"], bar=["marmot"])
- duplicate = wrapper.copy()
- self.assertEqual(duplicate, {"foo": "panda", "bar": "marmot"})
-
-
- def test_get(self):
- """
- L{_DictHeaders.get} returns the last value for the given header name.
- """
- headers, wrapper = self.headers(foo=["lemur", "panda"])
- self.assertEqual(wrapper.get("foo"), "panda")
-
-
- def test_getMissing(self):
- """
- L{_DictHeaders.get} returns C{None} for a header which is not present.
- """
- headers, wrapper = self.headers()
- self.assertIdentical(wrapper.get("foo"), None)
-
-
- def test_getDefault(self):
- """
- L{_DictHeaders.get} returns the last value for the given header name
- even when it is invoked with a default value.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- self.assertEqual(wrapper.get("foo", "bar"), "lemur")
-
-
- def test_getDefaultMissing(self):
- """
- L{_DictHeaders.get} returns the default value specified if asked for a
- header which is not present.
- """
- headers, wrapper = self.headers()
- self.assertEqual(wrapper.get("foo", "bar"), "bar")
-
-
- def test_has_key(self):
- """
- L{_DictHeaders.has_key} returns C{True} if the given header is present,
- C{False} otherwise.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- self.assertTrue(wrapper.has_key("foo"))
- self.assertFalse(wrapper.has_key("bar"))
-
-
- def test_contains(self):
- """
- L{_DictHeaders.__contains__} returns C{True} if the given header is
- present, C{False} otherwise.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- self.assertIn("foo", wrapper)
- self.assertNotIn("bar", wrapper)
-
-
- def test_pop(self):
- """
- L{_DictHeaders.pop} returns the last header value associated with the
- given header name and removes the header.
- """
- headers, wrapper = self.headers(foo=["lemur", "panda"])
- self.assertEqual(wrapper.pop("foo"), "panda")
- self.assertIdentical(headers.getRawHeaders("foo"), None)
-
-
- def test_popMissing(self):
- """
- L{_DictHeaders.pop} raises L{KeyError} if passed a header name which is
- not present.
- """
- headers, wrapper = self.headers()
- self.assertRaises(KeyError, wrapper.pop, "foo")
-
-
- def test_popDefault(self):
- """
- L{_DictHeaders.pop} returns the last header value associated with the
- given header name and removes the header, even if it is supplied with a
- default value.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- self.assertEqual(wrapper.pop("foo", "bar"), "lemur")
- self.assertIdentical(headers.getRawHeaders("foo"), None)
-
-
- def test_popDefaultMissing(self):
- """
- L{_DictHeaders.pop} returns the default value is asked for a header
- name which is not present.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- self.assertEqual(wrapper.pop("bar", "baz"), "baz")
- self.assertEqual(headers.getRawHeaders("foo"), ["lemur"])
-
-
- def test_popitem(self):
- """
- L{_DictHeaders.popitem} returns some header name/value pair.
- """
- headers, wrapper = self.headers(foo=["lemur", "panda"])
- self.assertEqual(wrapper.popitem(), ("foo", "panda"))
- self.assertIdentical(headers.getRawHeaders("foo"), None)
-
-
- def test_popitemEmpty(self):
- """
- L{_DictHeaders.popitem} raises L{KeyError} if there are no headers
- present.
- """
- headers, wrapper = self.headers()
- self.assertRaises(KeyError, wrapper.popitem)
-
-
- def test_update(self):
- """
- L{_DictHeaders.update} adds the header/value pairs in the C{dict} it is
- passed, overriding any existing values for those headers.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- wrapper.update({"foo": "panda", "bar": "marmot"})
- self.assertEqual(headers.getRawHeaders("foo"), ["panda"])
- self.assertEqual(headers.getRawHeaders("bar"), ["marmot"])
-
-
- def test_updateWithKeywords(self):
- """
- L{_DictHeaders.update} adds header names given as keyword arguments
- with the keyword values as the header value.
- """
- headers, wrapper = self.headers(foo=["lemur"])
- wrapper.update(foo="panda", bar="marmot")
- self.assertEqual(headers.getRawHeaders("foo"), ["panda"])
- self.assertEqual(headers.getRawHeaders("bar"), ["marmot"])
-
- if sys.version_info < (2, 4):
- test_updateWithKeywords.skip = (
- "Python 2.3 does not support keyword arguments to dict.update.")
-
-
- def test_setdefaultMissing(self):
- """
- If passed the name of a header which is not present,
- L{_DictHeaders.setdefault} sets the value of the given header to the
- specified default value and returns it.
- """
- headers, wrapper = self.headers(foo=["bar"])
- self.assertEqual(wrapper.setdefault("baz", "quux"), "quux")
- self.assertEqual(headers.getRawHeaders("foo"), ["bar"])
- self.assertEqual(headers.getRawHeaders("baz"), ["quux"])
-
-
- def test_setdefaultPresent(self):
- """
- If passed the name of a header which is present,
- L{_DictHeaders.setdefault} makes no changes to the headers and
- returns the last value already associated with that header.
- """
- headers, wrapper = self.headers(foo=["bar", "baz"])
- self.assertEqual(wrapper.setdefault("foo", "quux"), "baz")
- self.assertEqual(headers.getRawHeaders("foo"), ["bar", "baz"])
-
-
- def test_setdefaultDefault(self):
- """
- If a value is not passed to L{_DictHeaders.setdefault}, C{None} is
- used.
- """
- # This results in an invalid state for the headers, but maybe some
- # application is doing this an intermediate step towards some other
- # state. Anyway, it was broken with the old implementation so it's
- # broken with the new implementation. Compatibility, for the win.
- # -exarkun
- headers, wrapper = self.headers()
- self.assertIdentical(wrapper.setdefault("foo"), None)
- self.assertEqual(headers.getRawHeaders("foo"), [None])
-
-
- def test_dictComparison(self):
- """
- An instance of L{_DictHeaders} compares equal to a C{dict} which
- contains the same header/value pairs. For header names with multiple
- values, the last value only is considered.
- """
- headers, wrapper = self.headers(foo=["lemur"], bar=["panda", "marmot"])
- self.assertNotEqual(wrapper, {"foo": "lemur", "bar": "panda"})
- self.assertEqual(wrapper, {"foo": "lemur", "bar": "marmot"})
-
-
- def test_otherComparison(self):
- """
- An instance of L{_DictHeaders} does not compare equal to other
- unrelated objects.
- """
- headers, wrapper = self.headers()
- self.assertNotEqual(wrapper, ())
- self.assertNotEqual(wrapper, object())
- self.assertNotEqual(wrapper, "foo")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_httpauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_httpauth.py
deleted file mode 100755
index 1764b0fc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_httpauth.py
+++ /dev/null
@@ -1,634 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web._auth}.
-"""
-
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.trial import unittest
-
-from twisted.python.failure import Failure
-from twisted.internet.error import ConnectionDone
-from twisted.internet.address import IPv4Address
-
-from twisted.cred import error, portal
-from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
-from twisted.cred.checkers import ANONYMOUS, AllowAnonymousAccess
-from twisted.cred.credentials import IUsernamePassword
-
-from twisted.web.iweb import ICredentialFactory
-from twisted.web.resource import IResource, Resource, getChildForRequest
-from twisted.web._auth import basic, digest
-from twisted.web._auth.wrapper import HTTPAuthSessionWrapper, UnauthorizedResource
-from twisted.web._auth.basic import BasicCredentialFactory
-
-from twisted.web.server import NOT_DONE_YET
-from twisted.web.static import Data
-
-from twisted.web.test.test_web import DummyRequest
-
-
-def b64encode(s):
- return s.encode('base64').strip()
-
-
-class BasicAuthTestsMixin:
- """
- L{TestCase} mixin class which defines a number of tests for
- L{basic.BasicCredentialFactory}. Because this mixin defines C{setUp}, it
- must be inherited before L{TestCase}.
- """
- def setUp(self):
- self.request = self.makeRequest()
- self.realm = 'foo'
- self.username = 'dreid'
- self.password = 'S3CuR1Ty'
- self.credentialFactory = basic.BasicCredentialFactory(self.realm)
-
-
- def makeRequest(self, method='GET', clientAddress=None):
- """
- Create a request object to be passed to
- L{basic.BasicCredentialFactory.decode} along with a response value.
- Override this in a subclass.
- """
- raise NotImplementedError("%r did not implement makeRequest" % (
- self.__class__,))
-
-
- def test_interface(self):
- """
- L{BasicCredentialFactory} implements L{ICredentialFactory}.
- """
- self.assertTrue(
- verifyObject(ICredentialFactory, self.credentialFactory))
-
-
- def test_usernamePassword(self):
- """
- L{basic.BasicCredentialFactory.decode} turns a base64-encoded response
- into a L{UsernamePassword} object with a password which reflects the
- one which was encoded in the response.
- """
- response = b64encode('%s:%s' % (self.username, self.password))
-
- creds = self.credentialFactory.decode(response, self.request)
- self.assertTrue(IUsernamePassword.providedBy(creds))
- self.assertTrue(creds.checkPassword(self.password))
- self.assertFalse(creds.checkPassword(self.password + 'wrong'))
-
-
- def test_incorrectPadding(self):
- """
- L{basic.BasicCredentialFactory.decode} decodes a base64-encoded
- response with incorrect padding.
- """
- response = b64encode('%s:%s' % (self.username, self.password))
- response = response.strip('=')
-
- creds = self.credentialFactory.decode(response, self.request)
- self.assertTrue(verifyObject(IUsernamePassword, creds))
- self.assertTrue(creds.checkPassword(self.password))
-
-
- def test_invalidEncoding(self):
- """
- L{basic.BasicCredentialFactory.decode} raises L{LoginFailed} if passed
- a response which is not base64-encoded.
- """
- response = 'x' # one byte cannot be valid base64 text
- self.assertRaises(
- error.LoginFailed,
- self.credentialFactory.decode, response, self.makeRequest())
-
-
- def test_invalidCredentials(self):
- """
- L{basic.BasicCredentialFactory.decode} raises L{LoginFailed} when
- passed a response which is not valid base64-encoded text.
- """
- response = b64encode('123abc+/')
- self.assertRaises(
- error.LoginFailed,
- self.credentialFactory.decode,
- response, self.makeRequest())
-
-
-class RequestMixin:
- def makeRequest(self, method='GET', clientAddress=None):
- """
- Create a L{DummyRequest} (change me to create a
- L{twisted.web.http.Request} instead).
- """
- request = DummyRequest('/')
- request.method = method
- request.client = clientAddress
- return request
-
-
-
-class BasicAuthTestCase(RequestMixin, BasicAuthTestsMixin, unittest.TestCase):
- """
- Basic authentication tests which use L{twisted.web.http.Request}.
- """
-
-
-
-class DigestAuthTestCase(RequestMixin, unittest.TestCase):
- """
- Digest authentication tests which use L{twisted.web.http.Request}.
- """
-
- def setUp(self):
- """
- Create a DigestCredentialFactory for testing
- """
- self.realm = "test realm"
- self.algorithm = "md5"
- self.credentialFactory = digest.DigestCredentialFactory(
- self.algorithm, self.realm)
- self.request = self.makeRequest()
-
-
- def test_decode(self):
- """
- L{digest.DigestCredentialFactory.decode} calls the C{decode} method on
- L{twisted.cred.digest.DigestCredentialFactory} with the HTTP method and
- host of the request.
- """
- host = '169.254.0.1'
- method = 'GET'
- done = [False]
- response = object()
- def check(_response, _method, _host):
- self.assertEqual(response, _response)
- self.assertEqual(method, _method)
- self.assertEqual(host, _host)
- done[0] = True
-
- self.patch(self.credentialFactory.digest, 'decode', check)
- req = self.makeRequest(method, IPv4Address('TCP', host, 81))
- self.credentialFactory.decode(response, req)
- self.assertTrue(done[0])
-
-
- def test_interface(self):
- """
- L{DigestCredentialFactory} implements L{ICredentialFactory}.
- """
- self.assertTrue(
- verifyObject(ICredentialFactory, self.credentialFactory))
-
-
- def test_getChallenge(self):
- """
- The challenge issued by L{DigestCredentialFactory.getChallenge} must
- include C{'qop'}, C{'realm'}, C{'algorithm'}, C{'nonce'}, and
- C{'opaque'} keys. The values for the C{'realm'} and C{'algorithm'}
- keys must match the values supplied to the factory's initializer.
- None of the values may have newlines in them.
- """
- challenge = self.credentialFactory.getChallenge(self.request)
- self.assertEqual(challenge['qop'], 'auth')
- self.assertEqual(challenge['realm'], 'test realm')
- self.assertEqual(challenge['algorithm'], 'md5')
- self.assertIn('nonce', challenge)
- self.assertIn('opaque', challenge)
- for v in challenge.values():
- self.assertNotIn('\n', v)
-
-
- def test_getChallengeWithoutClientIP(self):
- """
- L{DigestCredentialFactory.getChallenge} can issue a challenge even if
- the L{Request} it is passed returns C{None} from C{getClientIP}.
- """
- request = self.makeRequest('GET', None)
- challenge = self.credentialFactory.getChallenge(request)
- self.assertEqual(challenge['qop'], 'auth')
- self.assertEqual(challenge['realm'], 'test realm')
- self.assertEqual(challenge['algorithm'], 'md5')
- self.assertIn('nonce', challenge)
- self.assertIn('opaque', challenge)
-
-
-
-class UnauthorizedResourceTests(unittest.TestCase):
- """
- Tests for L{UnauthorizedResource}.
- """
- def test_getChildWithDefault(self):
- """
- An L{UnauthorizedResource} is every child of itself.
- """
- resource = UnauthorizedResource([])
- self.assertIdentical(
- resource.getChildWithDefault("foo", None), resource)
- self.assertIdentical(
- resource.getChildWithDefault("bar", None), resource)
-
-
- def _unauthorizedRenderTest(self, request):
- """
- Render L{UnauthorizedResource} for the given request object and verify
- that the response code is I{Unauthorized} and that a I{WWW-Authenticate}
- header is set in the response containing a challenge.
- """
- resource = UnauthorizedResource([
- BasicCredentialFactory('example.com')])
- request.render(resource)
- self.assertEqual(request.responseCode, 401)
- self.assertEqual(
- request.responseHeaders.getRawHeaders('www-authenticate'),
- ['basic realm="example.com"'])
-
-
- def test_render(self):
- """
- L{UnauthorizedResource} renders with a 401 response code and a
- I{WWW-Authenticate} header and puts a simple unauthorized message
- into the response body.
- """
- request = DummyRequest([''])
- self._unauthorizedRenderTest(request)
- self.assertEqual('Unauthorized', ''.join(request.written))
-
-
- def test_renderHEAD(self):
- """
- The rendering behavior of L{UnauthorizedResource} for a I{HEAD} request
- is like its handling of a I{GET} request, but no response body is
- written.
- """
- request = DummyRequest([''])
- request.method = 'HEAD'
- self._unauthorizedRenderTest(request)
- self.assertEqual('', ''.join(request.written))
-
-
- def test_renderQuotesRealm(self):
- """
- The realm value included in the I{WWW-Authenticate} header set in
- the response when L{UnauthorizedResounrce} is rendered has quotes
- and backslashes escaped.
- """
- resource = UnauthorizedResource([
- BasicCredentialFactory('example\\"foo')])
- request = DummyRequest([''])
- request.render(resource)
- self.assertEqual(
- request.responseHeaders.getRawHeaders('www-authenticate'),
- ['basic realm="example\\\\\\"foo"'])
-
-
-
-class Realm(object):
- """
- A simple L{IRealm} implementation which gives out L{WebAvatar} for any
- avatarId.
-
- @type loggedIn: C{int}
- @ivar loggedIn: The number of times C{requestAvatar} has been invoked for
- L{IResource}.
-
- @type loggedOut: C{int}
- @ivar loggedOut: The number of times the logout callback has been invoked.
- """
- implements(portal.IRealm)
-
- def __init__(self, avatarFactory):
- self.loggedOut = 0
- self.loggedIn = 0
- self.avatarFactory = avatarFactory
-
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if IResource in interfaces:
- self.loggedIn += 1
- return IResource, self.avatarFactory(avatarId), self.logout
- raise NotImplementedError()
-
-
- def logout(self):
- self.loggedOut += 1
-
-
-
-class HTTPAuthHeaderTests(unittest.TestCase):
- """
- Tests for L{HTTPAuthSessionWrapper}.
- """
- makeRequest = DummyRequest
-
- def setUp(self):
- """
- Create a realm, portal, and L{HTTPAuthSessionWrapper} to use in the tests.
- """
- self.username = 'foo bar'
- self.password = 'bar baz'
- self.avatarContent = "contents of the avatar resource itself"
- self.childName = "foo-child"
- self.childContent = "contents of the foo child of the avatar"
- self.checker = InMemoryUsernamePasswordDatabaseDontUse()
- self.checker.addUser(self.username, self.password)
- self.avatar = Data(self.avatarContent, 'text/plain')
- self.avatar.putChild(
- self.childName, Data(self.childContent, 'text/plain'))
- self.avatars = {self.username: self.avatar}
- self.realm = Realm(self.avatars.get)
- self.portal = portal.Portal(self.realm, [self.checker])
- self.credentialFactories = []
- self.wrapper = HTTPAuthSessionWrapper(
- self.portal, self.credentialFactories)
-
-
- def _authorizedBasicLogin(self, request):
- """
- Add an I{basic authorization} header to the given request and then
- dispatch it, starting from C{self.wrapper} and returning the resulting
- L{IResource}.
- """
- authorization = b64encode(self.username + ':' + self.password)
- request.headers['authorization'] = 'Basic ' + authorization
- return getChildForRequest(self.wrapper, request)
-
-
- def test_getChildWithDefault(self):
- """
- Resource traversal which encounters an L{HTTPAuthSessionWrapper}
- results in an L{UnauthorizedResource} instance when the request does
- not have the required I{Authorization} headers.
- """
- request = self.makeRequest([self.childName])
- child = getChildForRequest(self.wrapper, request)
- d = request.notifyFinish()
- def cbFinished(result):
- self.assertEqual(request.responseCode, 401)
- d.addCallback(cbFinished)
- request.render(child)
- return d
-
-
- def _invalidAuthorizationTest(self, response):
- """
- Create a request with the given value as the value of an
- I{Authorization} header and perform resource traversal with it,
- starting at C{self.wrapper}. Assert that the result is a 401 response
- code. Return a L{Deferred} which fires when this is all done.
- """
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
- request = self.makeRequest([self.childName])
- request.headers['authorization'] = response
- child = getChildForRequest(self.wrapper, request)
- d = request.notifyFinish()
- def cbFinished(result):
- self.assertEqual(request.responseCode, 401)
- d.addCallback(cbFinished)
- request.render(child)
- return d
-
-
- def test_getChildWithDefaultUnauthorizedUser(self):
- """
- Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
- results in an L{UnauthorizedResource} when the request has an
- I{Authorization} header with a user which does not exist.
- """
- return self._invalidAuthorizationTest('Basic ' + b64encode('foo:bar'))
-
-
- def test_getChildWithDefaultUnauthorizedPassword(self):
- """
- Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
- results in an L{UnauthorizedResource} when the request has an
- I{Authorization} header with a user which exists and the wrong
- password.
- """
- return self._invalidAuthorizationTest(
- 'Basic ' + b64encode(self.username + ':bar'))
-
-
- def test_getChildWithDefaultUnrecognizedScheme(self):
- """
- Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
- results in an L{UnauthorizedResource} when the request has an
- I{Authorization} header with an unrecognized scheme.
- """
- return self._invalidAuthorizationTest('Quux foo bar baz')
-
-
- def test_getChildWithDefaultAuthorized(self):
- """
- Resource traversal which encounters an L{HTTPAuthSessionWrapper}
- results in an L{IResource} which renders the L{IResource} avatar
- retrieved from the portal when the request has a valid I{Authorization}
- header.
- """
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
- request = self.makeRequest([self.childName])
- child = self._authorizedBasicLogin(request)
- d = request.notifyFinish()
- def cbFinished(ignored):
- self.assertEqual(request.written, [self.childContent])
- d.addCallback(cbFinished)
- request.render(child)
- return d
-
-
- def test_renderAuthorized(self):
- """
- Resource traversal which terminates at an L{HTTPAuthSessionWrapper}
- and includes correct authentication headers results in the
- L{IResource} avatar (not one of its children) retrieved from the
- portal being rendered.
- """
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
- # Request it exactly, not any of its children.
- request = self.makeRequest([])
- child = self._authorizedBasicLogin(request)
- d = request.notifyFinish()
- def cbFinished(ignored):
- self.assertEqual(request.written, [self.avatarContent])
- d.addCallback(cbFinished)
- request.render(child)
- return d
-
-
- def test_getChallengeCalledWithRequest(self):
- """
- When L{HTTPAuthSessionWrapper} finds an L{ICredentialFactory} to issue
- a challenge, it calls the C{getChallenge} method with the request as an
- argument.
- """
- class DumbCredentialFactory(object):
- implements(ICredentialFactory)
- scheme = 'dumb'
-
- def __init__(self):
- self.requests = []
-
- def getChallenge(self, request):
- self.requests.append(request)
- return {}
-
- factory = DumbCredentialFactory()
- self.credentialFactories.append(factory)
- request = self.makeRequest([self.childName])
- child = getChildForRequest(self.wrapper, request)
- d = request.notifyFinish()
- def cbFinished(ignored):
- self.assertEqual(factory.requests, [request])
- d.addCallback(cbFinished)
- request.render(child)
- return d
-
-
- def _logoutTest(self):
- """
- Issue a request for an authentication-protected resource using valid
- credentials and then return the C{DummyRequest} instance which was
- used.
-
- This is a helper for tests about the behavior of the logout
- callback.
- """
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
-
- class SlowerResource(Resource):
- def render(self, request):
- return NOT_DONE_YET
-
- self.avatar.putChild(self.childName, SlowerResource())
- request = self.makeRequest([self.childName])
- child = self._authorizedBasicLogin(request)
- request.render(child)
- self.assertEqual(self.realm.loggedOut, 0)
- return request
-
-
- def test_logout(self):
- """
- The realm's logout callback is invoked after the resource is rendered.
- """
- request = self._logoutTest()
- request.finish()
- self.assertEqual(self.realm.loggedOut, 1)
-
-
- def test_logoutOnError(self):
- """
- The realm's logout callback is also invoked if there is an error
- generating the response (for example, if the client disconnects
- early).
- """
- request = self._logoutTest()
- request.processingFailed(
- Failure(ConnectionDone("Simulated disconnect")))
- self.assertEqual(self.realm.loggedOut, 1)
-
-
- def test_decodeRaises(self):
- """
- Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
- results in an L{UnauthorizedResource} when the request has a I{Basic
- Authorization} header which cannot be decoded using base64.
- """
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
- request = self.makeRequest([self.childName])
- request.headers['authorization'] = 'Basic decode should fail'
- child = getChildForRequest(self.wrapper, request)
- self.assertIsInstance(child, UnauthorizedResource)
-
-
- def test_selectParseResponse(self):
- """
- L{HTTPAuthSessionWrapper._selectParseHeader} returns a two-tuple giving
- the L{ICredentialFactory} to use to parse the header and a string
- containing the portion of the header which remains to be parsed.
- """
- basicAuthorization = 'Basic abcdef123456'
- self.assertEqual(
- self.wrapper._selectParseHeader(basicAuthorization),
- (None, None))
- factory = BasicCredentialFactory('example.com')
- self.credentialFactories.append(factory)
- self.assertEqual(
- self.wrapper._selectParseHeader(basicAuthorization),
- (factory, 'abcdef123456'))
-
-
- def test_unexpectedDecodeError(self):
- """
- Any unexpected exception raised by the credential factory's C{decode}
- method results in a 500 response code and causes the exception to be
- logged.
- """
- class UnexpectedException(Exception):
- pass
-
- class BadFactory(object):
- scheme = 'bad'
-
- def getChallenge(self, client):
- return {}
-
- def decode(self, response, request):
- raise UnexpectedException()
-
- self.credentialFactories.append(BadFactory())
- request = self.makeRequest([self.childName])
- request.headers['authorization'] = 'Bad abc'
- child = getChildForRequest(self.wrapper, request)
- request.render(child)
- self.assertEqual(request.responseCode, 500)
- self.assertEqual(len(self.flushLoggedErrors(UnexpectedException)), 1)
-
-
- def test_unexpectedLoginError(self):
- """
- Any unexpected failure from L{Portal.login} results in a 500 response
- code and causes the failure to be logged.
- """
- class UnexpectedException(Exception):
- pass
-
- class BrokenChecker(object):
- credentialInterfaces = (IUsernamePassword,)
-
- def requestAvatarId(self, credentials):
- raise UnexpectedException()
-
- self.portal.registerChecker(BrokenChecker())
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
- request = self.makeRequest([self.childName])
- child = self._authorizedBasicLogin(request)
- request.render(child)
- self.assertEqual(request.responseCode, 500)
- self.assertEqual(len(self.flushLoggedErrors(UnexpectedException)), 1)
-
-
- def test_anonymousAccess(self):
- """
- Anonymous requests are allowed if a L{Portal} has an anonymous checker
- registered.
- """
- unprotectedContents = "contents of the unprotected child resource"
-
- self.avatars[ANONYMOUS] = Resource()
- self.avatars[ANONYMOUS].putChild(
- self.childName, Data(unprotectedContents, 'text/plain'))
- self.portal.registerChecker(AllowAnonymousAccess())
-
- self.credentialFactories.append(BasicCredentialFactory('example.com'))
- request = self.makeRequest([self.childName])
- child = getChildForRequest(self.wrapper, request)
- d = request.notifyFinish()
- def cbFinished(ignored):
- self.assertEqual(request.written, [unprotectedContents])
- d.addCallback(cbFinished)
- request.render(child)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_newclient.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_newclient.py
deleted file mode 100755
index 516d0aa4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_newclient.py
+++ /dev/null
@@ -1,2521 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web._newclient}.
-"""
-
-__metaclass__ = type
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.internet.interfaces import IConsumer, IPushProducer
-from twisted.internet.error import ConnectionDone, ConnectionLost
-from twisted.internet.defer import Deferred, succeed, fail
-from twisted.internet.protocol import Protocol
-from twisted.trial.unittest import TestCase
-from twisted.test.proto_helpers import StringTransport, AccumulatingProtocol
-from twisted.web._newclient import UNKNOWN_LENGTH, STATUS, HEADER, BODY, DONE
-from twisted.web._newclient import Request, Response, HTTPParser, HTTPClientParser
-from twisted.web._newclient import BadResponseVersion, ParseError, HTTP11ClientProtocol
-from twisted.web._newclient import ChunkedEncoder, RequestGenerationFailed
-from twisted.web._newclient import RequestTransmissionFailed, ResponseFailed
-from twisted.web._newclient import WrongBodyLength, RequestNotSent
-from twisted.web._newclient import ConnectionAborted, ResponseNeverReceived
-from twisted.web._newclient import BadHeaders, ResponseDone, PotentialDataLoss, ExcessWrite
-from twisted.web._newclient import TransportProxyProducer, LengthEnforcingConsumer, makeStatefulDispatcher
-from twisted.web.http_headers import Headers
-from twisted.web.http import _DataLoss
-from twisted.web.iweb import IBodyProducer, IResponse
-
-
-
-class ArbitraryException(Exception):
- """
- A unique, arbitrary exception type which L{twisted.web._newclient} knows
- nothing about.
- """
-
-
-class AnotherArbitraryException(Exception):
- """
- Similar to L{ArbitraryException} but with a different identity.
- """
-
-
-# A re-usable Headers instance for tests which don't really care what headers
-# they're sending.
-_boringHeaders = Headers({'host': ['example.com']})
-
-
-def assertWrapperExceptionTypes(self, deferred, mainType, reasonTypes):
- """
- Assert that the given L{Deferred} fails with the exception given by
- C{mainType} and that the exceptions wrapped by the instance of C{mainType}
- it fails with match the list of exception types given by C{reasonTypes}.
-
- This is a helper for testing failures of exceptions which subclass
- L{_newclient._WrapperException}.
-
- @param self: A L{TestCase} instance which will be used to make the
- assertions.
-
- @param deferred: The L{Deferred} which is expected to fail with
- C{mainType}.
-
- @param mainType: A L{_newclient._WrapperException} subclass which will be
- trapped on C{deferred}.
-
- @param reasonTypes: A sequence of exception types which will be trapped on
- the resulting L{mainType} exception instance's C{reasons} sequence.
-
- @return: A L{Deferred} which fires with the C{mainType} instance
- C{deferred} fails with, or which fails somehow.
- """
- def cbFailed(err):
- for reason, type in zip(err.reasons, reasonTypes):
- reason.trap(type)
- self.assertEqual(len(err.reasons), len(reasonTypes),
- "len(%s) != len(%s)" % (err.reasons, reasonTypes))
- return err
- d = self.assertFailure(deferred, mainType)
- d.addCallback(cbFailed)
- return d
-
-
-
-def assertResponseFailed(self, deferred, reasonTypes):
- """
- A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
- of L{ResponseFailed}.
- """
- return assertWrapperExceptionTypes(self, deferred, ResponseFailed, reasonTypes)
-
-
-
-def assertRequestGenerationFailed(self, deferred, reasonTypes):
- """
- A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
- of L{RequestGenerationFailed}.
- """
- return assertWrapperExceptionTypes(self, deferred, RequestGenerationFailed, reasonTypes)
-
-
-
-def assertRequestTransmissionFailed(self, deferred, reasonTypes):
- """
- A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
- of L{RequestTransmissionFailed}.
- """
- return assertWrapperExceptionTypes(self, deferred, RequestTransmissionFailed, reasonTypes)
-
-
-
-def justTransportResponse(transport):
- """
- Helper function for creating a Response which uses the given transport.
- All of the other parameters to L{Response.__init__} are filled with
- arbitrary values. Only use this method if you don't care about any of
- them.
- """
- return Response(('HTTP', 1, 1), 200, 'OK', _boringHeaders, transport)
-
-
-class MakeStatefulDispatcherTests(TestCase):
- """
- Tests for L{makeStatefulDispatcher}.
- """
- def test_functionCalledByState(self):
- """
- A method defined with L{makeStatefulDispatcher} invokes a second
- method based on the current state of the object.
- """
- class Foo:
- _state = 'A'
-
- def bar(self):
- pass
- bar = makeStatefulDispatcher('quux', bar)
-
- def _quux_A(self):
- return 'a'
-
- def _quux_B(self):
- return 'b'
-
- stateful = Foo()
- self.assertEqual(stateful.bar(), 'a')
- stateful._state = 'B'
- self.assertEqual(stateful.bar(), 'b')
- stateful._state = 'C'
- self.assertRaises(RuntimeError, stateful.bar)
-
-
-
-class _HTTPParserTests(object):
- """
- Base test class for L{HTTPParser} which is responsible for the bulk of
- the task of parsing HTTP bytes.
- """
- sep = None
-
- def test_statusCallback(self):
- """
- L{HTTPParser} calls its C{statusReceived} method when it receives a
- status line.
- """
- status = []
- protocol = HTTPParser()
- protocol.statusReceived = status.append
- protocol.makeConnection(StringTransport())
- self.assertEqual(protocol.state, STATUS)
- protocol.dataReceived('HTTP/1.1 200 OK' + self.sep)
- self.assertEqual(status, ['HTTP/1.1 200 OK'])
- self.assertEqual(protocol.state, HEADER)
-
-
- def _headerTestSetup(self):
- header = {}
- protocol = HTTPParser()
- protocol.headerReceived = header.__setitem__
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK' + self.sep)
- return header, protocol
-
-
- def test_headerCallback(self):
- """
- L{HTTPParser} calls its C{headerReceived} method when it receives a
- header.
- """
- header, protocol = self._headerTestSetup()
- protocol.dataReceived('X-Foo:bar' + self.sep)
- # Cannot tell it's not a continue header until the next line arrives
- # and is not a continuation
- protocol.dataReceived(self.sep)
- self.assertEqual(header, {'X-Foo': 'bar'})
- self.assertEqual(protocol.state, BODY)
-
-
- def test_continuedHeaderCallback(self):
- """
- If a header is split over multiple lines, L{HTTPParser} calls
- C{headerReceived} with the entire value once it is received.
- """
- header, protocol = self._headerTestSetup()
- protocol.dataReceived('X-Foo: bar' + self.sep)
- protocol.dataReceived(' baz' + self.sep)
- protocol.dataReceived('\tquux' + self.sep)
- protocol.dataReceived(self.sep)
- self.assertEqual(header, {'X-Foo': 'bar baz\tquux'})
- self.assertEqual(protocol.state, BODY)
-
-
- def test_fieldContentWhitespace(self):
- """
- Leading and trailing linear whitespace is stripped from the header
- value passed to the C{headerReceived} callback.
- """
- header, protocol = self._headerTestSetup()
- value = ' \t %(sep)s bar \t%(sep)s \t%(sep)s' % dict(sep=self.sep)
- protocol.dataReceived('X-Bar:' + value)
- protocol.dataReceived('X-Foo:' + value)
- protocol.dataReceived(self.sep)
- self.assertEqual(header, {'X-Foo': 'bar',
- 'X-Bar': 'bar'})
-
-
- def test_allHeadersCallback(self):
- """
- After the last header is received, L{HTTPParser} calls
- C{allHeadersReceived}.
- """
- called = []
- header, protocol = self._headerTestSetup()
- def allHeadersReceived():
- called.append(protocol.state)
- protocol.state = STATUS
- protocol.allHeadersReceived = allHeadersReceived
- protocol.dataReceived(self.sep)
- self.assertEqual(called, [HEADER])
- self.assertEqual(protocol.state, STATUS)
-
-
- def test_noHeaderCallback(self):
- """
- If there are no headers in the message, L{HTTPParser} does not call
- C{headerReceived}.
- """
- header, protocol = self._headerTestSetup()
- protocol.dataReceived(self.sep)
- self.assertEqual(header, {})
- self.assertEqual(protocol.state, BODY)
-
-
- def test_headersSavedOnResponse(self):
- """
- All headers received by L{HTTPParser} are added to
- L{HTTPParser.headers}.
- """
- protocol = HTTPParser()
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK' + self.sep)
- protocol.dataReceived('X-Foo: bar' + self.sep)
- protocol.dataReceived('X-Foo: baz' + self.sep)
- protocol.dataReceived(self.sep)
- expected = [('X-Foo', ['bar', 'baz'])]
- self.assertEqual(expected, list(protocol.headers.getAllRawHeaders()))
-
-
- def test_connectionControlHeaders(self):
- """
- L{HTTPParser.isConnectionControlHeader} returns C{True} for headers
- which are always connection control headers (similar to "hop-by-hop"
- headers from RFC 2616 section 13.5.1) and C{False} for other headers.
- """
- protocol = HTTPParser()
- connHeaderNames = [
- 'content-length', 'connection', 'keep-alive', 'te', 'trailers',
- 'transfer-encoding', 'upgrade', 'proxy-connection']
-
- for header in connHeaderNames:
- self.assertTrue(
- protocol.isConnectionControlHeader(header),
- "Expecting %r to be a connection control header, but "
- "wasn't" % (header,))
- self.assertFalse(
- protocol.isConnectionControlHeader("date"),
- "Expecting the arbitrarily selected 'date' header to not be "
- "a connection control header, but was.")
-
-
- def test_switchToBodyMode(self):
- """
- L{HTTPParser.switchToBodyMode} raises L{RuntimeError} if called more
- than once.
- """
- protocol = HTTPParser()
- protocol.makeConnection(StringTransport())
- protocol.switchToBodyMode(object())
- self.assertRaises(RuntimeError, protocol.switchToBodyMode, object())
-
-
-
-class HTTPParserTestsRFCComplaintDelimeter(_HTTPParserTests, TestCase):
- """
- L{_HTTPParserTests} using standard CR LF newlines.
- """
- sep = '\r\n'
-
-
-
-class HTTPParserTestsNonRFCComplaintDelimeter(_HTTPParserTests, TestCase):
- """
- L{_HTTPParserTests} using bare LF newlines.
- """
- sep = '\n'
-
-
-
-class HTTPClientParserTests(TestCase):
- """
- Tests for L{HTTPClientParser} which is responsible for parsing HTTP
- response messages.
- """
- def test_parseVersion(self):
- """
- L{HTTPClientParser.parseVersion} parses a status line into its three
- components.
- """
- protocol = HTTPClientParser(None, None)
- self.assertEqual(
- protocol.parseVersion('CANDY/7.2'),
- ('CANDY', 7, 2))
-
-
- def test_parseBadVersion(self):
- """
- L{HTTPClientParser.parseVersion} raises L{ValueError} when passed an
- unparsable version.
- """
- protocol = HTTPClientParser(None, None)
- e = BadResponseVersion
- f = protocol.parseVersion
-
- def checkParsing(s):
- exc = self.assertRaises(e, f, s)
- self.assertEqual(exc.data, s)
-
- checkParsing('foo')
- checkParsing('foo/bar/baz')
-
- checkParsing('foo/')
- checkParsing('foo/..')
-
- checkParsing('foo/a.b')
- checkParsing('foo/-1.-1')
-
-
- def test_responseStatusParsing(self):
- """
- L{HTTPClientParser.statusReceived} parses the version, code, and phrase
- from the status line and stores them on the response object.
- """
- request = Request('GET', '/', _boringHeaders, None)
- protocol = HTTPClientParser(request, None)
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- self.assertEqual(protocol.response.version, ('HTTP', 1, 1))
- self.assertEqual(protocol.response.code, 200)
- self.assertEqual(protocol.response.phrase, 'OK')
-
-
- def test_badResponseStatus(self):
- """
- L{HTTPClientParser.statusReceived} raises L{ParseError} if it is called
- with a status line which cannot be parsed.
- """
- protocol = HTTPClientParser(None, None)
-
- def checkParsing(s):
- exc = self.assertRaises(ParseError, protocol.statusReceived, s)
- self.assertEqual(exc.data, s)
-
- # If there are fewer than three whitespace-delimited parts to the
- # status line, it is not valid and cannot be parsed.
- checkParsing('foo')
- checkParsing('HTTP/1.1 200')
-
- # If the response code is not an integer, the status line is not valid
- # and cannot be parsed.
- checkParsing('HTTP/1.1 bar OK')
-
-
- def _noBodyTest(self, request, response):
- """
- Assert that L{HTTPClientParser} parses the given C{response} to
- C{request}, resulting in a response with no body and no extra bytes and
- leaving the transport in the producing state.
-
- @param request: A L{Request} instance which might have caused a server
- to return the given response.
- @param response: A string giving the response to be parsed.
-
- @return: A C{dict} of headers from the response.
- """
- header = {}
- finished = []
- protocol = HTTPClientParser(request, finished.append)
- protocol.headerReceived = header.__setitem__
- body = []
- protocol._bodyDataReceived = body.append
- transport = StringTransport()
- protocol.makeConnection(transport)
- protocol.dataReceived(response)
- self.assertEqual(transport.producerState, 'producing')
- self.assertEqual(protocol.state, DONE)
- self.assertEqual(body, [])
- self.assertEqual(finished, [''])
- self.assertEqual(protocol.response.length, 0)
- return header
-
-
- def test_headResponse(self):
- """
- If the response is to a HEAD request, no body is expected, the body
- callback is not invoked, and the I{Content-Length} header is passed to
- the header callback.
- """
- request = Request('HEAD', '/', _boringHeaders, None)
- status = (
- 'HTTP/1.1 200 OK\r\n'
- 'Content-Length: 10\r\n'
- '\r\n')
- header = self._noBodyTest(request, status)
- self.assertEqual(header, {'Content-Length': '10'})
-
-
- def test_noContentResponse(self):
- """
- If the response code is I{NO CONTENT} (204), no body is expected and
- the body callback is not invoked.
- """
- request = Request('GET', '/', _boringHeaders, None)
- status = (
- 'HTTP/1.1 204 NO CONTENT\r\n'
- '\r\n')
- self._noBodyTest(request, status)
-
-
- def test_notModifiedResponse(self):
- """
- If the response code is I{NOT MODIFIED} (304), no body is expected and
- the body callback is not invoked.
- """
- request = Request('GET', '/', _boringHeaders, None)
- status = (
- 'HTTP/1.1 304 NOT MODIFIED\r\n'
- '\r\n')
- self._noBodyTest(request, status)
-
-
- def test_responseHeaders(self):
- """
- The response headers are added to the response object's C{headers}
- L{Headers} instance.
- """
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- lambda rest: None)
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- protocol.dataReceived('X-Foo: bar\r\n')
- protocol.dataReceived('\r\n')
- self.assertEqual(
- protocol.connHeaders,
- Headers({}))
- self.assertEqual(
- protocol.response.headers,
- Headers({'x-foo': ['bar']}))
- self.assertIdentical(protocol.response.length, UNKNOWN_LENGTH)
-
-
- def test_connectionHeaders(self):
- """
- The connection control headers are added to the parser's C{connHeaders}
- L{Headers} instance.
- """
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- lambda rest: None)
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- protocol.dataReceived('Content-Length: 123\r\n')
- protocol.dataReceived('Connection: close\r\n')
- protocol.dataReceived('\r\n')
- self.assertEqual(
- protocol.response.headers,
- Headers({}))
- self.assertEqual(
- protocol.connHeaders,
- Headers({'content-length': ['123'],
- 'connection': ['close']}))
- self.assertEqual(protocol.response.length, 123)
-
-
- def test_headResponseContentLengthEntityHeader(self):
- """
- If a HEAD request is made, the I{Content-Length} header in the response
- is added to the response headers, not the connection control headers.
- """
- protocol = HTTPClientParser(
- Request('HEAD', '/', _boringHeaders, None),
- lambda rest: None)
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- protocol.dataReceived('Content-Length: 123\r\n')
- protocol.dataReceived('\r\n')
- self.assertEqual(
- protocol.response.headers,
- Headers({'content-length': ['123']}))
- self.assertEqual(
- protocol.connHeaders,
- Headers({}))
- self.assertEqual(protocol.response.length, 0)
-
-
- def test_contentLength(self):
- """
- If a response includes a body with a length given by the
- I{Content-Length} header, the bytes which make up the body are passed
- to the C{_bodyDataReceived} callback on the L{HTTPParser}.
- """
- finished = []
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- finished.append)
- transport = StringTransport()
- protocol.makeConnection(transport)
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- body = []
- protocol.response._bodyDataReceived = body.append
- protocol.dataReceived('Content-Length: 10\r\n')
- protocol.dataReceived('\r\n')
-
- # Incidentally, the transport should be paused now. It is the response
- # object's responsibility to resume this when it is ready for bytes.
- self.assertEqual(transport.producerState, 'paused')
-
- self.assertEqual(protocol.state, BODY)
- protocol.dataReceived('x' * 6)
- self.assertEqual(body, ['x' * 6])
- self.assertEqual(protocol.state, BODY)
- protocol.dataReceived('y' * 4)
- self.assertEqual(body, ['x' * 6, 'y' * 4])
- self.assertEqual(protocol.state, DONE)
- self.assertTrue(finished, [''])
-
-
- def test_zeroContentLength(self):
- """
- If a response includes a I{Content-Length} header indicating zero bytes
- in the response, L{Response.length} is set accordingly and no data is
- delivered to L{Response._bodyDataReceived}.
- """
- finished = []
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- finished.append)
-
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
-
- body = []
- protocol.response._bodyDataReceived = body.append
-
- protocol.dataReceived('Content-Length: 0\r\n')
- protocol.dataReceived('\r\n')
-
- self.assertEqual(protocol.state, DONE)
- self.assertEqual(body, [])
- self.assertTrue(finished, [''])
- self.assertEqual(protocol.response.length, 0)
-
-
-
- def test_multipleContentLengthHeaders(self):
- """
- If a response includes multiple I{Content-Length} headers,
- L{HTTPClientParser.dataReceived} raises L{ValueError} to indicate that
- the response is invalid and the transport is now unusable.
- """
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- None)
-
- protocol.makeConnection(StringTransport())
- self.assertRaises(
- ValueError,
- protocol.dataReceived,
- 'HTTP/1.1 200 OK\r\n'
- 'Content-Length: 1\r\n'
- 'Content-Length: 2\r\n'
- '\r\n')
-
-
- def test_extraBytesPassedBack(self):
- """
- If extra bytes are received past the end of a response, they are passed
- to the finish callback.
- """
- finished = []
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- finished.append)
-
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- protocol.dataReceived('Content-Length: 0\r\n')
- protocol.dataReceived('\r\nHere is another thing!')
- self.assertEqual(protocol.state, DONE)
- self.assertEqual(finished, ['Here is another thing!'])
-
-
- def test_extraBytesPassedBackHEAD(self):
- """
- If extra bytes are received past the end of the headers of a response
- to a HEAD request, they are passed to the finish callback.
- """
- finished = []
- protocol = HTTPClientParser(
- Request('HEAD', '/', _boringHeaders, None),
- finished.append)
-
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
- protocol.dataReceived('Content-Length: 12\r\n')
- protocol.dataReceived('\r\nHere is another thing!')
- self.assertEqual(protocol.state, DONE)
- self.assertEqual(finished, ['Here is another thing!'])
-
-
- def test_chunkedResponseBody(self):
- """
- If the response headers indicate the response body is encoded with the
- I{chunked} transfer encoding, the body is decoded according to that
- transfer encoding before being passed to L{Response._bodyDataReceived}.
- """
- finished = []
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None),
- finished.append)
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
-
- body = []
- protocol.response._bodyDataReceived = body.append
-
- protocol.dataReceived('Transfer-Encoding: chunked\r\n')
- protocol.dataReceived('\r\n')
-
- # No data delivered yet
- self.assertEqual(body, [])
-
- # Cannot predict the length of a chunked encoded response body.
- self.assertIdentical(protocol.response.length, UNKNOWN_LENGTH)
-
- # Deliver some chunks and make sure the data arrives
- protocol.dataReceived('3\r\na')
- self.assertEqual(body, ['a'])
- protocol.dataReceived('bc\r\n')
- self.assertEqual(body, ['a', 'bc'])
-
- # The response's _bodyDataFinished method should be called when the last
- # chunk is received. Extra data should be passed to the finished
- # callback.
- protocol.dataReceived('0\r\n\r\nextra')
- self.assertEqual(finished, ['extra'])
-
-
- def test_unknownContentLength(self):
- """
- If a response does not include a I{Transfer-Encoding} or a
- I{Content-Length}, the end of response body is indicated by the
- connection being closed.
- """
- finished = []
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None), finished.append)
- transport = StringTransport()
- protocol.makeConnection(transport)
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
-
- body = []
- protocol.response._bodyDataReceived = body.append
-
- protocol.dataReceived('\r\n')
- protocol.dataReceived('foo')
- protocol.dataReceived('bar')
- self.assertEqual(body, ['foo', 'bar'])
- protocol.connectionLost(ConnectionDone("simulated end of connection"))
- self.assertEqual(finished, [''])
-
-
- def test_contentLengthAndTransferEncoding(self):
- """
- According to RFC 2616, section 4.4, point 3, if I{Content-Length} and
- I{Transfer-Encoding: chunked} are present, I{Content-Length} MUST be
- ignored
- """
- finished = []
- protocol = HTTPClientParser(
- Request('GET', '/', _boringHeaders, None), finished.append)
- transport = StringTransport()
- protocol.makeConnection(transport)
- protocol.dataReceived('HTTP/1.1 200 OK\r\n')
-
- body = []
- protocol.response._bodyDataReceived = body.append
-
- protocol.dataReceived(
- 'Content-Length: 102\r\n'
- 'Transfer-Encoding: chunked\r\n'
- '\r\n'
- '3\r\n'
- 'abc\r\n'
- '0\r\n'
- '\r\n')
-
- self.assertEqual(body, ['abc'])
- self.assertEqual(finished, [''])
-
-
- def test_connectionLostBeforeBody(self):
- """
- If L{HTTPClientParser.connectionLost} is called before the headers are
- finished, the C{_responseDeferred} is fired with the L{Failure} passed
- to C{connectionLost}.
- """
- transport = StringTransport()
- protocol = HTTPClientParser(Request('GET', '/', _boringHeaders, None), None)
- protocol.makeConnection(transport)
- # Grab this here because connectionLost gets rid of the attribute
- responseDeferred = protocol._responseDeferred
- protocol.connectionLost(Failure(ArbitraryException()))
-
- return assertResponseFailed(
- self, responseDeferred, [ArbitraryException])
-
-
- def test_connectionLostWithError(self):
- """
- If one of the L{Response} methods called by
- L{HTTPClientParser.connectionLost} raises an exception, the exception
- is logged and not re-raised.
- """
- transport = StringTransport()
- protocol = HTTPClientParser(Request('GET', '/', _boringHeaders, None),
- None)
- protocol.makeConnection(transport)
-
- response = []
- protocol._responseDeferred.addCallback(response.append)
- protocol.dataReceived(
- 'HTTP/1.1 200 OK\r\n'
- 'Content-Length: 1\r\n'
- '\r\n')
- response = response[0]
-
- # Arrange for an exception
- def fakeBodyDataFinished(err=None):
- raise ArbitraryException()
- response._bodyDataFinished = fakeBodyDataFinished
-
- protocol.connectionLost(None)
-
- self.assertEqual(len(self.flushLoggedErrors(ArbitraryException)), 1)
-
-
- def test_noResponseAtAll(self):
- """
- If no response at all was received and the connection is lost, the
- resulting error is L{ResponseNeverReceived}.
- """
- protocol = HTTPClientParser(
- Request('HEAD', '/', _boringHeaders, None),
- lambda ign: None)
- d = protocol._responseDeferred
-
- protocol.makeConnection(StringTransport())
- protocol.connectionLost(ConnectionLost())
- return self.assertFailure(d, ResponseNeverReceived)
-
-
- def test_someResponseButNotAll(self):
- """
- If a partial response was received and the connection is lost, the
- resulting error is L{ResponseFailed}, but not
- L{ResponseNeverReceived}.
- """
- protocol = HTTPClientParser(
- Request('HEAD', '/', _boringHeaders, None),
- lambda ign: None)
- d = protocol._responseDeferred
-
- protocol.makeConnection(StringTransport())
- protocol.dataReceived('2')
- protocol.connectionLost(ConnectionLost())
- return self.assertFailure(d, ResponseFailed).addCallback(
- self.assertIsInstance, ResponseFailed)
-
-
-
-class SlowRequest:
- """
- L{SlowRequest} is a fake implementation of L{Request} which is easily
- controlled externally (for example, by code in a test method).
-
- @ivar stopped: A flag indicating whether C{stopWriting} has been called.
-
- @ivar finished: After C{writeTo} is called, a L{Deferred} which was
- returned by that method. L{SlowRequest} will never fire this
- L{Deferred}.
- """
- method = 'GET'
- stopped = False
- persistent = False
-
- def writeTo(self, transport):
- self.finished = Deferred()
- return self.finished
-
-
- def stopWriting(self):
- self.stopped = True
-
-
-
-class SimpleRequest:
- """
- L{SimpleRequest} is a fake implementation of L{Request} which writes a
- short, fixed string to the transport passed to its C{writeTo} method and
- returns a succeeded L{Deferred}. This vaguely emulates the behavior of a
- L{Request} with no body producer.
- """
- persistent = False
-
- def writeTo(self, transport):
- transport.write('SOME BYTES')
- return succeed(None)
-
-
-
-class HTTP11ClientProtocolTests(TestCase):
- """
- Tests for the HTTP 1.1 client protocol implementation,
- L{HTTP11ClientProtocol}.
- """
- def setUp(self):
- """
- Create an L{HTTP11ClientProtocol} connected to a fake transport.
- """
- self.transport = StringTransport()
- self.protocol = HTTP11ClientProtocol()
- self.protocol.makeConnection(self.transport)
-
-
- def test_request(self):
- """
- L{HTTP11ClientProtocol.request} accepts a L{Request} and calls its
- C{writeTo} method with its own transport.
- """
- self.protocol.request(SimpleRequest())
- self.assertEqual(self.transport.value(), 'SOME BYTES')
-
-
- def test_secondRequest(self):
- """
- The second time L{HTTP11ClientProtocol.request} is called, it returns a
- L{Deferred} which immediately fires with a L{Failure} wrapping a
- L{RequestNotSent} exception.
- """
- self.protocol.request(SlowRequest())
- def cbNotSent(ignored):
- self.assertEqual(self.transport.value(), '')
- d = self.assertFailure(
- self.protocol.request(SimpleRequest()), RequestNotSent)
- d.addCallback(cbNotSent)
- return d
-
-
- def test_requestAfterConnectionLost(self):
- """
- L{HTTP11ClientProtocol.request} returns a L{Deferred} which immediately
- fires with a L{Failure} wrapping a L{RequestNotSent} if called after
- the protocol has been disconnected.
- """
- self.protocol.connectionLost(
- Failure(ConnectionDone("sad transport")))
- def cbNotSent(ignored):
- self.assertEqual(self.transport.value(), '')
- d = self.assertFailure(
- self.protocol.request(SimpleRequest()), RequestNotSent)
- d.addCallback(cbNotSent)
- return d
-
-
- def test_failedWriteTo(self):
- """
- If the L{Deferred} returned by L{Request.writeTo} fires with a
- L{Failure}, L{HTTP11ClientProtocol.request} disconnects its transport
- and returns a L{Deferred} which fires with a L{Failure} of
- L{RequestGenerationFailed} wrapping the underlying failure.
- """
- class BrokenRequest:
- persistent = False
- def writeTo(self, transport):
- return fail(ArbitraryException())
-
- d = self.protocol.request(BrokenRequest())
- def cbFailed(ignored):
- self.assertTrue(self.transport.disconnecting)
- # Simulate what would happen if the protocol had a real transport
- # and make sure no exception is raised.
- self.protocol.connectionLost(
- Failure(ConnectionDone("you asked for it")))
- d = assertRequestGenerationFailed(self, d, [ArbitraryException])
- d.addCallback(cbFailed)
- return d
-
-
- def test_synchronousWriteToError(self):
- """
- If L{Request.writeTo} raises an exception,
- L{HTTP11ClientProtocol.request} returns a L{Deferred} which fires with
- a L{Failure} of L{RequestGenerationFailed} wrapping that exception.
- """
- class BrokenRequest:
- persistent = False
- def writeTo(self, transport):
- raise ArbitraryException()
-
- d = self.protocol.request(BrokenRequest())
- return assertRequestGenerationFailed(self, d, [ArbitraryException])
-
-
- def test_connectionLostDuringRequestGeneration(self, mode=None):
- """
- If L{HTTP11ClientProtocol}'s transport is disconnected before the
- L{Deferred} returned by L{Request.writeTo} fires, the L{Deferred}
- returned by L{HTTP11ClientProtocol.request} fires with a L{Failure} of
- L{RequestTransmissionFailed} wrapping the underlying failure.
- """
- request = SlowRequest()
- d = self.protocol.request(request)
- d = assertRequestTransmissionFailed(self, d, [ArbitraryException])
-
- # The connection hasn't been lost yet. The request should still be
- # allowed to do its thing.
- self.assertFalse(request.stopped)
-
- self.protocol.connectionLost(Failure(ArbitraryException()))
-
- # Now the connection has been lost. The request should have been told
- # to stop writing itself.
- self.assertTrue(request.stopped)
-
- if mode == 'callback':
- request.finished.callback(None)
- elif mode == 'errback':
- request.finished.errback(Failure(AnotherArbitraryException()))
- errors = self.flushLoggedErrors(AnotherArbitraryException)
- self.assertEqual(len(errors), 1)
- else:
- # Don't fire the writeTo Deferred at all.
- pass
- return d
-
-
- def test_connectionLostBeforeGenerationFinished(self):
- """
- If the request passed to L{HTTP11ClientProtocol} finishes generation
- successfully after the L{HTTP11ClientProtocol}'s connection has been
- lost, nothing happens.
- """
- return self.test_connectionLostDuringRequestGeneration('callback')
-
-
- def test_connectionLostBeforeGenerationFailed(self):
- """
- If the request passed to L{HTTP11ClientProtocol} finished generation
- with an error after the L{HTTP11ClientProtocol}'s connection has been
- lost, nothing happens.
- """
- return self.test_connectionLostDuringRequestGeneration('errback')
-
-
- def test_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfuse(self):
- """
- If the request passed to L{HTTP11ClientProtocol} finished generation
- with an error after the L{HTTP11ClientProtocol}'s connection has been
- lost, an error is logged that gives a non-confusing hint to user on what
- went wrong.
- """
- errors = []
- log.addObserver(errors.append)
- self.addCleanup(log.removeObserver, errors.append)
-
- def check(ignore):
- error = errors[0]
- self.assertEqual(error['why'],
- 'Error writing request, but not in valid state '
- 'to finalize request: CONNECTION_LOST')
-
- return self.test_connectionLostDuringRequestGeneration(
- 'errback').addCallback(check)
-
-
- def test_receiveSimplestResponse(self):
- """
- When a response is delivered to L{HTTP11ClientProtocol}, the
- L{Deferred} previously returned by the C{request} method is called back
- with a L{Response} instance and the connection is closed.
- """
- d = self.protocol.request(Request('GET', '/', _boringHeaders, None))
- def cbRequest(response):
- self.assertEqual(response.code, 200)
- self.assertEqual(response.headers, Headers())
- self.assertTrue(self.transport.disconnecting)
- self.assertEqual(self.protocol.state, 'QUIESCENT')
- d.addCallback(cbRequest)
- self.protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-Length: 0\r\n"
- "Connection: close\r\n"
- "\r\n")
- return d
-
-
- def test_receiveResponseHeaders(self):
- """
- The headers included in a response delivered to L{HTTP11ClientProtocol}
- are included on the L{Response} instance passed to the callback
- returned by the C{request} method.
- """
- d = self.protocol.request(Request('GET', '/', _boringHeaders, None))
- def cbRequest(response):
- expected = Headers({'x-foo': ['bar', 'baz']})
- self.assertEqual(response.headers, expected)
- d.addCallback(cbRequest)
- self.protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "X-Foo: bar\r\n"
- "X-Foo: baz\r\n"
- "\r\n")
- return d
-
-
- def test_receiveResponseBeforeRequestGenerationDone(self):
- """
- If response bytes are delivered to L{HTTP11ClientProtocol} before the
- L{Deferred} returned by L{Request.writeTo} fires, those response bytes
- are parsed as part of the response.
-
- The connection is also closed, because we're in a confusing state, and
- therefore the C{quiescentCallback} isn't called.
- """
- quiescentResult = []
- transport = StringTransport()
- protocol = HTTP11ClientProtocol(quiescentResult.append)
- protocol.makeConnection(transport)
-
- request = SlowRequest()
- d = protocol.request(request)
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "X-Foo: bar\r\n"
- "Content-Length: 6\r\n"
- "\r\n"
- "foobar")
- def cbResponse(response):
- p = AccumulatingProtocol()
- whenFinished = p.closedDeferred = Deferred()
- response.deliverBody(p)
- self.assertEqual(
- protocol.state, 'TRANSMITTING_AFTER_RECEIVING_RESPONSE')
- self.assertTrue(transport.disconnecting)
- self.assertEqual(quiescentResult, [])
- return whenFinished.addCallback(
- lambda ign: (response, p.data))
- d.addCallback(cbResponse)
- def cbAllResponse((response, body)):
- self.assertEqual(response.version, ('HTTP', 1, 1))
- self.assertEqual(response.code, 200)
- self.assertEqual(response.phrase, 'OK')
- self.assertEqual(response.headers, Headers({'x-foo': ['bar']}))
- self.assertEqual(body, "foobar")
-
- # Also nothing bad should happen if the request does finally
- # finish, even though it is completely irrelevant.
- request.finished.callback(None)
-
- d.addCallback(cbAllResponse)
- return d
-
-
- def test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone(self):
- """
- If response bytes are delivered to L{HTTP11ClientProtocol} before the
- request completes, calling L{connectionLost} on the protocol will
- result in protocol being moved to C{'CONNECTION_LOST'} state.
- """
- request = SlowRequest()
- d = self.protocol.request(request)
- self.protocol.dataReceived(
- "HTTP/1.1 400 BAD REQUEST\r\n"
- "Content-Length: 9\r\n"
- "\r\n"
- "tisk tisk")
- def cbResponse(response):
- p = AccumulatingProtocol()
- whenFinished = p.closedDeferred = Deferred()
- response.deliverBody(p)
- return whenFinished.addCallback(
- lambda ign: (response, p.data))
- d.addCallback(cbResponse)
- def cbAllResponse(ignore):
- request.finished.callback(None)
- # Nothing dire will happen when the connection is lost
- self.protocol.connectionLost(Failure(ArbitraryException()))
- self.assertEqual(self.protocol._state, 'CONNECTION_LOST')
- d.addCallback(cbAllResponse)
- return d
-
-
- def test_receiveResponseBody(self):
- """
- The C{deliverBody} method of the response object with which the
- L{Deferred} returned by L{HTTP11ClientProtocol.request} fires can be
- used to get the body of the response.
- """
- protocol = AccumulatingProtocol()
- whenFinished = protocol.closedDeferred = Deferred()
- requestDeferred = self.protocol.request(Request('GET', '/', _boringHeaders, None))
-
- self.protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-Length: 6\r\n"
- "\r")
-
- # Here's what's going on: all the response headers have been delivered
- # by this point, so the request Deferred can fire with a Response
- # object. The body is yet to come, but that's okay, because the
- # Response object is how you *get* the body.
- result = []
- requestDeferred.addCallback(result.append)
-
- self.assertEqual(result, [])
- # Deliver the very last byte of the response. It is exactly at this
- # point which the Deferred returned by request should fire.
- self.protocol.dataReceived("\n")
- response = result[0]
-
- response.deliverBody(protocol)
-
- self.protocol.dataReceived("foo")
- self.protocol.dataReceived("bar")
-
- def cbAllResponse(ignored):
- self.assertEqual(protocol.data, "foobar")
- protocol.closedReason.trap(ResponseDone)
- whenFinished.addCallback(cbAllResponse)
- return whenFinished
-
-
- def test_responseBodyFinishedWhenConnectionLostWhenContentLengthIsUnknown(
- self):
- """
- If the length of the response body is unknown, the protocol passed to
- the response's C{deliverBody} method has its C{connectionLost}
- method called with a L{Failure} wrapping a L{PotentialDataLoss}
- exception.
- """
- requestDeferred = self.protocol.request(Request('GET', '/', _boringHeaders, None))
- self.protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "\r\n")
-
- result = []
- requestDeferred.addCallback(result.append)
- response = result[0]
-
- protocol = AccumulatingProtocol()
- response.deliverBody(protocol)
-
- self.protocol.dataReceived("foo")
- self.protocol.dataReceived("bar")
-
- self.assertEqual(protocol.data, "foobar")
- self.protocol.connectionLost(
- Failure(ConnectionDone("low-level transport disconnected")))
-
- protocol.closedReason.trap(PotentialDataLoss)
-
-
- def test_chunkedResponseBodyUnfinishedWhenConnectionLost(self):
- """
- If the final chunk has not been received when the connection is lost
- (for any reason), the protocol passed to C{deliverBody} has its
- C{connectionLost} method called with a L{Failure} wrapping the
- exception for that reason.
- """
- requestDeferred = self.protocol.request(Request('GET', '/', _boringHeaders, None))
- self.protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Transfer-Encoding: chunked\r\n"
- "\r\n")
-
- result = []
- requestDeferred.addCallback(result.append)
- response = result[0]
-
- protocol = AccumulatingProtocol()
- response.deliverBody(protocol)
-
- self.protocol.dataReceived("3\r\nfoo\r\n")
- self.protocol.dataReceived("3\r\nbar\r\n")
-
- self.assertEqual(protocol.data, "foobar")
-
- self.protocol.connectionLost(Failure(ArbitraryException()))
-
- return assertResponseFailed(
- self, fail(protocol.closedReason), [ArbitraryException, _DataLoss])
-
-
- def test_parserDataReceivedException(self):
- """
- If the parser L{HTTP11ClientProtocol} delivers bytes to in
- C{dataReceived} raises an exception, the exception is wrapped in a
- L{Failure} and passed to the parser's C{connectionLost} and then the
- L{HTTP11ClientProtocol}'s transport is disconnected.
- """
- requestDeferred = self.protocol.request(Request('GET', '/', _boringHeaders, None))
- self.protocol.dataReceived('unparseable garbage goes here\r\n')
- d = assertResponseFailed(self, requestDeferred, [ParseError])
- def cbFailed(exc):
- self.assertTrue(self.transport.disconnecting)
- self.assertEqual(
- exc.reasons[0].value.data, 'unparseable garbage goes here')
-
- # Now do what StringTransport doesn't do but a real transport would
- # have, call connectionLost on the HTTP11ClientProtocol. Nothing
- # is asserted about this, but it's important for it to not raise an
- # exception.
- self.protocol.connectionLost(Failure(ConnectionDone("it is done")))
-
- d.addCallback(cbFailed)
- return d
-
-
- def test_proxyStopped(self):
- """
- When the HTTP response parser is disconnected, the
- L{TransportProxyProducer} which was connected to it as a transport is
- stopped.
- """
- requestDeferred = self.protocol.request(Request('GET', '/', _boringHeaders, None))
- transport = self.protocol._parser.transport
- self.assertIdentical(transport._producer, self.transport)
- self.protocol._disconnectParser(Failure(ConnectionDone("connection done")))
- self.assertIdentical(transport._producer, None)
- return assertResponseFailed(self, requestDeferred, [ConnectionDone])
-
-
- def test_abortClosesConnection(self):
- """
- L{HTTP11ClientProtocol.abort} will tell the transport to close its
- connection when it is invoked, and returns a C{Deferred} that fires
- when the connection is lost.
- """
- transport = StringTransport()
- protocol = HTTP11ClientProtocol()
- protocol.makeConnection(transport)
- r1 = []
- r2 = []
- protocol.abort().addCallback(r1.append)
- protocol.abort().addCallback(r2.append)
- self.assertEqual((r1, r2), ([], []))
- self.assertTrue(transport.disconnecting)
-
- # Disconnect protocol, the Deferreds will fire:
- protocol.connectionLost(Failure(ConnectionDone()))
- self.assertEqual(r1, [None])
- self.assertEqual(r2, [None])
-
-
- def test_abortAfterConnectionLost(self):
- """
- L{HTTP11ClientProtocol.abort} called after the connection is lost
- returns a C{Deferred} that fires immediately.
- """
- transport = StringTransport()
- protocol = HTTP11ClientProtocol()
- protocol.makeConnection(transport)
- protocol.connectionLost(Failure(ConnectionDone()))
-
- result = []
- protocol.abort().addCallback(result.append)
- self.assertEqual(result, [None])
- self.assertEqual(protocol._state, "CONNECTION_LOST")
-
-
- def test_abortBeforeResponseBody(self):
- """
- The Deferred returned by L{HTTP11ClientProtocol.request} will fire
- with a L{ResponseFailed} failure containing a L{ConnectionAborted}
- exception, if the connection was aborted before all response headers
- have been received.
- """
- transport = StringTransport()
- protocol = HTTP11ClientProtocol()
- protocol.makeConnection(transport)
- result = protocol.request(Request('GET', '/', _boringHeaders, None))
- protocol.abort()
- self.assertTrue(transport.disconnecting)
- protocol.connectionLost(Failure(ConnectionDone()))
- return assertResponseFailed(self, result, [ConnectionAborted])
-
-
- def test_abortAfterResponseHeaders(self):
- """
- When the connection is aborted after the response headers have
- been received and the L{Response} has been made available to
- application code, the response body protocol's C{connectionLost}
- method will be invoked with a L{ResponseFailed} failure containing a
- L{ConnectionAborted} exception.
- """
- transport = StringTransport()
- protocol = HTTP11ClientProtocol()
- protocol.makeConnection(transport)
- result = protocol.request(Request('GET', '/', _boringHeaders, None))
-
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-Length: 1\r\n"
- "\r\n"
- )
-
- testResult = Deferred()
-
- class BodyDestination(Protocol):
- """
- A body response protocol which immediately aborts the HTTP
- connection.
- """
- def connectionMade(self):
- """
- Abort the HTTP connection.
- """
- protocol.abort()
-
- def connectionLost(self, reason):
- """
- Make the reason for the losing of the connection available to
- the unit test via C{testResult}.
- """
- testResult.errback(reason)
-
-
- def deliverBody(response):
- """
- Connect the L{BodyDestination} response body protocol to the
- response, and then simulate connection loss after ensuring that
- the HTTP connection has been aborted.
- """
- response.deliverBody(BodyDestination())
- self.assertTrue(transport.disconnecting)
- protocol.connectionLost(Failure(ConnectionDone()))
-
-
- def checkError(error):
- self.assertIsInstance(error.response, Response)
-
-
- result.addCallback(deliverBody)
- deferred = assertResponseFailed(self, testResult,
- [ConnectionAborted, _DataLoss])
- return deferred.addCallback(checkError)
-
-
- def test_quiescentCallbackCalled(self):
- """
- If after a response is done the {HTTP11ClientProtocol} stays open and
- returns to QUIESCENT state, all per-request state is reset and the
- C{quiescentCallback} is called with the protocol instance.
-
- This is useful for implementing a persistent connection pool.
-
- The C{quiescentCallback} is called *before* the response-receiving
- protocol's C{connectionLost}, so that new requests triggered by end of
- first request can re-use a persistent connection.
- """
- quiescentResult = []
- def callback(p):
- self.assertEqual(p, protocol)
- self.assertEqual(p.state, "QUIESCENT")
- quiescentResult.append(p)
-
- transport = StringTransport()
- protocol = HTTP11ClientProtocol(callback)
- protocol.makeConnection(transport)
-
- requestDeferred = protocol.request(
- Request('GET', '/', _boringHeaders, None, persistent=True))
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-length: 3\r\n"
- "\r\n")
-
- # Headers done, but still no quiescent callback:
- self.assertEqual(quiescentResult, [])
-
- result = []
- requestDeferred.addCallback(result.append)
- response = result[0]
-
- # When response body is done (i.e. connectionLost is called), note the
- # fact in quiescentResult:
- bodyProtocol = AccumulatingProtocol()
- bodyProtocol.closedDeferred = Deferred()
- bodyProtocol.closedDeferred.addCallback(
- lambda ign: quiescentResult.append("response done"))
-
- response.deliverBody(bodyProtocol)
- protocol.dataReceived("abc")
- bodyProtocol.closedReason.trap(ResponseDone)
- # Quiescent callback called *before* protocol handling the response
- # body gets its connectionLost called:
- self.assertEqual(quiescentResult, [protocol, "response done"])
-
- # Make sure everything was cleaned up:
- self.assertEqual(protocol._parser, None)
- self.assertEqual(protocol._finishedRequest, None)
- self.assertEqual(protocol._currentRequest, None)
- self.assertEqual(protocol._transportProxy, None)
- self.assertEqual(protocol._responseDeferred, None)
-
-
- def test_quiescentCallbackCalledEmptyResponse(self):
- """
- The quiescentCallback is called before the request C{Deferred} fires,
- in cases where the response has no body.
- """
- quiescentResult = []
- def callback(p):
- self.assertEqual(p, protocol)
- self.assertEqual(p.state, "QUIESCENT")
- quiescentResult.append(p)
-
- transport = StringTransport()
- protocol = HTTP11ClientProtocol(callback)
- protocol.makeConnection(transport)
-
- requestDeferred = protocol.request(
- Request('GET', '/', _boringHeaders, None, persistent=True))
- requestDeferred.addCallback(quiescentResult.append)
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-length: 0\r\n"
- "\r\n")
-
- self.assertEqual(len(quiescentResult), 2)
- self.assertIdentical(quiescentResult[0], protocol)
- self.assertIsInstance(quiescentResult[1], Response)
-
-
- def test_quiescentCallbackNotCalled(self):
- """
- If after a response is done the {HTTP11ClientProtocol} returns a
- C{Connection: close} header in the response, the C{quiescentCallback}
- is not called and the connection is lost.
- """
- quiescentResult = []
- transport = StringTransport()
- protocol = HTTP11ClientProtocol(quiescentResult.append)
- protocol.makeConnection(transport)
-
- requestDeferred = protocol.request(
- Request('GET', '/', _boringHeaders, None, persistent=True))
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-length: 0\r\n"
- "Connection: close\r\n"
- "\r\n")
-
- result = []
- requestDeferred.addCallback(result.append)
- response = result[0]
-
- bodyProtocol = AccumulatingProtocol()
- response.deliverBody(bodyProtocol)
- bodyProtocol.closedReason.trap(ResponseDone)
- self.assertEqual(quiescentResult, [])
- self.assertTrue(transport.disconnecting)
-
-
- def test_quiescentCallbackNotCalledNonPersistentQuery(self):
- """
- If the request was non-persistent (i.e. sent C{Connection: close}),
- the C{quiescentCallback} is not called and the connection is lost.
- """
- quiescentResult = []
- transport = StringTransport()
- protocol = HTTP11ClientProtocol(quiescentResult.append)
- protocol.makeConnection(transport)
-
- requestDeferred = protocol.request(
- Request('GET', '/', _boringHeaders, None, persistent=False))
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-length: 0\r\n"
- "\r\n")
-
- result = []
- requestDeferred.addCallback(result.append)
- response = result[0]
-
- bodyProtocol = AccumulatingProtocol()
- response.deliverBody(bodyProtocol)
- bodyProtocol.closedReason.trap(ResponseDone)
- self.assertEqual(quiescentResult, [])
- self.assertTrue(transport.disconnecting)
-
-
- def test_quiescentCallbackThrows(self):
- """
- If C{quiescentCallback} throws an exception, the error is logged and
- protocol is disconnected.
- """
- def callback(p):
- raise ZeroDivisionError()
-
- transport = StringTransport()
- protocol = HTTP11ClientProtocol(callback)
- protocol.makeConnection(transport)
-
- requestDeferred = protocol.request(
- Request('GET', '/', _boringHeaders, None, persistent=True))
- protocol.dataReceived(
- "HTTP/1.1 200 OK\r\n"
- "Content-length: 0\r\n"
- "\r\n")
-
- result = []
- requestDeferred.addCallback(result.append)
- response = result[0]
- bodyProtocol = AccumulatingProtocol()
- response.deliverBody(bodyProtocol)
- bodyProtocol.closedReason.trap(ResponseDone)
-
- errors = self.flushLoggedErrors(ZeroDivisionError)
- self.assertEqual(len(errors), 1)
- self.assertTrue(transport.disconnecting)
-
-
-
-class StringProducer:
- """
- L{StringProducer} is a dummy body producer.
-
- @ivar stopped: A flag which indicates whether or not C{stopProducing} has
- been called.
- @ivar consumer: After C{startProducing} is called, the value of the
- C{consumer} argument to that method.
- @ivar finished: After C{startProducing} is called, a L{Deferred} which was
- returned by that method. L{StringProducer} will never fire this
- L{Deferred}.
- """
- implements(IBodyProducer)
-
- stopped = False
-
- def __init__(self, length):
- self.length = length
-
-
- def startProducing(self, consumer):
- self.consumer = consumer
- self.finished = Deferred()
- return self.finished
-
-
- def stopProducing(self):
- self.stopped = True
-
-
-
-class RequestTests(TestCase):
- """
- Tests for L{Request}.
- """
- def setUp(self):
- self.transport = StringTransport()
-
-
- def test_sendSimplestRequest(self):
- """
- L{Request.writeTo} formats the request data and writes it to the given
- transport.
- """
- Request('GET', '/', _boringHeaders, None).writeTo(self.transport)
- self.assertEqual(
- self.transport.value(),
- "GET / HTTP/1.1\r\n"
- "Connection: close\r\n"
- "Host: example.com\r\n"
- "\r\n")
-
-
- def test_sendSimplestPersistentRequest(self):
- """
- A pesistent request does not send 'Connection: close' header.
- """
- req = Request('GET', '/', _boringHeaders, None, persistent=True)
- req.writeTo(self.transport)
- self.assertEqual(
- self.transport.value(),
- "GET / HTTP/1.1\r\n"
- "Host: example.com\r\n"
- "\r\n")
-
-
- def test_sendRequestHeaders(self):
- """
- L{Request.writeTo} formats header data and writes it to the given
- transport.
- """
- headers = Headers({'x-foo': ['bar', 'baz'], 'host': ['example.com']})
- Request('GET', '/foo', headers, None).writeTo(self.transport)
- lines = self.transport.value().split('\r\n')
- self.assertEqual(lines[0], "GET /foo HTTP/1.1")
- self.assertEqual(lines[-2:], ["", ""])
- del lines[0], lines[-2:]
- lines.sort()
- self.assertEqual(
- lines,
- ["Connection: close",
- "Host: example.com",
- "X-Foo: bar",
- "X-Foo: baz"])
-
-
- def test_sendChunkedRequestBody(self):
- """
- L{Request.writeTo} uses chunked encoding to write data from the request
- body producer to the given transport. It registers the request body
- producer with the transport.
- """
- producer = StringProducer(UNKNOWN_LENGTH)
- request = Request('POST', '/bar', _boringHeaders, producer)
- request.writeTo(self.transport)
-
- self.assertNotIdentical(producer.consumer, None)
- self.assertIdentical(self.transport.producer, producer)
- self.assertTrue(self.transport.streaming)
-
- self.assertEqual(
- self.transport.value(),
- "POST /bar HTTP/1.1\r\n"
- "Connection: close\r\n"
- "Transfer-Encoding: chunked\r\n"
- "Host: example.com\r\n"
- "\r\n")
- self.transport.clear()
-
- producer.consumer.write('x' * 3)
- producer.consumer.write('y' * 15)
- producer.finished.callback(None)
- self.assertIdentical(self.transport.producer, None)
- self.assertEqual(
- self.transport.value(),
- "3\r\n"
- "xxx\r\n"
- "f\r\n"
- "yyyyyyyyyyyyyyy\r\n"
- "0\r\n"
- "\r\n")
-
-
- def test_sendChunkedRequestBodyWithError(self):
- """
- If L{Request} is created with a C{bodyProducer} without a known length
- and the L{Deferred} returned from its C{startProducing} method fires
- with a L{Failure}, the L{Deferred} returned by L{Request.writeTo} fires
- with that L{Failure} and the body producer is unregistered from the
- transport. The final zero-length chunk is not written to the
- transport.
- """
- producer = StringProducer(UNKNOWN_LENGTH)
- request = Request('POST', '/bar', _boringHeaders, producer)
- writeDeferred = request.writeTo(self.transport)
- self.transport.clear()
- producer.finished.errback(ArbitraryException())
- def cbFailed(ignored):
- self.assertEqual(self.transport.value(), "")
- self.assertIdentical(self.transport.producer, None)
- d = self.assertFailure(writeDeferred, ArbitraryException)
- d.addCallback(cbFailed)
- return d
-
-
- def test_sendRequestBodyWithLength(self):
- """
- If L{Request} is created with a C{bodyProducer} with a known length,
- that length is sent as the value for the I{Content-Length} header and
- chunked encoding is not used.
- """
- producer = StringProducer(3)
- request = Request('POST', '/bar', _boringHeaders, producer)
- request.writeTo(self.transport)
-
- self.assertNotIdentical(producer.consumer, None)
- self.assertIdentical(self.transport.producer, producer)
- self.assertTrue(self.transport.streaming)
-
- self.assertEqual(
- self.transport.value(),
- "POST /bar HTTP/1.1\r\n"
- "Connection: close\r\n"
- "Content-Length: 3\r\n"
- "Host: example.com\r\n"
- "\r\n")
- self.transport.clear()
-
- producer.consumer.write('abc')
- producer.finished.callback(None)
- self.assertIdentical(self.transport.producer, None)
- self.assertEqual(self.transport.value(), "abc")
-
-
- def test_sendRequestBodyWithTooFewBytes(self):
- """
- If L{Request} is created with a C{bodyProducer} with a known length and
- the producer does not produce that many bytes, the L{Deferred} returned
- by L{Request.writeTo} fires with a L{Failure} wrapping a
- L{WrongBodyLength} exception.
- """
- producer = StringProducer(3)
- request = Request('POST', '/bar', _boringHeaders, producer)
- writeDeferred = request.writeTo(self.transport)
- producer.consumer.write('ab')
- producer.finished.callback(None)
- self.assertIdentical(self.transport.producer, None)
- return self.assertFailure(writeDeferred, WrongBodyLength)
-
-
- def _sendRequestBodyWithTooManyBytesTest(self, finisher):
- """
- Verify that when too many bytes have been written by a body producer
- and then the body producer's C{startProducing} L{Deferred} fires that
- the producer is unregistered from the transport and that the
- L{Deferred} returned from L{Request.writeTo} is fired with a L{Failure}
- wrapping a L{WrongBodyLength}.
-
- @param finisher: A callable which will be invoked with the body
- producer after too many bytes have been written to the transport.
- It should fire the startProducing Deferred somehow.
- """
- producer = StringProducer(3)
- request = Request('POST', '/bar', _boringHeaders, producer)
- writeDeferred = request.writeTo(self.transport)
-
- producer.consumer.write('ab')
-
- # The producer hasn't misbehaved yet, so it shouldn't have been
- # stopped.
- self.assertFalse(producer.stopped)
-
- producer.consumer.write('cd')
-
- # Now the producer *has* misbehaved, so we should have tried to
- # make it stop.
- self.assertTrue(producer.stopped)
-
- # The transport should have had the producer unregistered from it as
- # well.
- self.assertIdentical(self.transport.producer, None)
-
- def cbFailed(exc):
- # The "cd" should not have been written to the transport because
- # the request can now locally be recognized to be invalid. If we
- # had written the extra bytes, the server could have decided to
- # start processing the request, which would be bad since we're
- # going to indicate failure locally.
- self.assertEqual(
- self.transport.value(),
- "POST /bar HTTP/1.1\r\n"
- "Connection: close\r\n"
- "Content-Length: 3\r\n"
- "Host: example.com\r\n"
- "\r\n"
- "ab")
- self.transport.clear()
-
- # Subsequent writes should be ignored, as should firing the
- # Deferred returned from startProducing.
- self.assertRaises(ExcessWrite, producer.consumer.write, 'ef')
-
- # Likewise, if the Deferred returned from startProducing fires,
- # this should more or less be ignored (aside from possibly logging
- # an error).
- finisher(producer)
-
- # There should have been nothing further written to the transport.
- self.assertEqual(self.transport.value(), "")
-
- d = self.assertFailure(writeDeferred, WrongBodyLength)
- d.addCallback(cbFailed)
- return d
-
-
- def test_sendRequestBodyWithTooManyBytes(self):
- """
- If L{Request} is created with a C{bodyProducer} with a known length and
- the producer tries to produce more than than many bytes, the
- L{Deferred} returned by L{Request.writeTo} fires with a L{Failure}
- wrapping a L{WrongBodyLength} exception.
- """
- def finisher(producer):
- producer.finished.callback(None)
- return self._sendRequestBodyWithTooManyBytesTest(finisher)
-
-
- def test_sendRequestBodyErrorWithTooManyBytes(self):
- """
- If L{Request} is created with a C{bodyProducer} with a known length and
- the producer tries to produce more than than many bytes, the
- L{Deferred} returned by L{Request.writeTo} fires with a L{Failure}
- wrapping a L{WrongBodyLength} exception.
- """
- def finisher(producer):
- producer.finished.errback(ArbitraryException())
- errors = self.flushLoggedErrors(ArbitraryException)
- self.assertEqual(len(errors), 1)
- return self._sendRequestBodyWithTooManyBytesTest(finisher)
-
-
- def test_sendRequestBodyErrorWithConsumerError(self):
- """
- Though there should be no way for the internal C{finishedConsuming}
- L{Deferred} in L{Request._writeToContentLength} to fire a L{Failure}
- after the C{finishedProducing} L{Deferred} has fired, in case this does
- happen, the error should be logged with a message about how there's
- probably a bug in L{Request}.
-
- This is a whitebox test.
- """
- producer = StringProducer(3)
- request = Request('POST', '/bar', _boringHeaders, producer)
- request.writeTo(self.transport)
-
- finishedConsuming = producer.consumer._finished
-
- producer.consumer.write('abc')
- producer.finished.callback(None)
-
- finishedConsuming.errback(ArbitraryException())
- self.assertEqual(len(self.flushLoggedErrors(ArbitraryException)), 1)
-
-
- def _sendRequestBodyFinishedEarlyThenTooManyBytes(self, finisher):
- """
- Verify that if the body producer fires its Deferred and then keeps
- writing to the consumer that the extra writes are ignored and the
- L{Deferred} returned by L{Request.writeTo} fires with a L{Failure}
- wrapping the most appropriate exception type.
- """
- producer = StringProducer(3)
- request = Request('POST', '/bar', _boringHeaders, producer)
- writeDeferred = request.writeTo(self.transport)
-
- producer.consumer.write('ab')
- finisher(producer)
- self.assertIdentical(self.transport.producer, None)
- self.transport.clear()
- self.assertRaises(ExcessWrite, producer.consumer.write, 'cd')
- self.assertEqual(self.transport.value(), "")
- return writeDeferred
-
-
- def test_sendRequestBodyFinishedEarlyThenTooManyBytes(self):
- """
- If the request body producer indicates it is done by firing the
- L{Deferred} returned from its C{startProducing} method but then goes on
- to write too many bytes, the L{Deferred} returned by {Request.writeTo}
- fires with a L{Failure} wrapping L{WrongBodyLength}.
- """
- def finisher(producer):
- producer.finished.callback(None)
- return self.assertFailure(
- self._sendRequestBodyFinishedEarlyThenTooManyBytes(finisher),
- WrongBodyLength)
-
-
- def test_sendRequestBodyErroredEarlyThenTooManyBytes(self):
- """
- If the request body producer indicates an error by firing the
- L{Deferred} returned from its C{startProducing} method but then goes on
- to write too many bytes, the L{Deferred} returned by {Request.writeTo}
- fires with that L{Failure} and L{WrongBodyLength} is logged.
- """
- def finisher(producer):
- producer.finished.errback(ArbitraryException())
- return self.assertFailure(
- self._sendRequestBodyFinishedEarlyThenTooManyBytes(finisher),
- ArbitraryException)
-
-
- def test_sendChunkedRequestBodyFinishedThenWriteMore(self, _with=None):
- """
- If the request body producer with an unknown length tries to write
- after firing the L{Deferred} returned by its C{startProducing} method,
- the C{write} call raises an exception and does not write anything to
- the underlying transport.
- """
- producer = StringProducer(UNKNOWN_LENGTH)
- request = Request('POST', '/bar', _boringHeaders, producer)
- writeDeferred = request.writeTo(self.transport)
- producer.finished.callback(_with)
- self.transport.clear()
-
- self.assertRaises(ExcessWrite, producer.consumer.write, 'foo')
- self.assertEqual(self.transport.value(), "")
- return writeDeferred
-
-
- def test_sendChunkedRequestBodyFinishedWithErrorThenWriteMore(self):
- """
- If the request body producer with an unknown length tries to write
- after firing the L{Deferred} returned by its C{startProducing} method
- with a L{Failure}, the C{write} call raises an exception and does not
- write anything to the underlying transport.
- """
- d = self.test_sendChunkedRequestBodyFinishedThenWriteMore(
- Failure(ArbitraryException()))
- return self.assertFailure(d, ArbitraryException)
-
-
- def test_sendRequestBodyWithError(self):
- """
- If the L{Deferred} returned from the C{startProducing} method of the
- L{IBodyProducer} passed to L{Request} fires with a L{Failure}, the
- L{Deferred} returned from L{Request.writeTo} fails with that
- L{Failure}.
- """
- producer = StringProducer(5)
- request = Request('POST', '/bar', _boringHeaders, producer)
- writeDeferred = request.writeTo(self.transport)
-
- # Sanity check - the producer should be registered with the underlying
- # transport.
- self.assertIdentical(self.transport.producer, producer)
- self.assertTrue(self.transport.streaming)
-
- producer.consumer.write('ab')
- self.assertEqual(
- self.transport.value(),
- "POST /bar HTTP/1.1\r\n"
- "Connection: close\r\n"
- "Content-Length: 5\r\n"
- "Host: example.com\r\n"
- "\r\n"
- "ab")
-
- self.assertFalse(self.transport.disconnecting)
- producer.finished.errback(Failure(ArbitraryException()))
-
- # Disconnection is handled by a higher level. Request should leave the
- # transport alone in this case.
- self.assertFalse(self.transport.disconnecting)
-
- # Oh. Except it should unregister the producer that it registered.
- self.assertIdentical(self.transport.producer, None)
-
- return self.assertFailure(writeDeferred, ArbitraryException)
-
-
- def test_hostHeaderRequired(self):
- """
- L{Request.writeTo} raises L{BadHeaders} if there is not exactly one
- I{Host} header and writes nothing to the given transport.
- """
- request = Request('GET', '/', Headers({}), None)
- self.assertRaises(BadHeaders, request.writeTo, self.transport)
- self.assertEqual(self.transport.value(), '')
-
- request = Request('GET', '/', Headers({'Host': ['example.com', 'example.org']}), None)
- self.assertRaises(BadHeaders, request.writeTo, self.transport)
- self.assertEqual(self.transport.value(), '')
-
-
- def test_stopWriting(self):
- """
- L{Request.stopWriting} calls its body producer's C{stopProducing}
- method.
- """
- producer = StringProducer(3)
- request = Request('GET', '/', _boringHeaders, producer)
- request.writeTo(self.transport)
- self.assertFalse(producer.stopped)
- request.stopWriting()
- self.assertTrue(producer.stopped)
-
-
- def test_brokenStopProducing(self):
- """
- If the body producer's C{stopProducing} method raises an exception,
- L{Request.stopWriting} logs it and does not re-raise it.
- """
- producer = StringProducer(3)
- def brokenStopProducing():
- raise ArbitraryException("stopProducing is busted")
- producer.stopProducing = brokenStopProducing
-
- request = Request('GET', '/', _boringHeaders, producer)
- request.writeTo(self.transport)
- request.stopWriting()
- self.assertEqual(
- len(self.flushLoggedErrors(ArbitraryException)), 1)
-
-
-
-class LengthEnforcingConsumerTests(TestCase):
- """
- Tests for L{LengthEnforcingConsumer}.
- """
- def setUp(self):
- self.result = Deferred()
- self.producer = StringProducer(10)
- self.transport = StringTransport()
- self.enforcer = LengthEnforcingConsumer(
- self.producer, self.transport, self.result)
-
-
- def test_write(self):
- """
- L{LengthEnforcingConsumer.write} calls the wrapped consumer's C{write}
- method with the bytes it is passed as long as there are fewer of them
- than the C{length} attribute indicates remain to be received.
- """
- self.enforcer.write('abc')
- self.assertEqual(self.transport.value(), 'abc')
- self.transport.clear()
- self.enforcer.write('def')
- self.assertEqual(self.transport.value(), 'def')
-
-
- def test_finishedEarly(self):
- """
- L{LengthEnforcingConsumer._noMoreWritesExpected} raises
- L{WrongBodyLength} if it is called before the indicated number of bytes
- have been written.
- """
- self.enforcer.write('x' * 9)
- self.assertRaises(WrongBodyLength, self.enforcer._noMoreWritesExpected)
-
-
- def test_writeTooMany(self, _unregisterAfter=False):
- """
- If it is called with a total number of bytes exceeding the indicated
- limit passed to L{LengthEnforcingConsumer.__init__},
- L{LengthEnforcingConsumer.write} fires the L{Deferred} with a
- L{Failure} wrapping a L{WrongBodyLength} and also calls the
- C{stopProducing} method of the producer.
- """
- self.enforcer.write('x' * 10)
- self.assertFalse(self.producer.stopped)
- self.enforcer.write('x')
- self.assertTrue(self.producer.stopped)
- if _unregisterAfter:
- self.enforcer._noMoreWritesExpected()
- return self.assertFailure(self.result, WrongBodyLength)
-
-
- def test_writeAfterNoMoreExpected(self):
- """
- If L{LengthEnforcingConsumer.write} is called after
- L{LengthEnforcingConsumer._noMoreWritesExpected}, it calls the
- producer's C{stopProducing} method and raises L{ExcessWrite}.
- """
- self.enforcer.write('x' * 10)
- self.enforcer._noMoreWritesExpected()
- self.assertFalse(self.producer.stopped)
- self.assertRaises(ExcessWrite, self.enforcer.write, 'x')
- self.assertTrue(self.producer.stopped)
-
-
- def test_finishedLate(self):
- """
- L{LengthEnforcingConsumer._noMoreWritesExpected} does nothing (in
- particular, it does not raise any exception) if called after too many
- bytes have been passed to C{write}.
- """
- return self.test_writeTooMany(True)
-
-
- def test_finished(self):
- """
- If L{LengthEnforcingConsumer._noMoreWritesExpected} is called after
- the correct number of bytes have been written it returns C{None}.
- """
- self.enforcer.write('x' * 10)
- self.assertIdentical(self.enforcer._noMoreWritesExpected(), None)
-
-
- def test_stopProducingRaises(self):
- """
- If L{LengthEnforcingConsumer.write} calls the producer's
- C{stopProducing} because too many bytes were written and the
- C{stopProducing} method raises an exception, the exception is logged
- and the L{LengthEnforcingConsumer} still errbacks the finished
- L{Deferred}.
- """
- def brokenStopProducing():
- StringProducer.stopProducing(self.producer)
- raise ArbitraryException("stopProducing is busted")
- self.producer.stopProducing = brokenStopProducing
-
- def cbFinished(ignored):
- self.assertEqual(
- len(self.flushLoggedErrors(ArbitraryException)), 1)
- d = self.test_writeTooMany()
- d.addCallback(cbFinished)
- return d
-
-
-
-class RequestBodyConsumerTests(TestCase):
- """
- Tests for L{ChunkedEncoder} which sits between an L{ITransport} and a
- request/response body producer and chunked encodes everything written to
- it.
- """
- def test_interface(self):
- """
- L{ChunkedEncoder} instances provide L{IConsumer}.
- """
- self.assertTrue(
- verifyObject(IConsumer, ChunkedEncoder(StringTransport())))
-
-
- def test_write(self):
- """
- L{ChunkedEncoder.write} writes to the transport the chunked encoded
- form of the bytes passed to it.
- """
- transport = StringTransport()
- encoder = ChunkedEncoder(transport)
- encoder.write('foo')
- self.assertEqual(transport.value(), '3\r\nfoo\r\n')
- transport.clear()
- encoder.write('x' * 16)
- self.assertEqual(transport.value(), '10\r\n' + 'x' * 16 + '\r\n')
-
-
- def test_producerRegistration(self):
- """
- L{ChunkedEncoder.registerProducer} registers the given streaming
- producer with its transport and L{ChunkedEncoder.unregisterProducer}
- writes a zero-length chunk to its transport and unregisters the
- transport's producer.
- """
- transport = StringTransport()
- producer = object()
- encoder = ChunkedEncoder(transport)
- encoder.registerProducer(producer, True)
- self.assertIdentical(transport.producer, producer)
- self.assertTrue(transport.streaming)
- encoder.unregisterProducer()
- self.assertIdentical(transport.producer, None)
- self.assertEqual(transport.value(), '0\r\n\r\n')
-
-
-
-class TransportProxyProducerTests(TestCase):
- """
- Tests for L{TransportProxyProducer} which proxies the L{IPushProducer}
- interface of a transport.
- """
- def test_interface(self):
- """
- L{TransportProxyProducer} instances provide L{IPushProducer}.
- """
- self.assertTrue(
- verifyObject(IPushProducer, TransportProxyProducer(None)))
-
-
- def test_stopProxyingUnreferencesProducer(self):
- """
- L{TransportProxyProducer._stopProxying} drops the reference to the
- wrapped L{IPushProducer} provider.
- """
- transport = StringTransport()
- proxy = TransportProxyProducer(transport)
- self.assertIdentical(proxy._producer, transport)
- proxy._stopProxying()
- self.assertIdentical(proxy._producer, None)
-
-
- def test_resumeProducing(self):
- """
- L{TransportProxyProducer.resumeProducing} calls the wrapped
- transport's C{resumeProducing} method unless told to stop proxying.
- """
- transport = StringTransport()
- transport.pauseProducing()
-
- proxy = TransportProxyProducer(transport)
- # The transport should still be paused.
- self.assertEqual(transport.producerState, 'paused')
- proxy.resumeProducing()
- # The transport should now be resumed.
- self.assertEqual(transport.producerState, 'producing')
-
- transport.pauseProducing()
- proxy._stopProxying()
-
- # The proxy should no longer do anything to the transport.
- proxy.resumeProducing()
- self.assertEqual(transport.producerState, 'paused')
-
-
- def test_pauseProducing(self):
- """
- L{TransportProxyProducer.pauseProducing} calls the wrapped transport's
- C{pauseProducing} method unless told to stop proxying.
- """
- transport = StringTransport()
-
- proxy = TransportProxyProducer(transport)
- # The transport should still be producing.
- self.assertEqual(transport.producerState, 'producing')
- proxy.pauseProducing()
- # The transport should now be paused.
- self.assertEqual(transport.producerState, 'paused')
-
- transport.resumeProducing()
- proxy._stopProxying()
-
- # The proxy should no longer do anything to the transport.
- proxy.pauseProducing()
- self.assertEqual(transport.producerState, 'producing')
-
-
- def test_stopProducing(self):
- """
- L{TransportProxyProducer.stopProducing} calls the wrapped transport's
- C{stopProducing} method unless told to stop proxying.
- """
- transport = StringTransport()
- proxy = TransportProxyProducer(transport)
- # The transport should still be producing.
- self.assertEqual(transport.producerState, 'producing')
- proxy.stopProducing()
- # The transport should now be stopped.
- self.assertEqual(transport.producerState, 'stopped')
-
- transport = StringTransport()
- proxy = TransportProxyProducer(transport)
- proxy._stopProxying()
- proxy.stopProducing()
- # The transport should not have been stopped.
- self.assertEqual(transport.producerState, 'producing')
-
-
-
-class ResponseTests(TestCase):
- """
- Tests for L{Response}.
- """
-
- def test_verifyInterface(self):
- """
- L{Response} instances provide L{IResponse}.
- """
- response = justTransportResponse(StringTransport())
- self.assertTrue(verifyObject(IResponse, response))
-
-
- def test_makeConnection(self):
- """
- The L{IProtocol} provider passed to L{Response.deliverBody} has its
- C{makeConnection} method called with an L{IPushProducer} provider
- hooked up to the response as an argument.
- """
- producers = []
- transport = StringTransport()
- class SomeProtocol(Protocol):
- def makeConnection(self, producer):
- producers.append(producer)
-
- consumer = SomeProtocol()
- response = justTransportResponse(transport)
- response.deliverBody(consumer)
- [theProducer] = producers
- theProducer.pauseProducing()
- self.assertEqual(transport.producerState, 'paused')
- theProducer.resumeProducing()
- self.assertEqual(transport.producerState, 'producing')
-
-
- def test_dataReceived(self):
- """
- The L{IProtocol} provider passed to L{Response.deliverBody} has its
- C{dataReceived} method called with bytes received as part of the
- response body.
- """
- bytes = []
- class ListConsumer(Protocol):
- def dataReceived(self, data):
- bytes.append(data)
-
-
- consumer = ListConsumer()
- response = justTransportResponse(StringTransport())
- response.deliverBody(consumer)
-
- response._bodyDataReceived('foo')
- self.assertEqual(bytes, ['foo'])
-
-
- def test_connectionLost(self):
- """
- The L{IProtocol} provider passed to L{Response.deliverBody} has its
- C{connectionLost} method called with a L{Failure} wrapping
- L{ResponseDone} when the response's C{_bodyDataFinished} method is
- called.
- """
- lost = []
- class ListConsumer(Protocol):
- def connectionLost(self, reason):
- lost.append(reason)
-
- consumer = ListConsumer()
- response = justTransportResponse(StringTransport())
- response.deliverBody(consumer)
-
- response._bodyDataFinished()
- lost[0].trap(ResponseDone)
- self.assertEqual(len(lost), 1)
-
- # The protocol reference should be dropped, too, to facilitate GC or
- # whatever.
- self.assertIdentical(response._bodyProtocol, None)
-
-
- def test_bufferEarlyData(self):
- """
- If data is delivered to the L{Response} before a protocol is registered
- with C{deliverBody}, that data is buffered until the protocol is
- registered and then is delivered.
- """
- bytes = []
- class ListConsumer(Protocol):
- def dataReceived(self, data):
- bytes.append(data)
-
- protocol = ListConsumer()
- response = justTransportResponse(StringTransport())
- response._bodyDataReceived('foo')
- response._bodyDataReceived('bar')
- response.deliverBody(protocol)
- response._bodyDataReceived('baz')
- self.assertEqual(bytes, ['foo', 'bar', 'baz'])
- # Make sure the implementation-detail-byte-buffer is cleared because
- # not clearing it wastes memory.
- self.assertIdentical(response._bodyBuffer, None)
-
-
- def test_multipleStartProducingFails(self):
- """
- L{Response.deliverBody} raises L{RuntimeError} if called more than
- once.
- """
- response = justTransportResponse(StringTransport())
- response.deliverBody(Protocol())
- self.assertRaises(RuntimeError, response.deliverBody, Protocol())
-
-
- def test_startProducingAfterFinishedFails(self):
- """
- L{Response.deliverBody} raises L{RuntimeError} if called after
- L{Response._bodyDataFinished}.
- """
- response = justTransportResponse(StringTransport())
- response.deliverBody(Protocol())
- response._bodyDataFinished()
- self.assertRaises(RuntimeError, response.deliverBody, Protocol())
-
-
- def test_bodyDataReceivedAfterFinishedFails(self):
- """
- L{Response._bodyDataReceived} raises L{RuntimeError} if called after
- L{Response._bodyDataFinished} but before L{Response.deliverBody}.
- """
- response = justTransportResponse(StringTransport())
- response._bodyDataFinished()
- self.assertRaises(RuntimeError, response._bodyDataReceived, 'foo')
-
-
- def test_bodyDataReceivedAfterDeliveryFails(self):
- """
- L{Response._bodyDataReceived} raises L{RuntimeError} if called after
- L{Response._bodyDataFinished} and after L{Response.deliverBody}.
- """
- response = justTransportResponse(StringTransport())
- response._bodyDataFinished()
- response.deliverBody(Protocol())
- self.assertRaises(RuntimeError, response._bodyDataReceived, 'foo')
-
-
- def test_bodyDataFinishedAfterFinishedFails(self):
- """
- L{Response._bodyDataFinished} raises L{RuntimeError} if called more
- than once.
- """
- response = justTransportResponse(StringTransport())
- response._bodyDataFinished()
- self.assertRaises(RuntimeError, response._bodyDataFinished)
-
-
- def test_bodyDataFinishedAfterDeliveryFails(self):
- """
- L{Response._bodyDataFinished} raises L{RuntimeError} if called after
- the body has been delivered.
- """
- response = justTransportResponse(StringTransport())
- response._bodyDataFinished()
- response.deliverBody(Protocol())
- self.assertRaises(RuntimeError, response._bodyDataFinished)
-
-
- def test_transportResumed(self):
- """
- L{Response.deliverBody} resumes the HTTP connection's transport
- before passing it to the transport's C{makeConnection} method.
- """
- transportState = []
- class ListConsumer(Protocol):
- def makeConnection(self, transport):
- transportState.append(transport.producerState)
-
- transport = StringTransport()
- transport.pauseProducing()
- protocol = ListConsumer()
- response = justTransportResponse(transport)
- self.assertEqual(transport.producerState, 'paused')
- response.deliverBody(protocol)
- self.assertEqual(transportState, ['producing'])
-
-
- def test_bodyDataFinishedBeforeStartProducing(self):
- """
- If the entire body is delivered to the L{Response} before the
- response's C{deliverBody} method is called, the protocol passed to
- C{deliverBody} is immediately given the body data and then
- disconnected.
- """
- transport = StringTransport()
- response = justTransportResponse(transport)
- response._bodyDataReceived('foo')
- response._bodyDataReceived('bar')
- response._bodyDataFinished()
-
- protocol = AccumulatingProtocol()
- response.deliverBody(protocol)
- self.assertEqual(protocol.data, 'foobar')
- protocol.closedReason.trap(ResponseDone)
-
-
- def test_finishedWithErrorWhenConnected(self):
- """
- The L{Failure} passed to L{Response._bodyDataFinished} when the response
- is in the I{connected} state is passed to the C{connectionLost} method
- of the L{IProtocol} provider passed to the L{Response}'s
- C{deliverBody} method.
- """
- transport = StringTransport()
- response = justTransportResponse(transport)
-
- protocol = AccumulatingProtocol()
- response.deliverBody(protocol)
-
- # Sanity check - this test is for the connected state
- self.assertEqual(response._state, 'CONNECTED')
- response._bodyDataFinished(Failure(ArbitraryException()))
-
- protocol.closedReason.trap(ArbitraryException)
-
-
- def test_finishedWithErrorWhenInitial(self):
- """
- The L{Failure} passed to L{Response._bodyDataFinished} when the response
- is in the I{initial} state is passed to the C{connectionLost} method of
- the L{IProtocol} provider passed to the L{Response}'s C{deliverBody}
- method.
- """
- transport = StringTransport()
- response = justTransportResponse(transport)
-
- # Sanity check - this test is for the initial state
- self.assertEqual(response._state, 'INITIAL')
- response._bodyDataFinished(Failure(ArbitraryException()))
-
- protocol = AccumulatingProtocol()
- response.deliverBody(protocol)
-
- protocol.closedReason.trap(ArbitraryException)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_proxy.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_proxy.py
deleted file mode 100755
index 4452fcbd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_proxy.py
+++ /dev/null
@@ -1,544 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test for L{twisted.web.proxy}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.test.proto_helpers import StringTransportWithDisconnection
-from twisted.test.proto_helpers import MemoryReactor
-
-from twisted.web.resource import Resource
-from twisted.web.server import Site
-from twisted.web.proxy import ReverseProxyResource, ProxyClientFactory
-from twisted.web.proxy import ProxyClient, ProxyRequest, ReverseProxyRequest
-from twisted.web.test.test_web import DummyRequest
-
-
-class ReverseProxyResourceTestCase(TestCase):
- """
- Tests for L{ReverseProxyResource}.
- """
-
- def _testRender(self, uri, expectedURI):
- """
- Check that a request pointing at C{uri} produce a new proxy connection,
- with the path of this request pointing at C{expectedURI}.
- """
- root = Resource()
- reactor = MemoryReactor()
- resource = ReverseProxyResource("127.0.0.1", 1234, "/path", reactor)
- root.putChild('index', resource)
- site = Site(root)
-
- transport = StringTransportWithDisconnection()
- channel = site.buildProtocol(None)
- channel.makeConnection(transport)
- # Clear the timeout if the tests failed
- self.addCleanup(channel.connectionLost, None)
-
- channel.dataReceived("GET %s HTTP/1.1\r\nAccept: text/html\r\n\r\n" %
- (uri,))
-
- # Check that one connection has been created, to the good host/port
- self.assertEqual(len(reactor.tcpClients), 1)
- self.assertEqual(reactor.tcpClients[0][0], "127.0.0.1")
- self.assertEqual(reactor.tcpClients[0][1], 1234)
-
- # Check the factory passed to the connect, and its given path
- factory = reactor.tcpClients[0][2]
- self.assertIsInstance(factory, ProxyClientFactory)
- self.assertEqual(factory.rest, expectedURI)
- self.assertEqual(factory.headers["host"], "127.0.0.1:1234")
-
-
- def test_render(self):
- """
- Test that L{ReverseProxyResource.render} initiates a connection to the
- given server with a L{ProxyClientFactory} as parameter.
- """
- return self._testRender("/index", "/path")
-
-
- def test_renderWithQuery(self):
- """
- Test that L{ReverseProxyResource.render} passes query parameters to the
- created factory.
- """
- return self._testRender("/index?foo=bar", "/path?foo=bar")
-
-
- def test_getChild(self):
- """
- The L{ReverseProxyResource.getChild} method should return a resource
- instance with the same class as the originating resource, forward
- port, host, and reactor values, and update the path value with the
- value passed.
- """
- reactor = MemoryReactor()
- resource = ReverseProxyResource("127.0.0.1", 1234, "/path", reactor)
- child = resource.getChild('foo', None)
- # The child should keep the same class
- self.assertIsInstance(child, ReverseProxyResource)
- self.assertEqual(child.path, "/path/foo")
- self.assertEqual(child.port, 1234)
- self.assertEqual(child.host, "127.0.0.1")
- self.assertIdentical(child.reactor, resource.reactor)
-
-
- def test_getChildWithSpecial(self):
- """
- The L{ReverseProxyResource} return by C{getChild} has a path which has
- already been quoted.
- """
- resource = ReverseProxyResource("127.0.0.1", 1234, "/path")
- child = resource.getChild(' /%', None)
- self.assertEqual(child.path, "/path/%20%2F%25")
-
-
-
-class DummyChannel(object):
- """
- A dummy HTTP channel, that does nothing but holds a transport and saves
- connection lost.
-
- @ivar transport: the transport used by the client.
- @ivar lostReason: the reason saved at connection lost.
- """
-
- def __init__(self, transport):
- """
- Hold a reference to the transport.
- """
- self.transport = transport
- self.lostReason = None
-
-
- def connectionLost(self, reason):
- """
- Keep track of the connection lost reason.
- """
- self.lostReason = reason
-
-
-
-class ProxyClientTestCase(TestCase):
- """
- Tests for L{ProxyClient}.
- """
-
- def _parseOutHeaders(self, content):
- """
- Parse the headers out of some web content.
-
- @param content: Bytes received from a web server.
- @return: A tuple of (requestLine, headers, body). C{headers} is a dict
- of headers, C{requestLine} is the first line (e.g. "POST /foo ...")
- and C{body} is whatever is left.
- """
- headers, body = content.split('\r\n\r\n')
- headers = headers.split('\r\n')
- requestLine = headers.pop(0)
- return (
- requestLine, dict(header.split(': ') for header in headers), body)
-
-
- def makeRequest(self, path):
- """
- Make a dummy request object for the URL path.
-
- @param path: A URL path, beginning with a slash.
- @return: A L{DummyRequest}.
- """
- return DummyRequest(path)
-
-
- def makeProxyClient(self, request, method="GET", headers=None,
- requestBody=""):
- """
- Make a L{ProxyClient} object used for testing.
-
- @param request: The request to use.
- @param method: The HTTP method to use, GET by default.
- @param headers: The HTTP headers to use expressed as a dict. If not
- provided, defaults to {'accept': 'text/html'}.
- @param requestBody: The body of the request. Defaults to the empty
- string.
- @return: A L{ProxyClient}
- """
- if headers is None:
- headers = {"accept": "text/html"}
- path = '/' + request.postpath
- return ProxyClient(
- method, path, 'HTTP/1.0', headers, requestBody, request)
-
-
- def connectProxy(self, proxyClient):
- """
- Connect a proxy client to a L{StringTransportWithDisconnection}.
-
- @param proxyClient: A L{ProxyClient}.
- @return: The L{StringTransportWithDisconnection}.
- """
- clientTransport = StringTransportWithDisconnection()
- clientTransport.protocol = proxyClient
- proxyClient.makeConnection(clientTransport)
- return clientTransport
-
-
- def assertForwardsHeaders(self, proxyClient, requestLine, headers):
- """
- Assert that C{proxyClient} sends C{headers} when it connects.
-
- @param proxyClient: A L{ProxyClient}.
- @param requestLine: The request line we expect to be sent.
- @param headers: A dict of headers we expect to be sent.
- @return: If the assertion is successful, return the request body as
- bytes.
- """
- self.connectProxy(proxyClient)
- requestContent = proxyClient.transport.value()
- receivedLine, receivedHeaders, body = self._parseOutHeaders(
- requestContent)
- self.assertEqual(receivedLine, requestLine)
- self.assertEqual(receivedHeaders, headers)
- return body
-
-
- def makeResponseBytes(self, code, message, headers, body):
- lines = ["HTTP/1.0 %d %s" % (code, message)]
- for header, values in headers:
- for value in values:
- lines.append("%s: %s" % (header, value))
- lines.extend(['', body])
- return '\r\n'.join(lines)
-
-
- def assertForwardsResponse(self, request, code, message, headers, body):
- """
- Assert that C{request} has forwarded a response from the server.
-
- @param request: A L{DummyRequest}.
- @param code: The expected HTTP response code.
- @param message: The expected HTTP message.
- @param headers: The expected HTTP headers.
- @param body: The expected response body.
- """
- self.assertEqual(request.responseCode, code)
- self.assertEqual(request.responseMessage, message)
- receivedHeaders = list(request.responseHeaders.getAllRawHeaders())
- receivedHeaders.sort()
- expectedHeaders = headers[:]
- expectedHeaders.sort()
- self.assertEqual(receivedHeaders, expectedHeaders)
- self.assertEqual(''.join(request.written), body)
-
-
- def _testDataForward(self, code, message, headers, body, method="GET",
- requestBody="", loseConnection=True):
- """
- Build a fake proxy connection, and send C{data} over it, checking that
- it's forwarded to the originating request.
- """
- request = self.makeRequest('foo')
- client = self.makeProxyClient(
- request, method, {'accept': 'text/html'}, requestBody)
-
- receivedBody = self.assertForwardsHeaders(
- client, '%s /foo HTTP/1.0' % (method,),
- {'connection': 'close', 'accept': 'text/html'})
-
- self.assertEqual(receivedBody, requestBody)
-
- # Fake an answer
- client.dataReceived(
- self.makeResponseBytes(code, message, headers, body))
-
- # Check that the response data has been forwarded back to the original
- # requester.
- self.assertForwardsResponse(request, code, message, headers, body)
-
- # Check that when the response is done, the request is finished.
- if loseConnection:
- client.transport.loseConnection()
-
- # Even if we didn't call loseConnection, the transport should be
- # disconnected. This lets us not rely on the server to close our
- # sockets for us.
- self.assertFalse(client.transport.connected)
- self.assertEqual(request.finished, 1)
-
-
- def test_forward(self):
- """
- When connected to the server, L{ProxyClient} should send the saved
- request, with modifications of the headers, and then forward the result
- to the parent request.
- """
- return self._testDataForward(
- 200, "OK", [("Foo", ["bar", "baz"])], "Some data\r\n")
-
-
- def test_postData(self):
- """
- Try to post content in the request, and check that the proxy client
- forward the body of the request.
- """
- return self._testDataForward(
- 200, "OK", [("Foo", ["bar"])], "Some data\r\n", "POST", "Some content")
-
-
- def test_statusWithMessage(self):
- """
- If the response contains a status with a message, it should be
- forwarded to the parent request with all the information.
- """
- return self._testDataForward(
- 404, "Not Found", [], "")
-
-
- def test_contentLength(self):
- """
- If the response contains a I{Content-Length} header, the inbound
- request object should still only have C{finish} called on it once.
- """
- data = "foo bar baz"
- return self._testDataForward(
- 200, "OK", [("Content-Length", [str(len(data))])], data)
-
-
- def test_losesConnection(self):
- """
- If the response contains a I{Content-Length} header, the outgoing
- connection is closed when all response body data has been received.
- """
- data = "foo bar baz"
- return self._testDataForward(
- 200, "OK", [("Content-Length", [str(len(data))])], data,
- loseConnection=False)
-
-
- def test_headersCleanups(self):
- """
- The headers given at initialization should be modified:
- B{proxy-connection} should be removed if present, and B{connection}
- should be added.
- """
- client = ProxyClient('GET', '/foo', 'HTTP/1.0',
- {"accept": "text/html", "proxy-connection": "foo"}, '', None)
- self.assertEqual(client.headers,
- {"accept": "text/html", "connection": "close"})
-
-
- def test_keepaliveNotForwarded(self):
- """
- The proxy doesn't really know what to do with keepalive things from
- the remote server, so we stomp over any keepalive header we get from
- the client.
- """
- headers = {
- "accept": "text/html",
- 'keep-alive': '300',
- 'connection': 'keep-alive',
- }
- expectedHeaders = headers.copy()
- expectedHeaders['connection'] = 'close'
- del expectedHeaders['keep-alive']
- client = ProxyClient('GET', '/foo', 'HTTP/1.0', headers, '', None)
- self.assertForwardsHeaders(
- client, 'GET /foo HTTP/1.0', expectedHeaders)
-
-
- def test_defaultHeadersOverridden(self):
- """
- L{server.Request} within the proxy sets certain response headers by
- default. When we get these headers back from the remote server, the
- defaults are overridden rather than simply appended.
- """
- request = self.makeRequest('foo')
- request.responseHeaders.setRawHeaders('server', ['old-bar'])
- request.responseHeaders.setRawHeaders('date', ['old-baz'])
- request.responseHeaders.setRawHeaders('content-type', ["old/qux"])
- client = self.makeProxyClient(request, headers={'accept': 'text/html'})
- self.connectProxy(client)
- headers = {
- 'Server': ['bar'],
- 'Date': ['2010-01-01'],
- 'Content-Type': ['application/x-baz'],
- }
- client.dataReceived(
- self.makeResponseBytes(200, "OK", headers.items(), ''))
- self.assertForwardsResponse(
- request, 200, 'OK', headers.items(), '')
-
-
-
-class ProxyClientFactoryTestCase(TestCase):
- """
- Tests for L{ProxyClientFactory}.
- """
-
- def test_connectionFailed(self):
- """
- Check that L{ProxyClientFactory.clientConnectionFailed} produces
- a B{501} response to the parent request.
- """
- request = DummyRequest(['foo'])
- factory = ProxyClientFactory('GET', '/foo', 'HTTP/1.0',
- {"accept": "text/html"}, '', request)
-
- factory.clientConnectionFailed(None, None)
- self.assertEqual(request.responseCode, 501)
- self.assertEqual(request.responseMessage, "Gateway error")
- self.assertEqual(
- list(request.responseHeaders.getAllRawHeaders()),
- [("Content-Type", ["text/html"])])
- self.assertEqual(
- ''.join(request.written),
- "<H1>Could not connect</H1>")
- self.assertEqual(request.finished, 1)
-
-
- def test_buildProtocol(self):
- """
- L{ProxyClientFactory.buildProtocol} should produce a L{ProxyClient}
- with the same values of attributes (with updates on the headers).
- """
- factory = ProxyClientFactory('GET', '/foo', 'HTTP/1.0',
- {"accept": "text/html"}, 'Some data',
- None)
- proto = factory.buildProtocol(None)
- self.assertIsInstance(proto, ProxyClient)
- self.assertEqual(proto.command, 'GET')
- self.assertEqual(proto.rest, '/foo')
- self.assertEqual(proto.data, 'Some data')
- self.assertEqual(proto.headers,
- {"accept": "text/html", "connection": "close"})
-
-
-
-class ProxyRequestTestCase(TestCase):
- """
- Tests for L{ProxyRequest}.
- """
-
- def _testProcess(self, uri, expectedURI, method="GET", data=""):
- """
- Build a request pointing at C{uri}, and check that a proxied request
- is created, pointing a C{expectedURI}.
- """
- transport = StringTransportWithDisconnection()
- channel = DummyChannel(transport)
- reactor = MemoryReactor()
- request = ProxyRequest(channel, False, reactor)
- request.gotLength(len(data))
- request.handleContentChunk(data)
- request.requestReceived(method, 'http://example.com%s' % (uri,),
- 'HTTP/1.0')
-
- self.assertEqual(len(reactor.tcpClients), 1)
- self.assertEqual(reactor.tcpClients[0][0], "example.com")
- self.assertEqual(reactor.tcpClients[0][1], 80)
-
- factory = reactor.tcpClients[0][2]
- self.assertIsInstance(factory, ProxyClientFactory)
- self.assertEqual(factory.command, method)
- self.assertEqual(factory.version, 'HTTP/1.0')
- self.assertEqual(factory.headers, {'host': 'example.com'})
- self.assertEqual(factory.data, data)
- self.assertEqual(factory.rest, expectedURI)
- self.assertEqual(factory.father, request)
-
-
- def test_process(self):
- """
- L{ProxyRequest.process} should create a connection to the given server,
- with a L{ProxyClientFactory} as connection factory, with the correct
- parameters:
- - forward comment, version and data values
- - update headers with the B{host} value
- - remove the host from the URL
- - pass the request as parent request
- """
- return self._testProcess("/foo/bar", "/foo/bar")
-
-
- def test_processWithoutTrailingSlash(self):
- """
- If the incoming request doesn't contain a slash,
- L{ProxyRequest.process} should add one when instantiating
- L{ProxyClientFactory}.
- """
- return self._testProcess("", "/")
-
-
- def test_processWithData(self):
- """
- L{ProxyRequest.process} should be able to retrieve request body and
- to forward it.
- """
- return self._testProcess(
- "/foo/bar", "/foo/bar", "POST", "Some content")
-
-
- def test_processWithPort(self):
- """
- Check that L{ProxyRequest.process} correctly parse port in the incoming
- URL, and create a outgoing connection with this port.
- """
- transport = StringTransportWithDisconnection()
- channel = DummyChannel(transport)
- reactor = MemoryReactor()
- request = ProxyRequest(channel, False, reactor)
- request.gotLength(0)
- request.requestReceived('GET', 'http://example.com:1234/foo/bar',
- 'HTTP/1.0')
-
- # That should create one connection, with the port parsed from the URL
- self.assertEqual(len(reactor.tcpClients), 1)
- self.assertEqual(reactor.tcpClients[0][0], "example.com")
- self.assertEqual(reactor.tcpClients[0][1], 1234)
-
-
-
-class DummyFactory(object):
- """
- A simple holder for C{host} and C{port} information.
- """
-
- def __init__(self, host, port):
- self.host = host
- self.port = port
-
-
-
-class ReverseProxyRequestTestCase(TestCase):
- """
- Tests for L{ReverseProxyRequest}.
- """
-
- def test_process(self):
- """
- L{ReverseProxyRequest.process} should create a connection to its
- factory host/port, using a L{ProxyClientFactory} instantiated with the
- correct parameters, and particulary set the B{host} header to the
- factory host.
- """
- transport = StringTransportWithDisconnection()
- channel = DummyChannel(transport)
- reactor = MemoryReactor()
- request = ReverseProxyRequest(channel, False, reactor)
- request.factory = DummyFactory("example.com", 1234)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
-
- # Check that one connection has been created, to the good host/port
- self.assertEqual(len(reactor.tcpClients), 1)
- self.assertEqual(reactor.tcpClients[0][0], "example.com")
- self.assertEqual(reactor.tcpClients[0][1], 1234)
-
- # Check the factory passed to the connect, and its headers
- factory = reactor.tcpClients[0][2]
- self.assertIsInstance(factory, ProxyClientFactory)
- self.assertEqual(factory.headers, {'host': 'example.com'})
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_resource.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_resource.py
deleted file mode 100755
index 9475c6c2..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_resource.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.resource}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.web.http import NOT_FOUND, FORBIDDEN
-from twisted.web.resource import ErrorPage, NoResource, ForbiddenResource
-from twisted.web.test.test_web import DummyRequest
-
-
-class ErrorPageTests(TestCase):
- """
- Tests for L{ErrorPage}, L{NoResource}, and L{ForbiddenResource}.
- """
-
- errorPage = ErrorPage
- noResource = NoResource
- forbiddenResource = ForbiddenResource
-
- def test_getChild(self):
- """
- The C{getChild} method of L{ErrorPage} returns the L{ErrorPage} it is
- called on.
- """
- page = self.errorPage(321, "foo", "bar")
- self.assertIdentical(page.getChild("name", object()), page)
-
-
- def _pageRenderingTest(self, page, code, brief, detail):
- request = DummyRequest([''])
- self.assertEqual(
- page.render(request),
- "\n"
- "<html>\n"
- " <head><title>%s - %s</title></head>\n"
- " <body>\n"
- " <h1>%s</h1>\n"
- " <p>%s</p>\n"
- " </body>\n"
- "</html>\n" % (code, brief, brief, detail))
- self.assertEqual(request.responseCode, code)
- self.assertEqual(
- request.outgoingHeaders,
- {'content-type': 'text/html; charset=utf-8'})
-
-
- def test_errorPageRendering(self):
- """
- L{ErrorPage.render} returns a C{str} describing the error defined by
- the response code and message passed to L{ErrorPage.__init__}. It also
- uses that response code to set the response code on the L{Request}
- passed in.
- """
- code = 321
- brief = "brief description text"
- detail = "much longer text might go here"
- page = self.errorPage(code, brief, detail)
- self._pageRenderingTest(page, code, brief, detail)
-
-
- def test_noResourceRendering(self):
- """
- L{NoResource} sets the HTTP I{NOT FOUND} code.
- """
- detail = "long message"
- page = self.noResource(detail)
- self._pageRenderingTest(page, NOT_FOUND, "No Such Resource", detail)
-
-
- def test_forbiddenResourceRendering(self):
- """
- L{ForbiddenResource} sets the HTTP I{FORBIDDEN} code.
- """
- detail = "longer message"
- page = self.forbiddenResource(detail)
- self._pageRenderingTest(page, FORBIDDEN, "Forbidden Resource", detail)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_script.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_script.py
deleted file mode 100755
index b4248bf0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_script.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.script}.
-"""
-
-import os
-
-from twisted.trial.unittest import TestCase
-from twisted.web.http import NOT_FOUND
-from twisted.web.script import ResourceScriptDirectory, PythonScript
-from twisted.web.test._util import _render
-from twisted.web.test.test_web import DummyRequest
-
-
-class ResourceScriptDirectoryTests(TestCase):
- """
- Tests for L{ResourceScriptDirectory}.
- """
- def test_render(self):
- """
- L{ResourceScriptDirectory.render} sets the HTTP response code to I{NOT
- FOUND}.
- """
- resource = ResourceScriptDirectory(self.mktemp())
- request = DummyRequest([''])
- d = _render(resource, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
-
-
- def test_notFoundChild(self):
- """
- L{ResourceScriptDirectory.getChild} returns a resource which renders an
- response with the HTTP I{NOT FOUND} status code if the indicated child
- does not exist as an entry in the directory used to initialized the
- L{ResourceScriptDirectory}.
- """
- path = self.mktemp()
- os.makedirs(path)
- resource = ResourceScriptDirectory(path)
- request = DummyRequest(['foo'])
- child = resource.getChild("foo", request)
- d = _render(child, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
-
-
-
-class PythonScriptTests(TestCase):
- """
- Tests for L{PythonScript}.
- """
- def test_notFoundRender(self):
- """
- If the source file a L{PythonScript} is initialized with doesn't exist,
- L{PythonScript.render} sets the HTTP response code to I{NOT FOUND}.
- """
- resource = PythonScript(self.mktemp(), None)
- request = DummyRequest([''])
- d = _render(resource, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_soap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_soap.py
deleted file mode 100755
index 247282f1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_soap.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-#
-
-"""Test SOAP support."""
-
-try:
- import SOAPpy
-except ImportError:
- SOAPpy = None
- class SOAPPublisher: pass
-else:
- from twisted.web import soap
- SOAPPublisher = soap.SOAPPublisher
-
-from twisted.trial import unittest
-from twisted.web import server, error
-from twisted.internet import reactor, defer
-
-
-class Test(SOAPPublisher):
-
- def soap_add(self, a, b):
- return a + b
-
- def soap_kwargs(self, a=1, b=2):
- return a + b
- soap_kwargs.useKeywords=True
-
- def soap_triple(self, string, num):
- return [string, num, None]
-
- def soap_struct(self):
- return SOAPpy.structType({"a": "c"})
-
- def soap_defer(self, x):
- return defer.succeed(x)
-
- def soap_deferFail(self):
- return defer.fail(ValueError())
-
- def soap_fail(self):
- raise RuntimeError
-
- def soap_deferFault(self):
- return defer.fail(ValueError())
-
- def soap_complex(self):
- return {"a": ["b", "c", 12, []], "D": "foo"}
-
- def soap_dict(self, map, key):
- return map[key]
-
-
-class SOAPTestCase(unittest.TestCase):
-
- def setUp(self):
- self.publisher = Test()
- self.p = reactor.listenTCP(0, server.Site(self.publisher),
- interface="127.0.0.1")
- self.port = self.p.getHost().port
-
- def tearDown(self):
- return self.p.stopListening()
-
- def proxy(self):
- return soap.Proxy("http://127.0.0.1:%d/" % self.port)
-
- def testResults(self):
- inputOutput = [
- ("add", (2, 3), 5),
- ("defer", ("a",), "a"),
- ("dict", ({"a": 1}, "a"), 1),
- ("triple", ("a", 1), ["a", 1, None])]
-
- dl = []
- for meth, args, outp in inputOutput:
- d = self.proxy().callRemote(meth, *args)
- d.addCallback(self.assertEqual, outp)
- dl.append(d)
-
- # SOAPpy kinda blows.
- d = self.proxy().callRemote('complex')
- d.addCallback(lambda result: result._asdict())
- d.addCallback(self.assertEqual, {"a": ["b", "c", 12, []], "D": "foo"})
- dl.append(d)
-
- # We now return to our regularly scheduled program, already in progress.
- return defer.DeferredList(dl, fireOnOneErrback=True)
-
- def testMethodNotFound(self):
- """
- Check that a non existing method return error 500.
- """
- d = self.proxy().callRemote('doesntexist')
- self.assertFailure(d, error.Error)
- def cb(err):
- self.assertEqual(int(err.status), 500)
- d.addCallback(cb)
- return d
-
- def testLookupFunction(self):
- """
- Test lookupFunction method on publisher, to see available remote
- methods.
- """
- self.assertTrue(self.publisher.lookupFunction("add"))
- self.assertTrue(self.publisher.lookupFunction("fail"))
- self.assertFalse(self.publisher.lookupFunction("foobar"))
-
-if not SOAPpy:
- SOAPTestCase.skip = "SOAPpy not installed"
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_stan.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_stan.py
deleted file mode 100755
index 9aa65a62..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_stan.py
+++ /dev/null
@@ -1,139 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web._stan} portion of the L{twisted.web.template}
-implementation.
-"""
-
-from twisted.web.template import Comment, CDATA, CharRef, Tag
-from twisted.trial.unittest import TestCase
-
-def proto(*a, **kw):
- """
- Produce a new tag for testing.
- """
- return Tag('hello')(*a, **kw)
-
-
-class TestTag(TestCase):
- """
- Tests for L{Tag}.
- """
- def test_fillSlots(self):
- """
- L{Tag.fillSlots} returns self.
- """
- tag = proto()
- self.assertIdentical(tag, tag.fillSlots(test='test'))
-
-
- def test_cloneShallow(self):
- """
- L{Tag.clone} copies all attributes and children of a tag, including its
- render attribute. If the shallow flag is C{False}, that's where it
- stops.
- """
- innerList = ["inner list"]
- tag = proto("How are you", innerList,
- hello="world", render="aSampleMethod")
- tag.fillSlots(foo='bar')
- tag.filename = "foo/bar"
- tag.lineNumber = 6
- tag.columnNumber = 12
- clone = tag.clone(deep=False)
- self.assertEqual(clone.attributes['hello'], 'world')
- self.assertNotIdentical(clone.attributes, tag.attributes)
- self.assertEqual(clone.children, ["How are you", innerList])
- self.assertNotIdentical(clone.children, tag.children)
- self.assertIdentical(clone.children[1], innerList)
- self.assertEqual(tag.slotData, clone.slotData)
- self.assertNotIdentical(tag.slotData, clone.slotData)
- self.assertEqual(clone.filename, "foo/bar")
- self.assertEqual(clone.lineNumber, 6)
- self.assertEqual(clone.columnNumber, 12)
- self.assertEqual(clone.render, "aSampleMethod")
-
-
- def test_cloneDeep(self):
- """
- L{Tag.clone} copies all attributes and children of a tag, including its
- render attribute. In its normal operating mode (where the deep flag is
- C{True}, as is the default), it will clone all sub-lists and sub-tags.
- """
- innerTag = proto("inner")
- innerList = ["inner list"]
- tag = proto("How are you", innerTag, innerList,
- hello="world", render="aSampleMethod")
- tag.fillSlots(foo='bar')
- tag.filename = "foo/bar"
- tag.lineNumber = 6
- tag.columnNumber = 12
- clone = tag.clone()
- self.assertEqual(clone.attributes['hello'], 'world')
- self.assertNotIdentical(clone.attributes, tag.attributes)
- self.assertNotIdentical(clone.children, tag.children)
- # sanity check
- self.assertIdentical(tag.children[1], innerTag)
- # clone should have sub-clone
- self.assertNotIdentical(clone.children[1], innerTag)
- # sanity check
- self.assertIdentical(tag.children[2], innerList)
- # clone should have sub-clone
- self.assertNotIdentical(clone.children[2], innerList)
- self.assertEqual(tag.slotData, clone.slotData)
- self.assertNotIdentical(tag.slotData, clone.slotData)
- self.assertEqual(clone.filename, "foo/bar")
- self.assertEqual(clone.lineNumber, 6)
- self.assertEqual(clone.columnNumber, 12)
- self.assertEqual(clone.render, "aSampleMethod")
-
-
- def test_clear(self):
- """
- L{Tag.clear} removes all children from a tag, but leaves its attributes
- in place.
- """
- tag = proto("these are", "children", "cool", andSoIs='this-attribute')
- tag.clear()
- self.assertEqual(tag.children, [])
- self.assertEqual(tag.attributes, {'andSoIs': 'this-attribute'})
-
-
- def test_suffix(self):
- """
- L{Tag.__call__} accepts Python keywords with a suffixed underscore as
- the DOM attribute of that literal suffix.
- """
- proto = Tag('div')
- tag = proto()
- tag(class_='a')
- self.assertEqual(tag.attributes, {'class': 'a'})
-
-
- def test_commentRepr(self):
- """
- L{Comment.__repr__} returns a value which makes it easy to see what's in
- the comment.
- """
- self.assertEqual(repr(Comment(u"hello there")),
- "Comment(u'hello there')")
-
-
- def test_cdataRepr(self):
- """
- L{CDATA.__repr__} returns a value which makes it easy to see what's in
- the comment.
- """
- self.assertEqual(repr(CDATA(u"test data")),
- "CDATA(u'test data')")
-
-
- def test_charrefRepr(self):
- """
- L{CharRef.__repr__} returns a value which makes it easy to see what
- character is referred to.
- """
- snowman = ord(u"\N{SNOWMAN}")
- self.assertEqual(repr(CharRef(snowman)), "CharRef(9731)")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_static.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_static.py
deleted file mode 100755
index 9e746ce7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_static.py
+++ /dev/null
@@ -1,1486 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.static}.
-"""
-
-import os, re, StringIO
-
-from zope.interface.verify import verifyObject
-
-from twisted.internet import abstract, interfaces
-from twisted.python.compat import set
-from twisted.python.runtime import platform
-from twisted.python.filepath import FilePath
-from twisted.python import log
-from twisted.trial.unittest import TestCase
-from twisted.web import static, http, script, resource
-from twisted.web.server import UnsupportedMethod
-from twisted.web.test.test_web import DummyRequest
-from twisted.web.test._util import _render
-
-
-class StaticDataTests(TestCase):
- """
- Tests for L{Data}.
- """
- def test_headRequest(self):
- """
- L{Data.render} returns an empty response body for a I{HEAD} request.
- """
- data = static.Data("foo", "bar")
- request = DummyRequest([''])
- request.method = 'HEAD'
- d = _render(data, request)
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written), "")
- d.addCallback(cbRendered)
- return d
-
-
- def test_invalidMethod(self):
- """
- L{Data.render} raises L{UnsupportedMethod} in response to a non-I{GET},
- non-I{HEAD} request.
- """
- data = static.Data("foo", "bar")
- request = DummyRequest([''])
- request.method = 'POST'
- self.assertRaises(UnsupportedMethod, data.render, request)
-
-
-
-class StaticFileTests(TestCase):
- """
- Tests for the basic behavior of L{File}.
- """
- def _render(self, resource, request):
- return _render(resource, request)
-
-
- def test_invalidMethod(self):
- """
- L{File.render} raises L{UnsupportedMethod} in response to a non-I{GET},
- non-I{HEAD} request.
- """
- request = DummyRequest([''])
- request.method = 'POST'
- path = FilePath(self.mktemp())
- path.setContent("foo")
- file = static.File(path.path)
- self.assertRaises(UnsupportedMethod, file.render, request)
-
-
- def test_notFound(self):
- """
- If a request is made which encounters a L{File} before a final segment
- which does not correspond to any file in the path the L{File} was
- created with, a not found response is sent.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- file = static.File(base.path)
-
- request = DummyRequest(['foobar'])
- child = resource.getChildForRequest(file, request)
-
- d = self._render(child, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, 404)
- d.addCallback(cbRendered)
- return d
-
-
- def test_emptyChild(self):
- """
- The C{''} child of a L{File} which corresponds to a directory in the
- filesystem is a L{DirectoryLister}.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- file = static.File(base.path)
-
- request = DummyRequest([''])
- child = resource.getChildForRequest(file, request)
- self.assertIsInstance(child, static.DirectoryLister)
- self.assertEqual(child.path, base.path)
-
-
- def test_securityViolationNotFound(self):
- """
- If a request is made which encounters a L{File} before a final segment
- which cannot be looked up in the filesystem due to security
- considerations, a not found response is sent.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- file = static.File(base.path)
-
- request = DummyRequest(['..'])
- child = resource.getChildForRequest(file, request)
-
- d = self._render(child, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, 404)
- d.addCallback(cbRendered)
- return d
-
-
- def test_forbiddenResource(self):
- """
- If the file in the filesystem which would satisfy a request cannot be
- read, L{File.render} sets the HTTP response code to I{FORBIDDEN}.
- """
- base = FilePath(self.mktemp())
- base.setContent('')
- # Make sure we can delete the file later.
- self.addCleanup(base.chmod, 0700)
-
- # Get rid of our own read permission.
- base.chmod(0)
-
- file = static.File(base.path)
- request = DummyRequest([''])
- d = self._render(file, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, 403)
- d.addCallback(cbRendered)
- return d
- if platform.isWindows():
- test_forbiddenResource.skip = "Cannot remove read permission on Windows"
-
-
- def test_indexNames(self):
- """
- If a request is made which encounters a L{File} before a final empty
- segment, a file in the L{File} instance's C{indexNames} list which
- exists in the path the L{File} was created with is served as the
- response to the request.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- base.child("foo.bar").setContent("baz")
- file = static.File(base.path)
- file.indexNames = ['foo.bar']
-
- request = DummyRequest([''])
- child = resource.getChildForRequest(file, request)
-
- d = self._render(child, request)
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written), 'baz')
- self.assertEqual(request.outgoingHeaders['content-length'], '3')
- d.addCallback(cbRendered)
- return d
-
-
- def test_staticFile(self):
- """
- If a request is made which encounters a L{File} before a final segment
- which names a file in the path the L{File} was created with, that file
- is served as the response to the request.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- base.child("foo.bar").setContent("baz")
- file = static.File(base.path)
-
- request = DummyRequest(['foo.bar'])
- child = resource.getChildForRequest(file, request)
-
- d = self._render(child, request)
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written), 'baz')
- self.assertEqual(request.outgoingHeaders['content-length'], '3')
- d.addCallback(cbRendered)
- return d
-
-
- def test_staticFileDeletedGetChild(self):
- """
- A L{static.File} created for a directory which does not exist should
- return childNotFound from L{static.File.getChild}.
- """
- staticFile = static.File(self.mktemp())
- request = DummyRequest(['foo.bar'])
- child = staticFile.getChild("foo.bar", request)
- self.assertEqual(child, staticFile.childNotFound)
-
-
- def test_staticFileDeletedRender(self):
- """
- A L{static.File} created for a file which does not exist should render
- its C{childNotFound} page.
- """
- staticFile = static.File(self.mktemp())
- request = DummyRequest(['foo.bar'])
- request2 = DummyRequest(['foo.bar'])
- d = self._render(staticFile, request)
- d2 = self._render(staticFile.childNotFound, request2)
- def cbRendered2(ignored):
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written),
- ''.join(request2.written))
- d.addCallback(cbRendered)
- return d
- d2.addCallback(cbRendered2)
- return d2
-
-
- def test_headRequest(self):
- """
- L{static.File.render} returns an empty response body for I{HEAD}
- requests.
- """
- path = FilePath(self.mktemp())
- path.setContent("foo")
- file = static.File(path.path)
- request = DummyRequest([''])
- request.method = 'HEAD'
- d = _render(file, request)
- def cbRendered(ignored):
- self.assertEqual("".join(request.written), "")
- d.addCallback(cbRendered)
- return d
-
-
- def test_processors(self):
- """
- If a request is made which encounters a L{File} before a final segment
- which names a file with an extension which is in the L{File}'s
- C{processors} mapping, the processor associated with that extension is
- used to serve the response to the request.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- base.child("foo.bar").setContent(
- "from twisted.web.static import Data\n"
- "resource = Data('dynamic world','text/plain')\n")
-
- file = static.File(base.path)
- file.processors = {'.bar': script.ResourceScript}
- request = DummyRequest(["foo.bar"])
- child = resource.getChildForRequest(file, request)
-
- d = self._render(child, request)
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written), 'dynamic world')
- self.assertEqual(request.outgoingHeaders['content-length'], '13')
- d.addCallback(cbRendered)
- return d
-
-
- def test_ignoreExt(self):
- """
- The list of ignored extensions can be set by passing a value to
- L{File.__init__} or by calling L{File.ignoreExt} later.
- """
- file = static.File(".")
- self.assertEqual(file.ignoredExts, [])
- file.ignoreExt(".foo")
- file.ignoreExt(".bar")
- self.assertEqual(file.ignoredExts, [".foo", ".bar"])
-
- file = static.File(".", ignoredExts=(".bar", ".baz"))
- self.assertEqual(file.ignoredExts, [".bar", ".baz"])
-
-
- def test_ignoredExtensionsIgnored(self):
- """
- A request for the I{base} child of a L{File} succeeds with a resource
- for the I{base<extension>} file in the path the L{File} was created
- with if such a file exists and the L{File} has been configured to
- ignore the I{<extension>} extension.
- """
- base = FilePath(self.mktemp())
- base.makedirs()
- base.child('foo.bar').setContent('baz')
- base.child('foo.quux').setContent('foobar')
- file = static.File(base.path, ignoredExts=(".bar",))
-
- request = DummyRequest(["foo"])
- child = resource.getChildForRequest(file, request)
-
- d = self._render(child, request)
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written), 'baz')
- d.addCallback(cbRendered)
- return d
-
-
-
-class StaticMakeProducerTests(TestCase):
- """
- Tests for L{File.makeProducer}.
- """
-
-
- def makeResourceWithContent(self, content, type=None, encoding=None):
- """
- Make a L{static.File} resource that has C{content} for its content.
-
- @param content: The bytes to use as the contents of the resource.
- @param type: Optional value for the content type of the resource.
- """
- fileName = self.mktemp()
- fileObject = open(fileName, 'w')
- fileObject.write(content)
- fileObject.close()
- resource = static.File(fileName)
- resource.encoding = encoding
- resource.type = type
- return resource
-
-
- def contentHeaders(self, request):
- """
- Extract the content-* headers from the L{DummyRequest} C{request}.
-
- This returns the subset of C{request.outgoingHeaders} of headers that
- start with 'content-'.
- """
- contentHeaders = {}
- for k, v in request.outgoingHeaders.iteritems():
- if k.startswith('content-'):
- contentHeaders[k] = v
- return contentHeaders
-
-
- def test_noRangeHeaderGivesNoRangeStaticProducer(self):
- """
- makeProducer when no Range header is set returns an instance of
- NoRangeStaticProducer.
- """
- resource = self.makeResourceWithContent('')
- request = DummyRequest([])
- producer = resource.makeProducer(request, resource.openForReading())
- self.assertIsInstance(producer, static.NoRangeStaticProducer)
-
-
- def test_noRangeHeaderSets200OK(self):
- """
- makeProducer when no Range header is set sets the responseCode on the
- request to 'OK'.
- """
- resource = self.makeResourceWithContent('')
- request = DummyRequest([])
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(http.OK, request.responseCode)
-
-
- def test_noRangeHeaderSetsContentHeaders(self):
- """
- makeProducer when no Range header is set sets the Content-* headers
- for the response.
- """
- length = 123
- contentType = "text/plain"
- contentEncoding = 'gzip'
- resource = self.makeResourceWithContent(
- 'a'*length, type=contentType, encoding=contentEncoding)
- request = DummyRequest([])
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- {'content-type': contentType, 'content-length': str(length),
- 'content-encoding': contentEncoding},
- self.contentHeaders(request))
-
-
- def test_singleRangeGivesSingleRangeStaticProducer(self):
- """
- makeProducer when the Range header requests a single byte range
- returns an instance of SingleRangeStaticProducer.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3'
- resource = self.makeResourceWithContent('abcdef')
- producer = resource.makeProducer(request, resource.openForReading())
- self.assertIsInstance(producer, static.SingleRangeStaticProducer)
-
-
- def test_singleRangeSets206PartialContent(self):
- """
- makeProducer when the Range header requests a single, satisfiable byte
- range sets the response code on the request to 'Partial Content'.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3'
- resource = self.makeResourceWithContent('abcdef')
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- http.PARTIAL_CONTENT, request.responseCode)
-
-
- def test_singleRangeSetsContentHeaders(self):
- """
- makeProducer when the Range header requests a single, satisfiable byte
- range sets the Content-* headers appropriately.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3'
- contentType = "text/plain"
- contentEncoding = 'gzip'
- resource = self.makeResourceWithContent('abcdef', type=contentType, encoding=contentEncoding)
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- {'content-type': contentType, 'content-encoding': contentEncoding,
- 'content-range': 'bytes 1-3/6', 'content-length': '3'},
- self.contentHeaders(request))
-
-
- def test_singleUnsatisfiableRangeReturnsSingleRangeStaticProducer(self):
- """
- makeProducer still returns an instance of L{SingleRangeStaticProducer}
- when the Range header requests a single unsatisfiable byte range.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=4-10'
- resource = self.makeResourceWithContent('abc')
- producer = resource.makeProducer(request, resource.openForReading())
- self.assertIsInstance(producer, static.SingleRangeStaticProducer)
-
-
- def test_singleUnsatisfiableRangeSets416ReqestedRangeNotSatisfiable(self):
- """
- makeProducer sets the response code of the request to of 'Requested
- Range Not Satisfiable' when the Range header requests a single
- unsatisfiable byte range.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=4-10'
- resource = self.makeResourceWithContent('abc')
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- http.REQUESTED_RANGE_NOT_SATISFIABLE, request.responseCode)
-
-
- def test_singleUnsatisfiableRangeSetsContentHeaders(self):
- """
- makeProducer when the Range header requests a single, unsatisfiable
- byte range sets the Content-* headers appropriately.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=4-10'
- contentType = "text/plain"
- resource = self.makeResourceWithContent('abc', type=contentType)
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- {'content-type': 'text/plain', 'content-length': '0',
- 'content-range': 'bytes */3'},
- self.contentHeaders(request))
-
-
- def test_singlePartiallyOverlappingRangeSetsContentHeaders(self):
- """
- makeProducer when the Range header requests a single byte range that
- partly overlaps the resource sets the Content-* headers appropriately.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=2-10'
- contentType = "text/plain"
- resource = self.makeResourceWithContent('abc', type=contentType)
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- {'content-type': 'text/plain', 'content-length': '1',
- 'content-range': 'bytes 2-2/3'},
- self.contentHeaders(request))
-
-
- def test_multipleRangeGivesMultipleRangeStaticProducer(self):
- """
- makeProducer when the Range header requests a single byte range
- returns an instance of MultipleRangeStaticProducer.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3,5-6'
- resource = self.makeResourceWithContent('abcdef')
- producer = resource.makeProducer(request, resource.openForReading())
- self.assertIsInstance(producer, static.MultipleRangeStaticProducer)
-
-
- def test_multipleRangeSets206PartialContent(self):
- """
- makeProducer when the Range header requests a multiple satisfiable
- byte ranges sets the response code on the request to 'Partial
- Content'.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3,5-6'
- resource = self.makeResourceWithContent('abcdef')
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- http.PARTIAL_CONTENT, request.responseCode)
-
-
- def test_mutipleRangeSetsContentHeaders(self):
- """
- makeProducer when the Range header requests a single, satisfiable byte
- range sets the Content-* headers appropriately.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3,5-6'
- resource = self.makeResourceWithContent(
- 'abcdefghijkl', encoding='gzip')
- producer = resource.makeProducer(request, resource.openForReading())
- contentHeaders = self.contentHeaders(request)
- # The only content-* headers set are content-type and content-length.
- self.assertEqual(
- set(['content-length', 'content-type']),
- set(contentHeaders.keys()))
- # The content-length depends on the boundary used in the response.
- expectedLength = 5
- for boundary, offset, size in producer.rangeInfo:
- expectedLength += len(boundary)
- self.assertEqual(expectedLength, contentHeaders['content-length'])
- # Content-type should be set to a value indicating a multipart
- # response and the boundary used to separate the parts.
- self.assertIn('content-type', contentHeaders)
- contentType = contentHeaders['content-type']
- self.assertNotIdentical(
- None, re.match(
- 'multipart/byteranges; boundary="[^"]*"\Z', contentType))
- # Content-encoding is not set in the response to a multiple range
- # response, which is a bit wussy but works well enough with the way
- # static.File does content-encodings...
- self.assertNotIn('content-encoding', contentHeaders)
-
-
- def test_multipleUnsatisfiableRangesReturnsMultipleRangeStaticProducer(self):
- """
- makeProducer still returns an instance of L{SingleRangeStaticProducer}
- when the Range header requests multiple ranges, none of which are
- satisfiable.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=10-12,15-20'
- resource = self.makeResourceWithContent('abc')
- producer = resource.makeProducer(request, resource.openForReading())
- self.assertIsInstance(producer, static.MultipleRangeStaticProducer)
-
-
- def test_multipleUnsatisfiableRangesSets416ReqestedRangeNotSatisfiable(self):
- """
- makeProducer sets the response code of the request to of 'Requested
- Range Not Satisfiable' when the Range header requests multiple ranges,
- none of which are satisfiable.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=10-12,15-20'
- resource = self.makeResourceWithContent('abc')
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- http.REQUESTED_RANGE_NOT_SATISFIABLE, request.responseCode)
-
-
- def test_multipleUnsatisfiableRangeSetsContentHeaders(self):
- """
- makeProducer when the Range header requests multiple ranges, none of
- which are satisfiable, sets the Content-* headers appropriately.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=4-10'
- contentType = "text/plain"
- request.headers['range'] = 'bytes=10-12,15-20'
- resource = self.makeResourceWithContent('abc', type=contentType)
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- {'content-length': '0', 'content-range': 'bytes */3'},
- self.contentHeaders(request))
-
-
- def test_oneSatisfiableRangeIsEnough(self):
- """
- makeProducer when the Range header requests multiple ranges, at least
- one of which matches, sets the response code to 'Partial Content'.
- """
- request = DummyRequest([])
- request.headers['range'] = 'bytes=1-3,100-200'
- resource = self.makeResourceWithContent('abcdef')
- resource.makeProducer(request, resource.openForReading())
- self.assertEqual(
- http.PARTIAL_CONTENT, request.responseCode)
-
-
-
-class StaticProducerTests(TestCase):
- """
- Tests for the abstract L{StaticProducer}.
- """
-
- def test_stopProducingClosesFile(self):
- """
- L{StaticProducer.stopProducing} closes the file object the producer is
- producing data from.
- """
- fileObject = StringIO.StringIO()
- producer = static.StaticProducer(None, fileObject)
- producer.stopProducing()
- self.assertTrue(fileObject.closed)
-
-
- def test_stopProducingSetsRequestToNone(self):
- """
- L{StaticProducer.stopProducing} sets the request instance variable to
- None, which indicates to subclasses' resumeProducing methods that no
- more data should be produced.
- """
- fileObject = StringIO.StringIO()
- producer = static.StaticProducer(DummyRequest([]), fileObject)
- producer.stopProducing()
- self.assertIdentical(None, producer.request)
-
-
-
-class NoRangeStaticProducerTests(TestCase):
- """
- Tests for L{NoRangeStaticProducer}.
- """
-
- def test_implementsIPullProducer(self):
- """
- L{NoRangeStaticProducer} implements L{IPullProducer}.
- """
- verifyObject(
- interfaces.IPullProducer,
- static.NoRangeStaticProducer(None, None))
-
-
- def test_resumeProducingProducesContent(self):
- """
- L{NoRangeStaticProducer.resumeProducing} writes content from the
- resource to the request.
- """
- request = DummyRequest([])
- content = 'abcdef'
- producer = static.NoRangeStaticProducer(
- request, StringIO.StringIO(content))
- # start calls registerProducer on the DummyRequest, which pulls all
- # output from the producer and so we just need this one call.
- producer.start()
- self.assertEqual(content, ''.join(request.written))
-
-
- def test_resumeProducingBuffersOutput(self):
- """
- L{NoRangeStaticProducer.start} writes at most
- C{abstract.FileDescriptor.bufferSize} bytes of content from the
- resource to the request at once.
- """
- request = DummyRequest([])
- bufferSize = abstract.FileDescriptor.bufferSize
- content = 'a' * (2*bufferSize + 1)
- producer = static.NoRangeStaticProducer(
- request, StringIO.StringIO(content))
- # start calls registerProducer on the DummyRequest, which pulls all
- # output from the producer and so we just need this one call.
- producer.start()
- expected = [
- content[0:bufferSize],
- content[bufferSize:2*bufferSize],
- content[2*bufferSize:]
- ]
- self.assertEqual(expected, request.written)
-
-
- def test_finishCalledWhenDone(self):
- """
- L{NoRangeStaticProducer.resumeProducing} calls finish() on the request
- after it is done producing content.
- """
- request = DummyRequest([])
- finishDeferred = request.notifyFinish()
- callbackList = []
- finishDeferred.addCallback(callbackList.append)
- producer = static.NoRangeStaticProducer(
- request, StringIO.StringIO('abcdef'))
- # start calls registerProducer on the DummyRequest, which pulls all
- # output from the producer and so we just need this one call.
- producer.start()
- self.assertEqual([None], callbackList)
-
-
-
-class SingleRangeStaticProducerTests(TestCase):
- """
- Tests for L{SingleRangeStaticProducer}.
- """
-
- def test_implementsIPullProducer(self):
- """
- L{SingleRangeStaticProducer} implements L{IPullProducer}.
- """
- verifyObject(
- interfaces.IPullProducer,
- static.SingleRangeStaticProducer(None, None, None, None))
-
-
- def test_resumeProducingProducesContent(self):
- """
- L{SingleRangeStaticProducer.resumeProducing} writes the given amount
- of content, starting at the given offset, from the resource to the
- request.
- """
- request = DummyRequest([])
- content = 'abcdef'
- producer = static.SingleRangeStaticProducer(
- request, StringIO.StringIO(content), 1, 3)
- # DummyRequest.registerProducer pulls all output from the producer, so
- # we just need to call start.
- producer.start()
- self.assertEqual(content[1:4], ''.join(request.written))
-
-
- def test_resumeProducingBuffersOutput(self):
- """
- L{SingleRangeStaticProducer.start} writes at most
- C{abstract.FileDescriptor.bufferSize} bytes of content from the
- resource to the request at once.
- """
- request = DummyRequest([])
- bufferSize = abstract.FileDescriptor.bufferSize
- content = 'abc' * bufferSize
- producer = static.SingleRangeStaticProducer(
- request, StringIO.StringIO(content), 1, bufferSize+10)
- # DummyRequest.registerProducer pulls all output from the producer, so
- # we just need to call start.
- producer.start()
- expected = [
- content[1:bufferSize+1],
- content[bufferSize+1:bufferSize+11],
- ]
- self.assertEqual(expected, request.written)
-
-
- def test_finishCalledWhenDone(self):
- """
- L{SingleRangeStaticProducer.resumeProducing} calls finish() on the
- request after it is done producing content.
- """
- request = DummyRequest([])
- finishDeferred = request.notifyFinish()
- callbackList = []
- finishDeferred.addCallback(callbackList.append)
- producer = static.SingleRangeStaticProducer(
- request, StringIO.StringIO('abcdef'), 1, 1)
- # start calls registerProducer on the DummyRequest, which pulls all
- # output from the producer and so we just need this one call.
- producer.start()
- self.assertEqual([None], callbackList)
-
-
-
-class MultipleRangeStaticProducerTests(TestCase):
- """
- Tests for L{MultipleRangeStaticProducer}.
- """
-
- def test_implementsIPullProducer(self):
- """
- L{MultipleRangeStaticProducer} implements L{IPullProducer}.
- """
- verifyObject(
- interfaces.IPullProducer,
- static.MultipleRangeStaticProducer(None, None, None))
-
-
- def test_resumeProducingProducesContent(self):
- """
- L{MultipleRangeStaticProducer.resumeProducing} writes the requested
- chunks of content from the resource to the request, with the supplied
- boundaries in between each chunk.
- """
- request = DummyRequest([])
- content = 'abcdef'
- producer = static.MultipleRangeStaticProducer(
- request, StringIO.StringIO(content), [('1', 1, 3), ('2', 5, 1)])
- # DummyRequest.registerProducer pulls all output from the producer, so
- # we just need to call start.
- producer.start()
- self.assertEqual('1bcd2f', ''.join(request.written))
-
-
- def test_resumeProducingBuffersOutput(self):
- """
- L{MultipleRangeStaticProducer.start} writes about
- C{abstract.FileDescriptor.bufferSize} bytes of content from the
- resource to the request at once.
-
- To be specific about the 'about' above: it can write slightly more,
- for example in the case where the first boundary plus the first chunk
- is less than C{bufferSize} but first boundary plus the first chunk
- plus the second boundary is more, but this is unimportant as in
- practice the boundaries are fairly small. On the other side, it is
- important for performance to bundle up several small chunks into one
- call to request.write.
- """
- request = DummyRequest([])
- content = '0123456789' * 2
- producer = static.MultipleRangeStaticProducer(
- request, StringIO.StringIO(content),
- [('a', 0, 2), ('b', 5, 10), ('c', 0, 0)])
- producer.bufferSize = 10
- # DummyRequest.registerProducer pulls all output from the producer, so
- # we just need to call start.
- producer.start()
- expected = [
- 'a' + content[0:2] + 'b' + content[5:11],
- content[11:15] + 'c',
- ]
- self.assertEqual(expected, request.written)
-
-
- def test_finishCalledWhenDone(self):
- """
- L{MultipleRangeStaticProducer.resumeProducing} calls finish() on the
- request after it is done producing content.
- """
- request = DummyRequest([])
- finishDeferred = request.notifyFinish()
- callbackList = []
- finishDeferred.addCallback(callbackList.append)
- producer = static.MultipleRangeStaticProducer(
- request, StringIO.StringIO('abcdef'), [('', 1, 2)])
- # start calls registerProducer on the DummyRequest, which pulls all
- # output from the producer and so we just need this one call.
- producer.start()
- self.assertEqual([None], callbackList)
-
-
-
-class RangeTests(TestCase):
- """
- Tests for I{Range-Header} support in L{twisted.web.static.File}.
-
- @type file: L{file}
- @ivar file: Temporary (binary) file containing the content to be served.
-
- @type resource: L{static.File}
- @ivar resource: A leaf web resource using C{file} as content.
-
- @type request: L{DummyRequest}
- @ivar request: A fake request, requesting C{resource}.
-
- @type catcher: L{list}
- @ivar catcher: List which gathers all log information.
- """
- def setUp(self):
- """
- Create a temporary file with a fixed payload of 64 bytes. Create a
- resource for that file and create a request which will be for that
- resource. Each test can set a different range header to test different
- aspects of the implementation.
- """
- path = FilePath(self.mktemp())
- # This is just a jumble of random stuff. It's supposed to be a good
- # set of data for this test, particularly in order to avoid
- # accidentally seeing the right result by having a byte sequence
- # repeated at different locations or by having byte values which are
- # somehow correlated with their position in the string.
- self.payload = ('\xf8u\xf3E\x8c7\xce\x00\x9e\xb6a0y0S\xf0\xef\xac\xb7'
- '\xbe\xb5\x17M\x1e\x136k{\x1e\xbe\x0c\x07\x07\t\xd0'
- '\xbckY\xf5I\x0b\xb8\x88oZ\x1d\x85b\x1a\xcdk\xf2\x1d'
- '&\xfd%\xdd\x82q/A\x10Y\x8b')
- path.setContent(self.payload)
- self.file = path.open()
- self.resource = static.File(self.file.name)
- self.resource.isLeaf = 1
- self.request = DummyRequest([''])
- self.request.uri = self.file.name
- self.catcher = []
- log.addObserver(self.catcher.append)
-
-
- def tearDown(self):
- """
- Clean up the resource file and the log observer.
- """
- self.file.close()
- log.removeObserver(self.catcher.append)
-
-
- def _assertLogged(self, expected):
- """
- Asserts that a given log message occurred with an expected message.
- """
- logItem = self.catcher.pop()
- self.assertEqual(logItem["message"][0], expected)
- self.assertEqual(
- self.catcher, [], "An additional log occured: %r" % (logItem,))
-
-
- def test_invalidRanges(self):
- """
- L{File._parseRangeHeader} raises L{ValueError} when passed
- syntactically invalid byte ranges.
- """
- f = self.resource._parseRangeHeader
-
- # there's no =
- self.assertRaises(ValueError, f, 'bytes')
-
- # unknown isn't a valid Bytes-Unit
- self.assertRaises(ValueError, f, 'unknown=1-2')
-
- # there's no - in =stuff
- self.assertRaises(ValueError, f, 'bytes=3')
-
- # both start and end are empty
- self.assertRaises(ValueError, f, 'bytes=-')
-
- # start isn't an integer
- self.assertRaises(ValueError, f, 'bytes=foo-')
-
- # end isn't an integer
- self.assertRaises(ValueError, f, 'bytes=-foo')
-
- # end isn't equal to or greater than start
- self.assertRaises(ValueError, f, 'bytes=5-4')
-
-
- def test_rangeMissingStop(self):
- """
- A single bytes range without an explicit stop position is parsed into a
- two-tuple giving the start position and C{None}.
- """
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=0-'), [(0, None)])
-
-
- def test_rangeMissingStart(self):
- """
- A single bytes range without an explicit start position is parsed into
- a two-tuple of C{None} and the end position.
- """
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=-3'), [(None, 3)])
-
-
- def test_range(self):
- """
- A single bytes range with explicit start and stop positions is parsed
- into a two-tuple of those positions.
- """
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=2-5'), [(2, 5)])
-
-
- def test_rangeWithSpace(self):
- """
- A single bytes range with whitespace in allowed places is parsed in
- the same way as it would be without the whitespace.
- """
- self.assertEqual(
- self.resource._parseRangeHeader(' bytes=1-2 '), [(1, 2)])
- self.assertEqual(
- self.resource._parseRangeHeader('bytes =1-2 '), [(1, 2)])
- self.assertEqual(
- self.resource._parseRangeHeader('bytes= 1-2'), [(1, 2)])
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=1 -2'), [(1, 2)])
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=1- 2'), [(1, 2)])
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=1-2 '), [(1, 2)])
-
-
- def test_nullRangeElements(self):
- """
- If there are multiple byte ranges but only one is non-null, the
- non-null range is parsed and its start and stop returned.
- """
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=1-2,\r\n, ,\t'), [(1, 2)])
-
-
- def test_multipleRanges(self):
- """
- If multiple byte ranges are specified their starts and stops are
- returned.
- """
- self.assertEqual(
- self.resource._parseRangeHeader('bytes=1-2,3-4'),
- [(1, 2), (3, 4)])
-
-
- def test_bodyLength(self):
- """
- A correct response to a range request is as long as the length of the
- requested range.
- """
- self.request.headers['range'] = 'bytes=0-43'
- self.resource.render(self.request)
- self.assertEqual(len(''.join(self.request.written)), 44)
-
-
- def test_invalidRangeRequest(self):
- """
- An incorrect range request (RFC 2616 defines a correct range request as
- a Bytes-Unit followed by a '=' character followed by a specific range.
- Only 'bytes' is defined) results in the range header value being logged
- and a normal 200 response being sent.
- """
- self.request.headers['range'] = range = 'foobar=0-43'
- self.resource.render(self.request)
- expected = "Ignoring malformed Range header %r" % (range,)
- self._assertLogged(expected)
- self.assertEqual(''.join(self.request.written), self.payload)
- self.assertEqual(self.request.responseCode, http.OK)
- self.assertEqual(
- self.request.outgoingHeaders['content-length'],
- str(len(self.payload)))
-
-
- def parseMultipartBody(self, body, boundary):
- """
- Parse C{body} as a multipart MIME response separated by C{boundary}.
-
- Note that this with fail the calling test on certain syntactic
- problems.
- """
- sep = "\r\n--" + boundary
- parts = ''.join(body).split(sep)
- self.assertEqual('', parts[0])
- self.assertEqual('--\r\n', parts[-1])
- parsed_parts = []
- for part in parts[1:-1]:
- before, header1, header2, blank, partBody = part.split('\r\n', 4)
- headers = header1 + '\n' + header2
- self.assertEqual('', before)
- self.assertEqual('', blank)
- partContentTypeValue = re.search(
- '^content-type: (.*)$', headers, re.I|re.M).group(1)
- start, end, size = re.search(
- '^content-range: bytes ([0-9]+)-([0-9]+)/([0-9]+)$',
- headers, re.I|re.M).groups()
- parsed_parts.append(
- {'contentType': partContentTypeValue,
- 'contentRange': (start, end, size),
- 'body': partBody})
- return parsed_parts
-
-
- def test_multipleRangeRequest(self):
- """
- The response to a request for multipe bytes ranges is a MIME-ish
- multipart response.
- """
- startEnds = [(0, 2), (20, 30), (40, 50)]
- rangeHeaderValue = ','.join(["%s-%s"%(s,e) for (s, e) in startEnds])
- self.request.headers['range'] = 'bytes=' + rangeHeaderValue
- self.resource.render(self.request)
- self.assertEqual(self.request.responseCode, http.PARTIAL_CONTENT)
- boundary = re.match(
- '^multipart/byteranges; boundary="(.*)"$',
- self.request.outgoingHeaders['content-type']).group(1)
- parts = self.parseMultipartBody(''.join(self.request.written), boundary)
- self.assertEqual(len(startEnds), len(parts))
- for part, (s, e) in zip(parts, startEnds):
- self.assertEqual(self.resource.type, part['contentType'])
- start, end, size = part['contentRange']
- self.assertEqual(int(start), s)
- self.assertEqual(int(end), e)
- self.assertEqual(int(size), self.resource.getFileSize())
- self.assertEqual(self.payload[s:e+1], part['body'])
-
-
- def test_multipleRangeRequestWithRangeOverlappingEnd(self):
- """
- The response to a request for multipe bytes ranges is a MIME-ish
- multipart response, even when one of the ranged falls off the end of
- the resource.
- """
- startEnds = [(0, 2), (40, len(self.payload) + 10)]
- rangeHeaderValue = ','.join(["%s-%s"%(s,e) for (s, e) in startEnds])
- self.request.headers['range'] = 'bytes=' + rangeHeaderValue
- self.resource.render(self.request)
- self.assertEqual(self.request.responseCode, http.PARTIAL_CONTENT)
- boundary = re.match(
- '^multipart/byteranges; boundary="(.*)"$',
- self.request.outgoingHeaders['content-type']).group(1)
- parts = self.parseMultipartBody(''.join(self.request.written), boundary)
- self.assertEqual(len(startEnds), len(parts))
- for part, (s, e) in zip(parts, startEnds):
- self.assertEqual(self.resource.type, part['contentType'])
- start, end, size = part['contentRange']
- self.assertEqual(int(start), s)
- self.assertEqual(int(end), min(e, self.resource.getFileSize()-1))
- self.assertEqual(int(size), self.resource.getFileSize())
- self.assertEqual(self.payload[s:e+1], part['body'])
-
-
- def test_implicitEnd(self):
- """
- If the end byte position is omitted, then it is treated as if the
- length of the resource was specified by the end byte position.
- """
- self.request.headers['range'] = 'bytes=23-'
- self.resource.render(self.request)
- self.assertEqual(''.join(self.request.written), self.payload[23:])
- self.assertEqual(len(''.join(self.request.written)), 41)
- self.assertEqual(self.request.responseCode, http.PARTIAL_CONTENT)
- self.assertEqual(
- self.request.outgoingHeaders['content-range'], 'bytes 23-63/64')
- self.assertEqual(self.request.outgoingHeaders['content-length'], '41')
-
-
- def test_implicitStart(self):
- """
- If the start byte position is omitted but the end byte position is
- supplied, then the range is treated as requesting the last -N bytes of
- the resource, where N is the end byte position.
- """
- self.request.headers['range'] = 'bytes=-17'
- self.resource.render(self.request)
- self.assertEqual(''.join(self.request.written), self.payload[-17:])
- self.assertEqual(len(''.join(self.request.written)), 17)
- self.assertEqual(self.request.responseCode, http.PARTIAL_CONTENT)
- self.assertEqual(
- self.request.outgoingHeaders['content-range'], 'bytes 47-63/64')
- self.assertEqual(self.request.outgoingHeaders['content-length'], '17')
-
-
- def test_explicitRange(self):
- """
- A correct response to a bytes range header request from A to B starts
- with the A'th byte and ends with (including) the B'th byte. The first
- byte of a page is numbered with 0.
- """
- self.request.headers['range'] = 'bytes=3-43'
- self.resource.render(self.request)
- written = ''.join(self.request.written)
- self.assertEqual(written, self.payload[3:44])
- self.assertEqual(self.request.responseCode, http.PARTIAL_CONTENT)
- self.assertEqual(
- self.request.outgoingHeaders['content-range'], 'bytes 3-43/64')
- self.assertEqual(
- str(len(written)), self.request.outgoingHeaders['content-length'])
-
-
- def test_explicitRangeOverlappingEnd(self):
- """
- A correct response to a bytes range header request from A to B when B
- is past the end of the resource starts with the A'th byte and ends
- with the last byte of the resource. The first byte of a page is
- numbered with 0.
- """
- self.request.headers['range'] = 'bytes=40-100'
- self.resource.render(self.request)
- written = ''.join(self.request.written)
- self.assertEqual(written, self.payload[40:])
- self.assertEqual(self.request.responseCode, http.PARTIAL_CONTENT)
- self.assertEqual(
- self.request.outgoingHeaders['content-range'], 'bytes 40-63/64')
- self.assertEqual(
- str(len(written)), self.request.outgoingHeaders['content-length'])
-
-
- def test_statusCodeRequestedRangeNotSatisfiable(self):
- """
- If a range is syntactically invalid due to the start being greater than
- the end, the range header is ignored (the request is responded to as if
- it were not present).
- """
- self.request.headers['range'] = 'bytes=20-13'
- self.resource.render(self.request)
- self.assertEqual(self.request.responseCode, http.OK)
- self.assertEqual(''.join(self.request.written), self.payload)
- self.assertEqual(
- self.request.outgoingHeaders['content-length'],
- str(len(self.payload)))
-
-
- def test_invalidStartBytePos(self):
- """
- If a range is unsatisfiable due to the start not being less than the
- length of the resource, the response is 416 (Requested range not
- satisfiable) and no data is written to the response body (RFC 2616,
- section 14.35.1).
- """
- self.request.headers['range'] = 'bytes=67-108'
- self.resource.render(self.request)
- self.assertEqual(
- self.request.responseCode, http.REQUESTED_RANGE_NOT_SATISFIABLE)
- self.assertEqual(''.join(self.request.written), '')
- self.assertEqual(self.request.outgoingHeaders['content-length'], '0')
- # Sections 10.4.17 and 14.16
- self.assertEqual(
- self.request.outgoingHeaders['content-range'],
- 'bytes */%d' % (len(self.payload),))
-
-
-
-class DirectoryListerTest(TestCase):
- """
- Tests for L{static.DirectoryLister}.
- """
- def _request(self, uri):
- request = DummyRequest([''])
- request.uri = uri
- return request
-
-
- def test_renderHeader(self):
- """
- L{static.DirectoryLister} prints the request uri as header of the
- rendered content.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
-
- lister = static.DirectoryLister(path.path)
- data = lister.render(self._request('foo'))
- self.assertIn("<h1>Directory listing for foo</h1>", data)
- self.assertIn("<title>Directory listing for foo</title>", data)
-
-
- def test_renderUnquoteHeader(self):
- """
- L{static.DirectoryLister} unquote the request uri before printing it.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
-
- lister = static.DirectoryLister(path.path)
- data = lister.render(self._request('foo%20bar'))
- self.assertIn("<h1>Directory listing for foo bar</h1>", data)
- self.assertIn("<title>Directory listing for foo bar</title>", data)
-
-
- def test_escapeHeader(self):
- """
- L{static.DirectoryLister} escape "&", "<" and ">" after unquoting the
- request uri.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
-
- lister = static.DirectoryLister(path.path)
- data = lister.render(self._request('foo%26bar'))
- self.assertIn("<h1>Directory listing for foo&amp;bar</h1>", data)
- self.assertIn("<title>Directory listing for foo&amp;bar</title>", data)
-
-
- def test_renderFiles(self):
- """
- L{static.DirectoryLister} is able to list all the files inside a
- directory.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- path.child('file1').setContent("content1")
- path.child('file2').setContent("content2" * 1000)
-
- lister = static.DirectoryLister(path.path)
- data = lister.render(self._request('foo'))
- body = """<tr class="odd">
- <td><a href="file1">file1</a></td>
- <td>8B</td>
- <td>[text/html]</td>
- <td></td>
-</tr>
-<tr class="even">
- <td><a href="file2">file2</a></td>
- <td>7K</td>
- <td>[text/html]</td>
- <td></td>
-</tr>"""
- self.assertIn(body, data)
-
-
- def test_renderDirectories(self):
- """
- L{static.DirectoryLister} is able to list all the directories inside
- a directory.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- path.child('dir1').makedirs()
- path.child('dir2 & 3').makedirs()
-
- lister = static.DirectoryLister(path.path)
- data = lister.render(self._request('foo'))
- body = """<tr class="odd">
- <td><a href="dir1/">dir1/</a></td>
- <td></td>
- <td>[Directory]</td>
- <td></td>
-</tr>
-<tr class="even">
- <td><a href="dir2%20%26%203/">dir2 &amp; 3/</a></td>
- <td></td>
- <td>[Directory]</td>
- <td></td>
-</tr>"""
- self.assertIn(body, data)
-
-
- def test_renderFiltered(self):
- """
- L{static.DirectoryLister} takes a optional C{dirs} argument that
- filter out the list of of directories and files printed.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- path.child('dir1').makedirs()
- path.child('dir2').makedirs()
- path.child('dir3').makedirs()
- lister = static.DirectoryLister(path.path, dirs=["dir1", "dir3"])
- data = lister.render(self._request('foo'))
- body = """<tr class="odd">
- <td><a href="dir1/">dir1/</a></td>
- <td></td>
- <td>[Directory]</td>
- <td></td>
-</tr>
-<tr class="even">
- <td><a href="dir3/">dir3/</a></td>
- <td></td>
- <td>[Directory]</td>
- <td></td>
-</tr>"""
- self.assertIn(body, data)
-
-
- def test_oddAndEven(self):
- """
- L{static.DirectoryLister} gives an alternate class for each odd and
- even rows in the table.
- """
- lister = static.DirectoryLister(None)
- elements = [{"href": "", "text": "", "size": "", "type": "",
- "encoding": ""} for i in xrange(5)]
- content = lister._buildTableContent(elements)
-
- self.assertEqual(len(content), 5)
- self.assertTrue(content[0].startswith('<tr class="odd">'))
- self.assertTrue(content[1].startswith('<tr class="even">'))
- self.assertTrue(content[2].startswith('<tr class="odd">'))
- self.assertTrue(content[3].startswith('<tr class="even">'))
- self.assertTrue(content[4].startswith('<tr class="odd">'))
-
-
- def test_contentType(self):
- """
- L{static.DirectoryLister} produces a MIME-type that indicates that it is
- HTML, and includes its charset (UTF-8).
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- lister = static.DirectoryLister(path.path)
- req = self._request('')
- lister.render(req)
- self.assertEqual(req.outgoingHeaders['content-type'],
- "text/html; charset=utf-8")
-
-
- def test_mimeTypeAndEncodings(self):
- """
- L{static.DirectoryLister} is able to detect mimetype and encoding of
- listed files.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- path.child('file1.txt').setContent("file1")
- path.child('file2.py').setContent("python")
- path.child('file3.conf.gz').setContent("conf compressed")
- path.child('file4.diff.bz2').setContent("diff compressed")
- directory = os.listdir(path.path)
- directory.sort()
-
- contentTypes = {
- ".txt": "text/plain",
- ".py": "text/python",
- ".conf": "text/configuration",
- ".diff": "text/diff"
- }
-
- lister = static.DirectoryLister(path.path, contentTypes=contentTypes)
- dirs, files = lister._getFilesAndDirectories(directory)
- self.assertEqual(dirs, [])
- self.assertEqual(files, [
- {'encoding': '',
- 'href': 'file1.txt',
- 'size': '5B',
- 'text': 'file1.txt',
- 'type': '[text/plain]'},
- {'encoding': '',
- 'href': 'file2.py',
- 'size': '6B',
- 'text': 'file2.py',
- 'type': '[text/python]'},
- {'encoding': '[gzip]',
- 'href': 'file3.conf.gz',
- 'size': '15B',
- 'text': 'file3.conf.gz',
- 'type': '[text/configuration]'},
- {'encoding': '[bzip2]',
- 'href': 'file4.diff.bz2',
- 'size': '15B',
- 'text': 'file4.diff.bz2',
- 'type': '[text/diff]'}])
-
-
- def test_brokenSymlink(self):
- """
- If on the file in the listing points to a broken symlink, it should not
- be returned by L{static.DirectoryLister._getFilesAndDirectories}.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- file1 = path.child('file1')
- file1.setContent("file1")
- file1.linkTo(path.child("file2"))
- file1.remove()
-
- lister = static.DirectoryLister(path.path)
- directory = os.listdir(path.path)
- directory.sort()
- dirs, files = lister._getFilesAndDirectories(directory)
- self.assertEqual(dirs, [])
- self.assertEqual(files, [])
-
- if getattr(os, "symlink", None) is None:
- test_brokenSymlink.skip = "No symlink support"
-
-
- def test_childrenNotFound(self):
- """
- Any child resource of L{static.DirectoryLister} renders an HTTP
- I{NOT FOUND} response code.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- lister = static.DirectoryLister(path.path)
- request = self._request('')
- child = resource.getChildForRequest(lister, request)
- result = _render(child, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, http.NOT_FOUND)
- result.addCallback(cbRendered)
- return result
-
-
- def test_repr(self):
- """
- L{static.DirectoryLister.__repr__} gives the path of the lister.
- """
- path = FilePath(self.mktemp())
- lister = static.DirectoryLister(path.path)
- self.assertEqual(repr(lister),
- "<DirectoryLister of %r>" % (path.path,))
- self.assertEqual(str(lister),
- "<DirectoryLister of %r>" % (path.path,))
-
- def test_formatFileSize(self):
- """
- L{static.formatFileSize} format an amount of bytes into a more readable
- format.
- """
- self.assertEqual(static.formatFileSize(0), "0B")
- self.assertEqual(static.formatFileSize(123), "123B")
- self.assertEqual(static.formatFileSize(4567), "4K")
- self.assertEqual(static.formatFileSize(8900000), "8M")
- self.assertEqual(static.formatFileSize(1234000000), "1G")
- self.assertEqual(static.formatFileSize(1234567890000), "1149G")
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_tap.py
deleted file mode 100755
index a3e33da9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_tap.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.tap}.
-"""
-
-import os, stat
-
-from twisted.python.usage import UsageError
-from twisted.python.filepath import FilePath
-from twisted.internet.interfaces import IReactorUNIX
-from twisted.internet import reactor
-from twisted.python.threadpool import ThreadPool
-from twisted.trial.unittest import TestCase
-from twisted.application import strports
-
-from twisted.web.server import Site
-from twisted.web.static import Data, File
-from twisted.web.distrib import ResourcePublisher, UserDirectory
-from twisted.web.wsgi import WSGIResource
-from twisted.web.tap import Options, makePersonalServerFactory, makeService
-from twisted.web.twcgi import CGIScript
-from twisted.web.script import PythonScript
-
-
-from twisted.spread.pb import PBServerFactory
-
-application = object()
-
-class ServiceTests(TestCase):
- """
- Tests for the service creation APIs in L{twisted.web.tap}.
- """
- def _pathOption(self):
- """
- Helper for the I{--path} tests which creates a directory and creates
- an L{Options} object which uses that directory as its static
- filesystem root.
-
- @return: A two-tuple of a L{FilePath} referring to the directory and
- the value associated with the C{'root'} key in the L{Options}
- instance after parsing a I{--path} option.
- """
- path = FilePath(self.mktemp())
- path.makedirs()
- options = Options()
- options.parseOptions(['--path', path.path])
- root = options['root']
- return path, root
-
-
- def test_path(self):
- """
- The I{--path} option causes L{Options} to create a root resource
- which serves responses from the specified path.
- """
- path, root = self._pathOption()
- self.assertIsInstance(root, File)
- self.assertEqual(root.path, path.path)
-
-
- def test_cgiProcessor(self):
- """
- The I{--path} option creates a root resource which serves a
- L{CGIScript} instance for any child with the C{".cgi"} extension.
- """
- path, root = self._pathOption()
- path.child("foo.cgi").setContent("")
- self.assertIsInstance(root.getChild("foo.cgi", None), CGIScript)
-
-
- def test_epyProcessor(self):
- """
- The I{--path} option creates a root resource which serves a
- L{PythonScript} instance for any child with the C{".epy"} extension.
- """
- path, root = self._pathOption()
- path.child("foo.epy").setContent("")
- self.assertIsInstance(root.getChild("foo.epy", None), PythonScript)
-
-
- def test_rpyProcessor(self):
- """
- The I{--path} option creates a root resource which serves the
- C{resource} global defined by the Python source in any child with
- the C{".rpy"} extension.
- """
- path, root = self._pathOption()
- path.child("foo.rpy").setContent(
- "from twisted.web.static import Data\n"
- "resource = Data('content', 'major/minor')\n")
- child = root.getChild("foo.rpy", None)
- self.assertIsInstance(child, Data)
- self.assertEqual(child.data, 'content')
- self.assertEqual(child.type, 'major/minor')
-
-
- def test_makePersonalServerFactory(self):
- """
- L{makePersonalServerFactory} returns a PB server factory which has
- as its root object a L{ResourcePublisher}.
- """
- # The fact that this pile of objects can actually be used somehow is
- # verified by twisted.web.test.test_distrib.
- site = Site(Data("foo bar", "text/plain"))
- serverFactory = makePersonalServerFactory(site)
- self.assertIsInstance(serverFactory, PBServerFactory)
- self.assertIsInstance(serverFactory.root, ResourcePublisher)
- self.assertIdentical(serverFactory.root.site, site)
-
-
- def test_personalServer(self):
- """
- The I{--personal} option to L{makeService} causes it to return a
- service which will listen on the server address given by the I{--port}
- option.
- """
- port = self.mktemp()
- options = Options()
- options.parseOptions(['--port', 'unix:' + port, '--personal'])
- service = makeService(options)
- service.startService()
- self.addCleanup(service.stopService)
- self.assertTrue(os.path.exists(port))
- self.assertTrue(stat.S_ISSOCK(os.stat(port).st_mode))
-
- if not IReactorUNIX.providedBy(reactor):
- test_personalServer.skip = (
- "The reactor does not support UNIX domain sockets")
-
-
- def test_defaultPersonalPath(self):
- """
- If the I{--port} option not specified but the I{--personal} option is,
- L{Options} defaults the port to C{UserDirectory.userSocketName} in the
- user's home directory.
- """
- options = Options()
- options.parseOptions(['--personal'])
- path = os.path.expanduser(
- os.path.join('~', UserDirectory.userSocketName))
- self.assertEqual(
- strports.parse(options['port'], None)[:2],
- ('UNIX', (path, None)))
-
- if not IReactorUNIX.providedBy(reactor):
- test_defaultPersonalPath.skip = (
- "The reactor does not support UNIX domain sockets")
-
-
- def test_defaultPort(self):
- """
- If the I{--port} option is not specified, L{Options} defaults the port
- to C{8080}.
- """
- options = Options()
- options.parseOptions([])
- self.assertEqual(
- strports.parse(options['port'], None)[:2],
- ('TCP', (8080, None)))
-
-
- def test_wsgi(self):
- """
- The I{--wsgi} option takes the fully-qualifed Python name of a WSGI
- application object and creates a L{WSGIResource} at the root which
- serves that application.
- """
- options = Options()
- options.parseOptions(['--wsgi', __name__ + '.application'])
- root = options['root']
- self.assertTrue(root, WSGIResource)
- self.assertIdentical(root._reactor, reactor)
- self.assertTrue(isinstance(root._threadpool, ThreadPool))
- self.assertIdentical(root._application, application)
-
- # The threadpool should start and stop with the reactor.
- self.assertFalse(root._threadpool.started)
- reactor.fireSystemEvent('startup')
- self.assertTrue(root._threadpool.started)
- self.assertFalse(root._threadpool.joined)
- reactor.fireSystemEvent('shutdown')
- self.assertTrue(root._threadpool.joined)
-
-
- def test_invalidApplication(self):
- """
- If I{--wsgi} is given an invalid name, L{Options.parseOptions}
- raises L{UsageError}.
- """
- options = Options()
- for name in [__name__ + '.nosuchthing', 'foo.']:
- exc = self.assertRaises(
- UsageError, options.parseOptions, ['--wsgi', name])
- self.assertEqual(str(exc), "No such WSGI application: %r" % (name,))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_template.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_template.py
deleted file mode 100755
index b29303bb..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_template.py
+++ /dev/null
@@ -1,810 +0,0 @@
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Tests for L{twisted.web.template}
-"""
-
-from cStringIO import StringIO
-
-from zope.interface.verify import verifyObject
-
-from twisted.internet.defer import succeed, gatherResults
-from twisted.python.filepath import FilePath
-from twisted.trial.unittest import TestCase
-from twisted.web.template import (
- Element, TagLoader, renderer, tags, XMLFile, XMLString)
-from twisted.web.iweb import ITemplateLoader
-
-from twisted.web.error import (FlattenerError, MissingTemplateLoader,
- MissingRenderMethod)
-
-from twisted.web.template import renderElement
-from twisted.web._element import UnexposedMethodError
-from twisted.web.test._util import FlattenTestCase
-from twisted.web.test.test_web import DummyRequest
-from twisted.web.server import NOT_DONE_YET
-
-class TagFactoryTests(TestCase):
- """
- Tests for L{_TagFactory} through the publicly-exposed L{tags} object.
- """
- def test_lookupTag(self):
- """
- HTML tags can be retrieved through C{tags}.
- """
- tag = tags.a
- self.assertEqual(tag.tagName, "a")
-
-
- def test_lookupHTML5Tag(self):
- """
- Twisted supports the latest and greatest HTML tags from the HTML5
- specification.
- """
- tag = tags.video
- self.assertEqual(tag.tagName, "video")
-
-
- def test_lookupTransparentTag(self):
- """
- To support transparent inclusion in templates, there is a special tag,
- the transparent tag, which has no name of its own but is accessed
- through the "transparent" attribute.
- """
- tag = tags.transparent
- self.assertEqual(tag.tagName, "")
-
-
- def test_lookupInvalidTag(self):
- """
- Invalid tags which are not part of HTML cause AttributeErrors when
- accessed through C{tags}.
- """
- self.assertRaises(AttributeError, getattr, tags, "invalid")
-
-
- def test_lookupXMP(self):
- """
- As a special case, the <xmp> tag is simply not available through
- C{tags} or any other part of the templating machinery.
- """
- self.assertRaises(AttributeError, getattr, tags, "xmp")
-
-
-
-class ElementTests(TestCase):
- """
- Tests for the awesome new L{Element} class.
- """
- def test_missingTemplateLoader(self):
- """
- L{Element.render} raises L{MissingTemplateLoader} if the C{loader}
- attribute is C{None}.
- """
- element = Element()
- err = self.assertRaises(MissingTemplateLoader, element.render, None)
- self.assertIdentical(err.element, element)
-
-
- def test_missingTemplateLoaderRepr(self):
- """
- A L{MissingTemplateLoader} instance can be repr()'d without error.
- """
- class PrettyReprElement(Element):
- def __repr__(self):
- return 'Pretty Repr Element'
- self.assertIn('Pretty Repr Element',
- repr(MissingTemplateLoader(PrettyReprElement())))
-
-
- def test_missingRendererMethod(self):
- """
- When called with the name which is not associated with a render method,
- L{Element.lookupRenderMethod} raises L{MissingRenderMethod}.
- """
- element = Element()
- err = self.assertRaises(
- MissingRenderMethod, element.lookupRenderMethod, "foo")
- self.assertIdentical(err.element, element)
- self.assertEqual(err.renderName, "foo")
-
-
- def test_missingRenderMethodRepr(self):
- """
- A L{MissingRenderMethod} instance can be repr()'d without error.
- """
- class PrettyReprElement(Element):
- def __repr__(self):
- return 'Pretty Repr Element'
- s = repr(MissingRenderMethod(PrettyReprElement(),
- 'expectedMethod'))
- self.assertIn('Pretty Repr Element', s)
- self.assertIn('expectedMethod', s)
-
-
- def test_definedRenderer(self):
- """
- When called with the name of a defined render method,
- L{Element.lookupRenderMethod} returns that render method.
- """
- class ElementWithRenderMethod(Element):
- @renderer
- def foo(self, request, tag):
- return "bar"
- foo = ElementWithRenderMethod().lookupRenderMethod("foo")
- self.assertEqual(foo(None, None), "bar")
-
-
- def test_render(self):
- """
- L{Element.render} loads a document from the C{loader} attribute and
- returns it.
- """
- class TemplateLoader(object):
- def load(self):
- return "result"
-
- class StubElement(Element):
- loader = TemplateLoader()
-
- element = StubElement()
- self.assertEqual(element.render(None), "result")
-
-
- def test_misuseRenderer(self):
- """
- If the L{renderer} decorator is called without any arguments, it will
- raise a comprehensible exception.
- """
- te = self.assertRaises(TypeError, renderer)
- self.assertEqual(str(te),
- "expose() takes at least 1 argument (0 given)")
-
-
- def test_renderGetDirectlyError(self):
- """
- Called directly, without a default, L{renderer.get} raises
- L{UnexposedMethodError} when it cannot find a renderer.
- """
- self.assertRaises(UnexposedMethodError, renderer.get, None,
- "notARenderer")
-
-
-
-class XMLFileReprTests(TestCase):
- """
- Tests for L{twisted.web.template.XMLFile}'s C{__repr__}.
- """
- def test_filePath(self):
- """
- An L{XMLFile} with a L{FilePath} returns a useful repr().
- """
- path = FilePath("/tmp/fake.xml")
- self.assertEqual('<XMLFile of %r>' % (path,), repr(XMLFile(path)))
-
-
- def test_filename(self):
- """
- An L{XMLFile} with a filename returns a useful repr().
- """
- fname = "/tmp/fake.xml"
- self.assertEqual('<XMLFile of %r>' % (fname,), repr(XMLFile(fname)))
-
-
- def test_file(self):
- """
- An L{XMLFile} with a file object returns a useful repr().
- """
- fobj = StringIO("not xml")
- self.assertEqual('<XMLFile of %r>' % (fobj,), repr(XMLFile(fobj)))
-
-
-
-class XMLLoaderTestsMixin(object):
- """
- @ivar templateString: Simple template to use to excercise the loaders.
-
- @ivar deprecatedUse: C{True} if this use of L{XMLFile} is deprecated and
- should emit a C{DeprecationWarning}.
- """
-
- loaderFactory = None
- templateString = '<p>Hello, world.</p>'
- def test_load(self):
- """
- Verify that the loader returns a tag with the correct children.
- """
- loader = self.loaderFactory()
- tag, = loader.load()
-
- warnings = self.flushWarnings(offendingFunctions=[self.loaderFactory])
- if self.deprecatedUse:
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "Passing filenames or file objects to XMLFile is "
- "deprecated since Twisted 12.1. Pass a FilePath instead.")
- else:
- self.assertEqual(len(warnings), 0)
-
- self.assertEqual(tag.tagName, 'p')
- self.assertEqual(tag.children, [u'Hello, world.'])
-
-
- def test_loadTwice(self):
- """
- If {load()} can be called on a loader twice the result should be the
- same.
- """
- loader = self.loaderFactory()
- tags1 = loader.load()
- tags2 = loader.load()
- self.assertEqual(tags1, tags2)
-
-
-
-class XMLStringLoaderTests(TestCase, XMLLoaderTestsMixin):
- """
- Tests for L{twisted.web.template.XMLString}
- """
- deprecatedUse = False
- def loaderFactory(self):
- """
- @return: an L{XMLString} constructed with C{self.templateString}.
- """
- return XMLString(self.templateString)
-
-
-
-class XMLFileWithFilePathTests(TestCase, XMLLoaderTestsMixin):
- """
- Tests for L{twisted.web.template.XMLFile}'s L{FilePath} support.
- """
- deprecatedUse = False
- def loaderFactory(self):
- """
- @return: an L{XMLString} constructed with a L{FilePath} pointing to a
- file that contains C{self.templateString}.
- """
- fp = FilePath(self.mktemp())
- fp.setContent(self.templateString)
- return XMLFile(fp)
-
-
-
-class XMLFileWithFileTests(TestCase, XMLLoaderTestsMixin):
- """
- Tests for L{twisted.web.template.XMLFile}'s deprecated file object support.
- """
- deprecatedUse = True
- def loaderFactory(self):
- """
- @return: an L{XMLString} constructed with a file object that contains
- C{self.templateString}.
- """
- return XMLFile(StringIO(self.templateString))
-
-
-
-class XMLFileWithFilenameTests(TestCase, XMLLoaderTestsMixin):
- """
- Tests for L{twisted.web.template.XMLFile}'s deprecated filename support.
- """
- deprecatedUse = True
- def loaderFactory(self):
- """
- @return: an L{XMLString} constructed with a filename that points to a
- file containing C{self.templateString}.
- """
- fp = FilePath(self.mktemp())
- fp.setContent(self.templateString)
- return XMLFile(fp.path)
-
-
-
-class FlattenIntegrationTests(FlattenTestCase):
- """
- Tests for integration between L{Element} and
- L{twisted.web._flatten.flatten}.
- """
-
- def test_roundTrip(self):
- """
- Given a series of parsable XML strings, verify that
- L{twisted.web._flatten.flatten} will flatten the L{Element} back to the
- input when sent on a round trip.
- """
- fragments = [
- "<p>Hello, world.</p>",
- "<p><!-- hello, world --></p>",
- "<p><![CDATA[Hello, world.]]></p>",
- '<test1 xmlns:test2="urn:test2">'
- '<test2:test3></test2:test3></test1>',
- '<test1 xmlns="urn:test2"><test3></test3></test1>',
- '<p>\xe2\x98\x83</p>',
- ]
- deferreds = [
- self.assertFlattensTo(Element(loader=XMLString(xml)), xml)
- for xml in fragments]
- return gatherResults(deferreds)
-
-
- def test_entityConversion(self):
- """
- When flattening an HTML entity, it should flatten out to the utf-8
- representation if possible.
- """
- element = Element(loader=XMLString('<p>&#9731;</p>'))
- return self.assertFlattensTo(element, '<p>\xe2\x98\x83</p>')
-
-
- def test_missingTemplateLoader(self):
- """
- Rendering a Element without a loader attribute raises the appropriate
- exception.
- """
- return self.assertFlatteningRaises(Element(), MissingTemplateLoader)
-
-
- def test_missingRenderMethod(self):
- """
- Flattening an L{Element} with a C{loader} which has a tag with a render
- directive fails with L{FlattenerError} if there is no available render
- method to satisfy that directive.
- """
- element = Element(loader=XMLString("""
- <p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="unknownMethod" />
- """))
- return self.assertFlatteningRaises(element, MissingRenderMethod)
-
-
- def test_transparentRendering(self):
- """
- A C{transparent} element should be eliminated from the DOM and rendered as
- only its children.
- """
- element = Element(loader=XMLString(
- '<t:transparent '
- 'xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">'
- 'Hello, world.'
- '</t:transparent>'
- ))
- return self.assertFlattensTo(element, "Hello, world.")
-
-
- def test_attrRendering(self):
- """
- An Element with an attr tag renders the vaule of its attr tag as an
- attribute of its containing tag.
- """
- element = Element(loader=XMLString(
- '<a xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">'
- '<t:attr name="href">http://example.com</t:attr>'
- 'Hello, world.'
- '</a>'
- ))
- return self.assertFlattensTo(element,
- '<a href="http://example.com">Hello, world.</a>')
-
-
- def test_errorToplevelAttr(self):
- """
- A template with a toplevel C{attr} tag will not load; it will raise
- L{AssertionError} if you try.
- """
- self.assertRaises(
- AssertionError,
- XMLString,
- """<t:attr
- xmlns:t='http://twistedmatrix.com/ns/twisted.web.template/0.1'
- name='something'
- >hello</t:attr>
- """)
-
-
- def test_errorUnnamedAttr(self):
- """
- A template with an C{attr} tag with no C{name} attribute will not load;
- it will raise L{AssertionError} if you try.
- """
- self.assertRaises(
- AssertionError,
- XMLString,
- """<html><t:attr
- xmlns:t='http://twistedmatrix.com/ns/twisted.web.template/0.1'
- >hello</t:attr></html>""")
-
-
- def test_lenientPrefixBehavior(self):
- """
- If the parser sees a prefix it doesn't recognize on an attribute, it
- will pass it on through to serialization.
- """
- theInput = (
- '<hello:world hello:sample="testing" '
- 'xmlns:hello="http://made-up.example.com/ns/not-real">'
- 'This is a made-up tag.</hello:world>')
- element = Element(loader=XMLString(theInput))
- self.assertFlattensTo(element, theInput)
-
-
- def test_deferredRendering(self):
- """
- An Element with a render method which returns a Deferred will render
- correctly.
- """
- class RenderfulElement(Element):
- @renderer
- def renderMethod(self, request, tag):
- return succeed("Hello, world.")
- element = RenderfulElement(loader=XMLString("""
- <p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="renderMethod">
- Goodbye, world.
- </p>
- """))
- return self.assertFlattensTo(element, "Hello, world.")
-
-
- def test_loaderClassAttribute(self):
- """
- If there is a non-None loader attribute on the class of an Element
- instance but none on the instance itself, the class attribute is used.
- """
- class SubElement(Element):
- loader = XMLString("<p>Hello, world.</p>")
- return self.assertFlattensTo(SubElement(), "<p>Hello, world.</p>")
-
-
- def test_directiveRendering(self):
- """
- An Element with a valid render directive has that directive invoked and
- the result added to the output.
- """
- renders = []
- class RenderfulElement(Element):
- @renderer
- def renderMethod(self, request, tag):
- renders.append((self, request))
- return tag("Hello, world.")
- element = RenderfulElement(loader=XMLString("""
- <p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="renderMethod" />
- """))
- return self.assertFlattensTo(element, "<p>Hello, world.</p>")
-
-
- def test_directiveRenderingOmittingTag(self):
- """
- An Element with a render method which omits the containing tag
- successfully removes that tag from the output.
- """
- class RenderfulElement(Element):
- @renderer
- def renderMethod(self, request, tag):
- return "Hello, world."
- element = RenderfulElement(loader=XMLString("""
- <p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="renderMethod">
- Goodbye, world.
- </p>
- """))
- return self.assertFlattensTo(element, "Hello, world.")
-
-
- def test_elementContainingStaticElement(self):
- """
- An Element which is returned by the render method of another Element is
- rendered properly.
- """
- class RenderfulElement(Element):
- @renderer
- def renderMethod(self, request, tag):
- return tag(Element(
- loader=XMLString("<em>Hello, world.</em>")))
- element = RenderfulElement(loader=XMLString("""
- <p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="renderMethod" />
- """))
- return self.assertFlattensTo(element, "<p><em>Hello, world.</em></p>")
-
-
- def test_elementUsingSlots(self):
- """
- An Element which is returned by the render method of another Element is
- rendered properly.
- """
- class RenderfulElement(Element):
- @renderer
- def renderMethod(self, request, tag):
- return tag.fillSlots(test2='world.')
- element = RenderfulElement(loader=XMLString(
- '<p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"'
- ' t:render="renderMethod">'
- '<t:slot name="test1" default="Hello, " />'
- '<t:slot name="test2" />'
- '</p>'
- ))
- return self.assertFlattensTo(element, "<p>Hello, world.</p>")
-
-
- def test_elementContainingDynamicElement(self):
- """
- Directives in the document factory of a Element returned from a render
- method of another Element are satisfied from the correct object: the
- "inner" Element.
- """
- class OuterElement(Element):
- @renderer
- def outerMethod(self, request, tag):
- return tag(InnerElement(loader=XMLString("""
- <t:ignored
- xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="innerMethod" />
- """)))
- class InnerElement(Element):
- @renderer
- def innerMethod(self, request, tag):
- return "Hello, world."
- element = OuterElement(loader=XMLString("""
- <p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"
- t:render="outerMethod" />
- """))
- return self.assertFlattensTo(element, "<p>Hello, world.</p>")
-
-
- def test_sameLoaderTwice(self):
- """
- Rendering the output of a loader, or even the same element, should
- return different output each time.
- """
- sharedLoader = XMLString(
- '<p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">'
- '<t:transparent t:render="classCounter" /> '
- '<t:transparent t:render="instanceCounter" />'
- '</p>')
-
- class DestructiveElement(Element):
- count = 0
- instanceCount = 0
- loader = sharedLoader
-
- @renderer
- def classCounter(self, request, tag):
- DestructiveElement.count += 1
- return tag(str(DestructiveElement.count))
- @renderer
- def instanceCounter(self, request, tag):
- self.instanceCount += 1
- return tag(str(self.instanceCount))
-
- e1 = DestructiveElement()
- e2 = DestructiveElement()
- self.assertFlattensImmediately(e1, "<p>1 1</p>")
- self.assertFlattensImmediately(e1, "<p>2 2</p>")
- self.assertFlattensImmediately(e2, "<p>3 1</p>")
-
-
-
-class TagLoaderTests(FlattenTestCase):
- """
- Tests for L{TagLoader}.
- """
- def setUp(self):
- self.loader = TagLoader(tags.i('test'))
-
-
- def test_interface(self):
- """
- An instance of L{TagLoader} provides L{ITemplateLoader}.
- """
- self.assertTrue(verifyObject(ITemplateLoader, self.loader))
-
-
- def test_loadsList(self):
- """
- L{TagLoader.load} returns a list, per L{ITemplateLoader}.
- """
- self.assertIsInstance(self.loader.load(), list)
-
-
- def test_flatten(self):
- """
- L{TagLoader} can be used in an L{Element}, and flattens as the tag used
- to construct the L{TagLoader} would flatten.
- """
- e = Element(self.loader)
- self.assertFlattensImmediately(e, '<i>test</i>')
-
-
-
-class TestElement(Element):
- """
- An L{Element} that can be rendered successfully.
- """
- loader = XMLString(
- '<p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">'
- 'Hello, world.'
- '</p>')
-
-
-
-class TestFailureElement(Element):
- """
- An L{Element} that can be used in place of L{FailureElement} to verify
- that L{renderElement} can render failures properly.
- """
- loader = XMLString(
- '<p xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">'
- 'I failed.'
- '</p>')
-
- def __init__(self, failure, loader=None):
- self.failure = failure
-
-
-
-class FailingElement(Element):
- """
- An element that raises an exception when rendered.
- """
- def render(self, request):
- a = 42
- b = 0
- return a // b
-
-
-
-class FakeSite(object):
- """
- A minimal L{Site} object that we can use to test displayTracebacks
- """
- displayTracebacks = False
-
-
-
-class TestRenderElement(TestCase):
- """
- Test L{renderElement}
- """
-
- def setUp(self):
- """
- Set up a common L{DummyRequest} and L{FakeSite}.
- """
- self.request = DummyRequest([""])
- self.request.site = FakeSite()
-
-
- def test_simpleRender(self):
- """
- L{renderElement} returns NOT_DONE_YET and eventually
- writes the rendered L{Element} to the request before finishing the
- request.
- """
- element = TestElement()
-
- d = self.request.notifyFinish()
-
- def check(_):
- self.assertEqual(
- "".join(self.request.written),
- "<!DOCTYPE html>\n"
- "<p>Hello, world.</p>")
- self.assertTrue(self.request.finished)
-
- d.addCallback(check)
-
- self.assertIdentical(NOT_DONE_YET, renderElement(self.request, element))
-
- return d
-
-
- def test_simpleFailure(self):
- """
- L{renderElement} handles failures by writing a minimal
- error message to the request and finishing it.
- """
- element = FailingElement()
-
- d = self.request.notifyFinish()
-
- def check(_):
- flushed = self.flushLoggedErrors(FlattenerError)
- self.assertEqual(len(flushed), 1)
- self.assertEqual(
- "".join(self.request.written),
- ('<!DOCTYPE html>\n'
- '<div style="font-size:800%;'
- 'background-color:#FFF;'
- 'color:#F00'
- '">An error occurred while rendering the response.</div>'))
- self.assertTrue(self.request.finished)
-
- d.addCallback(check)
-
- self.assertIdentical(NOT_DONE_YET, renderElement(self.request, element))
-
- return d
-
-
- def test_simpleFailureWithTraceback(self):
- """
- L{renderElement} will render a traceback when rendering of
- the element fails and our site is configured to display tracebacks.
- """
- self.request.site.displayTracebacks = True
-
- element = FailingElement()
-
- d = self.request.notifyFinish()
-
- def check(_):
- flushed = self.flushLoggedErrors(FlattenerError)
- self.assertEqual(len(flushed), 1)
- self.assertEqual(
- "".join(self.request.written),
- "<!DOCTYPE html>\n<p>I failed.</p>")
- self.assertTrue(self.request.finished)
-
- d.addCallback(check)
-
- renderElement(self.request, element, _failElement=TestFailureElement)
-
- return d
-
-
- def test_nonDefaultDoctype(self):
- """
- L{renderElement} will write the doctype string specified by the
- doctype keyword argument.
- """
-
- element = TestElement()
-
- d = self.request.notifyFinish()
-
- def check(_):
- self.assertEqual(
- "".join(self.request.written),
- ('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
- ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
- '<p>Hello, world.</p>'))
-
- d.addCallback(check)
-
- renderElement(
- self.request,
- element,
- doctype=(
- '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
- ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'))
-
- return d
-
-
- def test_noneDoctype(self):
- """
- L{renderElement} will not write out a doctype if the doctype keyword
- argument is C{None}.
- """
-
- element = TestElement()
-
- d = self.request.notifyFinish()
-
- def check(_):
- self.assertEqual(
- "".join(self.request.written),
- '<p>Hello, world.</p>')
-
- d.addCallback(check)
-
- renderElement(self.request, element, doctype=None)
-
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_util.py
deleted file mode 100755
index 42b54b93..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_util.py
+++ /dev/null
@@ -1,380 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.util}.
-"""
-
-from twisted.python.failure import Failure
-from twisted.trial.unittest import TestCase
-from twisted.web import util
-from twisted.web.error import FlattenerError
-from twisted.web.util import (
- redirectTo, _SourceLineElement,
- _SourceFragmentElement, _FrameElement, _StackElement,
- FailureElement, formatFailure)
-
-from twisted.web.http import FOUND
-from twisted.web.server import Request
-from twisted.web.template import TagLoader, flattenString, tags
-
-from twisted.web.test.test_web import DummyChannel
-
-
-class RedirectToTestCase(TestCase):
- """
- Tests for L{redirectTo}.
- """
-
- def test_headersAndCode(self):
- """
- L{redirectTo} will set the C{Location} and C{Content-Type} headers on
- its request, and set the response code to C{FOUND}, so the browser will
- be redirected.
- """
- request = Request(DummyChannel(), True)
- request.method = 'GET'
- targetURL = "http://target.example.com/4321"
- redirectTo(targetURL, request)
- self.assertEqual(request.code, FOUND)
- self.assertEqual(
- request.responseHeaders.getRawHeaders('location'), [targetURL])
- self.assertEqual(
- request.responseHeaders.getRawHeaders('content-type'),
- ['text/html; charset=utf-8'])
-
-
- def test_redirectToUnicodeURL(self) :
- """
- L{redirectTo} will raise TypeError if unicode object is passed in URL
- """
- request = Request(DummyChannel(), True)
- request.method = 'GET'
- targetURL = u'http://target.example.com/4321'
- self.assertRaises(TypeError, redirectTo, targetURL, request)
-
-
-
-class FailureElementTests(TestCase):
- """
- Tests for L{FailureElement} and related helpers which can render a
- L{Failure} as an HTML string.
- """
- def setUp(self):
- """
- Create a L{Failure} which can be used by the rendering tests.
- """
- def lineNumberProbeAlsoBroken():
- message = "This is a problem"
- raise Exception(message)
- # Figure out the line number from which the exception will be raised.
- self.base = lineNumberProbeAlsoBroken.func_code.co_firstlineno + 1
-
- try:
- lineNumberProbeAlsoBroken()
- except:
- self.failure = Failure(captureVars=True)
- self.frame = self.failure.frames[-1]
-
-
- def test_sourceLineElement(self):
- """
- L{_SourceLineElement} renders a source line and line number.
- """
- element = _SourceLineElement(
- TagLoader(tags.div(
- tags.span(render="lineNumber"),
- tags.span(render="sourceLine"))),
- 50, " print 'hello'")
- d = flattenString(None, element)
- expected = (
- u"<div><span>50</span><span>"
- u" \N{NO-BREAK SPACE} \N{NO-BREAK SPACE}print 'hello'</span></div>")
- d.addCallback(
- self.assertEqual, expected.encode('utf-8'))
- return d
-
-
- def test_sourceFragmentElement(self):
- """
- L{_SourceFragmentElement} renders source lines at and around the line
- number indicated by a frame object.
- """
- element = _SourceFragmentElement(
- TagLoader(tags.div(
- tags.span(render="lineNumber"),
- tags.span(render="sourceLine"),
- render="sourceLines")),
- self.frame)
-
- source = [
- u' \N{NO-BREAK SPACE} \N{NO-BREAK SPACE}message = '
- u'"This is a problem"',
-
- u' \N{NO-BREAK SPACE} \N{NO-BREAK SPACE}raise Exception(message)',
- u'# Figure out the line number from which the exception will be '
- u'raised.',
- ]
- d = flattenString(None, element)
- d.addCallback(
- self.assertEqual,
- ''.join([
- '<div class="snippet%sLine"><span>%d</span><span>%s</span>'
- '</div>' % (
- ["", "Highlight"][lineNumber == 1],
- self.base + lineNumber,
- (u" \N{NO-BREAK SPACE}" * 4 + sourceLine).encode(
- 'utf-8'))
- for (lineNumber, sourceLine)
- in enumerate(source)]))
- return d
-
-
- def test_frameElementFilename(self):
- """
- The I{filename} renderer of L{_FrameElement} renders the filename
- associated with the frame object used to initialize the
- L{_FrameElement}.
- """
- element = _FrameElement(
- TagLoader(tags.span(render="filename")),
- self.frame)
- d = flattenString(None, element)
- d.addCallback(
- # __file__ differs depending on whether an up-to-date .pyc file
- # already existed.
- self.assertEqual, "<span>" + __file__.rstrip('c') + "</span>")
- return d
-
-
- def test_frameElementLineNumber(self):
- """
- The I{lineNumber} renderer of L{_FrameElement} renders the line number
- associated with the frame object used to initialize the
- L{_FrameElement}.
- """
- element = _FrameElement(
- TagLoader(tags.span(render="lineNumber")),
- self.frame)
- d = flattenString(None, element)
- d.addCallback(
- self.assertEqual, "<span>" + str(self.base + 1) + "</span>")
- return d
-
-
- def test_frameElementFunction(self):
- """
- The I{function} renderer of L{_FrameElement} renders the line number
- associated with the frame object used to initialize the
- L{_FrameElement}.
- """
- element = _FrameElement(
- TagLoader(tags.span(render="function")),
- self.frame)
- d = flattenString(None, element)
- d.addCallback(
- self.assertEqual, "<span>lineNumberProbeAlsoBroken</span>")
- return d
-
-
- def test_frameElementSource(self):
- """
- The I{source} renderer of L{_FrameElement} renders the source code near
- the source filename/line number associated with the frame object used to
- initialize the L{_FrameElement}.
- """
- element = _FrameElement(None, self.frame)
- renderer = element.lookupRenderMethod("source")
- tag = tags.div()
- result = renderer(None, tag)
- self.assertIsInstance(result, _SourceFragmentElement)
- self.assertIdentical(result.frame, self.frame)
- self.assertEqual([tag], result.loader.load())
-
-
- def test_stackElement(self):
- """
- The I{frames} renderer of L{_StackElement} renders each stack frame in
- the list of frames used to initialize the L{_StackElement}.
- """
- element = _StackElement(None, self.failure.frames[:2])
- renderer = element.lookupRenderMethod("frames")
- tag = tags.div()
- result = renderer(None, tag)
- self.assertIsInstance(result, list)
- self.assertIsInstance(result[0], _FrameElement)
- self.assertIdentical(result[0].frame, self.failure.frames[0])
- self.assertIsInstance(result[1], _FrameElement)
- self.assertIdentical(result[1].frame, self.failure.frames[1])
- # They must not share the same tag object.
- self.assertNotEqual(result[0].loader.load(), result[1].loader.load())
- self.assertEqual(2, len(result))
-
-
- def test_failureElementTraceback(self):
- """
- The I{traceback} renderer of L{FailureElement} renders the failure's
- stack frames using L{_StackElement}.
- """
- element = FailureElement(self.failure)
- renderer = element.lookupRenderMethod("traceback")
- tag = tags.div()
- result = renderer(None, tag)
- self.assertIsInstance(result, _StackElement)
- self.assertIdentical(result.stackFrames, self.failure.frames)
- self.assertEqual([tag], result.loader.load())
-
-
- def test_failureElementType(self):
- """
- The I{type} renderer of L{FailureElement} renders the failure's
- exception type.
- """
- element = FailureElement(
- self.failure, TagLoader(tags.span(render="type")))
- d = flattenString(None, element)
- d.addCallback(
- self.assertEqual, "<span>exceptions.Exception</span>")
- return d
-
-
- def test_failureElementValue(self):
- """
- The I{value} renderer of L{FailureElement} renders the value's exception
- value.
- """
- element = FailureElement(
- self.failure, TagLoader(tags.span(render="value")))
- d = flattenString(None, element)
- d.addCallback(
- self.assertEqual, '<span>This is a problem</span>')
- return d
-
-
-
-class FormatFailureTests(TestCase):
- """
- Tests for L{twisted.web.util.formatFailure} which returns an HTML string
- representing the L{Failure} instance passed to it.
- """
- def test_flattenerError(self):
- """
- If there is an error flattening the L{Failure} instance,
- L{formatFailure} raises L{FlattenerError}.
- """
- self.assertRaises(FlattenerError, formatFailure, object())
-
-
- def test_returnsBytes(self):
- """
- The return value of L{formatFailure} is a C{str} instance (not a
- C{unicode} instance) with numeric character references for any non-ASCII
- characters meant to appear in the output.
- """
- try:
- raise Exception("Fake bug")
- except:
- result = formatFailure(Failure())
-
- self.assertIsInstance(result, str)
- self.assertTrue(all(ord(ch) < 128 for ch in result))
- # Indentation happens to rely on NO-BREAK SPACE
- self.assertIn("&#160;", result)
-
-
-
-class DeprecatedHTMLHelpers(TestCase):
- """
- The various HTML generation helper APIs in L{twisted.web.util} are
- deprecated.
- """
- def _htmlHelperDeprecationTest(self, functionName):
- """
- Helper method which asserts that using the name indicated by
- C{functionName} from the L{twisted.web.util} module emits a deprecation
- warning.
- """
- getattr(util, functionName)
- warnings = self.flushWarnings([self._htmlHelperDeprecationTest])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "twisted.web.util.%s was deprecated in Twisted 12.1.0: "
- "See twisted.web.template." % (functionName,))
-
-
- def test_htmlrepr(self):
- """
- L{twisted.web.util.htmlrepr} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlrepr")
-
-
- def test_saferepr(self):
- """
- L{twisted.web.util.saferepr} is deprecated.
- """
- self._htmlHelperDeprecationTest("saferepr")
-
-
- def test_htmlUnknown(self):
- """
- L{twisted.web.util.htmlUnknown} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlUnknown")
-
-
- def test_htmlDict(self):
- """
- L{twisted.web.util.htmlDict} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlDict")
-
-
- def test_htmlList(self):
- """
- L{twisted.web.util.htmlList} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlList")
-
-
- def test_htmlInst(self):
- """
- L{twisted.web.util.htmlInst} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlInst")
-
-
- def test_htmlString(self):
- """
- L{twisted.web.util.htmlString} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlString")
-
-
- def test_htmlIndent(self):
- """
- L{twisted.web.util.htmlIndent} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlIndent")
-
-
- def test_htmlFunc(self):
- """
- L{twisted.web.util.htmlFunc} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlFunc")
-
-
- def test_htmlReprTypes(self):
- """
- L{twisted.web.util.htmlReprTypes} is deprecated.
- """
- self._htmlHelperDeprecationTest("htmlReprTypes")
-
-
- def test_stylesheet(self):
- """
- L{twisted.web.util.stylesheet} is deprecated.
- """
- self._htmlHelperDeprecationTest("stylesheet")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_vhost.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_vhost.py
deleted file mode 100755
index 13e6357f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_vhost.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.vhost}.
-"""
-
-from twisted.internet.defer import gatherResults
-from twisted.trial.unittest import TestCase
-from twisted.web.http import NOT_FOUND
-from twisted.web.static import Data
-from twisted.web.vhost import NameVirtualHost
-from twisted.web.test.test_web import DummyRequest
-from twisted.web.test._util import _render
-
-class NameVirtualHostTests(TestCase):
- """
- Tests for L{NameVirtualHost}.
- """
- def test_renderWithoutHost(self):
- """
- L{NameVirtualHost.render} returns the result of rendering the
- instance's C{default} if it is not C{None} and there is no I{Host}
- header in the request.
- """
- virtualHostResource = NameVirtualHost()
- virtualHostResource.default = Data("correct result", "")
- request = DummyRequest([''])
- self.assertEqual(
- virtualHostResource.render(request), "correct result")
-
-
- def test_renderWithoutHostNoDefault(self):
- """
- L{NameVirtualHost.render} returns a response with a status of I{NOT
- FOUND} if the instance's C{default} is C{None} and there is no I{Host}
- header in the request.
- """
- virtualHostResource = NameVirtualHost()
- request = DummyRequest([''])
- d = _render(virtualHostResource, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
-
-
- def test_renderWithHost(self):
- """
- L{NameVirtualHost.render} returns the result of rendering the resource
- which is the value in the instance's C{host} dictionary corresponding
- to the key indicated by the value of the I{Host} header in the request.
- """
- virtualHostResource = NameVirtualHost()
- virtualHostResource.addHost('example.org', Data("winner", ""))
-
- request = DummyRequest([''])
- request.headers['host'] = 'example.org'
- d = _render(virtualHostResource, request)
- def cbRendered(ignored, request):
- self.assertEqual(''.join(request.written), "winner")
- d.addCallback(cbRendered, request)
-
- # The port portion of the Host header should not be considered.
- requestWithPort = DummyRequest([''])
- requestWithPort.headers['host'] = 'example.org:8000'
- dWithPort = _render(virtualHostResource, requestWithPort)
- def cbRendered(ignored, requestWithPort):
- self.assertEqual(''.join(requestWithPort.written), "winner")
- dWithPort.addCallback(cbRendered, requestWithPort)
-
- return gatherResults([d, dWithPort])
-
-
- def test_renderWithUnknownHost(self):
- """
- L{NameVirtualHost.render} returns the result of rendering the
- instance's C{default} if it is not C{None} and there is no host
- matching the value of the I{Host} header in the request.
- """
- virtualHostResource = NameVirtualHost()
- virtualHostResource.default = Data("correct data", "")
- request = DummyRequest([''])
- request.headers['host'] = 'example.com'
- d = _render(virtualHostResource, request)
- def cbRendered(ignored):
- self.assertEqual(''.join(request.written), "correct data")
- d.addCallback(cbRendered)
- return d
-
-
- def test_renderWithUnknownHostNoDefault(self):
- """
- L{NameVirtualHost.render} returns a response with a status of I{NOT
- FOUND} if the instance's C{default} is C{None} and there is no host
- matching the value of the I{Host} header in the request.
- """
- virtualHostResource = NameVirtualHost()
- request = DummyRequest([''])
- request.headers['host'] = 'example.com'
- d = _render(virtualHostResource, request)
- def cbRendered(ignored):
- self.assertEqual(request.responseCode, NOT_FOUND)
- d.addCallback(cbRendered)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_web.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_web.py
deleted file mode 100755
index bd9b09c3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_web.py
+++ /dev/null
@@ -1,1079 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for various parts of L{twisted.web}.
-"""
-
-from cStringIO import StringIO
-
-from zope.interface import implements
-from zope.interface.verify import verifyObject
-
-from twisted.trial import unittest
-from twisted.internet import reactor
-from twisted.internet.address import IPv4Address
-from twisted.internet.defer import Deferred
-from twisted.web import server, resource, util
-from twisted.internet import defer, interfaces, task
-from twisted.web import iweb, http, http_headers, error
-from twisted.python import log
-
-
-class DummyRequest:
- """
- Represents a dummy or fake request.
-
- @ivar _finishedDeferreds: C{None} or a C{list} of L{Deferreds} which will
- be called back with C{None} when C{finish} is called or which will be
- errbacked if C{processingFailed} is called.
-
- @type headers: C{dict}
- @ivar headers: A mapping of header name to header value for all request
- headers.
-
- @type outgoingHeaders: C{dict}
- @ivar outgoingHeaders: A mapping of header name to header value for all
- response headers.
-
- @type responseCode: C{int}
- @ivar responseCode: The response code which was passed to
- C{setResponseCode}.
-
- @type written: C{list} of C{str}
- @ivar written: The bytes which have been written to the request.
- """
- uri = 'http://dummy/'
- method = 'GET'
- client = None
-
- def registerProducer(self, prod,s):
- self.go = 1
- while self.go:
- prod.resumeProducing()
-
- def unregisterProducer(self):
- self.go = 0
-
-
- def __init__(self, postpath, session=None):
- self.sitepath = []
- self.written = []
- self.finished = 0
- self.postpath = postpath
- self.prepath = []
- self.session = None
- self.protoSession = session or server.Session(0, self)
- self.args = {}
- self.outgoingHeaders = {}
- self.responseHeaders = http_headers.Headers()
- self.responseCode = None
- self.headers = {}
- self._finishedDeferreds = []
-
-
- def getHeader(self, name):
- """
- Retrieve the value of a request header.
-
- @type name: C{str}
- @param name: The name of the request header for which to retrieve the
- value. Header names are compared case-insensitively.
-
- @rtype: C{str} or L{NoneType}
- @return: The value of the specified request header.
- """
- return self.headers.get(name.lower(), None)
-
-
- def setHeader(self, name, value):
- """TODO: make this assert on write() if the header is content-length
- """
- self.outgoingHeaders[name.lower()] = value
-
- def getSession(self):
- if self.session:
- return self.session
- assert not self.written, "Session cannot be requested after data has been written."
- self.session = self.protoSession
- return self.session
-
-
- def render(self, resource):
- """
- Render the given resource as a response to this request.
-
- This implementation only handles a few of the most common behaviors of
- resources. It can handle a render method that returns a string or
- C{NOT_DONE_YET}. It doesn't know anything about the semantics of
- request methods (eg HEAD) nor how to set any particular headers.
- Basically, it's largely broken, but sufficient for some tests at least.
- It should B{not} be expanded to do all the same stuff L{Request} does.
- Instead, L{DummyRequest} should be phased out and L{Request} (or some
- other real code factored in a different way) used.
- """
- result = resource.render(self)
- if result is server.NOT_DONE_YET:
- return
- self.write(result)
- self.finish()
-
-
- def write(self, data):
- self.written.append(data)
-
- def notifyFinish(self):
- """
- Return a L{Deferred} which is called back with C{None} when the request
- is finished. This will probably only work if you haven't called
- C{finish} yet.
- """
- finished = Deferred()
- self._finishedDeferreds.append(finished)
- return finished
-
-
- def finish(self):
- """
- Record that the request is finished and callback and L{Deferred}s
- waiting for notification of this.
- """
- self.finished = self.finished + 1
- if self._finishedDeferreds is not None:
- observers = self._finishedDeferreds
- self._finishedDeferreds = None
- for obs in observers:
- obs.callback(None)
-
-
- def processingFailed(self, reason):
- """
- Errback and L{Deferreds} waiting for finish notification.
- """
- if self._finishedDeferreds is not None:
- observers = self._finishedDeferreds
- self._finishedDeferreds = None
- for obs in observers:
- obs.errback(reason)
-
-
- def addArg(self, name, value):
- self.args[name] = [value]
-
-
- def setResponseCode(self, code, message=None):
- """
- Set the HTTP status response code, but takes care that this is called
- before any data is written.
- """
- assert not self.written, "Response code cannot be set after data has been written: %s." % "@@@@".join(self.written)
- self.responseCode = code
- self.responseMessage = message
-
-
- def setLastModified(self, when):
- assert not self.written, "Last-Modified cannot be set after data has been written: %s." % "@@@@".join(self.written)
-
-
- def setETag(self, tag):
- assert not self.written, "ETag cannot be set after data has been written: %s." % "@@@@".join(self.written)
-
-
- def getClientIP(self):
- """
- Return the IPv4 address of the client which made this request, if there
- is one, otherwise C{None}.
- """
- if isinstance(self.client, IPv4Address):
- return self.client.host
- return None
-
-
-class ResourceTestCase(unittest.TestCase):
- def testListEntities(self):
- r = resource.Resource()
- self.assertEqual([], r.listEntities())
-
-
-class SimpleResource(resource.Resource):
- """
- @ivar _contentType: C{None} or a C{str} giving the value of the
- I{Content-Type} header in the response this resource will render. If it
- is C{None}, no I{Content-Type} header will be set in the response.
- """
- def __init__(self, contentType=None):
- resource.Resource.__init__(self)
- self._contentType = contentType
-
-
- def render(self, request):
- if self._contentType is not None:
- request.responseHeaders.setRawHeaders(
- "content-type", [self._contentType])
-
- if http.CACHED in (request.setLastModified(10),
- request.setETag('MatchingTag')):
- return ''
- else:
- return "correct"
-
-
-class DummyChannel:
- class TCP:
- port = 80
- disconnected = False
-
- def __init__(self):
- self.written = StringIO()
- self.producers = []
-
- def getPeer(self):
- return IPv4Address("TCP", '192.168.1.1', 12344)
-
- def write(self, bytes):
- assert isinstance(bytes, str)
- self.written.write(bytes)
-
- def writeSequence(self, iovec):
- map(self.write, iovec)
-
- def getHost(self):
- return IPv4Address("TCP", '10.0.0.1', self.port)
-
- def registerProducer(self, producer, streaming):
- self.producers.append((producer, streaming))
-
- def loseConnection(self):
- self.disconnected = True
-
-
- class SSL(TCP):
- implements(interfaces.ISSLTransport)
-
- site = server.Site(resource.Resource())
-
- def __init__(self):
- self.transport = self.TCP()
-
-
- def requestDone(self, request):
- pass
-
-
-
-class SiteTest(unittest.TestCase):
- def test_simplestSite(self):
- """
- L{Site.getResourceFor} returns the C{""} child of the root resource it
- is constructed with when processing a request for I{/}.
- """
- sres1 = SimpleResource()
- sres2 = SimpleResource()
- sres1.putChild("",sres2)
- site = server.Site(sres1)
- self.assertIdentical(
- site.getResourceFor(DummyRequest([''])),
- sres2, "Got the wrong resource.")
-
-
-
-class SessionTest(unittest.TestCase):
- """
- Tests for L{server.Session}.
- """
- def setUp(self):
- """
- Create a site with one active session using a deterministic, easily
- controlled clock.
- """
- self.clock = task.Clock()
- self.uid = 'unique'
- self.site = server.Site(resource.Resource())
- self.session = server.Session(self.site, self.uid, self.clock)
- self.site.sessions[self.uid] = self.session
-
-
- def test_defaultReactor(self):
- """
- If not value is passed to L{server.Session.__init__}, the global
- reactor is used.
- """
- session = server.Session(server.Site(resource.Resource()), '123')
- self.assertIdentical(session._reactor, reactor)
-
-
- def test_startCheckingExpiration(self):
- """
- L{server.Session.startCheckingExpiration} causes the session to expire
- after L{server.Session.sessionTimeout} seconds without activity.
- """
- self.session.startCheckingExpiration()
-
- # Advance to almost the timeout - nothing should happen.
- self.clock.advance(self.session.sessionTimeout - 1)
- self.assertIn(self.uid, self.site.sessions)
-
- # Advance to the timeout, the session should expire.
- self.clock.advance(1)
- self.assertNotIn(self.uid, self.site.sessions)
-
- # There should be no calls left over, either.
- self.assertFalse(self.clock.calls)
-
-
- def test_expire(self):
- """
- L{server.Session.expire} expires the session.
- """
- self.session.expire()
- # It should be gone from the session dictionary.
- self.assertNotIn(self.uid, self.site.sessions)
- # And there should be no pending delayed calls.
- self.assertFalse(self.clock.calls)
-
-
- def test_expireWhileChecking(self):
- """
- L{server.Session.expire} expires the session even if the timeout call
- isn't due yet.
- """
- self.session.startCheckingExpiration()
- self.test_expire()
-
-
- def test_notifyOnExpire(self):
- """
- A function registered with L{server.Session.notifyOnExpire} is called
- when the session expires.
- """
- callbackRan = [False]
- def expired():
- callbackRan[0] = True
- self.session.notifyOnExpire(expired)
- self.session.expire()
- self.assertTrue(callbackRan[0])
-
-
- def test_touch(self):
- """
- L{server.Session.touch} updates L{server.Session.lastModified} and
- delays session timeout.
- """
- # Make sure it works before startCheckingExpiration
- self.clock.advance(3)
- self.session.touch()
- self.assertEqual(self.session.lastModified, 3)
-
- # And after startCheckingExpiration
- self.session.startCheckingExpiration()
- self.clock.advance(self.session.sessionTimeout - 1)
- self.session.touch()
- self.clock.advance(self.session.sessionTimeout - 1)
- self.assertIn(self.uid, self.site.sessions)
-
- # It should have advanced it by just sessionTimeout, no more.
- self.clock.advance(1)
- self.assertNotIn(self.uid, self.site.sessions)
-
-
- def test_startCheckingExpirationParameterDeprecated(self):
- """
- L{server.Session.startCheckingExpiration} emits a deprecation warning
- if it is invoked with a parameter.
- """
- self.session.startCheckingExpiration(123)
- warnings = self.flushWarnings([
- self.test_startCheckingExpirationParameterDeprecated])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "The lifetime parameter to startCheckingExpiration is deprecated "
- "since Twisted 9.0. See Session.sessionTimeout instead.")
-
-
- def test_checkExpiredDeprecated(self):
- """
- L{server.Session.checkExpired} is deprecated.
- """
- self.session.checkExpired()
- warnings = self.flushWarnings([self.test_checkExpiredDeprecated])
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- "Session.checkExpired is deprecated since Twisted 9.0; sessions "
- "check themselves now, you don't need to.")
- self.assertEqual(len(warnings), 1)
-
-
-# Conditional requests:
-# If-None-Match, If-Modified-Since
-
-# make conditional request:
-# normal response if condition succeeds
-# if condition fails:
-# response code
-# no body
-
-def httpBody(whole):
- return whole.split('\r\n\r\n', 1)[1]
-
-def httpHeader(whole, key):
- key = key.lower()
- headers = whole.split('\r\n\r\n', 1)[0]
- for header in headers.split('\r\n'):
- if header.lower().startswith(key):
- return header.split(':', 1)[1].strip()
- return None
-
-def httpCode(whole):
- l1 = whole.split('\r\n', 1)[0]
- return int(l1.split()[1])
-
-class ConditionalTest(unittest.TestCase):
- """
- web.server's handling of conditional requests for cache validation.
- """
- def setUp(self):
- self.resrc = SimpleResource()
- self.resrc.putChild('', self.resrc)
- self.resrc.putChild('with-content-type', SimpleResource('image/jpeg'))
- self.site = server.Site(self.resrc)
- self.site.logFile = log.logfile
-
- # HELLLLLLLLLLP! This harness is Very Ugly.
- self.channel = self.site.buildProtocol(None)
- self.transport = http.StringTransport()
- self.transport.close = lambda *a, **kw: None
- self.transport.disconnecting = lambda *a, **kw: 0
- self.transport.getPeer = lambda *a, **kw: "peer"
- self.transport.getHost = lambda *a, **kw: "host"
- self.channel.makeConnection(self.transport)
-
-
- def tearDown(self):
- self.channel.connectionLost(None)
-
-
- def _modifiedTest(self, modifiedSince=None, etag=None):
- """
- Given the value C{modifiedSince} for the I{If-Modified-Since} header or
- the value C{etag} for the I{If-Not-Match} header, verify that a response
- with a 200 code, a default Content-Type, and the resource as the body is
- returned.
- """
- if modifiedSince is not None:
- validator = "If-Modified-Since: " + modifiedSince
- else:
- validator = "If-Not-Match: " + etag
- for line in ["GET / HTTP/1.1", validator, ""]:
- self.channel.lineReceived(line)
- result = self.transport.getvalue()
- self.assertEqual(httpCode(result), http.OK)
- self.assertEqual(httpBody(result), "correct")
- self.assertEqual(httpHeader(result, "Content-Type"), "text/html")
-
-
- def test_modified(self):
- """
- If a request is made with an I{If-Modified-Since} header value with
- a timestamp indicating a time before the last modification of the
- requested resource, a 200 response is returned along with a response
- body containing the resource.
- """
- self._modifiedTest(modifiedSince=http.datetimeToString(1))
-
-
- def test_unmodified(self):
- """
- If a request is made with an I{If-Modified-Since} header value with a
- timestamp indicating a time after the last modification of the request
- resource, a 304 response is returned along with an empty response body
- and no Content-Type header if the application does not set one.
- """
- for line in ["GET / HTTP/1.1",
- "If-Modified-Since: " + http.datetimeToString(100), ""]:
- self.channel.lineReceived(line)
- result = self.transport.getvalue()
- self.assertEqual(httpCode(result), http.NOT_MODIFIED)
- self.assertEqual(httpBody(result), "")
- # Since there SHOULD NOT (RFC 2616, section 10.3.5) be any
- # entity-headers, the Content-Type is not set if the application does
- # not explicitly set it.
- self.assertEqual(httpHeader(result, "Content-Type"), None)
-
-
- def test_invalidTimestamp(self):
- """
- If a request is made with an I{If-Modified-Since} header value which
- cannot be parsed, the header is treated as not having been present
- and a normal 200 response is returned with a response body
- containing the resource.
- """
- self._modifiedTest(modifiedSince="like, maybe a week ago, I guess?")
-
-
- def test_invalidTimestampYear(self):
- """
- If a request is made with an I{If-Modified-Since} header value which
- contains a string in the year position which is not an integer, the
- header is treated as not having been present and a normal 200
- response is returned with a response body containing the resource.
- """
- self._modifiedTest(modifiedSince="Thu, 01 Jan blah 00:00:10 GMT")
-
-
- def test_invalidTimestampTooLongAgo(self):
- """
- If a request is made with an I{If-Modified-Since} header value which
- contains a year before the epoch, the header is treated as not
- having been present and a normal 200 response is returned with a
- response body containing the resource.
- """
- self._modifiedTest(modifiedSince="Thu, 01 Jan 1899 00:00:10 GMT")
-
-
- def test_invalidTimestampMonth(self):
- """
- If a request is made with an I{If-Modified-Since} header value which
- contains a string in the month position which is not a recognized
- month abbreviation, the header is treated as not having been present
- and a normal 200 response is returned with a response body
- containing the resource.
- """
- self._modifiedTest(modifiedSince="Thu, 01 Blah 1970 00:00:10 GMT")
-
-
- def test_etagMatchedNot(self):
- """
- If a request is made with an I{If-None-Match} ETag which does not match
- the current ETag of the requested resource, the header is treated as not
- having been present and a normal 200 response is returned with a
- response body containing the resource.
- """
- self._modifiedTest(etag="unmatchedTag")
-
-
- def test_etagMatched(self):
- """
- If a request is made with an I{If-None-Match} ETag which does match the
- current ETag of the requested resource, a 304 response is returned along
- with an empty response body.
- """
- for line in ["GET / HTTP/1.1", "If-None-Match: MatchingTag", ""]:
- self.channel.lineReceived(line)
- result = self.transport.getvalue()
- self.assertEqual(httpHeader(result, "ETag"), "MatchingTag")
- self.assertEqual(httpCode(result), http.NOT_MODIFIED)
- self.assertEqual(httpBody(result), "")
-
-
- def test_unmodifiedWithContentType(self):
- """
- Similar to L{test_etagMatched}, but the response should include a
- I{Content-Type} header if the application explicitly sets one.
-
- This I{Content-Type} header SHOULD NOT be present according to RFC 2616,
- section 10.3.5. It will only be present if the application explicitly
- sets it.
- """
- for line in ["GET /with-content-type HTTP/1.1",
- "If-None-Match: MatchingTag", ""]:
- self.channel.lineReceived(line)
- result = self.transport.getvalue()
- self.assertEqual(httpCode(result), http.NOT_MODIFIED)
- self.assertEqual(httpBody(result), "")
- self.assertEqual(httpHeader(result, "Content-Type"), "image/jpeg")
-
-
-
-class RequestTests(unittest.TestCase):
- """
- Tests for the HTTP request class, L{server.Request}.
- """
-
- def test_interface(self):
- """
- L{server.Request} instances provide L{iweb.IRequest}.
- """
- self.assertTrue(
- verifyObject(iweb.IRequest, server.Request(DummyChannel(), True)))
-
-
- def testChildLink(self):
- request = server.Request(DummyChannel(), 1)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.childLink('baz'), 'bar/baz')
- request = server.Request(DummyChannel(), 1)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar/', 'HTTP/1.0')
- self.assertEqual(request.childLink('baz'), 'baz')
-
- def testPrePathURLSimple(self):
- request = server.Request(DummyChannel(), 1)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- request.setHost('example.com', 80)
- self.assertEqual(request.prePathURL(), 'http://example.com/foo/bar')
-
- def testPrePathURLNonDefault(self):
- d = DummyChannel()
- d.transport.port = 81
- request = server.Request(d, 1)
- request.setHost('example.com', 81)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'http://example.com:81/foo/bar')
-
- def testPrePathURLSSLPort(self):
- d = DummyChannel()
- d.transport.port = 443
- request = server.Request(d, 1)
- request.setHost('example.com', 443)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'http://example.com:443/foo/bar')
-
- def testPrePathURLSSLPortAndSSL(self):
- d = DummyChannel()
- d.transport = DummyChannel.SSL()
- d.transport.port = 443
- request = server.Request(d, 1)
- request.setHost('example.com', 443)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'https://example.com/foo/bar')
-
- def testPrePathURLHTTPPortAndSSL(self):
- d = DummyChannel()
- d.transport = DummyChannel.SSL()
- d.transport.port = 80
- request = server.Request(d, 1)
- request.setHost('example.com', 80)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'https://example.com:80/foo/bar')
-
- def testPrePathURLSSLNonDefault(self):
- d = DummyChannel()
- d.transport = DummyChannel.SSL()
- d.transport.port = 81
- request = server.Request(d, 1)
- request.setHost('example.com', 81)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'https://example.com:81/foo/bar')
-
- def testPrePathURLSetSSLHost(self):
- d = DummyChannel()
- d.transport.port = 81
- request = server.Request(d, 1)
- request.setHost('foo.com', 81, 1)
- request.gotLength(0)
- request.requestReceived('GET', '/foo/bar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'https://foo.com:81/foo/bar')
-
-
- def test_prePathURLQuoting(self):
- """
- L{Request.prePathURL} quotes special characters in the URL segments to
- preserve the original meaning.
- """
- d = DummyChannel()
- request = server.Request(d, 1)
- request.setHost('example.com', 80)
- request.gotLength(0)
- request.requestReceived('GET', '/foo%2Fbar', 'HTTP/1.0')
- self.assertEqual(request.prePathURL(), 'http://example.com/foo%2Fbar')
-
-
-
-class RootResource(resource.Resource):
- isLeaf=0
- def getChildWithDefault(self, name, request):
- request.rememberRootURL()
- return resource.Resource.getChildWithDefault(self, name, request)
- def render(self, request):
- return ''
-
-class RememberURLTest(unittest.TestCase):
- def createServer(self, r):
- chan = DummyChannel()
- chan.site = server.Site(r)
- return chan
-
- def testSimple(self):
- r = resource.Resource()
- r.isLeaf=0
- rr = RootResource()
- r.putChild('foo', rr)
- rr.putChild('', rr)
- rr.putChild('bar', resource.Resource())
- chan = self.createServer(r)
- for url in ['/foo/', '/foo/bar', '/foo/bar/baz', '/foo/bar/']:
- request = server.Request(chan, 1)
- request.setHost('example.com', 81)
- request.gotLength(0)
- request.requestReceived('GET', url, 'HTTP/1.0')
- self.assertEqual(request.getRootURL(), "http://example.com/foo")
-
- def testRoot(self):
- rr = RootResource()
- rr.putChild('', rr)
- rr.putChild('bar', resource.Resource())
- chan = self.createServer(rr)
- for url in ['/', '/bar', '/bar/baz', '/bar/']:
- request = server.Request(chan, 1)
- request.setHost('example.com', 81)
- request.gotLength(0)
- request.requestReceived('GET', url, 'HTTP/1.0')
- self.assertEqual(request.getRootURL(), "http://example.com/")
-
-
-class NewRenderResource(resource.Resource):
- def render_GET(self, request):
- return "hi hi"
-
- def render_HEH(self, request):
- return "ho ho"
-
-
-
-class HeadlessResource(object):
- """
- A resource that implements GET but not HEAD.
- """
- implements(resource.IResource)
-
- allowedMethods = ["GET"]
-
- def render(self, request):
- """
- Leave the request open for future writes.
- """
- self.request = request
- if request.method not in self.allowedMethods:
- raise error.UnsupportedMethod(self.allowedMethods)
- self.request.write("some data")
- return server.NOT_DONE_YET
-
-
-
-
-class NewRenderTestCase(unittest.TestCase):
- """
- Tests for L{server.Request.render}.
- """
- def _getReq(self, resource=None):
- """
- Create a request object with a stub channel and install the
- passed resource at /newrender. If no resource is passed,
- create one.
- """
- d = DummyChannel()
- if resource is None:
- resource = NewRenderResource()
- d.site.resource.putChild('newrender', resource)
- d.transport.port = 81
- request = server.Request(d, 1)
- request.setHost('example.com', 81)
- request.gotLength(0)
- return request
-
- def testGoodMethods(self):
- req = self._getReq()
- req.requestReceived('GET', '/newrender', 'HTTP/1.0')
- self.assertEqual(req.transport.getvalue().splitlines()[-1], 'hi hi')
-
- req = self._getReq()
- req.requestReceived('HEH', '/newrender', 'HTTP/1.0')
- self.assertEqual(req.transport.getvalue().splitlines()[-1], 'ho ho')
-
- def testBadMethods(self):
- req = self._getReq()
- req.requestReceived('CONNECT', '/newrender', 'HTTP/1.0')
- self.assertEqual(req.code, 501)
-
- req = self._getReq()
- req.requestReceived('hlalauguG', '/newrender', 'HTTP/1.0')
- self.assertEqual(req.code, 501)
-
- def testImplicitHead(self):
- req = self._getReq()
- req.requestReceived('HEAD', '/newrender', 'HTTP/1.0')
- self.assertEqual(req.code, 200)
- self.assertEqual(-1, req.transport.getvalue().find('hi hi'))
-
-
- def test_unsupportedHead(self):
- """
- HEAD requests against resource that only claim support for GET
- should not include a body in the response.
- """
- resource = HeadlessResource()
- req = self._getReq(resource)
- req.requestReceived("HEAD", "/newrender", "HTTP/1.0")
- headers, body = req.transport.getvalue().split('\r\n\r\n')
- self.assertEqual(req.code, 200)
- self.assertEqual(body, '')
-
-
-
-class GettableResource(resource.Resource):
- """
- Used by AllowedMethodsTest to simulate an allowed method.
- """
- def render_GET(self):
- pass
-
- def render_fred_render_ethel(self):
- """
- The unusual method name is designed to test the culling method
- in C{twisted.web.resource._computeAllowedMethods}.
- """
- pass
-
-
-
-class AllowedMethodsTest(unittest.TestCase):
- """
- 'C{twisted.web.resource._computeAllowedMethods} is provided by a
- default should the subclass not provide the method.
- """
-
-
- def _getReq(self):
- """
- Generate a dummy request for use by C{_computeAllowedMethod} tests.
- """
- d = DummyChannel()
- d.site.resource.putChild('gettableresource', GettableResource())
- d.transport.port = 81
- request = server.Request(d, 1)
- request.setHost('example.com', 81)
- request.gotLength(0)
- return request
-
-
- def test_computeAllowedMethods(self):
- """
- C{_computeAllowedMethods} will search through the
- 'gettableresource' for all attributes/methods of the form
- 'render_{method}' ('render_GET', for example) and return a list of
- the methods. 'HEAD' will always be included from the
- resource.Resource superclass.
- """
- res = GettableResource()
- allowedMethods = resource._computeAllowedMethods(res)
- self.assertEqual(set(allowedMethods),
- set(['GET', 'HEAD', 'fred_render_ethel']))
-
-
- def test_notAllowed(self):
- """
- When an unsupported method is requested, the default
- L{_computeAllowedMethods} method will be called to determine the
- allowed methods, and the HTTP 405 'Method Not Allowed' status will
- be returned with the allowed methods will be returned in the
- 'Allow' header.
- """
- req = self._getReq()
- req.requestReceived('POST', '/gettableresource', 'HTTP/1.0')
- self.assertEqual(req.code, 405)
- self.assertEqual(
- set(req.responseHeaders.getRawHeaders('allow')[0].split(", ")),
- set(['GET', 'HEAD','fred_render_ethel'])
- )
-
-
- def test_notAllowedQuoting(self):
- """
- When an unsupported method response is generated, an HTML message will
- be displayed. That message should include a quoted form of the URI and,
- since that value come from a browser and shouldn't necessarily be
- trusted.
- """
- req = self._getReq()
- req.requestReceived('POST', '/gettableresource?'
- 'value=<script>bad', 'HTTP/1.0')
- self.assertEqual(req.code, 405)
- renderedPage = req.transport.getvalue()
- self.assertNotIn("<script>bad", renderedPage)
- self.assertIn('&lt;script&gt;bad', renderedPage)
-
-
- def test_notImplementedQuoting(self):
- """
- When an not-implemented method response is generated, an HTML message
- will be displayed. That message should include a quoted form of the
- requested method, since that value come from a browser and shouldn't
- necessarily be trusted.
- """
- req = self._getReq()
- req.requestReceived('<style>bad', '/gettableresource', 'HTTP/1.0')
- self.assertEqual(req.code, 501)
- renderedPage = req.transport.getvalue()
- self.assertNotIn("<style>bad", renderedPage)
- self.assertIn('&lt;style&gt;bad', renderedPage)
-
-
-
-class SDResource(resource.Resource):
- def __init__(self,default):
- self.default = default
-
-
- def getChildWithDefault(self, name, request):
- d = defer.succeed(self.default)
- resource = util.DeferredResource(d)
- return resource.getChildWithDefault(name, request)
-
-
-
-class DeferredResourceTests(unittest.TestCase):
- """
- Tests for L{DeferredResource}.
- """
-
- def testDeferredResource(self):
- r = resource.Resource()
- r.isLeaf = 1
- s = SDResource(r)
- d = DummyRequest(['foo', 'bar', 'baz'])
- resource.getChildForRequest(s, d)
- self.assertEqual(d.postpath, ['bar', 'baz'])
-
-
- def test_render(self):
- """
- L{DeferredResource} uses the request object's C{render} method to
- render the resource which is the result of the L{Deferred} being
- handled.
- """
- rendered = []
- request = DummyRequest([])
- request.render = rendered.append
-
- result = resource.Resource()
- deferredResource = util.DeferredResource(defer.succeed(result))
- deferredResource.render(request)
- self.assertEqual(rendered, [result])
-
-
-
-class DummyRequestForLogTest(DummyRequest):
- uri = '/dummy' # parent class uri has "http://", which doesn't really happen
- code = 123
-
- clientproto = 'HTTP/1.0'
- sentLength = None
- client = IPv4Address('TCP', '1.2.3.4', 12345)
-
-
-
-class TestLogEscaping(unittest.TestCase):
- def setUp(self):
- self.site = http.HTTPFactory()
- self.site.logFile = StringIO()
- self.request = DummyRequestForLogTest(self.site, False)
-
- def testSimple(self):
- self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- 25, 'Oct', 2004, 12, 31, 59)
- self.site.log(self.request)
- self.site.logFile.seek(0)
- self.assertEqual(
- self.site.logFile.read(),
- '1.2.3.4 - - [25/Oct/2004:12:31:59 +0000] "GET /dummy HTTP/1.0" 123 - "-" "-"\n')
-
- def testMethodQuote(self):
- self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- 25, 'Oct', 2004, 12, 31, 59)
- self.request.method = 'G"T'
- self.site.log(self.request)
- self.site.logFile.seek(0)
- self.assertEqual(
- self.site.logFile.read(),
- '1.2.3.4 - - [25/Oct/2004:12:31:59 +0000] "G\\"T /dummy HTTP/1.0" 123 - "-" "-"\n')
-
- def testRequestQuote(self):
- self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- 25, 'Oct', 2004, 12, 31, 59)
- self.request.uri='/dummy"withquote'
- self.site.log(self.request)
- self.site.logFile.seek(0)
- self.assertEqual(
- self.site.logFile.read(),
- '1.2.3.4 - - [25/Oct/2004:12:31:59 +0000] "GET /dummy\\"withquote HTTP/1.0" 123 - "-" "-"\n')
-
- def testProtoQuote(self):
- self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- 25, 'Oct', 2004, 12, 31, 59)
- self.request.clientproto='HT"P/1.0'
- self.site.log(self.request)
- self.site.logFile.seek(0)
- self.assertEqual(
- self.site.logFile.read(),
- '1.2.3.4 - - [25/Oct/2004:12:31:59 +0000] "GET /dummy HT\\"P/1.0" 123 - "-" "-"\n')
-
- def testRefererQuote(self):
- self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- 25, 'Oct', 2004, 12, 31, 59)
- self.request.headers['referer'] = 'http://malicious" ".website.invalid'
- self.site.log(self.request)
- self.site.logFile.seek(0)
- self.assertEqual(
- self.site.logFile.read(),
- '1.2.3.4 - - [25/Oct/2004:12:31:59 +0000] "GET /dummy HTTP/1.0" 123 - "http://malicious\\" \\".website.invalid" "-"\n')
-
- def testUserAgentQuote(self):
- self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
- 25, 'Oct', 2004, 12, 31, 59)
- self.request.headers['user-agent'] = 'Malicious Web" Evil'
- self.site.log(self.request)
- self.site.logFile.seek(0)
- self.assertEqual(
- self.site.logFile.read(),
- '1.2.3.4 - - [25/Oct/2004:12:31:59 +0000] "GET /dummy HTTP/1.0" 123 - "-" "Malicious Web\\" Evil"\n')
-
-
-
-class ServerAttributesTestCase(unittest.TestCase):
- """
- Tests that deprecated twisted.web.server attributes raise the appropriate
- deprecation warnings when used.
- """
-
- def test_deprecatedAttributeDateTimeString(self):
- """
- twisted.web.server.date_time_string should not be used; instead use
- twisted.web.http.datetimeToString directly
- """
- deprecated_func = server.date_time_string
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_deprecatedAttributeDateTimeString])
-
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- ("twisted.web.server.date_time_string was deprecated in Twisted "
- "12.1.0: Please use twisted.web.http.datetimeToString instead"))
-
-
- def test_deprecatedAttributeStringDateTime(self):
- """
- twisted.web.server.string_date_time should not be used; instead use
- twisted.web.http.stringToDatetime directly
- """
- deprecated_func = server.string_date_time
- warnings = self.flushWarnings(
- offendingFunctions=[self.test_deprecatedAttributeStringDateTime])
-
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(
- warnings[0]['message'],
- ("twisted.web.server.string_date_time was deprecated in Twisted "
- "12.1.0: Please use twisted.web.http.stringToDatetime instead"))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_webclient.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_webclient.py
deleted file mode 100755
index 7291c6e5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_webclient.py
+++ /dev/null
@@ -1,3144 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.client}.
-"""
-
-import cookielib
-import os
-from errno import ENOSPC
-import zlib
-from StringIO import StringIO
-
-from urlparse import urlparse, urljoin
-
-from zope.interface.verify import verifyObject
-
-from twisted.trial import unittest
-from twisted.web import server, static, client, error, util, resource, http_headers
-from twisted.web._newclient import RequestNotSent, RequestTransmissionFailed
-from twisted.web._newclient import ResponseNeverReceived, ResponseFailed
-from twisted.internet import reactor, defer, interfaces, task
-from twisted.python.failure import Failure
-from twisted.python.filepath import FilePath
-from twisted.python.log import msg
-from twisted.python.components import proxyForInterface
-from twisted.protocols.policies import WrappingFactory
-from twisted.test.proto_helpers import StringTransport
-from twisted.test.proto_helpers import MemoryReactor
-from twisted.internet.task import Clock
-from twisted.internet.error import ConnectionRefusedError, ConnectionDone
-from twisted.internet.protocol import Protocol, Factory
-from twisted.internet.defer import Deferred, succeed
-from twisted.internet.endpoints import TCP4ClientEndpoint, SSL4ClientEndpoint
-from twisted.web.client import FileBodyProducer, Request, HTTPConnectionPool
-from twisted.web.client import _WebToNormalContextFactory
-from twisted.web.client import WebClientContextFactory, _HTTP11ClientFactory
-from twisted.web.iweb import UNKNOWN_LENGTH, IBodyProducer, IResponse
-from twisted.web._newclient import HTTP11ClientProtocol, Response
-from twisted.web.error import SchemeNotSupported
-
-try:
- from twisted.internet import ssl
-except:
- ssl = None
-
-
-
-class ExtendedRedirect(resource.Resource):
- """
- Redirection resource.
-
- The HTTP status code is set according to the C{code} query parameter.
-
- @type lastMethod: C{str}
- @ivar lastMethod: Last handled HTTP request method
- """
- isLeaf = 1
- lastMethod = None
-
-
- def __init__(self, url):
- resource.Resource.__init__(self)
- self.url = url
-
-
- def render(self, request):
- if self.lastMethod:
- self.lastMethod = request.method
- return "OK Thnx!"
- else:
- self.lastMethod = request.method
- code = int(request.args['code'][0])
- return self.redirectTo(self.url, request, code)
-
-
- def getChild(self, name, request):
- return self
-
-
- def redirectTo(self, url, request, code):
- request.setResponseCode(code)
- request.setHeader("location", url)
- return "OK Bye!"
-
-
-
-class ForeverTakingResource(resource.Resource):
- """
- L{ForeverTakingResource} is a resource which never finishes responding
- to requests.
- """
- def __init__(self, write=False):
- resource.Resource.__init__(self)
- self._write = write
-
- def render(self, request):
- if self._write:
- request.write('some bytes')
- return server.NOT_DONE_YET
-
-
-class CookieMirrorResource(resource.Resource):
- def render(self, request):
- l = []
- for k,v in request.received_cookies.items():
- l.append((k, v))
- l.sort()
- return repr(l)
-
-class RawCookieMirrorResource(resource.Resource):
- def render(self, request):
- return repr(request.getHeader('cookie'))
-
-class ErrorResource(resource.Resource):
-
- def render(self, request):
- request.setResponseCode(401)
- if request.args.get("showlength"):
- request.setHeader("content-length", "0")
- return ""
-
-class NoLengthResource(resource.Resource):
-
- def render(self, request):
- return "nolength"
-
-
-
-class HostHeaderResource(resource.Resource):
- """
- A testing resource which renders itself as the value of the host header
- from the request.
- """
- def render(self, request):
- return request.received_headers['host']
-
-
-
-class PayloadResource(resource.Resource):
- """
- A testing resource which renders itself as the contents of the request body
- as long as the request body is 100 bytes long, otherwise which renders
- itself as C{"ERROR"}.
- """
- def render(self, request):
- data = request.content.read()
- contentLength = request.received_headers['content-length']
- if len(data) != 100 or int(contentLength) != 100:
- return "ERROR"
- return data
-
-
-class DelayResource(resource.Resource):
-
- def __init__(self, seconds):
- self.seconds = seconds
-
- def render(self, request):
- def response():
- request.write('some bytes')
- request.finish()
- reactor.callLater(self.seconds, response)
- return server.NOT_DONE_YET
-
-
-class BrokenDownloadResource(resource.Resource):
-
- def render(self, request):
- # only sends 3 bytes even though it claims to send 5
- request.setHeader("content-length", "5")
- request.write('abc')
- return ''
-
-class CountingRedirect(util.Redirect):
- """
- A L{util.Redirect} resource that keeps track of the number of times the
- resource has been accessed.
- """
- def __init__(self, *a, **kw):
- util.Redirect.__init__(self, *a, **kw)
- self.count = 0
-
- def render(self, request):
- self.count += 1
- return util.Redirect.render(self, request)
-
-
-class CountingResource(resource.Resource):
- """
- A resource that keeps track of the number of times it has been accessed.
- """
- def __init__(self):
- resource.Resource.__init__(self)
- self.count = 0
-
- def render(self, request):
- self.count += 1
- return "Success"
-
-
-class ParseUrlTestCase(unittest.TestCase):
- """
- Test URL parsing facility and defaults values.
- """
-
- def test_parse(self):
- """
- L{client._parse} correctly parses a URL into its various components.
- """
- # The default port for HTTP is 80.
- self.assertEqual(
- client._parse('http://127.0.0.1/'),
- ('http', '127.0.0.1', 80, '/'))
-
- # The default port for HTTPS is 443.
- self.assertEqual(
- client._parse('https://127.0.0.1/'),
- ('https', '127.0.0.1', 443, '/'))
-
- # Specifying a port.
- self.assertEqual(
- client._parse('http://spam:12345/'),
- ('http', 'spam', 12345, '/'))
-
- # Weird (but commonly accepted) structure uses default port.
- self.assertEqual(
- client._parse('http://spam:/'),
- ('http', 'spam', 80, '/'))
-
- # Spaces in the hostname are trimmed, the default path is /.
- self.assertEqual(
- client._parse('http://foo '),
- ('http', 'foo', 80, '/'))
-
-
- def test_externalUnicodeInterference(self):
- """
- L{client._parse} should return C{str} for the scheme, host, and path
- elements of its return tuple, even when passed an URL which has
- previously been passed to L{urlparse} as a C{unicode} string.
- """
- badInput = u'http://example.com/path'
- goodInput = badInput.encode('ascii')
- urlparse(badInput)
- scheme, host, port, path = client._parse(goodInput)
- self.assertIsInstance(scheme, str)
- self.assertIsInstance(host, str)
- self.assertIsInstance(path, str)
-
-
-
-class HTTPPageGetterTests(unittest.TestCase):
- """
- Tests for L{HTTPPagerGetter}, the HTTP client protocol implementation
- used to implement L{getPage}.
- """
- def test_earlyHeaders(self):
- """
- When a connection is made, L{HTTPPagerGetter} sends the headers from
- its factory's C{headers} dict. If I{Host} or I{Content-Length} is
- present in this dict, the values are not sent, since they are sent with
- special values before the C{headers} dict is processed. If
- I{User-Agent} is present in the dict, it overrides the value of the
- C{agent} attribute of the factory. If I{Cookie} is present in the
- dict, its value is added to the values from the factory's C{cookies}
- attribute.
- """
- factory = client.HTTPClientFactory(
- 'http://foo/bar',
- agent="foobar",
- cookies={'baz': 'quux'},
- postdata="some data",
- headers={
- 'Host': 'example.net',
- 'User-Agent': 'fooble',
- 'Cookie': 'blah blah',
- 'Content-Length': '12981',
- 'Useful': 'value'})
- transport = StringTransport()
- protocol = client.HTTPPageGetter()
- protocol.factory = factory
- protocol.makeConnection(transport)
- self.assertEqual(
- transport.value(),
- "GET /bar HTTP/1.0\r\n"
- "Host: example.net\r\n"
- "User-Agent: foobar\r\n"
- "Content-Length: 9\r\n"
- "Useful: value\r\n"
- "connection: close\r\n"
- "Cookie: blah blah; baz=quux\r\n"
- "\r\n"
- "some data")
-
-
-class GetBodyProtocol(Protocol):
-
- def __init__(self, deferred):
- self.deferred = deferred
- self.buf = ''
-
- def dataReceived(self, bytes):
- self.buf += bytes
-
- def connectionLost(self, reason):
- self.deferred.callback(self.buf)
-
-
-def getBody(response):
- d = defer.Deferred()
- response.deliverBody(GetBodyProtocol(d))
- return d
-
-
-class WebClientTestCase(unittest.TestCase):
- def _listen(self, site):
- return reactor.listenTCP(0, site, interface="127.0.0.1")
-
- def setUp(self):
- self.agent = None # for twisted.web.client.Agent test
- self.cleanupServerConnections = 0
- name = self.mktemp()
- os.mkdir(name)
- FilePath(name).child("file").setContent("0123456789")
- r = static.File(name)
- r.putChild("redirect", util.Redirect("/file"))
- self.infiniteRedirectResource = CountingRedirect("/infiniteRedirect")
- r.putChild("infiniteRedirect", self.infiniteRedirectResource)
- r.putChild("wait", ForeverTakingResource())
- r.putChild("write-then-wait", ForeverTakingResource(write=True))
- r.putChild("error", ErrorResource())
- r.putChild("nolength", NoLengthResource())
- r.putChild("host", HostHeaderResource())
- r.putChild("payload", PayloadResource())
- r.putChild("broken", BrokenDownloadResource())
- r.putChild("cookiemirror", CookieMirrorResource())
- r.putChild('delay1', DelayResource(1))
- r.putChild('delay2', DelayResource(2))
-
- self.afterFoundGetCounter = CountingResource()
- r.putChild("afterFoundGetCounter", self.afterFoundGetCounter)
- r.putChild("afterFoundGetRedirect", util.Redirect("/afterFoundGetCounter"))
-
- miscasedHead = static.Data("miscased-head GET response content", "major/minor")
- miscasedHead.render_Head = lambda request: "miscased-head content"
- r.putChild("miscased-head", miscasedHead)
-
- self.extendedRedirect = ExtendedRedirect('/extendedRedirect')
- r.putChild("extendedRedirect", self.extendedRedirect)
- self.site = server.Site(r, timeout=None)
- self.wrapper = WrappingFactory(self.site)
- self.port = self._listen(self.wrapper)
- self.portno = self.port.getHost().port
-
- def tearDown(self):
- if self.agent:
- # clean up connections for twisted.web.client.Agent test.
- self.agent.closeCachedConnections()
- self.agent = None
-
- # If the test indicated it might leave some server-side connections
- # around, clean them up.
- connections = self.wrapper.protocols.keys()
- # If there are fewer server-side connections than requested,
- # that's okay. Some might have noticed that the client closed
- # the connection and cleaned up after themselves.
- for n in range(min(len(connections), self.cleanupServerConnections)):
- proto = connections.pop()
- msg("Closing %r" % (proto,))
- proto.transport.loseConnection()
- if connections:
- msg("Some left-over connections; this test is probably buggy.")
- return self.port.stopListening()
-
- def getURL(self, path):
- host = "http://127.0.0.1:%d/" % self.portno
- return urljoin(host, path)
-
- def testPayload(self):
- s = "0123456789" * 10
- return client.getPage(self.getURL("payload"), postdata=s
- ).addCallback(self.assertEqual, s
- )
-
-
- def test_getPageBrokenDownload(self):
- """
- If the connection is closed before the number of bytes indicated by
- I{Content-Length} have been received, the L{Deferred} returned by
- L{getPage} fails with L{PartialDownloadError}.
- """
- d = client.getPage(self.getURL("broken"))
- d = self.assertFailure(d, client.PartialDownloadError)
- d.addCallback(lambda exc: self.assertEqual(exc.response, "abc"))
- return d
-
-
- def test_downloadPageBrokenDownload(self):
- """
- If the connection is closed before the number of bytes indicated by
- I{Content-Length} have been received, the L{Deferred} returned by
- L{downloadPage} fails with L{PartialDownloadError}.
- """
- # test what happens when download gets disconnected in the middle
- path = FilePath(self.mktemp())
- d = client.downloadPage(self.getURL("broken"), path.path)
- d = self.assertFailure(d, client.PartialDownloadError)
-
- def checkResponse(response):
- """
- The HTTP status code from the server is propagated through the
- C{PartialDownloadError}.
- """
- self.assertEqual(response.status, "200")
- self.assertEqual(response.message, "OK")
- return response
- d.addCallback(checkResponse)
-
- def cbFailed(ignored):
- self.assertEqual(path.getContent(), "abc")
- d.addCallback(cbFailed)
- return d
-
-
- def test_downloadPageLogsFileCloseError(self):
- """
- If there is an exception closing the file being written to after the
- connection is prematurely closed, that exception is logged.
- """
- class BrokenFile:
- def write(self, bytes):
- pass
-
- def close(self):
- raise IOError(ENOSPC, "No file left on device")
-
- d = client.downloadPage(self.getURL("broken"), BrokenFile())
- d = self.assertFailure(d, client.PartialDownloadError)
- def cbFailed(ignored):
- self.assertEqual(len(self.flushLoggedErrors(IOError)), 1)
- d.addCallback(cbFailed)
- return d
-
-
- def testHostHeader(self):
- # if we pass Host header explicitly, it should be used, otherwise
- # it should extract from url
- return defer.gatherResults([
- client.getPage(self.getURL("host")).addCallback(self.assertEqual, "127.0.0.1:%s" % (self.portno,)),
- client.getPage(self.getURL("host"), headers={"Host": "www.example.com"}).addCallback(self.assertEqual, "www.example.com")])
-
-
- def test_getPage(self):
- """
- L{client.getPage} returns a L{Deferred} which is called back with
- the body of the response if the default method B{GET} is used.
- """
- d = client.getPage(self.getURL("file"))
- d.addCallback(self.assertEqual, "0123456789")
- return d
-
-
- def test_getPageHEAD(self):
- """
- L{client.getPage} returns a L{Deferred} which is called back with
- the empty string if the method is I{HEAD} and there is a successful
- response code.
- """
- d = client.getPage(self.getURL("file"), method="HEAD")
- d.addCallback(self.assertEqual, "")
- return d
-
-
- def test_getPageNotQuiteHEAD(self):
- """
- If the request method is a different casing of I{HEAD} (ie, not all
- capitalized) then it is not a I{HEAD} request and the response body
- is returned.
- """
- d = client.getPage(self.getURL("miscased-head"), method='Head')
- d.addCallback(self.assertEqual, "miscased-head content")
- return d
-
-
- def test_timeoutNotTriggering(self):
- """
- When a non-zero timeout is passed to L{getPage} and the page is
- retrieved before the timeout period elapses, the L{Deferred} is
- called back with the contents of the page.
- """
- d = client.getPage(self.getURL("host"), timeout=100)
- d.addCallback(self.assertEqual, "127.0.0.1:%s" % (self.portno,))
- return d
-
-
- def test_timeoutTriggering(self):
- """
- When a non-zero timeout is passed to L{getPage} and that many
- seconds elapse before the server responds to the request. the
- L{Deferred} is errbacked with a L{error.TimeoutError}.
- """
- # This will probably leave some connections around.
- self.cleanupServerConnections = 1
- return self.assertFailure(
- client.getPage(self.getURL("wait"), timeout=0.000001),
- defer.TimeoutError)
-
-
- def testDownloadPage(self):
- downloads = []
- downloadData = [("file", self.mktemp(), "0123456789"),
- ("nolength", self.mktemp(), "nolength")]
-
- for (url, name, data) in downloadData:
- d = client.downloadPage(self.getURL(url), name)
- d.addCallback(self._cbDownloadPageTest, data, name)
- downloads.append(d)
- return defer.gatherResults(downloads)
-
- def _cbDownloadPageTest(self, ignored, data, name):
- bytes = file(name, "rb").read()
- self.assertEqual(bytes, data)
-
- def testDownloadPageError1(self):
- class errorfile:
- def write(self, data):
- raise IOError, "badness happened during write"
- def close(self):
- pass
- ef = errorfile()
- return self.assertFailure(
- client.downloadPage(self.getURL("file"), ef),
- IOError)
-
- def testDownloadPageError2(self):
- class errorfile:
- def write(self, data):
- pass
- def close(self):
- raise IOError, "badness happened during close"
- ef = errorfile()
- return self.assertFailure(
- client.downloadPage(self.getURL("file"), ef),
- IOError)
-
- def testDownloadPageError3(self):
- # make sure failures in open() are caught too. This is tricky.
- # Might only work on posix.
- tmpfile = open("unwritable", "wb")
- tmpfile.close()
- os.chmod("unwritable", 0) # make it unwritable (to us)
- d = self.assertFailure(
- client.downloadPage(self.getURL("file"), "unwritable"),
- IOError)
- d.addBoth(self._cleanupDownloadPageError3)
- return d
-
- def _cleanupDownloadPageError3(self, ignored):
- os.chmod("unwritable", 0700)
- os.unlink("unwritable")
- return ignored
-
- def _downloadTest(self, method):
- dl = []
- for (url, code) in [("nosuchfile", "404"), ("error", "401"),
- ("error?showlength=1", "401")]:
- d = method(url)
- d = self.assertFailure(d, error.Error)
- d.addCallback(lambda exc, code=code: self.assertEqual(exc.args[0], code))
- dl.append(d)
- return defer.DeferredList(dl, fireOnOneErrback=True)
-
- def testServerError(self):
- return self._downloadTest(lambda url: client.getPage(self.getURL(url)))
-
- def testDownloadServerError(self):
- return self._downloadTest(lambda url: client.downloadPage(self.getURL(url), url.split('?')[0]))
-
- def testFactoryInfo(self):
- url = self.getURL('file')
- scheme, host, port, path = client._parse(url)
- factory = client.HTTPClientFactory(url)
- reactor.connectTCP(host, port, factory)
- return factory.deferred.addCallback(self._cbFactoryInfo, factory)
-
- def _cbFactoryInfo(self, ignoredResult, factory):
- self.assertEqual(factory.status, '200')
- self.assert_(factory.version.startswith('HTTP/'))
- self.assertEqual(factory.message, 'OK')
- self.assertEqual(factory.response_headers['content-length'][0], '10')
-
-
- def test_followRedirect(self):
- """
- By default, L{client.getPage} follows redirects and returns the content
- of the target resource.
- """
- d = client.getPage(self.getURL("redirect"))
- d.addCallback(self.assertEqual, "0123456789")
- return d
-
-
- def test_noFollowRedirect(self):
- """
- If C{followRedirect} is passed a false value, L{client.getPage} does not
- follow redirects and returns a L{Deferred} which fails with
- L{error.PageRedirect} when it encounters one.
- """
- d = self.assertFailure(
- client.getPage(self.getURL("redirect"), followRedirect=False),
- error.PageRedirect)
- d.addCallback(self._cbCheckLocation)
- return d
-
-
- def _cbCheckLocation(self, exc):
- self.assertEqual(exc.location, "/file")
-
-
- def test_infiniteRedirection(self):
- """
- When more than C{redirectLimit} HTTP redirects are encountered, the
- page request fails with L{InfiniteRedirection}.
- """
- def checkRedirectCount(*a):
- self.assertEqual(f._redirectCount, 13)
- self.assertEqual(self.infiniteRedirectResource.count, 13)
-
- f = client._makeGetterFactory(
- self.getURL('infiniteRedirect'),
- client.HTTPClientFactory,
- redirectLimit=13)
- d = self.assertFailure(f.deferred, error.InfiniteRedirection)
- d.addCallback(checkRedirectCount)
- return d
-
-
- def test_isolatedFollowRedirect(self):
- """
- C{client.HTTPPagerGetter} instances each obey the C{followRedirect}
- value passed to the L{client.getPage} call which created them.
- """
- d1 = client.getPage(self.getURL('redirect'), followRedirect=True)
- d2 = client.getPage(self.getURL('redirect'), followRedirect=False)
-
- d = self.assertFailure(d2, error.PageRedirect
- ).addCallback(lambda dummy: d1)
- return d
-
-
- def test_afterFoundGet(self):
- """
- Enabling unsafe redirection behaviour overwrites the method of
- redirected C{POST} requests with C{GET}.
- """
- url = self.getURL('extendedRedirect?code=302')
- f = client.HTTPClientFactory(url, followRedirect=True, method="POST")
- self.assertFalse(
- f.afterFoundGet,
- "By default, afterFoundGet must be disabled")
-
- def gotPage(page):
- self.assertEqual(
- self.extendedRedirect.lastMethod,
- "GET",
- "With afterFoundGet, the HTTP method must change to GET")
-
- d = client.getPage(
- url, followRedirect=True, afterFoundGet=True, method="POST")
- d.addCallback(gotPage)
- return d
-
-
- def test_downloadAfterFoundGet(self):
- """
- Passing C{True} for C{afterFoundGet} to L{client.downloadPage} invokes
- the same kind of redirect handling as passing that argument to
- L{client.getPage} invokes.
- """
- url = self.getURL('extendedRedirect?code=302')
-
- def gotPage(page):
- self.assertEqual(
- self.extendedRedirect.lastMethod,
- "GET",
- "With afterFoundGet, the HTTP method must change to GET")
-
- d = client.downloadPage(url, "downloadTemp",
- followRedirect=True, afterFoundGet=True, method="POST")
- d.addCallback(gotPage)
- return d
-
-
- def test_afterFoundGetMakesOneRequest(self):
- """
- When C{afterFoundGet} is C{True}, L{client.getPage} only issues one
- request to the server when following the redirect. This is a regression
- test, see #4760.
- """
- def checkRedirectCount(*a):
- self.assertEqual(self.afterFoundGetCounter.count, 1)
-
- url = self.getURL('afterFoundGetRedirect')
- d = client.getPage(
- url, followRedirect=True, afterFoundGet=True, method="POST")
- d.addCallback(checkRedirectCount)
- return d
-
-
- def testPartial(self):
- name = self.mktemp()
- f = open(name, "wb")
- f.write("abcd")
- f.close()
-
- partialDownload = [(True, "abcd456789"),
- (True, "abcd456789"),
- (False, "0123456789")]
-
- d = defer.succeed(None)
- for (partial, expectedData) in partialDownload:
- d.addCallback(self._cbRunPartial, name, partial)
- d.addCallback(self._cbPartialTest, expectedData, name)
-
- return d
-
- testPartial.skip = "Cannot test until webserver can serve partial data properly"
-
- def _cbRunPartial(self, ignored, name, partial):
- return client.downloadPage(self.getURL("file"), name, supportPartial=partial)
-
- def _cbPartialTest(self, ignored, expectedData, filename):
- bytes = file(filename, "rb").read()
- self.assertEqual(bytes, expectedData)
-
-
- def test_downloadTimeout(self):
- """
- If the timeout indicated by the C{timeout} parameter to
- L{client.HTTPDownloader.__init__} elapses without the complete response
- being received, the L{defer.Deferred} returned by
- L{client.downloadPage} fires with a L{Failure} wrapping a
- L{defer.TimeoutError}.
- """
- self.cleanupServerConnections = 2
- # Verify the behavior if no bytes are ever written.
- first = client.downloadPage(
- self.getURL("wait"),
- self.mktemp(), timeout=0.01)
-
- # Verify the behavior if some bytes are written but then the request
- # never completes.
- second = client.downloadPage(
- self.getURL("write-then-wait"),
- self.mktemp(), timeout=0.01)
-
- return defer.gatherResults([
- self.assertFailure(first, defer.TimeoutError),
- self.assertFailure(second, defer.TimeoutError)])
-
-
- def test_downloadHeaders(self):
- """
- After L{client.HTTPDownloader.deferred} fires, the
- L{client.HTTPDownloader} instance's C{status} and C{response_headers}
- attributes are populated with the values from the response.
- """
- def checkHeaders(factory):
- self.assertEqual(factory.status, '200')
- self.assertEqual(factory.response_headers['content-type'][0], 'text/html')
- self.assertEqual(factory.response_headers['content-length'][0], '10')
- os.unlink(factory.fileName)
- factory = client._makeGetterFactory(
- self.getURL('file'),
- client.HTTPDownloader,
- fileOrName=self.mktemp())
- return factory.deferred.addCallback(lambda _: checkHeaders(factory))
-
-
- def test_downloadCookies(self):
- """
- The C{cookies} dict passed to the L{client.HTTPDownloader}
- initializer is used to populate the I{Cookie} header included in the
- request sent to the server.
- """
- output = self.mktemp()
- factory = client._makeGetterFactory(
- self.getURL('cookiemirror'),
- client.HTTPDownloader,
- fileOrName=output,
- cookies={'foo': 'bar'})
- def cbFinished(ignored):
- self.assertEqual(
- FilePath(output).getContent(),
- "[('foo', 'bar')]")
- factory.deferred.addCallback(cbFinished)
- return factory.deferred
-
-
- def test_downloadRedirectLimit(self):
- """
- When more than C{redirectLimit} HTTP redirects are encountered, the
- page request fails with L{InfiniteRedirection}.
- """
- def checkRedirectCount(*a):
- self.assertEqual(f._redirectCount, 7)
- self.assertEqual(self.infiniteRedirectResource.count, 7)
-
- f = client._makeGetterFactory(
- self.getURL('infiniteRedirect'),
- client.HTTPDownloader,
- fileOrName=self.mktemp(),
- redirectLimit=7)
- d = self.assertFailure(f.deferred, error.InfiniteRedirection)
- d.addCallback(checkRedirectCount)
- return d
-
-
-
-class WebClientSSLTestCase(WebClientTestCase):
- def _listen(self, site):
- from twisted import test
- return reactor.listenSSL(0, site,
- contextFactory=ssl.DefaultOpenSSLContextFactory(
- FilePath(test.__file__).sibling('server.pem').path,
- FilePath(test.__file__).sibling('server.pem').path,
- ),
- interface="127.0.0.1")
-
- def getURL(self, path):
- return "https://127.0.0.1:%d/%s" % (self.portno, path)
-
- def testFactoryInfo(self):
- url = self.getURL('file')
- scheme, host, port, path = client._parse(url)
- factory = client.HTTPClientFactory(url)
- reactor.connectSSL(host, port, factory, ssl.ClientContextFactory())
- # The base class defines _cbFactoryInfo correctly for this
- return factory.deferred.addCallback(self._cbFactoryInfo, factory)
-
-
-
-class WebClientRedirectBetweenSSLandPlainText(unittest.TestCase):
- def getHTTPS(self, path):
- return "https://127.0.0.1:%d/%s" % (self.tlsPortno, path)
-
- def getHTTP(self, path):
- return "http://127.0.0.1:%d/%s" % (self.plainPortno, path)
-
- def setUp(self):
- plainRoot = static.Data('not me', 'text/plain')
- tlsRoot = static.Data('me neither', 'text/plain')
-
- plainSite = server.Site(plainRoot, timeout=None)
- tlsSite = server.Site(tlsRoot, timeout=None)
-
- from twisted import test
- self.tlsPort = reactor.listenSSL(0, tlsSite,
- contextFactory=ssl.DefaultOpenSSLContextFactory(
- FilePath(test.__file__).sibling('server.pem').path,
- FilePath(test.__file__).sibling('server.pem').path,
- ),
- interface="127.0.0.1")
- self.plainPort = reactor.listenTCP(0, plainSite, interface="127.0.0.1")
-
- self.plainPortno = self.plainPort.getHost().port
- self.tlsPortno = self.tlsPort.getHost().port
-
- plainRoot.putChild('one', util.Redirect(self.getHTTPS('two')))
- tlsRoot.putChild('two', util.Redirect(self.getHTTP('three')))
- plainRoot.putChild('three', util.Redirect(self.getHTTPS('four')))
- tlsRoot.putChild('four', static.Data('FOUND IT!', 'text/plain'))
-
- def tearDown(self):
- ds = map(defer.maybeDeferred,
- [self.plainPort.stopListening, self.tlsPort.stopListening])
- return defer.gatherResults(ds)
-
- def testHoppingAround(self):
- return client.getPage(self.getHTTP("one")
- ).addCallback(self.assertEqual, "FOUND IT!"
- )
-
-class FakeTransport:
- disconnecting = False
- def __init__(self):
- self.data = []
- def write(self, stuff):
- self.data.append(stuff)
-
-class CookieTestCase(unittest.TestCase):
- def _listen(self, site):
- return reactor.listenTCP(0, site, interface="127.0.0.1")
-
- def setUp(self):
- root = static.Data('El toro!', 'text/plain')
- root.putChild("cookiemirror", CookieMirrorResource())
- root.putChild("rawcookiemirror", RawCookieMirrorResource())
- site = server.Site(root, timeout=None)
- self.port = self._listen(site)
- self.portno = self.port.getHost().port
-
- def tearDown(self):
- return self.port.stopListening()
-
- def getHTTP(self, path):
- return "http://127.0.0.1:%d/%s" % (self.portno, path)
-
- def testNoCookies(self):
- return client.getPage(self.getHTTP("cookiemirror")
- ).addCallback(self.assertEqual, "[]"
- )
-
- def testSomeCookies(self):
- cookies = {'foo': 'bar', 'baz': 'quux'}
- return client.getPage(self.getHTTP("cookiemirror"), cookies=cookies
- ).addCallback(self.assertEqual, "[('baz', 'quux'), ('foo', 'bar')]"
- )
-
- def testRawNoCookies(self):
- return client.getPage(self.getHTTP("rawcookiemirror")
- ).addCallback(self.assertEqual, "None"
- )
-
- def testRawSomeCookies(self):
- cookies = {'foo': 'bar', 'baz': 'quux'}
- return client.getPage(self.getHTTP("rawcookiemirror"), cookies=cookies
- ).addCallback(self.assertEqual, "'foo=bar; baz=quux'"
- )
-
- def testCookieHeaderParsing(self):
- factory = client.HTTPClientFactory('http://foo.example.com/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.transport = FakeTransport()
- proto.connectionMade()
- for line in [
- '200 Ok',
- 'Squash: yes',
- 'Hands: stolen',
- 'Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT',
- 'Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/',
- 'Set-Cookie: SHIPPING=FEDEX; path=/foo',
- '',
- 'body',
- 'more body',
- ]:
- proto.dataReceived(line + '\r\n')
- self.assertEqual(proto.transport.data,
- ['GET / HTTP/1.0\r\n',
- 'Host: foo.example.com\r\n',
- 'User-Agent: Twisted PageGetter\r\n',
- '\r\n'])
- self.assertEqual(factory.cookies,
- {
- 'CUSTOMER': 'WILE_E_COYOTE',
- 'PART_NUMBER': 'ROCKET_LAUNCHER_0001',
- 'SHIPPING': 'FEDEX',
- })
-
-
-
-class TestHostHeader(unittest.TestCase):
- """
- Test that L{HTTPClientFactory} includes the port in the host header
- if needed.
- """
-
- def _getHost(self, bytes):
- """
- Retrieve the value of the I{Host} header from the serialized
- request given by C{bytes}.
- """
- for line in bytes.splitlines():
- try:
- name, value = line.split(':', 1)
- if name.strip().lower() == 'host':
- return value.strip()
- except ValueError:
- pass
-
-
- def test_HTTPDefaultPort(self):
- """
- No port should be included in the host header when connecting to the
- default HTTP port.
- """
- factory = client.HTTPClientFactory('http://foo.example.com/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.makeConnection(StringTransport())
- self.assertEqual(self._getHost(proto.transport.value()),
- 'foo.example.com')
-
-
- def test_HTTPPort80(self):
- """
- No port should be included in the host header when connecting to the
- default HTTP port even if it is in the URL.
- """
- factory = client.HTTPClientFactory('http://foo.example.com:80/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.makeConnection(StringTransport())
- self.assertEqual(self._getHost(proto.transport.value()),
- 'foo.example.com')
-
-
- def test_HTTPNotPort80(self):
- """
- The port should be included in the host header when connecting to the
- a non default HTTP port.
- """
- factory = client.HTTPClientFactory('http://foo.example.com:8080/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.makeConnection(StringTransport())
- self.assertEqual(self._getHost(proto.transport.value()),
- 'foo.example.com:8080')
-
-
- def test_HTTPSDefaultPort(self):
- """
- No port should be included in the host header when connecting to the
- default HTTPS port.
- """
- factory = client.HTTPClientFactory('https://foo.example.com/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.makeConnection(StringTransport())
- self.assertEqual(self._getHost(proto.transport.value()),
- 'foo.example.com')
-
-
- def test_HTTPSPort443(self):
- """
- No port should be included in the host header when connecting to the
- default HTTPS port even if it is in the URL.
- """
- factory = client.HTTPClientFactory('https://foo.example.com:443/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.makeConnection(StringTransport())
- self.assertEqual(self._getHost(proto.transport.value()),
- 'foo.example.com')
-
-
- def test_HTTPSNotPort443(self):
- """
- The port should be included in the host header when connecting to the
- a non default HTTPS port.
- """
- factory = client.HTTPClientFactory('http://foo.example.com:8080/')
- proto = factory.buildProtocol('127.42.42.42')
- proto.makeConnection(StringTransport())
- self.assertEqual(self._getHost(proto.transport.value()),
- 'foo.example.com:8080')
-
-
-
-class StubHTTPProtocol(Protocol):
- """
- A protocol like L{HTTP11ClientProtocol} but which does not actually know
- HTTP/1.1 and only collects requests in a list.
-
- @ivar requests: A C{list} of two-tuples. Each time a request is made, a
- tuple consisting of the request and the L{Deferred} returned from the
- request method is appended to this list.
- """
- def __init__(self):
- self.requests = []
- self.state = 'QUIESCENT'
-
-
- def request(self, request):
- """
- Capture the given request for later inspection.
-
- @return: A L{Deferred} which this code will never fire.
- """
- result = Deferred()
- self.requests.append((request, result))
- return result
-
-
-
-class FileConsumer(object):
- def __init__(self, outputFile):
- self.outputFile = outputFile
-
-
- def write(self, bytes):
- self.outputFile.write(bytes)
-
-
-
-class FileBodyProducerTests(unittest.TestCase):
- """
- Tests for the L{FileBodyProducer} which reads bytes from a file and writes
- them to an L{IConsumer}.
- """
- _NO_RESULT = object()
-
- def _resultNow(self, deferred):
- """
- Return the current result of C{deferred} if it is not a failure. If it
- has no result, return C{self._NO_RESULT}. If it is a failure, raise an
- exception.
- """
- result = []
- failure = []
- deferred.addCallbacks(result.append, failure.append)
- if len(result) == 1:
- return result[0]
- elif len(failure) == 1:
- raise Exception(
- "Deferred had failure instead of success: %r" % (failure[0],))
- return self._NO_RESULT
-
-
- def _failureNow(self, deferred):
- """
- Return the current result of C{deferred} if it is a failure. If it has
- no result, return C{self._NO_RESULT}. If it is not a failure, raise an
- exception.
- """
- result = []
- failure = []
- deferred.addCallbacks(result.append, failure.append)
- if len(result) == 1:
- raise Exception(
- "Deferred had success instead of failure: %r" % (result[0],))
- elif len(failure) == 1:
- return failure[0]
- return self._NO_RESULT
-
-
- def _termination(self):
- """
- This method can be used as the C{terminationPredicateFactory} for a
- L{Cooperator}. It returns a predicate which immediately returns
- C{False}, indicating that no more work should be done this iteration.
- This has the result of only allowing one iteration of a cooperative
- task to be run per L{Cooperator} iteration.
- """
- return lambda: True
-
-
- def setUp(self):
- """
- Create a L{Cooperator} hooked up to an easily controlled, deterministic
- scheduler to use with L{FileBodyProducer}.
- """
- self._scheduled = []
- self.cooperator = task.Cooperator(
- self._termination, self._scheduled.append)
-
-
- def test_interface(self):
- """
- L{FileBodyProducer} instances provide L{IBodyProducer}.
- """
- self.assertTrue(verifyObject(
- IBodyProducer, FileBodyProducer(StringIO(""))))
-
-
- def test_unknownLength(self):
- """
- If the L{FileBodyProducer} is constructed with a file-like object
- without either a C{seek} or C{tell} method, its C{length} attribute is
- set to C{UNKNOWN_LENGTH}.
- """
- class HasSeek(object):
- def seek(self, offset, whence):
- pass
-
- class HasTell(object):
- def tell(self):
- pass
-
- producer = FileBodyProducer(HasSeek())
- self.assertEqual(UNKNOWN_LENGTH, producer.length)
- producer = FileBodyProducer(HasTell())
- self.assertEqual(UNKNOWN_LENGTH, producer.length)
-
-
- def test_knownLength(self):
- """
- If the L{FileBodyProducer} is constructed with a file-like object with
- both C{seek} and C{tell} methods, its C{length} attribute is set to the
- size of the file as determined by those methods.
- """
- inputBytes = "here are some bytes"
- inputFile = StringIO(inputBytes)
- inputFile.seek(5)
- producer = FileBodyProducer(inputFile)
- self.assertEqual(len(inputBytes) - 5, producer.length)
- self.assertEqual(inputFile.tell(), 5)
-
-
- def test_defaultCooperator(self):
- """
- If no L{Cooperator} instance is passed to L{FileBodyProducer}, the
- global cooperator is used.
- """
- producer = FileBodyProducer(StringIO(""))
- self.assertEqual(task.cooperate, producer._cooperate)
-
-
- def test_startProducing(self):
- """
- L{FileBodyProducer.startProducing} starts writing bytes from the input
- file to the given L{IConsumer} and returns a L{Deferred} which fires
- when they have all been written.
- """
- expectedResult = "hello, world"
- readSize = 3
- output = StringIO()
- consumer = FileConsumer(output)
- producer = FileBodyProducer(
- StringIO(expectedResult), self.cooperator, readSize)
- complete = producer.startProducing(consumer)
- for i in range(len(expectedResult) // readSize + 1):
- self._scheduled.pop(0)()
- self.assertEqual([], self._scheduled)
- self.assertEqual(expectedResult, output.getvalue())
- self.assertEqual(None, self._resultNow(complete))
-
-
- def test_inputClosedAtEOF(self):
- """
- When L{FileBodyProducer} reaches end-of-file on the input file given to
- it, the input file is closed.
- """
- readSize = 4
- inputBytes = "some friendly bytes"
- inputFile = StringIO(inputBytes)
- producer = FileBodyProducer(inputFile, self.cooperator, readSize)
- consumer = FileConsumer(StringIO())
- producer.startProducing(consumer)
- for i in range(len(inputBytes) // readSize + 2):
- self._scheduled.pop(0)()
- self.assertTrue(inputFile.closed)
-
-
- def test_failedReadWhileProducing(self):
- """
- If a read from the input file fails while producing bytes to the
- consumer, the L{Deferred} returned by
- L{FileBodyProducer.startProducing} fires with a L{Failure} wrapping
- that exception.
- """
- class BrokenFile(object):
- def read(self, count):
- raise IOError("Simulated bad thing")
- producer = FileBodyProducer(BrokenFile(), self.cooperator)
- complete = producer.startProducing(FileConsumer(StringIO()))
- self._scheduled.pop(0)()
- self._failureNow(complete).trap(IOError)
-
-
- def test_stopProducing(self):
- """
- L{FileBodyProducer.stopProducing} stops the underlying L{IPullProducer}
- and the cooperative task responsible for calling C{resumeProducing} and
- closes the input file but does not cause the L{Deferred} returned by
- C{startProducing} to fire.
- """
- expectedResult = "hello, world"
- readSize = 3
- output = StringIO()
- consumer = FileConsumer(output)
- inputFile = StringIO(expectedResult)
- producer = FileBodyProducer(
- inputFile, self.cooperator, readSize)
- complete = producer.startProducing(consumer)
- producer.stopProducing()
- self.assertTrue(inputFile.closed)
- self._scheduled.pop(0)()
- self.assertEqual("", output.getvalue())
- self.assertIdentical(self._NO_RESULT, self._resultNow(complete))
-
-
- def test_pauseProducing(self):
- """
- L{FileBodyProducer.pauseProducing} temporarily suspends writing bytes
- from the input file to the given L{IConsumer}.
- """
- expectedResult = "hello, world"
- readSize = 5
- output = StringIO()
- consumer = FileConsumer(output)
- producer = FileBodyProducer(
- StringIO(expectedResult), self.cooperator, readSize)
- complete = producer.startProducing(consumer)
- self._scheduled.pop(0)()
- self.assertEqual(output.getvalue(), expectedResult[:5])
- producer.pauseProducing()
-
- # Sort of depends on an implementation detail of Cooperator: even
- # though the only task is paused, there's still a scheduled call. If
- # this were to go away because Cooperator became smart enough to cancel
- # this call in this case, that would be fine.
- self._scheduled.pop(0)()
-
- # Since the producer is paused, no new data should be here.
- self.assertEqual(output.getvalue(), expectedResult[:5])
- self.assertEqual([], self._scheduled)
- self.assertIdentical(self._NO_RESULT, self._resultNow(complete))
-
-
- def test_resumeProducing(self):
- """
- L{FileBodyProducer.resumeProducing} re-commences writing bytes from the
- input file to the given L{IConsumer} after it was previously paused
- with L{FileBodyProducer.pauseProducing}.
- """
- expectedResult = "hello, world"
- readSize = 5
- output = StringIO()
- consumer = FileConsumer(output)
- producer = FileBodyProducer(
- StringIO(expectedResult), self.cooperator, readSize)
- producer.startProducing(consumer)
- self._scheduled.pop(0)()
- self.assertEqual(expectedResult[:readSize], output.getvalue())
- producer.pauseProducing()
- producer.resumeProducing()
- self._scheduled.pop(0)()
- self.assertEqual(expectedResult[:readSize * 2], output.getvalue())
-
-
-
-class FakeReactorAndConnectMixin:
- """
- A test mixin providing a testable C{Reactor} class and a dummy C{connect}
- method which allows instances to pretend to be endpoints.
- """
-
- class Reactor(MemoryReactor, Clock):
- def __init__(self):
- MemoryReactor.__init__(self)
- Clock.__init__(self)
-
-
- class StubEndpoint(object):
- """
- Endpoint that wraps existing endpoint, substitutes StubHTTPProtocol, and
- resulting protocol instances are attached to the given test case.
- """
-
- def __init__(self, endpoint, testCase):
- self.endpoint = endpoint
- self.testCase = testCase
- self.factory = _HTTP11ClientFactory(lambda p: None)
- self.protocol = StubHTTPProtocol()
- self.factory.buildProtocol = lambda addr: self.protocol
-
- def connect(self, ignoredFactory):
- self.testCase.protocol = self.protocol
- self.endpoint.connect(self.factory)
- return succeed(self.protocol)
-
-
- def buildAgentForWrapperTest(self, reactor):
- """
- Return an Agent suitable for use in tests that wrap the Agent and want
- both a fake reactor and StubHTTPProtocol.
- """
- agent = client.Agent(reactor)
- _oldGetEndpoint = agent._getEndpoint
- agent._getEndpoint = lambda *args: (
- self.StubEndpoint(_oldGetEndpoint(*args), self))
- return agent
-
-
- def connect(self, factory):
- """
- Fake implementation of an endpoint which synchronously
- succeeds with an instance of L{StubHTTPProtocol} for ease of
- testing.
- """
- protocol = StubHTTPProtocol()
- protocol.makeConnection(None)
- self.protocol = protocol
- return succeed(protocol)
-
-
-
-class DummyEndpoint(object):
- """
- An endpoint that uses a fake transport.
- """
-
- def connect(self, factory):
- protocol = factory.buildProtocol(None)
- protocol.makeConnection(StringTransport())
- return succeed(protocol)
-
-
-
-class BadEndpoint(object):
- """
- An endpoint that shouldn't be called.
- """
-
- def connect(self, factory):
- raise RuntimeError("This endpoint should not have been used.")
-
-
-class DummyFactory(Factory):
- """
- Create C{StubHTTPProtocol} instances.
- """
- def __init__(self, quiescentCallback):
- pass
-
- protocol = StubHTTPProtocol
-
-
-
-class HTTPConnectionPoolTests(unittest.TestCase, FakeReactorAndConnectMixin):
- """
- Tests for the L{HTTPConnectionPool} class.
- """
-
- def setUp(self):
- self.fakeReactor = self.Reactor()
- self.pool = HTTPConnectionPool(self.fakeReactor)
- self.pool._factory = DummyFactory
- # The retry code path is tested in HTTPConnectionPoolRetryTests:
- self.pool.retryAutomatically = False
-
-
- def test_getReturnsNewIfCacheEmpty(self):
- """
- If there are no cached connections,
- L{HTTPConnectionPool.getConnection} returns a new connection.
- """
- self.assertEqual(self.pool._connections, {})
-
- def gotConnection(conn):
- self.assertIsInstance(conn, StubHTTPProtocol)
- # The new connection is not stored in the pool:
- self.assertNotIn(conn, self.pool._connections.values())
-
- unknownKey = 12245
- d = self.pool.getConnection(unknownKey, DummyEndpoint())
- return d.addCallback(gotConnection)
-
-
- def test_putStartsTimeout(self):
- """
- If a connection is put back to the pool, a 240-sec timeout is started.
-
- When the timeout hits, the connection is closed and removed from the
- pool.
- """
- # We start out with one cached connection:
- protocol = StubHTTPProtocol()
- protocol.makeConnection(StringTransport())
- self.pool._putConnection(("http", "example.com", 80), protocol)
-
- # Connection is in pool, still not closed:
- self.assertEqual(protocol.transport.disconnecting, False)
- self.assertIn(protocol,
- self.pool._connections[("http", "example.com", 80)])
-
- # Advance 239 seconds, still not closed:
- self.fakeReactor.advance(239)
- self.assertEqual(protocol.transport.disconnecting, False)
- self.assertIn(protocol,
- self.pool._connections[("http", "example.com", 80)])
- self.assertIn(protocol, self.pool._timeouts)
-
- # Advance past 240 seconds, connection will be closed:
- self.fakeReactor.advance(1.1)
- self.assertEqual(protocol.transport.disconnecting, True)
- self.assertNotIn(protocol,
- self.pool._connections[("http", "example.com", 80)])
- self.assertNotIn(protocol, self.pool._timeouts)
-
-
- def test_putExceedsMaxPersistent(self):
- """
- If an idle connection is put back in the cache and the max number of
- persistent connections has been exceeded, one of the connections is
- closed and removed from the cache.
- """
- pool = self.pool
-
- # We start out with two cached connection, the max:
- origCached = [StubHTTPProtocol(), StubHTTPProtocol()]
- for p in origCached:
- p.makeConnection(StringTransport())
- pool._putConnection(("http", "example.com", 80), p)
- self.assertEqual(pool._connections[("http", "example.com", 80)],
- origCached)
- timeouts = pool._timeouts.copy()
-
- # Now we add another one:
- newProtocol = StubHTTPProtocol()
- newProtocol.makeConnection(StringTransport())
- pool._putConnection(("http", "example.com", 80), newProtocol)
-
- # The oldest cached connections will be removed and disconnected:
- newCached = pool._connections[("http", "example.com", 80)]
- self.assertEqual(len(newCached), 2)
- self.assertEqual(newCached, [origCached[1], newProtocol])
- self.assertEqual([p.transport.disconnecting for p in newCached],
- [False, False])
- self.assertEqual(origCached[0].transport.disconnecting, True)
- self.assertTrue(timeouts[origCached[0]].cancelled)
- self.assertNotIn(origCached[0], pool._timeouts)
-
-
- def test_maxPersistentPerHost(self):
- """
- C{maxPersistentPerHost} is enforced per C{(scheme, host, port)}:
- different keys have different max connections.
- """
- def addProtocol(scheme, host, port):
- p = StubHTTPProtocol()
- p.makeConnection(StringTransport())
- self.pool._putConnection((scheme, host, port), p)
- return p
- persistent = []
- persistent.append(addProtocol("http", "example.com", 80))
- persistent.append(addProtocol("http", "example.com", 80))
- addProtocol("https", "example.com", 443)
- addProtocol("http", "www2.example.com", 80)
-
- self.assertEqual(
- self.pool._connections[("http", "example.com", 80)], persistent)
- self.assertEqual(
- len(self.pool._connections[("https", "example.com", 443)]), 1)
- self.assertEqual(
- len(self.pool._connections[("http", "www2.example.com", 80)]), 1)
-
-
- def test_getCachedConnection(self):
- """
- Getting an address which has a cached connection returns the cached
- connection, removes it from the cache and cancels its timeout.
- """
- # We start out with one cached connection:
- protocol = StubHTTPProtocol()
- protocol.makeConnection(StringTransport())
- self.pool._putConnection(("http", "example.com", 80), protocol)
-
- def gotConnection(conn):
- # We got the cached connection:
- self.assertIdentical(protocol, conn)
- self.assertNotIn(
- conn, self.pool._connections[("http", "example.com", 80)])
- # And the timeout was cancelled:
- self.fakeReactor.advance(241)
- self.assertEqual(conn.transport.disconnecting, False)
- self.assertNotIn(conn, self.pool._timeouts)
-
- return self.pool.getConnection(("http", "example.com", 80),
- BadEndpoint(),
- ).addCallback(gotConnection)
-
-
- def test_newConnection(self):
- """
- The pool's C{_newConnection} method constructs a new connection.
- """
- # We start out with one cached connection:
- protocol = StubHTTPProtocol()
- protocol.makeConnection(StringTransport())
- key = 12245
- self.pool._putConnection(key, protocol)
-
- def gotConnection(newConnection):
- # We got a new connection:
- self.assertNotIdentical(protocol, newConnection)
- # And the old connection is still there:
- self.assertIn(protocol, self.pool._connections[key])
- # While the new connection is not:
- self.assertNotIn(newConnection, self.pool._connections.values())
-
- d = self.pool._newConnection(key, DummyEndpoint())
- return d.addCallback(gotConnection)
-
-
- def test_getSkipsDisconnected(self):
- """
- When getting connections out of the cache, disconnected connections
- are removed and not returned.
- """
- pool = self.pool
- key = ("http", "example.com", 80)
-
- # We start out with two cached connection, the max:
- origCached = [StubHTTPProtocol(), StubHTTPProtocol()]
- for p in origCached:
- p.makeConnection(StringTransport())
- pool._putConnection(key, p)
- self.assertEqual(pool._connections[key], origCached)
-
- # We close the first one:
- origCached[0].state = "DISCONNECTED"
-
- # Now, when we retrive connections we should get the *second* one:
- result = []
- self.pool.getConnection(key,
- BadEndpoint()).addCallback(result.append)
- self.assertIdentical(result[0], origCached[1])
-
- # And both the disconnected and removed connections should be out of
- # the cache:
- self.assertEqual(pool._connections[key], [])
- self.assertEqual(pool._timeouts, {})
-
-
- def test_putNotQuiescent(self):
- """
- If a non-quiescent connection is put back in the cache, an error is
- logged.
- """
- protocol = StubHTTPProtocol()
- # By default state is QUIESCENT
- self.assertEqual(protocol.state, "QUIESCENT")
-
- protocol.state = "NOTQUIESCENT"
- self.pool._putConnection(("http", "example.com", 80), protocol)
- error, = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(
- error.value.args[0],
- "BUG: Non-quiescent protocol added to connection pool.")
- self.assertIdentical(None, self.pool._connections.get(
- ("http", "example.com", 80)))
-
-
- def test_getUsesQuiescentCallback(self):
- """
- When L{HTTPConnectionPool.getConnection} connects, it returns a
- C{Deferred} that fires with an instance of L{HTTP11ClientProtocol}
- that has the correct quiescent callback attached. When this callback
- is called the protocol is returned to the cache correctly, using the
- right key.
- """
- class StringEndpoint(object):
- def connect(self, factory):
- p = factory.buildProtocol(None)
- p.makeConnection(StringTransport())
- return succeed(p)
-
- pool = HTTPConnectionPool(self.fakeReactor, True)
- pool.retryAutomatically = False
- result = []
- key = "a key"
- pool.getConnection(
- key, StringEndpoint()).addCallback(
- result.append)
- protocol = result[0]
- self.assertIsInstance(protocol, HTTP11ClientProtocol)
-
- # Now that we have protocol instance, lets try to put it back in the
- # pool:
- protocol._state = "QUIESCENT"
- protocol._quiescentCallback(protocol)
-
- # If we try to retrive a connection to same destination again, we
- # should get the same protocol, because it should've been added back
- # to the pool:
- result2 = []
- pool.getConnection(
- key, StringEndpoint()).addCallback(
- result2.append)
- self.assertIdentical(result2[0], protocol)
-
-
- def test_closeCachedConnections(self):
- """
- L{HTTPConnectionPool.closeCachedConnections} closes all cached
- connections and removes them from the cache. It returns a Deferred
- that fires when they have all lost their connections.
- """
- persistent = []
- def addProtocol(scheme, host, port):
- p = HTTP11ClientProtocol()
- p.makeConnection(StringTransport())
- self.pool._putConnection((scheme, host, port), p)
- persistent.append(p)
- addProtocol("http", "example.com", 80)
- addProtocol("http", "www2.example.com", 80)
- doneDeferred = self.pool.closeCachedConnections()
-
- # Connections have begun disconnecting:
- for p in persistent:
- self.assertEqual(p.transport.disconnecting, True)
- self.assertEqual(self.pool._connections, {})
- # All timeouts were cancelled and removed:
- for dc in self.fakeReactor.getDelayedCalls():
- self.assertEqual(dc.cancelled, True)
- self.assertEqual(self.pool._timeouts, {})
-
- # Returned Deferred fires when all connections have been closed:
- result = []
- doneDeferred.addCallback(result.append)
- self.assertEqual(result, [])
- persistent[0].connectionLost(Failure(ConnectionDone()))
- self.assertEqual(result, [])
- persistent[1].connectionLost(Failure(ConnectionDone()))
- self.assertEqual(result, [None])
-
-
-
-class AgentTests(unittest.TestCase, FakeReactorAndConnectMixin):
- """
- Tests for the new HTTP client API provided by L{Agent}.
- """
- def setUp(self):
- """
- Create an L{Agent} wrapped around a fake reactor.
- """
- self.reactor = self.Reactor()
- self.agent = client.Agent(self.reactor)
-
-
- def completeConnection(self):
- """
- Do whitebox stuff to finish any outstanding connection attempts the
- agent may have initiated.
-
- This spins the fake reactor clock just enough to get L{ClientCreator},
- which agent is implemented in terms of, to fire its Deferreds.
- """
- self.reactor.advance(0)
-
-
- def test_defaultPool(self):
- """
- If no pool is passed in, the L{Agent} creates a non-persistent pool.
- """
- agent = client.Agent(self.reactor)
- self.assertIsInstance(agent._pool, HTTPConnectionPool)
- self.assertEqual(agent._pool.persistent, False)
- self.assertIdentical(agent._reactor, agent._pool._reactor)
-
-
- def test_persistent(self):
- """
- If C{persistent} is set to C{True} on the L{HTTPConnectionPool} (the
- default), C{Request}s are created with their C{persistent} flag set to
- C{True}.
- """
- pool = HTTPConnectionPool(self.reactor)
- agent = client.Agent(self.reactor, pool=pool)
- agent._getEndpoint = lambda *args: self
- agent.request("GET", "http://127.0.0.1")
- self.assertEqual(self.protocol.requests[0][0].persistent, True)
-
-
- def test_nonPersistent(self):
- """
- If C{persistent} is set to C{False} when creating the
- L{HTTPConnectionPool}, C{Request}s are created with their
- C{persistent} flag set to C{False}.
-
- Elsewhere in the tests for the underlying HTTP code we ensure that
- this will result in the disconnection of the HTTP protocol once the
- request is done, so that the connection will not be returned to the
- pool.
- """
- pool = HTTPConnectionPool(self.reactor, persistent=False)
- agent = client.Agent(self.reactor, pool=pool)
- agent._getEndpoint = lambda *args: self
- agent.request("GET", "http://127.0.0.1")
- self.assertEqual(self.protocol.requests[0][0].persistent, False)
-
-
- def test_connectUsesConnectionPool(self):
- """
- When a connection is made by the Agent, it uses its pool's
- C{getConnection} method to do so, with the endpoint returned by
- C{self._getEndpoint}. The key used is C{(scheme, host, port)}.
- """
- endpoint = DummyEndpoint()
- class MyAgent(client.Agent):
- def _getEndpoint(this, scheme, host, port):
- self.assertEqual((scheme, host, port),
- ("http", "foo", 80))
- return endpoint
-
- class DummyPool(object):
- connected = False
- persistent = False
- def getConnection(this, key, ep):
- this.connected = True
- self.assertEqual(ep, endpoint)
- # This is the key the default Agent uses, others will have
- # different keys:
- self.assertEqual(key, ("http", "foo", 80))
- return defer.succeed(StubHTTPProtocol())
-
- pool = DummyPool()
- agent = MyAgent(self.reactor, pool=pool)
- self.assertIdentical(pool, agent._pool)
-
- headers = http_headers.Headers()
- headers.addRawHeader("host", "foo")
- bodyProducer = object()
- agent.request('GET', 'http://foo/',
- bodyProducer=bodyProducer, headers=headers)
- self.assertEqual(agent._pool.connected, True)
-
-
- def test_unsupportedScheme(self):
- """
- L{Agent.request} returns a L{Deferred} which fails with
- L{SchemeNotSupported} if the scheme of the URI passed to it is not
- C{'http'}.
- """
- return self.assertFailure(
- self.agent.request('GET', 'mailto:alice@example.com'),
- SchemeNotSupported)
-
-
- def test_connectionFailed(self):
- """
- The L{Deferred} returned by L{Agent.request} fires with a L{Failure} if
- the TCP connection attempt fails.
- """
- result = self.agent.request('GET', 'http://foo/')
- # Cause the connection to be refused
- host, port, factory = self.reactor.tcpClients.pop()[:3]
- factory.clientConnectionFailed(None, Failure(ConnectionRefusedError()))
- self.completeConnection()
- return self.assertFailure(result, ConnectionRefusedError)
-
-
- def test_connectHTTP(self):
- """
- L{Agent._getEndpoint} return a C{TCP4ClientEndpoint} when passed a
- scheme of C{'http'}.
- """
- expectedHost = 'example.com'
- expectedPort = 1234
- endpoint = self.agent._getEndpoint('http', expectedHost, expectedPort)
- self.assertEqual(endpoint._host, expectedHost)
- self.assertEqual(endpoint._port, expectedPort)
- self.assertIsInstance(endpoint, TCP4ClientEndpoint)
-
-
- def test_connectHTTPS(self):
- """
- L{Agent._getEndpoint} return a C{SSL4ClientEndpoint} when passed a
- scheme of C{'https'}.
- """
- expectedHost = 'example.com'
- expectedPort = 4321
- endpoint = self.agent._getEndpoint('https', expectedHost, expectedPort)
- self.assertIsInstance(endpoint, SSL4ClientEndpoint)
- self.assertEqual(endpoint._host, expectedHost)
- self.assertEqual(endpoint._port, expectedPort)
- self.assertIsInstance(endpoint._sslContextFactory,
- _WebToNormalContextFactory)
- # Default context factory was used:
- self.assertIsInstance(endpoint._sslContextFactory._webContext,
- WebClientContextFactory)
- if ssl is None:
- test_connectHTTPS.skip = "OpenSSL not present"
-
-
- def test_connectHTTPSCustomContextFactory(self):
- """
- If a context factory is passed to L{Agent.__init__} it will be used to
- determine the SSL parameters for HTTPS requests. When an HTTPS request
- is made, the hostname and port number of the request URL will be passed
- to the context factory's C{getContext} method. The resulting context
- object will be used to establish the SSL connection.
- """
- expectedHost = 'example.org'
- expectedPort = 20443
- expectedContext = object()
-
- contextArgs = []
- class StubWebContextFactory(object):
- def getContext(self, hostname, port):
- contextArgs.append((hostname, port))
- return expectedContext
-
- agent = client.Agent(self.reactor, StubWebContextFactory())
- endpoint = agent._getEndpoint('https', expectedHost, expectedPort)
- contextFactory = endpoint._sslContextFactory
- context = contextFactory.getContext()
- self.assertEqual(context, expectedContext)
- self.assertEqual(contextArgs, [(expectedHost, expectedPort)])
-
-
- def test_hostProvided(self):
- """
- If C{None} is passed to L{Agent.request} for the C{headers} parameter,
- a L{Headers} instance is created for the request and a I{Host} header
- added to it.
- """
- self.agent._getEndpoint = lambda *args: self
- self.agent.request(
- 'GET', 'http://example.com/foo?bar')
-
- req, res = self.protocol.requests.pop()
- self.assertEqual(req.headers.getRawHeaders('host'), ['example.com'])
-
-
- def test_hostOverride(self):
- """
- If the headers passed to L{Agent.request} includes a value for the
- I{Host} header, that value takes precedence over the one which would
- otherwise be automatically provided.
- """
- headers = http_headers.Headers({'foo': ['bar'], 'host': ['quux']})
- self.agent._getEndpoint = lambda *args: self
- self.agent.request(
- 'GET', 'http://example.com/foo?bar', headers)
-
- req, res = self.protocol.requests.pop()
- self.assertEqual(req.headers.getRawHeaders('host'), ['quux'])
-
-
- def test_headersUnmodified(self):
- """
- If a I{Host} header must be added to the request, the L{Headers}
- instance passed to L{Agent.request} is not modified.
- """
- headers = http_headers.Headers()
- self.agent._getEndpoint = lambda *args: self
- self.agent.request(
- 'GET', 'http://example.com/foo', headers)
-
- protocol = self.protocol
-
- # The request should have been issued.
- self.assertEqual(len(protocol.requests), 1)
- # And the headers object passed in should not have changed.
- self.assertEqual(headers, http_headers.Headers())
-
-
- def test_hostValueStandardHTTP(self):
- """
- When passed a scheme of C{'http'} and a port of C{80},
- L{Agent._computeHostValue} returns a string giving just
- the host name passed to it.
- """
- self.assertEqual(
- self.agent._computeHostValue('http', 'example.com', 80),
- 'example.com')
-
-
- def test_hostValueNonStandardHTTP(self):
- """
- When passed a scheme of C{'http'} and a port other than C{80},
- L{Agent._computeHostValue} returns a string giving the
- host passed to it joined together with the port number by C{":"}.
- """
- self.assertEqual(
- self.agent._computeHostValue('http', 'example.com', 54321),
- 'example.com:54321')
-
-
- def test_hostValueStandardHTTPS(self):
- """
- When passed a scheme of C{'https'} and a port of C{443},
- L{Agent._computeHostValue} returns a string giving just
- the host name passed to it.
- """
- self.assertEqual(
- self.agent._computeHostValue('https', 'example.com', 443),
- 'example.com')
-
-
- def test_hostValueNonStandardHTTPS(self):
- """
- When passed a scheme of C{'https'} and a port other than C{443},
- L{Agent._computeHostValue} returns a string giving the
- host passed to it joined together with the port number by C{":"}.
- """
- self.assertEqual(
- self.agent._computeHostValue('https', 'example.com', 54321),
- 'example.com:54321')
-
-
- def test_request(self):
- """
- L{Agent.request} establishes a new connection to the host indicated by
- the host part of the URI passed to it and issues a request using the
- method, the path portion of the URI, the headers, and the body producer
- passed to it. It returns a L{Deferred} which fires with an
- L{IResponse} from the server.
- """
- self.agent._getEndpoint = lambda *args: self
-
- headers = http_headers.Headers({'foo': ['bar']})
- # Just going to check the body for identity, so it doesn't need to be
- # real.
- body = object()
- self.agent.request(
- 'GET', 'http://example.com:1234/foo?bar', headers, body)
-
- protocol = self.protocol
-
- # The request should be issued.
- self.assertEqual(len(protocol.requests), 1)
- req, res = protocol.requests.pop()
- self.assertIsInstance(req, Request)
- self.assertEqual(req.method, 'GET')
- self.assertEqual(req.uri, '/foo?bar')
- self.assertEqual(
- req.headers,
- http_headers.Headers({'foo': ['bar'],
- 'host': ['example.com:1234']}))
- self.assertIdentical(req.bodyProducer, body)
-
-
- def test_connectTimeout(self):
- """
- L{Agent} takes a C{connectTimeout} argument which is forwarded to the
- following C{connectTCP} agent.
- """
- agent = client.Agent(self.reactor, connectTimeout=5)
- agent.request('GET', 'http://foo/')
- timeout = self.reactor.tcpClients.pop()[3]
- self.assertEqual(5, timeout)
-
-
- def test_connectSSLTimeout(self):
- """
- L{Agent} takes a C{connectTimeout} argument which is forwarded to the
- following C{connectSSL} call.
- """
- agent = client.Agent(self.reactor, connectTimeout=5)
- agent.request('GET', 'https://foo/')
- timeout = self.reactor.sslClients.pop()[4]
- self.assertEqual(5, timeout)
-
-
- def test_bindAddress(self):
- """
- L{Agent} takes a C{bindAddress} argument which is forwarded to the
- following C{connectTCP} call.
- """
- agent = client.Agent(self.reactor, bindAddress='192.168.0.1')
- agent.request('GET', 'http://foo/')
- address = self.reactor.tcpClients.pop()[4]
- self.assertEqual('192.168.0.1', address)
-
-
- def test_bindAddressSSL(self):
- """
- L{Agent} takes a C{bindAddress} argument which is forwarded to the
- following C{connectSSL} call.
- """
- agent = client.Agent(self.reactor, bindAddress='192.168.0.1')
- agent.request('GET', 'https://foo/')
- address = self.reactor.sslClients.pop()[5]
- self.assertEqual('192.168.0.1', address)
-
-
-
-class HTTPConnectionPoolRetryTests(unittest.TestCase, FakeReactorAndConnectMixin):
- """
- L{client.HTTPConnectionPool}, by using
- L{client._RetryingHTTP11ClientProtocol}, supports retrying requests done
- against previously cached connections.
- """
-
- def test_onlyRetryIdempotentMethods(self):
- """
- Only GET, HEAD, OPTIONS, TRACE, DELETE methods should cause a retry.
- """
- pool = client.HTTPConnectionPool(None)
- connection = client._RetryingHTTP11ClientProtocol(None, pool)
- self.assertTrue(connection._shouldRetry("GET", RequestNotSent(), None))
- self.assertTrue(connection._shouldRetry("HEAD", RequestNotSent(), None))
- self.assertTrue(connection._shouldRetry(
- "OPTIONS", RequestNotSent(), None))
- self.assertTrue(connection._shouldRetry(
- "TRACE", RequestNotSent(), None))
- self.assertTrue(connection._shouldRetry(
- "DELETE", RequestNotSent(), None))
- self.assertFalse(connection._shouldRetry(
- "POST", RequestNotSent(), None))
- self.assertFalse(connection._shouldRetry(
- "MYMETHOD", RequestNotSent(), None))
- # This will be covered by a different ticket, since we need support
- #for resettable body producers:
- # self.assertTrue(connection._doRetry("PUT", RequestNotSent(), None))
-
-
- def test_onlyRetryIfNoResponseReceived(self):
- """
- Only L{RequestNotSent}, L{RequestTransmissionFailed} and
- L{ResponseNeverReceived} exceptions should be a cause for retrying.
- """
- pool = client.HTTPConnectionPool(None)
- connection = client._RetryingHTTP11ClientProtocol(None, pool)
- self.assertTrue(connection._shouldRetry("GET", RequestNotSent(), None))
- self.assertTrue(connection._shouldRetry(
- "GET", RequestTransmissionFailed([]), None))
- self.assertTrue(connection._shouldRetry(
- "GET", ResponseNeverReceived([]),None))
- self.assertFalse(connection._shouldRetry(
- "GET", ResponseFailed([]), None))
- self.assertFalse(connection._shouldRetry(
- "GET", ConnectionRefusedError(), None))
-
-
- def test_wrappedOnPersistentReturned(self):
- """
- If L{client.HTTPConnectionPool.getConnection} returns a previously
- cached connection, it will get wrapped in a
- L{client._RetryingHTTP11ClientProtocol}.
- """
- pool = client.HTTPConnectionPool(Clock())
-
- # Add a connection to the cache:
- protocol = StubHTTPProtocol()
- protocol.makeConnection(StringTransport())
- pool._putConnection(123, protocol)
-
- # Retrieve it, it should come back wrapped in a
- # _RetryingHTTP11ClientProtocol:
- d = pool.getConnection(123, DummyEndpoint())
-
- def gotConnection(connection):
- self.assertIsInstance(connection,
- client._RetryingHTTP11ClientProtocol)
- self.assertIdentical(connection._clientProtocol, protocol)
- return d.addCallback(gotConnection)
-
-
- def test_notWrappedOnNewReturned(self):
- """
- If L{client.HTTPConnectionPool.getConnection} returns a new
- connection, it will be returned as is.
- """
- pool = client.HTTPConnectionPool(None)
- d = pool.getConnection(123, DummyEndpoint())
-
- def gotConnection(connection):
- # Don't want to use isinstance since potentially the wrapper might
- # subclass it at some point:
- self.assertIdentical(connection.__class__, HTTP11ClientProtocol)
- return d.addCallback(gotConnection)
-
-
- def retryAttempt(self, willWeRetry):
- """
- Fail a first request, possibly retrying depending on argument.
- """
- protocols = []
- def newProtocol():
- protocol = StubHTTPProtocol()
- protocols.append(protocol)
- return defer.succeed(protocol)
-
- bodyProducer = object()
- request = client.Request("FOO", "/", client.Headers(), bodyProducer,
- persistent=True)
- newProtocol()
- protocol = protocols[0]
- retrier = client._RetryingHTTP11ClientProtocol(protocol, newProtocol)
-
- def _shouldRetry(m, e, bp):
- self.assertEqual(m, "FOO")
- self.assertIdentical(bp, bodyProducer)
- self.assertIsInstance(e, (RequestNotSent, ResponseNeverReceived))
- return willWeRetry
- retrier._shouldRetry = _shouldRetry
-
- d = retrier.request(request)
-
- # So far, one request made:
- self.assertEqual(len(protocols), 1)
- self.assertEqual(len(protocols[0].requests), 1)
-
- # Fail the first request:
- protocol.requests[0][1].errback(RequestNotSent())
- return d, protocols
-
-
- def test_retryIfShouldRetryReturnsTrue(self):
- """
- L{client._RetryingHTTP11ClientProtocol} retries when
- L{client._RetryingHTTP11ClientProtocol._shouldRetry} returns C{True}.
- """
- d, protocols = self.retryAttempt(True)
- # We retried!
- self.assertEqual(len(protocols), 2)
- response = object()
- protocols[1].requests[0][1].callback(response)
- return d.addCallback(self.assertIdentical, response)
-
-
- def test_dontRetryIfShouldRetryReturnsFalse(self):
- """
- L{client._RetryingHTTP11ClientProtocol} does not retry when
- L{client._RetryingHTTP11ClientProtocol._shouldRetry} returns C{False}.
- """
- d, protocols = self.retryAttempt(False)
- # We did not retry:
- self.assertEqual(len(protocols), 1)
- return self.assertFailure(d, RequestNotSent)
-
-
- def test_onlyRetryWithoutBody(self):
- """
- L{_RetryingHTTP11ClientProtocol} only retries queries that don't have
- a body.
-
- This is an implementation restriction; if the restriction is fixed,
- this test should be removed and PUT added to list of methods that
- support retries.
- """
- pool = client.HTTPConnectionPool(None)
- connection = client._RetryingHTTP11ClientProtocol(None, pool)
- self.assertTrue(connection._shouldRetry("GET", RequestNotSent(), None))
- self.assertFalse(connection._shouldRetry("GET", RequestNotSent(), object()))
-
-
- def test_onlyRetryOnce(self):
- """
- If a L{client._RetryingHTTP11ClientProtocol} fails more than once on
- an idempotent query before a response is received, it will not retry.
- """
- d, protocols = self.retryAttempt(True)
- self.assertEqual(len(protocols), 2)
- # Fail the second request too:
- protocols[1].requests[0][1].errback(ResponseNeverReceived([]))
- # We didn't retry again:
- self.assertEqual(len(protocols), 2)
- return self.assertFailure(d, ResponseNeverReceived)
-
-
- def test_dontRetryIfRetryAutomaticallyFalse(self):
- """
- If L{HTTPConnectionPool.retryAutomatically} is set to C{False}, don't
- wrap connections with retrying logic.
- """
- pool = client.HTTPConnectionPool(Clock())
- pool.retryAutomatically = False
-
- # Add a connection to the cache:
- protocol = StubHTTPProtocol()
- protocol.makeConnection(StringTransport())
- pool._putConnection(123, protocol)
-
- # Retrieve it, it should come back unwrapped:
- d = pool.getConnection(123, DummyEndpoint())
-
- def gotConnection(connection):
- self.assertIdentical(connection, protocol)
- return d.addCallback(gotConnection)
-
-
- def test_retryWithNewConnection(self):
- """
- L{client.HTTPConnectionPool} creates
- {client._RetryingHTTP11ClientProtocol} with a new connection factory
- method that creates a new connection using the same key and endpoint
- as the wrapped connection.
- """
- pool = client.HTTPConnectionPool(Clock())
- key = 123
- endpoint = DummyEndpoint()
- newConnections = []
-
- # Override the pool's _newConnection:
- def newConnection(k, e):
- newConnections.append((k, e))
- pool._newConnection = newConnection
-
- # Add a connection to the cache:
- protocol = StubHTTPProtocol()
- protocol.makeConnection(StringTransport())
- pool._putConnection(key, protocol)
-
- # Retrieve it, it should come back wrapped in a
- # _RetryingHTTP11ClientProtocol:
- d = pool.getConnection(key, endpoint)
-
- def gotConnection(connection):
- self.assertIsInstance(connection,
- client._RetryingHTTP11ClientProtocol)
- self.assertIdentical(connection._clientProtocol, protocol)
- # Verify that the _newConnection method on retrying connection
- # calls _newConnection on the pool:
- self.assertEqual(newConnections, [])
- connection._newConnection()
- self.assertEqual(len(newConnections), 1)
- self.assertEqual(newConnections[0][0], key)
- self.assertIdentical(newConnections[0][1], endpoint)
- return d.addCallback(gotConnection)
-
-
-
-
-class CookieTestsMixin(object):
- """
- Mixin for unit tests dealing with cookies.
- """
- def addCookies(self, cookieJar, uri, cookies):
- """
- Add a cookie to a cookie jar.
- """
- response = client._FakeUrllib2Response(
- client.Response(
- ('HTTP', 1, 1),
- 200,
- 'OK',
- client.Headers({'Set-Cookie': cookies}),
- None))
- request = client._FakeUrllib2Request(uri)
- cookieJar.extract_cookies(response, request)
- return request, response
-
-
-
-class CookieJarTests(unittest.TestCase, CookieTestsMixin):
- """
- Tests for L{twisted.web.client._FakeUrllib2Response} and
- L{twisted.web.client._FakeUrllib2Request}'s interactions with
- C{cookielib.CookieJar} instances.
- """
- def makeCookieJar(self):
- """
- Create a C{cookielib.CookieJar} with some sample cookies.
- """
- cookieJar = cookielib.CookieJar()
- reqres = self.addCookies(
- cookieJar,
- 'http://example.com:1234/foo?bar',
- ['foo=1; cow=moo; Path=/foo; Comment=hello',
- 'bar=2; Comment=goodbye'])
- return cookieJar, reqres
-
-
- def test_extractCookies(self):
- """
- L{cookielib.CookieJar.extract_cookies} extracts cookie information from
- fake urllib2 response instances.
- """
- jar = self.makeCookieJar()[0]
- cookies = dict([(c.name, c) for c in jar])
-
- cookie = cookies['foo']
- self.assertEqual(cookie.version, 0)
- self.assertEqual(cookie.name, 'foo')
- self.assertEqual(cookie.value, '1')
- self.assertEqual(cookie.path, '/foo')
- self.assertEqual(cookie.comment, 'hello')
- self.assertEqual(cookie.get_nonstandard_attr('cow'), 'moo')
-
- cookie = cookies['bar']
- self.assertEqual(cookie.version, 0)
- self.assertEqual(cookie.name, 'bar')
- self.assertEqual(cookie.value, '2')
- self.assertEqual(cookie.path, '/')
- self.assertEqual(cookie.comment, 'goodbye')
- self.assertIdentical(cookie.get_nonstandard_attr('cow'), None)
-
-
- def test_sendCookie(self):
- """
- L{cookielib.CookieJar.add_cookie_header} adds a cookie header to a fake
- urllib2 request instance.
- """
- jar, (request, response) = self.makeCookieJar()
-
- self.assertIdentical(
- request.get_header('Cookie', None),
- None)
-
- jar.add_cookie_header(request)
- self.assertEqual(
- request.get_header('Cookie', None),
- 'foo=1; bar=2')
-
-
-
-class CookieAgentTests(unittest.TestCase, CookieTestsMixin,
- FakeReactorAndConnectMixin):
- """
- Tests for L{twisted.web.client.CookieAgent}.
- """
- def setUp(self):
- self.reactor = self.Reactor()
-
-
- def test_emptyCookieJarRequest(self):
- """
- L{CookieAgent.request} does not insert any C{'Cookie'} header into the
- L{Request} object if there is no cookie in the cookie jar for the URI
- being requested. Cookies are extracted from the response and stored in
- the cookie jar.
- """
- cookieJar = cookielib.CookieJar()
- self.assertEqual(list(cookieJar), [])
-
- agent = self.buildAgentForWrapperTest(self.reactor)
- cookieAgent = client.CookieAgent(agent, cookieJar)
- d = cookieAgent.request(
- 'GET', 'http://example.com:1234/foo?bar')
-
- def _checkCookie(ignored):
- cookies = list(cookieJar)
- self.assertEqual(len(cookies), 1)
- self.assertEqual(cookies[0].name, 'foo')
- self.assertEqual(cookies[0].value, '1')
-
- d.addCallback(_checkCookie)
-
- req, res = self.protocol.requests.pop()
- self.assertIdentical(req.headers.getRawHeaders('cookie'), None)
-
- resp = client.Response(
- ('HTTP', 1, 1),
- 200,
- 'OK',
- client.Headers({'Set-Cookie': ['foo=1',]}),
- None)
- res.callback(resp)
-
- return d
-
-
- def test_requestWithCookie(self):
- """
- L{CookieAgent.request} inserts a C{'Cookie'} header into the L{Request}
- object when there is a cookie matching the request URI in the cookie
- jar.
- """
- uri = 'http://example.com:1234/foo?bar'
- cookie = 'foo=1'
-
- cookieJar = cookielib.CookieJar()
- self.addCookies(cookieJar, uri, [cookie])
- self.assertEqual(len(list(cookieJar)), 1)
-
- agent = self.buildAgentForWrapperTest(self.reactor)
- cookieAgent = client.CookieAgent(agent, cookieJar)
- cookieAgent.request('GET', uri)
-
- req, res = self.protocol.requests.pop()
- self.assertEqual(req.headers.getRawHeaders('cookie'), [cookie])
-
-
- def test_secureCookie(self):
- """
- L{CookieAgent} is able to handle secure cookies, ie cookies which
- should only be handled over https.
- """
- uri = 'https://example.com:1234/foo?bar'
- cookie = 'foo=1;secure'
-
- cookieJar = cookielib.CookieJar()
- self.addCookies(cookieJar, uri, [cookie])
- self.assertEqual(len(list(cookieJar)), 1)
-
- agent = self.buildAgentForWrapperTest(self.reactor)
- cookieAgent = client.CookieAgent(agent, cookieJar)
- cookieAgent.request('GET', uri)
-
- req, res = self.protocol.requests.pop()
- self.assertEqual(req.headers.getRawHeaders('cookie'), ['foo=1'])
-
-
- def test_secureCookieOnInsecureConnection(self):
- """
- If a cookie is setup as secure, it won't be sent with the request if
- it's not over HTTPS.
- """
- uri = 'http://example.com/foo?bar'
- cookie = 'foo=1;secure'
-
- cookieJar = cookielib.CookieJar()
- self.addCookies(cookieJar, uri, [cookie])
- self.assertEqual(len(list(cookieJar)), 1)
-
- agent = self.buildAgentForWrapperTest(self.reactor)
- cookieAgent = client.CookieAgent(agent, cookieJar)
- cookieAgent.request('GET', uri)
-
- req, res = self.protocol.requests.pop()
- self.assertIdentical(None, req.headers.getRawHeaders('cookie'))
-
-
- def test_portCookie(self):
- """
- L{CookieAgent} supports cookies which enforces the port number they
- need to be transferred upon.
- """
- uri = 'https://example.com:1234/foo?bar'
- cookie = 'foo=1;port=1234'
-
- cookieJar = cookielib.CookieJar()
- self.addCookies(cookieJar, uri, [cookie])
- self.assertEqual(len(list(cookieJar)), 1)
-
- agent = self.buildAgentForWrapperTest(self.reactor)
- cookieAgent = client.CookieAgent(agent, cookieJar)
- cookieAgent.request('GET', uri)
-
- req, res = self.protocol.requests.pop()
- self.assertEqual(req.headers.getRawHeaders('cookie'), ['foo=1'])
-
-
- def test_portCookieOnWrongPort(self):
- """
- When creating a cookie with a port directive, it won't be added to the
- L{cookie.CookieJar} if the URI is on a different port.
- """
- uri = 'https://example.com:4567/foo?bar'
- cookie = 'foo=1;port=1234'
-
- cookieJar = cookielib.CookieJar()
- self.addCookies(cookieJar, uri, [cookie])
- self.assertEqual(len(list(cookieJar)), 0)
-
-
-
-class Decoder1(proxyForInterface(IResponse)):
- """
- A test decoder to be used by L{client.ContentDecoderAgent} tests.
- """
-
-
-
-class Decoder2(Decoder1):
- """
- A test decoder to be used by L{client.ContentDecoderAgent} tests.
- """
-
-
-
-class ContentDecoderAgentTests(unittest.TestCase, FakeReactorAndConnectMixin):
- """
- Tests for L{client.ContentDecoderAgent}.
- """
-
- def setUp(self):
- """
- Create an L{Agent} wrapped around a fake reactor.
- """
- self.reactor = self.Reactor()
- self.agent = self.buildAgentForWrapperTest(self.reactor)
-
-
- def test_acceptHeaders(self):
- """
- L{client.ContentDecoderAgent} sets the I{Accept-Encoding} header to the
- names of the available decoder objects.
- """
- agent = client.ContentDecoderAgent(
- self.agent, [('decoder1', Decoder1), ('decoder2', Decoder2)])
-
- agent.request('GET', 'http://example.com/foo')
-
- protocol = self.protocol
-
- self.assertEqual(len(protocol.requests), 1)
- req, res = protocol.requests.pop()
- self.assertEqual(req.headers.getRawHeaders('accept-encoding'),
- ['decoder1,decoder2'])
-
-
- def test_existingHeaders(self):
- """
- If there are existing I{Accept-Encoding} fields,
- L{client.ContentDecoderAgent} creates a new field for the decoders it
- knows about.
- """
- headers = http_headers.Headers({'foo': ['bar'],
- 'accept-encoding': ['fizz']})
- agent = client.ContentDecoderAgent(
- self.agent, [('decoder1', Decoder1), ('decoder2', Decoder2)])
- agent.request('GET', 'http://example.com/foo', headers=headers)
-
- protocol = self.protocol
-
- self.assertEqual(len(protocol.requests), 1)
- req, res = protocol.requests.pop()
- self.assertEqual(
- list(req.headers.getAllRawHeaders()),
- [('Host', ['example.com']),
- ('Foo', ['bar']),
- ('Accept-Encoding', ['fizz', 'decoder1,decoder2'])])
-
-
- def test_plainEncodingResponse(self):
- """
- If the response is not encoded despited the request I{Accept-Encoding}
- headers, L{client.ContentDecoderAgent} simply forwards the response.
- """
- agent = client.ContentDecoderAgent(
- self.agent, [('decoder1', Decoder1), ('decoder2', Decoder2)])
- deferred = agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- response = Response(('HTTP', 1, 1), 200, 'OK', http_headers.Headers(),
- None)
- res.callback(response)
-
- return deferred.addCallback(self.assertIdentical, response)
-
-
- def test_unsupportedEncoding(self):
- """
- If an encoding unknown to the L{client.ContentDecoderAgent} is found,
- the response is unchanged.
- """
- agent = client.ContentDecoderAgent(
- self.agent, [('decoder1', Decoder1), ('decoder2', Decoder2)])
- deferred = agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers({'foo': ['bar'],
- 'content-encoding': ['fizz']})
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, None)
- res.callback(response)
-
- return deferred.addCallback(self.assertIdentical, response)
-
-
- def test_unknownEncoding(self):
- """
- When L{client.ContentDecoderAgent} encounters a decoder it doesn't know
- about, it stops decoding even if another encoding is known afterwards.
- """
- agent = client.ContentDecoderAgent(
- self.agent, [('decoder1', Decoder1), ('decoder2', Decoder2)])
- deferred = agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers({'foo': ['bar'],
- 'content-encoding':
- ['decoder1,fizz,decoder2']})
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, None)
- res.callback(response)
-
- def check(result):
- self.assertNotIdentical(response, result)
- self.assertIsInstance(result, Decoder2)
- self.assertEqual(['decoder1,fizz'],
- result.headers.getRawHeaders('content-encoding'))
-
- return deferred.addCallback(check)
-
-
-
-class SimpleAgentProtocol(Protocol):
- """
- A L{Protocol} to be used with an L{client.Agent} to receive data.
-
- @ivar finished: L{Deferred} firing when C{connectionLost} is called.
-
- @ivar made: L{Deferred} firing when C{connectionMade} is called.
-
- @ivar received: C{list} of received data.
- """
-
- def __init__(self):
- self.made = Deferred()
- self.finished = Deferred()
- self.received = []
-
-
- def connectionMade(self):
- self.made.callback(None)
-
-
- def connectionLost(self, reason):
- self.finished.callback(None)
-
-
- def dataReceived(self, data):
- self.received.append(data)
-
-
-
-class ContentDecoderAgentWithGzipTests(unittest.TestCase,
- FakeReactorAndConnectMixin):
-
- def setUp(self):
- """
- Create an L{Agent} wrapped around a fake reactor.
- """
- self.reactor = self.Reactor()
- agent = self.buildAgentForWrapperTest(self.reactor)
- self.agent = client.ContentDecoderAgent(
- agent, [("gzip", client.GzipDecoder)])
-
-
- def test_gzipEncodingResponse(self):
- """
- If the response has a C{gzip} I{Content-Encoding} header,
- L{GzipDecoder} wraps the response to return uncompressed data to the
- user.
- """
- deferred = self.agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers({'foo': ['bar'],
- 'content-encoding': ['gzip']})
- transport = StringTransport()
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, transport)
- response.length = 12
- res.callback(response)
-
- compressor = zlib.compressobj(2, zlib.DEFLATED, 16 + zlib.MAX_WBITS)
- data = (compressor.compress('x' * 6) + compressor.compress('y' * 4) +
- compressor.flush())
-
- def checkResponse(result):
- self.assertNotIdentical(result, response)
- self.assertEqual(result.version, ('HTTP', 1, 1))
- self.assertEqual(result.code, 200)
- self.assertEqual(result.phrase, 'OK')
- self.assertEqual(list(result.headers.getAllRawHeaders()),
- [('Foo', ['bar'])])
- self.assertEqual(result.length, UNKNOWN_LENGTH)
- self.assertRaises(AttributeError, getattr, result, 'unknown')
-
- response._bodyDataReceived(data[:5])
- response._bodyDataReceived(data[5:])
- response._bodyDataFinished()
-
- protocol = SimpleAgentProtocol()
- result.deliverBody(protocol)
-
- self.assertEqual(protocol.received, ['x' * 6 + 'y' * 4])
- return defer.gatherResults([protocol.made, protocol.finished])
-
- deferred.addCallback(checkResponse)
-
- return deferred
-
-
- def test_brokenContent(self):
- """
- If the data received by the L{GzipDecoder} isn't valid gzip-compressed
- data, the call to C{deliverBody} fails with a C{zlib.error}.
- """
- deferred = self.agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers({'foo': ['bar'],
- 'content-encoding': ['gzip']})
- transport = StringTransport()
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, transport)
- response.length = 12
- res.callback(response)
-
- data = "not gzipped content"
-
- def checkResponse(result):
- response._bodyDataReceived(data)
-
- result.deliverBody(Protocol())
-
- deferred.addCallback(checkResponse)
- self.assertFailure(deferred, client.ResponseFailed)
-
- def checkFailure(error):
- error.reasons[0].trap(zlib.error)
- self.assertIsInstance(error.response, Response)
-
- return deferred.addCallback(checkFailure)
-
-
- def test_flushData(self):
- """
- When the connection with the server is lost, the gzip protocol calls
- C{flush} on the zlib decompressor object to get uncompressed data which
- may have been buffered.
- """
- class decompressobj(object):
-
- def __init__(self, wbits):
- pass
-
- def decompress(self, data):
- return 'x'
-
- def flush(self):
- return 'y'
-
-
- oldDecompressObj = zlib.decompressobj
- zlib.decompressobj = decompressobj
- self.addCleanup(setattr, zlib, 'decompressobj', oldDecompressObj)
-
- deferred = self.agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers({'content-encoding': ['gzip']})
- transport = StringTransport()
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, transport)
- res.callback(response)
-
- def checkResponse(result):
- response._bodyDataReceived('data')
- response._bodyDataFinished()
-
- protocol = SimpleAgentProtocol()
- result.deliverBody(protocol)
-
- self.assertEqual(protocol.received, ['x', 'y'])
- return defer.gatherResults([protocol.made, protocol.finished])
-
- deferred.addCallback(checkResponse)
-
- return deferred
-
-
- def test_flushError(self):
- """
- If the C{flush} call in C{connectionLost} fails, the C{zlib.error}
- exception is caught and turned into a L{ResponseFailed}.
- """
- class decompressobj(object):
-
- def __init__(self, wbits):
- pass
-
- def decompress(self, data):
- return 'x'
-
- def flush(self):
- raise zlib.error()
-
-
- oldDecompressObj = zlib.decompressobj
- zlib.decompressobj = decompressobj
- self.addCleanup(setattr, zlib, 'decompressobj', oldDecompressObj)
-
- deferred = self.agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers({'content-encoding': ['gzip']})
- transport = StringTransport()
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, transport)
- res.callback(response)
-
- def checkResponse(result):
- response._bodyDataReceived('data')
- response._bodyDataFinished()
-
- protocol = SimpleAgentProtocol()
- result.deliverBody(protocol)
-
- self.assertEqual(protocol.received, ['x', 'y'])
- return defer.gatherResults([protocol.made, protocol.finished])
-
- deferred.addCallback(checkResponse)
-
- self.assertFailure(deferred, client.ResponseFailed)
-
- def checkFailure(error):
- error.reasons[1].trap(zlib.error)
- self.assertIsInstance(error.response, Response)
-
- return deferred.addCallback(checkFailure)
-
-
-
-class ProxyAgentTests(unittest.TestCase, FakeReactorAndConnectMixin):
- """
- Tests for L{client.ProxyAgent}.
- """
-
- def setUp(self):
- self.reactor = self.Reactor()
- self.agent = client.ProxyAgent(
- TCP4ClientEndpoint(self.reactor, "bar", 5678), self.reactor)
- oldEndpoint = self.agent._proxyEndpoint
- self.agent._proxyEndpoint = self.StubEndpoint(oldEndpoint, self)
-
-
- def test_proxyRequest(self):
- """
- L{client.ProxyAgent} issues an HTTP request against the proxy, with the
- full URI as path, when C{request} is called.
- """
- headers = http_headers.Headers({'foo': ['bar']})
- # Just going to check the body for identity, so it doesn't need to be
- # real.
- body = object()
- self.agent.request(
- 'GET', 'http://example.com:1234/foo?bar', headers, body)
-
- host, port, factory = self.reactor.tcpClients.pop()[:3]
- self.assertEqual(host, "bar")
- self.assertEqual(port, 5678)
-
- self.assertIsInstance(factory._wrappedFactory,
- client._HTTP11ClientFactory)
-
- protocol = self.protocol
-
- # The request should be issued.
- self.assertEqual(len(protocol.requests), 1)
- req, res = protocol.requests.pop()
- self.assertIsInstance(req, Request)
- self.assertEqual(req.method, 'GET')
- self.assertEqual(req.uri, 'http://example.com:1234/foo?bar')
- self.assertEqual(
- req.headers,
- http_headers.Headers({'foo': ['bar'],
- 'host': ['example.com:1234']}))
- self.assertIdentical(req.bodyProducer, body)
-
-
- def test_nonPersistent(self):
- """
- C{ProxyAgent} connections are not persistent by default.
- """
- self.assertEqual(self.agent._pool.persistent, False)
-
-
- def test_connectUsesConnectionPool(self):
- """
- When a connection is made by the C{ProxyAgent}, it uses its pool's
- C{getConnection} method to do so, with the endpoint it was constructed
- with and a key of C{("http-proxy", endpoint)}.
- """
- endpoint = DummyEndpoint()
- class DummyPool(object):
- connected = False
- persistent = False
- def getConnection(this, key, ep):
- this.connected = True
- self.assertIdentical(ep, endpoint)
- # The key is *not* tied to the final destination, but only to
- # the address of the proxy, since that's where *we* are
- # connecting:
- self.assertEqual(key, ("http-proxy", endpoint))
- return defer.succeed(StubHTTPProtocol())
-
- pool = DummyPool()
- agent = client.ProxyAgent(endpoint, self.reactor, pool=pool)
- self.assertIdentical(pool, agent._pool)
-
- agent.request('GET', 'http://foo/')
- self.assertEqual(agent._pool.connected, True)
-
-
-
-class RedirectAgentTests(unittest.TestCase, FakeReactorAndConnectMixin):
- """
- Tests for L{client.RedirectAgent}.
- """
-
- def setUp(self):
- self.reactor = self.Reactor()
- self.agent = client.RedirectAgent(
- self.buildAgentForWrapperTest(self.reactor))
-
-
- def test_noRedirect(self):
- """
- L{client.RedirectAgent} behaves like L{client.Agent} if the response
- doesn't contain a redirect.
- """
- deferred = self.agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers()
- response = Response(('HTTP', 1, 1), 200, 'OK', headers, None)
- res.callback(response)
-
- self.assertEqual(0, len(self.protocol.requests))
-
- def checkResponse(result):
- self.assertIdentical(result, response)
-
- return deferred.addCallback(checkResponse)
-
-
- def _testRedirectDefault(self, code):
- """
- When getting a redirect, L{RedirectAgent} follows the URL specified in
- the L{Location} header field and make a new request.
- """
- self.agent.request('GET', 'http://example.com/foo')
-
- host, port = self.reactor.tcpClients.pop()[:2]
- self.assertEqual("example.com", host)
- self.assertEqual(80, port)
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers(
- {'location': ['https://example.com/bar']})
- response = Response(('HTTP', 1, 1), code, 'OK', headers, None)
- res.callback(response)
-
- req2, res2 = self.protocol.requests.pop()
- self.assertEqual('GET', req2.method)
- self.assertEqual('/bar', req2.uri)
-
- host, port = self.reactor.sslClients.pop()[:2]
- self.assertEqual("example.com", host)
- self.assertEqual(443, port)
-
-
- def test_redirect301(self):
- """
- L{RedirectAgent} follows redirects on status code 301.
- """
- self._testRedirectDefault(301)
-
-
- def test_redirect302(self):
- """
- L{RedirectAgent} follows redirects on status code 302.
- """
- self._testRedirectDefault(302)
-
-
- def test_redirect307(self):
- """
- L{RedirectAgent} follows redirects on status code 307.
- """
- self._testRedirectDefault(307)
-
-
- def test_redirect303(self):
- """
- L{RedirectAgent} changes the methods to C{GET} when getting a redirect
- on a C{POST} request.
- """
- self.agent.request('POST', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers(
- {'location': ['http://example.com/bar']})
- response = Response(('HTTP', 1, 1), 303, 'OK', headers, None)
- res.callback(response)
-
- req2, res2 = self.protocol.requests.pop()
- self.assertEqual('GET', req2.method)
- self.assertEqual('/bar', req2.uri)
-
-
- def test_noLocationField(self):
- """
- If no L{Location} header field is found when getting a redirect,
- L{RedirectAgent} fails with a L{ResponseFailed} error wrapping a
- L{error.RedirectWithNoLocation} exception.
- """
- deferred = self.agent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers()
- response = Response(('HTTP', 1, 1), 301, 'OK', headers, None)
- res.callback(response)
-
- self.assertFailure(deferred, client.ResponseFailed)
-
- def checkFailure(fail):
- fail.reasons[0].trap(error.RedirectWithNoLocation)
- self.assertEqual('http://example.com/foo',
- fail.reasons[0].value.uri)
- self.assertEqual(301, fail.response.code)
-
- return deferred.addCallback(checkFailure)
-
-
- def test_307OnPost(self):
- """
- When getting a 307 redirect on a C{POST} request, L{RedirectAgent} fais
- with a L{ResponseFailed} error wrapping a L{error.PageRedirect}
- exception.
- """
- deferred = self.agent.request('POST', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers()
- response = Response(('HTTP', 1, 1), 307, 'OK', headers, None)
- res.callback(response)
-
- self.assertFailure(deferred, client.ResponseFailed)
-
- def checkFailure(fail):
- fail.reasons[0].trap(error.PageRedirect)
- self.assertEqual('http://example.com/foo',
- fail.reasons[0].value.location)
- self.assertEqual(307, fail.response.code)
-
- return deferred.addCallback(checkFailure)
-
-
- def test_redirectLimit(self):
- """
- If the limit of redirects specified to L{RedirectAgent} is reached, the
- deferred fires with L{ResponseFailed} error wrapping a
- L{InfiniteRedirection} exception.
- """
- agent = self.buildAgentForWrapperTest(self.reactor)
- redirectAgent = client.RedirectAgent(agent, 1)
-
- deferred = redirectAgent.request('GET', 'http://example.com/foo')
-
- req, res = self.protocol.requests.pop()
-
- headers = http_headers.Headers(
- {'location': ['http://example.com/bar']})
- response = Response(('HTTP', 1, 1), 302, 'OK', headers, None)
- res.callback(response)
-
- req2, res2 = self.protocol.requests.pop()
-
- response2 = Response(('HTTP', 1, 1), 302, 'OK', headers, None)
- res2.callback(response2)
-
- self.assertFailure(deferred, client.ResponseFailed)
-
- def checkFailure(fail):
- fail.reasons[0].trap(error.InfiniteRedirection)
- self.assertEqual('http://example.com/foo',
- fail.reasons[0].value.location)
- self.assertEqual(302, fail.response.code)
-
- return deferred.addCallback(checkFailure)
-
-
-
-if ssl is None or not hasattr(ssl, 'DefaultOpenSSLContextFactory'):
- for case in [WebClientSSLTestCase, WebClientRedirectBetweenSSLandPlainText]:
- case.skip = "OpenSSL not present"
-
-if not interfaces.IReactorSSL(reactor, None):
- for case in [WebClientSSLTestCase, WebClientRedirectBetweenSSLandPlainText]:
- case.skip = "Reactor doesn't support SSL"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_wsgi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_wsgi.py
deleted file mode 100755
index ddcdf11d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_wsgi.py
+++ /dev/null
@@ -1,1572 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.web.wsgi}.
-"""
-
-__metaclass__ = type
-
-from sys import exc_info
-from urllib import quote
-from thread import get_ident
-import StringIO, cStringIO, tempfile
-
-from zope.interface.verify import verifyObject
-
-from twisted.python.compat import set
-from twisted.python.log import addObserver, removeObserver, err
-from twisted.python.failure import Failure
-from twisted.python.threadpool import ThreadPool
-from twisted.internet.defer import Deferred, gatherResults
-from twisted.internet import reactor
-from twisted.internet.error import ConnectionLost
-from twisted.trial.unittest import TestCase
-from twisted.web import http
-from twisted.web.resource import IResource, Resource
-from twisted.web.server import Request, Site, version
-from twisted.web.wsgi import WSGIResource
-from twisted.web.test.test_web import DummyChannel
-
-
-class SynchronousThreadPool:
- """
- A single-threaded implementation of part of the L{ThreadPool} interface.
- This implementation calls functions synchronously rather than running
- them in a thread pool. It is used to make the tests which are not
- directly for thread-related behavior deterministic.
- """
- def callInThread(self, f, *a, **kw):
- """
- Call C{f(*a, **kw)} in this thread rather than scheduling it to be
- called in a thread.
- """
- try:
- f(*a, **kw)
- except:
- # callInThread doesn't let exceptions propagate to the caller.
- # None is always returned and any exception raised gets logged
- # later on.
- err(None, "Callable passed to SynchronousThreadPool.callInThread failed")
-
-
-
-class SynchronousReactorThreads:
- """
- A single-threaded implementation of part of the L{IReactorThreads}
- interface. This implementation assumes that it will only be invoked
- from the reactor thread, so it calls functions synchronously rather than
- trying to schedule them to run in the reactor thread. It is used in
- conjunction with L{SynchronousThreadPool} to make the tests which are
- not directly for thread-related behavior deterministic.
- """
- def callFromThread(self, f, *a, **kw):
- """
- Call C{f(*a, **kw)} in this thread which should also be the reactor
- thread.
- """
- f(*a, **kw)
-
-
-
-class WSGIResourceTests(TestCase):
- def setUp(self):
- """
- Create a L{WSGIResource} with synchronous threading objects and a no-op
- application object. This is useful for testing certain things about
- the resource implementation which are unrelated to WSGI.
- """
- self.resource = WSGIResource(
- SynchronousReactorThreads(), SynchronousThreadPool(),
- lambda environ, startResponse: None)
-
-
- def test_interfaces(self):
- """
- L{WSGIResource} implements L{IResource} and stops resource traversal.
- """
- verifyObject(IResource, self.resource)
- self.assertTrue(self.resource.isLeaf)
-
-
- def test_unsupported(self):
- """
- A L{WSGIResource} cannot have L{IResource} children. Its
- C{getChildWithDefault} and C{putChild} methods raise L{RuntimeError}.
- """
- self.assertRaises(
- RuntimeError,
- self.resource.getChildWithDefault,
- "foo", Request(DummyChannel(), False))
- self.assertRaises(
- RuntimeError,
- self.resource.putChild,
- "foo", Resource())
-
-
-class WSGITestsMixin:
- """
- @ivar channelFactory: A no-argument callable which will be invoked to
- create a new HTTP channel to associate with request objects.
- """
- channelFactory = DummyChannel
-
- def setUp(self):
- self.threadpool = SynchronousThreadPool()
- self.reactor = SynchronousReactorThreads()
-
-
- def lowLevelRender(
- self, requestFactory, applicationFactory, channelFactory, method,
- version, resourceSegments, requestSegments, query=None, headers=[],
- body=None, safe=''):
- """
- @param method: A C{str} giving the request method to use.
-
- @param version: A C{str} like C{'1.1'} giving the request version.
-
- @param resourceSegments: A C{list} of unencoded path segments which
- specifies the location in the resource hierarchy at which the
- L{WSGIResource} will be placed, eg C{['']} for I{/}, C{['foo',
- 'bar', '']} for I{/foo/bar/}, etc.
-
- @param requestSegments: A C{list} of unencoded path segments giving the
- request URI.
-
- @param query: A C{list} of two-tuples of C{str} giving unencoded query
- argument keys and values.
-
- @param headers: A C{list} of two-tuples of C{str} giving request header
- names and corresponding values.
-
- @param safe: A C{str} giving the bytes which are to be considered
- I{safe} for inclusion in the request URI and not quoted.
-
- @return: A L{Deferred} which will be called back with a two-tuple of
- the arguments passed which would be passed to the WSGI application
- object for this configuration and request (ie, the environment and
- start_response callable).
- """
- root = WSGIResource(
- self.reactor, self.threadpool, applicationFactory())
- resourceSegments.reverse()
- for seg in resourceSegments:
- tmp = Resource()
- tmp.putChild(seg, root)
- root = tmp
-
- channel = channelFactory()
- channel.site = Site(root)
- request = requestFactory(channel, False)
- for k, v in headers:
- request.requestHeaders.addRawHeader(k, v)
- request.gotLength(0)
- if body:
- request.content.write(body)
- request.content.seek(0)
- uri = '/' + '/'.join([quote(seg, safe) for seg in requestSegments])
- if query is not None:
- uri += '?' + '&'.join(['='.join([quote(k, safe), quote(v, safe)])
- for (k, v) in query])
- request.requestReceived(method, uri, 'HTTP/' + version)
- return request
-
-
- def render(self, *a, **kw):
- result = Deferred()
- def applicationFactory():
- def application(*args):
- environ, startResponse = args
- result.callback(args)
- startResponse('200 OK', [])
- return iter(())
- return application
- self.lowLevelRender(
- Request, applicationFactory, self.channelFactory, *a, **kw)
- return result
-
-
- def requestFactoryFactory(self, requestClass=Request):
- d = Deferred()
- def requestFactory(*a, **kw):
- request = requestClass(*a, **kw)
- # If notifyFinish is called after lowLevelRender returns, it won't
- # do the right thing, because the request will have already
- # finished. One might argue that this is a bug in
- # Request.notifyFinish.
- request.notifyFinish().chainDeferred(d)
- return request
- return d, requestFactory
-
-
- def getContentFromResponse(self, response):
- return response.split('\r\n\r\n', 1)[1]
-
-
-
-class EnvironTests(WSGITestsMixin, TestCase):
- """
- Tests for the values in the C{environ} C{dict} passed to the application
- object by L{twisted.web.wsgi.WSGIResource}.
- """
- def environKeyEqual(self, key, value):
- def assertEnvironKeyEqual((environ, startResponse)):
- self.assertEqual(environ[key], value)
- return assertEnvironKeyEqual
-
-
- def test_environIsDict(self):
- """
- L{WSGIResource} calls the application object with an C{environ}
- parameter which is exactly of type C{dict}.
- """
- d = self.render('GET', '1.1', [], [''])
- def cbRendered((environ, startResponse)):
- self.assertIdentical(type(environ), dict)
- d.addCallback(cbRendered)
- return d
-
-
- def test_requestMethod(self):
- """
- The C{'REQUEST_METHOD'} key of the C{environ} C{dict} passed to the
- application contains the HTTP method in the request (RFC 3875, section
- 4.1.12).
- """
- get = self.render('GET', '1.1', [], [''])
- get.addCallback(self.environKeyEqual('REQUEST_METHOD', 'GET'))
-
- # Also make sure a different request method shows up as a different
- # value in the environ dict.
- post = self.render('POST', '1.1', [], [''])
- post.addCallback(self.environKeyEqual('REQUEST_METHOD', 'POST'))
-
- return gatherResults([get, post])
-
-
- def test_scriptName(self):
- """
- The C{'SCRIPT_NAME'} key of the C{environ} C{dict} passed to the
- application contains the I{abs_path} (RFC 2396, section 3) to this
- resource (RFC 3875, section 4.1.13).
- """
- root = self.render('GET', '1.1', [], [''])
- root.addCallback(self.environKeyEqual('SCRIPT_NAME', ''))
-
- emptyChild = self.render('GET', '1.1', [''], [''])
- emptyChild.addCallback(self.environKeyEqual('SCRIPT_NAME', '/'))
-
- leaf = self.render('GET', '1.1', ['foo'], ['foo'])
- leaf.addCallback(self.environKeyEqual('SCRIPT_NAME', '/foo'))
-
- container = self.render('GET', '1.1', ['foo', ''], ['foo', ''])
- container.addCallback(self.environKeyEqual('SCRIPT_NAME', '/foo/'))
-
- internal = self.render('GET', '1.1', ['foo'], ['foo', 'bar'])
- internal.addCallback(self.environKeyEqual('SCRIPT_NAME', '/foo'))
-
- unencoded = self.render(
- 'GET', '1.1', ['foo', '/', 'bar\xff'], ['foo', '/', 'bar\xff'])
- # The RFC says "(not URL-encoded)", even though that makes
- # interpretation of SCRIPT_NAME ambiguous.
- unencoded.addCallback(
- self.environKeyEqual('SCRIPT_NAME', '/foo///bar\xff'))
-
- return gatherResults([
- root, emptyChild, leaf, container, internal, unencoded])
-
-
- def test_pathInfo(self):
- """
- The C{'PATH_INFO'} key of the C{environ} C{dict} passed to the
- application contains the suffix of the request URI path which is not
- included in the value for the C{'SCRIPT_NAME'} key (RFC 3875, section
- 4.1.5).
- """
- assertKeyEmpty = self.environKeyEqual('PATH_INFO', '')
-
- root = self.render('GET', '1.1', [], [''])
- root.addCallback(self.environKeyEqual('PATH_INFO', '/'))
-
- emptyChild = self.render('GET', '1.1', [''], [''])
- emptyChild.addCallback(assertKeyEmpty)
-
- leaf = self.render('GET', '1.1', ['foo'], ['foo'])
- leaf.addCallback(assertKeyEmpty)
-
- container = self.render('GET', '1.1', ['foo', ''], ['foo', ''])
- container.addCallback(assertKeyEmpty)
-
- internalLeaf = self.render('GET', '1.1', ['foo'], ['foo', 'bar'])
- internalLeaf.addCallback(self.environKeyEqual('PATH_INFO', '/bar'))
-
- internalContainer = self.render('GET', '1.1', ['foo'], ['foo', ''])
- internalContainer.addCallback(self.environKeyEqual('PATH_INFO', '/'))
-
- unencoded = self.render('GET', '1.1', [], ['foo', '/', 'bar\xff'])
- unencoded.addCallback(
- self.environKeyEqual('PATH_INFO', '/foo///bar\xff'))
-
- return gatherResults([
- root, leaf, container, internalLeaf,
- internalContainer, unencoded])
-
-
- def test_queryString(self):
- """
- The C{'QUERY_STRING'} key of the C{environ} C{dict} passed to the
- application contains the portion of the request URI after the first
- I{?} (RFC 3875, section 4.1.7).
- """
- missing = self.render('GET', '1.1', [], [''], None)
- missing.addCallback(self.environKeyEqual('QUERY_STRING', ''))
-
- empty = self.render('GET', '1.1', [], [''], [])
- empty.addCallback(self.environKeyEqual('QUERY_STRING', ''))
-
- present = self.render('GET', '1.1', [], [''], [('foo', 'bar')])
- present.addCallback(self.environKeyEqual('QUERY_STRING', 'foo=bar'))
-
- unencoded = self.render('GET', '1.1', [], [''], [('/', '/')])
- unencoded.addCallback(self.environKeyEqual('QUERY_STRING', '%2F=%2F'))
-
- # "?" is reserved in the <searchpart> portion of a URL. However, it
- # seems to be a common mistake of clients to forget to quote it. So,
- # make sure we handle that invalid case.
- doubleQuestion = self.render(
- 'GET', '1.1', [], [''], [('foo', '?bar')], safe='?')
- doubleQuestion.addCallback(
- self.environKeyEqual('QUERY_STRING', 'foo=?bar'))
-
- return gatherResults([
- missing, empty, present, unencoded, doubleQuestion])
-
-
- def test_contentType(self):
- """
- The C{'CONTENT_TYPE'} key of the C{environ} C{dict} passed to the
- application contains the value of the I{Content-Type} request header
- (RFC 3875, section 4.1.3).
- """
- missing = self.render('GET', '1.1', [], [''])
- missing.addCallback(self.environKeyEqual('CONTENT_TYPE', ''))
-
- present = self.render(
- 'GET', '1.1', [], [''], None, [('content-type', 'x-foo/bar')])
- present.addCallback(self.environKeyEqual('CONTENT_TYPE', 'x-foo/bar'))
-
- return gatherResults([missing, present])
-
-
- def test_contentLength(self):
- """
- The C{'CONTENT_LENGTH'} key of the C{environ} C{dict} passed to the
- application contains the value of the I{Content-Length} request header
- (RFC 3875, section 4.1.2).
- """
- missing = self.render('GET', '1.1', [], [''])
- missing.addCallback(self.environKeyEqual('CONTENT_LENGTH', ''))
-
- present = self.render(
- 'GET', '1.1', [], [''], None, [('content-length', '1234')])
- present.addCallback(self.environKeyEqual('CONTENT_LENGTH', '1234'))
-
- return gatherResults([missing, present])
-
-
- def test_serverName(self):
- """
- The C{'SERVER_NAME'} key of the C{environ} C{dict} passed to the
- application contains the best determination of the server hostname
- possible, using either the value of the I{Host} header in the request
- or the address the server is listening on if that header is not
- present (RFC 3875, section 4.1.14).
- """
- missing = self.render('GET', '1.1', [], [''])
- # 10.0.0.1 value comes from a bit far away -
- # twisted.test.test_web.DummyChannel.transport.getHost().host
- missing.addCallback(self.environKeyEqual('SERVER_NAME', '10.0.0.1'))
-
- present = self.render(
- 'GET', '1.1', [], [''], None, [('host', 'example.org')])
- present.addCallback(self.environKeyEqual('SERVER_NAME', 'example.org'))
-
- return gatherResults([missing, present])
-
-
- def test_serverPort(self):
- """
- The C{'SERVER_PORT'} key of the C{environ} C{dict} passed to the
- application contains the port number of the server which received the
- request (RFC 3875, section 4.1.15).
- """
- portNumber = 12354
- def makeChannel():
- channel = DummyChannel()
- channel.transport = DummyChannel.TCP()
- channel.transport.port = portNumber
- return channel
- self.channelFactory = makeChannel
-
- d = self.render('GET', '1.1', [], [''])
- d.addCallback(self.environKeyEqual('SERVER_PORT', str(portNumber)))
- return d
-
-
- def test_serverProtocol(self):
- """
- The C{'SERVER_PROTOCOL'} key of the C{environ} C{dict} passed to the
- application contains the HTTP version number received in the request
- (RFC 3875, section 4.1.16).
- """
- old = self.render('GET', '1.0', [], [''])
- old.addCallback(self.environKeyEqual('SERVER_PROTOCOL', 'HTTP/1.0'))
-
- new = self.render('GET', '1.1', [], [''])
- new.addCallback(self.environKeyEqual('SERVER_PROTOCOL', 'HTTP/1.1'))
-
- return gatherResults([old, new])
-
-
- def test_remoteAddr(self):
- """
- The C{'REMOTE_ADDR'} key of the C{environ} C{dict} passed to the
- application contains the address of the client making the request.
- """
- d = self.render('GET', '1.1', [], [''])
- d.addCallback(self.environKeyEqual('REMOTE_ADDR', '192.168.1.1'))
-
- return d
-
- def test_headers(self):
- """
- HTTP request headers are copied into the C{environ} C{dict} passed to
- the application with a C{HTTP_} prefix added to their names.
- """
- singleValue = self.render(
- 'GET', '1.1', [], [''], None, [('foo', 'bar'), ('baz', 'quux')])
- def cbRendered((environ, startResponse)):
- self.assertEqual(environ['HTTP_FOO'], 'bar')
- self.assertEqual(environ['HTTP_BAZ'], 'quux')
- singleValue.addCallback(cbRendered)
-
- multiValue = self.render(
- 'GET', '1.1', [], [''], None, [('foo', 'bar'), ('foo', 'baz')])
- multiValue.addCallback(self.environKeyEqual('HTTP_FOO', 'bar,baz'))
-
- withHyphen = self.render(
- 'GET', '1.1', [], [''], None, [('foo-bar', 'baz')])
- withHyphen.addCallback(self.environKeyEqual('HTTP_FOO_BAR', 'baz'))
-
- multiLine = self.render(
- 'GET', '1.1', [], [''], None, [('foo', 'bar\n\tbaz')])
- multiLine.addCallback(self.environKeyEqual('HTTP_FOO', 'bar \tbaz'))
-
- return gatherResults([singleValue, multiValue, withHyphen, multiLine])
-
-
- def test_wsgiVersion(self):
- """
- The C{'wsgi.version'} key of the C{environ} C{dict} passed to the
- application has the value C{(1, 0)} indicating that this is a WSGI 1.0
- container.
- """
- versionDeferred = self.render('GET', '1.1', [], [''])
- versionDeferred.addCallback(self.environKeyEqual('wsgi.version', (1, 0)))
- return versionDeferred
-
-
- def test_wsgiRunOnce(self):
- """
- The C{'wsgi.run_once'} key of the C{environ} C{dict} passed to the
- application is set to C{False}.
- """
- once = self.render('GET', '1.1', [], [''])
- once.addCallback(self.environKeyEqual('wsgi.run_once', False))
- return once
-
-
- def test_wsgiMultithread(self):
- """
- The C{'wsgi.multithread'} key of the C{environ} C{dict} passed to the
- application is set to C{True}.
- """
- thread = self.render('GET', '1.1', [], [''])
- thread.addCallback(self.environKeyEqual('wsgi.multithread', True))
- return thread
-
-
- def test_wsgiMultiprocess(self):
- """
- The C{'wsgi.multiprocess'} key of the C{environ} C{dict} passed to the
- application is set to C{False}.
- """
- process = self.render('GET', '1.1', [], [''])
- process.addCallback(self.environKeyEqual('wsgi.multiprocess', False))
- return process
-
-
- def test_wsgiURLScheme(self):
- """
- The C{'wsgi.url_scheme'} key of the C{environ} C{dict} passed to the
- application has the request URL scheme.
- """
- # XXX Does this need to be different if the request is for an absolute
- # URL?
- def channelFactory():
- channel = DummyChannel()
- channel.transport = DummyChannel.SSL()
- return channel
-
- self.channelFactory = DummyChannel
- httpDeferred = self.render('GET', '1.1', [], [''])
- httpDeferred.addCallback(self.environKeyEqual('wsgi.url_scheme', 'http'))
-
- self.channelFactory = channelFactory
- httpsDeferred = self.render('GET', '1.1', [], [''])
- httpsDeferred.addCallback(self.environKeyEqual('wsgi.url_scheme', 'https'))
-
- return gatherResults([httpDeferred, httpsDeferred])
-
-
- def test_wsgiErrors(self):
- """
- The C{'wsgi.errors'} key of the C{environ} C{dict} passed to the
- application is a file-like object (as defined in the U{Input and Errors
- Streams<http://www.python.org/dev/peps/pep-0333/#input-and-error-streams>}
- section of PEP 333) which converts bytes written to it into events for
- the logging system.
- """
- events = []
- addObserver(events.append)
- self.addCleanup(removeObserver, events.append)
-
- errors = self.render('GET', '1.1', [], [''])
- def cbErrors((environ, startApplication)):
- errors = environ['wsgi.errors']
- errors.write('some message\n')
- errors.writelines(['another\nmessage\n'])
- errors.flush()
- self.assertEqual(events[0]['message'], ('some message\n',))
- self.assertEqual(events[0]['system'], 'wsgi')
- self.assertTrue(events[0]['isError'])
- self.assertEqual(events[1]['message'], ('another\nmessage\n',))
- self.assertEqual(events[1]['system'], 'wsgi')
- self.assertTrue(events[1]['isError'])
- self.assertEqual(len(events), 2)
- errors.addCallback(cbErrors)
- return errors
-
-
-class InputStreamTestMixin(WSGITestsMixin):
- """
- A mixin for L{TestCase} subclasses which defines a number of tests against
- L{_InputStream}. The subclass is expected to create a file-like object to
- be wrapped by an L{_InputStream} under test.
- """
- def getFileType(self):
- raise NotImplementedError(
- "%s.getFile must be implemented" % (self.__class__.__name__,))
-
-
- def _renderAndReturnReaderResult(self, reader, content):
- contentType = self.getFileType()
- class CustomizedRequest(Request):
- def gotLength(self, length):
- # Always allocate a file of the specified type, instead of
- # using the base behavior of selecting one depending on the
- # length.
- self.content = contentType()
-
- def appFactoryFactory(reader):
- result = Deferred()
- def applicationFactory():
- def application(*args):
- environ, startResponse = args
- result.callback(reader(environ['wsgi.input']))
- startResponse('200 OK', [])
- return iter(())
- return application
- return result, applicationFactory
- d, appFactory = appFactoryFactory(reader)
- self.lowLevelRender(
- CustomizedRequest, appFactory, DummyChannel,
- 'PUT', '1.1', [], [''], None, [],
- content)
- return d
-
-
- def test_readAll(self):
- """
- Calling L{_InputStream.read} with no arguments returns the entire input
- stream.
- """
- bytes = "some bytes are here"
- d = self._renderAndReturnReaderResult(lambda input: input.read(), bytes)
- d.addCallback(self.assertEqual, bytes)
- return d
-
-
- def test_readSome(self):
- """
- Calling L{_InputStream.read} with an integer returns that many bytes
- from the input stream, as long as it is less than or equal to the total
- number of bytes available.
- """
- bytes = "hello, world."
- d = self._renderAndReturnReaderResult(lambda input: input.read(3), bytes)
- d.addCallback(self.assertEqual, "hel")
- return d
-
-
- def test_readMoreThan(self):
- """
- Calling L{_InputStream.read} with an integer that is greater than the
- total number of bytes in the input stream returns all bytes in the
- input stream.
- """
- bytes = "some bytes are here"
- d = self._renderAndReturnReaderResult(
- lambda input: input.read(len(bytes) + 3), bytes)
- d.addCallback(self.assertEqual, bytes)
- return d
-
-
- def test_readTwice(self):
- """
- Calling L{_InputStream.read} a second time returns bytes starting from
- the position after the last byte returned by the previous read.
- """
- bytes = "some bytes, hello"
- def read(input):
- input.read(3)
- return input.read()
- d = self._renderAndReturnReaderResult(read, bytes)
- d.addCallback(self.assertEqual, bytes[3:])
- return d
-
-
- def test_readNone(self):
- """
- Calling L{_InputStream.read} with C{None} as an argument returns all
- bytes in the input stream.
- """
- bytes = "the entire stream"
- d = self._renderAndReturnReaderResult(
- lambda input: input.read(None), bytes)
- d.addCallback(self.assertEqual, bytes)
- return d
-
-
- def test_readNegative(self):
- """
- Calling L{_InputStream.read} with a negative integer as an argument
- returns all bytes in the input stream.
- """
- bytes = "all of the input"
- d = self._renderAndReturnReaderResult(
- lambda input: input.read(-1), bytes)
- d.addCallback(self.assertEqual, bytes)
- return d
-
-
- def test_readline(self):
- """
- Calling L{_InputStream.readline} with no argument returns one line from
- the input stream.
- """
- bytes = "hello\nworld"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readline(), bytes)
- d.addCallback(self.assertEqual, "hello\n")
- return d
-
-
- def test_readlineSome(self):
- """
- Calling L{_InputStream.readline} with an integer returns at most that
- many bytes, even if it is not enough to make up a complete line.
-
- COMPATIBILITY NOTE: the size argument is excluded from the WSGI
- specification, but is provided here anyhow, because useful libraries
- such as python stdlib's cgi.py assume their input file-like-object
- supports readline with a size argument. If you use it, be aware your
- application may not be portable to other conformant WSGI servers.
- """
- bytes = "goodbye\nworld"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readline(3), bytes)
- d.addCallback(self.assertEqual, "goo")
- return d
-
-
- def test_readlineMoreThan(self):
- """
- Calling L{_InputStream.readline} with an integer which is greater than
- the number of bytes in the next line returns only the next line.
- """
- bytes = "some lines\nof text"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readline(20), bytes)
- d.addCallback(self.assertEqual, "some lines\n")
- return d
-
-
- def test_readlineTwice(self):
- """
- Calling L{_InputStream.readline} a second time returns the line
- following the line returned by the first call.
- """
- bytes = "first line\nsecond line\nlast line"
- def readline(input):
- input.readline()
- return input.readline()
- d = self._renderAndReturnReaderResult(readline, bytes)
- d.addCallback(self.assertEqual, "second line\n")
- return d
-
-
- def test_readlineNone(self):
- """
- Calling L{_InputStream.readline} with C{None} as an argument returns
- one line from the input stream.
- """
- bytes = "this is one line\nthis is another line"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readline(None), bytes)
- d.addCallback(self.assertEqual, "this is one line\n")
- return d
-
-
- def test_readlineNegative(self):
- """
- Calling L{_InputStream.readline} with a negative integer as an argument
- returns one line from the input stream.
- """
- bytes = "input stream line one\nline two"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readline(-1), bytes)
- d.addCallback(self.assertEqual, "input stream line one\n")
- return d
-
-
- def test_readlines(self):
- """
- Calling L{_InputStream.readlines} with no arguments returns a list of
- all lines from the input stream.
- """
- bytes = "alice\nbob\ncarol"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readlines(), bytes)
- d.addCallback(self.assertEqual, ["alice\n", "bob\n", "carol"])
- return d
-
-
- def test_readlinesSome(self):
- """
- Calling L{_InputStream.readlines} with an integer as an argument
- returns a list of lines from the input stream with the argument serving
- as an approximate bound on the total number of bytes to read.
- """
- bytes = "123\n456\n789\n0"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readlines(5), bytes)
- def cbLines(lines):
- # Make sure we got enough lines to make 5 bytes. Anything beyond
- # that is fine too.
- self.assertEqual(lines[:2], ["123\n", "456\n"])
- d.addCallback(cbLines)
- return d
-
-
- def test_readlinesMoreThan(self):
- """
- Calling L{_InputStream.readlines} with an integer which is greater than
- the total number of bytes in the input stream returns a list of all
- lines from the input.
- """
- bytes = "one potato\ntwo potato\nthree potato"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readlines(100), bytes)
- d.addCallback(
- self.assertEqual,
- ["one potato\n", "two potato\n", "three potato"])
- return d
-
-
- def test_readlinesAfterRead(self):
- """
- Calling L{_InputStream.readlines} after a call to L{_InputStream.read}
- returns lines starting at the byte after the last byte returned by the
- C{read} call.
- """
- bytes = "hello\nworld\nfoo"
- def readlines(input):
- input.read(7)
- return input.readlines()
- d = self._renderAndReturnReaderResult(readlines, bytes)
- d.addCallback(self.assertEqual, ["orld\n", "foo"])
- return d
-
-
- def test_readlinesNone(self):
- """
- Calling L{_InputStream.readlines} with C{None} as an argument returns
- all lines from the input.
- """
- bytes = "one fish\ntwo fish\n"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readlines(None), bytes)
- d.addCallback(self.assertEqual, ["one fish\n", "two fish\n"])
- return d
-
-
- def test_readlinesNegative(self):
- """
- Calling L{_InputStream.readlines} with a negative integer as an
- argument returns a list of all lines from the input.
- """
- bytes = "red fish\nblue fish\n"
- d = self._renderAndReturnReaderResult(
- lambda input: input.readlines(-1), bytes)
- d.addCallback(self.assertEqual, ["red fish\n", "blue fish\n"])
- return d
-
-
- def test_iterable(self):
- """
- Iterating over L{_InputStream} produces lines from the input stream.
- """
- bytes = "green eggs\nand ham\n"
- d = self._renderAndReturnReaderResult(lambda input: list(input), bytes)
- d.addCallback(self.assertEqual, ["green eggs\n", "and ham\n"])
- return d
-
-
- def test_iterableAfterRead(self):
- """
- Iterating over L{_InputStream} after calling L{_InputStream.read}
- produces lines from the input stream starting from the first byte after
- the last byte returned by the C{read} call.
- """
- bytes = "green eggs\nand ham\n"
- def iterate(input):
- input.read(3)
- return list(input)
- d = self._renderAndReturnReaderResult(iterate, bytes)
- d.addCallback(self.assertEqual, ["en eggs\n", "and ham\n"])
- return d
-
-
-
-class InputStreamStringIOTests(InputStreamTestMixin, TestCase):
- """
- Tests for L{_InputStream} when it is wrapped around a L{StringIO.StringIO}.
- """
- def getFileType(self):
- return StringIO.StringIO
-
-
-
-class InputStreamCStringIOTests(InputStreamTestMixin, TestCase):
- """
- Tests for L{_InputStream} when it is wrapped around a
- L{cStringIO.StringIO}.
- """
- def getFileType(self):
- return cStringIO.StringIO
-
-
-
-class InputStreamTemporaryFileTests(InputStreamTestMixin, TestCase):
- """
- Tests for L{_InputStream} when it is wrapped around a L{tempfile.TemporaryFile}.
- """
- def getFileType(self):
- return tempfile.TemporaryFile
-
-
-
-class StartResponseTests(WSGITestsMixin, TestCase):
- """
- Tests for the I{start_response} parameter passed to the application object
- by L{WSGIResource}.
- """
- def test_status(self):
- """
- The response status passed to the I{start_response} callable is written
- as the status of the response to the request.
- """
- channel = DummyChannel()
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('107 Strange message', [])
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertTrue(
- channel.transport.written.getvalue().startswith(
- 'HTTP/1.1 107 Strange message'))
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def _headersTest(self, appHeaders, expectedHeaders):
- """
- Verify that if the response headers given by C{appHeaders} are passed
- to the I{start_response} callable, then the response header lines given
- by C{expectedHeaders} plus I{Server} and I{Date} header lines are
- included in the response.
- """
- # Make the Date header value deterministic
- self.patch(http, 'datetimeToString', lambda: 'Tuesday')
-
- channel = DummyChannel()
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', appHeaders)
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- response = channel.transport.written.getvalue()
- headers, rest = response.split('\r\n\r\n', 1)
- headerLines = headers.split('\r\n')[1:]
- headerLines.sort()
- allExpectedHeaders = expectedHeaders + [
- 'Date: Tuesday',
- 'Server: ' + version,
- 'Transfer-Encoding: chunked']
- allExpectedHeaders.sort()
- self.assertEqual(headerLines, allExpectedHeaders)
-
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
- return d
-
-
- def test_headers(self):
- """
- The headers passed to the I{start_response} callable are included in
- the response as are the required I{Date} and I{Server} headers and the
- necessary connection (hop to hop) header I{Transfer-Encoding}.
- """
- return self._headersTest(
- [('foo', 'bar'), ('baz', 'quux')],
- ['Baz: quux', 'Foo: bar'])
-
-
- def test_applicationProvidedContentType(self):
- """
- If I{Content-Type} is included in the headers passed to the
- I{start_response} callable, one I{Content-Type} header is included in
- the response.
- """
- return self._headersTest(
- [('content-type', 'monkeys are great')],
- ['Content-Type: monkeys are great'])
-
-
- def test_applicationProvidedServerAndDate(self):
- """
- If either I{Server} or I{Date} is included in the headers passed to the
- I{start_response} callable, they are disregarded.
- """
- return self._headersTest(
- [('server', 'foo'), ('Server', 'foo'),
- ('date', 'bar'), ('dATE', 'bar')],
- [])
-
-
- def test_delayedUntilReturn(self):
- """
- Nothing is written in response to a request when the I{start_response}
- callable is invoked. If the iterator returned by the application
- object produces only empty strings, the response is written after the
- last element is produced.
- """
- channel = DummyChannel()
-
- intermediateValues = []
- def record():
- intermediateValues.append(channel.transport.written.getvalue())
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [('foo', 'bar'), ('baz', 'quux')])
- yield ''
- record()
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertEqual(intermediateValues, [''])
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_delayedUntilContent(self):
- """
- Nothing is written in response to a request when the I{start_response}
- callable is invoked. Once a non-empty string has been produced by the
- iterator returned by the application object, the response status and
- headers are written.
- """
- channel = DummyChannel()
-
- intermediateValues = []
- def record():
- intermediateValues.append(channel.transport.written.getvalue())
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [('foo', 'bar')])
- yield ''
- record()
- yield 'foo'
- record()
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertFalse(intermediateValues[0])
- self.assertTrue(intermediateValues[1])
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_content(self):
- """
- Content produced by the iterator returned by the application object is
- written to the request as it is produced.
- """
- channel = DummyChannel()
-
- intermediateValues = []
- def record():
- intermediateValues.append(channel.transport.written.getvalue())
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [('content-length', '6')])
- yield 'foo'
- record()
- yield 'bar'
- record()
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertEqual(
- self.getContentFromResponse(intermediateValues[0]),
- 'foo')
- self.assertEqual(
- self.getContentFromResponse(intermediateValues[1]),
- 'foobar')
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_multipleStartResponse(self):
- """
- If the I{start_response} callable is invoked multiple times before a
- data for the response body is produced, the values from the last call
- are used.
- """
- channel = DummyChannel()
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('100 Foo', [])
- startResponse('200 Bar', [])
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertTrue(
- channel.transport.written.getvalue().startswith(
- 'HTTP/1.1 200 Bar\r\n'))
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_startResponseWithException(self):
- """
- If the I{start_response} callable is invoked with a third positional
- argument before the status and headers have been written to the
- response, the status and headers become the newly supplied values.
- """
- channel = DummyChannel()
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('100 Foo', [], (Exception, Exception("foo"), None))
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertTrue(
- channel.transport.written.getvalue().startswith(
- 'HTTP/1.1 100 Foo\r\n'))
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_startResponseWithExceptionTooLate(self):
- """
- If the I{start_response} callable is invoked with a third positional
- argument after the status and headers have been written to the
- response, the supplied I{exc_info} values are re-raised to the
- application.
- """
- channel = DummyChannel()
-
- class SomeException(Exception):
- pass
-
- try:
- raise SomeException()
- except:
- excInfo = exc_info()
-
- reraised = []
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [])
- yield 'foo'
- try:
- startResponse('500 ERR', [], excInfo)
- except:
- reraised.append(exc_info())
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertTrue(
- channel.transport.written.getvalue().startswith(
- 'HTTP/1.1 200 OK\r\n'))
- self.assertEqual(reraised[0][0], excInfo[0])
- self.assertEqual(reraised[0][1], excInfo[1])
- self.assertEqual(reraised[0][2].tb_next, excInfo[2])
-
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_write(self):
- """
- I{start_response} returns the I{write} callable which can be used to
- write bytes to the response body without buffering.
- """
- channel = DummyChannel()
-
- intermediateValues = []
- def record():
- intermediateValues.append(channel.transport.written.getvalue())
-
- def applicationFactory():
- def application(environ, startResponse):
- write = startResponse('100 Foo', [('content-length', '6')])
- write('foo')
- record()
- write('bar')
- record()
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertEqual(
- self.getContentFromResponse(intermediateValues[0]),
- 'foo')
- self.assertEqual(
- self.getContentFromResponse(intermediateValues[1]),
- 'foobar')
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
-
-class ApplicationTests(WSGITestsMixin, TestCase):
- """
- Tests for things which are done to the application object and the iterator
- it returns.
- """
- def enableThreads(self):
- self.reactor = reactor
- self.threadpool = ThreadPool()
- self.threadpool.start()
- self.addCleanup(self.threadpool.stop)
-
-
- def test_close(self):
- """
- If the application object returns an iterator which also has a I{close}
- method, that method is called after iteration is complete.
- """
- channel = DummyChannel()
-
- class Result:
- def __init__(self):
- self.open = True
-
- def __iter__(self):
- for i in range(3):
- if self.open:
- yield str(i)
-
- def close(self):
- self.open = False
-
- result = Result()
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [('content-length', '3')])
- return result
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertEqual(
- self.getContentFromResponse(
- channel.transport.written.getvalue()),
- '012')
- self.assertFalse(result.open)
- d.addCallback(cbRendered)
-
- self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''])
-
- return d
-
-
- def test_applicationCalledInThread(self):
- """
- The application object is invoked and iterated in a thread which is not
- the reactor thread.
- """
- self.enableThreads()
- invoked = []
-
- def applicationFactory():
- def application(environ, startResponse):
- def result():
- for i in range(3):
- invoked.append(get_ident())
- yield str(i)
- invoked.append(get_ident())
- startResponse('200 OK', [('content-length', '3')])
- return result()
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- self.assertNotIn(get_ident(), invoked)
- self.assertEqual(len(set(invoked)), 1)
- d.addCallback(cbRendered)
-
- self.lowLevelRender(
- requestFactory, applicationFactory,
- DummyChannel, 'GET', '1.1', [], [''])
-
- return d
-
-
- def test_writeCalledFromThread(self):
- """
- The I{write} callable returned by I{start_response} calls the request's
- C{write} method in the reactor thread.
- """
- self.enableThreads()
- invoked = []
-
- class ThreadVerifier(Request):
- def write(self, bytes):
- invoked.append(get_ident())
- return Request.write(self, bytes)
-
- def applicationFactory():
- def application(environ, startResponse):
- write = startResponse('200 OK', [])
- write('foo')
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory(ThreadVerifier)
- def cbRendered(ignored):
- self.assertEqual(set(invoked), set([get_ident()]))
- d.addCallback(cbRendered)
-
- self.lowLevelRender(
- requestFactory, applicationFactory, DummyChannel,
- 'GET', '1.1', [], [''])
-
- return d
-
-
- def test_iteratedValuesWrittenFromThread(self):
- """
- Strings produced by the iterator returned by the application object are
- written to the request in the reactor thread.
- """
- self.enableThreads()
- invoked = []
-
- class ThreadVerifier(Request):
- def write(self, bytes):
- invoked.append(get_ident())
- return Request.write(self, bytes)
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [])
- yield 'foo'
- return application
-
- d, requestFactory = self.requestFactoryFactory(ThreadVerifier)
- def cbRendered(ignored):
- self.assertEqual(set(invoked), set([get_ident()]))
- d.addCallback(cbRendered)
-
- self.lowLevelRender(
- requestFactory, applicationFactory, DummyChannel,
- 'GET', '1.1', [], [''])
-
- return d
-
-
- def test_statusWrittenFromThread(self):
- """
- The response status is set on the request object in the reactor thread.
- """
- self.enableThreads()
- invoked = []
-
- class ThreadVerifier(Request):
- def setResponseCode(self, code, message):
- invoked.append(get_ident())
- return Request.setResponseCode(self, code, message)
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [])
- return iter(())
- return application
-
- d, requestFactory = self.requestFactoryFactory(ThreadVerifier)
- def cbRendered(ignored):
- self.assertEqual(set(invoked), set([get_ident()]))
- d.addCallback(cbRendered)
-
- self.lowLevelRender(
- requestFactory, applicationFactory, DummyChannel,
- 'GET', '1.1', [], [''])
-
- return d
-
-
- def test_connectionClosedDuringIteration(self):
- """
- If the request connection is lost while the application object is being
- iterated, iteration is stopped.
- """
- class UnreliableConnection(Request):
- """
- This is a request which pretends its connection is lost immediately
- after the first write is done to it.
- """
- def write(self, bytes):
- self.connectionLost(Failure(ConnectionLost("No more connection")))
-
- self.badIter = False
- def appIter():
- yield "foo"
- self.badIter = True
- raise Exception("Should not have gotten here")
-
- def applicationFactory():
- def application(environ, startResponse):
- startResponse('200 OK', [])
- return appIter()
- return application
-
- d, requestFactory = self.requestFactoryFactory(UnreliableConnection)
- def cbRendered(ignored):
- self.assertFalse(self.badIter, "Should not have resumed iteration")
- d.addCallback(cbRendered)
-
- self.lowLevelRender(
- requestFactory, applicationFactory, DummyChannel,
- 'GET', '1.1', [], [''])
-
- return self.assertFailure(d, ConnectionLost)
-
-
- def _internalServerErrorTest(self, application):
- channel = DummyChannel()
-
- def applicationFactory():
- return application
-
- d, requestFactory = self.requestFactoryFactory()
- def cbRendered(ignored):
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
-
- self.assertTrue(
- channel.transport.written.getvalue().startswith(
- 'HTTP/1.1 500 Internal Server Error'))
- d.addCallback(cbRendered)
-
- request = self.lowLevelRender(
- requestFactory, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- return d
-
-
- def test_applicationExceptionBeforeStartResponse(self):
- """
- If the application raises an exception before calling I{start_response}
- then the response status is I{500} and the exception is logged.
- """
- def application(environ, startResponse):
- raise RuntimeError("This application had some error.")
- return self._internalServerErrorTest(application)
-
-
- def test_applicationExceptionAfterStartResponse(self):
- """
- If the application calls I{start_response} but then raises an exception
- before any data is written to the response then the response status is
- I{500} and the exception is logged.
- """
- def application(environ, startResponse):
- startResponse('200 OK', [])
- raise RuntimeError("This application had some error.")
- return self._internalServerErrorTest(application)
-
-
- def _connectionClosedTest(self, application, responseContent):
- channel = DummyChannel()
-
- def applicationFactory():
- return application
-
- d, requestFactory = self.requestFactoryFactory()
-
- # Capture the request so we can disconnect it later on.
- requests = []
- def requestFactoryWrapper(*a, **kw):
- requests.append(requestFactory(*a, **kw))
- return requests[-1]
-
- def ebRendered(ignored):
- errors = self.flushLoggedErrors(RuntimeError)
- self.assertEqual(len(errors), 1)
-
- response = channel.transport.written.getvalue()
- self.assertTrue(response.startswith('HTTP/1.1 200 OK'))
- # Chunked transfer-encoding makes this a little messy.
- self.assertIn(responseContent, response)
- d.addErrback(ebRendered)
-
- request = self.lowLevelRender(
- requestFactoryWrapper, applicationFactory,
- lambda: channel, 'GET', '1.1', [], [''], None, [])
-
- # By now the connection should be closed.
- self.assertTrue(channel.transport.disconnected)
- # Give it a little push to go the rest of the way.
- requests[0].connectionLost(Failure(ConnectionLost("All gone")))
-
- return d
-
-
- def test_applicationExceptionAfterWrite(self):
- """
- If the application raises an exception after the response status has
- already been sent then the connection is closed and the exception is
- logged.
- """
- responseContent = (
- 'Some bytes, triggering the server to start sending the response')
-
- def application(environ, startResponse):
- startResponse('200 OK', [])
- yield responseContent
- raise RuntimeError("This application had some error.")
- return self._connectionClosedTest(application, responseContent)
-
-
- def test_applicationCloseException(self):
- """
- If the application returns a closeable iterator and the C{close} method
- raises an exception when called then the connection is still closed and
- the exception is logged.
- """
- responseContent = 'foo'
-
- class Application(object):
- def __init__(self, environ, startResponse):
- startResponse('200 OK', [])
-
- def __iter__(self):
- yield responseContent
-
- def close(self):
- raise RuntimeError("This application had some error.")
-
- return self._connectionClosedTest(Application, responseContent)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xml.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xml.py
deleted file mode 100755
index 513a9432..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xml.py
+++ /dev/null
@@ -1,1105 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_xml -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Some fairly inadequate testcases for Twisted XML support.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.web import sux
-from twisted.web import microdom
-from twisted.web import domhelpers
-
-
-class Sux0r(sux.XMLParser):
- def __init__(self):
- self.tokens = []
-
- def getTagStarts(self):
- return [token for token in self.tokens if token[0] == 'start']
-
- def gotTagStart(self, name, attrs):
- self.tokens.append(("start", name, attrs))
-
- def gotText(self, text):
- self.tokens.append(("text", text))
-
-class SUXTest(TestCase):
-
- def testBork(self):
- s = "<bork><bork><bork>"
- ms = Sux0r()
- ms.connectionMade()
- ms.dataReceived(s)
- self.assertEqual(len(ms.getTagStarts()),3)
-
-
-class MicroDOMTest(TestCase):
-
- def test_leadingTextDropping(self):
- """
- Make sure that if there's no top-level node lenient-mode won't
- drop leading text that's outside of any elements.
- """
- s = "Hi orders! <br>Well. <br>"
- d = microdom.parseString(s, beExtremelyLenient=True)
- self.assertEqual(d.firstChild().toxml(),
- '<html>Hi orders! <br />Well. <br /></html>')
-
- def test_trailingTextDropping(self):
- """
- Ensure that no *trailing* text in a mal-formed
- no-top-level-element document(s) will not be dropped.
- """
- s = "<br>Hi orders!"
- d = microdom.parseString(s, beExtremelyLenient=True)
- self.assertEqual(d.firstChild().toxml(),
- '<html><br />Hi orders!</html>')
-
-
- def test_noTags(self):
- """
- A string with nothing that looks like a tag at all should just
- be parsed as body text.
- """
- s = "Hi orders!"
- d = microdom.parseString(s, beExtremelyLenient=True)
- self.assertEqual(d.firstChild().toxml(),
- "<html>Hi orders!</html>")
-
-
- def test_surroundingCrap(self):
- """
- If a document is surrounded by non-xml text, the text should
- be remain in the XML.
- """
- s = "Hi<br> orders!"
- d = microdom.parseString(s, beExtremelyLenient=True)
- self.assertEqual(d.firstChild().toxml(),
- "<html>Hi<br /> orders!</html>")
-
-
- def testCaseSensitiveSoonCloser(self):
- s = """
- <HTML><BODY>
- <P ALIGN="CENTER">
- <A HREF="http://www.apache.org/"><IMG SRC="/icons/apache_pb.gif"></A>
- </P>
-
- <P>
- This is an insane set of text nodes that should NOT be gathered under
- the A tag above.
- </P>
- </BODY></HTML>
- """
- d = microdom.parseString(s, beExtremelyLenient=1)
- l = domhelpers.findNodesNamed(d.documentElement, 'a')
- n = domhelpers.gatherTextNodes(l[0],1).replace('&nbsp;',' ')
- self.assertEqual(n.find('insane'), -1)
-
-
- def test_lenientParenting(self):
- """
- Test that C{parentNode} attributes are set to meaningful values when
- we are parsing HTML that lacks a root node.
- """
- # Spare the rod, ruin the child.
- s = "<br/><br/>"
- d = microdom.parseString(s, beExtremelyLenient=1)
- self.assertIdentical(d.documentElement,
- d.documentElement.firstChild().parentNode)
-
-
- def test_lenientParentSingle(self):
- """
- Test that the C{parentNode} attribute is set to a meaningful value
- when we parse an HTML document that has a non-Element root node.
- """
- s = "Hello"
- d = microdom.parseString(s, beExtremelyLenient=1)
- self.assertIdentical(d.documentElement,
- d.documentElement.firstChild().parentNode)
-
-
- def testUnEntities(self):
- s = """
- <HTML>
- This HTML goes between Stupid <=CrAzY!=> Dumb.
- </HTML>
- """
- d = microdom.parseString(s, beExtremelyLenient=1)
- n = domhelpers.gatherTextNodes(d)
- self.assertNotEquals(n.find('>'), -1)
-
- def testEmptyError(self):
- self.assertRaises(sux.ParseError, microdom.parseString, "")
-
- def testTameDocument(self):
- s = """
- <test>
- <it>
- <is>
- <a>
- test
- </a>
- </is>
- </it>
- </test>
- """
- d = microdom.parseString(s)
- self.assertEqual(
- domhelpers.gatherTextNodes(d.documentElement).strip() ,'test')
-
- def testAwfulTagSoup(self):
- s = """
- <html>
- <head><title> I send you this message to have your advice!!!!</titl e
- </headd>
-
- <body bgcolor alink hlink vlink>
-
- <h1><BLINK>SALE</blINK> TWENTY MILLION EMAILS & FUR COAT NOW
- FREE WITH `ENLARGER'</h1>
-
- YES THIS WONDERFUL AWFER IS NOW HERER!!!
-
- <script LANGUAGE="javascript">
-function give_answers() {
-if (score < 70) {
-alert("I hate you");
-}}
- </script><a href=/foo.com/lalal name=foo>lalal</a>
- </body>
- </HTML>
- """
- d = microdom.parseString(s, beExtremelyLenient=1)
- l = domhelpers.findNodesNamed(d.documentElement, 'blink')
- self.assertEqual(len(l), 1)
-
- def testScriptLeniency(self):
- s = """
- <script>(foo < bar) and (bar > foo)</script>
- <script language="javascript">foo </scrip bar </script>
- <script src="foo">
- <script src="foo">baz</script>
- <script /><script></script>
- """
- d = microdom.parseString(s, beExtremelyLenient=1)
- self.assertEqual(d.firstChild().firstChild().firstChild().data,
- "(foo < bar) and (bar > foo)")
- self.assertEqual(
- d.firstChild().getElementsByTagName("script")[1].firstChild().data,
- "foo </scrip bar ")
-
- def testScriptLeniencyIntelligence(self):
- # if there is comment or CDATA in script, the autoquoting in bEL mode
- # should not happen
- s = """<script><!-- lalal --></script>"""
- self.assertEqual(
- microdom.parseString(s, beExtremelyLenient=1).firstChild().toxml(), s)
- s = """<script><![CDATA[lalal]]></script>"""
- self.assertEqual(
- microdom.parseString(s, beExtremelyLenient=1).firstChild().toxml(), s)
- s = """<script> // <![CDATA[
- lalal
- //]]></script>"""
- self.assertEqual(
- microdom.parseString(s, beExtremelyLenient=1).firstChild().toxml(), s)
-
- def testPreserveCase(self):
- s = '<eNcApSuLaTe><sUxor></sUxor><bOrk><w00T>TeXt</W00t></BoRk></EnCaPsUlAtE>'
- s2 = s.lower().replace('text', 'TeXt')
- # these are the only two option permutations that *can* parse the above
- d = microdom.parseString(s, caseInsensitive=1, preserveCase=1)
- d2 = microdom.parseString(s, caseInsensitive=1, preserveCase=0)
- # caseInsensitive=0 preserveCase=0 is not valid, it's converted to
- # caseInsensitive=0 preserveCase=1
- d3 = microdom.parseString(s2, caseInsensitive=0, preserveCase=1)
- d4 = microdom.parseString(s2, caseInsensitive=1, preserveCase=0)
- d5 = microdom.parseString(s2, caseInsensitive=1, preserveCase=1)
- # this is slightly contrived, toxml() doesn't need to be identical
- # for the documents to be equivalent (i.e. <b></b> to <b/>),
- # however this assertion tests preserving case for start and
- # end tags while still matching stuff like <bOrk></BoRk>
- self.assertEqual(d.documentElement.toxml(), s)
- self.assert_(d.isEqualToDocument(d2), "%r != %r" % (d.toxml(), d2.toxml()))
- self.assert_(d2.isEqualToDocument(d3), "%r != %r" % (d2.toxml(), d3.toxml()))
- # caseInsensitive=0 on the left, NOT perserveCase=1 on the right
- ## XXX THIS TEST IS TURNED OFF UNTIL SOMEONE WHO CARES ABOUT FIXING IT DOES
- #self.failIf(d3.isEqualToDocument(d2), "%r == %r" % (d3.toxml(), d2.toxml()))
- self.assert_(d3.isEqualToDocument(d4), "%r != %r" % (d3.toxml(), d4.toxml()))
- self.assert_(d4.isEqualToDocument(d5), "%r != %r" % (d4.toxml(), d5.toxml()))
-
- def testDifferentQuotes(self):
- s = '<test a="a" b=\'b\' />'
- d = microdom.parseString(s)
- e = d.documentElement
- self.assertEqual(e.getAttribute('a'), 'a')
- self.assertEqual(e.getAttribute('b'), 'b')
-
- def testLinebreaks(self):
- s = '<test \na="a"\n\tb="#b" />'
- d = microdom.parseString(s)
- e = d.documentElement
- self.assertEqual(e.getAttribute('a'), 'a')
- self.assertEqual(e.getAttribute('b'), '#b')
-
- def testMismatchedTags(self):
- for s in '<test>', '<test> </tset>', '</test>':
- self.assertRaises(microdom.MismatchedTags, microdom.parseString, s)
-
- def testComment(self):
- s = "<bar><!--<foo />--></bar>"
- d = microdom.parseString(s)
- e = d.documentElement
- self.assertEqual(e.nodeName, "bar")
- c = e.childNodes[0]
- self.assert_(isinstance(c, microdom.Comment))
- self.assertEqual(c.value, "<foo />")
- c2 = c.cloneNode()
- self.assert_(c is not c2)
- self.assertEqual(c2.toxml(), "<!--<foo />-->")
-
- def testText(self):
- d = microdom.parseString("<bar>xxxx</bar>").documentElement
- text = d.childNodes[0]
- self.assert_(isinstance(text, microdom.Text))
- self.assertEqual(text.value, "xxxx")
- clone = text.cloneNode()
- self.assert_(clone is not text)
- self.assertEqual(clone.toxml(), "xxxx")
-
- def testEntities(self):
- nodes = microdom.parseString("<b>&amp;&#12AB;</b>").documentElement.childNodes
- self.assertEqual(len(nodes), 2)
- self.assertEqual(nodes[0].data, "&amp;")
- self.assertEqual(nodes[1].data, "&#12AB;")
- self.assertEqual(nodes[0].cloneNode().toxml(), "&amp;")
- for n in nodes:
- self.assert_(isinstance(n, microdom.EntityReference))
-
- def testCData(self):
- s = '<x><![CDATA[</x>\r\n & foo]]></x>'
- cdata = microdom.parseString(s).documentElement.childNodes[0]
- self.assert_(isinstance(cdata, microdom.CDATASection))
- self.assertEqual(cdata.data, "</x>\r\n & foo")
- self.assertEqual(cdata.cloneNode().toxml(), "<![CDATA[</x>\r\n & foo]]>")
-
- def testSingletons(self):
- s = "<foo><b/><b /><b\n/></foo>"
- s2 = "<foo><b/><b/><b/></foo>"
- nodes = microdom.parseString(s).documentElement.childNodes
- nodes2 = microdom.parseString(s2).documentElement.childNodes
- self.assertEqual(len(nodes), 3)
- for (n, n2) in zip(nodes, nodes2):
- self.assert_(isinstance(n, microdom.Element))
- self.assertEqual(n.nodeName, "b")
- self.assert_(n.isEqualToNode(n2))
-
- def testAttributes(self):
- s = '<foo a="b" />'
- node = microdom.parseString(s).documentElement
-
- self.assertEqual(node.getAttribute("a"), "b")
- self.assertEqual(node.getAttribute("c"), None)
- self.assert_(node.hasAttribute("a"))
- self.assert_(not node.hasAttribute("c"))
- a = node.getAttributeNode("a")
- self.assertEqual(a.value, "b")
-
- node.setAttribute("foo", "bar")
- self.assertEqual(node.getAttribute("foo"), "bar")
-
- def testChildren(self):
- s = "<foo><bar /><baz /><bax>foo</bax></foo>"
- d = microdom.parseString(s).documentElement
- self.assertEqual([n.nodeName for n in d.childNodes], ["bar", "baz", "bax"])
- self.assertEqual(d.lastChild().nodeName, "bax")
- self.assertEqual(d.firstChild().nodeName, "bar")
- self.assert_(d.hasChildNodes())
- self.assert_(not d.firstChild().hasChildNodes())
-
- def testMutate(self):
- s = "<foo />"
- s1 = '<foo a="b"><bar/><foo/></foo>'
- s2 = '<foo a="b">foo</foo>'
- d = microdom.parseString(s).documentElement
- d1 = microdom.parseString(s1).documentElement
- d2 = microdom.parseString(s2).documentElement
-
- d.appendChild(d.cloneNode())
- d.setAttribute("a", "b")
- child = d.childNodes[0]
- self.assertEqual(child.getAttribute("a"), None)
- self.assertEqual(child.nodeName, "foo")
-
- d.insertBefore(microdom.Element("bar"), child)
- self.assertEqual(d.childNodes[0].nodeName, "bar")
- self.assertEqual(d.childNodes[1], child)
- for n in d.childNodes:
- self.assertEqual(n.parentNode, d)
- self.assert_(d.isEqualToNode(d1))
-
- d.removeChild(child)
- self.assertEqual(len(d.childNodes), 1)
- self.assertEqual(d.childNodes[0].nodeName, "bar")
-
- t = microdom.Text("foo")
- d.replaceChild(t, d.firstChild())
- self.assertEqual(d.firstChild(), t)
- self.assert_(d.isEqualToNode(d2))
-
-
- def test_replaceNonChild(self):
- """
- L{Node.replaceChild} raises L{ValueError} if the node given to be
- replaced is not a child of the node C{replaceChild} is called on.
- """
- parent = microdom.parseString('<foo />')
- orphan = microdom.parseString('<bar />')
- replacement = microdom.parseString('<baz />')
-
- self.assertRaises(
- ValueError, parent.replaceChild, replacement, orphan)
-
-
- def testSearch(self):
- s = "<foo><bar id='me' /><baz><foo /></baz></foo>"
- s2 = "<fOo><bAr id='me' /><bAz><fOO /></bAz></fOo>"
- d = microdom.parseString(s)
- d2 = microdom.parseString(s2, caseInsensitive=0, preserveCase=1)
- d3 = microdom.parseString(s2, caseInsensitive=1, preserveCase=1)
-
- root = d.documentElement
- self.assertEqual(root.firstChild(), d.getElementById('me'))
- self.assertEqual(d.getElementsByTagName("foo"),
- [root, root.lastChild().firstChild()])
-
- root = d2.documentElement
- self.assertEqual(root.firstChild(), d2.getElementById('me'))
- self.assertEqual(d2.getElementsByTagName('fOo'), [root])
- self.assertEqual(d2.getElementsByTagName('fOO'),
- [root.lastChild().firstChild()])
- self.assertEqual(d2.getElementsByTagName('foo'), [])
-
- root = d3.documentElement
- self.assertEqual(root.firstChild(), d3.getElementById('me'))
- self.assertEqual(d3.getElementsByTagName('FOO'),
- [root, root.lastChild().firstChild()])
- self.assertEqual(d3.getElementsByTagName('fOo'),
- [root, root.lastChild().firstChild()])
-
- def testDoctype(self):
- s = ('<?xml version="1.0"?>'
- '<!DOCTYPE foo PUBLIC "baz" "http://www.example.com/example.dtd">'
- '<foo></foo>')
- s2 = '<foo/>'
- d = microdom.parseString(s)
- d2 = microdom.parseString(s2)
- self.assertEqual(d.doctype,
- 'foo PUBLIC "baz" "http://www.example.com/example.dtd"')
- self.assertEqual(d.toxml(), s)
- self.failIf(d.isEqualToDocument(d2))
- self.failUnless(d.documentElement.isEqualToNode(d2.documentElement))
-
- samples = [("<img/>", "<img />"),
- ("<foo A='b'>x</foo>", '<foo A="b">x</foo>'),
- ("<foo><BAR /></foo>", "<foo><BAR></BAR></foo>"),
- ("<foo>hello there &amp; yoyoy</foo>",
- "<foo>hello there &amp; yoyoy</foo>"),
- ]
-
- def testOutput(self):
- for s, out in self.samples:
- d = microdom.parseString(s, caseInsensitive=0)
- d2 = microdom.parseString(out, caseInsensitive=0)
- testOut = d.documentElement.toxml()
- self.assertEqual(out, testOut)
- self.assert_(d.isEqualToDocument(d2))
-
- def testErrors(self):
- for s in ["<foo>&am</foo>", "<foo", "<f>&</f>", "<() />"]:
- self.assertRaises(Exception, microdom.parseString, s)
-
- def testCaseInsensitive(self):
- s = "<foo a='b'><BAx>x</bax></FOO>"
- s2 = '<foo a="b"><bax>x</bax></foo>'
- s3 = "<FOO a='b'><BAx>x</BAx></FOO>"
- s4 = "<foo A='b'>x</foo>"
- d = microdom.parseString(s)
- d2 = microdom.parseString(s2)
- d3 = microdom.parseString(s3, caseInsensitive=1)
- d4 = microdom.parseString(s4, caseInsensitive=1, preserveCase=1)
- d5 = microdom.parseString(s4, caseInsensitive=1, preserveCase=0)
- d6 = microdom.parseString(s4, caseInsensitive=0, preserveCase=0)
- out = microdom.parseString(s).documentElement.toxml()
- self.assertRaises(microdom.MismatchedTags, microdom.parseString,
- s, caseInsensitive=0)
- self.assertEqual(out, s2)
- self.failUnless(d.isEqualToDocument(d2))
- self.failUnless(d.isEqualToDocument(d3))
- self.failUnless(d4.documentElement.hasAttribute('a'))
- self.failIf(d6.documentElement.hasAttribute('a'))
- self.assertEqual(d4.documentElement.toxml(), '<foo A="b">x</foo>')
- self.assertEqual(d5.documentElement.toxml(), '<foo a="b">x</foo>')
- def testEatingWhitespace(self):
- s = """<hello>
- </hello>"""
- d = microdom.parseString(s)
- self.failUnless(not d.documentElement.hasChildNodes(),
- d.documentElement.childNodes)
- self.failUnless(d.isEqualToDocument(microdom.parseString('<hello></hello>')))
-
- def testLenientAmpersand(self):
- prefix = "<?xml version='1.0'?>"
- # we use <pre> so space will be preserved
- for i, o in [("&", "&amp;"),
- ("& ", "&amp; "),
- ("&amp;", "&amp;"),
- ("&hello monkey", "&amp;hello monkey")]:
- d = microdom.parseString("%s<pre>%s</pre>"
- % (prefix, i), beExtremelyLenient=1)
- self.assertEqual(d.documentElement.toxml(), "<pre>%s</pre>" % o)
- # non-space preserving
- d = microdom.parseString("<t>hello & there</t>", beExtremelyLenient=1)
- self.assertEqual(d.documentElement.toxml(), "<t>hello &amp; there</t>")
-
- def testInsensitiveLenient(self):
- # testing issue #537
- d = microdom.parseString(
- "<?xml version='1.0'?><bar><xA><y>c</Xa> <foo></bar>",
- beExtremelyLenient=1)
- self.assertEqual(d.documentElement.firstChild().toxml(), "<xa><y>c</y></xa>")
-
- def testLaterCloserSimple(self):
- s = "<ul><li>foo<li>bar<li>baz</ul>"
- d = microdom.parseString(s, beExtremelyLenient=1)
- expected = "<ul><li>foo</li><li>bar</li><li>baz</li></ul>"
- actual = d.documentElement.toxml()
- self.assertEqual(expected, actual)
-
- def testLaterCloserCaseInsensitive(self):
- s = "<DL><p><DT>foo<DD>bar</DL>"
- d = microdom.parseString(s, beExtremelyLenient=1)
- expected = "<dl><p></p><dt>foo</dt><dd>bar</dd></dl>"
- actual = d.documentElement.toxml()
- self.assertEqual(expected, actual)
-
- def testLaterCloserTable(self):
- s = ("<table>"
- "<tr><th>name<th>value<th>comment"
- "<tr><th>this<td>tag<td>soup"
- "<tr><th>must<td>be<td>handled"
- "</table>")
- expected = ("<table>"
- "<tr><th>name</th><th>value</th><th>comment</th></tr>"
- "<tr><th>this</th><td>tag</td><td>soup</td></tr>"
- "<tr><th>must</th><td>be</td><td>handled</td></tr>"
- "</table>")
- d = microdom.parseString(s, beExtremelyLenient=1)
- actual = d.documentElement.toxml()
- self.assertEqual(expected, actual)
- testLaterCloserTable.todo = "Table parsing needs to be fixed."
-
- def testLaterCloserDL(self):
- s = ("<dl>"
- "<dt>word<dd>definition"
- "<dt>word<dt>word<dd>definition<dd>definition"
- "</dl>")
- expected = ("<dl>"
- "<dt>word</dt><dd>definition</dd>"
- "<dt>word</dt><dt>word</dt><dd>definition</dd><dd>definition</dd>"
- "</dl>")
- d = microdom.parseString(s, beExtremelyLenient=1)
- actual = d.documentElement.toxml()
- self.assertEqual(expected, actual)
-
- def testLaterCloserDL2(self):
- s = ("<dl>"
- "<dt>word<dd>definition<p>more definition"
- "<dt>word"
- "</dl>")
- expected = ("<dl>"
- "<dt>word</dt><dd>definition<p>more definition</p></dd>"
- "<dt>word</dt>"
- "</dl>")
- d = microdom.parseString(s, beExtremelyLenient=1)
- actual = d.documentElement.toxml()
- self.assertEqual(expected, actual)
-
- testLaterCloserDL2.todo = "unclosed <p> messes it up."
-
- def testUnicodeTolerance(self):
- import struct
- s = '<foo><bar><baz /></bar></foo>'
- j =(u'<?xml version="1.0" encoding="UCS-2" ?>\r\n<JAPANESE>\r\n'
- u'<TITLE>\u5c02\u9580\u5bb6\u30ea\u30b9\u30c8 </TITLE></JAPANESE>')
- j2=('\xff\xfe<\x00?\x00x\x00m\x00l\x00 \x00v\x00e\x00r\x00s\x00i\x00o'
- '\x00n\x00=\x00"\x001\x00.\x000\x00"\x00 \x00e\x00n\x00c\x00o\x00d'
- '\x00i\x00n\x00g\x00=\x00"\x00U\x00C\x00S\x00-\x002\x00"\x00 \x00?'
- '\x00>\x00\r\x00\n\x00<\x00J\x00A\x00P\x00A\x00N\x00E\x00S\x00E'
- '\x00>\x00\r\x00\n\x00<\x00T\x00I\x00T\x00L\x00E\x00>\x00\x02\\'
- '\x80\x95\xb6[\xea0\xb90\xc80 \x00<\x00/\x00T\x00I\x00T\x00L\x00E'
- '\x00>\x00<\x00/\x00J\x00A\x00P\x00A\x00N\x00E\x00S\x00E\x00>\x00')
- def reverseBytes(s):
- fmt = str(len(s) // 2) + 'H'
- return struct.pack('<' + fmt, *struct.unpack('>' + fmt, s))
- urd = microdom.parseString(reverseBytes(s.encode('UTF-16')))
- ud = microdom.parseString(s.encode('UTF-16'))
- sd = microdom.parseString(s)
- self.assert_(ud.isEqualToDocument(sd))
- self.assert_(ud.isEqualToDocument(urd))
- ud = microdom.parseString(j)
- urd = microdom.parseString(reverseBytes(j2))
- sd = microdom.parseString(j2)
- self.assert_(ud.isEqualToDocument(sd))
- self.assert_(ud.isEqualToDocument(urd))
-
- # test that raw text still gets encoded
- # test that comments get encoded
- j3=microdom.parseString(u'<foo/>')
- hdr='<?xml version="1.0"?>'
- div=microdom.lmx().text(u'\u221a', raw=1).node
- de=j3.documentElement
- de.appendChild(div)
- de.appendChild(j3.createComment(u'\u221a'))
- self.assertEqual(j3.toxml(), hdr+
- u'<foo><div>\u221a</div><!--\u221a--></foo>'.encode('utf8'))
-
- def testNamedChildren(self):
- tests = {"<foo><bar /><bar unf='1' /><bar>asdfadsf</bar>"
- "<bam/></foo>" : 3,
- '<foo>asdf</foo>' : 0,
- '<foo><bar><bar></bar></bar></foo>' : 1,
- }
- for t in tests.keys():
- node = microdom.parseString(t).documentElement
- result = domhelpers.namedChildren(node, 'bar')
- self.assertEqual(len(result), tests[t])
- if result:
- self.assert_(hasattr(result[0], 'tagName'))
-
- def testCloneNode(self):
- s = '<foo a="b"><bax>x</bax></foo>'
- node = microdom.parseString(s).documentElement
- clone = node.cloneNode(deep=1)
- self.failIfEquals(node, clone)
- self.assertEqual(len(node.childNodes), len(clone.childNodes))
- c1, c2 = node.firstChild(), clone.firstChild()
- self.failIfEquals(c1, c2)
- self.assertEqual(len(c1.childNodes), len(c2.childNodes))
- self.failIfEquals(c1.firstChild(), c2.firstChild())
- self.assertEqual(s, clone.toxml())
- self.assertEqual(node.namespace, clone.namespace)
-
- def testCloneDocument(self):
- s = ('<?xml version="1.0"?>'
- '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
- '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><foo></foo>')
-
- node = microdom.parseString(s)
- clone = node.cloneNode(deep=1)
- self.failIfEquals(node, clone)
- self.assertEqual(len(node.childNodes), len(clone.childNodes))
- self.assertEqual(s, clone.toxml())
-
- self.failUnless(clone.isEqualToDocument(node))
- self.failUnless(node.isEqualToDocument(clone))
-
-
- def testLMX(self):
- n = microdom.Element("p")
- lmx = microdom.lmx(n)
- lmx.text("foo")
- b = lmx.b(a="c")
- b.foo()["z"] = "foo"
- b.foo()
- b.add("bar", c="y")
-
- s = '<p>foo<b a="c"><foo z="foo"></foo><foo></foo><bar c="y"></bar></b></p>'
- self.assertEqual(s, n.toxml())
-
- def testDict(self):
- n = microdom.Element("p")
- d = {n : 1} # will fail if Element is unhashable
-
- def testEscaping(self):
- # issue 590
- raw = "&'some \"stuff\"', <what up?>"
- cooked = "&amp;'some &quot;stuff&quot;', &lt;what up?&gt;"
- esc1 = microdom.escape(raw)
- self.assertEqual(esc1, cooked)
- self.assertEqual(microdom.unescape(esc1), raw)
-
- def testNamespaces(self):
- s = '''
- <x xmlns="base">
- <y />
- <y q="1" x:q="2" y:q="3" />
- <y:y xml:space="1">here is some space </y:y>
- <y:y />
- <x:y />
- </x>
- '''
- d = microdom.parseString(s)
- # at least make sure it doesn't traceback
- s2 = d.toprettyxml()
- self.assertEqual(d.documentElement.namespace,
- "base")
- self.assertEqual(d.documentElement.getElementsByTagName("y")[0].namespace,
- "base")
- self.assertEqual(
- d.documentElement.getElementsByTagName("y")[1].getAttributeNS('base','q'),
- '1')
-
- d2 = microdom.parseString(s2)
- self.assertEqual(d2.documentElement.namespace,
- "base")
- self.assertEqual(d2.documentElement.getElementsByTagName("y")[0].namespace,
- "base")
- self.assertEqual(
- d2.documentElement.getElementsByTagName("y")[1].getAttributeNS('base','q'),
- '1')
-
- def testNamespaceDelete(self):
- """
- Test that C{toxml} can support xml structures that remove namespaces.
- """
- s1 = ('<?xml version="1.0"?><html xmlns="http://www.w3.org/TR/REC-html40">'
- '<body xmlns=""></body></html>')
- s2 = microdom.parseString(s1).toxml()
- self.assertEqual(s1, s2)
-
- def testNamespaceInheritance(self):
- """
- Check that unspecified namespace is a thing separate from undefined
- namespace. This test added after discovering some weirdness in Lore.
- """
- # will only work if childNodes is mutated. not sure why.
- child = microdom.Element('ol')
- parent = microdom.Element('div', namespace='http://www.w3.org/1999/xhtml')
- parent.childNodes = [child]
- self.assertEqual(parent.toxml(),
- '<div xmlns="http://www.w3.org/1999/xhtml"><ol></ol></div>')
-
- def test_prefixedTags(self):
- """
- XML elements with a prefixed name as per upper level tag definition
- have a start-tag of C{"<prefix:tag>"} and an end-tag of
- C{"</prefix:tag>"}.
-
- Refer to U{http://www.w3.org/TR/xml-names/#ns-using} for details.
- """
- outerNamespace = "http://example.com/outer"
- innerNamespace = "http://example.com/inner"
-
- document = microdom.Document()
- # Create the root in one namespace. Microdom will probably make this
- # the default namespace.
- root = document.createElement("root", namespace=outerNamespace)
-
- # Give the root some prefixes to use.
- root.addPrefixes({innerNamespace: "inner"})
-
- # Append a child to the root from the namespace that prefix is bound
- # to.
- tag = document.createElement("tag", namespace=innerNamespace)
-
- # Give that tag a child too. This way we test rendering of tags with
- # children and without children.
- child = document.createElement("child", namespace=innerNamespace)
-
- tag.appendChild(child)
- root.appendChild(tag)
- document.appendChild(root)
-
- # ok, the xml should appear like this
- xmlOk = (
- '<?xml version="1.0"?>'
- '<root xmlns="http://example.com/outer" '
- 'xmlns:inner="http://example.com/inner">'
- '<inner:tag><inner:child></inner:child></inner:tag>'
- '</root>')
-
- xmlOut = document.toxml()
- self.assertEqual(xmlOut, xmlOk)
-
-
- def test_prefixPropagation(self):
- """
- Children of prefixed tags respect the default namespace at the point
- where they are rendered. Specifically, they are not influenced by the
- prefix of their parent as that prefix has no bearing on them.
-
- See U{http://www.w3.org/TR/xml-names/#scoping} for details.
-
- To further clarify the matter, the following::
-
- <root xmlns="http://example.com/ns/test">
- <mytag xmlns="http://example.com/ns/mytags">
- <mysubtag xmlns="http://example.com/ns/mytags">
- <element xmlns="http://example.com/ns/test"></element>
- </mysubtag>
- </mytag>
- </root>
-
- Should become this after all the namespace declarations have been
- I{moved up}::
-
- <root xmlns="http://example.com/ns/test"
- xmlns:mytags="http://example.com/ns/mytags">
- <mytags:mytag>
- <mytags:mysubtag>
- <element></element>
- </mytags:mysubtag>
- </mytags:mytag>
- </root>
- """
- outerNamespace = "http://example.com/outer"
- innerNamespace = "http://example.com/inner"
-
- document = microdom.Document()
- # creates a root element
- root = document.createElement("root", namespace=outerNamespace)
- document.appendChild(root)
-
- # Create a child with a specific namespace with a prefix bound to it.
- root.addPrefixes({innerNamespace: "inner"})
- mytag = document.createElement("mytag",namespace=innerNamespace)
- root.appendChild(mytag)
-
- # Create a child of that which has the outer namespace.
- mysubtag = document.createElement("mysubtag", namespace=outerNamespace)
- mytag.appendChild(mysubtag)
-
- xmlOk = (
- '<?xml version="1.0"?>'
- '<root xmlns="http://example.com/outer" '
- 'xmlns:inner="http://example.com/inner">'
- '<inner:mytag>'
- '<mysubtag></mysubtag>'
- '</inner:mytag>'
- '</root>'
- )
- xmlOut = document.toxml()
- self.assertEqual(xmlOut, xmlOk)
-
-
-
-class TestBrokenHTML(TestCase):
- """
- Tests for when microdom encounters very bad HTML and C{beExtremelyLenient}
- is enabled. These tests are inspired by some HTML generated in by a mailer,
- which breaks up very long lines by splitting them with '!\n '. The expected
- behaviour is loosely modelled on the way Firefox treats very bad HTML.
- """
-
- def checkParsed(self, input, expected, beExtremelyLenient=1):
- """
- Check that C{input}, when parsed, produces a DOM where the XML
- of the document element is equal to C{expected}.
- """
- output = microdom.parseString(input,
- beExtremelyLenient=beExtremelyLenient)
- self.assertEqual(output.documentElement.toxml(), expected)
-
-
- def test_brokenAttributeName(self):
- """
- Check that microdom does its best to handle broken attribute names.
- The important thing is that it doesn't raise an exception.
- """
- input = '<body><h1><div al!\n ign="center">Foo</div></h1></body>'
- expected = ('<body><h1><div ign="center" al="True">'
- 'Foo</div></h1></body>')
- self.checkParsed(input, expected)
-
-
- def test_brokenAttributeValue(self):
- """
- Check that microdom encompasses broken attribute values.
- """
- input = '<body><h1><div align="cen!\n ter">Foo</div></h1></body>'
- expected = '<body><h1><div align="cen!\n ter">Foo</div></h1></body>'
- self.checkParsed(input, expected)
-
-
- def test_brokenOpeningTag(self):
- """
- Check that microdom does its best to handle broken opening tags.
- The important thing is that it doesn't raise an exception.
- """
- input = '<body><h1><sp!\n an>Hello World!</span></h1></body>'
- expected = '<body><h1><sp an="True">Hello World!</sp></h1></body>'
- self.checkParsed(input, expected)
-
-
- def test_brokenSelfClosingTag(self):
- """
- Check that microdom does its best to handle broken self-closing tags
- The important thing is that it doesn't raise an exception.
- """
- self.checkParsed('<body><span /!\n></body>',
- '<body><span></span></body>')
- self.checkParsed('<span!\n />', '<span></span>')
-
-
- def test_brokenClosingTag(self):
- """
- Check that microdom does its best to handle broken closing tags.
- The important thing is that it doesn't raise an exception.
- """
- input = '<body><h1><span>Hello World!</sp!\nan></h1></body>'
- expected = '<body><h1><span>Hello World!</span></h1></body>'
- self.checkParsed(input, expected)
- input = '<body><h1><span>Hello World!</!\nspan></h1></body>'
- self.checkParsed(input, expected)
- input = '<body><h1><span>Hello World!</span!\n></h1></body>'
- self.checkParsed(input, expected)
- input = '<body><h1><span>Hello World!<!\n/span></h1></body>'
- expected = '<body><h1><span>Hello World!<!></!></span></h1></body>'
- self.checkParsed(input, expected)
-
-
-
-
-class NodeTests(TestCase):
- """
- Tests for L{Node}.
- """
- def test_isNodeEqualTo(self):
- """
- L{Node.isEqualToNode} returns C{True} if and only if passed a L{Node}
- with the same children.
- """
- # A node is equal to itself
- node = microdom.Node(object())
- self.assertTrue(node.isEqualToNode(node))
- another = microdom.Node(object())
- # Two nodes with no children are equal
- self.assertTrue(node.isEqualToNode(another))
- node.appendChild(microdom.Node(object()))
- # A node with no children is not equal to a node with a child
- self.assertFalse(node.isEqualToNode(another))
- another.appendChild(microdom.Node(object()))
- # A node with a child and no grandchildren is equal to another node
- # with a child and no grandchildren.
- self.assertTrue(node.isEqualToNode(another))
- # A node with a child and a grandchild is not equal to another node
- # with a child and no grandchildren.
- node.firstChild().appendChild(microdom.Node(object()))
- self.assertFalse(node.isEqualToNode(another))
- # A node with a child and a grandchild is equal to another node with a
- # child and a grandchild.
- another.firstChild().appendChild(microdom.Node(object()))
- self.assertTrue(node.isEqualToNode(another))
-
- def test_validChildInstance(self):
- """
- Children of L{Node} instances must also be L{Node} instances.
- """
- node = microdom.Node()
- child = microdom.Node()
- # Node.appendChild() only accepts Node instances.
- node.appendChild(child)
- self.assertRaises(TypeError, node.appendChild, None)
- # Node.insertBefore() only accepts Node instances.
- self.assertRaises(TypeError, node.insertBefore, child, None)
- self.assertRaises(TypeError, node.insertBefore, None, child)
- self.assertRaises(TypeError, node.insertBefore, None, None)
- # Node.removeChild() only accepts Node instances.
- node.removeChild(child)
- self.assertRaises(TypeError, node.removeChild, None)
- # Node.replaceChild() only accepts Node instances.
- self.assertRaises(TypeError, node.replaceChild, child, None)
- self.assertRaises(TypeError, node.replaceChild, None, child)
- self.assertRaises(TypeError, node.replaceChild, None, None)
-
-
-class DocumentTests(TestCase):
- """
- Tests for L{Document}.
- """
- doctype = 'foo PUBLIC "baz" "http://www.example.com/example.dtd"'
-
- def test_isEqualToNode(self):
- """
- L{Document.isEqualToNode} returns C{True} if and only if passed a
- L{Document} with the same C{doctype} and C{documentElement}.
- """
- # A document is equal to itself
- document = microdom.Document()
- self.assertTrue(document.isEqualToNode(document))
- # A document without a doctype or documentElement is equal to another
- # document without a doctype or documentElement.
- another = microdom.Document()
- self.assertTrue(document.isEqualToNode(another))
- # A document with a doctype is not equal to a document without a
- # doctype.
- document.doctype = self.doctype
- self.assertFalse(document.isEqualToNode(another))
- # Two documents with the same doctype are equal
- another.doctype = self.doctype
- self.assertTrue(document.isEqualToNode(another))
- # A document with a documentElement is not equal to a document without
- # a documentElement
- document.appendChild(microdom.Node(object()))
- self.assertFalse(document.isEqualToNode(another))
- # Two documents with equal documentElements are equal.
- another.appendChild(microdom.Node(object()))
- self.assertTrue(document.isEqualToNode(another))
- # Two documents with documentElements which are not equal are not
- # equal.
- document.documentElement.appendChild(microdom.Node(object()))
- self.assertFalse(document.isEqualToNode(another))
-
-
- def test_childRestriction(self):
- """
- L{Document.appendChild} raises L{ValueError} if the document already
- has a child.
- """
- document = microdom.Document()
- child = microdom.Node()
- another = microdom.Node()
- document.appendChild(child)
- self.assertRaises(ValueError, document.appendChild, another)
-
-
-
-class EntityReferenceTests(TestCase):
- """
- Tests for L{EntityReference}.
- """
- def test_isEqualToNode(self):
- """
- L{EntityReference.isEqualToNode} returns C{True} if and only if passed
- a L{EntityReference} with the same C{eref}.
- """
- self.assertTrue(
- microdom.EntityReference('quot').isEqualToNode(
- microdom.EntityReference('quot')))
- self.assertFalse(
- microdom.EntityReference('quot').isEqualToNode(
- microdom.EntityReference('apos')))
-
-
-
-class CharacterDataTests(TestCase):
- """
- Tests for L{CharacterData}.
- """
- def test_isEqualToNode(self):
- """
- L{CharacterData.isEqualToNode} returns C{True} if and only if passed a
- L{CharacterData} with the same value.
- """
- self.assertTrue(
- microdom.CharacterData('foo').isEqualToNode(
- microdom.CharacterData('foo')))
- self.assertFalse(
- microdom.CharacterData('foo').isEqualToNode(
- microdom.CharacterData('bar')))
-
-
-
-class CommentTests(TestCase):
- """
- Tests for L{Comment}.
- """
- def test_isEqualToNode(self):
- """
- L{Comment.isEqualToNode} returns C{True} if and only if passed a
- L{Comment} with the same value.
- """
- self.assertTrue(
- microdom.Comment('foo').isEqualToNode(
- microdom.Comment('foo')))
- self.assertFalse(
- microdom.Comment('foo').isEqualToNode(
- microdom.Comment('bar')))
-
-
-
-class TextTests(TestCase):
- """
- Tests for L{Text}.
- """
- def test_isEqualToNode(self):
- """
- L{Text.isEqualToNode} returns C{True} if and only if passed a L{Text}
- which represents the same data.
- """
- self.assertTrue(
- microdom.Text('foo', raw=True).isEqualToNode(
- microdom.Text('foo', raw=True)))
- self.assertFalse(
- microdom.Text('foo', raw=True).isEqualToNode(
- microdom.Text('foo', raw=False)))
- self.assertFalse(
- microdom.Text('foo', raw=True).isEqualToNode(
- microdom.Text('bar', raw=True)))
-
-
-
-class CDATASectionTests(TestCase):
- """
- Tests for L{CDATASection}.
- """
- def test_isEqualToNode(self):
- """
- L{CDATASection.isEqualToNode} returns C{True} if and only if passed a
- L{CDATASection} which represents the same data.
- """
- self.assertTrue(
- microdom.CDATASection('foo').isEqualToNode(
- microdom.CDATASection('foo')))
- self.assertFalse(
- microdom.CDATASection('foo').isEqualToNode(
- microdom.CDATASection('bar')))
-
-
-
-class ElementTests(TestCase):
- """
- Tests for L{Element}.
- """
- def test_isEqualToNode(self):
- """
- L{Element.isEqualToNode} returns C{True} if and only if passed a
- L{Element} with the same C{nodeName}, C{namespace}, C{childNodes}, and
- C{attributes}.
- """
- self.assertTrue(
- microdom.Element(
- 'foo', {'a': 'b'}, object(), namespace='bar').isEqualToNode(
- microdom.Element(
- 'foo', {'a': 'b'}, object(), namespace='bar')))
-
- # Elements with different nodeName values do not compare equal.
- self.assertFalse(
- microdom.Element(
- 'foo', {'a': 'b'}, object(), namespace='bar').isEqualToNode(
- microdom.Element(
- 'bar', {'a': 'b'}, object(), namespace='bar')))
-
- # Elements with different namespaces do not compare equal.
- self.assertFalse(
- microdom.Element(
- 'foo', {'a': 'b'}, object(), namespace='bar').isEqualToNode(
- microdom.Element(
- 'foo', {'a': 'b'}, object(), namespace='baz')))
-
- # Elements with different childNodes do not compare equal.
- one = microdom.Element('foo', {'a': 'b'}, object(), namespace='bar')
- two = microdom.Element('foo', {'a': 'b'}, object(), namespace='bar')
- two.appendChild(microdom.Node(object()))
- self.assertFalse(one.isEqualToNode(two))
-
- # Elements with different attributes do not compare equal.
- self.assertFalse(
- microdom.Element(
- 'foo', {'a': 'b'}, object(), namespace='bar').isEqualToNode(
- microdom.Element(
- 'foo', {'a': 'c'}, object(), namespace='bar')))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xmlrpc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xmlrpc.py
deleted file mode 100755
index f49ff026..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/test/test_xmlrpc.py
+++ /dev/null
@@ -1,849 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_xmlrpc -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for XML-RPC support in L{twisted.web.xmlrpc}.
-"""
-
-import datetime
-import xmlrpclib
-from StringIO import StringIO
-
-from twisted.trial import unittest
-from twisted.web import xmlrpc
-from twisted.web.xmlrpc import (
- XMLRPC, payloadTemplate, addIntrospection, _QueryFactory, Proxy,
- withRequest)
-from twisted.web import server, static, client, error, http
-from twisted.internet import reactor, defer
-from twisted.internet.error import ConnectionDone
-from twisted.python import failure
-from twisted.test.proto_helpers import MemoryReactor
-from twisted.web.test.test_web import DummyRequest
-try:
- import twisted.internet.ssl
-except ImportError:
- sslSkip = "OpenSSL not present"
-else:
- sslSkip = None
-
-
-class AsyncXMLRPCTests(unittest.TestCase):
- """
- Tests for L{XMLRPC}'s support of Deferreds.
- """
- def setUp(self):
- self.request = DummyRequest([''])
- self.request.method = 'POST'
- self.request.content = StringIO(
- payloadTemplate % ('async', xmlrpclib.dumps(())))
-
- result = self.result = defer.Deferred()
- class AsyncResource(XMLRPC):
- def xmlrpc_async(self):
- return result
-
- self.resource = AsyncResource()
-
-
- def test_deferredResponse(self):
- """
- If an L{XMLRPC} C{xmlrpc_*} method returns a L{defer.Deferred}, the
- response to the request is the result of that L{defer.Deferred}.
- """
- self.resource.render(self.request)
- self.assertEqual(self.request.written, [])
-
- self.result.callback("result")
-
- resp = xmlrpclib.loads("".join(self.request.written))
- self.assertEqual(resp, (('result',), None))
- self.assertEqual(self.request.finished, 1)
-
-
- def test_interruptedDeferredResponse(self):
- """
- While waiting for the L{Deferred} returned by an L{XMLRPC} C{xmlrpc_*}
- method to fire, the connection the request was issued over may close.
- If this happens, neither C{write} nor C{finish} is called on the
- request.
- """
- self.resource.render(self.request)
- self.request.processingFailed(
- failure.Failure(ConnectionDone("Simulated")))
- self.result.callback("result")
- self.assertEqual(self.request.written, [])
- self.assertEqual(self.request.finished, 0)
-
-
-
-class TestRuntimeError(RuntimeError):
- pass
-
-
-
-class TestValueError(ValueError):
- pass
-
-
-
-class Test(XMLRPC):
-
- # If you add xmlrpc_ methods to this class, go change test_listMethods
- # below.
-
- FAILURE = 666
- NOT_FOUND = 23
- SESSION_EXPIRED = 42
-
- def xmlrpc_echo(self, arg):
- return arg
-
- # the doc string is part of the test
- def xmlrpc_add(self, a, b):
- """
- This function add two numbers.
- """
- return a + b
-
- xmlrpc_add.signature = [['int', 'int', 'int'],
- ['double', 'double', 'double']]
-
- # the doc string is part of the test
- def xmlrpc_pair(self, string, num):
- """
- This function puts the two arguments in an array.
- """
- return [string, num]
-
- xmlrpc_pair.signature = [['array', 'string', 'int']]
-
- # the doc string is part of the test
- def xmlrpc_defer(self, x):
- """Help for defer."""
- return defer.succeed(x)
-
- def xmlrpc_deferFail(self):
- return defer.fail(TestValueError())
-
- # don't add a doc string, it's part of the test
- def xmlrpc_fail(self):
- raise TestRuntimeError
-
- def xmlrpc_fault(self):
- return xmlrpc.Fault(12, "hello")
-
- def xmlrpc_deferFault(self):
- return defer.fail(xmlrpc.Fault(17, "hi"))
-
- def xmlrpc_complex(self):
- return {"a": ["b", "c", 12, []], "D": "foo"}
-
- def xmlrpc_dict(self, map, key):
- return map[key]
- xmlrpc_dict.help = 'Help for dict.'
-
- @withRequest
- def xmlrpc_withRequest(self, request, other):
- """
- A method decorated with L{withRequest} which can be called by
- a test to verify that the request object really is passed as
- an argument.
- """
- return (
- # as a proof that request is a request
- request.method +
- # plus proof other arguments are still passed along
- ' ' + other)
-
-
- def lookupProcedure(self, procedurePath):
- try:
- return XMLRPC.lookupProcedure(self, procedurePath)
- except xmlrpc.NoSuchFunction:
- if procedurePath.startswith("SESSION"):
- raise xmlrpc.Fault(self.SESSION_EXPIRED,
- "Session non-existant/expired.")
- else:
- raise
-
-
-
-class TestLookupProcedure(XMLRPC):
- """
- This is a resource which customizes procedure lookup to be used by the tests
- of support for this customization.
- """
- def echo(self, x):
- return x
-
-
- def lookupProcedure(self, procedureName):
- """
- Lookup a procedure from a fixed set of choices, either I{echo} or
- I{system.listeMethods}.
- """
- if procedureName == 'echo':
- return self.echo
- raise xmlrpc.NoSuchFunction(
- self.NOT_FOUND, 'procedure %s not found' % (procedureName,))
-
-
-
-class TestListProcedures(XMLRPC):
- """
- This is a resource which customizes procedure enumeration to be used by the
- tests of support for this customization.
- """
- def listProcedures(self):
- """
- Return a list of a single method this resource will claim to support.
- """
- return ['foo']
-
-
-
-class TestAuthHeader(Test):
- """
- This is used to get the header info so that we can test
- authentication.
- """
- def __init__(self):
- Test.__init__(self)
- self.request = None
-
- def render(self, request):
- self.request = request
- return Test.render(self, request)
-
- def xmlrpc_authinfo(self):
- return self.request.getUser(), self.request.getPassword()
-
-
-class TestQueryProtocol(xmlrpc.QueryProtocol):
- """
- QueryProtocol for tests that saves headers received inside the factory.
- """
-
- def connectionMade(self):
- self.factory.transport = self.transport
- xmlrpc.QueryProtocol.connectionMade(self)
-
- def handleHeader(self, key, val):
- self.factory.headers[key.lower()] = val
-
-
-class TestQueryFactory(xmlrpc._QueryFactory):
- """
- QueryFactory using L{TestQueryProtocol} for saving headers.
- """
- protocol = TestQueryProtocol
-
- def __init__(self, *args, **kwargs):
- self.headers = {}
- xmlrpc._QueryFactory.__init__(self, *args, **kwargs)
-
-
-class TestQueryFactoryCancel(xmlrpc._QueryFactory):
- """
- QueryFactory that saves a reference to the
- L{twisted.internet.interfaces.IConnector} to test connection lost.
- """
-
- def startedConnecting(self, connector):
- self.connector = connector
-
-
-class XMLRPCTestCase(unittest.TestCase):
-
- def setUp(self):
- self.p = reactor.listenTCP(0, server.Site(Test()),
- interface="127.0.0.1")
- self.port = self.p.getHost().port
- self.factories = []
-
- def tearDown(self):
- self.factories = []
- return self.p.stopListening()
-
- def queryFactory(self, *args, **kwargs):
- """
- Specific queryFactory for proxy that uses our custom
- L{TestQueryFactory}, and save factories.
- """
- factory = TestQueryFactory(*args, **kwargs)
- self.factories.append(factory)
- return factory
-
- def proxy(self, factory=None):
- """
- Return a new xmlrpc.Proxy for the test site created in
- setUp(), using the given factory as the queryFactory, or
- self.queryFactory if no factory is provided.
- """
- p = xmlrpc.Proxy("http://127.0.0.1:%d/" % self.port)
- if factory is None:
- p.queryFactory = self.queryFactory
- else:
- p.queryFactory = factory
- return p
-
- def test_results(self):
- inputOutput = [
- ("add", (2, 3), 5),
- ("defer", ("a",), "a"),
- ("dict", ({"a": 1}, "a"), 1),
- ("pair", ("a", 1), ["a", 1]),
- ("complex", (), {"a": ["b", "c", 12, []], "D": "foo"})]
-
- dl = []
- for meth, args, outp in inputOutput:
- d = self.proxy().callRemote(meth, *args)
- d.addCallback(self.assertEqual, outp)
- dl.append(d)
- return defer.DeferredList(dl, fireOnOneErrback=True)
-
- def test_errors(self):
- """
- Verify that for each way a method exposed via XML-RPC can fail, the
- correct 'Content-type' header is set in the response and that the
- client-side Deferred is errbacked with an appropriate C{Fault}
- instance.
- """
- dl = []
- for code, methodName in [(666, "fail"), (666, "deferFail"),
- (12, "fault"), (23, "noSuchMethod"),
- (17, "deferFault"), (42, "SESSION_TEST")]:
- d = self.proxy().callRemote(methodName)
- d = self.assertFailure(d, xmlrpc.Fault)
- d.addCallback(lambda exc, code=code:
- self.assertEqual(exc.faultCode, code))
- dl.append(d)
- d = defer.DeferredList(dl, fireOnOneErrback=True)
- def cb(ign):
- for factory in self.factories:
- self.assertEqual(factory.headers['content-type'],
- 'text/xml')
- self.flushLoggedErrors(TestRuntimeError, TestValueError)
- d.addCallback(cb)
- return d
-
-
- def test_cancel(self):
- """
- A deferred from the Proxy can be cancelled, disconnecting
- the L{twisted.internet.interfaces.IConnector}.
- """
- def factory(*args, **kw):
- factory.f = TestQueryFactoryCancel(*args, **kw)
- return factory.f
- d = self.proxy(factory).callRemote('add', 2, 3)
- self.assertNotEquals(factory.f.connector.state, "disconnected")
- d.cancel()
- self.assertEqual(factory.f.connector.state, "disconnected")
- d = self.assertFailure(d, defer.CancelledError)
- return d
-
-
- def test_errorGet(self):
- """
- A classic GET on the xml server should return a NOT_ALLOWED.
- """
- d = client.getPage("http://127.0.0.1:%d/" % (self.port,))
- d = self.assertFailure(d, error.Error)
- d.addCallback(
- lambda exc: self.assertEqual(int(exc.args[0]), http.NOT_ALLOWED))
- return d
-
- def test_errorXMLContent(self):
- """
- Test that an invalid XML input returns an L{xmlrpc.Fault}.
- """
- d = client.getPage("http://127.0.0.1:%d/" % (self.port,),
- method="POST", postdata="foo")
- def cb(result):
- self.assertRaises(xmlrpc.Fault, xmlrpclib.loads, result)
- d.addCallback(cb)
- return d
-
-
- def test_datetimeRoundtrip(self):
- """
- If an L{xmlrpclib.DateTime} is passed as an argument to an XML-RPC
- call and then returned by the server unmodified, the result should
- be equal to the original object.
- """
- when = xmlrpclib.DateTime()
- d = self.proxy().callRemote("echo", when)
- d.addCallback(self.assertEqual, when)
- return d
-
-
- def test_doubleEncodingError(self):
- """
- If it is not possible to encode a response to the request (for example,
- because L{xmlrpclib.dumps} raises an exception when encoding a
- L{Fault}) the exception which prevents the response from being
- generated is logged and the request object is finished anyway.
- """
- d = self.proxy().callRemote("echo", "")
-
- # *Now* break xmlrpclib.dumps. Hopefully the client already used it.
- def fakeDumps(*args, **kwargs):
- raise RuntimeError("Cannot encode anything at all!")
- self.patch(xmlrpclib, 'dumps', fakeDumps)
-
- # It doesn't matter how it fails, so long as it does. Also, it happens
- # to fail with an implementation detail exception right now, not
- # something suitable as part of a public interface.
- d = self.assertFailure(d, Exception)
-
- def cbFailed(ignored):
- # The fakeDumps exception should have been logged.
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(cbFailed)
- return d
-
-
- def test_closeConnectionAfterRequest(self):
- """
- The connection to the web server is closed when the request is done.
- """
- d = self.proxy().callRemote('echo', '')
- def responseDone(ignored):
- [factory] = self.factories
- self.assertFalse(factory.transport.connected)
- self.assertTrue(factory.transport.disconnected)
- return d.addCallback(responseDone)
-
-
- def test_tcpTimeout(self):
- """
- For I{HTTP} URIs, L{xmlrpc.Proxy.callRemote} passes the value it
- received for the C{connectTimeout} parameter as the C{timeout} argument
- to the underlying connectTCP call.
- """
- reactor = MemoryReactor()
- proxy = xmlrpc.Proxy("http://127.0.0.1:69", connectTimeout=2.0,
- reactor=reactor)
- proxy.callRemote("someMethod")
- self.assertEqual(reactor.tcpClients[0][3], 2.0)
-
-
- def test_sslTimeout(self):
- """
- For I{HTTPS} URIs, L{xmlrpc.Proxy.callRemote} passes the value it
- received for the C{connectTimeout} parameter as the C{timeout} argument
- to the underlying connectSSL call.
- """
- reactor = MemoryReactor()
- proxy = xmlrpc.Proxy("https://127.0.0.1:69", connectTimeout=3.0,
- reactor=reactor)
- proxy.callRemote("someMethod")
- self.assertEqual(reactor.sslClients[0][4], 3.0)
- test_sslTimeout.skip = sslSkip
-
-
-
-class XMLRPCTestCase2(XMLRPCTestCase):
- """
- Test with proxy that doesn't add a slash.
- """
-
- def proxy(self, factory=None):
- p = xmlrpc.Proxy("http://127.0.0.1:%d" % self.port)
- if factory is None:
- p.queryFactory = self.queryFactory
- else:
- p.queryFactory = factory
- return p
-
-
-
-class XMLRPCTestPublicLookupProcedure(unittest.TestCase):
- """
- Tests for L{XMLRPC}'s support of subclasses which override
- C{lookupProcedure} and C{listProcedures}.
- """
-
- def createServer(self, resource):
- self.p = reactor.listenTCP(
- 0, server.Site(resource), interface="127.0.0.1")
- self.addCleanup(self.p.stopListening)
- self.port = self.p.getHost().port
- self.proxy = xmlrpc.Proxy('http://127.0.0.1:%d' % self.port)
-
-
- def test_lookupProcedure(self):
- """
- A subclass of L{XMLRPC} can override C{lookupProcedure} to find
- procedures that are not defined using a C{xmlrpc_}-prefixed method name.
- """
- self.createServer(TestLookupProcedure())
- what = "hello"
- d = self.proxy.callRemote("echo", what)
- d.addCallback(self.assertEqual, what)
- return d
-
-
- def test_errors(self):
- """
- A subclass of L{XMLRPC} can override C{lookupProcedure} to raise
- L{NoSuchFunction} to indicate that a requested method is not available
- to be called, signalling a fault to the XML-RPC client.
- """
- self.createServer(TestLookupProcedure())
- d = self.proxy.callRemote("xxxx", "hello")
- d = self.assertFailure(d, xmlrpc.Fault)
- return d
-
-
- def test_listMethods(self):
- """
- A subclass of L{XMLRPC} can override C{listProcedures} to define
- Overriding listProcedures should prevent introspection from being
- broken.
- """
- resource = TestListProcedures()
- addIntrospection(resource)
- self.createServer(resource)
- d = self.proxy.callRemote("system.listMethods")
- def listed(procedures):
- # The list will also include other introspection procedures added by
- # addIntrospection. We just want to see "foo" from our customized
- # listProcedures.
- self.assertIn('foo', procedures)
- d.addCallback(listed)
- return d
-
-
-
-class SerializationConfigMixin:
- """
- Mixin which defines a couple tests which should pass when a particular flag
- is passed to L{XMLRPC}.
-
- These are not meant to be exhaustive serialization tests, since L{xmlrpclib}
- does all of the actual serialization work. They are just meant to exercise
- a few codepaths to make sure we are calling into xmlrpclib correctly.
-
- @ivar flagName: A C{str} giving the name of the flag which must be passed to
- L{XMLRPC} to allow the tests to pass. Subclasses should set this.
-
- @ivar value: A value which the specified flag will allow the serialization
- of. Subclasses should set this.
- """
- def setUp(self):
- """
- Create a new XML-RPC server with C{allowNone} set to C{True}.
- """
- kwargs = {self.flagName: True}
- self.p = reactor.listenTCP(
- 0, server.Site(Test(**kwargs)), interface="127.0.0.1")
- self.addCleanup(self.p.stopListening)
- self.port = self.p.getHost().port
- self.proxy = xmlrpc.Proxy(
- "http://127.0.0.1:%d/" % (self.port,), **kwargs)
-
-
- def test_roundtripValue(self):
- """
- C{self.value} can be round-tripped over an XMLRPC method call/response.
- """
- d = self.proxy.callRemote('defer', self.value)
- d.addCallback(self.assertEqual, self.value)
- return d
-
-
- def test_roundtripNestedValue(self):
- """
- A C{dict} which contains C{self.value} can be round-tripped over an
- XMLRPC method call/response.
- """
- d = self.proxy.callRemote('defer', {'a': self.value})
- d.addCallback(self.assertEqual, {'a': self.value})
- return d
-
-
-
-class XMLRPCAllowNoneTestCase(SerializationConfigMixin, unittest.TestCase):
- """
- Tests for passing C{None} when the C{allowNone} flag is set.
- """
- flagName = "allowNone"
- value = None
-
-
-try:
- xmlrpclib.loads(xmlrpclib.dumps(({}, {})), use_datetime=True)
-except TypeError:
- _datetimeSupported = False
-else:
- _datetimeSupported = True
-
-
-
-class XMLRPCUseDateTimeTestCase(SerializationConfigMixin, unittest.TestCase):
- """
- Tests for passing a C{datetime.datetime} instance when the C{useDateTime}
- flag is set.
- """
- flagName = "useDateTime"
- value = datetime.datetime(2000, 12, 28, 3, 45, 59)
-
- if not _datetimeSupported:
- skip = (
- "Available version of xmlrpclib does not support datetime "
- "objects.")
-
-
-
-class XMLRPCDisableUseDateTimeTestCase(unittest.TestCase):
- """
- Tests for the C{useDateTime} flag on Python 2.4.
- """
- if _datetimeSupported:
- skip = (
- "Available version of xmlrpclib supports datetime objects.")
-
- def test_cannotInitializeWithDateTime(self):
- """
- L{XMLRPC} raises L{RuntimeError} if passed C{True} for C{useDateTime}.
- """
- self.assertRaises(RuntimeError, XMLRPC, useDateTime=True)
- self.assertRaises(
- RuntimeError, Proxy, "http://localhost/", useDateTime=True)
-
-
- def test_cannotSetDateTime(self):
- """
- Setting L{XMLRPC.useDateTime} to C{True} after initialization raises
- L{RuntimeError}.
- """
- xmlrpc = XMLRPC(useDateTime=False)
- self.assertRaises(RuntimeError, setattr, xmlrpc, "useDateTime", True)
- proxy = Proxy("http://localhost/", useDateTime=False)
- self.assertRaises(RuntimeError, setattr, proxy, "useDateTime", True)
-
-
-
-class XMLRPCTestAuthenticated(XMLRPCTestCase):
- """
- Test with authenticated proxy. We run this with the same inout/ouput as
- above.
- """
- user = "username"
- password = "asecret"
-
- def setUp(self):
- self.p = reactor.listenTCP(0, server.Site(TestAuthHeader()),
- interface="127.0.0.1")
- self.port = self.p.getHost().port
- self.factories = []
-
-
- def test_authInfoInURL(self):
- p = xmlrpc.Proxy("http://%s:%s@127.0.0.1:%d/" % (
- self.user, self.password, self.port))
- d = p.callRemote("authinfo")
- d.addCallback(self.assertEqual, [self.user, self.password])
- return d
-
-
- def test_explicitAuthInfo(self):
- p = xmlrpc.Proxy("http://127.0.0.1:%d/" % (
- self.port,), self.user, self.password)
- d = p.callRemote("authinfo")
- d.addCallback(self.assertEqual, [self.user, self.password])
- return d
-
-
- def test_explicitAuthInfoOverride(self):
- p = xmlrpc.Proxy("http://wrong:info@127.0.0.1:%d/" % (
- self.port,), self.user, self.password)
- d = p.callRemote("authinfo")
- d.addCallback(self.assertEqual, [self.user, self.password])
- return d
-
-
-class XMLRPCTestIntrospection(XMLRPCTestCase):
-
- def setUp(self):
- xmlrpc = Test()
- addIntrospection(xmlrpc)
- self.p = reactor.listenTCP(0, server.Site(xmlrpc),interface="127.0.0.1")
- self.port = self.p.getHost().port
- self.factories = []
-
- def test_listMethods(self):
-
- def cbMethods(meths):
- meths.sort()
- self.assertEqual(
- meths,
- ['add', 'complex', 'defer', 'deferFail',
- 'deferFault', 'dict', 'echo', 'fail', 'fault',
- 'pair', 'system.listMethods',
- 'system.methodHelp',
- 'system.methodSignature', 'withRequest'])
-
- d = self.proxy().callRemote("system.listMethods")
- d.addCallback(cbMethods)
- return d
-
- def test_methodHelp(self):
- inputOutputs = [
- ("defer", "Help for defer."),
- ("fail", ""),
- ("dict", "Help for dict.")]
-
- dl = []
- for meth, expected in inputOutputs:
- d = self.proxy().callRemote("system.methodHelp", meth)
- d.addCallback(self.assertEqual, expected)
- dl.append(d)
- return defer.DeferredList(dl, fireOnOneErrback=True)
-
- def test_methodSignature(self):
- inputOutputs = [
- ("defer", ""),
- ("add", [['int', 'int', 'int'],
- ['double', 'double', 'double']]),
- ("pair", [['array', 'string', 'int']])]
-
- dl = []
- for meth, expected in inputOutputs:
- d = self.proxy().callRemote("system.methodSignature", meth)
- d.addCallback(self.assertEqual, expected)
- dl.append(d)
- return defer.DeferredList(dl, fireOnOneErrback=True)
-
-
-class XMLRPCClientErrorHandling(unittest.TestCase):
- """
- Test error handling on the xmlrpc client.
- """
- def setUp(self):
- self.resource = static.Data(
- "This text is not a valid XML-RPC response.",
- "text/plain")
- self.resource.isLeaf = True
- self.port = reactor.listenTCP(0, server.Site(self.resource),
- interface='127.0.0.1')
-
- def tearDown(self):
- return self.port.stopListening()
-
- def test_erroneousResponse(self):
- """
- Test that calling the xmlrpc client on a static http server raises
- an exception.
- """
- proxy = xmlrpc.Proxy("http://127.0.0.1:%d/" %
- (self.port.getHost().port,))
- return self.assertFailure(proxy.callRemote("someMethod"), Exception)
-
-
-
-class TestQueryFactoryParseResponse(unittest.TestCase):
- """
- Test the behaviour of L{_QueryFactory.parseResponse}.
- """
-
- def setUp(self):
- # The _QueryFactory that we are testing. We don't care about any
- # of the constructor parameters.
- self.queryFactory = _QueryFactory(
- path=None, host=None, method='POST', user=None, password=None,
- allowNone=False, args=())
- # An XML-RPC response that will parse without raising an error.
- self.goodContents = xmlrpclib.dumps(('',))
- # An 'XML-RPC response' that will raise a parsing error.
- self.badContents = 'invalid xml'
- # A dummy 'reason' to pass to clientConnectionLost. We don't care
- # what it is.
- self.reason = failure.Failure(ConnectionDone())
-
-
- def test_parseResponseCallbackSafety(self):
- """
- We can safely call L{_QueryFactory.clientConnectionLost} as a callback
- of L{_QueryFactory.parseResponse}.
- """
- d = self.queryFactory.deferred
- # The failure mode is that this callback raises an AlreadyCalled
- # error. We have to add it now so that it gets called synchronously
- # and triggers the race condition.
- d.addCallback(self.queryFactory.clientConnectionLost, self.reason)
- self.queryFactory.parseResponse(self.goodContents)
- return d
-
-
- def test_parseResponseErrbackSafety(self):
- """
- We can safely call L{_QueryFactory.clientConnectionLost} as an errback
- of L{_QueryFactory.parseResponse}.
- """
- d = self.queryFactory.deferred
- # The failure mode is that this callback raises an AlreadyCalled
- # error. We have to add it now so that it gets called synchronously
- # and triggers the race condition.
- d.addErrback(self.queryFactory.clientConnectionLost, self.reason)
- self.queryFactory.parseResponse(self.badContents)
- return d
-
-
- def test_badStatusErrbackSafety(self):
- """
- We can safely call L{_QueryFactory.clientConnectionLost} as an errback
- of L{_QueryFactory.badStatus}.
- """
- d = self.queryFactory.deferred
- # The failure mode is that this callback raises an AlreadyCalled
- # error. We have to add it now so that it gets called synchronously
- # and triggers the race condition.
- d.addErrback(self.queryFactory.clientConnectionLost, self.reason)
- self.queryFactory.badStatus('status', 'message')
- return d
-
- def test_parseResponseWithoutData(self):
- """
- Some server can send a response without any data:
- L{_QueryFactory.parseResponse} should catch the error and call the
- result errback.
- """
- content = """
-<methodResponse>
- <params>
- <param>
- </param>
- </params>
-</methodResponse>"""
- d = self.queryFactory.deferred
- self.queryFactory.parseResponse(content)
- return self.assertFailure(d, IndexError)
-
-
-
-class XMLRPCTestWithRequest(unittest.TestCase):
-
- def setUp(self):
- self.resource = Test()
-
-
- def test_withRequest(self):
- """
- When an XML-RPC method is called and the implementation is
- decorated with L{withRequest}, the request object is passed as
- the first argument.
- """
- request = DummyRequest('/RPC2')
- request.method = "POST"
- request.content = StringIO(xmlrpclib.dumps(("foo",), 'withRequest'))
- def valid(n, request):
- data = xmlrpclib.loads(request.written[0])
- self.assertEqual(data, (('POST foo',), None))
- d = request.notifyFinish().addCallback(valid, request)
- self.resource.render_POST(request)
- return d
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/NEWS
deleted file mode 100644
index ad77c0e4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/NEWS
+++ /dev/null
@@ -1,573 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Web 12.2.0 (2012-08-26)
-===============================
-
-Deprecations and Removals
--------------------------
- - twisted.web.static.FileTransfer, deprecated since 9.0, is removed
- now. Use a subclass of StaticProducer instead. (#5651)
- - ErrorPage, NoResource and ForbiddenResource in twisted.web.error
- were deprecated since 9.0 and are removed now. (#5659)
- - twisted.web.google, deprecated since Twisted 11.1, is removed now.
- (#5768)
-
-Other
------
- - #5665
-
-
-Twisted Web 12.1.0 (2012-06-02)
-===============================
-
-Features
---------
- - twisted.web.client.Agent and ProxyAgent now support persistent
- connections. (#3420)
- - Added twisted.web.template.renderElement, a function which renders
- an Element to a response. (#5395)
- - twisted.web.client.HTTPConnectionPool now ensures that failed
- queries on persistent connections are retried, when possible.
- (#5479)
- - twisted.web.template.XMLFile now supports FilePath objects. (#5509)
- - twisted.web.template.renderElement takes a doctype keyword
- argument, which will be written as the first line of the response,
- defaulting to the HTML5 doctype. (#5560)
-
-Bugfixes
---------
- - twisted.web.util.formatFailure now quotes all data in its output to
- avoid it being mistakenly interpreted as markup. (#4896)
- - twisted.web.distrib now lets distributed servers set the response
- message. (#5525)
-
-Deprecations and Removals
--------------------------
- - PHP3Script and PHPScript were removed from twisted.web.twcgi,
- deprecated since 10.1. Use twcgi.FilteredScript instead. (#5456)
- - twisted.web.template.XMLFile's support for file objects and
- filenames is now deprecated. Use the new support for FilePath
- objects. (#5509)
- - twisted.web.server.date_time_string and
- twisted.web.server.string_date_time are now deprecated in favor of
- twisted.web.http.datetimeToString and twisted.web.
- http.stringToDatetime (#5535)
-
-Other
------
- - #4966, #5460, #5490, #5591, #5602, #5609, #5612
-
-
-Twisted Web 12.0.0 (2012-02-10)
-===============================
-
-Features
---------
- - twisted.web.util.redirectTo now raises TypeError if the URL passed
- to it is a unicode string instead of a byte string. (#5236)
- - The new class twisted.web.template.CharRef provides support for
- inserting numeric character references in output generated by
- twisted.web.template. (#5408)
-
-Improved Documentation
-----------------------
- - The Twisted Web howto now has a section on proxies and reverse
- proxies. (#399)
- - The web client howto now covers ContentDecoderAgent and links to an
- example of its use. (#5415)
-
-Other
------
- - #5404, #5438
-
-
-Twisted Web 11.1.0 (2011-11-15)
-===============================
-
-Features
---------
- - twisted.web.client.ProxyAgent is a new HTTP/1.1 web client which
- adds proxy support. (#1774)
- - twisted.web.client.Agent now takes optional connectTimeout and
- bindAddress arguments which are forwarded to the subsequent
- connectTCP/connectSSL call. (#3450)
- - The new class twisted.web.client.FileBodyProducer makes it easy to
- upload data in HTTP requests made using the Agent client APIs.
- (#4017)
- - twisted.web.xmlrpc.XMLRPC now allows its lookupProcedure method to
- be overridden to change how XML-RPC procedures are dispatched.
- (#4836)
- - A new HTTP cookie-aware Twisted Web Agent wrapper is included in
- twisted.web.client.CookieAgent (#4922)
- - New class twisted.web.template.TagLoader provides an
- ITemplateLoader implementation which loads already-created
- twisted.web.iweb.IRenderable providers. (#5040)
- - The new class twisted.web.client.RedirectAgent adds redirect
- support to the HTTP 1.1 client stack. (#5157)
- - twisted.web.template now supports HTML tags from the HTML5
- standard, including <canvas> and <video>. (#5306)
-
-Bugfixes
---------
- - twisted.web.client.getPage and .downloadPage now only fire their
- result Deferred after the underlying connection they use has been
- closed. (#3796)
- - twisted.web.server now omits the default Content-Type header from
- NOT MODIFIED responses. (#4156)
- - twisted.web.server now responds correctly to 'Expect: 100-continue'
- headers, although this is not yet usefully exposed to user code.
- (#4673)
- - twisted.web.client.Agent no longer raises an exception if a server
- responds and closes the connection before the request has been
- fully transmitted. (#5013)
- - twisted.web.http_headers.Headers now correctly capitalizes the
- header names Content-MD5, DNT, ETag, P3P, TE, and X-XSS-Protection.
- (#5054)
- - twisted.web.template now escapes more inputs to comments which
- require escaping in the output. (#5275)
-
-Improved Documentation
-----------------------
- - The twisted.web.template howto now documents the common idiom of
- yielding tag clones from a renderer. (#5286)
- - CookieAgent is now documented in the twisted.web.client how-to.
- (#5110)
-
-Deprecations and Removals
--------------------------
- - twisted.web.google is now deprecated. (#5209)
-
-Other
------
- - #4951, #5057, #5175, #5288, #5316
-
-
-Twisted Web 11.0.0 (2011-04-01)
-===============================
-
-Features
---------
- - twisted.web._newclient.HTTPParser (and therefore Agent) now handles
- HTTP headers delimited by bare LF newlines. (#3833)
- - twisted.web.client.downloadPage now accepts the `afterFoundGet`
- parameter, with the same meaning as the `getPage` parameter of the
- same name. (#4364)
- - twisted.web.xmlrpc.Proxy constructor now takes additional 'timeout'
- and 'reactor' arguments. The 'timeout' argument defaults to 30
- seconds. (#4741)
- - Twisted Web now has a templating system, twisted.web.template,
- which is a direct, simplified derivative of Divmod Nevow. (#4939)
-
-Bugfixes
---------
- - HTTPPageGetter now adds the port to the host header if it is not
- the default for that scheme. (#3857)
- - twisted.web.http.Request.write now raises an exception if it is
- called after response generation has already finished. (#4317)
- - twisted.web.client.HTTPPageGetter and twisted.web.client.getPage
- now no longer make two requests when using afterFoundGet. (#4760)
- - twisted.web.twcgi no longer adds an extra "content-type" header to
- CGI responses. (#4786)
- - twisted.web will now properly specify an encoding (UTF-8) on error,
- redirect, and directory listing pages, so that IE7 and previous
- will not improperly guess the 'utf7' encoding in these cases.
- Please note that Twisted still sets a *default* content-type of
- 'text/html', and you shouldn't rely on that: you should set the
- encoding appropriately in your application. (#4900)
- - twisted.web.http.Request.setHost now sets the port in the host
- header if it is not the default. (#4918)
- - default NOT_IMPLEMENTED and NOT_ALLOWED pages now quote the request
- method and URI respectively, to protect against browsers which
- don't quote those values for us. (#4978)
-
-Improved Documentation
-----------------------
- - The XML-RPC howto now includes an example demonstrating how to
- access the HTTP request object in a server-side XML-RPC method.
- (#4732)
- - The Twisted Web client howto now uses the correct, public name for
- twisted.web.client.Response. (#4769)
- - Some broken links were fixed, descriptions were updated, and new
- API links were added in the Resource Templating documentation
- (resource-templates.xhtml) (#4968)
-
-Other
------
- - #2271, #2386, #4162, #4733, #4855, #4911, #4973
-
-
-Twisted Web 10.2.0 (2010-11-29)
-===============================
-
-Features
---------
- - twisted.web.xmlrpc.XMLRPC.xmlrpc_* methods can now be decorated
- using withRequest to cause them to be passed the HTTP request
- object. (#3073)
-
-Bugfixes
---------
- - twisted.web.xmlrpc.QueryProtocol.handleResponse now disconnects
- from the server, meaning that Twisted XML-RPC clients disconnect
- from the server as soon as they receive a response, rather than
- relying on the server to disconnect. (#2518)
- - twisted.web.twcgi now generates responses containing all
- occurrences of duplicate headers produced by CGI scripts, not just
- the last value. (#4742)
-
-Deprecations and Removals
--------------------------
- - twisted.web.trp, which has been deprecated since Twisted 9.0, was
- removed. (#4299)
-
-Other
------
- - #4576, #4577, #4709, #4723
-
-
-Twisted Web 10.1.0 (2010-06-27)
-===============================
-
-Features
---------
- - twisted.web.xmlrpc.XMLRPC and twisted.web.xmlrpc.Proxy now expose
- xmlrpclib's support of datetime.datetime objects if useDateTime is
- set to True. (#3219)
- - HTTP11ClientProtocol now has an abort() method for cancelling an
- outstanding request by closing the connection before receiving the
- entire response. (#3811)
- - twisted.web.http_headers.Headers initializer now rejects
- incorrectly structured dictionaries. (#4022)
- - twisted.web.client.Agent now supports HTTPS URLs. (#4023)
- - twisted.web.xmlrpc.Proxy.callRemote now returns a Deferred which
- can be cancelled to abort the attempted XML-RPC call. (#4377)
-
-Bugfixes
---------
- - twisted.web.guard now logs out avatars even if a request completes
- with an error. (#4411)
- - twisted.web.xmlrpc.XMLRPC will now no longer trigger a RuntimeError
- by trying to write responses to closed connections. (#4423)
-
-Improved Documentation
-----------------------
- - Fix broken links to deliverBody and iweb.UNKNOWN_LENGTH in
- doc/web/howto/client.xhtml. (#4507)
-
-Deprecations and Removals
--------------------------
- - twisted.web.twcgi.PHP3Script and twisted.web.twcgi.PHPScript are
- now deprecated. (#516)
-
-Other
------
- - #4403, #4452
-
-
-Twisted Web 10.0.0 (2010-03-01)
-===============================
-
-Features
---------
- - Twisted Web in 60 Seconds, a series of short tutorials with self-
- contained examples on a range of common web topics, is now a part
- of the Twisted Web howto documentation. (#4192)
-
-Bugfixes
---------
- - Data and File from twisted.web.static and
- twisted.web.distrib.UserDirectory will now only generate a 200
- response for GET or HEAD requests.
- twisted.web.client.HTTPPageGetter will no longer ignore the case of
- a request method when considering whether to apply special HEAD
- processing to a response. (#446)
-
- - twisted.web.http.HTTPClient now supports multi-line headers.
- (#2062)
-
- - Resources served via twisted.web.distrib will no longer encounter a
- Banana error when writing more than 640kB at once to the request
- object. (#3212)
-
- - The Error, PageRedirect, and InfiniteRedirection exception in
- twisted.web now initialize an empty message parameter by mapping
- the HTTP status code parameter to a descriptive string. Previously
- the lookup would always fail, leaving message empty. (#3806)
-
- - The 'wsgi.input' WSGI environment object now supports -1 and None
- as arguments to the read and readlines methods. (#4114)
-
- - twisted.web.wsgi doesn't unquote QUERY_STRING anymore, thus
- complying with the WSGI reference implementation. (#4143)
-
- - The HTTP proxy will no longer pass on keep-alive request headers
- from the client, preventing pages from loading then "hanging"
- (leaving the connection open with no hope of termination). (#4179)
-
-Deprecations and Removals
--------------------------
- - Remove '--static' option from twistd web, that served as an alias
- for the '--path' option. (#3907)
-
-Other
------
- - #3784, #4216, #4242
-
-
-Twisted Web 9.0.0 (2009-11-24)
-==============================
-
-Features
---------
- - There is now an iweb.IRequest interface which specifies the interface that
- request objects provide (#3416)
- - downloadPage now supports the same cookie, redirect, and timeout features
- that getPage supports (#2971)
- - A chapter about WSGI has been added to the twisted.web documentation (#3510)
- - The HTTP auth support in the web server now allows anonymous sessions by
- logging in with ANONYMOUS credentials when no Authorization header is
- provided in a request (#3924, #3936)
- - HTTPClientFactory now accepts a parameter to enable a common deviation from
- the HTTP 1.1 standard by responding to redirects in a POSTed request with a
- GET instead of another POST (#3624)
- - A new basic HTTP/1.1 client API is included in twisted.web.client.Agent
- (#886, #3987)
-
-Fixes
------
- - Requests for "insecure" children of a static.File (such as paths containing
- encoded directory separators) will now result in a 404 instead of a 500
- (#3549, #3469)
- - When specifying a followRedirect argument to the getPage function, the state
- of redirect-following for other getPage calls should now be unaffected. It
- was previously overwriting a class attribute which would affect outstanding
- getPage calls (#3192)
- - Downloading an URL of the form "http://example.com:/" will now work,
- ignoring the extraneous colon (#2402)
- - microdom's appendChild method will no longer issue a spurious warning, and
- microdom's methods in general should now issue more meaningful exceptions
- when invalid parameters are passed (#3421)
- - WSGI applications will no longer have spurious Content-Type headers added to
- their responses by the twisted.web server. In addition, WSGI applications
- will no longer be able to specify the server-restricted headers Server and
- Date (#3569)
- - http_headers.Headers now normalizes the case of raw headers passed directly
- to it in the same way that it normalizes the headers passed to setRawHeaders
- (#3557)
- - The distrib module no longer relies on the deprecated woven package (#3559)
- - twisted.web.domhelpers now works with both microdom and minidom (#3600)
- - twisted.web servers will now ignore invalid If-Modified-Since headers instead
- of returning a 500 error (#3601)
- - Certain request-bound memory and file resources are cleaned up slightly
- sooner by the request when the connection is lost (#1621, #3176)
- - xmlrpclib.DateTime objects should now correctly round-trip over twisted.web's
- XMLRPC support in all supported versions of Python, and errors during error
- serialization will no longer hang a twisted.web XMLRPC response (#2446)
- - request.content should now always be seeked to the beginning when
- request.process is called, so application code should never need to seek
- back manually (#3585)
- - Fetching a child of static.File with a double-slash in the URL (such as
- "example//foo.html") should now return a 404 instead of a traceback and
- 500 error (#3631)
- - downloadPage will now fire a Failure on its returned Deferred instead of
- indicating success when the connection is prematurely lost (#3645)
- - static.File will now provide a 404 instead of a 500 error when it was
- constructed with a non-existent file (#3634)
- - microdom should now serialize namespaces correctly (#3672)
- - The HTTP Auth support resource wrapper should no longer corrupt requests and
- cause them to skip a segment in the request path (#3679)
- - The twisted.web WSGI support should now include leading slashes in PATH_INFO,
- and SCRIPT_NAME will be empty if the application is at the root of the
- resource tree. This means that WSGI applications should no longer generate
- URLs with double-slashes in them even if they naively concatenate the values
- (#3721)
- - WSGI applications should now receive the requesting client's IP in the
- REMOTE_ADDR environment variable (#3730)
- - The distrib module should work again. It was unfortunately broken with the
- refactoring of twisted.web's header support (#3697)
- - static.File now supports multiple ranges specified in the Range header
- (#3574)
- - static.File should now generate a correct Content-Length value when the
- requested Range value doesn't fit entirely within the file's contents (#3814)
- - Attempting to call request.finish() after the connection has been lost will
- now immediately raise a RuntimeError (#4013)
- - An HTTP-auth resource should now be able to directly render the wrapped
- avatar, whereas before it would only allow retrieval of child resources
- (#4014)
- - twisted.web's wsgi support should no longer attempt to call request.finish
- twice, which would cause errors in certain cases (#4025)
- - WSGI applications should now be able to handle requests with large bodies
- (#4029)
- - Exceptions raised from WSGI applications should now more reliably be turned
- into 500 errors on the HTTP level (#4019)
- - DeferredResource now correctly passes through exceptions raised from the
- wrapped resource, instead of turning them all into 500 errors (#3932)
- - Agent.request now generates a Host header when no headers are passed at
- (#4131)
-
-Deprecations and Removals
--------------------------
- - The unmaintained and untested twisted.web.monitor module was removed (#2763)
- - The twisted.web.woven package has been removed (#1522)
- - All of the error resources in twisted.web.error are now in
- twisted.web.resource, and accessing them through twisted.web.error is now
- deprecated (#3035)
- - To facilitate a simplification of the timeout logic in server.Session,
- various things have been deprecated (#3457)
- - the loopFactory attribute is now ignored
- - the checkExpired method now does nothing
- - the lifetime parameter to startCheckingExpiration is now ignored
- - The twisted.web.trp module is now deprecated (#2030)
-
-Other
------
- - #2763, #3540, #3575, #3610, #3605, #1176, #3539, #3750, #3761, #3779, #2677,
- #3782, #3904, #3919, #3418, #3990, #1404, #4050
-
-
-Web 8.2.0 (2008-12-16)
-======================
-
-Features
---------
- - The web server can now deal with multi-value headers in the new attributes of
- Request, requestHeaders and responseHeaders (#165)
- - There is now a resource-wrapper which implements HTTP Basic and Digest auth
- in terms of twisted.cred (#696)
- - It's now possible to limit the number of redirects that client.getPage will
- follow (#2412)
- - The directory-listing code no longer uses Woven (#3257)
- - static.File now supports Range headers with a single range (#1493)
- - twisted.web now has a rudimentary WSGI container (#2753)
- - The web server now supports chunked encoding in requests (#3385)
-
-Fixes
------
- - The xmlrpc client now raises an error when the server sends an empty
- response (#3399)
- - HTTPPageGetter no longer duplicates default headers when they're explicitly
- overridden in the headers parameter (#1382)
- - The server will no longer timeout clients which are still sending request
- data (#1903)
- - microdom's isEqualToNode now returns False when the nodes aren't equal
- (#2542)
-
-Deprecations and Removals
--------------------------
-
- - Request.headers and Request.received_headers are not quite deprecated, but
- they are discouraged in favor of requestHeaders and responseHeaders (#165)
-
-Other
------
- - #909, #687, #2938, #1152, #2930, #2025, #2683, #3471
-
-
-8.1.0 (2008-05-18)
-==================
-
-Fixes
------
-
- - Fixed an XMLRPC bug whereby sometimes a callRemote Deferred would
- accidentally be fired twice when a connection was lost during the handling of
- a response (#3152)
- - Fixed a bug in the "Using Twisted Web" document which prevented an example
- resource from being renderable (#3147)
- - The deprecated mktap API is no longer used (#3127)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Features
---------
- - Add support to twisted.web.client.getPage for the HTTP HEAD method. (#2750)
-
-Fixes
------
- - Set content-type in xmlrpc responses to "text/xml" (#2430)
- - Add more error checking in the xmlrpc.XMLRPC render method, and enforce
- POST requests. (#2505)
- - Reject unicode input to twisted.web.client._parse to reject invalid
- unicode URLs early. (#2628)
- - Correctly re-quote URL path segments when generating an URL string to
- return from Request.prePathURL. (#2934)
- - Make twisted.web.proxy.ProxyClientFactory close the connection when
- reporting a 501 error. (#1089)
- - Fix twisted.web.proxy.ReverseProxyResource to specify the port in the
- host header if different from 80. (#1117)
- - Change twisted.web.proxy.ReverseProxyResource so that it correctly encodes
- the request URI it sends on to the server for which it is a proxy. (#3013)
- - Make "twistd web --personal" use PBServerFactory (#2681)
-
-Misc
-----
- - #1996, #2382, #2211, #2633, #2634, #2640, #2752, #238, #2905
-
-
-0.7.0 (2007-01-02)
-==================
-
-Features
---------
- - Python 2.5 is now supported (#1867)
- - twisted.web.xmlrpc now supports the <nil/> xml-rpc extension type
- in both the server and the client (#469)
-
-Fixes
------
- - Microdom and SUX now manages certain malformed XML more resiliently
- (#1984, #2225, #2298)
- - twisted.web.client.getPage can now deal with an URL of the form
- "http://example.com" (no trailing slash) (#1080)
- - The HTTP server now allows (invalid) URLs with multiple question
- marks (#1550)
- - '=' can now be in the value of a cookie (#1051)
- - Microdom now correctly handles xmlns="" (#2184)
-
-Deprecations and Removals
--------------------------
- - websetroot was removed, because it wasn't working anyway (#945)
- - woven.guard no longer supports the old twisted.cred API (#1440)
-
-Other
------
-The following changes are minor or closely related to other changes.
-
- - #1636, #1637, #1638, #1936, #1883, #447
-
-
-0.6.0 (2006-05-21)
-==================
-
-Features
---------
- - Basic auth support for the XMLRPC client (#1474).
-
-Fixes
------
- - More correct datetime parsing.
- - Efficiency improvements (#974)
- - Handle popular non-RFC compliant formats for If-Modified-Since
- headers (#976).
- - Improve support for certain buggy CGI scripts.
- - CONTENT_LENGTH is now available to CGI scripts.
- - Support for even worse HTML in microdom (#1358).
- - Trying to view a user's home page when the user doesn't have a
- ~/public_html no longer displays a traceback (#551).
- - Misc: #543, #1011, #1005, #1287, #1337, #1383, #1079, #1492, #1189,
- #737, #872.
-
-
-0.5.0
-=====
- - Client properly reports timeouts as error
- - "Socially deprecate" woven
- - Fix memory leak in _c_urlarg library
- - Stop using _c_urlarg library
- - Fix 'gzip' and 'bzip2' content-encodings
- - Escape log entries so remote user cannot corrupt the log
- - Commented out range support because it's broken
- - Fix HEAD responses without content-length
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/README
deleted file mode 100644
index 50b59d04..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/topfiles/README
+++ /dev/null
@@ -1,6 +0,0 @@
-Twisted Web 12.2.0
-
-Twisted Web depends on Twisted Core. pyOpenSSL
-(<http://launchpad.net/pyopenssl>) is also required for HTTPS. SOAPpy
-(<http://pywebsvcs.sourceforge.net/>) is required for SOAP support. For Quixote
-resource templates, Quixote (<http://www.quixote.ca/>) is required.
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py
deleted file mode 100755
index 5ab580dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py
+++ /dev/null
@@ -1,299 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_cgi -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-I hold resource classes and helper classes that deal with CGI scripts.
-"""
-
-# System Imports
-import string
-import os
-import urllib
-
-# Twisted Imports
-from twisted.web import http
-from twisted.internet import reactor, protocol
-from twisted.spread import pb
-from twisted.python import log, filepath
-from twisted.web import resource, server, static
-
-
-class CGIDirectory(resource.Resource, filepath.FilePath):
- def __init__(self, pathname):
- resource.Resource.__init__(self)
- filepath.FilePath.__init__(self, pathname)
-
- def getChild(self, path, request):
- fnp = self.child(path)
- if not fnp.exists():
- return static.File.childNotFound
- elif fnp.isdir():
- return CGIDirectory(fnp.path)
- else:
- return CGIScript(fnp.path)
- return resource.NoResource()
-
- def render(self, request):
- notFound = resource.NoResource(
- "CGI directories do not support directory listing.")
- return notFound.render(request)
-
-
-
-class CGIScript(resource.Resource):
- """
- L{CGIScript} is a resource which runs child processes according to the CGI
- specification.
-
- The implementation is complex due to the fact that it requires asynchronous
- IPC with an external process with an unpleasant protocol.
- """
- isLeaf = 1
- def __init__(self, filename, registry=None):
- """
- Initialize, with the name of a CGI script file.
- """
- self.filename = filename
-
-
- def render(self, request):
- """
- Do various things to conform to the CGI specification.
-
- I will set up the usual slew of environment variables, then spin off a
- process.
-
- @type request: L{twisted.web.http.Request}
- @param request: An HTTP request.
- """
- script_name = "/"+string.join(request.prepath, '/')
- serverName = string.split(request.getRequestHostname(), ':')[0]
- env = {"SERVER_SOFTWARE": server.version,
- "SERVER_NAME": serverName,
- "GATEWAY_INTERFACE": "CGI/1.1",
- "SERVER_PROTOCOL": request.clientproto,
- "SERVER_PORT": str(request.getHost().port),
- "REQUEST_METHOD": request.method,
- "SCRIPT_NAME": script_name, # XXX
- "SCRIPT_FILENAME": self.filename,
- "REQUEST_URI": request.uri,
- }
-
- client = request.getClient()
- if client is not None:
- env['REMOTE_HOST'] = client
- ip = request.getClientIP()
- if ip is not None:
- env['REMOTE_ADDR'] = ip
- pp = request.postpath
- if pp:
- env["PATH_INFO"] = "/"+string.join(pp, '/')
-
- if hasattr(request, "content"):
- # request.content is either a StringIO or a TemporaryFile, and
- # the file pointer is sitting at the beginning (seek(0,0))
- request.content.seek(0,2)
- length = request.content.tell()
- request.content.seek(0,0)
- env['CONTENT_LENGTH'] = str(length)
-
- qindex = string.find(request.uri, '?')
- if qindex != -1:
- qs = env['QUERY_STRING'] = request.uri[qindex+1:]
- if '=' in qs:
- qargs = []
- else:
- qargs = [urllib.unquote(x) for x in qs.split('+')]
- else:
- env['QUERY_STRING'] = ''
- qargs = []
-
- # Propogate HTTP headers
- for title, header in request.getAllHeaders().items():
- envname = string.upper(string.replace(title, '-', '_'))
- if title not in ('content-type', 'content-length'):
- envname = "HTTP_" + envname
- env[envname] = header
- # Propogate our environment
- for key, value in os.environ.items():
- if key not in env:
- env[key] = value
- # And they're off!
- self.runProcess(env, request, qargs)
- return server.NOT_DONE_YET
-
-
- def runProcess(self, env, request, qargs=[]):
- """
- Run the cgi script.
-
- @type env: A C{dict} of C{str}, or C{None}
- @param env: The environment variables to pass to the processs that will
- get spawned. See
- L{twisted.internet.interfaces.IReactorProcess.spawnProcess} for more
- information about environments and process creation.
-
- @type request: L{twisted.web.http.Request}
- @param request: An HTTP request.
-
- @type qargs: A C{list} of C{str}
- @param qargs: The command line arguments to pass to the process that
- will get spawned.
- """
- p = CGIProcessProtocol(request)
- reactor.spawnProcess(p, self.filename, [self.filename] + qargs, env,
- os.path.dirname(self.filename))
-
-
-
-class FilteredScript(CGIScript):
- """
- I am a special version of a CGI script, that uses a specific executable.
-
- This is useful for interfacing with other scripting languages that adhere to
- the CGI standard. My C{filter} attribute specifies what executable to run,
- and my C{filename} init parameter describes which script to pass to the
- first argument of that script.
-
- To customize me for a particular location of a CGI interpreter, override
- C{filter}.
-
- @type filter: C{str}
- @ivar filter: The absolute path to the executable.
- """
-
- filter = '/usr/bin/cat'
-
-
- def runProcess(self, env, request, qargs=[]):
- """
- Run a script through the C{filter} executable.
-
- @type env: A C{dict} of C{str}, or C{None}
- @param env: The environment variables to pass to the processs that will
- get spawned. See
- L{twisted.internet.interfaces.IReactorProcess.spawnProcess} for more
- information about environments and process creation.
-
- @type request: L{twisted.web.http.Request}
- @param request: An HTTP request.
-
- @type qargs: A C{list} of C{str}
- @param qargs: The command line arguments to pass to the process that
- will get spawned.
- """
- p = CGIProcessProtocol(request)
- reactor.spawnProcess(p, self.filter,
- [self.filter, self.filename] + qargs, env,
- os.path.dirname(self.filename))
-
-
-
-class CGIProcessProtocol(protocol.ProcessProtocol, pb.Viewable):
- handling_headers = 1
- headers_written = 0
- headertext = ''
- errortext = ''
-
- # Remotely relay producer interface.
-
- def view_resumeProducing(self, issuer):
- self.resumeProducing()
-
- def view_pauseProducing(self, issuer):
- self.pauseProducing()
-
- def view_stopProducing(self, issuer):
- self.stopProducing()
-
- def resumeProducing(self):
- self.transport.resumeProducing()
-
- def pauseProducing(self):
- self.transport.pauseProducing()
-
- def stopProducing(self):
- self.transport.loseConnection()
-
- def __init__(self, request):
- self.request = request
-
- def connectionMade(self):
- self.request.registerProducer(self, 1)
- self.request.content.seek(0, 0)
- content = self.request.content.read()
- if content:
- self.transport.write(content)
- self.transport.closeStdin()
-
- def errReceived(self, error):
- self.errortext = self.errortext + error
-
- def outReceived(self, output):
- """
- Handle a chunk of input
- """
- # First, make sure that the headers from the script are sorted
- # out (we'll want to do some parsing on these later.)
- if self.handling_headers:
- text = self.headertext + output
- headerEnds = []
- for delimiter in '\n\n','\r\n\r\n','\r\r', '\n\r\n':
- headerend = text.find(delimiter)
- if headerend != -1:
- headerEnds.append((headerend, delimiter))
- if headerEnds:
- # The script is entirely in control of response headers; disable the
- # default Content-Type value normally provided by
- # twisted.web.server.Request.
- self.request.defaultContentType = None
-
- headerEnds.sort()
- headerend, delimiter = headerEnds[0]
- self.headertext = text[:headerend]
- # This is a final version of the header text.
- linebreak = delimiter[:len(delimiter)//2]
- headers = self.headertext.split(linebreak)
- for header in headers:
- br = header.find(': ')
- if br == -1:
- log.msg( 'ignoring malformed CGI header: %s' % header )
- else:
- headerName = header[:br].lower()
- headerText = header[br+2:]
- if headerName == 'location':
- self.request.setResponseCode(http.FOUND)
- if headerName == 'status':
- try:
- statusNum = int(headerText[:3]) #"XXX <description>" sometimes happens.
- except:
- log.msg( "malformed status header" )
- else:
- self.request.setResponseCode(statusNum)
- else:
- # Don't allow the application to control these required headers.
- if headerName.lower() not in ('server', 'date'):
- self.request.responseHeaders.addRawHeader(headerName, headerText)
- output = text[headerend+len(delimiter):]
- self.handling_headers = 0
- if self.handling_headers:
- self.headertext = text
- if not self.handling_headers:
- self.request.write(output)
-
- def processEnded(self, reason):
- if reason.value.exitCode != 0:
- log.msg("CGI %s exited with exit code %s" %
- (self.request.uri, reason.value.exitCode))
- if self.errortext:
- log.msg("Errors from CGI %s: %s" % (self.request.uri, self.errortext))
- if self.handling_headers:
- log.msg("Premature end of headers in %s: %s" % (self.request.uri, self.headertext))
- self.request.write(
- resource.ErrorPage(http.INTERNAL_SERVER_ERROR,
- "CGI Script Error",
- "Premature end of script headers.").render(self.request))
- self.request.unregisterProducer()
- self.request.finish()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/util.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/util.py
deleted file mode 100755
index 0c6cdb61..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/util.py
+++ /dev/null
@@ -1,433 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_util -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An assortment of web server-related utilities.
-"""
-
-__all__ = [
- "redirectTo", "Redirect", "ChildRedirector", "ParentRedirect",
- "DeferredResource", "htmlIndent", "FailureElement", "formatFailure"]
-
-from cStringIO import StringIO
-import linecache
-import string
-import types
-
-from twisted.python.filepath import FilePath
-from twisted.python.reflect import fullyQualifiedName
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-from twisted.python.modules import getModule
-
-from twisted.web import html, resource
-from twisted.web.template import (
- TagLoader, XMLFile, Element, renderer, flattenString)
-
-
-def redirectTo(URL, request):
- """
- Generate a redirect to the given location.
-
- @param URL: A C{str} giving the location to which to redirect.
- @type URL: C{str}
-
- @param request: The request object to use to generate the redirect.
- @type request: L{IRequest<twisted.web.iweb.IRequest>} provider
-
- @raise TypeError: If the type of C{URL} a C{unicode} instead of C{str}.
-
- @return: A C{str} containing HTML which tries to convince the client agent
- to visit the new location even if it doesn't respect the I{FOUND}
- response code. This is intended to be returned from a render method,
- eg::
-
- def render_GET(self, request):
- return redirectTo("http://example.com/", request)
- """
- if isinstance(URL, unicode) :
- raise TypeError("Unicode object not allowed as URL")
- request.setHeader("content-type", "text/html; charset=utf-8")
- request.redirect(URL)
- return """
-<html>
- <head>
- <meta http-equiv=\"refresh\" content=\"0;URL=%(url)s\">
- </head>
- <body bgcolor=\"#FFFFFF\" text=\"#000000\">
- <a href=\"%(url)s\">click here</a>
- </body>
-</html>
-""" % {'url': URL}
-
-class Redirect(resource.Resource):
-
- isLeaf = 1
-
- def __init__(self, url):
- resource.Resource.__init__(self)
- self.url = url
-
- def render(self, request):
- return redirectTo(self.url, request)
-
- def getChild(self, name, request):
- return self
-
-class ChildRedirector(Redirect):
- isLeaf = 0
- def __init__(self, url):
- # XXX is this enough?
- if ((url.find('://') == -1)
- and (not url.startswith('..'))
- and (not url.startswith('/'))):
- raise ValueError("It seems you've given me a redirect (%s) that is a child of myself! That's not good, it'll cause an infinite redirect." % url)
- Redirect.__init__(self, url)
-
- def getChild(self, name, request):
- newUrl = self.url
- if not newUrl.endswith('/'):
- newUrl += '/'
- newUrl += name
- return ChildRedirector(newUrl)
-
-
-from twisted.python import urlpath
-
-class ParentRedirect(resource.Resource):
- """
- I redirect to URLPath.here().
- """
- isLeaf = 1
- def render(self, request):
- return redirectTo(urlpath.URLPath.fromRequest(request).here(), request)
-
- def getChild(self, request):
- return self
-
-
-class DeferredResource(resource.Resource):
- """
- I wrap up a Deferred that will eventually result in a Resource
- object.
- """
- isLeaf = 1
-
- def __init__(self, d):
- resource.Resource.__init__(self)
- self.d = d
-
- def getChild(self, name, request):
- return self
-
- def render(self, request):
- self.d.addCallback(self._cbChild, request).addErrback(
- self._ebChild,request)
- from twisted.web.server import NOT_DONE_YET
- return NOT_DONE_YET
-
- def _cbChild(self, child, request):
- request.render(resource.getChildForRequest(child, request))
-
- def _ebChild(self, reason, request):
- request.processingFailed(reason)
- return reason
-
-
-stylesheet = ""
-
-def htmlrepr(x):
- return htmlReprTypes.get(type(x), htmlUnknown)(x)
-
-def saferepr(x):
- try:
- rx = repr(x)
- except:
- rx = "<repr failed! %s instance at %s>" % (x.__class__, id(x))
- return rx
-
-def htmlUnknown(x):
- return '<code>'+html.escape(saferepr(x))+'</code>'
-
-def htmlDict(d):
- io = StringIO()
- w = io.write
- w('<div class="dict"><span class="heading">Dictionary instance @ %s</span>' % hex(id(d)))
- w('<table class="dict">')
- for k, v in d.items():
-
- if k == '__builtins__':
- v = 'builtin dictionary'
- w('<tr><td class="dictKey">%s</td><td class="dictValue">%s</td></tr>' % (htmlrepr(k), htmlrepr(v)))
- w('</table></div>')
- return io.getvalue()
-
-def htmlList(l):
- io = StringIO()
- w = io.write
- w('<div class="list"><span class="heading">List instance @ %s</span>' % hex(id(l)))
- for i in l:
- w('<div class="listItem">%s</div>' % htmlrepr(i))
- w('</div>')
- return io.getvalue()
-
-def htmlInst(i):
- if hasattr(i, "__html__"):
- s = i.__html__()
- else:
- s = html.escape(saferepr(i))
- return '''<div class="instance"><span class="instanceName">%s instance @ %s</span>
- <span class="instanceRepr">%s</span></div>
- ''' % (i.__class__, hex(id(i)), s)
-
-def htmlString(s):
- return html.escape(saferepr(s))
-
-def htmlFunc(f):
- return ('<div class="function">' +
- html.escape("function %s in file %s at line %s" %
- (f.__name__, f.func_code.co_filename,
- f.func_code.co_firstlineno))+
- '</div>')
-
-htmlReprTypes = {types.DictType: htmlDict,
- types.ListType: htmlList,
- types.InstanceType: htmlInst,
- types.StringType: htmlString,
- types.FunctionType: htmlFunc}
-
-
-
-def htmlIndent(snippetLine):
- ret = string.replace(string.replace(html.escape(string.rstrip(snippetLine)),
- ' ', '&nbsp;'),
- '\t', '&nbsp; &nbsp; &nbsp; &nbsp; ')
- return ret
-
-
-
-class _SourceLineElement(Element):
- """
- L{_SourceLineElement} is an L{IRenderable} which can render a single line of
- source code.
-
- @ivar number: A C{int} giving the line number of the source code to be
- rendered.
- @ivar source: A C{str} giving the source code to be rendered.
- """
- def __init__(self, loader, number, source):
- Element.__init__(self, loader)
- self.number = number
- self.source = source
-
-
- @renderer
- def sourceLine(self, request, tag):
- """
- Render the line of source as a child of C{tag}.
- """
- return tag(self.source.replace(' ', u' \N{NO-BREAK SPACE}'))
-
-
- @renderer
- def lineNumber(self, request, tag):
- """
- Render the line number as a child of C{tag}.
- """
- return tag(str(self.number))
-
-
-
-class _SourceFragmentElement(Element):
- """
- L{_SourceFragmentElement} is an L{IRenderable} which can render several lines
- of source code near the line number of a particular frame object.
-
- @ivar frame: A L{Failure<twisted.python.failure.Failure>}-style frame object
- for which to load a source line to render. This is really a tuple
- holding some information from a frame object. See
- L{Failure.frames<twisted.python.failure.Failure>} for specifics.
- """
- def __init__(self, loader, frame):
- Element.__init__(self, loader)
- self.frame = frame
-
-
- def _getSourceLines(self):
- """
- Find the source line references by C{self.frame} and yield, in source
- line order, it and the previous and following lines.
-
- @return: A generator which yields two-tuples. Each tuple gives a source
- line number and the contents of that source line.
- """
- filename = self.frame[1]
- lineNumber = self.frame[2]
- for snipLineNumber in range(lineNumber - 1, lineNumber + 2):
- yield (snipLineNumber,
- linecache.getline(filename, snipLineNumber).rstrip())
-
-
- @renderer
- def sourceLines(self, request, tag):
- """
- Render the source line indicated by C{self.frame} and several
- surrounding lines. The active line will be given a I{class} of
- C{"snippetHighlightLine"}. Other lines will be given a I{class} of
- C{"snippetLine"}.
- """
- for (lineNumber, sourceLine) in self._getSourceLines():
- newTag = tag.clone()
- if lineNumber == self.frame[2]:
- cssClass = "snippetHighlightLine"
- else:
- cssClass = "snippetLine"
- loader = TagLoader(newTag(**{"class": cssClass}))
- yield _SourceLineElement(loader, lineNumber, sourceLine)
-
-
-
-class _FrameElement(Element):
- """
- L{_FrameElement} is an L{IRenderable} which can render details about one
- frame from a L{Failure<twisted.python.failure.Failure>}.
-
- @ivar frame: A L{Failure<twisted.python.failure.Failure>}-style frame object
- for which to load a source line to render. This is really a tuple
- holding some information from a frame object. See
- L{Failure.frames<twisted.python.failure.Failure>} for specifics.
- """
- def __init__(self, loader, frame):
- Element.__init__(self, loader)
- self.frame = frame
-
-
- @renderer
- def filename(self, request, tag):
- """
- Render the name of the file this frame references as a child of C{tag}.
- """
- return tag(self.frame[1])
-
-
- @renderer
- def lineNumber(self, request, tag):
- """
- Render the source line number this frame references as a child of
- C{tag}.
- """
- return tag(str(self.frame[2]))
-
-
- @renderer
- def function(self, request, tag):
- """
- Render the function name this frame references as a child of C{tag}.
- """
- return tag(self.frame[0])
-
-
- @renderer
- def source(self, request, tag):
- """
- Render the source code surrounding the line this frame references,
- replacing C{tag}.
- """
- return _SourceFragmentElement(TagLoader(tag), self.frame)
-
-
-
-class _StackElement(Element):
- """
- L{_StackElement} renders an L{IRenderable} which can render a list of frames.
- """
- def __init__(self, loader, stackFrames):
- Element.__init__(self, loader)
- self.stackFrames = stackFrames
-
-
- @renderer
- def frames(self, request, tag):
- """
- Render the list of frames in this L{_StackElement}, replacing C{tag}.
- """
- return [
- _FrameElement(TagLoader(tag.clone()), frame)
- for frame
- in self.stackFrames]
-
-
-
-class FailureElement(Element):
- """
- L{FailureElement} is an L{IRenderable} which can render detailed information
- about a L{Failure<twisted.python.failure.Failure>}.
-
- @ivar failure: The L{Failure<twisted.python.failure.Failure>} instance which
- will be rendered.
-
- @since: 12.1
- """
- loader = XMLFile(getModule(__name__).filePath.sibling("failure.xhtml"))
-
- def __init__(self, failure, loader=None):
- Element.__init__(self, loader)
- self.failure = failure
-
-
- @renderer
- def type(self, request, tag):
- """
- Render the exception type as a child of C{tag}.
- """
- return tag(fullyQualifiedName(self.failure.type))
-
-
- @renderer
- def value(self, request, tag):
- """
- Render the exception value as a child of C{tag}.
- """
- return tag(str(self.failure.value))
-
-
- @renderer
- def traceback(self, request, tag):
- """
- Render all the frames in the wrapped
- L{Failure<twisted.python.failure.Failure>}'s traceback stack, replacing
- C{tag}.
- """
- return _StackElement(TagLoader(tag), self.failure.frames)
-
-
-
-def formatFailure(myFailure):
- """
- Construct an HTML representation of the given failure.
-
- Consider using L{FailureElement} instead.
-
- @type myFailure: L{Failure<twisted.python.failure.Failure>}
-
- @rtype: C{str}
- @return: A string containing the HTML representation of the given failure.
- """
- result = []
- flattenString(None, FailureElement(myFailure)).addBoth(result.append)
- if isinstance(result[0], str):
- # Ensure the result string is all ASCII, for compatibility with the
- # default encoding expected by browsers.
- return result[0].decode('utf-8').encode('ascii', 'xmlcharrefreplace')
- result[0].raiseException()
-
-
-_twelveOne = Version("Twisted", 12, 1, 0)
-
-for name in ["htmlrepr", "saferepr", "htmlUnknown", "htmlString", "htmlList",
- "htmlDict", "htmlInst", "htmlFunc", "htmlIndent", "htmlReprTypes",
- "stylesheet"]:
- deprecatedModuleAttribute(
- _twelveOne, "See twisted.web.template.", __name__, name)
-del name
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/vhost.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/vhost.py
deleted file mode 100755
index 1acee218..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/vhost.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# -*- test-case-name: twisted.web.
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-I am a virtual hosts implementation.
-"""
-
-# Twisted Imports
-from twisted.python import roots
-from twisted.web import resource
-
-
-class VirtualHostCollection(roots.Homogenous):
- """Wrapper for virtual hosts collection.
-
- This exists for configuration purposes.
- """
- entityType = resource.Resource
-
- def __init__(self, nvh):
- self.nvh = nvh
-
- def listStaticEntities(self):
- return self.nvh.hosts.items()
-
- def getStaticEntity(self, name):
- return self.nvh.hosts.get(self)
-
- def reallyPutEntity(self, name, entity):
- self.nvh.addHost(name, entity)
-
- def delEntity(self, name):
- self.nvh.removeHost(name)
-
-
-class NameVirtualHost(resource.Resource):
- """I am a resource which represents named virtual hosts.
- """
-
- default = None
-
- def __init__(self):
- """Initialize.
- """
- resource.Resource.__init__(self)
- self.hosts = {}
-
- def listStaticEntities(self):
- return resource.Resource.listStaticEntities(self) + [("Virtual Hosts", VirtualHostCollection(self))]
-
- def getStaticEntity(self, name):
- if name == "Virtual Hosts":
- return VirtualHostCollection(self)
- else:
- return resource.Resource.getStaticEntity(self, name)
-
- def addHost(self, name, resrc):
- """Add a host to this virtual host.
-
- This will take a host named `name', and map it to a resource
- `resrc'. For example, a setup for our virtual hosts would be::
-
- nvh.addHost('divunal.com', divunalDirectory)
- nvh.addHost('www.divunal.com', divunalDirectory)
- nvh.addHost('twistedmatrix.com', twistedMatrixDirectory)
- nvh.addHost('www.twistedmatrix.com', twistedMatrixDirectory)
- """
- self.hosts[name] = resrc
-
- def removeHost(self, name):
- """Remove a host."""
- del self.hosts[name]
-
- def _getResourceForRequest(self, request):
- """(Internal) Get the appropriate resource for the given host.
- """
- hostHeader = request.getHeader('host')
- if hostHeader == None:
- return self.default or resource.NoResource()
- else:
- host = hostHeader.lower().split(':', 1)[0]
- return (self.hosts.get(host, self.default)
- or resource.NoResource("host %s not in vhost map" % repr(host)))
-
- def render(self, request):
- """Implementation of resource.Resource's render method.
- """
- resrc = self._getResourceForRequest(request)
- return resrc.render(request)
-
- def getChild(self, path, request):
- """Implementation of resource.Resource's getChild method.
- """
- resrc = self._getResourceForRequest(request)
- if resrc.isLeaf:
- request.postpath.insert(0,request.prepath.pop(-1))
- return resrc
- else:
- return resrc.getChildWithDefault(path, request)
-
-class _HostResource(resource.Resource):
-
- def getChild(self, path, request):
- if ':' in path:
- host, port = path.split(':', 1)
- port = int(port)
- else:
- host, port = path, 80
- request.setHost(host, port)
- prefixLen = 3+request.isSecure()+4+len(path)+len(request.prepath[-3])
- request.path = '/'+'/'.join(request.postpath)
- request.uri = request.uri[prefixLen:]
- del request.prepath[:3]
- return request.site.getResourceFor(request)
-
-
-class VHostMonsterResource(resource.Resource):
-
- """
- Use this to be able to record the hostname and method (http vs. https)
- in the URL without disturbing your web site. If you put this resource
- in a URL http://foo.com/bar then requests to
- http://foo.com/bar/http/baz.com/something will be equivalent to
- http://foo.com/something, except that the hostname the request will
- appear to be accessing will be "baz.com". So if "baz.com" is redirecting
- all requests for to foo.com, while foo.com is inaccessible from the outside,
- then redirect and url generation will work correctly
- """
- def getChild(self, path, request):
- if path == 'http':
- request.isSecure = lambda: 0
- elif path == 'https':
- request.isSecure = lambda: 1
- return _HostResource()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/wsgi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/wsgi.py
deleted file mode 100755
index 0918c4d8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/wsgi.py
+++ /dev/null
@@ -1,403 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-An implementation of
-U{Web Resource Gateway Interface<http://www.python.org/dev/peps/pep-0333/>}.
-"""
-
-__metaclass__ = type
-
-from sys import exc_info
-
-from zope.interface import implements
-
-from twisted.python.log import msg, err
-from twisted.python.failure import Failure
-from twisted.web.resource import IResource
-from twisted.web.server import NOT_DONE_YET
-from twisted.web.http import INTERNAL_SERVER_ERROR
-
-
-class _ErrorStream:
- """
- File-like object instances of which are used as the value for the
- C{'wsgi.errors'} key in the C{environ} dictionary passed to the application
- object.
-
- This simply passes writes on to L{logging<twisted.python.log>} system as
- error events from the C{'wsgi'} system. In the future, it may be desirable
- to expose more information in the events it logs, such as the application
- object which generated the message.
- """
- def write(self, bytes):
- """
- Generate an event for the logging system with the given bytes as the
- message.
-
- This is called in a WSGI application thread, not the I/O thread.
- """
- msg(bytes, system='wsgi', isError=True)
-
-
- def writelines(self, iovec):
- """
- Join the given lines and pass them to C{write} to be handled in the
- usual way.
-
- This is called in a WSGI application thread, not the I/O thread.
-
- @param iovec: A C{list} of C{'\\n'}-terminated C{str} which will be
- logged.
- """
- self.write(''.join(iovec))
-
-
- def flush(self):
- """
- Nothing is buffered, so flushing does nothing. This method is required
- to exist by PEP 333, though.
-
- This is called in a WSGI application thread, not the I/O thread.
- """
-
-
-
-class _InputStream:
- """
- File-like object instances of which are used as the value for the
- C{'wsgi.input'} key in the C{environ} dictionary passed to the application
- object.
-
- This only exists to make the handling of C{readline(-1)} consistent across
- different possible underlying file-like object implementations. The other
- supported methods pass through directly to the wrapped object.
- """
- def __init__(self, input):
- """
- Initialize the instance.
-
- This is called in the I/O thread, not a WSGI application thread.
- """
- self._wrapped = input
-
-
- def read(self, size=None):
- """
- Pass through to the underlying C{read}.
-
- This is called in a WSGI application thread, not the I/O thread.
- """
- # Avoid passing None because cStringIO and file don't like it.
- if size is None:
- return self._wrapped.read()
- return self._wrapped.read(size)
-
-
- def readline(self, size=None):
- """
- Pass through to the underlying C{readline}, with a size of C{-1} replaced
- with a size of C{None}.
-
- This is called in a WSGI application thread, not the I/O thread.
- """
- # Check for -1 because StringIO doesn't handle it correctly. Check for
- # None because files and tempfiles don't accept that.
- if size == -1 or size is None:
- return self._wrapped.readline()
- return self._wrapped.readline(size)
-
-
- def readlines(self, size=None):
- """
- Pass through to the underlying C{readlines}.
-
- This is called in a WSGI application thread, not the I/O thread.
- """
- # Avoid passing None because cStringIO and file don't like it.
- if size is None:
- return self._wrapped.readlines()
- return self._wrapped.readlines(size)
-
-
- def __iter__(self):
- """
- Pass through to the underlying C{__iter__}.
-
- This is called in a WSGI application thread, not the I/O thread.
- """
- return iter(self._wrapped)
-
-
-
-class _WSGIResponse:
- """
- Helper for L{WSGIResource} which drives the WSGI application using a
- threadpool and hooks it up to the L{Request}.
-
- @ivar started: A C{bool} indicating whether or not the response status and
- headers have been written to the request yet. This may only be read or
- written in the WSGI application thread.
-
- @ivar reactor: An L{IReactorThreads} provider which is used to call methods
- on the request in the I/O thread.
-
- @ivar threadpool: A L{ThreadPool} which is used to call the WSGI
- application object in a non-I/O thread.
-
- @ivar application: The WSGI application object.
-
- @ivar request: The L{Request} upon which the WSGI environment is based and
- to which the application's output will be sent.
-
- @ivar environ: The WSGI environment C{dict}.
-
- @ivar status: The HTTP response status C{str} supplied to the WSGI
- I{start_response} callable by the application.
-
- @ivar headers: A list of HTTP response headers supplied to the WSGI
- I{start_response} callable by the application.
-
- @ivar _requestFinished: A flag which indicates whether it is possible to
- generate more response data or not. This is C{False} until
- L{Request.notifyFinish} tells us the request is done, then C{True}.
- """
-
- _requestFinished = False
-
- def __init__(self, reactor, threadpool, application, request):
- self.started = False
- self.reactor = reactor
- self.threadpool = threadpool
- self.application = application
- self.request = request
- self.request.notifyFinish().addBoth(self._finished)
-
- if request.prepath:
- scriptName = '/' + '/'.join(request.prepath)
- else:
- scriptName = ''
-
- if request.postpath:
- pathInfo = '/' + '/'.join(request.postpath)
- else:
- pathInfo = ''
-
- parts = request.uri.split('?', 1)
- if len(parts) == 1:
- queryString = ''
- else:
- queryString = parts[1]
-
- self.environ = {
- 'REQUEST_METHOD': request.method,
- 'REMOTE_ADDR': request.getClientIP(),
- 'SCRIPT_NAME': scriptName,
- 'PATH_INFO': pathInfo,
- 'QUERY_STRING': queryString,
- 'CONTENT_TYPE': request.getHeader('content-type') or '',
- 'CONTENT_LENGTH': request.getHeader('content-length') or '',
- 'SERVER_NAME': request.getRequestHostname(),
- 'SERVER_PORT': str(request.getHost().port),
- 'SERVER_PROTOCOL': request.clientproto}
-
-
- # The application object is entirely in control of response headers;
- # disable the default Content-Type value normally provided by
- # twisted.web.server.Request.
- self.request.defaultContentType = None
-
- for name, values in request.requestHeaders.getAllRawHeaders():
- name = 'HTTP_' + name.upper().replace('-', '_')
- # It might be preferable for http.HTTPChannel to clear out
- # newlines.
- self.environ[name] = ','.join([
- v.replace('\n', ' ') for v in values])
-
- self.environ.update({
- 'wsgi.version': (1, 0),
- 'wsgi.url_scheme': request.isSecure() and 'https' or 'http',
- 'wsgi.run_once': False,
- 'wsgi.multithread': True,
- 'wsgi.multiprocess': False,
- 'wsgi.errors': _ErrorStream(),
- # Attend: request.content was owned by the I/O thread up until
- # this point. By wrapping it and putting the result into the
- # environment dictionary, it is effectively being given to
- # another thread. This means that whatever it is, it has to be
- # safe to access it from two different threads. The access
- # *should* all be serialized (first the I/O thread writes to
- # it, then the WSGI thread reads from it, then the I/O thread
- # closes it). However, since the request is made available to
- # arbitrary application code during resource traversal, it's
- # possible that some other code might decide to use it in the
- # I/O thread concurrently with its use in the WSGI thread.
- # More likely than not, this will break. This seems like an
- # unlikely possibility to me, but if it is to be allowed,
- # something here needs to change. -exarkun
- 'wsgi.input': _InputStream(request.content)})
-
-
- def _finished(self, ignored):
- """
- Record the end of the response generation for the request being
- serviced.
- """
- self._requestFinished = True
-
-
- def startResponse(self, status, headers, excInfo=None):
- """
- The WSGI I{start_response} callable. The given values are saved until
- they are needed to generate the response.
-
- This will be called in a non-I/O thread.
- """
- if self.started and excInfo is not None:
- raise excInfo[0], excInfo[1], excInfo[2]
- self.status = status
- self.headers = headers
- return self.write
-
-
- def write(self, bytes):
- """
- The WSGI I{write} callable returned by the I{start_response} callable.
- The given bytes will be written to the response body, possibly flushing
- the status and headers first.
-
- This will be called in a non-I/O thread.
- """
- def wsgiWrite(started):
- if not started:
- self._sendResponseHeaders()
- self.request.write(bytes)
- self.reactor.callFromThread(wsgiWrite, self.started)
- self.started = True
-
-
- def _sendResponseHeaders(self):
- """
- Set the response code and response headers on the request object, but
- do not flush them. The caller is responsible for doing a write in
- order for anything to actually be written out in response to the
- request.
-
- This must be called in the I/O thread.
- """
- code, message = self.status.split(None, 1)
- code = int(code)
- self.request.setResponseCode(code, message)
-
- for name, value in self.headers:
- # Don't allow the application to control these required headers.
- if name.lower() not in ('server', 'date'):
- self.request.responseHeaders.addRawHeader(name, value)
-
-
- def start(self):
- """
- Start the WSGI application in the threadpool.
-
- This must be called in the I/O thread.
- """
- self.threadpool.callInThread(self.run)
-
-
- def run(self):
- """
- Call the WSGI application object, iterate it, and handle its output.
-
- This must be called in a non-I/O thread (ie, a WSGI application
- thread).
- """
- try:
- appIterator = self.application(self.environ, self.startResponse)
- for elem in appIterator:
- if elem:
- self.write(elem)
- if self._requestFinished:
- break
- close = getattr(appIterator, 'close', None)
- if close is not None:
- close()
- except:
- def wsgiError(started, type, value, traceback):
- err(Failure(value, type, traceback), "WSGI application error")
- if started:
- self.request.transport.loseConnection()
- else:
- self.request.setResponseCode(INTERNAL_SERVER_ERROR)
- self.request.finish()
- self.reactor.callFromThread(wsgiError, self.started, *exc_info())
- else:
- def wsgiFinish(started):
- if not self._requestFinished:
- if not started:
- self._sendResponseHeaders()
- self.request.finish()
- self.reactor.callFromThread(wsgiFinish, self.started)
- self.started = True
-
-
-
-class WSGIResource:
- """
- An L{IResource} implementation which delegates responsibility for all
- resources hierarchically inferior to it to a WSGI application.
-
- @ivar _reactor: An L{IReactorThreads} provider which will be passed on to
- L{_WSGIResponse} to schedule calls in the I/O thread.
-
- @ivar _threadpool: A L{ThreadPool} which will be passed on to
- L{_WSGIResponse} to run the WSGI application object.
-
- @ivar _application: The WSGI application object.
- """
- implements(IResource)
-
- # Further resource segments are left up to the WSGI application object to
- # handle.
- isLeaf = True
-
- def __init__(self, reactor, threadpool, application):
- self._reactor = reactor
- self._threadpool = threadpool
- self._application = application
-
-
- def render(self, request):
- """
- Turn the request into the appropriate C{environ} C{dict} suitable to be
- passed to the WSGI application object and then pass it on.
-
- The WSGI application object is given almost complete control of the
- rendering process. C{NOT_DONE_YET} will always be returned in order
- and response completion will be dictated by the application object, as
- will the status, headers, and the response body.
- """
- response = _WSGIResponse(
- self._reactor, self._threadpool, self._application, request)
- response.start()
- return NOT_DONE_YET
-
-
- def getChildWithDefault(self, name, request):
- """
- Reject attempts to retrieve a child resource. All path segments beyond
- the one which refers to this resource are handled by the WSGI
- application object.
- """
- raise RuntimeError("Cannot get IResource children from WSGIResource")
-
-
- def putChild(self, path, child):
- """
- Reject attempts to add a child resource to this resource. The WSGI
- application object handles all path segments beneath this resource, so
- L{IResource} children can never be found.
- """
- raise RuntimeError("Cannot put IResource children under WSGIResource")
-
-
-__all__ = ['WSGIResource']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/xmlrpc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/xmlrpc.py
deleted file mode 100755
index cbcb7b0f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/xmlrpc.py
+++ /dev/null
@@ -1,590 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_xmlrpc -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A generic resource for publishing objects via XML-RPC.
-
-Maintainer: Itamar Shtull-Trauring
-"""
-
-# System Imports
-import sys, xmlrpclib, urlparse
-
-
-# Sibling Imports
-from twisted.web import resource, server, http
-from twisted.internet import defer, protocol, reactor
-from twisted.python import log, reflect, failure
-
-# These are deprecated, use the class level definitions
-NOT_FOUND = 8001
-FAILURE = 8002
-
-
-# Useful so people don't need to import xmlrpclib directly
-Fault = xmlrpclib.Fault
-Binary = xmlrpclib.Binary
-Boolean = xmlrpclib.Boolean
-DateTime = xmlrpclib.DateTime
-
-# On Python 2.4 and earlier, DateTime.decode returns unicode.
-if sys.version_info[:2] < (2, 5):
- _decode = DateTime.decode
- DateTime.decode = lambda self, value: _decode(self, value.encode('ascii'))
-
-
-def withRequest(f):
- """
- Decorator to cause the request to be passed as the first argument
- to the method.
-
- If an I{xmlrpc_} method is wrapped with C{withRequest}, the
- request object is passed as the first argument to that method.
- For example::
-
- @withRequest
- def xmlrpc_echo(self, request, s):
- return s
-
- @since: 10.2
- """
- f.withRequest = True
- return f
-
-
-
-class NoSuchFunction(Fault):
- """
- There is no function by the given name.
- """
-
-
-class Handler:
- """
- Handle a XML-RPC request and store the state for a request in progress.
-
- Override the run() method and return result using self.result,
- a Deferred.
-
- We require this class since we're not using threads, so we can't
- encapsulate state in a running function if we're going to have
- to wait for results.
-
- For example, lets say we want to authenticate against twisted.cred,
- run a LDAP query and then pass its result to a database query, all
- as a result of a single XML-RPC command. We'd use a Handler instance
- to store the state of the running command.
- """
-
- def __init__(self, resource, *args):
- self.resource = resource # the XML-RPC resource we are connected to
- self.result = defer.Deferred()
- self.run(*args)
-
- def run(self, *args):
- # event driven equivalent of 'raise UnimplementedError'
- self.result.errback(
- NotImplementedError("Implement run() in subclasses"))
-
-
-class XMLRPC(resource.Resource):
- """
- A resource that implements XML-RPC.
-
- You probably want to connect this to '/RPC2'.
-
- Methods published can return XML-RPC serializable results, Faults,
- Binary, Boolean, DateTime, Deferreds, or Handler instances.
-
- By default methods beginning with 'xmlrpc_' are published.
-
- Sub-handlers for prefixed methods (e.g., system.listMethods)
- can be added with putSubHandler. By default, prefixes are
- separated with a '.'. Override self.separator to change this.
-
- @ivar allowNone: Permit XML translating of Python constant None.
- @type allowNone: C{bool}
-
- @ivar useDateTime: Present datetime values as datetime.datetime objects?
- Requires Python >= 2.5.
- @type useDateTime: C{bool}
- """
-
- # Error codes for Twisted, if they conflict with yours then
- # modify them at runtime.
- NOT_FOUND = 8001
- FAILURE = 8002
-
- isLeaf = 1
- separator = '.'
- allowedMethods = ('POST',)
-
- def __init__(self, allowNone=False, useDateTime=False):
- resource.Resource.__init__(self)
- self.subHandlers = {}
- self.allowNone = allowNone
- self.useDateTime = useDateTime
-
-
- def __setattr__(self, name, value):
- if name == "useDateTime" and value and sys.version_info[:2] < (2, 5):
- raise RuntimeError("useDateTime requires Python 2.5 or later.")
- self.__dict__[name] = value
-
-
- def putSubHandler(self, prefix, handler):
- self.subHandlers[prefix] = handler
-
- def getSubHandler(self, prefix):
- return self.subHandlers.get(prefix, None)
-
- def getSubHandlerPrefixes(self):
- return self.subHandlers.keys()
-
- def render_POST(self, request):
- request.content.seek(0, 0)
- request.setHeader("content-type", "text/xml")
- try:
- if self.useDateTime:
- args, functionPath = xmlrpclib.loads(request.content.read(),
- use_datetime=True)
- else:
- # Maintain backwards compatibility with Python < 2.5
- args, functionPath = xmlrpclib.loads(request.content.read())
- except Exception, e:
- f = Fault(self.FAILURE, "Can't deserialize input: %s" % (e,))
- self._cbRender(f, request)
- else:
- try:
- function = self.lookupProcedure(functionPath)
- except Fault, f:
- self._cbRender(f, request)
- else:
- # Use this list to track whether the response has failed or not.
- # This will be used later on to decide if the result of the
- # Deferred should be written out and Request.finish called.
- responseFailed = []
- request.notifyFinish().addErrback(responseFailed.append)
- if getattr(function, 'withRequest', False):
- d = defer.maybeDeferred(function, request, *args)
- else:
- d = defer.maybeDeferred(function, *args)
- d.addErrback(self._ebRender)
- d.addCallback(self._cbRender, request, responseFailed)
- return server.NOT_DONE_YET
-
-
- def _cbRender(self, result, request, responseFailed=None):
- if responseFailed:
- return
-
- if isinstance(result, Handler):
- result = result.result
- if not isinstance(result, Fault):
- result = (result,)
- try:
- try:
- content = xmlrpclib.dumps(
- result, methodresponse=True,
- allow_none=self.allowNone)
- except Exception, e:
- f = Fault(self.FAILURE, "Can't serialize output: %s" % (e,))
- content = xmlrpclib.dumps(f, methodresponse=True,
- allow_none=self.allowNone)
-
- request.setHeader("content-length", str(len(content)))
- request.write(content)
- except:
- log.err()
- request.finish()
-
-
- def _ebRender(self, failure):
- if isinstance(failure.value, Fault):
- return failure.value
- log.err(failure)
- return Fault(self.FAILURE, "error")
-
-
- def lookupProcedure(self, procedurePath):
- """
- Given a string naming a procedure, return a callable object for that
- procedure or raise NoSuchFunction.
-
- The returned object will be called, and should return the result of the
- procedure, a Deferred, or a Fault instance.
-
- Override in subclasses if you want your own policy. The base
- implementation that given C{'foo'}, C{self.xmlrpc_foo} will be returned.
- If C{procedurePath} contains C{self.separator}, the sub-handler for the
- initial prefix is used to search for the remaining path.
-
- If you override C{lookupProcedure}, you may also want to override
- C{listProcedures} to accurately report the procedures supported by your
- resource, so that clients using the I{system.listMethods} procedure
- receive accurate results.
-
- @since: 11.1
- """
- if procedurePath.find(self.separator) != -1:
- prefix, procedurePath = procedurePath.split(self.separator, 1)
- handler = self.getSubHandler(prefix)
- if handler is None:
- raise NoSuchFunction(self.NOT_FOUND,
- "no such subHandler %s" % prefix)
- return handler.lookupProcedure(procedurePath)
-
- f = getattr(self, "xmlrpc_%s" % procedurePath, None)
- if not f:
- raise NoSuchFunction(self.NOT_FOUND,
- "procedure %s not found" % procedurePath)
- elif not callable(f):
- raise NoSuchFunction(self.NOT_FOUND,
- "procedure %s not callable" % procedurePath)
- else:
- return f
-
- def listProcedures(self):
- """
- Return a list of the names of all xmlrpc procedures.
-
- @since: 11.1
- """
- return reflect.prefixedMethodNames(self.__class__, 'xmlrpc_')
-
-
-class XMLRPCIntrospection(XMLRPC):
- """
- Implement the XML-RPC Introspection API.
-
- By default, the methodHelp method returns the 'help' method attribute,
- if it exists, otherwise the __doc__ method attribute, if it exists,
- otherwise the empty string.
-
- To enable the methodSignature method, add a 'signature' method attribute
- containing a list of lists. See methodSignature's documentation for the
- format. Note the type strings should be XML-RPC types, not Python types.
- """
-
- def __init__(self, parent):
- """
- Implement Introspection support for an XMLRPC server.
-
- @param parent: the XMLRPC server to add Introspection support to.
- @type parent: L{XMLRPC}
- """
- XMLRPC.__init__(self)
- self._xmlrpc_parent = parent
-
- def xmlrpc_listMethods(self):
- """
- Return a list of the method names implemented by this server.
- """
- functions = []
- todo = [(self._xmlrpc_parent, '')]
- while todo:
- obj, prefix = todo.pop(0)
- functions.extend([prefix + name for name in obj.listProcedures()])
- todo.extend([ (obj.getSubHandler(name),
- prefix + name + obj.separator)
- for name in obj.getSubHandlerPrefixes() ])
- return functions
-
- xmlrpc_listMethods.signature = [['array']]
-
- def xmlrpc_methodHelp(self, method):
- """
- Return a documentation string describing the use of the given method.
- """
- method = self._xmlrpc_parent.lookupProcedure(method)
- return (getattr(method, 'help', None)
- or getattr(method, '__doc__', None) or '')
-
- xmlrpc_methodHelp.signature = [['string', 'string']]
-
- def xmlrpc_methodSignature(self, method):
- """
- Return a list of type signatures.
-
- Each type signature is a list of the form [rtype, type1, type2, ...]
- where rtype is the return type and typeN is the type of the Nth
- argument. If no signature information is available, the empty
- string is returned.
- """
- method = self._xmlrpc_parent.lookupProcedure(method)
- return getattr(method, 'signature', None) or ''
-
- xmlrpc_methodSignature.signature = [['array', 'string'],
- ['string', 'string']]
-
-
-def addIntrospection(xmlrpc):
- """
- Add Introspection support to an XMLRPC server.
-
- @param parent: the XMLRPC server to add Introspection support to.
- @type parent: L{XMLRPC}
- """
- xmlrpc.putSubHandler('system', XMLRPCIntrospection(xmlrpc))
-
-
-class QueryProtocol(http.HTTPClient):
-
- def connectionMade(self):
- self._response = None
- self.sendCommand('POST', self.factory.path)
- self.sendHeader('User-Agent', 'Twisted/XMLRPClib')
- self.sendHeader('Host', self.factory.host)
- self.sendHeader('Content-type', 'text/xml')
- self.sendHeader('Content-length', str(len(self.factory.payload)))
- if self.factory.user:
- auth = '%s:%s' % (self.factory.user, self.factory.password)
- auth = auth.encode('base64').strip()
- self.sendHeader('Authorization', 'Basic %s' % (auth,))
- self.endHeaders()
- self.transport.write(self.factory.payload)
-
- def handleStatus(self, version, status, message):
- if status != '200':
- self.factory.badStatus(status, message)
-
- def handleResponse(self, contents):
- """
- Handle the XML-RPC response received from the server.
-
- Specifically, disconnect from the server and store the XML-RPC
- response so that it can be properly handled when the disconnect is
- finished.
- """
- self.transport.loseConnection()
- self._response = contents
-
- def connectionLost(self, reason):
- """
- The connection to the server has been lost.
-
- If we have a full response from the server, then parse it and fired a
- Deferred with the return value or C{Fault} that the server gave us.
- """
- http.HTTPClient.connectionLost(self, reason)
- if self._response is not None:
- response, self._response = self._response, None
- self.factory.parseResponse(response)
-
-
-payloadTemplate = """<?xml version="1.0"?>
-<methodCall>
-<methodName>%s</methodName>
-%s
-</methodCall>
-"""
-
-
-class _QueryFactory(protocol.ClientFactory):
- """
- XML-RPC Client Factory
-
- @ivar path: The path portion of the URL to which to post method calls.
- @type path: C{str}
-
- @ivar host: The value to use for the Host HTTP header.
- @type host: C{str}
-
- @ivar user: The username with which to authenticate with the server
- when making calls.
- @type user: C{str} or C{NoneType}
-
- @ivar password: The password with which to authenticate with the server
- when making calls.
- @type password: C{str} or C{NoneType}
-
- @ivar useDateTime: Accept datetime values as datetime.datetime objects.
- also passed to the underlying xmlrpclib implementation. Default to
- False. Requires Python >= 2.5.
- @type useDateTime: C{bool}
- """
-
- deferred = None
- protocol = QueryProtocol
-
- def __init__(self, path, host, method, user=None, password=None,
- allowNone=False, args=(), canceller=None, useDateTime=False):
- """
- @param method: The name of the method to call.
- @type method: C{str}
-
- @param allowNone: allow the use of None values in parameters. It's
- passed to the underlying xmlrpclib implementation. Default to False.
- @type allowNone: C{bool} or C{NoneType}
-
- @param args: the arguments to pass to the method.
- @type args: C{tuple}
-
- @param canceller: A 1-argument callable passed to the deferred as the
- canceller callback.
- @type canceller: callable or C{NoneType}
- """
- self.path, self.host = path, host
- self.user, self.password = user, password
- self.payload = payloadTemplate % (method,
- xmlrpclib.dumps(args, allow_none=allowNone))
- self.deferred = defer.Deferred(canceller)
- self.useDateTime = useDateTime
-
- def parseResponse(self, contents):
- if not self.deferred:
- return
- try:
- if self.useDateTime:
- response = xmlrpclib.loads(contents,
- use_datetime=True)[0][0]
- else:
- # Maintain backwards compatibility with Python < 2.5
- response = xmlrpclib.loads(contents)[0][0]
- except:
- deferred, self.deferred = self.deferred, None
- deferred.errback(failure.Failure())
- else:
- deferred, self.deferred = self.deferred, None
- deferred.callback(response)
-
- def clientConnectionLost(self, _, reason):
- if self.deferred is not None:
- deferred, self.deferred = self.deferred, None
- deferred.errback(reason)
-
- clientConnectionFailed = clientConnectionLost
-
- def badStatus(self, status, message):
- deferred, self.deferred = self.deferred, None
- deferred.errback(ValueError(status, message))
-
-
-
-class Proxy:
- """
- A Proxy for making remote XML-RPC calls.
-
- Pass the URL of the remote XML-RPC server to the constructor.
-
- Use proxy.callRemote('foobar', *args) to call remote method
- 'foobar' with *args.
-
- @ivar user: The username with which to authenticate with the server
- when making calls. If specified, overrides any username information
- embedded in C{url}. If not specified, a value may be taken from
- C{url} if present.
- @type user: C{str} or C{NoneType}
-
- @ivar password: The password with which to authenticate with the server
- when making calls. If specified, overrides any password information
- embedded in C{url}. If not specified, a value may be taken from
- C{url} if present.
- @type password: C{str} or C{NoneType}
-
- @ivar allowNone: allow the use of None values in parameters. It's
- passed to the underlying xmlrpclib implementation. Default to False.
- @type allowNone: C{bool} or C{NoneType}
-
- @ivar useDateTime: Accept datetime values as datetime.datetime objects.
- also passed to the underlying xmlrpclib implementation. Default to
- False. Requires Python >= 2.5.
- @type useDateTime: C{bool}
-
- @ivar connectTimeout: Number of seconds to wait before assuming the
- connection has failed.
- @type connectTimeout: C{float}
-
- @ivar _reactor: the reactor used to create connections.
- @type _reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
-
- @ivar queryFactory: object returning a factory for XML-RPC protocol. Mainly
- useful for tests.
- """
- queryFactory = _QueryFactory
-
- def __init__(self, url, user=None, password=None, allowNone=False,
- useDateTime=False, connectTimeout=30.0, reactor=reactor):
- """
- @param url: The URL to which to post method calls. Calls will be made
- over SSL if the scheme is HTTPS. If netloc contains username or
- password information, these will be used to authenticate, as long as
- the C{user} and C{password} arguments are not specified.
- @type url: C{str}
-
- """
- scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
- netlocParts = netloc.split('@')
- if len(netlocParts) == 2:
- userpass = netlocParts.pop(0).split(':')
- self.user = userpass.pop(0)
- try:
- self.password = userpass.pop(0)
- except:
- self.password = None
- else:
- self.user = self.password = None
- hostport = netlocParts[0].split(':')
- self.host = hostport.pop(0)
- try:
- self.port = int(hostport.pop(0))
- except:
- self.port = None
- self.path = path
- if self.path in ['', None]:
- self.path = '/'
- self.secure = (scheme == 'https')
- if user is not None:
- self.user = user
- if password is not None:
- self.password = password
- self.allowNone = allowNone
- self.useDateTime = useDateTime
- self.connectTimeout = connectTimeout
- self._reactor = reactor
-
-
- def __setattr__(self, name, value):
- if name == "useDateTime" and value and sys.version_info[:2] < (2, 5):
- raise RuntimeError("useDateTime requires Python 2.5 or later.")
- self.__dict__[name] = value
-
-
- def callRemote(self, method, *args):
- """
- Call remote XML-RPC C{method} with given arguments.
-
- @return: a L{defer.Deferred} that will fire with the method response,
- or a failure if the method failed. Generally, the failure type will
- be L{Fault}, but you can also have an C{IndexError} on some buggy
- servers giving empty responses.
-
- If the deferred is cancelled before the request completes, the
- connection is closed and the deferred will fire with a
- L{defer.CancelledError}.
- """
- def cancel(d):
- factory.deferred = None
- connector.disconnect()
- factory = self.queryFactory(
- self.path, self.host, method, self.user,
- self.password, self.allowNone, args, cancel, self.useDateTime)
-
- if self.secure:
- from twisted.internet import ssl
- connector = self._reactor.connectSSL(
- self.host, self.port or 443,
- factory, ssl.ClientContextFactory(),
- timeout=self.connectTimeout)
- else:
- connector = self._reactor.connectTCP(
- self.host, self.port or 80, factory,
- timeout=self.connectTimeout)
- return factory.deferred
-
-
-__all__ = [
- "XMLRPC", "Handler", "NoSuchFunction", "Proxy",
-
- "Fault", "Binary", "Boolean", "DateTime"]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/__init__.py
deleted file mode 100755
index 3e38d15e..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Twisted Words: a Twisted Chat service.
-"""
-
-from twisted.words._version import version
-__version__ = version.short()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/_version.py
deleted file mode 100755
index 55be9a55..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/_version.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Do not edit it.
-from twisted.python import versions
-version = versions.Version('twisted.words', 12, 2, 0)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/ewords.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/ewords.py
deleted file mode 100755
index 7621a71b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/ewords.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""Exception definitions for Words
-"""
-
-class WordsError(Exception):
- def __str__(self):
- return self.__class__.__name__ + ': ' + Exception.__str__(self)
-
-class NoSuchUser(WordsError):
- pass
-
-
-class DuplicateUser(WordsError):
- pass
-
-
-class NoSuchGroup(WordsError):
- pass
-
-
-class DuplicateGroup(WordsError):
- pass
-
-
-class AlreadyLoggedIn(WordsError):
- pass
-
-__all__ = [
- 'WordsError', 'NoSuchUser', 'DuplicateUser',
- 'NoSuchGroup', 'DuplicateGroup', 'AlreadyLoggedIn',
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/__init__.py
deleted file mode 100755
index cf3492b8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""Instance Messenger, Pan-protocol chat client."""
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/baseaccount.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/baseaccount.py
deleted file mode 100755
index 0261dbf1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/baseaccount.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- Python -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-
-class AccountManager:
- """I am responsible for managing a user's accounts.
-
- That is, remembering what accounts are available, their settings,
- adding and removal of accounts, etc.
-
- @ivar accounts: A collection of available accounts.
- @type accounts: mapping of strings to L{Account<interfaces.IAccount>}s.
- """
- def __init__(self):
- self.accounts = {}
-
- def getSnapShot(self):
- """A snapshot of all the accounts and their status.
-
- @returns: A list of tuples, each of the form
- (string:accountName, boolean:isOnline,
- boolean:autoLogin, string:gatewayType)
- """
- data = []
- for account in self.accounts.values():
- data.append((account.accountName, account.isOnline(),
- account.autoLogin, account.gatewayType))
- return data
-
- def isEmpty(self):
- return len(self.accounts) == 0
-
- def getConnectionInfo(self):
- connectioninfo = []
- for account in self.accounts.values():
- connectioninfo.append(account.isOnline())
- return connectioninfo
-
- def addAccount(self, account):
- self.accounts[account.accountName] = account
-
- def delAccount(self, accountName):
- del self.accounts[accountName]
-
- def connect(self, accountName, chatui):
- """
- @returntype: Deferred L{interfaces.IClient}
- """
- return self.accounts[accountName].logOn(chatui)
-
- def disconnect(self, accountName):
- pass
- #self.accounts[accountName].logOff() - not yet implemented
-
- def quit(self):
- pass
- #for account in self.accounts.values():
- # account.logOff() - not yet implemented
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basechat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basechat.py
deleted file mode 100755
index 076275f4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basechat.py
+++ /dev/null
@@ -1,512 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_basechat -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Base classes for Instance Messenger clients.
-"""
-
-from twisted.words.im.locals import OFFLINE, ONLINE, AWAY
-
-
-class ContactsList:
- """
- A GUI object that displays a contacts list.
-
- @ivar chatui: The GUI chat client associated with this contacts list.
- @type chatui: L{ChatUI}
-
- @ivar contacts: The contacts.
- @type contacts: C{dict} mapping C{str} to a L{IPerson<interfaces.IPerson>}
- provider
-
- @ivar onlineContacts: The contacts who are currently online (have a status
- that is not C{OFFLINE}).
- @type onlineContacts: C{dict} mapping C{str} to a
- L{IPerson<interfaces.IPerson>} provider
-
- @ivar clients: The signed-on clients.
- @type clients: C{list} of L{IClient<interfaces.IClient>} providers
- """
- def __init__(self, chatui):
- """
- @param chatui: The GUI chat client associated with this contacts list.
- @type chatui: L{ChatUI}
- """
- self.chatui = chatui
- self.contacts = {}
- self.onlineContacts = {}
- self.clients = []
-
-
- def setContactStatus(self, person):
- """
- Inform the user that a person's status has changed.
-
- @param person: The person whose status has changed.
- @type person: L{IPerson<interfaces.IPerson>} provider
- """
- if not self.contacts.has_key(person.name):
- self.contacts[person.name] = person
- if not self.onlineContacts.has_key(person.name) and \
- (person.status == ONLINE or person.status == AWAY):
- self.onlineContacts[person.name] = person
- if self.onlineContacts.has_key(person.name) and \
- person.status == OFFLINE:
- del self.onlineContacts[person.name]
-
-
- def registerAccountClient(self, client):
- """
- Notify the user that an account client has been signed on to.
-
- @param client: The client being added to your list of account clients.
- @type client: L{IClient<interfaces.IClient>} provider
- """
- if not client in self.clients:
- self.clients.append(client)
-
-
- def unregisterAccountClient(self, client):
- """
- Notify the user that an account client has been signed off or
- disconnected from.
-
- @param client: The client being removed from the list of account
- clients.
- @type client: L{IClient<interfaces.IClient>} provider
- """
- if client in self.clients:
- self.clients.remove(client)
-
-
- def contactChangedNick(self, person, newnick):
- """
- Update your contact information to reflect a change to a contact's
- nickname.
-
- @param person: The person in your contacts list whose nickname is
- changing.
- @type person: L{IPerson<interfaces.IPerson>} provider
-
- @param newnick: The new nickname for this person.
- @type newnick: C{str}
- """
- oldname = person.name
- if oldname in self.contacts:
- del self.contacts[oldname]
- person.name = newnick
- self.contacts[newnick] = person
- if self.onlineContacts.has_key(oldname):
- del self.onlineContacts[oldname]
- self.onlineContacts[newnick] = person
-
-
-
-class Conversation:
- """
- A GUI window of a conversation with a specific person.
-
- @ivar person: The person who you're having this conversation with.
- @type person: L{IPerson<interfaces.IPerson>} provider
-
- @ivar chatui: The GUI chat client associated with this conversation.
- @type chatui: L{ChatUI}
- """
- def __init__(self, person, chatui):
- """
- @param person: The person who you're having this conversation with.
- @type person: L{IPerson<interfaces.IPerson>} provider
-
- @param chatui: The GUI chat client associated with this conversation.
- @type chatui: L{ChatUI}
- """
- self.chatui = chatui
- self.person = person
-
-
- def show(self):
- """
- Display the ConversationWindow.
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def hide(self):
- """
- Hide the ConversationWindow.
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def sendText(self, text):
- """
- Send text to the person with whom the user is conversing.
-
- @param text: The text to be sent.
- @type text: C{str}
- """
- self.person.sendMessage(text, None)
-
-
- def showMessage(self, text, metadata=None):
- """
- Display a message sent from the person with whom the user is conversing.
-
- @param text: The sent message.
- @type text: C{str}
-
- @param metadata: Metadata associated with this message.
- @type metadata: C{dict}
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def contactChangedNick(self, person, newnick):
- """
- Change a person's name.
-
- @param person: The person whose nickname is changing.
- @type person: L{IPerson<interfaces.IPerson>} provider
-
- @param newnick: The new nickname for this person.
- @type newnick: C{str}
- """
- self.person.name = newnick
-
-
-
-class GroupConversation:
- """
- A GUI window of a conversation with a group of people.
-
- @ivar chatui: The GUI chat client associated with this conversation.
- @type chatui: L{ChatUI}
-
- @ivar group: The group of people that are having this conversation.
- @type group: L{IGroup<interfaces.IGroup>} provider
-
- @ivar members: The names of the people in this conversation.
- @type members: C{list} of C{str}
- """
- def __init__(self, group, chatui):
- """
- @param chatui: The GUI chat client associated with this conversation.
- @type chatui: L{ChatUI}
-
- @param group: The group of people that are having this conversation.
- @type group: L{IGroup<interfaces.IGroup>} provider
- """
- self.chatui = chatui
- self.group = group
- self.members = []
-
-
- def show(self):
- """
- Display the GroupConversationWindow.
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def hide(self):
- """
- Hide the GroupConversationWindow.
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def sendText(self, text):
- """
- Send text to the group.
-
- @param: The text to be sent.
- @type text: C{str}
- """
- self.group.sendGroupMessage(text, None)
-
-
- def showGroupMessage(self, sender, text, metadata=None):
- """
- Display to the user a message sent to this group from the given sender.
-
- @param sender: The person sending the message.
- @type sender: C{str}
-
- @param text: The sent message.
- @type text: C{str}
-
- @param metadata: Metadata associated with this message.
- @type metadata: C{dict}
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def setGroupMembers(self, members):
- """
- Set the list of members in the group.
-
- @param members: The names of the people that will be in this group.
- @type members: C{list} of C{str}
- """
- self.members = members
-
-
- def setTopic(self, topic, author):
- """
- Change the topic for the group conversation window and display this
- change to the user.
-
- @param topic: This group's topic.
- @type topic: C{str}
-
- @param author: The person changing the topic.
- @type author: C{str}
- """
- raise NotImplementedError("Subclasses must implement this method")
-
-
- def memberJoined(self, member):
- """
- Add the given member to the list of members in the group conversation
- and displays this to the user.
-
- @param member: The person joining the group conversation.
- @type member: C{str}
- """
- if not member in self.members:
- self.members.append(member)
-
-
- def memberChangedNick(self, oldnick, newnick):
- """
- Change the nickname for a member of the group conversation and displays
- this change to the user.
-
- @param oldnick: The old nickname.
- @type oldnick: C{str}
-
- @param newnick: The new nickname.
- @type newnick: C{str}
- """
- if oldnick in self.members:
- self.members.remove(oldnick)
- self.members.append(newnick)
-
-
- def memberLeft(self, member):
- """
- Delete the given member from the list of members in the group
- conversation and displays the change to the user.
-
- @param member: The person leaving the group conversation.
- @type member: C{str}
- """
- if member in self.members:
- self.members.remove(member)
-
-
-
-class ChatUI:
- """
- A GUI chat client.
-
- @type conversations: C{dict} of L{Conversation}
- @ivar conversations: A cache of all the direct windows.
-
- @type groupConversations: C{dict} of L{GroupConversation}
- @ivar groupConversations: A cache of all the group windows.
-
- @type persons: C{dict} with keys that are a C{tuple} of (C{str},
- L{IAccount<interfaces.IAccount>} provider) and values that are
- L{IPerson<interfaces.IPerson>} provider
- @ivar persons: A cache of all the users associated with this client.
-
- @type groups: C{dict} with keys that are a C{tuple} of (C{str},
- L{IAccount<interfaces.IAccount>} provider) and values that are
- L{IGroup<interfaces.IGroup>} provider
- @ivar groups: A cache of all the groups associated with this client.
-
- @type onlineClients: C{list} of L{IClient<interfaces.IClient>} providers
- @ivar onlineClients: A list of message sources currently online.
-
- @type contactsList: L{ContactsList}
- @ivar contactsList: A contacts list.
- """
- def __init__(self):
- self.conversations = {}
- self.groupConversations = {}
- self.persons = {}
- self.groups = {}
- self.onlineClients = []
- self.contactsList = ContactsList(self)
-
-
- def registerAccountClient(self, client):
- """
- Notify the user that an account has been signed on to.
-
- @type client: L{IClient<interfaces.IClient>} provider
- @param client: The client account for the person who has just signed on.
-
- @rtype client: L{IClient<interfaces.IClient>} provider
- @return: The client, so that it may be used in a callback chain.
- """
- self.onlineClients.append(client)
- self.contactsList.registerAccountClient(client)
- return client
-
-
- def unregisterAccountClient(self, client):
- """
- Notify the user that an account has been signed off or disconnected.
-
- @type client: L{IClient<interfaces.IClient>} provider
- @param client: The client account for the person who has just signed
- off.
- """
- self.onlineClients.remove(client)
- self.contactsList.unregisterAccountClient(client)
-
-
- def getContactsList(self):
- """
- Get the contacts list associated with this chat window.
-
- @rtype: L{ContactsList}
- @return: The contacts list associated with this chat window.
- """
- return self.contactsList
-
-
- def getConversation(self, person, Class=Conversation, stayHidden=False):
- """
- For the given person object, return the conversation window or create
- and return a new conversation window if one does not exist.
-
- @type person: L{IPerson<interfaces.IPerson>} provider
- @param person: The person whose conversation window we want to get.
-
- @type Class: L{IConversation<interfaces.IConversation>} implementor
- @param: The kind of conversation window we want. If the conversation
- window for this person didn't already exist, create one of this type.
-
- @type stayHidden: C{bool}
- @param stayHidden: Whether or not the conversation window should stay
- hidden.
-
- @rtype: L{IConversation<interfaces.IConversation>} provider
- @return: The conversation window.
- """
- conv = self.conversations.get(person)
- if not conv:
- conv = Class(person, self)
- self.conversations[person] = conv
- if stayHidden:
- conv.hide()
- else:
- conv.show()
- return conv
-
-
- def getGroupConversation(self, group, Class=GroupConversation,
- stayHidden=False):
- """
- For the given group object, return the group conversation window or
- create and return a new group conversation window if it doesn't exist.
-
- @type group: L{IGroup<interfaces.IGroup>} provider
- @param group: The group whose conversation window we want to get.
-
- @type Class: L{IConversation<interfaces.IConversation>} implementor
- @param: The kind of conversation window we want. If the conversation
- window for this person didn't already exist, create one of this type.
-
- @type stayHidden: C{bool}
- @param stayHidden: Whether or not the conversation window should stay
- hidden.
-
- @rtype: L{IGroupConversation<interfaces.IGroupConversation>} provider
- @return: The group conversation window.
- """
- conv = self.groupConversations.get(group)
- if not conv:
- conv = Class(group, self)
- self.groupConversations[group] = conv
- if stayHidden:
- conv.hide()
- else:
- conv.show()
- return conv
-
-
- def getPerson(self, name, client):
- """
- For the given name and account client, return an instance of a
- L{IGroup<interfaces.IPerson>} provider or create and return a new
- instance of a L{IGroup<interfaces.IPerson>} provider.
-
- @type name: C{str}
- @param name: The name of the person of interest.
-
- @type client: L{IClient<interfaces.IClient>} provider
- @param client: The client account of interest.
-
- @rtype: L{IPerson<interfaces.IPerson>} provider
- @return: The person with that C{name}.
- """
- account = client.account
- p = self.persons.get((name, account))
- if not p:
- p = account.getPerson(name)
- self.persons[name, account] = p
- return p
-
-
- def getGroup(self, name, client):
- """
- For the given name and account client, return an instance of a
- L{IGroup<interfaces.IGroup>} provider or create and return a new instance
- of a L{IGroup<interfaces.IGroup>} provider.
-
- @type name: C{str}
- @param name: The name of the group of interest.
-
- @type client: L{IClient<interfaces.IClient>} provider
- @param client: The client account of interest.
-
- @rtype: L{IGroup<interfaces.IGroup>} provider
- @return: The group with that C{name}.
- """
- # I accept 'client' instead of 'account' in my signature for
- # backwards compatibility. (Groups changed to be Account-oriented
- # in CVS revision 1.8.)
- account = client.account
- g = self.groups.get((name, account))
- if not g:
- g = account.getGroup(name)
- self.groups[name, account] = g
- return g
-
-
- def contactChangedNick(self, person, newnick):
- """
- For the given C{person}, change the C{person}'s C{name} to C{newnick}
- and tell the contact list and any conversation windows with that
- C{person} to change as well.
-
- @type person: L{IPerson<interfaces.IPerson>} provider
- @param person: The person whose nickname will get changed.
-
- @type newnick: C{str}
- @param newnick: The new C{name} C{person} will take.
- """
- oldnick = person.name
- if (oldnick, person.account) in self.persons:
- conv = self.conversations.get(person)
- if conv:
- conv.contactChangedNick(person, newnick)
- self.contactsList.contactChangedNick(person, newnick)
- del self.persons[oldnick, person.account]
- person.name = newnick
- self.persons[person.name, person.account] = person
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basesupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basesupport.py
deleted file mode 100755
index 5c8b424f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/basesupport.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-#
-
-"""Instance Messenger base classes for protocol support.
-
-You will find these useful if you're adding a new protocol to IM.
-"""
-
-# Abstract representation of chat "model" classes
-
-from twisted.words.im.locals import ONLINE, OFFLINE, OfflineError
-from twisted.words.im import interfaces
-
-from twisted.internet.protocol import Protocol
-
-from twisted.python.reflect import prefixedMethods
-from twisted.persisted import styles
-
-from twisted.internet import error
-
-class AbstractGroup:
- def __init__(self, name, account):
- self.name = name
- self.account = account
-
- def getGroupCommands(self):
- """finds group commands
-
- these commands are methods on me that start with imgroup_; they are
- called with no arguments
- """
- return prefixedMethods(self, "imgroup_")
-
- def getTargetCommands(self, target):
- """finds group commands
-
- these commands are methods on me that start with imgroup_; they are
- called with a user present within this room as an argument
-
- you may want to override this in your group in order to filter for
- appropriate commands on the given user
- """
- return prefixedMethods(self, "imtarget_")
-
- def join(self):
- if not self.account.client:
- raise OfflineError
- self.account.client.joinGroup(self.name)
-
- def leave(self):
- if not self.account.client:
- raise OfflineError
- self.account.client.leaveGroup(self.name)
-
- def __repr__(self):
- return '<%s %r>' % (self.__class__, self.name)
-
- def __str__(self):
- return '%s@%s' % (self.name, self.account.accountName)
-
-class AbstractPerson:
- def __init__(self, name, baseAccount):
- self.name = name
- self.account = baseAccount
- self.status = OFFLINE
-
- def getPersonCommands(self):
- """finds person commands
-
- these commands are methods on me that start with imperson_; they are
- called with no arguments
- """
- return prefixedMethods(self, "imperson_")
-
- def getIdleTime(self):
- """
- Returns a string.
- """
- return '--'
-
- def __repr__(self):
- return '<%s %r/%s>' % (self.__class__, self.name, self.status)
-
- def __str__(self):
- return '%s@%s' % (self.name, self.account.accountName)
-
-class AbstractClientMixin:
- """Designed to be mixed in to a Protocol implementing class.
-
- Inherit from me first.
-
- @ivar _logonDeferred: Fired when I am done logging in.
- """
- def __init__(self, account, chatui, logonDeferred):
- for base in self.__class__.__bases__:
- if issubclass(base, Protocol):
- self.__class__._protoBase = base
- break
- else:
- pass
- self.account = account
- self.chat = chatui
- self._logonDeferred = logonDeferred
-
- def connectionMade(self):
- self._protoBase.connectionMade(self)
-
- def connectionLost(self, reason):
- self.account._clientLost(self, reason)
- self.unregisterAsAccountClient()
- return self._protoBase.connectionLost(self, reason)
-
- def unregisterAsAccountClient(self):
- """Tell the chat UI that I have `signed off'.
- """
- self.chat.unregisterAccountClient(self)
-
-
-class AbstractAccount(styles.Versioned):
- """Base class for Accounts.
-
- I am the start of an implementation of L{IAccount<interfaces.IAccount>}, I
- implement L{isOnline} and most of L{logOn}, though you'll need to implement
- L{_startLogOn} in a subclass.
-
- @cvar _groupFactory: A Callable that will return a L{IGroup} appropriate
- for this account type.
- @cvar _personFactory: A Callable that will return a L{IPerson} appropriate
- for this account type.
-
- @type _isConnecting: boolean
- @ivar _isConnecting: Whether I am in the process of establishing a
- connection to the server.
- @type _isOnline: boolean
- @ivar _isOnline: Whether I am currently on-line with the server.
-
- @ivar accountName:
- @ivar autoLogin:
- @ivar username:
- @ivar password:
- @ivar host:
- @ivar port:
- """
-
- _isOnline = 0
- _isConnecting = 0
- client = None
-
- _groupFactory = AbstractGroup
- _personFactory = AbstractPerson
-
- persistanceVersion = 2
-
- def __init__(self, accountName, autoLogin, username, password, host, port):
- self.accountName = accountName
- self.autoLogin = autoLogin
- self.username = username
- self.password = password
- self.host = host
- self.port = port
-
- self._groups = {}
- self._persons = {}
-
- def upgrateToVersion2(self):
- # Added in CVS revision 1.16.
- for k in ('_groups', '_persons'):
- if not hasattr(self, k):
- setattr(self, k, {})
-
- def __getstate__(self):
- state = styles.Versioned.__getstate__(self)
- for k in ('client', '_isOnline', '_isConnecting'):
- try:
- del state[k]
- except KeyError:
- pass
- return state
-
- def isOnline(self):
- return self._isOnline
-
- def logOn(self, chatui):
- """Log on to this account.
-
- Takes care to not start a connection if a connection is
- already in progress. You will need to implement
- L{_startLogOn} for this to work, and it would be a good idea
- to override L{_loginFailed} too.
-
- @returntype: Deferred L{interfaces.IClient}
- """
- if (not self._isConnecting) and (not self._isOnline):
- self._isConnecting = 1
- d = self._startLogOn(chatui)
- d.addCallback(self._cb_logOn)
- # if chatui is not None:
- # (I don't particularly like having to pass chatUI to this function,
- # but we haven't factored it out yet.)
- d.addCallback(chatui.registerAccountClient)
- d.addErrback(self._loginFailed)
- return d
- else:
- raise error.ConnectError("Connection in progress")
-
- def getGroup(self, name):
- """Group factory.
-
- @param name: Name of the group on this account.
- @type name: string
- """
- group = self._groups.get(name)
- if group is None:
- group = self._groupFactory(name, self)
- self._groups[name] = group
- return group
-
- def getPerson(self, name):
- """Person factory.
-
- @param name: Name of the person on this account.
- @type name: string
- """
- person = self._persons.get(name)
- if person is None:
- person = self._personFactory(name, self)
- self._persons[name] = person
- return person
-
- def _startLogOn(self, chatui):
- """Start the sign on process.
-
- Factored out of L{logOn}.
-
- @returntype: Deferred L{interfaces.IClient}
- """
- raise NotImplementedError()
-
- def _cb_logOn(self, client):
- self._isConnecting = 0
- self._isOnline = 1
- self.client = client
- return client
-
- def _loginFailed(self, reason):
- """Errorback for L{logOn}.
-
- @type reason: Failure
-
- @returns: I{reason}, for further processing in the callback chain.
- @returntype: Failure
- """
- self._isConnecting = 0
- self._isOnline = 0 # just in case
- return reason
-
- def _clientLost(self, client, reason):
- self.client = None
- self._isConnecting = 0
- self._isOnline = 0
- return reason
-
- def __repr__(self):
- return "<%s: %s (%s@%s:%s)>" % (self.__class__,
- self.accountName,
- self.username,
- self.host,
- self.port)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/instancemessenger.glade b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/instancemessenger.glade
deleted file mode 100644
index 33ffaa27..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/instancemessenger.glade
+++ /dev/null
@@ -1,3165 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>InstanceMessenger</name>
- <program_name>instancemessenger</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
-</project>
-
-<widget>
- <class>GtkWindow</class>
- <name>UnseenConversationWindow</name>
- <visible>False</visible>
- <title>Unseen Conversation Window</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>ConversationWidget</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkVPaned</class>
- <name>vpaned1</name>
- <handle_size>10</handle_size>
- <gutter_size>6</gutter_size>
- <position>0</position>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow10</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <shrink>False</shrink>
- <resize>True</resize>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>ConversationOutput</name>
- <editable>False</editable>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow11</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <shrink>True</shrink>
- <resize>False</resize>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>ConversationMessageEntry</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <signal>
- <name>key_press_event</name>
- <handler>handle_key_press_event</handler>
- <last_modification_time>Tue, 29 Jan 2002 12:42:58 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text></text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox9</name>
- <homogeneous>True</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>3</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button42</name>
- <can_focus>True</can_focus>
- <label> Send Message </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>3</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>AddRemoveContact</name>
- <can_focus>True</can_focus>
- <label> Add Contact </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>3</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>CloseContact</name>
- <can_focus>True</can_focus>
- <label> Close </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>3</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>MainIMWindow</name>
- <signal>
- <name>destroy</name>
- <handler>on_MainIMWindow_destroy</handler>
- <last_modification_time>Sun, 21 Jul 2002 08:16:08 GMT</last_modification_time>
- </signal>
- <title>Instance Messenger</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>True</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkNotebook</class>
- <name>ContactsNotebook</name>
- <can_focus>True</can_focus>
- <signal>
- <name>key_press_event</name>
- <handler>on_ContactsWidget_key_press_event</handler>
- <last_modification_time>Tue, 07 May 2002 03:02:33 GMT</last_modification_time>
- </signal>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox11</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>OnlineCount</name>
- <label>Online: %d</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow14</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCTree</class>
- <name>OnlineContactsTree</name>
- <can_focus>True</can_focus>
- <signal>
- <name>tree_select_row</name>
- <handler>on_OnlineContactsTree_tree_select_row</handler>
- <last_modification_time>Tue, 07 May 2002 03:06:32 GMT</last_modification_time>
- </signal>
- <signal>
- <name>select_row</name>
- <handler>on_OnlineContactsTree_select_row</handler>
- <last_modification_time>Tue, 07 May 2002 04:36:10 GMT</last_modification_time>
- </signal>
- <columns>4</columns>
- <column_widths>109,35,23,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CTree:title</child_name>
- <name>label77</name>
- <label>Alias</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CTree:title</child_name>
- <name>label78</name>
- <label>Status</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CTree:title</child_name>
- <name>label79</name>
- <label>Idle</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CTree:title</child_name>
- <name>label80</name>
- <label>Account</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox30</name>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>1</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>ContactNameEntry</name>
- <can_focus>True</can_focus>
- <signal>
- <name>activate</name>
- <handler>on_ContactNameEntry_activate</handler>
- <last_modification_time>Tue, 07 May 2002 04:07:25 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>AccountsListPopup</name>
- <can_focus>True</can_focus>
- <items>Nothing
-To
-Speak
-Of
-</items>
- <initial_choice>1</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox7</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>PlainSendIM</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_PlainSendIM_clicked</handler>
- <last_modification_time>Tue, 29 Jan 2002 03:17:35 GMT</last_modification_time>
- </signal>
- <label> Send IM </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>PlainGetInfo</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_PlainGetInfo_clicked</handler>
- <last_modification_time>Tue, 07 May 2002 04:06:59 GMT</last_modification_time>
- </signal>
- <label> Get Info </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>PlainJoinChat</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_PlainJoinChat_clicked</handler>
- <last_modification_time>Tue, 29 Jan 2002 13:04:49 GMT</last_modification_time>
- </signal>
- <label> Join Group </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>PlainGoAway</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_PlainGoAway_clicked</handler>
- <last_modification_time>Tue, 07 May 2002 04:06:53 GMT</last_modification_time>
- </signal>
- <label> Go Away </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox8</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>AddContactButton</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_AddContactButton_clicked</handler>
- <last_modification_time>Tue, 07 May 2002 04:06:33 GMT</last_modification_time>
- </signal>
- <label> Add Contact </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>RemoveContactButton</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_RemoveContactButton_clicked</handler>
- <last_modification_time>Tue, 07 May 2002 04:06:28 GMT</last_modification_time>
- </signal>
- <label> Remove Contact </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label35</name>
- <label> Online Contacts </label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox14</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>OfflineContactsScroll</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>OfflineContactsList</name>
- <can_focus>True</can_focus>
- <signal>
- <name>select_row</name>
- <handler>on_OfflineContactsList_select_row</handler>
- <last_modification_time>Tue, 07 May 2002 03:00:07 GMT</last_modification_time>
- </signal>
- <columns>4</columns>
- <column_widths>66,80,80,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label41</name>
- <label>Contact</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label42</name>
- <label>Account</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label43</name>
- <label>Alias</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label44</name>
- <label>Group</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label36</name>
- <label> All Contacts </label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>AccountManWidget</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow12</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>accountsList</name>
- <can_focus>True</can_focus>
- <columns>4</columns>
- <column_widths>80,36,34,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label45</name>
- <label>Service Name</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label46</name>
- <label>Online</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label47</name>
- <label>Auto</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label48</name>
- <label>Gateway</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table5</name>
- <rows>2</rows>
- <columns>3</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
- <child>
- <padding>3</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>NewAccountButton</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_NewAccountButton_clicked</handler>
- <last_modification_time>Sun, 27 Jan 2002 10:32:20 GMT</last_modification_time>
- </signal>
- <label>New Account</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button46</name>
- <sensitive>False</sensitive>
- <can_default>True</can_default>
- <label>Modify Account</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>LogOnButton</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <signal>
- <name>clicked</name>
- <handler>on_LogOnButton_clicked</handler>
- <last_modification_time>Mon, 28 Jan 2002 04:06:23 GMT</last_modification_time>
- </signal>
- <label>Logon</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>DeleteAccountButton</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_DeleteAccountButton_clicked</handler>
- <last_modification_time>Mon, 28 Jan 2002 00:18:22 GMT</last_modification_time>
- </signal>
- <label>Delete Account</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>ConsoleButton</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_ConsoleButton_clicked</handler>
- <last_modification_time>Mon, 29 Apr 2002 09:13:32 GMT</last_modification_time>
- </signal>
- <label>Console</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button75</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Quit</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label107</name>
- <label>Accounts</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>UnseenGroupWindow</name>
- <visible>False</visible>
- <title>Unseen Group Window</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>GroupChatBox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox5</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>TopicEntry</name>
- <can_focus>True</can_focus>
- <signal>
- <name>activate</name>
- <handler>on_TopicEntry_activate</handler>
- <last_modification_time>Sat, 23 Feb 2002 02:57:41 GMT</last_modification_time>
- </signal>
- <signal>
- <name>focus_out_event</name>
- <handler>on_TopicEntry_focus_out_event</handler>
- <last_modification_time>Sun, 21 Jul 2002 09:36:54 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>&lt;TOPIC NOT RECEIVED&gt;</text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>AuthorLabel</name>
- <label>&lt;nobody&gt;</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>HideButton</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_HideButton_clicked</handler>
- <last_modification_time>Tue, 29 Jan 2002 14:10:00 GMT</last_modification_time>
- </signal>
- <label>&lt;</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVPaned</class>
- <name>vpaned2</name>
- <handle_size>10</handle_size>
- <gutter_size>6</gutter_size>
- <position>0</position>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHPaned</class>
- <name>GroupHPaned</name>
- <handle_size>6</handle_size>
- <gutter_size>6</gutter_size>
- <child>
- <shrink>False</shrink>
- <resize>True</resize>
- </child>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow4</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <shrink>False</shrink>
- <resize>True</resize>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>GroupOutput</name>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>actionvbox</name>
- <width>110</width>
- <homogeneous>False</homogeneous>
- <spacing>1</spacing>
- <child>
- <shrink>True</shrink>
- <resize>False</resize>
- </child>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow5</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>ParticipantList</name>
- <can_focus>True</can_focus>
- <signal>
- <name>select_row</name>
- <handler>on_ParticipantList_select_row</handler>
- <last_modification_time>Sat, 13 Jul 2002 08:11:12 GMT</last_modification_time>
- </signal>
- <signal>
- <name>unselect_row</name>
- <handler>on_ParticipantList_unselect_row</handler>
- <last_modification_time>Sat, 13 Jul 2002 08:23:25 GMT</last_modification_time>
- </signal>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label18</name>
- <label>Users</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame10</name>
- <label>Group</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>GroupActionsBox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>PersonFrame</name>
- <label>Person</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>PersonActionsBox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox6</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <shrink>True</shrink>
- <resize>False</resize>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>NickLabel</name>
- <label>&lt;no nick&gt;</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>4</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow9</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>GroupInput</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <signal>
- <name>key_press_event</name>
- <handler>handle_key_press_event</handler>
- <last_modification_time>Tue, 29 Jan 2002 12:41:03 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text></text>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>NewAccountWindow</name>
- <border_width>3</border_width>
- <visible>False</visible>
- <signal>
- <name>destroy</name>
- <handler>on_NewAccountWindow_destroy</handler>
- <last_modification_time>Sun, 27 Jan 2002 10:35:19 GMT</last_modification_time>
- </signal>
- <title>New Account</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>True</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox17</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox11</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>3</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label49</name>
- <label>Gateway:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>GatewayOptionMenu</name>
- <can_focus>True</can_focus>
- <items>Twisted (Perspective Broker)
-Internet Relay Chat
-AIM (TOC)
-AIM (OSCAR)
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>GatewayFrame</name>
- <border_width>3</border_width>
- <label>Gateway Options</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame2</name>
- <border_width>3</border_width>
- <label>Standard Options</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table1</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>AutoLogin</name>
- <can_focus>True</can_focus>
- <label>Automatically Log In</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>accountName</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label50</name>
- <label> Auto-Login: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label51</name>
- <label>Account Name: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox2</name>
- <layout_style>GTK_BUTTONBOX_SPREAD</layout_style>
- <spacing>30</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button50</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>createAccount</handler>
- <last_modification_time>Sun, 27 Jan 2002 11:25:05 GMT</last_modification_time>
- </signal>
- <label>OK</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button51</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>destroyMe</handler>
- <last_modification_time>Sun, 27 Jan 2002 11:27:12 GMT</last_modification_time>
- </signal>
- <label>Cancel</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>PBAccountWindow</name>
- <visible>False</visible>
- <title>PB Account Window</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>PBAccountWidget</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table3</name>
- <rows>4</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>hostname</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>twistedmatrix.com</text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>identity</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <signal>
- <name>changed</name>
- <handler>on_identity_changed</handler>
- <last_modification_time>Sun, 27 Jan 2002 11:52:17 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label52</name>
- <label> Hostname: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label54</name>
- <label>Identity Name: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>password</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>False</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>portno</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>8787</text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label55</name>
- <label> Password: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label53</name>
- <label> Port Number: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame3</name>
- <label>Perspectives</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox19</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow13</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>serviceList</name>
- <can_focus>True</can_focus>
- <signal>
- <name>select_row</name>
- <handler>on_serviceList_select_row</handler>
- <last_modification_time>Sun, 27 Jan 2002 12:04:38 GMT</last_modification_time>
- </signal>
- <columns>3</columns>
- <column_widths>80,80,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label60</name>
- <label>Service Type</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label61</name>
- <label>Service Name</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label62</name>
- <label>Perspective Name</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table4</name>
- <rows>3</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label63</name>
- <label>Perspective Name: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label59</name>
- <label> Service Type: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>serviceCombo</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items>twisted.words
-twisted.reality
-twisted.manhole
-</items>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>serviceType</name>
- <can_focus>True</can_focus>
- <signal>
- <name>changed</name>
- <handler>on_serviceType_changed</handler>
- <last_modification_time>Sun, 27 Jan 2002 11:49:07 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>twisted.words</text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label64</name>
- <label> Service Name: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>serviceName</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>perspectiveName</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox13</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button53</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>addPerspective</handler>
- <last_modification_time>Mon, 28 Jan 2002 01:07:15 GMT</last_modification_time>
- </signal>
- <label> Add Perspective </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button54</name>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>removePerspective</handler>
- <last_modification_time>Sun, 27 Jan 2002 11:34:36 GMT</last_modification_time>
- </signal>
- <label>Remove Perspective</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>IRCAccountWindow</name>
- <title>IRC Account Window</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkTable</class>
- <name>IRCAccountWidget</name>
- <rows>5</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label65</name>
- <label> Nickname: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label66</name>
- <label> Server: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label67</name>
- <label> Port: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label68</name>
- <label> Channels: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label69</name>
- <label> Password: </label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>ircNick</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>ircServer</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>ircPort</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>6667</text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>ircChannels</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>ircPassword</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>TOCAccountWindow</name>
- <title>TOC Account Window</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkTable</class>
- <name>TOCAccountWidget</name>
- <rows>4</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label70</name>
- <label> Screen Name: </label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label71</name>
- <label> Password: </label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label72</name>
- <label> Host: </label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label73</name>
- <label> Port: </label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>TOCName</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>TOCPass</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>False</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>TOCHost</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>toc.oscar.aol.com</text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>TOCPort</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>9898</text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>JoinGroupWindow</name>
- <border_width>5</border_width>
- <visible>False</visible>
- <title>Group to Join</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox20</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>AccountSelector</name>
- <can_focus>True</can_focus>
- <items>None
-In
-Particular
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox15</name>
- <homogeneous>False</homogeneous>
- <spacing>5</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>GroupNameEntry</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <signal>
- <name>activate</name>
- <handler>on_GroupJoinButton_clicked</handler>
- <last_modification_time>Tue, 29 Jan 2002 13:27:18 GMT</last_modification_time>
- </signal>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>GroupJoinButton</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_GroupJoinButton_clicked</handler>
- <last_modification_time>Tue, 29 Jan 2002 13:16:50 GMT</last_modification_time>
- </signal>
- <label>Join</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>UnifiedWindow</name>
- <title>Twisted Instance Messenger</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox25</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox28</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button74</name>
- <can_focus>True</can_focus>
- <label>&gt;</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry3</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>optionmenu3</name>
- <items>List
-Of
-Online
-Accounts
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>optionmenu4</name>
- <can_focus>True</can_focus>
- <items>Contact
-Person
-Group
-Account
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHPaned</class>
- <name>hpaned1</name>
- <handle_size>10</handle_size>
- <gutter_size>6</gutter_size>
- <position>0</position>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox26</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <shrink>True</shrink>
- <resize>False</resize>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame7</name>
- <border_width>2</border_width>
- <label>Accounts</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox27</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow18</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist4</name>
- <columns>4</columns>
- <column_widths>18,25,25,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label95</name>
- <label>label87</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label96</name>
- <label>label88</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label97</name>
- <label>label89</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label98</name>
- <label>label90</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox23</name>
- <homogeneous>True</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button65</name>
- <label>New</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button66</name>
- <label>Delete</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button67</name>
- <label>Connect</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame8</name>
- <border_width>2</border_width>
- <label>Contacts</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox28</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow19</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist5</name>
- <columns>3</columns>
- <column_widths>18,17,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label99</name>
- <label>label84</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label100</name>
- <label>label85</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label101</name>
- <label>label86</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox24</name>
- <homogeneous>True</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button68</name>
- <can_focus>True</can_focus>
- <label>Talk</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button69</name>
- <can_focus>True</can_focus>
- <label>Info</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button70</name>
- <can_focus>True</can_focus>
- <label>Add</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button71</name>
- <can_focus>True</can_focus>
- <label>Remove</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame9</name>
- <border_width>2</border_width>
- <label>Groups</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox29</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow20</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist6</name>
- <columns>3</columns>
- <column_widths>21,75,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label102</name>
- <label>label91</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label103</name>
- <label>label92</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label104</name>
- <label>label93</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox27</name>
- <homogeneous>True</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button72</name>
- <label>Join</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button73</name>
- <label>Leave</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator2</name>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label105</name>
- <label>Twisted IM V. %s</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>3</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label106</name>
- <label>This
-Space
-Left
-Intentionally
-Blank
-(Here is where the UI for the currently
-selected element
-for interaction
-will go.)</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <shrink>True</shrink>
- <resize>True</resize>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/interfaces.py
deleted file mode 100755
index 8f34fb1a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/interfaces.py
+++ /dev/null
@@ -1,364 +0,0 @@
-# -*- Python -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Pan-protocol chat client.
-"""
-
-from zope.interface import Interface, Attribute
-
-from twisted.words.im import locals
-
-# (Random musings, may not reflect on current state of code:)
-#
-# Accounts have Protocol components (clients)
-# Persons have Conversation components
-# Groups have GroupConversation components
-# Persons and Groups are associated with specific Accounts
-# At run-time, Clients/Accounts are slaved to a User Interface
-# (Note: User may be a bot, so don't assume all UIs are built on gui toolkits)
-
-
-class IAccount(Interface):
- """
- I represent a user's account with a chat service.
- """
-
- client = Attribute('The L{IClient} currently connecting to this account, if any.')
- gatewayType = Attribute('A C{str} that identifies the protocol used by this account.')
-
- def __init__(accountName, autoLogin, username, password, host, port):
- """
- @type accountName: string
- @param accountName: A name to refer to the account by locally.
- @type autoLogin: boolean
- @type username: string
- @type password: string
- @type host: string
- @type port: integer
- """
-
- def isOnline():
- """
- Am I online?
-
- @rtype: boolean
- """
-
- def logOn(chatui):
- """
- Go on-line.
-
- @type chatui: Implementor of C{IChatUI}
-
- @rtype: L{Deferred} L{Client}
- """
-
- def logOff():
- """
- Sign off.
- """
-
- def getGroup(groupName):
- """
- @rtype: L{Group<IGroup>}
- """
-
- def getPerson(personName):
- """
- @rtype: L{Person<IPerson>}
- """
-
-class IClient(Interface):
-
- account = Attribute('The L{IAccount} I am a Client for')
-
- def __init__(account, chatui, logonDeferred):
- """
- @type account: L{IAccount}
- @type chatui: L{IChatUI}
- @param logonDeferred: Will be called back once I am logged on.
- @type logonDeferred: L{Deferred<twisted.internet.defer.Deferred>}
- """
-
- def joinGroup(groupName):
- """
- @param groupName: The name of the group to join.
- @type groupName: string
- """
-
- def leaveGroup(groupName):
- """
- @param groupName: The name of the group to leave.
- @type groupName: string
- """
-
- def getGroupConversation(name, hide=0):
- pass
-
- def getPerson(name):
- pass
-
-
-class IPerson(Interface):
-
- def __init__(name, account):
- """
- Initialize me.
-
- @param name: My name, as the server knows me.
- @type name: string
- @param account: The account I am accessed through.
- @type account: I{Account}
- """
-
- def isOnline():
- """
- Am I online right now?
-
- @rtype: boolean
- """
-
- def getStatus():
- """
- What is my on-line status?
-
- @return: L{locals.StatusEnum}
- """
-
- def getIdleTime():
- """
- @rtype: string (XXX: How about a scalar?)
- """
-
- def sendMessage(text, metadata=None):
- """
- Send a message to this person.
-
- @type text: string
- @type metadata: dict
- """
-
-
-class IGroup(Interface):
- """
- A group which you may have a conversation with.
-
- Groups generally have a loosely-defined set of members, who may
- leave and join at any time.
- """
-
- name = Attribute('My C{str} name, as the server knows me.')
- account = Attribute('The L{Account<IAccount>} I am accessed through.')
-
- def __init__(name, account):
- """
- Initialize me.
-
- @param name: My name, as the server knows me.
- @type name: str
- @param account: The account I am accessed through.
- @type account: L{Account<IAccount>}
- """
-
- def setTopic(text):
- """
- Set this Groups topic on the server.
-
- @type text: string
- """
-
- def sendGroupMessage(text, metadata=None):
- """
- Send a message to this group.
-
- @type text: str
-
- @type metadata: dict
- @param metadata: Valid keys for this dictionary include:
-
- - C{'style'}: associated with one of:
- - C{'emote'}: indicates this is an action
- """
-
- def join():
- """
- Join this group.
- """
-
- def leave():
- """
- Depart this group.
- """
-
-
-class IConversation(Interface):
- """
- A conversation with a specific person.
- """
-
- def __init__(person, chatui):
- """
- @type person: L{IPerson}
- """
-
- def show():
- """
- doesn't seem like it belongs in this interface.
- """
-
- def hide():
- """
- nor this neither.
- """
-
- def sendText(text, metadata):
- pass
-
- def showMessage(text, metadata):
- pass
-
- def changedNick(person, newnick):
- """
- @param person: XXX Shouldn't this always be Conversation.person?
- """
-
-class IGroupConversation(Interface):
-
- def show():
- """
- doesn't seem like it belongs in this interface.
- """
-
- def hide():
- """
- nor this neither.
- """
-
- def sendText(text, metadata):
- pass
-
- def showGroupMessage(sender, text, metadata):
- pass
-
- def setGroupMembers(members):
- """
- Sets the list of members in the group and displays it to the user.
- """
-
- def setTopic(topic, author):
- """
- Displays the topic (from the server) for the group conversation window.
-
- @type topic: string
- @type author: string (XXX: Not Person?)
- """
-
- def memberJoined(member):
- """
- Adds the given member to the list of members in the group conversation
- and displays this to the user,
-
- @type member: string (XXX: Not Person?)
- """
-
- def memberChangedNick(oldnick, newnick):
- """
- Changes the oldnick in the list of members to C{newnick} and displays this
- change to the user,
-
- @type oldnick: string (XXX: Not Person?)
- @type newnick: string
- """
-
- def memberLeft(member):
- """
- Deletes the given member from the list of members in the group
- conversation and displays the change to the user.
-
- @type member: string (XXX: Not Person?)
- """
-
-
-class IChatUI(Interface):
-
- def registerAccountClient(client):
- """
- Notifies user that an account has been signed on to.
-
- @type client: L{Client<IClient>}
- """
-
- def unregisterAccountClient(client):
- """
- Notifies user that an account has been signed off or disconnected.
-
- @type client: L{Client<IClient>}
- """
-
- def getContactsList():
- """
- @rtype: L{ContactsList}
- """
-
- # WARNING: You'll want to be polymorphed into something with
- # intrinsic stoning resistance before continuing.
-
- def getConversation(person, Class, stayHidden=0):
- """
- For the given person object, returns the conversation window
- or creates and returns a new conversation window if one does not exist.
-
- @type person: L{Person<IPerson>}
- @type Class: L{Conversation<IConversation>} class
- @type stayHidden: boolean
-
- @rtype: L{Conversation<IConversation>}
- """
-
- def getGroupConversation(group, Class, stayHidden=0):
- """
- For the given group object, returns the group conversation window or
- creates and returns a new group conversation window if it doesn't exist.
-
- @type group: L{Group<interfaces.IGroup>}
- @type Class: L{Conversation<interfaces.IConversation>} class
- @type stayHidden: boolean
-
- @rtype: L{GroupConversation<interfaces.IGroupConversation>}
- """
-
- def getPerson(name, client):
- """
- Get a Person for a client.
-
- Duplicates L{IAccount.getPerson}.
-
- @type name: string
- @type client: L{Client<IClient>}
-
- @rtype: L{Person<IPerson>}
- """
-
- def getGroup(name, client):
- """
- Get a Group for a client.
-
- Duplicates L{IAccount.getGroup}.
-
- @type name: string
- @type client: L{Client<IClient>}
-
- @rtype: L{Group<IGroup>}
- """
-
- def contactChangedNick(oldnick, newnick):
- """
- For the given person, changes the person's name to newnick, and
- tells the contact list and any conversation windows with that person
- to change as well.
-
- @type oldnick: string
- @type newnick: string
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/ircsupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/ircsupport.py
deleted file mode 100755
index 1feddeb7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/ircsupport.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-IRC support for Instance Messenger.
-"""
-
-import string
-
-from twisted.words.protocols import irc
-from twisted.words.im.locals import ONLINE
-from twisted.internet import defer, reactor, protocol
-from twisted.internet.defer import succeed
-from twisted.words.im import basesupport, interfaces, locals
-from zope.interface import implements
-
-
-class IRCPerson(basesupport.AbstractPerson):
-
- def imperson_whois(self):
- if self.account.client is None:
- raise locals.OfflineError
- self.account.client.sendLine("WHOIS %s" % self.name)
-
- ### interface impl
-
- def isOnline(self):
- return ONLINE
-
- def getStatus(self):
- return ONLINE
-
- def setStatus(self,status):
- self.status=status
- self.chat.getContactsList().setContactStatus(self)
-
- def sendMessage(self, text, meta=None):
- if self.account.client is None:
- raise locals.OfflineError
- for line in string.split(text, '\n'):
- if meta and meta.get("style", None) == "emote":
- self.account.client.ctcpMakeQuery(self.name,[('ACTION', line)])
- else:
- self.account.client.msg(self.name, line)
- return succeed(text)
-
-class IRCGroup(basesupport.AbstractGroup):
-
- implements(interfaces.IGroup)
-
- def imgroup_testAction(self):
- pass
-
- def imtarget_kick(self, target):
- if self.account.client is None:
- raise locals.OfflineError
- reason = "for great justice!"
- self.account.client.sendLine("KICK #%s %s :%s" % (
- self.name, target.name, reason))
-
- ### Interface Implementation
-
- def setTopic(self, topic):
- if self.account.client is None:
- raise locals.OfflineError
- self.account.client.topic(self.name, topic)
-
- def sendGroupMessage(self, text, meta={}):
- if self.account.client is None:
- raise locals.OfflineError
- if meta and meta.get("style", None) == "emote":
- self.account.client.me(self.name,text)
- return succeed(text)
- #standard shmandard, clients don't support plain escaped newlines!
- for line in string.split(text, '\n'):
- self.account.client.say(self.name, line)
- return succeed(text)
-
- def leave(self):
- if self.account.client is None:
- raise locals.OfflineError
- self.account.client.leave(self.name)
- self.account.client.getGroupConversation(self.name,1)
-
-
-class IRCProto(basesupport.AbstractClientMixin, irc.IRCClient):
- def __init__(self, account, chatui, logonDeferred=None):
- basesupport.AbstractClientMixin.__init__(self, account, chatui,
- logonDeferred)
- self._namreplies={}
- self._ingroups={}
- self._groups={}
- self._topics={}
-
- def getGroupConversation(self, name, hide=0):
- name=string.lower(name)
- return self.chat.getGroupConversation(self.chat.getGroup(name, self),
- stayHidden=hide)
-
- def getPerson(self,name):
- return self.chat.getPerson(name, self)
-
- def connectionMade(self):
- # XXX: Why do I duplicate code in IRCClient.register?
- try:
- if self.account.password:
- self.sendLine("PASS :%s" % self.account.password)
- self.setNick(self.account.username)
- self.sendLine("USER %s foo bar :Twisted-IM user" % (
- self.account.username,))
- for channel in self.account.channels:
- self.joinGroup(channel)
- self.account._isOnline=1
- if self._logonDeferred is not None:
- self._logonDeferred.callback(self)
- self.chat.getContactsList()
- except:
- import traceback
- traceback.print_exc()
-
- def setNick(self,nick):
- self.name=nick
- self.accountName="%s (IRC)"%nick
- irc.IRCClient.setNick(self,nick)
-
- def kickedFrom(self, channel, kicker, message):
- """
- Called when I am kicked from a channel.
- """
- return self.chat.getGroupConversation(
- self.chat.getGroup(channel[1:], self), 1)
-
- def userKicked(self, kickee, channel, kicker, message):
- pass
-
- def noticed(self, username, channel, message):
- self.privmsg(username, channel, message, {"dontAutoRespond": 1})
-
- def privmsg(self, username, channel, message, metadata=None):
- if metadata is None:
- metadata = {}
- username=string.split(username,'!',1)[0]
- if username==self.name: return
- if channel[0]=='#':
- group=channel[1:]
- self.getGroupConversation(group).showGroupMessage(username, message, metadata)
- return
- self.chat.getConversation(self.getPerson(username)).showMessage(message, metadata)
-
- def action(self,username,channel,emote):
- username=string.split(username,'!',1)[0]
- if username==self.name: return
- meta={'style':'emote'}
- if channel[0]=='#':
- group=channel[1:]
- self.getGroupConversation(group).showGroupMessage(username, emote, meta)
- return
- self.chat.getConversation(self.getPerson(username)).showMessage(emote,meta)
-
- def irc_RPL_NAMREPLY(self,prefix,params):
- """
- RPL_NAMREPLY
- >> NAMES #bnl
- << :Arlington.VA.US.Undernet.Org 353 z3p = #bnl :pSwede Dan-- SkOyg AG
- """
- group=string.lower(params[2][1:])
- users=string.split(params[3])
- for ui in range(len(users)):
- while users[ui][0] in ["@","+"]: # channel modes
- users[ui]=users[ui][1:]
- if not self._namreplies.has_key(group):
- self._namreplies[group]=[]
- self._namreplies[group].extend(users)
- for nickname in users:
- try:
- self._ingroups[nickname].append(group)
- except:
- self._ingroups[nickname]=[group]
-
- def irc_RPL_ENDOFNAMES(self,prefix,params):
- group=params[1][1:]
- self.getGroupConversation(group).setGroupMembers(self._namreplies[string.lower(group)])
- del self._namreplies[string.lower(group)]
-
- def irc_RPL_TOPIC(self,prefix,params):
- self._topics[params[1][1:]]=params[2]
-
- def irc_333(self,prefix,params):
- group=params[1][1:]
- self.getGroupConversation(group).setTopic(self._topics[group],params[2])
- del self._topics[group]
-
- def irc_TOPIC(self,prefix,params):
- nickname = string.split(prefix,"!")[0]
- group = params[0][1:]
- topic = params[1]
- self.getGroupConversation(group).setTopic(topic,nickname)
-
- def irc_JOIN(self,prefix,params):
- nickname=string.split(prefix,"!")[0]
- group=string.lower(params[0][1:])
- if nickname!=self.nickname:
- try:
- self._ingroups[nickname].append(group)
- except:
- self._ingroups[nickname]=[group]
- self.getGroupConversation(group).memberJoined(nickname)
-
- def irc_PART(self,prefix,params):
- nickname=string.split(prefix,"!")[0]
- group=string.lower(params[0][1:])
- if nickname!=self.nickname:
- if group in self._ingroups[nickname]:
- self._ingroups[nickname].remove(group)
- self.getGroupConversation(group).memberLeft(nickname)
-
- def irc_QUIT(self,prefix,params):
- nickname=string.split(prefix,"!")[0]
- if self._ingroups.has_key(nickname):
- for group in self._ingroups[nickname]:
- self.getGroupConversation(group).memberLeft(nickname)
- self._ingroups[nickname]=[]
-
- def irc_NICK(self, prefix, params):
- fromNick = string.split(prefix, "!")[0]
- toNick = params[0]
- if not self._ingroups.has_key(fromNick):
- return
- for group in self._ingroups[fromNick]:
- self.getGroupConversation(group).memberChangedNick(fromNick, toNick)
- self._ingroups[toNick] = self._ingroups[fromNick]
- del self._ingroups[fromNick]
-
- def irc_unknown(self, prefix, command, params):
- pass
-
- # GTKIM calls
- def joinGroup(self,name):
- self.join(name)
- self.getGroupConversation(name)
-
-class IRCAccount(basesupport.AbstractAccount):
- implements(interfaces.IAccount)
- gatewayType = "IRC"
-
- _groupFactory = IRCGroup
- _personFactory = IRCPerson
-
- def __init__(self, accountName, autoLogin, username, password, host, port,
- channels=''):
- basesupport.AbstractAccount.__init__(self, accountName, autoLogin,
- username, password, host, port)
- self.channels = map(string.strip,string.split(channels,','))
- if self.channels == ['']:
- self.channels = []
-
- def _startLogOn(self, chatui):
- logonDeferred = defer.Deferred()
- cc = protocol.ClientCreator(reactor, IRCProto, self, chatui,
- logonDeferred)
- d = cc.connectTCP(self.host, self.port)
- d.addErrback(logonDeferred.errback)
- return logonDeferred
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/locals.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/locals.py
deleted file mode 100755
index a63547a3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/locals.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-class Enum:
- group = None
-
- def __init__(self, label):
- self.label = label
-
- def __repr__(self):
- return '<%s: %s>' % (self.group, self.label)
-
- def __str__(self):
- return self.label
-
-
-class StatusEnum(Enum):
- group = 'Status'
-
-OFFLINE = Enum('Offline')
-ONLINE = Enum('Online')
-AWAY = Enum('Away')
-
-class OfflineError(Exception):
- """The requested action can't happen while offline."""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/pbsupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/pbsupport.py
deleted file mode 100755
index 04d14e99..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/im/pbsupport.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-L{twisted.words} support for Instance Messenger.
-"""
-
-from twisted.internet import defer
-from twisted.internet import error
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.spread import pb
-
-from twisted.words.im.locals import ONLINE, OFFLINE, AWAY
-
-from twisted.words.im import basesupport, interfaces
-from zope.interface import implements
-
-
-class TwistedWordsPerson(basesupport.AbstractPerson):
- """I a facade for a person you can talk to through a twisted.words service.
- """
- def __init__(self, name, wordsAccount):
- basesupport.AbstractPerson.__init__(self, name, wordsAccount)
- self.status = OFFLINE
-
- def isOnline(self):
- return ((self.status == ONLINE) or
- (self.status == AWAY))
-
- def getStatus(self):
- return self.status
-
- def sendMessage(self, text, metadata):
- """Return a deferred...
- """
- if metadata:
- d=self.account.client.perspective.directMessage(self.name,
- text, metadata)
- d.addErrback(self.metadataFailed, "* "+text)
- return d
- else:
- return self.account.client.perspective.callRemote('directMessage',self.name, text)
-
- def metadataFailed(self, result, text):
- print "result:",result,"text:",text
- return self.account.client.perspective.directMessage(self.name, text)
-
- def setStatus(self, status):
- self.status = status
- self.chat.getContactsList().setContactStatus(self)
-
-class TwistedWordsGroup(basesupport.AbstractGroup):
- implements(interfaces.IGroup)
- def __init__(self, name, wordsClient):
- basesupport.AbstractGroup.__init__(self, name, wordsClient)
- self.joined = 0
-
- def sendGroupMessage(self, text, metadata=None):
- """Return a deferred.
- """
- #for backwards compatibility with older twisted.words servers.
- if metadata:
- d=self.account.client.perspective.callRemote(
- 'groupMessage', self.name, text, metadata)
- d.addErrback(self.metadataFailed, "* "+text)
- return d
- else:
- return self.account.client.perspective.callRemote('groupMessage',
- self.name, text)
-
- def setTopic(self, text):
- self.account.client.perspective.callRemote(
- 'setGroupMetadata',
- {'topic': text, 'topic_author': self.client.name},
- self.name)
-
- def metadataFailed(self, result, text):
- print "result:",result,"text:",text
- return self.account.client.perspective.callRemote('groupMessage',
- self.name, text)
-
- def joining(self):
- self.joined = 1
-
- def leaving(self):
- self.joined = 0
-
- def leave(self):
- return self.account.client.perspective.callRemote('leaveGroup',
- self.name)
-
-
-
-class TwistedWordsClient(pb.Referenceable, basesupport.AbstractClientMixin):
- """In some cases, this acts as an Account, since it a source of text
- messages (multiple Words instances may be on a single PB connection)
- """
- def __init__(self, acct, serviceName, perspectiveName, chatui,
- _logonDeferred=None):
- self.accountName = "%s (%s:%s)" % (acct.accountName, serviceName, perspectiveName)
- self.name = perspectiveName
- print "HELLO I AM A PB SERVICE", serviceName, perspectiveName
- self.chat = chatui
- self.account = acct
- self._logonDeferred = _logonDeferred
-
- def getPerson(self, name):
- return self.chat.getPerson(name, self)
-
- def getGroup(self, name):
- return self.chat.getGroup(name, self)
-
- def getGroupConversation(self, name):
- return self.chat.getGroupConversation(self.getGroup(name))
-
- def addContact(self, name):
- self.perspective.callRemote('addContact', name)
-
- def remote_receiveGroupMembers(self, names, group):
- print 'received group members:', names, group
- self.getGroupConversation(group).setGroupMembers(names)
-
- def remote_receiveGroupMessage(self, sender, group, message, metadata=None):
- print 'received a group message', sender, group, message, metadata
- self.getGroupConversation(group).showGroupMessage(sender, message, metadata)
-
- def remote_memberJoined(self, member, group):
- print 'member joined', member, group
- self.getGroupConversation(group).memberJoined(member)
-
- def remote_memberLeft(self, member, group):
- print 'member left'
- self.getGroupConversation(group).memberLeft(member)
-
- def remote_notifyStatusChanged(self, name, status):
- self.chat.getPerson(name, self).setStatus(status)
-
- def remote_receiveDirectMessage(self, name, message, metadata=None):
- self.chat.getConversation(self.chat.getPerson(name, self)).showMessage(message, metadata)
-
- def remote_receiveContactList(self, clist):
- for name, status in clist:
- self.chat.getPerson(name, self).setStatus(status)
-
- def remote_setGroupMetadata(self, dict_, groupName):
- if dict_.has_key("topic"):
- self.getGroupConversation(groupName).setTopic(dict_["topic"], dict_.get("topic_author", None))
-
- def joinGroup(self, name):
- self.getGroup(name).joining()
- return self.perspective.callRemote('joinGroup', name).addCallback(self._cbGroupJoined, name)
-
- def leaveGroup(self, name):
- self.getGroup(name).leaving()
- return self.perspective.callRemote('leaveGroup', name).addCallback(self._cbGroupLeft, name)
-
- def _cbGroupJoined(self, result, name):
- groupConv = self.chat.getGroupConversation(self.getGroup(name))
- groupConv.showGroupMessage("sys", "you joined")
- self.perspective.callRemote('getGroupMembers', name)
-
- def _cbGroupLeft(self, result, name):
- print 'left',name
- groupConv = self.chat.getGroupConversation(self.getGroup(name), 1)
- groupConv.showGroupMessage("sys", "you left")
-
- def connected(self, perspective):
- print 'Connected Words Client!', perspective
- if self._logonDeferred is not None:
- self._logonDeferred.callback(self)
- self.perspective = perspective
- self.chat.getContactsList()
-
-
-pbFrontEnds = {
- "twisted.words": TwistedWordsClient,
- "twisted.reality": None
- }
-
-
-class PBAccount(basesupport.AbstractAccount):
- implements(interfaces.IAccount)
- gatewayType = "PB"
- _groupFactory = TwistedWordsGroup
- _personFactory = TwistedWordsPerson
-
- def __init__(self, accountName, autoLogin, username, password, host, port,
- services=None):
- """
- @param username: The name of your PB Identity.
- @type username: string
- """
- basesupport.AbstractAccount.__init__(self, accountName, autoLogin,
- username, password, host, port)
- self.services = []
- if not services:
- services = [('twisted.words', 'twisted.words', username)]
- for serviceType, serviceName, perspectiveName in services:
- self.services.append([pbFrontEnds[serviceType], serviceName,
- perspectiveName])
-
- def logOn(self, chatui):
- """
- @returns: this breaks with L{interfaces.IAccount}
- @returntype: DeferredList of L{interfaces.IClient}s
- """
- # Overriding basesupport's implementation on account of the
- # fact that _startLogOn tends to return a deferredList rather
- # than a simple Deferred, and we need to do registerAccountClient.
- if (not self._isConnecting) and (not self._isOnline):
- self._isConnecting = 1
- d = self._startLogOn(chatui)
- d.addErrback(self._loginFailed)
- def registerMany(results):
- for success, result in results:
- if success:
- chatui.registerAccountClient(result)
- self._cb_logOn(result)
- else:
- log.err(result)
- d.addCallback(registerMany)
- return d
- else:
- raise error.ConnectionError("Connection in progress")
-
-
- def _startLogOn(self, chatui):
- print 'Connecting...',
- d = pb.getObjectAt(self.host, self.port)
- d.addCallbacks(self._cbConnected, self._ebConnected,
- callbackArgs=(chatui,))
- return d
-
- def _cbConnected(self, root, chatui):
- print 'Connected!'
- print 'Identifying...',
- d = pb.authIdentity(root, self.username, self.password)
- d.addCallbacks(self._cbIdent, self._ebConnected,
- callbackArgs=(chatui,))
- return d
-
- def _cbIdent(self, ident, chatui):
- if not ident:
- print 'falsely identified.'
- return self._ebConnected(Failure(Exception("username or password incorrect")))
- print 'Identified!'
- dl = []
- for handlerClass, sname, pname in self.services:
- d = defer.Deferred()
- dl.append(d)
- handler = handlerClass(self, sname, pname, chatui, d)
- ident.callRemote('attach', sname, pname, handler).addCallback(handler.connected)
- return defer.DeferredList(dl)
-
- def _ebConnected(self, error):
- print 'Not connected.'
- return error
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/iwords.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/iwords.py
deleted file mode 100755
index c8ce09f1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/iwords.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from zope.interface import Interface, Attribute, implements
-
-class IProtocolPlugin(Interface):
- """Interface for plugins providing an interface to a Words service
- """
-
- name = Attribute("A single word describing what kind of interface this is (eg, irc or web)")
-
- def getFactory(realm, portal):
- """Retrieve a C{twisted.internet.interfaces.IServerFactory} provider
-
- @param realm: An object providing C{twisted.cred.portal.IRealm} and
- C{IChatService}, with which service information should be looked up.
-
- @param portal: An object providing C{twisted.cred.portal.IPortal},
- through which logins should be performed.
- """
-
-
-class IGroup(Interface):
- name = Attribute("A short string, unique among groups.")
-
- def add(user):
- """Include the given user in this group.
-
- @type user: L{IUser}
- """
-
- def remove(user, reason=None):
- """Remove the given user from this group.
-
- @type user: L{IUser}
- @type reason: C{unicode}
- """
-
- def size():
- """Return the number of participants in this group.
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with an C{int} representing the the
- number of participants in this group.
- """
-
- def receive(sender, recipient, message):
- """
- Broadcast the given message from the given sender to other
- users in group.
-
- The message is not re-transmitted to the sender.
-
- @param sender: L{IUser}
-
- @type recipient: L{IGroup}
- @param recipient: This is probably a wart. Maybe it will be removed
- in the future. For now, it should be the group object the message
- is being delivered to.
-
- @param message: C{dict}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with None when delivery has been
- attempted for all users.
- """
-
- def setMetadata(meta):
- """Change the metadata associated with this group.
-
- @type meta: C{dict}
- """
-
- def iterusers():
- """Return an iterator of all users in this group.
- """
-
-
-class IChatClient(Interface):
- """Interface through which IChatService interacts with clients.
- """
-
- name = Attribute("A short string, unique among users. This will be set by the L{IChatService} at login time.")
-
- def receive(sender, recipient, message):
- """
- Callback notifying this user of the given message sent by the
- given user.
-
- This will be invoked whenever another user sends a message to a
- group this user is participating in, or whenever another user sends
- a message directly to this user. In the former case, C{recipient}
- will be the group to which the message was sent; in the latter, it
- will be the same object as the user who is receiving the message.
-
- @type sender: L{IUser}
- @type recipient: L{IUser} or L{IGroup}
- @type message: C{dict}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires when the message has been delivered,
- or which fails in some way. If the Deferred fails and the message
- was directed at a group, this user will be removed from that group.
- """
-
- def groupMetaUpdate(group, meta):
- """
- Callback notifying this user that the metadata for the given
- group has changed.
-
- @type group: L{IGroup}
- @type meta: C{dict}
-
- @rtype: L{twisted.internet.defer.Deferred}
- """
-
- def userJoined(group, user):
- """
- Callback notifying this user that the given user has joined
- the given group.
-
- @type group: L{IGroup}
- @type user: L{IUser}
-
- @rtype: L{twisted.internet.defer.Deferred}
- """
-
- def userLeft(group, user, reason=None):
- """
- Callback notifying this user that the given user has left the
- given group for the given reason.
-
- @type group: L{IGroup}
- @type user: L{IUser}
- @type reason: C{unicode}
-
- @rtype: L{twisted.internet.defer.Deferred}
- """
-
-
-class IUser(Interface):
- """Interface through which clients interact with IChatService.
- """
-
- realm = Attribute("A reference to the Realm to which this user belongs. Set if and only if the user is logged in.")
- mind = Attribute("A reference to the mind which logged in to this user. Set if and only if the user is logged in.")
- name = Attribute("A short string, unique among users.")
-
- lastMessage = Attribute("A POSIX timestamp indicating the time of the last message received from this user.")
- signOn = Attribute("A POSIX timestamp indicating this user's most recent sign on time.")
-
- def loggedIn(realm, mind):
- """Invoked by the associated L{IChatService} when login occurs.
-
- @param realm: The L{IChatService} through which login is occurring.
- @param mind: The mind object used for cred login.
- """
-
- def send(recipient, message):
- """Send the given message to the given user or group.
-
- @type recipient: Either L{IUser} or L{IGroup}
- @type message: C{dict}
- """
-
- def join(group):
- """Attempt to join the given group.
-
- @type group: L{IGroup}
- @rtype: L{twisted.internet.defer.Deferred}
- """
-
- def leave(group):
- """Discontinue participation in the given group.
-
- @type group: L{IGroup}
- @rtype: L{twisted.internet.defer.Deferred}
- """
-
- def itergroups():
- """
- Return an iterator of all groups of which this user is a
- member.
- """
-
-
-class IChatService(Interface):
- name = Attribute("A short string identifying this chat service (eg, a hostname)")
-
- createGroupOnRequest = Attribute(
- "A boolean indicating whether L{getGroup} should implicitly "
- "create groups which are requested but which do not yet exist.")
-
- createUserOnRequest = Attribute(
- "A boolean indicating whether L{getUser} should implicitly "
- "create users which are requested but which do not yet exist.")
-
- def itergroups():
- """Return all groups available on this service.
-
- @rtype: C{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with a list of C{IGroup} providers.
- """
-
- def getGroup(name):
- """Retrieve the group by the given name.
-
- @type name: C{str}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with the group with the given
- name if one exists (or if one is created due to the setting of
- L{createGroupOnRequest}, or which fails with
- L{twisted.words.ewords.NoSuchGroup} if no such group exists.
- """
-
- def createGroup(name):
- """Create a new group with the given name.
-
- @type name: C{str}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with the created group, or
- with fails with L{twisted.words.ewords.DuplicateGroup} if a
- group by that name exists already.
- """
-
- def lookupGroup(name):
- """Retrieve a group by name.
-
- Unlike C{getGroup}, this will never implicitly create a group.
-
- @type name: C{str}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with the group by the given
- name, or which fails with L{twisted.words.ewords.NoSuchGroup}.
- """
-
- def getUser(name):
- """Retrieve the user by the given name.
-
- @type name: C{str}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with the user with the given
- name if one exists (or if one is created due to the setting of
- L{createUserOnRequest}, or which fails with
- L{twisted.words.ewords.NoSuchUser} if no such user exists.
- """
-
- def createUser(name):
- """Create a new user with the given name.
-
- @type name: C{str}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with the created user, or
- with fails with L{twisted.words.ewords.DuplicateUser} if a
- user by that name exists already.
- """
-
-__all__ = [
- 'IChatInterface', 'IGroup', 'IChatClient', 'IUser', 'IChatService',
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/__init__.py
deleted file mode 100755
index 5b4f7e50..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"Chat protocols"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/irc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/irc.py
deleted file mode 100755
index 65daa7a9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/irc.py
+++ /dev/null
@@ -1,3302 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_irc -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Internet Relay Chat Protocol for client and server.
-
-Future Plans
-============
-
-The way the IRCClient class works here encourages people to implement
-IRC clients by subclassing the ephemeral protocol class, and it tends
-to end up with way more state than it should for an object which will
-be destroyed as soon as the TCP transport drops. Someone oughta do
-something about that, ya know?
-
-The DCC support needs to have more hooks for the client for it to be
-able to ask the user things like "Do you want to accept this session?"
-and "Transfer #2 is 67% done." and otherwise manage the DCC sessions.
-
-Test coverage needs to be better.
-
-@var MAX_COMMAND_LENGTH: The maximum length of a command, as defined by RFC
- 2812 section 2.3.
-
-@author: Kevin Turner
-
-@see: RFC 1459: Internet Relay Chat Protocol
-@see: RFC 2812: Internet Relay Chat: Client Protocol
-@see: U{The Client-To-Client-Protocol
-<http://www.irchelp.org/irchelp/rfc/ctcpspec.html>}
-"""
-
-import errno, os, random, re, stat, struct, sys, time, types, traceback
-import string, socket
-import warnings
-import textwrap
-from os import path
-
-from twisted.internet import reactor, protocol, task
-from twisted.persisted import styles
-from twisted.protocols import basic
-from twisted.python import log, reflect, text
-from twisted.python.compat import set
-
-NUL = chr(0)
-CR = chr(015)
-NL = chr(012)
-LF = NL
-SPC = chr(040)
-
-# This includes the CRLF terminator characters.
-MAX_COMMAND_LENGTH = 512
-
-CHANNEL_PREFIXES = '&#!+'
-
-class IRCBadMessage(Exception):
- pass
-
-class IRCPasswordMismatch(Exception):
- pass
-
-
-
-class IRCBadModes(ValueError):
- """
- A malformed mode was encountered while attempting to parse a mode string.
- """
-
-
-
-def parsemsg(s):
- """Breaks a message from an IRC server into its prefix, command, and arguments.
- """
- prefix = ''
- trailing = []
- if not s:
- raise IRCBadMessage("Empty line.")
- if s[0] == ':':
- prefix, s = s[1:].split(' ', 1)
- if s.find(' :') != -1:
- s, trailing = s.split(' :', 1)
- args = s.split()
- args.append(trailing)
- else:
- args = s.split()
- command = args.pop(0)
- return prefix, command, args
-
-
-
-def split(str, length=80):
- """
- Split a string into multiple lines.
-
- Whitespace near C{str[length]} will be preferred as a breaking point.
- C{"\\n"} will also be used as a breaking point.
-
- @param str: The string to split.
- @type str: C{str}
-
- @param length: The maximum length which will be allowed for any string in
- the result.
- @type length: C{int}
-
- @return: C{list} of C{str}
- """
- return [chunk
- for line in str.split('\n')
- for chunk in textwrap.wrap(line, length)]
-
-
-def _intOrDefault(value, default=None):
- """
- Convert a value to an integer if possible.
-
- @rtype: C{int} or type of L{default}
- @return: An integer when C{value} can be converted to an integer,
- otherwise return C{default}
- """
- if value:
- try:
- return int(value)
- except (TypeError, ValueError):
- pass
- return default
-
-
-
-class UnhandledCommand(RuntimeError):
- """
- A command dispatcher could not locate an appropriate command handler.
- """
-
-
-
-class _CommandDispatcherMixin(object):
- """
- Dispatch commands to handlers based on their name.
-
- Command handler names should be of the form C{prefix_commandName},
- where C{prefix} is the value specified by L{prefix}, and must
- accept the parameters as given to L{dispatch}.
-
- Attempting to mix this in more than once for a single class will cause
- strange behaviour, due to L{prefix} being overwritten.
-
- @type prefix: C{str}
- @ivar prefix: Command handler prefix, used to locate handler attributes
- """
- prefix = None
-
- def dispatch(self, commandName, *args):
- """
- Perform actual command dispatch.
- """
- def _getMethodName(command):
- return '%s_%s' % (self.prefix, command)
-
- def _getMethod(name):
- return getattr(self, _getMethodName(name), None)
-
- method = _getMethod(commandName)
- if method is not None:
- return method(*args)
-
- method = _getMethod('unknown')
- if method is None:
- raise UnhandledCommand("No handler for %r could be found" % (_getMethodName(commandName),))
- return method(commandName, *args)
-
-
-
-
-
-def parseModes(modes, params, paramModes=('', '')):
- """
- Parse an IRC mode string.
-
- The mode string is parsed into two lists of mode changes (added and
- removed), with each mode change represented as C{(mode, param)} where mode
- is the mode character, and param is the parameter passed for that mode, or
- C{None} if no parameter is required.
-
- @type modes: C{str}
- @param modes: Modes string to parse.
-
- @type params: C{list}
- @param params: Parameters specified along with L{modes}.
-
- @type paramModes: C{(str, str)}
- @param paramModes: A pair of strings (C{(add, remove)}) that indicate which modes take
- parameters when added or removed.
-
- @returns: Two lists of mode changes, one for modes added and the other for
- modes removed respectively, mode changes in each list are represented as
- C{(mode, param)}.
- """
- if len(modes) == 0:
- raise IRCBadModes('Empty mode string')
-
- if modes[0] not in '+-':
- raise IRCBadModes('Malformed modes string: %r' % (modes,))
-
- changes = ([], [])
-
- direction = None
- count = -1
- for ch in modes:
- if ch in '+-':
- if count == 0:
- raise IRCBadModes('Empty mode sequence: %r' % (modes,))
- direction = '+-'.index(ch)
- count = 0
- else:
- param = None
- if ch in paramModes[direction]:
- try:
- param = params.pop(0)
- except IndexError:
- raise IRCBadModes('Not enough parameters: %r' % (ch,))
- changes[direction].append((ch, param))
- count += 1
-
- if len(params) > 0:
- raise IRCBadModes('Too many parameters: %r %r' % (modes, params))
-
- if count == 0:
- raise IRCBadModes('Empty mode sequence: %r' % (modes,))
-
- return changes
-
-
-
-class IRC(protocol.Protocol):
- """
- Internet Relay Chat server protocol.
- """
-
- buffer = ""
- hostname = None
-
- encoding = None
-
- def connectionMade(self):
- self.channels = []
- if self.hostname is None:
- self.hostname = socket.getfqdn()
-
-
- def sendLine(self, line):
- if self.encoding is not None:
- if isinstance(line, unicode):
- line = line.encode(self.encoding)
- self.transport.write("%s%s%s" % (line, CR, LF))
-
-
- def sendMessage(self, command, *parameter_list, **prefix):
- """
- Send a line formatted as an IRC message.
-
- First argument is the command, all subsequent arguments are parameters
- to that command. If a prefix is desired, it may be specified with the
- keyword argument 'prefix'.
- """
-
- if not command:
- raise ValueError, "IRC message requires a command."
-
- if ' ' in command or command[0] == ':':
- # Not the ONLY way to screw up, but provides a little
- # sanity checking to catch likely dumb mistakes.
- raise ValueError, "Somebody screwed up, 'cuz this doesn't" \
- " look like a command to me: %s" % command
-
- line = string.join([command] + list(parameter_list))
- if 'prefix' in prefix:
- line = ":%s %s" % (prefix['prefix'], line)
- self.sendLine(line)
-
- if len(parameter_list) > 15:
- log.msg("Message has %d parameters (RFC allows 15):\n%s" %
- (len(parameter_list), line))
-
-
- def dataReceived(self, data):
- """
- This hack is to support mIRC, which sends LF only, even though the RFC
- says CRLF. (Also, the flexibility of LineReceiver to turn "line mode"
- on and off was not required.)
- """
- lines = (self.buffer + data).split(LF)
- # Put the (possibly empty) element after the last LF back in the
- # buffer
- self.buffer = lines.pop()
-
- for line in lines:
- if len(line) <= 2:
- # This is a blank line, at best.
- continue
- if line[-1] == CR:
- line = line[:-1]
- prefix, command, params = parsemsg(line)
- # mIRC is a big pile of doo-doo
- command = command.upper()
- # DEBUG: log.msg( "%s %s %s" % (prefix, command, params))
-
- self.handleCommand(command, prefix, params)
-
-
- def handleCommand(self, command, prefix, params):
- """
- Determine the function to call for the given command and call it with
- the given arguments.
- """
- method = getattr(self, "irc_%s" % command, None)
- try:
- if method is not None:
- method(prefix, params)
- else:
- self.irc_unknown(prefix, command, params)
- except:
- log.deferr()
-
-
- def irc_unknown(self, prefix, command, params):
- """
- Called by L{handleCommand} on a command that doesn't have a defined
- handler. Subclasses should override this method.
- """
- raise NotImplementedError(command, prefix, params)
-
-
- # Helper methods
- def privmsg(self, sender, recip, message):
- """
- Send a message to a channel or user
-
- @type sender: C{str} or C{unicode}
- @param sender: Who is sending this message. Should be of the form
- username!ident@hostmask (unless you know better!).
-
- @type recip: C{str} or C{unicode}
- @param recip: The recipient of this message. If a channel, it must
- start with a channel prefix.
-
- @type message: C{str} or C{unicode}
- @param message: The message being sent.
- """
- self.sendLine(":%s PRIVMSG %s :%s" % (sender, recip, lowQuote(message)))
-
-
- def notice(self, sender, recip, message):
- """
- Send a "notice" to a channel or user.
-
- Notices differ from privmsgs in that the RFC claims they are different.
- Robots are supposed to send notices and not respond to them. Clients
- typically display notices differently from privmsgs.
-
- @type sender: C{str} or C{unicode}
- @param sender: Who is sending this message. Should be of the form
- username!ident@hostmask (unless you know better!).
-
- @type recip: C{str} or C{unicode}
- @param recip: The recipient of this message. If a channel, it must
- start with a channel prefix.
-
- @type message: C{str} or C{unicode}
- @param message: The message being sent.
- """
- self.sendLine(":%s NOTICE %s :%s" % (sender, recip, message))
-
-
- def action(self, sender, recip, message):
- """
- Send an action to a channel or user.
-
- @type sender: C{str} or C{unicode}
- @param sender: Who is sending this message. Should be of the form
- username!ident@hostmask (unless you know better!).
-
- @type recip: C{str} or C{unicode}
- @param recip: The recipient of this message. If a channel, it must
- start with a channel prefix.
-
- @type message: C{str} or C{unicode}
- @param message: The action being sent.
- """
- self.sendLine(":%s ACTION %s :%s" % (sender, recip, message))
-
-
- def topic(self, user, channel, topic, author=None):
- """
- Send the topic to a user.
-
- @type user: C{str} or C{unicode}
- @param user: The user receiving the topic. Only their nick name, not
- the full hostmask.
-
- @type channel: C{str} or C{unicode}
- @param channel: The channel for which this is the topic.
-
- @type topic: C{str} or C{unicode} or C{None}
- @param topic: The topic string, unquoted, or None if there is no topic.
-
- @type author: C{str} or C{unicode}
- @param author: If the topic is being changed, the full username and
- hostmask of the person changing it.
- """
- if author is None:
- if topic is None:
- self.sendLine(':%s %s %s %s :%s' % (
- self.hostname, RPL_NOTOPIC, user, channel, 'No topic is set.'))
- else:
- self.sendLine(":%s %s %s %s :%s" % (
- self.hostname, RPL_TOPIC, user, channel, lowQuote(topic)))
- else:
- self.sendLine(":%s TOPIC %s :%s" % (author, channel, lowQuote(topic)))
-
-
- def topicAuthor(self, user, channel, author, date):
- """
- Send the author of and time at which a topic was set for the given
- channel.
-
- This sends a 333 reply message, which is not part of the IRC RFC.
-
- @type user: C{str} or C{unicode}
- @param user: The user receiving the topic. Only their nick name, not
- the full hostmask.
-
- @type channel: C{str} or C{unicode}
- @param channel: The channel for which this information is relevant.
-
- @type author: C{str} or C{unicode}
- @param author: The nickname (without hostmask) of the user who last set
- the topic.
-
- @type date: C{int}
- @param date: A POSIX timestamp (number of seconds since the epoch) at
- which the topic was last set.
- """
- self.sendLine(':%s %d %s %s %s %d' % (
- self.hostname, 333, user, channel, author, date))
-
-
- def names(self, user, channel, names):
- """
- Send the names of a channel's participants to a user.
-
- @type user: C{str} or C{unicode}
- @param user: The user receiving the name list. Only their nick name,
- not the full hostmask.
-
- @type channel: C{str} or C{unicode}
- @param channel: The channel for which this is the namelist.
-
- @type names: C{list} of C{str} or C{unicode}
- @param names: The names to send.
- """
- # XXX If unicode is given, these limits are not quite correct
- prefixLength = len(channel) + len(user) + 10
- namesLength = 512 - prefixLength
-
- L = []
- count = 0
- for n in names:
- if count + len(n) + 1 > namesLength:
- self.sendLine(":%s %s %s = %s :%s" % (
- self.hostname, RPL_NAMREPLY, user, channel, ' '.join(L)))
- L = [n]
- count = len(n)
- else:
- L.append(n)
- count += len(n) + 1
- if L:
- self.sendLine(":%s %s %s = %s :%s" % (
- self.hostname, RPL_NAMREPLY, user, channel, ' '.join(L)))
- self.sendLine(":%s %s %s %s :End of /NAMES list" % (
- self.hostname, RPL_ENDOFNAMES, user, channel))
-
-
- def who(self, user, channel, memberInfo):
- """
- Send a list of users participating in a channel.
-
- @type user: C{str} or C{unicode}
- @param user: The user receiving this member information. Only their
- nick name, not the full hostmask.
-
- @type channel: C{str} or C{unicode}
- @param channel: The channel for which this is the member information.
-
- @type memberInfo: C{list} of C{tuples}
- @param memberInfo: For each member of the given channel, a 7-tuple
- containing their username, their hostmask, the server to which they
- are connected, their nickname, the letter "H" or "G" (standing for
- "Here" or "Gone"), the hopcount from C{user} to this member, and
- this member's real name.
- """
- for info in memberInfo:
- (username, hostmask, server, nickname, flag, hops, realName) = info
- assert flag in ("H", "G")
- self.sendLine(":%s %s %s %s %s %s %s %s %s :%d %s" % (
- self.hostname, RPL_WHOREPLY, user, channel,
- username, hostmask, server, nickname, flag, hops, realName))
-
- self.sendLine(":%s %s %s %s :End of /WHO list." % (
- self.hostname, RPL_ENDOFWHO, user, channel))
-
-
- def whois(self, user, nick, username, hostname, realName, server, serverInfo, oper, idle, signOn, channels):
- """
- Send information about the state of a particular user.
-
- @type user: C{str} or C{unicode}
- @param user: The user receiving this information. Only their nick name,
- not the full hostmask.
-
- @type nick: C{str} or C{unicode}
- @param nick: The nickname of the user this information describes.
-
- @type username: C{str} or C{unicode}
- @param username: The user's username (eg, ident response)
-
- @type hostname: C{str}
- @param hostname: The user's hostmask
-
- @type realName: C{str} or C{unicode}
- @param realName: The user's real name
-
- @type server: C{str} or C{unicode}
- @param server: The name of the server to which the user is connected
-
- @type serverInfo: C{str} or C{unicode}
- @param serverInfo: A descriptive string about that server
-
- @type oper: C{bool}
- @param oper: Indicates whether the user is an IRC operator
-
- @type idle: C{int}
- @param idle: The number of seconds since the user last sent a message
-
- @type signOn: C{int}
- @param signOn: A POSIX timestamp (number of seconds since the epoch)
- indicating the time the user signed on
-
- @type channels: C{list} of C{str} or C{unicode}
- @param channels: A list of the channels which the user is participating in
- """
- self.sendLine(":%s %s %s %s %s %s * :%s" % (
- self.hostname, RPL_WHOISUSER, user, nick, username, hostname, realName))
- self.sendLine(":%s %s %s %s %s :%s" % (
- self.hostname, RPL_WHOISSERVER, user, nick, server, serverInfo))
- if oper:
- self.sendLine(":%s %s %s %s :is an IRC operator" % (
- self.hostname, RPL_WHOISOPERATOR, user, nick))
- self.sendLine(":%s %s %s %s %d %d :seconds idle, signon time" % (
- self.hostname, RPL_WHOISIDLE, user, nick, idle, signOn))
- self.sendLine(":%s %s %s %s :%s" % (
- self.hostname, RPL_WHOISCHANNELS, user, nick, ' '.join(channels)))
- self.sendLine(":%s %s %s %s :End of WHOIS list." % (
- self.hostname, RPL_ENDOFWHOIS, user, nick))
-
-
- def join(self, who, where):
- """
- Send a join message.
-
- @type who: C{str} or C{unicode}
- @param who: The name of the user joining. Should be of the form
- username!ident@hostmask (unless you know better!).
-
- @type where: C{str} or C{unicode}
- @param where: The channel the user is joining.
- """
- self.sendLine(":%s JOIN %s" % (who, where))
-
-
- def part(self, who, where, reason=None):
- """
- Send a part message.
-
- @type who: C{str} or C{unicode}
- @param who: The name of the user joining. Should be of the form
- username!ident@hostmask (unless you know better!).
-
- @type where: C{str} or C{unicode}
- @param where: The channel the user is joining.
-
- @type reason: C{str} or C{unicode}
- @param reason: A string describing the misery which caused this poor
- soul to depart.
- """
- if reason:
- self.sendLine(":%s PART %s :%s" % (who, where, reason))
- else:
- self.sendLine(":%s PART %s" % (who, where))
-
-
- def channelMode(self, user, channel, mode, *args):
- """
- Send information about the mode of a channel.
-
- @type user: C{str} or C{unicode}
- @param user: The user receiving the name list. Only their nick name,
- not the full hostmask.
-
- @type channel: C{str} or C{unicode}
- @param channel: The channel for which this is the namelist.
-
- @type mode: C{str}
- @param mode: A string describing this channel's modes.
-
- @param args: Any additional arguments required by the modes.
- """
- self.sendLine(":%s %s %s %s %s %s" % (
- self.hostname, RPL_CHANNELMODEIS, user, channel, mode, ' '.join(args)))
-
-
-
-class ServerSupportedFeatures(_CommandDispatcherMixin):
- """
- Handle ISUPPORT messages.
-
- Feature names match those in the ISUPPORT RFC draft identically.
-
- Information regarding the specifics of ISUPPORT was gleaned from
- <http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt>.
- """
- prefix = 'isupport'
-
- def __init__(self):
- self._features = {
- 'CHANNELLEN': 200,
- 'CHANTYPES': tuple('#&'),
- 'MODES': 3,
- 'NICKLEN': 9,
- 'PREFIX': self._parsePrefixParam('(ovh)@+%'),
- # The ISUPPORT draft explicitly says that there is no default for
- # CHANMODES, but we're defaulting it here to handle the case where
- # the IRC server doesn't send us any ISUPPORT information, since
- # IRCClient.getChannelModeParams relies on this value.
- 'CHANMODES': self._parseChanModesParam(['b', '', 'lk'])}
-
-
- def _splitParamArgs(cls, params, valueProcessor=None):
- """
- Split ISUPPORT parameter arguments.
-
- Values can optionally be processed by C{valueProcessor}.
-
- For example::
-
- >>> ServerSupportedFeatures._splitParamArgs(['A:1', 'B:2'])
- (('A', '1'), ('B', '2'))
-
- @type params: C{iterable} of C{str}
-
- @type valueProcessor: C{callable} taking {str}
- @param valueProcessor: Callable to process argument values, or C{None}
- to perform no processing
-
- @rtype: C{list} of C{(str, object)}
- @return: Sequence of C{(name, processedValue)}
- """
- if valueProcessor is None:
- valueProcessor = lambda x: x
-
- def _parse():
- for param in params:
- if ':' not in param:
- param += ':'
- a, b = param.split(':', 1)
- yield a, valueProcessor(b)
- return list(_parse())
- _splitParamArgs = classmethod(_splitParamArgs)
-
-
- def _unescapeParamValue(cls, value):
- """
- Unescape an ISUPPORT parameter.
-
- The only form of supported escape is C{\\xHH}, where HH must be a valid
- 2-digit hexadecimal number.
-
- @rtype: C{str}
- """
- def _unescape():
- parts = value.split('\\x')
- # The first part can never be preceeded by the escape.
- yield parts.pop(0)
- for s in parts:
- octet, rest = s[:2], s[2:]
- try:
- octet = int(octet, 16)
- except ValueError:
- raise ValueError('Invalid hex octet: %r' % (octet,))
- yield chr(octet) + rest
-
- if '\\x' not in value:
- return value
- return ''.join(_unescape())
- _unescapeParamValue = classmethod(_unescapeParamValue)
-
-
- def _splitParam(cls, param):
- """
- Split an ISUPPORT parameter.
-
- @type param: C{str}
-
- @rtype: C{(str, list)}
- @return C{(key, arguments)}
- """
- if '=' not in param:
- param += '='
- key, value = param.split('=', 1)
- return key, map(cls._unescapeParamValue, value.split(','))
- _splitParam = classmethod(_splitParam)
-
-
- def _parsePrefixParam(cls, prefix):
- """
- Parse the ISUPPORT "PREFIX" parameter.
-
- The order in which the parameter arguments appear is significant, the
- earlier a mode appears the more privileges it gives.
-
- @rtype: C{dict} mapping C{str} to C{(str, int)}
- @return: A dictionary mapping a mode character to a two-tuple of
- C({symbol, priority)}, the lower a priority (the lowest being
- C{0}) the more privileges it gives
- """
- if not prefix:
- return None
- if prefix[0] != '(' and ')' not in prefix:
- raise ValueError('Malformed PREFIX parameter')
- modes, symbols = prefix.split(')', 1)
- symbols = zip(symbols, xrange(len(symbols)))
- modes = modes[1:]
- return dict(zip(modes, symbols))
- _parsePrefixParam = classmethod(_parsePrefixParam)
-
-
- def _parseChanModesParam(self, params):
- """
- Parse the ISUPPORT "CHANMODES" parameter.
-
- See L{isupport_CHANMODES} for a detailed explanation of this parameter.
- """
- names = ('addressModes', 'param', 'setParam', 'noParam')
- if len(params) > len(names):
- raise ValueError(
- 'Expecting a maximum of %d channel mode parameters, got %d' % (
- len(names), len(params)))
- items = map(lambda key, value: (key, value or ''), names, params)
- return dict(items)
- _parseChanModesParam = classmethod(_parseChanModesParam)
-
-
- def getFeature(self, feature, default=None):
- """
- Get a server supported feature's value.
-
- A feature with the value C{None} is equivalent to the feature being
- unsupported.
-
- @type feature: C{str}
- @param feature: Feature name
-
- @type default: C{object}
- @param default: The value to default to, assuming that C{feature}
- is not supported
-
- @return: Feature value
- """
- return self._features.get(feature, default)
-
-
- def hasFeature(self, feature):
- """
- Determine whether a feature is supported or not.
-
- @rtype: C{bool}
- """
- return self.getFeature(feature) is not None
-
-
- def parse(self, params):
- """
- Parse ISUPPORT parameters.
-
- If an unknown parameter is encountered, it is simply added to the
- dictionary, keyed by its name, as a tuple of the parameters provided.
-
- @type params: C{iterable} of C{str}
- @param params: Iterable of ISUPPORT parameters to parse
- """
- for param in params:
- key, value = self._splitParam(param)
- if key.startswith('-'):
- self._features.pop(key[1:], None)
- else:
- self._features[key] = self.dispatch(key, value)
-
-
- def isupport_unknown(self, command, params):
- """
- Unknown ISUPPORT parameter.
- """
- return tuple(params)
-
-
- def isupport_CHANLIMIT(self, params):
- """
- The maximum number of each channel type a user may join.
- """
- return self._splitParamArgs(params, _intOrDefault)
-
-
- def isupport_CHANMODES(self, params):
- """
- Available channel modes.
-
- There are 4 categories of channel mode::
-
- addressModes - Modes that add or remove an address to or from a
- list, these modes always take a parameter.
-
- param - Modes that change a setting on a channel, these modes
- always take a parameter.
-
- setParam - Modes that change a setting on a channel, these modes
- only take a parameter when being set.
-
- noParam - Modes that change a setting on a channel, these modes
- never take a parameter.
- """
- try:
- return self._parseChanModesParam(params)
- except ValueError:
- return self.getFeature('CHANMODES')
-
-
- def isupport_CHANNELLEN(self, params):
- """
- Maximum length of a channel name a client may create.
- """
- return _intOrDefault(params[0], self.getFeature('CHANNELLEN'))
-
-
- def isupport_CHANTYPES(self, params):
- """
- Valid channel prefixes.
- """
- return tuple(params[0])
-
-
- def isupport_EXCEPTS(self, params):
- """
- Mode character for "ban exceptions".
-
- The presence of this parameter indicates that the server supports
- this functionality.
- """
- return params[0] or 'e'
-
-
- def isupport_IDCHAN(self, params):
- """
- Safe channel identifiers.
-
- The presence of this parameter indicates that the server supports
- this functionality.
- """
- return self._splitParamArgs(params)
-
-
- def isupport_INVEX(self, params):
- """
- Mode character for "invite exceptions".
-
- The presence of this parameter indicates that the server supports
- this functionality.
- """
- return params[0] or 'I'
-
-
- def isupport_KICKLEN(self, params):
- """
- Maximum length of a kick message a client may provide.
- """
- return _intOrDefault(params[0])
-
-
- def isupport_MAXLIST(self, params):
- """
- Maximum number of "list modes" a client may set on a channel at once.
-
- List modes are identified by the "addressModes" key in CHANMODES.
- """
- return self._splitParamArgs(params, _intOrDefault)
-
-
- def isupport_MODES(self, params):
- """
- Maximum number of modes accepting parameters that may be sent, by a
- client, in a single MODE command.
- """
- return _intOrDefault(params[0])
-
-
- def isupport_NETWORK(self, params):
- """
- IRC network name.
- """
- return params[0]
-
-
- def isupport_NICKLEN(self, params):
- """
- Maximum length of a nickname the client may use.
- """
- return _intOrDefault(params[0], self.getFeature('NICKLEN'))
-
-
- def isupport_PREFIX(self, params):
- """
- Mapping of channel modes that clients may have to status flags.
- """
- try:
- return self._parsePrefixParam(params[0])
- except ValueError:
- return self.getFeature('PREFIX')
-
-
- def isupport_SAFELIST(self, params):
- """
- Flag indicating that a client may request a LIST without being
- disconnected due to the large amount of data generated.
- """
- return True
-
-
- def isupport_STATUSMSG(self, params):
- """
- The server supports sending messages to only to clients on a channel
- with a specific status.
- """
- return params[0]
-
-
- def isupport_TARGMAX(self, params):
- """
- Maximum number of targets allowable for commands that accept multiple
- targets.
- """
- return dict(self._splitParamArgs(params, _intOrDefault))
-
-
- def isupport_TOPICLEN(self, params):
- """
- Maximum length of a topic that may be set.
- """
- return _intOrDefault(params[0])
-
-
-
-class IRCClient(basic.LineReceiver):
- """
- Internet Relay Chat client protocol, with sprinkles.
-
- In addition to providing an interface for an IRC client protocol,
- this class also contains reasonable implementations of many common
- CTCP methods.
-
- TODO
- ====
- - Limit the length of messages sent (because the IRC server probably
- does).
- - Add flood protection/rate limiting for my CTCP replies.
- - NickServ cooperation. (a mix-in?)
-
- @ivar nickname: Nickname the client will use.
- @ivar password: Password used to log on to the server. May be C{None}.
- @ivar realname: Supplied to the server during login as the "Real name"
- or "ircname". May be C{None}.
- @ivar username: Supplied to the server during login as the "User name".
- May be C{None}
-
- @ivar userinfo: Sent in reply to a C{USERINFO} CTCP query. If C{None}, no
- USERINFO reply will be sent.
- "This is used to transmit a string which is settable by
- the user (and never should be set by the client)."
- @ivar fingerReply: Sent in reply to a C{FINGER} CTCP query. If C{None}, no
- FINGER reply will be sent.
- @type fingerReply: Callable or String
-
- @ivar versionName: CTCP VERSION reply, client name. If C{None}, no VERSION
- reply will be sent.
- @type versionName: C{str}, or None.
- @ivar versionNum: CTCP VERSION reply, client version.
- @type versionNum: C{str}, or None.
- @ivar versionEnv: CTCP VERSION reply, environment the client is running in.
- @type versionEnv: C{str}, or None.
-
- @ivar sourceURL: CTCP SOURCE reply, a URL where the source code of this
- client may be found. If C{None}, no SOURCE reply will be sent.
-
- @ivar lineRate: Minimum delay between lines sent to the server. If
- C{None}, no delay will be imposed.
- @type lineRate: Number of Seconds.
-
- @ivar motd: Either L{None} or, between receipt of I{RPL_MOTDSTART} and
- I{RPL_ENDOFMOTD}, a L{list} of L{str}, each of which is the content
- of an I{RPL_MOTD} message.
-
- @ivar erroneousNickFallback: Default nickname assigned when an unregistered
- client triggers an C{ERR_ERRONEUSNICKNAME} while trying to register
- with an illegal nickname.
- @type erroneousNickFallback: C{str}
-
- @ivar _registered: Whether or not the user is registered. It becomes True
- once a welcome has been received from the server.
- @type _registered: C{bool}
-
- @ivar _attemptedNick: The nickname that will try to get registered. It may
- change if it is illegal or already taken. L{nickname} becomes the
- L{_attemptedNick} that is successfully registered.
- @type _attemptedNick: C{str}
-
- @type supported: L{ServerSupportedFeatures}
- @ivar supported: Available ISUPPORT features on the server
-
- @type hostname: C{str}
- @ivar hostname: Host name of the IRC server the client is connected to.
- Initially the host name is C{None} and later is set to the host name
- from which the I{RPL_WELCOME} message is received.
-
- @type _heartbeat: L{task.LoopingCall}
- @ivar _heartbeat: Looping call to perform the keepalive by calling
- L{IRCClient._sendHeartbeat} every L{heartbeatInterval} seconds, or
- C{None} if there is no heartbeat.
-
- @type heartbeatInterval: C{float}
- @ivar heartbeatInterval: Interval, in seconds, to send I{PING} messages to
- the server as a form of keepalive, defaults to 120 seconds. Use C{None}
- to disable the heartbeat.
- """
- hostname = None
- motd = None
- nickname = 'irc'
- password = None
- realname = None
- username = None
- ### Responses to various CTCP queries.
-
- userinfo = None
- # fingerReply is a callable returning a string, or a str()able object.
- fingerReply = None
- versionName = None
- versionNum = None
- versionEnv = None
-
- sourceURL = "http://twistedmatrix.com/downloads/"
-
- dcc_destdir = '.'
- dcc_sessions = None
-
- # If this is false, no attempt will be made to identify
- # ourself to the server.
- performLogin = 1
-
- lineRate = None
- _queue = None
- _queueEmptying = None
-
- delimiter = '\n' # '\r\n' will also work (see dataReceived)
-
- __pychecker__ = 'unusednames=params,prefix,channel'
-
- _registered = False
- _attemptedNick = ''
- erroneousNickFallback = 'defaultnick'
-
- _heartbeat = None
- heartbeatInterval = 120
-
-
- def _reallySendLine(self, line):
- return basic.LineReceiver.sendLine(self, lowQuote(line) + '\r')
-
- def sendLine(self, line):
- if self.lineRate is None:
- self._reallySendLine(line)
- else:
- self._queue.append(line)
- if not self._queueEmptying:
- self._sendLine()
-
- def _sendLine(self):
- if self._queue:
- self._reallySendLine(self._queue.pop(0))
- self._queueEmptying = reactor.callLater(self.lineRate,
- self._sendLine)
- else:
- self._queueEmptying = None
-
-
- def connectionLost(self, reason):
- basic.LineReceiver.connectionLost(self, reason)
- self.stopHeartbeat()
-
-
- def _createHeartbeat(self):
- """
- Create the heartbeat L{LoopingCall}.
- """
- return task.LoopingCall(self._sendHeartbeat)
-
-
- def _sendHeartbeat(self):
- """
- Send a I{PING} message to the IRC server as a form of keepalive.
- """
- self.sendLine('PING ' + self.hostname)
-
-
- def stopHeartbeat(self):
- """
- Stop sending I{PING} messages to keep the connection to the server
- alive.
-
- @since: 11.1
- """
- if self._heartbeat is not None:
- self._heartbeat.stop()
- self._heartbeat = None
-
-
- def startHeartbeat(self):
- """
- Start sending I{PING} messages every L{IRCClient.heartbeatInterval}
- seconds to keep the connection to the server alive during periods of no
- activity.
-
- @since: 11.1
- """
- self.stopHeartbeat()
- if self.heartbeatInterval is None:
- return
- self._heartbeat = self._createHeartbeat()
- self._heartbeat.start(self.heartbeatInterval, now=False)
-
-
- ### Interface level client->user output methods
- ###
- ### You'll want to override these.
-
- ### Methods relating to the server itself
-
- def created(self, when):
- """
- Called with creation date information about the server, usually at logon.
-
- @type when: C{str}
- @param when: A string describing when the server was created, probably.
- """
-
- def yourHost(self, info):
- """
- Called with daemon information about the server, usually at logon.
-
- @type info: C{str}
- @param when: A string describing what software the server is running, probably.
- """
-
- def myInfo(self, servername, version, umodes, cmodes):
- """
- Called with information about the server, usually at logon.
-
- @type servername: C{str}
- @param servername: The hostname of this server.
-
- @type version: C{str}
- @param version: A description of what software this server runs.
-
- @type umodes: C{str}
- @param umodes: All the available user modes.
-
- @type cmodes: C{str}
- @param cmodes: All the available channel modes.
- """
-
- def luserClient(self, info):
- """
- Called with information about the number of connections, usually at logon.
-
- @type info: C{str}
- @param info: A description of the number of clients and servers
- connected to the network, probably.
- """
-
- def bounce(self, info):
- """
- Called with information about where the client should reconnect.
-
- @type info: C{str}
- @param info: A plaintext description of the address that should be
- connected to.
- """
-
- def isupport(self, options):
- """
- Called with various information about what the server supports.
-
- @type options: C{list} of C{str}
- @param options: Descriptions of features or limits of the server, possibly
- in the form "NAME=VALUE".
- """
-
- def luserChannels(self, channels):
- """
- Called with the number of channels existant on the server.
-
- @type channels: C{int}
- """
-
- def luserOp(self, ops):
- """
- Called with the number of ops logged on to the server.
-
- @type ops: C{int}
- """
-
- def luserMe(self, info):
- """
- Called with information about the server connected to.
-
- @type info: C{str}
- @param info: A plaintext string describing the number of users and servers
- connected to this server.
- """
-
- ### Methods involving me directly
-
- def privmsg(self, user, channel, message):
- """
- Called when I have a message from a user to me or a channel.
- """
- pass
-
- def joined(self, channel):
- """
- Called when I finish joining a channel.
-
- channel has the starting character (C{'#'}, C{'&'}, C{'!'}, or C{'+'})
- intact.
- """
-
- def left(self, channel):
- """
- Called when I have left a channel.
-
- channel has the starting character (C{'#'}, C{'&'}, C{'!'}, or C{'+'})
- intact.
- """
-
-
- def noticed(self, user, channel, message):
- """
- Called when I have a notice from a user to me or a channel.
-
- If the client makes any automated replies, it must not do so in
- response to a NOTICE message, per the RFC::
-
- The difference between NOTICE and PRIVMSG is that
- automatic replies MUST NEVER be sent in response to a
- NOTICE message. [...] The object of this rule is to avoid
- loops between clients automatically sending something in
- response to something it received.
- """
-
-
- def modeChanged(self, user, channel, set, modes, args):
- """
- Called when users or channel's modes are changed.
-
- @type user: C{str}
- @param user: The user and hostmask which instigated this change.
-
- @type channel: C{str}
- @param channel: The channel where the modes are changed. If args is
- empty the channel for which the modes are changing. If the changes are
- at server level it could be equal to C{user}.
-
- @type set: C{bool} or C{int}
- @param set: True if the mode(s) is being added, False if it is being
- removed. If some modes are added and others removed at the same time
- this function will be called twice, the first time with all the added
- modes, the second with the removed ones. (To change this behaviour
- override the irc_MODE method)
-
- @type modes: C{str}
- @param modes: The mode or modes which are being changed.
-
- @type args: C{tuple}
- @param args: Any additional information required for the mode
- change.
- """
-
- def pong(self, user, secs):
- """
- Called with the results of a CTCP PING query.
- """
- pass
-
- def signedOn(self):
- """
- Called after sucessfully signing on to the server.
- """
- pass
-
- def kickedFrom(self, channel, kicker, message):
- """
- Called when I am kicked from a channel.
- """
- pass
-
- def nickChanged(self, nick):
- """
- Called when my nick has been changed.
- """
- self.nickname = nick
-
-
- ### Things I observe other people doing in a channel.
-
- def userJoined(self, user, channel):
- """
- Called when I see another user joining a channel.
- """
- pass
-
- def userLeft(self, user, channel):
- """
- Called when I see another user leaving a channel.
- """
- pass
-
- def userQuit(self, user, quitMessage):
- """
- Called when I see another user disconnect from the network.
- """
- pass
-
- def userKicked(self, kickee, channel, kicker, message):
- """
- Called when I observe someone else being kicked from a channel.
- """
- pass
-
- def action(self, user, channel, data):
- """
- Called when I see a user perform an ACTION on a channel.
- """
- pass
-
- def topicUpdated(self, user, channel, newTopic):
- """
- In channel, user changed the topic to newTopic.
-
- Also called when first joining a channel.
- """
- pass
-
- def userRenamed(self, oldname, newname):
- """
- A user changed their name from oldname to newname.
- """
- pass
-
- ### Information from the server.
-
- def receivedMOTD(self, motd):
- """
- I received a message-of-the-day banner from the server.
-
- motd is a list of strings, where each string was sent as a seperate
- message from the server. To display, you might want to use::
-
- '\\n'.join(motd)
-
- to get a nicely formatted string.
- """
- pass
-
- ### user input commands, client->server
- ### Your client will want to invoke these.
-
- def join(self, channel, key=None):
- """
- Join a channel.
-
- @type channel: C{str}
- @param channel: The name of the channel to join. If it has no prefix,
- C{'#'} will be prepended to it.
- @type key: C{str}
- @param key: If specified, the key used to join the channel.
- """
- if channel[0] not in CHANNEL_PREFIXES:
- channel = '#' + channel
- if key:
- self.sendLine("JOIN %s %s" % (channel, key))
- else:
- self.sendLine("JOIN %s" % (channel,))
-
- def leave(self, channel, reason=None):
- """
- Leave a channel.
-
- @type channel: C{str}
- @param channel: The name of the channel to leave. If it has no prefix,
- C{'#'} will be prepended to it.
- @type reason: C{str}
- @param reason: If given, the reason for leaving.
- """
- if channel[0] not in CHANNEL_PREFIXES:
- channel = '#' + channel
- if reason:
- self.sendLine("PART %s :%s" % (channel, reason))
- else:
- self.sendLine("PART %s" % (channel,))
-
- def kick(self, channel, user, reason=None):
- """
- Attempt to kick a user from a channel.
-
- @type channel: C{str}
- @param channel: The name of the channel to kick the user from. If it has
- no prefix, C{'#'} will be prepended to it.
- @type user: C{str}
- @param user: The nick of the user to kick.
- @type reason: C{str}
- @param reason: If given, the reason for kicking the user.
- """
- if channel[0] not in CHANNEL_PREFIXES:
- channel = '#' + channel
- if reason:
- self.sendLine("KICK %s %s :%s" % (channel, user, reason))
- else:
- self.sendLine("KICK %s %s" % (channel, user))
-
- part = leave
-
-
- def invite(self, user, channel):
- """
- Attempt to invite user to channel
-
- @type user: C{str}
- @param user: The user to invite
- @type channel: C{str}
- @param channel: The channel to invite the user too
-
- @since: 11.0
- """
- if channel[0] not in CHANNEL_PREFIXES:
- channel = '#' + channel
- self.sendLine("INVITE %s %s" % (user, channel))
-
-
- def topic(self, channel, topic=None):
- """
- Attempt to set the topic of the given channel, or ask what it is.
-
- If topic is None, then I sent a topic query instead of trying to set the
- topic. The server should respond with a TOPIC message containing the
- current topic of the given channel.
-
- @type channel: C{str}
- @param channel: The name of the channel to change the topic on. If it
- has no prefix, C{'#'} will be prepended to it.
- @type topic: C{str}
- @param topic: If specified, what to set the topic to.
- """
- # << TOPIC #xtestx :fff
- if channel[0] not in CHANNEL_PREFIXES:
- channel = '#' + channel
- if topic != None:
- self.sendLine("TOPIC %s :%s" % (channel, topic))
- else:
- self.sendLine("TOPIC %s" % (channel,))
-
-
- def mode(self, chan, set, modes, limit = None, user = None, mask = None):
- """
- Change the modes on a user or channel.
-
- The C{limit}, C{user}, and C{mask} parameters are mutually exclusive.
-
- @type chan: C{str}
- @param chan: The name of the channel to operate on.
- @type set: C{bool}
- @param set: True to give the user or channel permissions and False to
- remove them.
- @type modes: C{str}
- @param modes: The mode flags to set on the user or channel.
- @type limit: C{int}
- @param limit: In conjuction with the C{'l'} mode flag, limits the
- number of users on the channel.
- @type user: C{str}
- @param user: The user to change the mode on.
- @type mask: C{str}
- @param mask: In conjuction with the C{'b'} mode flag, sets a mask of
- users to be banned from the channel.
- """
- if set:
- line = 'MODE %s +%s' % (chan, modes)
- else:
- line = 'MODE %s -%s' % (chan, modes)
- if limit is not None:
- line = '%s %d' % (line, limit)
- elif user is not None:
- line = '%s %s' % (line, user)
- elif mask is not None:
- line = '%s %s' % (line, mask)
- self.sendLine(line)
-
-
- def say(self, channel, message, length=None):
- """
- Send a message to a channel
-
- @type channel: C{str}
- @param channel: The channel to say the message on. If it has no prefix,
- C{'#'} will be prepended to it.
- @type message: C{str}
- @param message: The message to say.
- @type length: C{int}
- @param length: The maximum number of octets to send at a time. This has
- the effect of turning a single call to C{msg()} into multiple
- commands to the server. This is useful when long messages may be
- sent that would otherwise cause the server to kick us off or
- silently truncate the text we are sending. If None is passed, the
- entire message is always send in one command.
- """
- if channel[0] not in CHANNEL_PREFIXES:
- channel = '#' + channel
- self.msg(channel, message, length)
-
-
- def _safeMaximumLineLength(self, command):
- """
- Estimate a safe maximum line length for the given command.
-
- This is done by assuming the maximum values for nickname length,
- realname and hostname combined with the command that needs to be sent
- and some guessing. A theoretical maximum value is used because it is
- possible that our nickname, username or hostname changes (on the server
- side) while the length is still being calculated.
- """
- # :nickname!realname@hostname COMMAND ...
- theoretical = ':%s!%s@%s %s' % (
- 'a' * self.supported.getFeature('NICKLEN'),
- # This value is based on observation.
- 'b' * 10,
- # See <http://tools.ietf.org/html/rfc2812#section-2.3.1>.
- 'c' * 63,
- command)
- # Fingers crossed.
- fudge = 10
- return MAX_COMMAND_LENGTH - len(theoretical) - fudge
-
-
- def msg(self, user, message, length=None):
- """
- Send a message to a user or channel.
-
- The message will be split into multiple commands to the server if:
- - The message contains any newline characters
- - Any span between newline characters is longer than the given
- line-length.
-
- @param user: Username or channel name to which to direct the
- message.
- @type user: C{str}
-
- @param message: Text to send.
- @type message: C{str}
-
- @param length: Maximum number of octets to send in a single
- command, including the IRC protocol framing. If C{None} is given
- then L{IRCClient._safeMaximumLineLength} is used to determine a
- value.
- @type length: C{int}
- """
- fmt = 'PRIVMSG %s :' % (user,)
-
- if length is None:
- length = self._safeMaximumLineLength(fmt)
-
- # Account for the line terminator.
- minimumLength = len(fmt) + 2
- if length <= minimumLength:
- raise ValueError("Maximum length must exceed %d for message "
- "to %s" % (minimumLength, user))
- for line in split(message, length - minimumLength):
- self.sendLine(fmt + line)
-
-
- def notice(self, user, message):
- """
- Send a notice to a user.
-
- Notices are like normal message, but should never get automated
- replies.
-
- @type user: C{str}
- @param user: The user to send a notice to.
- @type message: C{str}
- @param message: The contents of the notice to send.
- """
- self.sendLine("NOTICE %s :%s" % (user, message))
-
-
- def away(self, message=''):
- """
- Mark this client as away.
-
- @type message: C{str}
- @param message: If specified, the away message.
- """
- self.sendLine("AWAY :%s" % message)
-
-
- def back(self):
- """
- Clear the away status.
- """
- # An empty away marks us as back
- self.away()
-
-
- def whois(self, nickname, server=None):
- """
- Retrieve user information about the given nick name.
-
- @type nickname: C{str}
- @param nickname: The nick name about which to retrieve information.
-
- @since: 8.2
- """
- if server is None:
- self.sendLine('WHOIS ' + nickname)
- else:
- self.sendLine('WHOIS %s %s' % (server, nickname))
-
-
- def register(self, nickname, hostname='foo', servername='bar'):
- """
- Login to the server.
-
- @type nickname: C{str}
- @param nickname: The nickname to register.
- @type hostname: C{str}
- @param hostname: If specified, the hostname to logon as.
- @type servername: C{str}
- @param servername: If specified, the servername to logon as.
- """
- if self.password is not None:
- self.sendLine("PASS %s" % self.password)
- self.setNick(nickname)
- if self.username is None:
- self.username = nickname
- self.sendLine("USER %s %s %s :%s" % (self.username, hostname, servername, self.realname))
-
-
- def setNick(self, nickname):
- """
- Set this client's nickname.
-
- @type nickname: C{str}
- @param nickname: The nickname to change to.
- """
- self._attemptedNick = nickname
- self.sendLine("NICK %s" % nickname)
-
-
- def quit(self, message = ''):
- """
- Disconnect from the server
-
- @type message: C{str}
-
- @param message: If specified, the message to give when quitting the
- server.
- """
- self.sendLine("QUIT :%s" % message)
-
- ### user input commands, client->client
-
- def describe(self, channel, action):
- """
- Strike a pose.
-
- @type channel: C{str}
- @param channel: The name of the channel to have an action on. If it
- has no prefix, it is sent to the user of that name.
- @type action: C{str}
- @param action: The action to preform.
- @since: 9.0
- """
- self.ctcpMakeQuery(channel, [('ACTION', action)])
-
-
- _pings = None
- _MAX_PINGRING = 12
-
- def ping(self, user, text = None):
- """
- Measure round-trip delay to another IRC client.
- """
- if self._pings is None:
- self._pings = {}
-
- if text is None:
- chars = string.letters + string.digits + string.punctuation
- key = ''.join([random.choice(chars) for i in range(12)])
- else:
- key = str(text)
- self._pings[(user, key)] = time.time()
- self.ctcpMakeQuery(user, [('PING', key)])
-
- if len(self._pings) > self._MAX_PINGRING:
- # Remove some of the oldest entries.
- byValue = [(v, k) for (k, v) in self._pings.items()]
- byValue.sort()
- excess = self._MAX_PINGRING - len(self._pings)
- for i in xrange(excess):
- del self._pings[byValue[i][1]]
-
-
- def dccSend(self, user, file):
- if type(file) == types.StringType:
- file = open(file, 'r')
-
- size = fileSize(file)
-
- name = getattr(file, "name", "file@%s" % (id(file),))
-
- factory = DccSendFactory(file)
- port = reactor.listenTCP(0, factory, 1)
-
- raise NotImplementedError,(
- "XXX!!! Help! I need to bind a socket, have it listen, and tell me its address. "
- "(and stop accepting once we've made a single connection.)")
-
- my_address = struct.pack("!I", my_address)
-
- args = ['SEND', name, my_address, str(port)]
-
- if not (size is None):
- args.append(size)
-
- args = string.join(args, ' ')
-
- self.ctcpMakeQuery(user, [('DCC', args)])
-
-
- def dccResume(self, user, fileName, port, resumePos):
- """
- Send a DCC RESUME request to another user.
- """
- self.ctcpMakeQuery(user, [
- ('DCC', ['RESUME', fileName, port, resumePos])])
-
-
- def dccAcceptResume(self, user, fileName, port, resumePos):
- """
- Send a DCC ACCEPT response to clients who have requested a resume.
- """
- self.ctcpMakeQuery(user, [
- ('DCC', ['ACCEPT', fileName, port, resumePos])])
-
- ### server->client messages
- ### You might want to fiddle with these,
- ### but it is safe to leave them alone.
-
- def irc_ERR_NICKNAMEINUSE(self, prefix, params):
- """
- Called when we try to register or change to a nickname that is already
- taken.
- """
- self._attemptedNick = self.alterCollidedNick(self._attemptedNick)
- self.setNick(self._attemptedNick)
-
-
- def alterCollidedNick(self, nickname):
- """
- Generate an altered version of a nickname that caused a collision in an
- effort to create an unused related name for subsequent registration.
-
- @param nickname: The nickname a user is attempting to register.
- @type nickname: C{str}
-
- @returns: A string that is in some way different from the nickname.
- @rtype: C{str}
- """
- return nickname + '_'
-
-
- def irc_ERR_ERRONEUSNICKNAME(self, prefix, params):
- """
- Called when we try to register or change to an illegal nickname.
-
- The server should send this reply when the nickname contains any
- disallowed characters. The bot will stall, waiting for RPL_WELCOME, if
- we don't handle this during sign-on.
-
- @note: The method uses the spelling I{erroneus}, as it appears in
- the RFC, section 6.1.
- """
- if not self._registered:
- self.setNick(self.erroneousNickFallback)
-
-
- def irc_ERR_PASSWDMISMATCH(self, prefix, params):
- """
- Called when the login was incorrect.
- """
- raise IRCPasswordMismatch("Password Incorrect.")
-
-
- def irc_RPL_WELCOME(self, prefix, params):
- """
- Called when we have received the welcome from the server.
- """
- self.hostname = prefix
- self._registered = True
- self.nickname = self._attemptedNick
- self.signedOn()
- self.startHeartbeat()
-
-
- def irc_JOIN(self, prefix, params):
- """
- Called when a user joins a channel.
- """
- nick = string.split(prefix,'!')[0]
- channel = params[-1]
- if nick == self.nickname:
- self.joined(channel)
- else:
- self.userJoined(nick, channel)
-
- def irc_PART(self, prefix, params):
- """
- Called when a user leaves a channel.
- """
- nick = string.split(prefix,'!')[0]
- channel = params[0]
- if nick == self.nickname:
- self.left(channel)
- else:
- self.userLeft(nick, channel)
-
- def irc_QUIT(self, prefix, params):
- """
- Called when a user has quit.
- """
- nick = string.split(prefix,'!')[0]
- self.userQuit(nick, params[0])
-
-
- def irc_MODE(self, user, params):
- """
- Parse a server mode change message.
- """
- channel, modes, args = params[0], params[1], params[2:]
-
- if modes[0] not in '-+':
- modes = '+' + modes
-
- if channel == self.nickname:
- # This is a mode change to our individual user, not a channel mode
- # that involves us.
- paramModes = self.getUserModeParams()
- else:
- paramModes = self.getChannelModeParams()
-
- try:
- added, removed = parseModes(modes, args, paramModes)
- except IRCBadModes:
- log.err(None, 'An error occured while parsing the following '
- 'MODE message: MODE %s' % (' '.join(params),))
- else:
- if added:
- modes, params = zip(*added)
- self.modeChanged(user, channel, True, ''.join(modes), params)
-
- if removed:
- modes, params = zip(*removed)
- self.modeChanged(user, channel, False, ''.join(modes), params)
-
-
- def irc_PING(self, prefix, params):
- """
- Called when some has pinged us.
- """
- self.sendLine("PONG %s" % params[-1])
-
- def irc_PRIVMSG(self, prefix, params):
- """
- Called when we get a message.
- """
- user = prefix
- channel = params[0]
- message = params[-1]
-
- if not message:
- # Don't raise an exception if we get blank message.
- return
-
- if message[0] == X_DELIM:
- m = ctcpExtract(message)
- if m['extended']:
- self.ctcpQuery(user, channel, m['extended'])
-
- if not m['normal']:
- return
-
- message = string.join(m['normal'], ' ')
-
- self.privmsg(user, channel, message)
-
- def irc_NOTICE(self, prefix, params):
- """
- Called when a user gets a notice.
- """
- user = prefix
- channel = params[0]
- message = params[-1]
-
- if message[0]==X_DELIM:
- m = ctcpExtract(message)
- if m['extended']:
- self.ctcpReply(user, channel, m['extended'])
-
- if not m['normal']:
- return
-
- message = string.join(m['normal'], ' ')
-
- self.noticed(user, channel, message)
-
- def irc_NICK(self, prefix, params):
- """
- Called when a user changes their nickname.
- """
- nick = string.split(prefix,'!', 1)[0]
- if nick == self.nickname:
- self.nickChanged(params[0])
- else:
- self.userRenamed(nick, params[0])
-
- def irc_KICK(self, prefix, params):
- """
- Called when a user is kicked from a channel.
- """
- kicker = string.split(prefix,'!')[0]
- channel = params[0]
- kicked = params[1]
- message = params[-1]
- if string.lower(kicked) == string.lower(self.nickname):
- # Yikes!
- self.kickedFrom(channel, kicker, message)
- else:
- self.userKicked(kicked, channel, kicker, message)
-
- def irc_TOPIC(self, prefix, params):
- """
- Someone in the channel set the topic.
- """
- user = string.split(prefix, '!')[0]
- channel = params[0]
- newtopic = params[1]
- self.topicUpdated(user, channel, newtopic)
-
- def irc_RPL_TOPIC(self, prefix, params):
- """
- Called when the topic for a channel is initially reported or when it
- subsequently changes.
- """
- user = string.split(prefix, '!')[0]
- channel = params[1]
- newtopic = params[2]
- self.topicUpdated(user, channel, newtopic)
-
- def irc_RPL_NOTOPIC(self, prefix, params):
- user = string.split(prefix, '!')[0]
- channel = params[1]
- newtopic = ""
- self.topicUpdated(user, channel, newtopic)
-
- def irc_RPL_MOTDSTART(self, prefix, params):
- if params[-1].startswith("- "):
- params[-1] = params[-1][2:]
- self.motd = [params[-1]]
-
- def irc_RPL_MOTD(self, prefix, params):
- if params[-1].startswith("- "):
- params[-1] = params[-1][2:]
- if self.motd is None:
- self.motd = []
- self.motd.append(params[-1])
-
-
- def irc_RPL_ENDOFMOTD(self, prefix, params):
- """
- I{RPL_ENDOFMOTD} indicates the end of the message of the day
- messages. Deliver the accumulated lines to C{receivedMOTD}.
- """
- motd = self.motd
- self.motd = None
- self.receivedMOTD(motd)
-
-
- def irc_RPL_CREATED(self, prefix, params):
- self.created(params[1])
-
- def irc_RPL_YOURHOST(self, prefix, params):
- self.yourHost(params[1])
-
- def irc_RPL_MYINFO(self, prefix, params):
- info = params[1].split(None, 3)
- while len(info) < 4:
- info.append(None)
- self.myInfo(*info)
-
- def irc_RPL_BOUNCE(self, prefix, params):
- self.bounce(params[1])
-
- def irc_RPL_ISUPPORT(self, prefix, params):
- args = params[1:-1]
- # Several ISUPPORT messages, in no particular order, may be sent
- # to the client at any given point in time (usually only on connect,
- # though.) For this reason, ServerSupportedFeatures.parse is intended
- # to mutate the supported feature list.
- self.supported.parse(args)
- self.isupport(args)
-
- def irc_RPL_LUSERCLIENT(self, prefix, params):
- self.luserClient(params[1])
-
- def irc_RPL_LUSEROP(self, prefix, params):
- try:
- self.luserOp(int(params[1]))
- except ValueError:
- pass
-
- def irc_RPL_LUSERCHANNELS(self, prefix, params):
- try:
- self.luserChannels(int(params[1]))
- except ValueError:
- pass
-
- def irc_RPL_LUSERME(self, prefix, params):
- self.luserMe(params[1])
-
- def irc_unknown(self, prefix, command, params):
- pass
-
- ### Receiving a CTCP query from another party
- ### It is safe to leave these alone.
-
-
- def ctcpQuery(self, user, channel, messages):
- """
- Dispatch method for any CTCP queries received.
-
- Duplicated CTCP queries are ignored and no dispatch is
- made. Unrecognized CTCP queries invoke L{IRCClient.ctcpUnknownQuery}.
- """
- seen = set()
- for tag, data in messages:
- method = getattr(self, 'ctcpQuery_%s' % tag, None)
- if tag not in seen:
- if method is not None:
- method(user, channel, data)
- else:
- self.ctcpUnknownQuery(user, channel, tag, data)
- seen.add(tag)
-
-
- def ctcpUnknownQuery(self, user, channel, tag, data):
- """
- Fallback handler for unrecognized CTCP queries.
-
- No CTCP I{ERRMSG} reply is made to remove a potential denial of service
- avenue.
- """
- log.msg('Unknown CTCP query from %r: %r %r' % (user, tag, data))
-
-
- def ctcpQuery_ACTION(self, user, channel, data):
- self.action(user, channel, data)
-
- def ctcpQuery_PING(self, user, channel, data):
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick, [("PING", data)])
-
- def ctcpQuery_FINGER(self, user, channel, data):
- if data is not None:
- self.quirkyMessage("Why did %s send '%s' with a FINGER query?"
- % (user, data))
- if not self.fingerReply:
- return
-
- if callable(self.fingerReply):
- reply = self.fingerReply()
- else:
- reply = str(self.fingerReply)
-
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick, [('FINGER', reply)])
-
- def ctcpQuery_VERSION(self, user, channel, data):
- if data is not None:
- self.quirkyMessage("Why did %s send '%s' with a VERSION query?"
- % (user, data))
-
- if self.versionName:
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick, [('VERSION', '%s:%s:%s' %
- (self.versionName,
- self.versionNum or '',
- self.versionEnv or ''))])
-
- def ctcpQuery_SOURCE(self, user, channel, data):
- if data is not None:
- self.quirkyMessage("Why did %s send '%s' with a SOURCE query?"
- % (user, data))
- if self.sourceURL:
- nick = string.split(user,"!")[0]
- # The CTCP document (Zeuge, Rollo, Mesander 1994) says that SOURCE
- # replies should be responded to with the location of an anonymous
- # FTP server in host:directory:file format. I'm taking the liberty
- # of bringing it into the 21st century by sending a URL instead.
- self.ctcpMakeReply(nick, [('SOURCE', self.sourceURL),
- ('SOURCE', None)])
-
- def ctcpQuery_USERINFO(self, user, channel, data):
- if data is not None:
- self.quirkyMessage("Why did %s send '%s' with a USERINFO query?"
- % (user, data))
- if self.userinfo:
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick, [('USERINFO', self.userinfo)])
-
- def ctcpQuery_CLIENTINFO(self, user, channel, data):
- """
- A master index of what CTCP tags this client knows.
-
- If no arguments are provided, respond with a list of known tags.
- If an argument is provided, provide human-readable help on
- the usage of that tag.
- """
-
- nick = string.split(user,"!")[0]
- if not data:
- # XXX: prefixedMethodNames gets methods from my *class*,
- # but it's entirely possible that this *instance* has more
- # methods.
- names = reflect.prefixedMethodNames(self.__class__,
- 'ctcpQuery_')
-
- self.ctcpMakeReply(nick, [('CLIENTINFO',
- string.join(names, ' '))])
- else:
- args = string.split(data)
- method = getattr(self, 'ctcpQuery_%s' % (args[0],), None)
- if not method:
- self.ctcpMakeReply(nick, [('ERRMSG',
- "CLIENTINFO %s :"
- "Unknown query '%s'"
- % (data, args[0]))])
- return
- doc = getattr(method, '__doc__', '')
- self.ctcpMakeReply(nick, [('CLIENTINFO', doc)])
-
-
- def ctcpQuery_ERRMSG(self, user, channel, data):
- # Yeah, this seems strange, but that's what the spec says to do
- # when faced with an ERRMSG query (not a reply).
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick, [('ERRMSG',
- "%s :No error has occoured." % data)])
-
- def ctcpQuery_TIME(self, user, channel, data):
- if data is not None:
- self.quirkyMessage("Why did %s send '%s' with a TIME query?"
- % (user, data))
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick,
- [('TIME', ':%s' %
- time.asctime(time.localtime(time.time())))])
-
- def ctcpQuery_DCC(self, user, channel, data):
- """Initiate a Direct Client Connection
- """
-
- if not data: return
- dcctype = data.split(None, 1)[0].upper()
- handler = getattr(self, "dcc_" + dcctype, None)
- if handler:
- if self.dcc_sessions is None:
- self.dcc_sessions = []
- data = data[len(dcctype)+1:]
- handler(user, channel, data)
- else:
- nick = string.split(user,"!")[0]
- self.ctcpMakeReply(nick, [('ERRMSG',
- "DCC %s :Unknown DCC type '%s'"
- % (data, dcctype))])
- self.quirkyMessage("%s offered unknown DCC type %s"
- % (user, dcctype))
-
- def dcc_SEND(self, user, channel, data):
- # Use splitQuoted for those who send files with spaces in the names.
- data = text.splitQuoted(data)
- if len(data) < 3:
- raise IRCBadMessage, "malformed DCC SEND request: %r" % (data,)
-
- (filename, address, port) = data[:3]
-
- address = dccParseAddress(address)
- try:
- port = int(port)
- except ValueError:
- raise IRCBadMessage, "Indecipherable port %r" % (port,)
-
- size = -1
- if len(data) >= 4:
- try:
- size = int(data[3])
- except ValueError:
- pass
-
- # XXX Should we bother passing this data?
- self.dccDoSend(user, address, port, filename, size, data)
-
- def dcc_ACCEPT(self, user, channel, data):
- data = text.splitQuoted(data)
- if len(data) < 3:
- raise IRCBadMessage, "malformed DCC SEND ACCEPT request: %r" % (data,)
- (filename, port, resumePos) = data[:3]
- try:
- port = int(port)
- resumePos = int(resumePos)
- except ValueError:
- return
-
- self.dccDoAcceptResume(user, filename, port, resumePos)
-
- def dcc_RESUME(self, user, channel, data):
- data = text.splitQuoted(data)
- if len(data) < 3:
- raise IRCBadMessage, "malformed DCC SEND RESUME request: %r" % (data,)
- (filename, port, resumePos) = data[:3]
- try:
- port = int(port)
- resumePos = int(resumePos)
- except ValueError:
- return
- self.dccDoResume(user, filename, port, resumePos)
-
- def dcc_CHAT(self, user, channel, data):
- data = text.splitQuoted(data)
- if len(data) < 3:
- raise IRCBadMessage, "malformed DCC CHAT request: %r" % (data,)
-
- (filename, address, port) = data[:3]
-
- address = dccParseAddress(address)
- try:
- port = int(port)
- except ValueError:
- raise IRCBadMessage, "Indecipherable port %r" % (port,)
-
- self.dccDoChat(user, channel, address, port, data)
-
- ### The dccDo methods are the slightly higher-level siblings of
- ### common dcc_ methods; the arguments have been parsed for them.
-
- def dccDoSend(self, user, address, port, fileName, size, data):
- """Called when I receive a DCC SEND offer from a client.
-
- By default, I do nothing here."""
- ## filename = path.basename(arg)
- ## protocol = DccFileReceive(filename, size,
- ## (user,channel,data),self.dcc_destdir)
- ## reactor.clientTCP(address, port, protocol)
- ## self.dcc_sessions.append(protocol)
- pass
-
- def dccDoResume(self, user, file, port, resumePos):
- """Called when a client is trying to resume an offered file
- via DCC send. It should be either replied to with a DCC
- ACCEPT or ignored (default)."""
- pass
-
- def dccDoAcceptResume(self, user, file, port, resumePos):
- """Called when a client has verified and accepted a DCC resume
- request made by us. By default it will do nothing."""
- pass
-
- def dccDoChat(self, user, channel, address, port, data):
- pass
- #factory = DccChatFactory(self, queryData=(user, channel, data))
- #reactor.connectTCP(address, port, factory)
- #self.dcc_sessions.append(factory)
-
- #def ctcpQuery_SED(self, user, data):
- # """Simple Encryption Doodoo
- #
- # Feel free to implement this, but no specification is available.
- # """
- # raise NotImplementedError
-
-
- def ctcpMakeReply(self, user, messages):
- """
- Send one or more C{extended messages} as a CTCP reply.
-
- @type messages: a list of extended messages. An extended
- message is a (tag, data) tuple, where 'data' may be C{None}.
- """
- self.notice(user, ctcpStringify(messages))
-
- ### client CTCP query commands
-
- def ctcpMakeQuery(self, user, messages):
- """
- Send one or more C{extended messages} as a CTCP query.
-
- @type messages: a list of extended messages. An extended
- message is a (tag, data) tuple, where 'data' may be C{None}.
- """
- self.msg(user, ctcpStringify(messages))
-
- ### Receiving a response to a CTCP query (presumably to one we made)
- ### You may want to add methods here, or override UnknownReply.
-
- def ctcpReply(self, user, channel, messages):
- """
- Dispatch method for any CTCP replies received.
- """
- for m in messages:
- method = getattr(self, "ctcpReply_%s" % m[0], None)
- if method:
- method(user, channel, m[1])
- else:
- self.ctcpUnknownReply(user, channel, m[0], m[1])
-
- def ctcpReply_PING(self, user, channel, data):
- nick = user.split('!', 1)[0]
- if (not self._pings) or (not self._pings.has_key((nick, data))):
- raise IRCBadMessage,\
- "Bogus PING response from %s: %s" % (user, data)
-
- t0 = self._pings[(nick, data)]
- self.pong(user, time.time() - t0)
-
- def ctcpUnknownReply(self, user, channel, tag, data):
- """Called when a fitting ctcpReply_ method is not found.
-
- XXX: If the client makes arbitrary CTCP queries,
- this method should probably show the responses to
- them instead of treating them as anomolies.
- """
- log.msg("Unknown CTCP reply from %s: %s %s\n"
- % (user, tag, data))
-
- ### Error handlers
- ### You may override these with something more appropriate to your UI.
-
- def badMessage(self, line, excType, excValue, tb):
- """When I get a message that's so broken I can't use it.
- """
- log.msg(line)
- log.msg(string.join(traceback.format_exception(excType,
- excValue,
- tb),''))
-
- def quirkyMessage(self, s):
- """This is called when I receive a message which is peculiar,
- but not wholly indecipherable.
- """
- log.msg(s + '\n')
-
- ### Protocool methods
-
- def connectionMade(self):
- self.supported = ServerSupportedFeatures()
- self._queue = []
- if self.performLogin:
- self.register(self.nickname)
-
- def dataReceived(self, data):
- basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
-
- def lineReceived(self, line):
- line = lowDequote(line)
- try:
- prefix, command, params = parsemsg(line)
- if command in numeric_to_symbolic:
- command = numeric_to_symbolic[command]
- self.handleCommand(command, prefix, params)
- except IRCBadMessage:
- self.badMessage(line, *sys.exc_info())
-
-
- def getUserModeParams(self):
- """
- Get user modes that require parameters for correct parsing.
-
- @rtype: C{[str, str]}
- @return C{[add, remove]}
- """
- return ['', '']
-
-
- def getChannelModeParams(self):
- """
- Get channel modes that require parameters for correct parsing.
-
- @rtype: C{[str, str]}
- @return C{[add, remove]}
- """
- # PREFIX modes are treated as "type B" CHANMODES, they always take
- # parameter.
- params = ['', '']
- prefixes = self.supported.getFeature('PREFIX', {})
- params[0] = params[1] = ''.join(prefixes.iterkeys())
-
- chanmodes = self.supported.getFeature('CHANMODES')
- if chanmodes is not None:
- params[0] += chanmodes.get('addressModes', '')
- params[0] += chanmodes.get('param', '')
- params[1] = params[0]
- params[0] += chanmodes.get('setParam', '')
- return params
-
-
- def handleCommand(self, command, prefix, params):
- """Determine the function to call for the given command and call
- it with the given arguments.
- """
- method = getattr(self, "irc_%s" % command, None)
- try:
- if method is not None:
- method(prefix, params)
- else:
- self.irc_unknown(prefix, command, params)
- except:
- log.deferr()
-
-
- def __getstate__(self):
- dct = self.__dict__.copy()
- dct['dcc_sessions'] = None
- dct['_pings'] = None
- return dct
-
-
-def dccParseAddress(address):
- if '.' in address:
- pass
- else:
- try:
- address = long(address)
- except ValueError:
- raise IRCBadMessage,\
- "Indecipherable address %r" % (address,)
- else:
- address = (
- (address >> 24) & 0xFF,
- (address >> 16) & 0xFF,
- (address >> 8) & 0xFF,
- address & 0xFF,
- )
- address = '.'.join(map(str,address))
- return address
-
-
-class DccFileReceiveBasic(protocol.Protocol, styles.Ephemeral):
- """Bare protocol to receive a Direct Client Connection SEND stream.
-
- This does enough to keep the other guy talking, but you'll want to
- extend my dataReceived method to *do* something with the data I get.
- """
-
- bytesReceived = 0
-
- def __init__(self, resumeOffset=0):
- self.bytesReceived = resumeOffset
- self.resume = (resumeOffset != 0)
-
- def dataReceived(self, data):
- """Called when data is received.
-
- Warning: This just acknowledges to the remote host that the
- data has been received; it doesn't *do* anything with the
- data, so you'll want to override this.
- """
- self.bytesReceived = self.bytesReceived + len(data)
- self.transport.write(struct.pack('!i', self.bytesReceived))
-
-
-class DccSendProtocol(protocol.Protocol, styles.Ephemeral):
- """Protocol for an outgoing Direct Client Connection SEND.
- """
-
- blocksize = 1024
- file = None
- bytesSent = 0
- completed = 0
- connected = 0
-
- def __init__(self, file):
- if type(file) is types.StringType:
- self.file = open(file, 'r')
-
- def connectionMade(self):
- self.connected = 1
- self.sendBlock()
-
- def dataReceived(self, data):
- # XXX: Do we need to check to see if len(data) != fmtsize?
-
- bytesShesGot = struct.unpack("!I", data)
- if bytesShesGot < self.bytesSent:
- # Wait for her.
- # XXX? Add some checks to see if we've stalled out?
- return
- elif bytesShesGot > self.bytesSent:
- # self.transport.log("DCC SEND %s: She says she has %d bytes "
- # "but I've only sent %d. I'm stopping "
- # "this screwy transfer."
- # % (self.file,
- # bytesShesGot, self.bytesSent))
- self.transport.loseConnection()
- return
-
- self.sendBlock()
-
- def sendBlock(self):
- block = self.file.read(self.blocksize)
- if block:
- self.transport.write(block)
- self.bytesSent = self.bytesSent + len(block)
- else:
- # Nothing more to send, transfer complete.
- self.transport.loseConnection()
- self.completed = 1
-
- def connectionLost(self, reason):
- self.connected = 0
- if hasattr(self.file, "close"):
- self.file.close()
-
-
-class DccSendFactory(protocol.Factory):
- protocol = DccSendProtocol
- def __init__(self, file):
- self.file = file
-
- def buildProtocol(self, connection):
- p = self.protocol(self.file)
- p.factory = self
- return p
-
-
-def fileSize(file):
- """I'll try my damndest to determine the size of this file object.
- """
- size = None
- if hasattr(file, "fileno"):
- fileno = file.fileno()
- try:
- stat_ = os.fstat(fileno)
- size = stat_[stat.ST_SIZE]
- except:
- pass
- else:
- return size
-
- if hasattr(file, "name") and path.exists(file.name):
- try:
- size = path.getsize(file.name)
- except:
- pass
- else:
- return size
-
- if hasattr(file, "seek") and hasattr(file, "tell"):
- try:
- try:
- file.seek(0, 2)
- size = file.tell()
- finally:
- file.seek(0, 0)
- except:
- pass
- else:
- return size
-
- return size
-
-class DccChat(basic.LineReceiver, styles.Ephemeral):
- """Direct Client Connection protocol type CHAT.
-
- DCC CHAT is really just your run o' the mill basic.LineReceiver
- protocol. This class only varies from that slightly, accepting
- either LF or CR LF for a line delimeter for incoming messages
- while always using CR LF for outgoing.
-
- The lineReceived method implemented here uses the DCC connection's
- 'client' attribute (provided upon construction) to deliver incoming
- lines from the DCC chat via IRCClient's normal privmsg interface.
- That's something of a spoof, which you may well want to override.
- """
-
- queryData = None
- delimiter = CR + NL
- client = None
- remoteParty = None
- buffer = ""
-
- def __init__(self, client, queryData=None):
- """Initialize a new DCC CHAT session.
-
- queryData is a 3-tuple of
- (fromUser, targetUserOrChannel, data)
- as received by the CTCP query.
-
- (To be honest, fromUser is the only thing that's currently
- used here. targetUserOrChannel is potentially useful, while
- the 'data' argument is soley for informational purposes.)
- """
- self.client = client
- if queryData:
- self.queryData = queryData
- self.remoteParty = self.queryData[0]
-
- def dataReceived(self, data):
- self.buffer = self.buffer + data
- lines = string.split(self.buffer, LF)
- # Put the (possibly empty) element after the last LF back in the
- # buffer
- self.buffer = lines.pop()
-
- for line in lines:
- if line[-1] == CR:
- line = line[:-1]
- self.lineReceived(line)
-
- def lineReceived(self, line):
- log.msg("DCC CHAT<%s> %s" % (self.remoteParty, line))
- self.client.privmsg(self.remoteParty,
- self.client.nickname, line)
-
-
-class DccChatFactory(protocol.ClientFactory):
- protocol = DccChat
- noisy = 0
- def __init__(self, client, queryData):
- self.client = client
- self.queryData = queryData
-
-
- def buildProtocol(self, addr):
- p = self.protocol(client=self.client, queryData=self.queryData)
- p.factory = self
- return p
-
-
- def clientConnectionFailed(self, unused_connector, unused_reason):
- self.client.dcc_sessions.remove(self)
-
- def clientConnectionLost(self, unused_connector, unused_reason):
- self.client.dcc_sessions.remove(self)
-
-
-def dccDescribe(data):
- """Given the data chunk from a DCC query, return a descriptive string.
- """
-
- orig_data = data
- data = string.split(data)
- if len(data) < 4:
- return orig_data
-
- (dcctype, arg, address, port) = data[:4]
-
- if '.' in address:
- pass
- else:
- try:
- address = long(address)
- except ValueError:
- pass
- else:
- address = (
- (address >> 24) & 0xFF,
- (address >> 16) & 0xFF,
- (address >> 8) & 0xFF,
- address & 0xFF,
- )
- # The mapping to 'int' is to get rid of those accursed
- # "L"s which python 1.5.2 puts on the end of longs.
- address = string.join(map(str,map(int,address)), ".")
-
- if dcctype == 'SEND':
- filename = arg
-
- size_txt = ''
- if len(data) >= 5:
- try:
- size = int(data[4])
- size_txt = ' of size %d bytes' % (size,)
- except ValueError:
- pass
-
- dcc_text = ("SEND for file '%s'%s at host %s, port %s"
- % (filename, size_txt, address, port))
- elif dcctype == 'CHAT':
- dcc_text = ("CHAT for host %s, port %s"
- % (address, port))
- else:
- dcc_text = orig_data
-
- return dcc_text
-
-
-class DccFileReceive(DccFileReceiveBasic):
- """Higher-level coverage for getting a file from DCC SEND.
-
- I allow you to change the file's name and destination directory.
- I won't overwrite an existing file unless I've been told it's okay
- to do so. If passed the resumeOffset keyword argument I will attempt to
- resume the file from that amount of bytes.
-
- XXX: I need to let the client know when I am finished.
- XXX: I need to decide how to keep a progress indicator updated.
- XXX: Client needs a way to tell me "Do not finish until I say so."
- XXX: I need to make sure the client understands if the file cannot be written.
- """
-
- filename = 'dcc'
- fileSize = -1
- destDir = '.'
- overwrite = 0
- fromUser = None
- queryData = None
-
- def __init__(self, filename, fileSize=-1, queryData=None,
- destDir='.', resumeOffset=0):
- DccFileReceiveBasic.__init__(self, resumeOffset=resumeOffset)
- self.filename = filename
- self.destDir = destDir
- self.fileSize = fileSize
-
- if queryData:
- self.queryData = queryData
- self.fromUser = self.queryData[0]
-
- def set_directory(self, directory):
- """Set the directory where the downloaded file will be placed.
-
- May raise OSError if the supplied directory path is not suitable.
- """
- if not path.exists(directory):
- raise OSError(errno.ENOENT, "You see no directory there.",
- directory)
- if not path.isdir(directory):
- raise OSError(errno.ENOTDIR, "You cannot put a file into "
- "something which is not a directory.",
- directory)
- if not os.access(directory, os.X_OK | os.W_OK):
- raise OSError(errno.EACCES,
- "This directory is too hard to write in to.",
- directory)
- self.destDir = directory
-
- def set_filename(self, filename):
- """Change the name of the file being transferred.
-
- This replaces the file name provided by the sender.
- """
- self.filename = filename
-
- def set_overwrite(self, boolean):
- """May I overwrite existing files?
- """
- self.overwrite = boolean
-
-
- # Protocol-level methods.
-
- def connectionMade(self):
- dst = path.abspath(path.join(self.destDir,self.filename))
- exists = path.exists(dst)
- if self.resume and exists:
- # I have been told I want to resume, and a file already
- # exists - Here we go
- self.file = open(dst, 'ab')
- log.msg("Attempting to resume %s - starting from %d bytes" %
- (self.file, self.file.tell()))
- elif self.overwrite or not exists:
- self.file = open(dst, 'wb')
- else:
- raise OSError(errno.EEXIST,
- "There's a file in the way. "
- "Perhaps that's why you cannot open it.",
- dst)
-
- def dataReceived(self, data):
- self.file.write(data)
- DccFileReceiveBasic.dataReceived(self, data)
-
- # XXX: update a progress indicator here?
-
- def connectionLost(self, reason):
- """When the connection is lost, I close the file.
- """
- self.connected = 0
- logmsg = ("%s closed." % (self,))
- if self.fileSize > 0:
- logmsg = ("%s %d/%d bytes received"
- % (logmsg, self.bytesReceived, self.fileSize))
- if self.bytesReceived == self.fileSize:
- pass # Hooray!
- elif self.bytesReceived < self.fileSize:
- logmsg = ("%s (Warning: %d bytes short)"
- % (logmsg, self.fileSize - self.bytesReceived))
- else:
- logmsg = ("%s (file larger than expected)"
- % (logmsg,))
- else:
- logmsg = ("%s %d bytes received"
- % (logmsg, self.bytesReceived))
-
- if hasattr(self, 'file'):
- logmsg = "%s and written to %s.\n" % (logmsg, self.file.name)
- if hasattr(self.file, 'close'): self.file.close()
-
- # self.transport.log(logmsg)
-
- def __str__(self):
- if not self.connected:
- return "<Unconnected DccFileReceive object at %x>" % (id(self),)
- from_ = self.transport.getPeer()
- if self.fromUser:
- from_ = "%s (%s)" % (self.fromUser, from_)
-
- s = ("DCC transfer of '%s' from %s" % (self.filename, from_))
- return s
-
- def __repr__(self):
- s = ("<%s at %x: GET %s>"
- % (self.__class__, id(self), self.filename))
- return s
-
-
-# CTCP constants and helper functions
-
-X_DELIM = chr(001)
-
-def ctcpExtract(message):
- """
- Extract CTCP data from a string.
-
- @return: A C{dict} containing two keys:
- - C{'extended'}: A list of CTCP (tag, data) tuples.
- - C{'normal'}: A list of strings which were not inside a CTCP delimiter.
- """
- extended_messages = []
- normal_messages = []
- retval = {'extended': extended_messages,
- 'normal': normal_messages }
-
- messages = string.split(message, X_DELIM)
- odd = 0
-
- # X1 extended data X2 nomal data X3 extended data X4 normal...
- while messages:
- if odd:
- extended_messages.append(messages.pop(0))
- else:
- normal_messages.append(messages.pop(0))
- odd = not odd
-
- extended_messages[:] = filter(None, extended_messages)
- normal_messages[:] = filter(None, normal_messages)
-
- extended_messages[:] = map(ctcpDequote, extended_messages)
- for i in xrange(len(extended_messages)):
- m = string.split(extended_messages[i], SPC, 1)
- tag = m[0]
- if len(m) > 1:
- data = m[1]
- else:
- data = None
-
- extended_messages[i] = (tag, data)
-
- return retval
-
-# CTCP escaping
-
-M_QUOTE= chr(020)
-
-mQuoteTable = {
- NUL: M_QUOTE + '0',
- NL: M_QUOTE + 'n',
- CR: M_QUOTE + 'r',
- M_QUOTE: M_QUOTE + M_QUOTE
- }
-
-mDequoteTable = {}
-for k, v in mQuoteTable.items():
- mDequoteTable[v[-1]] = k
-del k, v
-
-mEscape_re = re.compile('%s.' % (re.escape(M_QUOTE),), re.DOTALL)
-
-def lowQuote(s):
- for c in (M_QUOTE, NUL, NL, CR):
- s = string.replace(s, c, mQuoteTable[c])
- return s
-
-def lowDequote(s):
- def sub(matchobj, mDequoteTable=mDequoteTable):
- s = matchobj.group()[1]
- try:
- s = mDequoteTable[s]
- except KeyError:
- s = s
- return s
-
- return mEscape_re.sub(sub, s)
-
-X_QUOTE = '\\'
-
-xQuoteTable = {
- X_DELIM: X_QUOTE + 'a',
- X_QUOTE: X_QUOTE + X_QUOTE
- }
-
-xDequoteTable = {}
-
-for k, v in xQuoteTable.items():
- xDequoteTable[v[-1]] = k
-
-xEscape_re = re.compile('%s.' % (re.escape(X_QUOTE),), re.DOTALL)
-
-def ctcpQuote(s):
- for c in (X_QUOTE, X_DELIM):
- s = string.replace(s, c, xQuoteTable[c])
- return s
-
-def ctcpDequote(s):
- def sub(matchobj, xDequoteTable=xDequoteTable):
- s = matchobj.group()[1]
- try:
- s = xDequoteTable[s]
- except KeyError:
- s = s
- return s
-
- return xEscape_re.sub(sub, s)
-
-def ctcpStringify(messages):
- """
- @type messages: a list of extended messages. An extended
- message is a (tag, data) tuple, where 'data' may be C{None}, a
- string, or a list of strings to be joined with whitespace.
-
- @returns: String
- """
- coded_messages = []
- for (tag, data) in messages:
- if data:
- if not isinstance(data, types.StringType):
- try:
- # data as list-of-strings
- data = " ".join(map(str, data))
- except TypeError:
- # No? Then use it's %s representation.
- pass
- m = "%s %s" % (tag, data)
- else:
- m = str(tag)
- m = ctcpQuote(m)
- m = "%s%s%s" % (X_DELIM, m, X_DELIM)
- coded_messages.append(m)
-
- line = string.join(coded_messages, '')
- return line
-
-
-# Constants (from RFC 2812)
-RPL_WELCOME = '001'
-RPL_YOURHOST = '002'
-RPL_CREATED = '003'
-RPL_MYINFO = '004'
-RPL_ISUPPORT = '005'
-RPL_BOUNCE = '010'
-RPL_USERHOST = '302'
-RPL_ISON = '303'
-RPL_AWAY = '301'
-RPL_UNAWAY = '305'
-RPL_NOWAWAY = '306'
-RPL_WHOISUSER = '311'
-RPL_WHOISSERVER = '312'
-RPL_WHOISOPERATOR = '313'
-RPL_WHOISIDLE = '317'
-RPL_ENDOFWHOIS = '318'
-RPL_WHOISCHANNELS = '319'
-RPL_WHOWASUSER = '314'
-RPL_ENDOFWHOWAS = '369'
-RPL_LISTSTART = '321'
-RPL_LIST = '322'
-RPL_LISTEND = '323'
-RPL_UNIQOPIS = '325'
-RPL_CHANNELMODEIS = '324'
-RPL_NOTOPIC = '331'
-RPL_TOPIC = '332'
-RPL_INVITING = '341'
-RPL_SUMMONING = '342'
-RPL_INVITELIST = '346'
-RPL_ENDOFINVITELIST = '347'
-RPL_EXCEPTLIST = '348'
-RPL_ENDOFEXCEPTLIST = '349'
-RPL_VERSION = '351'
-RPL_WHOREPLY = '352'
-RPL_ENDOFWHO = '315'
-RPL_NAMREPLY = '353'
-RPL_ENDOFNAMES = '366'
-RPL_LINKS = '364'
-RPL_ENDOFLINKS = '365'
-RPL_BANLIST = '367'
-RPL_ENDOFBANLIST = '368'
-RPL_INFO = '371'
-RPL_ENDOFINFO = '374'
-RPL_MOTDSTART = '375'
-RPL_MOTD = '372'
-RPL_ENDOFMOTD = '376'
-RPL_YOUREOPER = '381'
-RPL_REHASHING = '382'
-RPL_YOURESERVICE = '383'
-RPL_TIME = '391'
-RPL_USERSSTART = '392'
-RPL_USERS = '393'
-RPL_ENDOFUSERS = '394'
-RPL_NOUSERS = '395'
-RPL_TRACELINK = '200'
-RPL_TRACECONNECTING = '201'
-RPL_TRACEHANDSHAKE = '202'
-RPL_TRACEUNKNOWN = '203'
-RPL_TRACEOPERATOR = '204'
-RPL_TRACEUSER = '205'
-RPL_TRACESERVER = '206'
-RPL_TRACESERVICE = '207'
-RPL_TRACENEWTYPE = '208'
-RPL_TRACECLASS = '209'
-RPL_TRACERECONNECT = '210'
-RPL_TRACELOG = '261'
-RPL_TRACEEND = '262'
-RPL_STATSLINKINFO = '211'
-RPL_STATSCOMMANDS = '212'
-RPL_ENDOFSTATS = '219'
-RPL_STATSUPTIME = '242'
-RPL_STATSOLINE = '243'
-RPL_UMODEIS = '221'
-RPL_SERVLIST = '234'
-RPL_SERVLISTEND = '235'
-RPL_LUSERCLIENT = '251'
-RPL_LUSEROP = '252'
-RPL_LUSERUNKNOWN = '253'
-RPL_LUSERCHANNELS = '254'
-RPL_LUSERME = '255'
-RPL_ADMINME = '256'
-RPL_ADMINLOC = '257'
-RPL_ADMINLOC = '258'
-RPL_ADMINEMAIL = '259'
-RPL_TRYAGAIN = '263'
-ERR_NOSUCHNICK = '401'
-ERR_NOSUCHSERVER = '402'
-ERR_NOSUCHCHANNEL = '403'
-ERR_CANNOTSENDTOCHAN = '404'
-ERR_TOOMANYCHANNELS = '405'
-ERR_WASNOSUCHNICK = '406'
-ERR_TOOMANYTARGETS = '407'
-ERR_NOSUCHSERVICE = '408'
-ERR_NOORIGIN = '409'
-ERR_NORECIPIENT = '411'
-ERR_NOTEXTTOSEND = '412'
-ERR_NOTOPLEVEL = '413'
-ERR_WILDTOPLEVEL = '414'
-ERR_BADMASK = '415'
-ERR_UNKNOWNCOMMAND = '421'
-ERR_NOMOTD = '422'
-ERR_NOADMININFO = '423'
-ERR_FILEERROR = '424'
-ERR_NONICKNAMEGIVEN = '431'
-ERR_ERRONEUSNICKNAME = '432'
-ERR_NICKNAMEINUSE = '433'
-ERR_NICKCOLLISION = '436'
-ERR_UNAVAILRESOURCE = '437'
-ERR_USERNOTINCHANNEL = '441'
-ERR_NOTONCHANNEL = '442'
-ERR_USERONCHANNEL = '443'
-ERR_NOLOGIN = '444'
-ERR_SUMMONDISABLED = '445'
-ERR_USERSDISABLED = '446'
-ERR_NOTREGISTERED = '451'
-ERR_NEEDMOREPARAMS = '461'
-ERR_ALREADYREGISTRED = '462'
-ERR_NOPERMFORHOST = '463'
-ERR_PASSWDMISMATCH = '464'
-ERR_YOUREBANNEDCREEP = '465'
-ERR_YOUWILLBEBANNED = '466'
-ERR_KEYSET = '467'
-ERR_CHANNELISFULL = '471'
-ERR_UNKNOWNMODE = '472'
-ERR_INVITEONLYCHAN = '473'
-ERR_BANNEDFROMCHAN = '474'
-ERR_BADCHANNELKEY = '475'
-ERR_BADCHANMASK = '476'
-ERR_NOCHANMODES = '477'
-ERR_BANLISTFULL = '478'
-ERR_NOPRIVILEGES = '481'
-ERR_CHANOPRIVSNEEDED = '482'
-ERR_CANTKILLSERVER = '483'
-ERR_RESTRICTED = '484'
-ERR_UNIQOPPRIVSNEEDED = '485'
-ERR_NOOPERHOST = '491'
-ERR_NOSERVICEHOST = '492'
-ERR_UMODEUNKNOWNFLAG = '501'
-ERR_USERSDONTMATCH = '502'
-
-# And hey, as long as the strings are already intern'd...
-symbolic_to_numeric = {
- "RPL_WELCOME": '001',
- "RPL_YOURHOST": '002',
- "RPL_CREATED": '003',
- "RPL_MYINFO": '004',
- "RPL_ISUPPORT": '005',
- "RPL_BOUNCE": '010',
- "RPL_USERHOST": '302',
- "RPL_ISON": '303',
- "RPL_AWAY": '301',
- "RPL_UNAWAY": '305',
- "RPL_NOWAWAY": '306',
- "RPL_WHOISUSER": '311',
- "RPL_WHOISSERVER": '312',
- "RPL_WHOISOPERATOR": '313',
- "RPL_WHOISIDLE": '317',
- "RPL_ENDOFWHOIS": '318',
- "RPL_WHOISCHANNELS": '319',
- "RPL_WHOWASUSER": '314',
- "RPL_ENDOFWHOWAS": '369',
- "RPL_LISTSTART": '321',
- "RPL_LIST": '322',
- "RPL_LISTEND": '323',
- "RPL_UNIQOPIS": '325',
- "RPL_CHANNELMODEIS": '324',
- "RPL_NOTOPIC": '331',
- "RPL_TOPIC": '332',
- "RPL_INVITING": '341',
- "RPL_SUMMONING": '342',
- "RPL_INVITELIST": '346',
- "RPL_ENDOFINVITELIST": '347',
- "RPL_EXCEPTLIST": '348',
- "RPL_ENDOFEXCEPTLIST": '349',
- "RPL_VERSION": '351',
- "RPL_WHOREPLY": '352',
- "RPL_ENDOFWHO": '315',
- "RPL_NAMREPLY": '353',
- "RPL_ENDOFNAMES": '366',
- "RPL_LINKS": '364',
- "RPL_ENDOFLINKS": '365',
- "RPL_BANLIST": '367',
- "RPL_ENDOFBANLIST": '368',
- "RPL_INFO": '371',
- "RPL_ENDOFINFO": '374',
- "RPL_MOTDSTART": '375',
- "RPL_MOTD": '372',
- "RPL_ENDOFMOTD": '376',
- "RPL_YOUREOPER": '381',
- "RPL_REHASHING": '382',
- "RPL_YOURESERVICE": '383',
- "RPL_TIME": '391',
- "RPL_USERSSTART": '392',
- "RPL_USERS": '393',
- "RPL_ENDOFUSERS": '394',
- "RPL_NOUSERS": '395',
- "RPL_TRACELINK": '200',
- "RPL_TRACECONNECTING": '201',
- "RPL_TRACEHANDSHAKE": '202',
- "RPL_TRACEUNKNOWN": '203',
- "RPL_TRACEOPERATOR": '204',
- "RPL_TRACEUSER": '205',
- "RPL_TRACESERVER": '206',
- "RPL_TRACESERVICE": '207',
- "RPL_TRACENEWTYPE": '208',
- "RPL_TRACECLASS": '209',
- "RPL_TRACERECONNECT": '210',
- "RPL_TRACELOG": '261',
- "RPL_TRACEEND": '262',
- "RPL_STATSLINKINFO": '211',
- "RPL_STATSCOMMANDS": '212',
- "RPL_ENDOFSTATS": '219',
- "RPL_STATSUPTIME": '242',
- "RPL_STATSOLINE": '243',
- "RPL_UMODEIS": '221',
- "RPL_SERVLIST": '234',
- "RPL_SERVLISTEND": '235',
- "RPL_LUSERCLIENT": '251',
- "RPL_LUSEROP": '252',
- "RPL_LUSERUNKNOWN": '253',
- "RPL_LUSERCHANNELS": '254',
- "RPL_LUSERME": '255',
- "RPL_ADMINME": '256',
- "RPL_ADMINLOC": '257',
- "RPL_ADMINLOC": '258',
- "RPL_ADMINEMAIL": '259',
- "RPL_TRYAGAIN": '263',
- "ERR_NOSUCHNICK": '401',
- "ERR_NOSUCHSERVER": '402',
- "ERR_NOSUCHCHANNEL": '403',
- "ERR_CANNOTSENDTOCHAN": '404',
- "ERR_TOOMANYCHANNELS": '405',
- "ERR_WASNOSUCHNICK": '406',
- "ERR_TOOMANYTARGETS": '407',
- "ERR_NOSUCHSERVICE": '408',
- "ERR_NOORIGIN": '409',
- "ERR_NORECIPIENT": '411',
- "ERR_NOTEXTTOSEND": '412',
- "ERR_NOTOPLEVEL": '413',
- "ERR_WILDTOPLEVEL": '414',
- "ERR_BADMASK": '415',
- "ERR_UNKNOWNCOMMAND": '421',
- "ERR_NOMOTD": '422',
- "ERR_NOADMININFO": '423',
- "ERR_FILEERROR": '424',
- "ERR_NONICKNAMEGIVEN": '431',
- "ERR_ERRONEUSNICKNAME": '432',
- "ERR_NICKNAMEINUSE": '433',
- "ERR_NICKCOLLISION": '436',
- "ERR_UNAVAILRESOURCE": '437',
- "ERR_USERNOTINCHANNEL": '441',
- "ERR_NOTONCHANNEL": '442',
- "ERR_USERONCHANNEL": '443',
- "ERR_NOLOGIN": '444',
- "ERR_SUMMONDISABLED": '445',
- "ERR_USERSDISABLED": '446',
- "ERR_NOTREGISTERED": '451',
- "ERR_NEEDMOREPARAMS": '461',
- "ERR_ALREADYREGISTRED": '462',
- "ERR_NOPERMFORHOST": '463',
- "ERR_PASSWDMISMATCH": '464',
- "ERR_YOUREBANNEDCREEP": '465',
- "ERR_YOUWILLBEBANNED": '466',
- "ERR_KEYSET": '467',
- "ERR_CHANNELISFULL": '471',
- "ERR_UNKNOWNMODE": '472',
- "ERR_INVITEONLYCHAN": '473',
- "ERR_BANNEDFROMCHAN": '474',
- "ERR_BADCHANNELKEY": '475',
- "ERR_BADCHANMASK": '476',
- "ERR_NOCHANMODES": '477',
- "ERR_BANLISTFULL": '478',
- "ERR_NOPRIVILEGES": '481',
- "ERR_CHANOPRIVSNEEDED": '482',
- "ERR_CANTKILLSERVER": '483',
- "ERR_RESTRICTED": '484',
- "ERR_UNIQOPPRIVSNEEDED": '485',
- "ERR_NOOPERHOST": '491',
- "ERR_NOSERVICEHOST": '492',
- "ERR_UMODEUNKNOWNFLAG": '501',
- "ERR_USERSDONTMATCH": '502',
-}
-
-numeric_to_symbolic = {}
-for k, v in symbolic_to_numeric.items():
- numeric_to_symbolic[v] = k
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/__init__.py
deleted file mode 100755
index ad95b685..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-Twisted Jabber: Jabber Protocol Helpers
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/client.py
deleted file mode 100755
index 2a37bcb1..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/client.py
+++ /dev/null
@@ -1,368 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabberclient -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.words.xish import domish, xpath, utility
-from twisted.words.protocols.jabber import xmlstream, sasl, error
-from twisted.words.protocols.jabber.jid import JID
-
-NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
-NS_XMPP_BIND = 'urn:ietf:params:xml:ns:xmpp-bind'
-NS_XMPP_SESSION = 'urn:ietf:params:xml:ns:xmpp-session'
-NS_IQ_AUTH_FEATURE = 'http://jabber.org/features/iq-auth'
-
-DigestAuthQry = xpath.internQuery("/iq/query/digest")
-PlaintextAuthQry = xpath.internQuery("/iq/query/password")
-
-def basicClientFactory(jid, secret):
- a = BasicAuthenticator(jid, secret)
- return xmlstream.XmlStreamFactory(a)
-
-class IQ(domish.Element):
- """
- Wrapper for a Info/Query packet.
-
- This provides the necessary functionality to send IQs and get notified when
- a result comes back. It's a subclass from L{domish.Element}, so you can use
- the standard DOM manipulation calls to add data to the outbound request.
-
- @type callbacks: L{utility.CallbackList}
- @cvar callbacks: Callback list to be notified when response comes back
-
- """
- def __init__(self, xmlstream, type = "set"):
- """
- @type xmlstream: L{xmlstream.XmlStream}
- @param xmlstream: XmlStream to use for transmission of this IQ
-
- @type type: C{str}
- @param type: IQ type identifier ('get' or 'set')
- """
-
- domish.Element.__init__(self, ("jabber:client", "iq"))
- self.addUniqueId()
- self["type"] = type
- self._xmlstream = xmlstream
- self.callbacks = utility.CallbackList()
-
- def addCallback(self, fn, *args, **kwargs):
- """
- Register a callback for notification when the IQ result is available.
- """
-
- self.callbacks.addCallback(True, fn, *args, **kwargs)
-
- def send(self, to = None):
- """
- Call this method to send this IQ request via the associated XmlStream.
-
- @param to: Jabber ID of the entity to send the request to
- @type to: C{str}
-
- @returns: Callback list for this IQ. Any callbacks added to this list
- will be fired when the result comes back.
- """
- if to != None:
- self["to"] = to
- self._xmlstream.addOnetimeObserver("/iq[@id='%s']" % self["id"], \
- self._resultEvent)
- self._xmlstream.send(self)
-
- def _resultEvent(self, iq):
- self.callbacks.callback(iq)
- self.callbacks = None
-
-
-
-class IQAuthInitializer(object):
- """
- Non-SASL Authentication initializer for the initiating entity.
-
- This protocol is defined in
- U{JEP-0078<http://www.jabber.org/jeps/jep-0078.html>} and mainly serves for
- compatibility with pre-XMPP-1.0 server implementations.
- """
-
- INVALID_USER_EVENT = "//event/client/basicauth/invaliduser"
- AUTH_FAILED_EVENT = "//event/client/basicauth/authfailed"
-
- def __init__(self, xs):
- self.xmlstream = xs
-
-
- def initialize(self):
- # Send request for auth fields
- iq = xmlstream.IQ(self.xmlstream, "get")
- iq.addElement(("jabber:iq:auth", "query"))
- jid = self.xmlstream.authenticator.jid
- iq.query.addElement("username", content = jid.user)
-
- d = iq.send()
- d.addCallbacks(self._cbAuthQuery, self._ebAuthQuery)
- return d
-
-
- def _cbAuthQuery(self, iq):
- jid = self.xmlstream.authenticator.jid
- password = self.xmlstream.authenticator.password
-
- # Construct auth request
- reply = xmlstream.IQ(self.xmlstream, "set")
- reply.addElement(("jabber:iq:auth", "query"))
- reply.query.addElement("username", content = jid.user)
- reply.query.addElement("resource", content = jid.resource)
-
- # Prefer digest over plaintext
- if DigestAuthQry.matches(iq):
- digest = xmlstream.hashPassword(self.xmlstream.sid, unicode(password))
- reply.query.addElement("digest", content = digest)
- else:
- reply.query.addElement("password", content = password)
-
- d = reply.send()
- d.addCallbacks(self._cbAuth, self._ebAuth)
- return d
-
-
- def _ebAuthQuery(self, failure):
- failure.trap(error.StanzaError)
- e = failure.value
- if e.condition == 'not-authorized':
- self.xmlstream.dispatch(e.stanza, self.INVALID_USER_EVENT)
- else:
- self.xmlstream.dispatch(e.stanza, self.AUTH_FAILED_EVENT)
-
- return failure
-
-
- def _cbAuth(self, iq):
- pass
-
-
- def _ebAuth(self, failure):
- failure.trap(error.StanzaError)
- self.xmlstream.dispatch(failure.value.stanza, self.AUTH_FAILED_EVENT)
- return failure
-
-
-
-class BasicAuthenticator(xmlstream.ConnectAuthenticator):
- """
- Authenticates an XmlStream against a Jabber server as a Client.
-
- This only implements non-SASL authentication, per
- U{JEP-0078<http://www.jabber.org/jeps/jep-0078.html>}. Additionally, this
- authenticator provides the ability to perform inline registration, per
- U{JEP-0077<http://www.jabber.org/jeps/jep-0077.html>}.
-
- Under normal circumstances, the BasicAuthenticator generates the
- L{xmlstream.STREAM_AUTHD_EVENT} once the stream has authenticated. However,
- it can also generate other events, such as:
- - L{INVALID_USER_EVENT} : Authentication failed, due to invalid username
- - L{AUTH_FAILED_EVENT} : Authentication failed, due to invalid password
- - L{REGISTER_FAILED_EVENT} : Registration failed
-
- If authentication fails for any reason, you can attempt to register by
- calling the L{registerAccount} method. If the registration succeeds, a
- L{xmlstream.STREAM_AUTHD_EVENT} will be fired. Otherwise, one of the above
- errors will be generated (again).
- """
-
- namespace = "jabber:client"
-
- INVALID_USER_EVENT = IQAuthInitializer.INVALID_USER_EVENT
- AUTH_FAILED_EVENT = IQAuthInitializer.AUTH_FAILED_EVENT
- REGISTER_FAILED_EVENT = "//event/client/basicauth/registerfailed"
-
- def __init__(self, jid, password):
- xmlstream.ConnectAuthenticator.__init__(self, jid.host)
- self.jid = jid
- self.password = password
-
- def associateWithStream(self, xs):
- xs.version = (0, 0)
- xmlstream.ConnectAuthenticator.associateWithStream(self, xs)
-
- inits = [ (xmlstream.TLSInitiatingInitializer, False),
- (IQAuthInitializer, True),
- ]
-
- for initClass, required in inits:
- init = initClass(xs)
- init.required = required
- xs.initializers.append(init)
-
- # TODO: move registration into an Initializer?
-
- def registerAccount(self, username = None, password = None):
- if username:
- self.jid.user = username
- if password:
- self.password = password
-
- iq = IQ(self.xmlstream, "set")
- iq.addElement(("jabber:iq:register", "query"))
- iq.query.addElement("username", content = self.jid.user)
- iq.query.addElement("password", content = self.password)
-
- iq.addCallback(self._registerResultEvent)
-
- iq.send()
-
- def _registerResultEvent(self, iq):
- if iq["type"] == "result":
- # Registration succeeded -- go ahead and auth
- self.streamStarted()
- else:
- # Registration failed
- self.xmlstream.dispatch(iq, self.REGISTER_FAILED_EVENT)
-
-
-
-class CheckVersionInitializer(object):
- """
- Initializer that checks if the minimum common stream version number is 1.0.
- """
-
- def __init__(self, xs):
- self.xmlstream = xs
-
-
- def initialize(self):
- if self.xmlstream.version < (1, 0):
- raise error.StreamError('unsupported-version')
-
-
-
-class BindInitializer(xmlstream.BaseFeatureInitiatingInitializer):
- """
- Initializer that implements Resource Binding for the initiating entity.
-
- This protocol is documented in U{RFC 3920, section
- 7<http://www.xmpp.org/specs/rfc3920.html#bind>}.
- """
-
- feature = (NS_XMPP_BIND, 'bind')
-
- def start(self):
- iq = xmlstream.IQ(self.xmlstream, 'set')
- bind = iq.addElement((NS_XMPP_BIND, 'bind'))
- resource = self.xmlstream.authenticator.jid.resource
- if resource:
- bind.addElement('resource', content=resource)
- d = iq.send()
- d.addCallback(self.onBind)
- return d
-
-
- def onBind(self, iq):
- if iq.bind:
- self.xmlstream.authenticator.jid = JID(unicode(iq.bind.jid))
-
-
-
-class SessionInitializer(xmlstream.BaseFeatureInitiatingInitializer):
- """
- Initializer that implements session establishment for the initiating
- entity.
-
- This protocol is defined in U{RFC 3921, section
- 3<http://www.xmpp.org/specs/rfc3921.html#session>}.
- """
-
- feature = (NS_XMPP_SESSION, 'session')
-
- def start(self):
- iq = xmlstream.IQ(self.xmlstream, 'set')
- session = iq.addElement((NS_XMPP_SESSION, 'session'))
- return iq.send()
-
-
-
-def XMPPClientFactory(jid, password):
- """
- Client factory for XMPP 1.0 (only).
-
- This returns a L{xmlstream.XmlStreamFactory} with an L{XMPPAuthenticator}
- object to perform the stream initialization steps (such as authentication).
-
- @see: The notes at L{XMPPAuthenticator} describe how the L{jid} and
- L{password} parameters are to be used.
-
- @param jid: Jabber ID to connect with.
- @type jid: L{jid.JID}
- @param password: password to authenticate with.
- @type password: C{unicode}
- @return: XML stream factory.
- @rtype: L{xmlstream.XmlStreamFactory}
- """
- a = XMPPAuthenticator(jid, password)
- return xmlstream.XmlStreamFactory(a)
-
-
-
-class XMPPAuthenticator(xmlstream.ConnectAuthenticator):
- """
- Initializes an XmlStream connecting to an XMPP server as a Client.
-
- This authenticator performs the initialization steps needed to start
- exchanging XML stanzas with an XMPP server as an XMPP client. It checks if
- the server advertises XML stream version 1.0, negotiates TLS (when
- available), performs SASL authentication, binds a resource and establishes
- a session.
-
- Upon successful stream initialization, the L{xmlstream.STREAM_AUTHD_EVENT}
- event will be dispatched through the XML stream object. Otherwise, the
- L{xmlstream.INIT_FAILED_EVENT} event will be dispatched with a failure
- object.
-
- After inspection of the failure, initialization can then be restarted by
- calling L{initializeStream}. For example, in case of authentication
- failure, a user may be given the opportunity to input the correct password.
- By setting the L{password} instance variable and restarting initialization,
- the stream authentication step is then retried, and subsequent steps are
- performed if succesful.
-
- @ivar jid: Jabber ID to authenticate with. This may contain a resource
- part, as a suggestion to the server for resource binding. A
- server may override this, though. If the resource part is left
- off, the server will generate a unique resource identifier.
- The server will always return the full Jabber ID in the
- resource binding step, and this is stored in this instance
- variable.
- @type jid: L{jid.JID}
- @ivar password: password to be used during SASL authentication.
- @type password: C{unicode}
- """
-
- namespace = 'jabber:client'
-
- def __init__(self, jid, password):
- xmlstream.ConnectAuthenticator.__init__(self, jid.host)
- self.jid = jid
- self.password = password
-
-
- def associateWithStream(self, xs):
- """
- Register with the XML stream.
-
- Populates stream's list of initializers, along with their
- requiredness. This list is used by
- L{ConnectAuthenticator.initializeStream} to perform the initalization
- steps.
- """
- xmlstream.ConnectAuthenticator.associateWithStream(self, xs)
-
- xs.initializers = [CheckVersionInitializer(xs)]
- inits = [ (xmlstream.TLSInitiatingInitializer, False),
- (sasl.SASLInitiatingInitializer, True),
- (BindInitializer, False),
- (SessionInitializer, False),
- ]
-
- for initClass, required in inits:
- init = initClass(xs)
- init.required = required
- xs.initializers.append(init)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/component.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/component.py
deleted file mode 100755
index 1f37490b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/component.py
+++ /dev/null
@@ -1,474 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabbercomponent -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-External server-side components.
-
-Most Jabber server implementations allow for add-on components that act as a
-seperate entity on the Jabber network, but use the server-to-server
-functionality of a regular Jabber IM server. These so-called 'external
-components' are connected to the Jabber server using the Jabber Component
-Protocol as defined in U{JEP-0114<http://www.jabber.org/jeps/jep-0114.html>}.
-
-This module allows for writing external server-side component by assigning one
-or more services implementing L{ijabber.IService} up to L{ServiceManager}. The
-ServiceManager connects to the Jabber server and is responsible for the
-corresponding XML stream.
-"""
-
-from zope.interface import implements
-
-from twisted.application import service
-from twisted.internet import defer
-from twisted.python import log
-from twisted.words.xish import domish
-from twisted.words.protocols.jabber import error, ijabber, jstrports, xmlstream
-from twisted.words.protocols.jabber.jid import internJID as JID
-
-NS_COMPONENT_ACCEPT = 'jabber:component:accept'
-
-def componentFactory(componentid, password):
- """
- XML stream factory for external server-side components.
-
- @param componentid: JID of the component.
- @type componentid: C{unicode}
- @param password: password used to authenticate to the server.
- @type password: C{str}
- """
- a = ConnectComponentAuthenticator(componentid, password)
- return xmlstream.XmlStreamFactory(a)
-
-class ComponentInitiatingInitializer(object):
- """
- External server-side component authentication initializer for the
- initiating entity.
-
- @ivar xmlstream: XML stream between server and component.
- @type xmlstream: L{xmlstream.XmlStream}
- """
-
- def __init__(self, xs):
- self.xmlstream = xs
- self._deferred = None
-
- def initialize(self):
- xs = self.xmlstream
- hs = domish.Element((self.xmlstream.namespace, "handshake"))
- hs.addContent(xmlstream.hashPassword(xs.sid,
- unicode(xs.authenticator.password)))
-
- # Setup observer to watch for handshake result
- xs.addOnetimeObserver("/handshake", self._cbHandshake)
- xs.send(hs)
- self._deferred = defer.Deferred()
- return self._deferred
-
- def _cbHandshake(self, _):
- # we have successfully shaken hands and can now consider this
- # entity to represent the component JID.
- self.xmlstream.thisEntity = self.xmlstream.otherEntity
- self._deferred.callback(None)
-
-
-
-class ConnectComponentAuthenticator(xmlstream.ConnectAuthenticator):
- """
- Authenticator to permit an XmlStream to authenticate against a Jabber
- server as an external component (where the Authenticator is initiating the
- stream).
- """
- namespace = NS_COMPONENT_ACCEPT
-
- def __init__(self, componentjid, password):
- """
- @type componentjid: C{str}
- @param componentjid: Jabber ID that this component wishes to bind to.
-
- @type password: C{str}
- @param password: Password/secret this component uses to authenticate.
- """
- # Note that we are sending 'to' our desired component JID.
- xmlstream.ConnectAuthenticator.__init__(self, componentjid)
- self.password = password
-
- def associateWithStream(self, xs):
- xs.version = (0, 0)
- xmlstream.ConnectAuthenticator.associateWithStream(self, xs)
-
- xs.initializers = [ComponentInitiatingInitializer(xs)]
-
-
-
-class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
- """
- Authenticator for accepting components.
-
- @since: 8.2
- @ivar secret: The shared secret used to authorized incoming component
- connections.
- @type secret: C{unicode}.
- """
-
- namespace = NS_COMPONENT_ACCEPT
-
- def __init__(self, secret):
- self.secret = secret
- xmlstream.ListenAuthenticator.__init__(self)
-
-
- def associateWithStream(self, xs):
- """
- Associate the authenticator with a stream.
-
- This sets the stream's version to 0.0, because the XEP-0114 component
- protocol was not designed for XMPP 1.0.
- """
- xs.version = (0, 0)
- xmlstream.ListenAuthenticator.associateWithStream(self, xs)
-
-
- def streamStarted(self, rootElement):
- """
- Called by the stream when it has started.
-
- This examines the default namespace of the incoming stream and whether
- there is a requested hostname for the component. Then it generates a
- stream identifier, sends a response header and adds an observer for
- the first incoming element, triggering L{onElement}.
- """
-
- xmlstream.ListenAuthenticator.streamStarted(self, rootElement)
-
- if rootElement.defaultUri != self.namespace:
- exc = error.StreamError('invalid-namespace')
- self.xmlstream.sendStreamError(exc)
- return
-
- # self.xmlstream.thisEntity is set to the address the component
- # wants to assume.
- if not self.xmlstream.thisEntity:
- exc = error.StreamError('improper-addressing')
- self.xmlstream.sendStreamError(exc)
- return
-
- self.xmlstream.sendHeader()
- self.xmlstream.addOnetimeObserver('/*', self.onElement)
-
-
- def onElement(self, element):
- """
- Called on incoming XML Stanzas.
-
- The very first element received should be a request for handshake.
- Otherwise, the stream is dropped with a 'not-authorized' error. If a
- handshake request was received, the hash is extracted and passed to
- L{onHandshake}.
- """
- if (element.uri, element.name) == (self.namespace, 'handshake'):
- self.onHandshake(unicode(element))
- else:
- exc = error.StreamError('not-authorized')
- self.xmlstream.sendStreamError(exc)
-
-
- def onHandshake(self, handshake):
- """
- Called upon receiving the handshake request.
-
- This checks that the given hash in C{handshake} is equal to a
- calculated hash, responding with a handshake reply or a stream error.
- If the handshake was ok, the stream is authorized, and XML Stanzas may
- be exchanged.
- """
- calculatedHash = xmlstream.hashPassword(self.xmlstream.sid,
- unicode(self.secret))
- if handshake != calculatedHash:
- exc = error.StreamError('not-authorized', text='Invalid hash')
- self.xmlstream.sendStreamError(exc)
- else:
- self.xmlstream.send('<handshake/>')
- self.xmlstream.dispatch(self.xmlstream,
- xmlstream.STREAM_AUTHD_EVENT)
-
-
-
-class Service(service.Service):
- """
- External server-side component service.
- """
-
- implements(ijabber.IService)
-
- def componentConnected(self, xs):
- pass
-
- def componentDisconnected(self):
- pass
-
- def transportConnected(self, xs):
- pass
-
- def send(self, obj):
- """
- Send data over service parent's XML stream.
-
- @note: L{ServiceManager} maintains a queue for data sent using this
- method when there is no current established XML stream. This data is
- then sent as soon as a new stream has been established and initialized.
- Subsequently, L{componentConnected} will be called again. If this
- queueing is not desired, use C{send} on the XmlStream object (passed to
- L{componentConnected}) directly.
-
- @param obj: data to be sent over the XML stream. This is usually an
- object providing L{domish.IElement}, or serialized XML. See
- L{xmlstream.XmlStream} for details.
- """
-
- self.parent.send(obj)
-
-class ServiceManager(service.MultiService):
- """
- Business logic representing a managed component connection to a Jabber
- router.
-
- This service maintains a single connection to a Jabber router and provides
- facilities for packet routing and transmission. Business logic modules are
- services implementing L{ijabber.IService} (like subclasses of L{Service}), and
- added as sub-service.
- """
-
- def __init__(self, jid, password):
- service.MultiService.__init__(self)
-
- # Setup defaults
- self.jabberId = jid
- self.xmlstream = None
-
- # Internal buffer of packets
- self._packetQueue = []
-
- # Setup the xmlstream factory
- self._xsFactory = componentFactory(self.jabberId, password)
-
- # Register some lambda functions to keep the self.xmlstream var up to
- # date
- self._xsFactory.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
- self._connected)
- self._xsFactory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, self._authd)
- self._xsFactory.addBootstrap(xmlstream.STREAM_END_EVENT,
- self._disconnected)
-
- # Map addBootstrap and removeBootstrap to the underlying factory -- is
- # this right? I have no clue...but it'll work for now, until i can
- # think about it more.
- self.addBootstrap = self._xsFactory.addBootstrap
- self.removeBootstrap = self._xsFactory.removeBootstrap
-
- def getFactory(self):
- return self._xsFactory
-
- def _connected(self, xs):
- self.xmlstream = xs
- for c in self:
- if ijabber.IService.providedBy(c):
- c.transportConnected(xs)
-
- def _authd(self, xs):
- # Flush all pending packets
- for p in self._packetQueue:
- self.xmlstream.send(p)
- self._packetQueue = []
-
- # Notify all child services which implement the IService interface
- for c in self:
- if ijabber.IService.providedBy(c):
- c.componentConnected(xs)
-
- def _disconnected(self, _):
- self.xmlstream = None
-
- # Notify all child services which implement
- # the IService interface
- for c in self:
- if ijabber.IService.providedBy(c):
- c.componentDisconnected()
-
- def send(self, obj):
- """
- Send data over the XML stream.
-
- When there is no established XML stream, the data is queued and sent
- out when a new XML stream has been established and initialized.
-
- @param obj: data to be sent over the XML stream. This is usually an
- object providing L{domish.IElement}, or serialized XML. See
- L{xmlstream.XmlStream} for details.
- """
-
- if self.xmlstream != None:
- self.xmlstream.send(obj)
- else:
- self._packetQueue.append(obj)
-
-def buildServiceManager(jid, password, strport):
- """
- Constructs a pre-built L{ServiceManager}, using the specified strport
- string.
- """
-
- svc = ServiceManager(jid, password)
- client_svc = jstrports.client(strport, svc.getFactory())
- client_svc.setServiceParent(svc)
- return svc
-
-
-
-class Router(object):
- """
- XMPP Server's Router.
-
- A router connects the different components of the XMPP service and routes
- messages between them based on the given routing table.
-
- Connected components are trusted to have correct addressing in the
- stanzas they offer for routing.
-
- A route destination of C{None} adds a default route. Traffic for which no
- specific route exists, will be routed to this default route.
-
- @since: 8.2
- @ivar routes: Routes based on the host part of JIDs. Maps host names to the
- L{EventDispatcher<utility.EventDispatcher>}s that should
- receive the traffic. A key of C{None} means the default
- route.
- @type routes: C{dict}
- """
-
- def __init__(self):
- self.routes = {}
-
-
- def addRoute(self, destination, xs):
- """
- Add a new route.
-
- The passed XML Stream C{xs} will have an observer for all stanzas
- added to route its outgoing traffic. In turn, traffic for
- C{destination} will be passed to this stream.
-
- @param destination: Destination of the route to be added as a host name
- or C{None} for the default route.
- @type destination: C{str} or C{NoneType}.
- @param xs: XML Stream to register the route for.
- @type xs: L{EventDispatcher<utility.EventDispatcher>}.
- """
- self.routes[destination] = xs
- xs.addObserver('/*', self.route)
-
-
- def removeRoute(self, destination, xs):
- """
- Remove a route.
-
- @param destination: Destination of the route that should be removed.
- @type destination: C{str}.
- @param xs: XML Stream to remove the route for.
- @type xs: L{EventDispatcher<utility.EventDispatcher>}.
- """
- xs.removeObserver('/*', self.route)
- if (xs == self.routes[destination]):
- del self.routes[destination]
-
-
- def route(self, stanza):
- """
- Route a stanza.
-
- @param stanza: The stanza to be routed.
- @type stanza: L{domish.Element}.
- """
- destination = JID(stanza['to'])
-
- log.msg("Routing to %s: %r" % (destination.full(), stanza.toXml()))
-
- if destination.host in self.routes:
- self.routes[destination.host].send(stanza)
- else:
- self.routes[None].send(stanza)
-
-
-
-class XMPPComponentServerFactory(xmlstream.XmlStreamServerFactory):
- """
- XMPP Component Server factory.
-
- This factory accepts XMPP external component connections and makes
- the router service route traffic for a component's bound domain
- to that component.
-
- @since: 8.2
- """
-
- logTraffic = False
-
- def __init__(self, router, secret='secret'):
- self.router = router
- self.secret = secret
-
- def authenticatorFactory():
- return ListenComponentAuthenticator(self.secret)
-
- xmlstream.XmlStreamServerFactory.__init__(self, authenticatorFactory)
- self.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
- self.onConnectionMade)
- self.addBootstrap(xmlstream.STREAM_AUTHD_EVENT,
- self.onAuthenticated)
-
- self.serial = 0
-
-
- def onConnectionMade(self, xs):
- """
- Called when a component connection was made.
-
- This enables traffic debugging on incoming streams.
- """
- xs.serial = self.serial
- self.serial += 1
-
- def logDataIn(buf):
- log.msg("RECV (%d): %r" % (xs.serial, buf))
-
- def logDataOut(buf):
- log.msg("SEND (%d): %r" % (xs.serial, buf))
-
- if self.logTraffic:
- xs.rawDataInFn = logDataIn
- xs.rawDataOutFn = logDataOut
-
- xs.addObserver(xmlstream.STREAM_ERROR_EVENT, self.onError)
-
-
- def onAuthenticated(self, xs):
- """
- Called when a component has succesfully authenticated.
-
- Add the component to the routing table and establish a handler
- for a closed connection.
- """
- destination = xs.thisEntity.host
-
- self.router.addRoute(destination, xs)
- xs.addObserver(xmlstream.STREAM_END_EVENT, self.onConnectionLost, 0,
- destination, xs)
-
-
- def onError(self, reason):
- log.err(reason, "Stream Error")
-
-
- def onConnectionLost(self, destination, xs, reason):
- self.router.removeRoute(destination, xs)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/error.py
deleted file mode 100755
index aa5e9d2a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/error.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabbererror -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-XMPP Error support.
-"""
-
-import copy
-
-from twisted.words.xish import domish
-
-NS_XML = "http://www.w3.org/XML/1998/namespace"
-NS_XMPP_STREAMS = "urn:ietf:params:xml:ns:xmpp-streams"
-NS_XMPP_STANZAS = "urn:ietf:params:xml:ns:xmpp-stanzas"
-
-STANZA_CONDITIONS = {
- 'bad-request': {'code': '400', 'type': 'modify'},
- 'conflict': {'code': '409', 'type': 'cancel'},
- 'feature-not-implemented': {'code': '501', 'type': 'cancel'},
- 'forbidden': {'code': '403', 'type': 'auth'},
- 'gone': {'code': '302', 'type': 'modify'},
- 'internal-server-error': {'code': '500', 'type': 'wait'},
- 'item-not-found': {'code': '404', 'type': 'cancel'},
- 'jid-malformed': {'code': '400', 'type': 'modify'},
- 'not-acceptable': {'code': '406', 'type': 'modify'},
- 'not-allowed': {'code': '405', 'type': 'cancel'},
- 'not-authorized': {'code': '401', 'type': 'auth'},
- 'payment-required': {'code': '402', 'type': 'auth'},
- 'recipient-unavailable': {'code': '404', 'type': 'wait'},
- 'redirect': {'code': '302', 'type': 'modify'},
- 'registration-required': {'code': '407', 'type': 'auth'},
- 'remote-server-not-found': {'code': '404', 'type': 'cancel'},
- 'remote-server-timeout': {'code': '504', 'type': 'wait'},
- 'resource-constraint': {'code': '500', 'type': 'wait'},
- 'service-unavailable': {'code': '503', 'type': 'cancel'},
- 'subscription-required': {'code': '407', 'type': 'auth'},
- 'undefined-condition': {'code': '500', 'type': None},
- 'unexpected-request': {'code': '400', 'type': 'wait'},
-}
-
-CODES_TO_CONDITIONS = {
- '302': ('gone', 'modify'),
- '400': ('bad-request', 'modify'),
- '401': ('not-authorized', 'auth'),
- '402': ('payment-required', 'auth'),
- '403': ('forbidden', 'auth'),
- '404': ('item-not-found', 'cancel'),
- '405': ('not-allowed', 'cancel'),
- '406': ('not-acceptable', 'modify'),
- '407': ('registration-required', 'auth'),
- '408': ('remote-server-timeout', 'wait'),
- '409': ('conflict', 'cancel'),
- '500': ('internal-server-error', 'wait'),
- '501': ('feature-not-implemented', 'cancel'),
- '502': ('service-unavailable', 'wait'),
- '503': ('service-unavailable', 'cancel'),
- '504': ('remote-server-timeout', 'wait'),
- '510': ('service-unavailable', 'cancel'),
-}
-
-class BaseError(Exception):
- """
- Base class for XMPP error exceptions.
-
- @cvar namespace: The namespace of the C{error} element generated by
- C{getElement}.
- @type namespace: C{str}
- @ivar condition: The error condition. The valid values are defined by
- subclasses of L{BaseError}.
- @type contition: C{str}
- @ivar text: Optional text message to supplement the condition or application
- specific condition.
- @type text: C{unicode}
- @ivar textLang: Identifier of the language used for the message in C{text}.
- Values are as described in RFC 3066.
- @type textLang: C{str}
- @ivar appCondition: Application specific condition element, supplementing
- the error condition in C{condition}.
- @type appCondition: object providing L{domish.IElement}.
- """
-
- namespace = None
-
- def __init__(self, condition, text=None, textLang=None, appCondition=None):
- Exception.__init__(self)
- self.condition = condition
- self.text = text
- self.textLang = textLang
- self.appCondition = appCondition
-
-
- def __str__(self):
- message = "%s with condition %r" % (self.__class__.__name__,
- self.condition)
-
- if self.text:
- message += ': ' + self.text
-
- return message
-
-
- def getElement(self):
- """
- Get XML representation from self.
-
- The method creates an L{domish} representation of the
- error data contained in this exception.
-
- @rtype: L{domish.Element}
- """
- error = domish.Element((None, 'error'))
- error.addElement((self.namespace, self.condition))
- if self.text:
- text = error.addElement((self.namespace, 'text'),
- content=self.text)
- if self.textLang:
- text[(NS_XML, 'lang')] = self.textLang
- if self.appCondition:
- error.addChild(self.appCondition)
- return error
-
-
-
-class StreamError(BaseError):
- """
- Stream Error exception.
-
- Refer to RFC 3920, section 4.7.3, for the allowed values for C{condition}.
- """
-
- namespace = NS_XMPP_STREAMS
-
- def getElement(self):
- """
- Get XML representation from self.
-
- Overrides the base L{BaseError.getElement} to make sure the returned
- element is in the XML Stream namespace.
-
- @rtype: L{domish.Element}
- """
- from twisted.words.protocols.jabber.xmlstream import NS_STREAMS
-
- error = BaseError.getElement(self)
- error.uri = NS_STREAMS
- return error
-
-
-
-class StanzaError(BaseError):
- """
- Stanza Error exception.
-
- Refer to RFC 3920, section 9.3, for the allowed values for C{condition} and
- C{type}.
-
- @ivar type: The stanza error type. Gives a suggestion to the recipient
- of the error on how to proceed.
- @type type: C{str}
- @ivar code: A numeric identifier for the error condition for backwards
- compatibility with pre-XMPP Jabber implementations.
- """
-
- namespace = NS_XMPP_STANZAS
-
- def __init__(self, condition, type=None, text=None, textLang=None,
- appCondition=None):
- BaseError.__init__(self, condition, text, textLang, appCondition)
-
- if type is None:
- try:
- type = STANZA_CONDITIONS[condition]['type']
- except KeyError:
- pass
- self.type = type
-
- try:
- self.code = STANZA_CONDITIONS[condition]['code']
- except KeyError:
- self.code = None
-
- self.children = []
- self.iq = None
-
-
- def getElement(self):
- """
- Get XML representation from self.
-
- Overrides the base L{BaseError.getElement} to make sure the returned
- element has a C{type} attribute and optionally a legacy C{code}
- attribute.
-
- @rtype: L{domish.Element}
- """
- error = BaseError.getElement(self)
- error['type'] = self.type
- if self.code:
- error['code'] = self.code
- return error
-
-
- def toResponse(self, stanza):
- """
- Construct error response stanza.
-
- The C{stanza} is transformed into an error response stanza by
- swapping the C{to} and C{from} addresses and inserting an error
- element.
-
- @note: This creates a shallow copy of the list of child elements of the
- stanza. The child elements themselves are not copied themselves,
- and references to their parent element will still point to the
- original stanza element.
-
- The serialization of an element does not use the reference to
- its parent, so the typical use case of immediately sending out
- the constructed error response is not affected.
-
- @param stanza: the stanza to respond to
- @type stanza: L{domish.Element}
- """
- from twisted.words.protocols.jabber.xmlstream import toResponse
- response = toResponse(stanza, stanzaType='error')
- response.children = copy.copy(stanza.children)
- response.addChild(self.getElement())
- return response
-
-
-def _getText(element):
- for child in element.children:
- if isinstance(child, basestring):
- return unicode(child)
-
- return None
-
-
-
-def _parseError(error, errorNamespace):
- """
- Parses an error element.
-
- @param error: The error element to be parsed
- @type error: L{domish.Element}
- @param errorNamespace: The namespace of the elements that hold the error
- condition and text.
- @type errorNamespace: C{str}
- @return: Dictionary with extracted error information. If present, keys
- C{condition}, C{text}, C{textLang} have a string value,
- and C{appCondition} has an L{domish.Element} value.
- @rtype: C{dict}
- """
- condition = None
- text = None
- textLang = None
- appCondition = None
-
- for element in error.elements():
- if element.uri == errorNamespace:
- if element.name == 'text':
- text = _getText(element)
- textLang = element.getAttribute((NS_XML, 'lang'))
- else:
- condition = element.name
- else:
- appCondition = element
-
- return {
- 'condition': condition,
- 'text': text,
- 'textLang': textLang,
- 'appCondition': appCondition,
- }
-
-
-
-def exceptionFromStreamError(element):
- """
- Build an exception object from a stream error.
-
- @param element: the stream error
- @type element: L{domish.Element}
- @return: the generated exception object
- @rtype: L{StreamError}
- """
- error = _parseError(element, NS_XMPP_STREAMS)
-
- exception = StreamError(error['condition'],
- error['text'],
- error['textLang'],
- error['appCondition'])
-
- return exception
-
-
-
-def exceptionFromStanza(stanza):
- """
- Build an exception object from an error stanza.
-
- @param stanza: the error stanza
- @type stanza: L{domish.Element}
- @return: the generated exception object
- @rtype: L{StanzaError}
- """
- children = []
- condition = text = textLang = appCondition = type = code = None
-
- for element in stanza.elements():
- if element.name == 'error' and element.uri == stanza.uri:
- code = element.getAttribute('code')
- type = element.getAttribute('type')
- error = _parseError(element, NS_XMPP_STANZAS)
- condition = error['condition']
- text = error['text']
- textLang = error['textLang']
- appCondition = error['appCondition']
-
- if not condition and code:
- condition, type = CODES_TO_CONDITIONS[code]
- text = _getText(stanza.error)
- else:
- children.append(element)
-
- if condition is None:
- # TODO: raise exception instead?
- return StanzaError(None)
-
- exception = StanzaError(condition, type, text, textLang, appCondition)
-
- exception.children = children
- exception.stanza = stanza
-
- return exception
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/ijabber.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/ijabber.py
deleted file mode 100755
index 9cc65ff7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/ijabber.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Public Jabber Interfaces.
-"""
-
-from zope.interface import Attribute, Interface
-
-class IInitializer(Interface):
- """
- Interface for XML stream initializers.
-
- Initializers perform a step in getting the XML stream ready to be
- used for the exchange of XML stanzas.
- """
-
-
-
-class IInitiatingInitializer(IInitializer):
- """
- Interface for XML stream initializers for the initiating entity.
- """
-
- xmlstream = Attribute("""The associated XML stream""")
-
- def initialize():
- """
- Initiate the initialization step.
-
- May return a deferred when the initialization is done asynchronously.
- """
-
-
-
-class IIQResponseTracker(Interface):
- """
- IQ response tracker interface.
-
- The XMPP stanza C{iq} has a request-response nature that fits
- naturally with deferreds. You send out a request and when the response
- comes back a deferred is fired.
-
- The L{IQ} class implements a C{send} method that returns a deferred. This
- deferred is put in a dictionary that is kept in an L{XmlStream} object,
- keyed by the request stanzas C{id} attribute.
-
- An object providing this interface (usually an instance of L{XmlStream}),
- keeps the said dictionary and sets observers on the iq stanzas of type
- C{result} and C{error} and lets the callback fire the associated deferred.
- """
- iqDeferreds = Attribute("Dictionary of deferreds waiting for an iq "
- "response")
-
-
-
-class IXMPPHandler(Interface):
- """
- Interface for XMPP protocol handlers.
-
- Objects that provide this interface can be added to a stream manager to
- handle of (part of) an XMPP extension protocol.
- """
-
- parent = Attribute("""XML stream manager for this handler""")
- xmlstream = Attribute("""The managed XML stream""")
-
- def setHandlerParent(parent):
- """
- Set the parent of the handler.
-
- @type parent: L{IXMPPHandlerCollection}
- """
-
-
- def disownHandlerParent(parent):
- """
- Remove the parent of the handler.
-
- @type parent: L{IXMPPHandlerCollection}
- """
-
-
- def makeConnection(xs):
- """
- A connection over the underlying transport of the XML stream has been
- established.
-
- At this point, no traffic has been exchanged over the XML stream
- given in C{xs}.
-
- This should setup L{xmlstream} and call L{connectionMade}.
-
- @type xs: L{XmlStream<twisted.words.protocols.jabber.XmlStream>}
- """
-
-
- def connectionMade():
- """
- Called after a connection has been established.
-
- This method can be used to change properties of the XML Stream, its
- authenticator or the stream manager prior to stream initialization
- (including authentication).
- """
-
-
- def connectionInitialized():
- """
- The XML stream has been initialized.
-
- At this point, authentication was successful, and XML stanzas can be
- exchanged over the XML stream L{xmlstream}. This method can be
- used to setup observers for incoming stanzas.
- """
-
-
- def connectionLost(reason):
- """
- The XML stream has been closed.
-
- Subsequent use of C{parent.send} will result in data being queued
- until a new connection has been established.
-
- @type reason: L{twisted.python.failure.Failure}
- """
-
-
-
-class IXMPPHandlerCollection(Interface):
- """
- Collection of handlers.
-
- Contain several handlers and manage their connection.
- """
-
- def __iter__():
- """
- Get an iterator over all child handlers.
- """
-
-
- def addHandler(handler):
- """
- Add a child handler.
-
- @type handler: L{IXMPPHandler}
- """
-
-
- def removeHandler(handler):
- """
- Remove a child handler.
-
- @type handler: L{IXMPPHandler}
- """
-
-
-
-class IService(Interface):
- """
- External server-side component service interface.
-
- Services that provide this interface can be added to L{ServiceManager} to
- implement (part of) the functionality of the server-side component.
- """
-
- def componentConnected(xs):
- """
- Parent component has established a connection.
-
- At this point, authentication was succesful, and XML stanzas
- can be exchanged over the XML stream C{xs}. This method can be used
- to setup observers for incoming stanzas.
-
- @param xs: XML Stream that represents the established connection.
- @type xs: L{xmlstream.XmlStream}
- """
-
-
- def componentDisconnected():
- """
- Parent component has lost the connection to the Jabber server.
-
- Subsequent use of C{self.parent.send} will result in data being
- queued until a new connection has been established.
- """
-
-
- def transportConnected(xs):
- """
- Parent component has established a connection over the underlying
- transport.
-
- At this point, no traffic has been exchanged over the XML stream. This
- method can be used to change properties of the XML Stream (in C{xs}),
- the service manager or it's authenticator prior to stream
- initialization (including authentication).
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jid.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jid.py
deleted file mode 100755
index 9911cee9..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jid.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabberjid -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Jabber Identifier support.
-
-This module provides an object to represent Jabber Identifiers (JIDs) and
-parse string representations into them with proper checking for illegal
-characters, case folding and canonicalisation through L{stringprep<twisted.words.protocols.jabber.xmpp_stringprep>}.
-"""
-
-from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep, resourceprep, nameprep
-
-class InvalidFormat(Exception):
- """
- The given string could not be parsed into a valid Jabber Identifier (JID).
- """
-
-def parse(jidstring):
- """
- Parse given JID string into its respective parts and apply stringprep.
-
- @param jidstring: string representation of a JID.
- @type jidstring: C{unicode}
- @return: tuple of (user, host, resource), each of type C{unicode} as
- the parsed and stringprep'd parts of the given JID. If the
- given string did not have a user or resource part, the respective
- field in the tuple will hold C{None}.
- @rtype: C{tuple}
- """
- user = None
- host = None
- resource = None
-
- # Search for delimiters
- user_sep = jidstring.find("@")
- res_sep = jidstring.find("/")
-
- if user_sep == -1:
- if res_sep == -1:
- # host
- host = jidstring
- else:
- # host/resource
- host = jidstring[0:res_sep]
- resource = jidstring[res_sep + 1:] or None
- else:
- if res_sep == -1:
- # user@host
- user = jidstring[0:user_sep] or None
- host = jidstring[user_sep + 1:]
- else:
- if user_sep < res_sep:
- # user@host/resource
- user = jidstring[0:user_sep] or None
- host = jidstring[user_sep + 1:user_sep + (res_sep - user_sep)]
- resource = jidstring[res_sep + 1:] or None
- else:
- # host/resource (with an @ in resource)
- host = jidstring[0:res_sep]
- resource = jidstring[res_sep + 1:] or None
-
- return prep(user, host, resource)
-
-def prep(user, host, resource):
- """
- Perform stringprep on all JID fragments.
-
- @param user: The user part of the JID.
- @type user: C{unicode}
- @param host: The host part of the JID.
- @type host: C{unicode}
- @param resource: The resource part of the JID.
- @type resource: C{unicode}
- @return: The given parts with stringprep applied.
- @rtype: C{tuple}
- """
-
- if user:
- try:
- user = nodeprep.prepare(unicode(user))
- except UnicodeError:
- raise InvalidFormat, "Invalid character in username"
- else:
- user = None
-
- if not host:
- raise InvalidFormat, "Server address required."
- else:
- try:
- host = nameprep.prepare(unicode(host))
- except UnicodeError:
- raise InvalidFormat, "Invalid character in hostname"
-
- if resource:
- try:
- resource = resourceprep.prepare(unicode(resource))
- except UnicodeError:
- raise InvalidFormat, "Invalid character in resource"
- else:
- resource = None
-
- return (user, host, resource)
-
-__internJIDs = {}
-
-def internJID(jidstring):
- """
- Return interned JID.
-
- @rtype: L{JID}
- """
-
- if jidstring in __internJIDs:
- return __internJIDs[jidstring]
- else:
- j = JID(jidstring)
- __internJIDs[jidstring] = j
- return j
-
-class JID(object):
- """
- Represents a stringprep'd Jabber ID.
-
- JID objects are hashable so they can be used in sets and as keys in
- dictionaries.
- """
-
- def __init__(self, str=None, tuple=None):
- if not (str or tuple):
- raise RuntimeError("You must provide a value for either 'str' or "
- "'tuple' arguments.")
-
- if str:
- user, host, res = parse(str)
- else:
- user, host, res = prep(*tuple)
-
- self.user = user
- self.host = host
- self.resource = res
-
- def userhost(self):
- """
- Extract the bare JID as a unicode string.
-
- A bare JID does not have a resource part, so this returns either
- C{user@host} or just C{host}.
-
- @rtype: C{unicode}
- """
- if self.user:
- return u"%s@%s" % (self.user, self.host)
- else:
- return self.host
-
- def userhostJID(self):
- """
- Extract the bare JID.
-
- A bare JID does not have a resource part, so this returns a
- L{JID} object representing either C{user@host} or just C{host}.
-
- If the object this method is called upon doesn't have a resource
- set, it will return itself. Otherwise, the bare JID object will
- be created, interned using L{internJID}.
-
- @rtype: L{JID}
- """
- if self.resource:
- return internJID(self.userhost())
- else:
- return self
-
- def full(self):
- """
- Return the string representation of this JID.
-
- @rtype: C{unicode}
- """
- if self.user:
- if self.resource:
- return u"%s@%s/%s" % (self.user, self.host, self.resource)
- else:
- return u"%s@%s" % (self.user, self.host)
- else:
- if self.resource:
- return u"%s/%s" % (self.host, self.resource)
- else:
- return self.host
-
- def __eq__(self, other):
- """
- Equality comparison.
-
- L{JID}s compare equal if their user, host and resource parts all
- compare equal. When comparing against instances of other types, it
- uses the default comparison.
- """
- if isinstance(other, JID):
- return (self.user == other.user and
- self.host == other.host and
- self.resource == other.resource)
- else:
- return NotImplemented
-
- def __ne__(self, other):
- """
- Inequality comparison.
-
- This negates L{__eq__} for comparison with JIDs and uses the default
- comparison for other types.
- """
- result = self.__eq__(other)
- if result is NotImplemented:
- return result
- else:
- return not result
-
- def __hash__(self):
- """
- Calculate hash.
-
- L{JID}s with identical constituent user, host and resource parts have
- equal hash values. In combination with the comparison defined on JIDs,
- this allows for using L{JID}s in sets and as dictionary keys.
- """
- return hash((self.user, self.host, self.resource))
-
- def __unicode__(self):
- """
- Get unicode representation.
-
- Return the string representation of this JID as a unicode string.
- @see: L{full}
- """
-
- return self.full()
-
- def __repr__(self):
- """
- Get object representation.
-
- Returns a string that would create a new JID object that compares equal
- to this one.
- """
- return 'JID(%r)' % self.full()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jstrports.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jstrports.py
deleted file mode 100755
index 773b6d2a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/jstrports.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-""" A temporary placeholder for client-capable strports, until we
-sufficient use cases get identified """
-
-from twisted.internet.endpoints import _parse
-
-def _parseTCPSSL(factory, domain, port):
- """ For the moment, parse TCP or SSL connections the same """
- return (domain, int(port), factory), {}
-
-def _parseUNIX(factory, address):
- return (address, factory), {}
-
-
-_funcs = { "tcp" : _parseTCPSSL,
- "unix" : _parseUNIX,
- "ssl" : _parseTCPSSL }
-
-
-def parse(description, factory):
- args, kw = _parse(description)
- return (args[0].upper(),) + _funcs[args[0]](factory, *args[1:], **kw)
-
-def client(description, factory):
- from twisted.application import internet
- name, args, kw = parse(description, factory)
- return getattr(internet, name + 'Client')(*args, **kw)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl.py
deleted file mode 100755
index c804ad45..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-XMPP-specific SASL profile.
-"""
-
-import re
-from twisted.internet import defer
-from twisted.words.protocols.jabber import sasl_mechanisms, xmlstream
-from twisted.words.xish import domish
-
-# The b64decode and b64encode functions from the base64 module are new in
-# Python 2.4. For Python 2.3 compatibility, the legacy interface is used while
-# working around MIMEisms.
-
-try:
- from base64 import b64decode, b64encode
-except ImportError:
- import base64
-
- def b64encode(s):
- return "".join(base64.encodestring(s).split("\n"))
-
- b64decode = base64.decodestring
-
-NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl'
-
-def get_mechanisms(xs):
- """
- Parse the SASL feature to extract the available mechanism names.
- """
- mechanisms = []
- for element in xs.features[(NS_XMPP_SASL, 'mechanisms')].elements():
- if element.name == 'mechanism':
- mechanisms.append(str(element))
-
- return mechanisms
-
-
-class SASLError(Exception):
- """
- SASL base exception.
- """
-
-
-class SASLNoAcceptableMechanism(SASLError):
- """
- The server did not present an acceptable SASL mechanism.
- """
-
-
-class SASLAuthError(SASLError):
- """
- SASL Authentication failed.
- """
- def __init__(self, condition=None):
- self.condition = condition
-
-
- def __str__(self):
- return "SASLAuthError with condition %r" % self.condition
-
-
-class SASLIncorrectEncodingError(SASLError):
- """
- SASL base64 encoding was incorrect.
-
- RFC 3920 specifies that any characters not in the base64 alphabet
- and padding characters present elsewhere than at the end of the string
- MUST be rejected. See also L{fromBase64}.
-
- This exception is raised whenever the encoded string does not adhere
- to these additional restrictions or when the decoding itself fails.
-
- The recommended behaviour for so-called receiving entities (like servers in
- client-to-server connections, see RFC 3920 for terminology) is to fail the
- SASL negotiation with a C{'incorrect-encoding'} condition. For initiating
- entities, one should assume the receiving entity to be either buggy or
- malevolent. The stream should be terminated and reconnecting is not
- advised.
- """
-
-base64Pattern = re.compile("^[0-9A-Za-z+/]*[0-9A-Za-z+/=]{,2}$")
-
-def fromBase64(s):
- """
- Decode base64 encoded string.
-
- This helper performs regular decoding of a base64 encoded string, but also
- rejects any characters that are not in the base64 alphabet and padding
- occurring elsewhere from the last or last two characters, as specified in
- section 14.9 of RFC 3920. This safeguards against various attack vectors
- among which the creation of a covert channel that "leaks" information.
- """
-
- if base64Pattern.match(s) is None:
- raise SASLIncorrectEncodingError()
-
- try:
- return b64decode(s)
- except Exception, e:
- raise SASLIncorrectEncodingError(str(e))
-
-
-
-class SASLInitiatingInitializer(xmlstream.BaseFeatureInitiatingInitializer):
- """
- Stream initializer that performs SASL authentication.
-
- The supported mechanisms by this initializer are C{DIGEST-MD5}, C{PLAIN}
- and C{ANONYMOUS}. The C{ANONYMOUS} SASL mechanism is used when the JID, set
- on the authenticator, does not have a localpart (username), requesting an
- anonymous session where the username is generated by the server.
- Otherwise, C{DIGEST-MD5} and C{PLAIN} are attempted, in that order.
- """
-
- feature = (NS_XMPP_SASL, 'mechanisms')
- _deferred = None
-
- def setMechanism(self):
- """
- Select and setup authentication mechanism.
-
- Uses the authenticator's C{jid} and C{password} attribute for the
- authentication credentials. If no supported SASL mechanisms are
- advertized by the receiving party, a failing deferred is returned with
- a L{SASLNoAcceptableMechanism} exception.
- """
-
- jid = self.xmlstream.authenticator.jid
- password = self.xmlstream.authenticator.password
-
- mechanisms = get_mechanisms(self.xmlstream)
- if jid.user is not None:
- if 'DIGEST-MD5' in mechanisms:
- self.mechanism = sasl_mechanisms.DigestMD5('xmpp', jid.host, None,
- jid.user, password)
- elif 'PLAIN' in mechanisms:
- self.mechanism = sasl_mechanisms.Plain(None, jid.user, password)
- else:
- raise SASLNoAcceptableMechanism()
- else:
- if 'ANONYMOUS' in mechanisms:
- self.mechanism = sasl_mechanisms.Anonymous()
- else:
- raise SASLNoAcceptableMechanism()
-
-
- def start(self):
- """
- Start SASL authentication exchange.
- """
-
- self.setMechanism()
- self._deferred = defer.Deferred()
- self.xmlstream.addObserver('/challenge', self.onChallenge)
- self.xmlstream.addOnetimeObserver('/success', self.onSuccess)
- self.xmlstream.addOnetimeObserver('/failure', self.onFailure)
- self.sendAuth(self.mechanism.getInitialResponse())
- return self._deferred
-
-
- def sendAuth(self, data=None):
- """
- Initiate authentication protocol exchange.
-
- If an initial client response is given in C{data}, it will be
- sent along.
-
- @param data: initial client response.
- @type data: C{str} or C{None}.
- """
-
- auth = domish.Element((NS_XMPP_SASL, 'auth'))
- auth['mechanism'] = self.mechanism.name
- if data is not None:
- auth.addContent(b64encode(data) or '=')
- self.xmlstream.send(auth)
-
-
- def sendResponse(self, data=''):
- """
- Send response to a challenge.
-
- @param data: client response.
- @type data: C{str}.
- """
-
- response = domish.Element((NS_XMPP_SASL, 'response'))
- if data:
- response.addContent(b64encode(data))
- self.xmlstream.send(response)
-
-
- def onChallenge(self, element):
- """
- Parse challenge and send response from the mechanism.
-
- @param element: the challenge protocol element.
- @type element: L{domish.Element}.
- """
-
- try:
- challenge = fromBase64(str(element))
- except SASLIncorrectEncodingError:
- self._deferred.errback()
- else:
- self.sendResponse(self.mechanism.getResponse(challenge))
-
-
- def onSuccess(self, success):
- """
- Clean up observers, reset the XML stream and send a new header.
-
- @param success: the success protocol element. For now unused, but
- could hold additional data.
- @type success: L{domish.Element}
- """
-
- self.xmlstream.removeObserver('/challenge', self.onChallenge)
- self.xmlstream.removeObserver('/failure', self.onFailure)
- self.xmlstream.reset()
- self.xmlstream.sendHeader()
- self._deferred.callback(xmlstream.Reset)
-
-
- def onFailure(self, failure):
- """
- Clean up observers, parse the failure and errback the deferred.
-
- @param failure: the failure protocol element. Holds details on
- the error condition.
- @type failure: L{domish.Element}
- """
-
- self.xmlstream.removeObserver('/challenge', self.onChallenge)
- self.xmlstream.removeObserver('/success', self.onSuccess)
- try:
- condition = failure.firstChildElement().name
- except AttributeError:
- condition = None
- self._deferred.errback(SASLAuthError(condition))
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl_mechanisms.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl_mechanisms.py
deleted file mode 100755
index 5d51be2f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/sasl_mechanisms.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabbersaslmechanisms -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Protocol agnostic implementations of SASL authentication mechanisms.
-"""
-
-import binascii, random, time, os
-
-from zope.interface import Interface, Attribute, implements
-
-from twisted.python.hashlib import md5
-
-class ISASLMechanism(Interface):
- name = Attribute("""Common name for the SASL Mechanism.""")
-
- def getInitialResponse():
- """
- Get the initial client response, if defined for this mechanism.
-
- @return: initial client response string.
- @rtype: C{str}.
- """
-
-
- def getResponse(challenge):
- """
- Get the response to a server challenge.
-
- @param challenge: server challenge.
- @type challenge: C{str}.
- @return: client response.
- @rtype: C{str}.
- """
-
-
-
-class Anonymous(object):
- """
- Implements the ANONYMOUS SASL authentication mechanism.
-
- This mechanism is defined in RFC 2245.
- """
- implements(ISASLMechanism)
- name = 'ANONYMOUS'
-
- def getInitialResponse(self):
- return None
-
-
-
-class Plain(object):
- """
- Implements the PLAIN SASL authentication mechanism.
-
- The PLAIN SASL authentication mechanism is defined in RFC 2595.
- """
- implements(ISASLMechanism)
-
- name = 'PLAIN'
-
- def __init__(self, authzid, authcid, password):
- self.authzid = authzid or ''
- self.authcid = authcid or ''
- self.password = password or ''
-
-
- def getInitialResponse(self):
- return "%s\x00%s\x00%s" % (self.authzid.encode('utf-8'),
- self.authcid.encode('utf-8'),
- self.password.encode('utf-8'))
-
-
-
-class DigestMD5(object):
- """
- Implements the DIGEST-MD5 SASL authentication mechanism.
-
- The DIGEST-MD5 SASL authentication mechanism is defined in RFC 2831.
- """
- implements(ISASLMechanism)
-
- name = 'DIGEST-MD5'
-
- def __init__(self, serv_type, host, serv_name, username, password):
- self.username = username
- self.password = password
- self.defaultRealm = host
-
- self.digest_uri = '%s/%s' % (serv_type, host)
- if serv_name is not None:
- self.digest_uri += '/%s' % serv_name
-
-
- def getInitialResponse(self):
- return None
-
-
- def getResponse(self, challenge):
- directives = self._parse(challenge)
-
- # Compat for implementations that do not send this along with
- # a succesful authentication.
- if 'rspauth' in directives:
- return ''
-
- try:
- realm = directives['realm']
- except KeyError:
- realm = self.defaultRealm
-
- return self._gen_response(directives['charset'],
- realm,
- directives['nonce'])
-
- def _parse(self, challenge):
- """
- Parses the server challenge.
-
- Splits the challenge into a dictionary of directives with values.
-
- @return: challenge directives and their values.
- @rtype: C{dict} of C{str} to C{str}.
- """
- s = challenge
- paramDict = {}
- cur = 0
- remainingParams = True
- while remainingParams:
- # Parse a param. We can't just split on commas, because there can
- # be some commas inside (quoted) param values, e.g.:
- # qop="auth,auth-int"
-
- middle = s.index("=", cur)
- name = s[cur:middle].lstrip()
- middle += 1
- if s[middle] == '"':
- middle += 1
- end = s.index('"', middle)
- value = s[middle:end]
- cur = s.find(',', end) + 1
- if cur == 0:
- remainingParams = False
- else:
- end = s.find(',', middle)
- if end == -1:
- value = s[middle:].rstrip()
- remainingParams = False
- else:
- value = s[middle:end].rstrip()
- cur = end + 1
- paramDict[name] = value
-
- for param in ('qop', 'cipher'):
- if param in paramDict:
- paramDict[param] = paramDict[param].split(',')
-
- return paramDict
-
- def _unparse(self, directives):
- """
- Create message string from directives.
-
- @param directives: dictionary of directives (names to their values).
- For certain directives, extra quotes are added, as
- needed.
- @type directives: C{dict} of C{str} to C{str}
- @return: message string.
- @rtype: C{str}.
- """
-
- directive_list = []
- for name, value in directives.iteritems():
- if name in ('username', 'realm', 'cnonce',
- 'nonce', 'digest-uri', 'authzid', 'cipher'):
- directive = '%s="%s"' % (name, value)
- else:
- directive = '%s=%s' % (name, value)
-
- directive_list.append(directive)
-
- return ','.join(directive_list)
-
-
- def _gen_response(self, charset, realm, nonce):
- """
- Generate response-value.
-
- Creates a response to a challenge according to section 2.1.2.1 of
- RFC 2831 using the C{charset}, C{realm} and C{nonce} directives
- from the challenge.
- """
-
- def H(s):
- return md5(s).digest()
-
- def HEX(n):
- return binascii.b2a_hex(n)
-
- def KD(k, s):
- return H('%s:%s' % (k, s))
-
- try:
- username = self.username.encode(charset)
- password = self.password.encode(charset)
- except UnicodeError:
- # TODO - add error checking
- raise
-
- nc = '%08x' % 1 # TODO: support subsequent auth.
- cnonce = self._gen_nonce()
- qop = 'auth'
-
- # TODO - add support for authzid
- a1 = "%s:%s:%s" % (H("%s:%s:%s" % (username, realm, password)),
- nonce,
- cnonce)
- a2 = "AUTHENTICATE:%s" % self.digest_uri
-
- response = HEX( KD ( HEX(H(a1)),
- "%s:%s:%s:%s:%s" % (nonce, nc,
- cnonce, "auth", HEX(H(a2)))))
-
- directives = {'username': username,
- 'realm' : realm,
- 'nonce' : nonce,
- 'cnonce' : cnonce,
- 'nc' : nc,
- 'qop' : qop,
- 'digest-uri': self.digest_uri,
- 'response': response,
- 'charset': charset}
-
- return self._unparse(directives)
-
-
- def _gen_nonce(self):
- return md5("%s:%s:%s" % (str(random.random()) , str(time.gmtime()),str(os.getpid()))).hexdigest()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmlstream.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmlstream.py
deleted file mode 100755
index cc2745bd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmlstream.py
+++ /dev/null
@@ -1,1136 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabberxmlstream -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-XMPP XML Streams
-
-Building blocks for setting up XML Streams, including helping classes for
-doing authentication on either client or server side, and working with XML
-Stanzas.
-"""
-
-from zope.interface import directlyProvides, implements
-
-from twisted.internet import defer, protocol
-from twisted.internet.error import ConnectionLost
-from twisted.python import failure, log, randbytes
-from twisted.python.hashlib import sha1
-from twisted.words.protocols.jabber import error, ijabber, jid
-from twisted.words.xish import domish, xmlstream
-from twisted.words.xish.xmlstream import STREAM_CONNECTED_EVENT
-from twisted.words.xish.xmlstream import STREAM_START_EVENT
-from twisted.words.xish.xmlstream import STREAM_END_EVENT
-from twisted.words.xish.xmlstream import STREAM_ERROR_EVENT
-
-try:
- from twisted.internet import ssl
-except ImportError:
- ssl = None
-if ssl and not ssl.supported:
- ssl = None
-
-STREAM_AUTHD_EVENT = intern("//event/stream/authd")
-INIT_FAILED_EVENT = intern("//event/xmpp/initfailed")
-
-NS_STREAMS = 'http://etherx.jabber.org/streams'
-NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls'
-
-Reset = object()
-
-def hashPassword(sid, password):
- """
- Create a SHA1-digest string of a session identifier and password.
-
- @param sid: The stream session identifier.
- @type sid: C{unicode}.
- @param password: The password to be hashed.
- @type password: C{unicode}.
- """
- if not isinstance(sid, unicode):
- raise TypeError("The session identifier must be a unicode object")
- if not isinstance(password, unicode):
- raise TypeError("The password must be a unicode object")
- input = u"%s%s" % (sid, password)
- return sha1(input.encode('utf-8')).hexdigest()
-
-
-
-class Authenticator:
- """
- Base class for business logic of initializing an XmlStream
-
- Subclass this object to enable an XmlStream to initialize and authenticate
- to different types of stream hosts (such as clients, components, etc.).
-
- Rules:
- 1. The Authenticator MUST dispatch a L{STREAM_AUTHD_EVENT} when the
- stream has been completely initialized.
- 2. The Authenticator SHOULD reset all state information when
- L{associateWithStream} is called.
- 3. The Authenticator SHOULD override L{streamStarted}, and start
- initialization there.
-
- @type xmlstream: L{XmlStream}
- @ivar xmlstream: The XmlStream that needs authentication
-
- @note: the term authenticator is historical. Authenticators perform
- all steps required to prepare the stream for the exchange
- of XML stanzas.
- """
-
- def __init__(self):
- self.xmlstream = None
-
-
- def connectionMade(self):
- """
- Called by the XmlStream when the underlying socket connection is
- in place.
-
- This allows the Authenticator to send an initial root element, if it's
- connecting, or wait for an inbound root from the peer if it's accepting
- the connection.
-
- Subclasses can use self.xmlstream.send() to send any initial data to
- the peer.
- """
-
-
- def streamStarted(self, rootElement):
- """
- Called by the XmlStream when the stream has started.
-
- A stream is considered to have started when the start tag of the root
- element has been received.
-
- This examines C{rootElement} to see if there is a version attribute.
- If absent, C{0.0} is assumed per RFC 3920. Subsequently, the
- minimum of the version from the received stream header and the
- value stored in L{xmlstream} is taken and put back in L{xmlstream}.
-
- Extensions of this method can extract more information from the
- stream header and perform checks on them, optionally sending
- stream errors and closing the stream.
- """
- if rootElement.hasAttribute("version"):
- version = rootElement["version"].split(".")
- try:
- version = (int(version[0]), int(version[1]))
- except (IndexError, ValueError):
- version = (0, 0)
- else:
- version = (0, 0)
-
- self.xmlstream.version = min(self.xmlstream.version, version)
-
-
- def associateWithStream(self, xmlstream):
- """
- Called by the XmlStreamFactory when a connection has been made
- to the requested peer, and an XmlStream object has been
- instantiated.
-
- The default implementation just saves a handle to the new
- XmlStream.
-
- @type xmlstream: L{XmlStream}
- @param xmlstream: The XmlStream that will be passing events to this
- Authenticator.
-
- """
- self.xmlstream = xmlstream
-
-
-
-class ConnectAuthenticator(Authenticator):
- """
- Authenticator for initiating entities.
- """
-
- namespace = None
-
- def __init__(self, otherHost):
- self.otherHost = otherHost
-
-
- def connectionMade(self):
- self.xmlstream.namespace = self.namespace
- self.xmlstream.otherEntity = jid.internJID(self.otherHost)
- self.xmlstream.sendHeader()
-
-
- def initializeStream(self):
- """
- Perform stream initialization procedures.
-
- An L{XmlStream} holds a list of initializer objects in its
- C{initializers} attribute. This method calls these initializers in
- order and dispatches the C{STREAM_AUTHD_EVENT} event when the list has
- been successfully processed. Otherwise it dispatches the
- C{INIT_FAILED_EVENT} event with the failure.
-
- Initializers may return the special L{Reset} object to halt the
- initialization processing. It signals that the current initializer was
- successfully processed, but that the XML Stream has been reset. An
- example is the TLSInitiatingInitializer.
- """
-
- def remove_first(result):
- self.xmlstream.initializers.pop(0)
-
- return result
-
- def do_next(result):
- """
- Take the first initializer and process it.
-
- On success, the initializer is removed from the list and
- then next initializer will be tried.
- """
-
- if result is Reset:
- return None
-
- try:
- init = self.xmlstream.initializers[0]
- except IndexError:
- self.xmlstream.dispatch(self.xmlstream, STREAM_AUTHD_EVENT)
- return None
- else:
- d = defer.maybeDeferred(init.initialize)
- d.addCallback(remove_first)
- d.addCallback(do_next)
- return d
-
- d = defer.succeed(None)
- d.addCallback(do_next)
- d.addErrback(self.xmlstream.dispatch, INIT_FAILED_EVENT)
-
-
- def streamStarted(self, rootElement):
- """
- Called by the XmlStream when the stream has started.
-
- This extends L{Authenticator.streamStarted} to extract further stream
- headers from C{rootElement}, optionally wait for stream features being
- received and then call C{initializeStream}.
- """
-
- Authenticator.streamStarted(self, rootElement)
-
- self.xmlstream.sid = rootElement.getAttribute("id")
-
- if rootElement.hasAttribute("from"):
- self.xmlstream.otherEntity = jid.internJID(rootElement["from"])
-
- # Setup observer for stream features, if applicable
- if self.xmlstream.version >= (1, 0):
- def onFeatures(element):
- features = {}
- for feature in element.elements():
- features[(feature.uri, feature.name)] = feature
-
- self.xmlstream.features = features
- self.initializeStream()
-
- self.xmlstream.addOnetimeObserver('/features[@xmlns="%s"]' %
- NS_STREAMS,
- onFeatures)
- else:
- self.initializeStream()
-
-
-
-class ListenAuthenticator(Authenticator):
- """
- Authenticator for receiving entities.
- """
-
- namespace = None
-
- def associateWithStream(self, xmlstream):
- """
- Called by the XmlStreamFactory when a connection has been made.
-
- Extend L{Authenticator.associateWithStream} to set the L{XmlStream}
- to be non-initiating.
- """
- Authenticator.associateWithStream(self, xmlstream)
- self.xmlstream.initiating = False
-
-
- def streamStarted(self, rootElement):
- """
- Called by the XmlStream when the stream has started.
-
- This extends L{Authenticator.streamStarted} to extract further
- information from the stream headers from C{rootElement}.
- """
- Authenticator.streamStarted(self, rootElement)
-
- self.xmlstream.namespace = rootElement.defaultUri
-
- if rootElement.hasAttribute("to"):
- self.xmlstream.thisEntity = jid.internJID(rootElement["to"])
-
- self.xmlstream.prefixes = {}
- for prefix, uri in rootElement.localPrefixes.iteritems():
- self.xmlstream.prefixes[uri] = prefix
-
- self.xmlstream.sid = unicode(randbytes.secureRandom(8).encode('hex'))
-
-
-
-class FeatureNotAdvertized(Exception):
- """
- Exception indicating a stream feature was not advertized, while required by
- the initiating entity.
- """
-
-
-
-class BaseFeatureInitiatingInitializer(object):
- """
- Base class for initializers with a stream feature.
-
- This assumes the associated XmlStream represents the initiating entity
- of the connection.
-
- @cvar feature: tuple of (uri, name) of the stream feature root element.
- @type feature: tuple of (C{str}, C{str})
- @ivar required: whether the stream feature is required to be advertized
- by the receiving entity.
- @type required: C{bool}
- """
-
- implements(ijabber.IInitiatingInitializer)
-
- feature = None
- required = False
-
- def __init__(self, xs):
- self.xmlstream = xs
-
-
- def initialize(self):
- """
- Initiate the initialization.
-
- Checks if the receiving entity advertizes the stream feature. If it
- does, the initialization is started. If it is not advertized, and the
- C{required} instance variable is C{True}, it raises
- L{FeatureNotAdvertized}. Otherwise, the initialization silently
- succeeds.
- """
-
- if self.feature in self.xmlstream.features:
- return self.start()
- elif self.required:
- raise FeatureNotAdvertized
- else:
- return None
-
-
- def start(self):
- """
- Start the actual initialization.
-
- May return a deferred for asynchronous initialization.
- """
-
-
-
-class TLSError(Exception):
- """
- TLS base exception.
- """
-
-
-
-class TLSFailed(TLSError):
- """
- Exception indicating failed TLS negotiation
- """
-
-
-
-class TLSRequired(TLSError):
- """
- Exception indicating required TLS negotiation.
-
- This exception is raised when the receiving entity requires TLS
- negotiation and the initiating does not desire to negotiate TLS.
- """
-
-
-
-class TLSNotSupported(TLSError):
- """
- Exception indicating missing TLS support.
-
- This exception is raised when the initiating entity wants and requires to
- negotiate TLS when the OpenSSL library is not available.
- """
-
-
-
-class TLSInitiatingInitializer(BaseFeatureInitiatingInitializer):
- """
- TLS stream initializer for the initiating entity.
-
- It is strongly required to include this initializer in the list of
- initializers for an XMPP stream. By default it will try to negotiate TLS.
- An XMPP server may indicate that TLS is required. If TLS is not desired,
- set the C{wanted} attribute to False instead of removing it from the list
- of initializers, so a proper exception L{TLSRequired} can be raised.
-
- @cvar wanted: indicates if TLS negotiation is wanted.
- @type wanted: C{bool}
- """
-
- feature = (NS_XMPP_TLS, 'starttls')
- wanted = True
- _deferred = None
-
- def onProceed(self, obj):
- """
- Proceed with TLS negotiation and reset the XML stream.
- """
-
- self.xmlstream.removeObserver('/failure', self.onFailure)
- ctx = ssl.CertificateOptions()
- self.xmlstream.transport.startTLS(ctx)
- self.xmlstream.reset()
- self.xmlstream.sendHeader()
- self._deferred.callback(Reset)
-
-
- def onFailure(self, obj):
- self.xmlstream.removeObserver('/proceed', self.onProceed)
- self._deferred.errback(TLSFailed())
-
-
- def start(self):
- """
- Start TLS negotiation.
-
- This checks if the receiving entity requires TLS, the SSL library is
- available and uses the C{required} and C{wanted} instance variables to
- determine what to do in the various different cases.
-
- For example, if the SSL library is not available, and wanted and
- required by the user, it raises an exception. However if it is not
- required by both parties, initialization silently succeeds, moving
- on to the next step.
- """
- if self.wanted:
- if ssl is None:
- if self.required:
- return defer.fail(TLSNotSupported())
- else:
- return defer.succeed(None)
- else:
- pass
- elif self.xmlstream.features[self.feature].required:
- return defer.fail(TLSRequired())
- else:
- return defer.succeed(None)
-
- self._deferred = defer.Deferred()
- self.xmlstream.addOnetimeObserver("/proceed", self.onProceed)
- self.xmlstream.addOnetimeObserver("/failure", self.onFailure)
- self.xmlstream.send(domish.Element((NS_XMPP_TLS, "starttls")))
- return self._deferred
-
-
-
-class XmlStream(xmlstream.XmlStream):
- """
- XMPP XML Stream protocol handler.
-
- @ivar version: XML stream version as a tuple (major, minor). Initially,
- this is set to the minimally supported version. Upon
- receiving the stream header of the peer, it is set to the
- minimum of that value and the version on the received
- header.
- @type version: (C{int}, C{int})
- @ivar namespace: default namespace URI for stream
- @type namespace: C{unicode}
- @ivar thisEntity: JID of this entity
- @type thisEntity: L{JID}
- @ivar otherEntity: JID of the peer entity
- @type otherEntity: L{JID}
- @ivar sid: session identifier
- @type sid: C{unicode}
- @ivar initiating: True if this is the initiating stream
- @type initiating: C{bool}
- @ivar features: map of (uri, name) to stream features element received from
- the receiving entity.
- @type features: C{dict} of (C{unicode}, C{unicode}) to L{domish.Element}.
- @ivar prefixes: map of URI to prefixes that are to appear on stream
- header.
- @type prefixes: C{dict} of C{unicode} to C{unicode}
- @ivar initializers: list of stream initializer objects
- @type initializers: C{list} of objects that provide L{IInitializer}
- @ivar authenticator: associated authenticator that uses C{initializers} to
- initialize the XML stream.
- """
-
- version = (1, 0)
- namespace = 'invalid'
- thisEntity = None
- otherEntity = None
- sid = None
- initiating = True
-
- _headerSent = False # True if the stream header has been sent
-
- def __init__(self, authenticator):
- xmlstream.XmlStream.__init__(self)
-
- self.prefixes = {NS_STREAMS: 'stream'}
- self.authenticator = authenticator
- self.initializers = []
- self.features = {}
-
- # Reset the authenticator
- authenticator.associateWithStream(self)
-
-
- def _callLater(self, *args, **kwargs):
- from twisted.internet import reactor
- return reactor.callLater(*args, **kwargs)
-
-
- def reset(self):
- """
- Reset XML Stream.
-
- Resets the XML Parser for incoming data. This is to be used after
- successfully negotiating a new layer, e.g. TLS and SASL. Note that
- registered event observers will continue to be in place.
- """
- self._headerSent = False
- self._initializeStream()
-
-
- def onStreamError(self, errelem):
- """
- Called when a stream:error element has been received.
-
- Dispatches a L{STREAM_ERROR_EVENT} event with the error element to
- allow for cleanup actions and drops the connection.
-
- @param errelem: The received error element.
- @type errelem: L{domish.Element}
- """
- self.dispatch(failure.Failure(error.exceptionFromStreamError(errelem)),
- STREAM_ERROR_EVENT)
- self.transport.loseConnection()
-
-
- def sendHeader(self):
- """
- Send stream header.
- """
- # set up optional extra namespaces
- localPrefixes = {}
- for uri, prefix in self.prefixes.iteritems():
- if uri != NS_STREAMS:
- localPrefixes[prefix] = uri
-
- rootElement = domish.Element((NS_STREAMS, 'stream'), self.namespace,
- localPrefixes=localPrefixes)
-
- if self.otherEntity:
- rootElement['to'] = self.otherEntity.userhost()
-
- if self.thisEntity:
- rootElement['from'] = self.thisEntity.userhost()
-
- if not self.initiating and self.sid:
- rootElement['id'] = self.sid
-
- if self.version >= (1, 0):
- rootElement['version'] = "%d.%d" % self.version
-
- self.send(rootElement.toXml(prefixes=self.prefixes, closeElement=0))
- self._headerSent = True
-
-
- def sendFooter(self):
- """
- Send stream footer.
- """
- self.send('</stream:stream>')
-
-
- def sendStreamError(self, streamError):
- """
- Send stream level error.
-
- If we are the receiving entity, and haven't sent the header yet,
- we sent one first.
-
- After sending the stream error, the stream is closed and the transport
- connection dropped.
-
- @param streamError: stream error instance
- @type streamError: L{error.StreamError}
- """
- if not self._headerSent and not self.initiating:
- self.sendHeader()
-
- if self._headerSent:
- self.send(streamError.getElement())
- self.sendFooter()
-
- self.transport.loseConnection()
-
-
- def send(self, obj):
- """
- Send data over the stream.
-
- This overrides L{xmlstream.Xmlstream.send} to use the default namespace
- of the stream header when serializing L{domish.IElement}s. It is
- assumed that if you pass an object that provides L{domish.IElement},
- it represents a direct child of the stream's root element.
- """
- if domish.IElement.providedBy(obj):
- obj = obj.toXml(prefixes=self.prefixes,
- defaultUri=self.namespace,
- prefixesInScope=self.prefixes.values())
-
- xmlstream.XmlStream.send(self, obj)
-
-
- def connectionMade(self):
- """
- Called when a connection is made.
-
- Notifies the authenticator when a connection has been made.
- """
- xmlstream.XmlStream.connectionMade(self)
- self.authenticator.connectionMade()
-
-
- def onDocumentStart(self, rootElement):
- """
- Called when the stream header has been received.
-
- Extracts the header's C{id} and C{version} attributes from the root
- element. The C{id} attribute is stored in our C{sid} attribute and the
- C{version} attribute is parsed and the minimum of the version we sent
- and the parsed C{version} attribute is stored as a tuple (major, minor)
- in this class' C{version} attribute. If no C{version} attribute was
- present, we assume version 0.0.
-
- If appropriate (we are the initiating stream and the minimum of our and
- the other party's version is at least 1.0), a one-time observer is
- registered for getting the stream features. The registered function is
- C{onFeatures}.
-
- Ultimately, the authenticator's C{streamStarted} method will be called.
-
- @param rootElement: The root element.
- @type rootElement: L{domish.Element}
- """
- xmlstream.XmlStream.onDocumentStart(self, rootElement)
-
- # Setup observer for stream errors
- self.addOnetimeObserver("/error[@xmlns='%s']" % NS_STREAMS,
- self.onStreamError)
-
- self.authenticator.streamStarted(rootElement)
-
-
-
-class XmlStreamFactory(xmlstream.XmlStreamFactory):
- """
- Factory for Jabber XmlStream objects as a reconnecting client.
-
- Note that this differs from L{xmlstream.XmlStreamFactory} in that
- it generates Jabber specific L{XmlStream} instances that have
- authenticators.
- """
-
- protocol = XmlStream
-
- def __init__(self, authenticator):
- xmlstream.XmlStreamFactory.__init__(self, authenticator)
- self.authenticator = authenticator
-
-
-
-class XmlStreamServerFactory(xmlstream.BootstrapMixin,
- protocol.ServerFactory):
- """
- Factory for Jabber XmlStream objects as a server.
-
- @since: 8.2.
- @ivar authenticatorFactory: Factory callable that takes no arguments, to
- create a fresh authenticator to be associated
- with the XmlStream.
- """
-
- protocol = XmlStream
-
- def __init__(self, authenticatorFactory):
- xmlstream.BootstrapMixin.__init__(self)
- self.authenticatorFactory = authenticatorFactory
-
-
- def buildProtocol(self, addr):
- """
- Create an instance of XmlStream.
-
- A new authenticator instance will be created and passed to the new
- XmlStream. Registered bootstrap event observers are installed as well.
- """
- authenticator = self.authenticatorFactory()
- xs = self.protocol(authenticator)
- xs.factory = self
- self.installBootstraps(xs)
- return xs
-
-
-
-class TimeoutError(Exception):
- """
- Exception raised when no IQ response has been received before the
- configured timeout.
- """
-
-
-
-def upgradeWithIQResponseTracker(xs):
- """
- Enhances an XmlStream for iq response tracking.
-
- This makes an L{XmlStream} object provide L{IIQResponseTracker}. When a
- response is an error iq stanza, the deferred has its errback invoked with a
- failure that holds a L{StanzaException<error.StanzaException>} that is
- easier to examine.
- """
- def callback(iq):
- """
- Handle iq response by firing associated deferred.
- """
- if getattr(iq, 'handled', False):
- return
-
- try:
- d = xs.iqDeferreds[iq["id"]]
- except KeyError:
- pass
- else:
- del xs.iqDeferreds[iq["id"]]
- iq.handled = True
- if iq['type'] == 'error':
- d.errback(error.exceptionFromStanza(iq))
- else:
- d.callback(iq)
-
-
- def disconnected(_):
- """
- Make sure deferreds do not linger on after disconnect.
-
- This errbacks all deferreds of iq's for which no response has been
- received with a L{ConnectionLost} failure. Otherwise, the deferreds
- will never be fired.
- """
- iqDeferreds = xs.iqDeferreds
- xs.iqDeferreds = {}
- for d in iqDeferreds.itervalues():
- d.errback(ConnectionLost())
-
- xs.iqDeferreds = {}
- xs.iqDefaultTimeout = getattr(xs, 'iqDefaultTimeout', None)
- xs.addObserver(xmlstream.STREAM_END_EVENT, disconnected)
- xs.addObserver('/iq[@type="result"]', callback)
- xs.addObserver('/iq[@type="error"]', callback)
- directlyProvides(xs, ijabber.IIQResponseTracker)
-
-
-
-class IQ(domish.Element):
- """
- Wrapper for an iq stanza.
-
- Iq stanzas are used for communications with a request-response behaviour.
- Each iq request is associated with an XML stream and has its own unique id
- to be able to track the response.
-
- @ivar timeout: if set, a timeout period after which the deferred returned
- by C{send} will have its errback called with a
- L{TimeoutError} failure.
- @type timeout: C{float}
- """
-
- timeout = None
-
- def __init__(self, xmlstream, stanzaType="set"):
- """
- @type xmlstream: L{xmlstream.XmlStream}
- @param xmlstream: XmlStream to use for transmission of this IQ
-
- @type stanzaType: C{str}
- @param stanzaType: IQ type identifier ('get' or 'set')
- """
- domish.Element.__init__(self, (None, "iq"))
- self.addUniqueId()
- self["type"] = stanzaType
- self._xmlstream = xmlstream
-
-
- def send(self, to=None):
- """
- Send out this iq.
-
- Returns a deferred that is fired when an iq response with the same id
- is received. Result responses will be passed to the deferred callback.
- Error responses will be transformed into a
- L{StanzaError<error.StanzaError>} and result in the errback of the
- deferred being invoked.
-
- @rtype: L{defer.Deferred}
- """
- if to is not None:
- self["to"] = to
-
- if not ijabber.IIQResponseTracker.providedBy(self._xmlstream):
- upgradeWithIQResponseTracker(self._xmlstream)
-
- d = defer.Deferred()
- self._xmlstream.iqDeferreds[self['id']] = d
-
- timeout = self.timeout or self._xmlstream.iqDefaultTimeout
- if timeout is not None:
- def onTimeout():
- del self._xmlstream.iqDeferreds[self['id']]
- d.errback(TimeoutError("IQ timed out"))
-
- call = self._xmlstream._callLater(timeout, onTimeout)
-
- def cancelTimeout(result):
- if call.active():
- call.cancel()
-
- return result
-
- d.addBoth(cancelTimeout)
-
- self._xmlstream.send(self)
- return d
-
-
-
-def toResponse(stanza, stanzaType=None):
- """
- Create a response stanza from another stanza.
-
- This takes the addressing and id attributes from a stanza to create a (new,
- empty) response stanza. The addressing attributes are swapped and the id
- copied. Optionally, the stanza type of the response can be specified.
-
- @param stanza: the original stanza
- @type stanza: L{domish.Element}
- @param stanzaType: optional response stanza type
- @type stanzaType: C{str}
- @return: the response stanza.
- @rtype: L{domish.Element}
- """
-
- toAddr = stanza.getAttribute('from')
- fromAddr = stanza.getAttribute('to')
- stanzaID = stanza.getAttribute('id')
-
- response = domish.Element((None, stanza.name))
- if toAddr:
- response['to'] = toAddr
- if fromAddr:
- response['from'] = fromAddr
- if stanzaID:
- response['id'] = stanzaID
- if stanzaType:
- response['type'] = stanzaType
-
- return response
-
-
-
-class XMPPHandler(object):
- """
- XMPP protocol handler.
-
- Classes derived from this class implement (part of) one or more XMPP
- extension protocols, and are referred to as a subprotocol implementation.
- """
-
- implements(ijabber.IXMPPHandler)
-
- def __init__(self):
- self.parent = None
- self.xmlstream = None
-
-
- def setHandlerParent(self, parent):
- self.parent = parent
- self.parent.addHandler(self)
-
-
- def disownHandlerParent(self, parent):
- self.parent.removeHandler(self)
- self.parent = None
-
-
- def makeConnection(self, xs):
- self.xmlstream = xs
- self.connectionMade()
-
-
- def connectionMade(self):
- """
- Called after a connection has been established.
-
- Can be overridden to perform work before stream initialization.
- """
-
-
- def connectionInitialized(self):
- """
- The XML stream has been initialized.
-
- Can be overridden to perform work after stream initialization, e.g. to
- set up observers and start exchanging XML stanzas.
- """
-
-
- def connectionLost(self, reason):
- """
- The XML stream has been closed.
-
- This method can be extended to inspect the C{reason} argument and
- act on it.
- """
- self.xmlstream = None
-
-
- def send(self, obj):
- """
- Send data over the managed XML stream.
-
- @note: The stream manager maintains a queue for data sent using this
- method when there is no current initialized XML stream. This
- data is then sent as soon as a new stream has been established
- and initialized. Subsequently, L{connectionInitialized} will be
- called again. If this queueing is not desired, use C{send} on
- C{self.xmlstream}.
-
- @param obj: data to be sent over the XML stream. This is usually an
- object providing L{domish.IElement}, or serialized XML. See
- L{xmlstream.XmlStream} for details.
- """
- self.parent.send(obj)
-
-
-
-class XMPPHandlerCollection(object):
- """
- Collection of XMPP subprotocol handlers.
-
- This allows for grouping of subprotocol handlers, but is not an
- L{XMPPHandler} itself, so this is not recursive.
-
- @ivar handlers: List of protocol handlers.
- @type handlers: C{list} of objects providing
- L{IXMPPHandler}
- """
-
- implements(ijabber.IXMPPHandlerCollection)
-
- def __init__(self):
- self.handlers = []
-
-
- def __iter__(self):
- """
- Act as a container for handlers.
- """
- return iter(self.handlers)
-
-
- def addHandler(self, handler):
- """
- Add protocol handler.
-
- Protocol handlers are expected to provide L{ijabber.IXMPPHandler}.
- """
- self.handlers.append(handler)
-
-
- def removeHandler(self, handler):
- """
- Remove protocol handler.
- """
- self.handlers.remove(handler)
-
-
-
-class StreamManager(XMPPHandlerCollection):
- """
- Business logic representing a managed XMPP connection.
-
- This maintains a single XMPP connection and provides facilities for packet
- routing and transmission. Business logic modules are objects providing
- L{ijabber.IXMPPHandler} (like subclasses of L{XMPPHandler}), and added
- using L{addHandler}.
-
- @ivar xmlstream: currently managed XML stream
- @type xmlstream: L{XmlStream}
- @ivar logTraffic: if true, log all traffic.
- @type logTraffic: C{bool}
- @ivar _initialized: Whether the stream represented by L{xmlstream} has
- been initialized. This is used when caching outgoing
- stanzas.
- @type _initialized: C{bool}
- @ivar _packetQueue: internal buffer of unsent data. See L{send} for details.
- @type _packetQueue: C{list}
- """
-
- logTraffic = False
-
- def __init__(self, factory):
- XMPPHandlerCollection.__init__(self)
- self.xmlstream = None
- self._packetQueue = []
- self._initialized = False
-
- factory.addBootstrap(STREAM_CONNECTED_EVENT, self._connected)
- factory.addBootstrap(STREAM_AUTHD_EVENT, self._authd)
- factory.addBootstrap(INIT_FAILED_EVENT, self.initializationFailed)
- factory.addBootstrap(STREAM_END_EVENT, self._disconnected)
- self.factory = factory
-
-
- def addHandler(self, handler):
- """
- Add protocol handler.
-
- When an XML stream has already been established, the handler's
- C{connectionInitialized} will be called to get it up to speed.
- """
- XMPPHandlerCollection.addHandler(self, handler)
-
- # get protocol handler up to speed when a connection has already
- # been established
- if self.xmlstream and self._initialized:
- handler.makeConnection(self.xmlstream)
- handler.connectionInitialized()
-
-
- def _connected(self, xs):
- """
- Called when the transport connection has been established.
-
- Here we optionally set up traffic logging (depending on L{logTraffic})
- and call each handler's C{makeConnection} method with the L{XmlStream}
- instance.
- """
- def logDataIn(buf):
- log.msg("RECV: %r" % buf)
-
- def logDataOut(buf):
- log.msg("SEND: %r" % buf)
-
- if self.logTraffic:
- xs.rawDataInFn = logDataIn
- xs.rawDataOutFn = logDataOut
-
- self.xmlstream = xs
-
- for e in self:
- e.makeConnection(xs)
-
-
- def _authd(self, xs):
- """
- Called when the stream has been initialized.
-
- Send out cached stanzas and call each handler's
- C{connectionInitialized} method.
- """
- # Flush all pending packets
- for p in self._packetQueue:
- xs.send(p)
- self._packetQueue = []
- self._initialized = True
-
- # Notify all child services which implement
- # the IService interface
- for e in self:
- e.connectionInitialized()
-
-
- def initializationFailed(self, reason):
- """
- Called when stream initialization has failed.
-
- Stream initialization has halted, with the reason indicated by
- C{reason}. It may be retried by calling the authenticator's
- C{initializeStream}. See the respective authenticators for details.
-
- @param reason: A failure instance indicating why stream initialization
- failed.
- @type reason: L{failure.Failure}
- """
-
-
- def _disconnected(self, reason):
- """
- Called when the stream has been closed.
-
- From this point on, the manager doesn't interact with the
- L{XmlStream} anymore and notifies each handler that the connection
- was lost by calling its C{connectionLost} method.
- """
- self.xmlstream = None
- self._initialized = False
-
- # Notify all child services which implement
- # the IService interface
- for e in self:
- e.connectionLost(reason)
-
-
- def send(self, obj):
- """
- Send data over the XML stream.
-
- When there is no established XML stream, the data is queued and sent
- out when a new XML stream has been established and initialized.
-
- @param obj: data to be sent over the XML stream. See
- L{xmlstream.XmlStream.send} for details.
- """
- if self._initialized:
- self.xmlstream.send(obj)
- else:
- self._packetQueue.append(obj)
-
-
-
-__all__ = ['Authenticator', 'BaseFeatureInitiatingInitializer',
- 'ConnectAuthenticator', 'FeatureNotAdvertized',
- 'INIT_FAILED_EVENT', 'IQ', 'ListenAuthenticator', 'NS_STREAMS',
- 'NS_XMPP_TLS', 'Reset', 'STREAM_AUTHD_EVENT',
- 'STREAM_CONNECTED_EVENT', 'STREAM_END_EVENT', 'STREAM_ERROR_EVENT',
- 'STREAM_START_EVENT', 'StreamManager', 'TLSError', 'TLSFailed',
- 'TLSInitiatingInitializer', 'TLSNotSupported', 'TLSRequired',
- 'TimeoutError', 'XMPPHandler', 'XMPPHandlerCollection', 'XmlStream',
- 'XmlStreamFactory', 'XmlStreamServerFactory', 'hashPassword',
- 'toResponse', 'upgradeWithIQResponseTracker']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmpp_stringprep.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmpp_stringprep.py
deleted file mode 100755
index 75274121..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/jabber/xmpp_stringprep.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_jabberxmppstringprep -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-import sys, warnings
-from zope.interface import Interface, implements
-
-if sys.version_info < (2,3,2):
- import re
-
- class IDNA:
- dots = re.compile(u"[\u002E\u3002\uFF0E\uFF61]")
- def nameprep(self, label):
- return label.lower()
-
- idna = IDNA()
-
- crippled = True
-
- warnings.warn("Accented and non-Western Jabber IDs will not be properly "
- "case-folded with this version of Python, resulting in "
- "incorrect protocol-level behavior. It is strongly "
- "recommended you upgrade to Python 2.3.2 or newer if you "
- "intend to use Twisted's Jabber support.")
-
-else:
- import stringprep
- # We require Unicode version 3.2. Python 2.5 and later provide this as
- # a separate object. Before that the unicodedata module uses 3.2.
- try:
- from unicodedata import ucd_3_2_0 as unicodedata
- except:
- import unicodedata
- from encodings import idna
-
- crippled = False
-
-del sys, warnings
-
-class ILookupTable(Interface):
- """ Interface for character lookup classes. """
-
- def lookup(c):
- """ Return whether character is in this table. """
-
-class IMappingTable(Interface):
- """ Interface for character mapping classes. """
-
- def map(c):
- """ Return mapping for character. """
-
-class LookupTableFromFunction:
-
- implements(ILookupTable)
-
- def __init__(self, in_table_function):
- self.lookup = in_table_function
-
-class LookupTable:
-
- implements(ILookupTable)
-
- def __init__(self, table):
- self._table = table
-
- def lookup(self, c):
- return c in self._table
-
-class MappingTableFromFunction:
-
- implements(IMappingTable)
-
- def __init__(self, map_table_function):
- self.map = map_table_function
-
-class EmptyMappingTable:
-
- implements(IMappingTable)
-
- def __init__(self, in_table_function):
- self._in_table_function = in_table_function
-
- def map(self, c):
- if self._in_table_function(c):
- return None
- else:
- return c
-
-class Profile:
- def __init__(self, mappings=[], normalize=True, prohibiteds=[],
- check_unassigneds=True, check_bidi=True):
- self.mappings = mappings
- self.normalize = normalize
- self.prohibiteds = prohibiteds
- self.do_check_unassigneds = check_unassigneds
- self.do_check_bidi = check_bidi
-
- def prepare(self, string):
- result = self.map(string)
- if self.normalize:
- result = unicodedata.normalize("NFKC", result)
- self.check_prohibiteds(result)
- if self.do_check_unassigneds:
- self.check_unassigneds(result)
- if self.do_check_bidi:
- self.check_bidirectionals(result)
- return result
-
- def map(self, string):
- result = []
-
- for c in string:
- result_c = c
-
- for mapping in self.mappings:
- result_c = mapping.map(c)
- if result_c != c:
- break
-
- if result_c is not None:
- result.append(result_c)
-
- return u"".join(result)
-
- def check_prohibiteds(self, string):
- for c in string:
- for table in self.prohibiteds:
- if table.lookup(c):
- raise UnicodeError, "Invalid character %s" % repr(c)
-
- def check_unassigneds(self, string):
- for c in string:
- if stringprep.in_table_a1(c):
- raise UnicodeError, "Unassigned code point %s" % repr(c)
-
- def check_bidirectionals(self, string):
- found_LCat = False
- found_RandALCat = False
-
- for c in string:
- if stringprep.in_table_d1(c):
- found_RandALCat = True
- if stringprep.in_table_d2(c):
- found_LCat = True
-
- if found_LCat and found_RandALCat:
- raise UnicodeError, "Violation of BIDI Requirement 2"
-
- if found_RandALCat and not (stringprep.in_table_d1(string[0]) and
- stringprep.in_table_d1(string[-1])):
- raise UnicodeError, "Violation of BIDI Requirement 3"
-
-
-class NamePrep:
- """ Implements preparation of internationalized domain names.
-
- This class implements preparing internationalized domain names using the
- rules defined in RFC 3491, section 4 (Conversion operations).
-
- We do not perform step 4 since we deal with unicode representations of
- domain names and do not convert from or to ASCII representations using
- punycode encoding. When such a conversion is needed, the C{idna} standard
- library provides the C{ToUnicode()} and C{ToASCII()} functions. Note that
- C{idna} itself assumes UseSTD3ASCIIRules to be false.
-
- The following steps are performed by C{prepare()}:
-
- - Split the domain name in labels at the dots (RFC 3490, 3.1)
- - Apply nameprep proper on each label (RFC 3491)
- - Enforce the restrictions on ASCII characters in host names by
- assuming STD3ASCIIRules to be true. (STD 3)
- - Rejoin the labels using the label separator U+002E (full stop).
-
- """
-
- # Prohibited characters.
- prohibiteds = [unichr(n) for n in range(0x00, 0x2c + 1) +
- range(0x2e, 0x2f + 1) +
- range(0x3a, 0x40 + 1) +
- range(0x5b, 0x60 + 1) +
- range(0x7b, 0x7f + 1) ]
-
- def prepare(self, string):
- result = []
-
- labels = idna.dots.split(string)
-
- if labels and len(labels[-1]) == 0:
- trailing_dot = '.'
- del labels[-1]
- else:
- trailing_dot = ''
-
- for label in labels:
- result.append(self.nameprep(label))
-
- return ".".join(result) + trailing_dot
-
- def check_prohibiteds(self, string):
- for c in string:
- if c in self.prohibiteds:
- raise UnicodeError, "Invalid character %s" % repr(c)
-
- def nameprep(self, label):
- label = idna.nameprep(label)
- self.check_prohibiteds(label)
- if label[0] == '-':
- raise UnicodeError, "Invalid leading hyphen-minus"
- if label[-1] == '-':
- raise UnicodeError, "Invalid trailing hyphen-minus"
- return label
-
-if crippled:
- case_map = MappingTableFromFunction(lambda c: c.lower())
- nodeprep = Profile(mappings=[case_map],
- normalize=False,
- prohibiteds=[LookupTable([u' ', u'"', u'&', u"'", u'/',
- u':', u'<', u'>', u'@'])],
- check_unassigneds=False,
- check_bidi=False)
-
- resourceprep = Profile(normalize=False,
- check_unassigneds=False,
- check_bidi=False)
-
-else:
- C_11 = LookupTableFromFunction(stringprep.in_table_c11)
- C_12 = LookupTableFromFunction(stringprep.in_table_c12)
- C_21 = LookupTableFromFunction(stringprep.in_table_c21)
- C_22 = LookupTableFromFunction(stringprep.in_table_c22)
- C_3 = LookupTableFromFunction(stringprep.in_table_c3)
- C_4 = LookupTableFromFunction(stringprep.in_table_c4)
- C_5 = LookupTableFromFunction(stringprep.in_table_c5)
- C_6 = LookupTableFromFunction(stringprep.in_table_c6)
- C_7 = LookupTableFromFunction(stringprep.in_table_c7)
- C_8 = LookupTableFromFunction(stringprep.in_table_c8)
- C_9 = LookupTableFromFunction(stringprep.in_table_c9)
-
- B_1 = EmptyMappingTable(stringprep.in_table_b1)
- B_2 = MappingTableFromFunction(stringprep.map_table_b2)
-
- nodeprep = Profile(mappings=[B_1, B_2],
- prohibiteds=[C_11, C_12, C_21, C_22,
- C_3, C_4, C_5, C_6, C_7, C_8, C_9,
- LookupTable([u'"', u'&', u"'", u'/',
- u':', u'<', u'>', u'@'])])
-
- resourceprep = Profile(mappings=[B_1,],
- prohibiteds=[C_12, C_21, C_22,
- C_3, C_4, C_5, C_6, C_7, C_8, C_9])
-
-nameprep = NamePrep()
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/msn.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/msn.py
deleted file mode 100755
index 79c0fa1b..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/msn.py
+++ /dev/null
@@ -1,2479 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-MSNP8 Protocol (client only) - semi-experimental
-
-This module provides support for clients using the MSN Protocol (MSNP8).
-There are basically 3 servers involved in any MSN session:
-
-I{Dispatch server}
-
-The DispatchClient class handles connections to the
-dispatch server, which basically delegates users to a
-suitable notification server.
-
-You will want to subclass this and handle the gotNotificationReferral
-method appropriately.
-
-I{Notification Server}
-
-The NotificationClient class handles connections to the
-notification server, which acts as a session server
-(state updates, message negotiation etc...)
-
-I{Switcboard Server}
-
-The SwitchboardClient handles connections to switchboard
-servers which are used to conduct conversations with other users.
-
-There are also two classes (FileSend and FileReceive) used
-for file transfers.
-
-Clients handle events in two ways.
-
- - each client request requiring a response will return a Deferred,
- the callback for same will be fired when the server sends the
- required response
- - Events which are not in response to any client request have
- respective methods which should be overridden and handled in
- an adequate manner
-
-Most client request callbacks require more than one argument,
-and since Deferreds can only pass the callback one result,
-most of the time the callback argument will be a tuple of
-values (documented in the respective request method).
-To make reading/writing code easier, callbacks can be defined in
-a number of ways to handle this 'cleanly'. One way would be to
-define methods like: def callBack(self, (arg1, arg2, arg)): ...
-another way would be to do something like:
-d.addCallback(lambda result: myCallback(*result)).
-
-If the server sends an error response to a client request,
-the errback of the corresponding Deferred will be called,
-the argument being the corresponding error code.
-
-B{NOTE}:
-Due to the lack of an official spec for MSNP8, extra checking
-than may be deemed necessary often takes place considering the
-server is never 'wrong'. Thus, if gotBadLine (in any of the 3
-main clients) is called, or an MSNProtocolError is raised, it's
-probably a good idea to submit a bug report. ;)
-Use of this module requires that PyOpenSSL is installed.
-
-TODO
-====
-- check message hooks with invalid x-msgsinvite messages.
-- font handling
-- switchboard factory
-
-@author: Sam Jordan
-"""
-
-import types, operator, os
-from random import randint
-from urllib import quote, unquote
-
-from twisted.python import failure, log
-from twisted.python.hashlib import md5
-from twisted.internet import reactor
-from twisted.internet.defer import Deferred, execute
-from twisted.internet.protocol import ClientFactory
-try:
- from twisted.internet.ssl import ClientContextFactory
-except ImportError:
- ClientContextFactory = None
-from twisted.protocols.basic import LineReceiver
-from twisted.web.http import HTTPClient
-
-
-MSN_PROTOCOL_VERSION = "MSNP8 CVR0" # protocol version
-MSN_PORT = 1863 # default dispatch server port
-MSN_MAX_MESSAGE = 1664 # max message length
-MSN_CHALLENGE_STR = "Q1P7W2E4J9R8U3S5" # used for server challenges
-MSN_CVR_STR = "0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS" # :(
-
-# auth constants
-LOGIN_SUCCESS = 1
-LOGIN_FAILURE = 2
-LOGIN_REDIRECT = 3
-
-# list constants
-FORWARD_LIST = 1
-ALLOW_LIST = 2
-BLOCK_LIST = 4
-REVERSE_LIST = 8
-
-# phone constants
-HOME_PHONE = "PHH"
-WORK_PHONE = "PHW"
-MOBILE_PHONE = "PHM"
-HAS_PAGER = "MOB"
-
-# status constants
-STATUS_ONLINE = 'NLN'
-STATUS_OFFLINE = 'FLN'
-STATUS_HIDDEN = 'HDN'
-STATUS_IDLE = 'IDL'
-STATUS_AWAY = 'AWY'
-STATUS_BUSY = 'BSY'
-STATUS_BRB = 'BRB'
-STATUS_PHONE = 'PHN'
-STATUS_LUNCH = 'LUN'
-
-CR = "\r"
-LF = "\n"
-
-
-class SSLRequired(Exception):
- """
- This exception is raised when it is necessary to talk to a passport server
- using SSL, but the necessary SSL dependencies are unavailable.
-
- @since: 11.0
- """
-
-
-
-def checkParamLen(num, expected, cmd, error=None):
- if error == None:
- error = "Invalid Number of Parameters for %s" % cmd
- if num != expected:
- raise MSNProtocolError, error
-
-def _parseHeader(h, v):
- """
- Split a certin number of known
- header values with the format:
- field1=val,field2=val,field3=val into
- a dict mapping fields to values.
- @param h: the header's key
- @param v: the header's value as a string
- """
-
- if h in ('passporturls','authentication-info','www-authenticate'):
- v = v.replace('Passport1.4','').lstrip()
- fields = {}
- for fieldPair in v.split(','):
- try:
- field,value = fieldPair.split('=',1)
- fields[field.lower()] = value
- except ValueError:
- fields[field.lower()] = ''
- return fields
- else:
- return v
-
-def _parsePrimitiveHost(host):
- # Ho Ho Ho
- h,p = host.replace('https://','').split('/',1)
- p = '/' + p
- return h,p
-
-
-def _login(userHandle, passwd, nexusServer, cached=0, authData=''):
- """
- This function is used internally and should not ever be called
- directly.
-
- @raise SSLRequired: If there is no SSL support available.
- """
- if ClientContextFactory is None:
- raise SSLRequired(
- 'Connecting to the Passport server requires SSL, but SSL is '
- 'unavailable.')
-
- cb = Deferred()
- def _cb(server, auth):
- loginFac = ClientFactory()
- loginFac.protocol = lambda : PassportLogin(cb, userHandle, passwd, server, auth)
- reactor.connectSSL(_parsePrimitiveHost(server)[0], 443, loginFac, ClientContextFactory())
-
- if cached:
- _cb(nexusServer, authData)
- else:
- fac = ClientFactory()
- d = Deferred()
- d.addCallbacks(_cb, callbackArgs=(authData,))
- d.addErrback(lambda f: cb.errback(f))
- fac.protocol = lambda : PassportNexus(d, nexusServer)
- reactor.connectSSL(_parsePrimitiveHost(nexusServer)[0], 443, fac, ClientContextFactory())
- return cb
-
-
-class PassportNexus(HTTPClient):
-
- """
- Used to obtain the URL of a valid passport
- login HTTPS server.
-
- This class is used internally and should
- not be instantiated directly -- that is,
- The passport logging in process is handled
- transparantly by NotificationClient.
- """
-
- def __init__(self, deferred, host):
- self.deferred = deferred
- self.host, self.path = _parsePrimitiveHost(host)
-
- def connectionMade(self):
- HTTPClient.connectionMade(self)
- self.sendCommand('GET', self.path)
- self.sendHeader('Host', self.host)
- self.endHeaders()
- self.headers = {}
-
- def handleHeader(self, header, value):
- h = header.lower()
- self.headers[h] = _parseHeader(h, value)
-
- def handleEndHeaders(self):
- if self.connected:
- self.transport.loseConnection()
- if 'passporturls' not in self.headers or 'dalogin' not in self.headers['passporturls']:
- self.deferred.errback(failure.Failure(failure.DefaultException("Invalid Nexus Reply")))
- self.deferred.callback('https://' + self.headers['passporturls']['dalogin'])
-
- def handleResponse(self, r):
- pass
-
-class PassportLogin(HTTPClient):
- """
- This class is used internally to obtain
- a login ticket from a passport HTTPS
- server -- it should not be used directly.
- """
-
- _finished = 0
-
- def __init__(self, deferred, userHandle, passwd, host, authData):
- self.deferred = deferred
- self.userHandle = userHandle
- self.passwd = passwd
- self.authData = authData
- self.host, self.path = _parsePrimitiveHost(host)
-
- def connectionMade(self):
- self.sendCommand('GET', self.path)
- self.sendHeader('Authorization', 'Passport1.4 OrgVerb=GET,OrgURL=http://messenger.msn.com,' +
- 'sign-in=%s,pwd=%s,%s' % (quote(self.userHandle), self.passwd,self.authData))
- self.sendHeader('Host', self.host)
- self.endHeaders()
- self.headers = {}
-
- def handleHeader(self, header, value):
- h = header.lower()
- self.headers[h] = _parseHeader(h, value)
-
- def handleEndHeaders(self):
- if self._finished:
- return
- self._finished = 1 # I think we need this because of HTTPClient
- if self.connected:
- self.transport.loseConnection()
- authHeader = 'authentication-info'
- _interHeader = 'www-authenticate'
- if _interHeader in self.headers:
- authHeader = _interHeader
- try:
- info = self.headers[authHeader]
- status = info['da-status']
- handler = getattr(self, 'login_%s' % (status,), None)
- if handler:
- handler(info)
- else:
- raise Exception()
- except Exception, e:
- self.deferred.errback(failure.Failure(e))
-
- def handleResponse(self, r):
- pass
-
- def login_success(self, info):
- ticket = info['from-pp']
- ticket = ticket[1:len(ticket)-1]
- self.deferred.callback((LOGIN_SUCCESS, ticket))
-
- def login_failed(self, info):
- self.deferred.callback((LOGIN_FAILURE, unquote(info['cbtxt'])))
-
- def login_redir(self, info):
- self.deferred.callback((LOGIN_REDIRECT, self.headers['location'], self.authData))
-
-
-class MSNProtocolError(Exception):
- """
- This Exception is basically used for debugging
- purposes, as the official MSN server should never
- send anything _wrong_ and nobody in their right
- mind would run their B{own} MSN server.
- If it is raised by default command handlers
- (handle_BLAH) the error will be logged.
- """
- pass
-
-
-class MSNCommandFailed(Exception):
- """
- The server said that the command failed.
- """
-
- def __init__(self, errorCode):
- self.errorCode = errorCode
-
- def __str__(self):
- return ("Command failed: %s (error code %d)"
- % (errorCodes[self.errorCode], self.errorCode))
-
-
-class MSNMessage:
- """
- I am the class used to represent an 'instant' message.
-
- @ivar userHandle: The user handle (passport) of the sender
- (this is only used when receiving a message)
- @ivar screenName: The screen name of the sender (this is only used
- when receiving a message)
- @ivar message: The message
- @ivar headers: The message headers
- @type headers: dict
- @ivar length: The message length (including headers and line endings)
- @ivar ack: This variable is used to tell the server how to respond
- once the message has been sent. If set to MESSAGE_ACK
- (default) the server will respond with an ACK upon receiving
- the message, if set to MESSAGE_NACK the server will respond
- with a NACK upon failure to receive the message.
- If set to MESSAGE_ACK_NONE the server will do nothing.
- This is relevant for the return value of
- SwitchboardClient.sendMessage (which will return
- a Deferred if ack is set to either MESSAGE_ACK or MESSAGE_NACK
- and will fire when the respective ACK or NACK is received).
- If set to MESSAGE_ACK_NONE sendMessage will return None.
- """
- MESSAGE_ACK = 'A'
- MESSAGE_NACK = 'N'
- MESSAGE_ACK_NONE = 'U'
-
- ack = MESSAGE_ACK
-
- def __init__(self, length=0, userHandle="", screenName="", message=""):
- self.userHandle = userHandle
- self.screenName = screenName
- self.message = message
- self.headers = {'MIME-Version' : '1.0', 'Content-Type' : 'text/plain'}
- self.length = length
- self.readPos = 0
-
- def _calcMessageLen(self):
- """
- used to calculte the number to send
- as the message length when sending a message.
- """
- return reduce(operator.add, [len(x[0]) + len(x[1]) + 4 for x in self.headers.items()]) + len(self.message) + 2
-
- def setHeader(self, header, value):
- """ set the desired header """
- self.headers[header] = value
-
- def getHeader(self, header):
- """
- get the desired header value
- @raise KeyError: if no such header exists.
- """
- return self.headers[header]
-
- def hasHeader(self, header):
- """ check to see if the desired header exists """
- return header in self.headers
-
- def getMessage(self):
- """ return the message - not including headers """
- return self.message
-
- def setMessage(self, message):
- """ set the message text """
- self.message = message
-
-class MSNContact:
-
- """
- This class represents a contact (user).
-
- @ivar userHandle: The contact's user handle (passport).
- @ivar screenName: The contact's screen name.
- @ivar groups: A list of all the group IDs which this
- contact belongs to.
- @ivar lists: An integer representing the sum of all lists
- that this contact belongs to.
- @ivar status: The contact's status code.
- @type status: str if contact's status is known, None otherwise.
-
- @ivar homePhone: The contact's home phone number.
- @type homePhone: str if known, otherwise None.
- @ivar workPhone: The contact's work phone number.
- @type workPhone: str if known, otherwise None.
- @ivar mobilePhone: The contact's mobile phone number.
- @type mobilePhone: str if known, otherwise None.
- @ivar hasPager: Whether or not this user has a mobile pager
- (true=yes, false=no)
- """
-
- def __init__(self, userHandle="", screenName="", lists=0, groups=[], status=None):
- self.userHandle = userHandle
- self.screenName = screenName
- self.lists = lists
- self.groups = [] # if applicable
- self.status = status # current status
-
- # phone details
- self.homePhone = None
- self.workPhone = None
- self.mobilePhone = None
- self.hasPager = None
-
- def setPhone(self, phoneType, value):
- """
- set phone numbers/values for this specific user.
- for phoneType check the *_PHONE constants and HAS_PAGER
- """
-
- t = phoneType.upper()
- if t == HOME_PHONE:
- self.homePhone = value
- elif t == WORK_PHONE:
- self.workPhone = value
- elif t == MOBILE_PHONE:
- self.mobilePhone = value
- elif t == HAS_PAGER:
- self.hasPager = value
- else:
- raise ValueError, "Invalid Phone Type"
-
- def addToList(self, listType):
- """
- Update the lists attribute to
- reflect being part of the
- given list.
- """
- self.lists |= listType
-
- def removeFromList(self, listType):
- """
- Update the lists attribute to
- reflect being removed from the
- given list.
- """
- self.lists ^= listType
-
-class MSNContactList:
- """
- This class represents a basic MSN contact list.
-
- @ivar contacts: All contacts on my various lists
- @type contacts: dict (mapping user handles to MSNContact objects)
- @ivar version: The current contact list version (used for list syncing)
- @ivar groups: a mapping of group ids to group names
- (groups can only exist on the forward list)
- @type groups: dict
-
- B{Note}:
- This is used only for storage and doesn't effect the
- server's contact list.
- """
-
- def __init__(self):
- self.contacts = {}
- self.version = 0
- self.groups = {}
- self.autoAdd = 0
- self.privacy = 0
-
- def _getContactsFromList(self, listType):
- """
- Obtain all contacts which belong
- to the given list type.
- """
- return dict([(uH,obj) for uH,obj in self.contacts.items() if obj.lists & listType])
-
- def addContact(self, contact):
- """
- Add a contact
- """
- self.contacts[contact.userHandle] = contact
-
- def remContact(self, userHandle):
- """
- Remove a contact
- """
- try:
- del self.contacts[userHandle]
- except KeyError:
- pass
-
- def getContact(self, userHandle):
- """
- Obtain the MSNContact object
- associated with the given
- userHandle.
- @return: the MSNContact object if
- the user exists, or None.
- """
- try:
- return self.contacts[userHandle]
- except KeyError:
- return None
-
- def getBlockedContacts(self):
- """
- Obtain all the contacts on my block list
- """
- return self._getContactsFromList(BLOCK_LIST)
-
- def getAuthorizedContacts(self):
- """
- Obtain all the contacts on my auth list.
- (These are contacts which I have verified
- can view my state changes).
- """
- return self._getContactsFromList(ALLOW_LIST)
-
- def getReverseContacts(self):
- """
- Get all contacts on my reverse list.
- (These are contacts which have added me
- to their forward list).
- """
- return self._getContactsFromList(REVERSE_LIST)
-
- def getContacts(self):
- """
- Get all contacts on my forward list.
- (These are the contacts which I have added
- to my list).
- """
- return self._getContactsFromList(FORWARD_LIST)
-
- def setGroup(self, id, name):
- """
- Keep a mapping from the given id
- to the given name.
- """
- self.groups[id] = name
-
- def remGroup(self, id):
- """
- Removed the stored group
- mapping for the given id.
- """
- try:
- del self.groups[id]
- except KeyError:
- pass
- for c in self.contacts:
- if id in c.groups:
- c.groups.remove(id)
-
-
-class MSNEventBase(LineReceiver):
- """
- This class provides support for handling / dispatching events and is the
- base class of the three main client protocols (DispatchClient,
- NotificationClient, SwitchboardClient)
- """
-
- def __init__(self):
- self.ids = {} # mapping of ids to Deferreds
- self.currentID = 0
- self.connected = 0
- self.setLineMode()
- self.currentMessage = None
-
- def connectionLost(self, reason):
- self.ids = {}
- self.connected = 0
-
- def connectionMade(self):
- self.connected = 1
-
- def _fireCallback(self, id, *args):
- """
- Fire the callback for the given id
- if one exists and return 1, else return false
- """
- if id in self.ids:
- self.ids[id][0].callback(args)
- del self.ids[id]
- return 1
- return 0
-
- def _nextTransactionID(self):
- """ return a usable transaction ID """
- self.currentID += 1
- if self.currentID > 1000:
- self.currentID = 1
- return self.currentID
-
- def _createIDMapping(self, data=None):
- """
- return a unique transaction ID that is mapped internally to a
- deferred .. also store arbitrary data if it is needed
- """
- id = self._nextTransactionID()
- d = Deferred()
- self.ids[id] = (d, data)
- return (id, d)
-
- def checkMessage(self, message):
- """
- process received messages to check for file invitations and
- typing notifications and other control type messages
- """
- raise NotImplementedError
-
- def lineReceived(self, line):
- if self.currentMessage:
- self.currentMessage.readPos += len(line+CR+LF)
- if line == "":
- self.setRawMode()
- if self.currentMessage.readPos == self.currentMessage.length:
- self.rawDataReceived("") # :(
- return
- try:
- header, value = line.split(':')
- except ValueError:
- raise MSNProtocolError, "Invalid Message Header"
- self.currentMessage.setHeader(header, unquote(value).lstrip())
- return
- try:
- cmd, params = line.split(' ', 1)
- except ValueError:
- raise MSNProtocolError, "Invalid Message, %s" % repr(line)
-
- if len(cmd) != 3:
- raise MSNProtocolError, "Invalid Command, %s" % repr(cmd)
- if cmd.isdigit():
- errorCode = int(cmd)
- id = int(params.split()[0])
- if id in self.ids:
- self.ids[id][0].errback(MSNCommandFailed(errorCode))
- del self.ids[id]
- return
- else: # we received an error which doesn't map to a sent command
- self.gotError(errorCode)
- return
-
- handler = getattr(self, "handle_%s" % cmd.upper(), None)
- if handler:
- try:
- handler(params.split())
- except MSNProtocolError, why:
- self.gotBadLine(line, why)
- else:
- self.handle_UNKNOWN(cmd, params.split())
-
- def rawDataReceived(self, data):
- extra = ""
- self.currentMessage.readPos += len(data)
- diff = self.currentMessage.readPos - self.currentMessage.length
- if diff > 0:
- self.currentMessage.message += data[:-diff]
- extra = data[-diff:]
- elif diff == 0:
- self.currentMessage.message += data
- else:
- self.currentMessage += data
- return
- del self.currentMessage.readPos
- m = self.currentMessage
- self.currentMessage = None
- self.setLineMode(extra)
- if not self.checkMessage(m):
- return
- self.gotMessage(m)
-
- ### protocol command handlers - no need to override these.
-
- def handle_MSG(self, params):
- checkParamLen(len(params), 3, 'MSG')
- try:
- messageLen = int(params[2])
- except ValueError:
- raise MSNProtocolError, "Invalid Parameter for MSG length argument"
- self.currentMessage = MSNMessage(length=messageLen, userHandle=params[0], screenName=unquote(params[1]))
-
- def handle_UNKNOWN(self, cmd, params):
- """ implement me in subclasses if you want to handle unknown events """
- log.msg("Received unknown command (%s), params: %s" % (cmd, params))
-
- ### callbacks
-
- def gotMessage(self, message):
- """
- called when we receive a message - override in notification
- and switchboard clients
- """
- raise NotImplementedError
-
- def gotBadLine(self, line, why):
- """ called when a handler notifies me that this line is broken """
- log.msg('Error in line: %s (%s)' % (line, why))
-
- def gotError(self, errorCode):
- """
- called when the server sends an error which is not in
- response to a sent command (ie. it has no matching transaction ID)
- """
- log.msg('Error %s' % (errorCodes[errorCode]))
-
-
-
-class DispatchClient(MSNEventBase):
- """
- This class provides support for clients connecting to the dispatch server
- @ivar userHandle: your user handle (passport) needed before connecting.
- """
-
- # eventually this may become an attribute of the
- # factory.
- userHandle = ""
-
- def connectionMade(self):
- MSNEventBase.connectionMade(self)
- self.sendLine('VER %s %s' % (self._nextTransactionID(), MSN_PROTOCOL_VERSION))
-
- ### protocol command handlers ( there is no need to override these )
-
- def handle_VER(self, params):
- id = self._nextTransactionID()
- self.sendLine("CVR %s %s %s" % (id, MSN_CVR_STR, self.userHandle))
-
- def handle_CVR(self, params):
- self.sendLine("USR %s TWN I %s" % (self._nextTransactionID(), self.userHandle))
-
- def handle_XFR(self, params):
- if len(params) < 4:
- raise MSNProtocolError, "Invalid number of parameters for XFR"
- id, refType, addr = params[:3]
- # was addr a host:port pair?
- try:
- host, port = addr.split(':')
- except ValueError:
- host = addr
- port = MSN_PORT
- if refType == "NS":
- self.gotNotificationReferral(host, int(port))
-
- ### callbacks
-
- def gotNotificationReferral(self, host, port):
- """
- called when we get a referral to the notification server.
-
- @param host: the notification server's hostname
- @param port: the port to connect to
- """
- pass
-
-
-class NotificationClient(MSNEventBase):
- """
- This class provides support for clients connecting
- to the notification server.
- """
-
- factory = None # sssh pychecker
-
- def __init__(self, currentID=0):
- MSNEventBase.__init__(self)
- self.currentID = currentID
- self._state = ['DISCONNECTED', {}]
-
- def _setState(self, state):
- self._state[0] = state
-
- def _getState(self):
- return self._state[0]
-
- def _getStateData(self, key):
- return self._state[1][key]
-
- def _setStateData(self, key, value):
- self._state[1][key] = value
-
- def _remStateData(self, *args):
- for key in args:
- del self._state[1][key]
-
- def connectionMade(self):
- MSNEventBase.connectionMade(self)
- self._setState('CONNECTED')
- self.sendLine("VER %s %s" % (self._nextTransactionID(), MSN_PROTOCOL_VERSION))
-
- def connectionLost(self, reason):
- self._setState('DISCONNECTED')
- self._state[1] = {}
- MSNEventBase.connectionLost(self, reason)
-
- def checkMessage(self, message):
- """ hook used for detecting specific notification messages """
- cTypes = [s.lstrip() for s in message.getHeader('Content-Type').split(';')]
- if 'text/x-msmsgsprofile' in cTypes:
- self.gotProfile(message)
- return 0
- return 1
-
- ### protocol command handlers - no need to override these
-
- def handle_VER(self, params):
- id = self._nextTransactionID()
- self.sendLine("CVR %s %s %s" % (id, MSN_CVR_STR, self.factory.userHandle))
-
- def handle_CVR(self, params):
- self.sendLine("USR %s TWN I %s" % (self._nextTransactionID(), self.factory.userHandle))
-
- def handle_USR(self, params):
- if len(params) != 4 and len(params) != 6:
- raise MSNProtocolError, "Invalid Number of Parameters for USR"
-
- mechanism = params[1]
- if mechanism == "OK":
- self.loggedIn(params[2], unquote(params[3]), int(params[4]))
- elif params[2].upper() == "S":
- # we need to obtain auth from a passport server
- f = self.factory
- d = execute(
- _login, f.userHandle, f.password, f.passportServer,
- authData=params[3])
- d.addCallback(self._passportLogin)
- d.addErrback(self._passportError)
-
- def _passportLogin(self, result):
- if result[0] == LOGIN_REDIRECT:
- d = _login(self.factory.userHandle, self.factory.password,
- result[1], cached=1, authData=result[2])
- d.addCallback(self._passportLogin)
- d.addErrback(self._passportError)
- elif result[0] == LOGIN_SUCCESS:
- self.sendLine("USR %s TWN S %s" % (self._nextTransactionID(), result[1]))
- elif result[0] == LOGIN_FAILURE:
- self.loginFailure(result[1])
-
-
- def _passportError(self, failure):
- """
- Handle a problem logging in via the Passport server, passing on the
- error as a string message to the C{loginFailure} callback.
- """
- if failure.check(SSLRequired):
- failure = failure.getErrorMessage()
- self.loginFailure("Exception while authenticating: %s" % failure)
-
-
- def handle_CHG(self, params):
- checkParamLen(len(params), 3, 'CHG')
- id = int(params[0])
- if not self._fireCallback(id, params[1]):
- self.statusChanged(params[1])
-
- def handle_ILN(self, params):
- checkParamLen(len(params), 5, 'ILN')
- self.gotContactStatus(params[1], params[2], unquote(params[3]))
-
- def handle_CHL(self, params):
- checkParamLen(len(params), 2, 'CHL')
- self.sendLine("QRY %s msmsgs@msnmsgr.com 32" % self._nextTransactionID())
- self.transport.write(md5(params[1] + MSN_CHALLENGE_STR).hexdigest())
-
- def handle_QRY(self, params):
- pass
-
- def handle_NLN(self, params):
- checkParamLen(len(params), 4, 'NLN')
- self.contactStatusChanged(params[0], params[1], unquote(params[2]))
-
- def handle_FLN(self, params):
- checkParamLen(len(params), 1, 'FLN')
- self.contactOffline(params[0])
-
- def handle_LST(self, params):
- # support no longer exists for manually
- # requesting lists - why do I feel cleaner now?
- if self._getState() != 'SYNC':
- return
- contact = MSNContact(userHandle=params[0], screenName=unquote(params[1]),
- lists=int(params[2]))
- if contact.lists & FORWARD_LIST:
- contact.groups.extend(map(int, params[3].split(',')))
- self._getStateData('list').addContact(contact)
- self._setStateData('last_contact', contact)
- sofar = self._getStateData('lst_sofar') + 1
- if sofar == self._getStateData('lst_reply'):
- # this is the best place to determine that
- # a syn realy has finished - msn _may_ send
- # BPR information for the last contact
- # which is unfortunate because it means
- # that the real end of a syn is non-deterministic.
- # to handle this we'll keep 'last_contact' hanging
- # around in the state data and update it if we need
- # to later.
- self._setState('SESSION')
- contacts = self._getStateData('list')
- phone = self._getStateData('phone')
- id = self._getStateData('synid')
- self._remStateData('lst_reply', 'lsg_reply', 'lst_sofar', 'phone', 'synid', 'list')
- self._fireCallback(id, contacts, phone)
- else:
- self._setStateData('lst_sofar',sofar)
-
- def handle_BLP(self, params):
- # check to see if this is in response to a SYN
- if self._getState() == 'SYNC':
- self._getStateData('list').privacy = listCodeToID[params[0].lower()]
- else:
- id = int(params[0])
- self._fireCallback(id, int(params[1]), listCodeToID[params[2].lower()])
-
- def handle_GTC(self, params):
- # check to see if this is in response to a SYN
- if self._getState() == 'SYNC':
- if params[0].lower() == "a":
- self._getStateData('list').autoAdd = 0
- elif params[0].lower() == "n":
- self._getStateData('list').autoAdd = 1
- else:
- raise MSNProtocolError, "Invalid Paramater for GTC" # debug
- else:
- id = int(params[0])
- if params[1].lower() == "a":
- self._fireCallback(id, 0)
- elif params[1].lower() == "n":
- self._fireCallback(id, 1)
- else:
- raise MSNProtocolError, "Invalid Paramater for GTC" # debug
-
- def handle_SYN(self, params):
- id = int(params[0])
- if len(params) == 2:
- self._setState('SESSION')
- self._fireCallback(id, None, None)
- else:
- contacts = MSNContactList()
- contacts.version = int(params[1])
- self._setStateData('list', contacts)
- self._setStateData('lst_reply', int(params[2]))
- self._setStateData('lsg_reply', int(params[3]))
- self._setStateData('lst_sofar', 0)
- self._setStateData('phone', [])
-
- def handle_LSG(self, params):
- if self._getState() == 'SYNC':
- self._getStateData('list').groups[int(params[0])] = unquote(params[1])
-
- # Please see the comment above the requestListGroups / requestList methods
- # regarding support for this
- #
- #else:
- # self._getStateData('groups').append((int(params[4]), unquote(params[5])))
- # if params[3] == params[4]: # this was the last group
- # self._fireCallback(int(params[0]), self._getStateData('groups'), int(params[1]))
- # self._remStateData('groups')
-
- def handle_PRP(self, params):
- if self._getState() == 'SYNC':
- self._getStateData('phone').append((params[0], unquote(params[1])))
- else:
- self._fireCallback(int(params[0]), int(params[1]), unquote(params[3]))
-
- def handle_BPR(self, params):
- numParams = len(params)
- if numParams == 2: # part of a syn
- self._getStateData('last_contact').setPhone(params[0], unquote(params[1]))
- elif numParams == 4:
- self.gotPhoneNumber(int(params[0]), params[1], params[2], unquote(params[3]))
-
- def handle_ADG(self, params):
- checkParamLen(len(params), 5, 'ADG')
- id = int(params[0])
- if not self._fireCallback(id, int(params[1]), unquote(params[2]), int(params[3])):
- raise MSNProtocolError, "ADG response does not match up to a request" # debug
-
- def handle_RMG(self, params):
- checkParamLen(len(params), 3, 'RMG')
- id = int(params[0])
- if not self._fireCallback(id, int(params[1]), int(params[2])):
- raise MSNProtocolError, "RMG response does not match up to a request" # debug
-
- def handle_REG(self, params):
- checkParamLen(len(params), 5, 'REG')
- id = int(params[0])
- if not self._fireCallback(id, int(params[1]), int(params[2]), unquote(params[3])):
- raise MSNProtocolError, "REG response does not match up to a request" # debug
-
- def handle_ADD(self, params):
- numParams = len(params)
- if numParams < 5 or params[1].upper() not in ('AL','BL','RL','FL'):
- raise MSNProtocolError, "Invalid Paramaters for ADD" # debug
- id = int(params[0])
- listType = params[1].lower()
- listVer = int(params[2])
- userHandle = params[3]
- groupID = None
- if numParams == 6: # they sent a group id
- if params[1].upper() != "FL":
- raise MSNProtocolError, "Only forward list can contain groups" # debug
- groupID = int(params[5])
- if not self._fireCallback(id, listCodeToID[listType], userHandle, listVer, groupID):
- self.userAddedMe(userHandle, unquote(params[4]), listVer)
-
- def handle_REM(self, params):
- numParams = len(params)
- if numParams < 4 or params[1].upper() not in ('AL','BL','FL','RL'):
- raise MSNProtocolError, "Invalid Paramaters for REM" # debug
- id = int(params[0])
- listType = params[1].lower()
- listVer = int(params[2])
- userHandle = params[3]
- groupID = None
- if numParams == 5:
- if params[1] != "FL":
- raise MSNProtocolError, "Only forward list can contain groups" # debug
- groupID = int(params[4])
- if not self._fireCallback(id, listCodeToID[listType], userHandle, listVer, groupID):
- if listType.upper() == "RL":
- self.userRemovedMe(userHandle, listVer)
-
- def handle_REA(self, params):
- checkParamLen(len(params), 4, 'REA')
- id = int(params[0])
- self._fireCallback(id, int(params[1]), unquote(params[3]))
-
- def handle_XFR(self, params):
- checkParamLen(len(params), 5, 'XFR')
- id = int(params[0])
- # check to see if they sent a host/port pair
- try:
- host, port = params[2].split(':')
- except ValueError:
- host = params[2]
- port = MSN_PORT
-
- if not self._fireCallback(id, host, int(port), params[4]):
- raise MSNProtocolError, "Got XFR (referral) that I didn't ask for .. should this happen?" # debug
-
- def handle_RNG(self, params):
- checkParamLen(len(params), 6, 'RNG')
- # check for host:port pair
- try:
- host, port = params[1].split(":")
- port = int(port)
- except ValueError:
- host = params[1]
- port = MSN_PORT
- self.gotSwitchboardInvitation(int(params[0]), host, port, params[3], params[4],
- unquote(params[5]))
-
- def handle_OUT(self, params):
- checkParamLen(len(params), 1, 'OUT')
- if params[0] == "OTH":
- self.multipleLogin()
- elif params[0] == "SSD":
- self.serverGoingDown()
- else:
- raise MSNProtocolError, "Invalid Parameters received for OUT" # debug
-
- # callbacks
-
- def loggedIn(self, userHandle, screenName, verified):
- """
- Called when the client has logged in.
- The default behaviour of this method is to
- update the factory with our screenName and
- to sync the contact list (factory.contacts).
- When this is complete self.listSynchronized
- will be called.
-
- @param userHandle: our userHandle
- @param screenName: our screenName
- @param verified: 1 if our passport has been (verified), 0 if not.
- (i'm not sure of the significace of this)
- @type verified: int
- """
- self.factory.screenName = screenName
- if not self.factory.contacts:
- listVersion = 0
- else:
- listVersion = self.factory.contacts.version
- self.syncList(listVersion).addCallback(self.listSynchronized)
-
-
- def loginFailure(self, message):
- """
- Called when the client fails to login.
-
- @param message: a message indicating the problem that was encountered
- """
-
-
- def gotProfile(self, message):
- """
- Called after logging in when the server sends an initial
- message with MSN/passport specific profile information
- such as country, number of kids, etc.
- Check the message headers for the specific values.
-
- @param message: The profile message
- """
- pass
-
- def listSynchronized(self, *args):
- """
- Lists are now synchronized by default upon logging in, this
- method is called after the synchronization has finished
- and the factory now has the up-to-date contacts.
- """
- pass
-
- def statusChanged(self, statusCode):
- """
- Called when our status changes and it isn't in response to
- a client command. By default we will update the status
- attribute of the factory.
-
- @param statusCode: 3-letter status code
- """
- self.factory.status = statusCode
-
- def gotContactStatus(self, statusCode, userHandle, screenName):
- """
- Called after loggin in when the server sends status of online contacts.
- By default we will update the status attribute of the contact stored
- on the factory.
-
- @param statusCode: 3-letter status code
- @param userHandle: the contact's user handle (passport)
- @param screenName: the contact's screen name
- """
- self.factory.contacts.getContact(userHandle).status = statusCode
-
- def contactStatusChanged(self, statusCode, userHandle, screenName):
- """
- Called when we're notified that a contact's status has changed.
- By default we will update the status attribute of the contact
- stored on the factory.
-
- @param statusCode: 3-letter status code
- @param userHandle: the contact's user handle (passport)
- @param screenName: the contact's screen name
- """
- self.factory.contacts.getContact(userHandle).status = statusCode
-
- def contactOffline(self, userHandle):
- """
- Called when a contact goes offline. By default this method
- will update the status attribute of the contact stored
- on the factory.
-
- @param userHandle: the contact's user handle
- """
- self.factory.contacts.getContact(userHandle).status = STATUS_OFFLINE
-
- def gotPhoneNumber(self, listVersion, userHandle, phoneType, number):
- """
- Called when the server sends us phone details about
- a specific user (for example after a user is added
- the server will send their status, phone details etc.
- By default we will update the list version for the
- factory's contact list and update the phone details
- for the specific user.
-
- @param listVersion: the new list version
- @param userHandle: the contact's user handle (passport)
- @param phoneType: the specific phoneType
- (*_PHONE constants or HAS_PAGER)
- @param number: the value/phone number.
- """
- self.factory.contacts.version = listVersion
- self.factory.contacts.getContact(userHandle).setPhone(phoneType, number)
-
- def userAddedMe(self, userHandle, screenName, listVersion):
- """
- Called when a user adds me to their list. (ie. they have been added to
- the reverse list. By default this method will update the version of
- the factory's contact list -- that is, if the contact already exists
- it will update the associated lists attribute, otherwise it will create
- a new MSNContact object and store it.
-
- @param userHandle: the userHandle of the user
- @param screenName: the screen name of the user
- @param listVersion: the new list version
- @type listVersion: int
- """
- self.factory.contacts.version = listVersion
- c = self.factory.contacts.getContact(userHandle)
- if not c:
- c = MSNContact(userHandle=userHandle, screenName=screenName)
- self.factory.contacts.addContact(c)
- c.addToList(REVERSE_LIST)
-
- def userRemovedMe(self, userHandle, listVersion):
- """
- Called when a user removes us from their contact list
- (they are no longer on our reverseContacts list.
- By default this method will update the version of
- the factory's contact list -- that is, the user will
- be removed from the reverse list and if they are no longer
- part of any lists they will be removed from the contact
- list entirely.
-
- @param userHandle: the contact's user handle (passport)
- @param listVersion: the new list version
- """
- self.factory.contacts.version = listVersion
- c = self.factory.contacts.getContact(userHandle)
- c.removeFromList(REVERSE_LIST)
- if c.lists == 0:
- self.factory.contacts.remContact(c.userHandle)
-
- def gotSwitchboardInvitation(self, sessionID, host, port,
- key, userHandle, screenName):
- """
- Called when we get an invitation to a switchboard server.
- This happens when a user requests a chat session with us.
-
- @param sessionID: session ID number, must be remembered for logging in
- @param host: the hostname of the switchboard server
- @param port: the port to connect to
- @param key: used for authorization when connecting
- @param userHandle: the user handle of the person who invited us
- @param screenName: the screen name of the person who invited us
- """
- pass
-
- def multipleLogin(self):
- """
- Called when the server says there has been another login
- under our account, the server should disconnect us right away.
- """
- pass
-
- def serverGoingDown(self):
- """
- Called when the server has notified us that it is going down for
- maintenance.
- """
- pass
-
- # api calls
-
- def changeStatus(self, status):
- """
- Change my current status. This method will add
- a default callback to the returned Deferred
- which will update the status attribute of the
- factory.
-
- @param status: 3-letter status code (as defined by
- the STATUS_* constants)
- @return: A Deferred, the callback of which will be
- fired when the server confirms the change
- of status. The callback argument will be
- a tuple with the new status code as the
- only element.
- """
-
- id, d = self._createIDMapping()
- self.sendLine("CHG %s %s" % (id, status))
- def _cb(r):
- self.factory.status = r[0]
- return r
- return d.addCallback(_cb)
-
- # I am no longer supporting the process of manually requesting
- # lists or list groups -- as far as I can see this has no use
- # if lists are synchronized and updated correctly, which they
- # should be. If someone has a specific justified need for this
- # then please contact me and i'll re-enable/fix support for it.
-
- #def requestList(self, listType):
- # """
- # request the desired list type
- #
- # @param listType: (as defined by the *_LIST constants)
- # @return: A Deferred, the callback of which will be
- # fired when the list has been retrieved.
- # The callback argument will be a tuple with
- # the only element being a list of MSNContact
- # objects.
- # """
- # # this doesn't need to ever be used if syncing of the lists takes place
- # # i.e. please don't use it!
- # warnings.warn("Please do not use this method - use the list syncing process instead")
- # id, d = self._createIDMapping()
- # self.sendLine("LST %s %s" % (id, listIDToCode[listType].upper()))
- # self._setStateData('list',[])
- # return d
-
- def setPrivacyMode(self, privLevel):
- """
- Set my privacy mode on the server.
-
- B{Note}:
- This only keeps the current privacy setting on
- the server for later retrieval, it does not
- effect the way the server works at all.
-
- @param privLevel: This parameter can be true, in which
- case the server will keep the state as
- 'al' which the official client interprets
- as -> allow messages from only users on
- the allow list. Alternatively it can be
- false, in which case the server will keep
- the state as 'bl' which the official client
- interprets as -> allow messages from all
- users except those on the block list.
-
- @return: A Deferred, the callback of which will be fired when
- the server replies with the new privacy setting.
- The callback argument will be a tuple, the 2 elements
- of which being the list version and either 'al'
- or 'bl' (the new privacy setting).
- """
-
- id, d = self._createIDMapping()
- if privLevel:
- self.sendLine("BLP %s AL" % id)
- else:
- self.sendLine("BLP %s BL" % id)
- return d
-
- def syncList(self, version):
- """
- Used for keeping an up-to-date contact list.
- A callback is added to the returned Deferred
- that updates the contact list on the factory
- and also sets my state to STATUS_ONLINE.
-
- B{Note}:
- This is called automatically upon signing
- in using the version attribute of
- factory.contacts, so you may want to persist
- this object accordingly. Because of this there
- is no real need to ever call this method
- directly.
-
- @param version: The current known list version
-
- @return: A Deferred, the callback of which will be
- fired when the server sends an adequate reply.
- The callback argument will be a tuple with two
- elements, the new list (MSNContactList) and
- your current state (a dictionary). If the version
- you sent _was_ the latest list version, both elements
- will be None. To just request the list send a version of 0.
- """
-
- self._setState('SYNC')
- id, d = self._createIDMapping(data=str(version))
- self._setStateData('synid',id)
- self.sendLine("SYN %s %s" % (id, version))
- def _cb(r):
- self.changeStatus(STATUS_ONLINE)
- if r[0] is not None:
- self.factory.contacts = r[0]
- return r
- return d.addCallback(_cb)
-
-
- # I am no longer supporting the process of manually requesting
- # lists or list groups -- as far as I can see this has no use
- # if lists are synchronized and updated correctly, which they
- # should be. If someone has a specific justified need for this
- # then please contact me and i'll re-enable/fix support for it.
-
- #def requestListGroups(self):
- # """
- # Request (forward) list groups.
- #
- # @return: A Deferred, the callback for which will be called
- # when the server responds with the list groups.
- # The callback argument will be a tuple with two elements,
- # a dictionary mapping group IDs to group names and the
- # current list version.
- # """
- #
- # # this doesn't need to be used if syncing of the lists takes place (which it SHOULD!)
- # # i.e. please don't use it!
- # warnings.warn("Please do not use this method - use the list syncing process instead")
- # id, d = self._createIDMapping()
- # self.sendLine("LSG %s" % id)
- # self._setStateData('groups',{})
- # return d
-
- def setPhoneDetails(self, phoneType, value):
- """
- Set/change my phone numbers stored on the server.
-
- @param phoneType: phoneType can be one of the following
- constants - HOME_PHONE, WORK_PHONE,
- MOBILE_PHONE, HAS_PAGER.
- These are pretty self-explanatory, except
- maybe HAS_PAGER which refers to whether or
- not you have a pager.
- @param value: for all of the *_PHONE constants the value is a
- phone number (str), for HAS_PAGER accepted values
- are 'Y' (for yes) and 'N' (for no).
-
- @return: A Deferred, the callback for which will be fired when
- the server confirms the change has been made. The
- callback argument will be a tuple with 2 elements, the
- first being the new list version (int) and the second
- being the new phone number value (str).
- """
- # XXX: Add a default callback which updates
- # factory.contacts.version and the relevant phone
- # number
- id, d = self._createIDMapping()
- self.sendLine("PRP %s %s %s" % (id, phoneType, quote(value)))
- return d
-
- def addListGroup(self, name):
- """
- Used to create a new list group.
- A default callback is added to the
- returned Deferred which updates the
- contacts attribute of the factory.
-
- @param name: The desired name of the new group.
-
- @return: A Deferred, the callbacck for which will be called
- when the server clarifies that the new group has been
- created. The callback argument will be a tuple with 3
- elements: the new list version (int), the new group name
- (str) and the new group ID (int).
- """
-
- id, d = self._createIDMapping()
- self.sendLine("ADG %s %s 0" % (id, quote(name)))
- def _cb(r):
- self.factory.contacts.version = r[0]
- self.factory.contacts.setGroup(r[1], r[2])
- return r
- return d.addCallback(_cb)
-
- def remListGroup(self, groupID):
- """
- Used to remove a list group.
- A default callback is added to the
- returned Deferred which updates the
- contacts attribute of the factory.
-
- @param groupID: the ID of the desired group to be removed.
-
- @return: A Deferred, the callback for which will be called when
- the server clarifies the deletion of the group.
- The callback argument will be a tuple with 2 elements:
- the new list version (int) and the group ID (int) of
- the removed group.
- """
-
- id, d = self._createIDMapping()
- self.sendLine("RMG %s %s" % (id, groupID))
- def _cb(r):
- self.factory.contacts.version = r[0]
- self.factory.contacts.remGroup(r[1])
- return r
- return d.addCallback(_cb)
-
- def renameListGroup(self, groupID, newName):
- """
- Used to rename an existing list group.
- A default callback is added to the returned
- Deferred which updates the contacts attribute
- of the factory.
-
- @param groupID: the ID of the desired group to rename.
- @param newName: the desired new name for the group.
-
- @return: A Deferred, the callback for which will be called
- when the server clarifies the renaming.
- The callback argument will be a tuple of 3 elements,
- the new list version (int), the group id (int) and
- the new group name (str).
- """
-
- id, d = self._createIDMapping()
- self.sendLine("REG %s %s %s 0" % (id, groupID, quote(newName)))
- def _cb(r):
- self.factory.contacts.version = r[0]
- self.factory.contacts.setGroup(r[1], r[2])
- return r
- return d.addCallback(_cb)
-
- def addContact(self, listType, userHandle, groupID=0):
- """
- Used to add a contact to the desired list.
- A default callback is added to the returned
- Deferred which updates the contacts attribute of
- the factory with the new contact information.
- If you are adding a contact to the forward list
- and you want to associate this contact with multiple
- groups then you will need to call this method for each
- group you would like to add them to, changing the groupID
- parameter. The default callback will take care of updating
- the group information on the factory's contact list.
-
- @param listType: (as defined by the *_LIST constants)
- @param userHandle: the user handle (passport) of the contact
- that is being added
- @param groupID: the group ID for which to associate this contact
- with. (default 0 - default group). Groups are only
- valid for FORWARD_LIST.
-
- @return: A Deferred, the callback for which will be called when
- the server has clarified that the user has been added.
- The callback argument will be a tuple with 4 elements:
- the list type, the contact's user handle, the new list
- version, and the group id (if relevant, otherwise it
- will be None)
- """
-
- id, d = self._createIDMapping()
- listType = listIDToCode[listType].upper()
- if listType == "FL":
- self.sendLine("ADD %s FL %s %s %s" % (id, userHandle, userHandle, groupID))
- else:
- self.sendLine("ADD %s %s %s %s" % (id, listType, userHandle, userHandle))
-
- def _cb(r):
- self.factory.contacts.version = r[2]
- c = self.factory.contacts.getContact(r[1])
- if not c:
- c = MSNContact(userHandle=r[1])
- if r[3]:
- c.groups.append(r[3])
- c.addToList(r[0])
- return r
- return d.addCallback(_cb)
-
- def remContact(self, listType, userHandle, groupID=0):
- """
- Used to remove a contact from the desired list.
- A default callback is added to the returned deferred
- which updates the contacts attribute of the factory
- to reflect the new contact information. If you are
- removing from the forward list then you will need to
- supply a groupID, if the contact is in more than one
- group then they will only be removed from this group
- and not the entire forward list, but if this is their
- only group they will be removed from the whole list.
-
- @param listType: (as defined by the *_LIST constants)
- @param userHandle: the user handle (passport) of the
- contact being removed
- @param groupID: the ID of the group to which this contact
- belongs (only relevant for FORWARD_LIST,
- default is 0)
-
- @return: A Deferred, the callback for which will be called when
- the server has clarified that the user has been removed.
- The callback argument will be a tuple of 4 elements:
- the list type, the contact's user handle, the new list
- version, and the group id (if relevant, otherwise it will
- be None)
- """
-
- id, d = self._createIDMapping()
- listType = listIDToCode[listType].upper()
- if listType == "FL":
- self.sendLine("REM %s FL %s %s" % (id, userHandle, groupID))
- else:
- self.sendLine("REM %s %s %s" % (id, listType, userHandle))
-
- def _cb(r):
- l = self.factory.contacts
- l.version = r[2]
- c = l.getContact(r[1])
- group = r[3]
- shouldRemove = 1
- if group: # they may not have been removed from the list
- c.groups.remove(group)
- if c.groups:
- shouldRemove = 0
- if shouldRemove:
- c.removeFromList(r[0])
- if c.lists == 0:
- l.remContact(c.userHandle)
- return r
- return d.addCallback(_cb)
-
- def changeScreenName(self, newName):
- """
- Used to change your current screen name.
- A default callback is added to the returned
- Deferred which updates the screenName attribute
- of the factory and also updates the contact list
- version.
-
- @param newName: the new screen name
-
- @return: A Deferred, the callback for which will be called
- when the server sends an adequate reply.
- The callback argument will be a tuple of 2 elements:
- the new list version and the new screen name.
- """
-
- id, d = self._createIDMapping()
- self.sendLine("REA %s %s %s" % (id, self.factory.userHandle, quote(newName)))
- def _cb(r):
- self.factory.contacts.version = r[0]
- self.factory.screenName = r[1]
- return r
- return d.addCallback(_cb)
-
- def requestSwitchboardServer(self):
- """
- Used to request a switchboard server to use for conversations.
-
- @return: A Deferred, the callback for which will be called when
- the server responds with the switchboard information.
- The callback argument will be a tuple with 3 elements:
- the host of the switchboard server, the port and a key
- used for logging in.
- """
-
- id, d = self._createIDMapping()
- self.sendLine("XFR %s SB" % id)
- return d
-
- def logOut(self):
- """
- Used to log out of the notification server.
- After running the method the server is expected
- to close the connection.
- """
-
- self.sendLine("OUT")
-
-class NotificationFactory(ClientFactory):
- """
- Factory for the NotificationClient protocol.
- This is basically responsible for keeping
- the state of the client and thus should be used
- in a 1:1 situation with clients.
-
- @ivar contacts: An MSNContactList instance reflecting
- the current contact list -- this is
- generally kept up to date by the default
- command handlers.
- @ivar userHandle: The client's userHandle, this is expected
- to be set by the client and is used by the
- protocol (for logging in etc).
- @ivar screenName: The client's current screen-name -- this is
- generally kept up to date by the default
- command handlers.
- @ivar password: The client's password -- this is (obviously)
- expected to be set by the client.
- @ivar passportServer: This must point to an msn passport server
- (the whole URL is required)
- @ivar status: The status of the client -- this is generally kept
- up to date by the default command handlers
- """
-
- contacts = None
- userHandle = ''
- screenName = ''
- password = ''
- passportServer = 'https://nexus.passport.com/rdr/pprdr.asp'
- status = 'FLN'
- protocol = NotificationClient
-
-
-# XXX: A lot of the state currently kept in
-# instances of SwitchboardClient is likely to
-# be moved into a factory at some stage in the
-# future
-
-class SwitchboardClient(MSNEventBase):
- """
- This class provides support for clients connecting to a switchboard server.
-
- Switchboard servers are used for conversations with other people
- on the MSN network. This means that the number of conversations at
- any given time will be directly proportional to the number of
- connections to varioius switchboard servers.
-
- MSN makes no distinction between single and group conversations,
- so any number of users may be invited to join a specific conversation
- taking place on a switchboard server.
-
- @ivar key: authorization key, obtained when receiving
- invitation / requesting switchboard server.
- @ivar userHandle: your user handle (passport)
- @ivar sessionID: unique session ID, used if you are replying
- to a switchboard invitation
- @ivar reply: set this to 1 in connectionMade or before to signifiy
- that you are replying to a switchboard invitation.
- """
-
- key = 0
- userHandle = ""
- sessionID = ""
- reply = 0
-
- _iCookie = 0
-
- def __init__(self):
- MSNEventBase.__init__(self)
- self.pendingUsers = {}
- self.cookies = {'iCookies' : {}, 'external' : {}} # will maybe be moved to a factory in the future
-
- def connectionMade(self):
- MSNEventBase.connectionMade(self)
- print 'sending initial stuff'
- self._sendInit()
-
- def connectionLost(self, reason):
- self.cookies['iCookies'] = {}
- self.cookies['external'] = {}
- MSNEventBase.connectionLost(self, reason)
-
- def _sendInit(self):
- """
- send initial data based on whether we are replying to an invitation
- or starting one.
- """
- id = self._nextTransactionID()
- if not self.reply:
- self.sendLine("USR %s %s %s" % (id, self.userHandle, self.key))
- else:
- self.sendLine("ANS %s %s %s %s" % (id, self.userHandle, self.key, self.sessionID))
-
- def _newInvitationCookie(self):
- self._iCookie += 1
- if self._iCookie > 1000:
- self._iCookie = 1
- return self._iCookie
-
- def _checkTyping(self, message, cTypes):
- """ helper method for checkMessage """
- if 'text/x-msmsgscontrol' in cTypes and message.hasHeader('TypingUser'):
- self.userTyping(message)
- return 1
-
- def _checkFileInvitation(self, message, info):
- """ helper method for checkMessage """
- guid = info.get('Application-GUID', '').lower()
- name = info.get('Application-Name', '').lower()
-
- # Both fields are required, but we'll let some lazy clients get away
- # with only sending a name, if it is easy for us to recognize the
- # name (the name is localized, so this check might fail for lazy,
- # non-english clients, but I'm not about to include "file transfer"
- # in 80 different languages here).
-
- if name != "file transfer" and guid != classNameToGUID["file transfer"]:
- return 0
- try:
- cookie = int(info['Invitation-Cookie'])
- fileName = info['Application-File']
- fileSize = int(info['Application-FileSize'])
- except KeyError:
- log.msg('Received munged file transfer request ... ignoring.')
- return 0
- self.gotSendRequest(fileName, fileSize, cookie, message)
- return 1
-
- def _checkFileResponse(self, message, info):
- """ helper method for checkMessage """
- try:
- cmd = info['Invitation-Command'].upper()
- cookie = int(info['Invitation-Cookie'])
- except KeyError:
- return 0
- accept = (cmd == 'ACCEPT') and 1 or 0
- requested = self.cookies['iCookies'].get(cookie)
- if not requested:
- return 1
- requested[0].callback((accept, cookie, info))
- del self.cookies['iCookies'][cookie]
- return 1
-
- def _checkFileInfo(self, message, info):
- """ helper method for checkMessage """
- try:
- ip = info['IP-Address']
- iCookie = int(info['Invitation-Cookie'])
- aCookie = int(info['AuthCookie'])
- cmd = info['Invitation-Command'].upper()
- port = int(info['Port'])
- except KeyError:
- return 0
- accept = (cmd == 'ACCEPT') and 1 or 0
- requested = self.cookies['external'].get(iCookie)
- if not requested:
- return 1 # we didn't ask for this
- requested[0].callback((accept, ip, port, aCookie, info))
- del self.cookies['external'][iCookie]
- return 1
-
- def checkMessage(self, message):
- """
- hook for detecting any notification type messages
- (e.g. file transfer)
- """
- cTypes = [s.lstrip() for s in message.getHeader('Content-Type').split(';')]
- if self._checkTyping(message, cTypes):
- return 0
- if 'text/x-msmsgsinvite' in cTypes:
- # header like info is sent as part of the message body.
- info = {}
- for line in message.message.split('\r\n'):
- try:
- key, val = line.split(':')
- info[key] = val.lstrip()
- except ValueError:
- continue
- if self._checkFileInvitation(message, info) or self._checkFileInfo(message, info) or self._checkFileResponse(message, info):
- return 0
- elif 'text/x-clientcaps' in cTypes:
- # do something with capabilities
- return 0
- return 1
-
- # negotiation
- def handle_USR(self, params):
- checkParamLen(len(params), 4, 'USR')
- if params[1] == "OK":
- self.loggedIn()
-
- # invite a user
- def handle_CAL(self, params):
- checkParamLen(len(params), 3, 'CAL')
- id = int(params[0])
- if params[1].upper() == "RINGING":
- self._fireCallback(id, int(params[2])) # session ID as parameter
-
- # user joined
- def handle_JOI(self, params):
- checkParamLen(len(params), 2, 'JOI')
- self.userJoined(params[0], unquote(params[1]))
-
- # users participating in the current chat
- def handle_IRO(self, params):
- checkParamLen(len(params), 5, 'IRO')
- self.pendingUsers[params[3]] = unquote(params[4])
- if params[1] == params[2]:
- self.gotChattingUsers(self.pendingUsers)
- self.pendingUsers = {}
-
- # finished listing users
- def handle_ANS(self, params):
- checkParamLen(len(params), 2, 'ANS')
- if params[1] == "OK":
- self.loggedIn()
-
- def handle_ACK(self, params):
- checkParamLen(len(params), 1, 'ACK')
- self._fireCallback(int(params[0]), None)
-
- def handle_NAK(self, params):
- checkParamLen(len(params), 1, 'NAK')
- self._fireCallback(int(params[0]), None)
-
- def handle_BYE(self, params):
- #checkParamLen(len(params), 1, 'BYE') # i've seen more than 1 param passed to this
- self.userLeft(params[0])
-
- # callbacks
-
- def loggedIn(self):
- """
- called when all login details have been negotiated.
- Messages can now be sent, or new users invited.
- """
- pass
-
- def gotChattingUsers(self, users):
- """
- called after connecting to an existing chat session.
-
- @param users: A dict mapping user handles to screen names
- (current users taking part in the conversation)
- """
- pass
-
- def userJoined(self, userHandle, screenName):
- """
- called when a user has joined the conversation.
-
- @param userHandle: the user handle (passport) of the user
- @param screenName: the screen name of the user
- """
- pass
-
- def userLeft(self, userHandle):
- """
- called when a user has left the conversation.
-
- @param userHandle: the user handle (passport) of the user.
- """
- pass
-
- def gotMessage(self, message):
- """
- called when we receive a message.
-
- @param message: the associated MSNMessage object
- """
- pass
-
- def userTyping(self, message):
- """
- called when we receive the special type of message notifying
- us that a user is typing a message.
-
- @param message: the associated MSNMessage object
- """
- pass
-
- def gotSendRequest(self, fileName, fileSize, iCookie, message):
- """
- called when a contact is trying to send us a file.
- To accept or reject this transfer see the
- fileInvitationReply method.
-
- @param fileName: the name of the file
- @param fileSize: the size of the file
- @param iCookie: the invitation cookie, used so the client can
- match up your reply with this request.
- @param message: the MSNMessage object which brought about this
- invitation (it may contain more information)
- """
- pass
-
- # api calls
-
- def inviteUser(self, userHandle):
- """
- used to invite a user to the current switchboard server.
-
- @param userHandle: the user handle (passport) of the desired user.
-
- @return: A Deferred, the callback for which will be called
- when the server notifies us that the user has indeed
- been invited. The callback argument will be a tuple
- with 1 element, the sessionID given to the invited user.
- I'm not sure if this is useful or not.
- """
-
- id, d = self._createIDMapping()
- self.sendLine("CAL %s %s" % (id, userHandle))
- return d
-
- def sendMessage(self, message):
- """
- used to send a message.
-
- @param message: the corresponding MSNMessage object.
-
- @return: Depending on the value of message.ack.
- If set to MSNMessage.MESSAGE_ACK or
- MSNMessage.MESSAGE_NACK a Deferred will be returned,
- the callback for which will be fired when an ACK or
- NACK is received - the callback argument will be
- (None,). If set to MSNMessage.MESSAGE_ACK_NONE then
- the return value is None.
- """
-
- if message.ack not in ('A','N'):
- id, d = self._nextTransactionID(), None
- else:
- id, d = self._createIDMapping()
- if message.length == 0:
- message.length = message._calcMessageLen()
- self.sendLine("MSG %s %s %s" % (id, message.ack, message.length))
- # apparently order matters with at least MIME-Version and Content-Type
- self.sendLine('MIME-Version: %s' % message.getHeader('MIME-Version'))
- self.sendLine('Content-Type: %s' % message.getHeader('Content-Type'))
- # send the rest of the headers
- for header in [h for h in message.headers.items() if h[0].lower() not in ('mime-version','content-type')]:
- self.sendLine("%s: %s" % (header[0], header[1]))
- self.transport.write(CR+LF)
- self.transport.write(message.message)
- return d
-
- def sendTypingNotification(self):
- """
- used to send a typing notification. Upon receiving this
- message the official client will display a 'user is typing'
- message to all other users in the chat session for 10 seconds.
- The official client sends one of these every 5 seconds (I think)
- as long as you continue to type.
- """
- m = MSNMessage()
- m.ack = m.MESSAGE_ACK_NONE
- m.setHeader('Content-Type', 'text/x-msmsgscontrol')
- m.setHeader('TypingUser', self.userHandle)
- m.message = "\r\n"
- self.sendMessage(m)
-
- def sendFileInvitation(self, fileName, fileSize):
- """
- send an notification that we want to send a file.
-
- @param fileName: the file name
- @param fileSize: the file size
-
- @return: A Deferred, the callback of which will be fired
- when the user responds to this invitation with an
- appropriate message. The callback argument will be
- a tuple with 3 elements, the first being 1 or 0
- depending on whether they accepted the transfer
- (1=yes, 0=no), the second being an invitation cookie
- to identify your follow-up responses and the third being
- the message 'info' which is a dict of information they
- sent in their reply (this doesn't really need to be used).
- If you wish to proceed with the transfer see the
- sendTransferInfo method.
- """
- cookie = self._newInvitationCookie()
- d = Deferred()
- m = MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8')
- m.message += 'Application-Name: File Transfer\r\n'
- m.message += 'Application-GUID: %s\r\n' % (classNameToGUID["file transfer"],)
- m.message += 'Invitation-Command: INVITE\r\n'
- m.message += 'Invitation-Cookie: %s\r\n' % str(cookie)
- m.message += 'Application-File: %s\r\n' % fileName
- m.message += 'Application-FileSize: %s\r\n\r\n' % str(fileSize)
- m.ack = m.MESSAGE_ACK_NONE
- self.sendMessage(m)
- self.cookies['iCookies'][cookie] = (d, m)
- return d
-
- def fileInvitationReply(self, iCookie, accept=1):
- """
- used to reply to a file transfer invitation.
-
- @param iCookie: the invitation cookie of the initial invitation
- @param accept: whether or not you accept this transfer,
- 1 = yes, 0 = no, default = 1.
-
- @return: A Deferred, the callback for which will be fired when
- the user responds with the transfer information.
- The callback argument will be a tuple with 5 elements,
- whether or not they wish to proceed with the transfer
- (1=yes, 0=no), their ip, the port, the authentication
- cookie (see FileReceive/FileSend) and the message
- info (dict) (in case they send extra header-like info
- like Internal-IP, this doesn't necessarily need to be
- used). If you wish to proceed with the transfer see
- FileReceive.
- """
- d = Deferred()
- m = MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8')
- m.message += 'Invitation-Command: %s\r\n' % (accept and 'ACCEPT' or 'CANCEL')
- m.message += 'Invitation-Cookie: %s\r\n' % str(iCookie)
- if not accept:
- m.message += 'Cancel-Code: REJECT\r\n'
- m.message += 'Launch-Application: FALSE\r\n'
- m.message += 'Request-Data: IP-Address:\r\n'
- m.message += '\r\n'
- m.ack = m.MESSAGE_ACK_NONE
- self.sendMessage(m)
- self.cookies['external'][iCookie] = (d, m)
- return d
-
- def sendTransferInfo(self, accept, iCookie, authCookie, ip, port):
- """
- send information relating to a file transfer session.
-
- @param accept: whether or not to go ahead with the transfer
- (1=yes, 0=no)
- @param iCookie: the invitation cookie of previous replies
- relating to this transfer
- @param authCookie: the authentication cookie obtained from
- an FileSend instance
- @param ip: your ip
- @param port: the port on which an FileSend protocol is listening.
- """
- m = MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8')
- m.message += 'Invitation-Command: %s\r\n' % (accept and 'ACCEPT' or 'CANCEL')
- m.message += 'Invitation-Cookie: %s\r\n' % iCookie
- m.message += 'IP-Address: %s\r\n' % ip
- m.message += 'Port: %s\r\n' % port
- m.message += 'AuthCookie: %s\r\n' % authCookie
- m.message += '\r\n'
- m.ack = m.MESSAGE_NACK
- self.sendMessage(m)
-
-class FileReceive(LineReceiver):
- """
- This class provides support for receiving files from contacts.
-
- @ivar fileSize: the size of the receiving file. (you will have to set this)
- @ivar connected: true if a connection has been established.
- @ivar completed: true if the transfer is complete.
- @ivar bytesReceived: number of bytes (of the file) received.
- This does not include header data.
- """
-
- def __init__(self, auth, myUserHandle, file, directory="", overwrite=0):
- """
- @param auth: auth string received in the file invitation.
- @param myUserHandle: your userhandle.
- @param file: A string or file object represnting the file
- to save data to.
- @param directory: optional parameter specifiying the directory.
- Defaults to the current directory.
- @param overwrite: if true and a file of the same name exists on
- your system, it will be overwritten. (0 by default)
- """
- self.auth = auth
- self.myUserHandle = myUserHandle
- self.fileSize = 0
- self.connected = 0
- self.completed = 0
- self.directory = directory
- self.bytesReceived = 0
- self.overwrite = overwrite
-
- # used for handling current received state
- self.state = 'CONNECTING'
- self.segmentLength = 0
- self.buffer = ''
-
- if isinstance(file, types.StringType):
- path = os.path.join(directory, file)
- if os.path.exists(path) and not self.overwrite:
- log.msg('File already exists...')
- raise IOError, "File Exists" # is this all we should do here?
- self.file = open(os.path.join(directory, file), 'wb')
- else:
- self.file = file
-
- def connectionMade(self):
- self.connected = 1
- self.state = 'INHEADER'
- self.sendLine('VER MSNFTP')
-
- def connectionLost(self, reason):
- self.connected = 0
- self.file.close()
-
- def parseHeader(self, header):
- """ parse the header of each 'message' to obtain the segment length """
-
- if ord(header[0]) != 0: # they requested that we close the connection
- self.transport.loseConnection()
- return
- try:
- extra, factor = header[1:]
- except ValueError:
- # munged header, ending transfer
- self.transport.loseConnection()
- raise
- extra = ord(extra)
- factor = ord(factor)
- return factor * 256 + extra
-
- def lineReceived(self, line):
- temp = line.split()
- if len(temp) == 1:
- params = []
- else:
- params = temp[1:]
- cmd = temp[0]
- handler = getattr(self, "handle_%s" % cmd.upper(), None)
- if handler:
- handler(params) # try/except
- else:
- self.handle_UNKNOWN(cmd, params)
-
- def rawDataReceived(self, data):
- bufferLen = len(self.buffer)
- if self.state == 'INHEADER':
- delim = 3-bufferLen
- self.buffer += data[:delim]
- if len(self.buffer) == 3:
- self.segmentLength = self.parseHeader(self.buffer)
- if not self.segmentLength:
- return # hrm
- self.buffer = ""
- self.state = 'INSEGMENT'
- extra = data[delim:]
- if len(extra) > 0:
- self.rawDataReceived(extra)
- return
-
- elif self.state == 'INSEGMENT':
- dataSeg = data[:(self.segmentLength-bufferLen)]
- self.buffer += dataSeg
- self.bytesReceived += len(dataSeg)
- if len(self.buffer) == self.segmentLength:
- self.gotSegment(self.buffer)
- self.buffer = ""
- if self.bytesReceived == self.fileSize:
- self.completed = 1
- self.buffer = ""
- self.file.close()
- self.sendLine("BYE 16777989")
- return
- self.state = 'INHEADER'
- extra = data[(self.segmentLength-bufferLen):]
- if len(extra) > 0:
- self.rawDataReceived(extra)
- return
-
- def handle_VER(self, params):
- checkParamLen(len(params), 1, 'VER')
- if params[0].upper() == "MSNFTP":
- self.sendLine("USR %s %s" % (self.myUserHandle, self.auth))
- else:
- log.msg('they sent the wrong version, time to quit this transfer')
- self.transport.loseConnection()
-
- def handle_FIL(self, params):
- checkParamLen(len(params), 1, 'FIL')
- try:
- self.fileSize = int(params[0])
- except ValueError: # they sent the wrong file size - probably want to log this
- self.transport.loseConnection()
- return
- self.setRawMode()
- self.sendLine("TFR")
-
- def handle_UNKNOWN(self, cmd, params):
- log.msg('received unknown command (%s), params: %s' % (cmd, params))
-
- def gotSegment(self, data):
- """ called when a segment (block) of data arrives. """
- self.file.write(data)
-
-class FileSend(LineReceiver):
- """
- This class provides support for sending files to other contacts.
-
- @ivar bytesSent: the number of bytes that have currently been sent.
- @ivar completed: true if the send has completed.
- @ivar connected: true if a connection has been established.
- @ivar targetUser: the target user (contact).
- @ivar segmentSize: the segment (block) size.
- @ivar auth: the auth cookie (number) to use when sending the
- transfer invitation
- """
-
- def __init__(self, file):
- """
- @param file: A string or file object represnting the file to send.
- """
-
- if isinstance(file, types.StringType):
- self.file = open(file, 'rb')
- else:
- self.file = file
-
- self.fileSize = 0
- self.bytesSent = 0
- self.completed = 0
- self.connected = 0
- self.targetUser = None
- self.segmentSize = 2045
- self.auth = randint(0, 2**30)
- self._pendingSend = None # :(
-
- def connectionMade(self):
- self.connected = 1
-
- def connectionLost(self, reason):
- if self._pendingSend.active():
- self._pendingSend.cancel()
- self._pendingSend = None
- if self.bytesSent == self.fileSize:
- self.completed = 1
- self.connected = 0
- self.file.close()
-
- def lineReceived(self, line):
- temp = line.split()
- if len(temp) == 1:
- params = []
- else:
- params = temp[1:]
- cmd = temp[0]
- handler = getattr(self, "handle_%s" % cmd.upper(), None)
- if handler:
- handler(params)
- else:
- self.handle_UNKNOWN(cmd, params)
-
- def handle_VER(self, params):
- checkParamLen(len(params), 1, 'VER')
- if params[0].upper() == "MSNFTP":
- self.sendLine("VER MSNFTP")
- else: # they sent some weird version during negotiation, i'm quitting.
- self.transport.loseConnection()
-
- def handle_USR(self, params):
- checkParamLen(len(params), 2, 'USR')
- self.targetUser = params[0]
- if self.auth == int(params[1]):
- self.sendLine("FIL %s" % (self.fileSize))
- else: # they failed the auth test, disconnecting.
- self.transport.loseConnection()
-
- def handle_TFR(self, params):
- checkParamLen(len(params), 0, 'TFR')
- # they are ready for me to start sending
- self.sendPart()
-
- def handle_BYE(self, params):
- self.completed = (self.bytesSent == self.fileSize)
- self.transport.loseConnection()
-
- def handle_CCL(self, params):
- self.completed = (self.bytesSent == self.fileSize)
- self.transport.loseConnection()
-
- def handle_UNKNOWN(self, cmd, params):
- log.msg('received unknown command (%s), params: %s' % (cmd, params))
-
- def makeHeader(self, size):
- """ make the appropriate header given a specific segment size. """
- quotient, remainder = divmod(size, 256)
- return chr(0) + chr(remainder) + chr(quotient)
-
- def sendPart(self):
- """ send a segment of data """
- if not self.connected:
- self._pendingSend = None
- return # may be buggy (if handle_CCL/BYE is called but self.connected is still 1)
- data = self.file.read(self.segmentSize)
- if data:
- dataSize = len(data)
- header = self.makeHeader(dataSize)
- self.bytesSent += dataSize
- self.transport.write(header + data)
- self._pendingSend = reactor.callLater(0, self.sendPart)
- else:
- self._pendingSend = None
- self.completed = 1
-
-# mapping of error codes to error messages
-errorCodes = {
-
- 200 : "Syntax error",
- 201 : "Invalid parameter",
- 205 : "Invalid user",
- 206 : "Domain name missing",
- 207 : "Already logged in",
- 208 : "Invalid username",
- 209 : "Invalid screen name",
- 210 : "User list full",
- 215 : "User already there",
- 216 : "User already on list",
- 217 : "User not online",
- 218 : "Already in mode",
- 219 : "User is in the opposite list",
- 223 : "Too many groups",
- 224 : "Invalid group",
- 225 : "User not in group",
- 229 : "Group name too long",
- 230 : "Cannot remove group 0",
- 231 : "Invalid group",
- 280 : "Switchboard failed",
- 281 : "Transfer to switchboard failed",
-
- 300 : "Required field missing",
- 301 : "Too many FND responses",
- 302 : "Not logged in",
-
- 500 : "Internal server error",
- 501 : "Database server error",
- 502 : "Command disabled",
- 510 : "File operation failed",
- 520 : "Memory allocation failed",
- 540 : "Wrong CHL value sent to server",
-
- 600 : "Server is busy",
- 601 : "Server is unavaliable",
- 602 : "Peer nameserver is down",
- 603 : "Database connection failed",
- 604 : "Server is going down",
- 605 : "Server unavailable",
-
- 707 : "Could not create connection",
- 710 : "Invalid CVR parameters",
- 711 : "Write is blocking",
- 712 : "Session is overloaded",
- 713 : "Too many active users",
- 714 : "Too many sessions",
- 715 : "Not expected",
- 717 : "Bad friend file",
- 731 : "Not expected",
-
- 800 : "Requests too rapid",
-
- 910 : "Server too busy",
- 911 : "Authentication failed",
- 912 : "Server too busy",
- 913 : "Not allowed when offline",
- 914 : "Server too busy",
- 915 : "Server too busy",
- 916 : "Server too busy",
- 917 : "Server too busy",
- 918 : "Server too busy",
- 919 : "Server too busy",
- 920 : "Not accepting new users",
- 921 : "Server too busy",
- 922 : "Server too busy",
- 923 : "No parent consent",
- 924 : "Passport account not yet verified"
-
-}
-
-# mapping of status codes to readable status format
-statusCodes = {
-
- STATUS_ONLINE : "Online",
- STATUS_OFFLINE : "Offline",
- STATUS_HIDDEN : "Appear Offline",
- STATUS_IDLE : "Idle",
- STATUS_AWAY : "Away",
- STATUS_BUSY : "Busy",
- STATUS_BRB : "Be Right Back",
- STATUS_PHONE : "On the Phone",
- STATUS_LUNCH : "Out to Lunch"
-
-}
-
-# mapping of list ids to list codes
-listIDToCode = {
-
- FORWARD_LIST : 'fl',
- BLOCK_LIST : 'bl',
- ALLOW_LIST : 'al',
- REVERSE_LIST : 'rl'
-
-}
-
-# mapping of list codes to list ids
-listCodeToID = {}
-for id,code in listIDToCode.items():
- listCodeToID[code] = id
-
-del id, code
-
-# Mapping of class GUIDs to simple english names
-guidToClassName = {
- "{5D3E02AB-6190-11d3-BBBB-00C04F795683}": "file transfer",
- }
-
-# Reverse of the above
-classNameToGUID = {}
-for guid, name in guidToClassName.iteritems():
- classNameToGUID[name] = guid
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/oscar.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/oscar.py
deleted file mode 100755
index 81571d40..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/protocols/oscar.py
+++ /dev/null
@@ -1,1235 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-An implementation of the OSCAR protocol, which AIM and ICQ use to communcate.
-
-Maintainer: Paul Swartz
-"""
-
-import struct
-import string
-import socket
-import random
-import types
-import re
-
-from twisted.internet import reactor, defer, protocol
-from twisted.python import log
-from twisted.python.hashlib import md5
-
-def logPacketData(data):
- lines = len(data)/16
- if lines*16 != len(data): lines=lines+1
- for i in range(lines):
- d = tuple(data[16*i:16*i+16])
- hex = map(lambda x: "%02X"%ord(x),d)
- text = map(lambda x: (len(repr(x))>3 and '.') or x, d)
- log.msg(' '.join(hex)+ ' '*3*(16-len(d)) +''.join(text))
- log.msg('')
-
-def SNAC(fam,sub,id,data,flags=[0,0]):
- header="!HHBBL"
- head=struct.pack(header,fam,sub,
- flags[0],flags[1],
- id)
- return head+str(data)
-
-def readSNAC(data):
- header="!HHBBL"
- head=list(struct.unpack(header,data[:10]))
- return head+[data[10:]]
-
-def TLV(type,value):
- header="!HH"
- head=struct.pack(header,type,len(value))
- return head+str(value)
-
-def readTLVs(data,count=None):
- header="!HH"
- dict={}
- while data and len(dict)!=count:
- head=struct.unpack(header,data[:4])
- dict[head[0]]=data[4:4+head[1]]
- data=data[4+head[1]:]
- if not count:
- return dict
- return dict,data
-
-def encryptPasswordMD5(password,key):
- m=md5()
- m.update(key)
- m.update(md5(password).digest())
- m.update("AOL Instant Messenger (SM)")
- return m.digest()
-
-def encryptPasswordICQ(password):
- key=[0xF3,0x26,0x81,0xC4,0x39,0x86,0xDB,0x92,0x71,0xA3,0xB9,0xE6,0x53,0x7A,0x95,0x7C]
- bytes=map(ord,password)
- r=""
- for i in range(len(bytes)):
- r=r+chr(bytes[i]^key[i%len(key)])
- return r
-
-def dehtml(text):
- text=string.replace(text,"<br>","\n")
- text=string.replace(text,"<BR>","\n")
- text=string.replace(text,"<Br>","\n") # XXX make this a regexp
- text=string.replace(text,"<bR>","\n")
- text=re.sub('<.*?>','',text)
- text=string.replace(text,'&gt;','>')
- text=string.replace(text,'&lt;','<')
- text=string.replace(text,'&nbsp;',' ')
- text=string.replace(text,'&#34;','"')
- text=string.replace(text,'&amp;','&')
- return text
-
-def html(text):
- text=string.replace(text,'"','&#34;')
- text=string.replace(text,'&','&amp;')
- text=string.replace(text,'<','&lt;')
- text=string.replace(text,'>','&gt;')
- text=string.replace(text,"\n","<br>")
- return '<html><body bgcolor="white"><font color="black">%s</font></body></html>'%text
-
-class OSCARUser:
- def __init__(self, name, warn, tlvs):
- self.name = name
- self.warning = warn
- self.flags = []
- self.caps = []
- for k,v in tlvs.items():
- if k == 1: # user flags
- v=struct.unpack('!H',v)[0]
- for o, f in [(1,'trial'),
- (2,'unknown bit 2'),
- (4,'aol'),
- (8,'unknown bit 4'),
- (16,'aim'),
- (32,'away'),
- (1024,'activebuddy')]:
- if v&o: self.flags.append(f)
- elif k == 2: # member since date
- self.memberSince = struct.unpack('!L',v)[0]
- elif k == 3: # on-since
- self.onSince = struct.unpack('!L',v)[0]
- elif k == 4: # idle time
- self.idleTime = struct.unpack('!H',v)[0]
- elif k == 5: # unknown
- pass
- elif k == 6: # icq online status
- if v[2] == '\x00':
- self.icqStatus = 'online'
- elif v[2] == '\x01':
- self.icqStatus = 'away'
- elif v[2] == '\x02':
- self.icqStatus = 'dnd'
- elif v[2] == '\x04':
- self.icqStatus = 'out'
- elif v[2] == '\x10':
- self.icqStatus = 'busy'
- else:
- self.icqStatus = 'unknown'
- elif k == 10: # icq ip address
- self.icqIPaddy = socket.inet_ntoa(v)
- elif k == 12: # icq random stuff
- self.icqRandom = v
- elif k == 13: # capabilities
- caps=[]
- while v:
- c=v[:16]
- if c==CAP_ICON: caps.append("icon")
- elif c==CAP_IMAGE: caps.append("image")
- elif c==CAP_VOICE: caps.append("voice")
- elif c==CAP_CHAT: caps.append("chat")
- elif c==CAP_GET_FILE: caps.append("getfile")
- elif c==CAP_SEND_FILE: caps.append("sendfile")
- elif c==CAP_SEND_LIST: caps.append("sendlist")
- elif c==CAP_GAMES: caps.append("games")
- else: caps.append(("unknown",c))
- v=v[16:]
- caps.sort()
- self.caps=caps
- elif k == 14: pass
- elif k == 15: # session length (aim)
- self.sessionLength = struct.unpack('!L',v)[0]
- elif k == 16: # session length (aol)
- self.sessionLength = struct.unpack('!L',v)[0]
- elif k == 30: # no idea
- pass
- else:
- log.msg("unknown tlv for user %s\nt: %s\nv: %s"%(self.name,k,repr(v)))
-
- def __str__(self):
- s = '<OSCARUser %s' % self.name
- o = []
- if self.warning!=0: o.append('warning level %s'%self.warning)
- if hasattr(self, 'flags'): o.append('flags %s'%self.flags)
- if hasattr(self, 'sessionLength'): o.append('online for %i minutes' % (self.sessionLength/60,))
- if hasattr(self, 'idleTime'): o.append('idle for %i minutes' % self.idleTime)
- if self.caps: o.append('caps %s'%self.caps)
- if o:
- s=s+', '+', '.join(o)
- s=s+'>'
- return s
-
-
-class SSIGroup:
- def __init__(self, name, tlvs = {}):
- self.name = name
- #self.tlvs = []
- #self.userIDs = []
- self.usersToID = {}
- self.users = []
- #if not tlvs.has_key(0xC8): return
- #buddyIDs = tlvs[0xC8]
- #while buddyIDs:
- # bid = struct.unpack('!H',buddyIDs[:2])[0]
- # buddyIDs = buddyIDs[2:]
- # self.users.append(bid)
-
- def findIDFor(self, user):
- return self.usersToID[user]
-
- def addUser(self, buddyID, user):
- self.usersToID[user] = buddyID
- self.users.append(user)
- user.group = self
-
- def oscarRep(self, groupID, buddyID):
- tlvData = TLV(0xc8, reduce(lambda x,y:x+y, [struct.pack('!H',self.usersToID[x]) for x in self.users]))
- return struct.pack('!H', len(self.name)) + self.name + \
- struct.pack('!HH', groupID, buddyID) + '\000\001' + tlvData
-
-
-class SSIBuddy:
- def __init__(self, name, tlvs = {}):
- self.name = name
- self.tlvs = tlvs
- for k,v in tlvs.items():
- if k == 0x013c: # buddy comment
- self.buddyComment = v
- elif k == 0x013d: # buddy alerts
- actionFlag = ord(v[0])
- whenFlag = ord(v[1])
- self.alertActions = []
- self.alertWhen = []
- if actionFlag&1:
- self.alertActions.append('popup')
- if actionFlag&2:
- self.alertActions.append('sound')
- if whenFlag&1:
- self.alertWhen.append('online')
- if whenFlag&2:
- self.alertWhen.append('unidle')
- if whenFlag&4:
- self.alertWhen.append('unaway')
- elif k == 0x013e:
- self.alertSound = v
-
- def oscarRep(self, groupID, buddyID):
- tlvData = reduce(lambda x,y: x+y, map(lambda (k,v):TLV(k,v), self.tlvs.items()), '\000\000')
- return struct.pack('!H', len(self.name)) + self.name + \
- struct.pack('!HH', groupID, buddyID) + '\000\000' + tlvData
-
-
-class OscarConnection(protocol.Protocol):
- def connectionMade(self):
- self.state=""
- self.seqnum=0
- self.buf=''
- self.stopKeepAliveID = None
- self.setKeepAlive(4*60) # 4 minutes
-
- def connectionLost(self, reason):
- log.msg("Connection Lost! %s" % self)
- self.stopKeepAlive()
-
-# def connectionFailed(self):
-# log.msg("Connection Failed! %s" % self)
-# self.stopKeepAlive()
-
- def sendFLAP(self,data,channel = 0x02):
- header="!cBHH"
- self.seqnum=(self.seqnum+1)%0xFFFF
- seqnum=self.seqnum
- head=struct.pack(header,'*', channel,
- seqnum, len(data))
- self.transport.write(head+str(data))
-# if isinstance(self, ChatService):
-# logPacketData(head+str(data))
-
- def readFlap(self):
- header="!cBHH"
- if len(self.buf)<6: return
- flap=struct.unpack(header,self.buf[:6])
- if len(self.buf)<6+flap[3]: return
- data,self.buf=self.buf[6:6+flap[3]],self.buf[6+flap[3]:]
- return [flap[1],data]
-
- def dataReceived(self,data):
-# if isinstance(self, ChatService):
-# logPacketData(data)
- self.buf=self.buf+data
- flap=self.readFlap()
- while flap:
- func=getattr(self,"oscar_%s"%self.state,None)
- if not func:
- log.msg("no func for state: %s" % self.state)
- state=func(flap)
- if state:
- self.state=state
- flap=self.readFlap()
-
- def setKeepAlive(self,t):
- self.keepAliveDelay=t
- self.stopKeepAlive()
- self.stopKeepAliveID = reactor.callLater(t, self.sendKeepAlive)
-
- def sendKeepAlive(self):
- self.sendFLAP("",0x05)
- self.stopKeepAliveID = reactor.callLater(self.keepAliveDelay, self.sendKeepAlive)
-
- def stopKeepAlive(self):
- if self.stopKeepAliveID:
- self.stopKeepAliveID.cancel()
- self.stopKeepAliveID = None
-
- def disconnect(self):
- """
- send the disconnect flap, and sever the connection
- """
- self.sendFLAP('', 0x04)
- def f(reason): pass
- self.connectionLost = f
- self.transport.loseConnection()
-
-
-class SNACBased(OscarConnection):
- snacFamilies = {
- # family : (version, toolID, toolVersion)
- }
- def __init__(self,cookie):
- self.cookie=cookie
- self.lastID=0
- self.supportedFamilies = ()
- self.requestCallbacks={} # request id:Deferred
-
- def sendSNAC(self,fam,sub,data,flags=[0,0]):
- """
- send a snac and wait for the response by returning a Deferred.
- """
- reqid=self.lastID
- self.lastID=reqid+1
- d = defer.Deferred()
- d.reqid = reqid
-
- #d.addErrback(self._ebDeferredError,fam,sub,data) # XXX for testing
-
- self.requestCallbacks[reqid] = d
- self.sendFLAP(SNAC(fam,sub,reqid,data))
- return d
-
- def _ebDeferredError(self, error, fam, sub, data):
- log.msg('ERROR IN DEFERRED %s' % error)
- log.msg('on sending of message, family 0x%02x, subtype 0x%02x' % (fam, sub))
- log.msg('data: %s' % repr(data))
-
- def sendSNACnr(self,fam,sub,data,flags=[0,0]):
- """
- send a snac, but don't bother adding a deferred, we don't care.
- """
- self.sendFLAP(SNAC(fam,sub,0x10000*fam+sub,data))
-
- def oscar_(self,data):
- self.sendFLAP("\000\000\000\001"+TLV(6,self.cookie), 0x01)
- return "Data"
-
- def oscar_Data(self,data):
- snac=readSNAC(data[1])
- if self.requestCallbacks.has_key(snac[4]):
- d = self.requestCallbacks[snac[4]]
- del self.requestCallbacks[snac[4]]
- if snac[1]!=1:
- d.callback(snac)
- else:
- d.errback(snac)
- return
- func=getattr(self,'oscar_%02X_%02X'%(snac[0],snac[1]),None)
- if not func:
- self.oscar_unknown(snac)
- else:
- func(snac[2:])
- return "Data"
-
- def oscar_unknown(self,snac):
- log.msg("unknown for %s" % self)
- log.msg(snac)
-
-
- def oscar_01_03(self, snac):
- numFamilies = len(snac[3])/2
- self.supportedFamilies = struct.unpack("!"+str(numFamilies)+'H', snac[3])
- d = ''
- for fam in self.supportedFamilies:
- if self.snacFamilies.has_key(fam):
- d=d+struct.pack('!2H',fam,self.snacFamilies[fam][0])
- self.sendSNACnr(0x01,0x17, d)
-
- def oscar_01_0A(self,snac):
- """
- change of rate information.
- """
- # this can be parsed, maybe we can even work it in
- pass
-
- def oscar_01_18(self,snac):
- """
- host versions, in the same format as we sent
- """
- self.sendSNACnr(0x01,0x06,"") #pass
-
- def clientReady(self):
- """
- called when the client is ready to be online
- """
- d = ''
- for fam in self.supportedFamilies:
- if self.snacFamilies.has_key(fam):
- version, toolID, toolVersion = self.snacFamilies[fam]
- d = d + struct.pack('!4H',fam,version,toolID,toolVersion)
- self.sendSNACnr(0x01,0x02,d)
-
-class BOSConnection(SNACBased):
- snacFamilies = {
- 0x01:(3, 0x0110, 0x059b),
- 0x13:(3, 0x0110, 0x059b),
- 0x02:(1, 0x0110, 0x059b),
- 0x03:(1, 0x0110, 0x059b),
- 0x04:(1, 0x0110, 0x059b),
- 0x06:(1, 0x0110, 0x059b),
- 0x08:(1, 0x0104, 0x0001),
- 0x09:(1, 0x0110, 0x059b),
- 0x0a:(1, 0x0110, 0x059b),
- 0x0b:(1, 0x0104, 0x0001),
- 0x0c:(1, 0x0104, 0x0001)
- }
-
- capabilities = None
-
- def __init__(self,username,cookie):
- SNACBased.__init__(self,cookie)
- self.username=username
- self.profile = None
- self.awayMessage = None
- self.services = {}
-
- if not self.capabilities:
- self.capabilities = [CAP_CHAT]
-
- def parseUser(self,data,count=None):
- l=ord(data[0])
- name=data[1:1+l]
- warn,foo=struct.unpack("!HH",data[1+l:5+l])
- warn=int(warn/10)
- tlvs=data[5+l:]
- if count:
- tlvs,rest = readTLVs(tlvs,foo)
- else:
- tlvs,rest = readTLVs(tlvs), None
- u = OSCARUser(name, warn, tlvs)
- if rest == None:
- return u
- else:
- return u, rest
-
- def oscar_01_05(self, snac, d = None):
- """
- data for a new service connection
- d might be a deferred to be called back when the service is ready
- """
- tlvs = readTLVs(snac[3][2:])
- service = struct.unpack('!H',tlvs[0x0d])[0]
- ip = tlvs[5]
- cookie = tlvs[6]
- #c = serviceClasses[service](self, cookie, d)
- c = protocol.ClientCreator(reactor, serviceClasses[service], self, cookie, d)
- def addService(x):
- self.services[service] = x
- c.connectTCP(ip, 5190).addCallback(addService)
- #self.services[service] = c
-
- def oscar_01_07(self,snac):
- """
- rate paramaters
- """
- self.sendSNACnr(0x01,0x08,"\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05") # ack
- self.initDone()
- self.sendSNACnr(0x13,0x02,'') # SSI rights info
- self.sendSNACnr(0x02,0x02,'') # location rights info
- self.sendSNACnr(0x03,0x02,'') # buddy list rights
- self.sendSNACnr(0x04,0x04,'') # ICBM parms
- self.sendSNACnr(0x09,0x02,'') # BOS rights
-
- def oscar_01_10(self,snac):
- """
- we've been warned
- """
- skip = struct.unpack('!H',snac[3][:2])[0]
- newLevel = struct.unpack('!H',snac[3][2+skip:4+skip])[0]/10
- if len(snac[3])>4+skip:
- by = self.parseUser(snac[3][4+skip:])
- else:
- by = None
- self.receiveWarning(newLevel, by)
-
- def oscar_01_13(self,snac):
- """
- MOTD
- """
- pass # we don't care for now
-
- def oscar_02_03(self, snac):
- """
- location rights response
- """
- tlvs = readTLVs(snac[3])
- self.maxProfileLength = tlvs[1]
-
- def oscar_03_03(self, snac):
- """
- buddy list rights response
- """
- tlvs = readTLVs(snac[3])
- self.maxBuddies = tlvs[1]
- self.maxWatchers = tlvs[2]
-
- def oscar_03_0B(self, snac):
- """
- buddy update
- """
- self.updateBuddy(self.parseUser(snac[3]))
-
- def oscar_03_0C(self, snac):
- """
- buddy offline
- """
- self.offlineBuddy(self.parseUser(snac[3]))
-
-# def oscar_04_03(self, snac):
-
- def oscar_04_05(self, snac):
- """
- ICBM parms response
- """
- self.sendSNACnr(0x04,0x02,'\x00\x00\x00\x00\x00\x0b\x1f@\x03\xe7\x03\xe7\x00\x00\x00\x00') # IM rights
-
- def oscar_04_07(self, snac):
- """
- ICBM message (instant message)
- """
- data = snac[3]
- cookie, data = data[:8], data[8:]
- channel = struct.unpack('!H',data[:2])[0]
- data = data[2:]
- user, data = self.parseUser(data, 1)
- tlvs = readTLVs(data)
- if channel == 1: # message
- flags = []
- multiparts = []
- for k, v in tlvs.items():
- if k == 2:
- while v:
- v = v[2:] # skip bad data
- messageLength, charSet, charSubSet = struct.unpack('!3H', v[:6])
- messageLength -= 4
- message = [v[6:6+messageLength]]
- if charSet == 0:
- pass # don't add anything special
- elif charSet == 2:
- message.append('unicode')
- elif charSet == 3:
- message.append('iso-8859-1')
- elif charSet == 0xffff:
- message.append('none')
- if charSubSet == 0xb:
- message.append('macintosh')
- if messageLength > 0: multiparts.append(tuple(message))
- v = v[6+messageLength:]
- elif k == 3:
- flags.append('acknowledge')
- elif k == 4:
- flags.append('auto')
- elif k == 6:
- flags.append('offline')
- elif k == 8:
- iconLength, foo, iconSum, iconStamp = struct.unpack('!LHHL',v)
- if iconLength:
- flags.append('icon')
- flags.append((iconLength, iconSum, iconStamp))
- elif k == 9:
- flags.append('buddyrequest')
- elif k == 0xb: # unknown
- pass
- elif k == 0x17:
- flags.append('extradata')
- flags.append(v)
- else:
- log.msg('unknown TLV for incoming IM, %04x, %s' % (k,repr(v)))
-
-# unknown tlv for user SNewdorf
-# t: 29
-# v: '\x00\x00\x00\x05\x02\x01\xd2\x04r\x00\x01\x01\x10/\x8c\x8b\x8a\x1e\x94*\xbc\x80}\x8d\xc4;\x1dEM'
-# XXX what is this?
- self.receiveMessage(user, multiparts, flags)
- elif channel == 2: # rondevouz
- status = struct.unpack('!H',tlvs[5][:2])[0]
- requestClass = tlvs[5][10:26]
- moreTLVs = readTLVs(tlvs[5][26:])
- if requestClass == CAP_CHAT: # a chat request
- exchange = struct.unpack('!H',moreTLVs[10001][:2])[0]
- name = moreTLVs[10001][3:-2]
- instance = struct.unpack('!H',moreTLVs[10001][-2:])[0]
- if not self.services.has_key(SERVICE_CHATNAV):
- self.connectService(SERVICE_CHATNAV,1).addCallback(lambda x: self.services[SERVICE_CHATNAV].getChatInfo(exchange, name, instance).\
- addCallback(self._cbGetChatInfoForInvite, user, moreTLVs[12]))
- else:
- self.services[SERVICE_CHATNAV].getChatInfo(exchange, name, instance).\
- addCallback(self._cbGetChatInfoForInvite, user, moreTLVs[12])
- elif requestClass == CAP_SEND_FILE:
- if moreTLVs.has_key(11): # cancel
- log.msg('cancelled file request')
- log.msg(status)
- return # handle this later
- name = moreTLVs[10001][9:-7]
- desc = moreTLVs[12]
- log.msg('file request from %s, %s, %s' % (user, name, desc))
- self.receiveSendFileRequest(user, name, desc, cookie)
- else:
- log.msg('unsupported rondevouz: %s' % requestClass)
- log.msg(repr(moreTLVs))
- else:
- log.msg('unknown channel %02x' % channel)
- log.msg(tlvs)
-
- def _cbGetChatInfoForInvite(self, info, user, message):
- apply(self.receiveChatInvite, (user,message)+info)
-
- def oscar_09_03(self, snac):
- """
- BOS rights response
- """
- tlvs = readTLVs(snac[3])
- self.maxPermitList = tlvs[1]
- self.maxDenyList = tlvs[2]
-
- def oscar_0B_02(self, snac):
- """
- stats reporting interval
- """
- self.reportingInterval = struct.unpack('!H',snac[3][:2])[0]
-
- def oscar_13_03(self, snac):
- """
- SSI rights response
- """
- #tlvs = readTLVs(snac[3])
- pass # we don't know how to parse this
-
- # methods to be called by the client, and their support methods
- def requestSelfInfo(self):
- """
- ask for the OSCARUser for ourselves
- """
- d = defer.Deferred()
- self.sendSNAC(0x01, 0x0E, '').addCallback(self._cbRequestSelfInfo, d)
- return d
-
- def _cbRequestSelfInfo(self, snac, d):
- d.callback(self.parseUser(snac[5]))
-
- def initSSI(self):
- """
- this sends the rate request for family 0x13 (Server Side Information)
- so we can then use it
- """
- return self.sendSNAC(0x13, 0x02, '').addCallback(self._cbInitSSI)
-
- def _cbInitSSI(self, snac, d):
- return {} # don't even bother parsing this
-
- def requestSSI(self, timestamp = 0, revision = 0):
- """
- request the server side information
- if the deferred gets None, it means the SSI is the same
- """
- return self.sendSNAC(0x13, 0x05,
- struct.pack('!LH',timestamp,revision)).addCallback(self._cbRequestSSI)
-
- def _cbRequestSSI(self, snac, args = ()):
- if snac[1] == 0x0f: # same SSI as we have
- return
- itemdata = snac[5][3:]
- if args:
- revision, groups, permit, deny, permitMode, visibility = args
- else:
- version, revision = struct.unpack('!BH', snac[5][:3])
- groups = {}
- permit = []
- deny = []
- permitMode = None
- visibility = None
- while len(itemdata)>4:
- nameLength = struct.unpack('!H', itemdata[:2])[0]
- name = itemdata[2:2+nameLength]
- groupID, buddyID, itemType, restLength = \
- struct.unpack('!4H', itemdata[2+nameLength:10+nameLength])
- tlvs = readTLVs(itemdata[10+nameLength:10+nameLength+restLength])
- itemdata = itemdata[10+nameLength+restLength:]
- if itemType == 0: # buddies
- groups[groupID].addUser(buddyID, SSIBuddy(name, tlvs))
- elif itemType == 1: # group
- g = SSIGroup(name, tlvs)
- if groups.has_key(0): groups[0].addUser(groupID, g)
- groups[groupID] = g
- elif itemType == 2: # permit
- permit.append(name)
- elif itemType == 3: # deny
- deny.append(name)
- elif itemType == 4: # permit deny info
- if not tlvs.has_key(0xcb):
- continue # this happens with ICQ
- permitMode = {1:'permitall',2:'denyall',3:'permitsome',4:'denysome',5:'permitbuddies'}[ord(tlvs[0xca])]
- visibility = {'\xff\xff\xff\xff':'all','\x00\x00\x00\x04':'notaim'}[tlvs[0xcb]]
- elif itemType == 5: # unknown (perhaps idle data)?
- pass
- else:
- log.msg('%s %s %s %s %s' % (name, groupID, buddyID, itemType, tlvs))
- timestamp = struct.unpack('!L',itemdata)[0]
- if not timestamp: # we've got more packets coming
- # which means add some deferred stuff
- d = defer.Deferred()
- self.requestCallbacks[snac[4]] = d
- d.addCallback(self._cbRequestSSI, (revision, groups, permit, deny, permitMode, visibility))
- return d
- return (groups[0].users,permit,deny,permitMode,visibility,timestamp,revision)
-
- def activateSSI(self):
- """
- active the data stored on the server (use buddy list, permit deny settings, etc.)
- """
- self.sendSNACnr(0x13,0x07,'')
-
- def startModifySSI(self):
- """
- tell the OSCAR server to be on the lookout for SSI modifications
- """
- self.sendSNACnr(0x13,0x11,'')
-
- def addItemSSI(self, item, groupID = None, buddyID = None):
- """
- add an item to the SSI server. if buddyID == 0, then this should be a group.
- this gets a callback when it's finished, but you can probably ignore it.
- """
- if groupID is None:
- if isinstance(item, SSIGroup):
- groupID = 0
- else:
- groupID = item.group.group.findIDFor(item.group)
- if buddyID is None:
- buddyID = item.group.findIDFor(item)
- return self.sendSNAC(0x13,0x08, item.oscarRep(groupID, buddyID))
-
- def modifyItemSSI(self, item, groupID = None, buddyID = None):
- if groupID is None:
- if isinstance(item, SSIGroup):
- groupID = 0
- else:
- groupID = item.group.group.findIDFor(item.group)
- if buddyID is None:
- buddyID = item.group.findIDFor(item)
- return self.sendSNAC(0x13,0x09, item.oscarRep(groupID, buddyID))
-
- def delItemSSI(self, item, groupID = None, buddyID = None):
- if groupID is None:
- if isinstance(item, SSIGroup):
- groupID = 0
- else:
- groupID = item.group.group.findIDFor(item.group)
- if buddyID is None:
- buddyID = item.group.findIDFor(item)
- return self.sendSNAC(0x13,0x0A, item.oscarRep(groupID, buddyID))
-
- def endModifySSI(self):
- self.sendSNACnr(0x13,0x12,'')
-
- def setProfile(self, profile):
- """
- set the profile.
- send None to not set a profile (different from '' for a blank one)
- """
- self.profile = profile
- tlvs = ''
- if self.profile is not None:
- tlvs = TLV(1,'text/aolrtf; charset="us-ascii"') + \
- TLV(2,self.profile)
-
- tlvs = tlvs + TLV(5, ''.join(self.capabilities))
- self.sendSNACnr(0x02, 0x04, tlvs)
-
- def setAway(self, away = None):
- """
- set the away message, or return (if away == None)
- """
- self.awayMessage = away
- tlvs = TLV(3,'text/aolrtf; charset="us-ascii"') + \
- TLV(4,away or '')
- self.sendSNACnr(0x02, 0x04, tlvs)
-
- def setIdleTime(self, idleTime):
- """
- set our idle time. don't call more than once with a non-0 idle time.
- """
- self.sendSNACnr(0x01, 0x11, struct.pack('!L',idleTime))
-
- def sendMessage(self, user, message, wantAck = 0, autoResponse = 0, offline = 0 ): \
- #haveIcon = 0, ):
- """
- send a message to user (not an OSCARUseR).
- message can be a string, or a multipart tuple.
- if wantAck, we return a Deferred that gets a callback when the message is sent.
- if autoResponse, this message is an autoResponse, as if from an away message.
- if offline, this is an offline message (ICQ only, I think)
- """
- data = ''.join([chr(random.randrange(0, 127)) for i in range(8)]) # cookie
- data = data + '\x00\x01' + chr(len(user)) + user
- if not type(message) in (types.TupleType, types.ListType):
- message = [[message,]]
- if type(message[0][0]) == types.UnicodeType:
- message[0].append('unicode')
- messageData = ''
- for part in message:
- charSet = 0
- if 'unicode' in part[1:]:
- charSet = 2
- part[0] = part[0].encode('utf-8')
- elif 'iso-8859-1' in part[1:]:
- charSet = 3
- part[0] = part[0].encode('iso-8859-1')
- elif 'none' in part[1:]:
- charSet = 0xffff
- if 'macintosh' in part[1:]:
- charSubSet = 0xb
- else:
- charSubSet = 0
- messageData = messageData + '\x01\x01' + \
- struct.pack('!3H',len(part[0])+4,charSet,charSubSet)
- messageData = messageData + part[0]
- data = data + TLV(2, '\x05\x01\x00\x03\x01\x01\x02'+messageData)
- if wantAck:
- data = data + TLV(3,'')
- if autoResponse:
- data = data + TLV(4,'')
- if offline:
- data = data + TLV(6,'')
- if wantAck:
- return self.sendSNAC(0x04, 0x06, data).addCallback(self._cbSendMessageAck, user, message)
- self.sendSNACnr(0x04, 0x06, data)
-
- def _cbSendMessageAck(self, snac, user, message):
- return user, message
-
- def connectService(self, service, wantCallback = 0, extraData = ''):
- """
- connect to another service
- if wantCallback, we return a Deferred that gets called back when the service is online.
- if extraData, append that to our request.
- """
- if wantCallback:
- d = defer.Deferred()
- self.sendSNAC(0x01,0x04,struct.pack('!H',service) + extraData).addCallback(self._cbConnectService, d)
- return d
- else:
- self.sendSNACnr(0x01,0x04,struct.pack('!H',service))
-
- def _cbConnectService(self, snac, d):
- self.oscar_01_05(snac[2:], d)
-
- def createChat(self, shortName):
- """
- create a chat room
- """
- if self.services.has_key(SERVICE_CHATNAV):
- return self.services[SERVICE_CHATNAV].createChat(shortName)
- else:
- return self.connectService(SERVICE_CHATNAV,1).addCallback(lambda s: s.createChat(shortName))
-
-
- def joinChat(self, exchange, fullName, instance):
- """
- join a chat room
- """
- #d = defer.Deferred()
- return self.connectService(0x0e, 1, TLV(0x01, struct.pack('!HB',exchange, len(fullName)) + fullName +
- struct.pack('!H', instance))).addCallback(self._cbJoinChat) #, d)
- #return d
-
- def _cbJoinChat(self, chat):
- del self.services[SERVICE_CHAT]
- return chat
-
- def warnUser(self, user, anon = 0):
- return self.sendSNAC(0x04, 0x08, '\x00'+chr(anon)+chr(len(user))+user).addCallback(self._cbWarnUser)
-
- def _cbWarnUser(self, snac):
- oldLevel, newLevel = struct.unpack('!2H', snac[5])
- return oldLevel, newLevel
-
- def getInfo(self, user):
- #if user.
- return self.sendSNAC(0x02, 0x05, '\x00\x01'+chr(len(user))+user).addCallback(self._cbGetInfo)
-
- def _cbGetInfo(self, snac):
- user, rest = self.parseUser(snac[5],1)
- tlvs = readTLVs(rest)
- return tlvs.get(0x02,None)
-
- def getAway(self, user):
- return self.sendSNAC(0x02, 0x05, '\x00\x03'+chr(len(user))+user).addCallback(self._cbGetAway)
-
- def _cbGetAway(self, snac):
- user, rest = self.parseUser(snac[5],1)
- tlvs = readTLVs(rest)
- return tlvs.get(0x04,None) # return None if there is no away message
-
- #def acceptSendFileRequest(self,
-
- # methods to be overriden by the client
- def initDone(self):
- """
- called when we get the rate information, which means we should do other init. stuff.
- """
- log.msg('%s initDone' % self)
- pass
-
- def updateBuddy(self, user):
- """
- called when a buddy changes status, with the OSCARUser for that buddy.
- """
- log.msg('%s updateBuddy %s' % (self, user))
- pass
-
- def offlineBuddy(self, user):
- """
- called when a buddy goes offline
- """
- log.msg('%s offlineBuddy %s' % (self, user))
- pass
-
- def receiveMessage(self, user, multiparts, flags):
- """
- called when someone sends us a message
- """
- pass
-
- def receiveWarning(self, newLevel, user):
- """
- called when someone warns us.
- user is either None (if it was anonymous) or an OSCARUser
- """
- pass
-
- def receiveChatInvite(self, user, message, exchange, fullName, instance, shortName, inviteTime):
- """
- called when someone invites us to a chat room
- """
- pass
-
- def chatReceiveMessage(self, chat, user, message):
- """
- called when someone in a chatroom sends us a message in the chat
- """
- pass
-
- def chatMemberJoined(self, chat, member):
- """
- called when a member joins the chat
- """
- pass
-
- def chatMemberLeft(self, chat, member):
- """
- called when a member leaves the chat
- """
- pass
-
- def receiveSendFileRequest(self, user, file, description, cookie):
- """
- called when someone tries to send a file to us
- """
- pass
-
-class OSCARService(SNACBased):
- def __init__(self, bos, cookie, d = None):
- SNACBased.__init__(self, cookie)
- self.bos = bos
- self.d = d
-
- def connectionLost(self, reason):
- for k,v in self.bos.services.items():
- if v == self:
- del self.bos.services[k]
- return
-
- def clientReady(self):
- SNACBased.clientReady(self)
- if self.d:
- self.d.callback(self)
- self.d = None
-
-class ChatNavService(OSCARService):
- snacFamilies = {
- 0x01:(3, 0x0010, 0x059b),
- 0x0d:(1, 0x0010, 0x059b)
- }
- def oscar_01_07(self, snac):
- # rate info
- self.sendSNACnr(0x01, 0x08, '\000\001\000\002\000\003\000\004\000\005')
- self.sendSNACnr(0x0d, 0x02, '')
-
- def oscar_0D_09(self, snac):
- self.clientReady()
-
- def getChatInfo(self, exchange, name, instance):
- d = defer.Deferred()
- self.sendSNAC(0x0d,0x04,struct.pack('!HB',exchange,len(name)) + \
- name + struct.pack('!HB',instance,2)). \
- addCallback(self._cbGetChatInfo, d)
- return d
-
- def _cbGetChatInfo(self, snac, d):
- data = snac[5][4:]
- exchange, length = struct.unpack('!HB',data[:3])
- fullName = data[3:3+length]
- instance = struct.unpack('!H',data[3+length:5+length])[0]
- tlvs = readTLVs(data[8+length:])
- shortName = tlvs[0x6a]
- inviteTime = struct.unpack('!L',tlvs[0xca])[0]
- info = (exchange,fullName,instance,shortName,inviteTime)
- d.callback(info)
-
- def createChat(self, shortName):
- #d = defer.Deferred()
- data = '\x00\x04\x06create\xff\xff\x01\x00\x03'
- data = data + TLV(0xd7, 'en')
- data = data + TLV(0xd6, 'us-ascii')
- data = data + TLV(0xd3, shortName)
- return self.sendSNAC(0x0d, 0x08, data).addCallback(self._cbCreateChat)
- #return d
-
- def _cbCreateChat(self, snac): #d):
- exchange, length = struct.unpack('!HB',snac[5][4:7])
- fullName = snac[5][7:7+length]
- instance = struct.unpack('!H',snac[5][7+length:9+length])[0]
- #d.callback((exchange, fullName, instance))
- return exchange, fullName, instance
-
-class ChatService(OSCARService):
- snacFamilies = {
- 0x01:(3, 0x0010, 0x059b),
- 0x0E:(1, 0x0010, 0x059b)
- }
- def __init__(self,bos,cookie, d = None):
- OSCARService.__init__(self,bos,cookie,d)
- self.exchange = None
- self.fullName = None
- self.instance = None
- self.name = None
- self.members = None
-
- clientReady = SNACBased.clientReady # we'll do our own callback
-
- def oscar_01_07(self,snac):
- self.sendSNAC(0x01,0x08,"\000\001\000\002\000\003\000\004\000\005")
- self.clientReady()
-
- def oscar_0E_02(self, snac):
-# try: # this is EVIL
-# data = snac[3][4:]
-# self.exchange, length = struct.unpack('!HB',data[:3])
-# self.fullName = data[3:3+length]
-# self.instance = struct.unpack('!H',data[3+length:5+length])[0]
-# tlvs = readTLVs(data[8+length:])
-# self.name = tlvs[0xd3]
-# self.d.callback(self)
-# except KeyError:
- data = snac[3]
- self.exchange, length = struct.unpack('!HB',data[:3])
- self.fullName = data[3:3+length]
- self.instance = struct.unpack('!H',data[3+length:5+length])[0]
- tlvs = readTLVs(data[8+length:])
- self.name = tlvs[0xd3]
- self.d.callback(self)
-
- def oscar_0E_03(self,snac):
- users=[]
- rest=snac[3]
- while rest:
- user, rest = self.bos.parseUser(rest, 1)
- users.append(user)
- if not self.fullName:
- self.members = users
- else:
- self.members.append(users[0])
- self.bos.chatMemberJoined(self,users[0])
-
- def oscar_0E_04(self,snac):
- user=self.bos.parseUser(snac[3])
- for u in self.members:
- if u.name == user.name: # same person!
- self.members.remove(u)
- self.bos.chatMemberLeft(self,user)
-
- def oscar_0E_06(self,snac):
- data = snac[3]
- user,rest=self.bos.parseUser(snac[3][14:],1)
- tlvs = readTLVs(rest[8:])
- message=tlvs[1]
- self.bos.chatReceiveMessage(self,user,message)
-
- def sendMessage(self,message):
- tlvs=TLV(0x02,"us-ascii")+TLV(0x03,"en")+TLV(0x01,message)
- self.sendSNAC(0x0e,0x05,
- "\x46\x30\x38\x30\x44\x00\x63\x00\x00\x03\x00\x01\x00\x00\x00\x06\x00\x00\x00\x05"+
- struct.pack("!H",len(tlvs))+
- tlvs)
-
- def leaveChat(self):
- self.disconnect()
-
-class OscarAuthenticator(OscarConnection):
- BOSClass = BOSConnection
- def __init__(self,username,password,deferred=None,icq=0):
- self.username=username
- self.password=password
- self.deferred=deferred
- self.icq=icq # icq mode is disabled
- #if icq and self.BOSClass==BOSConnection:
- # self.BOSClass=ICQConnection
-
- def oscar_(self,flap):
- if not self.icq:
- self.sendFLAP("\000\000\000\001", 0x01)
- self.sendFLAP(SNAC(0x17,0x06,0,
- TLV(TLV_USERNAME,self.username)+
- TLV(0x004B,'')))
- self.state="Key"
- else:
- encpass=encryptPasswordICQ(self.password)
- self.sendFLAP('\000\000\000\001'+
- TLV(0x01,self.username)+
- TLV(0x02,encpass)+
- TLV(0x03,'ICQ Inc. - Product of ICQ (TM).2001b.5.18.1.3659.85')+
- TLV(0x16,"\x01\x0a")+
- TLV(0x17,"\x00\x05")+
- TLV(0x18,"\x00\x12")+
- TLV(0x19,"\000\001")+
- TLV(0x1a,"\x0eK")+
- TLV(0x14,"\x00\x00\x00U")+
- TLV(0x0f,"en")+
- TLV(0x0e,"us"),0x01)
- self.state="Cookie"
-
- def oscar_Key(self,data):
- snac=readSNAC(data[1])
- key=snac[5][2:]
- encpass=encryptPasswordMD5(self.password,key)
- self.sendFLAP(SNAC(0x17,0x02,0,
- TLV(TLV_USERNAME,self.username)+
- TLV(TLV_PASSWORD,encpass)+
- TLV(0x004C, '')+ # unknown
- TLV(TLV_CLIENTNAME,"AOL Instant Messenger (SM), version 4.8.2790/WIN32")+
- TLV(0x0016,"\x01\x09")+
- TLV(TLV_CLIENTMAJOR,"\000\004")+
- TLV(TLV_CLIENTMINOR,"\000\010")+
- TLV(0x0019,"\000\000")+
- TLV(TLV_CLIENTSUB,"\x0A\xE6")+
- TLV(0x0014,"\x00\x00\x00\xBB")+
- TLV(TLV_LANG,"en")+
- TLV(TLV_COUNTRY,"us")+
- TLV(TLV_USESSI,"\001")))
- return "Cookie"
-
- def oscar_Cookie(self,data):
- snac=readSNAC(data[1])
- if self.icq:
- i=snac[5].find("\000")
- snac[5]=snac[5][i:]
- tlvs=readTLVs(snac[5])
- if tlvs.has_key(6):
- self.cookie=tlvs[6]
- server,port=string.split(tlvs[5],":")
- d = self.connectToBOS(server, int(port))
- d.addErrback(lambda x: log.msg("Connection Failed! Reason: %s" % x))
- if self.deferred:
- d.chainDeferred(self.deferred)
- self.disconnect()
- elif tlvs.has_key(8):
- errorcode=tlvs[8]
- errorurl=tlvs[4]
- if errorcode=='\000\030':
- error="You are attempting to sign on again too soon. Please try again later."
- elif errorcode=='\000\005':
- error="Invalid Username or Password."
- else: error=repr(errorcode)
- self.error(error,errorurl)
- else:
- log.msg('hmm, weird tlvs for %s cookie packet' % str(self))
- log.msg(tlvs)
- log.msg('snac')
- log.msg(str(snac))
- return "None"
-
- def oscar_None(self,data): pass
-
- def connectToBOS(self, server, port):
- c = protocol.ClientCreator(reactor, self.BOSClass, self.username, self.cookie)
- return c.connectTCP(server, int(port))
-
- def error(self,error,url):
- log.msg("ERROR! %s %s" % (error,url))
- if self.deferred: self.deferred.errback((error,url))
- self.transport.loseConnection()
-
-FLAP_CHANNEL_NEW_CONNECTION = 0x01
-FLAP_CHANNEL_DATA = 0x02
-FLAP_CHANNEL_ERROR = 0x03
-FLAP_CHANNEL_CLOSE_CONNECTION = 0x04
-
-SERVICE_CHATNAV = 0x0d
-SERVICE_CHAT = 0x0e
-serviceClasses = {
- SERVICE_CHATNAV:ChatNavService,
- SERVICE_CHAT:ChatService
-}
-TLV_USERNAME = 0x0001
-TLV_CLIENTNAME = 0x0003
-TLV_COUNTRY = 0x000E
-TLV_LANG = 0x000F
-TLV_CLIENTMAJOR = 0x0017
-TLV_CLIENTMINOR = 0x0018
-TLV_CLIENTSUB = 0x001A
-TLV_PASSWORD = 0x0025
-TLV_USESSI = 0x004A
-
-CAP_ICON = '\011F\023FL\177\021\321\202"DEST\000\000'
-CAP_VOICE = '\011F\023AL\177\021\321\202"DEST\000\000'
-CAP_IMAGE = '\011F\023EL\177\021\321\202"DEST\000\000'
-CAP_CHAT = 't\217$ b\207\021\321\202"DEST\000\000'
-CAP_GET_FILE = '\011F\023HL\177\021\321\202"DEST\000\000'
-CAP_SEND_FILE = '\011F\023CL\177\021\321\202"DEST\000\000'
-CAP_GAMES = '\011F\023GL\177\021\321\202"DEST\000\000'
-CAP_SEND_LIST = '\011F\023KL\177\021\321\202"DEST\000\000'
-CAP_SERV_REL = '\011F\023IL\177\021\321\202"DEST\000\000'
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/service.py
deleted file mode 100755
index 0e4f8b6a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/service.py
+++ /dev/null
@@ -1,1223 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_service -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-A module that needs a better name.
-
-Implements new cred things for words.
-
-How does this thing work?
-
- - Network connection on some port expecting to speak some protocol
-
- - Protocol-specific authentication, resulting in some kind of credentials object
-
- - twisted.cred.portal login using those credentials for the interface
- IUser and with something implementing IChatClient as the mind
-
- - successful login results in an IUser avatar the protocol can call
- methods on, and state added to the realm such that the mind will have
- methods called on it as is necessary
-
- - protocol specific actions lead to calls onto the avatar; remote events
- lead to calls onto the mind
-
- - protocol specific hangup, realm is notified, user is removed from active
- play, the end.
-"""
-
-from time import time, ctime
-
-from zope.interface import implements
-
-from twisted.words import iwords, ewords
-
-from twisted.python.components import registerAdapter
-from twisted.cred import portal, credentials, error as ecred
-from twisted.spread import pb
-from twisted.words.protocols import irc
-from twisted.internet import defer, protocol
-from twisted.python import log, failure, reflect
-from twisted import copyright
-
-
-class Group(object):
- implements(iwords.IGroup)
-
- def __init__(self, name):
- self.name = name
- self.users = {}
- self.meta = {
- "topic": "",
- "topic_author": "",
- }
-
-
- def _ebUserCall(self, err, p):
- return failure.Failure(Exception(p, err))
-
-
- def _cbUserCall(self, results):
- for (success, result) in results:
- if not success:
- user, err = result.value # XXX
- self.remove(user, err.getErrorMessage())
-
-
- def add(self, user):
- assert iwords.IChatClient.providedBy(user), "%r is not a chat client" % (user,)
- if user.name not in self.users:
- additions = []
- self.users[user.name] = user
- for p in self.users.itervalues():
- if p is not user:
- d = defer.maybeDeferred(p.userJoined, self, user)
- d.addErrback(self._ebUserCall, p=p)
- additions.append(d)
- defer.DeferredList(additions).addCallback(self._cbUserCall)
- return defer.succeed(None)
-
-
- def remove(self, user, reason=None):
- assert reason is None or isinstance(reason, unicode)
- try:
- del self.users[user.name]
- except KeyError:
- pass
- else:
- removals = []
- for p in self.users.itervalues():
- if p is not user:
- d = defer.maybeDeferred(p.userLeft, self, user, reason)
- d.addErrback(self._ebUserCall, p=p)
- removals.append(d)
- defer.DeferredList(removals).addCallback(self._cbUserCall)
- return defer.succeed(None)
-
-
- def size(self):
- return defer.succeed(len(self.users))
-
-
- def receive(self, sender, recipient, message):
- assert recipient is self
- receives = []
- for p in self.users.itervalues():
- if p is not sender:
- d = defer.maybeDeferred(p.receive, sender, self, message)
- d.addErrback(self._ebUserCall, p=p)
- receives.append(d)
- defer.DeferredList(receives).addCallback(self._cbUserCall)
- return defer.succeed(None)
-
-
- def setMetadata(self, meta):
- self.meta = meta
- sets = []
- for p in self.users.itervalues():
- d = defer.maybeDeferred(p.groupMetaUpdate, self, meta)
- d.addErrback(self._ebUserCall, p=p)
- sets.append(d)
- defer.DeferredList(sets).addCallback(self._cbUserCall)
- return defer.succeed(None)
-
-
- def iterusers(self):
- # XXX Deferred?
- return iter(self.users.values())
-
-
-class User(object):
- implements(iwords.IUser)
-
- realm = None
- mind = None
-
- def __init__(self, name):
- self.name = name
- self.groups = []
- self.lastMessage = time()
-
-
- def loggedIn(self, realm, mind):
- self.realm = realm
- self.mind = mind
- self.signOn = time()
-
-
- def join(self, group):
- def cbJoin(result):
- self.groups.append(group)
- return result
- return group.add(self.mind).addCallback(cbJoin)
-
-
- def leave(self, group, reason=None):
- def cbLeave(result):
- self.groups.remove(group)
- return result
- return group.remove(self.mind, reason).addCallback(cbLeave)
-
-
- def send(self, recipient, message):
- self.lastMessage = time()
- return recipient.receive(self.mind, recipient, message)
-
-
- def itergroups(self):
- return iter(self.groups)
-
-
- def logout(self):
- for g in self.groups[:]:
- self.leave(g)
-
-
-NICKSERV = 'NickServ!NickServ@services'
-
-
-class IRCUser(irc.IRC):
- """
- Protocol instance representing an IRC user connected to the server.
- """
- implements(iwords.IChatClient)
-
- # A list of IGroups in which I am participating
- groups = None
-
- # A no-argument callable I should invoke when I go away
- logout = None
-
- # An IUser we use to interact with the chat service
- avatar = None
-
- # To whence I belong
- realm = None
-
- # How to handle unicode (TODO: Make this customizable on a per-user basis)
- encoding = 'utf-8'
-
- # Twisted callbacks
- def connectionMade(self):
- self.irc_PRIVMSG = self.irc_NICKSERV_PRIVMSG
- self.realm = self.factory.realm
- self.hostname = self.realm.name
-
-
- def connectionLost(self, reason):
- if self.logout is not None:
- self.logout()
- self.avatar = None
-
-
- # Make sendMessage a bit more useful to us
- def sendMessage(self, command, *parameter_list, **kw):
- if 'prefix' not in kw:
- kw['prefix'] = self.hostname
- if 'to' not in kw:
- kw['to'] = self.name.encode(self.encoding)
-
- arglist = [self, command, kw['to']] + list(parameter_list)
- irc.IRC.sendMessage(*arglist, **kw)
-
-
- # IChatClient implementation
- def userJoined(self, group, user):
- self.join(
- "%s!%s@%s" % (user.name, user.name, self.hostname),
- '#' + group.name)
-
-
- def userLeft(self, group, user, reason=None):
- assert reason is None or isinstance(reason, unicode)
- self.part(
- "%s!%s@%s" % (user.name, user.name, self.hostname),
- '#' + group.name,
- (reason or u"leaving").encode(self.encoding, 'replace'))
-
-
- def receive(self, sender, recipient, message):
- #>> :glyph!glyph@adsl-64-123-27-108.dsl.austtx.swbell.net PRIVMSG glyph_ :hello
-
- # omg???????????
- if iwords.IGroup.providedBy(recipient):
- recipientName = '#' + recipient.name
- else:
- recipientName = recipient.name
-
- text = message.get('text', '<an unrepresentable message>')
- for L in text.splitlines():
- self.privmsg(
- '%s!%s@%s' % (sender.name, sender.name, self.hostname),
- recipientName,
- L)
-
-
- def groupMetaUpdate(self, group, meta):
- if 'topic' in meta:
- topic = meta['topic']
- author = meta.get('topic_author', '')
- self.topic(
- self.name,
- '#' + group.name,
- topic,
- '%s!%s@%s' % (author, author, self.hostname)
- )
-
- # irc.IRC callbacks - starting with login related stuff.
- nickname = None
- password = None
-
- def irc_PASS(self, prefix, params):
- """Password message -- Register a password.
-
- Parameters: <password>
-
- [REQUIRED]
-
- Note that IRC requires the client send this *before* NICK
- and USER.
- """
- self.password = params[-1]
-
-
- def irc_NICK(self, prefix, params):
- """Nick message -- Set your nickname.
-
- Parameters: <nickname>
-
- [REQUIRED]
- """
- try:
- nickname = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.privmsg(
- NICKSERV,
- nickname,
- 'Your nickname is cannot be decoded. Please use ASCII or UTF-8.')
- self.transport.loseConnection()
- return
-
- self.nickname = nickname
- self.name = nickname
-
- for code, text in self._motdMessages:
- self.sendMessage(code, text % self.factory._serverInfo)
-
- if self.password is None:
- self.privmsg(
- NICKSERV,
- nickname,
- 'Password?')
- else:
- password = self.password
- self.password = None
- self.logInAs(nickname, password)
-
-
- def irc_USER(self, prefix, params):
- """User message -- Set your realname.
-
- Parameters: <user> <mode> <unused> <realname>
- """
- # Note: who gives a crap about this? The IUser has the real
- # information we care about. Save it anyway, I guess, just
- # for fun.
- self.realname = params[-1]
-
-
- def irc_NICKSERV_PRIVMSG(self, prefix, params):
- """Send a (private) message.
-
- Parameters: <msgtarget> <text to be sent>
- """
- target = params[0]
- password = params[-1]
-
- if self.nickname is None:
- # XXX Send an error response here
- self.transport.loseConnection()
- elif target.lower() != "nickserv":
- self.privmsg(
- NICKSERV,
- self.nickname,
- "Denied. Please send me (NickServ) your password.")
- else:
- nickname = self.nickname
- self.nickname = None
- self.logInAs(nickname, password)
-
-
- def logInAs(self, nickname, password):
- d = self.factory.portal.login(
- credentials.UsernamePassword(nickname, password),
- self,
- iwords.IUser)
- d.addCallbacks(self._cbLogin, self._ebLogin, errbackArgs=(nickname,))
-
-
- _welcomeMessages = [
- (irc.RPL_WELCOME,
- ":connected to Twisted IRC"),
- (irc.RPL_YOURHOST,
- ":Your host is %(serviceName)s, running version %(serviceVersion)s"),
- (irc.RPL_CREATED,
- ":This server was created on %(creationDate)s"),
-
- # "Bummer. This server returned a worthless 004 numeric.
- # I'll have to guess at all the values"
- # -- epic
- (irc.RPL_MYINFO,
- # w and n are the currently supported channel and user modes
- # -- specify this better
- "%(serviceName)s %(serviceVersion)s w n")
- ]
-
- _motdMessages = [
- (irc.RPL_MOTDSTART,
- ":- %(serviceName)s Message of the Day - "),
- (irc.RPL_ENDOFMOTD,
- ":End of /MOTD command.")
- ]
-
- def _cbLogin(self, (iface, avatar, logout)):
- assert iface is iwords.IUser, "Realm is buggy, got %r" % (iface,)
-
- # Let them send messages to the world
- del self.irc_PRIVMSG
-
- self.avatar = avatar
- self.logout = logout
- for code, text in self._welcomeMessages:
- self.sendMessage(code, text % self.factory._serverInfo)
-
-
- def _ebLogin(self, err, nickname):
- if err.check(ewords.AlreadyLoggedIn):
- self.privmsg(
- NICKSERV,
- nickname,
- "Already logged in. No pod people allowed!")
- elif err.check(ecred.UnauthorizedLogin):
- self.privmsg(
- NICKSERV,
- nickname,
- "Login failed. Goodbye.")
- else:
- log.msg("Unhandled error during login:")
- log.err(err)
- self.privmsg(
- NICKSERV,
- nickname,
- "Server error during login. Sorry.")
- self.transport.loseConnection()
-
-
- # Great, now that's out of the way, here's some of the interesting
- # bits
- def irc_PING(self, prefix, params):
- """Ping message
-
- Parameters: <server1> [ <server2> ]
- """
- if self.realm is not None:
- self.sendMessage('PONG', self.hostname)
-
-
- def irc_QUIT(self, prefix, params):
- """Quit
-
- Parameters: [ <Quit Message> ]
- """
- self.transport.loseConnection()
-
-
- def _channelMode(self, group, modes=None, *args):
- if modes:
- self.sendMessage(
- irc.ERR_UNKNOWNMODE,
- ":Unknown MODE flag.")
- else:
- self.channelMode(self.name, '#' + group.name, '+')
-
-
- def _userMode(self, user, modes=None):
- if modes:
- self.sendMessage(
- irc.ERR_UNKNOWNMODE,
- ":Unknown MODE flag.")
- elif user is self.avatar:
- self.sendMessage(
- irc.RPL_UMODEIS,
- "+")
- else:
- self.sendMessage(
- irc.ERR_USERSDONTMATCH,
- ":You can't look at someone else's modes.")
-
-
- def irc_MODE(self, prefix, params):
- """User mode message
-
- Parameters: <nickname>
- *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )
-
- """
- try:
- channelOrUser = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHNICK, params[0],
- ":No such nickname (could not decode your unicode!)")
- return
-
- if channelOrUser.startswith('#'):
- def ebGroup(err):
- err.trap(ewords.NoSuchGroup)
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, params[0],
- ":That channel doesn't exist.")
- d = self.realm.lookupGroup(channelOrUser[1:])
- d.addCallbacks(
- self._channelMode,
- ebGroup,
- callbackArgs=tuple(params[1:]))
- else:
- def ebUser(err):
- self.sendMessage(
- irc.ERR_NOSUCHNICK,
- ":No such nickname.")
-
- d = self.realm.lookupUser(channelOrUser)
- d.addCallbacks(
- self._userMode,
- ebUser,
- callbackArgs=tuple(params[1:]))
-
-
- def irc_USERHOST(self, prefix, params):
- """Userhost message
-
- Parameters: <nickname> *( SPACE <nickname> )
-
- [Optional]
- """
- pass
-
-
- def irc_PRIVMSG(self, prefix, params):
- """Send a (private) message.
-
- Parameters: <msgtarget> <text to be sent>
- """
- try:
- targetName = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHNICK, params[0],
- ":No such nick/channel (could not decode your unicode!)")
- return
-
- messageText = params[-1]
- if targetName.startswith('#'):
- target = self.realm.lookupGroup(targetName[1:])
- else:
- target = self.realm.lookupUser(targetName).addCallback(lambda user: user.mind)
-
- def cbTarget(targ):
- if targ is not None:
- return self.avatar.send(targ, {"text": messageText})
-
- def ebTarget(err):
- self.sendMessage(
- irc.ERR_NOSUCHNICK, targetName,
- ":No such nick/channel.")
-
- target.addCallbacks(cbTarget, ebTarget)
-
-
- def irc_JOIN(self, prefix, params):
- """Join message
-
- Parameters: ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] )
- """
- try:
- groupName = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, params[0],
- ":No such channel (could not decode your unicode!)")
- return
-
- if groupName.startswith('#'):
- groupName = groupName[1:]
-
- def cbGroup(group):
- def cbJoin(ign):
- self.userJoined(group, self)
- self.names(
- self.name,
- '#' + group.name,
- [user.name for user in group.iterusers()])
- self._sendTopic(group)
- return self.avatar.join(group).addCallback(cbJoin)
-
- def ebGroup(err):
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, '#' + groupName,
- ":No such channel.")
-
- self.realm.getGroup(groupName).addCallbacks(cbGroup, ebGroup)
-
-
- def irc_PART(self, prefix, params):
- """Part message
-
- Parameters: <channel> *( "," <channel> ) [ <Part Message> ]
- """
- try:
- groupName = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOTONCHANNEL, params[0],
- ":Could not decode your unicode!")
- return
-
- if groupName.startswith('#'):
- groupName = groupName[1:]
-
- if len(params) > 1:
- reason = params[1].decode('utf-8')
- else:
- reason = None
-
- def cbGroup(group):
- def cbLeave(result):
- self.userLeft(group, self, reason)
- return self.avatar.leave(group, reason).addCallback(cbLeave)
-
- def ebGroup(err):
- err.trap(ewords.NoSuchGroup)
- self.sendMessage(
- irc.ERR_NOTONCHANNEL,
- '#' + groupName,
- ":" + err.getErrorMessage())
-
- self.realm.lookupGroup(groupName).addCallbacks(cbGroup, ebGroup)
-
-
- def irc_NAMES(self, prefix, params):
- """Names message
-
- Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
- """
- #<< NAMES #python
- #>> :benford.openprojects.net 353 glyph = #python :Orban ... @glyph ... Zymurgy skreech
- #>> :benford.openprojects.net 366 glyph #python :End of /NAMES list.
- try:
- channel = params[-1].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, params[-1],
- ":No such channel (could not decode your unicode!)")
- return
-
- if channel.startswith('#'):
- channel = channel[1:]
-
- def cbGroup(group):
- self.names(
- self.name,
- '#' + group.name,
- [user.name for user in group.iterusers()])
-
- def ebGroup(err):
- err.trap(ewords.NoSuchGroup)
- # No group? Fine, no names!
- self.names(
- self.name,
- '#' + channel,
- [])
-
- self.realm.lookupGroup(channel).addCallbacks(cbGroup, ebGroup)
-
-
- def irc_TOPIC(self, prefix, params):
- """Topic message
-
- Parameters: <channel> [ <topic> ]
- """
- try:
- channel = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL,
- ":That channel doesn't exist (could not decode your unicode!)")
- return
-
- if channel.startswith('#'):
- channel = channel[1:]
-
- if len(params) > 1:
- self._setTopic(channel, params[1])
- else:
- self._getTopic(channel)
-
-
- def _sendTopic(self, group):
- """
- Send the topic of the given group to this user, if it has one.
- """
- topic = group.meta.get("topic")
- if topic:
- author = group.meta.get("topic_author") or "<noone>"
- date = group.meta.get("topic_date", 0)
- self.topic(self.name, '#' + group.name, topic)
- self.topicAuthor(self.name, '#' + group.name, author, date)
-
-
- def _getTopic(self, channel):
- #<< TOPIC #python
- #>> :benford.openprojects.net 332 glyph #python :<churchr> I really did. I sprained all my toes.
- #>> :benford.openprojects.net 333 glyph #python itamar|nyc 994713482
- def ebGroup(err):
- err.trap(ewords.NoSuchGroup)
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, '=', channel,
- ":That channel doesn't exist.")
-
- self.realm.lookupGroup(channel).addCallbacks(self._sendTopic, ebGroup)
-
-
- def _setTopic(self, channel, topic):
- #<< TOPIC #divunal :foo
- #>> :glyph!glyph@adsl-64-123-27-108.dsl.austtx.swbell.net TOPIC #divunal :foo
-
- def cbGroup(group):
- newMeta = group.meta.copy()
- newMeta['topic'] = topic
- newMeta['topic_author'] = self.name
- newMeta['topic_date'] = int(time())
-
- def ebSet(err):
- self.sendMessage(
- irc.ERR_CHANOPRIVSNEEDED,
- "#" + group.name,
- ":You need to be a channel operator to do that.")
-
- return group.setMetadata(newMeta).addErrback(ebSet)
-
- def ebGroup(err):
- err.trap(ewords.NoSuchGroup)
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, '=', channel,
- ":That channel doesn't exist.")
-
- self.realm.lookupGroup(channel).addCallbacks(cbGroup, ebGroup)
-
-
- def list(self, channels):
- """Send a group of LIST response lines
-
- @type channel: C{list} of C{(str, int, str)}
- @param channel: Information about the channels being sent:
- their name, the number of participants, and their topic.
- """
- for (name, size, topic) in channels:
- self.sendMessage(irc.RPL_LIST, name, str(size), ":" + topic)
- self.sendMessage(irc.RPL_LISTEND, ":End of /LIST")
-
-
- def irc_LIST(self, prefix, params):
- """List query
-
- Return information about the indicated channels, or about all
- channels if none are specified.
-
- Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
- """
- #<< list #python
- #>> :orwell.freenode.net 321 exarkun Channel :Users Name
- #>> :orwell.freenode.net 322 exarkun #python 358 :The Python programming language
- #>> :orwell.freenode.net 323 exarkun :End of /LIST
- if params:
- # Return information about indicated channels
- try:
- channels = params[0].decode(self.encoding).split(',')
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHCHANNEL, params[0],
- ":No such channel (could not decode your unicode!)")
- return
-
- groups = []
- for ch in channels:
- if ch.startswith('#'):
- ch = ch[1:]
- groups.append(self.realm.lookupGroup(ch))
-
- groups = defer.DeferredList(groups, consumeErrors=True)
- groups.addCallback(lambda gs: [r for (s, r) in gs if s])
- else:
- # Return information about all channels
- groups = self.realm.itergroups()
-
- def cbGroups(groups):
- def gotSize(size, group):
- return group.name, size, group.meta.get('topic')
- d = defer.DeferredList([
- group.size().addCallback(gotSize, group) for group in groups])
- d.addCallback(lambda results: self.list([r for (s, r) in results if s]))
- return d
- groups.addCallback(cbGroups)
-
-
- def _channelWho(self, group):
- self.who(self.name, '#' + group.name,
- [(m.name, self.hostname, self.realm.name, m.name, "H", 0, m.name) for m in group.iterusers()])
-
-
- def _userWho(self, user):
- self.sendMessage(irc.RPL_ENDOFWHO,
- ":User /WHO not implemented")
-
-
- def irc_WHO(self, prefix, params):
- """Who query
-
- Parameters: [ <mask> [ "o" ] ]
- """
- #<< who #python
- #>> :x.opn 352 glyph #python aquarius pc-62-31-193-114-du.blueyonder.co.uk y.opn Aquarius H :3 Aquarius
- # ...
- #>> :x.opn 352 glyph #python foobar europa.tranquility.net z.opn skreech H :0 skreech
- #>> :x.opn 315 glyph #python :End of /WHO list.
- ### also
- #<< who glyph
- #>> :x.opn 352 glyph #python glyph adsl-64-123-27-108.dsl.austtx.swbell.net x.opn glyph H :0 glyph
- #>> :x.opn 315 glyph glyph :End of /WHO list.
- if not params:
- self.sendMessage(irc.RPL_ENDOFWHO, ":/WHO not supported.")
- return
-
- try:
- channelOrUser = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.RPL_ENDOFWHO, params[0],
- ":End of /WHO list (could not decode your unicode!)")
- return
-
- if channelOrUser.startswith('#'):
- def ebGroup(err):
- err.trap(ewords.NoSuchGroup)
- self.sendMessage(
- irc.RPL_ENDOFWHO, channelOrUser,
- ":End of /WHO list.")
- d = self.realm.lookupGroup(channelOrUser[1:])
- d.addCallbacks(self._channelWho, ebGroup)
- else:
- def ebUser(err):
- err.trap(ewords.NoSuchUser)
- self.sendMessage(
- irc.RPL_ENDOFWHO, channelOrUser,
- ":End of /WHO list.")
- d = self.realm.lookupUser(channelOrUser)
- d.addCallbacks(self._userWho, ebUser)
-
-
-
- def irc_WHOIS(self, prefix, params):
- """Whois query
-
- Parameters: [ <target> ] <mask> *( "," <mask> )
- """
- def cbUser(user):
- self.whois(
- self.name,
- user.name, user.name, self.realm.name,
- user.name, self.realm.name, 'Hi mom!', False,
- int(time() - user.lastMessage), user.signOn,
- ['#' + group.name for group in user.itergroups()])
-
- def ebUser(err):
- err.trap(ewords.NoSuchUser)
- self.sendMessage(
- irc.ERR_NOSUCHNICK,
- params[0],
- ":No such nick/channel")
-
- try:
- user = params[0].decode(self.encoding)
- except UnicodeDecodeError:
- self.sendMessage(
- irc.ERR_NOSUCHNICK,
- params[0],
- ":No such nick/channel")
- return
-
- self.realm.lookupUser(user).addCallbacks(cbUser, ebUser)
-
-
- # Unsupported commands, here for legacy compatibility
- def irc_OPER(self, prefix, params):
- """Oper message
-
- Parameters: <name> <password>
- """
- self.sendMessage(irc.ERR_NOOPERHOST, ":O-lines not applicable")
-
-
-class IRCFactory(protocol.ServerFactory):
- """
- IRC server that creates instances of the L{IRCUser} protocol.
-
- @ivar _serverInfo: A dictionary mapping:
- "serviceName" to the name of the server,
- "serviceVersion" to the copyright version,
- "creationDate" to the time that the server was started.
- """
- protocol = IRCUser
-
- def __init__(self, realm, portal):
- self.realm = realm
- self.portal = portal
- self._serverInfo = {
- "serviceName": self.realm.name,
- "serviceVersion": copyright.version,
- "creationDate": ctime()
- }
-
-
-
-class PBMind(pb.Referenceable):
- def __init__(self):
- pass
-
- def jellyFor(self, jellier):
- return reflect.qual(PBMind), jellier.invoker.registerReference(self)
-
- def remote_userJoined(self, user, group):
- pass
-
- def remote_userLeft(self, user, group, reason):
- pass
-
- def remote_receive(self, sender, recipient, message):
- pass
-
- def remote_groupMetaUpdate(self, group, meta):
- pass
-
-
-class PBMindReference(pb.RemoteReference):
- implements(iwords.IChatClient)
-
- def receive(self, sender, recipient, message):
- if iwords.IGroup.providedBy(recipient):
- rec = PBGroup(self.realm, self.avatar, recipient)
- else:
- rec = PBUser(self.realm, self.avatar, recipient)
- return self.callRemote(
- 'receive',
- PBUser(self.realm, self.avatar, sender),
- rec,
- message)
-
- def groupMetaUpdate(self, group, meta):
- return self.callRemote(
- 'groupMetaUpdate',
- PBGroup(self.realm, self.avatar, group),
- meta)
-
- def userJoined(self, group, user):
- return self.callRemote(
- 'userJoined',
- PBGroup(self.realm, self.avatar, group),
- PBUser(self.realm, self.avatar, user))
-
- def userLeft(self, group, user, reason=None):
- assert reason is None or isinstance(reason, unicode)
- return self.callRemote(
- 'userLeft',
- PBGroup(self.realm, self.avatar, group),
- PBUser(self.realm, self.avatar, user),
- reason)
-pb.setUnjellyableForClass(PBMind, PBMindReference)
-
-
-class PBGroup(pb.Referenceable):
- def __init__(self, realm, avatar, group):
- self.realm = realm
- self.avatar = avatar
- self.group = group
-
-
- def processUniqueID(self):
- return hash((self.realm.name, self.avatar.name, self.group.name))
-
-
- def jellyFor(self, jellier):
- return reflect.qual(self.__class__), self.group.name.encode('utf-8'), jellier.invoker.registerReference(self)
-
-
- def remote_leave(self, reason=None):
- return self.avatar.leave(self.group, reason)
-
-
- def remote_send(self, message):
- return self.avatar.send(self.group, message)
-
-
-class PBGroupReference(pb.RemoteReference):
- implements(iwords.IGroup)
-
- def unjellyFor(self, unjellier, unjellyList):
- clsName, name, ref = unjellyList
- self.name = name.decode('utf-8')
- return pb.RemoteReference.unjellyFor(self, unjellier, [clsName, ref])
-
- def leave(self, reason=None):
- return self.callRemote("leave", reason)
-
- def send(self, message):
- return self.callRemote("send", message)
-pb.setUnjellyableForClass(PBGroup, PBGroupReference)
-
-class PBUser(pb.Referenceable):
- def __init__(self, realm, avatar, user):
- self.realm = realm
- self.avatar = avatar
- self.user = user
-
- def processUniqueID(self):
- return hash((self.realm.name, self.avatar.name, self.user.name))
-
-
-class ChatAvatar(pb.Referenceable):
- implements(iwords.IChatClient)
-
- def __init__(self, avatar):
- self.avatar = avatar
-
-
- def jellyFor(self, jellier):
- return reflect.qual(self.__class__), jellier.invoker.registerReference(self)
-
-
- def remote_join(self, groupName):
- assert isinstance(groupName, unicode)
- def cbGroup(group):
- def cbJoin(ignored):
- return PBGroup(self.avatar.realm, self.avatar, group)
- d = self.avatar.join(group)
- d.addCallback(cbJoin)
- return d
- d = self.avatar.realm.getGroup(groupName)
- d.addCallback(cbGroup)
- return d
-registerAdapter(ChatAvatar, iwords.IUser, pb.IPerspective)
-
-class AvatarReference(pb.RemoteReference):
- def join(self, groupName):
- return self.callRemote('join', groupName)
-
- def quit(self):
- d = defer.Deferred()
- self.broker.notifyOnDisconnect(lambda: d.callback(None))
- self.broker.transport.loseConnection()
- return d
-
-pb.setUnjellyableForClass(ChatAvatar, AvatarReference)
-
-
-class WordsRealm(object):
- implements(portal.IRealm, iwords.IChatService)
-
- _encoding = 'utf-8'
-
- def __init__(self, name):
- self.name = name
-
-
- def userFactory(self, name):
- return User(name)
-
-
- def groupFactory(self, name):
- return Group(name)
-
-
- def logoutFactory(self, avatar, facet):
- def logout():
- # XXX Deferred support here
- getattr(facet, 'logout', lambda: None)()
- avatar.realm = avatar.mind = None
- return logout
-
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if isinstance(avatarId, str):
- avatarId = avatarId.decode(self._encoding)
-
- def gotAvatar(avatar):
- if avatar.realm is not None:
- raise ewords.AlreadyLoggedIn()
- for iface in interfaces:
- facet = iface(avatar, None)
- if facet is not None:
- avatar.loggedIn(self, mind)
- mind.name = avatarId
- mind.realm = self
- mind.avatar = avatar
- return iface, facet, self.logoutFactory(avatar, facet)
- raise NotImplementedError(self, interfaces)
-
- return self.getUser(avatarId).addCallback(gotAvatar)
-
-
- # IChatService, mostly.
- createGroupOnRequest = False
- createUserOnRequest = True
-
- def lookupUser(self, name):
- raise NotImplementedError
-
-
- def lookupGroup(self, group):
- raise NotImplementedError
-
-
- def addUser(self, user):
- """Add the given user to this service.
-
- This is an internal method intented to be overridden by
- L{WordsRealm} subclasses, not called by external code.
-
- @type user: L{IUser}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with C{None} when the user is
- added, or which fails with
- L{twisted.words.ewords.DuplicateUser} if a user with the
- same name exists already.
- """
- raise NotImplementedError
-
-
- def addGroup(self, group):
- """Add the given group to this service.
-
- @type group: L{IGroup}
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: A Deferred which fires with C{None} when the group is
- added, or which fails with
- L{twisted.words.ewords.DuplicateGroup} if a group with the
- same name exists already.
- """
- raise NotImplementedError
-
-
- def getGroup(self, name):
- assert isinstance(name, unicode)
- if self.createGroupOnRequest:
- def ebGroup(err):
- err.trap(ewords.DuplicateGroup)
- return self.lookupGroup(name)
- return self.createGroup(name).addErrback(ebGroup)
- return self.lookupGroup(name)
-
-
- def getUser(self, name):
- assert isinstance(name, unicode)
- if self.createUserOnRequest:
- def ebUser(err):
- err.trap(ewords.DuplicateUser)
- return self.lookupUser(name)
- return self.createUser(name).addErrback(ebUser)
- return self.lookupUser(name)
-
-
- def createUser(self, name):
- assert isinstance(name, unicode)
- def cbLookup(user):
- return failure.Failure(ewords.DuplicateUser(name))
- def ebLookup(err):
- err.trap(ewords.NoSuchUser)
- return self.userFactory(name)
-
- name = name.lower()
- d = self.lookupUser(name)
- d.addCallbacks(cbLookup, ebLookup)
- d.addCallback(self.addUser)
- return d
-
-
- def createGroup(self, name):
- assert isinstance(name, unicode)
- def cbLookup(group):
- return failure.Failure(ewords.DuplicateGroup(name))
- def ebLookup(err):
- err.trap(ewords.NoSuchGroup)
- return self.groupFactory(name)
-
- name = name.lower()
- d = self.lookupGroup(name)
- d.addCallbacks(cbLookup, ebLookup)
- d.addCallback(self.addGroup)
- return d
-
-
-class InMemoryWordsRealm(WordsRealm):
- def __init__(self, *a, **kw):
- super(InMemoryWordsRealm, self).__init__(*a, **kw)
- self.users = {}
- self.groups = {}
-
-
- def itergroups(self):
- return defer.succeed(self.groups.itervalues())
-
-
- def addUser(self, user):
- if user.name in self.users:
- return defer.fail(failure.Failure(ewords.DuplicateUser()))
- self.users[user.name] = user
- return defer.succeed(user)
-
-
- def addGroup(self, group):
- if group.name in self.groups:
- return defer.fail(failure.Failure(ewords.DuplicateGroup()))
- self.groups[group.name] = group
- return defer.succeed(group)
-
-
- def lookupUser(self, name):
- assert isinstance(name, unicode)
- name = name.lower()
- try:
- user = self.users[name]
- except KeyError:
- return defer.fail(failure.Failure(ewords.NoSuchUser(name)))
- else:
- return defer.succeed(user)
-
-
- def lookupGroup(self, name):
- assert isinstance(name, unicode)
- name = name.lower()
- try:
- group = self.groups[name]
- except KeyError:
- return defer.fail(failure.Failure(ewords.NoSuchGroup(name)))
- else:
- return defer.succeed(group)
-
-__all__ = [
- 'Group', 'User',
-
- 'WordsRealm', 'InMemoryWordsRealm',
- ]
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/tap.py
deleted file mode 100755
index c0ba9fd0..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/tap.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_tap -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-"""
-Shiny new words service maker
-"""
-
-import sys, socket
-
-from twisted.application import strports
-from twisted.application.service import MultiService
-from twisted.python import usage
-from twisted import plugin
-
-from twisted.words import iwords, service
-from twisted.cred import checkers, credentials, portal, strcred
-
-class Options(usage.Options, strcred.AuthOptionMixin):
- supportedInterfaces = [credentials.IUsernamePassword]
- optParameters = [
- ('hostname', None, socket.gethostname(),
- 'Name of this server; purely an informative')]
-
- compData = usage.Completions(multiUse=["group"])
-
- interfacePlugins = {}
- plg = None
- for plg in plugin.getPlugins(iwords.IProtocolPlugin):
- assert plg.name not in interfacePlugins
- interfacePlugins[plg.name] = plg
- optParameters.append((
- plg.name + '-port',
- None, None,
- 'strports description of the port to bind for the ' + plg.name + ' server'))
- del plg
-
- def __init__(self, *a, **kw):
- usage.Options.__init__(self, *a, **kw)
- self['groups'] = []
-
- def opt_group(self, name):
- """Specify a group which should exist
- """
- self['groups'].append(name.decode(sys.stdin.encoding))
-
- def opt_passwd(self, filename):
- """
- Name of a passwd-style file. (This is for
- backwards-compatibility only; you should use the --auth
- command instead.)
- """
- self.addChecker(checkers.FilePasswordDB(filename))
-
-def makeService(config):
- credCheckers = config.get('credCheckers', [])
- wordsRealm = service.InMemoryWordsRealm(config['hostname'])
- wordsPortal = portal.Portal(wordsRealm, credCheckers)
-
- msvc = MultiService()
-
- # XXX Attribute lookup on config is kind of bad - hrm.
- for plgName in config.interfacePlugins:
- port = config.get(plgName + '-port')
- if port is not None:
- factory = config.interfacePlugins[plgName].getFactory(wordsRealm, wordsPortal)
- svc = strports.service(port, factory)
- svc.setServiceParent(msvc)
-
- # This is bogus. createGroup is async. makeService must be
- # allowed to return a Deferred or some crap.
- for g in config['groups']:
- wordsRealm.createGroup(g)
-
- return msvc
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/__init__.py
deleted file mode 100755
index d599f20d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"Words tests"
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basechat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basechat.py
deleted file mode 100755
index 8347d302..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basechat.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.im.basechat}.
-"""
-
-from twisted.trial import unittest
-from twisted.words.im import basechat, basesupport
-
-
-class ChatUITests(unittest.TestCase):
- """
- Tests for the L{basechat.ChatUI} chat client.
- """
- def setUp(self):
- self.ui = basechat.ChatUI()
- self.account = basesupport.AbstractAccount("fooAccount", False, "foo",
- "password", "host", "port")
- self.person = basesupport.AbstractPerson("foo", self.account)
-
-
- def test_contactChangedNickNoKey(self):
- """
- L{basechat.ChatUI.contactChangedNick} on an
- L{twisted.words.im.interfaces.IPerson} who doesn't have an account
- associated with the L{basechat.ChatUI} instance has no effect.
- """
- self.assertEqual(self.person.name, "foo")
- self.assertEqual(self.person.account, self.account)
-
- self.ui.contactChangedNick(self.person, "bar")
- self.assertEqual(self.person.name, "foo")
- self.assertEqual(self.person.account, self.account)
-
-
- def test_contactChangedNickNoConversation(self):
- """
- L{basechat.ChatUI.contactChangedNick} changes the name for an
- L{twisted.words.im.interfaces.IPerson}.
- """
- self.ui.persons[self.person.name, self.person.account] = self.person
-
- self.assertEqual(self.person.name, "foo")
- self.assertEqual(self.person.account, self.account)
-
- self.ui.contactChangedNick(self.person, "bar")
- self.assertEqual(self.person.name, "bar")
- self.assertEqual(self.person.account, self.account)
-
-
- def test_contactChangedNickHasConversation(self):
- """
- If an L{twisted.words.im.interfaces.IPerson} is in a
- L{basechat.Conversation}, L{basechat.ChatUI.contactChangedNick} causes a
- name change for that person in both the L{basechat.Conversation} and the
- L{basechat.ChatUI}.
- """
- self.ui.persons[self.person.name, self.person.account] = self.person
- conversation = basechat.Conversation(self.person, self.ui)
- self.ui.conversations[self.person] = conversation
-
- self.assertEqual(self.person.name, "foo")
- self.assertEqual(self.person.account, self.account)
-
- self.ui.contactChangedNick(self.person, "bar")
- self.assertEqual(self.person.name, "bar")
- self.assertEqual(self.person.account, self.account)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basesupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basesupport.py
deleted file mode 100755
index 3a819632..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_basesupport.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-from twisted.words.im import basesupport
-from twisted.internet import error, defer
-
-class DummyAccount(basesupport.AbstractAccount):
- """
- An account object that will do nothing when asked to start to log on.
- """
-
- loginHasFailed = False
- loginCallbackCalled = False
-
- def _startLogOn(self, *args):
- """
- Set self.loginDeferred to the same as the deferred returned, allowing a
- testcase to .callback or .errback.
-
- @return: A deferred.
- """
- self.loginDeferred = defer.Deferred()
- return self.loginDeferred
-
- def _loginFailed(self, result):
- self.loginHasFailed = True
- return basesupport.AbstractAccount._loginFailed(self, result)
-
- def _cb_logOn(self, result):
- self.loginCallbackCalled = True
- return basesupport.AbstractAccount._cb_logOn(self, result)
-
-class DummyUI(object):
- """
- Provide just the interface required to be passed to AbstractAccount.logOn.
- """
- clientRegistered = False
-
- def registerAccountClient(self, result):
- self.clientRegistered = True
-
-class ClientMsgTests(unittest.TestCase):
- def makeUI(self):
- return DummyUI()
-
- def makeAccount(self):
- return DummyAccount('la', False, 'la', None, 'localhost', 6667)
-
- def test_connect(self):
- """
- Test that account.logOn works, and it calls the right callback when a
- connection is established.
- """
- account = self.makeAccount()
- ui = self.makeUI()
- d = account.logOn(ui)
- account.loginDeferred.callback(None)
-
- def check(result):
- self.assert_(not account.loginHasFailed,
- "Login shouldn't have failed")
- self.assert_(account.loginCallbackCalled,
- "We should be logged in")
- d.addCallback(check)
- return d
-
- def test_failedConnect(self):
- """
- Test that account.logOn works, and it calls the right callback when a
- connection is established.
- """
- account = self.makeAccount()
- ui = self.makeUI()
- d = account.logOn(ui)
- account.loginDeferred.errback(Exception())
-
- def err(reason):
- self.assert_(account.loginHasFailed, "Login should have failed")
- self.assert_(not account.loginCallbackCalled,
- "We shouldn't be logged in")
- self.assert_(not ui.clientRegistered,
- "Client shouldn't be registered in the UI")
- cb = lambda r: self.assert_(False, "Shouldn't get called back")
- d.addCallbacks(cb, err)
- return d
-
- def test_alreadyConnecting(self):
- """
- Test that it can fail sensibly when someone tried to connect before
- we did.
- """
- account = self.makeAccount()
- ui = self.makeUI()
- account.logOn(ui)
- self.assertRaises(error.ConnectError, account.logOn, ui)
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_domish.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_domish.py
deleted file mode 100755
index 275afb74..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_domish.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.xish.domish}, a DOM-like library for XMPP.
-"""
-
-from twisted.trial import unittest
-from twisted.words.xish import domish
-
-
-class DomishTestCase(unittest.TestCase):
- def testEscaping(self):
- s = "&<>'\""
- self.assertEqual(domish.escapeToXml(s), "&amp;&lt;&gt;'\"")
- self.assertEqual(domish.escapeToXml(s, 1), "&amp;&lt;&gt;&apos;&quot;")
-
- def testNamespaceObject(self):
- ns = domish.Namespace("testns")
- self.assertEqual(ns.foo, ("testns", "foo"))
-
- def testElementInit(self):
- e = domish.Element((None, "foo"))
- self.assertEqual(e.name, "foo")
- self.assertEqual(e.uri, None)
- self.assertEqual(e.defaultUri, None)
- self.assertEqual(e.parent, None)
-
- e = domish.Element(("", "foo"))
- self.assertEqual(e.name, "foo")
- self.assertEqual(e.uri, "")
- self.assertEqual(e.defaultUri, "")
- self.assertEqual(e.parent, None)
-
- e = domish.Element(("testns", "foo"))
- self.assertEqual(e.name, "foo")
- self.assertEqual(e.uri, "testns")
- self.assertEqual(e.defaultUri, "testns")
- self.assertEqual(e.parent, None)
-
- e = domish.Element(("testns", "foo"), "test2ns")
- self.assertEqual(e.name, "foo")
- self.assertEqual(e.uri, "testns")
- self.assertEqual(e.defaultUri, "test2ns")
-
- def testChildOps(self):
- e = domish.Element(("testns", "foo"))
- e.addContent("somecontent")
- b2 = e.addElement(("testns2", "bar2"))
- e["attrib1"] = "value1"
- e[("testns2", "attrib2")] = "value2"
- e.addElement("bar")
- e.addElement("bar")
- e.addContent("abc")
- e.addContent("123")
-
- # Check content merging
- self.assertEqual(e.children[-1], "abc123")
-
- # Check str()/content extraction
- self.assertEqual(str(e), "somecontent")
-
- # Check direct child accessor
- self.assertEqual(e.bar2, b2)
- e.bar2.addContent("subcontent")
- e.bar2["bar2value"] = "somevalue"
-
- # Check child ops
- self.assertEqual(e.children[1], e.bar2)
- self.assertEqual(e.children[2], e.bar)
-
- # Check attribute ops
- self.assertEqual(e["attrib1"], "value1")
- del e["attrib1"]
- self.assertEqual(e.hasAttribute("attrib1"), 0)
- self.assertEqual(e.hasAttribute("attrib2"), 0)
- self.assertEqual(e[("testns2", "attrib2")], "value2")
-
-
- def test_elements(self):
- """
- Calling C{elements} without arguments on a L{domish.Element} returns
- all child elements, whatever the qualfied name.
- """
- e = domish.Element((u"testns", u"foo"))
- c1 = e.addElement(u"name")
- c2 = e.addElement((u"testns2", u"baz"))
- c3 = e.addElement(u"quux")
- c4 = e.addElement((u"testns", u"name"))
-
- elts = list(e.elements())
-
- self.assertIn(c1, elts)
- self.assertIn(c2, elts)
- self.assertIn(c3, elts)
- self.assertIn(c4, elts)
-
-
- def test_elementsWithQN(self):
- """
- Calling C{elements} with a namespace and local name on a
- L{domish.Element} returns all child elements with that qualified name.
- """
- e = domish.Element((u"testns", u"foo"))
- c1 = e.addElement(u"name")
- c2 = e.addElement((u"testns2", u"baz"))
- c3 = e.addElement(u"quux")
- c4 = e.addElement((u"testns", u"name"))
-
- elts = list(e.elements(u"testns", u"name"))
-
- self.assertIn(c1, elts)
- self.assertNotIn(c2, elts)
- self.assertNotIn(c3, elts)
- self.assertIn(c4, elts)
-
-
-
-class DomishStreamTestsMixin:
- """
- Mixin defining tests for different stream implementations.
-
- @ivar streamClass: A no-argument callable which will be used to create an
- XML parser which can produce a stream of elements from incremental
- input.
- """
- def setUp(self):
- self.doc_started = False
- self.doc_ended = False
- self.root = None
- self.elements = []
- self.stream = self.streamClass()
- self.stream.DocumentStartEvent = self._docStarted
- self.stream.ElementEvent = self.elements.append
- self.stream.DocumentEndEvent = self._docEnded
-
- def _docStarted(self, root):
- self.root = root
- self.doc_started = True
-
- def _docEnded(self):
- self.doc_ended = True
-
- def doTest(self, xml):
- self.stream.parse(xml)
-
- def testHarness(self):
- xml = "<root><child/><child2/></root>"
- self.stream.parse(xml)
- self.assertEqual(self.doc_started, True)
- self.assertEqual(self.root.name, 'root')
- self.assertEqual(self.elements[0].name, 'child')
- self.assertEqual(self.elements[1].name, 'child2')
- self.assertEqual(self.doc_ended, True)
-
- def testBasic(self):
- xml = "<stream:stream xmlns:stream='etherx' xmlns='jabber'>\n" + \
- " <message to='bar'>" + \
- " <x xmlns='xdelay'>some&amp;data&gt;</x>" + \
- " </message>" + \
- "</stream:stream>"
-
- self.stream.parse(xml)
- self.assertEqual(self.root.name, 'stream')
- self.assertEqual(self.root.uri, 'etherx')
- self.assertEqual(self.elements[0].name, 'message')
- self.assertEqual(self.elements[0].uri, 'jabber')
- self.assertEqual(self.elements[0]['to'], 'bar')
- self.assertEqual(self.elements[0].x.uri, 'xdelay')
- self.assertEqual(unicode(self.elements[0].x), 'some&data>')
-
- def testNoRootNS(self):
- xml = "<stream><error xmlns='etherx'/></stream>"
-
- self.stream.parse(xml)
- self.assertEqual(self.root.uri, '')
- self.assertEqual(self.elements[0].uri, 'etherx')
-
- def testNoDefaultNS(self):
- xml = "<stream:stream xmlns:stream='etherx'><error/></stream:stream>"""
-
- self.stream.parse(xml)
- self.assertEqual(self.root.uri, 'etherx')
- self.assertEqual(self.root.defaultUri, '')
- self.assertEqual(self.elements[0].uri, '')
- self.assertEqual(self.elements[0].defaultUri, '')
-
- def testChildDefaultNS(self):
- xml = "<root xmlns='testns'><child/></root>"
-
- self.stream.parse(xml)
- self.assertEqual(self.root.uri, 'testns')
- self.assertEqual(self.elements[0].uri, 'testns')
-
- def testEmptyChildNS(self):
- xml = "<root xmlns='testns'><child1><child2 xmlns=''/></child1></root>"
-
- self.stream.parse(xml)
- self.assertEqual(self.elements[0].child2.uri, '')
-
-
- def test_namespaceWithWhitespace(self):
- """
- Whitespace in an xmlns value is preserved in the resulting node's C{uri}
- attribute.
- """
- xml = "<root xmlns:foo=' bar baz '><foo:bar foo:baz='quux'/></root>"
- self.stream.parse(xml)
- self.assertEqual(self.elements[0].uri, " bar baz ")
- self.assertEqual(
- self.elements[0].attributes, {(" bar baz ", "baz"): "quux"})
-
-
- def testChildPrefix(self):
- xml = "<root xmlns='testns' xmlns:foo='testns2'><foo:child/></root>"
-
- self.stream.parse(xml)
- self.assertEqual(self.root.localPrefixes['foo'], 'testns2')
- self.assertEqual(self.elements[0].uri, 'testns2')
-
- def testUnclosedElement(self):
- self.assertRaises(domish.ParserError, self.stream.parse,
- "<root><error></root>")
-
- def test_namespaceReuse(self):
- """
- Test that reuse of namespaces does affect an element's serialization.
-
- When one element uses a prefix for a certain namespace, this is
- stored in the C{localPrefixes} attribute of the element. We want
- to make sure that elements created after such use, won't have this
- prefix end up in their C{localPrefixes} attribute, too.
- """
-
- xml = """<root>
- <foo:child1 xmlns:foo='testns'/>
- <child2 xmlns='testns'/>
- </root>"""
-
- self.stream.parse(xml)
- self.assertEqual('child1', self.elements[0].name)
- self.assertEqual('testns', self.elements[0].uri)
- self.assertEqual('', self.elements[0].defaultUri)
- self.assertEqual({'foo': 'testns'}, self.elements[0].localPrefixes)
- self.assertEqual('child2', self.elements[1].name)
- self.assertEqual('testns', self.elements[1].uri)
- self.assertEqual('testns', self.elements[1].defaultUri)
- self.assertEqual({}, self.elements[1].localPrefixes)
-
-
-
-class DomishExpatStreamTestCase(DomishStreamTestsMixin, unittest.TestCase):
- """
- Tests for L{domish.ExpatElementStream}, the expat-based element stream
- implementation.
- """
- streamClass = domish.ExpatElementStream
-
- try:
- import pyexpat
- except ImportError:
- skip = "pyexpat is required for ExpatElementStream tests."
-
-
-
-class DomishSuxStreamTestCase(DomishStreamTestsMixin, unittest.TestCase):
- """
- Tests for L{domish.SuxElementStream}, the L{twisted.web.sux}-based element
- stream implementation.
- """
- streamClass = domish.SuxElementStream
-
- if domish.SuxElementStream is None:
- skip = "twisted.web is required for SuxElementStream tests."
-
-
-
-class SerializerTests(unittest.TestCase):
- def testNoNamespace(self):
- e = domish.Element((None, "foo"))
- self.assertEqual(e.toXml(), "<foo/>")
- self.assertEqual(e.toXml(closeElement = 0), "<foo>")
-
- def testDefaultNamespace(self):
- e = domish.Element(("testns", "foo"))
- self.assertEqual(e.toXml(), "<foo xmlns='testns'/>")
-
- def testOtherNamespace(self):
- e = domish.Element(("testns", "foo"), "testns2")
- self.assertEqual(e.toXml({'testns': 'bar'}),
- "<bar:foo xmlns:bar='testns' xmlns='testns2'/>")
-
- def testChildDefaultNamespace(self):
- e = domish.Element(("testns", "foo"))
- e.addElement("bar")
- self.assertEqual(e.toXml(), "<foo xmlns='testns'><bar/></foo>")
-
- def testChildSameNamespace(self):
- e = domish.Element(("testns", "foo"))
- e.addElement(("testns", "bar"))
- self.assertEqual(e.toXml(), "<foo xmlns='testns'><bar/></foo>")
-
- def testChildSameDefaultNamespace(self):
- e = domish.Element(("testns", "foo"))
- e.addElement("bar", "testns")
- self.assertEqual(e.toXml(), "<foo xmlns='testns'><bar/></foo>")
-
- def testChildOtherDefaultNamespace(self):
- e = domish.Element(("testns", "foo"))
- e.addElement(("testns2", "bar"), 'testns2')
- self.assertEqual(e.toXml(), "<foo xmlns='testns'><bar xmlns='testns2'/></foo>")
-
- def testOnlyChildDefaultNamespace(self):
- e = domish.Element((None, "foo"))
- e.addElement(("ns2", "bar"), 'ns2')
- self.assertEqual(e.toXml(), "<foo><bar xmlns='ns2'/></foo>")
-
- def testOnlyChildDefaultNamespace2(self):
- e = domish.Element((None, "foo"))
- e.addElement("bar")
- self.assertEqual(e.toXml(), "<foo><bar/></foo>")
-
- def testChildInDefaultNamespace(self):
- e = domish.Element(("testns", "foo"), "testns2")
- e.addElement(("testns2", "bar"))
- self.assertEqual(e.toXml(), "<xn0:foo xmlns:xn0='testns' xmlns='testns2'><bar/></xn0:foo>")
-
- def testQualifiedAttribute(self):
- e = domish.Element((None, "foo"),
- attribs = {("testns2", "bar"): "baz"})
- self.assertEqual(e.toXml(), "<foo xmlns:xn0='testns2' xn0:bar='baz'/>")
-
- def testQualifiedAttributeDefaultNS(self):
- e = domish.Element(("testns", "foo"),
- attribs = {("testns", "bar"): "baz"})
- self.assertEqual(e.toXml(), "<foo xmlns='testns' xmlns:xn0='testns' xn0:bar='baz'/>")
-
- def testTwoChilds(self):
- e = domish.Element(('', "foo"))
- child1 = e.addElement(("testns", "bar"), "testns2")
- child1.addElement(('testns2', 'quux'))
- child2 = e.addElement(("testns3", "baz"), "testns4")
- child2.addElement(('testns', 'quux'))
- self.assertEqual(e.toXml(), "<foo><xn0:bar xmlns:xn0='testns' xmlns='testns2'><quux/></xn0:bar><xn1:baz xmlns:xn1='testns3' xmlns='testns4'><xn0:quux xmlns:xn0='testns'/></xn1:baz></foo>")
-
- def testXMLNamespace(self):
- e = domish.Element((None, "foo"),
- attribs = {("http://www.w3.org/XML/1998/namespace",
- "lang"): "en_US"})
- self.assertEqual(e.toXml(), "<foo xml:lang='en_US'/>")
-
- def testQualifiedAttributeGivenListOfPrefixes(self):
- e = domish.Element((None, "foo"),
- attribs = {("testns2", "bar"): "baz"})
- self.assertEqual(e.toXml({"testns2": "qux"}),
- "<foo xmlns:qux='testns2' qux:bar='baz'/>")
-
- def testNSPrefix(self):
- e = domish.Element((None, "foo"),
- attribs = {("testns2", "bar"): "baz"})
- c = e.addElement(("testns2", "qux"))
- c[("testns2", "bar")] = "quux"
-
- self.assertEqual(e.toXml(), "<foo xmlns:xn0='testns2' xn0:bar='baz'><xn0:qux xn0:bar='quux'/></foo>")
-
- def testDefaultNSPrefix(self):
- e = domish.Element((None, "foo"),
- attribs = {("testns2", "bar"): "baz"})
- c = e.addElement(("testns2", "qux"))
- c[("testns2", "bar")] = "quux"
- c.addElement('foo')
-
- self.assertEqual(e.toXml(), "<foo xmlns:xn0='testns2' xn0:bar='baz'><xn0:qux xn0:bar='quux'><xn0:foo/></xn0:qux></foo>")
-
- def testPrefixScope(self):
- e = domish.Element(('testns', 'foo'))
-
- self.assertEqual(e.toXml(prefixes={'testns': 'bar'},
- prefixesInScope=['bar']),
- "<bar:foo/>")
-
- def testLocalPrefixes(self):
- e = domish.Element(('testns', 'foo'), localPrefixes={'bar': 'testns'})
- self.assertEqual(e.toXml(), "<bar:foo xmlns:bar='testns'/>")
-
- def testLocalPrefixesWithChild(self):
- e = domish.Element(('testns', 'foo'), localPrefixes={'bar': 'testns'})
- e.addElement('baz')
- self.assertIdentical(e.baz.defaultUri, None)
- self.assertEqual(e.toXml(), "<bar:foo xmlns:bar='testns'><baz/></bar:foo>")
-
- def test_prefixesReuse(self):
- """
- Test that prefixes passed to serialization are not modified.
-
- This test makes sure that passing a dictionary of prefixes repeatedly
- to C{toXml} of elements does not cause serialization errors. A
- previous implementation changed the passed in dictionary internally,
- causing havoc later on.
- """
- prefixes = {'testns': 'foo'}
-
- # test passing of dictionary
- s = domish.SerializerClass(prefixes=prefixes)
- self.assertNotIdentical(prefixes, s.prefixes)
-
- # test proper serialization on prefixes reuse
- e = domish.Element(('testns2', 'foo'),
- localPrefixes={'quux': 'testns2'})
- self.assertEqual("<quux:foo xmlns:quux='testns2'/>",
- e.toXml(prefixes=prefixes))
- e = domish.Element(('testns2', 'foo'))
- self.assertEqual("<foo xmlns='testns2'/>",
- e.toXml(prefixes=prefixes))
-
- def testRawXMLSerialization(self):
- e = domish.Element((None, "foo"))
- e.addRawXml("<abc123>")
- # The testcase below should NOT generate valid XML -- that's
- # the whole point of using the raw XML call -- it's the callers
- # responsiblity to ensure that the data inserted is valid
- self.assertEqual(e.toXml(), "<foo><abc123></foo>")
-
- def testRawXMLWithUnicodeSerialization(self):
- e = domish.Element((None, "foo"))
- e.addRawXml(u"<degree>\u00B0</degree>")
- self.assertEqual(e.toXml(), u"<foo><degree>\u00B0</degree></foo>")
-
- def testUnicodeSerialization(self):
- e = domish.Element((None, "foo"))
- e["test"] = u"my value\u0221e"
- e.addContent(u"A degree symbol...\u00B0")
- self.assertEqual(e.toXml(),
- u"<foo test='my value\u0221e'>A degree symbol...\u00B0</foo>")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc.py
deleted file mode 100755
index ffda6894..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc.py
+++ /dev/null
@@ -1,1898 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.irc}.
-"""
-
-import time
-
-from twisted.trial import unittest
-from twisted.trial.unittest import TestCase
-from twisted.words.protocols import irc
-from twisted.words.protocols.irc import IRCClient
-from twisted.internet import protocol, task
-from twisted.test.proto_helpers import StringTransport, StringIOWithoutClosing
-
-
-
-class ModeParsingTests(unittest.TestCase):
- """
- Tests for L{twisted.words.protocols.irc.parseModes}.
- """
- paramModes = ('klb', 'b')
-
-
- def test_emptyModes(self):
- """
- Parsing an empty mode string raises L{irc.IRCBadModes}.
- """
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '', [])
-
-
- def test_emptyModeSequence(self):
- """
- Parsing a mode string that contains an empty sequence (either a C{+} or
- C{-} followed directly by another C{+} or C{-}, or not followed by
- anything at all) raises L{irc.IRCBadModes}.
- """
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '++k', [])
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '-+k', [])
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '+', [])
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '-', [])
-
-
- def test_malformedModes(self):
- """
- Parsing a mode string that does not start with C{+} or C{-} raises
- L{irc.IRCBadModes}.
- """
- self.assertRaises(irc.IRCBadModes, irc.parseModes, 'foo', [])
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '%', [])
-
-
- def test_nullModes(self):
- """
- Parsing a mode string that contains no mode characters raises
- L{irc.IRCBadModes}.
- """
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '+', [])
- self.assertRaises(irc.IRCBadModes, irc.parseModes, '-', [])
-
-
- def test_singleMode(self):
- """
- Parsing a single mode setting with no parameters results in that mode,
- with no parameters, in the "added" direction and no modes in the
- "removed" direction.
- """
- added, removed = irc.parseModes('+s', [])
- self.assertEqual(added, [('s', None)])
- self.assertEqual(removed, [])
-
- added, removed = irc.parseModes('-s', [])
- self.assertEqual(added, [])
- self.assertEqual(removed, [('s', None)])
-
-
- def test_singleDirection(self):
- """
- Parsing a single-direction mode setting with multiple modes and no
- parameters, results in all modes falling into the same direction group.
- """
- added, removed = irc.parseModes('+stn', [])
- self.assertEqual(added, [('s', None),
- ('t', None),
- ('n', None)])
- self.assertEqual(removed, [])
-
- added, removed = irc.parseModes('-nt', [])
- self.assertEqual(added, [])
- self.assertEqual(removed, [('n', None),
- ('t', None)])
-
-
- def test_multiDirection(self):
- """
- Parsing a multi-direction mode setting with no parameters.
- """
- added, removed = irc.parseModes('+s-n+ti', [])
- self.assertEqual(added, [('s', None),
- ('t', None),
- ('i', None)])
- self.assertEqual(removed, [('n', None)])
-
-
- def test_consecutiveDirection(self):
- """
- Parsing a multi-direction mode setting containing two consecutive mode
- sequences with the same direction results in the same result as if
- there were only one mode sequence in the same direction.
- """
- added, removed = irc.parseModes('+sn+ti', [])
- self.assertEqual(added, [('s', None),
- ('n', None),
- ('t', None),
- ('i', None)])
- self.assertEqual(removed, [])
-
-
- def test_mismatchedParams(self):
- """
- If the number of mode parameters does not match the number of modes
- expecting parameters, L{irc.IRCBadModes} is raised.
- """
- self.assertRaises(irc.IRCBadModes,
- irc.parseModes,
- '+k', [],
- self.paramModes)
- self.assertRaises(irc.IRCBadModes,
- irc.parseModes,
- '+kl', ['foo', '10', 'lulz_extra_param'],
- self.paramModes)
-
-
- def test_parameters(self):
- """
- Modes which require parameters are parsed and paired with their relevant
- parameter, modes which do not require parameters do not consume any of
- the parameters.
- """
- added, removed = irc.parseModes(
- '+klbb',
- ['somekey', '42', 'nick!user@host', 'other!*@*'],
- self.paramModes)
- self.assertEqual(added, [('k', 'somekey'),
- ('l', '42'),
- ('b', 'nick!user@host'),
- ('b', 'other!*@*')])
- self.assertEqual(removed, [])
-
- added, removed = irc.parseModes(
- '-klbb',
- ['nick!user@host', 'other!*@*'],
- self.paramModes)
- self.assertEqual(added, [])
- self.assertEqual(removed, [('k', None),
- ('l', None),
- ('b', 'nick!user@host'),
- ('b', 'other!*@*')])
-
- # Mix a no-argument mode in with argument modes.
- added, removed = irc.parseModes(
- '+knbb',
- ['somekey', 'nick!user@host', 'other!*@*'],
- self.paramModes)
- self.assertEqual(added, [('k', 'somekey'),
- ('n', None),
- ('b', 'nick!user@host'),
- ('b', 'other!*@*')])
- self.assertEqual(removed, [])
-
-
-
-stringSubjects = [
- "Hello, this is a nice string with no complications.",
- "xargs%(NUL)smight%(NUL)slike%(NUL)sthis" % {'NUL': irc.NUL },
- "embedded%(CR)snewline%(CR)s%(NL)sFUN%(NL)s" % {'CR': irc.CR,
- 'NL': irc.NL},
- "escape!%(X)s escape!%(M)s %(X)s%(X)sa %(M)s0" % {'X': irc.X_QUOTE,
- 'M': irc.M_QUOTE}
- ]
-
-
-class QuotingTest(unittest.TestCase):
- def test_lowquoteSanity(self):
- """
- Testing client-server level quote/dequote.
- """
- for s in stringSubjects:
- self.assertEqual(s, irc.lowDequote(irc.lowQuote(s)))
-
-
- def test_ctcpquoteSanity(self):
- """
- Testing CTCP message level quote/dequote.
- """
- for s in stringSubjects:
- self.assertEqual(s, irc.ctcpDequote(irc.ctcpQuote(s)))
-
-
-
-class Dispatcher(irc._CommandDispatcherMixin):
- """
- A dispatcher that exposes one known command and handles unknown commands.
- """
- prefix = 'disp'
-
- def disp_working(self, a, b):
- """
- A known command that returns its input.
- """
- return a, b
-
-
- def disp_unknown(self, name, a, b):
- """
- Handle unknown commands by returning their name and inputs.
- """
- return name, a, b
-
-
-
-class DispatcherTests(unittest.TestCase):
- """
- Tests for L{irc._CommandDispatcherMixin}.
- """
- def test_dispatch(self):
- """
- Dispatching a command invokes the correct handler.
- """
- disp = Dispatcher()
- args = (1, 2)
- res = disp.dispatch('working', *args)
- self.assertEqual(res, args)
-
-
- def test_dispatchUnknown(self):
- """
- Dispatching an unknown command invokes the default handler.
- """
- disp = Dispatcher()
- name = 'missing'
- args = (1, 2)
- res = disp.dispatch(name, *args)
- self.assertEqual(res, (name,) + args)
-
-
- def test_dispatchMissingUnknown(self):
- """
- Dispatching an unknown command, when no default handler is present,
- results in an exception being raised.
- """
- disp = Dispatcher()
- disp.disp_unknown = None
- self.assertRaises(irc.UnhandledCommand, disp.dispatch, 'bar')
-
-
-
-class ServerSupportedFeatureTests(unittest.TestCase):
- """
- Tests for L{ServerSupportedFeatures} and related functions.
- """
- def test_intOrDefault(self):
- """
- L{_intOrDefault} converts values to C{int} if possible, otherwise
- returns a default value.
- """
- self.assertEqual(irc._intOrDefault(None), None)
- self.assertEqual(irc._intOrDefault([]), None)
- self.assertEqual(irc._intOrDefault(''), None)
- self.assertEqual(irc._intOrDefault('hello', 5), 5)
- self.assertEqual(irc._intOrDefault('123'), 123)
- self.assertEqual(irc._intOrDefault(123), 123)
-
-
- def test_splitParam(self):
- """
- L{ServerSupportedFeatures._splitParam} splits ISUPPORT parameters
- into key and values. Parameters without a separator are split into a
- key and a list containing only the empty string. Escaped parameters
- are unescaped.
- """
- params = [('FOO', ('FOO', [''])),
- ('FOO=', ('FOO', [''])),
- ('FOO=1', ('FOO', ['1'])),
- ('FOO=1,2,3', ('FOO', ['1', '2', '3'])),
- ('FOO=A\\x20B', ('FOO', ['A B'])),
- ('FOO=\\x5Cx', ('FOO', ['\\x'])),
- ('FOO=\\', ('FOO', ['\\'])),
- ('FOO=\\n', ('FOO', ['\\n']))]
-
- _splitParam = irc.ServerSupportedFeatures._splitParam
-
- for param, expected in params:
- res = _splitParam(param)
- self.assertEqual(res, expected)
-
- self.assertRaises(ValueError, _splitParam, 'FOO=\\x')
- self.assertRaises(ValueError, _splitParam, 'FOO=\\xNN')
- self.assertRaises(ValueError, _splitParam, 'FOO=\\xN')
- self.assertRaises(ValueError, _splitParam, 'FOO=\\x20\\x')
-
-
- def test_splitParamArgs(self):
- """
- L{ServerSupportedFeatures._splitParamArgs} splits ISUPPORT parameter
- arguments into key and value. Arguments without a separator are
- split into a key and an empty string.
- """
- res = irc.ServerSupportedFeatures._splitParamArgs(['A:1', 'B:2', 'C:', 'D'])
- self.assertEqual(res, [('A', '1'),
- ('B', '2'),
- ('C', ''),
- ('D', '')])
-
-
- def test_splitParamArgsProcessor(self):
- """
- L{ServerSupportedFeatures._splitParamArgs} uses the argument processor
- passed to to convert ISUPPORT argument values to some more suitable
- form.
- """
- res = irc.ServerSupportedFeatures._splitParamArgs(['A:1', 'B:2', 'C'],
- irc._intOrDefault)
- self.assertEqual(res, [('A', 1),
- ('B', 2),
- ('C', None)])
-
-
- def test_parsePrefixParam(self):
- """
- L{ServerSupportedFeatures._parsePrefixParam} parses the ISUPPORT PREFIX
- parameter into a mapping from modes to prefix symbols, returns
- C{None} if there is no parseable prefix parameter or raises
- C{ValueError} if the prefix parameter is malformed.
- """
- _parsePrefixParam = irc.ServerSupportedFeatures._parsePrefixParam
- self.assertEqual(_parsePrefixParam(''), None)
- self.assertRaises(ValueError, _parsePrefixParam, 'hello')
- self.assertEqual(_parsePrefixParam('(ov)@+'),
- {'o': ('@', 0),
- 'v': ('+', 1)})
-
-
- def test_parseChanModesParam(self):
- """
- L{ServerSupportedFeatures._parseChanModesParam} parses the ISUPPORT
- CHANMODES parameter into a mapping from mode categories to mode
- characters. Passing fewer than 4 parameters results in the empty string
- for the relevant categories. Passing more than 4 parameters raises
- C{ValueError}.
- """
- _parseChanModesParam = irc.ServerSupportedFeatures._parseChanModesParam
- self.assertEqual(
- _parseChanModesParam([]),
- {'addressModes': '',
- 'param': '',
- 'setParam': '',
- 'noParam': ''})
-
- self.assertEqual(
- _parseChanModesParam(['b', 'k', 'l', 'imnpst']),
- {'addressModes': 'b',
- 'param': 'k',
- 'setParam': 'l',
- 'noParam': 'imnpst'})
-
- self.assertEqual(
- _parseChanModesParam(['b', 'k', 'l']),
- {'addressModes': 'b',
- 'param': 'k',
- 'setParam': 'l',
- 'noParam': ''})
-
- self.assertRaises(
- ValueError,
- _parseChanModesParam, ['a', 'b', 'c', 'd', 'e'])
-
-
- def test_parse(self):
- """
- L{ServerSupportedFeatures.parse} changes the internal state of the
- instance to reflect the features indicated by the parsed ISUPPORT
- parameters, including unknown parameters and unsetting previously set
- parameters.
- """
- supported = irc.ServerSupportedFeatures()
- supported.parse(['MODES=4',
- 'CHANLIMIT=#:20,&:10',
- 'INVEX',
- 'EXCEPTS=Z',
- 'UNKNOWN=A,B,C'])
-
- self.assertEqual(supported.getFeature('MODES'), 4)
- self.assertEqual(supported.getFeature('CHANLIMIT'),
- [('#', 20),
- ('&', 10)])
- self.assertEqual(supported.getFeature('INVEX'), 'I')
- self.assertEqual(supported.getFeature('EXCEPTS'), 'Z')
- self.assertEqual(supported.getFeature('UNKNOWN'), ('A', 'B', 'C'))
-
- self.assertTrue(supported.hasFeature('INVEX'))
- supported.parse(['-INVEX'])
- self.assertFalse(supported.hasFeature('INVEX'))
- # Unsetting a previously unset parameter should not be a problem.
- supported.parse(['-INVEX'])
-
-
- def _parse(self, features):
- """
- Parse all specified features according to the ISUPPORT specifications.
-
- @type features: C{list} of C{(featureName, value)}
- @param features: Feature names and values to parse
-
- @rtype: L{irc.ServerSupportedFeatures}
- """
- supported = irc.ServerSupportedFeatures()
- features = ['%s=%s' % (name, value or '')
- for name, value in features]
- supported.parse(features)
- return supported
-
-
- def _parseFeature(self, name, value=None):
- """
- Parse a feature, with the given name and value, according to the
- ISUPPORT specifications and return the parsed value.
- """
- supported = self._parse([(name, value)])
- return supported.getFeature(name)
-
-
- def _testIntOrDefaultFeature(self, name, default=None):
- """
- Perform some common tests on a feature known to use L{_intOrDefault}.
- """
- self.assertEqual(
- self._parseFeature(name, None),
- default)
- self.assertEqual(
- self._parseFeature(name, 'notanint'),
- default)
- self.assertEqual(
- self._parseFeature(name, '42'),
- 42)
-
-
- def _testFeatureDefault(self, name, features=None):
- """
- Features known to have default values are reported as being present by
- L{irc.ServerSupportedFeatures.hasFeature}, and their value defaults
- correctly, when they don't appear in an ISUPPORT message.
- """
- default = irc.ServerSupportedFeatures()._features[name]
-
- if features is None:
- features = [('DEFINITELY_NOT', 'a_feature')]
-
- supported = self._parse(features)
- self.assertTrue(supported.hasFeature(name))
- self.assertEqual(supported.getFeature(name), default)
-
-
- def test_support_CHANMODES(self):
- """
- The CHANMODES ISUPPORT parameter is parsed into a C{dict} giving the
- four mode categories, C{'addressModes'}, C{'param'}, C{'setParam'}, and
- C{'noParam'}.
- """
- self._testFeatureDefault('CHANMODES')
- self._testFeatureDefault('CHANMODES', [('CHANMODES', 'b,,lk,')])
- self._testFeatureDefault('CHANMODES', [('CHANMODES', 'b,,lk,ha,ha')])
-
- self.assertEqual(
- self._parseFeature('CHANMODES', ''),
- {'addressModes': '',
- 'param': '',
- 'setParam': '',
- 'noParam': ''})
-
- self.assertEqual(
- self._parseFeature('CHANMODES', ',A'),
- {'addressModes': '',
- 'param': 'A',
- 'setParam': '',
- 'noParam': ''})
-
- self.assertEqual(
- self._parseFeature('CHANMODES', 'A,Bc,Def,Ghij'),
- {'addressModes': 'A',
- 'param': 'Bc',
- 'setParam': 'Def',
- 'noParam': 'Ghij'})
-
-
- def test_support_IDCHAN(self):
- """
- The IDCHAN support parameter is parsed into a sequence of two-tuples
- giving channel prefix and ID length pairs.
- """
- self.assertEqual(
- self._parseFeature('IDCHAN', '!:5'),
- [('!', '5')])
-
-
- def test_support_MAXLIST(self):
- """
- The MAXLIST support parameter is parsed into a sequence of two-tuples
- giving modes and their limits.
- """
- self.assertEqual(
- self._parseFeature('MAXLIST', 'b:25,eI:50'),
- [('b', 25), ('eI', 50)])
- # A non-integer parameter argument results in None.
- self.assertEqual(
- self._parseFeature('MAXLIST', 'b:25,eI:50,a:3.1415'),
- [('b', 25), ('eI', 50), ('a', None)])
- self.assertEqual(
- self._parseFeature('MAXLIST', 'b:25,eI:50,a:notanint'),
- [('b', 25), ('eI', 50), ('a', None)])
-
-
- def test_support_NETWORK(self):
- """
- The NETWORK support parameter is parsed as the network name, as
- specified by the server.
- """
- self.assertEqual(
- self._parseFeature('NETWORK', 'IRCNet'),
- 'IRCNet')
-
-
- def test_support_SAFELIST(self):
- """
- The SAFELIST support parameter is parsed into a boolean indicating
- whether the safe "list" command is supported or not.
- """
- self.assertEqual(
- self._parseFeature('SAFELIST'),
- True)
-
-
- def test_support_STATUSMSG(self):
- """
- The STATUSMSG support parameter is parsed into a string of channel
- status that support the exclusive channel notice method.
- """
- self.assertEqual(
- self._parseFeature('STATUSMSG', '@+'),
- '@+')
-
-
- def test_support_TARGMAX(self):
- """
- The TARGMAX support parameter is parsed into a dictionary, mapping
- strings to integers, of the maximum number of targets for a particular
- command.
- """
- self.assertEqual(
- self._parseFeature('TARGMAX', 'PRIVMSG:4,NOTICE:3'),
- {'PRIVMSG': 4,
- 'NOTICE': 3})
- # A non-integer parameter argument results in None.
- self.assertEqual(
- self._parseFeature('TARGMAX', 'PRIVMSG:4,NOTICE:3,KICK:3.1415'),
- {'PRIVMSG': 4,
- 'NOTICE': 3,
- 'KICK': None})
- self.assertEqual(
- self._parseFeature('TARGMAX', 'PRIVMSG:4,NOTICE:3,KICK:notanint'),
- {'PRIVMSG': 4,
- 'NOTICE': 3,
- 'KICK': None})
-
-
- def test_support_NICKLEN(self):
- """
- The NICKLEN support parameter is parsed into an integer value
- indicating the maximum length of a nickname the client may use,
- otherwise, if the parameter is missing or invalid, the default value
- (as specified by RFC 1459) is used.
- """
- default = irc.ServerSupportedFeatures()._features['NICKLEN']
- self._testIntOrDefaultFeature('NICKLEN', default)
-
-
- def test_support_CHANNELLEN(self):
- """
- The CHANNELLEN support parameter is parsed into an integer value
- indicating the maximum channel name length, otherwise, if the
- parameter is missing or invalid, the default value (as specified by
- RFC 1459) is used.
- """
- default = irc.ServerSupportedFeatures()._features['CHANNELLEN']
- self._testIntOrDefaultFeature('CHANNELLEN', default)
-
-
- def test_support_CHANTYPES(self):
- """
- The CHANTYPES support parameter is parsed into a tuple of
- valid channel prefix characters.
- """
- self._testFeatureDefault('CHANTYPES')
-
- self.assertEqual(
- self._parseFeature('CHANTYPES', '#&%'),
- ('#', '&', '%'))
-
-
- def test_support_KICKLEN(self):
- """
- The KICKLEN support parameter is parsed into an integer value
- indicating the maximum length of a kick message a client may use.
- """
- self._testIntOrDefaultFeature('KICKLEN')
-
-
- def test_support_PREFIX(self):
- """
- The PREFIX support parameter is parsed into a dictionary mapping
- modes to two-tuples of status symbol and priority.
- """
- self._testFeatureDefault('PREFIX')
- self._testFeatureDefault('PREFIX', [('PREFIX', 'hello')])
-
- self.assertEqual(
- self._parseFeature('PREFIX', None),
- None)
- self.assertEqual(
- self._parseFeature('PREFIX', '(ohv)@%+'),
- {'o': ('@', 0),
- 'h': ('%', 1),
- 'v': ('+', 2)})
- self.assertEqual(
- self._parseFeature('PREFIX', '(hov)@%+'),
- {'o': ('%', 1),
- 'h': ('@', 0),
- 'v': ('+', 2)})
-
-
- def test_support_TOPICLEN(self):
- """
- The TOPICLEN support parameter is parsed into an integer value
- indicating the maximum length of a topic a client may set.
- """
- self._testIntOrDefaultFeature('TOPICLEN')
-
-
- def test_support_MODES(self):
- """
- The MODES support parameter is parsed into an integer value
- indicating the maximum number of "variable" modes (defined as being
- modes from C{addressModes}, C{param} or C{setParam} categories for
- the C{CHANMODES} ISUPPORT parameter) which may by set on a channel
- by a single MODE command from a client.
- """
- self._testIntOrDefaultFeature('MODES')
-
-
- def test_support_EXCEPTS(self):
- """
- The EXCEPTS support parameter is parsed into the mode character
- to be used for "ban exception" modes. If no parameter is specified
- then the character C{e} is assumed.
- """
- self.assertEqual(
- self._parseFeature('EXCEPTS', 'Z'),
- 'Z')
- self.assertEqual(
- self._parseFeature('EXCEPTS'),
- 'e')
-
-
- def test_support_INVEX(self):
- """
- The INVEX support parameter is parsed into the mode character to be
- used for "invite exception" modes. If no parameter is specified then
- the character C{I} is assumed.
- """
- self.assertEqual(
- self._parseFeature('INVEX', 'Z'),
- 'Z')
- self.assertEqual(
- self._parseFeature('INVEX'),
- 'I')
-
-
-
-class IRCClientWithoutLogin(irc.IRCClient):
- performLogin = 0
-
-
-
-class CTCPTest(unittest.TestCase):
- """
- Tests for L{twisted.words.protocols.irc.IRCClient} CTCP handling.
- """
- def setUp(self):
- self.file = StringIOWithoutClosing()
- self.transport = protocol.FileWrapper(self.file)
- self.client = IRCClientWithoutLogin()
- self.client.makeConnection(self.transport)
-
- self.addCleanup(self.transport.loseConnection)
- self.addCleanup(self.client.connectionLost, None)
-
-
- def test_ERRMSG(self):
- """Testing CTCP query ERRMSG.
-
- Not because this is this is an especially important case in the
- field, but it does go through the entire dispatch/decode/encode
- process.
- """
-
- errQuery = (":nick!guy@over.there PRIVMSG #theChan :"
- "%(X)cERRMSG t%(X)c%(EOL)s"
- % {'X': irc.X_DELIM,
- 'EOL': irc.CR + irc.LF})
-
- errReply = ("NOTICE nick :%(X)cERRMSG t :"
- "No error has occoured.%(X)c%(EOL)s"
- % {'X': irc.X_DELIM,
- 'EOL': irc.CR + irc.LF})
-
- self.client.dataReceived(errQuery)
- reply = self.file.getvalue()
-
- self.assertEqual(errReply, reply)
-
-
- def test_noNumbersVERSION(self):
- """
- If attributes for version information on L{IRCClient} are set to
- C{None}, the parts of the CTCP VERSION response they correspond to
- are omitted.
- """
- self.client.versionName = "FrobozzIRC"
- self.client.ctcpQuery_VERSION("nick!guy@over.there", "#theChan", None)
- versionReply = ("NOTICE nick :%(X)cVERSION %(vname)s::"
- "%(X)c%(EOL)s"
- % {'X': irc.X_DELIM,
- 'EOL': irc.CR + irc.LF,
- 'vname': self.client.versionName})
- reply = self.file.getvalue()
- self.assertEqual(versionReply, reply)
-
-
- def test_fullVERSION(self):
- """
- The response to a CTCP VERSION query includes the version number and
- environment information, as specified by L{IRCClient.versionNum} and
- L{IRCClient.versionEnv}.
- """
- self.client.versionName = "FrobozzIRC"
- self.client.versionNum = "1.2g"
- self.client.versionEnv = "ZorkOS"
- self.client.ctcpQuery_VERSION("nick!guy@over.there", "#theChan", None)
- versionReply = ("NOTICE nick :%(X)cVERSION %(vname)s:%(vnum)s:%(venv)s"
- "%(X)c%(EOL)s"
- % {'X': irc.X_DELIM,
- 'EOL': irc.CR + irc.LF,
- 'vname': self.client.versionName,
- 'vnum': self.client.versionNum,
- 'venv': self.client.versionEnv})
- reply = self.file.getvalue()
- self.assertEqual(versionReply, reply)
-
-
- def test_noDuplicateCTCPDispatch(self):
- """
- Duplicated CTCP messages are ignored and no reply is made.
- """
- def testCTCP(user, channel, data):
- self.called += 1
-
- self.called = 0
- self.client.ctcpQuery_TESTTHIS = testCTCP
-
- self.client.irc_PRIVMSG(
- 'foo!bar@baz.quux', [
- '#chan',
- '%(X)sTESTTHIS%(X)sfoo%(X)sTESTTHIS%(X)s' % {'X': irc.X_DELIM}])
- self.assertEqual(
- self.file.getvalue(),
- '')
- self.assertEqual(self.called, 1)
-
-
- def test_noDefaultDispatch(self):
- """
- The fallback handler is invoked for unrecognized CTCP messages.
- """
- def unknownQuery(user, channel, tag, data):
- self.calledWith = (user, channel, tag, data)
- self.called += 1
-
- self.called = 0
- self.patch(self.client, 'ctcpUnknownQuery', unknownQuery)
- self.client.irc_PRIVMSG(
- 'foo!bar@baz.quux', [
- '#chan',
- '%(X)sNOTREAL%(X)s' % {'X': irc.X_DELIM}])
- self.assertEqual(
- self.file.getvalue(),
- '')
- self.assertEqual(
- self.calledWith,
- ('foo!bar@baz.quux', '#chan', 'NOTREAL', None))
- self.assertEqual(self.called, 1)
-
- # The fallback handler is not invoked for duplicate unknown CTCP
- # messages.
- self.client.irc_PRIVMSG(
- 'foo!bar@baz.quux', [
- '#chan',
- '%(X)sNOTREAL%(X)sfoo%(X)sNOTREAL%(X)s' % {'X': irc.X_DELIM}])
- self.assertEqual(self.called, 2)
-
-
-
-class NoticingClient(IRCClientWithoutLogin, object):
- methods = {
- 'created': ('when',),
- 'yourHost': ('info',),
- 'myInfo': ('servername', 'version', 'umodes', 'cmodes'),
- 'luserClient': ('info',),
- 'bounce': ('info',),
- 'isupport': ('options',),
- 'luserChannels': ('channels',),
- 'luserOp': ('ops',),
- 'luserMe': ('info',),
- 'receivedMOTD': ('motd',),
-
- 'privmsg': ('user', 'channel', 'message'),
- 'joined': ('channel',),
- 'left': ('channel',),
- 'noticed': ('user', 'channel', 'message'),
- 'modeChanged': ('user', 'channel', 'set', 'modes', 'args'),
- 'pong': ('user', 'secs'),
- 'signedOn': (),
- 'kickedFrom': ('channel', 'kicker', 'message'),
- 'nickChanged': ('nick',),
-
- 'userJoined': ('user', 'channel'),
- 'userLeft': ('user', 'channel'),
- 'userKicked': ('user', 'channel', 'kicker', 'message'),
- 'action': ('user', 'channel', 'data'),
- 'topicUpdated': ('user', 'channel', 'newTopic'),
- 'userRenamed': ('oldname', 'newname')}
-
-
- def __init__(self, *a, **kw):
- # It is important that IRCClient.__init__ is not called since
- # traditionally it did not exist, so it is important that nothing is
- # initialised there that would prevent subclasses that did not (or
- # could not) invoke the base implementation. Any protocol
- # initialisation should happen in connectionMode.
- self.calls = []
-
-
- def __getattribute__(self, name):
- if name.startswith('__') and name.endswith('__'):
- return super(NoticingClient, self).__getattribute__(name)
- try:
- args = super(NoticingClient, self).__getattribute__('methods')[name]
- except KeyError:
- return super(NoticingClient, self).__getattribute__(name)
- else:
- return self.makeMethod(name, args)
-
-
- def makeMethod(self, fname, args):
- def method(*a, **kw):
- if len(a) > len(args):
- raise TypeError("TypeError: %s() takes %d arguments "
- "(%d given)" % (fname, len(args), len(a)))
- for (name, value) in zip(args, a):
- if name in kw:
- raise TypeError("TypeError: %s() got multiple values "
- "for keyword argument '%s'" % (fname, name))
- else:
- kw[name] = value
- if len(kw) != len(args):
- raise TypeError("TypeError: %s() takes %d arguments "
- "(%d given)" % (fname, len(args), len(a)))
- self.calls.append((fname, kw))
- return method
-
-
-def pop(dict, key, default):
- try:
- value = dict[key]
- except KeyError:
- return default
- else:
- del dict[key]
- return value
-
-
-
-class ClientImplementationTests(unittest.TestCase):
- def setUp(self):
- self.transport = StringTransport()
- self.client = NoticingClient()
- self.client.makeConnection(self.transport)
-
- self.addCleanup(self.transport.loseConnection)
- self.addCleanup(self.client.connectionLost, None)
-
-
- def _serverTestImpl(self, code, msg, func, **kw):
- host = pop(kw, 'host', 'server.host')
- nick = pop(kw, 'nick', 'nickname')
- args = pop(kw, 'args', '')
-
- message = (":" +
- host + " " +
- code + " " +
- nick + " " +
- args + " :" +
- msg + "\r\n")
-
- self.client.dataReceived(message)
- self.assertEqual(
- self.client.calls,
- [(func, kw)])
-
-
- def testYourHost(self):
- msg = "Your host is some.host[blah.blah/6667], running version server-version-3"
- self._serverTestImpl("002", msg, "yourHost", info=msg)
-
-
- def testCreated(self):
- msg = "This server was cobbled together Fri Aug 13 18:00:25 UTC 2004"
- self._serverTestImpl("003", msg, "created", when=msg)
-
-
- def testMyInfo(self):
- msg = "server.host server-version abcDEF bcdEHI"
- self._serverTestImpl("004", msg, "myInfo",
- servername="server.host",
- version="server-version",
- umodes="abcDEF",
- cmodes="bcdEHI")
-
-
- def testLuserClient(self):
- msg = "There are 9227 victims and 9542 hiding on 24 servers"
- self._serverTestImpl("251", msg, "luserClient",
- info=msg)
-
-
- def _sendISUPPORT(self):
- args = ("MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 HOSTLEN=63 "
- "TOPICLEN=450 KICKLEN=450 CHANNELLEN=30 KEYLEN=23 CHANTYPES=# "
- "PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer")
- msg = "are available on this server"
- self._serverTestImpl("005", msg, "isupport", args=args,
- options=['MODES=4',
- 'CHANLIMIT=#:20',
- 'NICKLEN=16',
- 'USERLEN=10',
- 'HOSTLEN=63',
- 'TOPICLEN=450',
- 'KICKLEN=450',
- 'CHANNELLEN=30',
- 'KEYLEN=23',
- 'CHANTYPES=#',
- 'PREFIX=(ov)@+',
- 'CASEMAPPING=ascii',
- 'CAPAB',
- 'IRCD=dancer'])
-
-
- def test_ISUPPORT(self):
- """
- The client parses ISUPPORT messages sent by the server and calls
- L{IRCClient.isupport}.
- """
- self._sendISUPPORT()
-
-
- def testBounce(self):
- msg = "Try server some.host, port 321"
- self._serverTestImpl("010", msg, "bounce",
- info=msg)
-
-
- def testLuserChannels(self):
- args = "7116"
- msg = "channels formed"
- self._serverTestImpl("254", msg, "luserChannels", args=args,
- channels=int(args))
-
-
- def testLuserOp(self):
- args = "34"
- msg = "flagged staff members"
- self._serverTestImpl("252", msg, "luserOp", args=args,
- ops=int(args))
-
-
- def testLuserMe(self):
- msg = "I have 1937 clients and 0 servers"
- self._serverTestImpl("255", msg, "luserMe",
- info=msg)
-
-
- def test_receivedMOTD(self):
- """
- Lines received in I{RPL_MOTDSTART} and I{RPL_MOTD} are delivered to
- L{IRCClient.receivedMOTD} when I{RPL_ENDOFMOTD} is received.
- """
- lines = [
- ":host.name 375 nickname :- host.name Message of the Day -",
- ":host.name 372 nickname :- Welcome to host.name",
- ":host.name 376 nickname :End of /MOTD command."]
- for L in lines:
- self.assertEqual(self.client.calls, [])
- self.client.dataReceived(L + '\r\n')
-
- self.assertEqual(
- self.client.calls,
- [("receivedMOTD", {"motd": ["host.name Message of the Day -", "Welcome to host.name"]})])
-
- # After the motd is delivered, the tracking variable should be
- # reset.
- self.assertIdentical(self.client.motd, None)
-
-
- def test_withoutMOTDSTART(self):
- """
- If L{IRCClient} receives I{RPL_MOTD} and I{RPL_ENDOFMOTD} without
- receiving I{RPL_MOTDSTART}, L{IRCClient.receivedMOTD} is still
- called with a list of MOTD lines.
- """
- lines = [
- ":host.name 372 nickname :- Welcome to host.name",
- ":host.name 376 nickname :End of /MOTD command."]
-
- for L in lines:
- self.client.dataReceived(L + '\r\n')
-
- self.assertEqual(
- self.client.calls,
- [("receivedMOTD", {"motd": ["Welcome to host.name"]})])
-
-
- def _clientTestImpl(self, sender, group, type, msg, func, **kw):
- ident = pop(kw, 'ident', 'ident')
- host = pop(kw, 'host', 'host')
-
- wholeUser = sender + '!' + ident + '@' + host
- message = (":" +
- wholeUser + " " +
- type + " " +
- group + " :" +
- msg + "\r\n")
- self.client.dataReceived(message)
- self.assertEqual(
- self.client.calls,
- [(func, kw)])
- self.client.calls = []
-
-
- def testPrivmsg(self):
- msg = "Tooty toot toot."
- self._clientTestImpl("sender", "#group", "PRIVMSG", msg, "privmsg",
- ident="ident", host="host",
- # Expected results below
- user="sender!ident@host",
- channel="#group",
- message=msg)
-
- self._clientTestImpl("sender", "recipient", "PRIVMSG", msg, "privmsg",
- ident="ident", host="host",
- # Expected results below
- user="sender!ident@host",
- channel="recipient",
- message=msg)
-
-
- def test_getChannelModeParams(self):
- """
- L{IRCClient.getChannelModeParams} uses ISUPPORT information, either
- given by the server or defaults, to determine which channel modes
- require arguments when being added or removed.
- """
- add, remove = map(sorted, self.client.getChannelModeParams())
- self.assertEqual(add, ['b', 'h', 'k', 'l', 'o', 'v'])
- self.assertEqual(remove, ['b', 'h', 'o', 'v'])
-
- def removeFeature(name):
- name = '-' + name
- msg = "are available on this server"
- self._serverTestImpl(
- '005', msg, 'isupport', args=name, options=[name])
- self.assertIdentical(
- self.client.supported.getFeature(name), None)
- self.client.calls = []
-
- # Remove CHANMODES feature, causing getFeature('CHANMODES') to return
- # None.
- removeFeature('CHANMODES')
- add, remove = map(sorted, self.client.getChannelModeParams())
- self.assertEqual(add, ['h', 'o', 'v'])
- self.assertEqual(remove, ['h', 'o', 'v'])
-
- # Remove PREFIX feature, causing getFeature('PREFIX') to return None.
- removeFeature('PREFIX')
- add, remove = map(sorted, self.client.getChannelModeParams())
- self.assertEqual(add, [])
- self.assertEqual(remove, [])
-
- # Restore ISUPPORT features.
- self._sendISUPPORT()
- self.assertNotIdentical(
- self.client.supported.getFeature('PREFIX'), None)
-
-
- def test_getUserModeParams(self):
- """
- L{IRCClient.getUserModeParams} returns a list of user modes (modes that
- the user sets on themself, outside of channel modes) that require
- parameters when added and removed, respectively.
- """
- add, remove = map(sorted, self.client.getUserModeParams())
- self.assertEqual(add, [])
- self.assertEqual(remove, [])
-
-
- def _sendModeChange(self, msg, args='', target=None):
- """
- Build a MODE string and send it to the client.
- """
- if target is None:
- target = '#chan'
- message = ":Wolf!~wolf@yok.utu.fi MODE %s %s %s\r\n" % (
- target, msg, args)
- self.client.dataReceived(message)
-
-
- def _parseModeChange(self, results, target=None):
- """
- Parse the results, do some test and return the data to check.
- """
- if target is None:
- target = '#chan'
-
- for n, result in enumerate(results):
- method, data = result
- self.assertEqual(method, 'modeChanged')
- self.assertEqual(data['user'], 'Wolf!~wolf@yok.utu.fi')
- self.assertEqual(data['channel'], target)
- results[n] = tuple([data[key] for key in ('set', 'modes', 'args')])
- return results
-
-
- def _checkModeChange(self, expected, target=None):
- """
- Compare the expected result with the one returned by the client.
- """
- result = self._parseModeChange(self.client.calls, target)
- self.assertEqual(result, expected)
- self.client.calls = []
-
-
- def test_modeMissingDirection(self):
- """
- Mode strings that do not begin with a directional character, C{'+'} or
- C{'-'}, have C{'+'} automatically prepended.
- """
- self._sendModeChange('s')
- self._checkModeChange([(True, 's', (None,))])
-
-
- def test_noModeParameters(self):
- """
- No parameters are passed to L{IRCClient.modeChanged} for modes that
- don't take any parameters.
- """
- self._sendModeChange('-s')
- self._checkModeChange([(False, 's', (None,))])
- self._sendModeChange('+n')
- self._checkModeChange([(True, 'n', (None,))])
-
-
- def test_oneModeParameter(self):
- """
- Parameters are passed to L{IRCClient.modeChanged} for modes that take
- parameters.
- """
- self._sendModeChange('+o', 'a_user')
- self._checkModeChange([(True, 'o', ('a_user',))])
- self._sendModeChange('-o', 'a_user')
- self._checkModeChange([(False, 'o', ('a_user',))])
-
-
- def test_mixedModes(self):
- """
- Mixing adding and removing modes that do and don't take parameters
- invokes L{IRCClient.modeChanged} with mode characters and parameters
- that match up.
- """
- self._sendModeChange('+osv', 'a_user another_user')
- self._checkModeChange([(True, 'osv', ('a_user', None, 'another_user'))])
- self._sendModeChange('+v-os', 'a_user another_user')
- self._checkModeChange([(True, 'v', ('a_user',)),
- (False, 'os', ('another_user', None))])
-
-
- def test_tooManyModeParameters(self):
- """
- Passing an argument to modes that take no parameters results in
- L{IRCClient.modeChanged} not being called and an error being logged.
- """
- self._sendModeChange('+s', 'wrong')
- self._checkModeChange([])
- errors = self.flushLoggedErrors(irc.IRCBadModes)
- self.assertEqual(len(errors), 1)
- self.assertSubstring(
- 'Too many parameters', errors[0].getErrorMessage())
-
-
- def test_tooFewModeParameters(self):
- """
- Passing no arguments to modes that do take parameters results in
- L{IRCClient.modeChange} not being called and an error being logged.
- """
- self._sendModeChange('+o')
- self._checkModeChange([])
- errors = self.flushLoggedErrors(irc.IRCBadModes)
- self.assertEqual(len(errors), 1)
- self.assertSubstring(
- 'Not enough parameters', errors[0].getErrorMessage())
-
-
- def test_userMode(self):
- """
- A C{MODE} message whose target is our user (the nickname of our user,
- to be precise), as opposed to a channel, will be parsed according to
- the modes specified by L{IRCClient.getUserModeParams}.
- """
- target = self.client.nickname
- # Mode "o" on channels is supposed to take a parameter, but since this
- # is not a channel this will not cause an exception.
- self._sendModeChange('+o', target=target)
- self._checkModeChange([(True, 'o', (None,))], target=target)
-
- def getUserModeParams():
- return ['Z', '']
-
- # Introduce our own user mode that takes an argument.
- self.patch(self.client, 'getUserModeParams', getUserModeParams)
-
- self._sendModeChange('+Z', 'an_arg', target=target)
- self._checkModeChange([(True, 'Z', ('an_arg',))], target=target)
-
-
- def test_heartbeat(self):
- """
- When the I{RPL_WELCOME} message is received a heartbeat is started that
- will send a I{PING} message to the IRC server every
- L{irc.IRCClient.heartbeatInterval} seconds. When the transport is
- closed the heartbeat looping call is stopped too.
- """
- def _createHeartbeat():
- heartbeat = self._originalCreateHeartbeat()
- heartbeat.clock = self.clock
- return heartbeat
-
- self.clock = task.Clock()
- self._originalCreateHeartbeat = self.client._createHeartbeat
- self.patch(self.client, '_createHeartbeat', _createHeartbeat)
-
- self.assertIdentical(self.client._heartbeat, None)
- self.client.irc_RPL_WELCOME('foo', [])
- self.assertNotIdentical(self.client._heartbeat, None)
- self.assertEqual(self.client.hostname, 'foo')
-
- # Pump the clock enough to trigger one LoopingCall.
- self.assertEqual(self.transport.value(), '')
- self.clock.advance(self.client.heartbeatInterval)
- self.assertEqual(self.transport.value(), 'PING foo\r\n')
-
- # When the connection is lost the heartbeat is stopped.
- self.transport.loseConnection()
- self.client.connectionLost(None)
- self.assertEqual(
- len(self.clock.getDelayedCalls()), 0)
- self.assertIdentical(self.client._heartbeat, None)
-
-
- def test_heartbeatDisabled(self):
- """
- If L{irc.IRCClient.heartbeatInterval} is set to C{None} then no
- heartbeat is created.
- """
- self.assertIdentical(self.client._heartbeat, None)
- self.client.heartbeatInterval = None
- self.client.irc_RPL_WELCOME('foo', [])
- self.assertIdentical(self.client._heartbeat, None)
-
-
-
-class BasicServerFunctionalityTestCase(unittest.TestCase):
- def setUp(self):
- self.f = StringIOWithoutClosing()
- self.t = protocol.FileWrapper(self.f)
- self.p = irc.IRC()
- self.p.makeConnection(self.t)
-
-
- def check(self, s):
- self.assertEqual(self.f.getvalue(), s)
-
-
- def testPrivmsg(self):
- self.p.privmsg("this-is-sender", "this-is-recip", "this is message")
- self.check(":this-is-sender PRIVMSG this-is-recip :this is message\r\n")
-
-
- def testNotice(self):
- self.p.notice("this-is-sender", "this-is-recip", "this is notice")
- self.check(":this-is-sender NOTICE this-is-recip :this is notice\r\n")
-
-
- def testAction(self):
- self.p.action("this-is-sender", "this-is-recip", "this is action")
- self.check(":this-is-sender ACTION this-is-recip :this is action\r\n")
-
-
- def testJoin(self):
- self.p.join("this-person", "#this-channel")
- self.check(":this-person JOIN #this-channel\r\n")
-
-
- def testPart(self):
- self.p.part("this-person", "#that-channel")
- self.check(":this-person PART #that-channel\r\n")
-
-
- def testWhois(self):
- """
- Verify that a whois by the client receives the right protocol actions
- from the server.
- """
- timestamp = int(time.time()-100)
- hostname = self.p.hostname
- req = 'requesting-nick'
- targ = 'target-nick'
- self.p.whois(req, targ, 'target', 'host.com',
- 'Target User', 'irc.host.com', 'A fake server', False,
- 12, timestamp, ['#fakeusers', '#fakemisc'])
- expected = '\r\n'.join([
-':%(hostname)s 311 %(req)s %(targ)s target host.com * :Target User',
-':%(hostname)s 312 %(req)s %(targ)s irc.host.com :A fake server',
-':%(hostname)s 317 %(req)s %(targ)s 12 %(timestamp)s :seconds idle, signon time',
-':%(hostname)s 319 %(req)s %(targ)s :#fakeusers #fakemisc',
-':%(hostname)s 318 %(req)s %(targ)s :End of WHOIS list.',
-'']) % dict(hostname=hostname, timestamp=timestamp, req=req, targ=targ)
- self.check(expected)
-
-
-
-class DummyClient(irc.IRCClient):
- """
- A L{twisted.words.protocols.irc.IRCClient} that stores sent lines in a
- C{list} rather than transmitting them.
- """
- def __init__(self):
- self.lines = []
-
-
- def connectionMade(self):
- irc.IRCClient.connectionMade(self)
- self.lines = []
-
-
- def _truncateLine(self, line):
- """
- Truncate an IRC line to the maximum allowed length.
- """
- return line[:irc.MAX_COMMAND_LENGTH - len(self.delimiter)]
-
-
- def lineReceived(self, line):
- # Emulate IRC servers throwing away our important data.
- line = self._truncateLine(line)
- return irc.IRCClient.lineReceived(self, line)
-
-
- def sendLine(self, m):
- self.lines.append(self._truncateLine(m))
-
-
-
-class ClientInviteTests(unittest.TestCase):
- """
- Tests for L{IRCClient.invite}.
- """
- def setUp(self):
- """
- Create a L{DummyClient} to call C{invite} on in test methods.
- """
- self.client = DummyClient()
-
-
- def test_channelCorrection(self):
- """
- If the channel name passed to L{IRCClient.invite} does not begin with a
- channel prefix character, one is prepended to it.
- """
- self.client.invite('foo', 'bar')
- self.assertEqual(self.client.lines, ['INVITE foo #bar'])
-
-
- def test_invite(self):
- """
- L{IRCClient.invite} sends an I{INVITE} message with the specified
- username and a channel.
- """
- self.client.invite('foo', '#bar')
- self.assertEqual(self.client.lines, ['INVITE foo #bar'])
-
-
-
-class ClientMsgTests(unittest.TestCase):
- """
- Tests for messages sent with L{twisted.words.protocols.irc.IRCClient}.
- """
- def setUp(self):
- self.client = DummyClient()
- self.client.connectionMade()
-
-
- def test_singleLine(self):
- """
- A message containing no newlines is sent in a single command.
- """
- self.client.msg('foo', 'bar')
- self.assertEqual(self.client.lines, ['PRIVMSG foo :bar'])
-
-
- def test_invalidMaxLength(self):
- """
- Specifying a C{length} value to L{IRCClient.msg} that is too short to
- contain the protocol command to send a message raises C{ValueError}.
- """
- self.assertRaises(ValueError, self.client.msg, 'foo', 'bar', 0)
- self.assertRaises(ValueError, self.client.msg, 'foo', 'bar', 3)
-
-
- def test_multipleLine(self):
- """
- Messages longer than the C{length} parameter to L{IRCClient.msg} will
- be split and sent in multiple commands.
- """
- maxLen = len('PRIVMSG foo :') + 3 + 2 # 2 for line endings
- self.client.msg('foo', 'barbazbo', maxLen)
- self.assertEqual(
- self.client.lines,
- ['PRIVMSG foo :bar',
- 'PRIVMSG foo :baz',
- 'PRIVMSG foo :bo'])
-
-
- def test_sufficientWidth(self):
- """
- Messages exactly equal in length to the C{length} paramtere to
- L{IRCClient.msg} are sent in a single command.
- """
- msg = 'barbazbo'
- maxLen = len('PRIVMSG foo :%s' % (msg,)) + 2
- self.client.msg('foo', msg, maxLen)
- self.assertEqual(self.client.lines, ['PRIVMSG foo :%s' % (msg,)])
- self.client.lines = []
- self.client.msg('foo', msg, maxLen-1)
- self.assertEqual(2, len(self.client.lines))
- self.client.lines = []
- self.client.msg('foo', msg, maxLen+1)
- self.assertEqual(1, len(self.client.lines))
-
-
- def test_newlinesAtStart(self):
- """
- An LF at the beginning of the message is ignored.
- """
- self.client.lines = []
- self.client.msg('foo', '\nbar')
- self.assertEqual(self.client.lines, ['PRIVMSG foo :bar'])
-
-
- def test_newlinesAtEnd(self):
- """
- An LF at the end of the message is ignored.
- """
- self.client.lines = []
- self.client.msg('foo', 'bar\n')
- self.assertEqual(self.client.lines, ['PRIVMSG foo :bar'])
-
-
- def test_newlinesWithinMessage(self):
- """
- An LF within a message causes a new line.
- """
- self.client.lines = []
- self.client.msg('foo', 'bar\nbaz')
- self.assertEqual(
- self.client.lines,
- ['PRIVMSG foo :bar',
- 'PRIVMSG foo :baz'])
-
-
- def test_consecutiveNewlines(self):
- """
- Consecutive LFs do not cause a blank line.
- """
- self.client.lines = []
- self.client.msg('foo', 'bar\n\nbaz')
- self.assertEqual(
- self.client.lines,
- ['PRIVMSG foo :bar',
- 'PRIVMSG foo :baz'])
-
-
- def assertLongMessageSplitting(self, message, expectedNumCommands,
- length=None):
- """
- Assert that messages sent by L{IRCClient.msg} are split into an
- expected number of commands and the original message is transmitted in
- its entirety over those commands.
- """
- responsePrefix = ':%s!%s@%s ' % (
- self.client.nickname,
- self.client.realname,
- self.client.hostname)
-
- self.client.msg('foo', message, length=length)
-
- privmsg = []
- self.patch(self.client, 'privmsg', lambda *a: privmsg.append(a))
- # Deliver these to IRCClient via the normal mechanisms.
- for line in self.client.lines:
- self.client.lineReceived(responsePrefix + line)
-
- self.assertEqual(len(privmsg), expectedNumCommands)
- receivedMessage = ''.join(
- message for user, target, message in privmsg)
-
- # Did the long message we sent arrive as intended?
- self.assertEqual(message, receivedMessage)
-
-
- def test_splitLongMessagesWithDefault(self):
- """
- If a maximum message length is not provided to L{IRCClient.msg} a
- best-guess effort is made to determine a safe maximum, messages longer
- than this are split into multiple commands with the intent of
- delivering long messages without losing data due to message truncation
- when the server relays them.
- """
- message = 'o' * (irc.MAX_COMMAND_LENGTH - 2)
- self.assertLongMessageSplitting(message, 2)
-
-
- def test_splitLongMessagesWithOverride(self):
- """
- The maximum message length can be specified to L{IRCClient.msg},
- messages longer than this are split into multiple commands with the
- intent of delivering long messages without losing data due to message
- truncation when the server relays them.
- """
- message = 'o' * (irc.MAX_COMMAND_LENGTH - 2)
- self.assertLongMessageSplitting(
- message, 3, length=irc.MAX_COMMAND_LENGTH // 2)
-
-
- def test_newlinesBeforeLineBreaking(self):
- """
- IRCClient breaks on newlines before it breaks long lines.
- """
- # Because MAX_COMMAND_LENGTH includes framing characters, this long
- # line is slightly longer than half the permissible message size.
- longline = 'o' * (irc.MAX_COMMAND_LENGTH // 2)
-
- self.client.msg('foo', longline + '\n' + longline)
- self.assertEqual(
- self.client.lines,
- ['PRIVMSG foo :' + longline,
- 'PRIVMSG foo :' + longline])
-
-
- def test_lineBreakOnWordBoundaries(self):
- """
- IRCClient prefers to break long lines at word boundaries.
- """
- # Because MAX_COMMAND_LENGTH includes framing characters, this long
- # line is slightly longer than half the permissible message size.
- longline = 'o' * (irc.MAX_COMMAND_LENGTH // 2)
-
- self.client.msg('foo', longline + ' ' + longline)
- self.assertEqual(
- self.client.lines,
- ['PRIVMSG foo :' + longline,
- 'PRIVMSG foo :' + longline])
-
-
- def test_splitSanity(self):
- """
- L{twisted.words.protocols.irc.split} raises C{ValueError} if given a
- length less than or equal to C{0} and returns C{[]} when splitting
- C{''}.
- """
- # Whiteboxing
- self.assertRaises(ValueError, irc.split, 'foo', -1)
- self.assertRaises(ValueError, irc.split, 'foo', 0)
- self.assertEqual([], irc.split('', 1))
- self.assertEqual([], irc.split(''))
-
-
- def test_splitDelimiters(self):
- """
- L{twisted.words.protocols.irc.split} skips any delimiter (space or
- newline) that it finds at the very beginning of the string segment it
- is operating on. Nothing should be added to the output list because of
- it.
- """
- r = irc.split("xx yyz", 2)
- self.assertEqual(['xx', 'yy', 'z'], r)
- r = irc.split("xx\nyyz", 2)
- self.assertEqual(['xx', 'yy', 'z'], r)
-
-
- def test_splitValidatesLength(self):
- """
- L{twisted.words.protocols.irc.split} raises C{ValueError} if given a
- length less than or equal to C{0}.
- """
- self.assertRaises(ValueError, irc.split, "foo", 0)
- self.assertRaises(ValueError, irc.split, "foo", -1)
-
-
- def test_say(self):
- """
- L{IRCClient.say} prepends the channel prefix C{"#"} if necessary and
- then sends the message to the server for delivery to that channel.
- """
- self.client.say("thechannel", "the message")
- self.assertEquals(
- self.client.lines, ["PRIVMSG #thechannel :the message"])
-
-
-
-class ClientTests(TestCase):
- """
- Tests for the protocol-level behavior of IRCClient methods intended to
- be called by application code.
- """
- def setUp(self):
- """
- Create and connect a new L{IRCClient} to a new L{StringTransport}.
- """
- self.transport = StringTransport()
- self.protocol = IRCClient()
- self.protocol.performLogin = False
- self.protocol.makeConnection(self.transport)
-
- # Sanity check - we don't want anything to have happened at this
- # point, since we're not in a test yet.
- self.assertEqual(self.transport.value(), "")
-
- self.addCleanup(self.transport.loseConnection)
- self.addCleanup(self.protocol.connectionLost, None)
-
-
- def getLastLine(self, transport):
- """
- Return the last IRC message in the transport buffer.
- """
- return transport.value().split('\r\n')[-2]
-
-
- def test_away(self):
- """
- L{IRCCLient.away} sends an AWAY command with the specified message.
- """
- message = "Sorry, I'm not here."
- self.protocol.away(message)
- expected = [
- 'AWAY :%s' % (message,),
- '',
- ]
- self.assertEqual(self.transport.value().split('\r\n'), expected)
-
-
- def test_back(self):
- """
- L{IRCClient.back} sends an AWAY command with an empty message.
- """
- self.protocol.back()
- expected = [
- 'AWAY :',
- '',
- ]
- self.assertEqual(self.transport.value().split('\r\n'), expected)
-
-
- def test_whois(self):
- """
- L{IRCClient.whois} sends a WHOIS message.
- """
- self.protocol.whois('alice')
- self.assertEqual(
- self.transport.value().split('\r\n'),
- ['WHOIS alice', ''])
-
-
- def test_whoisWithServer(self):
- """
- L{IRCClient.whois} sends a WHOIS message with a server name if a
- value is passed for the C{server} parameter.
- """
- self.protocol.whois('alice', 'example.org')
- self.assertEqual(
- self.transport.value().split('\r\n'),
- ['WHOIS example.org alice', ''])
-
-
- def test_register(self):
- """
- L{IRCClient.register} sends NICK and USER commands with the
- username, name, hostname, server name, and real name specified.
- """
- username = 'testuser'
- hostname = 'testhost'
- servername = 'testserver'
- self.protocol.realname = 'testname'
- self.protocol.password = None
- self.protocol.register(username, hostname, servername)
- expected = [
- 'NICK %s' % (username,),
- 'USER %s %s %s :%s' % (
- username, hostname, servername, self.protocol.realname),
- '']
- self.assertEqual(self.transport.value().split('\r\n'), expected)
-
-
- def test_registerWithPassword(self):
- """
- If the C{password} attribute of L{IRCClient} is not C{None}, the
- C{register} method also sends a PASS command with it as the
- argument.
- """
- username = 'testuser'
- hostname = 'testhost'
- servername = 'testserver'
- self.protocol.realname = 'testname'
- self.protocol.password = 'testpass'
- self.protocol.register(username, hostname, servername)
- expected = [
- 'PASS %s' % (self.protocol.password,),
- 'NICK %s' % (username,),
- 'USER %s %s %s :%s' % (
- username, hostname, servername, self.protocol.realname),
- '']
- self.assertEqual(self.transport.value().split('\r\n'), expected)
-
-
- def test_registerWithTakenNick(self):
- """
- Verify that the client repeats the L{IRCClient.setNick} method with a
- new value when presented with an C{ERR_NICKNAMEINUSE} while trying to
- register.
- """
- username = 'testuser'
- hostname = 'testhost'
- servername = 'testserver'
- self.protocol.realname = 'testname'
- self.protocol.password = 'testpass'
- self.protocol.register(username, hostname, servername)
- self.protocol.irc_ERR_NICKNAMEINUSE('prefix', ['param'])
- lastLine = self.getLastLine(self.transport)
- self.assertNotEquals(lastLine, 'NICK %s' % (username,))
-
- # Keep chaining underscores for each collision
- self.protocol.irc_ERR_NICKNAMEINUSE('prefix', ['param'])
- lastLine = self.getLastLine(self.transport)
- self.assertEqual(lastLine, 'NICK %s' % (username + '__',))
-
-
- def test_overrideAlterCollidedNick(self):
- """
- L{IRCClient.alterCollidedNick} determines how a nickname is altered upon
- collision while a user is trying to change to that nickname.
- """
- nick = 'foo'
- self.protocol.alterCollidedNick = lambda nick: nick + '***'
- self.protocol.register(nick)
- self.protocol.irc_ERR_NICKNAMEINUSE('prefix', ['param'])
- lastLine = self.getLastLine(self.transport)
- self.assertEqual(
- lastLine, 'NICK %s' % (nick + '***',))
-
-
- def test_nickChange(self):
- """
- When a NICK command is sent after signon, C{IRCClient.nickname} is set
- to the new nickname I{after} the server sends an acknowledgement.
- """
- oldnick = 'foo'
- newnick = 'bar'
- self.protocol.register(oldnick)
- self.protocol.irc_RPL_WELCOME('prefix', ['param'])
- self.protocol.setNick(newnick)
- self.assertEqual(self.protocol.nickname, oldnick)
- self.protocol.irc_NICK('%s!quux@qux' % (oldnick,), [newnick])
- self.assertEqual(self.protocol.nickname, newnick)
-
-
- def test_erroneousNick(self):
- """
- Trying to register an illegal nickname results in the default legal
- nickname being set, and trying to change a nickname to an illegal
- nickname results in the old nickname being kept.
- """
- # Registration case: change illegal nickname to erroneousNickFallback
- badnick = 'foo'
- self.assertEqual(self.protocol._registered, False)
- self.protocol.register(badnick)
- self.protocol.irc_ERR_ERRONEUSNICKNAME('prefix', ['param'])
- lastLine = self.getLastLine(self.transport)
- self.assertEqual(
- lastLine, 'NICK %s' % (self.protocol.erroneousNickFallback,))
- self.protocol.irc_RPL_WELCOME('prefix', ['param'])
- self.assertEqual(self.protocol._registered, True)
- self.protocol.setNick(self.protocol.erroneousNickFallback)
- self.assertEqual(
- self.protocol.nickname, self.protocol.erroneousNickFallback)
-
- # Illegal nick change attempt after registration. Fall back to the old
- # nickname instead of erroneousNickFallback.
- oldnick = self.protocol.nickname
- self.protocol.setNick(badnick)
- self.protocol.irc_ERR_ERRONEUSNICKNAME('prefix', ['param'])
- lastLine = self.getLastLine(self.transport)
- self.assertEqual(
- lastLine, 'NICK %s' % (badnick,))
- self.assertEqual(self.protocol.nickname, oldnick)
-
-
- def test_describe(self):
- """
- L{IRCClient.desrcibe} sends a CTCP ACTION message to the target
- specified.
- """
- target = 'foo'
- channel = '#bar'
- action = 'waves'
- self.protocol.describe(target, action)
- self.protocol.describe(channel, action)
- expected = [
- 'PRIVMSG %s :\01ACTION %s\01' % (target, action),
- 'PRIVMSG %s :\01ACTION %s\01' % (channel, action),
- '']
- self.assertEqual(self.transport.value().split('\r\n'), expected)
-
-
- def test_noticedDoesntPrivmsg(self):
- """
- The default implementation of L{IRCClient.noticed} doesn't invoke
- C{privmsg()}
- """
- def privmsg(user, channel, message):
- self.fail("privmsg() should not have been called")
- self.protocol.privmsg = privmsg
- self.protocol.irc_NOTICE(
- 'spam', ['#greasyspooncafe', "I don't want any spam!"])
-
-
-
-class DccChatFactoryTests(unittest.TestCase):
- """
- Tests for L{DccChatFactory}
- """
- def test_buildProtocol(self):
- """
- An instance of the DccChat protocol is returned, which has the factory
- property set to the factory which created it.
- """
- queryData = ('fromUser', None, None)
- f = irc.DccChatFactory(None, queryData)
- p = f.buildProtocol('127.0.0.1')
- self.assertTrue(isinstance(p, irc.DccChat))
- self.assertEqual(p.factory, f)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc_service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc_service.py
deleted file mode 100755
index f3ed292a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_irc_service.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for IRC portions of L{twisted.words.service}.
-"""
-
-from twisted.trial import unittest
-from twisted.test import proto_helpers
-from twisted.words.service import InMemoryWordsRealm, IRCFactory, IRCUser
-from twisted.words.protocols import irc
-from twisted.cred import checkers, portal
-
-class IRCUserTestCase(unittest.TestCase):
- """
- Isolated tests for L{IRCUser}
- """
-
- def setUp(self):
- """
- Sets up a Realm, Portal, Factory, IRCUser, Transport, and Connection
- for our tests.
- """
- self.wordsRealm = InMemoryWordsRealm("example.com")
- self.portal = portal.Portal(self.wordsRealm,
- [checkers.InMemoryUsernamePasswordDatabaseDontUse(john="pass")])
- self.factory = IRCFactory(self.wordsRealm, self.portal)
- self.ircUser = self.factory.buildProtocol(None)
- self.stringTransport = proto_helpers.StringTransport()
- self.ircUser.makeConnection(self.stringTransport)
-
-
- def test_sendMessage(self):
- """
- Sending a message to a user after they have sent NICK, but before they
- have authenticated, results in a message from "example.com".
- """
- self.ircUser.irc_NICK("", ["mynick"])
- self.stringTransport.clear()
- self.ircUser.sendMessage("foo")
- self.assertEqual(":example.com foo mynick\r\n",
- self.stringTransport.value())
-
-
- def response(self):
- """
- Grabs our responses and then clears the transport
- """
- response = self.ircUser.transport.value().splitlines()
- self.ircUser.transport.clear()
- return map(irc.parsemsg, response)
-
-
- def scanResponse(self, response, messageType):
- """
- Gets messages out of a response
-
- @param response: The parsed IRC messages of the response, as returned
- by L{IRCServiceTestCase.response}
-
- @param messageType: The string type of the desired messages.
-
- @return: An iterator which yields 2-tuples of C{(index, ircMessage)}
- """
- for n, message in enumerate(response):
- if (message[1] == messageType):
- yield n, message
-
-
- def test_sendNickSendsGreeting(self):
- """
- Receiving NICK without authenticating sends the MOTD Start and MOTD End
- messages, which is required by certain popular IRC clients (such as
- Pidgin) before a connection is considered to be fully established.
- """
- self.ircUser.irc_NICK("", ["mynick"])
- response = self.response()
- start = list(self.scanResponse(response, irc.RPL_MOTDSTART))
- end = list(self.scanResponse(response, irc.RPL_ENDOFMOTD))
- self.assertEqual(start,
- [(0, ('example.com', '375', ['mynick', '- example.com Message of the Day - ']))])
- self.assertEqual(end,
- [(1, ('example.com', '376', ['mynick', 'End of /MOTD command.']))])
-
-
- def test_fullLogin(self):
- """
- Receiving USER, PASS, NICK will log in the user, and transmit the
- appropriate response messages.
- """
- self.ircUser.irc_USER("", ["john doe"])
- self.ircUser.irc_PASS("", ["pass"])
- self.ircUser.irc_NICK("", ["john"])
-
- version = ('Your host is example.com, running version %s' %
- (self.factory._serverInfo["serviceVersion"],))
-
- creation = ('This server was created on %s' %
- (self.factory._serverInfo["creationDate"],))
-
- self.assertEqual(self.response(),
- [('example.com', '375',
- ['john', '- example.com Message of the Day - ']),
- ('example.com', '376', ['john', 'End of /MOTD command.']),
- ('example.com', '001', ['john', 'connected to Twisted IRC']),
- ('example.com', '002', ['john', version]),
- ('example.com', '003', ['john', creation]),
- ('example.com', '004',
- ['john', 'example.com', self.factory._serverInfo["serviceVersion"],
- 'w', 'n'])])
-
-
-
-class MocksyIRCUser(IRCUser):
- def __init__(self):
- self.mockedCodes = []
-
- def sendMessage(self, code, *_, **__):
- self.mockedCodes.append(code)
-
-BADTEXT = '\xff'
-
-class IRCUserBadEncodingTestCase(unittest.TestCase):
- """
- Verifies that L{IRCUser} sends the correct error messages back to clients
- when given indecipherable bytes
- """
- # TODO: irc_NICK -- but NICKSERV is used for that, so it isn't as easy.
-
- def setUp(self):
- self.ircuser = MocksyIRCUser()
-
- def assertChokesOnBadBytes(self, irc_x, error):
- """
- Asserts that IRCUser sends the relevant error code when a given irc_x
- dispatch method is given undecodable bytes.
-
- @param irc_x: the name of the irc_FOO method to test.
- For example, irc_x = 'PRIVMSG' will check irc_PRIVMSG
-
- @param error: the error code irc_x should send. For example,
- irc.ERR_NOTONCHANNEL
- """
- getattr(self.ircuser, 'irc_%s' % irc_x)(None, [BADTEXT])
- self.assertEqual(self.ircuser.mockedCodes, [error])
-
- # no such channel
-
- def test_JOIN(self):
- """
- Tests that irc_JOIN sends ERR_NOSUCHCHANNEL if the channel name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('JOIN', irc.ERR_NOSUCHCHANNEL)
-
- def test_NAMES(self):
- """
- Tests that irc_NAMES sends ERR_NOSUCHCHANNEL if the channel name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('NAMES', irc.ERR_NOSUCHCHANNEL)
-
- def test_TOPIC(self):
- """
- Tests that irc_TOPIC sends ERR_NOSUCHCHANNEL if the channel name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('TOPIC', irc.ERR_NOSUCHCHANNEL)
-
- def test_LIST(self):
- """
- Tests that irc_LIST sends ERR_NOSUCHCHANNEL if the channel name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('LIST', irc.ERR_NOSUCHCHANNEL)
-
- # no such nick
-
- def test_MODE(self):
- """
- Tests that irc_MODE sends ERR_NOSUCHNICK if the target name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('MODE', irc.ERR_NOSUCHNICK)
-
- def test_PRIVMSG(self):
- """
- Tests that irc_PRIVMSG sends ERR_NOSUCHNICK if the target name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('PRIVMSG', irc.ERR_NOSUCHNICK)
-
- def test_WHOIS(self):
- """
- Tests that irc_WHOIS sends ERR_NOSUCHNICK if the target name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('WHOIS', irc.ERR_NOSUCHNICK)
-
- # not on channel
-
- def test_PART(self):
- """
- Tests that irc_PART sends ERR_NOTONCHANNEL if the target name can't
- be decoded.
- """
- self.assertChokesOnBadBytes('PART', irc.ERR_NOTONCHANNEL)
-
- # probably nothing
-
- def test_WHO(self):
- """
- Tests that irc_WHO immediately ends the WHO list if the target name
- can't be decoded.
- """
- self.assertChokesOnBadBytes('WHO', irc.RPL_ENDOFWHO)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_ircsupport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_ircsupport.py
deleted file mode 100755
index de1f40b3..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_ircsupport.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.im.ircsupport}.
-"""
-
-from twisted.trial.unittest import TestCase
-from twisted.test.proto_helpers import StringTransport
-
-from twisted.words.im.basechat import Conversation, ChatUI
-from twisted.words.im.ircsupport import IRCAccount, IRCProto
-
-
-
-class StubConversation(Conversation):
- def show(self):
- pass
-
-
-
-class StubChatUI(ChatUI):
- def getGroupConversation(self, group, Class=StubConversation, stayHidden=0):
- return ChatUI.getGroupConversation(self, group, Class, stayHidden)
-
-
-
-class IRCProtoTests(TestCase):
- """
- Tests for L{IRCProto}.
- """
- def setUp(self):
- self.account = IRCAccount(
- "Some account", False, "alice", None, "example.com", 6667)
- self.proto = IRCProto(self.account, StubChatUI(), None)
-
-
- def test_login(self):
- """
- When L{IRCProto} is connected to a transport, it sends I{NICK} and
- I{USER} commands with the username from the account object.
- """
- transport = StringTransport()
- self.proto.makeConnection(transport)
- self.assertEqual(
- transport.value(),
- "NICK alice\r\n"
- "USER alice foo bar :Twisted-IM user\r\n")
-
-
- def test_authenticate(self):
- """
- If created with an account with a password, L{IRCProto} sends a
- I{PASS} command before the I{NICK} and I{USER} commands.
- """
- self.account.password = "secret"
- transport = StringTransport()
- self.proto.makeConnection(transport)
- self.assertEqual(
- transport.value(),
- "PASS :secret\r\n"
- "NICK alice\r\n"
- "USER alice foo bar :Twisted-IM user\r\n")
-
-
- def test_channels(self):
- """
- If created with an account with a list of channels, L{IRCProto}
- joins each of those channels after registering.
- """
- self.account.channels = ['#foo', '#bar']
- transport = StringTransport()
- self.proto.makeConnection(transport)
- self.assertEqual(
- transport.value(),
- "NICK alice\r\n"
- "USER alice foo bar :Twisted-IM user\r\n"
- "JOIN #foo\r\n"
- "JOIN #bar\r\n")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberclient.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberclient.py
deleted file mode 100755
index 87af8839..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberclient.py
+++ /dev/null
@@ -1,414 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.client}
-"""
-
-from twisted.internet import defer
-from twisted.python.hashlib import sha1
-from twisted.trial import unittest
-from twisted.words.protocols.jabber import client, error, jid, xmlstream
-from twisted.words.protocols.jabber.sasl import SASLInitiatingInitializer
-from twisted.words.xish import utility
-
-IQ_AUTH_GET = '/iq[@type="get"]/query[@xmlns="jabber:iq:auth"]'
-IQ_AUTH_SET = '/iq[@type="set"]/query[@xmlns="jabber:iq:auth"]'
-NS_BIND = 'urn:ietf:params:xml:ns:xmpp-bind'
-IQ_BIND_SET = '/iq[@type="set"]/bind[@xmlns="%s"]' % NS_BIND
-NS_SESSION = 'urn:ietf:params:xml:ns:xmpp-session'
-IQ_SESSION_SET = '/iq[@type="set"]/session[@xmlns="%s"]' % NS_SESSION
-
-class CheckVersionInitializerTest(unittest.TestCase):
- def setUp(self):
- a = xmlstream.Authenticator()
- xs = xmlstream.XmlStream(a)
- self.init = client.CheckVersionInitializer(xs)
-
-
- def testSupported(self):
- """
- Test supported version number 1.0
- """
- self.init.xmlstream.version = (1, 0)
- self.init.initialize()
-
-
- def testNotSupported(self):
- """
- Test unsupported version number 0.0, and check exception.
- """
- self.init.xmlstream.version = (0, 0)
- exc = self.assertRaises(error.StreamError, self.init.initialize)
- self.assertEqual('unsupported-version', exc.condition)
-
-
-
-class InitiatingInitializerHarness(object):
- """
- Testing harness for interacting with XML stream initializers.
-
- This sets up an L{utility.XmlPipe} to create a communication channel between
- the initializer and the stubbed receiving entity. It features a sink and
- source side that both act similarly to a real L{xmlstream.XmlStream}. The
- sink is augmented with an authenticator to which initializers can be added.
-
- The harness also provides some utility methods to work with event observers
- and deferreds.
- """
-
- def setUp(self):
- self.output = []
- self.pipe = utility.XmlPipe()
- self.xmlstream = self.pipe.sink
- self.authenticator = xmlstream.ConnectAuthenticator('example.org')
- self.xmlstream.authenticator = self.authenticator
-
-
- def waitFor(self, event, handler):
- """
- Observe an output event, returning a deferred.
-
- The returned deferred will be fired when the given event has been
- observed on the source end of the L{XmlPipe} tied to the protocol
- under test. The handler is added as the first callback.
-
- @param event: The event to be observed. See
- L{utility.EventDispatcher.addOnetimeObserver}.
- @param handler: The handler to be called with the observed event object.
- @rtype: L{defer.Deferred}.
- """
- d = defer.Deferred()
- d.addCallback(handler)
- self.pipe.source.addOnetimeObserver(event, d.callback)
- return d
-
-
-
-class IQAuthInitializerTest(InitiatingInitializerHarness, unittest.TestCase):
- """
- Tests for L{client.IQAuthInitializer}.
- """
-
- def setUp(self):
- super(IQAuthInitializerTest, self).setUp()
- self.init = client.IQAuthInitializer(self.xmlstream)
- self.authenticator.jid = jid.JID('user@example.com/resource')
- self.authenticator.password = 'secret'
-
-
- def testPlainText(self):
- """
- Test plain-text authentication.
-
- Act as a server supporting plain-text authentication and expect the
- C{password} field to be filled with the password. Then act as if
- authentication succeeds.
- """
-
- def onAuthGet(iq):
- """
- Called when the initializer sent a query for authentication methods.
-
- The response informs the client that plain-text authentication
- is supported.
- """
-
- # Create server response
- response = xmlstream.toResponse(iq, 'result')
- response.addElement(('jabber:iq:auth', 'query'))
- response.query.addElement('username')
- response.query.addElement('password')
- response.query.addElement('resource')
-
- # Set up an observer for the next request we expect.
- d = self.waitFor(IQ_AUTH_SET, onAuthSet)
-
- # Send server response
- self.pipe.source.send(response)
-
- return d
-
- def onAuthSet(iq):
- """
- Called when the initializer sent the authentication request.
-
- The server checks the credentials and responds with an empty result
- signalling success.
- """
- self.assertEqual('user', unicode(iq.query.username))
- self.assertEqual('secret', unicode(iq.query.password))
- self.assertEqual('resource', unicode(iq.query.resource))
-
- # Send server response
- response = xmlstream.toResponse(iq, 'result')
- self.pipe.source.send(response)
-
- # Set up an observer for the request for authentication fields
- d1 = self.waitFor(IQ_AUTH_GET, onAuthGet)
-
- # Start the initializer
- d2 = self.init.initialize()
- return defer.gatherResults([d1, d2])
-
-
- def testDigest(self):
- """
- Test digest authentication.
-
- Act as a server supporting digest authentication and expect the
- C{digest} field to be filled with a sha1 digest of the concatenated
- stream session identifier and password. Then act as if authentication
- succeeds.
- """
-
- def onAuthGet(iq):
- """
- Called when the initializer sent a query for authentication methods.
-
- The response informs the client that digest authentication is
- supported.
- """
-
- # Create server response
- response = xmlstream.toResponse(iq, 'result')
- response.addElement(('jabber:iq:auth', 'query'))
- response.query.addElement('username')
- response.query.addElement('digest')
- response.query.addElement('resource')
-
- # Set up an observer for the next request we expect.
- d = self.waitFor(IQ_AUTH_SET, onAuthSet)
-
- # Send server response
- self.pipe.source.send(response)
-
- return d
-
- def onAuthSet(iq):
- """
- Called when the initializer sent the authentication request.
-
- The server checks the credentials and responds with an empty result
- signalling success.
- """
- self.assertEqual('user', unicode(iq.query.username))
- self.assertEqual(sha1('12345secret').hexdigest(),
- unicode(iq.query.digest).encode('utf-8'))
- self.assertEqual('resource', unicode(iq.query.resource))
-
- # Send server response
- response = xmlstream.toResponse(iq, 'result')
- self.pipe.source.send(response)
-
- # Digest authentication relies on the stream session identifier. Set it.
- self.xmlstream.sid = u'12345'
-
- # Set up an observer for the request for authentication fields
- d1 = self.waitFor(IQ_AUTH_GET, onAuthGet)
-
- # Start the initializer
- d2 = self.init.initialize()
-
- return defer.gatherResults([d1, d2])
-
-
- def testFailRequestFields(self):
- """
- Test initializer failure of request for fields for authentication.
- """
- def onAuthGet(iq):
- """
- Called when the initializer sent a query for authentication methods.
-
- The server responds that the client is not authorized to authenticate.
- """
- response = error.StanzaError('not-authorized').toResponse(iq)
- self.pipe.source.send(response)
-
- # Set up an observer for the request for authentication fields
- d1 = self.waitFor(IQ_AUTH_GET, onAuthGet)
-
- # Start the initializer
- d2 = self.init.initialize()
-
- # The initialized should fail with a stanza error.
- self.assertFailure(d2, error.StanzaError)
-
- return defer.gatherResults([d1, d2])
-
-
- def testFailAuth(self):
- """
- Test initializer failure to authenticate.
- """
-
- def onAuthGet(iq):
- """
- Called when the initializer sent a query for authentication methods.
-
- The response informs the client that plain-text authentication
- is supported.
- """
-
- # Send server response
- response = xmlstream.toResponse(iq, 'result')
- response.addElement(('jabber:iq:auth', 'query'))
- response.query.addElement('username')
- response.query.addElement('password')
- response.query.addElement('resource')
-
- # Set up an observer for the next request we expect.
- d = self.waitFor(IQ_AUTH_SET, onAuthSet)
-
- # Send server response
- self.pipe.source.send(response)
-
- return d
-
- def onAuthSet(iq):
- """
- Called when the initializer sent the authentication request.
-
- The server checks the credentials and responds with a not-authorized
- stanza error.
- """
- response = error.StanzaError('not-authorized').toResponse(iq)
- self.pipe.source.send(response)
-
- # Set up an observer for the request for authentication fields
- d1 = self.waitFor(IQ_AUTH_GET, onAuthGet)
-
- # Start the initializer
- d2 = self.init.initialize()
-
- # The initializer should fail with a stanza error.
- self.assertFailure(d2, error.StanzaError)
-
- return defer.gatherResults([d1, d2])
-
-
-
-class BindInitializerTest(InitiatingInitializerHarness, unittest.TestCase):
- """
- Tests for L{client.BindInitializer}.
- """
-
- def setUp(self):
- super(BindInitializerTest, self).setUp()
- self.init = client.BindInitializer(self.xmlstream)
- self.authenticator.jid = jid.JID('user@example.com/resource')
-
-
- def testBasic(self):
- """
- Set up a stream, and act as if resource binding succeeds.
- """
- def onBind(iq):
- response = xmlstream.toResponse(iq, 'result')
- response.addElement((NS_BIND, 'bind'))
- response.bind.addElement('jid',
- content='user@example.com/other resource')
- self.pipe.source.send(response)
-
- def cb(result):
- self.assertEqual(jid.JID('user@example.com/other resource'),
- self.authenticator.jid)
-
- d1 = self.waitFor(IQ_BIND_SET, onBind)
- d2 = self.init.start()
- d2.addCallback(cb)
- return defer.gatherResults([d1, d2])
-
-
- def testFailure(self):
- """
- Set up a stream, and act as if resource binding fails.
- """
- def onBind(iq):
- response = error.StanzaError('conflict').toResponse(iq)
- self.pipe.source.send(response)
-
- d1 = self.waitFor(IQ_BIND_SET, onBind)
- d2 = self.init.start()
- self.assertFailure(d2, error.StanzaError)
- return defer.gatherResults([d1, d2])
-
-
-
-class SessionInitializerTest(InitiatingInitializerHarness, unittest.TestCase):
- """
- Tests for L{client.SessionInitializer}.
- """
-
- def setUp(self):
- super(SessionInitializerTest, self).setUp()
- self.init = client.SessionInitializer(self.xmlstream)
-
-
- def testSuccess(self):
- """
- Set up a stream, and act as if session establishment succeeds.
- """
-
- def onSession(iq):
- response = xmlstream.toResponse(iq, 'result')
- self.pipe.source.send(response)
-
- d1 = self.waitFor(IQ_SESSION_SET, onSession)
- d2 = self.init.start()
- return defer.gatherResults([d1, d2])
-
-
- def testFailure(self):
- """
- Set up a stream, and act as if session establishment fails.
- """
- def onSession(iq):
- response = error.StanzaError('forbidden').toResponse(iq)
- self.pipe.source.send(response)
-
- d1 = self.waitFor(IQ_SESSION_SET, onSession)
- d2 = self.init.start()
- self.assertFailure(d2, error.StanzaError)
- return defer.gatherResults([d1, d2])
-
-
-
-class XMPPAuthenticatorTest(unittest.TestCase):
- """
- Test for both XMPPAuthenticator and XMPPClientFactory.
- """
- def testBasic(self):
- """
- Test basic operations.
-
- Setup an XMPPClientFactory, which sets up an XMPPAuthenticator, and let
- it produce a protocol instance. Then inspect the instance variables of
- the authenticator and XML stream objects.
- """
- self.client_jid = jid.JID('user@example.com/resource')
-
- # Get an XmlStream instance. Note that it gets initialized with the
- # XMPPAuthenticator (that has its associateWithXmlStream called) that
- # is in turn initialized with the arguments to the factory.
- xs = client.XMPPClientFactory(self.client_jid,
- 'secret').buildProtocol(None)
-
- # test authenticator's instance variables
- self.assertEqual('example.com', xs.authenticator.otherHost)
- self.assertEqual(self.client_jid, xs.authenticator.jid)
- self.assertEqual('secret', xs.authenticator.password)
-
- # test list of initializers
- version, tls, sasl, bind, session = xs.initializers
-
- self.assert_(isinstance(tls, xmlstream.TLSInitiatingInitializer))
- self.assert_(isinstance(sasl, SASLInitiatingInitializer))
- self.assert_(isinstance(bind, client.BindInitializer))
- self.assert_(isinstance(session, client.SessionInitializer))
-
- self.assertFalse(tls.required)
- self.assertTrue(sasl.required)
- self.assertFalse(bind.required)
- self.assertFalse(session.required)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbercomponent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbercomponent.py
deleted file mode 100755
index d8bb1089..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbercomponent.py
+++ /dev/null
@@ -1,422 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.component}
-"""
-
-from twisted.python import failure
-from twisted.python.hashlib import sha1
-from twisted.trial import unittest
-from twisted.words.protocols.jabber import component, xmlstream
-from twisted.words.protocols.jabber.jid import JID
-from twisted.words.xish import domish
-from twisted.words.xish.utility import XmlPipe
-
-class DummyTransport:
- def __init__(self, list):
- self.list = list
-
- def write(self, bytes):
- self.list.append(bytes)
-
-class ComponentInitiatingInitializerTest(unittest.TestCase):
- def setUp(self):
- self.output = []
-
- self.authenticator = xmlstream.Authenticator()
- self.authenticator.password = 'secret'
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
- self.xmlstream.namespace = 'test:component'
- self.xmlstream.send = self.output.append
- self.xmlstream.connectionMade()
- self.xmlstream.dataReceived(
- "<stream:stream xmlns='test:component' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='1.0'>")
- self.xmlstream.sid = u'12345'
- self.init = component.ComponentInitiatingInitializer(self.xmlstream)
-
- def testHandshake(self):
- """
- Test basic operations of component handshake.
- """
-
- d = self.init.initialize()
-
- # the initializer should have sent the handshake request
-
- handshake = self.output[-1]
- self.assertEqual('handshake', handshake.name)
- self.assertEqual('test:component', handshake.uri)
- self.assertEqual(sha1("%s%s" % ('12345', 'secret')).hexdigest(),
- unicode(handshake))
-
- # successful authentication
-
- handshake.children = []
- self.xmlstream.dataReceived(handshake.toXml())
-
- return d
-
-class ComponentAuthTest(unittest.TestCase):
- def authPassed(self, stream):
- self.authComplete = True
-
- def testAuth(self):
- self.authComplete = False
- outlist = []
-
- ca = component.ConnectComponentAuthenticator("cjid", "secret")
- xs = xmlstream.XmlStream(ca)
- xs.transport = DummyTransport(outlist)
-
- xs.addObserver(xmlstream.STREAM_AUTHD_EVENT,
- self.authPassed)
-
- # Go...
- xs.connectionMade()
- xs.dataReceived("<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' from='cjid' id='12345'>")
-
- # Calculate what we expect the handshake value to be
- hv = sha1("%s%s" % ("12345", "secret")).hexdigest()
-
- self.assertEqual(outlist[1], "<handshake>%s</handshake>" % (hv))
-
- xs.dataReceived("<handshake/>")
-
- self.assertEqual(self.authComplete, True)
-
-
-class JabberServiceHarness(component.Service):
- def __init__(self):
- self.componentConnectedFlag = False
- self.componentDisconnectedFlag = False
- self.transportConnectedFlag = False
-
- def componentConnected(self, xmlstream):
- self.componentConnectedFlag = True
-
- def componentDisconnected(self):
- self.componentDisconnectedFlag = True
-
- def transportConnected(self, xmlstream):
- self.transportConnectedFlag = True
-
-
-class TestJabberServiceManager(unittest.TestCase):
- def testSM(self):
- # Setup service manager and test harnes
- sm = component.ServiceManager("foo", "password")
- svc = JabberServiceHarness()
- svc.setServiceParent(sm)
-
- # Create a write list
- wlist = []
-
- # Setup a XmlStream
- xs = sm.getFactory().buildProtocol(None)
- xs.transport = self
- xs.transport.write = wlist.append
-
- # Indicate that it's connected
- xs.connectionMade()
-
- # Ensure the test service harness got notified
- self.assertEqual(True, svc.transportConnectedFlag)
-
- # Jump ahead and pretend like the stream got auth'd
- xs.dispatch(xs, xmlstream.STREAM_AUTHD_EVENT)
-
- # Ensure the test service harness got notified
- self.assertEqual(True, svc.componentConnectedFlag)
-
- # Pretend to drop the connection
- xs.connectionLost(None)
-
- # Ensure the test service harness got notified
- self.assertEqual(True, svc.componentDisconnectedFlag)
-
-
-
-class RouterTest(unittest.TestCase):
- """
- Tests for L{component.Router}.
- """
-
- def test_addRoute(self):
- """
- Test route registration and routing on incoming stanzas.
- """
- router = component.Router()
- routed = []
- router.route = lambda element: routed.append(element)
-
- pipe = XmlPipe()
- router.addRoute('example.org', pipe.sink)
- self.assertEqual(1, len(router.routes))
- self.assertEqual(pipe.sink, router.routes['example.org'])
-
- element = domish.Element(('testns', 'test'))
- pipe.source.send(element)
- self.assertEqual([element], routed)
-
-
- def test_route(self):
- """
- Test routing of a message.
- """
- component1 = XmlPipe()
- component2 = XmlPipe()
- router = component.Router()
- router.addRoute('component1.example.org', component1.sink)
- router.addRoute('component2.example.org', component2.sink)
-
- outgoing = []
- component2.source.addObserver('/*',
- lambda element: outgoing.append(element))
- stanza = domish.Element((None, 'presence'))
- stanza['from'] = 'component1.example.org'
- stanza['to'] = 'component2.example.org'
- component1.source.send(stanza)
- self.assertEqual([stanza], outgoing)
-
-
- def test_routeDefault(self):
- """
- Test routing of a message using the default route.
-
- The default route is the one with C{None} as its key in the
- routing table. It is taken when there is no more specific route
- in the routing table that matches the stanza's destination.
- """
- component1 = XmlPipe()
- s2s = XmlPipe()
- router = component.Router()
- router.addRoute('component1.example.org', component1.sink)
- router.addRoute(None, s2s.sink)
-
- outgoing = []
- s2s.source.addObserver('/*', lambda element: outgoing.append(element))
- stanza = domish.Element((None, 'presence'))
- stanza['from'] = 'component1.example.org'
- stanza['to'] = 'example.com'
- component1.source.send(stanza)
- self.assertEqual([stanza], outgoing)
-
-
-
-class ListenComponentAuthenticatorTest(unittest.TestCase):
- """
- Tests for L{component.ListenComponentAuthenticator}.
- """
-
- def setUp(self):
- self.output = []
- authenticator = component.ListenComponentAuthenticator('secret')
- self.xmlstream = xmlstream.XmlStream(authenticator)
- self.xmlstream.send = self.output.append
-
-
- def loseConnection(self):
- """
- Stub loseConnection because we are a transport.
- """
- self.xmlstream.connectionLost("no reason")
-
-
- def test_streamStarted(self):
- """
- The received stream header should set several attributes.
- """
- observers = []
-
- def addOnetimeObserver(event, observerfn):
- observers.append((event, observerfn))
-
- xs = self.xmlstream
- xs.addOnetimeObserver = addOnetimeObserver
-
- xs.makeConnection(self)
- self.assertIdentical(None, xs.sid)
- self.assertFalse(xs._headerSent)
-
- xs.dataReceived("<stream:stream xmlns='jabber:component:accept' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "to='component.example.org'>")
- self.assertEqual((0, 0), xs.version)
- self.assertNotIdentical(None, xs.sid)
- self.assertTrue(xs._headerSent)
- self.assertEqual(('/*', xs.authenticator.onElement), observers[-1])
-
-
- def test_streamStartedWrongNamespace(self):
- """
- The received stream header should have a correct namespace.
- """
- streamErrors = []
-
- xs = self.xmlstream
- xs.sendStreamError = streamErrors.append
- xs.makeConnection(self)
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "to='component.example.org'>")
- self.assertEqual(1, len(streamErrors))
- self.assertEqual('invalid-namespace', streamErrors[-1].condition)
-
-
- def test_streamStartedNoTo(self):
- """
- The received stream header should have a 'to' attribute.
- """
- streamErrors = []
-
- xs = self.xmlstream
- xs.sendStreamError = streamErrors.append
- xs.makeConnection(self)
- xs.dataReceived("<stream:stream xmlns='jabber:component:accept' "
- "xmlns:stream='http://etherx.jabber.org/streams'>")
- self.assertEqual(1, len(streamErrors))
- self.assertEqual('improper-addressing', streamErrors[-1].condition)
-
-
- def test_onElement(self):
- """
- We expect a handshake element with a hash.
- """
- handshakes = []
-
- xs = self.xmlstream
- xs.authenticator.onHandshake = handshakes.append
-
- handshake = domish.Element(('jabber:component:accept', 'handshake'))
- handshake.addContent('1234')
- xs.authenticator.onElement(handshake)
- self.assertEqual('1234', handshakes[-1])
-
- def test_onElementNotHandshake(self):
- """
- Reject elements that are not handshakes
- """
- handshakes = []
- streamErrors = []
-
- xs = self.xmlstream
- xs.authenticator.onHandshake = handshakes.append
- xs.sendStreamError = streamErrors.append
-
- element = domish.Element(('jabber:component:accept', 'message'))
- xs.authenticator.onElement(element)
- self.assertFalse(handshakes)
- self.assertEqual('not-authorized', streamErrors[-1].condition)
-
-
- def test_onHandshake(self):
- """
- Receiving a handshake matching the secret authenticates the stream.
- """
- authd = []
-
- def authenticated(xs):
- authd.append(xs)
-
- xs = self.xmlstream
- xs.addOnetimeObserver(xmlstream.STREAM_AUTHD_EVENT, authenticated)
- xs.sid = u'1234'
- theHash = '32532c0f7dbf1253c095b18b18e36d38d94c1256'
- xs.authenticator.onHandshake(theHash)
- self.assertEqual('<handshake/>', self.output[-1])
- self.assertEqual(1, len(authd))
-
-
- def test_onHandshakeWrongHash(self):
- """
- Receiving a bad handshake should yield a stream error.
- """
- streamErrors = []
- authd = []
-
- def authenticated(xs):
- authd.append(xs)
-
- xs = self.xmlstream
- xs.addOnetimeObserver(xmlstream.STREAM_AUTHD_EVENT, authenticated)
- xs.sendStreamError = streamErrors.append
-
- xs.sid = u'1234'
- theHash = '1234'
- xs.authenticator.onHandshake(theHash)
- self.assertEqual('not-authorized', streamErrors[-1].condition)
- self.assertEqual(0, len(authd))
-
-
-
-class XMPPComponentServerFactoryTest(unittest.TestCase):
- """
- Tests for L{component.XMPPComponentServerFactory}.
- """
-
- def setUp(self):
- self.router = component.Router()
- self.factory = component.XMPPComponentServerFactory(self.router,
- 'secret')
- self.xmlstream = self.factory.buildProtocol(None)
- self.xmlstream.thisEntity = JID('component.example.org')
-
-
- def test_makeConnection(self):
- """
- A new connection increases the stream serial count. No logs by default.
- """
- self.xmlstream.dispatch(self.xmlstream,
- xmlstream.STREAM_CONNECTED_EVENT)
- self.assertEqual(0, self.xmlstream.serial)
- self.assertEqual(1, self.factory.serial)
- self.assertIdentical(None, self.xmlstream.rawDataInFn)
- self.assertIdentical(None, self.xmlstream.rawDataOutFn)
-
-
- def test_makeConnectionLogTraffic(self):
- """
- Setting logTraffic should set up raw data loggers.
- """
- self.factory.logTraffic = True
- self.xmlstream.dispatch(self.xmlstream,
- xmlstream.STREAM_CONNECTED_EVENT)
- self.assertNotIdentical(None, self.xmlstream.rawDataInFn)
- self.assertNotIdentical(None, self.xmlstream.rawDataOutFn)
-
-
- def test_onError(self):
- """
- An observer for stream errors should trigger onError to log it.
- """
- self.xmlstream.dispatch(self.xmlstream,
- xmlstream.STREAM_CONNECTED_EVENT)
-
- class TestError(Exception):
- pass
-
- reason = failure.Failure(TestError())
- self.xmlstream.dispatch(reason, xmlstream.STREAM_ERROR_EVENT)
- self.assertEqual(1, len(self.flushLoggedErrors(TestError)))
-
-
- def test_connectionInitialized(self):
- """
- Make sure a new stream is added to the routing table.
- """
- self.xmlstream.dispatch(self.xmlstream, xmlstream.STREAM_AUTHD_EVENT)
- self.assertIn('component.example.org', self.router.routes)
- self.assertIdentical(self.xmlstream,
- self.router.routes['component.example.org'])
-
-
- def test_connectionLost(self):
- """
- Make sure a stream is removed from the routing table on disconnect.
- """
- self.xmlstream.dispatch(self.xmlstream, xmlstream.STREAM_AUTHD_EVENT)
- self.xmlstream.dispatch(None, xmlstream.STREAM_END_EVENT)
- self.assertNotIn('component.example.org', self.router.routes)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbererror.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbererror.py
deleted file mode 100755
index 45d8dac8..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbererror.py
+++ /dev/null
@@ -1,342 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.error}.
-"""
-
-from twisted.trial import unittest
-
-from twisted.words.protocols.jabber import error
-from twisted.words.xish import domish
-
-NS_XML = 'http://www.w3.org/XML/1998/namespace'
-NS_STREAMS = 'http://etherx.jabber.org/streams'
-NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
-NS_XMPP_STANZAS = 'urn:ietf:params:xml:ns:xmpp-stanzas'
-
-class BaseErrorTest(unittest.TestCase):
-
- def test_getElementPlain(self):
- """
- Test getting an element for a plain error.
- """
- e = error.BaseError('feature-not-implemented')
- element = e.getElement()
- self.assertIdentical(element.uri, None)
- self.assertEqual(len(element.children), 1)
-
- def test_getElementText(self):
- """
- Test getting an element for an error with a text.
- """
- e = error.BaseError('feature-not-implemented', 'text')
- element = e.getElement()
- self.assertEqual(len(element.children), 2)
- self.assertEqual(unicode(element.text), 'text')
- self.assertEqual(element.text.getAttribute((NS_XML, 'lang')), None)
-
- def test_getElementTextLang(self):
- """
- Test getting an element for an error with a text and language.
- """
- e = error.BaseError('feature-not-implemented', 'text', 'en_US')
- element = e.getElement()
- self.assertEqual(len(element.children), 2)
- self.assertEqual(unicode(element.text), 'text')
- self.assertEqual(element.text[(NS_XML, 'lang')], 'en_US')
-
- def test_getElementAppCondition(self):
- """
- Test getting an element for an error with an app specific condition.
- """
- ac = domish.Element(('testns', 'myerror'))
- e = error.BaseError('feature-not-implemented', appCondition=ac)
- element = e.getElement()
- self.assertEqual(len(element.children), 2)
- self.assertEqual(element.myerror, ac)
-
-class StreamErrorTest(unittest.TestCase):
-
- def test_getElementPlain(self):
- """
- Test namespace of the element representation of an error.
- """
- e = error.StreamError('feature-not-implemented')
- element = e.getElement()
- self.assertEqual(element.uri, NS_STREAMS)
-
- def test_getElementConditionNamespace(self):
- """
- Test that the error condition element has the correct namespace.
- """
- e = error.StreamError('feature-not-implemented')
- element = e.getElement()
- self.assertEqual(NS_XMPP_STREAMS, getattr(element, 'feature-not-implemented').uri)
-
- def test_getElementTextNamespace(self):
- """
- Test that the error text element has the correct namespace.
- """
- e = error.StreamError('feature-not-implemented', 'text')
- element = e.getElement()
- self.assertEqual(NS_XMPP_STREAMS, element.text.uri)
-
-
-
-class StanzaErrorTest(unittest.TestCase):
- """
- Tests for L{error.StreamError}.
- """
-
-
- def test_typeRemoteServerTimeout(self):
- """
- Remote Server Timeout should yield type wait, code 504.
- """
- e = error.StanzaError('remote-server-timeout')
- self.assertEqual('wait', e.type)
- self.assertEqual('504', e.code)
-
-
- def test_getElementPlain(self):
- """
- Test getting an element for a plain stanza error.
- """
- e = error.StanzaError('feature-not-implemented')
- element = e.getElement()
- self.assertEqual(element.uri, None)
- self.assertEqual(element['type'], 'cancel')
- self.assertEqual(element['code'], '501')
-
-
- def test_getElementType(self):
- """
- Test getting an element for a stanza error with a given type.
- """
- e = error.StanzaError('feature-not-implemented', 'auth')
- element = e.getElement()
- self.assertEqual(element.uri, None)
- self.assertEqual(element['type'], 'auth')
- self.assertEqual(element['code'], '501')
-
-
- def test_getElementConditionNamespace(self):
- """
- Test that the error condition element has the correct namespace.
- """
- e = error.StanzaError('feature-not-implemented')
- element = e.getElement()
- self.assertEqual(NS_XMPP_STANZAS, getattr(element, 'feature-not-implemented').uri)
-
-
- def test_getElementTextNamespace(self):
- """
- Test that the error text element has the correct namespace.
- """
- e = error.StanzaError('feature-not-implemented', text='text')
- element = e.getElement()
- self.assertEqual(NS_XMPP_STANZAS, element.text.uri)
-
-
- def test_toResponse(self):
- """
- Test an error response is generated from a stanza.
-
- The addressing on the (new) response stanza should be reversed, an
- error child (with proper properties) added and the type set to
- C{'error'}.
- """
- stanza = domish.Element(('jabber:client', 'message'))
- stanza['type'] = 'chat'
- stanza['to'] = 'user1@example.com'
- stanza['from'] = 'user2@example.com/resource'
- e = error.StanzaError('service-unavailable')
- response = e.toResponse(stanza)
- self.assertNotIdentical(response, stanza)
- self.assertEqual(response['from'], 'user1@example.com')
- self.assertEqual(response['to'], 'user2@example.com/resource')
- self.assertEqual(response['type'], 'error')
- self.assertEqual(response.error.children[0].name,
- 'service-unavailable')
- self.assertEqual(response.error['type'], 'cancel')
- self.assertNotEqual(stanza.children, response.children)
-
-
-
-class ParseErrorTest(unittest.TestCase):
- """
- Tests for L{error._parseError}.
- """
-
-
- def setUp(self):
- self.error = domish.Element((None, 'error'))
-
-
- def test_empty(self):
- """
- Test parsing of the empty error element.
- """
- result = error._parseError(self.error, 'errorns')
- self.assertEqual({'condition': None,
- 'text': None,
- 'textLang': None,
- 'appCondition': None}, result)
-
-
- def test_condition(self):
- """
- Test parsing of an error element with a condition.
- """
- self.error.addElement(('errorns', 'bad-request'))
- result = error._parseError(self.error, 'errorns')
- self.assertEqual('bad-request', result['condition'])
-
-
- def test_text(self):
- """
- Test parsing of an error element with a text.
- """
- text = self.error.addElement(('errorns', 'text'))
- text.addContent('test')
- result = error._parseError(self.error, 'errorns')
- self.assertEqual('test', result['text'])
- self.assertEqual(None, result['textLang'])
-
-
- def test_textLang(self):
- """
- Test parsing of an error element with a text with a defined language.
- """
- text = self.error.addElement(('errorns', 'text'))
- text[NS_XML, 'lang'] = 'en_US'
- text.addContent('test')
- result = error._parseError(self.error, 'errorns')
- self.assertEqual('en_US', result['textLang'])
-
-
- def test_textLangInherited(self):
- """
- Test parsing of an error element with a text with inherited language.
- """
- text = self.error.addElement(('errorns', 'text'))
- self.error[NS_XML, 'lang'] = 'en_US'
- text.addContent('test')
- result = error._parseError(self.error, 'errorns')
- self.assertEqual('en_US', result['textLang'])
- test_textLangInherited.todo = "xml:lang inheritance not implemented"
-
-
- def test_appCondition(self):
- """
- Test parsing of an error element with an app specific condition.
- """
- condition = self.error.addElement(('testns', 'condition'))
- result = error._parseError(self.error, 'errorns')
- self.assertEqual(condition, result['appCondition'])
-
-
- def test_appConditionMultiple(self):
- """
- Test parsing of an error element with multiple app specific conditions.
- """
- self.error.addElement(('testns', 'condition'))
- condition = self.error.addElement(('testns', 'condition2'))
- result = error._parseError(self.error, 'errorns')
- self.assertEqual(condition, result['appCondition'])
-
-
-
-class ExceptionFromStanzaTest(unittest.TestCase):
-
- def test_basic(self):
- """
- Test basic operations of exceptionFromStanza.
-
- Given a realistic stanza, check if a sane exception is returned.
-
- Using this stanza::
-
- <iq type='error'
- from='pubsub.shakespeare.lit'
- to='francisco@denmark.lit/barracks'
- id='subscriptions1'>
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
- <subscriptions/>
- </pubsub>
- <error type='cancel'>
- <feature-not-implemented
- xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
- <unsupported xmlns='http://jabber.org/protocol/pubsub#errors'
- feature='retrieve-subscriptions'/>
- </error>
- </iq>
- """
-
- stanza = domish.Element((None, 'stanza'))
- p = stanza.addElement(('http://jabber.org/protocol/pubsub', 'pubsub'))
- p.addElement('subscriptions')
- e = stanza.addElement('error')
- e['type'] = 'cancel'
- e.addElement((NS_XMPP_STANZAS, 'feature-not-implemented'))
- uc = e.addElement(('http://jabber.org/protocol/pubsub#errors',
- 'unsupported'))
- uc['feature'] = 'retrieve-subscriptions'
-
- result = error.exceptionFromStanza(stanza)
- self.assert_(isinstance(result, error.StanzaError))
- self.assertEqual('feature-not-implemented', result.condition)
- self.assertEqual('cancel', result.type)
- self.assertEqual(uc, result.appCondition)
- self.assertEqual([p], result.children)
-
- def test_legacy(self):
- """
- Test legacy operations of exceptionFromStanza.
-
- Given a realistic stanza with only legacy (pre-XMPP) error information,
- check if a sane exception is returned.
-
- Using this stanza::
-
- <message type='error'
- to='piers@pipetree.com/Home'
- from='qmacro@jaber.org'>
- <body>Are you there?</body>
- <error code='502'>Unable to resolve hostname.</error>
- </message>
- """
- stanza = domish.Element((None, 'stanza'))
- p = stanza.addElement('body', content='Are you there?')
- e = stanza.addElement('error', content='Unable to resolve hostname.')
- e['code'] = '502'
-
- result = error.exceptionFromStanza(stanza)
- self.assert_(isinstance(result, error.StanzaError))
- self.assertEqual('service-unavailable', result.condition)
- self.assertEqual('wait', result.type)
- self.assertEqual('Unable to resolve hostname.', result.text)
- self.assertEqual([p], result.children)
-
-class ExceptionFromStreamErrorTest(unittest.TestCase):
-
- def test_basic(self):
- """
- Test basic operations of exceptionFromStreamError.
-
- Given a realistic stream error, check if a sane exception is returned.
-
- Using this error::
-
- <stream:error xmlns:stream='http://etherx.jabber.org/streams'>
- <xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
- </stream:error>
- """
-
- e = domish.Element(('http://etherx.jabber.org/streams', 'error'))
- e.addElement((NS_XMPP_STREAMS, 'xml-not-well-formed'))
-
- result = error.exceptionFromStreamError(e)
- self.assert_(isinstance(result, error.StreamError))
- self.assertEqual('xml-not-well-formed', result.condition)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjid.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjid.py
deleted file mode 100755
index fa3a1197..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjid.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.jid}.
-"""
-
-from twisted.trial import unittest
-
-from twisted.words.protocols.jabber import jid
-
-class JIDParsingTest(unittest.TestCase):
- def test_parse(self):
- """
- Test different forms of JIDs.
- """
- # Basic forms
- self.assertEqual(jid.parse("user@host/resource"),
- ("user", "host", "resource"))
- self.assertEqual(jid.parse("user@host"),
- ("user", "host", None))
- self.assertEqual(jid.parse("host"),
- (None, "host", None))
- self.assertEqual(jid.parse("host/resource"),
- (None, "host", "resource"))
-
- # More interesting forms
- self.assertEqual(jid.parse("foo/bar@baz"),
- (None, "foo", "bar@baz"))
- self.assertEqual(jid.parse("boo@foo/bar@baz"),
- ("boo", "foo", "bar@baz"))
- self.assertEqual(jid.parse("boo@foo/bar/baz"),
- ("boo", "foo", "bar/baz"))
- self.assertEqual(jid.parse("boo/foo@bar@baz"),
- (None, "boo", "foo@bar@baz"))
- self.assertEqual(jid.parse("boo/foo/bar"),
- (None, "boo", "foo/bar"))
- self.assertEqual(jid.parse("boo//foo"),
- (None, "boo", "/foo"))
-
- def test_noHost(self):
- """
- Test for failure on no host part.
- """
- self.assertRaises(jid.InvalidFormat, jid.parse, "user@")
-
- def test_doubleAt(self):
- """
- Test for failure on double @ signs.
-
- This should fail because @ is not a valid character for the host
- part of the JID.
- """
- self.assertRaises(jid.InvalidFormat, jid.parse, "user@@host")
-
- def test_multipleAt(self):
- """
- Test for failure on two @ signs.
-
- This should fail because @ is not a valid character for the host
- part of the JID.
- """
- self.assertRaises(jid.InvalidFormat, jid.parse, "user@host@host")
-
- # Basic tests for case mapping. These are fallback tests for the
- # prepping done in twisted.words.protocols.jabber.xmpp_stringprep
-
- def test_prepCaseMapUser(self):
- """
- Test case mapping of the user part of the JID.
- """
- self.assertEqual(jid.prep("UsEr", "host", "resource"),
- ("user", "host", "resource"))
-
- def test_prepCaseMapHost(self):
- """
- Test case mapping of the host part of the JID.
- """
- self.assertEqual(jid.prep("user", "hoST", "resource"),
- ("user", "host", "resource"))
-
- def test_prepNoCaseMapResource(self):
- """
- Test no case mapping of the resourcce part of the JID.
- """
- self.assertEqual(jid.prep("user", "hoST", "resource"),
- ("user", "host", "resource"))
- self.assertNotEquals(jid.prep("user", "host", "Resource"),
- ("user", "host", "resource"))
-
-class JIDTest(unittest.TestCase):
-
- def test_noneArguments(self):
- """
- Test that using no arguments raises an exception.
- """
- self.assertRaises(RuntimeError, jid.JID)
-
- def test_attributes(self):
- """
- Test that the attributes correspond with the JID parts.
- """
- j = jid.JID("user@host/resource")
- self.assertEqual(j.user, "user")
- self.assertEqual(j.host, "host")
- self.assertEqual(j.resource, "resource")
-
- def test_userhost(self):
- """
- Test the extraction of the bare JID.
- """
- j = jid.JID("user@host/resource")
- self.assertEqual("user@host", j.userhost())
-
- def test_userhostOnlyHost(self):
- """
- Test the extraction of the bare JID of the full form host/resource.
- """
- j = jid.JID("host/resource")
- self.assertEqual("host", j.userhost())
-
- def test_userhostJID(self):
- """
- Test getting a JID object of the bare JID.
- """
- j1 = jid.JID("user@host/resource")
- j2 = jid.internJID("user@host")
- self.assertIdentical(j2, j1.userhostJID())
-
- def test_userhostJIDNoResource(self):
- """
- Test getting a JID object of the bare JID when there was no resource.
- """
- j = jid.JID("user@host")
- self.assertIdentical(j, j.userhostJID())
-
- def test_fullHost(self):
- """
- Test giving a string representation of the JID with only a host part.
- """
- j = jid.JID(tuple=(None, 'host', None))
- self.assertEqual('host', j.full())
-
- def test_fullHostResource(self):
- """
- Test giving a string representation of the JID with host, resource.
- """
- j = jid.JID(tuple=(None, 'host', 'resource'))
- self.assertEqual('host/resource', j.full())
-
- def test_fullUserHost(self):
- """
- Test giving a string representation of the JID with user, host.
- """
- j = jid.JID(tuple=('user', 'host', None))
- self.assertEqual('user@host', j.full())
-
- def test_fullAll(self):
- """
- Test giving a string representation of the JID.
- """
- j = jid.JID(tuple=('user', 'host', 'resource'))
- self.assertEqual('user@host/resource', j.full())
-
- def test_equality(self):
- """
- Test JID equality.
- """
- j1 = jid.JID("user@host/resource")
- j2 = jid.JID("user@host/resource")
- self.assertNotIdentical(j1, j2)
- self.assertEqual(j1, j2)
-
- def test_equalityWithNonJIDs(self):
- """
- Test JID equality.
- """
- j = jid.JID("user@host/resource")
- self.assertFalse(j == 'user@host/resource')
-
- def test_inequality(self):
- """
- Test JID inequality.
- """
- j1 = jid.JID("user1@host/resource")
- j2 = jid.JID("user2@host/resource")
- self.assertNotEqual(j1, j2)
-
- def test_inequalityWithNonJIDs(self):
- """
- Test JID equality.
- """
- j = jid.JID("user@host/resource")
- self.assertNotEqual(j, 'user@host/resource')
-
- def test_hashable(self):
- """
- Test JID hashability.
- """
- j1 = jid.JID("user@host/resource")
- j2 = jid.JID("user@host/resource")
- self.assertEqual(hash(j1), hash(j2))
-
- def test_unicode(self):
- """
- Test unicode representation of JIDs.
- """
- j = jid.JID(tuple=('user', 'host', 'resource'))
- self.assertEqual("user@host/resource", unicode(j))
-
- def test_repr(self):
- """
- Test representation of JID objects.
- """
- j = jid.JID(tuple=('user', 'host', 'resource'))
- self.assertEqual("JID(u'user@host/resource')", repr(j))
-
-class InternJIDTest(unittest.TestCase):
- def test_identity(self):
- """
- Test that two interned JIDs yield the same object.
- """
- j1 = jid.internJID("user@host")
- j2 = jid.internJID("user@host")
- self.assertIdentical(j1, j2)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjstrports.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjstrports.py
deleted file mode 100755
index 6d8f045d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberjstrports.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.jstrports}.
-"""
-
-from twisted.trial import unittest
-
-from twisted.words.protocols.jabber import jstrports
-from twisted.application.internet import TCPClient
-
-
-class JabberStrPortsPlaceHolderTest(unittest.TestCase):
- """
- Tests for L{jstrports}
- """
-
- def test_parse(self):
- """
- L{jstrports.parse} accepts an endpoint description string and returns a
- tuple and dict of parsed endpoint arguments.
- """
- expected = ('TCP', ('DOMAIN', 65535, 'Factory'), {})
- got = jstrports.parse("tcp:DOMAIN:65535", "Factory")
- self.assertEqual(expected, got)
-
-
- def test_client(self):
- """
- L{jstrports.client} returns a L{TCPClient} service.
- """
- got = jstrports.client("tcp:DOMAIN:65535", "Factory")
- self.assertIsInstance(got, TCPClient)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersasl.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersasl.py
deleted file mode 100755
index b22f9567..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersasl.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from zope.interface import implements
-from twisted.internet import defer
-from twisted.trial import unittest
-from twisted.words.protocols.jabber import sasl, sasl_mechanisms, xmlstream, jid
-from twisted.words.xish import domish
-
-NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl'
-
-class DummySASLMechanism(object):
- """
- Dummy SASL mechanism.
-
- This just returns the initialResponse passed on creation, stores any
- challenges and replies with an empty response.
-
- @ivar challenge: Last received challenge.
- @type challenge: C{unicode}.
- @ivar initialResponse: Initial response to be returned when requested
- via C{getInitialResponse} or C{None}.
- @type initialResponse: C{unicode}
- """
-
- implements(sasl_mechanisms.ISASLMechanism)
-
- challenge = None
- name = "DUMMY"
-
- def __init__(self, initialResponse):
- self.initialResponse = initialResponse
-
- def getInitialResponse(self):
- return self.initialResponse
-
- def getResponse(self, challenge):
- self.challenge = challenge
- return ""
-
-class DummySASLInitiatingInitializer(sasl.SASLInitiatingInitializer):
- """
- Dummy SASL Initializer for initiating entities.
-
- This hardwires the SASL mechanism to L{DummySASLMechanism}, that is
- instantiated with the value of C{initialResponse}.
-
- @ivar initialResponse: The initial response to be returned by the
- dummy SASL mechanism or C{None}.
- @type initialResponse: C{unicode}.
- """
-
- initialResponse = None
-
- def setMechanism(self):
- self.mechanism = DummySASLMechanism(self.initialResponse)
-
-
-
-class SASLInitiatingInitializerTest(unittest.TestCase):
- """
- Tests for L{sasl.SASLInitiatingInitializer}
- """
-
- def setUp(self):
- self.output = []
-
- self.authenticator = xmlstream.Authenticator()
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
- self.xmlstream.send = self.output.append
- self.xmlstream.connectionMade()
- self.xmlstream.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='1.0'>")
- self.init = DummySASLInitiatingInitializer(self.xmlstream)
-
-
- def test_onFailure(self):
- """
- Test that the SASL error condition is correctly extracted.
- """
- failure = domish.Element(('urn:ietf:params:xml:ns:xmpp-sasl',
- 'failure'))
- failure.addElement('not-authorized')
- self.init._deferred = defer.Deferred()
- self.init.onFailure(failure)
- self.assertFailure(self.init._deferred, sasl.SASLAuthError)
- self.init._deferred.addCallback(lambda e:
- self.assertEqual('not-authorized',
- e.condition))
- return self.init._deferred
-
-
- def test_sendAuthInitialResponse(self):
- """
- Test starting authentication with an initial response.
- """
- self.init.initialResponse = "dummy"
- self.init.start()
- auth = self.output[0]
- self.assertEqual(NS_XMPP_SASL, auth.uri)
- self.assertEqual('auth', auth.name)
- self.assertEqual('DUMMY', auth['mechanism'])
- self.assertEqual('ZHVtbXk=', str(auth))
-
-
- def test_sendAuthNoInitialResponse(self):
- """
- Test starting authentication without an initial response.
- """
- self.init.initialResponse = None
- self.init.start()
- auth = self.output[0]
- self.assertEqual('', str(auth))
-
-
- def test_sendAuthEmptyInitialResponse(self):
- """
- Test starting authentication where the initial response is empty.
- """
- self.init.initialResponse = ""
- self.init.start()
- auth = self.output[0]
- self.assertEqual('=', str(auth))
-
-
- def test_onChallenge(self):
- """
- Test receiving a challenge message.
- """
- d = self.init.start()
- challenge = domish.Element((NS_XMPP_SASL, 'challenge'))
- challenge.addContent('bXkgY2hhbGxlbmdl')
- self.init.onChallenge(challenge)
- self.assertEqual('my challenge', self.init.mechanism.challenge)
- self.init.onSuccess(None)
- return d
-
-
- def test_onChallengeEmpty(self):
- """
- Test receiving an empty challenge message.
- """
- d = self.init.start()
- challenge = domish.Element((NS_XMPP_SASL, 'challenge'))
- self.init.onChallenge(challenge)
- self.assertEqual('', self.init.mechanism.challenge)
- self.init.onSuccess(None)
- return d
-
-
- def test_onChallengeIllegalPadding(self):
- """
- Test receiving a challenge message with illegal padding.
- """
- d = self.init.start()
- challenge = domish.Element((NS_XMPP_SASL, 'challenge'))
- challenge.addContent('bXkg=Y2hhbGxlbmdl')
- self.init.onChallenge(challenge)
- self.assertFailure(d, sasl.SASLIncorrectEncodingError)
- return d
-
-
- def test_onChallengeIllegalCharacters(self):
- """
- Test receiving a challenge message with illegal characters.
- """
- d = self.init.start()
- challenge = domish.Element((NS_XMPP_SASL, 'challenge'))
- challenge.addContent('bXkg*Y2hhbGxlbmdl')
- self.init.onChallenge(challenge)
- self.assertFailure(d, sasl.SASLIncorrectEncodingError)
- return d
-
-
- def test_onChallengeMalformed(self):
- """
- Test receiving a malformed challenge message.
- """
- d = self.init.start()
- challenge = domish.Element((NS_XMPP_SASL, 'challenge'))
- challenge.addContent('a')
- self.init.onChallenge(challenge)
- self.assertFailure(d, sasl.SASLIncorrectEncodingError)
- return d
-
-
-class SASLInitiatingInitializerSetMechanismTest(unittest.TestCase):
- """
- Test for L{sasl.SASLInitiatingInitializer.setMechanism}.
- """
-
- def setUp(self):
- self.output = []
-
- self.authenticator = xmlstream.Authenticator()
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
- self.xmlstream.send = self.output.append
- self.xmlstream.connectionMade()
- self.xmlstream.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='1.0'>")
-
- self.init = sasl.SASLInitiatingInitializer(self.xmlstream)
-
-
- def _setMechanism(self, name):
- """
- Set up the XML Stream to have a SASL feature with the given mechanism.
- """
- feature = domish.Element((NS_XMPP_SASL, 'mechanisms'))
- feature.addElement('mechanism', content=name)
- self.xmlstream.features[(feature.uri, feature.name)] = feature
-
- self.init.setMechanism()
- return self.init.mechanism.name
-
-
- def test_anonymous(self):
- """
- Test setting ANONYMOUS as the authentication mechanism.
- """
- self.authenticator.jid = jid.JID('example.com')
- self.authenticator.password = None
- name = "ANONYMOUS"
-
- self.assertEqual(name, self._setMechanism(name))
-
-
- def test_plain(self):
- """
- Test setting PLAIN as the authentication mechanism.
- """
- self.authenticator.jid = jid.JID('test@example.com')
- self.authenticator.password = 'secret'
- name = "PLAIN"
-
- self.assertEqual(name, self._setMechanism(name))
-
-
- def test_digest(self):
- """
- Test setting DIGEST-MD5 as the authentication mechanism.
- """
- self.authenticator.jid = jid.JID('test@example.com')
- self.authenticator.password = 'secret'
- name = "DIGEST-MD5"
-
- self.assertEqual(name, self._setMechanism(name))
-
-
- def test_notAcceptable(self):
- """
- Test using an unacceptable SASL authentication mechanism.
- """
-
- self.authenticator.jid = jid.JID('test@example.com')
- self.authenticator.password = 'secret'
-
- self.assertRaises(sasl.SASLNoAcceptableMechanism,
- self._setMechanism, 'SOMETHING_UNACCEPTABLE')
-
-
- def test_notAcceptableWithoutUser(self):
- """
- Test using an unacceptable SASL authentication mechanism with no JID.
- """
- self.authenticator.jid = jid.JID('example.com')
- self.authenticator.password = 'secret'
-
- self.assertRaises(sasl.SASLNoAcceptableMechanism,
- self._setMechanism, 'SOMETHING_UNACCEPTABLE')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersaslmechanisms.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersaslmechanisms.py
deleted file mode 100755
index 1e195ab4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabbersaslmechanisms.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.sasl_mechanisms}.
-"""
-
-from twisted.trial import unittest
-
-from twisted.words.protocols.jabber import sasl_mechanisms
-
-class PlainTest(unittest.TestCase):
- def test_getInitialResponse(self):
- """
- Test the initial response.
- """
- m = sasl_mechanisms.Plain(None, 'test', 'secret')
- self.assertEqual(m.getInitialResponse(), '\x00test\x00secret')
-
-
-
-class AnonymousTest(unittest.TestCase):
- """
- Tests for L{twisted.words.protocols.jabber.sasl_mechanisms.Anonymous}.
- """
- def test_getInitialResponse(self):
- """
- Test the initial response to be empty.
- """
- m = sasl_mechanisms.Anonymous()
- self.assertEqual(m.getInitialResponse(), None)
-
-
-
-class DigestMD5Test(unittest.TestCase):
- def setUp(self):
- self.mechanism = sasl_mechanisms.DigestMD5('xmpp', 'example.org', None,
- 'test', 'secret')
-
-
- def test_getInitialResponse(self):
- """
- Test that no initial response is generated.
- """
- self.assertIdentical(self.mechanism.getInitialResponse(), None)
-
- def test_getResponse(self):
- """
- Partially test challenge response.
-
- Does not actually test the response-value, yet.
- """
-
- challenge = 'realm="localhost",nonce="1234",qop="auth",charset=utf-8,algorithm=md5-sess'
- directives = self.mechanism._parse(self.mechanism.getResponse(challenge))
- self.assertEqual(directives['username'], 'test')
- self.assertEqual(directives['nonce'], '1234')
- self.assertEqual(directives['nc'], '00000001')
- self.assertEqual(directives['qop'], ['auth'])
- self.assertEqual(directives['charset'], 'utf-8')
- self.assertEqual(directives['digest-uri'], 'xmpp/example.org')
- self.assertEqual(directives['realm'], 'localhost')
-
- def test_getResponseNoRealm(self):
- """
- Test that we accept challenges without realm.
-
- The realm should default to the host part of the JID.
- """
-
- challenge = 'nonce="1234",qop="auth",charset=utf-8,algorithm=md5-sess'
- directives = self.mechanism._parse(self.mechanism.getResponse(challenge))
- self.assertEqual(directives['realm'], 'example.org')
-
- def test__parse(self):
- """
- Test challenge decoding.
-
- Specifically, check for multiple values for the C{qop} and C{cipher}
- directives.
- """
- challenge = 'nonce="1234",qop="auth,auth-conf",charset=utf-8,' \
- 'algorithm=md5-sess,cipher="des,3des"'
- directives = self.mechanism._parse(challenge)
- self.assertEqual('1234', directives['nonce'])
- self.assertEqual('utf-8', directives['charset'])
- self.assertIn('auth', directives['qop'])
- self.assertIn('auth-conf', directives['qop'])
- self.assertIn('des', directives['cipher'])
- self.assertIn('3des', directives['cipher'])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmlstream.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmlstream.py
deleted file mode 100755
index caa2ba63..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmlstream.py
+++ /dev/null
@@ -1,1334 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.jabber.xmlstream}.
-"""
-
-from twisted.trial import unittest
-
-from zope.interface.verify import verifyObject
-
-from twisted.internet import defer, task
-from twisted.internet.error import ConnectionLost
-from twisted.internet.interfaces import IProtocolFactory
-from twisted.python import failure
-from twisted.test import proto_helpers
-from twisted.words.test.test_xmlstream import GenericXmlStreamFactoryTestsMixin
-from twisted.words.xish import domish
-from twisted.words.protocols.jabber import error, ijabber, jid, xmlstream
-
-
-
-NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls'
-
-
-
-class HashPasswordTest(unittest.TestCase):
- """
- Tests for L{xmlstream.hashPassword}.
- """
-
- def test_basic(self):
- """
- The sid and secret are concatenated to calculate sha1 hex digest.
- """
- hash = xmlstream.hashPassword(u"12345", u"secret")
- self.assertEqual('99567ee91b2c7cabf607f10cb9f4a3634fa820e0', hash)
-
-
- def test_sidNotUnicode(self):
- """
- The session identifier must be a unicode object.
- """
- self.assertRaises(TypeError, xmlstream.hashPassword, "\xc2\xb92345",
- u"secret")
-
-
- def test_passwordNotUnicode(self):
- """
- The password must be a unicode object.
- """
- self.assertRaises(TypeError, xmlstream.hashPassword, u"12345",
- "secr\xc3\xa9t")
-
-
- def test_unicodeSecret(self):
- """
- The concatenated sid and password must be encoded to UTF-8 before hashing.
- """
- hash = xmlstream.hashPassword(u"12345", u"secr\u00e9t")
- self.assertEqual('659bf88d8f8e179081f7f3b4a8e7d224652d2853', hash)
-
-
-
-class IQTest(unittest.TestCase):
- """
- Tests both IQ and the associated IIQResponseTracker callback.
- """
-
- def setUp(self):
- authenticator = xmlstream.ConnectAuthenticator('otherhost')
- authenticator.namespace = 'testns'
- self.xmlstream = xmlstream.XmlStream(authenticator)
- self.clock = task.Clock()
- self.xmlstream._callLater = self.clock.callLater
- self.xmlstream.makeConnection(proto_helpers.StringTransport())
- self.xmlstream.dataReceived(
- "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
- "xmlns='testns' from='otherhost' version='1.0'>")
- self.iq = xmlstream.IQ(self.xmlstream, 'get')
-
-
- def testBasic(self):
- self.assertEqual(self.iq['type'], 'get')
- self.assertTrue(self.iq['id'])
-
-
- def testSend(self):
- self.xmlstream.transport.clear()
- self.iq.send()
- self.assertIn(self.xmlstream.transport.value(), [
- "<iq type='get' id='%s'/>" % self.iq['id'],
- "<iq id='%s' type='get'/>" % self.iq['id'],
- ])
-
-
- def testResultResponse(self):
- def cb(result):
- self.assertEqual(result['type'], 'result')
-
- d = self.iq.send()
- d.addCallback(cb)
-
- xs = self.xmlstream
- xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
- return d
-
-
- def testErrorResponse(self):
- d = self.iq.send()
- self.assertFailure(d, error.StanzaError)
-
- xs = self.xmlstream
- xs.dataReceived("<iq type='error' id='%s'/>" % self.iq['id'])
- return d
-
-
- def testNonTrackedResponse(self):
- """
- Test that untracked iq responses don't trigger any action.
-
- Untracked means that the id of the incoming response iq is not
- in the stream's C{iqDeferreds} dictionary.
- """
- xs = self.xmlstream
- xmlstream.upgradeWithIQResponseTracker(xs)
-
- # Make sure we aren't tracking any iq's.
- self.assertFalse(xs.iqDeferreds)
-
- # Set up a fallback handler that checks the stanza's handled attribute.
- # If that is set to True, the iq tracker claims to have handled the
- # response.
- def cb(iq):
- self.assertFalse(getattr(iq, 'handled', False))
-
- xs.addObserver("/iq", cb, -1)
-
- # Receive an untracked iq response
- xs.dataReceived("<iq type='result' id='test'/>")
-
-
- def testCleanup(self):
- """
- Test if the deferred associated with an iq request is removed
- from the list kept in the L{XmlStream} object after it has
- been fired.
- """
-
- d = self.iq.send()
- xs = self.xmlstream
- xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
- self.assertNotIn(self.iq['id'], xs.iqDeferreds)
- return d
-
-
- def testDisconnectCleanup(self):
- """
- Test if deferreds for iq's that haven't yet received a response
- have their errback called on stream disconnect.
- """
-
- d = self.iq.send()
- xs = self.xmlstream
- xs.connectionLost("Closed by peer")
- self.assertFailure(d, ConnectionLost)
- return d
-
-
- def testNoModifyingDict(self):
- """
- Test to make sure the errbacks cannot cause the iteration of the
- iqDeferreds to blow up in our face.
- """
-
- def eb(failure):
- d = xmlstream.IQ(self.xmlstream).send()
- d.addErrback(eb)
-
- d = self.iq.send()
- d.addErrback(eb)
- self.xmlstream.connectionLost("Closed by peer")
- return d
-
-
- def testRequestTimingOut(self):
- """
- Test that an iq request with a defined timeout times out.
- """
- self.iq.timeout = 60
- d = self.iq.send()
- self.assertFailure(d, xmlstream.TimeoutError)
-
- self.clock.pump([1, 60])
- self.assertFalse(self.clock.calls)
- self.assertFalse(self.xmlstream.iqDeferreds)
- return d
-
-
- def testRequestNotTimingOut(self):
- """
- Test that an iq request with a defined timeout does not time out
- when a response was received before the timeout period elapsed.
- """
- self.iq.timeout = 60
- d = self.iq.send()
- self.clock.callLater(1, self.xmlstream.dataReceived,
- "<iq type='result' id='%s'/>" % self.iq['id'])
- self.clock.pump([1, 1])
- self.assertFalse(self.clock.calls)
- return d
-
-
- def testDisconnectTimeoutCancellation(self):
- """
- Test if timeouts for iq's that haven't yet received a response
- are cancelled on stream disconnect.
- """
-
- self.iq.timeout = 60
- d = self.iq.send()
-
- xs = self.xmlstream
- xs.connectionLost("Closed by peer")
- self.assertFailure(d, ConnectionLost)
- self.assertFalse(self.clock.calls)
- return d
-
-
-
-class XmlStreamTest(unittest.TestCase):
-
- def onStreamStart(self, obj):
- self.gotStreamStart = True
-
-
- def onStreamEnd(self, obj):
- self.gotStreamEnd = True
-
-
- def onStreamError(self, obj):
- self.gotStreamError = True
-
-
- def setUp(self):
- """
- Set up XmlStream and several observers.
- """
- self.gotStreamStart = False
- self.gotStreamEnd = False
- self.gotStreamError = False
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- xs.addObserver('//event/stream/start', self.onStreamStart)
- xs.addObserver('//event/stream/end', self.onStreamEnd)
- xs.addObserver('//event/stream/error', self.onStreamError)
- xs.makeConnection(proto_helpers.StringTransportWithDisconnection())
- xs.transport.protocol = xs
- xs.namespace = 'testns'
- xs.version = (1, 0)
- self.xmlstream = xs
-
-
- def test_sendHeaderBasic(self):
- """
- Basic test on the header sent by sendHeader.
- """
- xs = self.xmlstream
- xs.sendHeader()
- splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
- self.assertIn("<stream:stream", splitHeader)
- self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
- splitHeader)
- self.assertIn("xmlns='testns'", splitHeader)
- self.assertIn("version='1.0'", splitHeader)
- self.assertTrue(xs._headerSent)
-
-
- def test_sendHeaderAdditionalNamespaces(self):
- """
- Test for additional namespace declarations.
- """
- xs = self.xmlstream
- xs.prefixes['jabber:server:dialback'] = 'db'
- xs.sendHeader()
- splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
- self.assertIn("<stream:stream", splitHeader)
- self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
- splitHeader)
- self.assertIn("xmlns:db='jabber:server:dialback'", splitHeader)
- self.assertIn("xmlns='testns'", splitHeader)
- self.assertIn("version='1.0'", splitHeader)
- self.assertTrue(xs._headerSent)
-
-
- def test_sendHeaderInitiating(self):
- """
- Test addressing when initiating a stream.
- """
- xs = self.xmlstream
- xs.thisEntity = jid.JID('thisHost')
- xs.otherEntity = jid.JID('otherHost')
- xs.initiating = True
- xs.sendHeader()
- splitHeader = xs.transport.value()[0:-1].split(' ')
- self.assertIn("to='otherhost'", splitHeader)
- self.assertIn("from='thishost'", splitHeader)
-
-
- def test_sendHeaderReceiving(self):
- """
- Test addressing when receiving a stream.
- """
- xs = self.xmlstream
- xs.thisEntity = jid.JID('thisHost')
- xs.otherEntity = jid.JID('otherHost')
- xs.initiating = False
- xs.sid = 'session01'
- xs.sendHeader()
- splitHeader = xs.transport.value()[0:-1].split(' ')
- self.assertIn("to='otherhost'", splitHeader)
- self.assertIn("from='thishost'", splitHeader)
- self.assertIn("id='session01'", splitHeader)
-
-
- def test_receiveStreamError(self):
- """
- Test events when a stream error is received.
- """
- xs = self.xmlstream
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='1.0'>")
- xs.dataReceived("<stream:error/>")
- self.assertTrue(self.gotStreamError)
- self.assertTrue(self.gotStreamEnd)
-
-
- def test_sendStreamErrorInitiating(self):
- """
- Test sendStreamError on an initiating xmlstream with a header sent.
-
- An error should be sent out and the connection lost.
- """
- xs = self.xmlstream
- xs.initiating = True
- xs.sendHeader()
- xs.transport.clear()
- xs.sendStreamError(error.StreamError('version-unsupported'))
- self.assertNotEqual('', xs.transport.value())
- self.assertTrue(self.gotStreamEnd)
-
-
- def test_sendStreamErrorInitiatingNoHeader(self):
- """
- Test sendStreamError on an initiating xmlstream without having sent a
- header.
-
- In this case, no header should be generated. Also, the error should
- not be sent out on the stream. Just closing the connection.
- """
- xs = self.xmlstream
- xs.initiating = True
- xs.transport.clear()
- xs.sendStreamError(error.StreamError('version-unsupported'))
- self.assertNot(xs._headerSent)
- self.assertEqual('', xs.transport.value())
- self.assertTrue(self.gotStreamEnd)
-
-
- def test_sendStreamErrorReceiving(self):
- """
- Test sendStreamError on a receiving xmlstream with a header sent.
-
- An error should be sent out and the connection lost.
- """
- xs = self.xmlstream
- xs.initiating = False
- xs.sendHeader()
- xs.transport.clear()
- xs.sendStreamError(error.StreamError('version-unsupported'))
- self.assertNotEqual('', xs.transport.value())
- self.assertTrue(self.gotStreamEnd)
-
-
- def test_sendStreamErrorReceivingNoHeader(self):
- """
- Test sendStreamError on a receiving xmlstream without having sent a
- header.
-
- In this case, a header should be generated. Then, the error should
- be sent out on the stream followed by closing the connection.
- """
- xs = self.xmlstream
- xs.initiating = False
- xs.transport.clear()
- xs.sendStreamError(error.StreamError('version-unsupported'))
- self.assertTrue(xs._headerSent)
- self.assertNotEqual('', xs.transport.value())
- self.assertTrue(self.gotStreamEnd)
-
-
- def test_reset(self):
- """
- Test resetting the XML stream to start a new layer.
- """
- xs = self.xmlstream
- xs.sendHeader()
- stream = xs.stream
- xs.reset()
- self.assertNotEqual(stream, xs.stream)
- self.assertNot(xs._headerSent)
-
-
- def test_send(self):
- """
- Test send with various types of objects.
- """
- xs = self.xmlstream
- xs.send('<presence/>')
- self.assertEqual(xs.transport.value(), '<presence/>')
-
- xs.transport.clear()
- el = domish.Element(('testns', 'presence'))
- xs.send(el)
- self.assertEqual(xs.transport.value(), '<presence/>')
-
- xs.transport.clear()
- el = domish.Element(('http://etherx.jabber.org/streams', 'features'))
- xs.send(el)
- self.assertEqual(xs.transport.value(), '<stream:features/>')
-
-
- def test_authenticator(self):
- """
- Test that the associated authenticator is correctly called.
- """
- connectionMadeCalls = []
- streamStartedCalls = []
- associateWithStreamCalls = []
-
- class TestAuthenticator:
- def connectionMade(self):
- connectionMadeCalls.append(None)
-
- def streamStarted(self, rootElement):
- streamStartedCalls.append(rootElement)
-
- def associateWithStream(self, xs):
- associateWithStreamCalls.append(xs)
-
- a = TestAuthenticator()
- xs = xmlstream.XmlStream(a)
- self.assertEqual([xs], associateWithStreamCalls)
- xs.connectionMade()
- self.assertEqual([None], connectionMadeCalls)
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345'>")
- self.assertEqual(1, len(streamStartedCalls))
- xs.reset()
- self.assertEqual([None], connectionMadeCalls)
-
-
-
-class TestError(Exception):
- pass
-
-
-
-class AuthenticatorTest(unittest.TestCase):
- def setUp(self):
- self.authenticator = xmlstream.Authenticator()
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
-
-
- def test_streamStart(self):
- """
- Test streamStart to fill the appropriate attributes from the
- stream header.
- """
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.org' to='example.com' id='12345' "
- "version='1.0'>")
- self.assertEqual((1, 0), xs.version)
- self.assertIdentical(None, xs.sid)
- self.assertEqual('invalid', xs.namespace)
- self.assertIdentical(None, xs.otherEntity)
- self.assertEqual(None, xs.thisEntity)
-
-
- def test_streamStartLegacy(self):
- """
- Test streamStart to fill the appropriate attributes from the
- stream header for a pre-XMPP-1.0 header.
- """
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345'>")
- self.assertEqual((0, 0), xs.version)
-
-
- def test_streamBadVersionOneDigit(self):
- """
- Test streamStart to fill the appropriate attributes from the
- stream header for a version with only one digit.
- """
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='1'>")
- self.assertEqual((0, 0), xs.version)
-
-
- def test_streamBadVersionNoNumber(self):
- """
- Test streamStart to fill the appropriate attributes from the
- stream header for a malformed version.
- """
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='blah'>")
- self.assertEqual((0, 0), xs.version)
-
-
-
-class ConnectAuthenticatorTest(unittest.TestCase):
-
- def setUp(self):
- self.gotAuthenticated = False
- self.initFailure = None
- self.authenticator = xmlstream.ConnectAuthenticator('otherHost')
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
- self.xmlstream.addObserver('//event/stream/authd', self.onAuthenticated)
- self.xmlstream.addObserver('//event/xmpp/initfailed', self.onInitFailed)
-
-
- def onAuthenticated(self, obj):
- self.gotAuthenticated = True
-
-
- def onInitFailed(self, failure):
- self.initFailure = failure
-
-
- def testSucces(self):
- """
- Test successful completion of an initialization step.
- """
- class Initializer:
- def initialize(self):
- pass
-
- init = Initializer()
- self.xmlstream.initializers = [init]
-
- self.authenticator.initializeStream()
- self.assertEqual([], self.xmlstream.initializers)
- self.assertTrue(self.gotAuthenticated)
-
-
- def testFailure(self):
- """
- Test failure of an initialization step.
- """
- class Initializer:
- def initialize(self):
- raise TestError
-
- init = Initializer()
- self.xmlstream.initializers = [init]
-
- self.authenticator.initializeStream()
- self.assertEqual([init], self.xmlstream.initializers)
- self.assertFalse(self.gotAuthenticated)
- self.assertNotIdentical(None, self.initFailure)
- self.assertTrue(self.initFailure.check(TestError))
-
-
- def test_streamStart(self):
- """
- Test streamStart to fill the appropriate attributes from the
- stream header.
- """
- self.authenticator.namespace = 'testns'
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' to='example.org' id='12345' "
- "version='1.0'>")
- self.assertEqual((1, 0), xs.version)
- self.assertEqual('12345', xs.sid)
- self.assertEqual('testns', xs.namespace)
- self.assertEqual('example.com', xs.otherEntity.host)
- self.assertIdentical(None, xs.thisEntity)
- self.assertNot(self.gotAuthenticated)
- xs.dataReceived("<stream:features>"
- "<test xmlns='testns'/>"
- "</stream:features>")
- self.assertIn(('testns', 'test'), xs.features)
- self.assertTrue(self.gotAuthenticated)
-
-
-
-class ListenAuthenticatorTest(unittest.TestCase):
- """
- Tests for L{xmlstream.ListenAuthenticator}
- """
-
- def setUp(self):
- self.authenticator = xmlstream.ListenAuthenticator()
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
-
-
- def test_streamStart(self):
- """
- Test streamStart to fill the appropriate attributes from the
- stream header.
- """
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- self.assertIdentical(None, xs.sid)
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.org' to='example.com' id='12345' "
- "version='1.0'>")
- self.assertEqual((1, 0), xs.version)
- self.assertNotIdentical(None, xs.sid)
- self.assertNotEquals('12345', xs.sid)
- self.assertEqual('jabber:client', xs.namespace)
- self.assertIdentical(None, xs.otherEntity)
- self.assertEqual('example.com', xs.thisEntity.host)
-
-
- def test_streamStartUnicodeSessionID(self):
- """
- The generated session id must be a unicode object.
- """
- xs = self.xmlstream
- xs.makeConnection(proto_helpers.StringTransport())
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.org' to='example.com' id='12345' "
- "version='1.0'>")
- self.assertIsInstance(xs.sid, unicode)
-
-
-
-class TLSInitiatingInitializerTest(unittest.TestCase):
- def setUp(self):
- self.output = []
- self.done = []
-
- self.savedSSL = xmlstream.ssl
-
- self.authenticator = xmlstream.Authenticator()
- self.xmlstream = xmlstream.XmlStream(self.authenticator)
- self.xmlstream.send = self.output.append
- self.xmlstream.connectionMade()
- self.xmlstream.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345' version='1.0'>")
- self.init = xmlstream.TLSInitiatingInitializer(self.xmlstream)
-
-
- def tearDown(self):
- xmlstream.ssl = self.savedSSL
-
-
- def testWantedSupported(self):
- """
- Test start when TLS is wanted and the SSL library available.
- """
- self.xmlstream.transport = proto_helpers.StringTransport()
- self.xmlstream.transport.startTLS = lambda ctx: self.done.append('TLS')
- self.xmlstream.reset = lambda: self.done.append('reset')
- self.xmlstream.sendHeader = lambda: self.done.append('header')
-
- d = self.init.start()
- d.addCallback(self.assertEqual, xmlstream.Reset)
- starttls = self.output[0]
- self.assertEqual('starttls', starttls.name)
- self.assertEqual(NS_XMPP_TLS, starttls.uri)
- self.xmlstream.dataReceived("<proceed xmlns='%s'/>" % NS_XMPP_TLS)
- self.assertEqual(['TLS', 'reset', 'header'], self.done)
-
- return d
-
- if not xmlstream.ssl:
- testWantedSupported.skip = "SSL not available"
-
-
- def testWantedNotSupportedNotRequired(self):
- """
- Test start when TLS is wanted and the SSL library available.
- """
- xmlstream.ssl = None
-
- d = self.init.start()
- d.addCallback(self.assertEqual, None)
- self.assertEqual([], self.output)
-
- return d
-
-
- def testWantedNotSupportedRequired(self):
- """
- Test start when TLS is wanted and the SSL library available.
- """
- xmlstream.ssl = None
- self.init.required = True
-
- d = self.init.start()
- self.assertFailure(d, xmlstream.TLSNotSupported)
- self.assertEqual([], self.output)
-
- return d
-
-
- def testNotWantedRequired(self):
- """
- Test start when TLS is not wanted, but required by the server.
- """
- tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
- tls.addElement('required')
- self.xmlstream.features = {(tls.uri, tls.name): tls}
- self.init.wanted = False
-
- d = self.init.start()
- self.assertEqual([], self.output)
- self.assertFailure(d, xmlstream.TLSRequired)
-
- return d
-
-
- def testNotWantedNotRequired(self):
- """
- Test start when TLS is not wanted, but required by the server.
- """
- tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
- self.xmlstream.features = {(tls.uri, tls.name): tls}
- self.init.wanted = False
-
- d = self.init.start()
- d.addCallback(self.assertEqual, None)
- self.assertEqual([], self.output)
- return d
-
-
- def testFailed(self):
- """
- Test failed TLS negotiation.
- """
- # Pretend that ssl is supported, it isn't actually used when the
- # server starts out with a failure in response to our initial
- # C{starttls} stanza.
- xmlstream.ssl = 1
-
- d = self.init.start()
- self.assertFailure(d, xmlstream.TLSFailed)
- self.xmlstream.dataReceived("<failure xmlns='%s'/>" % NS_XMPP_TLS)
- return d
-
-
-
-class TestFeatureInitializer(xmlstream.BaseFeatureInitiatingInitializer):
- feature = ('testns', 'test')
-
- def start(self):
- return defer.succeed(None)
-
-
-
-class BaseFeatureInitiatingInitializerTest(unittest.TestCase):
-
- def setUp(self):
- self.xmlstream = xmlstream.XmlStream(xmlstream.Authenticator())
- self.init = TestFeatureInitializer(self.xmlstream)
-
-
- def testAdvertized(self):
- """
- Test that an advertized feature results in successful initialization.
- """
- self.xmlstream.features = {self.init.feature:
- domish.Element(self.init.feature)}
- return self.init.initialize()
-
-
- def testNotAdvertizedRequired(self):
- """
- Test that when the feature is not advertized, but required by the
- initializer, an exception is raised.
- """
- self.init.required = True
- self.assertRaises(xmlstream.FeatureNotAdvertized, self.init.initialize)
-
-
- def testNotAdvertizedNotRequired(self):
- """
- Test that when the feature is not advertized, and not required by the
- initializer, the initializer silently succeeds.
- """
- self.init.required = False
- self.assertIdentical(None, self.init.initialize())
-
-
-
-class ToResponseTest(unittest.TestCase):
-
- def test_toResponse(self):
- """
- Test that a response stanza is generated with addressing swapped.
- """
- stanza = domish.Element(('jabber:client', 'iq'))
- stanza['type'] = 'get'
- stanza['to'] = 'user1@example.com'
- stanza['from'] = 'user2@example.com/resource'
- stanza['id'] = 'stanza1'
- response = xmlstream.toResponse(stanza, 'result')
- self.assertNotIdentical(stanza, response)
- self.assertEqual(response['from'], 'user1@example.com')
- self.assertEqual(response['to'], 'user2@example.com/resource')
- self.assertEqual(response['type'], 'result')
- self.assertEqual(response['id'], 'stanza1')
-
-
- def test_toResponseNoFrom(self):
- """
- Test that a response is generated from a stanza without a from address.
- """
- stanza = domish.Element(('jabber:client', 'iq'))
- stanza['type'] = 'get'
- stanza['to'] = 'user1@example.com'
- response = xmlstream.toResponse(stanza)
- self.assertEqual(response['from'], 'user1@example.com')
- self.assertFalse(response.hasAttribute('to'))
-
-
- def test_toResponseNoTo(self):
- """
- Test that a response is generated from a stanza without a to address.
- """
- stanza = domish.Element(('jabber:client', 'iq'))
- stanza['type'] = 'get'
- stanza['from'] = 'user2@example.com/resource'
- response = xmlstream.toResponse(stanza)
- self.assertFalse(response.hasAttribute('from'))
- self.assertEqual(response['to'], 'user2@example.com/resource')
-
-
- def test_toResponseNoAddressing(self):
- """
- Test that a response is generated from a stanza without any addressing.
- """
- stanza = domish.Element(('jabber:client', 'message'))
- stanza['type'] = 'chat'
- response = xmlstream.toResponse(stanza)
- self.assertFalse(response.hasAttribute('to'))
- self.assertFalse(response.hasAttribute('from'))
-
-
- def test_noID(self):
- """
- Test that a proper response is generated without id attribute.
- """
- stanza = domish.Element(('jabber:client', 'message'))
- response = xmlstream.toResponse(stanza)
- self.assertFalse(response.hasAttribute('id'))
-
-
- def test_noType(self):
- """
- Test that a proper response is generated without type attribute.
- """
- stanza = domish.Element(('jabber:client', 'message'))
- response = xmlstream.toResponse(stanza)
- self.assertFalse(response.hasAttribute('type'))
-
-
-class DummyFactory(object):
- """
- Dummy XmlStream factory that only registers bootstrap observers.
- """
- def __init__(self):
- self.callbacks = {}
-
-
- def addBootstrap(self, event, callback):
- self.callbacks[event] = callback
-
-
-
-class DummyXMPPHandler(xmlstream.XMPPHandler):
- """
- Dummy XMPP subprotocol handler to count the methods are called on it.
- """
- def __init__(self):
- self.doneMade = 0
- self.doneInitialized = 0
- self.doneLost = 0
-
-
- def makeConnection(self, xs):
- self.connectionMade()
-
-
- def connectionMade(self):
- self.doneMade += 1
-
-
- def connectionInitialized(self):
- self.doneInitialized += 1
-
-
- def connectionLost(self, reason):
- self.doneLost += 1
-
-
-
-class FailureReasonXMPPHandler(xmlstream.XMPPHandler):
- """
- Dummy handler specifically for failure Reason tests.
- """
- def __init__(self):
- self.gotFailureReason = False
-
-
- def connectionLost(self, reason):
- if isinstance(reason, failure.Failure):
- self.gotFailureReason = True
-
-
-
-class XMPPHandlerTest(unittest.TestCase):
- """
- Tests for L{xmlstream.XMPPHandler}.
- """
-
- def test_interface(self):
- """
- L{xmlstream.XMPPHandler} implements L{ijabber.IXMPPHandler}.
- """
- verifyObject(ijabber.IXMPPHandler, xmlstream.XMPPHandler())
-
-
- def test_send(self):
- """
- Test that data is passed on for sending by the stream manager.
- """
- class DummyStreamManager(object):
- def __init__(self):
- self.outlist = []
-
- def send(self, data):
- self.outlist.append(data)
-
- handler = xmlstream.XMPPHandler()
- handler.parent = DummyStreamManager()
- handler.send('<presence/>')
- self.assertEqual(['<presence/>'], handler.parent.outlist)
-
-
- def test_makeConnection(self):
- """
- Test that makeConnection saves the XML stream and calls connectionMade.
- """
- class TestXMPPHandler(xmlstream.XMPPHandler):
- def connectionMade(self):
- self.doneMade = True
-
- handler = TestXMPPHandler()
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- handler.makeConnection(xs)
- self.assertTrue(handler.doneMade)
- self.assertIdentical(xs, handler.xmlstream)
-
-
- def test_connectionLost(self):
- """
- Test that connectionLost forgets the XML stream.
- """
- handler = xmlstream.XMPPHandler()
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- handler.makeConnection(xs)
- handler.connectionLost(Exception())
- self.assertIdentical(None, handler.xmlstream)
-
-
-
-class XMPPHandlerCollectionTest(unittest.TestCase):
- """
- Tests for L{xmlstream.XMPPHandlerCollection}.
- """
-
- def setUp(self):
- self.collection = xmlstream.XMPPHandlerCollection()
-
-
- def test_interface(self):
- """
- L{xmlstream.StreamManager} implements L{ijabber.IXMPPHandlerCollection}.
- """
- verifyObject(ijabber.IXMPPHandlerCollection, self.collection)
-
-
- def test_addHandler(self):
- """
- Test the addition of a protocol handler.
- """
- handler = DummyXMPPHandler()
- handler.setHandlerParent(self.collection)
- self.assertIn(handler, self.collection)
- self.assertIdentical(self.collection, handler.parent)
-
-
- def test_removeHandler(self):
- """
- Test removal of a protocol handler.
- """
- handler = DummyXMPPHandler()
- handler.setHandlerParent(self.collection)
- handler.disownHandlerParent(self.collection)
- self.assertNotIn(handler, self.collection)
- self.assertIdentical(None, handler.parent)
-
-
-
-class StreamManagerTest(unittest.TestCase):
- """
- Tests for L{xmlstream.StreamManager}.
- """
-
- def setUp(self):
- factory = DummyFactory()
- self.streamManager = xmlstream.StreamManager(factory)
-
-
- def test_basic(self):
- """
- Test correct initialization and setup of factory observers.
- """
- sm = self.streamManager
- self.assertIdentical(None, sm.xmlstream)
- self.assertEqual([], sm.handlers)
- self.assertEqual(sm._connected,
- sm.factory.callbacks['//event/stream/connected'])
- self.assertEqual(sm._authd,
- sm.factory.callbacks['//event/stream/authd'])
- self.assertEqual(sm._disconnected,
- sm.factory.callbacks['//event/stream/end'])
- self.assertEqual(sm.initializationFailed,
- sm.factory.callbacks['//event/xmpp/initfailed'])
-
-
- def test_connected(self):
- """
- Test that protocol handlers have their connectionMade method called
- when the XML stream is connected.
- """
- sm = self.streamManager
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._connected(xs)
- self.assertEqual(1, handler.doneMade)
- self.assertEqual(0, handler.doneInitialized)
- self.assertEqual(0, handler.doneLost)
-
-
- def test_connectedLogTrafficFalse(self):
- """
- Test raw data functions unset when logTraffic is set to False.
- """
- sm = self.streamManager
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._connected(xs)
- self.assertIdentical(None, xs.rawDataInFn)
- self.assertIdentical(None, xs.rawDataOutFn)
-
-
- def test_connectedLogTrafficTrue(self):
- """
- Test raw data functions set when logTraffic is set to True.
- """
- sm = self.streamManager
- sm.logTraffic = True
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._connected(xs)
- self.assertNotIdentical(None, xs.rawDataInFn)
- self.assertNotIdentical(None, xs.rawDataOutFn)
-
-
- def test_authd(self):
- """
- Test that protocol handlers have their connectionInitialized method
- called when the XML stream is initialized.
- """
- sm = self.streamManager
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._authd(xs)
- self.assertEqual(0, handler.doneMade)
- self.assertEqual(1, handler.doneInitialized)
- self.assertEqual(0, handler.doneLost)
-
-
- def test_disconnected(self):
- """
- Test that protocol handlers have their connectionLost method
- called when the XML stream is disconnected.
- """
- sm = self.streamManager
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._disconnected(xs)
- self.assertEqual(0, handler.doneMade)
- self.assertEqual(0, handler.doneInitialized)
- self.assertEqual(1, handler.doneLost)
-
-
- def test_disconnectedReason(self):
- """
- A L{STREAM_END_EVENT} results in L{StreamManager} firing the handlers
- L{connectionLost} methods, passing a L{failure.Failure} reason.
- """
- sm = self.streamManager
- handler = FailureReasonXMPPHandler()
- handler.setHandlerParent(sm)
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._disconnected(failure.Failure(Exception("no reason")))
- self.assertEqual(True, handler.gotFailureReason)
-
-
- def test_addHandler(self):
- """
- Test the addition of a protocol handler while not connected.
- """
- sm = self.streamManager
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
-
- self.assertEqual(0, handler.doneMade)
- self.assertEqual(0, handler.doneInitialized)
- self.assertEqual(0, handler.doneLost)
-
-
- def test_addHandlerInitialized(self):
- """
- Test the addition of a protocol handler after the stream
- have been initialized.
-
- Make sure that the handler will have the connected stream
- passed via C{makeConnection} and have C{connectionInitialized}
- called.
- """
- sm = self.streamManager
- xs = xmlstream.XmlStream(xmlstream.Authenticator())
- sm._connected(xs)
- sm._authd(xs)
- handler = DummyXMPPHandler()
- handler.setHandlerParent(sm)
-
- self.assertEqual(1, handler.doneMade)
- self.assertEqual(1, handler.doneInitialized)
- self.assertEqual(0, handler.doneLost)
-
-
- def test_sendInitialized(self):
- """
- Test send when the stream has been initialized.
-
- The data should be sent directly over the XML stream.
- """
- factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
- sm = xmlstream.StreamManager(factory)
- xs = factory.buildProtocol(None)
- xs.transport = proto_helpers.StringTransport()
- xs.connectionMade()
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345'>")
- xs.dispatch(xs, "//event/stream/authd")
- sm.send("<presence/>")
- self.assertEqual("<presence/>", xs.transport.value())
-
-
- def test_sendNotConnected(self):
- """
- Test send when there is no established XML stream.
-
- The data should be cached until an XML stream has been established and
- initialized.
- """
- factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
- sm = xmlstream.StreamManager(factory)
- handler = DummyXMPPHandler()
- sm.addHandler(handler)
-
- xs = factory.buildProtocol(None)
- xs.transport = proto_helpers.StringTransport()
- sm.send("<presence/>")
- self.assertEqual("", xs.transport.value())
- self.assertEqual("<presence/>", sm._packetQueue[0])
-
- xs.connectionMade()
- self.assertEqual("", xs.transport.value())
- self.assertEqual("<presence/>", sm._packetQueue[0])
-
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345'>")
- xs.dispatch(xs, "//event/stream/authd")
-
- self.assertEqual("<presence/>", xs.transport.value())
- self.assertFalse(sm._packetQueue)
-
-
- def test_sendNotInitialized(self):
- """
- Test send when the stream is connected but not yet initialized.
-
- The data should be cached until the XML stream has been initialized.
- """
- factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
- sm = xmlstream.StreamManager(factory)
- xs = factory.buildProtocol(None)
- xs.transport = proto_helpers.StringTransport()
- xs.connectionMade()
- xs.dataReceived("<stream:stream xmlns='jabber:client' "
- "xmlns:stream='http://etherx.jabber.org/streams' "
- "from='example.com' id='12345'>")
- sm.send("<presence/>")
- self.assertEqual("", xs.transport.value())
- self.assertEqual("<presence/>", sm._packetQueue[0])
-
-
- def test_sendDisconnected(self):
- """
- Test send after XML stream disconnection.
-
- The data should be cached until a new XML stream has been established
- and initialized.
- """
- factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
- sm = xmlstream.StreamManager(factory)
- handler = DummyXMPPHandler()
- sm.addHandler(handler)
-
- xs = factory.buildProtocol(None)
- xs.connectionMade()
- xs.transport = proto_helpers.StringTransport()
- xs.connectionLost(None)
-
- sm.send("<presence/>")
- self.assertEqual("", xs.transport.value())
- self.assertEqual("<presence/>", sm._packetQueue[0])
-
-
-
-class XmlStreamServerFactoryTest(GenericXmlStreamFactoryTestsMixin):
- """
- Tests for L{xmlstream.XmlStreamServerFactory}.
- """
-
- def setUp(self):
- """
- Set up a server factory with a authenticator factory function.
- """
- class TestAuthenticator(object):
- def __init__(self):
- self.xmlstreams = []
-
- def associateWithStream(self, xs):
- self.xmlstreams.append(xs)
-
- def authenticatorFactory():
- return TestAuthenticator()
-
- self.factory = xmlstream.XmlStreamServerFactory(authenticatorFactory)
-
-
- def test_interface(self):
- """
- L{XmlStreamServerFactory} is a L{Factory}.
- """
- verifyObject(IProtocolFactory, self.factory)
-
-
- def test_buildProtocolAuthenticatorInstantiation(self):
- """
- The authenticator factory should be used to instantiate the
- authenticator and pass it to the protocol.
-
- The default protocol, L{XmlStream} stores the authenticator it is
- passed, and calls its C{associateWithStream} method. so we use that to
- check whether our authenticator factory is used and the protocol
- instance gets an authenticator.
- """
- xs = self.factory.buildProtocol(None)
- self.assertEqual([xs], xs.authenticator.xmlstreams)
-
-
- def test_buildProtocolXmlStream(self):
- """
- The protocol factory creates Jabber XML Stream protocols by default.
- """
- xs = self.factory.buildProtocol(None)
- self.assertIsInstance(xs, xmlstream.XmlStream)
-
-
- def test_buildProtocolTwice(self):
- """
- Subsequent calls to buildProtocol should result in different instances
- of the protocol, as well as their authenticators.
- """
- xs1 = self.factory.buildProtocol(None)
- xs2 = self.factory.buildProtocol(None)
- self.assertNotIdentical(xs1, xs2)
- self.assertNotIdentical(xs1.authenticator, xs2.authenticator)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmppstringprep.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmppstringprep.py
deleted file mode 100755
index 4b25c0b7..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_jabberxmppstringprep.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.trial import unittest
-
-from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep, resourceprep, nameprep, crippled
-
-class XMPPStringPrepTest(unittest.TestCase):
- """
-
- The nodeprep stringprep profile is similar to the resourceprep profile,
- but does an extra mapping of characters (table B.2) and disallows
- more characters (table C.1.1 and eight extra punctuation characters).
- Due to this similarity, the resourceprep tests are more extensive, and
- the nodeprep tests only address the mappings additional restrictions.
-
- The nameprep profile is nearly identical to the nameprep implementation in
- L{encodings.idna}, but that implementation assumes the C{UseSTD4ASCIIRules}
- flag to be false. This implementation assumes it to be true, and restricts
- the allowed set of characters. The tests here only check for the
- differences.
-
- """
-
- def testResourcePrep(self):
- self.assertEqual(resourceprep.prepare(u'resource'), u'resource')
- self.assertNotEquals(resourceprep.prepare(u'Resource'), u'resource')
- self.assertEqual(resourceprep.prepare(u' '), u' ')
-
- if crippled:
- return
-
- self.assertEqual(resourceprep.prepare(u'Henry \u2163'), u'Henry IV')
- self.assertEqual(resourceprep.prepare(u'foo\xad\u034f\u1806\u180b'
- u'bar\u200b\u2060'
- u'baz\ufe00\ufe08\ufe0f\ufeff'),
- u'foobarbaz')
- self.assertEqual(resourceprep.prepare(u'\u00a0'), u' ')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u1680')
- self.assertEqual(resourceprep.prepare(u'\u2000'), u' ')
- self.assertEqual(resourceprep.prepare(u'\u200b'), u'')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u0010\u007f')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u0085')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u180e')
- self.assertEqual(resourceprep.prepare(u'\ufeff'), u'')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\uf123')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U000f1234')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U0010f234')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U0008fffe')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U0010ffff')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\udf42')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\ufffd')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u2ff5')
- self.assertEqual(resourceprep.prepare(u'\u0341'), u'\u0301')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u200e')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u202a')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U000e0001')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U000e0042')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'foo\u05bebar')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'foo\ufd50bar')
- #self.assertEqual(resourceprep.prepare(u'foo\ufb38bar'),
- # u'foo\u064ebar')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\u06271')
- self.assertEqual(resourceprep.prepare(u'\u06271\u0628'),
- u'\u06271\u0628')
- self.assertRaises(UnicodeError, resourceprep.prepare, u'\U000e0002')
-
- def testNodePrep(self):
- self.assertEqual(nodeprep.prepare(u'user'), u'user')
- self.assertEqual(nodeprep.prepare(u'User'), u'user')
- self.assertRaises(UnicodeError, nodeprep.prepare, u'us&er')
-
-
- def test_nodeprepUnassignedInUnicode32(self):
- """
- Make sure unassigned code points from Unicode 3.2 are rejected.
- """
- self.assertRaises(UnicodeError, nodeprep.prepare, u'\u1d39')
-
-
- def testNamePrep(self):
- self.assertEqual(nameprep.prepare(u'example.com'), u'example.com')
- self.assertEqual(nameprep.prepare(u'Example.com'), u'example.com')
- self.assertRaises(UnicodeError, nameprep.prepare, u'ex@mple.com')
- self.assertRaises(UnicodeError, nameprep.prepare, u'-example.com')
- self.assertRaises(UnicodeError, nameprep.prepare, u'example-.com')
-
- if crippled:
- return
-
- self.assertEqual(nameprep.prepare(u'stra\u00dfe.example.com'),
- u'strasse.example.com')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_msn.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_msn.py
deleted file mode 100755
index ece580fe..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_msn.py
+++ /dev/null
@@ -1,522 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for L{twisted.words.protocols.msn}.
-"""
-
-# System imports
-import StringIO
-
-# Twisted imports
-
-# t.w.p.msn requires an HTTP client
-try:
- # So try to get one - do it directly instead of catching an ImportError
- # from t.w.p.msn so that other problems which cause that module to fail
- # to import don't cause the tests to be skipped.
- from twisted.web import client
-except ImportError:
- # If there isn't one, we're going to skip all the tests.
- msn = None
-else:
- # Otherwise importing it should work, so do it.
- from twisted.words.protocols import msn
-
-
-from twisted.python.hashlib import md5
-from twisted.protocols import loopback
-from twisted.internet.defer import Deferred
-from twisted.trial import unittest
-from twisted.test.proto_helpers import StringTransport, StringIOWithoutClosing
-
-def printError(f):
- print f
-
-
-class PassportTests(unittest.TestCase):
-
- def setUp(self):
- self.result = []
- self.deferred = Deferred()
- self.deferred.addCallback(lambda r: self.result.append(r))
- self.deferred.addErrback(printError)
-
- def test_nexus(self):
- """
- When L{msn.PassportNexus} receives enough information to identify the
- address of the login server, it fires the L{Deferred} passed to its
- initializer with that address.
- """
- protocol = msn.PassportNexus(self.deferred, 'https://foobar.com/somepage.quux')
- headers = {
- 'Content-Length' : '0',
- 'Content-Type' : 'text/html',
- 'PassportURLs' : 'DARealm=Passport.Net,DALogin=login.myserver.com/,DAReg=reg.myserver.com'
- }
- transport = StringTransport()
- protocol.makeConnection(transport)
- protocol.dataReceived('HTTP/1.0 200 OK\r\n')
- for (h, v) in headers.items():
- protocol.dataReceived('%s: %s\r\n' % (h,v))
- protocol.dataReceived('\r\n')
- self.assertEqual(self.result[0], "https://login.myserver.com/")
-
-
- def _doLoginTest(self, response, headers):
- protocol = msn.PassportLogin(self.deferred,'foo@foo.com','testpass','https://foo.com/', 'a')
- protocol.makeConnection(StringTransport())
- protocol.dataReceived(response)
- for (h,v) in headers.items(): protocol.dataReceived('%s: %s\r\n' % (h,v))
- protocol.dataReceived('\r\n')
-
- def testPassportLoginSuccess(self):
- headers = {
- 'Content-Length' : '0',
- 'Content-Type' : 'text/html',
- 'Authentication-Info' : "Passport1.4 da-status=success,tname=MSPAuth," +
- "tname=MSPProf,tname=MSPSec,from-PP='somekey'," +
- "ru=http://messenger.msn.com"
- }
- self._doLoginTest('HTTP/1.1 200 OK\r\n', headers)
- self.failUnless(self.result[0] == (msn.LOGIN_SUCCESS, 'somekey'))
-
- def testPassportLoginFailure(self):
- headers = {
- 'Content-Type' : 'text/html',
- 'WWW-Authenticate' : 'Passport1.4 da-status=failed,' +
- 'srealm=Passport.NET,ts=-3,prompt,cburl=http://host.com,' +
- 'cbtxt=the%20error%20message'
- }
- self._doLoginTest('HTTP/1.1 401 Unauthorized\r\n', headers)
- self.failUnless(self.result[0] == (msn.LOGIN_FAILURE, 'the error message'))
-
- def testPassportLoginRedirect(self):
- headers = {
- 'Content-Type' : 'text/html',
- 'Authentication-Info' : 'Passport1.4 da-status=redir',
- 'Location' : 'https://newlogin.host.com/'
- }
- self._doLoginTest('HTTP/1.1 302 Found\r\n', headers)
- self.failUnless(self.result[0] == (msn.LOGIN_REDIRECT, 'https://newlogin.host.com/', 'a'))
-
-
-if msn is not None:
- class DummySwitchboardClient(msn.SwitchboardClient):
- def userTyping(self, message):
- self.state = 'TYPING'
-
- def gotSendRequest(self, fileName, fileSize, cookie, message):
- if fileName == 'foobar.ext' and fileSize == 31337 and cookie == 1234: self.state = 'INVITATION'
-
-
- class DummyNotificationClient(msn.NotificationClient):
- def loggedIn(self, userHandle, screenName, verified):
- if userHandle == 'foo@bar.com' and screenName == 'Test Screen Name' and verified:
- self.state = 'LOGIN'
-
- def gotProfile(self, message):
- self.state = 'PROFILE'
-
- def gotContactStatus(self, code, userHandle, screenName):
- if code == msn.STATUS_AWAY and userHandle == "foo@bar.com" and screenName == "Test Screen Name":
- self.state = 'INITSTATUS'
-
- def contactStatusChanged(self, code, userHandle, screenName):
- if code == msn.STATUS_LUNCH and userHandle == "foo@bar.com" and screenName == "Test Name":
- self.state = 'NEWSTATUS'
-
- def contactOffline(self, userHandle):
- if userHandle == "foo@bar.com": self.state = 'OFFLINE'
-
- def statusChanged(self, code):
- if code == msn.STATUS_HIDDEN: self.state = 'MYSTATUS'
-
- def listSynchronized(self, *args):
- self.state = 'GOTLIST'
-
- def gotPhoneNumber(self, listVersion, userHandle, phoneType, number):
- msn.NotificationClient.gotPhoneNumber(self, listVersion, userHandle, phoneType, number)
- self.state = 'GOTPHONE'
-
- def userRemovedMe(self, userHandle, listVersion):
- msn.NotificationClient.userRemovedMe(self, userHandle, listVersion)
- c = self.factory.contacts.getContact(userHandle)
- if not c and self.factory.contacts.version == listVersion: self.state = 'USERREMOVEDME'
-
- def userAddedMe(self, userHandle, screenName, listVersion):
- msn.NotificationClient.userAddedMe(self, userHandle, screenName, listVersion)
- c = self.factory.contacts.getContact(userHandle)
- if c and (c.lists | msn.REVERSE_LIST) and (self.factory.contacts.version == listVersion) and \
- (screenName == 'Screen Name'):
- self.state = 'USERADDEDME'
-
- def gotSwitchboardInvitation(self, sessionID, host, port, key, userHandle, screenName):
- if sessionID == 1234 and \
- host == '192.168.1.1' and \
- port == 1863 and \
- key == '123.456' and \
- userHandle == 'foo@foo.com' and \
- screenName == 'Screen Name':
- self.state = 'SBINVITED'
-
-
-
-class DispatchTests(unittest.TestCase):
- """
- Tests for L{DispatchClient}.
- """
- def _versionTest(self, serverVersionResponse):
- """
- Test L{DispatchClient} version negotiation.
- """
- client = msn.DispatchClient()
- client.userHandle = "foo"
-
- transport = StringTransport()
- client.makeConnection(transport)
- self.assertEqual(
- transport.value(), "VER 1 MSNP8 CVR0\r\n")
- transport.clear()
-
- client.dataReceived(serverVersionResponse)
- self.assertEqual(
- transport.value(),
- "CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS foo\r\n")
-
-
- def test_version(self):
- """
- L{DispatchClient.connectionMade} greets the server with a I{VER}
- (version) message and then L{NotificationClient.dataReceived}
- handles the server's I{VER} response by sending a I{CVR} (client
- version) message.
- """
- self._versionTest("VER 1 MSNP8 CVR0\r\n")
-
-
- def test_versionWithoutCVR0(self):
- """
- If the server responds to a I{VER} command without including the
- I{CVR0} protocol, L{DispatchClient} behaves in the same way as if
- that protocol were included.
-
- Starting in August 2008, CVR0 disappeared from the I{VER} response.
- """
- self._versionTest("VER 1 MSNP8\r\n")
-
-
-
-class NotificationTests(unittest.TestCase):
- """ testing the various events in NotificationClient """
-
- def setUp(self):
- self.client = DummyNotificationClient()
- self.client.factory = msn.NotificationFactory()
- self.client.state = 'START'
-
-
- def tearDown(self):
- self.client = None
-
-
- def _versionTest(self, serverVersionResponse):
- """
- Test L{NotificationClient} version negotiation.
- """
- self.client.factory.userHandle = "foo"
-
- transport = StringTransport()
- self.client.makeConnection(transport)
- self.assertEqual(
- transport.value(), "VER 1 MSNP8 CVR0\r\n")
- transport.clear()
-
- self.client.dataReceived(serverVersionResponse)
- self.assertEqual(
- transport.value(),
- "CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS foo\r\n")
-
-
- def test_version(self):
- """
- L{NotificationClient.connectionMade} greets the server with a I{VER}
- (version) message and then L{NotificationClient.dataReceived}
- handles the server's I{VER} response by sending a I{CVR} (client
- version) message.
- """
- self._versionTest("VER 1 MSNP8 CVR0\r\n")
-
-
- def test_versionWithoutCVR0(self):
- """
- If the server responds to a I{VER} command without including the
- I{CVR0} protocol, L{NotificationClient} behaves in the same way as
- if that protocol were included.
-
- Starting in August 2008, CVR0 disappeared from the I{VER} response.
- """
- self._versionTest("VER 1 MSNP8\r\n")
-
-
- def test_challenge(self):
- """
- L{NotificationClient} responds to a I{CHL} message by sending a I{QRY}
- back which included a hash based on the parameters of the I{CHL}.
- """
- transport = StringTransport()
- self.client.makeConnection(transport)
- transport.clear()
-
- challenge = "15570131571988941333"
- self.client.dataReceived('CHL 0 ' + challenge + '\r\n')
- # md5 of the challenge and a magic string defined by the protocol
- response = "8f2f5a91b72102cd28355e9fc9000d6e"
- # Sanity check - the response is what the comment above says it is.
- self.assertEqual(
- response, md5(challenge + "Q1P7W2E4J9R8U3S5").hexdigest())
- self.assertEqual(
- transport.value(),
- # 2 is the next transaction identifier. 32 is the length of the
- # response.
- "QRY 2 msmsgs@msnmsgr.com 32\r\n" + response)
-
-
- def testLogin(self):
- self.client.lineReceived('USR 1 OK foo@bar.com Test%20Screen%20Name 1 0')
- self.failUnless((self.client.state == 'LOGIN'), msg='Failed to detect successful login')
-
-
- def test_loginWithoutSSLFailure(self):
- """
- L{NotificationClient.loginFailure} is called if the necessary SSL APIs
- are unavailable.
- """
- self.patch(msn, 'ClientContextFactory', None)
- success = []
- self.client.loggedIn = lambda *args: success.append(args)
- failure = []
- self.client.loginFailure = failure.append
-
- self.client.lineReceived('USR 6 TWN S opaque-string-goes-here')
- self.assertEqual(success, [])
- self.assertEqual(
- failure,
- ["Exception while authenticating: "
- "Connecting to the Passport server requires SSL, but SSL is "
- "unavailable."])
-
-
- def testProfile(self):
- m = 'MSG Hotmail Hotmail 353\r\nMIME-Version: 1.0\r\nContent-Type: text/x-msmsgsprofile; charset=UTF-8\r\n'
- m += 'LoginTime: 1016941010\r\nEmailEnabled: 1\r\nMemberIdHigh: 40000\r\nMemberIdLow: -600000000\r\nlang_preference: 1033\r\n'
- m += 'preferredEmail: foo@bar.com\r\ncountry: AU\r\nPostalCode: 90210\r\nGender: M\r\nKid: 0\r\nAge:\r\nsid: 400\r\n'
- m += 'kv: 2\r\nMSPAuth: 2CACCBCCADMoV8ORoz64BVwmjtksIg!kmR!Rj5tBBqEaW9hc4YnPHSOQ$$\r\n\r\n'
- map(self.client.lineReceived, m.split('\r\n')[:-1])
- self.failUnless((self.client.state == 'PROFILE'), msg='Failed to detect initial profile')
-
- def testStatus(self):
- t = [('ILN 1 AWY foo@bar.com Test%20Screen%20Name 0', 'INITSTATUS', 'Failed to detect initial status report'),
- ('NLN LUN foo@bar.com Test%20Name 0', 'NEWSTATUS', 'Failed to detect contact status change'),
- ('FLN foo@bar.com', 'OFFLINE', 'Failed to detect contact signing off'),
- ('CHG 1 HDN 0', 'MYSTATUS', 'Failed to detect my status changing')]
- for i in t:
- self.client.lineReceived(i[0])
- self.failUnless((self.client.state == i[1]), msg=i[2])
-
- def testListSync(self):
- # currently this test does not take into account the fact
- # that BPRs sent as part of the SYN reply may not be interpreted
- # as such if they are for the last LST -- maybe I should
- # factor this in later.
- self.client.makeConnection(StringTransport())
- msn.NotificationClient.loggedIn(self.client, 'foo@foo.com', 'foobar', 1)
- lines = [
- "SYN %s 100 1 1" % self.client.currentID,
- "GTC A",
- "BLP AL",
- "LSG 0 Other%20Contacts 0",
- "LST userHandle@email.com Some%20Name 11 0"
- ]
- map(self.client.lineReceived, lines)
- contacts = self.client.factory.contacts
- contact = contacts.getContact('userHandle@email.com')
- self.failUnless(contacts.version == 100, "Invalid contact list version")
- self.failUnless(contact.screenName == 'Some Name', "Invalid screen-name for user")
- self.failUnless(contacts.groups == {0 : 'Other Contacts'}, "Did not get proper group list")
- self.failUnless(contact.groups == [0] and contact.lists == 11, "Invalid contact list/group info")
- self.failUnless(self.client.state == 'GOTLIST', "Failed to call list sync handler")
-
- def testAsyncPhoneChange(self):
- c = msn.MSNContact(userHandle='userHandle@email.com')
- self.client.factory.contacts = msn.MSNContactList()
- self.client.factory.contacts.addContact(c)
- self.client.makeConnection(StringTransport())
- self.client.lineReceived("BPR 101 userHandle@email.com PHH 123%20456")
- c = self.client.factory.contacts.getContact('userHandle@email.com')
- self.failUnless(self.client.state == 'GOTPHONE', "Did not fire phone change callback")
- self.failUnless(c.homePhone == '123 456', "Did not update the contact's phone number")
- self.failUnless(self.client.factory.contacts.version == 101, "Did not update list version")
-
- def testLateBPR(self):
- """
- This test makes sure that if a BPR response that was meant
- to be part of a SYN response (but came after the last LST)
- is received, the correct contact is updated and all is well
- """
- self.client.makeConnection(StringTransport())
- msn.NotificationClient.loggedIn(self.client, 'foo@foo.com', 'foo', 1)
- lines = [
- "SYN %s 100 1 1" % self.client.currentID,
- "GTC A",
- "BLP AL",
- "LSG 0 Other%20Contacts 0",
- "LST userHandle@email.com Some%20Name 11 0",
- "BPR PHH 123%20456"
- ]
- map(self.client.lineReceived, lines)
- contact = self.client.factory.contacts.getContact('userHandle@email.com')
- self.failUnless(contact.homePhone == '123 456', "Did not update contact's phone number")
-
- def testUserRemovedMe(self):
- self.client.factory.contacts = msn.MSNContactList()
- contact = msn.MSNContact(userHandle='foo@foo.com')
- contact.addToList(msn.REVERSE_LIST)
- self.client.factory.contacts.addContact(contact)
- self.client.lineReceived("REM 0 RL 100 foo@foo.com")
- self.failUnless(self.client.state == 'USERREMOVEDME', "Failed to remove user from reverse list")
-
- def testUserAddedMe(self):
- self.client.factory.contacts = msn.MSNContactList()
- self.client.lineReceived("ADD 0 RL 100 foo@foo.com Screen%20Name")
- self.failUnless(self.client.state == 'USERADDEDME', "Failed to add user to reverse lise")
-
- def testAsyncSwitchboardInvitation(self):
- self.client.lineReceived("RNG 1234 192.168.1.1:1863 CKI 123.456 foo@foo.com Screen%20Name")
- self.failUnless(self.client.state == "SBINVITED")
-
- def testCommandFailed(self):
- """
- Ensures that error responses from the server fires an errback with
- MSNCommandFailed.
- """
- id, d = self.client._createIDMapping()
- self.client.lineReceived("201 %s" % id)
- d = self.assertFailure(d, msn.MSNCommandFailed)
- def assertErrorCode(exception):
- self.assertEqual(201, exception.errorCode)
- return d.addCallback(assertErrorCode)
-
-
-class MessageHandlingTests(unittest.TestCase):
- """ testing various message handling methods from SwichboardClient """
-
- def setUp(self):
- self.client = DummySwitchboardClient()
- self.client.state = 'START'
-
- def tearDown(self):
- self.client = None
-
- def testClientCapabilitiesCheck(self):
- m = msn.MSNMessage()
- m.setHeader('Content-Type', 'text/x-clientcaps')
- self.assertEqual(self.client.checkMessage(m), 0, 'Failed to detect client capability message')
-
- def testTypingCheck(self):
- m = msn.MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgscontrol')
- m.setHeader('TypingUser', 'foo@bar')
- self.client.checkMessage(m)
- self.failUnless((self.client.state == 'TYPING'), msg='Failed to detect typing notification')
-
- def testFileInvitation(self, lazyClient=False):
- m = msn.MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8')
- m.message += 'Application-Name: File Transfer\r\n'
- if not lazyClient:
- m.message += 'Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}\r\n'
- m.message += 'Invitation-Command: Invite\r\n'
- m.message += 'Invitation-Cookie: 1234\r\n'
- m.message += 'Application-File: foobar.ext\r\n'
- m.message += 'Application-FileSize: 31337\r\n\r\n'
- self.client.checkMessage(m)
- self.failUnless((self.client.state == 'INVITATION'), msg='Failed to detect file transfer invitation')
-
- def testFileInvitationMissingGUID(self):
- return self.testFileInvitation(True)
-
- def testFileResponse(self):
- d = Deferred()
- d.addCallback(self.fileResponse)
- self.client.cookies['iCookies'][1234] = (d, None)
- m = msn.MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8')
- m.message += 'Invitation-Command: ACCEPT\r\n'
- m.message += 'Invitation-Cookie: 1234\r\n\r\n'
- self.client.checkMessage(m)
- self.failUnless((self.client.state == 'RESPONSE'), msg='Failed to detect file transfer response')
-
- def testFileInfo(self):
- d = Deferred()
- d.addCallback(self.fileInfo)
- self.client.cookies['external'][1234] = (d, None)
- m = msn.MSNMessage()
- m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8')
- m.message += 'Invitation-Command: ACCEPT\r\n'
- m.message += 'Invitation-Cookie: 1234\r\n'
- m.message += 'IP-Address: 192.168.0.1\r\n'
- m.message += 'Port: 6891\r\n'
- m.message += 'AuthCookie: 4321\r\n\r\n'
- self.client.checkMessage(m)
- self.failUnless((self.client.state == 'INFO'), msg='Failed to detect file transfer info')
-
- def fileResponse(self, (accept, cookie, info)):
- if accept and cookie == 1234: self.client.state = 'RESPONSE'
-
- def fileInfo(self, (accept, ip, port, aCookie, info)):
- if accept and ip == '192.168.0.1' and port == 6891 and aCookie == 4321: self.client.state = 'INFO'
-
-
-class FileTransferTestCase(unittest.TestCase):
- """
- test FileSend against FileReceive
- """
-
- def setUp(self):
- self.input = 'a' * 7000
- self.output = StringIOWithoutClosing()
-
-
- def tearDown(self):
- self.input = None
- self.output = None
-
-
- def test_fileTransfer(self):
- """
- Test L{FileSend} against L{FileReceive} using a loopback transport.
- """
- auth = 1234
- sender = msn.FileSend(StringIO.StringIO(self.input))
- sender.auth = auth
- sender.fileSize = 7000
- client = msn.FileReceive(auth, "foo@bar.com", self.output)
- client.fileSize = 7000
- def check(ignored):
- self.assertTrue(
- client.completed and sender.completed,
- msg="send failed to complete")
- self.assertEqual(
- self.input, self.output.getvalue(),
- msg="saved file does not match original")
- d = loopback.loopbackAsync(sender, client)
- d.addCallback(check)
- return d
-
-if msn is None:
- for testClass in [DispatchTests, PassportTests, NotificationTests,
- MessageHandlingTests, FileTransferTestCase]:
- testClass.skip = (
- "MSN requires an HTTP client but none is available, "
- "skipping tests.")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_oscar.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_oscar.py
deleted file mode 100755
index f807ce5a..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_oscar.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.protocols.oscar}.
-"""
-
-from twisted.trial.unittest import TestCase
-
-from twisted.words.protocols.oscar import encryptPasswordMD5
-
-
-class PasswordTests(TestCase):
- """
- Tests for L{encryptPasswordMD5}.
- """
- def test_encryptPasswordMD5(self):
- """
- L{encryptPasswordMD5} hashes the given password and key and returns a
- string suitable to use to authenticate against an OSCAR server.
- """
- self.assertEqual(
- encryptPasswordMD5('foo', 'bar').encode('hex'),
- 'd73475c370a7b18c6c20386bcf1339f2')
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_service.py
deleted file mode 100755
index 12720fea..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_service.py
+++ /dev/null
@@ -1,995 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.service}.
-"""
-
-import time
-
-from twisted.trial import unittest
-from twisted.test import proto_helpers
-
-from twisted.cred import portal, credentials, checkers
-from twisted.words import ewords, service
-from twisted.words.protocols import irc
-from twisted.spread import pb
-from twisted.internet.defer import Deferred, DeferredList, maybeDeferred, succeed
-from twisted.internet.defer import deferredGenerator as dG, waitForDeferred as wFD
-from twisted.internet import address, reactor
-
-class RealmTestCase(unittest.TestCase):
- def _entityCreationTest(self, kind):
- # Kind is "user" or "group"
- realm = service.InMemoryWordsRealm("realmname")
-
- name = u'test' + kind.lower()
- create = getattr(realm, 'create' + kind.title())
- get = getattr(realm, 'get' + kind.title())
- flag = 'create' + kind.title() + 'OnRequest'
- dupExc = getattr(ewords, 'Duplicate' + kind.title())
- noSuchExc = getattr(ewords, 'NoSuch' + kind.title())
-
- # Creating should succeed
- d = wFD(create(name))
- yield d
- p = d.getResult()
- self.assertEqual(p.name, name)
-
- # Creating the same user again should not
- d = wFD(create(name))
- yield d
- self.assertRaises(dupExc, d.getResult)
-
- # Getting a non-existent user should succeed if createUserOnRequest is True
- setattr(realm, flag, True)
- d = wFD(get(u"new" + kind.lower()))
- yield d
- p = d.getResult()
- self.assertEqual(p.name, "new" + kind.lower())
-
- # Getting that user again should return the same object
- d = wFD(get(u"new" + kind.lower()))
- yield d
- newp = d.getResult()
- self.assertIdentical(p, newp)
-
- # Getting a non-existent user should fail if createUserOnRequest is False
- setattr(realm, flag, False)
- d = wFD(get(u"another" + kind.lower()))
- yield d
- self.assertRaises(noSuchExc, d.getResult)
- _entityCreationTest = dG(_entityCreationTest)
-
-
- def testUserCreation(self):
- return self._entityCreationTest("User")
-
-
- def testGroupCreation(self):
- return self._entityCreationTest("Group")
-
-
- def testUserRetrieval(self):
- realm = service.InMemoryWordsRealm("realmname")
-
- # Make a user to play around with
- d = wFD(realm.createUser(u"testuser"))
- yield d
- user = d.getResult()
-
- # Make sure getting the user returns the same object
- d = wFD(realm.getUser(u"testuser"))
- yield d
- retrieved = d.getResult()
- self.assertIdentical(user, retrieved)
-
- # Make sure looking up the user also returns the same object
- d = wFD(realm.lookupUser(u"testuser"))
- yield d
- lookedUp = d.getResult()
- self.assertIdentical(retrieved, lookedUp)
-
- # Make sure looking up a user who does not exist fails
- d = wFD(realm.lookupUser(u"nosuchuser"))
- yield d
- self.assertRaises(ewords.NoSuchUser, d.getResult)
- testUserRetrieval = dG(testUserRetrieval)
-
-
- def testUserAddition(self):
- realm = service.InMemoryWordsRealm("realmname")
-
- # Create and manually add a user to the realm
- p = service.User("testuser")
- d = wFD(realm.addUser(p))
- yield d
- user = d.getResult()
- self.assertIdentical(p, user)
-
- # Make sure getting that user returns the same object
- d = wFD(realm.getUser(u"testuser"))
- yield d
- retrieved = d.getResult()
- self.assertIdentical(user, retrieved)
-
- # Make sure looking up that user returns the same object
- d = wFD(realm.lookupUser(u"testuser"))
- yield d
- lookedUp = d.getResult()
- self.assertIdentical(retrieved, lookedUp)
- testUserAddition = dG(testUserAddition)
-
-
- def testGroupRetrieval(self):
- realm = service.InMemoryWordsRealm("realmname")
-
- d = wFD(realm.createGroup(u"testgroup"))
- yield d
- group = d.getResult()
-
- d = wFD(realm.getGroup(u"testgroup"))
- yield d
- retrieved = d.getResult()
-
- self.assertIdentical(group, retrieved)
-
- d = wFD(realm.getGroup(u"nosuchgroup"))
- yield d
- self.assertRaises(ewords.NoSuchGroup, d.getResult)
- testGroupRetrieval = dG(testGroupRetrieval)
-
-
- def testGroupAddition(self):
- realm = service.InMemoryWordsRealm("realmname")
-
- p = service.Group("testgroup")
- d = wFD(realm.addGroup(p))
- yield d
- d.getResult()
-
- d = wFD(realm.getGroup(u"testGroup"))
- yield d
- group = d.getResult()
-
- self.assertIdentical(p, group)
- testGroupAddition = dG(testGroupAddition)
-
-
- def testGroupUsernameCollision(self):
- """
- Try creating a group with the same name as an existing user and
- assert that it succeeds, since users and groups should not be in the
- same namespace and collisions should be impossible.
- """
- realm = service.InMemoryWordsRealm("realmname")
-
- d = wFD(realm.createUser(u"test"))
- yield d
- user = d.getResult()
-
- d = wFD(realm.createGroup(u"test"))
- yield d
- group = d.getResult()
- testGroupUsernameCollision = dG(testGroupUsernameCollision)
-
-
- def testEnumeration(self):
- realm = service.InMemoryWordsRealm("realmname")
- d = wFD(realm.createGroup(u"groupone"))
- yield d
- d.getResult()
-
- d = wFD(realm.createGroup(u"grouptwo"))
- yield d
- d.getResult()
-
- groups = wFD(realm.itergroups())
- yield groups
- groups = groups.getResult()
-
- n = [g.name for g in groups]
- n.sort()
- self.assertEqual(n, ["groupone", "grouptwo"])
- testEnumeration = dG(testEnumeration)
-
-
-class TestGroup(object):
- def __init__(self, name, size, topic):
- self.name = name
- self.size = lambda: size
- self.meta = {'topic': topic}
-
-
-class TestUser(object):
- def __init__(self, name, groups, signOn, lastMessage):
- self.name = name
- self.itergroups = lambda: iter([TestGroup(g, 3, 'Hello') for g in groups])
- self.signOn = signOn
- self.lastMessage = lastMessage
-
-
-class TestPortal(object):
- def __init__(self):
- self.logins = []
-
-
- def login(self, credentials, mind, *interfaces):
- d = Deferred()
- self.logins.append((credentials, mind, interfaces, d))
- return d
-
-
-class TestCaseUserAgg(object):
- def __init__(self, user, realm, factory, address=address.IPv4Address('TCP', '127.0.0.1', 54321)):
- self.user = user
- self.transport = proto_helpers.StringTransportWithDisconnection()
- self.protocol = factory.buildProtocol(address)
- self.transport.protocol = self.protocol
- self.user.mind = self.protocol
- self.protocol.makeConnection(self.transport)
-
-
- def write(self, stuff):
- if isinstance(stuff, unicode):
- stuff = stuff.encode('utf-8')
- self.protocol.dataReceived(stuff)
-
-
-class IRCProtocolTestCase(unittest.TestCase):
- STATIC_USERS = [
- u'useruser', u'otheruser', u'someguy', u'firstuser', u'username',
- u'userone', u'usertwo', u'userthree', u'someuser']
-
-
- def setUp(self):
- self.realm = service.InMemoryWordsRealm("realmname")
- self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- self.portal = portal.Portal(self.realm, [self.checker])
- self.factory = service.IRCFactory(self.realm, self.portal)
-
- c = []
- for nick in self.STATIC_USERS:
- c.append(self.realm.createUser(nick))
- self.checker.addUser(nick.encode('ascii'), nick + "_password")
- return DeferredList(c)
-
-
- def _assertGreeting(self, user):
- """
- The user has been greeted with the four messages that are (usually)
- considered to start an IRC session.
-
- Asserts that the required responses were received.
- """
- # Make sure we get 1-4 at least
- response = self._response(user)
- expected = [irc.RPL_WELCOME, irc.RPL_YOURHOST, irc.RPL_CREATED,
- irc.RPL_MYINFO]
- for (prefix, command, args) in response:
- if command in expected:
- expected.remove(command)
- self.failIf(expected, "Missing responses for %r" % (expected,))
-
-
- def _login(self, user, nick, password=None):
- if password is None:
- password = nick + "_password"
- user.write('PASS %s\r\n' % (password,))
- user.write('NICK %s extrainfo\r\n' % (nick,))
-
-
- def _loggedInUser(self, name):
- d = wFD(self.realm.lookupUser(name))
- yield d
- user = d.getResult()
- agg = TestCaseUserAgg(user, self.realm, self.factory)
- self._login(agg, name)
- yield agg
- _loggedInUser = dG(_loggedInUser)
-
-
- def _response(self, user, messageType=None):
- """
- Extracts the user's response, and returns a list of parsed lines.
- If messageType is defined, only messages of that type will be returned.
- """
- response = user.transport.value().splitlines()
- user.transport.clear()
- result = []
- for message in map(irc.parsemsg, response):
- if messageType is None or message[1] == messageType:
- result.append(message)
- return result
-
-
- def testPASSLogin(self):
- user = wFD(self._loggedInUser(u'firstuser'))
- yield user
- user = user.getResult()
- self._assertGreeting(user)
- testPASSLogin = dG(testPASSLogin)
-
-
- def test_nickServLogin(self):
- """
- Sending NICK without PASS will prompt the user for their password.
- When the user sends their password to NickServ, it will respond with a
- Greeting.
- """
- firstuser = wFD(self.realm.lookupUser(u'firstuser'))
- yield firstuser
- firstuser = firstuser.getResult()
-
- user = TestCaseUserAgg(firstuser, self.realm, self.factory)
- user.write('NICK firstuser extrainfo\r\n')
- response = self._response(user, 'PRIVMSG')
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][0], service.NICKSERV)
- self.assertEqual(response[0][1], 'PRIVMSG')
- self.assertEqual(response[0][2], ['firstuser', 'Password?'])
- user.transport.clear()
-
- user.write('PRIVMSG nickserv firstuser_password\r\n')
- self._assertGreeting(user)
- test_nickServLogin = dG(test_nickServLogin)
-
-
- def testFailedLogin(self):
- firstuser = wFD(self.realm.lookupUser(u'firstuser'))
- yield firstuser
- firstuser = firstuser.getResult()
-
- user = TestCaseUserAgg(firstuser, self.realm, self.factory)
- self._login(user, "firstuser", "wrongpass")
- response = self._response(user, "PRIVMSG")
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][2], ['firstuser', 'Login failed. Goodbye.'])
- testFailedLogin = dG(testFailedLogin)
-
-
- def testLogout(self):
- logout = []
- firstuser = wFD(self.realm.lookupUser(u'firstuser'))
- yield firstuser
- firstuser = firstuser.getResult()
-
- user = TestCaseUserAgg(firstuser, self.realm, self.factory)
- self._login(user, "firstuser")
- user.protocol.logout = lambda: logout.append(True)
- user.write('QUIT\r\n')
- self.assertEqual(logout, [True])
- testLogout = dG(testLogout)
-
-
- def testJoin(self):
- firstuser = wFD(self.realm.lookupUser(u'firstuser'))
- yield firstuser
- firstuser = firstuser.getResult()
-
- somechannel = wFD(self.realm.createGroup(u"somechannel"))
- yield somechannel
- somechannel = somechannel.getResult()
-
- somechannel.meta['topic'] = 'some random topic'
-
- # Bring in one user, make sure he gets into the channel sanely
- user = TestCaseUserAgg(firstuser, self.realm, self.factory)
- self._login(user, "firstuser")
- user.transport.clear()
- user.write('JOIN #somechannel\r\n')
-
- response = self._response(user)
- self.assertEqual(len(response), 5)
-
- # Join message
- self.assertEqual(response[0][0], 'firstuser!firstuser@realmname')
- self.assertEqual(response[0][1], 'JOIN')
- self.assertEqual(response[0][2], ['#somechannel'])
-
- # User list
- self.assertEqual(response[1][1], '353')
- self.assertEqual(response[2][1], '366')
-
- # Topic (or lack thereof, as the case may be)
- self.assertEqual(response[3][1], '332')
- self.assertEqual(response[4][1], '333')
-
-
- # Hook up another client! It is a CHAT SYSTEM!!!!!!!
- other = wFD(self._loggedInUser(u'otheruser'))
- yield other
- other = other.getResult()
-
- other.transport.clear()
- user.transport.clear()
- other.write('JOIN #somechannel\r\n')
-
- # At this point, both users should be in the channel
- response = self._response(other)
-
- event = self._response(user)
- self.assertEqual(len(event), 1)
- self.assertEqual(event[0][0], 'otheruser!otheruser@realmname')
- self.assertEqual(event[0][1], 'JOIN')
- self.assertEqual(event[0][2], ['#somechannel'])
-
- self.assertEqual(response[1][0], 'realmname')
- self.assertEqual(response[1][1], '353')
- self.assertIn(response[1][2], [
- ['otheruser', '=', '#somechannel', 'firstuser otheruser'],
- ['otheruser', '=', '#somechannel', 'otheruser firstuser'],
- ])
- testJoin = dG(testJoin)
-
-
- def test_joinTopicless(self):
- """
- When a user joins a group without a topic, no topic information is
- sent to that user.
- """
- firstuser = wFD(self.realm.lookupUser(u'firstuser'))
- yield firstuser
- firstuser = firstuser.getResult()
-
- somechannel = wFD(self.realm.createGroup(u"somechannel"))
- yield somechannel
- somechannel = somechannel.getResult()
-
- # Bring in one user, make sure he gets into the channel sanely
- user = TestCaseUserAgg(firstuser, self.realm, self.factory)
- self._login(user, "firstuser")
- user.transport.clear()
- user.write('JOIN #somechannel\r\n')
-
- response = self._response(user)
- responseCodes = [r[1] for r in response]
- self.assertNotIn('332', responseCodes)
- self.assertNotIn('333', responseCodes)
- test_joinTopicless = dG(test_joinTopicless)
-
-
- def testLeave(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- somechannel = wFD(self.realm.createGroup(u"somechannel"))
- yield somechannel
- somechannel = somechannel.getResult()
-
- user.write('JOIN #somechannel\r\n')
- user.transport.clear()
-
- other = wFD(self._loggedInUser(u'otheruser'))
- yield other
- other = other.getResult()
-
- other.write('JOIN #somechannel\r\n')
-
- user.transport.clear()
- other.transport.clear()
-
- user.write('PART #somechannel\r\n')
-
- response = self._response(user)
- event = self._response(other)
-
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][0], 'useruser!useruser@realmname')
- self.assertEqual(response[0][1], 'PART')
- self.assertEqual(response[0][2], ['#somechannel', 'leaving'])
- self.assertEqual(response, event)
-
- # Now again, with a part message
- user.write('JOIN #somechannel\r\n')
-
- user.transport.clear()
- other.transport.clear()
-
- user.write('PART #somechannel :goodbye stupidheads\r\n')
-
- response = self._response(user)
- event = self._response(other)
-
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][0], 'useruser!useruser@realmname')
- self.assertEqual(response[0][1], 'PART')
- self.assertEqual(response[0][2], ['#somechannel', 'goodbye stupidheads'])
- self.assertEqual(response, event)
- testLeave = dG(testLeave)
-
-
- def testGetTopic(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- group = service.Group("somechannel")
- group.meta["topic"] = "This is a test topic."
- group.meta["topic_author"] = "some_fellow"
- group.meta["topic_date"] = 77777777
-
- add = wFD(self.realm.addGroup(group))
- yield add
- add.getResult()
-
- user.transport.clear()
- user.write("JOIN #somechannel\r\n")
-
- response = self._response(user)
-
- self.assertEqual(response[3][0], 'realmname')
- self.assertEqual(response[3][1], '332')
-
- # XXX Sigh. irc.parsemsg() is not as correct as one might hope.
- self.assertEqual(response[3][2], ['useruser', '#somechannel', 'This is a test topic.'])
- self.assertEqual(response[4][1], '333')
- self.assertEqual(response[4][2], ['useruser', '#somechannel', 'some_fellow', '77777777'])
-
- user.transport.clear()
-
- user.write('TOPIC #somechannel\r\n')
-
- response = self._response(user)
-
- self.assertEqual(response[0][1], '332')
- self.assertEqual(response[0][2], ['useruser', '#somechannel', 'This is a test topic.'])
- self.assertEqual(response[1][1], '333')
- self.assertEqual(response[1][2], ['useruser', '#somechannel', 'some_fellow', '77777777'])
- testGetTopic = dG(testGetTopic)
-
-
- def testSetTopic(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- add = wFD(self.realm.createGroup(u"somechannel"))
- yield add
- somechannel = add.getResult()
-
- user.write("JOIN #somechannel\r\n")
-
- other = wFD(self._loggedInUser(u'otheruser'))
- yield other
- other = other.getResult()
-
- other.write("JOIN #somechannel\r\n")
-
- user.transport.clear()
- other.transport.clear()
-
- other.write('TOPIC #somechannel :This is the new topic.\r\n')
-
- response = self._response(other)
- event = self._response(user)
-
- self.assertEqual(response, event)
-
- self.assertEqual(response[0][0], 'otheruser!otheruser@realmname')
- self.assertEqual(response[0][1], 'TOPIC')
- self.assertEqual(response[0][2], ['#somechannel', 'This is the new topic.'])
-
- other.transport.clear()
-
- somechannel.meta['topic_date'] = 12345
- other.write('TOPIC #somechannel\r\n')
-
- response = self._response(other)
- self.assertEqual(response[0][1], '332')
- self.assertEqual(response[0][2], ['otheruser', '#somechannel', 'This is the new topic.'])
- self.assertEqual(response[1][1], '333')
- self.assertEqual(response[1][2], ['otheruser', '#somechannel', 'otheruser', '12345'])
-
- other.transport.clear()
- other.write('TOPIC #asdlkjasd\r\n')
-
- response = self._response(other)
- self.assertEqual(response[0][1], '403')
- testSetTopic = dG(testSetTopic)
-
-
- def testGroupMessage(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- add = wFD(self.realm.createGroup(u"somechannel"))
- yield add
- somechannel = add.getResult()
-
- user.write("JOIN #somechannel\r\n")
-
- other = wFD(self._loggedInUser(u'otheruser'))
- yield other
- other = other.getResult()
-
- other.write("JOIN #somechannel\r\n")
-
- user.transport.clear()
- other.transport.clear()
-
- user.write('PRIVMSG #somechannel :Hello, world.\r\n')
-
- response = self._response(user)
- event = self._response(other)
-
- self.failIf(response)
- self.assertEqual(len(event), 1)
- self.assertEqual(event[0][0], 'useruser!useruser@realmname')
- self.assertEqual(event[0][1], 'PRIVMSG', -1)
- self.assertEqual(event[0][2], ['#somechannel', 'Hello, world.'])
- testGroupMessage = dG(testGroupMessage)
-
-
- def testPrivateMessage(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- other = wFD(self._loggedInUser(u'otheruser'))
- yield other
- other = other.getResult()
-
- user.transport.clear()
- other.transport.clear()
-
- user.write('PRIVMSG otheruser :Hello, monkey.\r\n')
-
- response = self._response(user)
- event = self._response(other)
-
- self.failIf(response)
- self.assertEqual(len(event), 1)
- self.assertEqual(event[0][0], 'useruser!useruser@realmname')
- self.assertEqual(event[0][1], 'PRIVMSG')
- self.assertEqual(event[0][2], ['otheruser', 'Hello, monkey.'])
-
- user.write('PRIVMSG nousernamedthis :Hello, monkey.\r\n')
-
- response = self._response(user)
-
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][0], 'realmname')
- self.assertEqual(response[0][1], '401')
- self.assertEqual(response[0][2], ['useruser', 'nousernamedthis', 'No such nick/channel.'])
- testPrivateMessage = dG(testPrivateMessage)
-
-
- def testOper(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- user.transport.clear()
- user.write('OPER user pass\r\n')
- response = self._response(user)
-
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][1], '491')
- testOper = dG(testOper)
-
-
- def testGetUserMode(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- user.transport.clear()
- user.write('MODE useruser\r\n')
-
- response = self._response(user)
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][0], 'realmname')
- self.assertEqual(response[0][1], '221')
- self.assertEqual(response[0][2], ['useruser', '+'])
- testGetUserMode = dG(testGetUserMode)
-
-
- def testSetUserMode(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- user.transport.clear()
- user.write('MODE useruser +abcd\r\n')
-
- response = self._response(user)
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][1], '472')
- testSetUserMode = dG(testSetUserMode)
-
-
- def testGetGroupMode(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- add = wFD(self.realm.createGroup(u"somechannel"))
- yield add
- somechannel = add.getResult()
-
- user.write('JOIN #somechannel\r\n')
-
- user.transport.clear()
- user.write('MODE #somechannel\r\n')
-
- response = self._response(user)
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][1], '324')
- testGetGroupMode = dG(testGetGroupMode)
-
-
- def testSetGroupMode(self):
- user = wFD(self._loggedInUser(u'useruser'))
- yield user
- user = user.getResult()
-
- group = wFD(self.realm.createGroup(u"groupname"))
- yield group
- group = group.getResult()
-
- user.write('JOIN #groupname\r\n')
-
- user.transport.clear()
- user.write('MODE #groupname +abcd\r\n')
-
- response = self._response(user)
- self.assertEqual(len(response), 1)
- self.assertEqual(response[0][1], '472')
- testSetGroupMode = dG(testSetGroupMode)
-
-
- def testWho(self):
- group = service.Group('groupname')
- add = wFD(self.realm.addGroup(group))
- yield add
- add.getResult()
-
- users = []
- for nick in u'userone', u'usertwo', u'userthree':
- u = wFD(self._loggedInUser(nick))
- yield u
- u = u.getResult()
- users.append(u)
- users[-1].write('JOIN #groupname\r\n')
- for user in users:
- user.transport.clear()
-
- users[0].write('WHO #groupname\r\n')
-
- r = self._response(users[0])
- self.failIf(self._response(users[1]))
- self.failIf(self._response(users[2]))
-
- wantusers = ['userone', 'usertwo', 'userthree']
- for (prefix, code, stuff) in r[:-1]:
- self.assertEqual(prefix, 'realmname')
- self.assertEqual(code, '352')
-
- (myname, group, theirname, theirhost, theirserver, theirnick, flag, extra) = stuff
- self.assertEqual(myname, 'userone')
- self.assertEqual(group, '#groupname')
- self.failUnless(theirname in wantusers)
- self.assertEqual(theirhost, 'realmname')
- self.assertEqual(theirserver, 'realmname')
- wantusers.remove(theirnick)
- self.assertEqual(flag, 'H')
- self.assertEqual(extra, '0 ' + theirnick)
- self.failIf(wantusers)
-
- prefix, code, stuff = r[-1]
- self.assertEqual(prefix, 'realmname')
- self.assertEqual(code, '315')
- myname, channel, extra = stuff
- self.assertEqual(myname, 'userone')
- self.assertEqual(channel, '#groupname')
- self.assertEqual(extra, 'End of /WHO list.')
- testWho = dG(testWho)
-
-
- def testList(self):
- user = wFD(self._loggedInUser(u"someuser"))
- yield user
- user = user.getResult()
- user.transport.clear()
-
- somegroup = wFD(self.realm.createGroup(u"somegroup"))
- yield somegroup
- somegroup = somegroup.getResult()
- somegroup.size = lambda: succeed(17)
- somegroup.meta['topic'] = 'this is the topic woo'
-
- # Test one group
- user.write('LIST #somegroup\r\n')
-
- r = self._response(user)
- self.assertEqual(len(r), 2)
- resp, end = r
-
- self.assertEqual(resp[0], 'realmname')
- self.assertEqual(resp[1], '322')
- self.assertEqual(resp[2][0], 'someuser')
- self.assertEqual(resp[2][1], 'somegroup')
- self.assertEqual(resp[2][2], '17')
- self.assertEqual(resp[2][3], 'this is the topic woo')
-
- self.assertEqual(end[0], 'realmname')
- self.assertEqual(end[1], '323')
- self.assertEqual(end[2][0], 'someuser')
- self.assertEqual(end[2][1], 'End of /LIST')
-
- user.transport.clear()
- # Test all groups
-
- user.write('LIST\r\n')
- r = self._response(user)
- self.assertEqual(len(r), 2)
-
- fg1, end = r
-
- self.assertEqual(fg1[1], '322')
- self.assertEqual(fg1[2][1], 'somegroup')
- self.assertEqual(fg1[2][2], '17')
- self.assertEqual(fg1[2][3], 'this is the topic woo')
-
- self.assertEqual(end[1], '323')
- testList = dG(testList)
-
-
- def testWhois(self):
- user = wFD(self._loggedInUser(u'someguy'))
- yield user
- user = user.getResult()
-
- otherguy = service.User("otherguy")
- otherguy.itergroups = lambda: iter([
- service.Group('groupA'),
- service.Group('groupB')])
- otherguy.signOn = 10
- otherguy.lastMessage = time.time() - 15
-
- add = wFD(self.realm.addUser(otherguy))
- yield add
- add.getResult()
-
- user.transport.clear()
- user.write('WHOIS otherguy\r\n')
- r = self._response(user)
-
- self.assertEqual(len(r), 5)
- wuser, wserver, idle, channels, end = r
-
- self.assertEqual(wuser[0], 'realmname')
- self.assertEqual(wuser[1], '311')
- self.assertEqual(wuser[2][0], 'someguy')
- self.assertEqual(wuser[2][1], 'otherguy')
- self.assertEqual(wuser[2][2], 'otherguy')
- self.assertEqual(wuser[2][3], 'realmname')
- self.assertEqual(wuser[2][4], '*')
- self.assertEqual(wuser[2][5], 'otherguy')
-
- self.assertEqual(wserver[0], 'realmname')
- self.assertEqual(wserver[1], '312')
- self.assertEqual(wserver[2][0], 'someguy')
- self.assertEqual(wserver[2][1], 'otherguy')
- self.assertEqual(wserver[2][2], 'realmname')
- self.assertEqual(wserver[2][3], 'Hi mom!')
-
- self.assertEqual(idle[0], 'realmname')
- self.assertEqual(idle[1], '317')
- self.assertEqual(idle[2][0], 'someguy')
- self.assertEqual(idle[2][1], 'otherguy')
- self.assertEqual(idle[2][2], '15')
- self.assertEqual(idle[2][3], '10')
- self.assertEqual(idle[2][4], "seconds idle, signon time")
-
- self.assertEqual(channels[0], 'realmname')
- self.assertEqual(channels[1], '319')
- self.assertEqual(channels[2][0], 'someguy')
- self.assertEqual(channels[2][1], 'otherguy')
- self.assertEqual(channels[2][2], '#groupA #groupB')
-
- self.assertEqual(end[0], 'realmname')
- self.assertEqual(end[1], '318')
- self.assertEqual(end[2][0], 'someguy')
- self.assertEqual(end[2][1], 'otherguy')
- self.assertEqual(end[2][2], 'End of WHOIS list.')
- testWhois = dG(testWhois)
-
-
-class TestMind(service.PBMind):
- def __init__(self, *a, **kw):
- self.joins = []
- self.parts = []
- self.messages = []
- self.meta = []
-
- def remote_userJoined(self, user, group):
- self.joins.append((user, group))
-
-
- def remote_userLeft(self, user, group, reason):
- self.parts.append((user, group, reason))
-
-
- def remote_receive(self, sender, recipient, message):
- self.messages.append((sender, recipient, message))
-
-
- def remote_groupMetaUpdate(self, group, meta):
- self.meta.append((group, meta))
-pb.setUnjellyableForClass(TestMind, service.PBMindReference)
-
-
-class PBProtocolTestCase(unittest.TestCase):
- def setUp(self):
- self.realm = service.InMemoryWordsRealm("realmname")
- self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- self.portal = portal.Portal(
- self.realm, [self.checker])
- self.serverFactory = pb.PBServerFactory(self.portal)
- self.serverFactory.protocol = self._protocolFactory
- self.serverFactory.unsafeTracebacks = True
- self.clientFactory = pb.PBClientFactory()
- self.clientFactory.unsafeTracebacks = True
- self.serverPort = reactor.listenTCP(0, self.serverFactory)
- self.clientConn = reactor.connectTCP(
- '127.0.0.1',
- self.serverPort.getHost().port,
- self.clientFactory)
-
-
- def _protocolFactory(self, *args, **kw):
- self._serverProtocol = pb.Broker(0)
- return self._serverProtocol
-
-
- def tearDown(self):
- d3 = Deferred()
- self._serverProtocol.notifyOnDisconnect(lambda: d3.callback(None))
- return DeferredList([
- maybeDeferred(self.serverPort.stopListening),
- maybeDeferred(self.clientConn.disconnect), d3])
-
-
- def _loggedInAvatar(self, name, password, mind):
- creds = credentials.UsernamePassword(name, password)
- self.checker.addUser(name.encode('ascii'), password)
- d = self.realm.createUser(name)
- d.addCallback(lambda ign: self.clientFactory.login(creds, mind))
- return d
-
-
- def testGroups(self):
- mindone = TestMind()
- one = wFD(self._loggedInAvatar(u"one", "p1", mindone))
- yield one
- one = one.getResult()
-
- mindtwo = TestMind()
- two = wFD(self._loggedInAvatar(u"two", "p2", mindtwo))
- yield two
- two = two.getResult()
-
- add = wFD(self.realm.createGroup(u"foobar"))
- yield add
- add.getResult()
-
- groupone = wFD(one.join(u"foobar"))
- yield groupone
- groupone = groupone.getResult()
-
- grouptwo = wFD(two.join(u"foobar"))
- yield grouptwo
- grouptwo = grouptwo.getResult()
-
- msg = wFD(groupone.send({"text": "hello, monkeys"}))
- yield msg
- msg = msg.getResult()
-
- leave = wFD(groupone.leave())
- yield leave
- leave = leave.getResult()
- testGroups = dG(testGroups)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_tap.py
deleted file mode 100755
index 099c104f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_tap.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.cred import credentials, error
-from twisted.words import tap
-from twisted.trial import unittest
-
-
-
-class WordsTap(unittest.TestCase):
- """
- Ensures that the twisted.words.tap API works.
- """
-
- PASSWD_TEXT = "admin:admin\njoe:foo\n"
- admin = credentials.UsernamePassword('admin', 'admin')
- joeWrong = credentials.UsernamePassword('joe', 'bar')
-
-
- def setUp(self):
- """
- Create a file with two users.
- """
- self.filename = self.mktemp()
- self.file = open(self.filename, 'w')
- self.file.write(self.PASSWD_TEXT)
- self.file.flush()
-
-
- def tearDown(self):
- """
- Close the dummy user database.
- """
- self.file.close()
-
-
- def test_hostname(self):
- """
- Tests that the --hostname parameter gets passed to Options.
- """
- opt = tap.Options()
- opt.parseOptions(['--hostname', 'myhost'])
- self.assertEqual(opt['hostname'], 'myhost')
-
-
- def test_passwd(self):
- """
- Tests the --passwd command for backwards-compatibility.
- """
- opt = tap.Options()
- opt.parseOptions(['--passwd', self.file.name])
- self._loginTest(opt)
-
-
- def test_auth(self):
- """
- Tests that the --auth command generates a checker.
- """
- opt = tap.Options()
- opt.parseOptions(['--auth', 'file:'+self.file.name])
- self._loginTest(opt)
-
-
- def _loginTest(self, opt):
- """
- This method executes both positive and negative authentication
- tests against whatever credentials checker has been stored in
- the Options class.
-
- @param opt: An instance of L{tap.Options}.
- """
- self.assertEqual(len(opt['credCheckers']), 1)
- checker = opt['credCheckers'][0]
- self.assertFailure(checker.requestAvatarId(self.joeWrong),
- error.UnauthorizedLogin)
- def _gotAvatar(username):
- self.assertEqual(username, self.admin.username)
- return checker.requestAvatarId(self.admin).addCallback(_gotAvatar)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xishutil.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xishutil.py
deleted file mode 100755
index b046e6ea..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xishutil.py
+++ /dev/null
@@ -1,345 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Test cases for twisted.words.xish.utility
-"""
-
-from twisted.trial import unittest
-
-from twisted.python.util import OrderedDict
-from twisted.words.xish import utility
-from twisted.words.xish.domish import Element
-from twisted.words.xish.utility import EventDispatcher
-
-class CallbackTracker:
- """
- Test helper for tracking callbacks.
-
- Increases a counter on each call to L{call} and stores the object
- passed in the call.
- """
-
- def __init__(self):
- self.called = 0
- self.obj = None
-
-
- def call(self, obj):
- self.called = self.called + 1
- self.obj = obj
-
-
-
-class OrderedCallbackTracker:
- """
- Test helper for tracking callbacks and their order.
- """
-
- def __init__(self):
- self.callList = []
-
-
- def call1(self, object):
- self.callList.append(self.call1)
-
-
- def call2(self, object):
- self.callList.append(self.call2)
-
-
- def call3(self, object):
- self.callList.append(self.call3)
-
-
-
-class EventDispatcherTest(unittest.TestCase):
- """
- Tests for L{EventDispatcher}.
- """
-
- def testStuff(self):
- d = EventDispatcher()
- cb1 = CallbackTracker()
- cb2 = CallbackTracker()
- cb3 = CallbackTracker()
-
- d.addObserver("/message/body", cb1.call)
- d.addObserver("/message", cb1.call)
- d.addObserver("/presence", cb2.call)
- d.addObserver("//event/testevent", cb3.call)
-
- msg = Element(("ns", "message"))
- msg.addElement("body")
-
- pres = Element(("ns", "presence"))
- pres.addElement("presence")
-
- d.dispatch(msg)
- self.assertEqual(cb1.called, 2)
- self.assertEqual(cb1.obj, msg)
- self.assertEqual(cb2.called, 0)
-
- d.dispatch(pres)
- self.assertEqual(cb1.called, 2)
- self.assertEqual(cb2.called, 1)
- self.assertEqual(cb2.obj, pres)
- self.assertEqual(cb3.called, 0)
-
- d.dispatch(d, "//event/testevent")
- self.assertEqual(cb3.called, 1)
- self.assertEqual(cb3.obj, d)
-
- d.removeObserver("/presence", cb2.call)
- d.dispatch(pres)
- self.assertEqual(cb2.called, 1)
-
-
- def test_addObserverTwice(self):
- """
- Test adding two observers for the same query.
-
- When the event is dispath both of the observers need to be called.
- """
- d = EventDispatcher()
- cb1 = CallbackTracker()
- cb2 = CallbackTracker()
-
- d.addObserver("//event/testevent", cb1.call)
- d.addObserver("//event/testevent", cb2.call)
- d.dispatch(d, "//event/testevent")
-
- self.assertEqual(cb1.called, 1)
- self.assertEqual(cb1.obj, d)
- self.assertEqual(cb2.called, 1)
- self.assertEqual(cb2.obj, d)
-
-
- def test_addObserverInDispatch(self):
- """
- Test for registration of an observer during dispatch.
- """
- d = EventDispatcher()
- msg = Element(("ns", "message"))
- cb = CallbackTracker()
-
- def onMessage(_):
- d.addObserver("/message", cb.call)
-
- d.addOnetimeObserver("/message", onMessage)
-
- d.dispatch(msg)
- self.assertEqual(cb.called, 0)
-
- d.dispatch(msg)
- self.assertEqual(cb.called, 1)
-
- d.dispatch(msg)
- self.assertEqual(cb.called, 2)
-
-
- def test_addOnetimeObserverInDispatch(self):
- """
- Test for registration of a onetime observer during dispatch.
- """
- d = EventDispatcher()
- msg = Element(("ns", "message"))
- cb = CallbackTracker()
-
- def onMessage(msg):
- d.addOnetimeObserver("/message", cb.call)
-
- d.addOnetimeObserver("/message", onMessage)
-
- d.dispatch(msg)
- self.assertEqual(cb.called, 0)
-
- d.dispatch(msg)
- self.assertEqual(cb.called, 1)
-
- d.dispatch(msg)
- self.assertEqual(cb.called, 1)
-
-
- def testOnetimeDispatch(self):
- d = EventDispatcher()
- msg = Element(("ns", "message"))
- cb = CallbackTracker()
-
- d.addOnetimeObserver("/message", cb.call)
- d.dispatch(msg)
- self.assertEqual(cb.called, 1)
- d.dispatch(msg)
- self.assertEqual(cb.called, 1)
-
-
- def testDispatcherResult(self):
- d = EventDispatcher()
- msg = Element(("ns", "message"))
- pres = Element(("ns", "presence"))
- cb = CallbackTracker()
-
- d.addObserver("/presence", cb.call)
- result = d.dispatch(msg)
- self.assertEqual(False, result)
-
- result = d.dispatch(pres)
- self.assertEqual(True, result)
-
-
- def testOrderedXPathDispatch(self):
- d = EventDispatcher()
- cb = OrderedCallbackTracker()
- d.addObserver("/message/body", cb.call2)
- d.addObserver("/message", cb.call3, -1)
- d.addObserver("/message/body", cb.call1, 1)
-
- msg = Element(("ns", "message"))
- msg.addElement("body")
- d.dispatch(msg)
- self.assertEqual(cb.callList, [cb.call1, cb.call2, cb.call3],
- "Calls out of order: %s" %
- repr([c.__name__ for c in cb.callList]))
-
-
- # Observers are put into CallbackLists that are then put into dictionaries
- # keyed by the event trigger. Upon removal of the last observer for a
- # particular event trigger, the (now empty) CallbackList and corresponding
- # event trigger should be removed from those dictionaries to prevent
- # slowdown and memory leakage.
-
- def test_cleanUpRemoveEventObserver(self):
- """
- Test observer clean-up after removeObserver for named events.
- """
-
- d = EventDispatcher()
- cb = CallbackTracker()
-
- d.addObserver('//event/test', cb.call)
- d.dispatch(None, '//event/test')
- self.assertEqual(1, cb.called)
- d.removeObserver('//event/test', cb.call)
- self.assertEqual(0, len(d._eventObservers.pop(0)))
-
-
- def test_cleanUpRemoveXPathObserver(self):
- """
- Test observer clean-up after removeObserver for XPath events.
- """
-
- d = EventDispatcher()
- cb = CallbackTracker()
- msg = Element((None, "message"))
-
- d.addObserver('/message', cb.call)
- d.dispatch(msg)
- self.assertEqual(1, cb.called)
- d.removeObserver('/message', cb.call)
- self.assertEqual(0, len(d._xpathObservers.pop(0)))
-
-
- def test_cleanUpOnetimeEventObserver(self):
- """
- Test observer clean-up after onetime named events.
- """
-
- d = EventDispatcher()
- cb = CallbackTracker()
-
- d.addOnetimeObserver('//event/test', cb.call)
- d.dispatch(None, '//event/test')
- self.assertEqual(1, cb.called)
- self.assertEqual(0, len(d._eventObservers.pop(0)))
-
-
- def test_cleanUpOnetimeXPathObserver(self):
- """
- Test observer clean-up after onetime XPath events.
- """
-
- d = EventDispatcher()
- cb = CallbackTracker()
- msg = Element((None, "message"))
-
- d.addOnetimeObserver('/message', cb.call)
- d.dispatch(msg)
- self.assertEqual(1, cb.called)
- self.assertEqual(0, len(d._xpathObservers.pop(0)))
-
-
- def test_observerRaisingException(self):
- """
- Test that exceptions in observers do not bubble up to dispatch.
-
- The exceptions raised in observers should be logged and other
- observers should be called as if nothing happened.
- """
-
- class OrderedCallbackList(utility.CallbackList):
- def __init__(self):
- self.callbacks = OrderedDict()
-
- class TestError(Exception):
- pass
-
- def raiseError(_):
- raise TestError()
-
- d = EventDispatcher()
- cb = CallbackTracker()
-
- originalCallbackList = utility.CallbackList
-
- try:
- utility.CallbackList = OrderedCallbackList
-
- d.addObserver('//event/test', raiseError)
- d.addObserver('//event/test', cb.call)
- try:
- d.dispatch(None, '//event/test')
- except TestError:
- self.fail("TestError raised. Should have been logged instead.")
-
- self.assertEqual(1, len(self.flushLoggedErrors(TestError)))
- self.assertEqual(1, cb.called)
- finally:
- utility.CallbackList = originalCallbackList
-
-
-
-class XmlPipeTest(unittest.TestCase):
- """
- Tests for L{twisted.words.xish.utility.XmlPipe}.
- """
-
- def setUp(self):
- self.pipe = utility.XmlPipe()
-
-
- def test_sendFromSource(self):
- """
- Send an element from the source and observe it from the sink.
- """
- def cb(obj):
- called.append(obj)
-
- called = []
- self.pipe.sink.addObserver('/test[@xmlns="testns"]', cb)
- element = Element(('testns', 'test'))
- self.pipe.source.send(element)
- self.assertEqual([element], called)
-
-
- def test_sendFromSink(self):
- """
- Send an element from the sink and observe it from the source.
- """
- def cb(obj):
- called.append(obj)
-
- called = []
- self.pipe.source.addObserver('/test[@xmlns="testns"]', cb)
- element = Element(('testns', 'test'))
- self.pipe.sink.send(element)
- self.assertEqual([element], called)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmlstream.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmlstream.py
deleted file mode 100755
index 4eb24463..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmlstream.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.xish.xmlstream}.
-"""
-
-from twisted.internet import protocol
-from twisted.python import failure
-from twisted.trial import unittest
-from twisted.words.xish import domish, utility, xmlstream
-
-class XmlStreamTest(unittest.TestCase):
- def setUp(self):
- self.connectionLostMsg = "no reason"
- self.outlist = []
- self.xmlstream = xmlstream.XmlStream()
- self.xmlstream.transport = self
- self.xmlstream.transport.write = self.outlist.append
-
-
- def loseConnection(self):
- """
- Stub loseConnection because we are a transport.
- """
- self.xmlstream.connectionLost(failure.Failure(
- Exception(self.connectionLostMsg)))
-
-
- def test_send(self):
- """
- Calling L{xmlstream.XmlStream.send} results in the data being written
- to the transport.
- """
- self.xmlstream.connectionMade()
- self.xmlstream.send("<root>")
- self.assertEqual(self.outlist[0], "<root>")
-
-
- def test_receiveRoot(self):
- """
- Receiving the starttag of the root element results in stream start.
- """
- streamStarted = []
-
- def streamStartEvent(rootelem):
- streamStarted.append(None)
-
- self.xmlstream.addObserver(xmlstream.STREAM_START_EVENT,
- streamStartEvent)
- self.xmlstream.connectionMade()
- self.xmlstream.dataReceived("<root>")
- self.assertEqual(1, len(streamStarted))
-
-
- def test_receiveBadXML(self):
- """
- Receiving malformed XML results in an L{STREAM_ERROR_EVENT}.
- """
- streamError = []
- streamEnd = []
-
- def streamErrorEvent(reason):
- streamError.append(reason)
-
- def streamEndEvent(_):
- streamEnd.append(None)
-
- self.xmlstream.addObserver(xmlstream.STREAM_ERROR_EVENT,
- streamErrorEvent)
- self.xmlstream.addObserver(xmlstream.STREAM_END_EVENT,
- streamEndEvent)
- self.xmlstream.connectionMade()
-
- self.xmlstream.dataReceived("<root>")
- self.assertEqual(0, len(streamError))
- self.assertEqual(0, len(streamEnd))
-
- self.xmlstream.dataReceived("<child><unclosed></child>")
- self.assertEqual(1, len(streamError))
- self.assertTrue(streamError[0].check(domish.ParserError))
- self.assertEqual(1, len(streamEnd))
-
-
- def test_streamEnd(self):
- """
- Ending the stream fires a L{STREAM_END_EVENT}.
- """
- streamEnd = []
-
- def streamEndEvent(reason):
- streamEnd.append(reason)
-
- self.xmlstream.addObserver(xmlstream.STREAM_END_EVENT,
- streamEndEvent)
- self.xmlstream.connectionMade()
- self.loseConnection()
- self.assertEqual(1, len(streamEnd))
- self.assertIsInstance(streamEnd[0], failure.Failure)
- self.assertEqual(streamEnd[0].getErrorMessage(),
- self.connectionLostMsg)
-
-
-
-class DummyProtocol(protocol.Protocol, utility.EventDispatcher):
- """
- I am a protocol with an event dispatcher without further processing.
-
- This protocol is only used for testing XmlStreamFactoryMixin to make
- sure the bootstrap observers are added to the protocol instance.
- """
-
- def __init__(self, *args, **kwargs):
- self.args = args
- self.kwargs = kwargs
- self.observers = []
-
- utility.EventDispatcher.__init__(self)
-
-
-
-class BootstrapMixinTest(unittest.TestCase):
- """
- Tests for L{xmlstream.BootstrapMixin}.
-
- @ivar factory: Instance of the factory or mixin under test.
- """
-
- def setUp(self):
- self.factory = xmlstream.BootstrapMixin()
-
-
- def test_installBootstraps(self):
- """
- Dispatching an event fires registered bootstrap observers.
- """
- called = []
-
- def cb(data):
- called.append(data)
-
- dispatcher = DummyProtocol()
- self.factory.addBootstrap('//event/myevent', cb)
- self.factory.installBootstraps(dispatcher)
-
- dispatcher.dispatch(None, '//event/myevent')
- self.assertEqual(1, len(called))
-
-
- def test_addAndRemoveBootstrap(self):
- """
- Test addition and removal of a bootstrap event handler.
- """
-
- called = []
-
- def cb(data):
- called.append(data)
-
- self.factory.addBootstrap('//event/myevent', cb)
- self.factory.removeBootstrap('//event/myevent', cb)
-
- dispatcher = DummyProtocol()
- self.factory.installBootstraps(dispatcher)
-
- dispatcher.dispatch(None, '//event/myevent')
- self.assertFalse(called)
-
-
-
-class GenericXmlStreamFactoryTestsMixin(BootstrapMixinTest):
- """
- Generic tests for L{XmlStream} factories.
- """
-
- def setUp(self):
- self.factory = xmlstream.XmlStreamFactory()
-
-
- def test_buildProtocolInstallsBootstraps(self):
- """
- The protocol factory installs bootstrap event handlers on the protocol.
- """
- called = []
-
- def cb(data):
- called.append(data)
-
- self.factory.addBootstrap('//event/myevent', cb)
-
- xs = self.factory.buildProtocol(None)
- xs.dispatch(None, '//event/myevent')
-
- self.assertEqual(1, len(called))
-
-
- def test_buildProtocolStoresFactory(self):
- """
- The protocol factory is saved in the protocol.
- """
- xs = self.factory.buildProtocol(None)
- self.assertIdentical(self.factory, xs.factory)
-
-
-
-class XmlStreamFactoryMixinTest(GenericXmlStreamFactoryTestsMixin):
- """
- Tests for L{xmlstream.XmlStreamFactoryMixin}.
- """
-
- def setUp(self):
- self.factory = xmlstream.XmlStreamFactoryMixin(None, test=None)
- self.factory.protocol = DummyProtocol
-
-
- def test_buildProtocolFactoryArguments(self):
- """
- Arguments passed to the factory are passed to protocol on
- instantiation.
- """
- xs = self.factory.buildProtocol(None)
-
- self.assertEqual((None,), xs.args)
- self.assertEqual({'test': None}, xs.kwargs)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmpproutertap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmpproutertap.py
deleted file mode 100755
index aaadf34d..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xmpproutertap.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for L{twisted.words.xmpproutertap}.
-"""
-
-from twisted.application import internet
-from twisted.trial import unittest
-from twisted.words import xmpproutertap as tap
-from twisted.words.protocols.jabber import component
-
-class XMPPRouterTapTest(unittest.TestCase):
-
- def test_port(self):
- """
- The port option is recognised as a parameter.
- """
- opt = tap.Options()
- opt.parseOptions(['--port', '7001'])
- self.assertEqual(opt['port'], '7001')
-
-
- def test_portDefault(self):
- """
- The port option has '5347' as default value
- """
- opt = tap.Options()
- opt.parseOptions([])
- self.assertEqual(opt['port'], 'tcp:5347:interface=127.0.0.1')
-
-
- def test_secret(self):
- """
- The secret option is recognised as a parameter.
- """
- opt = tap.Options()
- opt.parseOptions(['--secret', 'hushhush'])
- self.assertEqual(opt['secret'], 'hushhush')
-
-
- def test_secretDefault(self):
- """
- The secret option has 'secret' as default value
- """
- opt = tap.Options()
- opt.parseOptions([])
- self.assertEqual(opt['secret'], 'secret')
-
-
- def test_verbose(self):
- """
- The verbose option is recognised as a flag.
- """
- opt = tap.Options()
- opt.parseOptions(['--verbose'])
- self.assertTrue(opt['verbose'])
-
-
- def test_makeService(self):
- """
- The service gets set up with a router and factory.
- """
- opt = tap.Options()
- opt.parseOptions([])
- s = tap.makeService(opt)
- self.assertIsInstance(s, internet.StreamServerEndpointService)
- self.assertEqual('127.0.0.1', s.endpoint._interface)
- self.assertEqual(5347, s.endpoint._port)
- factory = s.factory
- self.assertIsInstance(factory, component.XMPPComponentServerFactory)
- self.assertIsInstance(factory.router, component.Router)
- self.assertEqual('secret', factory.secret)
- self.assertFalse(factory.logTraffic)
-
-
- def test_makeServiceVerbose(self):
- """
- The verbose flag enables traffic logging.
- """
- opt = tap.Options()
- opt.parseOptions(['--verbose'])
- s = tap.makeService(opt)
- self.assertTrue(s.factory.logTraffic)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xpath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xpath.py
deleted file mode 100755
index 9dbda0fc..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/test/test_xpath.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-from twisted.trial import unittest
-import sys, os
-
-from twisted.words.xish.domish import Element
-from twisted.words.xish.xpath import XPathQuery
-from twisted.words.xish import xpath
-
-class XPathTest(unittest.TestCase):
- def setUp(self):
- # Build element:
- # <foo xmlns='testns' attrib1='value1' attrib3="user@host/resource">
- # somecontent
- # <bar>
- # <foo>
- # <gar>DEF</gar>
- # </foo>
- # </bar>
- # somemorecontent
- # <bar attrib2="value2">
- # <bar>
- # <foo/>
- # <gar>ABC</gar>
- # </bar>
- # <bar/>
- # <bar attrib4='value4' attrib5='value5'>
- # <foo/>
- # <gar>JKL</gar>
- # </bar>
- # <bar attrib4='value4' attrib5='value4'>
- # <foo/>
- # <gar>MNO</gar>
- # </bar>
- # <bar attrib4='value4' attrib5='value6'/>
- # </foo>
- self.e = Element(("testns", "foo"))
- self.e["attrib1"] = "value1"
- self.e["attrib3"] = "user@host/resource"
- self.e.addContent("somecontent")
- self.bar1 = self.e.addElement("bar")
- self.subfoo = self.bar1.addElement("foo")
- self.gar1 = self.subfoo.addElement("gar")
- self.gar1.addContent("DEF")
- self.e.addContent("somemorecontent")
- self.bar2 = self.e.addElement("bar")
- self.bar2["attrib2"] = "value2"
- self.bar3 = self.bar2.addElement("bar")
- self.subfoo2 = self.bar3.addElement("foo")
- self.gar2 = self.bar3.addElement("gar")
- self.gar2.addContent("ABC")
- self.bar4 = self.e.addElement("bar")
- self.bar5 = self.e.addElement("bar")
- self.bar5["attrib4"] = "value4"
- self.bar5["attrib5"] = "value5"
- self.subfoo3 = self.bar5.addElement("foo")
- self.gar3 = self.bar5.addElement("gar")
- self.gar3.addContent("JKL")
- self.bar6 = self.e.addElement("bar")
- self.bar6["attrib4"] = "value4"
- self.bar6["attrib5"] = "value4"
- self.subfoo4 = self.bar6.addElement("foo")
- self.gar4 = self.bar6.addElement("gar")
- self.gar4.addContent("MNO")
- self.bar7 = self.e.addElement("bar")
- self.bar7["attrib4"] = "value4"
- self.bar7["attrib5"] = "value6"
-
- def test_staticMethods(self):
- """
- Test basic operation of the static methods.
- """
- self.assertEqual(xpath.matches("/foo/bar", self.e),
- True)
- self.assertEqual(xpath.queryForNodes("/foo/bar", self.e),
- [self.bar1, self.bar2, self.bar4,
- self.bar5, self.bar6, self.bar7])
- self.assertEqual(xpath.queryForString("/foo", self.e),
- "somecontent")
- self.assertEqual(xpath.queryForStringList("/foo", self.e),
- ["somecontent", "somemorecontent"])
-
- def test_locationFooBar(self):
- """
- Test matching foo with child bar.
- """
- xp = XPathQuery("/foo/bar")
- self.assertEqual(xp.matches(self.e), 1)
-
- def test_locationFooBarFoo(self):
- """
- Test finding foos at the second level.
- """
- xp = XPathQuery("/foo/bar/foo")
- self.assertEqual(xp.matches(self.e), 1)
- self.assertEqual(xp.queryForNodes(self.e), [self.subfoo,
- self.subfoo3,
- self.subfoo4])
-
- def test_locationNoBar3(self):
- """
- Test not finding bar3.
- """
- xp = XPathQuery("/foo/bar3")
- self.assertEqual(xp.matches(self.e), 0)
-
- def test_locationAllChilds(self):
- """
- Test finding childs of foo.
- """
- xp = XPathQuery("/foo/*")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar1, self.bar2,
- self.bar4, self.bar5,
- self.bar6, self.bar7])
-
- def test_attribute(self):
- """
- Test matching foo with attribute.
- """
- xp = XPathQuery("/foo[@attrib1]")
- self.assertEqual(xp.matches(self.e), True)
-
- def test_attributeWithValueAny(self):
- """
- Test find nodes with attribute having value.
- """
- xp = XPathQuery("/foo/*[@attrib2='value2']")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar2])
-
- def test_position(self):
- """
- Test finding element at position.
- """
- xp = XPathQuery("/foo/bar[2]")
- self.assertEqual(xp.matches(self.e), 1)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar1])
-
- test_position.todo = "XPath queries with position are not working."
-
- def test_namespaceFound(self):
- """
- Test matching node with namespace.
- """
- xp = XPathQuery("/foo[@xmlns='testns']/bar")
- self.assertEqual(xp.matches(self.e), 1)
-
- def test_namespaceNotFound(self):
- """
- Test not matching node with wrong namespace.
- """
- xp = XPathQuery("/foo[@xmlns='badns']/bar2")
- self.assertEqual(xp.matches(self.e), 0)
-
- def test_attributeWithValue(self):
- """
- Test matching node with attribute having value.
- """
- xp = XPathQuery("/foo[@attrib1='value1']")
- self.assertEqual(xp.matches(self.e), 1)
-
- def test_queryForString(self):
- """
- Test for queryForString and queryForStringList.
- """
- xp = XPathQuery("/foo")
- self.assertEqual(xp.queryForString(self.e), "somecontent")
- self.assertEqual(xp.queryForStringList(self.e),
- ["somecontent", "somemorecontent"])
-
- def test_queryForNodes(self):
- """
- Test finding nodes.
- """
- xp = XPathQuery("/foo/bar")
- self.assertEqual(xp.queryForNodes(self.e), [self.bar1, self.bar2,
- self.bar4, self.bar5,
- self.bar6, self.bar7])
-
- def test_textCondition(self):
- """
- Test matching a node with given text.
- """
- xp = XPathQuery("/foo[text() = 'somecontent']")
- self.assertEqual(xp.matches(self.e), True)
-
- def test_textNotOperator(self):
- """
- Test for not operator.
- """
- xp = XPathQuery("/foo[not(@nosuchattrib)]")
- self.assertEqual(xp.matches(self.e), True)
-
- def test_anyLocationAndText(self):
- """
- Test finding any nodes named gar and getting their text contents.
- """
- xp = XPathQuery("//gar")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.gar1, self.gar2,
- self.gar3, self.gar4])
- self.assertEqual(xp.queryForStringList(self.e), ["DEF", "ABC",
- "JKL", "MNO"])
-
- def test_anyLocation(self):
- """
- Test finding any nodes named bar.
- """
- xp = XPathQuery("//bar")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar1, self.bar2,
- self.bar3, self.bar4,
- self.bar5, self.bar6,
- self.bar7])
-
- def test_anyLocationQueryForString(self):
- """
- L{XPathQuery.queryForString} should raise a L{NotImplementedError}
- for any location.
- """
- xp = XPathQuery("//bar")
- self.assertRaises(NotImplementedError, xp.queryForString, None)
-
- def test_andOperator(self):
- """
- Test boolean and operator in condition.
- """
- xp = XPathQuery("//bar[@attrib4='value4' and @attrib5='value5']")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar5])
-
- def test_orOperator(self):
- """
- Test boolean or operator in condition.
- """
- xp = XPathQuery("//bar[@attrib5='value4' or @attrib5='value5']")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar5, self.bar6])
-
- def test_booleanOperatorsParens(self):
- """
- Test multiple boolean operators in condition with parens.
- """
- xp = XPathQuery("""//bar[@attrib4='value4' and
- (@attrib5='value4' or @attrib5='value6')]""")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar6, self.bar7])
-
- def test_booleanOperatorsNoParens(self):
- """
- Test multiple boolean operators in condition without parens.
- """
- xp = XPathQuery("""//bar[@attrib5='value4' or
- @attrib5='value5' or
- @attrib5='value6']""")
- self.assertEqual(xp.matches(self.e), True)
- self.assertEqual(xp.queryForNodes(self.e), [self.bar5, self.bar6, self.bar7])
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/NEWS
deleted file mode 100644
index 416bf000..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/NEWS
+++ /dev/null
@@ -1,369 +0,0 @@
-Ticket numbers in this file can be looked up by visiting
-http://twistedmatrix.com/trac/ticket/<number>
-
-Twisted Words 12.2.0 (2012-08-26)
-=================================
-
-No significant changes have been made for this release.
-
-Other
------
- - #5752, #5753
-
-
-Twisted Words 12.1.0 (2012-06-02)
-=================================
-
-Bugfixes
---------
- - twisted.words.protocols.irc.DccChatFactory.buildProtocol now
- returns the protocol object that it creates (#3179)
- - twisted.words.im no longer offers an empty threat of a rewrite on
- import. (#5598)
-
-Other
------
- - #5555, #5595
-
-
-Twisted Words 12.0.0 (2012-02-10)
-=================================
-
-Improved Documentation
-----------------------
- - twisted.words.im.basechat now has improved API documentation.
- (#2458)
-
-Other
------
- - #5401
-
-
-Twisted Words 11.1.0 (2011-11-15)
-=================================
-
-Features
---------
- - twisted.words.protocols.irc.IRCClient now uses a PING heartbeat as
- a keepalive to avoid losing an IRC connection without being aware
- of it. (#5047)
-
-Bugfixes
---------
- - twisted.words.protocols.irc.IRCClient now replies only once to
- known CTCP queries per message and not at all to unknown CTCP
- queries. (#5029)
- - IRCClient.msg now determines a safe maximum command length,
- drastically reducing the chance of relayed text being truncated on
- the server side. (#5176)
-
-Deprecations and Removals
--------------------------
- - twisted.words.protocols.irc.IRCClient.me was deprecated in Twisted
- 9.0 and has been removed. Use IRCClient.describe instead. (#5059)
-
-Other
------
- - #5025, #5330
-
-
-Twisted Words 11.0.0 (2011-04-01)
-=================================
-
-Features
---------
- - twisted.words.protocols.irc.IRCClient now has an invite method.
- (#4820)
-
-Bugfixes
---------
- - twisted.words.protocols.irc.IRCClient.say is once again able to
- send messages when using the default value for the length limit
- argument. (#4758)
- - twisted.words.protocols.jabber.jstrports is once again able to
- parse jstrport description strings. (#4771)
- - twisted.words.protocols.msn.NotificationClient now calls the
- loginFailure callback when it is unable to connect to the Passport
- server due to missing SSL dependencies. (#4801)
- - twisted.words.protocols.jabber.xmpp_stringprep now always uses
- Unicode version 3.2 for stringprep normalization. (#4850)
-
-Improved Documentation
-----------------------
- - Removed the non-working AIM bot example, depending on the obsolete
- twisted.words.protocols.toc functionality. (#4007)
- - Outdated GUI-related information was removed from the IM howto.
- (#4054)
-
-Deprecations and Removals
--------------------------
- - Remove twisted.words.protocols.toc, that was largely non-working
- and useless since AOL disabled TOC on their AIM network. (#4363)
-
-Other
------
- - #4733, #4902
-
-
-Twisted Words 10.2.0 (2010-11-29)
-=================================
-
-Features
---------
- - twisted.words.protocols.irc.IRCClient.msg now enforces a maximum
- length for messages, splitting up messages that are too long.
- (#4416)
-
-Bugfixes
---------
- - twisted.words.protocols.irc.IRCClient no longer invokes privmsg()
- in the default noticed() implementation. (#4419)
- - twisted.words.im.ircsupport.IRCProto now sends the correct name in
- the USER command. (#4641)
-
-Deprecations and Removals
--------------------------
- - Remove twisted.words.im.proxyui and twisted.words.im.tap. (#1823)
-
-
-Twisted Words 10.1.0 (2010-06-27)
-=================================
-
-Bugfixes
---------
- - twisted.words.im.basechat.ChatUI now has a functional
- contactChangedNick with unit tests. (#229)
- - twisted.words.protocols.jabber.error.StanzaError now correctly sets
- a default error type and code for the remote-server-timeout
- condition (#4311)
- - twisted.words.protocols.jabber.xmlstream.ListenAuthenticator now
- uses unicode objects for session identifiers (#4345)
-
-
-Twisted Words 10.0.0 (2010-03-01)
-=================================
-
-Features
---------
- - twisted.words.protocols.irc.IRCClient.irc_MODE now takes ISUPPORT
- parameters into account when parsing mode messages with arguments
- that take parameters (#3296)
-
-Bugfixes
---------
- - When twisted.words.protocols.irc.IRCClient's versionNum and
- versionEnv attributes are set to None, they will no longer be
- included in the client's response to CTCP VERSION queries. (#3660)
-
- - twisted.words.protocols.jabber.xmlstream.hashPassword now only
- accepts unicode as input (#3741, #3742, #3847)
-
-Other
------
- - #2503, #4066, #4261
-
-
-Twisted Words 9.0.0 (2009-11-24)
-================================
-
-Features
---------
- - IRCClient.describe is a new method meant to replace IRCClient.me to send
- CTCP ACTION messages with less confusing behavior (#3910)
- - The XMPP client protocol implementation now supports ANONYMOUS SASL
- authentication (#4067)
- - The IRC client protocol implementation now has better support for the
- ISUPPORT server->client message, storing the data in a new
- ServerSupportedFeatures object accessible via IRCClient.supported (#3285)
-
-Fixes
------
- - The twisted.words IRC server now always sends an MOTD, which at least makes
- Pidgin able to successfully connect to a twisted.words IRC server (#2385)
- - The IRC client will now dispatch "RPL MOTD" messages received before a
- "RPL MOTD START" instead of raising an exception (#3676)
- - The IRC client protocol implementation no longer updates its 'nickname'
- attribute directly; instead, that attribute will be updated when the server
- acknowledges the change (#3377)
- - The IRC client protocol implementation now supports falling back to another
- nickname when a nick change request fails (#3377, #4010)
-
-Deprecations and Removals
--------------------------
- - The TOC protocol implementation is now deprecated, since the protocol itself
- has been deprecated and obselete for quite a long time (#3580)
- - The gui "im" application has been removed, since it relied on GTK1, which is
- hard to find these days (#3699, #3340)
-
-Other
------
- - #2763, #3540, #3647, #3750, #3895, #3968, #4050
-
-Words 8.2.0 (2008-12-16)
-========================
-
-Feature
--------
- - There is now a standalone XMPP router included in twisted.words: it can be
- used with the 'twistd xmpp-router' command line (#3407)
- - A server factory for Jabber XML Streams has been added (#3435)
- - Domish now allows for iterating child elements with specific qualified names
- (#2429)
- - IRCClient now has a 'back' method which removes the away status (#3366)
- - IRCClient now has a 'whois' method (#3133)
-
-Fixes
------
- - The IRC Client implementation can now deal with compound mode changes (#3230)
- - The MSN protocol implementation no longer requires the CVR0 protocol to
- be included in the VER command (#3394)
- - In the IRC server implementation, topic messages will no longer be sent for
- a group which has no topic (#2204)
- - An infinite loop (which caused infinite memory usage) in irc.split has been
- fixed. This was triggered any time a message that starts with a delimiter
- was sent (#3446)
- - Jabber's toResponse now generates a valid stanza even when stanzaType is not
- specified (#3467)
- - The lifetime of authenticator instances in XmlStreamServerFactory is no
- longer artificially extended (#3464)
-
-Other
------
- - #3365
-
-
-8.1.0 (2008-05-18)
-==================
-
-Features
---------
- - JID objects now have a nice __repr__ (#3156)
- - Extending XMPP protocols is now easier (#2178)
-
-Fixes
------
- - The deprecated mktap API is no longer used (#3127)
- - A bug whereby one-time XMPP observers would be enabled permanently was fixed
- (#3066)
-
-
-8.0.0 (2008-03-17)
-==================
-
-Features
---------
- - Provide function for creating XMPP response stanzas. (#2614, #2614)
- - Log exceptions raised in Xish observers. (#2616)
- - Add 'and' and 'or' operators for Xish XPath expressions. (#2502)
- - Make JIDs hashable. (#2770)
-
-Fixes
------
- - Respect the hostname and servername parameters to IRCClient.register. (#1649)
- - Make EventDispatcher remove empty callback lists. (#1652)
- - Use legacy base64 API to support Python 2.3 (#2461)
- - Fix support of DIGEST-MD5 challenge parsing with multi-valued directives.
- (#2606)
- - Fix reuse of dict of prefixes in domish.Element.toXml (#2609)
- - Properly process XMPP stream headers (#2615)
- - Use proper namespace for XMPP stream errors. (#2630)
- - Properly parse XMPP stream errors. (#2771)
- - Fix toResponse for XMPP stanzas without an id attribute. (#2773)
- - Move XMPP stream header procesing to authenticators. (#2772)
-
-Misc
-----
- - #2617, #2640, #2741, #2063, #2570, #2847
-
-
-0.5.0 (2007-01-06)
-==================
-
-Features
---------
- - (Jabber) IQ.send now optionally has a 'timeout' parameter which
- specifies a time at which to errback the Deferred with a
- TimeoutError (#2218)
- - (Jabber) SASL authentication, resource binding and session
- establishment were added. (#1046) The following were done in
- support of this change:
- - Rework ConnectAuthenticator to work with initializer objects that
- provide a stream initialization step.
- - Reimplement iq:auth as an initializer.
- - Reimplement TLS negotiation as an initializer.
- - Add XMPPAuthenticator as a XMPP 1.0 client authenticator (only), along
- with XMPPClientFactory.
- - Add support for working with pre-XMPP-1.0 error stanzas.
- - Remove hasFeature() from XmlStream as you can test (uri, name) in
- xs.features.
- - Add sendFooter() and sendStreamError() to XmlStream
-
-Fixes
------
- - (Jabber) Deferreds from queries which were never resolved before
- a lost connection are now errbacked (#2006)
- - (Jabber) servers which didn't send a 'realm' directive in
- authentication challenges no longer cause the Jabber client to
- choke (#2098)
- - (MSN) error responses are now properly turned into errbacks (#2019)
- - (IRC) A trivial bug in IRCClient which would cause whois(oper=True)
- to always raise an exception was fixed (#2089)
- - (IM) Bugs in the error handling and already-connecting cases of
- AbstractAccount.logOn were fixed (#2086)
-
-Misc
-----
- - #1734, #1735, #1636, #1936, #1883, #1995, #2171, #2165, #2177
-
-
-0.4.0 (2006-05-21)
-==================
-
-Features
---------
- - Jabber:
- - Add support for stream and stanza level errors
- - Create new IQ stanza helper that works with deferreds
- - Add TLS support for initiating entities to XmlStream
- - Fix account registration
- - Xish:
- - Fix various namespace issues
- - Add IElement
- - Store namespace declarations in parsed XML for later serialization
- - Fix user name/group collision in server service (#1655).
- - Correctly recognize MSN capability messages (#861).
-
-Fixes
------
- - Misc: #1283, #1296, #1302, #1424
- - Fix unicode/str confusion in IRC server service.
-
-
-0.3.0:
- - Jabber:
-
- - Fix digest authentication in Jabber
- - Add Jabber xmlstream module that contains the Jabber specific bits that
- got factored out of Twisted Xish's xmlstream, and make it suitable for
- implementing full XMPP support.
- - Xish:
- - Fixed serialization in _ListSerializer
- - Removed unneeded extra whitespace generated in serialization
- - Removed _Serializer in favour of _ListSerializer
- - Use unicode objects for representing serialized XML, instead of utf-8
- encoded str objects.
- - Properly catch XML parser errors
- - Rework and fix element stream test cases
- - Strip xmlstream from all Jabber specifics that moved to Twisted Words
- - Added exhaustive docstrings to xmlstream.
- - Words Service:
- - Complete rewrite
- - Not backwards compatible
-
-0.1.0:
- - Fix some miscellaneous bugs in OSCAR
- - Add QUIT notification for IRC
- - Fix message wrapping
- - Misc Jabber fixes
- - Add stringprep support for Jabber IDs
- This only works properly on 2.3.2 or higher
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/README
deleted file mode 100644
index 30d37afd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/topfiles/README
+++ /dev/null
@@ -1,5 +0,0 @@
-Twisted Words 12.2.0
-
-Twisted Words depends on Twisted Core and Twisted Web. The Twisted Web
-dependency is only necessary for MSN support. MSN support also requires HTTPS,
-and therefore pyOpenSSL (<http://launchpad.net/pyopenssl>).
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/__init__.py
deleted file mode 100755
index 1d2469fe..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- test-case-name: twisted.words.test -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-
-Twisted X-ish: XML-ish DOM and XPath-ish engine
-
-"""
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/domish.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/domish.py
deleted file mode 100755
index 3be7ed64..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/domish.py
+++ /dev/null
@@ -1,848 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_domish -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-DOM-like XML processing support.
-
-This module provides support for parsing XML into DOM-like object structures
-and serializing such structures to an XML string representation, optimized
-for use in streaming XML applications.
-"""
-
-import types
-
-from zope.interface import implements, Interface, Attribute
-
-def _splitPrefix(name):
- """ Internal method for splitting a prefixed Element name into its
- respective parts """
- ntok = name.split(":", 1)
- if len(ntok) == 2:
- return ntok
- else:
- return (None, ntok[0])
-
-# Global map of prefixes that always get injected
-# into the serializers prefix map (note, that doesn't
-# mean they're always _USED_)
-G_PREFIXES = { "http://www.w3.org/XML/1998/namespace":"xml" }
-
-class _ListSerializer:
- """ Internal class which serializes an Element tree into a buffer """
- def __init__(self, prefixes=None, prefixesInScope=None):
- self.writelist = []
- self.prefixes = {}
- if prefixes:
- self.prefixes.update(prefixes)
- self.prefixes.update(G_PREFIXES)
- self.prefixStack = [G_PREFIXES.values()] + (prefixesInScope or [])
- self.prefixCounter = 0
-
- def getValue(self):
- return u"".join(self.writelist)
-
- def getPrefix(self, uri):
- if uri not in self.prefixes:
- self.prefixes[uri] = "xn%d" % (self.prefixCounter)
- self.prefixCounter = self.prefixCounter + 1
- return self.prefixes[uri]
-
- def prefixInScope(self, prefix):
- stack = self.prefixStack
- for i in range(-1, (len(self.prefixStack)+1) * -1, -1):
- if prefix in stack[i]:
- return True
- return False
-
- def serialize(self, elem, closeElement=1, defaultUri=''):
- # Optimization shortcuts
- write = self.writelist.append
-
- # Shortcut, check to see if elem is actually a chunk o' serialized XML
- if isinstance(elem, SerializedXML):
- write(elem)
- return
-
- # Shortcut, check to see if elem is actually a string (aka Cdata)
- if isinstance(elem, types.StringTypes):
- write(escapeToXml(elem))
- return
-
- # Further optimizations
- name = elem.name
- uri = elem.uri
- defaultUri, currentDefaultUri = elem.defaultUri, defaultUri
-
- for p, u in elem.localPrefixes.iteritems():
- self.prefixes[u] = p
- self.prefixStack.append(elem.localPrefixes.keys())
-
- # Inherit the default namespace
- if defaultUri is None:
- defaultUri = currentDefaultUri
-
- if uri is None:
- uri = defaultUri
-
- prefix = None
- if uri != defaultUri or uri in self.prefixes:
- prefix = self.getPrefix(uri)
- inScope = self.prefixInScope(prefix)
-
- # Create the starttag
-
- if not prefix:
- write("<%s" % (name))
- else:
- write("<%s:%s" % (prefix, name))
-
- if not inScope:
- write(" xmlns:%s='%s'" % (prefix, uri))
- self.prefixStack[-1].append(prefix)
- inScope = True
-
- if defaultUri != currentDefaultUri and \
- (uri != defaultUri or not prefix or not inScope):
- write(" xmlns='%s'" % (defaultUri))
-
- for p, u in elem.localPrefixes.iteritems():
- write(" xmlns:%s='%s'" % (p, u))
-
- # Serialize attributes
- for k,v in elem.attributes.items():
- # If the attribute name is a tuple, it's a qualified attribute
- if isinstance(k, types.TupleType):
- attr_uri, attr_name = k
- attr_prefix = self.getPrefix(attr_uri)
-
- if not self.prefixInScope(attr_prefix):
- write(" xmlns:%s='%s'" % (attr_prefix, attr_uri))
- self.prefixStack[-1].append(attr_prefix)
-
- write(" %s:%s='%s'" % (attr_prefix, attr_name,
- escapeToXml(v, 1)))
- else:
- write((" %s='%s'" % ( k, escapeToXml(v, 1))))
-
- # Shortcut out if this is only going to return
- # the element (i.e. no children)
- if closeElement == 0:
- write(">")
- return
-
- # Serialize children
- if len(elem.children) > 0:
- write(">")
- for c in elem.children:
- self.serialize(c, defaultUri=defaultUri)
- # Add closing tag
- if not prefix:
- write("</%s>" % (name))
- else:
- write("</%s:%s>" % (prefix, name))
- else:
- write("/>")
-
- self.prefixStack.pop()
-
-
-SerializerClass = _ListSerializer
-
-def escapeToXml(text, isattrib = 0):
- """ Escape text to proper XML form, per section 2.3 in the XML specification.
-
- @type text: C{str}
- @param text: Text to escape
-
- @type isattrib: C{bool}
- @param isattrib: Triggers escaping of characters necessary for use as
- attribute values
- """
- text = text.replace("&", "&amp;")
- text = text.replace("<", "&lt;")
- text = text.replace(">", "&gt;")
- if isattrib == 1:
- text = text.replace("'", "&apos;")
- text = text.replace("\"", "&quot;")
- return text
-
-def unescapeFromXml(text):
- text = text.replace("&lt;", "<")
- text = text.replace("&gt;", ">")
- text = text.replace("&apos;", "'")
- text = text.replace("&quot;", "\"")
- text = text.replace("&amp;", "&")
- return text
-
-def generateOnlyInterface(list, int):
- """ Filters items in a list by class
- """
- for n in list:
- if int.providedBy(n):
- yield n
-
-def generateElementsQNamed(list, name, uri):
- """ Filters Element items in a list with matching name and URI. """
- for n in list:
- if IElement.providedBy(n) and n.name == name and n.uri == uri:
- yield n
-
-def generateElementsNamed(list, name):
- """ Filters Element items in a list with matching name, regardless of URI.
- """
- for n in list:
- if IElement.providedBy(n) and n.name == name:
- yield n
-
-
-class SerializedXML(unicode):
- """ Marker class for pre-serialized XML in the DOM. """
- pass
-
-
-class Namespace:
- """ Convenience object for tracking namespace declarations. """
- def __init__(self, uri):
- self._uri = uri
- def __getattr__(self, n):
- return (self._uri, n)
- def __getitem__(self, n):
- return (self._uri, n)
-
-class IElement(Interface):
- """
- Interface to XML element nodes.
-
- See L{Element} for a detailed example of its general use.
-
- Warning: this Interface is not yet complete!
- """
-
- uri = Attribute(""" Element's namespace URI """)
- name = Attribute(""" Element's local name """)
- defaultUri = Attribute(""" Default namespace URI of child elements """)
- attributes = Attribute(""" Dictionary of element attributes """)
- children = Attribute(""" List of child nodes """)
- parent = Attribute(""" Reference to element's parent element """)
- localPrefixes = Attribute(""" Dictionary of local prefixes """)
-
- def toXml(prefixes=None, closeElement=1, defaultUri='',
- prefixesInScope=None):
- """ Serializes object to a (partial) XML document
-
- @param prefixes: dictionary that maps namespace URIs to suggested
- prefix names.
- @type prefixes: L{dict}
- @param closeElement: flag that determines whether to include the
- closing tag of the element in the serialized
- string. A value of C{0} only generates the
- element's start tag. A value of C{1} yields a
- complete serialization.
- @type closeElement: C{int}
- @param defaultUri: Initial default namespace URI. This is most useful
- for partial rendering, where the logical parent
- element (of which the starttag was already
- serialized) declares a default namespace that should
- be inherited.
- @type defaultUri: C{str}
- @param prefixesInScope: list of prefixes that are assumed to be
- declared by ancestors.
- @type prefixesInScope: C{list}
- @return: (partial) serialized XML
- @rtype: C{unicode}
- """
-
- def addElement(name, defaultUri = None, content = None):
- """ Create an element and add as child.
-
- The new element is added to this element as a child, and will have
- this element as its parent.
-
- @param name: element name. This can be either a C{unicode} object that
- contains the local name, or a tuple of (uri, local_name)
- for a fully qualified name. In the former case,
- the namespace URI is inherited from this element.
- @type name: C{unicode} or C{tuple} of (C{unicode}, C{unicode})
- @param defaultUri: default namespace URI for child elements. If
- C{None}, this is inherited from this element.
- @type defaultUri: C{unicode}
- @param content: text contained by the new element.
- @type content: C{unicode}
- @return: the created element
- @rtype: object providing L{IElement}
- """
-
- def addChild(node):
- """ Adds a node as child of this element.
-
- The C{node} will be added to the list of childs of this element, and
- will have this element set as its parent when C{node} provides
- L{IElement}.
-
- @param node: the child node.
- @type node: C{unicode} or object implementing L{IElement}
- """
-
-class Element(object):
- """ Represents an XML element node.
-
- An Element contains a series of attributes (name/value pairs), content
- (character data), and other child Element objects. When building a document
- with markup (such as HTML or XML), use this object as the starting point.
-
- Element objects fully support XML Namespaces. The fully qualified name of
- the XML Element it represents is stored in the C{uri} and C{name}
- attributes, where C{uri} holds the namespace URI. There is also a default
- namespace, for child elements. This is stored in the C{defaultUri}
- attribute. Note that C{''} means the empty namespace.
-
- Serialization of Elements through C{toXml()} will use these attributes
- for generating proper serialized XML. When both C{uri} and C{defaultUri}
- are not None in the Element and all of its descendents, serialization
- proceeds as expected:
-
- >>> from twisted.words.xish import domish
- >>> root = domish.Element(('myns', 'root'))
- >>> root.addElement('child', content='test')
- <twisted.words.xish.domish.Element object at 0x83002ac>
- >>> root.toXml()
- u"<root xmlns='myns'><child>test</child></root>"
-
- For partial serialization, needed for streaming XML, a special value for
- namespace URIs can be used: C{None}.
-
- Using C{None} as the value for C{uri} means: this element is in whatever
- namespace inherited by the closest logical ancestor when the complete XML
- document has been serialized. The serialized start tag will have a
- non-prefixed name, and no xmlns declaration will be generated.
-
- Similarly, C{None} for C{defaultUri} means: the default namespace for my
- child elements is inherited from the logical ancestors of this element,
- when the complete XML document has been serialized.
-
- To illustrate, an example from a Jabber stream. Assume the start tag of the
- root element of the stream has already been serialized, along with several
- complete child elements, and sent off, looking like this::
-
- <stream:stream xmlns:stream='http://etherx.jabber.org/streams'
- xmlns='jabber:client' to='example.com'>
- ...
-
- Now suppose we want to send a complete element represented by an
- object C{message} created like:
-
- >>> message = domish.Element((None, 'message'))
- >>> message['to'] = 'user@example.com'
- >>> message.addElement('body', content='Hi!')
- <twisted.words.xish.domish.Element object at 0x8276e8c>
- >>> message.toXml()
- u"<message to='user@example.com'><body>Hi!</body></message>"
-
- As, you can see, this XML snippet has no xmlns declaration. When sent
- off, it inherits the C{jabber:client} namespace from the root element.
- Note that this renders the same as using C{''} instead of C{None}:
-
- >>> presence = domish.Element(('', 'presence'))
- >>> presence.toXml()
- u"<presence/>"
-
- However, if this object has a parent defined, the difference becomes
- clear:
-
- >>> child = message.addElement(('http://example.com/', 'envelope'))
- >>> child.addChild(presence)
- <twisted.words.xish.domish.Element object at 0x8276fac>
- >>> message.toXml()
- u"<message to='user@example.com'><body>Hi!</body><envelope xmlns='http://example.com/'><presence xmlns=''/></envelope></message>"
-
- As, you can see, the <presence/> element is now in the empty namespace, not
- in the default namespace of the parent or the streams'.
-
- @type uri: C{unicode} or None
- @ivar uri: URI of this Element's name
-
- @type name: C{unicode}
- @ivar name: Name of this Element
-
- @type defaultUri: C{unicode} or None
- @ivar defaultUri: URI this Element exists within
-
- @type children: C{list}
- @ivar children: List of child Elements and content
-
- @type parent: L{Element}
- @ivar parent: Reference to the parent Element, if any.
-
- @type attributes: L{dict}
- @ivar attributes: Dictionary of attributes associated with this Element.
-
- @type localPrefixes: L{dict}
- @ivar localPrefixes: Dictionary of namespace declarations on this
- element. The key is the prefix to bind the
- namespace uri to.
- """
-
- implements(IElement)
-
- _idCounter = 0
-
- def __init__(self, qname, defaultUri=None, attribs=None,
- localPrefixes=None):
- """
- @param qname: Tuple of (uri, name)
- @param defaultUri: The default URI of the element; defaults to the URI
- specified in C{qname}
- @param attribs: Dictionary of attributes
- @param localPrefixes: Dictionary of namespace declarations on this
- element. The key is the prefix to bind the
- namespace uri to.
- """
- self.localPrefixes = localPrefixes or {}
- self.uri, self.name = qname
- if defaultUri is None and \
- self.uri not in self.localPrefixes.itervalues():
- self.defaultUri = self.uri
- else:
- self.defaultUri = defaultUri
- self.attributes = attribs or {}
- self.children = []
- self.parent = None
-
- def __getattr__(self, key):
- # Check child list for first Element with a name matching the key
- for n in self.children:
- if IElement.providedBy(n) and n.name == key:
- return n
-
- # Tweak the behaviour so that it's more friendly about not
- # finding elements -- we need to document this somewhere :)
- if key.startswith('_'):
- raise AttributeError(key)
- else:
- return None
-
- def __getitem__(self, key):
- return self.attributes[self._dqa(key)]
-
- def __delitem__(self, key):
- del self.attributes[self._dqa(key)];
-
- def __setitem__(self, key, value):
- self.attributes[self._dqa(key)] = value
-
- def __str__(self):
- """ Retrieve the first CData (content) node
- """
- for n in self.children:
- if isinstance(n, types.StringTypes): return n
- return ""
-
- def _dqa(self, attr):
- """ Dequalify an attribute key as needed """
- if isinstance(attr, types.TupleType) and not attr[0]:
- return attr[1]
- else:
- return attr
-
- def getAttribute(self, attribname, default = None):
- """ Retrieve the value of attribname, if it exists """
- return self.attributes.get(attribname, default)
-
- def hasAttribute(self, attrib):
- """ Determine if the specified attribute exists """
- return self._dqa(attrib) in self.attributes
-
- def compareAttribute(self, attrib, value):
- """ Safely compare the value of an attribute against a provided value.
-
- C{None}-safe.
- """
- return self.attributes.get(self._dqa(attrib), None) == value
-
- def swapAttributeValues(self, left, right):
- """ Swap the values of two attribute. """
- d = self.attributes
- l = d[left]
- d[left] = d[right]
- d[right] = l
-
- def addChild(self, node):
- """ Add a child to this Element. """
- if IElement.providedBy(node):
- node.parent = self
- self.children.append(node)
- return self.children[-1]
-
- def addContent(self, text):
- """ Add some text data to this Element. """
- c = self.children
- if len(c) > 0 and isinstance(c[-1], types.StringTypes):
- c[-1] = c[-1] + text
- else:
- c.append(text)
- return c[-1]
-
- def addElement(self, name, defaultUri = None, content = None):
- result = None
- if isinstance(name, type(())):
- if defaultUri is None:
- defaultUri = name[0]
- self.children.append(Element(name, defaultUri))
- else:
- if defaultUri is None:
- defaultUri = self.defaultUri
- self.children.append(Element((defaultUri, name), defaultUri))
-
- result = self.children[-1]
- result.parent = self
-
- if content:
- result.children.append(content)
-
- return result
-
- def addRawXml(self, rawxmlstring):
- """ Add a pre-serialized chunk o' XML as a child of this Element. """
- self.children.append(SerializedXML(rawxmlstring))
-
- def addUniqueId(self):
- """ Add a unique (across a given Python session) id attribute to this
- Element.
- """
- self.attributes["id"] = "H_%d" % Element._idCounter
- Element._idCounter = Element._idCounter + 1
-
-
- def elements(self, uri=None, name=None):
- """
- Iterate across all children of this Element that are Elements.
-
- Returns a generator over the child elements. If both the C{uri} and
- C{name} parameters are set, the returned generator will only yield
- on elements matching the qualified name.
-
- @param uri: Optional element URI.
- @type uri: C{unicode}
- @param name: Optional element name.
- @type name: C{unicode}
- @return: Iterator that yields objects implementing L{IElement}.
- """
- if name is None:
- return generateOnlyInterface(self.children, IElement)
- else:
- return generateElementsQNamed(self.children, name, uri)
-
-
- def toXml(self, prefixes=None, closeElement=1, defaultUri='',
- prefixesInScope=None):
- """ Serialize this Element and all children to a string. """
- s = SerializerClass(prefixes=prefixes, prefixesInScope=prefixesInScope)
- s.serialize(self, closeElement=closeElement, defaultUri=defaultUri)
- return s.getValue()
-
- def firstChildElement(self):
- for c in self.children:
- if IElement.providedBy(c):
- return c
- return None
-
-
-class ParserError(Exception):
- """ Exception thrown when a parsing error occurs """
- pass
-
-def elementStream():
- """ Preferred method to construct an ElementStream
-
- Uses Expat-based stream if available, and falls back to Sux if necessary.
- """
- try:
- es = ExpatElementStream()
- return es
- except ImportError:
- if SuxElementStream is None:
- raise Exception("No parsers available :(")
- es = SuxElementStream()
- return es
-
-try:
- from twisted.web import sux
-except:
- SuxElementStream = None
-else:
- class SuxElementStream(sux.XMLParser):
- def __init__(self):
- self.connectionMade()
- self.DocumentStartEvent = None
- self.ElementEvent = None
- self.DocumentEndEvent = None
- self.currElem = None
- self.rootElem = None
- self.documentStarted = False
- self.defaultNsStack = []
- self.prefixStack = []
-
- def parse(self, buffer):
- try:
- self.dataReceived(buffer)
- except sux.ParseError, e:
- raise ParserError, str(e)
-
-
- def findUri(self, prefix):
- # Walk prefix stack backwards, looking for the uri
- # matching the specified prefix
- stack = self.prefixStack
- for i in range(-1, (len(self.prefixStack)+1) * -1, -1):
- if prefix in stack[i]:
- return stack[i][prefix]
- return None
-
- def gotTagStart(self, name, attributes):
- defaultUri = None
- localPrefixes = {}
- attribs = {}
- uri = None
-
- # Pass 1 - Identify namespace decls
- for k, v in attributes.items():
- if k.startswith("xmlns"):
- x, p = _splitPrefix(k)
- if (x is None): # I.e. default declaration
- defaultUri = v
- else:
- localPrefixes[p] = v
- del attributes[k]
-
- # Push namespace decls onto prefix stack
- self.prefixStack.append(localPrefixes)
-
- # Determine default namespace for this element; if there
- # is one
- if defaultUri is None:
- if len(self.defaultNsStack) > 0:
- defaultUri = self.defaultNsStack[-1]
- else:
- defaultUri = ''
-
- # Fix up name
- prefix, name = _splitPrefix(name)
- if prefix is None: # This element is in the default namespace
- uri = defaultUri
- else:
- # Find the URI for the prefix
- uri = self.findUri(prefix)
-
- # Pass 2 - Fix up and escape attributes
- for k, v in attributes.items():
- p, n = _splitPrefix(k)
- if p is None:
- attribs[n] = v
- else:
- attribs[(self.findUri(p)), n] = unescapeFromXml(v)
-
- # Construct the actual Element object
- e = Element((uri, name), defaultUri, attribs, localPrefixes)
-
- # Save current default namespace
- self.defaultNsStack.append(defaultUri)
-
- # Document already started
- if self.documentStarted:
- # Starting a new packet
- if self.currElem is None:
- self.currElem = e
- # Adding to existing element
- else:
- self.currElem = self.currElem.addChild(e)
- # New document
- else:
- self.rootElem = e
- self.documentStarted = True
- self.DocumentStartEvent(e)
-
- def gotText(self, data):
- if self.currElem != None:
- self.currElem.addContent(data)
-
- def gotCData(self, data):
- if self.currElem != None:
- self.currElem.addContent(data)
-
- def gotComment(self, data):
- # Ignore comments for the moment
- pass
-
- entities = { "amp" : "&",
- "lt" : "<",
- "gt" : ">",
- "apos": "'",
- "quot": "\"" }
-
- def gotEntityReference(self, entityRef):
- # If this is an entity we know about, add it as content
- # to the current element
- if entityRef in SuxElementStream.entities:
- self.currElem.addContent(SuxElementStream.entities[entityRef])
-
- def gotTagEnd(self, name):
- # Ensure the document hasn't already ended
- if self.rootElem is None:
- # XXX: Write more legible explanation
- raise ParserError, "Element closed after end of document."
-
- # Fix up name
- prefix, name = _splitPrefix(name)
- if prefix is None:
- uri = self.defaultNsStack[-1]
- else:
- uri = self.findUri(prefix)
-
- # End of document
- if self.currElem is None:
- # Ensure element name and uri matches
- if self.rootElem.name != name or self.rootElem.uri != uri:
- raise ParserError, "Mismatched root elements"
- self.DocumentEndEvent()
- self.rootElem = None
-
- # Other elements
- else:
- # Ensure the tag being closed matches the name of the current
- # element
- if self.currElem.name != name or self.currElem.uri != uri:
- # XXX: Write more legible explanation
- raise ParserError, "Malformed element close"
-
- # Pop prefix and default NS stack
- self.prefixStack.pop()
- self.defaultNsStack.pop()
-
- # Check for parent null parent of current elem;
- # that's the top of the stack
- if self.currElem.parent is None:
- self.currElem.parent = self.rootElem
- self.ElementEvent(self.currElem)
- self.currElem = None
-
- # Anything else is just some element wrapping up
- else:
- self.currElem = self.currElem.parent
-
-
-class ExpatElementStream:
- def __init__(self):
- import pyexpat
- self.DocumentStartEvent = None
- self.ElementEvent = None
- self.DocumentEndEvent = None
- self.error = pyexpat.error
- self.parser = pyexpat.ParserCreate("UTF-8", " ")
- self.parser.StartElementHandler = self._onStartElement
- self.parser.EndElementHandler = self._onEndElement
- self.parser.CharacterDataHandler = self._onCdata
- self.parser.StartNamespaceDeclHandler = self._onStartNamespace
- self.parser.EndNamespaceDeclHandler = self._onEndNamespace
- self.currElem = None
- self.defaultNsStack = ['']
- self.documentStarted = 0
- self.localPrefixes = {}
-
- def parse(self, buffer):
- try:
- self.parser.Parse(buffer)
- except self.error, e:
- raise ParserError, str(e)
-
- def _onStartElement(self, name, attrs):
- # Generate a qname tuple from the provided name. See
- # http://docs.python.org/library/pyexpat.html#xml.parsers.expat.ParserCreate
- # for an explanation of the formatting of name.
- qname = name.rsplit(" ", 1)
- if len(qname) == 1:
- qname = ('', name)
-
- # Process attributes
- for k, v in attrs.items():
- if " " in k:
- aqname = k.rsplit(" ", 1)
- attrs[(aqname[0], aqname[1])] = v
- del attrs[k]
-
- # Construct the new element
- e = Element(qname, self.defaultNsStack[-1], attrs, self.localPrefixes)
- self.localPrefixes = {}
-
- # Document already started
- if self.documentStarted == 1:
- if self.currElem != None:
- self.currElem.children.append(e)
- e.parent = self.currElem
- self.currElem = e
-
- # New document
- else:
- self.documentStarted = 1
- self.DocumentStartEvent(e)
-
- def _onEndElement(self, _):
- # Check for null current elem; end of doc
- if self.currElem is None:
- self.DocumentEndEvent()
-
- # Check for parent that is None; that's
- # the top of the stack
- elif self.currElem.parent is None:
- self.ElementEvent(self.currElem)
- self.currElem = None
-
- # Anything else is just some element in the current
- # packet wrapping up
- else:
- self.currElem = self.currElem.parent
-
- def _onCdata(self, data):
- if self.currElem != None:
- self.currElem.addContent(data)
-
- def _onStartNamespace(self, prefix, uri):
- # If this is the default namespace, put
- # it on the stack
- if prefix is None:
- self.defaultNsStack.append(uri)
- else:
- self.localPrefixes[prefix] = uri
-
- def _onEndNamespace(self, prefix):
- # Remove last element on the stack
- if prefix is None:
- self.defaultNsStack.pop()
-
-## class FileParser(ElementStream):
-## def __init__(self):
-## ElementStream.__init__(self)
-## self.DocumentStartEvent = self.docStart
-## self.ElementEvent = self.elem
-## self.DocumentEndEvent = self.docEnd
-## self.done = 0
-
-## def docStart(self, elem):
-## self.document = elem
-
-## def elem(self, elem):
-## self.document.addChild(elem)
-
-## def docEnd(self):
-## self.done = 1
-
-## def parse(self, filename):
-## for l in open(filename).readlines():
-## self.parser.Parse(l)
-## assert self.done == 1
-## return self.document
-
-## def parseFile(filename):
-## return FileParser().parse(filename)
-
-
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/utility.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/utility.py
deleted file mode 100755
index 5c54095f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/utility.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_xishutil -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Event Dispatching and Callback utilities.
-"""
-
-from twisted.python import log
-from twisted.words.xish import xpath
-
-class _MethodWrapper(object):
- """
- Internal class for tracking method calls.
- """
- def __init__(self, method, *args, **kwargs):
- self.method = method
- self.args = args
- self.kwargs = kwargs
-
-
- def __call__(self, *args, **kwargs):
- nargs = self.args + args
- nkwargs = self.kwargs.copy()
- nkwargs.update(kwargs)
- self.method(*nargs, **nkwargs)
-
-
-
-class CallbackList:
- """
- Container for callbacks.
-
- Event queries are linked to lists of callables. When a matching event
- occurs, these callables are called in sequence. One-time callbacks
- are removed from the list after the first time the event was triggered.
-
- Arguments to callbacks are split spread across two sets. The first set,
- callback specific, is passed to C{addCallback} and is used for all
- subsequent event triggers. The second set is passed to C{callback} and is
- event specific. Positional arguments in the second set come after the
- positional arguments of the first set. Keyword arguments in the second set
- override those in the first set.
-
- @ivar callbacks: The registered callbacks as mapping from the callable to a
- tuple of a wrapper for that callable that keeps the
- callback specific arguments and a boolean that signifies
- if it is to be called only once.
- @type callbacks: C{dict}
- """
-
- def __init__(self):
- self.callbacks = {}
-
-
- def addCallback(self, onetime, method, *args, **kwargs):
- """
- Add callback.
-
- The arguments passed are used as callback specific arguments.
-
- @param onetime: If C{True}, this callback is called at most once.
- @type onetime: C{bool}
- @param method: The callback callable to be added.
- @param args: Positional arguments to the callable.
- @type args: C{list}
- @param kwargs: Keyword arguments to the callable.
- @type kwargs: C{dict}
- """
-
- if not method in self.callbacks:
- self.callbacks[method] = (_MethodWrapper(method, *args, **kwargs),
- onetime)
-
-
- def removeCallback(self, method):
- """
- Remove callback.
-
- @param method: The callable to be removed.
- """
-
- if method in self.callbacks:
- del self.callbacks[method]
-
-
- def callback(self, *args, **kwargs):
- """
- Call all registered callbacks.
-
- The passed arguments are event specific and augment and override
- the callback specific arguments as described above.
-
- @note: Exceptions raised by callbacks are trapped and logged. They will
- not propagate up to make sure other callbacks will still be
- called, and the event dispatching always succeeds.
-
- @param args: Positional arguments to the callable.
- @type args: C{list}
- @param kwargs: Keyword arguments to the callable.
- @type kwargs: C{dict}
- """
-
- for key, (methodwrapper, onetime) in self.callbacks.items():
- try:
- methodwrapper(*args, **kwargs)
- except:
- log.err()
-
- if onetime:
- del self.callbacks[key]
-
-
- def isEmpty(self):
- """
- Return if list of registered callbacks is empty.
-
- @rtype: C{bool}
- """
-
- return len(self.callbacks) == 0
-
-
-
-class EventDispatcher:
- """
- Event dispatching service.
-
- The C{EventDispatcher} allows observers to be registered for certain events
- that are dispatched. There are two types of events: XPath events and Named
- events.
-
- Every dispatch is triggered by calling L{dispatch} with a data object and,
- for named events, the name of the event.
-
- When an XPath type event is dispatched, the associated object is assumed to
- be an L{Element<twisted.words.xish.domish.Element>} instance, which is
- matched against all registered XPath queries. For every match, the
- respective observer will be called with the data object.
-
- A named event will simply call each registered observer for that particular
- event name, with the data object. Unlike XPath type events, the data object
- is not restricted to L{Element<twisted.words.xish.domish.Element>}, but can
- be anything.
-
- When registering observers, the event that is to be observed is specified
- using an L{xpath.XPathQuery} instance or a string. In the latter case, the
- string can also contain the string representation of an XPath expression.
- To distinguish these from named events, each named event should start with
- a special prefix that is stored in C{self.prefix}. It defaults to
- C{//event/}.
-
- Observers registered using L{addObserver} are persistent: after the
- observer has been triggered by a dispatch, it remains registered for a
- possible next dispatch. If instead L{addOnetimeObserver} was used to
- observe an event, the observer is removed from the list of observers after
- the first observed event.
-
- Observers can also be prioritized, by providing an optional C{priority}
- parameter to the L{addObserver} and L{addOnetimeObserver} methods. Higher
- priority observers are then called before lower priority observers.
-
- Finally, observers can be unregistered by using L{removeObserver}.
- """
-
- def __init__(self, eventprefix="//event/"):
- self.prefix = eventprefix
- self._eventObservers = {}
- self._xpathObservers = {}
- self._dispatchDepth = 0 # Flag indicating levels of dispatching
- # in progress
- self._updateQueue = [] # Queued updates for observer ops
-
-
- def _getEventAndObservers(self, event):
- if isinstance(event, xpath.XPathQuery):
- # Treat as xpath
- observers = self._xpathObservers
- else:
- if self.prefix == event[:len(self.prefix)]:
- # Treat as event
- observers = self._eventObservers
- else:
- # Treat as xpath
- event = xpath.internQuery(event)
- observers = self._xpathObservers
-
- return event, observers
-
-
- def addOnetimeObserver(self, event, observerfn, priority=0, *args, **kwargs):
- """
- Register a one-time observer for an event.
-
- Like L{addObserver}, but is only triggered at most once. See there
- for a description of the parameters.
- """
- self._addObserver(True, event, observerfn, priority, *args, **kwargs)
-
-
- def addObserver(self, event, observerfn, priority=0, *args, **kwargs):
- """
- Register an observer for an event.
-
- Each observer will be registered with a certain priority. Higher
- priority observers get called before lower priority observers.
-
- @param event: Name or XPath query for the event to be monitored.
- @type event: C{str} or L{xpath.XPathQuery}.
- @param observerfn: Function to be called when the specified event
- has been triggered. This callable takes
- one parameter: the data object that triggered
- the event. When specified, the C{*args} and
- C{**kwargs} parameters to addObserver are being used
- as additional parameters to the registered observer
- callable.
- @param priority: (Optional) priority of this observer in relation to
- other observer that match the same event. Defaults to
- C{0}.
- @type priority: C{int}
- """
- self._addObserver(False, event, observerfn, priority, *args, **kwargs)
-
-
- def _addObserver(self, onetime, event, observerfn, priority, *args, **kwargs):
- # If this is happening in the middle of the dispatch, queue
- # it up for processing after the dispatch completes
- if self._dispatchDepth > 0:
- self._updateQueue.append(lambda:self._addObserver(onetime, event, observerfn, priority, *args, **kwargs))
- return
-
- event, observers = self._getEventAndObservers(event)
-
- if priority not in observers:
- cbl = CallbackList()
- observers[priority] = {event: cbl}
- else:
- priorityObservers = observers[priority]
- if event not in priorityObservers:
- cbl = CallbackList()
- observers[priority][event] = cbl
- else:
- cbl = priorityObservers[event]
-
- cbl.addCallback(onetime, observerfn, *args, **kwargs)
-
-
- def removeObserver(self, event, observerfn):
- """
- Remove callable as observer for an event.
-
- The observer callable is removed for all priority levels for the
- specified event.
-
- @param event: Event for which the observer callable was registered.
- @type event: C{str} or L{xpath.XPathQuery}
- @param observerfn: Observer callable to be unregistered.
- """
-
- # If this is happening in the middle of the dispatch, queue
- # it up for processing after the dispatch completes
- if self._dispatchDepth > 0:
- self._updateQueue.append(lambda:self.removeObserver(event, observerfn))
- return
-
- event, observers = self._getEventAndObservers(event)
-
- emptyLists = []
- for priority, priorityObservers in observers.iteritems():
- for query, callbacklist in priorityObservers.iteritems():
- if event == query:
- callbacklist.removeCallback(observerfn)
- if callbacklist.isEmpty():
- emptyLists.append((priority, query))
-
- for priority, query in emptyLists:
- del observers[priority][query]
-
-
- def dispatch(self, obj, event=None):
- """
- Dispatch an event.
-
- When C{event} is C{None}, an XPath type event is triggered, and
- C{obj} is assumed to be an instance of
- L{Element<twisted.words.xish.domish.Element>}. Otherwise, C{event}
- holds the name of the named event being triggered. In the latter case,
- C{obj} can be anything.
-
- @param obj: The object to be dispatched.
- @param event: Optional event name.
- @type event: C{str}
- """
-
- foundTarget = False
-
- self._dispatchDepth += 1
-
- if event != None:
- # Named event
- observers = self._eventObservers
- match = lambda query, obj: query == event
- else:
- # XPath event
- observers = self._xpathObservers
- match = lambda query, obj: query.matches(obj)
-
- priorities = observers.keys()
- priorities.sort()
- priorities.reverse()
-
- emptyLists = []
- for priority in priorities:
- for query, callbacklist in observers[priority].iteritems():
- if match(query, obj):
- callbacklist.callback(obj)
- foundTarget = True
- if callbacklist.isEmpty():
- emptyLists.append((priority, query))
-
- for priority, query in emptyLists:
- del observers[priority][query]
-
- self._dispatchDepth -= 1
-
- # If this is a dispatch within a dispatch, don't
- # do anything with the updateQueue -- it needs to
- # wait until we've back all the way out of the stack
- if self._dispatchDepth == 0:
- # Deal with pending update operations
- for f in self._updateQueue:
- f()
- self._updateQueue = []
-
- return foundTarget
-
-
-
-class XmlPipe(object):
- """
- XML stream pipe.
-
- Connects two objects that communicate stanzas through an XML stream like
- interface. Each of the ends of the pipe (sink and source) can be used to
- send XML stanzas to the other side, or add observers to process XML stanzas
- that were sent from the other side.
-
- XML pipes are usually used in place of regular XML streams that are
- transported over TCP. This is the reason for the use of the names source
- and sink for both ends of the pipe. The source side corresponds with the
- entity that initiated the TCP connection, whereas the sink corresponds with
- the entity that accepts that connection. In this object, though, the source
- and sink are treated equally.
-
- Unlike Jabber
- L{XmlStream<twisted.words.protocols.jabber.xmlstream.XmlStream>}s, the sink
- and source objects are assumed to represent an eternal connected and
- initialized XML stream. As such, events corresponding to connection,
- disconnection, initialization and stream errors are not dispatched or
- processed.
-
- @since: 8.2
- @ivar source: Source XML stream.
- @ivar sink: Sink XML stream.
- """
-
- def __init__(self):
- self.source = EventDispatcher()
- self.sink = EventDispatcher()
- self.source.send = lambda obj: self.sink.dispatch(obj)
- self.sink.send = lambda obj: self.source.dispatch(obj)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xmlstream.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xmlstream.py
deleted file mode 100755
index 3018a0e4..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xmlstream.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_xmlstream -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-XML Stream processing.
-
-An XML Stream is defined as a connection over which two XML documents are
-exchanged during the lifetime of the connection, one for each direction. The
-unit of interaction is a direct child element of the root element (stanza).
-
-The most prominent use of XML Streams is Jabber, but this module is generically
-usable. See Twisted Words for Jabber specific protocol support.
-
-Maintainer: Ralph Meijer
-"""
-
-from twisted.python import failure
-from twisted.internet import protocol
-from twisted.words.xish import domish, utility
-
-STREAM_CONNECTED_EVENT = intern("//event/stream/connected")
-STREAM_START_EVENT = intern("//event/stream/start")
-STREAM_END_EVENT = intern("//event/stream/end")
-STREAM_ERROR_EVENT = intern("//event/stream/error")
-
-class XmlStream(protocol.Protocol, utility.EventDispatcher):
- """ Generic Streaming XML protocol handler.
-
- This protocol handler will parse incoming data as XML and dispatch events
- accordingly. Incoming stanzas can be handled by registering observers using
- XPath-like expressions that are matched against each stanza. See
- L{utility.EventDispatcher} for details.
- """
- def __init__(self):
- utility.EventDispatcher.__init__(self)
- self.stream = None
- self.rawDataOutFn = None
- self.rawDataInFn = None
-
- def _initializeStream(self):
- """ Sets up XML Parser. """
- self.stream = domish.elementStream()
- self.stream.DocumentStartEvent = self.onDocumentStart
- self.stream.ElementEvent = self.onElement
- self.stream.DocumentEndEvent = self.onDocumentEnd
-
- ### --------------------------------------------------------------
- ###
- ### Protocol events
- ###
- ### --------------------------------------------------------------
-
- def connectionMade(self):
- """ Called when a connection is made.
-
- Sets up the XML parser and dispatches the L{STREAM_CONNECTED_EVENT}
- event indicating the connection has been established.
- """
- self._initializeStream()
- self.dispatch(self, STREAM_CONNECTED_EVENT)
-
- def dataReceived(self, data):
- """ Called whenever data is received.
-
- Passes the data to the XML parser. This can result in calls to the
- DOM handlers. If a parse error occurs, the L{STREAM_ERROR_EVENT} event
- is called to allow for cleanup actions, followed by dropping the
- connection.
- """
- try:
- if self.rawDataInFn:
- self.rawDataInFn(data)
- self.stream.parse(data)
- except domish.ParserError:
- self.dispatch(failure.Failure(), STREAM_ERROR_EVENT)
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- """ Called when the connection is shut down.
-
- Dispatches the L{STREAM_END_EVENT}.
- """
- self.dispatch(reason, STREAM_END_EVENT)
- self.stream = None
-
- ### --------------------------------------------------------------
- ###
- ### DOM events
- ###
- ### --------------------------------------------------------------
-
- def onDocumentStart(self, rootElement):
- """ Called whenever the start tag of a root element has been received.
-
- Dispatches the L{STREAM_START_EVENT}.
- """
- self.dispatch(self, STREAM_START_EVENT)
-
- def onElement(self, element):
- """ Called whenever a direct child element of the root element has
- been received.
-
- Dispatches the received element.
- """
- self.dispatch(element)
-
- def onDocumentEnd(self):
- """ Called whenever the end tag of the root element has been received.
-
- Closes the connection. This causes C{connectionLost} being called.
- """
- self.transport.loseConnection()
-
- def setDispatchFn(self, fn):
- """ Set another function to handle elements. """
- self.stream.ElementEvent = fn
-
- def resetDispatchFn(self):
- """ Set the default function (C{onElement}) to handle elements. """
- self.stream.ElementEvent = self.onElement
-
- def send(self, obj):
- """ Send data over the stream.
-
- Sends the given C{obj} over the connection. C{obj} may be instances of
- L{domish.Element}, C{unicode} and C{str}. The first two will be
- properly serialized and/or encoded. C{str} objects must be in UTF-8
- encoding.
-
- Note: because it is easy to make mistakes in maintaining a properly
- encoded C{str} object, it is advised to use C{unicode} objects
- everywhere when dealing with XML Streams.
-
- @param obj: Object to be sent over the stream.
- @type obj: L{domish.Element}, L{domish} or C{str}
-
- """
- if domish.IElement.providedBy(obj):
- obj = obj.toXml()
-
- if isinstance(obj, unicode):
- obj = obj.encode('utf-8')
-
- if self.rawDataOutFn:
- self.rawDataOutFn(obj)
-
- self.transport.write(obj)
-
-
-
-class BootstrapMixin(object):
- """
- XmlStream factory mixin to install bootstrap event observers.
-
- This mixin is for factories providing
- L{IProtocolFactory<twisted.internet.interfaces.IProtocolFactory>} to make
- sure bootstrap event observers are set up on protocols, before incoming
- data is processed. Such protocols typically derive from
- L{utility.EventDispatcher}, like L{XmlStream}.
-
- You can set up bootstrap event observers using C{addBootstrap}. The
- C{event} and C{fn} parameters correspond with the C{event} and
- C{observerfn} arguments to L{utility.EventDispatcher.addObserver}.
-
- @since: 8.2.
- @ivar bootstraps: The list of registered bootstrap event observers.
- @type bootstrap: C{list}
- """
-
- def __init__(self):
- self.bootstraps = []
-
-
- def installBootstraps(self, dispatcher):
- """
- Install registered bootstrap observers.
-
- @param dispatcher: Event dispatcher to add the observers to.
- @type dispatcher: L{utility.EventDispatcher}
- """
- for event, fn in self.bootstraps:
- dispatcher.addObserver(event, fn)
-
-
- def addBootstrap(self, event, fn):
- """
- Add a bootstrap event handler.
-
- @param event: The event to register an observer for.
- @type event: C{str} or L{xpath.XPathQuery}
- @param fn: The observer callable to be registered.
- """
- self.bootstraps.append((event, fn))
-
-
- def removeBootstrap(self, event, fn):
- """
- Remove a bootstrap event handler.
-
- @param event: The event the observer is registered for.
- @type event: C{str} or L{xpath.XPathQuery}
- @param fn: The registered observer callable.
- """
- self.bootstraps.remove((event, fn))
-
-
-
-class XmlStreamFactoryMixin(BootstrapMixin):
- """
- XmlStream factory mixin that takes care of event handlers.
-
- All positional and keyword arguments passed to create this factory are
- passed on as-is to the protocol.
-
- @ivar args: Positional arguments passed to the protocol upon instantiation.
- @type args: C{tuple}.
- @ivar kwargs: Keyword arguments passed to the protocol upon instantiation.
- @type kwargs: C{dict}.
- """
-
- def __init__(self, *args, **kwargs):
- BootstrapMixin.__init__(self)
- self.args = args
- self.kwargs = kwargs
-
-
- def buildProtocol(self, addr):
- """
- Create an instance of XmlStream.
-
- The returned instance will have bootstrap event observers registered
- and will proceed to handle input on an incoming connection.
- """
- xs = self.protocol(*self.args, **self.kwargs)
- xs.factory = self
- self.installBootstraps(xs)
- return xs
-
-
-
-class XmlStreamFactory(XmlStreamFactoryMixin,
- protocol.ReconnectingClientFactory):
- """
- Factory for XmlStream protocol objects as a reconnection client.
- """
-
- protocol = XmlStream
-
- def buildProtocol(self, addr):
- """
- Create a protocol instance.
-
- Overrides L{XmlStreamFactoryMixin.buildProtocol} to work with
- a L{ReconnectingClientFactory}. As this is called upon having an
- connection established, we are resetting the delay for reconnection
- attempts when the connection is lost again.
- """
- self.resetDelay()
- return XmlStreamFactoryMixin.buildProtocol(self, addr)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpath.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpath.py
deleted file mode 100755
index bf5b5299..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpath.py
+++ /dev/null
@@ -1,333 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_xpath -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-XPath query support.
-
-This module provides L{XPathQuery} to match
-L{domish.Element<twisted.words.xish.domish.Element>} instances against
-XPath-like expressions.
-"""
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-class LiteralValue(str):
- def value(self, elem):
- return self
-
-
-class IndexValue:
- def __init__(self, index):
- self.index = int(index) - 1
-
- def value(self, elem):
- return elem.children[self.index]
-
-
-class AttribValue:
- def __init__(self, attribname):
- self.attribname = attribname
- if self.attribname == "xmlns":
- self.value = self.value_ns
-
- def value_ns(self, elem):
- return elem.uri
-
- def value(self, elem):
- if self.attribname in elem.attributes:
- return elem.attributes[self.attribname]
- else:
- return None
-
-
-class CompareValue:
- def __init__(self, lhs, op, rhs):
- self.lhs = lhs
- self.rhs = rhs
- if op == "=":
- self.value = self._compareEqual
- else:
- self.value = self._compareNotEqual
-
- def _compareEqual(self, elem):
- return self.lhs.value(elem) == self.rhs.value(elem)
-
- def _compareNotEqual(self, elem):
- return self.lhs.value(elem) != self.rhs.value(elem)
-
-
-class BooleanValue:
- """
- Provide boolean XPath expression operators.
-
- @ivar lhs: Left hand side expression of the operator.
- @ivar op: The operator. One of C{'and'}, C{'or'}.
- @ivar rhs: Right hand side expression of the operator.
- @ivar value: Reference to the method that will calculate the value of
- this expression given an element.
- """
- def __init__(self, lhs, op, rhs):
- self.lhs = lhs
- self.rhs = rhs
- if op == "and":
- self.value = self._booleanAnd
- else:
- self.value = self._booleanOr
-
- def _booleanAnd(self, elem):
- """
- Calculate boolean and of the given expressions given an element.
-
- @param elem: The element to calculate the value of the expression from.
- """
- return self.lhs.value(elem) and self.rhs.value(elem)
-
- def _booleanOr(self, elem):
- """
- Calculate boolean or of the given expressions given an element.
-
- @param elem: The element to calculate the value of the expression from.
- """
- return self.lhs.value(elem) or self.rhs.value(elem)
-
-
-def Function(fname):
- """
- Internal method which selects the function object
- """
- klassname = "_%s_Function" % fname
- c = globals()[klassname]()
- return c
-
-
-class _not_Function:
- def __init__(self):
- self.baseValue = None
-
- def setParams(self, baseValue):
- self.baseValue = baseValue
-
- def value(self, elem):
- return not self.baseValue.value(elem)
-
-
-class _text_Function:
- def setParams(self):
- pass
-
- def value(self, elem):
- return str(elem)
-
-
-class _Location:
- def __init__(self):
- self.predicates = []
- self.elementName = None
- self.childLocation = None
-
- def matchesPredicates(self, elem):
- if self.elementName != None and self.elementName != elem.name:
- return 0
-
- for p in self.predicates:
- if not p.value(elem):
- return 0
-
- return 1
-
- def matches(self, elem):
- if not self.matchesPredicates(elem):
- return 0
-
- if self.childLocation != None:
- for c in elem.elements():
- if self.childLocation.matches(c):
- return 1
- else:
- return 1
-
- return 0
-
- def queryForString(self, elem, resultbuf):
- if not self.matchesPredicates(elem):
- return
-
- if self.childLocation != None:
- for c in elem.elements():
- self.childLocation.queryForString(c, resultbuf)
- else:
- resultbuf.write(str(elem))
-
- def queryForNodes(self, elem, resultlist):
- if not self.matchesPredicates(elem):
- return
-
- if self.childLocation != None:
- for c in elem.elements():
- self.childLocation.queryForNodes(c, resultlist)
- else:
- resultlist.append(elem)
-
- def queryForStringList(self, elem, resultlist):
- if not self.matchesPredicates(elem):
- return
-
- if self.childLocation != None:
- for c in elem.elements():
- self.childLocation.queryForStringList(c, resultlist)
- else:
- for c in elem.children:
- if isinstance(c, (str, unicode)):
- resultlist.append(c)
-
-
-class _AnyLocation:
- def __init__(self):
- self.predicates = []
- self.elementName = None
- self.childLocation = None
-
- def matchesPredicates(self, elem):
- for p in self.predicates:
- if not p.value(elem):
- return 0
- return 1
-
- def listParents(self, elem, parentlist):
- if elem.parent != None:
- self.listParents(elem.parent, parentlist)
- parentlist.append(elem.name)
-
- def isRootMatch(self, elem):
- if (self.elementName == None or self.elementName == elem.name) and \
- self.matchesPredicates(elem):
- if self.childLocation != None:
- for c in elem.elements():
- if self.childLocation.matches(c):
- return True
- else:
- return True
- return False
-
- def findFirstRootMatch(self, elem):
- if (self.elementName == None or self.elementName == elem.name) and \
- self.matchesPredicates(elem):
- # Thus far, the name matches and the predicates match,
- # now check into the children and find the first one
- # that matches the rest of the structure
- # the rest of the structure
- if self.childLocation != None:
- for c in elem.elements():
- if self.childLocation.matches(c):
- return c
- return None
- else:
- # No children locations; this is a match!
- return elem
- else:
- # Ok, predicates or name didn't match, so we need to start
- # down each child and treat it as the root and try
- # again
- for c in elem.elements():
- if self.matches(c):
- return c
- # No children matched...
- return None
-
- def matches(self, elem):
- if self.isRootMatch(elem):
- return True
- else:
- # Ok, initial element isn't an exact match, walk
- # down each child and treat it as the root and try
- # again
- for c in elem.elements():
- if self.matches(c):
- return True
- # No children matched...
- return False
-
- def queryForString(self, elem, resultbuf):
- raise NotImplementedError(
- "queryForString is not implemented for any location")
-
- def queryForNodes(self, elem, resultlist):
- # First check to see if _this_ element is a root
- if self.isRootMatch(elem):
- resultlist.append(elem)
-
- # Now check each child
- for c in elem.elements():
- self.queryForNodes(c, resultlist)
-
-
- def queryForStringList(self, elem, resultlist):
- if self.isRootMatch(elem):
- for c in elem.children:
- if isinstance(c, (str, unicode)):
- resultlist.append(c)
- for c in elem.elements():
- self.queryForStringList(c, resultlist)
-
-
-class XPathQuery:
- def __init__(self, queryStr):
- self.queryStr = queryStr
- from twisted.words.xish.xpathparser import parse
- self.baseLocation = parse('XPATH', queryStr)
-
- def __hash__(self):
- return self.queryStr.__hash__()
-
- def matches(self, elem):
- return self.baseLocation.matches(elem)
-
- def queryForString(self, elem):
- result = StringIO.StringIO()
- self.baseLocation.queryForString(elem, result)
- return result.getvalue()
-
- def queryForNodes(self, elem):
- result = []
- self.baseLocation.queryForNodes(elem, result)
- if len(result) == 0:
- return None
- else:
- return result
-
- def queryForStringList(self, elem):
- result = []
- self.baseLocation.queryForStringList(elem, result)
- if len(result) == 0:
- return None
- else:
- return result
-
-
-__internedQueries = {}
-
-def internQuery(queryString):
- if queryString not in __internedQueries:
- __internedQueries[queryString] = XPathQuery(queryString)
- return __internedQueries[queryString]
-
-
-def matches(xpathstr, elem):
- return internQuery(xpathstr).matches(elem)
-
-
-def queryForStringList(xpathstr, elem):
- return internQuery(xpathstr).queryForStringList(elem)
-
-
-def queryForString(xpathstr, elem):
- return internQuery(xpathstr).queryForString(elem)
-
-
-def queryForNodes(xpathstr, elem):
- return internQuery(xpathstr).queryForNodes(elem)
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.g b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.g
deleted file mode 100644
index 02c67c90..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.g
+++ /dev/null
@@ -1,375 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# DO NOT EDIT xpathparser.py!
-#
-# It is generated from xpathparser.g using Yapps. Make needed changes there.
-# This also means that the generated Python may not conform to Twisted's coding
-# standards.
-
-# HOWTO Generate me:
-#
-# 1.) Grab a copy of yapps2, version 2.1.1:
-# http://theory.stanford.edu/~amitp/Yapps/
-#
-# Note: Do NOT use the package in debian/ubuntu as it has incompatible
-# modifications.
-#
-# 2.) Generate the grammar:
-#
-# yapps2 xpathparser.g xpathparser.py.proto
-#
-# 3.) Edit the output to depend on the embedded runtime, not yappsrt.
-#
-# sed -e '/^import yapps/d' -e '/^[^#]/s/yappsrt\.//g' \
-# xpathparser.py.proto > xpathparser.py
-
-"""
-XPath Parser.
-
-Besides the parser code produced by Yapps, this module also defines the
-parse-time exception classes, a scanner class, a base class for parsers
-produced by Yapps, and a context class that keeps track of the parse stack.
-These have been copied from the Yapps runtime.
-"""
-
-import sys, re
-
-class SyntaxError(Exception):
- """When we run into an unexpected token, this is the exception to use"""
- def __init__(self, charpos=-1, msg="Bad Token", context=None):
- Exception.__init__(self)
- self.charpos = charpos
- self.msg = msg
- self.context = context
-
- def __str__(self):
- if self.charpos < 0: return 'SyntaxError'
- else: return 'SyntaxError@char%s(%s)' % (repr(self.charpos), self.msg)
-
-class NoMoreTokens(Exception):
- """Another exception object, for when we run out of tokens"""
- pass
-
-class Scanner:
- """Yapps scanner.
-
- The Yapps scanner can work in context sensitive or context
- insensitive modes. The token(i) method is used to retrieve the
- i-th token. It takes a restrict set that limits the set of tokens
- it is allowed to return. In context sensitive mode, this restrict
- set guides the scanner. In context insensitive mode, there is no
- restriction (the set is always the full set of tokens).
-
- """
-
- def __init__(self, patterns, ignore, input):
- """Initialize the scanner.
-
- @param patterns: [(terminal, uncompiled regex), ...] or C{None}
- @param ignore: [terminal,...]
- @param input: string
-
- If patterns is C{None}, we assume that the subclass has defined
- C{self.patterns} : [(terminal, compiled regex), ...]. Note that the
- patterns parameter expects uncompiled regexes, whereas the
- C{self.patterns} field expects compiled regexes.
- """
- self.tokens = [] # [(begin char pos, end char pos, token name, matched text), ...]
- self.restrictions = []
- self.input = input
- self.pos = 0
- self.ignore = ignore
- self.first_line_number = 1
-
- if patterns is not None:
- # Compile the regex strings into regex objects
- self.patterns = []
- for terminal, regex in patterns:
- self.patterns.append( (terminal, re.compile(regex)) )
-
- def get_token_pos(self):
- """Get the current token position in the input text."""
- return len(self.tokens)
-
- def get_char_pos(self):
- """Get the current char position in the input text."""
- return self.pos
-
- def get_prev_char_pos(self, i=None):
- """Get the previous position (one token back) in the input text."""
- if self.pos == 0: return 0
- if i is None: i = -1
- return self.tokens[i][0]
-
- def get_line_number(self):
- """Get the line number of the current position in the input text."""
- # TODO: make this work at any token/char position
- return self.first_line_number + self.get_input_scanned().count('\n')
-
- def get_column_number(self):
- """Get the column number of the current position in the input text."""
- s = self.get_input_scanned()
- i = s.rfind('\n') # may be -1, but that's okay in this case
- return len(s) - (i+1)
-
- def get_input_scanned(self):
- """Get the portion of the input that has been tokenized."""
- return self.input[:self.pos]
-
- def get_input_unscanned(self):
- """Get the portion of the input that has not yet been tokenized."""
- return self.input[self.pos:]
-
- def token(self, i, restrict=None):
- """Get the i'th token in the input.
-
- If C{i} is one past the end, then scan for another token.
-
- @param i: token index
-
- @param restrict: [token, ...] or C{None}; if restrict is
- C{None}, then any token is allowed. You may call
- token(i) more than once. However, the restrict set
- may never be larger than what was passed in on the
- first call to token(i).
- """
- if i == len(self.tokens):
- self.scan(restrict)
- if i < len(self.tokens):
- # Make sure the restriction is more restricted. This
- # invariant is needed to avoid ruining tokenization at
- # position i+1 and higher.
- if restrict and self.restrictions[i]:
- for r in restrict:
- if r not in self.restrictions[i]:
- raise NotImplementedError("Unimplemented: restriction set changed")
- return self.tokens[i]
- raise NoMoreTokens()
-
- def __repr__(self):
- """Print the last 10 tokens that have been scanned in"""
- output = ''
- for t in self.tokens[-10:]:
- output = '%s\n (@%s) %s = %s' % (output,t[0],t[2],repr(t[3]))
- return output
-
- def scan(self, restrict):
- """Should scan another token and add it to the list, self.tokens,
- and add the restriction to self.restrictions"""
- # Keep looking for a token, ignoring any in self.ignore
- while 1:
- # Search the patterns for the longest match, with earlier
- # tokens in the list having preference
- best_match = -1
- best_pat = '(error)'
- for p, regexp in self.patterns:
- # First check to see if we're ignoring this token
- if restrict and p not in restrict and p not in self.ignore:
- continue
- m = regexp.match(self.input, self.pos)
- if m and len(m.group(0)) > best_match:
- # We got a match that's better than the previous one
- best_pat = p
- best_match = len(m.group(0))
-
- # If we didn't find anything, raise an error
- if best_pat == '(error)' and best_match < 0:
- msg = 'Bad Token'
- if restrict:
- msg = 'Trying to find one of '+', '.join(restrict)
- raise SyntaxError(self.pos, msg)
-
- # If we found something that isn't to be ignored, return it
- if best_pat not in self.ignore:
- # Create a token with this data
- token = (self.pos, self.pos+best_match, best_pat,
- self.input[self.pos:self.pos+best_match])
- self.pos = self.pos + best_match
- # Only add this token if it's not in the list
- # (to prevent looping)
- if not self.tokens or token != self.tokens[-1]:
- self.tokens.append(token)
- self.restrictions.append(restrict)
- return
- else:
- # This token should be ignored ..
- self.pos = self.pos + best_match
-
-class Parser:
- """Base class for Yapps-generated parsers.
-
- """
-
- def __init__(self, scanner):
- self._scanner = scanner
- self._pos = 0
-
- def _peek(self, *types):
- """Returns the token type for lookahead; if there are any args
- then the list of args is the set of token types to allow"""
- tok = self._scanner.token(self._pos, types)
- return tok[2]
-
- def _scan(self, type):
- """Returns the matched text, and moves to the next token"""
- tok = self._scanner.token(self._pos, [type])
- if tok[2] != type:
- raise SyntaxError(tok[0], 'Trying to find '+type+' :'+ ' ,'.join(self._scanner.restrictions[self._pos]))
- self._pos = 1 + self._pos
- return tok[3]
-
-class Context:
- """Class to represent the parser's call stack.
-
- Every rule creates a Context that links to its parent rule. The
- contexts can be used for debugging.
-
- """
-
- def __init__(self, parent, scanner, tokenpos, rule, args=()):
- """Create a new context.
-
- @param parent: Context object or C{None}
- @param scanner: Scanner object
- @param tokenpos: scanner token position
- @type tokenpos: C{int}
- @param rule: name of the rule
- @type rule: C{str}
- @param args: tuple listing parameters to the rule
-
- """
- self.parent = parent
- self.scanner = scanner
- self.tokenpos = tokenpos
- self.rule = rule
- self.args = args
-
- def __str__(self):
- output = ''
- if self.parent: output = str(self.parent) + ' > '
- output += self.rule
- return output
-
-def print_line_with_pointer(text, p):
- """Print the line of 'text' that includes position 'p',
- along with a second line with a single caret (^) at position p"""
-
- # TODO: separate out the logic for determining the line/character
- # location from the logic for determining how to display an
- # 80-column line to stderr.
-
- # Now try printing part of the line
- text = text[max(p-80, 0):p+80]
- p = p - max(p-80, 0)
-
- # Strip to the left
- i = text[:p].rfind('\n')
- j = text[:p].rfind('\r')
- if i < 0 or (0 <= j < i): i = j
- if 0 <= i < p:
- p = p - i - 1
- text = text[i+1:]
-
- # Strip to the right
- i = text.find('\n', p)
- j = text.find('\r', p)
- if i < 0 or (0 <= j < i): i = j
- if i >= 0:
- text = text[:i]
-
- # Now shorten the text
- while len(text) > 70 and p > 60:
- # Cut off 10 chars
- text = "..." + text[10:]
- p = p - 7
-
- # Now print the string, along with an indicator
- print >>sys.stderr, '> ',text
- print >>sys.stderr, '> ',' '*p + '^'
-
-def print_error(input, err, scanner):
- """Print error messages, the parser stack, and the input text -- for human-readable error messages."""
- # NOTE: this function assumes 80 columns :-(
- # Figure out the line number
- line_number = scanner.get_line_number()
- column_number = scanner.get_column_number()
- print >>sys.stderr, '%d:%d: %s' % (line_number, column_number, err.msg)
-
- context = err.context
- if not context:
- print_line_with_pointer(input, err.charpos)
-
- while context:
- # TODO: add line number
- print >>sys.stderr, 'while parsing %s%s:' % (context.rule, tuple(context.args))
- print_line_with_pointer(input, context.scanner.get_prev_char_pos(context.tokenpos))
- context = context.parent
-
-def wrap_error_reporter(parser, rule):
- try:
- return getattr(parser, rule)()
- except SyntaxError, e:
- input = parser._scanner.input
- print_error(input, e, parser._scanner)
- except NoMoreTokens:
- print >>sys.stderr, 'Could not complete parsing; stopped around here:'
- print >>sys.stderr, parser._scanner
-
-
-from twisted.words.xish.xpath import AttribValue, BooleanValue, CompareValue
-from twisted.words.xish.xpath import Function, IndexValue, LiteralValue
-from twisted.words.xish.xpath import _AnyLocation, _Location
-
-%%
-parser XPathParser:
- ignore: "\\s+"
- token INDEX: "[0-9]+"
- token WILDCARD: "\*"
- token IDENTIFIER: "[a-zA-Z][a-zA-Z0-9_\-]*"
- token ATTRIBUTE: "\@[a-zA-Z][a-zA-Z0-9_\-]*"
- token FUNCNAME: "[a-zA-Z][a-zA-Z0-9_]*"
- token CMP_EQ: "\="
- token CMP_NE: "\!\="
- token STR_DQ: '"([^"]|(\\"))*?"'
- token STR_SQ: "'([^']|(\\'))*?'"
- token OP_AND: "and"
- token OP_OR: "or"
- token END: "$"
-
- rule XPATH: PATH {{ result = PATH; current = result }}
- ( PATH {{ current.childLocation = PATH; current = current.childLocation }} ) * END
- {{ return result }}
-
- rule PATH: ("/" {{ result = _Location() }} | "//" {{ result = _AnyLocation() }} )
- ( IDENTIFIER {{ result.elementName = IDENTIFIER }} | WILDCARD {{ result.elementName = None }} )
- ( "\[" PREDICATE {{ result.predicates.append(PREDICATE) }} "\]")*
- {{ return result }}
-
- rule PREDICATE: EXPR {{ return EXPR }} |
- INDEX {{ return IndexValue(INDEX) }}
-
- rule EXPR: FACTOR {{ e = FACTOR }}
- ( BOOLOP FACTOR {{ e = BooleanValue(e, BOOLOP, FACTOR) }} )*
- {{ return e }}
-
- rule BOOLOP: ( OP_AND {{ return OP_AND }} | OP_OR {{ return OP_OR }} )
-
- rule FACTOR: TERM {{ return TERM }}
- | "\(" EXPR "\)" {{ return EXPR }}
-
- rule TERM: VALUE {{ t = VALUE }}
- [ CMP VALUE {{ t = CompareValue(t, CMP, VALUE) }} ]
- {{ return t }}
-
- rule VALUE: "@" IDENTIFIER {{ return AttribValue(IDENTIFIER) }} |
- FUNCNAME {{ f = Function(FUNCNAME); args = [] }}
- "\(" [ VALUE {{ args.append(VALUE) }}
- (
- "," VALUE {{ args.append(VALUE) }}
- )*
- ] "\)" {{ f.setParams(*args); return f }} |
- STR {{ return LiteralValue(STR[1:len(STR)-1]) }}
-
- rule CMP: (CMP_EQ {{ return CMP_EQ }} | CMP_NE {{ return CMP_NE }})
- rule STR: (STR_DQ {{ return STR_DQ }} | STR_SQ {{ return STR_SQ }})
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.py
deleted file mode 100755
index 312f6ecd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xish/xpathparser.py
+++ /dev/null
@@ -1,508 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-# DO NOT EDIT xpathparser.py!
-#
-# It is generated from xpathparser.g using Yapps. Make needed changes there.
-# This also means that the generated Python may not conform to Twisted's coding
-# standards.
-
-# HOWTO Generate me:
-#
-# 1.) Grab a copy of yapps2, version 2.1.1:
-# http://theory.stanford.edu/~amitp/Yapps/
-#
-# Note: Do NOT use the package in debian/ubuntu as it has incompatible
-# modifications.
-#
-# 2.) Generate the grammar:
-#
-# yapps2 xpathparser.g xpathparser.py.proto
-#
-# 3.) Edit the output to depend on the embedded runtime, not yappsrt.
-#
-# sed -e '/^import yapps/d' -e '/^[^#]/s/yappsrt\.//g' \
-# xpathparser.py.proto > xpathparser.py
-
-"""
-XPath Parser.
-
-Besides the parser code produced by Yapps, this module also defines the
-parse-time exception classes, a scanner class, a base class for parsers
-produced by Yapps, and a context class that keeps track of the parse stack.
-These have been copied from the Yapps runtime.
-"""
-
-import sys, re
-
-class SyntaxError(Exception):
- """When we run into an unexpected token, this is the exception to use"""
- def __init__(self, charpos=-1, msg="Bad Token", context=None):
- Exception.__init__(self)
- self.charpos = charpos
- self.msg = msg
- self.context = context
-
- def __str__(self):
- if self.charpos < 0: return 'SyntaxError'
- else: return 'SyntaxError@char%s(%s)' % (repr(self.charpos), self.msg)
-
-class NoMoreTokens(Exception):
- """Another exception object, for when we run out of tokens"""
- pass
-
-class Scanner:
- """Yapps scanner.
-
- The Yapps scanner can work in context sensitive or context
- insensitive modes. The token(i) method is used to retrieve the
- i-th token. It takes a restrict set that limits the set of tokens
- it is allowed to return. In context sensitive mode, this restrict
- set guides the scanner. In context insensitive mode, there is no
- restriction (the set is always the full set of tokens).
-
- """
-
- def __init__(self, patterns, ignore, input):
- """Initialize the scanner.
-
- @param patterns: [(terminal, uncompiled regex), ...] or C{None}
- @param ignore: [terminal,...]
- @param input: string
-
- If patterns is C{None}, we assume that the subclass has defined
- C{self.patterns} : [(terminal, compiled regex), ...]. Note that the
- patterns parameter expects uncompiled regexes, whereas the
- C{self.patterns} field expects compiled regexes.
- """
- self.tokens = [] # [(begin char pos, end char pos, token name, matched text), ...]
- self.restrictions = []
- self.input = input
- self.pos = 0
- self.ignore = ignore
- self.first_line_number = 1
-
- if patterns is not None:
- # Compile the regex strings into regex objects
- self.patterns = []
- for terminal, regex in patterns:
- self.patterns.append( (terminal, re.compile(regex)) )
-
- def get_token_pos(self):
- """Get the current token position in the input text."""
- return len(self.tokens)
-
- def get_char_pos(self):
- """Get the current char position in the input text."""
- return self.pos
-
- def get_prev_char_pos(self, i=None):
- """Get the previous position (one token back) in the input text."""
- if self.pos == 0: return 0
- if i is None: i = -1
- return self.tokens[i][0]
-
- def get_line_number(self):
- """Get the line number of the current position in the input text."""
- # TODO: make this work at any token/char position
- return self.first_line_number + self.get_input_scanned().count('\n')
-
- def get_column_number(self):
- """Get the column number of the current position in the input text."""
- s = self.get_input_scanned()
- i = s.rfind('\n') # may be -1, but that's okay in this case
- return len(s) - (i+1)
-
- def get_input_scanned(self):
- """Get the portion of the input that has been tokenized."""
- return self.input[:self.pos]
-
- def get_input_unscanned(self):
- """Get the portion of the input that has not yet been tokenized."""
- return self.input[self.pos:]
-
- def token(self, i, restrict=None):
- """Get the i'th token in the input.
-
- If C{i} is one past the end, then scan for another token.
-
- @param i: token index
-
- @param restrict: [token, ...] or C{None}; if restrict is
- C{None}, then any token is allowed. You may call
- token(i) more than once. However, the restrict set
- may never be larger than what was passed in on the
- first call to token(i).
- """
- if i == len(self.tokens):
- self.scan(restrict)
- if i < len(self.tokens):
- # Make sure the restriction is more restricted. This
- # invariant is needed to avoid ruining tokenization at
- # position i+1 and higher.
- if restrict and self.restrictions[i]:
- for r in restrict:
- if r not in self.restrictions[i]:
- raise NotImplementedError("Unimplemented: restriction set changed")
- return self.tokens[i]
- raise NoMoreTokens()
-
- def __repr__(self):
- """Print the last 10 tokens that have been scanned in"""
- output = ''
- for t in self.tokens[-10:]:
- output = '%s\n (@%s) %s = %s' % (output,t[0],t[2],repr(t[3]))
- return output
-
- def scan(self, restrict):
- """Should scan another token and add it to the list, self.tokens,
- and add the restriction to self.restrictions"""
- # Keep looking for a token, ignoring any in self.ignore
- while 1:
- # Search the patterns for the longest match, with earlier
- # tokens in the list having preference
- best_match = -1
- best_pat = '(error)'
- for p, regexp in self.patterns:
- # First check to see if we're ignoring this token
- if restrict and p not in restrict and p not in self.ignore:
- continue
- m = regexp.match(self.input, self.pos)
- if m and len(m.group(0)) > best_match:
- # We got a match that's better than the previous one
- best_pat = p
- best_match = len(m.group(0))
-
- # If we didn't find anything, raise an error
- if best_pat == '(error)' and best_match < 0:
- msg = 'Bad Token'
- if restrict:
- msg = 'Trying to find one of '+', '.join(restrict)
- raise SyntaxError(self.pos, msg)
-
- # If we found something that isn't to be ignored, return it
- if best_pat not in self.ignore:
- # Create a token with this data
- token = (self.pos, self.pos+best_match, best_pat,
- self.input[self.pos:self.pos+best_match])
- self.pos = self.pos + best_match
- # Only add this token if it's not in the list
- # (to prevent looping)
- if not self.tokens or token != self.tokens[-1]:
- self.tokens.append(token)
- self.restrictions.append(restrict)
- return
- else:
- # This token should be ignored ..
- self.pos = self.pos + best_match
-
-class Parser:
- """Base class for Yapps-generated parsers.
-
- """
-
- def __init__(self, scanner):
- self._scanner = scanner
- self._pos = 0
-
- def _peek(self, *types):
- """Returns the token type for lookahead; if there are any args
- then the list of args is the set of token types to allow"""
- tok = self._scanner.token(self._pos, types)
- return tok[2]
-
- def _scan(self, type):
- """Returns the matched text, and moves to the next token"""
- tok = self._scanner.token(self._pos, [type])
- if tok[2] != type:
- raise SyntaxError(tok[0], 'Trying to find '+type+' :'+ ' ,'.join(self._scanner.restrictions[self._pos]))
- self._pos = 1 + self._pos
- return tok[3]
-
-class Context:
- """Class to represent the parser's call stack.
-
- Every rule creates a Context that links to its parent rule. The
- contexts can be used for debugging.
-
- """
-
- def __init__(self, parent, scanner, tokenpos, rule, args=()):
- """Create a new context.
-
- @param parent: Context object or C{None}
- @param scanner: Scanner object
- @param tokenpos: scanner token position
- @type tokenpos: C{int}
- @param rule: name of the rule
- @type rule: C{str}
- @param args: tuple listing parameters to the rule
-
- """
- self.parent = parent
- self.scanner = scanner
- self.tokenpos = tokenpos
- self.rule = rule
- self.args = args
-
- def __str__(self):
- output = ''
- if self.parent: output = str(self.parent) + ' > '
- output += self.rule
- return output
-
-def print_line_with_pointer(text, p):
- """Print the line of 'text' that includes position 'p',
- along with a second line with a single caret (^) at position p"""
-
- # TODO: separate out the logic for determining the line/character
- # location from the logic for determining how to display an
- # 80-column line to stderr.
-
- # Now try printing part of the line
- text = text[max(p-80, 0):p+80]
- p = p - max(p-80, 0)
-
- # Strip to the left
- i = text[:p].rfind('\n')
- j = text[:p].rfind('\r')
- if i < 0 or (0 <= j < i): i = j
- if 0 <= i < p:
- p = p - i - 1
- text = text[i+1:]
-
- # Strip to the right
- i = text.find('\n', p)
- j = text.find('\r', p)
- if i < 0 or (0 <= j < i): i = j
- if i >= 0:
- text = text[:i]
-
- # Now shorten the text
- while len(text) > 70 and p > 60:
- # Cut off 10 chars
- text = "..." + text[10:]
- p = p - 7
-
- # Now print the string, along with an indicator
- print >>sys.stderr, '> ',text
- print >>sys.stderr, '> ',' '*p + '^'
-
-def print_error(input, err, scanner):
- """Print error messages, the parser stack, and the input text -- for human-readable error messages."""
- # NOTE: this function assumes 80 columns :-(
- # Figure out the line number
- line_number = scanner.get_line_number()
- column_number = scanner.get_column_number()
- print >>sys.stderr, '%d:%d: %s' % (line_number, column_number, err.msg)
-
- context = err.context
- if not context:
- print_line_with_pointer(input, err.charpos)
-
- while context:
- # TODO: add line number
- print >>sys.stderr, 'while parsing %s%s:' % (context.rule, tuple(context.args))
- print_line_with_pointer(input, context.scanner.get_prev_char_pos(context.tokenpos))
- context = context.parent
-
-def wrap_error_reporter(parser, rule):
- try:
- return getattr(parser, rule)()
- except SyntaxError, e:
- input = parser._scanner.input
- print_error(input, e, parser._scanner)
- except NoMoreTokens:
- print >>sys.stderr, 'Could not complete parsing; stopped around here:'
- print >>sys.stderr, parser._scanner
-
-
-from twisted.words.xish.xpath import AttribValue, BooleanValue, CompareValue
-from twisted.words.xish.xpath import Function, IndexValue, LiteralValue
-from twisted.words.xish.xpath import _AnyLocation, _Location
-
-
-# Begin -- grammar generated by Yapps
-import sys, re
-
-class XPathParserScanner(Scanner):
- patterns = [
- ('","', re.compile(',')),
- ('"@"', re.compile('@')),
- ('"\\)"', re.compile('\\)')),
- ('"\\("', re.compile('\\(')),
- ('"\\]"', re.compile('\\]')),
- ('"\\["', re.compile('\\[')),
- ('"//"', re.compile('//')),
- ('"/"', re.compile('/')),
- ('\\s+', re.compile('\\s+')),
- ('INDEX', re.compile('[0-9]+')),
- ('WILDCARD', re.compile('\\*')),
- ('IDENTIFIER', re.compile('[a-zA-Z][a-zA-Z0-9_\\-]*')),
- ('ATTRIBUTE', re.compile('\\@[a-zA-Z][a-zA-Z0-9_\\-]*')),
- ('FUNCNAME', re.compile('[a-zA-Z][a-zA-Z0-9_]*')),
- ('CMP_EQ', re.compile('\\=')),
- ('CMP_NE', re.compile('\\!\\=')),
- ('STR_DQ', re.compile('"([^"]|(\\"))*?"')),
- ('STR_SQ', re.compile("'([^']|(\\'))*?'")),
- ('OP_AND', re.compile('and')),
- ('OP_OR', re.compile('or')),
- ('END', re.compile('$')),
- ]
- def __init__(self, str):
- Scanner.__init__(self,None,['\\s+'],str)
-
-class XPathParser(Parser):
- Context = Context
- def XPATH(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'XPATH', [])
- PATH = self.PATH(_context)
- result = PATH; current = result
- while self._peek('END', '"/"', '"//"') != 'END':
- PATH = self.PATH(_context)
- current.childLocation = PATH; current = current.childLocation
- if self._peek() not in ['END', '"/"', '"//"']:
- raise SyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['END', '"/"', '"//"']))
- END = self._scan('END')
- return result
-
- def PATH(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'PATH', [])
- _token = self._peek('"/"', '"//"')
- if _token == '"/"':
- self._scan('"/"')
- result = _Location()
- else: # == '"//"'
- self._scan('"//"')
- result = _AnyLocation()
- _token = self._peek('IDENTIFIER', 'WILDCARD')
- if _token == 'IDENTIFIER':
- IDENTIFIER = self._scan('IDENTIFIER')
- result.elementName = IDENTIFIER
- else: # == 'WILDCARD'
- WILDCARD = self._scan('WILDCARD')
- result.elementName = None
- while self._peek('"\\["', 'END', '"/"', '"//"') == '"\\["':
- self._scan('"\\["')
- PREDICATE = self.PREDICATE(_context)
- result.predicates.append(PREDICATE)
- self._scan('"\\]"')
- if self._peek() not in ['"\\["', 'END', '"/"', '"//"']:
- raise SyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['"\\["', 'END', '"/"', '"//"']))
- return result
-
- def PREDICATE(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'PREDICATE', [])
- _token = self._peek('INDEX', '"\\("', '"@"', 'FUNCNAME', 'STR_DQ', 'STR_SQ')
- if _token != 'INDEX':
- EXPR = self.EXPR(_context)
- return EXPR
- else: # == 'INDEX'
- INDEX = self._scan('INDEX')
- return IndexValue(INDEX)
-
- def EXPR(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'EXPR', [])
- FACTOR = self.FACTOR(_context)
- e = FACTOR
- while self._peek('OP_AND', 'OP_OR', '"\\)"', '"\\]"') in ['OP_AND', 'OP_OR']:
- BOOLOP = self.BOOLOP(_context)
- FACTOR = self.FACTOR(_context)
- e = BooleanValue(e, BOOLOP, FACTOR)
- if self._peek() not in ['OP_AND', 'OP_OR', '"\\)"', '"\\]"']:
- raise SyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['OP_AND', 'OP_OR', '"\\)"', '"\\]"']))
- return e
-
- def BOOLOP(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'BOOLOP', [])
- _token = self._peek('OP_AND', 'OP_OR')
- if _token == 'OP_AND':
- OP_AND = self._scan('OP_AND')
- return OP_AND
- else: # == 'OP_OR'
- OP_OR = self._scan('OP_OR')
- return OP_OR
-
- def FACTOR(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'FACTOR', [])
- _token = self._peek('"\\("', '"@"', 'FUNCNAME', 'STR_DQ', 'STR_SQ')
- if _token != '"\\("':
- TERM = self.TERM(_context)
- return TERM
- else: # == '"\\("'
- self._scan('"\\("')
- EXPR = self.EXPR(_context)
- self._scan('"\\)"')
- return EXPR
-
- def TERM(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'TERM', [])
- VALUE = self.VALUE(_context)
- t = VALUE
- if self._peek('CMP_EQ', 'CMP_NE', 'OP_AND', 'OP_OR', '"\\)"', '"\\]"') in ['CMP_EQ', 'CMP_NE']:
- CMP = self.CMP(_context)
- VALUE = self.VALUE(_context)
- t = CompareValue(t, CMP, VALUE)
- return t
-
- def VALUE(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'VALUE', [])
- _token = self._peek('"@"', 'FUNCNAME', 'STR_DQ', 'STR_SQ')
- if _token == '"@"':
- self._scan('"@"')
- IDENTIFIER = self._scan('IDENTIFIER')
- return AttribValue(IDENTIFIER)
- elif _token == 'FUNCNAME':
- FUNCNAME = self._scan('FUNCNAME')
- f = Function(FUNCNAME); args = []
- self._scan('"\\("')
- if self._peek('"\\)"', '"@"', 'FUNCNAME', '","', 'STR_DQ', 'STR_SQ') not in ['"\\)"', '","']:
- VALUE = self.VALUE(_context)
- args.append(VALUE)
- while self._peek('","', '"\\)"') == '","':
- self._scan('","')
- VALUE = self.VALUE(_context)
- args.append(VALUE)
- if self._peek() not in ['","', '"\\)"']:
- raise SyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['","', '"\\)"']))
- self._scan('"\\)"')
- f.setParams(*args); return f
- else: # in ['STR_DQ', 'STR_SQ']
- STR = self.STR(_context)
- return LiteralValue(STR[1:len(STR)-1])
-
- def CMP(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'CMP', [])
- _token = self._peek('CMP_EQ', 'CMP_NE')
- if _token == 'CMP_EQ':
- CMP_EQ = self._scan('CMP_EQ')
- return CMP_EQ
- else: # == 'CMP_NE'
- CMP_NE = self._scan('CMP_NE')
- return CMP_NE
-
- def STR(self, _parent=None):
- _context = self.Context(_parent, self._scanner, self._pos, 'STR', [])
- _token = self._peek('STR_DQ', 'STR_SQ')
- if _token == 'STR_DQ':
- STR_DQ = self._scan('STR_DQ')
- return STR_DQ
- else: # == 'STR_SQ'
- STR_SQ = self._scan('STR_SQ')
- return STR_SQ
-
-
-def parse(rule, text):
- P = XPathParser(XPathParserScanner(text))
- return wrap_error_reporter(P, rule)
-
-if __name__ == '__main__':
- from sys import argv, stdin
- if len(argv) >= 2:
- if len(argv) >= 3:
- f = open(argv[2],'r')
- else:
- f = stdin
- print parse(argv[1], f.read())
- else: print >>sys.stderr, 'Args: <rule> [<filename>]'
-# End -- grammar generated by Yapps
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xmpproutertap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xmpproutertap.py
deleted file mode 100755
index 0bdae0ae..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/words/xmpproutertap.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- test-case-name: twisted.words.test.test_xmpproutertap -*-
-#
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-from twisted.application import strports
-from twisted.python import usage
-from twisted.words.protocols.jabber import component
-
-class Options(usage.Options):
- optParameters = [
- ('port', None, 'tcp:5347:interface=127.0.0.1',
- 'Port components connect to'),
- ('secret', None, 'secret', 'Router secret'),
- ]
-
- optFlags = [
- ('verbose', 'v', 'Log traffic'),
- ]
-
-
-
-def makeService(config):
- router = component.Router()
- factory = component.XMPPComponentServerFactory(router, config['secret'])
-
- if config['verbose']:
- factory.logTraffic = True
-
- return strports.service(config['port'], factory)
diff --git a/lib/python2.7/site-packages/autobuilder/Autobuilder.py b/lib/python2.7/site-packages/autobuilder/Autobuilder.py
deleted file mode 100644
index c8e24528..00000000
--- a/lib/python2.7/site-packages/autobuilder/Autobuilder.py
+++ /dev/null
@@ -1,396 +0,0 @@
-'''
-Created on Dec 4, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-#!/usr/bin/python
-from twisted.python import log
-from config import *
-from buildbot.schedulers.forcesched import *
-from buildbot.schedulers.triggerable import Triggerable
-from buildbot.schedulers import timed
-from buildbot.schedulers.basic import SingleBranchScheduler
-from buildbot.changes import filter
-from buildbot.changes.pb import PBChangeSource
-from buildbot.changes.gitpoller import *
-from buildbot import util
-from lib.ABTools import capitalize
-import ast
-import BuildSet
-
-class Autobuilder:
- def __init__(self, cfile=None):
- self.yocto_sources = YOCTO_SOURCES
- self.yocto_sched = YOCTO_SCHED
- self.yocto_builders = YOCTO_BUILDERS
- self.yocto_projname = YOCTO_PROJNAME
- self.yocto_projurl = YOCTO_PROJURL
- self.config = None
- import os, config
- if cfile is None:
- try:
- self.cfile = os.environ.get("YOCTO_AB_CONFIG")
- except:
- self.cfile = "./buildset-config/yoctoAB.conf"
- else:
- self.cfile = cfile
-
- def createBuildsets(self):
- buildersSorted=[]
- sort = True
- if self.config.has_option('BuildSets', 'order'):
- sort = False
- for set in ast.literal_eval(self.config.get('BuildSets', 'order')):
- buildersSorted.append(set)
-
- for key in self.configdict:
- if key not in buildersSorted and key != "BuildSets":
- buildersSorted.append(key)
-
- if sort:
- util.naturalSort(buildersSorted)
-
- for buildset in buildersSorted:
- self.schedprops = []
- self.checkoutprops={}
- self.set_props = {}
- self.repos = []
- self.properties = []
- self.builders = None
- self.schedprops.append(NestedParameter(name='ss_' + buildset, label="<h3><div class='trigger_heading' id='"+buildset+"'>" + buildset + " defaults:</div></h3>", fields=[FixedParameter(name="dummy", default="dummy")]))
- self.parseBuildSet(buildset)
- steps = ast.literal_eval(self.configdict[buildset]['steps'])
- repos = ast.literal_eval(self.configdict[buildset].get('repos', '{}'))
- locals()['buildset_%s' % buildset] = BuildSet.BuildSet(name = buildset,
- steps = steps,
- builders = self.builders,
- layers = repos,
- set_props = self.set_props)
-
- self.yocto_sched.append(ForceScheduler(
- name=str(buildset),
- branch=FixedParameter(name="branch",
- default=""),
- reason=StringParameter(name="reason",
- label="Reason (please note the reason for triggering the build and any expecations for the builds outcome):<br>",
- required=False,
- size=120),
- revision=FixedParameter(name="revision",
- default=""),
- repository=FixedParameter(name="repository",
- default=""),
- project=FixedParameter(name="repository",
- default=""),
- builderNames=['%s' % buildset],
- properties=self.schedprops))
- self.createExtraSchedulers(key=buildset, checkoutprops=self.checkoutprops)
-
- def parseBuildSet(self, buildset):
- log.msg("Parsing " + buildset)
- if buildset is not "BuildSets":
- self.builders=self.parseBuilders(buildset)
- self.parseProps(buildset)
- self.parseRepos(buildset)
- self.parseSteps(buildset)
- self.set_props.update(self.checkoutprops)
-
- def parseSteps(self, buildset):
- buildset=buildset
- try:
- for step in ast.literal_eval(self.configdict[buildset]['steps']):
- if step.has_key('TriggerBuilds'):
- master_trigger_name = step['TriggerBuilds']['schedulerName']
- for b in ["", "_nowait"]:
- buildername=[]
- if 'schedulerNames' + b in step['TriggerBuilds' ]:
- for scheduler in step['TriggerBuilds']['schedulerNames' + b].iterkeys():
- if scheduler not in buildername:
- buildername.append(scheduler)
- self.yocto_sched.append(Triggerable(name="trigger_" + master_trigger_name + b, builderNames=buildername))
- except SyntaxError as err:
- raise ABConfigError("%s found in %s" % (err, buildset))
-
- def parseRepos(self, buildset=None):
- buildset=buildset
- if self.configdict[buildset].has_key('repos'):
- try:
- for layer in ast.literal_eval(self.configdict[buildset]['repos']):
- if layer.iterkeys().next() not in self.repos:
- schedpropstoextend, newcheckoutprops = self.CreateLayerSchedulerParams(layer=layer, trigger=buildset, triggerer=True)
- self.schedprops.extend(schedpropstoextend)
- self.checkoutprops.update(newcheckoutprops)
- self.repos.append(layer.iterkeys().next())
- except SyntaxError as err:
- raise ABConfigError("%s found in %s" % (err, buildset))
- return
-
- def parseProps(self, buildset):
- buildset=buildset
- if self.configdict[buildset].has_key('props'):
- for props in ast.literal_eval(self.configdict[buildset]['props']):
- for prop in dict(props):
- self.prop_name=""
- self.prop_prop_type=""
- self.prop_default=""
- self.prop_choices=""
- self.prop_label=""
- self.prop_required=""
- self.prop_size=""
- setattr(self, "prop_name", prop)
- for k, v in props[prop].iteritems():
- setattr(self, "prop_"+str(k), v)
- if self.prop_name not in self.properties:
- schedpropstoextend = self.CreateExtraSchedulerParams(name=self.prop_name,
- prop_type=self.prop_prop_type,
- default=self.prop_default,
- choices=self.prop_choices,
- label=self.prop_label,
- required=self.prop_required,
- scheduler=buildset,
- size=self.prop_size)
- self.schedprops.extend(schedpropstoextend)
- self.properties.append(self.prop_name)
-
- def parseBuilders(self, buildset):
- buildset=buildset
- builders=ast.literal_eval(self.configdict[buildset]['builders'])
- return builders
-
- def parseConfig(self):
- import ConfigParser
- from os import listdir
- from os.path import dirname, isfile, join
- print "LOADING CONFIG FILE"
- self.config = ConfigParser.ConfigParser()
- self.configdir=os.path.dirname(self.cfile)
- self.configfiles = [ join(self.configdir,f) for f in listdir(self.configdir) if isfile(join(self.configdir,f)) and (f != 'autobuilder.conf') and f.endswith(".conf")]
- try:
- self.config.read(self.configfiles)
- except ConfigParser.Error as err:
- print("Failed parsing config files with error: %s" % err)
- self.buildsets=self.config.sections()
- self.configdict = {}
- for section in self.buildsets:
- self.configdict[section]= dict(self.config.items(section))
- return self.configdict
-
- def GetLayerCommitId(self, layer):
- if 'hash' in layer[layer.iterkeys().next()] :
- layercommitid=layer[layer.iterkeys().next()]['hash']
- elif 'tag' in layer[layer.iterkeys().next()]:
- layercommitid=layer[layer.iterkeys().next()]['tag']
- else:
- layercommitid="HEAD"
- return layercommitid
-
- def GetLayerBranch(self, layer):
- if 'branch' in layer[layer.iterkeys().next()]:
- layerbranch=layer[layer.iterkeys().next()]['branch']
- else:
- layerbranch="master"
- return layerbranch
-
- # Create extra schedulers requested for the given buildset using 'scheduler:'
- def createExtraSchedulers(self, key, checkoutprops):
- import ast
- schedulerkey = 'scheduler'
- if self.configdict[key].has_key(schedulerkey):
- for scheds in ast.literal_eval(self.configdict[key][schedulerkey]):
- for name,value in dict(scheds).iteritems():
- schedtype = None
- if value.has_key('type'):
- schedtype = value['type']
-
- # For each change based scheduler, create separate change source
- # for each repo in the build set; this is so that each repo can have
- # distinct authorisation credential, etc.
- if schedtype == "SingleBranchScheduler":
- if not value.has_key('repository'):
- log.msg("%s has no repository property" % schedtype)
- continue
-
- reponame = value['repository']
- repos=None
- repo=None
-
- for x in ast.literal_eval(self.configdict[key]['repos']):
- if dict(x).has_key(reponame):
- repos=x
- repo=repos[reponame]
- break
-
- if repo is None:
- log.msg("No repo %s found" % reponame)
- continue
-
- repo=repos[reponame]
- if not repo.has_key('repourl'):
- log.msg("No repourl for %s found" % reponame)
- continue
-
- # default user to the name of the repo
- user=str(reponame)
- if value.has_key('change-user'):
- user=value['change-user']
-
- # default password is None, which in the change source becomes 'changepw'
- passwd=None
- if value.has_key('change-password'):
- passwd=value['change-password']
-
- branch="master"
- stabletimer=60
- if repo.has_key('branch'):
- branch = repo['branch']
- if value.has_key('stable-timer'):
- stabletimer = value['stable-timer']
-
- if value.has_key('changesource') and value['changesource'] == 'GitPoller':
- if value.has_key('interval'):
- interval = int(value['interval'])
- else:
- # default to 5 minutes poll intervals
- interval = 60*5
- gitpoller = GitPoller(repourl=repo['repourl'], branch=branch, pollInterval=interval)
- if gitpoller not in self.yocto_sources:
- self.yocto_sources.append(gitpoller)
- log.msg("Adding GitPoller as changesource for " + reponame)
- else:
- log.msg("GitPoller already registered as changesource for " + reponame)
- else:
- # default to use PBChangeSource as the changesource
- self.yocto_sources.append(PBChangeSource(user=user, passwd=passwd))
- log.msg("Adding PBChangeSource as changesource for " + reponame)
-
- self.yocto_sched.append(SingleBranchScheduler(name=str(name),
- builderNames=['%s' % key],
- properties=checkoutprops,
- change_filter=filter.ChangeFilter(branch=branch,
- repository=repo['repourl']),
- treeStableTimer=stabletimer))
- log.msg("Added %s '%s' for branch '%s' in repository '%s'" % (schedtype,str(name),branch,repo['repourl']))
-
- elif not schedtype or schedtype == "Nightly":
- # Set default values for optional nightly build
- # parameters.
- buildmonth="*"
- builddayOfWeek = "*"
- if value.has_key('month'):
- buildmonth = value['month']
- if value.has_key('dayOfWeek'):
- builddayOfWeek = value['dayOfWeek']
- self.yocto_sched.append(timed.Nightly(name=str(name),
- branch='default',
- builderNames=['%s' % key],
- properties=checkoutprops,
- hour=value['hour'],
- minute=value['minute'],
- month=buildmonth,
- dayOfWeek=builddayOfWeek))
-
-
- def CreateExtraSchedulerParams(self, name=None,
- prop_type=None,
- default=None,
- choices=None,
- label=None,
- required=None,
- size=None,
- scheduler=""):
- supported_prop_types = ["ChoiceStringParameter",
- "StringParameter",
- "FixedParameter",
- "BooleanParameter"]
- schedprops = []
- prop_type=prop_type
- name=name
- choices=choices
- prop_type=prop_type
- label=label
- required=required
- size=size
- default=default
- scheduler=scheduler
- propid="custom_"+name
- if label is None:
- label=self.name
-
- if default is None:
- if prop_type == "FixedParameter":
- try:
- raise ABConfigError("your config file has a fixed type property declaration that has no default")
- except ABConfigError, (instance):
- log.msg("Caught: " + instance.parameter)
- else:
- default = ""
-
- if prop_type == "ChoiceStringParameter":
- if choices is None:
- try:
- raise ABConfigError("your config file has a ChoiceStringParameter declaration that has no choices")
- except ABConfigError, (instance):
- log.msg("Caught: " + instance.parameter)
-
- if required is None:
- required=True
-
- if size is None:
- size=80
-
- if prop_type is None:
- prop_type = "StringParameter"
-
- if prop_type=="ChoiceStringParameter":
- schedprops.append(ChoiceStringParameter(name=propid,
- label=label,
- required=required,
- choices=choices))
- elif prop_type=="StringParameter":
- schedprops.append(StringParameter(name=propid,
- label=label,
- required=required,
- default=default,
- size=size))
- elif prop_type=="FixedParameter":
- schedprops.append(FixedParameter(name=propid,
- label=label,
- required=required,
- default=default))
- elif prop_type=="BooleanParameter":
- schedprops.append(BooleanParameter(name=propid,
- label=label,
- required=required,
- default=default))
- else:
- try:
- raise ABConfigError("your config file has a prop declaration that is not valid")
- except ABConfigError, (instance):
- log.msg("Caught: " + instance.parameter)
- return schedprops
-
- def CreateLayerSchedulerParams(self, layer=None, trigger=None, triggerer=None):
- schedprops = []
- set_checkoutprops = {}
- layerrepo=layer[layer.iterkeys().next()]['repourl']
- layerbranch=self.GetLayerBranch(layer)
- layercommitid=self.GetLayerCommitId(layer)
- layername=layer.iterkeys().next()
- set_checkoutprops['repo_' + layername] = layerrepo
- set_checkoutprops['branch_' + layername] = layerbranch
- set_checkoutprops['commit_' + layername] = layercommitid
- schedprops.append(StringParameter(name="repo_"+ layername, label="<hr><b>" + layername + "</b> Repository:<br>", required=True, default=layerrepo, size=50))
- schedprops.append(StringParameter(name="branch_" + layername, label="Branch:<br>", required=True, default=layerbranch, size=18))
- schedprops.append(StringParameter(name="commit_" + layername, label="Tag/Commit Hash:<br>", required=True, default=layercommitid, size=20))
- return schedprops, set_checkoutprops
-
-class ABConfigError(Exception):
- def __init__(self, value):
- self.parameter = value
- def __str__(self):
- return repr(self.parameter)
diff --git a/lib/python2.7/site-packages/autobuilder/BuildSet.py b/lib/python2.7/site-packages/autobuilder/BuildSet.py
deleted file mode 100644
index df2be357..00000000
--- a/lib/python2.7/site-packages/autobuilder/BuildSet.py
+++ /dev/null
@@ -1,185 +0,0 @@
-'''
-Created on Dec 17, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from config import *
-from twisted.python import log
-from buildsteps import *
-from buildbot.process import factory as factory
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.properties import Property, Properties, PropertiesMixin, renderer
-from buildbot.steps.trigger import Trigger
-import os
-from lib.ABTools import stringToBool
-
-
-class BuildSet():
- '''
- classdocs
- '''
- def __init__(self, name, layers, steps, builders, set_props={}):
- '''
- Constructor
- '''
- locals()['f'+name] = factory.BuildFactory()
- for stepOrder in steps:
- for step in dict(stepOrder):
- factoryFN=getattr(locals()['f'+name], 'addStep')
- if step=="PublishLayerTarballs":
- for layer in layers:
- kwargs=stepOrder[step]
- layername=layer.iterkeys().next()
- if layer[layer.iterkeys().next()].has_key('checkout') and layer[layer.iterkeys().next()]['checkout'] == False:
- pass
- else:
- if layername == "poky" or layername == 'oecore':
- workdir = 'build'
- elif "eclipse" in layername:
- workdir="build"
- else:
- workdir="build/" + layername
- m = __import__ (step)
- func = getattr(m, step)
- factoryFN(func(locals()['f'+name],
- layername=layername,
- workdir=workdir,
- argdict=layer[layer.iterkeys().next()]))
- elif step=="CheckOutLayers":
- # All steps need the factory passed as the first param
- for layer in layers:
- kwargs=stepOrder[step]
- layername=layer.iterkeys().next()
- if os.environ.get("RESOLVE_TRIGGERED_HEAD") == "True":
- m = __import__ ("ResolveLayerHead")
- func = getattr(m, "ResolveLayerHead")
- factoryFN(func(locals()['f'+name],
- layername=layername,
- scheduler=name,
- argdict=layer[layer.iterkeys().next()]))
- if 'checkout' in layer[layer.iterkeys().next()]:
- if layer[layer.iterkeys().next()]['checkout'] == False:
- pass
- else:
- storedir=None
- mirrordir=None
- method = 'clobber'
- mode='full'
- if str(os.environ.get('OPTIMIZED_GIT_CLONE')) == "True":
- if 'poky' in layername or 'oecore' in layername or 'eclipse' in layername:
- method='movecopy'
- storedir=os.environ.get('OGIT_TRASH_DIR')
- mirrordir=os.environ.get('OGIT_MIRROR_DIR')
- else:
- method='barecopy'
- storedir=os.environ.get('OGIT_TRASH_DIR')
- mirrordir=os.environ.get('OGIT_MIRROR_DIR')
- elif os.environ.get('OGIT_MIRROR_DIR', None) != None:
- mirrordir=os.environ.get('OGIT_MIRROR_DIR')
- if 'poky' in layername or 'oecore' in layername:
- workdir = 'build'
- elif "eclipse-poky" in layername:
- workdir="build/" + layername
- else:
- workdir="build/" + layername
- m = __import__ (step)
- func = getattr(m, step)
- factoryFN(func(locals()['f'+name],
- layername=layername,
- mode=mode,
- scheduler=name,
- method=method,
- storedir=storedir,
- mirrordir=mirrordir,
- workdir=workdir,
- argdict=layer[layer.iterkeys().next()]))
- if 'layerversion' in layer[layer.iterkeys().next()]:
- m = __import__ ("GetLayerVersion")
- func = getattr(m, "GetLayerVersion")
- for layerversion_name, layerversion_path in layer[layer.iterkeys().next()]['layerversion'].iteritems():
- factoryFN(func(locals()['f'+name],
- layerversion=layerversion_name,
- workdir=layerversion_path,
- argdict={}))
-
- elif step=="CreateBBLayersConf":
- kwargs=stepOrder[step]
- m = __import__ (step)
- func = getattr(m, step)
- factoryFN(func(locals()['f'+name],
- layers,
- argdict=stepOrder[step]))
- elif step=="TriggerBuilds":
- set_properties = {}
- copy_properties = []
- set_properties['DEST']= Property("DEST")
- trigger_name = ""
- waitForFinish = False
- if 'schedulerName' in stepOrder[step]:
- trigger_name = 'trigger_' + stepOrder[step]['schedulerName']
- if 'set_properties' in stepOrder[step]:
- for p in stepOrder[step]['set_properties'].iterkeys():
- set_properties[p]=stepOrder[step]['set_properties'][p]
- if 'copy_properties' in stepOrder[step]:
- for p in stepOrder[step]['copy_properties']:
- copy_properties.append('%s' % p)
- if 'waitForFinish' in stepOrder[step]:
- waitForFinish = stringToBool(stepOrder[step]['waitForFinish'])
- else:
- waitForFinish = False
- if 'schedulerNames_nowait' in stepOrder[step]:
- for scheduler in stepOrder[step]['schedulerNames_nowait'].keys():
- for layer in layers:
- layername=layer.iterkeys().next()
- if Property('commit_resolvedhead_' + layername):
- set_properties['commit_resolvedhead_' + layername] = Property('commit_resolvedhead_' + layername)
- set_properties['commit_' + layername] = Property('commit_resolvedhead_' + layername)
- elif Property('commit_' + layername):
- set_properties['commit_' + layername] = Property('commit_' + layername)
- if Property('branch_' + layername):
- set_properties['branch_' + layername] = Property('branch_' + layername)
- if Property('repo_' + layername):
- set_properties['repo_' + layername] = Property('repo_' + layername)
- elif Property('repourl_' + layername):
- set_properties['repo_' + layername] = Property('repourl_' + layername)
- if 'schedulerNames' in stepOrder[step]:
- for scheduler in stepOrder[step]['schedulerNames'].keys():
- for layer in layers:
- layername=layer.iterkeys().next()
- if Property('commit_resolvedhead_' + layername):
- set_properties['commit_resolvedhead_' + layername] = Property('commit_resolvedhead_' + layername)
- set_properties['commit_' + layername] = Property('commit_resolvedhead_' + layername)
- elif Property('commit_' + layername):
- set_properties['commit_' + layername] = Property('commit_' + layername)
- if Property('branch_' + layername):
- set_properties['branch_' + layername] = Property('branch_' + layername)
- if Property('repo_' + layername):
- set_properties['repo_' + layername] = Property('repo_' + layername)
- elif Property('repourl_' + layername):
- set_properties['repo_' + layername] = Property('repourl_' + layername)
- factoryFN(Trigger(schedulerNames=[trigger_name, trigger_name + "_nowait"],
- noWait=[trigger_name + "_nowait"],
- set_properties=set_properties,
- copy_properties=copy_properties,
- waitForFinish=waitForFinish))
- else:
- kwargs=stepOrder[step]
- m = __import__ (step)
- func = getattr(m, step)
- factoryFN(func(locals()['f'+name],
- argdict=stepOrder[step]))
- locals()['b%s' % name] = {'name': name,
- 'slavenames': builders,
- 'builddir': name,
- 'factory': locals()['f'+name],
- }
- yocto_builders=YOCTO_BUILDERS
- yocto_builders.append(locals()['b%s' % name])
-
diff --git a/lib/python2.7/site-packages/autobuilder/YoctoMailer.py b/lib/python2.7/site-packages/autobuilder/YoctoMailer.py
deleted file mode 100644
index 1e435a0b..00000000
--- a/lib/python2.7/site-packages/autobuilder/YoctoMailer.py
+++ /dev/null
@@ -1,109 +0,0 @@
-'''
-Created on June 28, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from buildbot.status.mail import MailNotifier
-from buildbot.status.mail import *
-from buildbot import interfaces, util, config
-from buildbot.process.users import users
-from buildbot.status import base
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, EXCEPTION, Results
-from twisted.python import log
-
-class YoctoMailNotifier(MailNotifier):
- def __init__(self, fromaddr, mode=("failing"),
- categories=None, branches=None, yoctorepos=None, builders=None, addLogs=False,
- relayhost="localhost", buildSetSummary=False,
- subject="buildbot %(result)s in %(title)s on %(builder)s",
- lookup=None, extraRecipients=[],
- sendToInterestedUsers=True, customMesg=None,
- messageFormatter=defaultMessage, extraHeaders=None,
- addPatch=True, useTls=False,
- smtpUser=None, smtpPassword=None, smtpPort=25):
- self.fromaddr = fromaddr
- self.mode=mode
- self.categories = categories
- self.branches = branches
- self.yoctorepos = yoctorepos
- self.builders = builders
- self.addLogs = addLogs
- self.relayhost = relayhost
- self.buildSetSummary = buildSetSummary
- self.subject = subject
- self.lookup = lookup
- self.extraRecipients = extraRecipients
- self.sendToInterestedUsers = sendToInterestedUsers
- self.customMesg = customMesg
- self.messageFormatter = messageFormatter
- self.extraHeaders = extraHeaders
- self.addPatch = addPatch
- self.useTls = useTls
- self.smtpUser = smtpUser
- self.smtpPassword = smtpPassword
- self.smtpPort = smtpPort
- MailNotifier.__init__(self, fromaddr, mode=self.mode,
- categories = self.categories, builders = self.builders,
- addLogs = self.addLogs, relayhost = self.relayhost,
- buildSetSummary = self.buildSetSummary,
- subject = self.subject,
- lookup = self.lookup,
- extraRecipients = self.extraRecipients,
- sendToInterestedUsers = self.sendToInterestedUsers,
- customMesg = self.customMesg,
- messageFormatter = self.messageFormatter,
- extraHeaders = self.extraHeaders, addPatch = self.addPatch,
- useTls = self.useTls, smtpUser = self.smtpUser,
- smtpPassword = self.smtpPassword, smtpPort = self.smtpPort)
-
- def isMailNeeded(self, build, results):
- # here is where we actually do something.
- builder = build.getBuilder()
- repo=build.getProperty("repository")
- branch=build.getProperty("branch")
- log.msg(repo)
- log.msg(branch)
- buildme = False
- if self.builders is not None and builder.name not in self.builders:
- return False # ignore this build
- if self.categories is not None and \
- builder.category not in self.categories:
- return False # ignore this build
-
- if self.yoctorepos is not None and repo in self.yoctorepos:
- if self.branches is not None:
- if branch in self.branches:
- buildme = True
- else:
- return False # ignore this build
- elif self.yoctorepos is None:
- if self.branches is not None and branch in self.branches:
- buildme = True
- elif self.branches is not None and branch not in self.branches:
- return False # ignore this build
- else:
- buildme = True
-
- if buildme is True:
- prev = build.getPreviousBuild()
- if "change" in self.mode:
- if prev and prev.getResults() != results:
- return True
- if "failing" in self.mode and results == FAILURE:
- return True
- if "passing" in self.mode and results == SUCCESS:
- return True
- if "problem" in self.mode and results == FAILURE:
- if prev and prev.getResults() != FAILURE:
- return True
- if "warnings" in self.mode and results == WARNINGS:
- return True
- if "exception" in self.mode and results == EXCEPTION:
- return True
- return False
diff --git a/lib/python2.7/site-packages/autobuilder/Yocto_Message_Formatter.py b/lib/python2.7/site-packages/autobuilder/Yocto_Message_Formatter.py
deleted file mode 100644
index 611da1f8..00000000
--- a/lib/python2.7/site-packages/autobuilder/Yocto_Message_Formatter.py
+++ /dev/null
@@ -1,79 +0,0 @@
-'''
-Created on Jun 3, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-#!/usr/bin/python
-from twisted.python import log
-from buildbot.status.builder import Results
-
-def message_formatter(mode, name, build, results, master_status):
- result = Results[results]
- limit_lines = 60
- text = list()
- text.append('<h4>Build status: %s</h4>' % result.upper())
- text.append("Build worker for this Build: <b>%s</b>" % build.getSlavename())
- text.append('<br>')
- if master_status.getURLForThing(build):
- text.append('Complete logs for all build steps: <a href="%s">%s</a>'
- % (master_status.getURLForThing(build),
- master_status.getURLForThing(build))
- )
- text.append('<br>')
- text.append("Build Reason: %s" % build.getReason())
- text.append('<br>')
-
- try:
- build_properties = build.getProperties().asList()
- except:
- pass
- if build_properties:
- text.append("Build Properties:<br>")
- text.append("<ul>")
- for prop in build_properties:
- if str(prop[1]) != '':
- if prop[0] == "BBLAYERS" or prop[0] == "LOCALCONF":
- if prop[0] == 'BBLAYERS':
- text.append('<li>Contents of bblayers.conf (Note. LCONF_VERSION will not show up correctly)<br><code>')
- else:
- text.append('<li>Contents of auto.conf (local.conf for autobuilders)<br><code>')
- lines=prop[1].splitlines()
- for line in lines:
- text.append(line + "<br>")
- text.append('<br></code></li>')
- elif "trigger" not in prop[0] and "ss_" not in prop[0]:
- text.append('<li>' + prop[0] + " : " + str(prop[1])+"</li>")
- text.append('</ul>')
- url = ""
- for log in build.getLogs():
- log_name = "%s.%s" % (log.getStep().getName(), log.getName())
- log_status, dummy = log.getStep().getResults()
- log_body = []
- for line in log.getText().splitlines(): # Note: can be VERY LARGE
- print line
- if "ERROR" in line or "|" in line:
- log_body.append(line)
-
- log_url = '%s/steps/%s/logs/%s' % (master_status.getURLForThing(build),
- log.getStep().getName(),
- log.getName())
-
- if log_status == 2 and log_body:
- text.append('<i>Detailed log of last build step:</i> <a href="%s">%s</a>'
- % (log_url, log_url))
- text.append('<br>')
- text.append('<h4>Last %d lines of "%s" Error log:</h4>' % (limit_lines, log_name))
- text.append('<p>')
- text.append('<br>'.join([line for line in
- log_body[len(log_body)-limit_lines:]]))
- text.append('</p>')
- text.append('<br><br>')
- text.append('<b>-The Yocto BuildBot</b>')
- return {'body': "\n".join(text), 'type': 'html'}
-
diff --git a/lib/python2.7/site-packages/autobuilder/__init__.py b/lib/python2.7/site-packages/autobuilder/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/autobuilder/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/AddKernelProps.py b/lib/python2.7/site-packages/autobuilder/buildsteps/AddKernelProps.py
deleted file mode 100644
index 1ff96592..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/AddKernelProps.py
+++ /dev/null
@@ -1,60 +0,0 @@
-'''
-Created on March 18, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-import os
-from twisted.python import log
-import ast, json
-
-class AddKernelProps(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "AutoConfKernOverR"
- def __init__(self, factory, argdict=None, **kwargs):
- self.machine=""
- self.distro="poky"
- self.kstring = "pn-linux-yocto"
- self.kwargs = kwargs
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- self.description = "Add Kernel Bits to Auto Configuration"
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.distro = self.getProperty("DISTRO")
- self.machine = self.getProperty("MACHINE")
- kmeta = self.getProperty("custom_kmeta")
- kbranch = self.getProperty("custom_kbranch")
- srcrev_meta = self.getProperty("custom_srcrev_meta")
- srcrev_machine = self.getProperty("custom_srcrev_machine")
- srcuri_meta = self.getProperty("custom_srcuri_meta")
- srcuri_machine = self.getProperty("custom_srcuri_machine")
- fout = ""
- if self.distro == "poky-rt":
- self.kstring = "pn-linux-yocto-rt"
- if srcrev_machine != "" and str(srcrev_machine) != "None":
- fout += "SRCREV_machine_%s_%s = \"%s\"\n" % (self.machine, self.kstring, srcrev_machine)
- if srcrev_meta != "" and str(srcrev_meta) != "None":
- fout += "SRCREV_meta_%s_%s = \"%s\"\n" % (self.machine, self.kstring, srcrev_meta)
- if kmeta != "" and str(kmeta) != "None":
- fout += 'KMETA_%s_%s = \"%s\"\n' % (self.machine, self.kstring, kmeta)
- if srcuri_meta != "" and str(srcuri_meta) != "None":
- fout += "SRC_URI_%s_%s += \"%s;bareclone=1;branch=${KMETA};type=kmeta;name=meta\"\n" % (self.machine, self.kstring, srcuri_meta)
- if kbranch != "" and str(kbranch) != "None":
- fout += 'KBRANCH_%s_%s = \"%s\"\n' % (self.machine, self.kstring, kbranch)
- if srcuri_machine != "" and str(srcuri_machine) != "None":
- fout += "SRC_URI_%s_%s += \"%s;bareclone=1;branch=${KBRANCH};type=machine;name=machine\"\n" % (self.machine, self.kstring, srcuri_machine)
- self.command = ["sh", "-c", "printf '" + fout + "'>> ./build/conf/auto.conf"]
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/BitbakeSelftest.py b/lib/python2.7/site-packages/autobuilder/buildsteps/BitbakeSelftest.py
deleted file mode 100644
index 97b06aef..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/BitbakeSelftest.py
+++ /dev/null
@@ -1,32 +0,0 @@
-'''
-Created on Jan 19, 2016
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2016, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-
-class BitbakeSelftest(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "BitbakeSelftest"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.command = ". ./oe-init-build-env; bitbake-selftest"
- self.description = ["Bitbake selftest"]
- ShellCommand.start(self)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py b/lib/python2.7/site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py
deleted file mode 100644
index c71ba129..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py
+++ /dev/null
@@ -1,52 +0,0 @@
-'''
-Created on March 10, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from autobuilder.config import *
-import os
-from twisted.python import log
-
-class BuildEclipsePlugin(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Building Eclipse Plugin"
- def __init__(self, factory, argdict=None, **kwargs):
- self._pendingLogObservers = []
- self.factory = factory
- self.eclipsedir = "eclipse-poky"
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Building Eclipse Plugin"
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- self.workerworkdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- buildername=self.getProperty("buildername")
- eclipsename=buildername.replace("eclipse-plugin-", "")
- oldbuildername=buildername.replace("plugin", "poky")
- doc_branch=self.getProperty("branch").replace(eclipsename,"").replace("/","").replace("-","")
- eclipse_branch=self.getProperty("branch_%s" % (oldbuildername))
- eclipsehome=self.workerworkdir + "/" + buildername + '/build'
- rel_name = 'development'
- if str(self.getProperty("custom_release_me")) == "True":
- yocto_number = self.getProperty("custom_yocto_number")
- rel_name = 'yocto-'+ yocto_number
- self.command='cd %s/scripts/; ./setup.sh; ECLIPSE_HOME="%s/scripts/eclipse/" ./build.sh %s %s %s' % \
- (eclipsehome, eclipsehome, eclipse_branch, doc_branch, rel_name)
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/BuildImages.py b/lib/python2.7/site-packages/autobuilder/buildsteps/BuildImages.py
deleted file mode 100644
index 23527c97..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/BuildImages.py
+++ /dev/null
@@ -1,195 +0,0 @@
-'''
-Created on Jan 6, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from distutils.version import StrictVersion
-from buildbot.status.results import SUCCESS, SKIPPED
-import os, datetime
-
-from lib.buildsteps import BitbakeShellCommand
-
-class BuildImages(BitbakeShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "BuildImages"
- def __init__(self, factory, argdict=None, **kwargs):
- self.layerversion_yoctobsp=0
- self.machine=""
- self.images=""
- self.oeinit = "oe-init-build-env"
- self.overrideenv = []
- self._pendingLogObservers = []
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- super(BuildImages, self).__init__(factory, argdict=None,
- **kwargs)
-
- def start(self):
- self.localconf = self.getProperty("LOCALCONF")
- self.layerversion_yoctobsp = \
- int(self.getProperty("layerversion_yoctobsp", "0"))
- self.layerversion_core = \
- int(self.getProperty("layerversion_core", "0"))
- self.machine = self.getProperty("MACHINE", "")
- self.minnowExists = self.getProperty("minnowExists")
- try:
- self.deploycheck = self.getProperty('custom_deploy_artifacts')
- except:
- self.deploycheck = "True"
-
- builddir = os.path.join(self.getProperty('builddir'), 'build')
- if self.overrideenv:
- for i, e in enumerate(self.overrideenv):
- self.overrideenv[i] = e.replace('#YPDIR', builddir)
-
- # the eventlog capability exists only in bitbake 1.25 and newer
- self.create_eventlog = "False"
- if self.getProperty('bitbakeversion') \
- and StrictVersion(self.getProperty('bitbakeversion')) >= StrictVersion("1.25"):
- try:
- self.create_eventlog = self.getProperty("custom_create_eventlog")
- if self.create_eventlog == "True":
- timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
- self.eventlog_name = "tmp/log/bitbake_eventlog-%s.json" % timestamp
- except:
- pass
-
- env = ''
- if self.overrideenv:
- env = ' '.join(self.overrideenv) + ' '
-
- # Refkit builds should only happen for non-releases on master,
- # master-next or ross/mut* branches
- branch = self.getProperty('branch')
- masterish = False
- if self.getProperty('is_release') != 'True' \
- and (branch in ['master', 'master-next'] \
- or branch.startswith('ross/mut')):
- masterish = True
-
- if self.images == "#SCRAPEDTARGETS":
- self.images = self.getProperty("scraped_targets")
-
- if self.images == "#TOASTER":
- bitbakeflags = "-k "
- if self.create_eventlog == "True":
- bitbakeflags += "-w '" + self.eventlog_name + "' "
- self.images=self.getProperty("custom_images")
- self.command = env + ". ./" + self.oeinit + "; bitbake " + bitbakeflags + self.images
- self.description = ["Building " + str(self.images)]
- elif self.images == "package-index" and str(self.deploycheck) == "False":
- self.skipStep('Skipping build as the required artifacts are not there')
- elif not masterish and 'refkit' in self.images:
- # Refkit tracks OE-Core master, skip it for named branches
- self.skipStep('Skipping refkit build, not supported for releases.')
- # core-image-basic rename
- # See: http://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/?id=b7f1cca517bbd4191828c6bae32e0c5041f1ff19
- # I hate making people change their configs, so support both.
- else:
- if self.layerversion_core < 4:
- self.images=self.images.replace("core-image-full-cmdline", "core-image-basic")
- else:
- self.images=self.images.replace("core-image-basic", "core-image-full-cmdline")
-
- if self.layerversion_core < 8:
- self.images=self.images.replace("core-image-sato-sdk-ptest", "")
-
- if self.layerversion_core > 6:
- self.images=self.images.replace("LSB-QT-IMAGES", "")
- else:
- self.images=self.images.replace("LSB-QT-IMAGES", "core-image-lsb-qt3")
-
- # Releases older than Rocko didn't build
- # core-image-sato-sdk with musl.
- if self.layerversion_core < 11 \
- and "musl" in self.localconf:
- self.images = self.images.replace("core-image-sato-sdk", "core-image-sato")
-
- # Releases older than Pyro need to build an image before
- # invoking oe-selfest
- if self.layerversion_core < 10:
- self.images = self.images.replace("SELFTEST-PRE", "core-image-minimal")
- else:
- self.images = self.images.replace("SELFTEST-PRE", "")
-
- # The switch to recipe-specific-sysroots during the Pyro release forced us
- # to change how we build the native dependencies for wic and introduce
- # wic-tools. As we've traditionally made efforts in the AB to not break
- # existing buildset we should handle both wic-tools and the full list
- # of native dependencies correctly.
- wicNativeDeps = ("syslinux syslinux-native parted-native "
- "gptfdisk-native dosfstools-native mtools-native")
- if self.layerversion_core > 9:
- self.images = self.images.replace(wicNativeDeps, "wic-tools")
- else:
- self.images = self.images.replace("wic-tools", wicNativeDeps)
-
- if "minnow" in self.machine:
-
- if self.minnowExists is "False":
- self.skipStep("Minnowboard layer does not build for 1.8")
-
- '''
- Various images/builds/features do not work in earlier versions of
- oe-core/other layers. This excludes certain builds from building.
-
- While we could do something like:
-
- if <some condition is met>:
- self.finished(SUCCESS)
- self.description = ["Skipping Build"]
- self.build.allStepsDone()
-
- we really don't want to do this as other bits later in the build
- set may in fact be needed.
- '''
- if self.layerversion_core > 7 \
- and "adt-installer" in self.images:
- self.skipStep('Skipping adt-installer.')
- elif self.layerversion_core < 8 \
- and 'DISTRO_FEATURES_remove="x11"' in self.localconf.replace(" ", ""):
- self.skipStep('Skipping no-x11 Build.')
- elif self.layerversion_core != 8 \
- and 'uclibc' in self.localconf:
- self.skipStep('Skipping uclib Build.')
- elif self.layerversion_core < 8 \
- and 'musl' in self.localconf:
- self.skipStep('Skipping musl Build.')
- elif self.layerversion_core < 7 \
- and "populate_sdk_ext" in self.images:
- self.skipStep('Skipping eSDK Build.')
- elif self.layerversion_yoctobsp < 2 \
- and self.machine == "genericx86-64":
- self.skipStep("Skipping genericx86-64 Build")
- elif self.images == "":
- self.skipStep("Skipping Build. No Images to be built")
- else:
- bitbakeflags = "-k "
- if self.create_eventlog == "True":
- bitbakeflags += "-w '" + self.eventlog_name + "' "
- if self.minnowExists is None or self.minnowExists == "True":
- self.command = env + ". ./" + self.oeinit + "; bitbake " + bitbakeflags + self.images
- self.description = ["Building " + str(self.images)]
-
- self.setProperty("BuildImages", self.images, "BuildImages")
-
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self, done)
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/BuildToolchainImages.py b/lib/python2.7/site-packages/autobuilder/buildsteps/BuildToolchainImages.py
deleted file mode 100644
index 37725e78..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/BuildToolchainImages.py
+++ /dev/null
@@ -1,53 +0,0 @@
-'''
-Created on Jan 6, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-import os
-
-from lib.buildsteps import BitbakeShellCommand
-
-class BuildToolchainImages(BitbakeShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Building Toolchain Images"
- def __init__(self, factory, argdict=None, **kwargs):
- self.images=""
- self._pendingLogObservers = []
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
-
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- super(BuildToolchainImages, self).__init__(factory, argdict=None,
- **kwargs)
-
- def start(self):
- layerversion = int(self.getProperty("layerversion_core", "0"))
- if self.images is not "":
- self.description = ["Building " + self.images +" -c populate_sdk"]
- self.command = ". ./oe-init-build-env; bitbake " + self.images + " -c populate_sdk"
- else:
- if layerversion > 1:
- self.description = ["Building core-image-sato -c populate_sdk"]
- self.command = ". ./oe-init-build-env; bitbake core-image-sato -c populate_sdk"
- else:
- self.description = ["Building meta-toolchain-gmae"]
- self.command = ". ./oe-init-build-env; bitbake meta-toolchain-gmae"
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckBSPExists.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckBSPExists.py
deleted file mode 100644
index b46a263c..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckBSPExists.py
+++ /dev/null
@@ -1,74 +0,0 @@
-'''
-Created on March 18th, 2014
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from buildbot.process.buildstep import BuildStep, LoggingBuildStep
-from buildbot.process.build import Build
-from buildbot.status.results import SUCCESS
-from buildbot.process.properties import WithProperties
-from twisted.python import log
-from autobuilder.config import *
-
-class CheckBSPExists(LoggingBuildStep):
- haltOnFailure = False
- flunkOnFailure = False
- name = "Check BSP Exists"
- def __init__(self, factory, argdict=None, **kwargs):
- self.description = "Check if BSP Exists"
- self.layerversion_intel = None
- self.buildername = None
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- LoggingBuildStep.__init__(self, **kwargs)
-
- def start(self):
- # layerversion_metaintel values:
- # 1: removed: chiefriver
- # sys940x
- # n450
- # 2: removed: fri2
- # crownbay
- # emenlow
- # 3: removed: jasperforest
- # sugarbay
- # nuc
- self.layerversion_intel = int(self.getProperty("layerversion_intel", "0"))
- self.buildername = self.getProperty("buildername")
- if 'n450' in self.buildername or 'chiefriver' in self.buildername or \
- 'sys940' in self.buildername:
- if self.layerversion_intel is not None and \
- int(self.layerversion_intel) >= 1:
- self.finished(SUCCESS)
- self.build.allStepsDone()
- else:
- self.finished(SUCCESS)
- elif 'fri2' in self.buildername or 'crownbay' in self.buildername or \
- 'emenlow' in self.buildername:
- if self.layerversion_intel >= 2:
- self.finished(SUCCESS)
- self.build.allStepsDone()
- else:
- self.finished(SUCCESS)
- elif 'jasperforest' in self.buildername \
- or 'sugarbay' in self.buildername or 'nuc' in self.buildername:
- if self.layerversion_intel >= 3:
- self.finished(SUCCESS)
- self.build.allStepsDone()
- else:
- self.finished(SUCCESS)
- else:
- self.finished(SUCCESS)
-
- def describe(self, done=False):
- description = LoggingBuildStep.describe(self, done)
- if self.layerversion_intel is not None and self > "1":
- description = "This BSP exists in the branch. Building."
- else:
- description = "This BSP does not exists in the branch. Skipping."
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForGPLv3.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForGPLv3.py
deleted file mode 100644
index 591fd94d..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForGPLv3.py
+++ /dev/null
@@ -1,50 +0,0 @@
-'''
-Created on June 17th, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-
-class CheckForGPLv3(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CheckForGPLv3"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.command = 'for x in `find ./build/tmp/deploy/licenses -name "license.manifest"`; do cat $x|grep -E "GPLv3|GPL-3"; done'
- self.description = ["Checking to ensure no GPLv3 packages"]
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- result = cmd.logs['stdio'].getText()
- hasGPLv3 = ""
- try:
- hasGPLv3 = result.split()[-1]
- except:
- self.setProperty('hasGPLv3', "False", "No GPLv3, we're ok.")
- self.finished(SUCCESS)
- if "|" in result:
- self.setProperty('hasGPLv3', "True", "A license may be dual licensed as GPLv3")
- self.description = ["A license may be dual licensed as GPLv3"]
- self.finished(SUCCESS)
- else:
- self.setProperty('hasGPLv3', "True", "GPLv3, Fail out.")
- self.finished(FAILURE)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForMinnow.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForMinnow.py
deleted file mode 100644
index 994f4414..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForMinnow.py
+++ /dev/null
@@ -1,50 +0,0 @@
-'''
-Created on Feb 24, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from buildbot.status.results import SUCCESS, SKIPPED
-
-class CheckForMinnow(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CheckForMinnow"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- # minnowboard breaks, right about here
- self.command = "git log --pretty=format:'%H' |grep 19e06e6584ab2aa31709bcf8fe7b566cafd297e7"
- self.description = ["Checking for working minnowboard"]
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- result = cmd.logs['stdio'].getText()
- minnowExists = ""
- try:
- minnowExists = result.split()[-1]
- except:
- self.setProperty('minnowExists', "True", "Minnowboard Builds.")
- self.finished(SUCCESS)
- if minnowExists == "19e06e6584ab2aa31709bcf8fe7b566cafd297e7":
- self.setProperty('minnowExists', "False", "Minnowboard Does Not Build.")
- self.finished(SUCCESS)
- self.build.allStepsDone()
-
- def getText(self, cmd, results):
- return ShellCommand.getText(self, cmd, results)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForWorldLsb.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForWorldLsb.py
deleted file mode 100644
index 97b73992..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckForWorldLsb.py
+++ /dev/null
@@ -1,51 +0,0 @@
-'''
-Created on May 1st, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from buildbot.status.results import SUCCESS, SKIPPED
-
-class CheckForWorldLsb(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CheckForWorldLsb"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- # world-lsb works, right about here
- self.command = "git log --pretty=format:'%H' |grep db409697db2ea0931cdcd2015d089b6b0ea39bbb"
- self.description = ["Checking for working world-lsb"]
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- result = cmd.logs['stdio'].getText()
- worldLSBExists = ""
- try:
- worldLSBExists = result.split()[-1]
- except:
- self.setProperty('worldLSBExists', "False", "World LSB Does Not Build.")
- self.finished(SUCCESS)
- self.build.allStepsDone()
-
- if worldLSBExists == "db409697db2ea0931cdcd2015d089b6b0ea39bbb":
- self.setProperty('worldLSBExists', "True", "World LSB Builds.")
- self.finished(SUCCESS)
-
- def getText(self, cmd, results):
- return ShellCommand.getText(self, cmd, results)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py
deleted file mode 100644
index b3278625..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-#
-#
-'''
-Created on Jan 14, 2012
-
-__copyright__ = "Copyright Buildbot Team Members"
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from twisted.python import log
-from twisted.internet import defer
-
-import os
-from buildbot.steps.source.yoctogit import YoctoGit
-from buildbot import config
-from buildbot.status import build
-from buildbot.process import buildstep
-
-class CheckOutLayers(YoctoGit):
- def __init__(self, factory, scheduler=None, layername=None, mode='full', storedir=None, mirrordir=None,
- method='clobber', submodules=False, shallow=False, workdir='build',
- timeout=100000, progress=True, retryFetch=True, clobberOnFailure=False,
- getDescription=True, argdict=None,
- **kwargs):
- self.scheduler = scheduler
- self.workdir=workdir
- self.branch = ""
- self.commit = ""
- self.method = method
- self.prog = progress
- self.repourl = ""
- self.retryFetch = retryFetch
- self.submodules = submodules
- self.shallow = shallow
- self.storedir=storedir
- self.mirrordir=mirrordir
- self.fetchcount = 0
- self.clobberOnFailure = clobberOnFailure
- self.mode = mode
- self.timeout = 100000
- self.getDescription = getDescription
- self.layername = layername
- self.name="Git checkout of " + layername
- kwargs['timeout']=self.timeout
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- YoctoGit.__init__(self, repourl=self.repourl, branch=self.branch, mode=self.mode,
- method=self.method, storedir=self.storedir, mirrordir=mirrordir, submodules=self.submodules,
- workdir=self.workdir, shallow=self.shallow, progress=self.progress,
- retryFetch=self.retryFetch, clobberOnFailure=self.clobberOnFailure,
- getDescription=self.getDescription, layername=self.layername, **kwargs)
-
- def startVC(self, branch, revision, patch):
- if self.getProperty('branch_'+self.layername):
- self.branch = self.getProperty('branch_'+self.layername)
- else:
- self.branch = "master"
- if self.getProperty('repo_'+self.layername):
- self.repourl = self.getProperty('repo_'+self.layername)
- else:
- self.repourl = "git://git.yoctoproject.org/poky"
-
- if self.getProperty('commit_'+self.layername) == "HEAD" and \
- self.getProperty('commit_resolvedhead_'+self.layername) is not None:
- log.msg("Using Resolved HEAD")
- self.commit = self.getProperty('commit_resolvedhead_'+self.layername)
- elif self.getProperty('commit_'+self.layername):
- self.commit = self.getProperty('commit_'+self.layername)
- else:
- self.commit = "HEAD"
-
- self.setProperty('repourl_' + self.layername, self.repourl, "CheckOutLayers")
- self.setProperty('branch_' + self.layername, self.branch, "CheckOutLayers")
- self.setProperty('commit_' + self.layername, self.commit, "CheckOutLayers")
-
- # Store non-core (and non-eclipse) layer names in a variable for use
- # by other buildsteps
- if self.layername not in ["poky", "oecore", "eclipse", "bitbake"]:
- layers = self.getProperty('cloned_layers', default='')
- if len(layers) == 0:
- layers = self.layername
- else:
- layers = layers + ' ' + self.layername
- self.setProperty("cloned_layers", layers, "CheckOutLayers")
-
- if self.layername == "poky" or self.layername == "oecore" or "eclipse" in self.layername:
- self.setProperty('repository', self.repourl, "CheckOutLayers")
- self.setProperty('branch', self.branch, "CheckOutLayers")
- self.setProperty('revision', self.commit, "CheckOutLayers")
- YoctoGit.startVC(self, branch=self.branch, patch=None, revision=self.commit)
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _=None):
- self.workdir = "source/" + self.repourl
- stdout = yield self._dovccmd(['rev-parse', self.commit], collectStdout=True)
- revision = stdout.strip()
- if len(revision) != 40:
- raise buildstep.BuildStepFailed()
- if self.layername == "poky":
- self.updateSourceProperty('got_revision', revision)
- self.updateSourceProperty('got_revision_' + self.layername, revision)
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutToasterLayers.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutToasterLayers.py
deleted file mode 100644
index a45dd67c..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutToasterLayers.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-#
-#
-'''
-Created on Jun 15, 2015
-
-__copyright__ = "Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from twisted.python import log
-from twisted.internet import defer
-
-import os, ast
-from buildbot.steps.source.yoctogit import YoctoGit
-from buildbot.steps.shell import ShellCommand
-from buildbot import config
-from buildbot.status import build
-from buildbot.process import buildstep
-
-class CheckOutToasterLayers(ShellCommand):
- def __init__(self, factory, argdict=None, **kwargs):
- self.workdir=""
- self.branch = ""
- self.commit = ""
- self.repourl = ""
- self.timeout = 100000
- self.description = "Git Checkout of Toaster Layers:"
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- _layers = ast.literal_eval(self.getProperty('custom_layers'))
- fout=""
- for layer in _layers:
- layername=layer.iterkeys().next()
- repo=layer[layer.iterkeys().next()]['repourl']
- branch=layer[layer.iterkeys().next()]['branch']
- #commit=layer[layer.iterkeys().next()]['commit']
- storedir=None
- mirrordir=None
- method = 'clobber'
- mode='full'
- self.workdir=""
- self.description+="/n" + layername + "/n"
- if 'poky' in layername or 'oecore' in layername:
- workdir = 'build'
- else:
- workdir="build/" + layername
- log.msg(layer)
- fout += "mkdir -p "+ workdir +"; cd " + workdir + "; git clone " + repo + " .;git checkout" + branch +"; cd $BASEBUILDDIR;"
- self.command = ["sh", "-c", "BASEBUILDDIR=`pwd`; rm -rf build;" + fout]
- ShellCommand.start(self)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckYoctoCompat.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CheckYoctoCompat.py
deleted file mode 100644
index 0eca5287..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CheckYoctoCompat.py
+++ /dev/null
@@ -1,56 +0,0 @@
-'''
-Created on Sep 07, 2017
-
-__author__ = "Joshua Lock"
-__copyright__ = "Copyright 2017, Intel Corp."
-__credits__ = ["Joshua Lock"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Joshua Lock"
-__email__ = "joshua.g.lock@intel.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from autobuilder.config import *
-import os
-
-from lib.buildsteps import BitbakeShellCommand
-
-
-class CheckYoctoCompat(BitbakeShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CheckYoctoCompat"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self._pendingLogObservers = []
- self.layers = []
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout'] = self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- if not self.layers:
- self.layers = self.getProperty("cloned_layers", "").split()
-
- builddir = os.path.join(self.getProperty("builddir"), "build")
-
- layerversioncore = int(self.getProperty("layerversion_core", "0"))
- # yocto-check-layer-wrapper was introduced with Rocko
- if layerversioncore >= 11:
- command = ". ./oe-init-build-env;"
- for layer in self.layers:
- layerpath = os.path.join(builddir, layer)
- cmd = "yocto-check-layer-wrapper {}".format(layerpath)
- cmd = cmd + " || export CL_FAIL=1;"
- command = command + cmd
- command = command + 'if [ "$CL_FAIL" = "1" ]; then exit 1; fi;'
- self.command = command
- else:
- self.skipStep('Skipping step for older versions.')
-
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py
deleted file mode 100644
index b7f758bb..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py
+++ /dev/null
@@ -1,361 +0,0 @@
-'''
-Created on Dec 26, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-import os
-from twisted.python import log
-import ast, json
-from buildbot.status.results import FAILURE
-
-class CreateAutoConf(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CreateAutoConf"
- def __init__(self, factory, argdict=None, **kwargs):
- self.machine=""
- self.buildapp=""
- self.distro="poky"
- self.packages=None
- self.buildhistory=False
- self.gplv3=True
- self.multilib=False
- self.swabber=False
- self.x32=False
- self.atext=None
- self.emgd=False
- self.pvr=False
- self.atextprepend=None
- self.atextappend=None
- self.SDKMACHINE="i686"
- self.adtdev=False
- self.factory = factory
- self.buildappsrcrev = "${AUTOREV}"
- self.initmgr=None
- self.nosstate=False
- self.kwargs = kwargs
- self.devkernel = True
- self.tmpdir = None
- self.prserv = True
- self.lockedsigs = False
- self.buildinfo = False
- self.autoconfpath = "./build/conf/auto.conf"
- self.sdkconfpath = "./build/conf/sdk-extra.conf"
- self.rmautoconf = "True"
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- self.description = "Create Auto Configuration"
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- buildername=self.getProperty("buildername")
- buildername=self.getProperty("devkernel")
- distroversion=self.getProperty("distroversion")
- layerversion = int(self.getProperty("layerversion_yoctobsp", "0"))
- layerversioncore = int(self.getProperty("layerversion_core", "0"))
- branch=self.getProperty("branch")
- sstatemirror = os.environ.get('SSTATE_MIRROR_BASE')
- release = False
- sstate_release_number = ""
-
- release_me = self.getProperty("custom_release_me", "None")
- if release_me != 'None':
- self.setProperty('is_release', release_me, "CreateAutoConf")
-
- release = (self.getProperty("is_release") == "True")
- if release:
- sstate_release_number = self.get_release_number()
-
- if release and sstate_release_number == "":
- self.step_status.setText(["Release build requested without release number."])
- self.finished(FAILURE)
- return None
- elif release and sstate_release_number:
- sstatemirror = "%s/%s" % (sstatemirror, sstate_release_number)
-
- self.setProperty('DISTRO', self.distro, "Setting DISTRO", "CreateAutoConf")
- self.command = ""
- fout = ""
- if self.rmautoconf == "True":
- self.command += "rm -rf %s;" % self.autoconfpath
- self.command += "rm -rf %s;" % self.sdkconfpath
- #check to see if we have a prepend
- if self.atextprepend:
- fout = fout +"\n"+ self.atextprepend
- #check to see if we have text override
- if self.atext == "#TOASTER":
- fout = fout+"\n"+self.getProperty("custom_atext")
- elif self.atext != "#TOASTER" and self.atext is not None:
- fout = fout+"\n"+self.atext
- else:
-
- if os.environ.get('ERROR_REPORT_COLLECT', 'False') == "True":
- fout += 'INHERIT += "report-error"\n'
- if self.distro != "oecore":
- fout = fout + 'DISTRO = "' + self.distro + '"\n'
- if self.tmpdir:
- if self.tmpdir.startswith('/'):
- fout = fout + 'TMPDIR = "' + self.tmpdir + '"\n'
- else:
- fout = fout + 'TMPDIR = "${TOPDIR}/' + self.tmpdir + '"\n'
- if self.packages:
- self.classes = [ "package_%s" % p for p in self.packages.split() ]
- fout = fout + 'PACKAGE_CLASSES = "' + " ".join(self.classes) + '"\n'
- else:
- fout = fout + 'PACKAGE_CLASSES = "package_rpm package_deb package_ipk"\n'
- repo=self.getProperty("repository")
- if os.environ.get('DEVKERNEL_MUT_REPO') is not None:
- mut_repos=ast.literal_eval(os.environ.get('DEVKERNEL_MUT_REPO').encode('utf-8'))
- if mut_repos is not None and repo in mut_repos.keys():
- if self.getProperty("branch") in mut_repos[self.getProperty("repository")] and self.devkernel is not "False":
- fout = fout + 'PREFERRED_PROVIDER_virtual/kernel = "' + os.environ.get('DEVKERNEL') + '"\n'
- elif self.getProperty("custom_prefered_kernel") is not None:
- fout = fout + 'PREFERRED_PROVIDER_virtual/kernel = "' + self.getProperty("custom_prefered_kernel") +'"\n'
- fout = fout + 'BB_NUMBER_THREADS = "' + os.environ.get('BB_NUMBER_THREADS') + '"\n'
-
- # We renamed this variable to prevent it affecting OE
- # configurations where the OE setting of the same name
- # has a weak assignment. In order to be less brittle to
- # changes in the config we try and read the old variable
- # when the new variable isn't set.
- pmakenum = os.environ.get('PARALLEL_MAKE_NUM')
- if not pmakenum:
- pmakenum = os.environ.get('PARALLEL_MAKE')
- fout = fout + 'PARALLEL_MAKE = "-j ' + pmakenum + '"\n'
- fout = fout + 'SDKMACHINE ?= "' + self.SDKMACHINE + '"\n'
- if os.environ.get('IMAGE_FSTYPES'):
- fout = fout + 'IMAGE_FSTYPES_append = " ' + os.environ.get('IMAGE_FSTYPES') +'"\n'
- if os.environ.get('TMP_DIR'):
- fout = fout + 'TMPDIR = "' + os.environ.get('TMP_DIR') + '"\n'
- fout = fout + 'BB_TASK_NICE_LEVEL = "5"\n'
- fout = fout + 'BB_TASK_NICE_LEVEL_task-testimage = "0"\n'
- fout = fout + 'BB_TASK_IONICE_LEVEL = "2.7"\n'
- fout = fout + 'BB_TASK_IONICE_LEVEL_task-testimage = "2.1"\n'
- buildprops = self.getProperties().asDict()
- for k, v in buildprops.iteritems():
- if "buildappsrcrev" in k:
- self.buildappsrcrev=v[0]
- if self.buildapp == "True":
- if self.buildappsrcrev == "AUTOREV":
- self.buildappsrcrev="${AUTOREV}"
- fout = fout + 'DL_DIR ?= "${TOPDIR}/downloads"\n'
- fout = fout + 'INHERIT += "own-mirrors"\n'
- fout = fout + 'SOURCE_MIRROR_URL = "file:///' + os.environ.get('DL_DIR') +'"\n'
- if self.buildappsrcrev != "DEFAULT":
- fout = fout + 'SRCREV_pn-build-appliance-image = "' + self.buildappsrcrev + '"\n'
- fout = fout + 'PV_append_pn-build-appliance-image = "+git${SRCPV}"\n'
- else:
- fout = fout + 'DL_DIR = "' + os.environ.get('DL_DIR')+'"\n'
- if self.emgd == "True":
- fout = fout + 'LICENSE_FLAGS_WHITELIST += "license_emgd-driver-bin" \n'
- if self.pvr == "True":
- fout = fout + 'LICENSE_FLAGS_WHITELIST += "license_cdv-pvr-driver" \n'
- fout = fout + 'PVR_LICENSE = "yes" \n'
- if self.multilib and self.multilib != "False":
- if self.multilib == "True" or self.multilib == "lib32":
- fout = fout + 'require conf/multilib.conf \n'
- fout = fout + 'MULTILIBS = "multilib:lib32" \n'
- fout = fout + 'DEFAULTTUNE_virtclass-multilib-lib32 = "x86" \n'
- elif self.multilib == "lib64":
- fout = fout + 'require conf/multilib.conf \n'
- fout = fout + 'MULTILIBS = "multilib:lib64" \n'
- fout = fout + 'DEFAULTTUNE_virtclass-multilib-lib64 = "x86-64" \n'
- if not self.nosstate:
- sstatedir = os.environ.get("SSTATE_DIR")
- if release:
- # Use a separate SSTATE_DIR with the primary
- # SSTATE_DIR configured as a mirror so that we
- # have a directory of symlinks to sstate objects
- # that can be published for the release
- fout = fout + 'SSTATE_MIRRORS += "file://.* file://%s/PATH"\n' % sstatedir
- pubdir = os.environ.get("SSTATE_RELEASE_DIR")
- if pubdir:
- sstatedir = pubdir + '/' + sstate_release_number
- fout = fout + 'SSTATE_DIR ?= "' + sstatedir + '/" \n'
-
- if self.gplv3 == "False":
- fout = fout + 'INCOMPATIBLE_LICENSE = "*GPLv3" \n'
- if self.x32 == "True":
- fout = fout + 'DEFAULTTUNE = "x86-64-x32"\n'
- fout = fout + 'baselib = \\042${@d.getVar(\\047BASE_LIB_tune-\\047 + (d.getVar(\\047DEFAULTTUNE\\047, True) or \\047INVALID\\047), True) or \\047lib\\047}\\042 \n'
- if self.distro == "poky-rt":
- fout = fout + 'PREFERRED_PROVIDER_virtual/kernel="linux-yocto-rt" \n'
- machine=self.getProperty('custom_machine')
- if machine:
- self.machine = machine
- else:
- machine = self.machine
- if self.machine == "atom-pc":
- machine = self.machine.replace("atom-pc", "genericx86")
- if self.machine == "beagleboard":
- machine = self.machine.replace("beagleboard", "beaglebone")
- # NOTE: this is the reverse of how we'd usually do this, but we do
- # not want to break support for using meta-ti with yocto-autobuilder
- if self.machine == "beaglebone-yocto" and layerversion < 4:
- machine = self.machine.replace("beaglebone-yocto", "beaglebone")
- if self.machine == "routerstationpro":
- machine = self.machine.replace("routerstationpro", "edgerouter")
-
- self.setProperty('MACHINE', machine, "Setting Layer Version")
- fout = fout + 'MACHINE = "' + machine + '"\n'
- fout = fout + 'PREMIRRORS = ""\n'
- if "imx" in self.machine and "danny" in self.getProperty("branch_poky"):
- fout = fout + 'BBMASK = "udev_.*\.bbappend$"\n'
- if self.swabber == "True":
- fout = fout + 'USER_CLASSES += "image-prelink image-swab"\n'
- if os.environ.get("PUBLISH_SOURCE_MIRROR") == "True":
- fout = fout + 'BB_GENERATE_MIRROR_TARBALLS = "1"\n'
- if self.distro == "oecore":
- fout = fout + 'INHERIT += "uninative"\n'
- fout = fout + 'require conf/distro/include/yocto-uninative.inc\n'
-
-# Setup buildhistory
-# We only collect for the whitelisted repo/branch combinations. This keeps
-# us from having a trashed history from "junk" builds (MUTs/release branches/etc)
-
- if self.buildhistory == "True" and os.environ.get("BUILD_HISTORY_COLLECT") == "True":
-
- if os.environ.get('BUILD_HISTORY_WHITELIST') is not None or \
- os.environ.get('BUILD_HISTORY_THROWAWAY_WHITELIST') is not None:
- ta_history_repos={}
- history_repos={}
- fout = fout + 'ERROR_QA_remove = "version-going-backwards"\n'
- if os.environ.get('BUILD_HISTORY_THROWAWAY_WHITELIST') is not None:
- ta_history_repos=ast.literal_eval(os.environ.get('BUILD_HISTORY_THROWAWAY_WHITELIST').encode('utf-8'))
- if os.environ.get('BUILD_HISTORY_WHITELIST') is not None:
- history_repos=ast.literal_eval(os.environ.get('BUILD_HISTORY_WHITELIST').encode('utf-8'))
- if repo in history_repos.keys() and \
- self.getProperty("branch") in history_repos[self.getProperty("repository")]:
- # We keep this build history
- self.setProperty('KEEP_BUILD_HIST', "True", "Keeping Buildhistory")
- elif repo in ta_history_repos.keys() and \
- self.getProperty("branch") in ta_history_repos[self.getProperty("repository")]:
- # We toss the prior version of this build history
- self.setProperty('KEEP_BUILD_HIST', "False", "Temp Buildhistory")
-
- if self.getProperty("KEEP_BUILD_HIST"):
- fout += 'INHERIT += "buildhistory"\n'
- fout += 'BUILDHISTORY_COMMIT = "1"\n'
- bh_path = repo.split('/')[-1] + '/' + \
- self.getProperty("branch") + '/' + \
- self.getProperty("buildername")
-
- bh_repo_dir = os.environ.get('BUILD_HISTORY_DIR') + '/' + bh_path
-
- fout += 'BUILDHISTORY_DIR = "' + bh_repo_dir + '"\n'
- fout += 'BUILDHISTORY_PUSH_REPO = "' + os.environ.get('BUILD_HISTORY_REPO') + ' ' + \
- bh_path + ':' + bh_path + '"\n'
-
- #toaster can only be run on whitelisted branches.
- if os.environ.get('TOASTER_UPLOAD_URL', None) is not None:
- fout += 'INHERIT += "toaster"\n'
- self.command += "pwd=`pwd`;"
-
- # Check if the local git clone dir exists
- # If it doesn't create it and then init it
- self.command += "if [ ! -d " + bh_repo_dir +" ];"
- self.command += "then mkdir -p " + bh_repo_dir +";"
- self.command += "git init " + bh_repo_dir +"; fi;"
-
- # If we're tossing away the history, do it now.
- if self.getProperty("KEEP_BUILD_HIST") is "False":
- self.command += "rm -rf " + bh_repo_dir +";"
- self.command += "mkdir -p " + bh_repo_dir +";"
- self.command += "git init " + bh_repo_dir +";"
- # We only try and delete the remote if it exists
- self.command += "if git ls-remote --exit-code " + os.environ.get('BUILD_HISTORY_REPO') + \
- " refs/heads/" + bh_path + "> /dev/null;"
- self.command += "then git push -q " + os.environ.get('BUILD_HISTORY_REPO') + \
- " :" + bh_path + ";fi;"
-
- # Check if the remote exists
- # If it doesn't create it and then push
- self.command += "if ! git ls-remote --exit-code " + os.environ.get('BUILD_HISTORY_REPO') + \
- " refs/heads/" + bh_path + " > /dev/null;"
- self.command += "then cd " + bh_repo_dir +"; echo 'Initializing Repo' >> README;" + \
- "git checkout -b " + bh_path + ";git add README; git commit -s -m 'Initializing Repo';"
- self.command += "git push -q " + os.environ.get('BUILD_HISTORY_REPO') + \
- " " + bh_path + ":" + bh_path +";fi;"
- self.command += "cd $pwd;"
-
- if self.prserv != "False":
- prserv_host = os.environ.get('PRSERV_HOST', None)
- prserv_port = os.environ.get('PRSERV_PORT', None)
- if prserv_host and prserv_port:
- fout += 'PRSERV_HOST = "%s:%s"\n' % (prserv_host, prserv_port)
-
- # using locked-sigs whilst generating an eSDK is only
- # supported on pyro or newer
- if layerversioncore > 9 and self.lockedsigs:
- fout += 'require ../locked-sigs.inc\n'
-
- if self.buildinfo:
- fout += 'INHERIT += "image-buildinfo"\n'
- fout += 'IMAGE_BUILDINFO_VARS_append = " IMAGE_BASENAME IMAGE_NAME"\n'
-
- if self.getProperty("branch_poky"):
- if "danny" not in self.getProperty("branch_poky") and distroversion is not None:
- if self.adtdev == "True":
- adtrepo_url=os.environ.get("ADTREPO_DEV_URL")
- fout=fout+'ADTREPO = "' + adtrepo_url + '/' + self.getProperty("distroversion") + '-' + self.getProperty("got_revision_poky") + '-' + self.getProperty("branch_poky") + '"\n'
- else:
- adtrepo_url=os.environ.get("ADTREPO_URL")
- fout=fout+'ADTREPO = "' + adtrepo_url + '/' + self.getProperty("distroversion") + '"\n'
- if self.initmgr and "danny" not in self.getProperty("branch_poky"):
- # we don't neet to test sysvinit only, because that's the default
- if self.initmgr == "systemd":
- fout = fout + 'DISTRO_FEATURES_append = " systemd"\n'
- fout = fout + 'VIRTUAL-RUNTIME_init_manager = "systemd"\n'
- fout = fout + 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n'
- if self.initmgr == "systemd sysvinit":
- fout = fout + 'DISTRO_FEATURES_append = " systemd"\n'
- fout = fout + 'VIRTUAL-RUNTIME_init_manager = "systemd"\n'
- if self.initmgr == "sysvinit systemd":
- fout = fout + 'DISTRO_FEATURES_append = " systemd"\n'
- fout = fout + 'VIRTUAL-RUNTIME_init_manager = "sysvinit"\n'
- if os.environ.get("QEMU_USE_KVM") == "True":
- fout = fout + 'QEMU_USE_KVM = "True"\n'
-
- sout = ''
- # for pyro or newer when SSTATE_MIRROR_BASE is defined build a
- # minimal eSDK and point SSTATE_MIRRORS at the shared state mirror
- if sstatemirror and layerversioncore > 9:
- sout = 'SSTATE_MIRRORS += "\\ \\n '
- sout = sout + 'file://.* %s/PATH;downloadfilename=PATH"\n' % sstatemirror
- fout = fout + 'SDK_EXT_TYPE = "minimal"\n'
- fout = fout + 'SDK_INCLUDE_TOOLCHAIN = "1"\n'
-
- # The SANITY_TESTED_DISTROS values in meta-poky can easily
- # fall out of sync with the host OS on the AB workers.
- fout = fout + 'SANITY_TESTED_DISTROS = ""\n'
-
- # the append text should be the last thing added to the fout string so
- # that we are appending this as the final item in the generated
- # auto.conf
- if self.atextappend:
- fout = fout + self.atextappend
-
- self.setProperty("LOCALCONF", fout, "CreateAutoConf")
- self.command += "printf '" + fout + "'>> " + self.autoconfpath
- if sout:
- self.command += "; printf '" + sout + "' >> " + self.sdkconfpath
-
- ShellCommand.start(self)
-
- def get_release_number(self):
- release_number = self.getProperty("custom_yocto_number", "")
- if not release_number:
- return ""
- release_components = release_number.split('.', 3)
- return '.'.join(release_components).strip('.')
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateBBLayersConf.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CreateBBLayersConf.py
deleted file mode 100644
index 593b9ee3..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateBBLayersConf.py
+++ /dev/null
@@ -1,124 +0,0 @@
-'''
-Created on Dec 26, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-
-class CreateBBLayersConf(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Create BBLayers Configuration"
- def __init__(self, factory, layers, argdict=None, **kwargs):
- self.factory = factory
- self.layers=layers
- self.buildprovider="yocto"
- self.bsplayer=False
- self.bspprovider=""
- self.x32abi=False
- self.bbtext=""
- self.bbtextprepend=""
- self.bbtextappend=""
- self.layerdirs=""
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Create BBLayers Configuration"
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- import os
- fout = ""
- buildername=self.getProperty("buildername")
- branch=self.getProperty("branch")
- workdir=self.getProperty("workdir")
- layerversioncore = int(self.getProperty("layerversion_core", "0"))
- layerversionyocto = int(self.getProperty("layerversion_yocto", "0"))
- if self.bbtextprepend != "":
- fout = fout +"\n"+self.bbtextprepend
- if self.bbtext:
- if self.bbtext == "#TOASTER":
- fout = fout+"\n"+self.getProperty("custom_bbtext")
- else:
- fout = fout+"\n"+self.bbtext #check to see if we have a prepend
- #check to see if we have text override
- self.command = "rm -rf ./build/conf/bblayers.conf; echo '" + fout + "'>> ./build/conf/bblayers.conf"
- self.setProperty("BBLAYERS", fout)
- ShellCommand.start(self)
- else:
- if self.buildprovider == "yocto" and layerversionyocto > 2:
- fout = fout + 'POKY_BBLAYERS_CONF_VERSION = <PCONF> \n'
- self.command = "PCONF=`cat ./build/conf/bblayers.conf| grep \"POKY_BBLAYERS_CONF_VERSION =\"|cut -d'=' -f2|tr -d '[:space:]'`;"
- else:
- fout = fout + 'LCONF_VERSION = <LCONF> \n'
- self.command = "LCONF=`cat ./build/conf/bblayers.conf| grep \"LCONF_VERSION =\"|cut -d'=' -f2|tr -d '[:space:]'`;"
- fout = fout + 'BBPATH = "${TOPDIR}" \n'
- fout = fout + 'BBFILES ?="" \n'
- fout = fout + 'BBLAYERS += " \ \n'
- ldirs = ['poky', 'oecore', 'bitbake']
- if self.buildprovider == "yocto":
- if layerversionyocto > 2:
- fout = fout + workdir + "/build/meta \ \n"
- fout = fout + workdir + "/build/meta-poky \ \n"
- fout = fout + workdir + "/build/meta-yocto-bsp \ \n"
- ldirs.append("meta")
- ldirs.append("meta-poky")
- ldirs.append("meta-yocto-bsp")
- else:
- fout = fout + workdir + "/build/meta \ \n"
- fout = fout + workdir + "/build/meta-yocto \ \n"
- fout = fout + workdir + "/build/meta-yocto-bsp \ \n"
- ldirs.append("meta")
- ldirs.append("meta-yocto")
- ldirs.append("meta-yocto-bsp")
- if self.x32abi == True:
- fout = fout + workdir + '/build/meta-x32 \ \n'
- ldirs.append("meta-x32")
- elif self.buildprovider == "oe":
- fout = fout + workdir + "/build/meta \ \n"
- ldirs.append("meta")
- for layer in self.layers:
- if layer.iterkeys().next() not in ldirs:
- if (layer[layer.iterkeys().next()].has_key('checkout') and layer[layer.iterkeys().next()]['checkout'] is not False) \
- or layer[layer.iterkeys().next()].has_key('checkout') is False:
- if layer.iterkeys().next()=="meta-qt3":
- if layerversioncore < 9:
- fout = fout + workdir + '/build/' + layer.iterkeys().next() + ' \ \n'
- elif layer.iterkeys().next()=="meta-qt4":
- if layerversioncore > 6 and layerversioncore < 11:
- fout = fout + workdir + '/build/' + layer.iterkeys().next() + ' \ \n'
- elif layer.iterkeys().next()=="meta-gplv2":
- # We only want meta-gplv2 for pyro or newer
- if layerversioncore > 9:
- fout = fout + workdir + '/build/' + layer.iterkeys().next() + ' \ \n'
- elif (layer[layer.iterkeys().next()].has_key('autoinclude') and layer[layer.iterkeys().next()]['autoinclude'] is not False) or \
- layer[layer.iterkeys().next()].has_key('autoinclude') is False:
- fout = fout + workdir + '/build/' + layer.iterkeys().next() + ' \ \n'
- ldirs.append(layer.iterkeys().next())
-
- if list(self.layerdirs):
- for layer in self.layerdirs:
- if layer not in ldirs:
- fout = fout + workdir + '/build/' + layer + ' \ \n'
- ldirs.append(layer)
- fout = fout + '" \n'
- if self.bbtextappend != "":
- fout = fout + self.bbtextappend
- self.command += "rm -rf ./build/conf/bblayers.conf; echo '" + fout + "'>> ./build/conf/bblayers.conf;"
- if self.buildprovider == "yocto" and layerversionyocto > 2:
- self.command += "sed -i \"s/<PCONF>/$PCONF/\" ./build/conf/bblayers.conf"
- else:
- self.command += "sed -i \"s/<LCONF>/$LCONF/\" ./build/conf/bblayers.conf"
- self.setProperty("BBLAYERS", fout)
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateCurrentLink.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CreateCurrentLink.py
deleted file mode 100644
index b421b91b..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateCurrentLink.py
+++ /dev/null
@@ -1,50 +0,0 @@
-'''
-Created on Dec 26, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-
-class CreateCurrentLink(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CreateCurrentLink"
- def __init__(self, factory, argdict=None, **kwargs):
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Creating Current Link"
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.timeout = 100000
- self.workdir="build/build/tmp/deploy/"
- kwargs['timeout']=self.timeout
- kwargs['workdir']=self.workdir
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- import os
- try:
- self.deploycheck = self.getProperty('custom_deploy_artifacts')
- except:
- self.deploycheck = "True"
- if str(os.environ.get('PUBLISH_BUILDS')) == "True" and str(self.deploycheck) == "True":
- DEST=self.getProperty('DEST')
- self.command = "rm -rf " + DEST + "/../CURRENT; ln -s "+ DEST + " " + DEST+"/../CURRENT"
- else:
- self.command = "echo 'We will not be Publishing this build either because PUBLISH_BUILDS is False or this is a non-publish build'"
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
-
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateGPLTarball.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CreateGPLTarball.py
deleted file mode 100644
index 55b4e806..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateGPLTarball.py
+++ /dev/null
@@ -1,40 +0,0 @@
-'''
-Created on Dec 1, 2014
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2014, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-
-class CreateGPLTarball(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Create GPL Tarball"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Create the GPL tarballs for compliance"
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- if str(self.getProperty("custom_release_tarball")) == "True":
- self.command = 'if [ -d "./build/tmp/deploy/sources" ]; then tar cvf gpl_compliance.tar.bz2 ./build/tmp/deploy/sources; fi'
- else:
- self.command = 'echo "Skipping step"'
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateIntelBSPPackage.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CreateIntelBSPPackage.py
deleted file mode 100644
index 44cbcb93..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateIntelBSPPackage.py
+++ /dev/null
@@ -1,102 +0,0 @@
-'''
-Created on Mar 17, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-import os, datetime
-from autobuilder.config import *
-
-class CreateIntelBSPPackage(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Creating BSP Packages"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.machine = ""
- self.workerdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- self.description = "Creating BSP packages for " + self.machine + " tarball"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- DEST=self.getProperty("DEST")
- buildername=self.getProperty("buildername")
- revision=self.getProperty("got_revision_poky")
- is_milestone = self.getProperty("custom_is_milestone")
- milestone_number = self.getProperty("custom_milestone_number")
- rc_number = self.getProperty("custom_rc_number")
- snapshot = ""
-
- self.layerversion_intel = int(self.getProperty("layerversion_intel", "0"))
- self.buildername = self.getProperty("buildername")
-
- if 'n450' in self.buildername or 'chiefriver' in self.buildername or \
- 'sys940' in self.buildername:
- if self.layerversion_intel >= 1:
- self.finished(SUCCESS)
- self.build.allStepsDone()
- return None
- elif 'fri2' in self.buildername or 'crownbay' in self.buildername or \
- 'emenlow' in self.buildername:
- if self.layerversion_intel >= 2:
- self.finished(SUCCESS)
- self.build.allStepsDone()
- return None
- elif 'jasperforest' in self.buildername or 'sugarbay' in self.buildername or \
- 'nuc' in self.buildername:
- if self.layerversion_intel >= 3:
- self.finished(SUCCESS)
- self.build.allStepsDone()
- return None
-
- if str(self.getProperty("custom_release_me")) == "True":
- if is_milestone == "True":
- snapshot = milestone_number+"+snapshot"
- elif milestone_number is not None and rc_number is not None:
- snapshot = milestone_number+"."+rc_number
- else:
- snapshot = None
- prefix = snapshot
- poky_name = self.getProperty("custom_poky_name")+prefix
- poky_number = self.getProperty("custom_poky_number")+prefix
- yocto_number = self.getProperty("custom_yocto_number")+prefix
- revision = self.machine+'-'+ yocto_number
- self.basedir=os.path.join(self.workerdir, buildername)
- bsptardir = revision
- cmd = "mkdir -p " + bsptardir + "/meta-intel; cd " + bsptardir + "; rm -rf meta-intel;"
- cmd = cmd + "git clone " + self.getProperty("repourl_meta-intel") + " meta-intel;"
- cmd = cmd + "cd meta-intel; git checkout " + self.getProperty("got_revision_meta-intel")+";"
- # issue with buildbot choking on a find exec. figure this out later.
- cmd = cmd + "for x in `find . -name .git\*`; do rm -rf $x; done;"
- cmd = cmd + "for x in `/bin/ls|egrep -v '(common|tlk|conf|README|MAINT|meta-" + self.machine.replace("-noemgd", "").replace("-lsb", "") + ")'`; do rm -rf $x; done;"
- cmd = cmd + "mkdir -p ./meta-" + self.machine.replace("-noemgd", "").replace("-lsb", "") + "/binary;"
- cmd = cmd + "cp -RL " + DEST + "/machines/" + self.machine + "/core-image-sato-" + self.machine + ".hddimage ./meta-" + self.machine.replace("-noemgd", "").replace("-lsb", "") + "/binary;"
- cmd = cmd + "cp -RL " + DEST + "/machines/" + self.machine + "/core-image-minimal-" + self.machine + ".hddimage ./meta-" + self.machine.replace("-noemgd", "").replace("-lsb", "") + "/binary;"
- cmd = cmd + "echo '' >> ./README.tlk;"
- cmd = cmd + "echo 'The following text is autogenerated during the autobuilder build process.' >> ./README.tlk;"
- cmd = cmd + "echo 'It is not a part of the repositories used to create this BSP package.' >> ./README.tlk;"
- cmd = cmd + "echo '------------------------------------------------------------------------' >> ./README.tlk;"
- cmd = cmd + "echo 'Please note that the provided images were built using the meta-tlk layer' >> ./README.tlk;"
- cmd = cmd + "echo '(time limited kernel). Build instructions to build non-tlk images are' >> ./README.tlk;"
- cmd = cmd + "echo 'provided in ./meta-" + self.machine.replace("-noemgd", "").replace("-lsb", "") + "/README' >> ./README.tlk;"
- cmd = cmd + "echo '' >> ./README.tlk; cd ..;"
- cmd = cmd + "cd ..; tar cjvf " + self.machine + ".tar.bz2 meta-intel;"
- cmd = cmd + "mkdir -p " + DEST + "/machines/" + self.machine +";"
- cmd = cmd + "cp -RL " + self.machine + ".tar.bz2 " + DEST + "/machines/" + self.machine +";"
- self.command=cmd
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateWicImages.py b/lib/python2.7/site-packages/autobuilder/buildsteps/CreateWicImages.py
deleted file mode 100644
index af65f87b..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/CreateWicImages.py
+++ /dev/null
@@ -1,57 +0,0 @@
-'''
-__author__ = "Daniel Istrate"
-__copyright__ = "Copyright 2015 Intel Corporation"
-__credits__ = ["Daniel Istrate"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Daniel Istrate"
-__email__ = "daniel.alexandrux.istrate@intel.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-import os
-from buildbot.status.results import SUCCESS
-from lib.buildsteps import BitbakeShellCommand
-
-class CreateWicImages(BitbakeShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "CreateWicImages"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.workerdir = os.getenv('WORKERBASEDIR')
- self.command = ''
- self.machine = None
- self.wic_img_type = None
- self.target_img = None
- self.wic_dir = None
-
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.timeout = 100000
- kwargs['timeout']=self.timeout
-
- BitbakeShellCommand.__init__(self, factory, argdict, **kwargs)
-
- def start(self):
- # Get Machine
- self.machine = self.getProperty("MACHINE")
- self.description = ['Create wic image: %s for %s (%s)' % (self.wic_img_type, self.target_img, self.machine)]
- # Check to see if we an build with directdisk-gpt
- self.layerversion_core = int(self.getProperty("layerversion_core", "0"))
- if self.layerversion_core < 6 \
- and 'directdisk-gpt' in self.wic_img_type:
- self.skipStep("Skipping directdisk-gpt Build")
- else:
- # Set the wic build directory
- buildername = self.getProperty("buildername")
- self.wic_dir = os.path.join(os.path.join(self.workerdir, buildername), 'build/build/tmp/deploy/wic_images/')
- self.wic_dir += '%s/%s/%s/' % (self.machine, self.wic_img_type, self.target_img)
-
- # Create wic image 'wic_img_type'
- self.command += '. ./oe-init-build-env && '
- self.command += 'wic create %s -e %s -o %s ' % (self.wic_img_type, self.target_img, self.wic_dir)
-
- BitbakeShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/DaftFlash.py b/lib/python2.7/site-packages/autobuilder/buildsteps/DaftFlash.py
deleted file mode 100644
index 746932e6..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/DaftFlash.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import os
-
-from autobuilder.config import DAFT_WORKER_WORKSPACE
-from buildbot.steps.shell import ShellCommand
-
-class DaftFlash(ShellCommand):
- haltOnFailure = True
-
- name = "DaftFlash"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.tests = None
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "DUT Flashing"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- workspace_dir = DAFT_WORKER_WORKSPACE
-
- dut_name = self.getProperty('dut_name')
- workdir = self.getProperty('workdir')
- image = self.getProperty('BuildImages')
- machine = self.getProperty('MACHINE')
-
- image_path = os.path.join(workdir, 'build', 'build', 'tmp', 'deploy',
- 'images', machine, '%s-%s.hddimg' % (image, machine))
- image_name = os.path.basename(image_path)
-
- # XXX: DAFT needs to have the image in a shared workspace
- self.command = "cp %s %s; " % (image_path, workspace_dir)
- self.command += "cd %s; " % (workspace_dir)
- daft_cmd = "daft --setout %s %s" % (dut_name, image_name)
- self.command += "cd {} && {} ".format(workspace_dir, daft_cmd)
-
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py b/lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py
deleted file mode 100644
index a6e87e7f..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import os
-from buildbot.steps.transfer import FileUpload
-from buildbot.process.buildstep import BuildStep
-
-from lib.daft import DeployScanner
-from autobuilder.config import DAFT_WORKER_DEVICES_CFG
-
-class DaftGetDevices(FileUpload):
- haltOnFailure = True
-
- name = "DaftGetDevices"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.tests = None
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Getting devices configuration"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
-
- super(DaftGetDevices, self).__init__(DAFT_WORKER_DEVICES_CFG,
- os.path.join('/tmp', 'devices.cfg'))
-
- def finished(self, result):
- if self.cmd:
- ds = DeployScanner(devsconf_file = self.masterdest)
- devices = ds.getDevices()
-
- found = False
- dut_label = self.getProperty('custom_dut')
- for d in devices:
- if d['dut_label'] == dut_label:
- self.setProperty('dut_name', d['dut_label'], 'DaftGetDevices')
- self.setProperty('server_ip', d['server_address'], 'DaftGetDevices')
- target_ip = "%s:%s" % (d['ctrl_address'], d['dut_sshport'])
- self.setProperty('target_ip', target_ip, 'DaftGetDevices')
-
- found = True
-
- if not found:
- return BuildStep.finished(self, FAILURE)
-
- return super(DaftGetDevices, self).finished(result)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/DeleteGoogleVMs.py b/lib/python2.7/site-packages/autobuilder/buildsteps/DeleteGoogleVMs.py
deleted file mode 100644
index a18c44e2..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/DeleteGoogleVMs.py
+++ /dev/null
@@ -1,52 +0,0 @@
-'''
-Created on Aug 13, 2014
-
-__author__ = "California Sullivan"
-__copyright__ = "Copyright 2014, Intel Corp."
-__credits__ = ["California Sullivan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-
-class DeleteGoogleVMs(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Delete Google VMs"
- def __init__(self, factory, argdict=None, **kwargs):
-
- self.factory = factory
- self.description = "Deleting Google VMs"
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 1000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
-
- def start(self):
- self.vmnames = self.getProperty("vmnames")
- self.vmcount = self.getProperty("vmcount")
- self.zone = self.getProperty("zone")
-
- if self.vmnames is not None and self.vmnames != "":
- self.command = "gcloud compute instances delete"
- self.command += " " + self.vmnames
-
- if self.zone is not None and self.zone in ["us-central1-a", "us-central1-b", "us-central1-f", "europe-west1-a", "europe-west1-b", "asia-east1-a", "asia-east1-b", "asia-east1-b"]:
- self.command += " --zone " + self.zone
- else:
- self.command += " --zone us-central1-a"
- self.command += " --quiet"
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/DownloadErrorReports.py b/lib/python2.7/site-packages/autobuilder/buildsteps/DownloadErrorReports.py
deleted file mode 100644
index 696f56cb..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/DownloadErrorReports.py
+++ /dev/null
@@ -1,42 +0,0 @@
-'''
-Created on Jan 1, 2016
-
-__author__ = "Anibal (alimon) Limon"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Anibal Limon"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Anibal Limon"
-__email__ = "anibal.limon@linux.intel.com"
-'''
-
-import os
-from buildbot.steps.transfer import DirectoryDownload
-from buildbot.process.buildstep import SKIPPED
-
-from lib.ABTools import get_error_report_worker_dir, \
- get_error_report_controller_dir
-
-class DownloadErrorReports(DirectoryDownload):
- """
- Transfer from master to slave the error reports when bitbake
- fails.
- """
- name = "DownloadErrorReports"
-
- def __init__(self, factory, argdict=None, **kwargs):
- super(DownloadErrorReports, self).__init__(
- "", "")
-
- def start(self):
- buildername = self.getProperty('buildername')
- buildnumber = self.getProperty('buildnumber')
-
- self.mastersrc = get_error_report_controller_dir(buildername,
- buildnumber)
- self.slavedest = get_error_report_worker_dir(buildername)
-
- if not os.path.exists(self.mastersrc):
- return SKIPPED
-
- super(DownloadErrorReports, self).start()
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/GetBitbakeVersion.py b/lib/python2.7/site-packages/autobuilder/buildsteps/GetBitbakeVersion.py
deleted file mode 100644
index 61233430..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/GetBitbakeVersion.py
+++ /dev/null
@@ -1,51 +0,0 @@
-'''
-Created on January 20th, 2015
-
-__author__ = "Brendan Le Foll"
-__copyright__ = "Copyright 2015, Intel Corp."
-__credits__ = ["Brendan Le Foll"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "elizabeth.flanagan at intel.com"
-'''
-from buildbot.steps.shell import ShellCommand
-from buildbot.status import progress
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.process.properties import WithProperties
-from twisted.python import log
-from autobuilder.config import *
-
-from lib.buildsteps import BitbakeShellCommand
-
-class GetBitbakeVersion(BitbakeShellCommand):
- haltOnFailure = False
- flunkOnFailure = False
- name = "GetBitbakeVersion"
- def __init__(self, factory, argdict=None, **kwargs):
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Get Bitbake Version"
- self.workerworkdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- super(GetBitbakeVersion, self).__init__(factory, argdict=None, **kwargs)
-
- def start(self):
- buildername=self.getProperty("buildername")
-
- self.command = '. ./oe-init-build-env; bitbake --version'
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- result = cmd.logs['stdio'].getText()
-
- bitbakev= result.split()[-1]
- log.msg("Bitbake version: " + bitbakev)
- if cmd.didFail():
- bitbakev = "1"
- self.setProperty('bitbakeversion', bitbakev, "Setting Bitbake Version")
- self.finished(SUCCESS)
-
- def getText(self, cmd, results):
- return ShellCommand.getText(self, cmd, results)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/GetDistroVersion.py b/lib/python2.7/site-packages/autobuilder/buildsteps/GetDistroVersion.py
deleted file mode 100644
index ed7289f4..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/GetDistroVersion.py
+++ /dev/null
@@ -1,113 +0,0 @@
-'''
-Created on Dec 26, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from buildbot.steps.shell import ShellCommand
-from buildbot.status import progress
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.process.properties import WithProperties
-from twisted.python import log
-from autobuilder.config import *
-
-class GetDistroVersion(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "GetDistroVersion"
- def __init__(self, factory, argdict=None, **kwargs):
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Get Distro Version"
- self.distroversion = None
- self.workerworkdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.buildername=self.getProperty("buildername")
- layerversionyocto = int(self.getProperty("layerversion_yocto", "0"))
- self.distroconf=self.workerworkdir + "/" + self.buildername
- if 'poky' in self.distro or 'clanton' in self.distro:
- if layerversionyocto < 3:
- self.distroconf+="/build/meta-yocto/conf/distro/poky.conf|grep 'DISTRO_VERSION = \"'"
- else:
- self.distroconf+="/build/meta-poky/conf/distro/poky.conf|grep 'DISTRO_VERSION = \"'"
- elif 'oecore' in self.distro:
- self.distroconf+="/build/meta/conf/distro/include/default-distrovars.inc|grep 'DISTRO_VERSION '"
- elif 'angstrom' in self.distro:
- self.distroconf+="/build/meta-angstrom/conf/distro/angstrom-*.conf|grep 'DISTRO_VERSION = \"'"
- elif 'refkit' in self.distro:
- self.distroconf += "/build/*/meta-refkit/conf/distro/refkit*.conf|grep 'DISTRO_VERSION ?= \"'"
- else:
- logmsg = 'distro %s is not recognised by the yocto-autobuilder.' \
- % self.distro
- self.addCompleteLog("failure", logmsg)
- self.finished(FAILURE)
- return None
-
- cmd = 'cat ' + self.distroconf
- self.command = cmd
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- return
- result = cmd.logs['stdio'].getText()
- distroversion = result.replace("DISTRO_VERSION = ", "").replace("-${DATE}","").replace('"','').strip()
- self.setProperty('distroversion', distroversion, "Setting Distro Version")
- is_milestone = self.getProperty("custom_is_milestone")
- milestone_number = self.getProperty("custom_milestone_number")
- rc_number = self.getProperty("custom_rc_number")
-
- if str(self.getProperty("custom_release_me")) == "True":
- yocto_number = self.getProperty("custom_yocto_number")
- if is_milestone == "True":
- distroversion = distroversion.replace('+snapshot', '')
- # If distroversion has more than one . and can't be coerced
- # into a float we can't easily do our automatic version
- # bumping for milestone releases.
- if len(distroversion.split('.')) > 2:
- logmsg = 'Unexpectedly long DISTRO_VERSION="%s"' \
- % distroversion
- logmsg = logmsg + ' only expected 2 components, '
- logmsg = logmsg + 'i.e. 2.2 not 2.2.1'
- self.addCompleteLog("failure", logmsg)
- self.finished(FAILURE)
- self.build.allStepsDone()
- else:
- try:
- distroversion = str(float(distroversion)+0.1)
- except ValueError:
- # If the distro version can't be coerced into a float
- # fail early and tell the user something went wrong.
- logmsg = 'Unexpected DISTRO_VERSION="%s"' \
- % distroversion
- self.addCompleteLog("failure", logmsg)
- self.finished(FAILURE)
- self.build.allStepsDone()
- self.setProperty('distroversion', distroversion, "Setting Distro Version")
-
- if distroversion == yocto_number and "poky" in self.distro:
- self.finished(SUCCESS)
- elif "poky" not in self.distro:
- self.finished(SUCCESS)
- else:
- logmsg = 'Failed to get distroversion. DISTRO_VERSION="%s"' \
- % distroversion
- logmsg = logmsg + ' is not the same as specified Yocto Project'
- logmsg = logmsg + ' release number %s' % yocto_number
- self.addCompleteLog("failure", logmsg)
- self.finished(FAILURE)
- self.build.allStepsDone()
- else:
- self.finished(SUCCESS)
-
- def getText(self, cmd, results):
- return ShellCommand.getText(self, cmd, results)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/GetLayerVersion.py b/lib/python2.7/site-packages/autobuilder/buildsteps/GetLayerVersion.py
deleted file mode 100644
index 8dd00e53..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/GetLayerVersion.py
+++ /dev/null
@@ -1,55 +0,0 @@
-'''
-Created on July 17th, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from buildbot.steps.shell import ShellCommand
-from buildbot.status import progress
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.process.properties import WithProperties
-from twisted.python import log
-from autobuilder.config import *
-
-class GetLayerVersion(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = False
- name = "GetLayerVersion"
- def __init__(self, factory, layerversion=None, workdir='build', argdict=None, **kwargs):
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Get Layer Version"
- self.layerversion = layerversion
- self.layerfile = layerversion
- self.workdir=workdir
- self.workerworkdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- buildername=self.getProperty("buildername")
- log.msg(self.workdir)
- log.msg(self.layerversion)
- if self.layerversion == "poky":
- self.layerfile = "yocto"
- layerconf=self.workerworkdir + "/" + buildername + "/build/" + self.workdir + "/conf/layer.conf|grep LAYERVERSION_" + self.layerfile
- cmd = 'cat ' + layerconf
- self.command = cmd
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- if not cmd.didFail():
- result = cmd.logs['stdio'].getText()
- layerv = result.replace("LAYERVERSION_" + self.layerfile, "").replace("=","").replace(' ','').replace('"','').replace("'",'').strip()
- if not self.getProperty('layerversion_' + self.layerfile):
- self.setProperty('layerversion_' + self.layerfile, layerv, "Setting Layer Version")
- self.finished(SUCCESS)
-
- def getText(self, cmd, results):
- return ShellCommand.getText(self, cmd, results)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/HelloWorld.py b/lib/python2.7/site-packages/autobuilder/buildsteps/HelloWorld.py
deleted file mode 100644
index 6e3dd480..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/HelloWorld.py
+++ /dev/null
@@ -1,48 +0,0 @@
-'''
-Created on Dec 22, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-
-class HelloWorld(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Hello World"
- def __init__(self, factory, argdict=None, **kwargs):
- self.firstname=""
- self.lastname=""
- self.factory = factory
- for k, v in argdict.iteritems():
- if k=="firstname":
- self.firstname=v
- elif k=="lastname":
- self.lastname=v
- else:
- setattr(self, k, v)
- self.description = "Hello World"
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- if self.firstname == "" and self.lastname == "":
- self.firstname=self.getProperty("custom_firstname")
- self.lastname=self.getProperty("custom_lastname")
-
- self.command = "echo 'Hello World " + self.firstname + " " + self.lastname + "'"
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ModBBLayersConf.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ModBBLayersConf.py
deleted file mode 100644
index 5e9a7f22..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ModBBLayersConf.py
+++ /dev/null
@@ -1,40 +0,0 @@
-'''
-Created on July 24, 2017
-
-__author__ = "Stephano Cetola"
-__copyright__ = "Copyright 2017, Intel Corp."
-__credits__ = ["Stephano Cetola"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Stephano Cetola"
-__email__ = "stephano.cetola@linux.intel.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-import os
-
-class ModBBLayersConf(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Modify BBLayers Configuration"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Modify BBLayers Configuration"
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- builddir = os.path.join(self.getProperty('builddir'), 'build')
- bblayers = "%s/build/conf/bblayers.conf" % builddir
- cmd = 'echo "Not configured"'
- if self.sub:
- cmd = ""
- for mod in self.sub:
- tgt, rep = mod
- rep = rep.replace("#YPDIR", builddir)
- cmd = cmd + "sed -i 's|.*%s .*|%s \\\\|' %s;" % (tgt, rep, bblayers)
-
- self.command = cmd
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/NoOp.py b/lib/python2.7/site-packages/autobuilder/buildsteps/NoOp.py
deleted file mode 100644
index 2a6b2cdb..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/NoOp.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from buildbot.process import buildstep
-from buildbot.status.results import SUCCESS, FAILURE
-class NoOp(buildstep.BuildStep):
- """
- A build step that does nothing except finish with a caller-
- supplied status (default SUCCESS).
- """
- parms = buildstep.BuildStep.parms + ['result']
-
- result = SUCCESS
- flunkOnFailure = False
-
- def start(self):
- self.step_status.setText([self.name])
- self.finished(self.result)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py b/lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py
deleted file mode 100644
index adfef378..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py
+++ /dev/null
@@ -1,48 +0,0 @@
-'''
-Created on Dec 26, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-from autobuilder.config import *
-
-class PrepPkgIndex(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "PrepPkgIndex"
- def __init__(self, factory, argdict=None, **kwargs):
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Prepping to create pkg index"
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.timeout = 100000
- self.workdir="build/build/tmp/deploy/"
- kwargs['workdir']=self.workdir
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- import os
- DEST=self.getProperty('DEST')
- layerversion = int(self.getProperty("layerversion_core", "0"))
- IPK_PUBLISH_DIR = os.environ.get("IPK_PUBLISH_DIR")
- if layerversion < 4:
- command = "rm -rf ipk; cp -R " + DEST + "/" + IPK_PUBLISH_DIR + " ipk;"
- else:
- command = "rm -rf ipk; ln -s " + DEST + "/" + IPK_PUBLISH_DIR + " ipk;"
- self.command = command
- ShellCommand.start(self)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ProvisionGoogleVMs.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ProvisionGoogleVMs.py
deleted file mode 100644
index 5240c65e..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ProvisionGoogleVMs.py
+++ /dev/null
@@ -1,90 +0,0 @@
-'''
-Created on Aug 13, 2014
-
-__author__ = "California Sullivan"
-__copyright__ = "Copyright 2014, Intel Corp."
-__credits__ = ["California Sullivan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from autobuilder.config import *
-from buildbot.steps.shell import ShellCommand
-
-class ProvisionGoogleVMs(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Provision Google VMs"
- def __init__(self, factory, argdict=None, **kwargs):
- self.vmname=None
- self.vmnames=""
- self.vmcount=1
- self.startupscript=None
- self.metadata=None
- self.zone="us-central1-a"
- self.image=None
- self.machine=None
- self.network=None
- self.disksize=None
- self.factory = factory
- self.description = "Provision Google VMs"
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
-
- if self.vmname is None or self.vmname == "":
- self.finished(FAILURE)
- else:
- self.command = ""
- if self.zone is None or self.zone not in ["us-central1-a", "us-central1-b", "us-central1-f", "europe-west1-a", "europe-west1-b", "asia-east1-a", "asia-east1-b", "asia-east1-b"]:
- self.zone = "us-central1-a"
- for x in range(0, self.vmcount):
- self.vmnames += " " + self.vmname + "-" + str(x)
- self.command += " gcloud compute instances delete"
- self.command += self.vmnames
- self.command += " --zone " + self.zone + " --quiet;"
- self.command += " gcloud compute instances create"
- self.command += self.vmnames
- self.command += " --zone " + self.zone
-
- if self.disksize is not None and self.disksize != "":
- self.command += " --boot-disk-size " + self.disksize
- else:
- self.command += " --boot-disk-size 200GB"
- if self.image is None:
- self.command += " --image debian-7"
- else:
- self.command += " --image " + self.image
-
- if self.machine is not None and self.machine in ["g1-small", "f1-micro", "n1-standard-1", "n1-standard-2", "n1-standard-4", "n1-standard-8", "n1-standard-16", "n1-highmem-2", "n1-highmem-4"]:
- self.command += " --machine-type " + self.machine
- else:
- self.command += " --machine-type n1-standard-1"
- if self.network is not None and self.network != "":
- self.command += " --network " + self.network
- if self.startupscript is not None and self.startupscript != "":
- self.command += " --metadata-from-file startup-script="+YOCTO_ABBASE+"/bin/"+self.startupscript
- if self.metadata is not None and self.metadata != "":
- self.command += " --metadata " + self.metadata
- self.command += " 1> /dev/null";
-
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 1000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
-
- def commandComplete(self, cmd):
- if not cmd.didFail():
- self.setProperty("vmnames", self.vmnames)
- self.setProperty("zone", self.zone)
- self.setProperty("vmcount", self.vmcount)
-
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py b/lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py
deleted file mode 100644
index 8ea6a81f..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py
+++ /dev/null
@@ -1,315 +0,0 @@
-'''
-Created on Jan 11, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-import os, datetime
-from autobuilder.config import *
-
-class PublishArtifacts(ShellCommand):
-
- haltOnFailure = False
- flunkOnFailure = True
- name = "Publishing Artifacts"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Publishing Artifacts"
- self.workerdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- pipeline = "|| export PA_FAIL=1"
- DEST=self.getProperty("DEST")
- buildername=self.getProperty("buildername")
- got_revision_poky=self.getProperty("got_revision_poky")
- distroversion=self.getProperty("distroversion")
- self.layerversion_yoctobsp = int(self.getProperty("layerversion_yoctobsp", "0"))
- self.layerversion_yocto = int(self.getProperty("layerversion_yocto", "0"))
- self.layerversion_core = int(self.getProperty("layerversion_core", "0"))
- self.minnowExists = self.getProperty("minnowExists", "False")
- self.basedir=os.path.join(os.path.join(
- self.workerdir, buildername),
- "build/build/")
- self.tmpdir = os.environ.get("TMP_DIR")
- if self.tmpdir is None:
- self.tmpdir = os.path.join(self.basedir, "tmp")
- command = ""
- deploy = self.getProperty("custom_deploy_artifacts", "False")
- if str(os.environ.get('PUBLISH_BUILDS')) == "True" \
- and deploy == "True":
- for artifact in self.artifacts:
- if self.layerversion_yoctobsp > 1 and artifact == "atom-pc":
- artifact = "genericx86"
- elif self.layerversion_yoctobsp < 2 and artifact == "genericx86":
- artifact = "atom-pc"
- if self.layerversion_yoctobsp < 2 and artifact == "genericx86-64":
- artifact = "None"
- if self.minnowExists == "False" and "minnow" in artifact:
- artifact = "None"
- if self.layerversion_yoctobsp > 2 and artifact == "beagleboard":
- artifact = "beaglebone"
- elif self.layerversion_yoctobsp < 3 and artifact == "beaglebone-yocto":
- artifact = "beagleboard"
- elif self.layerversion_yoctobsp < 4 and artifact == "beaglebone-yocto":
- artifact = "beaglebone"
-
- if self.layerversion_yoctobsp > 2 and artifact == "routerstationpro":
- artifact = "edgerouter"
- elif self.layerversion_yoctobsp < 3 and artifact == "edgerouter":
- artifact = "routerstationpro"
- if self.layerversion_core > 7 and "adt" in artifact:
- artifact = "None"
- elif self.layerversion_core < 8 and "uninative" in artifact:
- artifact = "None"
-
- if artifact == "adt-installer":
- command=command+"mkdir -p " + os.path.join(DEST, ADT_INST_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/sdk/") + \
- "*adt* " + os.path.join(DEST, ADT_INST_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "adt-installer-QA":
- command=command+"mkdir -p " + os.path.join(DEST, ADTQA_INST_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/sdk/") + \
- "*adt* " + os.path.join(DEST, ADTQA_INST_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "adtrepo-dev":
- adt_dev_dest= os.environ.get("ADTREPO_DEV_PATH") + "/" + distroversion + "-" + got_revision_poky + '-' + self.getProperty("branch_poky")
- command=command+"mkdir -p " + adt_dev_dest + "/adt-ipk;"
- command=command+"rsync -av " + os.path.join(self.tmpdir, "deploy/ipk/") + " " + adt_dev_dest + "/adt-ipk " + pipeline + ";"
- command=command+"rm -rf " + adt_dev_dest + "/rootfs; mkdir -p " + adt_dev_dest + "/rootfs;"
- command=command+"for x in `ls " + DEST + "/machines/qemu/|grep -v tiny`; do ln -s " + DEST + "/machines/qemu/$x " + adt_dev_dest + "/rootfs/$x; done;"
- if self.layerversion_yocto < 2:
- command=command+"mv " + adt_dev_dest + "/rootfs/qemux86-64 " + adt_dev_dest + "/rootfs/qemux86_64;"
- elif "eclipse-plugin" in artifact:
- artifact_base = artifact.replace("eclipse-plugin-", "")
- deploy_dir = os.path.join(os.path.join(self.workerdir, buildername), "build/scripts")
- # create md5sums only for the zip files
- if os.environ.get('GEN_IMG_MD5') == "True":
- command += "for x in `ls " + deploy_dir + "/*.zip`;"
- command += "do md5sum $x >> " + "$x.md5sum; done;"
- command=command+"mkdir -p " + DEST + "/eclipse-plugin/"+ artifact_base +";"
- command=command+"cp --no-dereference --preserve=links " + \
- os.path.join(deploy_dir, "org.*.zip") + \
- " " + os.path.join(deploy_dir, "org.*.md5sum") + \
- " " + DEST + "/eclipse-plugin/"+ artifact_base + pipeline + ";"
- elif artifact == "build-appliance":
- command=command+"mkdir -p " + DEST + "/" + BA_PUBLISH_DIR + ";"
- if self.layerversion_core > 2:
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/images/qemux86-64/*.zip") + \
- " " + DEST + "/" + BA_PUBLISH_DIR + pipeline + ";"
- else:
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/images/*.zip") + \
- " " + DEST + "/" + BA_PUBLISH_DIR + pipeline + ";"
- elif artifact == "buildtools-tarball":
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- command=command+self.generateMD5cmd(artifact, deploy_image_dir)
- command=command+"mkdir -p " + DEST + "/buildtools;"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(deploy_image_dir, "*buildtools*") + \
- " " + DEST + "/buildtools" + pipeline + ";"
- elif artifact == "rpm":
- command=command+"mkdir -p " + os.path.join(DEST, RPM_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/rpm/* ") + \
- os.path.join(DEST, RPM_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "deb":
- command=command+"mkdir -p " + os.path.join(DEST, DEB_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/deb/* ") + \
- os.path.join(DEST, DEB_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "ipk":
- command=command+"mkdir -p " + os.path.join(DEST, IPK_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/ipk/* ") + \
- os.path.join(DEST, IPK_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "sstate":
- if str(os.environ.get("PUBLISH_SSTATE")) == "True":
- is_release = self.getProperty('custom_is_release', 'No')
- if is_release == 'No':
- is_release = self.getProperty("is_release")
- release = str(is_release) == "True"
- sstate_dir = os.environ.get("SSTATE_DIR")
- pub_dir = os.environ.get("SSTATE_PUBLISH_DIR")
- rel_dir = ""
- if release and self.layerversion_core > 8:
- sstate_release_number = self.get_release_number()
- sstate_dir = sstate_dir + '-' + sstate_release_number
- rel_dir = pub_dir + '-' + sstate_release_number
- if sstate_dir is not None and pub_dir is not None:
- command=command+"mkdir -p " + pub_dir + pipeline + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- sstate_dir + "/* " + pub_dir + pipeline + ";"
- if release:
- command=command+"mkdir -p " + rel_dir + pipeline + ";"
- # For a release build we want to deep copy symlinks
- command=command+"cp -R --dereference --preserve=links " + \
- sstate_dir + "/* " + rel_dir + pipeline + ";"
- else:
- command=command+"echo 'Skipping copy of sstate, directories not configured.';"
- else:
- command=command+"echo 'Skipping copy of sstate, PUBLISH_SSTATE not set.';"
- elif artifact == "toolchain":
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- command=command+self.generateMD5cmd(artifact, deploy_image_dir)
- command=command+"mkdir -p " + os.path.join(DEST, X86TC_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(deploy_image_dir, "poky-*i686-core-image* ") + \
- os.path.join(DEST, X86TC_PUBLISH_DIR) + pipeline + ";"
- command=command+"mkdir -p " + os.path.join(DEST, X8664TC_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(deploy_image_dir, "poky-*x86_64-core-image* ") + \
- os.path.join(DEST, X8664TC_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "uninative":
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- command=command+self.generateMD5cmd(artifact, deploy_image_dir)
- command=command+"mkdir -p " + os.path.join(DEST, X86TC_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(deploy_image_dir, "i686-nativesdk-libc* ") + \
- os.path.join(DEST, X86TC_PUBLISH_DIR) + pipeline + ";"
- command=command+"mkdir -p " + os.path.join(DEST, X8664TC_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(deploy_image_dir, "x86_64-nativesdk-libc* ") + \
- os.path.join(DEST, X8664TC_PUBLISH_DIR) + pipeline + ";"
- elif artifact == "oe-toolchain":
- command=command+"mkdir -p " + os.path.join(DEST, X86TC_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/sdk/oecore-i686* ") + \
- os.path.join(DEST, X86TC_PUBLISH_DIR) + pipeline + ";"
- command=command+"mkdir -p " + os.path.join(DEST, X8664TC_PUBLISH_DIR) + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/sdk/oecore-x86_64* ") + \
- os.path.join(DEST, X8664TC_PUBLISH_DIR) + pipeline + ";"
- elif "qemu" in artifact:
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- command += self.generateMD5cmd(artifact, deploy_image_dir)
- command=command+"mkdir -p " + DEST + "/" + QEMU_PUBLISH_DIR + "/" + artifact_name + ";"
- if "-wic" in buildername:
- deploy_image_dir += "/*/*"
- if self.layerversion_core < 10:
- deploy_image_dir += "/build"
- command=command+"cp --no-dereference --preserve=links " + \
- deploy_image_dir + "/*\.direct " + \
- deploy_image_dir + "/*\.direct.md5sum " + \
- DEST + "/" + QEMU_PUBLISH_DIR + "/" + artifact_name + pipeline + ";"
- else:
- command=command+"cp -R --no-dereference --preserve=links " + \
- deploy_image_dir + \
- "/*" + artifact + "* " + DEST + "/" + QEMU_PUBLISH_DIR + "/" + artifact_name + pipeline + ";"
- if "qemuarm" in artifact:
- command=command+"cp -R --no-dereference --preserve=links " + \
- deploy_image_dir + \
- "/*Image* " + DEST + "/" + QEMU_PUBLISH_DIR +"/" + artifact_name + pipeline + ";"
- elif "mpc8315e" in artifact:
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- command += self.generateMD5cmd(artifact, deploy_image_dir)
- command=command+"mkdir -p " + DEST + "/" + MACHINE_PUBLISH_DIR + "/" + artifact_name + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- deploy_image_dir + \
- "/*mpc8315* " + DEST + "/" + MACHINE_PUBLISH_DIR + "/" + artifact_name + pipeline + ";"
- elif artifact == "tiny":
- command=command+"mkdir -p " + DEST + "/" + QEMU_PUBLISH_DIR + "/qemu-tiny;"
- command += self.generateMD5cmd(artifact, QEMU_PUBLISH_DIR + "/qemu-tiny")
- if self.layerversion_core > 2:
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/images/qemux86/* ") + \
- " " + DEST + "/" + QEMU_PUBLISH_DIR + "/qemu-tiny" + pipeline + ";"
- else:
- command=command+"cp -R --no-dereference --preserve=links " + \
- os.path.join(self.tmpdir, "deploy/images/*") + \
- DEST + "/" + QEMU_PUBLISH_DIR + "/qemu-tiny" + pipeline + ";"
- elif artifact == "conf":
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- command=command+"mkdir -p " + DEST + "/"+ MACHINE_PUBLISH_DIR + "/" + artifact_name + "/conf;"
- command=command+"cp -R --no-dereference " + \
- os.path.join(self.basedir, "conf/") + \
- "/* " + DEST + "/" + MACHINE_PUBLISH_DIR + "/" + artifact_name + "/conf" + pipeline + ";"
- elif artifact == "md5sums":
- command = command + "echo 'MD5sums are generated and deployed from the image or toolchain artifact';"
- elif artifact == "None":
- command=command+"echo 'Skipping copy of " + artifact + ".';"
- else:
- artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername)
- self.layerversion_yoctobsp = int(self.getProperty("layerversion_yoctobsp", "0"))
- if self.layerversion_yoctobsp < 2 and \
- "genericx86-64" in artifact:
- command = command+"echo 'Skipping copy of genericx86-64.'; "
- else:
- command += self.generateMD5cmd(artifact, deploy_image_dir)
- if "-wic" in buildername:
- deploy_image_dir += "/*/*"
- if self.layerversion_core < 10:
- deploy_image_dir += "/build"
- command=command+"mkdir -p " + DEST + "/" + MACHINE_PUBLISH_DIR + "/" + artifact_name + ";"
- command=command+"cp --no-dereference --preserve=links " + \
- deploy_image_dir + "/*\.direct " + \
- deploy_image_dir + "/*\.direct.md5sum " + \
- DEST + "/" + MACHINE_PUBLISH_DIR + "/" + artifact_name + pipeline + ";"
- else:
- command=command+"mkdir -p " + DEST + "/"+ MACHINE_PUBLISH_DIR +"/" + artifact_name + ";"
- if "beagle" in artifact:
- command=command+"cp -R --no-dereference --preserve=links " + \
- deploy_image_dir + \
- "/*Image* " + DEST + "/" + MACHINE_PUBLISH_DIR +"/" + artifact_name + pipeline + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- deploy_image_dir + \
- "/u-boot* " + DEST + "/" + MACHINE_PUBLISH_DIR +"/" + artifact_name + pipeline + ";"
- command=command+"cp -R --no-dereference --preserve=links " + \
- deploy_image_dir + \
- "/*"+artifact+"* " + DEST + "/" + MACHINE_PUBLISH_DIR +"/" + artifact_name + pipeline + ";"
- command=command+'if [ "$PA_FAIL" = "1" ]; then exit 1; fi;'
- self.command = command
- else:
- self.command = "echo 'Skipping Step.'"
- ShellCommand.start(self)
-
- def generateMD5cmd(self, artifact, deploy_dir):
- cmd = ""
- if os.environ.get('GEN_IMG_MD5') == "True":
- cmd += "for x in `find " + deploy_dir + " -maxdepth 5 -type f`;"
- cmd += "do if [ ${x##*.} != md5sum ]; then md5sum $x >> " + "$x.md5sum; fi; done;"
- return cmd
-
- def getDeployNames(self, artifact, buildername):
- artifact_name = artifact
- if "-lsb" in buildername:
- artifact_name = artifact_name + "-lsb"
- if "-wic" in buildername:
- deploy_dir_image = os.path.join(os.path.join(self.tmpdir, "deploy/wic_images/"), artifact)
- elif artifact_name == "md5sums":
- deploy_dir_image = os.path.join(self.tmpdir, "deploy/images/")
- elif artifact_name == "uninative" or artifact_name == "buildtools-tarball" \
- or artifact_name == "toolchain":
- deploy_dir_image = os.path.join(self.tmpdir, "deploy/sdk/")
- else:
- if self.layerversion_core > 2:
- deploy_dir_image = os.path.join(os.path.join(self.tmpdir, "deploy/images/"), artifact)
- else:
- deploy_dir_image = os.path.join(self.tmpdir, "deploy/images/")
- return artifact_name, deploy_dir_image
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
-
- def get_release_number(self):
- release_number = self.getProperty("custom_yocto_number", "")
- release_components = release_number.split('.', 3)
- return '.'.join(release_components).strip('.')
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/PublishDistroData.py b/lib/python2.7/site-packages/autobuilder/buildsteps/PublishDistroData.py
deleted file mode 100644
index 83aeb8d1..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/PublishDistroData.py
+++ /dev/null
@@ -1,57 +0,0 @@
-'''
-Created on March 11, 2016
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2016, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-import os, datetime
-from autobuilder.config import *
-
-class PublishDistroData(ShellCommand):
-
- haltOnFailure = False
- flunkOnFailure = True
- name = "Publishing Artifacts"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Publishing DistroData Artifacts"
- self.workerdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- command = ""
- DEST=self.getProperty("DEST")
- buildername=self.getProperty("buildername")
- self.basedir=os.path.join(os.path.join(
- self.workerdir, buildername),
- "build/build/")
- self.tmpdir = os.environ.get("TMP_DIR")
- if self.tmpdir is None:
- self.tmpdir = os.path.join(self.basedir, "tmp")
- command+="mkdir -p " + os.path.join(DEST, 'distro_data/'+ self.machine) + ";"
- command+="cp -R --dereference " + os.path.join(self.tmpdir, "log/distrocheck.csv") + \
- " " + os.path.join(DEST, 'distro_data/'+ self.machine) + ";"
- command+="cp -R --dereference " + os.path.join(self.tmpdir, "log/distrodata.csv") + \
- " " + os.path.join(DEST, 'distro_data/'+ self.machine) + ";"
- command+="cp -R --dereference " + os.path.join(self.tmpdir, "log/missinglicense.csv") + \
- " " + os.path.join(DEST, 'distro_data/'+ self.machine) + ";"
- command+="cp -R --dereference " + os.path.join(self.tmpdir, "log/checkpkg.csv") + \
- " " + os.path.join(DEST, 'distro_data/'+ self.machine) + ";"
- self.command = command
- ShellCommand.start(self)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/PublishLayerTarballs.py b/lib/python2.7/site-packages/autobuilder/buildsteps/PublishLayerTarballs.py
deleted file mode 100644
index 933ea1ce..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/PublishLayerTarballs.py
+++ /dev/null
@@ -1,79 +0,0 @@
-'''
-Created on Mar 17, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-import os, datetime
-from autobuilder.config import *
-
-class PublishLayerTarballs(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Publishing Layer Tarballs"
- def __init__(self, factory, layername, workdir, argdict=None, **kwargs):
- self.factory = factory
- self.layername = layername
- self.workdir = workdir
- self.description = "Publishing " + layername + " tarball"
- self.workerdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- DEST=self.getProperty("DEST")
- buildername=self.getProperty("buildername")
- revision = ""
- snapshot = ""
- self.basedir=os.path.join(os.path.join(os.path.join(
- self.workerdir, buildername), self.workdir))
- if self.layername is not "poky" \
- and "eclipse" not in self.layername:
- command = "cd " + self.layername + ";"
- else:
- command = ""
- deploy = "True"
- deploy = self.getProperty("custom_deploy_artifacts")
- if str(os.environ.get('PUBLISH_BUILDS')) == "True" and (deploy == "True" or deploy is None):
- if self.getProperty("custom_release_me_"+buildername):
- is_milestone = self.getProperty("custom_is_milestone")
- if is_milestone == "True":
- snapshot = "+snapshot"
- poky_name = self.getProperty("poky_name")
- poky_number = self.getProperty("poky_number")
- yocto_number = self.getProperty("yocto_number")
- archive_name = self.layername + "-" + poky_name + "-" + poky_number
- command = command + " git archive --format=tar HEAD "
- command = command + "--prefix=" + archive_name + "/"
- command = command + " | bzip2 -c > " + archive_name + ".tar.bz2; "
- command = command + "md5sum " + archive_name + ".tar.bz2 >> "
- command = command + self.layername + "-" + revision + ".tar.bz2.md5sum; "
- command = command + "mkdir -p " + DEST + "; rsync -av "
- command = command + archive_name +".tar.bz2* " + DEST
- elif self.getProperty("got_revision_"+self.layername):
- revision=self.getProperty("got_revision_"+self.layername)
- archive_name = self.layername + "-" + revision
- command = command + " git archive --format=tar HEAD "
- command = command + "--prefix=" + self.layername + "-" + revision + "/"
- command = command + " | bzip2 -c > " + self.layername + "-" + revision + ".tar.bz2; "
- command = command + "md5sum " + self.layername + "-" + revision + ".tar.bz2 >> "
- command = command + self.layername + "-" + revision + ".tar.bz2.md5sum; "
- command = command + "mkdir -p " + DEST + "; rsync -av "
- command = command + archive_name +".tar.bz2* " + DEST
- self.command=command
- else:
- self.command="echo 'No revision found. Skipping tarball'"
- else:
- self.command="echo 'Not publishing build, skipping step'"
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RemoveTmpFiles.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RemoveTmpFiles.py
deleted file mode 100644
index 3517d22a..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RemoveTmpFiles.py
+++ /dev/null
@@ -1,65 +0,0 @@
-'''
-Created on Jun 06, 2017
-
-__author__ = "Joshua Lock"
-__copyright__ = "Copyright 2017, Intel Corp."
-__credits__ = ["Joshua Lock"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Joshua Lock"
-__email__ = "joshua.g.lock@intel.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from autobuilder.config import *
-import os
-
-class RemoveTmpFiles(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "RemoveTmpFiles"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self._pendingLogObservers = []
- self.files = ""
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout'] = self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- # the "build" child of the buildbot builddir is the directory poky (or
- # openembedded-core) has been cloned to, the build subdirectory of that
- # directory (build/build) is the OE-Core BUILDDIR.
- builddir = os.path.join(self.getProperty("builddir"), "build", "build")
-
- filesOK = True
- if not self.files:
- self.files = os.path.join(builddir, 'tmp')
- else:
- files = self.files.split()
- for f in files:
- if f.startswith('/') and not f.startswith(builddir):
- filesOK = False
- break
- else:
- abs = os.path.abspath(os.path.join(builddir, f))
- if not abs.startswith(builddir):
- filesOK = False
- break
-
- # Ensure the resulting path is a sub-directory of the build directory
- if not filesOK:
- reason = "Skipping RemoveTmpFiles because one or more of '%s' "
- reason = reason + "aren't a child of the build directory "
- reason = reason + "(BUILDDIR) '%s'"
- reason = reason % (self.files, build)
- self.command = "echo '%s'" % reason
- self.description = ["%s" % reason]
- else:
- self.command = "rm -rf %s" % self.files
-
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ResolveLayerHead.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ResolveLayerHead.py
deleted file mode 100644
index d7127c57..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ResolveLayerHead.py
+++ /dev/null
@@ -1,73 +0,0 @@
-'''
-Created on Sept 17th, 2013
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from buildbot.steps.shell import ShellCommand
-from buildbot.status import progress
-from buildbot.process.build import Build
-from buildbot.status.results import SUCCESS
-from buildbot.process.properties import WithProperties
-from twisted.python import log
-from autobuilder.config import *
-
-class ResolveLayerHead(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = False
- name = "ResolveLayerHead"
- def __init__(self, factory, layername=None, scheduler=None, argdict=None, **kwargs):
- self.branch = ""
- self.commit = ""
- self.repourl = ""
- self.layername = layername
- self.scheduler = scheduler
- self.description = "Resolve " + self.layername + " " + self.branch + " HEAD"
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- cmd = ''
- if self.getProperty('branch_'+self.layername):
- self.branch = self.getProperty('branch_'+self.layername)
- else:
- self.branch = "master"
-
- if self.getProperty('repo_'+self.layername):
- self.repourl = self.getProperty('repo_'+self.layername)
- else:
- self.repourl = "git://git.yoctoproject.org/poky"
-
- if self.getProperty('commit_'+self.layername) is 'HEAD' and self.getProperty('commit_resolvedhead_'+self.layername) is not None:
- self.commit = self.getProperty('commit_resolvedhead_'+self.layername)
- else:
- self.commit = self.getProperty('commit_' + self.layername)
- if self.commit == "HEAD":
- cmd = 'git ls-remote ' + self.repourl + ' refs/heads/' + self.branch + '|cut -f1'
- elif self.commit is not None:
- cmd = 'echo ' + self.commit
-
- if cmd:
- self.command = cmd
- ShellCommand.start(self)
- else:
- self.finished(SUCCESS)
- self.build.stopBuild('STOPPED!')
-
- def commandComplete(self, cmd):
- result = cmd.logs['stdio'].getText()
- githash= result.strip()
- if cmd.didFail():
- githash = self.commit
- self.setProperty('commit_resolvedhead_'+self.layername, githash, "Setting Layer Version")
- self.setProperty('commit_'+self.layername, githash, "Setting Layer Version")
- log.msg("Setting hash for " + self.layername + " " + self.repourl + " to " + githash)
- self.finished(SUCCESS)
-
- def getText(self, cmd, results):
- return ShellCommand.getText(self, cmd, results)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunBitbakeSelftest.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunBitbakeSelftest.py
deleted file mode 100644
index 7d1874f0..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunBitbakeSelftest.py
+++ /dev/null
@@ -1,28 +0,0 @@
-'''
-Created on May 13, 2013
-
-__author__ = "Stefan Stanacar"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Stefan Stanacar"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Stefan Stanacar"
-__email__ = "stefanx.stanacar@intel.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-
-class RunBitbakeSelftest(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Running bitbake-selftest"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running bitbake-selftest"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- self.command = ". ./oe-init-build-env; bitbake-selftest"
- ShellCommand.__init__(self, **kwargs)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunESDKSanityTests.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunESDKSanityTests.py
deleted file mode 100644
index 1ec26e41..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunESDKSanityTests.py
+++ /dev/null
@@ -1,113 +0,0 @@
-'''
-Created on Aug 18, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-from twisted.python import log as tlog
-import os, re
-
-from lib.buildsteps import BitbakeShellCommand
-
-class RunESDKSanityTests(BitbakeShellCommand):
-
- haltOnFailure = False
- flunkOnFailure = True
- name = "Running ESDK Sanity Tests"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.testsfailed = 0
- self.testspassed = 0
- self.testsnoresult = 0
- self.namefailed = []
- self.namepassed = []
- self.namenoresult = []
- self.images=""
- self.scene=None
- self.suites=None
- self.suitesappend=None
- # the default of 4800 seconds is enough for running sanity tests in most cases
- self.timeout = 14800
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running SDK Sanity Tests"
- kwargs['timeout']=self.timeout
- super(RunESDKSanityTests, self).__init__(factory, argdict=None, **kwargs)
-
- def start(self):
- layerversion = int(self.getProperty("layerversion_core", "0"))
- command = ""
- command = command + ". ./oe-init-build-env; "
- command = command + "checkvnc; "
- if layerversion >= 7:
- command = command + "echo 'INHERIT += \"testsdk\"' >> ./conf/auto.conf;"
- command = command + "echo 'TEST_QEMUBOOT_TIMEOUT = \"1500\"' >> ./conf/auto.conf;"
- if self.suites:
- command = command + "echo 'TEST_SUITES = \"" + self.suites + "\"'" + " >> ./conf/auto.conf;"
- if self.suitesappend:
- command = command + "echo 'TEST_SUITES_append = \" " + self.suitesappend + "\"'" + " >> ./conf/auto.conf;"
- command = command + "DISPLAY=:1 bitbake -v " + self.images + " -c testsdkext"
- self.command = command
- else:
- self.skipStep('Skipping step for older versions.')
- ShellCommand.start(self)
-
-######################################################################
-#
-#
-# Until we get better sanity reporting, I'm commenting this out.
-#
-#
-######################################################################
-
-# def describe(self, done=False):
-# description = ShellCommand.describe(self,done)
-# return description
-
-# def createSummary(self, log):
-# log_text = log.getText()
-# from StringIO import StringIO
-# for line in StringIO(log_text):
-# tlog.msg(line)
-# if "NOTE:" in line:
-# if "0 1 0" in line:
-# self.testsfailed = self.testsfailed + 1
-# self.namefailed.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-# elif "1 0 0" in line:
-# self.testspassed = self.testspassed + 1
-# self.namepassed.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-# elif "0 0 1" in line:
-# self.testsnoresult = self.testsnoresult + 1
-# self.namenoresult.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-
-# def getText(self, cmd, results):
-# text = self.describe(True)[:]
-# text.append("---------")
-# text.append("failed : " + str(self.testsfailed))
-# text.append("")
-# if self.namefailed != []:
-# for test in self.namefailed:
-# text.append(test)
-# text.append("---------")
-# text.append("passed : " + str(self.testspassed))
-# text.append("")
-# if self.namepassed != []:
-# for test in self.namepassed:
-# text.append(test)
-# text.append("---------")
-# text.append("noresult : " + str(self.testsnoresult))
-# text.append("")
-# if self.namenoresult != []:
-# for test in self.namenoresult:
-# text.append(test)
-# text.append("---------")
-# return text
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunOeBuildPerfTest.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunOeBuildPerfTest.py
deleted file mode 100644
index dcc17ddb..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunOeBuildPerfTest.py
+++ /dev/null
@@ -1,78 +0,0 @@
-import os, datetime, subprocess
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-
-from autobuilder.config import PERFORMANCE_PUBLISH_DIR
-
-class OeBuildPerfTestLogLineObserver(LogLineObserver):
- """
- Scans lines in order to save the oe-buil-perf-test command
- output.
- """
-
- def _handleLine(self, line):
- if not hasattr(self.step, 'oe_build_perf_test_output'):
- self.step.oe_build_perf_test_output = ""
- self.step.oe_build_perf_test_match = False
-
- # Search for ### Shell environment set up for builds. ### to start
- # capturing.
- if not self.step.oe_build_perf_test_match and line.startswith('###'):
- self.step.oe_build_perf_test_match = True
-
- if self.step.oe_build_perf_test_match:
- self.step.oe_build_perf_test_output += line + '\n'
-
- def outLineReceived(self, line):
- self._handleLine(line)
-
- def errLineReceived(self, line):
- self._handleLine(line)
-
-class RunOeBuildPerfTest(ShellCommand):
- flunkOnFailure = True
- name = "Running oe-build-perf-test"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.tests = None
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running oe-build-perf-test"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- self.stdio_observer = OeBuildPerfTestLogLineObserver()
- self.addLogObserver('stdio', self.stdio_observer)
-
- def start(self):
- branch = self.getProperty("branch")
- revision = self.getProperty("got_revision")[0:10] # small rev
- machine = self.getProperty("MACHINE")
-
- # for oe-build-perf-test
- timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
- results_basename = 'results-%s-%s-%s' % (branch, revision, timestamp)
- results_dir = os.path.join(PERFORMANCE_PUBLISH_DIR, results_basename)
- lock_file = 'oe-build-perf.lock'
- globalres_log = os.path.join(PERFORMANCE_PUBLISH_DIR, 'globalres.log')
- git_dir = os.path.join(PERFORMANCE_PUBLISH_DIR, 'git')
-
- self.setProperty("oe_perf_globalres_log", globalres_log, "RunOeBuildPerfTest")
- self.setProperty("oe_perf_results_dir", results_dir, "RunOeBuildPerfTest")
-
- self.command = "mkdir -p %s; " % (results_dir)
-
- self.command += ". ./oe-init-build-env; "
- self.command += """ oe-build-perf-test --out-dir "%s" \
---globalres-file "%s" --lock-file "%s" --commit-results "%s" --commit-results-branch "{tester_host}/{git_branch}/%s" \
---commit-results-tag "{tester_host}/{git_branch}/%s/{git_commit_count}-g{git_commit}/{tag_num}"
-""" % (results_dir, globalres_log, lock_file, git_dir, machine, machine)
-
-
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- self.setProperty("oe_build_perf_test_output",
- self.oe_build_perf_test_output, "RunOeBuildPerfTest")
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py
deleted file mode 100644
index eb53f9c4..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py
+++ /dev/null
@@ -1,109 +0,0 @@
-'''
-__author__ = "Stefan Stanacar"
-__copyright__ = "Copyright 2014 Intel Corporation"
-__credits__ = ["Stefan Stanacar"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Stefan Stanacar"
-__email__ = "stefanx.stanacar@intel.com"
-'''
-
-import platform
-
-from buildbot.steps.shell import ShellCommand
-
-from lib.ABTools import save_error_report, get_lsb_distro
-from lib.buildsteps import BitbakeShellCommand
-
-class RunOeSelftest(BitbakeShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Running oe-selftest"
- def __init__(self, factory, argdict=None, **kwargs):
- self.tests = None
- self.skiptests = None
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running oe-selftest"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.command = ""
- self.command += ". ./oe-init-build-env; "
- self.command += "checkvnc; "
-
- self.layerversion_core = \
- int(self.getProperty("layerversion_core", "0"))
-
- if self.tests == '#SCRAPEDTARGETS':
- self.tests = self.getProperty("scraped_targets")
-
- testcmd = "--run-all-tests"
- if self.skiptests and self.layerversion_core >= 11:
- # -R/--skip-tests was only added in Rocko
- testcmd = "--skip-tests " + self.skiptests
- elif self.tests:
- testcmd = "--run-tests " + self.tests
-
- # test_checkpkg was only added in Rocko (layer version 11), filter that
- # test out on layer versions prior to 11. If we filter the tests and
- # the resulting filtered list is empty we need not run oe-selftest.
- shouldrun = True
- if self.tests and self.layerversion_core < 11:
- self.tests = \
- self.tests.replace("distrodata.Distrodata.test_checkpkg", "")
- if len(self.tests.strip()) == 0:
- shouldrun = False
-
- if shouldrun:
- self.command += "if [ -d ../meta-selftest ]; then export DISPLAY=:1; oe-selftest " + testcmd + "; else echo 'Skipping step - no meta-selftest layer here'; fi"
- else:
- self.skipStep("Skipping due to tests having been filtered out.")
- ShellCommand.start(self)
-
- def _createOESelftestErrorReport(self, log):
- """
- Create a oe-selftest error report since oe-selftest
- is intended to test the build system no information
- about machine, distro and target_sys are provided so
- use universal value.
- """
-
- report = {}
-
- report['machine'] = 'universal'
- report['build_sys'] = "%s-%s" % (platform.machine(),
- platform.system().lower())
- # XXX: Set to universal because isn't easy to get Autobuilder
- # worker distro.
- report['nativelsb'] = 'universal'
- report['distro'] = 'universal'
- report['target_sys'] = 'universal'
-
- report['component'] = 'oe-selftest'
- report['branch_commit'] = self.getProperty('branch') + ': ' + \
- self.getProperty('got_revision')
-
- report['error_type'] = 'oe-selftest'
-
- failure = {}
- failure['package'] = 'oe-selftest'
- failure['task'] = self.command[self.command.find('oe-selftest'):]
- failure['log'] = log
-
- report['failures'] = [failure]
-
- return report
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- buildername = self.getProperty('buildername')
- buildnumber = self.getProperty('buildnumber')
-
- log = cmd.logs['stdio'].getText()
-
- report = self._createOESelftestErrorReport(log)
- save_error_report(buildername, buildnumber, report, 'oe_selftest')
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunPreamble.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunPreamble.py
deleted file mode 100644
index e9de3c76..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunPreamble.py
+++ /dev/null
@@ -1,30 +0,0 @@
-'''
-Created on Jan 6, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-
-class RunPreamble(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "RunPreamble"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.altcmd = ""
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running Preamble"
- if self.altcmd == "":
- self.command = ". ./oe-init-build-env"
- else:
- self.command = ". ./" + self.altcmd
- ShellCommand.__init__(self, **kwargs)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunSDKSanityTests.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunSDKSanityTests.py
deleted file mode 100644
index 4835faf7..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunSDKSanityTests.py
+++ /dev/null
@@ -1,116 +0,0 @@
-'''
-Created on Aug 18, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-from twisted.python import log as tlog
-import os, re
-
-from lib.buildsteps import BitbakeShellCommand
-
-class RunSDKSanityTests(BitbakeShellCommand):
-
- haltOnFailure = False
- flunkOnFailure = True
- name = "Running SDK Sanity Tests"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.testsfailed = 0
- self.testspassed = 0
- self.testsnoresult = 0
- self.namefailed = []
- self.namepassed = []
- self.namenoresult = []
- self.images=""
- self.scene=None
- self.suites=None
- self.suitesappend=None
- # the default of 4800 seconds is enough for running sanity tests in most cases
- self.timeout = 14800
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running SDK Sanity Tests"
- kwargs['timeout']=self.timeout
- super(RunSDKSanityTests, self).__init__(factory, argdict=None, **kwargs)
-
- def start(self):
- layerversion = int(self.getProperty("layerversion_core", "0"))
- command = ""
- command = command + ". ./oe-init-build-env; "
- command = command + "checkvnc; "
- if layerversion >= 6:
- command = command + "echo 'INHERIT += \"testimage\"' >> ./conf/auto.conf;"
- command = command + "echo 'TEST_QEMUBOOT_TIMEOUT = \"1500\"' >> ./conf/auto.conf;"
- if self.suites:
- if layerversion > 3:
- command = command + "echo 'TEST_SUITES = \"" + self.suites + "\"'" + " >> ./conf/auto.conf;"
- else:
- command = command + "echo 'TEST_SUITES = \"" + self.suites.replace('kernelmodule', '').replace('python', '') + "\"'" + " >> ./conf/auto.conf;"
- if self.suitesappend:
- command = command + "echo 'TEST_SUITES_append = \" " + self.suitesappend + "\"'" + " >> ./conf/auto.conf;"
- command = command + "DISPLAY=:1 bitbake -v " + self.images + " -c testsdk"
- else:
- command = "echo 'Skipping step.'"
- self.command = command
- ShellCommand.start(self)
-
-######################################################################
-#
-#
-# Until we get better sanity reporting, I'm commenting this out.
-#
-#
-######################################################################
-
-# def describe(self, done=False):
-# description = ShellCommand.describe(self,done)
-# return description
-
-# def createSummary(self, log):
-# log_text = log.getText()
-# from StringIO import StringIO
-# for line in StringIO(log_text):
-# tlog.msg(line)
-# if "NOTE:" in line:
-# if "0 1 0" in line:
-# self.testsfailed = self.testsfailed + 1
-# self.namefailed.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-# elif "1 0 0" in line:
-# self.testspassed = self.testspassed + 1
-# self.namepassed.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-# elif "0 0 1" in line:
-# self.testsnoresult = self.testsnoresult + 1
-# self.namenoresult.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-
-# def getText(self, cmd, results):
-# text = self.describe(True)[:]
-# text.append("---------")
-# text.append("failed : " + str(self.testsfailed))
-# text.append("")
-# if self.namefailed != []:
-# for test in self.namefailed:
-# text.append(test)
-# text.append("---------")
-# text.append("passed : " + str(self.testspassed))
-# text.append("")
-# if self.namepassed != []:
-# for test in self.namepassed:
-# text.append(test)
-# text.append("---------")
-# text.append("noresult : " + str(self.testsnoresult))
-# text.append("")
-# if self.namenoresult != []:
-# for test in self.namenoresult:
-# text.append(test)
-# text.append("---------")
-# return text
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/RunSanityTests.py b/lib/python2.7/site-packages/autobuilder/buildsteps/RunSanityTests.py
deleted file mode 100644
index c52672e9..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/RunSanityTests.py
+++ /dev/null
@@ -1,139 +0,0 @@
-'''
-Created on Jan 10, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-from twisted.python import log as tlog
-import os, re
-
-from lib.buildsteps import BitbakeShellCommand
-
-class RunSanityTests(BitbakeShellCommand):
-
- haltOnFailure = False
- flunkOnFailure = True
- name = "Running Sanity Tests"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.testsfailed = 0
- self.testspassed = 0
- self.testsnoresult = 0
- self.namefailed = []
- self.namepassed = []
- self.namenoresult = []
- self.images=""
- self.scene=None
- self.suites=None
- self.suitesappend=None
- # the default of 4800 seconds is enough for running sanity tests in most cases
- self.timeout = 14800
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running Sanity Tests"
- kwargs['timeout']=self.timeout
- super(RunSanityTests, self).__init__(factory, argdict=None, **kwargs)
-
- def start(self):
- localconf = self.getProperty("LOCALCONF")
- layerversion = int(self.getProperty("layerversion_core", "0"))
- distro = self.getProperty("DISTRO")
- self.command = ""
- self.command = self.command + ". ./oe-init-build-env; "
- self.command = self.command + "checkvnc; "
- if distro == "poky-lsb" and layerversion < 6:
- self.skipStep('Skipping step.')
- elif layerversion < 9 and 'musl' in localconf:
- self.skipStep('Skipping step for musl.')
- # Releases older than Rocko didn't build core-image-sato-sdk
- # with musl.
- elif layerversion < 11 and 'musl' in localconf:
- self.images = self.images.replace("core-image-sato-sdk", "core-image-sato")
- elif layerversion < 8 \
- and 'DISTRO_FEATURES_remove="x11"' in localconf.replace(" ", ""):
- self.skipStep('Skipping step for no-x11.')
- elif layerversion > 1:
- self.command = self.command + "echo 'INHERIT += \"testimage\"' >> ./conf/auto.conf;"
- self.command = self.command + "echo 'TEST_QEMUBOOT_TIMEOUT = \"1500\"' >> ./conf/auto.conf;"
-
- target_ip = self.getProperty('target_ip')
- server_ip = self.getProperty('server_ip')
- if target_ip and server_ip:
- self.command = self.command + "echo 'TEST_TARGET=\"simpleremote\"' >> ./conf/auto.conf;"
- self.command = self.command + "echo 'TEST_TARGET_IP=\"%s\"' >> ./conf/auto.conf;" % target_ip
- self.command = self.command + "echo 'TEST_SERVER_IP=\"%s\"' >> ./conf/auto.conf;" % server_ip
-
- if self.suites:
- if layerversion > 3:
- self.command = self.command + "echo 'TEST_SUITES = \"" + self.suites + "\"'" + " >> ./conf/auto.conf;"
- else:
- self.command = self.command + "echo 'TEST_SUITES = \"" + self.suites.replace('kernelmodule', '').replace('python', '') + "\"'" + " >> ./conf/auto.conf;"
- if self.suitesappend:
- self.command = self.command + "echo 'TEST_SUITES_append = \" " + self.suitesappend + "\"'" + " >> ./conf/auto.conf;"
- self.command = self.command + "DISPLAY=:1 bitbake -v " + self.images + " -c testimage"
- else:
- self.command = self.command + "echo 'IMAGETEST = \"qemu\"' >> ./conf/auto.conf;"
- if self.scene:
- self.command = self.command + "echo 'TEST_SCEN = \"" + self.scene + "\"'" + " >> ./conf/auto.conf;"
- self.command = self.command + "DISPLAY=localhost:1 bitbake -v " + self.images + " -c qemuimagetest_standalone"
- ShellCommand.start(self)
-
-######################################################################
-#
-#
-# Until we get better sanity reporting, I'm commenting this out.
-#
-#
-######################################################################
-
-# def describe(self, done=False):
-# description = ShellCommand.describe(self,done)
-# return description
-
-# def createSummary(self, log):
-# log_text = log.getText()
-# from StringIO import StringIO
-# for line in StringIO(log_text):
-# tlog.msg(line)
-# if "NOTE:" in line:
-# if "0 1 0" in line:
-# self.testsfailed = self.testsfailed + 1
-# self.namefailed.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-# elif "1 0 0" in line:
-# self.testspassed = self.testspassed + 1
-# self.namepassed.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-# elif "0 0 1" in line:
-# self.testsnoresult = self.testsnoresult + 1
-# self.namenoresult.append(line.replace("|","").replace(" ", "").replace("NOTE:", "").replace("0","").replace("1","").replace("\n","").replace("\t",""))
-
-# def getText(self, cmd, results):
-# text = self.describe(True)[:]
-# text.append("---------")
-# text.append("failed : " + str(self.testsfailed))
-# text.append("")
-# if self.namefailed != []:
-# for test in self.namefailed:
-# text.append(test)
-# text.append("---------")
-# text.append("passed : " + str(self.testspassed))
-# text.append("")
-# if self.namepassed != []:
-# for test in self.namepassed:
-# text.append(test)
-# text.append("---------")
-# text.append("noresult : " + str(self.testsnoresult))
-# text.append("")
-# if self.namenoresult != []:
-# for test in self.namenoresult:
-# text.append(test)
-# text.append("---------")
-# return text
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ScrapeTargets.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ScrapeTargets.py
deleted file mode 100644
index 0480f3de..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ScrapeTargets.py
+++ /dev/null
@@ -1,67 +0,0 @@
-'''
-Created on Apr 27, 2017
-
-__author__ = "Joshua Lock"
-__copyright__ = "Copyright 2017, Intel Corp."
-__credits__ = ["Joshua Lock"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Joshua Lock"
-__email__ = "joshua.g.lock@intel.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-from autobuilder.config import *
-import os
-import re
-
-class ScrapeTargets(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "ScrapeTargets"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self._pendingLogObservers = []
- self.source = ""
- self.targetsvar = ""
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout'] = self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- if not self.targetsvar or not self.source:
- self.step_status.setText(["Scrape incorrectly configured."])
- self.finished(FAILURE)
- return
-
- workerdir = os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- buildername = self.getProperty("buildername")
- src = os.path.join(workerdir, buildername, "build", self.source)
- self.command = ["cat", src]
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- return
-
- result = cmd.logs['stdio'].getText()
- start = result.find(self.targetsvar) + len(self.targetsvar)
- res = re.search('"([^"]*)"', result[start:])
- targets = ""
- if res:
- targets = res.group()
- # Try and ensure we scrape the target regardless of which
- # assignment operator is used and surrounding whitespace
- targets = targets.replace(self.targetsvar, '')
- targets = targets.translate(None, ':+?="')
- targets = targets.replace("\\", "")
- targets = targets.replace ("\n", "")
- self.setProperty("scraped_targets",
- targets,
- 'Targets "%s" scraped from %s' % (targets,
- self.source))
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/SendErrorReport.py b/lib/python2.7/site-packages/autobuilder/buildsteps/SendErrorReport.py
deleted file mode 100644
index c4e377c4..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/SendErrorReport.py
+++ /dev/null
@@ -1,78 +0,0 @@
-'''
-Created on Jan 6, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-import os
-
-from buildbot.steps.shell import ShellCommand
-
-from lib.ABTools import get_error_report_worker_dir
-
-class SendErrorReport(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "SendErrorReport"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.buildername=self.getProperty("buildername")
- self.buildnumber=self.getProperty("buildnumber")
- self.errordir = get_error_report_worker_dir(self.buildername)
- self.layerversion_core = int(self.getProperty("layerversion_core", "0"))
- self.command=""
-
- if self.layerversion_core < 4:
- self.command = "echo 'Skipping Step.'"
- else:
- if str(os.environ.get('ERROR_REPORT_COLLECT')) == "True":
- self.command += "rm -rf ~/.oe-send-error;"
- self.command += "echo ${ERROR_REPORT_SUBMITTER_ID};"
- self.command += " if [ -z ${ERROR_REPORT_SUBMITTER_ID}+x ]; then host=`hostname`; echo \"yocto-autobuilder-autogenerated-$host\" > ~/.oe-send-error; else echo \"$ERROR_REPORT_SUBMITTER_ID\" > ~/.oe-send-error; fi ; "
- self.command += ". ./oe-init-build-env; if [ -d " + self.errordir + " ]; then for x in `ls " + self.errordir + " | grep error_report_`;"
-
- if self.layerversion_core == 4:
- if os.environ.get('ERROR_REPORT_SERVER') is not None:
- self.er_server = str(os.environ.get('ERROR_REPORT_SERVER'))
- else:
- self.er_server = ""
- self.command += "do send-error-report " + self.errordir +"/$x"+ self.er_server + "; done; fi"
- elif self.layerversion_core >= 5:
- master = self.build.builder.botmaster.parent
- self.er_link = " -l " + master.status.getURLForBuild(self.buildername, self.buildnumber)
- if os.environ.get('ERROR_REPORT_SERVER') is not None:
- self.er_server = " -s " + str(os.environ.get('ERROR_REPORT_SERVER'))
- else:
- self.er_server = ""
- if os.environ.get('ERROR_REPORT_EMAIL') is not None:
- self.er_email = " -e " + str(os.environ.get('ERROR_REPORT_EMAIL'))
- else:
- self.er_email = ""
- if os.environ.get('ERROR_REPORT_NAME') is not None:
- self.er_name = " -n " + str(os.environ.get('ERROR_REPORT_NAME'))
- else:
- self.er_name = ""
- self.command += "do send-error-report -y "
- self.command += self.er_server + self.er_email
- self.command += self.er_name + self.er_link
- self.command += " " + self.errordir +"/$x; done; fi"
- else:
- self.command = "echo 'Layer doesn't support error reporting - Step is noop'"
- else:
- self.command = "echo 'environment var ERROR_REPORT_COLLECT not set - Step is noop'"
- self.description = ["Sending error reports"]
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/SendOePerfEmail.py b/lib/python2.7/site-packages/autobuilder/buildsteps/SendOePerfEmail.py
deleted file mode 100644
index 60543973..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/SendOePerfEmail.py
+++ /dev/null
@@ -1,64 +0,0 @@
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import SKIPPED
-import os, subprocess
-
-class SendOePerfEmail(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "SendOePerfEmail"
- description = ["Sending Performance Email"]
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- description = ["Sending alert emails"]
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- if not os.environ.get("PERFORMANCE_SEND_EMAIL") == "True":
- return SKIPPED
-
- branch = self.getProperty("branch")
- oe_build_perf_test_output = self.getProperty("oe_build_perf_test_output")
- mailto = ""
- mailcc = ""
- mailbcc = ""
- mailsig = ""
- if os.environ.get('PERFORMANCE_MAIL_TO'):
- mailto = os.environ.get('PERFORMANCE_MAIL_TO')
- if os.environ.get('PERFORMANCE_MAIL_CC'):
- mailcc = os.environ.get('PERFORMANCE_MAIL_CC')
- if os.environ.get('PERFORMANCE_MAIL_BCC'):
- mailbcc = os.environ.get('PERFORMANCE_MAIL_BCC')
- if os.environ.get('PERFORMANCE_MAIL_SIG'):
- mailsig = os.environ.get('PERFORMANCE_MAIL_SIG')
-
- archive_dir = self.getProperty("oe_perf_archive_dir")
- globalres_log = self.getProperty("oe_perf_globalres_log")
- email_base = '''
-Running on %s \n
-
-%s
-
------------------\n\n Global results file \n\n""$read_file"" \n
------------------\n\n Archive results in %s \n''' % (oe_build_perf_test_output,
- os.uname()[1], archive_dir)
-
- mailsubject = "Build Performance Report - %s branch" % (branch)
- email_header = ""
- if mailto is not None and mailto is not "":
- email_header += "To: " + mailto + "\n"
- if mailcc is not None and mailcc is not "":
- email_header += "Cc: " + mailcc + "\n"
- if mailbcc is not None and mailbcc is not "":
- email_header += "Bcc: " + mailbcc + "\n"
-
- email_header += "Subject: " + mailsubject + "\n"
- mailcmd = 'read_file=`cat %s`;' %(globalres_log)
- mailcmd += ' echo "' + email_header + '\n' + email_base + '\n' + mailsig + '" | sendmail -t;'
- self.command = mailcmd
-
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/SendQAEmail.py b/lib/python2.7/site-packages/autobuilder/buildsteps/SendQAEmail.py
deleted file mode 100644
index d92aca8e..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/SendQAEmail.py
+++ /dev/null
@@ -1,103 +0,0 @@
-'''
-Created on Aug 26, 2014
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2014, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.properties import Properties
-import os
-
-class SendQAEmail(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "SendQAEmail"
- description = ["Sending QA Email"]
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- description = ["Sending alert emails"]
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- if self.getProperty("custom_send_email") == 'True':
- web_root = os.environ.get('WEB_ROOT')
- web_url = os.environ.get('WEB_URL')
- mailto = ""
- mailcc = ""
- mailbcc = ""
- if os.environ.get('QA_MAIL_TO'):
- mailto = os.environ.get('QA_MAIL_TO')
- if os.environ.get('QA_MAIL_CC'):
- mailcc = os.environ.get('QA_MAIL_CC')
- if os.environ.get('QA_MAIL_BCC'):
- mailbcc = os.environ.get('QA_MAIL_BCC')
- mailsig = os.environ.get('QA_MAIL_SIG')
- properties = self.build.getProperties().asDict()
- repoprops = {}
- mailsubject = "Build available for QA"
- email_base = '''
-A build identified as needing QA has finished on the autobuilder. This
-build is located at:\n\n
- %s''' % (self.getProperty('DEST').replace(web_root, web_url))
-
- if str(self.getProperty("custom_release_me")) == "True":
- is_milestone = self.getProperty("custom_is_milestone")
- milestone_number = self.getProperty("custom_milestone_number")
- rc_number = self.getProperty("custom_rc_number")
-
- if is_milestone == "False":
- snapshot = "."+rc_number
- elif is_milestone == "True" and milestone_number is not "" and rc_number is not "":
- snapshot = "_"+milestone_number+"."+rc_number
- else:
- snapshot = ""
- prefix = snapshot
- poky_name = self.getProperty("custom_poky_name")+prefix
- poky_number = self.getProperty("custom_poky_number")+prefix
- yocto_number = self.getProperty("custom_yocto_number")+prefix
- rel_name = 'yocto-'+ yocto_number
- email_base = '''
-A release candidate build for %s is now available at:\n\n
- %s\n\n
-Please begin QA on this build as soon as possible.''' % (rel_name, self.getProperty('DEST').replace(web_root, web_url))
- mailsubject = "Release Candidate Build for " + rel_name + " now available."
-
-
- for k, v in properties.iteritems():
- if "repourl_" in k:
- name = k.replace("repourl_", '')
- repourl = str(v[0])
- githash = properties["commit_"+name][0]
- repoprops[name]=repourl, githash
- email_body = '\n\nBuild hash information: \n'
- for k, v in repoprops.iteritems():
- email_body = email_body + '%s : %s \n' % (k, v[1])
-
- email_header = ""
- if mailto is not None and mailto is not "":
- email_header += "To: " + mailto + "\n"
- if mailcc is not None and mailcc is not "":
- email_header += "Cc: " + mailcc + "\n"
- if mailbcc is not None and mailbcc is not "":
- email_header += "Bcc: " + mailbcc + "\n"
-
- email_header += "Subject: " + mailsubject + "\n"
-
- mailcmd = 'echo "' + email_header + "\n" + email_base + '\n' + email_body + '\n' + mailsig + ' " | sendmail -t'
-
- self.command = mailcmd
- else:
- self.command = 'echo "Not a QA build"'
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/SetDest.py b/lib/python2.7/site-packages/autobuilder/buildsteps/SetDest.py
deleted file mode 100644
index ec7e4335..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/SetDest.py
+++ /dev/null
@@ -1,107 +0,0 @@
-'''
-Created on Dec 25, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED, \
- EXCEPTION, RETRY, worst_status
-import os, datetime
-import cPickle as pickle
-from autobuilder.config import *
-from twisted.python import log
-from buildbot.steps.shell import ShellCommand
-
-class SetDest(ShellCommand):
- name = "SetDest"
- haltOnFailure = True
- flunkOnFailure = True
- name = "Destination"
- description = ["Setting %s" % name]
- descriptionDone = [name]
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.target=""
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.workerworkdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- self.description = ["Setting", "Destination"]
-
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Setting Destination"
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- DEST = self.getProperty("DEST")
- snapshot = ""
- if DEST is not None:
- self.finished(SUCCESS)
- else:
- buildername=self.getProperty("buildername")
- self.workdir=os.path.join(self.workerworkdir, buildername)
- if str(self.getProperty("custom_release_me")) == "True":
- is_milestone = self.getProperty("custom_is_milestone")
- milestone_number = self.getProperty("custom_milestone_number")
- rc_number = self.getProperty("custom_rc_number")
-
- if is_milestone == "False":
- snapshot = "."+rc_number
- elif is_milestone == "True" and milestone_number is not "" and rc_number is not "":
- snapshot = "_"+milestone_number+"."+rc_number
- else:
- snapshot = ""
- prefix = snapshot
- poky_name = self.getProperty("custom_poky_name")+prefix
- poky_number = self.getProperty("custom_poky_number")+prefix
- yocto_number = self.getProperty("custom_yocto_number")+prefix
- rel_name = 'yocto-'+ yocto_number
- if not rel_name or rel_name == "":
- rel_name = self.getProperty(commit-description)
- DEST=os.path.normpath(os.path.join(
- os.environ.get("RELEASE_PUBLISH_DIR"),rel_name))
- if os.environ.get("RELEASE_PUBLISH_DIR") not in DEST:
- self.step_status.setText(["Failed Setting Destination:", "Bad Release Name."])
- self.finished(FAILURE)
- else:
- DEST = os.path.normpath(os.path.join(
- os.environ.get("BUILD_PUBLISH_DIR"), buildername))
- if os.environ.get("BUILD_PUBLISH_DIR") not in DEST:
- self.step_status.setText(["Failed Setting Destination:", "Bad Release Name."])
- self.finished(FAILURE)
- DEST_DATE=datetime.datetime.now().strftime("%Y%m%d")
- DATA_FILE = os.path.join(YOCTO_ABBASE, self.target + "_dest.dat")
- try:
- pfile = open(DATA_FILE, 'rb')
- data = pickle.load(pfile)
- except:
- pfile = open(DATA_FILE, 'wb')
- data = {}
- pickle.dump(data, pfile)
- pfile.close()
- # we can't os.path.exists here as we don't neccessarily have
- # access to the worker dest from controller. So we keep a cpickle of
- # the dests.
- try:
- # if the dictionary entry exists, we increment value by one, then repickle
- REV=data[os.path.join(DEST, DEST_DATE)]
- REV=int(REV) + 1
- except:
- REV=1
- data[os.path.join(DEST, DEST_DATE)] = REV
- pfile = open(DATA_FILE, 'wb')
- pickle.dump(data, pfile)
- pfile.close()
-
- DEST = os.path.join(DEST, DEST_DATE + "-" + str(REV))
- self.setProperty("DEST", DEST)
- self.finished(SUCCESS)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/SetupDistroData.py b/lib/python2.7/site-packages/autobuilder/buildsteps/SetupDistroData.py
deleted file mode 100644
index 2d3a68bc..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/SetupDistroData.py
+++ /dev/null
@@ -1,37 +0,0 @@
-'''
-Created on March 11, 2016
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2016, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-from buildbot.steps.shell import ShellCommand
-from twisted.python import log
-import os, datetime
-from autobuilder.config import *
-
-class SetupDistroData(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "Publishing Artifacts"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Setting Up DistroData"
- self.dvdir=os.path.join(os.path.join(YOCTO_ABBASE, "etc/distro-version"))
- for k, v in argdict.iteritems():
- if type(v) is bool:
- setattr(self, k, str(v))
- else:
- setattr(self, k, v)
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.command="cp -R " + self.dvdir + "/* /tmp;"
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/Sleep.py b/lib/python2.7/site-packages/autobuilder/buildsteps/Sleep.py
deleted file mode 100644
index 91dcbed3..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/Sleep.py
+++ /dev/null
@@ -1,58 +0,0 @@
-'''
-Created on Dec 22, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-
-class Sleep(ShellCommand):
- haltOnFailure = True
- flunkOnFailure = True
- name = "Sleep"
- def __init__(self, factory, argdict=None, **kwargs):
- self.time="0"
- self.funny="False"
- self.factory = factory
- for k, v in argdict.iteritems():
- if k=="time":
- self.time=v
- else:
- setattr(self, k, v)
- sleep_quotes = ["Sleep, those little slices of death, how I loathe them.",
- "No day is so bad it can't be fixed with a nap.",
- "People who say they sleep like a baby usually don't have one.",
- "Life is too short to sleep on low thread-count sheets",
- "Sleep is a symptom of caffeine deprivation.",
- "Without enough sleep, we all become tall two-year-olds.",
- "I'm not asleep... but that doesn't mean I'm awake.",
- "When you have insomnia, you're never really asleep, and you're never really awake.",
- "Life is something that happens when you can't get to sleep.",
- "Sleeping is no mean art: for its sake one must stay awake all day.",
- "I count it as a certainty that in paradise, everyone naps.",
- "Early to rise and early to bed, makes a man healthy and wealthy and dead.",
- "I like sleeping, its like death without commitment.",
- "I do 5 sit-ups every morning. May not sound like much, but there's only so many times you can hit the snooze button.",
- "The early bird gets the worm. The early worm...gets eaten."]
- from random import choice
- if self.funny == "True":
- self.description = choice(sleep_quotes) + "<br><br>Sleeping for " + self.time + " sec."
- else:
- self.description = "Sleeping for " + self.time + " sec."
- self.command = "/bin/sleep " + self.time
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 1000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def describe(self, done=False):
- description = ShellCommand.describe(self,done)
- return description
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/TarballOeBuildPerfTest.py b/lib/python2.7/site-packages/autobuilder/buildsteps/TarballOeBuildPerfTest.py
deleted file mode 100644
index ca60c937..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/TarballOeBuildPerfTest.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import os, datetime, subprocess
-from buildbot.steps.shell import ShellCommand
-from autobuilder.config import PERFORMANCE_PUBLISH_DIR
-
-class TarballOeBuildPerfTest(ShellCommand):
- flunkOnFailure = True
- name = "Tarball oe-build-perf-test results"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.tests = None
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Running tarball oe-build-perf-test results"
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- results_dir = self.getProperty("oe_perf_results_dir")
-
- results_basename = os.path.basename(results_dir)
- archive_dir = os.path.join(PERFORMANCE_PUBLISH_DIR, 'archives')
- archive_file = os.path.join(archive_dir, results_basename + '.tar.gz')
-
- self.setProperty("oe_perf_archive_dir", archive_dir, "TarballOeBuildPerfTest")
- self.setProperty("oe_perf_archive_file", archive_dir, "TarballOeBuildPerfTest")
-
- self.command = "mkdir -p %s; " % archive_dir
- self.command += "tar -czf \"%s\" \"%s\"" % (archive_file, results_dir)
-
- ShellCommand.start(self)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/TestFailStep.py b/lib/python2.7/site-packages/autobuilder/buildsteps/TestFailStep.py
deleted file mode 100644
index 5c18a777..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/TestFailStep.py
+++ /dev/null
@@ -1,30 +0,0 @@
-'''
-Created on Dec 26, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import FAILURE
-
-class TestFailStep(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "TestFailStep"
- def __init__(self, factory, argdict=None, **kwargs):
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.description = "Generic Fail Step"
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- self.command="echo 'Failing out'"
- ShellCommand.__init__(self, **kwargs)
-
- def commandComplete(self, cmd):
- self.finished(FAILURE)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterRunTests.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterRunTests.py
deleted file mode 100644
index 141768cb..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterRunTests.py
+++ /dev/null
@@ -1,31 +0,0 @@
-'''
-Created on Feb 15, 2016
-
-__author__ = "Anibal (alimon) Limon"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Anibal Limon"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Anibal Limon"
-__email__ = "anibal.limon@linux.intel.com"
-'''
-
-from lib.buildsteps import ShellCommandCleanEnv
-import os
-
-class ToasterRunTests(ShellCommandCleanEnv):
- haltOnFailure = True
- flunkOnFailure = True
- name = "ToasterRunTests"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Running toaster tests..."
-
- oe_cmd = "source ./oe-init-build-env;"
- venv_cmd = "source venv/bin/activate;"
- cmd = "DISPLAY=:1 toaster-test --run-all-tests --verbose"
-
- self.command = oe_cmd + venv_cmd + cmd
-
- ShellCommandCleanEnv.__init__(self, factory, argdict, **kwargs)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterSetupVenv.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterSetupVenv.py
deleted file mode 100644
index 4b22baf1..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterSetupVenv.py
+++ /dev/null
@@ -1,31 +0,0 @@
-'''
-Created on Feb 15, 2016
-
-__author__ = "Anibal (alimon) Limon"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Anibal Limon"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Anibal Limon"
-__email__ = "anibal.limon@linux.intel.com"
-'''
-
-from lib.buildsteps import ShellCommandCleanEnv
-
-class ToasterSetupVenv(ShellCommandCleanEnv):
- haltOnFailure = True
- flunkOnFailure = True
- name = "ToasterSetupVenv"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Creating virtualenv..."
-
- oe_cmd = "source ./oe-init-build-env;"
- venv_cmd = "virtualenv venv; source venv/bin/activate;"
- install_cmd = "pip install -r ../bitbake/toaster-requirements.txt;"
- install_tests_cmd = "pip install -r ../bitbake/toaster-tests-requirements.txt;"
-
- self.command = oe_cmd + venv_cmd + install_cmd + install_tests_cmd
-
- ShellCommandCleanEnv.__init__(self, factory, argdict, **kwargs)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStart.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStart.py
deleted file mode 100644
index 14cf9db3..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStart.py
+++ /dev/null
@@ -1,32 +0,0 @@
-'''
-Created on Feb 15, 2016
-
-__author__ = "Anibal (alimon) Limon"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Anibal Limon"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Anibal Limon"
-__email__ = "anibal.limon@linux.intel.com"
-'''
-
-from lib.buildsteps import ShellCommandCleanEnv
-import os
-
-class ToasterStart(ShellCommandCleanEnv):
- haltOnFailure = True
- flunkOnFailure = True
- name = "ToasterStart"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Starting toaster..."
-
- oe_cmd = "source ./oe-init-build-env;"
- venv_cmd = "source venv/bin/activate;"
- start_cmd = "../bitbake/lib/toaster/tests/helpers.py -a start" \
- " -d $(readlink -e ../)"
-
- self.command = oe_cmd + venv_cmd + start_cmd
-
- ShellCommandCleanEnv.__init__(self, factory, argdict, **kwargs)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStop.py b/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStop.py
deleted file mode 100644
index 6fda0e8f..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/ToasterStop.py
+++ /dev/null
@@ -1,33 +0,0 @@
-'''
-Created on Feb 15, 2016
-
-__author__ = "Anibal (alimon) Limon"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Anibal Limon"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Anibal Limon"
-__email__ = "anibal.limon@linux.intel.com"
-'''
-
-from lib.buildsteps import ShellCommandCleanEnv
-import os
-
-class ToasterStop(ShellCommandCleanEnv):
- alwaysRun = True
- haltOnFailure = True
- flunkOnFailure = True
- name = "ToasterStop"
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.description = "Stopping toaster..."
-
- oe_cmd = "source ./oe-init-build-env;"
- venv_cmd = "source venv/bin/activate;"
- start_cmd = "../bitbake/lib/toaster/tests/helpers.py -a stop" \
- " -d $(readlink -e ../)"
-
- self.command = oe_cmd + venv_cmd + start_cmd
-
- ShellCommandCleanEnv.__init__(self, factory, argdict, **kwargs)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/TriggerBuilds.py b/lib/python2.7/site-packages/autobuilder/buildsteps/TriggerBuilds.py
deleted file mode 100644
index 80568595..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/TriggerBuilds.py
+++ /dev/null
@@ -1,52 +0,0 @@
-'''
-Created on Jan 15, 2013
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.scheduler import Scheduler
-from buildbot.steps.trigger import Trigger
-from buildbot.process.properties import Properties, Property
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import config
-import ast
-
-class TriggerBuilds():
- name = "trigger"
-
- renderables = [ 'set_properties', 'schedulerNames', 'sourceStamps',
- 'updateSourceStamp', 'alwaysUseLatest' ]
-
- flunkOnFailure = True
-
- def __init__(self, factory, argdict=None, **kwargs):
- self.set_properties = {}
- self.schedulerNames={}
- self.copy_properties = []
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- if not self.schedulerNames:
- config.error(
- "You must specify a scheduler to trigger")
- else:
- for x in self.schedulerNames.iterkeys():
- self.scheduler = 'trigger_'+x
- log.msg(self.set_properties}
- self.waitForFinish = False
- if self.schedulerNames[x]:
- for prop in self.schedulerNames[x].iterkeys():
- setattr(self, prop, self.schedulerNames[x][prop])
- factory.addStep(Trigger(schedulerNames=self.scheduler],
- updateSourceStamp=False,
- set_properties=self.set_properties,
- waitForFinish=self.waitForFinish,
- copy_properties=self.copy_properties))
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/UpdateBuildHistory.py b/lib/python2.7/site-packages/autobuilder/buildsteps/UpdateBuildHistory.py
deleted file mode 100644
index 48c16fa2..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/UpdateBuildHistory.py
+++ /dev/null
@@ -1,49 +0,0 @@
-'''
-Created on Jan 12, 2015
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2015, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "pidge@toganlabs.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from autobuilder.config import *
-import os, ast
-
-class UpdateBuildHistory(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = False
- name = "Update Build History"
- def __init__(self, factory, argdict=None, **kwargs):
- self.machines=""
- self.factory = factory
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 100000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- repo = self.getProperty("repo_poky")
- self.command = "echo 'Skipping Step.'"
- if os.environ.get('BUILD_HISTORY_WHITELIST') is not None:
- history_repos=ast.literal_eval(os.environ.get('BUILD_HISTORY_WHITELIST').encode('utf-8'))
- if history_repos is not None and repo in history_repos.keys():
- if self.getProperty("branch_poky") in history_repos[self.getProperty("repo_poky")] and \
- os.environ.get("BUILD_HISTORY_COLLECT") == "True":
- bhw_dir = os.environ.get("BUILD_HISTORY_WEB_DIR")
- bh_dir = os.environ.get("BUILD_HISTORY_DIR")
- pokydir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"), self.getProperty("buildername")) + "/build"
- cmd=""
- for machine in self.machines:
- cmd += os.path.join(bhw_dir + "/warningmgr/import.py") + " -m " + machine + " -b " + machine + " " + pokydir + " " + bh_dir + "/" + machine + "/poky-buildhistory;"
- self.command=cmd
- ShellCommand.start(self)
-
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/UploadToasterEventlog.py b/lib/python2.7/site-packages/autobuilder/buildsteps/UploadToasterEventlog.py
deleted file mode 100644
index 8cf24035..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/UploadToasterEventlog.py
+++ /dev/null
@@ -1,58 +0,0 @@
-'''
-Created on Dec 9, 2014
-
-__author__ = "Alex Damian"
-__copyright__ = "Copyright 2012-2014, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Alex Damian"
-__email__ = "alexandru.damian@intel.com"
-'''
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from autobuilder.config import *
-
-
-class UploadToasterEventlog(ShellCommand):
- haltOnFailure = False
- flunkOnFailure = True
- name = "UploadToasterEventlog"
- def __init__(self, factory, argdict=None, **kwargs):
- self.factory = factory
- self.workerdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- for k, v in argdict.iteritems():
- setattr(self, k, v)
- # Timeout needs to be passed to LoggingBuildStep as a kwarg
- self.timeout = 2000
- kwargs['timeout']=self.timeout
- ShellCommand.__init__(self, **kwargs)
-
- def start(self):
- self.workerdir=os.path.join(os.path.join(YOCTO_ABBASE, "yocto-worker"))
- self.buildername=self.getProperty("buildername")
- self.layerversion_core = int(self.getProperty("layerversion_core", "0"))
- try:
- self.create_eventlog = self.getProperty("custom_create_eventlog")
- except:
- self.create_eventlog = "False"
-
- if self.layerversion_core < 5 or self.create_eventlog == "False":
- self.command = "echo 'Skipping Step.'"
- self.description = ["Uploading toaster data skipped"]
- else:
- if os.environ.get('TOASTER_UPLOAD_URL') is not None:
- self.filepath = os.path.join(os.path.join(
- self.workerdir, self.buildername),
- "build/build/tmp/log/bitbake_eventlog-*.json")
- self.toasterserver = str(os.environ.get('TOASTER_UPLOAD_URL'))
-
- self.command = "for fn in %s; do " % self.filepath
- self.command += "curl -F eventlog=@$fn " + self.toasterserver + ";"
- self.command += "done"
- else:
- self.command = "echo environment var TOASTER_UPLOADURL not set - Step is noop"
- self.description = ["Uploading toaster data"]
- ShellCommand.start(self)
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/__init__.py b/lib/python2.7/site-packages/autobuilder/buildsteps/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/autobuilder/buildsteps/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/autobuilder/config.py b/lib/python2.7/site-packages/autobuilder/config.py
deleted file mode 100644
index fcc08f0a..00000000
--- a/lib/python2.7/site-packages/autobuilder/config.py
+++ /dev/null
@@ -1,27 +0,0 @@
-'''
-Created on Dec 18, 2012
-
-@author: pidge
-'''
-YOCTO_SOURCES = []
-YOCTO_SCHED = []
-YOCTO_BUILDERS = []
-YOCTO_PROJNAME = []
-YOCTO_PROJURL = []
-YOCTO_BUILDERS_SORTED = []
-import os
-YOCTO_ABBASE=os.environ.get("PWD")
-MACHINE_PUBLISH_DIR = os.environ.get("MACHINE_PUBLISH_DIR")
-QEMU_PUBLISH_DIR = os.environ.get("QEMU_PUBLISH_DIR")
-MARKED_RELEASE_DIR = os.environ.get("MARKED_RELEASE_DIR")
-ADT_INST_PUBLISH_DIR = os.environ.get("ADT_INST_PUBLISH_DIR")
-BA_PUBLISH_DIR = os.environ.get("BA_PUBLISH_DIR")
-ADTQA_INST_PUBLISH_DIR = os.environ.get("ADTQA_INST_PUBLISH_DIR")
-X86TC_PUBLISH_DIR = os.environ.get("X86TC_PUBLISH_DIR")
-X8664TC_PUBLISH_DIR = os.environ.get("X8664TC_PUBLISH_DIR")
-RPM_PUBLISH_DIR = os.environ.get("RPM_PUBLISH_DIR")
-IPK_PUBLISH_DIR = os.environ.get("IPK_PUBLISH_DIR")
-DEB_PUBLISH_DIR = os.environ.get("DEB_PUBLISH_DIR")
-PERFORMANCE_PUBLISH_DIR = os.environ.get("PERFORMANCE_PUBLISH_DIR")
-DAFT_WORKER_DEVICES_CFG = os.environ.get("DAFT_WORKER_DEVICES_CFG")
-DAFT_WORKER_WORKSPACE = os.environ.get("DAFT_WORKER_WORKSPACE")
diff --git a/lib/python2.7/site-packages/autobuilder/lib/ABTools.py b/lib/python2.7/site-packages/autobuilder/lib/ABTools.py
deleted file mode 100644
index 9ff1bc80..00000000
--- a/lib/python2.7/site-packages/autobuilder/lib/ABTools.py
+++ /dev/null
@@ -1,79 +0,0 @@
-'''
-Created on Jan 19, 2014
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2014, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "elizabeth.flanagan@intel.com"
-'''
-
-import os
-import time
-import json
-import codecs
-
-import subprocess
-import platform
-
-from autobuilder.config import YOCTO_ABBASE
-
-def capitalize(word):
- return ' '.join([s[0].upper() + s[1:] for s in word.split(' ')])
-
-def stringToBool(v):
- return v.lower() in ("true", "t", "1")
-
-def get_error_report_controller_dir(buildername, buildnumber):
- errordir_base = os.path.join(YOCTO_ABBASE, 'yocto-controller', buildername,
- 'error-report')
- errordir = os.path.join(errordir_base, str(buildnumber))
- return errordir
-
-def get_error_report_worker_dir(buildername):
- if os.environ.get('ERROR_REPORT_DIR') is None:
- workerdir = os.path.join(YOCTO_ABBASE, 'yocto-worker')
- errordir = os.path.join(workerdir, buildername,
- 'build/build/tmp/log/error-report/')
- else:
- errordir = os.environ.get('ERROR_REPORT_DIR')
-
- return errordir
-
-def save_error_report(buildername, buildnumber, report, report_type):
- errordir = get_error_report_controller_dir(buildername, buildnumber)
- if not os.path.exists(errordir):
- os.makedirs(errordir)
-
- filename = os.path.join(errordir, "error_report_%s_%d.txt" % \
- (report_type, int(time.time())))
- with codecs.open(filename, 'w', 'utf-8') as f:
- json.dump(report, f, indent=4, sort_keys=True)
-
-def get_lsb_distro():
- """
- Try to get Linux distribution ID using lsb_release if lsb_release
- isn't installed use information provided by linux_distribution()
- method in platform returns "DISTRONAME-VERSION".
- """
-
- lsb_distro = None
-
- try:
- output = subprocess.check_output("lsb_release -ir", shell=True)
-
- lines = output.splitlines()
-
- # Output example:
- # Distributor ID:\tDebian
- # Release:\t8.4
- distro_name = lines[0].split(':')[1].strip()
- version = lines[1].split(':')[1].strip()
-
- lsb_distro = "%s-%s" % (distro_name, version)
- except Exception as e:
- lsb_distro = "%s-%s" % platform.linux_distribution()[0:2]
-
- return lsb_distro
diff --git a/lib/python2.7/site-packages/autobuilder/lib/__init__.py b/lib/python2.7/site-packages/autobuilder/lib/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/autobuilder/lib/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/autobuilder/lib/buildsteps.py b/lib/python2.7/site-packages/autobuilder/lib/buildsteps.py
deleted file mode 100644
index 8e3707f2..00000000
--- a/lib/python2.7/site-packages/autobuilder/lib/buildsteps.py
+++ /dev/null
@@ -1,158 +0,0 @@
-'''
-Created on Feb 15, 2016
-
-__author__ = "Anibal (alimon) Limon"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Anibal Limon"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Anibal Limon"
-__email__ = "anibal.limon@linux.intel.com"
-'''
-
-import os
-import re
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from buildbot.status.results import SUCCESS
-
-from lib.ABTools import save_error_report
-
-DEFAULT_SHELL = 'bash'
-
-class ShellCommandCleanEnv(ShellCommand):
- def __init__(self, factory, argdict=None, **kwargs):
- shell = DEFAULT_SHELL
- if 'SHELL' in kwargs:
- shell = kwargs['SHELL']
- del kwargs['SHELL']
-
- if 'PENV' in kwargs:
- preserve_env = kwargs['PENV']
- del kwargs['PENV']
- else:
- preserve_env = ['HOME', 'PWD', 'PATH',
- 'http_proxy', 'https_proxy',
- 'ftp_proxy', 'no_proxy', 'GIT_PROXY_COMMAND']
-
- env_command = self._get_env_cleaned_command(shell, preserve_env)
- self.command = "%s \'%s\'" % (env_command, self.command)
- ShellCommand.__init__(self, **kwargs)
-
- def _get_env_cleaned_command(self, shell, preserve_env):
- pe_cmd = ''
- for pe in preserve_env:
- pe_cmd += "%s=\"$%s\" " % (pe, pe)
-
- return "env -i %s %s -c " % (pe_cmd, shell)
-
-class BitbakeLogLineObserver(LogLineObserver):
- """
- Search in the stdio bitbake log for exception/errors, identify
- if the error is a recipe/task one if not turn on the flag of
- bitbake error/exception and save the log.
- """
-
- rexp_error = re.compile("^ERROR: .*$")
-
- # recipe task errors regex'es
- rexp_pnpv_error = re.compile("^ERROR: (?P<pnpv>.*) do_(?P<task>.*):.*$")
- rexp_task_error = re.compile("^ERROR: Task .*$")
- rexp_log_error = re.compile("^ERROR: Logfile of failure stored in: "\
- "(?P<path>.*)$")
-
- def _handleError(self, line):
- if not hasattr(self.step, 'errors'):
- self.step.errors = {}
- self.step.errors['bitbake'] = False
- self.step.errors['log'] = []
-
- # save all the log for be able to get report variables like
- # machine, target, distro, etc
- self.step.errors['log'].append(line)
-
- # discard line that are not errors and line that
- # is recipe task errors
- if (not self.rexp_error.match(line)) or \
- self.rexp_pnpv_error.match(line) or \
- self.rexp_task_error.match(line) or \
- self.rexp_log_error.match(line):
- return
-
- # if not match recipe task type is a bitbake exception/error
- self.step.errors['bitbake'] = True
-
- def outLineReceived(self, line):
- self._handleError(line)
-
- def errLineReceived(self, line):
- self._handleError(line)
-
-class BitbakeShellCommand(ShellCommand):
- def __init__(self, factory, argdict=None, **kwargs):
- super(BitbakeShellCommand, self).__init__(**kwargs)
-
- self.stdio_observer = BitbakeLogLineObserver()
- self.addLogObserver('stdio', self.stdio_observer)
-
- def _get_variables(self, log):
- vrs = {}
-
- rexp = re.compile("^(.*)=.*\"(.*)\"$")
- for line in log:
- m = rexp.match(line)
- if m:
- vrs[m.group(1).rstrip()] = m.group(2)
-
- return vrs
-
- def _createBitbakeErrorReport(self, log):
- vrs = self._get_variables(log)
-
- report = {}
- report['machine'] = vrs.get('MACHINE', 'unknown_{0}'.format('MACHINE'))
- report['build_sys'] = vrs.get('BUILD_SYS', 'unknown_{0}'.format('BUILD_SYS'))
- report['nativelsb'] = vrs.get('NATIVELSBSTRING', 'unknown_{0}'.format('NATIVELSBSTRING'))
- report['distro'] = vrs.get('DISTRO', 'unknown_{0}'.format('DISTRO'))
- report['target_sys'] = vrs.get('TARGET_SYS', 'unknown_{0}'.format('TARGET_SYS'))
-
- report['component'] = 'bitbake'
- try:
- branch = self.getProperty('branch')
- revision = self.getProperty('got_revision')
- if not revision:
- revision = self.getProperty('got_revision_oecore')
- except:
- branch = "unknown_branch"
- revision = "unknown_revision"
- report['branch_commit'] = branch + ': ' + revision
-
- failure = {}
- failure['package'] = "bitbake-%s" % vrs.get('BB_VERSION', 'unknown_{0}'.format('BB_VERSION'))
- if 'bitbake-selftest' in self.command:
- report['error_type'] = 'bitbake-selftest'
- failure['task'] = self.command[self.command.find('bitbake-selftest'):]
- else:
- report['error_type'] = 'core'
- failure['task'] = self.command[self.command.find('bitbake'):]
-
- failure['log'] = "\n".join(log)
-
- report['failures'] = [failure]
-
- return report
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- if hasattr(self, 'errors') and self.errors['bitbake']:
- buildername = self.getProperty('buildername')
- buildnumber = self.getProperty('buildnumber')
-
- report = self._createBitbakeErrorReport(self.errors['log'])
- save_error_report(buildername, buildnumber, report, 'bitbake')
-
- def skipStep(self, reason):
- self.command = "echo '%s'" % reason
- self.description = ["%s" % reason]
diff --git a/lib/python2.7/site-packages/autobuilder/lib/daft.py b/lib/python2.7/site-packages/autobuilder/lib/daft.py
deleted file mode 100644
index 925efa7e..00000000
--- a/lib/python2.7/site-packages/autobuilder/lib/daft.py
+++ /dev/null
@@ -1,118 +0,0 @@
-import os
-import ConfigParser as configparser
-
-class DeployScanner(object):
- '''
- In charge of scanning deployed daft bbb devices
- '''
-
- __MAGIC_SERVER_ADDRESS = '192.168.30.1' # DAFT uses this address for this internal network
- __MAGIC_SSH_PORT = 2233 # it is hardcoded as per DAFT implementation manual
-
- def __init__(self, *args, **kwargs):
- self.devsconf_fp = kwargs.get('devsconf_file', None)
- if not self.devsconf_fp:
- raise Exception('not fed devsconf file')
- self.ign_leases = kwargs.get('ign_leases', True)
- if not self.ign_leases:
- self.leases_file_path = kwargs.get('leases_file', None)
- if not self.leases_file_path:
- raise Exception('not fed leases file')
-
- def getDevices(self):
- '''
- Creates relation of deployed devices
- Returns:
- List of dictionaries containing info about devices deployed.
- '''
-
- def _map_config(conf, leases=None):
- """
- Creates a list with dictionaries for DUT config
- information, if DHCP leases isn't none also validate
- if the DUT IP is active.
- """
-
- mapped_config = []
-
- for entry in conf:
- append = False
- if leases:
- for active in leases:
- if conf['bb_ip'] == active['ip']:
- append = True
- break
- else:
- append = True
-
- if append:
- mapped_config.append({
- 'dut_label': entry['device'],
- 'dut_family': entry['device_type'],
- 'dut_sshport': str(self.__MAGIC_SSH_PORT),
- 'ctrl_address': entry['bb_ip'],
- 'server_address': self.__MAGIC_SERVER_ADDRESS
- })
-
- return mapped_config
-
- conf = self.__fetch_confs()
- if not conf:
- raise Exception('There are no configurations as per BBB devices')
-
- leases = None
- if not self.ign_leases:
- leases = self.__active_leases()
- if not leases:
- raise Exception('DHCP server has not registered any host yet')
-
- return _map_config(conf, leases)
-
- def __fetch_confs(self):
- '''
- Read and parse BBB configuration file and return result as dictionary
- '''
- config = configparser.SafeConfigParser()
- config.read(self.devsconf_fp)
- configurations = []
- for device in config.sections():
- device_config = dict(config.items(device))
- device_config["device"] = device
- device_config["device_type"] = device.rstrip('1234567890_')
- configurations.append(device_config)
- return configurations
-
- def __active_leases(self):
- """
- Read the active leases from dnsmasq leases file and return a list of
- active leases as dictionaries.
- Args:
- file_name (str): Path to leases file, e.g. /path/to/file/dnsmasq.leases
- Returns:
- List of dictionaries containing the active leases.
- The dictionaries have the following format:
- {
- "mac": "device_mac_address",
- "ip": "device_ip_address",
- "hostname": "device_host_name",
- "client_id": "client_id_or_*_if_unset"
- }
- """
- with open(self.leases_file_path) as lease_file:
- leases = lease_file.readlines()
-
- leases_list = []
-
- # dnsmasq.leases contains rows with the following format:
- # <lease_expiry_time_as_epoch_format> <mac> <ip> <hostname> <domain>
- # See:
- #http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2005q1/000143.html
- for lease in leases:
- lease = lease.split()
- leases_list.append({
- "mac": lease[1],
- "ip": lease[2],
- "hostname": lease[3],
- "client_id": lease[4],
- })
- return leases_list
diff --git a/lib/python2.7/site-packages/autobuilder/lib/wiki.py b/lib/python2.7/site-packages/autobuilder/lib/wiki.py
deleted file mode 100644
index 7bdd4e3e..00000000
--- a/lib/python2.7/site-packages/autobuilder/lib/wiki.py
+++ /dev/null
@@ -1,206 +0,0 @@
-'''
-Created on Dec 13, 2016
-
-__author__ = "Joshua Lock"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Joshua Lock"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Joshua Lock"
-__email__ = "joshua.g.lock@intel.com"
-'''
-
-import codecs
-import hashlib
-import time
-import requests
-from twisted.python import log
-
-
-class YPWiki(object):
- MAX_TRIES = 5
- TIMEOUT = 60
-
- def __init__(self, wiki_uri, wiki_un, wiki_pass):
- self.wiki_uri = wiki_uri
- self.wiki_un = wiki_un
- self.wiki_pass = wiki_pass
-
- @staticmethod
- def retry_request(requesturl, **kwargs):
- """
- Rather than failing when a request to a 'requesturl' throws an
- exception retry again a minute later. Perform this retry no more than
- 5 times.
-
- @type requesturl: string
- """
- kwargs['timeout'] = YPWiki.TIMEOUT
-
- def try_request():
- try:
- req = requests.get(requesturl, **kwargs)
- return req
- except (requests.exceptions.RequestException,
- requests.exceptions.Timeout):
- return None
-
- tries = 0
- req = None
- while not req and tries < YPWiki.MAX_TRIES:
- if tries > 0:
- time.sleep(60)
- req = try_request()
- tries = tries + 1
-
- return req
-
- @staticmethod
- def parse_json(response):
- """
- This method handles stripping UTF-8 BOM from the beginning of responses
- from the Yocto Project wiki.
-
- http://en.wikipedia.org/wiki/Byte_Order_Mark
- http://bugs.python.org/issue18958
-
- @type response: requests.Response
- """
- bom = codecs.BOM_UTF8
- text = ''
-
- # In Requests 0.8.2 (Ubuntu 12.04) Response.content has type unicode,
- # whereas in requests 2.1.10 (Fedora 23) Response.content is a str
- # Ensure that bom is the same type as the content, codecs.BOM_UTF8 is
- # a str
- if type(response.content) == unicode:
- bom = unicode(codecs.BOM_UTF8, 'utf8')
-
- # If we discover a BOM set the encoding appropriately so that the
- # built in decoding routines in requests work correctly.
- if response.content.startswith(bom):
- response.encoding = 'utf-8-sig'
-
- return response.json()
-
- def login(self):
- """
- Login to the wiki and return cookies for the logged in session
- """
- payload = {
- 'action': 'login',
- 'lgname': self.wiki_un,
- 'lgpassword': self.wiki_pass,
- 'utf8': '',
- 'format': 'json'
- }
-
- try:
- req1 = requests.post(self.wiki_uri, data=payload,
- timeout=self.TIMEOUT)
- except (requests.exceptions.RequestException,
- requests.exceptions.Timeout):
- return None
-
- parsed = self.parse_json(req1)
- login_token = parsed['login']['token'].encode('utf-8')
-
- payload['lgtoken'] = login_token
- try:
- req2 = requests.post(self.wiki_uri, data=payload,
- cookies=req1.cookies, timeout=self.TIMEOUT)
- except (requests.exceptions.RequestException,
- requests.exceptions.Timeout):
- return None
-
- return req2.cookies.copy()
-
- def get_content(self, wiki_page):
- """
- Get the current content of the 'wiki_page' -- to make the wiki page
- as useful as possible the most recent log entry should be at the top,
- to that end we need to edit the whole page so that we can insert the
- new entry after the log but before the other entries.
-
- This method fetches the current page content, splits out the blurb and
- returns a pair:
- 1) the blurb
- 2) the current entries
-
- @type wiki_page: string
- """
-
- pm = '?format=json&action=query&prop=revisions&rvprop=content&titles='
-
- req = self.retry_request(self.wiki_uri+pm+wiki_page)
- if not req:
- return None, None
-
- parsed = self.parse_json(req)
- pageid = sorted(parsed['query']['pages'].keys())[-1].encode('utf-8')
- content = parsed['query']['pages'][pageid]['revisions'][0]['*']
- content = content.encode('utf-8')
- blurb, entries = content.split('==', 1)
- # ensure we keep only a single newline after the blurb
- blurb = blurb.strip() + "\n"
- entries = '=='+entries
-
- return blurb, entries
-
- def post_entry(self, wiki_page, content, summary, cookies):
- """
- Post the new page contents 'content' to the page title 'wiki_page'
- with a 'summary' using the login credentials from 'cookies'
-
- @type wiki_page: string
- @type content: string
- @type summary: string
- @type cookies: CookieJar
- """
-
- params = ("?format=json&action=query&prop=info|revisions"
- "&intoken=edit&rvprop=timestamp&titles=")
- req = self.retry_request(self.wiki_uri+params+wiki_page,
- cookies=cookies)
- if not req:
- return False
-
- parsed = self.parse_json(req)
- pageid = sorted(parsed['query']['pages'].keys())[-1].encode('utf-8')
- edit_token = parsed['query']['pages'][pageid]['edittoken']
- edit_token = edit_token.encode('utf-8')
-
- edit_cookie = cookies.copy()
- edit_cookie.update(req.cookies)
-
- content_hash = hashlib.md5(content).hexdigest()
-
- payload = {
- 'action': 'edit',
- 'assert': 'user',
- 'title': wiki_page,
- 'summary': summary,
- 'text': content,
- 'md5': content_hash,
- 'token': edit_token,
- 'utf8': '',
- 'format': 'json'
- }
-
- try:
- req = requests.post(self.wiki_uri, data=payload,
- cookies=edit_cookie, timeout=self.TIMEOUT)
- except (requests.exceptions.RequestException,
- requests.exceptions.Timeout):
- return False
-
- if not req.status_code == requests.codes.ok:
- log.err("Unexpected status code %s received when trying to post"
- " an entry to the wiki." % req.status_code)
- return False
- else:
- result = self.parse_json(req)
- status = result.get('edit', {}).get('result', '').encode('utf-8')
- if status == 'Success':
- return True
- return False
diff --git a/lib/python2.7/site-packages/autobuilder/release/download.py b/lib/python2.7/site-packages/autobuilder/release/download.py
deleted file mode 100644
index 4f98b752..00000000
--- a/lib/python2.7/site-packages/autobuilder/release/download.py
+++ /dev/null
@@ -1,38 +0,0 @@
-class Download(object):
- def __init__(self):
- self._build_conf = None
- self._main = None
- self._md5sum = None
- self._mirror = None
-
- @property
- def build_conf(self):
- return self._build_conf
-
- @build_conf.setter
- def build_conf(self, build_conf):
- self._build_conf = build_conf
-
- @property
- def main(self):
- return self._main
-
- @main.setter
- def main(self, main):
- self._main = main
-
- @property
- def md5sum(self):
- return self._md5sum
-
- @md5sum.setter
- def md5sum(self, md5sum):
- self._md5sum = md5sum
-
- @property
- def mirror(self):
- return self._mirror
-
- @mirror.setter
- def mirror(self, mirror):
- self._mirror = mirror
diff --git a/lib/python2.7/site-packages/autobuilder/release/git.py b/lib/python2.7/site-packages/autobuilder/release/git.py
deleted file mode 100644
index 508966bc..00000000
--- a/lib/python2.7/site-packages/autobuilder/release/git.py
+++ /dev/null
@@ -1,47 +0,0 @@
-class Git(object):
- def __init__(self):
- self._cgit_link = None
- self._git_branch = None
- self._git_clone_command = None
- self._git_tag = None
- self._git_url = None
-
- @property
- def cgit_link(self):
- return self._cgit_link
-
- @cgit_link.setter
- def cgit_link(self, cgit_link):
- self._cgit_link = cgit_link
-
- @property
- def git_branch(self):
- return self._git_branch
-
- @git_branch.setter
- def git_branch(self, git_branch):
- self._git_branch = git_branch
-
- @property
- def git_clone_command(self):
- return self._git_clone_command
-
- @git_clone_command.setter
- def git_clone_command(self, git_clone_command):
- self._git_clone_command = git_clone_command
-
- @property
- def git_tag(self):
- return self._git_tag
-
- @git_tag.setter
- def git_tag(self, git_tag):
- self._git_tag = git_tag
-
- @property
- def git_url(self):
- return self._git_url
-
- @git_url.setter
- def git_url(self, git_url):
- self._git_url = git_url
diff --git a/lib/python2.7/site-packages/autobuilder/release/tabs.py b/lib/python2.7/site-packages/autobuilder/release/tabs.py
deleted file mode 100644
index 4d3698ab..00000000
--- a/lib/python2.7/site-packages/autobuilder/release/tabs.py
+++ /dev/null
@@ -1,27 +0,0 @@
-class Tabs(object):
- def __init__(self):
- self._features = None
- self._bug_fixes = None
- self._security_fixes = None
-
- @property
- def bug_fixes(self):
- return self._bug_fixes
-
- @bug_fixes.setter
- def bug_fixes(self, bug_fixes):
- self._bug_fixes = bug_fixes
-
- @property
- def features(self):
- return self._features
- @features.setter
- def features(self, features):
- self._features = features
-
- @property
- def security_fixes(self):
- return self._security_fixes
- @security_fixes.setter
- def security_fixes(self, security_fixes):
- self._security_fixes = security_fixes
diff --git a/lib/python2.7/site-packages/autobuilder/release/title.py b/lib/python2.7/site-packages/autobuilder/release/title.py
deleted file mode 100644
index 01f4439b..00000000
--- a/lib/python2.7/site-packages/autobuilder/release/title.py
+++ /dev/null
@@ -1,159 +0,0 @@
-class Title(object):
- def __init__(self):
- self._architecture = None
- self._board = None
- self._built_with = None
- self._gpg_key = None
- self._inherit_parent_downloads = None
- self._inherit_parent_tabs = None
- self._mailinglist_url = None
- self._maintainer = None
- self._parent = None
- self._project_url = None
- self._release_date = None
- self._release_note = None
- self._release_title = None
- self._release_type = None
- self._sponsoring_org = None
- self._tsu_exception = None
- self._yocto_compatible = None
-
- @property
- def architecture(self):
- return self._architecture
-
- @architecture.setter
- def architecture(self, architecture):
- self._architecture = architecture
-
- @property
- def board(self):
- return self._board
-
- @board.setter
- def board(self, board):
- self._board = board
-
- @property
- def built_with(self):
- return self._built_with
-
- @built_with.setter
- def built_with(self, built_with):
- self._built_with = built_with
-
- @property
- def gpg_key(self):
- return self._gpg_key
-
- @gpg_key.setter
- def gpg_key(self, gpg_key):
- self._gpg_key = gpg_key
-
- @property
- def inherit_parent_downloads(self):
- return self._inherit_parent_downloads
-
- @inherit_parent_downloads.setter
- def inherit_parent_downloads(self, inherit_parent_downloads):
- self._inherit_parent_downloads = inherit_parent_downloads
-
- @property
- def inherit_parent_tabs(self):
- return self._inherit_parent_tabs
-
- @inherit_parent_tabs.setter
- def inherit_parent_tabs(self, inherit_parent_tabs):
- self._inherit_parent_tabs = inherit_parent_tabs
-
- @property
- def mailinglist_url(self):
- return self._mailinglist_url
-
- @mailinglist_url.setter
- def mailinglist_url(self, mailinglist_url):
- self._mailinglist_url = mailinglist_url
-
- @property
- def maintainer(self):
- return self._maintainer
-
- @maintainer.setter
- def maintainer(self, maintainer):
- self._maintainer = maintainer
-
- @property
- def parent(self):
- return self._parent
-
- @parent.setter
- def parent(self, parent):
- self._parent = parent
-
- @property
- def project_url(self):
- return self._project_url
-
- @project_url.setter
- def project_url(self, project_url):
- self._project_url = project_url
-
- @property
- def release_date(self):
- return self._release_date
-
- @release_date.setter
- def release_date(self, release_date):
- self._release_date = release_date
-
- @property
- def release_note(self):
- return self._release_note
-
- @release_note.setter
- def release_note(self, release_note):
- self._release_note = release_note
-
- @property
- def release_title(self):
- return self._release_title
-
- @release_title.setter
- def release_title(self, release_title):
- self._release_title = release_title
-
- @property
- def release_type(self):
- return self._release_type
-
- @release_type.setter
- def release_type(self, release_type):
- self._release_type = release_type
-
- @property
- def sponsoring_org(self):
- return self._sponsoring_org
-
- @sponsoring_org.setter
- def sponsoring_org(self, sponsoring_org):
- self._sponsoring_org = sponsoring_org
-
- @property
- def tsu_exception(self):
- return self._tsu_exception
-
- @tsu_exception.setter
- def tsu_exception(self, tsu_exception):
- self._tsu_exception = tsu_exception
-
- @property
- def yocto_compatible(self):
- return self._yocto_compatible
-
- @yocto_compatible.setter
- def yocto_compatible(self, yocto_compatible):
- self._yocto_compatible = yocto_compatible
-
- @gpg_key.setter
- def gpg_key(self, gpg_key):
- self._gpg_key = gpg_key
diff --git a/lib/python2.7/site-packages/autobuilder/status/__init__.py b/lib/python2.7/site-packages/autobuilder/status/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/autobuilder/status/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/autobuilder/status/wikilog.py b/lib/python2.7/site-packages/autobuilder/status/wikilog.py
deleted file mode 100644
index 1b25633b..00000000
--- a/lib/python2.7/site-packages/autobuilder/status/wikilog.py
+++ /dev/null
@@ -1,459 +0,0 @@
-'''
-Created on Dec 13, 2016
-
-__author__ = "Joshua Lock"
-__copyright__ = "Copyright 2016, Intel Corp."
-__credits__ = ["Joshua Lock"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Joshua Lock"
-__email__ = "joshua.g.lock@intel.com"
-'''
-
-from zope.interface import implements
-
-from twisted.python import log
-
-from buildbot import interfaces
-from buildbot.interfaces import IStatusReceiver
-from buildbot.status import base
-from buildbot.status.results import SUCCESS
-from buildbot.process.properties import Properties
-
-import re
-import time
-
-from lib.wiki import YPWiki
-
-
-class WikiLog(base.StatusReceiverMultiService):
- implements(IStatusReceiver)
-
- def __init__(self, wiki_uri, wiki_un, wiki_pass, wiki_page,
- identifier):
- """
- initialise object
-
- @type wiki_uri: string
- @type wiki_un: string
- @type wiki_pass: string
- @type wiki_page: string
- @type identifier: string
- """
- base.StatusReceiverMultiService.__init__(self)
-
- self.wiki_page = wiki_page
- tagfmt = " on {}"
- if identifier:
- self.tag = tagfmt.format(identifier)
- else:
- self.tag = tagfmt.format("unnamed yocto-autobuilder")
- self.wiki = YPWiki(wiki_uri, wiki_un, wiki_pass)
-
- def logBuild(self, build):
- """
- Extract information about 'build' and post an entry to the wiki
-
- @type build: buildbot.status.build.BuildStatus
- """
-
- builder = build.getBuilder().getName()
- reason = build.getReason()
- buildid = str(build.getNumber())
- start, _ = build.getTimes()
- url = self.status.getURLForThing(build)
- buildbranch = build.getProperty('branch').strip()
- if not buildbranch or len(buildbranch) < 1:
- buildbranch = "YP_BUILDBRANCH"
- chash = build.getProperty('commit_poky').strip()
- if not chash or len(chash) < 1 or chash == "HEAD":
- chash = "YP_CHASH"
-
- reason_list = reason.split(':', 1)
- forcedby = reason_list[0].strip()
- description = 'No reason given.'
- if len(reason_list) > 1 and reason_list[1] != ' ':
- description = reason_list[1].strip()
- starttime = time.ctime(start)
-
- sectionfmt = '==[{} {} {} - {} {}]=='
- section_title = sectionfmt.format(url, builder, buildid, buildbranch,
- chash)
- summaryfmt = 'Adding new BuildLog entry for build %s (%s)'
- summary = summaryfmt % (buildid, chash)
- summary = summary + self.tag
- content = "* '''Build ID''' - %s" % chash
- content = content + self.tag + "\n"
- content = content + '* Started at: %s\n' % starttime
- content = content + '* ' + forcedby + '\n* ' + description + '\n'
- new_entry = '{}\n{}\n'.format(section_title, content).encode('utf-8')
-
- blurb, entries = self.wiki.get_content(self.wiki_page)
- if not blurb:
- log.err("wkl: Unexpected content retrieved from wiki!")
- return False
-
- entries = new_entry + entries
- cookies = self.wiki.login()
-
- if not cookies:
- log.err("wkl: Failed to login to wiki")
- return False
-
- if not self.wiki.post_entry(self.wiki_page, blurb+entries,
- summary, cookies):
- log.err("wkl: Failed to post entry for %s" % buildid)
- return False
-
- log.msg("wkl: Posting wikilog entry for %s" % buildid)
- return True
-
- def updateEntryBuildInfo(self, entry, build):
- """
- Extract the branch and commit hash from the properties of the 'build'
- and update the 'entry' string with extracted values
-
- @type entry: string
- @type build: buildbot.status.build.BuildStatus
- """
- # We only want to update the commit and branch info for the
- # primary poky build
- # FIXME: this is quite poky specific. Can we handle this in
- # a more generic manner?
- repo = build.getProperty("repourl_poky")
- if not repo:
- return entry
- buildbranch = build.getProperty('branch').strip()
- if not buildbranch or len(buildbranch) < 1:
- buildbranch = "YP_BUILDBRANCH"
- chash = build.getProperty('commit_poky').strip()
- if not chash or len(chash) < 1 or chash == "HEAD":
- chash = "YP_CHASH"
-
- new_entry = entry.replace("YP_BUILDBRANCH", buildbranch, 1)
- new_entry = new_entry.replace("YP_CHASH", chash, 2)
-
- return new_entry
-
- def updateBuildInfo(self, content, build):
- """
- Extract the branch and commit hash from the properties of the 'build'
- and update the 'content' string with extracted values
-
- @type content: string
- @type build: buildbot.status.build.BuildStatus
- """
-
- # Try to find an entry that matches this build, rather than blindly
- # updating all instances of the template value in the content
- buildid = build.getProperty('buildnumber', '0')
- builder = build.getProperty('buildername', 'nobuilder')
- entry_list = re.split('\=\=\[(.+)\]\=\=', content)
- title_idx = -1
- # Start at the beginning of entry list and keep iterating until we find
- # a title which looks ~right
- for idx, ent in enumerate(entry_list):
- # The matched title contents should always start with a http*
- # schemed URI
- if ent.startswith('http'):
- # format of the title is:
- # ==[url builder buildid - buildbranch commit_hash]==
- title_components = ent.split(None, 6)
- if builder == title_components[1] and \
- str(buildid) == title_components[2]:
- title_idx = idx
- break
-
- if title_idx < 0:
- errmsg = ("wkl: Failed to update entry for {0} couldn't find a "
- "matching title with builder {1}")
- log.err(errmsg.format(buildid, builder))
- return content
-
- entry = entry_list[title_idx + 1]
- title = entry_list[title_idx]
-
- combined = "==[{0}]=={1}".format(title, entry)
- new_entry = self.updateEntryBuildInfo(combined, build)
- new_entry = new_entry.encode('utf-8')
-
- it = re.finditer('\=\=\[(.+)\]\=\=', content)
- entry_title = it.next()
- while entry_title.group(1) != title:
- entry_title = it.next()
- next_title = it.next()
- head = content[:entry_title.start()]
- tail = content[next_title.start():]
- update = head + new_entry + tail
-
- # log.msg("wkl: Updating commit info YP_BUILDBRANCH=%s YP_CHASH=%s" %
- # (buildbranch, chash))
-
- return update
-
- def updateBuild(self, build):
- """
- Extract information about 'build' and update an entry in the wiki
-
- @type build: buildbot.status.build.BuildStatus
- """
- builder = build.getBuilder().getName()
- buildid = str(build.getNumber())
- reason = build.getReason()
- blurb, entries = self.wiki.get_content(self.wiki_page)
- if not blurb:
- log.err("wkl: Unexpected content retrieved from wiki!")
- return False
-
- url = self.status.getURLForThing(build)
- log_entries = []
- logfmt = '[%s %s]'
- for l in build.getLogs():
- # Ignore logs for steps which succeeded
- result, _ = l.getStep().getResults()
- if result == SUCCESS:
- continue
-
- step_name = l.getStep().getName()
- log_url = '%s/steps/%s/logs/%s' % (url,
- step_name,
- l.getName())
- log_url = log_url.replace(' ', '%20')
- log_entry = logfmt % (log_url, step_name)
- log_entries.append(log_entry)
- buildbranch = build.getProperty('branch').strip()
- if not buildbranch or len(buildbranch) < 1:
- buildbranch = "YP_BUILDBRANCH"
- chash = build.getProperty('commit_poky').strip()
- if not chash or len(chash) < 1 or chash == "HEAD":
- chash = "YP_CHASH"
-
- entry_list = re.split('\=\=\[(.+)\]\=\=', entries)
- entry = ''
- title = ''
- # Start at the beginning of entry list and keep iterating until we find
- # a title which looks ~right
- trigger = "Triggerable(trigger_main-build"
- for idx, entry in enumerate(entry_list):
- # The matched title contents should always start with a http*
- # schemed URI
- if entry.startswith('http'):
- # format of the title is:
- # ==[url builder buildid - buildbranch commit_hash]==
- title_components = entry.split(None, 6)
-
- # For the primary, nightly, builder we can match on chash and
- # buildbranch, otherwise we have to hope that the first
- # triggered build with matching chash and tag
- foundmatch = False
- if buildbranch == title_components[4] \
- and chash == title_components[5] \
- and self.tag in entry_list[idx+1]:
- foundmatch = True
- elif trigger in reason \
- and chash == title_components[5] \
- and self.tag in entry_list[idx+1]:
- foundmatch = True
-
- if foundmatch:
- entry = entry_list[idx+1]
- title = entry_list[idx]
- break
-
- if not entry or not title:
- errmsg = ("wkl: Failed to update entry for {0} couldn't find a "
- "matching title for branch: {1} or hash: {2} "
- "(reason was '{3}')")
- log.err(errmsg.format(buildid, buildbranch, chash, reason))
- return False
-
- log_fmt = ''
- logs = ''
- new_entry = ''
- if builder == 'nightly':
- # for failures in nightly we just append extra entries to the
- # bullet list pointing to the failure logs
- if len(log_entries) > 0:
- logs = '\n* '.join(log_entries) + '\n'
- new_entry = '\n' + entry.strip() + '\n* ' + logs
- else:
- # We only update the buildlog for a nightly build if there
- # are additional items to append to the log list.
- return True
- else:
- # for non-nightly failures we create an entry in the list linking
- # to the failed builder and indent the logs as a child bullet list
- log_fmt = '\n* '
- builderfmt = log_fmt
- if self.isTriggered(build) or self.isNightlyRunning():
- log_fmt = '\n** '
- builderfmt = '\n* [%s %s] failed' % (url, builder)
-
- if len(log_entries) > 0:
- if self.isTriggered(build) or self.isNightlyRunning():
- builderfmt = builderfmt + ': ' + log_fmt
- logs = log_fmt.join(log_entries)
- logs = logs + '\n'
- new_entry = '\n' + entry.strip() + builderfmt + logs
-
- summary = 'Updating entry with failures in %s' % builder
- summary = summary + self.tag
-
- new_entry = self.updateEntryBuildInfo(new_entry, build)
- new_entry = new_entry.encode('utf-8')
-
- # Find the point where the first entry's title starts and the second
- # entry's title begins, then replace the text between those points
- # with the newly generated entry.
- it = re.finditer('\=\=\[(.+)\]\=\=', entries)
- entry_title = it.next()
- while entry_title.group(1) != title:
- entry_title = it.next()
- next_title = it.next()
- head = entries[:entry_title.end()]
- tail = entries[next_title.start():]
- update = head + new_entry + tail
-
- cookies = self.wiki.login()
- if not cookies:
- log.err("wkl: Failed to login to wiki")
- return False
-
- if not self.wiki.post_entry(self.wiki_page, blurb+update, summary,
- cookies):
- log.err("wkl: Failed to update entry for %s" % buildid)
- return False
-
- log.msg("wkl: Updating wikilog entry for %s" % buildid)
- return True
-
- def isNightlyRunning(self):
- """
- Determine whether there's a nightly build in progress
- """
- nightly = self.master.getBuilder("nightly")
- if not nightly:
- return False
- build = nightly.getBuild(-1) # the most recent build
- if not build:
- return False
- running = not build.isFinished()
- return running
-
- def isTriggered(self, build):
- """
- build.isFinished() can return True when buildsteps triggered by
- nightly are still running, therefore we provide a method to check
- whether the 'build' was triggered by a nightly build.
-
- @type build: buildbot.status.build.BuildStatus
- """
- reason = build.getReason()
- reason_list = reason.split(':', 1)
- forcedby = reason_list[0].strip()
- if forcedby.startswith("Triggerable"):
- return True
- return False
-
- def startService(self):
- """
- Hook into this method of base.StatusReceiverMultiService to subscribe
- to events from the controller/master.
- """
- log.msg("wkl: WikiLog service started, logging to %s" % self.wiki.wiki_uri)
- base.StatusReceiverMultiService.startService(self)
- self.master = self.parent
- self.status = self.parent.getStatus()
- self.status.subscribe(self)
-
- def builderAdded(self, name, builder):
- """
- This method is called each time a new Builder is added and may
- return an IStatusReceiver, i.e. self, if the IStatusReceiver
- wishes to subscribe to events (buildStarted, buildFinished, etc)
- from the builder.
-
- For our purposes we wish to subscribe to all builders events
- and thus always return self.
-
- @type name: string
- @type builder: buildbot.status.builder.BuilderStatus
- """
- return self
-
- def buildStarted(self, builderName, build):
- """
- Builder 'builderName' has just started a build. The build is an
- object which implements IBuildStatus, and can be queried for more
- information.
-
- @type builderName: string
- @type build: buildbot.status.build.BuildStatus
- """
- if builderName != "nightly" and not self.isTriggered(build)\
- and not self.isNightlyRunning():
- # If a build has been started which isn't nightly and a nightly
- # build isn't running, chances are a single builder has been
- # started in order to test something and it just finished.
- if not self.logBuild(build):
- log.err("wkl: Failed to log build %s" % build.getNumber())
- elif builderName == "nightly":
- if not self.logBuild(build):
- log.err("wkl: Failed to log build %s" % build.getNumber())
-
- # Return an IStatusReceiver, self, to subscribe to stepStarted()
- # and stepFinished() messages
- return self
-
- def stepFinished(self, build, step, results):
- """
- The buildstep 'step' of 'build' just finished 'results' is one of the
- constants in buildbot.status.builder: SUCCESS, WARNINGS, FAILURE,
- SKIPPED or EXCEPTION.
-
- @type build: buildbot.status.build.BuildStatus
- @type step: buildbot.status.build.BuildStepStatus
- @type results: constant
- """
- blurb, content = self.wiki.get_content(self.wiki_page)
- if not blurb:
- log.err("wkl: Couldn't get wiki content in stepFinished()")
- return
- update = self.updateBuildInfo(content, build)
-
- if not update:
- #log.msg("wkl: No update, nothing to POST")
- return
-
- if content == update:
- #log.msg("wkl: No update made, no need to make a POST")
- return
-
- cookies = self.wiki.login()
- if not cookies:
- log.err("wkl: Failed to login to wiki")
- return
-
- summary = "Updating branch and commitish for %s" %\
- build.getNumber()
- if not self.wiki.post_entry(self.wiki_page, blurb+update, summary,
- cookies):
- #log.err("wkl: Failed to update wikilog with summary: '{}'".format(summary))
- return
-
- def buildFinished(self, builderName, build, result):
- """
- A build has just finished. 'results' is one of the constants in
- buildbot.status.builder: SUCCESS, WARNINGS, FAILURE, SKIPPED or
- EXCEPTION.
-
- @type builderName: string
- @type build: buildbot.status.build.BuildStatus
- @type results: constant
- """
- if result == SUCCESS:
- return
-
- if not self.updateBuild(build):
- log.err("wkl: Failed to update wikilog with build %s failure" %
- build.getNumber())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 86d0b235..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,30 +0,0 @@
-Metadata-Version: 1.1
-Name: buildbot
-Version: 0.8.8
-Summary: BuildBot build automation system
-Home-page: http://buildbot.net/
-Author: Dustin J. Mitchell
-Author-email: dustin@v.igoro.us
-License: GNU GPL
-Description:
- The BuildBot is a system to automate the compile/test cycle required by
- most software projects to validate code changes. By automatically
- rebuilding and testing the tree each time something has changed, build
- problems are pinpointed quickly, before other developers are
- inconvenienced by the failure. The guilty developer can be identified
- and harassed without human intervention. By running the builds on a
- variety of platforms, developers who do not have the facilities to test
- their changes everywhere before checkin will at least know shortly
- afterwards whether they have broken the build or not. Warning counts,
- lint checks, image size, compile time, and other build parameters can
- be tracked over time, are more visible, and are therefore easier to
- improve.
-
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: No Input/Output (Daemon)
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: GNU General Public License (GPL)
-Classifier: Topic :: Software Development :: Build Tools
-Classifier: Topic :: Software Development :: Testing
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 33dddcef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,640 +0,0 @@
-COPYING
-CREDITS
-MANIFEST.in
-README
-UPGRADING
-setup.cfg
-setup.py
-bin/buildbot
-buildbot/__init__.py
-buildbot/buildbot.png
-buildbot/buildrequest.py
-buildbot/config.py
-buildbot/ec2buildslave.py
-buildbot/interfaces.py
-buildbot/libvirtbuildslave.py
-buildbot/locks.py
-buildbot/manhole.py
-buildbot/master.py
-buildbot/pbmanager.py
-buildbot/pbutil.py
-buildbot/revlinks.py
-buildbot/scheduler.py
-buildbot/sourcestamp.py
-buildbot.egg-info/PKG-INFO
-buildbot.egg-info/SOURCES.txt
-buildbot.egg-info/dependency_links.txt
-buildbot.egg-info/requires.txt
-buildbot.egg-info/top_level.txt
-buildbot/buildslave/__init__.py
-buildbot/buildslave/base.py
-buildbot/buildslave/ec2.py
-buildbot/buildslave/libvirt.py
-buildbot/buildslave/openstack.py
-buildbot/changes/__init__.py
-buildbot/changes/base.py
-buildbot/changes/bonsaipoller.py
-buildbot/changes/changes.py
-buildbot/changes/filter.py
-buildbot/changes/gerritchangesource.py
-buildbot/changes/gitpoller.py
-buildbot/changes/hgbuildbot.py
-buildbot/changes/hgpoller.py
-buildbot/changes/mail.py
-buildbot/changes/manager.py
-buildbot/changes/p4poller.py
-buildbot/changes/pb.py
-buildbot/changes/svnpoller.py
-buildbot/clients/__init__.py
-buildbot/clients/base.py
-buildbot/clients/debug.glade
-buildbot/clients/debug.py
-buildbot/clients/gtkPanes.py
-buildbot/clients/sendchange.py
-buildbot/clients/text.py
-buildbot/clients/tryclient.py
-buildbot/clients/usersclient.py
-buildbot/db/__init__.py
-buildbot/db/base.py
-buildbot/db/buildrequests.py
-buildbot/db/builds.py
-buildbot/db/buildsets.py
-buildbot/db/changes.py
-buildbot/db/connector.py
-buildbot/db/enginestrategy.py
-buildbot/db/exceptions.py
-buildbot/db/model.py
-buildbot/db/pool.py
-buildbot/db/schedulers.py
-buildbot/db/sourcestamps.py
-buildbot/db/sourcestampsets.py
-buildbot/db/state.py
-buildbot/db/users.py
-buildbot/db/migrate/README
-buildbot/db/migrate/migrate.cfg
-buildbot/db/migrate/versions/001_initial.py
-buildbot/db/migrate/versions/002_add_proj_repo.py
-buildbot/db/migrate/versions/003_scheduler_class_name.py
-buildbot/db/migrate/versions/004_add_autoincrement.py
-buildbot/db/migrate/versions/005_add_indexes.py
-buildbot/db/migrate/versions/006_drop_last_access.py
-buildbot/db/migrate/versions/007_add_object_tables.py
-buildbot/db/migrate/versions/008_add_scheduler_changes_index.py
-buildbot/db/migrate/versions/009_add_patch_author.py
-buildbot/db/migrate/versions/010_fix_column_lengths.py
-buildbot/db/migrate/versions/011_add_buildrequest_claims.py
-buildbot/db/migrate/versions/012_add_users_table.py
-buildbot/db/migrate/versions/013_remove_schedulers_state_column.py
-buildbot/db/migrate/versions/014_add_users_userpass_columns.py
-buildbot/db/migrate/versions/015_remove_bad_master_objectid.py
-buildbot/db/migrate/versions/016_restore_buildrequest_indices.py
-buildbot/db/migrate/versions/017_restore_other_indices.py
-buildbot/db/migrate/versions/018_add_sourcestampset.py
-buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py
-buildbot/db/migrate/versions/020_remove_change_links.py
-buildbot/db/migrate/versions/021_fix_postgres_sequences.py
-buildbot/db/migrate/versions/022_add_codebase.py
-buildbot/db/migrate/versions/__init__.py
-buildbot/monkeypatches/__init__.py
-buildbot/monkeypatches/bug4520.py
-buildbot/monkeypatches/bug4881.py
-buildbot/monkeypatches/bug5079.py
-buildbot/monkeypatches/gatherResults.py
-buildbot/monkeypatches/servicechecks.py
-buildbot/monkeypatches/sqlalchemy2189.py
-buildbot/monkeypatches/sqlalchemy2364.py
-buildbot/monkeypatches/testcase_patch.py
-buildbot/process/__init__.py
-buildbot/process/base.py
-buildbot/process/botmaster.py
-buildbot/process/build.py
-buildbot/process/builder.py
-buildbot/process/buildrequest.py
-buildbot/process/buildrequestdistributor.py
-buildbot/process/buildstep.py
-buildbot/process/cache.py
-buildbot/process/debug.py
-buildbot/process/factory.py
-buildbot/process/metrics.py
-buildbot/process/mtrlogobserver.py
-buildbot/process/properties.py
-buildbot/process/slavebuilder.py
-buildbot/process/subunitlogobserver.py
-buildbot/process/users/__init__.py
-buildbot/process/users/manager.py
-buildbot/process/users/manual.py
-buildbot/process/users/users.py
-buildbot/schedulers/__init__.py
-buildbot/schedulers/base.py
-buildbot/schedulers/basic.py
-buildbot/schedulers/dependent.py
-buildbot/schedulers/filter.py
-buildbot/schedulers/forcesched.py
-buildbot/schedulers/manager.py
-buildbot/schedulers/timed.py
-buildbot/schedulers/triggerable.py
-buildbot/schedulers/trysched.py
-buildbot/scripts/__init__.py
-buildbot/scripts/base.py
-buildbot/scripts/buildbot_tac.tmpl
-buildbot/scripts/checkconfig.py
-buildbot/scripts/create_master.py
-buildbot/scripts/debugclient.py
-buildbot/scripts/logwatcher.py
-buildbot/scripts/reconfig.py
-buildbot/scripts/restart.py
-buildbot/scripts/runner.py
-buildbot/scripts/sample.cfg
-buildbot/scripts/sendchange.py
-buildbot/scripts/start.py
-buildbot/scripts/statusgui.py
-buildbot/scripts/statuslog.py
-buildbot/scripts/stop.py
-buildbot/scripts/trycmd.py
-buildbot/scripts/tryserver.py
-buildbot/scripts/upgrade_master.py
-buildbot/scripts/user.py
-buildbot/status/__init__.py
-buildbot/status/base.py
-buildbot/status/build.py
-buildbot/status/builder.py
-buildbot/status/buildrequest.py
-buildbot/status/buildset.py
-buildbot/status/buildstep.py
-buildbot/status/client.py
-buildbot/status/event.py
-buildbot/status/html.py
-buildbot/status/logfile.py
-buildbot/status/mail.py
-buildbot/status/master.py
-buildbot/status/persistent_queue.py
-buildbot/status/progress.py
-buildbot/status/results.py
-buildbot/status/slave.py
-buildbot/status/status_gerrit.py
-buildbot/status/status_push.py
-buildbot/status/testresult.py
-buildbot/status/tinderbox.py
-buildbot/status/words.py
-buildbot/status/web/__init__.py
-buildbot/status/web/about.py
-buildbot/status/web/auth.py
-buildbot/status/web/authz.py
-buildbot/status/web/base.py
-buildbot/status/web/baseweb.py
-buildbot/status/web/build.py
-buildbot/status/web/builder.py
-buildbot/status/web/buildstatus.py
-buildbot/status/web/change_hook.py
-buildbot/status/web/changes.py
-buildbot/status/web/console.py
-buildbot/status/web/feeds.py
-buildbot/status/web/grid.py
-buildbot/status/web/logs.py
-buildbot/status/web/olpb.py
-buildbot/status/web/root.py
-buildbot/status/web/session.py
-buildbot/status/web/slaves.py
-buildbot/status/web/status_json.py
-buildbot/status/web/step.py
-buildbot/status/web/tests.py
-buildbot/status/web/users.py
-buildbot/status/web/waterfall.py
-buildbot/status/web/files/bg_gradient.jpg
-buildbot/status/web/files/default.css
-buildbot/status/web/files/favicon.ico
-buildbot/status/web/files/robots.txt
-buildbot/status/web/files/templates_readme.txt
-buildbot/status/web/hooks/__init__.py
-buildbot/status/web/hooks/base.py
-buildbot/status/web/hooks/github.py
-buildbot/status/web/hooks/googlecode.py
-buildbot/status/web/hooks/poller.py
-buildbot/status/web/templates/about.html
-buildbot/status/web/templates/authfail.html
-buildbot/status/web/templates/authzfail.html
-buildbot/status/web/templates/box_macros.html
-buildbot/status/web/templates/build.html
-buildbot/status/web/templates/build_line.html
-buildbot/status/web/templates/builder.html
-buildbot/status/web/templates/builders.html
-buildbot/status/web/templates/buildslave.html
-buildbot/status/web/templates/buildslaves.html
-buildbot/status/web/templates/buildstatus.html
-buildbot/status/web/templates/buildstep.html
-buildbot/status/web/templates/change.html
-buildbot/status/web/templates/change_macros.html
-buildbot/status/web/templates/change_sources.html
-buildbot/status/web/templates/console.html
-buildbot/status/web/templates/directory.html
-buildbot/status/web/templates/empty.html
-buildbot/status/web/templates/feed_atom10.xml
-buildbot/status/web/templates/feed_description.html
-buildbot/status/web/templates/feed_rss20.xml
-buildbot/status/web/templates/feed_sources.html
-buildbot/status/web/templates/footer.html
-buildbot/status/web/templates/forms.html
-buildbot/status/web/templates/grid.html
-buildbot/status/web/templates/grid_macros.html
-buildbot/status/web/templates/grid_transposed.html
-buildbot/status/web/templates/jsonhelp.html
-buildbot/status/web/templates/layout.html
-buildbot/status/web/templates/logs.html
-buildbot/status/web/templates/onelineperbuild.html
-buildbot/status/web/templates/onelineperbuildonebuilder.html
-buildbot/status/web/templates/revmacros.html
-buildbot/status/web/templates/root.html
-buildbot/status/web/templates/testresult.html
-buildbot/status/web/templates/user.html
-buildbot/status/web/templates/users.html
-buildbot/status/web/templates/waterfall.html
-buildbot/status/web/templates/waterfallhelp.html
-buildbot/steps/__init__.py
-buildbot/steps/master.py
-buildbot/steps/maxq.py
-buildbot/steps/python.py
-buildbot/steps/python_twisted.py
-buildbot/steps/shell.py
-buildbot/steps/slave.py
-buildbot/steps/subunit.py
-buildbot/steps/transfer.py
-buildbot/steps/trigger.py
-buildbot/steps/vstudio.py
-buildbot/steps/package/__init__.py
-buildbot/steps/package/deb/__init__.py
-buildbot/steps/package/deb/lintian.py
-buildbot/steps/package/deb/pbuilder.py
-buildbot/steps/package/rpm/__init__.py
-buildbot/steps/package/rpm/mock.py
-buildbot/steps/package/rpm/rpmbuild.py
-buildbot/steps/package/rpm/rpmlint.py
-buildbot/steps/package/rpm/rpmspec.py
-buildbot/steps/source/__init__.py
-buildbot/steps/source/base.py
-buildbot/steps/source/bzr.py
-buildbot/steps/source/cvs.py
-buildbot/steps/source/git.py
-buildbot/steps/source/mercurial.py
-buildbot/steps/source/oldsource.py
-buildbot/steps/source/p4.py
-buildbot/steps/source/repo.py
-buildbot/steps/source/svn.py
-buildbot/test/__init__.py
-buildbot/test/test_extra_coverage.py
-buildbot/test/fake/__init__.py
-buildbot/test/fake/botmaster.py
-buildbot/test/fake/fakebuild.py
-buildbot/test/fake/fakedb.py
-buildbot/test/fake/fakemaster.py
-buildbot/test/fake/libvirt.py
-buildbot/test/fake/openstack.py
-buildbot/test/fake/pbmanager.py
-buildbot/test/fake/remotecommand.py
-buildbot/test/fake/slave.py
-buildbot/test/fake/state.py
-buildbot/test/fake/web.py
-buildbot/test/regressions/__init__.py
-buildbot/test/regressions/test_bad_change_properties_rows.py
-buildbot/test/regressions/test_import_unicode_changes.py
-buildbot/test/regressions/test_oldpaths.py
-buildbot/test/regressions/test_shell_command_properties.py
-buildbot/test/regressions/test_sourcestamp_revision.py
-buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py
-buildbot/test/regressions/test_unpickling.py
-buildbot/test/unit/__init__.py
-buildbot/test/unit/test_buildslave_base.py
-buildbot/test/unit/test_buildslave_libvirt.py
-buildbot/test/unit/test_buildslave_openstack.py
-buildbot/test/unit/test_changes_base.py
-buildbot/test/unit/test_changes_bonsaipoller.py
-buildbot/test/unit/test_changes_changes.py
-buildbot/test/unit/test_changes_filter.py
-buildbot/test/unit/test_changes_gerritchangesource.py
-buildbot/test/unit/test_changes_gitpoller.py
-buildbot/test/unit/test_changes_hgpoller.py
-buildbot/test/unit/test_changes_mail.py
-buildbot/test/unit/test_changes_mail_CVSMaildirSource.py
-buildbot/test/unit/test_changes_manager.py
-buildbot/test/unit/test_changes_p4poller.py
-buildbot/test/unit/test_changes_pb.py
-buildbot/test/unit/test_changes_svnpoller.py
-buildbot/test/unit/test_clients_sendchange.py
-buildbot/test/unit/test_clients_tryclient.py
-buildbot/test/unit/test_clients_usersclient.py
-buildbot/test/unit/test_config.py
-buildbot/test/unit/test_contrib_buildbot_cvs_mail.py
-buildbot/test/unit/test_db_base.py
-buildbot/test/unit/test_db_buildrequests.py
-buildbot/test/unit/test_db_builds.py
-buildbot/test/unit/test_db_buildsets.py
-buildbot/test/unit/test_db_changes.py
-buildbot/test/unit/test_db_connector.py
-buildbot/test/unit/test_db_enginestrategy.py
-buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py
-buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py
-buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py
-buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py
-buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py
-buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py
-buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py
-buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py
-buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py
-buildbot/test/unit/test_db_model.py
-buildbot/test/unit/test_db_pool.py
-buildbot/test/unit/test_db_schedulers.py
-buildbot/test/unit/test_db_sourcestamps.py
-buildbot/test/unit/test_db_sourcestampsets.py
-buildbot/test/unit/test_db_state.py
-buildbot/test/unit/test_db_users.py
-buildbot/test/unit/test_master.py
-buildbot/test/unit/test_pbmanager.py
-buildbot/test/unit/test_process_botmaster_BotMaster.py
-buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py
-buildbot/test/unit/test_process_build.py
-buildbot/test/unit/test_process_builder.py
-buildbot/test/unit/test_process_buildrequest.py
-buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py
-buildbot/test/unit/test_process_buildstep.py
-buildbot/test/unit/test_process_cache.py
-buildbot/test/unit/test_process_debug.py
-buildbot/test/unit/test_process_factory.py
-buildbot/test/unit/test_process_metrics.py
-buildbot/test/unit/test_process_properties.py
-buildbot/test/unit/test_process_users_manager.py
-buildbot/test/unit/test_process_users_manual.py
-buildbot/test/unit/test_process_users_users.py
-buildbot/test/unit/test_revlinks.py
-buildbot/test/unit/test_schedulers_base.py
-buildbot/test/unit/test_schedulers_basic.py
-buildbot/test/unit/test_schedulers_dependent.py
-buildbot/test/unit/test_schedulers_forcesched.py
-buildbot/test/unit/test_schedulers_manager.py
-buildbot/test/unit/test_schedulers_timed_Nightly.py
-buildbot/test/unit/test_schedulers_timed_NightlyBase.py
-buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py
-buildbot/test/unit/test_schedulers_timed_Periodic.py
-buildbot/test/unit/test_schedulers_timed_Timed.py
-buildbot/test/unit/test_schedulers_triggerable.py
-buildbot/test/unit/test_schedulers_trysched.py
-buildbot/test/unit/test_scripts_base.py
-buildbot/test/unit/test_scripts_checkconfig.py
-buildbot/test/unit/test_scripts_create_master.py
-buildbot/test/unit/test_scripts_restart.py
-buildbot/test/unit/test_scripts_runner.py
-buildbot/test/unit/test_scripts_sendchange.py
-buildbot/test/unit/test_scripts_start.py
-buildbot/test/unit/test_scripts_statuslog.py
-buildbot/test/unit/test_scripts_stop.py
-buildbot/test/unit/test_scripts_trycmd.py
-buildbot/test/unit/test_scripts_tryserver.py
-buildbot/test/unit/test_scripts_upgrade_master.py
-buildbot/test/unit/test_scripts_user.py
-buildbot/test/unit/test_sourcestamp.py
-buildbot/test/unit/test_status_build.py
-buildbot/test/unit/test_status_builder_cache.py
-buildbot/test/unit/test_status_buildstep.py
-buildbot/test/unit/test_status_client.py
-buildbot/test/unit/test_status_logfile.py
-buildbot/test/unit/test_status_mail.py
-buildbot/test/unit/test_status_master.py
-buildbot/test/unit/test_status_persistent_queue.py
-buildbot/test/unit/test_status_progress.py
-buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py
-buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py
-buildbot/test/unit/test_status_web_authz_Authz.py
-buildbot/test/unit/test_status_web_base.py
-buildbot/test/unit/test_status_web_change_hook.py
-buildbot/test/unit/test_status_web_change_hooks_github.py
-buildbot/test/unit/test_status_web_change_hooks_googlecode.py
-buildbot/test/unit/test_status_web_change_hooks_poller.py
-buildbot/test/unit/test_status_web_links.py
-buildbot/test/unit/test_status_words.py
-buildbot/test/unit/test_steps_master.py
-buildbot/test/unit/test_steps_maxq.py
-buildbot/test/unit/test_steps_package_deb_lintian.py
-buildbot/test/unit/test_steps_package_deb_pbuilder.py
-buildbot/test/unit/test_steps_package_rpm_mock.py
-buildbot/test/unit/test_steps_package_rpm_rpmbuild.py
-buildbot/test/unit/test_steps_package_rpm_rpmlint.py
-buildbot/test/unit/test_steps_python.py
-buildbot/test/unit/test_steps_python_twisted.py
-buildbot/test/unit/test_steps_shell.py
-buildbot/test/unit/test_steps_slave.py
-buildbot/test/unit/test_steps_source_base_Source.py
-buildbot/test/unit/test_steps_source_bzr.py
-buildbot/test/unit/test_steps_source_cvs.py
-buildbot/test/unit/test_steps_source_git.py
-buildbot/test/unit/test_steps_source_mercurial.py
-buildbot/test/unit/test_steps_source_oldsource.py
-buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py
-buildbot/test/unit/test_steps_source_oldsource_Repo.py
-buildbot/test/unit/test_steps_source_p4.py
-buildbot/test/unit/test_steps_source_repo.py
-buildbot/test/unit/test_steps_source_svn.py
-buildbot/test/unit/test_steps_subunit.py
-buildbot/test/unit/test_steps_transfer.py
-buildbot/test/unit/test_steps_trigger.py
-buildbot/test/unit/test_steps_vstudio.py
-buildbot/test/unit/test_test_util_gpo.py
-buildbot/test/unit/test_util.py
-buildbot/test/unit/test_util_ComparableMixin.py
-buildbot/test/unit/test_util_bbcollections.py
-buildbot/test/unit/test_util_eventual.py
-buildbot/test/unit/test_util_lru.py
-buildbot/test/unit/test_util_maildir.py
-buildbot/test/unit/test_util_misc.py
-buildbot/test/unit/test_util_netstrings.py
-buildbot/test/unit/test_util_sautils.py
-buildbot/test/unit/test_util_state.py
-buildbot/test/unit/test_util_subscriptions.py
-buildbot/test/util/__init__.py
-buildbot/test/util/change_import.py
-buildbot/test/util/changesource.py
-buildbot/test/util/compat.py
-buildbot/test/util/config.py
-buildbot/test/util/connector_component.py
-buildbot/test/util/db.py
-buildbot/test/util/dirs.py
-buildbot/test/util/gpo.py
-buildbot/test/util/interfaces.py
-buildbot/test/util/logging.py
-buildbot/test/util/migration.py
-buildbot/test/util/misc.py
-buildbot/test/util/pbmanager.py
-buildbot/test/util/properties.py
-buildbot/test/util/querylog.py
-buildbot/test/util/scheduler.py
-buildbot/test/util/sourcesteps.py
-buildbot/test/util/steps.py
-buildbot/util/__init__.py
-buildbot/util/bbcollections.py
-buildbot/util/croniter.py
-buildbot/util/eventual.py
-buildbot/util/lru.py
-buildbot/util/maildir.py
-buildbot/util/misc.py
-buildbot/util/netstrings.py
-buildbot/util/sautils.py
-buildbot/util/state.py
-buildbot/util/subscription.py
-contrib/README.txt
-contrib/bb_applet.py
-contrib/bitbucket_buildbot.py
-contrib/bk_buildbot.py
-contrib/buildbot_cvs_mail.py
-contrib/buildbot_json.py
-contrib/bzr_buildbot.py
-contrib/check_buildbot.py
-contrib/coverage2text.py
-contrib/darcs_buildbot.py
-contrib/fakechange.py
-contrib/fakemaster.py
-contrib/fix_changes_pickle_encoding.py
-contrib/generate_changelog.py
-contrib/git_buildbot.py
-contrib/github_buildbot.py
-contrib/googlecode_atom.py
-contrib/post_build_request.py
-contrib/run_maxq.py
-contrib/svn_buildbot.py
-contrib/svn_watcher.py
-contrib/svnpoller.py
-contrib/viewcvspoll.py
-contrib/webhook_status.py
-contrib/css/sample1.css
-contrib/css/sample2.css
-contrib/init-scripts/buildmaster.default
-contrib/init-scripts/buildmaster.init.sh
-contrib/libvirt/network.xml
-contrib/libvirt/vmbuilder
-contrib/os-x/README
-contrib/os-x/net.sourceforge.buildbot.master.plist
-contrib/trac/README.md
-contrib/trac/TODO.md
-contrib/trac/setup.py
-contrib/trac/bbwatcher/__init__.py
-contrib/trac/bbwatcher/api.py
-contrib/trac/bbwatcher/model.py
-contrib/trac/bbwatcher/web_ui.py
-contrib/trac/bbwatcher/templates/bbw_allbuilders.html
-contrib/trac/bbwatcher/templates/bbw_builder.html
-contrib/trac/bbwatcher/templates/bbw_welcome.html
-contrib/windows/buildbot.bat
-contrib/windows/buildbot_service.py
-docs/Makefile
-docs/buildbot.1
-docs/conf.py
-docs/index.rst
-docs/_images/header-text-transparent.png
-docs/_static/buildbot.ico
-docs/_templates/layout.html
-docs/bbdocs/__init__.py
-docs/bbdocs/ext.py
-docs/developer/classes.rst
-docs/developer/cls-buildfactory.rst
-docs/developer/cls-buildsteps.rst
-docs/developer/cls-forcesched.rst
-docs/developer/cls-iproperties.rst
-docs/developer/cls-irenderable.rst
-docs/developer/cls-remotecommands.rst
-docs/developer/config.rst
-docs/developer/database.rst
-docs/developer/definitions.rst
-docs/developer/encodings.rst
-docs/developer/formats.rst
-docs/developer/index.rst
-docs/developer/master-overview.rst
-docs/developer/master-slave.rst
-docs/developer/metrics.rst
-docs/developer/results.rst
-docs/developer/style.rst
-docs/developer/tests.rst
-docs/developer/utils.rst
-docs/developer/webstatus.rst
-docs/examples/hello.cfg
-docs/examples/repo_gerrit.cfg
-docs/examples/twisted_master.cfg
-docs/manual/cfg-builders.rst
-docs/manual/cfg-buildfactories.rst
-docs/manual/cfg-buildslaves.rst
-docs/manual/cfg-buildsteps.rst
-docs/manual/cfg-changesources.rst
-docs/manual/cfg-global.rst
-docs/manual/cfg-interlocks.rst
-docs/manual/cfg-intro.rst
-docs/manual/cfg-properties.rst
-docs/manual/cfg-schedulers.rst
-docs/manual/cfg-statustargets.rst
-docs/manual/cmdline.rst
-docs/manual/concepts.rst
-docs/manual/configuration.rst
-docs/manual/customization.rst
-docs/manual/index.rst
-docs/manual/installation.rst
-docs/manual/introduction.rst
-docs/manual/optimization.rst
-docs/manual/resources.rst
-docs/manual/_images/Makefile
-docs/manual/_images/icon.blend
-docs/manual/_images/master.ai
-docs/manual/_images/master.svg
-docs/manual/_images/master.txt
-docs/manual/_images/overview.ai
-docs/manual/_images/overview.svg
-docs/manual/_images/overview.txt
-docs/manual/_images/slaves.ai
-docs/manual/_images/slaves.svg
-docs/manual/_images/slaves.txt
-docs/manual/_images/status.ai
-docs/manual/_images/status.svg
-docs/manual/_images/status.txt
-docs/relnotes/0.3.1.txt
-docs/relnotes/0.3.2.txt
-docs/relnotes/0.3.3.txt
-docs/relnotes/0.3.4.txt
-docs/relnotes/0.3.5.txt
-docs/relnotes/0.4.0.txt
-docs/relnotes/0.4.1.txt
-docs/relnotes/0.4.2.txt
-docs/relnotes/0.4.3.txt
-docs/relnotes/0.5.0.txt
-docs/relnotes/0.6.0.txt
-docs/relnotes/0.6.1.txt
-docs/relnotes/0.6.2.txt
-docs/relnotes/0.6.3.txt
-docs/relnotes/0.6.4.txt
-docs/relnotes/0.6.5.txt
-docs/relnotes/0.6.6.txt
-docs/relnotes/0.7.0.txt
-docs/relnotes/0.7.1.txt
-docs/relnotes/0.7.10.txt
-docs/relnotes/0.7.11.txt
-docs/relnotes/0.7.12.txt
-docs/relnotes/0.7.2.txt
-docs/relnotes/0.7.3.txt
-docs/relnotes/0.7.4.txt
-docs/relnotes/0.7.5.txt
-docs/relnotes/0.7.6.txt
-docs/relnotes/0.7.7.txt
-docs/relnotes/0.7.8.txt
-docs/relnotes/0.7.9.txt
-docs/relnotes/0.8.0.txt
-docs/relnotes/0.8.1.txt
-docs/relnotes/0.8.2.txt
-docs/relnotes/0.8.3.txt
-docs/relnotes/0.8.4.txt
-docs/relnotes/0.8.5.txt
-docs/relnotes/0.8.6.rst
-docs/relnotes/0.8.7.rst
-docs/relnotes/index.rst
-docs/relnotes/index.rst~
-docs/tutorial/firstrun.rst
-docs/tutorial/fiveminutes.rst
-docs/tutorial/further.rst
-docs/tutorial/index.rst
-docs/tutorial/tour.rst
-docs/tutorial/_images/force-build.png
-docs/tutorial/_images/index.png
-docs/tutorial/_images/irc-testrun.png
-docs/tutorial/_images/runtests-success.png
-docs/tutorial/_images/waterfall-empty.png \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/requires.txt
deleted file mode 100644
index 0eb16b91..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-twisted >= 9.0.0
-Jinja2 >= 2.1
-sqlalchemy >= 0.6, <= 0.7.9
-sqlalchemy-migrate ==0.6.1, ==0.7.0, ==0.7.1, ==0.7.2
-python-dateutil==1.5 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/scripts/buildbot b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/scripts/buildbot
deleted file mode 100644
index cf3628dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/scripts/buildbot
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/python
-
-from buildbot.scripts import runner
-runner.run()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 8683f0a6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-buildbot
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION
deleted file mode 100644
index 5c5cbb3b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.8.8 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py
deleted file mode 100644
index e9948006..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-# strategy:
-#
-# if there is a VERSION file, use its contents. otherwise, call git to
-# get a version string. if that also fails, use 'latest'.
-#
-import os
-
-version = "latest"
-
-try:
- fn = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'VERSION')
- with open(fn) as f:
- version = f.read().strip()
-
-except IOError:
- from subprocess import Popen, PIPE
- import re
-
- VERSION_MATCH = re.compile(r'\d+\.\d+\.\d+(\w|-)*')
-
- try:
- dir = os.path.dirname(os.path.abspath(__file__))
- p = Popen(['git', 'describe', '--tags', '--always'], cwd=dir, stdout=PIPE, stderr=PIPE)
- out = p.communicate()[0]
-
- if (not p.returncode) and out:
- v = VERSION_MATCH.search(out)
- if v:
- version = v.group()
- except OSError:
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.png b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.png
deleted file mode 100644
index 387ba15f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.png
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py
deleted file mode 100644
index ed6b6db6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.process.buildrequest import BuildRequest
-_hush_pyflakes = [ BuildRequest ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py
deleted file mode 100644
index c216e0c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.buildslave.base import (
- AbstractBuildSlave, BuildSlave, AbstractLatentBuildSlave)
-
-_hush_pyflakes = [
- AbstractBuildSlave, BuildSlave, AbstractLatentBuildSlave ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py
deleted file mode 100644
index 272b323d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py
+++ /dev/null
@@ -1,1049 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Canonical Ltd. 2009
-
-import time
-from email.Message import Message
-from email.Utils import formatdate
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer, reactor
-from twisted.application import service
-from twisted.spread import pb
-from twisted.python.reflect import namedModule
-
-from buildbot.status.slave import SlaveStatus
-from buildbot.status.mail import MailNotifier
-from buildbot.process import metrics, botmaster
-from buildbot.interfaces import IBuildSlave, ILatentBuildSlave
-from buildbot.process.properties import Properties
-from buildbot.util import subscription
-from buildbot.util.eventual import eventually
-from buildbot import config
-
-class AbstractBuildSlave(config.ReconfigurableServiceMixin, pb.Avatar,
- service.MultiService):
- """This is the master-side representative for a remote buildbot slave.
- There is exactly one for each slave described in the config file (the
- c['slaves'] list). When buildbots connect in (.attach), they get a
- reference to this instance. The BotMaster object is stashed as the
- .botmaster attribute. The BotMaster is also our '.parent' Service.
-
- I represent a build slave -- a remote machine capable of
- running builds. I am instantiated by the configuration file, and can be
- subclassed to add extra functionality."""
-
- implements(IBuildSlave)
- keepalive_timer = None
- keepalive_interval = None
-
- # reconfig slaves after builders
- reconfig_priority = 64
-
- def __init__(self, name, password, max_builds=None,
- notify_on_missing=[], missing_timeout=3600,
- properties={}, locks=None, keepalive_interval=3600):
- """
- @param name: botname this machine will supply when it connects
- @param password: password this machine will supply when
- it connects
- @param max_builds: maximum number of simultaneous builds that will
- be run concurrently on this buildslave (the
- default is None for no limit)
- @param properties: properties that will be applied to builds run on
- this slave
- @type properties: dictionary
- @param locks: A list of locks that must be acquired before this slave
- can be used
- @type locks: dictionary
- """
- service.MultiService.__init__(self)
- self.slavename = name
- self.password = password
-
- # PB registration
- self.registration = None
- self.registered_port = None
-
- # these are set when the service is started, and unset when it is
- # stopped
- self.botmaster = None
- self.master = None
-
- self.slave_status = SlaveStatus(name)
- self.slave = None # a RemoteReference to the Bot, when connected
- self.slave_commands = None
- self.slavebuilders = {}
- self.max_builds = max_builds
- self.access = []
- if locks:
- self.access = locks
- self.lock_subscriptions = []
-
- self.properties = Properties()
- self.properties.update(properties, "BuildSlave")
- self.properties.setProperty("slavename", name, "BuildSlave")
-
- self.lastMessageReceived = 0
- if isinstance(notify_on_missing, str):
- notify_on_missing = [notify_on_missing]
- self.notify_on_missing = notify_on_missing
- for i in notify_on_missing:
- if not isinstance(i, str):
- config.error(
- 'notify_on_missing arg %r is not a string' % (i,))
- self.missing_timeout = missing_timeout
- self.missing_timer = None
- self.keepalive_interval = keepalive_interval
-
- self.detached_subs = None
-
- self._old_builder_list = None
-
- def __repr__(self):
- return "<%s %r>" % (self.__class__.__name__, self.slavename)
-
- def updateLocks(self):
- """Convert the L{LockAccess} objects in C{self.locks} into real lock
- objects, while also maintaining the subscriptions to lock releases."""
- # unsubscribe from any old locks
- for s in self.lock_subscriptions:
- s.unsubscribe()
-
- # convert locks into their real form
- locks = [ (self.botmaster.getLockFromLockAccess(a), a)
- for a in self.access ]
- self.locks = [(l.getLock(self), la) for l, la in locks]
- self.lock_subscriptions = [ l.subscribeToReleases(self._lockReleased)
- for l, la in self.locks ]
-
- def locksAvailable(self):
- """
- I am called to see if all the locks I depend on are available,
- in which I return True, otherwise I return False
- """
- if not self.locks:
- return True
- for lock, access in self.locks:
- if not lock.isAvailable(self, access):
- return False
- return True
-
- def acquireLocks(self):
- """
- I am called when a build is preparing to run. I try to claim all
- the locks that are needed for a build to happen. If I can't, then
- my caller should give up the build and try to get another slave
- to look at it.
- """
- log.msg("acquireLocks(slave %s, locks %s)" % (self, self.locks))
- if not self.locksAvailable():
- log.msg("slave %s can't lock, giving up" % (self, ))
- return False
- # all locks are available, claim them all
- for lock, access in self.locks:
- lock.claim(self, access)
- return True
-
- def releaseLocks(self):
- """
- I am called to release any locks after a build has finished
- """
- log.msg("releaseLocks(%s): %s" % (self, self.locks))
- for lock, access in self.locks:
- lock.release(self, access)
-
- def _lockReleased(self):
- """One of the locks for this slave was released; try scheduling
- builds."""
- if not self.botmaster:
- return # oh well..
- self.botmaster.maybeStartBuildsForSlave(self.slavename)
-
- def setServiceParent(self, parent):
- # botmaster needs to set before setServiceParent which calls startService
- self.botmaster = parent
- self.master = parent.master
- service.MultiService.setServiceParent(self, parent)
-
- def startService(self):
- self.updateLocks()
- self.startMissingTimer()
- return service.MultiService.startService(self)
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # Given a new BuildSlave, configure this one identically. Because
- # BuildSlave objects are remotely referenced, we can't replace them
- # without disconnecting the slave, yet there's no reason to do that.
- new = self.findNewSlaveInstance(new_config)
-
- assert self.slavename == new.slavename
-
- # do we need to re-register?
- if (not self.registration or
- self.password != new.password or
- new_config.slavePortnum != self.registered_port):
- if self.registration:
- yield self.registration.unregister()
- self.registration = None
- self.password = new.password
- self.registered_port = new_config.slavePortnum
- self.registration = self.master.pbmanager.register(
- self.registered_port, self.slavename,
- self.password, self.getPerspective)
-
- # adopt new instance's configuration parameters
- self.max_builds = new.max_builds
- self.access = new.access
- self.notify_on_missing = new.notify_on_missing
- self.keepalive_interval = new.keepalive_interval
-
- if self.missing_timeout != new.missing_timeout:
- running_missing_timer = self.missing_timer
- self.stopMissingTimer()
- self.missing_timeout = new.missing_timeout
- if running_missing_timer:
- self.startMissingTimer()
-
- properties = Properties()
- properties.updateFromProperties(new.properties)
- self.properties = properties
-
- self.updateLocks()
-
- # update the attached slave's notion of which builders are attached.
- # This assumes that the relevant builders have already been configured,
- # which is why the reconfig_priority is set low in this class.
- yield self.updateSlave()
-
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def stopService(self):
- if self.registration:
- self.registration.unregister()
- self.registration = None
- self.stopMissingTimer()
- return service.MultiService.stopService(self)
-
- def findNewSlaveInstance(self, new_config):
- # TODO: called multiple times per reconfig; use 1-element cache?
- for sl in new_config.slaves:
- if sl.slavename == self.slavename:
- return sl
- assert 0, "no new slave named '%s'" % self.slavename
-
- def startMissingTimer(self):
- if self.notify_on_missing and self.missing_timeout and self.parent:
- self.stopMissingTimer() # in case it's already running
- self.missing_timer = reactor.callLater(self.missing_timeout,
- self._missing_timer_fired)
-
- def stopMissingTimer(self):
- if self.missing_timer:
- self.missing_timer.cancel()
- self.missing_timer = None
-
- def getPerspective(self, mind, slavename):
- assert slavename == self.slavename
- metrics.MetricCountEvent.log("attached_slaves", 1)
-
- # record when this connection attempt occurred
- if self.slave_status:
- self.slave_status.recordConnectTime()
-
- # try to use TCP keepalives
- try:
- mind.broker.transport.setTcpKeepAlive(1)
- except:
- pass
-
- if self.isConnected():
- # duplicate slave - send it to arbitration
- arb = botmaster.DuplicateSlaveArbitrator(self)
- return arb.getPerspective(mind, slavename)
- else:
- log.msg("slave '%s' attaching from %s" % (slavename, mind.broker.transport.getPeer()))
- return self
-
- def doKeepalive(self):
- self.keepalive_timer = reactor.callLater(self.keepalive_interval,
- self.doKeepalive)
- if not self.slave:
- return
- d = self.slave.callRemote("print", "Received keepalive from master")
- d.addErrback(log.msg, "Keepalive failed for '%s'" % (self.slavename, ))
-
- def stopKeepaliveTimer(self):
- if self.keepalive_timer:
- self.keepalive_timer.cancel()
-
- def startKeepaliveTimer(self):
- assert self.keepalive_interval
- log.msg("Starting buildslave keepalive timer for '%s'" % \
- (self.slavename, ))
- self.doKeepalive()
-
- def isConnected(self):
- return self.slave
-
- def _missing_timer_fired(self):
- self.missing_timer = None
- # notify people, but only if we're still in the config
- if not self.parent:
- return
-
- buildmaster = self.botmaster.master
- status = buildmaster.getStatus()
- text = "The Buildbot working for '%s'\n" % status.getTitle()
- text += ("has noticed that the buildslave named %s went away\n" %
- self.slavename)
- text += "\n"
- text += ("It last disconnected at %s (buildmaster-local time)\n" %
- time.ctime(time.time() - self.missing_timeout)) # approx
- text += "\n"
- text += "The admin on record (as reported by BUILDSLAVE:info/admin)\n"
- text += "was '%s'.\n" % self.slave_status.getAdmin()
- text += "\n"
- text += "Sincerely,\n"
- text += " The Buildbot\n"
- text += " %s\n" % status.getTitleURL()
- text += "\n"
- text += "%s\n" % status.getURLForThing(self.slave_status)
- subject = "Buildbot: buildslave %s was lost" % self.slavename
- return self._mail_missing_message(subject, text)
-
-
- def updateSlave(self):
- """Called to add or remove builders after the slave has connected.
-
- @return: a Deferred that indicates when an attached slave has
- accepted the new builders and/or released the old ones."""
- if self.slave:
- return self.sendBuilderList()
- else:
- return defer.succeed(None)
-
- def updateSlaveStatus(self, buildStarted=None, buildFinished=None):
- if buildStarted:
- self.slave_status.buildStarted(buildStarted)
- if buildFinished:
- self.slave_status.buildFinished(buildFinished)
-
- @metrics.countMethod('AbstractBuildSlave.attached()')
- def attached(self, bot):
- """This is called when the slave connects.
-
- @return: a Deferred that fires when the attachment is complete
- """
-
- # the botmaster should ensure this.
- assert not self.isConnected()
-
- metrics.MetricCountEvent.log("AbstractBuildSlave.attached_slaves", 1)
-
- # set up the subscription point for eventual detachment
- self.detached_subs = subscription.SubscriptionPoint("detached")
-
- # now we go through a sequence of calls, gathering information, then
- # tell the Botmaster that it can finally give this slave to all the
- # Builders that care about it.
-
- # we accumulate slave information in this 'state' dictionary, then
- # set it atomically if we make it far enough through the process
- state = {}
-
- # Reset graceful shutdown status
- self.slave_status.setGraceful(False)
- # We want to know when the graceful shutdown flag changes
- self.slave_status.addGracefulWatcher(self._gracefulChanged)
-
- d = defer.succeed(None)
- def _log_attachment_on_slave(res):
- d1 = bot.callRemote("print", "attached")
- d1.addErrback(lambda why: None)
- return d1
- d.addCallback(_log_attachment_on_slave)
-
- def _get_info(res):
- d1 = bot.callRemote("getSlaveInfo")
- def _got_info(info):
- log.msg("Got slaveinfo from '%s'" % self.slavename)
- # TODO: info{} might have other keys
- state["admin"] = info.get("admin")
- state["host"] = info.get("host")
- state["access_uri"] = info.get("access_uri", None)
- state["slave_environ"] = info.get("environ", {})
- state["slave_basedir"] = info.get("basedir", None)
- state["slave_system"] = info.get("system", None)
- def _info_unavailable(why):
- why.trap(pb.NoSuchMethod)
- # maybe an old slave, doesn't implement remote_getSlaveInfo
- log.msg("BuildSlave.info_unavailable")
- log.err(why)
- d1.addCallbacks(_got_info, _info_unavailable)
- return d1
- d.addCallback(_get_info)
- self.startKeepaliveTimer()
-
- def _get_version(res):
- d = bot.callRemote("getVersion")
- def _got_version(version):
- state["version"] = version
- def _version_unavailable(why):
- why.trap(pb.NoSuchMethod)
- # probably an old slave
- state["version"] = '(unknown)'
- d.addCallbacks(_got_version, _version_unavailable)
- return d
- d.addCallback(_get_version)
-
- def _get_commands(res):
- d1 = bot.callRemote("getCommands")
- def _got_commands(commands):
- state["slave_commands"] = commands
- def _commands_unavailable(why):
- # probably an old slave
- if why.check(AttributeError):
- return
- log.msg("BuildSlave.getCommands is unavailable - ignoring")
- log.err(why)
- d1.addCallbacks(_got_commands, _commands_unavailable)
- return d1
- d.addCallback(_get_commands)
-
- def _accept_slave(res):
- self.slave_status.setAdmin(state.get("admin"))
- self.slave_status.setHost(state.get("host"))
- self.slave_status.setAccessURI(state.get("access_uri"))
- self.slave_status.setVersion(state.get("version"))
- self.slave_status.setConnected(True)
- self.slave_commands = state.get("slave_commands")
- self.slave_environ = state.get("slave_environ")
- self.slave_basedir = state.get("slave_basedir")
- self.slave_system = state.get("slave_system")
- self.slave = bot
- if self.slave_system == "nt":
- self.path_module = namedModule("ntpath")
- else:
- # most eveything accepts / as separator, so posix should be a
- # reasonable fallback
- self.path_module = namedModule("posixpath")
- log.msg("bot attached")
- self.messageReceivedFromSlave()
- self.stopMissingTimer()
- self.botmaster.master.status.slaveConnected(self.slavename)
-
- return self.updateSlave()
- d.addCallback(_accept_slave)
- d.addCallback(lambda _:
- self.botmaster.maybeStartBuildsForSlave(self.slavename))
-
- # Finally, the slave gets a reference to this BuildSlave. They
- # receive this later, after we've started using them.
- d.addCallback(lambda _: self)
- return d
-
- def messageReceivedFromSlave(self):
- now = time.time()
- self.lastMessageReceived = now
- self.slave_status.setLastMessageReceived(now)
-
- def detached(self, mind):
- metrics.MetricCountEvent.log("AbstractBuildSlave.attached_slaves", -1)
- self.slave = None
- self._old_builder_list = []
- self.slave_status.removeGracefulWatcher(self._gracefulChanged)
- self.slave_status.setConnected(False)
- log.msg("BuildSlave.detached(%s)" % self.slavename)
- self.botmaster.master.status.slaveDisconnected(self.slavename)
- self.stopKeepaliveTimer()
- self.releaseLocks()
-
- # notify watchers, but do so in the next reactor iteration so that
- # any further detached() action by subclasses happens first
- def notif():
- subs = self.detached_subs
- self.detached_subs = None
- subs.deliver()
- eventually(notif)
-
- def subscribeToDetach(self, callback):
- """
- Request that C{callable} be invoked with no arguments when the
- L{detached} method is invoked.
-
- @returns: L{Subscription}
- """
- assert self.detached_subs, "detached_subs is only set if attached"
- return self.detached_subs.subscribe(callback)
-
- def disconnect(self):
- """Forcibly disconnect the slave.
-
- This severs the TCP connection and returns a Deferred that will fire
- (with None) when the connection is probably gone.
-
- If the slave is still alive, they will probably try to reconnect
- again in a moment.
-
- This is called in two circumstances. The first is when a slave is
- removed from the config file. In this case, when they try to
- reconnect, they will be rejected as an unknown slave. The second is
- when we wind up with two connections for the same slave, in which
- case we disconnect the older connection.
- """
-
- if not self.slave:
- return defer.succeed(None)
- log.msg("disconnecting old slave %s now" % self.slavename)
- # When this Deferred fires, we'll be ready to accept the new slave
- return self._disconnect(self.slave)
-
- def _disconnect(self, slave):
- # all kinds of teardown will happen as a result of
- # loseConnection(), but it happens after a reactor iteration or
- # two. Hook the actual disconnect so we can know when it is safe
- # to connect the new slave. We have to wait one additional
- # iteration (with callLater(0)) to make sure the *other*
- # notifyOnDisconnect handlers have had a chance to run.
- d = defer.Deferred()
-
- # notifyOnDisconnect runs the callback with one argument, the
- # RemoteReference being disconnected.
- def _disconnected(rref):
- eventually(d.callback, None)
- slave.notifyOnDisconnect(_disconnected)
- tport = slave.broker.transport
- # this is the polite way to request that a socket be closed
- tport.loseConnection()
- try:
- # but really we don't want to wait for the transmit queue to
- # drain. The remote end is unlikely to ACK the data, so we'd
- # probably have to wait for a (20-minute) TCP timeout.
- #tport._closeSocket()
- # however, doing _closeSocket (whether before or after
- # loseConnection) somehow prevents the notifyOnDisconnect
- # handlers from being run. Bummer.
- tport.offset = 0
- tport.dataBuffer = ""
- except:
- # however, these hacks are pretty internal, so don't blow up if
- # they fail or are unavailable
- log.msg("failed to accelerate the shutdown process")
- log.msg("waiting for slave to finish disconnecting")
-
- return d
-
- def sendBuilderList(self):
- our_builders = self.botmaster.getBuildersForSlave(self.slavename)
- blist = [(b.name, b.config.slavebuilddir) for b in our_builders]
- if blist == self._old_builder_list:
- return defer.succeed(None)
-
- d = self.slave.callRemote("setBuilderList", blist)
- def sentBuilderList(ign):
- self._old_builder_list = blist
- return ign
- d.addCallback(sentBuilderList)
- return d
-
- def perspective_keepalive(self):
- self.messageReceivedFromSlave()
-
- def perspective_shutdown(self):
- log.msg("slave %s wants to shut down" % self.slavename)
- self.slave_status.setGraceful(True)
-
- def addSlaveBuilder(self, sb):
- self.slavebuilders[sb.builder_name] = sb
-
- def removeSlaveBuilder(self, sb):
- try:
- del self.slavebuilders[sb.builder_name]
- except KeyError:
- pass
-
- def buildFinished(self, sb):
- """This is called when a build on this slave is finished."""
- self.botmaster.maybeStartBuildsForSlave(self.slavename)
-
- def canStartBuild(self):
- """
- I am called when a build is requested to see if this buildslave
- can start a build. This function can be used to limit overall
- concurrency on the buildslave.
-
- Note for subclassers: if a slave can become willing to start a build
- without any action on that slave (for example, by a resource in use on
- another slave becoming available), then you must arrange for
- L{maybeStartBuildsForSlave} to be called at that time, or builds on
- this slave will not start.
- """
-
- if self.slave_status.isPaused():
- return False
-
- # If we're waiting to shutdown gracefully, then we shouldn't
- # accept any new jobs.
- if self.slave_status.getGraceful():
- return False
-
- if self.max_builds:
- active_builders = [sb for sb in self.slavebuilders.values()
- if sb.isBusy()]
- if len(active_builders) >= self.max_builds:
- return False
-
- if not self.locksAvailable():
- return False
-
- return True
-
- def _mail_missing_message(self, subject, text):
- # first, see if we have a MailNotifier we can use. This gives us a
- # fromaddr and a relayhost.
- buildmaster = self.botmaster.master
- for st in buildmaster.status:
- if isinstance(st, MailNotifier):
- break
- else:
- # if not, they get a default MailNotifier, which always uses SMTP
- # to localhost and uses a dummy fromaddr of "buildbot".
- log.msg("buildslave-missing msg using default MailNotifier")
- st = MailNotifier("buildbot")
- # now construct the mail
-
- m = Message()
- m.set_payload(text)
- m['Date'] = formatdate(localtime=True)
- m['Subject'] = subject
- m['From'] = st.fromaddr
- recipients = self.notify_on_missing
- m['To'] = ", ".join(recipients)
- d = st.sendMessage(m, recipients)
- # return the Deferred for testing purposes
- return d
-
- def _gracefulChanged(self, graceful):
- """This is called when our graceful shutdown setting changes"""
- self.maybeShutdown()
-
- @defer.inlineCallbacks
- def shutdown(self):
- """Shutdown the slave"""
- if not self.slave:
- log.msg("no remote; slave is already shut down")
- return
-
- # First, try the "new" way - calling our own remote's shutdown
- # method. The method was only added in 0.8.3, so ignore NoSuchMethod
- # failures.
- def new_way():
- d = self.slave.callRemote('shutdown')
- d.addCallback(lambda _ : True) # successful shutdown request
- def check_nsm(f):
- f.trap(pb.NoSuchMethod)
- return False # fall through to the old way
- d.addErrback(check_nsm)
- def check_connlost(f):
- f.trap(pb.PBConnectionLost)
- return True # the slave is gone, so call it finished
- d.addErrback(check_connlost)
- return d
-
- if (yield new_way()):
- return # done!
-
- # Now, the old way. Look for a builder with a remote reference to the
- # client side slave. If we can find one, then call "shutdown" on the
- # remote builder, which will cause the slave buildbot process to exit.
- def old_way():
- d = None
- for b in self.slavebuilders.values():
- if b.remote:
- d = b.remote.callRemote("shutdown")
- break
-
- if d:
- log.msg("Shutting down (old) slave: %s" % self.slavename)
- # The remote shutdown call will not complete successfully since the
- # buildbot process exits almost immediately after getting the
- # shutdown request.
- # Here we look at the reason why the remote call failed, and if
- # it's because the connection was lost, that means the slave
- # shutdown as expected.
- def _errback(why):
- if why.check(pb.PBConnectionLost):
- log.msg("Lost connection to %s" % self.slavename)
- else:
- log.err("Unexpected error when trying to shutdown %s" % self.slavename)
- d.addErrback(_errback)
- return d
- log.err("Couldn't find remote builder to shut down slave")
- return defer.succeed(None)
- yield old_way()
-
- def maybeShutdown(self):
- """Shut down this slave if it has been asked to shut down gracefully,
- and has no active builders."""
- if not self.slave_status.getGraceful():
- return
- active_builders = [sb for sb in self.slavebuilders.values()
- if sb.isBusy()]
- if active_builders:
- return
- d = self.shutdown()
- d.addErrback(log.err, 'error while shutting down slave')
-
- def pause(self):
- """Stop running new builds on the slave."""
- self.slave_status.setPaused(True)
-
- def unpause(self):
- """Restart running new builds on the slave."""
- self.slave_status.setPaused(False)
- self.botmaster.maybeStartBuildsForSlave(self.slavename)
-
- def isPaused(self):
- return self.paused
-
-class BuildSlave(AbstractBuildSlave):
-
- def sendBuilderList(self):
- d = AbstractBuildSlave.sendBuilderList(self)
- def _sent(slist):
- # Nothing has changed, so don't need to re-attach to everything
- if not slist:
- return
- dl = []
- for name, remote in slist.items():
- # use get() since we might have changed our mind since then
- b = self.botmaster.builders.get(name)
- if b:
- d1 = b.attached(self, remote, self.slave_commands)
- dl.append(d1)
- return defer.DeferredList(dl)
- def _set_failed(why):
- log.msg("BuildSlave.sendBuilderList (%s) failed" % self)
- log.err(why)
- # TODO: hang up on them?, without setBuilderList we can't use
- # them
- d.addCallbacks(_sent, _set_failed)
- return d
-
- def detached(self, mind):
- AbstractBuildSlave.detached(self, mind)
- self.botmaster.slaveLost(self)
- self.startMissingTimer()
-
- def buildFinished(self, sb):
- """This is called when a build on this slave is finished."""
- AbstractBuildSlave.buildFinished(self, sb)
-
- # If we're gracefully shutting down, and we have no more active
- # builders, then it's safe to disconnect
- self.maybeShutdown()
-
-class AbstractLatentBuildSlave(AbstractBuildSlave):
- """A build slave that will start up a slave instance when needed.
-
- To use, subclass and implement start_instance and stop_instance.
-
- See ec2buildslave.py for a concrete example. Also see the stub example in
- test/test_slaves.py.
- """
-
- implements(ILatentBuildSlave)
-
- substantiated = False
- substantiation_deferred = None
- substantiation_build = None
- insubstantiating = False
- build_wait_timer = None
- _shutdown_callback_handle = None
-
- def __init__(self, name, password, max_builds=None,
- notify_on_missing=[], missing_timeout=60*20,
- build_wait_timeout=60*10,
- properties={}, locks=None):
- AbstractBuildSlave.__init__(
- self, name, password, max_builds, notify_on_missing,
- missing_timeout, properties, locks)
- self.building = set()
- self.build_wait_timeout = build_wait_timeout
-
- def start_instance(self, build):
- # responsible for starting instance that will try to connect with this
- # master. Should return deferred with either True (instance started)
- # or False (instance not started, so don't run a build here). Problems
- # should use an errback.
- raise NotImplementedError
-
- def stop_instance(self, fast=False):
- # responsible for shutting down instance.
- raise NotImplementedError
-
- def substantiate(self, sb, build):
- if self.substantiated:
- self._clearBuildWaitTimer()
- self._setBuildWaitTimer()
- return defer.succeed(True)
- if self.substantiation_deferred is None:
- if self.parent and not self.missing_timer:
- # start timer. if timer times out, fail deferred
- self.missing_timer = reactor.callLater(
- self.missing_timeout,
- self._substantiation_failed, defer.TimeoutError())
- self.substantiation_deferred = defer.Deferred()
- self.substantiation_build = build
- if self.slave is None:
- d = self._substantiate(build) # start up instance
- d.addErrback(log.err, "while substantiating")
- # else: we're waiting for an old one to detach. the _substantiate
- # will be done in ``detached`` below.
- return self.substantiation_deferred
-
- def _substantiate(self, build):
- # register event trigger
- d = self.start_instance(build)
- self._shutdown_callback_handle = reactor.addSystemEventTrigger(
- 'before', 'shutdown', self._soft_disconnect, fast=True)
- def start_instance_result(result):
- # If we don't report success, then preparation failed.
- if not result:
- log.msg("Slave '%s' doesn not want to substantiate at this time" % (self.slavename,))
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- d.callback(False)
- return result
- def clean_up(failure):
- if self.missing_timer is not None:
- self.missing_timer.cancel()
- self._substantiation_failed(failure)
- if self._shutdown_callback_handle is not None:
- handle = self._shutdown_callback_handle
- del self._shutdown_callback_handle
- reactor.removeSystemEventTrigger(handle)
- return failure
- d.addCallbacks(start_instance_result, clean_up)
- return d
-
- def attached(self, bot):
- if self.substantiation_deferred is None and self.build_wait_timeout >= 0:
- msg = 'Slave %s received connection while not trying to ' \
- 'substantiate. Disconnecting.' % (self.slavename,)
- log.msg(msg)
- self._disconnect(bot)
- return defer.fail(RuntimeError(msg))
- return AbstractBuildSlave.attached(self, bot)
-
- def detached(self, mind):
- AbstractBuildSlave.detached(self, mind)
- if self.substantiation_deferred is not None:
- d = self._substantiate(self.substantiation_build)
- d.addErrback(log.err, 'while re-substantiating')
-
- def _substantiation_failed(self, failure):
- self.missing_timer = None
- if self.substantiation_deferred:
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- d.errback(failure)
- self.insubstantiate()
- # notify people, but only if we're still in the config
- if not self.parent or not self.notify_on_missing:
- return
-
- buildmaster = self.botmaster.master
- status = buildmaster.getStatus()
- text = "The Buildbot working for '%s'\n" % status.getTitle()
- text += ("has noticed that the latent buildslave named %s \n" %
- self.slavename)
- text += "never substantiated after a request\n"
- text += "\n"
- text += ("The request was made at %s (buildmaster-local time)\n" %
- time.ctime(time.time() - self.missing_timeout)) # approx
- text += "\n"
- text += "Sincerely,\n"
- text += " The Buildbot\n"
- text += " %s\n" % status.getTitleURL()
- subject = "Buildbot: buildslave %s never substantiated" % self.slavename
- return self._mail_missing_message(subject, text)
-
- def canStartBuild(self):
- if self.insubstantiating:
- return False
- return AbstractBuildSlave.canStartBuild(self)
-
- def buildStarted(self, sb):
- assert self.substantiated
- self._clearBuildWaitTimer()
- self.building.add(sb.builder_name)
-
- def buildFinished(self, sb):
- AbstractBuildSlave.buildFinished(self, sb)
-
- self.building.remove(sb.builder_name)
- if not self.building:
- if self.build_wait_timeout == 0:
- self.insubstantiate()
- else:
- self._setBuildWaitTimer()
-
- def _clearBuildWaitTimer(self):
- if self.build_wait_timer is not None:
- if self.build_wait_timer.active():
- self.build_wait_timer.cancel()
- self.build_wait_timer = None
-
- def _setBuildWaitTimer(self):
- self._clearBuildWaitTimer()
- if self.build_wait_timeout <= 0:
- return
- self.build_wait_timer = reactor.callLater(
- self.build_wait_timeout, self._soft_disconnect)
-
- @defer.inlineCallbacks
- def insubstantiate(self, fast=False):
- self.insubstantiating = True
- self._clearBuildWaitTimer()
- d = self.stop_instance(fast)
- if self._shutdown_callback_handle is not None:
- handle = self._shutdown_callback_handle
- del self._shutdown_callback_handle
- reactor.removeSystemEventTrigger(handle)
- self.substantiated = False
- self.building.clear() # just to be sure
- yield d
- self.insubstantiating = False
-
- @defer.inlineCallbacks
- def _soft_disconnect(self, fast=False):
- # a negative build_wait_timeout means the slave should never be shut
- # down, so just disconnect.
- if self.build_wait_timeout < 0:
- yield AbstractBuildSlave.disconnect(self)
- return
-
- if self.missing_timer:
- self.missing_timer.cancel()
- self.missing_timer = None
-
- if self.substantiation_deferred is not None:
- log.msg("Weird: Got request to stop before started. Allowing "
- "slave to start cleanly to avoid inconsistent state")
- yield self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- log.msg("Substantiation complete, immediately terminating.")
-
- if self.slave is not None:
- # this could be called when the slave needs to shut down, such as
- # in BotMaster.removeSlave, *or* when a new slave requests a
- # connection when we already have a slave. It's not clear what to
- # do in the second case: this shouldn't happen, and if it
- # does...if it's a latent slave, shutting down will probably kill
- # something we want...but we can't know what the status is. So,
- # here, we just do what should be appropriate for the first case,
- # and put our heads in the sand for the second, at least for now.
- # The best solution to the odd situation is removing it as a
- # possibility: make the master in charge of connecting to the
- # slave, rather than vice versa. TODO.
- yield defer.DeferredList([
- AbstractBuildSlave.disconnect(self),
- self.insubstantiate(fast)
- ], consumeErrors=True, fireOnOneErrback=True)
- else:
- yield AbstractBuildSlave.disconnect(self)
- yield self.stop_instance(fast)
-
- def disconnect(self):
- # This returns a Deferred but we don't use it
- self._soft_disconnect()
- # this removes the slave from all builders. It won't come back
- # without a restart (or maybe a sighup)
- self.botmaster.slaveLost(self)
-
- def stopService(self):
- res = defer.maybeDeferred(AbstractBuildSlave.stopService, self)
- if self.slave is not None:
- d = self._soft_disconnect()
- res = defer.DeferredList([res, d])
- return res
-
- def updateSlave(self):
- """Called to add or remove builders after the slave has connected.
-
- Also called after botmaster's builders are initially set.
-
- @return: a Deferred that indicates when an attached slave has
- accepted the new builders and/or released the old ones."""
- for b in self.botmaster.getBuildersForSlave(self.slavename):
- if b.name not in self.slavebuilders:
- b.addLatentSlave(self)
- return AbstractBuildSlave.updateSlave(self)
-
- def sendBuilderList(self):
- d = AbstractBuildSlave.sendBuilderList(self)
- def _sent(slist):
- if not slist:
- return
- dl = []
- for name, remote in slist.items():
- # use get() since we might have changed our mind since then.
- # we're checking on the builder in addition to the
- # slavebuilders out of a bit of paranoia.
- b = self.botmaster.builders.get(name)
- sb = self.slavebuilders.get(name)
- if b and sb:
- d1 = sb.attached(self, remote, self.slave_commands)
- dl.append(d1)
- return defer.DeferredList(dl)
- def _set_failed(why):
- log.msg("BuildSlave.sendBuilderList (%s) failed" % self)
- log.err(why)
- # TODO: hang up on them?, without setBuilderList we can't use
- # them
- if self.substantiation_deferred:
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- d.errback(why)
- if self.missing_timer:
- self.missing_timer.cancel()
- self.missing_timer = None
- # TODO: maybe log? send an email?
- return why
- d.addCallbacks(_sent, _set_failed)
- def _substantiated(res):
- log.msg("Slave %s substantiated \o/" % self.slavename)
- self.substantiated = True
- if not self.substantiation_deferred:
- log.msg("No substantiation deferred for %s" % self.slavename)
- if self.substantiation_deferred:
- log.msg("Firing %s substantiation deferred with success" % self.slavename)
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- d.callback(True)
- # note that the missing_timer is already handled within
- # ``attached``
- if not self.building:
- self._setBuildWaitTimer()
- d.addCallback(_substantiated)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py
deleted file mode 100644
index f144321b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-
-from __future__ import with_statement
-# Portions Copyright Canonical Ltd. 2009
-
-"""A LatentSlave that uses EC2 to instantiate the slaves on demand.
-
-Tested with Python boto 1.5c
-"""
-
-import os
-import re
-import time
-
-import boto
-import boto.ec2
-import boto.exception
-from twisted.internet import defer, threads
-from twisted.python import log
-
-from buildbot.buildslave.base import AbstractLatentBuildSlave
-from buildbot import interfaces
-
-PENDING = 'pending'
-RUNNING = 'running'
-SHUTTINGDOWN = 'shutting-down'
-TERMINATED = 'terminated'
-
-class EC2LatentBuildSlave(AbstractLatentBuildSlave):
-
- instance = image = None
- _poll_resolution = 5 # hook point for tests
-
- def __init__(self, name, password, instance_type, ami=None,
- valid_ami_owners=None, valid_ami_location_regex=None,
- elastic_ip=None, identifier=None, secret_identifier=None,
- aws_id_file_path=None, user_data=None, region=None,
- keypair_name='latent_buildbot_slave',
- security_name='latent_buildbot_slave',
- max_builds=None, notify_on_missing=[], missing_timeout=60*20,
- build_wait_timeout=60*10, properties={}, locks=None):
-
- AbstractLatentBuildSlave.__init__(
- self, name, password, max_builds, notify_on_missing,
- missing_timeout, build_wait_timeout, properties, locks)
- if not ((ami is not None) ^
- (valid_ami_owners is not None or
- valid_ami_location_regex is not None)):
- raise ValueError(
- 'You must provide either a specific ami, or one or both of '
- 'valid_ami_location_regex and valid_ami_owners')
- self.ami = ami
- if valid_ami_owners is not None:
- if isinstance(valid_ami_owners, (int, long)):
- valid_ami_owners = (valid_ami_owners,)
- else:
- for element in valid_ami_owners:
- if not isinstance(element, (int, long)):
- raise ValueError(
- 'valid_ami_owners should be int or iterable '
- 'of ints', element)
- if valid_ami_location_regex is not None:
- if not isinstance(valid_ami_location_regex, basestring):
- raise ValueError(
- 'valid_ami_location_regex should be a string')
- else:
- # verify that regex will compile
- re.compile(valid_ami_location_regex)
- self.valid_ami_owners = valid_ami_owners
- self.valid_ami_location_regex = valid_ami_location_regex
- self.instance_type = instance_type
- self.keypair_name = keypair_name
- self.security_name = security_name
- self.user_data = user_data
- if identifier is None:
- assert secret_identifier is None, (
- 'supply both or neither of identifier, secret_identifier')
- if aws_id_file_path is None:
- home = os.environ['HOME']
- aws_id_file_path = os.path.join(home, '.ec2', 'aws_id')
- if not os.path.exists(aws_id_file_path):
- raise ValueError(
- "Please supply your AWS access key identifier and secret "
- "access key identifier either when instantiating this %s "
- "or in the %s file (on two lines).\n" %
- (self.__class__.__name__, aws_id_file_path))
- with open(aws_id_file_path, 'r') as aws_file:
- identifier = aws_file.readline().strip()
- secret_identifier = aws_file.readline().strip()
- else:
- assert aws_id_file_path is None, \
- 'if you supply the identifier and secret_identifier, ' \
- 'do not specify the aws_id_file_path'
- assert secret_identifier is not None, \
- 'supply both or neither of identifier, secret_identifier'
-
- region_found = None
-
- # Make the EC2 connection.
- if region is not None:
- for r in boto.ec2.regions(aws_access_key_id=identifier,
- aws_secret_access_key=secret_identifier):
-
- if r.name == region:
- region_found = r
-
-
- if region_found is not None:
- self.conn = boto.ec2.connect_to_region(region,
- aws_access_key_id=identifier,
- aws_secret_access_key=secret_identifier)
- else:
- raise ValueError('The specified region does not exist: {0}'.format(region))
-
- else:
- self.conn = boto.connect_ec2(identifier, secret_identifier)
-
- # Make a keypair
- #
- # We currently discard the keypair data because we don't need it.
- # If we do need it in the future, we will always recreate the keypairs
- # because there is no way to
- # programmatically retrieve the private key component, unless we
- # generate it and store it on the filesystem, which is an unnecessary
- # usage requirement.
- try:
- key_pair = self.conn.get_all_key_pairs(keypair_name)[0]
- assert key_pair
- # key_pair.delete() # would be used to recreate
- except boto.exception.EC2ResponseError, e:
- if 'InvalidKeyPair.NotFound' not in e.body:
- if 'AuthFailure' in e.body:
- print ('POSSIBLE CAUSES OF ERROR:\n'
- ' Did you sign up for EC2?\n'
- ' Did you put a credit card number in your AWS '
- 'account?\n'
- 'Please doublecheck before reporting a problem.\n')
- raise
- # make one; we would always do this, and stash the result, if we
- # needed the key (for instance, to SSH to the box). We'd then
- # use paramiko to use the key to connect.
- self.conn.create_key_pair(keypair_name)
-
- # create security group
- try:
- group = self.conn.get_all_security_groups(security_name)[0]
- assert group
- except boto.exception.EC2ResponseError, e:
- if 'InvalidGroup.NotFound' in e.body:
- self.security_group = self.conn.create_security_group(
- security_name,
- 'Authorization to access the buildbot instance.')
- # Authorize the master as necessary
- # TODO this is where we'd open the hole to do the reverse pb
- # connect to the buildbot
- # ip = urllib.urlopen(
- # 'http://checkip.amazonaws.com').read().strip()
- # self.security_group.authorize('tcp', 22, 22, '%s/32' % ip)
- # self.security_group.authorize('tcp', 80, 80, '%s/32' % ip)
- else:
- raise
-
- # get the image
- if self.ami is not None:
- self.image = self.conn.get_image(self.ami)
- else:
- # verify we have access to at least one acceptable image
- discard = self.get_image()
- assert discard
-
- # get the specified elastic IP, if any
- if elastic_ip is not None:
- elastic_ip = self.conn.get_all_addresses([elastic_ip])[0]
- self.elastic_ip = elastic_ip
-
- def get_image(self):
- if self.image is not None:
- return self.image
- if self.valid_ami_location_regex:
- level = 0
- options = []
- get_match = re.compile(self.valid_ami_location_regex).match
- for image in self.conn.get_all_images(
- owners=self.valid_ami_owners):
- # gather sorting data
- match = get_match(image.location)
- if match:
- alpha_sort = int_sort = None
- if level < 2:
- try:
- alpha_sort = match.group(1)
- except IndexError:
- level = 2
- else:
- if level == 0:
- try:
- int_sort = int(alpha_sort)
- except ValueError:
- level = 1
- options.append([int_sort, alpha_sort,
- image.location, image.id, image])
- if level:
- log.msg('sorting images at level %d' % level)
- options = [candidate[level:] for candidate in options]
- else:
- options = [(image.location, image.id, image) for image
- in self.conn.get_all_images(
- owners=self.valid_ami_owners)]
- options.sort()
- log.msg('sorted images (last is chosen): %s' %
- (', '.join(
- ['%s (%s)' % (candidate[-1].id, candidate[-1].location)
- for candidate in options])))
- if not options:
- raise ValueError('no available images match constraints')
- return options[-1][-1]
-
- def dns(self):
- if self.instance is None:
- return None
- return self.instance.public_dns_name
- dns = property(dns)
-
- def start_instance(self, build):
- if self.instance is not None:
- raise ValueError('instance active')
- return threads.deferToThread(self._start_instance)
-
- def _start_instance(self):
- image = self.get_image()
- reservation = image.run(
- key_name=self.keypair_name, security_groups=[self.security_name],
- instance_type=self.instance_type, user_data=self.user_data)
- self.instance = reservation.instances[0]
- log.msg('%s %s starting instance %s' %
- (self.__class__.__name__, self.slavename, self.instance.id))
- duration = 0
- interval = self._poll_resolution
- while self.instance.state == PENDING:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg('%s %s has waited %d minutes for instance %s' %
- (self.__class__.__name__, self.slavename, duration//60,
- self.instance.id))
- self.instance.update()
- if self.instance.state == RUNNING:
- self.output = self.instance.get_console_output()
- minutes = duration//60
- seconds = duration%60
- log.msg('%s %s instance %s started on %s '
- 'in about %d minutes %d seconds (%s)' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.dns, minutes, seconds,
- self.output.output))
- if self.elastic_ip is not None:
- self.instance.use_ip(self.elastic_ip)
- return [self.instance.id,
- image.id,
- '%02d:%02d:%02d' % (minutes//60, minutes%60, seconds)]
- else:
- log.msg('%s %s failed to start instance %s (%s)' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.instance.state))
- raise interfaces.LatentBuildSlaveFailedToSubstantiate(
- self.instance.id, self.instance.state)
-
- def stop_instance(self, fast=False):
- if self.instance is None:
- # be gentle. Something may just be trying to alert us that an
- # instance never attached, and it's because, somehow, we never
- # started.
- return defer.succeed(None)
- instance = self.instance
- self.output = self.instance = None
- return threads.deferToThread(
- self._stop_instance, instance, fast)
-
- def _stop_instance(self, instance, fast):
- if self.elastic_ip is not None:
- self.conn.disassociate_address(self.elastic_ip.public_ip)
- instance.update()
- if instance.state not in (SHUTTINGDOWN, TERMINATED):
- instance.terminate()
- log.msg('%s %s terminating instance %s' %
- (self.__class__.__name__, self.slavename, instance.id))
- duration = 0
- interval = self._poll_resolution
- if fast:
- goal = (SHUTTINGDOWN, TERMINATED)
- instance.update()
- else:
- goal = (TERMINATED,)
- while instance.state not in goal:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg(
- '%s %s has waited %d minutes for instance %s to end' %
- (self.__class__.__name__, self.slavename, duration//60,
- instance.id))
- instance.update()
- log.msg('%s %s instance %s %s '
- 'after about %d minutes %d seconds' %
- (self.__class__.__name__, self.slavename,
- instance.id, goal, duration//60, duration%60))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py
deleted file mode 100644
index 5776f10d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2010 Isotoma Limited
-
-from __future__ import absolute_import
-import os
-
-from twisted.internet import defer, utils, threads
-from twisted.python import log, failure
-from buildbot.buildslave.base import AbstractBuildSlave, AbstractLatentBuildSlave
-from buildbot.util.eventual import eventually
-from buildbot import config
-
-try:
- import libvirt
- libvirt = libvirt
-except ImportError:
- libvirt = None
-
-
-class WorkQueue(object):
- """
- I am a class that turns parallel access into serial access.
-
- I exist because we want to run libvirt access in threads as we don't
- trust calls not to block, but under load libvirt doesn't seem to like
- this kind of threaded use.
- """
-
- def __init__(self):
- self.queue = []
-
- def _process(self):
- log.msg("Looking to start a piece of work now...")
-
- # Is there anything to do?
- if not self.queue:
- log.msg("_process called when there is no work")
- return
-
- # Peek at the top of the stack - get a function to call and
- # a deferred to fire when its all over
- d, next_operation, args, kwargs = self.queue[0]
-
- # Start doing some work - expects a deferred
- try:
- d2 = next_operation(*args, **kwargs)
- except:
- d2 = defer.fail()
-
- # Whenever a piece of work is done, whether it worked or not
- # call this to schedule the next piece of work
- def _work_done(res):
- log.msg("Completed a piece of work")
- self.queue.pop(0)
- if self.queue:
- log.msg("Preparing next piece of work")
- eventually(self._process)
- return res
- d2.addBoth(_work_done)
-
- # When the work is done, trigger d
- d2.chainDeferred(d)
-
- def execute(self, cb, *args, **kwargs):
- kickstart_processing = not self.queue
- d = defer.Deferred()
- self.queue.append((d, cb, args, kwargs))
- if kickstart_processing:
- self._process()
- return d
-
- def executeInThread(self, cb, *args, **kwargs):
- return self.execute(threads.deferToThread, cb, *args, **kwargs)
-
-
-# A module is effectively a singleton class, so this is OK
-queue = WorkQueue()
-
-
-class Domain(object):
-
- """
- I am a wrapper around a libvirt Domain object
- """
-
- def __init__(self, connection, domain):
- self.connection = connection
- self.domain = domain
-
- def name(self):
- return queue.executeInThread(self.domain.name)
-
- def create(self):
- return queue.executeInThread(self.domain.create)
-
- def shutdown(self):
- return queue.executeInThread(self.domain.shutdown)
-
- def destroy(self):
- return queue.executeInThread(self.domain.destroy)
-
-
-class Connection(object):
-
- """
- I am a wrapper around a libvirt Connection object.
- """
-
- DomainClass = Domain
-
- def __init__(self, uri):
- self.uri = uri
- self.connection = libvirt.open(uri)
-
- @defer.inlineCallbacks
- def lookupByName(self, name):
- """ I lookup an existing predefined domain """
- res = yield queue.executeInThread(self.connection.lookupByName, name)
- defer.returnValue(self.DomainClass(self, res))
-
- @defer.inlineCallbacks
- def create(self, xml):
- """ I take libvirt XML and start a new VM """
- res = yield queue.executeInThread(self.connection.createXML, xml, 0)
- defer.returnValue(self.DomainClass(self, res))
-
- @defer.inlineCallbacks
- def all(self):
- domains = []
- domain_ids = yield queue.executeInThread(self.connection.listDomainsID)
-
- for did in domain_ids:
- domain = yield queue.executeInThread(self.connection.lookupByID, did)
- domains.append(self.DomainClass(self, domain))
-
- defer.returnValue(domains)
-
-
-class LibVirtSlave(AbstractLatentBuildSlave):
-
- def __init__(self, name, password, connection, hd_image, base_image = None, xml=None, max_builds=None, notify_on_missing=[],
- missing_timeout=60*20, build_wait_timeout=60*10, properties={}, locks=None):
- AbstractLatentBuildSlave.__init__(self, name, password, max_builds, notify_on_missing,
- missing_timeout, build_wait_timeout, properties, locks)
-
- if not libvirt:
- config.error("The python module 'libvirt' is needed to use a LibVirtSlave")
-
- self.name = name
- self.connection = connection
- self.image = hd_image
- self.base_image = base_image
- self.xml = xml
-
- self.cheap_copy = True
- self.graceful_shutdown = False
-
- self.domain = None
-
- self.ready = False
- self._find_existing_deferred = self._find_existing_instance()
-
- @defer.inlineCallbacks
- def _find_existing_instance(self):
- """
- I find existing VMs that are already running that might be orphaned instances of this slave.
- """
- if not self.connection:
- defer.returnValue(None)
-
- domains = yield self.connection.all()
- for d in domains:
- name = yield d.name()
- if name.startswith(self.name):
- self.domain = d
- self.substantiated = True
- break
-
- self.ready = True
-
- def canStartBuild(self):
- if not self.ready:
- log.msg("Not accepting builds as existing domains not iterated")
- return False
-
- if self.domain and not self.isConnected():
- log.msg("Not accepting builds as existing domain but slave not connected")
- return False
-
- return AbstractLatentBuildSlave.canStartBuild(self)
-
- def _prepare_base_image(self):
- """
- I am a private method for creating (possibly cheap) copies of a
- base_image for start_instance to boot.
- """
- if not self.base_image:
- return defer.succeed(True)
-
- if self.cheap_copy:
- clone_cmd = "qemu-img"
- clone_args = "create -b %(base)s -f qcow2 %(image)s"
- else:
- clone_cmd = "cp"
- clone_args = "%(base)s %(image)s"
-
- clone_args = clone_args % {
- "base": self.base_image,
- "image": self.image,
- }
-
- log.msg("Cloning base image: %s %s'" % (clone_cmd, clone_args))
-
- def _log_result(res):
- log.msg("Cloning exit code was: %d" % res)
- return res
-
- d = utils.getProcessValue(clone_cmd, clone_args.split())
- d.addBoth(_log_result)
- return d
-
- @defer.inlineCallbacks
- def start_instance(self, build):
- """
- I start a new instance of a VM.
-
- If a base_image is specified, I will make a clone of that otherwise i will
- use image directly.
-
- If i'm not given libvirt domain definition XML, I will look for my name
- in the list of defined virtual machines and start that.
- """
- if self.domain is not None:
- log.msg("Cannot start_instance '%s' as already active" % self.name)
- defer.returnValue(False)
-
- yield self._prepare_base_image()
-
- try:
- if self.xml:
- self.domain = yield self.connection.create(self.xml)
- else:
- self.domain = yield self.connection.lookupByName(self.name)
- yield self.domain.create()
- except:
- log.err(failure.Failure(),
- "Cannot start a VM (%s), failing gracefully and triggering"
- "a new build check" % self.name)
- self.domain = None
- defer.returnValue(False)
-
- defer.returnValue(True)
-
- def stop_instance(self, fast=False):
- """
- I attempt to stop a running VM.
- I make sure any connection to the slave is removed.
- If the VM was using a cloned image, I remove the clone
- When everything is tidied up, I ask that bbot looks for work to do
- """
- log.msg("Attempting to stop '%s'" % self.name)
- if self.domain is None:
- log.msg("I don't think that domain is even running, aborting")
- return defer.succeed(None)
-
- domain = self.domain
- self.domain = None
-
- if self.graceful_shutdown and not fast:
- log.msg("Graceful shutdown chosen for %s" % self.name)
- d = domain.shutdown()
- else:
- d = domain.destroy()
-
- def _disconnect(res):
- log.msg("VM destroyed (%s): Forcing its connection closed." % self.name)
- return AbstractBuildSlave.disconnect(self)
- d.addCallback(_disconnect)
-
- def _disconnected(res):
- log.msg("We forced disconnection (%s), cleaning up and triggering new build" % self.name)
- if self.base_image:
- os.remove(self.image)
- self.botmaster.maybeStartBuildsForSlave(self.name)
- return res
- d.addBoth(_disconnected)
-
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py
deleted file mode 100644
index ec5c4861..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2013 Cray Inc.
-
-import time
-
-from twisted.internet import defer, threads
-from twisted.python import log
-
-from buildbot.buildslave.base import AbstractLatentBuildSlave
-from buildbot import config, interfaces
-
-try:
- import novaclient.exceptions as nce
- from novaclient.v1_1 import client
- _hush_pyflakes = [nce, client]
-except ImportError:
- nce = None
- client = None
-
-
-ACTIVE = 'ACTIVE'
-BUILD = 'BUILD'
-DELETED = 'DELETED'
-UNKNOWN = 'UNKNOWN'
-
-class OpenStackLatentBuildSlave(AbstractLatentBuildSlave):
-
- instance = None
- _poll_resolution = 5 # hook point for tests
-
- def __init__(self, name, password,
- flavor,
- image,
- os_username,
- os_password,
- os_tenant_name,
- os_auth_url,
- meta=None,
- max_builds=None, notify_on_missing=[], missing_timeout=60*20,
- build_wait_timeout=60*10, properties={}, locks=None):
-
- if not client or not nce:
- config.error("The python module 'novaclient' is needed "
- "to use a OpenStackLatentBuildSlave")
-
- AbstractLatentBuildSlave.__init__(
- self, name, password, max_builds, notify_on_missing,
- missing_timeout, build_wait_timeout, properties, locks)
- self.flavor = flavor
- self.image = image
- self.os_username = os_username
- self.os_password = os_password
- self.os_tenant_name = os_tenant_name
- self.os_auth_url = os_auth_url
- self.meta = meta
-
- def _getImage(self, os_client):
- # If self.image is a callable, then pass it the list of images. The
- # function should return the image's UUID to use.
- if callable(self.image):
- image_uuid = self.image(os_client.images.list())
- else:
- image_uuid = self.image
- return image_uuid
-
- def start_instance(self, build):
- if self.instance is not None:
- raise ValueError('instance active')
- return threads.deferToThread(self._start_instance)
-
- def _start_instance(self):
- # Authenticate to OpenStack.
- os_client = client.Client(self.os_username, self.os_password,
- self.os_tenant_name, self.os_auth_url)
- image_uuid = self._getImage(os_client)
- flavor_id = self.flavor
- boot_args = [self.slavename, image_uuid, flavor_id]
- boot_kwargs = {}
- if self.meta is not None:
- boot_kwargs['meta'] = self.meta
- self.instance = os_client.servers.create(*boot_args, **boot_kwargs)
- log.msg('%s %s starting instance %s (image %s)' %
- (self.__class__.__name__, self.slavename, self.instance.id,
- image_uuid))
- duration = 0
- interval = self._poll_resolution
- inst = self.instance
- while inst.status == BUILD:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg('%s %s has waited %d minutes for instance %s' %
- (self.__class__.__name__, self.slavename, duration//60,
- self.instance.id))
- try:
- inst = os_client.servers.get(self.instance.id)
- except nce.NotFound:
- log.msg('%s %s instance %s (%s) went missing' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.instance.name))
- raise interfaces.LatentBuildSlaveFailedToSubstantiate(
- self.instance.id, self.instance.status)
- if inst.status == ACTIVE:
- minutes = duration//60
- seconds = duration%60
- log.msg('%s %s instance %s (%s) started '
- 'in about %d minutes %d seconds' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.instance.name, minutes, seconds))
- return [self.instance.id, image_uuid,
- '%02d:%02d:%02d' % (minutes//60, minutes%60, seconds)]
- else:
- log.msg('%s %s failed to start instance %s (%s)' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, inst.status))
- raise interfaces.LatentBuildSlaveFailedToSubstantiate(
- self.instance.id, self.instance.status)
-
- def stop_instance(self, fast=False):
- if self.instance is None:
- # be gentle. Something may just be trying to alert us that an
- # instance never attached, and it's because, somehow, we never
- # started.
- return defer.succeed(None)
- instance = self.instance
- self.instance = None
- return threads.deferToThread(self._stop_instance, instance, fast)
-
- def _stop_instance(self, instance, fast):
- # Authenticate to OpenStack. This is needed since it seems the update
- # method doesn't do a whole lot of updating right now.
- os_client = client.Client(self.os_username, self.os_password,
- self.os_tenant_name, self.os_auth_url)
- # When the update method does work, replace the lines like below with
- # instance.update().
- try:
- inst = os_client.servers.get(instance.id)
- except nce.NotFound:
- # If can't find the instance, then it's already gone.
- log.msg('%s %s instance %s (%s) already terminated' %
- (self.__class__.__name__, self.slavename, instance.id,
- instance.name))
- return
- if inst.status not in (DELETED, UNKNOWN):
- inst.delete()
- log.msg('%s %s terminating instance %s (%s)' %
- (self.__class__.__name__, self.slavename, instance.id,
- instance.name))
- duration = 0
- interval = self._poll_resolution
- if fast:
- goal = (DELETED, UNKNOWN)
- else:
- goal = (DELETED,)
- while inst.status not in goal:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg(
- '%s %s has waited %d minutes for instance %s to end' %
- (self.__class__.__name__, self.slavename, duration//60,
- instance.id))
- try:
- inst = os_client.servers.get(instance.id)
- except nce.NotFound:
- break
- log.msg('%s %s instance %s %s '
- 'after about %d minutes %d seconds' %
- (self.__class__.__name__, self.slavename,
- instance.id, goal, duration//60, duration%60))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py
deleted file mode 100644
index 496f5787..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.application import service
-from twisted.internet import defer, task, reactor
-from twisted.python import log
-
-from buildbot.interfaces import IChangeSource
-from buildbot import util
-
-class ChangeSource(service.Service, util.ComparableMixin):
- implements(IChangeSource)
-
- master = None
- "if C{self.running} is true, then C{cs.master} points to the buildmaster."
-
- def describe(self):
- pass
-
-class PollingChangeSource(ChangeSource):
- """
- Utility subclass for ChangeSources that use some kind of periodic polling
- operation. Subclasses should define C{poll} and set C{self.pollInterval}.
- The rest is taken care of.
-
- Any subclass will be available via the "poller" webhook.
- """
-
- pollInterval = 60
- "time (in seconds) between calls to C{poll}"
-
- _loop = None
-
- def __init__(self, name=None, pollInterval=60*10):
- if name:
- self.setName(name)
- self.pollInterval = pollInterval
-
- self.doPoll = util.misc.SerializedInvocation(self.doPoll)
-
- def doPoll(self):
- """
- This is the method that is called by LoopingCall to actually poll.
- It may also be called by change hooks to request a poll.
- It is serialiazed - if you call it while a poll is in progress
- then the 2nd invocation won't start until the 1st has finished.
- """
- d = defer.maybeDeferred(self.poll)
- d.addErrback(log.err, 'while polling for changes')
- return d
-
- def poll(self):
- """
- Perform the polling operation, and return a deferred that will fire
- when the operation is complete. Failures will be logged, but the
- method will be called again after C{pollInterval} seconds.
- """
-
- def startLoop(self):
- self._loop = task.LoopingCall(self.doPoll)
- self._loop.start(self.pollInterval, now=False)
-
- def stopLoop(self):
- if self._loop and self._loop.running:
- self._loop.stop()
- self._loop = None
-
- def startService(self):
- ChangeSource.startService(self)
-
- # delay starting doing anything until the reactor is running - if
- # services are still starting up, they may miss an initial flood of
- # changes
- if self.pollInterval:
- reactor.callWhenRunning(self.startLoop)
- else:
- reactor.callWhenRunning(self.doPoll)
-
- def stopService(self):
- self.stopLoop()
- return ChangeSource.stopService(self)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py
deleted file mode 100644
index 76afcaa4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-from xml.dom import minidom
-
-from twisted.python import log
-from twisted.internet import defer
-from twisted.web import client
-
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-
-class InvalidResultError(Exception):
- def __init__(self, value="InvalidResultError"):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-class EmptyResult(Exception):
- pass
-
-class NoMoreCiNodes(Exception):
- pass
-
-class NoMoreFileNodes(Exception):
- pass
-
-class BonsaiResult:
- """I hold a list of CiNodes"""
- def __init__(self, nodes=[]):
- self.nodes = nodes
-
- def __cmp__(self, other):
- if len(self.nodes) != len(other.nodes):
- return False
- for i in range(len(self.nodes)):
- if self.nodes[i].log != other.nodes[i].log \
- or self.nodes[i].who != other.nodes[i].who \
- or self.nodes[i].date != other.nodes[i].date \
- or len(self.nodes[i].files) != len(other.nodes[i].files):
- return -1
-
- for j in range(len(self.nodes[i].files)):
- if self.nodes[i].files[j].revision \
- != other.nodes[i].files[j].revision \
- or self.nodes[i].files[j].filename \
- != other.nodes[i].files[j].filename:
- return -1
-
- return 0
-
-class CiNode:
- """I hold information baout one <ci> node, including a list of files"""
- def __init__(self, log="", who="", date=0, files=[]):
- self.log = log
- self.who = who
- self.date = date
- self.files = files
-
-class FileNode:
- """I hold information about one <f> node"""
- def __init__(self, revision="", filename=""):
- self.revision = revision
- self.filename = filename
-
-class BonsaiParser:
- """I parse the XML result from a bonsai cvsquery."""
-
- def __init__(self, data):
- try:
- # this is a fix for non-ascii characters
- # because bonsai does not give us an encoding to work with
- # it impossible to be 100% sure what to decode it as but latin1 covers
- # the broadest base
- data = data.decode("latin1")
- data = data.encode("ascii", "replace")
- self.dom = minidom.parseString(data)
- log.msg(data)
- except:
- raise InvalidResultError("Malformed XML in result")
-
- self.ciNodes = self.dom.getElementsByTagName("ci")
- self.currentCiNode = None # filled in by _nextCiNode()
- self.fileNodes = None # filled in by _nextCiNode()
- self.currentFileNode = None # filled in by _nextFileNode()
- self.bonsaiResult = self._parseData()
-
- def getData(self):
- return self.bonsaiResult
-
- def _parseData(self):
- """Returns data from a Bonsai cvsquery in a BonsaiResult object"""
- nodes = []
- try:
- while self._nextCiNode():
- files = []
- try:
- while self._nextFileNode():
- files.append(FileNode(self._getRevision(),
- self._getFilename()))
- except NoMoreFileNodes:
- pass
- except InvalidResultError:
- raise
- cinode = CiNode(self._getLog(), self._getWho(),
- self._getDate(), files)
- # hack around bonsai xml output bug for empty check-in comments
- if not cinode.log and nodes and \
- not nodes[-1].log and \
- cinode.who == nodes[-1].who and \
- cinode.date == nodes[-1].date:
- nodes[-1].files += cinode.files
- else:
- nodes.append(cinode)
-
- except NoMoreCiNodes:
- pass
- except (InvalidResultError, EmptyResult):
- raise
-
- return BonsaiResult(nodes)
-
-
- def _nextCiNode(self):
- """Iterates to the next <ci> node and fills self.fileNodes with
- child <f> nodes"""
- try:
- self.currentCiNode = self.ciNodes.pop(0)
- if len(self.currentCiNode.getElementsByTagName("files")) > 1:
- raise InvalidResultError("Multiple <files> for one <ci>")
-
- self.fileNodes = self.currentCiNode.getElementsByTagName("f")
- except IndexError:
- # if there was zero <ci> nodes in the result
- if not self.currentCiNode:
- raise EmptyResult
- else:
- raise NoMoreCiNodes
-
- return True
-
- def _nextFileNode(self):
- """Iterates to the next <f> node"""
- try:
- self.currentFileNode = self.fileNodes.pop(0)
- except IndexError:
- raise NoMoreFileNodes
-
- return True
-
- def _getLog(self):
- """Returns the log of the current <ci> node"""
- logs = self.currentCiNode.getElementsByTagName("log")
- if len(logs) < 1:
- raise InvalidResultError("No log present")
- elif len(logs) > 1:
- raise InvalidResultError("Multiple logs present")
-
- # catch empty check-in comments
- if logs[0].firstChild:
- return logs[0].firstChild.data
- return ''
-
- def _getWho(self):
- """Returns the e-mail address of the commiter"""
- # convert unicode string to regular string
- return str(self.currentCiNode.getAttribute("who"))
-
- def _getDate(self):
- """Returns the date (unix time) of the commit"""
- # convert unicode number to regular one
- try:
- commitDate = int(self.currentCiNode.getAttribute("date"))
- except ValueError:
- raise InvalidResultError
-
- return commitDate
-
- def _getFilename(self):
- """Returns the filename of the current <f> node"""
- try:
- filename = self.currentFileNode.firstChild.data
- except AttributeError:
- raise InvalidResultError("Missing filename")
-
- return filename
-
- def _getRevision(self):
- return self.currentFileNode.getAttribute("rev")
-
-
-class BonsaiPoller(base.PollingChangeSource):
- compare_attrs = ["bonsaiURL", "pollInterval", "tree",
- "module", "branch", "cvsroot"]
-
- def __init__(self, bonsaiURL, module, branch, tree="default",
- cvsroot="/cvsroot", pollInterval=30, project=''):
-
- base.PollingChangeSource.__init__(self, name=bonsaiURL, pollInterval=pollInterval)
-
- self.bonsaiURL = bonsaiURL
- self.module = module
- self.branch = branch
- self.tree = tree
- self.cvsroot = cvsroot
- self.repository = module != 'all' and module or ''
- self.lastChange = time.time()
- self.lastPoll = time.time()
-
- def describe(self):
- str = ""
- str += "Getting changes from the Bonsai service running at %s " \
- % self.bonsaiURL
- str += "<br>Using tree: %s, branch: %s, and module: %s" % (self.tree, \
- self.branch, self.module)
- return str
-
- def poll(self):
- d = self._get_changes()
- d.addCallback(self._process_changes)
- return d
-
- def _make_url(self):
- args = ["treeid=%s" % self.tree, "module=%s" % self.module,
- "branch=%s" % self.branch, "branchtype=match",
- "sortby=Date", "date=explicit",
- "mindate=%d" % self.lastChange,
- "maxdate=%d" % int(time.time()),
- "cvsroot=%s" % self.cvsroot, "xml=1"]
- # build the bonsai URL
- url = self.bonsaiURL
- url += "/cvsquery.cgi?"
- url += "&".join(args)
-
- return url
-
- def _get_changes(self):
- url = self._make_url()
- log.msg("Polling Bonsai tree at %s" % url)
-
- self.lastPoll = time.time()
- # get the page, in XML format
- return client.getPage(url, timeout=self.pollInterval)
-
- @defer.inlineCallbacks
- def _process_changes(self, query):
- try:
- bp = BonsaiParser(query)
- result = bp.getData()
- except InvalidResultError, e:
- log.msg("Could not process Bonsai query: " + e.value)
- return
- except EmptyResult:
- return
-
- for cinode in result.nodes:
- files = [file.filename + ' (revision '+file.revision+')'
- for file in cinode.files]
- self.lastChange = self.lastPoll
- yield self.master.addChange(author = cinode.who,
- files = files,
- comments = cinode.log,
- when_timestamp = epoch2datetime(cinode.date),
- branch = self.branch)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py
deleted file mode 100644
index 1bf9d51f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py
+++ /dev/null
@@ -1,289 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os, time
-from cPickle import dump
-
-from zope.interface import implements
-from twisted.python import log, runtime
-from twisted.internet import defer
-from twisted.web import html
-from buildbot.util import datetime2epoch
-
-from buildbot import interfaces, util
-from buildbot.process.properties import Properties
-
-class Change:
- """I represent a single change to the source tree. This may involve several
- files, but they are all changed by the same person, and there is a change
- comment for the group as a whole."""
-
- implements(interfaces.IStatusEvent)
-
- number = None
- branch = None
- category = None
- revision = None # used to create a source-stamp
- links = [] # links are gone, but upgrade code expects this attribute
-
- @classmethod
- def fromChdict(cls, master, chdict):
- """
- Class method to create a L{Change} from a dictionary as returned
- by L{ChangesConnectorComponent.getChange}.
-
- @param master: build master instance
- @param ssdict: change dictionary
-
- @returns: L{Change} via Deferred
- """
- cache = master.caches.get_cache("Changes", cls._make_ch)
- return cache.get(chdict['changeid'], chdict=chdict, master=master)
-
- @classmethod
- def _make_ch(cls, changeid, master, chdict):
- change = cls(None, None, None, _fromChdict=True)
- change.who = chdict['author']
- change.comments = chdict['comments']
- change.isdir = chdict['is_dir']
- change.revision = chdict['revision']
- change.branch = chdict['branch']
- change.category = chdict['category']
- change.revlink = chdict['revlink']
- change.repository = chdict['repository']
- change.codebase = chdict['codebase']
- change.project = chdict['project']
- change.number = chdict['changeid']
-
- when = chdict['when_timestamp']
- if when:
- when = datetime2epoch(when)
- change.when = when
-
- change.files = chdict['files'][:]
- change.files.sort()
-
- change.properties = Properties()
- for n, (v,s) in chdict['properties'].iteritems():
- change.properties.setProperty(n, v, s)
-
- return defer.succeed(change)
-
- def __init__(self, who, files, comments, isdir=0,
- revision=None, when=None, branch=None, category=None,
- revlink='', properties={}, repository='', codebase='',
- project='', _fromChdict=False):
- # skip all this madness if we're being built from the database
- if _fromChdict:
- return
-
- self.who = who
- self.comments = comments
- self.isdir = isdir
-
- def none_or_unicode(x):
- if x is None: return x
- return unicode(x)
-
- self.revision = none_or_unicode(revision)
- now = util.now()
- if when is None:
- self.when = now
- elif when > now:
- # this happens when the committing system has an incorrect clock, for example.
- # handle it gracefully
- log.msg("received a Change with when > now; assuming the change happened now")
- self.when = now
- else:
- self.when = when
- self.branch = none_or_unicode(branch)
- self.category = none_or_unicode(category)
- self.revlink = revlink
- self.properties = Properties()
- self.properties.update(properties, "Change")
- self.repository = repository
- self.codebase = codebase
- self.project = project
-
- # keep a sorted list of the files, for easier display
- self.files = (files or [])[:]
- self.files.sort()
-
- def __setstate__(self, dict):
- self.__dict__ = dict
- # Older Changes won't have a 'properties' attribute in them
- if not hasattr(self, 'properties'):
- self.properties = Properties()
- if not hasattr(self, 'revlink'):
- self.revlink = ""
-
- def __str__(self):
- return (u"Change(revision=%r, who=%r, branch=%r, comments=%r, " +
- u"when=%r, category=%r, project=%r, repository=%r, " +
- u"codebase=%r)") % (
- self.revision, self.who, self.branch, self.comments,
- self.when, self.category, self.project, self.repository,
- self.codebase)
-
- def __cmp__(self, other):
- return self.number - other.number
-
- def asText(self):
- data = ""
- data += self.getFileContents()
- if self.repository:
- data += "On: %s\n" % self.repository
- if self.project:
- data += "For: %s\n" % self.project
- data += "At: %s\n" % self.getTime()
- data += "Changed By: %s\n" % self.who
- data += "Comments: %s" % self.comments
- data += "Properties: \n%s\n\n" % self.getProperties()
- return data
-
- def asDict(self):
- '''returns a dictonary with suitable info for html/mail rendering'''
- result = {}
-
- files = [ dict(name=f) for f in self.files ]
- files.sort(cmp=lambda a, b: a['name'] < b['name'])
-
- # Constant
- result['number'] = self.number
- result['branch'] = self.branch
- result['category'] = self.category
- result['who'] = self.getShortAuthor()
- result['comments'] = self.comments
- result['revision'] = self.revision
- result['rev'] = self.revision
- result['when'] = self.when
- result['at'] = self.getTime()
- result['files'] = files
- result['revlink'] = getattr(self, 'revlink', None)
- result['properties'] = self.properties.asList()
- result['repository'] = getattr(self, 'repository', None)
- result['codebase'] = getattr(self, 'codebase', '')
- result['project'] = getattr(self, 'project', None)
- return result
-
- def getShortAuthor(self):
- return self.who
-
- def getTime(self):
- if not self.when:
- return "?"
- return time.strftime("%a %d %b %Y %H:%M:%S",
- time.localtime(self.when))
-
- def getTimes(self):
- return (self.when, None)
-
- def getText(self):
- return [html.escape(self.who)]
- def getLogs(self):
- return {}
-
- def getFileContents(self):
- data = ""
- if len(self.files) == 1:
- if self.isdir:
- data += "Directory: %s\n" % self.files[0]
- else:
- data += "File: %s\n" % self.files[0]
- else:
- data += "Files:\n"
- for f in self.files:
- data += " %s\n" % f
- return data
-
- def getProperties(self):
- data = ""
- for prop in self.properties.asList():
- data += " %s: %s" % (prop[0], prop[1])
- return data
-
-
-class ChangeMaster: # pragma: no cover
- # this is a stub, retained to allow the "buildbot upgrade-master" tool to
- # read old changes.pck pickle files and convert their contents into the
- # new database format. This is only instantiated by that tool, or by
- # test_db.py which tests that tool. The functionality that previously
- # lived here has been moved into buildbot.changes.manager.ChangeManager
-
- def __init__(self):
- self.changes = []
- # self.basedir must be filled in by the parent
- self.nextNumber = 1
-
- def saveYourself(self):
- filename = os.path.join(self.basedir, "changes.pck")
- tmpfilename = filename + ".tmp"
- try:
- with open(tmpfilename, "wb") as f:
- dump(self, f)
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(tmpfilename, filename)
- except Exception:
- log.msg("unable to save changes")
- log.err()
-
- # This method is used by contrib/fix_changes_pickle_encoding.py to recode all
- # bytestrings in an old changes.pck into unicode strings
- def recode_changes(self, old_encoding, quiet=False):
- """Processes the list of changes, with the change attributes re-encoded
- unicode objects"""
- nconvert = 0
- for c in self.changes:
- # give revision special handling, in case it is an integer
- if isinstance(c.revision, int):
- c.revision = unicode(c.revision)
-
- for attr in ("who", "comments", "revlink", "category", "branch", "revision"):
- a = getattr(c, attr)
- if isinstance(a, str):
- try:
- setattr(c, attr, a.decode(old_encoding))
- nconvert += 1
- except UnicodeDecodeError:
- raise UnicodeError("Error decoding %s of change #%s as %s:\n%r" %
- (attr, c.number, old_encoding, a))
-
- # filenames are a special case, but in general they'll have the same encoding
- # as everything else on a system. If not, well, hack this script to do your
- # import!
- newfiles = []
- for filename in util.flatten(c.files):
- if isinstance(filename, str):
- try:
- filename = filename.decode(old_encoding)
- nconvert += 1
- except UnicodeDecodeError:
- raise UnicodeError("Error decoding filename '%s' of change #%s as %s:\n%r" %
- (filename.decode('ascii', 'replace'),
- c.number, old_encoding, a))
- newfiles.append(filename)
- c.files = newfiles
- if not quiet:
- print "converted %d strings" % nconvert
-
-class OldChangeMaster(ChangeMaster): # pragma: no cover
- # this is a reminder that the ChangeMaster class is old
- pass
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py
deleted file mode 100644
index 30bdd83a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re, types
-
-from buildbot.util import ComparableMixin, NotABranch
-
-class ChangeFilter(ComparableMixin):
-
- # NOTE: If users use a filter_fn, we have no way to determine whether it has
- # changed at reconfig, so the scheduler will always be restarted. That's as
- # good as Python can do.
- compare_attrs = ('filter_fn', 'checks')
-
- def __init__(self,
- # gets a Change object, returns boolean
- filter_fn=None,
- # change attribute comparisons: exact match to PROJECT, member of
- # list PROJECTS, regular expression match to PROJECT_RE, or
- # PROJECT_FN returns True when called with the project; repository,
- # branch, and so on are similar. Note that the regular expressions
- # are anchored to the first character of the string. For convenience,
- # a list can also be specified to the singular option (e.g,. PROJETS
- project=None, project_re=None, project_fn=None,
- repository=None, repository_re=None, repository_fn=None,
- branch=NotABranch, branch_re=None, branch_fn=None,
- category=None, category_re=None, category_fn=None,
- codebase=None, codebase_re=None, codebase_fn=None):
- def mklist(x):
- if x is not None and type(x) is not types.ListType:
- return [ x ]
- return x
- def mklist_br(x): # branch needs to be handled specially
- if x is NotABranch:
- return None
- if type(x) is not types.ListType:
- return [ x ]
- return x
- def mkre(r):
- if r is not None and not hasattr(r, 'match'):
- r = re.compile(r)
- return r
-
- self.filter_fn = filter_fn
- self.checks = [
- (mklist(project), mkre(project_re), project_fn, "project"),
- (mklist(repository), mkre(repository_re), repository_fn, "repository"),
- (mklist_br(branch), mkre(branch_re), branch_fn, "branch"),
- (mklist(category), mkre(category_re), category_fn, "category"),
- (mklist(codebase), mkre(codebase_re), codebase_fn, "codebase"),
- ]
-
- def filter_change(self, change):
- if self.filter_fn is not None and not self.filter_fn(change):
- return False
- for (filt_list, filt_re, filt_fn, chg_attr) in self.checks:
- chg_val = getattr(change, chg_attr, '')
- if filt_list is not None and chg_val not in filt_list:
- return False
- if filt_re is not None and (chg_val is None or not filt_re.match(chg_val)):
- return False
- if filt_fn is not None and not filt_fn(chg_val):
- return False
- return True
-
- def __repr__(self):
- checks = []
- for (filt_list, filt_re, filt_fn, chg_attr) in self.checks:
- if filt_list is not None and len(filt_list) == 1:
- checks.append('%s == %s' % (chg_attr, filt_list[0]))
- elif filt_list is not None:
- checks.append('%s in %r' % (chg_attr, filt_list))
- if filt_re is not None :
- checks.append('%s ~/%s/' % (chg_attr, filt_re))
- if filt_fn is not None :
- checks.append('%s(%s)' % (filt_fn.__name__, chg_attr))
-
- return "<%s on %s>" % (self.__class__.__name__, ' and '.join(checks))
-
- @staticmethod
- def fromSchedulerConstructorArgs(change_filter=None,
- branch=NotABranch, categories=None):
-
- """
- Static method to create a filter based on constructor args
- change_filter, branch, and categories; use default values @code{None},
- @code{NotABranch}, and @code{None}, respectively. These arguments are
- interpreted as documented for the
- L{buildbot.schedulers.basic.Scheduler} class.
-
- @returns: L{ChangeFilter} instance or None for not filtering
- """
-
- # use a change_filter, if given one
- if change_filter:
- if (branch is not NotABranch or categories is not None):
- raise RuntimeError("cannot specify both change_filter and "
- "branch or categories")
- return change_filter
- elif branch is not NotABranch or categories:
- # build a change filter from the deprecated category and branch args
- cfargs = {}
- if branch is not NotABranch: cfargs['branch'] = branch
- if categories: cfargs['category'] = categories
- return ChangeFilter(**cfargs)
- else:
- return None
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py
deleted file mode 100644
index 62bf6a88..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import reactor
-
-from buildbot.changes import base
-from buildbot.util import json
-from buildbot import util
-from twisted.python import log
-from twisted.internet import defer
-from twisted.internet.protocol import ProcessProtocol
-
-class GerritChangeSource(base.ChangeSource):
- """This source will maintain a connection to gerrit ssh server
- that will provide us gerrit events in json format."""
-
- compare_attrs = ["gerritserver", "gerritport"]
-
- STREAM_GOOD_CONNECTION_TIME = 120
- "(seconds) connections longer than this are considered good, and reset the backoff timer"
-
- STREAM_BACKOFF_MIN = 0.5
- "(seconds) minimum, but nonzero, time to wait before retrying a failed connection"
-
- STREAM_BACKOFF_EXPONENT = 1.5
- "multiplier used to increase the backoff from MIN to MAX on repeated failures"
-
- STREAM_BACKOFF_MAX = 60
- "(seconds) maximum time to wait before retrying a failed connection"
-
- def __init__(self, gerritserver, username, gerritport=29418, identity_file=None):
- """
- @type gerritserver: string
- @param gerritserver: the dns or ip that host the gerrit ssh server,
-
- @type gerritport: int
- @param gerritport: the port of the gerrit ssh server,
-
- @type username: string
- @param username: the username to use to connect to gerrit,
-
- @type identity_file: string
- @param identity_file: identity file to for authentication (optional).
-
- """
- # TODO: delete API comment when documented
-
- self.gerritserver = gerritserver
- self.gerritport = gerritport
- self.username = username
- self.identity_file = identity_file
- self.process = None
- self.wantProcess = False
- self.streamProcessTimeout = self.STREAM_BACKOFF_MIN
-
- class LocalPP(ProcessProtocol):
- def __init__(self, change_source):
- self.change_source = change_source
- self.data = ""
-
- @defer.inlineCallbacks
- def outReceived(self, data):
- """Do line buffering."""
- self.data += data
- lines = self.data.split("\n")
- self.data = lines.pop(-1) # last line is either empty or incomplete
- for line in lines:
- log.msg("gerrit: %s" % (line,))
- yield self.change_source.lineReceived(line)
-
- def errReceived(self, data):
- log.msg("gerrit stderr: %s" % (data,))
-
- def processEnded(self, status_object):
- self.change_source.streamProcessStopped()
-
- def lineReceived(self, line):
- try:
- event = json.loads(line.decode('utf-8'))
- except ValueError:
- log.msg("bad json line: %s" % (line,))
- return defer.succeed(None)
-
- if not(type(event) == type({}) and "type" in event):
- log.msg("no type in event %s" % (line,))
- return defer.succeed(None)
- func = getattr(self, "eventReceived_"+event["type"].replace("-","_"), None)
- if func == None:
- log.msg("unsupported event %s" % (event["type"],))
- return defer.succeed(None)
-
- # flatten the event dictionary, for easy access with WithProperties
- def flatten(properties, base, event):
- for k, v in event.items():
- if type(v) == dict:
- flatten(properties, base + "." + k, v)
- else: # already there
- properties[base + "." + k] = v
-
- properties = {}
- flatten(properties, "event", event)
- return func(properties,event)
- def addChange(self, chdict):
- d = self.master.addChange(**chdict)
- # eat failures..
- d.addErrback(log.err, 'error adding change from GerritChangeSource')
- return d
- def eventReceived_patchset_created(self, properties, event):
- change = event["change"]
- return self.addChange(dict(
- author="%s <%s>" % (change["owner"]["name"], change["owner"]["email"]),
- project=change["project"],
- repository="ssh://%s@%s:%s/%s" % (
- self.username, self.gerritserver, self.gerritport, change["project"]),
- branch=change["branch"]+"/"+change["number"],
- revision=event["patchSet"]["revision"],
- revlink=change["url"],
- comments=change["subject"],
- files=["unknown"],
- category=event["type"],
- properties=properties))
- def eventReceived_ref_updated(self, properties, event):
- ref = event["refUpdate"]
- author = "gerrit"
-
- if "submitter" in event:
- author="%s <%s>" % (event["submitter"]["name"], event["submitter"]["email"])
-
- return self.addChange(dict(
- author=author,
- project=ref["project"],
- repository="ssh://%s@%s:%s/%s" % (
- self.username, self.gerritserver, self.gerritport, ref["project"]),
- branch=ref["refName"],
- revision=ref["newRev"],
- comments="Gerrit: patchset(s) merged.",
- files=["unknown"],
- category=event["type"],
- properties=properties))
-
- def streamProcessStopped(self):
- self.process = None
-
- # if the service is stopped, don't try to restart the process
- if not self.wantProcess:
- log.msg("service is not running; not reconnecting")
- return
-
- now = util.now()
- if now - self.lastStreamProcessStart < self.STREAM_GOOD_CONNECTION_TIME:
- # bad startup; start the stream process again after a timeout, and then
- # increase the timeout
- log.msg("'gerrit stream-events' failed; restarting after %ds" % round(self.streamProcessTimeout))
- reactor.callLater(self.streamProcessTimeout, self.startStreamProcess)
- self.streamProcessTimeout *= self.STREAM_BACKOFF_EXPONENT
- if self.streamProcessTimeout > self.STREAM_BACKOFF_MAX:
- self.streamProcessTimeout = self.STREAM_BACKOFF_MAX
- else:
- # good startup, but lost connection; restart immediately, and set the timeout
- # to its minimum
- self.startStreamProcess()
- self.streamProcessTimeout = self.STREAM_BACKOFF_MIN
-
- def startStreamProcess(self):
- log.msg("starting 'gerrit stream-events'")
- self.lastStreamProcessStart = util.now()
- args = [ self.username+"@"+self.gerritserver,"-p", str(self.gerritport)]
- if self.identity_file is not None:
- args = args + [ '-i', self.identity_file ]
- self.process = reactor.spawnProcess(self.LocalPP(self), "ssh",
- [ "ssh" ] + args + [ "gerrit", "stream-events" ])
-
- def startService(self):
- self.wantProcess = True
- self.startStreamProcess()
-
- def stopService(self):
- self.wantProcess = False
- if self.process:
- self.process.signalProcess("KILL")
- # TODO: if this occurs while the process is restarting, some exceptions may
- # be logged, although things will settle down normally
- return base.ChangeSource.stopService(self)
-
- def describe(self):
- status = ""
- if not self.process:
- status = "[NOT CONNECTED - check log]"
- str = ('GerritChangeSource watching the remote Gerrit repository %s@%s %s' %
- (self.username, self.gerritserver, status))
- return str
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py
deleted file mode 100644
index 120253af..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import urllib
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-from buildbot.util.state import StateMixin
-from buildbot import config
-
-class GitPoller(base.PollingChangeSource, StateMixin):
- """This source will poll a remote git repo for changes and submit
- them to the change master."""
-
- compare_attrs = ["repourl", "branches", "workdir",
- "pollInterval", "gitbin", "usetimestamps",
- "category", "project"]
-
- def __init__(self, repourl, branches=None, branch=None,
- workdir=None, pollInterval=10*60,
- gitbin='git', usetimestamps=True,
- category=None, project=None,
- pollinterval=-2, fetch_refspec=None,
- encoding='utf-8'):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- base.PollingChangeSource.__init__(self, name=repourl,
- pollInterval=pollInterval)
-
- if project is None: project = ''
-
- if branch and branches:
- config.error("GitPoller: can't specify both branch and branches")
- elif branch:
- branches = [branch]
- elif not branches:
- branches = ['master']
-
- self.repourl = repourl
- self.branches = branches
- self.encoding = encoding
- self.gitbin = gitbin
- self.workdir = workdir
- self.usetimestamps = usetimestamps
- self.category = category
- self.project = project
- self.changeCount = 0
- self.lastRev = {}
-
- if fetch_refspec is not None:
- config.error("GitPoller: fetch_refspec is no longer supported. "
- "Instead, only the given branches are downloaded.")
-
- if self.workdir == None:
- self.workdir = 'gitpoller-work'
-
- def startService(self):
- # make our workdir absolute, relative to the master's basedir
- if not os.path.isabs(self.workdir):
- self.workdir = os.path.join(self.master.basedir, self.workdir)
- log.msg("gitpoller: using workdir '%s'" % self.workdir)
-
- d = self.getState('lastRev', {})
- def setLastRev(lastRev):
- self.lastRev = lastRev
- d.addCallback(setLastRev)
-
- d.addCallback(lambda _:
- base.PollingChangeSource.startService(self))
- d.addErrback(log.err, 'while initializing GitPoller repository')
-
- return d
-
- def describe(self):
- status = ""
- if not self.master:
- status = "[STOPPED - check log]"
- str = ('GitPoller watching the remote git repository %s, branches: %s %s'
- % (self.repourl, ', '.join(self.branches), status))
- return str
-
- @defer.inlineCallbacks
- def poll(self):
- yield self._dovccmd('init', ['--bare', self.workdir])
-
- refspecs = [
- '+%s:%s'% (branch, self._localBranch(branch))
- for branch in self.branches
- ]
- yield self._dovccmd('fetch',
- [self.repourl] + refspecs, path=self.workdir)
-
- revs = {}
- for branch in self.branches:
- try:
- revs[branch] = rev = yield self._dovccmd('rev-parse',
- [self._localBranch(branch)], path=self.workdir)
- yield self._process_changes(rev, branch)
- except:
- log.err(_why="trying to poll branch %s of %s"
- % (branch, self.repourl))
-
- self.lastRev.update(revs)
- yield self.setState('lastRev', self.lastRev)
-
- def _get_commit_comments(self, rev):
- args = ['--no-walk', r'--format=%s%n%b', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- git_output = git_output.decode(self.encoding)
- if len(git_output) == 0:
- raise EnvironmentError('could not get commit comment for rev')
- return git_output
- d.addCallback(process)
- return d
-
- def _get_commit_timestamp(self, rev):
- # unix timestamp
- args = ['--no-walk', r'--format=%ct', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- if self.usetimestamps:
- try:
- stamp = float(git_output)
- except Exception, e:
- log.msg('gitpoller: caught exception converting output \'%s\' to timestamp' % git_output)
- raise e
- return stamp
- else:
- return None
- d.addCallback(process)
- return d
-
- def _get_commit_files(self, rev):
- args = ['--name-only', '--no-walk', r'--format=%n', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- fileList = git_output.split()
- return fileList
- d.addCallback(process)
- return d
-
- def _get_commit_author(self, rev):
- args = ['--no-walk', r'--format=%aN <%aE>', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- git_output = git_output.decode(self.encoding)
- if len(git_output) == 0:
- raise EnvironmentError('could not get commit author for rev')
- return git_output
- d.addCallback(process)
- return d
-
- @defer.inlineCallbacks
- def _process_changes(self, newRev, branch):
- """
- Read changes since last change.
-
- - Read list of commit hashes.
- - Extract details from each commit.
- - Add changes to database.
- """
-
- lastRev = self.lastRev.get(branch)
- self.lastRev[branch] = newRev
- if not lastRev:
- return
-
- # get the change list
- revListArgs = [r'--format=%H', '%s..%s' % (lastRev, newRev), '--']
- self.changeCount = 0
- results = yield self._dovccmd('log', revListArgs, path=self.workdir)
-
-
- # process oldest change first
- revList = results.split()
- revList.reverse()
- self.changeCount = len(revList)
-
- log.msg('gitpoller: processing %d changes: %s from "%s"'
- % (self.changeCount, revList, self.repourl) )
-
- for rev in revList:
- dl = defer.DeferredList([
- self._get_commit_timestamp(rev),
- self._get_commit_author(rev),
- self._get_commit_files(rev),
- self._get_commit_comments(rev),
- ], consumeErrors=True)
-
- results = yield dl
-
- # check for failures
- failures = [ r[1] for r in results if not r[0] ]
- if failures:
- # just fail on the first error; they're probably all related!
- raise failures[0]
-
- timestamp, author, files, comments = [ r[1] for r in results ]
- yield self.master.addChange(
- author=author,
- revision=rev,
- files=files,
- comments=comments,
- when_timestamp=epoch2datetime(timestamp),
- branch=branch,
- category=self.category,
- project=self.project,
- repository=self.repourl,
- src='git')
-
- def _dovccmd(self, command, args, path=None):
- d = utils.getProcessOutputAndValue(self.gitbin,
- [command] + args, path=path, env=os.environ)
- def _convert_nonzero_to_failure(res):
- "utility to handle the result of getProcessOutputAndValue"
- (stdout, stderr, code) = res
- if code != 0:
- raise EnvironmentError('command failed with exit code %d: %s'
- % (code, stderr))
- return stdout.strip()
- d.addCallback(_convert_nonzero_to_failure)
- return d
-
- def _localBranch(self, branch):
- return "refs/buildbot/%s/%s" % (urllib.quote(self.repourl, ''), branch)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py
deleted file mode 100644
index b01a13ca..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2007 Frederic Leroy <fredo@starox.org>
-
-# hook extension to send change notifications to buildbot when a changeset is
-# brought into the repository from elsewhere.
-#
-# See the Buildbot manual for configuration instructions.
-
-import os
-
-from mercurial.node import bin, hex, nullid #@UnresolvedImport
-
-# mercurial's on-demand-importing hacks interfere with the:
-#from zope.interface import Interface
-# that Twisted needs to do, so disable it.
-try:
- from mercurial import demandimport
- demandimport.disable()
-except ImportError:
- pass
-
-# In Mercurial post-1.7, some strings might be stored as a
-# encoding.localstr class. encoding.fromlocal will translate
-# those back to UTF-8 strings.
-try:
- from mercurial.encoding import fromlocal
- _hush_pyflakes = [fromlocal]
- del _hush_pyflakes
-except ImportError:
- def fromlocal(s):
- return s
-
-def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
- # read config parameters
- baseurl = ui.config('hgbuildbot', 'baseurl',
- ui.config('web', 'baseurl', ''))
- masters = ui.configlist('hgbuildbot', 'master')
- if masters:
- branchtype = ui.config('hgbuildbot', 'branchtype', 'inrepo')
- branch = ui.config('hgbuildbot', 'branch')
- fork = ui.configbool('hgbuildbot', 'fork', False)
- # notify also has this setting
- stripcount = int(ui.config('notify','strip') or ui.config('hgbuildbot','strip',3))
- category = ui.config('hgbuildbot', 'category', None)
- project = ui.config('hgbuildbot', 'project', '')
- auth = ui.config('hgbuildbot', 'auth', None)
- else:
- ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in "
- "order to use buildbot hook\n")
- return
-
- if hooktype != "changegroup":
- ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype)
- return
-
- if fork:
- child_pid = os.fork()
- if child_pid == 0:
- #child
- pass
- else:
- #parent
- ui.status("Notifying buildbot...\n")
- return
-
- # only import inside the fork if forked
- from buildbot.clients import sendchange
- from twisted.internet import defer, reactor
-
- if branch is None:
- if branchtype == 'dirname':
- branch = os.path.basename(repo.root)
-
- if not auth:
- auth = 'change:changepw'
- auth = auth.split(':', 1)
-
- # process changesets
- def _send(res, s, c):
- if not fork:
- ui.status("rev %s sent\n" % c['revision'])
- return s.send(c['branch'], c['revision'], c['comments'],
- c['files'], c['username'], category=category,
- repository=repository, project=project, vc='hg',
- properties=c['properties'])
-
- try: # first try Mercurial 1.1+ api
- start = repo[node].rev()
- end = len(repo)
- except TypeError: # else fall back to old api
- start = repo.changelog.rev(bin(node))
- end = repo.changelog.count()
-
- repository = strip(repo.root, stripcount)
- repository = baseurl + repository
-
- for master in masters:
- s = sendchange.Sender(master, auth=auth)
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
-
- for rev in xrange(start, end):
- # send changeset
- node = repo.changelog.node(rev)
- manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node)
- parents = filter(lambda p: not p == nullid, repo.changelog.parents(node))
- if branchtype == 'inrepo':
- branch = extra['branch']
- is_merge = len(parents) > 1
- # merges don't always contain files, but at least one file is required by buildbot
- if is_merge and not files:
- files = ["merge"]
- properties = {'is_merge': is_merge}
- if branch:
- branch = fromlocal(branch)
- change = {
- 'master': master,
- 'username': fromlocal(user),
- 'revision': hex(node),
- 'comments': fromlocal(desc),
- 'files': files,
- 'branch': branch,
- 'properties':properties
- }
- d.addCallback(_send, s, change)
-
- def _printSuccess(res):
- ui.status(s.getSuccessString(res) + '\n')
-
- def _printFailure(why):
- ui.warn(s.getFailureString(why) + '\n')
-
- d.addCallbacks(_printSuccess, _printFailure)
- d.addBoth(lambda _ : reactor.stop())
- reactor.run()
-
- if fork:
- os._exit(os.EX_OK)
- else:
- return
-
-# taken from the mercurial notify extension
-def strip(path, count):
- '''Strip the count first slash of the path'''
-
- # First normalize it
- path = '/'.join(path.split(os.sep))
- # and strip it part after part
- while count > 0:
- c = path.find('/')
- if c == -1:
- break
- path = path[c + 1:]
- count -= 1
- return path
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py
deleted file mode 100644
index 373ce735..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py
+++ /dev/null
@@ -1,305 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-import os
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot import config
-from buildbot.util import deferredLocked
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-
-class HgPoller(base.PollingChangeSource):
- """This source will poll a remote hg repo for changes and submit
- them to the change master."""
-
- compare_attrs = ["repourl", "branch", "workdir",
- "pollInterval", "hgpoller", "usetimestamps",
- "category", "project"]
-
- db_class_name = 'HgPoller'
-
- def __init__(self, repourl, branch='default',
- workdir=None, pollInterval=10*60,
- hgbin='hg', usetimestamps=True,
- category=None, project='', pollinterval=-2,
- encoding='utf-8'):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- self.repourl = repourl
- self.branch = branch
- base.PollingChangeSource.__init__(
- self, name=repourl, pollInterval=pollInterval)
- self.encoding = encoding
- self.lastChange = time.time()
- self.lastPoll = time.time()
- self.hgbin = hgbin
- self.workdir = workdir
- self.usetimestamps = usetimestamps
- self.category = category
- self.project = project
- self.commitInfo = {}
- self.initLock = defer.DeferredLock()
-
- if self.workdir == None:
- config.error("workdir is mandatory for now in HgPoller")
-
- def describe(self):
- status = ""
- if not self.master:
- status = "[STOPPED - check log]"
- return ("HgPoller watching the remote Mercurial repository %r, "
- "branch: %r, in workdir %r %s") % (self.repourl, self.branch,
- self.workdir, status)
-
- @deferredLocked('initLock')
- def poll(self):
- d = self._getChanges()
- d.addCallback(self._processChanges)
- d.addErrback(self._processChangesFailure)
- return d
-
- def _absWorkdir(self):
- workdir = self.workdir
- if os.path.isabs(workdir):
- return workdir
- return os.path.join(self.master.basedir, workdir)
-
- def _getRevDetails(self, rev):
- """Return a deferred for (date, author, files, comments) of given rev.
-
- Deferred will be in error if rev is unknown.
- """
- args = ['log', '-r', rev, os.linesep.join((
- '--template={date|hgdate}',
- '{author}',
- '{files}',
- '{desc|strip}'))]
- # Mercurial fails with status 255 if rev is unknown
- d = utils.getProcessOutput(self.hgbin, args, path=self._absWorkdir(),
- env=os.environ, errortoo=False )
- def process(output):
- # fortunately, Mercurial issues all filenames one one line
- date, author, files, comments = output.decode(self.encoding, "replace").split(
- os.linesep, 3)
-
- if not self.usetimestamps:
- stamp = None
- else:
- try:
- stamp = float(date.split()[0])
- except:
- log.msg('hgpoller: caught exception converting output %r '
- 'to timestamp' % date)
- raise
- return stamp, author.strip(), files.split(), comments.strip()
-
- d.addCallback(process)
- return d
-
- def _isRepositoryReady(self):
- """Easy to patch in tests."""
- return os.path.exists(os.path.join(self._absWorkdir(), '.hg'))
-
- def _initRepository(self):
- """Have mercurial init the workdir as a repository (hg init) if needed.
-
- hg init will also create all needed intermediate directories.
- """
- if self._isRepositoryReady():
- return defer.succeed(None)
- log.msg('hgpoller: initializing working dir from %s' % self.repourl)
- d = utils.getProcessOutputAndValue(self.hgbin,
- ['init', self._absWorkdir()],
- env=os.environ)
- d.addCallback(self._convertNonZeroToFailure)
- d.addErrback(self._stopOnFailure)
- d.addCallback(lambda _ : log.msg(
- "hgpoller: finished initializing working dir %r" % self.workdir))
- return d
-
- def _getChanges(self):
- self.lastPoll = time.time()
-
- d = self._initRepository()
- d.addCallback(lambda _ : log.msg(
- "hgpoller: polling hg repo at %s" % self.repourl))
-
- # get a deferred object that performs the fetch
- args = ['pull', '-b', self.branch, self.repourl]
-
- # This command always produces data on stderr, but we actually do not
- # care about the stderr or stdout from this command.
- # We set errortoo=True to avoid an errback from the deferred.
- # The callback which will be added to this
- # deferred will not use the response.
- d.addCallback(lambda _: utils.getProcessOutput(
- self.hgbin, args, path=self._absWorkdir(),
- env=os.environ, errortoo=True))
-
- return d
-
- def _getStateObjectId(self):
- """Return a deferred for object id in state db.
-
- Being unique among pollers, workdir is used with branch as instance
- name for db.
- """
- return self.master.db.state.getObjectId(
- '#'.join((self.workdir, self.branch)), self.db_class_name)
-
- def _getCurrentRev(self):
- """Return a deferred for object id in state db and current numeric rev.
-
- If never has been set, current rev is None.
- """
- d = self._getStateObjectId()
- def oid_cb(oid):
- d = self.master.db.state.getState(oid, 'current_rev', None)
- def addOid(cur):
- if cur is not None:
- return oid, int(cur)
- return oid, cur
- d.addCallback(addOid)
- return d
- d.addCallback(oid_cb)
- return d
-
- def _setCurrentRev(self, rev, oid=None):
- """Return a deferred to set current revision in persistent state.
-
- oid is self's id for state db. It can be passed to avoid a db lookup."""
- if oid is None:
- d = self._getStateObjectId()
- else:
- d = defer.succeed(oid)
-
- def set_in_state(obj_id):
- return self.master.db.state.setState(obj_id, 'current_rev', rev)
- d.addCallback(set_in_state)
-
- return d
-
- def _getHead(self):
- """Return a deferred for branch head revision or None.
-
- We'll get an error if there is no head for this branch, which is
- proabably a good thing, since it's probably a mispelling
- (if really buildbotting a branch that does not have any changeset
- yet, one shouldn't be surprised to get errors)
- """
- d = utils.getProcessOutput(self.hgbin,
- ['heads', self.branch, '--template={rev}' + os.linesep],
- path=self._absWorkdir(), env=os.environ, errortoo=False)
-
- def no_head_err(exc):
- log.err("hgpoller: could not find branch %r in repository %r" % (
- self.branch, self.repourl))
- d.addErrback(no_head_err)
-
- def results(heads):
- if not heads:
- return
-
- if len(heads.split()) > 1:
- log.err(("hgpoller: caught several heads in branch %r "
- "from repository %r. Staying at previous revision"
- "You should wait until the situation is normal again "
- "due to a merge or directly strip if remote repo "
- "gets stripped later.") % (self.branch, self.repourl))
- return
-
- # in case of whole reconstruction, are we sure that we'll get the
- # same node -> rev assignations ?
- return int(heads.strip())
-
- d.addCallback(results)
- return d
-
- @defer.inlineCallbacks
- def _processChanges(self, unused_output):
- """Send info about pulled changes to the master and record current.
-
- GitPoller does the recording by moving the working dir to the head
- of the branch.
- We don't update the tree (unnecessary treatment and waste of space)
- instead, we simply store the current rev number in a file.
- Recall that hg rev numbers are local and incremental.
- """
- oid, current = yield self._getCurrentRev()
- # hg log on a range of revisions is never empty
- # also, if a numeric revision does not exist, a node may match.
- # Therefore, we have to check explicitely that branch head > current.
- head = yield self._getHead()
- if head <= current:
- return
- if current is None:
- # we could have used current = -1 convention as well (as hg does)
- revrange = '%d:%d' % (head, head)
- else:
- revrange = '%d:%s' % (current + 1, head)
-
- # two passes for hg log makes parsing simpler (comments is multi-lines)
- revListArgs = ['log', '-b', self.branch, '-r', revrange,
- r'--template={rev}:{node}\n']
- results = yield utils.getProcessOutput(self.hgbin, revListArgs,
- path=self._absWorkdir(), env=os.environ, errortoo=False )
-
- revNodeList = [rn.split(':', 1) for rn in results.strip().split()]
-
- log.msg('hgpoller: processing %d changes: %r in %r'
- % (len(revNodeList), revNodeList, self._absWorkdir()))
- for rev, node in revNodeList:
- timestamp, author, files, comments = yield self._getRevDetails(
- node)
- yield self.master.addChange(
- author=author,
- revision=node,
- files=files,
- comments=comments,
- when_timestamp=epoch2datetime(timestamp),
- branch=self.branch,
- category=self.category,
- project=self.project,
- repository=self.repourl,
- src='hg')
- # writing after addChange so that a rev is never missed,
- # but at once to avoid impact from later errors
- yield self._setCurrentRev(rev, oid=oid)
-
- def _processChangesFailure(self, f):
- log.msg('hgpoller: repo poll failed')
- log.err(f)
- # eat the failure to continue along the defered chain - we still want to catch up
- return None
-
- def _convertNonZeroToFailure(self, res):
- "utility method to handle the result of getProcessOutputAndValue"
- (stdout, stderr, code) = res
- if code != 0:
- raise EnvironmentError('command failed with exit code %d: %s' % (code, stderr))
- return (stdout, stderr, code)
-
- def _stopOnFailure(self, f):
- "utility method to stop the service when a failure occurs"
- if self.running:
- d = defer.maybeDeferred(lambda : self.stopService())
- d.addErrback(log.err, 'while stopping broken HgPoller service')
- return f
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py
deleted file mode 100644
index c8e0dd32..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py
+++ /dev/null
@@ -1,507 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-Parse various kinds of 'CVS notify' email.
-"""
-import re
-import time, calendar
-import datetime
-from email import message_from_file
-from email.Utils import parseaddr, parsedate_tz, mktime_tz
-from email.Iterators import body_line_iterator
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import util
-from buildbot.interfaces import IChangeSource
-from buildbot.util.maildir import MaildirService
-
-class MaildirSource(MaildirService, util.ComparableMixin):
- """Generic base class for Maildir-based change sources"""
- implements(IChangeSource)
-
- compare_attrs = ["basedir", "pollinterval", "prefix"]
-
- def __init__(self, maildir, prefix=None, category='', repository=''):
- MaildirService.__init__(self, maildir)
- self.prefix = prefix
- self.category = category
- self.repository = repository
- if prefix and not prefix.endswith("/"):
- log.msg("%s: you probably want your prefix=('%s') to end with "
- "a slash")
-
- def describe(self):
- return "%s watching maildir '%s'" % (self.__class__.__name__, self.basedir)
-
- def messageReceived(self, filename):
- d = defer.succeed(None)
- def parse_file(_):
- f = self.moveToCurDir(filename)
- return self.parse_file(f, self.prefix)
- d.addCallback(parse_file)
-
- def add_change(chtuple):
- src, chdict = None, None
- if chtuple:
- src, chdict = chtuple
- if chdict:
- return self.master.addChange(src=src, **chdict)
- else:
- log.msg("no change found in maildir file '%s'" % filename)
- d.addCallback(add_change)
-
- return d
-
- def parse_file(self, fd, prefix=None):
- m = message_from_file(fd)
- return self.parse(m, prefix)
-
-class CVSMaildirSource(MaildirSource):
- name = "CVSMaildirSource"
-
- def __init__(self, maildir, prefix=None, category='',
- repository='', properties={}):
- MaildirSource.__init__(self, maildir, prefix, category, repository)
- self.properties = properties
-
- def parse(self, m, prefix=None):
- """Parse messages sent by the 'buildbot-cvs-mail' program.
- """
- # The mail is sent from the person doing the checkin. Assume that the
- # local username is enough to identify them (this assumes a one-server
- # cvs-over-rsh environment rather than the server-dirs-shared-over-NFS
- # model)
- name, addr = parseaddr(m["from"])
- if not addr:
- return None # no From means this message isn't from buildbot-cvs-mail
- at = addr.find("@")
- if at == -1:
- author = addr # might still be useful
- else:
- author = addr[:at]
-
- # CVS accecpts RFC822 dates. buildbot-cvs-mail adds the date as
- # part of the mail header, so use that.
- # This assumes cvs is being access via ssh or pserver, so the time
- # will be the CVS server's time.
-
- # calculate a "revision" based on that timestamp, or the current time
- # if we're unable to parse the date.
- log.msg('Processing CVS mail')
- dateTuple = parsedate_tz(m["date"])
- if dateTuple == None:
- when = util.now()
- else:
- when = mktime_tz(dateTuple)
-
- theTime = datetime.datetime.utcfromtimestamp(float(when))
- rev = theTime.strftime('%Y-%m-%d %H:%M:%S')
-
- catRE = re.compile( '^Category:\s*(\S.*)')
- cvsRE = re.compile( '^CVSROOT:\s*(\S.*)')
- cvsmodeRE = re.compile( '^Cvsmode:\s*(\S.*)')
- filesRE = re.compile( '^Files:\s*(\S.*)')
- modRE = re.compile( '^Module:\s*(\S.*)')
- pathRE = re.compile( '^Path:\s*(\S.*)')
- projRE = re.compile( '^Project:\s*(\S.*)')
- singleFileRE = re.compile( '(.*) (NONE|\d(\.|\d)+) (NONE|\d(\.|\d)+)')
- tagRE = re.compile( '^\s+Tag:\s*(\S.*)')
- updateRE = re.compile( '^Update of:\s*(\S.*)')
- comments = ""
- branch = None
- cvsroot = None
- fileList = None
- files = []
- isdir = 0
- path = None
- project = None
-
- lines = list(body_line_iterator(m))
- while lines:
- line = lines.pop(0)
- m = catRE.match(line)
- if m:
- category = m.group(1)
- continue
- m = cvsRE.match(line)
- if m:
- cvsroot = m.group(1)
- continue
- m = cvsmodeRE.match(line)
- if m:
- cvsmode = m.group(1)
- continue
- m = filesRE.match(line)
- if m:
- fileList = m.group(1)
- continue
- m = modRE.match(line)
- if m:
- # We don't actually use this
- #module = m.group(1)
- continue
- m = pathRE.match(line)
- if m:
- path = m.group(1)
- continue
- m = projRE.match(line)
- if m:
- project = m.group(1)
- continue
- m = tagRE.match(line)
- if m:
- branch = m.group(1)
- continue
- m = updateRE.match(line)
- if m:
- # We don't actually use this
- #updateof = m.group(1)
- continue
- if line == "Log Message:\n":
- break
-
- # CVS 1.11 lists files as:
- # repo/path file,old-version,new-version file2,old-version,new-version
- # Version 1.12 lists files as:
- # file1 old-version new-version file2 old-version new-version
- #
- # files consists of tuples of 'file-name old-version new-version'
- # The versions are either dotted-decimal version numbers, ie 1.1
- # or NONE. New files are of the form 'NONE NUMBER', while removed
- # files are 'NUMBER NONE'. 'NONE' is a literal string
- # Parsing this instead of files list in 'Added File:' etc
- # makes it possible to handle files with embedded spaces, though
- # it could fail if the filename was 'bad 1.1 1.2'
- # For cvs version 1.11, we expect
- # my_module new_file.c,NONE,1.1
- # my_module removed.txt,1.2,NONE
- # my_module modified_file.c,1.1,1.2
- # While cvs version 1.12 gives us
- # new_file.c NONE 1.1
- # removed.txt 1.2 NONE
- # modified_file.c 1.1,1.2
-
- if fileList is None:
- log.msg('CVSMaildirSource Mail with no files. Ignoring')
- return None # We don't have any files. Email not from CVS
-
- if cvsmode == '1.11':
- # Please, no repo paths with spaces!
- m = re.search('([^ ]*) ', fileList)
- if m:
- path = m.group(1)
- else:
- log.msg('CVSMaildirSource can\'t get path from file list. Ignoring mail')
- return
- fileList = fileList[len(path):].strip()
- singleFileRE = re.compile( '(.+?),(NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+)),(NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+))(?: |$)')
- elif cvsmode == '1.12':
- singleFileRE = re.compile( '(.+?) (NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+)) (NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+))(?: |$)')
- if path is None:
- raise ValueError('CVSMaildirSource cvs 1.12 require path. Check cvs loginfo config')
- else:
- raise ValueError('Expected cvsmode 1.11 or 1.12. got: %s' % cvsmode)
-
- log.msg("CVSMaildirSource processing filelist: %s" % fileList)
- while(fileList):
- m = singleFileRE.match(fileList)
- if m:
- curFile = path + '/' + m.group(1)
- files.append( curFile )
- fileList = fileList[m.end():]
- else:
- log.msg('CVSMaildirSource no files matched regex. Ignoring')
- return None # bail - we couldn't parse the files that changed
- # Now get comments
- while lines:
- line = lines.pop(0)
- comments += line
-
- comments = comments.rstrip() + "\n"
- if comments == '\n':
- comments = None
- return ('cvs', dict(author=author, files=files, comments=comments,
- isdir=isdir, when=when, branch=branch,
- revision=rev, category=category,
- repository=cvsroot, project=project,
- properties=self.properties))
-
-# svn "commit-email.pl" handler. The format is very similar to freshcvs mail;
-# here's a sample:
-
-# From: username [at] apache.org [slightly obfuscated to avoid spam here]
-# To: commits [at] spamassassin.apache.org
-# Subject: svn commit: r105955 - in spamassassin/trunk: . lib/Mail
-# ...
-#
-# Author: username
-# Date: Sat Nov 20 00:17:49 2004 [note: TZ = local tz on server!]
-# New Revision: 105955
-#
-# Modified: [also Removed: and Added:]
-# [filename]
-# ...
-# Log:
-# [log message]
-# ...
-#
-#
-# Modified: spamassassin/trunk/lib/Mail/SpamAssassin.pm
-# [unified diff]
-#
-# [end of mail]
-
-class SVNCommitEmailMaildirSource(MaildirSource):
- name = "SVN commit-email.pl"
-
- def parse(self, m, prefix=None):
- """Parse messages sent by the svn 'commit-email.pl' trigger.
- """
-
- # The mail is sent from the person doing the checkin. Assume that the
- # local username is enough to identify them (this assumes a one-server
- # cvs-over-rsh environment rather than the server-dirs-shared-over-NFS
- # model)
- name, addr = parseaddr(m["from"])
- if not addr:
- return None # no From means this message isn't from svn
- at = addr.find("@")
- if at == -1:
- author = addr # might still be useful
- else:
- author = addr[:at]
-
- # we take the time of receipt as the time of checkin. Not correct (it
- # depends upon the email latency), but it avoids the
- # out-of-order-changes issue. Also syncmail doesn't give us anything
- # better to work with, unless you count pulling the v1-vs-v2
- # timestamp out of the diffs, which would be ugly. TODO: Pulling the
- # 'Date:' header from the mail is a possibility, and
- # email.Utils.parsedate_tz may be useful. It should be configurable,
- # however, because there are a lot of broken clocks out there.
- when = util.now()
-
- files = []
- comments = ""
- lines = list(body_line_iterator(m))
- rev = None
- while lines:
- line = lines.pop(0)
-
- # "Author: jmason"
- match = re.search(r"^Author: (\S+)", line)
- if match:
- author = match.group(1)
-
- # "New Revision: 105955"
- match = re.search(r"^New Revision: (\d+)", line)
- if match:
- rev = match.group(1)
-
- # possible TODO: use "Date: ..." data here instead of time of
- # commit message receipt, above. however, this timestamp is
- # specified *without* a timezone, in the server's local TZ, so to
- # be accurate buildbot would need a config setting to specify the
- # source server's expected TZ setting! messy.
-
- # this stanza ends with the "Log:"
- if (line == "Log:\n"):
- break
-
- # commit message is terminated by the file-listing section
- while lines:
- line = lines.pop(0)
- if (line == "Modified:\n" or
- line == "Added:\n" or
- line == "Removed:\n"):
- break
- comments += line
- comments = comments.rstrip() + "\n"
-
- while lines:
- line = lines.pop(0)
- if line == "\n":
- break
- if line.find("Modified:\n") == 0:
- continue # ignore this line
- if line.find("Added:\n") == 0:
- continue # ignore this line
- if line.find("Removed:\n") == 0:
- continue # ignore this line
- line = line.strip()
-
- thesefiles = line.split(" ")
- for f in thesefiles:
- if prefix:
- # insist that the file start with the prefix: we may get
- # changes we don't care about too
- if f.startswith(prefix):
- f = f[len(prefix):]
- else:
- log.msg("ignored file from svn commit: prefix '%s' "
- "does not match filename '%s'" % (prefix, f))
- continue
-
- # TODO: figure out how new directories are described, set
- # .isdir
- files.append(f)
-
- if not files:
- log.msg("no matching files found, ignoring commit")
- return None
-
- return ('svn', dict(author=author, files=files, comments=comments,
- when=when, revision=rev))
-
-# bzr Launchpad branch subscription mails. Sample mail:
-#
-# From: noreply@launchpad.net
-# Subject: [Branch ~knielsen/maria/tmp-buildbot-test] Rev 2701: test add file
-# To: Joe <joe@acme.com>
-# ...
-#
-# ------------------------------------------------------------
-# revno: 2701
-# committer: Joe <joe@acme.com>
-# branch nick: tmpbb
-# timestamp: Fri 2009-05-15 10:35:43 +0200
-# message:
-# test add file
-# added:
-# test-add-file
-#
-#
-# --
-#
-# https://code.launchpad.net/~knielsen/maria/tmp-buildbot-test
-#
-# You are subscribed to branch lp:~knielsen/maria/tmp-buildbot-test.
-# To unsubscribe from this branch go to https://code.launchpad.net/~knielsen/maria/tmp-buildbot-test/+edit-subscription.
-#
-# [end of mail]
-
-class BzrLaunchpadEmailMaildirSource(MaildirSource):
- name = "Launchpad"
-
- compare_attrs = MaildirSource.compare_attrs + ["branchMap", "defaultBranch"]
-
- def __init__(self, maildir, prefix=None, branchMap=None, defaultBranch=None, **kwargs):
- self.branchMap = branchMap
- self.defaultBranch = defaultBranch
- MaildirSource.__init__(self, maildir, prefix, **kwargs)
-
- def parse(self, m, prefix=None):
- """Parse branch notification messages sent by Launchpad.
- """
-
- subject = m["subject"]
- match = re.search(r"^\s*\[Branch\s+([^]]+)\]", subject)
- if match:
- repository = match.group(1)
- else:
- repository = None
-
- # Put these into a dictionary, otherwise we cannot assign them
- # from nested function definitions.
- d = { 'files': [], 'comments': u"" }
- gobbler = None
- rev = None
- author = None
- when = util.now()
- def gobble_comment(s):
- d['comments'] += s + "\n"
- def gobble_removed(s):
- d['files'].append('%s REMOVED' % s)
- def gobble_added(s):
- d['files'].append('%s ADDED' % s)
- def gobble_modified(s):
- d['files'].append('%s MODIFIED' % s)
- def gobble_renamed(s):
- match = re.search(r"^(.+) => (.+)$", s)
- if match:
- d['files'].append('%s RENAMED %s' % (match.group(1), match.group(2)))
- else:
- d['files'].append('%s RENAMED' % s)
-
- lines = list(body_line_iterator(m, True))
- rev = None
- while lines:
- line = unicode(lines.pop(0), "utf-8", errors="ignore")
-
- # revno: 101
- match = re.search(r"^revno: ([0-9.]+)", line)
- if match:
- rev = match.group(1)
-
- # committer: Joe <joe@acme.com>
- match = re.search(r"^committer: (.*)$", line)
- if match:
- author = match.group(1)
-
- # timestamp: Fri 2009-05-15 10:35:43 +0200
- # datetime.strptime() is supposed to support %z for time zone, but
- # it does not seem to work. So handle the time zone manually.
- match = re.search(r"^timestamp: [a-zA-Z]{3} (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([-+])(\d{2})(\d{2})$", line)
- if match:
- datestr = match.group(1)
- tz_sign = match.group(2)
- tz_hours = match.group(3)
- tz_minutes = match.group(4)
- when = parseLaunchpadDate(datestr, tz_sign, tz_hours, tz_minutes)
-
- if re.search(r"^message:\s*$", line):
- gobbler = gobble_comment
- elif re.search(r"^removed:\s*$", line):
- gobbler = gobble_removed
- elif re.search(r"^added:\s*$", line):
- gobbler = gobble_added
- elif re.search(r"^renamed:\s*$", line):
- gobbler = gobble_renamed
- elif re.search(r"^modified:\s*$", line):
- gobbler = gobble_modified
- elif re.search(r"^ ", line) and gobbler:
- gobbler(line[2:-1]) # Use :-1 to gobble trailing newline
-
- # Determine the name of the branch.
- branch = None
- if self.branchMap and repository:
- if self.branchMap.has_key(repository):
- branch = self.branchMap[repository]
- elif self.branchMap.has_key('lp:' + repository):
- branch = self.branchMap['lp:' + repository]
- if not branch:
- if self.defaultBranch:
- branch = self.defaultBranch
- else:
- if repository:
- branch = 'lp:' + repository
- else:
- branch = None
-
- if rev and author:
- return ('bzr', dict(author=author, files=d['files'],
- comments=d['comments'],
- when=when, revision=rev,
- branch=branch, repository=repository or ''))
- else:
- return None
-
-def parseLaunchpadDate(datestr, tz_sign, tz_hours, tz_minutes):
- time_no_tz = calendar.timegm(time.strptime(datestr, "%Y-%m-%d %H:%M:%S"))
- tz_delta = 60 * 60 * int(tz_sign + tz_hours) + 60 * int(tz_minutes)
- return time_no_tz - tz_delta
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py
deleted file mode 100644
index 49eaa3bc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from twisted.application import service
-from buildbot import interfaces, config, util
-from buildbot.process import metrics
-
-class ChangeManager(config.ReconfigurableServiceMixin, service.MultiService):
- """
- This is the master-side service which receives file change notifications
- from version-control systems.
-
- It is a Twisted service, which has instances of
- L{buildbot.interfaces.IChangeSource} as child services. These are added by
- the master with C{addSource}.
- """
-
- implements(interfaces.IEventSource)
-
- name = "changemanager"
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('change_manager')
- self.master = master
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- timer = metrics.Timer("ChangeManager.reconfigService")
- timer.start()
-
- removed, added = util.diffSets(
- set(self),
- new_config.change_sources)
-
- if removed or added:
- log.msg("adding %d new changesources, removing %d" %
- (len(added), len(removed)))
-
- for src in removed:
- yield defer.maybeDeferred(
- src.disownServiceParent)
- src.master = None
-
- for src in added:
- src.master = self.master
- src.setServiceParent(self)
-
- num_sources = len(list(self))
- assert num_sources == len(new_config.change_sources)
- metrics.MetricCountEvent.log("num_sources", num_sources, absolute=True)
-
- # reconfig any newly-added change sources, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- timer.stop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py
deleted file mode 100644
index 4dbc56ec..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2011 National Instruments
-
-
-# Many thanks to Dave Peticolas for contributing this module
-
-import re
-import time
-import os
-
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot import util
-from buildbot.changes import base
-
-class P4PollerError(Exception):
- """Something went wrong with the poll. This is used as a distinctive
- exception type so that unit tests can detect and ignore it."""
-
-def get_simple_split(branchfile):
- """Splits the branchfile argument and assuming branch is
- the first path component in branchfile, will return
- branch and file else None."""
-
- index = branchfile.find('/')
- if index == -1: return None, None
- branch, file = branchfile.split('/', 1)
- return branch, file
-
-class P4Source(base.PollingChangeSource, util.ComparableMixin):
- """This source will poll a perforce repository for changes and submit
- them to the change master."""
-
- compare_attrs = ["p4port", "p4user", "p4passwd", "p4base",
- "p4bin", "pollInterval"]
-
- env_vars = ["P4CLIENT", "P4PORT", "P4PASSWD", "P4USER",
- "P4CHARSET" , "PATH"]
-
- changes_line_re = re.compile(
- r"Change (?P<num>\d+) on \S+ by \S+@\S+ '.*'$")
- describe_header_re = re.compile(
- r"Change \d+ by (?P<who>\S+)@\S+ on (?P<when>.+)$")
- file_re = re.compile(r"^\.\.\. (?P<path>[^#]+)#\d+ [/\w]+$")
- datefmt = '%Y/%m/%d %H:%M:%S'
-
- parent = None # filled in when we're added
- last_change = None
- loop = None
-
- def __init__(self, p4port=None, p4user=None, p4passwd=None,
- p4base='//', p4bin='p4',
- split_file=lambda branchfile: (None, branchfile),
- pollInterval=60 * 10, histmax=None, pollinterval=-2,
- encoding='utf8', project=None, name=None):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- base.PollingChangeSource.__init__(self, name=name, pollInterval=pollInterval)
-
- if project is None:
- project = ''
-
- self.p4port = p4port
- self.p4user = p4user
- self.p4passwd = p4passwd
- self.p4base = p4base
- self.p4bin = p4bin
- self.split_file = split_file
- self.encoding = encoding
- self.project = project
-
- def describe(self):
- return "p4source %s %s" % (self.p4port, self.p4base)
-
- def poll(self):
- d = self._poll()
- d.addErrback(log.err, 'P4 poll failed')
- return d
-
- def _get_process_output(self, args):
- env = dict([(e, os.environ.get(e)) for e in self.env_vars if os.environ.get(e)])
- d = utils.getProcessOutput(self.p4bin, args, env)
- return d
-
- @defer.inlineCallbacks
- def _poll(self):
- args = []
- if self.p4port:
- args.extend(['-p', self.p4port])
- if self.p4user:
- args.extend(['-u', self.p4user])
- if self.p4passwd:
- args.extend(['-P', self.p4passwd])
- args.extend(['changes'])
- if self.last_change is not None:
- args.extend(['%s...@%d,now' % (self.p4base, self.last_change+1)])
- else:
- args.extend(['-m', '1', '%s...' % (self.p4base,)])
-
- result = yield self._get_process_output(args)
-
- last_change = self.last_change
- changelists = []
- for line in result.split('\n'):
- line = line.strip()
- if not line: continue
- m = self.changes_line_re.match(line)
- if not m:
- raise P4PollerError("Unexpected 'p4 changes' output: %r" % result)
- num = int(m.group('num'))
- if last_change is None:
- # first time through, the poller just gets a "baseline" for where to
- # start on the next poll
- log.msg('P4Poller: starting at change %d' % num)
- self.last_change = num
- return
- changelists.append(num)
- changelists.reverse() # oldest first
-
- # Retrieve each sequentially.
- for num in changelists:
- args = []
- if self.p4port:
- args.extend(['-p', self.p4port])
- if self.p4user:
- args.extend(['-u', self.p4user])
- if self.p4passwd:
- args.extend(['-P', self.p4passwd])
- args.extend(['describe', '-s', str(num)])
- result = yield self._get_process_output(args)
-
- # decode the result from its designated encoding
- result = result.decode(self.encoding)
-
- lines = result.split('\n')
- # SF#1555985: Wade Brainerd reports a stray ^M at the end of the date
- # field. The rstrip() is intended to remove that.
- lines[0] = lines[0].rstrip()
- m = self.describe_header_re.match(lines[0])
- if not m:
- raise P4PollerError("Unexpected 'p4 describe -s' result: %r" % result)
- who = m.group('who')
- when = time.mktime(time.strptime(m.group('when'), self.datefmt))
- comments = ''
- while not lines[0].startswith('Affected files'):
- comments += lines.pop(0) + '\n'
- lines.pop(0) # affected files
-
- branch_files = {} # dict for branch mapped to file(s)
- while lines:
- line = lines.pop(0).strip()
- if not line: continue
- m = self.file_re.match(line)
- if not m:
- raise P4PollerError("Invalid file line: %r" % line)
- path = m.group('path')
- if path.startswith(self.p4base):
- branch, file = self.split_file(path[len(self.p4base):])
- if (branch == None and file == None): continue
- if branch_files.has_key(branch):
- branch_files[branch].append(file)
- else:
- branch_files[branch] = [file]
-
- for branch in branch_files:
- yield self.master.addChange(
- author=who,
- files=branch_files[branch],
- comments=comments,
- revision=str(num),
- when_timestamp=util.epoch2datetime(when),
- branch=branch,
- project=self.project)
-
- self.last_change = num
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py
deleted file mode 100644
index a73dca16..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.pbutil import NewCredPerspective
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-from buildbot import config
-
-class ChangePerspective(NewCredPerspective):
-
- def __init__(self, master, prefix):
- self.master = master
- self.prefix = prefix
-
- def attached(self, mind):
- return self
- def detached(self, mind):
- pass
-
- def perspective_addChange(self, changedict):
- log.msg("perspective_addChange called")
-
- if 'revlink' in changedict and not changedict['revlink']:
- changedict['revlink'] = ''
- if 'repository' in changedict and not changedict['repository']:
- changedict['repository'] = ''
- if 'project' in changedict and not changedict['project']:
- changedict['project'] = ''
- if 'files' not in changedict or not changedict['files']:
- changedict['files'] = []
-
- # rename arguments to new names. Note that the client still uses the
- # "old" names (who, when, and isdir), as they are not deprecated yet,
- # although the master will accept the new names (author,
- # when_timestamp, and is_dir). After a few revisions have passed, we
- # can switch the client to use the new names.
- if 'isdir' in changedict:
- changedict['is_dir'] = changedict['isdir']
- del changedict['isdir']
- if 'who' in changedict:
- changedict['author'] = changedict['who']
- del changedict['who']
- if 'when' in changedict:
- when = None
- if changedict['when'] is not None:
- when = epoch2datetime(changedict['when'])
- changedict['when_timestamp'] = when
- del changedict['when']
-
- # turn any bytestring keys into unicode, assuming utf8 but just
- # replacing unknown characters. Ideally client would send us unicode
- # in the first place, but older clients do not, so this fallback is
- # useful.
- for key in changedict:
- if type(changedict[key]) == str:
- changedict[key] = changedict[key].decode('utf8', 'replace')
- changedict['files'] = list(changedict['files'])
- for i, file in enumerate(changedict.get('files', [])):
- if type(file) == str:
- changedict['files'][i] = file.decode('utf8', 'replace')
-
- files = []
- for path in changedict['files']:
- if self.prefix:
- if not path.startswith(self.prefix):
- # this file does not start with the prefix, so ignore it
- continue
- path = path[len(self.prefix):]
- files.append(path)
- changedict['files'] = files
-
- if not files:
- log.msg("No files listed in change... bit strange, but not fatal.")
-
- if changedict.has_key('links'):
- log.msg("Found links: "+repr(changedict['links']))
- del changedict['links']
-
- d = self.master.addChange(**changedict)
- # since this is a remote method, we can't return a Change instance, so
- # this just sets the return value to None:
- d.addCallback(lambda _ : None)
- return d
-
-class PBChangeSource(config.ReconfigurableServiceMixin, base.ChangeSource):
- compare_attrs = ["user", "passwd", "port", "prefix", "port"]
-
- def __init__(self, user="change", passwd="changepw", port=None,
- prefix=None):
-
- self.user = user
- self.passwd = passwd
- self.port = port
- self.prefix = prefix
- self.registration = None
- self.registered_port = None
-
- def describe(self):
- portname = self.registered_port
- d = "PBChangeSource listener on " + str(portname)
- if self.prefix is not None:
- d += " (prefix '%s')" % self.prefix
- return d
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # calculate the new port
- port = self.port
- if port is None:
- port = new_config.slavePortnum
-
- # and, if it's changed, re-register
- if port != self.registered_port:
- yield self._unregister()
- self._register(port)
-
- yield config.ReconfigurableServiceMixin.reconfigService(
- self, new_config)
-
- def stopService(self):
- d = defer.maybeDeferred(base.ChangeSource.stopService, self)
- d.addCallback(lambda _ : self._unregister())
- return d
-
- def _register(self, port):
- if not port:
- log.msg("PBChangeSource has no port to listen on")
- return
- self.registered_port = port
- self.registration = self.master.pbmanager.register(
- port, self.user, self.passwd,
- self.getPerspective)
-
- def _unregister(self):
- self.registered_port = None
- if self.registration:
- reg = self.registration
- self.registration = None
- return reg.unregister()
- else:
- return defer.succeed(None)
-
- def getPerspective(self, mind, username):
- assert username == self.user
- return ChangePerspective(self.master, self.prefix)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py
deleted file mode 100644
index 1e2fde81..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py
+++ /dev/null
@@ -1,412 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-# Based on the work of Dave Peticolas for the P4poll
-# Changed to svn (using xml.dom.minidom) by Niklaus Giger
-# Hacked beyond recognition by Brian Warner
-
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot import util
-from buildbot.changes import base
-
-import xml.dom.minidom
-import os, urllib
-
-# these split_file_* functions are available for use as values to the
-# split_file= argument.
-def split_file_alwaystrunk(path):
- return dict(path=path)
-
-def split_file_branches(path):
- # turn "trunk/subdir/file.c" into (None, "subdir/file.c")
- # and "trunk/subdir/" into (None, "subdir/")
- # and "trunk/" into (None, "")
- # and "branches/1.5.x/subdir/file.c" into ("branches/1.5.x", "subdir/file.c")
- # and "branches/1.5.x/subdir/" into ("branches/1.5.x", "subdir/")
- # and "branches/1.5.x/" into ("branches/1.5.x", "")
- pieces = path.split('/')
- if len(pieces) > 1 and pieces[0] == 'trunk':
- return (None, '/'.join(pieces[1:]))
- elif len(pieces) > 2 and pieces[0] == 'branches':
- return ('/'.join(pieces[0:2]), '/'.join(pieces[2:]))
- else:
- return None
-
-def split_file_projects_branches(path):
- # turn projectname/trunk/subdir/file.c into dict(project=projectname, branch=trunk, path=subdir/file.c)
- if not "/" in path:
- return None
- project, path = path.split("/", 1)
- f = split_file_branches(path)
- if f:
- info = dict(project=project, path=f[1])
- if f[0]:
- info['branch'] = f[0]
- return info
- return f
-
-class SVNPoller(base.PollingChangeSource, util.ComparableMixin):
- """
- Poll a Subversion repository for changes and submit them to the change
- master.
- """
-
- compare_attrs = ["svnurl", "split_file",
- "svnuser", "svnpasswd", "project",
- "pollInterval", "histmax",
- "svnbin", "category", "cachepath"]
-
- parent = None # filled in when we're added
- last_change = None
- loop = None
-
- def __init__(self, svnurl, split_file=None,
- svnuser=None, svnpasswd=None,
- pollInterval=10*60, histmax=100,
- svnbin='svn', revlinktmpl='', category=None,
- project='', cachepath=None, pollinterval=-2,
- extra_args=None):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- base.PollingChangeSource.__init__(self, name=svnurl, pollInterval=pollInterval)
-
- if svnurl.endswith("/"):
- svnurl = svnurl[:-1] # strip the trailing slash
- self.svnurl = svnurl
- self.extra_args = extra_args
- self.split_file = split_file or split_file_alwaystrunk
- self.svnuser = svnuser
- self.svnpasswd = svnpasswd
-
- self.revlinktmpl = revlinktmpl
-
- self.environ = os.environ.copy() # include environment variables
- # required for ssh-agent auth
-
- self.svnbin = svnbin
- self.histmax = histmax
- self._prefix = None
- self.category = category
- self.project = project
-
- self.cachepath = cachepath
- if self.cachepath and os.path.exists(self.cachepath):
- try:
- with open(self.cachepath, "r") as f:
- self.last_change = int(f.read().strip())
- log.msg("SVNPoller: SVNPoller(%s) setting last_change to %s" % (self.svnurl, self.last_change))
- # try writing it, too
- with open(self.cachepath, "w") as f:
- f.write(str(self.last_change))
- except:
- self.cachepath = None
- log.msg(("SVNPoller: SVNPoller(%s) cache file corrupt or unwriteable; " +
- "skipping and not using") % self.svnurl)
- log.err()
-
- def describe(self):
- return "SVNPoller: watching %s" % self.svnurl
-
- def poll(self):
- # Our return value is only used for unit testing.
-
- # we need to figure out the repository root, so we can figure out
- # repository-relative pathnames later. Each SVNURL is in the form
- # (ROOT)/(PROJECT)/(BRANCH)/(FILEPATH), where (ROOT) is something
- # like svn://svn.twistedmatrix.com/svn/Twisted (i.e. there is a
- # physical repository at /svn/Twisted on that host), (PROJECT) is
- # something like Projects/Twisted (i.e. within the repository's
- # internal namespace, everything under Projects/Twisted/ has
- # something to do with Twisted, but these directory names do not
- # actually appear on the repository host), (BRANCH) is something like
- # "trunk" or "branches/2.0.x", and (FILEPATH) is a tree-relative
- # filename like "twisted/internet/defer.py".
-
- # our self.svnurl attribute contains (ROOT)/(PROJECT) combined
- # together in a way that we can't separate without svn's help. If the
- # user is not using the split_file= argument, then self.svnurl might
- # be (ROOT)/(PROJECT)/(BRANCH) . In any case, the filenames we will
- # get back from 'svn log' will be of the form
- # (PROJECT)/(BRANCH)/(FILEPATH), but we want to be able to remove
- # that (PROJECT) prefix from them. To do this without requiring the
- # user to tell us how svnurl is split into ROOT and PROJECT, we do an
- # 'svn info --xml' command at startup. This command will include a
- # <root> element that tells us ROOT. We then strip this prefix from
- # self.svnurl to determine PROJECT, and then later we strip the
- # PROJECT prefix from the filenames reported by 'svn log --xml' to
- # get a (BRANCH)/(FILEPATH) that can be passed to split_file() to
- # turn into separate BRANCH and FILEPATH values.
-
- # whew.
-
- if self.project:
- log.msg("SVNPoller: polling " + self.project)
- else:
- log.msg("SVNPoller: polling")
-
- d = defer.succeed(None)
- if not self._prefix:
- d.addCallback(lambda _ : self.get_prefix())
- def set_prefix(prefix):
- self._prefix = prefix
- d.addCallback(set_prefix)
-
- d.addCallback(self.get_logs)
- d.addCallback(self.parse_logs)
- d.addCallback(self.get_new_logentries)
- d.addCallback(self.create_changes)
- d.addCallback(self.submit_changes)
- d.addCallback(self.finished_ok)
- d.addErrback(log.err, 'SVNPoller: Error in while polling') # eat errors
- return d
-
- def getProcessOutput(self, args):
- # this exists so we can override it during the unit tests
- d = utils.getProcessOutput(self.svnbin, args, self.environ)
- return d
-
- def get_prefix(self):
- args = ["info", "--xml", "--non-interactive", self.svnurl]
- if self.svnuser:
- args.extend(["--username=%s" % self.svnuser])
- if self.svnpasswd:
- args.extend(["--password=%s" % self.svnpasswd])
- if self.extra_args:
- args.extend(self.extra_args)
- d = self.getProcessOutput(args)
- def determine_prefix(output):
- try:
- doc = xml.dom.minidom.parseString(output)
- except xml.parsers.expat.ExpatError:
- log.msg("SVNPoller: SVNPoller._determine_prefix_2: ExpatError in '%s'"
- % output)
- raise
- rootnodes = doc.getElementsByTagName("root")
- if not rootnodes:
- # this happens if the URL we gave was already the root. In this
- # case, our prefix is empty.
- self._prefix = ""
- return self._prefix
- rootnode = rootnodes[0]
- root = "".join([c.data for c in rootnode.childNodes])
- # root will be a unicode string
- if not self.svnurl.startswith(root):
- log.msg(format="svnurl='%(svnurl)s' doesn't start with <root>='%(root)s'",
- svnurl=self.svnurl, root=root)
- raise RuntimeError("Can't handle redirected svn connections!? "
- "This shouldn't happen.")
- prefix = self.svnurl[len(root):]
- if prefix.startswith("/"):
- prefix = prefix[1:]
- log.msg("SVNPoller: svnurl=%s, root=%s, so prefix=%s" %
- (self.svnurl, root, prefix))
- return prefix
- d.addCallback(determine_prefix)
- return d
-
- def get_logs(self, _):
- args = []
- args.extend(["log", "--xml", "--verbose", "--non-interactive"])
- if self.svnuser:
- args.extend(["--username=%s" % self.svnuser])
- if self.svnpasswd:
- args.extend(["--password=%s" % self.svnpasswd])
- if self.extra_args:
- args.extend(self.extra_args)
- args.extend(["--limit=%d" % (self.histmax), self.svnurl])
- d = self.getProcessOutput(args)
- return d
-
- def parse_logs(self, output):
- # parse the XML output, return a list of <logentry> nodes
- try:
- doc = xml.dom.minidom.parseString(output)
- except xml.parsers.expat.ExpatError:
- log.msg("SVNPoller: SVNPoller.parse_logs: ExpatError in '%s'" % output)
- raise
- logentries = doc.getElementsByTagName("logentry")
- return logentries
-
-
- def get_new_logentries(self, logentries):
- last_change = old_last_change = self.last_change
-
- # given a list of logentries, calculate new_last_change, and
- # new_logentries, where new_logentries contains only the ones after
- # last_change
-
- new_last_change = None
- new_logentries = []
- if logentries:
- new_last_change = int(logentries[0].getAttribute("revision"))
-
- if last_change is None:
- # if this is the first time we've been run, ignore any changes
- # that occurred before now. This prevents a build at every
- # startup.
- log.msg('SVNPoller: starting at change %s' % new_last_change)
- elif last_change == new_last_change:
- # an unmodified repository will hit this case
- log.msg('SVNPoller: no changes')
- else:
- for el in logentries:
- if last_change == int(el.getAttribute("revision")):
- break
- new_logentries.append(el)
- new_logentries.reverse() # return oldest first
-
- self.last_change = new_last_change
- log.msg('SVNPoller: _process_changes %s .. %s' %
- (old_last_change, new_last_change))
- return new_logentries
-
-
- def _get_text(self, element, tag_name):
- try:
- child_nodes = element.getElementsByTagName(tag_name)[0].childNodes
- text = "".join([t.data for t in child_nodes])
- except:
- text = "<unknown>"
- return text
-
- def _transform_path(self, path):
- if not path.startswith(self._prefix):
- log.msg(format="SVNPoller: ignoring path '%(path)s' which doesn't"
- "start with prefix '%(prefix)s'",
- path=path, prefix=self._prefix)
- return
- relative_path = path[len(self._prefix):]
- if relative_path.startswith("/"):
- relative_path = relative_path[1:]
- where = self.split_file(relative_path)
- # 'where' is either None, (branch, final_path) or a dict
- if not where:
- return
- if isinstance(where, tuple):
- where = dict(branch=where[0], path=where[1])
- return where
-
- def create_changes(self, new_logentries):
- changes = []
-
- for el in new_logentries:
- revision = str(el.getAttribute("revision"))
-
- revlink=''
-
- if self.revlinktmpl:
- if revision:
- revlink = self.revlinktmpl % urllib.quote_plus(revision)
-
- log.msg("Adding change revision %s" % (revision,))
- author = self._get_text(el, "author")
- comments = self._get_text(el, "msg")
- # there is a "date" field, but it provides localtime in the
- # repository's timezone, whereas we care about buildmaster's
- # localtime (since this will get used to position the boxes on
- # the Waterfall display, etc). So ignore the date field, and
- # addChange will fill in with the current time
- branches = {}
- try:
- pathlist = el.getElementsByTagName("paths")[0]
- except IndexError: # weird, we got an empty revision
- log.msg("ignoring commit with no paths")
- continue
-
- for p in pathlist.getElementsByTagName("path"):
- kind = p.getAttribute("kind")
- action = p.getAttribute("action")
- path = "".join([t.data for t in p.childNodes])
- # the rest of buildbot is certaily not yet ready to handle
- # unicode filenames, because they get put in RemoteCommands
- # which get sent via PB to the buildslave, and PB doesn't
- # handle unicode.
- path = path.encode("ascii")
- if path.startswith("/"):
- path = path[1:]
- if kind == "dir" and not path.endswith("/"):
- path += "/"
- where = self._transform_path(path)
-
- # if 'where' is None, the file was outside any project that
- # we care about and we should ignore it
- if where:
- branch = where.get("branch", None)
- filename = where["path"]
- if not branch in branches:
- branches[branch] = { 'files': [], 'number_of_directories': 0}
- if filename == "":
- # root directory of branch
- branches[branch]['files'].append(filename)
- branches[branch]['number_of_directories'] += 1
- elif filename.endswith("/"):
- # subdirectory of branch
- branches[branch]['files'].append(filename[:-1])
- branches[branch]['number_of_directories'] += 1
- else:
- branches[branch]['files'].append(filename)
-
- if not branches[branch].has_key('action'):
- branches[branch]['action'] = action
-
- for key in ("repository", "project", "codebase"):
- if key in where:
- branches[branch][key] = where[key]
-
- for branch in branches.keys():
- action = branches[branch]['action']
- files = branches[branch]['files']
-
- number_of_directories_changed = branches[branch]['number_of_directories']
- number_of_files_changed = len(files)
-
- if action == u'D' and number_of_directories_changed == 1 and number_of_files_changed == 1 and files[0] == '':
- log.msg("Ignoring deletion of branch '%s'" % branch)
- else:
- chdict = dict(
- author=author,
- files=files,
- comments=comments,
- revision=revision,
- branch=branch,
- revlink=revlink,
- category=self.category,
- repository=branches[branch].get('repository', self.svnurl),
- project=branches[branch].get('project', self.project),
- codebase=branches[branch].get('codebase', None))
- changes.append(chdict)
-
- return changes
-
- @defer.inlineCallbacks
- def submit_changes(self, changes):
- for chdict in changes:
- yield self.master.addChange(src='svn', **chdict)
-
- def finished_ok(self, res):
- if self.cachepath:
- with open(self.cachepath, "w") as f:
- f.write(str(self.last_change))
-
- log.msg("SVNPoller: finished polling %s" % res)
- return res
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py
deleted file mode 100644
index 24e2cfd6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.spread import pb
-
-class StatusClient(pb.Referenceable):
- """To use this, call my .connected method with a RemoteReference to the
- buildmaster's StatusClientPerspective object.
- """
-
- def __init__(self, events):
- self.builders = {}
- self.events = events
-
- def connected(self, remote):
- print "connected"
- self.remote = remote
- remote.callRemote("subscribe", self.events, 5, self)
-
- def remote_builderAdded(self, buildername, builder):
- print "builderAdded", buildername
-
- def remote_builderRemoved(self, buildername):
- print "builderRemoved", buildername
-
- def remote_builderChangedState(self, buildername, state, eta):
- print "builderChangedState", buildername, state, eta
-
- def remote_buildStarted(self, buildername, build):
- print "buildStarted", buildername
-
- def remote_buildFinished(self, buildername, build, results):
- print "buildFinished", results
-
- def remote_buildETAUpdate(self, buildername, build, eta):
- print "ETA", buildername, eta
-
- def remote_stepStarted(self, buildername, build, stepname, step):
- print "stepStarted", buildername, stepname
-
- def remote_stepFinished(self, buildername, build, stepname, step, results):
- print "stepFinished", buildername, stepname, results
-
- def remote_stepETAUpdate(self, buildername, build, stepname, step,
- eta, expectations):
- print "stepETA", buildername, stepname, eta
-
- def remote_logStarted(self, buildername, build, stepname, step,
- logname, log):
- print "logStarted", buildername, stepname
-
- def remote_logFinished(self, buildername, build, stepname, step,
- logname, log):
- print "logFinished", buildername, stepname
-
- def remote_logChunk(self, buildername, build, stepname, step, logname, log,
- channel, text):
- ChunkTypes = ["STDOUT", "STDERR", "HEADER"]
- print "logChunk[%s]: %s" % (ChunkTypes[channel], text)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade
deleted file mode 100644
index 40468bb9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade
+++ /dev/null
@@ -1,684 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="window1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Buildbot Debug Tool</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="connection">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="connectbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Connect</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_connect"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="connectlabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Disconnected</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="commands">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="reload">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Reload .cfg</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_reload" last_modification_time="Wed, 24 Sep 2003 20:47:55 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="rebuild">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Rebuild .py</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_rebuild" last_modification_time="Wed, 24 Sep 2003 20:49:18 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button7">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">poke IRC</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_poke_irc" last_modification_time="Wed, 14 Jan 2004 22:23:59 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="usebranch">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Branch:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_usebranch_toggled" last_modification_time="Tue, 25 Oct 2005 01:42:45 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="branch">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="userevision">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Revision:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_userevision_toggled" last_modification_time="Wed, 08 Sep 2004 17:58:33 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="revision">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="Commit">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="commit">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="button2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">commit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_commit"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="filename">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">twisted/internet/app.py</property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Who: </property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="who">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">bob</property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Commit</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">2</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="builderframe">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="builder">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Builder:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="buildname">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">one</property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="buildercontrol">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="button1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Request
-Build</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_build"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button8">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Ping
-Builder</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_ping" last_modification_time="Fri, 24 Nov 2006 05:18:51 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="status">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Currently:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">7</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">offline</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_offline"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button4">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">idle</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_idle"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button5">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">waiting</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_waiting"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button6">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">building</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_building"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Builder</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">2</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py
deleted file mode 100644
index 5316d148..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.internet import gtk2reactor
-gtk2reactor.install()
-from twisted.internet import reactor
-from twisted.python import util
-from twisted.spread import pb
-from twisted.cred import credentials
-import gtk.glade #@UnresolvedImport
-import re
-
-class DebugWidget:
- def __init__(self, master="localhost:8007", passwd="debugpw"):
- self.connected = 0
- try:
- host, port = re.search(r'(.+):(\d+)', master).groups()
- except:
- print "unparseable master location '%s'" % master
- print " expecting something more like localhost:8007"
- raise
- self.host = host
- self.port = int(port)
- self.passwd = passwd
- self.remote = None
- xml = self.xml = gtk.glade.XML(util.sibpath(__file__, "debug.glade"))
- g = xml.get_widget
- self.buildname = g('buildname')
- self.filename = g('filename')
- self.connectbutton = g('connectbutton')
- self.connectlabel = g('connectlabel')
- g('window1').connect('destroy', lambda win: gtk.main_quit())
- # put the master info in the window's titlebar
- g('window1').set_title("Buildbot Debug Tool: %s" % master)
- c = xml.signal_connect
- c('do_connect', self.do_connect)
- c('do_reload', self.do_reload)
- c('do_rebuild', self.do_rebuild)
- c('do_poke_irc', self.do_poke_irc)
- c('do_build', self.do_build)
- c('do_ping', self.do_ping)
- c('do_commit', self.do_commit)
- c('on_usebranch_toggled', self.usebranch_toggled)
- self.usebranch_toggled(g('usebranch'))
- c('on_userevision_toggled', self.userevision_toggled)
- self.userevision_toggled(g('userevision'))
- c('do_current_offline', self.do_current, "offline")
- c('do_current_idle', self.do_current, "idle")
- c('do_current_waiting', self.do_current, "waiting")
- c('do_current_building', self.do_current, "building")
-
- def do_connect(self, widget):
- if self.connected:
- self.connectlabel.set_text("Disconnecting...")
- if self.remote:
- self.remote.broker.transport.loseConnection()
- else:
- self.connectlabel.set_text("Connecting...")
- f = pb.PBClientFactory()
- creds = credentials.UsernamePassword("debug", self.passwd)
- d = f.login(creds)
- reactor.connectTCP(self.host, int(self.port), f)
- d.addCallbacks(self.connect_complete, self.connect_failed)
- def connect_complete(self, ref):
- self.connectbutton.set_label("Disconnect")
- self.connectlabel.set_text("Connected")
- self.connected = 1
- self.remote = ref
- self.remote.callRemote("print", "hello cleveland")
- self.remote.notifyOnDisconnect(self.disconnected)
- def connect_failed(self, why):
- self.connectlabel.set_text("Failed")
- print why
- def disconnected(self, ref):
- self.connectbutton.set_label("Connect")
- self.connectlabel.set_text("Disconnected")
- self.connected = 0
- self.remote = None
-
- def do_reload(self, widget):
- if not self.remote:
- return
- d = self.remote.callRemote("reload")
- d.addErrback(self.err)
- def do_rebuild(self, widget):
- print "Not yet implemented"
- return
- def do_poke_irc(self, widget):
- if not self.remote:
- return
- d = self.remote.callRemote("pokeIRC")
- d.addErrback(self.err)
-
- def do_build(self, widget):
- if not self.remote:
- return
- name = self.buildname.get_text()
- branch = None
- if self.xml.get_widget("usebranch").get_active():
- branch = self.xml.get_widget('branch').get_text()
- if branch == '':
- branch = None
- revision = None
- if self.xml.get_widget("userevision").get_active():
- revision = self.xml.get_widget('revision').get_text()
- if revision == '':
- revision = None
- reason = "debugclient 'Request Build' button pushed"
- properties = {}
- d = self.remote.callRemote("requestBuild",
- name, reason, branch, revision, properties)
- d.addErrback(self.err)
-
- def do_ping(self, widget):
- if not self.remote:
- return
- name = self.buildname.get_text()
- d = self.remote.callRemote("pingBuilder", name)
- d.addErrback(self.err)
-
- def usebranch_toggled(self, widget):
- rev = self.xml.get_widget('branch')
- if widget.get_active():
- rev.set_sensitive(True)
- else:
- rev.set_sensitive(False)
-
- def userevision_toggled(self, widget):
- rev = self.xml.get_widget('revision')
- if widget.get_active():
- rev.set_sensitive(True)
- else:
- rev.set_sensitive(False)
-
- def do_commit(self, widget):
- if not self.remote:
- return
- filename = self.filename.get_text()
- who = self.xml.get_widget("who").get_text()
-
- branch = None
- if self.xml.get_widget("usebranch").get_active():
- branch = self.xml.get_widget('branch').get_text()
- if branch == '':
- branch = None
-
- revision = None
- if self.xml.get_widget("userevision").get_active():
- revision = self.xml.get_widget('revision').get_text()
- try:
- revision = int(revision)
- except ValueError:
- pass
- if revision == '':
- revision = None
-
- kwargs = { 'revision': revision, 'who': who }
- if branch:
- kwargs['branch'] = branch
- d = self.remote.callRemote("fakeChange", filename, **kwargs)
- d.addErrback(self.err)
-
- def do_current(self, widget, state):
- if not self.remote:
- return
- name = self.buildname.get_text()
- d = self.remote.callRemote("setCurrentState", name, state)
- d.addErrback(self.err)
- def err(self, failure):
- print "received error:", failure
-
- def run(self):
- reactor.run()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py
deleted file mode 100644
index d79bb0fe..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py
+++ /dev/null
@@ -1,551 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.internet import gtk2reactor
-gtk2reactor.install() #@UndefinedVariable
-
-import sys, time
-
-import pygtk #@UnresolvedImport
-pygtk.require("2.0")
-import gobject, gtk #@UnresolvedImport
-assert(gtk.Window) # in gtk1 it's gtk.GtkWindow
-
-from twisted.spread import pb
-
-#from buildbot.clients.base import Builder, Client
-from buildbot.clients.base import StatusClient
-from buildbot.clients.text import TextClient
-from buildbot.util import now
-
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION
-
-'''
-class Pane:
- def __init__(self):
- pass
-
-class OneRow(Pane):
- """This is a one-row status bar. It has one square per Builder, and that
- square is either red, yellow, or green. """
-
- def __init__(self):
- Pane.__init__(self)
- self.widget = gtk.VBox(gtk.FALSE, 2)
- self.nameBox = gtk.HBox(gtk.TRUE)
- self.statusBox = gtk.HBox(gtk.TRUE)
- self.widget.add(self.nameBox)
- self.widget.add(self.statusBox)
- self.widget.show_all()
- self.builders = []
-
- def getWidget(self):
- return self.widget
- def addBuilder(self, builder):
- print "OneRow.addBuilder"
- # todo: ordering. Should follow the order in which they were added
- # to the original BotMaster
- self.builders.append(builder)
- # add the name to the left column, and a label (with background) to
- # the right
- name = gtk.Label(builder.name)
- status = gtk.Label('??')
- status.set_size_request(64,64)
- box = gtk.EventBox()
- box.add(status)
- name.show()
- box.show_all()
- self.nameBox.add(name)
- self.statusBox.add(box)
- builder.haveSomeWidgets([name, status, box])
-
-class R2Builder(Builder):
- def start(self):
- self.nameSquare.set_text(self.name)
- self.statusSquare.set_text("???")
- self.subscribe()
- def haveSomeWidgets(self, widgets):
- self.nameSquare, self.statusSquare, self.statusBox = widgets
-
- def remote_newLastBuildStatus(self, event):
- color = None
- if event:
- text = "\n".join(event.text)
- color = event.color
- else:
- text = "none"
- self.statusSquare.set_text(text)
- if color:
- print "color", color
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
-
- def remote_currentlyOffline(self):
- self.statusSquare.set_text("offline")
- def remote_currentlyIdle(self):
- self.statusSquare.set_text("idle")
- def remote_currentlyWaiting(self, seconds):
- self.statusSquare.set_text("waiting")
- def remote_currentlyInterlocked(self):
- self.statusSquare.set_text("interlocked")
- def remote_currentlyBuilding(self, eta):
- self.statusSquare.set_text("building")
-
-
-class CompactRow(Pane):
- def __init__(self):
- Pane.__init__(self)
- self.widget = gtk.VBox(gtk.FALSE, 3)
- self.nameBox = gtk.HBox(gtk.TRUE, 2)
- self.lastBuildBox = gtk.HBox(gtk.TRUE, 2)
- self.statusBox = gtk.HBox(gtk.TRUE, 2)
- self.widget.add(self.nameBox)
- self.widget.add(self.lastBuildBox)
- self.widget.add(self.statusBox)
- self.widget.show_all()
- self.builders = []
-
- def getWidget(self):
- return self.widget
-
- def addBuilder(self, builder):
- self.builders.append(builder)
-
- name = gtk.Label(builder.name)
- name.show()
- self.nameBox.add(name)
-
- last = gtk.Label('??')
- last.set_size_request(64,64)
- lastbox = gtk.EventBox()
- lastbox.add(last)
- lastbox.show_all()
- self.lastBuildBox.add(lastbox)
-
- status = gtk.Label('??')
- status.set_size_request(64,64)
- statusbox = gtk.EventBox()
- statusbox.add(status)
- statusbox.show_all()
- self.statusBox.add(statusbox)
-
- builder.haveSomeWidgets([name, last, lastbox, status, statusbox])
-
- def removeBuilder(self, name, builder):
- self.nameBox.remove(builder.nameSquare)
- self.lastBuildBox.remove(builder.lastBuildBox)
- self.statusBox.remove(builder.statusBox)
- self.builders.remove(builder)
-
-class CompactBuilder(Builder):
- def setup(self):
- self.timer = None
- self.text = []
- self.eta = None
- def start(self):
- self.nameSquare.set_text(self.name)
- self.statusSquare.set_text("???")
- self.subscribe()
- def haveSomeWidgets(self, widgets):
- (self.nameSquare,
- self.lastBuildSquare, self.lastBuildBox,
- self.statusSquare, self.statusBox) = widgets
-
- def remote_currentlyOffline(self):
- self.eta = None
- self.stopTimer()
- self.statusSquare.set_text("offline")
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse("red"))
- def remote_currentlyIdle(self):
- self.eta = None
- self.stopTimer()
- self.statusSquare.set_text("idle")
- def remote_currentlyWaiting(self, seconds):
- self.nextBuild = now() + seconds
- self.startTimer(self.updateWaiting)
- def remote_currentlyInterlocked(self):
- self.stopTimer()
- self.statusSquare.set_text("interlocked")
- def startTimer(self, func):
- # the func must clear self.timer and return gtk.FALSE when the event
- # has arrived
- self.stopTimer()
- self.timer = gtk.timeout_add(1000, func)
- func()
- def stopTimer(self):
- if self.timer:
- gtk.timeout_remove(self.timer)
- self.timer = None
- def updateWaiting(self):
- when = self.nextBuild
- if now() < when:
- next = time.strftime("%H:%M:%S", time.localtime(when))
- secs = "[%d seconds]" % (when - now())
- self.statusSquare.set_text("waiting\n%s\n%s" % (next, secs))
- return gtk.TRUE # restart timer
- else:
- # done
- self.statusSquare.set_text("waiting\n[RSN]")
- self.timer = None
- return gtk.FALSE
-
- def remote_currentlyBuilding(self, eta):
- self.stopTimer()
- self.statusSquare.set_text("building")
- if eta:
- d = eta.callRemote("subscribe", self, 5)
-
- def remote_newLastBuildStatus(self, event):
- color = None
- if event:
- text = "\n".join(event.text)
- color = event.color
- else:
- text = "none"
- if not color: color = "gray"
- self.lastBuildSquare.set_text(text)
- self.lastBuildBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
-
- def remote_newEvent(self, event):
- assert(event.__class__ == GtkUpdatingEvent)
- self.current = event
- event.builder = self
- self.text = event.text
- if not self.text: self.text = ["idle"]
- self.eta = None
- self.stopTimer()
- self.updateText()
- color = event.color
- if not color: color = "gray"
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
-
- def updateCurrent(self):
- text = self.current.text
- if text:
- self.text = text
- self.updateText()
- color = self.current.color
- if color:
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
- def updateText(self):
- etatext = []
- if self.eta:
- etatext = [time.strftime("%H:%M:%S", time.localtime(self.eta))]
- if now() > self.eta:
- etatext += ["RSN"]
- else:
- seconds = self.eta - now()
- etatext += ["[%d secs]" % seconds]
- text = "\n".join(self.text + etatext)
- self.statusSquare.set_text(text)
- def updateTextTimer(self):
- self.updateText()
- return gtk.TRUE # restart timer
-
- def remote_progress(self, seconds):
- if seconds == None:
- self.eta = None
- else:
- self.eta = now() + seconds
- self.startTimer(self.updateTextTimer)
- self.updateText()
- def remote_finished(self, eta):
- self.eta = None
- self.stopTimer()
- self.updateText()
- eta.callRemote("unsubscribe", self)
-'''
-
-class Box:
- def __init__(self, text="?"):
- self.text = text
- self.box = gtk.EventBox()
- self.label = gtk.Label(text)
- self.box.add(self.label)
- self.box.set_size_request(64,64)
- self.timer = None
-
- def getBox(self):
- return self.box
-
- def setText(self, text):
- self.text = text
- self.label.set_text(text)
-
- def setColor(self, color):
- if not color:
- return
- self.box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-
- def setETA(self, eta):
- if eta:
- self.when = now() + eta
- self.startTimer()
- else:
- self.stopTimer()
-
- def startTimer(self):
- self.stopTimer()
- self.timer = gobject.timeout_add(1000, self.update)
- self.update()
-
- def stopTimer(self):
- if self.timer:
- gobject.source_remove(self.timer)
- self.timer = None
- self.label.set_text(self.text)
-
- def update(self):
- if now() < self.when:
- next = time.strftime("%H:%M:%S", time.localtime(self.when))
- secs = "[%d secs]" % (self.when - now())
- self.label.set_text("%s\n%s\n%s" % (self.text, next, secs))
- return True # restart timer
- else:
- # done
- self.label.set_text("%s\n[soon]\n[overdue]" % (self.text,))
- self.timer = None
- return False
-
-
-
-class ThreeRowBuilder:
- def __init__(self, name, ref):
- self.name = name
-
- self.last = Box()
- self.current = Box()
- self.step = Box("idle")
- self.step.setColor("white")
-
- self.ref = ref
-
- def getBoxes(self):
- return self.last.getBox(), self.current.getBox(), self.step.getBox()
-
- def getLastBuild(self):
- d = self.ref.callRemote("getLastFinishedBuild")
- d.addCallback(self.gotLastBuild)
- def gotLastBuild(self, build):
- if build:
- build.callRemote("getText").addCallback(self.gotLastText)
- build.callRemote("getResults").addCallback(self.gotLastResult)
-
- def gotLastText(self, text):
- print "Got text", text
- self.last.setText("\n".join(text))
-
- def gotLastResult(self, result):
- colormap = {SUCCESS: 'green',
- FAILURE: 'red',
- WARNINGS: 'orange',
- EXCEPTION: 'purple',
- }
- self.last.setColor(colormap[result])
-
- def getState(self):
- self.ref.callRemote("getState").addCallback(self.gotState)
- def gotState(self, res):
- state, ETA, builds = res
- # state is one of: offline, idle, waiting, interlocked, building
- # TODO: ETA is going away, you have to look inside the builds to get
- # that value
- currentmap = {"offline": "red",
- "idle": "white",
- "waiting": "yellow",
- "interlocked": "yellow",
- "building": "yellow",}
- text = state
- self.current.setColor(currentmap[state])
- if ETA is not None:
- text += "\nETA=%s secs" % ETA
- self.current.setText(state)
-
- def buildStarted(self, build):
- print "[%s] buildStarted" % (self.name,)
- self.current.setColor("yellow")
-
- def buildFinished(self, build, results):
- print "[%s] buildFinished: %s" % (self.name, results)
- self.gotLastBuild(build)
- self.current.setColor("white")
- self.current.stopTimer()
-
- def buildETAUpdate(self, eta):
- print "[%s] buildETAUpdate: %s" % (self.name, eta)
- self.current.setETA(eta)
-
-
- def stepStarted(self, stepname, step):
- print "[%s] stepStarted: %s" % (self.name, stepname)
- self.step.setText(stepname)
- self.step.setColor("yellow")
- def stepFinished(self, stepname, step, results):
- print "[%s] stepFinished: %s %s" % (self.name, stepname, results)
- self.step.setText("idle")
- self.step.setColor("white")
- self.step.stopTimer()
- def stepETAUpdate(self, stepname, eta):
- print "[%s] stepETAUpdate: %s %s" % (self.name, stepname, eta)
- self.step.setETA(eta)
-
-
-class ThreeRowClient(pb.Referenceable):
- def __init__(self, window):
- self.window = window
- self.buildernames = []
- self.builders = {}
-
- def connected(self, ref):
- print "connected"
- self.ref = ref
- self.pane = gtk.VBox(False, 2)
- self.table = gtk.Table(1+3, 1)
- self.pane.add(self.table)
- self.window.vb.add(self.pane)
- self.pane.show_all()
- ref.callRemote("subscribe", "logs", 5, self)
-
- def removeTable(self):
- for child in self.table.get_children():
- self.table.remove(child)
- self.pane.remove(self.table)
-
- def makeTable(self):
- columns = len(self.builders)
- self.table = gtk.Table(2, columns)
- self.pane.add(self.table)
- for i in range(len(self.buildernames)):
- name = self.buildernames[i]
- b = self.builders[name]
- last,current,step = b.getBoxes()
- self.table.attach(gtk.Label(name), i, i+1, 0, 1)
- self.table.attach(last, i, i+1, 1, 2,
- xpadding=1, ypadding=1)
- self.table.attach(current, i, i+1, 2, 3,
- xpadding=1, ypadding=1)
- self.table.attach(step, i, i+1, 3, 4,
- xpadding=1, ypadding=1)
- self.table.show_all()
-
- def rebuildTable(self):
- self.removeTable()
- self.makeTable()
-
- def remote_builderAdded(self, buildername, builder):
- print "builderAdded", buildername
- assert buildername not in self.buildernames
- self.buildernames.append(buildername)
-
- b = ThreeRowBuilder(buildername, builder)
- self.builders[buildername] = b
- self.rebuildTable()
- b.getLastBuild()
- b.getState()
-
- def remote_builderRemoved(self, buildername):
- del self.builders[buildername]
- self.buildernames.remove(buildername)
- self.rebuildTable()
-
- def remote_builderChangedState(self, name, state, eta):
- self.builders[name].gotState((state, eta, None))
- def remote_buildStarted(self, name, build):
- self.builders[name].buildStarted(build)
- def remote_buildFinished(self, name, build, results):
- self.builders[name].buildFinished(build, results)
-
- def remote_buildETAUpdate(self, name, build, eta):
- self.builders[name].buildETAUpdate(eta)
- def remote_stepStarted(self, name, build, stepname, step):
- self.builders[name].stepStarted(stepname, step)
- def remote_stepFinished(self, name, build, stepname, step, results):
- self.builders[name].stepFinished(stepname, step, results)
-
- def remote_stepETAUpdate(self, name, build, stepname, step,
- eta, expectations):
- # expectations is a list of (metricname, current_value,
- # expected_value) tuples, so that we could show individual progress
- # meters for each metric
- self.builders[name].stepETAUpdate(stepname, eta)
-
- def remote_logStarted(self, buildername, build, stepname, step,
- logname, log):
- pass
-
- def remote_logFinished(self, buildername, build, stepname, step,
- logname, log):
- pass
-
-
-class GtkClient(TextClient):
- ClientClass = ThreeRowClient
-
- def __init__(self, master, events="steps", username="statusClient", passwd="clientpw"):
- self.master = master
- self.username = username
- self.passwd = passwd
- self.listener = StatusClient(events)
-
- w = gtk.Window()
- self.w = w
- #w.set_size_request(64,64)
- w.connect('destroy', lambda win: gtk.main_quit())
- self.vb = gtk.VBox(False, 2)
- self.status = gtk.Label("unconnected")
- self.vb.add(self.status)
- self.listener = self.ClientClass(self)
- w.add(self.vb)
- w.show_all()
-
- def connected(self, ref):
- self.status.set_text("connected")
- TextClient.connected(self, ref)
-
-"""
- def addBuilder(self, name, builder):
- Client.addBuilder(self, name, builder)
- self.pane.addBuilder(builder)
- def removeBuilder(self, name):
- self.pane.removeBuilder(name, self.builders[name])
- Client.removeBuilder(self, name)
-
- def startConnecting(self, master):
- self.master = master
- Client.startConnecting(self, master)
- self.status.set_text("connecting to %s.." % master)
- def connected(self, remote):
- Client.connected(self, remote)
- self.status.set_text(self.master)
- remote.notifyOnDisconnect(self.disconnected)
- def disconnected(self, remote):
- self.status.set_text("disconnected, will retry")
-"""
-
-def main():
- master = "localhost:8007"
- if len(sys.argv) > 1:
- master = sys.argv[1]
- c = GtkClient(master)
- c.run()
-
-if __name__ == '__main__':
- main()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py
deleted file mode 100644
index daae63b5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.spread import pb
-from twisted.cred import credentials
-from twisted.internet import reactor
-
-class Sender:
- def __init__(self, master, auth=('change','changepw'), encoding='utf8'):
- self.username, self.password = auth
- self.host, self.port = master.split(":")
- self.port = int(self.port)
- self.encoding = encoding
-
- def send(self, branch, revision, comments, files, who=None, category=None,
- when=None, properties={}, repository='', vc=None, project='',
- revlink='', codebase=None):
- change = {'project': project, 'repository': repository, 'who': who,
- 'files': files, 'comments': comments, 'branch': branch,
- 'revision': revision, 'category': category, 'when': when,
- 'properties': properties, 'revlink': revlink, 'src': vc}
-
- # codebase is only sent if set; this won't work with masters older than
- # 0.8.7
- if codebase:
- change['codebase'] = codebase
-
- for key in change:
- if type(change[key]) == str:
- change[key] = change[key].decode(self.encoding, 'replace')
- change['files'] = list(change['files'])
- for i, file in enumerate(change.get('files', [])):
- if type(file) == str:
- change['files'][i] = file.decode(self.encoding, 'replace')
-
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(self.username, self.password))
- reactor.connectTCP(self.host, self.port, f)
-
- def call_addChange(remote):
- d = remote.callRemote('addChange', change)
- d.addCallback(lambda res: remote.broker.transport.loseConnection())
- return d
- d.addCallback(call_addChange)
-
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py
deleted file mode 100644
index 77a430ee..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import re
-
-from twisted.spread import pb
-from twisted.cred import credentials, error
-from twisted.internet import reactor
-from buildbot.clients import base
-
-class TextClient:
- def __init__(self, master, events="steps", username="statusClient", passwd="clientpw"):
- """
- @type master: string
- @param master: a host:port string to masters L{buildbot.status.client.PBListener}
-
- @type username: string
- @param username:
-
- @type passwd: string
- @param passwd:
-
- @type events: string, one of builders, builds, steps, logs, full
- @param events: specify what level of detail should be reported.
- - 'builders': only announce new/removed Builders
- - 'builds': also announce builderChangedState, buildStarted, and
- buildFinished
- - 'steps': also announce buildETAUpdate, stepStarted, stepFinished
- - 'logs': also announce stepETAUpdate, logStarted, logFinished
- - 'full': also announce log contents
- """
- self.master = master
- self.username = username
- self.passwd = passwd
- self.listener = base.StatusClient(events)
-
- def run(self):
- """Start the TextClient."""
- self.startConnecting()
- reactor.run()
-
- def startConnecting(self):
- try:
- host, port = re.search(r'(.+):(\d+)', self.master).groups()
- port = int(port)
- except:
- print "unparseable master location '%s'" % self.master
- print " expecting something more like localhost:8007"
- raise
- cf = pb.PBClientFactory()
- creds = credentials.UsernamePassword(self.username, self.passwd)
- d = cf.login(creds)
- reactor.connectTCP(host, port, cf)
- d.addCallbacks(self.connected, self.not_connected)
- return d
- def connected(self, ref):
- ref.notifyOnDisconnect(self.disconnected)
- self.listener.connected(ref)
- def not_connected(self, why):
- if why.check(error.UnauthorizedLogin):
- print """
-Unable to login.. are you sure we are connecting to a
-buildbot.status.client.PBListener port and not to the slaveport?
-"""
- reactor.stop()
- return why
- def disconnected(self, ref):
- print "lost connection"
- # we can get here in one of two ways: the buildmaster has
- # disconnected us (probably because it shut itself down), or because
- # we've been SIGINT'ed. In the latter case, our reactor is already
- # shut down, but we have no easy way of detecting that. So protect
- # our attempt to shut down the reactor.
- try:
- reactor.stop()
- except RuntimeError:
- pass
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py
deleted file mode 100644
index d48f8088..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py
+++ /dev/null
@@ -1,891 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-import os
-import random
-import re
-import sys
-import time
-
-from twisted.cred import credentials
-from twisted.internet import defer
-from twisted.internet import protocol
-from twisted.internet import reactor
-from twisted.internet import task
-from twisted.internet import utils
-from twisted.python import log
-from twisted.python.procutils import which
-from twisted.spread import pb
-
-from buildbot.sourcestamp import SourceStamp
-from buildbot.status import builder
-from buildbot.util import json
-from buildbot.util import now
-from buildbot.util.eventual import fireEventually
-
-
-class SourceStampExtractor:
-
- def __init__(self, treetop, branch, repository):
- self.treetop = treetop
- self.repository = repository
- self.branch = branch
- exes = which(self.vcexe)
- if not exes:
- print "Could not find executable '%s'." % self.vcexe
- sys.exit(1)
- self.exe = exes[0]
-
- def dovc(self, cmd):
- """This accepts the arguments of a command, without the actual
- command itself."""
- env = os.environ.copy()
- env['LC_ALL'] = "C"
- d = utils.getProcessOutputAndValue(self.exe, cmd, env=env,
- path=self.treetop)
- d.addCallback(self._didvc, cmd)
- return d
-
- def _didvc(self, res, cmd):
- (stdout, stderr, code) = res
- # 'bzr diff' sets rc=1 if there were any differences.
- # cvs does something similar, so don't bother requring rc=0.
- return stdout
-
- def get(self):
- """Return a Deferred that fires with a SourceStamp instance."""
- d = self.getBaseRevision()
- d.addCallback(self.getPatch)
- d.addCallback(self.done)
- return d
-
- def readPatch(self, diff, patchlevel):
- if not diff:
- diff = None
- self.patch = (patchlevel, diff)
-
- def done(self, res):
- if not self.repository:
- self.repository = self.treetop
- # TODO: figure out the branch and project too
- ss = SourceStamp(self.branch, self.baserev, self.patch,
- repository=self.repository)
- return ss
-
-
-class CVSExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "cvs"
-
- def getBaseRevision(self):
- # this depends upon our local clock and the repository's clock being
- # reasonably synchronized with each other. We express everything in
- # UTC because the '%z' format specifier for strftime doesn't always
- # work.
- self.baserev = time.strftime("%Y-%m-%d %H:%M:%S +0000",
- time.gmtime(now()))
- return defer.succeed(None)
-
- def getPatch(self, res):
- # the -q tells CVS to not announce each directory as it works
- if self.branch is not None:
- # 'cvs diff' won't take both -r and -D at the same time (it
- # ignores the -r). As best I can tell, there is no way to make
- # cvs give you a diff relative to a timestamp on the non-trunk
- # branch. A bare 'cvs diff' will tell you about the changes
- # relative to your checked-out versions, but I know of no way to
- # find out what those checked-out versions are.
- print "Sorry, CVS 'try' builds don't work with branches"
- sys.exit(1)
- args = ['-q', 'diff', '-u', '-D', self.baserev]
- d = self.dovc(args)
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class SVNExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "svn"
-
- def getBaseRevision(self):
- d = self.dovc(["status", "-u"])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, res):
- # svn shows the base revision for each file that has been modified or
- # which needs an update. You can update each file to a different
- # version, so each file is displayed with its individual base
- # revision. It also shows the repository-wide latest revision number
- # on the last line ("Status against revision: \d+").
-
- # for our purposes, we use the latest revision number as the "base"
- # revision, and get a diff against that. This means we will get
- # reverse-diffs for local files that need updating, but the resulting
- # tree will still be correct. The only weirdness is that the baserev
- # that we emit may be different than the version of the tree that we
- # first checked out.
-
- # to do this differently would probably involve scanning the revision
- # numbers to find the max (or perhaps the min) revision, and then
- # using that as a base.
-
- for line in res.split("\n"):
- m = re.search(r'^Status against revision:\s+(\d+)', line)
- if m:
- self.baserev = int(m.group(1))
- return
- print "Could not find 'Status against revision' in SVN output: %s" % res
- sys.exit(1)
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-r%d" % self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class BzrExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "bzr"
-
- def getBaseRevision(self):
- d = self.dovc(["revision-info", "-rsubmit:"])
- d.addCallback(self.get_revision_number)
- return d
-
- def get_revision_number(self, out):
- revno, revid = out.split()
- self.baserev = 'revid:' + revid
- return
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-r%s.." % self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class MercurialExtractor(SourceStampExtractor):
- patchlevel = 1
- vcexe = "hg"
-
- def getBaseRevision(self):
- upstream = ""
- if self.repository:
- upstream = "r'%s'" % self.repository
- d = self.dovc(["log", "--template", "{node}\\n", "-r", "limit(parents(outgoing(%s) and branch(parents())) or parents(), 1)" % upstream])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, output):
- m = re.search(r'^(\w+)', output)
- self.baserev = m.group(0)
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-r", self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class PerforceExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "p4"
-
- def getBaseRevision(self):
- d = self.dovc(["changes", "-m1", "..."])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, res):
- #
- # extract the base change number
- #
- m = re.search(r'Change (\d+)', res)
- if m:
- self.baserev = m.group(1)
- return
-
- print "Could not find change number in output: %s" % res
- sys.exit(1)
-
- def readPatch(self, res, patchlevel):
- #
- # extract the actual patch from "res"
- #
- if not self.branch:
- print "you must specify a branch"
- sys.exit(1)
- mpatch = ""
- found = False
- for line in res.split("\n"):
- m = re.search('==== //depot/' + self.branch
- + r'/([\w\/\.\d\-\_]+)#(\d+) -', line)
- if m:
- mpatch += "--- %s#%s\n" % (m.group(1), m.group(2))
- mpatch += "+++ %s\n" % (m.group(1))
- found = True
- else:
- mpatch += line
- mpatch += "\n"
- if not found:
- print "could not parse patch file"
- sys.exit(1)
- self.patch = (patchlevel, mpatch)
-
- def getPatch(self, res):
- d = self.dovc(["diff"])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class DarcsExtractor(SourceStampExtractor):
- patchlevel = 1
- vcexe = "darcs"
-
- def getBaseRevision(self):
- d = self.dovc(["changes", "--context"])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, res):
- self.baserev = res # the whole context file
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-u"])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class GitExtractor(SourceStampExtractor):
- patchlevel = 1
- vcexe = "git"
- config = None
-
- def getBaseRevision(self):
- # If a branch is specified, parse out the rev it points to
- # and extract the local name (assuming it has a slash).
- # This may break if someone specifies the name of a local
- # branch that has a slash in it and has no corresponding
- # remote branch (or something similarly contrived).
- if self.branch:
- d = self.dovc(["rev-parse", self.branch])
- if '/' in self.branch:
- self.branch = self.branch.split('/', 1)[1]
- d.addCallback(self.override_baserev)
- return d
- d = self.dovc(["branch", "--no-color", "-v", "--no-abbrev"])
- d.addCallback(self.parseStatus)
- return d
-
- def readConfig(self):
- if self.config:
- return defer.succeed(self.config)
- d = self.dovc(["config", "-l"])
- d.addCallback(self.parseConfig)
- return d
-
- def parseConfig(self, res):
- self.config = {}
- for l in res.split("\n"):
- if l.strip():
- parts = l.strip().split("=", 2)
- self.config[parts[0]] = parts[1]
- return self.config
-
- def parseTrackingBranch(self, res):
- # If we're tracking a remote, consider that the base.
- remote = self.config.get("branch." + self.branch + ".remote")
- ref = self.config.get("branch." + self.branch + ".merge")
- if remote and ref:
- remote_branch = ref.split("/", 3)[-1]
- d = self.dovc(["rev-parse", remote + "/" + remote_branch])
- d.addCallback(self.override_baserev)
- return d
-
- def override_baserev(self, res):
- self.baserev = res.strip()
-
- def parseStatus(self, res):
- # The current branch is marked by '*' at the start of the
- # line, followed by the branch name and the SHA1.
- #
- # Branch names may contain pretty much anything but whitespace.
- m = re.search(r'^\* (\S+)\s+([0-9a-f]{40})', res, re.MULTILINE)
- if m:
- self.baserev = m.group(2)
- self.branch = m.group(1)
- d = self.readConfig()
- d.addCallback(self.parseTrackingBranch)
- return d
- print "Could not find current GIT branch: %s" % res
- sys.exit(1)
-
- def getPatch(self, res):
- d = self.dovc(["diff", self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class MonotoneExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "mtn"
-
- def getBaseRevision(self):
- d = self.dovc(["automate", "get_base_revision_id"])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, output):
- hash = output.strip()
- if len(hash) != 40:
- self.baserev = None
- self.baserev = hash
-
- def getPatch(self, res):
- d = self.dovc(["diff"])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-def getSourceStamp(vctype, treetop, branch=None, repository=None):
- if vctype == "cvs":
- cls = CVSExtractor
- elif vctype == "svn":
- cls = SVNExtractor
- elif vctype == "bzr":
- cls = BzrExtractor
- elif vctype == "hg":
- cls = MercurialExtractor
- elif vctype == "p4":
- cls = PerforceExtractor
- elif vctype == "darcs":
- cls = DarcsExtractor
- elif vctype == "git":
- cls = GitExtractor
- elif vctype == "mtn":
- cls = MonotoneExtractor
- else:
- print "unknown vctype '%s'" % vctype
- sys.exit(1)
- return cls(treetop, branch, repository).get()
-
-
-def ns(s):
- return "%d:%s," % (len(s), s)
-
-
-def createJobfile(jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties):
- #Determine job file version from provided arguments
- if properties:
- version = 5
- elif comment:
- version = 4
- elif who:
- version = 3
- else:
- version = 2
- job = ""
- job += ns(str(version))
- if version < 5:
- job += ns(jobid)
- job += ns(branch)
- job += ns(str(baserev))
- job += ns("%d" % patch_level)
- job += ns(patch_body)
- job += ns(repository)
- job += ns(project)
- if (version >= 3):
- job += ns(who)
- if (version >= 4):
- job += ns(comment)
- for bn in builderNames:
- job += ns(bn)
- else:
- job += ns(
- json.dumps({
- 'jobid': jobid, 'branch': branch, 'baserev': str(baserev),
- 'patch_level': patch_level, 'patch_body': patch_body,
- 'repository': repository, 'project': project, 'who': who,
- 'comment': comment, 'builderNames': builderNames,
- 'properties': properties,
- }))
- return job
-
-
-def getTopdir(topfile, start=None):
- """walk upwards from the current directory until we find this topfile"""
- if not start:
- start = os.getcwd()
- here = start
- toomany = 20
- while toomany > 0:
- if os.path.exists(os.path.join(here, topfile)):
- return here
- next = os.path.dirname(here)
- if next == here:
- break # we've hit the root
- here = next
- toomany -= 1
- print ("Unable to find topfile '%s' anywhere from %s upwards"
- % (topfile, start))
- sys.exit(1)
-
-
-class RemoteTryPP(protocol.ProcessProtocol):
- def __init__(self, job):
- self.job = job
- self.d = defer.Deferred()
-
- def connectionMade(self):
- self.transport.write(self.job)
- self.transport.closeStdin()
-
- def outReceived(self, data):
- sys.stdout.write(data)
-
- def errReceived(self, data):
- sys.stderr.write(data)
-
- def processEnded(self, status_object):
- sig = status_object.value.signal
- rc = status_object.value.exitCode
- if sig != None or rc != 0:
- self.d.errback(RuntimeError("remote 'buildbot tryserver' failed"
- ": sig=%s, rc=%s" % (sig, rc)))
- return
- self.d.callback((sig, rc))
-
-
-class BuildSetStatusGrabber:
- retryCount = 5 # how many times to we try to grab the BuildSetStatus?
- retryDelay = 3 # seconds to wait between attempts
-
- def __init__(self, status, bsid):
- self.status = status
- self.bsid = bsid
-
- def grab(self):
- # return a Deferred that either fires with the BuildSetStatus
- # reference or errbacks because we were unable to grab it
- self.d = defer.Deferred()
- # wait a second before querying to give the master's maildir watcher
- # a chance to see the job
- reactor.callLater(1, self.go)
- return self.d
-
- def go(self, dummy=None):
- if self.retryCount == 0:
- print "couldn't find matching buildset"
- sys.exit(1)
- self.retryCount -= 1
- d = self.status.callRemote("getBuildSets")
- d.addCallback(self._gotSets)
-
- def _gotSets(self, buildsets):
- for bs, bsid in buildsets:
- if bsid == self.bsid:
- # got it
- self.d.callback(bs)
- return
- d = defer.Deferred()
- d.addCallback(self.go)
- reactor.callLater(self.retryDelay, d.callback, None)
-
-
-class Try(pb.Referenceable):
- buildsetStatus = None
- quiet = False
- printloop = False
-
- def __init__(self, config):
- self.config = config
- self.connect = self.getopt('connect')
- if self.connect not in ['ssh', 'pb']:
- print "you must specify a connect style: ssh or pb"
- sys.exit(1)
- self.builderNames = self.getopt('builders')
- self.project = self.getopt('project', '')
- self.who = self.getopt('who')
- self.comment = self.getopt('comment')
-
- def getopt(self, config_name, default=None):
- value = self.config.get(config_name)
- if value is None or value == []:
- value = default
- return value
-
- def createJob(self):
- # returns a Deferred which fires when the job parameters have been
- # created
-
- # generate a random (unique) string. It would make sense to add a
- # hostname and process ID here, but a) I suspect that would cause
- # windows portability problems, and b) really this is good enough
- self.bsid = "%d-%s" % (time.time(), random.randint(0, 1000000))
-
- # common options
- branch = self.getopt("branch")
-
- difffile = self.config.get("diff")
- if difffile:
- baserev = self.config.get("baserev")
- if difffile == "-":
- diff = sys.stdin.read()
- else:
- with open(difffile, "r") as f:
- diff = f.read()
- if not diff:
- diff = None
- patch = (self.config['patchlevel'], diff)
- ss = SourceStamp(
- branch, baserev, patch, repository=self.getopt("repository"))
- d = defer.succeed(ss)
- else:
- vc = self.getopt("vc")
- if vc in ("cvs", "svn"):
- # we need to find the tree-top
- topdir = self.getopt("topdir")
- if topdir:
- treedir = os.path.expanduser(topdir)
- else:
- topfile = self.getopt("topfile")
- if topfile:
- treedir = getTopdir(topfile)
- else:
- print "Must specify topdir or topfile."
- sys.exit(1)
- else:
- treedir = os.getcwd()
- d = getSourceStamp(vc, treedir, branch, self.getopt("repository"))
- d.addCallback(self._createJob_1)
- return d
-
- def _createJob_1(self, ss):
- self.sourcestamp = ss
- if self.connect == "ssh":
- patchlevel, diff = ss.patch
- revspec = ss.revision
- if revspec is None:
- revspec = ""
- self.jobfile = createJobfile(
- self.bsid, ss.branch or "", revspec, patchlevel, diff,
- ss.repository, self.project, self.who, self.comment,
- self.builderNames, self.config.get('properties', {}))
-
- def fakeDeliverJob(self):
- # Display the job to be delivered, but don't perform delivery.
- ss = self.sourcestamp
- print ("Job:\n\tRepository: %s\n\tProject: %s\n\tBranch: %s\n\t"
- "Revision: %s\n\tBuilders: %s\n%s"
- % (ss.repository, self.project, ss.branch,
- ss.revision,
- self.builderNames,
- ss.patch[1]))
- d = defer.Deferred()
- d.callback(True)
- return d
-
- def deliverJob(self):
- # returns a Deferred that fires when the job has been delivered
- if self.connect == "ssh":
- tryhost = self.getopt("host")
- tryuser = self.getopt("username")
- trydir = self.getopt("jobdir")
- buildbotbin = self.getopt("buildbotbin")
- argv = ["ssh", "-l", tryuser, tryhost,
- buildbotbin, "tryserver", "--jobdir", trydir]
- pp = RemoteTryPP(self.jobfile)
- reactor.spawnProcess(pp, argv[0], argv, os.environ)
- d = pp.d
- return d
- if self.connect == "pb":
- user = self.getopt("username")
- passwd = self.getopt("passwd")
- master = self.getopt("master")
- tryhost, tryport = master.split(":")
- tryport = int(tryport)
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(user, passwd))
- reactor.connectTCP(tryhost, tryport, f)
- d.addCallback(self._deliverJob_pb)
- return d
- raise RuntimeError("unknown connecttype '%s', should be 'ssh' or 'pb'"
- % self.connect)
-
- def _deliverJob_pb(self, remote):
- ss = self.sourcestamp
- print "Delivering job; comment=", self.comment
-
- d = remote.callRemote("try",
- ss.branch,
- ss.revision,
- ss.patch,
- ss.repository,
- self.project,
- self.builderNames,
- self.who,
- self.comment,
- self.config.get('properties', {}))
- d.addCallback(self._deliverJob_pb2)
- return d
-
- def _deliverJob_pb2(self, status):
- self.buildsetStatus = status
- return status
-
- def getStatus(self):
- # returns a Deferred that fires when the builds have finished, and
- # may emit status messages while we wait
- wait = bool(self.getopt("wait"))
- if not wait:
- # TODO: emit the URL where they can follow the builds. This
- # requires contacting the Status server over PB and doing
- # getURLForThing() on the BuildSetStatus. To get URLs for
- # individual builds would require we wait for the builds to
- # start.
- print "not waiting for builds to finish"
- return
- d = self.running = defer.Deferred()
- if self.buildsetStatus:
- self._getStatus_1()
- return self.running
- # contact the status port
- # we're probably using the ssh style
- master = self.getopt("master")
- host, port = master.split(":")
- port = int(port)
- self.announce("contacting the status port at %s:%d" % (host, port))
- f = pb.PBClientFactory()
- creds = credentials.UsernamePassword("statusClient", "clientpw")
- d = f.login(creds)
- reactor.connectTCP(host, port, f)
- d.addCallback(self._getStatus_ssh_1)
- return self.running
-
- def _getStatus_ssh_1(self, remote):
- # find a remotereference to the corresponding BuildSetStatus object
- self.announce("waiting for job to be accepted")
- g = BuildSetStatusGrabber(remote, self.bsid)
- d = g.grab()
- d.addCallback(self._getStatus_1)
- return d
-
- def _getStatus_1(self, res=None):
- if res:
- self.buildsetStatus = res
- # gather the set of BuildRequests
- d = self.buildsetStatus.callRemote("getBuildRequests")
- d.addCallback(self._getStatus_2)
-
- def _getStatus_2(self, brs):
- self.builderNames = []
- self.buildRequests = {}
-
- # self.builds holds the current BuildStatus object for each one
- self.builds = {}
-
- # self.outstanding holds the list of builderNames which haven't
- # finished yet
- self.outstanding = []
-
- # self.results holds the list of build results. It holds a tuple of
- # (result, text)
- self.results = {}
-
- # self.currentStep holds the name of the Step that each build is
- # currently running
- self.currentStep = {}
-
- # self.ETA holds the expected finishing time (absolute time since
- # epoch)
- self.ETA = {}
-
- for n, br in brs:
- self.builderNames.append(n)
- self.buildRequests[n] = br
- self.builds[n] = None
- self.outstanding.append(n)
- self.results[n] = [None, None]
- self.currentStep[n] = None
- self.ETA[n] = None
- # get new Builds for this buildrequest. We follow each one until
- # it finishes or is interrupted.
- br.callRemote("subscribe", self)
-
- # now that those queries are in transit, we can start the
- # display-status-every-30-seconds loop
- if not self.getopt("quiet"):
- self.printloop = task.LoopingCall(self.printStatus)
- self.printloop.start(3, now=False)
-
- # these methods are invoked by the status objects we've subscribed to
-
- def remote_newbuild(self, bs, builderName):
- if self.builds[builderName]:
- self.builds[builderName].callRemote("unsubscribe", self)
- self.builds[builderName] = bs
- bs.callRemote("subscribe", self, 20)
- d = bs.callRemote("waitUntilFinished")
- d.addCallback(self._build_finished, builderName)
-
- def remote_stepStarted(self, buildername, build, stepname, step):
- self.currentStep[buildername] = stepname
-
- def remote_stepFinished(self, buildername, build, stepname, step, results):
- pass
-
- def remote_buildETAUpdate(self, buildername, build, eta):
- self.ETA[buildername] = now() + eta
-
- def _build_finished(self, bs, builderName):
- # we need to collect status from the newly-finished build. We don't
- # remove the build from self.outstanding until we've collected
- # everything we want.
- self.builds[builderName] = None
- self.ETA[builderName] = None
- self.currentStep[builderName] = "finished"
- d = bs.callRemote("getResults")
- d.addCallback(self._build_finished_2, bs, builderName)
- return d
-
- def _build_finished_2(self, results, bs, builderName):
- self.results[builderName][0] = results
- d = bs.callRemote("getText")
- d.addCallback(self._build_finished_3, builderName)
- return d
-
- def _build_finished_3(self, text, builderName):
- self.results[builderName][1] = text
-
- self.outstanding.remove(builderName)
- if not self.outstanding:
- # all done
- return self.statusDone()
-
- def printStatus(self):
- try:
- names = self.buildRequests.keys()
- names.sort()
- for n in names:
- if n not in self.outstanding:
- # the build is finished, and we have results
- code, text = self.results[n]
- t = builder.Results[code]
- if text:
- t += " (%s)" % " ".join(text)
- elif self.builds[n]:
- t = self.currentStep[n] or "building"
- if self.ETA[n]:
- t += " [ETA %ds]" % (self.ETA[n] - now())
- else:
- t = "no build"
- self.announce("%s: %s" % (n, t))
- self.announce("")
- except Exception:
- log.err(None, "printing status")
-
- def statusDone(self):
- if self.printloop:
- self.printloop.stop()
- print "All Builds Complete"
- # TODO: include a URL for all failing builds
- names = self.buildRequests.keys()
- names.sort()
- happy = True
- for n in names:
- code, text = self.results[n]
- t = "%s: %s" % (n, builder.Results[code])
- if text:
- t += " (%s)" % " ".join(text)
- print t
- if code != builder.SUCCESS:
- happy = False
-
- if happy:
- self.exitcode = 0
- else:
- self.exitcode = 1
- self.running.callback(self.exitcode)
-
- def getAvailableBuilderNames(self):
- # This logs into the master using the PB protocol to
- # get the names of the configured builders that can
- # be used for the --builder argument
- if self.connect == "pb":
- user = self.getopt("username")
- passwd = self.getopt("passwd")
- master = self.getopt("master")
- tryhost, tryport = master.split(":")
- tryport = int(tryport)
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(user, passwd))
- reactor.connectTCP(tryhost, tryport, f)
- d.addCallback(self._getBuilderNames, self._getBuilderNames2)
- return d
- if self.connect == "ssh":
- print "Cannot get availble builders over ssh."
- sys.exit(1)
- raise RuntimeError(
- "unknown connecttype '%s', should be 'pb'" % self.connect)
-
- def _getBuilderNames(self, remote, output):
- d = remote.callRemote("getAvailableBuilderNames")
- d.addCallback(self._getBuilderNames2)
- return d
-
- def _getBuilderNames2(self, buildernames):
- print "The following builders are available for the try scheduler: "
- for buildername in buildernames:
- print buildername
-
- def announce(self, message):
- if not self.quiet:
- print message
-
- def run(self):
- # we can't do spawnProcess until we're inside reactor.run(), so get
- # funky
- print "using '%s' connect method" % self.connect
- self.exitcode = 0
- d = fireEventually(None)
- if bool(self.config.get("get-builder-names")):
- d.addCallback(lambda res: self.getAvailableBuilderNames())
- else:
- d.addCallback(lambda res: self.createJob())
- d.addCallback(lambda res: self.announce("job created"))
- deliver = self.deliverJob
- if bool(self.config.get("dryrun")):
- deliver = self.fakeDeliverJob
- d.addCallback(lambda res: deliver())
- d.addCallback(lambda res: self.announce("job has been delivered"))
- d.addCallback(lambda res: self.getStatus())
- d.addErrback(self.trapSystemExit)
- d.addErrback(log.err)
- d.addCallback(self.cleanup)
- d.addCallback(lambda res: reactor.stop())
-
- reactor.run()
- sys.exit(self.exitcode)
-
- def trapSystemExit(self, why):
- why.trap(SystemExit)
- self.exitcode = why.value.code
-
- def cleanup(self, res=None):
- if self.buildsetStatus:
- self.buildsetStatus.broker.transport.loseConnection()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py
deleted file mode 100644
index 45ca62d5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# this class is known to contain cruft and will be looked at later, so
-# no current implementation utilizes it aside from scripts.runner.
-
-from twisted.spread import pb
-from twisted.cred import credentials
-from twisted.internet import reactor
-
-class UsersClient(object):
- """
- Client set up in buildbot.scripts.runner to send `buildbot user` args
- over a PB connection to perspective_commandline that will execute the
- args on the database.
- """
-
- def __init__(self, master, username, password, port):
- self.host = master
- self.username = username
- self.password = password
- self.port = int(port)
-
- def send(self, op, bb_username, bb_password, ids, info):
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(self.username, self.password))
- reactor.connectTCP(self.host, self.port, f)
-
- def call_commandline(remote):
- d = remote.callRemote("commandline", op, bb_username,
- bb_password, ids, info)
- def returnAndLose(res):
- remote.broker.transport.loseConnection()
- return res
- d.addCallback(returnAndLose)
- return d
- d.addCallback(call_commandline)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py
deleted file mode 100644
index e8632b2e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py
+++ /dev/null
@@ -1,730 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import re
-import sys
-import warnings
-from buildbot.util import safeTranslate
-from buildbot import interfaces
-from buildbot import locks
-from buildbot.revlinks import default_revlink_matcher
-from twisted.python import log, failure
-from twisted.internet import defer
-from twisted.application import service
-
-class ConfigErrors(Exception):
-
- def __init__(self, errors=[]):
- self.errors = errors[:]
-
- def __str__(self):
- return "\n".join(self.errors)
-
- def addError(self, msg):
- self.errors.append(msg)
-
- def __nonzero__(self):
- return len(self.errors)
-
-_errors = None
-def error(error):
- if _errors is not None:
- _errors.addError(error)
- else:
- raise ConfigErrors([error])
-
-class MasterConfig(object):
-
- def __init__(self):
- # local import to avoid circular imports
- from buildbot.process import properties
- # default values for all attributes
-
- # global
- self.title = 'Buildbot'
- self.titleURL = 'http://buildbot.net'
- self.buildbotURL = 'http://localhost:8080/'
- self.changeHorizon = None
- self.eventHorizon = 50
- self.logHorizon = None
- self.buildHorizon = None
- self.logCompressionLimit = 4*1024
- self.logCompressionMethod = 'bz2'
- self.logMaxTailSize = None
- self.logMaxSize = None
- self.properties = properties.Properties()
- self.mergeRequests = None
- self.codebaseGenerator = None
- self.prioritizeBuilders = None
- self.slavePortnum = None
- self.multiMaster = False
- self.debugPassword = None
- self.manhole = None
-
- self.validation = dict(
- branch=re.compile(r'^[\w.+/~-]*$'),
- revision=re.compile(r'^[ \w\.\-\/]*$'),
- property_name=re.compile(r'^[\w\.\-\/\~:]*$'),
- property_value=re.compile(r'^[\w\.\-\/\~:]*$'),
- )
- self.db = dict(
- db_url='sqlite:///state.sqlite',
- db_poll_interval=None,
- )
- self.metrics = None
- self.caches = dict(
- Builds=15,
- Changes=10,
- )
- self.schedulers = {}
- self.builders = []
- self.slaves = []
- self.change_sources = []
- self.status = []
- self.user_managers = []
- self.revlink = default_revlink_matcher
-
- _known_config_keys = set([
- "buildbotURL", "buildCacheSize", "builders", "buildHorizon", "caches",
- "change_source", "codebaseGenerator", "changeCacheSize", "changeHorizon",
- 'db', "db_poll_interval", "db_url", "debugPassword", "eventHorizon",
- "logCompressionLimit", "logCompressionMethod", "logHorizon",
- "logMaxSize", "logMaxTailSize", "manhole", "mergeRequests", "metrics",
- "multiMaster", "prioritizeBuilders", "projectName", "projectURL",
- "properties", "revlink", "schedulers", "slavePortnum", "slaves",
- "status", "title", "titleURL", "user_managers", "validation"
- ])
-
- @classmethod
- def loadConfig(cls, basedir, filename):
- if not os.path.isdir(basedir):
- raise ConfigErrors([
- "basedir '%s' does not exist" % (basedir,),
- ])
- filename = os.path.join(basedir, filename)
- if not os.path.exists(filename):
- raise ConfigErrors([
- "configuration file '%s' does not exist" % (filename,),
- ])
-
- try:
- f = open(filename, "r")
- except IOError, e:
- raise ConfigErrors([
- "unable to open configuration file %r: %s" % (filename, e),
- ])
-
- log.msg("Loading configuration from %r" % (filename,))
-
- # execute the config file
- localDict = {
- 'basedir': os.path.expanduser(basedir),
- '__file__': os.path.abspath(filename),
- }
-
- # from here on out we can batch errors together for the user's
- # convenience
- global _errors
- _errors = errors = ConfigErrors()
-
- old_sys_path = sys.path[:]
- sys.path.append(basedir)
- try:
- try:
- exec f in localDict
- except ConfigErrors, e:
- for err in e.errors:
- error(err)
- raise errors
- except:
- log.err(failure.Failure(), 'error while parsing config file:')
- error("error while parsing config file: %s (traceback in logfile)" %
- (sys.exc_info()[1],),
- )
- raise errors
- finally:
- f.close()
- sys.path[:] = old_sys_path
- _errors = None
-
- if 'BuildmasterConfig' not in localDict:
- error("Configuration file %r does not define 'BuildmasterConfig'"
- % (filename,),
- )
-
- config_dict = localDict['BuildmasterConfig']
-
- # check for unknown keys
- unknown_keys = set(config_dict.keys()) - cls._known_config_keys
- if unknown_keys:
- if len(unknown_keys) == 1:
- error('Unknown BuildmasterConfig key %s' %
- (unknown_keys.pop()))
- else:
- error('Unknown BuildmasterConfig keys %s' %
- (', '.join(sorted(unknown_keys))))
-
- # instantiate a new config object, which will apply defaults
- # automatically
- config = cls()
-
- _errors = errors
- # and defer the rest to sub-functions, for code clarity
- try:
- config.load_global(filename, config_dict)
- config.load_validation(filename, config_dict)
- config.load_db(filename, config_dict)
- config.load_metrics(filename, config_dict)
- config.load_caches(filename, config_dict)
- config.load_schedulers(filename, config_dict)
- config.load_builders(filename, config_dict)
- config.load_slaves(filename, config_dict)
- config.load_change_sources(filename, config_dict)
- config.load_status(filename, config_dict)
- config.load_user_managers(filename, config_dict)
-
- # run some sanity checks
- config.check_single_master()
- config.check_schedulers()
- config.check_locks()
- config.check_builders()
- config.check_status()
- config.check_horizons()
- config.check_slavePortnum()
- finally:
- _errors = None
-
- if errors:
- raise errors
-
- return config
-
- def load_global(self, filename, config_dict):
- def copy_param(name, alt_key=None,
- check_type=None, check_type_name=None):
- if name in config_dict:
- v = config_dict[name]
- elif alt_key and alt_key in config_dict:
- v = config_dict[alt_key]
- else:
- return
- if v is not None and check_type and not isinstance(v, check_type):
- error("c['%s'] must be %s" %
- (name, check_type_name))
- else:
- setattr(self, name, v)
-
- def copy_int_param(name, alt_key=None):
- copy_param(name, alt_key=alt_key,
- check_type=int, check_type_name='an int')
-
- def copy_str_param(name, alt_key=None):
- copy_param(name, alt_key=alt_key,
- check_type=basestring, check_type_name='a string')
-
- copy_str_param('title', alt_key='projectName')
- copy_str_param('titleURL', alt_key='projectURL')
- copy_str_param('buildbotURL')
-
- copy_int_param('changeHorizon')
- copy_int_param('eventHorizon')
- copy_int_param('logHorizon')
- copy_int_param('buildHorizon')
-
- copy_int_param('logCompressionLimit')
-
- if 'logCompressionMethod' in config_dict:
- logCompressionMethod = config_dict.get('logCompressionMethod')
- if logCompressionMethod not in ('bz2', 'gz'):
- error("c['logCompressionMethod'] must be 'bz2' or 'gz'")
- self.logCompressionMethod = logCompressionMethod
-
- copy_int_param('logMaxSize')
- copy_int_param('logMaxTailSize')
-
- properties = config_dict.get('properties', {})
- if not isinstance(properties, dict):
- error("c['properties'] must be a dictionary")
- else:
- self.properties.update(properties, filename)
-
- mergeRequests = config_dict.get('mergeRequests')
- if (mergeRequests not in (None, True, False)
- and not callable(mergeRequests)):
- error("mergeRequests must be a callable, True, or False")
- else:
- self.mergeRequests = mergeRequests
-
- codebaseGenerator = config_dict.get('codebaseGenerator')
- if (codebaseGenerator is not None and
- not callable(codebaseGenerator)):
- error("codebaseGenerator must be a callable accepting a dict and returning a str")
- else:
- self.codebaseGenerator = codebaseGenerator
-
- prioritizeBuilders = config_dict.get('prioritizeBuilders')
- if prioritizeBuilders is not None and not callable(prioritizeBuilders):
- error("prioritizeBuilders must be a callable")
- else:
- self.prioritizeBuilders = prioritizeBuilders
-
- if 'slavePortnum' in config_dict:
- slavePortnum = config_dict.get('slavePortnum')
- if isinstance(slavePortnum, int):
- slavePortnum = "tcp:%d" % slavePortnum
- self.slavePortnum = slavePortnum
-
- if 'multiMaster' in config_dict:
- self.multiMaster = config_dict["multiMaster"]
-
- copy_str_param('debugPassword')
-
- if 'manhole' in config_dict:
- # we don't check that this is a manhole instance, since that
- # requires importing buildbot.manhole for every user, and currently
- # that will fail if pycrypto isn't installed
- self.manhole = config_dict['manhole']
-
- if 'revlink' in config_dict:
- revlink = config_dict['revlink']
- if not callable(revlink):
- error("revlink must be a callable")
- else:
- self.revlink = revlink
-
- def load_validation(self, filename, config_dict):
- validation = config_dict.get("validation", {})
- if not isinstance(validation, dict):
- error("c['validation'] must be a dictionary")
- else:
- unknown_keys = (
- set(validation.keys()) - set(self.validation.keys()))
- if unknown_keys:
- error("unrecognized validation key(s): %s" %
- (", ".join(unknown_keys)))
- else:
- self.validation.update(validation)
-
-
- def load_db(self, filename, config_dict):
- if 'db' in config_dict:
- db = config_dict['db']
- if set(db.keys()) > set(['db_url', 'db_poll_interval']):
- error("unrecognized keys in c['db']")
- self.db.update(db)
- if 'db_url' in config_dict:
- self.db['db_url'] = config_dict['db_url']
- if 'db_poll_interval' in config_dict:
- self.db['db_poll_interval'] = config_dict["db_poll_interval"]
-
- # we don't attempt to parse db URLs here - the engine strategy will do so
-
- # check the db_poll_interval
- db_poll_interval = self.db['db_poll_interval']
- if db_poll_interval is not None and \
- not isinstance(db_poll_interval, int):
- error("c['db_poll_interval'] must be an int")
- else:
- self.db['db_poll_interval'] = db_poll_interval
-
-
- def load_metrics(self, filename, config_dict):
- # we don't try to validate metrics keys
- if 'metrics' in config_dict:
- metrics = config_dict["metrics"]
- if not isinstance(metrics, dict):
- error("c['metrics'] must be a dictionary")
- else:
- self.metrics = metrics
-
-
- def load_caches(self, filename, config_dict):
- explicit = False
- if 'caches' in config_dict:
- explicit = True
- caches = config_dict['caches']
- if not isinstance(caches, dict):
- error("c['caches'] must be a dictionary")
- else:
- valPairs = caches.items()
- for (x, y) in valPairs:
- if not isinstance(y, int):
- error("value for cache size '%s' must be an integer" % x)
- self.caches.update(caches)
-
- if 'buildCacheSize' in config_dict:
- if explicit:
- msg = "cannot specify c['caches'] and c['buildCacheSize']"
- error(msg)
- self.caches['Builds'] = config_dict['buildCacheSize']
- if 'changeCacheSize' in config_dict:
- if explicit:
- msg = "cannot specify c['caches'] and c['changeCacheSize']"
- error(msg)
- self.caches['Changes'] = config_dict['changeCacheSize']
-
-
- def load_schedulers(self, filename, config_dict):
- if 'schedulers' not in config_dict:
- return
- schedulers = config_dict['schedulers']
-
- ok = True
- if not isinstance(schedulers, (list, tuple)):
- ok = False
- else:
- for s in schedulers:
- if not interfaces.IScheduler.providedBy(s):
- ok = False
- if not ok:
- msg="c['schedulers'] must be a list of Scheduler instances"
- error(msg)
-
- # convert from list to dict, first looking for duplicates
- seen_names = set()
- for s in schedulers:
- if s.name in seen_names:
- error("scheduler name '%s' used multiple times" %
- s.name)
- seen_names.add(s.name)
-
- self.schedulers = dict((s.name, s) for s in schedulers)
-
-
- def load_builders(self, filename, config_dict):
- if 'builders' not in config_dict:
- return
- builders = config_dict['builders']
-
- if not isinstance(builders, (list, tuple)):
- error("c['builders'] must be a list")
- return
-
- # convert all builder configs to BuilderConfig instances
- def mapper(b):
- if isinstance(b, BuilderConfig):
- return b
- elif isinstance(b, dict):
- return BuilderConfig(**b)
- else:
- error("%r is not a builder config (in c['builders']" % (b,))
- builders = [ mapper(b) for b in builders ]
-
- for builder in builders:
- if builder and os.path.isabs(builder.builddir):
- warnings.warn("Absolute path '%s' for builder may cause "
- "mayhem. Perhaps you meant to specify slavebuilddir "
- "instead.")
-
- self.builders = builders
-
-
- def load_slaves(self, filename, config_dict):
- if 'slaves' not in config_dict:
- return
- slaves = config_dict['slaves']
-
- if not isinstance(slaves, (list, tuple)):
- error("c['slaves'] must be a list")
- return
-
- for sl in slaves:
- if not interfaces.IBuildSlave.providedBy(sl):
- msg = "c['slaves'] must be a list of BuildSlave instances"
- error(msg)
- return
-
- if sl.slavename in ("debug", "change", "status"):
- msg = "slave name '%s' is reserved" % sl.slavename
- error(msg)
-
- self.slaves = config_dict['slaves']
-
-
- def load_change_sources(self, filename, config_dict):
- change_source = config_dict.get('change_source', [])
- if isinstance(change_source, (list, tuple)):
- change_sources = change_source
- else:
- change_sources = [change_source]
-
- for s in change_sources:
- if not interfaces.IChangeSource.providedBy(s):
- msg = "c['change_source'] must be a list of change sources"
- error(msg)
- return
-
- self.change_sources = change_sources
-
- def load_status(self, filename, config_dict):
- if 'status' not in config_dict:
- return
- status = config_dict.get('status', [])
-
- msg = "c['status'] must be a list of status receivers"
- if not isinstance(status, (list, tuple)):
- error(msg)
- return
-
- for s in status:
- if not interfaces.IStatusReceiver.providedBy(s):
- error(msg)
- return
-
- self.status = status
-
-
- def load_user_managers(self, filename, config_dict):
- if 'user_managers' not in config_dict:
- return
- user_managers = config_dict['user_managers']
-
- msg = "c['user_managers'] must be a list of user managers"
- if not isinstance(user_managers, (list, tuple)):
- error(msg)
- return
-
- self.user_managers = user_managers
-
-
- def check_single_master(self):
- # check additional problems that are only valid in a single-master
- # installation
- if self.multiMaster:
- return
-
- if not self.slaves:
- error("no slaves are configured")
-
- if not self.builders:
- error("no builders are configured")
-
- # check that all builders are implemented on this master
- unscheduled_buildernames = set([ b.name for b in self.builders ])
- for s in self.schedulers.itervalues():
- for n in s.listBuilderNames():
- if n in unscheduled_buildernames:
- unscheduled_buildernames.remove(n)
- if unscheduled_buildernames:
- error("builder(s) %s have no schedulers to drive them"
- % (', '.join(unscheduled_buildernames),))
-
-
- def check_schedulers(self):
- # don't perform this check in multiMaster mode
- if self.multiMaster:
- return
-
- all_buildernames = set([ b.name for b in self.builders ])
-
- for s in self.schedulers.itervalues():
- for n in s.listBuilderNames():
- if n not in all_buildernames:
- error("Unknown builder '%s' in scheduler '%s'"
- % (n, s.name))
-
-
- def check_locks(self):
- # assert that all locks used by the Builds and their Steps are
- # uniquely named.
- lock_dict = {}
- def check_lock(l):
- if isinstance(l, locks.LockAccess):
- l = l.lockid
- if lock_dict.has_key(l.name):
- if lock_dict[l.name] is not l:
- msg = "Two locks share the same name, '%s'" % l.name
- error(msg)
- else:
- lock_dict[l.name] = l
-
- for b in self.builders:
- if b.locks:
- for l in b.locks:
- check_lock(l)
-
- def check_builders(self):
- # look both for duplicate builder names, and for builders pointing
- # to unknown slaves
- slavenames = set([ s.slavename for s in self.slaves ])
- seen_names = set()
- seen_builddirs = set()
-
- for b in self.builders:
- unknowns = set(b.slavenames) - slavenames
- if unknowns:
- error("builder '%s' uses unknown slaves %s" %
- (b.name, ", ".join(`u` for u in unknowns)))
- if b.name in seen_names:
- error("duplicate builder name '%s'" % b.name)
- seen_names.add(b.name)
-
- if b.builddir in seen_builddirs:
- error("duplicate builder builddir '%s'" % b.builddir)
- seen_builddirs.add(b.builddir)
-
-
- def check_status(self):
- # allow status receivers to check themselves against the rest of the
- # receivers
- for s in self.status:
- s.checkConfig(self.status)
-
-
- def check_horizons(self):
- if self.logHorizon is not None and self.buildHorizon is not None:
- if self.logHorizon > self.buildHorizon:
- error("logHorizon must be less than or equal to buildHorizon")
-
- def check_slavePortnum(self):
- if self.slavePortnum:
- return
-
- if self.slaves:
- error("slaves are configured, but no slavePortnum is set")
- if self.debugPassword:
- error("debug client is configured, but no slavePortnum is set")
-
-
-class BuilderConfig:
-
- def __init__(self, name=None, slavename=None, slavenames=None,
- builddir=None, slavebuilddir=None, factory=None, category=None,
- nextSlave=None, nextBuild=None, locks=None, env=None,
- properties=None, mergeRequests=None, description=None,
- canStartBuild=None):
-
- # name is required, and can't start with '_'
- if not name or type(name) not in (str, unicode):
- error("builder's name is required")
- name = '<unknown>'
- elif name[0] == '_':
- error("builder names must not start with an underscore: '%s'" % name)
- self.name = name
-
- # factory is required
- if factory is None:
- error("builder '%s' has no factory" % name)
- from buildbot.process.factory import BuildFactory
- if factory is not None and not isinstance(factory, BuildFactory):
- error("builder '%s's factory is not a BuildFactory instance" % name)
- self.factory = factory
-
- # slavenames can be a single slave name or a list, and should also
- # include slavename, if given
- if type(slavenames) is str:
- slavenames = [ slavenames ]
- if slavenames:
- if not isinstance(slavenames, list):
- error("builder '%s': slavenames must be a list or a string" %
- (name,))
- else:
- slavenames = []
-
- if slavename:
- if type(slavename) != str:
- error("builder '%s': slavename must be a string" % (name,))
- slavenames = slavenames + [ slavename ]
- if not slavenames:
- error("builder '%s': at least one slavename is required" % (name,))
-
- self.slavenames = slavenames
-
- # builddir defaults to name
- if builddir is None:
- builddir = safeTranslate(name)
- self.builddir = builddir
-
- # slavebuilddir defaults to builddir
- if slavebuilddir is None:
- slavebuilddir = builddir
- self.slavebuilddir = slavebuilddir
-
- # remainder are optional
- if category is not None and not isinstance(category, str):
- error("builder '%s': category must be a string" % (name,))
-
- self.category = category or ''
- self.nextSlave = nextSlave
- if nextSlave and not callable(nextSlave):
- error('nextSlave must be a callable')
- self.nextBuild = nextBuild
- if nextBuild and not callable(nextBuild):
- error('nextBuild must be a callable')
- self.canStartBuild = canStartBuild
- if canStartBuild and not callable(canStartBuild):
- error('canStartBuild must be a callable')
-
- self.locks = locks or []
- self.env = env or {}
- if not isinstance(self.env, dict):
- error("builder's env must be a dictionary")
- self.properties = properties or {}
- self.mergeRequests = mergeRequests
-
- self.description = description
-
-
- def getConfigDict(self):
- # note: this method will disappear eventually - put your smarts in the
- # constructor!
- rv = {
- 'name': self.name,
- 'slavenames': self.slavenames,
- 'factory': self.factory,
- 'builddir': self.builddir,
- 'slavebuilddir': self.slavebuilddir,
- }
- if self.category:
- rv['category'] = self.category
- if self.nextSlave:
- rv['nextSlave'] = self.nextSlave
- if self.nextBuild:
- rv['nextBuild'] = self.nextBuild
- if self.locks:
- rv['locks'] = self.locks
- if self.env:
- rv['env'] = self.env
- if self.properties:
- rv['properties'] = self.properties
- if self.mergeRequests:
- rv['mergeRequests'] = self.mergeRequests
- if self.description:
- rv['description'] = self.description
- return rv
-
-
-class ReconfigurableServiceMixin:
-
- reconfig_priority = 128
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- if not service.IServiceCollection.providedBy(self):
- return
-
- # get a list of child services to reconfigure
- reconfigurable_services = [ svc
- for svc in self
- if isinstance(svc, ReconfigurableServiceMixin) ]
-
- # sort by priority
- reconfigurable_services.sort(key=lambda svc : -svc.reconfig_priority)
-
- for svc in reconfigurable_services:
- yield svc.reconfigService(new_config)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py
deleted file mode 100644
index 2789d676..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py
deleted file mode 100644
index 78f88889..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-class DBConnectorComponent(object):
- # A fixed component of the DBConnector, handling one particular aspect of
- # the database. Instances of subclasses are assigned to attributes of the
- # DBConnector object, so that they are available at e.g.,
- # C{master.db.model} or C{master.db.changes}. This parent class takes care
- # of the necessary backlinks and other housekeeping.
-
- connector = None
-
- def __init__(self, connector):
- self.db = connector
-
- # set up caches
- for method in dir(self.__class__):
- o = getattr(self, method)
- if isinstance(o, CachedMethod):
- setattr(self, method, o.get_cached_method(self))
-
- _is_check_length_necessary = None
- def check_length(self, col, value):
- # for use by subclasses to check that 'value' will fit in 'col', where
- # 'col' is a table column from the model.
-
- # ignore this check for database engines that either provide this error
- # themselves (postgres) or that do not enforce maximum-length
- # restrictions (sqlite)
- if not self._is_check_length_necessary:
- if self.db.pool.engine.dialect.name == 'mysql':
- self._is_check_length_necessary = True
- else:
- # not necessary, so just stub out the method
- self.check_length = lambda col, value : None
- return
-
- assert col.type.length, "column %s does not have a length" % (col,)
- if value and len(value) > col.type.length:
- raise RuntimeError(
- "value for column %s is greater than max of %d characters: %s"
- % (col, col.type.length, value))
-
-
-class CachedMethod(object):
- def __init__(self, cache_name, method):
- self.cache_name = cache_name
- self.method = method
-
- def get_cached_method(self, component):
- meth = self.method
-
- meth_name = meth.__name__
- cache = component.db.master.caches.get_cache(self.cache_name,
- lambda key : meth(component, key))
- def wrap(key, no_cache=0):
- if no_cache:
- return meth(component, key)
- return cache.get(key)
- wrap.__name__ = meth_name + " (wrapped)"
- wrap.__module__ = meth.__module__
- wrap.__doc__ = meth.__doc__
- wrap.cache = cache
- return wrap
-
-def cached(cache_name):
- return lambda method : CachedMethod(cache_name, method)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py
deleted file mode 100644
index 33091c90..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py
+++ /dev/null
@@ -1,284 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import itertools
-import sqlalchemy as sa
-from twisted.internet import reactor
-from twisted.python import log
-from buildbot.db import base
-from buildbot.util import epoch2datetime, datetime2epoch
-
-class AlreadyClaimedError(Exception):
- pass
-
-class NotClaimedError(Exception):
- pass
-
-class BrDict(dict):
- pass
-
-# private decorator to add a _master_objectid keyword argument, querying from
-# the master
-def with_master_objectid(fn):
- def wrap(self, *args, **kwargs):
- d = self.db.master.getObjectId()
- d.addCallback(lambda master_objectid :
- fn(self, _master_objectid=master_objectid, *args, **kwargs))
- return d
- wrap.__name__ = fn.__name__
- wrap.__doc__ = fn.__doc__
- return wrap
-
-class BuildRequestsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- @with_master_objectid
- def getBuildRequest(self, brid, _master_objectid=None):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- res = conn.execute(sa.select([
- reqs_tbl.outerjoin(claims_tbl,
- (reqs_tbl.c.id == claims_tbl.c.brid)) ],
- whereclause=(reqs_tbl.c.id == brid)), use_labels=True)
- row = res.fetchone()
-
- rv = None
- if row:
- rv = self._brdictFromRow(row, _master_objectid)
- res.close()
- return rv
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def getBuildRequests(self, buildername=None, complete=None, claimed=None,
- bsid=None, _master_objectid=None, branch=None, repository=None):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- bsets_tbl = self.db.model.buildsets
- sstamps_tbls = self.db.model.sourcestamps
-
- from_clause = reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid)
-
- if branch or repository:
- from_clause = from_clause.join(bsets_tbl,
- reqs_tbl.c.buildsetid ==
- bsets_tbl.c.id)
- from_clause = from_clause.join(sstamps_tbls,
- bsets_tbl.c.sourcestampsetid ==
- sstamps_tbls.c.sourcestampsetid)
-
- q = sa.select([ reqs_tbl, claims_tbl ]).select_from(from_clause)
- if claimed is not None:
- if not claimed:
- q = q.where(
- (claims_tbl.c.claimed_at == None) &
- (reqs_tbl.c.complete == 0))
- elif claimed == "mine":
- q = q.where(
- (claims_tbl.c.objectid == _master_objectid))
- else:
- q = q.where(
- (claims_tbl.c.claimed_at != None))
- if buildername is not None:
- q = q.where(reqs_tbl.c.buildername == buildername)
- if complete is not None:
- if complete:
- q = q.where(reqs_tbl.c.complete != 0)
- else:
- q = q.where(reqs_tbl.c.complete == 0)
- if bsid is not None:
- q = q.where(reqs_tbl.c.buildsetid == bsid)
-
- if branch is not None:
- q = q.where(sstamps_tbls.c.branch == branch)
- if repository is not None:
- q = q.where(sstamps_tbls.c.repository == repository)
-
- res = conn.execute(q)
-
- return [ self._brdictFromRow(row, _master_objectid)
- for row in res.fetchall() ]
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def claimBuildRequests(self, brids, claimed_at=None, _reactor=reactor,
- _master_objectid=None):
- if claimed_at is not None:
- claimed_at = datetime2epoch(claimed_at)
- else:
- claimed_at = _reactor.seconds()
-
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.buildrequest_claims
-
- try:
- q = tbl.insert()
- conn.execute(q, [ dict(brid=id, objectid=_master_objectid,
- claimed_at=claimed_at)
- for id in brids ])
- except (sa.exc.IntegrityError, sa.exc.ProgrammingError):
- transaction.rollback()
- raise AlreadyClaimedError
-
- transaction.commit()
-
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def reclaimBuildRequests(self, brids, _reactor=reactor,
- _master_objectid=None):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.buildrequest_claims
- claimed_at = _reactor.seconds()
-
- # we'll need to batch the brids into groups of 100, so that the
- # parameter lists supported by the DBAPI aren't exhausted
- iterator = iter(brids)
-
- while 1:
- batch = list(itertools.islice(iterator, 100))
- if not batch:
- break # success!
-
- q = tbl.update(tbl.c.brid.in_(batch)
- & (tbl.c.objectid==_master_objectid))
- res = conn.execute(q, claimed_at=claimed_at)
-
- # if fewer rows were updated than expected, then something
- # went wrong
- if res.rowcount != len(batch):
- transaction.rollback()
- raise AlreadyClaimedError
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def unclaimBuildRequests(self, brids, _master_objectid=None):
- def thd(conn):
- transaction = conn.begin()
- claims_tbl = self.db.model.buildrequest_claims
-
- # we'll need to batch the brids into groups of 100, so that the
- # parameter lists supported by the DBAPI aren't exhausted
- iterator = iter(brids)
-
- while 1:
- batch = list(itertools.islice(iterator, 100))
- if not batch:
- break # success!
-
- try:
- q = claims_tbl.delete(
- (claims_tbl.c.brid.in_(batch))
- & (claims_tbl.c.objectid == _master_objectid))
- conn.execute(q)
- except:
- transaction.rollback()
- raise
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def completeBuildRequests(self, brids, results, complete_at=None,
- _reactor=reactor, _master_objectid=None):
- if complete_at is not None:
- complete_at = datetime2epoch(complete_at)
- else:
- complete_at = _reactor.seconds()
-
- def thd(conn):
- transaction = conn.begin()
-
- # the update here is simple, but a number of conditions are
- # attached to ensure that we do not update a row inappropriately,
- # Note that checking that the request is mine would require a
- # subquery, so for efficiency that is not checed.
-
- reqs_tbl = self.db.model.buildrequests
-
- # we'll need to batch the brids into groups of 100, so that the
- # parameter lists supported by the DBAPI aren't exhausted
- iterator = iter(brids)
-
- while 1:
- batch = list(itertools.islice(iterator, 100))
- if not batch:
- break # success!
-
- q = reqs_tbl.update()
- q = q.where(reqs_tbl.c.id.in_(batch))
- q = q.where(reqs_tbl.c.complete != 1)
- res = conn.execute(q,
- complete=1,
- results=results,
- complete_at=complete_at)
-
- # if an incorrect number of rows were updated, then we failed.
- if res.rowcount != len(batch):
- log.msg("tried to complete %d buildreqests, "
- "but only completed %d" % (len(batch), res.rowcount))
- transaction.rollback()
- raise NotClaimedError
- transaction.commit()
- return self.db.pool.do(thd)
-
- def unclaimExpiredRequests(self, old, _reactor=reactor):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- old_epoch = _reactor.seconds() - old
-
- # select any expired requests, and delete each one individually
- expired_brids = sa.select([ reqs_tbl.c.id ],
- whereclause=(reqs_tbl.c.complete != 1))
- res = conn.execute(claims_tbl.delete(
- (claims_tbl.c.claimed_at < old_epoch) &
- claims_tbl.c.brid.in_(expired_brids)))
- return res.rowcount
- d = self.db.pool.do(thd)
- def log_nonzero_count(count):
- if count != 0:
- log.msg("unclaimed %d expired buildrequests (over %d seconds "
- "old)" % (count, old))
- d.addCallback(log_nonzero_count)
- return d
-
- def _brdictFromRow(self, row, master_objectid):
- claimed = mine = False
- claimed_at = None
- if row.claimed_at is not None:
- claimed_at = row.claimed_at
- claimed = True
- mine = row.objectid == master_objectid
-
- def mkdt(epoch):
- if epoch:
- return epoch2datetime(epoch)
- submitted_at = mkdt(row.submitted_at)
- complete_at = mkdt(row.complete_at)
- claimed_at = mkdt(row.claimed_at)
-
- return BrDict(brid=row.id, buildsetid=row.buildsetid,
- buildername=row.buildername, priority=row.priority,
- claimed=claimed, claimed_at=claimed_at, mine=mine,
- complete=bool(row.complete), results=row.results,
- submitted_at=submitted_at, complete_at=complete_at)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py
deleted file mode 100644
index 8c25f078..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import reactor
-from buildbot.db import base
-from buildbot.util import epoch2datetime
-
-class BuildsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def getBuild(self, bid):
- def thd(conn):
- tbl = self.db.model.builds
- res = conn.execute(tbl.select(whereclause=(tbl.c.id == bid)))
- row = res.fetchone()
-
- rv = None
- if row:
- rv = self._bdictFromRow(row)
- res.close()
- return rv
- return self.db.pool.do(thd)
-
- def getBuildsForRequest(self, brid):
- def thd(conn):
- tbl = self.db.model.builds
- q = tbl.select(whereclause=(tbl.c.brid == brid))
- res = conn.execute(q)
- return [ self._bdictFromRow(row) for row in res.fetchall() ]
- return self.db.pool.do(thd)
-
- def addBuild(self, brid, number, _reactor=reactor):
- def thd(conn):
- start_time = _reactor.seconds()
- r = conn.execute(self.db.model.builds.insert(),
- dict(number=number, brid=brid, start_time=start_time,
- finish_time=None))
- return r.inserted_primary_key[0]
- return self.db.pool.do(thd)
-
- def finishBuilds(self, bids, _reactor=reactor):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.builds
- now = _reactor.seconds()
-
- # split the bids into batches, so as not to overflow the parameter
- # lists of the database interface
- remaining = bids
- while remaining:
- batch, remaining = remaining[:100], remaining[100:]
- q = tbl.update(whereclause=(tbl.c.id.in_(batch)))
- conn.execute(q, finish_time=now)
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- def _bdictFromRow(self, row):
- def mkdt(epoch):
- if epoch:
- return epoch2datetime(epoch)
-
- return dict(
- bid=row.id,
- brid=row.brid,
- number=row.number,
- start_time=mkdt(row.start_time),
- finish_time=mkdt(row.finish_time))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py
deleted file mode 100644
index b379198e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-Support for buildsets in the database
-"""
-
-import sqlalchemy as sa
-from twisted.internet import reactor
-from buildbot.util import json
-from buildbot.db import base
-from buildbot.util import epoch2datetime, datetime2epoch
-
-class BsDict(dict):
- pass
-
-class BuildsetsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addBuildset(self, sourcestampsetid, reason, properties, builderNames,
- external_idstring=None, _reactor=reactor):
- def thd(conn):
- buildsets_tbl = self.db.model.buildsets
- submitted_at = _reactor.seconds()
-
- self.check_length(buildsets_tbl.c.reason, reason)
- self.check_length(buildsets_tbl.c.external_idstring,
- external_idstring)
-
- transaction = conn.begin()
-
- # insert the buildset itself
- r = conn.execute(buildsets_tbl.insert(), dict(
- sourcestampsetid=sourcestampsetid, submitted_at=submitted_at,
- reason=reason, complete=0, complete_at=None, results=-1,
- external_idstring=external_idstring))
- bsid = r.inserted_primary_key[0]
-
- # add any properties
- if properties:
- bs_props_tbl = self.db.model.buildset_properties
-
- inserts = [
- dict(buildsetid=bsid, property_name=k,
- property_value=json.dumps([v,s]))
- for k,(v,s) in properties.iteritems() ]
- for i in inserts:
- self.check_length(bs_props_tbl.c.property_name,
- i['property_name'])
- self.check_length(bs_props_tbl.c.property_value,
- i['property_value'])
-
- conn.execute(bs_props_tbl.insert(), inserts)
-
- # and finish with a build request for each builder. Note that
- # sqlalchemy and the Python DBAPI do not provide a way to recover
- # inserted IDs from a multi-row insert, so this is done one row at
- # a time.
- brids = {}
- br_tbl = self.db.model.buildrequests
- ins = br_tbl.insert()
- for buildername in builderNames:
- self.check_length(br_tbl.c.buildername, buildername)
- r = conn.execute(ins,
- dict(buildsetid=bsid, buildername=buildername, priority=0,
- claimed_at=0, claimed_by_name=None,
- claimed_by_incarnation=None, complete=0, results=-1,
- submitted_at=submitted_at, complete_at=None))
-
- brids[buildername] = r.inserted_primary_key[0]
-
- transaction.commit()
-
- return (bsid, brids)
- return self.db.pool.do(thd)
-
- def completeBuildset(self, bsid, results, complete_at=None,
- _reactor=reactor):
- if complete_at is not None:
- complete_at = datetime2epoch(complete_at)
- else:
- complete_at = _reactor.seconds()
-
- def thd(conn):
- tbl = self.db.model.buildsets
-
- q = tbl.update(whereclause=(
- (tbl.c.id == bsid) &
- ((tbl.c.complete == None) | (tbl.c.complete != 1))))
- res = conn.execute(q,
- complete=1,
- results=results,
- complete_at=complete_at)
-
- if res.rowcount != 1:
- raise KeyError
- return self.db.pool.do(thd)
-
- def getBuildset(self, bsid):
- def thd(conn):
- bs_tbl = self.db.model.buildsets
- q = bs_tbl.select(whereclause=(bs_tbl.c.id == bsid))
- res = conn.execute(q)
- row = res.fetchone()
- if not row:
- return None
- return self._row2dict(row)
- return self.db.pool.do(thd)
-
- def getBuildsets(self, complete=None):
- def thd(conn):
- bs_tbl = self.db.model.buildsets
- q = bs_tbl.select()
- if complete is not None:
- if complete:
- q = q.where(bs_tbl.c.complete != 0)
- else:
- q = q.where((bs_tbl.c.complete == 0) |
- (bs_tbl.c.complete == None))
- res = conn.execute(q)
- return [ self._row2dict(row) for row in res.fetchall() ]
- return self.db.pool.do(thd)
-
- def getRecentBuildsets(self, count, branch=None, repository=None,
- complete=None):
- def thd(conn):
- bs_tbl = self.db.model.buildsets
- ss_tbl = self.db.model.sourcestamps
- j = sa.join(self.db.model.buildsets,
- self.db.model.sourcestampsets)
- j = j.join(self.db.model.sourcestamps)
- q = sa.select(columns=[bs_tbl], from_obj=[j],
- distinct=True)
- q = q.order_by(sa.desc(bs_tbl.c.submitted_at))
- q = q.limit(count)
-
- if complete is not None:
- if complete:
- q = q.where(bs_tbl.c.complete != 0)
- else:
- q = q.where((bs_tbl.c.complete == 0) |
- (bs_tbl.c.complete == None))
- if branch:
- q = q.where(ss_tbl.c.branch == branch)
- if repository:
- q = q.where(ss_tbl.c.repository == repository)
- res = conn.execute(q)
- return list(reversed([ self._row2dict(row)
- for row in res.fetchall() ]))
- return self.db.pool.do(thd)
-
- def getBuildsetProperties(self, buildsetid):
- """
- Return the properties for a buildset, in the same format they were
- given to L{addBuildset}.
-
- Note that this method does not distinguish a nonexistent buildset from
- a buildset with no properties, and returns C{{}} in either case.
-
- @param buildsetid: buildset ID
-
- @returns: dictionary mapping property name to (value, source), via
- Deferred
- """
- def thd(conn):
- bsp_tbl = self.db.model.buildset_properties
- q = sa.select(
- [ bsp_tbl.c.property_name, bsp_tbl.c.property_value ],
- whereclause=(bsp_tbl.c.buildsetid == buildsetid))
- l = []
- for row in conn.execute(q):
- try:
- properties = json.loads(row.property_value)
- l.append((row.property_name,
- tuple(properties)))
- except ValueError:
- pass
- return dict(l)
- return self.db.pool.do(thd)
-
- def _row2dict(self, row):
- def mkdt(epoch):
- if epoch:
- return epoch2datetime(epoch)
- return BsDict(external_idstring=row.external_idstring,
- reason=row.reason, sourcestampsetid=row.sourcestampsetid,
- submitted_at=mkdt(row.submitted_at),
- complete=bool(row.complete),
- complete_at=mkdt(row.complete_at), results=row.results,
- bsid=row.id)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py
deleted file mode 100644
index 4288be53..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py
+++ /dev/null
@@ -1,257 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-Support for changes in the database
-"""
-
-from buildbot.util import json
-import sqlalchemy as sa
-from twisted.internet import defer, reactor
-from buildbot.db import base
-from buildbot.util import epoch2datetime, datetime2epoch
-
-class ChDict(dict):
- pass
-
-class ChangesConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addChange(self, author=None, files=None, comments=None, is_dir=0,
- revision=None, when_timestamp=None, branch=None,
- category=None, revlink='', properties={}, repository='', codebase='',
- project='', uid=None, _reactor=reactor):
- assert project is not None, "project must be a string, not None"
- assert repository is not None, "repository must be a string, not None"
-
- if when_timestamp is None:
- when_timestamp = epoch2datetime(_reactor.seconds())
-
- # verify that source is 'Change' for each property
- for pv in properties.values():
- assert pv[1] == 'Change', ("properties must be qualified with"
- "source 'Change'")
-
- def thd(conn):
- # note that in a read-uncommitted database like SQLite this
- # transaction does not buy atomicitiy - other database users may
- # still come across a change without its files, properties,
- # etc. That's OK, since we don't announce the change until it's
- # all in the database, but beware.
-
- transaction = conn.begin()
-
- ch_tbl = self.db.model.changes
-
- self.check_length(ch_tbl.c.author, author)
- self.check_length(ch_tbl.c.comments, comments)
- self.check_length(ch_tbl.c.branch, branch)
- self.check_length(ch_tbl.c.revision, revision)
- self.check_length(ch_tbl.c.revlink, revlink)
- self.check_length(ch_tbl.c.category, category)
- self.check_length(ch_tbl.c.repository, repository)
- self.check_length(ch_tbl.c.project, project)
-
- r = conn.execute(ch_tbl.insert(), dict(
- author=author,
- comments=comments,
- is_dir=is_dir,
- branch=branch,
- revision=revision,
- revlink=revlink,
- when_timestamp=datetime2epoch(when_timestamp),
- category=category,
- repository=repository,
- codebase=codebase,
- project=project))
- changeid = r.inserted_primary_key[0]
- if files:
- tbl = self.db.model.change_files
- for f in files:
- self.check_length(tbl.c.filename, f)
- conn.execute(tbl.insert(), [
- dict(changeid=changeid, filename=f)
- for f in files
- ])
- if properties:
- tbl = self.db.model.change_properties
- inserts = [
- dict(changeid=changeid,
- property_name=k,
- property_value=json.dumps(v))
- for k,v in properties.iteritems()
- ]
- for i in inserts:
- self.check_length(tbl.c.property_name,
- i['property_name'])
- self.check_length(tbl.c.property_value,
- i['property_value'])
-
- conn.execute(tbl.insert(), inserts)
- if uid:
- ins = self.db.model.change_users.insert()
- conn.execute(ins, dict(changeid=changeid, uid=uid))
-
- transaction.commit()
-
- return changeid
- d = self.db.pool.do(thd)
- return d
-
- @base.cached("chdicts")
- def getChange(self, changeid):
- assert changeid >= 0
- def thd(conn):
- # get the row from the 'changes' table
- changes_tbl = self.db.model.changes
- q = changes_tbl.select(whereclause=(changes_tbl.c.changeid == changeid))
- rp = conn.execute(q)
- row = rp.fetchone()
- if not row:
- return None
- # and fetch the ancillary data (files, properties)
- return self._chdict_from_change_row_thd(conn, row)
- d = self.db.pool.do(thd)
- return d
-
- def getChangeUids(self, changeid):
- assert changeid >= 0
- def thd(conn):
- cu_tbl = self.db.model.change_users
- q = cu_tbl.select(whereclause=(cu_tbl.c.changeid == changeid))
- res = conn.execute(q)
- rows = res.fetchall()
- row_uids = [ row.uid for row in rows ]
- return row_uids
- d = self.db.pool.do(thd)
- return d
-
- def getRecentChanges(self, count):
- def thd(conn):
- # get the changeids from the 'changes' table
- changes_tbl = self.db.model.changes
- q = sa.select([changes_tbl.c.changeid],
- order_by=[sa.desc(changes_tbl.c.changeid)],
- limit=count)
- rp = conn.execute(q)
- changeids = [ row.changeid for row in rp ]
- rp.close()
- return list(reversed(changeids))
- d = self.db.pool.do(thd)
-
- # then turn those into changes, using the cache
- def get_changes(changeids):
- return defer.gatherResults([ self.getChange(changeid)
- for changeid in changeids ])
- d.addCallback(get_changes)
- return d
-
- def getLatestChangeid(self):
- def thd(conn):
- changes_tbl = self.db.model.changes
- q = sa.select([ changes_tbl.c.changeid ],
- order_by=sa.desc(changes_tbl.c.changeid),
- limit=1)
- return conn.scalar(q)
- d = self.db.pool.do(thd)
- return d
-
- # utility methods
-
- def pruneChanges(self, changeHorizon):
- """
- Called periodically by DBConnector, this method deletes changes older
- than C{changeHorizon}.
- """
-
- if not changeHorizon:
- return defer.succeed(None)
- def thd(conn):
- changes_tbl = self.db.model.changes
-
- # First, get the list of changes to delete. This could be written
- # as a subquery but then that subquery would be run for every
- # table, which is very inefficient; also, MySQL's subquery support
- # leaves much to be desired, and doesn't support this particular
- # form.
- q = sa.select([changes_tbl.c.changeid],
- order_by=[sa.desc(changes_tbl.c.changeid)],
- offset=changeHorizon)
- res = conn.execute(q)
- ids_to_delete = [ r.changeid for r in res ]
-
- # and delete from all relevant tables, in dependency order
- for table_name in ('scheduler_changes', 'sourcestamp_changes',
- 'change_files', 'change_properties', 'changes',
- 'change_users'):
- remaining = ids_to_delete[:]
- while remaining:
- batch, remaining = remaining[:100], remaining[100:]
- table = self.db.model.metadata.tables[table_name]
- conn.execute(
- table.delete(table.c.changeid.in_(batch)))
- return self.db.pool.do(thd)
-
- def _chdict_from_change_row_thd(self, conn, ch_row):
- # This method must be run in a db.pool thread, and returns a chdict
- # given a row from the 'changes' table
- change_files_tbl = self.db.model.change_files
- change_properties_tbl = self.db.model.change_properties
-
- chdict = ChDict(
- changeid=ch_row.changeid,
- author=ch_row.author,
- files=[], # see below
- comments=ch_row.comments,
- is_dir=ch_row.is_dir,
- revision=ch_row.revision,
- when_timestamp=epoch2datetime(ch_row.when_timestamp),
- branch=ch_row.branch,
- category=ch_row.category,
- revlink=ch_row.revlink,
- properties={}, # see below
- repository=ch_row.repository,
- codebase=ch_row.codebase,
- project=ch_row.project)
-
- query = change_files_tbl.select(
- whereclause=(change_files_tbl.c.changeid == ch_row.changeid))
- rows = conn.execute(query)
- for r in rows:
- chdict['files'].append(r.filename)
-
- # and properties must be given without a source, so strip that, but
- # be flexible in case users have used a development version where the
- # change properties were recorded incorrectly
- def split_vs(vs):
- try:
- v,s = vs
- if s != "Change":
- v,s = vs, "Change"
- except:
- v,s = vs, "Change"
- return v, s
-
- query = change_properties_tbl.select(
- whereclause=(change_properties_tbl.c.changeid == ch_row.changeid))
- rows = conn.execute(query)
- for r in rows:
- try:
- v, s = split_vs(json.loads(r.property_value))
- chdict['properties'][r.property_name] = (v,s)
- except ValueError:
- pass
-
- return chdict
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py
deleted file mode 100644
index bc571649..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import textwrap
-from twisted.internet import defer
-from twisted.python import log
-from twisted.application import internet, service
-from buildbot import config
-from buildbot.db import enginestrategy
-from buildbot.db import pool, model, changes, schedulers, sourcestamps, sourcestampsets
-from buildbot.db import state, buildsets, buildrequests, builds, users
-
-class DatabaseNotReadyError(Exception):
- pass
-
-upgrade_message = textwrap.dedent("""\
-
- The Buildmaster database needs to be upgraded before this version of
- buildbot can run. Use the following command-line
-
- buildbot upgrade-master path/to/master
-
- to upgrade the database, and try starting the buildmaster again. You may
- want to make a backup of your buildmaster before doing so.
- """).strip()
-
-class DBConnector(config.ReconfigurableServiceMixin, service.MultiService):
- # The connection between Buildbot and its backend database. This is
- # generally accessible as master.db, but is also used during upgrades.
- #
- # Most of the interesting operations available via the connector are
- # implemented in connector components, available as attributes of this
- # object, and listed below.
-
- # Period, in seconds, of the cleanup task. This master will perform
- # periodic cleanup actions on this schedule.
- CLEANUP_PERIOD = 3600
-
- def __init__(self, master, basedir):
- service.MultiService.__init__(self)
- self.setName('db')
- self.master = master
- self.basedir = basedir
-
- # not configured yet - we don't build an engine until the first
- # reconfig
- self.configured_url = None
-
- # set up components
- self._engine = None # set up in reconfigService
- self.pool = None # set up in reconfigService
- self.model = model.Model(self)
- self.changes = changes.ChangesConnectorComponent(self)
- self.schedulers = schedulers.SchedulersConnectorComponent(self)
- self.sourcestamps = sourcestamps.SourceStampsConnectorComponent(self)
- self.sourcestampsets = sourcestampsets.SourceStampSetsConnectorComponent(self)
- self.buildsets = buildsets.BuildsetsConnectorComponent(self)
- self.buildrequests = buildrequests.BuildRequestsConnectorComponent(self)
- self.state = state.StateConnectorComponent(self)
- self.builds = builds.BuildsConnectorComponent(self)
- self.users = users.UsersConnectorComponent(self)
-
- self.cleanup_timer = internet.TimerService(self.CLEANUP_PERIOD,
- self._doCleanup)
- self.cleanup_timer.setServiceParent(self)
-
-
- def setup(self, check_version=True, verbose=True):
- db_url = self.configured_url = self.master.config.db['db_url']
-
- log.msg("Setting up database with URL %r" % (db_url,))
-
- # set up the engine and pool
- self._engine = enginestrategy.create_engine(db_url,
- basedir=self.basedir)
- self.pool = pool.DBThreadPool(self._engine, verbose=verbose)
-
- # make sure the db is up to date, unless specifically asked not to
- if check_version:
- d = self.model.is_current()
- def check_current(res):
- if not res:
- for l in upgrade_message.split('\n'):
- log.msg(l)
- raise DatabaseNotReadyError()
- d.addCallback(check_current)
- else:
- d = defer.succeed(None)
-
- return d
-
-
- def reconfigService(self, new_config):
- # double-check -- the master ensures this in config checks
- assert self.configured_url == new_config.db['db_url']
-
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
-
- def _doCleanup(self):
- """
- Perform any periodic database cleanup tasks.
-
- @returns: Deferred
- """
- # pass on this if we're not configured yet
- if not self.configured_url:
- return
-
- d = self.changes.pruneChanges(self.master.config.changeHorizon)
- d.addErrback(log.err, 'while pruning changes')
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py
deleted file mode 100644
index 2be80f9a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-A wrapper around `sqlalchemy.create_engine` that handles all of the
-special cases that Buildbot needs. Those include:
-
- - pool_recycle for MySQL
- - %(basedir) substitution
- - optimal thread pool size calculation
-
-"""
-
-import os
-import sqlalchemy as sa
-from twisted.python import log
-from sqlalchemy.engine import strategies, url
-from sqlalchemy.pool import NullPool
-from buildbot.util import sautils
-
-# from http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg15079.html
-class ReconnectingListener(object):
- def __init__(self):
- self.retried = False
-
-class BuildbotEngineStrategy(strategies.ThreadLocalEngineStrategy):
- # A subclass of the ThreadLocalEngineStrategy that can effectively interact
- # with Buildbot.
- #
- # This adjusts the passed-in parameters to ensure that we get the behaviors
- # Buildbot wants from particular drivers, and wraps the outgoing Engine
- # object so that its methods run in threads and return deferreds.
-
- name = 'buildbot'
-
- def special_case_sqlite(self, u, kwargs):
- """For sqlite, percent-substitute %(basedir)s and use a full
- path to the basedir. If using a memory database, force the
- pool size to be 1."""
- max_conns = None
-
- # when given a database path, stick the basedir in there
- if u.database:
-
- # Use NullPool instead of the sqlalchemy-0.6.8-default
- # SingletonThreadpool for sqlite to suppress the error in
- # http://groups.google.com/group/sqlalchemy/msg/f8482e4721a89589,
- # which also explains that NullPool is the new default in
- # sqlalchemy 0.7 for non-memory SQLite databases.
- kwargs.setdefault('poolclass', NullPool)
-
- u.database = u.database % dict(basedir = kwargs['basedir'])
- if not os.path.isabs(u.database[0]):
- u.database = os.path.join(kwargs['basedir'], u.database)
-
- # in-memory databases need exactly one connection
- if not u.database:
- kwargs['pool_size'] = 1
- max_conns = 1
-
- # allow serializing access to the db
- if 'serialize_access' in u.query:
- u.query.pop('serialize_access')
- max_conns = 1
-
- return u, kwargs, max_conns
-
- def set_up_sqlite_engine(self, u, engine):
- """Special setup for sqlite engines"""
- # try to enable WAL logging
- if u.database:
- def connect_listener(connection, record):
- connection.execute("pragma checkpoint_fullfsync = off")
-
- if sautils.sa_version() < (0,7,0):
- class CheckpointFullfsyncDisabler(object):
- pass
- disabler = CheckpointFullfsyncDisabler()
- disabler.connect = connect_listener
- engine.pool.add_listener(disabler)
- else:
- sa.event.listen(engine.pool, 'connect', connect_listener)
-
- log.msg("setting database journal mode to 'wal'")
- try:
- engine.execute("pragma journal_mode = wal")
- except:
- log.msg("failed to set journal mode - database may fail")
-
- def special_case_mysql(self, u, kwargs):
- """For mysql, take max_idle out of the query arguments, and
- use its value for pool_recycle. Also, force use_unicode and
- charset to be True and 'utf8', failing if they were set to
- anything else."""
-
- kwargs['pool_recycle'] = int(u.query.pop('max_idle', 3600))
-
- # default to the InnoDB storage engine
- storage_engine = u.query.pop('storage_engine', 'MyISAM')
- kwargs['connect_args'] = {
- 'init_command' : 'SET storage_engine=%s' % storage_engine,
- }
-
- if 'use_unicode' in u.query:
- if u.query['use_unicode'] != "True":
- raise TypeError("Buildbot requires use_unicode=True " +
- "(and adds it automatically)")
- else:
- u.query['use_unicode'] = True
-
- if 'charset' in u.query:
- if u.query['charset'] != "utf8":
- raise TypeError("Buildbot requires charset=utf8 " +
- "(and adds it automatically)")
- else:
- u.query['charset'] = 'utf8'
-
- return u, kwargs, None
-
- def set_up_mysql_engine(self, u, engine):
- """Special setup for mysql engines"""
- # add the reconnecting PoolListener that will detect a
- # disconnected connection and automatically start a new
- # one. This provides a measure of additional safety over
- # the pool_recycle parameter, and is useful when e.g., the
- # mysql server goes away
- def checkout_listener(dbapi_con, con_record, con_proxy):
- try:
- cursor = dbapi_con.cursor()
- cursor.execute("SELECT 1")
- except dbapi_con.OperationalError, ex:
- if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
- # sqlalchemy will re-create the connection
- raise sa.exc.DisconnectionError()
- raise
-
- # older versions of sqlalchemy require the listener to be specified
- # in the kwargs, in a class instance
- if sautils.sa_version() < (0,7,0):
- class ReconnectingListener(object):
- pass
- rcl = ReconnectingListener()
- rcl.checkout = checkout_listener
- engine.pool.add_listener(rcl)
- else:
- sa.event.listen(engine.pool, 'checkout', checkout_listener)
-
- def create(self, name_or_url, **kwargs):
- if 'basedir' not in kwargs:
- raise TypeError('no basedir supplied to create_engine')
-
- max_conns = None
-
- # apply special cases
- u = url.make_url(name_or_url)
- if u.drivername.startswith('sqlite'):
- u, kwargs, max_conns = self.special_case_sqlite(u, kwargs)
- elif u.drivername.startswith('mysql'):
- u, kwargs, max_conns = self.special_case_mysql(u, kwargs)
-
- # remove the basedir as it may confuse sqlalchemy
- basedir = kwargs.pop('basedir')
-
- # calculate the maximum number of connections from the pool parameters,
- # if it hasn't already been specified
- if max_conns is None:
- max_conns = kwargs.get('pool_size', 5) + kwargs.get('max_overflow', 10)
-
- engine = strategies.ThreadLocalEngineStrategy.create(self,
- u, **kwargs)
-
- # annotate the engine with the optimal thread pool size; this is used
- # by DBConnector to configure the surrounding thread pool
- engine.optimal_thread_pool_size = max_conns
-
- # keep the basedir
- engine.buildbot_basedir = basedir
-
- if u.drivername.startswith('sqlite'):
- self.set_up_sqlite_engine(u, engine)
- elif u.drivername.startswith('mysql'):
- self.set_up_mysql_engine(u, engine)
-
- return engine
-
-BuildbotEngineStrategy()
-
-# this module is really imported for the side-effects, but pyflakes will like
-# us to use something from the module -- so offer a copy of create_engine,
-# which explicitly adds the strategy argument
-def create_engine(*args, **kwargs):
- kwargs['strategy'] = 'buildbot'
-
- return sa.create_engine(*args, **kwargs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py
deleted file mode 100644
index c8fbd6d6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-class DatabaseNotReadyError(Exception):
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg
deleted file mode 100644
index d63b6835..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg
+++ /dev/null
@@ -1,20 +0,0 @@
-[db_settings]
-# Used to identify which repository this database is versioned under.
-# You can use the name of your project.
-repository_id=Buildbot
-
-# The name of the database table used to track the schema version.
-# This name shouldn't already be used by your project.
-# If this is changed once a database is under version control, you'll need to
-# change the table name in each database too.
-version_table=migrate_version
-
-# When committing a change script, Migrate will attempt to generate the
-# sql for all supported databases; normally, if one of them fails - probably
-# because you don't have that database installed - it is ignored and the
-# commit continues, perhaps ending successfully.
-# Databases in this list MUST compile successfully during a commit, or the
-# entire commit will fail. List the databases your application will actually
-# be using to ensure your updates to that database work properly.
-# This must be a list; example: ['postgres','sqlite']
-required_dbs=[]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py
deleted file mode 100644
index 297d7a2c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py
+++ /dev/null
@@ -1,283 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import cPickle
-from twisted.persisted import styles
-from buildbot.util import json
-import sqlalchemy as sa
-
-metadata = sa.MetaData()
-
-last_access = sa.Table('last_access', metadata,
- sa.Column('who', sa.String(256), nullable=False),
- sa.Column('writing', sa.Integer, nullable=False),
- sa.Column('last_access', sa.Integer, nullable=False),
-)
-
-changes_nextid = sa.Table('changes_nextid', metadata,
- sa.Column('next_changeid', sa.Integer),
-)
-
-changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
-)
-
-change_links = sa.Table('change_links', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('link', sa.String(1024), nullable=False),
-)
-
-change_files = sa.Table('change_files', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('filename', sa.String(1024), nullable=False),
-)
-
-change_properties = sa.Table('change_properties', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
-)
-
-schedulers = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('state', sa.String(1024), nullable=False),
-)
-
-scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer, sa.ForeignKey('schedulers.schedulerid')),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid')),
- sa.Column('important', sa.SmallInteger),
-)
-
-scheduler_upstream_buildsets = sa.Table('scheduler_upstream_buildsets', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id')),
- sa.Column('schedulerid', sa.Integer, sa.ForeignKey('schedulers.schedulerid')),
- sa.Column('active', sa.SmallInteger),
-)
-
-sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
-)
-
-patches = sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('patchlevel', sa.Integer, nullable=False),
- sa.Column('patch_base64', sa.Text, nullable=False),
- sa.Column('subdir', sa.Text),
-)
-
-sourcestamp_changes = sa.Table('sourcestamp_changes', metadata,
- sa.Column('sourcestampid', sa.Integer, sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
-)
-
-buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer, sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False, server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
-)
-
-buildset_properties = sa.Table('buildset_properties', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id'), nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
-)
-
-buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"), nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False, server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=256)),
- sa.Column('claimed_by_incarnation', sa.String(length=256)),
- sa.Column('complete', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
-)
-
-builds = sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'), nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
-)
-
-def test_unicode(migrate_engine):
- """Test that the database can handle inserting and selecting Unicode"""
- # set up a subsidiary MetaData object to hold this temporary table
- submeta = sa.MetaData()
- submeta.bind = migrate_engine
-
- test_unicode = sa.Table('test_unicode', submeta,
- sa.Column('u', sa.Unicode(length=100)),
- sa.Column('b', sa.LargeBinary),
- )
- test_unicode.create()
-
- # insert a unicode value in there
- u = u"Frosty the \N{SNOWMAN}"
- b='\xff\xff\x00'
- ins = test_unicode.insert().values(u=u, b=b)
- migrate_engine.execute(ins)
-
- # see if the data is intact
- row = migrate_engine.execute(sa.select([test_unicode])).fetchall()[0]
- assert type(row['u']) is unicode
- assert row['u'] == u
- assert type(row['b']) is str
- assert row['b'] == b
-
- # drop the test table
- test_unicode.drop()
-
-def import_changes(migrate_engine):
- # get the basedir from the engine - see model.py if you're wondering
- # how it got there
- basedir = migrate_engine.buildbot_basedir
-
- # strip None from any of these values, just in case
- def remove_none(x):
- if x is None: return u""
- elif isinstance(x, str):
- return x.decode("utf8")
- else:
- return x
-
- # if we still have a changes.pck, then we need to migrate it
- changes_pickle = os.path.join(basedir, "changes.pck")
- if not os.path.exists(changes_pickle):
- migrate_engine.execute(changes_nextid.insert(),
- next_changeid=1)
- return
-
- #if not quiet: print "migrating changes.pck to database"
-
- # 'source' will be an old b.c.changes.ChangeMaster instance, with a
- # .changes attribute. Note that we use 'r', and not 'rb', because these
- # pickles were written using the old text pickle format, which requires
- # newline translation
- with open(changes_pickle,"r") as f:
- source = cPickle.load(f)
- styles.doUpgrade()
-
- #if not quiet: print " (%d Change objects)" % len(source.changes)
-
- # first, scan for changes without a number. If we find any, then we'll
- # renumber the changes sequentially
- have_unnumbered = False
- for c in source.changes:
- if c.revision and c.number is None:
- have_unnumbered = True
- break
- if have_unnumbered:
- n = 1
- for c in source.changes:
- if c.revision:
- c.number = n
- n = n + 1
-
- # insert the changes
- for c in source.changes:
- if not c.revision:
- continue
- try:
- values = dict(
- changeid=c.number,
- author=c.who,
- comments=c.comments,
- is_dir=c.isdir,
- branch=c.branch,
- revision=c.revision,
- revlink=c.revlink,
- when_timestamp=c.when,
- category=c.category)
- values = dict([ (k, remove_none(v)) for k, v in values.iteritems() ])
- except UnicodeDecodeError, e:
- raise UnicodeError("Trying to import change data as UTF-8 failed. Please look at contrib/fix_changes_pickle_encoding.py: %s" % str(e))
-
- migrate_engine.execute(changes.insert(), **values)
-
- # NOTE: change_links is not populated, since it is deleted in db
- # version 20. The table is still created, though.
-
- # sometimes c.files contains nested lists -- why, I do not know! But we deal with
- # it all the same - see bug #915. We'll assume for now that c.files contains *either*
- # lists of filenames or plain filenames, not both.
- def flatten(l):
- if l and type(l[0]) == list:
- rv = []
- for e in l:
- if type(e) == list:
- rv.extend(e)
- else:
- rv.append(e)
- return rv
- else:
- return l
- for filename in flatten(c.files):
- migrate_engine.execute(change_files.insert(),
- changeid=c.number,
- filename=filename)
-
- for propname,propvalue in c.properties.properties.items():
- encoded_value = json.dumps(propvalue)
- migrate_engine.execute(change_properties.insert(),
- changeid=c.number,
- property_name=propname,
- property_value=encoded_value)
-
- # update next_changeid
- max_changeid = max([ c.number for c in source.changes if c.revision ] + [ 0 ])
- migrate_engine.execute(changes_nextid.insert(),
- next_changeid=max_changeid+1)
-
- #if not quiet:
- # print "moving changes.pck to changes.pck.old; delete it or keep it as a backup"
- os.rename(changes_pickle, changes_pickle+".old")
-
-def upgrade(migrate_engine):
- metadata.bind = migrate_engine
-
- # do some tests before getting started
- test_unicode(migrate_engine)
-
- # create the initial schema
- metadata.create_all()
-
- # and import some changes
- import_changes(migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py
deleted file mode 100644
index ad221553..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # add project and repository columns to 'changes' an 'sourcestamps'
- def add_cols(table):
- repository = sa.Column('repository', sa.String(512), nullable=False, server_default=sa.DefaultClause(''))
- repository.create(table, populate_default=True)
- project = sa.Column('project', sa.String(512), nullable=False, server_default=sa.DefaultClause(''))
- project.create(table, populate_default=True)
-
- add_cols(sa.Table('changes', metadata, autoload=True))
- add_cols(sa.Table('sourcestamps', metadata, autoload=True))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py
deleted file mode 100644
index 0a3a4f36..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # add an empty class_name to the schedulers table
- schedulers = sa.Table('schedulers', metadata, autoload=True)
- class_name = sa.Column('class_name', sa.String(length=128), nullable=False, server_default=sa.DefaultClause(''))
- class_name.create(schedulers, populate_default=True)
-
- # and an index since we'll be selecting with (name= AND class=)
- idx = sa.Index('name_and_class', schedulers.c.name, schedulers.c.class_name)
- idx.create(migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py
deleted file mode 100644
index c0ec66e6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # re-include some of the relevant tables, as they were in version 3, since
- # sqlalchemy's reflection doesn't work very well for defaults. These must
- # be complete table specifications as for some dialects sqlalchemy will
- # create a brand new, temporary table, and copy data over
-
- sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, autoincrement=False,
- primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('state', sa.String(1024), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
-
- sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, autoincrement=False,
- primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.Text, nullable=False, server_default=''),
- sa.Column('project', sa.Text, nullable=False, server_default=''),
- )
-
- sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('patchlevel', sa.Integer, nullable=False),
- sa.Column('patch_base64', sa.Text, nullable=False),
- sa.Column('subdir', sa.Text),
- )
-
- sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, autoincrement=True, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
- sa.Column('repository', sa.Text(length=None), nullable=False,
- server_default=''),
- sa.Column('project', sa.Text(length=None), nullable=False,
- server_default=''),
- )
-
- sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer,
- sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
-
- sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
- nullable=False),
- sa.Column('buildername', sa.String(length=None), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=None)),
- sa.Column('claimed_by_incarnation', sa.String(length=None)),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
-
- sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
- )
-
- to_autoinc = [ s.split(".") for s in
- "schedulers.schedulerid",
- "builds.id",
- "changes.changeid",
- "buildrequests.id",
- "buildsets.id",
- "patches.id",
- "sourcestamps.id",
- ]
-
- # It seems that SQLAlchemy's ALTER TABLE doesn't work when migrating from
- # INTEGER to PostgreSQL's SERIAL data type (which is just pseudo data type
- # for INTEGER with SEQUENCE), so we have to work-around this with raw SQL.
- if migrate_engine.dialect.name in ('postgres', 'postgresql'):
- for table_name, col_name in to_autoinc:
- migrate_engine.execute("CREATE SEQUENCE %s_%s_seq"
- % (table_name, col_name))
- migrate_engine.execute("ALTER TABLE %s ALTER COLUMN %s SET DEFAULT nextval('%s_%s_seq'::regclass)"
- % (table_name, col_name, table_name, col_name))
- migrate_engine.execute("ALTER SEQUENCE %s_%s_seq OWNED BY %s.%s"
- % (table_name, col_name, table_name, col_name))
- else:
- for table_name, col_name in to_autoinc:
- table = metadata.tables[table_name]
- col = table.c[col_name]
- col.alter(autoincrement=True)
-
-
- # also drop the changes_nextid table here (which really should have been a
- # sequence..)
- table = sa.Table('changes_nextid', metadata, autoload=True)
- table.drop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py
deleted file mode 100644
index bb0a3d65..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # note that all of the tables defined here omit the ForeignKey constraints;
- # this just lets this code specify the tables in any order; the tables are
- # not re-created here, so this omission causes no problems - the key
- # constraints are still defined in the table
-
- def add_index(table_name, col_name):
- idx_name = "%s_%s" % (table_name, col_name)
- idx = sa.Index(idx_name, metadata.tables[table_name].c[col_name])
- idx.create(migrate_engine)
-
- sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, nullable=False),
- sa.Column('buildername', sa.String(length=None), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False),
- sa.Column('claimed_at', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=None)),
- sa.Column('claimed_by_incarnation', sa.String(length=None)),
- sa.Column('complete', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
- add_index("buildrequests", "buildsetid")
- add_index("buildrequests", "buildername")
- add_index("buildrequests", "complete")
- add_index("buildrequests", "claimed_at")
- add_index("buildrequests", "claimed_by_name")
-
- sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
- )
- add_index("builds", "number")
- add_index("builds", "brid")
-
- sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer, nullable=False),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False, server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
- add_index("buildsets", "complete")
- add_index("buildsets", "submitted_at")
-
- sa.Table('buildset_properties', metadata,
- sa.Column('buildsetid', sa.Integer, nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
- add_index("buildset_properties", "buildsetid")
-
- sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.Text, nullable=False, server_default=''),
- sa.Column('project', sa.Text, nullable=False, server_default=''),
- )
- add_index("changes", "branch")
- add_index("changes", "revision")
- add_index("changes", "author")
- add_index("changes", "category")
- add_index("changes", "when_timestamp")
-
- sa.Table('change_files', metadata,
- sa.Column('changeid', sa.Integer, nullable=False),
- sa.Column('filename', sa.String(1024), nullable=False),
- )
- add_index("change_files", "changeid")
-
- sa.Table('change_links', metadata,
- sa.Column('changeid', sa.Integer, nullable=False),
- sa.Column('link', sa.String(1024), nullable=False),
- )
- add_index("change_links", "changeid")
-
- sa.Table('change_properties', metadata,
- sa.Column('changeid', sa.Integer, nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
- add_index("change_properties", "changeid")
-
- # schedulers already has an index
-
- sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer),
- sa.Column('changeid', sa.Integer),
- sa.Column('important', sa.SmallInteger),
- )
- add_index("scheduler_changes", "schedulerid")
- add_index("scheduler_changes", "changeid")
-
- sa.Table('scheduler_upstream_buildsets', metadata,
- sa.Column('buildsetid', sa.Integer),
- sa.Column('schedulerid', sa.Integer),
- sa.Column('active', sa.SmallInteger),
- )
- add_index("scheduler_upstream_buildsets", "buildsetid")
- add_index("scheduler_upstream_buildsets", "schedulerid")
- add_index("scheduler_upstream_buildsets", "active")
-
- # sourcestamps are only queried by id, no need for additional indexes
-
- sa.Table('sourcestamp_changes', metadata,
- sa.Column('sourcestampid', sa.Integer, nullable=False),
- sa.Column('changeid', sa.Integer, nullable=False),
- )
- add_index("sourcestamp_changes", "sourcestampid")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py
deleted file mode 100644
index fc807714..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- table = sa.Table('last_access', metadata, autoload=True)
- table.drop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py
deleted file mode 100644
index e09b0c8c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
- objects.create()
-
- object_state = sa.Table("object_state", metadata,
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- sa.Column("name", sa.String(length=256), nullable=False),
- sa.Column("value_json", sa.Text, nullable=False),
- sa.UniqueConstraint('objectid', 'name', name='name_per_object'),
- )
- object_state.create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py
deleted file mode 100644
index e758576b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer),
- sa.Column('changeid', sa.Integer),
- sa.Column('important', sa.SmallInteger),
- )
-
- idx = sa.Index('scheduler_changes_unique',
- scheduler_changes.c.schedulerid,
- scheduler_changes.c.changeid, unique=True)
- idx.create(migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py
deleted file mode 100644
index fc1771c2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # add patch_author and patch_comment to the patches table
-
- # mysql doesn't like default values on these columns
- defaults = {}
- if migrate_engine.dialect.name != "mysql":
- defaults['server_default'] = sa.DefaultClause('')
-
- patches = sa.Table('patches', metadata, autoload=True)
- patch_author= sa.Column('patch_author', sa.Text, nullable=False,
- **defaults)
- patch_author.create(patches, populate_default=True)
-
- patch_author= sa.Column('patch_comment', sa.Text, nullable=False,
- **defaults)
- patch_author.create(patches, populate_default=True)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py
deleted file mode 100644
index a3ae3e14..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from migrate import changeset
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # the old (non-sqlalchemy-migrate) migration scripts messed up the
- # lengths of these columns, so fix them here.
- changeset.alter_column(
- sa.Column('class_name', sa.String(128), nullable=False),
- table="schedulers",
- metadata=metadata,
- engine=migrate_engine)
-
- changeset.alter_column(
- sa.Column('name', sa.String(128), nullable=False),
- table="schedulers",
- metadata=metadata,
- engine=migrate_engine)
-
- # sqlalchemy's reflection gets the server_defaults wrong, so this
- # table has to be included here.
- changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
- )
- changeset.alter_column(
- sa.Column('author', sa.String(256), nullable=False),
- table=changes,
- metadata=metadata,
- engine=migrate_engine)
- changeset.alter_column(
- sa.Column('branch', sa.String(256)),
- table=changes,
- metadata=metadata,
- engine=migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py
deleted file mode 100644
index 21e93c01..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-import migrate
-from buildbot.util import sautils
-
-def migrate_claims(migrate_engine, metadata, buildrequests, objects,
- buildrequest_claims):
-
- # First, ensure there is an object row for each master
- null_id = sa.null().label('id')
- if migrate_engine.dialect.name == 'postgresql':
- # postgres needs NULL cast to an integer:
- null_id = sa.cast(null_id, sa.INTEGER)
- new_objects = sa.select([
- null_id,
- buildrequests.c.claimed_by_name.label("name"),
- sa.literal_column("'BuildMaster'").label("class_name"),
- ],
- whereclause=buildrequests.c.claimed_by_name != None,
- distinct=True)
-
- # this doesn't seem to work without str() -- verified in sqla 0.6.0 - 0.7.1
- migrate_engine.execute(
- str(sautils.InsertFromSelect(objects, new_objects)))
-
- # now make a buildrequest_claims row for each claimed build request
- join = buildrequests.join(objects,
- (buildrequests.c.claimed_by_name == objects.c.name)
- # (have to use sa.text because str, below, doesn't work
- # with placeholders)
- & (objects.c.class_name == sa.text("'BuildMaster'")))
- claims = sa.select([
- buildrequests.c.id.label('brid'),
- objects.c.id.label('objectid'),
- buildrequests.c.claimed_at,
- ], from_obj=[ join ],
- whereclause=buildrequests.c.claimed_by_name != None)
- migrate_engine.execute(
- str(sautils.InsertFromSelect(buildrequest_claims, claims)))
-
-def drop_columns(metadata, buildrequests):
- # sqlalchemy-migrate <0.7.0 has a bug with sqlalchemy >=0.7.0, where
- # it tries to change an immutable column; this is the workaround, from
- # http://code.google.com/p/sqlalchemy-migrate/issues/detail?id=112
- if not sa.__version__.startswith('0.6.'):
- if not hasattr(migrate, '__version__'): # that is, older than 0.7
- buildrequests.columns = buildrequests._columns
-
- buildrequests.c.claimed_at.drop()
- buildrequests.c.claimed_by_name.drop()
- buildrequests.c.claimed_by_incarnation.drop()
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # a copy of the buildrequests table, but with the foreign keys stripped
- buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=256)),
- sa.Column('claimed_by_incarnation', sa.String(length=256)),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
-
- # existing objects table, used as a foreign key
- objects = sa.Table("objects", metadata,
- # unique ID for this object
- sa.Column("id", sa.Integer, primary_key=True),
- # object's user-given name
- sa.Column('name', sa.String(128), nullable=False),
- # object's class name, basically representing a "type" for the state
- sa.Column('class_name', sa.String(128), nullable=False),
-
- # prohibit multiple id's for the same object
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
-
- # and a new buildrequest_claims table
- buildrequest_claims = sa.Table('buildrequest_claims', metadata,
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- index=True, unique=True),
- sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id'),
- index=True, nullable=True),
- sa.Column('claimed_at', sa.Integer, nullable=False),
- )
-
- # create the new table
- buildrequest_claims.create()
-
- # migrate the claims into that table
- migrate_claims(migrate_engine, metadata, buildrequests,
- objects, buildrequest_claims)
-
- # and drop the claim-related columns in buildrequests
- drop_columns(metadata, buildrequests)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py
deleted file mode 100644
index a485bcb1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # what defines a user
- users = sa.Table("users", metadata,
- sa.Column("uid", sa.Integer, primary_key=True),
- sa.Column("identifier", sa.String(256), nullable=False),
- )
- users.create()
-
- idx = sa.Index('users_identifier', users.c.identifier)
- idx.create()
-
- # ways buildbot knows about users
- users_info = sa.Table("users_info", metadata,
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False),
- sa.Column("attr_type", sa.String(128), nullable=False),
- sa.Column("attr_data", sa.String(128), nullable=False)
- )
- users_info.create()
-
- idx = sa.Index('users_info_uid', users_info.c.uid)
- idx.create()
- idx = sa.Index('users_info_uid_attr_type', users_info.c.uid,
- users_info.c.attr_type, unique=True)
- idx.create()
- idx = sa.Index('users_info_attrs', users_info.c.attr_type,
- users_info.c.attr_data, unique=True)
- idx.create()
-
- # correlates change authors and user uids
- sa.Table('changes', metadata, autoload=True)
- change_users = sa.Table("change_users", metadata,
- sa.Column("changeid", sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False)
- )
- change_users.create()
-
- idx = sa.Index('change_users_changeid', change_users.c.changeid)
- idx.create()
-
- # note that existing changes are not added to the users table; this would
- # be *very* time-consuming and would not be helpful to the vast majority of
- # users.
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py
deleted file mode 100644
index 0bce4d47..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from migrate import changeset
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # Specify what the new table should look like
- schedulers = sa.Table("schedulers", metadata,
- # unique ID for scheduler
- sa.Column('schedulerid', sa.Integer, primary_key=True), # TODO: rename to id
- # scheduler's name in master.cfg
- sa.Column('name', sa.String(128), nullable=False),
- # scheduler's class name, basically representing a "type" for the state
- sa.Column('class_name', sa.String(128), nullable=False),
- )
-
- # Now drop column
- changeset.drop_column(
- sa.Column('state', sa.String(128), nullable=False),
- table=schedulers,
- metadata=metadata,
- engine=migrate_engine)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py
deleted file mode 100644
index b115a1e9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- users_table = sa.Table('users', metadata, autoload=True)
-
- username = sa.Column('bb_username', sa.String(128))
- username.create(users_table)
- password = sa.Column('bb_password', sa.String(128))
- password.create(users_table)
-
- idx = sa.Index('users_bb_user', users_table.c.bb_username, unique=True)
- idx.create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py
deleted file mode 100644
index 4f17f719..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # older build masters stored some of their state with an object named
- # 'master' with class 'buildbot.master.BuildMaster', while other state was
- # stored with objects named after each master itself, with class
- # BuildMaster.
-
- objects_table = sa.Table('objects', metadata, autoload=True)
- object_state_table = sa.Table('object_state', metadata, autoload=True)
-
- # get the old, unwanted ID
- q = sa.select([ objects_table.c.id ],
- whereclause=(objects_table.c.name=='master')
- & (objects_table.c.class_name == 'buildbot.master.BuildMaster'))
- res = q.execute()
- old_id = res.scalar()
-
- # if there's no such ID, there's nothing to change
- if old_id is not None:
-
- # get the new ID
- q = sa.select([ objects_table.c.id ],
- whereclause=objects_table.c.class_name == 'BuildMaster')
- res = q.execute()
- ids = res.fetchall()
-
- # if there is exactly one ID, update the existing object_states. If
- # there are zero or multiple object_states, then we do not know which
- # master to assign last_processed_change to, so we just delete it.
- # This indicates to the master that it has processed all changes, which
- # is probably accurate.
- if len(ids) == 1:
- new_id = ids[0][0]
-
- # update rows with the old id to use the new id
- q = object_state_table.update(
- whereclause=(object_state_table.c.objectid == old_id))
- q.execute(objectid=new_id)
- else:
- q = object_state_table.delete(
- whereclause=(object_state_table.c.objectid == old_id))
- q.execute()
-
- # in either case, delete the old object row
- q = objects_table.delete(
- whereclause=(objects_table.c.id == old_id))
- q.execute()
-
- # and update the class name for the new rows
- q = objects_table.update(
- whereclause=(objects_table.c.class_name == 'BuildMaster'))
- q.execute(class_name='buildbot.master.BuildMaster')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py
deleted file mode 100644
index 78d60051..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # the column drops in 011_add_buildrequest_claims.py unfortunately
- # also drop a great deal of other stuff on sqlite. In particular, all
- # indexes and foreign keys.
- #
- # The foreign keys do not matter anyway - SQLite tracks them but ignores
- # them. The indices, however, are important, so they are re-added here,
- # but only for the sqlite dialect.
-
- if migrate_engine.dialect.name != 'sqlite':
- return
-
- buildrequests = sa.Table('buildrequests', metadata, autoload=True)
- sa.Index('buildrequests_buildsetid', buildrequests.c.buildsetid).create()
- sa.Index('buildrequests_buildername', buildrequests.c.buildername).create()
- sa.Index('buildrequests_complete', buildrequests.c.complete).create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py
deleted file mode 100644
index 59d2f8aa..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # the column changes in 010_fix_column_lengths.py unfortunately also drop a
- # great deal of other stuff on sqlite. In particular, all indexes and
- # foreign keys on the 'changes' and 'schedulers' tables.
- #
- # The foreign keys do not matter anyway - SQLite tracks them but ignores
- # them. The indices, however, are important, so they are re-added here,
- # but only for the sqlite dialect.
-
- if migrate_engine.dialect.name == 'sqlite':
- schedulers = sa.Table('schedulers', metadata, autoload=True)
-
- sa.Index('name_and_class',
- schedulers.c.name, schedulers.c.class_name).create()
-
- changes = sa.Table('changes', metadata, autoload=True)
-
- sa.Index('changes_branch', changes.c.branch).create()
- sa.Index('changes_revision', changes.c.revision).create()
- sa.Index('changes_author', changes.c.author).create()
- sa.Index('changes_category', changes.c.category).create()
- sa.Index('changes_when_timestamp', changes.c.when_timestamp).create()
-
- # These were implemented as UniqueConstraint objects, which are
- # recognized as indexes on non-sqlite DB's. So add them as explicit
- # indexes on sqlite.
-
- objects = sa.Table('objects', metadata, autoload=True)
- sa.Index('object_identity', objects.c.name, objects.c.class_name,
- unique=True).create()
-
- object_state = sa.Table('object_state', metadata, autoload=True)
- sa.Index('name_per_object', object_state.c.objectid,
- object_state.c.name, unique=True).create()
-
- # Due to a coding bug in version 012, the users_identifier index is not
- # unique (on any DB). SQLAlchemy-migrate does not provide an interface to
- # drop columns, so we fake it here.
-
- users = sa.Table('users', metadata, autoload=True)
-
- dialect = migrate_engine.dialect.name
- if dialect in ('sqlite', 'postgresql'):
- migrate_engine.execute("DROP INDEX users_identifier")
- elif dialect == 'mysql':
- migrate_engine.execute("DROP INDEX users_identifier ON users")
-
- sa.Index('users_identifier', users.c.identifier, unique=True).create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py
deleted file mode 100644
index b8de49cb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from migrate.changeset import constraint
-from buildbot.util import sautils
-
-def upgrade(migrate_engine):
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- sourcestamps_table = sa.Table('sourcestamps', metadata, autoload=True)
- buildsets_table = sa.Table('buildsets', metadata, autoload=True)
-
- # Create the sourcestampset table
- # that defines a sourcestampset
- sourcestampsets_table = sa.Table("sourcestampsets", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- )
- sourcestampsets_table.create()
-
- # All current sourcestampid's are migrated to sourcestampsetid
- # Insert all sourcestampid's as setid's into sourcestampsets table
- sourcestampsetids = sa.select([sourcestamps_table.c.id])
- # this doesn't seem to work without str() -- verified in sqla 0.6.0 - 0.7.1
- migrate_engine.execute(str(sautils.InsertFromSelect(sourcestampsets_table, sourcestampsetids)))
-
- # rename the buildsets table column
- buildsets_table.c.sourcestampid.alter(name='sourcestampsetid')
-
- metadata.remove(buildsets_table)
- buildsets_table = sa.Table('buildsets', metadata, autoload=True)
-
- cons = constraint.ForeignKeyConstraint([buildsets_table.c.sourcestampsetid], [sourcestampsets_table.c.id])
- cons.create()
-
- # Add sourcestampsetid including index to sourcestamps table
- ss_sourcestampsetid = sa.Column('sourcestampsetid', sa.Integer)
- ss_sourcestampsetid.create(sourcestamps_table)
-
- # Update the setid to the same value as sourcestampid
- migrate_engine.execute(str(sourcestamps_table.update().values(sourcestampsetid=sourcestamps_table.c.id)))
- ss_sourcestampsetid.alter(nullable=False)
-
- # Data is up to date, now force integrity
- cons = constraint.ForeignKeyConstraint([sourcestamps_table.c.sourcestampsetid], [sourcestampsets_table.c.id])
- cons.create()
-
- # Add index for performance reasons to find all sourcestamps in a set quickly
- idx = sa.Index('sourcestamps_sourcestampsetid', sourcestamps_table.c.sourcestampsetid, unique=False)
- idx.create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py
deleted file mode 100644
index bd2cc5c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # autoload the tables that are only referenced here
- sa.Table('changes', metadata, autoload=True)
- sa.Table('buildsets', metadata, autoload=True)
- sa.Table("objects", metadata, autoload=True)
-
- # drop all tables. Schedulers will re-populate on startup
-
- scheduler_changes_tbl = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer),
- # ...
- )
- scheduler_changes_tbl.drop()
- metadata.remove(scheduler_changes_tbl)
-
- scheduler_upstream_buildsets_tbl = sa.Table('scheduler_upstream_buildsets',
- metadata,
- sa.Column('buildsetid', sa.Integer),
- # ...
- )
- scheduler_upstream_buildsets_tbl.drop()
- metadata.remove(scheduler_upstream_buildsets_tbl)
-
- schedulers_tbl = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer),
- # ...
- )
- schedulers_tbl.drop()
- metadata.remove(schedulers_tbl)
-
- # schedulers and scheduler_upstream_buildsets aren't coming back, but
- # scheduler_changes is -- along with its indexes
-
- scheduler_changes_tbl = sa.Table('scheduler_changes', metadata,
- sa.Column('objectid', sa.Integer,
- sa.ForeignKey('objects.id')),
- sa.Column('changeid', sa.Integer,
- sa.ForeignKey('changes.changeid')),
- sa.Column('important', sa.Integer),
- )
- scheduler_changes_tbl.create()
-
- idx = sa.Index('scheduler_changes_objectid',
- scheduler_changes_tbl.c.objectid)
- idx.create()
-
- idx = sa.Index('scheduler_changes_changeid',
- scheduler_changes_tbl.c.changeid)
- idx.create()
-
- idx = sa.Index('scheduler_changes_unique',
- scheduler_changes_tbl.c.objectid,
- scheduler_changes_tbl.c.changeid, unique=True)
- idx.create()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py
deleted file mode 100644
index a955b4c5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- tbl = sa.Table('change_links', metadata, autoload=True)
- tbl.drop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py
deleted file mode 100644
index f412073d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
- # see bug #2119
-
- # this only applies to postgres
- if migrate_engine.dialect.name != 'postgresql':
- return
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- to_fix = [
- 'buildrequests.id',
- 'builds.id',
- 'buildsets.id',
- 'changes.changeid',
- 'patches.id',
- 'sourcestampsets.id',
- 'sourcestamps.id',
- 'objects.id',
- 'users.uid',
- ]
-
- for col in to_fix:
- tbl_name, col_name = col.split('.')
- tbl = sa.Table(tbl_name, metadata, autoload=True)
- col = tbl.c[col_name]
-
- res = migrate_engine.execute(sa.select([ sa.func.max(col) ]))
- max = res.fetchall()[0][0]
-
- if max:
- seq_name = "%s_%s_seq" % (tbl_name, col_name)
- r = migrate_engine.execute("SELECT setval('%s', %d)"
- % (seq_name, max))
- r.close()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py
deleted file mode 100644
index 7f03efc0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-
-def upgrade(migrate_engine):
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- sourcestamps_table = sa.Table('sourcestamps', metadata, autoload=True)
- changes_table = sa.Table('changes', metadata, autoload=True)
-
-
- # Add codebase to tables
- ss_codebase = sa.Column('codebase', sa.String(length=256), nullable=False,
- server_default=sa.DefaultClause(""))
- ss_codebase.create(sourcestamps_table)
-
- c_codebase = sa.Column('codebase', sa.String(length=256), nullable=False,
- server_default=sa.DefaultClause(""))
- c_codebase.create(changes_table)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py
deleted file mode 100644
index 263e9cfb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py
+++ /dev/null
@@ -1,539 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-import migrate
-import migrate.versioning.schema
-import migrate.versioning.repository
-from twisted.python import util, log
-from buildbot.db import base
-
-try:
- from migrate.versioning import exceptions
- _hush_pyflakes = exceptions
-except ImportError:
- from migrate import exceptions
-
-class Model(base.DBConnectorComponent):
- #
- # schema
- #
-
- metadata = sa.MetaData()
-
- # NOTES
-
- # * server_defaults here are included to match those added by the migration
- # scripts, but they should not be depended on - all code accessing these
- # tables should supply default values as necessary. The defaults are
- # required during migration when adding non-nullable columns to existing
- # tables.
- #
- # * dates are stored as unix timestamps (UTC-ish epoch time)
- #
- # * sqlalchemy does not handle sa.Boolean very well on MySQL or Postgres;
- # use sa.Integer instead
-
- # build requests
-
- # A BuildRequest is a request for a particular build to be performed. Each
- # BuildRequest is a part of a Buildset. BuildRequests are claimed by
- # masters, to avoid multiple masters running the same build.
- buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
- nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
-
- # if this is zero, then the build is still pending
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
-
- # results is only valid when complete == 1; 0 = SUCCESS, 1 = WARNINGS,
- # etc - see master/buildbot/status/builder.py
- sa.Column('results', sa.SmallInteger),
-
- # time the buildrequest was created
- sa.Column('submitted_at', sa.Integer, nullable=False),
-
- # time the buildrequest was completed, or NULL
- sa.Column('complete_at', sa.Integer),
- )
-
- # Each row in this table represents a claimed build request, where the
- # claim is made by the object referenced by objectid.
- buildrequest_claims = sa.Table('buildrequest_claims', metadata,
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- index=True, unique=True),
- sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id'),
- index=True, nullable=True),
- sa.Column('claimed_at', sa.Integer, nullable=False),
- )
-
- # builds
-
- # This table contains basic information about each build. Note that most
- # data about a build is still stored in on-disk pickles.
- builds = sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
- )
-
- # buildsets
-
- # This table contains input properties for buildsets
- buildset_properties = sa.Table('buildset_properties', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id'),
- nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- # JSON-encoded tuple of (value, source)
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
-
- # This table represents Buildsets - sets of BuildRequests that share the
- # same original cause and source information.
- buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
-
- # a simple external identifier to track down this buildset later, e.g.,
- # for try requests
- sa.Column('external_idstring', sa.String(256)),
-
- # a short string giving the reason the buildset was created
- sa.Column('reason', sa.String(256)),
- sa.Column('submitted_at', sa.Integer, nullable=False),
-
- # if this is zero, then the build set is still pending
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
-
- # results is only valid when complete == 1; 0 = SUCCESS, 1 = WARNINGS,
- # etc - see master/buildbot/status/builder.py
- sa.Column('results', sa.SmallInteger),
-
- # buildset belongs to all sourcestamps with setid
- sa.Column('sourcestampsetid', sa.Integer,
- sa.ForeignKey('sourcestampsets.id')),
- )
-
- # changes
-
- # Files touched in changes
- change_files = sa.Table('change_files', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- sa.Column('filename', sa.String(1024), nullable=False),
- )
-
- # Properties for changes
- change_properties = sa.Table('change_properties', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- # JSON-encoded tuple of (value, source)
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
-
- # users associated with this change; this allows multiple users for
- # situations where a version-control system can represent both an author
- # and committer, for example.
- change_users = sa.Table("change_users", metadata,
- sa.Column("changeid", sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- # uid for the author of the change with the given changeid
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False)
- )
-
- # Changes to the source code, produced by ChangeSources
- changes = sa.Table('changes', metadata,
- # changeid also serves as 'change number'
- sa.Column('changeid', sa.Integer, primary_key=True),
-
- # author's name (usually an email address)
- sa.Column('author', sa.String(256), nullable=False),
-
- # commit comment
- sa.Column('comments', sa.String(1024), nullable=False),
-
- # old, CVS-related boolean
- sa.Column('is_dir', sa.SmallInteger, nullable=False), # old, for CVS
-
- # The branch where this change occurred. When branch is NULL, that
- # means the main branch (trunk, master, etc.)
- sa.Column('branch', sa.String(256)),
-
- # revision identifier for this change
- sa.Column('revision', sa.String(256)), # CVS uses NULL
-
- sa.Column('revlink', sa.String(256)),
-
- # this is the timestamp of the change - it is usually copied from the
- # version-control system, and may be long in the past or even in the
- # future!
- sa.Column('when_timestamp', sa.Integer, nullable=False),
-
- # an arbitrary string used for filtering changes
- sa.Column('category', sa.String(256)),
-
- # repository specifies, along with revision and branch, the
- # source tree in which this change was detected.
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
-
- # codebase is a logical name to specify what is in the repository
- sa.Column('codebase', sa.String(256), nullable=False,
- server_default=sa.DefaultClause("")),
-
- # project names the project this source code represents. It is used
- # later to filter changes
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
- )
-
- # sourcestamps
-
- # Patches for SourceStamps that were generated through the try mechanism
- patches = sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
-
- # number of directory levels to strip off (patch -pN)
- sa.Column('patchlevel', sa.Integer, nullable=False),
-
- # base64-encoded version of the patch file
- sa.Column('patch_base64', sa.Text, nullable=False),
-
- # patch author, if known
- sa.Column('patch_author', sa.Text, nullable=False),
-
- # patch comment
- sa.Column('patch_comment', sa.Text, nullable=False),
-
- # subdirectory in which the patch should be applied; NULL for top-level
- sa.Column('subdir', sa.Text),
- )
-
- # The changes that led up to a particular source stamp.
- sourcestamp_changes = sa.Table('sourcestamp_changes', metadata,
- sa.Column('sourcestampid', sa.Integer,
- sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- )
-
- # A sourcestampset identifies a set of sourcestamps. A sourcestamp belongs
- # to a particular set if the sourcestamp has the same setid
- sourcestampsets = sa.Table('sourcestampsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- )
-
- # A sourcestamp identifies a particular instance of the source code.
- # Ideally, this would always be absolute, but in practice source stamps can
- # also mean "latest" (when revision is NULL), which is of course a
- # time-dependent definition.
- sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
-
- # the branch to check out. When branch is NULL, that means
- # the main branch (trunk, master, etc.)
- sa.Column('branch', sa.String(256)),
-
- # the revision to check out, or the latest if NULL
- sa.Column('revision', sa.String(256)),
-
- # the patch to apply to generate this source code
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
-
- # the repository from which this source should be checked out
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
-
- # codebase is a logical name to specify what is in the repository
- sa.Column('codebase', sa.String(256), nullable=False,
- server_default=sa.DefaultClause("")),
-
- # the project this source code represents
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
-
- # each sourcestamp belongs to a set of sourcestamps
- sa.Column('sourcestampsetid', sa.Integer,
- sa.ForeignKey('sourcestampsets.id')),
- )
-
- # schedulers
-
- # This table references "classified" changes that have not yet been
- # "processed". That is, the scheduler has looked at these changes and
- # determined that something should be done, but that hasn't happened yet.
- # Rows are deleted from this table as soon as the scheduler is done with
- # the change.
- scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id')),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid')),
- # true (nonzero) if this change is important to this scheduler
- sa.Column('important', sa.Integer),
- )
-
- # objects
-
- # This table uniquely identifies objects that need to maintain state across
- # invocations.
- objects = sa.Table("objects", metadata,
- # unique ID for this object
- sa.Column("id", sa.Integer, primary_key=True),
- # object's user-given name
- sa.Column('name', sa.String(128), nullable=False),
- # object's class name, basically representing a "type" for the state
- sa.Column('class_name', sa.String(128), nullable=False),
- )
-
- # This table stores key/value pairs for objects, where the key is a string
- # and the value is a JSON string.
- object_state = sa.Table("object_state", metadata,
- # object for which this value is set
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- # name for this value (local to the object)
- sa.Column("name", sa.String(length=256), nullable=False),
- # value, as a JSON string
- sa.Column("value_json", sa.Text, nullable=False),
- )
-
- #users
-
- # This table identifies individual users, and contains buildbot-specific
- # information about those users.
- users = sa.Table("users", metadata,
- # unique user id number
- sa.Column("uid", sa.Integer, primary_key=True),
-
- # identifier (nickname) for this user; used for display
- sa.Column("identifier", sa.String(256), nullable=False),
-
- # username portion of user credentials for authentication
- sa.Column("bb_username", sa.String(128)),
-
- # password portion of user credentials for authentication
- sa.Column("bb_password", sa.String(128)),
- )
-
- # This table stores information identifying a user that's related to a
- # particular interface - a version-control system, status plugin, etc.
- users_info = sa.Table("users_info", metadata,
- # unique user id number
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False),
-
- # type of user attribute, such as 'git'
- sa.Column("attr_type", sa.String(128), nullable=False),
-
- # data for given user attribute, such as a commit string or password
- sa.Column("attr_data", sa.String(128), nullable=False),
- )
-
-
- # indexes
-
- sa.Index('buildrequests_buildsetid', buildrequests.c.buildsetid)
- sa.Index('buildrequests_buildername', buildrequests.c.buildername)
- sa.Index('buildrequests_complete', buildrequests.c.complete)
- sa.Index('builds_number', builds.c.number)
- sa.Index('builds_brid', builds.c.brid)
- sa.Index('buildsets_complete', buildsets.c.complete)
- sa.Index('buildsets_submitted_at', buildsets.c.submitted_at)
- sa.Index('buildset_properties_buildsetid',
- buildset_properties.c.buildsetid)
- sa.Index('changes_branch', changes.c.branch)
- sa.Index('changes_revision', changes.c.revision)
- sa.Index('changes_author', changes.c.author)
- sa.Index('changes_category', changes.c.category)
- sa.Index('changes_when_timestamp', changes.c.when_timestamp)
- sa.Index('change_files_changeid', change_files.c.changeid)
- sa.Index('change_properties_changeid', change_properties.c.changeid)
- sa.Index('scheduler_changes_objectid', scheduler_changes.c.objectid)
- sa.Index('scheduler_changes_changeid', scheduler_changes.c.changeid)
- sa.Index('scheduler_changes_unique', scheduler_changes.c.objectid,
- scheduler_changes.c.changeid, unique=True)
- sa.Index('sourcestamp_changes_sourcestampid',
- sourcestamp_changes.c.sourcestampid)
- sa.Index('sourcestamps_sourcestampsetid', sourcestamps.c.sourcestampsetid,
- unique=False)
- sa.Index('users_identifier', users.c.identifier, unique=True)
- sa.Index('users_info_uid', users_info.c.uid)
- sa.Index('users_info_uid_attr_type', users_info.c.uid,
- users_info.c.attr_type, unique=True)
- sa.Index('users_info_attrs', users_info.c.attr_type,
- users_info.c.attr_data, unique=True)
- sa.Index('change_users_changeid', change_users.c.changeid)
- sa.Index('users_bb_user', users.c.bb_username, unique=True)
- sa.Index('object_identity', objects.c.name, objects.c.class_name,
- unique=True)
- sa.Index('name_per_object', object_state.c.objectid, object_state.c.name,
- unique=True)
-
- # MySQl creates indexes for foreign keys, and these appear in the
- # reflection. This is a list of (table, index) names that should be
- # expected on this platform
-
- implied_indexes = [
- ('change_users',
- dict(unique=False, column_names=['uid'], name='uid')),
- ('sourcestamps',
- dict(unique=False, column_names=['patchid'], name='patchid')),
- ('sourcestamp_changes',
- dict(unique=False, column_names=['changeid'], name='changeid')),
- ('buildsets',
- dict(unique=False, column_names=['sourcestampsetid'],
- name='buildsets_sourcestampsetid_fkey')),
- ]
-
- #
- # migration support
- #
-
- # this is a bit more complicated than might be expected because the first
- # seven database versions were once implemented using a homespun migration
- # system, and we need to support upgrading masters from that system. The
- # old system used a 'version' table, where SQLAlchemy-Migrate uses
- # 'migrate_version'
-
- repo_path = util.sibpath(__file__, "migrate")
-
- def is_current(self):
- def thd(engine):
- # we don't even have to look at the old version table - if there's
- # no migrate_version, then we're not up to date.
- repo = migrate.versioning.repository.Repository(self.repo_path)
- repo_version = repo.latest
- try:
- # migrate.api doesn't let us hand in an engine
- schema = migrate.versioning.schema.ControlledSchema(engine,
- self.repo_path)
- db_version = schema.version
- except exceptions.DatabaseNotControlledError:
- return False
-
- return db_version == repo_version
- return self.db.pool.do_with_engine(thd)
-
- def upgrade(self):
-
- # here, things are a little tricky. If we have a 'version' table, then
- # we need to version_control the database with the proper version
- # number, drop 'version', and then upgrade. If we have no 'version'
- # table and no 'migrate_version' table, then we need to version_control
- # the database. Otherwise, we just need to upgrade it.
-
- def table_exists(engine, tbl):
- try:
- r = engine.execute("select * from %s limit 1" % tbl)
- r.close()
- return True
- except:
- return False
-
- # http://code.google.com/p/sqlalchemy-migrate/issues/detail?id=100
- # means we cannot use the migrate.versioning.api module. So these
- # methods perform similar wrapping functions to what is done by the API
- # functions, but without disposing of the engine.
- def upgrade(engine):
- schema = migrate.versioning.schema.ControlledSchema(engine,
- self.repo_path)
- changeset = schema.changeset(None)
- for version, change in changeset:
- log.msg('migrating schema version %s -> %d'
- % (version, version + 1))
- schema.runchange(version, change, 1)
-
- def check_sqlalchemy_migrate_version():
- # sqlalchemy-migrate started including a version number in 0.7; we
- # support back to 0.6.1, but not 0.6. We'll use some discovered
- # differences between 0.6.1 and 0.6 to get that resolution.
- version = getattr(migrate, '__version__', 'old')
- if version == 'old':
- try:
- from migrate.versioning import schemadiff
- if hasattr(schemadiff, 'ColDiff'):
- version = "0.6.1"
- else:
- version = "0.6"
- except:
- version = "0.0"
- version_tup = tuple(map(int, version.split('.')))
- log.msg("using SQLAlchemy-Migrate version %s" % (version,))
- if version_tup < (0,6,1):
- raise RuntimeError("You are using SQLAlchemy-Migrate %s. "
- "The minimum version is 0.6.1." % (version,))
-
- def version_control(engine, version=None):
- migrate.versioning.schema.ControlledSchema.create(engine,
- self.repo_path, version)
-
- # the upgrade process must run in a db thread
- def thd(engine):
- # if the migrate_version table exists, we can just let migrate
- # take care of this process.
- if table_exists(engine, 'migrate_version'):
- upgrade(engine)
-
- # if the version table exists, then we can version_control things
- # at that version, drop the version table, and let migrate take
- # care of the rest.
- elif table_exists(engine, 'version'):
- # get the existing version
- r = engine.execute("select version from version limit 1")
- old_version = r.scalar()
-
- # set up migrate at the same version
- version_control(engine, old_version)
-
- # drop the no-longer-required version table, using a dummy
- # metadata entry
- table = sa.Table('version', self.metadata,
- sa.Column('x', sa.Integer))
- table.drop(bind=engine)
-
- # clear the dummy metadata entry
- self.metadata.remove(table)
-
- # and, finally, upgrade using migrate
- upgrade(engine)
-
- # otherwise, this db is uncontrolled, so we just version control it
- # and update it.
- else:
- version_control(engine)
- upgrade(engine)
-
- check_sqlalchemy_migrate_version()
- return self.db.pool.do_with_engine(thd)
-
-# migrate has a bug in one of its warnings; this is fixed in version control
-# (3ba66abc4d), but not yet released. It can't hurt to fix it here, too, so we
-# get realistic tracebacks
-try:
- import migrate.versioning.exceptions as ex1
- import migrate.changeset.exceptions as ex2
- ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning
-except (ImportError,AttributeError):
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py
deleted file mode 100644
index 03c6f940..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-import traceback
-import inspect
-import shutil
-import os
-import sqlalchemy as sa
-import tempfile
-from buildbot.process import metrics
-from twisted.internet import reactor, threads
-from twisted.python import threadpool, log
-
-# set this to True for *very* verbose query debugging output; this can
-# be monkey-patched from master.cfg, too:
-# from buildbot.db import pool
-# pool.debug = True
-debug = False
-_debug_id = 1
-
-def timed_do_fn(f):
- """Decorate a do function to log before, after, and elapsed time,
- with the name of the calling function. This is not speedy!"""
- def wrap(callable, *args, **kwargs):
- global _debug_id
-
- # get a description of the function that called us
- st = traceback.extract_stack(limit=2)
- file, line, name, _ = st[0]
-
- # and its locals
- frame = inspect.currentframe(1)
- locals = frame.f_locals
-
- # invent a unique ID for the description
- id, _debug_id = _debug_id, _debug_id+1
-
- descr = "%s-%08x" % (name, id)
-
- start_time = time.time()
- log.msg("%s - before ('%s' line %d)" % (descr, file, line))
- for name in locals:
- if name in ('self', 'thd'):
- continue
- log.msg("%s - %s = %r" % (descr, name, locals[name]))
-
- # wrap the callable to log the begin and end of the actual thread
- # function
- def callable_wrap(*args, **kargs):
- log.msg("%s - thd start" % (descr,))
- try:
- return callable(*args, **kwargs)
- finally:
- log.msg("%s - thd end" % (descr,))
- d = f(callable_wrap, *args, **kwargs)
-
- def after(x):
- end_time = time.time()
- elapsed = (end_time - start_time) * 1000
- log.msg("%s - after (%0.2f ms elapsed)" % (descr, elapsed))
- return x
- d.addBoth(after)
- return d
- wrap.__name__ = f.__name__
- wrap.__doc__ = f.__doc__
- return wrap
-
-class DBThreadPool(threadpool.ThreadPool):
-
- running = False
-
- # Some versions of SQLite incorrectly cache metadata about which tables are
- # and are not present on a per-connection basis. This cache can be flushed
- # by querying the sqlite_master table. We currently assume all versions of
- # SQLite have this bug, although it has only been observed in 3.4.2. A
- # dynamic check for this bug would be more appropriate. This is documented
- # in bug #1810.
- __broken_sqlite = None
-
- def __init__(self, engine, verbose=False):
- # verbose is used by upgrade scripts, and if it is set we should print
- # messages about versions and other warnings
- log_msg = log.msg
- if verbose:
- def log_msg(m):
- print m
-
- pool_size = 5
-
- # If the engine has an C{optimal_thread_pool_size} attribute, then the
- # maxthreads of the thread pool will be set to that value. This is
- # most useful for SQLite in-memory connections, where exactly one
- # connection (and thus thread) should be used.
- if hasattr(engine, 'optimal_thread_pool_size'):
- pool_size = engine.optimal_thread_pool_size
-
- threadpool.ThreadPool.__init__(self,
- minthreads=1,
- maxthreads=pool_size,
- name='DBThreadPool')
- self.engine = engine
- if engine.dialect.name == 'sqlite':
- vers = self.get_sqlite_version()
- if vers < (3,7):
- log_msg("Using SQLite Version %s" % (vers,))
- log_msg("NOTE: this old version of SQLite does not support "
- "WAL journal mode; a busy master may encounter "
- "'Database is locked' errors. Consider upgrading.")
- if vers < (3,4):
- log_msg("NOTE: this old version of SQLite is not "
- "supported.")
- raise RuntimeError("unsupported SQLite version")
- if self.__broken_sqlite is None:
- self.__class__.__broken_sqlite = self.detect_bug1810()
- brkn = self.__broken_sqlite
- if brkn:
- log_msg("Applying SQLite workaround from Buildbot bug #1810")
- self._start_evt = reactor.callWhenRunning(self._start)
-
- # patch the do methods to do verbose logging if necessary
- if debug:
- self.do = timed_do_fn(self.do)
- self.do_with_engine = timed_do_fn(self.do_with_engine)
-
- def _start(self):
- self._start_evt = None
- if not self.running:
- self.start()
- self._stop_evt = reactor.addSystemEventTrigger(
- 'during', 'shutdown', self._stop)
- self.running = True
-
- def _stop(self):
- self._stop_evt = None
- self.stop()
- self.engine.dispose()
- self.running = False
-
- def shutdown(self):
- """Manually stop the pool. This is only necessary from tests, as the
- pool will stop itself when the reactor stops under normal
- circumstances."""
- if not self._stop_evt:
- return # pool is already stopped
- reactor.removeSystemEventTrigger(self._stop_evt)
- self._stop()
-
- # Try about 170 times over the space of a day, with the last few tries
- # being about an hour apart. This is designed to span a reasonable amount
- # of time for repairing a broken database server, while still failing
- # actual problematic queries eventually
- BACKOFF_START = 1.0
- BACKOFF_MULT = 1.05
- MAX_OPERATIONALERROR_TIME = 3600*24 # one day
- def __thd(self, with_engine, callable, args, kwargs):
- # try to call callable(arg, *args, **kwargs) repeatedly until no
- # OperationalErrors occur, where arg is either the engine (with_engine)
- # or a connection (not with_engine)
- backoff = self.BACKOFF_START
- start = time.time()
- while True:
- if with_engine:
- arg = self.engine
- else:
- arg = self.engine.contextual_connect()
-
- if self.__broken_sqlite: # see bug #1810
- arg.execute("select * from sqlite_master")
- try:
- try:
- rv = callable(arg, *args, **kwargs)
- assert not isinstance(rv, sa.engine.ResultProxy), \
- "do not return ResultProxy objects!"
- except sa.exc.OperationalError, e:
- text = e.orig.args[0]
- if not isinstance(text, basestring):
- raise
- if "Lost connection" in text \
- or "database is locked" in text:
-
- # see if we've retried too much
- elapsed = time.time() - start
- if elapsed > self.MAX_OPERATIONALERROR_TIME:
- raise
-
- metrics.MetricCountEvent.log(
- "DBThreadPool.retry-on-OperationalError")
- log.msg("automatically retrying query after "
- "OperationalError (%ss sleep)" % backoff)
-
- # sleep (remember, we're in a thread..)
- time.sleep(backoff)
- backoff *= self.BACKOFF_MULT
-
- # and re-try
- continue
- else:
- raise
- finally:
- if not with_engine:
- arg.close()
- break
- return rv
-
- def do(self, callable, *args, **kwargs):
- return threads.deferToThreadPool(reactor, self,
- self.__thd, False, callable, args, kwargs)
-
- def do_with_engine(self, callable, *args, **kwargs):
- return threads.deferToThreadPool(reactor, self,
- self.__thd, True, callable, args, kwargs)
-
- def detect_bug1810(self):
- # detect buggy SQLite implementations; call only for a known-sqlite
- # dialect
- try:
- import pysqlite2.dbapi2 as sqlite
- sqlite = sqlite
- except ImportError:
- import sqlite3 as sqlite
-
- tmpdir = tempfile.mkdtemp()
- dbfile = os.path.join(tmpdir, "detect_bug1810.db")
- def test(select_from_sqlite_master=False):
- conn1 = None
- conn2 = None
- try:
- conn1 = sqlite.connect(dbfile)
- curs1 = conn1.cursor()
- curs1.execute("PRAGMA table_info('foo')")
-
- conn2 = sqlite.connect(dbfile)
- curs2 = conn2.cursor()
- curs2.execute("CREATE TABLE foo ( a integer )")
-
- if select_from_sqlite_master:
- curs1.execute("SELECT * from sqlite_master")
- curs1.execute("SELECT * from foo")
- finally:
- if conn1:
- conn1.close()
- if conn2:
- conn2.close()
- os.unlink(dbfile)
-
- try:
- test()
- except sqlite.OperationalError:
- # this is the expected error indicating it's broken
- shutil.rmtree(tmpdir)
- return True
-
- # but this version should not fail..
- test(select_from_sqlite_master=True)
- shutil.rmtree(tmpdir)
- return False # not broken - no workaround required
-
- def get_sqlite_version(self):
- engine = sa.create_engine('sqlite://')
- conn = engine.contextual_connect()
-
- try:
- r = conn.execute("SELECT sqlite_version()")
- vers_row = r.fetchone()
- r.close()
- except:
- return (0,)
-
- if vers_row:
- try:
- return tuple(map(int, vers_row[0].split('.')))
- except (TypeError, ValueError):
- return (0,)
- else:
- return (0,)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py
deleted file mode 100644
index 0e845da3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-import sqlalchemy.exc
-from buildbot.db import base
-
-class SchedulersConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def classifyChanges(self, objectid, classifications):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.scheduler_changes
- ins_q = tbl.insert()
- upd_q = tbl.update(
- ((tbl.c.objectid == objectid)
- & (tbl.c.changeid == sa.bindparam('wc_changeid'))))
- for changeid, important in classifications.items():
- # convert the 'important' value into an integer, since that
- # is the column type
- imp_int = important and 1 or 0
- try:
- conn.execute(ins_q,
- objectid=objectid,
- changeid=changeid,
- important=imp_int)
- except (sqlalchemy.exc.ProgrammingError,
- sqlalchemy.exc.IntegrityError):
- # insert failed, so try an update
- conn.execute(upd_q,
- wc_changeid=changeid,
- important=imp_int)
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- def flushChangeClassifications(self, objectid, less_than=None):
- def thd(conn):
- sch_ch_tbl = self.db.model.scheduler_changes
- wc = (sch_ch_tbl.c.objectid == objectid)
- if less_than is not None:
- wc = wc & (sch_ch_tbl.c.changeid < less_than)
- q = sch_ch_tbl.delete(whereclause=wc)
- conn.execute(q)
- return self.db.pool.do(thd)
-
- class Thunk: pass
- def getChangeClassifications(self, objectid, branch=Thunk,
- repository=Thunk, project=Thunk,
- codebase=Thunk):
- def thd(conn):
- sch_ch_tbl = self.db.model.scheduler_changes
- ch_tbl = self.db.model.changes
-
- wc = (sch_ch_tbl.c.objectid == objectid)
-
- # may need to filter further based on branch, etc
- extra_wheres = []
- if branch is not self.Thunk:
- extra_wheres.append(ch_tbl.c.branch == branch)
- if repository is not self.Thunk:
- extra_wheres.append(ch_tbl.c.repository == repository)
- if project is not self.Thunk:
- extra_wheres.append(ch_tbl.c.project == project)
- if codebase is not self.Thunk:
- extra_wheres.append(ch_tbl.c.codebase == codebase)
-
- # if we need to filter further append those, as well as a join
- # on changeid (but just once for that one)
- if extra_wheres:
- wc &= (sch_ch_tbl.c.changeid == ch_tbl.c.changeid)
- for w in extra_wheres:
- wc &= w
-
- q = sa.select(
- [ sch_ch_tbl.c.changeid, sch_ch_tbl.c.important ],
- whereclause=wc)
- return dict([ (r.changeid, [False,True][r.important])
- for r in conn.execute(q) ])
- return self.db.pool.do(thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py
deleted file mode 100644
index 741fdee9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import base64
-import sqlalchemy as sa
-from twisted.internet import defer
-from twisted.python import log
-from buildbot.db import base
-
-class SsDict(dict):
- pass
-
-class SsList(list):
- pass
-
-class SourceStampsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addSourceStamp(self, branch, revision, repository,
- project, sourcestampsetid, codebase='',
- patch_body=None, patch_level=0, patch_author="",
- patch_comment="", patch_subdir=None, changeids=[]):
- def thd(conn):
- transaction = conn.begin()
-
- # handle inserting a patch
- patchid = None
- if patch_body is not None:
- ins = self.db.model.patches.insert()
- r = conn.execute(ins, dict(
- patchlevel=patch_level,
- patch_base64=base64.b64encode(patch_body),
- patch_author=patch_author,
- patch_comment=patch_comment,
- subdir=patch_subdir))
- patchid = r.inserted_primary_key[0]
-
- # insert the sourcestamp itself
- tbl = self.db.model.sourcestamps
- self.check_length(tbl.c.branch, branch)
- self.check_length(tbl.c.revision, revision)
- self.check_length(tbl.c.repository, repository)
- self.check_length(tbl.c.project, project)
-
- r = conn.execute(tbl.insert(), dict(
- branch=branch,
- revision=revision,
- patchid=patchid,
- repository=repository,
- codebase=codebase,
- project=project,
- sourcestampsetid=sourcestampsetid))
- ssid = r.inserted_primary_key[0]
-
- # handle inserting change ids
- if changeids:
- ins = self.db.model.sourcestamp_changes.insert()
- conn.execute(ins, [
- dict(sourcestampid=ssid, changeid=changeid)
- for changeid in changeids ])
-
- transaction.commit()
-
- # and return the new ssid
- return ssid
- return self.db.pool.do(thd)
-
- @base.cached("sssetdicts")
- @defer.inlineCallbacks
- def getSourceStamps(self,sourcestampsetid):
- def getSourceStampIds(sourcestampsetid):
- def thd(conn):
- tbl = self.db.model.sourcestamps
- q = sa.select([tbl.c.id],
- whereclause=(tbl.c.sourcestampsetid == sourcestampsetid))
- res = conn.execute(q)
- return [ row.id for row in res.fetchall() ]
- return self.db.pool.do(thd)
- ssids = yield getSourceStampIds(sourcestampsetid)
-
- sslist=SsList()
- for ssid in ssids:
- sourcestamp = yield self.getSourceStamp(ssid)
- sslist.append(sourcestamp)
- defer.returnValue(sslist)
-
- @base.cached("ssdicts")
- def getSourceStamp(self, ssid):
- def thd(conn):
- tbl = self.db.model.sourcestamps
- q = tbl.select(whereclause=(tbl.c.id == ssid))
- res = conn.execute(q)
- row = res.fetchone()
- if not row:
- return None
- ssdict = SsDict(ssid=ssid, branch=row.branch, sourcestampsetid=row.sourcestampsetid,
- revision=row.revision, patch_body=None, patch_level=None,
- patch_author=None, patch_comment=None, patch_subdir=None,
- repository=row.repository, codebase=row.codebase,
- project=row.project,
- changeids=set([]))
- patchid = row.patchid
- res.close()
-
- # fetch the patch, if necessary
- if patchid is not None:
- tbl = self.db.model.patches
- q = tbl.select(whereclause=(tbl.c.id == patchid))
- res = conn.execute(q)
- row = res.fetchone()
- if row:
- # note the subtle renaming here
- ssdict['patch_level'] = row.patchlevel
- ssdict['patch_subdir'] = row.subdir
- ssdict['patch_author'] = row.patch_author
- ssdict['patch_comment'] = row.patch_comment
- body = base64.b64decode(row.patch_base64)
- ssdict['patch_body'] = body
- else:
- log.msg('patchid %d, referenced from ssid %d, not found'
- % (patchid, ssid))
- res.close()
-
- # fetch change ids
- tbl = self.db.model.sourcestamp_changes
- q = tbl.select(whereclause=(tbl.c.sourcestampid == ssid))
- res = conn.execute(q)
- for row in res:
- ssdict['changeids'].add(row.changeid)
- res.close()
-
- return ssdict
- return self.db.pool.do(thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py
deleted file mode 100644
index 9210c69c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.db import base
-
-class SourceStampSetsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addSourceStampSet(self):
- def thd(conn):
- # insert the sourcestampset. sourcestampset has no attributes, but
- # inserting a new row results in a new setid
- r = conn.execute(self.db.model.sourcestampsets.insert(), dict())
- sourcestampsetid = r.inserted_primary_key[0]
-
- return sourcestampsetid
- return self.db.pool.do(thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py
deleted file mode 100644
index 52fdd68b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.util import json
-import sqlalchemy as sa
-import sqlalchemy.exc
-from buildbot.db import base
-
-class _IdNotFoundError(Exception):
- pass # used internally
-
-class ObjDict(dict):
- pass
-
-class StateConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def getObjectId(self, name, class_name):
- # defer to a cached method that only takes one parameter (a tuple)
- return self._getObjectId((name, class_name)
- ).addCallback(lambda objdict : objdict['id'])
-
- @base.cached('objectids')
- def _getObjectId(self, name_class_name_tuple):
- name, class_name = name_class_name_tuple
- def thd(conn):
- objects_tbl = self.db.model.objects
-
- self.check_length(objects_tbl.c.name, name)
- self.check_length(objects_tbl.c.class_name, class_name)
-
- def select():
- q = sa.select([ objects_tbl.c.id ],
- whereclause=((objects_tbl.c.name == name)
- & (objects_tbl.c.class_name == class_name)))
- res = conn.execute(q)
- row = res.fetchone()
- res.close()
- if not row:
- raise _IdNotFoundError
- return row.id
-
- def insert():
- res = conn.execute(objects_tbl.insert(),
- name=name,
- class_name=class_name)
- return res.inserted_primary_key[0]
-
- # we want to try selecting, then inserting, but if the insert fails
- # then try selecting again. We include an invocation of a hook
- # method to allow tests to exercise this particular behavior
- try:
- return ObjDict(id=select())
- except _IdNotFoundError:
- pass
-
- self._test_timing_hook(conn)
-
- try:
- return ObjDict(id=insert())
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
-
- return ObjDict(id=select())
-
- return self.db.pool.do(thd)
-
- class Thunk: pass
- def getState(self, objectid, name, default=Thunk):
- def thd(conn):
- object_state_tbl = self.db.model.object_state
-
- q = sa.select([ object_state_tbl.c.value_json ],
- whereclause=((object_state_tbl.c.objectid == objectid)
- & (object_state_tbl.c.name == name)))
- res = conn.execute(q)
- row = res.fetchone()
- res.close()
-
- if not row:
- if default is self.Thunk:
- raise KeyError("no such state value '%s' for object %d" %
- (name, objectid))
- return default
- try:
- return json.loads(row.value_json)
- except:
- raise TypeError("JSON error loading state value '%s' for %d" %
- (name, objectid))
- return self.db.pool.do(thd)
-
- def setState(self, objectid, name, value):
- def thd(conn):
- object_state_tbl = self.db.model.object_state
-
- try:
- value_json = json.dumps(value)
- except:
- raise TypeError("Error encoding JSON for %r" % (value,))
-
- self.check_length(object_state_tbl.c.name, name)
-
- def update():
- q = object_state_tbl.update(
- whereclause=((object_state_tbl.c.objectid == objectid)
- & (object_state_tbl.c.name == name)))
- res = conn.execute(q, value_json=value_json)
-
- # check whether that worked
- return res.rowcount > 0
-
- def insert():
- conn.execute(object_state_tbl.insert(),
- objectid=objectid,
- name=name,
- value_json=value_json)
-
- # try updating; if that fails, try inserting; if that fails, then
- # we raced with another instance to insert, so let that instance
- # win.
-
- if update():
- return
-
- self._test_timing_hook(conn)
-
- try:
- insert()
- except (sqlalchemy.exc.IntegrityError, sqlalchemy.exc.ProgrammingError):
- pass # someone beat us to it - oh well
-
- return self.db.pool.do(thd)
-
- def _test_timing_hook(self, conn):
- # called so tests can simulate another process inserting a database row
- # at an inopportune moment
- pass
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py
deleted file mode 100644
index 7e32902c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from sqlalchemy.sql.expression import and_
-
-from buildbot.db import base
-
-class UsDict(dict):
- pass
-
-class UsersConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def findUserByAttr(self, identifier, attr_type, attr_data, _race_hook=None):
- def thd(conn, no_recurse=False):
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
-
- self.check_length(tbl.c.identifier, identifier)
- self.check_length(tbl_info.c.attr_type, attr_type)
- self.check_length(tbl_info.c.attr_data, attr_data)
-
- # try to find the user
- q = sa.select([ tbl_info.c.uid ],
- whereclause=and_(tbl_info.c.attr_type == attr_type,
- tbl_info.c.attr_data == attr_data))
- rows = conn.execute(q).fetchall()
-
- if rows:
- return rows[0].uid
-
- _race_hook and _race_hook(conn)
-
- # try to do both of these inserts in a transaction, so that both
- # the new user and the corresponding attributes appear at the same
- # time from the perspective of other masters.
- transaction = conn.begin()
- try:
- r = conn.execute(tbl.insert(), dict(identifier=identifier))
- uid = r.inserted_primary_key[0]
-
- conn.execute(tbl_info.insert(),
- dict(uid=uid, attr_type=attr_type,
- attr_data=attr_data))
-
- transaction.commit()
- except (sa.exc.IntegrityError, sa.exc.ProgrammingError):
- transaction.rollback()
-
- # try it all over again, in case there was an overlapping,
- # identical call to findUserByAttr, but only retry once.
- if no_recurse:
- raise
- return thd(conn, no_recurse=True)
-
- return uid
- d = self.db.pool.do(thd)
- return d
-
- @base.cached("usdicts")
- def getUser(self, uid):
- def thd(conn):
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
-
- q = tbl.select(whereclause=(tbl.c.uid == uid))
- users_row = conn.execute(q).fetchone()
-
- if not users_row:
- return None
-
- # make UsDict to return
- usdict = UsDict()
-
- # gather all attr_type and attr_data entries from users_info table
- q = tbl_info.select(whereclause=(tbl_info.c.uid == uid))
- rows = conn.execute(q).fetchall()
- for row in rows:
- usdict[row.attr_type] = row.attr_data
-
- # add the users_row data *after* the attributes in case attr_type
- # matches one of these keys.
- usdict['uid'] = users_row.uid
- usdict['identifier'] = users_row.identifier
- usdict['bb_username'] = users_row.bb_username
- usdict['bb_password'] = users_row.bb_password
-
- return usdict
- d = self.db.pool.do(thd)
- return d
-
- def getUserByUsername(self, username):
- def thd(conn):
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
-
- q = tbl.select(whereclause=(tbl.c.bb_username == username))
- users_row = conn.execute(q).fetchone()
-
- if not users_row:
- return None
-
- # make UsDict to return
- usdict = UsDict()
-
- # gather all attr_type and attr_data entries from users_info table
- q = tbl_info.select(whereclause=(tbl_info.c.uid == users_row.uid))
- rows = conn.execute(q).fetchall()
- for row in rows:
- usdict[row.attr_type] = row.attr_data
-
- # add the users_row data *after* the attributes in case attr_type
- # matches one of these keys.
- usdict['uid'] = users_row.uid
- usdict['identifier'] = users_row.identifier
- usdict['bb_username'] = users_row.bb_username
- usdict['bb_password'] = users_row.bb_password
-
- return usdict
- d = self.db.pool.do(thd)
- return d
-
- def getUsers(self):
- def thd(conn):
- tbl = self.db.model.users
- rows = conn.execute(tbl.select()).fetchall()
-
- dicts = []
- if rows:
- for row in rows:
- ud = dict(uid=row.uid, identifier=row.identifier)
- dicts.append(ud)
- return dicts
- d = self.db.pool.do(thd)
- return d
-
- def updateUser(self, uid=None, identifier=None, bb_username=None,
- bb_password=None, attr_type=None, attr_data=None,
- _race_hook=None):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
- update_dict = {}
-
- # first, add the identifier is it exists
- if identifier is not None:
- self.check_length(tbl.c.identifier, identifier)
- update_dict['identifier'] = identifier
-
- # then, add the creds if they exist
- if bb_username is not None:
- assert bb_password is not None
- self.check_length(tbl.c.bb_username, bb_username)
- self.check_length(tbl.c.bb_password, bb_password)
- update_dict['bb_username'] = bb_username
- update_dict['bb_password'] = bb_password
-
- # update the users table if it needs to be updated
- if update_dict:
- q = tbl.update(whereclause=(tbl.c.uid == uid))
- res = conn.execute(q, update_dict)
-
- # then, update the attributes, carefully handling the potential
- # update-or-insert race condition.
- if attr_type is not None:
- assert attr_data is not None
-
- self.check_length(tbl_info.c.attr_type, attr_type)
- self.check_length(tbl_info.c.attr_data, attr_data)
-
- # first update, then insert
- q = tbl_info.update(
- whereclause=(tbl_info.c.uid == uid)
- & (tbl_info.c.attr_type == attr_type))
- res = conn.execute(q, attr_data=attr_data)
- if res.rowcount == 0:
- _race_hook and _race_hook(conn)
-
- # the update hit 0 rows, so try inserting a new one
- try:
- q = tbl_info.insert()
- res = conn.execute(q,
- uid=uid,
- attr_type=attr_type,
- attr_data=attr_data)
- except (sa.exc.IntegrityError, sa.exc.ProgrammingError):
- # someone else beat us to the punch inserting this row;
- # let them win.
- transaction.rollback()
- return
-
- transaction.commit()
- d = self.db.pool.do(thd)
- return d
-
- def removeUser(self, uid):
- def thd(conn):
- # delete from dependent tables first, followed by 'users'
- for tbl in [
- self.db.model.change_users,
- self.db.model.users_info,
- self.db.model.users,
- ]:
- conn.execute(tbl.delete(whereclause=(tbl.c.uid==uid)))
- d = self.db.pool.do(thd)
- return d
-
- def identifierToUid(self, identifier):
- def thd(conn):
- tbl = self.db.model.users
-
- q = tbl.select(whereclause=(tbl.c.identifier == identifier))
- row = conn.execute(q).fetchone()
- if not row:
- return None
-
- return row.uid
- d = self.db.pool.do(thd)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py
deleted file mode 100644
index 085cb3dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-from buildbot.buildslave.libvirt import (
- EC2LatentBuildSlave)
-
-deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
- "It has been moved to buildbot.buildslave.ec2",
- "buildbot.libvirtbuildslave", "EC2LatentBuildSlave")
-
-_hush_pyflakes = [
- EC2LatentBuildSlave]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py
deleted file mode 100644
index ecbf6a4a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py
+++ /dev/null
@@ -1,1216 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""Interface documentation.
-
-Define the interfaces that are implemented by various buildbot classes.
-"""
-# E0211: Method has no argument
-# E0213: Method should have "self" as first argument
-# pylint: disable-msg=E0211,E0213
-
-from zope.interface import Interface, Attribute
-
-# exceptions that can be raised while trying to start a build
-class NoSlaveError(Exception):
- pass
-class BuilderInUseError(Exception):
- pass
-class BuildSlaveTooOldError(Exception):
- pass
-class LatentBuildSlaveFailedToSubstantiate(Exception):
- pass
-
-class IChangeSource(Interface):
- """
- Service which feeds Change objects to the changemaster. When files or
- directories are changed in version control, this object should represent
- the changes as a change dictionary and call::
-
- self.master.addChange(who=.., rev=.., ..)
-
- See 'Writing Change Sources' in the manual for more information.
- """
- master = Attribute('master',
- 'Pointer to BuildMaster, automatically set when started.')
-
- def describe():
- """Return a string which briefly describes this source."""
-
-class ISourceStamp(Interface):
- """
- @cvar branch: branch from which source was drawn
- @type branch: string or None
-
- @cvar revision: revision of the source, or None to use CHANGES
- @type revision: varies depending on VC
-
- @cvar patch: patch applied to the source, or None if no patch
- @type patch: None or tuple (level diff)
-
- @cvar changes: the source step should check out the latest revision
- in the given changes
- @type changes: tuple of L{buildbot.changes.changes.Change} instances,
- all of which are on the same branch
-
- @cvar project: project this source code represents
- @type project: string
-
- @cvar repository: repository from which source was drawn
- @type repository: string
- """
-
- def canBeMergedWith(self, other):
- """
- Can this SourceStamp be merged with OTHER?
- """
-
- def mergeWith(self, others):
- """Generate a SourceStamp for the merger of me and all the other
- SourceStamps. This is called by a Build when it starts, to figure
- out what its sourceStamp should be."""
-
- def getAbsoluteSourceStamp(self, got_revision):
- """Get a new SourceStamp object reflecting the actual revision found
- by a Source step."""
-
- def getText(self):
- """Returns a list of strings to describe the stamp. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
-class IEmailSender(Interface):
- """I know how to send email, and can be used by other parts of the
- Buildbot to contact developers."""
- pass
-
-class IEmailLookup(Interface):
- def getAddress(user):
- """Turn a User-name string into a valid email address. Either return
- a string (with an @ in it), None (to indicate that the user cannot
- be reached by email), or a Deferred which will fire with the same."""
-
-class IStatus(Interface):
- """I am an object, obtainable from the buildmaster, which can provide
- status information."""
-
- def getTitle():
- """Return the name of the project that this Buildbot is working
- for."""
- def getTitleURL():
- """Return the URL of this Buildbot's project."""
- def getBuildbotURL():
- """Return the URL of the top-most Buildbot status page, or None if
- this Buildbot does not provide a web status page."""
- def getURLForThing(thing):
- """Return the URL of a page which provides information on 'thing',
- which should be an object that implements one of the status
- interfaces defined in L{buildbot.interfaces}. Returns None if no
- suitable page is available (or if no Waterfall is running)."""
-
- def getChangeSources():
- """Return a list of IChangeSource objects."""
-
- def getChange(number):
- """Return an IChange object."""
-
- def getSchedulers():
- """Return a list of ISchedulerStatus objects for all
- currently-registered Schedulers."""
-
- def getBuilderNames(categories=None):
- """Return a list of the names of all current Builders."""
- def getBuilder(name):
- """Return the IBuilderStatus object for a given named Builder. Raises
- KeyError if there is no Builder by that name."""
-
- def getSlaveNames():
- """Return a list of buildslave names, suitable for passing to
- getSlave()."""
- def getSlave(name):
- """Return the ISlaveStatus object for a given named buildslave."""
-
- def getBuildSets():
- """
- Return a list of un-completed build sets.
-
- @returns: list of L{IBuildSetStatus} implementations, via Deferred.
- """
-
- def generateFinishedBuilds(builders=[], branches=[],
- num_builds=None, finished_before=None,
- max_search=200):
- """Return a generator that will produce IBuildStatus objects each
- time you invoke its .next() method, starting with the most recent
- finished build and working backwards.
-
- @param builders: this is a list of Builder names, and the generator
- will only produce builds that ran on the given
- Builders. If the list is empty, produce builds from
- all Builders.
-
- @param branches: this is a list of branch names, and the generator
- will only produce builds that used the given
- branches. If the list is empty, produce builds from
- all branches.
-
- @param num_builds: the generator will stop after providing this many
- builds. The default of None means to produce as
- many builds as possible.
-
- @type finished_before: int: a timestamp, seconds since the epoch
- @param finished_before: if provided, do not produce any builds that
- finished after the given timestamp.
-
- @type max_search: int
- @param max_search: this method may have to examine a lot of builds
- to find some that match the search parameters,
- especially if there aren't any matching builds.
- This argument imposes a hard limit on the number
- of builds that will be examined within any given
- Builder.
- """
-
- def subscribe(receiver):
- """Register an IStatusReceiver to receive new status events. The
- receiver will immediately be sent a set of 'builderAdded' messages
- for all current builders. It will receive further 'builderAdded' and
- 'builderRemoved' messages as the config file is reloaded and builders
- come and go. It will also receive 'buildsetSubmitted' messages for
- all outstanding BuildSets (and each new BuildSet that gets
- submitted). No additional messages will be sent unless the receiver
- asks for them by calling .subscribe on the IBuilderStatus objects
- which accompany the addedBuilder message."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class IBuildSetStatus(Interface):
- """I represent a set of Builds, each run on a separate Builder but all
- using the same source tree."""
-
- def getReason():
- pass
- def getID():
- """Return the BuildSet's ID string, if any. The 'try' feature uses a
- random string as a BuildSetID to relate submitted jobs with the
- resulting BuildSet."""
- def getResponsibleUsers():
- pass # not implemented
- def getInterestedUsers():
- pass # not implemented
- def getBuilderNames():
- """Return a list of the names of all Builders on which this set will
- do builds.
-
- @returns: list of names via Deferred"""
- def isFinished():
- pass
- def waitUntilFinished():
- """Return a Deferred that fires (with this IBuildSetStatus object)
- when all builds have finished."""
- def getResults():
- """Return SUCCESS/FAILURE, or None if the buildset is not finished
- yet"""
-
-
-class IBuildRequestStatus(Interface):
- """I represent a request to build a particular set of source code on a
- particular Builder. These requests may be merged by the time they are
- finally turned into a Build."""
-
- def getSourceStamp():
- """
- Get a SourceStamp object which can be used to re-create the source tree
- that this build used. This method will return an absolute SourceStamp
- if possible, and its results may change as the build progresses.
- Specifically, a "HEAD" build may later be more accurately specified by
- an absolute SourceStamp with the specific revision information.
-
- This method will return None if the source information is no longer
- available.
-
- @returns: SourceStamp via Deferred
- """
-
- def getBuilds():
- """Return a list of IBuildStatus objects for each Build that has been
- started in an attempt to satify this BuildRequest."""
-
- def subscribe(observer):
- """Register a callable that will be invoked (with a single
- IBuildStatus object) for each Build that is created to satisfy this
- request. There may be multiple Builds created in an attempt to handle
- the request: they may be interrupted by the user or abandoned due to
- a lost slave. The last Build (the one which actually gets to run to
- completion) is said to 'satisfy' the BuildRequest. The observer will
- be called once for each of these Builds, both old and new."""
- def unsubscribe(observer):
- """Unregister the callable that was registered with subscribe()."""
- def getSubmitTime():
- """Return the time when this request was submitted. Returns a
- Deferred."""
-
-
-class ISlaveStatus(Interface):
- def getName():
- """Return the name of the build slave."""
-
- def getAdmin():
- """Return a string with the slave admin's contact data."""
-
- def getHost():
- """Return a string with the slave host info."""
-
- def isConnected():
- """Return True if the slave is currently online, False if not."""
-
- def lastMessageReceived():
- """Return a timestamp (seconds since epoch) indicating when the most
- recent message was received from the buildslave."""
-
-class ISchedulerStatus(Interface):
- def getName():
- """Return the name of this Scheduler (a string)."""
-
- def getPendingBuildsets():
- """Return an IBuildSet for all BuildSets that are pending. These
- BuildSets are waiting for their tree-stable-timers to expire."""
- # TODO: this is not implemented anywhere
-
-
-class IBuilderStatus(Interface):
- def getName():
- """Return the name of this Builder (a string)."""
-
- def getCategory():
- """Return the category of this builder (a string)."""
-
- def getDescription():
- """Return the description of this builder (a string)."""
-
- def getState():
- # TODO: this isn't nearly as meaningful as it used to be
- """Return a tuple (state, builds) for this Builder. 'state' is the
- so-called 'big-status', indicating overall status (as opposed to
- which step is currently running). It is a string, one of 'offline',
- 'idle', or 'building'. 'builds' is a list of IBuildStatus objects
- (possibly empty) representing the currently active builds."""
-
- def getSlaves():
- """Return a list of ISlaveStatus objects for the buildslaves that are
- used by this builder."""
-
- def getPendingBuildRequestStatuses():
- """
- Get a L{IBuildRequestStatus} implementations for all unclaimed build
- requests.
-
- @returns: list of objects via Deferred
- """
-
- def getCurrentBuilds():
- """Return a list containing an IBuildStatus object for each build
- currently in progress."""
- # again, we could probably provide an object for 'waiting' and
- # 'interlocked' too, but things like the Change list might still be
- # subject to change
-
- def getLastFinishedBuild():
- """Return the IBuildStatus object representing the last finished
- build, which may be None if the builder has not yet finished any
- builds."""
-
- def getBuild(number):
- """Return an IBuildStatus object for a historical build. Each build
- is numbered (starting at 0 when the Builder is first added),
- getBuild(n) will retrieve the Nth such build. getBuild(-n) will
- retrieve a recent build, with -1 being the most recent build
- started. If the Builder is idle, this will be the same as
- getLastFinishedBuild(). If the Builder is active, it will be an
- unfinished build. This method will return None if the build is no
- longer available. Older builds are likely to have less information
- stored: Logs are the first to go, then Steps."""
-
- def getEvent(number):
- """Return an IStatusEvent object for a recent Event. Builders
- connecting and disconnecting are events, as are ping attempts.
- getEvent(-1) will return the most recent event. Events are numbered,
- but it probably doesn't make sense to ever do getEvent(+n)."""
-
- def generateFinishedBuilds(branches=[],
- num_builds=None,
- max_buildnum=None, finished_before=None,
- max_search=200,
- ):
- """Return a generator that will produce IBuildStatus objects each
- time you invoke its .next() method, starting with the most recent
- finished build, then the previous build, and so on back to the oldest
- build available.
-
- @param branches: this is a list of branch names, and the generator
- will only produce builds that involve the given
- branches. If the list is empty, the generator will
- produce all builds regardless of what branch they
- used.
-
- @param num_builds: if provided, the generator will stop after
- providing this many builds. The default of None
- means to produce as many builds as possible.
-
- @param max_buildnum: if provided, the generator will start by
- providing the build with this number, or the
- highest-numbered preceding build (i.e. the
- generator will not produce any build numbered
- *higher* than max_buildnum). The default of None
- means to start with the most recent finished
- build. -1 means the same as None. -2 means to
- start with the next-most-recent completed build,
- etc.
-
- @type finished_before: int: a timestamp, seconds since the epoch
- @param finished_before: if provided, do not produce any builds that
- finished after the given timestamp.
-
- @type max_search: int
- @param max_search: this method may have to examine a lot of builds
- to find some that match the search parameters,
- especially if there aren't any matching builds.
- This argument imposes a hard limit on the number
- of builds that will be examined.
- """
-
- def subscribe(receiver):
- """Register an IStatusReceiver to receive new status events. The
- receiver will be given builderChangedState, buildStarted, and
- buildFinished messages."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class IEventSource(Interface):
- def eventGenerator(branches=[], categories=[], committers=[], minTime=0):
- """This function creates a generator which will yield all of this
- object's status events, starting with the most recent and progressing
- backwards in time. These events provide the IStatusEvent interface.
- At the moment they are all instances of buildbot.status.builder.Event
- or buildbot.status.builder.BuildStepStatus .
-
- @param branches: a list of branch names. The generator should only
- return events that are associated with these branches. If the list is
- empty, events for all branches should be returned (i.e. an empty list
- means 'accept all' rather than 'accept none').
-
- @param categories: a list of category names. The generator
- should only return events that are categorized within the
- given category. If the list is empty, events for all
- categories should be returned.
-
- @param comitters: a list of committers. The generator should only
- return events caused by one of the listed committers. If the list is
- empty or None, events from every committers should be returned.
-
- @param minTime: a timestamp. Do not generate events occuring prior to
- this timestamp.
- """
-
-class IBuildStatus(Interface):
- """I represent the status of a single Build/BuildRequest. It could be
- in-progress or finished."""
-
- def getBuilder():
- """
- Return the BuilderStatus that owns this build.
-
- @rtype: implementor of L{IBuilderStatus}
- """
-
- def isFinished():
- """Return a boolean. True means the build has finished, False means
- it is still running."""
-
- def waitUntilFinished():
- """Return a Deferred that will fire when the build finishes. If the
- build has already finished, this deferred will fire right away. The
- callback is given this IBuildStatus instance as an argument."""
-
- def getReason():
- """Return a string that indicates why the build was run. 'changes',
- 'forced', and 'periodic' are the most likely values. 'try' will be
- added in the future."""
-
- def getSourceStamps():
- """Return a list of SourceStamp objects which can be used to re-create
- the source tree that this build used.
-
- This method will return None if the source information is no longer
- available."""
- # TODO: it should be possible to expire the patch but still remember
- # that the build was r123+something.
-
- def getChanges():
- """Return a list of Change objects which represent which source
- changes went into the build."""
-
- def getRevisions():
- """Returns a string representing the list of revisions that led to
- the build, rendered from each Change.revision"""
-
- def getResponsibleUsers():
- """Return a list of Users who are to blame for the changes that went
- into this build. If anything breaks (at least anything that wasn't
- already broken), blame them. Specifically, this is the set of users
- who were responsible for the Changes that went into this build. Each
- User is a string, corresponding to their name as known by the VC
- repository."""
-
- def getInterestedUsers():
- """Return a list of Users who will want to know about the results of
- this build but who did not actually make the Changes that went into it
- (build sheriffs, code-domain owners)."""
-
- def getNumber():
- """Within each builder, each Build has a number. Return it."""
-
- def getPreviousBuild():
- """Convenience method. Returns None if the previous build is
- unavailable."""
-
- def getSteps():
- """Return a list of IBuildStepStatus objects. For invariant builds
- (those which always use the same set of Steps), this should always
- return the complete list, however some of the steps may not have
- started yet (step.getTimes()[0] will be None). For variant builds,
- this may not be complete (asking again later may give you more of
- them)."""
-
- def getTimes():
- """Returns a tuple of (start, end). 'start' and 'end' are the times
- (seconds since the epoch) when the Build started and finished. If
- the build is still running, 'end' will be None."""
-
- # while the build is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA():
- """Returns the number of seconds from now in which the build is
- expected to finish, or None if we can't make a guess. This guess will
- be refined over time."""
-
- def getCurrentStep():
- """Return an IBuildStepStatus object representing the currently
- active step."""
-
- # Once you know the build has finished, the following methods are legal.
- # Before ths build has finished, they all return None.
-
- def getSlavename():
- """Return the name of the buildslave which handled this build."""
-
- def getText():
- """Returns a list of strings to describe the build. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
- def getResults():
- """Return a constant describing the results of the build: one of the
- constants in buildbot.status.builder: SUCCESS, WARNINGS,
- FAILURE, SKIPPED or EXCEPTION."""
-
- def getLogs():
- """Return a list of logs that describe the build as a whole. Some
- steps will contribute their logs, while others are are less important
- and will only be accessible through the IBuildStepStatus objects.
- Each log is an object which implements the IStatusLog interface."""
-
- def getTestResults():
- """Return a dictionary that maps test-name tuples to ITestResult
- objects. This may return an empty or partially-filled dictionary
- until the build has completed."""
-
- # subscription interface
-
- def subscribe(receiver, updateInterval=None):
- """Register an IStatusReceiver to receive new status events. The
- receiver will be given stepStarted and stepFinished messages. If
- 'updateInterval' is non-None, buildETAUpdate messages will be sent
- every 'updateInterval' seconds."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class ITestResult(Interface):
- """I describe the results of a single unit test."""
-
- def getName():
- """Returns a tuple of strings which make up the test name. Tests may
- be arranged in a hierarchy, so looking for common prefixes may be
- useful."""
-
- def getResults():
- """Returns a constant describing the results of the test: SUCCESS,
- WARNINGS, FAILURE."""
-
- def getText():
- """Returns a list of short strings which describe the results of the
- test in slightly more detail. Suggested components include
- 'failure', 'error', 'passed', 'timeout'."""
-
- def getLogs():
- # in flux, it may be possible to provide more structured information
- # like python Failure instances
- """Returns a dictionary of test logs. The keys are strings like
- 'stdout', 'log', 'exceptions'. The values are strings."""
-
-
-class IBuildStepStatus(Interface):
- """I hold status for a single BuildStep."""
-
- def getName():
- """Returns a short string with the name of this step. This string
- may have spaces in it."""
-
- def getBuild():
- """Returns the IBuildStatus object which contains this step."""
-
- def getTimes():
- """Returns a tuple of (start, end). 'start' and 'end' are the times
- (seconds since the epoch) when the Step started and finished. If the
- step has not yet started, 'start' will be None. If the step is still
- running, 'end' will be None."""
-
- def getExpectations():
- """Returns a list of tuples (name, current, target). Each tuple
- describes a single axis along which the step's progress can be
- measured. 'name' is a string which describes the axis itself, like
- 'filesCompiled' or 'tests run' or 'bytes of output'. 'current' is a
- number with the progress made so far, while 'target' is the value
- that we expect (based upon past experience) to get to when the build
- is finished.
-
- 'current' will change over time until the step is finished. It is
- 'None' until the step starts. When the build is finished, 'current'
- may or may not equal 'target' (which is merely the expectation based
- upon previous builds)."""
-
- def getURLs():
- """Returns a dictionary of URLs. Each key is a link name (a short
- string, like 'results' or 'coverage'), and each value is a URL. These
- links will be displayed along with the LogFiles.
- """
-
- def getLogs():
- """Returns a list of IStatusLog objects. If the step has not yet
- finished, this list may be incomplete (asking again later may give
- you more of them)."""
-
-
- def isFinished():
- """Return a boolean. True means the step has finished, False means it
- is still running."""
-
- def waitUntilFinished():
- """Return a Deferred that will fire when the step finishes. If the
- step has already finished, this deferred will fire right away. The
- callback is given this IBuildStepStatus instance as an argument."""
-
- # while the step is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA():
- """Returns the number of seconds from now in which the step is
- expected to finish, or None if we can't make a guess. This guess will
- be refined over time."""
-
- # Once you know the step has finished, the following methods are legal.
- # Before ths step has finished, they all return None.
-
- def getText():
- """Returns a list of strings which describe the step. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
- def getResults():
- """Return a tuple describing the results of the step: (result,
- strings). 'result' is one of the constants in
- buildbot.status.builder: SUCCESS, WARNINGS, FAILURE, or SKIPPED.
- 'strings' is an optional list of strings that the step wants to
- append to the overall build's results. These strings are usually
- more terse than the ones returned by getText(): in particular,
- successful Steps do not usually contribute any text to the overall
- build."""
-
- # subscription interface
-
- def subscribe(receiver, updateInterval=10):
- """Register an IStatusReceiver to receive new status events. The
- receiver will be given logStarted and logFinished messages. It will
- also be given a ETAUpdate message every 'updateInterval' seconds."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class IStatusEvent(Interface):
- """I represent a Builder Event, something non-Build related that can
- happen to a Builder."""
-
- def getTimes():
- """Returns a tuple of (start, end) like IBuildStepStatus, but end==0
- indicates that this is a 'point event', which has no duration.
- SlaveConnect/Disconnect are point events. Ping is not: it starts
- when requested and ends when the response (positive or negative) is
- returned"""
-
- def getText():
- """Returns a list of strings which describe the event. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
-
-LOG_CHANNEL_STDOUT = 0
-LOG_CHANNEL_STDERR = 1
-LOG_CHANNEL_HEADER = 2
-
-class IStatusLog(Interface):
- """I represent a single Log, which is a growing list of text items that
- contains some kind of output for a single BuildStep. I might be finished,
- in which case this list has stopped growing.
-
- Each Log has a name, usually something boring like 'log' or 'output'.
- These names are not guaranteed to be unique, however they are usually
- chosen to be useful within the scope of a single step (i.e. the Compile
- step might produce both 'log' and 'warnings'). The name may also have
- spaces. If you want something more globally meaningful, at least within a
- given Build, try::
-
- '%s.%s' % (log.getStep.getName(), log.getName())
-
- The Log can be presented as plain text, or it can be accessed as a list
- of items, each of which has a channel indicator (header, stdout, stderr)
- and a text chunk. An HTML display might represent the interleaved
- channels with different styles, while a straight download-the-text
- interface would just want to retrieve a big string.
-
- The 'header' channel is used by ShellCommands to prepend a note about
- which command is about to be run ('running command FOO in directory
- DIR'), and append another note giving the exit code of the process.
-
- Logs can be streaming: if the Log has not yet finished, you can
- subscribe to receive new chunks as they are added.
-
- A ShellCommand will have a Log associated with it that gathers stdout
- and stderr. Logs may also be created by parsing command output or
- through other synthetic means (grepping for all the warnings in a
- compile log, or listing all the test cases that are going to be run).
- Such synthetic Logs are usually finished as soon as they are created."""
-
-
- def getName():
- """Returns a short string with the name of this log, probably 'log'.
- """
-
- def getStep():
- """Returns the IBuildStepStatus which owns this log."""
- # TODO: can there be non-Step logs?
-
- def isFinished():
- """Return a boolean. True means the log has finished and is closed,
- False means it is still open and new chunks may be added to it."""
-
- def waitUntilFinished():
- """Return a Deferred that will fire when the log is closed. If the
- log has already finished, this deferred will fire right away. The
- callback is given this IStatusLog instance as an argument."""
-
- def subscribe(receiver, catchup):
- """Register an IStatusReceiver to receive chunks (with logChunk) as
- data is added to the Log. If you use this, you will also want to use
- waitUntilFinished to find out when the listener can be retired.
- Subscribing to a closed Log is a no-op.
-
- If 'catchup' is True, the receiver will immediately be sent a series
- of logChunk messages to bring it up to date with the partially-filled
- log. This allows a status client to join a Log already in progress
- without missing any data. If the Log has already finished, it is too
- late to catch up: just do getText() instead.
-
- If the Log is very large, the receiver will be called many times with
- a lot of data. There is no way to throttle this data. If the receiver
- is planning on sending the data on to somewhere else, over a narrow
- connection, you can get a throttleable subscription by using
- C{subscribeConsumer} instead."""
-
- def unsubscribe(receiver):
- """Remove a receiver previously registered with subscribe(). Attempts
- to remove a receiver which was not previously registered is a no-op.
- """
-
- def subscribeConsumer(consumer):
- """Register an L{IStatusLogConsumer} to receive all chunks of the
- logfile, including all the old entries and any that will arrive in
- the future. The consumer will first have their C{registerProducer}
- method invoked with a reference to an object that can be told
- C{pauseProducing}, C{resumeProducing}, and C{stopProducing}. Then the
- consumer's C{writeChunk} method will be called repeatedly with each
- (channel, text) tuple in the log, starting with the very first. The
- consumer will be notified with C{finish} when the log has been
- exhausted (which can only happen when the log is finished). Note that
- a small amount of data could be written via C{writeChunk} even after
- C{pauseProducing} has been called.
-
- To unsubscribe the consumer, use C{producer.stopProducing}."""
-
- # once the log has finished, the following methods make sense. They can
- # be called earlier, but they will only return the contents of the log up
- # to the point at which they were called. You will lose items that are
- # added later. Use C{subscribe} or C{subscribeConsumer} to avoid missing
- # anything.
-
- def hasContents():
- """Returns True if the LogFile still has contents available. Returns
- False for logs that have been pruned. Clients should test this before
- offering to show the contents of any log."""
-
- def getText():
- """Return one big string with the contents of the Log. This merges
- all non-header chunks together."""
-
- def readlines(channel=LOG_CHANNEL_STDOUT):
- """Read lines from one channel of the logfile. This returns an
- iterator that will provide single lines of text (including the
- trailing newline).
- """
-
- def getTextWithHeaders():
- """Return one big string with the contents of the Log. This merges
- all chunks (including headers) together."""
-
- def getChunks():
- """Generate a list of (channel, text) tuples. 'channel' is a number,
- 0 for stdout, 1 for stderr, 2 for header. (note that stderr is merged
- into stdout if PTYs are in use)."""
-
-class IStatusLogConsumer(Interface):
- """I am an object which can be passed to IStatusLog.subscribeConsumer().
- I represent a target for writing the contents of an IStatusLog. This
- differs from a regular IStatusReceiver in that it can pause the producer.
- This makes it more suitable for use in streaming data over network
- sockets, such as an HTTP request. Note that the consumer can only pause
- the producer until it has caught up with all the old data. After that
- point, C{pauseProducing} is ignored and all new output from the log is
- sent directoy to the consumer."""
-
- def registerProducer(producer, streaming):
- """A producer is being hooked up to this consumer. The consumer only
- has to handle a single producer. It should send .pauseProducing and
- .resumeProducing messages to the producer when it wants to stop or
- resume the flow of data. 'streaming' will be set to True because the
- producer is always a PushProducer.
- """
-
- def unregisterProducer():
- """The previously-registered producer has been removed. No further
- pauseProducing or resumeProducing calls should be made. The consumer
- should delete its reference to the Producer so it can be released."""
-
- def writeChunk(chunk):
- """A chunk (i.e. a tuple of (channel, text)) is being written to the
- consumer."""
-
- def finish():
- """The log has finished sending chunks to the consumer."""
-
-class IStatusReceiver(Interface):
- """I am an object which can receive build status updates. I may be
- subscribed to an IStatus, an IBuilderStatus, or an IBuildStatus."""
-
- def buildsetSubmitted(buildset):
- """A new BuildSet has been submitted to the buildmaster.
-
- @type buildset: implementor of L{IBuildSetStatus}
- """
-
- def requestSubmitted(request):
- """A new BuildRequest has been submitted to the buildmaster.
-
- @type request: implementor of L{IBuildRequestStatus}
- """
-
- def requestCancelled(builder, request):
- """A BuildRequest has been cancelled on the given Builder.
-
- @type builder: L{buildbot.status.builder.BuilderStatus}
- @type request: implementor of L{IBuildRequestStatus}
- """
-
- def builderAdded(builderName, builder):
- """
- A new Builder has just been added. This method may return an
- IStatusReceiver (probably 'self') which will be subscribed to receive
- builderChangedState and buildStarted/Finished events.
-
- @type builderName: string
- @type builder: L{buildbot.status.builder.BuilderStatus}
- @rtype: implementor of L{IStatusReceiver}
- """
-
- def builderChangedState(builderName, state):
- """Builder 'builderName' has changed state. The possible values for
- 'state' are 'offline', 'idle', and 'building'."""
-
- def buildStarted(builderName, build):
- """Builder 'builderName' has just started a build. The build is an
- object which implements IBuildStatus, and can be queried for more
- information.
-
- This method may return an IStatusReceiver (it could even return
- 'self'). If it does so, stepStarted and stepFinished methods will be
- invoked on the object for the steps of this one build. This is a
- convenient way to subscribe to all build steps without missing any.
- This receiver will automatically be unsubscribed when the build
- finishes.
-
- It can also return a tuple of (IStatusReceiver, interval), in which
- case buildETAUpdate messages are sent ever 'interval' seconds, in
- addition to the stepStarted and stepFinished messages."""
-
- def buildETAUpdate(build, ETA):
- """This is a periodic update on the progress this Build has made
- towards completion."""
-
- def changeAdded(change):
- """A new Change was added to the ChangeMaster. By the time this event
- is received, all schedulers have already received the change."""
-
- def stepStarted(build, step):
- """A step has just started. 'step' is the IBuildStepStatus which
- represents the step: it can be queried for more information.
-
- This method may return an IStatusReceiver (it could even return
- 'self'). If it does so, logStarted and logFinished methods will be
- invoked on the object for logs created by this one step. This
- receiver will be automatically unsubscribed when the step finishes.
-
- Alternatively, the method may return a tuple of an IStatusReceiver
- and an integer named 'updateInterval'. In addition to
- logStarted/logFinished messages, it will also receive stepETAUpdate
- messages about every updateInterval seconds."""
-
- def stepTextChanged(build, step, text):
- """The text for a step has been updated.
-
- This is called when calling setText() on the step status, and
- hands in the text list."""
-
- def stepText2Changed(build, step, text2):
- """The text2 for a step has been updated.
-
- This is called when calling setText2() on the step status, and
- hands in text2 list."""
-
- def stepETAUpdate(build, step, ETA, expectations):
- """This is a periodic update on the progress this Step has made
- towards completion. It gets an ETA (in seconds from the present) of
- when the step ought to be complete, and a list of expectation tuples
- (as returned by IBuildStepStatus.getExpectations) with more detailed
- information."""
-
- def logStarted(build, step, log):
- """A new Log has been started, probably because a step has just
- started running a shell command. 'log' is the IStatusLog object
- which can be queried for more information.
-
- This method may return an IStatusReceiver (such as 'self'), in which
- case the target's logChunk method will be invoked as text is added to
- the logfile. This receiver will automatically be unsubsribed when the
- log finishes."""
-
- def logChunk(build, step, log, channel, text):
- """Some text has been added to this log. 'channel' is one of
- LOG_CHANNEL_STDOUT, LOG_CHANNEL_STDERR, or LOG_CHANNEL_HEADER, as
- defined in IStatusLog.getChunks."""
-
- def logFinished(build, step, log):
- """A Log has been closed."""
-
- def stepFinished(build, step, results):
- """A step has just finished. 'results' is the result tuple described
- in IBuildStepStatus.getResults."""
-
- def buildFinished(builderName, build, results):
- """
- A build has just finished. 'results' is the result tuple described
- in L{IBuildStatus.getResults}.
-
- @type builderName: string
- @type build: L{buildbot.status.build.BuildStatus}
- @type results: tuple
- """
-
- def builderRemoved(builderName):
- """The Builder has been removed."""
-
- def slaveConnected(slaveName):
- """The slave has connected."""
-
- def slaveDisconnected(slaveName):
- """The slave has disconnected."""
-
- def checkConfig(otherStatusReceivers):
- """Verify that there are no other status receivers which conflict with
- the current one.
-
- @type otherStatusReceivers: A list of L{IStatusReceiver} objects which
- will contain self.
- """
-
-
-class IControl(Interface):
- def addChange(change):
- """Add a change to the change queue, for analysis by schedulers."""
-
- def getBuilder(name):
- """Retrieve the IBuilderControl object for the given Builder."""
-
-class IBuilderControl(Interface):
- def submitBuildRequest(ss, reason, props=None):
- """Create a BuildRequest, which will eventually cause a build of the
- given SourceStamp to be run on this builder. This returns a
- BuildRequestStatus object via a Deferred, which can be used to keep
- track of the builds that are performed."""
-
- def rebuildBuild(buildStatus, reason="<rebuild, no reason given>"):
- """Rebuild something we've already built before. This submits a
- BuildRequest to our Builder using the same SourceStamp as the earlier
- build. This has no effect (but may eventually raise an exception) if
- this Build has not yet finished."""
-
- def getPendingBuildRequestControls():
- """
- Get a list of L{IBuildRequestControl} objects for this Builder.
- Each one corresponds to an unclaimed build request.
-
- @returns: list of objects via Deferred
- """
-
- def getBuild(number):
- """Attempt to return an IBuildControl object for the given build.
- Returns None if no such object is available. This will only work for
- the build that is currently in progress: once the build finishes,
- there is nothing to control anymore."""
-
- def ping():
- """Attempt to contact the slave and see if it is still alive. This
- returns a Deferred which fires with either True (the slave is still
- alive) or False (the slave did not respond). As a side effect, adds an
- event to this builder's column in the waterfall display containing the
- results of the ping. Note that this may not fail for a long time, it is
- implemented in terms of the timeout on the underlying TCP connection."""
- # TODO: this ought to live in ISlaveControl, maybe with disconnect()
- # or something. However the event that is emitted is most useful in
- # the Builder column, so it kinda fits here too.
-
-class IBuildRequestControl(Interface):
- def subscribe(observer):
- """Register a callable that will be invoked (with a single
- IBuildControl object) for each Build that is created to satisfy this
- request. There may be multiple Builds created in an attempt to handle
- the request: they may be interrupted by the user or abandoned due to
- a lost slave. The last Build (the one which actually gets to run to
- completion) is said to 'satisfy' the BuildRequest. The observer will
- be called once for each of these Builds, both old and new."""
- def unsubscribe(observer):
- """Unregister the callable that was registered with subscribe()."""
- def cancel():
- """Remove the build from the pending queue. Has no effect if the
- build has already been started."""
-
-class IBuildControl(Interface):
- def getStatus():
- """Return an IBuildStatus object for the Build that I control."""
- def stopBuild(reason="<no reason given>"):
- """Halt the build. This has no effect if the build has already
- finished."""
-
-class ILogFile(Interface):
- """This is the internal interface to a LogFile, used by the BuildStep to
- write data into the log.
- """
- def addStdout(data):
- pass
- def addStderr(data):
- pass
- def addHeader(data):
- pass
- def finish():
- """The process that is feeding the log file has finished, and no
- further data will be added. This closes the logfile."""
-
-class ILogObserver(Interface):
- """Objects which provide this interface can be used in a BuildStep to
- watch the output of a LogFile and parse it incrementally.
- """
-
- # internal methods
- def setStep(step):
- pass
- def setLog(log):
- pass
-
- # methods called by the LogFile
- def logChunk(build, step, log, channel, text):
- pass
-
-class IBuildSlave(Interface):
- # this is a marker interface for the BuildSlave class
- pass
-
-class ILatentBuildSlave(IBuildSlave):
- """A build slave that is not always running, but can run when requested.
- """
- substantiated = Attribute('Substantiated',
- 'Whether the latent build slave is currently '
- 'substantiated with a real instance.')
-
- def substantiate():
- """Request that the slave substantiate with a real instance.
-
- Returns a deferred that will callback when a real instance has
- attached."""
-
- # there is an insubstantiate too, but that is not used externally ATM.
-
- def buildStarted(sb):
- """Inform the latent build slave that a build has started.
-
- @param sb: a L{LatentSlaveBuilder}. The sb is the one for whom the
- build finished.
- """
-
- def buildFinished(sb):
- """Inform the latent build slave that a build has finished.
-
- @param sb: a L{LatentSlaveBuilder}. The sb is the one for whom the
- build finished.
- """
-
-class IRenderable(Interface):
- """An object that can be interpolated with properties from a build.
- """
-
- def getRenderingFor(iprops):
- """Return a deferred that fires with interpolation with the given properties
-
- @param iprops: the L{IProperties} provider supplying the properties.
- """
-class IProperties(Interface):
- """
- An object providing access to build properties
- """
-
- def getProperty(name, default=None):
- """Get the named property, returning the default if the property does
- not exist.
-
- @param name: property name
- @type name: string
-
- @param default: default value (default: @code{None})
-
- @returns: property value
- """
-
- def hasProperty(name):
- """Return true if the named property exists.
-
- @param name: property name
- @type name: string
- @returns: boolean
- """
-
- def has_key(name):
- """Deprecated name for L{hasProperty}."""
-
- def setProperty(name, value, source, runtime=False):
- """Set the given property, overwriting any existing value. The source
- describes the source of the value for human interpretation.
-
- @param name: property name
- @type name: string
-
- @param value: property value
- @type value: JSON-able value
-
- @param source: property source
- @type source: string
-
- @param runtime: (optional) whether this property was set during the
- build's runtime: usually left at its default value
- @type runtime: boolean
- """
-
- def getProperties():
- """Get the L{buildbot.process.properties.Properties} instance storing
- these properties. Note that the interface for this class is not
- stable, so where possible the other methods of this interface should be
- used.
-
- @returns: L{buildbot.process.properties.Properties} instance
- """
-
- def getBuild():
- """Get the L{buildbot.process.build.Build} instance for the current
- build. Note that this object is not available after the build is
- complete, at which point this method will return None.
-
- Try to avoid using this method, as the API of L{Build} instances is not
- well-defined.
-
- @returns L{buildbot.process.build.Build} instance
- """
-
- def render(value):
- """Render @code{value} as an L{IRenderable}. This essentially coerces
- @code{value} to an L{IRenderable} and calls its @L{getRenderingFor}
- method.
-
- @name value: value to render
- @returns: rendered value
- """
-
-class IScheduler(Interface):
- pass
-
-class ITriggerableScheduler(Interface):
- """
- A scheduler that can be triggered by buildsteps.
- """
-
- def trigger(sourcestamps, set_props=None):
- """Trigger a build with the given source stamp and properties.
- """
-
-class IBuildStepFactory(Interface):
- def buildStep():
- """
- """
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py
deleted file mode 100644
index ab9b2730..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-from buildbot.buildslave.libvirt import (
- LibVirtSlave, Domain, Connection)
-
-for _attr in ["LibVirtSlave", "Connection", "Domain"]:
- deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
- "It has been moved to buildbot.buildslave.libvirt",
- "buildbot.libvirtbuildslave", _attr)
-
-_hush_pyflakes = [
- LibVirtSlave, Domain, Connection]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py
deleted file mode 100644
index 0f6941d4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py
+++ /dev/null
@@ -1,310 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import util
-from buildbot.util import subscription
-from buildbot.util.eventual import eventually
-
-if False: # for debugging
- debuglog = log.msg
-else:
- debuglog = lambda m: None
-
-class BaseLock:
- """
- Class handling claiming and releasing of L{self}, and keeping track of
- current and waiting owners.
-
- We maintain the wait queue in FIFO order, and ensure that counting waiters
- in the queue behind exclusive waiters cannot acquire the lock. This ensures
- that exclusive waiters are not starved.
- """
- description = "<BaseLock>"
-
- def __init__(self, name, maxCount=1):
- self.name = name # Name of the lock
- self.waiting = [] # Current queue, tuples (waiter, LockAccess,
- # deferred)
- self.owners = [] # Current owners, tuples (owner, LockAccess)
- self.maxCount = maxCount # maximal number of counting owners
-
- # subscriptions to this lock being released
- self.release_subs = subscription.SubscriptionPoint("%r releases"
- % (self,))
-
- def __repr__(self):
- return self.description
-
- def _getOwnersCount(self):
- """ Return the number of current exclusive and counting owners.
-
- @return: Tuple (number exclusive owners, number counting owners)
- """
- num_excl, num_counting = 0, 0
- for owner in self.owners:
- if owner[1].mode == 'exclusive':
- num_excl = num_excl + 1
- else: # mode == 'counting'
- num_counting = num_counting + 1
-
- assert (num_excl == 1 and num_counting == 0) \
- or (num_excl == 0 and num_counting <= self.maxCount)
- return num_excl, num_counting
-
-
- def isAvailable(self, requester, access):
- """ Return a boolean whether the lock is available for claiming """
- debuglog("%s isAvailable(%s, %s): self.owners=%r"
- % (self, requester, access, self.owners))
- num_excl, num_counting = self._getOwnersCount()
-
- # Find all waiters ahead of the requester in the wait queue
- for idx, waiter in enumerate(self.waiting):
- if waiter[0] == requester:
- w_index = idx
- break
- else:
- w_index = len(self.waiting)
- ahead = self.waiting[:w_index]
-
- if access.mode == 'counting':
- # Wants counting access
- return num_excl == 0 and num_counting + len(ahead) < self.maxCount \
- and all([w[1].mode == 'counting' for w in ahead])
- else:
- # Wants exclusive access
- return num_excl == 0 and num_counting == 0 and len(ahead) == 0
-
- def claim(self, owner, access):
- """ Claim the lock (lock must be available) """
- debuglog("%s claim(%s, %s)" % (self, owner, access.mode))
- assert owner is not None
- assert self.isAvailable(owner, access), "ask for isAvailable() first"
-
- assert isinstance(access, LockAccess)
- assert access.mode in ['counting', 'exclusive']
- self.waiting = [w for w in self.waiting if w[0] != owner]
- self.owners.append((owner, access))
- debuglog(" %s is claimed '%s'" % (self, access.mode))
-
- def subscribeToReleases(self, callback):
- """Schedule C{callback} to be invoked every time this lock is
- released. Returns a L{Subscription}."""
- return self.release_subs.subscribe(callback)
-
- def release(self, owner, access):
- """ Release the lock """
- assert isinstance(access, LockAccess)
-
- debuglog("%s release(%s, %s)" % (self, owner, access.mode))
- entry = (owner, access)
- if not entry in self.owners:
- debuglog("%s already released" % self)
- return
- self.owners.remove(entry)
- # who can we wake up?
- # After an exclusive access, we may need to wake up several waiting.
- # Break out of the loop when the first waiting client should not be awakened.
- num_excl, num_counting = self._getOwnersCount()
- for i, (w_owner, w_access, d) in enumerate(self.waiting):
- if w_access.mode == 'counting':
- if num_excl > 0 or num_counting == self.maxCount:
- break
- else:
- num_counting = num_counting + 1
- else:
- # w_access.mode == 'exclusive'
- if num_excl > 0 or num_counting > 0:
- break
- else:
- num_excl = num_excl + 1
-
- # If the waiter has a deferred, wake it up and clear the deferred
- # from the wait queue entry to indicate that it has been woken.
- if d:
- self.waiting[i] = (w_owner, w_access, None)
- eventually(d.callback, self)
-
- # notify any listeners
- self.release_subs.deliver()
-
- def waitUntilMaybeAvailable(self, owner, access):
- """Fire when the lock *might* be available. The caller will need to
- check with isAvailable() when the deferred fires. This loose form is
- used to avoid deadlocks. If we were interested in a stronger form,
- this would be named 'waitUntilAvailable', and the deferred would fire
- after the lock had been claimed.
- """
- debuglog("%s waitUntilAvailable(%s)" % (self, owner))
- assert isinstance(access, LockAccess)
- if self.isAvailable(owner, access):
- return defer.succeed(self)
- d = defer.Deferred()
-
- # Are we already in the wait queue?
- w = [i for i, w in enumerate(self.waiting) if w[0] == owner]
- if w:
- self.waiting[w[0]] = (owner, access, d)
- else:
- self.waiting.append((owner, access, d))
- return d
-
- def stopWaitingUntilAvailable(self, owner, access, d):
- debuglog("%s stopWaitingUntilAvailable(%s)" % (self, owner))
- assert isinstance(access, LockAccess)
- assert (owner, access, d) in self.waiting
- self.waiting = [w for w in self.waiting if w[0] != owner]
-
- def isOwner(self, owner, access):
- return (owner, access) in self.owners
-
-
-class RealMasterLock(BaseLock):
- def __init__(self, lockid):
- BaseLock.__init__(self, lockid.name, lockid.maxCount)
- self.description = "<MasterLock(%s, %s)>" % (self.name, self.maxCount)
-
- def getLock(self, slave):
- return self
-
-class RealSlaveLock:
- def __init__(self, lockid):
- self.name = lockid.name
- self.maxCount = lockid.maxCount
- self.maxCountForSlave = lockid.maxCountForSlave
- self.description = "<SlaveLock(%s, %s, %s)>" % (self.name,
- self.maxCount,
- self.maxCountForSlave)
- self.locks = {}
-
- def __repr__(self):
- return self.description
-
- def getLock(self, slave):
- slavename = slave.slavename
- if not self.locks.has_key(slavename):
- maxCount = self.maxCountForSlave.get(slavename,
- self.maxCount)
- lock = self.locks[slavename] = BaseLock(self.name, maxCount)
- desc = "<SlaveLock(%s, %s)[%s] %d>" % (self.name, maxCount,
- slavename, id(lock))
- lock.description = desc
- self.locks[slavename] = lock
- return self.locks[slavename]
-
-
-class LockAccess(util.ComparableMixin):
- """ I am an object representing a way to access a lock.
-
- @param lockid: LockId instance that should be accessed.
- @type lockid: A MasterLock or SlaveLock instance.
-
- @param mode: Mode of accessing the lock.
- @type mode: A string, either 'counting' or 'exclusive'.
- """
-
- compare_attrs = ['lockid', 'mode']
- def __init__(self, lockid, mode, _skipChecks=False):
- self.lockid = lockid
- self.mode = mode
-
- if not _skipChecks:
- # these checks fail with mock < 0.8.0 when lockid is a Mock
- # TODO: remove this in Buildbot-0.9.0+
- assert isinstance(lockid, (MasterLock, SlaveLock))
- assert mode in ['counting', 'exclusive']
-
-
-class BaseLockId(util.ComparableMixin):
- """ Abstract base class for LockId classes.
-
- Sets up the 'access()' function for the LockId's available to the user
- (MasterLock and SlaveLock classes).
- Derived classes should add
- - Comparison with the L{util.ComparableMixin} via the L{compare_attrs}
- class variable.
- - Link to the actual lock class should be added with the L{lockClass}
- class variable.
- """
- def access(self, mode):
- """ Express how the lock should be accessed """
- assert mode in ['counting', 'exclusive']
- return LockAccess(self, mode)
-
- def defaultAccess(self):
- """ For buildbot 0.7.7 compability: When user doesn't specify an access
- mode, this one is chosen.
- """
- return self.access('counting')
-
-
-
-# master.cfg should only reference the following MasterLock and SlaveLock
-# classes. They are identifiers that will be turned into real Locks later,
-# via the BotMaster.getLockByID method.
-
-class MasterLock(BaseLockId):
- """I am a semaphore that limits the number of simultaneous actions.
-
- Builds and BuildSteps can declare that they wish to claim me as they run.
- Only a limited number of such builds or steps will be able to run
- simultaneously. By default this number is one, but my maxCount parameter
- can be raised to allow two or three or more operations to happen at the
- same time.
-
- Use this to protect a resource that is shared among all builders and all
- slaves, for example to limit the load on a common SVN repository.
- """
-
- compare_attrs = ['name', 'maxCount']
- lockClass = RealMasterLock
- def __init__(self, name, maxCount=1):
- self.name = name
- self.maxCount = maxCount
-
-class SlaveLock(BaseLockId):
- """I am a semaphore that limits simultaneous actions on each buildslave.
-
- Builds and BuildSteps can declare that they wish to claim me as they run.
- Only a limited number of such builds or steps will be able to run
- simultaneously on any given buildslave. By default this number is one,
- but my maxCount parameter can be raised to allow two or three or more
- operations to happen on a single buildslave at the same time.
-
- Use this to protect a resource that is shared among all the builds taking
- place on each slave, for example to limit CPU or memory load on an
- underpowered machine.
-
- Each buildslave will get an independent copy of this semaphore. By
- default each copy will use the same owner count (set with maxCount), but
- you can provide maxCountForSlave with a dictionary that maps slavename to
- owner count, to allow some slaves more parallelism than others.
-
- """
-
- compare_attrs = ['name', 'maxCount', '_maxCountForSlaveList']
- lockClass = RealSlaveLock
- def __init__(self, name, maxCount=1, maxCountForSlave={}):
- self.name = name
- self.maxCount = maxCount
- self.maxCountForSlave = maxCountForSlave
- # for comparison purposes, turn this dictionary into a stably-sorted
- # list of tuples
- self._maxCountForSlaveList = self.maxCountForSlave.items()
- self._maxCountForSlaveList.sort()
- self._maxCountForSlaveList = tuple(self._maxCountForSlaveList)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py
deleted file mode 100644
index 2e20084b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-import os
-import types
-import binascii
-import base64
-from twisted.python import log
-from twisted.application import service, strports
-from twisted.cred import checkers, portal
-from twisted.conch import manhole, telnet
-try:
- from twisted.conch import checkers as conchc, manhole_ssh
- _hush_pyflakes = [manhole_ssh, conchc]
- del _hush_pyflakes
-except ImportError:
- manhole_ssh = None
- conchc = None
-from twisted.conch.insults import insults
-from twisted.internet import protocol
-
-from buildbot import config
-from buildbot.util import ComparableMixin
-from zope.interface import implements # requires Twisted-2.0 or later
-
-# makeTelnetProtocol and _TelnetRealm are for the TelnetManhole
-
-class makeTelnetProtocol:
- # this curries the 'portal' argument into a later call to
- # TelnetTransport()
- def __init__(self, portal):
- self.portal = portal
-
- def __call__(self):
- auth = telnet.AuthenticatingTelnetProtocol
- return telnet.TelnetTransport(auth, self.portal)
-
-class _TelnetRealm:
- implements(portal.IRealm)
-
- def __init__(self, namespace_maker):
- self.namespace_maker = namespace_maker
-
- def requestAvatar(self, avatarId, *interfaces):
- if telnet.ITelnetProtocol in interfaces:
- namespace = self.namespace_maker()
- p = telnet.TelnetBootstrapProtocol(insults.ServerProtocol,
- manhole.ColoredManhole,
- namespace)
- return (telnet.ITelnetProtocol, p, lambda: None)
- raise NotImplementedError()
-
-
-class chainedProtocolFactory:
- # this curries the 'namespace' argument into a later call to
- # chainedProtocolFactory()
- def __init__(self, namespace):
- self.namespace = namespace
-
- def __call__(self):
- return insults.ServerProtocol(manhole.ColoredManhole, self.namespace)
-
-if conchc:
- class AuthorizedKeysChecker(conchc.SSHPublicKeyDatabase):
- """Accept connections using SSH keys from a given file.
-
- SSHPublicKeyDatabase takes the username that the prospective client has
- requested and attempts to get a ~/.ssh/authorized_keys file for that
- username. This requires root access, so it isn't as useful as you'd
- like.
-
- Instead, this subclass looks for keys in a single file, given as an
- argument. This file is typically kept in the buildmaster's basedir. The
- file should have 'ssh-dss ....' lines in it, just like authorized_keys.
- """
-
- def __init__(self, authorized_keys_file):
- self.authorized_keys_file = os.path.expanduser(authorized_keys_file)
-
- def checkKey(self, credentials):
- with open(self.authorized_keys_file) as f:
- for l in f.readlines():
- l2 = l.split()
- if len(l2) < 2:
- continue
- try:
- if base64.decodestring(l2[1]) == credentials.blob:
- return 1
- except binascii.Error:
- continue
- return 0
-
-
-class _BaseManhole(service.MultiService):
- """This provides remote access to a python interpreter (a read/exec/print
- loop) embedded in the buildmaster via an internal SSH server. This allows
- detailed inspection of the buildmaster state. It is of most use to
- buildbot developers. Connect to this by running an ssh client.
- """
-
- def __init__(self, port, checker, using_ssh=True):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @type checker: an object providing the
- L{twisted.cred.checkers.ICredentialsChecker} interface
- @param checker: if provided, this checker is used to authenticate the
- client instead of using the username/password scheme. You must either
- provide a username/password or a Checker. Some useful values are::
- import twisted.cred.checkers as credc
- import twisted.conch.checkers as conchc
- c = credc.AllowAnonymousAccess # completely open
- c = credc.FilePasswordDB(passwd_filename) # file of name:passwd
- c = conchc.UNIXPasswordDatabase # getpwnam() (probably /etc/passwd)
-
- @type using_ssh: bool
- @param using_ssh: If True, accept SSH connections. If False, accept
- regular unencrypted telnet connections.
- """
-
- # unfortunately, these don't work unless we're running as root
- #c = credc.PluggableAuthenticationModulesChecker: PAM
- #c = conchc.SSHPublicKeyDatabase() # ~/.ssh/authorized_keys
- # and I can't get UNIXPasswordDatabase to work
-
- service.MultiService.__init__(self)
- if type(port) is int:
- port = "tcp:%d" % port
- self.port = port # for comparison later
- self.checker = checker # to maybe compare later
-
- def makeNamespace():
- master = self.master
- namespace = {
- 'master': master,
- 'status': master.getStatus(),
- 'show': show,
- }
- return namespace
-
- def makeProtocol():
- namespace = makeNamespace()
- p = insults.ServerProtocol(manhole.ColoredManhole, namespace)
- return p
-
- self.using_ssh = using_ssh
- if using_ssh:
- r = manhole_ssh.TerminalRealm()
- r.chainedProtocolFactory = makeProtocol
- p = portal.Portal(r, [self.checker])
- f = manhole_ssh.ConchFactory(p)
- else:
- r = _TelnetRealm(makeNamespace)
- p = portal.Portal(r, [self.checker])
- f = protocol.ServerFactory()
- f.protocol = makeTelnetProtocol(p)
- s = strports.service(self.port, f)
- s.setServiceParent(self)
-
-
- def startService(self):
- service.MultiService.startService(self)
- if self.using_ssh:
- via = "via SSH"
- else:
- via = "via telnet"
- log.msg("Manhole listening %s on port %s" % (via, self.port))
-
-
-class TelnetManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts unencrypted (telnet) connections, and requires a
- username and password authorize access. You are encouraged to use the
- encrypted ssh-based manhole classes instead."""
-
- compare_attrs = ["port", "username", "password"]
-
- def __init__(self, port, username, password):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param username:
- @param password: username= and password= form a pair of strings to
- use when authenticating the remote user.
- """
-
- self.username = username
- self.password = password
-
- c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser(username, password)
-
- _BaseManhole.__init__(self, port, c, using_ssh=False)
-
-class PasswordManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts encrypted (ssh) connections, and requires a
- username and password to authorize access.
- """
-
- compare_attrs = ["port", "username", "password"]
-
- def __init__(self, port, username, password):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param username:
- @param password: username= and password= form a pair of strings to
- use when authenticating the remote user.
- """
-
- if not manhole_ssh:
- config.error("pycrypto required for ssh mahole.")
- self.username = username
- self.password = password
-
- c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser(username, password)
-
- _BaseManhole.__init__(self, port, c)
-
-class AuthorizedKeysManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts ssh connections, and requires that the
- prospective client have an ssh private key that matches one of the public
- keys in our authorized_keys file. It is created with the name of a file
- that contains the public keys that we will accept."""
-
- compare_attrs = ["port", "keyfile"]
-
- def __init__(self, port, keyfile):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param keyfile: the name of a file (relative to the buildmaster's
- basedir) that contains SSH public keys of authorized
- users, one per line. This is the exact same format
- as used by sshd in ~/.ssh/authorized_keys .
- """
-
- if not manhole_ssh:
- config.error("pycrypto required for ssh mahole.")
-
- # TODO: expanduser this, and make it relative to the buildmaster's
- # basedir
- self.keyfile = keyfile
- c = AuthorizedKeysChecker(keyfile)
- _BaseManhole.__init__(self, port, c)
-
-class ArbitraryCheckerManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts ssh connections, but uses an arbitrary
- user-supplied 'checker' object to perform authentication."""
-
- compare_attrs = ["port", "checker"]
-
- def __init__(self, port, checker):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param checker: an instance of a twisted.cred 'checker' which will
- perform authentication
- """
-
- if not manhole_ssh:
- config.error("pycrypto required for ssh mahole.")
-
- _BaseManhole.__init__(self, port, checker)
-
-## utility functions for the manhole
-
-def show(x):
- """Display the data attributes of an object in a readable format"""
- print "data attributes of %r" % (x,)
- names = dir(x)
- maxlen = max([0] + [len(n) for n in names])
- for k in names:
- v = getattr(x,k)
- t = type(v)
- if t == types.MethodType: continue
- if k[:2] == '__' and k[-2:] == '__': continue
- if t is types.StringType or t is types.UnicodeType:
- if len(v) > 80 - maxlen - 5:
- v = `v[:80 - maxlen - 5]` + "..."
- elif t in (types.IntType, types.NoneType):
- v = str(v)
- elif v in (types.ListType, types.TupleType, types.DictType):
- v = "%s (%d elements)" % (v, len(v))
- else:
- v = str(t)
- print "%*s : %s" % (maxlen, k, v)
- return x
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py
deleted file mode 100644
index 63c784fa..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py
+++ /dev/null
@@ -1,779 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os
-import signal
-import socket
-
-from zope.interface import implements
-from twisted.python import log, components, failure
-from twisted.internet import defer, reactor, task
-from twisted.application import service
-
-import buildbot
-import buildbot.pbmanager
-from buildbot.util import subscription, epoch2datetime
-from buildbot.status.master import Status
-from buildbot.changes import changes
-from buildbot.changes.manager import ChangeManager
-from buildbot import interfaces
-from buildbot.process.builder import BuilderControl
-from buildbot.db import connector
-from buildbot.schedulers.manager import SchedulerManager
-from buildbot.process.botmaster import BotMaster
-from buildbot.process import debug
-from buildbot.process import metrics
-from buildbot.process import cache
-from buildbot.process.users import users
-from buildbot.process.users.manager import UserManagerManager
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot.util.eventual import eventually
-from buildbot import monkeypatches
-from buildbot import config
-
-########################################
-
-class LogRotation(object):
- def __init__(self):
- self.rotateLength = 1 * 1000 * 1000
- self.maxRotatedFiles = 10
-
-class BuildMaster(config.ReconfigurableServiceMixin, service.MultiService):
-
- # frequency with which to reclaim running builds; this should be set to
- # something fairly long, to avoid undue database load
- RECLAIM_BUILD_INTERVAL = 10*60
-
- # multiplier on RECLAIM_BUILD_INTERVAL at which a build is considered
- # unclaimed; this should be at least 2 to avoid false positives
- UNCLAIMED_BUILD_FACTOR = 6
-
- # if this quantity of unclaimed build requests are present in the table,
- # then something is probably wrong! The master will log a WARNING on every
- # database poll operation.
- WARNING_UNCLAIMED_COUNT = 10000
-
- def __init__(self, basedir, configFileName="master.cfg", umask=None):
- service.MultiService.__init__(self)
- self.setName("buildmaster")
-
- self.umask = umask
-
- self.basedir = basedir
- assert os.path.isdir(self.basedir)
- self.configFileName = configFileName
-
- # set up child services
- self.create_child_services()
-
- # loop for polling the db
- self.db_loop = None
- # db configured values
- self.configured_db_url = None
- self.configured_poll_interval = None
-
- # configuration / reconfiguration handling
- self.config = config.MasterConfig()
- self.reconfig_active = False
- self.reconfig_requested = False
- self.reconfig_notifier = None
-
- # this stores parameters used in the tac file, and is accessed by the
- # WebStatus to duplicate those values.
- self.log_rotation = LogRotation()
-
- # subscription points
- self._change_subs = \
- subscription.SubscriptionPoint("changes")
- self._new_buildrequest_subs = \
- subscription.SubscriptionPoint("buildrequest_additions")
- self._new_buildset_subs = \
- subscription.SubscriptionPoint("buildset_additions")
- self._complete_buildset_subs = \
- subscription.SubscriptionPoint("buildset_completion")
-
- # local cache for this master's object ID
- self._object_id = None
-
-
- def create_child_services(self):
- # note that these are order-dependent. If you get the order wrong,
- # you'll know it, as the master will fail to start.
-
- self.metrics = metrics.MetricLogObserver()
- self.metrics.setServiceParent(self)
-
- self.caches = cache.CacheManager()
- self.caches.setServiceParent(self)
-
- self.pbmanager = buildbot.pbmanager.PBManager()
- self.pbmanager.setServiceParent(self)
-
- self.change_svc = ChangeManager(self)
- self.change_svc.setServiceParent(self)
-
- self.botmaster = BotMaster(self)
- self.botmaster.setServiceParent(self)
-
- self.scheduler_manager = SchedulerManager(self)
- self.scheduler_manager.setServiceParent(self)
-
- self.user_manager = UserManagerManager(self)
- self.user_manager.setServiceParent(self)
-
- self.db = connector.DBConnector(self, self.basedir)
- self.db.setServiceParent(self)
-
- self.debug = debug.DebugServices(self)
- self.debug.setServiceParent(self)
-
- self.status = Status(self)
- self.status.setServiceParent(self)
-
- # setup and reconfig handling
-
- _already_started = False
- @defer.inlineCallbacks
- def startService(self, _reactor=reactor):
- assert not self._already_started, "can only start the master once"
- self._already_started = True
-
- log.msg("Starting BuildMaster -- buildbot.version: %s" %
- buildbot.version)
-
- # Set umask
- if self.umask is not None:
- os.umask(self.umask)
-
- # first, apply all monkeypatches
- monkeypatches.patch_all()
-
- # we want to wait until the reactor is running, so we can call
- # reactor.stop() for fatal errors
- d = defer.Deferred()
- _reactor.callWhenRunning(d.callback, None)
- yield d
-
- try:
- # load the configuration file, treating errors as fatal
- try:
- self.config = config.MasterConfig.loadConfig(self.basedir,
- self.configFileName)
-
- except config.ConfigErrors, e:
- log.msg("Configuration Errors:")
- for msg in e.errors:
- log.msg(" " + msg)
- log.msg("Halting master.")
- _reactor.stop()
- return
- except:
- log.err(failure.Failure(), 'while starting BuildMaster')
- _reactor.stop()
- return
-
- # set up services that need access to the config before everything else
- # gets told to reconfig
- try:
- yield self.db.setup()
- except connector.DatabaseNotReadyError:
- # (message was already logged)
- _reactor.stop()
- return
-
- if hasattr(signal, "SIGHUP"):
- def sighup(*args):
- eventually(self.reconfig)
- signal.signal(signal.SIGHUP, sighup)
-
- if hasattr(signal, "SIGUSR1"):
- def sigusr1(*args):
- _reactor.callLater(0, self.botmaster.cleanShutdown)
- signal.signal(signal.SIGUSR1, sigusr1)
-
- # call the parent method
- yield defer.maybeDeferred(lambda :
- service.MultiService.startService(self))
-
- # give all services a chance to load the new configuration, rather than
- # the base configuration
- yield self.reconfigService(self.config)
- except:
- f = failure.Failure()
- log.err(f, 'while starting BuildMaster')
- _reactor.stop()
-
- log.msg("BuildMaster is running")
-
- @defer.inlineCallbacks
- def stopService(self):
- if self.running:
- yield service.MultiService.stopService(self)
- if self.db_loop:
- self.db_loop.stop()
- self.db_loop = None
-
-
- def reconfig(self):
- # this method wraps doConfig, ensuring it is only ever called once at
- # a time, and alerting the user if the reconfig takes too long
- if self.reconfig_active:
- log.msg("reconfig already active; will reconfig again after")
- self.reconfig_requested = True
- return
-
- self.reconfig_active = reactor.seconds()
- metrics.MetricCountEvent.log("loaded_config", 1)
-
- # notify every 10 seconds that the reconfig is still going on, although
- # reconfigs should not take that long!
- self.reconfig_notifier = task.LoopingCall(lambda :
- log.msg("reconfig is ongoing for %d s" %
- (reactor.seconds() - self.reconfig_active)))
- self.reconfig_notifier.start(10, now=False)
-
- timer = metrics.Timer("BuildMaster.reconfig")
- timer.start()
-
- d = self.doReconfig()
-
- @d.addBoth
- def cleanup(res):
- timer.stop()
- self.reconfig_notifier.stop()
- self.reconfig_notifier = None
- self.reconfig_active = False
- if self.reconfig_requested:
- self.reconfig_requested = False
- self.reconfig()
- return res
-
- d.addErrback(log.err, 'while reconfiguring')
-
- return d # for tests
-
-
- @defer.inlineCallbacks
- def doReconfig(self):
- log.msg("beginning configuration update")
- changes_made = False
- failed = False
- try:
- new_config = config.MasterConfig.loadConfig(self.basedir,
- self.configFileName)
- changes_made = True
- self.config = new_config
- yield self.reconfigService(new_config)
-
- except config.ConfigErrors, e:
- for msg in e.errors:
- log.msg(msg)
- failed = True
-
- except:
- log.err(failure.Failure(), 'during reconfig:')
- failed = True
-
- if failed:
- if changes_made:
- log.msg("WARNING: reconfig partially applied; master "
- "may malfunction")
- else:
- log.msg("reconfig aborted without making any changes")
- else:
- log.msg("configuration update complete")
-
-
- def reconfigService(self, new_config):
- if self.configured_db_url is None:
- self.configured_db_url = new_config.db['db_url']
- elif (self.configured_db_url != new_config.db['db_url']):
- config.error(
- "Cannot change c['db']['db_url'] after the master has started",
- )
-
- # adjust the db poller
- if (self.configured_poll_interval
- != new_config.db['db_poll_interval']):
- if self.db_loop:
- self.db_loop.stop()
- self.db_loop = None
- self.configured_poll_interval = new_config.db['db_poll_interval']
- if self.configured_poll_interval:
- self.db_loop = task.LoopingCall(self.pollDatabase)
- self.db_loop.start(self.configured_poll_interval, now=False)
-
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
-
- ## informational methods
-
- def allSchedulers(self):
- return list(self.scheduler_manager)
-
- def getStatus(self):
- """
- @rtype: L{buildbot.status.builder.Status}
- """
- return self.status
-
- def getObjectId(self):
- """
- Return the obejct id for this master, for associating state with the
- master.
-
- @returns: ID, via Deferred
- """
- # try to get the cached value
- if self._object_id is not None:
- return defer.succeed(self._object_id)
-
- # failing that, get it from the DB; multiple calls to this function
- # at the same time will not hurt
- try:
- hostname = os.uname()[1] # only on unix
- except AttributeError:
- hostname = socket.getfqdn()
- master_name = "%s:%s" % (hostname, os.path.abspath(self.basedir))
-
- d = self.db.state.getObjectId(master_name,
- "buildbot.master.BuildMaster")
- def keep(id):
- self._object_id = id
- return id
- d.addCallback(keep)
- return d
-
-
- ## triggering methods and subscriptions
-
- def addChange(self, who=None, files=None, comments=None, author=None,
- isdir=None, is_dir=None, revision=None, when=None,
- when_timestamp=None, branch=None, category=None, revlink='',
- properties={}, repository='', codebase=None, project='', src=None):
- """
- Add a change to the buildmaster and act on it.
-
- This is a wrapper around L{ChangesConnectorComponent.addChange} which
- also acts on the resulting change and returns a L{Change} instance.
-
- Note that all parameters are keyword arguments, although C{who},
- C{files}, and C{comments} can be specified positionally for
- backward-compatibility.
-
- @param author: the author of this change
- @type author: unicode string
-
- @param who: deprecated name for C{author}
-
- @param files: a list of filenames that were changed
- @type branch: list of unicode strings
-
- @param comments: user comments on the change
- @type branch: unicode string
-
- @param is_dir: deprecated
-
- @param isdir: deprecated name for C{is_dir}
-
- @param revision: the revision identifier for this change
- @type revision: unicode string
-
- @param when_timestamp: when this change occurred, or the current time
- if None
- @type when_timestamp: datetime instance or None
-
- @param when: deprecated name and type for C{when_timestamp}
- @type when: integer (UNIX epoch time) or None
-
- @param branch: the branch on which this change took place
- @type branch: unicode string
-
- @param category: category for this change (arbitrary use by Buildbot
- users)
- @type category: unicode string
-
- @param revlink: link to a web view of this revision
- @type revlink: unicode string
-
- @param properties: properties to set on this change
- @type properties: dictionary with string keys and simple values
- (JSON-able). Note that the property source is I{not} included
- in this dictionary.
-
- @param repository: the repository in which this change took place
- @type repository: unicode string
-
- @param project: the project this change is a part of
- @type project: unicode string
-
- @param src: source of the change (vcs or other)
- @type src: string
-
- @returns: L{Change} instance via Deferred
- """
- metrics.MetricCountEvent.log("added_changes", 1)
-
- # handle translating deprecated names into new names for db.changes
- def handle_deprec(oldname, old, newname, new, default=None,
- converter = lambda x:x):
- if old is not None:
- if new is None:
- log.msg("WARNING: change source is using deprecated "
- "addChange parameter '%s'" % oldname)
- return converter(old)
- raise TypeError("Cannot provide '%s' and '%s' to addChange"
- % (oldname, newname))
- if new is None:
- new = default
- return new
-
- author = handle_deprec("who", who, "author", author)
- is_dir = handle_deprec("isdir", isdir, "is_dir", is_dir,
- default=0)
- when_timestamp = handle_deprec("when", when,
- "when_timestamp", when_timestamp,
- converter=epoch2datetime)
-
- # add a source to each property
- for n in properties:
- properties[n] = (properties[n], 'Change')
-
- if codebase is None:
- if self.config.codebaseGenerator is not None:
- chdict = {
- 'changeid': None,
- 'author': author,
- 'files': files,
- 'comments': comments,
- 'is_dir': is_dir,
- 'revision': revision,
- 'when_timestamp': when_timestamp,
- 'branch': branch,
- 'category': category,
- 'revlink': revlink,
- 'properties': properties,
- 'repository': repository,
- 'project': project,
- }
- codebase = self.config.codebaseGenerator(chdict)
- else:
- codebase = ''
-
- d = defer.succeed(None)
- if src:
- # create user object, returning a corresponding uid
- d.addCallback(lambda _ : users.createUserObject(self, author, src))
-
- # add the Change to the database
- d.addCallback(lambda uid :
- self.db.changes.addChange(author=author, files=files,
- comments=comments, is_dir=is_dir,
- revision=revision,
- when_timestamp=when_timestamp,
- branch=branch, category=category,
- revlink=revlink, properties=properties,
- repository=repository, codebase=codebase,
- project=project, uid=uid))
-
- # convert the changeid to a Change instance
- d.addCallback(lambda changeid :
- self.db.changes.getChange(changeid))
- d.addCallback(lambda chdict :
- changes.Change.fromChdict(self, chdict))
-
- def notify(change):
- msg = u"added change %s to database" % change
- log.msg(msg.encode('utf-8', 'replace'))
- # only deliver messages immediately if we're not polling
- if not self.config.db['db_poll_interval']:
- self._change_subs.deliver(change)
- return change
- d.addCallback(notify)
- return d
-
- def subscribeToChanges(self, callback):
- """
- Request that C{callback} be called with each Change object added to the
- cluster.
-
- Note: this method will go away in 0.9.x
- """
- return self._change_subs.subscribe(callback)
-
- def addBuildset(self, **kwargs):
- """
- Add a buildset to the buildmaster and act on it. Interface is
- identical to
- L{buildbot.db.buildsets.BuildsetConnectorComponent.addBuildset},
- including returning a Deferred, but also potentially triggers the
- resulting builds.
- """
- d = self.db.buildsets.addBuildset(**kwargs)
- def notify((bsid,brids)):
- log.msg("added buildset %d to database" % bsid)
- # note that buildset additions are only reported on this master
- self._new_buildset_subs.deliver(bsid=bsid, **kwargs)
- # only deliver messages immediately if we're not polling
- if not self.config.db['db_poll_interval']:
- for bn, brid in brids.iteritems():
- self.buildRequestAdded(bsid=bsid, brid=brid,
- buildername=bn)
- return (bsid,brids)
- d.addCallback(notify)
- return d
-
- def subscribeToBuildsets(self, callback):
- """
- Request that C{callback(bsid=bsid, ssid=ssid, reason=reason,
- properties=properties, builderNames=builderNames,
- external_idstring=external_idstring)} be called whenever a buildset is
- added. Properties is a dictionary as expected for
- L{BuildsetsConnectorComponent.addBuildset}.
-
- Note that this only works for buildsets added on this master.
-
- Note: this method will go away in 0.9.x
- """
- return self._new_buildset_subs.subscribe(callback)
-
- @defer.inlineCallbacks
- def maybeBuildsetComplete(self, bsid):
- """
- Instructs the master to check whether the buildset is complete,
- and notify appropriately if it is.
-
- Note that buildset completions are only reported on the master
- on which the last build request completes.
- """
- brdicts = yield self.db.buildrequests.getBuildRequests(
- bsid=bsid, complete=False)
-
- # if there are incomplete buildrequests, bail out
- if brdicts:
- return
-
- brdicts = yield self.db.buildrequests.getBuildRequests(bsid=bsid)
-
- # figure out the overall results of the buildset
- cumulative_results = SUCCESS
- for brdict in brdicts:
- if brdict['results'] not in (SUCCESS, WARNINGS):
- cumulative_results = FAILURE
-
- # mark it as completed in the database
- yield self.db.buildsets.completeBuildset(bsid, cumulative_results)
-
- # and deliver to any listeners
- self._buildsetComplete(bsid, cumulative_results)
-
- def _buildsetComplete(self, bsid, results):
- self._complete_buildset_subs.deliver(bsid, results)
-
- def subscribeToBuildsetCompletions(self, callback):
- """
- Request that C{callback(bsid, result)} be called whenever a
- buildset is complete.
-
- Note: this method will go away in 0.9.x
- """
- return self._complete_buildset_subs.subscribe(callback)
-
- def buildRequestAdded(self, bsid, brid, buildername):
- """
- Notifies the master that a build request is available to be claimed;
- this may be a brand new build request, or a build request that was
- previously claimed and unclaimed through a timeout or other calamity.
-
- @param bsid: containing buildset id
- @param brid: buildrequest ID
- @param buildername: builder named by the build request
- """
- self._new_buildrequest_subs.deliver(
- dict(bsid=bsid, brid=brid, buildername=buildername))
-
- def subscribeToBuildRequests(self, callback):
- """
- Request that C{callback} be invoked with a dictionary with keys C{brid}
- (the build request id), C{bsid} (buildset id) and C{buildername}
- whenever a new build request is added to the database. Note that, due
- to the delayed nature of subscriptions, the build request may already
- be claimed by the time C{callback} is invoked.
-
- Note: this method will go away in 0.9.x
- """
- return self._new_buildrequest_subs.subscribe(callback)
-
-
- ## database polling
-
- def pollDatabase(self):
- # poll each of the tables that can indicate new, actionable stuff for
- # this buildmaster to do. This is used in a TimerService, so returning
- # a Deferred means that we won't run two polling operations
- # simultaneously. Each particular poll method handles errors itself,
- # although catastrophic errors are handled here
- d = defer.gatherResults([
- self.pollDatabaseChanges(),
- self.pollDatabaseBuildRequests(),
- # also unclaim
- ])
- d.addErrback(log.err, 'while polling database')
- return d
-
- _last_processed_change = None
- @defer.inlineCallbacks
- def pollDatabaseChanges(self):
- # Older versions of Buildbot had each scheduler polling the database
- # independently, and storing a "last_processed" state indicating the
- # last change it had processed. This had the advantage of allowing
- # schedulers to pick up changes that arrived in the database while
- # the scheduler was not running, but was horribly inefficient.
-
- # This version polls the database on behalf of the schedulers, using a
- # similar state at the master level.
-
- timer = metrics.Timer("BuildMaster.pollDatabaseChanges()")
- timer.start()
-
- need_setState = False
-
- # get the last processed change id
- if self._last_processed_change is None:
- self._last_processed_change = \
- yield self._getState('last_processed_change')
-
- # if it's still None, assume we've processed up to the latest changeid
- if self._last_processed_change is None:
- lpc = yield self.db.changes.getLatestChangeid()
- # if there *are* no changes, count the last as '0' so that we don't
- # skip the first change
- if lpc is None:
- lpc = 0
- self._last_processed_change = lpc
-
- need_setState = True
-
- if self._last_processed_change is None:
- timer.stop()
- return
-
- while True:
- changeid = self._last_processed_change + 1
- chdict = yield self.db.changes.getChange(changeid)
-
- # if there's no such change, we've reached the end and can
- # stop polling
- if not chdict:
- break
-
- change = yield changes.Change.fromChdict(self, chdict)
-
- self._change_subs.deliver(change)
-
- self._last_processed_change = changeid
- need_setState = True
-
- # write back the updated state, if it's changed
- if need_setState:
- yield self._setState('last_processed_change',
- self._last_processed_change)
- timer.stop()
-
- _last_unclaimed_brids_set = None
- _last_claim_cleanup = 0
- @defer.inlineCallbacks
- def pollDatabaseBuildRequests(self):
- # deal with cleaning up unclaimed requests, and (if necessary)
- # requests from a previous instance of this master
- timer = metrics.Timer("BuildMaster.pollDatabaseBuildRequests()")
- timer.start()
-
- # cleanup unclaimed builds
- since_last_cleanup = reactor.seconds() - self._last_claim_cleanup
- if since_last_cleanup < self.RECLAIM_BUILD_INTERVAL:
- unclaimed_age = (self.RECLAIM_BUILD_INTERVAL
- * self.UNCLAIMED_BUILD_FACTOR)
- yield self.db.buildrequests.unclaimExpiredRequests(unclaimed_age)
-
- self._last_claim_cleanup = reactor.seconds()
-
- # _last_unclaimed_brids_set tracks the state of unclaimed build
- # requests; whenever it sees a build request which was not claimed on
- # the last poll, it notifies the subscribers. It only tracks that
- # state within the master instance, though; on startup, it notifies for
- # all unclaimed requests in the database.
-
- last_unclaimed = self._last_unclaimed_brids_set or set()
- if len(last_unclaimed) > self.WARNING_UNCLAIMED_COUNT:
- log.msg("WARNING: %d unclaimed buildrequests - is a scheduler "
- "producing builds for which no builder is running?"
- % len(last_unclaimed))
-
- # get the current set of unclaimed buildrequests
- now_unclaimed_brdicts = \
- yield self.db.buildrequests.getBuildRequests(claimed=False)
- now_unclaimed = set([ brd['brid'] for brd in now_unclaimed_brdicts ])
-
- # and store that for next time
- self._last_unclaimed_brids_set = now_unclaimed
-
- # see what's new, and notify if anything is
- new_unclaimed = now_unclaimed - last_unclaimed
- if new_unclaimed:
- brdicts = dict((brd['brid'], brd) for brd in now_unclaimed_brdicts)
- for brid in new_unclaimed:
- brd = brdicts[brid]
- self.buildRequestAdded(brd['buildsetid'], brd['brid'],
- brd['buildername'])
- timer.stop()
-
- ## state maintenance (private)
-
- def _getState(self, name, default=None):
- "private wrapper around C{self.db.state.getState}"
- d = self.getObjectId()
- def get(objectid):
- return self.db.state.getState(objectid, name, default)
- d.addCallback(get)
- return d
-
- def _setState(self, name, value):
- "private wrapper around C{self.db.state.setState}"
- d = self.getObjectId()
- def set(objectid):
- return self.db.state.setState(objectid, name, value)
- d.addCallback(set)
- return d
-
-class Control:
- implements(interfaces.IControl)
-
- def __init__(self, master):
- self.master = master
-
- def addChange(self, change):
- self.master.addChange(change)
-
- def addBuildset(self, **kwargs):
- return self.master.addBuildset(**kwargs)
-
- def getBuilder(self, name):
- b = self.master.botmaster.builders[name]
- return BuilderControl(b, self)
-
-components.registerAdapter(Control, BuildMaster, interfaces.IControl)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py
deleted file mode 100644
index 285e4476..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import twisted
-from twisted.python import versions
-from buildbot.util import sautils
-
-# NOTE: all of these patches test for applicability *before* importing the
-# patch module. This will help cut down on unnecessary imports where the
-# patches are not needed, and also avoid problems with patches importing
-# private things in external libraries that no longer exist.
-
-def patch_bug4881():
- # this patch doesn't apply (or even import!) on Windows
- import sys
- if sys.platform == 'win32':
- return
-
- # this bug was only present in Twisted-10.2.0
- if twisted.version == versions.Version('twisted', 10, 2, 0):
- from buildbot.monkeypatches import bug4881
- bug4881.patch()
-
-def patch_bug4520():
- # this bug was patched in twisted-11.1.0, and only affects py26 and up
- import sys
- py_26 = (sys.version_info[0] > 2 or
- (sys.version_info[0] == 2 and sys.version_info[1] >= 6))
- if twisted.version < versions.Version('twisted', 11, 1, 0) and py_26:
- from buildbot.monkeypatches import bug4520
- bug4520.patch()
-
-def patch_bug5079():
- # this bug is patched in Twisted-12.0.0; it was probably
- # present in Twisted-8.x.0, but the patch doesn't work
- if (twisted.version < versions.Version('twisted', 12, 0, 0) and
- twisted.version >= versions.Version('twisted', 9, 0, 0)):
- from buildbot.monkeypatches import bug5079
- bug5079.patch()
-
-def patch_sqlalchemy2364():
- # fix for SQLAlchemy bug 2364
- if sautils.sa_version() < (0,7,5):
- from buildbot.monkeypatches import sqlalchemy2364
- sqlalchemy2364.patch()
-
-def patch_sqlalchemy2189():
- # fix for SQLAlchemy bug 2189
- if sautils.sa_version() <= (0,7,1):
- from buildbot.monkeypatches import sqlalchemy2189
- sqlalchemy2189.patch()
-
-def patch_gatherResults():
- if twisted.version < versions.Version('twisted', 11, 1, 0):
- from buildbot.monkeypatches import gatherResults
- gatherResults.patch()
-
-
-def patch_all(for_tests=False):
- patch_bug4881()
- patch_bug4520()
- patch_bug5079()
- patch_sqlalchemy2364()
- patch_sqlalchemy2189()
- patch_gatherResults()
-
- if for_tests:
- from buildbot.monkeypatches import servicechecks
- servicechecks.patch_servicechecks()
- from buildbot.monkeypatches import testcase_patch
- testcase_patch.patch_testcase_patch()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py
deleted file mode 100644
index ffb891eb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# coding=utf-8
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.spread import pb
-from twisted.python import log
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/4520")
- pb.RemoteError = RemoteError
- pb.CopiedFailure.throwExceptionIntoGenerator = \
- CopiedFailure_throwExceptionIntoGenerator
- old_getStateToCopy = pb.CopyableFailure.getStateToCopy
- def getStateToCopy(self):
- state = old_getStateToCopy(self)
- state['value'] = str(self.value) # Exception instance
- return state
-
-
-#############################################################################
-# Everything below this line was taken from Twisted, except as annotated. See
-# http://twistedmatrix.com/trac/changeset/32211
-#
-# Merge copiedfailure-stringexc-4520
-#
-# Author: sirgolan, Koblaid, glyph
-# Reviewer: exarkun, glyph
-# Fixes: #4520
-#
-# Allow inlineCallbacks and exceptions raised from a twisted.spread remote
-# call to work together. A new RemoteError exception will be raised into
-# the generator when a yielded Deferred fails with a remote PB failure.
-
-class RemoteError(Exception):
- def __init__(self, remoteType, value, remoteTraceback):
- Exception.__init__(self, value)
- self.remoteType = remoteType
- self.remoteTraceback = remoteTraceback
-
-def CopiedFailure_throwExceptionIntoGenerator(self, g):
- return g.throw(RemoteError(self.type, self.value, self.traceback))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py
deleted file mode 100644
index aaa4bba3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# coding=utf-8
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from twisted.internet import process
-from twisted.python import log
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/4881")
- process._listOpenFDs = _listOpenFDs
-
-#############################################################################
-# Everything below this line was taken verbatim from Twisted, except as
-# annotated.
-
-########
-# r31474:trunk/LICENSE
-
-# Copyright (c) 2001-2010
-# Allen Short
-# Andy Gayton
-# Andrew Bennetts
-# Antoine Pitrou
-# Apple Computer, Inc.
-# Benjamin Bruheim
-# Bob Ippolito
-# Canonical Limited
-# Christopher Armstrong
-# David Reid
-# Donovan Preston
-# Eric Mangold
-# Eyal Lotem
-# Itamar Shtull-Trauring
-# James Knight
-# Jason A. Mobarak
-# Jean-Paul Calderone
-# Jessica McKellar
-# Jonathan Jacobs
-# Jonathan Lange
-# Jonathan D. Simms
-# Jürgen Hermann
-# Kevin Horn
-# Kevin Turner
-# Mary Gardiner
-# Matthew Lefkowitz
-# Massachusetts Institute of Technology
-# Moshe Zadka
-# Paul Swartz
-# Pavel Pergamenshchik
-# Ralph Meijer
-# Sean Riley
-# Software Freedom Conservancy
-# Travis B. Hartwell
-# Thijs Triemstra
-# Thomas Herve
-# Timothy Allen
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-########
-# r31474:trunk/twisted/internet/process.py
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-class _FDDetector(object):
- """
- This class contains the logic necessary to decide which of the available
- system techniques should be used to detect the open file descriptors for
- the current process. The chosen technique gets monkey-patched into the
- _listOpenFDs method of this class so that the detection only needs to occur
- once.
-
- @ivars listdir: The implementation of listdir to use. This gets overwritten
- by the test cases.
- @ivars getpid: The implementation of getpid to use, returns the PID of the
- running process.
- @ivars openfile: The implementation of open() to use, by default the Python
- builtin.
- """
- # So that we can unit test this
- listdir = os.listdir
- getpid = os.getpid
- openfile = open
-
-
- def _listOpenFDs(self):
- """
- Figure out which implementation to use, then run it.
- """
- self._listOpenFDs = self._getImplementation()
- return self._listOpenFDs()
-
-
- def _getImplementation(self):
- """
- Check if /dev/fd works, if so, use that. Otherwise, check if
- /proc/%d/fd exists, if so use that.
-
- Otherwise, ask resource.getrlimit, if that throws an exception, then
- fallback to _fallbackFDImplementation.
- """
- try:
- self.listdir("/dev/fd")
- if self._checkDevFDSanity(): # FreeBSD support :-)
- return self._devFDImplementation
- else:
- return self._fallbackFDImplementation
- except:
- try:
- self.listdir("/proc/%d/fd" % (self.getpid(),))
- return self._procFDImplementation
- except:
- try:
- self._resourceFDImplementation() # Imports resource
- return self._resourceFDImplementation
- except:
- return self._fallbackFDImplementation
-
-
- def _checkDevFDSanity(self):
- """
- Returns true iff opening a file modifies the fds visible
- in /dev/fd, as it should on a sane platform.
- """
- start = self.listdir("/dev/fd")
- self.openfile("/dev/null", "r") # changed in Buildbot to hush pyflakes
- end = self.listdir("/dev/fd")
- return start != end
-
-
- def _devFDImplementation(self):
- """
- Simple implementation for systems where /dev/fd actually works.
- See: http://www.freebsd.org/cgi/man.cgi?fdescfs
- """
- dname = "/dev/fd"
- result = [int(fd) for fd in os.listdir(dname)]
- return result
-
-
- def _procFDImplementation(self):
- """
- Simple implementation for systems where /proc/pid/fd exists (we assume
- it works).
- """
- dname = "/proc/%d/fd" % (os.getpid(),)
- return [int(fd) for fd in os.listdir(dname)]
-
-
- def _resourceFDImplementation(self):
- """
- Fallback implementation where the resource module can inform us about
- how many FDs we can expect.
-
- Note that on OS-X we expect to be using the /dev/fd implementation.
- """
- import resource
- maxfds = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + 1
- # OS-X reports 9223372036854775808. That's a lot of fds
- # to close
- if maxfds > 1024:
- maxfds = 1024
- return xrange(maxfds)
-
-
- def _fallbackFDImplementation(self):
- """
- Fallback-fallback implementation where we just assume that we need to
- close 256 FDs.
- """
- maxfds = 256
- return xrange(maxfds)
-
-
-detector = _FDDetector()
-
-def _listOpenFDs():
- """
- Use the global detector object to figure out which FD implementation to
- use.
- """
- return detector._listOpenFDs()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py
deleted file mode 100644
index 30202323..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.spread import pb
-from twisted.python import log
-from twisted.spread.interfaces import IJellyable
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/5079")
- if not hasattr(pb, '_JellyableAvatarMixin'):
- log.msg("..patch not applicable; please file a bug at buildbot.net")
- else:
- pb._JellyableAvatarMixin._cbLogin = _fixed_cbLogin
-
-def _fixed_cbLogin(self, (interface, avatar, logout)):
- """
- Ensure that the avatar to be returned to the client is jellyable and
- set up disconnection notification to call the realm's logout object.
- """
- if not IJellyable.providedBy(avatar):
- avatar = pb.AsReferenceable(avatar, "perspective")
-
- puid = avatar.processUniqueID()
-
- # only call logout once, whether the connection is dropped (disconnect)
- # or a logout occurs (cleanup), and be careful to drop the reference to
- # it in either case
- logout = [ logout ]
- def maybeLogout():
- if not logout: return
- fn = logout[0]
- del logout[0]
- fn()
- self.broker._localCleanup[puid] = maybeLogout
- self.broker.notifyOnDisconnect(maybeLogout)
-
- return avatar
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py
deleted file mode 100644
index 492f97ba..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-
-def patch():
- """
- Patch gatherResults to support consumeErrors on old versions of twisted
- """
- defer.gatherResults = gatherResults
-
-#############################################################################
-# Everything below this line was taken from Twisted, except as annotated. See
-# https://twistedmatrix.com/trac/browser/trunk/twisted/internet/defer.py?rev=32405#L805
-#
-# Merge gatherresults-consumeerrors-5159
-#
-# Author: dustin
-# Reviewer: exarkun
-# Fixes: #5159
-#
-# Add a `consumeErrors` parameter to `twisted.internet.defer.gatherResults`
-# with the same meaning as the parameter of the same name accepted by
-# `DeferredList`.
-
-
-
-def _parseDListResult(l, fireOnOneErrback=False):
- if __debug__:
- for success, value in l:
- assert success
- return [x[1] for x in l]
-
-def gatherResults(deferredList, consumeErrors=False):
- """
- Returns, via a L{Deferred}, a list with the results of the given
- L{Deferred}s - in effect, a "join" of multiple deferred operations.
-
- The returned L{Deferred} will fire when I{all} of the provided L{Deferred}s
- have fired, or when any one of them has failed.
-
- This differs from L{DeferredList} in that you don't need to parse
- the result for success/failure.
-
- @type deferredList: C{list} of L{Deferred}s
-
- @param consumeErrors: (keyword param) a flag, defaulting to False,
- indicating that failures in any of the given L{Deferreds} should not be
- propagated to errbacks added to the individual L{Deferreds} after this
- L{gatherResults} invocation. Any such errors in the individual
- L{Deferred}s will be converted to a callback result of C{None}. This
- is useful to prevent spurious 'Unhandled error in Deferred' messages
- from being logged. This parameter is available since 11.1.0.
- @type consumeErrors: C{bool}
- """
- d = defer.DeferredList(deferredList, fireOnOneErrback=True,
- consumeErrors=consumeErrors)
- d.addCallback(_parseDListResult)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py
deleted file mode 100644
index 46ac7bc2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-def patch_servicechecks():
- """
- Patch startService and stopService so that they check the previous state
- first.
-
- (used for debugging only)
- """
- from twisted.application.service import Service
- old_startService = Service.startService
- old_stopService = Service.stopService
- def startService(self):
- assert not self.running
- return old_startService(self)
- def stopService(self):
- assert self.running
- return old_stopService(self)
- Service.startService = startService
- Service.stopService = stopService
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py
deleted file mode 100644
index eda357ed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-from buildbot.util import sautils
-from sqlalchemy.engine import reflection
-from sqlalchemy.dialects.sqlite.base import SQLiteDialect, _pragma_cursor
-from sqlalchemy.dialects.sqlite.base import sqltypes, util
-
-@reflection.cache
-def get_columns_06x_fixed(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%stable_info(%s)" % (pragma, qtable)))
- #### found_table = False (pyflake)
- columns = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- (name, type_, nullable, default, has_default, primary_key) = (row[1], row[2].upper(), not row[3], row[4], row[4] is not None, row[5])
- name = re.sub(r'^\"|\"$', '', name)
- #### if default:
- #### default = re.sub(r"^\'|\'$", '', default)
- match = re.match(r'(\w+)(\(.*?\))?', type_)
- if match:
- coltype = match.group(1)
- args = match.group(2)
- else:
- coltype = "VARCHAR"
- args = ''
- try:
- coltype = self.ischema_names[coltype]
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, name))
- coltype = sqltypes.NullType
- if args is not None:
- args = re.findall(r'(\d+)', args)
- coltype = coltype(*[int(a) for a in args])
-
- columns.append({
- 'name' : name,
- 'type' : coltype,
- 'nullable' : nullable,
- 'default' : default,
- 'primary_key': primary_key
- })
- return columns
-
-
-@reflection.cache
-def get_columns_07x_fixed(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%stable_info(%s)" % (pragma, qtable)))
- #### found_table = False (pyflake)
- columns = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- (name, type_, nullable, default, has_default, primary_key) = (row[1], row[2].upper(), not row[3], row[4], row[4] is not None, row[5])
- name = re.sub(r'^\"|\"$', '', name)
- #### if default:
- #### default = re.sub(r"^\'|\'$", '', default)
- match = re.match(r'(\w+)(\(.*?\))?', type_)
- if match:
- coltype = match.group(1)
- args = match.group(2)
- else:
- coltype = "VARCHAR"
- args = ''
- try:
- coltype = self.ischema_names[coltype]
- if args is not None:
- args = re.findall(r'(\d+)', args)
- coltype = coltype(*[int(a) for a in args])
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, name))
- coltype = sqltypes.NullType()
-
- columns.append({
- 'name' : name,
- 'type' : coltype,
- 'nullable' : nullable,
- 'default' : default,
- 'autoincrement':default is None,
- 'primary_key': primary_key
- })
- return columns
-
-def patch():
- # fix for http://www.sqlalchemy.org/trac/ticket/2189, backported to 0.6.0
- if sautils.sa_version()[:2] == (0, 6):
- get_columns_fixed = get_columns_06x_fixed
- else:
- get_columns_fixed = get_columns_07x_fixed
- SQLiteDialect.get_columns = get_columns_fixed
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py
deleted file mode 100644
index 5720d31a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-def patch():
- # a fix for http://www.sqlalchemy.org/trac/ticket/2364
- from sqlalchemy.dialects.sqlite.base import SQLiteDialect
- old_get_foreign_keys = SQLiteDialect.get_foreign_keys
- def get_foreign_keys_wrapper(*args, **kwargs):
- fkeys = old_get_foreign_keys(*args, **kwargs)
- # foreign keys don't have names
- for fkey in fkeys:
- fkey['name'] = None
- return fkeys
- SQLiteDialect.get_foreign_keys = get_foreign_keys_wrapper
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py
deleted file mode 100644
index f626f4f7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import twisted
-from twisted.trial import unittest
-
-def patch_testcase_patch():
- """
- Patch out TestCase.patch to skip the test on version combinations where it
- does not work.
-
- (used for debugging only)
- """
- # Twisted-9.0.0 and earlier did not have a UnitTest.patch that worked on
- # Python-2.7
- if twisted.version.major <= 9 and sys.version_info[:2] == (2,7):
- def nopatch(self, *args):
- raise unittest.SkipTest('unittest.TestCase.patch is not available')
- unittest.TestCase.patch = nopatch
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py
deleted file mode 100644
index d499c112..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.spread import pb
-from twisted.python import failure, log
-from twisted.internet import defer
-from twisted.cred import portal, checkers, credentials, error
-from twisted.application import service, strports
-
-debug = False
-
-class PBManager(service.MultiService):
- """
- A centralized manager for PB ports and authentication on them.
-
- Allows various pieces of code to request a (port, username) combo, along
- with a password and a perspective factory.
- """
- def __init__(self):
- service.MultiService.__init__(self)
- self.setName('pbmanager')
- self.dispatchers = {}
-
- def register(self, portstr, username, password, pfactory):
- """
- Register a perspective factory PFACTORY to be executed when a PB
- connection arrives on PORTSTR with USERNAME/PASSWORD. Returns a
- Registration object which can be used to unregister later.
- """
- # do some basic normalization of portstrs
- if type(portstr) == type(0) or ':' not in portstr:
- portstr = "tcp:%s" % portstr
-
- reg = Registration(self, portstr, username)
-
- if portstr not in self.dispatchers:
- disp = self.dispatchers[portstr] = Dispatcher(portstr)
- disp.setServiceParent(self)
- else:
- disp = self.dispatchers[portstr]
-
- disp.register(username, password, pfactory)
-
- return reg
-
- def _unregister(self, registration):
- disp = self.dispatchers[registration.portstr]
- disp.unregister(registration.username)
- registration.username = None
- if not disp.users:
- disp = self.dispatchers[registration.portstr]
- del self.dispatchers[registration.portstr]
- return disp.disownServiceParent()
- return defer.succeed(None)
-
-class Registration(object):
- def __init__(self, pbmanager, portstr, username):
- self.portstr = portstr
- "portstr this registration is active on"
- self.username = username
- "username of this registration"
-
- self.pbmanager = pbmanager
-
- def __repr__(self):
- return "<pbmanager.Registration for %s on %s>" % \
- (self.username, self.portstr)
-
- def unregister(self):
- """
- Unregister this registration, removing the username from the port, and
- closing the port if there are no more users left. Returns a Deferred.
- """
- return self.pbmanager._unregister(self)
-
- def getPort(self):
- """
- Helper method for testing; returns the TCP port used for this
- registration, even if it was specified as 0 and thus allocated by the
- OS.
- """
- disp = self.pbmanager.dispatchers[self.portstr]
- return disp.port.getHost().port
-
-
-class Dispatcher(service.Service):
- implements(portal.IRealm, checkers.ICredentialsChecker)
-
- credentialInterfaces = [ credentials.IUsernamePassword,
- credentials.IUsernameHashedPassword ]
-
- def __init__(self, portstr):
- self.portstr = portstr
- self.users = {}
-
- # there's lots of stuff to set up for a PB connection!
- self.portal = portal.Portal(self)
- self.portal.registerChecker(self)
- self.serverFactory = pb.PBServerFactory(self.portal)
- self.serverFactory.unsafeTracebacks = True
- self.port = strports.listen(portstr, self.serverFactory)
-
- def __repr__(self):
- return "<pbmanager.Dispatcher for %s on %s>" % \
- (", ".join(self.users.keys()), self.portstr)
-
- def stopService(self):
- # stop listening on the port when shut down
- d = defer.maybeDeferred(self.port.stopListening)
- d.addCallback(lambda _ : service.Service.stopService(self))
- return d
-
- def register(self, username, password, pfactory):
- if debug:
- log.msg("registering username '%s' on pb port %s: %s"
- % (username, self.portstr, pfactory))
- if username in self.users:
- raise KeyError, ("username '%s' is already registered on PB port %s"
- % (username, self.portstr))
- self.users[username] = (password, pfactory)
-
- def unregister(self, username):
- if debug:
- log.msg("unregistering username '%s' on pb port %s"
- % (username, self.portstr))
- del self.users[username]
-
- # IRealm
-
- def requestAvatar(self, username, mind, interface):
- assert interface == pb.IPerspective
- if username not in self.users:
- d = defer.succeed(None) # no perspective
- else:
- _, afactory = self.users.get(username)
- d = defer.maybeDeferred(afactory, mind, username)
-
- # check that we got a perspective
- def check(persp):
- if not persp:
- raise ValueError("no perspective for '%s'" % username)
- return persp
- d.addCallback(check)
-
- # call the perspective's attached(mind)
- def call_attached(persp):
- d = defer.maybeDeferred(persp.attached, mind)
- d.addCallback(lambda _ : persp) # keep returning the perspective
- return d
- d.addCallback(call_attached)
-
- # return the tuple requestAvatar is expected to return
- def done(persp):
- return (pb.IPerspective, persp, lambda: persp.detached(mind))
- d.addCallback(done)
-
- return d
-
- # ICredentialsChecker
-
- def requestAvatarId(self, creds):
- if creds.username in self.users:
- password, _ = self.users[creds.username]
- d = defer.maybeDeferred(creds.checkPassword, password)
- def check(matched):
- if not matched:
- log.msg("invalid login from user '%s'" % creds.username)
- return failure.Failure(error.UnauthorizedLogin())
- return creds.username
- d.addCallback(check)
- return d
- else:
- log.msg("invalid login from unknown user '%s'" % creds.username)
- return defer.fail(error.UnauthorizedLogin())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py
deleted file mode 100644
index b1ef76d4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-"""Base classes handy for use with PB clients.
-"""
-
-from twisted.spread import pb
-
-from twisted.spread.pb import PBClientFactory
-from twisted.internet import protocol
-from twisted.python import log
-
-class NewCredPerspective(pb.Avatar):
- def attached(self, mind):
- return self
- def detached(self, mind):
- pass
-
-class ReconnectingPBClientFactory(PBClientFactory,
- protocol.ReconnectingClientFactory):
- """Reconnecting client factory for PB brokers.
-
- Like PBClientFactory, but if the connection fails or is lost, the factory
- will attempt to reconnect.
-
- Instead of using f.getRootObject (which gives a Deferred that can only
- be fired once), override the gotRootObject method.
-
- Instead of using the newcred f.login (which is also one-shot), call
- f.startLogin() with the credentials and client, and override the
- gotPerspective method.
-
- Instead of using the oldcred f.getPerspective (also one-shot), call
- f.startGettingPerspective() with the same arguments, and override
- gotPerspective.
-
- gotRootObject and gotPerspective will be called each time the object is
- received (once per successful connection attempt). You will probably want
- to use obj.notifyOnDisconnect to find out when the connection is lost.
-
- If an authorization error occurs, failedToGetPerspective() will be
- invoked.
-
- To use me, subclass, then hand an instance to a connector (like
- TCPClient).
- """
-
- def __init__(self):
- PBClientFactory.__init__(self)
- self._doingLogin = False
- self._doingGetPerspective = False
-
- def clientConnectionFailed(self, connector, reason):
- PBClientFactory.clientConnectionFailed(self, connector, reason)
- # Twisted-1.3 erroneously abandons the connection on non-UserErrors.
- # To avoid this bug, don't upcall, and implement the correct version
- # of the method here.
- if self.continueTrying:
- self.connector = connector
- self.retry()
-
- def clientConnectionLost(self, connector, reason):
- PBClientFactory.clientConnectionLost(self, connector, reason,
- reconnecting=True)
- RCF = protocol.ReconnectingClientFactory
- RCF.clientConnectionLost(self, connector, reason)
-
- def clientConnectionMade(self, broker):
- self.resetDelay()
- PBClientFactory.clientConnectionMade(self, broker)
- if self._doingLogin:
- self.doLogin(self._root)
- if self._doingGetPerspective:
- self.doGetPerspective(self._root)
- self.gotRootObject(self._root)
-
- # oldcred methods
-
- def getPerspective(self, *args):
- raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead"
-
- def startGettingPerspective(self, username, password, serviceName,
- perspectiveName=None, client=None):
- self._doingGetPerspective = True
- if perspectiveName == None:
- perspectiveName = username
- self._oldcredArgs = (username, password, serviceName,
- perspectiveName, client)
-
- def doGetPerspective(self, root):
- # oldcred getPerspective()
- (username, password,
- serviceName, perspectiveName, client) = self._oldcredArgs
- d = self._cbAuthIdentity(root, username, password)
- d.addCallback(self._cbGetPerspective,
- serviceName, perspectiveName, client)
- d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
-
-
- # newcred methods
-
- def login(self, *args):
- raise RuntimeError, "login is one-shot: use startLogin instead"
-
- def startLogin(self, credentials, client=None):
- self._credentials = credentials
- self._client = client
- self._doingLogin = True
-
- def doLogin(self, root):
- # newcred login()
- d = self._cbSendUsername(root, self._credentials.username,
- self._credentials.password, self._client)
- d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
-
-
- # methods to override
-
- def gotPerspective(self, perspective):
- """The remote avatar or perspective (obtained each time this factory
- connects) is now available."""
- pass
-
- def gotRootObject(self, root):
- """The remote root object (obtained each time this factory connects)
- is now available. This method will be called each time the connection
- is established and the object reference is retrieved."""
- pass
-
- def failedToGetPerspective(self, why):
- """The login process failed, most likely because of an authorization
- failure (bad password), but it is also possible that we lost the new
- connection before we managed to send our credentials.
- """
- log.msg("ReconnectingPBClientFactory.failedToGetPerspective")
- if why.check(pb.PBConnectionLost):
- log.msg("we lost the brand-new connection")
- # retrying might help here, let clientConnectionLost decide
- return
- # probably authorization
- self.stopTrying() # logging in harder won't help
- log.err(why)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py
deleted file mode 100644
index 6735e932..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.process.build import Build
-_hush_pyflakes = [ Build ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py
deleted file mode 100644
index f2c3b9fe..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py
+++ /dev/null
@@ -1,492 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.python import log, reflect
-from twisted.python.failure import Failure
-from twisted.internet import defer, reactor
-from twisted.spread import pb
-from twisted.application import service
-
-from buildbot.process.builder import Builder
-from buildbot import interfaces, locks, config, util
-from buildbot.process import metrics
-from buildbot.process.buildrequestdistributor import BuildRequestDistributor
-
-class BotMaster(config.ReconfigurableServiceMixin, service.MultiService):
-
- """This is the master-side service which manages remote buildbot slaves.
- It provides them with BuildSlaves, and distributes build requests to
- them."""
-
- debug = 0
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName("botmaster")
- self.master = master
-
- self.builders = {}
- self.builderNames = []
- # builders maps Builder names to instances of bb.p.builder.Builder,
- # which is the master-side object that defines and controls a build.
-
- # self.slaves contains a ready BuildSlave instance for each
- # potential buildslave, i.e. all the ones listed in the config file.
- # If the slave is connected, self.slaves[slavename].slave will
- # contain a RemoteReference to their Bot instance. If it is not
- # connected, that attribute will hold None.
- self.slaves = {} # maps slavename to BuildSlave
- self.watchers = {}
-
- # self.locks holds the real Lock instances
- self.locks = {}
-
- # self.mergeRequests is the callable override for merging build
- # requests
- self.mergeRequests = None
-
- self.shuttingDown = False
-
- self.lastSlavePortnum = None
-
- # subscription to new build requests
- self.buildrequest_sub = None
-
- # a distributor for incoming build requests; see below
- self.brd = BuildRequestDistributor(self)
- self.brd.setServiceParent(self)
-
- def cleanShutdown(self, _reactor=reactor):
- """Shut down the entire process, once all currently-running builds are
- complete."""
- if self.shuttingDown:
- return
- log.msg("Initiating clean shutdown")
- self.shuttingDown = True
-
- # first, stop the distributor; this will finish any ongoing scheduling
- # operations before firing
- d = self.brd.stopService()
-
- # then wait for all builds to finish
- def wait(_):
- l = []
- for builder in self.builders.values():
- for build in builder.builder_status.getCurrentBuilds():
- l.append(build.waitUntilFinished())
- if len(l) == 0:
- log.msg("No running jobs, starting shutdown immediately")
- else:
- log.msg("Waiting for %i build(s) to finish" % len(l))
- return defer.DeferredList(l)
- d.addCallback(wait)
-
- # Finally, shut the whole process down
- def shutdown(ign):
- # Double check that we're still supposed to be shutting down
- # The shutdown may have been cancelled!
- if self.shuttingDown:
- # Check that there really aren't any running builds
- for builder in self.builders.values():
- n = len(builder.builder_status.getCurrentBuilds())
- if n > 0:
- log.msg("Not shutting down, builder %s has %i builds running" % (builder, n))
- log.msg("Trying shutdown sequence again")
- self.shuttingDown = False
- self.cleanShutdown()
- return
- log.msg("Stopping reactor")
- _reactor.stop()
- else:
- self.brd.startService()
- d.addCallback(shutdown)
- d.addErrback(log.err, 'while processing cleanShutdown')
-
- def cancelCleanShutdown(self):
- """Cancel a clean shutdown that is already in progress, if any"""
- if not self.shuttingDown:
- return
- log.msg("Cancelling clean shutdown")
- self.shuttingDown = False
-
- @metrics.countMethod('BotMaster.slaveLost()')
- def slaveLost(self, bot):
- metrics.MetricCountEvent.log("BotMaster.attached_slaves", -1)
- for name, b in self.builders.items():
- if bot.slavename in b.config.slavenames:
- b.detached(bot)
-
- @metrics.countMethod('BotMaster.getBuildersForSlave()')
- def getBuildersForSlave(self, slavename):
- return [ b for b in self.builders.values()
- if slavename in b.config.slavenames ]
-
- def getBuildernames(self):
- return self.builderNames
-
- def getBuilders(self):
- return self.builders.values()
-
- def startService(self):
- def buildRequestAdded(notif):
- self.maybeStartBuildsForBuilder(notif['buildername'])
- self.buildrequest_sub = \
- self.master.subscribeToBuildRequests(buildRequestAdded)
- service.MultiService.startService(self)
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- timer = metrics.Timer("BotMaster.reconfigService")
- timer.start()
-
- # reconfigure slaves
- yield self.reconfigServiceSlaves(new_config)
-
- # reconfigure builders
- yield self.reconfigServiceBuilders(new_config)
-
- # call up
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- # try to start a build for every builder; this is necessary at master
- # startup, and a good idea in any other case
- self.maybeStartBuildsForAllBuilders()
-
- timer.stop()
-
-
- @defer.inlineCallbacks
- def reconfigServiceSlaves(self, new_config):
-
- timer = metrics.Timer("BotMaster.reconfigServiceSlaves")
- timer.start()
-
- # arrange slaves by name
- old_by_name = dict([ (s.slavename, s)
- for s in list(self)
- if interfaces.IBuildSlave.providedBy(s) ])
- old_set = set(old_by_name.iterkeys())
- new_by_name = dict([ (s.slavename, s)
- for s in new_config.slaves ])
- new_set = set(new_by_name.iterkeys())
-
- # calculate new slaves, by name, and removed slaves
- removed_names, added_names = util.diffSets(old_set, new_set)
-
- # find any slaves for which the fully qualified class name has
- # changed, and treat those as an add and remove
- for n in old_set & new_set:
- old = old_by_name[n]
- new = new_by_name[n]
- # detect changed class name
- if reflect.qual(old.__class__) != reflect.qual(new.__class__):
- removed_names.add(n)
- added_names.add(n)
-
- if removed_names or added_names:
- log.msg("adding %d new slaves, removing %d" %
- (len(added_names), len(removed_names)))
-
- for n in removed_names:
- slave = old_by_name[n]
-
- del self.slaves[n]
- slave.master = None
- slave.botmaster = None
-
- yield defer.maybeDeferred(lambda :
- slave.disownServiceParent())
-
- for n in added_names:
- slave = new_by_name[n]
- slave.setServiceParent(self)
- self.slaves[n] = slave
-
- metrics.MetricCountEvent.log("num_slaves",
- len(self.slaves), absolute=True)
-
- timer.stop()
-
-
- @defer.inlineCallbacks
- def reconfigServiceBuilders(self, new_config):
-
- timer = metrics.Timer("BotMaster.reconfigServiceBuilders")
- timer.start()
-
- # arrange builders by name
- old_by_name = dict([ (b.name, b)
- for b in list(self)
- if isinstance(b, Builder) ])
- old_set = set(old_by_name.iterkeys())
- new_by_name = dict([ (bc.name, bc)
- for bc in new_config.builders ])
- new_set = set(new_by_name.iterkeys())
-
- # calculate new builders, by name, and removed builders
- removed_names, added_names = util.diffSets(old_set, new_set)
-
- if removed_names or added_names:
- log.msg("adding %d new builders, removing %d" %
- (len(added_names), len(removed_names)))
-
- for n in removed_names:
- builder = old_by_name[n]
-
- del self.builders[n]
- builder.master = None
- builder.botmaster = None
-
- yield defer.maybeDeferred(lambda :
- builder.disownServiceParent())
-
- for n in added_names:
- builder = Builder(n)
- self.builders[n] = builder
-
- builder.botmaster = self
- builder.master = self.master
- builder.setServiceParent(self)
-
- # Use order according to configuration files builders list
- self.builderNames = list([ (bc.name) for bc in new_config.builders ])
-
- metrics.MetricCountEvent.log("num_builders",
- len(self.builders), absolute=True)
-
- timer.stop()
-
-
- def stopService(self):
- if self.buildrequest_sub:
- self.buildrequest_sub.unsubscribe()
- self.buildrequest_sub = None
- for b in self.builders.values():
- b.builder_status.addPointEvent(["master", "shutdown"])
- b.builder_status.saveYourself()
- return service.MultiService.stopService(self)
-
- def getLockByID(self, lockid):
- """Convert a Lock identifier into an actual Lock instance.
- @param lockid: a locks.MasterLock or locks.SlaveLock instance
- @return: a locks.RealMasterLock or locks.RealSlaveLock instance
- """
- assert isinstance(lockid, (locks.MasterLock, locks.SlaveLock))
- if not lockid in self.locks:
- self.locks[lockid] = lockid.lockClass(lockid)
- # if the master.cfg file has changed maxCount= on the lock, the next
- # time a build is started, they'll get a new RealLock instance. Note
- # that this requires that MasterLock and SlaveLock (marker) instances
- # be hashable and that they should compare properly.
- return self.locks[lockid]
-
- def getLockFromLockAccess(self, access):
- # Convert a lock-access object into an actual Lock instance.
- if not isinstance(access, locks.LockAccess):
- # Buildbot 0.7.7 compability: user did not specify access
- access = access.defaultAccess()
- lock = self.getLockByID(access.lockid)
- return lock
-
- def maybeStartBuildsForBuilder(self, buildername):
- """
- Call this when something suggests that a particular builder may now
- be available to start a build.
-
- @param buildername: the name of the builder
- """
- self.brd.maybeStartBuildsOn([buildername])
-
- def maybeStartBuildsForSlave(self, slave_name):
- """
- Call this when something suggests that a particular slave may now be
- available to start a build.
-
- @param slave_name: the name of the slave
- """
- builders = self.getBuildersForSlave(slave_name)
- self.brd.maybeStartBuildsOn([ b.name for b in builders ])
-
- def maybeStartBuildsForAllBuilders(self):
- """
- Call this when something suggests that this would be a good time to
- start some builds, but nothing more specific.
- """
- self.brd.maybeStartBuildsOn(self.builderNames)
-
-
-class DuplicateSlaveArbitrator(object):
- """Utility class to arbitrate the situation when a new slave connects with
- the name of an existing, connected slave
-
- @ivar buildslave: L{buildbot.process.slavebuilder.AbstractBuildSlave}
- instance
- @ivar old_remote: L{RemoteReference} to the old slave
- @ivar new_remote: L{RemoteReference} to the new slave
- """
- _reactor = reactor # for testing
-
- # There are several likely duplicate slave scenarios in practice:
- #
- # 1. two slaves are configured with the same username/password
- #
- # 2. the same slave process believes it is disconnected (due to a network
- # hiccup), and is trying to reconnect
- #
- # For the first case, we want to prevent the two slaves from repeatedly
- # superseding one another (which results in lots of failed builds), so we
- # will prefer the old slave. However, for the second case we need to
- # detect situations where the old slave is "gone". Sometimes "gone" means
- # that the TCP/IP connection to it is in a long timeout period (10-20m,
- # depending on the OS configuration), so this can take a while.
-
- PING_TIMEOUT = 10
- """Timeout for pinging the old slave. Set this to something quite long, as
- a very busy slave (e.g., one sending a big log chunk) may take a while to
- return a ping.
- """
-
- def __init__(self, buildslave):
- self.buildslave = buildslave
- self.old_remote = self.buildslave.slave
-
- def getPerspective(self, mind, slavename):
- self.new_remote = mind
- self.ping_old_slave_done = False
- self.old_slave_connected = True
- self.ping_new_slave_done = False
-
- old_tport = self.old_remote.broker.transport
- new_tport = self.new_remote.broker.transport
- log.msg("duplicate slave %s; delaying new slave (%s) and pinging old "
- "(%s)" % (self.buildslave.slavename, new_tport.getPeer(),
- old_tport.getPeer()))
-
- # delay the new slave until we decide what to do with it
- d = self.new_slave_d = defer.Deferred()
-
- # Ping the old slave. If this kills it, then we can allow the new
- # slave to connect. If this does not kill it, then we disconnect
- # the new slave.
- self.ping_old_slave(new_tport.getPeer())
-
- # Print a message on the new slave, if possible.
- self.ping_new_slave()
-
- return d
-
- def ping_new_slave(self):
- d = defer.maybeDeferred(lambda :
- self.new_remote.callRemote("print", "master already has a "
- "connection named '%s' - checking its liveness"
- % self.buildslave.slavename))
- def done(_):
- # failure or success, doesn't matter - the ping is done.
- self.ping_new_slave_done = True
- self.maybe_done()
- d.addBoth(done)
-
- def ping_old_slave(self, new_peer):
- # set a timer on this ping, in case the network is bad. TODO: a
- # timeout on the ping itself is not quite what we want. If there is
- # other data flowing over the PB connection, then we should keep
- # waiting. Bug #1703
- def timeout():
- self.ping_old_slave_timeout = None
- self.ping_old_slave_timed_out = True
- self.old_slave_connected = False
- self.ping_old_slave_done = True
- self.maybe_done()
- self.ping_old_slave_timeout = self._reactor.callLater(
- self.PING_TIMEOUT, timeout)
- self.ping_old_slave_timed_out = False
-
- # call this in maybeDeferred because callRemote tends to raise
- # exceptions instead of returning Failures
- d = defer.maybeDeferred(lambda :
- self.old_remote.callRemote("print",
- "master got a duplicate connection from %s; keeping this one"
- % new_peer))
-
- def clear_timeout(r):
- if self.ping_old_slave_timeout:
- self.ping_old_slave_timeout.cancel()
- self.ping_old_slave_timeout = None
- return r
- d.addBoth(clear_timeout)
-
- def old_gone(f):
- if self.ping_old_slave_timed_out:
- return # ignore after timeout
- f.trap(pb.PBConnectionLost, pb.DeadReferenceError)
- log.msg(("connection lost while pinging old slave '%s' - " +
- "keeping new slave") % self.buildslave.slavename)
- self.old_slave_connected = False
- d.addErrback(old_gone)
-
- def other_err(f):
- log.err(f, "unexpected error pinging old slave; disconnecting it")
- self.old_slave_connected = False
- d.addErrback(other_err)
-
- def done(_):
- if self.ping_old_slave_timed_out:
- return # ignore after timeout
- self.ping_old_slave_done = True
- self.maybe_done()
- d.addCallback(done)
-
- def maybe_done(self):
- if not self.ping_new_slave_done or not self.ping_old_slave_done:
- return
-
- # both pings are done, so sort out the results
- if self.old_slave_connected:
- self.disconnect_new_slave()
- else:
- self.start_new_slave()
-
- def start_new_slave(self):
- # just in case
- if not self.new_slave_d: # pragma: ignore
- return
-
- d = self.new_slave_d
- self.new_slave_d = None
-
- if self.buildslave.isConnected():
- # we need to wait until the old slave has fully detached, which can
- # take a little while as buffers drain, etc.
- def detached():
- d.callback(self.buildslave)
- self.buildslave.subscribeToDetach(detached)
- self.old_remote.broker.transport.loseConnection()
- else: # pragma: ignore
- # by some unusual timing, it's quite possible that the old slave
- # has disconnected while the arbitration was going on. In that
- # case, we're already done!
- d.callback(self.buildslave)
-
- def disconnect_new_slave(self):
- # just in case
- if not self.new_slave_d: # pragma: ignore
- return
-
- d = self.new_slave_d
- self.new_slave_d = None
- log.msg("rejecting duplicate slave with exception")
- d.errback(Failure(RuntimeError("rejecting duplicate slave")))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py
deleted file mode 100644
index e30d685c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import types
-
-from zope.interface import implements
-from twisted.python import log, components
-from twisted.python.failure import Failure
-from twisted.internet import defer, error
-
-from buildbot import interfaces
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION, \
- RETRY, SKIPPED, worst_status
-from buildbot.status.builder import Results
-from buildbot.status.progress import BuildProgress
-from buildbot.process import metrics, properties
-from buildbot.util.eventual import eventually
-
-
-class Build(properties.PropertiesMixin):
- """I represent a single build by a single slave. Specialized Builders can
- use subclasses of Build to hold status information unique to those build
- processes.
-
- I control B{how} the build proceeds. The actual build is broken up into a
- series of steps, saved in the .buildSteps[] array as a list of
- L{buildbot.process.step.BuildStep} objects. Each step is a single remote
- command, possibly a shell command.
-
- During the build, I put status information into my C{BuildStatus}
- gatherer.
-
- After the build, I go away.
-
- I can be used by a factory by setting buildClass on
- L{buildbot.process.factory.BuildFactory}
-
- @ivar requests: the list of L{BuildRequest}s that triggered me
- @ivar build_status: the L{buildbot.status.build.BuildStatus} that
- collects our status
- """
-
- implements(interfaces.IBuildControl)
-
- workdir = "build"
- build_status = None
- reason = "changes"
- finished = False
- results = None
- stopped = False
- set_runtime_properties = True
-
- def __init__(self, requests):
- self.requests = requests
- self.locks = []
- # build a source stamp
- self.sources = requests[0].mergeSourceStampsWith(requests[1:])
- self.reason = requests[0].mergeReasons(requests[1:])
-
- self.progress = None
- self.currentStep = None
- self.slaveEnvironment = {}
-
- self.terminate = False
-
- self._acquiringLock = None
-
- def setBuilder(self, builder):
- """
- Set the given builder as our builder.
-
- @type builder: L{buildbot.process.builder.Builder}
- """
- self.builder = builder
-
- def setLocks(self, lockList):
- # convert all locks into their real forms
- self.locks = [(self.builder.botmaster.getLockFromLockAccess(access), access)
- for access in lockList ]
-
- def setSlaveEnvironment(self, env):
- self.slaveEnvironment = env
-
- def getSourceStamp(self, codebase=''):
- for source in self.sources:
- if source.codebase == codebase:
- return source
- return None
-
- def getAllSourceStamps(self):
- return list(self.sources)
-
- def allChanges(self):
- for s in self.sources:
- for c in s.changes:
- yield c
-
- def allFiles(self):
- # return a list of all source files that were changed
- files = []
- for c in self.allChanges():
- for f in c.files:
- files.append(f)
- return files
-
- def __repr__(self):
- return "<Build %s>" % (self.builder.name,)
-
- def blamelist(self):
- blamelist = []
- for c in self.allChanges():
- if c.who not in blamelist:
- blamelist.append(c.who)
- for source in self.sources:
- if source.patch_info: #Add patch author to blamelist
- blamelist.append(source.patch_info[0])
- blamelist.sort()
- return blamelist
-
- def changesText(self):
- changetext = ""
- for c in self.allChanges():
- changetext += "-" * 60 + "\n\n" + c.asText() + "\n"
- # consider sorting these by number
- return changetext
-
- def setStepFactories(self, step_factories):
- """Set a list of 'step factories', which are tuples of (class,
- kwargs), where 'class' is generally a subclass of step.BuildStep .
- These are used to create the Steps themselves when the Build starts
- (as opposed to when it is first created). By creating the steps
- later, their __init__ method will have access to things like
- build.allFiles() ."""
- self.stepFactories = list(step_factories)
-
- useProgress = True
-
- def getSlaveCommandVersion(self, command, oldversion=None):
- return self.slavebuilder.getSlaveCommandVersion(command, oldversion)
- def getSlaveName(self):
- return self.slavebuilder.slave.slavename
-
- def setupProperties(self):
- props = interfaces.IProperties(self)
-
- # give the properties a reference back to this build
- props.build = self
-
- # start with global properties from the configuration
- master = self.builder.botmaster.master
- props.updateFromProperties(master.config.properties)
-
- # from the SourceStamps, which have properties via Change
- for change in self.allChanges():
- props.updateFromProperties(change.properties)
-
- # and finally, get any properties from requests (this is the path
- # through which schedulers will send us properties)
- for rq in self.requests:
- props.updateFromProperties(rq.properties)
-
- # now set some properties of our own, corresponding to the
- # build itself
- props.setProperty("buildnumber", self.build_status.number, "Build")
-
- if self.sources and len(self.sources) == 1:
- # old interface for backwards compatibility
- source = self.sources[0]
- props.setProperty("branch", source.branch, "Build")
- props.setProperty("revision", source.revision, "Build")
- props.setProperty("repository", source.repository, "Build")
- props.setProperty("codebase", source.codebase, "Build")
- props.setProperty("project", source.project, "Build")
-
- self.builder.setupProperties(props)
-
- def setupSlaveBuilder(self, slavebuilder):
- self.slavebuilder = slavebuilder
-
- self.path_module = slavebuilder.slave.path_module
-
- # navigate our way back to the L{buildbot.buildslave.BuildSlave}
- # object that came from the config, and get its properties
- buildslave_properties = slavebuilder.slave.properties
- self.getProperties().updateFromProperties(buildslave_properties)
- if slavebuilder.slave.slave_basedir:
- builddir = self.path_module.join(
- slavebuilder.slave.slave_basedir,
- self.builder.config.slavebuilddir)
- self.setProperty("builddir", builddir, "slave")
- self.setProperty("workdir", builddir, "slave (deprecated)")
-
- self.slavename = slavebuilder.slave.slavename
- self.build_status.setSlavename(self.slavename)
-
- def startBuild(self, build_status, expectations, slavebuilder):
- """This method sets up the build, then starts it by invoking the
- first Step. It returns a Deferred which will fire when the build
- finishes. This Deferred is guaranteed to never errback."""
-
- # we are taking responsibility for watching the connection to the
- # remote. This responsibility was held by the Builder until our
- # startBuild was called, and will not return to them until we fire
- # the Deferred returned by this method.
-
- log.msg("%s.startBuild" % self)
- self.build_status = build_status
- # now that we have a build_status, we can set properties
- self.setupProperties()
- self.setupSlaveBuilder(slavebuilder)
- slavebuilder.slave.updateSlaveStatus(buildStarted=build_status)
-
- # then narrow SlaveLocks down to the right slave
- self.locks = [(l.getLock(self.slavebuilder.slave), a)
- for l, a in self.locks ]
- self.remote = slavebuilder.remote
- self.remote.notifyOnDisconnect(self.lostRemote)
-
- metrics.MetricCountEvent.log('active_builds', 1)
-
- d = self.deferred = defer.Deferred()
- def _uncount_build(res):
- metrics.MetricCountEvent.log('active_builds', -1)
- return res
- d.addBoth(_uncount_build)
-
- def _release_slave(res, slave, bs):
- self.slavebuilder.buildFinished()
- slave.updateSlaveStatus(buildFinished=bs)
- return res
- d.addCallback(_release_slave, self.slavebuilder.slave, build_status)
-
- try:
- self.setupBuild(expectations) # create .steps
- except:
- # the build hasn't started yet, so log the exception as a point
- # event instead of flunking the build.
- # TODO: associate this failure with the build instead.
- # this involves doing
- # self.build_status.buildStarted() from within the exception
- # handler
- log.msg("Build.setupBuild failed")
- log.err(Failure())
- self.builder.builder_status.addPointEvent(["setupBuild",
- "exception"])
- self.finished = True
- self.results = EXCEPTION
- self.deferred = None
- d.callback(self)
- return d
-
- self.build_status.buildStarted(self)
- self.acquireLocks().addCallback(self._startBuild_2)
- return d
-
- @staticmethod
- def canStartWithSlavebuilder(lockList, slavebuilder):
- for lock, access in lockList:
- slave_lock = lock.getLock(slavebuilder.slave)
- if not slave_lock.isAvailable(None, access):
- return False
- return True
-
- def acquireLocks(self, res=None):
- self._acquiringLock = None
- if not self.locks:
- return defer.succeed(None)
- if self.stopped:
- return defer.succeed(None)
- log.msg("acquireLocks(build %s, locks %s)" % (self, self.locks))
- for lock, access in self.locks:
- if not lock.isAvailable(self, access):
- log.msg("Build %s waiting for lock %s" % (self, lock))
- d = lock.waitUntilMaybeAvailable(self, access)
- d.addCallback(self.acquireLocks)
- self._acquiringLock = (lock, access, d)
- return d
- # all locks are available, claim them all
- for lock, access in self.locks:
- lock.claim(self, access)
- return defer.succeed(None)
-
- def _startBuild_2(self, res):
- self.startNextStep()
-
- def setupBuild(self, expectations):
- # create the actual BuildSteps. If there are any name collisions, we
- # add a count to the loser until it is unique.
- self.steps = []
- self.stepStatuses = {}
- stepnames = {}
- sps = []
-
- for factory in self.stepFactories:
- step = factory.buildStep()
- step.setBuild(self)
- step.setBuildSlave(self.slavebuilder.slave)
- if callable (self.workdir):
- step.setDefaultWorkdir (self.workdir (self.sources))
- else:
- step.setDefaultWorkdir (self.workdir)
- name = step.name
- if stepnames.has_key(name):
- count = stepnames[name]
- count += 1
- stepnames[name] = count
- name = step.name + "_%d" % count
- else:
- stepnames[name] = 0
- step.name = name
- self.steps.append(step)
-
- # tell the BuildStatus about the step. This will create a
- # BuildStepStatus and bind it to the Step.
- step_status = self.build_status.addStepWithName(name)
- step.setStepStatus(step_status)
-
- sp = None
- if self.useProgress:
- # XXX: maybe bail if step.progressMetrics is empty? or skip
- # progress for that one step (i.e. "it is fast"), or have a
- # separate "variable" flag that makes us bail on progress
- # tracking
- sp = step.setupProgress()
- if sp:
- sps.append(sp)
-
- # Create a buildbot.status.progress.BuildProgress object. This is
- # called once at startup to figure out how to build the long-term
- # Expectations object, and again at the start of each build to get a
- # fresh BuildProgress object to track progress for that individual
- # build. TODO: revisit at-startup call
-
- if self.useProgress:
- self.progress = BuildProgress(sps)
- if self.progress and expectations:
- self.progress.setExpectationsFrom(expectations)
-
- # we are now ready to set up our BuildStatus.
- # pass all sourcestamps to the buildstatus
- self.build_status.setSourceStamps(self.sources)
- self.build_status.setReason(self.reason)
- self.build_status.setBlamelist(self.blamelist())
- self.build_status.setProgress(self.progress)
-
- # gather owners from build requests
- owners = [r.properties['owner'] for r in self.requests
- if r.properties.has_key('owner')]
- if owners: self.setProperty('owners', owners, self.reason)
-
- self.results = [] # list of FAILURE, SUCCESS, WARNINGS, SKIPPED
- self.result = SUCCESS # overall result, may downgrade after each step
- self.text = [] # list of text string lists (text2)
-
- def getNextStep(self):
- """This method is called to obtain the next BuildStep for this build.
- When it returns None (or raises a StopIteration exception), the build
- is complete."""
- if not self.steps:
- return None
- if not self.remote:
- return None
- if self.terminate or self.stopped:
- # Run any remaining alwaysRun steps, and skip over the others
- while True:
- s = self.steps.pop(0)
- if s.alwaysRun:
- return s
- if not self.steps:
- return None
- else:
- return self.steps.pop(0)
-
- def startNextStep(self):
- try:
- s = self.getNextStep()
- except StopIteration:
- s = None
- if not s:
- return self.allStepsDone()
- self.currentStep = s
- d = defer.maybeDeferred(s.startStep, self.remote)
- d.addCallback(self._stepDone, s)
- d.addErrback(self.buildException)
-
- def _stepDone(self, results, step):
- self.currentStep = None
- if self.finished:
- return # build was interrupted, don't keep building
- terminate = self.stepDone(results, step) # interpret/merge results
- if terminate:
- self.terminate = True
- return self.startNextStep()
-
- def stepDone(self, result, step):
- """This method is called when the BuildStep completes. It is passed a
- status object from the BuildStep and is responsible for merging the
- Step's results into those of the overall Build."""
-
- terminate = False
- text = None
- if type(result) == types.TupleType:
- result, text = result
- assert type(result) == type(SUCCESS)
- log.msg(" step '%s' complete: %s" % (step.name, Results[result]))
- self.results.append(result)
- if text:
- self.text.extend(text)
- if not self.remote:
- terminate = True
-
- possible_overall_result = result
- if result == FAILURE:
- if not step.flunkOnFailure:
- possible_overall_result = SUCCESS
- if step.warnOnFailure:
- possible_overall_result = WARNINGS
- if step.flunkOnFailure:
- possible_overall_result = FAILURE
- if step.haltOnFailure:
- terminate = True
- elif result == WARNINGS:
- if not step.warnOnWarnings:
- possible_overall_result = SUCCESS
- else:
- possible_overall_result = WARNINGS
- if step.flunkOnWarnings:
- possible_overall_result = FAILURE
- elif result in (EXCEPTION, RETRY):
- terminate = True
-
- # if we skipped this step, then don't adjust the build status
- if result != SKIPPED:
- self.result = worst_status(self.result, possible_overall_result)
-
- return terminate
-
- def lostRemote(self, remote=None):
- # the slave went away. There are several possible reasons for this,
- # and they aren't necessarily fatal. For now, kill the build, but
- # TODO: see if we can resume the build when it reconnects.
- log.msg("%s.lostRemote" % self)
- self.remote = None
- if self.currentStep:
- # this should cause the step to finish.
- log.msg(" stopping currentStep", self.currentStep)
- self.currentStep.interrupt(Failure(error.ConnectionLost()))
- else:
- self.result = RETRY
- self.text = ["lost", "remote"]
- self.stopped = True
- if self._acquiringLock:
- lock, access, d = self._acquiringLock
- lock.stopWaitingUntilAvailable(self, access, d)
- d.callback(None)
-
- def stopBuild(self, reason="<no reason given>"):
- # the idea here is to let the user cancel a build because, e.g.,
- # they realized they committed a bug and they don't want to waste
- # the time building something that they know will fail. Another
- # reason might be to abandon a stuck build. We want to mark the
- # build as failed quickly rather than waiting for the slave's
- # timeout to kill it on its own.
-
- log.msg(" %s: stopping build: %s" % (self, reason))
- if self.finished:
- return
- # TODO: include 'reason' in this point event
- self.builder.builder_status.addPointEvent(['interrupt'])
- self.stopped = True
- if self.currentStep:
- self.currentStep.interrupt(reason)
-
- self.result = EXCEPTION
-
- if self._acquiringLock:
- lock, access, d = self._acquiringLock
- lock.stopWaitingUntilAvailable(self, access, d)
- d.callback(None)
-
- def allStepsDone(self):
- if self.result == FAILURE:
- text = ["failed"]
- elif self.result == WARNINGS:
- text = ["warnings"]
- elif self.result == EXCEPTION:
- text = ["exception"]
- elif self.result == RETRY:
- text = ["retry"]
- else:
- text = ["build", "successful"]
- text.extend(self.text)
- return self.buildFinished(text, self.result)
-
- def buildException(self, why):
- log.msg("%s.buildException" % self)
- log.err(why)
- # try to finish the build, but since we've already faced an exception,
- # this may not work well.
- try:
- self.buildFinished(["build", "exception"], EXCEPTION)
- except:
- log.err(Failure(), 'while finishing a build with an exception')
-
- def buildFinished(self, text, results):
- """This method must be called when the last Step has completed. It
- marks the Build as complete and returns the Builder to the 'idle'
- state.
-
- It takes two arguments which describe the overall build status:
- text, results. 'results' is one of SUCCESS, WARNINGS, or FAILURE.
-
- If 'results' is SUCCESS or WARNINGS, we will permit any dependant
- builds to start. If it is 'FAILURE', those builds will be
- abandoned."""
-
- self.finished = True
- if self.remote:
- self.remote.dontNotifyOnDisconnect(self.lostRemote)
- self.remote = None
- self.results = results
-
- log.msg(" %s: build finished" % self)
- self.build_status.setText(text)
- self.build_status.setResults(results)
- self.build_status.buildFinished()
- if self.progress and results == SUCCESS:
- # XXX: also test a 'timing consistent' flag?
- log.msg(" setting expectations for next time")
- self.builder.setExpectations(self.progress)
- eventually(self.releaseLocks)
- self.deferred.callback(self)
- self.deferred = None
-
- def releaseLocks(self):
- if self.locks:
- log.msg("releaseLocks(%s): %s" % (self, self.locks))
- for lock, access in self.locks:
- if lock.isOwner(self, access):
- lock.release(self, access)
- else:
- # This should only happen if we've been interrupted
- assert self.stopped
-
- # IBuildControl
-
- def getStatus(self):
- return self.build_status
-
- # stopBuild is defined earlier
-
-components.registerAdapter(
- lambda build : interfaces.IProperties(build.build_status),
- Build, interfaces.IProperties)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py
deleted file mode 100644
index fe521581..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py
+++ /dev/null
@@ -1,629 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import weakref
-from zope.interface import implements
-from twisted.python import log, failure
-from twisted.spread import pb
-from twisted.application import service, internet
-from twisted.internet import defer
-
-from buildbot import interfaces, config
-from buildbot.status.progress import Expectations
-from buildbot.status.builder import RETRY
-from buildbot.status.buildrequest import BuildRequestStatus
-from buildbot.process.properties import Properties
-from buildbot.process import buildrequest, slavebuilder
-from buildbot.process.build import Build
-from buildbot.process.slavebuilder import BUILDING
-
-def enforceChosenSlave(bldr, slavebuilder, breq):
- if 'slavename' in breq.properties:
- slavename = breq.properties['slavename']
- if isinstance(slavename, basestring):
- return slavename==slavebuilder.slave.slavename
-
- return True
-
-class Builder(config.ReconfigurableServiceMixin,
- pb.Referenceable,
- service.MultiService):
-
- # reconfigure builders before slaves
- reconfig_priority = 196
-
- def __init__(self, name, _addServices=True):
- service.MultiService.__init__(self)
- self.name = name
-
- # this is created the first time we get a good build
- self.expectations = None
-
- # build/wannabuild slots: Build objects move along this sequence
- self.building = []
- # old_building holds active builds that were stolen from a predecessor
- self.old_building = weakref.WeakKeyDictionary()
-
- # buildslaves which have connected but which are not yet available.
- # These are always in the ATTACHING state.
- self.attaching_slaves = []
-
- # buildslaves at our disposal. Each SlaveBuilder instance has a
- # .state that is IDLE, PINGING, or BUILDING. "PINGING" is used when a
- # Build is about to start, to make sure that they're still alive.
- self.slaves = []
-
- self.config = None
- self.builder_status = None
-
- if _addServices:
- self.reclaim_svc = internet.TimerService(10*60,
- self.reclaimAllBuilds)
- self.reclaim_svc.setServiceParent(self)
-
- # update big status every 30 minutes, working around #1980
- self.updateStatusService = internet.TimerService(30*60,
- self.updateBigStatus)
- self.updateStatusService.setServiceParent(self)
-
- def reconfigService(self, new_config):
- # find this builder in the config
- for builder_config in new_config.builders:
- if builder_config.name == self.name:
- break
- else:
- assert 0, "no config found for builder '%s'" % self.name
-
- # set up a builder status object on the first reconfig
- if not self.builder_status:
- self.builder_status = self.master.status.builderAdded(
- builder_config.name,
- builder_config.builddir,
- builder_config.category,
- builder_config.description)
-
- self.config = builder_config
-
- self.builder_status.setDescription(builder_config.description)
- self.builder_status.setCategory(builder_config.category)
- self.builder_status.setSlavenames(self.config.slavenames)
- self.builder_status.setCacheSize(new_config.caches['Builds'])
-
- return defer.succeed(None)
-
- def stopService(self):
- d = defer.maybeDeferred(lambda :
- service.MultiService.stopService(self))
- return d
-
- def __repr__(self):
- return "<Builder '%r' at %d>" % (self.name, id(self))
-
- @defer.inlineCallbacks
- def getOldestRequestTime(self):
-
- """Returns the submitted_at of the oldest unclaimed build request for
- this builder, or None if there are no build requests.
-
- @returns: datetime instance or None, via Deferred
- """
- unclaimed = yield self.master.db.buildrequests.getBuildRequests(
- buildername=self.name, claimed=False)
-
- if unclaimed:
- unclaimed = [ brd['submitted_at'] for brd in unclaimed ]
- unclaimed.sort()
- defer.returnValue(unclaimed[0])
- else:
- defer.returnValue(None)
-
- def reclaimAllBuilds(self):
- brids = set()
- for b in self.building:
- brids.update([br.id for br in b.requests])
- for b in self.old_building:
- brids.update([br.id for br in b.requests])
-
- if not brids:
- return defer.succeed(None)
-
- d = self.master.db.buildrequests.reclaimBuildRequests(brids)
- d.addErrback(log.err, 'while re-claiming running BuildRequests')
- return d
-
- def getBuild(self, number):
- for b in self.building:
- if b.build_status and b.build_status.number == number:
- return b
- for b in self.old_building.keys():
- if b.build_status and b.build_status.number == number:
- return b
- return None
-
- def addLatentSlave(self, slave):
- assert interfaces.ILatentBuildSlave.providedBy(slave)
- for s in self.slaves:
- if s == slave:
- break
- else:
- sb = slavebuilder.LatentSlaveBuilder(slave, self)
- self.builder_status.addPointEvent(
- ['added', 'latent', slave.slavename])
- self.slaves.append(sb)
- self.botmaster.maybeStartBuildsForBuilder(self.name)
-
- def attached(self, slave, remote, commands):
- """This is invoked by the BuildSlave when the self.slavename bot
- registers their builder.
-
- @type slave: L{buildbot.buildslave.BuildSlave}
- @param slave: the BuildSlave that represents the buildslave as a whole
- @type remote: L{twisted.spread.pb.RemoteReference}
- @param remote: a reference to the L{buildbot.slave.bot.SlaveBuilder}
- @type commands: dict: string -> string, or None
- @param commands: provides the slave's version of each RemoteCommand
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: a Deferred that fires (with 'self') when the slave-side
- builder is fully attached and ready to accept commands.
- """
- for s in self.attaching_slaves + self.slaves:
- if s.slave == slave:
- # already attached to them. This is fairly common, since
- # attached() gets called each time we receive the builder
- # list from the slave, and we ask for it each time we add or
- # remove a builder. So if the slave is hosting builders
- # A,B,C, and the config file changes A, we'll remove A and
- # re-add it, triggering two builder-list requests, getting
- # two redundant calls to attached() for B, and another two
- # for C.
- #
- # Therefore, when we see that we're already attached, we can
- # just ignore it.
- return defer.succeed(self)
-
- sb = slavebuilder.SlaveBuilder()
- sb.setBuilder(self)
- self.attaching_slaves.append(sb)
- d = sb.attached(slave, remote, commands)
- d.addCallback(self._attached)
- d.addErrback(self._not_attached, slave)
- return d
-
- def _attached(self, sb):
- self.builder_status.addPointEvent(['connect', sb.slave.slavename])
- self.attaching_slaves.remove(sb)
- self.slaves.append(sb)
-
- self.updateBigStatus()
-
- return self
-
- def _not_attached(self, why, slave):
- # already log.err'ed by SlaveBuilder._attachFailure
- # TODO: remove from self.slaves (except that detached() should get
- # run first, right?)
- log.err(why, 'slave failed to attach')
- self.builder_status.addPointEvent(['failed', 'connect',
- slave.slavename])
- # TODO: add an HTMLLogFile of the exception
-
- def detached(self, slave):
- """This is called when the connection to the bot is lost."""
- for sb in self.attaching_slaves + self.slaves:
- if sb.slave == slave:
- break
- else:
- log.msg("WEIRD: Builder.detached(%s) (%s)"
- " not in attaching_slaves(%s)"
- " or slaves(%s)" % (slave, slave.slavename,
- self.attaching_slaves,
- self.slaves))
- return
- if sb.state == BUILDING:
- # the Build's .lostRemote method (invoked by a notifyOnDisconnect
- # handler) will cause the Build to be stopped, probably right
- # after the notifyOnDisconnect that invoked us finishes running.
- pass
-
- if sb in self.attaching_slaves:
- self.attaching_slaves.remove(sb)
- if sb in self.slaves:
- self.slaves.remove(sb)
-
- self.builder_status.addPointEvent(['disconnect', slave.slavename])
- sb.detached() # inform the SlaveBuilder that their slave went away
- self.updateBigStatus()
-
- def updateBigStatus(self):
- try:
- # Catch exceptions here, since this is called in a LoopingCall.
- if not self.builder_status:
- return
- if not self.slaves:
- self.builder_status.setBigState("offline")
- elif self.building or self.old_building:
- self.builder_status.setBigState("building")
- else:
- self.builder_status.setBigState("idle")
- except Exception:
- log.err(None, "while trying to update status of builder '%s'" % (self.name,))
-
- def getAvailableSlaves(self):
- return [ sb for sb in self.slaves if sb.isAvailable() ]
-
- def canStartWithSlavebuilder(self, slavebuilder):
- locks = [(self.botmaster.getLockFromLockAccess(access), access)
- for access in self.config.locks ]
- return Build.canStartWithSlavebuilder(locks, slavebuilder)
-
- def canStartBuild(self, slavebuilder, breq):
- if callable(self.config.canStartBuild):
- return defer.maybeDeferred(self.config.canStartBuild, self, slavebuilder, breq)
- return defer.succeed(True)
-
- @defer.inlineCallbacks
- def _startBuildFor(self, slavebuilder, buildrequests):
- """Start a build on the given slave.
- @param build: the L{base.Build} to start
- @param sb: the L{SlaveBuilder} which will host this build
-
- @return: (via Deferred) boolean indicating that the build was
- succesfully started.
- """
-
- # as of the Python versions supported now, try/finally can't be used
- # with a generator expression. So instead, we push cleanup functions
- # into a list so that, at any point, we can abort this operation.
- cleanups = []
- def run_cleanups():
- try:
- while cleanups:
- fn = cleanups.pop()
- fn()
- except:
- log.err(failure.Failure(), "while running %r" % (run_cleanups,))
-
- # the last cleanup we want to perform is to update the big
- # status based on any other cleanup
- cleanups.append(lambda : self.updateBigStatus())
-
- build = self.config.factory.newBuild(buildrequests)
- build.setBuilder(self)
- log.msg("starting build %s using slave %s" % (build, slavebuilder))
-
- # set up locks
- build.setLocks(self.config.locks)
- cleanups.append(lambda : slavebuilder.slave.releaseLocks())
-
- if len(self.config.env) > 0:
- build.setSlaveEnvironment(self.config.env)
-
- # append the build to self.building
- self.building.append(build)
- cleanups.append(lambda : self.building.remove(build))
-
- # update the big status accordingly
- self.updateBigStatus()
-
- try:
- ready = yield slavebuilder.prepare(self.builder_status, build)
- except:
- log.err(failure.Failure(), 'while preparing slavebuilder:')
- ready = False
-
- # If prepare returns True then it is ready and we start a build
- # If it returns false then we don't start a new build.
- if not ready:
- log.msg("slave %s can't build %s after all; re-queueing the "
- "request" % (build, slavebuilder))
- run_cleanups()
- defer.returnValue(False)
- return
-
- # ping the slave to make sure they're still there. If they've
- # fallen off the map (due to a NAT timeout or something), this
- # will fail in a couple of minutes, depending upon the TCP
- # timeout.
- #
- # TODO: This can unnecessarily suspend the starting of a build, in
- # situations where the slave is live but is pushing lots of data to
- # us in a build.
- log.msg("starting build %s.. pinging the slave %s"
- % (build, slavebuilder))
- try:
- ping_success = yield slavebuilder.ping()
- except:
- log.err(failure.Failure(), 'while pinging slave before build:')
- ping_success = False
-
- if not ping_success:
- log.msg("slave ping failed; re-queueing the request")
- run_cleanups()
- defer.returnValue(False)
- return
-
- # The buildslave is ready to go. slavebuilder.buildStarted() sets its
- # state to BUILDING (so we won't try to use it for any other builds).
- # This gets set back to IDLE by the Build itself when it finishes.
- slavebuilder.buildStarted()
- cleanups.append(lambda : slavebuilder.buildFinished())
-
- # tell the remote that it's starting a build, too
- try:
- yield slavebuilder.remote.callRemote("startBuild")
- except:
- log.err(failure.Failure(), 'while calling remote startBuild:')
- run_cleanups()
- defer.returnValue(False)
- return
-
- # create the BuildStatus object that goes with the Build
- bs = self.builder_status.newBuild()
-
- # record the build in the db - one row per buildrequest
- try:
- bids = []
- for req in build.requests:
- bid = yield self.master.db.builds.addBuild(req.id, bs.number)
- bids.append(bid)
- except:
- log.err(failure.Failure(), 'while adding rows to build table:')
- run_cleanups()
- defer.returnValue(False)
- return
-
- # IMPORTANT: no yielding is allowed from here to the startBuild call!
-
- # it's possible that we lost the slave remote between the ping above
- # and now. If so, bail out. The build.startBuild call below transfers
- # responsibility for monitoring this connection to the Build instance,
- # so this check ensures we hand off a working connection.
- if not slavebuilder.remote:
- log.msg("slave disappeared before build could start")
- run_cleanups()
- defer.returnValue(False)
- return
-
- # let status know
- self.master.status.build_started(req.id, self.name, bs)
-
- # start the build. This will first set up the steps, then tell the
- # BuildStatus that it has started, which will announce it to the world
- # (through our BuilderStatus object, which is its parent). Finally it
- # will start the actual build process. This is done with a fresh
- # Deferred since _startBuildFor should not wait until the build is
- # finished. This uses `maybeDeferred` to ensure that any exceptions
- # raised by startBuild are treated as deferred errbacks (see
- # http://trac.buildbot.net/ticket/2428).
- d = defer.maybeDeferred(build.startBuild,
- bs, self.expectations, slavebuilder)
- d.addCallback(self.buildFinished, slavebuilder, bids)
- # this shouldn't happen. if it does, the slave will be wedged
- d.addErrback(log.err, 'from a running build; this is a '
- 'serious error - please file a bug at http://buildbot.net')
-
- # make sure the builder's status is represented correctly
- self.updateBigStatus()
-
- defer.returnValue(True)
-
- def setupProperties(self, props):
- props.setProperty("buildername", self.name, "Builder")
- if len(self.config.properties) > 0:
- for propertyname in self.config.properties:
- props.setProperty(propertyname,
- self.config.properties[propertyname],
- "Builder")
-
- def buildFinished(self, build, sb, bids):
- """This is called when the Build has finished (either success or
- failure). Any exceptions during the build are reported with
- results=FAILURE, not with an errback."""
-
- # by the time we get here, the Build has already released the slave,
- # which will trigger a check for any now-possible build requests
- # (maybeStartBuilds)
-
- # mark the builds as finished, although since nothing ever reads this
- # table, it's not too important that it complete successfully
- d = self.master.db.builds.finishBuilds(bids)
- d.addErrback(log.err, 'while marking builds as finished (ignored)')
-
- results = build.build_status.getResults()
- self.building.remove(build)
- if results == RETRY:
- self._resubmit_buildreqs(build).addErrback(log.err)
- else:
- brids = [br.id for br in build.requests]
- db = self.master.db
- d = db.buildrequests.completeBuildRequests(brids, results)
- d.addCallback(
- lambda _ : self._maybeBuildsetsComplete(build.requests))
- # nothing in particular to do with this deferred, so just log it if
- # it fails..
- d.addErrback(log.err, 'while marking build requests as completed')
-
- if sb.slave:
- sb.slave.releaseLocks()
-
- self.updateBigStatus()
-
- @defer.inlineCallbacks
- def _maybeBuildsetsComplete(self, requests):
- # inform the master that we may have completed a number of buildsets
- for br in requests:
- yield self.master.maybeBuildsetComplete(br.bsid)
-
- def _resubmit_buildreqs(self, build):
- brids = [br.id for br in build.requests]
- return self.master.db.buildrequests.unclaimBuildRequests(brids)
-
- def setExpectations(self, progress):
- """Mark the build as successful and update expectations for the next
- build. Only call this when the build did not fail in any way that
- would invalidate the time expectations generated by it. (if the
- compile failed and thus terminated early, we can't use the last
- build to predict how long the next one will take).
- """
- if self.expectations:
- self.expectations.update(progress)
- else:
- # the first time we get a good build, create our Expectations
- # based upon its results
- self.expectations = Expectations(progress)
- log.msg("new expectations: %s seconds" %
- self.expectations.expectedBuildTime())
-
- # Build Creation
-
- @defer.inlineCallbacks
- def maybeStartBuild(self, slavebuilder, breqs):
- # This method is called by the botmaster whenever this builder should
- # start a set of buildrequests on a slave. Do not call this method
- # directly - use master.botmaster.maybeStartBuildsForBuilder, or one of
- # the other similar methods if more appropriate
-
- # first, if we're not running, then don't start builds; stopService
- # uses this to ensure that any ongoing maybeStartBuild invocations
- # are complete before it stops.
- if not self.running:
- defer.returnValue(False)
- return
-
- # If the build fails from here on out (e.g., because a slave has failed),
- # it will be handled outside of this function. TODO: test that!
-
- build_started = yield self._startBuildFor(slavebuilder, breqs)
- defer.returnValue(build_started)
-
- # a few utility functions to make the maybeStartBuild a bit shorter and
- # easier to read
-
- def getMergeRequestsFn(self):
- """Helper function to determine which mergeRequests function to use
- from L{_mergeRequests}, or None for no merging"""
- # first, seek through builder, global, and the default
- mergeRequests_fn = self.config.mergeRequests
- if mergeRequests_fn is None:
- mergeRequests_fn = self.master.config.mergeRequests
- if mergeRequests_fn is None:
- mergeRequests_fn = True
-
- # then translate False and True properly
- if mergeRequests_fn is False:
- mergeRequests_fn = None
- elif mergeRequests_fn is True:
- mergeRequests_fn = Builder._defaultMergeRequestFn
-
- return mergeRequests_fn
-
- def _defaultMergeRequestFn(self, req1, req2):
- return req1.canBeMergedWith(req2)
-
-
-class BuilderControl:
- implements(interfaces.IBuilderControl)
-
- def __init__(self, builder, control):
- self.original = builder
- self.control = control
-
- def submitBuildRequest(self, ss, reason, props=None):
- d = ss.getSourceStampSetId(self.control.master)
- def add_buildset(sourcestampsetid):
- return self.control.master.addBuildset(
- builderNames=[self.original.name],
- sourcestampsetid=sourcestampsetid, reason=reason, properties=props)
- d.addCallback(add_buildset)
- def get_brs((bsid,brids)):
- brs = BuildRequestStatus(self.original.name,
- brids[self.original.name],
- self.control.master.status)
- return brs
- d.addCallback(get_brs)
- return d
-
- @defer.inlineCallbacks
- def rebuildBuild(self, bs, reason="<rebuild, no reason given>", extraProperties=None):
- if not bs.isFinished():
- return
-
- # Make a copy of the properties so as not to modify the original build.
- properties = Properties()
- # Don't include runtime-set properties in a rebuild request
- properties.updateFromPropertiesNoRuntime(bs.getProperties())
- if extraProperties is None:
- properties.updateFromProperties(extraProperties)
-
- properties_dict = dict((k,(v,s)) for (k,v,s) in properties.asList())
- ssList = bs.getSourceStamps(absolute=True)
-
- if ssList:
- sourcestampsetid = yield ssList[0].getSourceStampSetId(self.control.master)
- dl = []
- for ss in ssList[1:]:
- # add defered to the list
- dl.append(ss.addSourceStampToDatabase(self.control.master, sourcestampsetid))
- yield defer.gatherResults(dl)
-
- bsid, brids = yield self.control.master.addBuildset(
- builderNames=[self.original.name],
- sourcestampsetid=sourcestampsetid,
- reason=reason,
- properties=properties_dict)
- defer.returnValue((bsid, brids))
- else:
- log.msg('Cannot start rebuild, rebuild has no sourcestamps for a new build')
- defer.returnValue(None)
-
- @defer.inlineCallbacks
- def getPendingBuildRequestControls(self):
- master = self.original.master
- brdicts = yield master.db.buildrequests.getBuildRequests(
- buildername=self.original.name,
- claimed=False)
-
- # convert those into BuildRequest objects
- buildrequests = [ ]
- for brdict in brdicts:
- br = yield buildrequest.BuildRequest.fromBrdict(
- self.control.master, brdict)
- buildrequests.append(br)
-
- # and return the corresponding control objects
- defer.returnValue([ buildrequest.BuildRequestControl(self.original, r)
- for r in buildrequests ])
-
- def getBuild(self, number):
- return self.original.getBuild(number)
-
- def ping(self):
- if not self.original.slaves:
- self.original.builder_status.addPointEvent(["ping", "no slave"])
- return defer.succeed(False) # interfaces.NoSlaveError
- dl = []
- for s in self.original.slaves:
- dl.append(s.ping(self.original.builder_status))
- d = defer.DeferredList(dl)
- d.addCallback(self._gatherPingResults)
- return d
-
- def _gatherPingResults(self, res):
- for ignored,success in res:
- if not success:
- return False
- return True
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py
deleted file mode 100644
index c9b9daa7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import calendar
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces, sourcestamp
-from buildbot.process import properties
-from buildbot.status.results import FAILURE
-from buildbot.db import buildrequests
-
-class BuildRequest(object):
- """
-
- A rolled-up encapsulation of all of the data relevant to a build request.
-
- This class is used by the C{nextBuild} and C{mergeRequests} configuration
- parameters, as well as in starting a build. Construction of a BuildRequest
- object is a heavyweight process involving a lot of database queries, so
- it should be avoided where possible. See bug #1894.
-
- Build requests have a SourceStamp which specifies what sources to build.
- This may specify a specific revision of the source tree (so source.branch,
- source.revision, and source.patch are used). The .patch attribute is either
- None or a tuple of (patchlevel, diff), consisting of a number to use in
- 'patch -pN', and a unified-format context diff.
-
- Alternatively, the SourceStamp may specify a set of Changes to be built,
- contained in source.changes. In this case, the requeset may be mergeable
- with other BuildRequests on the same branch.
-
- @type source: L{buildbot.sourcestamp.SourceStamp}
- @ivar source: the source stamp that this BuildRequest use
-
- @type reason: string
- @ivar reason: the reason this Build is being requested. Schedulers provide
- this, but for forced builds the user requesting the build will provide a
- string. It comes from the buildsets table.
-
- @type properties: L{properties.Properties}
- @ivar properties: properties that should be applied to this build, taken
- from the buildset containing this build request
-
- @ivar submittedAt: a timestamp (seconds since epoch) when this request was
- submitted to the Builder. This is used by the CVS step to compute a
- checkout timestamp, as well as by the master to prioritize build requests
- from oldest to newest.
-
- @ivar buildername: name of the requested builder
-
- @ivar priority: request priority
-
- @ivar id: build request ID
-
- @ivar bsid: ID of the parent buildset
- """
-
- source = None
- sources = None
- submittedAt = None
-
- @classmethod
- def fromBrdict(cls, master, brdict):
- """
- Construct a new L{BuildRequest} from a dictionary as returned by
- L{BuildRequestsConnectorComponent.getBuildRequest}.
-
- This method uses a cache, which may result in return of stale objects;
- for the most up-to-date information, use the database connector
- methods.
-
- @param master: current build master
- @param brdict: build request dictionary
-
- @returns: L{BuildRequest}, via Deferred
- """
- cache = master.caches.get_cache("BuildRequests", cls._make_br)
- return cache.get(brdict['brid'], brdict=brdict, master=master)
-
- @classmethod
- @defer.inlineCallbacks
- def _make_br(cls, brid, brdict, master):
- buildrequest = cls()
- buildrequest.id = brid
- buildrequest.bsid = brdict['buildsetid']
- buildrequest.buildername = brdict['buildername']
- buildrequest.priority = brdict['priority']
- dt = brdict['submitted_at']
- buildrequest.submittedAt = dt and calendar.timegm(dt.utctimetuple())
- buildrequest.master = master
-
- # fetch the buildset to get the reason
- buildset = yield master.db.buildsets.getBuildset(brdict['buildsetid'])
- assert buildset # schema should guarantee this
- buildrequest.reason = buildset['reason']
-
- # fetch the buildset properties, and convert to Properties
- buildset_properties = yield master.db.buildsets.getBuildsetProperties(brdict['buildsetid'])
-
- buildrequest.properties = properties.Properties.fromDict(buildset_properties)
-
- # fetch the sourcestamp dictionary
- sslist = yield master.db.sourcestamps.getSourceStamps(buildset['sourcestampsetid'])
- assert len(sslist) > 0, "Empty sourcestampset: db schema enforces set to exist but cannot enforce a non empty set"
-
- # and turn it into a SourceStamps
- buildrequest.sources = {}
- def store_source(source):
- buildrequest.sources[source.codebase] = source
-
- dlist = []
- for ssdict in sslist:
- d = sourcestamp.SourceStamp.fromSsdict(master, ssdict)
- d.addCallback(store_source)
- dlist.append(d)
-
- yield defer.gatherResults(dlist)
-
- if buildrequest.sources:
- buildrequest.source = buildrequest.sources.values()[0]
-
- defer.returnValue(buildrequest)
-
- def requestsHaveSameCodebases(self, other):
- self_codebases = set(self.sources.iterkeys())
- other_codebases = set(other.sources.iterkeys())
- return self_codebases == other_codebases
-
- def requestsHaveChangesForSameCodebases(self, other):
- # Merge can only be done if both requests have sourcestampsets containing
- # comparable sourcestamps, that means sourcestamps with the same codebase.
- # This means that both requests must have exact the same set of codebases
- # If not then merge cannot be performed.
- # The second requirement is that both request have the changes in the
- # same codebases.
- #
- # Normaly a scheduler always delivers the same set of codebases:
- # sourcestamps with and without changes
- # For the case a scheduler is not configured with a set of codebases
- # it delivers only a set with sourcestamps that have changes.
- self_codebases = set(self.sources.iterkeys())
- other_codebases = set(other.sources.iterkeys())
- if self_codebases != other_codebases:
- return False
-
- for c in self_codebases:
- # Check either both or neither have changes
- if ((len(self.sources[c].changes) > 0)
- != (len(other.sources[c].changes) > 0)):
- return False
- # all codebases tested, no differences found
- return True
-
- def canBeMergedWith(self, other):
- """
- Returns if both requests can be merged
- """
-
- if not self.requestsHaveChangesForSameCodebases(other):
- return False
-
- #get codebases from myself, they are equal to other
- self_codebases = set(self.sources.iterkeys())
-
- for c in self_codebases:
- # check to prevent exception
- if c not in other.sources:
- return False
- if not self.sources[c].canBeMergedWith(other.sources[c]):
- return False
- return True
-
- def mergeSourceStampsWith(self, others):
- """ Returns one merged sourcestamp for every codebase """
- #get all codebases from all requests
- all_codebases = set(self.sources.iterkeys())
- for other in others:
- all_codebases |= set(other.sources.iterkeys())
-
- all_merged_sources = {}
- # walk along the codebases
- for codebase in all_codebases:
- all_sources = []
- if codebase in self.sources:
- all_sources.append(self.sources[codebase])
- for other in others:
- if codebase in other.sources:
- all_sources.append(other.sources[codebase])
- assert len(all_sources)>0, "each codebase should have atleast one sourcestamp"
- all_merged_sources[codebase] = all_sources[0].mergeWith(all_sources[1:])
-
- return [source for source in all_merged_sources.itervalues()]
-
- def mergeReasons(self, others):
- """Return a reason for the merged build request."""
- reasons = []
- for req in [self] + others:
- if req.reason and req.reason not in reasons:
- reasons.append(req.reason)
- return ", ".join(reasons)
-
- def getSubmitTime(self):
- return self.submittedAt
-
- @defer.inlineCallbacks
- def cancelBuildRequest(self):
- # first, try to claim the request; if this fails, then it's too late to
- # cancel the build anyway
- try:
- yield self.master.db.buildrequests.claimBuildRequests([self.id])
- except buildrequests.AlreadyClaimedError:
- log.msg("build request already claimed; cannot cancel")
- return
-
- # then complete it with 'FAILURE'; this is the closest we can get to
- # cancelling a request without running into trouble with dangling
- # references.
- yield self.master.db.buildrequests.completeBuildRequests([self.id],
- FAILURE)
-
- # and let the master know that the enclosing buildset may be complete
- yield self.master.maybeBuildsetComplete(self.bsid)
-
-class BuildRequestControl:
- implements(interfaces.IBuildRequestControl)
-
- def __init__(self, builder, request):
- self.original_builder = builder
- self.original_request = request
- self.brid = request.id
-
- def subscribe(self, observer):
- raise NotImplementedError
-
- def unsubscribe(self, observer):
- raise NotImplementedError
-
- def cancel(self):
- d = self.original_request.cancelBuildRequest()
- d.addErrback(log.err, 'while cancelling build request')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py
deleted file mode 100644
index afae3b8e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py
+++ /dev/null
@@ -1,544 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.internet import defer
-from twisted.application import service
-
-from buildbot.process import metrics
-from buildbot.process.buildrequest import BuildRequest
-from buildbot.db.buildrequests import AlreadyClaimedError
-
-import random
-
-class BuildChooserBase(object):
- #
- # WARNING: This API is experimental and in active development.
- #
- # This internal object selects a new build+slave pair. It acts as a
- # generator, initializing its state on creation and offering up new
- # pairs until exhaustion. The object can be destroyed at any time
- # (eg, before the list exhausts), and can be "restarted" by abandoning
- # an old instance and creating a new one.
- #
- # The entry point is:
- # * bc.chooseNextBuild() - get the next (slave, [breqs]) or (None, None)
- #
- # The default implementation of this class implements a default
- # chooseNextBuild() that delegates out to two other functions:
- # * bc.popNextBuild() - get the next (slave, breq) pair
- # * bc.mergeRequests(breq) - perform a merge for this breq and return
- # the list of breqs consumed by the merge (including breq itself)
-
- def __init__(self, bldr, master):
- self.bldr = bldr
- self.master = master
- self.breqCache = {}
- self.unclaimedBrdicts = None
-
- @defer.inlineCallbacks
- def chooseNextBuild(self):
- # Return the next build, as a (slave, [breqs]) pair
-
- slave, breq = yield self.popNextBuild()
- if not slave or not breq:
- defer.returnValue((None, None))
- return
-
- breqs = yield self.mergeRequests(breq)
- for b in breqs:
- self._removeBuildRequest(b)
-
- defer.returnValue((slave, breqs))
-
-
- # Must be implemented by subclass
- def popNextBuild(self):
- # Pick the next (slave, breq) pair; note this is pre-merge, so
- # it's just one breq
- raise NotImplementedError("Subclasses must implement this!")
-
- # Must be implemented by subclass
- def mergeRequests(self, breq):
- # Merge the chosen breq with any other breqs that are compatible
- # Returns a list of the breqs chosen (and should include the
- # original breq as well!)
- raise NotImplementedError("Subclasses must implement this!")
-
-
- # - Helper functions that are generally useful to all subclasses -
-
- @defer.inlineCallbacks
- def _fetchUnclaimedBrdicts(self):
- # Sets up a cache of all the unclaimed brdicts. The cache is
- # saved at self.unclaimedBrdicts cache. If the cache already
- # exists, this function does nothing. If a refetch is desired, set
- # the self.unclaimedBrdicts to None before calling."""
-
- if self.unclaimedBrdicts is None:
- brdicts = yield self.master.db.buildrequests.getBuildRequests(
- buildername=self.bldr.name, claimed=False)
- # sort by submitted_at, so the first is the oldest
- brdicts.sort(key=lambda brd : brd['submitted_at'])
- self.unclaimedBrdicts = brdicts
- defer.returnValue(self.unclaimedBrdicts)
-
- @defer.inlineCallbacks
- def _getBuildRequestForBrdict(self, brdict):
- # Turn a brdict into a BuildRequest into a brdict. This is useful
- # for API like 'nextBuild', which operate on BuildRequest objects.
-
- breq = self.breqCache.get(brdict['brid'])
- if not breq:
- breq = yield BuildRequest.fromBrdict(self.master, brdict)
- if breq:
- self.breqCache[brdict['brid']] = breq
- defer.returnValue(breq)
-
- def _getBrdictForBuildRequest(self, breq):
- # Turn a BuildRequest back into a brdict. This operates from the
- # cache, which must be set up once via _fetchUnclaimedBrdicts
-
- if breq is None:
- return None
-
- brid = breq.id
- for brdict in self.unclaimedBrdicts:
- if brid == brdict['brid']:
- return brdict
- return None
-
- def _removeBuildRequest(self, breq):
- # Remove a BuildrRequest object (and its brdict)
- # from the caches
-
- if breq is None:
- return
-
- brdict = self._getBrdictForBuildRequest(breq)
- if brdict is not None:
- self.unclaimedBrdicts.remove(brdict)
-
- if breq.id in self.breqCache:
- del self.breqCache[breq.id]
-
- def _getUnclaimedBuildRequests(self):
- # Retrieve the list of BuildRequest objects for all unclaimed builds
- return defer.gatherResults([
- self._getBuildRequestForBrdict(brdict)
- for brdict in self.unclaimedBrdicts ])
-
-class BasicBuildChooser(BuildChooserBase):
- # BasicBuildChooser generates build pairs via the configuration points:
- # * config.nextSlave (or random.choice if not set)
- # * config.nextBuild (or "pop top" if not set)
- #
- # For N slaves, this will call nextSlave at most N times. If nextSlave
- # returns a slave that cannot satisfy the build chosen by nextBuild,
- # it will search for a slave that can satisfy the build. If one is found,
- # the slaves that cannot be used are "recycled" back into a list
- # to be tried, in order, for the next chosen build.
- #
- # There are two tests performed on the slave:
- # * can the slave start a generic build for the Builder?
- # * if so, can the slave start the chosen build on the Builder?
- # Slaves that cannot meet the first criterion are saved into the
- # self.rejectedSlaves list and will be used as a last resort. An example
- # of this test is whether the slave can grab the Builder's locks.
- #
- # If all slaves fail the first test, then the algorithm will assign the
- # slaves in the order originally generated. By setting self.rejectedSlaves
- # to None, the behavior will instead refuse to ever assign to a slave that
- # fails the generic test.
-
- def __init__(self, bldr, master):
- BuildChooserBase.__init__(self, bldr, master)
-
- self.nextSlave = self.bldr.config.nextSlave
- if not self.nextSlave:
- self.nextSlave = lambda _,slaves: random.choice(slaves) if slaves else None
-
- self.slavepool = self.bldr.getAvailableSlaves()
-
- # Pick slaves one at a time from the pool, and if the Builder says
- # they're usable (eg, locks can be satisfied), then prefer those slaves;
- # otherwise they go in the 'last resort' bucket, and we'll use them if
- # we need to. (Setting rejectedSlaves to None disables that feature)
- self.preferredSlaves = []
- self.rejectedSlaves = []
-
- self.nextBuild = self.bldr.config.nextBuild
-
- self.mergeRequestsFn = self.bldr.getMergeRequestsFn()
-
- @defer.inlineCallbacks
- def popNextBuild(self):
- nextBuild = (None, None)
-
- while 1:
- # 1. pick a slave
- slave = yield self._popNextSlave()
- if not slave:
- break
-
- # 2. pick a build
- breq = yield self._getNextUnclaimedBuildRequest()
- if not breq:
- break
-
- # either satisfy this build or we leave it for another day
- self._removeBuildRequest(breq)
-
- # 3. make sure slave+ is usable for the breq
- recycledSlaves = []
- while slave:
- canStart = yield self.canStartBuild(slave, breq)
- if canStart:
- break
- # try a different slave
- recycledSlaves.append(slave)
- slave = yield self._popNextSlave()
-
- # recycle the slaves that we didnt use to the head of the queue
- # this helps ensure we run 'nextSlave' only once per slave choice
- if recycledSlaves:
- self._unpopSlaves(recycledSlaves)
-
- # 4. done? otherwise we will try another build
- if slave:
- nextBuild = (slave, breq)
- break
-
- defer.returnValue(nextBuild)
-
- @defer.inlineCallbacks
- def mergeRequests(self, breq):
- mergedRequests = [ breq ]
-
- # short circuit if there is no merging to do
- if not self.mergeRequestsFn or not self.unclaimedBrdicts:
- defer.returnValue(mergedRequests)
- return
-
- # we'll need BuildRequest objects, so get those first
- unclaimedBreqs = yield self._getUnclaimedBuildRequests()
-
- # gather the mergeable requests
- for req in unclaimedBreqs:
- canMerge = yield self.mergeRequestsFn(self.bldr, breq, req)
- if canMerge:
- mergedRequests.append(req)
-
- defer.returnValue(mergedRequests)
-
-
- @defer.inlineCallbacks
- def _getNextUnclaimedBuildRequest(self):
- # ensure the cache is there
- yield self._fetchUnclaimedBrdicts()
- if not self.unclaimedBrdicts:
- defer.returnValue(None)
- return
-
- if self.nextBuild:
- # nextBuild expects BuildRequest objects
- breqs = yield self._getUnclaimedBuildRequests()
- try:
- nextBreq = yield self.nextBuild(self.bldr, breqs)
- if nextBreq not in breqs:
- nextBreq = None
- except Exception:
- nextBreq = None
- else:
- # otherwise just return the first build
- brdict = self.unclaimedBrdicts[0]
- nextBreq = yield self._getBuildRequestForBrdict(brdict)
-
- defer.returnValue(nextBreq)
-
- @defer.inlineCallbacks
- def _popNextSlave(self):
- # use 'preferred' slaves first, if we have some ready
- if self.preferredSlaves:
- slave = self.preferredSlaves.pop(0)
- defer.returnValue(slave)
- return
-
- while self.slavepool:
- try:
- slave = yield self.nextSlave(self.bldr, self.slavepool)
- except Exception:
- slave = None
-
- if not slave or slave not in self.slavepool:
- # bad slave or no slave returned
- break
-
- self.slavepool.remove(slave)
-
- canStart = yield self.bldr.canStartWithSlavebuilder(slave)
- if canStart:
- defer.returnValue(slave)
- return
-
- # save as a last resort, just in case we need them later
- if self.rejectedSlaves is not None:
- self.rejectedSlaves.append(slave)
-
- # if we chewed through them all, use as last resort:
- if self.rejectedSlaves:
- slave = self.rejectedSlaves.pop(0)
- defer.returnValue(slave)
- return
-
- defer.returnValue(None)
-
- def _unpopSlaves(self, slaves):
- # push the slaves back to the front
- self.preferredSlaves[:0] = slaves
-
- def canStartBuild(self, slave, breq):
- return self.bldr.canStartBuild(slave, breq)
-
-
-class BuildRequestDistributor(service.Service):
- """
- Special-purpose class to handle distributing build requests to builders by
- calling their C{maybeStartBuild} method.
-
- This takes account of the C{prioritizeBuilders} configuration, and is
- highly re-entrant; that is, if a new build request arrives while builders
- are still working on the previous build request, then this class will
- correctly re-prioritize invocations of builders' C{maybeStartBuild}
- methods.
- """
-
- BuildChooser = BasicBuildChooser
-
- def __init__(self, botmaster):
- self.botmaster = botmaster
- self.master = botmaster.master
-
- # lock to ensure builders are only sorted once at any time
- self.pending_builders_lock = defer.DeferredLock()
-
- # sorted list of names of builders that need their maybeStartBuild
- # method invoked.
- self._pending_builders = []
- self.activity_lock = defer.DeferredLock()
- self.active = False
-
- self._pendingMSBOCalls = []
-
- @defer.inlineCallbacks
- def stopService(self):
- # Lots of stuff happens asynchronously here, so we need to let it all
- # quiesce. First, let the parent stopService succeed between
- # activities; then the loop will stop calling itself, since
- # self.running is false.
- yield self.activity_lock.run(service.Service.stopService, self)
-
- # now let any outstanding calls to maybeStartBuildsOn to finish, so
- # they don't get interrupted in mid-stride. This tends to be
- # particularly painful because it can occur when a generator is gc'd.
- if self._pendingMSBOCalls:
- yield defer.DeferredList(self._pendingMSBOCalls)
-
- def maybeStartBuildsOn(self, new_builders):
- """
- Try to start any builds that can be started right now. This function
- returns immediately, and promises to trigger those builders
- eventually.
-
- @param new_builders: names of new builders that should be given the
- opportunity to check for new requests.
- """
- if not self.running:
- return
-
- d = self._maybeStartBuildsOn(new_builders)
- self._pendingMSBOCalls.append(d)
- @d.addBoth
- def remove(x):
- self._pendingMSBOCalls.remove(d)
- return x
- d.addErrback(log.err, "while strting builds on %s" % (new_builders,))
-
- def _maybeStartBuildsOn(self, new_builders):
- new_builders = set(new_builders)
- existing_pending = set(self._pending_builders)
-
- # if we won't add any builders, there's nothing to do
- if new_builders < existing_pending:
- return defer.succeed(None)
-
- # reset the list of pending builders
- @defer.inlineCallbacks
- def resetPendingBuildersList(new_builders):
- try:
- # re-fetch existing_pending, in case it has changed
- # while acquiring the lock
- existing_pending = set(self._pending_builders)
-
- # then sort the new, expanded set of builders
- self._pending_builders = \
- yield self._sortBuilders(
- list(existing_pending | new_builders))
-
- # start the activity loop, if we aren't already
- # working on that.
- if not self.active:
- self._activityLoop()
- except Exception:
- log.err(Failure(),
- "while attempting to start builds on %s" % self.name)
-
- return self.pending_builders_lock.run(
- resetPendingBuildersList, new_builders)
-
- @defer.inlineCallbacks
- def _defaultSorter(self, master, builders):
- timer = metrics.Timer("BuildRequestDistributor._defaultSorter()")
- timer.start()
- # perform an asynchronous schwarzian transform, transforming None
- # into sys.maxint so that it sorts to the end
- def xform(bldr):
- d = defer.maybeDeferred(lambda :
- bldr.getOldestRequestTime())
- d.addCallback(lambda time :
- (((time is None) and None or time),bldr))
- return d
- xformed = yield defer.gatherResults(
- [ xform(bldr) for bldr in builders ])
-
- # sort the transformed list synchronously, comparing None to the end of
- # the list
- def nonecmp(a,b):
- if a[0] is None: return 1
- if b[0] is None: return -1
- return cmp(a,b)
- xformed.sort(cmp=nonecmp)
-
- # and reverse the transform
- rv = [ xf[1] for xf in xformed ]
- timer.stop()
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def _sortBuilders(self, buildernames):
- timer = metrics.Timer("BuildRequestDistributor._sortBuilders()")
- timer.start()
- # note that this takes and returns a list of builder names
-
- # convert builder names to builders
- builders_dict = self.botmaster.builders
- builders = [ builders_dict.get(n)
- for n in buildernames
- if n in builders_dict ]
-
- # find a sorting function
- sorter = self.master.config.prioritizeBuilders
- if not sorter:
- sorter = self._defaultSorter
-
- # run it
- try:
- builders = yield defer.maybeDeferred(lambda :
- sorter(self.master, builders))
- except Exception:
- log.err(Failure(), "prioritizing builders; order unspecified")
-
- # and return the names
- rv = [ b.name for b in builders ]
- timer.stop()
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def _activityLoop(self):
- self.active = True
-
- timer = metrics.Timer('BuildRequestDistributor._activityLoop()')
- timer.start()
-
- while 1:
- yield self.activity_lock.acquire()
-
- # lock pending_builders, pop an element from it, and release
- yield self.pending_builders_lock.acquire()
-
- # bail out if we shouldn't keep looping
- if not self.running or not self._pending_builders:
- self.pending_builders_lock.release()
- self.activity_lock.release()
- break
-
- bldr_name = self._pending_builders.pop(0)
- self.pending_builders_lock.release()
-
- # get the actual builder object
- bldr = self.botmaster.builders.get(bldr_name)
- try:
- if bldr:
- yield self._maybeStartBuildsOnBuilder(bldr)
- except Exception:
- log.err(Failure(),
- "from maybeStartBuild for builder '%s'" % (bldr_name,))
-
- self.activity_lock.release()
-
- timer.stop()
-
- self.active = False
- self._quiet()
-
- @defer.inlineCallbacks
- def _maybeStartBuildsOnBuilder(self, bldr):
- # create a chooser to give us our next builds
- # this object is temporary and will go away when we're done
-
- bc = self.createBuildChooser(bldr, self.master)
-
- while 1:
- slave, breqs = yield bc.chooseNextBuild()
- if not slave or not breqs:
- break
-
- # claim brid's
- brids = [ br.id for br in breqs ]
- try:
- yield self.master.db.buildrequests.claimBuildRequests(brids)
- except AlreadyClaimedError:
- # some brids were already claimed, so start over
- bc = self.createBuildChooser(bldr, self.master)
- continue
-
- buildStarted = yield bldr.maybeStartBuild(slave, breqs)
-
- if not buildStarted:
- yield self.master.db.buildrequests.unclaimBuildRequests(brids)
-
- # and try starting builds again. If we still have a working slave,
- # then this may re-claim the same buildrequests
- self.botmaster.maybeStartBuildsForBuilder(self.name)
-
- def createBuildChooser(self, bldr, master):
- # just instantiate the build chooser requested
- return self.BuildChooser(bldr, master)
-
- def _quiet(self):
- # shim for tests
- pass # pragma: no cover
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py
deleted file mode 100644
index c8272aa4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py
+++ /dev/null
@@ -1,985 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-
-from zope.interface import implements
-from twisted.internet import defer, error
-from twisted.protocols import basic
-from twisted.spread import pb
-from twisted.python import log, components
-from twisted.python.failure import Failure
-from twisted.web.util import formatFailure
-from twisted.python.reflect import accumulateClassList
-
-from buildbot import interfaces, util, config
-from buildbot.status import progress
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED, \
- EXCEPTION, RETRY, worst_status
-from buildbot.process import metrics, properties
-from buildbot.util.eventual import eventually
-
-class BuildStepFailed(Exception):
- pass
-
-class RemoteCommand(pb.Referenceable):
-
- # class-level unique identifier generator for command ids
- _commandCounter = 0
-
- active = False
- rc = None
- debug = False
-
- def __init__(self, remote_command, args, ignore_updates=False,
- collectStdout=False, collectStderr=False, decodeRC={0:SUCCESS}):
- self.logs = {}
- self.delayedLogs = {}
- self._closeWhenFinished = {}
- self.collectStdout = collectStdout
- self.collectStderr = collectStderr
- self.stdout = ''
- self.stderr = ''
-
- self._startTime = None
- self._remoteElapsed = None
- self.remote_command = remote_command
- self.args = args
- self.ignore_updates = ignore_updates
- self.decodeRC = decodeRC
-
- def __repr__(self):
- return "<RemoteCommand '%s' at %d>" % (self.remote_command, id(self))
-
- def run(self, step, remote):
- self.active = True
- self.step = step
- self.remote = remote
-
- # generate a new command id
- cmd_id = RemoteCommand._commandCounter
- RemoteCommand._commandCounter += 1
- self.commandID = "%d" % cmd_id
-
- log.msg("%s: RemoteCommand.run [%s]" % (self, self.commandID))
- self.deferred = defer.Deferred()
-
- d = defer.maybeDeferred(self._start)
-
- # _finished is called with an error for unknown commands, errors
- # that occur while the command is starting (including OSErrors in
- # exec()), StaleBroker (when the connection was lost before we
- # started), and pb.PBConnectionLost (when the slave isn't responding
- # over this connection, perhaps it had a power failure, or NAT
- # weirdness). If this happens, self.deferred is fired right away.
- d.addErrback(self._finished)
-
- # Connections which are lost while the command is running are caught
- # when our parent Step calls our .lostRemote() method.
- return self.deferred
-
- def useLog(self, log, closeWhenFinished=False, logfileName=None):
- assert interfaces.ILogFile.providedBy(log)
- if not logfileName:
- logfileName = log.getName()
- assert logfileName not in self.logs
- assert logfileName not in self.delayedLogs
- self.logs[logfileName] = log
- self._closeWhenFinished[logfileName] = closeWhenFinished
-
- def useLogDelayed(self, logfileName, activateCallBack, closeWhenFinished=False):
- assert logfileName not in self.logs
- assert logfileName not in self.delayedLogs
- self.delayedLogs[logfileName] = (activateCallBack, closeWhenFinished)
-
- def _start(self):
- self.updates = {}
- self._startTime = util.now()
-
- # This method only initiates the remote command.
- # We will receive remote_update messages as the command runs.
- # We will get a single remote_complete when it finishes.
- # We should fire self.deferred when the command is done.
- d = self.remote.callRemote("startCommand", self, self.commandID,
- self.remote_command, self.args)
- return d
-
- def _finished(self, failure=None):
- self.active = False
- # call .remoteComplete. If it raises an exception, or returns the
- # Failure that we gave it, our self.deferred will be errbacked. If
- # it does not (either it ate the Failure or there the step finished
- # normally and it didn't raise a new exception), self.deferred will
- # be callbacked.
- d = defer.maybeDeferred(self.remoteComplete, failure)
- # arrange for the callback to get this RemoteCommand instance
- # instead of just None
- d.addCallback(lambda r: self)
- # this fires the original deferred we returned from .run(),
- # with self as the result, or a failure
- d.addBoth(self.deferred.callback)
-
- def interrupt(self, why):
- log.msg("RemoteCommand.interrupt", self, why)
- if not self.active:
- log.msg(" but this RemoteCommand is already inactive")
- return defer.succeed(None)
- if not self.remote:
- log.msg(" but our .remote went away")
- return defer.succeed(None)
- if isinstance(why, Failure) and why.check(error.ConnectionLost):
- log.msg("RemoteCommand.disconnect: lost slave")
- self.remote = None
- self._finished(why)
- return defer.succeed(None)
-
- # tell the remote command to halt. Returns a Deferred that will fire
- # when the interrupt command has been delivered.
-
- d = defer.maybeDeferred(self.remote.callRemote, "interruptCommand",
- self.commandID, str(why))
- # the slave may not have remote_interruptCommand
- d.addErrback(self._interruptFailed)
- return d
-
- def _interruptFailed(self, why):
- log.msg("RemoteCommand._interruptFailed", self)
- # TODO: forcibly stop the Command now, since we can't stop it
- # cleanly
- return None
-
- def remote_update(self, updates):
- """
- I am called by the slave's L{buildbot.slave.bot.SlaveBuilder} so
- I can receive updates from the running remote command.
-
- @type updates: list of [object, int]
- @param updates: list of updates from the remote command
- """
- self.buildslave.messageReceivedFromSlave()
- max_updatenum = 0
- for (update, num) in updates:
- #log.msg("update[%d]:" % num)
- try:
- if self.active and not self.ignore_updates:
- self.remoteUpdate(update)
- except:
- # log failure, terminate build, let slave retire the update
- self._finished(Failure())
- # TODO: what if multiple updates arrive? should
- # skip the rest but ack them all
- if num > max_updatenum:
- max_updatenum = num
- return max_updatenum
-
- def remote_complete(self, failure=None):
- """
- Called by the slave's L{buildbot.slave.bot.SlaveBuilder} to
- notify me the remote command has finished.
-
- @type failure: L{twisted.python.failure.Failure} or None
-
- @rtype: None
- """
- self.buildslave.messageReceivedFromSlave()
- # call the real remoteComplete a moment later, but first return an
- # acknowledgement so the slave can retire the completion message.
- if self.active:
- eventually(self._finished, failure)
- return None
-
- def addStdout(self, data):
- if 'stdio' in self.logs:
- self.logs['stdio'].addStdout(data)
- if self.collectStdout:
- self.stdout += data
-
- def addStderr(self, data):
- if 'stdio' in self.logs:
- self.logs['stdio'].addStderr(data)
- if self.collectStderr:
- self.stderr += data
-
- def addHeader(self, data):
- if 'stdio' in self.logs:
- self.logs['stdio'].addHeader(data)
-
- def addToLog(self, logname, data):
- # Activate delayed logs on first data.
- if logname in self.delayedLogs:
- (activateCallBack, closeWhenFinished) = self.delayedLogs[logname]
- del self.delayedLogs[logname]
- loog = activateCallBack(self)
- self.logs[logname] = loog
- self._closeWhenFinished[logname] = closeWhenFinished
-
- if logname in self.logs:
- self.logs[logname].addStdout(data)
- else:
- log.msg("%s.addToLog: no such log %s" % (self, logname))
-
- @metrics.countMethod('RemoteCommand.remoteUpdate()')
- def remoteUpdate(self, update):
- if self.debug:
- for k,v in update.items():
- log.msg("Update[%s]: %s" % (k,v))
- if update.has_key('stdout'):
- # 'stdout': data
- self.addStdout(update['stdout'])
- if update.has_key('stderr'):
- # 'stderr': data
- self.addStderr(update['stderr'])
- if update.has_key('header'):
- # 'header': data
- self.addHeader(update['header'])
- if update.has_key('log'):
- # 'log': (logname, data)
- logname, data = update['log']
- self.addToLog(logname, data)
- if update.has_key('rc'):
- rc = self.rc = update['rc']
- log.msg("%s rc=%s" % (self, rc))
- self.addHeader("program finished with exit code %d\n" % rc)
- if update.has_key('elapsed'):
- self._remoteElapsed = update['elapsed']
-
- # TODO: these should be handled at the RemoteCommand level
- for k in update:
- if k not in ('stdout', 'stderr', 'header', 'rc'):
- if k not in self.updates:
- self.updates[k] = []
- self.updates[k].append(update[k])
-
- def remoteComplete(self, maybeFailure):
- if self._startTime and self._remoteElapsed:
- delta = (util.now() - self._startTime) - self._remoteElapsed
- metrics.MetricTimeEvent.log("RemoteCommand.overhead", delta)
-
- for name,loog in self.logs.items():
- if self._closeWhenFinished[name]:
- if maybeFailure:
- loog.addHeader("\nremoteFailed: %s" % maybeFailure)
- else:
- log.msg("closing log %s" % loog)
- loog.finish()
- return maybeFailure
-
- def results(self):
- if self.rc in self.decodeRC:
- return self.decodeRC[self.rc]
- return FAILURE
-
- def didFail(self):
- return self.results() == FAILURE
-LoggedRemoteCommand = RemoteCommand
-
-
-class LogObserver:
- implements(interfaces.ILogObserver)
-
- def setStep(self, step):
- self.step = step
-
- def setLog(self, loog):
- assert interfaces.IStatusLog.providedBy(loog)
- loog.subscribe(self, True)
-
- def logChunk(self, build, step, log, channel, text):
- if channel == interfaces.LOG_CHANNEL_STDOUT:
- self.outReceived(text)
- elif channel == interfaces.LOG_CHANNEL_STDERR:
- self.errReceived(text)
-
- # TODO: add a logEnded method? er, stepFinished?
-
- def outReceived(self, data):
- """This will be called with chunks of stdout data. Override this in
- your observer."""
- pass
-
- def errReceived(self, data):
- """This will be called with chunks of stderr data. Override this in
- your observer."""
- pass
-
-
-class LogLineObserver(LogObserver):
- def __init__(self):
- self.stdoutParser = basic.LineOnlyReceiver()
- self.stdoutParser.delimiter = "\n"
- self.stdoutParser.lineReceived = self.outLineReceived
- self.stdoutParser.transport = self # for the .disconnecting attribute
- self.disconnecting = False
-
- self.stderrParser = basic.LineOnlyReceiver()
- self.stderrParser.delimiter = "\n"
- self.stderrParser.lineReceived = self.errLineReceived
- self.stderrParser.transport = self
-
- def setMaxLineLength(self, max_length):
- """
- Set the maximum line length: lines longer than max_length are
- dropped. Default is 16384 bytes. Use sys.maxint for effective
- infinity.
- """
- self.stdoutParser.MAX_LENGTH = max_length
- self.stderrParser.MAX_LENGTH = max_length
-
- def outReceived(self, data):
- self.stdoutParser.dataReceived(data)
-
- def errReceived(self, data):
- self.stderrParser.dataReceived(data)
-
- def outLineReceived(self, line):
- """This will be called with complete stdout lines (not including the
- delimiter). Override this in your observer."""
- pass
-
- def errLineReceived(self, line):
- """This will be called with complete lines of stderr (not including
- the delimiter). Override this in your observer."""
- pass
-
-
-class RemoteShellCommand(RemoteCommand):
- def __init__(self, workdir, command, env=None,
- want_stdout=1, want_stderr=1,
- timeout=20*60, maxTime=None, logfiles={},
- usePTY="slave-config", logEnviron=True,
- collectStdout=False,collectStderr=False,
- interruptSignal=None,
- initialStdin=None, decodeRC={0:SUCCESS}):
-
- self.command = command # stash .command, set it later
- if env is not None:
- # avoid mutating the original master.cfg dictionary. Each
- # ShellCommand gets its own copy, any start() methods won't be
- # able to modify the original.
- env = env.copy()
- args = {'workdir': workdir,
- 'env': env,
- 'want_stdout': want_stdout,
- 'want_stderr': want_stderr,
- 'logfiles': logfiles,
- 'timeout': timeout,
- 'maxTime': maxTime,
- 'usePTY': usePTY,
- 'logEnviron': logEnviron,
- 'initial_stdin': initialStdin
- }
- if interruptSignal is not None:
- args['interruptSignal'] = interruptSignal
- RemoteCommand.__init__(self, "shell", args, collectStdout=collectStdout,
- collectStderr=collectStderr,
- decodeRC=decodeRC)
-
- def _start(self):
- self.args['command'] = self.command
- if self.remote_command == "shell":
- # non-ShellCommand slavecommands are responsible for doing this
- # fixup themselves
- if self.step.slaveVersion("shell", "old") == "old":
- self.args['dir'] = self.args['workdir']
- what = "command '%s' in dir '%s'" % (self.args['command'],
- self.args['workdir'])
- log.msg(what)
- return RemoteCommand._start(self)
-
- def __repr__(self):
- return "<RemoteShellCommand '%s'>" % repr(self.command)
-
-class _BuildStepFactory(util.ComparableMixin):
- """
- This is a wrapper to record the arguments passed to as BuildStep subclass.
- We use an instance of this class, rather than a closure mostly to make it
- easier to test that the right factories are getting created.
- """
- compare_attrs = ['factory', 'args', 'kwargs' ]
- implements(interfaces.IBuildStepFactory)
-
- def __init__(self, factory, *args, **kwargs):
- self.factory = factory
- self.args = args
- self.kwargs = kwargs
-
- def buildStep(self):
- try:
- return self.factory(*self.args, **self.kwargs)
- except:
- log.msg("error while creating step, factory=%s, args=%s, kwargs=%s"
- % (self.factory, self.args, self.kwargs))
- raise
-
-class BuildStep(object, properties.PropertiesMixin):
-
- haltOnFailure = False
- flunkOnWarnings = False
- flunkOnFailure = False
- warnOnWarnings = False
- warnOnFailure = False
- alwaysRun = False
- doStepIf = True
- hideStepIf = False
-
- # properties set on a build step are, by nature, always runtime properties
- set_runtime_properties = True
-
- # 'parms' holds a list of all the parameters we care about, to allow
- # users to instantiate a subclass of BuildStep with a mixture of
- # arguments, some of which are for us, some of which are for the subclass
- # (or a delegate of the subclass, like how ShellCommand delivers many
- # arguments to the RemoteShellCommand that it creates). Such delegating
- # subclasses will use this list to figure out which arguments are meant
- # for us and which should be given to someone else.
- parms = ['name', 'locks',
- 'haltOnFailure',
- 'flunkOnWarnings',
- 'flunkOnFailure',
- 'warnOnWarnings',
- 'warnOnFailure',
- 'alwaysRun',
- 'progressMetrics',
- 'useProgress',
- 'doStepIf',
- 'hideStepIf',
- ]
-
- name = "generic"
- locks = []
- progressMetrics = () # 'time' is implicit
- useProgress = True # set to False if step is really unpredictable
- build = None
- step_status = None
- progress = None
-
- def __init__(self, **kwargs):
- for p in self.__class__.parms:
- if kwargs.has_key(p):
- setattr(self, p, kwargs[p])
- del kwargs[p]
- if kwargs:
- config.error("%s.__init__ got unexpected keyword argument(s) %s" \
- % (self.__class__, kwargs.keys()))
- self._pendingLogObservers = []
-
- if not isinstance(self.name, str):
- config.error("BuildStep name must be a string: %r" % (self.name,))
-
- self._acquiringLock = None
- self.stopped = False
-
- def __new__(klass, *args, **kwargs):
- self = object.__new__(klass)
- self._factory = _BuildStepFactory(klass, *args, **kwargs)
- return self
-
- def describe(self, done=False):
- return [self.name]
-
- def setBuild(self, build):
- self.build = build
-
- def setBuildSlave(self, buildslave):
- self.buildslave = buildslave
-
- def setDefaultWorkdir(self, workdir):
- pass
-
- def addFactoryArguments(self, **kwargs):
- # this is here for backwards compatability
- pass
-
- def _getStepFactory(self):
- return self._factory
-
- def setStepStatus(self, step_status):
- self.step_status = step_status
-
- def setupProgress(self):
- if self.useProgress:
- sp = progress.StepProgress(self.name, self.progressMetrics)
- self.progress = sp
- self.step_status.setProgress(sp)
- return sp
- return None
-
- def setProgress(self, metric, value):
- if self.progress:
- self.progress.setProgress(metric, value)
-
- def startStep(self, remote):
- self.remote = remote
- self.deferred = defer.Deferred()
- # convert all locks into their real form
- self.locks = [(self.build.builder.botmaster.getLockByID(access.lockid), access)
- for access in self.locks ]
- # then narrow SlaveLocks down to the slave that this build is being
- # run on
- self.locks = [(l.getLock(self.build.slavebuilder.slave), la)
- for l, la in self.locks ]
-
- for l, la in self.locks:
- if l in self.build.locks:
- log.msg("Hey, lock %s is claimed by both a Step (%s) and the"
- " parent Build (%s)" % (l, self, self.build))
- raise RuntimeError("lock claimed by both Step and Build")
-
- # Set the step's text here so that the stepStarted notification sees
- # the correct description
- self.step_status.setText(self.describe(False))
- self.step_status.stepStarted()
-
- d = self.acquireLocks()
- d.addCallback(self._startStep_2)
- d.addErrback(self.failed)
- return self.deferred
-
- def acquireLocks(self, res=None):
- self._acquiringLock = None
- if not self.locks:
- return defer.succeed(None)
- if self.stopped:
- return defer.succeed(None)
- log.msg("acquireLocks(step %s, locks %s)" % (self, self.locks))
- for lock, access in self.locks:
- if not lock.isAvailable(self, access):
- self.step_status.setWaitingForLocks(True)
- log.msg("step %s waiting for lock %s" % (self, lock))
- d = lock.waitUntilMaybeAvailable(self, access)
- d.addCallback(self.acquireLocks)
- self._acquiringLock = (lock, access, d)
- return d
- # all locks are available, claim them all
- for lock, access in self.locks:
- lock.claim(self, access)
- self.step_status.setWaitingForLocks(False)
- return defer.succeed(None)
-
- def _startStep_2(self, res):
- if self.stopped:
- self.finished(EXCEPTION)
- return
-
- if self.progress:
- self.progress.start()
-
- if isinstance(self.doStepIf, bool):
- doStep = defer.succeed(self.doStepIf)
- else:
- doStep = defer.maybeDeferred(self.doStepIf, self)
-
- renderables = []
- accumulateClassList(self.__class__, 'renderables', renderables)
-
- def setRenderable(res, attr):
- setattr(self, attr, res)
-
- dl = [ doStep ]
- for renderable in renderables:
- d = self.build.render(getattr(self, renderable))
- d.addCallback(setRenderable, renderable)
- dl.append(d)
- dl = defer.gatherResults(dl)
-
- dl.addCallback(self._startStep_3)
- return dl
-
- @defer.inlineCallbacks
- def _startStep_3(self, doStep):
- doStep = doStep[0]
- try:
- if doStep:
- result = yield defer.maybeDeferred(self.start)
- if result == SKIPPED:
- doStep = False
- except:
- log.msg("BuildStep.startStep exception in .start")
- self.failed(Failure())
-
- if not doStep:
- self.step_status.setText(self.describe(True) + ['skipped'])
- self.step_status.setSkipped(True)
- # this return value from self.start is a shortcut to finishing
- # the step immediately; we skip calling finished() as
- # subclasses may have overridden that an expect it to be called
- # after start() (bug #837)
- eventually(self._finishFinished, SKIPPED)
-
- def start(self):
- raise NotImplementedError("your subclass must implement this method")
-
- def interrupt(self, reason):
- self.stopped = True
- if self._acquiringLock:
- lock, access, d = self._acquiringLock
- lock.stopWaitingUntilAvailable(self, access, d)
- d.callback(None)
-
- def releaseLocks(self):
- log.msg("releaseLocks(%s): %s" % (self, self.locks))
- for lock, access in self.locks:
- if lock.isOwner(self, access):
- lock.release(self, access)
- else:
- # This should only happen if we've been interrupted
- assert self.stopped
-
- def finished(self, results):
- if self.stopped and results != RETRY:
- # We handle this specially because we don't care about
- # the return code of an interrupted command; we know
- # that this should just be exception due to interrupt
- # At the same time we must respect RETRY status because it's used
- # to retry interrupted build due to some other issues for example
- # due to slave lost
- results = EXCEPTION
- self.step_status.setText(self.describe(True) +
- ["interrupted"])
- self.step_status.setText2(["interrupted"])
- self._finishFinished(results)
-
- def _finishFinished(self, results):
- # internal function to indicate that this step is done; this is separated
- # from finished() so that subclasses can override finished()
- if self.progress:
- self.progress.finish()
-
- try:
- hidden = self._maybeEvaluate(self.hideStepIf, results, self)
- except Exception:
- why = Failure()
- self.addHTMLLog("err.html", formatFailure(why))
- self.addCompleteLog("err.text", why.getTraceback())
- results = EXCEPTION
- hidden = False
-
- self.step_status.stepFinished(results)
- self.step_status.setHidden(hidden)
-
- self.releaseLocks()
- self.deferred.callback(results)
-
- def failed(self, why):
- # This can either be a BuildStepFailed exception/failure, meaning we
- # should call self.finished, or it can be a real exception, which should
- # be recorded as such.
- if why.check(BuildStepFailed):
- self.finished(FAILURE)
- return
-
- log.err(why, "BuildStep.failed; traceback follows")
- try:
- if self.progress:
- self.progress.finish()
- try:
- self.addCompleteLog("err.text", why.getTraceback())
- self.addHTMLLog("err.html", formatFailure(why))
- except Exception:
- log.err(Failure(), "error while formatting exceptions")
-
- # could use why.getDetailedTraceback() for more information
- self.step_status.setText([self.name, "exception"])
- self.step_status.setText2([self.name])
- self.step_status.stepFinished(EXCEPTION)
-
- hidden = self._maybeEvaluate(self.hideStepIf, EXCEPTION, self)
- self.step_status.setHidden(hidden)
- except Exception:
- log.err(Failure(), "exception during failure processing")
- # the progress stuff may still be whacked (the StepStatus may
- # think that it is still running), but the build overall will now
- # finish
-
- try:
- self.releaseLocks()
- except Exception:
- log.err(Failure(), "exception while releasing locks")
-
- log.msg("BuildStep.failed now firing callback")
- self.deferred.callback(EXCEPTION)
-
- # utility methods that BuildSteps may find useful
-
- def slaveVersion(self, command, oldversion=None):
- return self.build.getSlaveCommandVersion(command, oldversion)
-
- def slaveVersionIsOlderThan(self, command, minversion):
- sv = self.build.getSlaveCommandVersion(command, None)
- if sv is None:
- return True
- if map(int, sv.split(".")) < map(int, minversion.split(".")):
- return True
- return False
-
- def getSlaveName(self):
- return self.build.getSlaveName()
-
- def addLog(self, name):
- loog = self.step_status.addLog(name)
- self._connectPendingLogObservers()
- return loog
-
- def getLog(self, name):
- for l in self.step_status.getLogs():
- if l.getName() == name:
- return l
- raise KeyError("no log named '%s'" % (name,))
-
- def addCompleteLog(self, name, text):
- log.msg("addCompleteLog(%s)" % name)
- loog = self.step_status.addLog(name)
- size = loog.chunkSize
- for start in range(0, len(text), size):
- loog.addStdout(text[start:start+size])
- loog.finish()
- self._connectPendingLogObservers()
-
- def addHTMLLog(self, name, html):
- log.msg("addHTMLLog(%s)" % name)
- self.step_status.addHTMLLog(name, html)
- self._connectPendingLogObservers()
-
- def addLogObserver(self, logname, observer):
- assert interfaces.ILogObserver.providedBy(observer)
- observer.setStep(self)
- self._pendingLogObservers.append((logname, observer))
- self._connectPendingLogObservers()
-
- def _connectPendingLogObservers(self):
- if not self._pendingLogObservers:
- return
- if not self.step_status:
- return
- current_logs = {}
- for loog in self.step_status.getLogs():
- current_logs[loog.getName()] = loog
- for logname, observer in self._pendingLogObservers[:]:
- if logname in current_logs:
- observer.setLog(current_logs[logname])
- self._pendingLogObservers.remove((logname, observer))
-
- def addURL(self, name, url):
- self.step_status.addURL(name, url)
-
- def runCommand(self, c):
- c.buildslave = self.buildslave
- d = c.run(self, self.remote)
- return d
-
- @staticmethod
- def _maybeEvaluate(value, *args, **kwargs):
- if callable(value):
- value = value(*args, **kwargs)
- return value
-
-components.registerAdapter(
- BuildStep._getStepFactory,
- BuildStep, interfaces.IBuildStepFactory)
-components.registerAdapter(
- lambda step : interfaces.IProperties(step.build),
- BuildStep, interfaces.IProperties)
-
-
-class OutputProgressObserver(LogObserver):
- length = 0
-
- def __init__(self, name):
- self.name = name
-
- def logChunk(self, build, step, log, channel, text):
- self.length += len(text)
- self.step.setProgress(self.name, self.length)
-
-class LoggingBuildStep(BuildStep):
-
- progressMetrics = ('output',)
- logfiles = {}
-
- parms = BuildStep.parms + ['logfiles', 'lazylogfiles', 'log_eval_func']
- cmd = None
-
- renderables = [ 'logfiles', 'lazylogfiles' ]
-
- def __init__(self, logfiles={}, lazylogfiles=False, log_eval_func=None,
- *args, **kwargs):
- BuildStep.__init__(self, *args, **kwargs)
-
- if logfiles and not isinstance(logfiles, dict):
- config.error(
- "the ShellCommand 'logfiles' parameter must be a dictionary")
-
- # merge a class-level 'logfiles' attribute with one passed in as an
- # argument
- self.logfiles = self.logfiles.copy()
- self.logfiles.update(logfiles)
- self.lazylogfiles = lazylogfiles
- if log_eval_func and not callable(log_eval_func):
- config.error(
- "the 'log_eval_func' paramater must be a callable")
- self.log_eval_func = log_eval_func
- self.addLogObserver('stdio', OutputProgressObserver("output"))
-
- def addLogFile(self, logname, filename):
- self.logfiles[logname] = filename
-
- def buildCommandKwargs(self):
- kwargs = dict()
- kwargs['logfiles'] = self.logfiles
- return kwargs
-
- def startCommand(self, cmd, errorMessages=[]):
- """
- @param cmd: a suitable RemoteCommand which will be launched, with
- all output being put into our self.stdio_log LogFile
- """
- log.msg("ShellCommand.startCommand(cmd=%s)" % (cmd,))
- log.msg(" cmd.args = %r" % (cmd.args))
- self.cmd = cmd # so we can interrupt it
- self.step_status.setText(self.describe(False))
-
- # stdio is the first log
- self.stdio_log = stdio_log = self.addLog("stdio")
- cmd.useLog(stdio_log, True)
- for em in errorMessages:
- stdio_log.addHeader(em)
- # TODO: consider setting up self.stdio_log earlier, and have the
- # code that passes in errorMessages instead call
- # self.stdio_log.addHeader() directly.
-
- # there might be other logs
- self.setupLogfiles(cmd, self.logfiles)
-
- d = self.runCommand(cmd) # might raise ConnectionLost
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addCallback(lambda res: self.createSummary(cmd.logs['stdio']))
- d.addCallback(lambda res: self.evaluateCommand(cmd)) # returns results
- def _gotResults(results):
- self.setStatus(cmd, results)
- return results
- d.addCallback(_gotResults) # returns results
- d.addCallbacks(self.finished, self.checkDisconnect)
- d.addErrback(self.failed)
-
- def setupLogfiles(self, cmd, logfiles):
- for logname,remotefilename in logfiles.items():
- if self.lazylogfiles:
- # Ask RemoteCommand to watch a logfile, but only add
- # it when/if we see any data.
- #
- # The dummy default argument local_logname is a work-around for
- # Python name binding; default values are bound by value, but
- # captured variables in the body are bound by name.
- callback = lambda cmd_arg, local_logname=logname: self.addLog(local_logname)
- cmd.useLogDelayed(logname, callback, True)
- else:
- # tell the BuildStepStatus to add a LogFile
- newlog = self.addLog(logname)
- # and tell the RemoteCommand to feed it
- cmd.useLog(newlog, True)
-
- def interrupt(self, reason):
- # TODO: consider adding an INTERRUPTED or STOPPED status to use
- # instead of FAILURE, might make the text a bit more clear.
- # 'reason' can be a Failure, or text
- BuildStep.interrupt(self, reason)
- if self.step_status.isWaitingForLocks():
- self.addCompleteLog('interrupt while waiting for locks', str(reason))
- else:
- self.addCompleteLog('interrupt', str(reason))
-
- if self.cmd:
- d = self.cmd.interrupt(reason)
- d.addErrback(log.err, 'while interrupting command')
-
- def checkDisconnect(self, f):
- f.trap(error.ConnectionLost)
- self.step_status.setText(self.describe(True) +
- ["exception", "slave", "lost"])
- self.step_status.setText2(["exception", "slave", "lost"])
- return self.finished(RETRY)
-
- def commandComplete(self, cmd):
- pass
-
- def createSummary(self, stdio):
- pass
-
- def evaluateCommand(self, cmd):
- if self.log_eval_func:
- return self.log_eval_func(cmd, self.step_status)
- return cmd.results()
-
- def getText(self, cmd, results):
- if results == SUCCESS:
- return self.describe(True)
- elif results == WARNINGS:
- return self.describe(True) + ["warnings"]
- elif results == EXCEPTION:
- return self.describe(True) + ["exception"]
- else:
- return self.describe(True) + ["failed"]
-
- def getText2(self, cmd, results):
- return [self.name]
-
- def maybeGetText2(self, cmd, results):
- if results == SUCCESS:
- # successful steps do not add anything to the build's text
- pass
- elif results == WARNINGS:
- if (self.flunkOnWarnings or self.warnOnWarnings):
- # we're affecting the overall build, so tell them why
- return self.getText2(cmd, results)
- else:
- if (self.haltOnFailure or self.flunkOnFailure
- or self.warnOnFailure):
- # we're affecting the overall build, so tell them why
- return self.getText2(cmd, results)
- return []
-
- def setStatus(self, cmd, results):
- # this is good enough for most steps, but it can be overridden to
- # get more control over the displayed text
- self.step_status.setText(self.getText(cmd, results))
- self.step_status.setText2(self.maybeGetText2(cmd, results))
-
-
-# Parses the logs for a list of regexs. Meant to be invoked like:
-# regexes = ((re.compile(...), FAILURE), (re.compile(...), WARNINGS))
-# self.addStep(ShellCommand,
-# command=...,
-# ...,
-# log_eval_func=lambda c,s: regex_log_evaluator(c, s, regexs)
-# )
-def regex_log_evaluator(cmd, step_status, regexes):
- worst = cmd.results()
- for err, possible_status in regexes:
- # worst_status returns the worse of the two status' passed to it.
- # we won't be changing "worst" unless possible_status is worse than it,
- # so we don't even need to check the log if that's the case
- if worst_status(worst, possible_status) == possible_status:
- if isinstance(err, (basestring)):
- err = re.compile(".*%s.*" % err, re.DOTALL)
- for l in cmd.logs.values():
- if err.search(l.getText()):
- worst = possible_status
- return worst
-
-# (WithProperties used to be available in this module)
-from buildbot.process.properties import WithProperties
-_hush_pyflakes = [WithProperties]
-del _hush_pyflakes
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py
deleted file mode 100644
index fbc0051d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.util import lru
-from buildbot import config
-from twisted.application import service
-
-class CacheManager(config.ReconfigurableServiceMixin, service.Service):
- """
- A manager for a collection of caches, each for different types of objects
- and with potentially-overlapping key spaces.
-
- There is generally only one instance of this class, available at
- C{master.caches}.
- """
-
- # a cache of length one still has many benefits: it collects objects that
- # remain referenced elsewhere; it collapses simultaneous misses into one
- # miss function; and it will optimize repeated fetches of the same object.
- DEFAULT_CACHE_SIZE = 1
-
- def __init__(self):
- self.setName('caches')
- self.config = {}
- self._caches = {}
-
- def get_cache(self, cache_name, miss_fn):
- """
- Get an L{AsyncLRUCache} object with the given name. If such an object
- does not exist, it will be created. Since the cache is permanent, this
- method can be called only once, e.g., in C{startService}, and it value
- stored indefinitely.
-
- @param cache_name: name of the cache (usually the name of the type of
- object it stores)
- @param miss_fn: miss function for the cache; see L{AsyncLRUCache}
- constructor.
- @returns: L{AsyncLRUCache} instance
- """
- try:
- return self._caches[cache_name]
- except KeyError:
- max_size = self.config.get(cache_name, self.DEFAULT_CACHE_SIZE)
- assert max_size >= 1
- c = self._caches[cache_name] = lru.AsyncLRUCache(miss_fn, max_size)
- return c
-
- def reconfigService(self, new_config):
- self.config = new_config.caches
- for name, cache in self._caches.iteritems():
- cache.set_max_size(new_config.caches.get(name,
- self.DEFAULT_CACHE_SIZE))
-
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def get_metrics(self):
- return dict([
- (n, dict(hits=c.hits, refhits=c.refhits,
- misses=c.misses, max_size=c.max_size))
- for n, c in self._caches.iteritems()])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py
deleted file mode 100644
index 485928e7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python import log
-from twisted.internet import defer
-from twisted.application import service
-from buildbot.pbutil import NewCredPerspective
-from buildbot.sourcestamp import SourceStamp
-from buildbot import interfaces, config
-from buildbot.process.properties import Properties
-
-class DebugServices(config.ReconfigurableServiceMixin, service.MultiService):
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('debug_services')
- self.master = master
-
- self.debug_port = None
- self.debug_password = None
- self.debug_registration = None
- self.manhole = None
-
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
-
- # debug client
- config_changed = (self.debug_port != new_config.slavePortnum or
- self.debug_password != new_config.debugPassword)
-
- if not new_config.debugPassword or config_changed:
- if self.debug_registration:
- yield self.debug_registration.unregister()
- self.debug_registration = None
-
- if new_config.debugPassword and config_changed:
- factory = lambda mind, user : DebugPerspective(self.master)
- self.debug_registration = self.master.pbmanager.register(
- new_config.slavePortnum, "debug", new_config.debugPassword,
- factory)
-
- self.debug_password = new_config.debugPassword
- if self.debug_password:
- self.debug_port = new_config.slavePortnum
- else:
- self.debug_port = None
-
- # manhole
- if new_config.manhole != self.manhole:
- if self.manhole:
- yield defer.maybeDeferred(lambda :
- self.manhole.disownServiceParent())
- self.manhole.master = None
- self.manhole = None
-
- if new_config.manhole:
- self.manhole = new_config.manhole
- self.manhole.master = self.master
- self.manhole.setServiceParent(self)
-
- # chain up
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
-
- @defer.inlineCallbacks
- def stopService(self):
- if self.debug_registration:
- yield self.debug_registration.unregister()
- self.debug_registration = None
-
- # manhole will get stopped as a sub-service
-
- yield defer.maybeDeferred(lambda :
- service.MultiService.stopService(self))
-
- # clean up
- if self.manhole:
- self.manhole.master = None
- self.manhole = None
-
-
-class DebugPerspective(NewCredPerspective):
-
- def __init__(self, master):
- self.master = master
-
- def attached(self, mind):
- return self
-
- def detached(self, mind):
- pass
-
- def perspective_requestBuild(self, buildername, reason, branch,
- revision, properties={}):
- c = interfaces.IControl(self.master)
- bc = c.getBuilder(buildername)
- ss = SourceStamp(branch, revision)
- bpr = Properties()
- bpr.update(properties, "remote requestBuild")
- return bc.submitBuildRequest(ss, reason, bpr)
-
- def perspective_pingBuilder(self, buildername):
- c = interfaces.IControl(self.master)
- bc = c.getBuilder(buildername)
- bc.ping()
-
- def perspective_reload(self):
- log.msg("debug client - triggering master reconfig")
- self.master.reconfig()
-
- def perspective_pokeIRC(self):
- log.msg("saying something on IRC")
- from buildbot.status import words
- for s in self.master:
- if isinstance(s, words.IRC):
- bot = s.f
- for channel in bot.channels:
- print " channel", channel
- bot.p.msg(channel, "Ow, quit it")
-
- def perspective_print(self, msg):
- log.msg("debug %s" % msg)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py
deleted file mode 100644
index 5578a033..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import warnings
-from twisted.python import deprecate, versions
-
-from buildbot import interfaces, util
-from buildbot.process.build import Build
-from buildbot.process.buildstep import BuildStep
-from buildbot.steps.source import CVS, SVN
-from buildbot.steps.shell import Configure, Compile, Test, PerlModuleTest
-
-# deprecated, use BuildFactory.addStep
-@deprecate.deprecated(versions.Version("buildbot", 0, 8, 6))
-def s(steptype, **kwargs):
- # convenience function for master.cfg files, to create step
- # specification tuples
- return interfaces.IBuildStepFactory(steptype(**kwargs))
-
-
-class BuildFactory(util.ComparableMixin):
- """
- @cvar buildClass: class to use when creating builds
- @type buildClass: L{buildbot.process.build.Build}
- """
- buildClass = Build
- useProgress = 1
- workdir = "build"
- compare_attrs = ['buildClass', 'steps', 'useProgress', 'workdir']
-
- def __init__(self, steps=None):
- self.steps = []
- if steps:
- self.addSteps(steps)
-
- def newBuild(self, requests):
- """Create a new Build instance.
-
- @param requests: a list of buildrequest dictionaries describing what is
- to be built
- """
- b = self.buildClass(requests)
- b.useProgress = self.useProgress
- b.workdir = self.workdir
- b.setStepFactories(self.steps)
- return b
-
- def addStep(self, step, **kwargs):
- if kwargs or (type(step) == type(BuildStep) and issubclass(step, BuildStep)):
- warnings.warn(
- "Passing a BuildStep subclass to factory.addStep is "
- "deprecated. Please pass a BuildStep instance instead.",
- DeprecationWarning, stacklevel=2)
- step = step(**kwargs)
- self.steps.append(interfaces.IBuildStepFactory(step))
-
- def addSteps(self, steps):
- for s in steps:
- self.addStep(s)
-
-# BuildFactory subclasses for common build tools
-
-class GNUAutoconf(BuildFactory):
- def __init__(self, source, configure="./configure",
- configureEnv={},
- configureFlags=[],
- compile=["make", "all"],
- test=["make", "check"]):
- BuildFactory.__init__(self, [source])
- if configure is not None:
- # we either need to wind up with a string (which will be
- # space-split), or with a list of strings (which will not). The
- # list of strings is the preferred form.
- if type(configure) is str:
- if configureFlags:
- assert not " " in configure # please use list instead
- command = [configure] + configureFlags
- else:
- command = configure
- else:
- assert isinstance(configure, (list, tuple))
- command = configure + configureFlags
- self.addStep(Configure(command=command, env=configureEnv))
- if compile is not None:
- self.addStep(Compile(command=compile))
- if test is not None:
- self.addStep(Test(command=test))
-
-class CPAN(BuildFactory):
- def __init__(self, source, perl="perl"):
- BuildFactory.__init__(self, [source])
- self.addStep(Configure(command=[perl, "Makefile.PL"]))
- self.addStep(Compile(command=["make"]))
- self.addStep(PerlModuleTest(command=["make", "test"]))
-
-class Distutils(BuildFactory):
- def __init__(self, source, python="python", test=None):
- BuildFactory.__init__(self, [source])
- self.addStep(Compile(command=[python, "./setup.py", "build"]))
- if test is not None:
- self.addStep(Test(command=test))
-
-class Trial(BuildFactory):
- """Build a python module that uses distutils and trial. Set 'tests' to
- the module in which the tests can be found, or set useTestCaseNames=True
- to always have trial figure out which tests to run (based upon which
- files have been changed).
-
- See docs/factories.xhtml for usage samples. Not all of the Trial
- BuildStep options are available here, only the most commonly used ones.
- To get complete access, you will need to create a custom
- BuildFactory."""
-
- trial = "trial"
- randomly = False
- recurse = False
-
- def __init__(self, source,
- buildpython=["python"], trialpython=[], trial=None,
- testpath=".", randomly=None, recurse=None,
- tests=None, useTestCaseNames=False, env=None):
- BuildFactory.__init__(self, [source])
- assert tests or useTestCaseNames, "must use one or the other"
- if trial is not None:
- self.trial = trial
- if randomly is not None:
- self.randomly = randomly
- if recurse is not None:
- self.recurse = recurse
-
- from buildbot.steps.python_twisted import Trial
- buildcommand = buildpython + ["./setup.py", "build"]
- self.addStep(Compile(command=buildcommand, env=env))
- self.addStep(Trial(
- python=trialpython, trial=self.trial,
- testpath=testpath,
- tests=tests, testChanges=useTestCaseNames,
- randomly=self.randomly,
- recurse=self.recurse,
- env=env,
- ))
-
-
-# compatibility classes, will go away. Note that these only offer
-# compatibility at the constructor level: if you have subclassed these
-# factories, your subclasses are unlikely to still work correctly.
-
-ConfigurableBuildFactory = BuildFactory
-
-class BasicBuildFactory(GNUAutoconf):
- # really a "GNU Autoconf-created tarball -in-CVS tree" builder
-
- def __init__(self, cvsroot, cvsmodule,
- configure=None, configureEnv={},
- compile="make all",
- test="make check", cvsCopy=False):
- mode = "clobber"
- if cvsCopy:
- mode = "copy"
- source = CVS(cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode)
- GNUAutoconf.__init__(self, source,
- configure=configure, configureEnv=configureEnv,
- compile=compile,
- test=test)
-
-class QuickBuildFactory(BasicBuildFactory):
- useProgress = False
-
- def __init__(self, cvsroot, cvsmodule,
- configure=None, configureEnv={},
- compile="make all",
- test="make check", cvsCopy=False):
- mode = "update"
- source = CVS(cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode)
- GNUAutoconf.__init__(self, source,
- configure=configure, configureEnv=configureEnv,
- compile=compile,
- test=test)
-
-class BasicSVN(GNUAutoconf):
-
- def __init__(self, svnurl,
- configure=None, configureEnv={},
- compile="make all",
- test="make check"):
- source = SVN(svnurl=svnurl, mode="update")
- GNUAutoconf.__init__(self, source,
- configure=configure, configureEnv=configureEnv,
- compile=compile,
- test=test)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py
deleted file mode 100644
index d0f28bb3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py
+++ /dev/null
@@ -1,494 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-"""
-Buildbot metrics module
-
-Keeps track of counts and timings of various internal buildbot
-activities.
-
-Basic architecture:
-
- MetricEvent.log(...)
- ||
- \/
- MetricLogObserver
- ||
- \/
- MetricHandler
- ||
- \/
- MetricWatcher
-"""
-from collections import deque
-
-from twisted.python import log
-from twisted.internet.task import LoopingCall
-from twisted.internet import reactor
-from twisted.application import service
-from buildbot import util, config
-from collections import defaultdict
-
-import gc, os, sys
-# Make use of the resource module if we can
-try:
- import resource
- assert resource
-except ImportError:
- resource = None
-
-class MetricEvent(object):
- @classmethod
- def log(cls, *args, **kwargs):
- log.msg(metric=cls(*args, **kwargs))
-
-class MetricCountEvent(MetricEvent):
- def __init__(self, counter, count=1, absolute=False):
- self.counter = counter
- self.count = count
- self.absolute = absolute
-
-class MetricTimeEvent(MetricEvent):
- def __init__(self, timer, elapsed):
- self.timer = timer
- self.elapsed = elapsed
-
-ALARM_OK, ALARM_WARN, ALARM_CRIT = range(3)
-ALARM_TEXT = ["OK", "WARN", "CRIT"]
-
-class MetricAlarmEvent(MetricEvent):
- def __init__(self, alarm, msg=None, level=ALARM_OK):
- self.alarm = alarm
- self.level = level
- self.msg = msg
-
-def countMethod(counter):
- def decorator(func):
- def wrapper(*args, **kwargs):
- MetricCountEvent.log(counter=counter)
- return func(*args, **kwargs)
- return wrapper
- return decorator
-
-class Timer(object):
- # For testing
- _reactor = None
-
- def __init__(self, name):
- self.name = name
- self.started = None
-
- def startTimer(self, func):
- def wrapper(*args, **kwargs):
- self.start()
- return func(*args, **kwargs)
- return wrapper
-
- def stopTimer(self, func):
- def wrapper(*args, **kwargs):
- try:
- return func(*args, **kwargs)
- finally:
- self.stop()
- return wrapper
-
- def start(self):
- self.started = util.now(self._reactor)
-
- def stop(self):
- if self.started is not None:
- elapsed = util.now(self._reactor) - self.started
- MetricTimeEvent.log(timer=self.name, elapsed=elapsed)
- self.started = None
-
-def timeMethod(name, _reactor=None):
- def decorator(func):
- t = Timer(name)
- t._reactor=_reactor
- def wrapper(*args, **kwargs):
- t.start()
- try:
- return func(*args, **kwargs)
- finally:
- t.stop()
- return wrapper
- return decorator
-
-class FiniteList(deque):
- def __init__(self, maxlen=10):
- self._maxlen = maxlen
- deque.__init__(self)
-
- def append(self, o):
- deque.append(self, o)
- if len(self) > self._maxlen:
- self.popleft()
-
-class AveragingFiniteList(FiniteList):
- def __init__(self, maxlen=10):
- FiniteList.__init__(self, maxlen)
- self.average = 0
-
- def append(self, o):
- FiniteList.append(self, o)
- self._calc()
-
- def _calc(self):
- if len(self) == 0:
- self.average = 0
- else:
- self.average = float(sum(self)) / len(self)
-
- return self.average
-
-class MetricHandler(object):
- def __init__(self, metrics):
- self.metrics = metrics
- self.watchers = []
-
- self.reset()
-
- def addWatcher(self, watcher):
- self.watchers.append(watcher)
-
- def removeWatcher(self, watcher):
- self.watchers.remove(watcher)
-
- # For subclasses to define
- def reset(self):
- raise NotImplementedError
-
- def handle(self, eventDict, metric):
- raise NotImplementedError
-
- def get(self, metric):
- raise NotImplementedError
-
- def keys(self):
- raise NotImplementedError
-
- def report(self):
- raise NotImplementedError
-
- def asDict(self):
- raise NotImplementedError
-
-class MetricCountHandler(MetricHandler):
- _counters = None
- def reset(self):
- self._counters = defaultdict(int)
-
- def handle(self, eventDict, metric):
- if metric.absolute:
- self._counters[metric.counter] = metric.count
- else:
- self._counters[metric.counter] += metric.count
-
- def keys(self):
- return self._counters.keys()
-
- def get(self, counter):
- return self._counters[counter]
-
- def report(self):
- retval = []
- for counter in sorted(self.keys()):
- retval.append("Counter %s: %i" % (counter, self.get(counter)))
- return "\n".join(retval)
-
- def asDict(self):
- retval = {}
- for counter in sorted(self.keys()):
- retval[counter] = self.get(counter)
- return dict(counters=retval)
-
-class MetricTimeHandler(MetricHandler):
- _timers = None
- def reset(self):
- self._timers = defaultdict(AveragingFiniteList)
-
- def handle(self, eventDict, metric):
- self._timers[metric.timer].append(metric.elapsed)
-
- def keys(self):
- return self._timers.keys()
-
- def get(self, timer):
- return self._timers[timer].average
-
- def report(self):
- retval = []
- for timer in sorted(self.keys()):
- retval.append("Timer %s: %.3g" % (timer, self.get(timer)))
- return "\n".join(retval)
-
- def asDict(self):
- retval = {}
- for timer in sorted(self.keys()):
- retval[timer] = self.get(timer)
- return dict(timers=retval)
-
-class MetricAlarmHandler(MetricHandler):
- _alarms = None
- def reset(self):
- self._alarms = defaultdict(lambda x: ALARM_OK)
-
- def handle(self, eventDict, metric):
- self._alarms[metric.alarm] = (metric.level, metric.msg)
-
- def report(self):
- retval = []
- for alarm, (level, msg) in sorted(self._alarms.items()):
- if msg:
- retval.append("%s %s: %s" % (ALARM_TEXT[level], alarm, msg))
- else:
- retval.append("%s %s" % (ALARM_TEXT[level], alarm))
- return "\n".join(retval)
-
- def asDict(self):
- retval = {}
- for alarm, (level, msg) in sorted(self._alarms.items()):
- retval[alarm] = (ALARM_TEXT[level], msg)
- return dict(alarms=retval)
-
-class PollerWatcher(object):
- def __init__(self, metrics):
- self.metrics = metrics
-
- def run(self):
- # Check if 'BuildMaster.pollDatabaseChanges()' and
- # 'BuildMaster.pollDatabaseBuildRequests()' are running fast enough
- h = self.metrics.getHandler(MetricTimeEvent)
- if not h:
- log.msg("Couldn't get MetricTimeEvent handler")
- MetricAlarmEvent.log('PollerWatcher',
- msg="Coudln't get MetricTimeEvent handler",
- level=ALARM_WARN)
- return
-
- for method in ('BuildMaster.pollDatabaseChanges()',
- 'BuildMaster.pollDatabaseBuildRequests()'):
- t = h.get(method)
- master = self.metrics.parent
- db_poll_interval = master.config.db['db_poll_interval']
-
- if db_poll_interval:
- if t < 0.8 * db_poll_interval:
- level = ALARM_OK
- elif t < db_poll_interval:
- level = ALARM_WARN
- else:
- level = ALARM_CRIT
- MetricAlarmEvent.log(method, level=level)
-
-class AttachedSlavesWatcher(object):
- def __init__(self, metrics):
- self.metrics = metrics
-
- def run(self):
- # Check if 'BotMaster.attached_slaves' equals
- # 'AbstractBuildSlave.attached_slaves'
- h = self.metrics.getHandler(MetricCountEvent)
- if not h:
- log.msg("Couldn't get MetricCountEvent handler")
- MetricAlarmEvent.log('AttachedSlavesWatcher',
- msg="Coudln't get MetricCountEvent handler",
- level=ALARM_WARN)
- return
- botmaster_count = h.get('BotMaster.attached_slaves')
- buildslave_count = h.get('AbstractBuildSlave.attached_slaves')
-
- # We let these be off by one since they're counted at slightly
- # different times
- if abs(botmaster_count - buildslave_count) > 1:
- level = ALARM_WARN
- else:
- level = ALARM_OK
-
- MetricAlarmEvent.log('attached_slaves',
- msg='%s %s' % (botmaster_count, buildslave_count),
- level=level)
-
-def _get_rss():
- if sys.platform == 'linux2':
- try:
- with open("/proc/%i/statm" % os.getpid()) as f:
- return int(f.read().split()[1])
- except:
- return 0
- return 0
-
-def periodicCheck(_reactor=reactor):
- try:
- # Measure how much garbage we have
- garbage_count = len(gc.garbage)
- MetricCountEvent.log('gc.garbage', garbage_count, absolute=True)
- if garbage_count == 0:
- level = ALARM_OK
- else:
- level = ALARM_WARN
- MetricAlarmEvent.log('gc.garbage', level=level)
-
- if resource:
- r = resource.getrusage(resource.RUSAGE_SELF)
- attrs = ['ru_utime', 'ru_stime', 'ru_maxrss', 'ru_ixrss', 'ru_idrss',
- 'ru_isrss', 'ru_minflt', 'ru_majflt', 'ru_nswap',
- 'ru_inblock', 'ru_oublock', 'ru_msgsnd', 'ru_msgrcv',
- 'ru_nsignals', 'ru_nvcsw', 'ru_nivcsw']
- for i,a in enumerate(attrs):
- # Linux versions prior to 2.6.32 didn't report this value, but we
- # can calculate it from /proc/<pid>/statm
- v = r[i]
- if a == 'ru_maxrss' and v == 0:
- v = _get_rss() * resource.getpagesize() / 1024
- MetricCountEvent.log('resource.%s' % a, v, absolute=True)
- MetricCountEvent.log('resource.pagesize', resource.getpagesize(), absolute=True)
- # Measure the reactor delay
- then = util.now(_reactor)
- dt = 0.1
- def cb():
- now = util.now(_reactor)
- delay = (now - then) - dt
- MetricTimeEvent.log("reactorDelay", delay)
- _reactor.callLater(dt, cb)
- except Exception:
- log.err(None, "while collecting VM metrics")
-
-class MetricLogObserver(config.ReconfigurableServiceMixin,
- service.MultiService):
- _reactor = reactor
- def __init__(self):
- service.MultiService.__init__(self)
- self.setName('metrics')
-
- self.enabled = False
- self.periodic_task = None
- self.periodic_interval = None
- self.log_task = None
- self.log_interval = None
-
- # Mapping of metric type to handlers for that type
- self.handlers = {}
-
- # Register our default handlers
- self.registerHandler(MetricCountEvent, MetricCountHandler(self))
- self.registerHandler(MetricTimeEvent, MetricTimeHandler(self))
- self.registerHandler(MetricAlarmEvent, MetricAlarmHandler(self))
-
- # Make sure our changes poller is behaving
- self.getHandler(MetricTimeEvent).addWatcher(PollerWatcher(self))
- self.getHandler(MetricCountEvent).addWatcher(
- AttachedSlavesWatcher(self))
-
- def reconfigService(self, new_config):
- # first, enable or disable
- if new_config.metrics is None:
- self.disable()
- else:
- self.enable()
-
- metrics_config = new_config.metrics
-
- # Start up periodic logging
- log_interval = metrics_config.get('log_interval', 60)
- if log_interval != self.log_interval:
- if self.log_task:
- self.log_task.stop()
- self.log_task = None
- if log_interval:
- self.log_task = LoopingCall(self.report)
- self.log_task.clock = self._reactor
- self.log_task.start(log_interval)
-
- # same for the periodic task
- periodic_interval = metrics_config.get('periodic_interval', 10)
- if periodic_interval != self.periodic_interval:
- if self.periodic_task:
- self.periodic_task.stop()
- self.periodic_task = None
- if periodic_interval:
- self.periodic_task = LoopingCall(periodicCheck,
- self._reactor)
- self.periodic_task.clock = self._reactor
- self.periodic_task.start(periodic_interval)
-
- # upcall
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def stopService(self):
- self.disable()
- service.MultiService.stopService(self)
-
- def enable(self):
- if self.enabled:
- return
- log.addObserver(self.emit)
- self.enabled = True
-
- def disable(self):
- if not self.enabled:
- return
-
- if self.periodic_task:
- self.periodic_task.stop()
- self.periodic_task = None
-
- if self.log_task:
- self.log_task.stop()
- self.log_task = None
-
- log.removeObserver(self.emit)
- self.enabled = False
-
- def registerHandler(self, interface, handler):
- old = self.getHandler(interface)
- self.handlers[interface] = handler
- return old
-
- def getHandler(self, interface):
- return self.handlers.get(interface)
-
- def emit(self, eventDict):
- # Ignore non-statistic events
- metric = eventDict.get('metric')
- if not metric or not isinstance(metric, MetricEvent):
- return
-
- if metric.__class__ not in self.handlers:
- return
-
- h = self.handlers[metric.__class__]
- h.handle(eventDict, metric)
- for w in h.watchers:
- w.run()
-
- def asDict(self):
- retval = {}
- for interface, handler in self.handlers.iteritems():
- retval.update(handler.asDict())
- return retval
-
- def report(self):
- try:
- for interface, handler in self.handlers.iteritems():
- report = handler.report()
- if not report:
- continue
- for line in report.split("\n"):
- log.msg(line)
- except:
- log.err(None, "generating metric report")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py
deleted file mode 100644
index a49b90e2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py
+++ /dev/null
@@ -1,474 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import re
-from twisted.python import log
-from twisted.internet import defer
-from twisted.enterprise import adbapi
-from buildbot.process.buildstep import LogLineObserver
-from buildbot.steps.shell import Test
-
-class EqConnectionPool(adbapi.ConnectionPool):
- """This class works the same way as
-twisted.enterprise.adbapi.ConnectionPool. But it adds the ability to
-compare connection pools for equality (by comparing the arguments
-passed to the constructor).
-
-This is useful when passing the ConnectionPool to a BuildStep, as
-otherwise Buildbot will consider the buildstep (and hence the
-containing buildfactory) to have changed every time the configuration
-is reloaded.
-
-It also sets some defaults differently from adbapi.ConnectionPool that
-are more suitable for use in MTR.
-"""
- def __init__(self, *args, **kwargs):
- self._eqKey = (args, kwargs)
- return adbapi.ConnectionPool.__init__(self,
- cp_reconnect=True, cp_min=1, cp_max=3,
- *args, **kwargs)
-
- def __eq__(self, other):
- if isinstance(other, EqConnectionPool):
- return self._eqKey == other._eqKey
- else:
- return False
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-
-class MtrTestFailData:
- def __init__(self, testname, variant, result, info, text, callback):
- self.testname = testname
- self.variant = variant
- self.result = result
- self.info = info
- self.text = text
- self.callback = callback
-
- def add(self, line):
- self.text+= line
-
- def fireCallback(self):
- return self.callback(self.testname, self.variant, self.result, self.info, self.text)
-
-
-class MtrLogObserver(LogLineObserver):
- """
- Class implementing a log observer (can be passed to
- BuildStep.addLogObserver().
-
- It parses the output of mysql-test-run.pl as used in MySQL,
- MariaDB, Drizzle, etc.
-
- It counts number of tests run and uses it to provide more accurate
- completion estimates.
-
- It parses out test failures from the output and summarises the results on
- the Waterfall page. It also passes the information to methods that can be
- overridden in a subclass to do further processing on the information."""
-
- _line_re = re.compile(r"^([-._0-9a-zA-z]+)( '[-_ a-zA-Z]+')?\s+(w[0-9]+\s+)?\[ (fail|pass) \]\s*(.*)$")
- _line_re2 = re.compile(r"^[-._0-9a-zA-z]+( '[-_ a-zA-Z]+')?\s+(w[0-9]+\s+)?\[ [-a-z]+ \]")
- _line_re3 = re.compile(r"^\*\*\*Warnings generated in error logs during shutdown after running tests: (.*)")
- _line_re4 = re.compile(r"^The servers were restarted [0-9]+ times$")
- _line_re5 = re.compile(r"^Only\s+[0-9]+\s+of\s+[0-9]+\s+completed.$")
-
- def __init__(self, textLimit=5, testNameLimit=16, testType=None):
- self.textLimit = textLimit
- self.testNameLimit = testNameLimit
- self.testType = testType
- self.numTests = 0
- self.testFail = None
- self.failList = []
- self.warnList = []
- LogLineObserver.__init__(self)
-
- def setLog(self, loog):
- LogLineObserver.setLog(self, loog)
- d= loog.waitUntilFinished()
- d.addCallback(lambda l: self.closeTestFail())
-
- def outLineReceived(self, line):
- stripLine = line.strip("\r\n")
- m = self._line_re.search(stripLine)
- if m:
- testname, variant, worker, result, info = m.groups()
- self.closeTestFail()
- self.numTests += 1
- self.step.setProgress('tests', self.numTests)
-
- if result == "fail":
- if variant == None:
- variant = ""
- else:
- variant = variant[2:-1]
- self.openTestFail(testname, variant, result, info, stripLine + "\n")
-
- else:
- m = self._line_re3.search(stripLine)
- if m:
- stuff = m.group(1)
- self.closeTestFail()
- testList = stuff.split(" ")
- self.doCollectWarningTests(testList)
-
- elif (self._line_re2.search(stripLine) or
- self._line_re4.search(stripLine) or
- self._line_re5.search(stripLine) or
- stripLine == "Test suite timeout! Terminating..." or
- stripLine.startswith("mysql-test-run: *** ERROR: Not all tests completed") or
- (stripLine.startswith("------------------------------------------------------------")
- and self.testFail != None)):
- self.closeTestFail()
-
- else:
- self.addTestFailOutput(stripLine + "\n")
-
- def openTestFail(self, testname, variant, result, info, line):
- self.testFail = MtrTestFailData(testname, variant, result, info, line, self.doCollectTestFail)
-
- def addTestFailOutput(self, line):
- if self.testFail != None:
- self.testFail.add(line)
-
- def closeTestFail(self):
- if self.testFail != None:
- self.testFail.fireCallback()
- self.testFail = None
-
- def addToText(self, src, dst):
- lastOne = None
- count = 0
- for t in src:
- if t != lastOne:
- dst.append(t)
- count += 1
- if count >= self.textLimit:
- break
-
- def makeText(self, done):
- if done:
- text = ["test"]
- else:
- text = ["testing"]
- if self.testType:
- text.append(self.testType)
- fails = self.failList[:]
- fails.sort()
- self.addToText(fails, text)
- warns = self.warnList[:]
- warns.sort()
- self.addToText(warns, text)
- return text
-
- # Update waterfall status.
- def updateText(self):
- self.step.step_status.setText(self.makeText(False))
-
- strip_re = re.compile(r"^[a-z]+\.")
-
- def displayTestName(self, testname):
-
- displayTestName = self.strip_re.sub("", testname)
-
- if len(displayTestName) > self.testNameLimit:
- displayTestName = displayTestName[:(self.testNameLimit-2)] + "..."
- return displayTestName
-
- def doCollectTestFail(self, testname, variant, result, info, text):
- self.failList.append("F:" + self.displayTestName(testname))
- self.updateText()
- self.collectTestFail(testname, variant, result, info, text)
-
- def doCollectWarningTests(self, testList):
- for t in testList:
- self.warnList.append("W:" + self.displayTestName(t))
- self.updateText()
- self.collectWarningTests(testList)
-
- # These two methods are overridden to actually do something with the data.
- def collectTestFail(self, testname, variant, result, info, text):
- pass
- def collectWarningTests(self, testList):
- pass
-
-class MTR(Test):
- """
- Build step that runs mysql-test-run.pl, as used in MySQL, Drizzle,
- MariaDB, etc.
-
- It uses class MtrLogObserver to parse test results out from the
- output of mysql-test-run.pl, providing better completion time
- estimates and summarising test failures on the waterfall page.
-
- It also provides access to mysqld server error logs from the test
- run to help debugging any problems.
-
- Optionally, it can insert into a database data about the test run,
- including details of any test failures.
-
- Parameters:
-
- textLimit
- Maximum number of test failures to show on the waterfall page
- (to not flood the page in case of a large number of test
- failures. Defaults to 5.
-
- testNameLimit
- Maximum length of test names to show unabbreviated in the
- waterfall page, to avoid excessive column width. Defaults to 16.
-
- parallel
- Value of --parallel option used for mysql-test-run.pl (number
- of processes used to run the test suite in parallel). Defaults
- to 4. This is used to determine the number of server error log
- files to download from the slave. Specifying a too high value
- does not hurt (as nonexisting error logs will be ignored),
- however if using --parallel value greater than the default it
- needs to be specified, or some server error logs will be
- missing.
-
- dbpool
- An instance of twisted.enterprise.adbapi.ConnectionPool, or None.
- Defaults to None. If specified, results are inserted into the database
- using the ConnectionPool.
-
- The class process.mtrlogobserver.EqConnectionPool subclass of
- ConnectionPool can be useful to pass as value for dbpool, to
- avoid having config reloads think the Buildstep is changed
- just because it gets a new ConnectionPool instance (even
- though connection parameters are unchanged).
-
- autoCreateTables
- Boolean, defaults to False. If True (and dbpool is specified), the
- necessary database tables will be created automatically if they do
- not exist already. Alternatively, the tables can be created manually
- from the SQL statements found in the mtrlogobserver.py source file.
-
- test_type
- test_info
- Two descriptive strings that will be inserted in the database tables if
- dbpool is specified. The test_type string, if specified, will also
- appear on the waterfall page."""
-
- renderables = [ 'mtr_subdir' ]
-
- def __init__(self, dbpool=None, test_type=None, test_info="",
- description=None, descriptionDone=None,
- autoCreateTables=False, textLimit=5, testNameLimit=16,
- parallel=4, logfiles = {}, lazylogfiles = True,
- warningPattern="MTR's internal check of the test case '.*' failed",
- mtr_subdir="mysql-test", **kwargs):
-
- if description is None:
- description = ["testing"]
- if test_type:
- description.append(test_type)
- if descriptionDone is None:
- descriptionDone = ["test"]
- if test_type:
- descriptionDone.append(test_type)
- Test.__init__(self, logfiles=logfiles, lazylogfiles=lazylogfiles,
- description=description, descriptionDone=descriptionDone,
- warningPattern=warningPattern, **kwargs)
- self.dbpool = dbpool
- self.test_type = test_type
- self.test_info = test_info
- self.autoCreateTables = autoCreateTables
- self.textLimit = textLimit
- self.testNameLimit = testNameLimit
- self.parallel = parallel
- self.mtr_subdir = mtr_subdir
- self.progressMetrics += ('tests',)
-
- def start(self):
- # Add mysql server logfiles.
- for mtr in range(0, self.parallel+1):
- for mysqld in range(1, 4+1):
- if mtr == 0:
- logname = "mysqld.%d.err" % mysqld
- filename = "var/log/mysqld.%d.err" % mysqld
- else:
- logname = "mysqld.%d.err.%d" % (mysqld, mtr)
- filename = "var/%d/log/mysqld.%d.err" % (mtr, mysqld)
- self.addLogFile(logname, self.mtr_subdir + "/" + filename)
-
- self.myMtr = self.MyMtrLogObserver(textLimit=self.textLimit,
- testNameLimit=self.testNameLimit,
- testType=self.test_type)
- self.addLogObserver("stdio", self.myMtr)
- # Insert a row for this test run into the database and set up
- # build properties, then start the command proper.
- d = self.registerInDB()
- d.addCallback(self.afterRegisterInDB)
- d.addErrback(self.failed)
-
- def getText(self, command, results):
- return self.myMtr.makeText(True)
-
- def runInteractionWithRetry(self, actionFn, *args, **kw):
- """
- Run a database transaction with dbpool.runInteraction, but retry the
- transaction in case of a temporary error (like connection lost).
-
- This is needed to be robust against things like database connection
- idle timeouts.
-
- The passed callable that implements the transaction must be retryable,
- ie. it must not have any destructive side effects in the case where
- an exception is thrown and/or rollback occurs that would prevent it
- from functioning correctly when called again."""
-
- def runWithRetry(txn, *args, **kw):
- retryCount = 0
- while(True):
- try:
- return actionFn(txn, *args, **kw)
- except txn.OperationalError:
- retryCount += 1
- if retryCount >= 5:
- raise
- excType, excValue, excTraceback = sys.exc_info()
- log.msg("Database transaction failed (caught exception %s(%s)), retrying ..." % (excType, excValue))
- txn.close()
- txn.reconnect()
- txn.reopen()
-
- return self.dbpool.runInteraction(runWithRetry, *args, **kw)
-
- def runQueryWithRetry(self, *args, **kw):
- """
- Run a database query, like with dbpool.runQuery, but retry the query in
- case of a temporary error (like connection lost).
-
- This is needed to be robust against things like database connection
- idle timeouts."""
-
- def runQuery(txn, *args, **kw):
- txn.execute(*args, **kw)
- return txn.fetchall()
-
- return self.runInteractionWithRetry(runQuery, *args, **kw)
-
- def registerInDB(self):
- if self.dbpool:
- return self.runInteractionWithRetry(self.doRegisterInDB)
- else:
- return defer.succeed(0)
-
- # The real database work is done in a thread in a synchronous way.
- def doRegisterInDB(self, txn):
- # Auto create tables.
- # This is off by default, as it gives warnings in log file
- # about tables already existing (and I did not find the issue
- # important enough to find a better fix).
- if self.autoCreateTables:
- txn.execute("""
-CREATE TABLE IF NOT EXISTS test_run(
- id INT PRIMARY KEY AUTO_INCREMENT,
- branch VARCHAR(100),
- revision VARCHAR(32) NOT NULL,
- platform VARCHAR(100) NOT NULL,
- dt TIMESTAMP NOT NULL,
- bbnum INT NOT NULL,
- typ VARCHAR(32) NOT NULL,
- info VARCHAR(255),
- KEY (branch, revision),
- KEY (dt),
- KEY (platform, bbnum)
-) ENGINE=innodb
-""")
- txn.execute("""
-CREATE TABLE IF NOT EXISTS test_failure(
- test_run_id INT NOT NULL,
- test_name VARCHAR(100) NOT NULL,
- test_variant VARCHAR(16) NOT NULL,
- info_text VARCHAR(255),
- failure_text TEXT,
- PRIMARY KEY (test_run_id, test_name, test_variant)
-) ENGINE=innodb
-""")
- txn.execute("""
-CREATE TABLE IF NOT EXISTS test_warnings(
- test_run_id INT NOT NULL,
- list_id INT NOT NULL,
- list_idx INT NOT NULL,
- test_name VARCHAR(100) NOT NULL,
- PRIMARY KEY (test_run_id, list_id, list_idx)
-) ENGINE=innodb
-""")
-
- revision = self.getProperty("got_revision")
- if revision is None:
- revision = self.getProperty("revision")
- typ = "mtr"
- if self.test_type:
- typ = self.test_type
- txn.execute("""
-INSERT INTO test_run(branch, revision, platform, dt, bbnum, typ, info)
-VALUES (%s, %s, %s, CURRENT_TIMESTAMP(), %s, %s, %s)
-""", (self.getProperty("branch"), revision,
- self.getProperty("buildername"), self.getProperty("buildnumber"),
- typ, self.test_info))
-
- return txn.lastrowid
-
- def afterRegisterInDB(self, insert_id):
- self.setProperty("mtr_id", insert_id)
- self.setProperty("mtr_warn_id", 0)
-
- Test.start(self)
-
- def reportError(self, err):
- log.msg("Error in async insert into database: %s" % err)
-
- class MyMtrLogObserver(MtrLogObserver):
- def collectTestFail(self, testname, variant, result, info, text):
- # Insert asynchronously into database.
- dbpool = self.step.dbpool
- run_id = self.step.getProperty("mtr_id")
- if dbpool == None:
- return defer.succeed(None)
- if variant == None:
- variant = ""
- d = self.step.runQueryWithRetry("""
-INSERT INTO test_failure(test_run_id, test_name, test_variant, info_text, failure_text)
-VALUES (%s, %s, %s, %s, %s)
-""", (run_id, testname, variant, info, text))
-
- d.addErrback(self.step.reportError)
- return d
-
- def collectWarningTests(self, testList):
- # Insert asynchronously into database.
- dbpool = self.step.dbpool
- if dbpool == None:
- return defer.succeed(None)
- run_id = self.step.getProperty("mtr_id")
- warn_id = self.step.getProperty("mtr_warn_id")
- self.step.setProperty("mtr_warn_id", warn_id + 1)
- q = ("INSERT INTO test_warnings(test_run_id, list_id, list_idx, test_name) " +
- "VALUES " + ", ".join(map(lambda x: "(%s, %s, %s, %s)", testList)))
- v = []
- idx = 0
- for t in testList:
- v.extend([run_id, warn_id, idx, t])
- idx = idx + 1
- d = self.step.runQueryWithRetry(q, tuple(v))
- d.addErrback(self.step.reportError)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py
deleted file mode 100644
index 4edf394e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py
+++ /dev/null
@@ -1,689 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import collections
-import re
-import warnings
-import weakref
-from buildbot import config, util
-from buildbot.util import json
-from buildbot.interfaces import IRenderable, IProperties
-from twisted.internet import defer
-from twisted.python.components import registerAdapter
-from zope.interface import implements
-
-class Properties(util.ComparableMixin):
- """
- I represent a set of properties that can be interpolated into various
- strings in buildsteps.
-
- @ivar properties: dictionary mapping property values to tuples
- (value, source), where source is a string identifing the source
- of the property.
-
- Objects of this class can be read like a dictionary -- in this case,
- only the property value is returned.
-
- As a special case, a property value of None is returned as an empty
- string when used as a mapping.
- """
-
- compare_attrs = ('properties',)
- implements(IProperties)
-
- def __init__(self, **kwargs):
- """
- @param kwargs: initial property values (for testing)
- """
- self.properties = {}
- # Track keys which are 'runtime', and should not be
- # persisted if a build is rebuilt
- self.runtime = set()
- self.build = None # will be set by the Build when starting
- if kwargs: self.update(kwargs, "TEST")
-
- @classmethod
- def fromDict(cls, propDict):
- properties = cls()
- for name, (value, source) in propDict.iteritems():
- properties.setProperty(name, value, source)
- return properties
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['build'] = None
- return d
-
- def __setstate__(self, d):
- self.__dict__ = d
- if not hasattr(self, 'runtime'):
- self.runtime = set()
-
- def __contains__(self, name):
- return name in self.properties
-
- def __getitem__(self, name):
- """Just get the value for this property."""
- rv = self.properties[name][0]
- return rv
-
- def __nonzero__(self):
- return not not self.properties
-
- def getPropertySource(self, name):
- return self.properties[name][1]
-
- def asList(self):
- """Return the properties as a sorted list of (name, value, source)"""
- l = [ (k, v[0], v[1]) for k,v in self.properties.iteritems() ]
- l.sort()
- return l
-
- def asDict(self):
- """Return the properties as a simple key:value dictionary"""
- return dict(self.properties)
-
- def __repr__(self):
- return ('Properties(**' +
- repr(dict((k,v[0]) for k,v in self.properties.iteritems())) +
- ')')
-
- def update(self, dict, source, runtime=False):
- """Update this object from a dictionary, with an explicit source specified."""
- for k, v in dict.items():
- self.setProperty(k, v, source, runtime=runtime)
-
- def updateFromProperties(self, other):
- """Update this object based on another object; the other object's """
- self.properties.update(other.properties)
- self.runtime.update(other.runtime)
-
- def updateFromPropertiesNoRuntime(self, other):
- """Update this object based on another object, but don't
- include properties that were marked as runtime."""
- for k,v in other.properties.iteritems():
- if k not in other.runtime:
- self.properties[k] = v
-
- # IProperties methods
-
- def getProperty(self, name, default=None):
- return self.properties.get(name, (default,))[0]
-
- def hasProperty(self, name):
- return self.properties.has_key(name)
-
- has_key = hasProperty
-
- def setProperty(self, name, value, source, runtime=False):
- try:
- json.dumps(value)
- except TypeError:
- warnings.warn(
- "Non jsonable properties are not explicitly supported and" +
- "will be explicitly disallowed in a future version.",
- DeprecationWarning, stacklevel=2)
-
- self.properties[name] = (value, source)
- if runtime:
- self.runtime.add(name)
-
- def getProperties(self):
- return self
-
- def getBuild(self):
- return self.build
-
- def render(self, value):
- renderable = IRenderable(value)
- return defer.maybeDeferred(renderable.getRenderingFor, self)
-
-
-class PropertiesMixin:
- """
- A mixin to add L{IProperties} methods to a class which does not implement
- the interface, but which can be coerced to the interface via an adapter.
-
- This is useful because L{IProperties} methods are often called on L{Build}
- and L{BuildStatus} objects without first coercing them.
-
- @ivar set_runtime_properties: the default value for the C{runtime}
- parameter of L{setProperty}.
- """
-
- set_runtime_properties = False
-
- def getProperty(self, propname, default=None):
- props = IProperties(self)
- return props.getProperty(propname, default)
-
- def hasProperty(self, propname):
- props = IProperties(self)
- return props.hasProperty(propname)
-
- has_key = hasProperty
-
- def setProperty(self, propname, value, source='Unknown', runtime=None):
- # source is not optional in IProperties, but is optional here to avoid
- # breaking user-supplied code that fails to specify a source
- props = IProperties(self)
- if runtime is None:
- runtime = self.set_runtime_properties
- props.setProperty(propname, value, source, runtime=runtime)
-
- def getProperties(self):
- return IProperties(self)
-
- def render(self, value):
- props = IProperties(self)
- return props.render(value)
-
-
-
-class _PropertyMap(object):
- """
- Privately-used mapping object to implement WithProperties' substitutions,
- including the rendering of None as ''.
- """
- colon_minus_re = re.compile(r"(.*):-(.*)")
- colon_tilde_re = re.compile(r"(.*):~(.*)")
- colon_plus_re = re.compile(r"(.*):\+(.*)")
- def __init__(self, properties):
- # use weakref here to avoid a reference loop
- self.properties = weakref.ref(properties)
- self.temp_vals = {}
-
- def __getitem__(self, key):
- properties = self.properties()
- assert properties is not None
-
- def colon_minus(mo):
- # %(prop:-repl)s
- # if prop exists, use it; otherwise, use repl
- prop, repl = mo.group(1,2)
- if prop in self.temp_vals:
- return self.temp_vals[prop]
- elif properties.has_key(prop):
- return properties[prop]
- else:
- return repl
-
- def colon_tilde(mo):
- # %(prop:~repl)s
- # if prop exists and is true (nonempty), use it; otherwise, use repl
- prop, repl = mo.group(1,2)
- if prop in self.temp_vals and self.temp_vals[prop]:
- return self.temp_vals[prop]
- elif properties.has_key(prop) and properties[prop]:
- return properties[prop]
- else:
- return repl
-
- def colon_plus(mo):
- # %(prop:+repl)s
- # if prop exists, use repl; otherwise, an empty string
- prop, repl = mo.group(1,2)
- if properties.has_key(prop) or prop in self.temp_vals:
- return repl
- else:
- return ''
-
- for regexp, fn in [
- ( self.colon_minus_re, colon_minus ),
- ( self.colon_tilde_re, colon_tilde ),
- ( self.colon_plus_re, colon_plus ),
- ]:
- mo = regexp.match(key)
- if mo:
- rv = fn(mo)
- break
- else:
- # If explicitly passed as a kwarg, use that,
- # otherwise, use the property value.
- if key in self.temp_vals:
- rv = self.temp_vals[key]
- else:
- rv = properties[key]
-
- # translate 'None' to an empty string
- if rv is None: rv = ''
- return rv
-
- def add_temporary_value(self, key, val):
- 'Add a temporary value (to support keyword arguments to WithProperties)'
- self.temp_vals[key] = val
-
-class WithProperties(util.ComparableMixin):
- """
- This is a marker class, used fairly widely to indicate that we
- want to interpolate build properties.
- """
-
- implements(IRenderable)
- compare_attrs = ('fmtstring', 'args', 'lambda_subs')
-
- def __init__(self, fmtstring, *args, **lambda_subs):
- self.fmtstring = fmtstring
- self.args = args
- if not self.args:
- self.lambda_subs = lambda_subs
- for key, val in self.lambda_subs.iteritems():
- if not callable(val):
- raise ValueError('Value for lambda substitution "%s" must be callable.' % key)
- elif lambda_subs:
- raise ValueError('WithProperties takes either positional or keyword substitutions, not both.')
-
- def getRenderingFor(self, build):
- pmap = _PropertyMap(build.getProperties())
- if self.args:
- strings = []
- for name in self.args:
- strings.append(pmap[name])
- s = self.fmtstring % tuple(strings)
- else:
- for k,v in self.lambda_subs.iteritems():
- pmap.add_temporary_value(k, v(build))
- s = self.fmtstring % pmap
- return s
-
-
-
-_notHasKey = object() ## Marker object for _Lookup(..., hasKey=...) default
-class _Lookup(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('value', 'index', 'default', 'defaultWhenFalse', 'hasKey', 'elideNoneAs')
-
- def __init__(self, value, index, default=None,
- defaultWhenFalse=True, hasKey=_notHasKey,
- elideNoneAs=None):
- self.value = value
- self.index = index
- self.default = default
- self.defaultWhenFalse = defaultWhenFalse
- self.hasKey = hasKey
- self.elideNoneAs = elideNoneAs
-
- def __repr__(self):
- return '_Lookup(%r, %r%s%s%s%s)' % (
- self.value,
- self.index,
- ', default=%r' % (self.default,)
- if self.default is not None else '',
- ', defaultWhenFalse=False'
- if not self.defaultWhenFalse else '',
- ', hasKey=%r' % (self.hasKey,)
- if self.hasKey is not _notHasKey else '',
- ', elideNoneAs=%r'% (self.elideNoneAs,)
- if self.elideNoneAs is not None else '')
-
-
- @defer.inlineCallbacks
- def getRenderingFor(self, build):
- value = build.render(self.value)
- index = build.render(self.index)
- value, index = yield defer.gatherResults([value, index])
- if not value.has_key(index):
- rv = yield build.render(self.default)
- else:
- if self.defaultWhenFalse:
- rv = yield build.render(value[index])
- if not rv:
- rv = yield build.render(self.default)
- elif self.hasKey is not _notHasKey:
- rv = yield build.render(self.hasKey)
- elif self.hasKey is not _notHasKey:
- rv = yield build.render(self.hasKey)
- else:
- rv = yield build.render(value[index])
- if rv is None:
- rv = yield build.render(self.elideNoneAs)
- defer.returnValue(rv)
-
-
-def _getInterpolationList(fmtstring):
- # TODO: Verify that no positial substitutions are requested
- dd = collections.defaultdict(str)
- fmtstring % dd
- return dd.keys()
-
-
-class _PropertyDict(object):
- implements(IRenderable)
- def getRenderingFor(self, build):
- return build.getProperties()
-_thePropertyDict = _PropertyDict()
-
-class _SourceStampDict(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('codebase',)
-
- def __init__(self, codebase):
- self.codebase = codebase
- def getRenderingFor(self, build):
- ss = build.getBuild().getSourceStamp(self.codebase)
- if ss:
- return ss.asDict()
- else:
- return {}
-
-class _Lazy(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('value',)
- def __init__(self, value):
- self.value = value
- def getRenderingFor(self, build):
- return self.value
-
- def __repr__(self):
- return '_Lazy(%r)' % self.value
-
-
-class Interpolate(util.ComparableMixin, object):
- """
- This is a marker class, used fairly widely to indicate that we
- want to interpolate build properties.
- """
-
- implements(IRenderable)
- compare_attrs = ('fmtstring', 'args', 'kwargs')
-
- identifier_re = re.compile('^[\w-]*$')
-
- def __init__(self, fmtstring, *args, **kwargs):
- self.fmtstring = fmtstring
- self.args = args
- self.kwargs = kwargs
- if self.args and self.kwargs:
- config.error("Interpolate takes either positional or keyword "
- "substitutions, not both.")
- if not self.args:
- self.interpolations = {}
- self._parse(fmtstring)
-
- # TODO: add case below for when there's no args or kwargs..
- def __repr__(self):
- if self.args:
- return 'Interpolate(%r, *%r)' % (self.fmtstring, self.args)
- elif self.kwargs:
- return 'Interpolate(%r, **%r)' % (self.fmtstring, self.kwargs)
- else:
- return 'Interpolate(%r)' % (self.fmtstring,)
-
- @staticmethod
- def _parse_prop(arg):
- try:
- prop, repl = arg.split(":", 1)
- except ValueError:
- prop, repl = arg, None
- if not Interpolate.identifier_re.match(prop):
- config.error("Property name must be alphanumeric for prop Interpolation '%s'" % arg)
- prop = repl = None
- return _thePropertyDict, prop, repl
-
- @staticmethod
- def _parse_src(arg):
- ## TODO: Handle changes
- try:
- codebase, attr, repl = arg.split(":", 2)
- except ValueError:
- try:
- codebase, attr = arg.split(":",1)
- repl = None
- except ValueError:
- config.error("Must specify both codebase and attribute for src Interpolation '%s'" % arg)
- return {}, None, None
-
- if not Interpolate.identifier_re.match(codebase):
- config.error("Codebase must be alphanumeric for src Interpolation '%s'" % arg)
- codebase = attr = repl = None
- if not Interpolate.identifier_re.match(attr):
- config.error("Attribute must be alphanumeric for src Interpolation '%s'" % arg)
- codebase = attr = repl = None
- return _SourceStampDict(codebase), attr, repl
-
- def _parse_kw(self, arg):
- try:
- kw, repl = arg.split(":", 1)
- except ValueError:
- kw, repl = arg, None
- if not Interpolate.identifier_re.match(kw):
- config.error("Keyword must be alphanumeric for kw Interpolation '%s'" % arg)
- kw = repl = None
- return _Lazy(self.kwargs), kw, repl
-
- def _parseSubstitution(self, fmt):
- try:
- key, arg = fmt.split(":", 1)
- except ValueError:
- config.error("invalid Interpolate substitution without selector '%s'" % fmt)
- return
-
- fn = getattr(self, "_parse_" + key, None)
- if not fn:
- config.error("invalid Interpolate selector '%s'" % key)
- return None
- else:
- return fn(arg)
-
- @staticmethod
- def _splitBalancedParen(delim, arg):
- parenCount = 0
- for i in range(0, len(arg)):
- if arg[i] == "(":
- parenCount += 1
- if arg[i] == ")":
- parenCount -= 1
- if parenCount < 0:
- raise ValueError
- if parenCount == 0 and arg[i] == delim:
- return arg[0:i], arg[i+1:]
- return arg
-
- def _parseColon_minus(self, d, kw, repl):
- return _Lookup(d, kw,
- default=Interpolate(repl, **self.kwargs),
- defaultWhenFalse=False,
- elideNoneAs='')
-
- def _parseColon_tilde(self, d, kw, repl):
- return _Lookup(d, kw,
- default=Interpolate(repl, **self.kwargs),
- defaultWhenFalse=True,
- elideNoneAs='')
-
- def _parseColon_plus(self, d, kw, repl):
- return _Lookup(d, kw,
- hasKey=Interpolate(repl, **self.kwargs),
- default='',
- defaultWhenFalse=False,
- elideNoneAs='')
-
- def _parseColon_ternary(self, d, kw, repl, defaultWhenFalse=False):
- delim = repl[0]
- if delim == '(':
- config.error("invalid Interpolate ternary delimiter '('")
- return None
- try:
- truePart, falsePart = self._splitBalancedParen(delim, repl[1:])
- except ValueError:
- config.error("invalid Interpolate ternary expression '%s' with delimiter '%s'" % (repl[1:], repl[0]))
- return None
- return _Lookup(d, kw,
- hasKey=Interpolate(truePart, **self.kwargs),
- default=Interpolate(falsePart, **self.kwargs),
- defaultWhenFalse=defaultWhenFalse,
- elideNoneAs='')
-
- def _parseColon_ternary_hash(self, d, kw, repl):
- return self._parseColon_ternary(d, kw, repl, defaultWhenFalse=True)
-
- def _parse(self, fmtstring):
- keys = _getInterpolationList(fmtstring)
- for key in keys:
- if not self.interpolations.has_key(key):
- d, kw, repl = self._parseSubstitution(key)
- if repl is None:
- repl = '-'
- for pattern, fn in [
- ( "-", self._parseColon_minus ),
- ( "~", self._parseColon_tilde ),
- ( "+", self._parseColon_plus ),
- ( "?", self._parseColon_ternary ),
- ( "#?", self._parseColon_ternary_hash )
- ]:
- junk, matches, tail = repl.partition(pattern)
- if not junk and matches:
- self.interpolations[key] = fn(d, kw, tail)
- break
- if not self.interpolations.has_key(key):
- config.error("invalid Interpolate default type '%s'" % repl[0])
-
- def getRenderingFor(self, props):
- props = props.getProperties()
- if self.args:
- d = props.render(self.args)
- d.addCallback(lambda args:
- self.fmtstring % tuple(args))
- return d
- else:
- d = props.render(self.interpolations)
- d.addCallback(lambda res:
- self.fmtstring % res)
- return d
-
-class Property(util.ComparableMixin):
- """
- An instance of this class renders a property of a build.
- """
-
- implements(IRenderable)
-
- compare_attrs = ('key','default', 'defaultWhenFalse')
-
- def __init__(self, key, default=None, defaultWhenFalse=True):
- """
- @param key: Property to render.
- @param default: Value to use if property isn't set.
- @param defaultWhenFalse: When true (default), use default value
- if property evaluates to False. Otherwise, use default value
- only when property isn't set.
- """
- self.key = key
- self.default = default
- self.defaultWhenFalse = defaultWhenFalse
-
- def getRenderingFor(self, props):
- if self.defaultWhenFalse:
- d = props.render(props.getProperty(self.key))
- @d.addCallback
- def checkDefault(rv):
- if rv:
- return rv
- else:
- return props.render(self.default)
- return d
- else:
- if props.hasProperty(self.key):
- return props.render(props.getProperty(self.key))
- else:
- return props.render(self.default)
-
-class _Renderer(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('getRenderingFor',)
-
- def __init__(self, fn):
- self.getRenderingFor = fn
-
- def __repr__(self):
- return 'renderer(%r)' % (self.getRenderingFor,)
-
-def renderer(fn):
- return _Renderer(fn)
-
-class _DefaultRenderer(object):
- """
- Default IRenderable adaptor. Calls .getRenderingFor if availble, otherwise
- returns argument unchanged.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- try:
- self.renderer = value.getRenderingFor
- except AttributeError:
- self.renderer = lambda _: value
-
- def getRenderingFor(self, build):
- return self.renderer(build)
-
-registerAdapter(_DefaultRenderer, object, IRenderable)
-
-
-class _ListRenderer(object):
- """
- List IRenderable adaptor. Maps Build.render over the list.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- self.value = value
-
- def getRenderingFor(self, build):
- return defer.gatherResults([ build.render(e) for e in self.value ])
-
-registerAdapter(_ListRenderer, list, IRenderable)
-
-
-class _TupleRenderer(object):
- """
- Tuple IRenderable adaptor. Maps Build.render over the tuple.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- self.value = value
-
- def getRenderingFor(self, build):
- d = defer.gatherResults([ build.render(e) for e in self.value ])
- d.addCallback(tuple)
- return d
-
-registerAdapter(_TupleRenderer, tuple, IRenderable)
-
-
-class _DictRenderer(object):
- """
- Dict IRenderable adaptor. Maps Build.render over the keya and values in the dict.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- self.value = _ListRenderer([ _TupleRenderer((k,v)) for k,v in value.iteritems() ])
-
- def getRenderingFor(self, build):
- d = self.value.getRenderingFor(build)
- d.addCallback(dict)
- return d
-
-registerAdapter(_DictRenderer, dict, IRenderable)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py
deleted file mode 100644
index 174ee741..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py
+++ /dev/null
@@ -1,297 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.spread import pb
-from twisted.internet import defer
-from twisted.python import log
-
-(ATTACHING, # slave attached, still checking hostinfo/etc
- IDLE, # idle, available for use
- PINGING, # build about to start, making sure it is still alive
- BUILDING, # build is running
- LATENT, # latent slave is not substantiated; similar to idle
- SUBSTANTIATING,
- ) = range(6)
-
-class AbstractSlaveBuilder(pb.Referenceable):
- """I am the master-side representative for one of the
- L{buildbot.slave.bot.SlaveBuilder} objects that lives in a remote
- buildbot. When a remote builder connects, I query it for command versions
- and then make it available to any Builds that are ready to run. """
-
- def __init__(self):
- self.ping_watchers = []
- self.state = None # set in subclass
- self.remote = None
- self.slave = None
- self.builder_name = None
- self.locks = None
-
- def __repr__(self):
- r = ["<", self.__class__.__name__]
- if self.builder_name:
- r.extend([" builder=", repr(self.builder_name)])
- if self.slave:
- r.extend([" slave=", repr(self.slave.slavename)])
- r.append(">")
- return ''.join(r)
-
- def setBuilder(self, b):
- self.builder = b
- self.builder_name = b.name
-
- def getSlaveCommandVersion(self, command, oldversion=None):
- if self.remoteCommands is None:
- # the slave is 0.5.0 or earlier
- return oldversion
- return self.remoteCommands.get(command)
-
- def isAvailable(self):
- # if this SlaveBuilder is busy, then it's definitely not available
- if self.isBusy():
- return False
-
- # otherwise, check in with the BuildSlave
- if self.slave:
- return self.slave.canStartBuild()
-
- # no slave? not very available.
- return False
-
- def isBusy(self):
- return self.state not in (IDLE, LATENT)
-
- def buildStarted(self):
- self.state = BUILDING
-
- def buildFinished(self):
- self.state = IDLE
- if self.slave:
- self.slave.buildFinished(self)
-
- def attached(self, slave, remote, commands):
- """
- @type slave: L{buildbot.buildslave.BuildSlave}
- @param slave: the BuildSlave that represents the buildslave as a
- whole
- @type remote: L{twisted.spread.pb.RemoteReference}
- @param remote: a reference to the L{buildbot.slave.bot.SlaveBuilder}
- @type commands: dict: string -> string, or None
- @param commands: provides the slave's version of each RemoteCommand
- """
- self.state = ATTACHING
- self.remote = remote
- self.remoteCommands = commands # maps command name to version
- if self.slave is None:
- self.slave = slave
- self.slave.addSlaveBuilder(self)
- else:
- assert self.slave == slave
- log.msg("Buildslave %s attached to %s" % (slave.slavename,
- self.builder_name))
- d = defer.succeed(None)
-
- d.addCallback(lambda _:
- self.remote.callRemote("setMaster", self))
-
- d.addCallback(lambda _:
- self.remote.callRemote("print", "attached"))
-
- def setIdle(res):
- self.state = IDLE
- return self
- d.addCallback(setIdle)
-
- return d
-
- def prepare(self, builder_status, build):
- if not self.slave.acquireLocks():
- return defer.succeed(False)
- return defer.succeed(True)
-
- def ping(self, status=None):
- """Ping the slave to make sure it is still there. Returns a Deferred
- that fires with True if it is.
-
- @param status: if you point this at a BuilderStatus, a 'pinging'
- event will be pushed.
- """
- oldstate = self.state
- self.state = PINGING
- newping = not self.ping_watchers
- d = defer.Deferred()
- self.ping_watchers.append(d)
- if newping:
- if status:
- event = status.addEvent(["pinging"])
- d2 = defer.Deferred()
- d2.addCallback(self._pong_status, event)
- self.ping_watchers.insert(0, d2)
- # I think it will make the tests run smoother if the status
- # is updated before the ping completes
- Ping().ping(self.remote).addCallback(self._pong)
-
- def reset_state(res):
- if self.state == PINGING:
- self.state = oldstate
- return res
- d.addCallback(reset_state)
- return d
-
- def _pong(self, res):
- watchers, self.ping_watchers = self.ping_watchers, []
- for d in watchers:
- d.callback(res)
-
- def _pong_status(self, res, event):
- if res:
- event.text = ["ping", "success"]
- else:
- event.text = ["ping", "failed"]
- event.finish()
-
- def detached(self):
- log.msg("Buildslave %s detached from %s" % (self.slave.slavename,
- self.builder_name))
- if self.slave:
- self.slave.removeSlaveBuilder(self)
- self.slave = None
- self.remote = None
- self.remoteCommands = None
-
-
-class Ping:
- running = False
-
- def ping(self, remote):
- assert not self.running
- if not remote:
- # clearly the ping must fail
- return defer.succeed(False)
- self.running = True
- log.msg("sending ping")
- self.d = defer.Deferred()
- # TODO: add a distinct 'ping' command on the slave.. using 'print'
- # for this purpose is kind of silly.
- remote.callRemote("print", "ping").addCallbacks(self._pong,
- self._ping_failed,
- errbackArgs=(remote,))
- return self.d
-
- def _pong(self, res):
- log.msg("ping finished: success")
- self.d.callback(True)
-
- def _ping_failed(self, res, remote):
- log.msg("ping finished: failure")
- # the slave has some sort of internal error, disconnect them. If we
- # don't, we'll requeue a build and ping them again right away,
- # creating a nasty loop.
- remote.broker.transport.loseConnection()
- # TODO: except, if they actually did manage to get this far, they'll
- # probably reconnect right away, and we'll do this game again. Maybe
- # it would be better to leave them in the PINGING state.
- self.d.callback(False)
-
-
-class SlaveBuilder(AbstractSlaveBuilder):
-
- def __init__(self):
- AbstractSlaveBuilder.__init__(self)
- self.state = ATTACHING
-
- def detached(self):
- AbstractSlaveBuilder.detached(self)
- if self.slave:
- self.slave.removeSlaveBuilder(self)
- self.slave = None
- self.state = ATTACHING
-
-class LatentSlaveBuilder(AbstractSlaveBuilder):
- def __init__(self, slave, builder):
- AbstractSlaveBuilder.__init__(self)
- self.slave = slave
- self.state = LATENT
- self.setBuilder(builder)
- self.slave.addSlaveBuilder(self)
- log.msg("Latent buildslave %s attached to %s" % (slave.slavename,
- self.builder_name))
-
- def prepare(self, builder_status, build):
- # If we can't lock, then don't bother trying to substantiate
- if not self.slave or not self.slave.acquireLocks():
- return defer.succeed(False)
-
- log.msg("substantiating slave %s" % (self,))
- d = self.substantiate(build)
- def substantiation_failed(f):
- builder_status.addPointEvent(['removing', 'latent',
- self.slave.slavename])
- self.slave.disconnect()
- # TODO: should failover to a new Build
- return f
- def substantiation_cancelled(res):
- # if res is False, latent slave cancelled subtantiation
- if not res:
- self.state = LATENT
- return res
- d.addCallback(substantiation_cancelled)
- d.addErrback(substantiation_failed)
- return d
-
- def substantiate(self, build):
- self.state = SUBSTANTIATING
- d = self.slave.substantiate(self, build)
- if not self.slave.substantiated:
- event = self.builder.builder_status.addEvent(
- ["substantiating"])
- def substantiated(res):
- msg = ["substantiate", "success"]
- if isinstance(res, basestring):
- msg.append(res)
- elif isinstance(res, (tuple, list)):
- msg.extend(res)
- event.text = msg
- event.finish()
- return res
- def substantiation_failed(res):
- event.text = ["substantiate", "failed"]
- # TODO add log of traceback to event
- event.finish()
- return res
- d.addCallbacks(substantiated, substantiation_failed)
- return d
-
- def detached(self):
- AbstractSlaveBuilder.detached(self)
- self.state = LATENT
-
- def buildStarted(self):
- AbstractSlaveBuilder.buildStarted(self)
- self.slave.buildStarted(self)
-
- def _attachFailure(self, why, where):
- self.state = LATENT
- return AbstractSlaveBuilder._attachFailure(self, why, where)
-
- def ping(self, status=None):
- if not self.slave.substantiated:
- if status:
- status.addEvent(["ping", "latent"]).finish()
- return defer.succeed(True)
- return AbstractSlaveBuilder.ping(self, status)
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py
deleted file mode 100644
index de5df820..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from unittest import TestResult
-from StringIO import StringIO
-
-from buildbot.process import buildstep
-from buildbot.status.testresult import TestResult as aTestResult
-from buildbot.status.results import SUCCESS, FAILURE, SKIPPED
-
-class SubunitLogObserver(buildstep.LogLineObserver, TestResult):
- """Observe a log that may contain subunit output.
-
- This class extends TestResult to receive the callbacks from the subunit
- parser in the most direct fashion.
- """
-
- def __init__(self):
- buildstep.LogLineObserver.__init__(self)
- TestResult.__init__(self)
- try:
- from subunit import TestProtocolServer, PROGRESS_CUR, PROGRESS_SET
- from subunit import PROGRESS_PUSH, PROGRESS_POP
- except ImportError:
- raise ImportError("subunit is not importable, but is required for "
- "SubunitLogObserver support.")
- self.PROGRESS_CUR = PROGRESS_CUR
- self.PROGRESS_SET = PROGRESS_SET
- self.PROGRESS_PUSH = PROGRESS_PUSH
- self.PROGRESS_POP = PROGRESS_POP
- self.warningio = StringIO()
- self.protocol = TestProtocolServer(self, self.warningio)
- self.skips = []
- self.seen_tags = set() #don't yet know what tags does in subunit
-
- def outLineReceived(self, line):
- """Process a received stdout line."""
- # Impedance mismatch: subunit wants lines, observers get lines-no\n
- self.protocol.lineReceived(line + '\n')
-
- def errLineReceived(self, line):
- """same for stderr line."""
- self.protocol.lineReceived(line + '\n')
-
- def stopTest(self, test):
- TestResult.stopTest(self, test)
- self.step.setProgress('tests', self.testsRun)
-
- def addSuccess(self, test):
- TestResult.addSuccess(self, test)
- self.addAResult(test, SUCCESS, 'SUCCESS')
-
- def addSkip(self, test, detail):
- if hasattr(TestResult,'addSkip'):
- TestResult.addSkip(self, test, detail)
- else:
- self.skips.append((test, detail))
- self.addAResult(test, SKIPPED, 'SKIPPED', detail)
-
- def addError(self, test, err):
- TestResult.addError(self, test, err)
- self.issue(test, err)
-
- def addFailure(self, test, err):
- TestResult.addFailure(self, test, err)
- self.issue(test, err)
-
- def addAResult(self, test, result, text, log=""):
- tr = aTestResult(tuple(test.id().split('.')), result, text, log)
- self.step.build.build_status.addTestResult(tr)
-
- def issue(self, test, err):
- """An issue - failing, erroring etc test."""
- self.addAResult(test, FAILURE, 'FAILURE', err)
- self.step.setProgress('tests failed', len(self.failures) +
- len(self.errors))
-
- expectedTests = 0
- contextLevel = 0
- def progress(self, offset, whence):
- if not self.contextLevel:
- if whence == self.PROGRESS_CUR:
- self.expectedTests += offset
- elif whence == self.PROGRESS_SET:
- self.expectedTests = offset
- self.step.progress.setExpectations({'tests': self.expectedTests})
- #TODO: properly support PUSH/POP
- if whence == self.PROGRESS_PUSH:
- self.contextLevel += 1
- elif whence == self.PROGRESS_POP:
- self.contextLevel -= 1
-
- def tags(self, new_tags, gone_tags):
- """Accumulate the seen tags."""
- self.seen_tags.update(new_tags)
-
-# this used to be referenced here, so we keep a link for old time's sake
-import buildbot.steps.subunit
-SubunitShellCommand = buildbot.steps.subunit.SubunitShellCommand
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py
deleted file mode 100644
index 855af0c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from twisted.application import service
-from buildbot import config
-
-class UserManagerManager(config.ReconfigurableServiceMixin,
- service.MultiService):
- # this class manages a fleet of user managers; hence the name..
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('user_manager_manager')
- self.master = master
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # this is easy - kick out all of the old managers, and add the
- # new ones.
-
- for mgr in list(self):
- yield defer.maybeDeferred(lambda :
- mgr.disownServiceParent())
- mgr.master = None
-
- for mgr in new_config.user_managers:
- mgr.master = self.master
- mgr.setServiceParent(self)
-
- # reconfig any newly-added change sources, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py
deleted file mode 100644
index be94a691..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# this class is known to contain cruft and will be looked at later, so
-# no current implementation utilizes it aside from scripts.runner.
-
-from twisted.python import log
-from twisted.internet import defer
-from twisted.application import service
-from buildbot import pbutil
-
-class UsersBase(service.MultiService):
- """
- Base class for services that manage users manually. This takes care
- of the service.MultiService work needed by all the services that
- subclass it.
- """
-
- def __init__(self):
- service.MultiService.__init__(self)
- self.master = None
-
- def startService(self):
- service.MultiService.startService(self)
-
- def stopService(self):
- return service.MultiService.stopService(self)
-
-class CommandlineUserManagerPerspective(pbutil.NewCredPerspective):
- """
- Perspective registered in buildbot.pbmanager and contains the real
- workings of `buildbot user` by working with the database when
- perspective_commandline is called.
- """
-
- def __init__(self, master):
- self.master = master
-
- def formatResults(self, op, results):
- """
- This formats the results of the database operations for printing
- back to the caller
-
- @param op: operation to perform (add, remove, update, get)
- @type op: string
-
- @param results: results from db queries in perspective_commandline
- @type results: list
-
- @returns: string containing formatted results
- """
- formatted_results = ""
-
- if op == 'add':
- # list, alternating ident, uid
- formatted_results += "user(s) added:\n"
- for user in results:
- if isinstance(user, basestring):
- formatted_results += "identifier: %s\n" % user
- else:
- formatted_results += "uid: %d\n\n" % user
- elif op == 'remove':
- # list of dictionaries
- formatted_results += "user(s) removed:\n"
- for user in results:
- if user:
- formatted_results += "identifier: %s\n" % (user)
- elif op == 'update':
- # list, alternating ident, None
- formatted_results += "user(s) updated:\n"
- for user in results:
- if user:
- formatted_results += "identifier: %s\n" % (user)
- elif op == 'get':
- # list of dictionaries
- formatted_results += "user(s) found:\n"
- for user in results:
- if user:
- for key in user:
- if key != 'bb_password':
- formatted_results += "%s: %s\n" % (key, user[key])
- formatted_results += "\n"
- else:
- formatted_results += "no match found\n"
- return formatted_results
-
- @defer.inlineCallbacks
- def perspective_commandline(self, op, bb_username, bb_password, ids, info):
- """
- This performs the requested operations from the `buildbot user`
- call by calling the proper buildbot.db.users methods based on
- the operation. It yields a deferred instance with the results
- from the database methods.
-
- @param op: operation to perform (add, remove, update, get)
- @type op: string
-
- @param bb_username: username portion of auth credentials
- @type bb_username: string
-
- @param bb_password: hashed password portion of auth credentials
- @type bb_password: hashed string
-
- @param ids: user identifiers used to find existing users
- @type ids: list of strings or None
-
- @param info: type/value pairs for each user that will be added
- or updated in the database
- @type info: list of dictionaries or None
-
- @returns: results from db.users methods via deferred
- """
- log.msg("perspective_commandline called")
- results = []
-
- if ids:
- for user in ids:
- # get identifier, guaranteed to be in user from checks
- # done in C{scripts.runner}
- uid = yield self.master.db.users.identifierToUid(
- identifier=user)
-
- result = None
- if op == 'remove':
- if uid:
- yield self.master.db.users.removeUser(uid)
- result = user
- else:
- log.msg("Unable to find uid for identifier %s" % user)
- elif op == 'get':
- if uid:
- result = yield self.master.db.users.getUser(uid)
- else:
- log.msg("Unable to find uid for identifier %s" % user)
-
- results.append(result)
- else:
- for user in info:
- # get identifier, guaranteed to be in user from checks
- # done in C{scripts.runner}
- ident = user.pop('identifier')
- uid = yield self.master.db.users.identifierToUid(
- identifier=ident)
-
- # if only an identifier was in user, we're updating only
- # the bb_username and bb_password.
- if not user:
- if uid:
- result = yield self.master.db.users.updateUser(
- uid=uid,
- identifier=ident,
- bb_username=bb_username,
- bb_password=bb_password)
- results.append(ident)
- else:
- log.msg("Unable to find uid for identifier %s"
- % user)
- else:
- # when adding, we update the user after the first attr
- once_through = False
- for attr in user:
- if op == 'update' or once_through:
- if uid:
- result = yield self.master.db.users.updateUser(
- uid=uid,
- identifier=ident,
- bb_username=bb_username,
- bb_password=bb_password,
- attr_type=attr,
- attr_data=user[attr])
- else:
- log.msg("Unable to find uid for identifier %s"
- % user)
- elif op == 'add':
- result = yield self.master.db.users.findUserByAttr(
- identifier=ident,
- attr_type=attr,
- attr_data=user[attr])
- once_through = True
- results.append(ident)
-
- # result is None from updateUser calls
- if result:
- results.append(result)
- uid = result
- results = self.formatResults(op, results)
- defer.returnValue(results)
-
-class CommandlineUserManager(UsersBase):
- """
- Service that runs to set up and register CommandlineUserManagerPerspective
- so `buildbot user` calls get to perspective_commandline.
- """
-
- def __init__(self, username=None, passwd=None, port=None):
- UsersBase.__init__(self)
- assert username and passwd, ("A username and password pair must be given "
- "to connect and use `buildbot user`")
- self.username = username
- self.passwd = passwd
-
- assert port, "A port must be specified for a PB connection"
- self.port = port
- self.registration = None
-
- def startService(self):
- UsersBase.startService(self)
- # set up factory and register with buildbot.pbmanager
- def factory(mind, username):
- return CommandlineUserManagerPerspective(self.master)
- self.registration = self.master.pbmanager.register(self.port,
- self.username,
- self.passwd,
- factory)
-
- def stopService(self):
- d = defer.maybeDeferred(UsersBase.stopService, self)
- def unreg(_):
- if self.registration:
- return self.registration.unregister()
- d.addCallback(unreg)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py
deleted file mode 100644
index cae07428..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.util import flatten
-
-try:
- from hashlib import sha1 as sha
- assert sha
-except ImportError:
- # For Python 2.4
- import sha
-
-srcs = ['git', 'svn', 'hg', 'cvs', 'darcs', 'bzr']
-salt_len = 8
-
-def createUserObject(master, author, src=None):
- """
- Take a Change author and source and translate them into a User Object,
- storing the user in master.db, or returning None if the src is not
- specified.
-
- @param master: link to Buildmaster for database operations
- @type master: master.Buildmaster instance
-
- @param authors: Change author if string or Authz instance
- @type authors: string or status.web.authz instance
-
- @param src: source from which the User Object will be created
- @type src: string
- """
-
- if not src:
- log.msg("No vcs information found, unable to create User Object")
- return defer.succeed(None)
-
- if src in srcs:
- usdict = dict(identifier=author, attr_type=src, attr_data=author)
- else:
- log.msg("Unrecognized source argument: %s" % src)
- return defer.succeed(None)
-
- return master.db.users.findUserByAttr(
- identifier=usdict['identifier'],
- attr_type=usdict['attr_type'],
- attr_data=usdict['attr_data'])
-
-
-def _extractContact(usdict, contact_types, uid):
- if usdict:
- for type in contact_types:
- contact = usdict.get(type)
- if contact:
- break
- else:
- contact = None
- if contact is None:
- log.msg(format="Unable to find any of %(contact_types)r for uid: %(uid)r",
- contact_types=contact_types, uid=uid)
- return contact
-
-def getUserContact(master, contact_types, uid):
- """
- This is a simple getter function that returns a user attribute
- that matches the contact_types argument, or returns None if no
- uid/match is found.
-
- @param master: BuildMaster used to query the database
- @type master: BuildMaster instance
-
- @param contact_types: list of contact attributes to look for in
- in a given user, such as 'email' or 'nick'
- @type contact_types: list of strings
-
- @param uid: user that is searched for the contact_types match
- @type uid: integer
-
- @returns: string of contact information or None via deferred
- """
- d = master.db.users.getUser(uid)
- d.addCallback(_extractContact, contact_types, uid)
- return d
-
-def _filter(contacts):
- def notNone(c):
- return c is not None
- return filter(notNone, contacts)
-
-def getUsersContacts(master, contact_types, uids):
- d = defer.gatherResults([getUserContact(master, contact_types, uid) for uid in uids])
- d.addCallback(_filter)
- return d
-
-def getChangeContacts(master, change, contact_types):
- d = master.db.changes.getChangeUids(change.number)
- d.addCallback(lambda uids: getUsersContacts(master, contact_types, uids))
- return d
-
-def getSourceStampContacts(master, ss, contact_types):
- dl = [getChangeContacts(master, change, contact_types) for change in ss.changes]
- if False and ss.patch_info:
- d = master.db.users.getUserByUsername(ss.patch_into[0])
- d.addCallback(_extractContact, contact_types, ss.patch_info[0])
- d.addCallback(lambda contact: filter(None, [contact]))
- dl.append(d)
- d = defer.gatherResults(dl)
- d.addCallback(flatten)
- return d
-
-def getBuildContacts(master, build, contact_types):
- dl = []
- ss_list = build.getSourceStamps()
- for ss in ss_list:
- dl.append(getSourceStampContacts(master, ss, contact_types))
- d = defer.gatherResults(dl)
- d.addCallback(flatten)
- @d.addCallback
- def addOwners(recipients):
- dl = []
- for owner in build.getInterestedUsers():
- d = master.db.users.getUserByUsername(owner)
- d.addCallback(_extractContact, contact_types, owner)
- dl.append(d)
- d = defer.gatherResults(dl)
- d.addCallback(_filter)
- d.addCallback(lambda owners: recipients + owners)
- return d
- return d
-
-def encrypt(passwd):
- """
- Encrypts the incoming password after adding some salt to store
- it in the database.
-
- @param passwd: password portion of user credentials
- @type passwd: string
-
- @returns: encrypted/salted string
- """
- try:
- m = sha()
- except TypeError:
- m = sha.new()
-
- salt = os.urandom(salt_len).encode('hex_codec')
- m.update(passwd + salt)
- crypted = salt + m.hexdigest()
- return crypted
-
-def check_passwd(guess, passwd):
- """
- Tests to see if the guess, after salting and hashing, matches the
- passwd from the database.
-
- @param guess: incoming password trying to be used for authentication
- @param passwd: already encrypted password from the database
-
- @returns: boolean
- """
- try:
- m = sha()
- except TypeError:
- m = sha.new()
-
- salt = passwd[:salt_len * 2] # salt_len * 2 due to encode('hex_codec')
- m.update(guess + salt)
- crypted_guess = salt + m.hexdigest()
-
- return (crypted_guess == passwd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py
deleted file mode 100644
index 033af9ae..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-
-class RevlinkMatch(object):
- def __init__(self, repo_urls, revlink):
- if isinstance(repo_urls, str) or isinstance(repo_urls, unicode):
- repo_urls = [ repo_urls ]
- self.repo_urls = map(re.compile, repo_urls)
- self.revlink = revlink
- def __call__(self, rev, repo):
- for url in self.repo_urls:
- m = url.match(repo)
- if m:
- return m.expand(self.revlink) % rev
-
-GithubRevlink = RevlinkMatch(
- repo_urls = [ r'https://github.com/([^/]*)/([^/]*?)(?:\.git)?$',
- r'git://github.com/([^/]*)/([^/]*?)(?:\.git)?$',
- r'git@github.com:([^/]*)/([^/]*?)(?:\.git)?$',
- r'ssh://git@github.com/([^/]*)/([^/]*?)(?:\.git)?$'
- ],
- revlink = r'https://github.com/\1/\2/commit/%s')
-
-class GitwebMatch(RevlinkMatch):
- def __init__(self, repo_urls, revlink):
- RevlinkMatch.__init__(self, repo_urls = repo_urls, revlink = revlink + r'?p=\g<repo>;a=commit;h=%s')
-
-SourceforgeGitRevlink = GitwebMatch(
- repo_urls = [ r'^git://([^.]*).git.sourceforge.net/gitroot/(?P<repo>.*)$',
- r'[^@]*@([^.]*).git.sourceforge.net:gitroot/(?P<repo>.*)$',
- r'ssh://(?:[^@]*@)?([^.]*).git.sourceforge.net/gitroot/(?P<repo>.*)$',
- ],
- revlink = r'http://\1.git.sourceforge.net/git/gitweb.cgi')
-
-class RevlinkMultiplexer(object):
- def __init__(self, *revlinks):
- self.revlinks = revlinks
- def __call__(self, rev, repo):
- for revlink in self.revlinks:
- url = revlink(rev, repo)
- if url:
- return url
-
-default_revlink_matcher = RevlinkMultiplexer(GithubRevlink, SourceforgeGitRevlink)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py
deleted file mode 100644
index 5997faaf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.schedulers.basic import Scheduler, AnyBranchScheduler
-from buildbot.schedulers.dependent import Dependent
-from buildbot.schedulers.timed import Periodic, Nightly
-from buildbot.schedulers.triggerable import Triggerable
-from buildbot.schedulers.trysched import Try_Jobdir, Try_Userpass
-
-_hush_pyflakes = [Scheduler, AnyBranchScheduler, Dependent,
- Periodic, Nightly, Triggerable, Try_Jobdir, Try_Userpass]
-del _hush_pyflakes
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py
deleted file mode 100644
index 4b18f935..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py
+++ /dev/null
@@ -1,453 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.python import failure, log
-from twisted.application import service
-from twisted.internet import defer
-from buildbot.process.properties import Properties
-from buildbot.util import ComparableMixin
-from buildbot import config, interfaces
-from buildbot.util.state import StateMixin
-
-class BaseScheduler(service.MultiService, ComparableMixin, StateMixin):
- """
- Base class for all schedulers; this provides the equipment to manage
- reconfigurations and to handle basic scheduler state. It also provides
- utility methods to begin various sorts of builds.
-
- Subclasses should add any configuration-derived attributes to
- C{base.Scheduler.compare_attrs}.
- """
-
- implements(interfaces.IScheduler)
-
- DefaultCodebases = {'':{}}
-
- compare_attrs = ('name', 'builderNames', 'properties', 'codebases')
-
- def __init__(self, name, builderNames, properties,
- codebases = DefaultCodebases):
- """
- Initialize a Scheduler.
-
- @param name: name of this scheduler (used as a key for state)
- @type name: unicode
-
- @param builderNames: list of builders this scheduler may start
- @type builderNames: list of unicode
-
- @param properties: properties to add to builds triggered by this
- scheduler
- @type properties: dictionary
-
- @param codebases: codebases that are necessary to process the changes
- @type codebases: dict with following struct:
- key: '<codebase>'
- value: {'repository':'<repo>', 'branch':'<br>', 'revision:'<rev>'}
-
- @param consumeChanges: true if this scheduler wishes to be informed
- about the addition of new changes. Defaults to False. This should
- be passed explicitly from subclasses to indicate their interest in
- consuming changes.
- @type consumeChanges: boolean
- """
- service.MultiService.__init__(self)
- self.name = name
- "name of this scheduler; used to identify replacements on reconfig"
-
- ok = True
- if not isinstance(builderNames, (list, tuple)):
- ok = False
- else:
- for b in builderNames:
- if not isinstance(b, basestring):
- ok = False
- if not ok:
- config.error(
- "The builderNames argument to a scheduler must be a list "
- "of Builder names.")
-
- self.builderNames = builderNames
- "list of builder names to start in each buildset"
-
- self.properties = Properties()
- "properties that are contributed to each buildset"
- self.properties.update(properties, "Scheduler")
- self.properties.setProperty("scheduler", name, "Scheduler")
-
- self.objectid = None
-
- self.master = None
-
- # Set the codebases that are necessary to process the changes
- # These codebases will always result in a sourcestamp with or without changes
- if codebases is not None:
- if not isinstance(codebases, dict):
- config.error("Codebases must be a dict of dicts")
- for codebase, codebase_attrs in codebases.iteritems():
- if not isinstance(codebase_attrs, dict):
- config.error("Codebases must be a dict of dicts")
- if (codebases != BaseScheduler.DefaultCodebases and
- 'repository' not in codebase_attrs):
- config.error("The key 'repository' is mandatory in codebases")
- else:
- config.error("Codebases cannot be None")
-
- self.codebases = codebases
-
- # internal variables
- self._change_subscription = None
- self._change_consumption_lock = defer.DeferredLock()
-
- ## service handling
-
- def startService(self):
- service.MultiService.startService(self)
-
- def findNewSchedulerInstance(self, new_config):
- return new_config.schedulers[self.name] # should exist!
-
- def stopService(self):
- d = defer.maybeDeferred(self._stopConsumingChanges)
- d.addCallback(lambda _ : service.MultiService.stopService(self))
- return d
-
-
- ## status queries
-
- # TODO: these aren't compatible with distributed schedulers
-
- def listBuilderNames(self):
- "Returns the list of builder names"
- return self.builderNames
-
- def getPendingBuildTimes(self):
- "Returns a list of the next times that builds are scheduled, if known."
- return []
-
- ## change handling
-
- def startConsumingChanges(self, fileIsImportant=None, change_filter=None,
- onlyImportant=False):
- """
- Subclasses should call this method from startService to register to
- receive changes. The BaseScheduler class will take care of filtering
- the changes (using change_filter) and (if fileIsImportant is not None)
- classifying them. See L{gotChange}. Returns a Deferred.
-
- @param fileIsImportant: a callable provided by the user to distinguish
- important and unimportant changes
- @type fileIsImportant: callable
-
- @param change_filter: a filter to determine which changes are even
- considered by this scheduler, or C{None} to consider all changes
- @type change_filter: L{buildbot.changes.filter.ChangeFilter} instance
-
- @param onlyImportant: If True, only important changes, as specified by
- fileIsImportant, will be added to the buildset.
- @type onlyImportant: boolean
-
- """
- assert fileIsImportant is None or callable(fileIsImportant)
-
- # register for changes with master
- assert not self._change_subscription
- def changeCallback(change):
- # ignore changes delivered while we're not running
- if not self._change_subscription:
- return
-
- if change_filter and not change_filter.filter_change(change):
- return
- if change.codebase not in self.codebases:
- log.msg(format='change contains codebase %(codebase)s that is'
- 'not processed by scheduler %(scheduler)s',
- codebase=change.codebase, name=self.name)
- return
- if fileIsImportant:
- try:
- important = fileIsImportant(change)
- if not important and onlyImportant:
- return
- except:
- log.err(failure.Failure(),
- 'in fileIsImportant check for %s' % change)
- return
- else:
- important = True
-
- # use change_consumption_lock to ensure the service does not stop
- # while this change is being processed
- d = self._change_consumption_lock.run(self.gotChange, change, important)
- d.addErrback(log.err, 'while processing change')
- self._change_subscription = self.master.subscribeToChanges(changeCallback)
-
- return defer.succeed(None)
-
- def _stopConsumingChanges(self):
- # (note: called automatically in stopService)
-
- # acquire the lock change consumption lock to ensure that any change
- # consumption is complete before we are done stopping consumption
- def stop():
- if self._change_subscription:
- self._change_subscription.unsubscribe()
- self._change_subscription = None
- return self._change_consumption_lock.run(stop)
-
- def gotChange(self, change, important):
- """
- Called when a change is received; returns a Deferred. If the
- C{fileIsImportant} parameter to C{startConsumingChanges} was C{None},
- then all changes are considered important.
- The C{codebase} of the change has always an entry in the C{codebases}
- dictionary of the scheduler.
-
- @param change: the new change object
- @type change: L{buildbot.changes.changes.Change} instance
- @param important: true if this is an important change, according to
- C{fileIsImportant}.
- @type important: boolean
- @returns: Deferred
- """
- raise NotImplementedError
-
- ## starting bulids
-
- @defer.inlineCallbacks
- def addBuildsetForLatest(self, reason='', external_idstring=None,
- branch=None, repository='', project='',
- builderNames=None, properties=None):
- """
- Add a buildset for the 'latest' source in the given branch,
- repository, and project. This will create a relative sourcestamp for
- the buildset.
-
- This method will add any properties provided to the scheduler
- constructor to the buildset, and will call the master's addBuildset
- method with the appropriate parameters.
-
- @param reason: reason for this buildset
- @type reason: unicode string
- @param external_idstring: external identifier for this buildset, or None
- @param branch: branch to build (note that None often has a special meaning)
- @param repository: repository name for sourcestamp
- @param project: project name for sourcestamp
- @param builderNames: builders to name in the buildset (defaults to
- C{self.builderNames})
- @param properties: a properties object containing initial properties for
- the buildset
- @type properties: L{buildbot.process.properties.Properties}
- @returns: (buildset ID, buildrequest IDs) via Deferred
- """
- # Define setid for this set of changed repositories
- setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- # add a sourcestamp for each codebase
- for codebase, cb_info in self.codebases.iteritems():
- ss_repository = cb_info.get('repository', repository)
- ss_branch = cb_info.get('branch', branch)
- ss_revision = cb_info.get('revision', None)
- yield self.master.db.sourcestamps.addSourceStamp(
- codebase=codebase,
- repository=ss_repository,
- branch=ss_branch,
- revision=ss_revision,
- project=project,
- changeids=set(),
- sourcestampsetid=setid)
-
- bsid,brids = yield self.addBuildsetForSourceStamp(
- setid=setid, reason=reason,
- external_idstring=external_idstring,
- builderNames=builderNames,
- properties=properties)
-
- defer.returnValue((bsid,brids))
-
-
- @defer.inlineCallbacks
- def addBuildsetForSourceStampDetails(self, reason='', external_idstring=None,
- branch=None, repository='', project='', revision=None,
- builderNames=None, properties=None):
- """
- Given details about the source code to build, create a source stamp and
- then add a buildset for it.
-
- @param reason: reason for this buildset
- @type reason: unicode string
- @param external_idstring: external identifier for this buildset, or None
- @param branch: branch to build (note that None often has a special meaning)
- @param repository: repository name for sourcestamp
- @param project: project name for sourcestamp
- @param revision: revision to build - default is latest
- @param builderNames: builders to name in the buildset (defaults to
- C{self.builderNames})
- @param properties: a properties object containing initial properties for
- the buildset
- @type properties: L{buildbot.process.properties.Properties}
- @returns: (buildset ID, buildrequest IDs) via Deferred
- """
- # Define setid for this set of changed repositories
- setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- yield self.master.db.sourcestamps.addSourceStamp(
- branch=branch, revision=revision, repository=repository,
- project=project, sourcestampsetid=setid)
-
- rv = yield self.addBuildsetForSourceStamp(
- setid=setid, reason=reason,
- external_idstring=external_idstring,
- builderNames=builderNames,
- properties=properties)
- defer.returnValue(rv)
-
-
- @defer.inlineCallbacks
- def addBuildsetForSourceStampSetDetails(self, reason, sourcestamps,
- properties, builderNames=None):
- if sourcestamps is None:
- sourcestamps = {}
-
- # Define new setid for this set of sourcestamps
- new_setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- # Merge codebases with the passed list of sourcestamps
- # This results in a new sourcestamp for each codebase
- for codebase in self.codebases:
- ss = self.codebases[codebase].copy()
- # apply info from passed sourcestamps onto the configured default
- # sourcestamp attributes for this codebase.
- ss.update(sourcestamps.get(codebase,{}))
-
- # add sourcestamp to the new setid
- yield self.master.db.sourcestamps.addSourceStamp(
- codebase=codebase,
- repository=ss.get('repository', ''),
- branch=ss.get('branch', None),
- revision=ss.get('revision', None),
- project=ss.get('project', ''),
- changeids=[c['number'] for c in ss.get('changes', [])],
- patch_body=ss.get('patch_body', None),
- patch_level=ss.get('patch_level', None),
- patch_author=ss.get('patch_author', None),
- patch_comment=ss.get('patch_comment', None),
- sourcestampsetid=new_setid)
-
- rv = yield self.addBuildsetForSourceStamp(
- setid=new_setid, reason=reason,
- properties=properties,
- builderNames=builderNames)
-
- defer.returnValue(rv)
-
-
- @defer.inlineCallbacks
- def addBuildsetForChanges(self, reason='', external_idstring=None,
- changeids=[], builderNames=None, properties=None):
- changesByCodebase = {}
-
- def get_last_change_for_codebase(codebase):
- return max(changesByCodebase[codebase],key = lambda change: change["changeid"])
-
- # Define setid for this set of changed repositories
- setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- # Changes are retrieved from database and grouped by their codebase
- for changeid in changeids:
- chdict = yield self.master.db.changes.getChange(changeid)
- # group change by codebase
- changesByCodebase.setdefault(chdict["codebase"], []).append(chdict)
-
- for codebase in self.codebases:
- args = {'codebase': codebase, 'sourcestampsetid': setid }
- if codebase not in changesByCodebase:
- # codebase has no changes
- # create a sourcestamp that has no changes
- args['repository'] = self.codebases[codebase]['repository']
- args['branch'] = self.codebases[codebase].get('branch', None)
- args['revision'] = self.codebases[codebase].get('revision', None)
- args['changeids'] = set()
- args['project'] = ''
- else:
- #codebase has changes
- args['changeids'] = [c["changeid"] for c in changesByCodebase[codebase]]
- lastChange = get_last_change_for_codebase(codebase)
- for key in ['repository', 'branch', 'revision', 'project']:
- args[key] = lastChange[key]
-
- yield self.master.db.sourcestamps.addSourceStamp(**args)
-
- # add one buildset, this buildset is connected to the sourcestamps by the setid
- bsid,brids = yield self.addBuildsetForSourceStamp( setid=setid,
- reason=reason, external_idstring=external_idstring,
- builderNames=builderNames, properties=properties)
-
- defer.returnValue((bsid,brids))
-
- @defer.inlineCallbacks
- def addBuildsetForSourceStamp(self, ssid=None, setid=None, reason='', external_idstring=None,
- properties=None, builderNames=None):
- """
- Add a buildset for the given, already-existing sourcestamp.
-
- This method will add any properties provided to the scheduler
- constructor to the buildset, and will call the master's
- L{BuildMaster.addBuildset} method with the appropriate parameters, and
- return the same result.
-
- @param reason: reason for this buildset
- @type reason: unicode string
- @param external_idstring: external identifier for this buildset, or None
- @param properties: a properties object containing initial properties for
- the buildset
- @type properties: L{buildbot.process.properties.Properties}
- @param builderNames: builders to name in the buildset (defaults to
- C{self.builderNames})
- @param setid: idenitification of a set of sourcestamps
- @returns: (buildset ID, buildrequest IDs) via Deferred
- """
- assert (ssid is None and setid is not None) \
- or (ssid is not None and setid is None), "pass a single sourcestamp OR set not both"
-
- # combine properties
- if properties:
- properties.updateFromProperties(self.properties)
- else:
- properties = self.properties
-
- # apply the default builderNames
- if not builderNames:
- builderNames = self.builderNames
-
- # translate properties object into a dict as required by the
- # addBuildset method
- properties_dict = properties.asDict()
-
- if setid == None:
- if ssid is not None:
- ssdict = yield self.master.db.sourcestamps.getSourceStamp(ssid)
- setid = ssdict['sourcestampsetid']
- else:
- # no sourcestamp and no sets
- yield None
-
- rv = yield self.master.addBuildset(sourcestampsetid=setid,
- reason=reason, properties=properties_dict,
- builderNames=builderNames,
- external_idstring=external_idstring)
- defer.returnValue(rv)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py
deleted file mode 100644
index a2b9f19c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer, reactor
-from twisted.python import log
-from buildbot import util, config
-from buildbot.util import NotABranch
-from collections import defaultdict
-from buildbot.changes import filter, changes
-from buildbot.schedulers import base, dependent
-
-class BaseBasicScheduler(base.BaseScheduler):
- """
- @param onlyImportant: If True, only important changes will be added to the
- buildset.
- @type onlyImportant: boolean
-
- """
-
- compare_attrs = (base.BaseScheduler.compare_attrs +
- ('treeStableTimer', 'change_filter', 'fileIsImportant',
- 'onlyImportant') )
-
- _reactor = reactor # for tests
-
- fileIsImportant = None
-
- class NotSet: pass
- def __init__(self, name, shouldntBeSet=NotSet, treeStableTimer=None,
- builderNames=None, branch=NotABranch, branches=NotABranch,
- fileIsImportant=None, properties={}, categories=None,
- change_filter=None, onlyImportant=False, **kwargs):
- if shouldntBeSet is not self.NotSet:
- config.error(
- "pass arguments to schedulers using keyword arguments")
- if fileIsImportant and not callable(fileIsImportant):
- config.error(
- "fileIsImportant must be a callable")
-
- # initialize parent classes
- base.BaseScheduler.__init__(self, name, builderNames, properties, **kwargs)
-
- self.treeStableTimer = treeStableTimer
- if fileIsImportant is not None:
- self.fileIsImportant = fileIsImportant
- self.onlyImportant = onlyImportant
- self.change_filter = self.getChangeFilter(branch=branch,
- branches=branches, change_filter=change_filter,
- categories=categories)
-
- # the IDelayedCall used to wake up when this scheduler's
- # treeStableTimer expires.
- self._stable_timers = defaultdict(lambda : None)
- self._stable_timers_lock = defer.DeferredLock()
-
- def getChangeFilter(self, branch, branches, change_filter, categories):
- raise NotImplementedError
-
- def startService(self, _returnDeferred=False):
- base.BaseScheduler.startService(self)
-
- d = self.startConsumingChanges(fileIsImportant=self.fileIsImportant,
- change_filter=self.change_filter,
- onlyImportant=self.onlyImportant)
-
- # if treeStableTimer is False, then we don't care about classified
- # changes, so get rid of any hanging around from previous
- # configurations
- if not self.treeStableTimer:
- d.addCallback(lambda _ :
- self.master.db.schedulers.flushChangeClassifications(
- self.objectid))
-
- # otherwise, if there are classified changes out there, start their
- # treeStableTimers again
- else:
- d.addCallback(lambda _ :
- self.scanExistingClassifiedChanges())
-
- # handle Deferred errors, since startService does not return a Deferred
- d.addErrback(log.err, "while starting SingleBranchScheduler '%s'"
- % self.name)
-
- if _returnDeferred:
- return d # only used in tests
-
- def stopService(self):
- # the base stopService will unsubscribe from new changes
- d = base.BaseScheduler.stopService(self)
- @util.deferredLocked(self._stable_timers_lock)
- def cancel_timers(_):
- for timer in self._stable_timers.values():
- if timer:
- timer.cancel()
- self._stable_timers.clear()
- d.addCallback(cancel_timers)
- return d
-
- @util.deferredLocked('_stable_timers_lock')
- def gotChange(self, change, important):
- if not self.treeStableTimer:
- # if there's no treeStableTimer, we can completely ignore
- # unimportant changes
- if not important:
- return defer.succeed(None)
- # otherwise, we'll build it right away
- return self.addBuildsetForChanges(reason='scheduler',
- changeids=[ change.number ])
-
- timer_name = self.getTimerNameForChange(change)
-
- # if we have a treeStableTimer, then record the change's importance
- # and:
- # - for an important change, start the timer
- # - for an unimportant change, reset the timer if it is running
- d = self.master.db.schedulers.classifyChanges(
- self.objectid, { change.number : important })
- def fix_timer(_):
- if not important and not self._stable_timers[timer_name]:
- return
- if self._stable_timers[timer_name]:
- self._stable_timers[timer_name].cancel()
- def fire_timer():
- d = self.stableTimerFired(timer_name)
- d.addErrback(log.err, "while firing stable timer")
- self._stable_timers[timer_name] = self._reactor.callLater(
- self.treeStableTimer, fire_timer)
- d.addCallback(fix_timer)
- return d
-
- @defer.inlineCallbacks
- def scanExistingClassifiedChanges(self):
- # call gotChange for each classified change. This is called at startup
- # and is intended to re-start the treeStableTimer for any changes that
- # had not yet been built when the scheduler was stopped.
-
- # NOTE: this may double-call gotChange for changes that arrive just as
- # the scheduler starts up. In practice, this doesn't hurt anything.
- classifications = \
- yield self.master.db.schedulers.getChangeClassifications(
- self.objectid)
-
- # call gotChange for each change, after first fetching it from the db
- for changeid, important in classifications.iteritems():
- chdict = yield self.master.db.changes.getChange(changeid)
-
- if not chdict:
- continue
-
- change = yield changes.Change.fromChdict(self.master, chdict)
- yield self.gotChange(change, important)
-
- def getTimerNameForChange(self, change):
- raise NotImplementedError # see subclasses
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- """similar to db.schedulers.getChangeClassifications, but given timer
- name"""
- raise NotImplementedError # see subclasses
-
- @util.deferredLocked('_stable_timers_lock')
- @defer.inlineCallbacks
- def stableTimerFired(self, timer_name):
- # if the service has already been stoppd then just bail out
- if not self._stable_timers[timer_name]:
- return
-
- # delete this now-fired timer
- del self._stable_timers[timer_name]
-
- classifications = \
- yield self.getChangeClassificationsForTimer(self.objectid,
- timer_name)
-
- # just in case: databases do weird things sometimes!
- if not classifications: # pragma: no cover
- return
-
- changeids = sorted(classifications.keys())
- yield self.addBuildsetForChanges(reason='scheduler',
- changeids=changeids)
-
- max_changeid = changeids[-1] # (changeids are sorted)
- yield self.master.db.schedulers.flushChangeClassifications(
- self.objectid, less_than=max_changeid+1)
-
- def getPendingBuildTimes(self):
- # This isn't locked, since the caller expects and immediate value,
- # and in any case, this is only an estimate.
- return [timer.getTime() for timer in self._stable_timers.values() if timer and timer.active()]
-
-class SingleBranchScheduler(BaseBasicScheduler):
- def getChangeFilter(self, branch, branches, change_filter, categories):
- if branch is NotABranch and not change_filter:
- config.error(
- "the 'branch' argument to SingleBranchScheduler is " +
- "mandatory unless change_filter is provided")
- elif branches is not NotABranch:
- config.error(
- "the 'branches' argument is not allowed for " +
- "SingleBranchScheduler")
-
-
- return filter.ChangeFilter.fromSchedulerConstructorArgs(
- change_filter=change_filter, branch=branch,
- categories=categories)
-
- def getTimerNameForChange(self, change):
- return "only" # this class only uses one timer
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- return self.master.db.schedulers.getChangeClassifications(
- self.objectid)
-
-
-class Scheduler(SingleBranchScheduler):
- "alias for SingleBranchScheduler"
- def __init__(self, *args, **kwargs):
- log.msg("WARNING: the name 'Scheduler' is deprecated; use " +
- "buildbot.schedulers.basic.SingleBranchScheduler instead " +
- "(note that this may require you to change your import " +
- "statement)")
- SingleBranchScheduler.__init__(self, *args, **kwargs)
-
-
-class AnyBranchScheduler(BaseBasicScheduler):
- def getChangeFilter(self, branch, branches, change_filter, categories):
- assert branch is NotABranch
- return filter.ChangeFilter.fromSchedulerConstructorArgs(
- change_filter=change_filter, branch=branches,
- categories=categories)
-
- def getTimerNameForChange(self, change):
- # Py2.6+: could be a namedtuple
- return (change.codebase, change.project, change.repository, change.branch)
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- codebase, project, repository, branch = timer_name # set in getTimerNameForChange
- return self.master.db.schedulers.getChangeClassifications(
- self.objectid, branch=branch, repository=repository,
- codebase=codebase, project=project)
-
-# now at buildbot.schedulers.dependent, but keep the old name alive
-Dependent = dependent.Dependent
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py
deleted file mode 100644
index f28df579..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from twisted.python import log
-from buildbot import util, interfaces, config
-from buildbot.status.results import SUCCESS, WARNINGS
-from buildbot.schedulers import base
-
-class Dependent(base.BaseScheduler):
-
- compare_attrs = base.BaseScheduler.compare_attrs + ('upstream_name',)
-
- def __init__(self, name, upstream, builderNames, properties={}, **kwargs):
- base.BaseScheduler.__init__(self, name, builderNames, properties,
- **kwargs)
- if not interfaces.IScheduler.providedBy(upstream):
- config.error(
- "upstream must be another Scheduler instance")
- self.upstream_name = upstream.name
- self._buildset_addition_subscr = None
- self._buildset_completion_subscr = None
- self._cached_upstream_bsids = None
-
- # the subscription lock makes sure that we're done inserting a
- # subcription into the DB before registering that the buildset is
- # complete.
- self._subscription_lock = defer.DeferredLock()
-
- def startService(self):
- self._buildset_addition_subscr = \
- self.master.subscribeToBuildsets(self._buildsetAdded)
- self._buildset_completion_subscr = \
- self.master.subscribeToBuildsetCompletions(self._buildsetCompleted)
-
- # check for any buildsets completed before we started
- d = self._checkCompletedBuildsets(None, None)
- d.addErrback(log.err, 'while checking for completed buildsets in start')
-
- def stopService(self):
- if self._buildset_addition_subscr:
- self._buildset_addition_subscr.unsubscribe()
- if self._buildset_completion_subscr:
- self._buildset_completion_subscr.unsubscribe()
- self._cached_upstream_bsids = None
- return defer.succeed(None)
-
- @util.deferredLocked('_subscription_lock')
- def _buildsetAdded(self, bsid=None, properties=None, **kwargs):
- # check if this was submitetted by our upstream by checking the
- # scheduler property
- submitter = properties.get('scheduler', (None, None))[0]
- if submitter != self.upstream_name:
- return
-
- # record our interest in this buildset
- d = self._addUpstreamBuildset(bsid)
- d.addErrback(log.err, 'while subscribing to buildset %d' % bsid)
-
- def _buildsetCompleted(self, bsid, result):
- d = self._checkCompletedBuildsets(bsid, result)
- d.addErrback(log.err, 'while checking for completed buildsets')
-
- @util.deferredLocked('_subscription_lock')
- @defer.inlineCallbacks
- def _checkCompletedBuildsets(self, bsid, result):
- subs = yield self._getUpstreamBuildsets()
-
- sub_bsids = []
- for (sub_bsid, sub_sssetid, sub_complete, sub_results) in subs:
- # skip incomplete builds, handling the case where the 'complete'
- # column has not been updated yet
- if not sub_complete and sub_bsid != bsid:
- continue
-
- # build a dependent build if the status is appropriate
- if sub_results in (SUCCESS, WARNINGS):
- yield self.addBuildsetForSourceStamp(setid=sub_sssetid,
- reason='downstream')
-
- sub_bsids.append(sub_bsid)
-
- # and regardless of status, remove the subscriptions
- yield self._removeUpstreamBuildsets(sub_bsids)
-
- @defer.inlineCallbacks
- def _updateCachedUpstreamBuilds(self):
- if self._cached_upstream_bsids is None:
- bsids = yield self.master.db.state.getState(self.objectid,
- 'upstream_bsids', [])
- self._cached_upstream_bsids = bsids
-
- @defer.inlineCallbacks
- def _getUpstreamBuildsets(self):
- # get a list of (bsid, sssid, complete, results) for all
- # upstream buildsets
- yield self._updateCachedUpstreamBuilds()
-
- changed = False
- rv = []
- for bsid in self._cached_upstream_bsids[:]:
- bsdict = yield self.master.db.buildsets.getBuildset(bsid)
- if not bsdict:
- self._cached_upstream_bsids.remove(bsid)
- changed = True
- continue
-
- rv.append((bsid, bsdict['sourcestampsetid'], bsdict['complete'],
- bsdict['results']))
-
- if changed:
- yield self.master.db.state.setState(self.objectid,
- 'upstream_bsids', self._cached_upstream_bsids)
-
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def _addUpstreamBuildset(self, bsid):
- yield self._updateCachedUpstreamBuilds()
-
- if bsid not in self._cached_upstream_bsids:
- self._cached_upstream_bsids.append(bsid)
-
- yield self.master.db.state.setState(self.objectid,
- 'upstream_bsids', self._cached_upstream_bsids)
-
- @defer.inlineCallbacks
- def _removeUpstreamBuildsets(self, bsids):
- yield self._updateCachedUpstreamBuilds()
-
- old = set(self._cached_upstream_bsids)
- self._cached_upstream_bsids = list(old - set(bsids))
-
- yield self.master.db.state.setState(self.objectid,
- 'upstream_bsids', self._cached_upstream_bsids)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py
deleted file mode 100644
index c06e2315..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# old (pre-0.8.4) location for ChangeFilter
-from buildbot.changes.filter import ChangeFilter
-_hush_pyflakes = ChangeFilter # keep pyflakes happy
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py
deleted file mode 100644
index 90ff950f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py
+++ /dev/null
@@ -1,666 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import traceback
-import re
-from twisted.internet import defer
-import email.utils as email_utils
-
-from buildbot.process.properties import Properties
-from buildbot.schedulers import base
-from buildbot import config
-
-class ValidationError(ValueError):
- pass
-
-DefaultField = object() # sentinel object to signal default behavior
-
-class BaseParameter(object):
- """
- BaseParameter provides a base implementation for property customization
- """
- name = ""
- parentName = None
- label = ""
- type = []
- default = ""
- required = False
- multiple = False
- regex = None
- debug=True
- hide = False
-
- @property
- def fullName(self):
- """A full name, intended to uniquely identify a parameter"""
- # join with '_' if both are set
- if self.parentName and self.name:
- return self.parentName+'_'+self.name
- # otherwise just use the one that is set
- # (this allows empty name for "anonymous nests")
- return self.name or self.parentName
-
- def setParent(self, parent):
- self.parentName = parent.fullName if parent else None
-
- def __init__(self, name, label=None, regex=None, **kw):
- """
- @param name: the name of the field, used during posting values
- back to the scheduler. This is not necessarily a UI value,
- and there may be restrictions on the characters allowed for
- this value. For example, HTML would require this field to
- avoid spaces and other punctuation ('-', '.', and '_' allowed)
- @type name: unicode
-
- @param label: (optional) the name of the field, used for UI display.
- @type label: unicode or None (to use 'name')
-
- @param regex: (optional) regex to validate the value with. Not used by
- all subclasses
- @type regex: unicode or regex
- """
-
- self.name = name
- self.label = name if label is None else label
- if regex:
- self.regex = re.compile(regex)
- # all other properties are generically passed via **kw
- self.__dict__.update(kw)
-
- def getFromKwargs(self, kwargs):
- """Simple customization point for child classes that do not need the other
- parameters supplied to updateFromKwargs. Return the value for the property
- named 'self.name'.
-
- The default implementation converts from a list of items, validates using
- the optional regex field and calls 'parse_from_args' for the final conversion.
- """
- args = kwargs.get(self.fullName, [])
- if len(args) == 0:
- if self.required:
- raise ValidationError("'%s' needs to be specified" % (self.label))
- if self.multiple:
- args = self.default
- else:
- args = [self.default]
-
- if self.regex:
- for arg in args:
- if not self.regex.match(arg):
- raise ValidationError("%s:'%s' does not match pattern '%s'"
- % (self.label, arg, self.regex.pattern))
-
- try:
- arg = self.parse_from_args(args)
- except Exception, e:
- # an exception will just display an alert in the web UI
- # also log the exception
- if self.debug:
- traceback.print_exc()
- raise e
- if arg is None:
- raise ValidationError("need %s: no default provided by config"
- % (self.fullName,))
- return arg
-
- def updateFromKwargs(self, properties, kwargs, **unused):
- """Primary entry point to turn 'kwargs' into 'properties'"""
- properties[self.name] = self.getFromKwargs(kwargs)
-
- def parse_from_args(self, l):
- """Secondary customization point, called from getFromKwargs to turn
- a validated value into a single property value"""
- if self.multiple:
- return map(self.parse_from_arg, l)
- else:
- return self.parse_from_arg(l[0])
-
- def parse_from_arg(self, s):
- return s
-
-
-class FixedParameter(BaseParameter):
- """A fixed parameter that cannot be modified by the user."""
- type = ["fixed"]
- hide = True
- default = ""
-
- def parse_from_args(self, l):
- return self.default
-
-
-class StringParameter(BaseParameter):
- """A simple string parameter"""
- type = ["text"]
- size = 10
-
- def parse_from_arg(self, s):
- return s
-
-
-class TextParameter(StringParameter):
- """A generic string parameter that may span multiple lines"""
- type = ["textarea"]
- cols = 80
- rows = 20
-
- def value_to_text(self, value):
- return str(value)
-
-
-class IntParameter(StringParameter):
- """An integer parameter"""
- type = ["int"]
-
- parse_from_arg = int # will throw an exception if parse fail
-
-
-class BooleanParameter(BaseParameter):
- """A boolean parameter"""
- type = ["bool"]
-
- def getFromKwargs(self, kwargs):
- return kwargs.get(self.fullName, None) == [True]
-
-
-class UserNameParameter(StringParameter):
- """A username parameter to supply the 'owner' of a build"""
- type = ["text"]
- default = ""
- size = 30
- need_email = True
-
- def __init__(self, name="username", label="Your name:", **kw):
- BaseParameter.__init__(self, name, label, **kw)
-
- def parse_from_arg(self, s):
- if not s and not self.required:
- return s
- if self.need_email:
- e = email_utils.parseaddr(s)
- if e[0]=='' or e[1] == '':
- raise ValidationError("%s: please fill in email address in the "
- "form 'User <email@email.com>'" % (self.name,))
- return s
-
-
-class ChoiceStringParameter(BaseParameter):
- """A list of strings, allowing the selection of one of the predefined values.
- The 'strict' parameter controls whether values outside the predefined list
- of choices are allowed"""
- type = ["list"]
- choices = []
- strict = True
-
- def parse_from_arg(self, s):
- if self.strict and not s in self.choices:
- raise ValidationError("'%s' does not belongs to list of available choices '%s'"%(s, self.choices))
- return s
-
- def getChoices(self, master, scheduler, buildername):
- return self.choices
-
-class InheritBuildParameter(ChoiceStringParameter):
- """A parameter that takes its values from another build"""
- type = ChoiceStringParameter.type + ["inherit"]
- name = "inherit"
- compatible_builds = None
-
- def getChoices(self, master, scheduler, buildername):
- return self.compatible_builds(master.status, buildername)
-
- def getFromKwargs(self, kwargs):
- raise ValidationError("InheritBuildParameter can only be used by properties")
-
- def updateFromKwargs(self, master, properties, changes, kwargs, **unused):
- arg = kwargs.get(self.fullName, [""])[0]
- splitted_arg = arg.split(" ")[0].split("/")
- if len(splitted_arg) != 2:
- raise ValidationError("bad build: %s"%(arg))
- builder, num = splitted_arg
- builder_status = master.status.getBuilder(builder)
- if not builder_status:
- raise ValidationError("unknown builder: %s in %s"%(builder, arg))
- b = builder_status.getBuild(int(num))
- if not b:
- raise ValidationError("unknown build: %d in %s"%(num, arg))
- props = {self.name:(arg.split(" ")[0])}
- for name, value, source in b.getProperties().asList():
- if source == "Force Build Form":
- if name == "owner":
- name = "orig_owner"
- props[name] = value
- properties.update(props)
- changes.extend(b.changes)
-
-
-class BuildslaveChoiceParameter(ChoiceStringParameter):
- """A parameter that lets the buildslave name be explicitly chosen.
-
- This parameter works in conjunction with 'buildbot.process.builder.enforceChosenSlave',
- which should be added as the 'canStartBuild' parameter to the Builder.
-
- The "anySentinel" parameter represents the sentinel value to specify that
- there is no buildslave preference.
- """
- anySentinel = '-any-'
- label = 'Build slave'
- required = False
- strict = False
-
- def __init__(self, name='slavename', **kwargs):
- ChoiceStringParameter.__init__(self, name, **kwargs)
-
- def updateFromKwargs(self, kwargs, **unused):
- slavename = self.getFromKwargs(kwargs)
- if slavename==self.anySentinel:
- # no preference, so dont set a parameter at all
- return
- ChoiceStringParameter.updateFromKwargs(self, kwargs=kwargs, **unused)
-
- def getChoices(self, master, scheduler, buildername):
- if buildername is None:
- # this is the "Force All Builds" page
- slavenames = master.status.getSlaveNames()
- else:
- builderStatus = master.status.getBuilder(buildername)
- slavenames = [slave.getName() for slave in builderStatus.getSlaves()]
- slavenames.sort()
- slavenames.insert(0, self.anySentinel)
- return slavenames
-
-
-class NestedParameter(BaseParameter):
- """A 'parent' parameter for a set of related parameters. This provices a
- logical grouping for the child parameters.
-
- Typically, the 'fullName' of the child parameters mix in the parent's
- 'fullName'. This allows for a field to appear multiple times in a form
- (for example, two codebases each have a 'branch' field).
-
- If the 'name' of the parent is the empty string, then the parent's name
- does not mix in with the child 'fullName'. This is useful when a field
- will not appear multiple time in a scheduler but the logical grouping is
- helpful.
-
- The result of a NestedParameter is typically a dictionary, with the key/value
- being the name/value of the children.
- """
- type = ['nested']
- fields = None
-
- def __init__(self, name, fields, **kwargs):
- BaseParameter.__init__(self, fields=fields, name=name, **kwargs)
-
- # fix up the child nodes with the parent (use None for now):
- self.setParent(None)
-
- def setParent(self, parent):
- BaseParameter.setParent(self, parent)
- for field in self.fields:
- field.setParent(self)
-
- def collectChildProperties(self, kwargs, properties, **kw):
- """Collapse the child values into a dictionary. This is intended to be
- called by child classes to fix up the fullName->name conversions."""
-
- childProperties = {}
- for field in self.fields:
- field.updateFromKwargs(kwargs=kwargs,
- properties=childProperties,
- **kw)
-
- kwargs[self.fullName] = childProperties
-
- def updateFromKwargs(self, kwargs, properties, **kw):
- """By default, the child values will be collapsed into a dictionary. If
- the parent is anonymous, this dictionary is the top-level properties."""
- self.collectChildProperties(kwargs=kwargs, properties=properties, **kw)
-
- # default behavior is to set a property
- # -- use setdefault+update in order to collapse 'anonymous' nested
- # parameters correctly
- if self.name:
- d = properties.setdefault(self.name, {})
- else:
- # if there's no name, collapse this nest all the way
- d = properties
- d.update(kwargs[self.fullName])
-
-class AnyPropertyParameter(NestedParameter):
- """A generic property parameter, where both the name and value of the property
- must be given."""
- type = NestedParameter.type + ["any"]
-
- def __init__(self, name, **kw):
- fields = [
- StringParameter(name='name', label="Name:"),
- StringParameter(name='value', label="Value:"),
- ]
- NestedParameter.__init__(self, name, label='', fields=fields, **kw)
-
- def getFromKwargs(self, kwargs):
- raise ValidationError("AnyPropertyParameter can only be used by properties")
-
- def updateFromKwargs(self, master, properties, kwargs, **kw):
- self.collectChildProperties(master=master,
- properties=properties,
- kwargs=kwargs,
- **kw)
-
- pname = kwargs[self.fullName].get("name", "")
- pvalue = kwargs[self.fullName].get("value", "")
- if not pname:
- return
-
- validation = master.config.validation
- pname_validate = validation['property_name']
- pval_validate = validation['property_value']
-
- if not pname_validate.match(pname) \
- or not pval_validate.match(pvalue):
- raise ValidationError("bad property name='%s', value='%s'" % (pname, pvalue))
- properties[pname] = pvalue
-
-
-class CodebaseParameter(NestedParameter):
- """A parameter whose result is a codebase specification instead of a property"""
- type = NestedParameter.type + ["codebase"]
- codebase = ''
-
- def __init__(self,
- codebase,
- name=None,
- label=None,
-
- branch=DefaultField,
- revision=DefaultField,
- repository=DefaultField,
- project=DefaultField,
-
- **kwargs):
- """
- A set of properties that will be used to generate a codebase dictionary.
-
- The branch/revision/repository/project should each be a parameter that
- will map to the corresponding value in the sourcestamp. Use None to disable
- the field.
-
- @param codebase: name of the codebase; used as key for the sourcestamp set
- @type codebase: unicode
-
- @param name: optional override for the name-currying for the subfields
- @type codebase: unicode
-
- @param label: optional override for the label for this set of parameters
- @type codebase: unicode
- """
-
- name = name or codebase
- if label is None and codebase:
- label = "Codebase: " + codebase
-
- if branch is DefaultField:
- branch = StringParameter(name='branch', label="Branch:")
- if revision is DefaultField:
- revision = StringParameter(name='revision', label="Revision:")
- if repository is DefaultField:
- repository = StringParameter(name='repository', label="Repository:")
- if project is DefaultField:
- project = StringParameter(name='project', label="Project:")
-
- fields = filter(None, [branch, revision, repository, project])
-
- NestedParameter.__init__(self, name=name, label=label,
- codebase=codebase,
- fields=fields, **kwargs)
-
- def createSourcestamp(self, properties, kwargs):
- # default, just return the things we put together
- return kwargs.get(self.fullName, {})
-
- def updateFromKwargs(self, sourcestamps, kwargs, properties, **kw):
- self.collectChildProperties(sourcestamps=sourcestamps,
- properties=properties,
- kwargs=kwargs,
- **kw)
-
- # convert the "property" to a sourcestamp
- ss = self.createSourcestamp(properties, kwargs)
- if ss is not None:
- sourcestamps[self.codebase] = ss
-
-
-class ForceScheduler(base.BaseScheduler):
- """
- ForceScheduler implements the backend for a UI to allow customization of
- builds. For example, a web form be populated to trigger a build.
- """
- compare_attrs = ( 'name', 'builderNames',
- 'reason', 'username',
- 'forcedProperties' )
-
- def __init__(self, name, builderNames,
- username=UserNameParameter(),
- reason=StringParameter(name="reason", default="force build", length=20),
-
- codebases=None,
-
- properties=[
- NestedParameter(name='', fields=[
- AnyPropertyParameter("property1"),
- AnyPropertyParameter("property2"),
- AnyPropertyParameter("property3"),
- AnyPropertyParameter("property4"),
- ])
- ],
-
- # deprecated; use 'codebase' instead
- branch=None,
- revision=None,
- repository=None,
- project=None
- ):
- """
- Initialize a ForceScheduler.
-
- The UI will provide a set of fields to the user; these fields are
- driven by a corresponding child class of BaseParameter.
-
- Use NestedParameter to provide logical groupings for parameters.
-
- The branch/revision/repository/project fields are deprecated and
- provided only for backwards compatibility. Using a Codebase(name='')
- will give the equivalent behavior.
-
- @param name: name of this scheduler (used as a key for state)
- @type name: unicode
-
- @param builderNames: list of builders this scheduler may start
- @type builderNames: list of unicode
-
- @param username: the "owner" for a build (may not be shown depending
- on the Auth configuration for the master)
- @type username: BaseParameter
-
- @param reason: the "reason" for a build
- @type reason: BaseParameter
-
- @param codebases: the codebases for a build
- @type codebases: list of string's or CodebaseParameter's;
- None will generate a default, but [] will
- remove all codebases
-
- @param properties: extra properties to configure the build
- @type properties: list of BaseParameter's
- """
-
- if not self.checkIfType(name, str):
- config.error("ForceScheduler name must be a unicode string: %r" %
- name)
-
- if not name:
- config.error("ForceScheduler name must not be empty: %r " %
- name)
-
- if not self.checkIfListOfType(builderNames, str):
- config.error("ForceScheduler builderNames must be a list of strings: %r" %
- builderNames)
-
- if self.checkIfType(reason, BaseParameter):
- self.reason = reason
- else:
- config.error("ForceScheduler reason must be a StringParameter: %r" %
- reason)
-
- if not self.checkIfListOfType(properties, BaseParameter):
- config.error("ForceScheduler properties must be a list of BaseParameters: %r" %
- properties)
-
- if self.checkIfType(username, BaseParameter):
- self.username = username
- else:
- config.error("ForceScheduler username must be a StringParameter: %r" %
- username)
-
- self.forcedProperties = []
-
- if any((branch, revision, repository, project)):
- if codebases:
- config.error("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters: %r " % (codebases,))
-
- codebases = [
- CodebaseParameter(codebase='',
- branch=branch or DefaultField,
- revision=revision or DefaultField,
- repository=repository or DefaultField,
- project=project or DefaultField,
- )
- ]
-
- # Use the default single codebase form if none are provided
- if codebases is None:
- codebases =[CodebaseParameter(codebase='')]
- elif not codebases:
- config.error("ForceScheduler: 'codebases' cannot be empty; use CodebaseParameter(codebase='', hide=True) if needed: %r " % (codebases,))
-
- codebase_dict = {}
- for codebase in codebases:
- if isinstance(codebase, basestring):
- codebase = CodebaseParameter(codebase=codebase)
- elif not isinstance(codebase, CodebaseParameter):
- config.error("ForceScheduler: 'codebases' must be a list of strings or CodebaseParameter objects: %r" % (codebases,))
-
- self.forcedProperties.append(codebase)
- codebase_dict[codebase.codebase] = dict(branch='',repository='',revision='')
-
- base.BaseScheduler.__init__(self,
- name=name,
- builderNames=builderNames,
- properties={},
- codebases=codebase_dict)
-
- if properties:
- self.forcedProperties.extend(properties)
-
- # this is used to simplify the template
- self.all_fields = [ NestedParameter(name='', fields=[username, reason]) ]
- self.all_fields.extend(self.forcedProperties)
-
- def checkIfType(self, obj, chkType):
- return isinstance(obj, chkType)
-
- def checkIfListOfType(self, obj, chkType):
- isListOfType = True
-
- if self.checkIfType(obj, list):
- for item in obj:
- if not self.checkIfType(item, chkType):
- isListOfType = False
- break
- else:
- isListOfType = False
-
- return isListOfType
-
- def startService(self):
- pass
-
- def stopService(self):
- pass
-
- @defer.inlineCallbacks
- def gatherPropertiesAndChanges(self, **kwargs):
- properties = {}
- changeids = []
- sourcestamps = {}
-
- for param in self.forcedProperties:
- yield defer.maybeDeferred(param.updateFromKwargs,
- master=self.master,
- properties=properties,
- changes=changeids,
- sourcestamps=sourcestamps,
- kwargs=kwargs)
-
- changeids = map(lambda a: type(a)==int and a or a.number, changeids)
-
- real_properties = Properties()
- for pname, pvalue in properties.items():
- real_properties.setProperty(pname, pvalue, "Force Build Form")
-
- defer.returnValue((real_properties, changeids, sourcestamps))
-
- @defer.inlineCallbacks
- def force(self, owner, builderNames=None, **kwargs):
- """
- We check the parameters, and launch the build, if everything is correct
- """
- if builderNames is None:
- builderNames = self.builderNames
- else:
- builderNames = set(builderNames).intersection(self.builderNames)
-
- if not builderNames:
- defer.returnValue(None)
- return
-
- # Currently the validation code expects all kwargs to be lists
- # I don't want to refactor that now so much sure we comply...
- kwargs = dict((k, [v]) if not isinstance(v, list) else (k,v) for k,v in kwargs.items())
-
- # probably need to clean that out later as the IProperty is already a
- # validation mechanism
-
- reason = self.reason.getFromKwargs(kwargs)
- if owner is None:
- owner = self.username.getFromKwargs(kwargs)
-
- properties, changeids, sourcestamps = yield self.gatherPropertiesAndChanges(**kwargs)
-
- properties.setProperty("reason", reason, "Force Build Form")
- properties.setProperty("owner", owner, "Force Build Form")
-
- r = ("A build was forced by '%s': %s" % (owner, reason))
-
- # everything is validated, we can create our source stamp, and buildrequest
- res = yield self.addBuildsetForSourceStampSetDetails(
- reason = r,
- sourcestamps = sourcestamps,
- properties = properties,
- builderNames = builderNames,
- )
-
- defer.returnValue(res)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py
deleted file mode 100644
index d4c8b795..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from twisted.application import service
-from twisted.python import log, reflect
-from buildbot.process import metrics
-from buildbot import config, util
-
-class SchedulerManager(config.ReconfigurableServiceMixin,
- service.MultiService):
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('scheduler_manager')
- self.master = master
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- timer = metrics.Timer("SchedulerManager.reconfigService")
- timer.start()
-
- old_by_name = dict((sch.name, sch) for sch in self)
- old_set = set(old_by_name.iterkeys())
- new_by_name = new_config.schedulers
- new_set = set(new_by_name.iterkeys())
-
- removed_names, added_names = util.diffSets(old_set, new_set)
-
- # find any schedulers that don't know how to reconfig, and, if they
- # have changed, add them to both removed and added, so that we
- # run the new version. While we're at it, find any schedulers whose
- # fully qualified class name has changed, and consider those a removal
- # and re-add as well.
- for n in old_set & new_set:
- old = old_by_name[n]
- new = new_by_name[n]
- # detect changed class name
- if reflect.qual(old.__class__) != reflect.qual(new.__class__):
- removed_names.add(n)
- added_names.add(n)
-
- # compare using ComparableMixin if they don't support reconfig
- elif not hasattr(old, 'reconfigService'):
- if old != new:
- removed_names.add(n)
- added_names.add(n)
-
- # removals first
-
- for sch_name in removed_names:
- log.msg("removing scheduler '%s'" % (sch_name,))
- sch = old_by_name[sch_name]
- yield defer.maybeDeferred(lambda :
- sch.disownServiceParent())
- sch.master = None
-
- # .. then additions
-
- for sch_name in added_names:
- log.msg("adding scheduler '%s'" % (sch_name,))
- sch = new_by_name[sch_name]
-
- # get the scheduler's objectid
- class_name = '%s.%s' % (sch.__class__.__module__,
- sch.__class__.__name__)
- objectid = yield self.master.db.state.getObjectId(
- sch.name, class_name)
-
- # set up the scheduler
- sch.objectid = objectid
- sch.master = self.master
-
- # *then* attacah and start it
- sch.setServiceParent(self)
-
- metrics.MetricCountEvent.log("num_schedulers", len(list(self)),
- absolute=True)
-
- # reconfig any newly-added schedulers, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- timer.stop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py
deleted file mode 100644
index e735ca93..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py
+++ /dev/null
@@ -1,410 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-
-from buildbot import util
-from buildbot.interfaces import ITriggerableScheduler
-from buildbot.process import buildstep, properties
-from buildbot.schedulers import base
-from twisted.internet import defer, reactor
-from twisted.python import log
-from buildbot import config
-from buildbot.changes import filter
-# Import croniter if available.
-# This is only required for Nightly schedulers,
-# so fail gracefully if it isn't present.
-try:
- from buildbot.util import croniter
-except ImportError:
- # Pyflakes doesn't like a redefinition here
- # Instead, we check if croniter is defined when we need it
- pass
-
-class Timed(base.BaseScheduler):
- """
- Parent class for timed schedulers. This takes care of the (surprisingly
- subtle) mechanics of ensuring that each timed actuation runs to completion
- before the service stops.
- """
-
- compare_attrs = base.BaseScheduler.compare_attrs
-
- def __init__(self, name, builderNames, properties={}, **kwargs):
- base.BaseScheduler.__init__(self, name, builderNames, properties,
- **kwargs)
-
- # tracking for when to start the next build
- self.lastActuated = None
-
- # A lock to make sure that each actuation occurs without interruption.
- # This lock governs actuateAt, actuateAtTimer, and actuateOk
- self.actuationLock = defer.DeferredLock()
- self.actuateOk = False
- self.actuateAt = None
- self.actuateAtTimer = None
-
- self._reactor = reactor # patched by tests
-
- def startService(self):
- base.BaseScheduler.startService(self)
-
- # no need to lock this; nothing else can run before the service is started
- self.actuateOk = True
-
- # get the scheduler's last_build time (note: only done at startup)
- d = self.getState('last_build', None)
- def set_last(lastActuated):
- self.lastActuated = lastActuated
- d.addCallback(set_last)
-
- # schedule the next build
- d.addCallback(lambda _ : self.scheduleNextBuild())
-
- # give subclasses a chance to start up
- d.addCallback(lambda _ : self.startTimedSchedulerService())
-
- # startService does not return a Deferred, so handle errors with a traceback
- d.addErrback(log.err, "while initializing %s '%s'" %
- (self.__class__.__name__, self.name))
-
- def startTimedSchedulerService(self):
- """Hook for subclasses to participate in the L{startService} process;
- can return a Deferred"""
-
- def stopService(self):
- # shut down any pending actuation, and ensure that we wait for any
- # current actuation to complete by acquiring the lock. This ensures
- # that no build will be scheduled after stopService is complete.
- def stop_actuating():
- self.actuateOk = False
- self.actuateAt = None
- if self.actuateAtTimer:
- self.actuateAtTimer.cancel()
- self.actuateAtTimer = None
- d = self.actuationLock.run(stop_actuating)
-
- # and chain to the parent class
- d.addCallback(lambda _ : base.BaseScheduler.stopService(self))
- return d
-
- ## Scheduler methods
-
- def getPendingBuildTimes(self):
- # take the latest-calculated value of actuateAt as a reasonable
- # estimate
- return [ self.actuateAt ]
-
- ## Timed methods
-
- def startBuild(self):
- """The time has come to start a new build. Returns a Deferred.
- Override in subclasses."""
- raise NotImplementedError
-
- def getNextBuildTime(self, lastActuation):
- """
- Called by to calculate the next time to actuate a BuildSet. Override
- in subclasses. To trigger a fresh call to this method, use
- L{rescheduleNextBuild}.
-
- @param lastActuation: the time of the last actuation, or None for never
-
- @returns: a Deferred firing with the next time a build should occur (in
- the future), or None for never.
- """
- raise NotImplementedError
-
- def scheduleNextBuild(self):
- """
- Schedule the next build, re-invoking L{getNextBuildTime}. This can be
- called at any time, and it will avoid contention with builds being
- started concurrently.
-
- @returns: Deferred
- """
- return self.actuationLock.run(self._scheduleNextBuild_locked)
-
- ## utilities
-
- def now(self):
- "Similar to util.now, but patchable by tests"
- return util.now(self._reactor)
-
- def _scheduleNextBuild_locked(self):
- # clear out the existing timer
- if self.actuateAtTimer:
- self.actuateAtTimer.cancel()
- self.actuateAtTimer = None
-
- # calculate the new time
- d = self.getNextBuildTime(self.lastActuated)
-
- # set up the new timer
- def set_timer(actuateAt):
- now = self.now()
- self.actuateAt = max(actuateAt, now)
- if actuateAt is not None:
- untilNext = self.actuateAt - now
- if untilNext == 0:
- log.msg(("%s: missed scheduled build time, so building "
- "immediately") % self.name)
- self.actuateAtTimer = self._reactor.callLater(untilNext,
- self._actuate)
- d.addCallback(set_timer)
-
- return d
-
- def _actuate(self):
- # called from the timer when it's time to start a build
- self.actuateAtTimer = None
- self.lastActuated = self.actuateAt
-
- @defer.inlineCallbacks
- def set_state_and_start():
- # bail out if we shouldn't be actuating anymore
- if not self.actuateOk:
- return
-
- # mark the last build time
- self.actuateAt = None
- yield self.setState('last_build', self.lastActuated)
-
- # start the build
- yield self.startBuild()
-
- # schedule the next build (noting the lock is already held)
- yield self._scheduleNextBuild_locked()
- d = self.actuationLock.run(set_state_and_start)
-
- # this function can't return a deferred, so handle any failures via
- # log.err
- d.addErrback(log.err, 'while actuating')
-
-
-class Periodic(Timed):
- compare_attrs = Timed.compare_attrs + ('periodicBuildTimer', 'branch',)
-
- def __init__(self, name, builderNames, periodicBuildTimer,
- branch=None, properties={}, onlyImportant=False):
- Timed.__init__(self, name=name, builderNames=builderNames,
- properties=properties)
- if periodicBuildTimer <= 0:
- config.error(
- "periodicBuildTimer must be positive")
- self.periodicBuildTimer = periodicBuildTimer
- self.branch = branch
- self.reason = "The Periodic scheduler named '%s' triggered this build" % self.name
-
- def getNextBuildTime(self, lastActuated):
- if lastActuated is None:
- return defer.succeed(self.now()) # meaning "ASAP"
- else:
- return defer.succeed(lastActuated + self.periodicBuildTimer)
-
- def startBuild(self):
- return self.addBuildsetForLatest(reason=self.reason, branch=self.branch)
-
-class NightlyBase(Timed):
- compare_attrs = (Timed.compare_attrs
- + ('minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek'))
-
- def __init__(self, name, builderNames, minute=0, hour='*',
- dayOfMonth='*', month='*', dayOfWeek='*',
- properties={}, codebases=base.BaseScheduler.DefaultCodebases):
- Timed.__init__(self, name=name, builderNames=builderNames,
- properties=properties, codebases=codebases)
-
- self.minute = minute
- self.hour = hour
- self.dayOfMonth = dayOfMonth
- self.month = month
- self.dayOfWeek = dayOfWeek
-
- try:
- croniter
- except NameError:
- config.error("python-dateutil required for scheduler %s '%s'." %
- (self.__class__.__name__, self.name))
-
- def _timeToCron(self, time, isDayOfWeek = False):
- if isinstance(time, int):
- if isDayOfWeek:
- time = (time + 1) % 7 # Convert from Mon = 0 format to Sun = 0 format for use in croniter
- return time
-
- if isinstance(time, basestring):
- return time
-
- if isDayOfWeek:
- time = [ (t + 1) % 7 for t in time ] # Conversion for croniter (see above)
-
- return ','.join([ str(s) for s in time ]) # Convert the list to a string
-
- def getNextBuildTime(self, lastActuated):
- dateTime = lastActuated or self.now()
- sched = '%s %s %s %s %s' % (self._timeToCron(self.minute),
- self._timeToCron(self.hour),
- self._timeToCron(self.dayOfMonth),
- self._timeToCron(self.month),
- self._timeToCron(self.dayOfWeek, True))
- cron = croniter.croniter(sched, dateTime)
- nextdate = cron.get_next(float)
- return defer.succeed(nextdate)
-
-class Nightly(NightlyBase):
- compare_attrs = (NightlyBase.compare_attrs
- + ('branch', 'onlyIfChanged', 'fileIsImportant',
- 'change_filter', 'onlyImportant',))
-
- class NoBranch: pass
- def __init__(self, name, builderNames, minute=0, hour='*',
- dayOfMonth='*', month='*', dayOfWeek='*',
- branch=NoBranch, fileIsImportant=None, onlyIfChanged=False,
- properties={}, change_filter=None, onlyImportant=False,
- codebases = base.BaseScheduler.DefaultCodebases):
- NightlyBase.__init__(self, name=name, builderNames=builderNames,
- minute=minute, hour=hour, dayOfWeek=dayOfWeek, dayOfMonth=dayOfMonth,
- properties=properties, codebases=codebases)
-
- # If True, only important changes will be added to the buildset.
- self.onlyImportant = onlyImportant
-
- if fileIsImportant and not callable(fileIsImportant):
- config.error(
- "fileIsImportant must be a callable")
-
- if branch is Nightly.NoBranch:
- config.error(
- "Nightly parameter 'branch' is required")
-
- self.branch = branch
- self.onlyIfChanged = onlyIfChanged
- self.fileIsImportant = fileIsImportant
- self.change_filter = filter.ChangeFilter.fromSchedulerConstructorArgs(
- change_filter=change_filter)
- self.reason = "The Nightly scheduler named '%s' triggered this build" % self.name
-
- def startTimedSchedulerService(self):
- if self.onlyIfChanged:
- return self.startConsumingChanges(fileIsImportant=self.fileIsImportant,
- change_filter=self.change_filter,
- onlyImportant=self.onlyImportant)
- else:
- return self.master.db.schedulers.flushChangeClassifications(self.objectid)
-
- def gotChange(self, change, important):
- # both important and unimportant changes on our branch are recorded, as
- # we will include all such changes in any buildsets we start. Note
- # that we must check the branch here because it is not included in the
- # change filter.
- if change.branch != self.branch:
- return defer.succeed(None) # don't care about this change
- return self.master.db.schedulers.classifyChanges(
- self.objectid, { change.number : important })
-
- @defer.inlineCallbacks
- def startBuild(self):
- scheds = self.master.db.schedulers
- # if onlyIfChanged is True, then we will skip this build if no
- # important changes have occurred since the last invocation
- if self.onlyIfChanged:
- classifications = \
- yield scheds.getChangeClassifications(self.objectid)
-
- # see if we have any important changes
- for imp in classifications.itervalues():
- if imp:
- break
- else:
- log.msg(("Nightly Scheduler <%s>: skipping build " +
- "- No important changes on configured branch") % self.name)
- return
-
- changeids = sorted(classifications.keys())
- yield self.addBuildsetForChanges(reason=self.reason,
- changeids=changeids)
-
- max_changeid = changeids[-1] # (changeids are sorted)
- yield scheds.flushChangeClassifications(self.objectid,
- less_than=max_changeid+1)
- else:
- # start a build of the latest revision, whatever that is
- yield self.addBuildsetForLatest(reason=self.reason,
- branch=self.branch)
-
-class NightlyTriggerable(NightlyBase):
- implements(ITriggerableScheduler)
- def __init__(self, name, builderNames, minute=0, hour='*',
- dayOfMonth='*', month='*', dayOfWeek='*',
- properties={}, codebases=base.BaseScheduler.DefaultCodebases):
- NightlyBase.__init__(self, name=name, builderNames=builderNames, minute=minute, hour=hour,
- dayOfWeek=dayOfWeek, dayOfMonth=dayOfMonth, properties=properties, codebases=codebases)
-
- self._lastTrigger = None
- self.reason = "The NightlyTriggerable scheduler named '%s' triggered this build" % self.name
-
- def startService(self):
- NightlyBase.startService(self)
-
- # get the scheduler's lastTrigger time (note: only done at startup)
- d = self.getState('lastTrigger', None)
- def setLast(lastTrigger):
- try:
- if lastTrigger:
- assert isinstance(lastTrigger[0], dict)
- self._lastTrigger = (lastTrigger[0], properties.Properties.fromDict(lastTrigger[1]))
- except:
- # If the lastTrigger isn't of the right format, ignore it
- log.msg("NightlyTriggerable Scheduler <%s>: bad lastTrigger: %r" % (self.name, lastTrigger))
- d.addCallback(setLast)
-
- def trigger(self, sourcestamps, set_props=None):
- """Trigger this scheduler with the given sourcestamp ID. Returns a
- deferred that will fire when the buildset is finished."""
- self._lastTrigger = (sourcestamps, set_props)
-
- # record the trigger in the db
- if set_props:
- propsDict = set_props.asDict()
- else:
- propsDict = {}
- d = self.setState('lastTrigger',
- (sourcestamps, propsDict))
-
- ## Trigger expects a callback with the success of the triggered
- ## build, if waitForFinish is True.
- ## Just return SUCCESS, to indicate that the trigger was succesful,
- ## don't want for the nightly to run.
- return d.addCallback(lambda _: buildstep.SUCCESS)
-
- @defer.inlineCallbacks
- def startBuild(self):
- if self._lastTrigger is None:
- defer.returnValue(None)
-
- (sourcestamps, set_props) = self._lastTrigger
- self._lastTrigger = None
- yield self.setState('lastTrigger', None)
-
- # properties for this buildset are composed of our own properties,
- # potentially overridden by anything from the triggering build
- props = properties.Properties()
- props.updateFromProperties(self.properties)
- if set_props:
- props.updateFromProperties(set_props)
-
- yield self.addBuildsetForSourceStampSetDetails(reason=self.reason, sourcestamps=sourcestamps,
- properties=props)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py
deleted file mode 100644
index a50e120e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-
-from twisted.python import failure
-from twisted.internet import defer
-from buildbot.interfaces import ITriggerableScheduler
-from buildbot.schedulers import base
-from buildbot.process.properties import Properties
-
-class Triggerable(base.BaseScheduler):
- implements(ITriggerableScheduler)
-
- compare_attrs = base.BaseScheduler.compare_attrs
-
- def __init__(self, name, builderNames, properties={}, **kwargs):
- base.BaseScheduler.__init__(self, name, builderNames, properties,
- **kwargs)
- self._waiters = {}
- self._bsc_subscription = None
- self.reason = "Triggerable(%s)" % name
-
- def trigger(self, sourcestamps = None, set_props=None):
- """Trigger this scheduler with the optional given list of sourcestamps
- Returns a deferred that will fire when the buildset is finished."""
- # properties for this buildset are composed of our own properties,
- # potentially overridden by anything from the triggering build
- props = Properties()
- props.updateFromProperties(self.properties)
- if set_props:
- props.updateFromProperties(set_props)
-
- # note that this does not use the buildset subscriptions mechanism, as
- # the duration of interest to the caller is bounded by the lifetime of
- # this process.
- d = self.addBuildsetForSourceStampSetDetails(self.reason,
- sourcestamps, props)
- def setup_waiter((bsid,brids)):
- d = defer.Deferred()
- self._waiters[bsid] = (d, brids)
- self._updateWaiters()
- return d
- d.addCallback(setup_waiter)
- return d
-
- def stopService(self):
- # cancel any outstanding subscription
- if self._bsc_subscription:
- self._bsc_subscription.unsubscribe()
- self._bsc_subscription = None
-
- # and errback any outstanding deferreds
- if self._waiters:
- msg = 'Triggerable scheduler stopped before build was complete'
- for d, brids in self._waiters.values():
- d.errback(failure.Failure(RuntimeError(msg)))
- self._waiters = {}
-
- return base.BaseScheduler.stopService(self)
-
-
- def _updateWaiters(self):
- if self._waiters and not self._bsc_subscription:
- self._bsc_subscription = \
- self.master.subscribeToBuildsetCompletions(
- self._buildsetComplete)
- elif not self._waiters and self._bsc_subscription:
- self._bsc_subscription.unsubscribe()
- self._bsc_subscription = None
-
- def _buildsetComplete(self, bsid, result):
- if bsid not in self._waiters:
- return
-
- # pop this bsid from the waiters list, and potentially unsubscribe
- # from completion notifications
- d, brids = self._waiters.pop(bsid)
- self._updateWaiters()
-
- # fire the callback to indicate that the triggered build is complete
- d.callback((result, brids))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py
deleted file mode 100644
index 79179ba8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.internet import defer
-from twisted.python import log
-from twisted.protocols import basic
-
-from buildbot import pbutil
-from buildbot.util.maildir import MaildirService
-from buildbot.util import json
-from buildbot.util import netstrings
-from buildbot.process.properties import Properties
-from buildbot.schedulers import base
-from buildbot.status.buildset import BuildSetStatus
-
-
-class TryBase(base.BaseScheduler):
-
- def filterBuilderList(self, builderNames):
- """
- Make sure that C{builderNames} is a subset of the configured
- C{self.builderNames}, returning an empty list if not. If
- C{builderNames} is empty, use C{self.builderNames}.
-
- @returns: list of builder names to build on
- """
-
- # self.builderNames is the configured list of builders
- # available for try. If the user supplies a list of builders,
- # it must be restricted to the configured list. If not, build
- # on all of the configured builders.
- if builderNames:
- for b in builderNames:
- if not b in self.builderNames:
- log.msg("%s got with builder %s" % (self, b))
- log.msg(" but that wasn't in our list: %s"
- % (self.builderNames,))
- return []
- else:
- builderNames = self.builderNames
- return builderNames
-
-
-class BadJobfile(Exception):
- pass
-
-
-class JobdirService(MaildirService):
- # NOTE: tightly coupled with Try_Jobdir, below
-
- def messageReceived(self, filename):
- f = self.moveToCurDir(filename)
- return self.parent.handleJobFile(filename, f)
-
-
-class Try_Jobdir(TryBase):
-
- compare_attrs = TryBase.compare_attrs + ('jobdir',)
-
- def __init__(self, name, builderNames, jobdir,
- properties={}):
- TryBase.__init__(self, name=name, builderNames=builderNames,
- properties=properties)
- self.jobdir = jobdir
- self.watcher = JobdirService()
- self.watcher.setServiceParent(self)
-
- def startService(self):
- # set the watcher's basedir now that we have a master
- jobdir = os.path.join(self.master.basedir, self.jobdir)
- self.watcher.setBasedir(jobdir)
- for subdir in "cur new tmp".split():
- if not os.path.exists(os.path.join(jobdir, subdir)):
- os.mkdir(os.path.join(jobdir, subdir))
- TryBase.startService(self)
-
- def parseJob(self, f):
- # jobfiles are serialized build requests. Each is a list of
- # serialized netstrings, in the following order:
- # format version number:
- # "1" the original
- # "2" introduces project and repository
- # "3" introduces who
- # "4" introduces comment
- # "5" introduces properties and JSON serialization of values after
- # version
- # jobid: arbitrary string, used to find the buildSet later
- # branch: branch name, "" for default-branch
- # baserev: revision, "" for HEAD
- # patch_level: usually "1"
- # patch_body: patch to be applied for build
- # repository
- # project
- # who: user requesting build
- # comment: comment from user about diff and/or build
- # builderNames: list of builder names
- # properties: dict of build properties
- p = netstrings.NetstringParser()
- f.seek(0,2)
- if f.tell() > basic.NetstringReceiver.MAX_LENGTH:
- raise BadJobfile("The patch size is greater that NetStringReceiver.MAX_LENGTH. Please Set this higher in the master.cfg")
- f.seek(0,0)
- try:
- p.feed(f.read())
- except basic.NetstringParseError:
- raise BadJobfile("unable to parse netstrings")
- if not p.strings:
- raise BadJobfile("could not find any complete netstrings")
- ver = p.strings.pop(0)
-
- v1_keys = ['jobid', 'branch', 'baserev', 'patch_level', 'patch_body']
- v2_keys = v1_keys + ['repository', 'project']
- v3_keys = v2_keys + ['who']
- v4_keys = v3_keys + ['comment']
- keys = [v1_keys, v2_keys, v3_keys, v4_keys]
- # v5 introduces properties and uses JSON serialization
-
- parsed_job = {}
-
- def extract_netstrings(p, keys):
- for i, key in enumerate(keys):
- parsed_job[key] = p.strings[i]
-
- def postprocess_parsed_job():
- # apply defaults and handle type casting
- parsed_job['branch'] = parsed_job['branch'] or None
- parsed_job['baserev'] = parsed_job['baserev'] or None
- parsed_job['patch_level'] = int(parsed_job['patch_level'])
- for key in 'repository project who comment'.split():
- parsed_job[key] = parsed_job.get(key, '')
- parsed_job['properties'] = parsed_job.get('properties', {})
-
- if ver <= "4":
- i = int(ver) - 1
- extract_netstrings(p, keys[i])
- parsed_job['builderNames'] = p.strings[len(keys[i]):]
- postprocess_parsed_job()
- elif ver == "5":
- try:
- parsed_job = json.loads(p.strings[0])
- except ValueError:
- raise BadJobfile("unable to parse JSON")
- postprocess_parsed_job()
- else:
- raise BadJobfile("unknown version '%s'" % ver)
- return parsed_job
-
- def handleJobFile(self, filename, f):
- try:
- parsed_job = self.parseJob(f)
- builderNames = parsed_job['builderNames']
- except BadJobfile:
- log.msg("%s reports a bad jobfile in %s" % (self, filename))
- log.err()
- return defer.succeed(None)
-
- # Validate/fixup the builder names.
- builderNames = self.filterBuilderList(builderNames)
- if not builderNames:
- log.msg(
- "incoming Try job did not specify any allowed builder names")
- return defer.succeed(None)
-
- who = ""
- if parsed_job['who']:
- who = parsed_job['who']
-
- comment = ""
- if parsed_job['comment']:
- comment = parsed_job['comment']
-
- d = self.master.db.sourcestampsets.addSourceStampSet()
-
- def addsourcestamp(setid):
- self.master.db.sourcestamps.addSourceStamp(
- sourcestampsetid=setid,
- branch=parsed_job['branch'],
- revision=parsed_job['baserev'],
- patch_body=parsed_job['patch_body'],
- patch_level=parsed_job['patch_level'],
- patch_author=who,
- patch_comment=comment,
- patch_subdir='', # TODO: can't set this remotely - #1769
- project=parsed_job['project'],
- repository=parsed_job['repository'])
- return setid
-
- d.addCallback(addsourcestamp)
-
- def create_buildset(setid):
- reason = "'try' job"
- if parsed_job['who']:
- reason += " by user %s" % parsed_job['who']
- properties = parsed_job['properties']
- requested_props = Properties()
- requested_props.update(properties, "try build")
- return self.addBuildsetForSourceStamp(
- ssid=None, setid=setid,
- reason=reason, external_idstring=parsed_job['jobid'],
- builderNames=builderNames, properties=requested_props)
- d.addCallback(create_buildset)
- return d
-
-
-class Try_Userpass_Perspective(pbutil.NewCredPerspective):
- def __init__(self, scheduler, username):
- self.scheduler = scheduler
- self.username = username
-
- @defer.inlineCallbacks
- def perspective_try(self, branch, revision, patch, repository, project,
- builderNames, who="", comment="", properties={}):
- db = self.scheduler.master.db
- log.msg("user %s requesting build on builders %s" % (self.username,
- builderNames))
-
- # build the intersection of the request and our configured list
- builderNames = self.scheduler.filterBuilderList(builderNames)
- if not builderNames:
- return
-
- reason = "'try' job"
-
- if who:
- reason += " by user %s" % who
-
- if comment:
- reason += " (%s)" % comment
-
- sourcestampsetid = yield db.sourcestampsets.addSourceStampSet()
-
- yield db.sourcestamps.addSourceStamp(
- branch=branch, revision=revision, repository=repository,
- project=project, patch_level=patch[0], patch_body=patch[1],
- patch_subdir='', patch_author=who or '',
- patch_comment=comment or '',
- sourcestampsetid=sourcestampsetid)
- # note: no way to specify patch subdir - #1769
-
- requested_props = Properties()
- requested_props.update(properties, "try build")
- (bsid, brids) = yield self.scheduler.addBuildsetForSourceStamp(
- setid=sourcestampsetid, reason=reason,
- properties=requested_props, builderNames=builderNames)
-
- # return a remotely-usable BuildSetStatus object
- bsdict = yield db.buildsets.getBuildset(bsid)
-
- bss = BuildSetStatus(bsdict, self.scheduler.master.status)
- from buildbot.status.client import makeRemote
- defer.returnValue(makeRemote(bss))
-
- def perspective_getAvailableBuilderNames(self):
- # Return a list of builder names that are configured
- # for the try service
- # This is mostly intended for integrating try services
- # into other applications
- return self.scheduler.listBuilderNames()
-
-
-class Try_Userpass(TryBase):
- compare_attrs = ('name', 'builderNames', 'port', 'userpass', 'properties')
-
- def __init__(self, name, builderNames, port, userpass,
- properties={}):
- TryBase.__init__(self, name=name, builderNames=builderNames,
- properties=properties)
- self.port = port
- self.userpass = userpass
-
- def startService(self):
- TryBase.startService(self)
-
- # register each user/passwd with the pbmanager
- def factory(mind, username):
- return Try_Userpass_Perspective(self, username)
- self.registrations = []
- for user, passwd in self.userpass:
- self.registrations.append(
- self.master.pbmanager.register(
- self.port, user, passwd, factory))
-
- def stopService(self):
- d = defer.maybeDeferred(TryBase.stopService, self)
-
- def unreg(_):
- return defer.gatherResults(
- [reg.unregister() for reg in self.registrations])
- d.addCallback(unreg)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py
deleted file mode 100644
index b1349a65..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import copy
-import stat
-from twisted.python import usage, runtime
-
-def isBuildmasterDir(dir):
- def print_error(error_message):
- print "%s\ninvalid buildmaster directory '%s'" % (error_message, dir)
-
- buildbot_tac = os.path.join(dir, "buildbot.tac")
- try:
- contents = open(buildbot_tac).read()
- except IOError, exception:
- print_error("error reading '%s': %s" % \
- (buildbot_tac, exception.strerror))
- return False
-
- if "Application('buildmaster')" not in contents:
- print_error("unexpected content in '%s'" % buildbot_tac)
- return False
-
- return True
-
-def getConfigFileFromTac(basedir):
- # execute the .tac file to see if its configfile location exists
- tacFile = os.path.join(basedir, 'buildbot.tac')
- if os.path.exists(tacFile):
- # don't mess with the global namespace, but set __file__ for relocatable buildmasters
- tacGlobals = {'__file__' : tacFile}
- execfile(tacFile, tacGlobals)
- return tacGlobals.get("configfile", "master.cfg")
- else:
- return "master.cfg"
-
-class SubcommandOptions(usage.Options):
- # subclasses should set this to a list-of-lists in order to source the
- # .buildbot/options file. Note that this *only* works with optParameters,
- # not optFlags. Example:
- # buildbotOptions = [ [ 'optfile-name', 'parameter-name' ], .. ]
- buildbotOptions = None
-
- # set this to options that must have non-None values
- requiredOptions = []
-
- def __init__(self, *args):
- # for options in self.buildbotOptions, optParameters, and the options
- # file, change the default in optParameters to the value in the options
- # file, call through to the constructor, and then change it back.
- # Options uses reflect.accumulateClassList, so this *must* be a class
- # attribute; however, we do not want to permanently change the class.
- # So we patch it temporarily and restore it after.
- cls = self.__class__
- if hasattr(cls, 'optParameters'):
- old_optParameters = cls.optParameters
- cls.optParameters = op = copy.deepcopy(cls.optParameters)
- if self.buildbotOptions:
- optfile = self.optionsFile = self.loadOptionsFile()
- for optfile_name, option_name in self.buildbotOptions:
- for i in range(len(op)):
- if (op[i][0] == option_name
- and optfile_name in optfile):
- op[i] = list(op[i])
- op[i][2] = optfile[optfile_name]
- usage.Options.__init__(self, *args)
- if hasattr(cls, 'optParameters'):
- cls.optParameters = old_optParameters
-
- def loadOptionsFile(self, _here=None):
- """Find the .buildbot/options file. Crawl from the current directory
- up towards the root, and also look in ~/.buildbot . The first directory
- that's owned by the user and has the file we're looking for wins.
- Windows skips the owned-by-user test.
-
- @rtype: dict
- @return: a dictionary of names defined in the options file. If no
- options file was found, return an empty dict.
- """
-
- here = _here or os.path.abspath(os.getcwd())
-
- if runtime.platformType == 'win32':
- # never trust env-vars, use the proper API
- from win32com.shell import shellcon, shell
- appdata = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)
- home = os.path.join(appdata, "buildbot")
- else:
- home = os.path.expanduser("~/.buildbot")
-
- searchpath = []
- toomany = 20
- while True:
- searchpath.append(os.path.join(here, ".buildbot"))
- next = os.path.dirname(here)
- if next == here:
- break # we've hit the root
- here = next
- toomany -= 1 # just in case
- if toomany == 0:
- print ("I seem to have wandered up into the infinite glories "
- "of the heavens. Oops.")
- break
-
- searchpath.append(home)
-
- localDict = {}
-
- for d in searchpath:
- if os.path.isdir(d):
- if runtime.platformType != 'win32':
- if os.stat(d)[stat.ST_UID] != os.getuid():
- print "skipping %s because you don't own it" % d
- continue # security, skip other people's directories
- optfile = os.path.join(d, "options")
- if os.path.exists(optfile):
- try:
- with open(optfile, "r") as f:
- options = f.read()
- exec options in localDict
- except:
- print "error while reading %s" % optfile
- raise
- break
-
- for k in localDict.keys():
- if k.startswith("__"):
- del localDict[k]
- return localDict
-
- def postOptions(self):
- missing = [ k for k in self.requiredOptions if self[k] is None ]
- if missing:
- if len(missing) > 1:
- msg = 'Required arguments missing: ' + ', '.join(missing)
- else:
- msg = 'Required argument missing: ' + missing[0]
- raise usage.UsageError(msg)
-
-class BasedirMixin(object):
-
- """SubcommandOptions Mixin to handle subcommands that take a basedir
- argument"""
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['basedir'] = args[0]
- else:
- # Use the current directory if no basedir was specified.
- self['basedir'] = os.getcwd()
- if len(args) > 1:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- # get an unambiguous, epxnaed basedir, including expanding '~', which
- # may be useful in a .buildbot/config file
- self['basedir'] = os.path.abspath(os.path.expanduser(self['basedir']))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl
deleted file mode 100644
index 146c9698..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl
+++ /dev/null
@@ -1,42 +0,0 @@
-import os
-
-from twisted.application import service
-from buildbot.master import BuildMaster
-
-{% if relocatable -%}
-basedir = '.'
-{% else -%}
-basedir = {{ basedir|repr }}
-{%- endif %}
-{% if not no_logrotate -%}
-rotateLength = {{ log_size|repr }}
-maxRotatedFiles = {{ log_count|repr }}
-{%- endif %}
-configfile = {{ config|repr }}
-
-# Default umask for server
-umask = None
-
-# if this is a relocatable tac file, get the directory containing the TAC
-if basedir == '.':
- import os.path
- basedir = os.path.abspath(os.path.dirname(__file__))
-
-# note: this line is matched against to check that this is a buildmaster
-# directory; do not edit it.
-application = service.Application('buildmaster')
-{% if not no_logrotate -%}
-from twisted.python.logfile import LogFile
-from twisted.python.log import ILogObserver, FileLogObserver
-logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
- maxRotatedFiles=maxRotatedFiles)
-application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
-{%- endif %}
-
-m = BuildMaster(basedir, configfile, umask)
-m.setServiceParent(application)
-{% if not no_logrotate -%}
-m.log_rotation.rotateLength = rotateLength
-m.log_rotation.maxRotatedFiles = maxRotatedFiles
-{%- endif %}
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py
deleted file mode 100644
index 8e05b0bb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import os
-from buildbot import config
-from buildbot.scripts.base import getConfigFileFromTac
-
-def _loadConfig(basedir, configFile, quiet):
- try:
- config.MasterConfig.loadConfig(
- basedir, configFile)
- except config.ConfigErrors, e:
- if not quiet:
- print >> sys.stderr, "Configuration Errors:"
- for e in e.errors:
- print >> sys.stderr, " " + e
- return 1
-
- if not quiet:
- print "Config file is good!"
- return 0
-
-
-def checkconfig(config):
- quiet = config.get('quiet')
- configFile = config.get('configFile')
-
- if os.path.isdir(configFile):
- basedir = configFile
- try:
- configFile = getConfigFileFromTac(basedir)
- except (SyntaxError, ImportError), e:
- if not quiet:
- print "Unable to load 'buildbot.tac' from '%s':" % basedir
- print e
- return 1
- else:
- basedir = os.getcwd()
-
- return _loadConfig(basedir=basedir, configFile=configFile, quiet=quiet)
-
-
-__all__ = ['checkconfig']
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py
deleted file mode 100644
index ba5a5f60..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import jinja2
-from twisted.python import util
-from twisted.internet import defer
-from buildbot.util import in_reactor
-from buildbot.db import connector
-from buildbot.master import BuildMaster
-from buildbot import config as config_module
-from buildbot import monkeypatches
-
-def makeBasedir(config):
- if os.path.exists(config['basedir']):
- if not config['quiet']:
- print "updating existing installation"
- return
- if not config['quiet']:
- print "mkdir", config['basedir']
- os.mkdir(config['basedir'])
-
-def makeTAC(config):
- # render buildbot_tac.tmpl using the config
- loader = jinja2.FileSystemLoader(os.path.dirname(__file__))
- env = jinja2.Environment(loader=loader, undefined=jinja2.StrictUndefined)
- env.filters['repr'] = repr
- tpl = env.get_template('buildbot_tac.tmpl')
- cxt = dict((k.replace('-', '_'), v) for k,v in config.iteritems())
- contents = tpl.render(cxt)
-
- tacfile = os.path.join(config['basedir'], "buildbot.tac")
- if os.path.exists(tacfile):
- with open(tacfile, "rt") as f:
- oldcontents = f.read()
- if oldcontents == contents:
- if not config['quiet']:
- print "buildbot.tac already exists and is correct"
- return
- if not config['quiet']:
- print "not touching existing buildbot.tac"
- print "creating buildbot.tac.new instead"
- tacfile += ".new"
- with open(tacfile, "wt") as f:
- f.write(contents)
-
-def makeSampleConfig(config):
- source = util.sibpath(__file__, "sample.cfg")
- target = os.path.join(config['basedir'], "master.cfg.sample")
- if not config['quiet']:
- print "creating %s" % target
- with open(source, "rt") as f:
- config_sample = f.read()
- if config['db']:
- config_sample = config_sample.replace('sqlite:///state.sqlite',
- config['db'])
- with open(target, "wt") as f:
- f.write(config_sample)
- os.chmod(target, 0600)
-
-def makePublicHtml(config):
- files = {
- 'bg_gradient.jpg' : "../status/web/files/bg_gradient.jpg",
- 'default.css' : "../status/web/files/default.css",
- 'robots.txt' : "../status/web/files/robots.txt",
- 'favicon.ico' : "../status/web/files/favicon.ico",
- }
- webdir = os.path.join(config['basedir'], "public_html")
- if os.path.exists(webdir):
- if not config['quiet']:
- print "public_html/ already exists: not replacing"
- return
- else:
- os.mkdir(webdir)
- if not config['quiet']:
- print "populating public_html/"
- for target, source in files.iteritems():
- source = util.sibpath(__file__, source)
- target = os.path.join(webdir, target)
- with open(target, "wt") as f:
- with open(source, "rt") as i:
- f.write(i.read())
-
-def makeTemplatesDir(config):
- files = {
- 'README.txt' : "../status/web/files/templates_readme.txt",
- }
- template_dir = os.path.join(config['basedir'], "templates")
- if os.path.exists(template_dir):
- if not config['quiet']:
- print "templates/ already exists: not replacing"
- return
- else:
- os.mkdir(template_dir)
- if not config['quiet']:
- print "populating templates/"
- for target, source in files.iteritems():
- source = util.sibpath(__file__, source)
- target = os.path.join(template_dir, target)
- with open(target, "wt") as f:
- with open(source, "rt") as i:
- f.write(i.read())
-
-@defer.inlineCallbacks
-def createDB(config, _noMonkey=False):
- # apply the db monkeypatches (and others - no harm)
- if not _noMonkey: # pragma: no cover
- monkeypatches.patch_all()
-
- # create a master with the default configuration, but with db_url
- # overridden
- master_cfg = config_module.MasterConfig()
- master_cfg.db['db_url'] = config['db']
- master = BuildMaster(config['basedir'])
- master.config = master_cfg
- db = connector.DBConnector(master, config['basedir'])
- yield db.setup(check_version=False, verbose=not config['quiet'])
- if not config['quiet']:
- print "creating database (%s)" % (master_cfg.db['db_url'],)
- yield db.model.upgrade()
-
-
-@in_reactor
-@defer.inlineCallbacks
-def createMaster(config):
- makeBasedir(config)
- makeTAC(config)
- makeSampleConfig(config)
- makePublicHtml(config)
- makeTemplatesDir(config)
- yield createDB(config)
-
- if not config['quiet']:
- print "buildmaster configured in %s" % (config['basedir'],)
-
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py
deleted file mode 100644
index 4846c0bf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-def debugclient(config):
- from buildbot.clients import debug
-
- d = debug.DebugWidget(config['master'], config['passwd'])
- d.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py
deleted file mode 100644
index dede9704..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os
-from twisted.python.failure import Failure
-from twisted.internet import defer, reactor, protocol, error
-from twisted.protocols.basic import LineOnlyReceiver
-
-class FakeTransport:
- disconnecting = False
-
-class BuildmasterTimeoutError(Exception):
- pass
-class ReconfigError(Exception):
- pass
-
-class TailProcess(protocol.ProcessProtocol):
- def outReceived(self, data):
- self.lw.dataReceived(data)
- def errReceived(self, data):
- print "ERR: '%s'" % (data,)
-
-
-class LogWatcher(LineOnlyReceiver):
- POLL_INTERVAL = 0.1
- TIMEOUT_DELAY = 10.0
- delimiter = os.linesep
-
- def __init__(self, logfile):
- self.logfile = logfile
- self.in_reconfig = False
- self.transport = FakeTransport()
- self.pp = TailProcess()
- self.pp.lw = self
- self.timer = None
-
- def start(self):
- # If the log file doesn't exist, create it now.
- if not os.path.exists(self.logfile):
- open(self.logfile, 'a').close()
-
- # return a Deferred that fires when the reconfig process has
- # finished. It errbacks with TimeoutError if the finish line has not
- # been seen within 10 seconds, and with ReconfigError if the error
- # line was seen. If the logfile could not be opened, it errbacks with
- # an IOError.
- self.p = reactor.spawnProcess(self.pp, "/usr/bin/tail",
- ("tail", "-f", "-n", "0", self.logfile),
- env=os.environ,
- )
- self.running = True
- d = defer.maybeDeferred(self._start)
- return d
-
- def _start(self):
- self.d = defer.Deferred()
- self.timer = reactor.callLater(self.TIMEOUT_DELAY, self.timeout)
- return self.d
-
- def timeout(self):
- self.timer = None
- e = BuildmasterTimeoutError()
- self.finished(Failure(e))
-
- def finished(self, results):
- try:
- self.p.signalProcess("KILL")
- except error.ProcessExitedAlready:
- pass
- if self.timer:
- self.timer.cancel()
- self.timer = None
- self.running = False
- self.in_reconfig = False
- self.d.callback(results)
-
- def lineReceived(self, line):
- if not self.running:
- return
- if "Log opened." in line:
- self.in_reconfig = True
- if "beginning configuration update" in line:
- self.in_reconfig = True
-
- if self.in_reconfig:
- print line
-
- if "message from master: attached" in line:
- return self.finished("buildslave")
- if "reconfig aborted" in line or 'reconfig partially applied' in line:
- return self.finished(Failure(ReconfigError()))
- if "Server Shut Down" in line:
- return self.finished(Failure(ReconfigError()))
- if "configuration update complete" in line:
- return self.finished("buildmaster")
- if "BuildMaster is running" in line:
- return self.finished("buildmaster")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py
deleted file mode 100644
index a7f5602e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-import os
-import signal
-import platform
-from twisted.internet import reactor
-
-from buildbot.scripts.logwatcher import LogWatcher, BuildmasterTimeoutError, \
- ReconfigError
-from buildbot.util import in_reactor
-
-class Reconfigurator:
-
- rc = 0
-
- def run(self, basedir, quiet):
- # Returns "Microsoft" for Vista and "Windows" for other versions
- if platform.system() in ("Windows", "Microsoft"):
- print "Reconfig (through SIGHUP) is not supported on Windows."
- print "The 'buildbot debugclient' tool can trigger a reconfig"
- print "remotely, but requires Gtk+ libraries to run."
- return
-
- with open(os.path.join(basedir, "twistd.pid"), "rt") as f:
- self.pid = int(f.read().strip())
- if quiet:
- os.kill(self.pid, signal.SIGHUP)
- return
-
- # keep reading twistd.log. Display all messages between "loading
- # configuration from ..." and "configuration update complete" or
- # "I will keep using the previous config file instead.", or until
- # 10 seconds have elapsed.
-
- self.sent_signal = False
- reactor.callLater(0.2, self.sighup)
-
- lw = LogWatcher(os.path.join(basedir, "twistd.log"))
- d = lw.start()
- d.addCallbacks(self.success, self.failure)
- d.addBoth(lambda _ : self.rc)
- return d
-
- def sighup(self):
- if self.sent_signal:
- return
- print "sending SIGHUP to process %d" % self.pid
- self.sent_signal = True
- os.kill(self.pid, signal.SIGHUP)
-
- def success(self, res):
- print """
-Reconfiguration appears to have completed successfully.
-"""
-
- def failure(self, why):
- self.rc = 1
- if why.check(BuildmasterTimeoutError):
- print "Never saw reconfiguration finish."
- elif why.check(ReconfigError):
- print """
-Reconfiguration failed. Please inspect the master.cfg file for errors,
-correct them, then try 'buildbot reconfig' again.
-"""
- elif why.check(IOError):
- # we were probably unable to open the file in the first place
- self.sighup()
- else:
- print "Error while following twistd.log: %s" % why
-
-@in_reactor
-def reconfig(config):
- basedir = config['basedir']
- quiet = config['quiet']
- r = Reconfigurator()
- return r.run(basedir, quiet)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py
deleted file mode 100644
index f9e0e28a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-from buildbot.scripts import base, stop, start
-
-def restart(config):
- basedir = config['basedir']
- quiet = config['quiet']
-
- if not base.isBuildmasterDir(basedir):
- return 1
-
- if stop.stop(config, wait=True) != 0:
- return 1
- if not quiet:
- print "now restarting buildbot process.."
- return start.start(config)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py
deleted file mode 100644
index 89254c2a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py
+++ /dev/null
@@ -1,731 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-# N.B.: don't import anything that might pull in a reactor yet. Some of our
-# subcommands want to load modules that need the gtk reactor.
-#
-# Also don't forget to mirror your changes on command-line options in manual
-# pages and texinfo documentation.
-
-from twisted.python import usage, reflect
-import re
-import sys
-
-from buildbot.scripts import base
-
-# Note that the terms 'options' and 'config' are used interchangeably here - in
-# fact, they are interchanged several times. Caveat legator.
-
-def validateMasterOption(master):
- """
- Validate master (-m, --master) command line option.
-
- Checks that option is a string of the 'hostname:port' form, otherwise
- raises an UsageError exception.
-
- @type master: string
- @param master: master option
-
- @raise usage.UsageError: on invalid master option
- """
- try:
- hostname, port = master.split(":")
- port = int(port)
- except:
- raise usage.UsageError("master must have the form 'hostname:port'")
-
-
-class UpgradeMasterOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.upgrade_master.upgradeMaster"
- optFlags = [
- ["quiet", "q", "Do not emit the commands being run"],
- ["replace", "r", "Replace any modified files without confirmation."],
- ]
- optParameters = [
- ]
-
- def getSynopsis(self):
- return "Usage: buildbot upgrade-master [options] [<basedir>]"
-
- longdesc = """
- This command takes an existing buildmaster working directory and
- adds/modifies the files there to work with the current version of
- buildbot. When this command is finished, the buildmaster directory should
- look much like a brand-new one created by the 'create-master' command.
-
- Use this after you've upgraded your buildbot installation and before you
- restart the buildmaster to use the new version.
-
- If you have modified the files in your working directory, this command
- will leave them untouched, but will put the new recommended contents in a
- .new file (for example, if index.html has been modified, this command
- will create index.html.new). You can then look at the new version and
- decide how to merge its contents into your modified file.
-
- When upgrading from a pre-0.8.0 release (which did not use a database),
- this command will create the given database and migrate data from the old
- pickle files into it, then move the pickle files out of the way (e.g. to
- changes.pck.old).
-
- When upgrading the database, this command uses the database specified in
- the master configuration file. If you wish to use a database other than
- the default (sqlite), be sure to set that parameter before upgrading.
- """
-
-
-class CreateMasterOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.create_master.createMaster"
- optFlags = [
- ["quiet", "q", "Do not emit the commands being run"],
- ["force", "f",
- "Re-use an existing directory (will not overwrite master.cfg file)"],
- ["relocatable", "r",
- "Create a relocatable buildbot.tac"],
- ["no-logrotate", "n",
- "Do not permit buildmaster rotate logs by itself"]
- ]
- optParameters = [
- ["config", "c", "master.cfg", "name of the buildmaster config file"],
- ["log-size", "s", "10000000",
- "size at which to rotate twisted log files"],
- ["log-count", "l", "10",
- "limit the number of kept old twisted log files"],
- ["db", None, "sqlite:///state.sqlite",
- "which DB to use for scheduler/status state. See below for syntax."],
- ]
- def getSynopsis(self):
- return "Usage: buildbot create-master [options] [<basedir>]"
-
- longdesc = """
- This command creates a buildmaster working directory and buildbot.tac file.
- The master will live in <dir> and create various files there. If
- --relocatable is given, then the resulting buildbot.tac file will be
- written such that its containing directory is assumed to be the basedir.
- This is generally a good idea.
-
- At runtime, the master will read a configuration file (named
- 'master.cfg' by default) in its basedir. This file should contain python
- code which eventually defines a dictionary named 'BuildmasterConfig'.
- The elements of this dictionary are used to configure the Buildmaster.
- See doc/config.xhtml for details about what can be controlled through
- this interface.
-
- The --db string is evaluated to build the DB object, which specifies
- which database the buildmaster should use to hold scheduler state and
- status information. The default (which creates an SQLite database in
- BASEDIR/state.sqlite) is equivalent to:
-
- --db='sqlite:///state.sqlite'
-
- To use a remote MySQL database instead, use something like:
-
- --db='mysql://bbuser:bbpasswd@dbhost/bbdb'
- The --db string is stored verbatim in the buildbot.tac file, and
- evaluated as 'buildbot start' time to pass a DBConnector instance into
- the newly-created BuildMaster object.
- """
-
- def postOptions(self):
- base.BasedirMixin.postOptions(self)
- if not re.match('^\d+$', self['log-size']):
- raise usage.UsageError("log-size parameter needs to be an int")
- if not re.match('^\d+$', self['log-count']) and \
- self['log-count'] != 'None':
- raise usage.UsageError("log-count parameter needs to be an int "+
- " or None")
-
-
-class StopOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.stop.stop"
- optFlags = [
- ["quiet", "q", "Do not emit the commands being run"],
- ["clean", "c", "Clean shutdown master"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot stop [<basedir>]"
-
-
-class RestartOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.restart.restart"
- optFlags = [
- ['quiet', 'q', "Don't display startup log messages"],
- ['nodaemon', None, "Don't daemonize (stay in foreground)"],
- ["clean", "c", "Clean shutdown master"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot restart [<basedir>]"
-
-
-class StartOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.start.start"
- optFlags = [
- ['quiet', 'q', "Don't display startup log messages"],
- ['nodaemon', None, "Don't daemonize (stay in foreground)"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot start [<basedir>]"
-
-
-class ReconfigOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.reconfig.reconfig"
- optFlags = [
- ['quiet', 'q', "Don't display log messages about reconfiguration"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot reconfig [<basedir>]"
-
-
-class DebugClientOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.debugclient.debugclient"
- optParameters = [
- ["master", "m", None,
- "Location of the buildmaster's slaveport (host:port)"],
- ["passwd", "p", None, "Debug password to use"],
- ]
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'debugMaster', 'master' ],
- ]
- requiredOptions = [ 'master', 'passwd' ]
-
- def getSynopsis(self):
- return "Usage: buildbot debugclient [options]"
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['master'] = args[0]
- if len(args) > 1:
- self['passwd'] = args[1]
- if len(args) > 2:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
- validateMasterOption(self.get('master'))
-
-
-class BaseStatusClientOptions(base.SubcommandOptions):
- optFlags = [
- ['help', 'h', "Display this message"],
- ]
- optParameters = [
- ["master", "m", None,
- "Location of the buildmaster's status port (host:port)"],
- ["username", "u", "statusClient", "Username performing the trial build"],
- ["passwd", 'p', "clientpw", "password for PB authentication"],
- ]
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'masterstatus', 'master' ],
- ]
- requiredOptions = [ 'master' ]
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['master'] = args[0]
- if len(args) > 1:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
- validateMasterOption(self.get('master'))
-
-
-
-class StatusLogOptions(BaseStatusClientOptions):
- subcommandFunction = "buildbot.scripts.statuslog.statuslog"
- def getSynopsis(self):
- return "Usage: buildbot statuslog [options]"
-
-
-class StatusGuiOptions(BaseStatusClientOptions):
- subcommandFunction = "buildbot.scripts.statusgui.statusgui"
- def getSynopsis(self):
- return "Usage: buildbot statusgui [options]"
-
-
-class SendChangeOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.sendchange.sendchange"
- def __init__(self):
- base.SubcommandOptions.__init__(self)
- self['properties'] = {}
-
- optParameters = [
- ("master", "m", None,
- "Location of the buildmaster's PBListener (host:port)"),
- # deprecated in 0.8.3; remove in 0.8.5 (bug #1711)
- ("auth", "a", 'change:changepw',
- "Authentication token - username:password, or prompt for password"),
- ("who", "W", None, "Author of the commit"),
- ("repository", "R", '', "Repository specifier"),
- ("vc", "s", None, "The VC system in use, one of: cvs, svn, darcs, hg, "
- "bzr, git, mtn, p4"),
- ("project", "P", '', "Project specifier"),
- ("branch", "b", None, "Branch specifier"),
- ("category", "C", None, "Category of repository"),
- ("codebase", None, None,
- "Codebase this change is in (requires 0.8.7 master or later)"),
- ("revision", "r", None, "Revision specifier"),
- ("revision_file", None, None, "Filename containing revision spec"),
- ("property", "p", None,
- "A property for the change, in the format: name:value"),
- ("comments", "c", None, "log message"),
- ("logfile", "F", None,
- "Read the log messages from this file (- for stdin)"),
- ("when", "w", None, "timestamp to use as the change time"),
- ("revlink", "l", '', "Revision link (revlink)"),
- ("encoding", "e", 'utf8',
- "Encoding of other parameters (default utf8)"),
- ]
-
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'who', 'who' ],
- [ 'branch', 'branch' ],
- [ 'category', 'category' ],
- [ 'vc', 'vc' ],
- ]
-
- requiredOptions = [ 'who', 'master' ]
-
- def getSynopsis(self):
- return "Usage: buildbot sendchange [options] filenames.."
-
- def parseArgs(self, *args):
- self['files'] = args
-
- def opt_property(self, property):
- name,value = property.split(':', 1)
- self['properties'][name] = value
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
-
- if self.get("revision_file"):
- with open(self["revision_file"],"r") as f:
- self['revision'] = f.read()
-
- if self.get('when'):
- try:
- self['when'] = float(self['when'])
- except:
- raise usage.UsageError('invalid "when" value %s'
- % (self['when'],))
- else:
- self['when'] = None
-
- if not self.get('comments') and self.get('logfile'):
- if self['logfile'] == "-":
- self['comments'] = sys.stdin.read()
- else:
- with open(self['logfile'], "rt") as f:
- self['comments'] = f.read()
- if self.get('comments') is None:
- self['comments'] = ""
-
- # fix up the auth with a password if none was given
- auth = self.get('auth')
- if ':' not in auth:
- import getpass
- pw = getpass.getpass("Enter password for '%s': " % auth)
- auth = "%s:%s" % (auth, pw)
- self['auth'] = tuple(auth.split(':', 1))
-
- vcs = ['cvs', 'svn', 'darcs', 'hg', 'bzr', 'git', 'mtn', 'p4']
- if self.get('vc') and self.get('vc') not in vcs:
- raise usage.UsageError("vc must be one of %s" % (', '.join(vcs)))
-
- validateMasterOption(self.get('master'))
-
-class TryOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.trycmd.trycmd"
- optParameters = [
- ["connect", "c", None,
- "How to reach the buildmaster, either 'ssh' or 'pb'"],
- # for ssh, use --host, --username, and --jobdir
- ["host", None, None,
- "Hostname (used by ssh) for the buildmaster"],
- ["jobdir", None, None,
- "Directory (on the buildmaster host) where try jobs are deposited"],
- ["username", "u", None,
- "Username performing the try build"],
- # for PB, use --master, --username, and --passwd
- ["master", "m", None,
- "Location of the buildmaster's PBListener (host:port)"],
- ["passwd", None, None,
- "Password for PB authentication"],
- ["who", "w", None,
- "Who is responsible for the try build"],
- ["comment", "C", None,
- "A comment which can be used in notifications for this build"],
-
- # for ssh to accommodate running in a virtualenv on the buildmaster
- ["buildbotbin", None, "buildbot",
- "buildbot binary to use on the buildmaster host"],
-
- ["diff", None, None,
- "Filename of a patch to use instead of scanning a local tree. "
- "Use '-' for stdin."],
- ["patchlevel", "p", 0,
- "Number of slashes to remove from patch pathnames, "
- "like the -p option to 'patch'"],
-
- ["baserev", None, None,
- "Base revision to use instead of scanning a local tree."],
-
- ["vc", None, None,
- "The VC system in use, one of: bzr, cvs, darcs, git, hg, "
- "mtn, p4, svn"],
- ["branch", None, None,
- "The branch in use, for VC systems that can't figure it out "
- "themselves"],
- ["repository", None, None,
- "Repository to use, instead of path to working directory."],
-
- ["builder", "b", None,
- "Run the trial build on this Builder. Can be used multiple times."],
- ["properties", None, None,
- "A set of properties made available in the build environment, "
- "format is --properties=prop1=value1,prop2=value2,.. "
- "option can be specified multiple times."],
- ["property", None, None,
- "A property made available in the build environment, "
- "format:prop=value. Can be used multiple times."],
-
- ["topfile", None, None,
- "Name of a file at the top of the tree, used to find the top. "
- "Only needed for SVN and CVS."],
- ["topdir", None, None,
- "Path to the top of the working copy. Only needed for SVN and CVS."],
- ]
-
- optFlags = [
- ["wait", None,
- "wait until the builds have finished"],
- ["dryrun", 'n',
- "Gather info, but don't actually submit."],
- ["get-builder-names", None,
- "Get the names of available builders. Doesn't submit anything. "
- "Only supported for 'pb' connections."],
- ["quiet", "q",
- "Don't print status of current builds while waiting."],
- ]
-
- # Mapping of .buildbot/options names to command-line options
- buildbotOptions = [
- [ 'try_connect', 'connect' ],
- #[ 'try_builders', 'builders' ], <-- handled in postOptions
- [ 'try_vc', 'vc' ],
- [ 'try_branch', 'branch' ],
- [ 'try_repository', 'repository' ],
- [ 'try_topdir', 'topdir' ],
- [ 'try_topfile', 'topfile' ],
- [ 'try_host', 'host' ],
- [ 'try_username', 'username' ],
- [ 'try_jobdir', 'jobdir' ],
- [ 'try_buildbotbin', 'buildbotbin' ],
- [ 'try_passwd', 'passwd' ],
- [ 'try_master', 'master' ],
- [ 'try_who', 'who' ],
- [ 'try_comment', 'comment' ],
- #[ 'try_wait', 'wait' ], <-- handled in postOptions
- #[ 'try_quiet', 'quiet' ], <-- handled in postOptions
-
- # Deprecated command mappings from the quirky old days:
- [ 'try_masterstatus', 'master' ],
- [ 'try_dir', 'jobdir' ],
- [ 'try_password', 'passwd' ],
- ]
-
- def __init__(self):
- base.SubcommandOptions.__init__(self)
- self['builders'] = []
- self['properties'] = {}
-
- def opt_builder(self, option):
- self['builders'].append(option)
-
- def opt_properties(self, option):
- # We need to split the value of this option into a dictionary of properties
- propertylist = option.split(",")
- for i in range(0,len(propertylist)):
- splitproperty = propertylist[i].split("=", 1)
- self['properties'][splitproperty[0]] = splitproperty[1]
-
- def opt_property(self, option):
- name, _, value = option.partition("=")
- self['properties'][name] = value
-
- def opt_patchlevel(self, option):
- self['patchlevel'] = int(option)
-
- def getSynopsis(self):
- return "Usage: buildbot try [options]"
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
- opts = self.optionsFile
- if not self['builders']:
- self['builders'] = opts.get('try_builders', [])
- if opts.get('try_wait', False):
- self['wait'] = True
- if opts.get('try_quiet', False):
- self['quiet'] = True
- # get the global 'masterstatus' option if it's set and no master
- # was specified otherwise
- if not self['master']:
- self['master'] = opts.get('masterstatus', None)
-
- if self['connect'] == 'pb':
- if not self['master']:
- raise usage.UsageError("master location must be specified" \
- "for 'pb' connections")
- validateMasterOption(self['master'])
-
-
-class TryServerOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.tryserver.tryserver"
- optParameters = [
- ["jobdir", None, None, "the jobdir (maildir) for submitting jobs"],
- ]
- requiredOptions = [ 'jobdir' ]
-
- def getSynopsis(self):
- return "Usage: buildbot tryserver [options]"
-
- def postOptions(self):
- if not self['jobdir']:
- raise usage.UsageError('jobdir is required')
-
-
-class CheckConfigOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.checkconfig.checkconfig"
- optFlags = [
- ['quiet', 'q', "Don't display error messages or tracebacks"],
- ]
-
- def getSynopsis(self):
- return "Usage: buildbot checkconfig [configFile]\n" + \
- " If not specified, 'master.cfg' will be used as 'configFile'"
-
- def parseArgs(self, *args):
- if len(args) >= 1:
- self['configFile'] = args[0]
- else:
- self['configFile'] = 'master.cfg'
-
-
-class UserOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.user.user"
- optParameters = [
- ["master", "m", None,
- "Location of the buildmaster's PBListener (host:port)"],
- ["username", "u", None,
- "Username for PB authentication"],
- ["passwd", "p", None,
- "Password for PB authentication"],
- ["op", None, None,
- "User management operation: add, remove, update, get"],
- ["bb_username", None, None,
- "Username to set for a given user. Only availabe on 'update', "
- "and bb_password must be given as well."],
- ["bb_password", None, None,
- "Password to set for a given user. Only availabe on 'update', "
- "and bb_username must be given as well."],
- ["ids", None, None,
- "User's identifiers, used to find users in 'remove' and 'get' "
- "Can be specified multiple times (--ids=id1,id2,id3)"],
- ["info", None, None,
- "User information in the form: --info=type=value,type=value,.. "
- "Used in 'add' and 'update', can be specified multiple times. "
- "Note that 'update' requires --info=id:type=value..."]
- ]
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'user_master', 'master' ],
- [ 'user_username', 'username' ],
- [ 'user_passwd', 'passwd' ],
- ]
- requiredOptions = [ 'master' ]
-
- longdesc = """
- Currently implemented types for --info= are:\n
- git, svn, hg, cvs, darcs, bzr, email
- """
-
- def __init__(self):
- base.SubcommandOptions.__init__(self)
- self['ids'] = []
- self['info'] = []
-
- def opt_ids(self, option):
- id_list = option.split(",")
- self['ids'].extend(id_list)
-
- def opt_info(self, option):
- # splits info into type/value dictionary, appends to info
- info_list = option.split(",")
- info_elem = {}
-
- if len(info_list) == 1 and '=' not in info_list[0]:
- info_elem["identifier"] = info_list[0]
- self['info'].append(info_elem)
- else:
- for i in range(0, len(info_list)):
- split_info = info_list[i].split("=", 1)
-
- # pull identifier from update --info
- if ":" in split_info[0]:
- split_id = split_info[0].split(":")
- info_elem["identifier"] = split_id[0]
- split_info[0] = split_id[1]
-
- info_elem[split_info[0]] = split_info[1]
- self['info'].append(info_elem)
-
- def getSynopsis(self):
- return "Usage: buildbot user [options]"
-
- def _checkValidTypes(self, info):
- from buildbot.process.users import users
- valid = set(['identifier', 'email'] + users.srcs)
-
- for user in info:
- for attr_type in user:
- if attr_type not in valid:
- raise usage.UsageError(
- "Type not a valid attr_type, must be in: %s"
- % ', '.join(valid))
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
-
- validateMasterOption(self.get('master'))
-
- op = self.get('op')
- if not op:
- raise usage.UsageError("you must specify an operation: add, "
- "remove, update, get")
- if op not in ['add', 'remove', 'update', 'get']:
- raise usage.UsageError("bad op %r, use 'add', 'remove', 'update', "
- "or 'get'" % op)
-
- if not self.get('username') or not self.get('passwd'):
- raise usage.UsageError("A username and password must be given")
-
- bb_username = self.get('bb_username')
- bb_password = self.get('bb_password')
- if bb_username or bb_password:
- if op != 'update':
- raise usage.UsageError("bb_username and bb_password only work "
- "with update")
- if not bb_username or not bb_password:
- raise usage.UsageError("Must specify both bb_username and "
- "bb_password or neither.")
-
- info = self.get('info')
- ids = self.get('ids')
-
- # check for erroneous args
- if not info and not ids:
- raise usage.UsageError("must specify either --ids or --info")
-
- if op == 'add' or op == 'update':
- if ids:
- raise usage.UsageError("cannot use --ids with 'add' or "
- "'update'")
- self._checkValidTypes(info)
- if op == 'update':
- for user in info:
- if 'identifier' not in user:
- raise usage.UsageError("no ids found in update info; "
- "use: --info=id:type=value,type=value,..")
- if op == 'add':
- for user in info:
- if 'identifier' in user:
- raise usage.UsageError("identifier found in add info, "
- "use: --info=type=value,type=value,..")
- if op == 'remove' or op == 'get':
- if info:
- raise usage.UsageError("cannot use --info with 'remove' "
- "or 'get'")
-
-
-class Options(usage.Options):
- synopsis = "Usage: buildbot <command> [command options]"
-
- subCommands = [
- ['create-master', None, CreateMasterOptions,
- "Create and populate a directory for a new buildmaster"],
- ['upgrade-master', None, UpgradeMasterOptions,
- "Upgrade an existing buildmaster directory for the current version"],
- ['start', None, StartOptions,
- "Start a buildmaster"],
- ['stop', None, StopOptions,
- "Stop a buildmaster"],
- ['restart', None, RestartOptions,
- "Restart a buildmaster"],
- ['reconfig', None, ReconfigOptions,
- "SIGHUP a buildmaster to make it re-read the config file"],
- ['sighup', None, ReconfigOptions,
- "SIGHUP a buildmaster to make it re-read the config file"],
- ['sendchange', None, SendChangeOptions,
- "Send a change to the buildmaster"],
- ['debugclient', None, DebugClientOptions,
- "Launch a small debug panel GUI"],
- ['statuslog', None, StatusLogOptions,
- "Emit current builder status to stdout"],
- ['statusgui', None, StatusGuiOptions,
- "Display a small window showing current builder status"],
- ['try', None, TryOptions,
- "Run a build with your local changes"],
- ['tryserver', None, TryServerOptions,
- "buildmaster-side 'try' support function, not for users"],
- ['checkconfig', None, CheckConfigOptions,
- "test the validity of a master.cfg config file"],
- ['user', None, UserOptions,
- "Manage users in buildbot's database"]
- ]
-
- def opt_version(self):
- import buildbot
- print "Buildbot version: %s" % buildbot.version
- usage.Options.opt_version(self)
-
- def opt_verbose(self):
- from twisted.python import log
- log.startLogging(sys.stderr)
-
- def postOptions(self):
- if not hasattr(self, 'subOptions'):
- raise usage.UsageError("must specify a command")
-
-
-def run():
- config = Options()
- try:
- config.parseOptions(sys.argv[1:])
- except usage.error, e:
- print "%s: %s" % (sys.argv[0], e)
- print
- c = getattr(config, 'subOptions', config)
- print str(c)
- sys.exit(1)
-
- subconfig = config.subOptions
- subcommandFunction = reflect.namedObject(subconfig.subcommandFunction)
- sys.exit(subcommandFunction(subconfig))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg
deleted file mode 100644
index c461f644..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- python -*-
-# ex: set syntax=python:
-
-# This is a sample buildmaster config file. It must be installed as
-# 'master.cfg' in your buildmaster's base directory.
-
-# This is the dictionary that the buildmaster pays attention to. We also use
-# a shorter alias to save typing.
-c = BuildmasterConfig = {}
-
-####### BUILDSLAVES
-
-# The 'slaves' list defines the set of recognized buildslaves. Each element is
-# a BuildSlave object, specifying a unique slave name and password. The same
-# slave name and password must be configured on the slave.
-from buildbot.buildslave import BuildSlave
-c['slaves'] = [BuildSlave("example-slave", "pass")]
-
-# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
-# This must match the value configured into the buildslaves (with their
-# --master option)
-c['slavePortnum'] = 9989
-
-####### CHANGESOURCES
-
-# the 'change_source' setting tells the buildmaster how it should find out
-# about source code changes. Here we point to the buildbot clone of pyflakes.
-
-from buildbot.changes.gitpoller import GitPoller
-c['change_source'] = []
-c['change_source'].append(GitPoller(
- 'git://github.com/buildbot/pyflakes.git',
- workdir='gitpoller-workdir', branch='master',
- pollinterval=300))
-
-####### SCHEDULERS
-
-# Configure the Schedulers, which decide how to react to incoming changes. In this
-# case, just kick off a 'runtests' build
-
-from buildbot.schedulers.basic import SingleBranchScheduler
-from buildbot.schedulers.forcesched import ForceScheduler
-from buildbot.changes import filter
-c['schedulers'] = []
-c['schedulers'].append(SingleBranchScheduler(
- name="all",
- change_filter=filter.ChangeFilter(branch='master'),
- treeStableTimer=None,
- builderNames=["runtests"]))
-c['schedulers'].append(ForceScheduler(
- name="force",
- builderNames=["runtests"]))
-
-####### BUILDERS
-
-# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
-# what steps, and which slaves can execute them. Note that any particular build will
-# only take place on one slave.
-
-from buildbot.process.factory import BuildFactory
-from buildbot.steps.source.git import Git
-from buildbot.steps.shell import ShellCommand
-
-factory = BuildFactory()
-# check out the source
-factory.addStep(Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental'))
-# run the tests (note that this will require that 'trial' is installed)
-factory.addStep(ShellCommand(command=["trial", "pyflakes"]))
-
-from buildbot.config import BuilderConfig
-
-c['builders'] = []
-c['builders'].append(
- BuilderConfig(name="runtests",
- slavenames=["example-slave"],
- factory=factory))
-
-####### STATUS TARGETS
-
-# 'status' is a list of Status Targets. The results of each build will be
-# pushed to these targets. buildbot/status/*.py has a variety to choose from,
-# including web pages, email senders, and IRC bots.
-
-c['status'] = []
-
-from buildbot.status import html
-from buildbot.status.web import authz, auth
-
-authz_cfg=authz.Authz(
- # change any of these to True to enable; see the manual for more
- # options
- auth=auth.BasicAuth([("pyflakes","pyflakes")]),
- gracefulShutdown = False,
- forceBuild = 'auth', # use this to test your slave once it is set up
- forceAllBuilds = False,
- pingBuilder = False,
- stopBuild = False,
- stopAllBuilds = False,
- cancelPendingBuild = False,
-)
-c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
-
-####### PROJECT IDENTITY
-
-# the 'title' string will appear at the top of this buildbot
-# installation's html.WebStatus home page (linked to the
-# 'titleURL') and is embedded in the title of the waterfall HTML page.
-
-c['title'] = "Pyflakes"
-c['titleURL'] = "https://launchpad.net/pyflakes"
-
-# the 'buildbotURL' string should point to the location where the buildbot's
-# internal web server (usually the html.WebStatus page) is visible. This
-# typically uses the port number set in the Waterfall 'status' entry, but
-# with an externally-visible host name which the buildbot cannot figure out
-# without some help.
-
-c['buildbotURL'] = "http://localhost:8010/"
-
-####### DB URL
-
-c['db'] = {
- # This specifies what database buildbot uses to store its state. You can leave
- # this at its default for all but the largest installations.
- 'db_url' : "sqlite:///state.sqlite",
-}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py
deleted file mode 100644
index 480d28dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import traceback
-from twisted.internet import defer
-from buildbot.clients import sendchange as sendchange_client
-from buildbot.util import in_reactor
-
-@in_reactor
-@defer.inlineCallbacks
-def sendchange(config):
- encoding = config.get('encoding', 'utf8')
- who = config.get('who')
- auth = config.get('auth')
- master = config.get('master')
- branch = config.get('branch')
- category = config.get('category')
- revision = config.get('revision')
- properties = config.get('properties', {})
- repository = config.get('repository', '')
- vc = config.get('vc', None)
- project = config.get('project', '')
- revlink = config.get('revlink', '')
- when = config.get('when')
- comments = config.get('comments')
- files = config.get('files', ())
- codebase = config.get('codebase', None)
-
- s = sendchange_client.Sender(master, auth, encoding=encoding)
- try:
- yield s.send(branch, revision, comments, files, who=who,
- category=category, when=when, properties=properties,
- repository=repository, vc=vc, project=project, revlink=revlink,
- codebase=codebase)
- except:
- print "change not sent:"
- traceback.print_exc(file=sys.stdout)
- defer.returnValue(1)
- else:
- print "change sent successfully"
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py
deleted file mode 100644
index e49787b5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os, sys
-from buildbot.scripts import base
-from twisted.internet import reactor, protocol
-from twisted.python.runtime import platformType
-from buildbot.scripts.logwatcher import LogWatcher
-from buildbot.scripts.logwatcher import BuildmasterTimeoutError
-from buildbot.scripts.logwatcher import ReconfigError
-
-class Follower:
- def follow(self, basedir):
- self.rc = 0
- print "Following twistd.log until startup finished.."
- lw = LogWatcher(os.path.join(basedir, "twistd.log"))
- d = lw.start()
- d.addCallbacks(self._success, self._failure)
- reactor.run()
- return self.rc
-
- def _success(self, _):
- print "The buildmaster appears to have (re)started correctly."
- self.rc = 0
- reactor.stop()
-
- def _failure(self, why):
- if why.check(BuildmasterTimeoutError):
- print """
-The buildmaster took more than 10 seconds to start, so we were unable to
-confirm that it started correctly. Please 'tail twistd.log' and look for a
-line that says 'configuration update complete' to verify correct startup.
-"""
- elif why.check(ReconfigError):
- print """
-The buildmaster appears to have encountered an error in the master.cfg config
-file during startup. Please inspect and fix master.cfg, then restart the
-buildmaster.
-"""
- else:
- print """
-Unable to confirm that the buildmaster started correctly. You may need to
-stop it, fix the config file, and restart.
-"""
- print why
- self.rc = 1
- reactor.stop()
-
-def launchNoDaemon(config):
- os.chdir(config['basedir'])
- sys.path.insert(0, os.path.abspath(config['basedir']))
-
- argv = ["twistd",
- "--no_save",
- '--nodaemon',
- "--logfile=twistd.log", # windows doesn't use the same default
- "--python=buildbot.tac"]
- sys.argv = argv
-
- # this is copied from bin/twistd. twisted-2.0.0 through 2.4.0 use
- # _twistw.run . Twisted-2.5.0 and later use twistd.run, even for
- # windows.
- from twisted.scripts import twistd
- twistd.run()
-
-def launch(config):
- os.chdir(config['basedir'])
- sys.path.insert(0, os.path.abspath(config['basedir']))
-
- # see if we can launch the application without actually having to
- # spawn twistd, since spawning processes correctly is a real hassle
- # on windows.
- argv = [sys.executable,
- "-c",
- # this is copied from bin/twistd. twisted-2.0.0 through 2.4.0 use
- # _twistw.run . Twisted-2.5.0 and later use twistd.run, even for
- # windows.
- "from twisted.scripts import twistd; twistd.run()",
- "--no_save",
- "--logfile=twistd.log", # windows doesn't use the same default
- "--python=buildbot.tac"]
-
- # ProcessProtocol just ignores all output
- reactor.spawnProcess(protocol.ProcessProtocol(), sys.executable, argv, env=os.environ)
-
-def start(config):
- if not base.isBuildmasterDir(config['basedir']):
- return 1
-
- if config['nodaemon']:
- launchNoDaemon(config)
- return 0
-
- launch(config)
-
- # We don't have tail on windows
- if platformType == "win32" or config['quiet']:
- return 0
-
- # this is the parent
- rc = Follower().follow(config['basedir'])
- return rc
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py
deleted file mode 100644
index bf8ac31f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# note that this cannot be run in tests for code coverage, as it requires a
-# different reactor than the default
-
-def statusgui(config):
- from buildbot.clients import gtkPanes
-
- master = config.get('master')
- passwd = config.get('passwd')
- username = config.get('username')
- c = gtkPanes.GtkClient(master, username=username, passwd=passwd)
- c.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py
deleted file mode 100644
index 2c65cc41..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# note that this cannot be run in tests for code coverage, as it requires a
-# different reactor than the default
-
-from buildbot.clients import text
-
-def statuslog(config):
- master = config.get('master')
- passwd = config.get('passwd')
- username = config.get('username')
- c = text.TextClient(master, username=username, passwd=passwd)
- c.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py
deleted file mode 100644
index 69020a3b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import time
-import os
-import errno
-import signal
-from buildbot.scripts import base
-
-def stop(config, signame="TERM", wait=False):
- basedir = config['basedir']
- quiet = config['quiet']
-
- if config['clean']:
- signame = 'USR1'
-
- if not base.isBuildmasterDir(config['basedir']):
- return 1
-
- pidfile = os.path.join(basedir, 'twistd.pid')
- try:
- with open(pidfile, "rt") as f:
- pid = int(f.read().strip())
- except:
- if not config['quiet']:
- print "buildmaster not running"
- return 0
-
- signum = getattr(signal, "SIG"+signame)
- try:
- os.kill(pid, signum)
- except OSError, e:
- if e.errno != errno.ESRCH:
- raise
- else:
- if not config['quiet']:
- print "buildmaster not running"
- try:
- os.unlink(pidfile)
- except:
- pass
- return 0
-
- if not wait:
- if not quiet:
- print "sent SIG%s to process" % signame
- return 0
-
- time.sleep(0.1)
-
- # poll once per second until twistd.pid goes away, up to 10 seconds,
- # unless we're doing a clean stop, in which case wait forever
- count = 0
- while count < 10 or config['clean']:
- try:
- os.kill(pid, 0)
- except OSError:
- if not quiet:
- print "buildbot process %d is dead" % pid
- return 0
- time.sleep(1)
- count += 1
- if not quiet:
- print "never saw process go away"
- return 1
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py
deleted file mode 100644
index e4f70cd1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-def trycmd(config):
- from buildbot.clients import tryclient
- t = tryclient.Try(config)
- t.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py
deleted file mode 100644
index 713cdacb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import sys
-import time
-from hashlib import md5
-
-def tryserver(config):
- jobdir = os.path.expanduser(config["jobdir"])
- job = sys.stdin.read()
- # now do a 'safecat'-style write to jobdir/tmp, then move atomically to
- # jobdir/new . Rather than come up with a unique name randomly, I'm just
- # going to MD5 the contents and prepend a timestamp.
- timestring = "%d" % time.time()
- m = md5()
- m.update(job)
- jobhash = m.hexdigest()
- fn = "%s-%s" % (timestring, jobhash)
- tmpfile = os.path.join(jobdir, "tmp", fn)
- newfile = os.path.join(jobdir, "new", fn)
- with open(tmpfile, "w") as f:
- f.write(job)
- os.rename(tmpfile, newfile)
-
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py
deleted file mode 100644
index c471965d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import sys
-import traceback
-from twisted.internet import defer
-from twisted.python import util, runtime
-from buildbot import config as config_module
-from buildbot import monkeypatches
-from buildbot.db import connector
-from buildbot.master import BuildMaster
-from buildbot.util import in_reactor
-from buildbot.scripts import base
-
-def checkBasedir(config):
- if not config['quiet']:
- print "checking basedir"
-
- if not base.isBuildmasterDir(config['basedir']):
- return False
-
- if runtime.platformType != 'win32': # no pids on win32
- if not config['quiet']:
- print "checking for running master"
- pidfile = os.path.join(config['basedir'], 'twistd.pid')
- if os.path.exists(pidfile):
- print "'%s' exists - is this master still running?" % (pidfile,)
- return False
-
- return True
-
-def loadConfig(config, configFileName='master.cfg'):
- if not config['quiet']:
- print "checking %s" % configFileName
-
- try:
- master_cfg = config_module.MasterConfig.loadConfig(
- config['basedir'], configFileName)
- except config_module.ConfigErrors, e:
- print "Errors loading configuration:"
- for msg in e.errors:
- print " " + msg
- return
- except:
- print "Errors loading configuration:"
- traceback.print_exc(file=sys.stdout)
- return
-
- return master_cfg
-
-def installFile(config, target, source, overwrite=False):
- with open(source, "rt") as f:
- new_contents = f.read()
- if os.path.exists(target):
- with open(target, "rt") as f:
- old_contents = f.read()
- if old_contents != new_contents:
- if overwrite:
- if not config['quiet']:
- print "%s has old/modified contents" % target
- print " overwriting it with new contents"
- with open(target, "wt") as f:
- f.write(new_contents)
- else:
- if not config['quiet']:
- print "%s has old/modified contents" % target
- print " writing new contents to %s.new" % target
- with open(target + ".new", "wt") as f:
- f.write(new_contents)
- # otherwise, it's up to date
- else:
- if not config['quiet']:
- print "creating %s" % target
- with open(target, "wt") as f:
- f.write(new_contents)
-
-def upgradeFiles(config):
- if not config['quiet']:
- print "upgrading basedir"
-
- webdir = os.path.join(config['basedir'], "public_html")
- if not os.path.exists(webdir):
- if not config['quiet']:
- print "creating public_html"
- os.mkdir(webdir)
-
- templdir = os.path.join(config['basedir'], "templates")
- if not os.path.exists(templdir):
- if not config['quiet']:
- print "creating templates"
- os.mkdir(templdir)
-
- for file in ('bg_gradient.jpg', 'default.css',
- 'robots.txt', 'favicon.ico'):
- source = util.sibpath(__file__, "../status/web/files/%s" % (file,))
- target = os.path.join(webdir, file)
- try:
- installFile(config, target, source)
- except IOError:
- print "Can't write '%s'." % (target,)
-
- installFile(config, os.path.join(config['basedir'], "master.cfg.sample"),
- util.sibpath(__file__, "sample.cfg"), overwrite=True)
-
- # if index.html exists, use it to override the root page tempalte
- index_html = os.path.join(webdir, "index.html")
- root_html = os.path.join(templdir, "root.html")
- if os.path.exists(index_html):
- if os.path.exists(root_html):
- print "Notice: %s now overrides %s" % (root_html, index_html)
- print " as the latter is not used by buildbot anymore."
- print " Decide which one you want to keep."
- else:
- try:
- print "Notice: Moving %s to %s." % (index_html, root_html)
- print " You can (and probably want to) remove it if " \
- "you haven't modified this file."
- os.renames(index_html, root_html)
- except Exception, e:
- print "Error moving %s to %s: %s" % (index_html, root_html,
- str(e))
-
-@defer.inlineCallbacks
-def upgradeDatabase(config, master_cfg):
- if not config['quiet']:
- print "upgrading database (%s)" % (master_cfg.db['db_url'])
-
- master = BuildMaster(config['basedir'])
- master.config = master_cfg
- db = connector.DBConnector(master, basedir=config['basedir'])
-
- yield db.setup(check_version=False, verbose=not config['quiet'])
- yield db.model.upgrade()
-
-@in_reactor
-@defer.inlineCallbacks
-def upgradeMaster(config, _noMonkey=False):
- if not _noMonkey: # pragma: no cover
- monkeypatches.patch_all()
-
- if not checkBasedir(config):
- defer.returnValue(1)
- return
-
- os.chdir(config['basedir'])
-
- try:
- configFile = base.getConfigFileFromTac(config['basedir'])
- except (SyntaxError, ImportError), e:
- print "Unable to load 'buildbot.tac' from '%s':" % config['basedir']
- print e
- defer.returnValue(1)
- return
- master_cfg = loadConfig(config, configFile)
- if not master_cfg:
- defer.returnValue(1)
- return
-
- upgradeFiles(config)
- yield upgradeDatabase(config, master_cfg)
-
- if not config['quiet']:
- print "upgrade complete"
-
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py
deleted file mode 100644
index 4f231e76..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from buildbot.clients import usersclient
-from buildbot.process.users import users
-from buildbot.util import in_reactor
-
-@in_reactor
-@defer.inlineCallbacks
-def user(config):
-
- master = config.get('master')
- op = config.get('op')
- username = config.get('username')
- passwd = config.get('passwd')
- master, port = master.split(":")
- port = int(port)
- bb_username = config.get('bb_username')
- bb_password = config.get('bb_password')
- if bb_username or bb_password:
- bb_password = users.encrypt(bb_password)
- info = config.get('info')
- ids = config.get('ids')
-
- # find identifier if op == add
- if info and op == 'add':
- for user in info:
- user['identifier'] = sorted(user.values())[0]
-
- uc = usersclient.UsersClient(master, username, passwd, port)
- output = yield uc.send(op, bb_username, bb_password, ids, info)
- if output:
- print output
-
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py
deleted file mode 100644
index bb4042ce..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py
+++ /dev/null
@@ -1,359 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from zope.interface import implements
-from twisted.persisted import styles
-from twisted.internet import defer
-from buildbot.changes.changes import Change
-from buildbot import util, interfaces
-# TODO: kill this class, or at least make it less significant
-class SourceStamp(util.ComparableMixin, styles.Versioned):
- """This is a tuple of (branch, revision, patchspec, changes, project, repository).
-
- C{branch} is always valid, although it may be None to let the Source
- step use its default branch. There are three possibilities for the
- remaining elements:
- - (revision=REV, patchspec=None, changes=None): build REV. If REV is
- None, build the HEAD revision from the given branch. Note that REV
- must always be a string: SVN, Perforce, and other systems which use
- integers should provide a string here, but the Source checkout step
- will integerize it when making comparisons.
- - (revision=REV, patchspec=(LEVEL, DIFF), changes=None): checkout REV,
- then apply a patch to the source, with C{patch -pLEVEL <DIFF}.
- If REV is None, checkout HEAD and patch it.
- - (revision=None, patchspec=None, changes=[CHANGES]): let the Source
- step check out the latest revision indicated by the given Changes.
- CHANGES is a tuple of L{buildbot.changes.changes.Change} instances,
- and all must be on the same branch.
-
- @ivar ssid: sourcestamp ID, or None if this sourcestamp has not yet been
- added to the database
-
- @ivar branch: branch name or None
-
- @ivar revision: revision string or None
-
- @ivar patch: tuple (patch level, patch body) or None
-
- @ivar patch_info: tuple (patch author, patch comment) or None
-
- @ivar changes: tuple of changes that went into this source stamp, sorted by
- number
-
- @ivar project: project name
-
- @ivar repository: repository URL
- """
-
- persistenceVersion = 3
- persistenceForgets = ( 'wasUpgraded', )
-
- # all seven of these are publicly visible attributes
- branch = None
- revision = None
- patch = None
- patch_info = None
- changes = ()
- project = ''
- repository = ''
- codebase = ''
- sourcestampsetid = None
- ssid = None
-
- compare_attrs = ('branch', 'revision', 'patch', 'patch_info', 'changes', 'project', 'repository', 'codebase')
-
- implements(interfaces.ISourceStamp)
-
- @classmethod
- def fromSsdict(cls, master, ssdict):
- """
- Class method to create a L{SourceStamp} from a dictionary as returned
- by L{SourceStampConnectorComponent.getSourceStamp}.
-
- @param master: build master instance
- @param ssdict: source stamp dictionary
-
- @returns: L{SourceStamp} via Deferred
- """
- # try to fetch from the cache, falling back to _make_ss if not
- # found
- cache = master.caches.get_cache("SourceStamps", cls._make_ss)
- return cache.get(ssdict['ssid'], ssdict=ssdict, master=master)
-
- @classmethod
- def _make_ss(cls, ssid, ssdict, master):
- sourcestamp = cls(_fromSsdict=True)
- sourcestamp.ssid = ssid
- sourcestamp.branch = ssdict['branch']
- sourcestamp.revision = ssdict['revision']
- sourcestamp.project = ssdict['project']
- sourcestamp.repository = ssdict['repository']
- sourcestamp.codebase = ssdict['codebase']
- sourcestamp.sourcestampsetid = ssdict['sourcestampsetid']
-
- sourcestamp.patch = None
- if ssdict['patch_body']:
- sourcestamp.patch = (ssdict['patch_level'], ssdict['patch_body'],
- ssdict.get('patch_subdir'))
- sourcestamp.patch_info = (ssdict['patch_author'],
- ssdict['patch_comment'])
-
- if ssdict['changeids']:
- # sort the changeids in order, oldest to newest
- sorted_changeids = sorted(ssdict['changeids'])
- def gci(id):
- d = master.db.changes.getChange(id)
- d.addCallback(lambda chdict :
- Change.fromChdict(master, chdict))
- return d
- d = defer.gatherResults([ gci(id)
- for id in sorted_changeids ])
- else:
- d = defer.succeed([])
- def got_changes(changes):
- sourcestamp.changes = tuple(changes)
- return sourcestamp
- d.addCallback(got_changes)
- return d
-
- def __init__(self, branch=None, revision=None, patch=None, sourcestampsetid=None,
- patch_info=None, changes=None, project='', repository='',
- codebase = '', _fromSsdict=False, _ignoreChanges=False):
- self._addSourceStampToDatabase_lock = defer.DeferredLock();
-
- # skip all this madness if we're being built from the database
- if _fromSsdict:
- return
-
- if patch is not None:
- assert 2 <= len(patch) <= 3
- assert int(patch[0]) != -1
- self.sourcestampsetid = sourcestampsetid
- self.branch = branch
- self.patch = patch
- self.patch_info = patch_info
- self.project = project or ''
- self.repository = repository or ''
- self.codebase = codebase or ''
- if changes:
- self.changes = changes = list(changes)
- changes.sort()
- if not _ignoreChanges:
- # set branch and revision to most recent change
- self.branch = changes[-1].branch
- revision = changes[-1].revision
- if not self.project and hasattr(changes[-1], 'project'):
- self.project = changes[-1].project
- if not self.repository and hasattr(changes[-1], 'repository'):
- self.repository = changes[-1].repository
-
- if revision is not None:
- if isinstance(revision, int):
- revision = str(revision)
-
- self.revision = revision
-
- def canBeMergedWith(self, other):
- # this algorithm implements the "compatible" mergeRequests defined in
- # detail in cfg-buidlers.texinfo; change that documentation if the
- # algorithm changes!
- if other.codebase != self.codebase:
- return False
- if other.repository != self.repository:
- return False
- if other.branch != self.branch:
- return False # the builds are completely unrelated
- if other.project != self.project:
- return False
- if self.patch or other.patch:
- # you can't merge patched builds with anything else
- return self is other
-
- if self.changes and other.changes:
- return True
- elif self.changes and not other.changes:
- return False # we're using changes, they aren't
- elif not self.changes and other.changes:
- return False # they're using changes, we aren't
-
- if self.revision == other.revision:
- # both builds are using the same specific revision, so they can
- # be merged. It might be the case that revision==None, so they're
- # both building HEAD.
- return True
-
- return False
-
- def mergeWith(self, others):
- """Generate a SourceStamp for the merger of me and all the other
- SourceStamps. This is called by a Build when it starts, to figure
- out what its sourceStamp should be."""
-
- # either we're all building the same thing (changes==None), or we're
- # all building changes (which can be merged)
- changes = []
- changes.extend(self.changes)
- for ss in others:
- changes.extend(ss.changes)
- newsource = SourceStamp(sourcestampsetid=self.sourcestampsetid,
- branch=self.branch,
- revision=self.revision,
- patch=self.patch,
- patch_info=self.patch_info,
- project=self.project,
- repository=self.repository,
- codebase=self.codebase,
- changes=changes)
- return newsource
-
- def clone(self):
- # Create an exact but identityless copy
- return SourceStamp(branch=self.branch, revision=self.revision,
- patch=self.patch, repository=self.repository,
- codebase=self.codebase, patch_info=self.patch_info,
- project=self.project, changes=self.changes,
- _ignoreChanges=True)
-
- def getAbsoluteSourceStamp(self, got_revision):
- cloned = self.clone()
- cloned.revision = got_revision
- return cloned
-
- def getText(self):
- # note: this won't work for VC systems with huge 'revision' strings
- text = []
- if self.project:
- text.append("for %s" % self.project)
- if self.repository:
- text.append("in %s" % self.repository)
- if self.codebase:
- text.append("(%s)" % self.codebase)
- if self.revision is None:
- return text + [ "latest" ]
- text.append(str(self.revision))
- if self.branch:
- text.append("in '%s'" % self.branch)
- if self.patch:
- text.append("[patch]")
- return text
-
- def asDict(self):
- result = {}
- # Constant
- result['revision'] = self.revision
-
- # TODO(maruel): Make the patch content a suburl.
- result['hasPatch'] = self.patch is not None
- if self.patch:
- result['patch_level'] = self.patch[0]
- result['patch_body'] = self.patch[1]
- if len(self.patch) > 2:
- result['patch_subdir'] = self.patch[2]
- if self.patch_info:
- result['patch_author'] = self.patch_info[0]
- result['patch_comment'] = self.patch_info[1]
-
- result['branch'] = self.branch
- result['changes'] = [c.asDict() for c in getattr(self, 'changes', [])]
- result['project'] = self.project
- result['repository'] = self.repository
- result['codebase'] = self.codebase
- return result
-
- def __setstate__(self, d):
- styles.Versioned.__setstate__(self, d)
- self._addSourceStampToDatabase_lock = defer.DeferredLock();
-
- def upgradeToVersion1(self):
- # version 0 was untyped; in version 1 and later, types matter.
- if self.branch is not None and not isinstance(self.branch, str):
- self.branch = str(self.branch)
- if self.revision is not None and not isinstance(self.revision, str):
- self.revision = str(self.revision)
- if self.patch is not None:
- self.patch = ( int(self.patch[0]), str(self.patch[1]) )
- self.wasUpgraded = True
-
- def upgradeToVersion2(self):
- # version 1 did not have project or repository; just set them to a default ''
- self.project = ''
- self.repository = ''
- self.wasUpgraded = True
-
- def upgradeToVersion3(self):
- #The database has been upgraded where all existing sourcestamps got an
- #setid equal to its ssid
- self.sourcestampsetid = self.ssid
- #version 2 did not have codebase; set to ''
- self.codebase = ''
- self.wasUpgraded = True
-
- def getSourceStampSetId(self, master):
- "temporary; do not use widely!"
- if self.sourcestampsetid:
- return defer.succeed(self.sourcestampsetid)
- else:
- return self.addSourceStampToDatabase(master)
-
-
- @util.deferredLocked('_addSourceStampToDatabase_lock')
- def addSourceStampToDatabase(self, master, sourcestampsetid = None):
- # add it to the DB
- patch_body = None
- patch_level = None
- patch_subdir = None
- if self.patch:
- patch_level = self.patch[0]
- patch_body = self.patch[1]
- if len(self.patch) > 2:
- patch_subdir = self.patch[2]
-
- patch_author = None
- patch_comment = None
- if self.patch_info:
- patch_author, patch_comment = self.patch_info
-
- def get_setid():
- if sourcestampsetid is not None:
- return defer.succeed( sourcestampsetid )
- else:
- return master.db.sourcestampsets.addSourceStampSet()
-
- def set_setid(setid):
- self.sourcestampsetid = setid
- return setid
-
- def add_sourcestamp(setid):
- return master.db.sourcestamps.addSourceStamp(
- sourcestampsetid=setid,
- branch=self.branch, revision=self.revision,
- repository=self.repository, codebase=self.codebase,
- project=self.project,
- patch_body=patch_body, patch_level=patch_level,
- patch_author=patch_author, patch_comment=patch_comment,
- patch_subdir=patch_subdir,
- changeids=[c.number for c in self.changes])
-
- def set_ssid(ssid):
- self.ssid = ssid
- return ssid
-
- d = get_setid()
- d.addCallback(set_setid)
- d.addCallback(add_sourcestamp)
- d.addCallback(set_ssid)
- d.addCallback(lambda _ : self.sourcestampsetid)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py
deleted file mode 100644
index 080f18f1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import build, builder, buildstep, buildset, testresult, logfile
-import slave, master, buildrequest
-
-# styles.Versioned requires this, as it keys the version numbers on the fully
-# qualified class name; see master/buildbot/test/regressions/test_unpickling.py
-buildstep.BuildStepStatus.__module__ = 'buildbot.status.builder'
-build.BuildStatus.__module__ = 'buildbot.status.builder'
-
-# add all of these classes to builder; this is a form of late binding to allow
-# circular module references among the status modules
-builder.BuildStepStatus = buildstep.BuildStepStatus
-builder.BuildSetStatus = buildset.BuildSetStatus
-builder.TestResult = testresult.TestResult
-builder.LogFile = logfile.LogFile
-builder.HTMLLogFile = logfile.HTMLLogFile
-builder.SlaveStatus = slave.SlaveStatus
-builder.Status = master.Status
-builder.BuildStatus = build.BuildStatus
-builder.BuildRequestStatus = buildrequest.BuildRequestStatus
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py
deleted file mode 100644
index 5efaf20f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from zope.interface import implements
-from twisted.application import service
-
-from buildbot.interfaces import IStatusReceiver
-from buildbot import util, pbutil
-
-class StatusReceiverBase:
- implements(IStatusReceiver)
-
- def requestSubmitted(self, request):
- pass
-
- def requestCancelled(self, builder, request):
- pass
-
- def buildsetSubmitted(self, buildset):
- pass
-
- def builderAdded(self, builderName, builder):
- pass
-
- def builderChangedState(self, builderName, state):
- pass
-
- def buildStarted(self, builderName, build):
- pass
-
- def buildETAUpdate(self, build, ETA):
- pass
-
- def changeAdded(self, change):
- pass
-
- def stepStarted(self, build, step):
- pass
-
- def stepTextChanged(self, build, step, text):
- pass
-
- def stepText2Changed(self, build, step, text2):
- pass
-
- def stepETAUpdate(self, build, step, ETA, expectations):
- pass
-
- def logStarted(self, build, step, log):
- pass
-
- def logChunk(self, build, step, log, channel, text):
- pass
-
- def logFinished(self, build, step, log):
- pass
-
- def stepFinished(self, build, step, results):
- pass
-
- def buildFinished(self, builderName, build, results):
- pass
-
- def builderRemoved(self, builderName):
- pass
-
- def slaveConnected(self, slaveName):
- pass
-
- def slaveDisconnected(self, slaveName):
- pass
-
- def checkConfig(self, otherStatusReceivers):
- pass
-
-class StatusReceiverMultiService(StatusReceiverBase, service.MultiService,
- util.ComparableMixin):
-
- def __init__(self):
- service.MultiService.__init__(self)
-
-class StatusReceiverService(StatusReceiverBase, service.Service,
- util.ComparableMixin):
- pass
-
-StatusReceiver = StatusReceiverService
-
-
-class StatusReceiverPerspective(StatusReceiver, pbutil.NewCredPerspective):
- implements(IStatusReceiver)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py
deleted file mode 100644
index d1efa96d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py
+++ /dev/null
@@ -1,479 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os, shutil, re
-from cPickle import dump
-from zope.interface import implements
-from twisted.python import log, runtime, components
-from twisted.persisted import styles
-from twisted.internet import reactor, defer
-from buildbot import interfaces, util, sourcestamp
-from buildbot.process import properties
-from buildbot.status.buildstep import BuildStepStatus
-
-class BuildStatus(styles.Versioned, properties.PropertiesMixin):
- implements(interfaces.IBuildStatus, interfaces.IStatusEvent)
-
- persistenceVersion = 4
- persistenceForgets = ( 'wasUpgraded', )
-
- sources = None
- reason = None
- changes = []
- blamelist = []
- progress = None
- started = None
- finished = None
- currentStep = None
- text = []
- results = None
- slavename = "???"
-
- set_runtime_properties = True
-
- # these lists/dicts are defined here so that unserialized instances have
- # (empty) values. They are set in __init__ to new objects to make sure
- # each instance gets its own copy.
- watchers = []
- updates = {}
- finishedWatchers = []
- testResults = {}
-
- def __init__(self, parent, master, number):
- """
- @type parent: L{BuilderStatus}
- @type number: int
- """
- assert interfaces.IBuilderStatus(parent)
- self.builder = parent
- self.master = master
- self.number = number
- self.watchers = []
- self.updates = {}
- self.finishedWatchers = []
- self.steps = []
- self.testResults = {}
- self.properties = properties.Properties()
-
- def __repr__(self):
- return "<%s #%s>" % (self.__class__.__name__, self.number)
-
- # IBuildStatus
-
- def getBuilder(self):
- """
- @rtype: L{BuilderStatus}
- """
- return self.builder
-
- def getNumber(self):
- return self.number
-
- def getPreviousBuild(self):
- if self.number == 0:
- return None
- return self.builder.getBuild(self.number-1)
-
- def getAllGotRevisions(self):
- all_got_revisions = self.properties.getProperty('got_revision', {})
- # For backwards compatibility all_got_revisions is a string if codebases
- # are not used. Convert to the default internal type (dict)
- if not isinstance(all_got_revisions, dict):
- all_got_revisions = {'': all_got_revisions}
- return all_got_revisions
-
- def getSourceStamps(self, absolute=False):
- sourcestamps = []
- if not absolute:
- sourcestamps.extend(self.sources)
- else:
- all_got_revisions = self.getAllGotRevisions() or {}
- # always make a new instance
- for ss in self.sources:
- if ss.codebase in all_got_revisions:
- got_revision = all_got_revisions[ss.codebase]
- sourcestamps.append(ss.getAbsoluteSourceStamp(got_revision))
- else:
- # No absolute revision information available
- # Probably build has been stopped before ending all sourcesteps
- # Return a clone with original revision
- sourcestamps.append(ss.clone())
- return sourcestamps
-
- def getReason(self):
- return self.reason
-
- def getChanges(self):
- return self.changes
-
- def getRevisions(self):
- revs = []
- for c in self.changes:
- rev = str(c.revision)
- if rev > 7: # for long hashes
- rev = rev[:7]
- revs.append(rev)
- return ", ".join(revs)
-
- def getResponsibleUsers(self):
- return self.blamelist
-
- def getInterestedUsers(self):
- # TODO: the Builder should add others: sheriffs, domain-owners
- return self.properties.getProperty('owners', [])
-
- def getSteps(self):
- """Return a list of IBuildStepStatus objects. For invariant builds
- (those which always use the same set of Steps), this should be the
- complete list, however some of the steps may not have started yet
- (step.getTimes()[0] will be None). For variant builds, this may not
- be complete (asking again later may give you more of them)."""
- return self.steps
-
- def getTimes(self):
- return (self.started, self.finished)
-
- _sentinel = [] # used as a sentinel to indicate unspecified initial_value
- def getSummaryStatistic(self, name, summary_fn, initial_value=_sentinel):
- """Summarize the named statistic over all steps in which it
- exists, using combination_fn and initial_value to combine multiple
- results into a single result. This translates to a call to Python's
- X{reduce}::
- return reduce(summary_fn, step_stats_list, initial_value)
- """
- step_stats_list = [
- st.getStatistic(name)
- for st in self.steps
- if st.hasStatistic(name) ]
- if initial_value is self._sentinel:
- return reduce(summary_fn, step_stats_list)
- else:
- return reduce(summary_fn, step_stats_list, initial_value)
-
- def isFinished(self):
- return (self.finished is not None)
-
- def waitUntilFinished(self):
- if self.finished:
- d = defer.succeed(self)
- else:
- d = defer.Deferred()
- self.finishedWatchers.append(d)
- return d
-
- # while the build is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA(self):
- if self.finished is not None:
- return None
- if not self.progress:
- return None
- eta = self.progress.eta()
- if eta is None:
- return None
- return eta - util.now()
-
- def getCurrentStep(self):
- return self.currentStep
-
- # Once you know the build has finished, the following methods are legal.
- # Before ths build has finished, they all return None.
-
- def getText(self):
- text = []
- text.extend(self.text)
- for s in self.steps:
- text.extend(s.text2)
- return text
-
- def getResults(self):
- return self.results
-
- def getSlavename(self):
- return self.slavename
-
- def getTestResults(self):
- return self.testResults
-
- def getLogs(self):
- logs = []
- for s in self.steps:
- for loog in s.getLogs():
- logs.append(loog)
- return logs
-
- # subscription interface
-
- def subscribe(self, receiver, updateInterval=None):
- # will receive stepStarted and stepFinished messages
- # and maybe buildETAUpdate
- self.watchers.append(receiver)
- if updateInterval is not None:
- self.sendETAUpdate(receiver, updateInterval)
-
- def sendETAUpdate(self, receiver, updateInterval):
- self.updates[receiver] = None
- ETA = self.getETA()
- if ETA is not None:
- receiver.buildETAUpdate(self, self.getETA())
- # they might have unsubscribed during buildETAUpdate
- if receiver in self.watchers:
- self.updates[receiver] = reactor.callLater(updateInterval,
- self.sendETAUpdate,
- receiver,
- updateInterval)
-
- def unsubscribe(self, receiver):
- if receiver in self.watchers:
- self.watchers.remove(receiver)
- if receiver in self.updates:
- if self.updates[receiver] is not None:
- self.updates[receiver].cancel()
- del self.updates[receiver]
-
- # methods for the base.Build to invoke
-
- def addStepWithName(self, name):
- """The Build is setting up, and has added a new BuildStep to its
- list. Create a BuildStepStatus object to which it can send status
- updates."""
-
- s = BuildStepStatus(self, self.master, len(self.steps))
- s.setName(name)
- self.steps.append(s)
- return s
-
- def addTestResult(self, result):
- self.testResults[result.getName()] = result
-
- def setSourceStamps(self, sourceStamps):
- self.sources = sourceStamps
- self.changes = []
- for source in self.sources:
- self.changes.extend(source.changes)
-
- def setReason(self, reason):
- self.reason = reason
- def setBlamelist(self, blamelist):
- self.blamelist = blamelist
- def setProgress(self, progress):
- self.progress = progress
-
- def buildStarted(self, build):
- """The Build has been set up and is about to be started. It can now
- be safely queried, so it is time to announce the new build."""
-
- self.started = util.now()
- # now that we're ready to report status, let the BuilderStatus tell
- # the world about us
- self.builder.buildStarted(self)
-
- def setSlavename(self, slavename):
- self.slavename = slavename
-
- def setText(self, text):
- assert isinstance(text, (list, tuple))
- self.text = text
- def setResults(self, results):
- self.results = results
-
- def buildFinished(self):
- self.currentStep = None
- self.finished = util.now()
-
- for r in self.updates.keys():
- if self.updates[r] is not None:
- self.updates[r].cancel()
- del self.updates[r]
-
- watchers = self.finishedWatchers
- self.finishedWatchers = []
- for w in watchers:
- w.callback(self)
-
- # methods called by our BuildStepStatus children
-
- def stepStarted(self, step):
- self.currentStep = step
- for w in self.watchers:
- receiver = w.stepStarted(self, step)
- if receiver:
- if type(receiver) == type(()):
- step.subscribe(receiver[0], receiver[1])
- else:
- step.subscribe(receiver)
- d = step.waitUntilFinished()
- d.addCallback(lambda step: step.unsubscribe(receiver))
-
- step.waitUntilFinished().addCallback(self._stepFinished)
-
- def _stepFinished(self, step):
- results = step.getResults()
- for w in self.watchers:
- w.stepFinished(self, step, results)
-
- # methods called by our BuilderStatus parent
-
- def pruneSteps(self):
- # this build is very old: remove the build steps too
- self.steps = []
-
- # persistence stuff
-
- def generateLogfileName(self, stepname, logname):
- """Return a filename (relative to the Builder's base directory) where
- the logfile's contents can be stored uniquely.
-
- The base filename is made by combining our build number, the Step's
- name, and the log's name, then removing unsuitable characters. The
- filename is then made unique by appending _0, _1, etc, until it does
- not collide with any other logfile.
-
- These files are kept in the Builder's basedir (rather than a
- per-Build subdirectory) because that makes cleanup easier: cron and
- find will help get rid of the old logs, but the empty directories are
- more of a hassle to remove."""
-
- starting_filename = "%d-log-%s-%s" % (self.number, stepname, logname)
- starting_filename = re.sub(r'[^\w\.\-]', '_', starting_filename)
- # now make it unique
- unique_counter = 0
- filename = starting_filename
- while filename in [l.filename
- for step in self.steps
- for l in step.getLogs()
- if l.filename]:
- filename = "%s_%d" % (starting_filename, unique_counter)
- unique_counter += 1
- return filename
-
- def __getstate__(self):
- d = styles.Versioned.__getstate__(self)
- # for now, a serialized Build is always "finished". We will never
- # save unfinished builds.
- if not self.finished:
- d['finished'] = util.now()
- # TODO: push an "interrupted" step so it is clear that the build
- # was interrupted. The builder will have a 'shutdown' event, but
- # someone looking at just this build will be confused as to why
- # the last log is truncated.
- for k in [ 'builder', 'watchers', 'updates', 'finishedWatchers',
- 'master' ]:
- if k in d: del d[k]
- return d
-
- def __setstate__(self, d):
- styles.Versioned.__setstate__(self, d)
- self.watchers = []
- self.updates = {}
- self.finishedWatchers = []
-
- def setProcessObjects(self, builder, master):
- self.builder = builder
- self.master = master
- for step in self.steps:
- step.setProcessObjects(self, master)
- def upgradeToVersion1(self):
- if hasattr(self, "sourceStamp"):
- # the old .sourceStamp attribute wasn't actually very useful
- maxChangeNumber, patch = self.sourceStamp
- changes = getattr(self, 'changes', [])
- source = sourcestamp.SourceStamp(branch=None,
- revision=None,
- patch=patch,
- changes=changes)
- self.source = source
- self.changes = source.changes
- del self.sourceStamp
- self.wasUpgraded = True
-
- def upgradeToVersion2(self):
- self.properties = {}
- self.wasUpgraded = True
-
- def upgradeToVersion3(self):
- # in version 3, self.properties became a Properties object
- propdict = self.properties
- self.properties = properties.Properties()
- self.properties.update(propdict, "Upgrade from previous version")
- self.wasUpgraded = True
-
- def upgradeToVersion4(self):
- # buildstatus contains list of sourcestamps, convert single to list
- if hasattr(self, "source"):
- self.sources = [self.source]
- del self.source
- self.wasUpgraded = True
-
- def checkLogfiles(self):
- # check that all logfiles exist, and remove references to any that
- # have been deleted (e.g., by purge())
- for s in self.steps:
- s.checkLogfiles()
-
- def saveYourself(self):
- filename = os.path.join(self.builder.basedir, "%d" % self.number)
- if os.path.isdir(filename):
- # leftover from 0.5.0, which stored builds in directories
- shutil.rmtree(filename, ignore_errors=True)
- tmpfilename = filename + ".tmp"
- try:
- with open(tmpfilename, "wb") as f:
- dump(self, f, -1)
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one, so
- # fall back to delete-first. There are ways this can fail and
- # lose the builder's history, so we avoid using it in the
- # general (non-windows) case
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(tmpfilename, filename)
- except:
- log.msg("unable to save build %s-#%d" % (self.builder.name,
- self.number))
- log.err()
-
- def asDict(self):
- result = {}
- # Constant
- result['builderName'] = self.builder.name
- result['number'] = self.getNumber()
- result['sourceStamps'] = [ss.asDict() for ss in self.getSourceStamps()]
- result['reason'] = self.getReason()
- result['blame'] = self.getResponsibleUsers()
-
- # Transient
- result['properties'] = self.getProperties().asList()
- result['times'] = self.getTimes()
- result['text'] = self.getText()
- result['results'] = self.getResults()
- result['slave'] = self.getSlavename()
- # TODO(maruel): Add.
- #result['test_results'] = self.getTestResults()
- result['logs'] = [[l.getName(),
- self.builder.status.getURLForThing(l)] for l in self.getLogs()]
- result['eta'] = self.getETA()
- result['steps'] = [bss.asDict() for bss in self.steps]
- if self.getCurrentStep():
- result['currentStep'] = self.getCurrentStep().asDict()
- else:
- result['currentStep'] = None
- return result
-
-components.registerAdapter(lambda build_status : build_status.properties,
- BuildStatus, interfaces.IProperties)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py
deleted file mode 100644
index 8430d13e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py
+++ /dev/null
@@ -1,583 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-import os, re, itertools
-from cPickle import load, dump
-
-from zope.interface import implements
-from twisted.python import log, runtime
-from twisted.persisted import styles
-from buildbot import interfaces, util
-from buildbot.util.lru import LRUCache
-from buildbot.status.event import Event
-from buildbot.status.build import BuildStatus
-from buildbot.status.buildrequest import BuildRequestStatus
-
-# user modules expect these symbols to be present here
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED
-from buildbot.status.results import EXCEPTION, RETRY, Results, worst_status
-_hush_pyflakes = [ SUCCESS, WARNINGS, FAILURE, SKIPPED,
- EXCEPTION, RETRY, Results, worst_status ]
-
-class BuilderStatus(styles.Versioned):
- """I handle status information for a single process.build.Builder object.
- That object sends status changes to me (frequently as Events), and I
- provide them on demand to the various status recipients, like the HTML
- waterfall display and the live status clients. It also sends build
- summaries to me, which I log and provide to status clients who aren't
- interested in seeing details of the individual build steps.
-
- I am responsible for maintaining the list of historic Events and Builds,
- pruning old ones, and loading them from / saving them to disk.
-
- I live in the buildbot.process.build.Builder object, in the
- .builder_status attribute.
-
- @type category: string
- @ivar category: user-defined category this builder belongs to; can be
- used to filter on in status clients
- """
-
- implements(interfaces.IBuilderStatus, interfaces.IEventSource)
-
- persistenceVersion = 1
- persistenceForgets = ( 'wasUpgraded', )
-
- category = None
- currentBigState = "offline" # or idle/waiting/interlocked/building
- basedir = None # filled in by our parent
-
- def __init__(self, buildername, category, master, description):
- self.name = buildername
- self.category = category
- self.description = description
- self.master = master
-
- self.slavenames = []
- self.events = []
- # these three hold Events, and are used to retrieve the current
- # state of the boxes.
- self.lastBuildStatus = None
- #self.currentBig = None
- #self.currentSmall = None
- self.currentBuilds = []
- self.nextBuild = None
- self.watchers = []
- self.buildCache = LRUCache(self.cacheMiss)
-
- # persistence
-
- def __getstate__(self):
- # when saving, don't record transient stuff like what builds are
- # currently running, because they won't be there when we start back
- # up. Nor do we save self.watchers, nor anything that gets set by our
- # parent like .basedir and .status
- d = styles.Versioned.__getstate__(self)
- d['watchers'] = []
- del d['buildCache']
- for b in self.currentBuilds:
- b.saveYourself()
- # TODO: push a 'hey, build was interrupted' event
- del d['currentBuilds']
- d.pop('pendingBuilds', None)
- del d['currentBigState']
- del d['basedir']
- del d['status']
- del d['nextBuildNumber']
- del d['master']
- return d
-
- def __setstate__(self, d):
- # when loading, re-initialize the transient stuff. Remember that
- # upgradeToVersion1 and such will be called after this finishes.
- styles.Versioned.__setstate__(self, d)
- self.buildCache = LRUCache(self.cacheMiss)
- self.currentBuilds = []
- self.watchers = []
- self.slavenames = []
- # self.basedir must be filled in by our parent
- # self.status must be filled in by our parent
- # self.master must be filled in by our parent
-
- def upgradeToVersion1(self):
- if hasattr(self, 'slavename'):
- self.slavenames = [self.slavename]
- del self.slavename
- if hasattr(self, 'nextBuildNumber'):
- del self.nextBuildNumber # determineNextBuildNumber chooses this
- self.wasUpgraded = True
-
- def determineNextBuildNumber(self):
- """Scan our directory of saved BuildStatus instances to determine
- what our self.nextBuildNumber should be. Set it one larger than the
- highest-numbered build we discover. This is called by the top-level
- Status object shortly after we are created or loaded from disk.
- """
- existing_builds = [int(f)
- for f in os.listdir(self.basedir)
- if re.match("^\d+$", f)]
- if existing_builds:
- self.nextBuildNumber = max(existing_builds) + 1
- else:
- self.nextBuildNumber = 0
-
- def saveYourself(self):
- for b in self.currentBuilds:
- if not b.isFinished:
- # interrupted build, need to save it anyway.
- # BuildStatus.saveYourself will mark it as interrupted.
- b.saveYourself()
- filename = os.path.join(self.basedir, "builder")
- tmpfilename = filename + ".tmp"
- try:
- with open(tmpfilename, "wb") as f:
- dump(self, f, -1)
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(tmpfilename, filename)
- except:
- log.msg("unable to save builder %s" % self.name)
- log.err()
-
- # build cache management
-
- def setCacheSize(self, size):
- self.buildCache.set_max_size(size)
-
- def makeBuildFilename(self, number):
- return os.path.join(self.basedir, "%d" % number)
-
- def getBuildByNumber(self, number):
- return self.buildCache.get(number)
-
- def loadBuildFromFile(self, number):
- filename = self.makeBuildFilename(number)
- try:
- log.msg("Loading builder %s's build %d from on-disk pickle"
- % (self.name, number))
- with open(filename, "rb") as f:
- build = load(f)
- build.setProcessObjects(self, self.master)
-
- # (bug #1068) if we need to upgrade, we probably need to rewrite
- # this pickle, too. We determine this by looking at the list of
- # Versioned objects that have been unpickled, and (after doUpgrade)
- # checking to see if any of them set wasUpgraded. The Versioneds'
- # upgradeToVersionNN methods all set this.
- versioneds = styles.versionedsToUpgrade
- styles.doUpgrade()
- if True in [ hasattr(o, 'wasUpgraded') for o in versioneds.values() ]:
- log.msg("re-writing upgraded build pickle")
- build.saveYourself()
-
- # check that logfiles exist
- build.checkLogfiles()
- return build
- except IOError:
- raise IndexError("no such build %d" % number)
- except EOFError:
- raise IndexError("corrupted build pickle %d" % number)
-
- def cacheMiss(self, number, **kwargs):
- # If kwargs['val'] exists, this is a new value being added to
- # the cache. Just return it.
- if 'val' in kwargs:
- return kwargs['val']
-
- # first look in currentBuilds
- for b in self.currentBuilds:
- if b.number == number:
- return b
-
- # then fall back to loading it from disk
- return self.loadBuildFromFile(number)
-
- def prune(self, events_only=False):
- # begin by pruning our own events
- eventHorizon = self.master.config.eventHorizon
- self.events = self.events[-eventHorizon:]
-
- if events_only:
- return
-
- # get the horizons straight
- buildHorizon = self.master.config.buildHorizon
- if buildHorizon is not None:
- earliest_build = self.nextBuildNumber - buildHorizon
- else:
- earliest_build = 0
-
- logHorizon = self.master.config.logHorizon
- if logHorizon is not None:
- earliest_log = self.nextBuildNumber - logHorizon
- else:
- earliest_log = 0
-
- if earliest_log < earliest_build:
- earliest_log = earliest_build
-
- if earliest_build == 0:
- return
-
- # skim the directory and delete anything that shouldn't be there anymore
- build_re = re.compile(r"^([0-9]+)$")
- build_log_re = re.compile(r"^([0-9]+)-.*$")
- # if the directory doesn't exist, bail out here
- if not os.path.exists(self.basedir):
- return
-
- for filename in os.listdir(self.basedir):
- num = None
- mo = build_re.match(filename)
- is_logfile = False
- if mo:
- num = int(mo.group(1))
- else:
- mo = build_log_re.match(filename)
- if mo:
- num = int(mo.group(1))
- is_logfile = True
-
- if num is None: continue
- if num in self.buildCache.cache: continue
-
- if (is_logfile and num < earliest_log) or num < earliest_build:
- pathname = os.path.join(self.basedir, filename)
- log.msg("pruning '%s'" % pathname)
- try: os.unlink(pathname)
- except OSError: pass
-
- # IBuilderStatus methods
- def getName(self):
- # if builderstatus page does show not up without any reason then
- # str(self.name) may be a workaround
- return self.name
-
- def setDescription(self, description):
- # used during reconfig
- self.description = description
-
- def getDescription(self):
- return self.description
-
- def getState(self):
- return (self.currentBigState, self.currentBuilds)
-
- def getSlaves(self):
- return [self.status.getSlave(name) for name in self.slavenames]
-
- def getPendingBuildRequestStatuses(self):
- db = self.status.master.db
- d = db.buildrequests.getBuildRequests(claimed=False,
- buildername=self.name)
- def make_statuses(brdicts):
- return [BuildRequestStatus(self.name, brdict['brid'],
- self.status)
- for brdict in brdicts]
- d.addCallback(make_statuses)
- return d
-
- def getCurrentBuilds(self):
- return self.currentBuilds
-
- def getLastFinishedBuild(self):
- b = self.getBuild(-1)
- if not (b and b.isFinished()):
- b = self.getBuild(-2)
- return b
-
- def setCategory(self, category):
- # used during reconfig
- self.category = category
-
- def getCategory(self):
- return self.category
-
- def getBuild(self, number):
- if number < 0:
- number = self.nextBuildNumber + number
- if number < 0 or number >= self.nextBuildNumber:
- return None
-
- try:
- return self.getBuildByNumber(number)
- except IndexError:
- return None
-
- def getEvent(self, number):
- try:
- return self.events[number]
- except IndexError:
- return None
-
- def _getBuildBranches(self, build):
- return set([ ss.branch
- for ss in build.getSourceStamps() ])
-
- def generateFinishedBuilds(self, branches=[],
- num_builds=None,
- max_buildnum=None,
- finished_before=None,
- results=None,
- max_search=200):
- got = 0
- branches = set(branches)
- for Nb in itertools.count(1):
- if Nb > self.nextBuildNumber:
- break
- if Nb > max_search:
- break
- build = self.getBuild(-Nb)
- if build is None:
- continue
- if max_buildnum is not None:
- if build.getNumber() > max_buildnum:
- continue
- if not build.isFinished():
- continue
- if finished_before is not None:
- start, end = build.getTimes()
- if end >= finished_before:
- continue
- # if we were asked to filter on branches, and none of the
- # sourcestamps match, skip this build
- if branches and not branches & self._getBuildBranches(build):
- continue
- if results is not None:
- if build.getResults() not in results:
- continue
- got += 1
- yield build
- if num_builds is not None:
- if got >= num_builds:
- return
-
- def eventGenerator(self, branches=[], categories=[], committers=[], minTime=0):
- """This function creates a generator which will provide all of this
- Builder's status events, starting with the most recent and
- progressing backwards in time. """
-
- # remember the oldest-to-earliest flow here. "next" means earlier.
-
- # TODO: interleave build steps and self.events by timestamp.
- # TODO: um, I think we're already doing that.
-
- # TODO: there's probably something clever we could do here to
- # interleave two event streams (one from self.getBuild and the other
- # from self.getEvent), which would be simpler than this control flow
-
- eventIndex = -1
- e = self.getEvent(eventIndex)
- branches = set(branches)
- for Nb in range(1, self.nextBuildNumber+1):
- b = self.getBuild(-Nb)
- if not b:
- # HACK: If this is the first build we are looking at, it is
- # possible it's in progress but locked before it has written a
- # pickle; in this case keep looking.
- if Nb == 1:
- continue
- break
- if b.getTimes()[0] < minTime:
- break
- # if we were asked to filter on branches, and none of the
- # sourcestamps match, skip this build
- if branches and not branches & self._getBuildBranches(b):
- continue
- if categories and not b.getBuilder().getCategory() in categories:
- continue
- if committers and not [True for c in b.getChanges() if c.who in committers]:
- continue
- steps = b.getSteps()
- for Ns in range(1, len(steps)+1):
- if steps[-Ns].started:
- step_start = steps[-Ns].getTimes()[0]
- while e is not None and e.getTimes()[0] > step_start:
- yield e
- eventIndex -= 1
- e = self.getEvent(eventIndex)
- yield steps[-Ns]
- yield b
- while e is not None:
- yield e
- eventIndex -= 1
- e = self.getEvent(eventIndex)
- if e and e.getTimes()[0] < minTime:
- break
-
- def subscribe(self, receiver):
- # will get builderChangedState, buildStarted, buildFinished,
- # requestSubmitted, requestCancelled. Note that a request which is
- # resubmitted (due to a slave disconnect) will cause requestSubmitted
- # to be invoked multiple times.
- self.watchers.append(receiver)
- self.publishState(receiver)
- # our parent Status provides requestSubmitted and requestCancelled
- self.status._builder_subscribe(self.name, receiver)
-
- def unsubscribe(self, receiver):
- self.watchers.remove(receiver)
- self.status._builder_unsubscribe(self.name, receiver)
-
- ## Builder interface (methods called by the Builder which feeds us)
-
- def setSlavenames(self, names):
- self.slavenames = names
-
- def addEvent(self, text=[]):
- # this adds a duration event. When it is done, the user should call
- # e.finish(). They can also mangle it by modifying .text
- e = Event()
- e.started = util.now()
- e.text = text
- self.events.append(e)
- self.prune(events_only=True)
- return e # they are free to mangle it further
-
- def addPointEvent(self, text=[]):
- # this adds a point event, one which occurs as a single atomic
- # instant of time.
- e = Event()
- e.started = util.now()
- e.finished = 0
- e.text = text
- self.events.append(e)
- self.prune(events_only=True)
- return e # for consistency, but they really shouldn't touch it
-
- def setBigState(self, state):
- needToUpdate = state != self.currentBigState
- self.currentBigState = state
- if needToUpdate:
- self.publishState()
-
- def publishState(self, target=None):
- state = self.currentBigState
-
- if target is not None:
- # unicast
- target.builderChangedState(self.name, state)
- return
- for w in self.watchers:
- try:
- w.builderChangedState(self.name, state)
- except:
- log.msg("Exception caught publishing state to %r" % w)
- log.err()
-
- def newBuild(self):
- """The Builder has decided to start a build, but the Build object is
- not yet ready to report status (it has not finished creating the
- Steps). Create a BuildStatus object that it can use."""
- number = self.nextBuildNumber
- self.nextBuildNumber += 1
- # TODO: self.saveYourself(), to make sure we don't forget about the
- # build number we've just allocated. This is not quite as important
- # as it was before we switch to determineNextBuildNumber, but I think
- # it may still be useful to have the new build save itself.
- s = BuildStatus(self, self.master, number)
- s.waitUntilFinished().addCallback(self._buildFinished)
- return s
-
- # buildStarted is called by our child BuildStatus instances
- def buildStarted(self, s):
- """Now the BuildStatus object is ready to go (it knows all of its
- Steps, its ETA, etc), so it is safe to notify our watchers."""
-
- assert s.builder is self # paranoia
- assert s not in self.currentBuilds
- self.currentBuilds.append(s)
- self.buildCache.get(s.number, val=s)
-
- # now that the BuildStatus is prepared to answer queries, we can
- # announce the new build to all our watchers
-
- for w in self.watchers: # TODO: maybe do this later? callLater(0)?
- try:
- receiver = w.buildStarted(self.getName(), s)
- if receiver:
- if type(receiver) == type(()):
- s.subscribe(receiver[0], receiver[1])
- else:
- s.subscribe(receiver)
- d = s.waitUntilFinished()
- d.addCallback(lambda s: s.unsubscribe(receiver))
- except:
- log.msg("Exception caught notifying %r of buildStarted event" % w)
- log.err()
-
- def _buildFinished(self, s):
- assert s in self.currentBuilds
- s.saveYourself()
- self.currentBuilds.remove(s)
-
- name = self.getName()
- results = s.getResults()
- for w in self.watchers:
- try:
- w.buildFinished(name, s, results)
- except:
- log.msg("Exception caught notifying %r of buildFinished event" % w)
- log.err()
-
- self.prune() # conserve disk
-
-
- def asDict(self):
- result = {}
- # Constant
- # TODO(maruel): Fix me. We don't want to leak the full path.
- result['basedir'] = os.path.basename(self.basedir)
- result['category'] = self.category
- result['slaves'] = self.slavenames
- result['schedulers'] = [ s.name
- for s in self.status.master.allSchedulers()
- if self.name in s.builderNames ]
- #result['url'] = self.parent.getURLForThing(self)
- # TODO(maruel): Add cache settings? Do we care?
-
- # Transient
- # Collect build numbers.
- # Important: Only grab the *cached* builds numbers to reduce I/O.
- current_builds = [b.getNumber() for b in self.currentBuilds]
- cached_builds = list(set(self.buildCache.keys() + current_builds))
- cached_builds.sort()
- result['cachedBuilds'] = cached_builds
- result['currentBuilds'] = current_builds
- result['state'] = self.getState()[0]
- # lies, but we don't have synchronous access to this info; use
- # asDict_async instead
- result['pendingBuilds'] = 0
- return result
-
- def asDict_async(self):
- """Just like L{asDict}, but with a nonzero pendingBuilds."""
- result = self.asDict()
- d = self.getPendingBuildRequestStatuses()
- def combine(statuses):
- result['pendingBuilds'] = len(statuses)
- return result
- d.addCallback(combine)
- return d
-
- def getMetrics(self):
- return self.botmaster.parent.metrics
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py
deleted file mode 100644
index 1f52902e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces
-from buildbot.util.eventual import eventually
-
-class BuildRequestStatus:
- implements(interfaces.IBuildRequestStatus)
-
- def __init__(self, buildername, brid, status):
- self.buildername = buildername
- self.brid = brid
- self.status = status
- self.master = status.master
-
- self._buildrequest = None
- self._buildrequest_lock = defer.DeferredLock()
-
- @defer.inlineCallbacks
- def _getBuildRequest(self):
- """
- Get the underlying BuildRequest object for this status. This is a slow
- operation!
-
- @returns: BuildRequest instance or None, via Deferred
- """
- # late binding to avoid an import cycle
- from buildbot.process import buildrequest
-
- # this is only set once, so no need to lock if we already have it
- if self._buildrequest:
- defer.returnValue(self._buildrequest)
- return
-
- yield self._buildrequest_lock.acquire()
-
- try:
- if not self._buildrequest:
- brd = yield self.master.db.buildrequests.getBuildRequest(
- self.brid)
-
- br = yield buildrequest.BuildRequest.fromBrdict(self.master,
- brd)
- self._buildrequest = br
- except: # try/finally isn't allowed in generators in older Pythons
- self._buildrequest_lock.release()
- raise
-
- self._buildrequest_lock.release()
-
- defer.returnValue(self._buildrequest)
-
- def buildStarted(self, build):
- self.status._buildrequest_buildStarted(build.status)
- self.builds.append(build.status)
-
- # methods called by our clients
- @defer.inlineCallbacks
- def getBsid(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.bsid)
-
- @defer.inlineCallbacks
- def getBuildProperties(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.properties)
-
- @defer.inlineCallbacks
- def getSourceStamp(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.source)
-
- def getBuilderName(self):
- return self.buildername
-
- @defer.inlineCallbacks
- def getBuilds(self):
- builder = self.status.getBuilder(self.getBuilderName())
- builds = []
-
- bdicts = yield self.master.db.builds.getBuildsForRequest(self.brid)
-
- buildnums = sorted([ bdict['number'] for bdict in bdicts ])
-
- for buildnum in buildnums:
- bs = builder.getBuild(buildnum)
- if bs:
- builds.append(bs)
- defer.returnValue(builds)
-
- def subscribe(self, observer):
- d = self.getBuilds()
- def notify_old(oldbuilds):
- for bs in oldbuilds:
- eventually(observer, bs)
- d.addCallback(notify_old)
- d.addCallback(lambda _ :
- self.status._buildrequest_subscribe(self.brid, observer))
- d.addErrback(log.err, 'while notifying subscribers')
-
- def unsubscribe(self, observer):
- self.status._buildrequest_unsubscribe(self.brid, observer)
-
- @defer.inlineCallbacks
- def getSubmitTime(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.submittedAt)
-
- def asDict(self):
- result = {}
- # Constant
- result['source'] = None # not available sync, sorry
- result['builderName'] = self.buildername
- result['submittedAt'] = None # not availably sync, sorry
-
- # Transient
- result['builds'] = [] # not available async, sorry
- return result
-
- @defer.inlineCallbacks
- def asDict_async(self):
- result = {}
-
- ss = yield self.getSourceStamp()
- result['source'] = ss.asDict()
- props = yield self.getBuildProperties()
- result['properties'] = props.asList()
- result['builderName'] = self.getBuilderName()
- result['submittedAt'] = yield self.getSubmitTime()
-
- builds = yield self.getBuilds()
- result['builds'] = [ build.asDict() for build in builds ]
-
- defer.returnValue(result)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py
deleted file mode 100644
index 524473a7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from buildbot import interfaces
-from buildbot.status.buildrequest import BuildRequestStatus
-
-class BuildSetStatus:
- implements(interfaces.IBuildSetStatus)
-
- def __init__(self, bsdict, status):
- self.id = bsdict['bsid']
- self.bsdict = bsdict
- self.status = status
- self.master = status.master
-
- # methods for our clients
-
- def getReason(self):
- return self.bsdict['reason']
-
- def getResults(self):
- return self.bsdict['results']
-
- def getID(self):
- return self.bsdict['external_idstring']
-
- def isFinished(self):
- return self.bsdict['complete']
-
- def getBuilderNamesAndBuildRequests(self):
- # returns a Deferred; undocumented method that may be removed
- # without warning
- d = self.master.db.buildrequests.getBuildRequests(bsid=self.id)
- def get_objects(brdicts):
- return dict([
- (brd['buildername'], BuildRequestStatus(brd['buildername'],
- brd['brid'], self.status))
- for brd in brdicts ])
- d.addCallback(get_objects)
- return d
-
- def getBuilderNames(self):
- d = self.master.db.buildrequests.getBuildRequests(bsid=self.id)
- def get_names(brdicts):
- return sorted([ brd['buildername'] for brd in brdicts ])
- d.addCallback(get_names)
- return d
-
- def waitUntilFinished(self):
- return self.status._buildset_waitUntilFinished(self.id)
-
- def asDict(self):
- d = dict(self.bsdict)
- d["submitted_at"] = str(self.bsdict["submitted_at"])
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py
deleted file mode 100644
index 8e453873..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py
+++ /dev/null
@@ -1,386 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from zope.interface import implements
-from twisted.persisted import styles
-from twisted.python import log
-from twisted.internet import reactor, defer
-from buildbot import interfaces, util
-from buildbot.status.logfile import LogFile, HTMLLogFile
-
-class BuildStepStatus(styles.Versioned):
- """
- I represent a collection of output status for a
- L{buildbot.process.step.BuildStep}.
-
- Statistics contain any information gleaned from a step that is
- not in the form of a logfile. As an example, steps that run
- tests might gather statistics about the number of passed, failed,
- or skipped tests.
-
- @type progress: L{buildbot.status.progress.StepProgress}
- @cvar progress: tracks ETA for the step
- @type text: list of strings
- @cvar text: list of short texts that describe the command and its status
- @type text2: list of strings
- @cvar text2: list of short texts added to the overall build description
- @type logs: dict of string -> L{buildbot.status.logfile.LogFile}
- @ivar logs: logs of steps
- @type statistics: dict
- @ivar statistics: results from running this step
- """
- # note that these are created when the Build is set up, before each
- # corresponding BuildStep has started.
- implements(interfaces.IBuildStepStatus, interfaces.IStatusEvent)
-
- persistenceVersion = 4
- persistenceForgets = ( 'wasUpgraded', )
-
- started = None
- finished = None
- progress = None
- text = []
- results = None
- text2 = []
- watchers = []
- updates = {}
- finishedWatchers = []
- statistics = {}
- step_number = None
- hidden = False
-
- def __init__(self, parent, master, step_number):
- assert interfaces.IBuildStatus(parent)
- self.build = parent
- self.step_number = step_number
- self.hidden = False
- self.logs = []
- self.urls = {}
- self.watchers = []
- self.updates = {}
- self.finishedWatchers = []
- self.statistics = {}
- self.skipped = False
-
- self.master = master
-
- self.waitingForLocks = False
-
- def getName(self):
- """Returns a short string with the name of this step. This string
- may have spaces in it."""
- return self.name
-
- def getBuild(self):
- return self.build
-
- def getTimes(self):
- return (self.started, self.finished)
-
- def getExpectations(self):
- """Returns a list of tuples (name, current, target)."""
- if not self.progress:
- return []
- ret = []
- metrics = self.progress.progress.keys()
- metrics.sort()
- for m in metrics:
- t = (m, self.progress.progress[m], self.progress.expectations[m])
- ret.append(t)
- return ret
-
- def getLogs(self):
- return self.logs
-
- def getURLs(self):
- return self.urls.copy()
-
- def isStarted(self):
- return (self.started is not None)
-
- def isSkipped(self):
- return self.skipped
-
- def isFinished(self):
- return (self.finished is not None)
-
- def isHidden(self):
- return self.hidden
-
- def waitUntilFinished(self):
- if self.finished:
- d = defer.succeed(self)
- else:
- d = defer.Deferred()
- self.finishedWatchers.append(d)
- return d
-
- # while the step is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA(self):
- if self.started is None:
- return None # not started yet
- if self.finished is not None:
- return None # already finished
- if not self.progress:
- return None # no way to predict
- return self.progress.remaining()
-
- # Once you know the step has finished, the following methods are legal.
- # Before this step has finished, they all return None.
-
- def getText(self):
- """Returns a list of strings which describe the step. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
- return self.text
-
- def getResults(self):
- """Return a tuple describing the results of the step.
- 'result' is one of the constants in L{buildbot.status.builder}:
- SUCCESS, WARNINGS, FAILURE, or SKIPPED.
- 'strings' is an optional list of strings that the step wants to
- append to the overall build's results. These strings are usually
- more terse than the ones returned by getText(): in particular,
- successful Steps do not usually contribute any text to the
- overall build.
-
- @rtype: tuple of int, list of strings
- @returns: (result, strings)
- """
- return (self.results, self.text2)
-
- def hasStatistic(self, name):
- """Return true if this step has a value for the given statistic.
- """
- return self.statistics.has_key(name)
-
- def getStatistic(self, name, default=None):
- """Return the given statistic, if present
- """
- return self.statistics.get(name, default)
-
- def getStatistics(self):
- return self.statistics.copy()
-
- # subscription interface
-
- def subscribe(self, receiver, updateInterval=10):
- # will get logStarted, logFinished, stepETAUpdate
- assert receiver not in self.watchers
- self.watchers.append(receiver)
- self.sendETAUpdate(receiver, updateInterval)
-
- def sendETAUpdate(self, receiver, updateInterval):
- self.updates[receiver] = None
- # they might unsubscribe during stepETAUpdate
- receiver.stepETAUpdate(self.build, self,
- self.getETA(), self.getExpectations())
- if receiver in self.watchers:
- self.updates[receiver] = reactor.callLater(updateInterval,
- self.sendETAUpdate,
- receiver,
- updateInterval)
-
- def unsubscribe(self, receiver):
- if receiver in self.watchers:
- self.watchers.remove(receiver)
- if receiver in self.updates:
- if self.updates[receiver] is not None:
- self.updates[receiver].cancel()
- del self.updates[receiver]
-
-
- # methods to be invoked by the BuildStep
-
- def setName(self, stepname):
- self.name = stepname
-
- def setColor(self, color):
- log.msg("BuildStepStatus.setColor is no longer supported -- ignoring color %s" % (color,))
-
- def setProgress(self, stepprogress):
- self.progress = stepprogress
-
- def setHidden(self, hidden):
- self.hidden = hidden
-
- def stepStarted(self):
- self.started = util.now()
- if self.build:
- self.build.stepStarted(self)
-
- def addLog(self, name):
- assert self.started # addLog before stepStarted won't notify watchers
- logfilename = self.build.generateLogfileName(self.name, name)
- log = LogFile(self, name, logfilename)
- self.logs.append(log)
- for w in self.watchers:
- receiver = w.logStarted(self.build, self, log)
- if receiver:
- log.subscribe(receiver, True)
- d = log.waitUntilFinished()
- d.addCallback(lambda log: log.unsubscribe(receiver))
- d = log.waitUntilFinished()
- d.addCallback(self.logFinished)
- return log
-
- def addHTMLLog(self, name, html):
- assert self.started # addLog before stepStarted won't notify watchers
- logfilename = self.build.generateLogfileName(self.name, name)
- log = HTMLLogFile(self, name, logfilename, html)
- self.logs.append(log)
- for w in self.watchers:
- w.logStarted(self.build, self, log)
- w.logFinished(self.build, self, log)
-
- def logFinished(self, log):
- for w in self.watchers:
- w.logFinished(self.build, self, log)
-
- def addURL(self, name, url):
- self.urls[name] = url
-
- def setText(self, text):
- self.text = text
- for w in self.watchers:
- w.stepTextChanged(self.build, self, text)
- def setText2(self, text):
- self.text2 = text
- for w in self.watchers:
- w.stepText2Changed(self.build, self, text)
-
- def setStatistic(self, name, value):
- """Set the given statistic. Usually called by subclasses.
- """
- self.statistics[name] = value
-
- def setSkipped(self, skipped):
- self.skipped = skipped
-
- def stepFinished(self, results):
- self.finished = util.now()
- self.results = results
- cld = [] # deferreds for log compression
- logCompressionLimit = self.master.config.logCompressionLimit
- for loog in self.logs:
- if not loog.isFinished():
- loog.finish()
- # if log compression is on, and it's a real LogFile,
- # HTMLLogFiles aren't files
- if logCompressionLimit is not False and \
- isinstance(loog, LogFile):
- if os.path.getsize(loog.getFilename()) > logCompressionLimit:
- loog_deferred = loog.compressLog()
- if loog_deferred:
- cld.append(loog_deferred)
-
- for r in self.updates.keys():
- if self.updates[r] is not None:
- self.updates[r].cancel()
- del self.updates[r]
-
- watchers = self.finishedWatchers
- self.finishedWatchers = []
- for w in watchers:
- w.callback(self)
- if cld:
- return defer.DeferredList(cld)
-
- def checkLogfiles(self):
- # filter out logs that have been deleted
- self.logs = [ l for l in self.logs if l.hasContents() ]
-
- def isWaitingForLocks(self):
- return self.waitingForLocks
-
- def setWaitingForLocks(self, waiting):
- self.waitingForLocks = waiting
-
- # persistence
-
- def __getstate__(self):
- d = styles.Versioned.__getstate__(self)
- del d['build'] # filled in when loading
- if d.has_key('progress'):
- del d['progress']
- del d['watchers']
- del d['finishedWatchers']
- del d['updates']
- del d['master']
- return d
-
- def __setstate__(self, d):
- styles.Versioned.__setstate__(self, d)
- # self.build must be filled in by our parent
-
- # point the logs to this object
- self.watchers = []
- self.finishedWatchers = []
- self.updates = {}
-
- def setProcessObjects(self, build, master):
- self.build = build
- self.master = master
- for loog in self.logs:
- loog.step = self
- loog.master = master
-
- def upgradeToVersion1(self):
- if not hasattr(self, "urls"):
- self.urls = {}
- self.wasUpgraded = True
-
- def upgradeToVersion2(self):
- if not hasattr(self, "statistics"):
- self.statistics = {}
- self.wasUpgraded = True
-
- def upgradeToVersion3(self):
- if not hasattr(self, "step_number"):
- self.step_number = 0
- self.wasUpgraded = True
-
- def upgradeToVersion4(self):
- if not hasattr(self, "hidden"):
- self.hidden = False
- self.wasUpgraded = True
-
- def asDict(self):
- result = {}
- # Constant
- result['name'] = self.getName()
-
- # Transient
- result['text'] = self.getText()
- result['results'] = self.getResults()
- result['isStarted'] = self.isStarted()
- result['isFinished'] = self.isFinished()
- result['statistics'] = self.statistics
- result['times'] = self.getTimes()
- result['expectations'] = self.getExpectations()
- result['eta'] = self.getETA()
- result['urls'] = self.getURLs()
- result['step_number'] = self.step_number
- result['hidden'] = self.hidden
- result['logs'] = [[l.getName(),
- self.build.builder.status.getURLForThing(l)]
- for l in self.getLogs()]
- return result
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py
deleted file mode 100644
index 39adcec5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py
+++ /dev/null
@@ -1,586 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.spread import pb
-from twisted.python import components, log as twlog
-from twisted.application import strports
-from twisted.cred import portal, checkers
-
-from buildbot import interfaces
-from zope.interface import Interface, implements
-from buildbot.status import logfile, base
-from buildbot.changes import changes
-from buildbot.util.eventual import eventually
-
-class IRemote(Interface):
- pass
-
-def makeRemote(obj):
- # we want IRemote(None) to be None, but you can't really do that with
- # adapters, so we fake it
- if obj is None:
- return None
- return IRemote(obj)
-
-
-class RemoteBuildSet(pb.Referenceable):
- def __init__(self, buildset):
- self.b = buildset
-
- def remote_getSourceStamp(self):
- return self.b.getSourceStamp()
-
- def remote_getReason(self):
- return self.b.getReason()
-
- def remote_getID(self):
- return self.b.getID()
-
- def remote_getBuilderNames(self):
- return self.b.getBuilderNames() # note: passes along the Deferred
-
- def remote_getBuildRequests(self):
- """Returns a list of (builderName, BuildRequest) tuples."""
- d = self.b.getBuilderNamesAndBuildRequests()
- def add_remote(buildrequests):
- for k,v in buildrequests.iteritems():
- buildrequests[k] = IRemote(v)
- return buildrequests.items()
- d.addCallback(add_remote)
- return d
-
- def remote_isFinished(self):
- return self.b.isFinished()
-
- def remote_waitUntilFinished(self):
- d = self.b.waitUntilFinished()
- d.addCallback(makeRemote)
- return d
-
- def remote_getResults(self):
- return self.b.getResults()
-
-components.registerAdapter(RemoteBuildSet,
- interfaces.IBuildSetStatus, IRemote)
-
-
-class RemoteBuilder(pb.Referenceable):
- def __init__(self, builder):
- self.b = builder
-
- def remote_getName(self):
- return self.b.getName()
-
- def remote_getCategory(self):
- return self.b.getCategory()
-
- def remote_getState(self):
- state, builds = self.b.getState()
- return (state,
- None, # TODO: remove leftover ETA
- [makeRemote(b) for b in builds])
-
- def remote_getSlaves(self):
- return [IRemote(s) for s in self.b.getSlaves()]
-
- def remote_getLastFinishedBuild(self):
- return makeRemote(self.b.getLastFinishedBuild())
-
- def remote_getCurrentBuilds(self):
- return [IRemote(b) for b in self.b.getCurrentBuilds()]
-
- def remote_getBuild(self, number):
- return makeRemote(self.b.getBuild(number))
-
- def remote_getEvent(self, number):
- return IRemote(self.b.getEvent(number))
-
-components.registerAdapter(RemoteBuilder,
- interfaces.IBuilderStatus, IRemote)
-
-
-class RemoteBuildRequest(pb.Referenceable):
- def __init__(self, buildreq):
- self.b = buildreq
- # mapping of observers (RemoteReference instances) to local callable
- # objects that have been passed to BuildRequestStatus.subscribe
- self.observers = []
-
- def remote_getSourceStamp(self):
- # note that this now returns a Deferred
- return self.b.getSourceStamp()
-
- def remote_getBuilderName(self):
- return self.b.getBuilderName()
-
- def remote_subscribe(self, observer):
- """The observer's remote_newbuild method will be called (with two
- arguments: the RemoteBuild object, and our builderName) for each new
- Build that is created to handle this BuildRequest."""
- def send(bs):
- d = observer.callRemote("newbuild",
- IRemote(bs), self.b.getBuilderName())
- d.addErrback(twlog.err,
- "while calling client-side remote_newbuild")
- self.observers.append((observer, send))
- self.b.subscribe(send)
-
- def remote_unsubscribe(self, observer):
- for i, (obs, send) in enumerate(self.observers):
- if obs == observer:
- del self.observers[i]
- self.b.unsubscribe(send)
- break
-
-components.registerAdapter(RemoteBuildRequest,
- interfaces.IBuildRequestStatus, IRemote)
-
-class RemoteBuild(pb.Referenceable):
- def __init__(self, build):
- self.b = build
- self.observers = []
-
- def remote_getBuilderName(self):
- return self.b.getBuilder().getName()
-
- def remote_getNumber(self):
- return self.b.getNumber()
-
- def remote_getReason(self):
- return self.b.getReason()
-
- def remote_getChanges(self):
- return [IRemote(c) for c in self.b.getChanges()]
-
- def remote_getRevisions(self):
- return self.b.getRevisions()
-
- def remote_getResponsibleUsers(self):
- return self.b.getResponsibleUsers()
-
- def remote_getSteps(self):
- return [IRemote(s) for s in self.b.getSteps()]
-
- def remote_getTimes(self):
- return self.b.getTimes()
-
- def remote_isFinished(self):
- return self.b.isFinished()
-
- def remote_waitUntilFinished(self):
- # the Deferred returned by callRemote() will fire when this build is
- # finished
- d = self.b.waitUntilFinished()
- d.addCallback(lambda res: self)
- return d
-
- def remote_getETA(self):
- return self.b.getETA()
-
- def remote_getCurrentStep(self):
- return makeRemote(self.b.getCurrentStep())
-
- def remote_getText(self):
- return self.b.getText()
-
- def remote_getResults(self):
- return self.b.getResults()
-
- def remote_getLogs(self):
- logs = {}
- for name,log in self.b.getLogs().items():
- logs[name] = IRemote(log)
- return logs
-
- def remote_subscribe(self, observer, updateInterval=None):
- """The observer will have remote_stepStarted(buildername, build,
- stepname, step), remote_stepFinished(buildername, build, stepname,
- step, results), and maybe remote_buildETAUpdate(buildername, build,
- eta)) messages sent to it."""
- self.observers.append(observer)
- s = BuildSubscriber(observer)
- self.b.subscribe(s, updateInterval)
-
- def remote_unsubscribe(self, observer):
- # TODO: is the observer automatically unsubscribed when the build
- # finishes? Or are they responsible for unsubscribing themselves
- # anyway? How do we avoid a race condition here?
- for o in self.observers:
- if o == observer:
- self.observers.remove(o)
-
-
-components.registerAdapter(RemoteBuild,
- interfaces.IBuildStatus, IRemote)
-
-class BuildSubscriber:
- def __init__(self, observer):
- self.observer = observer
-
- def buildETAUpdate(self, build, eta):
- self.observer.callRemote("buildETAUpdate",
- build.getBuilder().getName(),
- IRemote(build),
- eta)
-
- def stepStarted(self, build, step):
- self.observer.callRemote("stepStarted",
- build.getBuilder().getName(),
- IRemote(build),
- step.getName(), IRemote(step))
- return None
-
- def stepFinished(self, build, step, results):
- self.observer.callRemote("stepFinished",
- build.getBuilder().getName(),
- IRemote(build),
- step.getName(), IRemote(step),
- results)
-
-
-class RemoteBuildStep(pb.Referenceable):
- def __init__(self, step):
- self.s = step
-
- def remote_getName(self):
- return self.s.getName()
-
- def remote_getBuild(self):
- return IRemote(self.s.getBuild())
-
- def remote_getTimes(self):
- return self.s.getTimes()
-
- def remote_getExpectations(self):
- return self.s.getExpectations()
-
- def remote_getLogs(self):
- logs = {}
- for log in self.s.getLogs():
- logs[log.getName()] = IRemote(log)
- return logs
-
- def remote_isFinished(self):
- return self.s.isFinished()
-
- def remote_waitUntilFinished(self):
- return self.s.waitUntilFinished() # returns a Deferred
-
- def remote_getETA(self):
- return self.s.getETA()
-
- def remote_getText(self):
- return self.s.getText()
-
- def remote_getResults(self):
- return self.s.getResults()
-
-components.registerAdapter(RemoteBuildStep,
- interfaces.IBuildStepStatus, IRemote)
-
-class RemoteSlave:
- def __init__(self, slave):
- self.s = slave
-
- def remote_getName(self):
- return self.s.getName()
- def remote_getAdmin(self):
- return self.s.getAdmin()
- def remote_getHost(self):
- return self.s.getHost()
- def remote_isConnected(self):
- return self.s.isConnected()
-
-components.registerAdapter(RemoteSlave,
- interfaces.ISlaveStatus, IRemote)
-
-class RemoteEvent:
- def __init__(self, event):
- self.e = event
-
- def remote_getTimes(self):
- return self.s.getTimes()
- def remote_getText(self):
- return self.s.getText()
-
-components.registerAdapter(RemoteEvent,
- interfaces.IStatusEvent, IRemote)
-
-class RemoteLog(pb.Referenceable):
- def __init__(self, log):
- self.l = log
-
- def remote_getName(self):
- return self.l.getName()
-
- def remote_isFinished(self):
- return self.l.isFinished()
- def remote_waitUntilFinished(self):
- d = self.l.waitUntilFinished()
- d.addCallback(lambda res: self)
- return d
-
- def remote_getText(self):
- return self.l.getText()
- def remote_getTextWithHeaders(self):
- return self.l.getTextWithHeaders()
- def remote_getChunks(self):
- return self.l.getChunks()
- # TODO: subscription interface
-
-components.registerAdapter(RemoteLog, logfile.LogFile, IRemote)
-# TODO: something similar for builder.HTMLLogfile ?
-
-class RemoteChange:
- def __init__(self, change):
- self.c = change
-
- def getWho(self):
- return self.c.who
- def getFiles(self):
- return self.c.files
- def getComments(self):
- return self.c.comments
-
-components.registerAdapter(RemoteChange, changes.Change, IRemote)
-
-
-class StatusClientPerspective(base.StatusReceiverPerspective):
-
- subscribed = None
- client = None
-
- def __init__(self, status):
- self.status = status # the IStatus
- self.subscribed_to_builders = [] # Builders to which we're subscribed
- self.subscribed_to = [] # everything else we're subscribed to
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['client'] = None
- return d
-
- def attached(self, mind):
- #twlog.msg("StatusClientPerspective.attached")
- return self
-
- def detached(self, mind):
- twlog.msg("PB client detached")
- self.client = None
- for name in self.subscribed_to_builders:
- twlog.msg(" unsubscribing from Builder(%s)" % name)
- self.status.getBuilder(name).unsubscribe(self)
- for s in self.subscribed_to:
- twlog.msg(" unsubscribe from %s" % s)
- s.unsubscribe(self)
- self.subscribed = None
-
- def perspective_subscribe(self, mode, interval, target):
- """The remote client wishes to subscribe to some set of events.
- 'target' will be sent remote messages when these events happen.
- 'mode' indicates which events are desired: it is a string with one
- of the following values:
-
- 'builders': builderAdded, builderRemoved
- 'builds': those plus builderChangedState, buildStarted, buildFinished
- 'steps': all those plus buildETAUpdate, stepStarted, stepFinished
- 'logs': all those plus stepETAUpdate, logStarted, logFinished
- 'full': all those plus logChunk (with the log contents)
-
-
- Messages are defined by buildbot.interfaces.IStatusReceiver .
- 'interval' is used to specify how frequently ETAUpdate messages
- should be sent.
-
- Raising or lowering the subscription level will take effect starting
- with the next build or step."""
-
- assert mode in ("builders", "builds", "steps", "logs", "full")
- assert target
- twlog.msg("PB subscribe(%s)" % mode)
-
- self.client = target
- self.subscribed = mode
- self.interval = interval
- self.subscribed_to.append(self.status)
- # wait a moment before subscribing, so the new-builder messages
- # won't appear before this remote method finishes
- eventually(self.status.subscribe, self)
- return None
-
- def perspective_unsubscribe(self):
- twlog.msg("PB unsubscribe")
- self.status.unsubscribe(self)
- self.subscribed_to.remove(self.status)
- self.client = None
-
- def perspective_getBuildSets(self):
- """This returns tuples of (buildset, bsid), because that is much more
- convenient for tryclient."""
- d = self.status.getBuildSets()
- def make_remotes(buildsets):
- return [(IRemote(s), s.id) for s in buildsets]
- d.addCallback(make_remotes)
- return d
-
- def perspective_getBuilderNames(self):
- return self.status.getBuilderNames()
-
- def perspective_getBuilder(self, name):
- b = self.status.getBuilder(name)
- return IRemote(b)
-
- def perspective_getSlave(self, name):
- s = self.status.getSlave(name)
- return IRemote(s)
-
- def perspective_ping(self):
- """Ping method to allow pb clients to validate their connections."""
- return "pong"
-
- # IStatusReceiver methods, invoked if we've subscribed
-
- # mode >= builder
- def builderAdded(self, name, builder):
- self.client.callRemote("builderAdded", name, IRemote(builder))
- if self.subscribed in ("builds", "steps", "logs", "full"):
- self.subscribed_to_builders.append(name)
- return self
- return None
-
- def builderChangedState(self, name, state):
- self.client.callRemote("builderChangedState", name, state, None)
- # TODO: remove leftover ETA argument
-
- def builderRemoved(self, name):
- if name in self.subscribed_to_builders:
- self.subscribed_to_builders.remove(name)
- self.client.callRemote("builderRemoved", name)
-
- def buildsetSubmitted(self, buildset):
- # TODO: deliver to client, somehow
- pass
-
- # mode >= builds
- def buildStarted(self, name, build):
- self.client.callRemote("buildStarted", name, IRemote(build))
- if self.subscribed in ("steps", "logs", "full"):
- self.subscribed_to.append(build)
- return (self, self.interval)
- return None
-
- def buildFinished(self, name, build, results):
- if build in self.subscribed_to:
- # we might have joined during the build
- self.subscribed_to.remove(build)
- self.client.callRemote("buildFinished",
- name, IRemote(build), results)
-
- # mode >= steps
- def buildETAUpdate(self, build, eta):
- self.client.callRemote("buildETAUpdate",
- build.getBuilder().getName(), IRemote(build),
- eta)
-
- def stepStarted(self, build, step):
- # we add some information here so the client doesn't have to do an
- # extra round-trip
- self.client.callRemote("stepStarted",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step))
- if self.subscribed in ("logs", "full"):
- self.subscribed_to.append(step)
- return (self, self.interval)
- return None
-
- def stepFinished(self, build, step, results):
- self.client.callRemote("stepFinished",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- results)
- if step in self.subscribed_to:
- # eventually (through some new subscription method) we could
- # join in the middle of the step
- self.subscribed_to.remove(step)
-
- # mode >= logs
- def stepETAUpdate(self, build, step, ETA, expectations):
- self.client.callRemote("stepETAUpdate",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- ETA, expectations)
-
- def logStarted(self, build, step, log):
- # TODO: make the HTMLLog adapter
- rlog = IRemote(log, None)
- if not rlog:
- print "hey, couldn't adapt %s to IRemote" % log
- self.client.callRemote("logStarted",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- log.getName(), IRemote(log, None))
- if self.subscribed in ("full",):
- self.subscribed_to.append(log)
- return self
- return None
-
- def logFinished(self, build, step, log):
- self.client.callRemote("logFinished",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- log.getName(), IRemote(log, None))
- if log in self.subscribed_to:
- self.subscribed_to.remove(log)
-
- # mode >= full
- def logChunk(self, build, step, log, channel, text):
- self.client.callRemote("logChunk",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- log.getName(), IRemote(log),
- channel, text)
-
-
-class PBListener(base.StatusReceiverMultiService):
- """I am a listener for PB-based status clients."""
-
- compare_attrs = ["port", "cred"]
- implements(portal.IRealm)
-
- def __init__(self, port, user="statusClient", passwd="clientpw"):
- base.StatusReceiverMultiService.__init__(self)
- if type(port) is int:
- port = "tcp:%d" % port
- self.port = port
- self.cred = (user, passwd)
- p = portal.Portal(self)
- c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser(user, passwd)
- p.registerChecker(c)
- f = pb.PBServerFactory(p)
- s = strports.service(port, f)
- s.setServiceParent(self)
-
- def setServiceParent(self, parent):
- base.StatusReceiverMultiService.setServiceParent(self, parent)
- self.status = parent
-
- def requestAvatar(self, avatarID, mind, interface):
- assert interface == pb.IPerspective
- p = StatusClientPerspective(self.status)
- p.attached(mind) # perhaps .callLater(0) ?
- return (pb.IPerspective, p,
- lambda p=p,mind=mind: p.detached(mind))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py
deleted file mode 100644
index 8e072931..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from buildbot import interfaces, util
-
-class Event:
- implements(interfaces.IStatusEvent)
-
- started = None
- finished = None
- text = []
-
- # IStatusEvent methods
- def getTimes(self):
- return (self.started, self.finished)
- def getText(self):
- return self.text
- def getLogs(self):
- return []
-
- def finish(self):
- self.finished = util.now()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py
deleted file mode 100644
index a0fc5755..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-# compatibility wrapper. This is currently the preferred place for master.cfg
-# to import from.
-
-from buildbot.status.web.baseweb import WebStatus
-_hush_pyflakes = [WebStatus]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py
deleted file mode 100644
index bd1d686d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py
+++ /dev/null
@@ -1,699 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from cStringIO import StringIO
-from bz2 import BZ2File
-from gzip import GzipFile
-
-from zope.interface import implements
-from twisted.python import log, runtime
-from twisted.internet import defer, threads, reactor
-from buildbot.util import netstrings
-from buildbot.util.eventual import eventually
-from buildbot import interfaces
-
-STDOUT = interfaces.LOG_CHANNEL_STDOUT
-STDERR = interfaces.LOG_CHANNEL_STDERR
-HEADER = interfaces.LOG_CHANNEL_HEADER
-ChunkTypes = ["stdout", "stderr", "header"]
-
-class LogFileScanner(netstrings.NetstringParser):
- def __init__(self, chunk_cb, channels=[]):
- self.chunk_cb = chunk_cb
- self.channels = channels
- netstrings.NetstringParser.__init__(self)
-
- def stringReceived(self, line):
- channel = int(line[0])
- if not self.channels or (channel in self.channels):
- self.chunk_cb((channel, line[1:]))
-
-class LogFileProducer:
- """What's the plan?
-
- the LogFile has just one FD, used for both reading and writing.
- Each time you add an entry, fd.seek to the end and then write.
-
- Each reader (i.e. Producer) keeps track of their own offset. The reader
- starts by seeking to the start of the logfile, and reading forwards.
- Between each hunk of file they yield chunks, so they must remember their
- offset before yielding and re-seek back to that offset before reading
- more data. When their read() returns EOF, they're finished with the first
- phase of the reading (everything that's already been written to disk).
-
- After EOF, the remaining data is entirely in the current entries list.
- These entries are all of the same channel, so we can do one "".join and
- obtain a single chunk to be sent to the listener. But since that involves
- a yield, and more data might arrive after we give up control, we have to
- subscribe them before yielding. We can't subscribe them any earlier,
- otherwise they'd get data out of order.
-
- We're using a generator in the first place so that the listener can
- throttle us, which means they're pulling. But the subscription means
- we're pushing. Really we're a Producer. In the first phase we can be
- either a PullProducer or a PushProducer. In the second phase we're only a
- PushProducer.
-
- So the client gives a LogFileConsumer to File.subscribeConsumer . This
- Consumer must have registerProducer(), unregisterProducer(), and
- writeChunk(), and is just like a regular twisted.interfaces.IConsumer,
- except that writeChunk() takes chunks (tuples of (channel,text)) instead
- of the normal write() which takes just text. The LogFileConsumer is
- allowed to call stopProducing, pauseProducing, and resumeProducing on the
- producer instance it is given. """
-
- paused = False
- subscribed = False
- BUFFERSIZE = 2048
-
- def __init__(self, logfile, consumer):
- self.logfile = logfile
- self.consumer = consumer
- self.chunkGenerator = self.getChunks()
- consumer.registerProducer(self, True)
-
- def getChunks(self):
- f = self.logfile.getFile()
- offset = 0
- chunks = []
- p = LogFileScanner(chunks.append)
- f.seek(offset)
- data = f.read(self.BUFFERSIZE)
- offset = f.tell()
- while data:
- p.dataReceived(data)
- while chunks:
- yield chunks.pop(0)
- f.seek(offset)
- data = f.read(self.BUFFERSIZE)
- offset = f.tell()
- del f
-
- # now subscribe them to receive new entries
- self.subscribed = True
- self.logfile.watchers.append(self)
- d = self.logfile.waitUntilFinished()
-
- # then give them the not-yet-merged data
- if self.logfile.runEntries:
- channel = self.logfile.runEntries[0][0]
- text = "".join([c[1] for c in self.logfile.runEntries])
- yield (channel, text)
-
- # now we've caught up to the present. Anything further will come from
- # the logfile subscription. We add the callback *after* yielding the
- # data from runEntries, because the logfile might have finished
- # during the yield.
- d.addCallback(self.logfileFinished)
-
- def stopProducing(self):
- # TODO: should we still call consumer.finish? probably not.
- self.paused = True
- self.consumer = None
- self.done()
-
- def done(self):
- if self.chunkGenerator:
- self.chunkGenerator = None # stop making chunks
- if self.subscribed:
- self.logfile.watchers.remove(self)
- self.subscribed = False
-
- def pauseProducing(self):
- self.paused = True
-
- def resumeProducing(self):
- # Twisted-1.3.0 has a bug which causes hangs when resumeProducing
- # calls transport.write (there is a recursive loop, fixed in 2.0 in
- # t.i.abstract.FileDescriptor.doWrite by setting the producerPaused
- # flag *before* calling resumeProducing). To work around this, we
- # just put off the real resumeProducing for a moment. This probably
- # has a performance hit, but I'm going to assume that the log files
- # are not retrieved frequently enough for it to be an issue.
-
- eventually(self._resumeProducing)
-
- def _resumeProducing(self):
- self.paused = False
- if not self.chunkGenerator:
- return
- try:
- while not self.paused:
- chunk = self.chunkGenerator.next()
- self.consumer.writeChunk(chunk)
- # we exit this when the consumer says to stop, or we run out
- # of chunks
- except StopIteration:
- # if the generator finished, it will have done releaseFile
- self.chunkGenerator = None
- # now everything goes through the subscription, and they don't get to
- # pause anymore
-
- def logChunk(self, build, step, logfile, channel, chunk):
- if self.consumer:
- self.consumer.writeChunk((channel, chunk))
-
- def logfileFinished(self, logfile):
- self.done()
- if self.consumer:
- self.consumer.unregisterProducer()
- self.consumer.finish()
- self.consumer = None
-
-class LogFile:
- """
- A LogFile keeps all of its contents on disk, in a non-pickle format to
- which new entries can easily be appended. The file on disk has a name like
- 12-log-compile-output, under the Builder's directory. The actual filename
- is generated (before the LogFile is created) by
- L{BuildStatus.generateLogfileName}.
-
- @ivar length: length of the data in the logfile (sum of chunk sizes; not
- the length of the on-disk encoding)
- """
-
- implements(interfaces.IStatusLog, interfaces.ILogFile)
-
- finished = False
- length = 0
- nonHeaderLength = 0
- tailLength = 0
- chunkSize = 10*1000
- runLength = 0
- # No max size by default
- # Don't keep a tail buffer by default
- logMaxTailSize = None
- maxLengthExceeded = False
- runEntries = [] # provided so old pickled builds will getChunks() ok
- entries = None
- BUFFERSIZE = 2048
- filename = None # relative to the Builder's basedir
- openfile = None
-
- def __init__(self, parent, name, logfilename):
- """
- @type parent: L{BuildStepStatus}
- @param parent: the Step that this log is a part of
- @type name: string
- @param name: the name of this log, typically 'output'
- @type logfilename: string
- @param logfilename: the Builder-relative pathname for the saved entries
- """
- self.step = parent
- self.master = parent.build.builder.master
- self.name = name
- self.filename = logfilename
- fn = self.getFilename()
- if os.path.exists(fn):
- # the buildmaster was probably stopped abruptly, before the
- # BuilderStatus could be saved, so BuilderStatus.nextBuildNumber
- # is out of date, and we're overlapping with earlier builds now.
- # Warn about it, but then overwrite the old pickle file
- log.msg("Warning: Overwriting old serialized Build at %s" % fn)
- dirname = os.path.dirname(fn)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
- self.openfile = open(fn, "w+")
- self.runEntries = []
- self.watchers = []
- self.finishedWatchers = []
- self.tailBuffer = []
-
- def getFilename(self):
- """
- Get the base (uncompressed) filename for this log file.
-
- @returns: filename
- """
- return os.path.join(self.step.build.builder.basedir, self.filename)
-
- def hasContents(self):
- """
- Return true if this logfile's contents are available. For a newly
- created logfile, this is always true, but for a L{LogFile} instance
- that has been persisted, the logfiles themselves may have been deleted,
- in which case this method will return False.
-
- @returns: boolean
- """
- return os.path.exists(self.getFilename() + '.bz2') or \
- os.path.exists(self.getFilename() + '.gz') or \
- os.path.exists(self.getFilename())
-
- def getName(self):
- """
- Get this logfile's name
-
- @returns: string
- """
- return self.name
-
- def getStep(self):
- """
- Get the L{BuildStepStatus} instance containing this logfile
-
- @returns: L{BuildStepStatus} instance
- """
- return self.step
-
- def isFinished(self):
- """
- Return true if this logfile is finished (that is, if it will not
- receive any additional data
-
- @returns: boolean
- """
-
- return self.finished
-
- def waitUntilFinished(self):
- """
- Return a Deferred that will fire when this logfile is finished, or will
- fire immediately if the logfile is already finished.
- """
- if self.finished:
- d = defer.succeed(self)
- else:
- d = defer.Deferred()
- self.finishedWatchers.append(d)
- return d
-
- def getFile(self):
- """
- Get an open file object for this log. The file may also be in use for
- writing, so it should not be closed by the caller, and the caller
- should not rely on its file position remaining constant between
- asynchronous code segments.
-
- @returns: file object
- """
- if self.openfile:
- # this is the filehandle we're using to write to the log, so
- # don't close it!
- return self.openfile
- # otherwise they get their own read-only handle
- # try a compressed log first
- try:
- return BZ2File(self.getFilename() + ".bz2", "r")
- except IOError:
- pass
- try:
- return GzipFile(self.getFilename() + ".gz", "r")
- except IOError:
- pass
- return open(self.getFilename(), "r")
-
- def getText(self):
- # this produces one ginormous string
- return "".join(self.getChunks([STDOUT, STDERR], onlyText=True))
-
- def getTextWithHeaders(self):
- return "".join(self.getChunks(onlyText=True))
-
- def getChunks(self, channels=[], onlyText=False):
- # generate chunks for everything that was logged at the time we were
- # first called, so remember how long the file was when we started.
- # Don't read beyond that point. The current contents of
- # self.runEntries will follow.
-
- # this returns an iterator, which means arbitrary things could happen
- # while we're yielding. This will faithfully deliver the log as it
- # existed when it was started, and not return anything after that
- # point. To use this in subscribe(catchup=True) without missing any
- # data, you must insure that nothing will be added to the log during
- # yield() calls.
-
- f = self.getFile()
- if not self.finished:
- offset = 0
- f.seek(0, 2)
- remaining = f.tell()
- else:
- offset = 0
- remaining = None
-
- leftover = None
- if self.runEntries and (not channels or
- (self.runEntries[0][0] in channels)):
- leftover = (self.runEntries[0][0],
- "".join([c[1] for c in self.runEntries]))
-
- # freeze the state of the LogFile by passing a lot of parameters into
- # a generator
- return self._generateChunks(f, offset, remaining, leftover,
- channels, onlyText)
-
- def _generateChunks(self, f, offset, remaining, leftover,
- channels, onlyText):
- chunks = []
- p = LogFileScanner(chunks.append, channels)
- f.seek(offset)
- if remaining is not None:
- data = f.read(min(remaining, self.BUFFERSIZE))
- remaining -= len(data)
- else:
- data = f.read(self.BUFFERSIZE)
-
- offset = f.tell()
- while data:
- p.dataReceived(data)
- while chunks:
- channel, text = chunks.pop(0)
- if onlyText:
- yield text
- else:
- yield (channel, text)
- f.seek(offset)
- if remaining is not None:
- data = f.read(min(remaining, self.BUFFERSIZE))
- remaining -= len(data)
- else:
- data = f.read(self.BUFFERSIZE)
- offset = f.tell()
- del f
-
- if leftover:
- if onlyText:
- yield leftover[1]
- else:
- yield leftover
-
- def readlines(self):
- """Return an iterator that produces newline-terminated lines,
- excluding header chunks."""
- alltext = "".join(self.getChunks([STDOUT], onlyText=True))
- io = StringIO(alltext)
- return io.readlines()
-
- def subscribe(self, receiver, catchup):
- if self.finished:
- return
- self.watchers.append(receiver)
- if catchup:
- for channel, text in self.getChunks():
- # TODO: add logChunks(), to send over everything at once?
- receiver.logChunk(self.step.build, self.step, self,
- channel, text)
-
- def unsubscribe(self, receiver):
- if receiver in self.watchers:
- self.watchers.remove(receiver)
-
- def subscribeConsumer(self, consumer):
- p = LogFileProducer(self, consumer)
- p.resumeProducing()
-
- # interface used by the build steps to add things to the log
-
- def _merge(self):
- # merge all .runEntries (which are all of the same type) into a
- # single chunk for .entries
- if not self.runEntries:
- return
- channel = self.runEntries[0][0]
- text = "".join([c[1] for c in self.runEntries])
- assert channel < 10, "channel number must be a single decimal digit"
- f = self.openfile
- f.seek(0, 2)
- offset = 0
- while offset < len(text):
- size = min(len(text)-offset, self.chunkSize)
- f.write("%d:%d" % (1 + size, channel))
- f.write(text[offset:offset+size])
- f.write(",")
- offset += size
- self.runEntries = []
- self.runLength = 0
-
- def addEntry(self, channel, text, _no_watchers=False):
- """
- Add an entry to the logfile. The C{channel} is one of L{STDOUT},
- L{STDERR}, or L{HEADER}. The C{text} is the text to add to the
- logfile, which can be a unicode string or a bytestring which is
- presumed to be encoded with utf-8.
-
- This method cannot be called after the logfile is finished.
-
- @param channel: channel to add a chunk for
- @param text: chunk of text
- @param _no_watchers: private
- """
-
- assert not self.finished, "logfile is already finished"
-
- if isinstance(text, unicode):
- text = text.encode('utf-8')
-
- # notify watchers first, before the chunk gets munged, so that they get
- # a complete picture of the actual log output
- # TODO: is this right, or should the watchers get a picture of the chunks?
- if not _no_watchers:
- for w in self.watchers:
- w.logChunk(self.step.build, self.step, self, channel, text)
-
- if channel != HEADER:
- # Truncate the log if it's more than logMaxSize bytes
- logMaxSize = self.master.config.logMaxSize
- logMaxTailSize = self.master.config.logMaxTailSize
- if logMaxSize:
- self.nonHeaderLength += len(text)
- if self.nonHeaderLength > logMaxSize:
- # Add a message about what's going on and truncate this
- # chunk if necessary
- if not self.maxLengthExceeded:
- if self.runEntries and channel != self.runEntries[0][0]:
- self._merge()
- i = -(self.nonHeaderLength - logMaxSize)
- trunc, text = text[:i], text[i:]
- self.runEntries.append((channel, trunc))
- self._merge()
- msg = ("\nOutput exceeded %i bytes, remaining output "
- "has been truncated\n" % logMaxSize)
- self.runEntries.append((HEADER, msg))
- self.maxLengthExceeded = True
-
- # and track the tail of the text
- if logMaxTailSize and text:
- # Update the tail buffer
- self.tailBuffer.append((channel, text))
- self.tailLength += len(text)
- while self.tailLength > logMaxTailSize:
- # Drop some stuff off the beginning of the buffer
- c,t = self.tailBuffer.pop(0)
- n = len(t)
- self.tailLength -= n
- assert self.tailLength >= 0
- return
-
- # we only add to .runEntries here. _merge() is responsible for adding
- # merged chunks to .entries
- if self.runEntries and channel != self.runEntries[0][0]:
- self._merge()
- self.runEntries.append((channel, text))
- self.runLength += len(text)
- if self.runLength >= self.chunkSize:
- self._merge()
-
- self.length += len(text)
-
- def addStdout(self, text):
- """
- Shortcut to add stdout text to the logfile
-
- @param text: text to add to the logfile
- """
- self.addEntry(STDOUT, text)
-
- def addStderr(self, text):
- """
- Shortcut to add stderr text to the logfile
-
- @param text: text to add to the logfile
- """
- self.addEntry(STDERR, text)
-
- def addHeader(self, text):
- """
- Shortcut to add header text to the logfile
-
- @param text: text to add to the logfile
- """
- self.addEntry(HEADER, text)
-
- def finish(self):
- """
- Finish the logfile, flushing any buffers and preventing any further
- writes to the log.
- """
- self._merge()
- if self.tailBuffer:
- msg = "\nFinal %i bytes follow below:\n" % self.tailLength
- tmp = self.runEntries
- self.runEntries = [(HEADER, msg)]
- self._merge()
- self.runEntries = self.tailBuffer
- self._merge()
- self.runEntries = tmp
- self._merge()
- self.tailBuffer = []
-
- if self.openfile:
- # we don't do an explicit close, because there might be readers
- # shareing the filehandle. As soon as they stop reading, the
- # filehandle will be released and automatically closed.
- self.openfile.flush()
- self.openfile = None
- self.finished = True
- watchers = self.finishedWatchers
- self.finishedWatchers = []
- for w in watchers:
- w.callback(self)
- self.watchers = []
-
-
- def compressLog(self):
- logCompressionMethod = self.master.config.logCompressionMethod
- # bail out if there's no compression support
- if logCompressionMethod == "bz2":
- compressed = self.getFilename() + ".bz2.tmp"
- elif logCompressionMethod == "gz":
- compressed = self.getFilename() + ".gz.tmp"
- else:
- return defer.succeed(None)
-
- def _compressLog():
- infile = self.getFile()
- if logCompressionMethod == "bz2":
- cf = BZ2File(compressed, 'w')
- elif logCompressionMethod == "gz":
- cf = GzipFile(compressed, 'w')
- bufsize = 1024*1024
- while True:
- buf = infile.read(bufsize)
- cf.write(buf)
- if len(buf) < bufsize:
- break
- cf.close()
- d = threads.deferToThread(_compressLog)
-
- def _renameCompressedLog(rv):
- if logCompressionMethod == "bz2":
- filename = self.getFilename() + '.bz2'
- else:
- filename = self.getFilename() + '.gz'
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one, so
- # fall back to delete-first. There are ways this can fail and
- # lose the builder's history, so we avoid using it in the
- # general (non-windows) case
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(compressed, filename)
- _tryremove(self.getFilename(), 1, 5)
- d.addCallback(_renameCompressedLog)
-
- def _cleanupFailedCompress(failure):
- log.msg("failed to compress %s" % self.getFilename())
- if os.path.exists(compressed):
- _tryremove(compressed, 1, 5)
- failure.trap() # reraise the failure
- d.addErrback(_cleanupFailedCompress)
- return d
-
-
- # persistence stuff
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['step'] # filled in upon unpickling
- del d['watchers']
- del d['finishedWatchers']
- del d['master']
- d['entries'] = [] # let 0.6.4 tolerate the saved log. TODO: really?
- if d.has_key('finished'):
- del d['finished']
- if d.has_key('openfile'):
- del d['openfile']
- return d
-
- def __setstate__(self, d):
- self.__dict__ = d
- self.watchers = [] # probably not necessary
- self.finishedWatchers = [] # same
- # self.step must be filled in by our parent
- self.finished = True
-
-class HTMLLogFile:
- implements(interfaces.IStatusLog)
-
- filename = None
-
- def __init__(self, parent, name, logfilename, html):
- self.step = parent
- self.name = name
- self.filename = logfilename
- self.html = html
-
- def getName(self):
- return self.name # set in BuildStepStatus.addLog
- def getStep(self):
- return self.step
-
- def isFinished(self):
- return True
- def waitUntilFinished(self):
- return defer.succeed(self)
-
- def hasContents(self):
- return True
- def getText(self):
- return self.html # looks kinda like text
- def getTextWithHeaders(self):
- return self.html
- def getChunks(self):
- return [(STDERR, self.html)]
-
- def subscribe(self, receiver, catchup):
- pass
- def unsubscribe(self, receiver):
- pass
-
- def finish(self):
- pass
-
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['step']
- if d.has_key('master'):
- del d['master']
- return d
-
-
-def _tryremove(filename, timeout, retries):
- """Try to remove a file, and if failed, try again in timeout.
- Increases the timeout by a factor of 4, and only keeps trying for
- another retries-amount of times.
-
- """
- try:
- os.unlink(filename)
- except OSError:
- if retries > 0:
- reactor.callLater(timeout, _tryremove, filename, timeout * 4,
- retries - 1)
- else:
- log.msg("giving up on removing %s after over %d seconds" %
- (filename, timeout))
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py
deleted file mode 100644
index ef48d8e2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py
+++ /dev/null
@@ -1,798 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import re
-import types
-from email.Message import Message
-from email.Utils import formatdate
-from email.MIMEText import MIMEText
-from email.MIMENonMultipart import MIMENonMultipart
-from email.MIMEMultipart import MIMEMultipart
-from StringIO import StringIO
-import urllib
-
-from zope.interface import implements
-from twisted.internet import defer, reactor
-from twisted.python import log as twlog
-
-try:
- from twisted.mail.smtp import ESMTPSenderFactory
- ESMTPSenderFactory = ESMTPSenderFactory # for pyflakes
-except ImportError:
- ESMTPSenderFactory = None
-
-have_ssl = True
-try:
- from twisted.internet import ssl
- from OpenSSL.SSL import SSLv3_METHOD
-except ImportError:
- have_ssl = False
-
-# this incantation teaches email to output utf-8 using 7- or 8-bit encoding,
-# although it has no effect before python-2.7.
-from email import Charset
-Charset.add_charset('utf-8', Charset.SHORTEST, None, 'utf-8')
-
-from buildbot import interfaces, util, config
-from buildbot.process.users import users
-from buildbot.status import base
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, EXCEPTION, Results
-
-VALID_EMAIL = re.compile("[a-zA-Z0-9\.\_\%\-\+]+@[a-zA-Z0-9\.\_\%\-]+.[a-zA-Z]{2,6}")
-
-ENCODING = 'utf8'
-LOG_ENCODING = 'utf-8'
-
-class Domain(util.ComparableMixin):
- implements(interfaces.IEmailLookup)
- compare_attrs = ["domain"]
-
- def __init__(self, domain):
- assert "@" not in domain
- self.domain = domain
-
- def getAddress(self, name):
- """If name is already an email address, pass it through."""
- if '@' in name:
- return name
- return name + "@" + self.domain
-
-
-def defaultMessage(mode, name, build, results, master_status):
- """Generate a buildbot mail message and return a tuple of message text
- and type."""
- ss_list = build.getSourceStamps()
-
- prev = build.getPreviousBuild()
-
- text = ""
- if results == FAILURE:
- if "change" in mode and prev and prev.getResults() != results or \
- "problem" in mode and prev and prev.getResults() != FAILURE:
- text += "The Buildbot has detected a new failure"
- else:
- text += "The Buildbot has detected a failed build"
- elif results == WARNINGS:
- text += "The Buildbot has detected a problem in the build"
- elif results == SUCCESS:
- if "change" in mode and prev and prev.getResults() != results:
- text += "The Buildbot has detected a restored build"
- else:
- text += "The Buildbot has detected a passing build"
- elif results == EXCEPTION:
- text += "The Buildbot has detected a build exception"
-
- projects = []
- if ss_list:
- for ss in ss_list:
- if ss.project and ss.project not in projects:
- projects.append(ss.project)
- if not projects:
- projects = [master_status.getTitle()]
- text += " on builder %s while building %s.\n" % (name, ', '.join(projects))
-
- if master_status.getURLForThing(build):
- text += "Full details are available at:\n %s\n" % master_status.getURLForThing(build)
- text += "\n"
-
- if master_status.getBuildbotURL():
- text += "Buildbot URL: %s\n\n" % urllib.quote(master_status.getBuildbotURL(), '/:')
-
- text += "Buildslave for this Build: %s\n\n" % build.getSlavename()
- text += "Build Reason: %s\n" % build.getReason()
-
- for ss in ss_list:
- source = ""
- if ss and ss.branch:
- source += "[branch %s] " % ss.branch
- if ss and ss.revision:
- source += str(ss.revision)
- else:
- source += "HEAD"
- if ss and ss.patch:
- source += " (plus patch)"
-
- discriminator = ""
- if ss.codebase:
- discriminator = " '%s'" % ss.codebase
- text += "Build Source Stamp%s: %s\n" % (discriminator, source)
-
- text += "Blamelist: %s\n" % ",".join(build.getResponsibleUsers())
-
- text += "\n"
-
- t = build.getText()
- if t:
- t = ": " + " ".join(t)
- else:
- t = ""
-
- if results == SUCCESS:
- text += "Build succeeded!\n"
- elif results == WARNINGS:
- text += "Build Had Warnings%s\n" % t
- else:
- text += "BUILD FAILED%s\n" % t
-
- text += "\n"
- text += "sincerely,\n"
- text += " -The Buildbot\n"
- text += "\n"
- return { 'body' : text, 'type' : 'plain' }
-
-def defaultGetPreviousBuild(current_build):
- return current_build.getPreviousBuild()
-
-class MailNotifier(base.StatusReceiverMultiService):
- """This is a status notifier which sends email to a list of recipients
- upon the completion of each build. It can be configured to only send out
- mail for certain builds, and only send messages when the build fails, or
- when it transitions from success to failure. It can also be configured to
- include various build logs in each message.
-
- By default, the message will be sent to the Interested Users list, which
- includes all developers who made changes in the build. You can add
- additional recipients with the extraRecipients argument.
-
- To get a simple one-message-per-build (say, for a mailing list), use
- sendToInterestedUsers=False, extraRecipients=['listaddr@example.org']
-
- Each MailNotifier sends mail to a single set of recipients. To send
- different kinds of mail to different recipients, use multiple
- MailNotifiers.
- """
-
- implements(interfaces.IEmailSender)
-
- compare_attrs = ["extraRecipients", "lookup", "fromaddr", "mode",
- "categories", "builders", "addLogs", "relayhost",
- "subject", "sendToInterestedUsers", "customMesg",
- "messageFormatter", "extraHeaders"]
-
- possible_modes = ("change", "failing", "passing", "problem", "warnings", "exception")
-
- def __init__(self, fromaddr, mode=("failing", "passing", "warnings"),
- categories=None, builders=None, addLogs=False,
- relayhost="localhost", buildSetSummary=False,
- subject="buildbot %(result)s in %(title)s on %(builder)s",
- lookup=None, extraRecipients=[],
- sendToInterestedUsers=True, customMesg=None,
- messageFormatter=defaultMessage, extraHeaders=None,
- addPatch=True, useTls=False,
- smtpUser=None, smtpPassword=None, smtpPort=25,
- previousBuildGetter=defaultGetPreviousBuild):
- """
- @type fromaddr: string
- @param fromaddr: the email address to be used in the 'From' header.
- @type sendToInterestedUsers: boolean
- @param sendToInterestedUsers: if True (the default), send mail to all
- of the Interested Users. If False, only
- send mail to the extraRecipients list.
-
- @type extraRecipients: tuple of strings
- @param extraRecipients: a list of email addresses to which messages
- should be sent (in addition to the
- InterestedUsers list, which includes any
- developers who made Changes that went into this
- build). It is a good idea to create a small
- mailing list and deliver to that, then let
- subscribers come and go as they please. The
- addresses in this list are used literally (they
- are not processed by lookup).
-
- @type subject: string
- @param subject: a string to be used as the subject line of the message.
- %(builder)s will be replaced with the name of the
- builder which provoked the message.
-
- @type mode: list of strings
- @param mode: a list of MailNotifer.possible_modes:
- - "change": send mail about builds which change status
- - "failing": send mail about builds which fail
- - "passing": send mail about builds which succeed
- - "problem": send mail about a build which failed
- when the previous build passed
- - "warnings": send mail if a build contain warnings
- - "exception": send mail if a build fails due to an exception
- - "all": always send mail
- Defaults to ("failing", "passing", "warnings").
-
- @type builders: list of strings
- @param builders: a list of builder names for which mail should be
- sent. Defaults to None (send mail for all builds).
- Use either builders or categories, but not both.
-
- @type categories: list of strings
- @param categories: a list of category names to serve status
- information for. Defaults to None (all
- categories). Use either builders or categories,
- but not both.
-
- @type addLogs: boolean
- @param addLogs: if True, include all build logs as attachments to the
- messages. These can be quite large. This can also be
- set to a list of log names, to send a subset of the
- logs. Defaults to False.
-
- @type addPatch: boolean
- @param addPatch: if True, include the patch when the source stamp
- includes one.
-
- @type relayhost: string
- @param relayhost: the host to which the outbound SMTP connection
- should be made. Defaults to 'localhost'
-
- @type buildSetSummary: boolean
- @param buildSetSummary: if True, this notifier will only send a summary
- email when a buildset containing any of its
- watched builds completes
-
- @type lookup: implementor of {IEmailLookup}
- @param lookup: object which provides IEmailLookup, which is
- responsible for mapping User names for Interested
- Users (which come from the VC system) into valid
- email addresses. If not provided, the notifier will
- only be able to send mail to the addresses in the
- extraRecipients list. Most of the time you can use a
- simple Domain instance. As a shortcut, you can pass
- as string: this will be treated as if you had provided
- Domain(str). For example, lookup='twistedmatrix.com'
- will allow mail to be sent to all developers whose SVN
- usernames match their twistedmatrix.com account names.
-
- @type customMesg: func
- @param customMesg: (this function is deprecated)
-
- @type messageFormatter: func
- @param messageFormatter: function taking (mode, name, build, result,
- master_status) and returning a dictionary
- containing two required keys "body" and "type",
- with a third optional key, "subject". The
- "body" key gives a string that contains the
- complete text of the message. The "type" key
- is the message type ('plain' or 'html'). The
- 'html' type should be used when generating an
- HTML message. The optional "subject" key
- gives the subject for the email.
-
- @type extraHeaders: dict
- @param extraHeaders: A dict of extra headers to add to the mail. It's
- best to avoid putting 'To', 'From', 'Date',
- 'Subject', or 'CC' in here. Both the names and
- values may be WithProperties instances.
-
- @type useTls: boolean
- @param useTls: Send emails using TLS and authenticate with the
- smtp host. Defaults to False.
-
- @type smtpUser: string
- @param smtpUser: The user that will attempt to authenticate with the
- relayhost when useTls is True.
-
- @type smtpPassword: string
- @param smtpPassword: The password that smtpUser will use when
- authenticating with relayhost.
-
- @type smtpPort: int
- @param smtpPort: The port that will be used when connecting to the
- relayhost. Defaults to 25.
-
- @type previousBuildGetter: func
- @param previousBuildGetter: function taking a BuildStatus instance
- returning a BuildStatus of the build
- previous to the one passed in. This allows
- to implement a relative ordering between
- builds other than the default one, which is
- chronological.
- """
- base.StatusReceiverMultiService.__init__(self)
-
- if not isinstance(extraRecipients, (list, tuple)):
- config.error("extraRecipients must be a list or tuple")
- else:
- for r in extraRecipients:
- if not isinstance(r, str) or not VALID_EMAIL.search(r):
- config.error(
- "extra recipient %r is not a valid email" % (r,))
- self.extraRecipients = extraRecipients
- self.sendToInterestedUsers = sendToInterestedUsers
- self.fromaddr = fromaddr
- if isinstance(mode, basestring):
- if mode == "all":
- mode = ("failing", "passing", "warnings", "exception")
- elif mode == "warnings":
- mode = ("failing", "warnings")
- else:
- mode = (mode,)
- for m in mode:
- if m not in self.possible_modes:
- config.error(
- "mode %s is not a valid mode" % (m,))
- self.mode = mode
- self.categories = categories
- self.builders = builders
- self.addLogs = addLogs
- self.relayhost = relayhost
- if '\n' in subject:
- config.error(
- 'Newlines are not allowed in email subjects')
- self.subject = subject
- if lookup is not None:
- if type(lookup) is str:
- lookup = Domain(lookup)
- assert interfaces.IEmailLookup.providedBy(lookup)
- self.lookup = lookup
- self.customMesg = customMesg
- self.messageFormatter = messageFormatter
- if extraHeaders:
- if not isinstance(extraHeaders, dict):
- config.error("extraHeaders must be a dictionary")
- self.extraHeaders = extraHeaders
- self.addPatch = addPatch
- self.useTls = useTls
- self.smtpUser = smtpUser
- self.smtpPassword = smtpPassword
- self.smtpPort = smtpPort
- self.buildSetSummary = buildSetSummary
- self.buildSetSubscription = None
- self.getPreviousBuild = previousBuildGetter
- self.watched = []
- self.master_status = None
-
- # you should either limit on builders or categories, not both
- if self.builders != None and self.categories != None:
- config.error(
- "Please specify only builders or categories to include - " +
- "not both.")
-
- if customMesg:
- config.error(
- "customMesg is deprecated; use messageFormatter instead")
-
- def setServiceParent(self, parent):
- """
- @type parent: L{buildbot.master.BuildMaster}
- """
- base.StatusReceiverMultiService.setServiceParent(self, parent)
- self.master_status = self.parent
- self.master_status.subscribe(self)
- self.master = self.master_status.master
-
- def startService(self):
- if self.buildSetSummary:
- self.buildSetSubscription = \
- self.master.subscribeToBuildsetCompletions(self.buildsetFinished)
-
- base.StatusReceiverMultiService.startService(self)
-
- def stopService(self):
- if self.buildSetSubscription is not None:
- self.buildSetSubscription.unsubscribe()
- self.buildSetSubscription = None
-
- return base.StatusReceiverMultiService.stopService(self)
-
- def disownServiceParent(self):
- self.master_status.unsubscribe(self)
- self.master_status = None
- for w in self.watched:
- w.unsubscribe(self)
- return base.StatusReceiverMultiService.disownServiceParent(self)
-
- def builderAdded(self, name, builder):
- # only subscribe to builders we are interested in
- if self.categories != None and builder.category not in self.categories:
- return None
-
- self.watched.append(builder)
- return self # subscribe to this builder
-
- def builderRemoved(self, name):
- pass
-
- def builderChangedState(self, name, state):
- pass
-
- def buildStarted(self, name, build):
- pass
-
- def isMailNeeded(self, build, results):
- # here is where we actually do something.
- builder = build.getBuilder()
- if self.builders is not None and builder.name not in self.builders:
- return False # ignore this build
- if self.categories is not None and \
- builder.category not in self.categories:
- return False # ignore this build
-
- prev = self.getPreviousBuild(build)
- if "change" in self.mode:
- if prev and prev.getResults() != results:
- return True
- if "failing" in self.mode and results == FAILURE:
- return True
- if "passing" in self.mode and results == SUCCESS:
- return True
- if "problem" in self.mode and results == FAILURE:
- if prev and prev.getResults() != FAILURE:
- return True
- if "warnings" in self.mode and results == WARNINGS:
- return True
- if "exception" in self.mode and results == EXCEPTION:
- return True
-
- return False
-
- def buildFinished(self, name, build, results):
- if ( not self.buildSetSummary and
- self.isMailNeeded(build, results) ):
- # for testing purposes, buildMessage returns a Deferred that fires
- # when the mail has been sent. To help unit tests, we return that
- # Deferred here even though the normal IStatusReceiver.buildFinished
- # signature doesn't do anything with it. If that changes (if
- # .buildFinished's return value becomes significant), we need to
- # rearrange this.
- return self.buildMessage(name, [build], results)
- return None
-
- def _gotBuilds(self, res, buildset):
- builds = []
- for (builddictlist, builder) in res:
- for builddict in builddictlist:
- build = builder.getBuild(builddict['number'])
- if build is not None and self.isMailNeeded(build, build.results):
- builds.append(build)
-
- if builds:
- self.buildMessage("Buildset Complete: " + buildset['reason'], builds,
- buildset['results'])
-
- def _gotBuildRequests(self, breqs, buildset):
- dl = []
- for breq in breqs:
- buildername = breq['buildername']
- builder = self.master_status.getBuilder(buildername)
- d = self.master.db.builds.getBuildsForRequest(breq['brid'])
- d.addCallback(lambda builddictlist, builder=builder:
- (builddictlist, builder))
- dl.append(d)
- d = defer.gatherResults(dl)
- d.addCallback(self._gotBuilds, buildset)
-
- def _gotBuildSet(self, buildset, bsid):
- d = self.master.db.buildrequests.getBuildRequests(bsid=bsid)
- d.addCallback(self._gotBuildRequests, buildset)
-
- def buildsetFinished(self, bsid, result):
- d = self.master.db.buildsets.getBuildset(bsid=bsid)
- d.addCallback(self._gotBuildSet, bsid)
-
- return d
-
- def getCustomMesgData(self, mode, name, build, results, master_status):
- #
- # logs is a list of tuples that contain the log
- # name, log url, and the log contents as a list of strings.
- #
- logs = list()
- for logf in build.getLogs():
- logStep = logf.getStep()
- stepName = logStep.getName()
- logStatus, dummy = logStep.getResults()
- logName = logf.getName()
- logs.append(('%s.%s' % (stepName, logName),
- '%s/steps/%s/logs/%s' % (
- master_status.getURLForThing(build),
- stepName, logName),
- logf.getText().splitlines(),
- logStatus))
-
- attrs = {'builderName': name,
- 'title': master_status.getTitle(),
- 'mode': mode,
- 'result': Results[results],
- 'buildURL': master_status.getURLForThing(build),
- 'buildbotURL': master_status.getBuildbotURL(),
- 'buildText': build.getText(),
- 'buildProperties': build.getProperties(),
- 'slavename': build.getSlavename(),
- 'reason': build.getReason().replace('\n', ''),
- 'responsibleUsers': build.getResponsibleUsers(),
- 'branch': "",
- 'revision': "",
- 'patch': "",
- 'patch_info': "",
- 'changes': [],
- 'logs': logs}
-
- ss = None
- ss_list = build.getSourceStamps()
-
- if ss_list:
- if len(ss_list) == 1:
- ss = ss_list[0]
- if ss:
- attrs['branch'] = ss.branch
- attrs['revision'] = ss.revision
- attrs['patch'] = ss.patch
- attrs['patch_info'] = ss.patch_info
- attrs['changes'] = ss.changes[:]
- else:
- for key in ['branch', 'revision', 'patch', 'patch_info', 'changes']:
- attrs[key] = {}
- for ss in ss_list:
- attrs['branch'][ss.codebase] = ss.branch
- attrs['revision'][ss.codebase] = ss.revision
- attrs['patch'][ss.codebase] = ss.patch
- attrs['patch_info'][ss.codebase] = ss.patch_info
- attrs['changes'][ss.codebase] = ss.changes[:]
-
- return attrs
-
- def patch_to_attachment(self, patch, index):
- # patches don't come with an encoding. If the patch is valid utf-8,
- # we'll attach it as MIMEText; otherwise, it gets attached as a binary
- # file. This will suit the vast majority of cases, since utf8 is by
- # far the most common encoding.
- if type(patch[1]) != types.UnicodeType:
- try:
- unicode = patch[1].decode('utf8')
- except UnicodeDecodeError:
- unicode = None
- else:
- unicode = patch[1]
-
- if unicode:
- a = MIMEText(unicode.encode(ENCODING), _charset=ENCODING)
- else:
- # MIMEApplication is not present in Python-2.4 :(
- a = MIMENonMultipart('application', 'octet-stream')
- a.set_payload(patch[1])
- a.add_header('Content-Disposition', "attachment",
- filename="source patch " + str(index) )
- return a
-
- def createEmail(self, msgdict, builderName, title, results, builds=None,
- patches=None, logs=None):
- text = msgdict['body'].encode(ENCODING)
- type = msgdict['type']
- if 'subject' in msgdict:
- subject = msgdict['subject'].encode(ENCODING)
- else:
- subject = self.subject % { 'result': Results[results],
- 'projectName': title,
- 'title': title,
- 'builder': builderName,
- }
-
- assert '\n' not in subject, \
- "Subject cannot contain newlines"
-
- assert type in ('plain', 'html'), \
- "'%s' message type must be 'plain' or 'html'." % type
-
- if patches or logs:
- m = MIMEMultipart()
- m.attach(MIMEText(text, type, ENCODING))
- else:
- m = Message()
- m.set_payload(text, ENCODING)
- m.set_type("text/%s" % type)
-
- m['Date'] = formatdate(localtime=True)
- m['Subject'] = subject
- m['From'] = self.fromaddr
- # m['To'] is added later
-
- if patches:
- for (i, patch) in enumerate(patches):
- a = self.patch_to_attachment(patch, i)
- m.attach(a)
- if logs:
- for log in logs:
- name = "%s.%s" % (log.getStep().getName(),
- log.getName())
- if ( self._shouldAttachLog(log.getName()) or
- self._shouldAttachLog(name) ):
- text = log.getText()
- if not isinstance(text, unicode):
- # guess at the encoding, and use replacement symbols
- # for anything that's not in that encoding
- text = text.decode(LOG_ENCODING, 'replace')
- a = MIMEText(text.encode(ENCODING),
- _charset=ENCODING)
- a.add_header('Content-Disposition', "attachment",
- filename=name)
- m.attach(a)
-
- #@todo: is there a better way to do this?
- # Add any extra headers that were requested, doing WithProperties
- # interpolation if only one build was given
- if self.extraHeaders:
- if len(builds) == 1:
- d = builds[0].render(self.extraHeaders)
- else:
- d = defer.succeed(self.extraHeaders)
- @d.addCallback
- def addExtraHeaders(extraHeaders):
- for k,v in extraHeaders.items():
- if k in m:
- twlog.msg("Warning: Got header " + k +
- " in self.extraHeaders "
- "but it already exists in the Message - "
- "not adding it.")
- m[k] = v
- d.addCallback(lambda _: m)
- return d
-
- return defer.succeed(m)
-
- def buildMessageDict(self, name, build, results):
- if self.customMesg:
- # the customMesg stuff can be *huge*, so we prefer not to load it
- attrs = self.getCustomMesgData(self.mode, name, build, results,
- self.master_status)
- text, type = self.customMesg(attrs)
- msgdict = { 'body' : text, 'type' : type }
- else:
- msgdict = self.messageFormatter(self.mode, name, build, results,
- self.master_status)
-
- return msgdict
-
-
- def buildMessage(self, name, builds, results):
- patches = []
- logs = []
- msgdict = {"body":""}
-
- for build in builds:
- ss_list = build.getSourceStamps()
- if self.addPatch:
- for ss in ss_list:
- if ss.patch:
- patches.append(ss.patch)
- if self.addLogs:
- logs.extend(build.getLogs())
-
- tmp = self.buildMessageDict(name=build.getBuilder().name,
- build=build, results=build.results)
- msgdict['body'] += tmp['body']
- msgdict['body'] += '\n\n'
- msgdict['type'] = tmp['type']
- if "subject" in tmp:
- msgdict['subject'] = tmp['subject']
-
- d = self.createEmail(msgdict, name, self.master_status.getTitle(),
- results, builds, patches, logs)
-
- @d.addCallback
- def getRecipients(m):
- # now, who is this message going to?
- if self.sendToInterestedUsers:
- dl = []
- for build in builds:
- if self.lookup:
- d = self.useLookup(build)
- else:
- d = self.useUsers(build)
- dl.append(d)
- d = defer.gatherResults(dl)
- else:
- d = defer.succeed([])
- d.addCallback(self._gotRecipients, m)
- return d
-
- def useLookup(self, build):
- dl = []
- for u in build.getResponsibleUsers() + build.getInterestedUsers():
- d = defer.maybeDeferred(self.lookup.getAddress, u)
- dl.append(d)
- return defer.gatherResults(dl)
-
- def useUsers(self, build):
- return users.getBuildContacts(self.master, build, ['email'])
-
- def _shouldAttachLog(self, logname):
- if type(self.addLogs) is bool:
- return self.addLogs
- return logname in self.addLogs
-
- def _gotRecipients(self, rlist, m):
- to_recipients = set()
- cc_recipients = set()
-
- for r in reduce(list.__add__, rlist, []):
- if r is None: # getAddress didn't like this address
- continue
-
- # Git can give emails like 'User' <user@foo.com>@foo.com so check
- # for two @ and chop the last
- if r.count('@') > 1:
- r = r[:r.rindex('@')]
-
- if VALID_EMAIL.search(r):
- to_recipients.add(r)
- else:
- twlog.msg("INVALID EMAIL: %r" + r)
-
- # If we're sending to interested users put the extras in the
- # CC list so they can tell if they are also interested in the
- # change:
- if self.sendToInterestedUsers and to_recipients:
- cc_recipients.update(self.extraRecipients)
- else:
- to_recipients.update(self.extraRecipients)
-
- m['To'] = ", ".join(sorted(to_recipients))
- if cc_recipients:
- m['CC'] = ", ".join(sorted(cc_recipients))
-
- return self.sendMessage(m, list(to_recipients | cc_recipients))
-
- def sendmail(self, s, recipients):
- result = defer.Deferred()
-
- if have_ssl and self.useTls:
- client_factory = ssl.ClientContextFactory()
- client_factory.method = SSLv3_METHOD
- else:
- client_factory = None
-
- if self.smtpUser and self.smtpPassword:
- useAuth = True
- else:
- useAuth = False
-
- if not ESMTPSenderFactory:
- raise RuntimeError("twisted-mail is not installed - cannot "
- "send mail")
- sender_factory = ESMTPSenderFactory(
- self.smtpUser, self.smtpPassword,
- self.fromaddr, recipients, StringIO(s),
- result, contextFactory=client_factory,
- requireTransportSecurity=self.useTls,
- requireAuthentication=useAuth)
-
- reactor.connectTCP(self.relayhost, self.smtpPort, sender_factory)
-
- return result
-
- def sendMessage(self, m, recipients):
- s = m.as_string()
- twlog.msg("sending mail (%d bytes) to" % len(s), recipients)
- return self.sendmail(s, recipients)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py
deleted file mode 100644
index 8d5b7e7d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py
+++ /dev/null
@@ -1,475 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os, urllib
-from cPickle import load
-from twisted.python import log
-from twisted.persisted import styles
-from twisted.internet import defer
-from twisted.application import service
-from zope.interface import implements
-from buildbot import config, interfaces, util
-from buildbot.util import bbcollections
-from buildbot.util.eventual import eventually
-from buildbot.changes import changes
-from buildbot.status import buildset, builder, buildrequest
-
-class Status(config.ReconfigurableServiceMixin, service.MultiService):
- implements(interfaces.IStatus)
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.master = master
- self.botmaster = master.botmaster
- self.basedir = master.basedir
- self.watchers = []
- # No default limit to the log size
- self.logMaxSize = None
-
- self._builder_observers = bbcollections.KeyedSets()
- self._buildreq_observers = bbcollections.KeyedSets()
- self._buildset_finished_waiters = bbcollections.KeyedSets()
- self._buildset_completion_sub = None
- self._buildset_sub = None
- self._build_request_sub = None
- self._change_sub = None
-
- # service management
-
- def startService(self):
- # subscribe to the things we need to know about
- self._buildset_completion_sub = \
- self.master.subscribeToBuildsetCompletions(
- self._buildsetCompletionCallback)
- self._buildset_sub = \
- self.master.subscribeToBuildsets(
- self._buildsetCallback)
- self._build_request_sub = \
- self.master.subscribeToBuildRequests(
- self._buildRequestCallback)
- self._change_sub = \
- self.master.subscribeToChanges(
- self.changeAdded)
-
- return service.MultiService.startService(self)
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # remove the old listeners, then add the new
- for sr in list(self):
- yield defer.maybeDeferred(lambda :
- sr.disownServiceParent())
-
- # WebStatus instances tend to "hang around" longer than we'd like -
- # if there's an ongoing HTTP request, or even a connection held
- # open by keepalive, then users may still be talking to an old
- # WebStatus. So WebStatus objects get to keep their `master`
- # attribute, but all other status objects lose theirs. And we want
- # to test this without importing WebStatus, so we use name
- if not sr.__class__.__name__.endswith('WebStatus'):
- sr.master = None
-
- for sr in new_config.status:
- sr.master = self.master
- sr.setServiceParent(self)
-
- # reconfig any newly-added change sources, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def stopService(self):
- if self._buildset_completion_sub:
- self._buildset_completion_sub.unsubscribe()
- self._buildset_completion_sub = None
- if self._buildset_sub:
- self._buildset_sub.unsubscribe()
- self._buildset_sub = None
- if self._build_request_sub:
- self._build_request_sub.unsubscribe()
- self._build_request_sub = None
- if self._change_sub:
- self._change_sub.unsubscribe()
- self._change_sub = None
-
- return service.MultiService.stopService(self)
-
- # clean shutdown
-
- @property
- def shuttingDown(self):
- return self.botmaster.shuttingDown
-
- def cleanShutdown(self):
- return self.botmaster.cleanShutdown()
-
- def cancelCleanShutdown(self):
- return self.botmaster.cancelCleanShutdown()
-
- # methods called by our clients
-
- def getTitle(self):
- return self.master.config.title
- def getTitleURL(self):
- return self.master.config.titleURL
- def getBuildbotURL(self):
- return self.master.config.buildbotURL
-
- def getStatus(self):
- # some listeners expect their .parent to be a BuildMaster object, and
- # use this method to get the Status object. This is documented, so for
- # now keep it working.
- return self
-
- def getMetrics(self):
- return self.master.metrics
-
- def getURLForBuild(self, builder_name, build_number):
- prefix = self.getBuildbotURL()
- import urlparse
- url_path = "builders/%s/builds/%d" % (
- urllib.quote(builder_name, safe=''),
- build_number)
- return(urlparse.urljoin(prefix,url_path))
-
- def getURLForThing(self, thing):
- prefix = self.getBuildbotURL()
- if not prefix:
- return None
- if interfaces.IStatus.providedBy(thing):
- return prefix
- if interfaces.ISchedulerStatus.providedBy(thing):
- pass
- if interfaces.IBuilderStatus.providedBy(thing):
- bldr = thing
- return prefix + "builders/%s" % (
- urllib.quote(bldr.getName(), safe=''),
- )
- if interfaces.IBuildStatus.providedBy(thing):
- build = thing
- bldr = build.getBuilder()
- return self.getURLForBuild(bldr.getName(), build.getNumber())
-
- if interfaces.IBuildStepStatus.providedBy(thing):
- step = thing
- build = step.getBuild()
- bldr = build.getBuilder()
- return prefix + "builders/%s/builds/%d/steps/%s" % (
- urllib.quote(bldr.getName(), safe=''),
- build.getNumber(),
- urllib.quote(step.getName(), safe=''))
- # IBuildSetStatus
- # IBuildRequestStatus
- # ISlaveStatus
- if interfaces.ISlaveStatus.providedBy(thing):
- slave = thing
- return prefix + "buildslaves/%s" % (
- urllib.quote(slave.getName(), safe=''),
- )
-
- # IStatusEvent
- if interfaces.IStatusEvent.providedBy(thing):
- # TODO: this is goofy, create IChange or something
- if isinstance(thing, changes.Change):
- change = thing
- return "%schanges/%d" % (prefix, change.number)
-
- if interfaces.IStatusLog.providedBy(thing):
- loog = thing
- step = loog.getStep()
- build = step.getBuild()
- bldr = build.getBuilder()
-
- logs = step.getLogs()
- for i in range(len(logs)):
- if loog is logs[i]:
- break
- else:
- return None
- return prefix + "builders/%s/builds/%d/steps/%s/logs/%s" % (
- urllib.quote(bldr.getName(), safe=''),
- build.getNumber(),
- urllib.quote(step.getName(), safe=''),
- urllib.quote(loog.getName(), safe=''))
-
- def getChangeSources(self):
- return list(self.master.change_svc)
-
- def getChange(self, number):
- """Get a Change object; returns a deferred"""
- d = self.master.db.changes.getChange(number)
- def chdict2change(chdict):
- if not chdict:
- return None
- return changes.Change.fromChdict(self.master, chdict)
- d.addCallback(chdict2change)
- return d
-
- def getSchedulers(self):
- return self.master.allSchedulers()
-
- def getBuilderNames(self, categories=None):
- if categories == None:
- # assume this is already sorted...
- return self.botmaster.builderNames
-
- l = []
- # respect addition order
- for name in self.botmaster.builderNames:
- bldr = self.botmaster.builders[name]
- if bldr.config.category in categories:
- l.append(name)
- return util.naturalSort(l)
-
- def getBuilder(self, name):
- """
- @rtype: L{BuilderStatus}
- """
- return self.botmaster.builders[name].builder_status
-
- def getSlaveNames(self):
- return self.botmaster.slaves.keys()
-
- def getSlave(self, slavename):
- return self.botmaster.slaves[slavename].slave_status
-
- def getBuildSets(self):
- d = self.master.db.buildsets.getBuildsets(complete=False)
- def make_status_objects(bsdicts):
- return [ buildset.BuildSetStatus(bsdict, self)
- for bsdict in bsdicts ]
- d.addCallback(make_status_objects)
- return d
-
- def generateFinishedBuilds(self, builders=[], branches=[],
- num_builds=None, finished_before=None,
- max_search=200):
-
- def want_builder(bn):
- if builders:
- return bn in builders
- return True
- builder_names = [bn
- for bn in self.getBuilderNames()
- if want_builder(bn)]
-
- # 'sources' is a list of generators, one for each Builder we're
- # using. When the generator is exhausted, it is replaced in this list
- # with None.
- sources = []
- for bn in builder_names:
- b = self.getBuilder(bn)
- g = b.generateFinishedBuilds(branches,
- finished_before=finished_before,
- max_search=max_search)
- sources.append(g)
-
- # next_build the next build from each source
- next_build = [None] * len(sources)
-
- def refill():
- for i,g in enumerate(sources):
- if next_build[i]:
- # already filled
- continue
- if not g:
- # already exhausted
- continue
- try:
- next_build[i] = g.next()
- except StopIteration:
- next_build[i] = None
- sources[i] = None
-
- got = 0
- while True:
- refill()
- # find the latest build among all the candidates
- candidates = [(i, b, b.getTimes()[1])
- for i,b in enumerate(next_build)
- if b is not None]
- candidates.sort(lambda x,y: cmp(x[2], y[2]))
- if not candidates:
- return
-
- # and remove it from the list
- i, build, finshed_time = candidates[-1]
- next_build[i] = None
- got += 1
- yield build
- if num_builds is not None:
- if got >= num_builds:
- return
-
- def subscribe(self, target):
- self.watchers.append(target)
- for name in self.botmaster.builderNames:
- self.announceNewBuilder(target, name, self.getBuilder(name))
- def unsubscribe(self, target):
- self.watchers.remove(target)
-
-
- # methods called by upstream objects
-
- def announceNewBuilder(self, target, name, builder_status):
- t = target.builderAdded(name, builder_status)
- if t:
- builder_status.subscribe(t)
-
- def builderAdded(self, name, basedir, category=None, description=None):
- """
- @rtype: L{BuilderStatus}
- """
- filename = os.path.join(self.basedir, basedir, "builder")
- log.msg("trying to load status pickle from %s" % filename)
- builder_status = None
- try:
- with open(filename, "rb") as f:
- builder_status = load(f)
- builder_status.master = self.master
-
- # (bug #1068) if we need to upgrade, we probably need to rewrite
- # this pickle, too. We determine this by looking at the list of
- # Versioned objects that have been unpickled, and (after doUpgrade)
- # checking to see if any of them set wasUpgraded. The Versioneds'
- # upgradeToVersionNN methods all set this.
- versioneds = styles.versionedsToUpgrade
- styles.doUpgrade()
- if True in [ hasattr(o, 'wasUpgraded') for o in versioneds.values() ]:
- log.msg("re-writing upgraded builder pickle")
- builder_status.saveYourself()
-
- except IOError:
- log.msg("no saved status pickle, creating a new one")
- except:
- log.msg("error while loading status pickle, creating a new one")
- log.msg("error follows:")
- log.err()
- if not builder_status:
- builder_status = builder.BuilderStatus(name, category, self.master,
- description)
- builder_status.addPointEvent(["builder", "created"])
- log.msg("added builder %s in category %s" % (name, category))
- # an unpickled object might not have category set from before,
- # so set it here to make sure
- builder_status.category = category
- builder_status.description = description
- builder_status.master = self.master
- builder_status.basedir = os.path.join(self.basedir, basedir)
- builder_status.name = name # it might have been updated
- builder_status.status = self
-
- if not os.path.isdir(builder_status.basedir):
- os.makedirs(builder_status.basedir)
- builder_status.determineNextBuildNumber()
-
- builder_status.setBigState("offline")
-
- for t in self.watchers:
- self.announceNewBuilder(t, name, builder_status)
-
- return builder_status
-
- def builderRemoved(self, name):
- for t in self.watchers:
- if hasattr(t, 'builderRemoved'):
- t.builderRemoved(name)
-
- def slaveConnected(self, name):
- for t in self.watchers:
- if hasattr(t, 'slaveConnected'):
- t.slaveConnected(name)
-
- def slaveDisconnected(self, name):
- for t in self.watchers:
- if hasattr(t, 'slaveDisconnected'):
- t.slaveDisconnected(name)
-
- def changeAdded(self, change):
- for t in self.watchers:
- if hasattr(t, 'changeAdded'):
- t.changeAdded(change)
-
- def asDict(self):
- result = {}
- # Constant
- result['title'] = self.getTitle()
- result['titleURL'] = self.getTitleURL()
- result['buildbotURL'] = self.getBuildbotURL()
- # TODO: self.getSchedulers()
- # self.getChangeSources()
- return result
-
- def build_started(self, brid, buildername, build_status):
- if brid in self._buildreq_observers:
- for o in self._buildreq_observers[brid]:
- eventually(o, build_status)
-
- def _buildrequest_subscribe(self, brid, observer):
- self._buildreq_observers.add(brid, observer)
-
- def _buildrequest_unsubscribe(self, brid, observer):
- self._buildreq_observers.discard(brid, observer)
-
- def _buildset_waitUntilFinished(self, bsid):
- d = defer.Deferred()
- self._buildset_finished_waiters.add(bsid, d)
- self._maybeBuildsetFinished(bsid)
- return d
-
- def _maybeBuildsetFinished(self, bsid):
- # check bsid to see if it's successful or finished, and notify anyone
- # who cares
- if bsid not in self._buildset_finished_waiters:
- return
- d = self.master.db.buildsets.getBuildset(bsid)
- def do_notifies(bsdict):
- bss = buildset.BuildSetStatus(bsdict, self)
- if bss.isFinished():
- for d in self._buildset_finished_waiters.pop(bsid):
- eventually(d.callback, bss)
- d.addCallback(do_notifies)
- d.addErrback(log.err, 'while notifying for buildset finishes')
-
- def _builder_subscribe(self, buildername, watcher):
- # should get requestSubmitted and requestCancelled
- self._builder_observers.add(buildername, watcher)
-
- def _builder_unsubscribe(self, buildername, watcher):
- self._builder_observers.discard(buildername, watcher)
-
- def _buildsetCallback(self, **kwargs):
- bsid = kwargs['bsid']
- d = self.master.db.buildsets.getBuildset(bsid)
- def do_notifies(bsdict):
- bss = buildset.BuildSetStatus(bsdict, self)
- for t in self.watchers:
- if hasattr(t, 'buildsetSubmitted'):
- t.buildsetSubmitted(bss)
- d.addCallback(do_notifies)
- d.addErrback(log.err, 'while notifying buildsetSubmitted')
-
- def _buildsetCompletionCallback(self, bsid, result):
- self._maybeBuildsetFinished(bsid)
-
- def _buildRequestCallback(self, notif):
- buildername = notif['buildername']
- if buildername in self._builder_observers:
- brs = buildrequest.BuildRequestStatus(buildername,
- notif['brid'], self)
- for observer in self._builder_observers[buildername]:
- if hasattr(observer, 'requestSubmitted'):
- eventually(observer.requestSubmitted, brs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py
deleted file mode 100644
index 0106a210..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-from collections import deque
-import os
-import cPickle as pickle
-
-from zope.interface import implements, Interface
-
-
-def ReadFile(path):
- with open(path, 'rb') as f:
- return f.read()
-
-
-def WriteFile(path, buf):
- with open(path, 'wb') as f:
- f.write(buf)
-
-
-class IQueue(Interface):
- """Abstraction of a queue."""
- def pushItem(item):
- """Adds an individual item to the end of the queue.
-
- Returns an item if it was overflowed."""
-
- def insertBackChunk(items):
- """Adds a list of items as the oldest entries.
-
- Normally called in case of failure to process the data, queue the data
- back so it can be retrieved at a later time.
-
- Returns a list of items if it was overflowed."""
-
- def popChunk(nbItems=None):
- """Pop many items at once. Defaults to self.maxItems()."""
-
- def save():
- """Save the queue to storage if implemented."""
-
- def items():
- """Returns items in the queue.
-
- Warning: Can be extremely slow for queue on disk."""
-
- def nbItems():
- """Returns the number of items in the queue."""
-
- def maxItems():
- """Returns the maximum number of items this queue can hold."""
-
-
-class MemoryQueue(object):
- """Simple length bounded queue using deque.
-
- list.pop(0) operation is O(n) so for a 10000 items list, it can start to
- be real slow. On the contrary, deque.popleft() is O(1) most of the time.
- See http://docs.python.org/library/collections.html for more
- information.
- """
- implements(IQueue)
-
- def __init__(self, maxItems=None):
- self._maxItems = maxItems
- if self._maxItems is None:
- self._maxItems = 10000
- self._items = deque()
-
- def pushItem(self, item):
- ret = None
- if len(self._items) == self._maxItems:
- ret = self._items.popleft()
- self._items.append(item)
- return ret
-
- def insertBackChunk(self, chunk):
- ret = None
- excess = len(self._items) + len(chunk) - self._maxItems
- if excess > 0:
- ret = chunk[0:excess]
- chunk = chunk[excess:]
- self._items.extendleft(reversed(chunk))
- return ret
-
- def popChunk(self, nbItems=None):
- if nbItems is None:
- nbItems = self._maxItems
- if nbItems > len(self._items):
- items = list(self._items)
- self._items = deque()
- else:
- items = []
- for i in range(nbItems):
- items.append(self._items.popleft())
- return items
-
- def save(self):
- pass
-
- def items(self):
- return list(self._items)
-
- def nbItems(self):
- return len(self._items)
-
- def maxItems(self):
- return self._maxItems
-
-
-class DiskQueue(object):
- """Keeps a list of abstract items and serializes it to the disk.
-
- Use pickle for serialization."""
- implements(IQueue)
-
- def __init__(self, path, maxItems=None, pickleFn=pickle.dumps,
- unpickleFn=pickle.loads):
- """
- @path: directory to save the items.
- @maxItems: maximum number of items to keep on disk, flush the
- older ones.
- @pickleFn: function used to pack the items to disk.
- @unpickleFn: function used to unpack items from disk.
- """
- self.path = path
- self._maxItems = maxItems
- if self._maxItems is None:
- self._maxItems = 100000
- if not os.path.isdir(self.path):
- os.mkdir(self.path)
- self.pickleFn = pickleFn
- self.unpickleFn = unpickleFn
-
- # Total number of items.
- self._nbItems = 0
- # The actual items id start at one.
- self.firstItemId = 0
- self.lastItemId = 0
- self._loadFromDisk()
-
- def pushItem(self, item):
- ret = None
- if self._nbItems == self._maxItems:
- id = self._findNext(self.firstItemId)
- path = os.path.join(self.path, str(id))
- ret = self.unpickleFn(ReadFile(path))
- os.remove(path)
- self.firstItemId = id + 1
- else:
- self._nbItems += 1
- self.lastItemId += 1
- path = os.path.join(self.path, str(self.lastItemId))
- if os.path.exists(path):
- raise IOError('%s already exists.' % path)
- WriteFile(path, self.pickleFn(item))
- return ret
-
- def insertBackChunk(self, chunk):
- ret = None
- excess = self._nbItems + len(chunk) - self._maxItems
- if excess > 0:
- ret = chunk[0:excess]
- chunk = chunk[excess:]
- for i in reversed(chunk):
- self.firstItemId -= 1
- path = os.path.join(self.path, str(self.firstItemId))
- if os.path.exists(path):
- raise IOError('%s already exists.' % path)
- WriteFile(path, self.pickleFn(i))
- self._nbItems += 1
- return ret
-
- def popChunk(self, nbItems=None):
- if nbItems is None:
- nbItems = self._maxItems
- ret = []
- for i in range(nbItems):
- if self._nbItems == 0:
- break
- id = self._findNext(self.firstItemId)
- path = os.path.join(self.path, str(id))
- ret.append(self.unpickleFn(ReadFile(path)))
- os.remove(path)
- self._nbItems -= 1
- self.firstItemId = id + 1
- return ret
-
- def save(self):
- pass
-
- def items(self):
- """Warning, very slow."""
- ret = []
- for id in range(self.firstItemId, self.lastItemId + 1):
- path = os.path.join(self.path, str(id))
- if os.path.exists(path):
- ret.append(self.unpickleFn(ReadFile(path)))
- return ret
-
- def nbItems(self):
- return self._nbItems
-
- def maxItems(self):
- return self._maxItems
-
- #### Protected functions
-
- def _findNext(self, id):
- while True:
- path = os.path.join(self.path, str(id))
- if os.path.isfile(path):
- return id
- id += 1
- return None
-
- def _loadFromDisk(self):
- """Loads the queue from disk upto self.maxMemoryItems items into
- self.items.
- """
- def SafeInt(item):
- try:
- return int(item)
- except ValueError:
- return None
-
- files = filter(None, [SafeInt(x) for x in os.listdir(self.path)])
- files.sort()
- self._nbItems = len(files)
- if self._nbItems:
- self.firstItemId = files[0]
- self.lastItemId = files[-1]
-
-
-class PersistentQueue(object):
- """Keeps a list of abstract items and serializes it to the disk.
-
- It has 2 layers of queue, normally an in-memory queue and an on-disk queue.
- When the number of items in the primary queue gets too large, the new items
- are automatically saved to the secondary queue. The older items are kept in
- the primary queue.
- """
- implements(IQueue)
-
- def __init__(self, primaryQueue=None, secondaryQueue=None, path=None):
- """
- @primaryQueue: memory queue to use before buffering to disk.
- @secondaryQueue: disk queue to use as permanent buffer.
- @path: path is a shortcut when using default DiskQueue settings.
- """
- self.primaryQueue = primaryQueue
- if self.primaryQueue is None:
- self.primaryQueue = MemoryQueue()
- self.secondaryQueue = secondaryQueue
- if self.secondaryQueue is None:
- self.secondaryQueue = DiskQueue(path)
- # Preload data from the secondary queue only if we know we won't start
- # using the secondary queue right away.
- if self.secondaryQueue.nbItems() < self.primaryQueue.maxItems():
- self.primaryQueue.insertBackChunk(
- self.secondaryQueue.popChunk(self.primaryQueue.maxItems()))
-
- def pushItem(self, item):
- # If there is already items in secondaryQueue, we'd need to pop them
- # all to start inserting them into primaryQueue so don't bother and
- # just push it in secondaryQueue.
- if (self.secondaryQueue.nbItems() or
- self.primaryQueue.nbItems() == self.primaryQueue.maxItems()):
- item = self.secondaryQueue.pushItem(item)
- if item is None:
- return item
- # If item is not None, secondaryQueue overflowed. We need to push it
- # back to primaryQueue so the oldest item is dumped.
- # Or everything fit in the primaryQueue.
- return self.primaryQueue.pushItem(item)
-
- def insertBackChunk(self, chunk):
- ret = None
- # Overall excess
- excess = self.nbItems() + len(chunk) - self.maxItems()
- if excess > 0:
- ret = chunk[0:excess]
- chunk = chunk[excess:]
- # Memory excess
- excess = (self.primaryQueue.nbItems() + len(chunk) -
- self.primaryQueue.maxItems())
- if excess > 0:
- chunk2 = []
- for i in range(excess):
- chunk2.append(self.primaryQueue.items().pop())
- chunk2.reverse()
- x = self.primaryQueue.insertBackChunk(chunk)
- assert x is None, "primaryQueue.insertBackChunk did not return None"
- if excess > 0:
- x = self.secondaryQueue.insertBackChunk(chunk2)
- assert x is None, ("secondaryQueue.insertBackChunk did not return "
- " None")
- return ret
-
- def popChunk(self, nbItems=None):
- if nbItems is None:
- nbItems = self.primaryQueue.maxItems()
- ret = self.primaryQueue.popChunk(nbItems)
- nbItems -= len(ret)
- if nbItems and self.secondaryQueue.nbItems():
- ret.extend(self.secondaryQueue.popChunk(nbItems))
- return ret
-
- def save(self):
- self.secondaryQueue.insertBackChunk(self.primaryQueue.popChunk())
-
- def items(self):
- return self.primaryQueue.items() + self.secondaryQueue.items()
-
- def nbItems(self):
- return self.primaryQueue.nbItems() + self.secondaryQueue.nbItems()
-
- def maxItems(self):
- return self.primaryQueue.maxItems() + self.secondaryQueue.maxItems()
-
-
-class IndexedQueue(object):
- """Adds functionality to a IQueue object to track its usage.
-
- Adds a new member function getIndex() and modify popChunk() and
- insertBackChunk() to keep a virtual pointer to the queue's first entry
- index."""
- implements(IQueue)
-
- def __init__(self, queue):
- # Copy all the member functions from the other object that this class
- # doesn't already define.
- assert IQueue.providedBy(queue)
- def Filter(m):
- return (m[0] != '_' and callable(getattr(queue, m))
- and not hasattr(self, m))
- for member in filter(Filter, dir(queue)):
- setattr(self, member, getattr(queue, member))
- self.queue = queue
- self._index = 0
-
- def getIndex(self):
- return self._index
-
- def popChunk(self, *args, **kwargs):
- items = self.queue.popChunk(*args, **kwargs)
- if items:
- self._index += len(items)
- return items
-
- def insertBackChunk(self, items):
- self._index -= len(items)
- ret = self.queue.insertBackChunk(items)
- if ret:
- self._index += len(ret)
- return ret
-
-
-def ToIndexedQueue(queue):
- """If the IQueue wasn't already a IndexedQueue, makes it an IndexedQueue."""
- if not IQueue.providedBy(queue):
- raise TypeError("queue doesn't implement IQueue", queue)
- if isinstance(queue, IndexedQueue):
- return queue
- return IndexedQueue(queue)
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py
deleted file mode 100644
index 62aae317..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py
+++ /dev/null
@@ -1,324 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.internet import reactor
-from twisted.spread import pb
-from twisted.python import log
-from buildbot import util
-from collections import defaultdict
-
-class StepProgress:
- """I keep track of how much progress a single BuildStep has made.
-
- Progress is measured along various axes. Time consumed is one that is
- available for all steps. Amount of command output is another, and may be
- better quantified by scanning the output for markers to derive number of
- files compiled, directories walked, tests run, etc.
-
- I am created when the build begins, and given to a BuildProgress object
- so it can track the overall progress of the whole build.
-
- """
-
- startTime = None
- stopTime = None
- expectedTime = None
- buildProgress = None
- debug = False
-
- def __init__(self, name, metricNames):
- self.name = name
- self.progress = {}
- self.expectations = {}
- for m in metricNames:
- self.progress[m] = None
- self.expectations[m] = None
-
- def setBuildProgress(self, bp):
- self.buildProgress = bp
-
- def setExpectations(self, metrics):
- """The step can call this to explicitly set a target value for one
- of its metrics. E.g., ShellCommands knows how many commands it will
- execute, so it could set the 'commands' expectation."""
- for metric, value in metrics.items():
- self.expectations[metric] = value
- self.buildProgress.newExpectations()
-
- def setExpectedTime(self, seconds):
- self.expectedTime = seconds
- self.buildProgress.newExpectations()
-
- def start(self):
- if self.debug: print "StepProgress.start[%s]" % self.name
- self.startTime = util.now()
-
- def setProgress(self, metric, value):
- """The step calls this as progress is made along various axes."""
- if self.debug:
- print "setProgress[%s][%s] = %s" % (self.name, metric, value)
- self.progress[metric] = value
- if self.debug:
- r = self.remaining()
- print " step remaining:", r
- self.buildProgress.newProgress()
-
- def finish(self):
- """This stops the 'time' metric and marks the step as finished
- overall. It should be called after the last .setProgress has been
- done for each axis."""
- if self.debug: print "StepProgress.finish[%s]" % self.name
- self.stopTime = util.now()
- self.buildProgress.stepFinished(self.name)
-
- def totalTime(self):
- if self.startTime != None and self.stopTime != None:
- return self.stopTime - self.startTime
-
- def remaining(self):
- if self.startTime == None:
- return self.expectedTime
- if self.stopTime != None:
- return 0 # already finished
- # TODO: replace this with cleverness that graphs each metric vs.
- # time, then finds the inverse function. Will probably need to save
- # a timestamp with each setProgress update, when finished, go back
- # and find the 2% transition points, then save those 50 values in a
- # list. On the next build, do linear interpolation between the two
- # closest samples to come up with a percentage represented by that
- # metric.
-
- # TODO: If no other metrics are available, just go with elapsed
- # time. Given the non-time-uniformity of text output from most
- # steps, this would probably be better than the text-percentage
- # scheme currently implemented.
-
- percentages = []
- for metric, value in self.progress.items():
- expectation = self.expectations[metric]
- if value != None and expectation != None:
- p = 1.0 * value / expectation
- percentages.append(p)
- if percentages:
- avg = reduce(lambda x,y: x+y, percentages) / len(percentages)
- if avg > 1.0:
- # overdue
- avg = 1.0
- if avg < 0.0:
- avg = 0.0
- if percentages and self.expectedTime != None:
- return self.expectedTime - (avg * self.expectedTime)
- if self.expectedTime is not None:
- # fall back to pure time
- return self.expectedTime - (util.now() - self.startTime)
- return None # no idea
-
-
-class WatcherState:
- def __init__(self, interval):
- self.interval = interval
- self.timer = None
- self.needUpdate = 0
-
-class BuildProgress(pb.Referenceable):
- """I keep track of overall build progress. I hold a list of StepProgress
- objects.
- """
-
- def __init__(self, stepProgresses):
- self.steps = {}
- for s in stepProgresses:
- self.steps[s.name] = s
- s.setBuildProgress(self)
- self.finishedSteps = []
- self.watchers = {}
- self.debug = 0
-
- def setExpectationsFrom(self, exp):
- """Set our expectations from the builder's Expectations object."""
- for name, metrics in exp.steps.items():
- s = self.steps.get(name)
- if s:
- s.setExpectedTime(exp.times[name])
- s.setExpectations(exp.steps[name])
-
- def newExpectations(self):
- """Call this when one of the steps has changed its expectations.
- This should trigger us to update our ETA value and notify any
- subscribers."""
- pass # subscribers are not implemented: they just poll
-
- def stepFinished(self, stepname):
- assert(stepname not in self.finishedSteps)
- self.finishedSteps.append(stepname)
- if len(self.finishedSteps) == len(self.steps.keys()):
- self.sendLastUpdates()
-
- def newProgress(self):
- r = self.remaining()
- if self.debug:
- print " remaining:", r
- if r != None:
- self.sendAllUpdates()
-
- def remaining(self):
- # sum eta of all steps
- sum = 0
- for name, step in self.steps.items():
- rem = step.remaining()
- if rem == None:
- return None # not sure
- sum += rem
- return sum
- def eta(self):
- left = self.remaining()
- if left == None:
- return None # not sure
- done = util.now() + left
- return done
-
-
- def remote_subscribe(self, remote, interval=5):
- # [interval, timer, needUpdate]
- # don't send an update more than once per interval
- self.watchers[remote] = WatcherState(interval)
- remote.notifyOnDisconnect(self.removeWatcher)
- self.updateWatcher(remote)
- self.startTimer(remote)
- log.msg("BuildProgress.remote_subscribe(%s)" % remote)
- def remote_unsubscribe(self, remote):
- # TODO: this doesn't work. I think 'remote' will always be different
- # than the object that appeared in _subscribe.
- log.msg("BuildProgress.remote_unsubscribe(%s)" % remote)
- self.removeWatcher(remote)
- #remote.dontNotifyOnDisconnect(self.removeWatcher)
- def removeWatcher(self, remote):
- #log.msg("removeWatcher(%s)" % remote)
- try:
- timer = self.watchers[remote].timer
- if timer:
- timer.cancel()
- del self.watchers[remote]
- except KeyError:
- log.msg("Weird, removeWatcher on non-existent subscriber:",
- remote)
- def sendAllUpdates(self):
- for r in self.watchers.keys():
- self.updateWatcher(r)
- def updateWatcher(self, remote):
- # an update wants to go to this watcher. Send it if we can, otherwise
- # queue it for later
- w = self.watchers[remote]
- if not w.timer:
- # no timer, so send update now and start the timer
- self.sendUpdate(remote)
- self.startTimer(remote)
- else:
- # timer is running, just mark as needing an update
- w.needUpdate = 1
- def startTimer(self, remote):
- w = self.watchers[remote]
- timer = reactor.callLater(w.interval, self.watcherTimeout, remote)
- w.timer = timer
- def sendUpdate(self, remote, last=0):
- self.watchers[remote].needUpdate = 0
- #text = self.asText() # TODO: not text, duh
- try:
- remote.callRemote("progress", self.remaining())
- if last:
- remote.callRemote("finished", self)
- except:
- log.deferr()
- self.removeWatcher(remote)
-
- def watcherTimeout(self, remote):
- w = self.watchers.get(remote, None)
- if not w:
- return # went away
- w.timer = None
- if w.needUpdate:
- self.sendUpdate(remote)
- self.startTimer(remote)
- def sendLastUpdates(self):
- for remote in self.watchers.keys():
- self.sendUpdate(remote, 1)
- self.removeWatcher(remote)
-
-
-class Expectations:
- debug = False
- # decay=1.0 ignores all but the last build
- # 0.9 is short time constant. 0.1 is very long time constant
- # TODO: let decay be specified per-metric
- decay = 0.5
-
- def __init__(self, buildprogress):
- """Create us from a successful build. We will expect each step to
- take as long as it did in that build."""
-
- # .steps maps stepname to dict2
- # dict2 maps metricname to final end-of-step value
- self.steps = defaultdict(dict)
-
- # .times maps stepname to per-step elapsed time
- self.times = {}
-
- for name, step in buildprogress.steps.items():
- self.steps[name] = {}
- for metric, value in step.progress.items():
- self.steps[name][metric] = value
- self.times[name] = None
- if step.startTime is not None and step.stopTime is not None:
- self.times[name] = step.stopTime - step.startTime
-
- def wavg(self, old, current):
- if old is None:
- return current
- if current is None:
- return old
- else:
- return (current * self.decay) + (old * (1 - self.decay))
-
- def update(self, buildprogress):
- for name, stepprogress in buildprogress.steps.items():
- old = self.times.get(name)
- current = stepprogress.totalTime()
- if current == None:
- log.msg("Expectations.update: current[%s] was None!" % name)
- continue
- new = self.wavg(old, current)
- self.times[name] = new
- if self.debug:
- print "new expected time[%s] = %s, old %s, cur %s" % \
- (name, new, old, current)
-
- for metric, current in stepprogress.progress.items():
- old = self.steps[name].get(metric)
- new = self.wavg(old, current)
- if self.debug:
- print "new expectation[%s][%s] = %s, old %s, cur %s" % \
- (name, metric, new, old, current)
- self.steps[name][metric] = new
-
- def expectedBuildTime(self):
- if None in self.times.values():
- return None
- #return sum(self.times.values())
- # python-2.2 doesn't have 'sum'. TODO: drop python-2.2 support
- s = 0
- for v in self.times.values():
- s += v
- return s
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py
deleted file mode 100644
index 2b012f0e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY = range(6)
-Results = ["success", "warnings", "failure", "skipped", "exception", "retry"]
-
-def worst_status(a, b):
- # SUCCESS > WARNINGS > FAILURE > EXCEPTION > RETRY
- # Retry needs to be considered the worst so that conusmers don't have to
- # worry about other failures undermining the RETRY.
- for s in (RETRY, EXCEPTION, FAILURE, WARNINGS, SKIPPED, SUCCESS):
- if s in (a, b):
- return s
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py
deleted file mode 100644
index a3c5b4ec..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-from zope.interface import implements
-from buildbot import interfaces
-from buildbot.util.eventual import eventually
-
-class SlaveStatus:
- implements(interfaces.ISlaveStatus)
-
- admin = None
- host = None
- access_uri = None
- version = None
- connected = False
- graceful_shutdown = False
- paused = False
-
- def __init__(self, name):
- self.name = name
- self._lastMessageReceived = 0
- self.runningBuilds = []
- self.graceful_callbacks = []
- self.connect_times = []
-
- def getName(self):
- return self.name
- def getAdmin(self):
- return self.admin
- def getHost(self):
- return self.host
- def getAccessURI(self):
- return self.access_uri
- def getVersion(self):
- return self.version
- def isConnected(self):
- return self.connected
- def isPaused(self):
- return self.paused
- def lastMessageReceived(self):
- return self._lastMessageReceived
- def getRunningBuilds(self):
- return self.runningBuilds
- def getConnectCount(self):
- then = time.time() - 3600
- return len([ t for t in self.connect_times if t > then ])
-
- def setAdmin(self, admin):
- self.admin = admin
- def setHost(self, host):
- self.host = host
- def setAccessURI(self, access_uri):
- self.access_uri = access_uri
- def setVersion(self, version):
- self.version = version
- def setConnected(self, isConnected):
- self.connected = isConnected
- def setLastMessageReceived(self, when):
- self._lastMessageReceived = when
- def setPaused(self, isPaused):
- self.paused = isPaused
-
- def recordConnectTime(self):
- # record this connnect, and keep data for the last hour
- now = time.time()
- self.connect_times = [ t for t in self.connect_times if t > now - 3600 ] + [ now ]
-
- def buildStarted(self, build):
- self.runningBuilds.append(build)
- def buildFinished(self, build):
- self.runningBuilds.remove(build)
-
- def getGraceful(self):
- """Return the graceful shutdown flag"""
- return self.graceful_shutdown
- def setGraceful(self, graceful):
- """Set the graceful shutdown flag, and notify all the watchers"""
- self.graceful_shutdown = graceful
- for cb in self.graceful_callbacks:
- eventually(cb, graceful)
- def addGracefulWatcher(self, watcher):
- """Add watcher to the list of watchers to be notified when the
- graceful shutdown flag is changed."""
- if not watcher in self.graceful_callbacks:
- self.graceful_callbacks.append(watcher)
- def removeGracefulWatcher(self, watcher):
- """Remove watcher from the list of watchers to be notified when the
- graceful shutdown flag is changed."""
- if watcher in self.graceful_callbacks:
- self.graceful_callbacks.remove(watcher)
-
- def asDict(self):
- result = {}
- # Constant
- result['name'] = self.getName()
- result['access_uri'] = self.getAccessURI()
-
- # Transient (since it changes when the slave reconnects)
- result['host'] = self.getHost()
- result['admin'] = self.getAdmin()
- result['version'] = self.getVersion()
- result['connected'] = self.isConnected()
- result['runningBuilds'] = [b.asDict() for b in self.getRunningBuilds()]
- return result
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py
deleted file mode 100644
index b4925ccf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-"""Push events to gerrit
-
-."""
-
-from buildbot.status.base import StatusReceiverMultiService
-from buildbot.status.builder import Results, SUCCESS, RETRY
-from twisted.internet import reactor
-from twisted.internet.protocol import ProcessProtocol
-
-def defaultReviewCB(builderName, build, result, status, arg):
- if result == RETRY:
- return None, 0, 0
-
- message = "Buildbot finished compiling your patchset\n"
- message += "on configuration: %s\n" % builderName
- message += "The result is: %s\n" % Results[result].upper()
-
- # message, verified, reviewed
- return message, (result == SUCCESS or -1), 0
-
-class GerritStatusPush(StatusReceiverMultiService):
- """Event streamer to a gerrit ssh server."""
-
- def __init__(self, server, username, reviewCB=defaultReviewCB,
- startCB=None, port=29418, reviewArg=None,
- startArg=None, **kwargs):
- """
- @param server: Gerrit SSH server's address to use for push event notifications.
- @param username: Gerrit SSH server's username.
- @param reviewCB: Callback that is called each time a build is finished, and that is used
- to define the message and review approvals depending on the build result.
- @param startCB: Callback that is called each time a build is started.
- Used to define the message sent to Gerrit.
- @param port: Gerrit SSH server's port.
- @param reviewArg: Optional argument passed to the review callback.
- @param startArg: Optional argument passed to the start callback.
- """
- StatusReceiverMultiService.__init__(self)
- # Parameters.
- self.gerrit_server = server
- self.gerrit_username = username
- self.gerrit_port = port
- self.reviewCB = reviewCB
- self.reviewArg = reviewArg
- self.startCB = startCB
- self.startArg = startArg
-
- class LocalPP(ProcessProtocol):
- def __init__(self, status):
- self.status = status
-
- def outReceived(self, data):
- print "gerritout:", data
-
- def errReceived(self, data):
- print "gerriterr:", data
-
- def processEnded(self, status_object):
- if status_object.value.exitCode:
- print "gerrit status: ERROR:", status_object
- else:
- print "gerrit status: OK"
-
- def startService(self):
- print """Starting up."""
- StatusReceiverMultiService.startService(self)
- self.status = self.parent.getStatus()
- self.status.subscribe(self)
-
- def builderAdded(self, name, builder):
- return self # subscribe to this builder
-
- def buildStarted(self, builderName, build):
- if self.startCB is not None:
- message = self.startCB(builderName, build, self.startArg)
- self.sendCodeReviews(build, message)
-
- def buildFinished(self, builderName, build, result):
- """Do the SSH gerrit verify command to the server."""
- message, verified, reviewed = self.reviewCB(builderName, build, result, self.status, self.reviewArg)
- self.sendCodeReviews(build, message, verified, reviewed)
-
- def sendCodeReviews(self, build, message, verified=0, reviewed=0):
- if message is None:
- return
-
- # Gerrit + Repo
- downloads = build.getProperty("repo_downloads")
- downloaded = build.getProperty("repo_downloaded")
- if downloads is not None and downloaded is not None:
- downloaded = downloaded.split(" ")
- if downloads and 2 * len(downloads) == len(downloaded):
- for i in range(0, len(downloads)):
- try:
- project, change1 = downloads[i].split(" ")
- except ValueError:
- return # something is wrong, abort
- change2 = downloaded[2 * i]
- revision = downloaded[2 * i + 1]
- if change1 == change2:
- self.sendCodeReview(project, revision, message, verified, reviewed)
- else:
- return # something is wrong, abort
- return
-
- # Gerrit + Git
- if build.getProperty("gerrit_branch") is not None: # used only to verify Gerrit source
- project = build.getProperty("project")
- revision = build.getProperty("got_revision")
-
- # review doesn't really work with multiple revisions, so let's
- # just assume it's None there
- if isinstance(revision, dict):
- revision = None
-
- if project is not None and revision is not None:
- self.sendCodeReview(project, revision, message, verified, reviewed)
- return
-
- def sendCodeReview(self, project, revision, message=None, verified=0, reviewed=0):
- command = ["ssh", self.gerrit_username + "@" + self.gerrit_server, "-p %d" % self.gerrit_port,
- "gerrit", "review", "--project %s" % str(project)]
- if message:
- command.append("--message '%s'" % message.replace("'","\""))
- if verified:
- command.extend(["--verified %d" % int(verified)])
- if reviewed:
- command.extend(["--code-review %d" % int(reviewed)])
- command.append(str(revision))
- print command
- reactor.spawnProcess(self.LocalPP(self), "ssh", command)
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py
deleted file mode 100644
index a3ecf5c0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py
+++ /dev/null
@@ -1,442 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-"""Push events to an abstract receiver.
-
-Implements the HTTP receiver."""
-
-import datetime
-import os
-import urllib
-import urlparse
-
-try:
- import simplejson as json
- assert json
-except ImportError:
- import json
-
-from buildbot import config
-from buildbot.status.base import StatusReceiverMultiService
-from buildbot.status.persistent_queue import DiskQueue, IndexedQueue, \
- MemoryQueue, PersistentQueue
-from buildbot.status.web.status_json import FilterOut
-from twisted.internet import defer, reactor
-from twisted.python import log
-from twisted.web import client
-
-
-
-class StatusPush(StatusReceiverMultiService):
- """Event streamer to a abstract channel.
-
- It uses IQueue to batch push requests and queue the data when
- the receiver is down.
- When a PersistentQueue object is used, the items are saved to disk on master
- shutdown so they can be pushed back when the master is restarted.
- """
-
- def __init__(self, serverPushCb, queue=None, path=None, filter=True,
- bufferDelay=1, retryDelay=5, blackList=None):
- """
- @serverPushCb: callback to be used. It receives 'self' as parameter. It
- should call self.queueNextServerPush() when it's done to queue the next
- push. It is guaranteed that the queue is not empty when this function is
- called.
- @queue: a item queue that implements IQueue.
- @path: path to save config.
- @filter: when True (default), removes all "", None, False, [] or {}
- entries.
- @bufferDelay: amount of time events are queued before sending, to
- reduce the number of push requests rate. This is the delay between the
- end of a request to initializing a new one.
- @retryDelay: amount of time between retries when no items were pushed on
- last serverPushCb call.
- @blackList: events that shouldn't be sent.
- """
- StatusReceiverMultiService.__init__(self)
-
- # Parameters.
- self.queue = queue
- if self.queue is None:
- self.queue = MemoryQueue()
- self.queue = IndexedQueue(self.queue)
- self.path = path
- self.filter = filter
- self.bufferDelay = bufferDelay
- self.retryDelay = retryDelay
- if not callable(serverPushCb):
- raise NotImplementedError('Please pass serverPushCb parameter.')
- def hookPushCb():
- # Update the index so we know if the next push succeed or not, don't
- # update the value when the queue is empty.
- if not self.queue.nbItems():
- return
- self.lastIndex = self.queue.getIndex()
- return serverPushCb(self)
- self.serverPushCb = hookPushCb
- self.blackList = blackList
-
- # Other defaults.
- # IDelayedCall object that represents the next queued push.
- self.task = None
- self.stopped = False
- self.lastIndex = -1
- self.state = {}
- self.state['started'] = str(datetime.datetime.utcnow())
- self.state['next_id'] = 1
- self.state['last_id_pushed'] = 0
- # Try to load back the state.
- if self.path and os.path.isdir(self.path):
- state_path = os.path.join(self.path, 'state')
- if os.path.isfile(state_path):
- with open(state_path, 'r') as f:
- self.state.update(json.load(f))
-
- if self.queue.nbItems():
- # Last shutdown was not clean, don't wait to send events.
- self.queueNextServerPush()
-
- def startService(self):
- """Starting up."""
- StatusReceiverMultiService.startService(self)
- self.status = self.parent.getStatus()
- self.status.subscribe(self)
- self.initialPush()
-
- def wasLastPushSuccessful(self):
- """Returns if the "virtual pointer" in the queue advanced."""
- return self.lastIndex <= self.queue.getIndex()
-
- def queueNextServerPush(self):
- """Queue the next push or call it immediately.
-
- Called to signal new items are available to be sent or on shutdown.
- A timer should be queued to trigger a network request or the callback
- should be called immediately. If a status push is already queued, ignore
- the current call."""
- # Determine the delay.
- if self.wasLastPushSuccessful():
- if self.stopped:
- # Shutting down.
- delay = 0
- else:
- # Normal case.
- delay = self.bufferDelay
- else:
- if self.stopped:
- # Too bad, we can't do anything now, we're shutting down and the
- # receiver is also down. We'll just save the objects to disk.
- return
- else:
- # The server is inaccessible, retry less often.
- delay = self.retryDelay
-
- # Cleanup a previously queued task if necessary.
- if self.task:
- # Warning: we could be running inside the task.
- if self.task.active():
- # There was already a task queue, don't requeue it, just let it
- # go.
- return
- else:
- if self.task.active():
- # There was a task queued but it is requested to call it
- # *right now* so cancel it.
- self.task.cancel()
- # Otherwise, it was just a stray object.
- self.task = None
-
- # Do the queue/direct call.
- if delay:
- # Call in delay seconds.
- self.task = reactor.callLater(delay, self.serverPushCb)
- elif self.stopped:
- if not self.queue.nbItems():
- return
- # Call right now, we're shutting down.
- @defer.inlineCallbacks
- def BlockForEverythingBeingSent():
- yield self.serverPushCb()
- return BlockForEverythingBeingSent()
- else:
- # delay should never be 0. That can cause Buildbot to spin tightly
- # trying to push events that may not be received well by a status
- # listener.
- log.err('Did not expect delay to be 0, but it is.')
- return
-
- def stopService(self):
- """Shutting down."""
- self.finalPush()
- self.stopped = True
- if (self.task and self.task.active()):
- # We don't have time to wait, force an immediate call.
- self.task.cancel()
- self.task = None
- d = self.queueNextServerPush()
- elif self.wasLastPushSuccessful():
- d = self.queueNextServerPush()
- else:
- d = defer.succeed(None)
-
- # We're dying, make sure we save the results.
- self.queue.save()
- if self.path and os.path.isdir(self.path):
- state_path = os.path.join(self.path, 'state')
- with open(state_path, 'w') as f:
- json.dump(self.state, f, sort_keys=True,
- indent=2)
- # Make sure all Deferreds are called on time and in a sane order.
- defers = filter(None, [d, StatusReceiverMultiService.stopService(self)])
- return defer.DeferredList(defers)
-
- def push(self, event, **objs):
- """Push a new event.
-
- The new event will be either:
- - Queued in memory to reduce network usage
- - Queued to disk when the sink server is down
- - Pushed (along the other queued items) to the server
- """
- if self.blackList and event in self.blackList:
- return
- # First, generate the packet.
- packet = {}
- packet['id'] = self.state['next_id']
- self.state['next_id'] += 1
- packet['timestamp'] = str(datetime.datetime.utcnow())
- packet['project'] = self.status.getTitle()
- packet['started'] = self.state['started']
- packet['event'] = event
- packet['payload'] = {}
- for obj_name, obj in objs.items():
- if hasattr(obj, 'asDict'):
- obj = obj.asDict()
- if self.filter:
- obj = FilterOut(obj)
- packet['payload'][obj_name] = obj
- self.queue.pushItem(packet)
- if self.task is None or not self.task.active():
- # No task queued since it was probably idle, let's queue a task.
- return self.queueNextServerPush()
-
- #### Events
-
- def initialPush(self):
- # Push everything we want to push from the initial configuration.
- self.push('start', status=self.status)
-
- def finalPush(self):
- self.push('shutdown', status=self.status)
-
- def requestSubmitted(self, request):
- self.push('requestSubmitted', request=request)
-
- def requestCancelled(self, builder, request):
- self.push('requestCancelled', builder=builder, request=request)
-
- def buildsetSubmitted(self, buildset):
- self.push('buildsetSubmitted', buildset=buildset)
-
- def builderAdded(self, builderName, builder):
- self.push('builderAdded', builderName=builderName, builder=builder)
- return self
-
- def builderChangedState(self, builderName, state):
- self.push('builderChangedState', builderName=builderName, state=state)
-
- def buildStarted(self, builderName, build):
- self.push('buildStarted', build=build)
- return self
-
- def buildETAUpdate(self, build, ETA):
- self.push('buildETAUpdate', build=build, ETA=ETA)
-
- def stepStarted(self, build, step):
- self.push('stepStarted',
- properties=build.getProperties().asList(),
- step=step)
-
- def stepTextChanged(self, build, step, text):
- self.push('stepTextChanged',
- properties=build.getProperties().asList(),
- step=step,
- text=text)
-
- def stepText2Changed(self, build, step, text2):
- self.push('stepText2Changed',
- properties=build.getProperties().asList(),
- step=step,
- text2=text2)
-
- def stepETAUpdate(self, build, step, ETA, expectations):
- self.push('stepETAUpdate',
- properties=build.getProperties().asList(),
- step=step,
- ETA=ETA,
- expectations=expectations)
-
- def logStarted(self, build, step, log):
- self.push('logStarted',
- properties=build.getProperties().asList(),
- step=step)
-
- def logFinished(self, build, step, log):
- self.push('logFinished',
- properties=build.getProperties().asList(),
- step=step)
-
- def stepFinished(self, build, step, results):
- self.push('stepFinished',
- properties=build.getProperties().asList(),
- step=step)
-
- def buildFinished(self, builderName, build, results):
- self.push('buildFinished', build=build)
-
- def builderRemoved(self, builderName):
- self.push('buildedRemoved', builderName=builderName)
-
- def changeAdded(self, change):
- self.push('changeAdded', change=change)
-
- def slaveConnected(self, slavename):
- self.push('slaveConnected', slave=self.status.getSlave(slavename))
-
- def slaveDisconnected(self, slavename):
- self.push('slaveDisconnected', slavename=slavename)
-
-
-class HttpStatusPush(StatusPush):
- """Event streamer to a HTTP server."""
-
- def __init__(self, serverUrl, debug=None, maxMemoryItems=None,
- maxDiskItems=None, chunkSize=200, maxHttpRequestSize=2**20,
- extra_post_params=None, **kwargs):
- """
- @serverUrl: Base URL to be used to push events notifications.
- @maxMemoryItems: Maximum number of items to keep queued in memory.
- @maxDiskItems: Maximum number of items to buffer to disk, if 0, doesn't
- use disk at all.
- @debug: Save the json with nice formatting.
- @chunkSize: maximum number of items to send in each at each HTTP POST.
- @maxHttpRequestSize: limits the size of encoded data for AE, the default
- is 1MB.
- """
- if not serverUrl:
- raise config.ConfigErrors(['HttpStatusPush requires a serverUrl'])
-
- # Parameters.
- self.serverUrl = serverUrl
- self.extra_post_params = extra_post_params or {}
- self.debug = debug
- self.chunkSize = chunkSize
- self.lastPushWasSuccessful = True
- self.maxHttpRequestSize = maxHttpRequestSize
- if maxDiskItems != 0:
- # The queue directory is determined by the server url.
- path = ('events_' +
- urlparse.urlparse(self.serverUrl)[1].split(':')[0])
- queue = PersistentQueue(
- primaryQueue=MemoryQueue(maxItems=maxMemoryItems),
- secondaryQueue=DiskQueue(path, maxItems=maxDiskItems))
- else:
- path = None
- queue = MemoryQueue(maxItems=maxMemoryItems)
-
- # Use the unbounded method.
- StatusPush.__init__(self, serverPushCb=HttpStatusPush.pushHttp,
- queue=queue, path=path, **kwargs)
-
- def wasLastPushSuccessful(self):
- return self.lastPushWasSuccessful
-
- def popChunk(self):
- """Pops items from the pending list.
-
- They must be queued back on failure."""
- if self.wasLastPushSuccessful():
- chunkSize = self.chunkSize
- else:
- chunkSize = 1
-
- while True:
- items = self.queue.popChunk(chunkSize)
- newitems = []
- for item in items:
- if hasattr(item, 'asDict'):
- newitems.append(item.asDict())
- else:
- newitems.append(item)
- if self.debug:
- packets = json.dumps(newitems, indent=2, sort_keys=True)
- else:
- packets = json.dumps(newitems, separators=(',',':'))
- params = {'packets': packets}
- params.update(self.extra_post_params)
- data = urllib.urlencode(params)
- if (not self.maxHttpRequestSize or
- len(data) < self.maxHttpRequestSize):
- return (data, items)
-
- if chunkSize == 1:
- # This packet is just too large. Drop this packet.
- log.msg("ERROR: packet %s was dropped, too large: %d > %d" %
- (items[0]['id'], len(data), self.maxHttpRequestSize))
- chunkSize = self.chunkSize
- else:
- # Try with half the packets.
- chunkSize /= 2
- self.queue.insertBackChunk(items)
-
- def pushHttp(self):
- """Do the HTTP POST to the server."""
- (encoded_packets, items) = self.popChunk()
-
- def Success(result):
- """Queue up next push."""
- log.msg('Sent %d events to %s' % (len(items), self.serverUrl))
- self.lastPushWasSuccessful = True
- return self.queueNextServerPush()
-
- def Failure(result):
- """Insert back items not sent and queue up next push."""
- # Server is now down.
- log.msg('Failed to push %d events to %s: %s' %
- (len(items), self.serverUrl, str(result)))
- self.queue.insertBackChunk(items)
- if self.stopped:
- # Bad timing, was being called on shutdown and the server died
- # on us. Make sure the queue is saved since we just queued back
- # items.
- self.queue.save()
- self.lastPushWasSuccessful = False
- return self.queueNextServerPush()
-
- # Trigger the HTTP POST request.
- headers = {'Content-Type': 'application/x-www-form-urlencoded'}
- connection = client.getPage(self.serverUrl,
- method='POST',
- postdata=encoded_packets,
- headers=headers,
- agent='buildbot')
- connection.addCallbacks(Success, Failure)
- return connection
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py
deleted file mode 100644
index 20002405..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from buildbot import interfaces
-
-class TestResult:
- implements(interfaces.ITestResult)
-
- def __init__(self, name, results, text, logs):
- assert isinstance(name, tuple)
- self.name = name
- self.results = results
- self.text = text
- self.logs = logs
-
- def getName(self):
- return self.name
-
- def getResults(self):
- return self.results
-
- def getText(self):
- return self.text
-
- def getLogs(self):
- return self.logs
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py
deleted file mode 100644
index 1694c243..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py
+++ /dev/null
@@ -1,276 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from email.Message import Message
-from email.Utils import formatdate
-
-from zope.interface import implements
-from twisted.internet import defer
-
-from buildbot import interfaces
-from buildbot.status import mail
-from buildbot.status.results import SUCCESS, WARNINGS, EXCEPTION, RETRY
-from buildbot.steps.shell import WithProperties
-
-import gzip, bz2, base64, re, cStringIO
-
-# TODO: docs, maybe a test of some sort just to make sure it actually imports
-# and can format email without raising an exception.
-
-class TinderboxMailNotifier(mail.MailNotifier):
- """This is a Tinderbox status notifier. It can send e-mail to a number of
- different tinderboxes or people. E-mails are sent at the beginning and
- upon completion of each build. It can be configured to send out e-mails
- for only certain builds.
-
- The most basic usage is as follows::
- TinderboxMailNotifier(fromaddr="buildbot@localhost",
- tree="MyTinderboxTree",
- extraRecipients=["tinderboxdaemon@host.org"])
-
- The builder name (as specified in master.cfg) is used as the "build"
- tinderbox option.
-
- """
- implements(interfaces.IEmailSender)
-
- compare_attrs = ["extraRecipients", "fromaddr", "categories", "builders",
- "addLogs", "relayhost", "subject", "binaryURL", "tree",
- "logCompression", "errorparser", "columnName",
- "useChangeTime"]
-
- def __init__(self, fromaddr, tree, extraRecipients,
- categories=None, builders=None, relayhost="localhost",
- subject="buildbot %(result)s in %(builder)s", binaryURL="",
- logCompression="", errorparser="unix", columnName=None,
- useChangeTime=False):
- """
- @type fromaddr: string
- @param fromaddr: the email address to be used in the 'From' header.
-
- @type tree: string
- @param tree: The Tinderbox tree to post to.
- When tree is a WithProperties instance it will be
- interpolated as such. See WithProperties for more detail
-
- @type extraRecipients: tuple of string
- @param extraRecipients: E-mail addresses of recipients. This should at
- least include the tinderbox daemon.
-
- @type categories: list of strings
- @param categories: a list of category names to serve status
- information for. Defaults to None (all
- categories). Use either builders or categories,
- but not both.
-
- @type builders: list of strings
- @param builders: a list of builder names for which mail should be
- sent. Defaults to None (send mail for all builds).
- Use either builders or categories, but not both.
-
- @type relayhost: string
- @param relayhost: the host to which the outbound SMTP connection
- should be made. Defaults to 'localhost'
-
- @type subject: string
- @param subject: a string to be used as the subject line of the message.
- %(builder)s will be replaced with the name of the
- %builder which provoked the message.
- This parameter is not significant for the tinderbox
- daemon.
-
- @type binaryURL: string
- @param binaryURL: If specified, this should be the location where final
- binary for a build is located.
- (ie. http://www.myproject.org/nightly/08-08-2006.tgz)
- It will be posted to the Tinderbox.
-
- @type logCompression: string
- @param logCompression: The type of compression to use on the log.
- Valid options are"bzip2" and "gzip". gzip is
- only known to work on Python 2.4 and above.
-
- @type errorparser: string
- @param errorparser: The error parser that the Tinderbox server
- should use when scanning the log file.
- Default is "unix".
-
- @type columnName: string
- @param columnName: When columnName is None, use the buildername as
- the Tinderbox column name. When columnName is a
- string this exact string will be used for all
- builders that this TinderboxMailNotifier cares
- about (not recommended). When columnName is a
- WithProperties instance it will be interpolated
- as such. See WithProperties for more detail.
- @type useChangeTime: bool
- @param useChangeTime: When True, the time of the first Change for a
- build is used as the builddate. When False,
- the current time is used as the builddate.
- """
-
- mail.MailNotifier.__init__(self, fromaddr, categories=categories,
- builders=builders, relayhost=relayhost,
- subject=subject,
- extraRecipients=extraRecipients,
- sendToInterestedUsers=False)
- assert isinstance(tree, basestring) \
- or isinstance(tree, WithProperties), \
- "tree must be a string or a WithProperties instance"
- self.tree = tree
- self.binaryURL = binaryURL
- self.logCompression = logCompression
- self.errorparser = errorparser
- self.useChangeTime = useChangeTime
- assert columnName is None or type(columnName) is str \
- or isinstance(columnName, WithProperties), \
- "columnName must be None, a string, or a WithProperties instance"
- self.columnName = columnName
-
- def buildStarted(self, name, build):
- builder = build.getBuilder()
- if self.builders is not None and name not in self.builders:
- return # ignore this Build
- if self.categories is not None and \
- builder.category not in self.categories:
- return # ignore this build
- self.buildMessage(name, build, "building")
-
- @defer.inlineCallbacks
- def buildMessage(self, name, build, results):
- text = ""
- res = ""
- # shortform
- t = "tinderbox:"
-
- tree = yield build.render(self.tree)
- text += "%s tree: %s\n" % (t, tree)
-
- # the start time
- # getTimes() returns a fractioned time that tinderbox doesn't understand
- builddate = int(build.getTimes()[0])
- # attempt to pull a Change time from this Build's Changes.
- # if that doesn't work, fall back on the current time
- if self.useChangeTime:
- try:
- builddate = build.getChanges()[-1].when
- except:
- pass
- text += "%s builddate: %s\n" % (t, builddate)
- text += "%s status: " % t
-
- if results == "building":
- res = "building"
- text += res
- elif results == SUCCESS:
- res = "success"
- text += res
- elif results == WARNINGS:
- res = "testfailed"
- text += res
- elif results in (EXCEPTION, RETRY):
- res = "exception"
- text += res
- else:
- res += "busted"
- text += res
-
- text += "\n";
-
- if self.columnName is None:
- # use the builder name
- text += "%s build: %s\n" % (t, name)
- else:
- columnName = yield build.render(self.columnName)
- text += "%s build: %s\n" % (t, columnName)
- text += "%s errorparser: %s\n" % (t, self.errorparser)
-
- # if the build just started...
- if results == "building":
- text += "%s END\n" % t
- # if the build finished...
- else:
- text += "%s binaryurl: %s\n" % (t, self.binaryURL)
- text += "%s logcompression: %s\n" % (t, self.logCompression)
-
- # logs will always be appended
- logEncoding = ""
- tinderboxLogs = ""
- for bs in build.getSteps():
- # Make sure that shortText is a regular string, so that bad
- # data in the logs don't generate UnicodeDecodeErrors
- shortText = "%s\n" % ' '.join(bs.getText()).encode('ascii', 'replace')
-
- # ignore steps that haven't happened
- if not re.match(".*[^\s].*", shortText):
- continue
- # we ignore TinderboxPrint's here so we can do things like:
- # ShellCommand(command=['echo', 'TinderboxPrint:', ...])
- if re.match(".+TinderboxPrint.*", shortText):
- shortText = shortText.replace("TinderboxPrint",
- "Tinderbox Print")
- logs = bs.getLogs()
-
- tinderboxLogs += "======== BuildStep started ========\n"
- tinderboxLogs += shortText
- tinderboxLogs += "=== Output ===\n"
- for log in logs:
- logText = log.getTextWithHeaders()
- # Because we pull in the log headers here we have to ignore
- # some of them. Basically, if we're TinderboxPrint'ing in
- # a ShellCommand, the only valid one(s) are at the start
- # of a line. The others are prendeded by whitespace, quotes,
- # or brackets/parentheses
- for line in logText.splitlines():
- if re.match(".+TinderboxPrint.*", line):
- line = line.replace("TinderboxPrint",
- "Tinderbox Print")
- tinderboxLogs += line + "\n"
-
- tinderboxLogs += "=== Output ended ===\n"
- tinderboxLogs += "======== BuildStep ended ========\n"
-
- if self.logCompression == "bzip2":
- cLog = bz2.compress(tinderboxLogs)
- tinderboxLogs = base64.encodestring(cLog)
- logEncoding = "base64"
- elif self.logCompression == "gzip":
- cLog = cStringIO.StringIO()
- gz = gzip.GzipFile(mode="w", fileobj=cLog)
- gz.write(tinderboxLogs)
- gz.close()
- cLog = cLog.getvalue()
- tinderboxLogs = base64.encodestring(cLog)
- logEncoding = "base64"
-
- text += "%s logencoding: %s\n" % (t, logEncoding)
- text += "%s END\n\n" % t
- text += tinderboxLogs
- text += "\n"
-
- m = Message()
- m.set_payload(text)
-
- m['Date'] = formatdate(localtime=True)
- m['Subject'] = self.subject % { 'result': res,
- 'builder': name,
- }
- m['From'] = self.fromaddr
- # m['To'] is added later
-
- d = defer.DeferredList([])
- d.addCallback(self._gotRecipients, self.extraRecipients, m)
- defer.returnValue((yield d))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py
deleted file mode 100644
index 0a5e068b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from buildbot.status.web.base import HtmlResource
-import buildbot
-import twisted
-import sys
-import jinja2
-
-class AboutBuildbot(HtmlResource):
- pageTitle = "About this Buildbot"
-
- def content(self, request, cxt):
- cxt.update(dict(buildbot=buildbot.version,
- twisted=twisted.__version__,
- jinja=jinja2.__version__,
- python=sys.version,
- platform=sys.platform))
-
- template = request.site.buildbot_service.templates.get_template("about.html")
- template.autoescape = True
- return template.render(**cxt)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py
deleted file mode 100644
index e9b168c9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os
-from zope.interface import Interface, Attribute, implements
-from buildbot.status.web.base import HtmlResource, ActionResource
-from buildbot.status.web.base import path_to_authfail
-
-from buildbot.process.users import users
-
-class IAuth(Interface):
- """
- Represent an authentication method.
-
- Note that each IAuth instance contains a link to the BuildMaster that
- will be set once the IAuth instance is initialized.
- """
-
- master = Attribute('master', "Link to BuildMaster, set when initialized")
-
- def authenticate(self, user, passwd):
- """Check whether C{user} / C{passwd} are valid."""
-
- def getUserInfo(self, user):
- """return dict with user info.
- dict( fullName="", email="", groups=[])
- """
-
- def errmsg(self):
- """Get the reason authentication failed."""
-
-class AuthBase:
- master = None # set in status.web.baseweb
- err = ""
-
- def errmsg(self):
- return self.err
-
- def getUserInfo(self, user):
- """default dummy impl"""
- return dict(userName=user, fullName=user, email=user+"@localhost", groups=[ user ])
-
-class BasicAuth(AuthBase):
- implements(IAuth)
- """Implement basic authentication against a list of user/passwd."""
-
- userpass = []
- """List of user/pass tuples."""
-
- def __init__(self, userpass):
- """C{userpass} is a list of (user, passwd)."""
- for item in userpass:
- assert isinstance(item, tuple) or isinstance(item, list)
- u, p = item
- assert isinstance(u, str)
- assert isinstance(p, str)
- self.userpass = userpass
-
- def authenticate(self, user, passwd):
- """Check that C{user}/C{passwd} is a valid user/pass tuple."""
- if not self.userpass:
- self.err = "Bad self.userpass data"
- return False
- for u, p in self.userpass:
- if user == u and passwd == p:
- self.err = ""
- return True
- self.err = "Invalid username or password"
- return False
-
-class HTPasswdAuth(AuthBase):
- implements(IAuth)
- """Implement authentication against an .htpasswd file."""
-
- file = ""
- """Path to the .htpasswd file to use."""
-
- def __init__(self, file):
- """C{file} is a path to an .htpasswd file."""
- assert os.path.exists(file)
- self.file = file
-
- def authenticate(self, user, passwd):
- """Authenticate C{user} and C{passwd} against an .htpasswd file"""
- if not os.path.exists(self.file):
- self.err = "No such file: " + self.file
- return False
- # Fetch each line from the .htpasswd file and split it into a
- # [user, passwd] array.
- lines = [l.rstrip().split(':', 1)
- for l in file(self.file).readlines()]
- # Keep only the line for this login
- lines = [l for l in lines if l[0] == user]
- if not lines:
- self.err = "Invalid user/passwd"
- return False
- hash = lines[0][1]
- res = self.validatePassword(passwd, hash)
- if res:
- self.err = ""
- else:
- self.err = "Invalid user/passwd"
- return res
-
- def validatePassword(self, passwd, hash):
- # This is the DES-hash of the password. The first two characters are
- # the salt used to introduce disorder in the DES algorithm.
- from crypt import crypt #@UnresolvedImport
- return hash == crypt(passwd, hash[0:2])
-
-
-class HTPasswdAprAuth(HTPasswdAuth):
- implements(IAuth)
- """Implement authentication against an .htpasswd file based on libaprutil"""
-
- file = ""
- """Path to the .htpasswd file to use."""
-
- def __init__(self, file):
- HTPasswdAuth.__init__(self, file)
-
- # Try to load libaprutil throug ctypes
- self.apr = None
- try:
- from ctypes import CDLL
- from ctypes.util import find_library
- lib = find_library("aprutil-1")
- if lib:
- self.apr = CDLL(lib)
- except:
- self.apr = None
-
- def validatePassword(self, passwd, hash):
- # Use apr_password_validate from libaprutil if libaprutil is available.
- # Fallback to DES only checking from HTPasswdAuth
- if self.apr:
- return self.apr.apr_password_validate(passwd, hash) == 0
- else:
- return HTPasswdAuth.validatePassword(self, passwd, hash)
-
-class UsersAuth(AuthBase):
- """Implement authentication against users in database"""
- implements(IAuth)
-
- def authenticate(self, user, passwd):
- """
- It checks for a matching uid in the database for the credentials
- and return True if a match is found, False otherwise.
-
- @param user: username portion of user credentials
- @type user: string
-
- @param passwd: password portion of user credentials
- @type passwd: string
-
- @returns: boolean via deferred.
- """
- d = self.master.db.users.getUserByUsername(user)
- def check_creds(user):
- if user:
- if users.check_passwd(passwd, user['bb_password']):
- return True
- self.err = "no user found with those credentials"
- return False
- d.addCallback(check_creds)
- return d
-
-class AuthFailResource(HtmlResource):
- pageTitle = "Authentication Failed"
-
- def content(self, request, cxt):
- templates =request.site.buildbot_service.templates
- template = templates.get_template("authfail.html")
- return template.render(**cxt)
-
-class AuthzFailResource(HtmlResource):
- pageTitle = "Authorization Failed"
-
- def content(self, request, cxt):
- templates =request.site.buildbot_service.templates
- template = templates.get_template("authzfail.html")
- return template.render(**cxt)
-
-class LoginResource(ActionResource):
-
- def performAction(self, request):
- authz = self.getAuthz(request)
- d = authz.login(request)
- def on_login(res):
- if res:
- status = request.site.buildbot_service.master.status
- root = status.getBuildbotURL()
- return request.requestHeaders.getRawHeaders('referer',
- [root])[0]
- else:
- return path_to_authfail(request)
- d.addBoth(on_login)
- return d
-
-class LogoutResource(ActionResource):
-
- def performAction(self, request):
- authz = self.getAuthz(request)
- authz.logout(request)
- status = request.site.buildbot_service.master.status
- root = status.getBuildbotURL()
- return request.requestHeaders.getRawHeaders('referer',[root])[0]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py
deleted file mode 100644
index dace7f23..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from buildbot.status.web.auth import IAuth
-from buildbot.status.web.session import SessionManager
-
-COOKIE_KEY="BuildBotSession"
-class Authz(object):
- """Decide who can do what."""
-
- knownActions = [
- # If you add a new action here, be sure to also update the documentation
- # at docs/manual/cfg-statustargets.rst.
- 'view',
- 'gracefulShutdown',
- 'forceBuild',
- 'forceAllBuilds',
- 'pingBuilder',
- 'stopBuild',
- 'stopAllBuilds',
- 'cancelPendingBuild',
- 'cancelAllPendingBuilds',
- 'stopChange',
- 'cleanShutdown',
- 'showUsersPage',
- 'pauseSlave',
- ]
-
- def __init__(self,
- default_action=False,
- auth=None,
- useHttpHeader=False,
- httpLoginUrl=False,
- view=True,
- **kwargs):
- self.auth = auth
- if auth:
- assert IAuth.providedBy(auth)
-
- self.useHttpHeader = useHttpHeader
- self.httpLoginUrl = httpLoginUrl
-
- self.config = dict((a, default_action) for a in self.knownActions)
- self.config['view'] = view
- for act in self.knownActions:
- if act in kwargs:
- self.config[act] = kwargs[act]
- del kwargs[act]
-
- self.sessions = SessionManager()
- if kwargs:
- raise ValueError("unknown authorization action(s) " + ", ".join(kwargs.keys()))
-
- def session(self, request):
- if COOKIE_KEY in request.received_cookies:
- cookie = request.received_cookies[COOKIE_KEY]
- return self.sessions.get(cookie)
- return None
-
- def authenticated(self, request):
- if self.useHttpHeader:
- return request.getUser() != ''
- return self.session(request) is not None
-
- def getUserInfo(self, user):
- if self.useHttpHeader:
- return dict(userName=user, fullName=user, email=user, groups=[user])
- s = self.sessions.getUser(user)
- if s:
- return s.infos
-
- def getUsername(self, request):
- """Get the userid of the user"""
- if self.useHttpHeader:
- return request.getUser()
- s = self.session(request)
- if s:
- return s.user
- return request.args.get("username", ["<unknown>"])[0]
-
- def getUsernameHTML(self, request):
- """Get the user formatated in html (with possible link to email)"""
- if self.useHttpHeader:
- return request.getUser()
- s = self.session(request)
- if s:
- return s.userInfosHTML()
- return "not authenticated?!"
-
- def getUsernameFull(self, request):
- """Get the full username as fullname <email>"""
- if self.useHttpHeader:
- return request.getUser()
- s = self.session(request)
- if s:
- return "%(fullName)s <%(email)s>" % (s.infos)
- else:
- return request.args.get("username", ["<unknown>"])[0]
-
-
- def getPassword(self, request):
- if self.useHttpHeader:
- return request.getPassword()
- return request.args.get("passwd", ["<no-password>"])[0]
-
- def advertiseAction(self, action, request):
- """Should the web interface even show the form for ACTION?"""
- if action not in self.knownActions:
- raise KeyError("unknown action")
- cfg = self.config.get(action, False)
- if cfg:
- if cfg == 'auth' or callable(cfg):
- return self.authenticated(request)
- return cfg
-
- def actionAllowed(self, action, request, *args):
- """Is this ACTION allowed, given this http REQUEST?"""
- if action not in self.knownActions:
- raise KeyError("unknown action")
- cfg = self.config.get(action, False)
- if cfg:
- if cfg == 'auth' or callable(cfg):
- if not self.auth:
- return defer.succeed(False)
- def check_authenticate(res):
- if callable(cfg) and not cfg(self.getUsername(request), *args):
- return False
- return True
- # retain old behaviour, if people have scripts
- # without cookie support
- passwd = self.getPassword(request)
- if self.authenticated(request):
- return defer.succeed(check_authenticate(None))
- elif passwd != "<no-password>":
- def check_login(cookie):
- ret = False
- if isinstance(cookie, str):
- ret = check_authenticate(None)
- self.sessions.remove(cookie)
- return ret
- d = self.login(request)
- d.addBoth(check_login)
- return d
- else:
- return defer.succeed(False)
- return defer.succeed(cfg)
-
- def login(self, request):
- """Login one user, and return session cookie"""
- if self.authenticated(request):
- return defer.succeed(False)
-
- user = request.args.get("username", ["<unknown>"])[0]
- passwd = request.args.get("passwd", ["<no-password>"])[0]
- if user == "<unknown>" or passwd == "<no-password>":
- return defer.succeed(False)
- if not self.auth:
- return defer.succeed(False)
- d = defer.maybeDeferred(self.auth.authenticate, user, passwd)
-
- def check_authenticate(res):
- if res:
- cookie, s = self.sessions.new(user, self.auth.getUserInfo(user))
- request.addCookie(COOKIE_KEY, cookie, expires=s.getExpiration(), path="/")
- request.received_cookies = {COOKIE_KEY: cookie}
- return cookie
- else:
- return False
- d.addBoth(check_authenticate)
- return d
-
- def logout(self, request):
- if COOKIE_KEY in request.received_cookies:
- cookie = request.received_cookies[COOKIE_KEY]
- self.sessions.remove(cookie)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py
deleted file mode 100644
index 47a3f344..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py
+++ /dev/null
@@ -1,806 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import urlparse, urllib, time, re
-import os, cgi, sys, locale
-import jinja2
-from zope.interface import Interface
-from twisted.internet import defer
-from twisted.web import resource, static, server
-from twisted.python import log
-from buildbot.status import builder, buildstep, build
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED
-from buildbot.status.results import EXCEPTION, RETRY
-from buildbot import version, util
-from buildbot.process.properties import Properties
-
-class ITopBox(Interface):
- """I represent a box in the top row of the waterfall display: the one
- which shows the status of the last build for each builder."""
- def getBox(self, request):
- """Return a Box instance, which can produce a <td> cell.
- """
-
-class ICurrentBox(Interface):
- """I represent the 'current activity' box, just above the builder name."""
- def getBox(self, status):
- """Return a Box instance, which can produce a <td> cell.
- """
-
-class IBox(Interface):
- """I represent a box in the waterfall display."""
- def getBox(self, request):
- """Return a Box instance, which wraps an Event and can produce a <td>
- cell.
- """
-
-class IHTMLLog(Interface):
- pass
-
-css_classes = {SUCCESS: "success",
- WARNINGS: "warnings",
- FAILURE: "failure",
- SKIPPED: "skipped",
- EXCEPTION: "exception",
- RETRY: "retry",
- None: "",
- }
-
-
-def getAndCheckProperties(req):
- """
- Fetch custom build properties from the HTTP request of a "Force build" or
- "Resubmit build" HTML form.
- Check the names for valid strings, and return None if a problem is found.
- Return a new Properties object containing each property found in req.
- """
- master = req.site.buildbot_service.master
- pname_validate = master.config.validation['property_name']
- pval_validate = master.config.validation['property_value']
- properties = Properties()
- i = 1
- while True:
- pname = req.args.get("property%dname" % i, [""])[0]
- pvalue = req.args.get("property%dvalue" % i, [""])[0]
- if not pname:
- break
- if not pname_validate.match(pname) \
- or not pval_validate.match(pvalue):
- log.msg("bad property name='%s', value='%s'" % (pname, pvalue))
- return None
- properties.setProperty(pname, pvalue, "Force Build Form")
- i = i + 1
-
- return properties
-
-def build_get_class(b):
- """
- Return the class to use for a finished build or buildstep,
- based on the result.
- """
- # FIXME: this getResults duplicity might need to be fixed
- result = b.getResults()
- if isinstance(b, build.BuildStatus):
- result = b.getResults()
- elif isinstance(b, buildstep.BuildStepStatus):
- result = b.getResults()[0]
- # after forcing a build, b.getResults() returns ((None, []), []), ugh
- if isinstance(result, tuple):
- result = result[0]
- else:
- raise TypeError, "%r is not a BuildStatus or BuildStepStatus" % b
-
- if result == None:
- # FIXME: this happens when a buildstep is running ?
- return "running"
- return builder.Results[result]
-
-def path_to_root(request):
- # /waterfall : ['waterfall'] -> './'
- # /somewhere/lower : ['somewhere', 'lower'] -> '../'
- # /somewhere/indexy/ : ['somewhere', 'indexy', ''] -> '../../'
- # / : [] -> './'
- if request.prepath:
- segs = len(request.prepath) - 1
- else:
- segs = 0
- root = "../" * segs if segs else './'
- return root
-
-def path_to_authfail(request):
- return path_to_root(request) + "authfail"
-
-def path_to_authzfail(request):
- return path_to_root(request) + "authzfail"
-
-def path_to_builder(request, builderstatus):
- return (path_to_root(request) +
- "builders/" +
- urllib.quote(builderstatus.getName(), safe=''))
-
-def path_to_build(request, buildstatus):
- return (path_to_builder(request, buildstatus.getBuilder()) +
- "/builds/%d" % buildstatus.getNumber())
-
-def path_to_step(request, stepstatus):
- return (path_to_build(request, stepstatus.getBuild()) +
- "/steps/%s" % urllib.quote(stepstatus.getName(), safe=''))
-
-def path_to_slave(request, slave):
- return (path_to_root(request) +
- "buildslaves/" +
- urllib.quote(slave.getName(), safe=''))
-
-def path_to_change(request, change):
- return (path_to_root(request) +
- "changes/%s" % change.number)
-
-class Box:
- # a Box wraps an Event. The Box has HTML <td> parameters that Events
- # lack, and it has a base URL to which each File's name is relative.
- # Events don't know about HTML.
- spacer = False
- def __init__(self, text=[], class_=None, urlbase=None,
- **parms):
- self.text = text
- self.class_ = class_
- self.urlbase = urlbase
- self.show_idle = 0
- if parms.has_key('show_idle'):
- del parms['show_idle']
- self.show_idle = 1
-
- self.parms = parms
- # parms is a dict of HTML parameters for the <td> element that will
- # represent this Event in the waterfall display.
-
- def td(self, **props):
- props.update(self.parms)
- text = self.text
- if not text and self.show_idle:
- text = ["[idle]"]
- props['class'] = self.class_
- props['text'] = text;
- return props
-
-
-class AccessorMixin(object):
- def getStatus(self, request):
- return request.site.buildbot_service.getStatus()
-
- def getPageTitle(self, request):
- return self.pageTitle
-
- def getAuthz(self, request):
- return request.site.buildbot_service.authz
-
- def getBuildmaster(self, request):
- return request.site.buildbot_service.master
-
-
-class ContextMixin(AccessorMixin):
- def getContext(self, request):
- status = self.getStatus(request)
- rootpath = path_to_root(request)
- locale_enc = locale.getdefaultlocale()[1]
- if locale_enc is not None:
- locale_tz = unicode(time.tzname[time.localtime()[-1]], locale_enc)
- else:
- locale_tz = unicode(time.tzname[time.localtime()[-1]])
- return dict(title_url = status.getTitleURL(),
- title = status.getTitle(),
- stylesheet = rootpath + 'default.css',
- path_to_root = rootpath,
- version = version,
- time = time.strftime("%a %d %b %Y %H:%M:%S",
- time.localtime(util.now())),
- tz = locale_tz,
- metatags = [],
- pageTitle = self.getPageTitle(request),
- welcomeurl = rootpath,
- authz = self.getAuthz(request),
- request = request,
- alert_msg = request.args.get("alert_msg", [""])[0],
- )
-
-
-class ActionResource(resource.Resource, AccessorMixin):
- """A resource that performs some action, then redirects to a new URL."""
-
- isLeaf = 1
-
- def getChild(self, name, request):
- return self
-
- def performAction(self, request):
- """
- Perform the action, and return the URL to redirect to
-
- @param request: the web request
- @returns: URL via Deferred
- can also return (URL, alert_msg) to display simple
- feedback to user in case of failure
- """
-
- def render(self, request):
- d = defer.maybeDeferred(lambda : self.performAction(request))
- def redirect(url):
- if isinstance(url, tuple):
- url, alert_msg = url
- if alert_msg:
- url += "?alert_msg="+urllib.quote(alert_msg, safe='')
- request.redirect(url)
- request.write("see <a href='%s'>%s</a>" % (url,url))
- try:
- request.finish()
- except RuntimeError:
- # this occurs when the client has already disconnected; ignore
- # it (see #2027)
- log.msg("http client disconnected before results were sent")
- d.addCallback(redirect)
-
- def fail(f):
- request.processingFailed(f)
- return None # processingFailed will log this for us
- d.addErrback(fail)
- return server.NOT_DONE_YET
-
-class HtmlResource(resource.Resource, ContextMixin):
- # this is a cheap sort of template thingy
- contentType = "text/html; charset=utf-8"
- pageTitle = "Buildbot"
- addSlash = False # adapted from Nevow
-
- def getChild(self, path, request):
- if self.addSlash and path == "" and len(request.postpath) == 0:
- return self
- return resource.Resource.getChild(self, path, request)
-
-
- def content(self, req, context):
- """
- Generate content using the standard layout and the result of the C{body}
- method.
-
- This is suitable for the case where a resource just wants to generate
- the body of a page. It depends on another method, C{body}, being
- defined to accept the request object and return a C{str}. C{render}
- will call this method and to generate the response body.
- """
- body = self.body(req)
- context['content'] = body
- template = req.site.buildbot_service.templates.get_template(
- "empty.html")
- return template.render(**context)
-
-
- def render(self, request):
- # tell the WebStatus about the HTTPChannel that got opened, so they
- # can close it if we get reconfigured and the WebStatus goes away.
- # They keep a weakref to this, since chances are good that it will be
- # closed by the browser or by us before we get reconfigured. See
- # ticket #102 for details.
- if hasattr(request, "channel"):
- # web.distrib.Request has no .channel
- request.site.buildbot_service.registerChannel(request.channel)
-
- # Our pages no longer require that their URL end in a slash. Instead,
- # they all use request.childLink() or some equivalent which takes the
- # last path component into account. This clause is left here for
- # historical and educational purposes.
- if False and self.addSlash and request.prepath[-1] != '':
- # this is intended to behave like request.URLPath().child('')
- # but we need a relative URL, since we might be living behind a
- # reverse proxy
- #
- # note that the Location: header (as used in redirects) are
- # required to have absolute URIs, and my attempt to handle
- # reverse-proxies gracefully violates rfc2616. This frequently
- # works, but single-component paths sometimes break. The best
- # strategy is to avoid these redirects whenever possible by using
- # HREFs with trailing slashes, and only use the redirects for
- # manually entered URLs.
- url = request.prePathURL()
- scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
- new_url = request.prepath[-1] + "/"
- if query:
- new_url += "?" + query
- request.redirect(new_url)
- return ''
-
- ctx = self.getContext(request)
-
- d = defer.maybeDeferred(lambda : self.content(request, ctx))
- def handle(data):
- request.setHeader("X-Clacks-Overhead", 'GNU N%C3%B3ir%C3%ADn Plunkett')
- if isinstance(data, unicode):
- data = data.encode("utf-8")
- request.setHeader("content-type", self.contentType)
- if request.method == "HEAD":
- request.setHeader("content-length", len(data))
- return ''
- return data
- d.addCallback(handle)
- def ok(data):
- request.write(data)
- try:
- request.finish()
- except RuntimeError:
- # this occurs when the client has already disconnected; ignore
- # it (see #2027)
- log.msg("http client disconnected before results were sent")
- def fail(f):
- request.processingFailed(f)
- return None # processingFailed will log this for us
- d.addCallbacks(ok, fail)
- return server.NOT_DONE_YET
-
-class StaticHTML(HtmlResource):
- def __init__(self, body, pageTitle):
- HtmlResource.__init__(self)
- self.bodyHTML = body
- self.pageTitle = pageTitle
- def content(self, request, cxt):
- cxt['content'] = self.bodyHTML
- cxt['pageTitle'] = self.pageTitle
- template = request.site.buildbot_service.templates.get_template("empty.html")
- return template.render(**cxt)
-
-class DirectoryLister(static.DirectoryLister, ContextMixin):
- """This variant of the static.DirectoryLister uses a template
- for rendering."""
-
- pageTitle = 'BuildBot'
-
- def render(self, request):
- cxt = self.getContext(request)
-
- if self.dirs is None:
- directory = os.listdir(self.path)
- directory.sort()
- else:
- directory = self.dirs
-
- dirs, files = self._getFilesAndDirectories(directory)
-
- cxt['path'] = cgi.escape(urllib.unquote(request.uri))
- cxt['directories'] = dirs
- cxt['files'] = files
- template = request.site.buildbot_service.templates.get_template("directory.html")
- data = template.render(**cxt)
- if isinstance(data, unicode):
- data = data.encode("utf-8")
- return data
-
-class StaticFile(static.File):
- """This class adds support for templated directory
- views."""
-
- def directoryListing(self):
- return DirectoryLister(self.path,
- self.listNames(),
- self.contentTypes,
- self.contentEncodings,
- self.defaultType)
-
-
-MINUTE = 60
-HOUR = 60*MINUTE
-DAY = 24*HOUR
-WEEK = 7*DAY
-MONTH = 30*DAY
-
-def plural(word, words, num):
- if int(num) == 1:
- return "%d %s" % (num, word)
- else:
- return "%d %s" % (num, words)
-
-def abbreviate_age(age):
- if age <= 90:
- return "%s ago" % plural("second", "seconds", age)
- if age < 90*MINUTE:
- return "about %s ago" % plural("minute", "minutes", age / MINUTE)
- if age < DAY:
- return "about %s ago" % plural("hour", "hours", age / HOUR)
- if age < 2*WEEK:
- return "about %s ago" % plural("day", "days", age / DAY)
- if age < 2*MONTH:
- return "about %s ago" % plural("week", "weeks", age / WEEK)
- return "a long time ago"
-
-
-class BuildLineMixin:
- LINE_TIME_FORMAT = "%b %d %H:%M"
-
- def get_line_values(self, req, build, include_builder=True):
- '''
- Collect the data needed for each line display
- '''
- builder_name = build.getBuilder().getName()
- results = build.getResults()
- text = build.getText()
- all_got_revision = build.getAllGotRevisions()
- css_class = css_classes.get(results, "")
- ss_list = build.getSourceStamps()
- if ss_list:
- repo = ss_list[0].repository
- if all_got_revision:
- if len(ss_list) == 1:
- rev = all_got_revision.get(ss_list[0].codebase, "??")
- else:
- rev = "multiple rev."
- else:
- rev = "??"
- else:
- repo = 'unknown, no information in build'
- rev = 'unknown'
-
- if type(text) == list:
- text = " ".join(text)
-
- values = {'class': css_class,
- 'builder_name': builder_name,
- 'buildnum': build.getNumber(),
- 'results': css_class,
- 'text': " ".join(build.getText()),
- 'buildurl': path_to_build(req, build),
- 'builderurl': path_to_builder(req, build.getBuilder()),
- 'rev': rev,
- 'rev_repo' : repo,
- 'time': time.strftime(self.LINE_TIME_FORMAT,
- time.localtime(build.getTimes()[0])),
- 'text': text,
- 'include_builder': include_builder
- }
- return values
-
-def map_branches(branches):
- # when the query args say "trunk", present that to things like
- # IBuilderStatus.generateFinishedBuilds as None, since that's the
- # convention in use. But also include 'trunk', because some VC systems
- # refer to it that way. In the long run we should clean this up better,
- # maybe with Branch objects or something.
- if "trunk" in branches:
- return branches + [None]
- return branches
-
-
-# jinja utilities
-
-def createJinjaEnv(revlink=None, changecommentlink=None,
- repositories=None, projects=None, jinja_loaders=None):
- ''' Create a jinja environment changecommentlink is used to
- render HTML in the WebStatus and for mail changes
-
- @type changecommentlink: C{None}, tuple (2 or 3 strings), dict (string -> 2- or 3-tuple) or callable
- @param changecommentlink: see changelinkfilter()
-
- @type revlink: C{None}, format-string, dict (repository -> format string) or callable
- @param revlink: see revlinkfilter()
-
- @type repositories: C{None} or dict (string -> url)
- @param repositories: an (optinal) mapping from repository identifiers
- (as given by Change sources) to URLs. Is used to create a link
- on every place where a repository is listed in the WebStatus.
-
- @type projects: C{None} or dict (string -> url)
- @param projects: similar to repositories, but for projects.
- '''
-
- # See http://buildbot.net/trac/ticket/658
- assert not hasattr(sys, "frozen"), 'Frozen config not supported with jinja (yet)'
-
- all_loaders = [jinja2.FileSystemLoader(os.path.join(os.getcwd(), 'templates'))]
- if jinja_loaders:
- all_loaders.extend(jinja_loaders)
- all_loaders.append(jinja2.PackageLoader('buildbot.status.web', 'templates'))
- loader = jinja2.ChoiceLoader(all_loaders)
-
- env = jinja2.Environment(loader=loader,
- extensions=['jinja2.ext.i18n'],
- trim_blocks=True,
- undefined=AlmostStrictUndefined)
-
- env.install_null_translations() # needed until we have a proper i18n backend
-
- env.tests['mapping'] = lambda obj : isinstance(obj, dict)
-
- env.filters.update(dict(
- urlencode = urllib.quote,
- email = emailfilter,
- user = userfilter,
- shortrev = shortrevfilter(revlink, env),
- revlink = revlinkfilter(revlink, env),
- changecomment = changelinkfilter(changecommentlink),
- repolink = dictlinkfilter(repositories),
- projectlink = dictlinkfilter(projects)
- ))
-
- return env
-
-def emailfilter(value):
- ''' Escape & obfuscate e-mail addresses
-
- replacing @ with <span style="display:none> reportedly works well against web-spiders
- and the next level is to use rot-13 (or something) and decode in javascript '''
-
- user = jinja2.escape(value)
- obfuscator = jinja2.Markup('<span style="display:none">ohnoyoudont</span>@')
- output = user.replace('@', obfuscator)
- return output
-
-
-def userfilter(value):
- ''' Hide e-mail address from user name when viewing changes
-
- We still include the (obfuscated) e-mail so that we can show
- it on mouse-over or similar etc
- '''
- r = re.compile('(.*) +<(.*)>')
- m = r.search(value)
- if m:
- user = jinja2.escape(m.group(1))
- email = emailfilter(m.group(2))
- return jinja2.Markup('<div class="user">%s<div class="email">%s</div></div>' % (user, email))
- else:
- return emailfilter(value) # filter for emails here for safety
-
-def _revlinkcfg(replace, templates):
- '''Helper function that returns suitable macros and functions
- for building revision links depending on replacement mechanism
-'''
-
- assert not replace or callable(replace) or isinstance(replace, dict) or \
- isinstance(replace, str) or isinstance(replace, unicode)
-
- if not replace:
- return lambda rev, repo: None
- else:
- if callable(replace):
- return lambda rev, repo: replace(rev, repo)
- elif isinstance(replace, dict): # TODO: test for [] instead
- def filter(rev, repo):
- url = replace.get(repo)
- if url:
- return url % urllib.quote(rev)
- else:
- return None
-
- return filter
- else:
- return lambda rev, repo: replace % urllib.quote(rev)
-
- assert False, '_replace has a bad type, but we should never get here'
-
-
-def _revlinkmacros(replace, templates):
- '''return macros for use with revision links, depending
- on whether revlinks are configured or not'''
-
- macros = templates.get_template("revmacros.html").module
-
- if not replace:
- id = macros.id
- short = macros.shorten
- else:
- id = macros.id_replace
- short = macros.shorten_replace
-
- return (id, short)
-
-
-def shortrevfilter(replace, templates):
- ''' Returns a function which shortens the revisison string
- to 12-chars (chosen as this is the Mercurial short-id length)
- and add link if replacement string is set.
-
- (The full id is still visible in HTML, for mouse-over events etc.)
-
- @param replace: see revlinkfilter()
- @param templates: a jinja2 environment
- '''
-
- url_f = _revlinkcfg(replace, templates)
-
- def filter(rev, repo):
- if not rev:
- return u''
-
- id_html, short_html = _revlinkmacros(replace, templates)
- rev = unicode(rev)
- url = url_f(rev, repo)
- rev = jinja2.escape(rev)
- shortrev = rev[:12] # TODO: customize this depending on vc type
-
- if shortrev == rev:
- if url:
- return id_html(rev=rev, url=url)
- else:
- return rev
- else:
- if url:
- return short_html(short=shortrev, rev=rev, url=url)
- else:
- return shortrev + '...'
-
- return filter
-
-
-def revlinkfilter(replace, templates):
- ''' Returns a function which adds an url link to a
- revision identifiers.
-
- Takes same params as shortrevfilter()
-
- @param replace: either a python format string with an %s,
- or a dict mapping repositories to format strings,
- or a callable taking (revision, repository) arguments
- and return an URL (or None, if no URL is available),
- or None, in which case revisions do not get decorated
- with links
-
- @param templates: a jinja2 environment
- '''
-
- url_f = _revlinkcfg(replace, templates)
-
- def filter(rev, repo):
- if not rev:
- return u''
-
- rev = unicode(rev)
- url = url_f(rev, repo)
- if url:
- id_html, _ = _revlinkmacros(replace, templates)
- return id_html(rev=rev, url=url)
- else:
- return jinja2.escape(rev)
-
- return filter
-
-
-def changelinkfilter(changelink):
- ''' Returns function that does regex search/replace in
- comments to add links to bug ids and similar.
-
- @param changelink:
- Either C{None}
- or: a tuple (2 or 3 elements)
- 1. a regex to match what we look for
- 2. an url with regex refs (\g<0>, \1, \2, etc) that becomes the 'href' attribute
- 3. (optional) an title string with regex ref regex
- or: a dict mapping projects to above tuples
- (no links will be added if the project isn't found)
- or: a callable taking (changehtml, project) args
- (where the changetext is HTML escaped in the
- form of a jinja2.Markup instance) and
- returning another jinja2.Markup instance with
- the same change text plus any HTML tags added to it.
- '''
-
- assert not changelink or isinstance(changelink, dict) or \
- isinstance(changelink, tuple) or callable(changelink)
-
- def replace_from_tuple(t):
- search, url_replace = t[:2]
- if len(t) == 3:
- title_replace = t[2]
- else:
- title_replace = ''
-
- search_re = re.compile(search)
-
- def replacement_unmatched(text):
- return jinja2.escape(text)
- def replacement_matched(mo):
- # expand things *after* application of the regular expressions
- url = jinja2.escape(mo.expand(url_replace))
- title = jinja2.escape(mo.expand(title_replace))
- body = jinja2.escape(mo.group())
- if title:
- return '<a href="%s" title="%s">%s</a>' % (url, title, body)
- else:
- return '<a href="%s">%s</a>' % (url, body)
-
- def filter(text, project):
- # now, we need to split the string into matched and unmatched portions,
- # quoting the unmatched portions directly and quoting the components of
- # the 'a' element for the matched portions. We can't use re.split here,
- # because the user-supplied patterns may have multiple groups.
- html = []
- last_idx = 0
- for mo in search_re.finditer(text):
- html.append(replacement_unmatched(text[last_idx:mo.start()]))
- html.append(replacement_matched(mo))
- last_idx = mo.end()
- html.append(replacement_unmatched(text[last_idx:]))
- return jinja2.Markup(''.join(html))
-
- return filter
-
- if not changelink:
- return lambda text, project: jinja2.escape(text)
-
- elif isinstance(changelink, dict):
- def dict_filter(text, project):
- # TODO: Optimize and cache return value from replace_from_tuple so
- # we only compile regex once per project, not per view
-
- t = changelink.get(project)
- if t:
- return replace_from_tuple(t)(text, project)
- else:
- return cgi.escape(text)
-
- return dict_filter
-
- elif isinstance(changelink, tuple):
- return replace_from_tuple(changelink)
-
- elif callable(changelink):
- def callable_filter(text, project):
- text = jinja2.escape(text)
- return changelink(text, project)
-
- return callable_filter
-
- assert False, 'changelink has unsupported type, but that is checked before'
-
-
-def dictlinkfilter(links):
- '''A filter that encloses the given value in a link tag
- given that the value exists in the dictionary'''
-
- assert not links or callable(links) or isinstance(links, dict)
-
- if not links:
- return jinja2.escape
-
- def filter(key):
- if callable(links):
- url = links(key)
- else:
- url = links.get(key)
-
- safe_key = jinja2.escape(key)
-
- if url:
- return jinja2.Markup(r'<a href="%s">%s</a>' % (url, safe_key))
- else:
- return safe_key
-
- return filter
-
-class AlmostStrictUndefined(jinja2.StrictUndefined):
- ''' An undefined that allows boolean testing but
- fails properly on every other use.
-
- Much better than the default Undefined, but not
- fully as strict as StrictUndefined '''
- def __nonzero__(self):
- return False
-
-_charsetRe = re.compile('charset=([^;]*)', re.I)
-def getRequestCharset(req):
- """Get the charset for an x-www-form-urlencoded request"""
- # per http://stackoverflow.com/questions/708915/detecting-the-character-encoding-of-an-http-post-request
- hdr = req.getHeader('Content-Type')
- if hdr:
- mo = _charsetRe.search(hdr)
- if mo:
- return mo.group(1).strip()
- return 'utf-8' # reasonable guess, works for ascii
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py
deleted file mode 100644
index 9fe5e7fc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py
+++ /dev/null
@@ -1,607 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os, weakref
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.application import strports, service
-from twisted.internet import defer
-from twisted.web import server, distrib, static
-from twisted.spread import pb
-from twisted.web.util import Redirect
-from buildbot import config
-from buildbot.interfaces import IStatusReceiver
-from buildbot.status.web.base import StaticFile, createJinjaEnv
-from buildbot.status.web.feeds import Rss20StatusResource, \
- Atom10StatusResource
-from buildbot.status.web.waterfall import WaterfallStatusResource
-from buildbot.status.web.console import ConsoleStatusResource
-from buildbot.status.web.olpb import OneLinePerBuild
-from buildbot.status.web.grid import GridStatusResource
-from buildbot.status.web.grid import TransposedGridStatusResource
-from buildbot.status.web.changes import ChangesResource
-from buildbot.status.web.builder import BuildersResource
-from buildbot.status.web.buildstatus import BuildStatusStatusResource
-from buildbot.status.web.slaves import BuildSlavesResource
-from buildbot.status.web.status_json import JsonStatusResource
-from buildbot.status.web.about import AboutBuildbot
-from buildbot.status.web.authz import Authz
-from buildbot.status.web.auth import AuthFailResource,AuthzFailResource, LoginResource, LogoutResource
-from buildbot.status.web.root import RootPage
-from buildbot.status.web.users import UsersResource
-from buildbot.status.web.change_hook import ChangeHookResource
-from twisted.cred.portal import IRealm, Portal
-from twisted.cred import strcred
-from twisted.cred.checkers import ICredentialsChecker
-from twisted.cred.credentials import IUsernamePassword
-from twisted.web import resource, guard
-
-# this class contains the WebStatus class. Basic utilities are in base.py,
-# and specific pages are each in their own module.
-
-class WebStatus(service.MultiService):
- implements(IStatusReceiver)
- # TODO: IStatusReceiver is really about things which subscribe to hear
- # about buildbot events. We need a different interface (perhaps a parent
- # of IStatusReceiver) for status targets that don't subscribe, like the
- # WebStatus class. buildbot.master.BuildMaster.loadConfig:737 asserts
- # that everything in c['status'] provides IStatusReceiver, but really it
- # should check that they provide IStatusTarget instead.
-
- """
- The webserver provided by this class has the following resources:
-
- /waterfall : the big time-oriented 'waterfall' display, with links
- to individual changes, builders, builds, steps, and logs.
- A number of query-arguments can be added to influence
- the display.
- /rss : a rss feed summarizing all failed builds. The same
- query-arguments used by 'waterfall' can be added to
- influence the feed output.
- /atom : an atom feed summarizing all failed builds. The same
- query-arguments used by 'waterfall' can be added to
- influence the feed output.
- /grid : another summary display that shows a grid of builds, with
- sourcestamps on the x axis, and builders on the y. Query
- arguments similar to those for the waterfall can be added.
- /tgrid : similar to the grid display, but the commits are down the
- left side, and the build hosts are across the top.
- /builders/BUILDERNAME: a page summarizing the builder. This includes
- references to the Schedulers that feed it,
- any builds currently in the queue, which
- buildslaves are designated or attached, and a
- summary of the build process it uses.
- /builders/BUILDERNAME/builds/NUM: a page describing a single Build
- /builders/BUILDERNAME/builds/NUM/steps/STEPNAME: describes a single step
- /builders/BUILDERNAME/builds/NUM/steps/STEPNAME/logs/LOGNAME: a StatusLog
- /builders/_all/{force,stop}: force a build/stop building on all builders.
- /buildstatus?builder=...&number=...: an embedded iframe for the console
- /changes : summarize all ChangeSources
- /changes/CHANGENUM: a page describing a single Change
- /buildslaves : list all BuildSlaves
- /buildslaves/SLAVENAME : describe a single BuildSlave
- /one_line_per_build : summarize the last few builds, one line each
- /one_line_per_build/BUILDERNAME : same, but only for a single builder
- /about : describe this buildmaster (Buildbot and support library versions)
- /change_hook[/DIALECT] : accepts changes from external sources, optionally
- choosing the dialect that will be permitted
- (i.e. github format, etc..)
-
- and more! see the manual.
-
-
- All URLs for pages which are not defined here are used to look
- for files in PUBLIC_HTML, which defaults to BASEDIR/public_html.
- This means that /robots.txt or /favicon.ico can be placed in
- that directory
-
- This webserver uses the jinja2 template system to generate the web pages
- (see http://jinja.pocoo.org/2/) and by default loads pages from the
- buildbot.status.web.templates package. Any file here can be overridden by placing
- a corresponding file in the master's 'templates' directory.
-
- The main customization points are layout.html which loads style sheet
- (css) and provides header and footer content, and root.html, which
- generates the root page.
-
- All of the resources provided by this service use relative URLs to reach
- each other. The only absolute links are the c['titleURL'] links at the
- top and bottom of the page, and the buildbot home-page link at the
- bottom.
-
- Buildbot uses some generic classes to identify the type of object, and
- some more specific classes for the various kinds of those types. It does
- this by specifying both in the class attributes where applicable,
- separated by a space. It is important that in your CSS you declare the
- more generic class styles above the more specific ones. For example,
- first define a style for .Event, and below that for .SUCCESS
-
- The following CSS class names are used:
- - Activity, Event, BuildStep, LastBuild: general classes
- - waiting, interlocked, building, offline, idle: Activity states
- - start, running, success, failure, warnings, skipped, exception:
- LastBuild and BuildStep states
- - Change: box with change
- - Builder: box for builder name (at top)
- - Project
- - Time
-
- """
-
- # we are not a ComparableMixin, and therefore the webserver will be
- # rebuilt every time we reconfig. This is because WebStatus.putChild()
- # makes it too difficult to tell whether two instances are the same or
- # not (we'd have to do a recursive traversal of all children to discover
- # all the changes).
-
- def __init__(self, http_port=None, distrib_port=None, allowForce=None,
- public_html="public_html", site=None, numbuilds=20,
- num_events=200, num_events_max=None, auth=None,
- order_console_by_time=False, changecommentlink=None,
- revlink=None, projects=None, repositories=None,
- authz=None, logRotateLength=None, maxRotatedFiles=None,
- change_hook_dialects = {}, provide_feeds=None, jinja_loaders=None,
- change_hook_auth=None):
- """Run a web server that provides Buildbot status.
-
- @type http_port: int or L{twisted.application.strports} string
- @param http_port: a strports specification describing which port the
- buildbot should use for its web server, with the
- Waterfall display as the root page. For backwards
- compatibility this can also be an int. Use
- 'tcp:8000' to listen on that port, or
- 'tcp:12345:interface=127.0.0.1' if you only want
- local processes to connect to it (perhaps because
- you are using an HTTP reverse proxy to make the
- buildbot available to the outside world, and do not
- want to make the raw port visible).
-
- @type distrib_port: int or L{twisted.application.strports} string
- @param distrib_port: Use this if you want to publish the Waterfall
- page using web.distrib instead. The most common
- case is to provide a string that is an absolute
- pathname to the unix socket on which the
- publisher should listen
- (C{os.path.expanduser(~/.twistd-web-pb)} will
- match the default settings of a standard
- twisted.web 'personal web server'). Another
- possibility is to pass an integer, which means
- the publisher should listen on a TCP socket,
- allowing the web server to be on a different
- machine entirely. Both forms are provided for
- backwards compatibility; the preferred form is a
- strports specification like
- 'unix:/home/buildbot/.twistd-web-pb'. Providing
- a non-absolute pathname will probably confuse
- the strports parser.
-
- @param allowForce: deprecated; use authz instead
- @param auth: deprecated; use with authz
-
- @param authz: a buildbot.status.web.authz.Authz instance giving the authorization
- parameters for this view
-
- @param public_html: the path to the public_html directory for this display,
- either absolute or relative to the basedir. The default
- is 'public_html', which selects BASEDIR/public_html.
-
- @type site: None or L{twisted.web.server.Site}
- @param site: Use this if you want to define your own object instead of
- using the default.`
-
- @type numbuilds: int
- @param numbuilds: Default number of entries in lists at the /one_line_per_build
- and /builders/FOO URLs. This default can be overriden both programatically ---
- by passing the equally named argument to constructors of OneLinePerBuildOneBuilder
- and OneLinePerBuild --- and via the UI, by tacking ?numbuilds=xy onto the URL.
-
- @type num_events: int
- @param num_events: Default number of events to show in the waterfall.
-
- @type num_events_max: int
- @param num_events_max: The maximum number of events that are allowed to be
- shown in the waterfall. The default value of C{None} will disable this
- check
-
- @type auth: a L{status.web.auth.IAuth} or C{None}
- @param auth: an object that performs authentication to restrict access
- to the C{allowForce} features. Ignored if C{allowForce}
- is not C{True}. If C{auth} is C{None}, people can force or
- stop builds without auth.
-
- @type order_console_by_time: bool
- @param order_console_by_time: Whether to order changes (commits) in the console
- view according to the time they were created (for VCS like Git) or
- according to their integer revision numbers (for VCS like SVN).
-
- @type changecommentlink: callable, dict, tuple (2 or 3 strings) or C{None}
- @param changecommentlink: adds links to ticket/bug ids in change comments,
- see buildbot.status.web.base.changecommentlink for details
-
- @type revlink: callable, dict, string or C{None}
- @param revlink: decorations revision ids with links to a web-view,
- see buildbot.status.web.base.revlink for details
-
- @type projects: callable, dict or c{None}
- @param projects: maps project identifiers to URLs, so that any project listed
- is automatically decorated with a link to it's front page.
- see buildbot.status.web.base.dictlink for details
-
- @type repositories: callable, dict or c{None}
- @param repositories: maps repository identifiers to URLs, so that any project listed
- is automatically decorated with a link to it's web view.
- see buildbot.status.web.base.dictlink for details
-
- @type logRotateLength: None or int
- @param logRotateLength: file size at which the http.log is rotated/reset.
- If not set, the value set in the buildbot.tac will be used,
- falling back to the BuildMaster's default value (1 Mb).
-
- @type maxRotatedFiles: None or int
- @param maxRotatedFiles: number of old http.log files to keep during log rotation.
- If not set, the value set in the buildbot.tac will be used,
- falling back to the BuildMaster's default value (10 files).
-
- @type change_hook_dialects: None or dict
- @param change_hook_dialects: If empty, disables change_hook support, otherwise
- whitelists valid dialects. In the format of
- {"dialect1": "Option1", "dialect2", None}
- Where the values are options that will be passed
- to the dialect
-
- To enable the DEFAULT handler, use a key of DEFAULT
-
-
-
-
- @type provide_feeds: None or list
- @param provide_feeds: If empty, provides atom, json, and rss feeds.
- Otherwise, a dictionary of strings of
- the type of feeds provided. Current
- possibilities are "atom", "json", and "rss"
-
- @type jinja_loaders: None or list
- @param jinja_loaders: If not empty, a list of additional Jinja2 loader
- objects to search for templates.
- """
-
- service.MultiService.__init__(self)
- if type(http_port) is int:
- http_port = "tcp:%d" % http_port
- self.http_port = http_port
- if distrib_port is not None:
- if type(distrib_port) is int:
- distrib_port = "tcp:%d" % distrib_port
- if distrib_port[0] in "/~.": # pathnames
- distrib_port = "unix:%s" % distrib_port
- self.distrib_port = distrib_port
- self.num_events = num_events
- if num_events_max:
- if num_events_max < num_events:
- config.error(
- "num_events_max must be greater than num_events")
- self.num_events_max = num_events_max
- self.public_html = public_html
-
- # make up an authz if allowForce was given
- if authz:
- if allowForce is not None:
- config.error(
- "cannot use both allowForce and authz parameters")
- if auth:
- config.error(
- "cannot use both auth and authz parameters (pass " +
- "auth as an Authz parameter)")
- else:
- # invent an authz
- if allowForce and auth:
- authz = Authz(auth=auth, default_action="auth")
- elif allowForce:
- authz = Authz(default_action=True)
- else:
- if auth:
- log.msg("Warning: Ignoring authentication. Search for 'authorization'"
- " in the manual")
- authz = Authz() # no authorization for anything
-
- self.authz = authz
-
- # check for correctness of HTTP auth parameters
- if change_hook_auth is not None:
- self.change_hook_auth = []
- for checker in change_hook_auth:
- if isinstance(checker, str):
- try:
- checker = strcred.makeChecker(checker)
- except Exception, error:
- config.error("Invalid change_hook checker description: %s" % (error,))
- continue
- elif not ICredentialsChecker.providedBy(checker):
- config.error("change_hook checker doesn't provide ICredentialChecker: %r" % (checker,))
- continue
-
- if IUsernamePassword not in checker.credentialInterfaces:
- config.error("change_hook checker doesn't support IUsernamePassword: %r" % (checker,))
- continue
-
- self.change_hook_auth.append(checker)
- else:
- self.change_hook_auth = None
-
- self.orderConsoleByTime = order_console_by_time
-
- # If we were given a site object, go ahead and use it. (if not, we add one later)
- self.site = site
-
- # keep track of our child services
- self.http_svc = None
- self.distrib_svc = None
-
- # store the log settings until we create the site object
- self.logRotateLength = logRotateLength
- self.maxRotatedFiles = maxRotatedFiles
-
- # create the web site page structure
- self.childrenToBeAdded = {}
- self.setupUsualPages(numbuilds=numbuilds, num_events=num_events,
- num_events_max=num_events_max)
-
- self.revlink = revlink
- self.changecommentlink = changecommentlink
- self.repositories = repositories
- self.projects = projects
-
- # keep track of cached connections so we can break them when we shut
- # down. See ticket #102 for more details.
- self.channels = weakref.WeakKeyDictionary()
-
- # do we want to allow change_hook
- self.change_hook_dialects = {}
- if change_hook_dialects:
- self.change_hook_dialects = change_hook_dialects
- resource_obj = ChangeHookResource(dialects=self.change_hook_dialects)
- if self.change_hook_auth is not None:
- resource_obj = self.setupProtectedResource(
- resource_obj, self.change_hook_auth)
- self.putChild("change_hook", resource_obj)
-
- # Set default feeds
- if provide_feeds is None:
- self.provide_feeds = ["atom", "json", "rss"]
- else:
- self.provide_feeds = provide_feeds
-
- self.jinja_loaders = jinja_loaders
-
- def setupProtectedResource(self, resource_obj, checkers):
- class SimpleRealm(object):
- """
- A realm which gives out L{ChangeHookResource} instances for authenticated
- users.
- """
- implements(IRealm)
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if resource.IResource in interfaces:
- return (resource.IResource, resource_obj, lambda: None)
- raise NotImplementedError()
-
- portal = Portal(SimpleRealm(), checkers)
- credentialFactory = guard.BasicCredentialFactory('Protected area')
- wrapper = guard.HTTPAuthSessionWrapper(portal, [credentialFactory])
- return wrapper
-
- def setupUsualPages(self, numbuilds, num_events, num_events_max):
- #self.putChild("", IndexOrWaterfallRedirection())
- self.putChild("waterfall", WaterfallStatusResource(num_events=num_events,
- num_events_max=num_events_max))
- self.putChild("grid", GridStatusResource())
- self.putChild("console", ConsoleStatusResource(
- orderByTime=self.orderConsoleByTime))
- self.putChild("tgrid", TransposedGridStatusResource())
- self.putChild("builders", BuildersResource(numbuilds=numbuilds)) # has builds/steps/logs
- self.putChild("one_box_per_builder", Redirect("builders"))
- self.putChild("changes", ChangesResource())
- self.putChild("buildslaves", BuildSlavesResource())
- self.putChild("buildstatus", BuildStatusStatusResource())
- self.putChild("one_line_per_build",
- OneLinePerBuild(numbuilds=numbuilds))
- self.putChild("about", AboutBuildbot())
- self.putChild("authfail", AuthFailResource())
- self.putChild("authzfail", AuthzFailResource())
- self.putChild("users", UsersResource())
- self.putChild("login", LoginResource())
- self.putChild("logout", LogoutResource())
-
- def __repr__(self):
- if self.http_port is None:
- return "<WebStatus on path %s at %s>" % (self.distrib_port,
- hex(id(self)))
- if self.distrib_port is None:
- return "<WebStatus on port %s at %s>" % (self.http_port,
- hex(id(self)))
- return ("<WebStatus on port %s and path %s at %s>" %
- (self.http_port, self.distrib_port, hex(id(self))))
-
- def setServiceParent(self, parent):
- # this class keeps a *separate* link to the buildmaster, rather than
- # just using self.parent, so that when we are "disowned" (and thus
- # parent=None), any remaining HTTP clients of this WebStatus will still
- # be able to get reasonable results.
- self.master = parent.master
-
- # set master in IAuth instance
- if self.authz.auth:
- self.authz.auth.master = self.master
-
- def either(a,b): # a if a else b for py2.4
- if a:
- return a
- else:
- return b
-
- rotateLength = either(self.logRotateLength, self.master.log_rotation.rotateLength)
- maxRotatedFiles = either(self.maxRotatedFiles, self.master.log_rotation.maxRotatedFiles)
-
- # Set up the jinja templating engine.
- if self.revlink:
- revlink = self.revlink
- else:
- revlink = self.master.config.revlink
- self.templates = createJinjaEnv(revlink, self.changecommentlink,
- self.repositories, self.projects, self.jinja_loaders)
-
- if not self.site:
-
- class RotateLogSite(server.Site):
- def _openLogFile(self, path):
- try:
- from twisted.python.logfile import LogFile
- log.msg("Setting up http.log rotating %s files of %s bytes each" %
- (maxRotatedFiles, rotateLength))
- if hasattr(LogFile, "fromFullPath"): # not present in Twisted-2.5.0
- return LogFile.fromFullPath(path, rotateLength=rotateLength, maxRotatedFiles=maxRotatedFiles)
- else:
- log.msg("WebStatus: rotated http logs are not supported on this version of Twisted")
- except ImportError, e:
- log.msg("WebStatus: Unable to set up rotating http.log: %s" % e)
-
- # if all else fails, just call the parent method
- return server.Site._openLogFile(self, path)
-
- # this will be replaced once we've been attached to a parent (and
- # thus have a basedir and can reference BASEDIR)
- root = static.Data("placeholder", "text/plain")
- httplog = os.path.abspath(os.path.join(self.master.basedir, "http.log"))
- self.site = RotateLogSite(root, logPath=httplog)
-
- # the following items are accessed by HtmlResource when it renders
- # each page.
- self.site.buildbot_service = self
-
- if self.http_port is not None:
- self.http_svc = s = strports.service(self.http_port, self.site)
- s.setServiceParent(self)
- if self.distrib_port is not None:
- f = pb.PBServerFactory(distrib.ResourcePublisher(self.site))
- self.distrib_svc = s = strports.service(self.distrib_port, f)
- s.setServiceParent(self)
-
- self.setupSite()
-
- service.MultiService.setServiceParent(self, parent)
-
- def setupSite(self):
- # this is responsible for creating the root resource. It isn't done
- # at __init__ time because we need to reference the parent's basedir.
- htmldir = os.path.abspath(os.path.join(self.master.basedir, self.public_html))
- if os.path.isdir(htmldir):
- log.msg("WebStatus using (%s)" % htmldir)
- else:
- log.msg("WebStatus: warning: %s is missing. Do you need to run"
- " 'buildbot upgrade-master' on this buildmaster?" % htmldir)
- # all static pages will get a 404 until upgrade-master is used to
- # populate this directory. Create the directory, though, since
- # otherwise we get internal server errors instead of 404s.
- os.mkdir(htmldir)
-
- root = StaticFile(htmldir)
- root_page = RootPage()
- root.putChild("", root_page)
- root.putChild("shutdown", root_page)
- root.putChild("cancel_shutdown", root_page)
-
- for name, child_resource in self.childrenToBeAdded.iteritems():
- root.putChild(name, child_resource)
-
- status = self.getStatus()
- if "rss" in self.provide_feeds:
- root.putChild("rss", Rss20StatusResource(status))
- if "atom" in self.provide_feeds:
- root.putChild("atom", Atom10StatusResource(status))
- if "json" in self.provide_feeds:
- root.putChild("json", JsonStatusResource(status))
-
- self.site.resource = root
-
- def putChild(self, name, child_resource):
- """This behaves a lot like root.putChild() . """
- self.childrenToBeAdded[name] = child_resource
-
- def registerChannel(self, channel):
- self.channels[channel] = 1 # weakrefs
-
- @defer.inlineCallbacks
- def stopService(self):
- for channel in self.channels:
- try:
- channel.transport.loseConnection()
- except:
- log.msg("WebStatus.stopService: error while disconnecting"
- " leftover clients")
- log.err()
- yield service.MultiService.stopService(self)
-
- # having shut them down, now remove our child services so they don't
- # start up again if we're re-started
- if self.http_svc:
- yield self.http_svc.disownServiceParent()
- self.http_svc = None
- if self.distrib_svc:
- yield self.distrib_svc.disownServiceParent()
- self.distrib_svc = None
-
- def getStatus(self):
- return self.master.getStatus()
-
- def getChangeSvc(self):
- return self.master.change_svc
-
- def getPortnum(self):
- # this is for the benefit of unit tests
- s = list(self)[0]
- return s._port.getHost().port
-
- # What happened to getControl?!
- #
- # instead of passing control objects all over the place in the web
- # code, at the few places where a control instance is required we
- # find the requisite object manually, starting at the buildmaster.
- # This is in preparation for removal of the IControl hierarchy
- # entirely.
-
- def checkConfig(self, otherStatusReceivers):
- duplicate_webstatus=0
- for osr in otherStatusReceivers:
- if isinstance(osr,WebStatus):
- if osr is self:
- continue
- # compare against myself and complain if the settings conflict
- if self.http_port == osr.http_port:
- if duplicate_webstatus == 0:
- duplicate_webstatus = 2
- else:
- duplicate_webstatus += 1
-
- if duplicate_webstatus:
- config.error(
- "%d Webstatus objects have same port: %s"
- % (duplicate_webstatus, self.http_port),
- )
-
-# resources can get access to the IStatus by calling
-# request.site.buildbot_service.getStatus()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py
deleted file mode 100644
index 1cf7f92f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.web import html
-from twisted.internet import defer, reactor
-from twisted.web.util import Redirect, DeferredResource
-
-import urllib, time
-from twisted.python import log
-from buildbot.status.web.base import HtmlResource, \
- css_classes, path_to_build, path_to_builder, path_to_slave, \
- getAndCheckProperties, ActionResource, path_to_authzfail, \
- getRequestCharset
-from buildbot.schedulers.forcesched import ForceScheduler, TextParameter
-from buildbot.status.web.step import StepsResource
-from buildbot.status.web.tests import TestsResource
-from buildbot import util, interfaces
-
-class ForceBuildActionResource(ActionResource):
-
- def __init__(self, build_status, builder):
- self.build_status = build_status
- self.builder = builder
- self.action = "forceBuild"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- url = None
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed(self.action, req, self.builder)
-
- if not res:
- url = path_to_authzfail(req)
- else:
- # get a control object
- c = interfaces.IControl(self.getBuildmaster(req))
- bc = c.getBuilder(self.builder.getName())
-
- b = self.build_status
- builder_name = self.builder.getName()
- log.msg("web rebuild of build %s:%s" % (builder_name, b.getNumber()))
- name =authz.getUsernameFull(req)
- comments = req.args.get("comments", ["<no reason specified>"])[0]
- comments.decode(getRequestCharset(req))
- reason = ("The web-page 'rebuild' button was pressed by "
- "'%s': %s\n" % (name, comments))
- msg = ""
- extraProperties = getAndCheckProperties(req)
- if not bc or not b.isFinished() or extraProperties is None:
- msg = "could not rebuild: "
- if b.isFinished():
- msg += "build still not finished "
- if bc:
- msg += "could not get builder control"
- else:
- tup = yield bc.rebuildBuild(b, reason, extraProperties)
- # rebuildBuild returns None on error (?!)
- if not tup:
- msg = "rebuilding a build failed "+ str(tup)
- # we're at
- # http://localhost:8080/builders/NAME/builds/5/rebuild?[args]
- # Where should we send them?
- #
- # Ideally it would be to the per-build page that they just started,
- # but we don't know the build number for it yet (besides, it might
- # have to wait for a current build to finish). The next-most
- # preferred place is somewhere that the user can see tangible
- # evidence of their build starting (or to see the reason that it
- # didn't start). This should be the Builder page.
-
- url = path_to_builder(req, self.builder), msg
- defer.returnValue(url)
-
-
-class StopBuildActionResource(ActionResource):
-
- def __init__(self, build_status):
- self.build_status = build_status
- self.action = "stopBuild"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed(self.action, req, self.build_status)
-
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- b = self.build_status
- log.msg("web stopBuild of build %s:%s" % \
- (b.getBuilder().getName(), b.getNumber()))
- name = authz.getUsernameFull(req)
- comments = req.args.get("comments", ["<no reason specified>"])[0]
- comments.decode(getRequestCharset(req))
- # html-quote both the username and comments, just to be safe
- reason = ("The web-page 'stop build' button was pressed by "
- "'%s': %s\n" % (html.escape(name), html.escape(comments)))
-
- c = interfaces.IControl(self.getBuildmaster(req))
- bldrc = c.getBuilder(self.build_status.getBuilder().getName())
- if bldrc:
- bldc = bldrc.getBuild(self.build_status.getNumber())
- if bldc:
- bldc.stopBuild(reason)
-
- defer.returnValue(path_to_builder(req, self.build_status.getBuilder()))
-
-# /builders/$builder/builds/$buildnum
-class StatusResourceBuild(HtmlResource):
- addSlash = True
-
- def __init__(self, build_status):
- HtmlResource.__init__(self)
- self.build_status = build_status
-
- def getPageTitle(self, request):
- return ("Buildbot: %s Build #%d" %
- (self.build_status.getBuilder().getName(),
- self.build_status.getNumber()))
-
- def content(self, req, cxt):
- b = self.build_status
- status = self.getStatus(req)
- req.setHeader('Cache-Control', 'no-cache')
-
- cxt['b'] = b
- cxt['path_to_builder'] = path_to_builder(req, b.getBuilder())
-
- if not b.isFinished():
- step = b.getCurrentStep()
- if not step:
- cxt['current_step'] = "[waiting for Lock]"
- else:
- if step.isWaitingForLocks():
- cxt['current_step'] = "%s [waiting for Lock]" % step.getName()
- else:
- cxt['current_step'] = step.getName()
- when = b.getETA()
- if when is not None:
- cxt['when'] = util.formatInterval(when)
- cxt['when_time'] = time.strftime("%H:%M:%S",
- time.localtime(time.time() + when))
-
- else:
- cxt['result_css'] = css_classes[b.getResults()]
- if b.getTestResults():
- cxt['tests_link'] = req.childLink("tests")
-
- ssList = b.getSourceStamps()
- sourcestamps = cxt['sourcestamps'] = ssList
-
- all_got_revisions = b.getAllGotRevisions()
- cxt['got_revisions'] = all_got_revisions
-
- try:
- cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename()))
- except KeyError:
- pass
-
- cxt['steps'] = []
-
- for s in b.getSteps():
- step = {'name': s.getName() }
-
- if s.isFinished():
- if s.isHidden():
- continue
-
- step['css_class'] = css_classes[s.getResults()[0]]
- (start, end) = s.getTimes()
- step['time_to_run'] = util.formatInterval(end - start)
- elif s.isStarted():
- if s.isWaitingForLocks():
- step['css_class'] = "waiting"
- step['time_to_run'] = "waiting for locks"
- else:
- start = s.getTimes()[0]
- step['css_class'] = "running"
- step['time_to_run'] = "running %s" % (util.formatInterval(util.now() - start))
- else:
- step['css_class'] = "not_started"
- step['time_to_run'] = ""
-
- cxt['steps'].append(step)
-
- step['link'] = req.childLink("steps/%s" %
- urllib.quote(s.getName(), safe=''))
- step['text'] = " ".join(s.getText())
- step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items())
-
- step['logs']= []
- for l in s.getLogs():
- logname = l.getName()
- step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" %
- (urllib.quote(s.getName(), safe=''),
- urllib.quote(logname, safe=''))),
- 'name': logname })
-
- scheduler = b.getProperty("scheduler", None)
- parameters = {}
- master = self.getBuildmaster(req)
- for sch in master.allSchedulers():
- if isinstance(sch, ForceScheduler) and scheduler == sch.name:
- for p in sch.all_fields:
- parameters[p.name] = p
-
- ps = cxt['properties'] = []
- for name, value, source in b.getProperties().asList():
- if not isinstance(value, dict):
- cxt_value = unicode(value)
- else:
- cxt_value = value
- p = { 'name': name, 'value': cxt_value, 'source': source}
- if len(cxt_value) > 500:
- p['short_value'] = cxt_value[:500]
- if name in parameters:
- param = parameters[name]
- if isinstance(param, TextParameter):
- p['text'] = param.value_to_text(value)
- p['cols'] = param.cols
- p['rows'] = param.rows
- p['label'] = param.label
- ps.append(p)
-
-
- cxt['responsible_users'] = list(b.getResponsibleUsers())
-
- (start, end) = b.getTimes()
- cxt['start'] = time.ctime(start)
- if end:
- cxt['end'] = time.ctime(end)
- cxt['elapsed'] = util.formatInterval(end - start)
- else:
- now = util.now()
- cxt['elapsed'] = util.formatInterval(now - start)
-
- exactly = True
- has_changes = False
- for ss in sourcestamps:
- exactly = exactly and (ss.revision is not None)
- has_changes = has_changes or ss.changes
- cxt['exactly'] = (exactly) or b.getChanges()
- cxt['has_changes'] = has_changes
- cxt['build_url'] = path_to_build(req, b)
- cxt['authz'] = self.getAuthz(req)
-
- template = req.site.buildbot_service.templates.get_template("build.html")
- return template.render(**cxt)
-
- def stop(self, req, auth_ok=False):
- # check if this is allowed
- if not auth_ok:
- return StopBuildActionResource(self.build_status)
-
- b = self.build_status
- log.msg("web stopBuild of build %s:%s" % \
- (b.getBuilder().getName(), b.getNumber()))
-
- name = self.getAuthz(req).getUsernameFull(req)
- comments = req.args.get("comments", ["<no reason specified>"])[0]
- comments.decode(getRequestCharset(req))
- # html-quote both the username and comments, just to be safe
- reason = ("The web-page 'stop build' button was pressed by "
- "'%s': %s\n" % (html.escape(name), html.escape(comments)))
-
- c = interfaces.IControl(self.getBuildmaster(req))
- bldrc = c.getBuilder(self.build_status.getBuilder().getName())
- if bldrc:
- bldc = bldrc.getBuild(self.build_status.getNumber())
- if bldc:
- bldc.stopBuild(reason)
-
- # we're at http://localhost:8080/svn-hello/builds/5/stop?[args] and
- # we want to go to: http://localhost:8080/svn-hello
- r = Redirect(path_to_builder(req, self.build_status.getBuilder()))
- d = defer.Deferred()
- reactor.callLater(1, d.callback, r)
- return DeferredResource(d)
-
- def rebuild(self, req):
- return ForceBuildActionResource(self.build_status,
- self.build_status.getBuilder())
-
- def getChild(self, path, req):
- if path == "stop":
- return self.stop(req)
- if path == "rebuild":
- return self.rebuild(req)
- if path == "steps":
- return StepsResource(self.build_status)
- if path == "tests":
- return TestsResource(self.build_status)
-
- return HtmlResource.getChild(self, path, req)
-
-# /builders/$builder/builds
-class BuildsResource(HtmlResource):
- addSlash = True
-
- def __init__(self, builder_status):
- HtmlResource.__init__(self)
- self.builder_status = builder_status
-
- def content(self, req, cxt):
- return "subpages shows data for each build"
-
- def getChild(self, path, req):
- try:
- num = int(path)
- except ValueError:
- num = None
- if num is not None:
- build_status = self.builder_status.getBuild(num)
- if build_status:
- return StatusResourceBuild(build_status)
-
- return HtmlResource.getChild(self, path, req)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py
deleted file mode 100644
index b4d15233..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py
+++ /dev/null
@@ -1,632 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.web import html
-import urllib, time
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces
-from buildbot.status.web.base import HtmlResource, BuildLineMixin, \
- path_to_build, path_to_slave, path_to_builder, path_to_change, \
- path_to_root, ICurrentBox, build_get_class, \
- map_branches, path_to_authzfail, ActionResource, \
- getRequestCharset
-from buildbot.schedulers.forcesched import ForceScheduler
-from buildbot.schedulers.forcesched import ValidationError
-from buildbot.status.web.build import BuildsResource, StatusResourceBuild
-from buildbot import util
-import collections
-
-class ForceAction(ActionResource):
- @defer.inlineCallbacks
- def force(self, req, builderNames):
- master = self.getBuildmaster(req)
- owner = self.getAuthz(req).getUsernameFull(req)
- schedulername = req.args.get("forcescheduler", ["<unknown>"])[0]
- if schedulername == "<unknown>":
- defer.returnValue((path_to_builder(req, self.builder_status),
- "forcescheduler arg not found"))
- return
-
- args = {}
- # decode all of the args
- encoding = getRequestCharset(req)
- for name, argl in req.args.iteritems():
- if name == "checkbox":
- # damn html's ungeneric checkbox implementation...
- for cb in argl:
- args[cb.decode(encoding)] = True
- else:
- args[name] = [ arg.decode(encoding) for arg in argl ]
-
- for sch in master.allSchedulers():
- if schedulername == sch.name:
- try:
- yield sch.force(owner, builderNames, **args)
- msg = ""
- except ValidationError, e:
- msg = html.escape(e.message.encode('ascii','ignore'))
- break
-
- # send the user back to the builder page
- defer.returnValue(msg)
-
-
-class ForceAllBuildsActionResource(ForceAction):
-
- def __init__(self, status, selectedOrAll):
- self.status = status
- self.selectedOrAll = selectedOrAll
- self.action = "forceAllBuilds"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('forceAllBuilds', req)
-
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- if self.selectedOrAll == 'all':
- builderNames = None
- elif self.selectedOrAll == 'selected':
- builderNames = [b for b in req.args.get("selected", []) if b]
-
- msg = yield self.force(req, builderNames)
-
- # back to the welcome page
- defer.returnValue((path_to_root(req) + "builders", msg))
-
-class StopAllBuildsActionResource(ActionResource):
-
- def __init__(self, status, selectedOrAll):
- self.status = status
- self.selectedOrAll = selectedOrAll
- self.action = "stopAllBuilds"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('stopAllBuilds', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- builders = None
- if self.selectedOrAll == 'all':
- builders = self.status.getBuilderNames()
- elif self.selectedOrAll == 'selected':
- builders = [b for b in req.args.get("selected", []) if b]
-
- for bname in builders:
- builder_status = self.status.getBuilder(bname)
- (state, current_builds) = builder_status.getState()
- if state != "building":
- continue
- for b in current_builds:
- build_status = builder_status.getBuild(b.number)
- if not build_status:
- continue
- build = StatusResourceBuild(build_status)
- build.stop(req, auth_ok=True)
-
- # go back to the welcome page
- defer.returnValue(path_to_root(req))
-
-
-class CancelAllPendingBuildsActionResource(ActionResource):
-
- def __init__(self, status, selectedOrAll):
- self.status = status
- self.selectedOrAll = selectedOrAll
- self.action = 'cancelAllPendingBuilds'
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('cancelAllPendingBuilds', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- builders = None
- if self.selectedOrAll == 'all':
- builders = self.status.getBuilderNames()
- elif self.selectedOrAll == 'selected':
- builders = [b for b in req.args.get("selected", []) if b]
-
- c = interfaces.IControl(self.getBuildmaster(req))
- for bname in builders:
- authz = self.getAuthz(req)
- builder_control = c.getBuilder(bname)
-
- brcontrols = yield builder_control.getPendingBuildRequestControls()
-
- for build_req in brcontrols:
- log.msg("Cancelling %s" % build_req)
- build_req.cancel()
-
- # go back to the welcome page
- defer.returnValue(path_to_root(req))
-
-
-class PingBuilderActionResource(ActionResource):
-
- def __init__(self, builder_status):
- self.builder_status = builder_status
- self.action = "pingBuilder"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- log.msg("web ping of builder '%s'" % self.builder_status.getName())
- res = yield self.getAuthz(req).actionAllowed('pingBuilder', req,
- self.builder_status)
- if not res:
- log.msg("..but not authorized")
- defer.returnValue(path_to_authzfail(req))
- return
-
- c = interfaces.IControl(self.getBuildmaster(req))
- bc = c.getBuilder(self.builder_status.getName())
- bc.ping()
- # send the user back to the builder page
- defer.returnValue(path_to_builder(req, self.builder_status))
-
-class ForceBuildActionResource(ForceAction):
-
- def __init__(self, builder_status):
- self.builder_status = builder_status
- self.action = "forceBuild"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- # check if this is allowed
- res = yield self.getAuthz(req).actionAllowed(self.action, req,
- self.builder_status)
- if not res:
- log.msg("..but not authorized")
- defer.returnValue(path_to_authzfail(req))
- return
-
- builderName = self.builder_status.getName()
-
- msg = yield self.force(req, [builderName])
-
- # send the user back to the builder page
- defer.returnValue((path_to_builder(req, self.builder_status), msg))
-
-def buildForceContextForField(req, default_props, sch, field, master, buildername):
- pname = "%s.%s"%(sch.name, field.fullName)
-
- default = field.default
-
- if "list" in field.type:
- choices = field.getChoices(master, sch, buildername)
- if choices:
- default = choices[0]
- default_props[pname+".choices"] = choices
-
- default = req.args.get(pname, [default])[0]
- if "bool" in field.type:
- default = "checked" if default else ""
- elif isinstance(default, unicode):
- # filter out unicode chars, and html stuff
- default = html.escape(default.encode('utf-8','ignore'))
-
- default_props[pname] = default
-
- if "nested" in field.type:
- for subfield in field.fields:
- buildForceContextForField(req, default_props, sch, subfield, master, buildername)
-
-def buildForceContext(cxt, req, master, buildername=None):
- force_schedulers = {}
- default_props = collections.defaultdict(str)
- for sch in master.allSchedulers():
- if isinstance(sch, ForceScheduler) and (buildername is None or(buildername in sch.builderNames)):
- force_schedulers[sch.name] = sch
- for field in sch.all_fields:
- buildForceContextForField(req, default_props, sch, field, master, buildername)
-
- cxt['force_schedulers'] = force_schedulers
- cxt['default_props'] = default_props
-
-# /builders/$builder
-class StatusResourceBuilder(HtmlResource, BuildLineMixin):
- addSlash = True
-
- def __init__(self, builder_status, numbuilds=20):
- HtmlResource.__init__(self)
- self.builder_status = builder_status
- self.numbuilds = numbuilds
-
- def getPageTitle(self, request):
- return "Buildbot: %s" % self.builder_status.getName()
-
- def builder(self, build, req):
- b = {}
-
- b['num'] = build.getNumber()
- b['link'] = path_to_build(req, build)
-
- when = build.getETA()
- if when is not None:
- b['when'] = util.formatInterval(when)
- b['when_time'] = time.strftime("%H:%M:%S",
- time.localtime(time.time() + when))
-
- step = build.getCurrentStep()
- # TODO: is this necessarily the case?
- if not step:
- b['current_step'] = "[waiting for Lock]"
- else:
- if step.isWaitingForLocks():
- b['current_step'] = "%s [waiting for Lock]" % step.getName()
- else:
- b['current_step'] = step.getName()
-
- b['stop_url'] = path_to_build(req, build) + '/stop'
-
- return b
-
- @defer.inlineCallbacks
- def content(self, req, cxt):
- b = self.builder_status
-
- cxt['name'] = b.getName()
- cxt['description'] = b.getDescription()
- req.setHeader('Cache-Control', 'no-cache')
- slaves = b.getSlaves()
- connected_slaves = [s for s in slaves if s.isConnected()]
-
- cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]
-
- cxt['pending'] = []
- statuses = yield b.getPendingBuildRequestStatuses()
- for pb in statuses:
- changes = []
-
- source = yield pb.getSourceStamp()
- submitTime = yield pb.getSubmitTime()
- bsid = yield pb.getBsid()
-
- properties = yield \
- pb.master.db.buildsets.getBuildsetProperties(bsid)
-
- if source.changes:
- for c in source.changes:
- changes.append({ 'url' : path_to_change(req, c),
- 'who' : c.who,
- 'revision' : c.revision,
- 'repo' : c.repository })
-
- cxt['pending'].append({
- 'when': time.strftime("%b %d %H:%M:%S",
- time.localtime(submitTime)),
- 'delay': util.formatInterval(util.now() - submitTime),
- 'id': pb.brid,
- 'changes' : changes,
- 'num_changes' : len(changes),
- 'properties' : properties,
- })
-
- numbuilds = cxt['numbuilds'] = int(req.args.get('numbuilds', [self.numbuilds])[0])
- recent = cxt['recent'] = []
- for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
- recent.append(self.get_line_values(req, build, False))
-
- sl = cxt['slaves'] = []
- connected_slaves = 0
- for slave in slaves:
- s = {}
- sl.append(s)
- s['link'] = path_to_slave(req, slave)
- s['name'] = slave.getName()
- c = s['connected'] = slave.isConnected()
- s['paused'] = slave.isPaused()
- s['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
- if c:
- connected_slaves += 1
- cxt['connected_slaves'] = connected_slaves
-
- cxt['authz'] = self.getAuthz(req)
- cxt['builder_url'] = path_to_builder(req, b)
- buildForceContext(cxt, req, self.getBuildmaster(req), b.getName())
- template = req.site.buildbot_service.templates.get_template("builder.html")
- defer.returnValue(template.render(**cxt))
-
- def ping(self, req):
- return PingBuilderActionResource(self.builder_status)
-
- def getChild(self, path, req):
- if path == "force":
- return ForceBuildActionResource(self.builder_status)
- if path == "ping":
- return self.ping(req)
- if path == "cancelbuild":
- return CancelChangeResource(self.builder_status)
- if path == "stopchange":
- return StopChangeResource(self.builder_status)
- if path == "builds":
- return BuildsResource(self.builder_status)
-
- return HtmlResource.getChild(self, path, req)
-
-class CancelChangeResource(ActionResource):
-
- def __init__(self, builder_status):
- ActionResource.__init__(self)
- self.builder_status = builder_status
-
- @defer.inlineCallbacks
- def performAction(self, req):
- try:
- request_id = req.args.get("id", [None])[0]
- if request_id == "all":
- cancel_all = True
- else:
- cancel_all = False
- request_id = int(request_id)
- except:
- request_id = None
-
- authz = self.getAuthz(req)
- if request_id:
- c = interfaces.IControl(self.getBuildmaster(req))
- builder_control = c.getBuilder(self.builder_status.getName())
-
- brcontrols = yield builder_control.getPendingBuildRequestControls()
-
- for build_req in brcontrols:
- if cancel_all or (build_req.brid == request_id):
- log.msg("Cancelling %s" % build_req)
- res = yield authz.actionAllowed('cancelPendingBuild', req,
- build_req)
- if res:
- build_req.cancel()
- else:
- defer.returnValue(path_to_authzfail(req))
- return
- if not cancel_all:
- break
-
- defer.returnValue(path_to_builder(req, self.builder_status))
-
-class StopChangeMixin(object):
-
- @defer.inlineCallbacks
- def stopChangeForBuilder(self, req, builder_status, auth_ok=False):
- try:
- request_change = req.args.get("change", [None])[0]
- request_change = int(request_change)
- except:
- request_change = None
-
- authz = self.getAuthz(req)
- if request_change:
- c = interfaces.IControl(self.getBuildmaster(req))
- builder_control = c.getBuilder(builder_status.getName())
-
- brcontrols = yield builder_control.getPendingBuildRequestControls()
- build_controls = dict((x.brid, x) for x in brcontrols)
-
- build_req_statuses = yield \
- builder_status.getPendingBuildRequestStatuses()
-
- for build_req in build_req_statuses:
- ss = yield build_req.getSourceStamp()
-
- if not ss.changes:
- continue
-
- for change in ss.changes:
- if change.number == request_change:
- control = build_controls[build_req.brid]
- log.msg("Cancelling %s" % control)
- res = yield authz.actionAllowed('stopChange', req, control)
- if (auth_ok or res):
- control.cancel()
- else:
- defer.returnValue(False)
- return
-
- defer.returnValue(True)
-
-
-class StopChangeResource(StopChangeMixin, ActionResource):
-
- def __init__(self, builder_status):
- ActionResource.__init__(self)
- self.builder_status = builder_status
-
- @defer.inlineCallbacks
- def performAction(self, req):
- """Cancel all pending builds that include a given numbered change."""
- success = yield self.stopChangeForBuilder(req, self.builder_status)
-
- if not success:
- defer.returnValue(path_to_authzfail(req))
- else:
- defer.returnValue(path_to_builder(req, self.builder_status))
-
-
-class StopChangeAllResource(StopChangeMixin, ActionResource):
-
- def __init__(self, status):
- ActionResource.__init__(self)
- self.status = status
-
- @defer.inlineCallbacks
- def performAction(self, req):
- """Cancel all pending builds that include a given numbered change."""
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('stopChange', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- for bname in self.status.getBuilderNames():
- builder_status = self.status.getBuilder(bname)
- res = yield self.stopChangeForBuilder(req, builder_status, auth_ok=True)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- defer.returnValue(path_to_root(req))
-
-
-# /builders/_all
-class StatusResourceAllBuilders(HtmlResource, BuildLineMixin):
-
- def __init__(self, status):
- HtmlResource.__init__(self)
- self.status = status
-
- def getChild(self, path, req):
- if path == "forceall":
- return self.forceall(req)
- if path == "stopall":
- return self.stopall(req)
- if path == "stopchangeall":
- return StopChangeAllResource(self.status)
- if path == "cancelpendingall":
- return CancelAllPendingBuildsActionResource(self.status, 'all')
-
- return HtmlResource.getChild(self, path, req)
-
- def forceall(self, req):
- return ForceAllBuildsActionResource(self.status, 'all')
-
- def stopall(self, req):
- return StopAllBuildsActionResource(self.status, 'all')
-
-# /builders/_selected
-
-
-class StatusResourceSelectedBuilders(HtmlResource, BuildLineMixin):
-
- def __init__(self, status):
- HtmlResource.__init__(self)
- self.status = status
-
- def getChild(self, path, req):
- if path == "forceselected":
- return self.forceselected(req)
- if path == "stopselected":
- return self.stopselected(req)
- if path == "cancelpendingselected":
- return CancelAllPendingBuildsActionResource(self.status, 'selected')
-
- return HtmlResource.getChild(self, path, req)
-
- def forceselected(self, req):
- return ForceAllBuildsActionResource(self.status, 'selected')
-
- def stopselected(self, req):
- return StopAllBuildsActionResource(self.status, 'selected')
-
-# /builders
-
-
-class BuildersResource(HtmlResource):
- pageTitle = "Builders"
- addSlash = True
-
- def __init__(self, numbuilds=20):
- HtmlResource.__init__(self)
- self.numbuilds = numbuilds
-
- @defer.inlineCallbacks
- def content(self, req, cxt):
- status = self.getStatus(req)
- encoding = getRequestCharset(req)
-
- builders = req.args.get("builder", status.getBuilderNames())
- branches = [ b.decode(encoding)
- for b in req.args.get("branch", [])
- if b ]
-
- # get counts of pending builds for each builder
- brstatus_ds = []
- brcounts = {}
- def keep_count(statuses, builderName):
- brcounts[builderName] = len(statuses)
- for builderName in builders:
- builder_status = status.getBuilder(builderName)
- d = builder_status.getPendingBuildRequestStatuses()
- d.addCallback(keep_count, builderName)
- brstatus_ds.append(d)
- yield defer.gatherResults(brstatus_ds)
-
- cxt['branches'] = branches
- bs = cxt['builders'] = []
-
- building = 0
- online = 0
- base_builders_url = path_to_root(req) + "builders/"
- for bn in builders:
- bld = { 'link': base_builders_url + urllib.quote(bn, safe=''),
- 'name': bn }
- bs.append(bld)
-
- builder = status.getBuilder(bn)
- builds = list(builder.generateFinishedBuilds(map_branches(branches),
- num_builds=1))
- if builds:
- b = builds[0]
- bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber())
- label = None
- all_got_revisions = b.getAllGotRevisions()
- # If len = 1 then try if revision can be used as label.
- if len(all_got_revisions) == 1:
- label = all_got_revisions[all_got_revisions.keys()[0]]
- if not label or len(str(label)) > 20:
- label = "#%d" % b.getNumber()
-
- bld['build_label'] = label
- bld['build_text'] = " ".join(b.getText())
- bld['build_css_class'] = build_get_class(b)
-
- current_box = ICurrentBox(builder).getBox(status, brcounts)
- bld['current_box'] = current_box.td()
-
- builder_status = builder.getState()[0]
- if builder_status == "building":
- building += 1
- online += 1
- elif builder_status != "offline":
- online += 1
-
- cxt['authz'] = self.getAuthz(req)
- cxt['num_building'] = building
- cxt['num_online'] = online
- buildForceContext(cxt, req, self.getBuildmaster(req))
- template = req.site.buildbot_service.templates.get_template("builders.html")
- defer.returnValue(template.render(**cxt))
-
- def getChild(self, path, req):
- s = self.getStatus(req)
- if path in s.getBuilderNames():
- builder_status = s.getBuilder(path)
- return StatusResourceBuilder(builder_status, self.numbuilds)
- if path == "_all":
- return StatusResourceAllBuilders(self.getStatus(req))
- if path == "_selected":
- return StatusResourceSelectedBuilders(self.getStatus(req))
-
- return HtmlResource.getChild(self, path, req)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py
deleted file mode 100644
index 9dd57b6c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.web.base import HtmlResource, IBox
-
-class BuildStatusStatusResource(HtmlResource):
- def __init__(self, categories=None):
- HtmlResource.__init__(self)
-
- def content(self, request, ctx):
- """Display a build in the same format as the waterfall page.
- The HTTP GET parameters are the builder name and the build
- number."""
-
- status = self.getStatus(request)
- request.setHeader('Cache-Control', 'no-cache')
-
- # Get the parameters.
- name = request.args.get("builder", [None])[0]
- number = request.args.get("number", [None])[0]
- if not name or not number:
- return "builder and number parameter missing"
- number = int(number)
-
- # Check if the builder in parameter exists.
- try:
- builder = status.getBuilder(name)
- except:
- return "unknown builder"
-
- # Check if the build in parameter exists.
- build = builder.getBuild(int(number))
- if not build:
- return "unknown build %s" % number
-
- rows = ctx['rows'] = []
-
- # Display each step, starting by the last one.
- for i in range(len(build.getSteps()) - 1, -1, -1):
- step = build.getSteps()[i]
- if step.isStarted() and step.getText():
- rows.append(IBox(step).getBox(request).td(align="center"))
-
- # Display the bottom box with the build number in it.
- ctx['build'] = IBox(build).getBox(request).td(align="center")
-
- template = request.site.buildbot_service.templates.get_template("buildstatus.html")
- data = template.render(**ctx)
-
- # We want all links to display in a new tab/window instead of in the
- # current one.
- # TODO: Move to template
- data = data.replace('<a ', '<a target="_blank"')
- return data
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py
deleted file mode 100644
index cc53e34b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# code inspired/copied from contrib/github_buildbot
-# and inspired from code from the Chromium project
-# otherwise, Andrew Melo <andrew.melo@gmail.com> wrote the rest
-# but "the rest" is pretty minimal
-
-import re
-from twisted.web import resource, server
-from twisted.python.reflect import namedModule
-from twisted.python import log
-from twisted.internet import defer
-
-class ChangeHookResource(resource.Resource):
- # this is a cheap sort of template thingy
- contentType = "text/html; charset=utf-8"
- children = {}
- def __init__(self, dialects={}):
- """
- The keys of 'dialects' select a modules to load under
- master/buildbot/status/web/hooks/
- The value is passed to the module's getChanges function, providing
- configuration options to the dialect.
- """
- self.dialects = dialects
- self.request_dialect = None
-
- def getChild(self, name, request):
- return self
-
- def render_GET(self, request):
- """
- Reponds to events and starts the build process
- different implementations can decide on what methods they will accept
- """
- return self.render_POST(request)
-
- def render_POST(self, request):
- """
- Reponds to events and starts the build process
- different implementations can decide on what methods they will accept
-
- :arguments:
- request
- the http request object
- """
-
- try:
- changes, src = self.getChanges( request )
- except ValueError, err:
- request.setResponseCode(400, err.args[0])
- return err.args[0]
- except Exception, e:
- log.err(e, "processing changes from web hook")
- msg = "Error processing changes."
- request.setResponseCode(500, msg)
- return msg
-
- log.msg("Payload: " + str(request.args))
-
- if not changes:
- log.msg("No changes found")
- return "no changes found"
- d = self.submitChanges( changes, request, src )
- def ok(_):
- request.setResponseCode(202)
- request.finish()
- def err(why):
- log.err(why, "adding changes from web hook")
- request.setResponseCode(500)
- request.finish()
- d.addCallbacks(ok, err)
- return server.NOT_DONE_YET
-
-
- def getChanges(self, request):
- """
- Take the logic from the change hook, and then delegate it
- to the proper handler
- http://localhost/change_hook/DIALECT will load up
- buildmaster/status/web/hooks/DIALECT.py
-
- and call getChanges()
-
- the return value is a list of changes
-
- if DIALECT is unspecified, a sample implementation is provided
- """
- uriRE = re.search(r'^/change_hook/?([a-zA-Z0-9_]*)', request.uri)
-
- if not uriRE:
- log.msg("URI doesn't match change_hook regex: %s" % request.uri)
- raise ValueError("URI doesn't match change_hook regex: %s" % request.uri)
-
- changes = []
- src = None
-
- # Was there a dialect provided?
- if uriRE.group(1):
- dialect = uriRE.group(1)
- else:
- dialect = 'base'
-
- if dialect in self.dialects.keys():
- log.msg("Attempting to load module buildbot.status.web.hooks." + dialect)
- tempModule = namedModule('buildbot.status.web.hooks.' + dialect)
- changes, src = tempModule.getChanges(request,self.dialects[dialect])
- log.msg("Got the following changes %s" % changes)
- self.request_dialect = dialect
- else:
- m = "The dialect specified, '%s', wasn't whitelisted in change_hook" % dialect
- log.msg(m)
- log.msg("Note: if dialect is 'base' then it's possible your URL is malformed and we didn't regex it properly")
- raise ValueError(m)
-
- return (changes, src)
-
- @defer.inlineCallbacks
- def submitChanges(self, changes, request, src):
- master = request.site.buildbot_service.master
- for chdict in changes:
- change = yield master.addChange(src=src, **chdict)
- log.msg("injected change %s" % change)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py
deleted file mode 100644
index e579669e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from zope.interface import implements
-from twisted.python import components
-from twisted.web.resource import NoResource
-
-from buildbot.changes.changes import Change
-from buildbot.status.web.base import HtmlResource, IBox, Box
-
-class ChangeResource(HtmlResource):
- def __init__(self, changeid):
- self.changeid = changeid
- self.pageTitle = "Change #%d" % changeid
-
- def content(self, req, cxt):
- d = self.getStatus(req).getChange(self.changeid)
- def cb(change):
- if not change:
- return "No change number %d" % self.changeid
- templates = req.site.buildbot_service.templates
- cxt['c'] = change.asDict()
- template = templates.get_template("change.html")
- data = template.render(cxt)
- return data
- d.addCallback(cb)
- return d
-
-# /changes/NN
-class ChangesResource(HtmlResource):
-
- def content(self, req, cxt):
- cxt['sources'] = self.getStatus(req).getChangeSources()
- template = req.site.buildbot_service.templates.get_template("change_sources.html")
- return template.render(**cxt)
-
- def getChild(self, path, req):
- try:
- changeid = int(path)
- except ValueError:
- return NoResource("Expected a change number")
-
- return ChangeResource(changeid)
-
-class ChangeBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- url = req.childLink("../changes/%d" % self.original.number)
- template = req.site.buildbot_service.templates.get_template("change_macros.html")
- text = template.module.box_contents(url=url,
- who=self.original.getShortAuthor(),
- pageTitle=self.original.comments,
- revision=self.original.revision,
- project=self.original.project)
- return Box([text], class_="Change")
-components.registerAdapter(ChangeBox, Change, IBox)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py
deleted file mode 100644
index 60eb67c0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py
+++ /dev/null
@@ -1,744 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-import operator
-import re
-import urllib
-from twisted.internet import defer
-from buildbot import util
-from buildbot.status import builder
-from buildbot.status.web.base import HtmlResource
-from buildbot.changes import changes
-
-class DoesNotPassFilter(Exception): pass # Used for filtering revs
-
-def getResultsClass(results, prevResults, inProgress):
- """Given the current and past results, return the class that will be used
- by the css to display the right color for a box."""
-
- if inProgress:
- return "running"
-
- if results is None:
- return "notstarted"
-
- if results == builder.SUCCESS:
- return "success"
-
- if results == builder.WARNINGS:
- return "warnings"
-
- if results == builder.FAILURE:
- if not prevResults:
- # This is the bottom box. We don't know if the previous one failed
- # or not. We assume it did not.
- return "failure"
-
- if prevResults != builder.FAILURE:
- # This is a new failure.
- return "failure"
- else:
- # The previous build also failed.
- return "failure-again"
-
- # Any other results? Like EXCEPTION?
- return "exception"
-
-class ANYBRANCH: pass # a flag value, used below
-
-class DevRevision:
- """Helper class that contains all the information we need for a revision."""
-
- def __init__(self, change):
- self.revision = change.revision
- self.comments = change.comments
- self.who = change.who
- self.date = change.getTime()
- self.revlink = getattr(change, 'revlink', None)
- self.when = change.when
- self.repository = change.repository
- self.project = change.project
-
-
-class DevBuild:
- """Helper class that contains all the information we need for a build."""
-
- def __init__(self, revision, build, details):
- self.revision = revision
- self.results = build.getResults()
- self.number = build.getNumber()
- self.isFinished = build.isFinished()
- self.text = build.getText()
- self.eta = build.getETA()
- self.details = details
- self.when = build.getTimes()[0]
- #TODO: support multiple sourcestamps
- self.source = build.getSourceStamps()[0]
-
-
-class ConsoleStatusResource(HtmlResource):
- """Main console class. It displays a user-oriented status page.
- Every change is a line in the page, and it shows the result of the first
- build with this change for each slave."""
-
- def __init__(self, orderByTime=False):
- HtmlResource.__init__(self)
-
- self.status = None
-
- if orderByTime:
- self.comparator = TimeRevisionComparator()
- else:
- self.comparator = IntegerRevisionComparator()
-
- def getPageTitle(self, request):
- status = self.getStatus(request)
- title = status.getTitle()
- if title:
- return "BuildBot: %s" % title
- else:
- return "BuildBot"
-
- def getChangeManager(self, request):
- return request.site.buildbot_service.parent.change_svc
-
- ##
- ## Data gathering functions
- ##
-
- def getHeadBuild(self, builder):
- """Get the most recent build for the given builder.
- """
- build = builder.getBuild(-1)
-
- # HACK: Work around #601, the head build may be None if it is
- # locked.
- if build is None:
- build = builder.getBuild(-2)
-
- return build
-
- def fetchChangesFromHistory(self, status, max_depth, max_builds, debugInfo):
- """Look at the history of the builders and try to fetch as many changes
- as possible. We need this when the main source does not contain enough
- sourcestamps.
-
- max_depth defines how many builds we will parse for a given builder.
- max_builds defines how many builds total we want to parse. This is to
- limit the amount of time we spend in this function.
-
- This function is sub-optimal, but the information returned by this
- function is cached, so this function won't be called more than once.
- """
-
- allChanges = list()
- build_count = 0
- for builderName in status.getBuilderNames()[:]:
- if build_count > max_builds:
- break
-
- builder = status.getBuilder(builderName)
- build = self.getHeadBuild(builder)
- depth = 0
- while build and depth < max_depth and build_count < max_builds:
- depth += 1
- build_count += 1
- sourcestamp = build.getSourceStamps()[0]
- allChanges.extend(sourcestamp.changes[:])
- build = build.getPreviousBuild()
-
- debugInfo["source_fetch_len"] = len(allChanges)
- return allChanges
-
- @defer.inlineCallbacks
- def getAllChanges(self, request, status, debugInfo):
- master = request.site.buildbot_service.master
-
- chdicts = yield master.db.changes.getRecentChanges(25)
-
- # convert those to Change instances
- allChanges = yield defer.gatherResults([
- changes.Change.fromChdict(master, chdict)
- for chdict in chdicts ])
-
- allChanges.sort(key=self.comparator.getSortingKey())
-
- # Remove the dups
- prevChange = None
- newChanges = []
- for change in allChanges:
- rev = change.revision
- if not prevChange or rev != prevChange.revision:
- newChanges.append(change)
- prevChange = change
- allChanges = newChanges
-
- defer.returnValue(allChanges)
-
- def getBuildDetails(self, request, builderName, build):
- """Returns an HTML list of failures for a given build."""
- details = {}
- if not build.getLogs():
- return details
-
- for step in build.getSteps():
- (result, reason) = step.getResults()
- if result == builder.FAILURE:
- name = step.getName()
-
- # Remove html tags from the error text.
- stripHtml = re.compile(r'<.*?>')
- strippedDetails = stripHtml.sub('', ' '.join(step.getText()))
-
- details['buildername'] = builderName
- details['status'] = strippedDetails
- details['reason'] = reason
- logs = details['logs'] = []
-
- if step.getLogs():
- for log in step.getLogs():
- logname = log.getName()
- logurl = request.childLink(
- "../builders/%s/builds/%s/steps/%s/logs/%s" %
- (urllib.quote(builderName),
- build.getNumber(),
- urllib.quote(name),
- urllib.quote(logname)))
- logs.append(dict(url=logurl, name=logname))
- return details
-
- def getBuildsForRevision(self, request, builder, builderName, codebase,
- lastRevision, numBuilds, debugInfo):
- """Return the list of all the builds for a given builder that we will
- need to be able to display the console page. We start by the most recent
- build, and we go down until we find a build that was built prior to the
- last change we are interested in."""
-
- revision = lastRevision
-
- builds = []
- build = self.getHeadBuild(builder)
- number = 0
- while build and number < numBuilds:
- debugInfo["builds_scanned"] += 1
-
- got_rev = None
- sourceStamps = build.getSourceStamps(absolute=True)
-
- # The console page cannot handle builds that have more than 1 revision
- if codebase is not None:
- # Get the last revision in this build for this codebase.
- for ss in sourceStamps:
- if ss.codebase == codebase:
- got_rev = ss.revision
- break
- elif len(sourceStamps) == 1:
- ss = sourceStamps[0]
- # Get the last revision in this build.
- got_rev = ss.revision
-
- # We ignore all builds that don't have last revisions.
- # TODO(nsylvain): If the build is over, maybe it was a problem
- # with the update source step. We need to find a way to tell the
- # user that his change might have broken the source update.
- if got_rev is not None:
- number += 1
- details = self.getBuildDetails(request, builderName, build)
- devBuild = DevBuild(got_rev, build, details)
- builds.append(devBuild)
-
- # Now break if we have enough builds.
- current_revision = self.getChangeForBuild(
- build, revision)
- if self.comparator.isRevisionEarlier(
- devBuild, current_revision):
- break
-
- build = build.getPreviousBuild()
-
- return builds
-
- def getChangeForBuild(self, build, revision):
- if not build or not build.getChanges(): # Forced build
- return DevBuild(revision, build, None)
-
- for change in build.getChanges():
- if change.revision == revision:
- return change
-
- # No matching change, return the last change in build.
- changes = list(build.getChanges())
- changes.sort(key=self.comparator.getSortingKey())
- return changes[-1]
-
- def getAllBuildsForRevision(self, status, request, codebase, lastRevision,
- numBuilds, categories, builders, debugInfo):
- """Returns a dictionary of builds we need to inspect to be able to
- display the console page. The key is the builder name, and the value is
- an array of build we care about. We also returns a dictionary of
- builders we care about. The key is it's category.
-
- codebase is the codebase to get revisions from
- lastRevision is the last revision we want to display in the page.
- categories is a list of categories to display. It is coming from the
- HTTP GET parameters.
- builders is a list of builders to display. It is coming from the HTTP
- GET parameters.
- """
-
- allBuilds = dict()
-
- # List of all builders in the dictionary.
- builderList = dict()
-
- debugInfo["builds_scanned"] = 0
- # Get all the builders.
- builderNames = status.getBuilderNames()[:]
- for builderName in builderNames:
- builder = status.getBuilder(builderName)
-
- # Make sure we are interested in this builder.
- if categories and builder.category not in categories:
- continue
- if builders and builderName not in builders:
- continue
-
- # We want to display this builder.
- category = builder.category or "default"
- # Strip the category to keep only the text before the first |.
- # This is a hack to support the chromium usecase where they have
- # multiple categories for each slave. We use only the first one.
- # TODO(nsylvain): Create another way to specify "display category"
- # in master.cfg.
- category = category.split('|')[0]
- if not builderList.get(category):
- builderList[category] = []
-
- # Append this builder to the dictionary of builders.
- builderList[category].append(builderName)
- # Set the list of builds for this builder.
- allBuilds[builderName] = self.getBuildsForRevision(request,
- builder,
- builderName,
- codebase,
- lastRevision,
- numBuilds,
- debugInfo)
-
- return (builderList, allBuilds)
-
-
- ##
- ## Display functions
- ##
-
- def displayCategories(self, builderList, debugInfo):
- """Display the top category line."""
-
- count = 0
- for category in builderList:
- count += len(builderList[category])
-
- categories = builderList.keys()
- categories.sort()
-
- cs = []
-
- for category in categories:
- c = {}
-
- c["name"] = category
-
- # To be able to align the table correctly, we need to know
- # what percentage of space this category will be taking. This is
- # (#Builders in Category) / (#Builders Total) * 100.
- c["size"] = (len(builderList[category]) * 100) / count
- cs.append(c)
-
- return cs
-
- def displaySlaveLine(self, status, builderList, debugInfo):
- """Display a line the shows the current status for all the builders we
- care about."""
-
- nbSlaves = 0
-
- # Get the number of builders.
- for category in builderList:
- nbSlaves += len(builderList[category])
-
- # Get the categories, and order them alphabetically.
- categories = builderList.keys()
- categories.sort()
-
- slaves = {}
-
- # For each category, we display each builder.
- for category in categories:
- slaves[category] = []
- # For each builder in this category, we set the build info and we
- # display the box.
- for builder in builderList[category]:
- s = {}
- s["color"] = "notstarted"
- s["pageTitle"] = builder
- s["url"] = "./builders/%s" % urllib.quote(builder)
- state, builds = status.getBuilder(builder).getState()
- # Check if it's offline, if so, the box is purple.
- if state == "offline":
- s["color"] = "offline"
- else:
- # If not offline, then display the result of the last
- # finished build.
- build = self.getHeadBuild(status.getBuilder(builder))
- while build and not build.isFinished():
- build = build.getPreviousBuild()
-
- if build:
- s["color"] = getResultsClass(build.getResults(), None,
- False)
-
- slaves[category].append(s)
-
- return slaves
-
- def displayStatusLine(self, builderList, allBuilds, revision, debugInfo):
- """Display the boxes that represent the status of each builder in the
- first build "revision" was in. Returns an HTML list of errors that
- happened during these builds."""
-
- details = []
- nbSlaves = 0
- for category in builderList:
- nbSlaves += len(builderList[category])
-
- # Sort the categories.
- categories = builderList.keys()
- categories.sort()
-
- builds = {}
-
- # Display the boxes by category group.
- for category in categories:
-
- builds[category] = []
-
- # Display the boxes for each builder in this category.
- for builder in builderList[category]:
- introducedIn = None
- firstNotIn = None
-
- # Find the first build that does not include the revision.
- for build in allBuilds[builder]:
- if self.comparator.isRevisionEarlier(build, revision):
- firstNotIn = build
- break
- else:
- introducedIn = build
-
- # Get the results of the first build with the revision, and the
- # first build that does not include the revision.
- results = None
- previousResults = None
- if introducedIn:
- results = introducedIn.results
- if firstNotIn:
- previousResults = firstNotIn.results
-
- isRunning = False
- if introducedIn and not introducedIn.isFinished:
- isRunning = True
-
- url = "./waterfall"
- pageTitle = builder
- tag = ""
- current_details = {}
- if introducedIn:
- current_details = introducedIn.details or ""
- url = "./buildstatus?builder=%s&number=%s" % (urllib.quote(builder),
- introducedIn.number)
- pageTitle += " "
- pageTitle += urllib.quote(' '.join(introducedIn.text), ' \n\\/:')
-
- builderStrip = builder.replace(' ', '')
- builderStrip = builderStrip.replace('(', '')
- builderStrip = builderStrip.replace(')', '')
- builderStrip = builderStrip.replace('.', '')
- tag = "Tag%s%s" % (builderStrip, introducedIn.number)
-
- if isRunning:
- pageTitle += ' ETA: %ds' % (introducedIn.eta or 0)
-
- resultsClass = getResultsClass(results, previousResults, isRunning)
-
- b = {}
- b["url"] = url
- b["pageTitle"] = pageTitle
- b["color"] = resultsClass
- b["tag"] = tag
-
- builds[category].append(b)
-
- # If the box is red, we add the explaination in the details
- # section.
- if current_details and resultsClass == "failure":
- details.append(current_details)
-
- return (builds, details)
-
- def filterRevisions(self, revisions, filter=None, max_revs=None):
- """Filter a set of revisions based on any number of filter criteria.
- If specified, filter should be a dict with keys corresponding to
- revision attributes, and values of 1+ strings"""
- if not filter:
- if max_revs is None:
- for rev in reversed(revisions):
- yield DevRevision(rev)
- else:
- for index,rev in enumerate(reversed(revisions)):
- if index >= max_revs:
- break
- yield DevRevision(rev)
- else:
- for index, rev in enumerate(reversed(revisions)):
- if max_revs and index >= max_revs:
- break
- try:
- for field,acceptable in filter.iteritems():
- if not hasattr(rev, field):
- raise DoesNotPassFilter
- if type(acceptable) in (str, unicode):
- if getattr(rev, field) != acceptable:
- raise DoesNotPassFilter
- elif type(acceptable) in (list, tuple, set):
- if getattr(rev, field) not in acceptable:
- raise DoesNotPassFilter
- yield DevRevision(rev)
- except DoesNotPassFilter:
- pass
-
- def displayPage(self, request, status, builderList, allBuilds, codebase,
- revisions, categories, repository, project, branch,
- debugInfo):
- """Display the console page."""
- # Build the main template directory with all the informations we have.
- subs = dict()
- subs["branch"] = branch or 'trunk'
- subs["repository"] = repository
- subs["project"] = project
- subs["codebase"] = codebase
- if categories:
- subs["categories"] = ' '.join(categories)
- subs["time"] = time.strftime("%a %d %b %Y %H:%M:%S",
- time.localtime(util.now()))
- subs["debugInfo"] = debugInfo
- subs["ANYBRANCH"] = ANYBRANCH
-
- if builderList:
- subs["categories"] = self.displayCategories(builderList, debugInfo)
- subs['slaves'] = self.displaySlaveLine(status, builderList, debugInfo)
- else:
- subs["categories"] = []
-
- subs['revisions'] = []
-
- # For each revision we show one line
- for revision in revisions:
- r = {}
-
- # Fill the dictionary with this new information
- r['id'] = revision.revision
- r['link'] = revision.revlink
- r['who'] = revision.who
- r['date'] = revision.date
- r['comments'] = revision.comments
- r['repository'] = revision.repository
- r['project'] = revision.project
-
- # Display the status for all builders.
- (builds, details) = self.displayStatusLine(builderList,
- allBuilds,
- revision,
- debugInfo)
- r['builds'] = builds
- r['details'] = details
-
- # Calculate the td span for the comment and the details.
- r["span"] = len(builderList) + 2
-
- subs['revisions'].append(r)
-
- #
- # Display the footer of the page.
- #
- debugInfo["load_time"] = time.time() - debugInfo["load_time"]
- return subs
-
-
- def content(self, request, cxt):
- "This method builds the main console view display."
-
- reload_time = None
- # Check if there was an arg. Don't let people reload faster than
- # every 15 seconds. 0 means no reload.
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- if reload_time != 0:
- reload_time = max(reload_time, 15)
- except ValueError:
- pass
-
- request.setHeader('Cache-Control', 'no-cache')
-
- # Sets the default reload time to 60 seconds.
- if not reload_time:
- reload_time = 60
-
- # Append the tag to refresh the page.
- if reload_time is not None and reload_time != 0:
- cxt['refresh'] = reload_time
-
- # Debug information to display at the end of the page.
- debugInfo = cxt['debuginfo'] = dict()
- debugInfo["load_time"] = time.time()
-
- # get url parameters
- # Categories to show information for.
- categories = request.args.get("category", [])
- # List of all builders to show on the page.
- builders = request.args.get("builder", [])
- # Repo used to filter the changes shown.
- repository = request.args.get("repository", [None])[0]
- # Project used to filter the changes shown.
- project = request.args.get("project", [None])[0]
- # Branch used to filter the changes shown.
- branch = request.args.get("branch", [ANYBRANCH])[0]
- # Codebase used to filter the changes shown.
- codebase = request.args.get("codebase", [None])[0]
- # List of all the committers name to display on the page.
- devName = request.args.get("name", [])
-
- # and the data we want to render
- status = self.getStatus(request)
-
- # Keep only the revisions we care about.
- # By default we process the last 40 revisions.
- # If a dev name is passed, we look for the changes by this person in the
- # last 80 revisions.
- numRevs = int(request.args.get("revs", [40])[0])
- if devName:
- numRevs *= 2
- numBuilds = numRevs
-
- # Get all changes we can find. This is a DB operation, so it must use
- # a deferred.
- d = self.getAllChanges(request, status, debugInfo)
- def got_changes(allChanges):
- debugInfo["source_all"] = len(allChanges)
-
- revFilter = {}
- if branch != ANYBRANCH:
- revFilter['branch'] = branch
- if devName:
- revFilter['who'] = devName
- if repository:
- revFilter['repository'] = repository
- if project:
- revFilter['project'] = project
- if codebase is not None:
- revFilter['codebase'] = codebase
- revisions = list(self.filterRevisions(allChanges, max_revs=numRevs,
- filter=revFilter))
- debugInfo["revision_final"] = len(revisions)
-
- # Fetch all the builds for all builders until we get the next build
- # after lastRevision.
- builderList = None
- allBuilds = None
- if revisions:
- lastRevision = revisions[len(revisions) - 1].revision
- debugInfo["last_revision"] = lastRevision
-
- (builderList, allBuilds) = self.getAllBuildsForRevision(status,
- request,
- codebase,
- lastRevision,
- numBuilds,
- categories,
- builders,
- debugInfo)
-
- debugInfo["added_blocks"] = 0
-
- cxt.update(self.displayPage(request, status, builderList,
- allBuilds, codebase, revisions,
- categories, repository, project,
- branch, debugInfo))
-
- templates = request.site.buildbot_service.templates
- template = templates.get_template("console.html")
- data = template.render(cxt)
- return data
- d.addCallback(got_changes)
- return d
-
-class RevisionComparator(object):
- """Used for comparing between revisions, as some
- VCS use a plain counter for revisions (like SVN)
- while others use different concepts (see Git).
- """
-
- # TODO (avivby): Should this be a zope interface?
-
- def isRevisionEarlier(self, first_change, second_change):
- """Used for comparing 2 changes"""
- raise NotImplementedError
-
- def isValidRevision(self, revision):
- """Checks whether the revision seems like a VCS revision"""
- raise NotImplementedError
-
- def getSortingKey(self):
- raise NotImplementedError
-
-class TimeRevisionComparator(RevisionComparator):
- def isRevisionEarlier(self, first, second):
- return first.when < second.when
-
- def isValidRevision(self, revision):
- return True # No general way of determining
-
- def getSortingKey(self):
- return operator.attrgetter('when')
-
-class IntegerRevisionComparator(RevisionComparator):
- def isRevisionEarlier(self, first, second):
- try:
- return int(first.revision) < int(second.revision)
- except (TypeError, ValueError):
- return False
-
- def isValidRevision(self, revision):
- try:
- int(revision)
- return True
- except:
- return False
-
- def getSortingKey(self):
- return operator.attrgetter('revision')
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py
deleted file mode 100644
index f29a11ca..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# This module enables ATOM and RSS feeds from webstatus.
-#
-# It is based on "feeder.py" which was part of the Buildbot
-# configuration for the Subversion project. The original file was
-# created by Lieven Gobaerts and later adjusted by API
-# (apinheiro@igalia.coma) and also here
-# http://code.google.com/p/pybots/source/browse/trunk/master/Feeder.py
-#
-# All subsequent changes to feeder.py where made by Chandan-Dutta
-# Chowdhury <chandan-dutta.chowdhury @ hp.com> and Gareth Armstrong
-# <gareth.armstrong @ hp.com>.
-#
-# Those modifications are as follows:
-# 1) the feeds are usable from baseweb.WebStatus
-# 2) feeds are fully validated ATOM 1.0 and RSS 2.0 feeds, verified
-# with code from http://feedvalidator.org
-# 3) nicer xml output
-# 4) feeds can be filtered as per the /waterfall display with the
-# builder and category filters
-# 5) cleaned up white space and imports
-#
-# Finally, the code was directly integrated into these two files,
-# buildbot/status/web/feeds.py (you're reading it, ;-)) and
-# buildbot/status/web/baseweb.py.
-
-import os
-import re
-import time
-from twisted.web import resource
-from buildbot.status import results
-
-class XmlResource(resource.Resource):
- contentType = "text/xml; charset=UTF-8"
- docType = ''
-
- def getChild(self, name, request):
- return self
-
- def render(self, request):
- data = self.content(request)
- request.setHeader("content-type", self.contentType)
- if request.method == "HEAD":
- request.setHeader("content-length", len(data))
- return ''
- return data
-
-_abbr_day = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-_abbr_mon = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
- 'Sep', 'Oct', 'Nov', 'Dec']
-
-def rfc822_time(tstamp):
- res = time.strftime("%%s, %d %%s %Y %H:%M:%S GMT",
- tstamp)
- res = res % (_abbr_day[tstamp.tm_wday], _abbr_mon[tstamp.tm_mon])
- return res
-
-class FeedResource(XmlResource):
- pageTitle = None
- link = 'http://dummylink'
- language = 'en-us'
- description = 'Dummy rss'
- status = None
-
- def __init__(self, status, categories=None, pageTitle=None):
- self.status = status
- self.categories = categories
- self.pageTitle = pageTitle
- self.title = self.status.getTitle()
- self.link = self.status.getBuildbotURL()
- self.description = 'List of builds'
- self.pubdate = time.gmtime(int(time.time()))
- self.user = self.getEnv(['USER', 'USERNAME'], 'buildmaster')
- self.hostname = self.getEnv(['HOSTNAME', 'COMPUTERNAME'],
- 'buildmaster')
- self.children = {}
-
- def getEnv(self, keys, fallback):
- for key in keys:
- if key in os.environ:
- return os.environ[key]
- return fallback
-
- def getBuilds(self, request):
- builds = []
- # THIS is lifted straight from the WaterfallStatusResource Class in
- # status/web/waterfall.py
- #
- # we start with all Builders available to this Waterfall: this is
- # limited by the config-file -time categories= argument, and defaults
- # to all defined Builders.
- allBuilderNames = self.status.getBuilderNames(categories=self.categories)
- builders = [self.status.getBuilder(name) for name in allBuilderNames]
-
- # but if the URL has one or more builder= arguments (or the old show=
- # argument, which is still accepted for backwards compatibility), we
- # use that set of builders instead. We still don't show anything
- # outside the config-file time set limited by categories=.
- showBuilders = request.args.get("show", [])
- showBuilders.extend(request.args.get("builder", []))
- if showBuilders:
- builders = [b for b in builders if b.name in showBuilders]
-
- # now, if the URL has one or category= arguments, use them as a
- # filter: only show those builders which belong to one of the given
- # categories.
- showCategories = request.args.get("category", [])
- if showCategories:
- builders = [b for b in builders if b.category in showCategories]
-
- failures_only = request.args.get("failures_only", ["false"])
- failures_only = failures_only[0] not in ('false', '0', 'no', 'off')
-
- maxFeeds = 25
-
- # Copy all failed builds in a new list.
- # This could clearly be implemented much better if we had
- # access to a global list of builds.
- for b in builders:
- if failures_only:
- res = (results.FAILURE,)
- else:
- res = None
- builds.extend(b.generateFinishedBuilds(results=res, max_search=maxFeeds))
-
- # Sort build list by date, youngest first.
- # To keep compatibility with python < 2.4, use this for sorting instead:
- # We apply Decorate-Sort-Undecorate
- deco = [(build.getTimes(), build) for build in builds]
- deco.sort()
- deco.reverse()
- builds = [build for (b1, build) in deco]
-
- if builds:
- builds = builds[:min(len(builds), maxFeeds)]
- return builds
-
- def content(self, request):
- builds = self.getBuilds(request)
-
- build_cxts = []
-
- for build in builds:
- start, finished = build.getTimes()
- finishedTime = time.gmtime(int(finished))
- link = re.sub(r'index.html', "", self.status.getURLForThing(build))
-
- # title: trunk r22191 (plus patch) failed on
- # 'i686-debian-sarge1 shared gcc-3.3.5'
- ss_list = build.getSourceStamps()
- all_got_revisions = build.getAllGotRevisions()
- src_cxts = []
- for ss in ss_list:
- sc = {}
- sc['codebase'] = ss.codebase
- if (ss.branch is None and ss.revision is None and ss.patch is None
- and not ss.changes):
- sc['repository'] = None
- sc['branch'] = None
- sc['revision'] = "Latest revision"
- else:
- sc['repository'] = ss.repository
- sc['branch'] = ss.branch
- got_revision = all_got_revisions.get(ss.codebase, None)
- if got_revision:
- sc['revision'] = got_revision
- else:
- sc['revision'] = str(ss.revision)
- if ss.patch:
- sc['revision'] += " (plus patch)"
- if ss.changes:
- pass
- src_cxts.append(sc)
- res = build.getResults()
- pageTitle = ('Builder "%s": %s' %
- (build.getBuilder().getName(), results.Results[res]))
-
- # Add information about the failing steps.
- failed_steps = []
- log_lines = []
- for s in build.getSteps():
- res = s.getResults()[0]
- if res not in (results.SUCCESS, results.WARNINGS,
- results.SKIPPED):
- failed_steps.append(s.getName())
-
- # Add the last 30 lines of each log.
- for log in s.getLogs():
- log_lines.append('Last lines of build log "%s":' %
- log.getName())
- log_lines.append([])
- try:
- logdata = log.getText()
- except IOError:
- # Probably the log file has been removed
- logdata ='** log file not available **'
- unilist = list()
- for line in logdata.split('\n')[-30:]:
- unilist.append(unicode(line,'utf-8'))
- log_lines.extend(unilist)
-
- bc = {}
- bc['sources'] = src_cxts
- bc['date'] = rfc822_time(finishedTime)
- bc['summary_link'] = ('%sbuilders/%s' %
- (self.link,
- build.getBuilder().getName()))
- bc['name'] = build.getBuilder().getName()
- bc['number'] = build.getNumber()
- bc['responsible_users'] = build.getResponsibleUsers()
- bc['failed_steps'] = failed_steps
- bc['pageTitle'] = pageTitle
- bc['link'] = link
- bc['log_lines'] = log_lines
-
- if finishedTime is not None:
- bc['rfc822_pubdate'] = rfc822_time(finishedTime)
- bc['rfc3339_pubdate'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",
- finishedTime)
-
- # Every RSS/Atom item must have a globally unique ID
- guid = ('tag:%s@%s,%s:%s' %
- (self.user, self.hostname,
- time.strftime("%Y-%m-%d", finishedTime),
- time.strftime("%Y%m%d%H%M%S", finishedTime)))
- bc['guid'] = guid
-
- build_cxts.append(bc)
-
- pageTitle = self.pageTitle
- if not pageTitle:
- pageTitle = 'Build status of %s' % self.title
-
- cxt = {}
- cxt['pageTitle'] = pageTitle
- cxt['title_url'] = self.link
- cxt['title'] = self.title
- cxt['language'] = self.language
- cxt['description'] = self.description
- if self.pubdate is not None:
- cxt['rfc822_pubdate'] = rfc822_time( self.pubdate)
- cxt['rfc3339_pubdate'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",
- self.pubdate)
-
- cxt['builds'] = build_cxts
- template = request.site.buildbot_service.templates.get_template(self.template_file)
- return template.render(**cxt).encode('utf-8').strip()
-
-class Rss20StatusResource(FeedResource):
- # contentType = 'application/rss+xml' (browser dependent)
- template_file = 'feed_rss20.xml'
-
- def __init__(self, status, categories=None, pageTitle=None):
- FeedResource.__init__(self, status, categories, pageTitle)
-
-class Atom10StatusResource(FeedResource):
- # contentType = 'application/atom+xml' (browser dependent)
- template_file = 'feed_atom10.xml'
-
- def __init__(self, status, categories=None, pageTitle=None):
- FeedResource.__init__(self, status, categories, pageTitle)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpg b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpg
deleted file mode 100644
index 6c2e5ddf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpg
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css
deleted file mode 100644
index d769f73a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css
+++ /dev/null
@@ -1,604 +0,0 @@
-body.interface {
- margin-left: 30px;
- margin-right: 30px;
- margin-top: 20px;
- margin-bottom: 50px;
- padding: 0;
- background: url(bg_gradient.jpg) repeat-x;
- font-family: Verdana, sans-serif;
- font-size: 10px;
- background-color: #fff;
- color: #333;
-}
-
-.auth {
-position:absolute;
-top:5px;
-right:40px;
-}
-
-.alert {
- color: #c30000;
- background-color: #f2dcdc;
- padding: 5px 5px 5px 25px;
- margin-bottom: 20px;
- border-top:1px solid #ccc;
- border-bottom:1px solid #ccc;
- border-color: #c30000;
- font-size: 20px;
-}
-a:link,a:visited,a:active {
- color: #444;
-}
-
-table {
- border-spacing: 1px 1px;
-}
-
-table td {
- padding: 3px 4px 3px 4px;
- text-align: center;
-}
-
-.Project {
- min-width: 6em;
-}
-
-.LastBuild,.Activity {
- padding: 0 0 0 4px;
-}
-
-.LastBuild,.Activity,.Builder,.BuildStep {
- min-width: 5em;
-}
-
-/* Chromium Specific styles */
-div.BuildResultInfo {
- color: #444;
-}
-
-div.Announcement {
- margin-bottom: 1em;
-}
-
-div.Announcement>a:hover {
- color: black;
-}
-
-div.Announcement>div.Notice {
- background-color: #afdaff;
- padding: 0.5em;
- font-size: 16px;
- text-align: center;
-}
-
-div.Announcement>div.Open {
- border: 3px solid #8fdf5f;
- padding: 0.5em;
- font-size: 16px;
- text-align: center;
-}
-
-div.Announcement>div.Closed {
- border: 5px solid #e98080;
- padding: 0.5em;
- font-size: 24px;
- font-weight: bold;
- text-align: center;
-}
-
-td.Time {
- color: #000;
- border-bottom: 1px solid #aaa;
- background-color: #eee;
-}
-
-td.Activity,td.Change,td.Builder {
- color: #333333;
- background-color: #CCCCCC;
-}
-
-td.Change {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-td.Event {
- color: #777;
- background-color: #ddd;
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-td.Activity {
- border-top-left-radius: 10px;
- -webkit-border-top-left-radius: 10px;
- -moz-border-radius-topleft: 10px;
- min-height: 20px;
- padding: 2px 0 2px 0;
-}
-
-td.idle,td.waiting,td.offline,td.building {
- border-top-left-radius: 0px;
- -webkit-border-top-left-radius: 0px;
- -moz-border-radius-topleft: 0px;
-}
-
-.LastBuild {
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- border-top-right-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topright: 5px;
-}
-
-/* Console view styles */
-td.DevRev {
- padding: 4px 8px 4px 8px;
- color: #333333;
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- background-color: #eee;
- width: 1%;
-}
-
-td.DevRevCollapse {
- border-bottom-left-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
-}
-
-td.DevName {
- padding: 4px 8px 4px 8px;
- color: #333333;
- background-color: #eee;
- width: 1%;
- text-align: left;
-}
-
-td.DevStatus {
- padding: 4px 4px 4px 4px;
- color: #333333;
- background-color: #eee;
-}
-
-td.DevSlave {
- padding: 4px 4px 4px 4px;
- color: #333333;
- background-color: #eee;
-}
-
-td.first {
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
-}
-
-td.last {
- border-top-right-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topright: 5px;
-}
-
-td.DevStatusCategory {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-width: 1px;
- border-style: solid;
-}
-
-td.DevStatusCollapse {
- border-bottom-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
-}
-
-td.DevDetails {
- font-weight: normal;
- padding: 8px 8px 8px 8px;
- color: #333333;
- background-color: #eee;
- text-align: left;
-}
-
-td.DevDetails li a {
- padding-right: 5px;
-}
-
-td.DevComment {
- font-weight: normal;
- padding: 8px 8px 8px 8px;
- color: #333333;
- background-color: #eee;
- text-align: left;
-}
-
-td.DevBottom {
- border-bottom-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- border-bottom-left-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
-}
-
-td.Alt {
- background-color: #ddd;
-}
-
-.legend {
- border-radius: 5px !important;
- -webkit-border-radius: 5px !important;
- -moz-border-radius: 5px !important;
- width: 100px;
- max-width: 100px;
- text-align: center;
- padding: 2px 2px 2px 2px;
- height: 14px;
- white-space: nowrap;
-}
-
-.DevStatusBox {
- text-align: center;
- height: 20px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.DevStatusBox a {
- opacity: 0.85;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- display: block;
- width: 90%;
- height: 20px;
- line-height: 20px;
- margin-left: auto;
- margin-right: auto;
-}
-
-.DevSlaveBox {
- text-align: center;
- height: 10px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.DevSlaveBox a {
- opacity: 0.85;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- display: block;
- width: 90%;
- height: 10px;
- line-height: 20px;
- margin-left: auto;
- margin-right: auto;
-}
-
-a.noround {
- border-radius: 0px;
- -webkit-border-radius: 0px;
- -moz-border-radius: 0px;
- position: relative;
- margin-top: -8px;
- margin-bottom: -8px;
- height: 36px;
- border-top-width: 0;
- border-bottom-width: 0;
-}
-
-a.begin {
- border-top-width: 1px;
- position: relative;
- margin-top: 0px;
- margin-bottom: -7px;
- height: 27px;
- border-top-left-radius: 4px;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topleft: 4px;
- border-top-right-radius: 4px;
- -webkit-border-top-right-radius: 4px;
- -moz-border-radius-topright: 4px;
-}
-
-a.end {
- border-bottom-width: 1px;
- position: relative;
- margin-top: -7px;
- margin-bottom: 0px;
- height: 27px;
- border-bottom-left-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -moz-border-radius-bottomleft: 4px;
- border-bottom-right-radius: 4px;
- -webkit-border-bottom-right-radius: 4px;
- -moz-border-radius-bottomright: 4px;
-}
-
-.center_align {
- text-align: center;
-}
-
-.right_align {
- text-align: right;
-}
-
-.left_align {
- text-align: left;
-}
-
-div.BuildWaterfall {
- border-radius: 7px;
- -webkit-border-radius: 7px;
- -moz-border-radius: 7px;
- position: absolute;
- left: 0px;
- top: 0px;
- background-color: #FFFFFF;
- padding: 4px 4px 4px 4px;
- float: left;
- display: none;
- border-width: 1px;
- border-style: solid;
-}
-
-/* LastBuild, BuildStep states */
-.success {
- color: #000;
- background-color: #8d4;
- border-color: #4F8530;
-}
-
-.failure {
- color: #000;
- background-color: #e88;
- border-color: #A77272;
-}
-
-.failure-again {
- color: #000;
- background-color: #eA9;
- border-color: #A77272;
-}
-
-.warnings {
- color: #FFFFFF;
- background-color: #fa3;
- border-color: #C29D46;
-}
-
-.skipped {
- color: #000;
- background: #AADDEE;
- border-color: #AADDEE;
-}
-
-.exception,.retry {
- color: #FFFFFF;
- background-color: #c6c;
- border-color: #ACA0B3;
-}
-
-.start {
- color: #000;
- background-color: #ccc;
- border-color: #ccc;
-}
-
-.running,.waiting,td.building {
- color: #000;
- background-color: #fd3;
- border-color: #C5C56D;
-}
-
-.paused {
- color: #FFFFFF;
- background-color: #8080FF;
- border-color: #dddddd;
-}
-
-.offline,td.offline {
- color: #FFFFFF;
- background-color: #777777;
- border-color: #dddddd;
-}
-
-
-.start {
- border-bottom-left-radius: 10px;
- -webkit-border-bottom-left-radius: 10px;
- -moz-border-radius-bottomleft: 10px;
- border-bottom-right-radius: 10px;
- -webkit-border-bottom-right-radius: 10px;
- -moz-border-radius-bottomright: 10px;
-}
-
-.notstarted {
- border-width: 1px;
- border-style: solid;
- border-color: #aaa;
- background-color: #fff;
-}
-
-.closed {
- background-color: #ff0000;
-}
-
-.closed .large {
- font-size: 1.5em;
- font-weight: bolder;
-}
-
-td.Project a:hover,td.start a:hover {
- color: #000;
-}
-
-.mini-box {
- text-align: center;
- height: 20px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.mini-box a {
- border-radius: 0;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- display: block;
- width: 100%;
- height: 20px;
- line-height: 20px;
- margin-top: -30px;
-}
-
-.mini-closed {
- -box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border: 4px solid red;
-}
-
-/* grid styles */
-table.Grid {
- border-collapse: collapse;
-}
-
-table.Grid tr td {
- padding: 0.2em;
- margin: 0px;
- text-align: center;
-}
-
-table.Grid tr td.title {
- font-size: 90%;
- border-right: 1px gray solid;
- border-bottom: 1px gray solid;
-}
-
-table.Grid tr td.sourcestamp {
- font-size: 90%;
-}
-
-table.Grid tr td.builder {
- text-align: right;
- font-size: 90%;
-}
-
-table.Grid tr td.build {
- border: 1px gray solid;
-}
-
-/* column container */
-div.column {
- margin: 0 2em 2em 0;
- float: left;
-}
-
-/* info tables */
-table.info {
- border-spacing: 1px;
-}
-
-table.info td {
- padding: 0.1em 1em 0.1em 1em;
- text-align: center;
-}
-
-table.info th {
- padding: 0.2em 1.5em 0.2em 1.5em;
- text-align: center;
-}
-
-table.info td.left {
- text-align: left
-}
-
-.alt {
- background-color: #f6f6f6;
-}
-
-li {
- padding: 0.1em 1em 0.1em 1em;
-}
-
-.result {
- padding: 0.3em 1em 0.3em 1em;
-}
-
-/* log view */
-.log * {
- vlink: #800080;
- font-family: "Courier New", courier, monotype, monospace;
-}
-
-span.stdout {
- color: black;
-}
-
-span.stderr {
- color: red;
-}
-
-span.header {
- color: blue;
-}
-
-/* revision & email */
-.revision .full {
- display: none;
-}
-
-.user .email {
- display: none;
-}
-
-pre {
- white-space: pre-wrap;
-}
-
-/* change comments (use regular colors here) */
-pre.comments>a:link,pre.comments>a:visited {
- color: blue;
-}
-
-pre.comments>a:active {
- color: purple;
-}
-
-form.command_forcebuild {
- border-top: 1px solid black;
- padding: .5em;
- margin: .5em;
-}
-
-form.command_forcebuild > .row {
- border-top: 1px dotted gray;
- padding: .5em 0;
-}
-
-form.command_forcebuild .force-textarea > .label {
- display: block;
-}
-
-form.command_forcebuild .force-nested > .label {
- font-weight: bold;
- display: list-item;
-}
-
-form.command_forcebuild .force-any .force-text {
- display: inline;
-}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.ico b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.ico
deleted file mode 100644
index b0b0845d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt
deleted file mode 100644
index 7b5fc8da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-User-agent: *
-Disallow: /waterfall
-Disallow: /builders
-Disallow: /changes
-Disallow: /buildslaves
-Disallow: /schedulers
-Disallow: /one_line_per_build
-Disallow: /builders
-Disallow: /grid
-Disallow: /tgrid
-Disallow: /json
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt
deleted file mode 100644
index 78201578..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is the directory to place customized templates for webstatus.
-
-You can find the sources for the templates used in:
-buildbot/status/web/templates
-
-You can copy any of those files to this directory, make changes, and buildbot will automatically
-use your modified templates.
-
-Also of note is that you will not need to restart/reconfig buildbot master to have these changes take effect.
-
-The syntax of the templates is Jinja2:
-http://jinja.pocoo.org/ \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py
deleted file mode 100644
index dc4fbd62..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from buildbot.status.web.base import HtmlResource
-from buildbot.status.web.base import build_get_class, path_to_builder, path_to_build
-from buildbot.sourcestamp import SourceStamp
-
-class ANYBRANCH: pass # a flag value, used below
-
-class GridStatusMixin(object):
- def getPageTitle(self, request):
- status = self.getStatus(request)
- p = status.getTitle()
- if p:
- return "BuildBot: %s" % p
- else:
- return "BuildBot"
-
- # handle reloads through an http header
- # TODO: send this as a real header, rather than a tag
- def get_reload_time(self, request):
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- return max(reload_time, 15)
- except ValueError:
- pass
- return None
-
- def build_cxt(self, request, build):
- if not build:
- return {}
-
- if build.isFinished():
- # get the text and annotate the first line with a link
- text = build.getText()
- if not text: text = [ "(no information)" ]
- if text == [ "build", "successful" ]: text = [ "OK" ]
- else:
- text = [ 'building' ]
-
- name = build.getBuilder().getName()
-
- cxt = {}
- cxt['name'] = name
- cxt['got_revision'] = build.getProperty("got_revision")
- cxt['DEST'] = build.getProperty("DEST")
- cxt['url'] = path_to_build(request, build)
- cxt['text'] = text
- cxt['class'] = build_get_class(build)
-
- if build.getProperty("repourl_poky"):
- if build.getProperty("repourl_poky") == "git://git.yoctoproject.org/poky":
- cxt['repository'] = "poky"
- cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/?h="
- elif "git://git.yoctoproject.org/poky-contrib" in build.getProperty("repourl_poky"):
- cxt['repository'] = "poky-contrib"
- cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/commit/?h="
- else:
- cxt['repository'] = build.getProperty("repourl_poky")
-
- if build.getProperty("branch_poky"):
- if build.getProperty("branch_poky") == "stage/master_under_test":
- cxt['branchshortname']="mut"
- else:
- cxt['branchshortname']=build.getProperty("branch_poky")
- cxt['branch'] = build.getProperty("branch_poky")
- if 'cgiturl' in cxt and 'got_revision' in cxt and cxt['cgiturl'] is not None and cxt['got_revision'] is not None:
- cxt['cgiturl'] = cxt['cgiturl'] + build.getProperty("branch_poky") + "&id=" + cxt['got_revision']
- if build.getProperty("custom_release_name_nightly"):
- cxt['release_name'] = build.getProperty("custom_release_name_nightly")
- else:
- cxt['commit_desc'] = build.getProperty("commit-description")
-
- return cxt
-
- @defer.inlineCallbacks
- def builder_cxt(self, request, builder):
- state, builds = builder.getState()
-
- # look for upcoming builds. We say the state is "waiting" if the
- # builder is otherwise idle and there is a scheduler which tells us a
- # build will be performed some time in the near future. TODO: this
- # functionality used to be in BuilderStatus.. maybe this code should
- # be merged back into it.
- upcoming = []
- builderName = builder.getName()
- for s in self.getStatus(request).getSchedulers():
- if builderName in s.listBuilderNames():
- upcoming.extend(s.getPendingBuildTimes())
- if state == "idle" and upcoming:
- state = "waiting"
-
- n_pending = len((yield builder.getPendingBuildRequestStatuses()))
-
- cxt = { 'url': path_to_builder(request, builder),
- 'name': builder.getName(),
- 'state': state,
- 'n_pending': n_pending }
-
- defer.returnValue(cxt)
-
- def getSourceStampKey(self, sourcestamps):
- """Given two source stamps, we want to assign them to the same row if
- they are the same version of code, even if they differ in minor detail.
-
- This function returns an appropriate comparison key for that.
- """
- # TODO: Maybe order sourcestamps in key by codebases names?
- return tuple([(ss.branch, ss.revision, ss.patch) for ss in sourcestamps])
-
- def clearRecentBuildsCache(self):
- self.__recentBuildsCache__ = {}
-
- def getRecentBuilds(self, builder, numBuilds, branch):
- cache = getattr(self, '__recentBuildsCache__', {})
- key = (builder.getName(), branch, numBuilds)
- try:
- return cache[key]
- except KeyError:
- # cache miss, get the value and store it in the cache
- result = [b for b in self.__getRecentBuilds(builder, numBuilds, branch)]
- cache[key] = result
- return result
-
- def __getRecentBuilds(self, builder, numBuilds, branch):
- """
- get a list of most recent builds on given builder
- """
- build = builder.getBuild(-1)
- num = 0
- while build and num < numBuilds:
- start = build.getTimes()[0]
- #TODO: support multiple sourcestamps
- ss = build.getSourceStamps(absolute=True)[0]
-
- okay_build = True
-
- # skip un-started builds
- if not start:
- okay_build = False
-
- # skip non-matching branches
- if branch != ANYBRANCH and ss.branch != branch:
- okay_build = False
-
- if okay_build:
- num += 1
- yield build
-
- build = build.getPreviousBuild()
- return
-
- def getRecentSourcestamps(self, status, numBuilds, categories, branch):
- """
- get a list of the most recent NUMBUILDS SourceStamp tuples, sorted
- by the earliest start we've seen for them
- """
- # TODO: use baseweb's getLastNBuilds?
- sourcestamps = { } # { ss-tuple : earliest time }
- for bn in status.getBuilderNames():
- builder = status.getBuilder(bn)
- if categories and builder.category not in categories:
- continue
- for build in self.getRecentBuilds(builder, numBuilds, branch):
- ss = build.getSourceStamps(absolute=True)
- key = self.getSourceStampKey(ss)
- start = min(x for x in build.getTimes() if x is not None)
- if key not in sourcestamps or sourcestamps[key][1] > start:
- sourcestamps[key] = (ss, start)
-
- # now sort those and take the NUMBUILDS most recent
- sourcestamps = sorted(sourcestamps.itervalues(), key = lambda stamp: stamp[1])
- sourcestamps = [stamp[0] for stamp in sourcestamps][-numBuilds:]
-
- return sourcestamps
-
-class GridStatusResource(HtmlResource, GridStatusMixin):
- # TODO: docs
- status = None
- changemaster = None
-
- @defer.inlineCallbacks
- def content(self, request, cxt):
- """This method builds the regular grid display.
- That is, build stamps across the top, build hosts down the left side
- """
-
- # get url parameters
- numBuilds = int(request.args.get("width", [5])[0])
- categories = request.args.get("category", [])
- branch = request.args.get("branch", [ANYBRANCH])[0]
- if branch == 'trunk': branch = None
-
- # and the data we want to render
- status = self.getStatus(request)
- stamps = self.getRecentSourcestamps(status, numBuilds, categories, branch)
-
- cxt['refresh'] = self.get_reload_time(request)
-
- cxt.update({'categories': categories,
- 'branch': branch,
- 'ANYBRANCH': ANYBRANCH,
- 'stamps': [map(SourceStamp.asDict, sstamp) for sstamp in stamps],
- })
- sortedBuilderNames = sorted(status.getBuilderNames())
-
- cxt['builders'] = []
- cxt['build_triggers'] = build_triggers = []
- cxt['range'] = range(len(stamps))
-
- # For each sstamp we want to know the name of the builder which
- # triggered the builds and the buildid of that builder. We'll keep
- # that in a list of dicts which align with the stamps objects list.
- for _ in range(len(stamps)):
- build_triggers.append({'builder': '', 'id': ''})
-
- for bn in sortedBuilderNames:
- builds = [None] * len(stamps)
-
- builder = status.getBuilder(bn)
- if categories and builder.category not in categories:
- continue
-
- for build in self.getRecentBuilds(builder, numBuilds, branch):
- ss = build.getSourceStamps(absolute=True)
- key = self.getSourceStampKey(ss)
-
- for i, sstamp in enumerate(stamps):
- if key == self.getSourceStampKey(sstamp) and builds[i] is None:
- builds[i] = build
- if build_triggers[i].get('builder', None) != 'nightly':
- build_triggers[i]['builder'] = bn
- build_triggers[i]['id'] = str(build.getNumber())
-
- b = yield self.builder_cxt(request, builder)
-
- b['builds'] = []
- for build in builds:
- b['builds'].append(self.build_cxt(request, build))
-
- cxt['builders'].append(b)
-
- self.clearRecentBuildsCache()
- template = request.site.buildbot_service.templates.get_template("grid.html")
- defer.returnValue(template.render(**cxt))
-
-
-class TransposedGridStatusResource(HtmlResource, GridStatusMixin):
- # TODO: docs
- status = None
- changemaster = None
- default_rev_order = "desc"
-
- @defer.inlineCallbacks
- def content(self, request, cxt):
- """This method builds the transposed grid display.
- That is, build hosts across the top, build stamps down the left side
- """
-
- # get url parameters
- numBuilds = int(request.args.get("length", [5])[0])
- categories = request.args.get("category", [])
- branch = request.args.get("branch", [ANYBRANCH])[0]
- if branch == 'trunk': branch = None
-
- rev_order = request.args.get("rev_order", [self.default_rev_order])[0]
- if rev_order not in ["asc", "desc"]:
- rev_order = self.default_rev_order
-
- cxt['refresh'] = self.get_reload_time(request)
-
- # and the data we want to render
- status = self.getStatus(request)
- stamps = self.getRecentSourcestamps(status, numBuilds, categories, branch)
-
- cxt.update({'categories': categories,
- 'branch': branch,
- 'ANYBRANCH': ANYBRANCH,
- 'stamps': [map(SourceStamp.asDict, sstamp) for sstamp in stamps],
- })
-
- sortedBuilderNames = sorted(status.getBuilderNames())
-
- cxt['sorted_builder_names'] = sortedBuilderNames
- cxt['builder_builds'] = builder_builds = []
- cxt['builders'] = builders = []
- cxt['build_triggers'] = build_triggers = []
- cxt['range'] = range(len(stamps))
- if rev_order == "desc":
- cxt['range'].reverse()
-
- # For each sstamp we want to know the name of the builder which
- # triggered the builds and the buildid of that builder. We'll keep
- # that in a list of dicts which align with the stamps objects list.
- for _ in range(len(stamps)):
- build_triggers.append({'builder': '', 'id': ''})
-
- for bn in sortedBuilderNames:
- builds = [None] * len(stamps)
-
- builder = status.getBuilder(bn)
- if categories and builder.category not in categories:
- continue
-
- for build in self.getRecentBuilds(builder, numBuilds, branch):
- #TODO: support multiple sourcestamps
- ss = build.getSourceStamps(absolute=True)
- key = self.getSourceStampKey(ss)
-
- for i, sstamp in enumerate(stamps):
- if key == self.getSourceStampKey(sstamp) and builds[i] is None:
- builds[i] = build
- # At this point we know that there's a build for the sstamp by this builder
- # update the corresponding dict in the build_triggers list with the builder
- # name and buildid unless 'nightly' is already set as the builder name.
- if build_triggers[i].get('builder', None) != 'nightly':
- build_triggers[i]['builder'] = bn
- build_triggers[i]['id'] = str(build.getNumber())
-
- b = yield self.builder_cxt(request, builder)
- builders.append(b)
-
- builder_builds.append(map(lambda b: self.build_cxt(request, b), builds))
-
- self.clearRecentBuildsCache()
- template = request.site.buildbot_service.templates.get_template('grid_transposed.html')
- defer.returnValue(template.render(**cxt))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py
deleted file mode 100644
index 00bcb6e3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# test \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py
deleted file mode 100644
index 3980e8f9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# code inspired/copied from contrib/github_buildbot
-# and inspired from code from the Chromium project
-# otherwise, Andrew Melo <andrew.melo@gmail.com> wrote the rest
-# but "the rest" is pretty minimal
-
-from buildbot.util import json
-
-def getChanges(request, options=None):
- """
- Consumes a naive build notification (the default for now)
- basically, set POST variables to match commit object parameters:
- revision, revlink, comments, branch, who, files, links
-
- files, links and properties will be de-json'd, the rest are interpreted as strings
- """
-
- def firstOrNothing( value ):
- """
- Small helper function to return the first value (if value is a list)
- or return the whole thing otherwise
- """
- if ( type(value) == type([])):
- return value[0]
- else:
- return value
-
- args = request.args
-
- # first, convert files, links and properties
- files = None
- if args.get('files'):
- files = json.loads( args.get('files')[0] )
- else:
- files = []
-
- properties = None
- if args.get('properties'):
- properties = json.loads( args.get('properties')[0] )
- else:
- properties = {}
-
- revision = firstOrNothing(args.get('revision'))
- when = firstOrNothing(args.get('when'))
- if when is not None:
- when = float(when)
- author = firstOrNothing(args.get('author'))
- if not author:
- author = firstOrNothing(args.get('who'))
- comments = firstOrNothing(args.get('comments'))
- isdir = firstOrNothing(args.get('isdir',0))
- branch = firstOrNothing(args.get('branch'))
- category = firstOrNothing(args.get('category'))
- revlink = firstOrNothing(args.get('revlink'))
- repository = firstOrNothing(args.get('repository'))
- project = firstOrNothing(args.get('project'))
-
- chdict = dict(author=author, files=files, comments=comments,
- isdir=isdir, revision=revision, when=when,
- branch=branch, category=category, revlink=revlink,
- properties=properties, repository=repository,
- project=project)
- return ([ chdict ], None)
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py
deleted file mode 100644
index 2ff05f12..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-#!/usr/bin/env python
-"""
-github_buildbot.py is based on git_buildbot.py
-
-github_buildbot.py will determine the repository information from the JSON
-HTTP POST it receives from github.com and build the appropriate repository.
-If your github repository is private, you must add a ssh key to the github
-repository for the user who initiated the build on the buildslave.
-
-"""
-
-import re
-import datetime
-from twisted.python import log
-import calendar
-
-try:
- import json
- assert json
-except ImportError:
- import simplejson as json
-
-# python is silly about how it handles timezones
-class fixedOffset(datetime.tzinfo):
- """
- fixed offset timezone
- """
- def __init__(self, minutes, hours, offsetSign = 1):
- self.minutes = int(minutes) * offsetSign
- self.hours = int(hours) * offsetSign
- self.offset = datetime.timedelta(minutes = self.minutes,
- hours = self.hours)
-
- def utcoffset(self, dt):
- return self.offset
-
- def dst(self, dt):
- return datetime.timedelta(0)
-
-def convertTime(myTestTimestamp):
- #"1970-01-01T00:00:00+00:00"
- matcher = re.compile(r'(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)([-+])(\d\d):(\d\d)')
- result = matcher.match(myTestTimestamp)
- (year, month, day, hour, minute, second, offsetsign, houroffset, minoffset) = \
- result.groups()
- if offsetsign == '+':
- offsetsign = 1
- else:
- offsetsign = -1
-
- offsetTimezone = fixedOffset( minoffset, houroffset, offsetsign )
- myDatetime = datetime.datetime( int(year),
- int(month),
- int(day),
- int(hour),
- int(minute),
- int(second),
- 0,
- offsetTimezone)
- return calendar.timegm( myDatetime.utctimetuple() )
-
-def getChanges(request, options = None):
- """
- Reponds only to POST events and starts the build process
-
- :arguments:
- request
- the http request object
- """
- payload = json.loads(request.args['payload'][0])
- user = payload['repository']['owner']['name']
- repo = payload['repository']['name']
- repo_url = payload['repository']['url']
- project = request.args.get('project', None)
- if project:
- project = project[0]
- elif project is None:
- project = ''
- # This field is unused:
- #private = payload['repository']['private']
- changes = process_change(payload, user, repo, repo_url, project)
- log.msg("Received %s changes from github" % len(changes))
- return (changes, 'git')
-
-def process_change(payload, user, repo, repo_url, project):
- """
- Consumes the JSON as a python object and actually starts the build.
-
- :arguments:
- payload
- Python Object that represents the JSON sent by GitHub Service
- Hook.
- """
- changes = []
- newrev = payload['after']
- refname = payload['ref']
-
- # We only care about regular heads, i.e. branches
- match = re.match(r"^refs\/heads\/(.+)$", refname)
- if not match:
- log.msg("Ignoring refname `%s': Not a branch" % refname)
- return []
-
- branch = match.group(1)
- if re.match(r"^0*$", newrev):
- log.msg("Branch `%s' deleted, ignoring" % branch)
- return []
- else:
- for commit in payload['commits']:
- files = []
- if 'added' in commit:
- files.extend(commit['added'])
- if 'modified' in commit:
- files.extend(commit['modified'])
- if 'removed' in commit:
- files.extend(commit['removed'])
- when = convertTime( commit['timestamp'])
- log.msg("New revision: %s" % commit['id'][:8])
- chdict = dict(
- who = commit['author']['name']
- + " <" + commit['author']['email'] + ">",
- files = files,
- comments = commit['message'],
- revision = commit['id'],
- when = when,
- branch = branch,
- revlink = commit['url'],
- repository = repo_url,
- project = project)
- changes.append(chdict)
- return changes
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py
deleted file mode 100644
index f40cf174..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright 2011, Louis Opter <kalessin@kalessin.fr>
-
-# Quite inspired from the github hook.
-
-import hmac
-from twisted.python import log
-from buildbot.util import json
-
-class GoogleCodeAuthFailed(Exception):
- pass
-
-class Payload(object):
- def __init__(self, headers, body, branch):
- self._auth_code = headers['Google-Code-Project-Hosting-Hook-Hmac']
- self._body = body # we need to save it if we want to authenticate it
- self._branch = branch
-
- payload = json.loads(body)
- self.project = payload['project_name']
- self.repository = payload['repository_path']
- self.revisions = payload['revisions']
- self.revision_count = payload['revision_count']
-
- def authenticate(self, secret_key):
- m = hmac.new(secret_key)
- m.update(self._body)
- digest = m.hexdigest()
- return digest == self._auth_code
-
- def changes(self):
- changes = []
-
- for r in self.revisions:
- files = set()
- files.update(r['added'])
- files.update(r['modified'])
- files.update(r['removed'])
- changes.append(dict(
- author=r['author'],
- files=list(files),
- comments=r['message'],
- revision=r['revision'],
- when=r['timestamp'],
- # Let's hope Google add the branch one day:
- branch=r.get('branch', self._branch),
- revlink=r['url'],
- repository=self.repository,
- project=self.project
- ))
-
- return changes
-
-def getChanges(request, options=None):
- headers = request.received_headers
- body = request.content.getvalue()
-
- # Instantiate a Payload object: this will parse the body, get the
- # authentication code from the headers and remember the branch picked
- # up by the user (Google Code doesn't send on which branch the changes
- # were made)
- payload = Payload(headers, body, options.get('branch', 'default'))
-
- if 'secret_key' in options:
- if not payload.authenticate(options['secret_key']):
- raise GoogleCodeAuthFailed()
- else:
- log.msg("Missing secret_key in the Google Code WebHook options: "
- "cannot authenticate the request!")
-
- log.msg('Received %d changes from Google Code' %
- (payload.revision_count,))
- changes = payload.changes()
-
- return changes, 'Google Code'
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py
deleted file mode 100644
index 1ac29a4f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# This change hook allows GitHub or a hand crafted curl inovcation to "knock on
-# the door" and trigger a change source to poll.
-
-from buildbot.changes.base import PollingChangeSource
-
-
-def getChanges(req, options=None):
- change_svc = req.site.buildbot_service.master.change_svc
- poll_all = not "poller" in req.args
-
- allow_all = True
- allowed = []
- if isinstance(options, dict) and "allowed" in options:
- allow_all = False
- allowed = options["allowed"]
-
- pollers = []
-
- for source in change_svc:
- if not isinstance(source, PollingChangeSource):
- continue
- if not hasattr(source, "name"):
- continue
- if not poll_all and not source.name in req.args['poller']:
- continue
- if not allow_all and not source.name in allowed:
- continue
- pollers.append(source)
-
- if not poll_all:
- missing = set(req.args['poller']) - set(s.name for s in pollers)
- if missing:
- raise ValueError("Could not find pollers: %s" % ",".join(missing))
-
- for p in pollers:
- p.doPoll()
-
- return [], None
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py
deleted file mode 100644
index d7da8111..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from zope.interface import implements
-from twisted.python import components
-from twisted.spread import pb
-from twisted.web import server
-from twisted.web.resource import Resource, NoResource
-
-from buildbot import interfaces
-from buildbot.status import logfile
-from buildbot.status.web.base import IHTMLLog, HtmlResource, path_to_root
-
-class ChunkConsumer:
- implements(interfaces.IStatusLogConsumer)
-
- def __init__(self, original, textlog):
- self.original = original
- self.textlog = textlog
- def registerProducer(self, producer, streaming):
- self.producer = producer
- self.original.registerProducer(producer, streaming)
- def unregisterProducer(self):
- self.original.unregisterProducer()
- def writeChunk(self, chunk):
- formatted = self.textlog.content([chunk])
- try:
- if isinstance(formatted, unicode):
- formatted = formatted.encode('utf-8')
- self.original.write(formatted)
- except pb.DeadReferenceError:
- self.producing.stopProducing()
- def finish(self):
- self.textlog.finished()
-
-
-# /builders/$builder/builds/$buildnum/steps/$stepname/logs/$logname
-class TextLog(Resource):
- # a new instance of this Resource is created for each client who views
- # it, so we can afford to track the request in the Resource.
- implements(IHTMLLog)
-
- asText = False
- subscribed = False
-
- def __init__(self, original):
- Resource.__init__(self)
- self.original = original
-
- def getChild(self, path, req):
- if path == "text":
- self.asText = True
- return self
- return Resource.getChild(self, path, req)
-
- def content(self, entries):
- html_entries = []
- text_data = ''
- for type, entry in entries:
- if type >= len(logfile.ChunkTypes) or type < 0:
- # non-std channel, don't display
- continue
-
- is_header = type == logfile.HEADER
-
- if not self.asText:
- # jinja only works with unicode, or pure ascii, so assume utf-8 in logs
- if not isinstance(entry, unicode):
- entry = unicode(entry, 'utf-8', 'replace')
- html_entries.append(dict(type = logfile.ChunkTypes[type],
- text = entry,
- is_header = is_header))
- elif not is_header:
- text_data += entry
-
- if self.asText:
- return text_data
- else:
- return self.template.module.chunks(html_entries)
-
- def render_HEAD(self, req):
- self._setContentType(req)
-
- # vague approximation, ignores markup
- req.setHeader("content-length", self.original.length)
- return ''
-
- def render_GET(self, req):
- self._setContentType(req)
- self.req = req
-
- if self.original.isFinished():
- req.setHeader("Cache-Control", "max-age=604800")
- else:
- req.setHeader("Cache-Control", "no-cache")
-
- if not self.asText:
- self.template = req.site.buildbot_service.templates.get_template("logs.html")
-
- data = self.template.module.page_header(
- pageTitle = "Log File contents",
- texturl = req.childLink("text"),
- path_to_root = path_to_root(req))
- data = data.encode('utf-8')
- req.write(data)
-
- self.original.subscribeConsumer(ChunkConsumer(req, self))
- return server.NOT_DONE_YET
-
- def _setContentType(self, req):
- if self.asText:
- req.setHeader("content-type", "text/plain; charset=utf-8")
- else:
- req.setHeader("content-type", "text/html; charset=utf-8")
-
- def finished(self):
- if not self.req:
- return
- try:
- if not self.asText:
- data = self.template.module.page_footer()
- data = data.encode('utf-8')
- self.req.write(data)
- self.req.finish()
- except pb.DeadReferenceError:
- pass
- # break the cycle, the Request's .notifications list includes the
- # Deferred (from req.notifyFinish) that's pointing at us.
- self.req = None
-
- # release template
- self.template = None
-
-components.registerAdapter(TextLog, interfaces.IStatusLog, IHTMLLog)
-
-
-class HTMLLog(Resource):
- implements(IHTMLLog)
-
- def __init__(self, original):
- Resource.__init__(self)
- self.original = original
-
- def render(self, request):
- request.setHeader("content-type", "text/html")
- return self.original.html
-
-components.registerAdapter(HTMLLog, logfile.HTMLLogFile, IHTMLLog)
-
-
-class LogsResource(HtmlResource):
- addSlash = True
-
- def __init__(self, step_status):
- HtmlResource.__init__(self)
- self.step_status = step_status
-
- def getChild(self, path, req):
- for log in self.step_status.getLogs():
- if path == log.getName():
- if log.hasContents():
- return IHTMLLog(interfaces.IStatusLog(log))
- return NoResource("Empty Log '%s'" % path)
- return HtmlResource.getChild(self, path, req)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py
deleted file mode 100644
index 1bfd647c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from buildbot.status.web.base import HtmlResource, BuildLineMixin, map_branches
-
-# /one_line_per_build
-# accepts builder=, branch=, numbuilds=, reload=
-class OneLinePerBuild(HtmlResource, BuildLineMixin):
- """This shows one line per build, combining all builders together. Useful
- query arguments:
-
- numbuilds=: how many lines to display
- builder=: show only builds for this builder. Multiple builder= arguments
- can be used to see builds from any builder in the set.
- reload=: reload the page after this many seconds
- """
-
- pageTitle = "Recent Builds"
-
- def __init__(self, numbuilds=20):
- HtmlResource.__init__(self)
- self.numbuilds = numbuilds
-
- def getChild(self, path, req):
- status = self.getStatus(req)
- builder = status.getBuilder(path)
- return OneLinePerBuildOneBuilder(builder, numbuilds=self.numbuilds)
-
- def get_reload_time(self, request):
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- return max(reload_time, 15)
- except ValueError:
- pass
- return None
-
- def content(self, req, cxt):
- status = self.getStatus(req)
- numbuilds = int(req.args.get("numbuilds", [self.numbuilds])[0])
- builders = req.args.get("builder", [])
- branches = [b for b in req.args.get("branch", []) if b]
-
- g = status.generateFinishedBuilds(builders, map_branches(branches),
- numbuilds, max_search=numbuilds)
-
- cxt['refresh'] = self.get_reload_time(req)
- cxt['num_builds'] = numbuilds
- cxt['branches'] = branches
- cxt['builders'] = builders
-
- builds = cxt['builds'] = []
- for build in g:
- builds.append(self.get_line_values(req, build))
-
- cxt['authz'] = self.getAuthz(req)
-
- # get information on the builders - mostly just a count
- building = 0
- online = 0
- for bn in builders:
- builder = status.getBuilder(bn)
- builder_status = builder.getState()[0]
- if builder_status == "building":
- building += 1
- online += 1
- elif builder_status != "offline":
- online += 1
-
- cxt['num_online'] = online
- cxt['num_building'] = building
-
- template = req.site.buildbot_service.templates.get_template('onelineperbuild.html')
- return template.render(**cxt)
-
-
-
-# /one_line_per_build/$BUILDERNAME
-# accepts branch=, numbuilds=
-
-class OneLinePerBuildOneBuilder(HtmlResource, BuildLineMixin):
- def __init__(self, builder, numbuilds=20):
- HtmlResource.__init__(self)
- self.builder = builder
- self.builder_name = builder.getName()
- self.numbuilds = numbuilds
- self.pageTitle = "Recent Builds of %s" % self.builder_name
-
- def content(self, req, cxt):
- numbuilds = int(req.args.get("numbuilds", [self.numbuilds])[0])
- branches = [b for b in req.args.get("branch", []) if b]
-
- # walk backwards through all builds of a single builder
- g = self.builder.generateFinishedBuilds(map_branches(branches),
- numbuilds)
-
- cxt['builds'] = map(lambda b: self.get_line_values(req, b), g)
- cxt.update(dict(num_builds=numbuilds,
- builder_name=self.builder_name,
- branches=branches))
-
- template = req.site.buildbot_service.templates.get_template('onelineperbuildonebuilder.html')
- return template.render(**cxt)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py
deleted file mode 100644
index 01a926ed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.web.util import redirectTo
-from twisted.internet import defer
-
-from buildbot.status.web.base import HtmlResource, path_to_authzfail
-from buildbot.util.eventual import eventually
-
-class RootPage(HtmlResource):
- pageTitle = "Buildbot"
-
- @defer.inlineCallbacks
- def content(self, request, cxt):
- status = self.getStatus(request)
-
- res = yield self.getAuthz(request).actionAllowed("cleanShutdown",
- request)
-
- if request.path == '/shutdown':
- if res:
- eventually(status.cleanShutdown)
- defer.returnValue(redirectTo("/", request))
- return
- else:
- defer.returnValue(
- redirectTo(path_to_authzfail(request), request))
- return
- elif request.path == '/cancel_shutdown':
- if res:
- eventually(status.cancelCleanShutdown)
- defer.returnValue(redirectTo("/", request))
- return
- else:
- defer.returnValue(
- redirectTo(path_to_authzfail(request), request))
- return
-
- cxt.update(
- shutting_down = status.shuttingDown,
- shutdown_url = request.childLink("shutdown"),
- cancel_shutdown_url = request.childLink("cancel_shutdown"),
- )
- template = request.site.buildbot_service.templates.get_template("root.html")
- defer.returnValue(template.render(**cxt))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py
deleted file mode 100644
index 35c0ad24..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-#
-# Insipration, and some code, from:
-# :copyright: (c) 2011 by the Werkzeug Team, see Werkzeug's AUTHORS for more
-# details.
-
-try:
- from hashlib import sha1
- sha1 = sha1 # make pyflakes happy
-except ImportError:
- from sha import new as sha1
-from time import time
-from random import random
-from datetime import datetime, timedelta
-import os
-def _urandom():
- if hasattr(os, 'urandom'):
- return os.urandom(30)
- return random()
-
-def generate_cookie():
- return sha1('%s%s' % (time(), _urandom())).hexdigest()
-
-
-class Session(object):
- """I'm a user's session. Contains information about a user's session
- a user can have several session
- a session is associated with a cookie
- """
- user = ""
- infos = {}
- def __init__(self, user, infos):
- self.user = user
- self.infos = infos
- self.renew()
-
- def renew(self):
- # one day expiration. hardcoded for now...
- self.expiration = datetime.now()+ timedelta(1)
- return self.expiration
-
- def expired(self):
- return datetime.now() > self.expiration
-
- def userInfosHTML(self):
- return ('%(fullName)s [<a href="mailto:%(email)s">%(email)s</a>]' %
- (self.infos))
-
- def getExpiration(self):
- delim = '-'
- d = self.expiration.utctimetuple()
- return '%s, %02d%s%s%s%s %02d:%02d:%02d GMT' % (
- ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')[d.tm_wday],
- d.tm_mday, delim,
- ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec')[d.tm_mon - 1],
- delim, str(d.tm_year), d.tm_hour, d.tm_min, d.tm_sec
- )
-
-class SessionManager(object):
- """I'm the session manager. Holding the current sessions
- managing cookies, and their expiration
-
- KISS version for the moment:
-
- The sessions are stored in RAM so that you have to relogin after buildbot
- reboot
-
- Old sessions are searched at every connection, which is not very good for
- scaling
-
- """
-
- # borg pattern (similar to singleton) not too loose sessions with reconfig
- __shared_state = dict(sessions={},users={})
-
- def __init__(self):
- self.__dict__ = self.__shared_state
-
- def new(self, user, infos):
- cookie = generate_cookie()
- user = infos["userName"]
- self.users[user] = self.sessions[cookie] = s = Session(user, infos)
- return cookie, s
-
- def gc(self):
- """remove old cookies"""
- expired = []
- for cookie in self.sessions:
- s = self.sessions[cookie]
- if s.expired():
- expired.append(cookie)
- for cookie in expired:
- del self.sessions[cookie]
-
- def get(self, cookie):
- self.gc()
- if cookie in self.sessions:
- return self.sessions[cookie]
- return None
-
- def remove(self, cookie):
- if cookie in self.sessions:
- del self.sessions[cookie]
-
- def getUser(self, user):
- return self.users.get(user)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py
deleted file mode 100644
index 323b5463..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import time, urllib
-from twisted.web import html
-from twisted.web.util import Redirect
-from twisted.web.resource import NoResource
-from twisted.internet import defer
-
-from buildbot.status.web.base import HtmlResource, abbreviate_age, \
- BuildLineMixin, ActionResource, path_to_slave, path_to_authzfail
-from buildbot import util
-
-class ShutdownActionResource(ActionResource):
-
- def __init__(self, slave):
- self.slave = slave
- self.action = "gracefulShutdown"
-
- @defer.inlineCallbacks
- def performAction(self, request):
- res = yield self.getAuthz(request).actionAllowed(self.action,
- request,
- self.slave)
-
- url = None
- if res:
- self.slave.setGraceful(True)
- url = path_to_slave(request, self.slave)
- else:
- url = path_to_authzfail(request)
- defer.returnValue(url)
-
-class PauseActionResource(ActionResource):
-
- def __init__(self, slave, state):
- self.slave = slave
- self.action = "pauseSlave"
- self.state = state
-
- @defer.inlineCallbacks
- def performAction(self, request):
- res = yield self.getAuthz(request).actionAllowed(self.action,
- request,
- self.slave)
-
- url = None
- if res:
- self.slave.setPaused(self.state)
- url = path_to_slave(request, self.slave)
- else:
- url = path_to_authzfail(request)
- defer.returnValue(url)
-
-# /buildslaves/$slavename
-class OneBuildSlaveResource(HtmlResource, BuildLineMixin):
- addSlash = False
- def __init__(self, slavename):
- HtmlResource.__init__(self)
- self.slavename = slavename
-
- def getPageTitle(self, req):
- return "Buildbot: %s" % self.slavename
-
- def getChild(self, path, req):
- s = self.getStatus(req)
- slave = s.getSlave(self.slavename)
- if path == "shutdown":
- return ShutdownActionResource(slave)
- if path == "pause" or path == "unpause":
- return PauseActionResource(slave, path == "pause")
- return Redirect(path_to_slave(req, slave))
-
- def content(self, request, ctx):
- s = self.getStatus(request)
- slave = s.getSlave(self.slavename)
-
- my_builders = []
- for bname in s.getBuilderNames():
- b = s.getBuilder(bname)
- for bs in b.getSlaves():
- if bs.getName() == self.slavename:
- my_builders.append(b)
-
- # Current builds
- current_builds = []
- for b in my_builders:
- for cb in b.getCurrentBuilds():
- if cb.getSlavename() == self.slavename:
- current_builds.append(self.get_line_values(request, cb))
-
- try:
- max_builds = int(request.args.get('numbuilds')[0])
- except:
- max_builds = 10
-
- recent_builds = []
- n = 0
- for rb in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]):
- if rb.getSlavename() == self.slavename:
- n += 1
- recent_builds.append(self.get_line_values(request, rb))
- if n > max_builds:
- break
-
- # connects over the last hour
- slave = s.getSlave(self.slavename)
- connect_count = slave.getConnectCount()
-
- if slave.isPaused():
- pause_url = request.childLink("unpause")
- else:
- pause_url = request.childLink("pause")
-
- ctx.update(dict(slave=slave,
- slavename = self.slavename,
- current = current_builds,
- recent = recent_builds,
- shutdown_url = request.childLink("shutdown"),
- pause_url = pause_url,
- authz = self.getAuthz(request),
- this_url = "../../../" + path_to_slave(request, slave),
- access_uri = slave.getAccessURI()),
- admin = unicode(slave.getAdmin() or '', 'utf-8'),
- host = unicode(slave.getHost() or '', 'utf-8'),
- slave_version = slave.getVersion(),
- show_builder_column = True,
- connect_count = connect_count)
- template = request.site.buildbot_service.templates.get_template("buildslave.html")
- data = template.render(**ctx)
- return data
-
-# /buildslaves
-class BuildSlavesResource(HtmlResource):
- pageTitle = "BuildSlaves"
- addSlash = True
-
- def content(self, request, ctx):
- s = self.getStatus(request)
-
- #?no_builders=1 disables build column
- show_builder_column = not (request.args.get('no_builders', '0')[0])=='1'
- ctx['show_builder_column'] = show_builder_column
-
- used_by_builder = {}
- for bname in s.getBuilderNames():
- b = s.getBuilder(bname)
- for bs in b.getSlaves():
- slavename = bs.getName()
- if slavename not in used_by_builder:
- used_by_builder[slavename] = []
- used_by_builder[slavename].append(bname)
-
- slaves = ctx['slaves'] = []
- for name in util.naturalSort(s.getSlaveNames()):
- info = {}
- slaves.append(info)
- slave = s.getSlave(name)
- slave_status = s.botmaster.slaves[name].slave_status
- info['running_builds'] = len(slave_status.getRunningBuilds())
- info['link'] = request.childLink(urllib.quote(name,''))
- info['name'] = name
-
- if show_builder_column:
- info['builders'] = []
- for b in used_by_builder.get(name, []):
- info['builders'].append(dict(link=request.childLink("../builders/%s" % b), name=b))
-
- info['version'] = slave.getVersion()
- info['connected'] = slave.isConnected()
- info['connectCount'] = slave.getConnectCount()
- info['paused'] = slave.isPaused()
-
- info['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
- last = slave.lastMessageReceived()
- if last:
- info['last_heard_from_age'] = abbreviate_age(time.time() - last)
- info['last_heard_from_time'] = time.strftime("%Y-%b-%d %H:%M:%S",
- time.localtime(last))
-
- template = request.site.buildbot_service.templates.get_template("buildslaves.html")
- data = template.render(**ctx)
- return data
-
- def getChild(self, path, req):
- try:
- self.getStatus(req).getSlave(path)
- return OneBuildSlaveResource(path)
- except KeyError:
- return NoResource("No such slave '%s'" % html.escape(path))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py
deleted file mode 100644
index a725a35d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py
+++ /dev/null
@@ -1,741 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Original Copyright (c) 2010 The Chromium Authors.
-
-"""Simple JSON exporter."""
-
-import datetime
-import os
-import re
-
-from twisted.internet import defer
-from twisted.web import html, resource, server
-
-from buildbot.status.web.base import HtmlResource
-from buildbot.util import json
-
-
-_IS_INT = re.compile('^[-+]?\d+$')
-
-
-FLAGS = """\
- - as_text
- - By default, application/json is used. Setting as_text=1 change the type
- to text/plain and implicitly sets compact=0 and filter=1. Mainly useful to
- look at the result in a web browser.
- - compact
- - By default, the json data is compact and defaults to 1. For easier to read
- indented output, set compact=0.
- - select
- - By default, most children data is listed. You can do a random selection
- of data by using select=<sub-url> multiple times to coagulate data.
- "select=" includes the actual url otherwise it is skipped.
- - numbuilds
- - By default, only in memory cached builds are listed. You can as for more data
- by using numbuilds=<number>.
- - filter
- - Filters out null, false, and empty string, list and dict. This reduce the
- amount of useless data sent.
- - callback
- - Enable uses of JSONP as described in
- http://en.wikipedia.org/wiki/JSONP. Note that
- Access-Control-Allow-Origin:* is set in the HTTP response header so you
- can use this in compatible browsers.
-"""
-
-EXAMPLES = """\
- - /json
- - Root node, that *doesn't* mean all the data. Many things (like logs) must
- be explicitly queried for performance reasons.
- - /json/builders/
- - All builders.
- - /json/builders/<A_BUILDER>
- - A specific builder as compact text.
- - /json/builders/<A_BUILDER>/builds
- - All *cached* builds.
- - /json/builders/<A_BUILDER>/builds/_all
- - All builds. Warning, reads all previous build data.
- - /json/builders/<A_BUILDER>/builds/<A_BUILD>
- - Where <A_BUILD> is either positive, a build number, or negative, a past
- build.
- - /json/builders/<A_BUILDER>/builds/-1/source_stamp/changes
- - Build changes
- - /json/builders/<A_BUILDER>/builds?select=-1&select=-2
- - Two last builds on '<A_BUILDER>' builder.
- - /json/builders/<A_BUILDER>/builds?select=-1/source_stamp/changes&select=-2/source_stamp/changes
- - Changes of the two last builds on '<A_BUILDER>' builder.
- - /json/builders/<A_BUILDER>/slaves
- - Slaves associated to this builder.
- - /json/builders/<A_BUILDER>?select=&select=slaves
- - Builder information plus details information about its slaves. Neat eh?
- - /json/slaves/<A_SLAVE>
- - A specific slave.
- - /json?select=slaves/<A_SLAVE>/&select=project&select=builders/<A_BUILDER>/builds/<A_BUILD>
- - A selection of random unrelated stuff as an random example. :)
-"""
-
-
-def RequestArg(request, arg, default):
- return request.args.get(arg, [default])[0]
-
-
-def RequestArgToBool(request, arg, default):
- value = RequestArg(request, arg, default)
- if value in (False, True):
- return value
- value = value.lower()
- if value in ('1', 'true'):
- return True
- if value in ('0', 'false'):
- return False
- # Ignore value.
- return default
-
-
-def FilterOut(data):
- """Returns a copy with None, False, "", [], () and {} removed.
- Warning: converts tuple to list."""
- if isinstance(data, (list, tuple)):
- # Recurse in every items and filter them out.
- items = map(FilterOut, data)
- if not filter(lambda x: not x in ('', False, None, [], {}, ()), items):
- return None
- return items
- elif isinstance(data, dict):
- return dict(filter(lambda x: not x[1] in ('', False, None, [], {}, ()),
- [(k, FilterOut(v)) for (k, v) in data.iteritems()]))
- else:
- return data
-
-
-class JsonResource(resource.Resource):
- """Base class for json data."""
-
- contentType = "application/json"
- cache_seconds = 60
- help = None
- pageTitle = None
- level = 0
-
- def __init__(self, status):
- """Adds transparent lazy-child initialization."""
- resource.Resource.__init__(self)
- # buildbot.status.builder.Status
- self.status = status
-
- def getChildWithDefault(self, path, request):
- """Adds transparent support for url ending with /"""
- if path == "" and len(request.postpath) == 0:
- return self
- if path == 'help' and self.help:
- pageTitle = ''
- if self.pageTitle:
- pageTitle = self.pageTitle + ' help'
- return HelpResource(self.help,
- pageTitle=pageTitle,
- parent_node=self)
- # Equivalent to resource.Resource.getChildWithDefault()
- if self.children.has_key(path):
- return self.children[path]
- return self.getChild(path, request)
-
- def putChild(self, name, res):
- """Adds the resource's level for help links generation."""
-
- def RecurseFix(res, level):
- res.level = level + 1
- for c in res.children.itervalues():
- RecurseFix(c, res.level)
-
- RecurseFix(res, self.level)
- resource.Resource.putChild(self, name, res)
-
- def render_GET(self, request):
- """Renders a HTTP GET at the http request level."""
- d = defer.maybeDeferred(lambda : self.content(request))
- def handle(data):
- if isinstance(data, unicode):
- data = data.encode("utf-8")
- request.setHeader("Access-Control-Allow-Origin", "*")
- if RequestArgToBool(request, 'as_text', False):
- request.setHeader("content-type", 'text/plain')
- else:
- request.setHeader("content-type", self.contentType)
- request.setHeader("content-disposition",
- "attachment; filename=\"%s.json\"" % request.path)
- # Make sure we get fresh pages.
- if self.cache_seconds:
- now = datetime.datetime.utcnow()
- expires = now + datetime.timedelta(seconds=self.cache_seconds)
- request.setHeader("Expires",
- expires.strftime("%a, %d %b %Y %H:%M:%S GMT"))
- request.setHeader("Pragma", "no-cache")
- return data
- d.addCallback(handle)
- def ok(data):
- request.write(data)
- request.finish()
- def fail(f):
- request.processingFailed(f)
- return None # processingFailed will log this for us
- d.addCallbacks(ok, fail)
- return server.NOT_DONE_YET
-
- @defer.inlineCallbacks
- def content(self, request):
- """Renders the json dictionaries."""
- # Supported flags.
- select = request.args.get('select')
- as_text = RequestArgToBool(request, 'as_text', False)
- filter_out = RequestArgToBool(request, 'filter', as_text)
- compact = RequestArgToBool(request, 'compact', not as_text)
- callback = request.args.get('callback')
-
- # Implement filtering at global level and every child.
- if select is not None:
- del request.args['select']
- # Do not render self.asDict()!
- data = {}
- # Remove superfluous /
- select = [s.strip('/') for s in select]
- select.sort(cmp=lambda x,y: cmp(x.count('/'), y.count('/')),
- reverse=True)
- for item in select:
- # Start back at root.
- node = data
- # Implementation similar to twisted.web.resource.getChildForRequest
- # but with a hacked up request.
- child = self
- prepath = request.prepath[:]
- postpath = request.postpath[:]
- request.postpath = filter(None, item.split('/'))
- while request.postpath and not child.isLeaf:
- pathElement = request.postpath.pop(0)
- node[pathElement] = {}
- node = node[pathElement]
- request.prepath.append(pathElement)
- child = child.getChildWithDefault(pathElement, request)
-
- # some asDict methods return a Deferred, so handle that
- # properly
- if hasattr(child, 'asDict'):
- child_dict = yield defer.maybeDeferred(lambda :
- child.asDict(request))
- else:
- child_dict = {
- 'error' : 'Not available',
- }
- node.update(child_dict)
-
- request.prepath = prepath
- request.postpath = postpath
- else:
- data = yield defer.maybeDeferred(lambda : self.asDict(request))
-
- if filter_out:
- data = FilterOut(data)
- if compact:
- data = json.dumps(data, sort_keys=True, separators=(',',':'))
- else:
- data = json.dumps(data, sort_keys=True, indent=2)
- if callback:
- # Only accept things that look like identifiers for now
- callback = callback[0]
- if re.match(r'^[a-zA-Z$][a-zA-Z$0-9.]*$', callback):
- data = '%s(%s);' % (callback, data)
- defer.returnValue(data)
-
- @defer.inlineCallbacks
- def asDict(self, request):
- """Generates the json dictionary.
-
- By default, renders every childs."""
- if self.children:
- data = {}
- for name in self.children:
- child = self.getChildWithDefault(name, request)
- if isinstance(child, JsonResource):
- data[name] = yield defer.maybeDeferred(lambda :
- child.asDict(request))
- # else silently pass over non-json resources.
- defer.returnValue(data)
- else:
- raise NotImplementedError()
-
-
-def ToHtml(text):
- """Convert a string in a wiki-style format into HTML."""
- indent = 0
- in_item = False
- output = []
- for line in text.splitlines(False):
- match = re.match(r'^( +)\- (.*)$', line)
- if match:
- if indent < len(match.group(1)):
- output.append('<ul>')
- indent = len(match.group(1))
- elif indent > len(match.group(1)):
- while indent > len(match.group(1)):
- output.append('</ul>')
- indent -= 2
- if in_item:
- # Close previous item
- output.append('</li>')
- output.append('<li>')
- in_item = True
- line = match.group(2)
- elif indent:
- if line.startswith((' ' * indent) + ' '):
- # List continuation
- line = line.strip()
- else:
- # List is done
- if in_item:
- output.append('</li>')
- in_item = False
- while indent > 0:
- output.append('</ul>')
- indent -= 2
-
- if line.startswith('/'):
- if not '?' in line:
- line_full = line + '?as_text=1'
- else:
- line_full = line + '&as_text=1'
- output.append('<a href="' + html.escape(line_full) + '">' +
- html.escape(line) + '</a>')
- else:
- output.append(html.escape(line).replace(' ', '&nbsp;&nbsp;'))
- if not in_item:
- output.append('<br>')
-
- if in_item:
- output.append('</li>')
- while indent > 0:
- output.append('</ul>')
- indent -= 2
- return '\n'.join(output)
-
-
-class HelpResource(HtmlResource):
- def __init__(self, text, pageTitle, parent_node):
- HtmlResource.__init__(self)
- self.text = text
- self.pageTitle = pageTitle
- self.parent_level = parent_node.level
- self.parent_children = parent_node.children.keys()
-
- def content(self, request, cxt):
- cxt['level'] = self.parent_level
- cxt['text'] = ToHtml(self.text)
- cxt['children'] = [ n for n in self.parent_children if n != 'help' ]
- cxt['flags'] = ToHtml(FLAGS)
- cxt['examples'] = ToHtml(EXAMPLES).replace(
- 'href="/json',
- 'href="../%sjson' % (self.parent_level * '../'))
-
- template = request.site.buildbot_service.templates.get_template("jsonhelp.html")
- return template.render(**cxt)
-
-class BuilderPendingBuildsJsonResource(JsonResource):
- help = """Describe pending builds for a builder.
-"""
- pageTitle = 'Builder'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
-
- def asDict(self, request):
- # buildbot.status.builder.BuilderStatus
- d = self.builder_status.getPendingBuildRequestStatuses()
- def to_dict(statuses):
- return defer.gatherResults(
- [ b.asDict_async() for b in statuses ])
- d.addCallback(to_dict)
- return d
-
-
-class BuilderJsonResource(JsonResource):
- help = """Describe a single builder.
-"""
- pageTitle = 'Builder'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
- self.putChild('builds', BuildsJsonResource(status, builder_status))
- self.putChild('slaves', BuilderSlavesJsonResources(status,
- builder_status))
- self.putChild(
- 'pendingBuilds',
- BuilderPendingBuildsJsonResource(status, builder_status))
-
- def asDict(self, request):
- # buildbot.status.builder.BuilderStatus
- return self.builder_status.asDict_async()
-
-
-class BuildersJsonResource(JsonResource):
- help = """List of all the builders defined on a master.
-"""
- pageTitle = 'Builders'
-
- def __init__(self, status):
- JsonResource.__init__(self, status)
- for builder_name in self.status.getBuilderNames():
- self.putChild(builder_name,
- BuilderJsonResource(status,
- status.getBuilder(builder_name)))
-
-
-class BuilderSlavesJsonResources(JsonResource):
- help = """Describe the slaves attached to a single builder.
-"""
- pageTitle = 'BuilderSlaves'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
- for slave_name in self.builder_status.slavenames:
- self.putChild(slave_name,
- SlaveJsonResource(status,
- self.status.getSlave(slave_name)))
-
-
-class BuildJsonResource(JsonResource):
- help = """Describe a single build.
-"""
- pageTitle = 'Build'
-
- def __init__(self, status, build_status):
- JsonResource.__init__(self, status)
- self.build_status = build_status
- # TODO: support multiple sourcestamps
- sourcestamp = build_status.getSourceStamps()[0]
- self.putChild('source_stamp',
- SourceStampJsonResource(status, sourcestamp))
- self.putChild('steps', BuildStepsJsonResource(status, build_status))
-
- def asDict(self, request):
- return self.build_status.asDict()
-
-
-class AllBuildsJsonResource(JsonResource):
- help = """All the builds that were run on a builder.
-"""
- pageTitle = 'AllBuilds'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
-
- def getChild(self, path, request):
- # Dynamic childs.
- if isinstance(path, int) or _IS_INT.match(path):
- build_status = self.builder_status.getBuild(int(path))
- if build_status:
- return BuildJsonResource(self.status, build_status)
- return JsonResource.getChild(self, path, request)
-
- def asDict(self, request):
- results = {}
- # If max > buildCacheSize, it'll trash the cache...
- cache_size = self.builder_status.master.config.caches['Builds']
- max = int(RequestArg(request, 'max', cache_size))
- for i in range(0, max):
- child = self.getChildWithDefault(-i, request)
- if not isinstance(child, BuildJsonResource):
- continue
- results[child.build_status.getNumber()] = child.asDict(request)
- return results
-
-
-class BuildsJsonResource(AllBuildsJsonResource):
- help = """Builds that were run on a builder.
-"""
- pageTitle = 'Builds'
-
- def __init__(self, status, builder_status):
- AllBuildsJsonResource.__init__(self, status, builder_status)
- self.putChild('_all', AllBuildsJsonResource(status, builder_status))
-
- def getChild(self, path, request):
- # Transparently redirects to _all if path is not ''.
- return self.children['_all'].getChildWithDefault(path, request)
-
- def asDict(self, request):
- # This would load all the pickles and is way too heavy, especially that
- # it would trash the cache:
- # self.children['builds'].asDict(request)
- # TODO(maruel) This list should also need to be cached but how?
- builds = dict([
- (int(file), None)
- for file in os.listdir(self.builder_status.basedir)
- if _IS_INT.match(file)
- ])
- return builds
-
-
-class BuildStepJsonResource(JsonResource):
- help = """A single build step.
-"""
- pageTitle = 'BuildStep'
-
- def __init__(self, status, build_step_status):
- # buildbot.status.buildstep.BuildStepStatus
- JsonResource.__init__(self, status)
- self.build_step_status = build_step_status
- # TODO self.putChild('logs', LogsJsonResource())
-
- def asDict(self, request):
- return self.build_step_status.asDict()
-
-
-class BuildStepsJsonResource(JsonResource):
- help = """A list of build steps that occurred during a build.
-"""
- pageTitle = 'BuildSteps'
-
- def __init__(self, status, build_status):
- JsonResource.__init__(self, status)
- self.build_status = build_status
- # The build steps are constantly changing until the build is done so
- # keep a reference to build_status instead
-
- def getChild(self, path, request):
- # Dynamic childs.
- build_step_status = None
- if isinstance(path, int) or _IS_INT.match(path):
- build_step_status = self.build_status.getSteps()[int(path)]
- else:
- steps_dict = dict([(step.getName(), step)
- for step in self.build_status.getSteps()])
- build_step_status = steps_dict.get(path)
- if build_step_status:
- # Create it on-demand.
- child = BuildStepJsonResource(self.status, build_step_status)
- # Cache it.
- index = self.build_status.getSteps().index(build_step_status)
- self.putChild(str(index), child)
- self.putChild(build_step_status.getName(), child)
- return child
- return JsonResource.getChild(self, path, request)
-
- def asDict(self, request):
- # Only use the number and not the names!
- results = {}
- index = 0
- for step in self.build_status.getSteps():
- results[index] = step.asDict()
- index += 1
- return results
-
-
-class ChangeJsonResource(JsonResource):
- help = """Describe a single change that originates from a change source.
-"""
- pageTitle = 'Change'
-
- def __init__(self, status, change):
- # buildbot.changes.changes.Change
- JsonResource.__init__(self, status)
- self.change = change
-
- def asDict(self, request):
- return self.change.asDict()
-
-
-class ChangesJsonResource(JsonResource):
- help = """List of changes.
-"""
- pageTitle = 'Changes'
-
- def __init__(self, status, changes):
- JsonResource.__init__(self, status)
- for c in changes:
- # c.number can be None or clash another change if the change was
- # generated inside buildbot or if using multiple pollers.
- if c.number is not None and str(c.number) not in self.children:
- self.putChild(str(c.number), ChangeJsonResource(status, c))
- else:
- # Temporary hack since it creates information exposure.
- self.putChild(str(id(c)), ChangeJsonResource(status, c))
-
- def asDict(self, request):
- """Don't throw an exception when there is no child."""
- if not self.children:
- return {}
- return JsonResource.asDict(self, request)
-
-
-class ChangeSourcesJsonResource(JsonResource):
- help = """Describe a change source.
-"""
- pageTitle = 'ChangeSources'
-
- def asDict(self, request):
- result = {}
- n = 0
- for c in self.status.getChangeSources():
- # buildbot.changes.changes.ChangeMaster
- change = {}
- change['description'] = c.describe()
- result[n] = change
- n += 1
- return result
-
-
-class ProjectJsonResource(JsonResource):
- help = """Project-wide settings.
-"""
- pageTitle = 'Project'
-
- def asDict(self, request):
- return self.status.asDict()
-
-
-class SlaveJsonResource(JsonResource):
- help = """Describe a slave.
-"""
- pageTitle = 'Slave'
-
- def __init__(self, status, slave_status):
- JsonResource.__init__(self, status)
- self.slave_status = slave_status
- self.name = self.slave_status.getName()
- self.builders = None
-
- def getBuilders(self):
- if self.builders is None:
- # Figure out all the builders to which it's attached
- self.builders = []
- for builderName in self.status.getBuilderNames():
- if self.name in self.status.getBuilder(builderName).slavenames:
- self.builders.append(builderName)
- return self.builders
-
- def asDict(self, request):
- results = self.slave_status.asDict()
- # Enhance it by adding more informations.
- results['builders'] = {}
- for builderName in self.getBuilders():
- builds = []
- builder_status = self.status.getBuilder(builderName)
- cache_size = builder_status.master.config.caches['Builds']
- numbuilds = int(request.args.get('numbuilds', [cache_size - 1])[0])
- for i in range(1, numbuilds):
- build_status = builder_status.getBuild(-i)
- if not build_status or not build_status.isFinished():
- # If not finished, it will appear in runningBuilds.
- break
- if build_status.getSlavename() == self.name:
- builds.append(build_status.getNumber())
- results['builders'][builderName] = builds
- return results
-
-
-class SlavesJsonResource(JsonResource):
- help = """List the registered slaves.
-"""
- pageTitle = 'Slaves'
-
- def __init__(self, status):
- JsonResource.__init__(self, status)
- for slave_name in status.getSlaveNames():
- self.putChild(slave_name,
- SlaveJsonResource(status,
- status.getSlave(slave_name)))
-
-
-class SourceStampJsonResource(JsonResource):
- help = """Describe the sources for a SourceStamp.
-"""
- pageTitle = 'SourceStamp'
-
- def __init__(self, status, source_stamp):
- # buildbot.sourcestamp.SourceStamp
- JsonResource.__init__(self, status)
- self.source_stamp = source_stamp
- self.putChild('changes',
- ChangesJsonResource(status, source_stamp.changes))
- # TODO(maruel): Should redirect to the patch's url instead.
- #if source_stamp.patch:
- # self.putChild('patch', StaticHTML(source_stamp.path))
-
- def asDict(self, request):
- return self.source_stamp.asDict()
-
-class MetricsJsonResource(JsonResource):
- help = """Master metrics.
-"""
- title = "Metrics"
-
- def asDict(self, request):
- metrics = self.status.getMetrics()
- if metrics:
- return metrics.asDict()
- else:
- # Metrics are disabled
- return None
-
-
-
-class JsonStatusResource(JsonResource):
- """Retrieves all json data."""
- help = """JSON status
-
-Root page to give a fair amount of information in the current buildbot master
-status. You may want to use a child instead to reduce the load on the server.
-
-For help on any sub directory, use url /child/help
-"""
- pageTitle = 'Buildbot JSON'
-
- def __init__(self, status):
- JsonResource.__init__(self, status)
- self.level = 1
- self.putChild('builders', BuildersJsonResource(status))
- self.putChild('change_sources', ChangeSourcesJsonResource(status))
- self.putChild('project', ProjectJsonResource(status))
- self.putChild('slaves', SlavesJsonResource(status))
- self.putChild('metrics', MetricsJsonResource(status))
- # This needs to be called before the first HelpResource().body call.
- self.hackExamples()
-
- def content(self, request):
- result = JsonResource.content(self, request)
- # This is done to hook the downloaded filename.
- request.path = 'buildbot'
- return result
-
- def hackExamples(self):
- global EXAMPLES
- # Find the first builder with a previous build or select the last one.
- builder = None
- for b in self.status.getBuilderNames():
- builder = self.status.getBuilder(b)
- if builder.getBuild(-1):
- break
- if not builder:
- return
- EXAMPLES = EXAMPLES.replace('<A_BUILDER>', builder.getName())
- build = builder.getBuild(-1)
- if build:
- EXAMPLES = EXAMPLES.replace('<A_BUILD>', str(build.getNumber()))
- if builder.slavenames:
- EXAMPLES = EXAMPLES.replace('<A_SLAVE>', builder.slavenames[0])
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py
deleted file mode 100644
index 138fa3cc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import urllib
-from buildbot.status.web.base import HtmlResource, path_to_builder, \
- path_to_build, css_classes
-from buildbot.status.web.logs import LogsResource
-from buildbot import util
-from time import ctime
-
-# /builders/$builder/builds/$buildnum/steps/$stepname
-class StatusResourceBuildStep(HtmlResource):
- pageTitle = "Build Step"
- addSlash = True
-
- def __init__(self, build_status, step_status):
- HtmlResource.__init__(self)
- self.status = build_status
- self.step_status = step_status
-
- def content(self, req, cxt):
- s = self.step_status
- b = s.getBuild()
-
- logs = cxt['logs'] = []
- for l in s.getLogs():
- # FIXME: If the step name has a / in it, this is broken
- # either way. If we quote it but say '/'s are safe,
- # it chops up the step name. If we quote it and '/'s
- # are not safe, it escapes the / that separates the
- # step name from the log number.
- logs.append({'has_contents': l.hasContents(),
- 'name': l.getName(),
- 'link': req.childLink("logs/%s" % urllib.quote(l.getName())) })
-
- stepStatistics = s.getStatistics()
- statistics = cxt['statistics'] = []
- for stat in stepStatistics:
- statistics.append({'name': stat, 'value': stepStatistics[stat]})
-
- start, end = s.getTimes()
-
- if start:
- cxt['start'] = ctime(start)
- if end:
- cxt['end'] = ctime(end)
- cxt['elapsed'] = util.formatInterval(end - start)
- else:
- cxt['end'] = "Not Finished"
- cxt['elapsed'] = util.formatInterval(util.now() - start)
-
- cxt.update(dict(builder_link = path_to_builder(req, b.getBuilder()),
- build_link = path_to_build(req, b),
- b = b,
- s = s,
- result_css = css_classes[s.getResults()[0]]))
-
- template = req.site.buildbot_service.templates.get_template("buildstep.html");
- return template.render(**cxt)
-
- def getChild(self, path, req):
- if path == "logs":
- return LogsResource(self.step_status)
- return HtmlResource.getChild(self, path, req)
-
-
-
-# /builders/$builder/builds/$buildnum/steps
-class StepsResource(HtmlResource):
- addSlash = True
-
- def __init__(self, build_status):
- HtmlResource.__init__(self)
- self.build_status = build_status
-
- def content(self, req, ctx):
- return "subpages show data for each step"
-
- def getChild(self, path, req):
- for s in self.build_status.getSteps():
- if s.getName() == path:
- return StatusResourceBuildStep(self.build_status, s)
- return HtmlResource.getChild(self, path, req)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html
deleted file mode 100644
index f7b799a2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>About this Buildbot</h1>
-
-<div class="column">
-
-<h2>Version Information</h2>
-<ul>
-{% set item_class=cycler('alt', '') %}
-
- <li class="{{ item_class.next() }}">Buildbot: {{ buildbot }}</li>
- <li class="{{ item_class.next() }}">Twisted: {{ twisted }}</li>
- <li class="{{ item_class.next() }}">Jinja: {{ jinja }}</li>
- <li class="{{ item_class.next() }}">Python: {{ python }}</li>
- <li class="{{ item_class.next() }}">Buildmaster platform: {{ platform }}</li>
-
-</ul>
-
-<h2>Source code</h2>
-
-<p>Buildbot is a free software project, released under the terms of the
-<a href="http://www.gnu.org/licenses/gpl.html">GNU GPL</a>.</p>
-
-<p>Please visit the <a href="http://buildbot.net/">Buildbot Home Page</a> for
-more information, including documentation, bug reports, and source
-downloads.</p>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html
deleted file mode 100644
index bae600f7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Authentication Failed</h1>
-
-<p>The username or password you entered were not correct.
- Please go back and try again.
-</p>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html
deleted file mode 100644
index e2bfcd99..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Authorization Failed</h1>
-
-<p>You are not allowed to perform this action.
-</p>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html
deleted file mode 100644
index ec5b80b6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% macro box(text=[], comment=None) -%}
-
-{%- if comment -%}<!-- {{ comment }} -->{%- endif -%}
- <td class="{{ kwargs.class or kwargs.class_ or "" }}"
- {%- for prop in ("align", "colspan", "rowspan", "border", "valign", "halign") -%}
- {%- if prop in kwargs %} {{ prop }}="{{ kwargs[prop] }}"{% endif -%}
- {%- endfor -%}>
-
- {%- if text is string -%}
- {{ text }}
- {%- else -%}
- {{- text|join("<br/>") -}}
- {%- endif -%}
- </td>
-{% endmacro %}
-
-{# this is currently just the text part of the boxes #}
-
-{% macro build_box(reason, url, number) -%}
- <a title="Reason: {{ reason|e }}" href="{{ url }}">Build {{ number }}</a>
-{%- endmacro %}
-
-{% macro step_box(text, logs, urls, stepinfo) -%}
- {%- if text is string -%}
- {{ text }}
- {%- else -%}
- {{- text|join("<br/>") -}}
- {%- endif -%}
- <br/>
- {%- for l in logs %}
- <a {% if l.url %}href="{{ l.url }}"{% endif %}>{{ l.name|e }}</a><br/>
- {%- endfor -%}
-
- {%- for u in urls %}
- [<a href="{{ u.link }}" class="BuildStep external">{{ u.name|e }}</a>]<br/>
- {%- endfor -%}
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html
deleted file mode 100644
index 0f508880..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html
+++ /dev/null
@@ -1,238 +0,0 @@
-{% extends "layout.html" %}
-{% import 'forms.html' as forms %}
-{% from "change_macros.html" import change with context %}
-
-{% block content %}
-
-<h1>
-Builder <a href="{{ path_to_builder }}">{{ b.getBuilder().getName() }}</a>
-Build #{{ b.getNumber() }}
-</h1>
-
-<div class="column">
-
-{% if not b.isFinished() %}
- <h2>Build In Progress:</h2>
-
- {% if when_time %}
- <p>ETA: {{ when_time }} [{{ when }}]</p>
- {% endif %}
-
- {{ current_step }}
-
- {% if authz.advertiseAction('stopBuild', request) %}
- <h2>Stop Build</h2>
- {{ forms.stop_build(build_url+"/stop", authz, on_all=False, short=False, label='This Build') }}
- {% endif %}
-{% else %}
- <h2>Results:</h2>
-
- <p class="{{ result_css }} result">
- {{ b.getText()|join(' ')|capitalize }}
- </p>
-
- {% if b.getTestResults() %}
- <h3><a href="{{ tests_link }}"/></h3>
- {% endif %}
-{% endif %}
-
-<h2>
-{% if sourcestamps|count == 1 %}
-SourceStamp:
-{% else %}
-SourceStamps:
-{% endif %}
-</h2>
-
-{% for ss in sourcestamps %}
-<h3>{{ ss.codebase }}</h3>
- <table class="info" width="100%">
- {% set ss_class = cycler('alt','') %}
-
- {% if ss.project %}
- <tr class="{{ ss_class.next() }}"><td class="left">Project</td><td>{{ ss.project|projectlink }}</td></tr>
- {% endif %}
-
- {% if ss.repository %}
- <tr class="{{ ss_class.next() }}"><td class="left">Repository</td><td>{{ ss.repository|repolink }}</td></tr>
- {% endif %}
-
- {% if ss.branch %}
- <tr class="{{ ss_class.next() }}"><td class="left">Branch</td><td>{{ ss.branch|e }}</td></tr>
- {% endif %}
-
- {% if ss.revision %}
- <tr class="{{ ss_class.next() }}"><td class="left">Revision</td><td>{{ ss.revision|revlink(ss.repository) }}</td></tr>
- {% endif %}
-
- {% if got_revisions[ss.codebase] %}
- <tr class="{{ ss_class.next() }}"><td class="left">Got Revision</td><td>{{ got_revisions[ss.codebase]|revlink(ss.repository) }}</td></tr>
- {% endif %}
-
- {% if ss.patch %}
- <tr class="{{ ss_class.next() }}"><td class="left">Patch</td><td>YES</td></tr>
- {% endif %}
-
- {% if ss.changes %}
- <tr class="{{ ss_class.next() }}"><td class="left">Changes</td><td><a href="#changes-{{ ss.codebase }}">{{ ss.changes|count }} change{{ 's' if ss.changes|count > 1 else '' }}</a></td></tr>
- {% endif %}
-
- {% if not ss.branch and not ss.revision and not ss.patch and not ss.changes %}
- <tr class="{{ ss_class.next() }}"><td class="left" colspan="2">Build of most recent revision</td></tr>
- {% endif %}
- </table>
-{% endfor %}
-
-{#
- # TODO: turn this into a table, or some other sort of definition-list
- # that doesn't take up quite so much vertical space
- #}
-
-<h2>BuildSlave:</h2>
-
-{% if slave_url %}
- <a href="{{ slave_url|e }}">{{ b.getSlavename()|e }}</a>
-{% else %}
- {{ b.getSlavename()|e }}
-{% endif %}
-
-<h2>Reason:</h2>
-<p>
-{{ b.getReason()|e }}
-</p>
-
-<h2>Steps and Logfiles:</h2>
-
-{#
- # TODO:
- # urls = self.original.getURLs()
- # ex_url_class = "BuildStep external"
- # for name, target in urls.items():
- # text.append('[<a href="%s" class="%s">%s</a>]' %
- # (target, ex_url_class, html.escape(name)))
- #}
-
-<ol>
-{% for s in steps %}
- <li>
- <div class="{{ s.css_class }} result">
- <a href="{{ s.link }}">{{ s.name }}</a>
- {{ s.text }}&nbsp;<span style="float:right">{{ '( ' + s.time_to_run + ' )' if s.time_to_run else '' }}</span>
- </div>
-
- <ol>
- {% set item_class = cycler('alt', '') %}
- {% for l in s.logs %}
- <li class="{{ item_class.next() }}"><a href="{{ l.link }}">{{ l.name }}</a></li>
- {% else %}
- <li class="{{ item_class.next() }}">- no logs -</li>
- {% endfor %}
-
- {% for u in s.urls %}
- <li class="{{ item_class.next() }}"><a href="{{ u.url }}">{{ u.logname }}</a></li>
- {% endfor %}
- </ol>
- </li>
-{% endfor %}
-</ol>
-
-</div>
-<div class="column">
-
-<h2>Build Properties:</h2>
-
-<table class="info" width="100%">
-<tr><th>Name</th><th>Value</th><th>Source</th></tr>
-
-{% for p in properties %}
-{% if p.source != "Force Build Form" %}
- <tr class="{{ loop.cycle('alt', '') }}">
- <td class="left">{{ p.name|e }}</td>
- {% if p.short_value %}
- <td>{{ p.short_value|e }} .. [property value too long]</td>
- {% else %}
- {% if p.value is not mapping %}
- <td>{{ p.value|e }}</td>
- {% else %}
- <td>
- <table class="info" width="100%">
- {%- for key, value in p.value.items() recursive %}
- <tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
- {% endfor %}
- </table>
- </td>
- {% endif %}
- {% endif %}
- <td>{{ p.source|e }}</td>
- </tr>
-{% endif %}
-{% endfor %}
-</table>
-<h2>Forced Build Properties:</h2>
-<table class="info" width="100%">
-<tr><th>Name</th><th>Label</th><th>Value</th></tr>
-
-{% for p in properties %}
- {% if p.source == "Force Build Form" %}
- <tr class="{{ loop.cycle('alt', '') }}">
- <td class="left">{{ p.name|e }}</td>
- <td class="left">
- {% if p.label %}
- {{ p.label }}
- {% endif %}
- </td>
- {% if p.text %}
- <td><textarea readonly cols="{{p.cols}}" rows="{{p.rows}}">{{ p.text|e }}</textarea></td>
- {% else %}
- <td>{{ p.value|e }}</td>
- {% endif %}
- </tr>
- {% endif %}
-{% endfor %}
-</table>
-
-<h2>Responsible Users:</h2>
-
-{% if responsible_users %}
- <ol>
- {% for u in responsible_users %}
- <li class="{{ loop.cycle('alt', '') }}">{{ u|user }}</li>
- {% endfor %}
- </ol>
-{% else %}
- <p>no responsible users</p>
-{% endif %}
-
-
-<h2>Timing:</h2>
-<table class="info" width="100%">
- <tr class="alt"><td class="left">Start</td><td>{{ start }}</td></tr>
-{% if end %}
- <tr><td class="left">End</td><td>{{ end }}</td></tr>
-{% endif %}
- <tr {{ 'class="alt"' if end else '' }}><td class="left">Elapsed</td><td>{{ elapsed }}</td></tr>
-</table>
-
-</div>
-
-<br style="clear:both"/>
-
-{% if has_changes %}
- <div class="column">
- <h2>All Changes:</h2>
- {% for ss in sourcestamps %}
- {% if ss.changes %}
- <h3 id="changes-{{ ss.codebase }}"> {{ ss.codebase }}:</h3>
- <ol>
- {% for c in ss.changes %}
- <li><h3>Change #{{ c.number }}</h3>
- {{ change(c.asDict()) }}
- </li>
- {% endfor %}
- </ol>
- {% endif %}
- {% endfor %}
- </div>
-{% endif %}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html
deleted file mode 100644
index fc08b9dc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html
+++ /dev/null
@@ -1,45 +0,0 @@
-{% macro build_line(b, include_builder=False) %}
- <small>({{ b.time }})</small>
- Rev: {{ b.rev|shortrev(b.rev_repo) }}
- <span class="{{ b.class }}">{{ b.results }}</span>
- {% if include_builder %}
- <a href="{{ b.builderurl }}">{{ b.builder_name }}</a>
- {% endif %}
- <a href="{{ b.buildurl }}">#{{ b.buildnum }}</a> -
- {{ b.text|capitalize }}
-{% endmacro %}
-
-{% macro build_tr(b, include_builder=False, loop=None) %}
- <tr class="{{ loop.cycle('alt', '') if loop }}">
- <td>{{ b.time }}</td>
- <td>{{ b.rev|shortrev(b.rev_repo) }}</td>
- <td class="{{ b.class }}">{{ b.results }}</td>
- {%- if include_builder %}
- <td><a href="{{ b.builderurl }}">{{ b.builder_name }}</a></td>
- {% endif %}
- <td><a href="{{ b.buildurl }}">#{{ b.buildnum }}</a></td>
- <td class="left">{{ b.text|capitalize }}</td>
- </tr>
-{% endmacro %}
-
-{% macro build_table(builds, include_builder=False) %}
-{% if builds %}
-<table class="info">
- <tr>
- <th>Time</th>
- <th>Revision</th>
- <th>Result</th>
- {%- if include_builder %}
- <th>Builder</th>
- {% endif %}
- <th>Build #</th>
- <th>Info</th>
- </tr>
- {% for b in builds %}
- {{ build_tr(b, include_builder, loop) }}
- {% endfor %}
-</table>
-{% else %}
- No matching builds found
-{% endif %}
-{% endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html
deleted file mode 100644
index f557d7c5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html
+++ /dev/null
@@ -1,184 +0,0 @@
-{% from 'build_line.html' import build_table %}
-{% import 'forms.html' as forms %}
-
-{% extends "layout.html" %}
-
-{% block head %}
-{{ super() }}
-<script type='text/javascript'>
-// <![CDATA[
-//
-
-// Mapping OE Core branch names to bitbake branch names
-var bbvermap = {
- 'jethro': '1.28',
- 'krogoth': '1.30',
- 'morty': '1.32',
- 'pyro': '1.34',
- 'rocko': '1.36',
- 'sumo': '1.38',
- 'master': 'master'
-};
-
-var eclipseBranchFormat = "branch_eclipse-poky-";
-
-function isEclipseBranch(elementName) {
- var pattern = eclipseBranchFormat + "*";
- return new RegExp(pattern).test(elementName);
-}
-
-function updateFormBranchInputs(pokybranch) {
- var elements = document.querySelectorAll('input[name^="branch_"]');
-
- for (var i = 0, len = elements.length; i < len; i++) {
- var newval = pokybranch;
- if (elements[i].name == "branch_bitbake") {
- newval = bbvermap[pokybranch];
- } else if (isEclipseBranch(elements[i].name)) {
- eclipseRelease = elements[i].name.split(eclipseBranchFormat, 2)[1];
- // Match the Eclipse branch format
- if (pokybranch != "master") {
- newval = eclipseRelease + "/" + pokybranch;
- } else {
- newval = eclipseRelease + "-master";
- }
- } else if (elements[i].name == "branch_refkit") {
- // Refkit only tracks OE-Core master
- newval = "master";
- } else if (elements[i].name == "branch_meta-qt3") {
- // won't get a rocko, or newer, branch
- if (['jethro', 'krogoth', 'morty', 'pyro'].indexOf(pokybranch) < 0) {
- newval = "master"
- }
- } else if (elements[i].name == "branch_meta-gplv2") {
- // only has pyro and master branches
- if (pokybranch != "pyro") {
- newval = "master"
- }
- }
- elements[i].value = newval;
- }
-}
-
-// ]]>
-</script>
-{% endblock %}
-
-{% block content %}
-
-<h1>Builder {{ name }}</h1>
-
-<p>(<a href="{{ path_to_root }}waterfall?show={{ name }}">view in waterfall</a>)</p>
-
-{% if description %}
- <div class="BuilderDescription">{{ description }}</div>
-{% endif %}
-
-<div class="column">
-
-{% if current %}
- <h2>Current Builds:</h2>
- <ul>
- {% for b in current %}
- <li><a href="{{ b.link }}">{{ b.num }}</a>
- {% if b.when %}
- ETA: {{ b.when_time }} [{{ b.when }}]
- {% endif %}
-
- {{ b.current_step }}
-
- {% if authz.advertiseAction('stopBuild', request) %}
- {{ forms.stop_build(b.stop_url, authz, on_all=False, short=True, label='Build') }}
- {% endif %}
- </li>
- {% endfor %}
- </ul>
-{% else %}
- <h2>No current builds</h2>
-{% endif %}
-
-{% if pending %}
- <h2>Pending Build Requests:</h2>
- <ul>
- {% for b in pending %}
- <li><small>({{ b.when }}, waiting {{ b.delay }})</small>
-
- {% if authz.advertiseAction('cancelPendingBuild', request) %}
- {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=True, id=b.id) }}
- {% endif %}
-
- {% if b.num_changes < 4 %}
- {% for c in b.changes %}{{ c.revision|shortrev(c.repo) }}
- (<a href="{{ c.url }}">{{ c.who|email }}</a>){% if not loop.last %},{% endif %}
- {% endfor %}
- {% else %}
- ({{ b.num_changes }} changes)
- {% endif %}
-
- {% if 'owner' in b.properties %}
- <b>Forced build</b>
- by {{b.properties['owner'][0]}}
- <small>{{b.properties['reason'][0]}}</small>
- {% endif %}
- </li>
- {% endfor %}
- </ul>
-
- {% if authz.advertiseAction('cancelPendingBuild', request) %}
- {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=False, id='all') }}
- {% endif %}
-
-{% else %}
- <h2>No Pending Build Requests</h2>
-{% endif %}
-
-<h2>Recent Builds:</h2>
-
-{{ build_table(recent) }}
-
-<a href="?numbuilds={{numbuilds + 5}}">Show more</a>
-
-</div>
-<div class="column">
-
-<h2>Buildslaves:</h2>
-<table class="info">
-{% if slaves %}
-<tr>
- <th>Name</th>
- <th>Status</th>
- <th>Admin</th>
-</tr>
-{% endif %}
-{% for s in slaves %}
- <tr class="{{ loop.cycle('alt', '') }}">
- <td><b><a href="{{ s.link|e }}">{{ s.name|e }}</a></b></td>
- {% if s.connected %}
- {% if s.paused %}
- <td class="paused">paused</td>
- {% else %}
- <td class="idle">connected</td>
- {% endif %}
- {% else %}
- <td class="offline">offline</td>
- {% endif %}
- <td>{{ s.admin|email if s.admin else ""}}</td>
- </tr>
-{% else %}
- <td>no slaves attached</td>
-{% endfor %}
-</table>
-
-{% if authz.advertiseAction('pingBuilder', request) %}
- <h2>Ping slaves</h2>
- {{ forms.ping_builder(builder_url+"/ping", authz) }}
-{% endif %}
-
-{% if authz.advertiseAction('forceBuild', request) and force_schedulers != {} %}
- <h2>Force build</h2>
- {{ forms.force_build(builder_url+"/force", authz, request, False, force_schedulers=force_schedulers,default_props=default_props) }}
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html
deleted file mode 100644
index 67cb0225..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% extends 'layout.html' %}
-{% import 'forms.html' as forms %}
-{% from "box_macros.html" import box %}
-
-{% block content %}
-<h1>Builders: {{ branches|join(', ')|e }}</h1>
-
-<table>
-{% for b in builders %}
- <tr>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- {% if b.build_url %}
- <td class="LastBuild box {{ b.build_css_class }}">
- <a href="{{ b.build_url }}">{{ b.build_label }}</a>
- <br/>{{ b.build_text }}
- </td>
- {% else %}
- <td class="LastBuild box">no build</td>
- {% endif %}
- {{ box(**b.current_box) }}
- </tr>
-{% endfor %}
-</table>
-
-{% if num_building > 0 %}
- {% if authz.advertiseAction('stopAllBuilds', request) or authz.advertiseAction('stopBuild', request) %}
- <h2>Stop Selected Builds</h2>
- {{ forms.stop_build(path_to_root+"builders/_selected/stopselected", authz, on_selected=True, builders=builders, label='Selected Builds') }}
- <h2>Stop All Builds</h2>
- {{ forms.stop_build(path_to_root+"builders/_all/stopall", authz, on_all=True, label='All Builds') }}
- {% endif %}
-{% endif %}
-
-{% if authz.advertiseAction('cancelAllPendingBuilds', request) %}
- <h2>Cancel Selected Pending Builds</h2>
- {{ forms.cancel_build(path_to_root+"builders/_selected/cancelpendingselected", authz, on_selected=True, builders=builders, label='Selected Pending Builds') }}
- <h2>Cancel All Pending Builds</h2>
- {{ forms.cancel_build(path_to_root+"builders/_all/cancelpendingall", authz, on_all=True, label='All Pending Builds') }}
-{% endif %}
-
-{% if num_online > 0 %}
- {% if authz.advertiseAction('forceAllBuilds', request) or authz.advertiseAction('forceBuild', request) %}
- <h2>Force Selected Builds</h2>
- {{ forms.force_build(path_to_root+"builders/_selected/forceselected", authz, request, on_selected=True, builders=builders, force_schedulers=force_schedulers, default_props=default_props) }}
- <h2>Force All Builds</h2>
- {{ forms.force_build(path_to_root+"builders/_all/forceall", authz,request, on_all=True, force_schedulers=force_schedulers, default_props=default_props) }}
- {% endif %}
-{% endif %}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html
deleted file mode 100644
index d9f55038..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html
+++ /dev/null
@@ -1,68 +0,0 @@
-{% from 'build_line.html' import build_table, build_line %}
-{% import 'forms.html' as forms %}
-
-{% extends "layout.html" %}
-{% block content %}
-<h1>Buildslave: {{ slavename|e }}</h1>
-
-<div class="column">
-
-{% if current %}
- <h2>Currently building:</h2>
- <ul>
- {% for b in current %}
- <li>{{ build_line(b, True) }}
- <form method="post" action="{{ b.buildurl }}/stop" class="command stopbuild" style="display:inline">
- <input type="submit" value="Stop Build" />
- <input type="hidden" name="url" value="{{ this_url }}" />
- </form>
- </li>
- {% endfor %}
- </ul>
-{% else %}
- <h2>No current builds</h2>
-{% endif %}
-
-<h2>Recent builds</h2>
-{{ build_table(recent, True) }}
-
-</div>
-<div class="column">
-{% if access_uri %}
- <a href="{{ access_uri|e }}">Click to Access Slave</a>
-{% endif %}
-
-{% if admin %}
- <h2>Administrator</h2>
- <p>{{ admin|email }}</p>
-{% endif %}
-
-{% if host %}
- <h2>Slave information</h2>
- Buildbot-Slave {{ slave_version }}
- <pre>{{ host|e }}</pre>
-{% endif %}
-
-<h2>Connection Status</h2>
-<p>
-{{ connect_count }} connection(s) in the last hour
-{% if not slave.isConnected() %}
-(not currently connected)
-{% else %}
-</p>
- {% if authz.advertiseAction('gracefulShutdown', request) %}
- <h2>Graceful Shutdown</h2>
- {% if slave.getGraceful() %}
- <p>Slave will shut down gracefully when it is idle.</p>
- {% else %}
- {{ forms.graceful_shutdown(shutdown_url, authz) }}
- {% endif %}
- {% endif %}
- {% if authz.advertiseAction('pauseSlave', request) %}
- <h2>Pause Slave</h2>
- {{ forms.pause_slave(pause_url, authz, slave.isPaused()) }}
- {% endif %}
-{% endif %}
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html
deleted file mode 100644
index 567e3747..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html
+++ /dev/null
@@ -1,76 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Buildslaves</h1>
-
-<div class="column">
-
-<table class="info">
-
-<tr>
- <th>Name</th>
- {%- if show_builder_column %}
- <th>Builders</th>
- {%- endif %}
- <th>BuildBot</th>
- <th>Admin</th>
- <th>Last heard from</th>
- <th>Connects/Hour</th>
- <th>Status</th>
-</tr>
-
-{% for s in slaves %}
- <tr class="{{ loop.cycle('alt','') }}">
- <td><b><a href="{{ s.link }}">{{ s.name }}</a></b></td>
-
- {%- if show_builder_column %}
- <td>
- {%- if s.builders %}
- {%- for b in s.builders %}
- <a href="{{ b.link }}">{{ b.name }}</a>
- {%- endfor %}
- {%- else %}
- <span class="Warning">no builders</span>
- {%- endif -%}
- </td>
- {%- endif %}
-
-
- <td>{{ (s.version or '-')|e }}</td>
-
- {%- if s.admin -%}
- <td>{{ s.admin|email }}</td>
- {%- else -%}
- <td>-</td>
- {%- endif -%}
-
- <td>
- {%- if s.last_heard_from_age -%}
- {{ s.last_heard_from_age }} <small>({{ s.last_heard_from_time }})</small>
- {%- endif -%}
- </td>
- <td>
- {{ s.connectCount }}
- </td>
-
- {% if s.connected %}
- {% if s.running_builds %}
- <td class="building">Running {{ s.running_builds }} build(s)</td>
- {% elif s.paused %}
- <td class="paused">Paused</td>
- {% else %}
- <td class="idle">Idle</td>
- {% endif %}
-
- {% else %}
- <td class="offline">Not connected</td>
- {% endif %}
-
- </tr>
-{% endfor %}
-</table>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html
deleted file mode 100644
index df33878a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{% extends "layout.html" %}
-{% from "box_macros.html" import box %}
-
-{% block header %}
-{% endblock %}
-
-{% block barecontent %}
-<table>
- {% for r in rows %}
- <tr>{{ box(**r) }}</tr>
- {% endfor %}
-
- <tr>{{ box(**build) }}</tr>
-</table>
-{% endblock %}
-
-{% block footer %}
-{% endblock %}
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html
deleted file mode 100644
index c2c75140..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html
+++ /dev/null
@@ -1,73 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>
- Builder <a href="{{ builder_link }}">{{ b.getBuilder().getName() }}</a>
- build <a href="{{ build_link }}">#{{ b.getNumber() }}</a>
- step <a href="">{{ s.getName() }}</a>
-</h1>
-
-<div class="column">
-
-{% if s.isFinished() %}
- <h2>Finished</h2>
- <p class="{{ result_css }} result">
- {%- set text = s.getText() -%}
- {%- if text is string %}{{ text|e }}
- {%- else %}{{ text|join(" ")|e }}{% endif -%}
- </p>
-{% else %}
- <h2>Not Finished</h2>
- <p>ETA {{ s.getETA()|e }} seconds</p>
-{% endif %}
-
-{% set exp = s.getExpectations() %}
-{% if exp %}
- <h2>Expectations</h2>
- <ul>
- {% for e in exp %}
- <li>{{ e[0]|e }}: current={{ e[1] }}, target={{ e[2] }}</li>
- {% endfor %}
- </ul>
-{% endif %}
-
-<h2>Timing</h2>
-{% if start %}
- <table class="info">
- <tr class="alt"><td class="left">Start</td><td>{{ start }}</td></tr>
- <tr><td class="left">End</td><td>{{ end or "Not finished" }}</td></tr>
- <tr class="alt"><td class="left">Elapsed</td><td>{{ elapsed }}</td></tr>
- </table>
-{% else %}
- <b>Not started</b>
-{% endif %}
-
-<h2>Logs</h2>
-<ul>
-{% for l in logs %}
- <li class="{{ loop.cycle('alt', '') }}">
- {% if l.has_contents %}
- <a href="{{ l.link|e }}">{{ l.name|e }}</a>
- {% else %}
- {{ l.name|e }}
- {% endif %}
- </li>
-{% else %}
- <li class="alt">- No logs -</li>
-{% endfor %}
-</ul>
-
-{% if statistics %}
-<h2>Statistics</h2>
-<table class="info">
- <tr><th>Name</th><th>Value</th></tr>
- {% for stat in statistics %}
- <tr class="{{ loop.cycle('alt', '') }}"><td>{{ stat.name|e }}</td><td>{{ stat.value|e }}</td></tr>
- {% endfor %}
-</table>
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html
deleted file mode 100644
index f12161da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% extends "layout.html" %}
-{% from "change_macros.html" import change with context %}
-{% import 'forms.html' as forms %}
-
-{% block content %}
-
-<h1>{{ pageTitle }}</h1>
-
-<div class="column">
-
-{{ change(c) }}
-
-{% if authz.advertiseAction('stopChange', request) %}
- <h3>Cancel Builds For Change:</h3>
- {{ forms.stop_change_builds("/builders/_all/stopchangeall", c.number, authz) }}
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html
deleted file mode 100644
index 2ca01d9f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html
+++ /dev/null
@@ -1,76 +0,0 @@
-{% macro change(c) %}
-
-<table class="info">
- {% set row_class=cycler('alt','') %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Category</td>
- <td><b>{{ c.category }}</b></td>
- </tr>
- <tr class="{{ row_class.next() }}">
- <td class="left">Changed by</td>
- <td><b>{{ c.who|email }}</b></td>
- </tr>
- <tr class="{{ row_class.next() }}">
- <td class="left">Changed at</td>
- <td><b>{{ c.at }}</b></td>
- </tr>
-
- {% if c.repository %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Repository</td>
- <td><b>{{ c.repository|repolink }}</b></td>
- </tr>
- {% endif %} {% if c.project %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Project</td>
- <td><b>{{ c.project|projectlink }}</b></td>
- </tr>
- {% endif %} {% if c.branch %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Branch</td>
- <td><b>{{ c.branch|e }}</b></td>
- </tr>
- {% endif %} {% if c.rev %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Revision</td>
- <td>{%- if c.revlink -%}<a href="{{ c.revlink }}">{{ c.rev|e }}</a>
- {%- else -%}{{ c.rev|revlink(c.repository) }} {%- endif -%}</td>
- </tr>
- {% endif %}
-</table>
-
-{% if c.comments %}
-<h3>Comments</h3>
-<pre class="comments">{{ c.comments|changecomment(c.project) }}</pre>
-{% endif %}
-
-<h3 class="files">Changed files</h3>
-<ul>
- {% for f in c.files -%}
- <li class="{{ loop.cycle('alt', '') }}">{%- if f.url %}<a
- href="{{ f.url }}"><b>{{ f.name|e }}</b></a></li>
- {%- else %}
- <b>{{ f.name|e }}</b>
- {%- endif -%}
- </li>
- {% else %}
- <li>no files</li>
- {% endfor %}
-</ul>
-
-{% if c.properties %}
-<h3>Properties</h3>
-<table class="info">
- {% for p in c.properties %}
- <tr class="{{ loop.cycle('alt') }}">
- <td class="left">{{ p[0]|capitalize|e }}</td>
- <td>{{ p[1]|e }}</td>
- </tr>
- {% endfor %}
-</table>
-{% endif %}
-{%- endmacro %}
-
-{% macro box_contents(who, url, pageTitle, revision, project) -%}
-<a href="{{ url }}" title="{{ pageTitle|e }}">{{ who|user }}</a>
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html
deleted file mode 100644
index 24674dd5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Changesources</h1>
-
-<div class="column">
-
-{% if sources %}
- <ol>
- {% for s in sources -%}
- <li class="{{ loop.cycle('alt', '') }}">{{ s.describe() }}</li>
- {% endfor -%}
- </ol>
-{% else %}
- none (push only)
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html
deleted file mode 100644
index a51c946e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html
+++ /dev/null
@@ -1,276 +0,0 @@
-{% extends "layout.html" %}
-
-{% block head %}
-{{ super() }}
-<script type='text/javascript'>
-// <![CDATA[
-//
-
-//
-// Functions used to display the build status bubble on box click.
-//
-
-// show the build status box. This is called when the user clicks on a block.
-function showBuildBox(url, event) {
- // Find the current curson position.
- var cursorPosTop = (window.event ? window.event.clientY : event.pageY)
- var cursorPosLeft = (window.event ? window.event.clientX : event.pageX)
-
- // Offset the position by 5, to make the window appears under the cursor.
- cursorPosTop = cursorPosTop + document.body.scrollTop -5 ;
- cursorPosLeft = cursorPosLeft + document.body.scrollLeft - 5;
-
- // Move the div (hidden) under the cursor.
- var divBox = document.getElementById('divBox');
- divBox.style.top = parseInt(cursorPosTop) + 'px';
- divBox.style.left = parseInt(cursorPosLeft) + 'px';
-
- // Reload the hidden frame with the build page we want to show.
- // The onload even on this frame will update the div and make it visible.
- document.getElementById("frameBox").src = url
-
- // We don't want to reload the page.
- return false;
-}
-
-// OnLoad handler for the iframe containing the build to show.
-function updateDiv(event) {
- // Get the frame innerHTML.
- var iframeContent = document.getElementById("frameBox").contentWindow.document.body.innerHTML;
-
- // If there is any content, update the div, and make it visible.
- if (iframeContent) {
- var divBox = document.getElementById('divBox');
- divBox.innerHTML = iframeContent ;
- divBox.style.display = "block";
- }
-}
-
-// Util functions to know if an element is contained inside another element.
-// We use this to know when we mouse out our build status div.
-function containsDOM (container, containee) {
- var isParent = false;
- do {
- if ((isParent = container == containee))
- break;
- containee = containee.parentNode;
- } while (containee != null);
-
- return isParent;
-}
-
-// OnMouseOut handler. Returns true if the mouse moved out of the element.
-// It is false if the mouse is still in the element, but in a blank part of it,
-// like in an empty table cell.
-function checkMouseLeave(element, event) {
- if (element.contains && event.toElement) {
- return !element.contains(event.toElement);
- }
- else if (event.relatedTarget) {
- return !containsDOM(element, event.relatedTarget);
- }
-}
-
-// ]]>
-</script>
-{% endblock %}
-
-{% block content %}
-
-<h1>Console View</h1>
-
-<div align="center">
- <table width="95%" class="Grid" border="0" cellspacing="0">
- <tr>
- <td width="33%" align="left" class="left_align">
-{% if categories|length > 1 %}
- <br><b>Categories:</b> {% for c in categories %}{{ c.name|e }} {% endfor %}
-{% endif %}
-{% if codebase %}
- <br><b>Codebase:</b> {{ codebase|e }}
-{% endif %}
-{% if repository %}
- <br><b>Repository:</b> {{ repository|e }}
-{% endif %}
-{% if project %}
- <br><b>Project:</b> {{ project|e }}
-{% endif %}
-{% if branch != ANYBRANCH %}
- <br><b>Branch:</b> {{ branch|e }}
-{% endif %}
- </td>
- <td width="33%" align="center" class="center_align">
- <div align="center">
- <table class="info">
- <tr>
- <td>Legend:&nbsp;&nbsp;</td>
- <td class='legend success' title='All tests passed'>Passed</td>
- <td class='legend failure' title='There is a new failure. Take a look!'>Failed</td>
- <td class='legend warnings' title='Build has warnings'>Warnings</td>
- <td class='legend failure-again' title='It was failing before, and it is still failing. Make sure you did not introduce new regressions'>Failed&nbsp;Again</td>
- <td class='legend running' title='The tests are still running'>Running</td>
- <td class='legend exception' title='Something went wrong with the test, there is no result'>Exception</td>
- <td class='legend offline' title='The builder is offline, as there are no slaves connected to it'>Offline</td>
- <td class='legend notstarted' title='No result yet.'>No&nbsp;data</td>
- </tr>
- </table>
- </div>
- </td>
- <td width="33%" align="right" class="right_align">
- <script type="text/javascript">
-// <![CDATA[
- function reload_page() {
- name_value = document.getElementById('namebox').value
- if (document.location.href.lastIndexOf('?') == -1)
- document.location.href = document.location.href+ '?name=' + name_value;
- else
- document.location.href = document.location.href+ '&name=' + name_value;
- }
-// ]]>
- </script>
- <form onsubmit='reload_page()'>
- <input id='namebox' name='name' type='text' style='color:#999;'
- onblur='this.value = this.value || this.defaultValue; this.style.color = "#999";'
- onfocus='this.value=""; this.style.color = "#000";'
- value='Personalized for...'/>
- <input type='submit' value='Go'/>
- </form>
- </td>
- </tr>
- </table>
-</div>
-
-<br/>
-
-{% set alt_class = cycler('', 'Alt') %}
-
-<div align="center">
-<table width="96%">
-
-{% if categories|length > 1 %}
- <tr>
- <td width="1%">
- </td>
- <td width="1%">
- </td>
- {% for c in categories %}
- <td class='DevStatus {{ alt_class.next() }} {{ "first" if loop.first else '' }} {{ "last" if loop.last else '' }}' width='{{ c.size }}%'>
- {{ c.name|e }}
- </td>
- {% endfor %}
- </tr>
- <tr class='DevStatusSpacing'>
- </tr>
-{% endif %}
-
-{% if slaves %}
- <tr>
- <td width="1%">
- </td>
- <td width="1%">
- </td>
- {% for c in categories %}
- <td class='DevSlave {{ alt_class.next() }}'>
- <table width="100%">
- <tr>
- {% for s in slaves[c.name] %}
- <td class='DevSlaveBox'>
- <a href='{{ s.url }}' title='{{ s.pageTitle }}' class='DevSlaveBox {{ s.color }}' target="_blank">
- </a>
- </td>
- {% endfor %}
- </tr>
- </table>
- </td>
- {% endfor %}
- </tr>
-{% endif %}
-
-{% for r in revisions %}
- {% set alt = alt_class.next() %}
- {% set firstrev = "first" if loop.first else '' %}
-
- <tr>
- <td class='DevRev {{ alt }}' width="1%">
- {{ r.id|shortrev(r.repository) }}
- </td>
- <td class='DevName {{ alt }}' width="1%">
- {{ r.who|user }}
- </td>
-
- {% for c in categories %}
- {% set last = "last" if loop.last else "" %}
- <td class='DevStatus {{ alt }} {{ last if not firstrev else '' }}'>
- <table width="100%">
- <tr>
- {% for b in r.builds[c.name] %}
- <td class='DevStatusBox'>
- <a href='#' onclick='showBuildBox("{{ b.url }}", event); return false;'
- title='{{ b.pageTitle|e }}' class='DevStatusBox {{ b.color }} {{ b.tag }}'
- target="_blank"></a>
- </td>
- {% endfor %}
- </tr>
- </table>
- </td>
- {% endfor %}
- </tr>
-
- <tr>
- <td colspan="{{ r.span }}" class='DevComment {{ alt }} {% if not r.details %}DevBottom{% endif %}'>
- {{ r.comments|changecomment(r.project or None)|replace('\n', '<br/>')|replace(' ','&nbsp; ') }}
- </td>
- </tr>
-
- {% if r.details %}
- <tr>
- <td colspan="{{ r.span }}" class='DevDetails {{ alt }} DevBottom'>
- <ul style='margin: 0px; padding: 0 0 0 1.5em;'>
- {% for d in r.details %}
- <li>{{ d.buildername }}: {{ d.status }} - &nbsp;
- {%- for l in d.logs -%}
- <a href="{{ l.url }}">{{ l.name }}</a>
- {%- endfor -%}
- </li>
- {% endfor %}
- </ul>
- </td>
- </tr>
- {% endif %}
-
- <tr class='DevStatusSpacing'>
- <td>
- </td>
- </tr>
-
-{% else %}
- <tr><td>No revisions available</td></tr>
-{% endfor %}
-
-</table>
-</div>
-
-
-<div id="divBox" onmouseout="if (checkMouseLeave(this, event)) this.style.display = 'None'" class="BuildWaterfall">
-</div>
-
-
-<iframe id="frameBox" style="display: none;"></iframe>
-
-<script type="text/javascript">
-// replace 'onload="updateDiv(event);" with this, as iframe doesn't have onload event in xhtml
-window.onload = function() {
- document.getElementById('frameBox').onload = function(event) {
- updateDiv(event);
- };
-};
-</script>
-
-{% endblock %}
-
-
-{% block footer %}
-
-{{ super() }}
-{# <p>Debug info: {{ debuginfo }}</p> #}
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html
deleted file mode 100644
index 662355de..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Directory listing for {{ path }}</h1>
-
-{% set row_class = cycler('alt', '') %}
-
-<table>
-
-<tr class="{{ row_class.next() }}">
-<th style="min-width:18em">Name</th>
-<th style="min-width:8em">Size</th>
-<th style="min-width:10em">Type</th>
-<th style="min-width:10em">Encoding</th>
-</tr>
-
-{% for d in directories %}
- <tr class="directory {{ row_class.next() }}">
- <td><a href="{{ d.href }}"><b>{{ d.text }}</b></a></td>
- <td><b>{{ d.size }}</b></td>
- <td><b>{{ d.type }}</b></td>
- <td><b>{{ d.encoding }}</b></td>
- </tr>
-{% endfor %}
-
-{% for f in files %}
- <tr class="file {{ row_class.next() }}">
- <td><a href="{{ f.href }}">{{ f.text }}</a></td>
- <td>{{ f.size }}</td>
- <td>{{ f.type }}</td>
- <td>{{ f.encoding }}</td>
- </tr>
-{% endfor %}
-</table>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html
deleted file mode 100644
index 91f4e591..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-{{ content }}
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml
deleted file mode 100644
index c423e7b0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-{% from 'feed_description.html' import item_desc %}
-
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ title_url }}</id>
- <title>{{ pageTitle|e }}</title>
- {% if project_url -%}
- <link rel="self" href="{{ title_url }}/atom"/>
- <link rel="alternate" href="{{ title_url }}"/>
- {% endif %}
- {%- if description -%}
- <subtitle>{{ description }}</subtitle>
- {% endif %}
- {%- if rfc3339_pubdate -%}
- <updated>{{ rfc3339_pubdate }}</updated>
- {% endif -%}
- <author>
- <name>BuildBot</name>
- </author>
-
- {% for b in builds -%}
- <entry>
- <title>{{ b.pageTitle }}</title>
- <link href="{{ b.link }}"/>
- <content type="xhtml">
- <div xmlns="http://www.w3.org/1999/xhtml">
- {{ item_desc(b, title_url, title)|indent(6) }}
- <pre xml:space="preserve">{{ b.log_lines|join('\n')|e }}</pre>
- </div>
- </content>
- {% if b.rfc3339_pubdate -%}
- <updated>{{ b.rfc3339_pubdate }}</updated>
- <id>{{ b.guid }}</id>
- {% endif -%}
- <author>Buildbot</author>
- </entry>
-
- {% endfor -%}
-
-</feed>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html
deleted file mode 100644
index 7f387c67..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% from 'feed_sources.html' import srcs_desc %}
-
-{% macro item_desc(b, title_url, title) -%}
- <p>
- Date: {{ b.date }}<br/>
- Project home: <a href="{{ title_url }}">{{ title|e }}</a><br/>
- Builder summary: <a href="{{ b.summary_link }}">{{ b.name }}</a><br/>
- Build details: <a href="{{ b.link }}">Build {{ b.number }}</a><br/>
- Author list: <b>{{ b.responsible_users|join(', ') }}</b><br/>
- Failed step(s): <b>{{ b.failed_steps|join(', ') }}</b><br/>
- </p>
- {% for src in b.sources %}
- {{ srcs_desc(src) }}
- {% endfor %}
- <p>
- <i>Last lines of the build log:</i>
- </p>
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml
deleted file mode 100644
index 9f30112a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-{% from 'feed_description.html' import item_desc %}
-
-<?xml version="1.0" encoding="utf-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ pageTitle|e }}</title>
- <link>{{ title_url }}</link>
- <atom:link href="{{ title_url }}rss" rel="self" type="application/rss+xml"/>
- {% if language -%}
- <language>{{ language }}</language>
- {% endif %}
- {%- if description -%}
- <description>{{ description }}</description>
- {% endif %}
- {%- if rfc822_pubdate -%}
- <pubDate>{{ rfc822_pubdate }}</pubDate>
- {% endif %}
-
- {% for b in builds -%}
- <item>
- <title>{{ b.pageTitle }}</title>
- <link>{{ b.link }}</link>
- <description>
- <![CDATA[
- {{ item_desc(b, title_url, title)|indent(8) }}
- <pre>{{ b.log_lines|join('\n')|e }}</pre>
- ]]>
- </description>
- {% if b.rfc822_pubdate -%}
- <pubDate>{{ b.rfc822_pubdate }}</pubDate>
- <guid isPermaLink="false">{{ b.guid }}</guid>
- {%- endif %}
-
- </item>
-
- {% endfor %}
-
- </channel>
-</rss>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html
deleted file mode 100644
index 4ec3bc8f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% macro srcs_desc(src) -%}
- <div>
- {%- if src.codebase -%}
- <b>Codebase: {{ src.codebase }}</b><br/>
- {% endif %}
- <p>
- Repository: {{ src.repository }}<br/>
- {%- if src.branch -%}
- Branch: {{ src.branch }}<br/>
- {% endif %}
- {%- if src.revision -%}
- Revision: {{ src.revision }}<br/>
- {% endif %}
- </p>
- </div>
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html
deleted file mode 100644
index 30c664c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<hr />
-<div class="footer">
-
-<a href="{{ welcomeurl }}">Welcome Page</a>
-<br />
-
-<a href="http://buildbot.net/">Buildbot</a>-{{ version }}
-
-{% if title %}
- working for
- {% if title_url %}
- <a href="{{ title_url }}">{{ title }}</a>
- {% else %}
- {{ title }}
- {% endif %}
- project
-{% endif %}
-
-<br />
-
-Page built: {{ time }} ({{ tz }})
-</div>
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html
deleted file mode 100644
index 133c465a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html
+++ /dev/null
@@ -1,288 +0,0 @@
-
-{% macro cancel_pending_build(cancel_url, authz, short=False, id='all') %}
- <form method="post" name="cancel" action="{{ cancel_url }}" class='command cancelbuild'
- {{ 'style="display:inline"' if short else '' }}>
- {% if not short %}
- {% if id == 'all' %}
- <p>To cancel all builds, push the 'Cancel' button</p>
- <p>To cancel individual builds, click the 'Cancel' buttons above.</p>
- {% else %}
- <p>To cancel this build, push the 'Cancel' button</p>
- {% endif %}
- {% endif %}
- <input type="hidden" name="id" value="{{ id }}" />
- <input type="submit" value="Cancel" />
- </form>
-{% endmacro %}
-
-{% macro stop_change_builds(stopchange_url, changenum, authz) %}
- {% if not changenum %}
- <form method="post" action="{{ stopchange_url }}" class='command stopchange'>
- {% if changenum %}
- <p>To cancel all builds for this change, push the 'Cancel' button</p>
- {% else %}
- <p>To cancel builds for this builder for a given change, fill out the
- following field and push the 'Cancel' button</p>
- {% endif %}
-
- {% if changenum %}
- <input type="hidden" name="change" value="{{ changenum }}" />
- {% else %}
- <div class="row">
- <span class="label">Change #:</span>
- <input type="text" name="change"/>
- </div>
- {% endif %}
- <input type="submit" value="Cancel" />
- </form>
- {% endif %}
-{% endmacro %}
-
-{% macro stop_build(stop_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
- {% if not short %}
- <form method="post" name="stop_build" action="{{ stop_url }}" class='command stopbuild'
- {{ 'style="display:inline"' if short else '' }}>
- {% if not short %}
- {% if on_all %}
- <p>To stop all builds, fill out the following field and
- push the <i>Stop {{ label }}</i> button</p>
- {% elif on_selected %}
- <p>To stop selected builds, select the builders, fill out the
- following field and push the <i>Stop {{ label }}</i> button</p>
- <table>
- {% for b in builders %}
- <tr>
- <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- </tr>
- {% endfor %}
- </table>
-
- {% else %}
- <p>To stop this build, fill out the following field and
- push the <i>Stop {{ label }}</i> button</p>
- {% endif %}
- {% endif %}
-
- {% if not short %}
- <div class="row">
- <span class="label">Reason:</span>
- <input type="text" name="comments"/>
- </div>
- {% endif %}
-
- <input type="submit" value="Stop {{ label }}" />
- </form>
- {% endif %}
-{% endmacro %}
-
-{% macro cancel_build(cancel_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
- {% if not short %}
- <form method="post" name="cancel_build" action="{{ cancel_url }}" class='command cancelbuild'
- {{ 'style="display:inline"' if short else '' }}>
- {% if not short %}
- {% if on_all %}
- <p>To cancel all pending builds, fill out the following field and
- push the <i>Cancel {{ label }}</i> button</p>
- {% elif on_selected %}
- <p>To cancel selected pending builds, select the builders, fill out the
- following field and push the <i>Cancel {{ label }}</i> button</p>
- <table>
- {% for b in builders %}
- <tr>
- <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- </tr>
- {% endfor %}
- </table>
-
- {% else %}
- <p>To cancel this pending build, fill out the following field and
- push the <i>Cancel {{ label }}</i> button</p>
- {% endif %}
- {% endif %}
-
- {% if not short %}
- <div class="row">
- <span class="label">Reason:</span>
- <input type="text" name="comments"/>
- </div>
- {% endif %}
-
- <input type="submit" value="Cancel {{ label }}" />
- </form>
- {% endif %}
-{% endmacro %}
-
-{% macro force_build_scheduler_parameter(f, authz, request, sch, default_props) %}
- {% if f and not f.hide and (f.fullName != "username" or not authz.authenticated(request)) %}
- <div class="row{% for subtype in f.type %} force-{{subtype}}{%endfor%}"{% if f.name %} id="force-{{sch.name}}-{{f.fullName}}"{% endif %}>
- {% if 'text' in f.type or 'int' in f.type %}
- <span class="label">{{f.label}}</span>
- <input type='text' size='{{f.size}}' name='{{f.fullName}}' value='{{default_props[sch.name+"."+f.fullName]}}' />
- {% elif 'bool' in f.type%}
- <input type='checkbox' name='checkbox' value='{{f.fullName}}' {{default_props[sch.name+"."+f.fullName]}} />
- <span class="label">{{f.label}}</span>
- {% elif 'textarea' in f.type %}
- <span class="label">{{f.label}}</span>
- <textarea name='{{f.fullName}}' rows={{f.rows}} cols={{f.cols}}>{{default_props[sch.name+"."+f.fullName]}}</textarea>
- {% elif 'list' in f.type %}
- <span class="label">{{f.label}}</span>
- <span class="select">
- <select name='{{f.fullName}}' {{ f.multiple and "multiple" or ""}}>
- {% for c in default_props[sch.name+"."+f.fullName+".choices"] %}
- <option {{(c in default_props[sch.name+"."+f.fullName]) and "selected" or ""}}>{{c}}</option>
- {% endfor %}
- </select>
- </span>
- {% elif 'nested' in f.type %}
- {% if f.label %}<span class="label">{{f.label}}</span>{% endif %}
- {% for subfield in f.fields %}
- {{ force_build_scheduler_parameter(subfield, authz, request, sch, default_props) }}
- {% endfor %}
- {% endif %}
- </div>
- {% endif %}
-{% endmacro %}
-
-{% macro force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props) %}
- <form method="post" name="force_build" action="{{ force_url }}" class="command_forcebuild">
-
- <h3>{{ sch.name|e }}</h3>
- {% if on_all %}
- <p>To force a build on <strong>all Builders</strong>, fill out the following fields
- and push the 'Force Build' button</p>
- {% elif on_selected %}
- <p>To force a build on <strong>certain Builders</strong>, select the
- builders, fill out the following fields and push the
- 'Force Build' button</p>
-
- <table>
- {% for b in builders %}
- {% if b.name in sch.builderNames %}
- <tr>
- <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- </tr>
- {% endif %}
- {% endfor %}
- </table>
-
- {% else %}
- <p>To force a build, fill out the following fields and
- push the 'Force Build' button</p>
- {% endif %}
- <input type='hidden' name='forcescheduler' value='{{sch.name}}' />
- <p>
- <hr />
- {% if "nightly" in sch.builderNames %}
- Set up branch values for Poky branch: <select id ="select_release"
- name="build_release" onchange="updateFormBranchInputs(this.value)">
- <option value="master" selected>master</option>
- <option value="rocko">rocko</option>
- <option value="pyro">pyro</option>
- <option value="morty">morty</option>
- <option value="krogoth">krogoth</option>
- </select>
- <hr/>
- {% endif %}
-
- {% for f in sch.all_fields %}
- {{ force_build_scheduler_parameter(f, authz, request, sch, default_props) }}
- {% endfor %}
-
- <input type="submit" value="Force Build" />
- </form>
-{% endmacro %}
-{% macro force_build(force_url, authz, request, on_all=False, on_selected=False, builders=[], force_schedulers={},default_props={}) %}
- {% for name, sch in force_schedulers.items() | sort %}
- {{ force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props=default_props) }}
- {% endfor %}
-
-{% endmacro %}
-
-{% macro graceful_shutdown(shutdown_url, authz) %}
- <form method="post" action="{{ shutdown_url }}" class='command graceful_shutdown'>
-
- <p>To cause this slave to shut down gracefully when it is idle,
- push the 'Graceful Shutdown' button</p>
- <input type="submit" value="Graceful Shutdown" />
- </form>
-{% endmacro %}
-
-{% macro pause_slave(pause_url, authz, paused) %}
- <form method="post" action="{{ pause_url }}" class='command pause_slave'>
-
- {% if paused %}
- <p>To cause this slave to start running new builds again,
- push the 'Unpause Slave' button</p>
- {% else %}
- <p>To cause this slave to stop running new builds,
- push the 'Pause Slave' button</p>
- {% endif %}
-
- {% if paused %}
- <input type="submit" value="Unpause Slave" />
- {% else %}
- <input type="submit" value="Pause Slave" />
- {% endif %}
- </form>
-{% endmacro %}
-
-{% macro clean_shutdown(shutdown_url, authz) %}
- <form method="post" action="{{ shutdown_url }}" class='command clean_shutdown'>
- <p>To cause this master to shut down cleanly, push the 'Clean Shutdown' button.</p>
- <p>No other builds will be started on this master, and the master will
- stop once all current builds are finished.</p>
-
- <input type="submit" value="Clean Shutdown" />
- </form>
-{% endmacro %}
-
-{% macro cancel_clean_shutdown(cancel_shutdown_url, authz) %}
- <form method="post" action="{{ cancel_shutdown_url }}" class='command cancel_clean_shutdown'>
- <p>To cancel a previously initiated shutdown, push the 'Cancel Shutdown' button.</p>
-
- <input type="submit" value="Cancel Shutdown" />
- </form>
-{% endmacro %}
-
-{% macro ping_builder(ping_url, authz) %}
- <form method="post" action="{{ ping_url }}" class='command ping_builder'>
- <p>To ping the buildslave(s), push the 'Ping' button</p>
- <input type="submit" value="Ping Builder" />
- </form>
-{% endmacro %}
-
-{% macro rebuild_build(rebuild_url, authz, ss) %}
- <form method="post" action="{{ rebuild_url }}" class="command rebuild">
-
- {% if on_all %}
- <p>To force a build on <strong>all Builders</strong>, fill out the following fields
- and push the 'Force Build' button</p>
- {% else %}
- <p>To force a build, fill out the following fields and
- push the 'Force Build' button</p>
- {% endif %}
- <div class="row">
- <span class="label">Reason for re-running build:</span>
- <input type='text' name='comments' />
- </div>
- <div class="row">
- Rebuild using:
- <select name="useSourcestamp">
- <option value='exact' selected>Exact same revisions</option>
- <option value='updated'>Same sourcestamps (ignoring 'got revision')</option>
- </select>
- </div>
- <input type="submit" value="Rebuild" />
- </form>
-{% endmacro %}
-
-{% macro show_users(users_url, authz) %}
- <form method="post" action="{{ users_url }}" class='command show_users'>
- <p>To show users, press the 'Show Users' button</p>
-
- <input type="submit" value="Show Users" />
- </form>
-{% endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html
deleted file mode 100644
index ed44ea10..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "layout.html" %}
-{% import 'grid_macros.html' as grid with context %}
-
-{% block content %}
-
-<h1>Grid View</h1>
-
-<table class="Grid" border="0" cellspacing="0">
-
-<tr>
- <td class="title"><a href="{{ title_url }}">{{ title }}</a>
- {{ grid.category_title() }}
- </td>
-
- {% for i in range %}
- {{ grid.stamp_td(stamps[i], build_triggers[i]) }}
- {% endfor %}
-</tr>
-
-{% for builder in builders %}
- <tr>
- {{ grid.builder_td(builder) }}
- {% for build in builder.builds %}
- {{ grid.build_td(build) }}
- {% endfor %}
- </tr>
-{% endfor %}
-
-</table>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html
deleted file mode 100644
index 42a1b451..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html
+++ /dev/null
@@ -1,65 +0,0 @@
-{% macro category_title() -%}
- {% if categories %}
- <br>
- {% trans categories=categories %}
- <b>Category:</b></br>
- {% pluralize categories %}
- <b>Categories:</b><br/>
- {% endtrans %}
- {% for c in categories %}
- {{ c|e }}<br/>
- {% endfor %}
- {% endif %}
-
- {% if branch != ANYBRANCH %}
- <br><b>Branch:</b> {{ branch|e or "trunk" }}
- {% endif %}
-{%- endmacro %}
-
-
-{% macro stamp_td(sourcestamps, trigger) -%}
- <td valign="bottom" class="sourcestamp">
- {% for ss in sourcestamps %}
- {%- if ss.codebase %}{{ ss.codebase|e }}: {% endif %}
- {%- if ss.revision -%}
- <br/><b>Commit: </b>{{ ss.revision|shortrev(ss.repository) }}
- {%- else %}<br/><b>Commit: </b>latest{% endif %}
- {%- if ss.branch %} in {{ ss.branch|e }}{% endif %}
- {%- if ss.hasPatch %} [patch]{% endif -%}
- (<a href="http://errors.yoctoproject.org/Errors/Latest/Autobuilder/?filter={{ss.revision}}&type=commit">errors</a>,
- <a href="https://wiki.yoctoproject.org/wiki/BuildLog#{{trigger.builder}}_{{trigger.id}}_-_{{ss.branch}}_{{ss.revision}}">log</a>)
- <br/>
- {%- endfor %}
- </td>
-{%- endmacro %}
-
-{% macro builder_td(b) -%}
- <td valign="middle" style="text-align: center" class="builder {{ b.state }}">
- <a href="{{ b.url }}">{{ b.name }}</a>
- {%- if b.state != 'idle' or b.n_pending > 0 -%}
- <br/>({{ b.state }}
- {%- if b.n_pending > 0 -%}
- , plus {{ b.n_pending }}
- {%- endif -%}
- )
- {%- endif -%}
- {%- if b.time %}<br/><b>Time: </b> {{ b.time }} {% endif %}
- </td>
-{%- endmacro %}
-
-{% macro build_td(build) -%}
-{% if build %}
- <td valign="top" class="build {{ build.class }}" style="text-align: left" style="white-space: nowrap" valign="bottom" >
- {%- if build.release_name %}<br/><b>RELEASE NAME:</b> {{ build.release_name }}{% endif %}
- {%- if build.branchshortname %}<br/><b>Branch:</b> {{ build.branchshortname }} {% endif %}
- {%- if build.repository %}<br/><b>Repo: </b>
- {%- if build.cgiturl %} <a href="{{ build.cgiturl }}"> {% endif %}
- {{ build.repository }}
- {%- if build.cgiturl %} </a> {% endif %}
- {% endif %}
- <br/><b>Build:</b> <a href="{{ build.url }}">{{ build.text|join('<br/>') }}</a>
- </td>
-{% else %}
- <td class="build">&nbsp;</td>
-{% endif %}
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html
deleted file mode 100644
index 9b6cadad..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "layout.html" %}
-{% import 'grid_macros.html' as grid with context %}
-
-{% block content %}
-
-<h1>Transposed Grid View</h1>
-
-<table class="Grid" border="0" cellspacing="0">
-
-<tr>
- <td class="title"><a href="{{ title_url }}">{{ title }}</a>
- {{ grid.category_title() }}
- </td>
- {% for builder in builders %}
- {{ grid.builder_td(builder) }}
- {% endfor %}
-</tr>
-
-{% for i in range %}
- <tr>
- {{ grid.stamp_td(stamps[i], build_triggers[i]) }}
- {% for b in builder_builds %}
- {{ grid.build_td(b[i]) }}
- {% endfor %}
- </tr>
-{% endfor %}
-
-</table>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html
deleted file mode 100644
index 63c155b9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "layout.html" %}
-{% block content %}
-
-<p>{{ text }}</p>
-<h2>More Help:</h2>
-
-{% if level != 1 %}
-<p><a href="../help">Parent's Help</a></p>
-{% endif %}
-
-{% if children %}
-<p>Child Nodes</p>
-<ul>
-{% for child in children %}
- <li><a href="{{ child|e }}">{{ child|e }}</a>
- (<a href="{{ child|e }}/help">{{ child|e }}/help</a>)
- </li>
-{% endfor %}
-</ul>
-{% endif %}
-
-<h2>Flags:</h2>
-{{ flags }}
-
-<h2>Examples:</h2>
-{{ examples }}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html
deleted file mode 100644
index 01dfb80c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html
+++ /dev/null
@@ -1,90 +0,0 @@
-{%- block doctype -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-{% endblock %}
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- {% block head %}
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- {% if metatags %}
- {{ metatags }}
- {% endif %}
- {% if refresh %}
- <meta http-equiv="refresh" content="{{ refresh|e }}"/>
- {% endif %}
- <title>{{ pageTitle|e }}</title>
- <link rel="stylesheet" href="{{ stylesheet }}" type="text/css" />
- <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ path_to_root }}rss">
- <link rel="shortcut icon" href="{{ path_to_root }}favicon.ico">
- {% endblock %}
- </head>
- <body class="interface">
- {% block header -%}
- <div class="header">
- <a href="{{ path_to_root or '.' }}">Home</a>
- {% if authz.advertiseAction('view', request) %}
- - <a href="{{ path_to_root }}waterfall">Waterfall</a>
- <a href="{{ path_to_root }}grid">Grid</a>
- <a href="{{ path_to_root }}tgrid">T-Grid</a>
- <a href="{{ path_to_root }}console">Console</a>
- <a href="{{ path_to_root }}builders">Builders</a>
- <a href="{{ path_to_root }}one_line_per_build">Recent Builds</a>
- <a href="{{ path_to_root }}buildslaves">Buildslaves</a>
- <a href="{{ path_to_root }}changes">Changesources</a>
- {% if authz.advertiseAction('showUsersPage', request) %}
- <a href="{{ path_to_root }}users">Users</a>
- {% endif %}
- - <a href="{{ path_to_root }}json/help">JSON API</a>
- - <a href="{{ path_to_root }}about">About</a>
- {% endif %}
- <div class="auth">
- {% if authz.authenticated(request) %}
- {{ authz.getUsernameHTML(request) }}
- |<a href="{{ path_to_root }}logout">Logout</a>
- {% elif authz.useHttpHeader and authz.httpLoginUrl %}
- <a href="{{ authz.httpLoginUrl }}">Login</a>
- {% elif authz.auth %}
- <form method="post" name="login" action="{{ path_to_root }}login">
- <input type="text" name="username" size=10 />
- <input type="password" name="passwd" size=10 />
- <input type="submit" value="login" />
- </form>
- {% endif %}
- </div>
- </div>
- {% endblock %}
-
- {%- block barecontent -%}
- <hr/>
-
- {% if alert_msg != "" %}
- <div class="alert">
- {{ alert_msg }}
- </div>
- {% endif %}
-
- <div class="content">
- {%- block content -%}
- {%- endblock -%}
- </div>
- {%- endblock -%}
-
- {%- block footer -%}
- <div class="footer" style="clear:both">
- <hr/>
- <a href="http://buildbot.net/">BuildBot</a> ({{version}})
- {% if title -%}
- working for the&nbsp;
- {%- if title_url -%}
- <a href="{{ title_url }}">{{ title }}</a>
- {%- else -%}
- {{ title }}
- {%- endif -%}
- &nbsp;project.
- {%- endif -%}
- <br/>
- Page built: <b>{{ time }}</b> ({{ tz }})
- </div>
- {% endblock -%}
- </body>
-</html>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html
deleted file mode 100644
index 116bbd6a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html
+++ /dev/null
@@ -1,23 +0,0 @@
-{%- macro page_header(pageTitle, path_to_root, texturl) -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html>
- <head><title>{{ pageTitle }}</title>
- <link rel="stylesheet" href="{{ path_to_root }}default.css" type="text/css" />
- </head>
- <body class='log'>
- <a href="{{ texturl }}">(view as text)</a><br/>
- <pre>
-{%- endmacro -%}
-
-{%- macro chunks(entries) -%}
-{%- for entry in entries -%}
- <span class="{{ entry.type }}">{{ entry.text|e }}</span>
-{%- endfor -%}
-{%- endmacro -%}
-
-{%- macro page_footer() -%}
-</pre>
-</body>
-</html>
-{%- endmacro -%}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html
deleted file mode 100644
index d2484465..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html
+++ /dev/null
@@ -1,36 +0,0 @@
-{% extends "layout.html" %}
-{% from 'build_line.html' import build_table %}
-{% import 'forms.html' as forms %}
-
-{% block content %}
-<h1>Last {{ num_builds }} finished builds: {{ branches|join(', ')|e }}</h1>
-
-{% if builders %}
- <p>of builders: {{ builders|join(", ")|e }}</p>
-{% endif %}
-
-<div class="column">
-
-{{ build_table(builds, True) }}
-
-</div>
-<div class="column">
-
-{% if num_building > 0 %}
- {% if authz.advertiseAction('stopBuild', request) %}
- <h2>Stop All Builds</h2>
- {{ forms.stop_build("builders/_all/stopall", authz, on_all=True, label='All Builds') }}
- {% endif %}
-{% endif %}
-
-{% if num_online > 0 %}
- {% if authz.advertiseAction('forceAllBuilds', request) %}
- <h2>Force All Builds</h2>
- {{ forms.force_build("builders/_all/forceall", authz, request, True, force_schedulers=force_schedulers, default_props=default_props) }}
- {% endif %}
-{% endif %}
-
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html
deleted file mode 100644
index 051501f2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends "layout.html" %}
-{% from 'build_line.html' import build_line %}
-
-{% block content %}
-
-<h1>Last {{ num_builds }} builds of builder {{ builder_name|e }}:
- {{ branches|join(', ')|e }}
-</h1>
-
-<ul>
-{% for b in builds %}
- <li>{{ build_line(b) }}</li>
-{% else %}
- <li>No matching builds found</li>
-{% endfor %}
-</ul>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html
deleted file mode 100644
index 87a87a02..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{# both macro pairs must have the same signature #}
-
-{% macro id_replace(rev, url) -%}
- <span class="revision" title="Revision {{ rev }}"><a href="{{ url }}">
- {%- if rev|length > 40 %}{{ rev[:40] }}...
- {%- else %}{{ rev }}
- {%- endif -%}
- </a></span>
-{%- endmacro %}
-
-{% macro shorten_replace(short, rev, url) %}
- <div class="revision">
- <div class="short" title="Revision {{ rev }}">
- <a href="{{ url }}">{{ short }}...</a>
- </div>
- <div class="full">
- <a href="{{ url }}">{{ rev }}</a>
- </div>
- </div>
-{% endmacro %}
-
-{% macro id(rev, url) -%}
- <span class="revision" title="Revision {{ rev }}">
- {%- if rev|length > 40 %}{{ rev[:40] }}...
- {%- else %}{{ rev }}
- {%- endif -%}
- </span>
-{%- endmacro %}
-
-{% macro shorten(short, rev, url) %}
- <div class="revision">
- <div class="short" title="Revision {{ rev }}">{{ short }}...</div>
- <div class="full">{{ rev }}</div>
- </div>
-{% endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html
deleted file mode 100644
index 561973e4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html
+++ /dev/null
@@ -1,61 +0,0 @@
-{% extends 'layout.html' %}
-{% import 'forms.html' as forms %}
-
-{% block content %}
-
-<h1>Welcome to the Buildbot
-{%- if title -%}
- &nbsp;for the&nbsp;
- {%- if title_url -%}
- <a href="{{ title_url }}">{{ title }}</a>
- {%- else -%}
- {{ title }}
- {%- endif -%}
-&nbsp;project
-{%- endif -%}
-!
-</h1>
-
-<div class="column">
-
-<ul>
- {% set item_class=cycler('alt', '') %}
-
- <li class="{{ item_class.next() }}">The <a href="waterfall">Waterfall Display</a> will give you a
- time-oriented summary of recent buildbot activity. <a href="waterfall/help">Waterfall Help.</a></li>
-
- <li class="{{ item_class.next() }}">The <a href="grid">Grid Display</a> will give you a
- developer-oriented summary of recent buildbot activity.</li>
-
- <li class="{{ item_class.next() }}">The <a href="tgrid">Transposed Grid Display</a> presents
- the same information as the grid, but lists the revisions down the side.</li>
-
- <li class="{{ item_class.next() }}">The <a href="console">Console</a> presents
- a user-oriented status page.</li>
-
- <li class="{{ item_class.next() }}">The <a href="builders">Builders</a> and their most recent builds are
- here.</li>
-
- <li class="{{ item_class.next() }}"><a href="one_line_per_build">Recent Builds</a> are summarized here, one
- per line.</li>
-
- <li class="{{ item_class.next() }}"><a href="buildslaves">Buildslave</a> information</li>
- <li class="{{ item_class.next() }}"><a href="changes">Changesource</a> information.</li>
-
- <li class="{{ item_class.next() }}"><a href="about">About</a> this Buildbot</li>
-</ul>
-
-{%- if authz.advertiseAction('cleanShutdown', request) -%}
-{%- if shutting_down -%}
-Master is shutting down<br/>
-{{ forms.cancel_clean_shutdown(cancel_shutdown_url, authz) }}
-{%- else -%}
-{{ forms.clean_shutdown(shutdown_url, authz) }}
-{%- endif -%}
-{%- endif -%}
-
-<p><i>This and other pages can be overridden and customized.</i></p>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html
deleted file mode 100644
index 70dac7ae..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html
+++ /dev/null
@@ -1,34 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>
- Builder <a href="{{ builder_link }}">{{ b.getBuilder().getName() }}</a>
- build <a href="{{ build_link }}">#{{ b.getNumber() }}</a>
- test <a href="">{{ '.'.join(tr.getName()) }}</a>
-</h1>
-
-<div class="column">
-
- <h2>Result</h2>
- <p class="{{ result_css }} result">
- {{ result_word }}
- {%- set text = tr.getText() -%}
- {%- if text is string %}{{ text|e }}
- {%- else %}{{ text|join(" ")|e }}{% endif -%}
- </p>
-
-<h2>Logs</h2>
-<ul>
-{% for l in logs %}
- <h3>Log: {{ l.name|e }}</h3>
- <samp><pre>{{ l.log|e }}</pre></samp>
- </br>
-{% else %}
- <li class="alt">- No logs -</li>
-{% endfor %}
-</ul>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html
deleted file mode 100644
index eb136175..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>User: {{ user_identifier|e }}</h1>
-
-<div class="column">
-
-<table class="info">
-
-<tr>
- <th>Attribute Type</th>
- <th>Attribute Value</th>
-</tr>
-
-{% for attr in user %}
- <tr class="{{ loop.cycle('alt','') }}">
-
- <td>{{ attr|e }}</td>
- <td>{{ user[attr]|e }}</td>
-
- </tr>
-{% endfor %}
-
-</table>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html
deleted file mode 100644
index 5cb2dafc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Users</h1>
-
-<table class="info">
-
-<tr>
- <th>Uid</th>
- <th>Identifier</th>
-</tr>
-
-{% for user in users %}
- <tr class="{{ loop.cycle('alt','') }}">
-
- <td><b><a href="{{ user.user_link }}">{{ user.uid }}</a></b></td>
- <td>{{ user.identifier|e }}</td>
-
- </tr>
-{% endfor %}
-
-</table>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html
deleted file mode 100644
index e380406e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html
+++ /dev/null
@@ -1,66 +0,0 @@
-{% extends "layout.html" %}
-{% from "box_macros.html" import box %}
-
-{% block content %}
-
-<div>
- <h1 style="display: inline;">Waterfall</h1>
- <a style="float: right;" href="{{ help_url }}">waterfall help</a>
-</div>
-
-<table border="0" cellspacing="0">
-
-<tr class="LastBuild">
- <td align="right" colspan="2" class="Project">
- last build
- </td>
-
-{% for b in builders %}
- <td align="center" class="{{ b.top_class }}">
- <a href="{{ b.url }}">{{ b.name }}</a><br/>
- {{ " ".join(b.top) }}
- </td>
-{% endfor %}
-</tr>
-
-<tr class="Activity">
-<td align="right" colspan="2">current activity</td>
-
-{% for b in builders %}
- <td align="center" class="{{ b.status_class }}">
- {{ "<br/>".join(b.status) }}
- </td>
-{% endfor %}
-</tr>
-
-<tr>
-<td align="center" class="Time">{{ tz }}</td>
-<td align="center" class="Change"><a href="{{ changes_url }}">changes</a></td>
-
-{% for b in builders %}
- <td align="center" class="Builder"><a href="{{ b.url }}">{{ b.name }}</a></td>
-{% endfor %}
-</tr>
-
-{# waterfall contents goes here #}
-{% for i in range(gridlen) -%}
- <tr>
- {% for strip in grid -%}
- {%- if strip[i] -%}{{ box(**strip[i]) }}
- {%- elif no_bubble -%}{{ box() }}
- {%- endif -%}
- {%- endfor -%}
- </tr>
-{% endfor %}
-
-</table>
-
-{% if nextpage %}
- <a href="{{ nextpage }}">next page</a>
-{% endif %}
-
-{% if no_reload_page %}
- <a href="{{ no_reload_page }}">Stop Reloading</a>
-{% endif %}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html
deleted file mode 100644
index c0e5ec6e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html
+++ /dev/null
@@ -1,140 +0,0 @@
-{% extends "layout.html" %}
-{% block content %}
-
-<form action="../waterfall" method="get">
-
-<h1>The Waterfall Display</h1>
-
-<p>The Waterfall display can be controlled by adding query arguments to the
-URL. For example, if your Waterfall is accessed via the URL
-<tt>http://buildbot.example.org:8080</tt>, then you could add a
-<tt>branch=</tt> argument (described below) by going to
-<tt>http://buildbot.example.org:8080?branch=beta4</tt> instead. Remember that
-query arguments are separated from each other with ampersands, but they are
-separated from the main URL with a question mark, so to add a
-<tt>branch=</tt> and two <tt>builder=</tt> arguments, you would use
-<tt>http://buildbot.example.org:8080?branch=beta4&amp;builder=unix&amp;builder=macos</tt>.</p>
-
-<h2>Limiting the Displayed Interval</h2>
-
-<p>The <tt>last_time=</tt> argument is a unix timestamp (seconds since the
-start of 1970) that will be used as an upper bound on the interval of events
-displayed: nothing will be shown that is more recent than the given time.
-When no argument is provided, all events up to and including the most recent
-steps are included.</p>
-
-<p>The <tt>first_time=</tt> argument provides the lower bound. No events will
-be displayed that occurred <b>before</b> this timestamp. Instead of providing
-<tt>first_time=</tt>, you can provide <tt>show_time=</tt>: in this case,
-<tt>first_time</tt> will be set equal to <tt>last_time</tt> minus
-<tt>show_time</tt>. <tt>show_time</tt> overrides <tt>first_time</tt>.</p>
-
-<p>The display normally shows the latest 200 events that occurred in the
-given interval, where each timestamp on the left hand edge counts as a single
-event. You can add a <tt>num_events=</tt> argument to override this this.</p>
-
-<h2>Showing non-Build events</h2>
-
-<p>By passing <tt>show_events=true</tt>, you can add the "buildslave
-attached", "buildslave detached", and "builder reconfigured" events that
-appear in-between the actual builds.</p>
-
-<p>
-<input type="checkbox" name="show_events" value="true"
-{% if show_events_checked %} checked="checked" {% endif %}/>
-Show non-Build events
-</p>
-
-<h2>Showing only Certain Branches</h2>
-
-<p>If you provide one or more <tt>branch=</tt> arguments, the display will be
-limited to builds that used one of the given branches. If no <tt>branch=</tt>
-arguments are given, builds from all branches will be displayed.</p>
-
-Erase the text from these "Show Branch:" boxes to remove that branch filter.
-
-{% if branches %}
-<table>
- {% for b in branches %}
- <tr>
- <td>Show Branch:
- <input type="text" name="branch" value="{{ b|e }}"/>
- </td>
- </tr>
- {% endfor %}
-</table>
-{% endif %}
-
-<h2>Limiting the Builders that are Displayed</h2>
-
-<p>By adding one or more <tt>builder=</tt> arguments, the display will be
-limited to showing builds that ran on the given builders. This serves to
-limit the display to the specific named columns. If no <tt>builder=</tt>
-arguments are provided, all Builders will be displayed.</p>
-
-<p>To view a Waterfall page with only a subset of Builders displayed, select
-the Builders you are interested in here.</p>
-
-<table>
-{% for bn in all_builders %}
- <tr><td><input type="checkbox" name="builder" value="{{ bn }}"
- {% if bn in show_builders %}checked="checked"{% endif %} />
- </td><td>{{bn}}</td></tr>
-{% endfor %}
-</table>
-
-<h2>Limiting the Builds that are Displayed</h2>
-
-<p>By adding one or more <tt>committer=</tt> arguments, the display will be
-limited to showing builds that were started by the given committer. If no
-<tt>committer=</tt> arguments are provided, all builds will be displayed.</p>
-
-<p>To view a Waterfall page with only a subset of Builds displayed, select
-the committers your are interested in here.</p>
-
-Erase the text from these "Show Committer:" boxes to remove that filter.
-
-{% if committers %}
- <table>
- {% for cn in committers %}
- <tr>
- <td>
- Show Committer: <input type="text" name="committer" value="{{ cn }}">
- </td>
- </tr>
- {% endfor %}
- </table>
-{% endif %}
-
-<h2>Showing only the Builders with failures</h2>
-
-<p>By adding the <tt>failures_only=true</tt> argument, the display will be limited
-to showing builders that are currently failing. A builder is considered
-failing if the last finished build was not successful, a step in the current
-build(s) failed, or if the builder is offline.</p>
-
-<p>
- <input type="checkbox" name="failures_only" value="true"
- {% if failures_only %}checked="checked"{% endif %}/>
- Show failures only
-</p>
-
-<h2>Auto-reloading the Page</h2>
-
-<p>Adding a <tt>reload=</tt> argument will cause the page to automatically
-reload itself after that many seconds.</p>
-
-<table>
-{% for value, name in times %}
- <tr><td><input type="radio" name="reload" value="{{ value|e }}"
- {% if value == current_reload_time %}checked="checked"{% endif %}/>
- </td><td>{{ name|e }}</td></tr>
-{% endfor %}
-</table>
-
-
-<h2>Reload Waterfall Page</h2>
-
-<input type="submit" value="View Waterfall" />
-</form>
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py
deleted file mode 100644
index 52622982..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import urllib
-from buildbot.status.web.base import HtmlResource, path_to_builder, \
- path_to_build, css_classes
-from buildbot.status.builder import Results
-
-# /builders/$builder/builds/$buildnum/steps/$stepname
-class StatusResourceBuildTest(HtmlResource):
- pageTitle = "Test Result"
- addSlash = True
-
- def __init__(self, build_status, test_result):
- HtmlResource.__init__(self)
- self.status = build_status
- self.test_result = test_result
-
- def content(self, req, cxt):
- tr = self.test_result
- b = self.status
-
- cxt['b'] = self.status
- logs = cxt['logs'] = []
- for lname, log in tr.getLogs().items():
- if isinstance(log, str):
- log = log.decode('utf-8')
- logs.append({'name': lname,
- 'log': log,
- 'link': req.childLink("logs/%s" % urllib.quote(lname)) })
-
- cxt['text'] = tr.text
- cxt['result_word'] = Results[tr.getResults()]
- cxt.update(dict(builder_link = path_to_builder(req, b.getBuilder()),
- build_link = path_to_build(req, b),
- result_css = css_classes[tr.getResults()],
- b = b,
- tr = tr))
-
- template = req.site.buildbot_service.templates.get_template("testresult.html")
- return template.render(**cxt)
-
- def getChild(self, path, req):
- # if path == "logs":
- # return LogsResource(self.step_status) #TODO we need another class
- return HtmlResource.getChild(self, path, req)
-
-
-
-# /builders/$builder/builds/$buildnum/steps
-class TestsResource(HtmlResource):
- addSlash = True
- nameDelim = '.' # Test result have names like a.b.c
-
- def __init__(self, build_status):
- HtmlResource.__init__(self)
- self.build_status = build_status
-
- def content(self, req, ctx):
- # TODO list the tests
- return "subpages show data for each test"
-
- def getChild(self, path, req):
- tpath = None
- if path:
- tpath = tuple(path.split(self.nameDelim))
- if tpath:
- tr = self.build_status.getTestResults().get(tpath)
- if tr:
- return StatusResourceBuildTest(self.build_status, tr)
- return HtmlResource.getChild(self, path, req)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py
deleted file mode 100644
index 953ae68f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import urllib
-from twisted.internet import defer
-from twisted.web.util import redirectTo
-from buildbot.status.web.base import HtmlResource, path_to_authzfail, \
- path_to_root, ActionResource
-
-class UsersActionResource(ActionResource):
-
- def __init__(self):
- self.action = "showUsersPage"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- res = yield self.getAuthz(req).actionAllowed('showUsersPage', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
- # show the table
- defer.returnValue(path_to_root(req) + "users")
-
-# /users/$uid
-class OneUserResource(HtmlResource):
- addSlash = False
- def __init__(self, uid):
- HtmlResource.__init__(self)
- self.uid = int(uid)
-
- def getPageTitle (self, req):
- return "Buildbot User: %s" % self.uid
-
- def content(self, request, ctx):
- status = self.getStatus(request)
-
- d = status.master.db.users.getUser(self.uid)
- def cb(usdict):
- ctx['user_identifier'] = usdict['identifier']
- user = ctx['user'] = {}
- for attr in usdict:
- if attr not in ['uid', 'identifier', 'bb_password']:
- user[attr] = usdict[attr]
-
- template = request.site.buildbot_service.templates.get_template("user.html")
- data = template.render(**ctx)
- return data
- d.addCallback(cb)
- return d
-
-# /users
-class UsersResource(HtmlResource):
- pageTitle = "Users"
- addSlash = True
-
- def __init__(self):
- HtmlResource.__init__(self)
-
- def getChild(self, path, req):
- return OneUserResource(path)
-
- @defer.inlineCallbacks
- def content(self, req, ctx):
- res = yield self.getAuthz(req).actionAllowed('showUsersPage', req)
- if not res:
- defer.returnValue(redirectTo(path_to_authzfail(req), req))
- return
-
- s = self.getStatus(req)
-
- usdicts = yield s.master.db.users.getUsers()
- users = ctx['users'] = usdicts
-
- for user in users:
- user['user_link'] = req.childLink(urllib.quote(str(user['uid']), ''))
- template = req.site.buildbot_service.templates.get_template(
- "users.html")
- defer.returnValue(template.render(**ctx))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py
deleted file mode 100644
index 681c5768..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py
+++ /dev/null
@@ -1,813 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from zope.interface import implements
-from twisted.python import log, components
-from twisted.internet import defer
-import urllib
-
-import time, locale
-import operator
-
-from buildbot import interfaces, util
-from buildbot.status import builder, buildstep, build
-from buildbot.changes import changes
-
-from buildbot.status.web.base import Box, HtmlResource, IBox, ICurrentBox, \
- ITopBox, build_get_class, path_to_build, path_to_step, path_to_root, \
- map_branches
-
-
-def earlier(old, new):
- # minimum of two things, but "None" counts as +infinity
- if old:
- if new < old:
- return new
- return old
- return new
-
-def later(old, new):
- # maximum of two things, but "None" counts as -infinity
- if old:
- if new > old:
- return new
- return old
- return new
-
-
-class CurrentBox(components.Adapter):
- # this provides the "current activity" box, just above the builder name
- implements(ICurrentBox)
-
- def formatETA(self, prefix, eta):
- if eta is None:
- return []
- if eta < 60:
- return ["< 1 min"]
- eta_parts = ["~"]
- eta_secs = eta
- if eta_secs > 3600:
- eta_parts.append("%d hrs" % (eta_secs / 3600))
- eta_secs %= 3600
- if eta_secs > 60:
- eta_parts.append("%d mins" % (eta_secs / 60))
- eta_secs %= 60
- abstime = time.strftime("%H:%M", time.localtime(util.now()+eta))
- return [prefix, " ".join(eta_parts), "at %s" % abstime]
-
- def getBox(self, status, brcounts):
- # getState() returns offline, idle, or building
- state, builds = self.original.getState()
-
- # look for upcoming builds. We say the state is "waiting" if the
- # builder is otherwise idle and there is a scheduler which tells us a
- # build will be performed some time in the near future. TODO: this
- # functionality used to be in BuilderStatus.. maybe this code should
- # be merged back into it.
- upcoming = []
- builderName = self.original.getName()
- for s in status.getSchedulers():
- if builderName in s.listBuilderNames():
- upcoming.extend(s.getPendingBuildTimes())
- if state == "idle" and upcoming:
- state = "waiting"
-
- if state == "building":
- text = ["building"]
- if builds:
- for b in builds:
- eta = b.getETA()
- text.extend(self.formatETA("ETA in", eta))
- elif state == "offline":
- text = ["offline"]
- elif state == "idle":
- text = ["idle"]
- elif state == "waiting":
- text = ["waiting"]
- else:
- # just in case I add a state and forget to update this
- text = [state]
-
- # TODO: for now, this pending/upcoming stuff is in the "current
- # activity" box, but really it should go into a "next activity" row
- # instead. The only times it should show up in "current activity" is
- # when the builder is otherwise idle.
-
- # are any builds pending? (waiting for a slave to be free)
- brcount = brcounts[builderName]
- if brcount:
- text.append("%d pending" % brcount)
- for t in sorted(upcoming):
- if t is not None:
- eta = t - util.now()
- text.extend(self.formatETA("next in", eta))
- return Box(text, class_="Activity " + state)
-
-components.registerAdapter(CurrentBox, builder.BuilderStatus, ICurrentBox)
-
-
-class BuildTopBox(components.Adapter):
- # this provides a per-builder box at the very top of the display,
- # showing the results of the most recent build
- implements(IBox)
-
- def getBox(self, req):
- assert interfaces.IBuilderStatus(self.original)
- branches = [b for b in req.args.get("branch", []) if b]
- builder = self.original
- builds = list(builder.generateFinishedBuilds(map_branches(branches),
- num_builds=1))
- if not builds:
- return Box(["none"], class_="LastBuild")
- b = builds[0]
- url = path_to_build(req, b)
- text = b.getText()
- tests_failed = b.getSummaryStatistic('tests-failed', operator.add, 0)
- if tests_failed: text.extend(["Failed tests: %d" % tests_failed])
- # TODO: maybe add logs?
- class_ = build_get_class(b)
- return Box(text, urlbase=url, class_="LastBuild %s" % class_)
-components.registerAdapter(BuildTopBox, builder.BuilderStatus, ITopBox)
-
-class BuildBox(components.Adapter):
- # this provides the yellow "starting line" box for each build
- implements(IBox)
-
- def getBox(self, req):
- b = self.original
- number = b.getNumber()
- url = path_to_build(req, b)
- reason = b.getReason()
- template = req.site.buildbot_service.templates.get_template("box_macros.html")
- text = template.module.build_box(reason=reason,url=url,number=number)
- class_ = "start"
- if b.isFinished() and not b.getSteps():
- # the steps have been pruned, so there won't be any indication
- # of whether it succeeded or failed.
- class_ = build_get_class(b)
- return Box([text], class_="BuildStep " + class_)
-components.registerAdapter(BuildBox, build.BuildStatus, IBox)
-
-class StepBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- urlbase = path_to_step(req, self.original)
- text = self.original.getText()
- if text is None:
- log.msg("getText() gave None", urlbase)
- text = []
- text = text[:]
- logs = self.original.getLogs()
-
- cxt = dict(text=text, logs=[], urls=[], stepinfo=self)
-
- for num in range(len(logs)):
- name = logs[num].getName()
- if logs[num].hasContents():
- url = urlbase + "/logs/%s" % urllib.quote(name)
- else:
- url = None
- cxt['logs'].append(dict(name=name, url=url))
-
- for name, target in self.original.getURLs().items():
- cxt['urls'].append(dict(link=target,name=name))
-
- template = req.site.buildbot_service.templates.get_template("box_macros.html")
- text = template.module.step_box(**cxt)
-
- class_ = "BuildStep " + build_get_class(self.original)
- return Box(text, class_=class_)
-components.registerAdapter(StepBox, buildstep.BuildStepStatus, IBox)
-
-
-class EventBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- text = self.original.getText()
- class_ = "Event"
- return Box(text, class_=class_)
-components.registerAdapter(EventBox, builder.Event, IBox)
-
-
-class Spacer:
- implements(interfaces.IStatusEvent)
-
- def __init__(self, start, finish):
- self.started = start
- self.finished = finish
-
- def getTimes(self):
- return (self.started, self.finished)
- def getText(self):
- return []
-
-class SpacerBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- #b = Box(["spacer"], "white")
- b = Box([])
- b.spacer = True
- return b
-components.registerAdapter(SpacerBox, Spacer, IBox)
-
-def insertGaps(g, showEvents, lastEventTime, idleGap=2):
- debug = False
-
- e = g.next()
- starts, finishes = e.getTimes()
- if debug: log.msg("E0", starts, finishes)
- if finishes == 0:
- finishes = starts
- if debug: log.msg("E1 finishes=%s, gap=%s, lET=%s" % \
- (finishes, idleGap, lastEventTime))
- if finishes is not None and finishes + idleGap < lastEventTime:
- if debug: log.msg(" spacer0")
- yield Spacer(finishes, lastEventTime)
-
- followingEventStarts = starts
- if debug: log.msg(" fES0", starts)
- yield e
-
- while 1:
- e = g.next()
- if not showEvents and isinstance(e, builder.Event):
- continue
- starts, finishes = e.getTimes()
- if debug: log.msg("E2", starts, finishes)
- if finishes == 0:
- finishes = starts
- if finishes is not None and finishes + idleGap < followingEventStarts:
- # there is a gap between the end of this event and the beginning
- # of the next one. Insert an idle event so the waterfall display
- # shows a gap here.
- if debug:
- log.msg(" finishes=%s, gap=%s, fES=%s" % \
- (finishes, idleGap, followingEventStarts))
- yield Spacer(finishes, followingEventStarts)
- yield e
- followingEventStarts = starts
- if debug: log.msg(" fES1", starts)
-
-
-class WaterfallHelp(HtmlResource):
- pageTitle = "Waterfall Help"
-
- def __init__(self, categories=None):
- HtmlResource.__init__(self)
- self.categories = categories
-
- def content(self, request, cxt):
- status = self.getStatus(request)
-
- cxt['show_events_checked'] = request.args.get("show_events", ["false"])[0].lower() == "true"
- cxt['branches'] = [b for b in request.args.get("branch", []) if b]
- cxt['failures_only'] = request.args.get("failures_only", ["false"])[0].lower() == "true"
- cxt['committers'] = [c for c in request.args.get("committer", []) if c]
-
- # this has a set of toggle-buttons to let the user choose the
- # builders
- show_builders = request.args.get("show", [])
- show_builders.extend(request.args.get("builder", []))
- cxt['show_builders'] = show_builders
- cxt['all_builders'] = status.getBuilderNames(categories=self.categories)
-
- # a couple of radio-button selectors for refresh time will appear
- # just after that text
- times = [("none", "None"),
- ("60", "60 seconds"),
- ("300", "5 minutes"),
- ("600", "10 minutes"),
- ]
- current_reload_time = request.args.get("reload", ["none"])
- if current_reload_time:
- current_reload_time = current_reload_time[0]
- if current_reload_time not in [t[0] for t in times]:
- times.insert(0, (current_reload_time, current_reload_time) )
-
- cxt['times'] = times
- cxt['current_reload_time'] = current_reload_time
-
- template = request.site.buildbot_service.templates.get_template("waterfallhelp.html")
- return template.render(**cxt)
-
-
-class ChangeEventSource(object):
- "A wrapper around a list of changes to supply the IEventSource interface"
- def __init__(self, changes):
- self.changes = changes
- # we want them in newest-to-oldest order
- self.changes.reverse()
-
- def eventGenerator(self, branches, categories, committers, minTime):
- for change in self.changes:
- if branches and change.branch not in branches:
- continue
- if categories and change.category not in categories:
- continue
- if committers and change.author not in committers:
- continue
- if minTime and change.when < minTime:
- continue
- yield change
-
-class WaterfallStatusResource(HtmlResource):
- """This builds the main status page, with the waterfall display, and
- all child pages."""
-
- def __init__(self, categories=None, num_events=200, num_events_max=None):
- HtmlResource.__init__(self)
- self.categories = categories
- self.num_events=num_events
- self.num_events_max=num_events_max
- self.putChild("help", WaterfallHelp(categories))
-
- def getPageTitle(self, request):
- status = self.getStatus(request)
- p = status.getTitle()
- if p:
- return "BuildBot: %s" % p
- else:
- return "BuildBot"
-
- def getChangeManager(self, request):
- # TODO: this wants to go away, access it through IStatus
- return request.site.buildbot_service.getChangeSvc()
-
- def get_reload_time(self, request):
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- return max(reload_time, 15)
- except ValueError:
- pass
- return None
-
- def isSuccess(self, builderStatus):
- # Helper function to return True if the builder is not failing.
- # The function will return false if the current state is "offline",
- # the last build was not successful, or if a step from the current
- # build(s) failed.
-
- # Make sure the builder is online.
- if builderStatus.getState()[0] == 'offline':
- return False
-
- # Look at the last finished build to see if it was success or not.
- lastBuild = builderStatus.getLastFinishedBuild()
- if lastBuild and lastBuild.getResults() != builder.SUCCESS:
- return False
-
- # Check all the current builds to see if one step is already
- # failing.
- currentBuilds = builderStatus.getCurrentBuilds()
- if currentBuilds:
- for build in currentBuilds:
- for step in build.getSteps():
- if step.getResults()[0] == builder.FAILURE:
- return False
-
- # The last finished build was successful, and all the current builds
- # don't have any failed steps.
- return True
-
- def content(self, request, ctx):
- status = self.getStatus(request)
- master = request.site.buildbot_service.master
-
- # before calling content_with_db_data, make a bunch of database
- # queries. This is a sick hack, but beats rewriting the entire
- # waterfall around asynchronous calls
-
- results = {}
-
- # recent changes
- changes_d = master.db.changes.getRecentChanges(40)
- def to_changes(chdicts):
- return defer.gatherResults([
- changes.Change.fromChdict(master, chdict)
- for chdict in chdicts ])
- changes_d.addCallback(to_changes)
- def keep_changes(changes):
- results['changes'] = changes
- changes_d.addCallback(keep_changes)
-
- # build request counts for each builder
- allBuilderNames = status.getBuilderNames(categories=self.categories)
- brstatus_ds = []
- brcounts = {}
- def keep_count(statuses, builderName):
- brcounts[builderName] = len(statuses)
- for builderName in allBuilderNames:
- builder_status = status.getBuilder(builderName)
- d = builder_status.getPendingBuildRequestStatuses()
- d.addCallback(keep_count, builderName)
- brstatus_ds.append(d)
-
- # wait for it all to finish
- d = defer.gatherResults([ changes_d ] + brstatus_ds)
- def call_content(_):
- return self.content_with_db_data(results['changes'],
- brcounts, request, ctx)
- d.addCallback(call_content)
- return d
-
- def content_with_db_data(self, changes, brcounts, request, ctx):
- status = self.getStatus(request)
- ctx['refresh'] = self.get_reload_time(request)
-
- # we start with all Builders available to this Waterfall: this is
- # limited by the config-file -time categories= argument, and defaults
- # to all defined Builders.
- allBuilderNames = status.getBuilderNames(categories=self.categories)
- builders = [status.getBuilder(name) for name in allBuilderNames]
-
- # but if the URL has one or more builder= arguments (or the old show=
- # argument, which is still accepted for backwards compatibility), we
- # use that set of builders instead. We still don't show anything
- # outside the config-file time set limited by categories=.
- showBuilders = request.args.get("show", [])
- showBuilders.extend(request.args.get("builder", []))
- if showBuilders:
- builders = [b for b in builders if b.name in showBuilders]
-
- # now, if the URL has one or category= arguments, use them as a
- # filter: only show those builders which belong to one of the given
- # categories.
- showCategories = request.args.get("category", [])
- if showCategories:
- builders = [b for b in builders if b.category in showCategories]
-
- # If the URL has the failures_only=true argument, we remove all the
- # builders that are not currently red or won't be turning red at the end
- # of their current run.
- failuresOnly = request.args.get("failures_only", ["false"])[0]
- if failuresOnly.lower() == "true":
- builders = [b for b in builders if not self.isSuccess(b)]
-
- (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = \
- self.buildGrid(request, builders, changes)
-
- # start the table: top-header material
- locale_enc = locale.getdefaultlocale()[1]
- if locale_enc is not None:
- locale_tz = unicode(time.tzname[time.localtime()[-1]], locale_enc)
- else:
- locale_tz = unicode(time.tzname[time.localtime()[-1]])
- ctx['tz'] = locale_tz
- ctx['changes_url'] = request.childLink("../changes")
-
- bn = ctx['builders'] = []
-
- for name in builderNames:
- builder = status.getBuilder(name)
- top_box = ITopBox(builder).getBox(request)
- current_box = ICurrentBox(builder).getBox(status, brcounts)
- bn.append({'name': name,
- 'url': request.childLink("../builders/%s" % urllib.quote(name, safe='')),
- 'top': top_box.text,
- 'top_class': top_box.class_,
- 'status': current_box.text,
- 'status_class': current_box.class_,
- })
-
- ctx.update(self.phase2(request, changeNames + builderNames, timestamps, eventGrid,
- sourceEvents))
-
- def with_args(req, remove_args=[], new_args=[], new_path=None):
- # sigh, nevow makes this sort of manipulation easier
- newargs = req.args.copy()
- for argname in remove_args:
- newargs[argname] = []
- if "branch" in newargs:
- newargs["branch"] = [b for b in newargs["branch"] if b]
- for k,v in new_args:
- if k in newargs:
- newargs[k].append(v)
- else:
- newargs[k] = [v]
- newquery = "&amp;".join(["%s=%s" % (urllib.quote(k), urllib.quote(v))
- for k in newargs
- for v in newargs[k]
- ])
- if new_path:
- new_url = new_path
- elif req.prepath:
- new_url = req.prepath[-1]
- else:
- new_url = ''
- if newquery:
- new_url += "?" + newquery
- return new_url
-
- if timestamps:
- bottom = timestamps[-1]
- ctx['nextpage'] = with_args(request, ["last_time"],
- [("last_time", str(int(bottom)))])
-
-
- helpurl = path_to_root(request) + "waterfall/help"
- ctx['help_url'] = with_args(request, new_path=helpurl)
-
- if self.get_reload_time(request) is not None:
- ctx['no_reload_page'] = with_args(request, remove_args=["reload"])
-
- template = request.site.buildbot_service.templates.get_template("waterfall.html")
- data = template.render(**ctx)
- return data
-
- def buildGrid(self, request, builders, changes):
- debug = False
- # TODO: see if we can use a cached copy
-
- showEvents = False
- if request.args.get("show_events", ["false"])[0].lower() == "true":
- showEvents = True
- filterCategories = request.args.get('category', [])
- filterBranches = [b for b in request.args.get("branch", []) if b]
- filterBranches = map_branches(filterBranches)
- filterCommitters = [c for c in request.args.get("committer", []) if c]
- maxTime = int(request.args.get("last_time", [util.now()])[0])
- if "show_time" in request.args:
- minTime = maxTime - int(request.args["show_time"][0])
- elif "first_time" in request.args:
- minTime = int(request.args["first_time"][0])
- elif filterBranches or filterCommitters:
- minTime = util.now() - 24 * 60 * 60
- else:
- minTime = 0
- spanLength = 10 # ten-second chunks
- req_events=int(request.args.get("num_events", [self.num_events])[0])
- if self.num_events_max and req_events > self.num_events_max:
- maxPageLen = self.num_events_max
- else:
- maxPageLen = req_events
-
- # first step is to walk backwards in time, asking each column
- # (commit, all builders) if they have any events there. Build up the
- # array of events, and stop when we have a reasonable number.
-
- commit_source = ChangeEventSource(changes)
-
- lastEventTime = util.now()
- sources = [commit_source] + builders
- changeNames = ["changes"]
- builderNames = map(lambda builder: builder.getName(), builders)
- sourceNames = changeNames + builderNames
- sourceEvents = []
- sourceGenerators = []
-
- def get_event_from(g):
- try:
- while True:
- e = g.next()
- # e might be buildstep.BuildStepStatus,
- # builder.BuildStatus, builder.Event,
- # waterfall.Spacer(builder.Event), or changes.Change .
- # The showEvents=False flag means we should hide
- # builder.Event .
- if not showEvents and isinstance(e, builder.Event):
- continue
-
- if isinstance(e, buildstep.BuildStepStatus):
- # unfinished steps are always shown
- if e.isFinished() and e.isHidden():
- continue
-
- break
- event = interfaces.IStatusEvent(e)
- if debug:
- log.msg("gen %s gave1 %s" % (g, event.getText()))
- except StopIteration:
- event = None
- return event
-
- for s in sources:
- gen = insertGaps(s.eventGenerator(filterBranches,
- filterCategories,
- filterCommitters,
- minTime),
- showEvents,
- lastEventTime)
- sourceGenerators.append(gen)
- # get the first event
- sourceEvents.append(get_event_from(gen))
- eventGrid = []
- timestamps = []
-
- lastEventTime = 0
- for e in sourceEvents:
- if e and e.getTimes()[0] > lastEventTime:
- lastEventTime = e.getTimes()[0]
- if lastEventTime == 0:
- lastEventTime = util.now()
-
- spanStart = lastEventTime - spanLength
- debugGather = 0
-
- while 1:
- if debugGather: log.msg("checking (%s,]" % spanStart)
- # the tableau of potential events is in sourceEvents[]. The
- # window crawls backwards, and we examine one source at a time.
- # If the source's top-most event is in the window, is it pushed
- # onto the events[] array and the tableau is refilled. This
- # continues until the tableau event is not in the window (or is
- # missing).
-
- spanEvents = [] # for all sources, in this span. row of eventGrid
- firstTimestamp = None # timestamp of first event in the span
- lastTimestamp = None # last pre-span event, for next span
-
- for c in range(len(sourceGenerators)):
- events = [] # for this source, in this span. cell of eventGrid
- event = sourceEvents[c]
- while event and spanStart < event.getTimes()[0]:
- # to look at windows that don't end with the present,
- # condition the .append on event.time <= spanFinish
- if not IBox(event, None):
- log.msg("BAD EVENT", event, event.getText())
- assert 0
- if debug:
- log.msg("pushing", event.getText(), event)
- events.append(event)
- starts, finishes = event.getTimes()
- firstTimestamp = earlier(firstTimestamp, starts)
- event = get_event_from(sourceGenerators[c])
- if debug:
- log.msg("finished span")
-
- if event:
- # this is the last pre-span event for this source
- lastTimestamp = later(lastTimestamp,
- event.getTimes()[0])
- if debugGather:
- log.msg(" got %s from %s" % (events, sourceNames[c]))
- sourceEvents[c] = event # refill the tableau
- spanEvents.append(events)
-
- # only show events older than maxTime. This makes it possible to
- # visit a page that shows what it would be like to scroll off the
- # bottom of this one.
- if firstTimestamp is not None and firstTimestamp <= maxTime:
- eventGrid.append(spanEvents)
- timestamps.append(firstTimestamp)
-
- if lastTimestamp:
- spanStart = lastTimestamp - spanLength
- else:
- # no more events
- break
- if minTime is not None and lastTimestamp < minTime:
- break
-
- if len(timestamps) > maxPageLen:
- break
-
-
- # now loop
-
- # loop is finished. now we have eventGrid[] and timestamps[]
- if debugGather: log.msg("finished loop")
- assert(len(timestamps) == len(eventGrid))
- return (changeNames, builderNames, timestamps, eventGrid, sourceEvents)
-
- def phase2(self, request, sourceNames, timestamps, eventGrid,
- sourceEvents):
-
- if not timestamps:
- return dict(grid=[], gridlen=0)
-
- # first pass: figure out the height of the chunks, populate grid
- grid = []
- for i in range(1+len(sourceNames)):
- grid.append([])
- # grid is a list of columns, one for the timestamps, and one per
- # event source. Each column is exactly the same height. Each element
- # of the list is a single <td> box.
- lastDate = time.strftime("%d %b %Y",
- time.localtime(util.now()))
- for r in range(0, len(timestamps)):
- chunkstrip = eventGrid[r]
- # chunkstrip is a horizontal strip of event blocks. Each block
- # is a vertical list of events, all for the same source.
- assert(len(chunkstrip) == len(sourceNames))
- maxRows = reduce(lambda x,y: max(x,y),
- map(lambda x: len(x), chunkstrip))
- for i in range(maxRows):
- if i != maxRows-1:
- grid[0].append(None)
- else:
- # timestamp goes at the bottom of the chunk
- stuff = []
- # add the date at the beginning (if it is not the same as
- # today's date), and each time it changes
- todayday = time.strftime("%a",
- time.localtime(timestamps[r]))
- today = time.strftime("%d %b %Y",
- time.localtime(timestamps[r]))
- if today != lastDate:
- stuff.append(todayday)
- stuff.append(today)
- lastDate = today
- stuff.append(
- time.strftime("%H:%M:%S",
- time.localtime(timestamps[r])))
- grid[0].append(Box(text=stuff, class_="Time",
- valign="bottom", align="center"))
-
- # at this point the timestamp column has been populated with
- # maxRows boxes, most None but the last one has the time string
- for c in range(0, len(chunkstrip)):
- block = chunkstrip[c]
- assert(block != None) # should be [] instead
- for i in range(maxRows - len(block)):
- # fill top of chunk with blank space
- grid[c+1].append(None)
- for i in range(len(block)):
- # so the events are bottom-justified
- b = IBox(block[i]).getBox(request)
- b.parms['valign'] = "top"
- b.parms['align'] = "center"
- grid[c+1].append(b)
- # now all the other columns have maxRows new boxes too
- # populate the last row, if empty
- gridlen = len(grid[0])
- for i in range(len(grid)):
- strip = grid[i]
- assert(len(strip) == gridlen)
- if strip[-1] == None:
- if sourceEvents[i-1]:
- filler = IBox(sourceEvents[i-1]).getBox(request)
- else:
- # this can happen if you delete part of the build history
- filler = Box(text=["?"], align="center")
- strip[-1] = filler
- strip[-1].parms['rowspan'] = 1
- # second pass: bubble the events upwards to un-occupied locations
- # Every square of the grid that has a None in it needs to have
- # something else take its place.
- noBubble = request.args.get("nobubble",['0'])
- noBubble = int(noBubble[0])
- if not noBubble:
- for col in range(len(grid)):
- strip = grid[col]
- if col == 1: # changes are handled differently
- for i in range(2, len(strip)+1):
- # only merge empty boxes. Don't bubble commit boxes.
- if strip[-i] == None:
- next = strip[-i+1]
- assert(next)
- if next:
- #if not next.event:
- if next.spacer:
- # bubble the empty box up
- strip[-i] = next
- strip[-i].parms['rowspan'] += 1
- strip[-i+1] = None
- else:
- # we are above a commit box. Leave it
- # be, and turn the current box into an
- # empty one
- strip[-i] = Box([], rowspan=1,
- comment="commit bubble")
- strip[-i].spacer = True
- else:
- # we are above another empty box, which
- # somehow wasn't already converted.
- # Shouldn't happen
- pass
- else:
- for i in range(2, len(strip)+1):
- # strip[-i] will go from next-to-last back to first
- if strip[-i] == None:
- # bubble previous item up
- assert(strip[-i+1] != None)
- strip[-i] = strip[-i+1]
- strip[-i].parms['rowspan'] += 1
- strip[-i+1] = None
- else:
- strip[-i].parms['rowspan'] = 1
-
- # convert to dicts
- for i in range(gridlen):
- for strip in grid:
- if strip[i]:
- strip[i] = strip[i].td()
-
- return dict(grid=grid, gridlen=gridlen, no_bubble=noBubble, time=lastDate)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py
deleted file mode 100644
index 32565ac6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re, shlex, random
-from string import join, capitalize, lower
-
-from zope.interface import implements
-from twisted.internet import protocol, reactor
-from twisted.words.protocols import irc
-from twisted.python import usage, log
-from twisted.application import internet
-from twisted.internet import defer, task
-
-from buildbot import config, interfaces, util
-from buildbot import version
-from buildbot.interfaces import IStatusReceiver
-from buildbot.sourcestamp import SourceStamp
-from buildbot.status import base
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION, RETRY
-from buildbot.process.properties import Properties
-
-# twisted.internet.ssl requires PyOpenSSL, so be resilient if it's missing
-try:
- from twisted.internet import ssl
- have_ssl = True
-except ImportError:
- have_ssl = False
-
-def maybeColorize(text, color, useColors):
- irc_colors = [
- 'WHITE',
- 'BLACK',
- 'NAVY_BLUE',
- 'GREEN',
- 'RED',
- 'BROWN',
- 'PURPLE',
- 'OLIVE',
- 'YELLOW',
- 'LIME_GREEN',
- 'TEAL',
- 'AQUA_LIGHT',
- 'ROYAL_BLUE',
- 'HOT_PINK',
- 'DARK_GRAY',
- 'LIGHT_GRAY'
- ]
-
- if useColors:
- return "%c%d%s%c" % (3, irc_colors.index(color), text, 3)
- else:
- return text
-
-class UsageError(ValueError):
- def __init__(self, string = "Invalid usage", *more):
- ValueError.__init__(self, string, *more)
-
-class ForceOptions(usage.Options):
- optParameters = [
- ["builder", None, None, "which Builder to start"],
- ["branch", None, None, "which branch to build"],
- ["revision", None, None, "which revision to build"],
- ["reason", None, None, "the reason for starting the build"],
- ["props", None, None,
- "A set of properties made available in the build environment, "
- "format is --properties=prop1=value1,prop2=value2,.. "
- "option can be specified multiple times."],
- ]
-
- def parseArgs(self, *args):
- args = list(args)
- if len(args) > 0:
- if self['builder'] is not None:
- raise UsageError("--builder provided in two ways")
- self['builder'] = args.pop(0)
- if len(args) > 0:
- if self['reason'] is not None:
- raise UsageError("--reason provided in two ways")
- self['reason'] = " ".join(args)
-
-
-class IrcBuildRequest:
- hasStarted = False
- timer = None
-
- def __init__(self, parent, useRevisions=False, useColors=True):
- self.parent = parent
- self.useRevisions = useRevisions
- self.useColors = useColors
- self.timer = reactor.callLater(5, self.soon)
-
- def soon(self):
- del self.timer
- if not self.hasStarted:
- self.parent.send("The build has been queued, I'll give a shout"
- " when it starts")
-
- def started(self, s):
- self.hasStarted = True
- if self.timer:
- self.timer.cancel()
- del self.timer
- eta = s.getETA()
- if self.useRevisions:
- response = "build containing revision(s) [%s] forced" % s.getRevisions()
- else:
- response = "build #%d forced" % s.getNumber()
- if eta is not None:
- response = "build forced [ETA %s]" % self.parent.convertTime(eta)
- self.parent.send(response)
- self.parent.send("I'll give a shout when the build finishes")
- d = s.waitUntilFinished()
- d.addCallback(self.parent.watchedBuildFinished)
-
-class IRCContact(base.StatusReceiver):
- implements(IStatusReceiver)
- """I hold the state for a single user's interaction with the buildbot.
-
- There will be one instance of me for each user who interacts personally
- with the buildbot. There will be an additional instance for each
- 'broadcast contact' (chat rooms, IRC channels as a whole).
- """
-
- def __init__(self, bot, dest):
- self.bot = bot
- self.master = bot.master
- self.notify_events = {}
- self.subscribed = 0
- self.muted = False
- self.useRevisions = bot.useRevisions
- self.useColors = bot.useColors
- self.reported_builds = [] # tuples (when, buildername, buildnum)
- self.add_notification_events(bot.notify_events)
-
- # when people send us public messages ("buildbot: command"),
- # self.dest is the name of the channel ("#twisted"). When they send
- # us private messages (/msg buildbot command), self.dest is their
- # username.
- self.dest = dest
-
- # silliness
-
- silly = {
- "What happen ?": [ "Somebody set up us the bomb." ],
- "It's You !!": ["How are you gentlemen !!",
- "All your base are belong to us.",
- "You are on the way to destruction."],
- "What you say !!": ["You have no chance to survive make your time.",
- "HA HA HA HA ...."],
- }
-
- def doSilly(self, message):
- response = self.silly[message]
- when = 0.5
- for r in response:
- reactor.callLater(when, self.send, r)
- when += 2.5
-
- def getBuilder(self, which):
- try:
- b = self.bot.status.getBuilder(which)
- except KeyError:
- raise UsageError, "no such builder '%s'" % which
- return b
-
- def getControl(self, which):
- if not self.bot.control:
- raise UsageError("builder control is not enabled")
- try:
- bc = self.bot.control.getBuilder(which)
- except KeyError:
- raise UsageError("no such builder '%s'" % which)
- return bc
-
- def getAllBuilders(self):
- """
- @rtype: list of L{buildbot.process.builder.Builder}
- """
- names = self.bot.status.getBuilderNames(categories=self.bot.categories)
- names.sort()
- builders = [self.bot.status.getBuilder(n) for n in names]
- return builders
-
- def convertTime(self, seconds):
- if seconds < 60:
- return "%d seconds" % seconds
- minutes = int(seconds / 60)
- seconds = seconds - 60*minutes
- if minutes < 60:
- return "%dm%02ds" % (minutes, seconds)
- hours = int(minutes / 60)
- minutes = minutes - 60*hours
- return "%dh%02dm%02ds" % (hours, minutes, seconds)
-
- def reportBuild(self, builder, buildnum):
- """Returns True if this build should be reported for this contact
- (eliminating duplicates), and also records the report for later"""
- for w, b, n in self.reported_builds:
- if b == builder and n == buildnum:
- return False
- self.reported_builds.append([util.now(), builder, buildnum])
-
- # clean the reported builds
- horizon = util.now() - 60
- while self.reported_builds and self.reported_builds[0][0] < horizon:
- self.reported_builds.pop(0)
-
- # and return True, since this is a new one
- return True
-
- def splitArgs(self, args):
- """Returns list of arguments parsed by shlex.split() or
- raise UsageError if failed"""
- try:
- return shlex.split(args)
- except ValueError, e:
- raise UsageError(e)
-
- def command_HELLO(self, args, who):
- self.send("yes?")
-
- def command_VERSION(self, args, who):
- self.send("buildbot-%s at your service" % version)
-
- def command_LIST(self, args, who):
- args = self.splitArgs(args)
- if len(args) == 0:
- raise UsageError, "try 'list builders'"
- if args[0] == 'builders':
- builders = self.getAllBuilders()
- str = "Configured builders: "
- for b in builders:
- str += b.name
- state = b.getState()[0]
- if state == 'offline':
- str += "[offline]"
- str += " "
- str.rstrip()
- self.send(str)
- return
- command_LIST.usage = "list builders - List configured builders"
-
- def command_STATUS(self, args, who):
- args = self.splitArgs(args)
- if len(args) == 0:
- which = "all"
- elif len(args) == 1:
- which = args[0]
- else:
- raise UsageError, "try 'status <builder>'"
- if which == "all":
- builders = self.getAllBuilders()
- for b in builders:
- self.emit_status(b.name)
- return
- self.emit_status(which)
- command_STATUS.usage = "status [<which>] - List status of a builder (or all builders)"
-
- def validate_notification_event(self, event):
- if not re.compile("^(started|finished|success|failure|exception|warnings|(success|warnings|exception|failure)To(Failure|Success|Warnings|Exception))$").match(event):
- raise UsageError("try 'notify on|off <EVENT>'")
-
- def list_notified_events(self):
- self.send( "The following events are being notified: %r" % self.notify_events.keys() )
-
- def notify_for(self, *events):
- for event in events:
- if self.notify_events.has_key(event):
- return 1
- return 0
-
- def subscribe_to_build_events(self):
- self.bot.status.subscribe(self)
- self.subscribed = 1
-
- def unsubscribe_from_build_events(self):
- self.bot.status.unsubscribe(self)
- self.subscribed = 0
-
- def add_notification_events(self, events):
- for event in events:
- self.validate_notification_event(event)
- self.notify_events[event] = 1
-
- if not self.subscribed:
- self.subscribe_to_build_events()
-
- def remove_notification_events(self, events):
- for event in events:
- self.validate_notification_event(event)
- del self.notify_events[event]
-
- if len(self.notify_events) == 0 and self.subscribed:
- self.unsubscribe_from_build_events()
-
- def remove_all_notification_events(self):
- self.notify_events = {}
-
- if self.subscribed:
- self.unsubscribe_from_build_events()
-
- def command_NOTIFY(self, args, who):
- args = self.splitArgs(args)
-
- if not args:
- raise UsageError("try 'notify on|off|list <EVENT>'")
- action = args.pop(0)
- events = args
-
- if action == "on":
- if not events: events = ('started','finished')
- self.add_notification_events(events)
-
- self.list_notified_events()
-
- elif action == "off":
- if events:
- self.remove_notification_events(events)
- else:
- self.remove_all_notification_events()
-
- self.list_notified_events()
-
- elif action == "list":
- self.list_notified_events()
- return
-
- else:
- raise UsageError("try 'notify on|off <EVENT>'")
-
- command_NOTIFY.usage = "notify on|off|list [<EVENT>] ... - Notify me about build events. event should be one or more of: 'started', 'finished', 'failure', 'success', 'exception' or 'xToY' (where x and Y are one of success, warnings, failure, exception, but Y is capitalized)"
-
- def command_WATCH(self, args, who):
- args = self.splitArgs(args)
- if len(args) != 1:
- raise UsageError("try 'watch <builder>'")
- which = args[0]
- b = self.getBuilder(which)
- builds = b.getCurrentBuilds()
- if not builds:
- self.send("there are no builds currently running")
- return
- for build in builds:
- assert not build.isFinished()
- d = build.waitUntilFinished()
- d.addCallback(self.watchedBuildFinished)
- if self.useRevisions:
- r = "watching build %s containing revision(s) [%s] until it finishes" \
- % (which, build.getRevisions())
- else:
- r = "watching build %s #%d until it finishes" \
- % (which, build.getNumber())
- eta = build.getETA()
- if eta is not None:
- r += " [%s]" % self.convertTime(eta)
- r += ".."
- self.send(r)
- command_WATCH.usage = "watch <which> - announce the completion of an active build"
-
- def builderAdded(self, builderName, builder):
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- return
-
- log.msg('[Contact] Builder %s added' % (builder))
- builder.subscribe(self)
-
- def builderRemoved(self, builderName):
- log.msg('[Contact] Builder %s removed' % (builderName))
-
- def buildStarted(self, builderName, build):
- builder = build.getBuilder()
- log.msg('[Contact] Builder %r in category %s started' % (builder, builder.category))
-
- # only notify about builders we are interested in
-
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- log.msg('Not notifying for a build in the wrong category')
- return
-
- if not self.notify_for('started'):
- return
-
- if self.useRevisions:
- r = "build containing revision(s) [%s] on %s started" % \
- (build.getRevisions(), builder.getName())
- else:
- r = "build #%d of %s started, including [%s]" % \
- (build.getNumber(),
- builder.getName(),
- ", ".join([str(c.revision) for c in build.getChanges()])
- )
-
- self.send(r)
-
- results_descriptions = {
- SUCCESS: ("Success", 'GREEN'),
- WARNINGS: ("Warnings", 'YELLOW'),
- FAILURE: ("Failure", 'RED'),
- EXCEPTION: ("Exception", 'PURPLE'),
- RETRY: ("Retry", 'AQUA_LIGHT'),
- }
-
- def getResultsDescriptionAndColor(self, results):
- return self.results_descriptions.get(results, ("??",'RED'))
-
- def buildFinished(self, builderName, build, results):
- builder = build.getBuilder()
-
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- return
-
- if not self.notify_for_finished(build):
- return
-
- builder_name = builder.getName()
- buildnum = build.getNumber()
- buildrevs = build.getRevisions()
-
- results = self.getResultsDescriptionAndColor(build.getResults())
- if self.reportBuild(builder_name, buildnum):
- if self.useRevisions:
- r = "build containing revision(s) [%s] on %s is complete: %s" % \
- (buildrevs, builder_name, results[0])
- else:
- r = "build #%d of %s is complete: %s" % \
- (buildnum, builder_name, results[0])
-
- r += ' [%s]' % maybeColorize(" ".join(build.getText()), results[1], self.useColors)
- buildurl = self.bot.status.getURLForThing(build)
- if buildurl:
- r += " Build details are at %s" % buildurl
-
- if self.bot.showBlameList and build.getResults() != SUCCESS and len(build.changes) != 0:
- r += ' blamelist: ' + ', '.join(list(set([c.who for c in build.changes])))
-
- self.send(r)
-
- def notify_for_finished(self, build):
- results = build.getResults()
-
- if self.notify_for('finished'):
- return True
-
- if self.notify_for(lower(self.results_descriptions.get(results)[0])):
- return True
-
- prevBuild = build.getPreviousBuild()
- if prevBuild:
- prevResult = prevBuild.getResults()
-
- required_notification_control_string = join((lower(self.results_descriptions.get(prevResult)[0]), \
- 'To', \
- capitalize(self.results_descriptions.get(results)[0])), \
- '')
-
- if (self.notify_for(required_notification_control_string)):
- return True
-
- return False
-
- def watchedBuildFinished(self, b):
-
- # only notify about builders we are interested in
- builder = b.getBuilder()
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- return
-
- builder_name = builder.getName()
- buildnum = b.getNumber()
- buildrevs = b.getRevisions()
-
- results = self.getResultsDescriptionAndColor(b.getResults())
- if self.reportBuild(builder_name, buildnum):
- if self.useRevisions:
- r = "Hey! build %s containing revision(s) [%s] is complete: %s" % \
- (builder_name, buildrevs, results[0])
- else:
- r = "Hey! build %s #%d is complete: %s" % \
- (builder_name, buildnum, results[0])
-
- r += ' [%s]' % maybeColorize(" ".join(b.getText()), results[1], self.useColors)
- self.send(r)
- buildurl = self.bot.status.getURLForThing(b)
- if buildurl:
- self.send("Build details are at %s" % buildurl)
-
- def command_FORCE(self, args, who):
- errReply = "try 'force build [--branch=BRANCH] [--revision=REVISION] [--props=PROP1=VAL1,PROP2=VAL2...] <WHICH> <REASON>'"
- args = self.splitArgs(args)
- if not args:
- raise UsageError(errReply)
- what = args.pop(0)
- if what != "build":
- raise UsageError(errReply)
- opts = ForceOptions()
- opts.parseOptions(args)
-
- which = opts['builder']
- branch = opts['branch']
- revision = opts['revision']
- reason = opts['reason']
- props = opts['props']
-
- if which is None:
- raise UsageError("you must provide a Builder, " + errReply)
-
- # keep weird stuff out of the branch, revision, and properties args.
- branch_validate = self.master.config.validation['branch']
- revision_validate = self.master.config.validation['revision']
- pname_validate = self.master.config.validation['property_name']
- pval_validate = self.master.config.validation['property_value']
- if branch and not branch_validate.match(branch):
- log.msg("bad branch '%s'" % branch)
- self.send("sorry, bad branch '%s'" % branch)
- return
- if revision and not revision_validate.match(revision):
- log.msg("bad revision '%s'" % revision)
- self.send("sorry, bad revision '%s'" % revision)
- return
-
- properties = Properties()
- if props:
- # split props into name:value dict
- pdict = {}
- propertylist = props.split(",")
- for i in range(0,len(propertylist)):
- splitproperty = propertylist[i].split("=", 1)
- pdict[splitproperty[0]] = splitproperty[1]
-
- # set properties
- for prop in pdict:
- pname = prop
- pvalue = pdict[prop]
- if not pname_validate.match(pname) \
- or not pval_validate.match(pvalue):
- log.msg("bad property name='%s', value='%s'" % (pname, pvalue))
- self.send("sorry, bad property name='%s', value='%s'" %
- (pname, pvalue))
- return
- properties.setProperty(pname, pvalue, "Force Build IRC")
-
- bc = self.getControl(which)
-
- reason = "forced: by %s: %s" % (self.describeUser(who), reason)
- ss = SourceStamp(branch=branch, revision=revision)
- d = bc.submitBuildRequest(ss, reason, props=properties.asDict())
- def subscribe(buildreq):
- ireq = IrcBuildRequest(self, self.useRevisions)
- buildreq.subscribe(ireq.started)
- d.addCallback(subscribe)
- d.addErrback(log.err, "while forcing a build")
-
-
- command_FORCE.usage = "force build [--branch=branch] [--revision=revision] [--props=prop1=val1,prop2=val2...] <which> <reason> - Force a build"
-
- def command_STOP(self, args, who):
- args = self.splitArgs(args)
- if len(args) < 3 or args[0] != 'build':
- raise UsageError, "try 'stop build WHICH <REASON>'"
- which = args[1]
- reason = args[2]
-
- buildercontrol = self.getControl(which)
-
- r = "stopped: by %s: %s" % (self.describeUser(who), reason)
-
- # find an in-progress build
- builderstatus = self.getBuilder(which)
- builds = builderstatus.getCurrentBuilds()
- if not builds:
- self.send("sorry, no build is currently running")
- return
- for build in builds:
- num = build.getNumber()
- revs = build.getRevisions()
-
- # obtain the BuildControl object
- buildcontrol = buildercontrol.getBuild(num)
-
- # make it stop
- buildcontrol.stopBuild(r)
-
- if self.useRevisions:
- response = "build containing revision(s) [%s] interrupted" % revs
- else:
- response = "build %d interrupted" % num
- self.send(response)
-
- command_STOP.usage = "stop build <which> <reason> - Stop a running build"
-
- def emit_status(self, which):
- b = self.getBuilder(which)
- str = "%s: " % which
- state, builds = b.getState()
- str += state
- if state == "idle":
- last = b.getLastFinishedBuild()
- if last:
- start,finished = last.getTimes()
- str += ", last build %s ago: %s" % \
- (self.convertTime(int(util.now() - finished)), " ".join(last.getText()))
- if state == "building":
- t = []
- for build in builds:
- step = build.getCurrentStep()
- if step:
- s = "(%s)" % " ".join(step.getText())
- else:
- s = "(no current step)"
- ETA = build.getETA()
- if ETA is not None:
- s += " [ETA %s]" % self.convertTime(ETA)
- t.append(s)
- str += ", ".join(t)
- self.send(str)
-
- def command_LAST(self, args, who):
- args = self.splitArgs(args)
-
- if len(args) == 0:
- which = "all"
- elif len(args) == 1:
- which = args[0]
- else:
- raise UsageError, "try 'last <builder>'"
-
- def emit_last(which):
- last = self.getBuilder(which).getLastFinishedBuild()
- if not last:
- str = "(no builds run since last restart)"
- else:
- start,finish = last.getTimes()
- str = "%s ago: " % (self.convertTime(int(util.now() - finish)))
- str += " ".join(last.getText())
- self.send("last build [%s]: %s" % (which, str))
-
- if which == "all":
- builders = self.getAllBuilders()
- for b in builders:
- emit_last(b.name)
- return
- emit_last(which)
- command_LAST.usage = "last <which> - list last build status for builder <which>"
-
- def build_commands(self):
- commands = []
- for k in dir(self):
- if k.startswith('command_'):
- commands.append(k[8:].lower())
- commands.sort()
- return commands
-
- def describeUser(self, user):
- if self.dest[0] == '#':
- return "IRC user <%s> on channel %s" % (user, self.dest)
- return "IRC user <%s> (privmsg)" % user
-
- # commands
-
- def command_MUTE(self, args, who):
- # The order of these is important! ;)
- self.send("Shutting up for now.")
- self.muted = True
- command_MUTE.usage = "mute - suppress all messages until a corresponding 'unmute' is issued"
-
- def command_UNMUTE(self, args, who):
- if self.muted:
- # The order of these is important! ;)
- self.muted = False
- self.send("I'm baaaaaaaaaaack!")
- else:
- self.send("You hadn't told me to be quiet, but it's the thought that counts, right?")
- command_UNMUTE.usage = "unmute - disable a previous 'mute'"
-
- def command_HELP(self, args, who):
- args = self.splitArgs(args)
- if len(args) == 0:
- self.send("Get help on what? (try 'help <foo>', 'help <foo> <bar>, "
- "or 'commands' for a command list)")
- return
- command = args[0]
- meth = self.getCommandMethod(command)
- if not meth:
- raise UsageError, "no such command '%s'" % command
- usage = getattr(meth, 'usage', None)
- if isinstance(usage, dict):
- if len(args) == 1:
- k = None # command
- elif len(args) == 2:
- k = args[1] # command arg
- else:
- k = tuple(args[1:]) # command arg subarg ...
- usage = usage.get(k, None)
- if usage:
- self.send("Usage: %s" % usage)
- else:
- self.send("No usage info for " + ' '.join(["'%s'" % arg for arg in args]))
- command_HELP.usage = "help <command> [<arg> [<subarg> ...]] - Give help for <command> or one of it's arguments"
-
- def command_SOURCE(self, args, who):
- self.send("My source can be found at "
- "https://github.com/buildbot/buildbot")
- command_SOURCE.usage = "source - the source code for Buildbot"
-
- def command_COMMANDS(self, args, who):
- commands = self.build_commands()
- str = "buildbot commands: " + ", ".join(commands)
- self.send(str)
- command_COMMANDS.usage = "commands - List available commands"
-
- def command_DESTROY(self, args, who):
- if self.bot.nickname not in args:
- self.act("readies phasers")
-
- def command_DANCE(self, args, who):
- reactor.callLater(1.0, self.send, "<(^.^<)")
- reactor.callLater(2.0, self.send, "<(^.^)>")
- reactor.callLater(3.0, self.send, "(>^.^)>")
- reactor.callLater(3.5, self.send, "(7^.^)7")
- reactor.callLater(5.0, self.send, "(>^.^<)")
-
- def command_SHUTDOWN(self, args, who):
- if args not in ('check','start','stop','now'):
- raise UsageError("try 'shutdown check|start|stop|now'")
-
- if not self.bot.factory.allowShutdown:
- raise UsageError("shutdown control is not enabled")
-
- botmaster = self.master.botmaster
- shuttingDown = botmaster.shuttingDown
-
- if args == 'check':
- if shuttingDown:
- self.send("Status: buildbot is shutting down")
- else:
- self.send("Status: buildbot is running")
- elif args == 'start':
- if shuttingDown:
- self.send("Already started")
- else:
- self.send("Starting clean shutdown")
- botmaster.cleanShutdown()
- elif args == 'stop':
- if not shuttingDown:
- self.send("Nothing to stop")
- else:
- self.send("Stopping clean shutdown")
- botmaster.cancelCleanShutdown()
- elif args == 'now':
- self.send("Stopping buildbot")
- reactor.stop()
- command_SHUTDOWN.usage = {
- None: "shutdown check|start|stop|now - shutdown the buildbot master",
- "check": "shutdown check - check if the buildbot master is running or shutting down",
- "start": "shutdown start - start a clean shutdown",
- "stop": "shutdown cancel - stop the clean shutdown",
- "now": "shutdown now - shutdown immediately without waiting for the builders to finish"}
-
- # communication with the user
-
- def send(self, message):
- if not self.muted:
- self.bot.msgOrNotice(self.dest, message.encode("ascii", "replace"))
-
- def act(self, action):
- if not self.muted:
- self.bot.describe(self.dest, action.encode("ascii", "replace"))
-
- # main dispatchers for incoming messages
-
- def getCommandMethod(self, command):
- return getattr(self, 'command_' + command.upper(), None)
-
- def handleMessage(self, message, who):
- # a message has arrived from 'who'. For broadcast contacts (i.e. when
- # people do an irc 'buildbot: command'), this will be a string
- # describing the sender of the message in some useful-to-log way, and
- # a single Contact may see messages from a variety of users. For
- # unicast contacts (i.e. when people do an irc '/msg buildbot
- # command'), a single Contact will only ever see messages from a
- # single user.
- message = message.lstrip()
- if self.silly.has_key(message):
- self.doSilly(message)
- return defer.succeed(None)
-
- parts = message.split(' ', 1)
- if len(parts) == 1:
- parts = parts + ['']
- cmd, args = parts
- log.msg("irc command", cmd)
-
- meth = self.getCommandMethod(cmd)
- if not meth and message[-1] == '!':
- self.send("What you say!")
- return defer.succeed(None)
-
- if meth:
- d = defer.maybeDeferred(meth, args.strip(), who)
- @d.addErrback
- def usageError(f):
- f.trap(UsageError)
- self.send(str(f.value))
- @d.addErrback
- def logErr(f):
- log.err(f)
- self.send("Something bad happened (see logs)")
- d.addErrback(log.err)
- return d
- return defer.succeed(None)
-
- def handleAction(self, data, user):
- # this is sent when somebody performs an action that mentions the
- # buildbot (like '/me kicks buildbot'). 'user' is the name/nick/id of
- # the person who performed the action, so if their action provokes a
- # response, they can be named. This is 100% silly.
- if not data.endswith("s "+ self.bot.nickname):
- return
- words = data.split()
- verb = words[-2]
- if verb == "kicks":
- response = "%s back" % verb
- else:
- response = "%s %s too" % (verb, user)
- self.act(response)
-
-
-class IrcStatusBot(irc.IRCClient):
- """I represent the buildbot to an IRC server.
- """
- contactClass = IRCContact
-
- def __init__(self, nickname, password, channels, pm_to_nicks, status,
- categories, notify_events, noticeOnChannel=False,
- useRevisions=False, showBlameList=False, useColors=True):
- self.nickname = nickname
- self.channels = channels
- self.pm_to_nicks = pm_to_nicks
- self.password = password
- self.status = status
- self.master = status.master
- self.categories = categories
- self.notify_events = notify_events
- self.hasQuit = 0
- self.contacts = {}
- self.noticeOnChannel = noticeOnChannel
- self.useColors = useColors
- self.useRevisions = useRevisions
- self.showBlameList = showBlameList
- self._keepAliveCall = task.LoopingCall(lambda: self.ping(self.nickname))
-
- def connectionMade(self):
- irc.IRCClient.connectionMade(self)
- self._keepAliveCall.start(60)
-
- def connectionLost(self, reason):
- if self._keepAliveCall.running:
- self._keepAliveCall.stop()
- irc.IRCClient.connectionLost(self, reason)
-
- def msgOrNotice(self, dest, message):
- if self.noticeOnChannel and dest[0] == '#':
- self.notice(dest, message)
- else:
- self.msg(dest, message)
-
- def getContact(self, name):
- name = name.lower() # nicknames and channel names are case insensitive
- if name in self.contacts:
- return self.contacts[name]
- new_contact = self.contactClass(self, name)
- self.contacts[name] = new_contact
- return new_contact
-
- def log(self, msg):
- log.msg("%s: %s" % (self, msg))
-
-
- # the following irc.IRCClient methods are called when we have input
-
- def privmsg(self, user, channel, message):
- user = user.split('!', 1)[0] # rest is ~user@hostname
- # channel is '#twisted' or 'buildbot' (for private messages)
- if channel == self.nickname:
- # private message
- contact = self.getContact(user)
- contact.handleMessage(message, user)
- return
- # else it's a broadcast message, maybe for us, maybe not. 'channel'
- # is '#twisted' or the like.
- contact = self.getContact(channel)
- if message.startswith("%s:" % self.nickname) or message.startswith("%s," % self.nickname):
- message = message[len("%s:" % self.nickname):]
- contact.handleMessage(message, user)
-
- def action(self, user, channel, data):
- user = user.split('!', 1)[0] # rest is ~user@hostname
- # somebody did an action (/me actions) in the broadcast channel
- contact = self.getContact(channel)
- if self.nickname in data:
- contact.handleAction(data, user)
-
- def signedOn(self):
- if self.password:
- self.msg("Nickserv", "IDENTIFY " + self.password)
- for c in self.channels:
- if isinstance(c, dict):
- channel = c.get('channel', None)
- password = c.get('password', None)
- else:
- channel = c
- password = None
- self.join(channel=channel, key=password)
- for c in self.pm_to_nicks:
- self.getContact(c)
-
- def joined(self, channel):
- self.log("I have joined %s" % (channel,))
- # trigger contact contructor, which in turn subscribes to notify events
- self.getContact(channel)
-
- def left(self, channel):
- self.log("I have left %s" % (channel,))
-
- def kickedFrom(self, channel, kicker, message):
- self.log("I have been kicked from %s by %s: %s" % (channel,
- kicker,
- message))
-
-
-class ThrottledClientFactory(protocol.ClientFactory):
- lostDelay = random.randint(1, 5)
- failedDelay = random.randint(45, 60)
-
- def __init__(self, lostDelay=None, failedDelay=None):
- if lostDelay is not None:
- self.lostDelay = lostDelay
- if failedDelay is not None:
- self.failedDelay = failedDelay
-
- def clientConnectionLost(self, connector, reason):
- reactor.callLater(self.lostDelay, connector.connect)
-
- def clientConnectionFailed(self, connector, reason):
- reactor.callLater(self.failedDelay, connector.connect)
-
-
-class IrcStatusFactory(ThrottledClientFactory):
- protocol = IrcStatusBot
-
- status = None
- control = None
- shuttingDown = False
- p = None
-
- def __init__(self, nickname, password, channels, pm_to_nicks, categories, notify_events,
- noticeOnChannel=False, useRevisions=False, showBlameList=False,
- lostDelay=None, failedDelay=None, useColors=True, allowShutdown=False):
- ThrottledClientFactory.__init__(self, lostDelay=lostDelay,
- failedDelay=failedDelay)
- self.status = None
- self.nickname = nickname
- self.password = password
- self.channels = channels
- self.pm_to_nicks = pm_to_nicks
- self.categories = categories
- self.notify_events = notify_events
- self.noticeOnChannel = noticeOnChannel
- self.useRevisions = useRevisions
- self.showBlameList = showBlameList
- self.useColors = useColors
- self.allowShutdown = allowShutdown
-
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['p']
- return d
-
- def shutdown(self):
- self.shuttingDown = True
- if self.p:
- self.p.quit("buildmaster reconfigured: bot disconnecting")
-
- def buildProtocol(self, address):
- p = self.protocol(self.nickname, self.password,
- self.channels, self.pm_to_nicks, self.status,
- self.categories, self.notify_events,
- noticeOnChannel = self.noticeOnChannel,
- useColors = self.useColors,
- useRevisions = self.useRevisions,
- showBlameList = self.showBlameList)
- p.factory = self
- p.status = self.status
- p.control = self.control
- self.p = p
- return p
-
- # TODO: I think a shutdown that occurs while the connection is being
- # established will make this explode
-
- def clientConnectionLost(self, connector, reason):
- if self.shuttingDown:
- log.msg("not scheduling reconnection attempt")
- return
- ThrottledClientFactory.clientConnectionLost(self, connector, reason)
-
- def clientConnectionFailed(self, connector, reason):
- if self.shuttingDown:
- log.msg("not scheduling reconnection attempt")
- return
- ThrottledClientFactory.clientConnectionFailed(self, connector, reason)
-
-
-class IRC(base.StatusReceiverMultiService):
- implements(IStatusReceiver)
-
- in_test_harness = False
-
- compare_attrs = ["host", "port", "nick", "password",
- "channels", "pm_to_nicks", "allowForce", "useSSL",
- "useRevisions", "categories", "useColors",
- "lostDelay", "failedDelay", "allowShutdown"]
-
- def __init__(self, host, nick, channels, pm_to_nicks=[], port=6667,
- allowForce=False, categories=None, password=None, notify_events={},
- noticeOnChannel = False, showBlameList = True, useRevisions=False,
- useSSL=False, lostDelay=None, failedDelay=None, useColors=True,
- allowShutdown=False):
- base.StatusReceiverMultiService.__init__(self)
-
- if allowForce not in (True, False):
- config.error("allowForce must be boolean, not %r" % (allowForce,))
- if allowShutdown not in (True, False):
- config.error("allowShutdown must be boolean, not %r" % (allowShutdown,))
-
- # need to stash these so we can detect changes later
- self.host = host
- self.port = port
- self.nick = nick
- self.channels = channels
- self.pm_to_nicks = pm_to_nicks
- self.password = password
- self.allowForce = allowForce
- self.useRevisions = useRevisions
- self.categories = categories
- self.notify_events = notify_events
- self.allowShutdown = allowShutdown
-
- self.f = IrcStatusFactory(self.nick, self.password,
- self.channels, self.pm_to_nicks,
- self.categories, self.notify_events,
- noticeOnChannel = noticeOnChannel,
- useRevisions = useRevisions,
- showBlameList = showBlameList,
- lostDelay = lostDelay,
- failedDelay = failedDelay,
- useColors = useColors,
- allowShutdown = allowShutdown)
-
- if useSSL:
- # SSL client needs a ClientContextFactory for some SSL mumbo-jumbo
- if not have_ssl:
- raise RuntimeError("useSSL requires PyOpenSSL")
- cf = ssl.ClientContextFactory()
- c = internet.SSLClient(self.host, self.port, self.f, cf)
- else:
- c = internet.TCPClient(self.host, self.port, self.f)
-
- c.setServiceParent(self)
-
- def setServiceParent(self, parent):
- base.StatusReceiverMultiService.setServiceParent(self, parent)
- self.f.status = parent
- if self.allowForce:
- self.f.control = interfaces.IControl(self.master)
-
- def stopService(self):
- # make sure the factory will stop reconnecting
- self.f.shutdown()
- return base.StatusReceiverMultiService.stopService(self)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py
deleted file mode 100644
index 52e75de3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os, types, re
-from twisted.python import runtime
-from twisted.internet import reactor
-from buildbot.process.buildstep import BuildStep
-from buildbot.process.buildstep import SUCCESS, FAILURE
-from twisted.internet import error
-from twisted.internet.protocol import ProcessProtocol
-import pprint
-
-class MasterShellCommand(BuildStep):
- """
- Run a shell command locally - on the buildmaster. The shell command
- COMMAND is specified just as for a RemoteShellCommand. Note that extra
- logfiles are not supported.
- """
- name='MasterShellCommand'
- description='Running'
- descriptionDone='Ran'
- descriptionSuffix = None
- renderables = [ 'command', 'env', 'description', 'descriptionDone', 'descriptionSuffix' ]
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, command,
- description=None, descriptionDone=None, descriptionSuffix=None,
- env=None, path=None, usePTY=0, interruptSignal="KILL",
- **kwargs):
- BuildStep.__init__(self, **kwargs)
-
- self.command=command
- if description:
- self.description = description
- if isinstance(self.description, str):
- self.description = [self.description]
- if descriptionDone:
- self.descriptionDone = descriptionDone
- if isinstance(self.descriptionDone, str):
- self.descriptionDone = [self.descriptionDone]
- if descriptionSuffix:
- self.descriptionSuffix = descriptionSuffix
- if isinstance(self.descriptionSuffix, str):
- self.descriptionSuffix = [self.descriptionSuffix]
- self.env=env
- self.path=path
- self.usePTY=usePTY
- self.interruptSignal = interruptSignal
-
- class LocalPP(ProcessProtocol):
- def __init__(self, step):
- self.step = step
-
- def outReceived(self, data):
- self.step.stdio_log.addStdout(data)
-
- def errReceived(self, data):
- self.step.stdio_log.addStderr(data)
-
- def processEnded(self, status_object):
- if status_object.value.exitCode is not None:
- self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
- if status_object.value.signal is not None:
- self.step.stdio_log.addHeader("signal %s\n" % status_object.value.signal)
- self.step.processEnded(status_object)
-
- def start(self):
- # render properties
- command = self.command
- # set up argv
- if type(command) in types.StringTypes:
- if runtime.platformType == 'win32':
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += [command]
- else:
- # for posix, use /bin/sh. for other non-posix, well, doesn't
- # hurt to try
- argv = ['/bin/sh', '-c', command]
- else:
- if runtime.platformType == 'win32':
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += list(command)
- else:
- argv = command
-
- self.stdio_log = stdio_log = self.addLog("stdio")
-
- if type(command) in types.StringTypes:
- stdio_log.addHeader(command.strip() + "\n\n")
- else:
- stdio_log.addHeader(" ".join(command) + "\n\n")
- stdio_log.addHeader("** RUNNING ON BUILDMASTER **\n")
- stdio_log.addHeader(" in dir %s\n" % os.getcwd())
- stdio_log.addHeader(" argv: %s\n" % (argv,))
- self.step_status.setText(self.describe())
-
- if self.env is None:
- env = os.environ
- else:
- assert isinstance(self.env, dict)
- env = self.env
- for key, v in self.env.iteritems():
- if isinstance(v, list):
- # Need to do os.pathsep translation. We could either do that
- # by replacing all incoming ':'s with os.pathsep, or by
- # accepting lists. I like lists better.
- # If it's not a string, treat it as a sequence to be
- # turned in to a string.
- self.env[key] = os.pathsep.join(self.env[key])
-
- # do substitution on variable values matching pattern: ${name}
- p = re.compile('\${([0-9a-zA-Z_]*)}')
- def subst(match):
- return os.environ.get(match.group(1), "")
- newenv = {}
- for key, v in env.iteritems():
- if v is not None:
- if not isinstance(v, basestring):
- raise RuntimeError("'env' values must be strings or "
- "lists; key '%s' is incorrect" % (key,))
- newenv[key] = p.sub(subst, env[key])
- env = newenv
- stdio_log.addHeader(" env: %r\n" % (env,))
-
- # TODO add a timeout?
- self.process = reactor.spawnProcess(self.LocalPP(self), argv[0], argv,
- path=self.path, usePTY=self.usePTY, env=env )
- # (the LocalPP object will call processEnded for us)
-
- def processEnded(self, status_object):
- if status_object.value.signal is not None:
- self.descriptionDone = ["killed (%s)" % status_object.value.signal]
- self.step_status.setText(self.describe(done=True))
- self.finished(FAILURE)
- elif status_object.value.exitCode != 0:
- self.descriptionDone = ["failed (%d)" % status_object.value.exitCode]
- self.step_status.setText(self.describe(done=True))
- self.finished(FAILURE)
- else:
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
- def describe(self, done=False):
- desc = self.descriptionDone if done else self.description
- if self.descriptionSuffix:
- desc = desc[:]
- desc.extend(self.descriptionSuffix)
- return desc
-
- def interrupt(self, reason):
- try:
- self.process.signalProcess(self.interruptSignal)
- except KeyError: # Process not started yet
- pass
- except error.ProcessExitedAlready:
- pass
- BuildStep.interrupt(self, reason)
-
-
-class SetProperty(BuildStep):
- name='SetProperty'
- description=['Setting']
- descriptionDone=['Set']
- renderables = [ 'value' ]
-
- def __init__(self, property, value, **kwargs):
- BuildStep.__init__(self, **kwargs)
- self.property = property
- self.value = value
-
- def start(self):
- properties = self.build.getProperties()
- properties.setProperty(self.property, self.value, self.name, runtime=True)
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-
-class LogRenderable(BuildStep):
- name='LogRenderable'
- description=['Logging']
- descriptionDone=['Logged']
- renderables = ['content']
-
- def __init__(self, content, **kwargs):
- BuildStep.__init__(self, **kwargs)
- self.content = content
-
- def start(self):
- content = pprint.pformat(self.content)
- self.addCompleteLog(name='Output', text=content)
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py
deleted file mode 100644
index bb40677a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot import config
-
-class MaxQ(ShellCommand):
- flunkOnFailure = True
- name = "maxq"
-
- def __init__(self, testdir=None, **kwargs):
- if not testdir:
- config.error("please pass testdir")
- kwargs['command'] = 'run_maxq.py %s' % (testdir,)
- ShellCommand.__init__(self, **kwargs)
-
- def commandComplete(self, cmd):
- output = cmd.logs['stdio'].getText()
- self.failures = output.count('\nTEST FAILURE:')
-
- def evaluateCommand(self, cmd):
- # treat a nonzero exit status as a failure, if no other failures are
- # detected
- if not self.failures and cmd.didFail():
- self.failures = 1
- if self.failures:
- return FAILURE
- return SUCCESS
-
- def getText(self, cmd, results):
- if self.failures:
- return [ str(self.failures), 'maxq', 'failures' ]
- return ['maxq', 'tests']
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py
deleted file mode 100644
index a65e68da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-Steps specific to package formats.
-"""
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py
deleted file mode 100644
index 5c01a15d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# This program is free software; you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Marius Rieder <marius.rieder@durchmesser.ch>
-"""
-Steps and objects related to lintian
-"""
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot import config
-
-class DebLintian(ShellCommand):
- name = "lintian"
- description = ["Lintian running"]
- descriptionDone = ["Lintian"]
-
- fileloc = None
- suppressTags = []
-
- warnCount = 0
- errCount = 0
-
- flunkOnFailure=False
- warnOnFailure=True
-
- def __init__(self, fileloc=None, suppressTags=None, **kwargs):
- """
- Create the DebLintian object.
-
- @type fileloc: str
- @param fileloc: Location of the .deb or .changes to test.
- @type suppressTags: list
- @param suppressTags: List of tags to suppress.
- @type kwargs: dict
- @param kwargs: all other keyword arguments.
- """
- ShellCommand.__init__(self, **kwargs)
- if fileloc:
- self.fileloc = fileloc
- if suppressTags:
- self.suppressTags = suppressTags
-
- if not self.fileloc:
- config.error("You must specify a fileloc")
-
- self.command = ["lintian", "-v", self.fileloc]
-
- if self.suppressTags:
- for tag in self.suppressTags:
- self.command += ['--suppress-tags', tag]
-
- def createSummary(self, log):
- """
- Create nice summary logs.
-
- @param log: log to create summary off of.
- """
- warnings = []
- errors = []
- for line in log.readlines():
- if 'W: ' in line:
- warnings.append(line)
- elif 'E: ' in line:
- errors.append(line)
-
- if warnings:
- self.addCompleteLog('%d Warnings' % len(warnings), "".join(warnings))
- self.warnCount = len(warnings)
- if errors:
- self.addCompleteLog('%d Errors' % len(errors), "".join(errors))
- self.errCount = len(errors)
-
- def evaluateCommand(self, cmd):
- if ( cmd.rc != 0 or self.errCount):
- return FAILURE
- if self.warnCount:
- return WARNINGS
- return SUCCESS
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py
deleted file mode 100644
index 1ed64c37..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# This program is free software; you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Marius Rieder <marius.rieder@durchmesser.ch>
-"""
-Steps and objects related to pbuilder
-"""
-
-import re
-import stat
-import time
-
-from twisted.python import log
-
-from buildbot.steps.shell import WarningCountingShellCommand
-from buildbot.process import buildstep
-from buildbot.process.buildstep import FAILURE
-from buildbot import config
-
-class DebPbuilder(WarningCountingShellCommand):
- """Build a debian package with pbuilder inside of a chroot."""
- name = "pbuilder"
-
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["pdebuilding"]
- descriptionDone = ["pdebuild"]
-
- warningPattern = ".*(warning[: ]|\sW: ).*"
-
- architecture = None
- distribution = 'stable'
- basetgz = "/var/cache/pbuilder/%(distribution)s-%(architecture)s-buildbot.tgz"
- mirror = "http://cdn.debian.net/debian/"
- extrapackages = []
- keyring = None
- components = None
-
- maxAge = 60*60*24*7
- pbuilder = '/usr/sbin/pbuilder'
- baseOption = '--basetgz'
-
- def __init__(self,
- architecture=None,
- distribution=None,
- basetgz=None,
- mirror=None,
- extrapackages=None,
- keyring=None,
- components=None,
- **kwargs):
- """
- Creates the DebPbuilder object.
-
- @type architecture: str
- @param architecture: the name of the architecture to build
- @type distribution: str
- @param distribution: the man of the distribution to use
- @type basetgz: str
- @param basetgz: the path or path template of the basetgz
- @type mirror: str
- @param mirror: the mirror for building basetgz
- @type extrapackages: list
- @param extrapackages: adds packages specified to buildroot
- @type keyring: str
- @param keyring: keyring file to use for verification
- @type components: str
- @param components: components to use for chroot creation
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- WarningCountingShellCommand.__init__(self, **kwargs)
-
- if architecture:
- self.architecture = architecture
- if distribution:
- self.distribution = distribution
- if mirror:
- self.mirror = mirror
- if extrapackages:
- self.extrapackages = extrapackages
- if keyring:
- self.keyring = keyring
- if components:
- self.components = components
-
- if self.architecture:
- kwargs['architecture'] = self.architecture
- else:
- kwargs['architecture'] = 'local'
- kwargs['distribution'] = self.distribution
-
- if basetgz:
- self.basetgz = basetgz % kwargs
- else:
- self.basetgz = self.basetgz % kwargs
-
- if not self.distribution:
- config.error("You must specify a distribution.")
-
- self.command = ['pdebuild', '--buildresult', '.', '--pbuilder', self.pbuilder]
- if self.architecture:
- self.command += ['--architecture', self.architecture]
- self.command += ['--', '--buildresult', '.', self.baseOption, self.basetgz]
- if self.extrapackages:
- self.command += ['--extrapackages', " ".join(self.extrapackages)]
-
- self.suppressions.append((None, re.compile("\.pbuilderrc does not exist"), None, None))
-
- # Check for Basetgz
- def start(self):
- cmd = buildstep.RemoteCommand('stat', {'file': self.basetgz})
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.checkBasetgz(cmd))
- d.addErrback(self.failed)
- return d
-
- def checkBasetgz(self, cmd):
- if cmd.rc != 0:
- log.msg("basetgz not found, initializing it.")
-
- command = ['sudo', self.pbuilder, '--create', self.baseOption,
- self.basetgz, '--distribution', self.distribution,
- '--mirror', self.mirror]
- if self.architecture:
- command += ['--architecture', self.architecture]
- if self.extrapackages:
- command += ['--extrapackages', " ".join(self.extrapackages)]
- if self.keyring:
- command += ['--debootstrapopts', "--keyring=%s" % self.keyring]
- if self.components:
- command += ['--components', self.components]
-
- cmd = buildstep.RemoteShellCommand(self.getWorkdir(), command)
-
- stdio_log = stdio_log = self.addLog("pbuilder")
- cmd.useLog(stdio_log, True, "stdio")
- d = self.runCommand(cmd)
- self.step_status.setText(["PBuilder create."])
- d.addCallback(lambda res: self.startBuild(cmd))
- return d
- s = cmd.updates["stat"][-1]
- # basetgz will be a file when running in pbuilder
- # and a directory in case of cowbuilder
- if stat.S_ISREG(s[stat.ST_MODE]) or stat.S_ISDIR(s[stat.ST_MODE]):
- log.msg("%s found." % self.basetgz)
- age = time.time() - s[stat.ST_MTIME]
- if age >= self.maxAge:
- log.msg("basetgz outdated, updating")
- command = ['sudo', self.pbuilder, '--update',
- self.baseOption, self.basetgz]
-
- cmd = buildstep.RemoteShellCommand(self.getWorkdir(), command)
- stdio_log = stdio_log = self.addLog("pbuilder")
- cmd.useLog(stdio_log, True, "stdio")
- d = self.runCommand(cmd)
- self.step_status.setText(["PBuilder update."])
- d.addCallback(lambda res: self.startBuild(cmd))
- return d
- return self.startBuild(cmd)
- else:
- log.msg("%s is not a file or a directory." % self.basetgz)
- self.finished(FAILURE)
-
- def startBuild(self, cmd):
- if cmd.rc != 0:
- log.msg("Failure when running %s." % cmd)
- self.finished(FAILURE)
- else:
- return WarningCountingShellCommand.start(self)
-
- def commandComplete(self, cmd):
- out = cmd.logs['stdio'].getText()
- m = re.search(r"dpkg-genchanges >\.\./(.+\.changes)", out)
- if m:
- self.setProperty("deb-changes", m.group(1), "DebPbuilder")
-
-class DebCowbuilder(DebPbuilder):
- """Build a debian package with cowbuilder inside of a chroot."""
- name = "cowbuilder"
-
- description = ["pdebuilding"]
- descriptionDone = ["pdebuild"]
-
- basetgz = "/var/cache/pbuilder/%(distribution)s-%(architecture)s-buildbot.cow/"
-
- pbuilder = '/usr/sbin/cowbuilder'
- baseOption = '--basepath'
-
-class UbuPbuilder(DebPbuilder):
- """Build a Ubuntu package with pbuilder inside of a chroot."""
- distribution = None
- mirror = "http://archive.ubuntu.com/ubuntu/"
-
- components = "main universe"
-
-class UbuCowbuilder(DebCowbuilder):
- """Build a Ubuntu package with cowbuilder inside of a chroot."""
- distribution = None
- mirror = "http://archive.ubuntu.com/ubuntu/"
-
- components = "main universe"
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py
deleted file mode 100644
index 429730a0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-Steps specific to the rpm format.
-"""
-
-from buildbot.steps.package.rpm.rpmbuild import RpmBuild
-from buildbot.steps.package.rpm.rpmspec import RpmSpec
-from buildbot.steps.package.rpm.rpmlint import RpmLint
-from buildbot.steps.package.rpm.mock import MockBuildSRPM, MockRebuild
-
-__all__ = ['RpmBuild', 'RpmSpec', 'RpmLint', 'MockBuildSRPM', 'MockRebuild']
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py
deleted file mode 100644
index 8c7e3491..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Marius Rieder <marius.rieder@durchmesser.ch>
-"""
-Steps and objects related to mock building.
-"""
-
-import re
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process import buildstep
-from buildbot import config
-
-class MockStateObserver(buildstep.LogLineObserver):
- _line_re = re.compile(r'^.*State Changed: (.*)$')
-
- def outLineReceived(self, line):
- m = self._line_re.search(line.strip())
- if m:
- state = m.group(1)
- if not state == 'end':
- self.step.descriptionSuffix = ["[%s]"%m.group(1)]
- else:
- self.step.descriptionSuffix = None
- self.step.step_status.setText(self.step.describe(False))
-
-class Mock(ShellCommand):
- """Add the mock logfiles and clean them if they already exist. Add support
- for the root and resultdir parameter of mock."""
-
- name = "mock"
-
- haltOnFailure = 1
- flunkOnFailure = 1
-
- mock_logfiles = ['build.log', 'root.log', 'state.log']
-
- root = None
- resultdir = None
-
- def __init__(self,
- root=None,
- resultdir=None,
- **kwargs):
- """
- Creates the Mock object.
-
- @type root: str
- @param root: the name of the mock buildroot
- @type resultdir: str
- @param resultdir: the path of the result dir
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- ShellCommand.__init__(self, **kwargs)
- if root:
- self.root = root
- if resultdir:
- self.resultdir = resultdir
-
- if not self.root:
- config.error("You must specify a mock root")
-
-
- self.command = ['mock', '--root', self.root]
- if self.resultdir:
- self.command += ['--resultdir', self.resultdir]
-
- def start(self):
- """
- Try to remove the old mock logs first.
- """
- if self.resultdir:
- for lname in self.mock_logfiles:
- self.logfiles[lname] = self.build.path_module.join(self.resultdir,
- lname)
- else:
- for lname in self.mock_logfiles:
- self.logfiles[lname] = lname
- self.addLogObserver('state.log', MockStateObserver())
-
- cmd = buildstep.RemoteCommand('rmdir', {'dir':
- map(lambda l: self.build.path_module.join('build', self.logfiles[l]),
- self.mock_logfiles)})
- d = self.runCommand(cmd)
- def removeDone(cmd):
- ShellCommand.start(self)
- d.addCallback(removeDone)
- d.addErrback(self.failed)
-
-class MockBuildSRPM(Mock):
- """Build a srpm within a mock. Requires a spec file and a sources dir."""
-
- name = "mockbuildsrpm"
-
- description = ["mock buildsrpm"]
- descriptionDone = ["mock buildsrpm"]
-
- spec = None
- sources = '.'
-
- def __init__(self,
- spec=None,
- sources=None,
- **kwargs):
- """
- Creates the MockBuildSRPM object.
-
- @type spec: str
- @param spec: the path of the specfiles.
- @type sources: str
- @param sources: the path of the sources dir.
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- Mock.__init__(self, **kwargs)
- if spec:
- self.spec = spec
- if sources:
- self.sources = sources
-
- if not self.spec:
- config.error("You must specify a spec file")
- if not self.sources:
- config.error("You must specify a sources dir")
-
- self.command += ['--buildsrpm', '--spec', self.spec,
- '--sources', self.sources]
-
- def commandComplete(self, cmd):
- out = cmd.logs['build.log'].getText()
- m = re.search(r"Wrote: .*/([^/]*.src.rpm)", out)
- if m:
- self.setProperty("srpm", m.group(1), 'MockBuildSRPM')
-
-class MockRebuild(Mock):
- """Rebuild a srpm within a mock. Requires a srpm file."""
-
- name = "mock"
-
- description = ["mock rebuilding srpm"]
- descriptionDone = ["mock rebuild srpm"]
-
- srpm = None
-
- def __init__(self, srpm=None, **kwargs):
- """
- Creates the MockRebuildRPM object.
-
- @type srpm: str
- @param srpm: the path of the srpm file.
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- Mock.__init__(self, **kwargs)
- if srpm:
- self.srpm = srpm
-
- if not self.srpm:
- config.error("You must specify a srpm")
-
- self.command += ['--rebuild', self.srpm]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py
deleted file mode 100644
index 9d5c88ea..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-
-from __future__ import with_statement
-# Portions Copyright Dan Radez <dradez+buildbot@redhat.com>
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-
-import os
-from buildbot.steps.shell import ShellCommand
-from buildbot.process import buildstep
-from buildbot import config
-
-class RpmBuild(ShellCommand):
- """
- RpmBuild build step.
- """
-
- name = "rpmbuilder"
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["RPMBUILD"]
- descriptionDone = ["RPMBUILD"]
-
- def __init__(self,
- specfile=None,
- topdir='`pwd`',
- builddir='`pwd`',
- rpmdir='`pwd`',
- sourcedir='`pwd`',
- specdir='`pwd`',
- srcrpmdir='`pwd`',
- dist='.el5',
- autoRelease=False,
- vcsRevision=False,
- **kwargs):
- """
- Create the RpmBuild object.
-
- @type specfile: str
- @param specfile: location of the specfile to build
- @type topdir: str
- @param topdir: define the _topdir rpm parameter
- @type builddir: str
- @param builddir: define the _builddir rpm parameter
- @type rpmdir: str
- @param rpmdir: define the _rpmdir rpm parameter
- @type sourcedir: str
- @param sourcedir: define the _sourcedir rpm parameter
- @type specdir: str
- @param specdir: define the _specdir rpm parameter
- @type srcrpmdir: str
- @param srcrpmdir: define the _srcrpmdir rpm parameter
- @type dist: str
- @param dist: define the dist string.
- @type autoRelease: boolean
- @param autoRelease: Use auto incrementing release numbers.
- @type vcsRevision: boolean
- @param vcsRevision: Use vcs version number as revision number.
- """
- ShellCommand.__init__(self, **kwargs)
- self.rpmbuild = (
- 'rpmbuild --define "_topdir %s" --define "_builddir %s"'
- ' --define "_rpmdir %s" --define "_sourcedir %s"'
- ' --define "_specdir %s" --define "_srcrpmdir %s"'
- ' --define "dist %s"' % (topdir, builddir, rpmdir, sourcedir,
- specdir, srcrpmdir, dist))
- self.specfile = specfile
- self.autoRelease = autoRelease
- self.vcsRevision = vcsRevision
-
- if not self.specfile:
- config.error("You must specify a specfile")
-
- def start(self):
- if self.autoRelease:
- relfile = '%s.release' % (
- os.path.basename(self.specfile).split('.')[0])
- try:
- with open(relfile, 'r') as rfile:
- rel = int(rfile.readline().strip())
- except:
- rel = 0
- self.rpmbuild = self.rpmbuild + ' --define "_release %s"' % rel
- with open(relfile, 'w') as rfile:
- rfile.write(str(rel+1))
-
- if self.vcsRevision:
- revision = self.getProperty('got_revision')
- # only do this in the case where there's a single codebase
- if revision and not isinstance(revision, dict):
- self.rpmbuild = (self.rpmbuild + ' --define "_revision %s"' %
- revision)
-
- self.rpmbuild = self.rpmbuild + ' -ba %s' % self.specfile
-
- self.command = self.rpmbuild
-
- # create the actual RemoteShellCommand instance now
- kwargs = self.remote_kwargs
- kwargs['command'] = self.command
- cmd = buildstep.RemoteShellCommand(**kwargs)
- self.setupEnvironment(cmd)
- self.startCommand(cmd)
-
- def createSummary(self, log):
- rpm_prefixes = ['Provides:', 'Requires(', 'Requires:',
- 'Checking for unpackaged', 'Wrote:',
- 'Executing(%', '+ ', 'Processing files:']
- rpm_err_pfx = [' ', 'RPM build errors:', 'error: ']
-
- rpmcmdlog = []
- rpmerrors = []
-
- for line in log.getText().splitlines(True):
- for pfx in rpm_prefixes:
- if line.startswith(pfx):
- rpmcmdlog.append(line)
- break
- for err in rpm_err_pfx:
- if line.startswith(err):
- rpmerrors.append(line)
- break
- self.addCompleteLog('RPM Command Log', "".join(rpmcmdlog))
- if rpmerrors:
- self.addCompleteLog('RPM Errors', "".join(rpmerrors))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py
deleted file mode 100644
index ab14ca1a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-Steps and objects related to rpmlint.
-"""
-
-from buildbot.steps.shell import Test
-
-
-class RpmLint(Test):
- """
- Rpmlint build step.
- """
-
- name = "rpmlint"
-
- description = ["Checking for RPM/SPEC issues"]
- descriptionDone = ["Finished checking RPM/SPEC issues"]
-
- fileloc = '.'
- config = None
-
- def __init__(self,
- fileloc=None,
- config=None,
- **kwargs):
- """
- Create the Rpmlint object.
-
- @type fileloc: str
- @param fileloc: Location glob of the specs or rpms.
- @type config: str
- @param config: path to the rpmlint user config.
- @type kwargs: dict
- @param fileloc: all other keyword arguments.
- """
- Test.__init__(self, **kwargs)
- if fileloc:
- self.fileloc = fileloc
- if config:
- self.config = config
-
- self.command = ["rpmlint", "-i"]
- if self.config:
- self.command += ['-f', self.config]
- self.command.append(self.fileloc)
-
- def createSummary(self, log):
- """
- Create nice summary logs.
-
- @param log: log to create summary off of.
- """
- warnings = []
- errors = []
- for line in log.readlines():
- if ' W: ' in line:
- warnings.append(line)
- elif ' E: ' in line:
- errors.append(line)
- if warnings:
- self.addCompleteLog('%d Warnings'%len(warnings), "".join(warnings))
- if errors:
- self.addCompleteLog('%d Errors'%len(errors), "".join(errors))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py
deleted file mode 100644
index a3676c81..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Dan Radez <dradez+buildbot@redhat.com>
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-library to populate parameters from and rpmspec file into a memory structure
-"""
-
-import re
-from buildbot.steps.shell import ShellCommand
-
-
-class RpmSpec(ShellCommand):
- """
- read parameters out of an rpm spec file
- """
-
- #initialize spec info vars and get them from the spec file
- n_regex = re.compile('^Name:[ ]*([^\s]*)')
- v_regex = re.compile('^Version:[ ]*([0-9\.]*)')
-
- def __init__(self, specfile=None, **kwargs):
- """
- Creates the RpmSpec object.
-
- @type specfile: str
- @param specfile: the name of the specfile to get the package
- name and version from
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- self.specfile = specfile
- self._pkg_name = None
- self._pkg_version = None
- self._loaded = False
-
- def load(self):
- """
- call this function after the file exists to populate properties
- """
- # If we are given a string, open it up else assume it's something we
- # can call read on.
- if isinstance(self.specfile, str):
- f = open(self.specfile, 'r')
- else:
- f = self.specfile
-
- for line in f:
- if self.v_regex.match(line):
- self._pkg_version = self.v_regex.match(line).group(1)
- if self.n_regex.match(line):
- self._pkg_name = self.n_regex.match(line).group(1)
- f.close()
- self._loaded = True
-
- # Read-only properties
- loaded = property(lambda self: self._loaded)
- pkg_name = property(lambda self: self._pkg_name)
- pkg_version = property(lambda self: self._pkg_version)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py
deleted file mode 100644
index ce552b0d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import re
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.steps.shell import ShellCommand
-from buildbot import config
-
-try:
- import cStringIO
- StringIO = cStringIO.StringIO
-except ImportError:
- from StringIO import StringIO
-
-
-class BuildEPYDoc(ShellCommand):
- name = "epydoc"
- command = ["make", "epydocs"]
- description = ["building", "epydocs"]
- descriptionDone = ["epydoc"]
-
- def createSummary(self, log):
- import_errors = 0
- warnings = 0
- errors = 0
-
- for line in StringIO(log.getText()):
- if line.startswith("Error importing "):
- import_errors += 1
- if line.find("Warning: ") != -1:
- warnings += 1
- if line.find("Error: ") != -1:
- errors += 1
-
- self.descriptionDone = self.descriptionDone[:]
- if import_errors:
- self.descriptionDone.append("ierr=%d" % import_errors)
- if warnings:
- self.descriptionDone.append("warn=%d" % warnings)
- if errors:
- self.descriptionDone.append("err=%d" % errors)
-
- self.import_errors = import_errors
- self.warnings = warnings
- self.errors = errors
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- if self.warnings or self.errors:
- return WARNINGS
- return SUCCESS
-
-
-class PyFlakes(ShellCommand):
- name = "pyflakes"
- command = ["make", "pyflakes"]
- description = ["running", "pyflakes"]
- descriptionDone = ["pyflakes"]
- flunkOnFailure = False
- flunkingIssues = ["undefined"] # any pyflakes lines like this cause FAILURE
-
- MESSAGES = ("unused", "undefined", "redefs", "import*", "misc")
-
- def __init__(self, *args, **kwargs):
- # PyFlakes return 1 for both warnings and errors. We
- # categorize this initially as WARNINGS so that
- # evaluateCommand below can inspect the results more closely.
- kwargs['decodeRC'] = {0: SUCCESS, 1: WARNINGS}
- ShellCommand.__init__(self, *args, **kwargs)
-
- def createSummary(self, log):
- counts = {}
- summaries = {}
- for m in self.MESSAGES:
- counts[m] = 0
- summaries[m] = []
-
- first = True
- for line in StringIO(log.getText()).readlines():
- # the first few lines might contain echoed commands from a 'make
- # pyflakes' step, so don't count these as warnings. Stop ignoring
- # the initial lines as soon as we see one with a colon.
- if first:
- if line.find(":") != -1:
- # there's the colon, this is the first real line
- first = False
- # fall through and parse the line
- else:
- # skip this line, keep skipping non-colon lines
- continue
- if line.find("imported but unused") != -1:
- m = "unused"
- elif line.find("*' used; unable to detect undefined names") != -1:
- m = "import*"
- elif line.find("undefined name") != -1:
- m = "undefined"
- elif line.find("redefinition of unused") != -1:
- m = "redefs"
- else:
- m = "misc"
- summaries[m].append(line)
- counts[m] += 1
-
- self.descriptionDone = self.descriptionDone[:]
- for m in self.MESSAGES:
- if counts[m]:
- self.descriptionDone.append("%s=%d" % (m, counts[m]))
- self.addCompleteLog(m, "".join(summaries[m]))
- self.setProperty("pyflakes-%s" % m, counts[m], "pyflakes")
- self.setProperty("pyflakes-total", sum(counts.values()), "pyflakes")
-
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- for m in self.flunkingIssues:
- if self.getProperty("pyflakes-%s" % m):
- return FAILURE
- if self.getProperty("pyflakes-total"):
- return WARNINGS
- return SUCCESS
-
-class PyLint(ShellCommand):
- '''A command that knows about pylint output.
- It is a good idea to add --output-format=parseable to your
- command, since it includes the filename in the message.
- '''
- name = "pylint"
- description = ["running", "pylint"]
- descriptionDone = ["pylint"]
-
- # pylint's return codes (see pylint(1) for details)
- # 1 - 16 will be bit-ORed
-
- RC_OK = 0
- RC_FATAL = 1
- RC_ERROR = 2
- RC_WARNING = 4
- RC_REFACTOR = 8
- RC_CONVENTION = 16
- RC_USAGE = 32
-
- # Using the default text output, the message format is :
- # MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
- # with --output-format=parseable it is: (the outer brackets are literal)
- # FILE_NAME:LINE_NUM: [MESSAGE_TYPE[, OBJECT]] MESSAGE
- # message type consists of the type char and 4 digits
- # The message types:
-
- MESSAGES = {
- 'C': "convention", # for programming standard violation
- 'R': "refactor", # for bad code smell
- 'W': "warning", # for python specific problems
- 'E': "error", # for much probably bugs in the code
- 'F': "fatal", # error prevented pylint from further processing.
- 'I': "info",
- }
-
- flunkingIssues = ["F", "E"] # msg categories that cause FAILURE
-
- _re_groupname = 'errtype'
- _msgtypes_re_str = '(?P<%s>[%s])' % (_re_groupname, ''.join(MESSAGES.keys()))
- _default_line_re = re.compile(r'^%s(\d{4})?: *\d+(,\d+)?:.+' % _msgtypes_re_str)
- _parseable_line_re = re.compile(r'[^:]+:\d+: \[%s(\d{4})?[,\]] .+' % _msgtypes_re_str)
-
- def createSummary(self, log):
- counts = {}
- summaries = {}
- for m in self.MESSAGES:
- counts[m] = 0
- summaries[m] = []
-
- line_re = None # decide after first match
- for line in StringIO(log.getText()).readlines():
- if not line_re:
- # need to test both and then decide on one
- if self._parseable_line_re.match(line):
- line_re = self._parseable_line_re
- elif self._default_line_re.match(line):
- line_re = self._default_line_re
- else: # no match yet
- continue
- mo = line_re.match(line)
- if mo:
- msgtype = mo.group(self._re_groupname)
- assert msgtype in self.MESSAGES
- summaries[msgtype].append(line)
- counts[msgtype] += 1
-
- self.descriptionDone = self.descriptionDone[:]
- for msg, fullmsg in self.MESSAGES.items():
- if counts[msg]:
- self.descriptionDone.append("%s=%d" % (fullmsg, counts[msg]))
- self.addCompleteLog(fullmsg, "".join(summaries[msg]))
- self.setProperty("pylint-%s" % fullmsg, counts[msg])
- self.setProperty("pylint-total", sum(counts.values()))
-
- def evaluateCommand(self, cmd):
- if cmd.rc & (self.RC_FATAL|self.RC_ERROR|self.RC_USAGE):
- return FAILURE
- for msg in self.flunkingIssues:
- if self.getProperty("pylint-%s" % self.MESSAGES[msg]):
- return FAILURE
- if self.getProperty("pylint-total"):
- return WARNINGS
- return SUCCESS
-
-class Sphinx(ShellCommand):
- ''' A Step to build sphinx documentation '''
-
- name = "sphinx"
- description = ["running", "sphinx"]
- descriptionDone = ["sphinx"]
-
- haltOnFailure = True
-
- def __init__(self, sphinx_sourcedir='.', sphinx_builddir=None,
- sphinx_builder=None, sphinx = 'sphinx-build', tags = [],
- defines = {}, mode='incremental', **kwargs):
-
- if sphinx_builddir is None:
- # Who the heck is not interested in the built doc ?
- config.error("Sphinx argument sphinx_builddir is required")
-
- if mode not in ('incremental', 'full'):
- config.error("Sphinx argument mode has to be 'incremental' or" +
- "'full' is required")
-
- self.warnings = 0
- self.success = False
- ShellCommand.__init__(self, **kwargs)
-
- # build the command
- command = [sphinx]
- if sphinx_builder is not None:
- command.extend(['-b', sphinx_builder])
-
- for tag in tags:
- command.extend(['-t', tag])
-
- for key in sorted(defines):
- if defines[key] is None:
- command.extend(['-D', key])
- elif isinstance(defines[key], bool):
- command.extend(['-D',
- '%s=%d' % (key, defines[key] and 1 or 0)])
- else:
- command.extend(['-D', '%s=%s' % (key, defines[key])])
-
- if mode == 'full':
- command.extend(['-E']) # Don't use a saved environment
-
- command.extend([sphinx_sourcedir, sphinx_builddir])
- self.setCommand(command)
-
- def createSummary(self, log):
-
- msgs = ['WARNING', 'ERROR', 'SEVERE']
-
- warnings = []
- for line in log.getText().split('\n'):
- if (line.startswith('build succeeded')
- or line.startswith('no targets are out of date.')):
- self.success = True
- else:
- for msg in msgs:
- if msg in line:
- warnings.append(line)
- self.warnings += 1
- if self.warnings > 0:
- self.addCompleteLog('warnings', "\n".join(warnings))
-
- self.step_status.setStatistic('warnings', self.warnings)
-
- def evaluateCommand(self, cmd):
- if self.success:
- if self.warnings == 0:
- return SUCCESS
- else:
- return WARNINGS
- else:
- return FAILURE
-
- def describe(self, done=False):
- if not done:
- return ["building"]
-
- description = [self.name]
- description.append('%d warnings' % self.warnings)
- return description
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py
deleted file mode 100644
index fa91f552..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py
+++ /dev/null
@@ -1,611 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.python import log
-
-from buildbot.status import testresult
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS, SKIPPED
-from buildbot.process.buildstep import LogLineObserver, OutputProgressObserver
-from buildbot.steps.shell import ShellCommand
-
-try:
- import cStringIO
- StringIO = cStringIO
-except ImportError:
- import StringIO
-import re
-
-# BuildSteps that are specific to the Twisted source tree
-
-class HLint(ShellCommand):
- """I run a 'lint' checker over a set of .xhtml files. Any deviations
- from recommended style is flagged and put in the output log.
-
- This step looks at .changes in the parent Build to extract a list of
- Lore XHTML files to check."""
-
- name = "hlint"
- description = ["running", "hlint"]
- descriptionDone = ["hlint"]
- warnOnWarnings = True
- warnOnFailure = True
- # TODO: track time, but not output
- warnings = 0
-
- def __init__(self, python=None, **kwargs):
- ShellCommand.__init__(self, **kwargs)
- self.python = python
-
- def start(self):
- # create the command
- htmlFiles = {}
- for f in self.build.allFiles():
- if f.endswith(".xhtml") and not f.startswith("sandbox/"):
- htmlFiles[f] = 1
- # remove duplicates
- hlintTargets = htmlFiles.keys()
- hlintTargets.sort()
- if not hlintTargets:
- return SKIPPED
- self.hlintFiles = hlintTargets
- c = []
- if self.python:
- c.append(self.python)
- c += ["bin/lore", "-p", "--output", "lint"] + self.hlintFiles
- self.setCommand(c)
-
- # add an extra log file to show the .html files we're checking
- self.addCompleteLog("files", "\n".join(self.hlintFiles)+"\n")
-
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- # TODO: remove the 'files' file (a list of .xhtml files that were
- # submitted to hlint) because it is available in the logfile and
- # mostly exists to give the user an idea of how long the step will
- # take anyway).
- lines = cmd.logs['stdio'].getText().split("\n")
- warningLines = filter(lambda line:':' in line, lines)
- if warningLines:
- self.addCompleteLog("warnings", "".join(warningLines))
- warnings = len(warningLines)
- self.warnings = warnings
-
- def evaluateCommand(self, cmd):
- # warnings are in stdout, rc is always 0, unless the tools break
- if cmd.didFail():
- return FAILURE
- if self.warnings:
- return WARNINGS
- return SUCCESS
-
- def getText2(self, cmd, results):
- if cmd.didFail():
- return ["hlint"]
- return ["%d hlin%s" % (self.warnings,
- self.warnings == 1 and 't' or 'ts')]
-
-def countFailedTests(output):
- # start scanning 10kb from the end, because there might be a few kb of
- # import exception tracebacks between the total/time line and the errors
- # line
- chunk = output[-10000:]
- lines = chunk.split("\n")
- lines.pop() # blank line at end
- # lines[-3] is "Ran NN tests in 0.242s"
- # lines[-2] is blank
- # lines[-1] is 'OK' or 'FAILED (failures=1, errors=12)'
- # or 'FAILED (failures=1)'
- # or "PASSED (skips=N, successes=N)" (for Twisted-2.0)
- # there might be other lines dumped here. Scan all the lines.
- res = {'total': None,
- 'failures': 0,
- 'errors': 0,
- 'skips': 0,
- 'expectedFailures': 0,
- 'unexpectedSuccesses': 0,
- }
- for l in lines:
- out = re.search(r'Ran (\d+) tests', l)
- if out:
- res['total'] = int(out.group(1))
- if (l.startswith("OK") or
- l.startswith("FAILED ") or
- l.startswith("PASSED")):
- # the extra space on FAILED_ is to distinguish the overall
- # status from an individual test which failed. The lack of a
- # space on the OK is because it may be printed without any
- # additional text (if there are no skips,etc)
- out = re.search(r'failures=(\d+)', l)
- if out: res['failures'] = int(out.group(1))
- out = re.search(r'errors=(\d+)', l)
- if out: res['errors'] = int(out.group(1))
- out = re.search(r'skips=(\d+)', l)
- if out: res['skips'] = int(out.group(1))
- out = re.search(r'expectedFailures=(\d+)', l)
- if out: res['expectedFailures'] = int(out.group(1))
- out = re.search(r'unexpectedSuccesses=(\d+)', l)
- if out: res['unexpectedSuccesses'] = int(out.group(1))
- # successes= is a Twisted-2.0 addition, and is not currently used
- out = re.search(r'successes=(\d+)', l)
- if out: res['successes'] = int(out.group(1))
-
- return res
-
-
-class TrialTestCaseCounter(LogLineObserver):
- _line_re = re.compile(r'^(?:Doctest: )?([\w\.]+) \.\.\. \[([^\]]+)\]$')
- numTests = 0
- finished = False
-
- def outLineReceived(self, line):
- # different versions of Twisted emit different per-test lines with
- # the bwverbose reporter.
- # 2.0.0: testSlave (buildbot.test.test_runner.Create) ... [OK]
- # 2.1.0: buildbot.test.test_runner.Create.testSlave ... [OK]
- # 2.4.0: buildbot.test.test_runner.Create.testSlave ... [OK]
- # Let's just handle the most recent version, since it's the easiest.
- # Note that doctests create lines line this:
- # Doctest: viff.field.GF ... [OK]
-
- if self.finished:
- return
- if line.startswith("=" * 40):
- self.finished = True
- return
-
- m = self._line_re.search(line.strip())
- if m:
- testname, result = m.groups()
- self.numTests += 1
- self.step.setProgress('tests', self.numTests)
-
-
-UNSPECIFIED=() # since None is a valid choice
-
-class Trial(ShellCommand):
- """
- There are some class attributes which may be usefully overridden
- by subclasses. 'trialMode' and 'trialArgs' can influence the trial
- command line.
- """
-
- name = "trial"
- progressMetrics = ('output', 'tests', 'test.log')
- # note: the slash only works on unix buildslaves, of course, but we have
- # no way to know what the buildslave uses as a separator.
- # TODO: figure out something clever.
- logfiles = {"test.log": "_trial_temp/test.log"}
- # we use test.log to track Progress at the end of __init__()
-
- renderables = ['tests', 'jobs']
- flunkOnFailure = True
- python = None
- trial = "trial"
- trialMode = ["--reporter=bwverbose"] # requires Twisted-2.1.0 or newer
- # for Twisted-2.0.0 or 1.3.0, use ["-o"] instead
- trialArgs = []
- jobs = None
- testpath = UNSPECIFIED # required (but can be None)
- testChanges = False # TODO: needs better name
- recurse = False
- reactor = None
- randomly = False
- tests = None # required
-
- def __init__(self, reactor=UNSPECIFIED, python=None, trial=None,
- testpath=UNSPECIFIED,
- tests=None, testChanges=None,
- recurse=None, randomly=None,
- trialMode=None, trialArgs=None, jobs=None,
- **kwargs):
- """
- @type testpath: string
- @param testpath: use in PYTHONPATH when running the tests. If
- None, do not set PYTHONPATH. Setting this to '.' will
- cause the source files to be used in-place.
-
- @type python: string (without spaces) or list
- @param python: which python executable to use. Will form the start of
- the argv array that will launch trial. If you use this,
- you should set 'trial' to an explicit path (like
- /usr/bin/trial or ./bin/trial). Defaults to None, which
- leaves it out entirely (running 'trial args' instead of
- 'python ./bin/trial args'). Likely values are 'python',
- ['python2.2'], ['python', '-Wall'], etc.
-
- @type trial: string
- @param trial: which 'trial' executable to run.
- Defaults to 'trial', which will cause $PATH to be
- searched and probably find /usr/bin/trial . If you set
- 'python', this should be set to an explicit path (because
- 'python2.3 trial' will not work).
-
- @type trialMode: list of strings
- @param trialMode: a list of arguments to pass to trial, specifically
- to set the reporting mode. This defaults to ['-to']
- which means 'verbose colorless output' to the trial
- that comes with Twisted-2.0.x and at least -2.1.0 .
- Newer versions of Twisted may come with a trial
- that prefers ['--reporter=bwverbose'].
-
- @type trialArgs: list of strings
- @param trialArgs: a list of arguments to pass to trial, available to
- turn on any extra flags you like. Defaults to [].
-
- @type jobs: integer
- @param jobs: integer to be used as trial -j/--jobs option (for
- running tests on several workers). Only supported
- since Twisted-12.3.0.
-
- @type tests: list of strings
- @param tests: a list of test modules to run, like
- ['twisted.test.test_defer', 'twisted.test.test_process'].
- If this is a string, it will be converted into a one-item
- list.
-
- @type testChanges: boolean
- @param testChanges: if True, ignore the 'tests' parameter and instead
- ask the Build for all the files that make up the
- Changes going into this build. Pass these filenames
- to trial and ask it to look for test-case-name
- tags, running just the tests necessary to cover the
- changes.
-
- @type recurse: boolean
- @param recurse: If True, pass the --recurse option to trial, allowing
- test cases to be found in deeper subdirectories of the
- modules listed in 'tests'. This does not appear to be
- necessary when using testChanges.
-
- @type reactor: string
- @param reactor: which reactor to use, like 'gtk' or 'java'. If not
- provided, the Twisted's usual platform-dependent
- default is used.
-
- @type randomly: boolean
- @param randomly: if True, add the --random=0 argument, which instructs
- trial to run the unit tests in a random order each
- time. This occasionally catches problems that might be
- masked when one module always runs before another
- (like failing to make registerAdapter calls before
- lookups are done).
-
- @type kwargs: dict
- @param kwargs: parameters. The following parameters are inherited from
- L{ShellCommand} and may be useful to set: workdir,
- haltOnFailure, flunkOnWarnings, flunkOnFailure,
- warnOnWarnings, warnOnFailure, want_stdout, want_stderr,
- timeout.
- """
- ShellCommand.__init__(self, **kwargs)
-
- if python:
- self.python = python
- if self.python is not None:
- if type(self.python) is str:
- self.python = [self.python]
- for s in self.python:
- if " " in s:
- # this is not strictly an error, but I suspect more
- # people will accidentally try to use python="python2.3
- # -Wall" than will use embedded spaces in a python flag
- log.msg("python= component '%s' has spaces")
- log.msg("To add -Wall, use python=['python', '-Wall']")
- why = "python= value has spaces, probably an error"
- raise ValueError(why)
-
- if trial:
- self.trial = trial
- if " " in self.trial:
- raise ValueError("trial= value has spaces")
- if trialMode is not None:
- self.trialMode = trialMode
- if trialArgs is not None:
- self.trialArgs = trialArgs
- if jobs is not None:
- self.jobs = jobs
-
- if testpath is not UNSPECIFIED:
- self.testpath = testpath
- if self.testpath is UNSPECIFIED:
- raise ValueError("You must specify testpath= (it can be None)")
- assert isinstance(self.testpath, str) or self.testpath is None
-
- if reactor is not UNSPECIFIED:
- self.reactor = reactor
-
- if tests is not None:
- self.tests = tests
- if type(self.tests) is str:
- self.tests = [self.tests]
- if testChanges is not None:
- self.testChanges = testChanges
- #self.recurse = True # not sure this is necessary
-
- if not self.testChanges and self.tests is None:
- raise ValueError("Must either set testChanges= or provide tests=")
-
- if recurse is not None:
- self.recurse = recurse
- if randomly is not None:
- self.randomly = randomly
-
- # build up most of the command, then stash it until start()
- command = []
- if self.python:
- command.extend(self.python)
- command.append(self.trial)
- command.extend(self.trialMode)
- if self.recurse:
- command.append("--recurse")
- if self.reactor:
- command.append("--reactor=%s" % reactor)
- if self.randomly:
- command.append("--random=0")
- command.extend(self.trialArgs)
- self.command = command
-
- if self.reactor:
- self.description = ["testing", "(%s)" % self.reactor]
- self.descriptionDone = ["tests"]
- # commandComplete adds (reactorname) to self.text
- else:
- self.description = ["testing"]
- self.descriptionDone = ["tests"]
-
- # this counter will feed Progress along the 'test cases' metric
- self.addLogObserver('stdio', TrialTestCaseCounter())
-
- def setupEnvironment(self, cmd):
- ShellCommand.setupEnvironment(self, cmd)
- if self.testpath != None:
- e = cmd.args['env']
- if e is None:
- cmd.args['env'] = {'PYTHONPATH': self.testpath}
- else:
- #this bit produces a list, which can be used
- #by buildslave.runprocess.RunProcess
- ppath = e.get('PYTHONPATH', self.testpath)
- if isinstance(ppath, str):
- ppath = [ppath]
- if self.testpath not in ppath:
- ppath.insert(0, self.testpath)
- e['PYTHONPATH'] = ppath
-
- def start(self):
- # choose progressMetrics and logfiles based on whether trial is being
- # run with multiple workers or not.
- output_observer = OutputProgressObserver('test.log')
-
- if self.jobs is not None:
- self.jobs = int(self.jobs)
- self.command.append("--jobs=%d" % self.jobs)
-
- # using -j/--jobs flag produces more than one test log.
- self.logfiles = {}
- for i in xrange(self.jobs):
- self.logfiles['test.%d.log' % i] = '_trial_temp/%d/test.log' % i
- self.logfiles['err.%d.log' % i] = '_trial_temp/%d/err.log' % i
- self.logfiles['out.%d.log' % i] = '_trial_temp/%d/out.log' % i
- self.addLogObserver('test.%d.log' % i, output_observer)
- else:
- # this one just measures bytes of output in _trial_temp/test.log
- self.addLogObserver('test.log', output_observer)
-
- # now that self.build.allFiles() is nailed down, finish building the
- # command
- if self.testChanges:
- for f in self.build.allFiles():
- if f.endswith(".py"):
- self.command.append("--testmodule=%s" % f)
- else:
- self.command.extend(self.tests)
- log.msg("Trial.start: command is", self.command)
-
- ShellCommand.start(self)
-
-
- def commandComplete(self, cmd):
- # figure out all status, then let the various hook functions return
- # different pieces of it
-
- # 'cmd' is the original trial command, so cmd.logs['stdio'] is the
- # trial output. We don't have access to test.log from here.
- output = cmd.logs['stdio'].getText()
- counts = countFailedTests(output)
-
- total = counts['total']
- failures, errors = counts['failures'], counts['errors']
- parsed = (total != None)
- text = []
- text2 = ""
-
- if not cmd.didFail():
- if parsed:
- results = SUCCESS
- if total:
- text += ["%d %s" % \
- (total,
- total == 1 and "test" or "tests"),
- "passed"]
- else:
- text += ["no tests", "run"]
- else:
- results = FAILURE
- text += ["testlog", "unparseable"]
- text2 = "tests"
- else:
- # something failed
- results = FAILURE
- if parsed:
- text.append("tests")
- if failures:
- text.append("%d %s" % \
- (failures,
- failures == 1 and "failure" or "failures"))
- if errors:
- text.append("%d %s" % \
- (errors,
- errors == 1 and "error" or "errors"))
- count = failures + errors
- text2 = "%d tes%s" % (count, (count == 1 and 't' or 'ts'))
- else:
- text += ["tests", "failed"]
- text2 = "tests"
-
- if counts['skips']:
- text.append("%d %s" % \
- (counts['skips'],
- counts['skips'] == 1 and "skip" or "skips"))
- if counts['expectedFailures']:
- text.append("%d %s" % \
- (counts['expectedFailures'],
- counts['expectedFailures'] == 1 and "todo"
- or "todos"))
- if 0: # TODO
- results = WARNINGS
- if not text2:
- text2 = "todo"
-
- if 0:
- # ignore unexpectedSuccesses for now, but it should really mark
- # the build WARNING
- if counts['unexpectedSuccesses']:
- text.append("%d surprises" % counts['unexpectedSuccesses'])
- results = WARNINGS
- if not text2:
- text2 = "tests"
-
- if self.reactor:
- text.append(self.rtext('(%s)'))
- if text2:
- text2 = "%s %s" % (text2, self.rtext('(%s)'))
-
- self.results = results
- self.text = text
- self.text2 = [text2]
-
-
- def rtext(self, fmt='%s'):
- if self.reactor:
- rtext = fmt % self.reactor
- return rtext.replace("reactor", "")
- return ""
-
- def addTestResult(self, testname, results, text, tlog):
- if self.reactor is not None:
- testname = (self.reactor,) + testname
- tr = testresult.TestResult(testname, results, text, logs={'log': tlog})
- #self.step_status.build.addTestResult(tr)
- self.build.build_status.addTestResult(tr)
-
- def createSummary(self, loog):
- output = loog.getText()
- problems = ""
- sio = StringIO.StringIO(output)
- warnings = {}
- while 1:
- line = sio.readline()
- if line == "":
- break
- if line.find(" exceptions.DeprecationWarning: ") != -1:
- # no source
- warning = line # TODO: consider stripping basedir prefix here
- warnings[warning] = warnings.get(warning, 0) + 1
- elif (line.find(" DeprecationWarning: ") != -1 or
- line.find(" UserWarning: ") != -1):
- # next line is the source
- warning = line + sio.readline()
- warnings[warning] = warnings.get(warning, 0) + 1
- elif line.find("Warning: ") != -1:
- warning = line
- warnings[warning] = warnings.get(warning, 0) + 1
-
- if line.find("=" * 60) == 0 or line.find("-" * 60) == 0:
- problems += line
- problems += sio.read()
- break
-
- if problems:
- self.addCompleteLog("problems", problems)
- # now parse the problems for per-test results
- pio = StringIO.StringIO(problems)
- pio.readline() # eat the first separator line
- testname = None
- done = False
- while not done:
- while 1:
- line = pio.readline()
- if line == "":
- done = True
- break
- if line.find("=" * 60) == 0:
- break
- if line.find("-" * 60) == 0:
- # the last case has --- as a separator before the
- # summary counts are printed
- done = True
- break
- if testname is None:
- # the first line after the === is like:
-# EXPECTED FAILURE: testLackOfTB (twisted.test.test_failure.FailureTestCase)
-# SKIPPED: testRETR (twisted.test.test_ftp.TestFTPServer)
-# FAILURE: testBatchFile (twisted.conch.test.test_sftp.TestOurServerBatchFile)
- r = re.search(r'^([^:]+): (\w+) \(([\w\.]+)\)', line)
- if not r:
- # TODO: cleanup, if there are no problems,
- # we hit here
- continue
- result, name, case = r.groups()
- testname = tuple(case.split(".") + [name])
- results = {'SKIPPED': SKIPPED,
- 'EXPECTED FAILURE': SUCCESS,
- 'UNEXPECTED SUCCESS': WARNINGS,
- 'FAILURE': FAILURE,
- 'ERROR': FAILURE,
- 'SUCCESS': SUCCESS, # not reported
- }.get(result, WARNINGS)
- text = result.lower().split()
- loog = line
- # the next line is all dashes
- loog += pio.readline()
- else:
- # the rest goes into the log
- loog += line
- if testname:
- self.addTestResult(testname, results, text, loog)
- testname = None
-
- if warnings:
- lines = warnings.keys()
- lines.sort()
- self.addCompleteLog("warnings", "".join(lines))
-
- def evaluateCommand(self, cmd):
- return self.results
-
- def getText(self, cmd, results):
- return self.text
- def getText2(self, cmd, results):
- return self.text2
-
-
-class RemovePYCs(ShellCommand):
- name = "remove-.pyc"
- command = ['find', '.', '-name', '*.pyc', '-exec', 'rm', '{}', ';']
- description = ["removing", ".pyc", "files"]
- descriptionDone = ["remove", ".pycs"]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py
deleted file mode 100644
index b4695795..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py
+++ /dev/null
@@ -1,756 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import re
-import inspect
-from twisted.python import log, failure
-from twisted.spread import pb
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-from buildbot.process import buildstep
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot.status.logfile import STDOUT, STDERR
-from buildbot import config
-
-# for existing configurations that import WithProperties from here. We like
-# to move this class around just to keep our readers guessing.
-from buildbot.process.properties import WithProperties
-_hush_pyflakes = [WithProperties]
-del _hush_pyflakes
-
-class ShellCommand(buildstep.LoggingBuildStep):
- """I run a single shell command on the buildslave. I return FAILURE if
- the exit code of that command is non-zero, SUCCESS otherwise. To change
- this behavior, override my .evaluateCommand method, or customize
- decodeRC argument
-
- By default, a failure of this step will mark the whole build as FAILURE.
- To override this, give me an argument of flunkOnFailure=False .
-
- I create a single Log named 'log' which contains the output of the
- command. To create additional summary Logs, override my .createSummary
- method.
-
- The shell command I run (a list of argv strings) can be provided in
- several ways:
- - a class-level .command attribute
- - a command= parameter to my constructor (overrides .command)
- - set explicitly with my .setCommand() method (overrides both)
-
- @ivar command: a list of renderable objects (typically strings or
- WithProperties instances). This will be used by start()
- to create a RemoteShellCommand instance.
-
- @ivar logfiles: a dict mapping log NAMEs to workdir-relative FILENAMEs
- of their corresponding logfiles. The contents of the file
- named FILENAME will be put into a LogFile named NAME, ina
- something approximating real-time. (note that logfiles=
- is actually handled by our parent class LoggingBuildStep)
-
- @ivar lazylogfiles: Defaults to False. If True, logfiles will be tracked
- `lazily', meaning they will only be added when and if
- they are written to. Empty or nonexistent logfiles
- will be omitted. (Also handled by class
- LoggingBuildStep.)
- """
-
- name = "shell"
- renderables = buildstep.LoggingBuildStep.renderables + [
- 'slaveEnvironment', 'remote_kwargs', 'command',
- 'description', 'descriptionDone', 'descriptionSuffix']
-
- description = None # set this to a list of short strings to override
- descriptionDone = None # alternate description when the step is complete
- descriptionSuffix = None # extra information to append to suffix
-
- command = None # set this to a command, or set in kwargs
- # logfiles={} # you can also set 'logfiles' to a dictionary, and it
- # will be merged with any logfiles= argument passed in
- # to __init__
-
- # override this on a specific ShellCommand if you want to let it fail
- # without dooming the entire build to a status of FAILURE
- flunkOnFailure = True
-
- def __init__(self, workdir=None,
- description=None, descriptionDone=None, descriptionSuffix=None,
- command=None,
- usePTY="slave-config",
- **kwargs):
- # most of our arguments get passed through to the RemoteShellCommand
- # that we create, but first strip out the ones that we pass to
- # BuildStep (like haltOnFailure and friends), and a couple that we
- # consume ourselves.
-
- if description:
- self.description = description
- if isinstance(self.description, str):
- self.description = [self.description]
- if descriptionDone:
- self.descriptionDone = descriptionDone
- if isinstance(self.descriptionDone, str):
- self.descriptionDone = [self.descriptionDone]
-
- if descriptionSuffix:
- self.descriptionSuffix = descriptionSuffix
- if isinstance(self.descriptionSuffix, str):
- self.descriptionSuffix = [self.descriptionSuffix]
-
- if command:
- self.setCommand(command)
-
- # pull out the ones that LoggingBuildStep wants, then upcall
- buildstep_kwargs = {}
- for k in kwargs.keys()[:]:
- if k in self.__class__.parms:
- buildstep_kwargs[k] = kwargs[k]
- del kwargs[k]
- buildstep.LoggingBuildStep.__init__(self, **buildstep_kwargs)
-
- # check validity of arguments being passed to RemoteShellCommand
- invalid_args = []
- valid_rsc_args = inspect.getargspec(buildstep.RemoteShellCommand.__init__)[0]
- for arg in kwargs.keys():
- if arg not in valid_rsc_args:
- invalid_args.append(arg)
- # Raise Configuration error in case invalid arguments are present
- if invalid_args:
- config.error("Invalid argument(s) passed to RemoteShellCommand: "
- + ', '.join(invalid_args))
-
- # everything left over goes to the RemoteShellCommand
- kwargs['workdir'] = workdir # including a copy of 'workdir'
- kwargs['usePTY'] = usePTY
- self.remote_kwargs = kwargs
-
- def setBuild(self, build):
- buildstep.LoggingBuildStep.setBuild(self, build)
- # Set this here, so it gets rendered when we start the step
- self.slaveEnvironment = self.build.slaveEnvironment
-
- def setStepStatus(self, step_status):
- buildstep.LoggingBuildStep.setStepStatus(self, step_status)
-
- def setDefaultWorkdir(self, workdir):
- rkw = self.remote_kwargs
- rkw['workdir'] = rkw['workdir'] or workdir
-
- def getWorkdir(self):
- """
- Get the current notion of the workdir. Note that this may change
- between instantiation of the step and C{start}, as it is based on the
- build's default workdir, and may even be C{None} before that point.
- """
- return self.remote_kwargs['workdir']
-
- def setCommand(self, command):
- self.command = command
-
- def _flattenList(self, mainlist, commands):
- for x in commands:
- if isinstance(x, (list, tuple)):
- if x != []:
- self._flattenList(mainlist, x)
- else:
- mainlist.append(x)
-
- def describe(self, done=False):
- desc = self._describe(done)
- if self.descriptionSuffix:
- desc = desc[:]
- desc.extend(self.descriptionSuffix)
- return desc
-
- def _describe(self, done=False):
- """Return a list of short strings to describe this step, for the
- status display. This uses the first few words of the shell command.
- You can replace this by setting .description in your subclass, or by
- overriding this method to describe the step better.
-
- @type done: boolean
- @param done: whether the command is complete or not, to improve the
- way the command is described. C{done=False} is used
- while the command is still running, so a single
- imperfect-tense verb is appropriate ('compiling',
- 'testing', ...) C{done=True} is used when the command
- has finished, and the default getText() method adds some
- text, so a simple noun is appropriate ('compile',
- 'tests' ...)
- """
-
- try:
- if done and self.descriptionDone is not None:
- return self.descriptionDone
- if self.description is not None:
- return self.description
-
- # we may have no command if this is a step that sets its command
- # name late in the game (e.g., in start())
- if not self.command:
- return ["???"]
-
- words = self.command
- if isinstance(words, (str, unicode)):
- words = words.split()
-
- try:
- len(words)
- except AttributeError:
- # WithProperties and Property don't have __len__
- return ["???"]
-
- # flatten any nested lists
- tmp = []
- self._flattenList(tmp, words)
- words = tmp
-
- # strip instances and other detritus (which can happen if a
- # description is requested before rendering)
- words = [ w for w in words if isinstance(w, (str, unicode)) ]
-
- if len(words) < 1:
- return ["???"]
- if len(words) == 1:
- return ["'%s'" % words[0]]
- if len(words) == 2:
- return ["'%s" % words[0], "%s'" % words[1]]
- return ["'%s" % words[0], "%s" % words[1], "...'"]
-
- except:
- log.err(failure.Failure(), "Error describing step")
- return ["???"]
-
- def setupEnvironment(self, cmd):
- # merge in anything from Build.slaveEnvironment
- # This can be set from a Builder-level environment, or from earlier
- # BuildSteps. The latter method is deprecated and superceded by
- # BuildProperties.
- # Environment variables passed in by a BuildStep override
- # those passed in at the Builder level.
- slaveEnv = self.slaveEnvironment
- if slaveEnv:
- if cmd.args['env'] is None:
- cmd.args['env'] = {}
- fullSlaveEnv = slaveEnv.copy()
- fullSlaveEnv.update(cmd.args['env'])
- cmd.args['env'] = fullSlaveEnv
- # note that each RemoteShellCommand gets its own copy of the
- # dictionary, so we shouldn't be affecting anyone but ourselves.
-
- def buildCommandKwargs(self, warnings):
- kwargs = buildstep.LoggingBuildStep.buildCommandKwargs(self)
- kwargs.update(self.remote_kwargs)
- tmp = []
- if isinstance(self.command, list):
- self._flattenList(tmp, self.command)
- else:
- tmp = self.command
-
- kwargs['command'] = tmp
-
- # check for the usePTY flag
- if kwargs.has_key('usePTY') and kwargs['usePTY'] != 'slave-config':
- if self.slaveVersionIsOlderThan("svn", "2.7"):
- warnings.append("NOTE: slave does not allow master to override usePTY\n")
- del kwargs['usePTY']
-
- # check for the interruptSignal flag
- if kwargs.has_key('interruptSignal') and self.slaveVersionIsOlderThan("shell", "2.15"):
- warnings.append("NOTE: slave does not allow master to specify interruptSignal\n")
- del kwargs['interruptSignal']
-
- return kwargs
-
- def start(self):
- # this block is specific to ShellCommands. subclasses that don't need
- # to set up an argv array, an environment, or extra logfiles= (like
- # the Source subclasses) can just skip straight to startCommand()
-
- warnings = []
-
- # create the actual RemoteShellCommand instance now
- kwargs = self.buildCommandKwargs(warnings)
- cmd = buildstep.RemoteShellCommand(**kwargs)
- self.setupEnvironment(cmd)
-
- self.startCommand(cmd, warnings)
-
-
-
-class TreeSize(ShellCommand):
- name = "treesize"
- command = ["du", "-s", "-k", "."]
- description = "measuring tree size"
- descriptionDone = "tree size measured"
- kib = None
-
- def commandComplete(self, cmd):
- out = cmd.logs['stdio'].getText()
- m = re.search(r'^(\d+)', out)
- if m:
- self.kib = int(m.group(1))
- self.setProperty("tree-size-KiB", self.kib, "treesize")
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- if self.kib is None:
- return WARNINGS # not sure how 'du' could fail, but whatever
- return SUCCESS
-
- def getText(self, cmd, results):
- if self.kib is not None:
- return ["treesize", "%d KiB" % self.kib]
- return ["treesize", "unknown"]
-
-class SetPropertyFromCommand(ShellCommand):
- name = "setproperty"
- renderables = [ 'property' ]
-
- def __init__(self, property=None, extract_fn=None, strip=True, **kwargs):
- self.property = property
- self.extract_fn = extract_fn
- self.strip = strip
-
- if not ((property is not None) ^ (extract_fn is not None)):
- config.error(
- "Exactly one of property and extract_fn must be set")
-
- ShellCommand.__init__(self, **kwargs)
-
- self.property_changes = {}
-
- def commandComplete(self, cmd):
- if self.property:
- if cmd.didFail():
- return
- result = cmd.logs['stdio'].getText()
- if self.strip: result = result.strip()
- propname = self.property
- self.setProperty(propname, result, "SetProperty Step")
- self.property_changes[propname] = result
- else:
- log = cmd.logs['stdio']
- new_props = self.extract_fn(cmd.rc,
- ''.join(log.getChunks([STDOUT], onlyText=True)),
- ''.join(log.getChunks([STDERR], onlyText=True)))
- for k,v in new_props.items():
- self.setProperty(k, v, "SetProperty Step")
- self.property_changes = new_props
-
- def createSummary(self, log):
- if self.property_changes:
- props_set = [ "%s: %r" % (k,v)
- for k,v in self.property_changes.items() ]
- self.addCompleteLog('property changes', "\n".join(props_set))
-
- def getText(self, cmd, results):
- if len(self.property_changes) > 1:
- return [ "%d properties set" % len(self.property_changes) ]
- elif len(self.property_changes) == 1:
- return [ "property '%s' set" % self.property_changes.keys()[0] ]
- else:
- # let ShellCommand describe
- return ShellCommand.getText(self, cmd, results)
-
-
-SetProperty = SetPropertyFromCommand
-deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
- "It has been renamed to SetPropertyFromCommand",
- "buildbot.steps.shell", "SetProperty")
-
-
-class Configure(ShellCommand):
-
- name = "configure"
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["configuring"]
- descriptionDone = ["configure"]
- command = ["./configure"]
-
-class StringFileWriter(pb.Referenceable):
- """
- FileWriter class that just puts received data into a buffer.
-
- Used to upload a file from slave for inline processing rather than
- writing into a file on master.
- """
- def __init__(self):
- self.buffer = ""
-
- def remote_write(self, data):
- self.buffer += data
-
- def remote_close(self):
- pass
-
-class WarningCountingShellCommand(ShellCommand):
- renderables = [ 'suppressionFile' ]
-
- warnCount = 0
- warningPattern = '.*warning[: ].*'
- # The defaults work for GNU Make.
- directoryEnterPattern = (u"make.*: Entering directory "
- u"[\u2019\"`'](.*)[\u2019'`\"]")
- directoryLeavePattern = "make.*: Leaving directory"
- suppressionFile = None
-
- commentEmptyLineRe = re.compile(r"^\s*(\#.*)?$")
- suppressionLineRe = re.compile(r"^\s*(.+?)\s*:\s*(.+?)\s*(?:[:]\s*([0-9]+)(?:-([0-9]+))?\s*)?$")
-
- def __init__(self,
- warningPattern=None, warningExtractor=None, maxWarnCount=None,
- directoryEnterPattern=None, directoryLeavePattern=None,
- suppressionFile=None, **kwargs):
- # See if we've been given a regular expression to use to match
- # warnings. If not, use a default that assumes any line with "warning"
- # present is a warning. This may lead to false positives in some cases.
- if warningPattern:
- self.warningPattern = warningPattern
- if directoryEnterPattern:
- self.directoryEnterPattern = directoryEnterPattern
- if directoryLeavePattern:
- self.directoryLeavePattern = directoryLeavePattern
- if suppressionFile:
- self.suppressionFile = suppressionFile
- if warningExtractor:
- self.warningExtractor = warningExtractor
- else:
- self.warningExtractor = WarningCountingShellCommand.warnExtractWholeLine
- self.maxWarnCount = maxWarnCount
-
- # And upcall to let the base class do its work
- ShellCommand.__init__(self, **kwargs)
-
- self.suppressions = []
- self.directoryStack = []
-
- def addSuppression(self, suppressionList):
- """
- This method can be used to add patters of warnings that should
- not be counted.
-
- It takes a single argument, a list of patterns.
-
- Each pattern is a 4-tuple (FILE-RE, WARN-RE, START, END).
-
- FILE-RE is a regular expression (string or compiled regexp), or None.
- If None, the pattern matches all files, else only files matching the
- regexp. If directoryEnterPattern is specified in the class constructor,
- matching is against the full path name, eg. src/main.c.
-
- WARN-RE is similarly a regular expression matched against the
- text of the warning, or None to match all warnings.
-
- START and END form an inclusive line number range to match against. If
- START is None, there is no lower bound, similarly if END is none there
- is no upper bound."""
-
- for fileRe, warnRe, start, end in suppressionList:
- if fileRe != None and isinstance(fileRe, basestring):
- fileRe = re.compile(fileRe)
- if warnRe != None and isinstance(warnRe, basestring):
- warnRe = re.compile(warnRe)
- self.suppressions.append((fileRe, warnRe, start, end))
-
- def warnExtractWholeLine(self, line, match):
- """
- Extract warning text as the whole line.
- No file names or line numbers."""
- return (None, None, line)
-
- def warnExtractFromRegexpGroups(self, line, match):
- """
- Extract file name, line number, and warning text as groups (1,2,3)
- of warningPattern match."""
- file = match.group(1)
- lineNo = match.group(2)
- if lineNo != None:
- lineNo = int(lineNo)
- text = match.group(3)
- return (file, lineNo, text)
-
- def maybeAddWarning(self, warnings, line, match):
- if self.suppressions:
- (file, lineNo, text) = self.warningExtractor(self, line, match)
- lineNo = lineNo and int(lineNo)
-
- if file != None and file != "" and self.directoryStack:
- currentDirectory = '/'.join(self.directoryStack)
- if currentDirectory != None and currentDirectory != "":
- file = "%s/%s" % (currentDirectory, file)
-
- # Skip adding the warning if any suppression matches.
- for fileRe, warnRe, start, end in self.suppressions:
- if not (file == None or fileRe == None or fileRe.match(file)):
- continue
- if not (warnRe == None or warnRe.search(text)):
- continue
- if not ((start == None and end == None) or
- (lineNo != None and start <= lineNo and end >= lineNo)):
- continue
- return
-
- warnings.append(line)
- self.warnCount += 1
-
- def start(self):
- if self.suppressionFile == None:
- return ShellCommand.start(self)
-
- self.myFileWriter = StringFileWriter()
-
- args = {
- 'slavesrc': self.suppressionFile,
- 'workdir': self.getWorkdir(),
- 'writer': self.myFileWriter,
- 'maxsize': None,
- 'blocksize': 32*1024,
- }
- cmd = buildstep.RemoteCommand('uploadFile', args, ignore_updates=True)
- d = self.runCommand(cmd)
- d.addCallback(self.uploadDone)
- d.addErrback(self.failed)
-
- def uploadDone(self, dummy):
- lines = self.myFileWriter.buffer.split("\n")
- del(self.myFileWriter)
-
- list = []
- for line in lines:
- if self.commentEmptyLineRe.match(line):
- continue
- match = self.suppressionLineRe.match(line)
- if (match):
- file, test, start, end = match.groups()
- if (end != None):
- end = int(end)
- if (start != None):
- start = int(start)
- if end == None:
- end = start
- list.append((file, test, start, end))
-
- self.addSuppression(list)
- return ShellCommand.start(self)
-
- def createSummary(self, log):
- """
- Match log lines against warningPattern.
-
- Warnings are collected into another log for this step, and the
- build-wide 'warnings-count' is updated."""
-
- self.warnCount = 0
-
- # Now compile a regular expression from whichever warning pattern we're
- # using
- wre = self.warningPattern
- if isinstance(wre, str):
- wre = re.compile(wre)
-
- directoryEnterRe = self.directoryEnterPattern
- if (directoryEnterRe != None
- and isinstance(directoryEnterRe, basestring)):
- directoryEnterRe = re.compile(directoryEnterRe)
-
- directoryLeaveRe = self.directoryLeavePattern
- if (directoryLeaveRe != None
- and isinstance(directoryLeaveRe, basestring)):
- directoryLeaveRe = re.compile(directoryLeaveRe)
-
- # Check if each line in the output from this command matched our
- # warnings regular expressions. If did, bump the warnings count and
- # add the line to the collection of lines with warnings
- warnings = []
- # TODO: use log.readlines(), except we need to decide about stdout vs
- # stderr
- for line in log.getText().split("\n"):
- if directoryEnterRe:
- match = directoryEnterRe.search(line)
- if match:
- self.directoryStack.append(match.group(1))
- continue
- if (directoryLeaveRe and
- self.directoryStack and
- directoryLeaveRe.search(line)):
- self.directoryStack.pop()
- continue
-
- match = wre.match(line)
- if match:
- self.maybeAddWarning(warnings, line, match)
-
- # If there were any warnings, make the log if lines with warnings
- # available
- if self.warnCount:
- self.addCompleteLog("warnings (%d)" % self.warnCount,
- "\n".join(warnings) + "\n")
-
- warnings_stat = self.step_status.getStatistic('warnings', 0)
- self.step_status.setStatistic('warnings', warnings_stat + self.warnCount)
-
- old_count = self.getProperty("warnings-count", 0)
- self.setProperty("warnings-count", old_count + self.warnCount, "WarningCountingShellCommand")
-
-
- def evaluateCommand(self, cmd):
- if ( cmd.didFail() or
- ( self.maxWarnCount != None and self.warnCount > self.maxWarnCount ) ):
- return FAILURE
- if self.warnCount:
- return WARNINGS
- return SUCCESS
-
-
-class Compile(WarningCountingShellCommand):
-
- name = "compile"
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["compiling"]
- descriptionDone = ["compile"]
- command = ["make", "all"]
-
-class Test(WarningCountingShellCommand):
-
- name = "test"
- warnOnFailure = 1
- description = ["testing"]
- descriptionDone = ["test"]
- command = ["make", "test"]
-
- def setTestResults(self, total=0, failed=0, passed=0, warnings=0):
- """
- Called by subclasses to set the relevant statistics; this actually
- adds to any statistics already present
- """
- total += self.step_status.getStatistic('tests-total', 0)
- self.step_status.setStatistic('tests-total', total)
- failed += self.step_status.getStatistic('tests-failed', 0)
- self.step_status.setStatistic('tests-failed', failed)
- warnings += self.step_status.getStatistic('tests-warnings', 0)
- self.step_status.setStatistic('tests-warnings', warnings)
- passed += self.step_status.getStatistic('tests-passed', 0)
- self.step_status.setStatistic('tests-passed', passed)
-
- def describe(self, done=False):
- description = WarningCountingShellCommand.describe(self, done)
- if done:
- description = description[:] # make a private copy
- if self.step_status.hasStatistic('tests-total'):
- total = self.step_status.getStatistic("tests-total", 0)
- failed = self.step_status.getStatistic("tests-failed", 0)
- passed = self.step_status.getStatistic("tests-passed", 0)
- warnings = self.step_status.getStatistic("tests-warnings", 0)
- if not total:
- total = failed + passed + warnings
-
- if total:
- description.append('%d tests' % total)
- if passed:
- description.append('%d passed' % passed)
- if warnings:
- description.append('%d warnings' % warnings)
- if failed:
- description.append('%d failed' % failed)
- return description
-
-class PerlModuleTest(Test):
- command=["prove", "--lib", "lib", "-r", "t"]
- total = 0
-
- def evaluateCommand(self, cmd):
- # Get stdio, stripping pesky newlines etc.
- lines = map(
- lambda line : line.replace('\r\n','').replace('\r','').replace('\n',''),
- self.getLog('stdio').readlines()
- )
-
- total = 0
- passed = 0
- failed = 0
- rc = SUCCESS
- if cmd.didFail():
- rc = FAILURE
-
- # New version of Test::Harness?
- if "Test Summary Report" in lines:
- test_summary_report_index = lines.index("Test Summary Report")
- del lines[0:test_summary_report_index + 2]
-
- re_test_result = re.compile("^Result: (PASS|FAIL)$|Tests: \d+ Failed: (\d+)\)|Files=\d+, Tests=(\d+)")
-
- mos = map(lambda line: re_test_result.search(line), lines)
- test_result_lines = [mo.groups() for mo in mos if mo]
-
- for line in test_result_lines:
- if line[0] == 'FAIL':
- rc = FAILURE
-
- if line[1]:
- failed += int(line[1])
- if line[2]:
- total = int(line[2])
-
- else: # Nope, it's the old version
- re_test_result = re.compile("^(All tests successful)|(\d+)/(\d+) subtests failed|Files=\d+, Tests=(\d+),")
-
- mos = map(lambda line: re_test_result.search(line), lines)
- test_result_lines = [mo.groups() for mo in mos if mo]
-
- if test_result_lines:
- test_result_line = test_result_lines[0]
-
- success = test_result_line[0]
-
- if success:
- failed = 0
-
- test_totals_line = test_result_lines[1]
- total_str = test_totals_line[3]
- else:
- failed_str = test_result_line[1]
- failed = int(failed_str)
-
- total_str = test_result_line[2]
-
- rc = FAILURE
-
- total = int(total_str)
-
- warnings = 0
- if self.warningPattern:
- wre = self.warningPattern
- if isinstance(wre, str):
- wre = re.compile(wre)
-
- warnings = len([l for l in lines if wre.search(l)])
-
- # Because there are two paths that are used to determine
- # the success/fail result, I have to modify it here if
- # there were warnings.
- if rc == SUCCESS and warnings:
- rc = WARNINGS
-
- if total:
- passed = total - failed
-
- self.setTestResults(total=total, failed=failed, passed=passed,
- warnings=warnings)
-
- return rc
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py
deleted file mode 100644
index 3b5a20f6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import stat
-from twisted.internet import defer
-from buildbot.process import buildstep
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class SlaveBuildStep(buildstep.BuildStep):
- def describe(self, done=False):
- return self.descriptionDone if done else self.description
-
-class SetPropertiesFromEnv(SlaveBuildStep):
- """
- Sets properties from envirionment variables on the slave.
-
- Note this is transfered when the slave first connects
- """
- name='SetPropertiesFromEnv'
- description=['Setting']
- descriptionDone=['Set']
-
- def __init__(self, variables, source="SlaveEnvironment", **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.variables = variables
- self.source = source
-
- def start(self):
- # on Windows, environment variables are case-insensitive, but we have
- # a case-sensitive dictionary in slave_environ. Fortunately, that
- # dictionary is also folded to uppercase, so we can simply fold the
- # variable names to uppercase to duplicate the case-insensitivity.
- fold_to_uppercase = (self.buildslave.slave_system == 'win32')
-
- properties = self.build.getProperties()
- environ = self.buildslave.slave_environ
- variables = self.variables
- log = []
- if isinstance(variables, str):
- variables = [self.variables]
- for variable in variables:
- key = variable
- if fold_to_uppercase:
- key = variable.upper()
- value = environ.get(key, None)
- if value:
- # note that the property is not uppercased
- properties.setProperty(variable, value, self.source,
- runtime=True)
- log.append("%s = %r" % (variable, value))
- self.addCompleteLog("properties", "\n".join(log))
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-class FileExists(SlaveBuildStep):
- """
- Check for the existence of a file on the slave.
- """
- name='FileExists'
- description='Checking'
- descriptionDone='Checked'
-
- renderables = [ 'file' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
-
- def __init__(self, file, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.file = file
-
- def start(self):
- slavever = self.slaveVersion('stat')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about stat")
- cmd = buildstep.RemoteCommand('stat', {'file': self.file })
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["File not found."])
- self.finished(FAILURE)
- return
- s = cmd.updates["stat"][-1]
- if stat.S_ISREG(s[stat.ST_MODE]):
- self.step_status.setText(["File found."])
- self.finished(SUCCESS)
- else:
- self.step_status.setText(["Not a file."])
- self.finished(FAILURE)
-
-class CopyDirectory(SlaveBuildStep):
- """
- Copy a directory tree on the slave.
- """
- name='CopyDirectory'
- description=['Copying']
- descriptionDone=['Copied']
-
- renderables = [ 'src', 'dest' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, src, dest, timeout=None, maxTime=None, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.src = src
- self.dest = dest
- self.timeout = timeout
- self.maxTime = maxTime
-
- def start(self):
- slavever = self.slaveVersion('cpdir')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about cpdir")
-
- args = {'fromdir': self.src, 'todir': self.dest }
- if self.timeout:
- args['timeout'] = self.timeout
- if self.maxTime:
- args['maxTime'] = self.maxTime
-
- cmd = buildstep.RemoteCommand('cpdir', args)
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["Copying", self.src, "to", self.dest, "failed."])
- self.finished(FAILURE)
- return
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
- def describe(self, done=False):
- desc = self.descriptionDone if done else self.description
- desc = desc[:]
- desc.extend([self.src, "to", self.dest])
- return desc
-
-class RemoveDirectory(SlaveBuildStep):
- """
- Remove a directory tree on the slave.
- """
- name='RemoveDirectory'
- description=['Deleting']
- descriptionDone=['Deleted']
-
- renderables = [ 'dir' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, dir, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.dir = dir
-
- def start(self):
- slavever = self.slaveVersion('rmdir')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about rmdir")
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.dir })
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["Delete failed."])
- self.finished(FAILURE)
- return
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-class MakeDirectory(SlaveBuildStep):
- """
- Create a directory on the slave.
- """
- name='MakeDirectory'
- description=['Creating']
- descriptionDone=['Created']
-
- renderables = [ 'dir' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, dir, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.dir = dir
-
- def start(self):
- slavever = self.slaveVersion('mkdir')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about mkdir")
- cmd = buildstep.RemoteCommand('mkdir', {'dir': self.dir })
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["Create failed."])
- self.finished(FAILURE)
- return
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-class CompositeStepMixin():
- """I define utils for composite steps, factorizing basic remote commands"""
- def addLogForRemoteCommands(self, logname):
- """This method must be called by user classes
- composite steps could create several logs, this mixin functions will write
- to the last one.
- """
- self.rc_log = self.addLog(logname)
- return self.rc_log
-
- def runRemoteCommand(self, cmd, args, abandonOnFailure=True):
- """generic RemoteCommand boilerplate"""
- cmd = buildstep.RemoteCommand(cmd, args)
- cmd.useLog(self.rc_log, False)
- d = self.runCommand(cmd)
- def commandComplete(cmd):
- if abandonOnFailure and cmd.didFail():
- raise buildstep.BuildStepFailed()
- return cmd.didFail()
- d.addCallback(lambda res: commandComplete(cmd))
- return d
-
- def runRmdir(self, dir, **kwargs):
- """ remove a directory from the slave """
- return self.runRemoteCommand('rmdir',
- {'dir': dir, 'logEnviron': self.logEnviron },
- **kwargs)
-
- @defer.inlineCallbacks
- def pathExists(self, path):
- """ test whether path exists"""
- res = yield self.runRemoteCommand('stat', {'file': path,
- 'logEnviron': self.logEnviron,},
- abandonOnFailure=False)
- defer.returnValue(not res)
-
- def runMkdir(self, _dir, **kwargs):
- """ create a directory and its parents"""
- return self.runRemoteCommand('mkdir', {'dir': _dir,
- 'logEnviron': self.logEnviron,},
- **kwargs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py
deleted file mode 100644
index 57fa1107..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.steps.source.base import Source
-from buildbot.steps.source.oldsource import CVS, \
- SVN, Git, Darcs, Repo, Bzr, Mercurial, P4, Monotone, BK
-
-_hush_pyflakes = [ Source, CVS, SVN, \
- Git, Darcs, Repo, Bzr, Mercurial, P4, Monotone, BK ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py
deleted file mode 100644
index 13da81c3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.python import log
-from buildbot.process.buildstep import LoggingBuildStep
-from buildbot.status.builder import SKIPPED, FAILURE
-from buildbot.steps.slave import CompositeStepMixin
-
-class Source(LoggingBuildStep, CompositeStepMixin):
- """This is a base class to generate a source tree in the buildslave.
- Each version control system has a specialized subclass, and is expected
- to override __init__ and implement computeSourceRevision() and
- startVC(). The class as a whole builds up the self.args dictionary, then
- starts a RemoteCommand with those arguments.
- """
-
- renderables = LoggingBuildStep.renderables + [
- 'description', 'descriptionDone', 'descriptionSuffix',
- 'workdir' ]
-
- description = None # set this to a list of short strings to override
- descriptionDone = None # alternate description when the step is complete
- descriptionSuffix = None # extra information to append to suffix
-
- # if the checkout fails, there's no point in doing anything else
- haltOnFailure = True
- flunkOnFailure = True
- notReally = False
-
- branch = None # the default branch, should be set in __init__
-
- def __init__(self, workdir=None, mode='update', alwaysUseLatest=False,
- timeout=20*60, retry=None, env=None, logEnviron=True,
- description=None, descriptionDone=None, descriptionSuffix=None,
- codebase='', **kwargs):
- """
- @type workdir: string
- @param workdir: local directory (relative to the Builder's root)
- where the tree should be placed
-
- @type alwaysUseLatest: boolean
- @param alwaysUseLatest: whether to always update to the most
- recent available sources for this build.
-
- Normally the Source step asks its Build for a list of all
- Changes that are supposed to go into the build, then computes a
- 'source stamp' (revision number or timestamp) that will cause
- exactly that set of changes to be present in the checked out
- tree. This is turned into, e.g., 'cvs update -D timestamp', or
- 'svn update -r revnum'. If alwaysUseLatest=True, bypass this
- computation and always update to the latest available sources
- for each build.
-
- The source stamp helps avoid a race condition in which someone
- commits a change after the master has decided to start a build
- but before the slave finishes checking out the sources. At best
- this results in a build which contains more changes than the
- buildmaster thinks it has (possibly resulting in the wrong
- person taking the blame for any problems that result), at worst
- is can result in an incoherent set of sources (splitting a
- non-atomic commit) which may not build at all.
-
- @type logEnviron: boolean
- @param logEnviron: If this option is true (the default), then the
- step's logfile will describe the environment
- variables on the slave. In situations where the
- environment is not relevant and is long, it may
- be easier to set logEnviron=False.
-
- @type codebase: string
- @param codebase: Specifies which changes in a build are processed by
- the step. The default codebase value is ''. The codebase must correspond
- to a codebase assigned by the codebaseGenerator. If no codebaseGenerator
- is defined in the master then codebase doesn't need to be set, the
- default value will then match all changes.
- """
-
- LoggingBuildStep.__init__(self, **kwargs)
-
- # This will get added to args later, after properties are rendered
- self.workdir = workdir
-
- self.sourcestamp = None
-
- self.codebase = codebase
- if self.codebase:
- self.name = ' '.join((self.name, self.codebase))
-
- self.alwaysUseLatest = alwaysUseLatest
-
- self.logEnviron = logEnviron
- self.env = env
- self.timeout = timeout
-
- descriptions_for_mode = {
- "clobber": "checkout",
- "export": "exporting"}
- descriptionDones_for_mode = {
- "clobber": "checkout",
- "export": "export"}
- if description:
- self.description = description
- else:
- self.description = [
- descriptions_for_mode.get(mode, "updating")]
- if isinstance(self.description, str):
- self.description = [self.description]
-
- if descriptionDone:
- self.descriptionDone = descriptionDone
- else:
- self.descriptionDone = [
- descriptionDones_for_mode.get(mode, "update")]
- if isinstance(self.descriptionDone, str):
- self.descriptionDone = [self.descriptionDone]
-
- if descriptionSuffix:
- self.descriptionSuffix = descriptionSuffix
- else:
- self.descriptionSuffix = self.codebase or None # want None in lieu of ''
- if isinstance(self.descriptionSuffix, str):
- self.descriptionSuffix = [self.descriptionSuffix]
-
- def updateSourceProperty(self, name, value, source=''):
- """
- Update a property, indexing the property by codebase if codebase is not
- ''. Source steps should generally use this instead of setProperty.
- """
- # pick a decent source name
- if source == '':
- source = self.__class__.__name__
-
- if self.codebase != '':
- assert not isinstance(self.getProperty(name, None), str), \
- "Sourcestep %s has a codebase, other sourcesteps don't" \
- % self.name
- property_dict = self.getProperty(name, {})
- property_dict[self.codebase] = value
- LoggingBuildStep.setProperty(self, name, property_dict, source)
- else:
- assert not isinstance(self.getProperty(name, None), dict), \
- "Sourcestep %s does not have a codebase, other sourcesteps do" \
- % self.name
- LoggingBuildStep.setProperty(self, name, value, source)
-
- def setStepStatus(self, step_status):
- LoggingBuildStep.setStepStatus(self, step_status)
-
- def setDefaultWorkdir(self, workdir):
- self.workdir = self.workdir or workdir
-
- def describe(self, done=False):
- desc = self.descriptionDone if done else self.description
- if self.descriptionSuffix:
- desc = desc[:]
- desc.extend(self.descriptionSuffix)
- return desc
-
- def computeSourceRevision(self, changes):
- """Each subclass must implement this method to do something more
- precise than -rHEAD every time. For version control systems that use
- repository-wide change numbers (SVN, P4), this can simply take the
- maximum such number from all the changes involved in this build. For
- systems that do not (CVS), it needs to create a timestamp based upon
- the latest Change, the Build's treeStableTimer, and an optional
- self.checkoutDelay value."""
- return None
-
- def start(self):
- if self.notReally:
- log.msg("faking %s checkout/update" % self.name)
- self.step_status.setText(["fake", self.name, "successful"])
- self.addCompleteLog("log",
- "Faked %s checkout/update 'successful'\n" \
- % self.name)
- return SKIPPED
-
- if not self.alwaysUseLatest:
- # what source stamp would this step like to use?
- s = self.build.getSourceStamp(self.codebase)
- self.sourcestamp = s
-
- if self.sourcestamp:
- # if branch is None, then use the Step's "default" branch
- branch = s.branch or self.branch
- # if revision is None, use the latest sources (-rHEAD)
- revision = s.revision
- if not revision:
- revision = self.computeSourceRevision(s.changes)
- # the revision property is currently None, so set it to something
- # more interesting
- if revision is not None:
- self.updateSourceProperty('revision', str(revision))
-
- # if patch is None, then do not patch the tree after checkout
-
- # 'patch' is None or a tuple of (patchlevel, diff, root)
- # root is optional.
- patch = s.patch
- if patch:
- self.addCompleteLog("patch", patch[1])
- else:
- log.msg("No sourcestamp found in build for codebase '%s'" % self.codebase)
- self.step_status.setText(["Codebase", '%s' % self.codebase ,"not", "in", "build" ])
- self.addCompleteLog("log",
- "No sourcestamp found in build for codebase '%s'" \
- % self.codebase)
- self.finished(FAILURE)
- return FAILURE
-
- else:
- revision = None
- branch = self.branch
- patch = None
-
- self.startVC(branch, revision, patch)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py
deleted file mode 100644
index a7deed93..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class Bzr(Source):
-
- name = 'bzr'
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, mode='incremental',
- method=None, defaultBranch=None, **kwargs):
-
- self.repourl = repourl
- self.baseURL = baseURL
- self.branch = defaultBranch
- self.mode = mode
- self.method = method
- Source.__init__(self, **kwargs)
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- if repourl is None and baseURL is None:
- raise ValueError("you must privide at least one of repourl and"
- " baseURL")
-
- if baseURL is not None and defaultBranch is None:
- raise ValueError("you must provide defaultBranch with baseURL")
-
- assert self.mode in ['incremental', 'full']
-
- if self.mode == 'full':
- assert self.method in ['clean', 'fresh', 'clobber', 'copy', None]
-
- def startVC(self, branch, revision, patch):
- if branch:
- self.branch = branch
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- if self.repourl is None:
- self.repourl = os.path.join(self.baseURL, self.branch)
-
- d = self.checkBzr()
- def checkInstall(bzrInstalled):
- if not bzrInstalled:
- raise BuildSlaveTooOldError("bzr is not installed on slave")
- return 0
-
- d.addCallback(checkInstall)
- if self.mode == 'full':
- d.addCallback(lambda _: self.full())
- elif self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- def incremental(self):
- d = self._sourcedirIsUpdatable()
- def _cmd(updatable):
- if updatable:
- command = ['update']
- else:
- command = ['checkout', self.repourl, '.']
-
- if self.revision:
- command.extend(['-r', self.revision])
- return command
-
- d.addCallback(_cmd)
- d.addCallback(self._dovccmd)
- return d
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method == 'copy':
- self.workdir = 'source'
- yield self.copy()
- return
-
- updatable = self._sourcedirIsUpdatable()
- if not updatable:
- log.msg("No bzr repo present, making full checkout")
- yield self._doFull()
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
-
- def clobber(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- d.addCallback(lambda _: self._doFull())
- return d
-
- def copy(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': 'build',
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- d.addCallback(lambda _: self.incremental())
- def copy(_):
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': 'source',
- 'todir':'build',
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- return d
- d.addCallback(copy)
- return d
-
- def clean(self):
- d = self._dovccmd(['clean-tree', '--ignored', '--force'])
- command = ['update']
- if self.revision:
- command.extend(['-r', self.revision])
- d.addCallback(lambda _: self._dovccmd(command))
- return d
-
- def fresh(self):
- d = self._dovccmd(['clean-tree', '--force'])
- command = ['update']
- if self.revision:
- command.extend(['-r', self.revision])
- d.addCallback(lambda _: self._dovccmd(command))
- return d
-
- def _doFull(self):
- command = ['checkout', self.repourl, '.']
- if self.revision:
- command.extend(['-r', self.revision])
- d = self._dovccmd(command)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- log.msg("Closing log, sending result of the command %s " % \
- (self.cmd))
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.bzr'))
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False):
- cmd = buildstep.RemoteShellCommand(self.workdir, ['bzr'] + command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def checkBzr(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def parseGotRevision(self, _):
- d = self._dovccmd(["version-info", "--custom", "--template='{revno}"],
- collectStdout=True)
- def setrev(stdout):
- revision = stdout.strip("'")
- try:
- int(revision)
- except ValueError:
- log.msg("Invalid revision number")
- raise buildstep.BuildStepFailed()
-
- log.msg("Got Git revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
- return 0
- d.addCallback(setrev)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py
deleted file mode 100644
index 3fbb40e4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from email.Utils import formatdate
-import time
-import re
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.shell import StringFileWriter
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class CVS(Source):
-
- name = "cvs"
-
- renderables = [ "cvsroot" ]
-
- def __init__(self, cvsroot=None, cvsmodule='', mode='incremental',
- method=None, branch=None, global_options=[], extra_options=[],
- login=None, **kwargs):
-
- self.cvsroot = cvsroot
- self.cvsmodule = cvsmodule
- self.branch = branch
- self.global_options = global_options
- self.extra_options = extra_options
- self.login = login
- self.mode = mode
- self.method = method
- self.srcdir = 'source'
- Source.__init__(self, **kwargs)
-
- def startVC(self, branch, revision, patch):
- self.branch = branch
- self.revision = revision
- self.stdio_log = self.addLog("stdio")
- self.method = self._getMethod()
- d = self.checkCvs()
- def checkInstall(cvsInstalled):
- if not cvsInstalled:
- raise BuildSlaveTooOldError("CVS is not installed on slave")
- return 0
- d.addCallback(checkInstall)
- d.addCallback(self.checkLogin)
-
- if self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
- elif self.mode == 'full':
- d.addCallback(lambda _: self.full())
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def incremental(self):
- updatable = yield self._sourcedirIsUpdatable()
- if updatable:
- rv = yield self.doUpdate()
- else:
- rv = yield self.clobber()
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- rv = yield self.clobber()
- defer.returnValue(rv)
- return
-
- elif self.method == 'copy':
- rv = yield self.copy()
- defer.returnValue(rv)
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- log.msg("CVS repo not present, making full checkout")
- rv = yield self.doCheckout(self.workdir)
- elif self.method == 'clean':
- rv = yield self.clean()
- elif self.method == 'fresh':
- rv = yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
- defer.returnValue(rv)
-
- def clobber(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- d.addCallback(lambda _: self.doCheckout(self.workdir))
- return d
-
- def fresh(self, ):
- d = self.purge(True)
- d.addCallback(lambda _: self.doUpdate())
- return d
-
- def clean(self, ):
- d = self.purge(False)
- d.addCallback(lambda _: self.doUpdate())
- return d
-
- def copy(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- self.workdir = 'source'
- d.addCallback(lambda _: self.incremental())
- def copy(_):
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': 'source',
- 'todir':'build',
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- return d
- d.addCallback(copy)
- def resetWorkdir(_):
- self.workdir = 'build'
- return 0
- d.addCallback(resetWorkdir)
- return d
-
- def purge(self, ignore_ignores):
- command = ['cvsdiscard']
- if ignore_ignores:
- command += ['--ignore']
- cmd = buildstep.RemoteShellCommand(self.workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluate(cmd):
- if cmd.didFail():
- raise buildstep.BuildStepFailed()
- return cmd.rc
- d.addCallback(evaluate)
- return d
-
- def doCheckout(self, dir):
- command = ['-d', self.cvsroot, '-z3', 'checkout', '-d', dir ]
- command = self.global_options + command + self.extra_options
- if self.branch:
- command += ['-r', self.branch]
- if self.revision:
- command += ['-D', self.revision]
- command += [ self.cvsmodule ]
- d = self._dovccmd(command, '')
- return d
-
- def doUpdate(self):
- command = ['-z3', 'update', '-dP']
- branch = self.branch
- # special case. 'cvs update -r HEAD -D today' gives no files; see #2351
- if branch == 'HEAD' and self.revision:
- branch = None
- if branch:
- command += ['-r', self.branch]
- if self.revision:
- command += ['-D', self.revision]
- d = self._dovccmd(command)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def checkLogin(self, _):
- if self.login:
- d = defer.succeed(0)
- else:
- d = self._dovccmd(['-d', self.cvsroot, 'login'])
- def setLogin(res):
- # this happens only if the login command succeeds.
- self.login = True
- return res
- d.addCallback(setLogin)
-
- return d
-
- def _dovccmd(self, command, workdir=None):
- if workdir is None:
- workdir = self.workdir
- if not command:
- raise ValueError("No command specified")
- cmd = buildstep.RemoteShellCommand(workdir, ['cvs'] +
- command,
- env=self.env,
- timeout=self.timeout,
- logEnviron=self.logEnviron)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.rc != 0:
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- @defer.inlineCallbacks
- def _sourcedirIsUpdatable(self):
- myFileWriter = StringFileWriter()
- args = {
- 'workdir': self.build.path_module.join(self.workdir, 'CVS'),
- 'writer': myFileWriter,
- 'maxsize': None,
- 'blocksize': 32*1024,
- }
-
- cmd = buildstep.RemoteCommand('uploadFile',
- dict(slavesrc='Root', **args),
- ignore_updates=True)
- yield self.runCommand(cmd)
- if cmd.rc is not None and cmd.rc != 0:
- defer.returnValue(False)
- return
-
- # on Windows, the cvsroot may not contain the password, so compare to
- # both
- cvsroot_without_pw = re.sub("(:pserver:[^:]*):[^@]*(@.*)",
- r"\1\2", self.cvsroot)
- if myFileWriter.buffer.strip() not in (self.cvsroot,
- cvsroot_without_pw):
- defer.returnValue(False)
- return
-
- myFileWriter.buffer = ""
- cmd = buildstep.RemoteCommand('uploadFile',
- dict(slavesrc='Repository', **args),
- ignore_updates=True)
- yield self.runCommand(cmd)
- if cmd.rc is not None and cmd.rc != 0:
- defer.returnValue(False)
- return
- if myFileWriter.buffer.strip() != self.cvsmodule:
- defer.returnValue(False)
- return
-
- defer.returnValue(True)
-
- def parseGotRevision(self, res):
- revision = time.strftime("%Y-%m-%d %H:%M:%S +0000", time.gmtime())
- self.updateSourceProperty('got_revision', revision)
- return res
-
- def checkCvs(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([c.when for c in changes])
- lastSubmit = max([br.submittedAt for br in self.build.requests])
- when = (lastChange + lastSubmit) / 2
- return formatdate(when)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py
deleted file mode 100644
index 21fcc8e5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py
+++ /dev/null
@@ -1,481 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot import config as bbconfig
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-def isTrueOrIsExactlyZero(v):
- # nonzero values are true...
- if v:
- return True
-
- # ... and True for the number zero, but we have to
- # explicitly guard against v==False, since
- # isinstance(False, int) is surprisingly True
- if isinstance(v, int) and v is not False:
- return True
-
- # all other false-ish values are false
- return False
-
-git_describe_flags = [
- # on or off
- ('all', lambda v: ['--all'] if v else None),
- ('always', lambda v: ['--always'] if v else None),
- ('contains', lambda v: ['--contains'] if v else None),
- ('debug', lambda v: ['--debug'] if v else None),
- ('long', lambda v: ['--long'] if v else None),
- ('exact-match', lambda v: ['--exact-match'] if v else None),
- ('tags', lambda v: ['--tags'] if v else None),
- # string parameter
- ('match', lambda v: ['--match', v] if v else None),
- # numeric parameter
- ('abbrev', lambda v: ['--abbrev=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- ('candidates', lambda v: ['--candidates=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- # optional string parameter
- ('dirty', lambda v: ['--dirty'] if (v is True or v=='') else None),
- ('dirty', lambda v: ['--dirty=%s' % v] if (v and v is not True) else None),
-]
-
-class Git(Source):
- """ Class for Git with all the smarts """
- name='git'
- renderables = [ "repourl"]
-
- def __init__(self, repourl=None, branch='HEAD', mode='incremental',
- method=None, submodules=False, shallow=False, progress=False,
- retryFetch=False, clobberOnFailure=False, getDescription=False,
- config=None, **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the git repository
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type submodules: boolean
- @param submodules: Whether or not to update (and initialize)
- git submodules.
-
- @type mode: string
- @param mode: Type of checkout. Described in docs.
-
- @type method: string
- @param method: Full builds can be done is different ways. This parameter
- specifies which method to use.
-
- @type progress: boolean
- @param progress: Pass the --progress option when fetching. This
- can solve long fetches getting killed due to
- lack of output, but requires Git 1.7.2+.
- @type shallow: boolean
- @param shallow: Use a shallow or clone, if possible
-
- @type retryFetch: boolean
- @param retryFetch: Retry fetching before failing source checkout.
-
- @type getDescription: boolean or dict
- @param getDescription: Use 'git describe' to describe the fetched revision
-
- @type config: dict
- @param config: Git configuration options to enable when running git
- """
- if not getDescription and not isinstance(getDescription, dict):
- getDescription = False
-
- self.branch = branch
- self.method = method
- self.prog = progress
- self.repourl = repourl
- self.retryFetch = retryFetch
- self.submodules = submodules
- self.shallow = shallow
- self.fetchcount = 0
- self.clobberOnFailure = clobberOnFailure
- self.mode = mode
- self.getDescription = getDescription
- self.config = config
- Source.__init__(self, **kwargs)
-
- if self.mode not in ['incremental', 'full']:
- bbconfig.error("Git: mode must be 'incremental' or 'full'.")
- if not self.repourl:
- bbconfig.error("Git: must provide repourl.")
- if (self.mode == 'full' and
- self.method not in ['clean', 'fresh', 'clobber', 'copy', None]):
- bbconfig.error("Git: invalid method for mode 'full'.")
- if self.shallow and (self.mode != 'full' or self.method != 'clobber'):
- bbconfig.error("Git: shallow only possible with mode 'full' and method 'clobber'.")
- if not isinstance(self.getDescription, (bool, dict)):
- bbconfig.error("Git: getDescription must be a boolean or a dict.")
-
- def startVC(self, branch, revision, patch):
- self.branch = branch or 'HEAD'
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkGit()
- def checkInstall(gitInstalled):
- if not gitInstalled:
- raise BuildSlaveTooOldError("git is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
- elif self.mode == 'full':
- d.addCallback(lambda _: self.full())
- if patch:
- d.addCallback(self.patch, patch)
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.parseCommitDescription)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method == 'copy':
- yield self.copy()
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- log.msg("No git repo present, making full clone")
- yield self._fullCloneOrFallback()
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
-
- @defer.inlineCallbacks
- def incremental(self):
- updatable = yield self._sourcedirIsUpdatable()
-
- # if not updateable, do a full checkout
- if not updatable:
- yield self._fullCloneOrFallback()
- return
-
- # test for existence of the revision; rc=1 indicates it does not exist
- if self.revision:
- rc = yield self._dovccmd(['cat-file', '-e', self.revision],
- abandonOnFailure=False)
- else:
- rc = 1
-
- # if revision exists checkout to that revision
- # else fetch and update
- if rc == 0:
- yield self._dovccmd(['reset', '--hard', self.revision, '--'])
-
- if self.branch != 'HEAD':
- yield self._dovccmd(['branch', '-M', self.branch],
- abandonOnFailure=False)
- else:
- yield self._fetchOrFallback(None)
-
- yield self._updateSubmodule(None)
-
- def clean(self):
- command = ['clean', '-f', '-d']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def clobber(self):
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone(shallowClone=self.shallow))
- return d
-
- def fresh(self):
- command = ['clean', '-f', '-d', '-x']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def copy(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- self.workdir = 'source'
- d.addCallback(lambda _: self.incremental())
- def copy(_):
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': 'source',
- 'todir':'build',
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- return d
- d.addCallback(copy)
- def resetWorkdir(_):
- self.workdir = 'build'
- return 0
-
- d.addCallback(resetWorkdir)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- log.msg("Closing log, sending result of the command %s " % \
- (self.cmd))
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _=None):
- stdout = yield self._dovccmd(['rev-parse', 'HEAD'], collectStdout=True)
- revision = stdout.strip()
- if len(revision) != 40:
- raise buildstep.BuildStepFailed()
- log.msg("Got Git revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
-
- defer.returnValue(0)
-
- @defer.inlineCallbacks
- def parseCommitDescription(self, _=None):
- if self.getDescription==False: # dict() should not return here
- defer.returnValue(0)
- return
-
- cmd = ['describe']
- if isinstance(self.getDescription, dict):
- for opt, arg in git_describe_flags:
- opt = self.getDescription.get(opt, None)
- arg = arg(opt)
- if arg:
- cmd.extend(arg)
- cmd.append('HEAD')
-
- try:
- stdout = yield self._dovccmd(cmd, collectStdout=True)
- desc = stdout.strip()
- self.updateSourceProperty('commit-description', desc)
- except:
- pass
-
- defer.returnValue(0)
-
- def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False, initialStdin=None):
- full_command = ['git']
- if self.config is not None:
- for name, value in self.config.iteritems():
- full_command.append('-c')
- full_command.append('%s=%s' % (name, value))
- full_command.extend(command)
- cmd = buildstep.RemoteShellCommand(self.workdir,
- full_command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting git command : git %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _fetch(self, _):
- command = ['fetch', '-t', self.repourl, self.branch]
- # If the 'progress' option is set, tell git fetch to output
- # progress information to the log. This can solve issues with
- # long fetches killed due to lack of output, but only works
- # with Git 1.7.2 or later.
- if self.prog:
- command.append('--progress')
-
- d = self._dovccmd(command)
- def checkout(_):
- if self.revision:
- rev = self.revision
- else:
- rev = 'FETCH_HEAD'
- command = ['reset', '--hard', rev, '--']
- abandonOnFailure = not self.retryFetch and not self.clobberOnFailure
- return self._dovccmd(command, abandonOnFailure)
- d.addCallback(checkout)
- def renameBranch(res):
- if res != 0:
- return res
- d = self._dovccmd(['branch', '-M', self.branch], abandonOnFailure=False)
- # Ignore errors
- d.addCallback(lambda _: res)
- return d
-
- if self.branch != 'HEAD':
- d.addCallback(renameBranch)
- return d
-
- @defer.inlineCallbacks
- def _fetchOrFallback(self, _):
- """
- Handles fallbacks for failure of fetch,
- wrapper for self._fetch
- """
- res = yield self._fetch(None)
- if res == 0:
- defer.returnValue(res)
- return
- elif self.retryFetch:
- yield self._fetch(None)
- elif self.clobberOnFailure:
- yield self._doClobber()
- yield self._fullClone()
- else:
- raise buildstep.BuildStepFailed()
-
- def _fullClone(self, shallowClone=False):
- """Perform full clone and checkout to the revision if specified
- In the case of shallow clones if any of the step fail abort whole build step.
- """
- args = []
- if self.branch != 'HEAD':
- args += ['--branch', self.branch]
- if shallowClone:
- args += ['--depth', '1']
- command = ['clone'] + args + [self.repourl, '.']
-
- #Fix references
- if self.prog:
- command.append('--progress')
-
- # If it's a shallow clone abort build step
- d = self._dovccmd(command, shallowClone)
- # If revision specified checkout that revision
- if self.revision:
- d.addCallback(lambda _: self._dovccmd(['reset', '--hard',
- self.revision, '--'],
- shallowClone))
- # init and update submodules, recurisively. If there's not recursion
- # it will not do it.
- if self.submodules:
- d.addCallback(lambda _: self._dovccmd(['submodule', 'update',
- '--init', '--recursive'],
- shallowClone))
- return d
-
- def _fullCloneOrFallback(self):
- """Wrapper for _fullClone(). In the case of failure, if clobberOnFailure
- is set to True remove the build directory and try a full clone again.
- """
-
- d = self._fullClone()
- def clobber(res):
- if res != 0:
- if self.clobberOnFailure:
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone())
- return d
- else:
- raise buildstep.BuildStepFailed()
- else:
- return res
- d.addCallback(clobber)
- return d
-
- def _doClobber(self):
- """Remove the work directory"""
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.git'))
-
- def _updateSubmodule(self, _):
- if self.submodules:
- return self._dovccmd(['submodule', 'update', '--recursive'])
- else:
- return defer.succeed(0)
-
- def _cleanSubmodule(self, _):
- if self.submodules:
- command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
- if self.mode == 'full' and self.method == 'fresh':
- command.append('-x')
- return self._dovccmd(command)
- else:
- return defer.succeed(0)
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def checkGit(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def patch(self, _, patch):
- d = self._dovccmd(['apply', '--index', '-p', str(patch[0])],
- initialStdin=patch[1])
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py
deleted file mode 100644
index cbf872b1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py
+++ /dev/null
@@ -1,338 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-## Source step code for mercurial
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.config import ConfigErrors
-from buildbot.status.results import SUCCESS
-
-class Mercurial(Source):
- """ Class for Mercurial with all the smarts """
- name = "hg"
-
- renderables = [ "repourl" ]
- possible_modes = ('incremental', 'full')
- possible_methods = (None, 'clean', 'fresh', 'clobber')
- possible_branchTypes = ('inrepo', 'dirname')
-
- def __init__(self, repourl=None, mode='incremental',
- method=None, defaultBranch=None, branchType='dirname',
- clobberOnBranchChange=True, **kwargs):
-
- """
- @type repourl: string
- @param repourl: the URL which points at the Mercurial repository.
- if 'dirname' branches are enabled, this is the base URL
- to which a branch name will be appended. It should
- probably end in a slash.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly.
- For 'dirname' branches, It will simply be
- appended to C{repourl} and the result handed to
- the 'hg update' command.
- For 'inrepo' branches, this specifies the named
- revision to which the tree will update after a
- clone.
-
- @param branchType: either 'dirname' or 'inrepo' depending on whether
- the branch name should be appended to the C{repourl}
- or the branch is a mercurial named branch and can be
- found within the C{repourl}
-
- @param clobberOnBranchChange: boolean, defaults to True. If set and
- using inrepos branches, clobber the tree
- at each branch change. Otherwise, just
- update to the branch.
- """
-
- self.repourl = repourl
- self.defaultBranch = self.branch = defaultBranch
- self.branchType = branchType
- self.method = method
- self.clobberOnBranchChange = clobberOnBranchChange
- self.mode = mode
- Source.__init__(self, **kwargs)
-
- errors = []
- if self.mode not in self.possible_modes:
- errors.append("mode %s is not one of %s" %
- (self.mode, self.possible_modes))
- if self.method not in self.possible_methods:
- errors.append("method %s is not one of %s" %
- (self.method, self.possible_methods))
- if self.branchType not in self.possible_branchTypes:
- errors.append("branchType %s is not one of %s" %
- (self.branchType, self.possible_branchTypes))
-
- if repourl is None:
- errors.append("you must provide a repourl")
-
- if errors:
- raise ConfigErrors(errors)
-
- def startVC(self, branch, revision, patch):
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
- d = self.checkHg()
- def checkInstall(hgInstalled):
- if not hgInstalled:
- raise BuildSlaveTooOldError("Mercurial is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.branchType == 'dirname':
- self.repourl = self.repourl + (branch or '')
- self.branch = self.defaultBranch
- self.update_branch = branch
- elif self.branchType == 'inrepo':
- self.update_branch = (branch or 'default')
-
- if self.mode == 'full':
- d.addCallback(lambda _: self.full())
- elif self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
-
- if patch:
- d.addCallback(self.patch, patch)
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- yield self.clobber(None)
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- yield self._dovccmd(['clone', self.repourl, '.'])
- elif self.method == 'clean':
- yield self.clean(None)
- elif self.method == 'fresh':
- yield self.fresh(None)
- else:
- raise ValueError("Unknown method, check your configuration")
-
- def incremental(self):
- if self.method is not None:
- raise ValueError(self.method)
-
- d = self._sourcedirIsUpdatable()
- def _cmd(updatable):
- if updatable:
- command = ['pull', self.repourl]
- else:
- command = ['clone', self.repourl, '.', '--noupdate']
- return command
-
- d.addCallback(_cmd)
- d.addCallback(self._dovccmd)
- d.addCallback(self._checkBranchChange)
- return d
-
- def clean(self, _):
- command = ['--config', 'extensions.purge=', 'purge']
- d = self._dovccmd(command)
- d.addCallback(self._pullUpdate)
- return d
-
- def clobber(self, _):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron':self.logEnviron})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- d.addCallback(lambda _: self._dovccmd(['clone', '--noupdate'
- , self.repourl, "."]))
- d.addCallback(self._update)
- return d
-
- def fresh(self, _):
- command = ['--config', 'extensions.purge=', 'purge', '--all']
- d = self._dovccmd(command)
- d.addCallback(self._pullUpdate)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def parseGotRevision(self, _):
- d = self._dovccmd(['parents', '--template', '{node}\\n'], collectStdout=True)
- def _setrev(stdout):
- revision = stdout.strip()
- if len(revision) != 40:
- raise ValueError("Incorrect revision id")
- log.msg("Got Mercurial revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
- return 0
- d.addCallback(_setrev)
- return d
-
- @defer.inlineCallbacks
- def _checkBranchChange(self, _):
- current_branch = yield self._getCurrentBranch()
- msg = "Working dir is on in-repo branch '%s' and build needs '%s'." % \
- (current_branch, self.update_branch)
- if current_branch != self.update_branch and self.clobberOnBranchChange:
- msg += ' Clobbering.'
- log.msg(msg)
- yield self.clobber(None)
- return
- msg += ' Updating.'
- log.msg(msg)
- yield self._removeAddedFilesAndUpdate(None)
-
- def _pullUpdate(self, res):
- command = ['pull' , self.repourl]
- if self.revision:
- command.extend(['--rev', self.revision])
- d = self._dovccmd(command)
- d.addCallback(self._checkBranchChange)
- return d
-
- def _dovccmd(self, command, collectStdout=False, initialStdin=None, decodeRC={0:SUCCESS}):
- if not command:
- raise ValueError("No command specified")
- cmd = buildstep.RemoteShellCommand(self.workdir, ['hg', '--verbose'] + command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin,
- decodeRC=decodeRC)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting mercurial command : hg %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- # without knowing the revision ancestry graph, we can't sort the
- # changes at all. So for now, assume they were given to us in sorted
- # order, and just pay attention to the last one. See ticket #103 for
- # more details.
- if len(changes) > 1:
- log.msg("Mercurial.computeSourceRevision: warning: "
- "there are %d changes here, assuming the last one is "
- "the most recent" % len(changes))
- return changes[-1].revision
-
- def patch(self, _, patch):
- d = self._dovccmd(['import', '--no-commit', '-p', str(patch[0]), '-'],
- initialStdin=patch[1])
- return d
-
- def _getCurrentBranch(self):
- if self.branchType == 'dirname':
- return defer.succeed(self.branch)
- else:
- d = self._dovccmd(['identify', '--branch'], collectStdout=True)
- def _getbranch(stdout):
- return stdout.strip()
- d.addCallback(_getbranch).addErrback
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.hg'))
-
- def _removeAddedFilesAndUpdate(self, _):
- command = ['locate', 'set:added()']
- d = self._dovccmd(command, collectStdout=True, decodeRC={0:SUCCESS,1:SUCCESS})
- def parseAndRemove(stdout):
- files = []
- for filename in stdout.splitlines() :
- filename = self.workdir+'/'+filename
- files.append(filename)
- if len(files) == 0:
- d = defer.succeed(0)
- else:
- if self.slaveVersionIsOlderThan('rmdir', '2.14'):
- d = self.removeFiles(files)
- else:
- cmd = buildstep.RemoteCommand('rmdir', {'dir': files,
- 'logEnviron':
- self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- d.addCallback(lambda _: cmd.rc)
- return d
- d.addCallback(parseAndRemove)
- d.addCallback(self._update)
- return d
-
- @defer.inlineCallbacks
- def removeFiles(self, files):
- for filename in files:
- cmd = buildstep.RemoteCommand('rmdir', {'dir': filename,
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- yield self.runCommand(cmd)
- if cmd.rc != 0:
- defer.returnValue(cmd.rc)
- return
- defer.returnValue(0)
-
- def _update(self, _):
- command = ['update', '--clean']
- if self.revision:
- command += ['--rev', self.revision]
- elif self.branchType == 'inrepo':
- command += ['--rev', self.update_branch]
- d = self._dovccmd(command)
- return d
-
- def checkHg(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py
deleted file mode 100644
index 4bfe645f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py
+++ /dev/null
@@ -1,1173 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from warnings import warn
-from email.Utils import formatdate
-from twisted.python import log
-from twisted.internet import defer
-from zope.interface import implements
-from buildbot.process.buildstep import RemoteCommand
-from buildbot.interfaces import BuildSlaveTooOldError, IRenderable
-from buildbot.steps.source.base import Source
-
-class _ComputeRepositoryURL(object):
- implements(IRenderable)
-
- def __init__(self, step, repository):
- self.step = step
- self.repository = repository
-
- def getRenderingFor(self, props):
- '''
- Helper function that the repository URL based on the parameter the
- source step took and the Change 'repository' property
- '''
-
- build = props.getBuild()
- assert build is not None, "Build should be available *during* a build?"
- s = build.getSourceStamp(self.step.codebase)
-
- repository = self.repository
-
- if not repository:
- return str(s.repository)
- else:
- if callable(repository):
- d = props.render(repository(s.repository))
- elif isinstance(repository, dict):
- d = props.render(repository.get(s.repository))
- elif isinstance(repository, str) or isinstance(repository, unicode):
- try:
- return str(repository % s.repository)
- except TypeError:
- # that's the backward compatibility case
- d = props.render(repository)
- else:
- d = props.render(repository)
-
- d.addCallback(str)
- return d
-
-class SlaveSource(Source):
-
- def __init__(self, mode='update', retry=None, **kwargs):
- """
- @type mode: string
- @param mode: the kind of VC operation that is desired:
- - 'update': specifies that the checkout/update should be
- performed directly into the workdir. Each build is performed
- in the same directory, allowing for incremental builds. This
- minimizes disk space, bandwidth, and CPU time. However, it
- may encounter problems if the build process does not handle
- dependencies properly (if you must sometimes do a 'clean
- build' to make sure everything gets compiled), or if source
- files are deleted but generated files can influence test
- behavior (e.g. python's .pyc files), or when source
- directories are deleted but generated files prevent CVS from
- removing them. When used with a patched checkout, from a
- previous buildbot try for instance, it will try to "revert"
- the changes first and will do a clobber if it is unable to
- get a clean checkout. The behavior is SCM-dependent.
-
- - 'copy': specifies that the source-controlled workspace
- should be maintained in a separate directory (called the
- 'copydir'), using checkout or update as necessary. For each
- build, a new workdir is created with a copy of the source
- tree (rm -rf workdir; cp -R -P -p copydir workdir). This
- doubles the disk space required, but keeps the bandwidth low
- (update instead of a full checkout). A full 'clean' build
- is performed each time. This avoids any generated-file
- build problems, but is still occasionally vulnerable to
- problems such as a CVS repository being manually rearranged
- (causing CVS errors on update) which are not an issue with
- a full checkout.
-
- - 'clobber': specifies that the working directory should be
- deleted each time, necessitating a full checkout for each
- build. This insures a clean build off a complete checkout,
- avoiding any of the problems described above, but is
- bandwidth intensive, as the whole source tree must be
- pulled down for each build.
-
- - 'export': is like 'clobber', except that e.g. the 'cvs
- export' command is used to create the working directory.
- This command removes all VC metadata files (the
- CVS/.svn/{arch} directories) from the tree, which is
- sometimes useful for creating source tarballs (to avoid
- including the metadata in the tar file). Not all VC systems
- support export.
-
- @type retry: tuple of ints (delay, repeats) (or None)
- @param retry: if provided, VC update failures are re-attempted up
- to REPEATS times, with DELAY seconds between each
- attempt. Some users have slaves with poor connectivity
- to their VC repository, and they say that up to 80% of
- their build failures are due to transient network
- failures that could be handled by simply retrying a
- couple times.
- """
- Source.__init__(self, **kwargs)
-
- assert mode in ("update", "copy", "clobber", "export")
- if retry:
- delay, repeats = retry
- assert isinstance(repeats, int)
- assert repeats > 0
- self.args = {'mode': mode,
- 'retry': retry,
- }
-
- def start(self):
- self.args['workdir'] = self.workdir
- self.args['logEnviron'] = self.logEnviron
- self.args['env'] = self.env
- self.args['timeout'] = self.timeout
- Source.start(self)
-
- def commandComplete(self, cmd):
- if not cmd.updates.has_key("got_revision"):
- return
- got_revision = cmd.updates["got_revision"][-1]
- if got_revision is None:
- return
-
- self.updateSourceProperty('got_revision', str(got_revision))
-
-
-class BK(SlaveSource):
- """I perform BitKeeper checkout/update operations."""
-
- name = 'bk'
-
- renderables = [ 'bkurl', 'baseURL' ]
-
- def __init__(self, bkurl=None, baseURL=None,
- directory=None, extra_args=None, **kwargs):
- """
- @type bkurl: string
- @param bkurl: the URL which points to the BitKeeper server.
-
- @type baseURL: string
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{bkurl} and C{baseURL}.
- """
-
- self.bkurl = _ComputeRepositoryURL(bkurl)
- self.baseURL = _ComputeRepositoryURL(baseURL)
- self.extra_args = extra_args
-
- Source.__init__(self, **kwargs)
-
- if bkurl and baseURL:
- raise ValueError("you must use exactly one of bkurl and baseURL")
-
-
- def computeSourceRevision(self, changes):
- return changes.revision
-
-
- def startVC(self, branch, revision, patch):
-
- warnings = []
- slavever = self.slaveVersion("bk")
- if not slavever:
- m = "slave does not have the 'bk' command"
- raise BuildSlaveTooOldError(m)
-
- if self.bkurl:
- assert not branch # we need baseURL= to use branches
- self.args['bkurl'] = self.bkurl
- else:
- self.args['bkurl'] = self.baseURL + branch
- self.args['revision'] = revision
- self.args['patch'] = patch
- self.args['branch'] = branch
- if self.extra_args is not None:
- self.args['extra_args'] = self.extra_args
-
- revstuff = []
- revstuff.append("[branch]")
- if revision is not None:
- revstuff.append("r%s" % revision)
- if patch is not None:
- revstuff.append("[patch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("bk", self.args)
- self.startCommand(cmd, warnings)
-
-
-
-class CVS(SlaveSource):
- """I do CVS checkout/update operations.
-
- Note: if you are doing anonymous/pserver CVS operations, you will need
- to manually do a 'cvs login' on each buildslave before the slave has any
- hope of success. XXX: fix then, take a cvs password as an argument and
- figure out how to do a 'cvs login' on each build
- """
-
- name = "cvs"
-
- renderables = [ "cvsroot" ]
-
- #progressMetrics = ('output',)
- #
- # additional things to track: update gives one stderr line per directory
- # (starting with 'cvs server: Updating ') (and is fairly stable if files
- # is empty), export gives one line per directory (starting with 'cvs
- # export: Updating ') and another line per file (starting with U). Would
- # be nice to track these, requires grepping LogFile data for lines,
- # parsing each line. Might be handy to have a hook in LogFile that gets
- # called with each complete line.
-
- def __init__(self, cvsroot=None, cvsmodule="",
- global_options=[], branch=None, checkoutDelay=None,
- checkout_options=[], export_options=[], extra_options=[],
- login=None,
- **kwargs):
-
- """
- @type cvsroot: string
- @param cvsroot: CVS Repository from which the source tree should
- be obtained. '/home/warner/Repository' for local
- or NFS-reachable repositories,
- ':pserver:anon@foo.com:/cvs' for anonymous CVS,
- 'user@host.com:/cvs' for non-anonymous CVS or
- CVS over ssh. Lots of possibilities, check the
- CVS documentation for more.
-
- @type cvsmodule: string
- @param cvsmodule: subdirectory of CVS repository that should be
- retrieved
-
- @type login: string or None
- @param login: if not None, a string which will be provided as a
- password to the 'cvs login' command, used when a
- :pserver: method is used to access the repository.
- This login is only needed once, but must be run
- each time (just before the CVS operation) because
- there is no way for the buildslave to tell whether
- it was previously performed or not.
-
- @type branch: string
- @param branch: the default branch name, will be used in a '-r'
- argument to specify which branch of the source tree
- should be used for this checkout. Defaults to None,
- which means to use 'HEAD'.
-
- @type checkoutDelay: int or None
- @param checkoutDelay: if not None, the number of seconds to put
- between the last known Change and the
- timestamp given to the -D argument. This
- defaults to exactly half of the parent
- Build's .treeStableTimer, but it could be
- set to something else if your CVS change
- notification has particularly weird
- latency characteristics.
-
- @type global_options: list of strings
- @param global_options: these arguments are inserted in the cvs
- command line, before the
- 'checkout'/'update' command word. See
- 'cvs --help-options' for a list of what
- may be accepted here. ['-r'] will make
- the checked out files read only. ['-r',
- '-R'] will also assume the repository is
- read-only (I assume this means it won't
- use locks to insure atomic access to the
- ,v files).
-
- @type checkout_options: list of strings
- @param checkout_options: these arguments are inserted in the cvs
- command line, after 'checkout' but before
- branch or revision specifiers.
-
- @type export_options: list of strings
- @param export_options: these arguments are inserted in the cvs
- command line, after 'export' but before
- branch or revision specifiers.
-
- @type extra_options: list of strings
- @param extra_options: these arguments are inserted in the cvs
- command line, after 'checkout' or 'export' but before
- branch or revision specifiers.
- """
-
- self.checkoutDelay = checkoutDelay
- self.branch = branch
- self.cvsroot = _ComputeRepositoryURL(self, cvsroot)
-
- SlaveSource.__init__(self, **kwargs)
-
- self.args.update({'cvsmodule': cvsmodule,
- 'global_options': global_options,
- 'checkout_options':checkout_options,
- 'export_options':export_options,
- 'extra_options':extra_options,
- 'login': login,
- })
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([c.when for c in changes])
- if self.checkoutDelay is not None:
- when = lastChange + self.checkoutDelay
- else:
- lastSubmit = max([br.submittedAt for br in self.build.requests])
- when = (lastChange + lastSubmit) / 2
- return formatdate(when)
-
- def startVC(self, branch, revision, patch):
- if self.slaveVersionIsOlderThan("cvs", "1.39"):
- # the slave doesn't know to avoid re-using the same sourcedir
- # when the branch changes. We have no way of knowing which branch
- # the last build used, so if we're using a non-default branch and
- # either 'update' or 'copy' modes, it is safer to refuse to
- # build, and tell the user they need to upgrade the buildslave.
- if (branch != self.branch
- and self.args['mode'] in ("update", "copy")):
- m = ("This buildslave (%s) does not know about multiple "
- "branches, and using mode=%s would probably build the "
- "wrong tree. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.0 or newer." % (self.build.slavename,
- self.args['mode']))
- log.msg(m)
- raise BuildSlaveTooOldError(m)
-
- if self.slaveVersionIsOlderThan("cvs", "2.10"):
- if self.args['extra_options'] or self.args['export_options']:
- m = ("This buildslave (%s) does not support export_options "
- "or extra_options arguments to the CVS step."
- % (self.build.slavename))
- log.msg(m)
- raise BuildSlaveTooOldError(m)
- # the unwanted args are empty, and will probably be ignored by
- # the slave, but delete them just to be safe
- del self.args['export_options']
- del self.args['extra_options']
-
- if branch is None:
- branch = "HEAD"
- self.args['cvsroot'] = self.cvsroot
- self.args['branch'] = branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- if self.args['branch'] == "HEAD" and self.args['revision']:
- # special case. 'cvs update -r HEAD -D today' gives no files
- # TODO: figure out why, see if it applies to -r BRANCH
- self.args['branch'] = None
-
- # deal with old slaves
- warnings = []
- slavever = self.slaveVersion("cvs", "old")
-
- if slavever == "old":
- # 0.5.0
- if self.args['mode'] == "export":
- self.args['export'] = 1
- elif self.args['mode'] == "clobber":
- self.args['clobber'] = 1
- elif self.args['mode'] == "copy":
- self.args['copydir'] = "source"
- self.args['tag'] = self.args['branch']
- assert not self.args['patch'] # 0.5.0 slave can't do patch
-
- cmd = RemoteCommand("cvs", self.args)
- self.startCommand(cmd, warnings)
-
-
-class SVN(SlaveSource):
- """I perform Subversion checkout/update operations."""
-
- name = 'svn'
- branch_placeholder = '%%BRANCH%%'
-
- renderables = [ 'svnurl', 'baseURL' ]
-
- def __init__(self, svnurl=None, baseURL=None, defaultBranch=None,
- directory=None, username=None, password=None,
- extra_args=None, keep_on_purge=None, ignore_ignores=None,
- always_purge=None, depth=None, **kwargs):
- """
- @type svnurl: string
- @param svnurl: the URL which points to the Subversion server,
- combining the access method (HTTP, ssh, local file),
- the repository host/port, the repository path, the
- sub-tree within the repository, and the branch to
- check out. Use exactly one of C{svnurl} and C{baseURL}.
-
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{svnurl} and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly. It will simply be appended
- to C{baseURL} and the result handed to
- the SVN command.
-
- @type username: string
- @param username: username to pass to svn's --username
-
- @type password: string
- @param password: password to pass to svn's --password
- """
-
- if not 'workdir' in kwargs and directory is not None:
- # deal with old configs
- warn("Please use workdir=, not directory=", DeprecationWarning)
- kwargs['workdir'] = directory
-
- self.svnurl = svnurl and _ComputeRepositoryURL(self, svnurl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- self.username = username
- self.password = password
- self.extra_args = extra_args
- self.keep_on_purge = keep_on_purge
- self.ignore_ignores = ignore_ignores
- self.always_purge = always_purge
- self.depth = depth
-
- SlaveSource.__init__(self, **kwargs)
-
- if svnurl and baseURL:
- raise ValueError("you must use either svnurl OR baseURL")
-
- def computeSourceRevision(self, changes):
- if not changes or None in [c.revision for c in changes]:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def checkCompatibility(self):
- ''' Handle compatibility between old slaves/svn clients '''
-
- slavever = self.slaveVersion("svn", "old")
-
- if not slavever:
- m = "slave does not have the 'svn' command"
- raise BuildSlaveTooOldError(m)
-
- if self.slaveVersionIsOlderThan("svn", "1.39"):
- # the slave doesn't know to avoid re-using the same sourcedir
- # when the branch changes. We have no way of knowing which branch
- # the last build used, so if we're using a non-default branch and
- # either 'update' or 'copy' modes, it is safer to refuse to
- # build, and tell the user they need to upgrade the buildslave.
- if (self.args['branch'] != self.branch
- and self.args['mode'] in ("update", "copy")):
- m = ("This buildslave (%s) does not know about multiple "
- "branches, and using mode=%s would probably build the "
- "wrong tree. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.0 or newer." % (self.build.slavename,
- self.args['mode']))
- raise BuildSlaveTooOldError(m)
-
- if (self.depth is not None) and self.slaveVersionIsOlderThan("svn","2.9"):
- m = ("This buildslave (%s) does not support svn depth "
- "arguments. Refusing to build. "
- "Please upgrade the buildslave." % (self.build.slavename))
- raise BuildSlaveTooOldError(m)
-
- if (self.username is not None or self.password is not None) \
- and self.slaveVersionIsOlderThan("svn", "2.8"):
- m = ("This buildslave (%s) does not support svn usernames "
- "and passwords. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.10 or newer." % (self.build.slavename,))
- raise BuildSlaveTooOldError(m)
-
- def getSvnUrl(self, branch):
- ''' Compute the svn url that will be passed to the svn remote command '''
- if self.svnurl:
- return self.svnurl
- else:
- if branch is None:
- m = ("The SVN source step belonging to builder '%s' does not know "
- "which branch to work with. This means that the change source "
- "did not specify a branch and that defaultBranch is None." \
- % self.build.builder.name)
- raise RuntimeError(m)
-
- computed = self.baseURL
-
- if self.branch_placeholder in self.baseURL:
- return computed.replace(self.branch_placeholder, branch)
- else:
- return computed + branch
-
- def startVC(self, branch, revision, patch):
- warnings = []
-
- self.checkCompatibility()
-
- self.args['svnurl'] = self.getSvnUrl(branch)
- self.args['revision'] = revision
- self.args['patch'] = patch
- self.args['always_purge'] = self.always_purge
-
- #Set up depth if specified
- if self.depth is not None:
- self.args['depth'] = self.depth
-
- if self.username is not None:
- self.args['username'] = self.username
- if self.password is not None:
- self.args['password'] = self.password
-
- if self.extra_args is not None:
- self.args['extra_args'] = self.extra_args
-
- revstuff = []
- #revstuff.append(self.args['svnurl'])
- if self.args['svnurl'].find('trunk') == -1:
- revstuff.append("[branch]")
- if revision is not None:
- revstuff.append("r%s" % revision)
- if patch is not None:
- revstuff.append("[patch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("svn", self.args)
- self.startCommand(cmd, warnings)
-
-
-class Darcs(SlaveSource):
- """Check out a source tree from a Darcs repository at 'repourl'.
-
- Darcs has no concept of file modes. This means the eXecute-bit will be
- cleared on all source files. As a result, you may need to invoke
- configuration scripts with something like:
-
- C{s(step.Configure, command=['/bin/sh', './configure'])}
- """
-
- name = "darcs"
-
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, defaultBranch=None,
- **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the Darcs repository. This
- is used as the default branch. Using C{repourl} does
- not enable builds of alternate branches: use
- C{baseURL} to enable this. Use either C{repourl} or
- C{baseURL}, not both.
-
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{repourl} and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly. It will simply be appended to
- C{baseURL} and the result handed to the
- 'darcs pull' command.
- """
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- SlaveSource.__init__(self, **kwargs)
- assert self.args['mode'] != "export", \
- "Darcs does not have an 'export' mode"
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("darcs")
- if not slavever:
- m = "slave is too old, does not know about darcs"
- raise BuildSlaveTooOldError(m)
-
- if self.slaveVersionIsOlderThan("darcs", "1.39"):
- if revision:
- # TODO: revisit this once we implement computeSourceRevision
- m = "0.6.6 slaves can't handle args['revision']"
- raise BuildSlaveTooOldError(m)
-
- # the slave doesn't know to avoid re-using the same sourcedir
- # when the branch changes. We have no way of knowing which branch
- # the last build used, so if we're using a non-default branch and
- # either 'update' or 'copy' modes, it is safer to refuse to
- # build, and tell the user they need to upgrade the buildslave.
- if (branch != self.branch
- and self.args['mode'] in ("update", "copy")):
- m = ("This buildslave (%s) does not know about multiple "
- "branches, and using mode=%s would probably build the "
- "wrong tree. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.0 or newer." % (self.build.slavename,
- self.args['mode']))
- raise BuildSlaveTooOldError(m)
-
- if self.repourl:
- assert not branch # we need baseURL= to use branches
- self.args['repourl'] = self.repourl
- else:
- self.args['repourl'] = self.baseURL + branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- revstuff = []
- if branch is not None and branch != self.branch:
- revstuff.append("[branch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("darcs", self.args)
- self.startCommand(cmd)
-
-
-class Git(SlaveSource):
- """Check out a source tree from a git repository 'repourl'."""
-
- name = "git"
-
- renderables = [ 'repourl' ]
-
- def __init__(self, repourl=None,
- branch="master",
- submodules=False,
- ignore_ignores=None,
- reference=None,
- shallow=False,
- progress=False,
- **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the git repository
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type submodules: boolean
- @param submodules: Whether or not to update (and initialize)
- git submodules.
-
- @type reference: string
- @param reference: The path to a reference repository to obtain
- objects from, if any.
-
- @type shallow: boolean
- @param shallow: Use a shallow or clone, if possible
-
- @type progress: boolean
- @param progress: Pass the --progress option when fetching. This
- can solve long fetches getting killed due to
- lack of output, but requires Git 1.7.2+.
- """
- SlaveSource.__init__(self, **kwargs)
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.branch = branch
- self.args.update({'submodules': submodules,
- 'ignore_ignores': ignore_ignores,
- 'reference': reference,
- 'shallow': shallow,
- 'progress': progress,
- })
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def startVC(self, branch, revision, patch):
- self.args['branch'] = branch
- self.args['repourl'] = self.repourl
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- # check if there is any patchset we should fetch from Gerrit
- if self.build.hasProperty("event.patchSet.ref"):
- # GerritChangeSource
- self.args['gerrit_branch'] = self.build.getProperty("event.patchSet.ref")
- self.updateSourceProperty("gerrit_branch",
- self.args['gerrit_branch'])
- else:
- try:
- # forced build
- change = self.build.getProperty("gerrit_change", '').split('/')
- if len(change) == 2:
- self.args['gerrit_branch'] = "refs/changes/%2.2d/%d/%d" \
- % (int(change[0]) % 100, int(change[0]), int(change[1]))
- self.updateSourceProperty("gerrit_branch",
- self.args['gerrit_branch'])
- except:
- pass
-
- slavever = self.slaveVersion("git")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about git")
- cmd = RemoteCommand("git", self.args)
- self.startCommand(cmd)
-
-
-class Repo(SlaveSource):
- """Check out a source tree from a repo repository described by manifest."""
-
- name = "repo"
-
- renderables = [ "manifest_url" ]
-
- def __init__(self,
- manifest_url=None,
- manifest_branch="master",
- manifest_file="default.xml",
- tarball=None,
- jobs=None,
- **kwargs):
- """
- @type manifest_url: string
- @param manifest_url: The URL which points at the repo manifests repository.
-
- @type manifest_branch: string
- @param manifest_branch: The manifest branch to check out by default.
-
- @type manifest_file: string
- @param manifest_file: The manifest to use for sync.
-
- """
- SlaveSource.__init__(self, **kwargs)
- self.manifest_url = _ComputeRepositoryURL(self, manifest_url)
- self.args.update({'manifest_branch': manifest_branch,
- 'manifest_file': manifest_file,
- 'tarball': tarball,
- 'manifest_override_url': None,
- 'jobs': jobs
- })
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def parseDownloadProperty(self, s):
- """
- lets try to be nice in the format we want
- can support several instances of "repo download proj number/patch" (direct copy paste from gerrit web site)
- or several instances of "proj number/patch" (simpler version)
- This feature allows integrator to build with several pending interdependant changes.
- returns list of repo downloads sent to the buildslave
- """
- import re
- if s == None:
- return []
- re1 = re.compile("repo download ([^ ]+) ([0-9]+/[0-9]+)")
- re2 = re.compile("([^ ]+) ([0-9]+/[0-9]+)")
- re3 = re.compile("([^ ]+)/([0-9]+/[0-9]+)")
- ret = []
- for cur_re in [re1, re2, re3]:
- res = cur_re.search(s)
- while res:
- ret.append("%s %s" % (res.group(1), res.group(2)))
- s = s[:res.start(0)] + s[res.end(0):]
- res = cur_re.search(s)
- return ret
-
- def buildDownloadList(self):
- """taken the changesource and forcebuild property,
- build the repo download command to send to the slave
- making this a defereable allow config to tweak this
- in order to e.g. manage dependancies
- """
- downloads = self.build.getProperty("repo_downloads", [])
-
- # download patches based on GerritChangeSource events
- for change in self.build.allChanges():
- if (change.properties.has_key("event.type") and
- change.properties["event.type"] == "patchset-created"):
- downloads.append("%s %s/%s"% (change.properties["event.change.project"],
- change.properties["event.change.number"],
- change.properties["event.patchSet.number"]))
-
- # download patches based on web site forced build properties:
- # "repo_d", "repo_d0", .., "repo_d9"
- # "repo_download", "repo_download0", .., "repo_download9"
- for propName in ["repo_d"] + ["repo_d%d" % i for i in xrange(0,10)] + \
- ["repo_download"] + ["repo_download%d" % i for i in xrange(0,10)]:
- s = self.build.getProperty(propName)
- if s is not None:
- downloads.extend(self.parseDownloadProperty(s))
-
- if downloads:
- self.args["repo_downloads"] = downloads
- self.updateSourceProperty("repo_downloads", downloads)
- return defer.succeed(None)
-
- def startVC(self, branch, revision, patch):
- self.args['manifest_url'] = self.manifest_url
-
- # manifest override
- self.args['manifest_override_url'] = None
- try:
- self.args['manifest_override_url'] = self.build.getProperty("manifest_override_url")
- except KeyError:
- pass
- # only master has access to properties, so we must implement this here.
- d = self.buildDownloadList()
- d.addCallback(self.continueStartVC, branch, revision, patch)
- d.addErrback(self.failed)
-
- def continueStartVC(self, ignored, branch, revision, patch):
- slavever = self.slaveVersion("repo")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about repo")
- cmd = RemoteCommand("repo", self.args)
- self.startCommand(cmd)
-
- def commandComplete(self, cmd):
- repo_downloaded = []
- if cmd.updates.has_key("repo_downloaded"):
- repo_downloaded = cmd.updates["repo_downloaded"][-1]
- if repo_downloaded:
- self.updateSourceProperty("repo_downloaded",
- str(repo_downloaded))
- else:
- repo_downloaded = []
- orig_downloads = self.getProperty("repo_downloads") or []
- if len(orig_downloads) != len(repo_downloaded):
- self.step_status.setText(["repo download issues"])
-
-
-class Bzr(SlaveSource):
- """Check out a source tree from a bzr (Bazaar) repository at 'repourl'.
-
- """
-
- name = "bzr"
-
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, defaultBranch=None,
- forceSharedRepo=None,
- **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the bzr repository. This
- is used as the default branch. Using C{repourl} does
- not enable builds of alternate branches: use
- C{baseURL} to enable this. Use either C{repourl} or
- C{baseURL}, not both.
-
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{repourl} and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly. It will simply be appended to
- C{baseURL} and the result handed to the
- 'bzr checkout pull' command.
-
-
- @param forceSharedRepo: Boolean, defaults to False. If set to True,
- the working directory will be made into a
- bzr shared repository if it is not already.
- Shared repository greatly reduces the amount
- of history data that needs to be downloaded
- if not using update/copy mode, or if using
- update/copy mode with multiple branches.
- """
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- SlaveSource.__init__(self, **kwargs)
- self.args.update({'forceSharedRepo': forceSharedRepo})
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("bzr")
- if not slavever:
- m = "slave is too old, does not know about bzr"
- raise BuildSlaveTooOldError(m)
-
- if self.repourl:
- assert not branch # we need baseURL= to use branches
- self.args['repourl'] = self.repourl
- else:
- self.args['repourl'] = self.baseURL + branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- revstuff = []
- if branch is not None and branch != self.branch:
- revstuff.append("[" + branch + "]")
- if revision is not None:
- revstuff.append("r%s" % revision)
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("bzr", self.args)
- self.startCommand(cmd)
-
-
-class Mercurial(SlaveSource):
- """Check out a source tree from a mercurial repository 'repourl'."""
-
- name = "hg"
-
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, defaultBranch=None,
- branchType='dirname', clobberOnBranchChange=True, **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the Mercurial repository.
- This uses the 'default' branch unless defaultBranch is
- specified below and the C{branchType} is set to
- 'inrepo'. It is an error to specify a branch without
- setting the C{branchType} to 'inrepo'.
-
- @param baseURL: if 'dirname' branches are enabled, this is the base URL
- to which a branch name will be appended. It should
- probably end in a slash. Use exactly one of C{repourl}
- and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly.
- For 'dirname' branches, It will simply be
- appended to C{baseURL} and the result handed to
- the 'hg update' command.
- For 'inrepo' branches, this specifies the named
- revision to which the tree will update after a
- clone.
-
- @param branchType: either 'dirname' or 'inrepo' depending on whether
- the branch name should be appended to the C{baseURL}
- or the branch is a mercurial named branch and can be
- found within the C{repourl}
-
- @param clobberOnBranchChange: boolean, defaults to True. If set and
- using inrepos branches, clobber the tree
- at each branch change. Otherwise, just
- update to the branch.
- """
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- self.branchType = branchType
- self.clobberOnBranchChange = clobberOnBranchChange
- SlaveSource.__init__(self, **kwargs)
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("hg")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about hg")
-
- if self.repourl:
- # we need baseURL= to use dirname branches
- assert self.branchType == 'inrepo' or not branch
- self.args['repourl'] = self.repourl
- if branch:
- self.args['branch'] = branch
- else:
- self.args['repourl'] = self.baseURL + (branch or '')
- self.args['revision'] = revision
- self.args['patch'] = patch
- self.args['clobberOnBranchChange'] = self.clobberOnBranchChange
- self.args['branchType'] = self.branchType
-
- revstuff = []
- if branch is not None and branch != self.branch:
- revstuff.append("[branch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("hg", self.args)
- self.startCommand(cmd)
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- # without knowing the revision ancestry graph, we can't sort the
- # changes at all. So for now, assume they were given to us in sorted
- # order, and just pay attention to the last one. See ticket #103 for
- # more details.
- if len(changes) > 1:
- log.msg("Mercurial.computeSourceRevision: warning: "
- "there are %d changes here, assuming the last one is "
- "the most recent" % len(changes))
- return changes[-1].revision
-
-
-class P4(SlaveSource):
- """ P4 is a class for accessing perforce revision control"""
- name = "p4"
-
- renderables = [ 'p4base' ]
-
- def __init__(self, p4base=None, defaultBranch=None, p4port=None, p4user=None,
- p4passwd=None, p4extra_views=[], p4line_end='local',
- p4client='buildbot_%(slave)s_%(builder)s', **kwargs):
- """
- @type p4base: string
- @param p4base: A view into a perforce depot, typically
- "//depot/proj/"
-
- @type defaultBranch: string
- @param defaultBranch: Identify a branch to build by default. Perforce
- is a view based branching system. So, the branch
- is normally the name after the base. For example,
- branch=1.0 is view=//depot/proj/1.0/...
- branch=1.1 is view=//depot/proj/1.1/...
-
- @type p4port: string
- @param p4port: Specify the perforce server to connection in the format
- <host>:<port>. Example "perforce.example.com:1666"
-
- @type p4user: string
- @param p4user: The perforce user to run the command as.
-
- @type p4passwd: string
- @param p4passwd: The password for the perforce user.
-
- @type p4extra_views: list of tuples
- @param p4extra_views: Extra views to be added to
- the client that is being used.
-
- @type p4line_end: string
- @param p4line_end: value of the LineEnd client specification property
-
- @type p4client: string
- @param p4client: The perforce client to use for this buildslave.
- """
-
- self.p4base = _ComputeRepositoryURL(self, p4base)
- self.branch = defaultBranch
- SlaveSource.__init__(self, **kwargs)
- self.args['p4port'] = p4port
- self.args['p4user'] = p4user
- self.args['p4passwd'] = p4passwd
- self.args['p4extra_views'] = p4extra_views
- self.args['p4line_end'] = p4line_end
- self.p4client = p4client
-
- def setBuild(self, build):
- SlaveSource.setBuild(self, build)
- self.args['p4client'] = self.p4client % {
- 'slave': build.slavename,
- 'builder': build.builder.name,
- }
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("p4")
- assert slavever, "slave is too old, does not know about p4"
- args = dict(self.args)
- args['p4base'] = self.p4base
- args['branch'] = branch or self.branch
- args['revision'] = revision
- args['patch'] = patch
- cmd = RemoteCommand("p4", args)
- self.startCommand(cmd)
-
-class Monotone(SlaveSource):
- """Check out a source tree from a monotone repository 'repourl'."""
-
- name = "mtn"
-
- renderables = [ 'repourl' ]
-
- def __init__(self, repourl=None, branch=None, progress=False, **kwargs):
- """
- @type repourl: string
- @param repourl: the URI which points at the monotone repository.
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type progress: boolean
- @param progress: Pass the --ticker=dot option when pulling. This
- can solve long fetches getting killed due to
- lack of output.
- """
- SlaveSource.__init__(self, **kwargs)
- self.repourl = _ComputeRepositoryURL(self, repourl)
- if (not repourl):
- raise ValueError("you must provide a repository uri in 'repourl'")
- if (not branch):
- raise ValueError("you must provide a default branch in 'branch'")
- self.args.update({'branch': branch,
- 'progress': progress,
- })
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("mtn")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about mtn")
-
- self.args['repourl'] = self.repourl
- if branch:
- self.args['branch'] = branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- cmd = RemoteCommand("mtn", self.args)
- self.startCommand(cmd)
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- # without knowing the revision ancestry graph, we can't sort the
- # changes at all. So for now, assume they were given to us in sorted
- # order, and just pay attention to the last one. See ticket #103 for
- # more details.
- if len(changes) > 1:
- log.msg("Monotone.computeSourceRevision: warning: "
- "there are %d changes here, assuming the last one is "
- "the most recent" % len(changes))
- return changes[-1].revision
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py
deleted file mode 100644
index b6d47daf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-# Portions Copyright 2013 Bad Dog Consulting
-
-import re
-import os
-
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces, config
-from buildbot.process import buildstep
-from buildbot.steps.source import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.process.properties import Interpolate
-from types import StringType
-
-
-# Notes:
-# see
-# http://perforce.com/perforce/doc.current/manuals/cmdref/o.gopts.html#1040647
-# for getting p4 command to output marshalled python dictionaries as output
-# for commands.
-# Perhaps switch to using 'p4 -G' : From URL above:
-# -G Causes all output (and batch input for form commands with -i) to be
-# formatted as marshalled Python dictionary objects. This is most often used
-# when scripting.
-
-debug_logging = False
-
-
-class P4(Source):
- """Perform Perforce checkout/update operations."""
-
- name = 'p4'
-
- renderables = ['p4base', 'p4client', 'p4viewspec', 'p4branch']
- possible_modes = ('incremental', 'full')
-
- def __init__(self, mode='incremental',
- method=None, p4base=None, p4branch=None,
- p4port=None, p4user=None,
- p4passwd=None, p4extra_views=(), p4line_end='local',
- p4viewspec=None,
- p4client=Interpolate('buildbot_%(prop:slavename)s_%(prop:buildername)s'),
- p4bin='p4',
- **kwargs):
- self.method = method
- self.mode = mode
- self.p4branch = p4branch
- self.p4bin = p4bin
- self.p4base = p4base
- self.p4port = p4port
- self.p4user = p4user
- self.p4passwd = p4passwd
- self.p4extra_views = p4extra_views
- self.p4viewspec = p4viewspec
- self.p4line_end = p4line_end
- self.p4client = p4client
-
- Source.__init__(self, **kwargs)
-
- if self.mode not in self.possible_modes:
- config.error("mode %s is not one of %s" % (self.mode, self.possible_modes))
-
- if not p4viewspec and p4base is None:
- config.error("You must provide p4base or p4viewspec")
-
- if p4viewspec and (p4base or p4branch or p4extra_views):
- config.error("Either provide p4viewspec or p4base and p4branch (and optionally p4extra_views")
-
- if p4viewspec and type(p4viewspec) is StringType:
- config.error("p4viewspec must not be a string, and should be a sequence of 2 element sequences")
-
- if not interfaces.IRenderable.providedBy(p4base) and p4base and p4base.endswith('/'):
- config.error('p4base should not end with a trailing / [p4base = %s]' % p4base)
-
- if not interfaces.IRenderable.providedBy(p4branch) and p4branch and p4branch.endswith('/'):
- config.error('p4branch should not end with a trailing / [p4branch = %s]' % p4branch)
-
- if (p4branch or p4extra_views) and not p4base:
- config.error('If you specify either p4branch or p4extra_views you must also specify p4base')
-
- def startVC(self, branch, revision, patch):
- if debug_logging:
- log.msg('in startVC')
-
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkP4()
-
- def checkInstall(p4Installed):
- if not p4Installed:
- raise BuildSlaveTooOldError("p4 is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'full':
- d.addCallback(self.full)
- elif self.mode == 'incremental':
- d.addCallback(self.incremental)
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self, _):
- if debug_logging:
- log.msg("P4:full()..")
-
- # First we need to create the client
- yield self._createClientSpec()
-
- # Then p4 sync #none
- yield self._dovccmd(['sync', '#none'])
-
- # Then remove directory.
- yield self.runRmdir(self.workdir)
-
- # Then we need to sync the client
- if self.revision:
- if debug_logging:
- log.msg("P4: full() sync command based on :base:%s changeset:%d", self.p4base, int(self.revision))
- yield self._dovccmd(['sync', '%s...@%d' % (self.p4base, int(self.revision))], collectStdout=True)
- else:
- if debug_logging:
- log.msg("P4: full() sync command based on :base:%s no revision", self.p4base)
- yield self._dovccmd(['sync'], collectStdout=True)
-
- if debug_logging:
- log.msg("P4: full() sync done.")
-
- @defer.inlineCallbacks
- def incremental(self, _):
- if debug_logging:
- log.msg("P4:incremental()")
-
- # First we need to create the client
- yield self._createClientSpec()
-
- # and plan to do a checkout
- command = ['sync', ]
-
- if self.revision:
- command.extend(['%s...@%d' % (self.p4base, int(self.revision))])
-
- if debug_logging:
- log.msg("P4:incremental() command:%s revision:%s", command, self.revision)
- yield self._dovccmd(command)
-
- def finish(self, res):
- d = defer.succeed(res)
-
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def _buildVCCommand(self, doCommand):
- assert doCommand, "No command specified"
-
- command = [self.p4bin, ]
-
- if self.p4port:
- command.extend(['-p', self.p4port])
- if self.p4user:
- command.extend(['-u', self.p4user])
- if self.p4passwd:
- # Need to find out if there's a way to obfuscate this
- command.extend(['-P', self.p4passwd])
- if self.p4client:
- command.extend(['-c', self.p4client])
-
- command.extend(doCommand)
-
- command = [c.encode('utf-8') for c in command]
- return command
-
- def _dovccmd(self, command, collectStdout=False, initialStdin=None):
- command = self._buildVCCommand(command)
-
- if debug_logging:
- log.msg("P4:_dovccmd():workdir->%s" % self.workdir)
- cmd = buildstep.RemoteShellCommand(self.workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- collectStdout=collectStdout,
- initialStdin=initialStdin,)
- cmd.useLog(self.stdio_log, False)
- if debug_logging:
- log.msg("Starting p4 command : p4 %s" % (" ".join(command),))
-
- d = self.runCommand(cmd)
-
- def evaluateCommand(cmd):
- if cmd.rc != 0:
- if debug_logging:
- log.msg("P4:_dovccmd():Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def _sourcedirIsUpdatable(self):
- # In general you should always be able to write to the directory
- # You just specified as the root of your client
- # So just return.
- # If we find a case where this is no longer true, then this
- # needs to be implemented
- return defer.succeed(True)
-
- @defer.inlineCallbacks
- def _createClientSpec(self):
- builddir = self.getProperty('builddir')
-
- if debug_logging:
- log.msg("P4:_createClientSpec() builddir:%s" % builddir)
- log.msg("P4:_createClientSpec() SELF.workdir:%s" % self.workdir)
-
- prop_dict = self.getProperties().asDict()
- prop_dict['p4client'] = self.p4client
-
- client_spec = ''
- client_spec += "Client: %s\n\n" % self.p4client
- client_spec += "Owner: %s\n\n" % self.p4user
- client_spec += "Description:\n\tCreated by %s\n\n" % self.p4user
- client_spec += "Root:\t%s\n\n" % os.path.join(builddir, self.workdir)
- client_spec += "Options:\tallwrite rmdir\n\n"
- if self.p4line_end:
- client_spec += "LineEnd:\t%s\n\n" % self.p4line_end
- else:
- client_spec += "LineEnd:\tlocal\n\n"
-
- # Setup a view
- client_spec += "View:\n"
-
- if self.p4viewspec:
- # uses only p4viewspec array of tuples to build view
- # If the user specifies a viewspec via an array of tuples then
- # Ignore any specified p4base,p4branch, and/or p4extra_views
- for k, v in self.p4viewspec:
- if debug_logging:
- log.msg('P4:_createClientSpec():key:%s value:%s' % (k, v))
- client_spec += '\t%s... //%s/%s...\n' % (k, self.p4client, v)
- else:
- # Uses p4base, p4branch, p4extra_views
- client_spec += "\t%s" % (self.p4base)
-
- if self.p4branch:
- client_spec += "/%s" % (self.p4branch)
-
- client_spec += "/... //%s/...\n" % (self.p4client)
-
- if self.p4extra_views:
- for k, v in self.p4extra_views:
- client_spec += "\t%s/... //%s/%s/...\n" % (k, self.p4client, v)
-
- client_spec = client_spec.encode('utf-8') # resolve unicode issues
- if debug_logging:
- log.msg(client_spec)
-
- stdout = yield self._dovccmd(['client', '-i'], collectStdout=True, initialStdin=client_spec)
- mo = re.search(r'Client (\S+) (.+)$', stdout, re.M)
- defer.returnValue(mo and (mo.group(2) == 'saved.' or mo.group(2) == 'not changed.'))
-
- def parseGotRevision(self, _):
- command = self._buildVCCommand(['changes', '-m1', '#have'])
-
- cmd = buildstep.RemoteShellCommand(self.workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- collectStdout=True)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- def _setrev(_):
- stdout = cmd.stdout.strip()
- # Example output from p4 changes -m1 #have
- # Change 212798 on 2012/04/13 by user@user-unix-bldng2 'change to pickup build'
- revision = stdout.split()[1]
- try:
- int(revision)
- except ValueError:
- msg = ("p4.parseGotRevision unable to parse output "
- "of 'p4 changes -m1 \"#have\"': '%s'" % stdout)
- log.msg(msg)
- raise buildstep.BuildStepFailed()
-
- if debug_logging:
- log.msg("Got p4 revision %s" % (revision,))
- self.updateSourceProperty('got_revision', revision)
- return 0
- d.addCallback(lambda _: _setrev(cmd.rc))
- return d
-
- def purge(self, ignore_ignores):
- """Delete everything that shown up on status."""
- command = ['sync', '#none']
- if ignore_ignores:
- command.append('--no-ignore')
- d = self._dovccmd(command, collectStdout=True)
-
- # add deferred to rm tree
-
- # then add defer to sync to revision
- return d
-
- def checkP4(self):
- cmd = buildstep.RemoteShellCommand(self.workdir, ['p4', '-V'],
- env=self.env,
- logEnviron=self.logEnviron)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- def evaluate(cmd):
- if cmd.rc != 0:
- return False
- return True
- d.addCallback(lambda _: evaluate(cmd))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes or None in [c.revision for c in changes]:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py
deleted file mode 100644
index f1a75e18..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-import textwrap
-
-from twisted.internet import defer, reactor
-
-from buildbot import util
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import IRenderable
-from zope.interface import implements
-
-
-class RepoDownloadsFromProperties(util.ComparableMixin, object):
- implements(IRenderable)
- parse_download_re = (re.compile(r"repo download ([^ ]+) ([0-9]+/[0-9]+)"),
- re.compile(r"([^ ]+) ([0-9]+/[0-9]+)"),
- re.compile(r"([^ ]+)/([0-9]+/[0-9]+)"),
- )
-
- compare_attrs = ('names',)
-
- def __init__(self, names):
- self.names = names
-
- def getRenderingFor(self, props):
- downloads = []
- for propName in self.names:
- s = props.getProperty(propName)
- if s is not None:
- downloads.extend(self.parseDownloadProperty(s))
- return downloads
-
- def parseDownloadProperty(self, s):
- """
- lets try to be nice in the format we want
- can support several instances of "repo download proj number/patch" (direct copy paste from gerrit web site)
- or several instances of "proj number/patch" (simpler version)
- This feature allows integrator to build with several pending interdependant changes.
- returns list of repo downloads sent to the buildslave
- """
- if s is None:
- return []
- ret = []
- for cur_re in self.parse_download_re:
- res = cur_re.search(s)
- while res:
- ret.append("%s %s" % (res.group(1), res.group(2)))
- s = s[:res.start(0)] + s[res.end(0):]
- res = cur_re.search(s)
- return ret
-
-
-class RepoDownloadsFromChangeSource(util.ComparableMixin, object):
- implements(IRenderable)
- compare_attrs = ('codebase',)
-
- def __init__(self, codebase=None):
- self.codebase = codebase
-
- def getRenderingFor(self, props):
- downloads = []
- if self.codebase is None:
- changes = props.getBuild().allChanges()
- else:
- changes = props.getBuild().getSourceStamp(self.codebase).changes
- for change in changes:
- if ("event.type" in change.properties and
- change.properties["event.type"] == "patchset-created"):
- downloads.append("%s %s/%s" % (change.properties["event.change.project"],
- change.properties["event.change.number"],
- change.properties["event.patchSet.number"]))
- return downloads
-
-
-class Repo(Source):
- """ Class for Repo with all the smarts """
- name = 'repo'
- renderables = ["manifestURL", "manifestFile", "tarball", "jobs",
- "syncAllBranches", "updateTarballAge", "manifestOverrideUrl",
- "repoDownloads"]
-
- ref_not_found_re = re.compile(r"fatal: Couldn't find remote ref")
- cherry_pick_error_re = re.compile(r"|".join([r"Automatic cherry-pick failed",
- r"error: "
- r"fatal: "
- r"possibly due to conflict resolution."]))
- re_change = re.compile(r".* refs/changes/\d\d/(\d+)/(\d+) -> FETCH_HEAD$")
- re_head = re.compile(r"^HEAD is now at ([0-9a-f]+)...")
- mirror_sync_retry = 10 # number of retries, if we detect mirror desynchronization
- mirror_sync_sleep = 60 # wait 1min between retries (thus default total retry time is 10min)
-
- def __init__(self,
- manifestURL=None,
- manifestBranch="master",
- manifestFile="default.xml",
- tarball=None,
- jobs=None,
- syncAllBranches=False,
- updateTarballAge=7*24.0*3600.0,
- manifestOverrideUrl=None,
- repoDownloads=None,
- **kwargs):
- """
- @type manifestURL: string
- @param manifestURL: The URL which points at the repo manifests repository.
-
- @type manifestBranch: string
- @param manifestBranch: The manifest branch to check out by default.
-
- @type manifestFile: string
- @param manifestFile: The manifest to use for sync.
-
- @type syncAllBranches: bool.
- @param syncAllBranches: true, then we must slowly synchronize all branches.
-
- @type updateTarballAge: float
- @param updateTarballAge: renderable to determine the update tarball policy,
- given properties
- Returns: max age of tarball in seconds, or None, if we
- want to skip tarball update
-
- @type manifestOverrideUrl: string
- @param manifestOverrideUrl: optional http URL for overriding the manifest
- usually coming from Property setup by a ForceScheduler
-
- @type repoDownloads: list of strings
- @param repoDownloads: optional repo download to perform after the repo sync
-
- """
- self.manifestURL = manifestURL
- self.manifestBranch = manifestBranch
- self.manifestFile = manifestFile
- self.tarball = tarball
- self.jobs = jobs
- self.syncAllBranches = syncAllBranches
- self.updateTarballAge = updateTarballAge
- self.manifestOverrideUrl = manifestOverrideUrl
- if repoDownloads is None:
- repoDownloads = []
- self.repoDownloads = repoDownloads
- Source.__init__(self, **kwargs)
-
- assert self.manifestURL is not None
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def filterManifestPatches(self):
- """
- Patches to manifest projects are a bit special.
- repo does not support a way to download them automatically,
- so we need to implement the boilerplate manually.
- This code separates the manifest patches from the other patches,
- and generates commands to import those manifest patches.
- """
- manifest_unrelated_downloads = []
- manifest_related_downloads = []
- for download in self.repoDownloads:
- project, ch_ps = download.split(" ")[-2:]
- if (self.manifestURL.endswith("/"+project) or
- self.manifestURL.endswith("/"+project+".git")):
- ch, ps = map(int, ch_ps.split("/"))
- branch = "refs/changes/%02d/%d/%d" % (ch % 100, ch, ps)
- manifest_related_downloads.append(
- ["git", "fetch", self.manifestURL, branch])
- manifest_related_downloads.append(
- ["git", "cherry-pick", "FETCH_HEAD"])
- else:
- manifest_unrelated_downloads.append(download)
- self.repoDownloads = manifest_unrelated_downloads
- self.manifestDownloads = manifest_related_downloads
-
- def _repoCmd(self, command, abandonOnFailure=True, **kwargs):
- return self._Cmd(["repo"]+command, abandonOnFailure=abandonOnFailure, **kwargs)
-
- def _Cmd(self, command, abandonOnFailure=True, workdir=None, **kwargs):
- if workdir is None:
- workdir = self.workdir
- self.cmd = cmd = buildstep.RemoteShellCommand(workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout, **kwargs)
- # does not make sense to logEnviron for each command (just for first)
- self.logEnviron = False
- cmd.useLog(self.stdio_log, False)
- self.stdio_log.addHeader("Starting command: %s\n" % (" ".join(command), ))
- self.step_status.setText(["%s" % (" ".join(command[:2]))])
- d = self.runCommand(cmd)
-
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- self.step_status.setText(["repo failed at: %s" % (" ".join(command[:2]))])
- self.stdio_log.addStderr("Source step failed while running command %s\n" % cmd)
- raise buildstep.BuildStepFailed()
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def repoDir(self):
- return self.build.path_module.join(self.workdir, ".repo")
-
- def sourcedirIsUpdateable(self):
- return self.pathExists(self.repoDir())
-
- def startVC(self, branch, revision, patch):
- d = self.doStartVC()
- d.addErrback(self.failed)
-
- @defer.inlineCallbacks
- def doStartVC(self):
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- self.filterManifestPatches()
-
- if self.repoDownloads:
- self.stdio_log.addHeader("will download:\n" + "repo download " + "\nrepo download ".join(self.repoDownloads) + "\n")
-
- self.willRetryInCaseOfFailure = True
-
- d = self.doRepoSync()
-
- def maybeRetry(why):
- # in case the tree was corrupted somehow because of previous build
- # we clobber one time, and retry everything
- if why.check(buildstep.BuildStepFailed) and self.willRetryInCaseOfFailure:
- self.stdio_log.addStderr("got issue at first try:\n" + str(why) +
- "\nRetry after clobber...")
- return self.doRepoSync(forceClobber=True)
- return why # propagate to self.failed
- d.addErrback(maybeRetry)
- yield d
- yield self.maybeUpdateTarball()
-
- # starting from here, clobbering will not help
- yield self.doRepoDownloads()
- self.setStatus(self.cmd, 0)
- yield self.finished(0)
-
- @defer.inlineCallbacks
- def doClobberStart(self):
- yield self.runRmdir(self.workdir)
- yield self.runMkdir(self.workdir)
- yield self.maybeExtractTarball()
-
- @defer.inlineCallbacks
- def doRepoSync(self, forceClobber=False):
- updatable = yield self.sourcedirIsUpdateable()
- if not updatable or forceClobber:
- # no need to re-clobber in case of failure
- self.willRetryInCaseOfFailure = False
- yield self.doClobberStart()
- yield self.doCleanup()
- yield self._repoCmd(['init',
- '-u', self.manifestURL,
- '-b', self.manifestBranch,
- '-m', self.manifestFile])
-
- if self.manifestOverrideUrl:
- self.stdio_log.addHeader("overriding manifest with %s\n" % (self.manifestOverrideUrl))
- local_file = yield self.pathExists(self.build.path_module.join(self.workdir,
- self.manifestOverrideUrl))
- if local_file:
- yield self._Cmd(["cp", "-f", self.manifestOverrideUrl, "manifest_override.xml"])
- else:
- yield self._Cmd(["wget", self.manifestOverrideUrl, "-O", "manifest_override.xml"])
- yield self._Cmd(["ln", "-sf", "../manifest_override.xml", "manifest.xml"],
- workdir=self.build.path_module.join(self.workdir, ".repo"))
-
- for command in self.manifestDownloads:
- yield self._Cmd(command, workdir=self.build.path_module.join(self.workdir, ".repo", "manifests"))
-
- command = ['sync']
- if self.jobs:
- command.append('-j' + str(self.jobs))
- if not self.syncAllBranches:
- command.append('-c')
- self.step_status.setText(["repo sync"])
- self.stdio_log.addHeader("synching manifest %s from branch %s from %s\n"
- % (self.manifestFile, self.manifestBranch, self.manifestURL))
- yield self._repoCmd(command)
-
- command = ['manifest', '-r', '-o', 'manifest-original.xml']
- yield self._repoCmd(command)
-
- # check whether msg matches one of the
- # compiled regexps in self.re_error_messages
- def _findErrorMessages(self, error_re):
- for logname in ['stderr', 'stdout']:
- if not hasattr(self.cmd, logname):
- continue
- msg = getattr(self.cmd, logname)
- if not (re.search(error_re, msg) is None):
- return True
- return False
-
- def _sleep(self, delay):
- d = defer.Deferred()
- reactor.callLater(delay, d.callback, 1)
- return d
-
- @defer.inlineCallbacks
- def doRepoDownloads(self):
- self.repo_downloaded = ""
- for download in self.repoDownloads:
- command = ['download'] + download.split(' ')
- self.stdio_log.addHeader("downloading changeset %s\n"
- % (download))
-
- retry = self.mirror_sync_retry + 1
- while retry > 0:
- yield self._repoCmd(command, abandonOnFailure=False,
- collectStdout=True, collectStderr=True)
- if not self._findErrorMessages(self.ref_not_found_re):
- break
- retry -= 1
- self.stdio_log.addStderr("failed downloading changeset %s\n" % (download))
- self.stdio_log.addHeader("wait one minute for mirror sync\n")
- yield self._sleep(self.mirror_sync_sleep)
-
- if retry == 0:
- self.step_status.setText(["repo: change %s does not exist" % download])
- self.step_status.setText2(["repo: change %s does not exist" % download])
- raise buildstep.BuildStepFailed()
-
- if self.cmd.didFail() or self._findErrorMessages(self.cherry_pick_error_re):
- # cherry pick error! We create a diff with status current workdir
- # in stdout, which reveals the merge errors and exit
- command = ['forall', '-c', 'git', 'diff', 'HEAD']
- yield self._repoCmd(command, abandonOnFailure=False)
- self.step_status.setText(["download failed: %s" % download])
- raise buildstep.BuildStepFailed()
-
- if hasattr(self.cmd, 'stderr'):
- lines = self.cmd.stderr.split("\n")
- match1 = match2 = False
- for line in lines:
- if not match1:
- match1 = self.re_change.match(line)
- if not match2:
- match2 = self.re_head.match(line)
- if match1 and match2:
- self.repo_downloaded += "%s/%s %s " % (match1.group(1),
- match1.group(2),
- match2.group(1))
-
- self.setProperty("repo_downloaded", self.repo_downloaded, "Source")
-
- def computeTarballOptions(self):
- # Keep in mind that the compression part of tarball generation
- # can be non negligible
- tar = ['tar']
- if self.tarball.endswith("gz"):
- tar.append('-z')
- if self.tarball.endswith("bz2") or self.tarball.endswith("bz"):
- tar.append('-j')
- if self.tarball.endswith("lzma"):
- tar.append('--lzma')
- if self.tarball.endswith("lzop"):
- tar.append('--lzop')
- return tar
-
- @defer.inlineCallbacks
- def maybeExtractTarball(self):
- if self.tarball:
- tar = self.computeTarballOptions() + ['-xvf', self.tarball]
- res = yield self._Cmd(tar, abandonOnFailure=False)
- if res: # error with tarball.. erase repo dir and tarball
- yield self._Cmd(["rm", "-f", self.tarball], abandonOnFailure=False)
- yield self.runRmdir(self.repoDir(), abandonOnFailure=False)
-
- @defer.inlineCallbacks
- def maybeUpdateTarball(self):
- if not self.tarball or self.updateTarballAge is None:
- return
- # tarball path is absolute, so we cannot use slave's stat command
- # stat -c%Y gives mtime in second since epoch
- res = yield self._Cmd(["stat", "-c%Y", self.tarball], collectStdout=True, abandonOnFailure=False)
- if not res:
- tarball_mtime = int(self.cmd.stdout)
- yield self._Cmd(["stat", "-c%Y", "."], collectStdout=True)
- now_mtime = int(self.cmd.stdout)
- age = now_mtime - tarball_mtime
- if res or age > self.updateTarballAge:
- tar = self.computeTarballOptions() + ['-cvf', self.tarball, ".repo"]
- res = yield self._Cmd(tar, abandonOnFailure=False)
- if res: # error with tarball.. erase tarball, but dont fail
- yield self._Cmd(["rm", "-f", self.tarball], abandonOnFailure=False)
-
- # a simple shell script to gather all cleanup tweaks...
- # doing them one by one just complicate the stuff
- # and messup the stdio log
- def _getCleanupCommand(self):
- """also used by tests for expectations"""
- return textwrap.dedent("""\
- set -v
- if [ -d .repo/manifests ]
- then
- # repo just refuse to run if manifest is messed up
- # so ensure we are in a known state
- cd .repo/manifests
- rm -f .git/index.lock
- git fetch origin
- git reset --hard remotes/origin/%(manifestBranch)s
- git config branch.default.merge %(manifestBranch)s
- cd ..
- ln -sf manifests/%(manifestFile)s manifest.xml
- cd ..
- fi
- repo forall -c rm -f .git/index.lock
- repo forall -c git clean -f -d -x 2>/dev/null
- repo forall -c git reset --hard HEAD 2>/dev/null
- rm -f %(workdir)s/.repo/project.list
- """) % self.__dict__
-
- def doCleanup(self):
- command = self._getCleanupCommand()
- return self._Cmd(["bash", "-c", command], abandonOnFailure=False)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py
deleted file mode 100644
index a49e9e07..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py
+++ /dev/null
@@ -1,381 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import xml.dom.minidom
-import xml.parsers.expat
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.config import ConfigErrors
-
-class SVN(Source):
- """I perform Subversion checkout/update operations."""
-
- name = 'svn'
-
- renderables = [ 'repourl' ]
- possible_modes = ('incremental', 'full')
- possible_methods = ('clean', 'fresh', 'clobber', 'copy', 'export', None)
-
- def __init__(self, repourl=None, mode='incremental',
- method=None, username=None,
- password=None, extra_args=None, keep_on_purge=None,
- depth=None, preferLastChangedRev=False, **kwargs):
-
- self.repourl = repourl
- self.username = username
- self.password = password
- self.extra_args = extra_args
- self.keep_on_purge = keep_on_purge or []
- self.depth = depth
- self.method = method
- self.mode = mode
- self.preferLastChangedRev = preferLastChangedRev
- Source.__init__(self, **kwargs)
- errors = []
- if self.mode not in self.possible_modes:
- errors.append("mode %s is not one of %s" % (self.mode, self.possible_modes))
- if self.method not in self.possible_methods:
- errors.append("method %s is not one of %s" % (self.method, self.possible_methods))
-
- if repourl is None:
- errors.append("you must provide repourl")
-
- if errors:
- raise ConfigErrors(errors)
-
- def startVC(self, branch, revision, patch):
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkSvn()
- def checkInstall(svnInstalled):
- if not svnInstalled:
- raise BuildSlaveTooOldError("SVN is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'full':
- d.addCallback(self.full)
- elif self.mode == 'incremental':
- d.addCallback(self.incremental)
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self, _):
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method in ['copy', 'export']:
- yield self.copy()
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- # blow away the old (un-updatable) directory
- yield self.runRmdir(self.workdir)
-
- # then do a checkout
- checkout_cmd = ['checkout', self.repourl, '.']
- if self.revision:
- checkout_cmd.extend(["--revision", str(self.revision)])
- yield self._dovccmd(checkout_cmd)
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
-
- @defer.inlineCallbacks
- def incremental(self, _):
- updatable = yield self._sourcedirIsUpdatable()
-
- if not updatable:
- # blow away the old (un-updatable) directory
- yield self.runRmdir(self.workdir)
-
- # and plan to do a checkout
- command = ['checkout', self.repourl, '.']
- else:
- # otherwise, do an update
- command = ['update']
-
- if self.revision:
- command.extend(['--revision', str(self.revision)])
-
- yield self._dovccmd(command)
-
- @defer.inlineCallbacks
- def clobber(self):
- yield self.runRmdir(self.workdir)
-
- checkout_cmd = ['checkout', self.repourl, '.']
- if self.revision:
- checkout_cmd.extend(["--revision", str(self.revision)])
-
- yield self._dovccmd(checkout_cmd)
-
- def fresh(self):
- d = self.purge(True)
- cmd = ['update']
- if self.revision:
- cmd.extend(['--revision', str(self.revision)])
- d.addCallback(lambda _: self._dovccmd(cmd))
- return d
-
- def clean(self):
- d = self.purge(False)
- cmd = ['update']
- if self.revision:
- cmd.extend(['--revision', str(self.revision)])
- d.addCallback(lambda _: self._dovccmd(cmd))
- return d
-
- @defer.inlineCallbacks
- def copy(self):
- yield self.runRmdir(self.workdir)
-
- # temporarily set workdir = 'source' and do an incremental checkout
- try:
- old_workdir = self.workdir
- self.workdir = 'source'
- yield self.incremental(None)
- except: # finally doesn't work in python-2.4
- self.workdir = old_workdir
- raise
- self.workdir = old_workdir
-
- # if we're copying, copy; otherwise, export from source to build
- if self.method == 'copy':
- cmd = buildstep.RemoteCommand('cpdir',
- { 'fromdir': 'source', 'todir':self.workdir,
- 'logEnviron': self.logEnviron })
- else:
- export_cmd = ['svn', 'export']
- if self.revision:
- export_cmd.extend(["--revision", str(self.revision)])
- export_cmd.extend(['source', self.workdir])
-
- cmd = buildstep.RemoteShellCommand('', export_cmd,
- env=self.env, logEnviron=self.logEnviron, timeout=self.timeout)
- cmd.useLog(self.stdio_log, False)
-
- yield self.runCommand(cmd)
-
- if cmd.didFail():
- raise buildstep.BuildStepFailed()
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
-
- def _dovccmd(self, command, collectStdout=False):
- assert command, "No command specified"
- command.extend(['--non-interactive', '--no-auth-cache'])
- if self.username:
- command.extend(['--username', self.username])
- if self.password:
- command.extend(['--password', self.password])
- if self.depth:
- command.extend(['--depth', self.depth])
- if self.extra_args:
- command.extend(self.extra_args)
-
- cmd = buildstep.RemoteShellCommand(self.workdir, ['svn'] + command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting SVN command : svn %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- @defer.inlineCallbacks
- def _sourcedirIsUpdatable(self):
- # first, perform a stat to ensure that this is really an svn directory
- res = yield self.pathExists(self.build.path_module.join(self.workdir, '.svn'))
- if not res:
- defer.returnValue(False)
- return
-
- # then run 'svn info --xml' to check that the URL matches our repourl
- stdout = yield self._dovccmd(['info', '--xml'], collectStdout=True)
-
- try:
- stdout_xml = xml.dom.minidom.parseString(stdout)
- extractedurl = stdout_xml.getElementsByTagName('url')[0].firstChild.nodeValue
- except xml.parsers.expat.ExpatError:
- msg = "Corrupted xml, aborting step"
- self.stdio_log.addHeader(msg)
- raise buildstep.BuildStepFailed()
- defer.returnValue(extractedurl == self.repourl)
- return
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _):
- # if this was a full/export, then we need to check svnversion in the
- # *source* directory, not the build directory
- svnversion_dir = self.workdir
- if self.mode == 'full' and self.method == 'export':
- svnversion_dir = 'source'
- cmd = buildstep.RemoteShellCommand(svnversion_dir, ['svn', 'info', '--xml'],
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=True)
- cmd.useLog(self.stdio_log, False)
- yield self.runCommand(cmd)
-
- stdout = cmd.stdout
- try:
- stdout_xml = xml.dom.minidom.parseString(stdout)
- except xml.parsers.expat.ExpatError:
- msg = "Corrupted xml, aborting step"
- self.stdio_log.addHeader(msg)
- raise buildstep.BuildStepFailed()
-
- revision = None
- if self.preferLastChangedRev:
- try:
- revision = stdout_xml.getElementsByTagName('commit')[0].attributes['revision'].value
- except (KeyError, IndexError):
- msg =("SVN.parseGotRevision unable to detect Last Changed Rev in"
- " output of svn info")
- log.msg(msg)
- # fall through and try to get 'Revision' instead
-
- if revision is None:
- try:
- revision = stdout_xml.getElementsByTagName('entry')[0].attributes['revision'].value
- except (KeyError, IndexError):
- msg =("SVN.parseGotRevision unable to detect revision in"
- " output of svn info")
- log.msg(msg)
- raise buildstep.BuildStepFailed()
-
- msg = "Got SVN revision %s" % (revision, )
- self.stdio_log.addHeader(msg)
- self.updateSourceProperty('got_revision', revision)
-
- defer.returnValue(cmd.rc)
-
-
- def purge(self, ignore_ignores):
- """Delete everything that shown up on status."""
- command = ['status', '--xml']
- if ignore_ignores:
- command.append('--no-ignore')
- d = self._dovccmd(command, collectStdout=True)
- def parseAndRemove(stdout):
- files = []
- for filename in self.getUnversionedFiles(stdout, self.keep_on_purge):
- filename = self.workdir+'/'+str(filename)
- files.append(filename)
- if len(files) == 0:
- d = defer.succeed(0)
- else:
- if self.slaveVersionIsOlderThan('rmdir', '2.14'):
- d = self.removeFiles(files)
- else:
- d = self.runRmdir(files, abandonOnFailure=False)
- return d
- d.addCallback(parseAndRemove)
- def evaluateCommand(rc):
- if rc != 0:
- log.msg("Failed removing files")
- raise buildstep.BuildStepFailed()
- return rc
- d.addCallback(evaluateCommand)
- return d
-
- @staticmethod
- def getUnversionedFiles(xmlStr, keep_on_purge):
- try:
- result_xml = xml.dom.minidom.parseString(xmlStr)
- except xml.parsers.expat.ExpatError:
- log.err("Corrupted xml, aborting step")
- raise buildstep.BuildStepFailed()
-
- for entry in result_xml.getElementsByTagName('entry'):
- (wc_status,) = entry.getElementsByTagName('wc-status')
- if wc_status.getAttribute('item') == 'external':
- continue
- if wc_status.getAttribute('item') == 'missing':
- continue
- filename = entry.getAttribute('path')
- if filename in keep_on_purge or filename == '':
- continue
- yield filename
-
- @defer.inlineCallbacks
- def removeFiles(self, files):
- for filename in files:
- res = yield self.runRmdir(filename, abandonOnFailure=False)
- if res:
- defer.returnValue(res)
- return
- defer.returnValue(0)
-
- def checkSvn(self):
- cmd = buildstep.RemoteShellCommand(self.workdir, ['svn', '--version'],
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluate(cmd):
- if cmd.rc != 0:
- return False
- return True
- d.addCallback(lambda _: evaluate(cmd))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes or None in [c.revision for c in changes]:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py
deleted file mode 100644
index ecf4d1a3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py
+++ /dev/null
@@ -1,640 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot import config as bbconfig
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-def isTrueOrIsExactlyZero(v):
- # nonzero values are true...
- if v:
- return True
-
- # ... and True for the number zero, but we have to
- # explicitly guard against v==False, since
- # isinstance(False, int) is surprisingly True
- if isinstance(v, int) and v is not False:
- return True
-
- # all other false-ish values are false
- return False
-
-git_describe_flags = [
- # on or off
- ('all', lambda v: ['--all'] if v else None),
- ('always', lambda v: ['--always'] if v else None),
- ('contains', lambda v: ['--contains'] if v else None),
- ('debug', lambda v: ['--debug'] if v else None),
- ('long', lambda v: ['--long'] if v else None),
- ('exact-match', lambda v: ['--exact-match'] if v else None),
- ('tags', lambda v: ['--tags'] if v else None),
- # string parameter
- ('match', lambda v: ['--match', v] if v else None),
- # numeric parameter
- ('abbrev', lambda v: ['--abbrev=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- ('candidates', lambda v: ['--candidates=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- # optional string parameter
- ('dirty', lambda v: ['--dirty'] if (v is True or v=='') else None),
- ('dirty', lambda v: ['--dirty=%s' % v] if (v and v is not True) else None),
-]
-
-class YoctoGit(Source):
- """ Class for Git specific to the YoctoProject. Now with smarts and weird
- Yocto specific stuff like defining source directories """
- name='yoctogit'
- renderables = [ "repourl"]
-
- def __init__(self, repourl=None, branch='HEAD', mode='incremental',
- method=None, submodules=False, shallow=False, progress=False,
- retryFetch=False, clobberOnFailure=False, getDescription=False,
- workdir='build', layername=None, storedir="/tmp/junk", mirrordir=None,
- config=None, **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the git repository
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type submodules: boolean
- @param submodules: Whether or not to update (and initialize)
- git submodules.
-
- @type mode: string
- @param mode: Type of checkout. Described in docs.
-
- @type method: string
- @param method: Full builds can be done is different ways. This parameter
- specifies which method to use.
-
- @type progress: boolean
- @param progress: Pass the --progress option when fetching. This
- can solve long fetches getting killed due to
- lack of output, but requires Git 1.7.2+.
- @type shallow: boolean
- @param shallow: Use a shallow or clone, if possible
-
- @type retryFetch: boolean
- @param retryFetch: Retry fetching before failing source checkout.
-
- @type getDescription: boolean or dict
- @param getDescription: Use 'git describe' to describe the fetched revision
-
- @type workdir: string
- @param workdir: Used to indicate the destination of the copy of srcdir
-
- @type storedir: string
- @param storedir: where the old build dir gets moved to during a movecopy
-
- @type layername: string
- @param layername: Used in the yocto-autobuilder's movecopy as a way
- of moving the old build directory to a unique area for outside cleanup/
- review.
-
- @type config: dict
- @param config: Git configuration options to enable when running git
- """
- if not getDescription and not isinstance(getDescription, dict):
- getDescription = False
-
- self.branch = branch
- self.method = method
- self.prog = progress
- self.repourl = repourl.rstrip('/').strip()
- self.retryFetch = retryFetch
- self.submodules = submodules
- self.shallow = shallow
- self.workdir = workdir
- self.storedir = storedir
- self.mirrordir = mirrordir
- self.layername = layername
- self.fetchcount = 0
- self.clobberOnFailure = clobberOnFailure
- self.mode = mode
- self.getDescription = getDescription
- self.config = config
- self.timeout = 10*60
- # We no longer pass srcdir in. There are way too many ways to hang
- # yourself by doing that.
- if self.mirrordir:
- if self.method in ['barecopy', 'movecopy']:
- self.srcdir='source/'+self.repourl
- else:
- if "poky" in self.layername or \
- "oecore" in self.layername or \
- "eclipse" in self.layername:
- self.srcdir = "build"
- else:
- self.srcdir = 'build/'+self.layername
- else:
- self.srcdir = 'source'
- if self.method in ['barecopy', 'movecopy']:
- self.workdir='source/'+self.repourl
- else:
- self.workdir = 'build'
-
- Source.__init__(self, **kwargs)
-
- if self.mode not in ['incremental', 'full']:
- bbconfig.error("Git: mode must be 'incremental' or 'full'.")
- if not self.repourl:
- bbconfig.error("Git: must provide repourl.")
- if (self.mode == 'full' and
- self.method not in ['clean', 'fresh', 'clobber', 'movecopy', 'barecopy', None]):
- bbconfig.error("Git: invalid method for mode 'full'.")
- if self.shallow and (self.mode != 'full' or self.method != 'clobber'):
- bbconfig.error("Git: shallow only possible with mode 'full' and method 'clobber'.")
- if not isinstance(self.getDescription, (bool, dict)):
- bbconfig.error("Git: getDescription must be a boolean or a dict.")
-
- def startVC(self, branch, revision, patch):
- self.branch = branch or 'HEAD'
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkGit()
- def checkInstall(gitInstalled):
- if not gitInstalled:
- raise BuildSlaveTooOldError("git is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
- elif self.mode == 'full':
- d.addCallback(lambda _: self.full())
- if patch:
- d.addCallback(self.patch, patch)
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.parseCommitDescription)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self):
- updatable = yield self._sourcedirIsUpdatable()
- self.mirrorexists = yield self._mirrorExists()
-
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method == 'barecopy':
- yield self.barecopy()
- yield self._srccopy()
- return
- elif self.method == 'movecopy':
- yield self.movecopy()
- yield self._srccopy()
- return
-
- if not updatable:
- log.msg("No git repo present, making full clone")
- yield self._fullCloneOrFallback()
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
-
- @defer.inlineCallbacks
- def incremental(self):
- updatable = yield self._sourcedirIsUpdatable()
- self.mirrorexists = yield self._mirrorExists()
-
- # if not updateable, do a full checkout
- if not updatable:
- yield self._fullCloneOrFallback()
- return
-
- # Just fetch everything and bring it up to date. This is because if you
- # pass "HEAD" in, you're not certain to get the most upto date as that ref
- # should always exist.
-
- yield self._fetchOrFallback(None)
- yield self._updateSubmodule(None)
-
- def clean(self):
- command = ['clean', '-f', '-d']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def clobber(self):
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone(shallowClone=self.shallow))
- return d
-
- def fresh(self):
- command = ['clean', '-f', '-d', '-x']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def barecopy(self):
- cmd = buildstep.RemoteCommand('mkdir', {'dir': 'build',
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- d.addCallback(lambda _: evaluateCommand(cmd))
- d.addCallback(lambda _: self.incremental())
- return d
-
- def movecopy(self):
- # This relies on an external method of cleaning up the todir, like a cron job
- # it can be rather disk space intensive.
- import time
- import random
-
- # Let's make the todir difficult to have duplicate dir names. This
- # method probably won't work correctly crossing filesystems, so utilize
- # movecopy with caution.
-
- cmd = buildstep.RemoteCommand('mv', {'fromdir': 'build',
- 'todir': self.storedir + '/' + self.getProperty("DEST") + '/' +
- str(int(time.time())) + '-' +
- str(random.randrange(100, 100000, 2)) +
- self.layername,
- 'logEnviron':self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- d.addCallback(lambda _: evaluateCommand(cmd))
- d.addCallback(lambda _: self.incremental())
- return d
-
- # Buildbot's standard copy has been removed from yoctogit.
- # We use _srccopy from either movecopy or barecopy as a callback
- # this uses self.srcdir to copy to the build dir.
-
- def _srccopy(self):
- if "poky" in self.layername or \
- "oecore" in self.layername or \
- "eclipse" in self.layername:
- todir = "build"
- else:
- todir = "build/" + self.layername
- fromdir='source/'+self.repourl
-
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': fromdir,
- 'todir': todir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- log.msg("Closing log, sending result of the command %s " % \
- (self.cmd))
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _=None):
- stdout = yield self._dovccmd(['rev-parse', 'HEAD'], collectStdout=True)
- revision = stdout.strip()
- if len(revision) != 40:
- raise buildstep.BuildStepFailed()
- log.msg("Got Git revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
-
- defer.returnValue(0)
-
- @defer.inlineCallbacks
- def parseCommitDescription(self, _=None):
- if self.getDescription==False: # dict() should not return here
- defer.returnValue(0)
- return
-
- cmd = ['describe']
- if isinstance(self.getDescription, dict):
- for opt, arg in git_describe_flags:
- opt = self.getDescription.get(opt, None)
- arg = arg(opt)
- if arg:
- cmd.extend(arg)
- cmd.append('HEAD')
-
- try:
- stdout = yield self._dovccmd(cmd, collectStdout=True)
- desc = stdout.strip()
- self.updateSourceProperty('commit-description', desc)
- except:
- pass
-
- defer.returnValue(0)
-
- def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False, initialStdin=None):
- full_command = ['git']
- if self.config is not None:
- for name, value in self.config.iteritems():
- full_command.append('-c')
- full_command.append('%s=%s' % (name, value))
- full_command.extend(command)
- if self.method in ['barecopy', 'movecopy']:
- self.workdir='source/'+self.repourl
- else:
- self.workdir = 'build'
- cmd = buildstep.RemoteShellCommand(self.workdir,
- full_command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting git command : git %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _dosimplecmd(self, command, abandonOnFailure=True, collectStdout=False, initialStdin=None):
- if self.method in ['barecopy', 'movecopy']:
- self.workdir='source/'+self.repourl
- else:
- self.workdir = 'build'
- cmd = buildstep.RemoteShellCommand(self.workdir,
- command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting simple command : %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _fetch(self, _):
- # We can run git gc on the core clone directory which means references can disappear
- # leading to fetch failures like:
- # error: refs/heads/master-next does not point to a valid object!
- # error: refs/remotes/master-next does not point to a valid object!
- # fatal: bad object HEAD
- # error: git://git.yoctoproject.org/poky did not send all necessary objects
- # However if we remove all heads, we can't hit that error!
-
- command = ['rm', '.git/refs/', '-rf']
- d = self._dosimplecmd(command)
-
- def mkdir(res):
- if res != 0:
- return res
- mkdircommand = ['mkdir', '.git/refs/']
- return self._dosimplecmd(mkdircommand)
- d.addCallback(mkdir)
-
- def fetch(res):
- if res != 0:
- return res
- gitcommand = ['fetch', '-t', '--prune', self.repourl, '+refs/heads/' + self.branch + ':refs/remotes/' + self.branch]
- # If the 'progress' option is set, tell git fetch to output
- # progress information to the log. This can solve issues with
- # long fetches killed due to lack of output, but only works
- # with Git 1.7.2 or later.
- if self.prog:
- gitcommand.append('--progress')
- return self._dovccmd(gitcommand)
- d.addCallback(fetch)
-
- def checkout(res):
- if res != 0:
- return res
- if self.revision and self.revision != 'HEAD':
- rev = self.revision
- else:
- rev = 'FETCH_HEAD'
- gitcommand = ['reset', '--hard', rev, '--']
- abandonOnFailure = not self.retryFetch and not self.clobberOnFailure
- return self._dovccmd(gitcommand, abandonOnFailure)
- d.addCallback(checkout)
-
- def gitclean(res):
- if res != 0:
- return res
- gitcommand = ['clean', '-d', '-f']
- return self._dovccmd(gitcommand)
- d.addCallback(gitclean)
-
- def renameBranch(res):
- if res != 0:
- return res
- d = self._dovccmd(['branch', '-M', self.branch], abandonOnFailure=False)
- # Ignore errors
- d.addCallback(lambda _: res)
- return d
-
- if self.branch != 'HEAD':
- d.addCallback(renameBranch)
- return d
-
- @defer.inlineCallbacks
- def _fetchOrFallback(self, _):
- """
- Handles fallbacks for failure of fetch,
- wrapper for self._fetch
- """
- res = yield self._fetch(None)
- if res == 0:
- defer.returnValue(res)
- return
- if self.retryFetch:
- res = yield self._fetch(None)
- if res == 0:
- defer.returnValue(res)
- return
- if self.clobberOnFailure:
- yield self._doClobber()
- yield self._fullClone()
- else:
- raise buildstep.BuildStepFailed()
-
- def _fullClone(self, shallowClone=False):
- """Perform full clone and checkout to the revision if specified
- In the case of shallow clones if any of the step fail abort whole build step.
- """
- args = []
- if self.branch != 'HEAD':
- args += ['--branch', self.branch]
- if shallowClone:
- args += ['--depth', '1']
- command = ['clone'] + args + [self.repourl, '.']
-
- mirror = None
- if self.mirrordir:
- mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/"
- if self.mirrorexists:
- command = ['clone'] + ["-s", "-n"] + [mirror, '.']
- else:
- command = ['clone'] + ["-s", "-n"] + [self.repourl, '.']
-
- #Fix references
- if self.prog:
- command.append('--progress')
-
- # If it's a shallow clone abort build step
- d = self._dovccmd(command, shallowClone)
-
- if mirror:
- d.addCallback(lambda _: self._fetch(None))
-
- # If revision specified checkout that revision
- if self.revision:
- d.addCallback(lambda _: self._dovccmd(['reset', '--hard',
- self.revision, '--'],
- shallowClone))
- # init and update submodules, recurisively. If there's not recursion
- # it will not do it.
- if self.submodules:
- d.addCallback(lambda _: self._dovccmd(['submodule', 'update',
- '--init', '--recursive'],
- shallowClone))
- return d
-
- def _fullCloneOrFallback(self):
- """Wrapper for _fullClone(). In the case of failure, if clobberOnFailure
- is set to True remove the build directory and try a full clone again.
- """
-
- d = self._fullClone()
- def clobber(res):
- if res != 0:
- if self.clobberOnFailure:
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone())
- return d
- else:
- raise buildstep.BuildStepFailed()
- else:
- return res
- d.addCallback(clobber)
- return d
-
- def _doClobber(self):
- """Remove the work directory"""
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.git'))
-
- def _mirrorExists(self):
- if self.mirrordir:
- mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/"
- return self.pathExists(self.build.path_module.join(mirror, '.git'))
- else:
- return None
-
- def _updateSubmodule(self, _):
- if self.submodules:
- return self._dovccmd(['submodule', 'update', '--init', '--recursive'])
- else:
- return defer.succeed(0)
-
- def _cleanSubmodule(self, _):
- if self.submodules:
- command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
- if self.mode == 'full' and self.method == 'fresh':
- command.append('-x')
- return self._dovccmd(command)
- else:
- return defer.succeed(0)
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def checkGit(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def patch(self, _, patch):
- d = self._dovccmd(['apply', '--index', '-p', str(patch[0])],
- initialStdin=patch[1])
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py
deleted file mode 100644
index f1e5749c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-
-class SubunitShellCommand(ShellCommand):
- """A ShellCommand that sniffs subunit output.
- """
-
- def __init__(self, failureOnNoTests=False, *args, **kwargs):
- ShellCommand.__init__(self, *args, **kwargs)
- self.failureOnNoTests = failureOnNoTests
-
- # importing here gets around an import loop
- from buildbot.process import subunitlogobserver
-
- self.ioObverser = subunitlogobserver.SubunitLogObserver()
- self.addLogObserver('stdio', self.ioObverser)
- self.progressMetrics = self.progressMetrics + ('tests', 'tests failed')
-
- def commandComplete(self, cmd):
- # figure out all statistics about the run
- ob = self.ioObverser
- failures = len(ob.failures)
- errors = len(ob.errors)
- skips = len(ob.skips)
- total = ob.testsRun
-
- count = failures + errors
-
- text = [self.name]
- text2 = ""
-
- if not count:
- results = SUCCESS
- if total:
- text += ["%d %s" % \
- (total,
- total == 1 and "test" or "tests"),
- "passed"]
- else:
- if self.failureOnNoTests:
- results = FAILURE
- text += ["no tests", "run"]
- else:
- results = FAILURE
- text.append("Total %d test(s)" % total)
- if failures:
- text.append("%d %s" % \
- (failures,
- failures == 1 and "failure" or "failures"))
- if errors:
- text.append("%d %s" % \
- (errors,
- errors == 1 and "error" or "errors"))
- text2 = "%d %s" % (count, (count == 1 and 'test' or 'tests'))
-
-
- if skips:
- text.append("%d %s" % (skips,
- skips == 1 and "skip" or "skips"))
-
- #TODO: expectedFailures/unexpectedSuccesses
-
- self.results = results
- self.text = text
- self.text2 = [text2]
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- return self.results
-
- def createSummary(self, loog):
- ob = self.ioObverser
- problems = ""
- for test, err in ob.errors + ob.failures:
- problems += "%s\n%s" % (test.id(), err)
- if problems:
- self.addCompleteLog("problems", problems)
- warnings = ob.warningio.getvalue()
- if warnings:
- self.addCompleteLog("warnings", warnings)
-
- def getText(self, cmd, results):
- return self.text
- def getText2(self, cmd, results):
- return self.text2
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py
deleted file mode 100644
index a2f7007f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py
+++ /dev/null
@@ -1,632 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-
-import os.path, tarfile, tempfile
-try:
- from cStringIO import StringIO
- assert StringIO
-except ImportError:
- from StringIO import StringIO
-from twisted.spread import pb
-from twisted.python import log
-from buildbot.process import buildstep
-from buildbot.process.buildstep import BuildStep
-from buildbot.process.buildstep import SUCCESS, FAILURE, SKIPPED
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.util import json
-from buildbot.util.eventual import eventually
-from buildbot import config
-
-
-class _FileWriter(pb.Referenceable):
- """
- Helper class that acts as a file-object with write access
- """
-
- def __init__(self, destfile, maxsize, mode):
- # Create missing directories.
- destfile = os.path.abspath(destfile)
- dirname = os.path.dirname(destfile)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
-
- self.destfile = destfile
- self.mode = mode
- fd, self.tmpname = tempfile.mkstemp(dir=dirname)
- self.fp = os.fdopen(fd, 'wb')
- self.remaining = maxsize
-
- def remote_write(self, data):
- """
- Called from remote slave to write L{data} to L{fp} within boundaries
- of L{maxsize}
-
- @type data: C{string}
- @param data: String of data to write
- """
- if self.remaining is not None:
- if len(data) > self.remaining:
- data = data[:self.remaining]
- self.fp.write(data)
- self.remaining = self.remaining - len(data)
- else:
- self.fp.write(data)
-
- def remote_utime(self, accessed_modified):
- os.utime(self.destfile,accessed_modified)
-
- def remote_close(self):
- """
- Called by remote slave to state that no more data will be transfered
- """
- self.fp.close()
- self.fp = None
- # on windows, os.rename does not automatically unlink, so do it manually
- if os.path.exists(self.destfile):
- os.unlink(self.destfile)
- os.rename(self.tmpname, self.destfile)
- self.tmpname = None
- if self.mode is not None:
- os.chmod(self.destfile, self.mode)
-
- def cancel(self):
- # unclean shutdown, the file is probably truncated, so delete it
- # altogether rather than deliver a corrupted file
- fp = getattr(self, "fp", None)
- if fp:
- fp.close()
- os.unlink(self.destfile)
- if self.tmpname and os.path.exists(self.tmpname):
- os.unlink(self.tmpname)
-
-
-def _extractall(self, path=".", members=None):
- """Fallback extractall method for TarFile, in case it doesn't have its own."""
-
- import copy
-
- directories = []
-
- if members is None:
- members = self
-
- for tarinfo in members:
- if tarinfo.isdir():
- # Extract directories with a safe mode.
- directories.append(tarinfo)
- tarinfo = copy.copy(tarinfo)
- tarinfo.mode = 0700
- self.extract(tarinfo, path)
-
- # Reverse sort directories.
- directories.sort(lambda a, b: cmp(a.name, b.name))
- directories.reverse()
-
- # Set correct owner, mtime and filemode on directories.
- for tarinfo in directories:
- dirpath = os.path.join(path, tarinfo.name)
- try:
- self.chown(tarinfo, dirpath)
- self.utime(tarinfo, dirpath)
- self.chmod(tarinfo, dirpath)
- except tarfile.ExtractError, e:
- if self.errorlevel > 1:
- raise
- else:
- self._dbg(1, "tarfile: %s" % e)
-
-class _DirectoryWriter(_FileWriter):
- """
- A DirectoryWriter is implemented as a FileWriter, with an added post-processing
- step to unpack the archive, once the transfer has completed.
- """
-
- def __init__(self, destroot, maxsize, compress, mode):
- self.destroot = destroot
- self.compress = compress
-
- self.fd, self.tarname = tempfile.mkstemp()
- os.close(self.fd)
-
- _FileWriter.__init__(self, self.tarname, maxsize, mode)
-
- def remote_unpack(self):
- """
- Called by remote slave to state that no more data will be transfered
- """
- # Make sure remote_close is called, otherwise atomic rename wont happen
- self.remote_close()
-
- # Map configured compression to a TarFile setting
- if self.compress == 'bz2':
- mode='r|bz2'
- elif self.compress == 'gz':
- mode='r|gz'
- else:
- mode = 'r'
-
- # Support old python
- if not hasattr(tarfile.TarFile, 'extractall'):
- tarfile.TarFile.extractall = _extractall
-
- # Unpack archive and clean up after self
- archive = tarfile.open(name=self.tarname, mode=mode)
- archive.extractall(path=self.destroot)
- archive.close()
- os.remove(self.tarname)
-
-def makeStatusRemoteCommand(step, remote_command, args):
- self = buildstep.RemoteCommand(remote_command, args, decodeRC={None:SUCCESS, 0:SUCCESS})
- callback = lambda arg: step.step_status.addLog('stdio')
- self.useLogDelayed('stdio', callback, True)
- return self
-
-class _TransferBuildStep(BuildStep):
- """
- Base class for FileUpload and FileDownload to factor out common
- functionality.
- """
- DEFAULT_WORKDIR = "build" # is this redundant?
-
- renderables = [ 'workdir' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def setDefaultWorkdir(self, workdir):
- if self.workdir is None:
- self.workdir = workdir
-
- def _getWorkdir(self):
- if self.workdir is None:
- workdir = self.DEFAULT_WORKDIR
- else:
- workdir = self.workdir
- return workdir
-
- def interrupt(self, reason):
- self.addCompleteLog('interrupt', str(reason))
- if self.cmd:
- d = self.cmd.interrupt(reason)
- return d
-
- def finished(self, result):
- # Subclasses may choose to skip a transfer. In those cases, self.cmd
- # will be None, and we should just let BuildStep.finished() handle
- # the rest
- if result == SKIPPED:
- return BuildStep.finished(self, SKIPPED)
-
- if self.cmd.didFail():
- return BuildStep.finished(self, FAILURE)
- return BuildStep.finished(self, SUCCESS)
-
-
-class FileUpload(_TransferBuildStep):
-
- name = 'upload'
-
- renderables = [ 'slavesrc', 'masterdest', 'url' ]
-
- def __init__(self, slavesrc, masterdest,
- workdir=None, maxsize=None, blocksize=16*1024, mode=None,
- keepstamp=False, url=None,
- **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.slavesrc = slavesrc
- self.masterdest = masterdest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if not isinstance(mode, (int, type(None))):
- config.error(
- 'mode must be an integer or None')
- self.mode = mode
- self.keepstamp = keepstamp
- self.url = url
-
- def start(self):
- version = self.slaveVersion("uploadFile")
-
- if not version:
- m = "slave is too old, does not know about uploadFile"
- raise BuildSlaveTooOldError(m)
-
- source = self.slavesrc
- masterdest = self.masterdest
- # we rely upon the fact that the buildmaster runs chdir'ed into its
- # basedir to make sure that relative paths in masterdest are expanded
- # properly. TODO: maybe pass the master's basedir all the way down
- # into the BuildStep so we can do this better.
- masterdest = os.path.expanduser(masterdest)
- log.msg("FileUpload started, from slave %r to master %r"
- % (source, masterdest))
-
- self.step_status.setText(['uploading', os.path.basename(source)])
- if self.url is not None:
- self.addURL(os.path.basename(masterdest), self.url)
-
- # we use maxsize to limit the amount of data on both sides
- fileWriter = _FileWriter(masterdest, self.maxsize, self.mode)
-
- if self.keepstamp and self.slaveVersionIsOlderThan("uploadFile","2.13"):
- m = ("This buildslave (%s) does not support preserving timestamps. "
- "Please upgrade the buildslave." % self.build.slavename )
- raise BuildSlaveTooOldError(m)
-
- # default arguments
- args = {
- 'slavesrc': source,
- 'workdir': self._getWorkdir(),
- 'writer': fileWriter,
- 'maxsize': self.maxsize,
- 'blocksize': self.blocksize,
- 'keepstamp': self.keepstamp,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'uploadFile', args)
- d = self.runCommand(self.cmd)
- @d.addErrback
- def cancel(res):
- fileWriter.cancel()
- return res
- d.addCallback(self.finished).addErrback(self.failed)
-
-
-class DirectoryUpload(_TransferBuildStep):
-
- name = 'upload'
-
- renderables = [ 'slavesrc', 'masterdest', 'url' ]
-
- def __init__(self, slavesrc, masterdest,
- workdir=None, maxsize=None, blocksize=16*1024,
- compress=None, url=None, **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.slavesrc = slavesrc
- self.masterdest = masterdest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if compress not in (None, 'gz', 'bz2'):
- config.error(
- "'compress' must be one of None, 'gz', or 'bz2'")
- self.compress = compress
- self.url = url
-
- def start(self):
- version = self.slaveVersion("uploadDirectory")
-
- if not version:
- m = "slave is too old, does not know about uploadDirectory"
- raise BuildSlaveTooOldError(m)
-
- source = self.slavesrc
- masterdest = self.masterdest
- # we rely upon the fact that the buildmaster runs chdir'ed into its
- # basedir to make sure that relative paths in masterdest are expanded
- # properly. TODO: maybe pass the master's basedir all the way down
- # into the BuildStep so we can do this better.
- masterdest = os.path.expanduser(masterdest)
- log.msg("DirectoryUpload started, from slave %r to master %r"
- % (source, masterdest))
-
- self.step_status.setText(['uploading', os.path.basename(source)])
- if self.url is not None:
- self.addURL(os.path.basename(masterdest), self.url)
-
- # we use maxsize to limit the amount of data on both sides
- dirWriter = _DirectoryWriter(masterdest, self.maxsize, self.compress, 0600)
-
- # default arguments
- args = {
- 'slavesrc': source,
- 'workdir': self._getWorkdir(),
- 'writer': dirWriter,
- 'maxsize': self.maxsize,
- 'blocksize': self.blocksize,
- 'compress': self.compress
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'uploadDirectory', args)
- d = self.runCommand(self.cmd)
- @d.addErrback
- def cancel(res):
- dirWriter.cancel()
- return res
- d.addCallback(self.finished).addErrback(self.failed)
-
- def finished(self, result):
- # Subclasses may choose to skip a transfer. In those cases, self.cmd
- # will be None, and we should just let BuildStep.finished() handle
- # the rest
- if result == SKIPPED:
- return BuildStep.finished(self, SKIPPED)
-
- if self.cmd.didFail():
- return BuildStep.finished(self, FAILURE)
- return BuildStep.finished(self, SUCCESS)
-
-class _FileReader(pb.Referenceable):
- """
- Helper class that acts as a file-object with read access
- """
-
- def __init__(self, fp):
- self.fp = fp
-
- def remote_read(self, maxlength):
- """
- Called from remote slave to read at most L{maxlength} bytes of data
-
- @type maxlength: C{integer}
- @param maxlength: Maximum number of data bytes that can be returned
-
- @return: Data read from L{fp}
- @rtype: C{string} of bytes read from file
- """
- if self.fp is None:
- return ''
-
- data = self.fp.read(maxlength)
- return data
-
- def remote_close(self):
- """
- Called by remote slave to state that no more data will be transfered
- """
- if self.fp is not None:
- self.fp.close()
- self.fp = None
-
-
-class FileDownload(_TransferBuildStep):
-
- name = 'download'
-
- renderables = [ 'mastersrc', 'slavedest' ]
-
- def __init__(self, mastersrc, slavedest,
- workdir=None, maxsize=None, blocksize=16*1024, mode=None,
- **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.mastersrc = mastersrc
- self.slavedest = slavedest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if not isinstance(mode, (int, type(None))):
- config.error(
- 'mode must be an integer or None')
- self.mode = mode
-
- def start(self):
- version = self.slaveVersion("downloadFile")
- if not version:
- m = "slave is too old, does not know about downloadFile"
- raise BuildSlaveTooOldError(m)
-
- # we are currently in the buildmaster's basedir, so any non-absolute
- # paths will be interpreted relative to that
- source = os.path.expanduser(self.mastersrc)
- slavedest = self.slavedest
- log.msg("FileDownload started, from master %r to slave %r" %
- (source, slavedest))
-
- self.step_status.setText(['downloading', "to",
- os.path.basename(slavedest)])
-
- # setup structures for reading the file
- try:
- fp = open(source, 'rb')
- except IOError:
- # if file does not exist, bail out with an error
- self.addCompleteLog('stderr',
- 'File %r not available at master' % source)
- # TODO: once BuildStep.start() gets rewritten to use
- # maybeDeferred, just re-raise the exception here.
- eventually(BuildStep.finished, self, FAILURE)
- return
- fileReader = _FileReader(fp)
-
- # default arguments
- args = {
- 'slavedest': slavedest,
- 'maxsize': self.maxsize,
- 'reader': fileReader,
- 'blocksize': self.blocksize,
- 'workdir': self._getWorkdir(),
- 'mode': self.mode,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'downloadFile', args)
- d = self.runCommand(self.cmd)
- d.addCallback(self.finished).addErrback(self.failed)
-
-class DirectoryDownload(_TransferBuildStep):
-
- name = 'download'
-
- renderables = [ 'mastersrc', 'slavedest' ]
-
- def __init__(self, mastersrc, slavedest,
- workdir=None, maxsize=None, blocksize=16*1024,
- compress=None, mode=None, **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.mastersrc = mastersrc
- self.slavedest = slavedest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if compress not in (None, 'gz', 'bz2'):
- config.error(
- "'compress' must be one of None, 'gz', or 'bz2'")
- self.compress = compress
- self.mode = mode
-
- def start(self):
- version = self.slaveVersion("downloadDirectory")
-
- if not version:
- m = "slave is too old, does not know about downloadDirectory"
- raise BuildSlaveTooOldError(m)
-
- # we rely upon the fact that the buildmaster runs chdir'ed into its
- # basedir to make sure that relative paths in mastersrc are expanded
- # properly. TODO: maybe pass the master's basedir all the way down
- # into the BuildStep so we can do this better.
- source = os.path.expanduser(self.mastersrc)
-
- slavedest = self.slavedest
-
- log.msg("DirectoryDownload started, from master %r to slave %r"
- % (source, slavedest))
-
- self.step_status.setText(['downloading', "to", slavedest])
-
- # setup structures for reading the file
- try:
- fd, self.tarname = tempfile.mkstemp()
- fileobj = os.fdopen(fd, 'w')
- if self.compress == 'bz2':
- mode='w|bz2'
- elif self.compress == 'gz':
- mode='w|gz'
- else:
- mode = 'w'
- archive = tarfile.open(name=self.tarname, mode=mode, fileobj=fileobj)
- archive.add(source, '')
- archive.close()
- fileobj.close()
-
- fp = open(self.tarname, 'rb')
- except IOError:
- # if file does not exist, bail out with an error
- self.addCompleteLog('stderr',
- 'Directory %r not available at master' % source)
- # TODO: once BuildStep.start() gets rewritten to use
- # maybeDeferred, just re-raise the exception here.
- eventually(BuildStep.finished, self, FAILURE)
- return
-
- fileReader = _FileReader(fp)
-
- # default arguments
- args = {
- 'slavedest': slavedest,
- 'maxsize': self.maxsize,
- 'reader': fileReader,
- 'blocksize': self.blocksize,
- 'workdir': self._getWorkdir(),
- 'mode': self.mode,
- 'compress': self.compress,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'downloadDirectory', args)
- d = self.runCommand(self.cmd)
- d.addCallback(self.finished).addErrback(self.failed)
-
-class StringDownload(_TransferBuildStep):
-
- name = 'string_download'
-
- renderables = [ 'slavedest', 's' ]
-
- def __init__(self, s, slavedest,
- workdir=None, maxsize=None, blocksize=16*1024, mode=None,
- **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.s = s
- self.slavedest = slavedest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if not isinstance(mode, (int, type(None))):
- config.error(
- 'mode must be an integer or None')
- self.mode = mode
-
- def start(self):
- version = self.slaveVersion("downloadFile")
- if not version:
- m = "slave is too old, does not know about downloadFile"
- raise BuildSlaveTooOldError(m)
-
- # we are currently in the buildmaster's basedir, so any non-absolute
- # paths will be interpreted relative to that
- slavedest = self.slavedest
- log.msg("StringDownload started, from master to slave %r" % slavedest)
-
- self.step_status.setText(['downloading', "to",
- os.path.basename(slavedest)])
-
- # setup structures for reading the file
- fp = StringIO(self.s)
- fileReader = _FileReader(fp)
-
- # default arguments
- args = {
- 'slavedest': slavedest,
- 'maxsize': self.maxsize,
- 'reader': fileReader,
- 'blocksize': self.blocksize,
- 'workdir': self._getWorkdir(),
- 'mode': self.mode,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'downloadFile', args)
- d = self.runCommand(self.cmd)
- d.addCallback(self.finished).addErrback(self.failed)
-
-class JSONStringDownload(StringDownload):
-
- name = "json_download"
-
- def __init__(self, o, slavedest, **buildstep_kwargs):
- if 's' in buildstep_kwargs:
- del buildstep_kwargs['s']
- s = json.dumps(o)
- StringDownload.__init__(self, s=s, slavedest=slavedest, **buildstep_kwargs)
-
-class JSONPropertiesDownload(StringDownload):
-
- name = "json_properties_download"
-
- def __init__(self, slavedest, **buildstep_kwargs):
- self.super_class = StringDownload
- if 's' in buildstep_kwargs:
- del buildstep_kwargs['s']
- StringDownload.__init__(self, s=None, slavedest=slavedest, **buildstep_kwargs)
-
- def start(self):
- properties = self.build.getProperties()
- props = {}
- for key, value, source in properties.asList():
- props[key] = value
-
- self.s = json.dumps(dict(
- properties=props,
- sourcestamp=self.build.getSourceStamp().asDict(),
- ),
- )
- return self.super_class.start(self)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py
deleted file mode 100644
index 11f6078a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.interfaces import ITriggerableScheduler
-from buildbot.process.buildstep import LoggingBuildStep, SUCCESS, FAILURE, EXCEPTION
-from buildbot.process.properties import Properties, Property
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import config
-
-class Trigger(LoggingBuildStep):
- name = "trigger"
-
- renderables = [ 'set_properties', 'schedulerNames', 'sourceStamps',
- 'updateSourceStamp', 'alwaysUseLatest' ]
-
- flunkOnFailure = True
-
- def __init__(self, schedulerNames=[], sourceStamp = None, sourceStamps = None,
- updateSourceStamp=None, alwaysUseLatest=False,
- waitForFinish=False, set_properties={},
- copy_properties=[], noWait=[], **kwargs):
- if not schedulerNames:
- config.error(
- "You must specify a scheduler to trigger")
- if (sourceStamp or sourceStamps) and (updateSourceStamp is not None):
- config.error(
- "You can't specify both sourceStamps and updateSourceStamp")
- if (sourceStamp or sourceStamps) and alwaysUseLatest:
- config.error(
- "You can't specify both sourceStamps and alwaysUseLatest")
- if alwaysUseLatest and (updateSourceStamp is not None):
- config.error(
- "You can't specify both alwaysUseLatest and updateSourceStamp"
- )
- self.schedulerNames = schedulerNames
- self.noWait = noWait
- self.sourceStamps = sourceStamps or []
- if sourceStamp:
- self.sourceStamps.append(sourceStamp)
- if updateSourceStamp is not None:
- self.updateSourceStamp = updateSourceStamp
- else:
- self.updateSourceStamp = not (alwaysUseLatest or self.sourceStamps)
- self.alwaysUseLatest = alwaysUseLatest
- self.waitForFinish = waitForFinish
- properties = {}
- properties.update(set_properties)
- for i in copy_properties:
- properties[i] = Property(i)
- self.set_properties = properties
- self.running = False
- self.ended = False
- LoggingBuildStep.__init__(self, **kwargs)
-
- def interrupt(self, reason):
- if self.running and not self.ended:
- self.step_status.setText(["interrupted"])
- return self.end(EXCEPTION)
-
- def end(self, result):
- if not self.ended:
- self.ended = True
- return self.finished(result)
-
- # Create the properties that are used for the trigger
- def createTriggerProperties(self):
- # make a new properties object from a dict rendered by the old
- # properties object
- trigger_properties = Properties()
- trigger_properties.update(self.set_properties, "Trigger")
- for prop in trigger_properties.asDict():
- if prop not in self.set_properties:
- self.set_properties[prop] = Property(prop)
- return trigger_properties
-
- # Get all scheduler instances that were configured
- # A tuple of (triggerables, invalidnames) is returned
- def getSchedulers(self):
- all_schedulers = self.build.builder.botmaster.parent.allSchedulers()
- all_schedulers = dict([(sch.name, sch) for sch in all_schedulers])
- invalid_schedulers = []
- triggered_schedulers = []
- # don't fire any schedulers if we discover an unknown one
- for scheduler in self.schedulerNames:
- scheduler = scheduler
- if all_schedulers.has_key(scheduler):
- sch = all_schedulers[scheduler]
- if ITriggerableScheduler.providedBy(sch):
- triggered_schedulers.append(sch)
- else:
- invalid_schedulers.append(scheduler)
- else:
- invalid_schedulers.append(scheduler)
-
- return (triggered_schedulers, invalid_schedulers)
-
- def prepareSourcestampListForTrigger(self):
- if self.sourceStamps:
- ss_for_trigger = {}
- for ss in self.sourceStamps:
- codebase = ss.get('codebase','')
- assert codebase not in ss_for_trigger, "codebase specified multiple times"
- ss_for_trigger[codebase] = ss
- return ss_for_trigger
-
- if self.alwaysUseLatest:
- return {}
-
- # start with the sourcestamps from current build
- ss_for_trigger = {}
- objs_from_build = self.build.getAllSourceStamps()
- for ss in objs_from_build:
- ss_for_trigger[ss.codebase] = ss.asDict()
-
- # overrule revision in sourcestamps with got revision
- if self.updateSourceStamp:
- got = self.build.build_status.getAllGotRevisions()
- for codebase in ss_for_trigger:
- if codebase in got:
- ss_for_trigger[codebase]['revision'] = got[codebase]
-
- return ss_for_trigger
-
- @defer.inlineCallbacks
- def start(self):
- # Get all triggerable schedulers and check if there are invalid schedules
- (triggered_schedulers, invalid_schedulers) = self.getSchedulers()
- if invalid_schedulers:
- self.step_status.setText(['not valid scheduler:'] + invalid_schedulers)
- self.end(FAILURE)
- return
-
- self.running = True
-
- props_to_set = self.createTriggerProperties()
-
- ss_for_trigger = self.prepareSourcestampListForTrigger()
-
- dl = []
- nowait = []
- triggered_names = []
- for sch in triggered_schedulers:
- if sch.name in self.noWait:
- import time
- time.sleep(5)
- nowait.append(sch.trigger(ss_for_trigger, set_props=props_to_set))
- else:
- dl.append(sch.trigger(ss_for_trigger, set_props=props_to_set))
- triggered_names.append(sch.name)
- self.step_status.setText(['triggered'] + triggered_names)
-
- for d in nowait:
- d.addErrback(log.err,
- '(ignored) while invoking Triggerable schedulers:')
-
- if self.waitForFinish:
- rclist = yield defer.DeferredList(dl, consumeErrors=1)
- else:
- # do something to handle errors
- for d in dl:
- d.addErrback(log.err,
- '(ignored) while invoking Triggerable schedulers:')
- rclist = None
- self.end(SUCCESS)
- return
-
- was_exception = was_failure = False
- brids = {}
- for was_cb, results in rclist:
- if isinstance(results, tuple):
- results, some_brids = results
- brids.update(some_brids)
-
- if not was_cb:
- was_exception = True
- log.err(results)
- continue
-
- if results==FAILURE:
- was_failure = True
-
- if was_exception:
- result = EXCEPTION
- elif was_failure:
- result = FAILURE
- else:
- result = SUCCESS
-
- if brids:
- master = self.build.builder.botmaster.parent
- def add_links(res):
- # reverse the dictionary lookup for brid to builder name
- brid_to_bn = dict((_brid,_bn) for _bn,_brid in brids.iteritems())
-
- for was_cb, builddicts in res:
- if was_cb:
- for build in builddicts:
- bn = brid_to_bn[build['brid']]
- num = build['number']
-
- url = master.status.getURLForBuild(bn, num)
- self.step_status.addURL("%s #%d" % (bn,num), url)
-
- return self.end(result)
-
- builddicts = [master.db.builds.getBuildsForRequest(br) for br in brids.values()]
- dl = defer.DeferredList(builddicts, consumeErrors=1)
- dl.addCallback(add_links)
-
- self.end(result)
- return
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py
deleted file mode 100644
index 5fad1f8d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py
+++ /dev/null
@@ -1,408 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# Visual studio steps
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from buildbot import config
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-
-import re
-
-
-def addEnvPath(env, name, value):
- """ concat a path for this name """
- try:
- oldval = env[name]
- if not oldval.endswith(';'):
- oldval = oldval + ';'
- except KeyError:
- oldval = ""
- if not value.endswith(';'):
- value = value + ';'
- env[name] = oldval + value
-
-class MSLogLineObserver(LogLineObserver):
-
- _re_delimiter = re.compile(r'^(\d+>)?-{5}.+-{5}$')
- _re_file = re.compile(r'^(\d+>)?[^ ]+\.(cpp|c)$')
- _re_warning = re.compile(r' ?: warning [A-Z]+[0-9]+:')
- _re_error = re.compile(r' ?error ([A-Z]+[0-9]+)?\s?: ')
-
- nbFiles = 0
- nbProjects = 0
- nbWarnings = 0
- nbErrors = 0
-
- logwarnings = None
- logerrors = None
-
- def __init__(self, logwarnings, logerrors, **kwargs):
- LogLineObserver.__init__(self, **kwargs)
- self.logwarnings = logwarnings
- self.logerrors = logerrors
- self.stdoutParser.delimiter = "\r\n"
- self.stderrParser.delimiter = "\r\n"
-
- def outLineReceived(self, line):
- if self._re_delimiter.search(line):
- self.nbProjects += 1
- self.logwarnings.addStdout("%s\n" % line)
- self.logerrors.addStdout("%s\n" % line)
- self.step.setProgress('projects', self.nbProjects)
- elif self._re_file.search(line):
- self.nbFiles += 1
- self.step.setProgress('files', self.nbFiles)
- elif self._re_warning.search(line):
- self.nbWarnings += 1
- self.logwarnings.addStdout("%s\n" % line)
- self.step.setProgress('warnings', self.nbWarnings)
- elif self._re_error.search("%s\n" % line):
- # error has no progress indication
- self.nbErrors += 1
- self.logerrors.addStderr("%s\n" % line)
-
-
-class VisualStudio(ShellCommand):
- # an *abstract* base class, which will not itself work as a buildstep
-
- name = "compile"
- description = "compiling"
- descriptionDone = "compile"
-
-
- progressMetrics = ( ShellCommand.progressMetrics +
- ('projects', 'files','warnings',))
-
- logobserver = None
-
- installdir = None
- default_installdir = None
-
- # One of build, or rebuild
- mode = "rebuild"
-
- projectfile = None
- config = None
- useenv = False
- project = None
- PATH = []
- INCLUDE = []
- LIB = []
-
- renderables = [ 'projectfile', 'config', 'project' ]
-
- def __init__(self,
- installdir = None,
- mode = "rebuild",
- projectfile = None,
- config = 'release',
- useenv = False,
- project = None,
- INCLUDE = [],
- LIB = [],
- PATH = [],
- **kwargs):
- self.installdir = installdir
- self.mode = mode
- self.projectfile = projectfile
- self.config = config
- self.useenv = useenv
- self.project = project
- if len(INCLUDE) > 0:
- self.INCLUDE = INCLUDE
- self.useenv = True
- if len(LIB) > 0:
- self.LIB = LIB
- self.useenv = True
- if len(PATH) > 0:
- self.PATH = PATH
- # always upcall !
- ShellCommand.__init__(self, **kwargs)
-
- def setupLogfiles(self, cmd, logfiles):
- logwarnings = self.addLog("warnings")
- logerrors = self.addLog("errors")
- self.logobserver = MSLogLineObserver(logwarnings, logerrors)
- self.addLogObserver('stdio', self.logobserver)
- ShellCommand.setupLogfiles(self, cmd, logfiles)
-
- def setupInstalldir(self):
- if not self.installdir:
- self.installdir = self.default_installdir
-
- def setupEnvironment(self, cmd):
- ShellCommand.setupEnvironment(self, cmd)
- if cmd.args['env'] is None:
- cmd.args['env'] = {}
-
- # setup the custom one, those one goes first
- for path in self.PATH:
- addEnvPath(cmd.args['env'], "PATH", path)
- for path in self.INCLUDE:
- addEnvPath(cmd.args['env'], "INCLUDE", path)
- for path in self.LIB:
- addEnvPath(cmd.args['env'], "LIB", path)
-
- self.setupInstalldir()
-
- def describe(self, done=False):
- description = ShellCommand.describe(self, done)
- if done:
- description.append('%d projects' % self.step_status.getStatistic('projects', 0))
- description.append('%d files' % self.step_status.getStatistic('files', 0))
- warnings = self.step_status.getStatistic('warnings', 0)
- if warnings > 0:
- description.append('%d warnings' % warnings)
- errors = self.step_status.getStatistic('errors', 0)
- if errors > 0:
- description.append('%d errors' % errors)
- return description
-
- def createSummary(self, log):
- self.step_status.setStatistic('projects', self.logobserver.nbProjects)
- self.step_status.setStatistic('files', self.logobserver.nbFiles)
- self.step_status.setStatistic('warnings', self.logobserver.nbWarnings)
- self.step_status.setStatistic('errors', self.logobserver.nbErrors)
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- if self.logobserver.nbErrors > 0:
- return FAILURE
- if self.logobserver.nbWarnings > 0:
- return WARNINGS
- else:
- return SUCCESS
-
- def finished(self, result):
- self.getLog("warnings").finish()
- self.getLog("errors").finish()
- ShellCommand.finished(self, result)
-
-class VC6(VisualStudio):
-
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio'
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
-
- # Root of Visual Developer Studio Common files.
- VSCommonDir = self.installdir + '\\Common'
- MSVCDir = self.installdir + '\\VC98'
- MSDevDir = VSCommonDir + '\\msdev98'
-
- addEnvPath(cmd.args['env'], "PATH", MSDevDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", MSVCDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", VSCommonDir + '\\TOOLS\\WINNT')
- addEnvPath(cmd.args['env'], "PATH", VSCommonDir + '\\TOOLS')
-
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\ATL\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\MFC\\INCLUDE')
-
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\LIB')
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\MFC\\LIB')
-
- def start(self):
- command = ["msdev"]
- command.append(self.projectfile)
- command.append("/MAKE")
- if self.project is not None:
- command.append(self.project + " - " + self.config)
- else:
- command.append("ALL - " + self.config)
- if self.mode == "rebuild":
- command.append("/REBUILD")
- elif self.mode == "clean":
- command.append("/CLEAN")
- else:
- command.append("/BUILD")
- if self.useenv:
- command.append("/USEENV")
- self.setCommand(command)
- return VisualStudio.start(self)
-
-class VC7(VisualStudio):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio .NET 2003'
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
-
- VSInstallDir = self.installdir + '\\Common7\\IDE'
- VCInstallDir = self.installdir
- MSVCDir = self.installdir + '\\VC7'
-
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir)
- addEnvPath(cmd.args['env'], "PATH", MSVCDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\Common7\\Tools')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\Common7\\Tools\\bin')
-
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\ATLMFC\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\PlatformSDK\\include')
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\SDK\\v1.1\\include')
-
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\LIB')
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\ATLMFC\\LIB')
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\PlatformSDK\\lib')
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\SDK\\v1.1\\lib')
-
- def start(self):
- command = ["devenv.com"]
- command.append(self.projectfile)
- if self.mode == "rebuild":
- command.append("/Rebuild")
- elif self.mode == "clean":
- command.append("/Clean")
- else:
- command.append("/Build")
- command.append(self.config)
- if self.useenv:
- command.append("/UseEnv")
- if self.project is not None:
- command.append("/Project")
- command.append(self.project)
- self.setCommand(command)
- return VisualStudio.start(self)
-
-#alias VC7 as VS2003
-VS2003 = VC7
-
-class VC8(VC7):
-
- # Our ones
- arch = None
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 8'
-
- renderables = ['arch']
-
- def __init__(self, arch = "x86", **kwargs):
- self.arch = arch
-
- # always upcall !
- VisualStudio.__init__(self, **kwargs)
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
-
- VSInstallDir = self.installdir
- VCInstallDir = self.installdir + '\\VC'
-
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\Common7\\IDE')
- if self.arch == "x64":
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\BIN\\x86_amd64')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\Common7\\Tools')
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\Common7\\Tools\\bin')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\PlatformSDK\\bin')
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\SDK\\v2.0\\bin')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\VCPackages')
- addEnvPath(cmd.args['env'], "PATH", r'${PATH}')
-
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\ATLMFC\\include')
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\PlatformSDK\\include')
-
- archsuffix = ''
- if self.arch == "x64":
- archsuffix = '\\amd64'
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\LIB' + archsuffix)
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\ATLMFC\\LIB' + archsuffix)
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\PlatformSDK\\lib' + archsuffix)
- addEnvPath(cmd.args['env'], "LIB", VSInstallDir + '\\SDK\\v2.0\\lib' + archsuffix)
-
-#alias VC8 as VS2005
-VS2005 = VC8
-
-class VCExpress9(VC8):
- def start(self):
- command = ["vcexpress"]
- command.append(self.projectfile)
- if self.mode == "rebuild":
- command.append("/Rebuild")
- elif self.mode == "clean":
- command.append("/Clean")
- else:
- command.append("/Build")
- command.append(self.config)
- if self.useenv:
- command.append("/UseEnv")
- if self.project is not None:
- command.append("/Project")
- command.append(self.project)
- self.setCommand(command)
- return VisualStudio.start(self)
-
-# Add first support for VC9 (Same as VC8, with a different installdir)
-class VC9(VC8):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 9.0'
-
-VS2008 = VC9
-
-# VC10 doesn't look like it needs extra stuff.
-class VC10(VC9):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 10.0'
-
-VS2010 = VC10
-
-# VC11 doesn't look like it needs extra stuff.
-class VC11(VC10):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 11.0'
-
-VS2012 = VC11
-
-class MsBuild(VisualStudio):
- platform = None
-
- def __init__(self, platform, **kwargs):
- self.platform = platform
- VisualStudio.__init__(self, **kwargs)
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
- cmd.args['env']['VCENV_BAT'] = "\"${VS110COMNTOOLS}..\\..\\VC\\vcvarsall.bat\""
-
- def describe(self, done=False):
- rv = []
- if done:
- rv.append("built")
- else:
- rv.append("building")
- if self.project is not None:
- rv.append("%s for" % (self.project))
- else:
- rv.append("solution for")
- rv.append("%s|%s" % (self.config, self.platform))
- return rv
-
- def start(self):
- if self.platform is None:
- config.error('platform is mandatory. Please specify a string such as "Win32"')
-
- command = ["%VCENV_BAT%",
- "x86",
- "&&",
- "msbuild",
- self.projectfile,
- "/p:Configuration=%s" % (self.config),
- "/p:Platform=%s" % (self.platform)]
- if self.project is not None:
- command.append("/t:%s" % (self.project))
-
- self.setCommand(command)
-
- return VisualStudio.start(self)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py
deleted file mode 100644
index 6812758b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# apply the same patches the buildmaster does when it starts
-from buildbot import monkeypatches
-monkeypatches.patch_all(for_tests=True)
-
-# import mock so we bail out early if it's not installed
-try:
- import mock
- mock = mock
-except ImportError:
- raise ImportError("Buildbot tests require the 'mock' module; "
- "try 'pip install mock'")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py
deleted file mode 100644
index f04a2a79..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.application import service
-
-class FakeBotMaster(service.MultiService):
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName("fake-botmaster")
- self.master = master
- self.locks = {}
-
- def getLockByID(self, lockid):
- if not lockid in self.locks:
- self.locks[lockid] = lockid.lockClass(lockid)
- # if the master.cfg file has changed maxCount= on the lock, the next
- # time a build is started, they'll get a new RealLock instance. Note
- # that this requires that MasterLock and SlaveLock (marker) instances
- # be hashable and that they should compare properly.
- return self.locks[lockid]
-
- def getLockFromLockAccess(self, access):
- return self.getLockByID(access.lockid)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py
deleted file mode 100644
index 02f45717..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-import posixpath
-from twisted.python import components
-from buildbot.process import properties
-from buildbot import interfaces
-
-class FakeBuildStatus(properties.PropertiesMixin, mock.Mock):
-
- # work around http://code.google.com/p/mock/issues/detail?id=105
- def _get_child_mock(self, **kw):
- return mock.Mock(**kw)
-
- def getInterestedUsers(self):
- return []
-
-components.registerAdapter(
- lambda build_status : build_status.properties,
- FakeBuildStatus, interfaces.IProperties)
-
-
-class FakeBuild(properties.PropertiesMixin):
-
- def __init__(self, props=None):
- self.build_status = FakeBuildStatus()
- self.builder = mock.Mock(name='build.builder')
- self.path_module = posixpath
-
- self.sources = {}
- if props is None:
- props = properties.Properties()
- props.build = self
- self.build_status.properties = props
-
- def getSourceStamp(self, codebase):
- if codebase in self.sources:
- return self.sources[codebase]
- return None
-
-
-components.registerAdapter(
- lambda build : build.build_status.properties,
- FakeBuild, interfaces.IProperties)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py
deleted file mode 100644
index db9b409c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py
+++ /dev/null
@@ -1,1224 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-A complete re-implementation of the database connector components, but without
-using a database. These classes should pass the same tests as are applied to
-the real connector components.
-"""
-
-import base64
-from buildbot.util import json, epoch2datetime, datetime2epoch
-from twisted.python import failure
-from twisted.internet import defer, reactor
-from buildbot.db import buildrequests
-
-# Fake DB Rows
-
-class Row(object):
- """
- Parent class for row classes, which are used to specify test data for
- database-related tests.
-
- @cvar defaults: default values for columns
- @type defaults: dictionary
-
- @cvar table: the table name
-
- @cvar id_column: specify a column that should be assigned an
- auto-incremented id. Auto-assigned id's begin at 1000, so any explicitly
- specified ID's should be less than 1000.
-
- @cvar required_columns: a tuple of columns that must be given in the
- constructor
-
- @ivar values: the values to be inserted into this row
- """
-
- id_column = ()
- required_columns = ()
- lists = ()
- dicts = ()
-
- def __init__(self, **kwargs):
- self.values = self.defaults.copy()
- self.values.update(kwargs)
- if self.id_column:
- if self.values[self.id_column] is None:
- self.values[self.id_column] = self.nextId()
- for col in self.required_columns:
- assert col in kwargs, "%s not specified" % col
- for col in self.lists:
- setattr(self, col, [])
- for col in self.dicts:
- setattr(self, col, {})
- for col in kwargs.keys():
- assert col in self.defaults, "%s is not a valid column" % col
- # make the values appear as attributes
- self.__dict__.update(self.values)
-
- def nextId(self):
- if not hasattr(self.__class__, '_next_id'):
- self.__class__._next_id = 1000
- else:
- self.__class__._next_id += 1
- return self.__class__._next_id
-
-
-class BuildRequest(Row):
- table = "buildrequests"
-
- defaults = dict(
- id = None,
- buildsetid = None,
- buildername = "bldr",
- priority = 0,
- complete = 0,
- results = -1,
- submitted_at = 0,
- complete_at = 0,
- )
-
- id_column = 'id'
- required_columns = ('buildsetid',)
-
-
-class BuildRequestClaim(Row):
- table = "buildrequest_claims"
-
- defaults = dict(
- brid = None,
- objectid = None,
- claimed_at = None
- )
-
- required_columns = ('brid', 'objectid', 'claimed_at')
-
-
-class Change(Row):
- table = "changes"
-
- defaults = dict(
- changeid = None,
- author = 'frank',
- comments = 'test change',
- is_dir = 0,
- branch = 'master',
- revision = 'abcd',
- revlink = 'http://vc/abcd',
- when_timestamp = 1200000,
- category = 'cat',
- repository = 'repo',
- codebase = '',
- project = 'proj',
- )
-
- lists = ('files',)
- dicts = ('properties',)
- id_column = 'changeid'
-
-
-class ChangeFile(Row):
- table = "change_files"
-
- defaults = dict(
- changeid = None,
- filename = None,
- )
-
- required_columns = ('changeid',)
-
-
-class ChangeProperty(Row):
- table = "change_properties"
-
- defaults = dict(
- changeid = None,
- property_name = None,
- property_value = None,
- )
-
- required_columns = ('changeid',)
-
-class ChangeUser(Row):
- table = "change_users"
-
- defaults = dict(
- changeid = None,
- uid = None,
- )
-
- required_columns = ('changeid',)
-
-class Patch(Row):
- table = "patches"
-
- defaults = dict(
- id = None,
- patchlevel = 0,
- patch_base64 = 'aGVsbG8sIHdvcmxk', # 'hello, world',
- patch_author = None,
- patch_comment = None,
- subdir = None,
- )
-
- id_column = 'id'
-
-
-class SourceStampChange(Row):
- table = "sourcestamp_changes"
-
- defaults = dict(
- sourcestampid = None,
- changeid = None,
- )
-
- required_columns = ('sourcestampid', 'changeid')
-
-class SourceStampSet(Row):
- table = "sourcestampsets"
- defaults = dict(
- id = None,
- )
- id_column = 'id'
-
-class SourceStamp(Row):
- table = "sourcestamps"
-
- defaults = dict(
- id = None,
- branch = 'master',
- revision = 'abcd',
- patchid = None,
- repository = 'repo',
- codebase = '',
- project = 'proj',
- sourcestampsetid = None,
- )
-
- id_column = 'id'
-
-
-class SchedulerChange(Row):
- table = "scheduler_changes"
-
- defaults = dict(
- objectid = None,
- changeid = None,
- important = 1,
- )
-
- required_columns = ( 'objectid', 'changeid' )
-
-
-class Buildset(Row):
- table = "buildsets"
-
- defaults = dict(
- id = None,
- external_idstring = 'extid',
- reason = 'because',
- sourcestampsetid = None,
- submitted_at = 12345678,
- complete = 0,
- complete_at = None,
- results = -1,
- )
-
- id_column = 'id'
- required_columns = ( 'sourcestampsetid', )
-
-
-class BuildsetProperty(Row):
- table = "buildset_properties"
-
- defaults = dict(
- buildsetid = None,
- property_name = 'prop',
- property_value = '[22, "fakedb"]',
- )
-
- required_columns = ( 'buildsetid', )
-
-
-class Object(Row):
- table = "objects"
-
- defaults = dict(
- id = None,
- name = 'nam',
- class_name = 'cls',
- )
-
- id_column = 'id'
-
-
-class ObjectState(Row):
- table = "object_state"
-
- defaults = dict(
- objectid = None,
- name = 'nam',
- value_json = '{}',
- )
-
- required_columns = ( 'objectid', )
-
-class User(Row):
- table = "users"
-
- defaults = dict(
- uid = None,
- identifier = 'soap',
- bb_username = None,
- bb_password = None,
- )
-
- id_column = 'uid'
-
-class UserInfo(Row):
- table = "users_info"
-
- defaults = dict(
- uid = None,
- attr_type = 'git',
- attr_data = 'Tyler Durden <tyler@mayhem.net>',
- )
-
- required_columns = ( 'uid', )
-
-class Build(Row):
- table = "builds"
-
- defaults = dict(
- id = None,
- number = 29,
- brid = 39,
- start_time = 1304262222,
- finish_time = None)
-
- id_column = 'id'
-
-# Fake DB Components
-
-# TODO: test these using the same test methods as are used against the real
-# database
-
-class FakeDBComponent(object):
-
- def __init__(self, db, testcase):
- self.db = db
- self.t = testcase
- self.setUp()
-
-
-class FakeChangesComponent(FakeDBComponent):
-
- def setUp(self):
- self.changes = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Change):
- self.changes[row.changeid] = row
-
- elif isinstance(row, ChangeFile):
- ch = self.changes[row.changeid]
- ch.files.append(row.filename)
-
- elif isinstance(row, ChangeProperty):
- ch = self.changes[row.changeid]
- n, vs = row.property_name, row.property_value
- v, s = json.loads(vs)
- ch.properties.setProperty(n, v, s)
-
- elif isinstance(row, ChangeUser):
- ch = self.changes[row.changeid]
- ch.uid = row.uid
-
- # component methods
-
- def addChange(self, author=None, files=None, comments=None, is_dir=0,
- revision=None, when_timestamp=None, branch=None,
- category=None, revlink='', properties={}, repository='',
- project='', codebase='', uid=None):
- if self.changes:
- changeid = max(self.changes.iterkeys()) + 1
- else:
- changeid = 500
-
- self.changes[changeid] = ch = Change(
- changeid=changeid,
- author=author,
- comments=comments,
- is_dir=is_dir,
- revision=revision,
- when_timestamp=datetime2epoch(when_timestamp),
- branch=branch,
- category=category,
- revlink=revlink,
- repository=repository,
- project=project,
- codebase=codebase)
- ch.files = files
- ch.properties = properties
-
- return defer.succeed(changeid)
-
- def getLatestChangeid(self):
- if self.changes:
- return defer.succeed(max(self.changes.iterkeys()))
- return defer.succeed(None)
-
- def getChange(self, changeid):
- try:
- row = self.changes[changeid]
- except KeyError:
- return defer.succeed(None)
-
- chdict = dict(
- changeid=row.changeid,
- author=row.author,
- files=row.files,
- comments=row.comments,
- is_dir=row.is_dir,
- revision=row.revision,
- when_timestamp=epoch2datetime(row.when_timestamp),
- branch=row.branch,
- category=row.category,
- revlink=row.revlink,
- properties=row.properties,
- repository=row.repository,
- codebase=row.codebase,
- project=row.project)
-
- return defer.succeed(chdict)
-
- def getChangeUids(self, changeid):
- try:
- ch_uids = [self.changes[changeid].uid]
- except KeyError:
- ch_uids = []
- return defer.succeed(ch_uids)
-
- # TODO: getRecentChanges
-
- # fake methods
-
- def fakeAddChangeInstance(self, change):
- if not hasattr(change, 'number') or not change.number:
- if self.changes:
- changeid = max(self.changes.iterkeys()) + 1
- else:
- changeid = 500
- else:
- changeid = change.number
-
- # make a row from the change
- row = dict(
- changeid=changeid,
- author=change.who,
- files=change.files,
- comments=change.comments,
- is_dir=change.isdir,
- revision=change.revision,
- when_timestamp=change.when,
- branch=change.branch,
- category=change.category,
- revlink=change.revlink,
- properties=change.properties,
- repository=change.repository,
- codebase=change.codebase,
- project=change.project)
- self.changes[changeid] = row
-
-class FakeSchedulersComponent(FakeDBComponent):
-
- def setUp(self):
- self.states = {}
- self.classifications = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, SchedulerChange):
- cls = self.classifications.setdefault(row.objectid, {})
- cls[row.changeid] = row.important
-
- # component methods
-
- def classifyChanges(self, objectid, classifications):
- self.classifications.setdefault(objectid, {}).update(classifications)
- return defer.succeed(None)
-
- def flushChangeClassifications(self, objectid, less_than=None):
- if less_than is not None:
- classifications = self.classifications.setdefault(objectid, {})
- for changeid in classifications.keys():
- if changeid < less_than:
- del classifications[changeid]
- else:
- self.classifications[objectid] = {}
- return defer.succeed(None)
-
- def getChangeClassifications(self, objectid, branch=-1, repository=-1,
- project=-1, codebase=-1):
- classifications = self.classifications.setdefault(objectid, {})
-
- sentinel = dict(branch=object(), repository=object(),
- project=object(), codebase=object())
-
- if branch != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['branch'] == branch )
-
- if repository != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['repository'] == repository )
-
- if project != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['project'] == project )
-
- if codebase != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['codebase'] == codebase )
-
- return defer.succeed(classifications)
-
- # fake methods
-
- def fakeClassifications(self, objectid, classifications):
- """Set the set of classifications for a scheduler"""
- self.classifications[objectid] = classifications
-
- # assertions
-
- def assertClassifications(self, objectid, classifications):
- self.t.assertEqual(
- self.classifications.get(objectid, {}),
- classifications)
-
-
-class FakeSourceStampSetsComponent(FakeDBComponent):
- def setUp(self):
- self.sourcestampsets = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, SourceStampSet):
- self.sourcestampsets[row.id] = dict()
-
- def addSourceStampSet(self):
- id = len(self.sourcestampsets) + 100
- while id in self.sourcestampsets:
- id += 1
- self.sourcestampsets[id] = dict()
- return defer.succeed(id)
-
-class FakeSourceStampsComponent(FakeDBComponent):
-
- def setUp(self):
- self.sourcestamps = {}
- self.patches = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Patch):
- self.patches[row.id] = dict(
- patch_level=row.patchlevel,
- patch_body=base64.b64decode(row.patch_base64),
- patch_author=row.patch_author,
- patch_comment=row.patch_comment,
- patch_subdir=row.subdir)
-
- for row in rows:
- if isinstance(row, SourceStamp):
- ss = self.sourcestamps[row.id] = row.values.copy()
- ss['changeids'] = set()
-
- for row in rows:
- if isinstance(row, SourceStampChange):
- ss = self.sourcestamps[row.sourcestampid]
- ss['changeids'].add(row.changeid)
-
- # component methods
-
- def addSourceStamp(self, branch, revision, repository, project, sourcestampsetid,
- codebase = '', patch_body=None, patch_level=0, patch_author=None,
- patch_comment=None, patch_subdir=None, changeids=[]):
- id = len(self.sourcestamps) + 100
- while id in self.sourcestamps:
- id += 1
-
- changeids = set(changeids)
-
- if patch_body:
- patchid = len(self.patches) + 100
- while patchid in self.patches:
- patchid += 1
- self.patches[patchid] = dict(
- patch_level=patch_level,
- patch_body=patch_body,
- patch_subdir=patch_subdir,
- patch_author=patch_author,
- patch_comment=patch_comment
- )
- else:
- patchid = None
-
- self.sourcestamps[id] = dict(id=id, sourcestampsetid=sourcestampsetid, branch=branch, revision=revision, codebase=codebase,
- patchid=patchid, repository=repository, project=project,
- changeids=changeids)
- return defer.succeed(id)
-
- def getSourceStamp(self, ssid):
- return defer.succeed(self._getSourceStamp(ssid))
-
- def _getSourceStamp(self, ssid):
- if ssid in self.sourcestamps:
- ssdict = self.sourcestamps[ssid].copy()
- del ssdict['id']
- ssdict['ssid'] = ssid
- patchid = ssdict['patchid']
- if patchid:
- ssdict.update(self.patches[patchid])
- else:
- ssdict['patch_body'] = None
- ssdict['patch_level'] = None
- ssdict['patch_subdir'] = None
- ssdict['patch_author'] = None
- ssdict['patch_comment'] = None
- del ssdict['patchid']
- return ssdict
- else:
- return None
-
- def getSourceStamps(self, sourcestampsetid):
- sslist = []
- for ssdict in self.sourcestamps.itervalues():
- if ssdict['sourcestampsetid'] == sourcestampsetid:
- ssdictcpy = self._getSourceStamp(ssdict['id'])
- sslist.append(ssdictcpy)
- return defer.succeed(sslist)
-
-class FakeBuildsetsComponent(FakeDBComponent):
-
- def setUp(self):
- self.buildsets = {}
- self.completed_bsids = set()
- self.buildset_subs = []
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Buildset):
- bs = self.buildsets[row.id] = row.values.copy()
- bs['properties'] = {}
-
- for row in rows:
- if isinstance(row, BuildsetProperty):
- assert row.buildsetid in self.buildsets
- n = row.property_name
- v, src = tuple(json.loads(row.property_value))
- self.buildsets[row.buildsetid]['properties'][n] = (v, src)
-
- # component methods
-
- def _newBsid(self):
- bsid = 200
- while bsid in self.buildsets:
- bsid += 1
- return bsid
-
- def addBuildset(self, sourcestampsetid, reason, properties, builderNames,
- external_idstring=None, _reactor=reactor):
- bsid = self._newBsid()
- br_rows = []
- for buildername in builderNames:
- br_rows.append(
- BuildRequest(buildsetid=bsid, buildername=buildername))
- self.db.buildrequests.insertTestData(br_rows)
-
- # make up a row and keep its dictionary, with the properties tacked on
- bsrow = Buildset(sourcestampsetid=sourcestampsetid, reason=reason, external_idstring=external_idstring)
- self.buildsets[bsid] = bsrow.values.copy()
- self.buildsets[bsid]['properties'] = properties
-
- return defer.succeed((bsid,
- dict([ (br.buildername, br.id) for br in br_rows ])))
-
- def completeBuildset(self, bsid, results, complete_at=None,
- _reactor=reactor):
- self.buildsets[bsid]['results'] = results
- self.buildsets[bsid]['complete'] = 1
- self.buildsets[bsid]['complete_at'] = complete_at or _reactor.seconds()
- return defer.succeed(None)
-
- def getBuildset(self, bsid):
- if bsid not in self.buildsets:
- return defer.succeed(None)
- row = self.buildsets[bsid]
- return defer.succeed(self._row2dict(row))
-
- def getBuildsets(self, complete=None):
- rv = []
- for bs in self.buildsets.itervalues():
- if complete is not None:
- if complete and bs['complete']:
- rv.append(self._row2dict(bs))
- elif not complete and not bs['complete']:
- rv.append(self._row2dict(bs))
- else:
- rv.append(self._row2dict(bs))
- return defer.succeed(rv)
-
- def _row2dict(self, row):
- row = row.copy()
- if row['complete_at']:
- row['complete_at'] = epoch2datetime(row['complete_at'])
- else:
- row['complete_at'] = None
- row['submitted_at'] = row['submitted_at'] and \
- epoch2datetime(row['submitted_at'])
- row['complete'] = bool(row['complete'])
- row['bsid'] = row['id']
- del row['id']
- return row
-
- def getBuildsetProperties(self, buildsetid):
- if buildsetid in self.buildsets:
- return defer.succeed(
- self.buildsets[buildsetid]['properties'])
- else:
- return defer.succeed({})
-
- # fake methods
-
- def fakeBuildsetCompletion(self, bsid, result):
- assert bsid in self.buildsets
- self.buildsets[bsid]['results'] = result
- self.completed_bsids.add(bsid)
-
- def flushBuildsets(self):
- """
- Flush the set of buildsets, for example after C{assertBuildset}
- """
- self.buildsets = {}
- self.completed_bsids = set()
-
- # assertions
-
- def assertBuildsets(self, count):
- """Assert that exactly COUNT buildsets were added"""
- self.t.assertEqual(len(self.buildsets), count,
- "buildsets are %r" % (self.buildsets,))
-
- def assertBuildset(self, bsid, expected_buildset, expected_sourcestamps):
- """Assert that the buildset and its attached sourcestamp look as
- expected; the ssid parameter of the buildset is omitted. Properties
- are converted with asList and sorted. Sourcestamp patches are inlined
- (patch_body, patch_level, patch_subdir), and changeids are represented
- as a set, but omitted if empty. If bsid is '?', then assert there is
- only one new buildset, and use that."""
- if bsid == '?':
- self.assertBuildsets(1)
- bsid = self.buildsets.keys()[0]
- else:
- self.t.assertIn(bsid, self.buildsets)
-
- buildset = self.buildsets[bsid].copy()
-
- dictOfssDict= {}
- for sourcestamp in self.db.sourcestamps.sourcestamps.itervalues():
- if sourcestamp['sourcestampsetid'] == buildset['sourcestampsetid']:
- ssdict = sourcestamp.copy()
- ss_repository = ssdict['codebase']
- dictOfssDict[ss_repository] = ssdict
-
- if 'id' in buildset:
- del buildset['id']
-
- # clear out some columns if the caller doesn't care
- for col in 'complete complete_at submitted_at results'.split():
- if col not in expected_buildset:
- del buildset[col]
-
- if buildset['properties']:
- buildset['properties'] = sorted(buildset['properties'].items())
-
- # only add brids if we're expecting them (sometimes they're unknown)
- if 'brids' in expected_buildset:
- buildset['brids'] = self.allBuildRequests(bsid)
-
- if 'builders' in expected_buildset:
- buildset['builders'] = self.allBuildRequests(bsid).keys()
-
- for ss in dictOfssDict.itervalues():
- if 'id' in ss:
- del ss['id']
- if not ss['changeids']:
- del ss['changeids']
-
- # incorporate patch info if we have it
- if 'patchid' in ss and ss['patchid']:
- ss.update(self.db.sourcestamps.patches[ss['patchid']])
- del ss['patchid']
-
- self.t.assertEqual(
- dict(buildset=buildset, sourcestamps=dictOfssDict),
- dict(buildset=expected_buildset, sourcestamps=expected_sourcestamps))
- return bsid
-
- def allBuildsetIds(self):
- return self.buildsets.keys()
-
- def allBuildRequests(self, bsid=None):
- if bsid is not None:
- is_same_bsid = lambda br: br.buildsetid==bsid
- else:
- is_same_bsid = lambda br: True
- return dict([ (br.buildername, br.id)
- for br in self.db.buildrequests.reqs.values()
- if is_same_bsid(br) ])
-
-
-class FakeStateComponent(FakeDBComponent):
-
- def setUp(self):
- self.objects = {}
- self.states = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Object):
- self.objects[(row.name, row.class_name)] = row.id
- self.states[row.id] = {}
-
- for row in rows:
- if isinstance(row, ObjectState):
- assert row.objectid in self.objects.values()
- self.states[row.objectid][row.name] = row.value_json
-
- # component methods
-
- def _newId(self):
- id = 100
- while id in self.states:
- id += 1
- return id
-
- def getObjectId(self, name, class_name):
- try:
- id = self.objects[(name, class_name)]
- except:
- # invent a new id and add it
- id = self.objects[(name, class_name)] = self._newId()
- self.states[id] = {}
- return defer.succeed(id)
-
- def getState(self, objectid, name, default=object):
- try:
- json_value = self.states[objectid][name]
- except KeyError:
- if default is not object:
- return defer.succeed(default)
- raise
- return defer.succeed(json.loads(json_value))
-
- def setState(self, objectid, name, value):
- self.states[objectid][name] = json.dumps(value)
- return defer.succeed(None)
-
- # fake methods
-
- def fakeState(self, name, class_name, **kwargs):
- id = self.objects[(name, class_name)] = self._newId()
- self.objects[(name, class_name)] = id
- self.states[id] = dict( (k, json.dumps(v))
- for k,v in kwargs.iteritems() )
- return id
-
- # assertions
-
- def assertState(self, objectid, missing_keys=[], **kwargs):
- state = self.states[objectid]
- for k in missing_keys:
- self.t.assertFalse(k in state, "%s in %s" % (k, state))
- for k,v in kwargs.iteritems():
- self.t.assertIn(k, state)
- self.t.assertEqual(json.loads(state[k]), v,
- "state is %r" % (state,))
-
- def assertStateByClass(self, name, class_name, **kwargs):
- objectid = self.objects[(name, class_name)]
- state = self.states[objectid]
- for k,v in kwargs.iteritems():
- self.t.assertIn(k, state)
- self.t.assertEqual(json.loads(state[k]), v,
- "state is %r" % (state,))
-
-
-class FakeBuildRequestsComponent(FakeDBComponent):
-
- # for use in determining "my" requests
- MASTER_ID = 824
-
- # override this to set reactor.seconds
- _reactor = reactor
-
- def setUp(self):
- self.reqs = {}
- self.claims = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, BuildRequest):
- self.reqs[row.id] = row
-
- if isinstance(row, BuildRequestClaim):
- self.claims[row.brid] = row
-
- # component methods
-
- def getBuildRequest(self, brid):
- try:
- return defer.succeed(self._brdictFromRow(self.reqs[brid]))
- except:
- return defer.succeed(None)
-
- def getBuildRequests(self, buildername=None, complete=None, claimed=None,
- bsid=None):
- rv = []
- for br in self.reqs.itervalues():
- if buildername and br.buildername != buildername:
- continue
- if complete is not None:
- if complete and not br.complete:
- continue
- if not complete and br.complete:
- continue
- if claimed is not None:
- claim_row = self.claims.get(br.id)
- if claimed == "mine":
- if not claim_row or claim_row.objectid != self.MASTER_ID:
- continue
- elif claimed:
- if not claim_row:
- continue
- else:
- if claim_row:
- continue
- if bsid is not None:
- if br.buildsetid != bsid:
- continue
- rv.append(self._brdictFromRow(br))
- return defer.succeed(rv)
-
- def claimBuildRequests(self, brids, claimed_at=None):
- for brid in brids:
- if brid not in self.reqs or brid in self.claims:
- return defer.fail(
- failure.Failure(buildrequests.AlreadyClaimedError))
-
- claimed_at = datetime2epoch(claimed_at)
- if not claimed_at:
- claimed_at = self._reactor.seconds()
-
- # now that we've thrown any necessary exceptions, get started
- for brid in brids:
- self.claims[brid] = BuildRequestClaim(brid=brid,
- objectid=self.MASTER_ID, claimed_at=claimed_at)
- return defer.succeed(None)
-
- def reclaimBuildRequests(self, brids):
- for brid in brids:
- if brid not in self.claims:
- print "trying to reclaim brid %d, but it's not claimed" % brid
- return defer.fail(
- failure.Failure(buildrequests.AlreadyClaimedError))
- # now that we've thrown any necessary exceptions, get started
- for brid in brids:
- self.claims[brid] = BuildRequestClaim(brid=brid,
- objectid=self.MASTER_ID, claimed_at=self._reactor.seconds())
- return defer.succeed(None)
-
- def unclaimBuildRequests(self, brids):
- for brid in brids:
- try:
- self.claims.pop(brid)
- except KeyError:
- print "trying to unclaim brid %d, but it's not claimed" % brid
- return defer.fail(
- failure.Failure(buildrequests.AlreadyClaimedError))
-
- return defer.succeed(None)
-
- # Code copied from buildrequests.BuildRequestConnectorComponent
- def _brdictFromRow(self, row):
- claimed = mine = False
- claimed_at = None
- claim_row = self.claims.get(row.id, None)
- if claim_row:
- claimed = True
- claimed_at = claim_row.claimed_at
- mine = claim_row.objectid == self.MASTER_ID
-
- submitted_at = epoch2datetime(row.submitted_at)
- complete_at = epoch2datetime(row.complete_at)
-
- return dict(brid=row.id, buildsetid=row.buildsetid,
- buildername=row.buildername, priority=row.priority,
- claimed=claimed, claimed_at=claimed_at, mine=mine,
- complete=bool(row.complete), results=row.results,
- submitted_at=submitted_at, complete_at=complete_at)
-
- # fake methods
-
- def fakeClaimBuildRequest(self, brid, claimed_at=None, objectid=None):
- if objectid is None:
- objectid = self.MASTER_ID
- self.claims[brid] = BuildRequestClaim(brid=brid,
- objectid=objectid, claimed_at=self._reactor.seconds())
-
- def fakeUnclaimBuildRequest(self, brid):
- del self.claims[brid]
-
- # assertions
-
- def assertMyClaims(self, claimed_brids):
- self.t.assertEqual(
- [ id for (id, brc) in self.claims.iteritems()
- if brc.objectid == self.MASTER_ID ],
- claimed_brids)
-
-
-class FakeBuildsComponent(FakeDBComponent):
-
- def setUp(self):
- self.builds = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Build):
- self.builds[row.id] = row
-
- # component methods
-
- def _newId(self):
- id = 100
- while id in self.builds:
- id += 1
- return id
-
- def getBuild(self, bid):
- row = self.builds.get(bid)
- if not row:
- return defer.succeed(None)
-
- return defer.succeed(dict(
- bid=row.id,
- brid=row.brid,
- number=row.number,
- start_time=epoch2datetime(row.start_time),
- finish_time=epoch2datetime(row.finish_time)))
-
- def getBuildsForRequest(self, brid):
- ret = []
-
- for (id, row) in self.builds.items():
- if row.brid == brid:
- ret.append(dict(bid = row.id,
- brid=row.brid,
- number=row.number,
- start_time=epoch2datetime(row.start_time),
- finish_time=epoch2datetime(row.finish_time)))
-
- return defer.succeed(ret)
-
- def addBuild(self, brid, number, _reactor=reactor):
- bid = self._newId()
- self.builds[bid] = Build(id=bid, number=number, brid=brid,
- start_time=_reactor.seconds, finish_time=None)
- return bid
-
- def finishBuilds(self, bids, _reactor=reactor):
- now = _reactor.seconds()
- for bid in bids:
- b = self.builds.get(bid)
- if b:
- b.finish_time = now
-
-class FakeUsersComponent(FakeDBComponent):
-
- def setUp(self):
- self.users = {}
- self.users_info = {}
- self.id_num = 0
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, User):
- self.users[row.uid] = dict(identifier=row.identifier,
- bb_username=row.bb_username,
- bb_password=row.bb_password)
-
- if isinstance(row, UserInfo):
- assert row.uid in self.users
- if row.uid not in self.users_info:
- self.users_info[row.uid] = [dict(attr_type=row.attr_type,
- attr_data=row.attr_data)]
- else:
- self.users_info[row.uid].append(
- dict(attr_type=row.attr_type,
- attr_data=row.attr_data))
-
- def _user2dict(self, uid):
- usdict = None
- if uid in self.users:
- usdict = self.users[uid]
- if uid in self.users_info:
- infos = self.users_info[uid]
- for attr in infos:
- usdict[attr['attr_type']] = attr['attr_data']
- usdict['uid'] = uid
- return usdict
-
- def nextId(self):
- self.id_num += 1
- return self.id_num
-
- # component methods
-
- def findUserByAttr(self, identifier, attr_type, attr_data):
- for uid in self.users_info:
- attrs = self.users_info[uid]
- for attr in attrs:
- if (attr_type == attr['attr_type'] and
- attr_data == attr['attr_data']):
- return defer.succeed(uid)
-
- uid = self.nextId()
- self.db.insertTestData([User(uid=uid, identifier=identifier)])
- self.db.insertTestData([UserInfo(uid=uid,
- attr_type=attr_type,
- attr_data=attr_data)])
- return defer.succeed(uid)
-
- def getUser(self, uid):
- usdict = None
- if uid in self.users:
- usdict = self._user2dict(uid)
- return defer.succeed(usdict)
-
- def getUserByUsername(self, username):
- usdict = None
- for uid in self.users:
- user = self.users[uid]
- if user['bb_username'] == username:
- usdict = self._user2dict(uid)
- return defer.succeed(usdict)
-
- def updateUser(self, uid=None, identifier=None, bb_username=None,
- bb_password=None, attr_type=None, attr_data=None):
- assert uid is not None
-
- if identifier is not None:
- self.users[uid]['identifier'] = identifier
-
- if bb_username is not None:
- assert bb_password is not None
- try:
- user = self.users[uid]
- user['bb_username'] = bb_username
- user['bb_password'] = bb_password
- except KeyError:
- pass
-
- if attr_type is not None:
- assert attr_data is not None
- try:
- infos = self.users_info[uid]
- for attr in infos:
- if attr_type == attr['attr_type']:
- attr['attr_data'] = attr_data
- break
- else:
- infos.append(dict(attr_type=attr_type,
- attr_data=attr_data))
- except KeyError:
- pass
-
- return defer.succeed(None)
-
- def removeUser(self, uid):
- if uid in self.users:
- self.users.pop(uid)
- self.users_info.pop(uid)
- return defer.succeed(None)
-
- def identifierToUid(self, identifier):
- for uid in self.users:
- if identifier == self.users[uid]['identifier']:
- return defer.succeed(uid)
- return defer.succeed(None)
-
-class FakeDBConnector(object):
- """
- A stand-in for C{master.db} that operates without an actual database
- backend. This also implements a test-data interface similar to the
- L{buildbot.test.util.db.RealDatabaseMixin.insertTestData} method.
-
- The child classes implement various useful assertions and faking methods;
- see their documentation for more.
- """
-
- def __init__(self, testcase):
- self._components = []
- self.changes = comp = FakeChangesComponent(self, testcase)
- self._components.append(comp)
- self.schedulers = comp = FakeSchedulersComponent(self, testcase)
- self._components.append(comp)
- self.sourcestampsets = comp = FakeSourceStampSetsComponent(self,testcase)
- self._components.append(comp)
- self.sourcestamps = comp = FakeSourceStampsComponent(self, testcase)
- self._components.append(comp)
- self.buildsets = comp = FakeBuildsetsComponent(self, testcase)
- self._components.append(comp)
- self.state = comp = FakeStateComponent(self, testcase)
- self._components.append(comp)
- self.buildrequests = comp = FakeBuildRequestsComponent(self, testcase)
- self._components.append(comp)
- self.builds = comp = FakeBuildsComponent(self, testcase)
- self._components.append(comp)
- self.users = comp = FakeUsersComponent(self, testcase)
- self._components.append(comp)
-
- def setup(self):
- self.is_setup = True
- return defer.succeed(None)
-
- def insertTestData(self, rows):
- """Insert a list of Row instances into the database; this method can be
- called synchronously or asynchronously (it completes immediately) """
- for comp in self._components:
- comp.insertTestData(rows)
- return defer.succeed(None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py
deleted file mode 100644
index 0187bedc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import weakref
-from twisted.internet import defer
-from buildbot.test.fake import fakedb
-from buildbot.test.fake import pbmanager
-from buildbot.test.fake.botmaster import FakeBotMaster
-from buildbot import config
-import mock
-
-class FakeCache(object):
- """Emulate an L{AsyncLRUCache}, but without any real caching. This
- I{does} do the weakref part, to catch un-weakref-able objects."""
- def __init__(self, name, miss_fn):
- self.name = name
- self.miss_fn = miss_fn
-
- def get(self, key, **kwargs):
- d = self.miss_fn(key, **kwargs)
- def mkref(x):
- if x is not None:
- weakref.ref(x)
- return x
- d.addCallback(mkref)
- return d
-
-
-class FakeCaches(object):
-
- def get_cache(self, name, miss_fn):
- return FakeCache(name, miss_fn)
-
-
-class FakeStatus(object):
-
- def builderAdded(self, name, basedir, category=None, description=None):
- return FakeBuilderStatus()
-
-
-class FakeBuilderStatus(object):
-
- def setDescription(self, description):
- self._description = description
-
- def getDescription(self):
- return self._description
-
- def setCategory(self, category):
- self._category = category
-
- def getCategory(self):
- return self._category
-
- def setSlavenames(self, names):
- pass
-
- def setCacheSize(self, size):
- pass
-
- def setBigState(self, state):
- pass
-
-
-class FakeMaster(object):
- """
- Create a fake Master instance: a Mock with some convenience
- implementations:
-
- - Non-caching implementation for C{self.caches}
- """
-
- def __init__(self, master_id=fakedb.FakeBuildRequestsComponent.MASTER_ID):
- self._master_id = master_id
- self.config = config.MasterConfig()
- self.caches = FakeCaches()
- self.pbmanager = pbmanager.FakePBManager()
- self.basedir = 'basedir'
- self.botmaster = FakeBotMaster(master=self)
- self.botmaster.parent = self
- self.status = FakeStatus()
- self.status.master = self
-
- def getObjectId(self):
- return defer.succeed(self._master_id)
-
- def subscribeToBuildRequests(self, callback):
- pass
-
- # work around http://code.google.com/p/mock/issues/detail?id=105
- def _get_child_mock(self, **kw):
- return mock.Mock(**kw)
-
-# Leave this alias, in case we want to add more behavior later
-def make_master(wantDb=False, testcase=None, **kwargs):
- master = FakeMaster(**kwargs)
- if wantDb:
- assert testcase is not None, "need testcase for wantDb"
- master.db = fakedb.FakeDBConnector(testcase)
- return master
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py
deleted file mode 100644
index 2a32f6e7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-class Domain(object):
-
- def __init__(self, name, conn):
- self.conn = conn
- self._name = name
- self.running = False
-
- def name(self):
- return self._name
-
- def create(self):
- self.running = True
-
- def shutdown(self):
- self.running = False
-
- def destroy(self):
- self.running = False
- del self.conn[self._name]
-
-
-class Connection(object):
-
- def __init__(self, uri):
- self.uri = uri
- self.domains = {}
-
- def createXML(self, xml, flags):
- #FIXME: This should really parse the name out of the xml, i guess
- d = self.fake_add("instance")
- d.running = True
- return d
-
- def listDomainsID(self):
- return self.domains.keys()
-
- def lookupByName(self, name):
- return self.domains[name]
-
- def lookupByID(self, ID):
- return self.domains[ID]
-
- def fake_add(self, name):
- d = Domain(name, self)
- self.domains[name] = d
- return d
-
-
-def open(uri):
- return Connection(uri)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py
deleted file mode 100644
index 6681ae3f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2013 Cray Inc.
-
-import uuid
-
-ACTIVE = 'ACTIVE'
-BUILD = 'BUILD'
-DELETED = 'DELETED'
-ERROR = 'ERROR'
-UNKNOWN = 'UNKNOWN'
-
-
-# Parts used from novaclient.v1_1.
-class Client():
- def __init__(self, username, password, tenant_name, auth_url):
- self.images = Images()
- self.servers = Servers()
-
-class Images():
- images = []
-
- def list(self):
- return self.images
-
-class Servers():
- fail_to_get = False
- fail_to_start = False
- gets_until_active = 2
-
- def __init__(self):
- self.instances = {}
-
- def create(self, *boot_args, **boot_kwargs):
- instance_id = uuid.uuid4()
- instance = Instance(instance_id, self, boot_args, boot_kwargs)
- self.instances[instance_id] = instance
- return instance
-
- def get(self, instance_id):
- if not self.fail_to_get and instance_id in self.instances:
- inst = self.instances[instance_id]
- inst.gets += 1
- if inst.gets >= self.gets_until_active:
- if not self.fail_to_start:
- inst.status = ACTIVE
- else:
- inst.status = ERROR
- return inst
- else:
- raise NotFound
-
- def delete(self, instance_id):
- if instance_id in self.instances:
- del self.instances[instance_id]
-
-
-# This is returned by Servers.create().
-class Instance():
- def __init__(self, id, servers, boot_args, boot_kwargs):
- self.id = id
- self.servers = servers
- self.boot_args = boot_args
- self.boot_kwargs = boot_kwargs
- self.gets = 0
- self.status = BUILD
- self.name = 'name'
-
- def delete(self):
- self.servers.delete(self.id)
-
-# Parts used from novaclient.exceptions.
-class NotFound():
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py
deleted file mode 100644
index e91b7e5e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.application import service
-from twisted.internet import defer
-
-class FakePBManager(service.MultiService):
-
- def __init__(self):
- service.MultiService.__init__(self)
- self.setName("fake-pbmanager")
- self._registrations = []
- self._unregistrations = []
-
- def register(self, portstr, username, password, pfactory):
- if (portstr, username) not in self._registrations:
- reg = FakeRegistration(self, portstr, username)
- self._registrations.append((portstr,username,password))
- return reg
- else:
- raise KeyError, ("username '%s' is already registered on port %s"
- % (username, portstr))
-
- def _unregister(self, portstr, username):
- self._unregistrations.append((portstr, username))
- return defer.succeed(None)
-
-class FakeRegistration(object):
- def __init__(self, pbmanager, portstr, username):
- self._portstr = portstr
- self._username = username
- self._pbmanager = pbmanager
-
- def unregister(self):
- self._pbmanager._unregister(self._portstr, self._username)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py
deleted file mode 100644
index 9c583c92..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-from twisted.python import failure
-from buildbot.status.logfile import STDOUT, STDERR, HEADER
-from cStringIO import StringIO
-from buildbot.status.results import SUCCESS, FAILURE
-
-
-class FakeRemoteCommand(object):
-
- # callers should set this to the running TestCase instance
- testcase = None
-
- active = False
-
- def __init__(self, remote_command, args,
- ignore_updates=False, collectStdout=False, collectStderr=False, decodeRC={0:SUCCESS}):
- # copy the args and set a few defaults
- self.remote_command = remote_command
- self.args = args.copy()
- self.logs = {}
- self.delayedLogs = {}
- self.rc = -999
- self.collectStdout = collectStdout
- self.collectStderr = collectStderr
- self.updates = {}
- self.decodeRC = decodeRC
- if collectStdout:
- self.stdout = ''
- if collectStderr:
- self.stderr = ''
-
- def run(self, step, remote):
- # delegate back to the test case
- return self.testcase._remotecommand_run(self, step, remote)
-
- def useLog(self, log, closeWhenFinished=False, logfileName=None):
- if not logfileName:
- logfileName = log.getName()
- self.logs[logfileName] = log
-
- def useLogDelayed(self, logfileName, activateCallBack, closeWhenFinished=False):
- self.delayedLogs[logfileName] = (activateCallBack, closeWhenFinished)
-
- def interrupt(self, why):
- raise NotImplementedError
-
- def results(self):
- if self.rc in self.decodeRC:
- return self.decodeRC[self.rc]
- return FAILURE
-
- def didFail(self):
- return self.results() == FAILURE
-
- def fakeLogData(self, step, log, header='', stdout='', stderr=''):
- # note that this should not be used in the same test as useLog(Delayed)
- self.logs[log] = l = FakeLogFile(log, step)
- l.fakeData(header=header, stdout=stdout, stderr=stderr)
-
- def __repr__(self):
- return "FakeRemoteCommand("+repr(self.remote_command)+","+repr(self.args)+")"
-class FakeRemoteShellCommand(FakeRemoteCommand):
-
- def __init__(self, workdir, command, env=None,
- want_stdout=1, want_stderr=1,
- timeout=20*60, maxTime=None, logfiles={},
- usePTY="slave-config", logEnviron=True, collectStdout=False,
- collectStderr=False,
- interruptSignal=None, initialStdin=None, decodeRC={0:SUCCESS}):
- args = dict(workdir=workdir, command=command, env=env or {},
- want_stdout=want_stdout, want_stderr=want_stderr,
- initial_stdin=initialStdin,
- timeout=timeout, maxTime=maxTime, logfiles=logfiles,
- usePTY=usePTY, logEnviron=logEnviron)
- FakeRemoteCommand.__init__(self, "shell", args,
- collectStdout=collectStdout,
- collectStderr=collectStderr,
- decodeRC=decodeRC)
-
-
-class FakeLogFile(object):
-
- def __init__(self, name, step):
- self.name = name
- self.header = ''
- self.stdout = ''
- self.stderr = ''
- self.chunks = []
- self.step = step
-
- def getName(self):
- return self.name
-
- def addHeader(self, text):
- self.header += text
- self.chunks.append((HEADER, text))
-
- def addStdout(self, text):
- self.stdout += text
- self.chunks.append((STDOUT, text))
- if self.name in self.step.logobservers:
- for obs in self.step.logobservers[self.name]:
- obs.outReceived(text)
-
- def addStderr(self, text):
- self.stderr += text
- self.chunks.append((STDERR, text))
- if self.name in self.step.logobservers:
- for obs in self.step.logobservers[self.name]:
- obs.errReceived(text)
-
- def readlines(self):
- io = StringIO(self.stdout)
- return io.readlines()
-
- def getText(self):
- return ''.join([ c for str,c in self.chunks
- if str in (STDOUT, STDERR)])
- def getTextWithHeaders(self):
- return ''.join([ c for str,c in self.chunks])
-
- def getChunks(self, channels=[], onlyText=False):
- if onlyText:
- return [ data
- for (ch, data) in self.chunks
- if not channels or ch in channels ]
- else:
- return [ (ch, data)
- for (ch, data) in self.chunks
- if not channels or ch in channels ]
-
- def finish(self):
- pass
-
- def fakeData(self, header='', stdout='', stderr=''):
- if header:
- self.header += header
- self.chunks.append((HEADER, header))
- if stdout:
- self.stdout += stdout
- self.chunks.append((STDOUT, stdout))
- if stderr:
- self.stderr += stderr
- self.chunks.append((STDERR, stderr))
-
-class ExpectRemoteRef(object):
- """
- Define an expected RemoteReference in the args to an L{Expect} class
- """
-
- def __init__(self, rrclass):
- self.rrclass = rrclass
-
- def __eq__(self, other):
- return isinstance(other, self.rrclass)
-
-class Expect(object):
- """
- Define an expected L{RemoteCommand}, with the same arguments
-
- Extra behaviors of the remote command can be added to the instance, using
- class methods. Use L{Expect.log} to add a logfile, L{Expect.update} to add
- an arbitrary update, or add an integer to specify the return code (rc), or
- add a Failure instance to raise an exception. Additionally, use
- L{Expect.behavior}, passing a callable that will be invoked with the real
- command and can do what it likes:
-
- def custom_behavior(command):
- ...
- Expect('somecommand', { args='foo' })
- + Expect.behavior(custom_behavior),
- ...
-
- Expect('somecommand', { args='foo' })
- + Expect.log('stdio', stdout='foo!')
- + Expect.log('config.log', stdout='some info')
- + Expect.update('status', 'running')
- + 0, # (specifies the rc)
- ...
-
- """
-
- def __init__(self, remote_command, args, incomparable_args=[]):
- """
-
- Expect a command named C{remote_command}, with args C{args}. Any args
- in C{incomparable_args} are not cmopared, but must exist.
-
- """
- self.remote_command = remote_command
- self.incomparable_args = incomparable_args
- self.args = args
- self.result = None
- self.behaviors = []
-
- @classmethod
- def behavior(cls, callable):
- """
- Add an arbitrary behavior that is expected of this command.
- C{callable} will be invoked with the real command as an argument, and
- can do what it wishes. It will be invoked with maybeDeferred, in case
- the operation is asynchronous.
- """
- return ('callable', callable)
-
- @classmethod
- def log(self, name, **streams):
- return ('log', name, streams)
-
- @classmethod
- def update(self, name, value):
- return ('update', name, value)
-
- def __add__(self, other):
- # special-case adding an integer (return code) or failure (error)
- if isinstance(other, int):
- self.behaviors.append(('rc', other))
- elif isinstance(other, failure.Failure):
- self.behaviors.append(('err', other))
- else:
- self.behaviors.append(other)
- return self
-
- def runBehavior(self, behavior, args, command):
- """
- Implement the given behavior. Returns a Deferred.
- """
- if behavior == 'rc':
- command.rc = args[0]
- elif behavior == 'err':
- return defer.fail(args[0])
- elif behavior == 'update':
- command.updates.setdefault(args[0], []).append(args[1])
- elif behavior == 'log':
- name, streams = args
- if 'header' in streams:
- command.logs[name].addHeader(streams['header'])
- if 'stdout' in streams:
- command.logs[name].addStdout(streams['stdout'])
- if command.collectStdout:
- command.stdout += streams['stdout']
- if 'stderr' in streams:
- command.logs[name].addStderr(streams['stderr'])
- if command.collectStderr:
- command.stderr += streams['stderr']
- elif behavior == 'callable':
- return defer.maybeDeferred(lambda : args[0](command))
- else:
- return defer.fail(failure.Failure(
- AssertionError('invalid behavior %s' % behavior)))
- return defer.succeed(None)
-
- @defer.inlineCallbacks
- def runBehaviors(self, command):
- """
- Run all expected behaviors for this command
- """
- for behavior in self.behaviors:
- yield self.runBehavior(behavior[0], behavior[1:], command)
- def __repr__(self):
- return "Expect("+repr(self.remote_command)+")"
-
-class ExpectShell(Expect):
- """
- Define an expected L{RemoteShellCommand}, with the same arguments Any
- non-default arguments must be specified explicitly (e.g., usePTY).
- """
- def __init__(self, workdir, command, env={},
- want_stdout=1, want_stderr=1, initialStdin=None,
- timeout=20*60, maxTime=None, logfiles={},
- usePTY="slave-config", logEnviron=True):
- args = dict(workdir=workdir, command=command, env=env,
- want_stdout=want_stdout, want_stderr=want_stderr,
- initial_stdin=initialStdin,
- timeout=timeout, maxTime=maxTime, logfiles=logfiles,
- usePTY=usePTY, logEnviron=logEnviron)
- Expect.__init__(self, "shell", args)
- def __repr__(self):
- return "ExpectShell("+repr(self.remote_command)+repr(self.args['command'])+")"
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py
deleted file mode 100644
index e95efc50..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-class FakeSlave(object):
- slave_system = 'posix'
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py
deleted file mode 100644
index 7b0f3f44..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-class State(object):
- """
- A simple class you can use to keep track of state throughout
- a test. Just assign whatever you want to its attributes. Its
- constructor provides a shortcut to setting initial values for
- attributes
- """
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py
deleted file mode 100644
index 2adaee44..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from mock import Mock
-
-from twisted.internet import defer
-from twisted.web import server
-
-class FakeRequest(Mock):
- """
- A fake Twisted Web Request object, including some pointers to the
- buildmaster and an addChange method on that master which will append its
- arguments to self.addedChanges.
- """
-
- written = ''
- finished = False
- redirected_to = None
- failure = None
-
- def __init__(self, args={}):
- Mock.__init__(self)
-
- self.args = args
- self.site = Mock()
- self.site.buildbot_service = Mock()
- master = self.site.buildbot_service.master = Mock()
-
- self.addedChanges = []
- def addChange(**kwargs):
- self.addedChanges.append(kwargs)
- return defer.succeed(Mock())
- master.addChange = addChange
-
- self.deferred = defer.Deferred()
-
- def write(self, data):
- self.written = self.written + data
-
- def redirect(self, url):
- self.redirected_to = url
-
- def finish(self):
- self.finished = True
- self.deferred.callback(None)
-
- def processingFailed(self, f):
- self.deferred.errback(f)
-
- # work around http://code.google.com/p/mock/issues/detail?id=105
- def _get_child_mock(self, **kw):
- return Mock(**kw)
-
- # cribed from twisted.web.test._util._render
- def test_render(self, resource):
- result = resource.render(self)
- if isinstance(result, str):
- self.write(result)
- self.finish()
- return self.deferred
- elif result is server.NOT_DONE_YET:
- return self.deferred
- else:
- raise ValueError("Unexpected return value: %r" % (result,))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py
deleted file mode 100644
index e68c7e6f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.util import connector_component
-from buildbot.db import changes
-from buildbot.test.fake import fakedb
-
-class TestBadRows(connector_component.ConnectorComponentMixin,
- unittest.TestCase):
- # See bug #1952 for details. This checks that users who used a development
- # version between 0.8.3 and 0.8.4 get reasonable behavior even though some
- # rows in the change_properties database do not contain a proper [value,
- # source] tuple.
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'change_properties', 'change_files'])
- def finish_setup(_):
- self.db.changes = changes.ChangesConnectorComponent(self.db)
- d.addCallback(finish_setup)
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- def test_bogus_row_no_source(self):
- d = self.insertTestData([
- fakedb.ChangeProperty(changeid=13, property_name='devel',
- property_value='"no source"'),
- fakedb.Change(changeid=13),
- ])
- def get13(_):
- return self.db.changes.getChange(13)
- d.addCallback(get13)
- def check13(c):
- self.assertEqual(c['properties'],
- dict(devel=('no source', 'Change')))
- d.addCallback(check13)
- return d
-
- def test_bogus_row_jsoned_list(self):
- d = self.insertTestData([
- fakedb.ChangeProperty(changeid=13, property_name='devel',
- property_value='[1, 2]'),
- fakedb.Change(changeid=13),
- ])
- def get13(_):
- return self.db.changes.getChange(13)
- d.addCallback(get13)
- def check13(c):
- self.assertEqual(c['properties'],
- dict(devel=([1,2], 'Change')))
- d.addCallback(check13)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py
deleted file mode 100644
index c8d3b2a7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.db.connector import DBConnector
-from buildbot.test.util import change_import
-from buildbot.test.fake import fakemaster
-
-class TestUnicodeChanges(change_import.ChangeImportMixin, unittest.TestCase):
- def setUp(self):
- d = self.setUpChangeImport()
- def make_dbc(_):
- master = fakemaster.make_master()
- master.config.db['db_url'] = self.db_url
- self.db = DBConnector(master, self.basedir)
- return self.db.setup(check_version=False)
-
- d.addCallback(make_dbc)
- # note the connector isn't started, as we're testing upgrades
- return d
-
- def tearDown(self):
- return self.tearDownChangeImport()
-
- # tests
-
- def testUnicodeChange(self):
- self.make_pickle(
- self.make_change(
- who=u"Frosty the \N{SNOWMAN}".encode("utf8"),
- files=["foo"],
- comments=u"Frosty the \N{SNOWMAN}".encode("utf8"),
- branch="b1",
- revision=12345))
-
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.changes.getChange(1))
- def check(c):
- self.failIf(c is None)
- self.assertEquals(c['author'], u"Frosty the \N{SNOWMAN}")
- self.assertEquals(c['comments'], u"Frosty the \N{SNOWMAN}")
- d.addCallback(check)
- return d
-
- def testNonUnicodeChange(self):
- self.make_pickle(
- self.make_change(
- who="\xff\xff\x00",
- files=["foo"],
- comments="\xff\xff\x00",
- branch="b1",
- revision=12345))
-
- d = self.db.model.upgrade()
- return self.assertFailure(d, UnicodeError)
-
- def testAsciiChange(self):
- self.make_pickle(
- self.make_change(
- who="Frosty the Snowman",
- files=["foo"],
- comments="Frosty the Snowman",
- branch="b1",
- revision=12345))
-
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.changes.getChange(1))
- def check(c):
- self.failIf(c is None)
- self.assertEquals(c['author'], "Frosty the Snowman")
- self.assertEquals(c['comments'], "Frosty the Snowman")
- d.addCallback(check)
- return d
-
- def testUTF16Change(self):
- self.make_pickle(
- self.make_change(
- who=u"Frosty the \N{SNOWMAN}".encode("utf16"),
- files=[u"foo".encode('utf16')],
- comments=u"Frosty the \N{SNOWMAN}".encode("utf16"),
- branch="b1",
- revision=12345),
- # instead of running contrib/fix_changes_pickle_encoding.py, we
- # just call the changemanager's recode_changes directly - it's
- # the function at the heart of the script anyway.
- recode_fn=lambda cm : cm.recode_changes('utf16', quiet=True))
-
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.changes.getChange(1))
- def check(c):
- self.failIf(c is None)
- self.assertEquals(c['author'], u"Frosty the \N{SNOWMAN}")
- self.assertEquals(c['comments'], u"Frosty the \N{SNOWMAN}")
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py
deleted file mode 100644
index 14a474ff..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.trial import unittest
-
-class OldImportPaths(unittest.TestCase):
- """
- Test that old, deprecated import paths still work.
- """
-
- def test_scheduler_Scheduler(self):
- from buildbot.scheduler import Scheduler
- assert Scheduler
-
- def test_schedulers_basic_Scheduler(self):
- # renamed to basic.SingleBranchScheduler
- from buildbot.schedulers.basic import Scheduler
- assert Scheduler
-
- def test_scheduler_AnyBranchScheduler(self):
- from buildbot.scheduler import AnyBranchScheduler
- assert AnyBranchScheduler
-
- def test_scheduler_basic_Dependent(self):
- from buildbot.schedulers.basic import Dependent
- assert Dependent
-
- def test_scheduler_Dependent(self):
- from buildbot.scheduler import Dependent
- assert Dependent
-
- def test_scheduler_Periodic(self):
- from buildbot.scheduler import Periodic
- assert Periodic
-
- def test_scheduler_Nightly(self):
- from buildbot.scheduler import Nightly
- assert Nightly
-
- def test_scheduler_Triggerable(self):
- from buildbot.scheduler import Triggerable
- assert Triggerable
-
- def test_scheduler_Try_Jobdir(self):
- from buildbot.scheduler import Try_Jobdir
- assert Try_Jobdir
-
- def test_scheduler_Try_Userpass(self):
- from buildbot.scheduler import Try_Userpass
- assert Try_Userpass
-
- def test_changes_changes_ChangeMaster(self):
- # this must exist to open old changes pickles
- from buildbot.changes.changes import ChangeMaster
- assert ChangeMaster
-
- def test_changes_changes_Change(self):
- # this must exist to open old changes pickles
- from buildbot.changes.changes import Change
- assert Change
-
- def test_status_html_Webstatus(self):
- from buildbot.status.html import WebStatus
- assert WebStatus
-
- def test_schedulers_filter_ChangeFilter(self):
- # this was the location of ChangeFilter until 0.8.4
- from buildbot.schedulers.filter import ChangeFilter
- assert ChangeFilter
-
- def test_process_base_Build(self):
- from buildbot.process.base import Build
- assert Build
-
- def test_buildrequest_BuildRequest(self):
- from buildbot.buildrequest import BuildRequest
- assert BuildRequest
-
- def test_sourcestamp_SourceStamp(self):
- # this must exist, and the class must be defined at this package path,
- # in order for old build pickles to be loaded.
- from buildbot.sourcestamp import SourceStamp
- assert SourceStamp
-
- def test_process_subunitlogobserver_SubunitShellCommand(self):
- from buildbot.process.subunitlogobserver import SubunitShellCommand
- assert SubunitShellCommand
-
- def test_status_builder_results(self):
- # these symbols are now in buildbot.status.results, but lots of user
- # code references them here:
- from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, SKIPPED
- from buildbot.status.builder import EXCEPTION, RETRY, Results
- from buildbot.status.builder import worst_status
- # reference the symbols to avoid failure from pyflakes
- (SUCCESS, WARNINGS, FAILURE, SKIPPED,EXCEPTION, RETRY, Results,
- worst_status)
-
- def test_status_builder_BuildStepStatus(self):
- from buildbot.status.builder import BuildStepStatus
- assert BuildStepStatus
-
- def test_status_builder_BuildSetStatus(self):
- from buildbot.status.builder import BuildSetStatus
- assert BuildSetStatus
-
- def test_status_builder_TestResult(self):
- from buildbot.status.builder import TestResult
- assert TestResult
-
- def test_status_builder_LogFile(self):
- from buildbot.status.builder import LogFile
- assert LogFile
-
- def test_status_builder_HTMLLogFile(self):
- from buildbot.status.builder import HTMLLogFile
- assert HTMLLogFile
-
- def test_status_builder_SlaveStatus(self):
- from buildbot.status.builder import SlaveStatus
- assert SlaveStatus
-
- def test_status_builder_Status(self):
- from buildbot.status.builder import Status
- assert Status
-
- def test_status_builder_Event(self):
- from buildbot.status.builder import Event
- assert Event
-
- def test_status_builder_BuildStatus(self):
- from buildbot.status.builder import BuildStatus
- assert BuildStatus
-
- def test_steps_source_Source(self):
- from buildbot.steps.source import Source
- assert Source
-
- def test_steps_source_CVS(self):
- from buildbot.steps.source import CVS
- assert CVS
-
- def test_steps_source_SVN(self):
- from buildbot.steps.source import SVN
- assert SVN
-
- def test_steps_source_Git(self):
- from buildbot.steps.source import Git
- assert Git
-
- def test_steps_source_Darcs(self):
- from buildbot.steps.source import Darcs
- assert Darcs
-
- def test_steps_source_Repo(self):
- from buildbot.steps.source import Repo
- assert Repo
-
- def test_steps_source_Bzr(self):
- from buildbot.steps.source import Bzr
- assert Bzr
-
- def test_steps_source_Mercurial(self):
- from buildbot.steps.source import Mercurial
- assert Mercurial
-
- def test_steps_source_P4(self):
- from buildbot.steps.source import P4
- assert P4
-
- def test_steps_source_Monotone(self):
- from buildbot.steps.source import Monotone
- assert Monotone
-
- def test_steps_source_BK(self):
- from buildbot.steps.source import BK
- assert BK
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py
deleted file mode 100644
index 8c575a34..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildbot.steps.shell import ShellCommand, SetPropertyFromCommand
-from buildbot.process.properties import WithProperties, Properties
-from buildbot.process.factory import BuildFactory
-from buildbot.sourcestamp import SourceStamp
-from buildbot import config
-
-class FakeSlaveBuilder:
- slave = None
-
-
-class FakeBuildStatus:
- def __init__(self):
- self.names = []
-
- def addStepWithName(self, name):
- self.names.append(name)
- return FakeStepStatus()
-
- def getProperties(self):
- return Properties()
-
- def setSourceStamps(self, ss_list):
- self.ss_list = ss_list
-
- def setReason(self, reason):
- self.reason = reason
-
- def setBlamelist(self, bl):
- self.bl = bl
-
- def setProgress(self, p):
- self.progress = p
-
-
-class FakeStepStatus:
- txt = None
- def setText(self, txt):
- self.txt = txt
-
- def setProgress(self, sp):
- pass
-
-
-class FakeBuildRequest:
- def __init__(self, reason, sources, buildername):
- self.reason = reason
- self.sources = sources
- self.buildername = buildername
- self.changes = []
- self.properties = Properties()
-
- def mergeSourceStampsWith(self, others):
- return [source for source in self.sources.itervalues()]
-
- def mergeReasons(self, others):
- return self.reason
-
-
-class TestShellCommandProperties(unittest.TestCase):
- def testCommand(self):
- f = BuildFactory()
- f.addStep(SetPropertyFromCommand(command=["echo", "value"], property="propname"))
- f.addStep(ShellCommand(command=["echo", WithProperties("%(propname)s")]))
-
- ss = SourceStamp()
-
- req = FakeBuildRequest("Testing", {ss.repository:ss}, None)
-
- b = f.newBuild([req])
- b.build_status = FakeBuildStatus()
- b.slavebuilder = FakeSlaveBuilder()
-
- # This shouldn't raise an exception
- b.setupBuild(None)
-
-
-class TestSetProperty(unittest.TestCase):
- def testGoodStep(self):
- f = BuildFactory()
- f.addStep(SetPropertyFromCommand(command=["echo", "value"], property="propname"))
-
- ss = SourceStamp()
-
- req = FakeBuildRequest("Testing", {ss.repository:ss}, None)
-
- b = f.newBuild([req])
- b.build_status = FakeBuildStatus()
- b.slavebuilder = FakeSlaveBuilder()
-
- # This shouldn't raise an exception
- b.setupBuild(None)
-
- def testErrorBothSet(self):
- self.assertRaises(config.ConfigErrors,
- SetPropertyFromCommand, command=["echo", "value"], property="propname", extract_fn=lambda x:{"propname": "hello"})
-
- def testErrorNoneSet(self):
- self.assertRaises(config.ConfigErrors,
- SetPropertyFromCommand, command=["echo", "value"])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py
deleted file mode 100644
index 66d62a8a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildbot.sourcestamp import SourceStamp
-from buildbot.changes.changes import Change
-
-class TestSourceStampRevision(unittest.TestCase):
- def testNoRevision(self):
- c = Change(who="catlee", files=["foo"], comments="", branch="b1", revision=None)
- ss = SourceStamp(changes=[c])
-
- self.assertEquals(ss.revision, None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py
deleted file mode 100644
index cea65b84..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-import re
-from buildbot.steps.shell import WarningCountingShellCommand
-
-class TestWarningCountingShellCommand(unittest.TestCase):
-
- # Makes sure that it is possible to supress warnings even if the
- # warning extractor does not provie line information
- def testSuppressingLinelessWarningsPossible(self):
- # Use a warningExtractor that does not provide line
- # information
- w = WarningCountingShellCommand(
- warningExtractor=WarningCountingShellCommand.warnExtractWholeLine)
-
- # Add suppression manually instead of using suppressionFile
- fileRe = None
- warnRe = ".*SUPPRESS.*"
- start = None
- end = None
- suppression = (fileRe, warnRe, start, end)
- w.addSuppression([suppression])
-
- # Now call maybeAddWarning
- warnings = []
- line = "this warning should be SUPPRESSed"
- match = re.match(".*warning.*", line)
- w.maybeAddWarning(warnings, line, match)
-
- # Finally make the suppressed warning was *not* added to the
- # list of warnings
- expectedWarnings = 0
- self.assertEquals(len(warnings), expectedWarnings)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py
deleted file mode 100644
index 0791d1f3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import base64
-import cPickle
-from twisted.trial import unittest
-from twisted.persisted import styles
-from buildbot.status.buildstep import BuildStepStatus
-from buildbot.status.build import BuildStatus
-from buildbot.status.builder import BuilderStatus
-
-class StatusPickles(unittest.TestCase):
- # This pickle was created with Buildbot tag v0.8.1:
- # >>> bs = BuildStatus(BuilderStatus('test'), 1)
- # >>> bss = BuildStepStatus(bs)
- # >>> pkl = pickle.dumps(dict(buildstatus=bs, buildstepstatus=bss))
- pickle_b64 = """
- KGRwMQpTJ2J1aWxkc3RlcHN0YXR1cycKcDIKKGlidWlsZGJvdC5zdGF0dXMuYnVpbGRlcgp
- CdWlsZFN0ZXBTdGF0dXMKcDMKKGRwNApTJ2xvZ3MnCnA1CihscDYKc1MndXJscycKcDcKKG
- RwOApzUydzdGF0aXN0aWNzJwpwOQooZHAxMApzUydidWlsZGJvdC5zdGF0dXMuYnVpbGRlc
- i5CdWlsZFN0ZXBTdGF0dXMucGVyc2lzdGVuY2VWZXJzaW9uJwpwMTEKSTIKc2JzUydidWls
- ZHN0YXR1cycKcDEyCihpYnVpbGRib3Quc3RhdHVzLmJ1aWxkZXIKQnVpbGRTdGF0dXMKcDE
- zCihkcDE0ClMnbnVtYmVyJwpwMTUKSTEKc1MnYnVpbGRib3Quc3RhdHVzLmJ1aWxkZXIuQn
- VpbGRTdGF0dXMucGVyc2lzdGVuY2VWZXJzaW9uJwpwMTYKSTMKc1MnZmluaXNoZWQnCnAxN
- wpJMDEKc1Mnc3RlcHMnCnAxOAoobHAxOQpzUydwcm9wZXJ0aWVzJwpwMjAKKGlidWlsZGJv
- dC5wcm9jZXNzLnByb3BlcnRpZXMKUHJvcGVydGllcwpwMjEKKGRwMjIKZzIwCihkcDIzCnN
- ic1MndGVzdFJlc3VsdHMnCnAyNAooZHAyNQpzYnMu"""
- pickle_data = base64.b64decode(pickle_b64)
-
- # In 0.8.1, the following persistence versions were in effect:
- #
- # BuildStepStatus: 2
- # BuildStatus: 3
- # BuilderStatus: 1
- #
- # the regression that can occur here is that if the classes are renamed,
- # then older upgradeToVersionX may be run in cases where it should not;
- # this error can be "silent" since the upgrade will not fail.
-
- def test_upgrade(self):
- self.patch(BuildStepStatus, 'upgradeToVersion1', lambda _ :
- self.fail("BuildStepStatus.upgradeToVersion1 called"))
- self.patch(BuildStatus, 'upgradeToVersion1', lambda _ :
- self.fail("BuildStatus.upgradeToVersion1 called"))
- self.patch(BuilderStatus, 'upgradeToVersion1', lambda _ :
- self.fail("BuilderStatus.upgradeToVersion1 called"))
- pkl_result = cPickle.loads(self.pickle_data)
- styles.doUpgrade()
- del pkl_result
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py
deleted file mode 100644
index 7a3509ff..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# this file imports a number of source files that are not
-# included in the coverage because none of the tests import
-# them; this results in a more accurate total coverage percent.
-
-modules = [] # for the benefit of pyflakes
-
-from buildbot import buildslave
-modules.extend([buildslave])
-from buildbot.changes import p4poller, svnpoller
-modules.extend([p4poller, svnpoller])
-from buildbot.clients import base, sendchange, tryclient
-modules.extend([base, sendchange, tryclient])
-from buildbot.process import mtrlogobserver, subunitlogobserver
-modules.extend([mtrlogobserver, subunitlogobserver])
-from buildbot.scripts import checkconfig, logwatcher, reconfig, runner
-modules.extend([checkconfig, logwatcher, reconfig, runner])
-from buildbot.status import client, html, status_gerrit, status_push
-modules.extend([client, html, status_gerrit, status_push])
-from buildbot.status import tinderbox, words
-modules.extend([tinderbox, words])
-from buildbot.status.web import baseweb, build, builder, buildstatus, changes
-modules.extend([baseweb, build, builder, buildstatus, changes])
-from buildbot.status.web import console, feeds, grid, logs, olpb, root, slaves
-modules.extend([console, feeds, grid, logs, olpb, root, slaves])
-from buildbot.status.web import status_json, step, tests, waterfall
-modules.extend([status_json, step, tests, waterfall])
-from buildbot.steps import master, maxq, python, python_twisted, subunit
-modules.extend([master, maxq, python, python_twisted, subunit])
-from buildbot.steps import trigger, vstudio
-modules.extend([trigger, vstudio])
-from buildbot.steps.package.rpm import rpmbuild, rpmlint, rpmspec
-modules.extend([rpmbuild, rpmlint, rpmspec])
-from buildbot.util import eventual
-modules.extend([eventual])
-
-# require gobject
-#import buildbot.clients.gtkPanes
-#import buildbot.clients.debug
-
-# requires mercurial
-#import buildbot.changes.hgbuildbot
-
-# requires libboto
-#import buildbot.ec2buildslave
-
-# requires libvirt
-#import buildbot.libvirtbuildslave
-
-# requires pycrypto
-#import buildbot.manhole
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py
deleted file mode 100644
index 250115aa..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config, locks
-from buildbot.buildslave import base
-from buildbot.test.fake import fakemaster, pbmanager
-from buildbot.test.fake.botmaster import FakeBotMaster
-
-class TestAbstractBuildSlave(unittest.TestCase):
-
- class ConcreteBuildSlave(base.AbstractBuildSlave):
- pass
-
- def test_constructor_minimal(self):
- bs = self.ConcreteBuildSlave('bot', 'pass')
- self.assertEqual(bs.slavename, 'bot')
- self.assertEqual(bs.password, 'pass')
- self.assertEqual(bs.max_builds, None)
- self.assertEqual(bs.notify_on_missing, [])
- self.assertEqual(bs.missing_timeout, 3600)
- self.assertEqual(bs.properties.getProperty('slavename'), 'bot')
- self.assertEqual(bs.access, [])
- self.assertEqual(bs.keepalive_interval, 3600)
-
- def test_constructor_full(self):
- lock1, lock2 = mock.Mock(name='lock1'), mock.Mock(name='lock2')
- bs = self.ConcreteBuildSlave('bot', 'pass',
- max_builds=2,
- notify_on_missing=['me@me.com'],
- missing_timeout=120,
- properties={'a':'b'},
- locks=[lock1, lock2],
- keepalive_interval=60)
- self.assertEqual(bs.max_builds, 2)
- self.assertEqual(bs.notify_on_missing, ['me@me.com'])
- self.assertEqual(bs.missing_timeout, 120)
- self.assertEqual(bs.properties.getProperty('a'), 'b')
- self.assertEqual(bs.access, [lock1, lock2])
- self.assertEqual(bs.keepalive_interval, 60)
-
- def test_constructor_notify_on_missing_not_list(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing='foo@foo.com')
- # turned into a list:
- self.assertEqual(bs.notify_on_missing, ['foo@foo.com'])
-
- def test_constructor_notify_on_missing_not_string(self):
- self.assertRaises(config.ConfigErrors, lambda :
- self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['a@b.com', 13]))
-
- @defer.inlineCallbacks
- def do_test_reconfigService(self, old, old_port, new, new_port):
- master = self.master = fakemaster.make_master()
- old.master = master
- if old_port:
- self.old_registration = old.registration = \
- pbmanager.FakeRegistration(master.pbmanager, old_port, old.slavename)
- old.registered_port = old_port
- old.missing_timer = mock.Mock(name='missing_timer')
- old.startService()
-
- new_config = mock.Mock()
- new_config.slavePortnum = new_port
- new_config.slaves = [ new ]
-
- yield old.reconfigService(new_config)
-
- @defer.inlineCallbacks
- def test_reconfigService_attrs(self):
- old = self.ConcreteBuildSlave('bot', 'pass',
- max_builds=2,
- notify_on_missing=['me@me.com'],
- missing_timeout=120,
- properties={'a':'b'},
- keepalive_interval=60)
- new = self.ConcreteBuildSlave('bot', 'pass',
- max_builds=3,
- notify_on_missing=['her@me.com'],
- missing_timeout=121,
- properties={'a':'c'},
- keepalive_interval=61)
-
- old.updateSlave = mock.Mock(side_effect=lambda : defer.succeed(None))
-
- yield self.do_test_reconfigService(old, 'tcp:1234', new, 'tcp:1234')
-
- self.assertEqual(old.max_builds, 3)
- self.assertEqual(old.notify_on_missing, ['her@me.com'])
- self.assertEqual(old.missing_timeout, 121)
- self.assertEqual(old.properties.getProperty('a'), 'c')
- self.assertEqual(old.keepalive_interval, 61)
- self.assertEqual(self.master.pbmanager._registrations, [])
- self.assertTrue(old.updateSlave.called)
-
- @defer.inlineCallbacks
- def test_reconfigService_has_properties(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- yield self.do_test_reconfigService(old, 'tcp:1234', old, 'tcp:1234')
- self.assertTrue(old.properties.getProperty('slavename'), 'bot')
-
- @defer.inlineCallbacks
- def test_reconfigService_initial_registration(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- yield self.do_test_reconfigService(old, None, old, 'tcp:1234')
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:1234', 'bot', 'pass')])
-
- @defer.inlineCallbacks
- def test_reconfigService_reregister_password(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- new = self.ConcreteBuildSlave('bot', 'newpass')
-
- yield self.do_test_reconfigService(old, 'tcp:1234', new, 'tcp:1234')
-
- self.assertEqual(old.password, 'newpass')
- self.assertEqual(self.master.pbmanager._unregistrations, [('tcp:1234', 'bot')])
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:1234', 'bot', 'newpass')])
-
- @defer.inlineCallbacks
- def test_reconfigService_reregister_port(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- new = self.ConcreteBuildSlave('bot', 'pass')
-
- yield self.do_test_reconfigService(old, 'tcp:1234', new, 'tcp:5678')
-
- self.assertEqual(self.master.pbmanager._unregistrations, [('tcp:1234', 'bot')])
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:5678', 'bot', 'pass')])
-
- @defer.inlineCallbacks
- def test_stopService(self):
- master = self.master = fakemaster.make_master()
- slave = self.ConcreteBuildSlave('bot', 'pass')
- slave.master = master
- slave.startService()
-
- config = mock.Mock()
- config.slavePortnum = "tcp:1234"
- config.slaves = [ slave ]
-
- yield slave.reconfigService(config)
- yield slave.stopService()
-
- self.assertEqual(self.master.pbmanager._unregistrations, [('tcp:1234', 'bot')])
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:1234', 'bot', 'pass')])
-
- # FIXME: Test that reconfig properly deals with
- # 1) locks
- # 2) telling slave about builder
- # 3) missing timer
- # in both the initial config and a reconfiguration.
-
- def test_startMissingTimer_no_parent(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['abc'],
- missing_timeout=10)
- bs.startMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_startMissingTimer_no_timeout(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['abc'],
- missing_timeout=0)
- bs.parent = mock.Mock()
- bs.startMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_startMissingTimer_no_notify(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- missing_timeout=3600)
- bs.parent = mock.Mock()
- bs.startMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_missing_timer(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['abc'],
- missing_timeout=100)
- bs.parent = mock.Mock()
- bs.startMissingTimer()
- self.assertNotEqual(bs.missing_timer, None)
- bs.stopMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_setServiceParent_started(self):
- master = self.master = fakemaster.make_master()
- botmaster = FakeBotMaster(master)
- botmaster.startService()
- bs = self.ConcreteBuildSlave('bot', 'pass')
- bs.setServiceParent(botmaster)
- self.assertEqual(bs.botmaster, botmaster)
- self.assertEqual(bs.master, master)
-
- def test_setServiceParent_masterLocks(self):
- """
- http://trac.buildbot.net/ticket/2278
- """
- master = self.master = fakemaster.make_master()
- botmaster = FakeBotMaster(master)
- botmaster.startService()
- lock = locks.MasterLock('masterlock')
- bs = self.ConcreteBuildSlave('bot', 'pass', locks = [lock.access("counting")])
- bs.setServiceParent(botmaster)
-
- def test_setServiceParent_slaveLocks(self):
- """
- http://trac.buildbot.net/ticket/2278
- """
- master = self.master = fakemaster.make_master()
- botmaster = FakeBotMaster(master)
- botmaster.startService()
- lock = locks.SlaveLock('lock')
- bs = self.ConcreteBuildSlave('bot', 'pass', locks = [lock.access("counting")])
- bs.setServiceParent(botmaster)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py
deleted file mode 100644
index 2478e46c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, utils
-from twisted.python import failure
-from buildbot import config
-from buildbot.test.fake import libvirt
-from buildbot.test.util import compat
-from buildbot.buildslave import libvirt as libvirtbuildslave
-
-
-class TestLibVirtSlave(unittest.TestCase):
-
- class ConcreteBuildSlave(libvirtbuildslave.LibVirtSlave):
- pass
-
- def setUp(self):
- self.patch(libvirtbuildslave, "libvirt", libvirt)
- self.conn = libvirtbuildslave.Connection("test://")
- self.lvconn = self.conn.connection
-
- def test_constructor_nolibvirt(self):
- self.patch(libvirtbuildslave, "libvirt", None)
- self.assertRaises(config.ConfigErrors, self.ConcreteBuildSlave,
- 'bot', 'pass', None, 'path', 'path')
-
- def test_constructor_minimal(self):
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'path', 'otherpath')
- yield bs._find_existing_deferred
- self.assertEqual(bs.slavename, 'bot')
- self.assertEqual(bs.password, 'pass')
- self.assertEqual(bs.connection, self.conn)
- self.assertEqual(bs.image, 'path')
- self.assertEqual(bs.base_image, 'otherpath')
- self.assertEqual(bs.keepalive_interval, 3600)
-
- @defer.inlineCallbacks
- def test_find_existing(self):
- d = self.lvconn.fake_add("bot")
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
-
- self.assertEqual(bs.domain.domain, d)
- self.assertEqual(bs.substantiated, True)
-
- @defer.inlineCallbacks
- def test_prepare_base_image_none(self):
- self.patch(utils, "getProcessValue", mock.Mock())
- utils.getProcessValue.side_effect = lambda x,y: defer.succeed(0)
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', None)
- yield bs._find_existing_deferred
- yield bs._prepare_base_image()
-
- self.assertEqual(utils.getProcessValue.call_count, 0)
-
- @defer.inlineCallbacks
- def test_prepare_base_image_cheap(self):
- self.patch(utils, "getProcessValue", mock.Mock())
- utils.getProcessValue.side_effect = lambda x,y: defer.succeed(0)
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
- yield bs._prepare_base_image()
-
- utils.getProcessValue.assert_called_with(
- "qemu-img", ["create", "-b", "o", "-f", "qcow2", "p"])
-
- @defer.inlineCallbacks
- def test_prepare_base_image_full(self):
- pass
- self.patch(utils, "getProcessValue", mock.Mock())
- utils.getProcessValue.side_effect = lambda x,y: defer.succeed(0)
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
- bs.cheap_copy = False
- yield bs._prepare_base_image()
-
- utils.getProcessValue.assert_called_with(
- "cp", ["o", "p"])
-
- @defer.inlineCallbacks
- def test_start_instance(self):
- bs = self.ConcreteBuildSlave('b', 'p', self.conn, 'p', 'o',
- xml='<xml/>')
-
- prep = mock.Mock()
- prep.side_effect = lambda: defer.succeed(0)
- self.patch(bs, "_prepare_base_image", prep)
-
- yield bs._find_existing_deferred
- started = yield bs.start_instance(mock.Mock())
-
- self.assertEqual(started, True)
-
- @compat.usesFlushLoggedErrors
- @defer.inlineCallbacks
- def test_start_instance_create_fails(self):
- bs = self.ConcreteBuildSlave('b', 'p', self.conn, 'p', 'o',
- xml='<xml/>')
-
- prep = mock.Mock()
- prep.side_effect = lambda: defer.succeed(0)
- self.patch(bs, "_prepare_base_image", prep)
-
- create = mock.Mock()
- create.side_effect = lambda self : defer.fail(
- failure.Failure(RuntimeError('oh noes')))
- self.patch(libvirtbuildslave.Connection, 'create', create)
-
- yield bs._find_existing_deferred
- started = yield bs.start_instance(mock.Mock())
-
- self.assertEqual(bs.domain, None)
- self.assertEqual(started, False)
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
-
- @defer.inlineCallbacks
- def setup_canStartBuild(self):
- bs = self.ConcreteBuildSlave('b', 'p', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
- bs.updateLocks()
- defer.returnValue(bs)
-
- @defer.inlineCallbacks
- def test_canStartBuild(self):
- bs = yield self.setup_canStartBuild()
- self.assertEqual(bs.canStartBuild(), True)
-
- @defer.inlineCallbacks
- def test_canStartBuild_notready(self):
- """
- If a LibVirtSlave hasnt finished scanning for existing VMs then we shouldn't
- start builds on it as it might create a 2nd VM when we want to reuse the existing
- one.
- """
- bs = yield self.setup_canStartBuild()
- bs.ready = False
- self.assertEqual(bs.canStartBuild(), False)
-
- @defer.inlineCallbacks
- def test_canStartBuild_domain_and_not_connected(self):
- """
- If we've found that the VM this slave would instance already exists but hasnt
- connected then we shouldn't start builds or we'll end up with a dupe.
- """
- bs = yield self.setup_canStartBuild()
- bs.domain = mock.Mock()
- self.assertEqual(bs.canStartBuild(), False)
-
- @defer.inlineCallbacks
- def test_canStartBuild_domain_and_connected(self):
- """
- If we've found an existing VM and it is connected then we should start builds
- """
- bs = yield self.setup_canStartBuild()
- bs.domain = mock.Mock()
- isconnected = mock.Mock()
- isconnected.return_value = True
- self.patch(bs, "isConnected", isconnected)
- self.assertEqual(bs.canStartBuild(), True)
-
-
-class TestWorkQueue(unittest.TestCase):
-
- def setUp(self):
- self.queue = libvirtbuildslave.WorkQueue()
-
- def delayed_success(self):
- def work():
- d = defer.Deferred()
- reactor.callLater(0, d.callback, True)
- return d
- return work
-
- def delayed_errback(self):
- def work():
- d = defer.Deferred()
- reactor.callLater(0, d.errback,
- failure.Failure(RuntimeError("Test failure")))
- return d
- return work
-
- def expect_errback(self, d):
- def shouldnt_get_called(f):
- self.failUnlessEqual(True, False)
- d.addCallback(shouldnt_get_called)
- def errback(f):
- #log.msg("errback called?")
- pass
- d.addErrback(errback)
- return d
-
- def test_handle_exceptions(self):
- def work():
- raise ValueError
- return self.expect_errback(self.queue.execute(work))
-
- def test_handle_immediate_errback(self):
- def work():
- return defer.fail(RuntimeError("Sad times"))
- return self.expect_errback(self.queue.execute(work))
-
- def test_handle_delayed_errback(self):
- work = self.delayed_errback()
- return self.expect_errback(self.queue.execute(work))
-
- def test_handle_immediate_success(self):
- def work():
- return defer.succeed(True)
- return self.queue.execute(work)
-
- def test_handle_delayed_success(self):
- work = self.delayed_success()
- return self.queue.execute(work)
-
- def test_single_pow_fires(self):
- return self.queue.execute(self.delayed_success())
-
- def test_single_pow_errors_gracefully(self):
- d = self.queue.execute(self.delayed_errback())
- return self.expect_errback(d)
-
- def test_fail_doesnt_break_further_work(self):
- self.expect_errback(self.queue.execute(self.delayed_errback()))
- return self.queue.execute(self.delayed_success())
-
- def test_second_pow_fires(self):
- self.queue.execute(self.delayed_success())
- return self.queue.execute(self.delayed_success())
-
- def test_work(self):
- # We want these deferreds to fire in order
- flags = {1: False, 2: False, 3: False }
-
- # When first deferred fires, flags[2] and flags[3] should still be false
- # flags[1] shouldnt already be set, either
- d1 = self.queue.execute(self.delayed_success())
- def cb1(res):
- self.failUnlessEqual(flags[1], False)
- flags[1] = True
- self.failUnlessEqual(flags[2], False)
- self.failUnlessEqual(flags[3], False)
- d1.addCallback(cb1)
-
- # When second deferred fires, only flags[3] should be set
- # flags[2] should definitely be False
- d2 = self.queue.execute(self.delayed_success())
- def cb2(res):
- assert flags[2] == False
- flags[2] = True
- assert flags[1] == True
- assert flags[3] == False
- d2.addCallback(cb2)
-
- # When third deferred fires, only flags[3] should be unset
- d3 = self.queue.execute(self.delayed_success())
- def cb3(res):
- assert flags[3] == False
- flags[3] = True
- assert flags[1] == True
- assert flags[2] == True
- d3.addCallback(cb3)
-
- return defer.DeferredList([d1, d2, d3], fireOnOneErrback=True)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py
deleted file mode 100644
index dcb0916f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2013 Cray Inc.
-
-import mock
-from twisted.trial import unittest
-from buildbot import config, interfaces
-from buildbot.buildslave import openstack
-import buildbot.test.fake.openstack as novaclient
-
-class TestOpenStackBuildSlave(unittest.TestCase):
-
- def setUp(self):
- self.patch(openstack, "nce", novaclient)
- self.patch(openstack, "client", novaclient)
-
- def test_constructor_nonova(self):
- self.patch(openstack, "nce", None)
- self.patch(openstack, "client", None)
- self.assertRaises(config.ConfigErrors,
- openstack.OpenStackLatentBuildSlave, 'bot', 'pass', flavor=1,
- image='image', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
-
- def test_constructor_minimal(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- self.assertEqual(bs.slavename, 'bot')
- self.assertEqual(bs.password, 'pass')
- self.assertEqual(bs.flavor, 1)
- self.assertEqual(bs.image, 'image')
- self.assertEqual(bs.os_username, 'user')
- self.assertEqual(bs.os_password, 'pass')
- self.assertEqual(bs.os_tenant_name, 'tenant')
- self.assertEqual(bs.os_auth_url, 'auth')
-
- def test_getImage_string(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- self.assertEqual('image-uuid', bs._getImage(None))
-
- def test_getImage_callable(self):
- def image_callable(images):
- return images[0]
-
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image=image_callable, os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- os_client = novaclient.Client('user', 'pass', 'tenant', 'auth')
- os_client.images.images = ['uuid1', 'uuid2', 'uuid2']
- self.assertEqual('uuid1', bs._getImage(os_client))
-
- def test_start_instance_already_exists(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs.instance = mock.Mock()
- self.assertRaises(ValueError, bs.start_instance, None)
-
- def test_start_instance_fail_to_find(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs._poll_resolution = 0
- self.patch(novaclient.Servers, 'fail_to_get', True)
- self.assertRaises(interfaces.LatentBuildSlaveFailedToSubstantiate,
- bs._start_instance)
-
- def test_start_instance_fail_to_start(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs._poll_resolution = 0
- self.patch(novaclient.Servers, 'fail_to_start', True)
- self.assertRaises(interfaces.LatentBuildSlaveFailedToSubstantiate,
- bs._start_instance)
-
- def test_start_instance_success(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs._poll_resolution = 0
- uuid, image_uuid, time_waiting = bs._start_instance()
- self.assertTrue(uuid)
- self.assertEqual(image_uuid, 'image-uuid')
- self.assertTrue(time_waiting)
-
- def test_start_instance_check_meta(self):
- meta_arg = {'some_key': 'some-value'}
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth', meta=meta_arg)
- bs._poll_resolution = 0
- uuid, image_uuid, time_waiting = bs._start_instance()
- self.assertIn('meta', bs.instance.boot_kwargs)
- self.assertIdentical(bs.instance.boot_kwargs['meta'], meta_arg)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py
deleted file mode 100644
index 5024b3c6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, task
-from buildbot.test.util import changesource, compat
-from buildbot.changes import base
-
-class TestPollingChangeSource(changesource.ChangeSourceMixin, unittest.TestCase):
- class Subclass(base.PollingChangeSource):
- pass
-
- def setUp(self):
- # patch in a Clock so we can manipulate the reactor's time
- self.clock = task.Clock()
- self.patch(reactor, 'callLater', self.clock.callLater)
- self.patch(reactor, 'seconds', self.clock.seconds)
-
- d = self.setUpChangeSource()
- def create_changesource(_):
- self.attachChangeSource(self.Subclass())
- d.addCallback(create_changesource)
- return d
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def runClockFor(self, _, secs):
- self.clock.pump([1.0] * secs)
-
- def test_loop_loops(self):
- # track when poll() gets called
- loops = []
- self.changesource.poll = \
- lambda : loops.append(self.clock.seconds())
-
- self.changesource.pollInterval = 5
- self.startChangeSource()
-
- d = defer.Deferred()
- d.addCallback(self.runClockFor, 12)
- def check(_):
- # note that it does *not* poll at time 0
- self.assertEqual(loops, [5.0, 10.0])
- d.addCallback(check)
- reactor.callWhenRunning(d.callback, None)
- return d
-
- @compat.usesFlushLoggedErrors
- def test_loop_exception(self):
- # track when poll() gets called
- loops = []
- def poll():
- loops.append(self.clock.seconds())
- raise RuntimeError("oh noes")
- self.changesource.poll = poll
-
- self.changesource.pollInterval = 5
- self.startChangeSource()
-
- d = defer.Deferred()
- d.addCallback(self.runClockFor, 12)
- def check(_):
- # note that it keeps looping after error
- self.assertEqual(loops, [5.0, 10.0])
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 2)
- d.addCallback(check)
- reactor.callWhenRunning(d.callback, None)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py
deleted file mode 100644
index 03338876..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py
+++ /dev/null
@@ -1,283 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from copy import deepcopy
-import re
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.web import client
-from buildbot.test.util import changesource
-from buildbot.util import epoch2datetime
-from buildbot.changes.bonsaipoller import FileNode, CiNode, BonsaiResult, \
- BonsaiParser, BonsaiPoller, InvalidResultError, EmptyResult
-
-log1 = "Add Bug 338541a"
-who1 = "sar@gmail.com"
-date1 = 1161908700
-log2 = "bug 357427 add static ctor/dtor methods"
-who2 = "aarrg@ooacm.org"
-date2 = 1161910620
-log3 = "Testing log #3 lbah blah"
-who3 = "huoents@hueont.net"
-date3 = 1089822728
-rev1 = "1.8"
-file1 = "mozilla/testing/mochitest/tests/index.html"
-rev2 = "1.1"
-file2 = "mozilla/testing/mochitest/tests/test_bug338541.xhtml"
-rev3 = "1.1812"
-file3 = "mozilla/xpcom/threads/nsAutoLock.cpp"
-rev4 = "1.3"
-file4 = "mozilla/xpcom/threads/nsAutoLock.h"
-rev5 = "2.4"
-file5 = "mozilla/xpcom/threads/test.cpp"
-
-nodes = []
-files = []
-files.append(FileNode(rev1,file1))
-nodes.append(CiNode(log1, who1, date1, files))
-
-files = []
-files.append(FileNode(rev2, file2))
-files.append(FileNode(rev3, file3))
-nodes.append(CiNode(log2, who2, date2, files))
-
-nodes.append(CiNode(log3, who3, date3, []))
-
-goodParsedResult = BonsaiResult(nodes)
-
-goodUnparsedResult = """\
-<?xml version="1.0"?>
-<queryResults>
-<ci who="%s" date="%d">
- <log>%s</log>
- <files>
- <f rev="%s">%s</f>
- </files>
-</ci>
-<ci who="%s" date="%d">
- <log>%s</log>
- <files>
- <f rev="%s">%s</f>
- <f rev="%s">%s</f>
- </files>
-</ci>
-<ci who="%s" date="%d">
- <log>%s</log>
- <files>
- </files>
-</ci>
-</queryResults>
-""" % (who1, date1, log1, rev1, file1,
- who2, date2, log2, rev2, file2, rev3, file3,
- who3, date3, log3)
-
-badUnparsedResult = deepcopy(goodUnparsedResult)
-badUnparsedResult = badUnparsedResult.replace("</queryResults>", "")
-
-invalidDateResult = deepcopy(goodUnparsedResult)
-invalidDateResult = invalidDateResult.replace(str(date1), "foobar")
-
-missingFilenameResult = deepcopy(goodUnparsedResult)
-missingFilenameResult = missingFilenameResult.replace(file2, "")
-
-duplicateLogResult = deepcopy(goodUnparsedResult)
-duplicateLogResult = re.sub("<log>"+log1+"</log>",
- "<log>blah</log><log>blah</log>",
- duplicateLogResult)
-
-duplicateFilesResult = deepcopy(goodUnparsedResult)
-duplicateFilesResult = re.sub("<files>\s*</files>",
- "<files></files><files></files>",
- duplicateFilesResult)
-
-missingCiResult = deepcopy(goodUnparsedResult)
-r = re.compile("<ci.*</ci>", re.DOTALL | re.MULTILINE)
-missingCiResult = re.sub(r, "", missingCiResult)
-
-badResultMsgs = { 'badUnparsedResult':
- "BonsaiParser did not raise an exception when given a bad query",
- 'invalidDateResult':
- "BonsaiParser did not raise an exception when given an invalid date",
- 'missingRevisionResult':
- "BonsaiParser did not raise an exception when a revision was missing",
- 'missingFilenameResult':
- "BonsaiParser did not raise an exception when a filename was missing",
- 'duplicateLogResult':
- "BonsaiParser did not raise an exception when there was two <log> tags",
- 'duplicateFilesResult':
- "BonsaiParser did not raise an exception when there was two <files> tags",
- 'missingCiResult':
- "BonsaiParser did not raise an exception when there was no <ci> tags"
-}
-
-noCheckinMsgResult = """\
-<?xml version="1.0"?>
-<queryResults>
-<ci who="johndoe@domain.tld" date="12345678">
- <log></log>
- <files>
- <f rev="1.1">first/file.ext</f>
- </files>
-</ci>
-<ci who="johndoe@domain.tld" date="12345678">
- <log></log>
- <files>
- <f rev="1.2">second/file.ext</f>
- </files>
-</ci>
-<ci who="johndoe@domain.tld" date="12345678">
- <log></log>
- <files>
- <f rev="1.3">third/file.ext</f>
- </files>
-</ci>
-</queryResults>
-"""
-
-noCheckinMsgRef = [dict(filename="first/file.ext",
- revision="1.1"),
- dict(filename="second/file.ext",
- revision="1.2"),
- dict(filename="third/file.ext",
- revision="1.3")]
-
-class TestBonsaiParser(unittest.TestCase):
- def testFullyFormedResult(self):
- br = BonsaiParser(goodUnparsedResult)
- result = br.getData()
- # make sure the result is a BonsaiResult
- self.failUnless(isinstance(result, BonsaiResult))
- # test for successful parsing
- self.failUnlessEqual(goodParsedResult, result,
- "BonsaiParser did not return the expected BonsaiResult")
-
- def testBadUnparsedResult(self):
- try:
- BonsaiParser(badUnparsedResult)
- self.fail(badResultMsgs["badUnparsedResult"])
- except InvalidResultError:
- pass
-
- def testInvalidDateResult(self):
- try:
- BonsaiParser(invalidDateResult)
- self.fail(badResultMsgs["invalidDateResult"])
- except InvalidResultError:
- pass
-
- def testMissingFilenameResult(self):
- try:
- BonsaiParser(missingFilenameResult)
- self.fail(badResultMsgs["missingFilenameResult"])
- except InvalidResultError:
- pass
-
- def testDuplicateLogResult(self):
- try:
- BonsaiParser(duplicateLogResult)
- self.fail(badResultMsgs["duplicateLogResult"])
- except InvalidResultError:
- pass
-
- def testDuplicateFilesResult(self):
- try:
- BonsaiParser(duplicateFilesResult)
- self.fail(badResultMsgs["duplicateFilesResult"])
- except InvalidResultError:
- pass
-
- def testMissingCiResult(self):
- try:
- BonsaiParser(missingCiResult)
- self.fail(badResultMsgs["missingCiResult"])
- except EmptyResult:
- pass
-
- def testMergeEmptyLogMsg(self):
- """Ensure that BonsaiPoller works around the bonsai xml output
- issue when the check-in comment is empty"""
- bp = BonsaiParser(noCheckinMsgResult)
- result = bp.getData()
- self.failUnlessEqual(len(result.nodes), 1)
- self.failUnlessEqual(result.nodes[0].who, "johndoe@domain.tld")
- self.failUnlessEqual(result.nodes[0].date, 12345678)
- self.failUnlessEqual(result.nodes[0].log, "")
- for file, ref in zip(result.nodes[0].files, noCheckinMsgRef):
- self.failUnlessEqual(file.filename, ref['filename'])
- self.failUnlessEqual(file.revision, ref['revision'])
-
-class TestBonsaiPoller(changesource.ChangeSourceMixin, unittest.TestCase):
- def setUp(self):
- d = self.setUpChangeSource()
- def create_poller(_):
- self.attachChangeSource(BonsaiPoller('http://bonsai.mozilla.org',
- 'all', 'seamonkey'))
- d.addCallback(create_poller)
- return d
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def fakeGetPage(self, result):
- """Install a fake getPage that puts the requested URL in C{self.getPage_got_url}
- and return C{result}"""
- self.getPage_got_url = None
- def fake(url, timeout=None):
- self.getPage_got_url = url
- return defer.succeed(result)
- self.patch(client, "getPage", fake)
-
- # tests
-
- def test_describe(self):
- assert re.search(r'bonsai\.mozilla\.org', self.changesource.describe())
-
- def test_poll_bad(self):
- # Make sure a change is not submitted if the BonsaiParser fails, and
- # that the poll operation catches the exception correctly
- self.fakeGetPage(badUnparsedResult)
- d = self.changesource.poll()
- def check(_):
- self.assertEqual(len(self.changes_added), 0)
- d.addCallback(check)
- return d
-
- def test_poll_good(self):
- self.fakeGetPage(goodUnparsedResult)
- d = self.changesource.poll()
- def check(_):
- self.assertEqual(len(self.changes_added), 3)
- self.assertEqual(self.changes_added[0]['author'], who1)
- self.assertEqual(self.changes_added[0]['when_timestamp'],
- epoch2datetime(date1))
- self.assertEqual(self.changes_added[0]['comments'], log1)
- self.assertEqual(self.changes_added[0]['branch'], 'seamonkey')
- self.assertEqual(self.changes_added[0]['files'],
- [ '%s (revision %s)' % (file1, rev1) ])
- self.assertEqual(self.changes_added[1]['author'], who2)
- self.assertEqual(self.changes_added[1]['when_timestamp'],
- epoch2datetime(date2))
- self.assertEqual(self.changes_added[1]['comments'], log2)
- self.assertEqual(self.changes_added[1]['files'],
- [ '%s (revision %s)' % (file2, rev2),
- '%s (revision %s)' % (file3, rev3) ])
- self.assertEqual(self.changes_added[2]['author'], who3)
- self.assertEqual(self.changes_added[2]['comments'], log3)
- self.assertEqual(self.changes_added[2]['when_timestamp'],
- epoch2datetime(date3))
- self.assertEqual(self.changes_added[2]['files'], [])
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py
deleted file mode 100644
index 6dcee925..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import textwrap
-import re
-from twisted.trial import unittest
-from buildbot.test.fake import fakedb
-from buildbot.changes import changes
-
-class Change(unittest.TestCase):
-
- change23_rows = [
- fakedb.Change(changeid=23, author="dustin", comments="fix whitespace",
- is_dir=0, branch="warnerdb", revision="deadbeef",
- when_timestamp=266738404, revlink='http://warner/0e92a098b',
- category='devel', repository='git://warner', codebase='mainapp',
- project='Buildbot'),
-
- fakedb.ChangeFile(changeid=23, filename='master/README.txt'),
- fakedb.ChangeFile(changeid=23, filename='slave/README.txt'),
-
- fakedb.ChangeProperty(changeid=23, property_name='notest',
- property_value='["no","Change"]'),
-
- fakedb.ChangeUser(changeid=23, uid=27),
- ]
-
- def setUp(self):
- self.change23 = changes.Change(**dict( # using **dict(..) forces kwargs
- category='devel',
- isdir=0,
- repository=u'git://warner',
- codebase=u'mainapp',
- who=u'dustin',
- when=266738404,
- comments=u'fix whitespace',
- project=u'Buildbot',
- branch=u'warnerdb',
- revlink=u'http://warner/0e92a098b',
- properties={'notest':"no"},
- files=[u'master/README.txt', u'slave/README.txt'],
- revision=u'deadbeef'))
- self.change23.number = 23
-
- def test_str(self):
- string = str(self.change23)
- self.assertTrue(re.match(r"Change\(.*\)", string), string)
-
- def test_asText(self):
- text = self.change23.asText()
- self.assertTrue(re.match(textwrap.dedent(u'''\
- Files:
- master/README.txt
- slave/README.txt
- On: git://warner
- For: Buildbot
- At: .*
- Changed By: dustin
- Comments: fix whitespaceProperties:
- notest: no
-
- '''), text), text)
-
- def test_asDict(self):
- dict = self.change23.asDict()
- self.assertIn('1978', dict['at']) # timezone-sensitive
- del dict['at']
- self.assertEqual(dict, {
- 'branch': u'warnerdb',
- 'category': u'devel',
- 'codebase': u'mainapp',
- 'comments': u'fix whitespace',
- 'files': [{'name': u'master/README.txt'},
- {'name': u'slave/README.txt'}],
- 'number': 23,
- 'project': u'Buildbot',
- 'properties': [('notest', 'no', 'Change')],
- 'repository': u'git://warner',
- 'rev': u'deadbeef',
- 'revision': u'deadbeef',
- 'revlink': u'http://warner/0e92a098b',
- 'when': 266738404,
- 'who': u'dustin'})
-
- def test_getShortAuthor(self):
- self.assertEqual(self.change23.getShortAuthor(), 'dustin')
-
- def test_getTime(self):
- # careful, or timezones will hurt here
- self.assertIn('Jun 1978', self.change23.getTime())
-
- def test_getTimes(self):
- self.assertEqual(self.change23.getTimes(), (266738404, None))
-
- def test_getText(self):
- self.change23.who = 'nasty < nasty' # test the html escaping (ugh!)
- self.assertEqual(self.change23.getText(), ['nasty &lt; nasty'])
-
- def test_getLogs(self):
- self.assertEqual(self.change23.getLogs(), {})
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py
deleted file mode 100644
index 35c2d316..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-
-from twisted.trial import unittest
-
-from buildbot.changes import filter
-from buildbot.test.fake.state import State
-
-class Change(State):
- project = ''
- repository = ''
- branch = ''
- category = ''
- codebase = ''
-
-class ChangeFilter(unittest.TestCase):
-
- def setUp(self):
- self.results = [] # (got, expected, msg)
- self.filt = None
-
- def tearDown(self):
- if self.results:
- raise RuntimeError("test forgot to call check()")
-
- def setfilter(self, **kwargs):
- self.filt = filter.ChangeFilter(**kwargs)
-
- def yes(self, change, msg):
- self.results.append((self.filt.filter_change(change), True, msg))
-
- def no(self, change, msg):
- self.results.append((self.filt.filter_change(change), False, msg))
-
- def check(self):
- errs = []
- for r in self.results:
- if (r[0] or r[1]) and not (r[0] and r[1]):
- errs.append(r[2])
- self.results = []
- if errs:
- self.fail("; ".join(errs))
-
- def test_filter_change_filter_fn(self):
- self.setfilter(filter_fn = lambda ch : ch.x > 3)
- self.no(Change(x=2), "filter_fn returns False")
- self.yes(Change(x=4), "filter_fn returns True")
- self.check()
-
- def test_filter_change_filt_str(self):
- self.setfilter(project = "myproj")
- self.no(Change(project="yourproj"), "non-matching PROJECT returns False")
- self.yes(Change(project="myproj"), "matching PROJECT returns True")
- self.check()
-
- def test_filter_change_filt_list(self):
- self.setfilter(repository = ["vc://a", "vc://b"])
- self.yes(Change(repository="vc://a"), "matching REPOSITORY vc://a returns True")
- self.yes(Change(repository="vc://b"), "matching REPOSITORY vc://b returns True")
- self.no(Change(repository="vc://c"), "non-matching REPOSITORY returns False")
- self.no(Change(repository=None), "None for REPOSITORY returns False")
- self.check()
-
- def test_filter_change_filt_list_None(self):
- self.setfilter(branch = ["mybr", None])
- self.yes(Change(branch="mybr"), "matching BRANCH mybr returns True")
- self.yes(Change(branch=None), "matching BRANCH None returns True")
- self.no(Change(branch="misc"), "non-matching BRANCH returns False")
- self.check()
-
- def test_filter_change_filt_re(self):
- self.setfilter(category_re = "^a.*")
- self.yes(Change(category="albert"), "matching CATEGORY returns True")
- self.no(Change(category="boris"), "non-matching CATEGORY returns False")
- self.check()
-
- def test_filter_change_branch_re(self): # regression - see #927
- self.setfilter(branch_re = "^t.*")
- self.yes(Change(branch="trunk"), "matching BRANCH returns True")
- self.no(Change(branch="development"), "non-matching BRANCH returns False")
- self.no(Change(branch=None), "branch=None returns False")
- self.check()
-
- def test_filter_change_filt_re_compiled(self):
- self.setfilter(category_re = re.compile("^b.*", re.I))
- self.no(Change(category="albert"), "non-matching CATEGORY returns False")
- self.yes(Change(category="boris"), "matching CATEGORY returns True")
- self.yes(Change(category="Bruce"), "matching CATEGORY returns True, using re.I")
- self.check()
-
- def test_filter_change_combination(self):
- self.setfilter(project='p', repository='r', branch='b', category='c',
- codebase='cb')
- self.no(Change(project='x', repository='x', branch='x', category='x'),
- "none match -> False")
- self.no(Change(project='p', repository='r', branch='b', category='x'),
- "three match -> False")
- self.no(Change(project='p', repository='r', branch='b', category='c',
- codebase='x'), "four match -> False")
- self.yes(Change(project='p', repository='r', branch='b', category='c',
- codebase='cb'), "all match -> True")
- self.check()
-
- def test_filter_change_combination_filter_fn(self):
- self.setfilter(project='p', repository='r', branch='b', category='c',
- filter_fn = lambda c : c.ff)
- self.no(Change(project='x', repository='x', branch='x', category='x', ff=False),
- "none match and fn returns False -> False")
- self.no(Change(project='p', repository='r', branch='b', category='c', ff=False),
- "all match and fn returns False -> False")
- self.no(Change(project='x', repository='x', branch='x', category='x', ff=True),
- "none match and fn returns True -> False")
- self.yes(Change(project='p', repository='r', branch='b', category='c', ff=True),
- "all match and fn returns True -> False")
- self.check()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py
deleted file mode 100644
index bcd8fe32..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc[''], 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.util import json
-from buildbot.test.util import changesource
-from buildbot.changes import gerritchangesource
-
-class TestGerritChangeSource(changesource.ChangeSourceMixin,
- unittest.TestCase):
- def setUp(self):
- return self.setUpChangeSource()
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def newChangeSource(self, host, user):
- s = gerritchangesource.GerritChangeSource(host, user)
- self.attachChangeSource(s)
- return s
-
- # tests
-
- def test_describe(self):
- s = self.newChangeSource('somehost', 'someuser')
- self.assertSubstring("GerritChangeSource", s.describe())
-
- # TODO: test the backoff algorithm
-
- # this variable is reused in test_steps_source_repo
- # to ensure correct integration between change source and repo step
- expected_change = {'category': u'patchset-created',
- 'files': ['unknown'],
- 'repository': u'ssh://someuser@somehost:29418/pr',
- 'author': u'Dustin <dustin@mozilla.com>',
- 'comments': u'fix 1234',
- 'project': u'pr',
- 'branch': u'br/4321',
- 'revlink': u'http://buildbot.net',
- 'properties': {u'event.change.owner.email': u'dustin@mozilla.com',
- u'event.change.subject': u'fix 1234',
- u'event.change.project': u'pr',
- u'event.change.owner.name': u'Dustin',
- u'event.change.number': u'4321',
- u'event.change.url': u'http://buildbot.net',
- u'event.change.branch': u'br',
- u'event.type': u'patchset-created',
- u'event.patchSet.revision': u'abcdef',
- u'event.patchSet.number': u'12'},
- u'revision': u'abcdef'}
-
- def test_lineReceived_patchset_created(self):
- s = self.newChangeSource('somehost', 'someuser')
- d = s.lineReceived(json.dumps(dict(
- type="patchset-created",
- change=dict(
- branch="br",
- project="pr",
- number="4321",
- owner=dict(name="Dustin", email="dustin@mozilla.com"),
- url="http://buildbot.net",
- subject="fix 1234"
- ),
- patchSet=dict(revision="abcdef", number="12")
- )))
-
- def check(_):
- self.failUnlessEqual(len(self.changes_added), 1)
- c = self.changes_added[0]
- for k, v in c.items():
- self.assertEqual(self.expected_change[k], v)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py
deleted file mode 100644
index 3067492a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py
+++ /dev/null
@@ -1,580 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import base, gitpoller
-from buildbot.test.util import changesource, config, gpo
-from buildbot.util import epoch2datetime
-
-# Test that environment variables get propagated to subprocesses (See #2116)
-os.environ['TEST_THAT_ENVIRONMENT_GETS_PASSED_TO_SUBPROCESSES'] = 'TRUE'
-
-class GitOutputParsing(gpo.GetProcessOutputMixin, unittest.TestCase):
- """Test GitPoller methods for parsing git output"""
- def setUp(self):
- self.poller = gitpoller.GitPoller('git@example.com:foo/baz.git')
- self.setUpGetProcessOutput()
-
- dummyRevStr = '12345abcde'
- def _perform_git_output_test(self, methodToTest, args,
- desiredGoodOutput, desiredGoodResult,
- emptyRaisesException=True):
-
- # make this call to self.patch here so that we raise a SkipTest if it
- # is not supported
- self.expectCommands(
- gpo.Expect('git', *args)
- .path('gitpoller-work'),
- )
-
- d = defer.succeed(None)
- def call_empty(_):
- # we should get an Exception with empty output from git
- return methodToTest(self.dummyRevStr)
- d.addCallback(call_empty)
-
- def cb_empty(_):
- if emptyRaisesException:
- self.fail("getProcessOutput should have failed on empty output")
- def eb_empty(f):
- if not emptyRaisesException:
- self.fail("getProcessOutput should NOT have failed on empty output")
- d.addCallbacks(cb_empty, eb_empty)
- d.addCallback(lambda _: self.assertAllCommandsRan())
-
- # and the method shouldn't supress any exceptions
- self.expectCommands(
- gpo.Expect('git', *args)
- .path('gitpoller-work')
- .exit(1),
- )
- def call_exception(_):
- return methodToTest(self.dummyRevStr)
- d.addCallback(call_exception)
-
- def cb_exception(_):
- self.fail("getProcessOutput should have failed on stderr output")
- def eb_exception(f):
- pass
- d.addCallbacks(cb_exception, eb_exception)
- d.addCallback(lambda _: self.assertAllCommandsRan())
-
- # finally we should get what's expected from good output
- self.expectCommands(
- gpo.Expect('git', *args)
- .path('gitpoller-work')
- .stdout(desiredGoodOutput)
- )
- def call_desired(_):
- return methodToTest(self.dummyRevStr)
- d.addCallback(call_desired)
-
- def cb_desired(r):
- self.assertEquals(r, desiredGoodResult)
- d.addCallback(cb_desired)
- d.addCallback(lambda _: self.assertAllCommandsRan())
-
- def test_get_commit_author(self):
- authorStr = 'Sammy Jankis <email@example.com>'
- return self._perform_git_output_test(self.poller._get_commit_author,
- ['log', '--no-walk', '--format=%aN <%aE>', self.dummyRevStr, '--'],
- authorStr, authorStr)
-
- def test_get_commit_comments(self):
- commentStr = 'this is a commit message\n\nthat is multiline'
- return self._perform_git_output_test(self.poller._get_commit_comments,
- ['log', '--no-walk', '--format=%s%n%b', self.dummyRevStr, '--'],
- commentStr, commentStr)
-
- def test_get_commit_files(self):
- filesStr = 'file1\nfile2'
- return self._perform_git_output_test(self.poller._get_commit_files,
- ['log', '--name-only', '--no-walk', '--format=%n', self.dummyRevStr, '--'],
- filesStr, filesStr.split(), emptyRaisesException=False)
-
- def test_get_commit_timestamp(self):
- stampStr = '1273258009'
- return self._perform_git_output_test(self.poller._get_commit_timestamp,
- ['log', '--no-walk', '--format=%ct', self.dummyRevStr, '--'],
- stampStr, float(stampStr))
-
- # _get_changes is tested in TestGitPoller, below
-
-class TestGitPoller(gpo.GetProcessOutputMixin,
- changesource.ChangeSourceMixin,
- unittest.TestCase):
-
- REPOURL = 'git@example.com:foo/baz.git'
- REPOURL_QUOTED = 'git%40example.com%3Afoo%2Fbaz.git'
-
- def setUp(self):
- self.setUpGetProcessOutput()
- d = self.setUpChangeSource()
- def create_poller(_):
- self.poller = gitpoller.GitPoller(self.REPOURL)
- self.poller.master = self.master
- d.addCallback(create_poller)
- return d
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def test_describe(self):
- self.assertSubstring("GitPoller", self.poller.describe())
-
- def test_poll_initial(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5\n'),
- )
-
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5'
- })
- self.master.db.state.assertStateByClass(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={
- 'master': 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5'
- })
- return d
-
- def test_poll_failInit(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work')
- .exit(1),
- )
-
- d = self.assertFailure(self.poller.poll(), EnvironmentError)
-
- d.addCallback(lambda _: self.assertAllCommandsRan)
- return d
-
- def test_poll_failFetch(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .exit(1),
- )
-
- d = self.assertFailure(self.poller.poll(), EnvironmentError)
- d.addCallback(lambda _: self.assertAllCommandsRan)
- return d
-
- def test_poll_failRevParse(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .exit(1),
- )
-
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(len(self.flushLoggedErrors()), 1)
- self.assertEqual(self.poller.lastRev, {})
-
- def test_poll_failLog(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'fa3ae8ed68e664d4db24798611b352e3c6509930..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .exit(1),
- )
-
- # do the poll
- self.poller.lastRev = {
- 'master': 'fa3ae8ed68e664d4db24798611b352e3c6509930'
- }
- d = self.poller.poll()
-
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(len(self.flushLoggedErrors()), 1)
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
-
- def test_poll_nothingNew(self):
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- self.patch(os, 'environ', {'ENVVAR': 'TRUE'})
- self.addGetProcessOutputExpectEnv({'ENVVAR': 'TRUE'})
-
-
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('no interesting output'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout(''),
- )
-
- self.poller.lastRev = {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- }
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.master.db.state.assertStateByClass(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- return d
-
- def test_poll_multipleBranches_initial(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED,
- '+release:refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('9118f4ab71963d23d02d4bdc54876ac8bf05acf2'),
- )
-
- # do the poll
- self.poller.branches = ['master', 'release']
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241',
- 'release': '9118f4ab71963d23d02d4bdc54876ac8bf05acf2'
- })
-
- return d
-
-
- def test_poll_multipleBranches(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED,
- '+release:refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'fa3ae8ed68e664d4db24798611b352e3c6509930..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout('\n'.join([
- '64a5dc2a4bd4f558b5dd193d47c83c7d7abc9a1a',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241'])),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('9118f4ab71963d23d02d4bdc54876ac8bf05acf2'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5..9118f4ab71963d23d02d4bdc54876ac8bf05acf2',
- '--')
- .path('gitpoller-work')
- .stdout( '\n'.join([
- '9118f4ab71963d23d02d4bdc54876ac8bf05acf2'
- ])),
- )
-
- # and patch out the _get_commit_foo methods which were already tested
- # above
- def timestamp(rev):
- return defer.succeed(1273258009.0)
- self.patch(self.poller, '_get_commit_timestamp', timestamp)
- def author(rev):
- return defer.succeed('by:' + rev[:8])
- self.patch(self.poller, '_get_commit_author', author)
- def files(rev):
- return defer.succeed(['/etc/' + rev[:3]])
- self.patch(self.poller, '_get_commit_files', files)
- def comments(rev):
- return defer.succeed('hello!')
- self.patch(self.poller, '_get_commit_comments', comments)
-
- # do the poll
- self.poller.branches = ['master', 'release']
- self.poller.lastRev = {
- 'master': 'fa3ae8ed68e664d4db24798611b352e3c6509930',
- 'release': 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5'
- }
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241',
- 'release': '9118f4ab71963d23d02d4bdc54876ac8bf05acf2'
- })
-
- self.assertEqual(len(self.changes_added), 3)
-
- self.assertEqual(self.changes_added[0]['author'], 'by:4423cdbc')
- self.assertEqual(self.changes_added[0]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[0]['comments'], 'hello!')
- self.assertEqual(self.changes_added[0]['branch'], 'master')
- self.assertEqual(self.changes_added[0]['files'], [ '/etc/442' ])
- self.assertEqual(self.changes_added[0]['src'], 'git')
-
- self.assertEqual(self.changes_added[1]['author'], 'by:64a5dc2a')
- self.assertEqual(self.changes_added[1]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[1]['comments'], 'hello!')
- self.assertEqual(self.changes_added[1]['files'], [ '/etc/64a' ])
- self.assertEqual(self.changes_added[1]['src'], 'git')
-
- self.assertEqual(self.changes_added[2]['author'], 'by:9118f4ab')
- self.assertEqual(self.changes_added[2]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[2]['comments'], 'hello!')
- self.assertEqual(self.changes_added[2]['files'], [ '/etc/911' ])
- self.assertEqual(self.changes_added[2]['src'], 'git')
-
- return d
-
-
- def test_poll_noChanges(self):
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- self.patch(os, 'environ', {'ENVVAR': 'TRUE'})
- self.addGetProcessOutputExpectEnv({'ENVVAR': 'TRUE'})
-
-
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('no interesting output'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout(''),
- )
-
- self.poller.lastRev = {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- }
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- return d
-
- def test_poll_old(self):
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- self.patch(os, 'environ', {'ENVVAR': 'TRUE'})
- self.addGetProcessOutputExpectEnv({'ENVVAR': 'TRUE'})
-
- # patch out getProcessOutput and getProcessOutputAndValue for the
- # benefit of the _get_changes method
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('no interesting output'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'fa3ae8ed68e664d4db24798611b352e3c6509930..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout('\n'.join([
- '64a5dc2a4bd4f558b5dd193d47c83c7d7abc9a1a',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- ])),
- )
-
- # and patch out the _get_commit_foo methods which were already tested
- # above
- def timestamp(rev):
- return defer.succeed(1273258009.0)
- self.patch(self.poller, '_get_commit_timestamp', timestamp)
- def author(rev):
- return defer.succeed('by:' + rev[:8])
- self.patch(self.poller, '_get_commit_author', author)
- def files(rev):
- return defer.succeed(['/etc/' + rev[:3]])
- self.patch(self.poller, '_get_commit_files', files)
- def comments(rev):
- return defer.succeed('hello!')
- self.patch(self.poller, '_get_commit_comments', comments)
-
- # do the poll
- self.poller.lastRev = {
- 'master': 'fa3ae8ed68e664d4db24798611b352e3c6509930'
- }
- d = self.poller.poll()
-
- # check the results
- def check_changes(_):
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- self.assertEqual(len(self.changes_added), 2)
- self.assertEqual(self.changes_added[0]['author'], 'by:4423cdbc')
- self.assertEqual(self.changes_added[0]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[0]['comments'], 'hello!')
- self.assertEqual(self.changes_added[0]['branch'], 'master')
- self.assertEqual(self.changes_added[0]['files'], [ '/etc/442' ])
- self.assertEqual(self.changes_added[0]['src'], 'git')
- self.assertEqual(self.changes_added[1]['author'], 'by:64a5dc2a')
- self.assertEqual(self.changes_added[1]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[1]['comments'], 'hello!')
- self.assertEqual(self.changes_added[1]['files'], [ '/etc/64a' ])
- self.assertEqual(self.changes_added[1]['src'], 'git')
- self.assertAllCommandsRan()
-
- self.master.db.state.assertStateByClass(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- d.addCallback(check_changes)
-
- return d
-
- # We mock out base.PollingChangeSource.startService, since it calls
- # reactor.callWhenRunning, which leaves a dirty reactor if a synchronous
- # deferred is returned from a test method.
- def test_startService(self):
- startService = mock.Mock()
- self.patch(base.PollingChangeSource, "startService", startService)
- d = self.poller.startService()
- def check(_):
- self.assertEqual(self.poller.workdir, os.path.join('basedir', 'gitpoller-work'))
- self.assertEqual(self.poller.lastRev, {})
- startService.assert_called_once_with(self.poller)
- d.addCallback(check)
- return d
-
- def test_startService_loadLastRev(self):
- startService = mock.Mock()
- self.patch(base.PollingChangeSource, "startService", startService)
- self.master.db.state.fakeState(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={"master": "fa3ae8ed68e664d4db24798611b352e3c6509930"},
- )
-
- d = self.poller.startService()
- def check(_):
- self.assertEqual(self.poller.lastRev, {
- "master": "fa3ae8ed68e664d4db24798611b352e3c6509930"
- })
- startService.assert_called_once_with(self.poller)
- d.addCallback(check)
- return d
-
-
-class TestGitPollerConstructor(unittest.TestCase, config.ConfigErrorsMixin):
- def test_deprecatedFetchRefspec(self):
- self.assertRaisesConfigError("fetch_refspec is no longer supported",
- lambda: gitpoller.GitPoller("/tmp/git.git",
- fetch_refspec='not-supported'))
-
- def test_oldPollInterval(self):
- poller = gitpoller.GitPoller("/tmp/git.git", pollinterval=10)
- self.assertEqual(poller.pollInterval, 10)
-
- def test_branches_default(self):
- poller = gitpoller.GitPoller("/tmp/git.git")
- self.assertEqual(poller.branches, ["master"])
-
- def test_branches_oldBranch(self):
- poller = gitpoller.GitPoller("/tmp/git.git", branch='magic')
- self.assertEqual(poller.branches, ["magic"])
-
- def test_branches(self):
- poller = gitpoller.GitPoller("/tmp/git.git",
- branches=['magic', 'marker'])
- self.assertEqual(poller.branches, ["magic", "marker"])
-
- def test_branches_andBranch(self):
- self.assertRaisesConfigError("can't specify both branch and branches",
- lambda: gitpoller.GitPoller("/tmp/git.git",
- branch='bad', branches=['listy']))
-
- def test_gitbin_default(self):
- poller = gitpoller.GitPoller("/tmp/git.git")
- self.assertEqual(poller.gitbin, "git")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py
deleted file mode 100644
index c6bf128b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import hgpoller
-from buildbot.test.util import changesource, gpo
-from buildbot.test.fake.fakedb import FakeDBConnector
-from buildbot.util import epoch2datetime
-
-ENVIRON_2116_KEY = 'TEST_THAT_ENVIRONMENT_GETS_PASSED_TO_SUBPROCESSES'
-
-class TestHgPoller(gpo.GetProcessOutputMixin,
- changesource.ChangeSourceMixin,
- unittest.TestCase):
-
- def setUp(self):
- # To test that environment variables get propagated to subprocesses
- # (See #2116)
- os.environ[ENVIRON_2116_KEY] = 'TRUE'
- self.setUpGetProcessOutput()
- d = self.setUpChangeSource()
- self.remote_repo = 'ssh://example.com/foo/baz'
- self.repo_ready = True
- def _isRepositoryReady():
- return self.repo_ready
- def create_poller(_):
- self.poller = hgpoller.HgPoller(self.remote_repo,
- workdir='/some/dir')
- self.poller.master = self.master
- self.poller._isRepositoryReady = _isRepositoryReady
- def create_db(_):
- db = self.master.db = FakeDBConnector(self)
- return db.setup()
- d.addCallback(create_poller)
- d.addCallback(create_db)
- return d
-
- def tearDown(self):
- del os.environ[ENVIRON_2116_KEY]
- return self.tearDownChangeSource()
-
- def gpoFullcommandPattern(self, commandName, *expected_args):
- """Match if the command is commandName and arg list start as expected.
-
- This allows to test a bit more if expected GPO are issued, be it
- by obscure failures due to the result not being given.
- """
- def matchesSubcommand(bin, given_args, **kwargs):
- return bin == commandName and tuple(
- given_args[:len(expected_args)]) == expected_args
- return matchesSubcommand
-
- def test_describe(self):
- self.assertSubstring("HgPoller", self.poller.describe())
-
- def test_hgbin_default(self):
- self.assertEqual(self.poller.hgbin, "hg")
-
- def test_poll_initial(self):
- self.repo_ready = False
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- expected_env = {ENVIRON_2116_KEY: 'TRUE'}
- self.addGetProcessOutputExpectEnv(expected_env)
- self.expectCommands(
- gpo.Expect('hg', 'init', '/some/dir'),
- gpo.Expect('hg', 'pull', '-b', 'default',
- 'ssh://example.com/foo/baz')
- .path('/some/dir'),
- gpo.Expect('hg', 'heads', 'default', '--template={rev}' + os.linesep)
- .path('/some/dir').stdout("73591"),
- gpo.Expect('hg', 'log', '-b', 'default', '-r', '73591:73591', # only fetches that head
- '--template={rev}:{node}\\n')
- .path('/some/dir').stdout(os.linesep.join(['73591:4423cdb'])),
- gpo.Expect('hg', 'log', '-r', '4423cdb',
- '--template={date|hgdate}' + os.linesep + '{author}' + os.linesep + '{files}' + os.linesep + '{desc|strip}')
- .path('/some/dir').stdout(os.linesep.join([
- '1273258100.0 -7200',
- 'Bob Test <bobtest@example.org>',
- 'file1 dir/file2',
- 'This is rev 73591',
- ''])),
- )
-
- # do the poll
- d = self.poller.poll()
-
- # check the results
- def check_changes(_):
- self.assertEqual(len(self.changes_added), 1)
-
- change = self.changes_added[0]
- self.assertEqual(change['revision'], '4423cdb')
- self.assertEqual(change['author'],
- 'Bob Test <bobtest@example.org>')
- self.assertEqual(change['when_timestamp'],
- epoch2datetime(1273258100)),
- self.assertEqual(change['files'], ['file1', 'dir/file2'])
- self.assertEqual(change['src'], 'hg')
- self.assertEqual(change['branch'], 'default')
- self.assertEqual(change['comments'], 'This is rev 73591')
-
- d.addCallback(check_changes)
- d.addCallback(self.check_current_rev(73591))
- return d
-
- def check_current_rev(self, wished):
- def check_on_rev(_):
- d = self.poller._getCurrentRev()
- d.addCallback(lambda oid_rev: self.assertEqual(oid_rev[1], wished))
- return check_on_rev
-
- @defer.inlineCallbacks
- def test_poll_several_heads(self):
- # If there are several heads on the named branch, the poller musn't
- # climb (good enough for now, ideally it should even go to the common
- # ancestor)
- self.expectCommands(
- gpo.Expect('hg', 'pull', '-b', 'default',
- 'ssh://example.com/foo/baz')
- .path('/some/dir'),
- gpo.Expect('hg', 'heads', 'default', '--template={rev}' + os.linesep)
- .path('/some/dir').stdout('5' + os.linesep + '6' + os.linesep),
- )
-
- yield self.poller._setCurrentRev(3)
-
- # do the poll: we must stay at rev 3
- d = self.poller.poll()
- d.addCallback(self.check_current_rev(3))
-
- @defer.inlineCallbacks
- def test_poll_regular(self):
- # normal operation. There's a previous revision, we get a new one.
- self.expectCommands(
- gpo.Expect('hg', 'pull', '-b', 'default',
- 'ssh://example.com/foo/baz')
- .path('/some/dir'),
- gpo.Expect('hg', 'heads', 'default', '--template={rev}' + os.linesep)
- .path('/some/dir').stdout('5' + os.linesep),
- gpo.Expect('hg', 'log', '-b', 'default', '-r', '5:5',
- '--template={rev}:{node}\\n')
- .path('/some/dir').stdout('5:784bd' + os.linesep),
- gpo.Expect('hg', 'log', '-r', '784bd',
- '--template={date|hgdate}' + os.linesep + '{author}' + os.linesep + '{files}' + os.linesep + '{desc|strip}')
- .path('/some/dir').stdout(os.linesep.join([
- '1273258009.0 -7200',
- 'Joe Test <joetest@example.org>',
- 'file1 file2',
- 'Comment for rev 5',
- ''])),
- )
-
- yield self.poller._setCurrentRev(4)
-
- d = self.poller.poll()
- d.addCallback(self.check_current_rev(5))
-
- def check_changes(_):
- self.assertEquals(len(self.changes_added), 1)
- change = self.changes_added[0]
- self.assertEqual(change['revision'], '784bd')
- self.assertEqual(change['comments'], 'Comment for rev 5')
- d.addCallback(check_changes)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py
deleted file mode 100644
index d4c7d210..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-from twisted.trial import unittest
-from buildbot.test.util import changesource, dirs
-from buildbot.changes import mail
-
-class TestMaildirSource(changesource.ChangeSourceMixin, dirs.DirsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.maildir = os.path.abspath("maildir")
-
- d = self.setUpChangeSource()
- d.addCallback(lambda _ : self.setUpDirs(self.maildir))
- return d
-
- def populateMaildir(self):
- "create a fake maildir with a fake new message ('newmsg') in it"
- newdir = os.path.join(self.maildir, "new")
- os.makedirs(newdir)
-
- curdir = os.path.join(self.maildir, "cur")
- os.makedirs(curdir)
-
- fake_message = "Subject: test\n\nthis is a test"
- mailfile = os.path.join(newdir, "newmsg")
- with open(mailfile, "w") as f:
- f.write(fake_message)
-
- def assertMailProcessed(self):
- self.assertFalse(os.path.exists(os.path.join(self.maildir, "new", "newmsg")))
- self.assertTrue(os.path.exists(os.path.join(self.maildir, "cur", "newmsg")))
-
- def tearDown(self):
- d = self.tearDownDirs()
- d.addCallback(lambda _ : self.tearDownChangeSource())
- return d
-
- # tests
-
- def test_describe(self):
- mds = mail.MaildirSource(self.maildir)
- self.assertSubstring(self.maildir, mds.describe())
-
- def test_messageReceived_svn(self):
- self.populateMaildir()
- mds = mail.MaildirSource(self.maildir)
- self.attachChangeSource(mds)
-
- # monkey-patch in a parse method
- def parse(message, prefix):
- assert 'this is a test' in message.get_payload()
- return ('svn', dict(fake_chdict=1))
- mds.parse = parse
-
- d = mds.messageReceived('newmsg')
- def check(_):
- self.assertMailProcessed()
- self.assertEqual(len(self.changes_added), 1)
- self.assertEqual(self.changes_added[0]['fake_chdict'], 1)
- self.assertEqual(self.changes_added[0]['src'], 'svn')
- d.addCallback(check)
- return d
-
- def test_messageReceived_bzr(self):
- self.populateMaildir()
- mds = mail.MaildirSource(self.maildir)
- self.attachChangeSource(mds)
-
- # monkey-patch in a parse method
- def parse(message, prefix):
- assert 'this is a test' in message.get_payload()
- return ('bzr', dict(fake_chdict=1))
- mds.parse = parse
-
- d = mds.messageReceived('newmsg')
- def check(_):
- self.assertMailProcessed()
- self.assertEqual(len(self.changes_added), 1)
- self.assertEqual(self.changes_added[0]['fake_chdict'], 1)
- self.assertEqual(self.changes_added[0]['src'], 'bzr')
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py
deleted file mode 100644
index 44e3c7ef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from email import message_from_string
-from email.Utils import parsedate_tz, mktime_tz
-from buildbot.changes.mail import CVSMaildirSource
-
-#
-# Sample message from CVS version 1.11
-#
-
-cvs1_11_msg = """From: Andy Howell <andy@example.com>
-To: buildbot@example.com
-Subject: cvs module MyModuleName
-Date: Sat, 07 Aug 2010 11:11:49 +0000
-X-Mailer: Python buildbot-cvs-mail $Revision: 1.3 $
-
-Cvsmode: 1.11
-Category: None
-CVSROOT: :ext:cvshost.example.com:/cvsroot
-Files: base/module/src/make GNUmakefile,1.362,1.363
-Project: MyModuleName
-Update of /cvsroot/base/moduel/src/make
-In directory cvshost:/tmp/cvs-serv10922
-
-Modified Files:
- GNUmakefile
-Log Message:
-Commented out some stuff.
-"""
-
-#
-# Sample message from CVS version 1.12
-#
-# Paths are handled differently by the two versions
-#
-
-cvs1_12_msg="""Date: Wed, 11 Aug 2010 04:56:44 +0000
-From: andy@example.com
-To: buildbot@example.com
-Subject: cvs update for project RaiCore
-X-Mailer: Python buildbot-cvs-mail $Revision: 1.3 $
-
-Cvsmode: 1.12
-Category: None
-CVSROOT: :ext:cvshost.example.com:/cvsroot
-Files: file1.cpp 1.77 1.78 file2.cpp 1.75 1.76
-Path: base/module/src
-Project: MyModuleName
-Update of /cvsroot/base/module/src
-In directory example.com:/tmp/cvs-serv26648/InsightMonAgent
-
-Modified Files:
- file1.cpp file2.cpp
-Log Message:
-Changes for changes sake
-"""
-
-class TestCVSMaildirSource(unittest.TestCase):
- def test_CVSMaildirSource_create_change_from_cvs1_11msg(self):
- m = message_from_string(cvs1_11_msg)
- src = CVSMaildirSource('/dev/null')
- try:
- src, chdict = src.parse( m )
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict != None)
- self.assert_(chdict['author'] == 'andy')
- self.assert_(len(chdict['files']) == 1)
- self.assert_(chdict['files'][0] == 'base/module/src/make/GNUmakefile')
- self.assert_(chdict['comments'] == 'Commented out some stuff.\n')
- self.assert_(chdict['isdir'] == False)
- self.assert_(chdict['revision'] == '2010-08-07 11:11:49')
- dateTuple = parsedate_tz('Sat, 07 Aug 2010 11:11:49 +0000')
- self.assert_(chdict['when'] == mktime_tz(dateTuple))
- self.assert_(chdict['branch'] == None)
- self.assert_(chdict['repository'] == ':ext:cvshost.example.com:/cvsroot')
- self.assert_(chdict['project'] == 'MyModuleName')
- self.assert_(len(chdict['properties']) == 0)
- self.assert_(src == 'cvs')
-
- def test_CVSMaildirSource_create_change_from_cvs1_12msg(self):
- m = message_from_string(cvs1_12_msg)
- src = CVSMaildirSource('/dev/null')
- try:
- src, chdict = src.parse( m )
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict != None)
- self.assert_(chdict['author'] == 'andy')
- self.assert_(len(chdict['files']) == 2)
- self.assert_(chdict['files'][0] == 'base/module/src/file1.cpp')
- self.assert_(chdict['files'][1] == 'base/module/src/file2.cpp')
- self.assert_(chdict['comments'] == 'Changes for changes sake\n')
- self.assert_(chdict['isdir'] == False)
- self.assert_(chdict['revision'] == '2010-08-11 04:56:44')
- dateTuple = parsedate_tz('Wed, 11 Aug 2010 04:56:44 +0000')
- self.assert_(chdict['when'] == mktime_tz(dateTuple))
- self.assert_(chdict['branch'] == None)
- self.assert_(chdict['repository'] == ':ext:cvshost.example.com:/cvsroot')
- self.assert_(chdict['project'] == 'MyModuleName')
- self.assert_(len(chdict['properties']) == 0)
- self.assert_(src == 'cvs')
-
- def test_CVSMaildirSource_create_change_from_cvs1_12_with_no_path(self):
- msg = cvs1_12_msg.replace('Path: base/module/src', '')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- assert src.parse( m )[1]
- except ValueError:
- pass
- else:
- self.fail('Expect ValueError.')
-
- def test_CVSMaildirSource_create_change_with_bad_cvsmode(self):
- # Branch is indicated afer 'Tag:' in modified file list
- msg = cvs1_11_msg.replace('Cvsmode: 1.11', 'Cvsmode: 9.99')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- assert src.parse( m )[1]
- except ValueError:
- pass
- else:
- self.fail('Expected ValueError')
-
- def test_CVSMaildirSource_create_change_with_branch(self):
- # Branch is indicated afer 'Tag:' in modified file list
- msg = cvs1_11_msg.replace(' GNUmakefile',
- ' Tag: Test_Branch\n GNUmakefile')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['branch'] == 'Test_Branch')
-
- def test_CVSMaildirSource_create_change_with_category(self):
- msg = cvs1_11_msg.replace('Category: None', 'Category: Test category')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['category'] == 'Test category')
-
- def test_CVSMaildirSource_create_change_with_no_comment(self):
- # Strip off comments
- msg = cvs1_11_msg[:cvs1_11_msg.find('Commented out some stuff')]
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['comments'] == None )
-
- def test_CVSMaildirSource_create_change_with_no_files(self):
- # A message with no files is likely not for us
- msg = cvs1_11_msg.replace('Files: base/module/src/make GNUmakefile,1.362,1.363','')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict == None )
-
- def test_CVSMaildirSource_create_change_with_no_project(self):
- msg = cvs1_11_msg.replace('Project: MyModuleName', '')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['project'] == None )
-
- def test_CVSMaildirSource_create_change_with_no_repository(self):
- msg = cvs1_11_msg.replace('CVSROOT: :ext:cvshost.example.com:/cvsroot', '')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['repository'] == None )
-
- def test_CVSMaildirSource_create_change_with_property(self):
- m = message_from_string(cvs1_11_msg)
- propDict = { 'foo' : 'bar' }
- src = CVSMaildirSource('/dev/null', properties=propDict)
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['properties']['foo'] == 'bar')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py
deleted file mode 100644
index 7eaec2ee..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.application import service
-from buildbot.changes import manager
-
-class FakeChangeSource(service.Service):
- pass
-
-class TestChangeManager(unittest.TestCase):
- def setUp(self):
- self.master = mock.Mock()
- self.cm = manager.ChangeManager(self.master)
- self.new_config = mock.Mock()
-
- def make_sources(self, n):
- for i in range(n):
- src = FakeChangeSource()
- src.setName('ChangeSource %d' % i)
- yield src
-
- def test_reconfigService_add(self):
- src1, src2 = self.make_sources(2)
- src1.setServiceParent(self.cm)
- self.new_config.change_sources = [ src1, src2 ]
-
- d = self.cm.reconfigService(self.new_config)
- @d.addCallback
- def check(_):
- self.assertIdentical(src2.parent, self.cm)
- self.assertIdentical(src2.master, self.master)
- return d
-
- def test_reconfigService_remove(self):
- src1, = self.make_sources(1)
- src1.setServiceParent(self.cm)
- self.new_config.change_sources = [ ]
-
- d = self.cm.reconfigService(self.new_config)
- @d.addCallback
- def check(_):
- self.assertIdentical(src1.parent, None)
- self.assertIdentical(src1.master, None)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py
deleted file mode 100644
index 02e0f67f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-from twisted.trial import unittest
-from buildbot.changes.p4poller import P4Source, get_simple_split, P4PollerError
-from buildbot.test.util import changesource, gpo
-from buildbot.util import epoch2datetime
-
-first_p4changes = \
-"""Change 1 on 2006/04/13 by slamb@testclient 'first rev'
-"""
-
-second_p4changes = \
-"""Change 3 on 2006/04/13 by bob@testclient 'short desc truncated'
-Change 2 on 2006/04/13 by slamb@testclient 'bar'
-"""
-
-third_p4changes = \
-"""Change 5 on 2006/04/13 by mpatel@testclient 'first rev'
-"""
-
-change_4_log = \
-"""Change 4 by mpatel@testclient on 2006/04/13 21:55:39
-
- short desc truncated because this is a long description.
-"""
-
-change_3_log = \
-u"""Change 3 by bob@testclient on 2006/04/13 21:51:39
-
- short desc truncated because this is a long description.
- ASDF-GUI-P3-\u2018Upgrade Icon\u2019 disappears sometimes.
-"""
-
-change_2_log = \
-"""Change 2 by slamb@testclient on 2006/04/13 21:46:23
-
- creation
-"""
-
-p4change = {
- 3: change_3_log +
-"""Affected files ...
-
-... //depot/myproject/branch_b/branch_b_file#1 add
-... //depot/myproject/branch_b/whatbranch#1 branch
-... //depot/myproject/branch_c/whatbranch#1 branch
-""",
- 2: change_2_log +
-"""Affected files ...
-
-... //depot/myproject/trunk/whatbranch#1 add
-... //depot/otherproject/trunk/something#1 add
-""",
- 5: change_4_log +
-"""Affected files ...
-
-... //depot/myproject/branch_b/branch_b_file#1 add
-... //depot/myproject/branch_b#75 edit
-... //depot/myproject/branch_c/branch_c_file#1 add
-""",
-}
-
-
-class TestP4Poller(changesource.ChangeSourceMixin,
- gpo.GetProcessOutputMixin,
- unittest.TestCase):
- def setUp(self):
- self.setUpGetProcessOutput()
- return self.setUpChangeSource()
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def add_p4_describe_result(self, number, result):
- self.expectCommands(
- gpo.Expect('p4', 'describe', '-s', str(number)).stdout(result))
-
- def makeTime(self, timestring):
- datefmt = '%Y/%m/%d %H:%M:%S'
- when = time.mktime(time.strptime(timestring, datefmt))
- return epoch2datetime(when)
-
- # tests
-
- def test_describe(self):
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1)))
- self.assertSubstring("p4source", self.changesource.describe())
-
- def do_test_poll_successful(self, **kwargs):
- encoding = kwargs.get('encoding', 'utf8')
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1),
- **kwargs))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '-m', '1', '//depot/myproject/...').stdout(first_p4changes),
- gpo.Expect('p4', 'changes', '//depot/myproject/...@2,now').stdout(second_p4changes),
- )
- encoded_p4change = p4change.copy()
- encoded_p4change[3] = encoded_p4change[3].encode(encoding)
- self.add_p4_describe_result(2, encoded_p4change[2])
- self.add_p4_describe_result(3, encoded_p4change[3])
-
- # The first time, it just learns the change to start at.
- self.assert_(self.changesource.last_change is None)
- d = self.changesource.poll()
- def check_first_check(_):
- self.assertEquals(self.changes_added, [])
- self.assertEquals(self.changesource.last_change, 1)
- d.addCallback(check_first_check)
-
- # Subsequent times, it returns Change objects for new changes.
- d.addCallback(lambda _ : self.changesource.poll())
- def check_second_check(res):
- self.assertEquals(len(self.changes_added), 3)
- self.assertEquals(self.changesource.last_change, 3)
-
- # They're supposed to go oldest to newest, so this one must be first.
- self.assertEquals(self.changes_added[0],
- dict(author='slamb',
- files=['whatbranch'],
- project='',
- comments=change_2_log,
- revision='2',
- when_timestamp=self.makeTime("2006/04/13 21:46:23"),
- branch='trunk'))
-
- # These two can happen in either order, since they're from the same
- # Perforce change.
- if self.changes_added[1]['branch'] == 'branch_c':
- self.changes_added[1:] = reversed(self.changes_added[1:])
-
- self.assertEquals(self.changes_added[1],
- dict(author='bob',
- files=['branch_b_file',
- 'whatbranch'],
- project='',
- comments=change_3_log, # converted to unicode correctly
- revision='3',
- when_timestamp=self.makeTime("2006/04/13 21:51:39"),
- branch='branch_b'))
- self.assertEquals(self.changes_added[2],
- dict(author='bob',
- files=['whatbranch'],
- project='',
- comments=change_3_log, # converted to unicode correctly
- revision='3',
- when_timestamp=self.makeTime("2006/04/13 21:51:39"),
- branch='branch_c'))
- self.assertAllCommandsRan()
- d.addCallback(check_second_check)
- return d
-
- def test_poll_successful_default_encoding(self):
- return self.do_test_poll_successful()
-
- def test_poll_successful_macroman_encoding(self):
- return self.do_test_poll_successful(encoding='macroman')
-
- def test_poll_failed_changes(self):
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1)))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '-m', '1', '//depot/myproject/...').stdout('Perforce client error:\n...'))
-
- # call _poll, so we can catch the failure
- d = self.changesource._poll()
- return self.assertFailure(d, P4PollerError)
-
- def test_poll_failed_describe(self):
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1)))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '//depot/myproject/...@3,now').stdout(second_p4changes),
- )
- self.add_p4_describe_result(2, p4change[2])
- self.add_p4_describe_result(3, 'Perforce client error:\n...')
-
- self.changesource.last_change = 2 # tell poll() that it's already been called once
-
- # call _poll, so we can catch the failure
- d = self.changesource._poll()
- self.assertFailure(d, P4PollerError)
- @d.addCallback
- def check(_):
- # check that 2 was processed OK
- self.assertEquals(self.changesource.last_change, 2)
- self.assertAllCommandsRan()
- return d
-
- def test_poll_split_file(self):
- """Make sure split file works on branch only changes"""
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=get_simple_split))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '//depot/myproject/...@51,now').stdout(third_p4changes),
- )
- self.add_p4_describe_result(5, p4change[5])
-
- self.changesource.last_change = 50
- d = self.changesource.poll()
- def check(res):
- self.assertEquals(len(self.changes_added), 2)
- self.assertEquals(self.changesource.last_change, 5)
- self.assertAllCommandsRan()
- d.addCallback(check)
- return d
-
-class TestSplit(unittest.TestCase):
- def test_get_simple_split(self):
- self.assertEqual(get_simple_split('foo/bar'), ('foo', 'bar'))
- self.assertEqual(get_simple_split('foo-bar'), (None, None))
- self.assertEqual(get_simple_split('/bar'), ('', 'bar'))
- self.assertEqual(get_simple_split('foo/'), ('foo', ''))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py
deleted file mode 100644
index 6a34b5d6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py
+++ /dev/null
@@ -1,265 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-"""
-Test the PB change source.
-"""
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import pb
-from buildbot.test.util import changesource, pbmanager
-from buildbot.util import epoch2datetime
-
-class TestPBChangeSource(
- changesource.ChangeSourceMixin,
- pbmanager.PBManagerMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpPBChangeSource()
- d = self.setUpChangeSource()
- @d.addCallback
- def setup(_):
- self.master.pbmanager = self.pbmanager
-
- return d
-
- def test_registration_no_slaveport(self):
- return self._test_registration(None,
- user='alice', passwd='sekrit')
-
- def test_registration_global_slaveport(self):
- return self._test_registration(('9999', 'alice', 'sekrit'),
- slavePort='9999', user='alice', passwd='sekrit')
-
- def test_registration_custom_port(self):
- return self._test_registration(('8888', 'alice', 'sekrit'),
- user='alice', passwd='sekrit', port='8888')
-
- def test_registration_no_userpass(self):
- return self._test_registration(('9939', 'change', 'changepw'),
- slavePort='9939')
-
- def test_registration_no_userpass_no_global(self):
- return self._test_registration(None)
-
- @defer.inlineCallbacks
- def _test_registration(self, exp_registration, slavePort=None,
- **constr_kwargs):
- config = mock.Mock()
- config.slavePortnum = slavePort
- self.attachChangeSource(pb.PBChangeSource(**constr_kwargs))
-
- self.startChangeSource()
- yield self.changesource.reconfigService(config)
-
- if exp_registration:
- self.assertRegistered(*exp_registration)
- else:
- self.assertNotRegistered()
-
- yield self.stopChangeSource()
-
- if exp_registration:
- self.assertUnregistered(*exp_registration)
- self.assertEqual(self.changesource.registration, None)
-
- def test_perspective(self):
- self.attachChangeSource(pb.PBChangeSource('alice', 'sekrit', port='8888'))
- persp = self.changesource.getPerspective(mock.Mock(), 'alice')
- self.assertIsInstance(persp, pb.ChangePerspective)
-
- def test_describe(self):
- cs = pb.PBChangeSource()
- self.assertSubstring("PBChangeSource", cs.describe())
-
- def test_describe_prefix(self):
- cs = pb.PBChangeSource(prefix="xyz")
- self.assertSubstring("PBChangeSource", cs.describe())
- self.assertSubstring("xyz", cs.describe())
-
- def test_describe_int(self):
- cs = pb.PBChangeSource(port=9989)
- self.assertSubstring("PBChangeSource", cs.describe())
-
- @defer.inlineCallbacks
- def test_reconfigService_no_change(self):
- config = mock.Mock()
- self.attachChangeSource(pb.PBChangeSource(port='9876'))
-
- self.startChangeSource()
- yield self.changesource.reconfigService(config)
-
- self.assertRegistered('9876', 'change', 'changepw')
-
- yield self.stopChangeSource()
-
- self.assertUnregistered('9876', 'change', 'changepw')
-
- @defer.inlineCallbacks
- def test_reconfigService_default_changed(self):
- config = mock.Mock()
- config.slavePortnum = '9876'
- self.attachChangeSource(pb.PBChangeSource())
-
- self.startChangeSource()
- yield self.changesource.reconfigService(config)
-
- self.assertRegistered('9876', 'change', 'changepw')
-
- config.slavePortnum = '1234'
-
- yield self.changesource.reconfigService(config)
-
- self.assertUnregistered('9876', 'change', 'changepw')
- self.assertRegistered('1234', 'change', 'changepw')
-
- yield self.stopChangeSource()
-
- self.assertUnregistered('1234', 'change', 'changepw')
-
-
-class TestChangePerspective(unittest.TestCase):
- def setUp(self):
- self.added_changes = []
- self.master = mock.Mock()
-
- def addChange(**chdict):
- self.added_changes.append(chdict)
- return defer.succeed(mock.Mock())
- self.master.addChange = addChange
-
- def test_addChange_noprefix(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(who="bar", files=['a']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author="bar", files=['a']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_codebase(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(who="bar", files=[], codebase='cb'))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author="bar", files=[], codebase='cb') ])
- d.addCallback(check)
- return d
-
- def test_addChange_prefix(self):
- cp = pb.ChangePerspective(self.master, 'xx/')
- d = cp.perspective_addChange(
- dict(who="bar", files=['xx/a', 'yy/b']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author="bar", files=['a']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_sanitize_None(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(
- dict(project=None, revlink=None, repository=None)
- )
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(project="", revlink="", repository="",
- files=[]) ])
- d.addCallback(check)
- return d
-
- def test_addChange_when_None(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(
- dict(when=None)
- )
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(when_timestamp=None, files=[]) ])
- d.addCallback(check)
- return d
-
- def test_addChange_files_tuple(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(
- dict(files=('a', 'b'))
- )
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(files=['a', 'b']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_unicode(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(author=u"\N{SNOWMAN}",
- comments=u"\N{SNOWMAN}",
- files=[u'\N{VERY MUCH GREATER-THAN}']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author=u"\N{SNOWMAN}",
- comments=u"\N{SNOWMAN}",
- files=[u'\N{VERY MUCH GREATER-THAN}']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_unicode_as_bytestring(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(author=u"\N{SNOWMAN}".encode('utf8'),
- comments=u"\N{SNOWMAN}".encode('utf8'),
- files=[u'\N{VERY MUCH GREATER-THAN}'.encode('utf8')]))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author=u"\N{SNOWMAN}",
- comments=u"\N{SNOWMAN}",
- files=[u'\N{VERY MUCH GREATER-THAN}']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_non_utf8_bytestring(self):
- cp = pb.ChangePerspective(self.master, None)
- bogus_utf8 = '\xff\xff\xff\xff'
- replacement = bogus_utf8.decode('utf8', 'replace')
- d = cp.perspective_addChange(dict(author=bogus_utf8, files=['a']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author=replacement, files=['a']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_old_param_names(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(isdir=1, who='me', when=1234,
- files=[]))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(is_dir=1, author='me', files=[],
- when_timestamp=epoch2datetime(1234)) ])
- d.addCallback(check)
- return d
-
- def test_createUserObject_git_src(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(who="c <h@c>", src='git'))
- def check_change(_):
- self.assertEqual(self.added_changes, [ dict(author="c <h@c>",
- files=[],
- src='git') ])
- d.addCallback(check_change)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py
deleted file mode 100644
index be288d8d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py
+++ /dev/null
@@ -1,627 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import xml.dom.minidom
-from twisted.internet import defer
-from twisted.trial import unittest
-from buildbot.test.util import changesource, gpo, compat
-from buildbot.changes import svnpoller
-
-# this is the output of "svn info --xml
-# svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
-prefix_output = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="trunk"
- revision="18354">
-<url>svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk</url>
-<repository>
-<root>svn+ssh://svn.twistedmatrix.com/svn/Twisted</root>
-<uuid>bbbe8e31-12d6-0310-92fd-ac37d47ddeeb</uuid>
-</repository>
-<commit
- revision="18352">
-<author>jml</author>
-<date>2006-10-01T02:37:34.063255Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-# and this is "svn info --xml svn://svn.twistedmatrix.com/svn/Twisted". I
-# think this is kind of a degenerate case.. it might even be a form of error.
-prefix_output_2 = """\
-<?xml version="1.0"?>
-<info>
-</info>
-"""
-
-# this is the svn info output for a local repository, svn info --xml
-# file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository
-prefix_output_3 = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="SVN-Repository"
- revision="3">
-<url>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository</url>
-<repository>
-<root>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository</root>
-<uuid>c0f47ff4-ba1e-0410-96b5-d44cc5c79e7f</uuid>
-</repository>
-<commit
- revision="3">
-<author>warner</author>
-<date>2006-10-01T07:37:04.182499Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-# % svn info --xml file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample/trunk
-
-prefix_output_4 = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="trunk"
- revision="3">
-<url>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample/trunk</url>
-<repository>
-<root>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository</root>
-<uuid>c0f47ff4-ba1e-0410-96b5-d44cc5c79e7f</uuid>
-</repository>
-<commit
- revision="1">
-<author>warner</author>
-<date>2006-10-01T07:37:02.286440Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-
-
-# output from svn log on .../SVN-Repository/sample
-# (so it includes trunk and branches)
-sample_base = ("file:///usr/home/warner/stuff/Projects/BuildBot/trees/misc/" +
- "_trial_temp/test_vc/repositories/SVN-Repository/sample")
-sample_logentries = [None] * 6
-
-sample_logentries[5] = """\
-<logentry
- revision="6">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-<paths>
-<path
- action="D">/sample/branch/version.c</path>
-</paths>
-<msg>revised_to_2</msg>
-</logentry>
-"""
-
-sample_logentries[4] = """\
-<logentry
- revision="5">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-<paths>
-<path
- action="D">/sample/branch</path>
-</paths>
-<msg>revised_to_2</msg>
-</logentry>
-"""
-
-sample_logentries[3] = """\
-<logentry
- revision="4">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-<paths>
-<path
- action="M">/sample/trunk/version.c</path>
-</paths>
-<msg>revised_to_2</msg>
-</logentry>
-"""
-
-sample_logentries[2] = """\
-<logentry
- revision="3">
-<author>warner</author>
-<date>2006-10-01T19:35:10.215692Z</date>
-<paths>
-<path
- action="M">/sample/branch/main.c</path>
-</paths>
-<msg>commit_on_branch</msg>
-</logentry>
-"""
-
-sample_logentries[1] = """\
-<logentry
- revision="2">
-<author>warner</author>
-<date>2006-10-01T19:35:09.154973Z</date>
-<paths>
-<path
- copyfrom-path="/sample/trunk"
- copyfrom-rev="1"
- action="A">/sample/branch</path>
-</paths>
-<msg>make_branch</msg>
-</logentry>
-"""
-
-sample_logentries[0] = """\
-<logentry
- revision="1">
-<author>warner</author>
-<date>2006-10-01T19:35:08.642045Z</date>
-<paths>
-<path
- action="A">/sample</path>
-<path
- action="A">/sample/trunk</path>
-<path
- action="A">/sample/trunk/subdir/subdir.c</path>
-<path
- action="A">/sample/trunk/main.c</path>
-<path
- action="A">/sample/trunk/version.c</path>
-<path
- action="A">/sample/trunk/subdir</path>
-</paths>
-<msg>sample_project_files</msg>
-</logentry>
-"""
-
-sample_info_output = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="sample"
- revision="4">
-<url>file:///usr/home/warner/stuff/Projects/BuildBot/trees/misc/_trial_temp/test_vc/repositories/SVN-Repository/sample</url>
-<repository>
-<root>file:///usr/home/warner/stuff/Projects/BuildBot/trees/misc/_trial_temp/test_vc/repositories/SVN-Repository</root>
-<uuid>4f94adfc-c41e-0410-92d5-fbf86b7c7689</uuid>
-</repository>
-<commit
- revision="4">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-
-changes_output_template = """\
-<?xml version="1.0"?>
-<log>
-%s</log>
-"""
-
-def make_changes_output(maxrevision):
- # return what 'svn log' would have just after the given revision was
- # committed
- logs = sample_logentries[0:maxrevision]
- assert len(logs) == maxrevision
- logs.reverse()
- output = changes_output_template % ("".join(logs))
- return output
-
-def make_logentry_elements(maxrevision):
- "return the corresponding logentry elements for the given revisions"
- doc = xml.dom.minidom.parseString(make_changes_output(maxrevision))
- return doc.getElementsByTagName("logentry")
-
-def split_file(path):
- pieces = path.split("/")
- if pieces[0] == "branch":
- return dict(branch="branch", path="/".join(pieces[1:]))
- if pieces[0] == "trunk":
- return dict(path="/".join(pieces[1:]))
- raise RuntimeError("there shouldn't be any files like %r" % path)
-
-
-class TestSVNPoller(gpo.GetProcessOutputMixin,
- changesource.ChangeSourceMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpGetProcessOutput()
- return self.setUpChangeSource()
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def attachSVNPoller(self, *args, **kwargs):
- s = svnpoller.SVNPoller(*args, **kwargs)
- self.attachChangeSource(s)
- return s
-
- def add_svn_command_result(self, command, result):
- self.expectCommands(
- gpo.Expect('svn', command).stdout(result))
-
-
- # tests
-
- def test_describe(self):
- s = self.attachSVNPoller('file://')
- self.assertSubstring("SVNPoller", s.describe())
-
- def test_strip_svnurl(self):
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
- s = self.attachSVNPoller(base + "/")
- self.failUnlessEqual(s.svnurl, base)
-
- def do_test_get_prefix(self, base, output, expected):
- s = self.attachSVNPoller(base)
- self.expectCommands(gpo.Expect('svn', 'info', '--xml', '--non-interactive', base).stdout(output))
- d = s.get_prefix()
- def check(prefix):
- self.failUnlessEqual(prefix, expected)
- self.assertAllCommandsRan()
- d.addCallback(check)
- return d
-
- def test_get_prefix_1(self):
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
- return self.do_test_get_prefix(base, prefix_output, 'trunk')
-
- def test_get_prefix_2(self):
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted"
- return self.do_test_get_prefix(base, prefix_output_2, '')
-
- def test_get_prefix_3(self):
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository")
- return self.do_test_get_prefix(base, prefix_output_3, '')
-
- def test_get_prefix_4(self):
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample/trunk")
- return self.do_test_get_prefix(base, prefix_output_3, 'sample/trunk')
-
- def test_log_parsing(self):
- s = self.attachSVNPoller('file:///foo')
- output = make_changes_output(4)
- entries = s.parse_logs(output)
- # no need for elaborate assertions here; this is minidom's logic
- self.assertEqual(len(entries), 4)
-
- def test_get_new_logentries(self):
- s = self.attachSVNPoller('file:///foo')
- entries = make_logentry_elements(4)
-
- s.last_change = 4
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 0)
-
- s.last_change = 3
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 1)
-
- s.last_change = 1
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 3)
-
- # special case: if last_change is None, then no new changes are queued
- s.last_change = None
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 0)
-
- def test_create_changes(self):
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample")
- s = self.attachSVNPoller(base, split_file=split_file)
- s._prefix = "sample"
-
- logentries = dict(zip(xrange(1, 7), reversed(make_logentry_elements(6))))
- changes = s.create_changes(reversed([ logentries[3], logentries[2] ]))
- self.failUnlessEqual(len(changes), 2)
- # note that parsing occurs in reverse
- self.failUnlessEqual(changes[0]['branch'], "branch")
- self.failUnlessEqual(changes[0]['revision'], '2')
- self.failUnlessEqual(changes[0]['project'], '')
- self.failUnlessEqual(changes[0]['repository'], base)
- self.failUnlessEqual(changes[1]['branch'], "branch")
- self.failUnlessEqual(changes[1]['files'], ["main.c"])
- self.failUnlessEqual(changes[1]['revision'], '3')
- self.failUnlessEqual(changes[1]['project'], '')
- self.failUnlessEqual(changes[1]['repository'], base)
-
- changes = s.create_changes([ logentries[4] ])
- self.failUnlessEqual(len(changes), 1)
- self.failUnlessEqual(changes[0]['branch'], None)
- self.failUnlessEqual(changes[0]['revision'], '4')
- self.failUnlessEqual(changes[0]['files'], ["version.c"])
-
- # r5 should *not* create a change as it's a branch deletion
- changes = s.create_changes([ logentries[5] ])
- self.failUnlessEqual(len(changes), 0)
-
- # r6 should create a change as it's not deleting an entire branch
- changes = s.create_changes([ logentries[6] ])
- self.failUnlessEqual(len(changes), 1)
- self.failUnlessEqual(changes[0]['branch'], 'branch')
- self.failUnlessEqual(changes[0]['revision'], '6')
- self.failUnlessEqual(changes[0]['files'], ["version.c"])
-
- def makeInfoExpect(self):
- return gpo.Expect('svn', 'info', '--xml', '--non-interactive', sample_base,
- '--username=dustin', '--password=bbrocks')
-
- def makeLogExpect(self):
- return gpo.Expect('svn', 'log', '--xml', '--verbose', '--non-interactive',
- '--username=dustin', '--password=bbrocks',
- '--limit=100', sample_base)
- def test_create_changes_overriden_project(self):
- def custom_split_file(path):
- f = split_file(path)
- if f:
- f["project"] = "overriden-project"
- f["repository"] = "overriden-repository"
- f["codebase"] = "overriden-codebase"
- return f
-
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample")
- s = self.attachSVNPoller(base, split_file=custom_split_file)
- s._prefix = "sample"
-
- logentries = dict(zip(xrange(1, 7), reversed(make_logentry_elements(6))))
- changes = s.create_changes(reversed([ logentries[3], logentries[2] ]))
- self.failUnlessEqual(len(changes), 2)
-
- # note that parsing occurs in reverse
- self.failUnlessEqual(changes[0]['branch'], "branch")
- self.failUnlessEqual(changes[0]['revision'], '2')
- self.failUnlessEqual(changes[0]['project'], "overriden-project")
- self.failUnlessEqual(changes[0]['repository'], "overriden-repository")
- self.failUnlessEqual(changes[0]['codebase'], "overriden-codebase")
-
- self.failUnlessEqual(changes[1]['branch'], "branch")
- self.failUnlessEqual(changes[1]['files'], ["main.c"])
- self.failUnlessEqual(changes[1]['revision'], '3')
- self.failUnlessEqual(changes[1]['project'], "overriden-project")
- self.failUnlessEqual(changes[1]['repository'], "overriden-repository")
- self.failUnlessEqual(changes[1]['codebase'], "overriden-codebase")
-
- def test_poll(self):
- s = self.attachSVNPoller(sample_base, split_file=split_file,
- svnuser='dustin', svnpasswd='bbrocks')
-
- d = defer.succeed(None)
-
-
- self.expectCommands(
- self.makeInfoExpect().stdout(sample_info_output),
- self.makeLogExpect().stdout(make_changes_output(1)),
- self.makeLogExpect().stdout(make_changes_output(1)),
- self.makeLogExpect().stdout(make_changes_output(2)),
- self.makeLogExpect().stdout(make_changes_output(4)),
- )
- # fire it the first time; it should do nothing
- d.addCallback(lambda _ : s.poll())
- def check_first(_):
- # no changes generated on the first iteration
- self.assertEqual(self.changes_added, [])
- self.failUnlessEqual(s.last_change, 1)
- d.addCallback(check_first)
-
- # now fire it again, nothing changing
- d.addCallback(lambda _ : s.poll())
- def check_second(_):
- self.assertEqual(self.changes_added, [])
- self.failUnlessEqual(s.last_change, 1)
- d.addCallback(check_second)
-
- # and again, with r2 this time
- d.addCallback(lambda _ : s.poll())
- def check_third(_):
- self.assertEqual(len(self.changes_added), 1)
- c = self.changes_added[0]
- self.failUnlessEqual(c['branch'], "branch")
- self.failUnlessEqual(c['revision'], '2')
- self.failUnlessEqual(c['files'], ['']) # signals a new branch
- self.failUnlessEqual(c['comments'], "make_branch")
- self.failUnlessEqual(c['src'], "svn")
- self.failUnlessEqual(s.last_change, 2)
- d.addCallback(check_third)
-
- # and again with both r3 and r4 appearing together
- def setup_fourth(_):
- self.changes_added = []
- d.addCallback(setup_fourth)
- d.addCallback(lambda _ : s.poll())
- def check_fourth(_):
- self.assertEqual(len(self.changes_added), 2)
- c = self.changes_added[0]
- self.failUnlessEqual(c['branch'], "branch")
- self.failUnlessEqual(c['revision'], '3')
- self.failUnlessEqual(c['files'], ["main.c"])
- self.failUnlessEqual(c['comments'], "commit_on_branch")
- self.failUnlessEqual(c['src'], "svn")
- c = self.changes_added[1]
- self.failUnlessEqual(c['branch'], None)
- self.failUnlessEqual(c['revision'], '4')
- self.failUnlessEqual(c['files'], ["version.c"])
- self.failUnlessEqual(c['comments'], "revised_to_2")
- self.failUnlessEqual(c['src'], "svn")
- self.failUnlessEqual(s.last_change, 4)
- self.assertAllCommandsRan()
- d.addCallback(check_fourth)
-
- return d
-
- @compat.usesFlushLoggedErrors
- def test_poll_get_prefix_exception(self):
- s = self.attachSVNPoller(sample_base, split_file=split_file,
- svnuser='dustin', svnpasswd='bbrocks')
-
- self.expectCommands(
- self.makeInfoExpect().stderr("error"))
- d = s.poll()
- @d.addCallback
- def check(_):
- # should have logged the RuntimeError, but not errback'd from poll
- self.assertEqual(len(self.flushLoggedErrors(IOError)), 1)
- self.assertAllCommandsRan()
- return d
-
- @compat.usesFlushLoggedErrors
- def test_poll_get_logs_exception(self):
- s = self.attachSVNPoller(sample_base, split_file=split_file,
- svnuser='dustin', svnpasswd='bbrocks')
- s._prefix = "abc" # skip the get_prefix stuff
-
- self.expectCommands(
- self.makeLogExpect().stderr("some error"))
- d = s.poll()
- @d.addCallback
- def check(_):
- # should have logged the RuntimeError, but not errback'd from poll
- self.assertEqual(len(self.flushLoggedErrors(IOError)), 1)
- self.assertAllCommandsRan()
- return d
-
- def test_cachepath_empty(self):
- cachepath = os.path.abspath('revcache')
- if os.path.exists(cachepath):
- os.unlink(cachepath)
- s = self.attachSVNPoller(sample_base, cachepath=cachepath)
- self.assertEqual(s.last_change, None)
-
- def test_cachepath_full(self):
- cachepath = os.path.abspath('revcache')
- with open(cachepath, "w") as f:
- f.write('33')
- s = self.attachSVNPoller(sample_base, cachepath=cachepath)
- self.assertEqual(s.last_change, 33)
-
- s.last_change = 44
- s.finished_ok(None)
- with open(cachepath) as f:
- self.assertEqual(f.read().strip(), '44')
-
- @compat.usesFlushLoggedErrors
- def test_cachepath_bogus(self):
- cachepath = os.path.abspath('revcache')
- with open(cachepath, "w") as f:
- f.write('nine')
- s = self.attachSVNPoller(sample_base, cachepath=cachepath)
- self.assertEqual(s.last_change, None)
- self.assertEqual(s.cachepath, None)
- # it should have called log.err once with a ValueError
- self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)
-
- def test_constructor_pollinterval(self):
- self.attachSVNPoller(sample_base, pollinterval=100) # just don't fail!
-
- def test_extra_args(self):
- extra_args = ['--no-auth-cache',]
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
-
- s = self.attachSVNPoller(svnurl=base, extra_args=extra_args)
- self.failUnlessEqual(s.extra_args, extra_args)
-
-class TestSplitFile(unittest.TestCase):
- def test_split_file_alwaystrunk(self):
- self.assertEqual(svnpoller.split_file_alwaystrunk('foo'), dict(path='foo'))
-
- def test_split_file_branches_trunk(self):
- self.assertEqual(
- svnpoller.split_file_branches('trunk/'),
- (None, ''))
-
- def test_split_file_branches_trunk_subdir(self):
- self.assertEqual(
- svnpoller.split_file_branches('trunk/subdir/'),
- (None, 'subdir/'))
-
- def test_split_file_branches_trunk_subfile(self):
- self.assertEqual(
- svnpoller.split_file_branches('trunk/subdir/file.c'),
- (None, 'subdir/file.c'))
-
- def test_split_file_branches_trunk_invalid(self):
- # file named trunk (not a directory):
- self.assertEqual(
- svnpoller.split_file_branches('trunk'),
- None)
-
- def test_split_file_branches_branch(self):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x/'),
- ('branches/1.5.x', ''))
-
- def test_split_file_branches_branch_subdir(self):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x/subdir/'),
- ('branches/1.5.x', 'subdir/'))
-
- def test_split_file_branches_branch_subfile(self):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x/subdir/file.c'),
- ('branches/1.5.x', 'subdir/file.c'))
-
- def test_split_file_branches_branch_invalid(self):
- # file named branches/1.5.x (not a directory):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x'),
- None)
-
- def test_split_file_branches_otherdir(self):
- # other dirs are ignored:
- self.assertEqual(
- svnpoller.split_file_branches('tags/testthis/subdir/'),
- None)
-
- def test_split_file_branches_otherfile(self):
- # other files are ignored:
- self.assertEqual(
- svnpoller.split_file_branches('tags/testthis/subdir/file.c'),
- None)
-
- def test_split_file_projects_branches(self):
- self.assertEqual(
- svnpoller.split_file_projects_branches('buildbot/trunk/subdir/file.c'),
- dict(project='buildbot', path='subdir/file.c'))
- self.assertEqual(
- svnpoller.split_file_projects_branches('buildbot/branches/1.5.x/subdir/file.c'),
- dict(project='buildbot', branch='branches/1.5.x', path='subdir/file.c'))
- # tags are ignored:
- self.assertEqual(
- svnpoller.split_file_projects_branches('buildbot/tags/testthis/subdir/file.c'),
- None)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py
deleted file mode 100644
index a403694d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py
+++ /dev/null
@@ -1,237 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import mock
-from twisted.trial import unittest
-from twisted.spread import pb
-from twisted.internet import defer, reactor
-from buildbot.clients import sendchange
-
-class Sender(unittest.TestCase):
-
- def setUp(self):
- # patch out some PB components and make up some mocks
- self.patch(pb, 'PBClientFactory', self._fake_PBClientFactory)
- self.patch(reactor, 'connectTCP', self._fake_connectTCP)
-
- self.factory = mock.Mock(name='PBClientFactory')
- self.factory.login = self._fake_login
- self.factory.login_d = defer.Deferred()
-
- self.remote = mock.Mock(name='PB Remote')
- self.remote.callRemote = self._fake_callRemote
- self.remote.broker.transport.loseConnection = self._fake_loseConnection
-
- # results
- self.creds = None
- self.conn_host = self.conn_port = None
- self.lostConnection = False
- self.added_changes = []
- self.vc_used = None
-
- def _fake_PBClientFactory(self):
- return self.factory
-
- def _fake_login(self, creds):
- self.creds = creds
- return self.factory.login_d
-
- def _fake_connectTCP(self, host, port, factory):
- self.conn_host = host
- self.conn_port = port
- self.assertIdentical(factory, self.factory)
- self.factory.login_d.callback(self.remote)
-
- def _fake_callRemote(self, method, change):
- self.assertEqual(method, 'addChange')
- self.added_changes.append(change)
- return defer.succeed(None)
-
- def _fake_loseConnection(self):
- self.lostConnection = True
-
- def assertProcess(self, host, port, username, password, changes):
- self.assertEqual([host, port, username, password, changes],
- [ self.conn_host, self.conn_port,
- self.creds.username, self.creds.password,
- self.added_changes])
-
- def test_send_minimal(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ['a'])
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='', repository='', who=None, files=['a'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_auth(self):
- s = sendchange.Sender('localhost:1234', auth=('me','sekrit'))
- d = s.send('branch', 'rev', 'comm', ['a'])
- def check(_):
- self.assertProcess('localhost', 1234, 'me', 'sekrit', [
- dict(project='', repository='', who=None, files=['a'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_full(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ['a'], who='me', category='cats',
- when=1234, properties={'a':'b'}, repository='r', vc='git',
- project='p', revlink='rl')
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='p', repository='r', who='me', files=['a'],
- comments='comm', branch='branch', revision='rev',
- category='cats', when=1234, properties={'a':'b'},
- revlink='rl', src='git')])
- d.addCallback(check)
- return d
-
- def test_send_files_tuple(self):
- # 'buildbot sendchange' sends files as a tuple, rather than a list..
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ('a', 'b'))
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='', repository='', who=None, files=['a', 'b'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_codebase(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ['a'], codebase='mycb')
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='', repository='', who=None, files=['a'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None, codebase='mycb')])
- d.addCallback(check)
- return d
-
- def test_send_unicode(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send(u'\N{DEGREE SIGN}',
- u'\U0001f49e',
- u'\N{POSTAL MARK FACE}',
- [u'\U0001F4C1'],
- project=u'\N{SKULL AND CROSSBONES}',
- repository=u'\N{SNOWMAN}',
- who=u'\N{THAI CHARACTER KHOMUT}',
- category=u'\U0001F640',
- when=1234,
- properties={u'\N{LATIN SMALL LETTER A WITH MACRON}':'b'},
- revlink=u'\U0001F517')
-
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project=u'\N{SKULL AND CROSSBONES}',
- repository=u'\N{SNOWMAN}',
- who=u'\N{THAI CHARACTER KHOMUT}',
- files=[u'\U0001F4C1'], # FILE FOLDER
- comments=u'\N{POSTAL MARK FACE}',
- branch=u'\N{DEGREE SIGN}',
- revision=u'\U0001f49e', # REVOLVING HEARTS
- category=u'\U0001F640', # WEARY CAT FACE
- when=1234,
- properties={u'\N{LATIN SMALL LETTER A WITH MACRON}':'b'},
- revlink=u'\U0001F517', # LINK SYMBOL
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_unicode_utf8(self):
- s = sendchange.Sender('localhost:1234')
-
- d = s.send(u'\N{DEGREE SIGN}'.encode('utf8'),
- u'\U0001f49e'.encode('utf8'),
- u'\N{POSTAL MARK FACE}'.encode('utf8'),
- [u'\U0001F4C1'.encode('utf8')],
- project=u'\N{SKULL AND CROSSBONES}'.encode('utf8'),
- repository=u'\N{SNOWMAN}'.encode('utf8'),
- who=u'\N{THAI CHARACTER KHOMUT}'.encode('utf8'),
- category=u'\U0001F640'.encode('utf8'),
- when=1234,
- properties={
- u'\N{LATIN SMALL LETTER A WITH MACRON}'.encode('utf8')
- : 'b'},
- revlink=u'\U0001F517'.encode('utf8'))
-
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project=u'\N{SKULL AND CROSSBONES}',
- repository=u'\N{SNOWMAN}',
- who=u'\N{THAI CHARACTER KHOMUT}',
- files=[u'\U0001F4C1'], # FILE FOLDER
- comments=u'\N{POSTAL MARK FACE}',
- branch=u'\N{DEGREE SIGN}',
- revision=u'\U0001f49e', # REVOLVING HEARTS
- category=u'\U0001F640', # WEARY CAT FACE
- when=1234,
- ## NOTE: not decoded!
- properties={'\xc4\x81':'b'},
- revlink=u'\U0001F517', # LINK SYMBOL
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_unicode_latin1(self):
- # hand send() a bunch of latin1 strings, and expect them recoded
- # to unicode
- s = sendchange.Sender('localhost:1234', encoding='latin1')
-
- d = s.send(u'\N{YEN SIGN}'.encode('latin1'),
- u'\N{POUND SIGN}'.encode('latin1'),
- u'\N{BROKEN BAR}'.encode('latin1'),
- [u'\N{NOT SIGN}'.encode('latin1')],
- project=u'\N{DEGREE SIGN}'.encode('latin1'),
- repository=u'\N{SECTION SIGN}'.encode('latin1'),
- who=u'\N{MACRON}'.encode('latin1'),
- category=u'\N{PILCROW SIGN}'.encode('latin1'),
- when=1234,
- properties={
- u'\N{SUPERSCRIPT ONE}'.encode('latin1')
- : 'b'},
- revlink=u'\N{INVERTED QUESTION MARK}'.encode('latin1'))
-
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project=u'\N{DEGREE SIGN}',
- repository=u'\N{SECTION SIGN}',
- who=u'\N{MACRON}',
- files=[u'\N{NOT SIGN}'],
- comments=u'\N{BROKEN BAR}',
- branch=u'\N{YEN SIGN}',
- revision=u'\N{POUND SIGN}',
- category=u'\N{PILCROW SIGN}',
- when=1234,
- ## NOTE: not decoded!
- properties={'\xb9':'b'},
- revlink=u'\N{INVERTED QUESTION MARK}',
- src=None)])
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py
deleted file mode 100644
index e4f61d3c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-from twisted.trial import unittest
-
-from buildbot.clients import tryclient
-from buildbot.util import json
-
-
-class createJobfile(unittest.TestCase):
-
- def makeNetstring(self, *strings):
- return ''.join(['%d:%s,' % (len(s), s) for s in strings])
-
- # version 1 is deprecated and not produced by the try client
-
- def test_createJobfile_v2_one_builder(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = None
- comment = None
- builderNames = ['runtests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '2', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, builderNames[0])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v2_two_builders(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = None
- comment = None
- builderNames = ['runtests', 'moretests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '2', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, builderNames[0], builderNames[1])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v3(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = 'someuser'
- comment = None
- builderNames = ['runtests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '3', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, who, builderNames[0])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v4(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = 'someuser'
- comment = 'insightful comment'
- builderNames = ['runtests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '4', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, who, comment, builderNames[0])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v5(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = 'someuser'
- comment = 'insightful comment'
- builderNames = ['runtests']
- properties = {'foo': 'bar'}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': jobid, 'branch': branch, 'baserev': baserev,
- 'patch_level': patch_level, 'patch_body': patch_body,
- 'repository': repository, 'project': project, 'who': who,
- 'comment': comment, 'builderNames': builderNames,
- 'properties': properties,
- }))
- self.assertEqual(job, jobstr)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py
deleted file mode 100644
index 23f1ea1a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.spread import pb
-from twisted.internet import defer, reactor
-from buildbot.clients import usersclient
-
-class TestUsersClient(unittest.TestCase):
-
- def setUp(self):
- # patch out some PB components and make up some mocks
- self.patch(pb, 'PBClientFactory', self._fake_PBClientFactory)
- self.patch(reactor, 'connectTCP', self._fake_connectTCP)
-
- self.factory = mock.Mock(name='PBClientFactory')
- self.factory.login = self._fake_login
- self.factory.login_d = defer.Deferred()
-
- self.remote = mock.Mock(name='PB Remote')
- self.remote.callRemote = self._fake_callRemote
- self.remote.broker.transport.loseConnection = self._fake_loseConnection
-
- # results
- self.conn_host = self.conn_port = None
- self.lostConnection = False
-
- def _fake_PBClientFactory(self):
- return self.factory
-
- def _fake_login(self, creds):
- return self.factory.login_d
-
- def _fake_connectTCP(self, host, port, factory):
- self.conn_host = host
- self.conn_port = port
- self.assertIdentical(factory, self.factory)
- self.factory.login_d.callback(self.remote)
-
- def _fake_callRemote(self, method, op, bb_username, bb_password, ids, info):
- self.assertEqual(method, 'commandline')
- self.called_with = dict(op=op, bb_username=bb_username,
- bb_password=bb_password, ids=ids, info=info)
- return defer.succeed(None)
-
- def _fake_loseConnection(self):
- self.lostConnection = True
-
- def assertProcess(self, host, port, called_with):
- self.assertEqual([host, port, called_with],
- [self.conn_host, self.conn_port, self.called_with])
-
- def test_usersclient_info(self):
- uc = usersclient.UsersClient('localhost', "user", "userpw", 1234)
- d = uc.send('update', 'bb_user', 'hashed_bb_pass', None,
- [{'identifier':'x', 'svn':'x'}])
- def check(_):
- self.assertProcess('localhost', 1234,
- dict(op='update', bb_username='bb_user',
- bb_password='hashed_bb_pass', ids=None,
- info=[dict(identifier='x', svn='x')]))
- d.addCallback(check)
- return d
-
- def test_usersclient_ids(self):
- uc = usersclient.UsersClient('localhost', "user", "userpw", 1234)
- d = uc.send('remove', None, None, ['x'], None)
- def check(_):
- self.assertProcess('localhost', 1234,
- dict(op='remove', bb_username=None,
- bb_password=None, ids=['x'], info=None))
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py
deleted file mode 100644
index 9b6f6c1d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py
+++ /dev/null
@@ -1,1207 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import re
-import os
-import textwrap
-import mock
-import __builtin__
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.application import service
-from twisted.internet import defer
-from buildbot import config, buildslave, interfaces, revlinks, locks
-from buildbot.process import properties, factory
-from buildbot.test.util import dirs, compat
-from buildbot.test.util.config import ConfigErrorsMixin
-from buildbot.changes import base as changes_base
-from buildbot.schedulers import base as schedulers_base
-from buildbot.status import base as status_base
-
-global_defaults = dict(
- title='Buildbot',
- titleURL='http://buildbot.net',
- buildbotURL='http://localhost:8080/',
- changeHorizon=None,
- eventHorizon=50,
- logHorizon=None,
- buildHorizon=None,
- logCompressionLimit=4096,
- logCompressionMethod='bz2',
- logMaxTailSize=None,
- logMaxSize=None,
- properties=properties.Properties(),
- mergeRequests=None,
- prioritizeBuilders=None,
- slavePortnum=None,
- multiMaster=False,
- debugPassword=None,
- manhole=None,
-)
-
-
-class FakeChangeSource(changes_base.ChangeSource):
- pass
-
-
-class FakeStatusReceiver(status_base.StatusReceiver):
- pass
-
-
-class FakeScheduler(object):
- implements(interfaces.IScheduler)
- def __init__(self, name):
- self.name = name
-
-class FakeBuilder(object):
-
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
-
-
-class ConfigErrors(unittest.TestCase):
-
- def test_constr(self):
- ex = config.ConfigErrors(['a', 'b'])
- self.assertEqual(ex.errors, ['a', 'b'])
-
- def test_addError(self):
- ex = config.ConfigErrors(['a'])
- ex.addError('c')
- self.assertEqual(ex.errors, ['a', 'c'])
-
- def test_nonempty(self):
- empty = config.ConfigErrors()
- full = config.ConfigErrors(['a'])
- self.failUnless(not empty)
- self.failIf(not full)
-
- def test_error_raises(self):
- e = self.assertRaises(config.ConfigErrors, config.error, "message")
- self.assertEqual(e.errors, ["message"])
-
- def test_error_no_raise(self):
- e = config.ConfigErrors()
- self.patch(config, "_errors", e)
- config.error("message")
- self.assertEqual(e.errors, ["message"])
-
- def test_str(self):
- ex = config.ConfigErrors()
- self.assertEqual(str(ex), "")
-
- ex = config.ConfigErrors(["a"])
- self.assertEqual(str(ex), "a")
-
- ex = config.ConfigErrors(["a", "b"])
- self.assertEqual(str(ex), "a\nb")
-
- ex = config.ConfigErrors(["a"])
- ex.addError('c')
- self.assertEqual(str(ex), "a\nc")
-
-
-class MasterConfig(ConfigErrorsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.basedir = os.path.abspath('basedir')
- self.filename = os.path.join(self.basedir, 'test.cfg')
- return self.setUpDirs('basedir')
-
- def tearDown(self):
- return self.tearDownDirs()
-
- # utils
-
- def patch_load_helpers(self):
- # patch out all of the "helpers" for laodConfig with null functions
- for n in dir(config.MasterConfig):
- if n.startswith('load_'):
- typ = 'loader'
- elif n.startswith('check_'):
- typ = 'checker'
- else:
- continue
-
- v = getattr(config.MasterConfig, n)
- if callable(v):
- if typ == 'loader':
- self.patch(config.MasterConfig, n,
- mock.Mock(side_effect=
- lambda filename, config_dict: None))
- else:
- self.patch(config.MasterConfig, n,
- mock.Mock(side_effect=
- lambda: None))
-
-
- def install_config_file(self, config_file, other_files={}):
- config_file = textwrap.dedent(config_file)
- with open(os.path.join(self.basedir, self.filename), "w") as f:
- f.write(config_file)
- for file, contents in other_files.items():
- with open(file, "w") as f:
- f.write(contents)
-
-
- # tests
-
- def test_defaults(self):
- cfg = config.MasterConfig()
- expected = dict(
- #validation,
- db=dict(
- db_url='sqlite:///state.sqlite',
- db_poll_interval=None),
- metrics = None,
- caches = dict(Changes=10, Builds=15),
- schedulers = {},
- builders = [],
- slaves = [],
- change_sources = [],
- status = [],
- user_managers = [],
- revlink = revlinks.default_revlink_matcher
- )
- expected.update(global_defaults)
- got = dict([
- (attr, getattr(cfg, attr))
- for attr, exp in expected.iteritems() ])
- self.assertEqual(got, expected)
-
- def test_defaults_validation(self):
- # re's aren't comparable, but we can make sure the keys match
- cfg = config.MasterConfig()
- self.assertEqual(sorted(cfg.validation.keys()),
- sorted([
- 'branch', 'revision', 'property_name', 'property_value',
- ]))
-
- def test_loadConfig_missing_file(self):
- self.assertRaisesConfigError(
- re.compile("configuration file .* does not exist"),
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_missing_basedir(self):
- self.assertRaisesConfigError(
- re.compile("basedir .* does not exist"),
- lambda : config.MasterConfig.loadConfig(
- os.path.join(self.basedir, 'NO'), 'test.cfg'))
-
- def test_loadConfig_open_error(self):
- """
- Check that loadConfig() raises correct ConfigError exception in cases
- when configure file is found, but we fail to open it.
- """
-
- def raise_IOError(*args):
- raise IOError("error_msg")
-
- self.install_config_file('#dummy')
-
- # override build-in open() function to always rise IOError
- self.patch(__builtin__, "open", raise_IOError)
-
- # check that we got the expected ConfigError exception
- self.assertRaisesConfigError(
- re.compile("unable to open configuration file .*: error_msg"),
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- @compat.usesFlushLoggedErrors
- def test_loadConfig_parse_error(self):
- self.install_config_file('def x:\nbar')
- self.assertRaisesConfigError(
- re.compile("error while parsing.*traceback in logfile"),
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
- self.assertEqual(len(self.flushLoggedErrors(SyntaxError)), 1)
-
- def test_loadConfig_eval_ConfigError(self):
- self.install_config_file("""\
- from buildbot import config
- BuildmasterConfig = { 'multiMaster': True }
- config.error('oh noes!')""")
- self.assertRaisesConfigError("oh noes",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_eval_ConfigErrors(self):
- # We test a config that has embedded errors, as well
- # as semantic errors that get added later. If an exception is raised
- # prematurely, then the semantic errors wouldn't get reported.
- self.install_config_file("""\
- from buildbot import config
- BuildmasterConfig = {}
- config.error('oh noes!')
- config.error('noes too!')""")
- e = self.assertRaises(config.ConfigErrors,
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
- self.assertEqual(e.errors, ['oh noes!', 'noes too!',
- 'no slaves are configured',
- 'no builders are configured'])
-
- def test_loadConfig_no_BuildmasterConfig(self):
- self.install_config_file('x=10')
- self.assertRaisesConfigError("does not define 'BuildmasterConfig'",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_unknown_key(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- BuildmasterConfig = dict(foo=10)
- """)
- self.assertRaisesConfigError("Unknown BuildmasterConfig key foo",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_unknown_keys(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- BuildmasterConfig = dict(foo=10, bar=20)
- """)
- self.assertRaisesConfigError("Unknown BuildmasterConfig keys bar, foo",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_success(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- BuildmasterConfig = dict()
- """)
- rv = config.MasterConfig.loadConfig(
- self.basedir, self.filename)
- self.assertIsInstance(rv, config.MasterConfig)
-
- # make sure all of the loaders and checkers are called
- self.failUnless(rv.load_global.called)
- self.failUnless(rv.load_validation.called)
- self.failUnless(rv.load_db.called)
- self.failUnless(rv.load_metrics.called)
- self.failUnless(rv.load_caches.called)
- self.failUnless(rv.load_schedulers.called)
- self.failUnless(rv.load_builders.called)
- self.failUnless(rv.load_slaves.called)
- self.failUnless(rv.load_change_sources.called)
- self.failUnless(rv.load_status.called)
- self.failUnless(rv.load_user_managers.called)
-
- self.failUnless(rv.check_single_master.called)
- self.failUnless(rv.check_schedulers.called)
- self.failUnless(rv.check_locks.called)
- self.failUnless(rv.check_builders.called)
- self.failUnless(rv.check_status.called)
- self.failUnless(rv.check_horizons.called)
- self.failUnless(rv.check_slavePortnum.called)
-
- def test_loadConfig_with_local_import(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- from subsidiary_module import x
- BuildmasterConfig = dict()
- """,
- {'basedir/subsidiary_module.py' : "x = 10"})
- rv = config.MasterConfig.loadConfig(
- self.basedir, self.filename)
- self.assertIsInstance(rv, config.MasterConfig)
-
-
-class MasterConfig_loaders(ConfigErrorsMixin, unittest.TestCase):
-
- filename = 'test.cfg'
-
- def setUp(self):
- self.cfg = config.MasterConfig()
- self.errors = config.ConfigErrors()
- self.patch(config, '_errors', self.errors)
-
- # utils
-
- def assertResults(self, **expected):
- self.failIf(self.errors, self.errors.errors)
- got = dict([
- (attr, getattr(self.cfg, attr))
- for attr, exp in expected.iteritems() ])
- self.assertEqual(got, expected)
-
- # tests
-
- def test_load_global_defaults(self):
- self.cfg.load_global(self.filename, {})
- self.assertResults(**global_defaults)
-
- def test_load_global_string_param_not_string(self):
- self.cfg.load_global(self.filename,
- dict(title=10))
- self.assertConfigError(self.errors, 'must be a string')
-
- def test_load_global_int_param_not_int(self):
- self.cfg.load_global(self.filename,
- dict(changeHorizon='yes'))
- self.assertConfigError(self.errors, 'must be an int')
-
- def do_test_load_global(self, config_dict, **expected):
- self.cfg.load_global(self.filename, config_dict)
- self.assertResults(**expected)
-
- def test_load_global_title(self):
- self.do_test_load_global(dict(title='hi'), title='hi')
-
- def test_load_global_projectURL(self):
- self.do_test_load_global(dict(projectName='hey'), title='hey')
-
- def test_load_global_titleURL(self):
- self.do_test_load_global(dict(titleURL='hi'), titleURL='hi')
-
- def test_load_global_buildbotURL(self):
- self.do_test_load_global(dict(buildbotURL='hey'), buildbotURL='hey')
-
- def test_load_global_changeHorizon(self):
- self.do_test_load_global(dict(changeHorizon=10), changeHorizon=10)
-
- def test_load_global_changeHorizon_none(self):
- self.do_test_load_global(dict(changeHorizon=None), changeHorizon=None)
-
- def test_load_global_eventHorizon(self):
- self.do_test_load_global(dict(eventHorizon=10), eventHorizon=10)
-
- def test_load_global_logHorizon(self):
- self.do_test_load_global(dict(logHorizon=10), logHorizon=10)
-
- def test_load_global_buildHorizon(self):
- self.do_test_load_global(dict(buildHorizon=10), buildHorizon=10)
-
- def test_load_global_logCompressionLimit(self):
- self.do_test_load_global(dict(logCompressionLimit=10),
- logCompressionLimit=10)
-
- def test_load_global_logCompressionMethod(self):
- self.do_test_load_global(dict(logCompressionMethod='gz'),
- logCompressionMethod='gz')
-
- def test_load_global_logCompressionMethod_invalid(self):
- self.cfg.load_global(self.filename,
- dict(logCompressionMethod='foo'))
- self.assertConfigError(self.errors, "must be 'bz2' or 'gz'")
-
- def test_load_global_codebaseGenerator(self):
- func = lambda _: "dummy"
- self.do_test_load_global(dict(codebaseGenerator=func),
- codebaseGenerator=func)
-
- def test_load_global_codebaseGenerator_invalid(self):
- self.cfg.load_global(self.filename,
- dict(codebaseGenerator='dummy'))
- self.assertConfigError(self.errors,
- "codebaseGenerator must be a callable "
- "accepting a dict and returning a str")
-
- def test_load_global_logMaxSize(self):
- self.do_test_load_global(dict(logMaxSize=123), logMaxSize=123)
-
- def test_load_global_logMaxTailSize(self):
- self.do_test_load_global(dict(logMaxTailSize=123), logMaxTailSize=123)
-
- def test_load_global_properties(self):
- exp = properties.Properties()
- exp.setProperty('x', 10, self.filename)
- self.do_test_load_global(dict(properties=dict(x=10)), properties=exp)
-
- def test_load_global_properties_invalid(self):
- self.cfg.load_global(self.filename,
- dict(properties='yes'))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_global_mergeRequests_bool(self):
- self.do_test_load_global(dict(mergeRequests=False),
- mergeRequests=False)
-
- def test_load_global_mergeRequests_callable(self):
- callable = lambda : None
- self.do_test_load_global(dict(mergeRequests=callable),
- mergeRequests=callable)
-
- def test_load_global_mergeRequests_invalid(self):
- self.cfg.load_global(self.filename,
- dict(mergeRequests='yes'))
- self.assertConfigError(self.errors,
- "must be a callable, True, or False")
-
- def test_load_global_prioritizeBuilders_callable(self):
- callable = lambda : None
- self.do_test_load_global(dict(prioritizeBuilders=callable),
- prioritizeBuilders=callable)
-
- def test_load_global_prioritizeBuilders_invalid(self):
- self.cfg.load_global(self.filename,
- dict(prioritizeBuilders='yes'))
- self.assertConfigError(self.errors, "must be a callable")
-
- def test_load_global_slavePortnum_int(self):
- self.do_test_load_global(dict(slavePortnum=123),
- slavePortnum='tcp:123')
-
- def test_load_global_slavePortnum_str(self):
- self.do_test_load_global(dict(slavePortnum='udp:123'),
- slavePortnum='udp:123')
-
- def test_load_global_multiMaster(self):
- self.do_test_load_global(dict(multiMaster=1), multiMaster=1)
-
- def test_load_global_debugPassword(self):
- self.do_test_load_global(dict(debugPassword='xyz'),
- debugPassword='xyz')
-
- def test_load_global_manhole(self):
- mh = mock.Mock(name='manhole')
- self.do_test_load_global(dict(manhole=mh), manhole=mh)
-
- def test_load_global_revlink_callable(self):
- callable = lambda : None
- self.do_test_load_global(dict(revlink=callable),
- revlink=callable)
-
- def test_load_global_revlink_invalid(self):
- self.cfg.load_global(self.filename, dict(revlink=''))
- self.assertConfigError(self.errors, "must be a callable")
-
- def test_load_validation_defaults(self):
- self.cfg.load_validation(self.filename, {})
- self.assertEqual(sorted(self.cfg.validation.keys()),
- sorted([
- 'branch', 'revision', 'property_name', 'property_value',
- ]))
-
- def test_load_validation_invalid(self):
- self.cfg.load_validation(self.filename,
- dict(validation='plz'))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_validation_unk_keys(self):
- self.cfg.load_validation(self.filename,
- dict(validation=dict(users='.*')))
- self.assertConfigError(self.errors, "unrecognized validation key(s)")
-
- def test_load_validation(self):
- r = re.compile('.*')
- self.cfg.load_validation(self.filename,
- dict(validation=dict(branch=r)))
- self.assertEqual(self.cfg.validation['branch'], r)
- # check that defaults are still around
- self.assertIn('revision', self.cfg.validation)
-
-
- def test_load_db_defaults(self):
- self.cfg.load_db(self.filename, {})
- self.assertResults(
- db=dict(db_url='sqlite:///state.sqlite', db_poll_interval=None))
-
- def test_load_db_db_url(self):
- self.cfg.load_db(self.filename, dict(db_url='abcd'))
- self.assertResults(db=dict(db_url='abcd', db_poll_interval=None))
-
- def test_load_db_db_poll_interval(self):
- self.cfg.load_db(self.filename, dict(db_poll_interval=2))
- self.assertResults(
- db=dict(db_url='sqlite:///state.sqlite', db_poll_interval=2))
-
- def test_load_db_dict(self):
- self.cfg.load_db(self.filename,
- dict(db=dict(db_url='abcd', db_poll_interval=10)))
- self.assertResults(db=dict(db_url='abcd', db_poll_interval=10))
-
- def test_load_db_unk_keys(self):
- self.cfg.load_db(self.filename,
- dict(db=dict(db_url='abcd', db_poll_interval=10, bar='bar')))
- self.assertConfigError(self.errors, "unrecognized keys in")
-
- def test_load_db_not_int(self):
- self.cfg.load_db(self.filename,
- dict(db=dict(db_url='abcd', db_poll_interval='ten')))
- self.assertConfigError(self.errors, "must be an int")
-
-
- def test_load_metrics_defaults(self):
- self.cfg.load_metrics(self.filename, {})
- self.assertResults(metrics=None)
-
- def test_load_metrics_invalid(self):
- self.cfg.load_metrics(self.filename, dict(metrics=13))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_metrics(self):
- self.cfg.load_metrics(self.filename,
- dict(metrics=dict(foo=1)))
- self.assertResults(metrics=dict(foo=1))
-
-
- def test_load_caches_defaults(self):
- self.cfg.load_caches(self.filename, {})
- self.assertResults(caches=dict(Changes=10, Builds=15))
-
- def test_load_caches_invalid(self):
- self.cfg.load_caches(self.filename, dict(caches=13))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_caches_buildCacheSize(self):
- self.cfg.load_caches(self.filename,
- dict(buildCacheSize=13))
- self.assertResults(caches=dict(Builds=13, Changes=10))
-
- def test_load_caches_buildCacheSize_and_caches(self):
- self.cfg.load_caches(self.filename,
- dict(buildCacheSize=13, caches=dict(builds=11)))
- self.assertConfigError(self.errors, "cannot specify")
-
- def test_load_caches_changeCacheSize(self):
- self.cfg.load_caches(self.filename,
- dict(changeCacheSize=13))
- self.assertResults(caches=dict(Changes=13, Builds=15))
-
- def test_load_caches_changeCacheSize_and_caches(self):
- self.cfg.load_caches(self.filename,
- dict(changeCacheSize=13, caches=dict(changes=11)))
- self.assertConfigError(self.errors, "cannot specify")
-
- def test_load_caches(self):
- self.cfg.load_caches(self.filename,
- dict(caches=dict(foo=1)))
- self.assertResults(caches=dict(Changes=10, Builds=15, foo=1))
-
- def test_load_caches_entries_test(self):
- self.cfg.load_caches(self.filename,
- dict(caches=dict(foo="1")))
- self.assertConfigError(self.errors,
- "value for cache size 'foo' must be an integer")
-
- def test_load_schedulers_defaults(self):
- self.cfg.load_schedulers(self.filename, {})
- self.assertResults(schedulers={})
-
- def test_load_schedulers_not_list(self):
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=dict()))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_schedulers_not_instance(self):
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=[mock.Mock()]))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_schedulers_dupe(self):
- sch1 = FakeScheduler(name='sch')
- sch2 = FakeScheduler(name='sch')
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=[ sch1, sch2 ]))
- self.assertConfigError(self.errors,
- "scheduler name 'sch' used multiple times")
-
- def test_load_schedulers(self):
- class Sch(schedulers_base.BaseScheduler):
- def __init__(self, name):
- self.name = name
- sch = Sch('sch')
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=[sch]))
- self.assertResults(schedulers=dict(sch=sch))
-
-
- def test_load_builders_defaults(self):
- self.cfg.load_builders(self.filename, {})
- self.assertResults(builders=[])
-
- def test_load_builders_not_list(self):
- self.cfg.load_builders(self.filename,
- dict(builders=dict()))
- self.assertConfigError(self.errors, "must be a list")
-
- def test_load_builders_not_instance(self):
- self.cfg.load_builders(self.filename,
- dict(builders=[mock.Mock()]))
- self.assertConfigError(self.errors, "is not a builder config (in c['builders']")
-
- def test_load_builders(self):
- bldr = config.BuilderConfig(name='x',
- factory=factory.BuildFactory(), slavename='x')
- self.cfg.load_builders(self.filename,
- dict(builders=[bldr]))
- self.assertResults(builders=[bldr])
-
- def test_load_builders_dict(self):
- bldr = dict(name='x', factory=factory.BuildFactory(), slavename='x')
- self.cfg.load_builders(self.filename,
- dict(builders=[bldr]))
- self.assertIsInstance(self.cfg.builders[0], config.BuilderConfig)
- self.assertEqual(self.cfg.builders[0].name, 'x')
-
- @compat.usesFlushWarnings
- def test_load_builders_abs_builddir(self):
- bldr = dict(name='x', factory=factory.BuildFactory(), slavename='x',
- builddir=os.path.abspath('.'))
- self.cfg.load_builders(self.filename,
- dict(builders=[bldr]))
- self.assertEqual(
- len(self.flushWarnings([self.cfg.load_builders])),
- 1)
-
- def test_load_slaves_defaults(self):
- self.cfg.load_slaves(self.filename, {})
- self.assertResults(slaves=[])
-
- def test_load_slaves_not_list(self):
- self.cfg.load_slaves(self.filename,
- dict(slaves=dict()))
- self.assertConfigError(self.errors, "must be a list")
-
- def test_load_slaves_not_instance(self):
- self.cfg.load_slaves(self.filename,
- dict(slaves=[mock.Mock()]))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_slaves_reserved_names(self):
- for name in 'debug', 'change', 'status':
- self.cfg.load_slaves(self.filename,
- dict(slaves=[buildslave.BuildSlave(name, 'x')]))
- self.assertConfigError(self.errors, "is reserved")
- self.errors.errors[:] = [] # clear out the errors
-
- def test_load_slaves(self):
- sl = buildslave.BuildSlave('foo', 'x')
- self.cfg.load_slaves(self.filename,
- dict(slaves=[sl]))
- self.assertResults(slaves=[sl])
-
-
- def test_load_change_sources_defaults(self):
- self.cfg.load_change_sources(self.filename, {})
- self.assertResults(change_sources=[])
-
- def test_load_change_sources_not_instance(self):
- self.cfg.load_change_sources(self.filename,
- dict(change_source=[mock.Mock()]))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_change_sources_single(self):
- chsrc = FakeChangeSource()
- self.cfg.load_change_sources(self.filename,
- dict(change_source=chsrc))
- self.assertResults(change_sources=[chsrc])
-
- def test_load_change_sources_list(self):
- chsrc = FakeChangeSource()
- self.cfg.load_change_sources(self.filename,
- dict(change_source=[chsrc]))
- self.assertResults(change_sources=[chsrc])
-
- def test_load_status_not_list(self):
- self.cfg.load_status(self.filename, dict(status="not-list"))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_status_not_status_rec(self):
- self.cfg.load_status(self.filename, dict(status=['fo']))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_user_managers_defaults(self):
- self.cfg.load_user_managers(self.filename, {})
- self.assertResults(user_managers=[])
-
- def test_load_user_managers_not_list(self):
- self.cfg.load_user_managers(self.filename,
- dict(user_managers='foo'))
- self.assertConfigError(self.errors, "must be a list")
-
- def test_load_user_managers(self):
- um = mock.Mock()
- self.cfg.load_user_managers(self.filename,
- dict(user_managers=[um]))
- self.assertResults(user_managers=[um])
-
-class MasterConfig_checkers(ConfigErrorsMixin, unittest.TestCase):
-
- def setUp(self):
- self.cfg = config.MasterConfig()
- self.errors = config.ConfigErrors()
- self.patch(config, '_errors', self.errors)
-
- # utils
-
- def setup_basic_attrs(self):
- # set up a basic config for checking; this will be modified below
- sch = mock.Mock()
- sch.name = 'sch'
- sch.listBuilderNames = lambda : [ 'b1', 'b2' ]
-
- b1 = mock.Mock()
- b1.name = 'b1'
-
- b2 = mock.Mock()
- b2.name = 'b2'
-
- self.cfg.schedulers = dict(sch=sch)
- self.cfg.slaves = [ mock.Mock() ]
- self.cfg.builders = [ b1, b2 ]
-
- def setup_builder_locks(self,
- builder_lock=None,
- dup_builder_lock=False,
- bare_builder_lock=False):
- """Set-up two mocked builders with specified locks.
-
- @type builder_lock: string or None
- @param builder_lock: Name of the lock to add to first builder.
- If None, no lock is added.
-
- @type dup_builder_lock: boolean
- @param dup_builder_lock: if True, add a lock with duplicate name
- to the second builder
-
- @type dup_builder_lock: boolean
- @param bare_builder_lock: if True, add bare lock objects, don't wrap
- them into locks.LockAccess object
- """
- def bldr(name):
- b = mock.Mock()
- b.name = name
- b.locks = []
- b.factory.steps = [ ('cls', (), dict(locks=[])) ]
- return b
-
- def lock(name):
- l = mock.Mock(spec=locks.MasterLock)
- l.name = name
- if bare_builder_lock:
- return l
- return locks.LockAccess(l, "counting", _skipChecks=True)
-
- b1, b2 = bldr('b1'), bldr('b2')
- self.cfg.builders = [ b1, b2 ]
- if builder_lock:
- b1.locks.append(lock(builder_lock))
- if dup_builder_lock:
- b2.locks.append(lock(builder_lock))
-
- # tests
-
- def test_check_single_master_multimaster(self):
- self.cfg.multiMaster = True
- self.cfg.check_single_master()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_single_master_no_builders(self):
- self.setup_basic_attrs()
- self.cfg.builders = [ ]
- self.cfg.check_single_master()
- self.assertConfigError(self.errors, "no builders are configured")
-
- def test_check_single_master_no_slaves(self):
- self.setup_basic_attrs()
- self.cfg.slaves = [ ]
- self.cfg.check_single_master()
- self.assertConfigError(self.errors, "no slaves are configured")
-
- def test_check_single_master_unsch_builder(self):
- self.setup_basic_attrs()
- b3 = mock.Mock()
- b3.name = 'b3'
- self.cfg.builders.append(b3)
- self.cfg.check_single_master()
- self.assertConfigError(self.errors, "have no schedulers to drive them")
-
-
- def test_check_schedulers_unknown_builder(self):
- self.setup_basic_attrs()
- del self.cfg.builders[1] # remove b2, leaving b1
-
- self.cfg.check_schedulers()
- self.assertConfigError(self.errors, "Unknown builder 'b2'")
-
- def test_check_schedulers_ignored_in_multiMaster(self):
- self.setup_basic_attrs()
- del self.cfg.builders[1] # remove b2, leaving b1
- self.cfg.multiMaster = True
- self.cfg.check_schedulers()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_schedulers(self):
- self.setup_basic_attrs()
- self.cfg.check_schedulers()
- self.assertNoConfigErrors(self.errors)
-
-
- def test_check_locks_dup_builder_lock(self):
- self.setup_builder_locks(builder_lock='l', dup_builder_lock=True)
- self.cfg.check_locks()
- self.assertConfigError(self.errors, "Two locks share")
-
- def test_check_locks(self):
- self.setup_builder_locks(builder_lock='bl')
- self.cfg.check_locks()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_locks_none(self):
- # no locks in the whole config, should be fine
- self.setup_builder_locks()
- self.cfg.check_locks()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_locks_bare(self):
- # check_locks() should be able to handle bare lock object,
- # lock objects that are not wrapped into LockAccess() object
- self.setup_builder_locks(builder_lock='oldlock',
- bare_builder_lock=True)
- self.cfg.check_locks()
- self.assertNoConfigErrors(self.errors)
-
-
- def test_check_builders_unknown_slave(self):
- sl = mock.Mock()
- sl.slavename = 'xyz'
- self.cfg.slaves = [ sl ]
-
- b1 = FakeBuilder(slavenames=[ 'xyz', 'abc' ], builddir='x', name='b1')
- self.cfg.builders = [ b1 ]
-
- self.cfg.check_builders()
- self.assertConfigError(self.errors,
- "builder 'b1' uses unknown slaves 'abc'")
-
- def test_check_builders_duplicate_name(self):
- b1 = FakeBuilder(slavenames=[], name='b1', builddir='1')
- b2 = FakeBuilder(slavenames=[], name='b1', builddir='2')
- self.cfg.builders = [ b1, b2 ]
-
- self.cfg.check_builders()
- self.assertConfigError(self.errors,
- "duplicate builder name 'b1'")
-
- def test_check_builders_duplicate_builddir(self):
- b1 = FakeBuilder(slavenames=[], name='b1', builddir='dir')
- b2 = FakeBuilder(slavenames=[], name='b2', builddir='dir')
- self.cfg.builders = [ b1, b2 ]
-
- self.cfg.check_builders()
- self.assertConfigError(self.errors,
- "duplicate builder builddir 'dir'")
-
- def test_check_builders(self):
- sl = mock.Mock()
- sl.slavename = 'a'
- self.cfg.slaves = [ sl ]
-
- b1 = FakeBuilder(slavenames=[ 'a' ], name='b1', builddir='dir1')
- b2 = FakeBuilder(slavenames=[ 'a' ], name='b2', builddir='dir2')
- self.cfg.builders = [ b1, b2 ]
-
- self.cfg.check_builders()
- self.assertNoConfigErrors(self.errors)
-
-
- def test_check_status_fails(self):
- st = FakeStatusReceiver()
- st.checkConfig = lambda status: config.error("oh noes")
- self.cfg.status = [ st ]
-
- self.cfg.check_status()
-
- self.assertConfigError(self.errors, "oh noes")
-
- def test_check_status(self):
- st = FakeStatusReceiver()
- st.checkConfig = mock.Mock()
- self.cfg.status = [ st ]
-
- self.cfg.check_status()
-
- self.assertNoConfigErrors(self.errors)
- st.checkConfig.assert_called_once_with(self.cfg.status)
-
- def test_check_horizons(self):
- self.cfg.logHorizon = 100
- self.cfg.buildHorizon = 50
- self.cfg.check_horizons()
-
- self.assertConfigError(self.errors, "logHorizon must be less")
-
- def test_check_slavePortnum_set(self):
- self.cfg.slavePortnum = 10
- self.cfg.check_slavePortnum()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_slavePortnum_not_set_slaves(self):
- self.cfg.slaves = [ mock.Mock() ]
- self.cfg.check_slavePortnum()
- self.assertConfigError(self.errors,
- "slaves are configured, but no slavePortnum is set")
-
- def test_check_slavePortnum_not_set_debug(self):
- self.cfg.debugPassword = 'ssh'
- self.cfg.check_slavePortnum()
- self.assertConfigError(self.errors,
- "debug client is configured, but no slavePortnum is set")
-
-
-class BuilderConfig(ConfigErrorsMixin, unittest.TestCase):
-
- factory = factory.BuildFactory()
-
- # utils
-
- def assertAttributes(self, cfg, **expected):
- got = dict([
- (attr, getattr(cfg, attr))
- for attr, exp in expected.iteritems() ])
- self.assertEqual(got, expected)
-
- # tests
-
- def test_no_name(self):
- self.assertRaisesConfigError(
- "builder's name is required",
- lambda : config.BuilderConfig(
- factory=self.factory, slavenames=['a']))
-
- def test_reserved_name(self):
- self.assertRaisesConfigError(
- "builder names must not start with an underscore: '_a'",
- lambda : config.BuilderConfig(name='_a',
- factory=self.factory, slavenames=['a']))
-
- def test_no_factory(self):
- self.assertRaisesConfigError(
- "builder 'a' has no factory",
- lambda : config.BuilderConfig(
- name='a', slavenames=['a']))
-
- def test_wrong_type_factory(self):
- self.assertRaisesConfigError(
- "builder 'a's factory is not",
- lambda : config.BuilderConfig(
- factory=[], name='a', slavenames=['a']))
-
- def test_no_slavenames(self):
- self.assertRaisesConfigError(
- "builder 'a': at least one slavename is required",
- lambda : config.BuilderConfig(
- name='a', factory=self.factory))
-
- def test_bogus_slavenames(self):
- self.assertRaisesConfigError(
- "slavenames must be a list or a string",
- lambda : config.BuilderConfig(
- name='a', slavenames={1:2}, factory=self.factory))
-
- def test_bogus_slavename(self):
- self.assertRaisesConfigError(
- "slavename must be a string",
- lambda : config.BuilderConfig(
- name='a', slavename=1, factory=self.factory))
-
- def test_bogus_category(self):
- self.assertRaisesConfigError(
- "category must be a string",
- lambda : config.BuilderConfig(category=13,
- name='a', slavenames=['a'], factory=self.factory))
-
- def test_inv_nextSlave(self):
- self.assertRaisesConfigError(
- "nextSlave must be a callable",
- lambda : config.BuilderConfig(nextSlave="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_inv_nextBuild(self):
- self.assertRaisesConfigError(
- "nextBuild must be a callable",
- lambda : config.BuilderConfig(nextBuild="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_inv_canStartBuild(self):
- self.assertRaisesConfigError(
- "canStartBuild must be a callable",
- lambda : config.BuilderConfig(canStartBuild="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_inv_env(self):
- self.assertRaisesConfigError(
- "builder's env must be a dictionary",
- lambda : config.BuilderConfig(env="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_defaults(self):
- cfg = config.BuilderConfig(
- name='a b c', slavename='a', factory=self.factory)
- self.assertIdentical(cfg.factory, self.factory)
- self.assertAttributes(cfg,
- name='a b c',
- slavenames=['a'],
- builddir='a_b_c',
- slavebuilddir='a_b_c',
- category='',
- nextSlave=None,
- locks=[],
- env={},
- properties={},
- mergeRequests=None,
- description=None)
-
- def test_args(self):
- cfg = config.BuilderConfig(
- name='b', slavename='s1', slavenames='s2', builddir='bd',
- slavebuilddir='sbd', factory=self.factory, category='c',
- nextSlave=lambda : 'ns', nextBuild=lambda : 'nb', locks=['l'],
- env=dict(x=10), properties=dict(y=20), mergeRequests='mr',
- description='buzz')
- self.assertIdentical(cfg.factory, self.factory)
- self.assertAttributes(cfg,
- name='b',
- slavenames=['s2', 's1'],
- builddir='bd',
- slavebuilddir='sbd',
- category='c',
- locks=['l'],
- env={'x':10},
- properties={'y':20},
- mergeRequests='mr',
- description='buzz')
-
- def test_getConfigDict(self):
- ns = lambda : 'ns'
- nb = lambda : 'nb'
- cfg = config.BuilderConfig(
- name='b', slavename='s1', slavenames='s2', builddir='bd',
- slavebuilddir='sbd', factory=self.factory, category='c',
- nextSlave=ns, nextBuild=nb, locks=['l'],
- env=dict(x=10), properties=dict(y=20), mergeRequests='mr',
- description='buzz')
- self.assertEqual(cfg.getConfigDict(), {'builddir': 'bd',
- 'category': 'c',
- 'description': 'buzz',
- 'env': {'x': 10},
- 'factory': self.factory,
- 'locks': ['l'],
- 'mergeRequests': 'mr',
- 'name': 'b',
- 'nextBuild': nb,
- 'nextSlave': ns,
- 'properties': {'y': 20},
- 'slavebuilddir': 'sbd',
- 'slavenames': ['s2', 's1'],
- })
-
-
-
-class FakeService(config.ReconfigurableServiceMixin,
- service.Service):
-
- succeed = True
- call_index = 1
-
- def reconfigService(self, new_config):
- self.called = FakeService.call_index
- FakeService.call_index += 1
- d = config.ReconfigurableServiceMixin.reconfigService(self, new_config)
- if not self.succeed:
- @d.addCallback
- def fail(_):
- raise ValueError("oh noes")
- return d
-
-
-
-class FakeMultiService(config.ReconfigurableServiceMixin,
- service.MultiService):
-
- def reconfigService(self, new_config):
- self.called = True
- d = config.ReconfigurableServiceMixin.reconfigService(self, new_config)
- return d
-
-
-
-class ReconfigurableServiceMixin(unittest.TestCase):
-
- def test_service(self):
- svc = FakeService()
- d = svc.reconfigService(mock.Mock())
- @d.addCallback
- def check(_):
- self.assertTrue(svc.called)
- return d
-
- @defer.inlineCallbacks
- def test_service_failure(self):
- svc = FakeService()
- svc.succeed = False
- try:
- yield svc.reconfigService(mock.Mock())
- except ValueError:
- pass
- else:
- self.fail("should have raised ValueError")
-
- def test_multiservice(self):
- svc = FakeMultiService()
- ch1 = FakeService()
- ch1.setServiceParent(svc)
- ch2 = FakeMultiService()
- ch2.setServiceParent(svc)
- ch3 = FakeService()
- ch3.setServiceParent(ch2)
- d = svc.reconfigService(mock.Mock())
- @d.addCallback
- def check(_):
- self.assertTrue(svc.called)
- self.assertTrue(ch1.called)
- self.assertTrue(ch2.called)
- self.assertTrue(ch3.called)
- return d
-
- def test_multiservice_priority(self):
- parent = FakeMultiService()
- svc128 = FakeService()
- svc128.setServiceParent(parent)
-
- services = [ svc128 ]
- for i in range(20, 1, -1):
- svc = FakeService()
- svc.reconfig_priority = i
- svc.setServiceParent(parent)
- services.append(svc)
-
- d = parent.reconfigService(mock.Mock())
- @d.addCallback
- def check(_):
- prio_order = [ svc.called for svc in services ]
- called_order = sorted(prio_order)
- self.assertEqual(prio_order, called_order)
- return d
-
- @compat.usesFlushLoggedErrors
- @defer.inlineCallbacks
- def test_multiservice_nested_failure(self):
- svc = FakeMultiService()
- ch1 = FakeService()
- ch1.setServiceParent(svc)
- ch1.succeed = False
- try:
- yield svc.reconfigService(mock.Mock())
- except ValueError:
- pass
- else:
- self.fail("should have raised ValueError")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py
deleted file mode 100644
index 30aaad07..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import re
-import os
-
-from twisted.python import log
-from twisted.trial import unittest
-from twisted.internet import protocol, defer, utils, reactor
-
-test = '''
-Update of /cvsroot/test
-In directory example:/tmp/cvs-serv21085
-
-Modified Files:
- README hello.c
-Log Message:
-two files checkin
-
-'''
-golden_1_11_regex=[
- '^From:',
- '^To: buildbot@example.com$',
- '^Reply-To: noreply@example.com$',
- '^Subject: cvs update for project test$',
- '^Date:',
- '^X-Mailer: Python buildbot-cvs-mail',
- '^$',
- '^Cvsmode: 1.11$',
- '^Category: None',
- '^CVSROOT: \"ext:example:/cvsroot\"',
- '^Files: test README 1.1,1.2 hello.c 2.2,2.3$',
- '^Project: test$',
- '^$',
- '^Update of /cvsroot/test$',
- '^In directory example:/tmp/cvs-serv21085$',
- '^$',
- '^Modified Files:$',
- 'README hello.c$',
- 'Log Message:$',
- '^two files checkin',
- '^$',
- '^$']
-
-golden_1_12_regex=[
- '^From: ',
- '^To: buildbot@example.com$',
- '^Reply-To: noreply@example.com$',
- '^Subject: cvs update for project test$',
- '^Date: ',
- '^X-Mailer: Python buildbot-cvs-mail',
- '^$',
- '^Cvsmode: 1.12$',
- '^Category: None$',
- '^CVSROOT: \"ext:example.com:/cvsroot\"$',
- '^Files: README 1.1 1.2 hello.c 2.2 2.3$',
- '^Path: test$',
- '^Project: test$',
- '^$',
- '^Update of /cvsroot/test$',
- '^In directory example:/tmp/cvs-serv21085$',
- '^$',
- '^Modified Files:$',
- 'README hello.c$',
- '^Log Message:$',
- 'two files checkin',
- '^$',
- '^$' ]
-
-class _SubprocessProtocol(protocol.ProcessProtocol):
- def __init__(self, input, deferred):
- self.input = input
- self.deferred = deferred
- self.output = ''
-
- def outReceived(self, s):
- self.output += s
- errReceived = outReceived
-
- def connectionMade(self):
- # push the input and send EOF
- self.transport.write(self.input)
- self.transport.closeStdin()
-
- def processEnded(self, reason):
- self.deferred.callback((self.output, reason.value.exitCode))
-
-def getProcessOutputAndValueWithInput(executable, args, input):
- "similar to getProcessOutputAndValue, but also allows injection of input on stdin"
- d = defer.Deferred()
- p = _SubprocessProtocol(input, d)
- reactor.spawnProcess(p, executable, (executable,) + tuple(args))
- return d
-
-class TestBuildbotCvsMail(unittest.TestCase):
- buildbot_cvs_mail_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../contrib/buildbot_cvs_mail.py'))
- if not os.path.exists(buildbot_cvs_mail_path):
- skip = ("'%s' does not exist (normal unless run from git)"
- % buildbot_cvs_mail_path)
-
- def assertOutputOk(self, (output, code), regexList):
- "assert that the output from getProcessOutputAndValueWithInput matches expectations"
- try:
- self.failUnlessEqual(code, 0, "subprocess exited uncleanly")
- lines = output.splitlines()
- self.failUnlessEqual(len(lines), len(regexList),
- "got wrong number of lines of output")
-
- misses = []
- for line, regex in zip(lines, regexList):
- m = re.search(regex, line)
- if not m:
- misses.append((regex,line))
- self.assertEqual(misses, [], "got non-matching lines")
- except:
- log.msg("got output:\n" + output)
- raise
-
- def test_buildbot_cvs_mail_from_cvs1_11(self):
- # Simulate CVS 1.11
- d = getProcessOutputAndValueWithInput(sys.executable,
- [ self.buildbot_cvs_mail_path, '--cvsroot=\"ext:example:/cvsroot\"',
- '--email=buildbot@example.com', '-P', 'test', '-R', 'noreply@example.com', '-t',
- 'test', 'README', '1.1,1.2', 'hello.c', '2.2,2.3' ],
- input=test)
- d.addCallback(self.assertOutputOk, golden_1_11_regex)
- return d
-
- def test_buildbot_cvs_mail_from_cvs1_12(self):
- # Simulate CVS 1.12, with --path option
- d = getProcessOutputAndValueWithInput(sys.executable,
- [ self.buildbot_cvs_mail_path, '--cvsroot=\"ext:example.com:/cvsroot\"',
- '--email=buildbot@example.com', '-P', 'test', '--path', 'test',
- '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3' ],
- input=test)
- d.addCallback(self.assertOutputOk, golden_1_12_regex)
- return d
-
- def test_buildbot_cvs_mail_no_args_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path ])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
-
- def test_buildbot_cvs_mail_without_email_opt_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path,
- '--cvsroot=\"ext:example.com:/cvsroot\"',
- '-P', 'test', '--path', 'test',
- '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3'])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
-
- def test_buildbot_cvs_mail_without_cvsroot_opt_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path,
- '--complete-garbage-opt=gomi',
- '--cvsroot=\"ext:example.com:/cvsroot\"',
- '--email=buildbot@example.com','-P', 'test', '--path',
- 'test', '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3'])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
-
- def test_buildbot_cvs_mail_with_unknown_opt_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path,
- '--email=buildbot@example.com','-P', 'test', '--path',
- 'test', '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3'])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py
deleted file mode 100644
index 24c8492c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-import mock
-from buildbot.db import base
-from twisted.trial import unittest
-from twisted.internet import defer
-
-class TestBase(unittest.TestCase):
-
- def setUp(self):
- meta = sa.MetaData()
- self.tbl = sa.Table('tbl', meta,
- sa.Column('str32', sa.String(length=32)),
- sa.Column('txt', sa.Text))
- self.db = mock.Mock()
- self.db.pool.engine.dialect.name = 'mysql'
- self.comp = base.DBConnectorComponent(self.db)
-
- def test_check_length_ok(self):
- self.comp.check_length(self.tbl.c.str32, "short string")
-
- def test_check_length_long(self):
- self.assertRaises(RuntimeError, lambda :
- self.comp.check_length(self.tbl.c.str32, "long string" * 5))
-
- def test_check_length_text(self):
- self.assertRaises(AssertionError, lambda :
- self.comp.check_length(self.tbl.c.txt, "long string" * 5))
-
- def test_check_length_long_not_mysql(self):
- self.db.pool.engine.dialect.name = 'sqlite'
- self.comp.check_length(self.tbl.c.str32, "long string" * 5)
- # run that again since the method gets stubbed out
- self.comp.check_length(self.tbl.c.str32, "long string" * 5)
-
-class TestCachedDecorator(unittest.TestCase):
-
- def setUp(self):
- # set this to True to check that cache.get isn't called (for
- # no_cache=1)
- self.cache_get_raises_exception = False
-
- class TestConnectorComponent(base.DBConnectorComponent):
- invocations = None
- @base.cached("mycache")
- def getThing(self, key):
- if self.invocations is None:
- self.invocations = []
- self.invocations.append(key)
- return defer.succeed(key * 2)
-
- def get_cache(self, cache_name, miss_fn):
- self.assertEqual(cache_name, "mycache")
- cache = mock.Mock(name="mycache")
- if self.cache_get_raises_exception:
- def ex(key):
- raise RuntimeError("cache.get called unexpectedly")
- cache.get = ex
- else:
- cache.get = miss_fn
- return cache
-
- # tests
-
- @defer.inlineCallbacks
- def test_cached(self):
- # attach it to the connector
- connector = mock.Mock(name="connector")
- connector.master.caches.get_cache = self.get_cache
-
- # build an instance
- comp = self.TestConnectorComponent(connector)
-
- # test it twice (to test an implementation detail)
- res1 = yield comp.getThing("foo")
-
- res2 = yield comp.getThing("bar")
-
- self.assertEqual((res1, res2, comp.invocations),
- ('foofoo', 'barbar', ['foo', 'bar']))
-
- @defer.inlineCallbacks
- def test_cached_no_cache(self):
- # attach it to the connector
- connector = mock.Mock(name="connector")
- connector.master.caches.get_cache = self.get_cache
- self.cache_get_raises_exception = True
-
- # build an instance
- comp = self.TestConnectorComponent(connector)
-
- yield comp.getThing("foo", no_cache=1)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py
deleted file mode 100644
index a4b1c001..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py
+++ /dev/null
@@ -1,729 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import datetime
-import sqlalchemy as sa
-from twisted.trial import unittest
-from twisted.internet import task, defer
-from buildbot.db import buildrequests
-from buildbot.test.util import connector_component, db
-from buildbot.test.fake import fakedb
-from buildbot.util import UTC, epoch2datetime
-
-class TestBuildsetsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- # test that the datetime translations are done correctly by specifying
- # the epoch timestamp and datetime objects explicitly. These should
- # pass regardless of the local timezone used while running tests!
- CLAIMED_AT = datetime.datetime(1978, 6, 15, 12, 31, 15, tzinfo=UTC)
- CLAIMED_AT_EPOCH = 266761875
- SUBMITTED_AT = datetime.datetime(1979, 6, 15, 12, 31, 15, tzinfo=UTC)
- SUBMITTED_AT_EPOCH = 298297875
- COMPLETE_AT = datetime.datetime(1980, 6, 15, 12, 31, 15, tzinfo=UTC)
- COMPLETE_AT_EPOCH = 329920275
- BSID = 567
- BSID2 = 5670
- MASTER_ID = "set in setUp"
- OTHER_MASTER_ID = "set in setUp"
-
- MASTER_NAME = "testmaster"
- MASTER_INCARN = "pid123-boot456789"
-
- def setUp(self):
- self.MASTER_ID = fakedb.FakeBuildRequestsComponent.MASTER_ID
- self.OTHER_MASTER_ID = self.MASTER_ID + 1111
- d = self.setUpConnectorComponent(
- table_names=[ 'patches', 'changes', 'sourcestamp_changes',
- 'buildsets', 'buildset_properties', 'buildrequests',
- 'objects', 'buildrequest_claims', 'sourcestamps', 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.buildrequests = \
- buildrequests.BuildRequestsConnectorComponent(self.db)
- self.db.master.getObjectId = lambda : defer.succeed(self.MASTER_ID)
- d.addCallback(finish_setup)
-
- # set up a sourcestamp and buildset for use below
- d.addCallback(lambda _ :
- self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- fakedb.Object(id=self.MASTER_ID, name="fake master",
- class_name="BuildMaster"),
- fakedb.Object(id=self.OTHER_MASTER_ID, name="other master",
- class_name="BuildMaster"),
- fakedb.Buildset(id=self.BSID, sourcestampsetid=234),
- ]))
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
-
- def test_getBuildRequest(self):
- # ned fakedb.BuildRequestClaim
- d = self.insertTestData([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=75, priority=7,
- submitted_at=self.SUBMITTED_AT_EPOCH,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(
- brid=44, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequest(44))
- def check(brdict):
- self.assertEqual(brdict,
- dict(brid=44, buildsetid=self.BSID, buildername="bbb",
- priority=7, claimed=True, mine=True, complete=True,
- results=75, claimed_at=self.CLAIMED_AT,
- submitted_at=self.SUBMITTED_AT,
- complete_at=self.COMPLETE_AT))
- d.addCallback(check)
- return d
-
- def test_getBuildRequest_missing(self):
- d = self.db.buildrequests.getBuildRequest(44)
- def check(brdict):
- self.assertEqual(brdict, None)
- d.addCallback(check)
- return d
-
- def do_test_getBuildRequests_claim_args(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- # 50: claimed by this master
- fakedb.BuildRequest(id=50, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=50, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 51: claimed by another master
- fakedb.BuildRequest(id=51, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=51, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 52: unclaimed
- fakedb.BuildRequest(id=52, buildsetid=self.BSID),
-
- # 53: unclaimed but complete (should not appear for claimed=False)
- fakedb.BuildRequest(id=53, buildsetid=self.BSID, complete=1),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_no_claimed_arg(self):
- return self.do_test_getBuildRequests_claim_args(
- expected=[50, 51, 52, 53])
-
- def test_getBuildRequests_claimed_mine(self):
- return self.do_test_getBuildRequests_claim_args(
- claimed="mine",
- expected=[50])
-
- def test_getBuildRequests_claimed_true(self):
- return self.do_test_getBuildRequests_claim_args(
- claimed=True,
- expected=[50, 51])
-
- def test_getBuildRequests_unclaimed(self):
- return self.do_test_getBuildRequests_claim_args(
- claimed=False,
- expected=[52])
-
- def do_test_getBuildRequests_buildername_arg(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- # 8: 'bb'
- fakedb.BuildRequest(id=8, buildsetid=self.BSID, buildername='bb'),
- # 9: 'cc'
- fakedb.BuildRequest(id=9, buildsetid=self.BSID, buildername='cc'),
- # 10: 'cc'
- fakedb.BuildRequest(id=10, buildsetid=self.BSID, buildername='cc'),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_buildername_single(self):
- return self.do_test_getBuildRequests_buildername_arg(
- buildername='bb',
- expected=[8])
-
- def test_getBuildRequests_buildername_multiple(self):
- return self.do_test_getBuildRequests_buildername_arg(
- buildername='cc',
- expected=[9,10])
-
- def test_getBuildRequests_buildername_none(self):
- return self.do_test_getBuildRequests_buildername_arg(
- buildername='dd',
- expected=[])
-
- def do_test_getBuildRequests_complete_arg(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- # 70: incomplete
- fakedb.BuildRequest(id=70, buildsetid=self.BSID,
- complete=0, complete_at=None),
- # 80: complete
- fakedb.BuildRequest(id=80, buildsetid=self.BSID,
- complete=1,
- complete_at=self.COMPLETE_AT_EPOCH),
- # 81: complete but no complete_at
- fakedb.BuildRequest(id=81, buildsetid=self.BSID,
- complete=1, complete_at=0),
- # 82: complete_at set but complete is false, so not complete
- fakedb.BuildRequest(id=82, buildsetid=self.BSID,
- complete=0,
- complete_at=self.COMPLETE_AT_EPOCH),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_complete_none(self):
- return self.do_test_getBuildRequests_complete_arg(
- expected=[ 70, 80, 81, 82])
-
- def test_getBuildRequests_complete_true(self):
- return self.do_test_getBuildRequests_complete_arg(
- complete=True,
- expected=[ 80, 81 ])
-
- def test_getBuildRequests_complete_false(self):
- return self.do_test_getBuildRequests_complete_arg(
- complete=False,
- expected=[ 70, 82 ])
-
- def test_getBuildRequests_bsid_arg(self):
- d = self.insertTestData([
- # the buildset that we are *not* looking for
- fakedb.Buildset(id=self.BSID+1, sourcestampsetid=234),
-
- fakedb.BuildRequest(id=70, buildsetid=self.BSID,
- complete=0, complete_at=None),
- fakedb.BuildRequest(id=71, buildsetid=self.BSID+1,
- complete=0, complete_at=None),
- fakedb.BuildRequest(id=72, buildsetid=self.BSID,
- complete=0, complete_at=None),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(bsid=self.BSID))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted([70, 72]))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_combo(self):
- d = self.insertTestData([
- # 44: everything we want
- fakedb.BuildRequest(id=44, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 45: different buildername
- fakedb.BuildRequest(id=45, buildsetid=self.BSID, buildername="ccc",
- complete=1,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=45, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 46: incomplete
- fakedb.BuildRequest(id=46, buildsetid=self.BSID, buildername="bbb",
- complete=0, results=92,
- complete_at=0),
- fakedb.BuildRequestClaim(brid=46, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 47: unclaimed
- fakedb.BuildRequest(id=47, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
-
- # 48: claimed by other
- fakedb.BuildRequest(id=48, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=48, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 49: different bsid
- fakedb.Buildset(id=self.BSID+1, sourcestampsetid=234),
- fakedb.BuildRequest(id=49, buildsetid=self.BSID+1,
- buildername="bbb", complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=49, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(buildername="bbb",
- claimed="mine", complete=True, bsid=self.BSID))
- def check(brlist):
- self.assertEqual([ br['brid'] for br in brlist ], [ 44 ])
- d.addCallback(check)
- return d
-
- def do_test_getBuildRequests_branch_arg(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- fakedb.BuildRequest(id=70, buildsetid=self.BSID+1),
- fakedb.Buildset(id=self.BSID+1, sourcestampsetid=self.BSID+1),
- fakedb.SourceStampSet(id=self.BSID+1),
- fakedb.SourceStamp(sourcestampsetid=self.BSID+1,
- branch='branch_A'),
-
- fakedb.BuildRequest(id=80, buildsetid=self.BSID+2),
- fakedb.Buildset(id=self.BSID+2, sourcestampsetid=self.BSID+2),
- fakedb.SourceStampSet(id=self.BSID+2),
- fakedb.SourceStamp(sourcestampsetid=self.BSID+2,
- repository='repository_A'),
-
- fakedb.BuildRequest(id=90, buildsetid=self.BSID+3),
- fakedb.Buildset(id=self.BSID+3, sourcestampsetid=self.BSID+3),
- fakedb.SourceStampSet(id=self.BSID+3),
- fakedb.SourceStamp(sourcestampsetid=self.BSID+3,
- branch='branch_A', repository='repository_A'),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_branch(self):
- return self.do_test_getBuildRequests_branch_arg(branch='branch_A',
- expected=[70, 90])
-
- def test_getBuildRequests_branch_empty(self):
- return self.do_test_getBuildRequests_branch_arg(branch='absent_branch',
- expected=[])
-
- def test_getBuildRequests_repository(self):
- return self.do_test_getBuildRequests_branch_arg(
- repository='repository_A', expected=[80, 90])
-
- def test_getBuildRequests_repository_empty(self):
- return self.do_test_getBuildRequests_branch_arg(
- repository='absent_repository', expected=[])
-
- def test_getBuildRequests_repository_and_branch(self):
- return self.do_test_getBuildRequests_branch_arg(
- repository='repository_A', branch='branch_A', expected=[90])
-
- def test_getBuildRequests_no_repository_nor_branch(self):
- return self.do_test_getBuildRequests_branch_arg(expected=[70, 80, 90])
-
- def do_test_claimBuildRequests(self, rows, now, brids, expected=None,
- expfailure=None, claimed_at=None):
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildrequests.claimBuildRequests(brids=brids,
- claimed_at=claimed_at, _reactor=clock))
- def check(brlist):
- self.assertNotEqual(expected, None,
- "unexpected success from claimBuildRequests")
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- q = sa.select([ reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid) ])
- results = conn.execute(q).fetchall()
- self.assertEqual(
- sorted([ (r.id, r.claimed_at, r.objectid)
- for r in results ]),
- sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- def fail(f):
- if not expfailure:
- raise f
- f.trap(expfailure)
- d.addErrback(fail)
- return d
-
- def test_claimBuildRequests_single(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- ], 1300305712, [ 44 ],
- [ (44, 1300305712, self.MASTER_ID) ])
-
- def test_claimBuildRequests_single_explicit_claimed_at(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- ], 1300305712, [ 44 ],
- [ (44, 14000000, self.MASTER_ID) ],
- claimed_at=epoch2datetime(14000000))
-
- def test_claimBuildRequests_multiple(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- fakedb.BuildRequest(id=46, buildsetid=self.BSID),
- ], 1300305712, [ 44, 46 ],
- [
- (44, 1300305712, self.MASTER_ID),
- (45, None, None),
- (46, 1300305712, self.MASTER_ID),
- ])
-
- def test_claimBuildRequests_stress(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=id, buildsetid=self.BSID)
- for id in xrange(1, 1000)
- ], 1300305713, range(1, 1000),
- [
- (id, 1300305713, self.MASTER_ID)
- for id in xrange(1, 1000)
- ])
-
- def test_claimBuildRequests_other_master_claim(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44,
- objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712, [ 44 ],
- expfailure=buildrequests.AlreadyClaimedError)
-
- @db.skip_for_dialect('mysql')
- def test_claimBuildRequests_other_master_claim_stress(self):
- d = self.do_test_claimBuildRequests(
- [ fakedb.BuildRequest(id=id, buildsetid=self.BSID)
- for id in range(1, 1000) ] +
- [
- fakedb.BuildRequest(id=1000, buildsetid=self.BSID),
- # the fly in the ointment..
- fakedb.BuildRequestClaim(brid=1000,
- objectid=self.OTHER_MASTER_ID, claimed_at=1300103810),
- ], 1300305712, range(1, 1001),
- expfailure=buildrequests.AlreadyClaimedError)
- def check(_):
- # check that [1,1000) were not claimed, and 1000 is still claimed
- def thd(conn):
- tbl = self.db.model.buildrequest_claims
- q = tbl.select()
- results = conn.execute(q).fetchall()
- self.assertEqual([ (r.brid, r.objectid, r.claimed_at)
- for r in results ][:10],
- [ (1000, self.OTHER_MASTER_ID, 1300103810) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_claimBuildRequests_sequential(self):
- now = 120350934
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.claimBuildRequests(brids=[44],
- _reactor=clock))
- d.addCallback(lambda _ :
- self.db.buildrequests.claimBuildRequests(brids=[45],
- _reactor=clock))
- def check(brlist):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- join = reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid)
- q = join.select(claims_tbl.c.claimed_at == None)
- results = conn.execute(q).fetchall()
- self.assertEqual(results, [])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def do_test_reclaimBuildRequests(self, rows, now, brids, expected=None,
- expfailure=None):
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildrequests.reclaimBuildRequests(brids=brids,
- _reactor=clock))
- def check(brlist):
- self.assertNotEqual(expected, None,
- "unexpected success from claimBuildRequests")
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- q = sa.select([ reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid) ])
- results = conn.execute(q).fetchall()
- self.assertEqual(
- sorted([ (r.id, r.claimed_at, r.objectid)
- for r in results ]),
- sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- def fail(f):
- if not expfailure:
- raise f
- f.trap(expfailure)
- d.addErrback(fail)
- return d
-
- def test_reclaimBuildRequests(self):
- return self.do_test_reclaimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712, [ 44 ],
- # note that the time is updated
- [ (44, 1300305712, self.MASTER_ID) ])
-
- def test_reclaimBuildRequests_fail(self):
- d = self.do_test_reclaimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=45, objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712, [ 44, 45 ],
- expfailure=buildrequests.AlreadyClaimedError)
- def check(_):
- # check that the time wasn't updated on 44, noting that MySQL does
- # not support this.
- if self.db_engine.dialect.name == 'mysql':
- return
- def thd(conn):
- tbl = self.db.model.buildrequest_claims
- q = tbl.select(order_by=tbl.c.brid)
- results = conn.execute(q).fetchall()
- self.assertEqual([ (r.brid, r.claimed_at, r.objectid)
- for r in results ], [
- (44, 1300103810, self.MASTER_ID),
- (45, 1300103810, self.OTHER_MASTER_ID),
- ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def do_test_completeBuildRequests(self, rows, now, expected=None,
- expfailure=None, brids=[44],
- complete_at=None):
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildrequests.completeBuildRequests(brids=brids,
- results=7, complete_at=complete_at,
- _reactor=clock))
- def check(brlist):
- self.assertNotEqual(expected, None,
- "unexpected success from completeBuildRequests")
- def thd(conn):
- tbl = self.db.model.buildrequests
- q = sa.select([ tbl.c.id, tbl.c.complete,
- tbl.c.results, tbl.c.complete_at ])
- results = conn.execute(q).fetchall()
- self.assertEqual(sorted(map(tuple, results)), sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- def fail(f):
- if not expfailure:
- raise f
- f.trap(expfailure)
- d.addErrback(fail)
- return d
-
- def test_completeBuildRequests(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712,
- [ (44, 1, 7, 1300305712) ])
-
- def test_completeBuildRequests_explicit_time(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712,
- [ (44, 1, 7, 999999) ],
- complete_at=epoch2datetime(999999))
-
- def test_completeBuildRequests_multiple(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=45, objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103811),
- fakedb.BuildRequest(id=46, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=46, objectid=self.MASTER_ID,
- claimed_at=1300103812),
- ], 1300305712,
- [ (44, 1, 7, 1300305712),
- (45, 0, -1, 0),
- (46, 1, 7, 1300305712),
- ], brids=[44, 46])
-
- def test_completeBuildRequests_stress(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=id, buildsetid=self.BSID)
- for id in range(1, 280)
- ] + [
- fakedb.BuildRequestClaim(brid=id, objectid=self.MASTER_ID,
- claimed_at=1300103810)
- for id in range(1, 280)
- ], 1300305712,
- [ (id, 1, 7, 1300305712)
- for id in range(1, 280)
- ], brids=range(1, 280))
-
- def test_completeBuildRequests_multiple_notmine(self):
- # note that the requests are completed even though they are not mine!
- return self.do_test_completeBuildRequests([
- # two unclaimed requests
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- # and one claimed by another master
- fakedb.BuildRequest(id=46, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=46, objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103812),
- ], 1300305712,
- [ (44, 1, 7, 1300305712),
- (45, 1, 7, 1300305712),
- (46, 1, 7, 1300305712), ],
- brids=[44, 45, 46])
-
- def test_completeBuildRequests_already_completed(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID,
- complete=1, complete_at=1300104190),
- ], 1300305712,
- expfailure=buildrequests.NotClaimedError)
-
- def test_completeBuildRequests_no_such(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- ], 1300305712,
- expfailure=buildrequests.NotClaimedError)
-
- def do_test_unclaimMethod(self, method, expected):
- d = self.insertTestData([
- # 44: a complete build (should not be unclaimed)
- fakedb.BuildRequest(id=44, buildsetid=self.BSID,
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 45: incomplete build belonging to this incarnation
- fakedb.BuildRequest(id=45, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=45, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 46: incomplete build belonging to another master
- fakedb.BuildRequest(id=46, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=46, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 47: unclaimed
- fakedb.BuildRequest(id=47, buildsetid=self.BSID,
- complete=0, complete_at=0),
-
- # 48: claimed by this master, but recently
- fakedb.BuildRequest(id=48, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=48, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH-50),
-
- # 49: incomplete old build belonging to another master
- fakedb.BuildRequest(id=49, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=49, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH - 1000),
- ])
- d.addCallback(lambda _ : method())
- def check(brlist):
- def thd(conn):
- # just select the unclaimed requests
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- join = reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid)
- q = sa.select([ reqs_tbl.c.id ],
- from_obj=[ join ],
- whereclause=claims_tbl.c.claimed_at == None)
- results = conn.execute(q).fetchall()
- self.assertEqual(sorted([ r.id for r in results ]),
- sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_unclaimExpiredRequests(self):
- clock = task.Clock()
- clock.advance(self.CLAIMED_AT_EPOCH)
-
- meth = self.db.buildrequests.unclaimExpiredRequests
- return self.do_test_unclaimMethod(
- lambda : meth(100, _reactor=clock),
- [47, 49])
-
- def test_unclaimBuildRequests(self):
- to_unclaim = [
- 44, # completed -> unclaimed anyway
- 45, # incomplete -> unclaimed
- 46, # from another master -> not unclaimed
- 47, # unclaimed -> still unclaimed
- 48, # claimed -> unclaimed
- 49, # another master -> not unclaimed
- 50 # no such buildrequest -> no error
- ]
- return self.do_test_unclaimMethod(
- lambda : self.db.buildrequests.unclaimBuildRequests(to_unclaim),
- [44, 45, 47, 48])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py
deleted file mode 100644
index 1773e1d1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot.db import builds
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-from buildbot.util import epoch2datetime
-
-class TestBuildsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['builds', 'buildrequests', 'buildsets',
- 'sourcestamps', 'sourcestampsets', 'patches' ])
-
- def finish_setup(_):
- self.db.builds = builds.BuildsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # common sample data
-
- background_data = [
- fakedb.SourceStampSet(id=27),
- fakedb.SourceStamp(id=27, sourcestampsetid=27, revision='abcd'),
- fakedb.Buildset(id=20, sourcestampsetid=27),
- fakedb.Buildset(id=30, sourcestampsetid=27),
- fakedb.BuildRequest(id=41, buildsetid=20, buildername='b1'),
- fakedb.BuildRequest(id=42, buildsetid=30, buildername='b1'),
- ]
-
- # tests
-
- def test_getBuild(self):
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=50, brid=42, number=5, start_time=1304262222),
- ])
- d.addCallback(lambda _ :
- self.db.builds.getBuild(50))
- def check(bdict):
- self.assertEqual(bdict, dict(bid=50, number=5, brid=42,
- start_time=epoch2datetime(1304262222), finish_time=None))
- d.addCallback(check)
- return d
-
- def test_getBuild_missing(self):
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.builds.getBuild(50))
- def check(bdict):
- self.assertEqual(bdict, None)
- d.addCallback(check)
- return d
-
- def test_getBuildsForRequest(self):
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=50, brid=42, number=5, start_time=1304262222),
- fakedb.Build(id=51, brid=41, number=6, start_time=1304262223),
- fakedb.Build(id=52, brid=42, number=7, start_time=1304262224,
- finish_time=1304262235),
- ])
- d.addCallback(lambda _ :
- self.db.builds.getBuildsForRequest(42))
- def check(bdicts):
- self.assertEqual(sorted(bdicts), sorted([
- dict(bid=50, number=5, brid=42,
- start_time=epoch2datetime(1304262222), finish_time=None),
- dict(bid=52, number=7, brid=42,
- start_time=epoch2datetime(1304262224),
- finish_time=epoch2datetime(1304262235)),
- ]))
- d.addCallback(check)
- return d
-
- def test_addBuild(self):
- clock = task.Clock()
- clock.advance(1302222222)
- d = self.insertTestData(self.background_data)
- d.addCallback(lambda _ :
- self.db.builds.addBuild(brid=41, number=119, _reactor=clock))
- def check(_):
- def thd(conn):
- r = conn.execute(self.db.model.builds.select())
- rows = [ (row.brid, row.number, row.start_time,
- row.finish_time) for row in r.fetchall() ]
- self.assertEqual(rows,
- [ (41, 119, 1302222222, None) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_finishBuilds(self):
- clock = task.Clock()
- clock.advance(1305555555)
-
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=50, brid=41, number=5, start_time=1304262222),
- fakedb.Build(id=51, brid=42, number=5, start_time=1304262222),
- fakedb.Build(id=52, brid=42, number=6, start_time=1304262222),
- ])
- d.addCallback(lambda _ :
- self.db.builds.finishBuilds([50,51], _reactor=clock))
- def check(_):
- def thd(conn):
- r = conn.execute(self.db.model.builds.select())
- rows = [ (row.id, row.brid, row.number, row.start_time,
- row.finish_time) for row in r.fetchall() ]
- self.assertEqual(sorted(rows), [
- (50, 41, 5, 1304262222, 1305555555),
- (51, 42, 5, 1304262222, 1305555555),
- (52, 42, 6, 1304262222, None),
- ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_finishBuilds_big(self):
- clock = task.Clock()
- clock.advance(1305555555)
-
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=nn, brid=41, number=nn, start_time=1304262222)
- for nn in xrange(50,200)
- ])
- d.addCallback(lambda _ :
- self.db.builds.finishBuilds(range(50,200), _reactor=clock))
- def check(_):
- def thd(conn):
- r = conn.execute(self.db.model.builds.select())
- rows = [ (row.id, row.brid, row.number, row.start_time,
- row.finish_time) for row in r.fetchall() ]
- self.assertEqual(sorted(rows), [
- (nn, 41, nn, 1304262222, 1305555555)
- for nn in xrange(50,200)
- ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py
deleted file mode 100644
index 714a7ab0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py
+++ /dev/null
@@ -1,430 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import datetime
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot.db import buildsets
-from buildbot.util import json, UTC, epoch2datetime
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestBuildsetsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.now = 9272359
- self.clock = task.Clock()
- self.clock.advance(self.now)
-
- d = self.setUpConnectorComponent(
- table_names=[ 'patches', 'changes', 'sourcestamp_changes',
- 'buildsets', 'buildset_properties', 'objects',
- 'buildrequests', 'sourcestamps', 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.buildsets = buildsets.BuildsetsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- # set up a sourcestamp with id 234 for use below
- d.addCallback(lambda _ :
- self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- ]))
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
-
- def test_addBuildset_simple(self):
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.buildsets.addBuildset(sourcestampsetid=234, reason='because',
- properties={}, builderNames=['bldr'], external_idstring='extid',
- _reactor=self.clock))
- def check((bsid, brids)):
- def thd(conn):
- # we should only have one brid
- self.assertEqual(len(brids), 1)
-
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.external_idstring, row.reason,
- row.sourcestampsetid, row.complete, row.complete_at,
- row.submitted_at, row.results) for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, 'extid', 'because', 234, 0, None, self.now, -1) ])
-
- # and one buildrequests row
- r = conn.execute(self.db.model.buildrequests.select())
-
- rows = [ (row.buildsetid, row.id, row.buildername,
- row.priority, row.complete, row.results,
- row.submitted_at, row.complete_at)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, brids['bldr'], 'bldr', 0, 0,
- -1, self.now, None) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_addBuildset_bigger(self):
- props = dict(prop=(['list'], 'test'))
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.buildsets.addBuildset(sourcestampsetid=234, reason='because',
- properties=props, builderNames=['a', 'b']))
- def check((bsid, brids)):
- def thd(conn):
- self.assertEqual(len(brids), 2)
-
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.external_idstring, row.reason,
- row.sourcestampsetid, row.complete,
- row.complete_at, row.results)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, None, u'because', 234, 0, None, -1) ])
-
- # one property row
- r = conn.execute(self.db.model.buildset_properties.select())
- rows = [ (row.buildsetid, row.property_name, row.property_value)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, 'prop', json.dumps([ ['list'], 'test' ]) ) ])
-
- # and two buildrequests rows (and don't re-check the default columns)
- r = conn.execute(self.db.model.buildrequests.select())
- rows = [ (row.buildsetid, row.id, row.buildername)
- for row in r.fetchall() ]
-
- # we don't know which of the brids is assigned to which
- # buildername, but either one will do
- self.assertEqual(sorted(rows),
- [ ( bsid, brids['a'], 'a'), (bsid, brids['b'], 'b') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def do_test_getBuildsetProperties(self, buildsetid, rows, expected):
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsetProperties(buildsetid))
- def check(props):
- self.assertEqual(props, expected)
- d.addCallback(check)
- return d
-
- def test_getBuildsetProperties_multiple(self):
- return self.do_test_getBuildsetProperties(91, [
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- results=-1, submitted_at=0),
- fakedb.BuildsetProperty(buildsetid=91, property_name='prop1',
- property_value='["one", "fake1"]'),
- fakedb.BuildsetProperty(buildsetid=91, property_name='prop2',
- property_value='["two", "fake2"]'),
- ], dict(prop1=("one", "fake1"), prop2=("two", "fake2")))
-
- def test_getBuildsetProperties_empty(self):
- return self.do_test_getBuildsetProperties(91, [
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- results=-1, submitted_at=0),
- ], dict())
-
- def test_getBuildsetProperties_nosuch(self):
- "returns an empty dict even if no such buildset exists"
- return self.do_test_getBuildsetProperties(91, [], dict())
-
- def test_getBuildset_incomplete_None(self):
- d = self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=None, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn'),
- ])
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildset(91))
- def check(bsdict):
- self.assertEqual(bsdict, dict(external_idstring='extid',
- reason='rsn', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, complete_at=None, results=-1,
- bsid=91))
- d.addCallback(check)
- return d
-
- def test_getBuildset_incomplete_zero(self):
- d = self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=0, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn'),
- ])
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildset(91))
- def check(bsdict):
- self.assertEqual(bsdict, dict(external_idstring='extid',
- reason='rsn', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, complete_at=None, results=-1,
- bsid=91))
- d.addCallback(check)
- return d
-
- def test_getBuildset_complete(self):
- d = self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=1,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn'),
- ])
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildset(91))
- def check(bsdict):
- self.assertEqual(bsdict, dict(external_idstring='extid',
- reason='rsn', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=True,
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- results=-1,
- bsid=91))
- d.addCallback(check)
- return d
-
- def test_getBuildset_nosuch(self):
- d = self.db.buildsets.getBuildset(91)
- def check(bsdict):
- self.assertEqual(bsdict, None)
- d.addCallback(check)
- return d
-
- def insert_test_getBuildsets_data(self):
- return self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- fakedb.Buildset(id=92, sourcestampsetid=234, complete=1,
- complete_at=298297876, results=7, submitted_at=266761876,
- external_idstring='extid', reason='rsn2'),
- ])
-
- def test_getBuildsets_empty(self):
- d = self.db.buildsets.getBuildsets()
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
-
- def test_getBuildsets_all(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsets())
- def check(bsdictlist):
- self.assertEqual(sorted(bsdictlist), sorted([
- dict(external_idstring='extid', reason='rsn1', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, results=-1, bsid=91),
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ]))
- d.addCallback(check)
- return d
-
- def test_getBuildsets_complete(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsets(complete=True))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ])
- d.addCallback(check)
- return d
-
- def test_getBuildsets_incomplete(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsets(complete=False))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn1', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, results=-1, bsid=91),
- ])
- d.addCallback(check)
- return d
-
- def test_completeBuildset(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=91, results=6,
- _reactor=self.clock))
- def check(_):
- def thd(conn):
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.complete, row.complete_at, row.results)
- for row in r.fetchall() ]
- self.assertEqual(sorted(rows), sorted([
- ( 91, 1, self.now, 6),
- ( 92, 1, 298297876, 7) ]))
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_completeBuildset_explicit_complete_at(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=91, results=6,
- complete_at=epoch2datetime(72759)))
- def check(_):
- def thd(conn):
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.complete, row.complete_at, row.results)
- for row in r.fetchall() ]
- self.assertEqual(sorted(rows), sorted([
- ( 91, 1, 72759, 6),
- ( 92, 1, 298297876, 7) ]))
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_completeBuildset_already_completed(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=92, results=6,
- _reactor=self.clock))
- return self.assertFailure(d, KeyError)
-
- def test_completeBuildset_missing(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=93, results=6,
- _reactor=self.clock))
- return self.assertFailure(d, KeyError)
-
- def insert_test_getRecentBuildsets_data(self):
- return self.insertTestData([
- fakedb.SourceStamp(id=91, branch='branch_a', repository='repo_a',
- sourcestampsetid=91),
- fakedb.SourceStampSet(id=91),
-
- fakedb.Buildset(id=91, sourcestampsetid=91, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- fakedb.Buildset(id=92, sourcestampsetid=91, complete=1,
- complete_at=298297876, results=7, submitted_at=266761876,
- external_idstring='extid', reason='rsn2'),
-
- # buildset unrelated to the change
- fakedb.SourceStampSet(id=1),
- fakedb.Buildset(id=93, sourcestampsetid=1, complete=1,
- complete_at=298297877, results=7, submitted_at=266761877,
- external_idstring='extid', reason='rsn2'),
- ])
-
- def test_getRecentBuildsets_all(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(2, branch='branch_a',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn1', sourcestampsetid=91,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, results=-1, bsid=91),
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=91,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_one(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(1, branch='branch_a',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=91,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_zero(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(0, branch='branch_a',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_noBranchMatch(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(2, branch='bad_branch',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_noRepoMatch(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(2, branch='branch_a',
- repository='bad_repo'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py
deleted file mode 100644
index f7427875..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py
+++ /dev/null
@@ -1,522 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-import pprint
-import sqlalchemy as sa
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot.changes.changes import Change
-from buildbot.db import changes
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-from buildbot.util import epoch2datetime
-
-class TestChangesConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'change_files',
- 'change_properties', 'scheduler_changes', 'objects',
- 'sourcestampsets', 'sourcestamps', 'sourcestamp_changes',
- 'patches', 'change_users', 'users'])
-
- def finish_setup(_):
- self.db.changes = changes.ChangesConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # common sample data
-
- change13_rows = [
- fakedb.Change(changeid=13, author="dustin", comments="fix spelling",
- is_dir=0, branch="master", revision="deadbeef",
- when_timestamp=266738400, revlink=None, category=None,
- repository='', codebase='', project=''),
-
- fakedb.ChangeFile(changeid=13, filename='master/README.txt'),
- fakedb.ChangeFile(changeid=13, filename='slave/README.txt'),
-
- fakedb.ChangeProperty(changeid=13, property_name='notest',
- property_value='["no","Change"]'),
- ]
-
- change14_rows = [
- fakedb.Change(changeid=14, author="warner", comments="fix whitespace",
- is_dir=0, branch="warnerdb", revision="0e92a098b",
- when_timestamp=266738404, revlink='http://warner/0e92a098b',
- category='devel', repository='git://warner', codebase='mainapp',
- project='Buildbot'),
-
- fakedb.ChangeFile(changeid=14, filename='master/buildbot/__init__.py'),
- ]
-
- change14_dict = {
- 'changeid': 14,
- 'author': u'warner',
- 'branch': u'warnerdb',
- 'category': u'devel',
- 'comments': u'fix whitespace',
- 'files': [u'master/buildbot/__init__.py'],
- 'is_dir': 0,
- 'project': u'Buildbot',
- 'properties': {},
- 'repository': u'git://warner',
- 'codebase': u'mainapp',
- 'revision': u'0e92a098b',
- 'revlink': u'http://warner/0e92a098b',
- 'when_timestamp': epoch2datetime(266738404),
- }
-
- def change14(self):
- c = Change(**dict(
- category='devel',
- isdir=0,
- repository=u'git://warner',
- codebase=u'mainapp',
- who=u'warner',
- when=266738404,
- comments=u'fix whitespace',
- project=u'Buildbot',
- branch=u'warnerdb',
- revlink=u'http://warner/0e92a098b',
- properties={},
- files=[u'master/buildbot/__init__.py'],
- revision=u'0e92a098b'))
- c.number = 14
- return c
-
- # assertions
-
- def assertChangesEqual(self, ca, cb):
- ok = True
- ok = ok and ca.number == cb.number
- ok = ok and ca.who == cb.who
- ok = ok and sorted(ca.files) == sorted(cb.files)
- ok = ok and ca.comments == cb.comments
- ok = ok and bool(ca.isdir) == bool(cb.isdir)
- ok = ok and ca.revision == cb.revision
- ok = ok and ca.when == cb.when
- ok = ok and ca.branch == cb.branch
- ok = ok and ca.category == cb.category
- ok = ok and ca.revlink == cb.revlink
- ok = ok and ca.properties == cb.properties
- ok = ok and ca.repository == cb.repository
- ok = ok and ca.codebase == cb.codebase
- ok = ok and ca.project == cb.project
- if not ok:
- def printable(c):
- return pprint.pformat(c.__dict__)
- self.fail("changes do not match; expected\n%s\ngot\n%s" %
- (printable(ca), printable(cb)))
-
- # tests
-
- def test_getChange(self):
- d = self.insertTestData(self.change14_rows)
- def get14(_):
- return self.db.changes.getChange(14)
- d.addCallback(get14)
- def check14(chdict):
- self.assertEqual(chdict, self.change14_dict)
- d.addCallback(check14)
- return d
-
- def test_Change_fromChdict_with_chdict(self):
- # test that the chdict getChange returns works with Change.fromChdict
- d = Change.fromChdict(mock.Mock(), self.change14_dict)
- def check(c):
- self.assertChangesEqual(c, self.change14())
- d.addCallback(check)
- return d
-
- def test_getChange_missing(self):
- d = defer.succeed(None)
- def get14(_):
- return self.db.changes.getChange(14)
- d.addCallback(get14)
- def check14(chdict):
- self.failUnless(chdict is None)
- d.addCallback(check14)
- return d
-
- def test_getLatestChangeid(self):
- d = self.insertTestData(self.change13_rows)
- def get(_):
- return self.db.changes.getLatestChangeid()
- d.addCallback(get)
- def check(changeid):
- self.assertEqual(changeid, 13)
- d.addCallback(check)
- return d
-
- def test_getLatestChangeid_empty(self):
- d = defer.succeed(None)
- def get(_):
- return self.db.changes.getLatestChangeid()
- d.addCallback(get)
- def check(changeid):
- self.assertEqual(changeid, None)
- d.addCallback(check)
- return d
-
- def test_addChange(self):
- d = self.db.changes.addChange(
- author=u'dustin',
- files=[u'master/LICENSING.txt', u'slave/LICENSING.txt'],
- comments=u'fix spelling',
- is_dir=0,
- revision=u'2d6caa52',
- when_timestamp=epoch2datetime(266738400),
- branch=u'master',
- category=None,
- revlink=None,
- properties={u'platform': (u'linux', 'Change')},
- repository=u'',
- codebase=u'',
- project=u'')
- # check all of the columns of the four relevant tables
- def check_change(changeid):
- def thd(conn):
- self.assertEqual(changeid, 1)
- r = conn.execute(self.db.model.changes.select())
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, changeid)
- self.assertEqual(r[0].author, 'dustin')
- self.assertEqual(r[0].comments, 'fix spelling')
- self.assertFalse(r[0].is_dir)
- self.assertEqual(r[0].branch, 'master')
- self.assertEqual(r[0].revision, '2d6caa52')
- self.assertEqual(r[0].when_timestamp, 266738400)
- self.assertEqual(r[0].category, None)
- self.assertEqual(r[0].repository, '')
- self.assertEqual(r[0].codebase, '')
- self.assertEqual(r[0].project, '')
- return self.db.pool.do(thd)
- d.addCallback(check_change)
- def check_change_files(_):
- def thd(conn):
- query = self.db.model.change_files.select()
- query.where(self.db.model.change_files.c.changeid == 1)
- query.order_by(self.db.model.change_files.c.filename)
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 2)
- self.assertEqual(r[0].filename, 'master/LICENSING.txt')
- self.assertEqual(r[1].filename, 'slave/LICENSING.txt')
- return self.db.pool.do(thd)
- d.addCallback(check_change_files)
- def check_change_properties(_):
- def thd(conn):
- query = self.db.model.change_properties.select()
- query.where(self.db.model.change_properties.c.changeid == 1)
- query.order_by(self.db.model.change_properties.c.property_name)
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].property_name, 'platform')
- self.assertEqual(r[0].property_value, '["linux", "Change"]')
- return self.db.pool.do(thd)
- d.addCallback(check_change_properties)
- def check_change_users(_):
- def thd(conn):
- query = self.db.model.change_users.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_users)
- return d
-
- def test_addChange_when_timestamp_None(self):
- clock = task.Clock()
- clock.advance(1239898353)
- d = self.db.changes.addChange(
- author=u'dustin',
- files=[],
- comments=u'fix spelling',
- is_dir=0,
- revision=u'2d6caa52',
- when_timestamp=None,
- branch=u'master',
- category=None,
- revlink=None,
- properties={},
- repository=u'',
- codebase=u'',
- project=u'',
- _reactor=clock)
- # check all of the columns of the four relevant tables
- def check_change(changeid):
- def thd(conn):
- r = conn.execute(self.db.model.changes.select())
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, changeid)
- self.assertEqual(r[0].when_timestamp, 1239898353)
- return self.db.pool.do(thd)
- d.addCallback(check_change)
- def check_change_files(_):
- def thd(conn):
- query = self.db.model.change_files.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_files)
- def check_change_properties(_):
- def thd(conn):
- query = self.db.model.change_properties.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_properties)
- def check_change_users(_):
- def thd(conn):
- query = self.db.model.change_users.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_users)
- return d
-
- def test_addChange_with_uid(self):
- d = self.insertTestData([
- fakedb.User(uid=1, identifier="one"),
- ])
- d.addCallback(lambda _ :
- self.db.changes.addChange(
- author=u'dustin',
- files=[],
- comments=u'fix spelling',
- is_dir=0,
- revision=u'2d6caa52',
- when_timestamp=epoch2datetime(1239898353),
- branch=u'master',
- category=None,
- revlink=None,
- properties={},
- repository=u'',
- codebase=u'',
- project=u'',
- uid=1))
- # check all of the columns of the five relevant tables
- def check_change(changeid):
- def thd(conn):
- r = conn.execute(self.db.model.changes.select())
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, changeid)
- self.assertEqual(r[0].when_timestamp, 1239898353)
- return self.db.pool.do(thd)
- d.addCallback(check_change)
- def check_change_files(_):
- def thd(conn):
- query = self.db.model.change_files.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_files)
- def check_change_properties(_):
- def thd(conn):
- query = self.db.model.change_properties.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_properties)
- def check_change_users(_):
- def thd(conn):
- query = self.db.model.change_users.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, 1)
- self.assertEqual(r[0].uid, 1)
- return self.db.pool.do(thd)
- d.addCallback(check_change_users)
- return d
-
- def test_getChangeUids_missing(self):
- d = self.db.changes.getChangeUids(1)
- def check(res):
- self.assertEqual(res, [])
- d.addCallback(check)
- return d
-
- def test_getChangeUids_found(self):
- d = self.insertTestData(self.change14_rows + [
- fakedb.User(uid=1),
- fakedb.ChangeUser(changeid=14, uid=1),
- ])
- d.addCallback(lambda _ : self.db.changes.getChangeUids(14))
- def check(res):
- self.assertEqual(res, [1])
- d.addCallback(check)
- return d
-
- def test_getChangeUids_multi(self):
- d = self.insertTestData(self.change14_rows + self.change13_rows + [
- fakedb.User(uid=1, identifier="one"),
- fakedb.User(uid=2, identifier="two"),
- fakedb.User(uid=99, identifier="nooo"),
- fakedb.ChangeUser(changeid=14, uid=1),
- fakedb.ChangeUser(changeid=14, uid=2),
- fakedb.ChangeUser(changeid=13, uid=99), # not selected
- ])
- d.addCallback(lambda _ : self.db.changes.getChangeUids(14))
- def check(res):
- self.assertEqual(sorted(res), [1, 2])
- d.addCallback(check)
- return d
-
- def test_pruneChanges(self):
- d = self.insertTestData([
- fakedb.Object(id=29),
- fakedb.SourceStamp(id=234),
-
- fakedb.Change(changeid=11),
-
- fakedb.Change(changeid=12),
- fakedb.SchedulerChange(objectid=29, changeid=12),
- fakedb.SourceStampChange(sourcestampid=234, changeid=12),
- ] +
-
- self.change13_rows + [
- fakedb.SchedulerChange(objectid=29, changeid=13),
- ] +
-
- self.change14_rows + [
- fakedb.SchedulerChange(objectid=29, changeid=14),
-
- fakedb.Change(changeid=15),
- fakedb.SourceStampChange(sourcestampid=234, changeid=15),
- ]
- )
-
- # pruning with a horizon of 2 should delete changes 11, 12 and 13
- d.addCallback(lambda _ : self.db.changes.pruneChanges(2))
- def check(_):
- def thd(conn):
- results = {}
- for tbl_name in ('scheduler_changes', 'sourcestamp_changes',
- 'change_files', 'change_properties',
- 'changes'):
- tbl = self.db.model.metadata.tables[tbl_name]
- r = conn.execute(sa.select([tbl.c.changeid]))
- results[tbl_name] = sorted([ r[0] for r in r.fetchall() ])
- self.assertEqual(results, {
- 'scheduler_changes': [14],
- 'sourcestamp_changes': [15],
- 'change_files': [14],
- 'change_properties': [],
- 'changes': [14, 15],
- })
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_pruneChanges_lots(self):
- d = self.insertTestData([
- fakedb.Change(changeid=n)
- for n in xrange(1, 151)
- ])
-
- d.addCallback(lambda _ : self.db.changes.pruneChanges(1))
- def check(_):
- def thd(conn):
- results = {}
- for tbl_name in ('scheduler_changes', 'sourcestamp_changes',
- 'change_files', 'change_properties',
- 'changes'):
- tbl = self.db.model.metadata.tables[tbl_name]
- r = conn.execute(sa.select([tbl.c.changeid]))
- results[tbl_name] = len([ r for r in r.fetchall() ])
- self.assertEqual(results, {
- 'scheduler_changes': 0,
- 'sourcestamp_changes': 0,
- 'change_files': 0,
- 'change_properties': 0,
- 'changes': 1,
- })
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_pruneChanges_None(self):
- d = self.insertTestData(self.change13_rows)
-
- d.addCallback(lambda _ : self.db.changes.pruneChanges(None))
- def check(_):
- def thd(conn):
- tbl = self.db.model.changes
- r = conn.execute(tbl.select())
- self.assertEqual([ row.changeid for row in r.fetchall() ],
- [ 13 ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getRecentChanges_subset(self):
- d = self.insertTestData([
- fakedb.Change(changeid=8),
- fakedb.Change(changeid=9),
- fakedb.Change(changeid=10),
- fakedb.Change(changeid=11),
- fakedb.Change(changeid=12),
- ] + self.change13_rows + self.change14_rows)
- d.addCallback(lambda _ :
- self.db.changes.getRecentChanges(5))
- def check(changes):
- changeids = [ c['changeid'] for c in changes ]
- self.assertEqual(changeids, [10, 11, 12, 13, 14])
- d.addCallback(check)
- return d
-
- def test_getRecentChanges_empty(self):
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.changes.getRecentChanges(5))
- def check(changes):
- changeids = [ c['changeid'] for c in changes ]
- self.assertEqual(changeids, [])
- d.addCallback(check)
- return d
-
- def test_getRecentChanges_missing(self):
- d = self.insertTestData(self.change13_rows + self.change14_rows)
- d.addCallback(lambda _ :
- self.db.changes.getRecentChanges(5))
- def check(changes):
- # requested 5, but only got 2
- changeids = [ c['changeid'] for c in changes ]
- self.assertEqual(changeids, [13, 14])
- # double-check that they have .files, etc.
- self.assertEqual(sorted(changes[0]['files']),
- sorted(['master/README.txt', 'slave/README.txt']))
- self.assertEqual(changes[0]['properties'],
- { 'notest' : ('no', 'Change') })
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py
deleted file mode 100644
index 3c3083cd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-from twisted.internet import defer
-from twisted.trial import unittest
-from buildbot.db import connector
-from buildbot import config
-from buildbot.test.util import db
-from buildbot.test.fake import fakemaster
-
-class DBConnector(db.RealDatabaseMixin, unittest.TestCase):
- """
- Basic tests of the DBConnector class - all start with an empty DB
- """
-
- @defer.inlineCallbacks
- def setUp(self):
- yield self.setUpRealDatabase(table_names=[
- 'changes', 'change_properties', 'change_files', 'patches',
- 'sourcestamps', 'buildset_properties', 'buildsets',
- 'sourcestampsets' ])
-
- self.master = fakemaster.make_master()
- self.master.config = config.MasterConfig()
- self.db = connector.DBConnector(self.master,
- os.path.abspath('basedir'))
-
- @defer.inlineCallbacks
- def tearDown(self):
- if self.db.running:
- yield self.db.stopService()
-
- yield self.tearDownRealDatabase()
-
- @defer.inlineCallbacks
- def startService(self, check_version=False):
- self.master.config.db['db_url'] = self.db_url
- yield self.db.setup(check_version=check_version)
- self.db.startService()
- yield self.db.reconfigService(self.master.config)
-
-
- # tests
-
- def test_doCleanup_service(self):
- d = self.startService()
- @d.addCallback
- def check(_):
- self.assertTrue(self.db.cleanup_timer.running)
-
- def test_doCleanup_unconfigured(self):
- self.db.changes.pruneChanges = mock.Mock(
- return_value=defer.succeed(None))
- self.db._doCleanup()
- self.assertFalse(self.db.changes.pruneChanges.called)
-
- def test_doCleanup_configured(self):
- self.db.changes.pruneChanges = mock.Mock(
- return_value=defer.succeed(None))
- d = self.startService()
- @d.addCallback
- def check(_):
- self.db._doCleanup()
- self.assertTrue(self.db.changes.pruneChanges.called)
- return d
-
- def test_setup_check_version_bad(self):
- d = self.startService(check_version=True)
- return self.assertFailure(d, connector.DatabaseNotReadyError)
-
- def test_setup_check_version_good(self):
- self.db.model.is_current = lambda : defer.succeed(True)
- return self.startService(check_version=True)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py
deleted file mode 100644
index d9693979..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.python import runtime
-from sqlalchemy.engine import url
-from sqlalchemy.pool import NullPool
-from buildbot.db import enginestrategy
-
-class BuildbotEngineStrategy_special_cases(unittest.TestCase):
- "Test the special case methods, without actually creating a db"
-
- # used several times below
- mysql_kwargs = dict(basedir='my-base-dir',
- connect_args=dict(init_command='SET storage_engine=MyISAM'),
- pool_recycle=3600)
- sqlite_kwargs = dict(basedir='/my-base-dir', poolclass=NullPool)
-
- def setUp(self):
- self.strat = enginestrategy.BuildbotEngineStrategy()
-
- # utility
-
- def filter_kwargs(self, kwargs):
- # filter out the listeners list to just include the class name
- if 'listeners' in kwargs:
- kwargs['listeners'] = [ lstnr.__class__.__name__
- for lstnr in kwargs['listeners'] ]
- return kwargs
-
- # tests
-
- def test_sqlite_pct_sub(self):
- u = url.make_url("sqlite:///%(basedir)s/x/state.sqlite")
- kwargs = dict(basedir='/my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "sqlite:////my-base-dir/x/state.sqlite", None,
- self.sqlite_kwargs ])
-
- def test_sqlite_relpath(self):
- url_src = "sqlite:///x/state.sqlite"
- basedir = "/my-base-dir"
- expected_url = "sqlite:////my-base-dir/x/state.sqlite"
-
- # this looks a whole lot different on windows
- if runtime.platformType == 'win32':
- url_src = r'sqlite:///X\STATE.SQLITE'
- basedir = r'C:\MYBASE~1'
- expected_url = r'sqlite:///C:\MYBASE~1\X\STATE.SQLITE'
-
- exp_kwargs = self.sqlite_kwargs.copy()
- exp_kwargs['basedir'] = basedir
-
- u = url.make_url(url_src)
- kwargs = dict(basedir=basedir)
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ expected_url, None, exp_kwargs ])
-
- def test_sqlite_abspath(self):
- u = url.make_url("sqlite:////x/state.sqlite")
- kwargs = dict(basedir='/my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "sqlite:////x/state.sqlite", None, self.sqlite_kwargs ])
-
- def test_sqlite_memory(self):
- u = url.make_url("sqlite://")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "sqlite://", 1, # only one conn at a time
- dict(basedir='my-base-dir',
- # note: no poolclass= argument
- pool_size=1) ]) # extra in-memory args
-
- def test_mysql_simple(self):
- u = url.make_url("mysql://host/dbname")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql://host/dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_userport(self):
- u = url.make_url("mysql://user:pass@host:1234/dbname")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql://user:pass@host:1234/dbname?"
- "charset=utf8&use_unicode=True", None, self.mysql_kwargs ])
-
- def test_mysql_local(self):
- u = url.make_url("mysql:///dbname")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_args(self):
- u = url.make_url("mysql:///dbname?foo=bar")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&foo=bar&use_unicode=True",
- None, self.mysql_kwargs ])
-
- def test_mysql_max_idle(self):
- u = url.make_url("mysql:///dbname?max_idle=1234")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- exp = self.mysql_kwargs.copy()
- exp['pool_recycle'] = 1234
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- exp ])
-
- def test_mysql_good_charset(self):
- u = url.make_url("mysql:///dbname?charset=utf8")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_bad_charset(self):
- u = url.make_url("mysql:///dbname?charset=ebcdic")
- kwargs = dict(basedir='my-base-dir')
- self.assertRaises(TypeError,
- lambda : self.strat.special_case_mysql(u, kwargs))
-
- def test_mysql_good_use_unicode(self):
- u = url.make_url("mysql:///dbname?use_unicode=True")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_bad_use_unicode(self):
- u = url.make_url("mysql:///dbname?use_unicode=maybe")
- kwargs = dict(basedir='my-base-dir')
- self.assertRaises(TypeError,
- lambda : self.strat.special_case_mysql(u, kwargs))
-
- def test_mysql_storage_engine(self):
- u = url.make_url("mysql:///dbname?storage_engine=foo")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- exp = self.mysql_kwargs.copy()
- exp['connect_args'] = dict(init_command='SET storage_engine=foo')
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- exp ])
-
-
-class BuildbotEngineStrategy(unittest.TestCase):
- "Test create_engine by creating a sqlite in-memory db"
-
- def test_create_engine(self):
- engine = enginestrategy.create_engine('sqlite://', basedir="/base")
- self.assertEqual(engine.scalar("SELECT 13 + 14"), 27)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py
deleted file mode 100644
index ea895983..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer,
- nullable=False), # NOTE: foreign key omitted
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
- self.buildsets.create(bind=conn)
-
- self.buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
- nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=256)),
- sa.Column('claimed_by_incarnation', sa.String(length=256)),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
- self.buildrequests.create(bind=conn)
-
- idx = sa.Index('buildrequests_buildsetid',
- self.buildrequests.c.buildsetid)
- idx.create()
-
- idx = sa.Index('buildrequests_buildername',
- self.buildrequests.c.buildername)
- idx.create()
-
- idx = sa.Index('buildrequests_complete',
- self.buildrequests.c.complete)
- idx.create()
-
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
- self.objects.create(bind=conn)
-
- # tests
-
- def test_migrate(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- # regression test for bug #2158; this is known to be broken on
- # sqlite (and fixed in db version 016) but expected to work on
- # other engines.
- if conn.dialect.name != 'sqlite':
- insp = reflection.Inspector.from_engine(conn)
- indexes = insp.get_indexes('buildrequests')
- self.assertEqual(
- sorted([ i['name'] for i in indexes ]),
- sorted([
- 'buildrequests_buildername',
- 'buildrequests_buildsetid',
- 'buildrequests_complete',
- ]))
-
- return self.do_test_migration(10, 11, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py
deleted file mode 100644
index 1ee7be07..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
- self.object_state = sa.Table("object_state", metadata,
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- sa.Column("name", sa.String(length=256), nullable=False),
- sa.Column("value_json", sa.Text, nullable=False),
- sa.UniqueConstraint('objectid', 'name', name='name_per_object'),
- )
- self.objects.create(bind=conn)
- self.object_state.create(bind=conn)
-
- def insert_old_obj(self, conn):
- conn.execute(self.objects.insert(),
- id=21,
- name='master',
- class_name='buildbot.master.BuildMaster')
- conn.execute(self.object_state.insert(),
- objectid=21,
- name='last_processed_change',
- value_json='938')
-
- def insert_new_objs(self, conn, count):
- for id in range(50, 50+count):
- conn.execute(self.objects.insert(),
- id=id,
- name='some_hostname:/base/dir/%d' % id,
- class_name='BuildMaster')
- # (this id would be referenced from buildrequests, but that table
- # doesn't change)
-
- def assertObjectState_thd(self, conn, exp_objects=[],
- exp_object_state=[]):
- tbl = self.objects
- res = conn.execute(tbl.select(order_by=tbl.c.id))
- got_objects = res.fetchall()
-
- tbl = self.object_state
- res = conn.execute(tbl.select(
- order_by=[tbl.c.objectid, tbl.c.name]))
- got_object_state = res.fetchall()
-
- self.assertEqual(
- dict(objects=exp_objects, object_state=exp_object_state),
- dict(objects=got_objects, object_state=got_object_state))
-
- # tests
-
- def test_no_old_id(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_new_objs(conn, 2)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [
- (50, 'some_hostname:/base/dir/50',
- 'buildbot.master.BuildMaster'),
- (51, 'some_hostname:/base/dir/51',
- 'buildbot.master.BuildMaster'),
- ], [])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
- def test_no_new_id(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_old_obj(conn)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [], [])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
- def test_one_new_id(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_old_obj(conn)
- self.insert_new_objs(conn, 1)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [
- (50, 'some_hostname:/base/dir/50',
- 'buildbot.master.BuildMaster'),
- ], [
- (50, 'last_processed_change', '938'),
- ])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
- def test_two_new_ids(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_old_obj(conn)
- self.insert_new_objs(conn, 2)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [
- (50, 'some_hostname:/base/dir/50',
- 'buildbot.master.BuildMaster'),
- (51, 'some_hostname:/base/dir/51',
- 'buildbot.master.BuildMaster'),
- ], [
- # last_processed_change is just deleted
- ])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py
deleted file mode 100644
index 0cb03645..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, # foreign key removed
- nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
- self.buildrequests.create(bind=conn)
-
- # these indices should already exist everywhere but on sqlite
- if conn.dialect.name != 'sqlite':
- idx = sa.Index('buildrequests_buildsetid',
- self.buildrequests.c.buildsetid)
- idx.create()
-
- idx = sa.Index('buildrequests_buildername',
- self.buildrequests.c.buildername)
- idx.create()
-
- idx = sa.Index('buildrequests_complete',
- self.buildrequests.c.complete)
- idx.create()
-
- # tests
-
- def test_migrate(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- insp = reflection.Inspector.from_engine(conn)
- indexes = insp.get_indexes('buildrequests')
- self.assertEqual(
- sorted([ i['name'] for i in indexes ]),
- sorted([
- 'buildrequests_buildername',
- 'buildrequests_buildsetid',
- 'buildrequests_complete',
- ]))
-
-
- return self.do_test_migration(15, 16, setup_thd, verify_thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py
deleted file mode 100644
index e8dcd6b5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
- )
- self.changes.create(bind=conn)
-
- self.schedulers = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.schedulers.create(bind=conn)
-
- self.users = sa.Table("users", metadata,
- sa.Column("uid", sa.Integer, primary_key=True),
- sa.Column("identifier", sa.String(256), nullable=False),
- sa.Column("bb_username", sa.String(128)),
- sa.Column("bb_password", sa.String(128)),
- )
- self.users.create(bind=conn)
-
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.objects.create()
-
- self.object_state = sa.Table("object_state", metadata,
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- sa.Column("name", sa.String(length=256), nullable=False),
- sa.Column("value_json", sa.Text, nullable=False),
- )
- self.object_state.create()
-
- # these indices should already exist everywhere but on sqlite
- if conn.dialect.name != 'sqlite':
- sa.Index('name_and_class', self.schedulers.c.name,
- self.schedulers.c.class_name).create()
- sa.Index('changes_branch', self.changes.c.branch).create()
- sa.Index('changes_revision', self.changes.c.revision).create()
- sa.Index('changes_author', self.changes.c.author).create()
- sa.Index('changes_category', self.changes.c.category).create()
- sa.Index('changes_when_timestamp',
- self.changes.c.when_timestamp).create()
-
- # create this index without the unique attribute
- sa.Index('users_identifier', self.users.c.identifier).create()
-
- # tests
-
- def test_migrate(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- insp = reflection.Inspector.from_engine(conn)
- indexes = (insp.get_indexes('changes')
- + insp.get_indexes('schedulers'))
- self.assertEqual(
- sorted([ i['name'] for i in indexes ]),
- sorted([
- 'changes_author',
- 'changes_branch',
- 'changes_category',
- 'changes_revision',
- 'changes_when_timestamp',
- 'name_and_class',
- ]))
- indexes = insp.get_indexes('users')
- for idx in indexes:
- if idx['name'] == 'users_identifier':
- self.assertTrue(idx['unique'])
- break
- else:
- self.fail("no users_identifier index")
-
- return self.do_test_migration(16, 17, setup_thd, verify_thd)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py
deleted file mode 100644
index 790bf1ac..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-from twisted.python import log
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer,
- nullable=False), # NOTE: foreign key omitted
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
- self.buildsets.create(bind=conn)
- sa.Index('buildsets_complete', self.buildsets.c.complete).create()
- sa.Index('buildsets_submitted_at', self.buildsets.c.submitted_at).create()
-
- self.patches = sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('patchlevel', sa.Integer, nullable=False),
- sa.Column('patch_base64', sa.Text, nullable=False),
- sa.Column('patch_author', sa.Text, nullable=False),
- sa.Column('patch_comment', sa.Text, nullable=False),
- sa.Column('subdir', sa.Text),
- )
- self.patches.create(bind=conn)
-
- self.sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
- sa.Column('repository', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('sourcestampid', sa.Integer, sa.ForeignKey('sourcestamps.id')),
- )
- self.sourcestamps.create(bind=conn)
-
- def fill_tables_with_testdata(self, conn, testdata):
- for bsid, ssid in testdata:
- self.insert_buildset_sourcestamp(conn, bsid, ssid)
-
- def insert_buildset_sourcestamp(self, conn, bsid, sourcestampid):
- conn.execute(self.buildsets.insert(),
- id=bsid,
- externalid_string='',
- reason = 'just',
- sourcestampid=sourcestampid,
- submitted_at=22417200,
- complete = 0,
- complete_at=22417200,
- results=0)
- conn.execute(self.sourcestamps.insert(),
- id=sourcestampid,
- branch='this_branch',
- revision='this_revision',
- patchid = None,
- repository='repo_a',
- project='')
-
- def assertBuildsetSourceStamp_thd(self, conn, exp_buildsets=[],
- exp_sourcestamps=[]):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('buildsets', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid], order_by=tbl.c.id))
- got_buildsets = res.fetchall()
-
- tbl = sa.Table('sourcestamps', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid],
- order_by=[tbl.c.sourcestampsetid, tbl.c.id]))
- got_sourcestamps = res.fetchall()
-
- self.assertEqual(
- dict(buildsets=exp_buildsets, sourcestamps=exp_sourcestamps),
- dict(buildsets=got_buildsets, sourcestamps=got_sourcestamps))
-
- # tests
-
- def thd_assertForeignKeys(self, conn, exp, with_constrained_columns=[]):
- # MySQL does not reflect or use foreign keys, so we can't check..
- if conn.dialect.name == 'mysql':
- return
-
- insp = reflection.Inspector.from_engine(conn)
- fks = orig_fks = insp.get_foreign_keys('buildsets')
-
- # filter out constraints including all of the given columns
- with_constrained_columns = set(with_constrained_columns)
- fks = sorted([ fk
- for fk in fks
- if not with_constrained_columns - set(fk['constrained_columns'])
- ])
-
- # clean up
- for fk in fks:
- del fk['name'] # schema dependent
- del fk['referred_schema'] # idem
-
- # finally, assert
- if fks != exp:
- log.msg("got: %r" % (orig_fks,))
- self.assertEqual(fks, exp)
-
- def test_1_buildsets(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('buildsets', metadata, autoload=True)
- self.assertTrue(hasattr(tbl.c, 'sourcestampsetid'))
-
- self.thd_assertForeignKeys(conn, [ {
- 'constrained_columns':['sourcestampsetid'],
- 'referred_table':'sourcestampsets',
- 'referred_columns':['id']},
- ], with_constrained_columns=['sourcestampsetid'])
-
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid], order_by=tbl.c.id))
- got_buildsets = res.fetchall()
- self.assertEqual(got_buildsets, buildsetdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
-
- def test_2_sourcestamp(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- sourcestampdata = [ (ssid, ssid) for bsid, ssid in buildsetdata ]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('sourcestamps', metadata, autoload=True)
- self.assertTrue(hasattr(tbl.c, 'sourcestampsetid'))
-
- self.thd_assertForeignKeys(conn, [ {
- 'constrained_columns':['sourcestampsetid'],
- 'referred_table':'sourcestampsets',
- 'referred_columns':['id']},
- ], with_constrained_columns=['sourcestampsetid'])
-
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid],
- order_by=[tbl.c.sourcestampsetid, tbl.c.id]))
- got_sourcestamps = res.fetchall()
- self.assertEqual(got_sourcestamps, sourcestampdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
-
- def test_3_sourcestampset(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- sourcestampsetdata = [ (ssid,) for bsid, ssid in buildsetdata ]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('sourcestampsets', metadata, autoload=True)
- self.assertTrue(hasattr(tbl.c, 'id'))
- res = conn.execute(sa.select([tbl.c.id],order_by=[tbl.c.id]))
- got_sourcestampsets = res.fetchall()
- self.assertEqual(got_sourcestampsets, sourcestampsetdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
-
- def test_4_integrated_migration(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- sourcestampdata = [ (ssid, ssid) for bsid, ssid in buildsetdata ]
- sourcestampsetdata = [ (ssid,) for bsid, ssid in buildsetdata ]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- # Test for the buildsets
- tbl = sa.Table('buildsets', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid], order_by=tbl.c.id))
- got_buildsets = res.fetchall()
- self.assertEqual(got_buildsets, buildsetdata)
-
- # Test for the sourcestamps
- tbl = sa.Table('sourcestamps', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid],
- order_by=[tbl.c.sourcestampsetid, tbl.c.id]))
- got_sourcestamps = res.fetchall()
- self.assertEqual(got_sourcestamps, sourcestampdata)
-
- tbl = sa.Table('sourcestampsets', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id],order_by=[tbl.c.id]))
- got_sourcestampsets = res.fetchall()
- self.assertEqual(got_sourcestampsets, sourcestampsetdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py
deleted file mode 100644
index 452fc743..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- # the rest is unimportant
- )
- changes.create()
-
- buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- # the rest is unimportant
- )
- buildsets.create()
-
- self.schedulers = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.schedulers.create(bind=conn)
- sa.Index('name_and_class', self.schedulers.c.name,
- self.schedulers.c.class_name).create()
-
- self.scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer,
- sa.ForeignKey('schedulers.schedulerid')),
- sa.Column('changeid', sa.Integer,
- sa.ForeignKey('changes.changeid')),
- sa.Column('important', sa.SmallInteger),
- )
- self.scheduler_changes.create()
- sa.Index('scheduler_changes_schedulerid',
- self.scheduler_changes.c.schedulerid).create()
- sa.Index('scheduler_changes_changeid',
- self.scheduler_changes.c.changeid).create()
- sa.Index('scheduler_changes_unique',
- self.scheduler_changes.c.schedulerid,
- self.scheduler_changes.c.changeid, unique=True).create()
-
- self.scheduler_upstream_buildsets = sa.Table(
- 'scheduler_upstream_buildsets', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id')),
- sa.Column('schedulerid', sa.Integer,
- sa.ForeignKey('schedulers.schedulerid')),
- )
- self.scheduler_upstream_buildsets.create()
-
- sa.Index('scheduler_upstream_buildsets_buildsetid',
- self.scheduler_upstream_buildsets.c.buildsetid).create()
- sa.Index('scheduler_upstream_buildsets_schedulerid',
- self.scheduler_upstream_buildsets.c.schedulerid).create()
-
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.objects.create(bind=conn)
-
- sa.Index('object_identity', self.objects.c.name,
- self.objects.c.class_name, unique=True).create()
-
- # tests
-
- def test_update(self):
- # this upgrade script really just drops a bunch of tables, so
- # there's not much to test!
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- # these tables are gone
- for tbl in 'schedulers', 'scheduler_upstream_buildsets':
- try:
- conn.execute("select * from %s" % tbl)
- except:
- pass
- else:
- self.fail("%s table still exists" % tbl)
-
- # but scheduler_changes is not
- s_c_tbl = sa.Table("scheduler_changes", metadata,
- autoload=True)
- q = sa.select(
- [ s_c_tbl.c.objectid, s_c_tbl.c.changeid, s_c_tbl.c.important ])
- self.assertEqual(conn.execute(q).fetchall(), [])
-
- return self.do_test_migration(18, 19, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py
deleted file mode 100644
index fedd3535..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- # the rest is unimportant
- )
- changes.create()
-
- # Links (URLs) for changes
- change_links = sa.Table('change_links', metadata,
- sa.Column('changeid', sa.Integer,
- sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('link', sa.String(1024), nullable=False),
- )
- change_links.create()
-
- sa.Index('change_links_changeid', change_links.c.changeid).create()
-
- # tests
-
- def test_update(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- try:
- conn.execute("select * from change_links")
- except:
- pass
- else:
- self.fail("change_links still exists")
-
- return self.do_test_migration(19, 20, setup_thd, verify_thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py
deleted file mode 100644
index 5cc3c980..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- cols = [
- 'buildrequests.id',
- 'builds.id',
- 'buildsets.id',
- 'changes.changeid',
- 'patches.id',
- 'sourcestampsets.id',
- 'sourcestamps.id',
- 'objects.id',
- 'users.uid',
- ]
-
- # tests
-
- def test_update(self):
- def setup_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- # insert a row into each table, giving an explicit id column so
- # that the sequence is not advanced correctly, but leave no rows in
- # one table to test that corner case
- for i, col in enumerate(self.cols):
- tbl_name, col_name = col.split('.')
- tbl = sa.Table(tbl_name, metadata,
- sa.Column(col_name, sa.Integer, primary_key=True))
- tbl.create()
- if i > 1:
- conn.execute(tbl.insert(), { col_name : i })
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- # try inserting *without* an ID, and verify that the resulting ID
- # is as expected
- for i, col in enumerate(self.cols):
- tbl_name, col_name = col.split('.')
- tbl = sa.Table(tbl_name, metadata,
- sa.Column(col_name, sa.Integer, primary_key=True))
- r = conn.execute(tbl.insert(), {})
- if i > 1:
- exp = i+1
- else:
- exp = 1
- self.assertEqual(r.inserted_primary_key[0], exp)
-
- return self.do_test_migration(20, 21, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py
deleted file mode 100644
index 95e154f5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import datetime
-import sqlalchemy as sa
-from twisted.trial import unittest
-from buildbot.test.util import migration
-from buildbot.util import UTC, datetime2epoch
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- # create tables as they are before migrating to version 019
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer),
- sa.Column('repository', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('sourcestampsetid', sa.Integer),
- )
- self.sourcestamps.create(bind=conn)
-
- self.changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False, server_default=''),
- )
- self.changes.create(bind=conn)
-
- def reload_tables_after_migration(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- self.sourcestamps = sa.Table('sourcestamps', metadata, autoload=True)
- self.changes = sa.Table('changes', metadata, autoload=True)
-
- def fill_tables_with_testdata(self, conn, testdata):
- for ssid, repo, codebase, cid in testdata:
- self.insert_sourcestamps_changes(conn, ssid, repo, codebase, cid)
-
- def insert_sourcestamps_changes(self, conn, sourcestampid, repository, codebase, changeid):
- conn.execute(self.sourcestamps.insert(),
- id=sourcestampid,
- sourcestampsetid=sourcestampid,
- branch='this_branch',
- revision='this_revision',
- patchid = None,
- repository=repository,
- project='',
- codebase=codebase)
-
- dt_when = datetime.datetime(1978, 6, 15, 12, 31, 15, tzinfo=UTC)
- conn.execute(self.changes.insert(),
- changeid = changeid,
- author = 'develop',
- comments = 'no comment',
- is_dir = 0,
- branch = 'default',
- revision = 'FD56A89',
- revling = None,
- when_timestamp = datetime2epoch(dt_when),
- category = None,
- repository = repository,
- codebase = codebase,
- project = '')
-
- def test_changes_has_codebase(self):
- changesdata = [(1000, 'https://svn.com/repo_a', 'repo_a', 1)]
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- self.reload_tables_after_migration(conn)
- tbl = self.changes
- self.assertTrue(hasattr(tbl.c, 'codebase'), 'Column codebase not found')
-
- # insert data in the table and new column
- self.fill_tables_with_testdata(conn, changesdata)
-
- res = conn.execute(sa.select([tbl.c.changeid, tbl.c.repository,
- tbl.c.codebase, ]))
- got_changes = res.fetchall()
- self.assertEqual(got_changes, [(1, 'https://svn.com/repo_a', 'repo_a')])
-
- return self.do_test_migration(21, 22, setup_thd, verify_thd)
-
- def test_sourcestamps_has_codebase(self):
- changesdata = [(1000, 'https://svn.com/repo_a', 'repo_a', 1)]
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- self.reload_tables_after_migration(conn)
- tbl = self.sourcestamps
- self.assertTrue(hasattr(tbl.c, 'codebase'), 'Column codebase not found')
-
- # insert data in the table and new column
- self.fill_tables_with_testdata(conn, changesdata)
-
- res = conn.execute(sa.select([tbl.c.id, tbl.c.repository,
- tbl.c.codebase,]))
- got_sourcestamps = res.fetchall()
- self.assertEqual(got_sourcestamps, [(1000, 'https://svn.com/repo_a', 'repo_a')])
-
- return self.do_test_migration(21, 22, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py
deleted file mode 100644
index 99af34ef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.db import model, enginestrategy
-from buildbot.test.util import db
-
-class DBConnector_Basic(db.RealDatabaseMixin, unittest.TestCase):
- """
- Basic tests of the DBConnector class - all start with an empty DB
- """
-
- def setUp(self):
- d = self.setUpRealDatabase()
- def make_fake_pool(_):
- engine = enginestrategy.create_engine(self.db_url,
- basedir=os.path.abspath('basedir'))
-
- # mock out the pool, and set up the model
- self.db = mock.Mock()
- self.db.pool.do_with_engine = lambda thd : defer.maybeDeferred(thd,engine)
- self.db.model = model.Model(self.db)
- self.db.start()
- d.addCallback(make_fake_pool)
- return d
-
- def tearDown(self):
- self.db.stop()
- return self.tearDownRealDatabase()
-
- def test_is_current_empty(self):
- d = self.db.model.is_current()
- d.addCallback(lambda r : self.assertFalse(r))
- return d
-
- def test_is_current_full(self):
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.model.is_current())
- d.addCallback(lambda r : self.assertTrue(r))
- return d
-
- # the upgrade method is very well-tested by the integration tests; the
- # remainder of the object is just tables.
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py
deleted file mode 100644
index 67d6a7e3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import time
-import sqlalchemy as sa
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from buildbot.db import pool
-from buildbot.test.util import db
-
-class Basic(unittest.TestCase):
-
- # basic tests, just using an in-memory SQL db and one thread
-
- def setUp(self):
- self.engine = sa.create_engine('sqlite://')
- self.engine.optimal_thread_pool_size = 1
- self.pool = pool.DBThreadPool(self.engine)
-
- def tearDown(self):
- self.pool.shutdown()
-
- def test_do(self):
- def add(conn, addend1, addend2):
- rp = conn.execute("SELECT %d + %d" % (addend1, addend2))
- return rp.scalar()
- d = self.pool.do(add, 10, 11)
- def check(res):
- self.assertEqual(res, 21)
- d.addCallback(check)
- return d
-
- def test_do_error(self):
- def fail(conn):
- rp = conn.execute("EAT COOKIES")
- return rp.scalar()
- d = self.pool.do(fail)
- return self.assertFailure(d, sa.exc.OperationalError)
-
- def test_do_exception(self):
- def raise_something(conn):
- raise RuntimeError("oh noes")
- d = self.pool.do(raise_something)
- return self.assertFailure(d, RuntimeError)
-
- def test_do_with_engine(self):
- def add(engine, addend1, addend2):
- rp = engine.execute("SELECT %d + %d" % (addend1, addend2))
- return rp.scalar()
- d = self.pool.do_with_engine(add, 10, 11)
- def check(res):
- self.assertEqual(res, 21)
- d.addCallback(check)
- return d
-
- def test_do_with_engine_exception(self):
- def fail(engine):
- rp = engine.execute("EAT COOKIES")
- return rp.scalar()
- d = self.pool.do_with_engine(fail)
- return self.assertFailure(d, sa.exc.OperationalError)
-
- def test_persistence_across_invocations(self):
- # NOTE: this assumes that both methods are called with the same
- # connection; if they run in parallel threads then it is not valid to
- # assume that the database engine will have finalized the first
- # transaction (and thus created the table) by the time the second
- # transaction runs. This is why we set optimal_thread_pool_size in
- # setUp.
- d = defer.succeed(None)
- def create_table(engine):
- engine.execute("CREATE TABLE tmp ( a integer )")
- d.addCallback( lambda r : self.pool.do_with_engine(create_table))
- def insert_into_table(engine):
- engine.execute("INSERT INTO tmp values ( 1 )")
- d.addCallback( lambda r : self.pool.do_with_engine(insert_into_table))
- return d
-
-
-class Stress(unittest.TestCase):
-
- def setUp(self):
- setup_engine = sa.create_engine('sqlite:///test.sqlite')
- setup_engine.execute("pragma journal_mode = wal")
- setup_engine.execute("CREATE TABLE test (a integer, b integer)")
-
- self.engine = sa.create_engine('sqlite:///test.sqlite')
- self.engine.optimal_thread_pool_size = 2
- self.pool = pool.DBThreadPool(self.engine)
-
- def tearDown(self):
- self.pool.shutdown()
- os.unlink("test.sqlite")
-
- @defer.inlineCallbacks
- def test_inserts(self):
- def write(conn):
- trans = conn.begin()
- conn.execute("INSERT INTO test VALUES (1, 1)")
- time.sleep(31)
- trans.commit()
- d1 = self.pool.do(write)
-
- def write2(conn):
- trans = conn.begin()
- conn.execute("INSERT INTO test VALUES (1, 1)")
- trans.commit()
- d2 = defer.Deferred()
- d2.addCallback(lambda _ :
- self.pool.do(write2))
- reactor.callLater(0.1, d2.callback, None)
-
- yield defer.DeferredList([ d1, d2 ])
-
- # don't run this test, since it takes 30s
- del test_inserts
-
-
-class BasicWithDebug(Basic):
-
- # same thing, but with debug=True
-
- def setUp(self):
- pool.debug = True
- return Basic.setUp(self)
-
- def tearDown(self):
- pool.debug = False
- return Basic.tearDown(self)
-
-
-class Native(unittest.TestCase, db.RealDatabaseMixin):
-
- # similar tests, but using the BUILDBOT_TEST_DB_URL
-
- def setUp(self):
- d = self.setUpRealDatabase(want_pool=False)
- def make_pool(_):
- self.pool = pool.DBThreadPool(self.db_engine)
- d.addCallback(make_pool)
- return d
-
- def tearDown(self):
- # try to delete the 'native_tests' table
- meta = sa.MetaData()
- native_tests = sa.Table("native_tests", meta)
- def thd(conn):
- native_tests.drop(bind=self.db_engine, checkfirst=True)
- d = self.pool.do(thd)
- d.addCallback(lambda _ : self.pool.shutdown())
- d.addCallback(lambda _ : self.tearDownRealDatabase())
- return d
-
- def test_ddl_and_queries(self):
- meta = sa.MetaData()
- native_tests = sa.Table("native_tests", meta,
- sa.Column('name', sa.String(length=200)))
-
- # perform a DDL operation and immediately try to access that table;
- # this has caused problems in the past, so this is basically a
- # regression test.
- def ddl(conn):
- t = conn.begin()
- native_tests.create(bind=conn)
- t.commit()
- d = self.pool.do(ddl)
- def access(conn):
- native_tests.insert(bind=conn).execute([ {'name':'foo'} ])
- d.addCallback(lambda _ :
- self.pool.do(access))
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py
deleted file mode 100644
index 395fbb79..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.db import schedulers
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestSchedulersConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'objects', 'scheduler_changes' ])
-
- def finish_setup(_):
- self.db.schedulers = \
- schedulers.SchedulersConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- def checkScheduler(self, objectid, name, class_name):
- def thd(conn):
- q = self.db.model.schedulers.select(
- whereclause=(self.db.model.schedulers.c.objectid == objectid))
- for row in conn.execute(q):
- self.assertEqual([ row.objectid, row.name, row.class_name],
- [ objectid, name, class_name])
- return self.db.pool.do(thd)
-
- # test data
-
- change3 = fakedb.Change(changeid=3)
- change4 = fakedb.Change(changeid=4)
- change5 = fakedb.Change(changeid=5)
- change6 = fakedb.Change(changeid=6, branch='sql')
-
- scheduler24 = fakedb.Object(id=24)
-
- def addClassifications(self, _, objectid, *classifications):
- def thd(conn):
- q = self.db.model.scheduler_changes.insert()
- conn.execute(q, [
- dict(changeid=c[0], objectid=objectid, important=c[1])
- for c in classifications ])
- return self.db.pool.do(thd)
-
- # tests
- def test_classifyChanges(self):
- d = self.insertTestData([ self.change3, self.change4,
- self.scheduler24 ])
- d.addCallback(lambda _ :
- self.db.schedulers.classifyChanges(24,
- { 3 : False, 4: True }))
- def check(_):
- def thd(conn):
- sch_chgs_tbl = self.db.model.scheduler_changes
- q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid)
- r = conn.execute(q)
- rows = [ (row.objectid, row.changeid, row.important)
- for row in r.fetchall() ]
- self.assertEqual(rows, [ (24, 3, 0), (24, 4, 1) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_classifyChanges_again(self):
- # test reclassifying changes, which may happen during some timing
- # conditions
- d = self.insertTestData([
- self.change3,
- self.scheduler24,
- fakedb.SchedulerChange(objectid=24, changeid=3, important=0),
- ])
- d.addCallback(lambda _ :
- self.db.schedulers.classifyChanges(24, { 3 : True }))
- def check(_):
- def thd(conn):
- sch_chgs_tbl = self.db.model.scheduler_changes
- q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid)
- r = conn.execute(q)
- rows = [ (row.objectid, row.changeid, row.important)
- for row in r.fetchall() ]
- self.assertEqual(rows, [ (24, 3, 1) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_flushChangeClassifications(self):
- d = self.insertTestData([ self.change3, self.change4,
- self.change5, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.flushChangeClassifications(24))
- def check(_):
- def thd(conn):
- q = self.db.model.scheduler_changes.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(rows, [])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_flushChangeClassifications_less_than(self):
- d = self.insertTestData([ self.change3, self.change4,
- self.change5, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.flushChangeClassifications(24, less_than=5))
- def check(_):
- def thd(conn):
- q = self.db.model.scheduler_changes.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual([ (r.changeid, r.important) for r in rows],
- [ (5, 1) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getChangeClassifications(self):
- d = self.insertTestData([ self.change3, self.change4, self.change5,
- self.change6, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1), (6, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.getChangeClassifications(24))
- def check(cls):
- self.assertEqual(cls, { 3 : True, 4 : False, 5 : True, 6: True })
- d.addCallback(check)
- return d
-
- def test_getChangeClassifications_branch(self):
- d = self.insertTestData([ self.change3, self.change4, self.change5,
- self.change6, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1), (6, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.getChangeClassifications(24, branch='sql'))
- def check(cls):
- self.assertEqual(cls, { 6 : True })
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py
deleted file mode 100644
index 01346a2c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.db import sourcestamps
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestSourceStampsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'change_files', 'patches',
- 'sourcestamp_changes', 'sourcestamps', 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.sourcestamps = \
- sourcestamps.SourceStampsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
-
- def test_addSourceStamp_simple(self):
- # add a sourcestampset for referential integrity
- d = self.insertTestData([
- fakedb.SourceStampSet(id=1),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.addSourceStamp(branch = 'production', revision='abdef',
- repository='test://repo', codebase='cb', project='stamper', sourcestampsetid=1))
- def check(ssid):
- def thd(conn):
- # should see one sourcestamp row
- ss_tbl = self.db.model.sourcestamps
- r = conn.execute(ss_tbl.select())
- rows = [ (row.id, row.branch, row.revision,
- row.patchid, row.repository, row.codebase, row.project, row.sourcestampsetid)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( ssid, 'production', 'abdef', None, 'test://repo', 'cb', 'stamper', 1) ])
-
- # .. and no sourcestamp_changes
- ssc_tbl = self.db.model.sourcestamp_changes
- r = conn.execute(ssc_tbl.select())
- rows = [ 1 for row in r.fetchall() ]
- self.assertEqual(rows, [])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_addSourceStamp_changes(self):
- # add some sample changes and a sourcestampset for referential integrity
- d = self.insertTestData([
- fakedb.SourceStampSet(id=1),
- fakedb.Change(changeid=3),
- fakedb.Change(changeid=4),
- ])
-
- d.addCallback(lambda _ :
- self.db.sourcestamps.addSourceStamp(branch = 'production', revision='abdef',
- repository='test://repo', codebase='cb', project='stamper', sourcestampsetid=1, changeids=[3,4]))
-
- def check(ssid):
- def thd(conn):
- # should see one sourcestamp row
- ss_tbl = self.db.model.sourcestamps
- r = conn.execute(ss_tbl.select())
- rows = [ (row.id, row.branch, row.revision,
- row.patchid, row.repository, row.codebase, row.project, row.sourcestampsetid)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( ssid, 'production', 'abdef', None, 'test://repo', 'cb', 'stamper', 1) ])
-
- # .. and two sourcestamp_changes
- ssc_tbl = self.db.model.sourcestamp_changes
- r = conn.execute(ssc_tbl.select())
- rows = [ (row.sourcestampid, row.changeid) for row in r.fetchall() ]
- self.assertEqual(sorted(rows), [ (ssid, 3), (ssid, 4) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_addSourceStamp_patch(self):
- # add a sourcestampset for referential integrity
- d = self.insertTestData([
- fakedb.SourceStampSet(id=1),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.addSourceStamp(branch = 'production', revision='abdef',
- repository='test://repo', codebase='cb', project='stamper', sourcestampsetid=1, patch_body='my patch', patch_level=3,
- patch_subdir='master/', patch_author='me',
- patch_comment="comment"))
- def check(ssid):
- def thd(conn):
- # should see one sourcestamp row
- ss_tbl = self.db.model.sourcestamps
- r = conn.execute(ss_tbl.select())
- rows = [ (row.id, row.branch, row.revision,
- row.patchid, row.repository, row.codebase, row.project, row.sourcestampsetid)
- for row in r.fetchall() ]
- patchid = row.patchid
- self.assertNotEqual(patchid, None)
- self.assertEqual(rows,
- [ ( ssid, 'production', 'abdef', patchid, 'test://repo', 'cb',
- 'stamper', 1) ])
-
- # .. and a single patch
- patches_tbl = self.db.model.patches
- r = conn.execute(patches_tbl.select())
- rows = [ (row.id, row.patchlevel, row.patch_base64, row.subdir,
- row.patch_author, row.patch_comment)
- for row in r.fetchall() ]
- self.assertEqual(rows, [(patchid, 3, 'bXkgcGF0Y2g=', 'master/',
- 'me', 'comment')])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_simple(self):
- d = self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='br', revision='rv', repository='rep', codebase='cb', project='prj'),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual(ssdict, dict(ssid=234, branch='br', revision='rv',
- sourcestampsetid=234, repository='rep', codebase = 'cb',
- project='prj', patch_body=None,
- patch_level=None, patch_subdir=None,
- patch_author=None, patch_comment=None, changeids=set([])))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_simple_None(self):
- "check that NULL branch and revision are handled correctly"
- d = self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch=None, revision=None,
- repository='rep', codebase='cb', project='prj'),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual((ssdict['branch'], ssdict['revision']),
- (None, None))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_changes(self):
- d = self.insertTestData([
- fakedb.Change(changeid=16),
- fakedb.Change(changeid=19),
- fakedb.Change(changeid=20),
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- fakedb.SourceStampChange(sourcestampid=234, changeid=16),
- fakedb.SourceStampChange(sourcestampid=234, changeid=20),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual(ssdict['changeids'], set([16,20]))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_patch(self):
- d = self.insertTestData([
- fakedb.Patch(id=99, patch_base64='aGVsbG8sIHdvcmxk',
- patch_author='bar', patch_comment='foo', subdir='/foo',
- patchlevel=3),
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, patchid=99),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual(dict((k,v) for k,v in ssdict.iteritems()
- if k.startswith('patch_')),
- dict(patch_body='hello, world',
- patch_level=3,
- patch_author='bar',
- patch_comment='foo',
- patch_subdir='/foo'))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_nosuch(self):
- d = self.db.sourcestamps.getSourceStamp(234)
- def check(ssdict):
- self.assertEqual(ssdict, None)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py
deleted file mode 100644
index 217b3ed3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.db import sourcestampsets
-from buildbot.test.util import connector_component
-
-class TestSourceStampSetsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=[ 'patches', 'buildsets', 'sourcestamps',
- 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.sourcestampsets = \
- sourcestampsets.SourceStampSetsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
- def test_addSourceStampSet_simple(self):
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.db.sourcestampsets.addSourceStampSet())
-
- def check(sourcestampsetid):
- def thd(conn):
- # should see one sourcestamp row
- ssset_tbl = self.db.model.sourcestampsets
- r = conn.execute(ssset_tbl.select())
- rows = [ (row.id)
- for row in r.fetchall() ]
- # Test if returned setid is in database
- self.assertEqual(rows,
- [ ( sourcestampsetid) ])
- # Test if returned set id starts with
- self.assertEqual(sourcestampsetid, 1)
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py
deleted file mode 100644
index 8002222e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.db import state
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestStateConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['objects', 'object_state' ])
-
- def finish_setup(_):
- self.db.state = \
- state.StateConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- def test_getObjectId_new(self):
- d = self.db.state.getObjectId('someobj', 'someclass')
- def check(objectid):
- self.assertNotEqual(objectid, None)
- def thd(conn):
- q = self.db.model.objects.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.id, r.name, r.class_name) for r in rows ],
- [ (objectid, 'someobj', 'someclass') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getObjectId_existing(self):
- d = self.insertTestData([
- fakedb.Object(id=19, name='someobj',
- class_name='someclass') ])
- d.addCallback(lambda _ :
- self.db.state.getObjectId('someobj', 'someclass'))
- def check(objectid):
- self.assertEqual(objectid, 19)
- d.addCallback(check)
- return d
-
-
- def test_getObjectId_conflict(self):
- # set up to insert a row between looking for an existing object
- # and adding a new one, triggering the fallback to re-running
- # the select.
- def hook(conn):
- conn.execute(self.db.model.objects.insert(),
- id=27, name='someobj', class_name='someclass')
- self.db.state._test_timing_hook = hook
-
- d = self.db.state.getObjectId('someobj', 'someclass')
- def check(objectid):
- self.assertEqual(objectid, 27)
- d.addCallback(check)
- return d
-
- def test_getState_missing(self):
- d = self.db.state.getState(10, 'nosuch')
- return self.assertFailure(d, KeyError)
-
- def test_getState_missing_default(self):
- d = self.db.state.getState(10, 'nosuch', 'abc')
- def check(val):
- self.assertEqual(val, 'abc')
- d.addCallback(check)
- return d
-
- def test_getState_missing_default_None(self):
- d = self.db.state.getState(10, 'nosuch', None)
- def check(val):
- self.assertEqual(val, None)
- d.addCallback(check)
- return d
-
- def test_getState_present(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='x', class_name='y'),
- fakedb.ObjectState(objectid=10, name='x', value_json='[1,2]'),
- ])
- d.addCallback(lambda _ :
- self.db.state.getState(10, 'x'))
- def check(val):
- self.assertEqual(val, [1,2])
- d.addCallback(check)
- return d
-
- def test_getState_badjson(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='x', class_name='y'),
- fakedb.ObjectState(objectid=10, name='x', value_json='ff[1'),
- ])
- d.addCallback(lambda _ :
- self.db.state.getState(10, 'x'))
- return self.assertFailure(d, TypeError)
-
- def test_setState(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='-', class_name='-'),
- ])
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', [1,2]))
- def check(_):
- def thd(conn):
- q = self.db.model.object_state.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.objectid, r.name, r.value_json) for r in rows ],
- [ (10, 'x', '[1, 2]') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_setState_badjson(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='x', class_name='y'),
- ])
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', self)) # self is not JSON-able..
- return self.assertFailure(d, TypeError)
-
- def test_setState_existing(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='-', class_name='-'),
- fakedb.ObjectState(objectid=10, name='x', value_json='99'),
- ])
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', [1,2]))
- def check(_):
- def thd(conn):
- q = self.db.model.object_state.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.objectid, r.name, r.value_json) for r in rows ],
- [ (10, 'x', '[1, 2]') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_setState_conflict(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='-', class_name='-'),
- ])
- def hook(conn):
- conn.execute(self.db.model.object_state.insert(),
- objectid=10, name='x', value_json='22')
- self.db.state._test_timing_hook = hook
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', [1,2]))
- def check(_):
- def thd(conn):
- q = self.db.model.object_state.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.objectid, r.name, r.value_json) for r in rows ],
- [ (10, 'x', '22') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py
deleted file mode 100644
index 63e2c0de..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py
+++ /dev/null
@@ -1,473 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from twisted.trial import unittest
-from buildbot.db import users
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestUsersConnectorComponent(connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['users', 'users_info', 'changes', 'change_users'])
- def finish_setup(_):
- self.db.users = users.UsersConnectorComponent(self.db)
- d.addCallback(finish_setup)
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # sample user data
-
- user1_rows = [
- fakedb.User(uid=1, identifier='soap'),
- fakedb.UserInfo(uid=1, attr_type='IPv9', attr_data='0578cc6.8db024'),
- ]
-
- user2_rows = [
- fakedb.User(uid=2, identifier='lye'),
- fakedb.UserInfo(uid=2, attr_type='git',
- attr_data='Tyler Durden <tyler@mayhem.net>'),
- fakedb.UserInfo(uid=2, attr_type='irc', attr_data='durden')
- ]
-
- user3_rows = [
- fakedb.User(uid=3, identifier='marla', bb_username='marla',
- bb_password='cancer')
- ]
-
- user1_dict = {
- 'uid': 1,
- 'identifier': u'soap',
- 'bb_username': None,
- 'bb_password': None,
- 'IPv9': u'0578cc6.8db024',
- }
-
- user2_dict = {
- 'uid': 2,
- 'identifier': u'lye',
- 'bb_username': None,
- 'bb_password': None,
- 'irc': u'durden',
- 'git': u'Tyler Durden <tyler@mayhem.net>'
- }
-
- user3_dict = {
- 'uid': 3,
- 'identifier': u'marla',
- 'bb_username': u'marla',
- 'bb_password': u'cancer',
- }
-
- # tests
-
- def test_addUser_new(self):
- d = self.db.users.findUserByAttr(identifier='soap',
- attr_type='subspace_net_handle',
- attr_data='Durden0924')
- def check_user(uid):
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual(len(users), 1)
- self.assertEqual(users[0].uid, uid)
- self.assertEqual(users[0].identifier, 'soap')
- self.assertEqual(len(infos), 1)
- self.assertEqual(infos[0].uid, uid)
- self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
- self.assertEqual(infos[0].attr_data, 'Durden0924')
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_addUser_existing(self):
- d = self.insertTestData(self.user1_rows)
- d.addCallback(lambda _ : self.db.users.findUserByAttr(
- identifier='soapy',
- attr_type='IPv9',
- attr_data='0578cc6.8db024'))
- def check_user(uid):
- self.assertEqual(uid, 1)
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual(len(users), 1)
- self.assertEqual(users[0].uid, uid)
- self.assertEqual(users[0].identifier, 'soap') # not changed!
- self.assertEqual(len(infos), 1)
- self.assertEqual(infos[0].uid, uid)
- self.assertEqual(infos[0].attr_type, 'IPv9')
- self.assertEqual(infos[0].attr_data, '0578cc6.8db024')
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_findUser_existing(self):
- d = self.insertTestData(
- self.user1_rows + self.user2_rows + self.user3_rows)
- d.addCallback(lambda _ : self.db.users.findUserByAttr(
- identifier='lye',
- attr_type='git',
- attr_data='Tyler Durden <tyler@mayhem.net>'))
- def check_user(uid):
- self.assertEqual(uid, 2)
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual((
- sorted([ tuple(u) for u in users]),
- sorted([ tuple(i) for i in infos])
- ), (
- [
- (1L, u'soap', None, None),
- (2L, u'lye', None, None),
- (3L, u'marla', u'marla', u'cancer'),
- ], [
- (1L, u'IPv9', u'0578cc6.8db024'),
- (2L, u'git', u'Tyler Durden <tyler@mayhem.net>'),
- (2L, u'irc', u'durden')
- ]))
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_addUser_race(self):
- def race_thd(conn):
- # note that this assumes that both inserts can happen "at once".
- # This is the case for DB engines that support transactions, but
- # not for MySQL. so this test does not detect the potential MySQL
- # failure, which will generally result in a spurious failure.
- conn.execute(self.db.model.users.insert(),
- uid=99, identifier='soap')
- conn.execute(self.db.model.users_info.insert(),
- uid=99, attr_type='subspace_net_handle',
- attr_data='Durden0924')
- d = self.db.users.findUserByAttr(identifier='soap',
- attr_type='subspace_net_handle',
- attr_data='Durden0924',
- _race_hook=race_thd)
- def check_user(uid):
- self.assertEqual(uid, 99)
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual(len(users), 1)
- self.assertEqual(users[0].uid, uid)
- self.assertEqual(users[0].identifier, 'soap')
- self.assertEqual(len(infos), 1)
- self.assertEqual(infos[0].uid, uid)
- self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
- self.assertEqual(infos[0].attr_data, 'Durden0924')
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_addUser_existing_identifier(self):
- d = self.insertTestData(self.user1_rows)
- d.addCallback(lambda _ : self.db.users.findUserByAttr(
- identifier='soap',
- attr_type='telepathIO(tm)',
- attr_data='hmm,lye'))
- return self.assertFailure(d, sa.exc.IntegrityError,
- sa.exc.ProgrammingError)
-
- def test_getUser(self):
- d = self.insertTestData(self.user1_rows)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict, self.user1_dict)
- d.addCallback(check1)
- return d
-
- def test_getUser_bb(self):
- d = self.insertTestData(self.user3_rows)
- def get3(_):
- return self.db.users.getUser(3)
- d.addCallback(get3)
- def check3(usdict):
- self.assertEqual(usdict, self.user3_dict)
- d.addCallback(check3)
- return d
-
- def test_getUser_multi_attr(self):
- d = self.insertTestData(self.user2_rows)
- def get1(_):
- return self.db.users.getUser(2)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict, self.user2_dict)
- d.addCallback(check1)
- return d
-
- def test_getUser_no_match(self):
- d = self.insertTestData(self.user1_rows)
- def get3(_):
- return self.db.users.getUser(3)
- d.addCallback(get3)
- def check3(none):
- self.assertEqual(none, None)
- d.addCallback(check3)
- return d
-
- def test_getUsers_none(self):
- d = self.db.users.getUsers()
- def check(res):
- self.assertEqual(res, [])
- d.addCallback(check)
- return d
-
- def test_getUsers(self):
- d = self.insertTestData(self.user1_rows)
- def get(_):
- return self.db.users.getUsers()
- d.addCallback(get)
- def check(res):
- self.assertEqual(res, [dict(uid=1, identifier='soap')])
- d.addCallback(check)
- return d
-
- def test_getUsers_multiple(self):
- d = self.insertTestData(self.user1_rows + self.user2_rows)
- def get(_):
- return self.db.users.getUsers()
- d.addCallback(get)
- def check(res):
- self.assertEqual(res, [dict(uid=1, identifier='soap'),
- dict(uid=2, identifier='lye')])
- d.addCallback(check)
- return d
-
- def test_getUserByUsername(self):
- d = self.insertTestData(self.user3_rows)
- def get3(_):
- return self.db.users.getUserByUsername("marla")
- d.addCallback(get3)
- def check3(res):
- self.assertEqual(res, self.user3_dict)
- d.addCallback(check3)
- return d
-
- def test_getUserByUsername_no_match(self):
- d = self.insertTestData(self.user3_rows)
- def get3(_):
- return self.db.users.getUserByUsername("tyler")
- d.addCallback(get3)
- def check3(none):
- self.assertEqual(none, None)
- d.addCallback(check3)
- return d
-
- def test_updateUser_existing_type(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, attr_type='IPv9', attr_data='abcd.1234')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv9'], 'abcd.1234')
- self.assertEqual(usdict['identifier'], 'soap') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_new_type(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, attr_type='IPv4', attr_data='123.134.156.167')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv4'], '123.134.156.167')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- self.assertEqual(usdict['identifier'], 'soap') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_identifier(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, identifier='lye')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'lye')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_bb(self):
- d = self.insertTestData(self.user3_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, bb_username='boss', bb_password='fired')
- d.addCallback(update3)
- def get3(_):
- return self.db.users.getUser(3)
- d.addCallback(get3)
- def check3(usdict):
- self.assertEqual(usdict['bb_username'], 'boss')
- self.assertEqual(usdict['bb_password'], 'fired')
- self.assertEqual(usdict['identifier'], 'marla') # no change
- d.addCallback(check3)
- return d
-
- def test_updateUser_all(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, identifier='lye', bb_username='marla',
- bb_password='cancer', attr_type='IPv4', attr_data='123.134.156.167')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'lye')
- self.assertEqual(usdict['bb_username'], 'marla')
- self.assertEqual(usdict['bb_password'], 'cancer')
- self.assertEqual(usdict['IPv4'], '123.134.156.167')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_race(self):
- # called from the db thread, this opens a *new* connection (to avoid
- # the existing transaction) and executes a conflicting insert in that
- # connection. This will cause the insert in the db method to fail, and
- # the data in this insert (8.8.8.8) will appear below.
- def race_thd(conn):
- conn = self.db.pool.engine.connect()
- conn.execute(self.db.model.users_info.insert(),
- uid=1, attr_type='IPv4',
- attr_data='8.8.8.8')
-
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, attr_type='IPv4', attr_data='123.134.156.167',
- _race_hook=race_thd)
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'soap')
- self.assertEqual(usdict['IPv4'], '8.8.8.8')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_update_NoMatch_identifier(self):
- d = self.insertTestData(self.user1_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, identifier='abcd')
- d.addCallback(update3)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'soap') # no change
- d.addCallback(check1)
- return d
-
- def test_update_NoMatch_attribute(self):
- d = self.insertTestData(self.user1_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, attr_type='abcd', attr_data='efgh')
- d.addCallback(update3)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_update_NoMatch_bb(self):
- d = self.insertTestData(self.user1_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, attr_type='marla', attr_data='cancer')
- d.addCallback(update3)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_removeUser_uid(self):
- d = self.insertTestData(self.user1_rows)
- def remove1(_):
- return self.db.users.removeUser(1)
- d.addCallback(remove1)
- def check1(_):
- def thd(conn):
- r = conn.execute(self.db.model.users.select())
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check1)
- return d
-
- def test_removeNoMatch(self):
- d = self.insertTestData(self.user1_rows)
- def check(_):
- return self.db.users.removeUser(uid=3)
- d.addCallback(check)
- return d
-
- def test_identifierToUid_NoMatch(self):
- d = self.db.users.identifierToUid(identifier="soap")
- def check(res):
- self.assertEqual(res, None)
- d.addCallback(check)
- return d
-
- def test_identifierToUid_match(self):
- d = self.insertTestData(self.user1_rows)
- def ident2uid(_):
- return self.db.users.identifierToUid(identifier="soap")
- d.addCallback(ident2uid)
- def check(res):
- self.assertEqual(res, 1)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py
deleted file mode 100644
index c170382e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-import signal
-from twisted.internet import defer, reactor, task
-from twisted.trial import unittest
-from twisted.python import log
-from buildbot import master, monkeypatches, config
-from buildbot.util import subscription
-from buildbot.db import connector
-from buildbot.test.util import dirs, compat, misc, logging
-from buildbot.test.fake import fakedb
-from buildbot.util import epoch2datetime
-from buildbot.changes import changes
-from buildbot.process.users import users
-
-class Subscriptions(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- basedir = os.path.abspath('basedir')
- d = self.setUpDirs(basedir)
- def set_master(_):
- self.master = master.BuildMaster(basedir)
- self.master.config.db['db_poll_interval'] = None
- d.addCallback(set_master)
- return d
-
- def tearDown(self):
- return self.tearDownDirs()
-
- def test_change_subscription(self):
- changeid = 918
- chdict = {
- 'changeid': 14,
- 'author': u'warner',
- 'branch': u'warnerdb',
- 'category': u'devel',
- 'comments': u'fix whitespace',
- 'files': [u'master/buildbot/__init__.py'],
- 'is_dir': 0,
- 'project': u'Buildbot',
- 'properties': {},
- 'repository': u'git://warner',
- 'revision': u'0e92a098b',
- 'revlink': u'http://warner/0e92a098b',
- 'when_timestamp': epoch2datetime(266738404),
- }
- newchange = mock.Mock(name='newchange')
-
- # patch out everything we're about to call
- self.master.db = mock.Mock()
- self.master.db.changes.addChange.return_value = \
- defer.succeed(changeid)
- self.master.db.changes.getChange.return_value = \
- defer.succeed(chdict)
- self.patch(changes.Change, 'fromChdict',
- classmethod(lambda cls, master, chdict :
- defer.succeed(newchange)))
-
- cb = mock.Mock()
- sub = self.master.subscribeToChanges(cb)
- self.assertIsInstance(sub, subscription.Subscription)
-
- d = self.master.addChange()
- def check(change):
- # master called the right thing in the db component, including with
- # appropriate default values
- self.master.db.changes.addChange.assert_called_with(author=None,
- files=None, comments=None, is_dir=0,
- revision=None, when_timestamp=None, branch=None, codebase='',
- category=None, revlink='', properties={}, repository='', project='', uid=None)
-
- self.master.db.changes.getChange.assert_called_with(changeid)
- # addChange returned the right value
- self.failUnless(change is newchange) # fromChdict's return value
- # and the notification sub was called correctly
- cb.assert_called_with(newchange)
- d.addCallback(check)
- return d
-
- def do_test_addChange_args(self, args=(), kwargs={}, exp_db_kwargs={}):
- # add default arguments
- default_db_kwargs = dict(files=None, comments=None, author=None,
- is_dir=0, revision=None, when_timestamp=None,
- branch=None, category=None, revlink='', properties={},
- repository='', codebase='', project='', uid=None)
- k = default_db_kwargs
- k.update(exp_db_kwargs)
- exp_db_kwargs = k
-
- self.master.db = mock.Mock()
- got = []
- def db_addChange(*args, **kwargs):
- got[:] = args, kwargs
- # use an exception as a quick way to bail out of the remainder
- # of the addChange method
- return defer.fail(RuntimeError)
- self.master.db.changes.addChange = db_addChange
-
- d = self.master.addChange(*args, **kwargs)
- d.addCallback(lambda _ : self.fail("should not succeed"))
- def check(f):
- self.assertEqual(got, [(), exp_db_kwargs])
- d.addErrback(check)
- return d
-
- def test_addChange_args_author(self):
- # who should come through as author
- return self.do_test_addChange_args(
- kwargs=dict(who='me'),
- exp_db_kwargs=dict(author='me'))
-
- def test_addChange_args_isdir(self):
- # isdir should come through as is_dir
- return self.do_test_addChange_args(
- kwargs=dict(isdir=1),
- exp_db_kwargs=dict(is_dir=1))
-
- def test_addChange_args_when(self):
- # when should come through as when_timestamp, as a datetime
- return self.do_test_addChange_args(
- kwargs=dict(when=892293875),
- exp_db_kwargs=dict(when_timestamp=epoch2datetime(892293875)))
-
- def test_addChange_args_properties(self):
- # properties should be qualified with a source
- return self.do_test_addChange_args(
- kwargs=dict(properties={ 'a' : 'b' }),
- exp_db_kwargs=dict(properties={ 'a' : ('b', 'Change') }))
-
- def test_addChange_args_properties_tuple(self):
- # properties should be qualified with a source, even if they
- # already look like they have a source
- return self.do_test_addChange_args(
- kwargs=dict(properties={ 'a' : ('b', 'Change') }),
- exp_db_kwargs=dict(properties={
- 'a' : (('b', 'Change'), 'Change') }))
-
- def test_addChange_args_positional(self):
- # master.addChange can take author, files, comments as positional
- # arguments
- return self.do_test_addChange_args(
- args=('me', ['a'], 'com'),
- exp_db_kwargs=dict(author='me', files=['a'], comments='com'))
-
- def do_test_createUserObjects_args(self, args=(), kwargs={}, exp_args=()):
- got = []
- def fake_createUserObject(*args, **kwargs):
- got[:] = args, kwargs
- # use an exception as a quick way to bail out of the remainder
- # of the createUserObject method
- return defer.fail(RuntimeError)
-
- self.patch(users, 'createUserObject', fake_createUserObject)
-
- d = self.master.addChange(*args, **kwargs)
- d.addCallback(lambda _ : self.fail("should not succeed"))
- def check(f):
- self.assertEqual(got, [exp_args, {}])
- d.addErrback(check)
- return d
-
- def test_addChange_createUserObject_args(self):
- # who should come through as author
- return self.do_test_createUserObjects_args(
- kwargs=dict(who='me', src='git'),
- exp_args=(self.master, 'me', 'git'))
-
- def test_buildset_subscription(self):
- self.master.db = mock.Mock()
- self.master.db.buildsets.addBuildset.return_value = \
- defer.succeed((938593, dict(a=19,b=20)))
-
- cb = mock.Mock()
- sub = self.master.subscribeToBuildsets(cb)
- self.assertIsInstance(sub, subscription.Subscription)
-
- d = self.master.addBuildset(ssid=999)
- def check((bsid,brids)):
- # master called the right thing in the db component
- self.master.db.buildsets.addBuildset.assert_called_with(ssid=999)
- # addBuildset returned the right value
- self.assertEqual((bsid,brids), (938593, dict(a=19,b=20)))
- # and the notification sub was called correctly
- cb.assert_called_with(bsid=938593, ssid=999)
- d.addCallback(check)
- return d
-
- def test_buildset_completion_subscription(self):
- self.master.db = mock.Mock()
-
- cb = mock.Mock()
- sub = self.master.subscribeToBuildsetCompletions(cb)
- self.assertIsInstance(sub, subscription.Subscription)
-
- self.master._buildsetComplete(938593, 999)
- # assert the notification sub was called correctly
- cb.assert_called_with(938593, 999)
-
-class StartupAndReconfig(dirs.DirsMixin, logging.LoggingMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpLogging()
- self.basedir = os.path.abspath('basedir')
- d = self.setUpDirs(self.basedir)
- @d.addCallback
- def make_master(_):
- # don't create child services
- self.patch(master.BuildMaster, 'create_child_services',
- lambda self : None)
-
- # patch out a few other annoying things the master likes to do
- self.patch(monkeypatches, 'patch_all', lambda : None)
- self.patch(signal, 'signal', lambda sig, hdlr : None)
- self.patch(master, 'Status', lambda master : mock.Mock()) # XXX temporary
- self.patch(config.MasterConfig, 'loadConfig',
- classmethod(lambda cls, b, f : cls()))
-
- self.master = master.BuildMaster(self.basedir)
- self.db = self.master.db = fakedb.FakeDBConnector(self)
-
- return d
-
- def tearDown(self):
- return self.tearDownDirs()
-
- def make_reactor(self):
- r = mock.Mock()
- r.callWhenRunning = reactor.callWhenRunning
- return r
-
- def patch_loadConfig_fail(self):
- @classmethod
- def loadConfig(cls, b, f):
- config.error('oh noes')
- self.patch(config.MasterConfig, 'loadConfig', loadConfig)
-
-
- # tests
-
- def test_startup_bad_config(self):
- reactor = self.make_reactor()
- self.patch_loadConfig_fail()
-
- d = self.master.startService(_reactor=reactor)
-
- @d.addCallback
- def check(_):
- reactor.stop.assert_called()
- self.assertLogged("oh noes")
- return d
-
- def test_startup_db_not_ready(self):
- reactor = self.make_reactor()
- def db_setup():
- log.msg("GOT HERE")
- raise connector.DatabaseNotReadyError()
- self.db.setup = db_setup
-
- d = self.master.startService(_reactor=reactor)
-
- @d.addCallback
- def check(_):
- reactor.stop.assert_called()
- self.assertLogged("GOT HERE")
- return d
-
- @compat.usesFlushLoggedErrors
- def test_startup_error(self):
- reactor = self.make_reactor()
- def db_setup():
- raise RuntimeError("oh noes")
- self.db.setup = db_setup
-
- d = self.master.startService(_reactor=reactor)
-
- @d.addCallback
- def check(_):
- reactor.stop.assert_called()
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- return d
-
- def test_startup_ok(self):
- reactor = self.make_reactor()
-
- d = self.master.startService(_reactor=reactor)
- d.addCallback(lambda _ : self.master.stopService())
-
- @d.addCallback
- def check(_):
- self.failIf(reactor.stop.called)
- self.assertLogged("BuildMaster is running")
- return d
-
- def test_reconfig(self):
- reactor = self.make_reactor()
- self.master.reconfigService = mock.Mock(
- side_effect=lambda n : defer.succeed(None))
-
- d = self.master.startService(_reactor=reactor)
- d.addCallback(lambda _ : self.master.reconfig())
- d.addCallback(lambda _ : self.master.stopService())
-
- @d.addCallback
- def check(_):
- self.master.reconfigService.assert_called()
- return d
-
- @defer.inlineCallbacks
- def test_reconfig_bad_config(self):
- reactor = self.make_reactor()
- self.master.reconfigService = mock.Mock(
- side_effect=lambda n : defer.succeed(None))
-
- yield self.master.startService(_reactor=reactor)
-
- # reset, since startService called reconfigService
- self.master.reconfigService.reset_mock()
-
- # reconfig, with a failure
- self.patch_loadConfig_fail()
- yield self.master.reconfig()
-
- self.master.stopService()
-
- self.assertLogged("reconfig aborted without")
- self.failIf(self.master.reconfigService.called)
-
- @defer.inlineCallbacks
- def test_reconfigService_db_url_changed(self):
- old = self.master.config = config.MasterConfig()
- old.db['db_url'] = 'aaaa'
- yield self.master.reconfigService(old)
-
- new = config.MasterConfig()
- new.db['db_url'] = 'bbbb'
-
- self.assertRaises(config.ConfigErrors, lambda :
- self.master.reconfigService(new))
-
- def test_reconfigService_start_polling(self):
- loopingcall = mock.Mock()
- self.patch(task, 'LoopingCall', lambda fn : loopingcall)
-
- self.master.config = config.MasterConfig()
- new = config.MasterConfig()
- new.db['db_poll_interval'] = 120
-
- d = self.master.reconfigService(new)
- @d.addCallback
- def check(_):
- loopingcall.start.assert_called_with(120, now=False)
- return d
-
- @defer.inlineCallbacks
- def test_reconfigService_stop_polling(self):
- db_loop = self.master.db_loop = mock.Mock()
-
- old = self.master.config = config.MasterConfig()
- old.db['db_poll_interval'] = 120
- yield self.master.reconfigService(old)
-
- new = config.MasterConfig()
- new.db['db_poll_interval'] = None
- yield self.master.reconfigService(new)
-
- db_loop.stop.assert_called()
- self.assertEqual(self.master.db_loop, None)
-
-
-class Polling(dirs.DirsMixin, misc.PatcherMixin, unittest.TestCase):
-
- def setUp(self):
- self.gotten_changes = []
- self.gotten_buildset_additions = []
- self.gotten_buildset_completions = []
- self.gotten_buildrequest_additions = []
-
-
- basedir = os.path.abspath('basedir')
-
- # patch out os.uname so that we get a consistent hostname
- self.patch_os_uname(lambda : [ 0, 'testhost.localdomain' ])
- self.master_name = "testhost.localdomain:%s" % (basedir,)
-
- d = self.setUpDirs(basedir)
- def set_master(_):
- self.master = master.BuildMaster(basedir)
-
- self.db = self.master.db = fakedb.FakeDBConnector(self)
-
- self.master.config.db['db_poll_interval'] = 10
-
- # overridesubscription callbacks
- self.master._change_subs = sub = mock.Mock()
- sub.deliver = self.deliverChange
- self.master._new_buildset_subs = sub = mock.Mock()
- sub.deliver = self.deliverBuildsetAddition
- self.master._complete_buildset_subs = sub = mock.Mock()
- sub.deliver = self.deliverBuildsetCompletion
- self.master._new_buildrequest_subs = sub = mock.Mock()
- sub.deliver = self.deliverBuildRequestAddition
-
- d.addCallback(set_master)
- return d
-
- def tearDown(self):
- return self.tearDownDirs()
-
- def deliverChange(self, change):
- self.gotten_changes.append(change)
-
- def deliverBuildsetAddition(self, **kwargs):
- self.gotten_buildset_additions.append(kwargs)
-
- def deliverBuildsetCompletion(self, bsid, result):
- self.gotten_buildset_completions.append((bsid, result))
-
- def deliverBuildRequestAddition(self, notif):
- self.gotten_buildrequest_additions.append(notif)
-
- # tests
-
- def test_pollDatabaseChanges_empty(self):
- self.db.insertTestData([
- fakedb.Object(id=22, name=self.master_name,
- class_name='buildbot.master.BuildMaster'),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual(self.gotten_changes, [])
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(22, last_processed_change=0)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseChanges_catchup(self):
- # with no existing state, it should catch up to the most recent change,
- # but not process anything
- self.db.insertTestData([
- fakedb.Object(id=22, name=self.master_name,
- class_name='buildbot.master.BuildMaster'),
- fakedb.Change(changeid=10),
- fakedb.Change(changeid=11),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual(self.gotten_changes, [])
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(22, last_processed_change=11)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseChanges_multiple(self):
- self.db.insertTestData([
- fakedb.Object(id=53, name=self.master_name,
- class_name='buildbot.master.BuildMaster'),
- fakedb.ObjectState(objectid=53, name='last_processed_change',
- value_json='10'),
- fakedb.Change(changeid=10),
- fakedb.Change(changeid=11),
- fakedb.Change(changeid=12),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual([ ch.number for ch in self.gotten_changes],
- [ 11, 12 ]) # note 10 was already seen
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(53, last_processed_change=12)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseChanges_nothing_new(self):
- self.db.insertTestData([
- fakedb.Object(id=53, name='master',
- class_name='buildbot.master.BuildMaster'),
- fakedb.ObjectState(objectid=53, name='last_processed_change',
- value_json='10'),
- fakedb.Change(changeid=10),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual(self.gotten_changes, [])
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(53, last_processed_change=10)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseBuildRequests_empty(self):
- d = self.master.pollDatabaseBuildRequests()
- def check(_):
- self.assertEqual(self.gotten_buildrequest_additions, [])
- d.addCallback(check)
- return d
-
- def test_pollDatabaseBuildRequests_new(self):
- self.db.insertTestData([
- fakedb.SourceStampSet(id=127),
- fakedb.SourceStamp(id=127, sourcestampsetid=127),
- fakedb.Buildset(id=99, sourcestampsetid=127),
- fakedb.BuildRequest(id=19, buildsetid=99, buildername='9teen'),
- fakedb.BuildRequest(id=20, buildsetid=99, buildername='twenty')
- ])
- d = self.master.pollDatabaseBuildRequests()
- def check(_):
- self.assertEqual(sorted(self.gotten_buildrequest_additions),
- sorted([dict(bsid=99, brid=19, buildername='9teen'),
- dict(bsid=99, brid=20, buildername='twenty')]))
- d.addCallback(check)
- return d
-
- def test_pollDatabaseBuildRequests_incremental(self):
- d = defer.succeed(None)
- def insert1(_):
- self.db.insertTestData([
- fakedb.SourceStampSet(id=127),
- fakedb.SourceStamp(id=127, sourcestampsetid=127),
- fakedb.Buildset(id=99, sourcestampsetid=127),
- fakedb.BuildRequest(id=11, buildsetid=9, buildername='eleventy'),
- ])
- d.addCallback(insert1)
- d.addCallback(lambda _ : self.master.pollDatabaseBuildRequests())
- def insert2_and_claim(_):
- self.gotten_buildrequest_additions.append('MARK')
- self.db.insertTestData([
- fakedb.BuildRequest(id=20, buildsetid=9,
- buildername='twenty'),
- ])
- self.db.buildrequests.fakeClaimBuildRequest(11)
- d.addCallback(insert2_and_claim)
- d.addCallback(lambda _ : self.master.pollDatabaseBuildRequests())
- def unclaim(_):
- self.gotten_buildrequest_additions.append('MARK')
- self.db.buildrequests.fakeUnclaimBuildRequest(11)
- # note that at this point brid 20 is still unclaimed, but we do
- # not get a new notification about it
- d.addCallback(unclaim)
- d.addCallback(lambda _ : self.master.pollDatabaseBuildRequests())
- def check(_):
- self.assertEqual(self.gotten_buildrequest_additions, [
- dict(bsid=9, brid=11, buildername='eleventy'),
- 'MARK',
- dict(bsid=9, brid=20, buildername='twenty'),
- 'MARK',
- dict(bsid=9, brid=11, buildername='eleventy'),
- ])
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py
deleted file mode 100644
index 032c8ff9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# Test clean shutdown functionality of the master
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.spread import pb
-from twisted.cred import credentials
-from buildbot import pbmanager
-
-class TestPBManager(unittest.TestCase):
-
- def setUp(self):
- self.pbm = pbmanager.PBManager()
- self.pbm.startService()
- self.connections = []
-
- def tearDown(self):
- return self.pbm.stopService()
-
- def perspectiveFactory(self, mind, username):
- persp = mock.Mock()
- persp.is_my_persp = True
- persp.attached = lambda mind : defer.succeed(None)
- self.connections.append(username)
- return defer.succeed(persp)
-
- def test_repr(self):
- reg = self.pbm.register('tcp:0:interface=127.0.0.1', "x", "y", self.perspectiveFactory)
- self.assertEqual(`self.pbm.dispatchers['tcp:0:interface=127.0.0.1']`,
- '<pbmanager.Dispatcher for x on tcp:0:interface=127.0.0.1>')
- self.assertEqual(`reg`, '<pbmanager.Registration for x on tcp:0:interface=127.0.0.1>')
-
- def test_register_unregister(self):
- portstr = "tcp:0:interface=127.0.0.1"
- reg = self.pbm.register(portstr, "boris", "pass", self.perspectiveFactory)
-
- # make sure things look right
- self.assertIn(portstr, self.pbm.dispatchers)
- disp = self.pbm.dispatchers[portstr]
- self.assertIn('boris', disp.users)
-
- # we can't actually connect to it, as that requires finding the
- # dynamically allocated port number which is buried out of reach;
- # however, we can try the requestAvatar and requestAvatarId methods.
-
- d = disp.requestAvatarId(credentials.UsernamePassword('boris', 'pass'))
- def check_avatarid(username):
- self.assertEqual(username, 'boris')
- d.addCallback(check_avatarid)
- d.addCallback(lambda _ :
- disp.requestAvatar('boris', mock.Mock(), pb.IPerspective))
- def check_avatar((iface, persp, detach_fn)):
- self.failUnless(persp.is_my_persp)
- self.assertIn('boris', self.connections)
- d.addCallback(check_avatar)
-
- d.addCallback(lambda _ : reg.unregister())
- return d
-
- def test_double_register_unregister(self):
- portstr = "tcp:0:interface=127.0.0.1"
- reg1 = self.pbm.register(portstr, "boris", "pass", None)
- reg2 = self.pbm.register(portstr, "ivona", "pass", None)
-
- # make sure things look right
- self.assertEqual(len(self.pbm.dispatchers), 1)
- self.assertIn(portstr, self.pbm.dispatchers)
- disp = self.pbm.dispatchers[portstr]
- self.assertIn('boris', disp.users)
- self.assertIn('ivona', disp.users)
-
- d = reg1.unregister()
- def check_boris_gone(_):
- self.assertEqual(len(self.pbm.dispatchers), 1)
- self.assertIn(portstr, self.pbm.dispatchers)
- disp = self.pbm.dispatchers[portstr]
- self.assertNotIn('boris', disp.users)
- self.assertIn('ivona', disp.users)
- d.addCallback(check_boris_gone)
- d.addCallback(lambda _ : reg2.unregister())
- def check_dispatcher_gone(_):
- self.assertEqual(len(self.pbm.dispatchers), 0)
- d.addCallback(check_dispatcher_gone)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py
deleted file mode 100644
index ff45c907..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.application import service
-from buildbot.process.botmaster import BotMaster
-from buildbot.process import factory
-from buildbot import config, interfaces
-from buildbot.test.fake import fakemaster
-
-class TestCleanShutdown(unittest.TestCase):
- def setUp(self):
- self.botmaster = BotMaster(mock.Mock())
- self.reactor = mock.Mock()
- self.botmaster.startService()
-
- def assertReactorStopped(self, _=None):
- self.assertTrue(self.reactor.stop.called)
-
- def assertReactorNotStopped(self, _=None):
- self.assertFalse(self.reactor.stop.called)
-
- def makeFakeBuild(self):
- self.fake_builder = builder = mock.Mock()
- build = mock.Mock()
- builder.builder_status.getCurrentBuilds.return_value = [build]
-
- self.build_deferred = defer.Deferred()
- build.waitUntilFinished.return_value = self.build_deferred
-
- self.botmaster.builders = mock.Mock()
- self.botmaster.builders.values.return_value = [builder]
-
- def finishFakeBuild(self):
- self.fake_builder.builder_status.getCurrentBuilds.return_value = []
- self.build_deferred.callback(None)
-
- # tests
-
- def test_shutdown_idle(self):
- """Test that the master shuts down when it's idle"""
- self.botmaster.cleanShutdown(_reactor=self.reactor)
- self.assertReactorStopped()
-
- def test_shutdown_busy(self):
- """Test that the master shuts down after builds finish"""
- self.makeFakeBuild()
-
- self.botmaster.cleanShutdown(_reactor=self.reactor)
-
- # check that we haven't stopped yet, since there's a running build
- self.assertReactorNotStopped()
-
- # try to shut it down again, just to check that this does not fail
- self.botmaster.cleanShutdown(_reactor=self.reactor)
-
- # Now we cause the build to finish
- self.finishFakeBuild()
-
- # And now we should be stopped
- self.assertReactorStopped()
-
- def test_shutdown_cancel_not_shutting_down(self):
- """Test that calling cancelCleanShutdown when none is in progress
- works"""
- # this just shouldn't fail..
- self.botmaster.cancelCleanShutdown()
-
- def test_shutdown_cancel(self):
- """Test that we can cancel a shutdown"""
- self.makeFakeBuild()
-
- self.botmaster.cleanShutdown(_reactor=self.reactor)
-
- # Next we check that we haven't stopped yet, since there's a running
- # build.
- self.assertReactorNotStopped()
-
- # but the BuildRequestDistributor should not be running
- self.assertFalse(self.botmaster.brd.running)
-
- # Cancel the shutdown
- self.botmaster.cancelCleanShutdown()
-
- # Now we cause the build to finish
- self.finishFakeBuild()
-
- # We should still be running!
- self.assertReactorNotStopped()
-
- # and the BuildRequestDistributor should be, as well
- self.assertTrue(self.botmaster.brd.running)
-
-
-class FakeBuildSlave(config.ReconfigurableServiceMixin, service.Service):
-
- implements(interfaces.IBuildSlave)
-
- reconfig_count = 0
-
- def __init__(self, slavename):
- self.slavename = slavename
-
- def reconfigService(self, new_config):
- self.reconfig_count += 1
- return defer.succeed(None)
-
-
-class FakeBuildSlave2(FakeBuildSlave):
- pass
-
-
-class TestBotMaster(unittest.TestCase):
-
- def setUp(self):
- self.master = fakemaster.make_master()
- self.botmaster = BotMaster(self.master)
- self.new_config = mock.Mock()
- self.botmaster.startService()
-
- def tearDown(self):
- return self.botmaster.stopService()
-
- def test_reconfigService(self):
- # check that reconfigServiceSlaves and reconfigServiceBuilders are
- # both called; they will be tested invidually below
- self.patch(self.botmaster, 'reconfigServiceBuilders',
- mock.Mock(side_effect=lambda c : defer.succeed(None)))
- self.patch(self.botmaster, 'reconfigServiceSlaves',
- mock.Mock(side_effect=lambda c : defer.succeed(None)))
- self.patch(self.botmaster, 'maybeStartBuildsForAllBuilders',
- mock.Mock())
-
- old_config, new_config = mock.Mock(), mock.Mock()
- d = self.botmaster.reconfigService(new_config)
- @d.addCallback
- def check(_):
- self.botmaster.reconfigServiceBuilders.assert_called_with(
- new_config)
- self.botmaster.reconfigServiceSlaves.assert_called_with(
- new_config)
- self.assertTrue(
- self.botmaster.maybeStartBuildsForAllBuilders.called)
- return d
-
- @defer.inlineCallbacks
- def test_reconfigServiceSlaves_add_remove(self):
- sl = FakeBuildSlave('sl1')
- self.new_config.slaves = [ sl ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- self.assertIdentical(sl.parent, self.botmaster)
- self.assertEqual(self.botmaster.slaves, { 'sl1' : sl })
-
- self.new_config.slaves = [ ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- self.assertIdentical(sl.parent, None)
- self.assertIdentical(sl.master, None)
-
- @defer.inlineCallbacks
- def test_reconfigServiceSlaves_reconfig(self):
- sl = FakeBuildSlave('sl1')
- self.botmaster.slaves = dict(sl1=sl)
- sl.setServiceParent(self.botmaster)
- sl.master = self.master
- sl.botmaster = self.botmaster
-
- sl_new = FakeBuildSlave('sl1')
- self.new_config.slaves = [ sl_new ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- # sl was not replaced..
- self.assertIdentical(self.botmaster.slaves['sl1'], sl)
-
- @defer.inlineCallbacks
- def test_reconfigServiceSlaves_class_changes(self):
- sl = FakeBuildSlave('sl1')
- self.botmaster.slaves = dict(sl1=sl)
- sl.setServiceParent(self.botmaster)
- sl.master = self.master
- sl.botmaster = self.botmaster
-
- sl_new = FakeBuildSlave2('sl1')
- self.new_config.slaves = [ sl_new ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- # sl *was* replaced (different class)
- self.assertIdentical(self.botmaster.slaves['sl1'], sl_new)
-
- @defer.inlineCallbacks
- def test_reconfigServiceBuilders_add_remove(self):
- bc = config.BuilderConfig(name='bldr', factory=factory.BuildFactory(),
- slavename='f')
- self.new_config.builders = [ bc ]
-
- yield self.botmaster.reconfigServiceBuilders(self.new_config)
-
- bldr = self.botmaster.builders['bldr']
- self.assertIdentical(bldr.parent, self.botmaster)
- self.assertIdentical(bldr.master, self.master)
- self.assertEqual(self.botmaster.builderNames, [ 'bldr' ])
-
- self.new_config.builders = [ ]
-
- yield self.botmaster.reconfigServiceBuilders(self.new_config)
-
- self.assertIdentical(bldr.parent, None)
- self.assertIdentical(bldr.master, None)
- self.assertEqual(self.botmaster.builders, {})
- self.assertEqual(self.botmaster.builderNames, [])
-
- def test_maybeStartBuildsForBuilder(self):
- brd = self.botmaster.brd = mock.Mock()
-
- self.botmaster.maybeStartBuildsForBuilder('frank')
-
- brd.maybeStartBuildsOn.assert_called_once_with(['frank'])
-
- def test_maybeStartBuildsForSlave(self):
- brd = self.botmaster.brd = mock.Mock()
- b1 = mock.Mock(name='frank')
- b1.name = 'frank'
- b2 = mock.Mock(name='larry')
- b2.name = 'larry'
- self.botmaster.getBuildersForSlave = mock.Mock(return_value=[b1, b2])
-
- self.botmaster.maybeStartBuildsForSlave('centos')
-
- self.botmaster.getBuildersForSlave.assert_called_once_with('centos')
- brd.maybeStartBuildsOn.assert_called_once_with(['frank', 'larry'])
-
- def test_maybeStartBuildsForAll(self):
- brd = self.botmaster.brd = mock.Mock()
- self.botmaster.builderNames = ['frank', 'larry']
-
- self.botmaster.maybeStartBuildsForAllBuilders()
-
- brd.maybeStartBuildsOn.assert_called_once_with(['frank', 'larry'])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py
deleted file mode 100644
index 34e5af1e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.python import failure, log
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, task
-from twisted.spread import pb
-from buildbot.test.util import compat
-from buildbot.process import botmaster
-from buildbot.util.eventual import eventually
-
-# TODO: should do this with more of the Twisted machinery intact - maybe in a
-# separate integration test?
-
-class FakeAbstractBuildSlave(object):
-
- def __init__(self, slave, name, isConnected=True, reactor=reactor):
- self.slavename = name
- self.slave = slave
- self.isConnectedResult = isConnected
- self.reactor = reactor
- self.call_on_detach = lambda : None
-
- # set up for loseConnection to cause the slave to detach, but not
- # immediately
- def tport_loseConnection():
- self.isConnectedResult = False
- self.call_on_detach()
- self.call_on_detach = None
- self.slave.broker.transport.loseConnection = (lambda :
- eventually(tport_loseConnection))
-
- def subscribeToDetach(self, callback):
- self.call_on_detach = callback
-
- def isConnected(self):
- return self.isConnectedResult
-
-
-class FakeRemoteBuildSlave(object):
-
- def __init__(self, name, callRemoteFailure=False,
- callRemoteException=False,
- callRemoteHang=0,
- reactor=reactor):
- self.name = name
- self.callRemoteFailure = callRemoteFailure
- self.callRemoteException = callRemoteException
- self.callRemoteHang = callRemoteHang
- self.reactor = reactor
-
- self.broker = mock.Mock()
- self.broker.transport.getPeer = lambda : "<peer %s>" % name
-
- def _makePingResult(self):
- if self.callRemoteException:
- exc = self.callRemoteException()
- log.msg(" -> exception %r" % (exc,))
- raise exc
- if self.callRemoteFailure:
- f = defer.fail(self.callRemoteFailure())
- log.msg(" -> failure %r" % (f,))
- return f
- return defer.succeed(None)
-
- def callRemote(self, meth, *args, **kwargs):
- assert meth == "print"
- log.msg("%r.callRemote('print', %r)" % (self, args[0],))
- # if we're asked to hang, then set up to fire the deferred later
- if self.callRemoteHang:
- log.msg(" -> hang for %d s" % (self.callRemoteHang,))
- d = defer.Deferred()
- self.reactor.callLater(self.callRemoteHang, d.callback, None)
- def hangdone(_):
- log.msg("%r.callRemote hang finished" % (self,))
- return self._makePingResult()
- d.addCallback(hangdone)
- self.callRemote_d = d
- # otherwise, return a fired deferred
- else:
- self.callRemote_d = self._makePingResult()
- return self.callRemote_d
-
- def __repr__(self):
- return "<FakeRemoteBuildSlave %s>" % (self.name,)
-
-
-class DuplicateSlaveArbitrator(unittest.TestCase):
-
- def makeDeadReferenceError(self):
- return pb.DeadReferenceError("Calling Stale Broker (fake exception)")
-
- def makeRuntimeError(self):
- return RuntimeError("oh noes!")
-
- def makePBConnectionLostFailure(self):
- return failure.Failure(pb.PBConnectionLost("gone"))
-
- def test_old_slave_present(self):
- old_remote = FakeRemoteBuildSlave("old")
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.fail("shouldn't get here")
- def failed(f):
- f.trap(RuntimeError) # expected error
- d.addCallbacks(got_persp, failed)
- return d
-
- def test_old_slave_absent_deadref_exc(self):
- old_remote = FakeRemoteBuildSlave("old",
- callRemoteException=self.makeDeadReferenceError)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.assertIdentical(bs, buildslave)
- d.addCallback(got_persp)
- return d
-
- def test_old_slave_absent_connlost_failure(self):
- old_remote = FakeRemoteBuildSlave("old",
- callRemoteFailure=self.makePBConnectionLostFailure)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.assertIdentical(bs, buildslave)
- d.addCallback(got_persp)
- return d
-
- @compat.usesFlushLoggedErrors
- def test_old_slave_absent_unexpected_exc(self):
- old_remote = FakeRemoteBuildSlave("old",
- callRemoteException=self.makeRuntimeError)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- # getPerspective has returned successfully:
- self.assertIdentical(bs, buildslave)
- # and the unexpected RuntimeError was logged:
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(got_persp)
- return d
-
- def do_test_old_slave_absent_timeout(self, callRemoteException=None):
- clock = task.Clock()
- PING_TIMEOUT = botmaster.DuplicateSlaveArbitrator.PING_TIMEOUT
-
- old_remote = FakeRemoteBuildSlave("old", reactor=clock,
- callRemoteHang=PING_TIMEOUT+1,
- callRemoteException=callRemoteException)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave",
- reactor=clock)
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- arb._reactor = clock
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.assertIdentical(bs, buildslave)
- d.addCallback(got_persp)
-
- # show the passage of time for 2s more than the PING_TIMEOUT, to allow
- # the old callRemote to return eventually
- clock.pump([.1] * 10 * (PING_TIMEOUT+4))
-
- # check that the timed-out call eventually returned (and was ignored,
- # even if there was an exception)
- self.failUnless(old_remote.callRemote_d.called)
-
- return d
-
- def test_old_slave_absent_timeout(self):
- return self.do_test_old_slave_absent_timeout()
-
- def test_old_slave_absent_timeout_exc(self):
- return self.do_test_old_slave_absent_timeout(
- callRemoteException=self.makeRuntimeError)
-
- @compat.usesFlushLoggedErrors
- def test_new_slave_ping_error(self):
- old_remote = FakeRemoteBuildSlave("old")
- new_remote = FakeRemoteBuildSlave("new",
- callRemoteException=self.makeRuntimeError)
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.fail("shouldn't get here")
- def failed(f):
- pass #f.trap(RuntimeError) # expected error
- d.addCallbacks(got_persp, failed)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py
deleted file mode 100644
index 784ea172..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py
+++ /dev/null
@@ -1,823 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import interfaces
-from buildbot.process.build import Build
-from buildbot.process.properties import Properties
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, RETRY, EXCEPTION
-from buildbot.locks import SlaveLock
-from buildbot.process.buildstep import LoggingBuildStep
-from buildbot.test.fake.fakemaster import FakeBotMaster
-from buildbot import config
-
-from mock import Mock
-
-class FakeChange:
- properties = Properties()
- def __init__(self, number = None):
- self.number = number
- self.who = "me"
-
-class FakeSource:
- def __init__(self):
- self.sourcestampsetid = None
- self.changes = []
- self.branch = None
- self.revision = None
- self.repository = ''
- self.codebase = ''
- self.project = ''
- self.patch_info = None
- self.patch = None
-
- def getRepository(self):
- return self.repository
-
-class FakeRequest:
- def __init__(self):
- self.sources = []
- self.reason = "Because"
- self.properties = Properties()
-
- def mergeSourceStampsWith(self, others):
- return self.sources
-
- def mergeReasons(self, others):
- return self.reason
-
-class FakeBuildStep:
- def __init__(self):
- self.haltOnFailure = False
- self.flunkOnWarnings = False
- self.flunkOnFailure = True
- self.warnOnWarnings = True
- self.warnOnFailure = False
- self.alwaysRun = False
- self.name = 'fake'
-
-class FakeMaster:
- def __init__(self):
- self.locks = {}
- self.parent = Mock()
- self.config = config.MasterConfig()
-
- def getLockByID(self, lockid):
- if not lockid in self.locks:
- self.locks[lockid] = lockid.lockClass(lockid)
- return self.locks[lockid]
-
-class FakeBuildStatus(Mock):
- implements(interfaces.IProperties)
-
-class FakeBuilderStatus:
- implements(interfaces.IBuilderStatus)
-
-class FakeStepFactory(object):
- """Fake step factory that just returns a fixed step object."""
- implements(interfaces.IBuildStepFactory)
- def __init__(self, step):
- self.step = step
-
- def buildStep(self):
- return self.step
-
-class TestBuild(unittest.TestCase):
-
- def setUp(self):
- r = FakeRequest()
- r.sources = [FakeSource()]
- r.sources[0].changes = [FakeChange()]
- r.sources[0].revision = "12345"
-
- self.request = r
- self.master = FakeMaster()
-
- self.master.botmaster = FakeBotMaster(master=self.master)
-
- self.builder = self.createBuilder()
- self.build = Build([r])
- self.build.setBuilder(self.builder)
-
- def createBuilder(self):
- bldr = Mock()
- bldr.botmaster = self.master.botmaster
- return bldr
-
- def testRunSuccessfulBuild(self):
- b = self.build
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- b.setStepFactories([FakeStepFactory(step)])
-
- slavebuilder = Mock()
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(b.result, SUCCESS)
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- in step.method_calls)
-
- def testStopBuild(self):
- b = self.build
-
- step = Mock()
- step.return_value = step
- b.setStepFactories([FakeStepFactory(step)])
-
- slavebuilder = Mock()
-
- def startStep(*args, **kw):
- # Now interrupt the build
- b.stopBuild("stop it")
- return defer.Deferred()
- step.startStep = startStep
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(b.result, EXCEPTION)
-
- self.assert_( ('interrupt', ('stop it',), {}) in step.method_calls)
-
- def testAlwaysRunStepStopBuild(self):
- """Test that steps marked with alwaysRun=True still get run even if
- the build is stopped."""
-
- # Create a build with 2 steps, the first one will get interrupted, and
- # the second one is marked with alwaysRun=True
- b = self.build
-
- step1 = Mock()
- step1.return_value = step1
- step1.alwaysRun = False
- step2 = Mock()
- step2.return_value = step2
- step2.alwaysRun = True
- b.setStepFactories([
- FakeStepFactory(step1),
- FakeStepFactory(step2),
- ])
-
- slavebuilder = Mock()
-
- def startStep1(*args, **kw):
- # Now interrupt the build
- b.stopBuild("stop it")
- return defer.succeed( SUCCESS )
- step1.startStep = startStep1
- step1.stepDone.return_value = False
-
- step2Started = [False]
- def startStep2(*args, **kw):
- step2Started[0] = True
- return defer.succeed( SUCCESS )
- step2.startStep = startStep2
- step1.stepDone.return_value = False
-
- d = b.startBuild(FakeBuildStatus(), None, slavebuilder)
- def check(ign):
- self.assertEqual(b.result, EXCEPTION)
- self.assert_( ('interrupt', ('stop it',), {}) in step1.method_calls)
- self.assert_(step2Started[0])
- d.addCallback(check)
- return d
-
- def testBuildcanStartWithSlavebuilder(self):
- b = self.build
-
- slavebuilder1 = Mock()
- slavebuilder2 = Mock()
-
- l = SlaveLock('lock')
- counting_access = l.access('counting')
- real_lock = b.builder.botmaster.getLockByID(l)
-
- # no locks, so both these pass (call twice to verify there's no state/memory)
- lock_list = [(real_lock, counting_access)]
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
-
- slave_lock_1 = real_lock.getLock(slavebuilder1.slave)
- slave_lock_2 = real_lock.getLock(slavebuilder2.slave)
-
- # then have slavebuilder2 claim its lock:
- slave_lock_2.claim(slavebuilder2, counting_access)
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- slave_lock_2.release(slavebuilder2, counting_access)
-
- # then have slavebuilder1 claim its lock:
- slave_lock_1.claim(slavebuilder1, counting_access)
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- slave_lock_1.release(slavebuilder1, counting_access)
-
-
- def testBuildLocksAcquired(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- claimCount = [0]
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder.slave)
- def claim(owner, access):
- claimCount[0] += 1
- return real_lock.old_claim(owner, access)
- real_lock.old_claim = real_lock.claim
- real_lock.claim = claim
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- b.setStepFactories([FakeStepFactory(step)])
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(b.result, SUCCESS)
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- in step.method_calls)
- self.assertEquals(claimCount[0], 1)
-
- def testBuildLocksOrder(self):
- """Test that locks are acquired in FIFO order; specifically that
- counting locks cannot jump ahead of exclusive locks"""
- eBuild = self.build
-
- cBuilder = self.createBuilder()
- cBuild = Build([self.request])
- cBuild.setBuilder(cBuilder)
-
- eSlavebuilder = Mock()
- cSlavebuilder = Mock()
-
- slave = eSlavebuilder.slave
- cSlavebuilder.slave = slave
-
- l = SlaveLock('lock', 2)
- claimLog = []
- realLock = self.master.botmaster.getLockByID(l).getLock(slave)
- def claim(owner, access):
- claimLog.append(owner)
- return realLock.oldClaim(owner, access)
- realLock.oldClaim = realLock.claim
- realLock.claim = claim
-
- eBuild.setLocks([l.access('exclusive')])
- cBuild.setLocks([l.access('counting')])
-
- fakeBuild = Mock()
- fakeBuildAccess = l.access('counting')
- realLock.claim(fakeBuild, fakeBuildAccess)
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- eBuild.setStepFactories([FakeStepFactory(step)])
- cBuild.setStepFactories([FakeStepFactory(step)])
-
- e = eBuild.startBuild(FakeBuildStatus(), None, eSlavebuilder)
- c = cBuild.startBuild(FakeBuildStatus(), None, cSlavebuilder)
- d = defer.DeferredList([e, c])
-
- realLock.release(fakeBuild, fakeBuildAccess)
-
- def check(ign):
- self.assertEqual(eBuild.result, SUCCESS)
- self.assertEqual(cBuild.result, SUCCESS)
- self.assertEquals(claimLog, [fakeBuild, eBuild, cBuild])
-
- d.addCallback(check)
- return d
-
- def testBuildWaitingForLocks(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- claimCount = [0]
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder.slave)
- def claim(owner, access):
- claimCount[0] += 1
- return real_lock.old_claim(owner, access)
- real_lock.old_claim = real_lock.claim
- real_lock.claim = claim
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- not in step.method_calls)
- self.assertEquals(claimCount[0], 1)
- self.assert_(b.currentStep is None)
- self.assert_(b._acquiringLock is not None)
-
- def testStopBuildWaitingForLocks(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- step.alwaysRun = False
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- def acquireLocks(res=None):
- retval = Build.acquireLocks(b, res)
- b.stopBuild('stop it')
- return retval
- b.acquireLocks = acquireLocks
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- not in step.method_calls)
- self.assert_(b.currentStep is None)
- self.assertEqual(b.result, EXCEPTION)
- self.assert_( ('interrupt', ('stop it',), {}) not in step.method_calls)
-
- def testStopBuildWaitingForLocks_lostRemote(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- step.alwaysRun = False
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- def acquireLocks(res=None):
- retval = Build.acquireLocks(b, res)
- b.lostRemote()
- return retval
- b.acquireLocks = acquireLocks
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- not in step.method_calls)
- self.assert_(b.currentStep is None)
- self.assertEqual(b.result, RETRY)
- self.assert_( ('interrupt', ('stop it',), {}) not in step.method_calls)
- self.build.build_status.setText.assert_called_with(["retry", "lost", "remote"])
- self.build.build_status.setResults.assert_called_with(RETRY)
-
- def testStopBuildWaitingForStepLocks(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
-
- step = LoggingBuildStep(locks=[lock_access])
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- gotLocks = [False]
-
- def acquireLocks(res=None):
- gotLocks[0] = True
- retval = LoggingBuildStep.acquireLocks(step, res)
- self.assert_(b.currentStep is step)
- b.stopBuild('stop it')
- return retval
- step.acquireLocks = acquireLocks
- step.setStepStatus = Mock()
- step.step_status = Mock()
- step.step_status.addLog().chunkSize = 10
- step.step_status.getLogs.return_value = []
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(gotLocks, [True])
- self.assert_(('stepStarted', (), {}) in step.step_status.method_calls)
- self.assertEqual(b.result, EXCEPTION)
-
- def testStepDone(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(SUCCESS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, SUCCESS)
-
- def testStepDoneHaltOnFailure(self):
- b = self.build
- b.results = []
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.haltOnFailure = True
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, True)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneHaltOnFailureNoFlunkOnFailure(self):
- b = self.build
- b.results = []
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnFailure = False
- step.haltOnFailure = True
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, True)
- self.assertEqual(b.result, SUCCESS)
-
- def testStepDoneFlunkOnWarningsFlunkOnFailure(self):
- b = self.build
- b.results = []
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnFailure = True
- step.flunkOnWarnings = True
- b.stepDone(WARNINGS, step)
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneNoWarnOnWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.warnOnWarnings = False
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, SUCCESS)
-
- def testStepDoneWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, WARNINGS)
-
- def testStepDoneFail(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneFailOverridesWarnings(self):
- b = self.build
- b.results = [SUCCESS, WARNINGS]
- b.result = WARNINGS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneWarnOnFailure(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.warnOnFailure = True
- step.flunkOnFailure = False
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, WARNINGS)
-
- def testStepDoneFlunkOnWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnWarnings = True
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneHaltOnFailureFlunkOnWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnWarnings = True
- self.haltOnFailure = True
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneWarningsDontOverrideFailure(self):
- b = self.build
- b.results = [FAILURE]
- b.result = FAILURE
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneRetryOverridesAnythingElse(self):
- b = self.build
- b.results = [RETRY]
- b.result = RETRY
- b.remote = Mock()
- step = FakeBuildStep()
- step.alwaysRun = True
- b.stepDone(WARNINGS, step)
- b.stepDone(FAILURE, step)
- b.stepDone(SUCCESS, step)
- terminate = b.stepDone(EXCEPTION, step)
- self.assertEqual(terminate, True)
- self.assertEqual(b.result, RETRY)
-
-class TestMultipleSourceStamps(unittest.TestCase):
-
- def setUp(self):
- r = FakeRequest()
- s1 = FakeSource()
- s1.repository = "repoA"
- s1.codebase = "A"
- s1.changes = [FakeChange(10), FakeChange(11)]
- s1.revision = "12345"
- s2 = FakeSource()
- s2.repository = "repoB"
- s2.codebase = "B"
- s2.changes = [FakeChange(12),FakeChange(13)]
- s2.revision = "67890"
- s3 = FakeSource()
- s3.repository = "repoC"
- # no codebase defined
- s3.changes = [FakeChange(14),FakeChange(15)]
- s3.revision = "111213"
- r.sources.extend([s1,s2,s3])
-
- self.build = Build([r])
-
- def test_buildReturnSourceStamp(self):
- """
- Test that a build returns the correct sourcestamp
- """
- source1 = self.build.getSourceStamp("A")
- source2 = self.build.getSourceStamp("B")
-
- self.assertEqual( [source1.repository, source1.revision], ["repoA", "12345"])
- self.assertEqual( [source2.repository, source2.revision], ["repoB", "67890"])
-
- def test_buildReturnSourceStamp_empty_codebase(self):
- """
- Test that a build returns the correct sourcestamp if codebase is empty
- """
- codebase = ''
- source3 = self.build.getSourceStamp(codebase)
- self.assertTrue(source3 is not None)
- self.assertEqual( [source3.repository, source3.revision], ["repoC", "111213"])
-
-
-class TestBuildBlameList(unittest.TestCase):
-
- def setUp(self):
- self.sourceByMe = FakeSource()
- self.sourceByMe.repository = "repoA"
- self.sourceByMe.codebase = "A"
- self.sourceByMe.changes = [FakeChange(10), FakeChange(11)]
- self.sourceByMe.changes[0].who = "me"
- self.sourceByMe.changes[1].who = "me"
-
- self.sourceByHim = FakeSource()
- self.sourceByHim.repository = "repoB"
- self.sourceByHim.codebase = "B"
- self.sourceByHim.changes = [FakeChange(12), FakeChange(13)]
- self.sourceByHim.changes[0].who = "him"
- self.sourceByHim.changes[1].who = "him"
-
- self.patchSource = FakeSource()
- self.patchSource.repository = "repoB"
- self.patchSource.codebase = "B"
- self.patchSource.changes = []
- self.patchSource.revision = "67890"
- self.patchSource.patch_info = ("jeff", "jeff's new feature")
-
- def test_blamelist_for_changes(self):
- r = FakeRequest()
- r.sources.extend([self.sourceByMe, self.sourceByHim])
- build = Build([r])
- blamelist = build.blamelist()
- self.assertEqual(blamelist, ['him', 'me'])
-
- def test_blamelist_for_patch(self):
- r = FakeRequest()
- r.sources.extend([self.patchSource])
- build = Build([r])
- blamelist = build.blamelist()
- self.assertEqual(blamelist, ['jeff'])
-
-class TestSetupProperties_MultipleSources(unittest.TestCase):
- """
- Test that the property values, based on the available requests, are
- initialized properly
- """
- def setUp(self):
- self.props = {}
- r = FakeRequest()
- r.sources = []
- r.sources.append(FakeSource())
- r.sources[0].changes = [FakeChange()]
- r.sources[0].repository = "http://svn-repo-A"
- r.sources[0].codebase = "A"
- r.sources[0].branch = "develop"
- r.sources[0].revision = "12345"
- r.sources.append(FakeSource())
- r.sources[1].changes = [FakeChange()]
- r.sources[1].repository = "http://svn-repo-B"
- r.sources[1].codebase = "B"
- r.sources[1].revision = "34567"
- self.build = Build([r])
- self.build.setStepFactories([])
- self.builder = Mock()
- self.build.setBuilder(self.builder)
- self.build.build_status = FakeBuildStatus()
- # record properties that will be set
- self.build.build_status.setProperty = self.setProperty
-
- def setProperty(self, n,v,s, runtime = False):
- if s not in self.props:
- self.props[s] = {}
- if not self.props[s]:
- self.props[s] = {}
- self.props[s][n] = v
-
- def test_sourcestamp_properties_not_set(self):
- self.build.setupProperties()
- self.assertTrue("codebase" not in self.props["Build"])
- self.assertTrue("revision" not in self.props["Build"])
- self.assertTrue("branch" not in self.props["Build"])
- self.assertTrue("project" not in self.props["Build"])
- self.assertTrue("repository" not in self.props["Build"])
-
-class TestSetupProperties_SingleSource(unittest.TestCase):
- """
- Test that the property values, based on the available requests, are
- initialized properly
- """
- def setUp(self):
- self.props = {}
- r = FakeRequest()
- r.sources = []
- r.sources.append(FakeSource())
- r.sources[0].changes = [FakeChange()]
- r.sources[0].repository = "http://svn-repo-A"
- r.sources[0].codebase = "A"
- r.sources[0].branch = "develop"
- r.sources[0].revision = "12345"
- self.build = Build([r])
- self.build.setStepFactories([])
- self.builder = Mock()
- self.build.setBuilder(self.builder)
- self.build.build_status = FakeBuildStatus()
- # record properties that will be set
- self.build.build_status.setProperty = self.setProperty
-
- def setProperty(self, n,v,s, runtime = False):
- if s not in self.props:
- self.props[s] = {}
- if not self.props[s]:
- self.props[s] = {}
- self.props[s][n] = v
-
- def test_properties_codebase(self):
- self.build.setupProperties()
- codebase = self.props["Build"]["codebase"]
- self.assertEqual(codebase, "A")
-
- def test_properties_repository(self):
- self.build.setupProperties()
- repository = self.props["Build"]["repository"]
- self.assertEqual(repository, "http://svn-repo-A")
-
- def test_properties_revision(self):
- self.build.setupProperties()
- revision = self.props["Build"]["revision"]
- self.assertEqual(revision, "12345")
-
- def test_properties_branch(self):
- self.build.setupProperties()
- branch = self.props["Build"]["branch"]
- self.assertEqual(branch, "develop")
-
- def test_property_project(self):
- self.build.setupProperties()
- project = self.props["Build"]["project"]
- self.assertEqual(project, '')
-
-class TestBuildProperties(unittest.TestCase):
- """
- Test that a Build has the necessary L{IProperties} methods, and that they
- properly delegate to the C{build_status} attribute - so really just a test
- of the L{IProperties} adapter.
- """
-
- def setUp(self):
- r = FakeRequest()
- r.sources = [FakeSource()]
- r.sources[0].changes = [FakeChange()]
- r.sources[0].revision = "12345"
- self.build = Build([r])
- self.build.setStepFactories([])
- self.builder = Mock()
- self.build.setBuilder(self.builder)
- self.build_status = FakeBuildStatus()
- self.build.startBuild(self.build_status, None, Mock())
-
- def test_getProperty(self):
- self.build.getProperty('x')
- self.build_status.getProperty.assert_called_with('x', None)
-
- def test_getProperty_default(self):
- self.build.getProperty('x', 'nox')
- self.build_status.getProperty.assert_called_with('x', 'nox')
-
- def test_setProperty(self):
- self.build.setProperty('n', 'v', 's')
- self.build_status.setProperty.assert_called_with('n', 'v', 's',
- runtime=True)
-
- def test_hasProperty(self):
- self.build_status.hasProperty.return_value = True
- self.assertTrue(self.build.hasProperty('p'))
- self.build_status.hasProperty.assert_called_with('p')
-
- def test_has_key(self):
- self.build_status.has_key.return_value = True
- self.assertTrue(self.build.has_key('p'))
- # has_key calls through to hasProperty
- self.build_status.hasProperty.assert_called_with('p')
-
- def test_render(self):
- self.build.render("xyz")
- self.build_status.render.assert_called_with("xyz")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py
deleted file mode 100644
index 462b5694..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py
+++ /dev/null
@@ -1,427 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-import random
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot.process import builder, factory
-from buildbot.util import epoch2datetime
-
-class BuilderMixin(object):
- def makeBuilder(self, name="bldr", patch_random=False, **config_kwargs):
- """Set up C{self.bldr}"""
- self.factory = factory.BuildFactory()
- self.master = fakemaster.make_master()
- # only include the necessary required config, plus user-requested
- config_args = dict(name=name, slavename="slv", builddir="bdir",
- slavebuilddir="sbdir", factory=self.factory)
- config_args.update(config_kwargs)
- self.builder_config = config.BuilderConfig(**config_args)
- self.bldr = builder.Builder(self.builder_config.name, _addServices=False)
- self.master.db = self.db = fakedb.FakeDBConnector(self)
- self.bldr.master = self.master
- self.bldr.botmaster = self.master.botmaster
-
- # patch into the _startBuildsFor method
- self.builds_started = []
- def _startBuildFor(slavebuilder, buildrequests):
- self.builds_started.append((slavebuilder, buildrequests))
- return defer.succeed(True)
- self.bldr._startBuildFor = _startBuildFor
-
- if patch_random:
- # patch 'random.choice' to always take the slave that sorts
- # last, based on its name
- self.patch(random, "choice",
- lambda lst : sorted(lst, key=lambda m : m.name)[-1])
-
- self.bldr.startService()
-
- mastercfg = config.MasterConfig()
- mastercfg.builders = [ self.builder_config ]
- return self.bldr.reconfigService(mastercfg)
-
-class TestBuilderBuildCreation(BuilderMixin, unittest.TestCase):
-
- def setUp(self):
- # a collection of rows that would otherwise clutter up every test
- self.base_rows = [
- fakedb.SourceStampSet(id=21),
- fakedb.SourceStamp(id=21, sourcestampsetid=21),
- fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
- ]
-
- def makeBuilder(self, patch_random=False, startBuildsForSucceeds=True, **config_kwargs):
- d = BuilderMixin.makeBuilder(self, patch_random=patch_random, **config_kwargs)
- @d.addCallback
- def patch_startBuildsFor(_):
- # patch into the _startBuildsFor method
- self.builds_started = []
- def _startBuildFor(slavebuilder, buildrequests):
- self.builds_started.append((slavebuilder, buildrequests))
- return defer.succeed(startBuildsForSucceeds)
- self.bldr._startBuildFor = _startBuildFor
- return d
-
- def assertBuildsStarted(self, exp):
- # munge builds_started into a list of (slave, [brids])
- builds_started = [
- (sl.name, [ br.id for br in buildreqs ])
- for (sl, buildreqs) in self.builds_started ]
- self.assertEqual(sorted(builds_started), sorted(exp))
-
- def setSlaveBuilders(self, slavebuilders):
- """C{slaves} maps name : available"""
- self.bldr.slaves = []
- for name, avail in slavebuilders.iteritems():
- sb = mock.Mock(spec=['isAvailable'], name=name)
- sb.name = name
- sb.isAvailable.return_value = avail
- self.bldr.slaves.append(sb)
-
- # services
-
- @defer.inlineCallbacks
- def test_maybeStartBuild_builder_stopped(self):
- yield self.makeBuilder()
-
- # this will cause an exception if maybeStartBuild tries to start
- self.bldr.slaves = None
-
- # so we just hope this does not fail
- yield self.bldr.stopService()
- started = yield self.bldr.maybeStartBuild(None, [])
- self.assertEquals(started, False)
-
-
- # maybeStartBuild
-
- def _makeMocks(self):
- slave = mock.Mock()
- slave.name = 'slave'
- buildrequest = mock.Mock()
- buildrequest.id = 10
- buildrequests = [buildrequest]
- return slave, buildrequests
-
- @defer.inlineCallbacks
- def test_maybeStartBuild(self):
- yield self.makeBuilder()
-
- slave, buildrequests = self._makeMocks()
-
- started = yield self.bldr.maybeStartBuild(slave, buildrequests)
- self.assertEqual(started, True)
- self.assertBuildsStarted([('slave', [10])])
-
- @defer.inlineCallbacks
- def test_maybeStartBuild_failsToStart(self):
- yield self.makeBuilder(startBuildsForSucceeds=False)
-
- slave, buildrequests = self._makeMocks()
-
- started = yield self.bldr.maybeStartBuild(slave, buildrequests)
- self.assertEqual(started, False)
- self.assertBuildsStarted([('slave', [10])])
-
- @defer.inlineCallbacks
- def do_test_getMergeRequestsFn(self, builder_param=None,
- global_param=None, expected=0):
- cble = lambda : None
- builder_param = builder_param == 'callable' and cble or builder_param
- global_param = global_param == 'callable' and cble or global_param
-
- # omit the constructor parameter if None was given
- if builder_param is None:
- yield self.makeBuilder()
- else:
- yield self.makeBuilder(mergeRequests=builder_param)
-
- self.master.config.mergeRequests = global_param
-
- fn = self.bldr.getMergeRequestsFn()
-
- if fn == builder.Builder._defaultMergeRequestFn:
- fn = "default"
- elif fn is cble:
- fn = 'callable'
- self.assertEqual(fn, expected)
-
- def test_getMergeRequestsFn_defaults(self):
- self.do_test_getMergeRequestsFn(None, None, "default")
-
- def test_getMergeRequestsFn_global_True(self):
- self.do_test_getMergeRequestsFn(None, True, "default")
-
- def test_getMergeRequestsFn_global_False(self):
- self.do_test_getMergeRequestsFn(None, False, None)
-
- def test_getMergeRequestsFn_global_function(self):
- self.do_test_getMergeRequestsFn(None, 'callable', 'callable')
-
- def test_getMergeRequestsFn_builder_True(self):
- self.do_test_getMergeRequestsFn(True, False, "default")
-
- def test_getMergeRequestsFn_builder_False(self):
- self.do_test_getMergeRequestsFn(False, True, None)
-
- def test_getMergeRequestsFn_builder_function(self):
- self.do_test_getMergeRequestsFn('callable', None, 'callable')
-
-
- # other methods
-
- @defer.inlineCallbacks
- def test_reclaimAllBuilds_empty(self):
- yield self.makeBuilder()
-
- # just to be sure this doesn't crash
- yield self.bldr.reclaimAllBuilds()
-
- @defer.inlineCallbacks
- def test_reclaimAllBuilds(self):
- yield self.makeBuilder()
-
- claims = []
- def fakeClaimBRs(*args):
- claims.append(args)
- return defer.succeed(None)
- self.bldr.master.db.buildrequests.claimBuildRequests = fakeClaimBRs
- self.bldr.master.db.buildrequests.reclaimBuildRequests = fakeClaimBRs
-
- def mkbld(brids):
- bld = mock.Mock(name='Build')
- bld.requests = []
- for brid in brids:
- br = mock.Mock(name='BuildRequest %d' % brid)
- br.id = brid
- bld.requests.append(br)
- return bld
-
- old = mkbld([15]) # keep a reference to the "old" build
- self.bldr.old_building[old] = None
- self.bldr.building.append(mkbld([10,11,12]))
-
- yield self.bldr.reclaimAllBuilds()
-
- self.assertEqual(claims, [ (set([10,11,12,15]),) ])
-
- @defer.inlineCallbacks
- def test_canStartBuild(self):
- yield self.makeBuilder()
-
- # by default, it returns True
- startable = yield self.bldr.canStartBuild('slave', 100)
- self.assertEqual(startable, True)
-
- startable = yield self.bldr.canStartBuild('slave', 101)
- self.assertEqual(startable, True)
-
- # set a configurable one
- record = []
- def canStartBuild(bldr, slave, breq):
- record.append((bldr, slave, breq))
- return (slave,breq)==('slave',100)
- self.bldr.config.canStartBuild = canStartBuild
-
- startable = yield self.bldr.canStartBuild('slave', 100)
- self.assertEqual(startable, True)
- self.assertEqual(record, [(self.bldr, 'slave', 100)])
-
- startable = yield self.bldr.canStartBuild('slave', 101)
- self.assertEqual(startable, False)
- self.assertEqual(record, [(self.bldr, 'slave', 100), (self.bldr, 'slave', 101)])
-
- # set a configurable one to return Deferred
- record = []
- def canStartBuild_deferred(bldr, slave, breq):
- record.append((bldr, slave, breq))
- return (slave,breq)==('slave',100)
- return defer.succeed((slave,breq)==('slave',100))
- self.bldr.config.canStartBuild = canStartBuild_deferred
-
- startable = yield self.bldr.canStartBuild('slave', 100)
- self.assertEqual(startable, True)
- self.assertEqual(record, [(self.bldr, 'slave', 100)])
-
- startable = yield self.bldr.canStartBuild('slave', 101)
- self.assertEqual(startable, False)
- self.assertEqual(record, [(self.bldr, 'slave', 100), (self.bldr, 'slave', 101)])
-
- @defer.inlineCallbacks
- def test_enforceChosenSlave(self):
- """enforceChosenSlave rejects and accepts builds"""
- yield self.makeBuilder()
-
- self.bldr.config.canStartBuild = builder.enforceChosenSlave
-
- slave = mock.Mock()
- slave.slave.slavename = 'slave5'
-
- breq = mock.Mock()
-
- # no buildslave requested
- breq.properties = {}
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(True, result)
-
- # buildslave requested as the right one
- breq.properties = { 'slavename': 'slave5' }
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(True, result)
-
- # buildslave requested as the wrong one
- breq.properties = { 'slavename': 'slave4' }
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(False, result)
-
- # buildslave set to non string value gets skipped
- breq.properties = { 'slavename': 0 }
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(True, result)
-
-
-
-
-class TestGetOldestRequestTime(BuilderMixin, unittest.TestCase):
-
- def setUp(self):
- # a collection of rows that would otherwise clutter up every test
- master_id = fakedb.FakeBuildRequestsComponent.MASTER_ID
- self.base_rows = [
- fakedb.SourceStampSet(id=21),
- fakedb.SourceStamp(id=21, sourcestampsetid=21),
- fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
- fakedb.BuildRequest(id=111, submitted_at=1000,
- buildername='bldr1', buildsetid=11),
- fakedb.BuildRequest(id=222, submitted_at=2000,
- buildername='bldr1', buildsetid=11),
- fakedb.BuildRequestClaim(brid=222, objectid=master_id,
- claimed_at=2001),
- fakedb.BuildRequest(id=333, submitted_at=3000,
- buildername='bldr1', buildsetid=11),
- fakedb.BuildRequest(id=444, submitted_at=2500,
- buildername='bldr2', buildsetid=11),
- fakedb.BuildRequestClaim(brid=444, objectid=master_id,
- claimed_at=2501),
- ]
-
- def test_gort_unclaimed(self):
- d = self.makeBuilder(name='bldr1')
- d.addCallback(lambda _ : self.db.insertTestData(self.base_rows))
- d.addCallback(lambda _ : self.bldr.getOldestRequestTime())
- def check(rqtime):
- self.assertEqual(rqtime, epoch2datetime(1000))
- d.addCallback(check)
- return d
-
- def test_gort_all_claimed(self):
- d = self.makeBuilder(name='bldr2')
- d.addCallback(lambda _ : self.db.insertTestData(self.base_rows))
- d.addCallback(lambda _ : self.bldr.getOldestRequestTime())
- def check(rqtime):
- self.assertEqual(rqtime, None)
- d.addCallback(check)
- return d
-
-class TestRebuild(BuilderMixin, unittest.TestCase):
-
- def makeBuilder(self, name, sourcestamps):
- d = BuilderMixin.makeBuilder(self, name=name)
- @d.addCallback
- def setupBstatus(_):
- self.bstatus = mock.Mock()
- bstatus_properties = mock.Mock()
- bstatus_properties.properties = {}
- self.bstatus.getProperties.return_value = bstatus_properties
- self.bstatus.getSourceStamps.return_value = sourcestamps
- self.master.addBuildset = addBuildset = mock.Mock()
- addBuildset.return_value = (1, [100])
- return d
-
- @defer.inlineCallbacks
- def do_test_rebuild(self,
- sourcestampsetid,
- nr_of_sourcestamps):
-
- # Store combinations of sourcestampId and sourcestampSetId
- self.sslist = {}
- self.ssseq = 1
- def addSourceStampToDatabase(master, sourcestampsetid):
- self.sslist[self.ssseq] = sourcestampsetid
- self.ssseq += 1
- return defer.succeed(sourcestampsetid)
- def getSourceStampSetId(master):
- return addSourceStampToDatabase(master, sourcestampsetid = sourcestampsetid)
-
- sslist = []
- for x in range(nr_of_sourcestamps):
- ssx = mock.Mock()
- ssx.addSourceStampToDatabase = addSourceStampToDatabase
- ssx.getSourceStampSetId = getSourceStampSetId
- sslist.append(ssx)
-
- yield self.makeBuilder(name='bldr1', sourcestamps = sslist)
- control = mock.Mock(spec=['master'])
- control.master = self.master
- self.bldrctrl = builder.BuilderControl(self.bldr, control)
-
- yield self.bldrctrl.rebuildBuild(self.bstatus, reason = 'unit test', extraProperties = {})
-
- @defer.inlineCallbacks
- def test_rebuild_with_no_sourcestamps(self):
- yield self.do_test_rebuild(101, 0)
- self.assertEqual(self.sslist, {})
-
- @defer.inlineCallbacks
- def test_rebuild_with_single_sourcestamp(self):
- yield self.do_test_rebuild(101, 1)
- self.assertEqual(self.sslist, {1:101})
- self.master.addBuildset.assert_called_with(builderNames=['bldr1'],
- sourcestampsetid=101,
- reason = 'unit test',
- properties = {})
-
-
- @defer.inlineCallbacks
- def test_rebuild_with_multiple_sourcestamp(self):
- yield self.do_test_rebuild(101, 3)
- self.assertEqual(self.sslist, {1:101, 2:101, 3:101})
- self.master.addBuildset.assert_called_with(builderNames=['bldr1'],
- sourcestampsetid=101,
- reason = 'unit test',
- properties = {})
-
-
-class TestReconfig(BuilderMixin, unittest.TestCase):
- """Tests that a reconfig properly updates all attributes"""
-
- @defer.inlineCallbacks
- def test_reconfig(self):
- yield self.makeBuilder(description="Old", category="OldCat")
- self.builder_config.description = "New"
- self.builder_config.category = "NewCat"
-
- mastercfg = config.MasterConfig()
- mastercfg.builders = [ self.builder_config ]
- yield self.bldr.reconfigService(mastercfg)
- self.assertEqual(
- dict(description=self.bldr.builder_status.getDescription(),
- category=self.bldr.builder_status.getCategory()),
- dict(description="New",
- category="NewCat"))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py
deleted file mode 100644
index 632be205..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py
+++ /dev/null
@@ -1,346 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot.process import buildrequest
-
-class FakeSource:
- def __init__(self, mergeable = True):
- self.codebase = ''
- self.mergeable = mergeable
- self.changes = []
-
- def canBeMergedWith(self, other):
- return self.mergeable
-
-class TestBuildRequest(unittest.TestCase):
-
- def test_fromBrdict(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', project='world-domination'),
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk',
- revision='9284', repository='svn://...',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildsetProperty(buildsetid=539, property_name='x',
- property_value='[1, "X"]'),
- fakedb.BuildsetProperty(buildsetid=539, property_name='y',
- property_value='[2, "Y"]'),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr',
- priority=13, submitted_at=1200000000),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- def check(br):
- # check enough of the source stamp to verify it found the changes
- self.assertEqual(br.source.ssid, 234)
- self.assertEqual([ ch.number for ch in br.source.changes], [13])
-
- self.assertEqual(br.reason, 'triggered')
-
- self.assertEqual(br.properties.getProperty('x'), 1)
- self.assertEqual(br.properties.getProperty('y'), 2)
- self.assertEqual(br.submittedAt, 1200000000)
- self.assertEqual(br.buildername, 'bldr')
- self.assertEqual(br.priority, 13)
- self.assertEqual(br.id, 288)
- self.assertEqual(br.bsid, 539)
- d.addCallback(check)
- return d
-
- def test_fromBrdict_submittedAt_NULL(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk',
- revision='9284', repository='svn://...',
- project='world-domination'),
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr',
- priority=13, submitted_at=None),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- def check(br):
- # remaining fields assumed to be checked in test_fromBrdict
- self.assertEqual(br.submittedAt, None)
- d.addCallback(check)
- return d
-
- def test_fromBrdict_no_sourcestamps(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=234),
- # Sourcestampset has no sourcestamps
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='not important',
- priority=0, submitted_at=None),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict:
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- return self.assertFailure(d, AssertionError)
-
- def test_fromBrdict_multiple_sourcestamps(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=234),
-
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk',
- revision='9283', repository='svn://a..',
- codebase='A', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
-
- fakedb.Change(changeid=14, branch='trunk', revision='9284',
- repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStamp(id=235, sourcestampsetid=234, branch='trunk',
- revision='9284', repository='svn://b..',
- codebase='B', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=235, changeid=14),
-
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildsetProperty(buildsetid=539, property_name='x',
- property_value='[1, "X"]'),
- fakedb.BuildsetProperty(buildsetid=539, property_name='y',
- property_value='[2, "Y"]'),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr',
- priority=13, submitted_at=1200000000),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- def check(br):
- # check enough of the source stamp to verify it found the changes
-
- # Test the single-sourcestamp interface
- self.assertEqual(br.source.ssid, 234)
-
- # Test the multiple sourcestamp interface
- self.assertEqual(br.sources['A'].ssid, 234)
- self.assertEqual(br.sources['B'].ssid, 235)
-
- self.assertEqual([ ch.number for ch in br.sources['A'].changes], [13])
- self.assertEqual([ ch.number for ch in br.sources['B'].changes], [14])
-
- self.assertEqual(br.reason, 'triggered')
-
- self.assertEqual(br.properties.getProperty('x'), 1)
- self.assertEqual(br.properties.getProperty('y'), 2)
- self.assertEqual(br.submittedAt, 1200000000)
- self.assertEqual(br.buildername, 'bldr')
- self.assertEqual(br.priority, 13)
- self.assertEqual(br.id, 288)
- self.assertEqual(br.bsid, 539)
- d.addCallback(check)
- return d
-
- def test_mergeSourceStampsWith_common_codebases(self):
- """ This testcase has two buildrequests
- Request Change Codebase Revision Comment
- ----------------------------------------------------------------------
- 288 13 A 9283
- 289 15 A 9284
- 288 14 B 9200
- 289 16 B 9201
- --------------------------------
- After merged in Build:
- Source1 has rev 9284 and contains changes 13 and 15 from repository svn://a
- Source2 has rev 9201 and contains changes 14 and 16 from repository svn://b
- """
- brs=[] # list of buildrequests
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=2340),
-
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=234, sourcestampsetid=2340, branch='trunk',
- revision='9283', repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
-
- fakedb.Change(changeid=14, branch='trunk', revision='9200',
- repository='svn://b..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=235, sourcestampsetid=2340, branch='trunk',
- revision='9200', repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=235, changeid=14),
-
- fakedb.SourceStampSet(id=2360),
-
- fakedb.Change(changeid=15, branch='trunk', revision='9284',
- repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=236, sourcestampsetid=2360, branch='trunk',
- revision='9284', repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=236, changeid=15),
-
- fakedb.Change(changeid=16, branch='trunk', revision='9201',
- repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStamp(id=237, sourcestampsetid=2360, branch='trunk',
- revision='9201', repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=237, changeid=16),
-
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=2340),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr'),
-
- fakedb.Buildset(id=540, reason='triggered', sourcestampsetid=2360),
- fakedb.BuildRequest(id=289, buildsetid=540, buildername='bldr'),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- d.addCallback(lambda _ :
- master.db.buildrequests.getBuildRequest(289))
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- def check(_):
- sources = brs[0].mergeSourceStampsWith(brs[1:])
-
- source1 = source2 = None
- for source in sources:
- if source.codebase == 'A':
- source1 = source
- if source.codebase == 'B':
- source2 = source
-
- self.assertFalse(source1 == None)
- self.assertEqual(source1.revision,'9284')
-
- self.assertFalse(source2 == None)
- self.assertEqual(source2.revision,'9201')
-
- self.assertEqual([c.number for c in source1.changes], [13,15])
- self.assertEqual([c.number for c in source2.changes], [14,16])
-
- d.addCallback(check)
- return d
-
- def test_canBeMergedWith_different_codebases_raises_error(self):
- """ This testcase has two buildrequests
- Request Change Codebase Revision Comment
- ----------------------------------------------------------------------
- 288 17 C 1800 request 1 has repo not in request 2
- 289 18 D 2100 request 2 has repo not in request 1
- --------------------------------
- Merge cannot be performd and raises error:
- Merging requests requires both requests to have the same codebases
- """
- brs=[] # list of buildrequests
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=2340),
-
- fakedb.Change(changeid=17, branch='trunk', revision='1800',
- repository='svn://c..', codebase='C',
- project='world-domination'),
- fakedb.SourceStamp(id=238, sourcestampsetid=2340, branch='trunk',
- revision='1800', repository='svn://c..',
- codebase='C', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=238, changeid=17),
-
- fakedb.SourceStampSet(id=2360),
-
- fakedb.Change(changeid=18, branch='trunk', revision='2100',
- repository='svn://d..', codebase='D',
- project='world-domination'),
- fakedb.SourceStamp(id=239, sourcestampsetid=2360, branch='trunk',
- revision='2100', repository='svn://d..',
- codebase='D', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=239, changeid=18),
-
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=2340),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr'),
-
- fakedb.Buildset(id=540, reason='triggered', sourcestampsetid=2360),
- fakedb.BuildRequest(id=289, buildsetid=540, buildername='bldr'),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- d.addCallback(lambda _ :
- master.db.buildrequests.getBuildRequest(289))
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- def check(_):
- self.assertEqual(brs[0].canBeMergedWith(brs[1]), False)
-
- d.addCallback(check)
- return d
-
- def test_build_can_be_merged_with_mergables_same_codebases(self):
- r1 = buildrequest.BuildRequest()
- r1.sources = {"A": FakeSource()}
- r2 = buildrequest.BuildRequest()
- r2.sources = {"A": FakeSource()}
- mergeable = r1.canBeMergedWith(r2)
- self.assertTrue(mergeable, "Both request should be able to merge")
-
- def test_build_can_be_merged_with_non_mergable_same_codebases(self):
- r1 = buildrequest.BuildRequest()
- r1.sources = {"A": FakeSource(mergeable = False)}
- r2 = buildrequest.BuildRequest()
- r2.sources = {"A": FakeSource(mergeable = False)}
- mergeable = r1.canBeMergedWith(r2)
- self.assertFalse(mergeable, "Both request should not be able to merge")
-
- def test_build_can_be_merged_with_non_mergables_different_codebases(self):
- r1 = buildrequest.BuildRequest()
- r1.sources = {"A": FakeSource(mergeable = False)}
- r2 = buildrequest.BuildRequest()
- r2.sources = {"B": FakeSource(mergeable = False)}
- mergeable = r1.canBeMergedWith(r2)
- self.assertFalse(mergeable, "Request containing different codebases " +
- "should never be able to merge")
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py
deleted file mode 100644
index e27e6f1d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py
+++ /dev/null
@@ -1,1031 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from twisted.python import failure
-from buildbot.test.util import compat
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot.process import buildrequestdistributor
-from buildbot.util import epoch2datetime
-from buildbot.util.eventual import fireEventually
-from buildbot.db import buildrequests
-
-def nth_slave(n):
- def pick_nth_by_name(lst):
- slaves = lst[:]
- slaves.sort(cmp=lambda a,b: cmp(a.name, b.name))
- return slaves[n]
- return pick_nth_by_name
-
-class SkipSlavesThatCantGetLock(buildrequestdistributor.BasicBuildChooser):
- """This class disables the 'rejectedSlaves' feature"""
- def __init__(self, *args, **kwargs):
- buildrequestdistributor.BasicBuildChooser.__init__(self, *args, **kwargs)
- self.rejectedSlaves = None # disable this feature
-
-class Test(unittest.TestCase):
-
- def setUp(self):
- self.botmaster = mock.Mock(name='botmaster')
- self.botmaster.builders = {}
- def prioritizeBuilders(master, builders):
- # simple sort-by-name by default
- return sorted(builders, lambda b1,b2 : cmp(b1.name, b2.name))
- self.master = self.botmaster.master = mock.Mock(name='master')
- self.master.config.prioritizeBuilders = prioritizeBuilders
- self.master.db = fakedb.FakeDBConnector(self)
- self.brd = buildrequestdistributor.BuildRequestDistributor(self.botmaster)
- self.brd.startService()
-
- # TODO: this is a terrible way to detect the "end" of the test -
- # it regularly completes too early after a simple modification of
- # a test. Is there a better way?
- self.quiet_deferred = defer.Deferred()
- def _quiet():
- if self.quiet_deferred:
- d, self.quiet_deferred = self.quiet_deferred, None
- d.callback(None)
- else:
- self.fail("loop has already gone quiet once")
- self.brd._quiet = _quiet
-
- self.builders = {}
-
- def tearDown(self):
- if self.brd.running:
- return self.brd.stopService()
-
- def checkAllCleanedUp(self):
- # check that the BRD didnt end with a stuck lock or in the 'active' state (which would mean
- # it ended without unwinding correctly)
- self.assertEqual(self.brd.pending_builders_lock.locked, False)
- self.assertEqual(self.brd.activity_lock.locked, False)
- self.assertEqual(self.brd.active, False)
-
- def useMock_maybeStartBuildsOnBuilder(self):
- # sets up a mock "maybeStartBuildsOnBuilder" so we can track
- # how the method gets invoked
-
- # keep track of the calls to brd.maybeStartBuildsOnBuilder
- self.maybeStartBuildsOnBuilder_calls = []
-
- def maybeStartBuildsOnBuilder(bldr):
- self.assertIdentical(self.builders[bldr.name], bldr)
- self.maybeStartBuildsOnBuilder_calls.append(bldr.name)
- return fireEventually()
- self.brd._maybeStartBuildsOnBuilder = maybeStartBuildsOnBuilder
-
- def addBuilders(self, names):
- self.startedBuilds = []
-
- for name in names:
- bldr = mock.Mock(name=name)
- bldr.name = name
- self.botmaster.builders[name] = bldr
- self.builders[name] = bldr
-
- def maybeStartBuild(*args):
- self.startedBuilds.append((name, args))
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
- return d
- bldr.maybeStartBuild = maybeStartBuild
- bldr.canStartWithSlavebuilder = lambda _: True
-
- bldr.slaves = []
- bldr.getAvailableSlaves = lambda : [ s for s in bldr.slaves if s.isAvailable ]
-
- def removeBuilder(self, name):
- del self.builders[name]
- del self.botmaster.builders[name]
-
- # tests
-
- def test_maybeStartBuildsOn_simple(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['bldr1'])
- self.brd.maybeStartBuildsOn(['bldr1'])
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls, ['bldr1'])
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def test_maybeStartBuildsOn_parallel(self):
- # test 15 "parallel" invocations of maybeStartBuildsOn, with a
- # _sortBuilders that takes a while. This is a regression test for bug
- # #1979.
- builders = ['bldr%02d' % i for i in xrange(15) ]
-
- def slow_sorter(master, bldrs):
- bldrs.sort(lambda b1, b2 : cmp(b1.name, b2.name))
- d = defer.Deferred()
- reactor.callLater(0, d.callback, bldrs)
- def done(_):
- return _
- d.addCallback(done)
- return d
- self.master.config.prioritizeBuilders = slow_sorter
-
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(builders)
- for bldr in builders:
- self.brd.maybeStartBuildsOn([bldr])
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls, builders)
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- @compat.usesFlushLoggedErrors
- def test_maybeStartBuildsOn_exception(self):
- self.addBuilders(['bldr1'])
-
- def _maybeStartBuildsOnBuilder(n):
- # fail slowly, so that the activity loop doesn't go quiet too soon
- d = defer.Deferred()
- reactor.callLater(0,
- d.errback, failure.Failure(RuntimeError("oh noes")))
- return d
- self.brd._maybeStartBuildsOnBuilder = _maybeStartBuildsOnBuilder
-
- self.brd.maybeStartBuildsOn(['bldr1'])
- def check(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def test_maybeStartBuildsOn_collapsing(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['bldr1', 'bldr2', 'bldr3'])
- self.brd.maybeStartBuildsOn(['bldr3'])
- self.brd.maybeStartBuildsOn(['bldr2', 'bldr1'])
- self.brd.maybeStartBuildsOn(['bldr4']) # should be ignored
- self.brd.maybeStartBuildsOn(['bldr2']) # already queued - ignored
- self.brd.maybeStartBuildsOn(['bldr3', 'bldr2'])
- def check(_):
- # bldr3 gets invoked twice, since it's considered to have started
- # already when the first call to maybeStartBuildsOn returns
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls,
- ['bldr3', 'bldr1', 'bldr2', 'bldr3'])
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def test_maybeStartBuildsOn_builders_missing(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['bldr1', 'bldr2', 'bldr3'])
- self.brd.maybeStartBuildsOn(['bldr1', 'bldr2', 'bldr3'])
- # bldr1 is already run, so surreptitiously remove the other
- # two - nothing should crash, but the builders should not run
- self.removeBuilder('bldr2')
- self.removeBuilder('bldr3')
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls, ['bldr1'])
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def do_test_sortBuilders(self, prioritizeBuilders, oldestRequestTimes,
- expected, returnDeferred=False):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(oldestRequestTimes.keys())
- self.master.config.prioritizeBuilders = prioritizeBuilders
-
- def mklambda(t): # work around variable-binding issues
- if returnDeferred:
- return lambda : defer.succeed(t)
- else:
- return lambda : t
-
- for n, t in oldestRequestTimes.iteritems():
- if t is not None:
- t = epoch2datetime(t)
- self.builders[n].getOldestRequestTime = mklambda(t)
-
- d = self.brd._sortBuilders(oldestRequestTimes.keys())
- def check(result):
- self.assertEqual(result, expected)
- self.checkAllCleanedUp()
- d.addCallback(check)
- return d
-
- def test_sortBuilders_default_sync(self):
- return self.do_test_sortBuilders(None, # use the default sort
- dict(bldr1=777, bldr2=999, bldr3=888),
- ['bldr1', 'bldr3', 'bldr2'])
-
- def test_sortBuilders_default_asyn(self):
- return self.do_test_sortBuilders(None, # use the default sort
- dict(bldr1=777, bldr2=999, bldr3=888),
- ['bldr1', 'bldr3', 'bldr2'],
- returnDeferred=True)
-
- def test_sortBuilders_default_None(self):
- return self.do_test_sortBuilders(None, # use the default sort
- dict(bldr1=777, bldr2=None, bldr3=888),
- ['bldr1', 'bldr3', 'bldr2'])
-
- def test_sortBuilders_custom(self):
- def prioritizeBuilders(master, builders):
- self.assertIdentical(master, self.master)
- return sorted(builders, key=lambda b : b.name)
-
- return self.do_test_sortBuilders(prioritizeBuilders,
- dict(bldr1=1, bldr2=1, bldr3=1),
- ['bldr1', 'bldr2', 'bldr3'])
-
- def test_sortBuilders_custom_async(self):
- def prioritizeBuilders(master, builders):
- self.assertIdentical(master, self.master)
- return defer.succeed(sorted(builders, key=lambda b : b.name))
-
- return self.do_test_sortBuilders(prioritizeBuilders,
- dict(bldr1=1, bldr2=1, bldr3=1),
- ['bldr1', 'bldr2', 'bldr3'])
-
- @compat.usesFlushLoggedErrors
- def test_sortBuilders_custom_exception(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['x', 'y'])
- def fail(m, b):
- raise RuntimeError("oh noes")
- self.master.config.prioritizeBuilders = fail
-
- # expect to get the builders back in the same order in the event of an
- # exception
- d = self.brd._sortBuilders(['y', 'x'])
- def check(result):
- self.assertEqual(result, ['y', 'x'])
-
- # and expect the exception to be logged
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(check)
- return d
-
- def test_stopService(self):
- # check that stopService waits for a builder run to complete, but does not
- # allow a subsequent run to start
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['A', 'B'])
-
- oldMSBOB = self.brd._maybeStartBuildsOnBuilder
- def maybeStartBuildsOnBuilder(bldr):
- d = oldMSBOB(bldr)
-
- stop_d = self.brd.stopService()
- stop_d.addCallback(lambda _ :
- self.maybeStartBuildsOnBuilder_calls.append('(stopped)'))
-
- d.addCallback(lambda _ :
- self.maybeStartBuildsOnBuilder_calls.append('finished'))
- return d
- self.brd._maybeStartBuildsOnBuilder = maybeStartBuildsOnBuilder
-
- # start both builds; A should start and complete *before* the service stops,
- # and B should not run.
- self.brd.maybeStartBuildsOn(['A', 'B'])
-
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls,
- ['A', 'finished', '(stopped)'])
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
-
-class TestMaybeStartBuilds(unittest.TestCase):
-
- def setUp(self):
- self.botmaster = mock.Mock(name='botmaster')
- self.botmaster.builders = {}
- self.master = self.botmaster.master = mock.Mock(name='master')
- self.master.db = fakedb.FakeDBConnector(self)
- class getCache(object):
- def get_cache(self):
- return self
- def get(self, name):
- return
- self.master.caches = fakemaster.FakeCaches()
- self.brd = buildrequestdistributor.BuildRequestDistributor(self.botmaster)
- self.brd.startService()
-
- self.startedBuilds = []
-
- # TODO: this is a terrible way to detect the "end" of the test -
- # it regularly completes too early after a simple modification of
- # a test. Is there a better way?
- self.quiet_deferred = defer.Deferred()
- def _quiet():
- if self.quiet_deferred:
- d, self.quiet_deferred = self.quiet_deferred, None
- d.callback(None)
- else:
- self.fail("loop has already gone quiet once")
- self.brd._quiet = _quiet
-
- self.bldr = self.createBuilder('A')
-
- # a collection of rows that would otherwise clutter up every test
- self.base_rows = [
- fakedb.SourceStampSet(id=21),
- fakedb.SourceStamp(id=21, sourcestampsetid=21),
- fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
- ]
-
-
- def tearDown(self):
- if self.brd.running:
- return self.brd.stopService()
-
- def createBuilder(self, name):
- bldr = mock.Mock(name=name)
- bldr.name = name
- self.botmaster.builders[name] = bldr
-
- def maybeStartBuild(slave, builds):
- self.startedBuilds.append((slave.name, builds))
- return defer.succeed(True)
-
- bldr.maybeStartBuild = maybeStartBuild
- bldr.canStartWithSlavebuilder = lambda _: True
- bldr.getMergeRequestsFn = lambda : False
-
- bldr.slaves = []
- bldr.getAvailableSlaves = lambda : [ s for s in bldr.slaves if s.isAvailable() ]
- bldr.config.nextSlave = None
- bldr.config.nextBuild = None
-
- def canStartBuild(*args):
- can = bldr.config.canStartBuild
- return not can or can(*args)
- bldr.canStartBuild = canStartBuild
-
- return bldr
-
- def addSlaves(self, slavebuilders):
- """C{slaves} maps name : available"""
- for name, avail in slavebuilders.iteritems():
- sb = mock.Mock(spec=['isAvailable'], name=name)
- sb.name = name
- sb.isAvailable.return_value = avail
- self.bldr.slaves.append(sb)
-
- def assertBuildsStarted(self, exp):
- # munge builds_started into (slave, [brids])
- builds_started = [
- (slave, [br.id for br in breqs])
- for (slave, breqs) in self.startedBuilds ]
- self.assertEqual(sorted(builds_started), sorted(exp))
-
- # _maybeStartBuildsOnBuilder
-
- @defer.inlineCallbacks
- def do_test_maybeStartBuildsOnBuilder(self, rows=[], exp_claims=[], exp_builds=[]):
- yield self.master.db.insertTestData(rows)
-
- yield self.brd._maybeStartBuildsOnBuilder(self.bldr)
-
- self.master.db.buildrequests.assertMyClaims(exp_claims)
- self.assertBuildsStarted(exp_builds)
-
- @defer.inlineCallbacks
- def test_no_buildreqests(self):
- self.addSlaves({'test-slave11':1})
- yield self.do_test_maybeStartBuildsOnBuilder(exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_no_slavebuilders(self):
- rows = [
- fakedb.BuildRequest(id=11, buildsetid=10, buildername="bldr"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_limited_by_slaves(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- @defer.inlineCallbacks
- def test_sorted_by_submit_time(self):
- self.master.config.mergeRequests = False
-
- # same as "limited_by_slaves" but with rows swapped
- self.addSlaves({'test-slave1':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- @defer.inlineCallbacks
- def test_limited_by_available_slaves(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':0, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave2', [10])])
-
- @defer.inlineCallbacks
- def test_slow_db(self):
- # test what happens if the "getBuildRequests" fetch takes a "long time"
-
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1})
-
- # wrap to simulate a "long" db access
- old_getBuildRequests = self.master.db.buildrequests.getBuildRequests
- def longGetBuildRequests(*args, **kwargs):
- res_d = old_getBuildRequests(*args, **kwargs)
- long_d = defer.Deferred()
- long_d.addCallback(lambda _: res_d)
- reactor.callLater(0, long_d.callback, None)
- return long_d
- self.master.db.buildrequests.getBuildRequests = longGetBuildRequests
-
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_limited_by_canStartBuild(self):
- """Set the 'canStartBuild' value in the config to something
- that limits the possible options."""
-
- self.master.config.mergeRequests = False
-
- slaves_attempted = []
- def _canStartWithSlavebuilder(slavebuilder):
- slaves_attempted.append(slavebuilder.name)
- return True
- self.bldr.canStartWithSlavebuilder = _canStartWithSlavebuilder
-
- pairs_tested = []
- def _canStartBuild(slave, breq):
- result = (slave.name, breq.id)
- pairs_tested.append(result)
- allowed = [
- ("test-slave1", 10),
- ("test-slave3", 11),
- ]
- return result in allowed
- self.bldr.config.canStartBuild = _canStartBuild
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1, 'test-slave3':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- fakedb.BuildRequest(id=12, buildsetid=11, buildername="A",
- submitted_at=140000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10, 11], exp_builds=[('test-slave1', [10]), ('test-slave3', [11])])
-
- self.assertEqual(slaves_attempted, ['test-slave3', 'test-slave2', 'test-slave1'])
-
- # we expect brids in order (10-11-12),
- # with each searched in reverse order of slaves (3-2-1) available (due to nth_slave(-1))
- self.assertEqual(pairs_tested, [
- ('test-slave3', 10),
- ('test-slave2', 10),
- ('test-slave1', 10),
- ('test-slave3', 11),
- ('test-slave2', 12)])
-
- @mock.patch('random.choice', nth_slave(-1))
- @mock.patch('buildbot.process.buildrequestdistributor.BuildRequestDistributor.BuildChooser', SkipSlavesThatCantGetLock)
- @defer.inlineCallbacks
- def test_limited_by_canStartBuild_deferreds(self):
- """Another variant that:
- * returns Defered types,
- * use 'canStartWithSlavebuilder' to reject one of the slaves
- * patch using SkipSlavesThatCantGetLock to disable the 'rejectedSlaves' feature"""
-
- self.master.config.mergeRequests = False
-
- slaves_attempted = []
- def _canStartWithSlavebuilder(slavebuilder):
- slaves_attempted.append(slavebuilder.name)
- allowed = slavebuilder.name in ['test-slave2', 'test-slave1']
- return defer.succeed(allowed) # a defered here!
- self.bldr.canStartWithSlavebuilder = _canStartWithSlavebuilder
-
- pairs_tested = []
- def _canStartBuild(slave, breq):
- result = (slave.name, breq.id)
- pairs_tested.append(result)
- allowed = [
- ("test-slave1", 10),
- ("test-slave3", 11),
- ]
- return defer.succeed(result in allowed)
- self.bldr.config.canStartBuild = _canStartBuild
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1, 'test-slave3':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- fakedb.BuildRequest(id=12, buildsetid=11, buildername="A",
- submitted_at=140000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- self.assertEqual(slaves_attempted, ['test-slave3', 'test-slave2', 'test-slave1'])
-
- # we expect brids in order (10-11-12),
- # with slave3 skipped, and slave2 unable to pair
- self.assertEqual(pairs_tested, [
- ('test-slave2', 10),
- ('test-slave1', 10),
- ('test-slave2', 11),
- ('test-slave2', 12)])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_limited_by_canStartWithSlavebuilder(self):
- self.master.config.mergeRequests = False
-
- slaves_attempted = []
- def _canStartWithSlavebuilder(slavebuilder):
- slaves_attempted.append(slavebuilder.name)
- return (slavebuilder.name == 'test-slave3')
- self.bldr.canStartWithSlavebuilder = _canStartWithSlavebuilder
- self.addSlaves({'test-slave1':0, 'test-slave2':1, 'test-slave3':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10, 11], exp_builds=[('test-slave3', [10]), ('test-slave2', [11])])
-
- self.assertEqual(slaves_attempted, ['test-slave3', 'test-slave2'])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_unlimited(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10, 11],
- exp_builds=[('test-slave2', [10]), ('test-slave1', [11])])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_bldr_maybeStartBuild_fails_always(self):
- # the builder fails to start the build; we'll see that the build
- # was requested, but the brids will get reclaimed
- def maybeStartBuild(slave, builds):
- self.startedBuilds.append((slave.name, builds))
- return defer.succeed(False)
- self.bldr.maybeStartBuild = maybeStartBuild
-
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], # reclaimed so none taken!
- exp_builds=[('test-slave2', [10]), ('test-slave1', [11])])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_bldr_maybeStartBuild_fails_once(self):
- # the builder fails to start the build; we'll see that the build
- # was requested, but the brids will get reclaimed
- def maybeStartBuild(slave, builds, _fail=[False]):
- self.startedBuilds.append((slave.name, builds))
- ret = _fail[0]
- _fail[0] = True
- return defer.succeed(ret)
- self.bldr.maybeStartBuild = maybeStartBuild
-
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
-
- yield self.master.db.insertTestData(rows)
-
- # first time around, only #11 stays claimed
- yield self.brd._maybeStartBuildsOnBuilder(self.bldr)
- self.master.db.buildrequests.assertMyClaims([11]) # reclaimed so none taken!
- self.assertBuildsStarted([('test-slave2', [10]), ('test-slave1', [11])])
-
- # second time around the #10 will pass, adding another request and it is claimed
- yield self.brd._maybeStartBuildsOnBuilder(self.bldr)
- self.master.db.buildrequests.assertMyClaims([10, 11])
- self.assertBuildsStarted([('test-slave2', [10]), ('test-slave1', [11]), ('test-slave2', [10])])
-
-
- @mock.patch('random.choice', nth_slave(1))
- @defer.inlineCallbacks
- def test_limited_by_requests(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[11], exp_builds=[('test-slave2', [11])])
-
-
- @defer.inlineCallbacks
- def test_nextSlave_None(self):
- self.bldr.config.nextSlave = lambda _1,_2 : defer.succeed(None)
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextSlave_bogus(self):
- self.bldr.config.nextSlave = lambda _1,_2 : defer.succeed(mock.Mock())
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextSlave_fails(self):
- def nextSlaveRaises(*args):
- raise RuntimeError("xx")
- self.bldr.config.nextSlave = nextSlaveRaises
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
-
- @defer.inlineCallbacks
- def test_nextBuild_None(self):
- self.bldr.config.nextBuild = lambda _1,_2 : defer.succeed(None)
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextBuild_bogus(self):
- self.bldr.config.nextBuild = lambda _1,_2 : mock.Mock()
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextBuild_fails(self):
- def nextBuildRaises(*args):
- raise RuntimeError("xx")
- self.bldr.config.nextBuild = nextBuildRaises
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
-
- # check concurrency edge cases
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_claim_race(self):
- # fake a race condition on the buildrequests table
- old_claimBuildRequests = self.master.db.buildrequests.claimBuildRequests
- def claimBuildRequests(brids):
- # first, ensure this only happens the first time
- self.master.db.buildrequests.claimBuildRequests = old_claimBuildRequests
- # claim brid 10 for some other master
- assert 10 in brids
- self.master.db.buildrequests.fakeClaimBuildRequest(10, 136000,
- objectid=9999) # some other objectid
- # ..and fail
- return defer.fail(buildrequests.AlreadyClaimedError())
- self.master.db.buildrequests.claimBuildRequests = claimBuildRequests
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000), # will turn out to be claimed!
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[11], exp_builds=[('test-slave1', [11])])
-
-
- # nextSlave
-
- @defer.inlineCallbacks
- def do_test_nextSlave(self, nextSlave, exp_choice=None):
- for i in range(4):
- self.addSlaves({'sb%d'%i: 1})
-
- self.bldr.config.nextSlave = nextSlave
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
-
- if exp_choice is None:
- exp_claims = []
- exp_builds = []
- else:
- exp_claims = [11]
- exp_builds = [('sb%d'%exp_choice, [11])]
-
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=exp_claims, exp_builds=exp_builds)
-
- @mock.patch('random.choice', nth_slave(2))
- def test_nextSlave_default(self):
- return self.do_test_nextSlave(None, exp_choice=2)
-
- def test_nextSlave_simple(self):
- def nextSlave(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return lst[1]
- return self.do_test_nextSlave(nextSlave, exp_choice=1)
-
- def test_nextSlave_deferred(self):
- def nextSlave(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return defer.succeed(lst[1])
- return self.do_test_nextSlave(nextSlave, exp_choice=1)
-
- def test_nextSlave_exception(self):
- def nextSlave(bldr, lst):
- raise RuntimeError("")
- return self.do_test_nextSlave(nextSlave)
-
- def test_nextSlave_failure(self):
- def nextSlave(bldr, lst):
- return defer.fail(failure.Failure(RuntimeError()))
- return self.do_test_nextSlave(nextSlave)
-
- # _nextBuild
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def do_test_nextBuild(self, nextBuild, exp_choice=None):
- self.bldr.config.nextBuild = nextBuild
- self.master.config.mergeRequests = False
-
- rows = self.base_rows[:]
- for i in range(4):
- rows.append(fakedb.Buildset(id=100+i, reason='because', sourcestampsetid=21))
- rows.append(fakedb.BuildRequest(id=10+i, buildsetid=100+i, buildername="A"))
- self.addSlaves({'test-slave%d'%i:1})
-
- exp_claims = []
- exp_builds = []
- if exp_choice is not None:
- slave = 3
- for choice in exp_choice:
- exp_claims.append(choice)
- exp_builds.append(('test-slave%d'%slave, [choice]))
- slave = slave - 1
-
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=sorted(exp_claims), exp_builds=exp_builds)
-
- def test_nextBuild_default(self):
- "default chooses the first in the list, which should be the earliest"
- return self.do_test_nextBuild(None, exp_choice=[10, 11, 12, 13])
-
- def test_nextBuild_simple(self):
- def nextBuild(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return lst[-1]
- return self.do_test_nextBuild(nextBuild, exp_choice=[13, 12, 11, 10])
-
- def test_nextBuild_deferred(self):
- def nextBuild(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return defer.succeed(lst[-1])
- return self.do_test_nextBuild(nextBuild, exp_choice=[13, 12, 11, 10])
-
- def test_nextBuild_exception(self):
- def nextBuild(bldr, lst):
- raise RuntimeError("")
- return self.do_test_nextBuild(nextBuild)
-
- def test_nextBuild_failure(self):
- def nextBuild(bldr, lst):
- return defer.fail(failure.Failure(RuntimeError()))
- return self.do_test_nextBuild(nextBuild)
-
-
- # merge tests
-
- @defer.inlineCallbacks
- def test_merge_ordering(self):
- # (patch_random=True)
- self.bldr.getMergeRequestsFn = lambda : lambda _, req1, req2: req1.canBeMergedWith(req2)
-
- self.addSlaves({'test-slave1':1})
-
- # based on the build in bug #2249
- rows = [
- fakedb.SourceStampSet(id=1976),
- fakedb.SourceStamp(id=1976, sourcestampsetid=1976),
- fakedb.Buildset(id=1980, reason='scheduler', sourcestampsetid=1976,
- submitted_at=1332024020.67792),
- fakedb.BuildRequest(id=42880, buildsetid=1980,
- submitted_at=1332024020.67792, buildername="A"),
-
- fakedb.SourceStampSet(id=1977),
- fakedb.SourceStamp(id=1977, sourcestampsetid=1977),
- fakedb.Buildset(id=1981, reason='scheduler', sourcestampsetid=1977,
- submitted_at=1332025495.19141),
- fakedb.BuildRequest(id=42922, buildsetid=1981,
- buildername="A", submitted_at=1332025495.19141),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[42880, 42922],
- exp_builds=[('test-slave1', [42880, 42922])])
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_mergeRequests(self):
- # set up all of the data required for a BuildRequest object
- rows = [
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=19, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=20, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=21, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- ]
-
- self.addSlaves({'test-slave1':1, 'test-slave2': 1})
-
- def mergeRequests_fn(builder, breq, other):
- # merge evens with evens, odds with odds
- self.assertIdentical(builder, self.bldr)
- return breq.id % 2 == other.id % 2
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[19, 20, 21],
- exp_builds=[
- ('test-slave1', [19, 21]),
- ('test-slave2', [20])
- ])
-
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_mergeRequest_no_other_request(self):
- """ Test if builder test for codebases in requests """
- # set up all of the data required for a BuildRequest object
- rows = [
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, codebase='A'),
- fakedb.Change(changeid=14, codebase='A'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=14),
- fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=19, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- ]
-
- self.addSlaves({'test-slave1':1, 'test-slave2': 1})
-
- def mergeRequests_fn(builder, breq, other):
- # Allow all requests
- self.fail("Should never be called")
- return True
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- # check if the request remains the same
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[19],
- exp_builds=[
- ('test-slave1', [19]),
- ])
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_mergeRequests_no_merging(self):
- """ Test if builder test for codebases in requests """
- # set up all of the data required for a BuildRequest object
- rows = [
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, codebase='C'),
- fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.SourceStampSet(id=235),
- fakedb.SourceStamp(id=235, sourcestampsetid=235, codebase='C'),
- fakedb.Buildset(id=31, sourcestampsetid=235, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.SourceStampSet(id=236),
- fakedb.SourceStamp(id=236, sourcestampsetid=236, codebase='C'),
- fakedb.Buildset(id=32, sourcestampsetid=236, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=19, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=20, buildsetid=31, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=21, buildsetid=32, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- ]
-
- self.addSlaves({'test-slave1':1, 'test-slave2': 1})
-
- def mergeRequests_fn(builder, breq, other):
- # Fail all merge attempts
- return False
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- # check if all are merged
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[19, 20],
- exp_builds=[
- ('test-slave1', [19]),
- ('test-slave2', [20]),
- ])
-
- @defer.inlineCallbacks
- def test_mergeRequests_fails(self):
- def mergeRequests_fn(*args):
- raise RuntimeError("xx")
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py
deleted file mode 100644
index 62dff108..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.python import log
-from buildbot.process import buildstep
-from buildbot.process.buildstep import regex_log_evaluator
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, EXCEPTION
-from buildbot.test.fake import fakebuild, remotecommand
-from buildbot.test.util import config, steps, compat
-from buildbot.util.eventual import eventually
-
-class FakeLogFile:
- def __init__(self, text):
- self.text = text
-
- def getText(self):
- return self.text
-
-class FakeStepStatus:
- pass
-
-class TestRegexLogEvaluator(unittest.TestCase):
-
- def makeRemoteCommand(self, rc, stdout, stderr=''):
- cmd = remotecommand.FakeRemoteCommand('cmd', {})
- cmd.fakeLogData(self, 'stdio', stdout=stdout, stderr=stderr)
- cmd.rc = rc
- return cmd
-
- def test_find_worse_status(self):
- cmd = self.makeRemoteCommand(0, 'This is a big step')
- step_status = FakeStepStatus()
- r = [(re.compile("This is"), WARNINGS)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, WARNINGS,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, WARNINGS))
-
- def test_multiple_regexes(self):
- cmd = self.makeRemoteCommand(0, "Normal stdout text\nan error")
- step_status = FakeStepStatus()
- r = [(re.compile("Normal stdout"), SUCCESS),
- (re.compile("error"), FAILURE)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, FAILURE,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, FAILURE))
-
- def test_exception_not_in_stdout(self):
- cmd = self.makeRemoteCommand(0,
- "Completely normal output", "exception output")
- step_status = FakeStepStatus()
- r = [(re.compile("exception"), EXCEPTION)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, EXCEPTION,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, EXCEPTION))
-
- def test_pass_a_string(self):
- cmd = self.makeRemoteCommand(0, "Output", "Some weird stuff on stderr")
- step_status = FakeStepStatus()
- r = [("weird stuff", WARNINGS)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, WARNINGS,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, WARNINGS))
-
-
-class TestBuildStep(steps.BuildStepMixin, config.ConfigErrorsMixin, unittest.TestCase):
-
- class FakeBuildStep(buildstep.BuildStep):
- def start(self):
- eventually(self.finished, 0)
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- # support
-
- def _setupWaterfallTest(self, hideStepIf, expect, expectedResult=SUCCESS):
- self.setupStep(TestBuildStep.FakeBuildStep(hideStepIf=hideStepIf))
- self.expectOutcome(result=expectedResult, status_text=["generic"])
- self.expectHidden(expect)
-
- # tests
-
- def test_nameIsntString(self):
- """
- When BuildStep is passed a name that isn't a string, it reports
- a config error.
- """
- self.assertRaisesConfigError("BuildStep name must be a string",
- lambda: buildstep.BuildStep(name=5))
-
- def test_unexpectedKeywordArgument(self):
- """
- When BuildStep is passed an unknown keyword argument, it reports
- a config error.
- """
- self.assertRaisesConfigError("__init__ got unexpected keyword argument(s) ['oogaBooga']",
- lambda: buildstep.BuildStep(oogaBooga=5))
-
-
- def test_getProperty(self):
- bs = buildstep.BuildStep()
- bs.build = fakebuild.FakeBuild()
- props = bs.build.build_status.properties = mock.Mock()
- bs.getProperty("xyz", 'b')
- props.getProperty.assert_called_with("xyz", 'b')
- bs.getProperty("xyz")
- props.getProperty.assert_called_with("xyz", None)
-
- def test_setProperty(self):
- bs = buildstep.BuildStep()
- bs.build = fakebuild.FakeBuild()
- props = bs.build.build_status.properties = mock.Mock()
- bs.setProperty("x", "y", "t")
- props.setProperty.assert_called_with("x", "y", "t", runtime=True)
- bs.setProperty("x", "abc", "test", runtime=True)
- props.setProperty.assert_called_with("x", "abc", "test", runtime=True)
-
- def test_hideStepIf_False(self):
- self._setupWaterfallTest(False, False)
- return self.runStep()
-
- def test_hideStepIf_True(self):
- self._setupWaterfallTest(True, True)
- return self.runStep()
-
- def test_hideStepIf_Callable_False(self):
- called = [False]
- def shouldHide(result, step):
- called[0] = True
- self.assertTrue(step is self.step)
- self.assertEquals(result, SUCCESS)
- return False
-
- self._setupWaterfallTest(shouldHide, False)
-
- d = self.runStep()
- d.addCallback(lambda _ : self.assertTrue(called[0]))
- return d
-
- def test_hideStepIf_Callable_True(self):
- called = [False]
- def shouldHide(result, step):
- called[0] = True
- self.assertTrue(step is self.step)
- self.assertEquals(result, SUCCESS)
- return True
-
- self._setupWaterfallTest(shouldHide, True)
-
- d = self.runStep()
- d.addCallback(lambda _ : self.assertTrue(called[0]))
- return d
-
- def test_hideStepIf_fails(self):
- # 0/0 causes DivideByZeroError, which should be flagged as an exception
- self._setupWaterfallTest(lambda : 0/0, False, expectedResult=EXCEPTION)
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_hideStepIf_Callable_Exception(self):
- called = [False]
- def shouldHide(result, step):
- called[0] = True
- self.assertTrue(step is self.step)
- self.assertEquals(result, EXCEPTION)
- return True
-
- def createException(*args, **kwargs):
- raise RuntimeError()
-
- self.setupStep(self.FakeBuildStep(hideStepIf=shouldHide,
- doStepIf=createException))
- self.expectOutcome(result=EXCEPTION,
- status_text=['generic', 'exception'])
- self.expectHidden(True)
-
- d = self.runStep()
- d.addErrback(log.err)
- d.addCallback(lambda _ :
- self.assertEqual(len(self.flushLoggedErrors(defer.FirstError)), 1))
- d.addCallback(lambda _:
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1))
- d.addCallback(lambda _ : self.assertTrue(called[0]))
- return d
-
-
-class TestLoggingBuildStep(unittest.TestCase):
-
- def makeRemoteCommand(self, rc, stdout, stderr=''):
- cmd = remotecommand.FakeRemoteCommand('cmd', {})
- cmd.fakeLogData(self, 'stdio', stdout=stdout, stderr=stderr)
- cmd.rc = rc
- return cmd
-
- def test_evaluateCommand_success(self):
- cmd = self.makeRemoteCommand(0, "Log text", "Log text")
- lbs = buildstep.LoggingBuildStep()
- status = lbs.evaluateCommand(cmd)
- self.assertEqual(status, SUCCESS, "evaluateCommand returned %d, should've returned %d" % (status, SUCCESS))
-
- def test_evaluateCommand_failed(self):
- cmd = self.makeRemoteCommand(23, "Log text", "")
- lbs = buildstep.LoggingBuildStep()
- status = lbs.evaluateCommand(cmd)
- self.assertEqual(status, FAILURE, "evaluateCommand returned %d, should've returned %d" % (status, FAILURE))
-
- def test_evaluateCommand_log_eval_func(self):
- cmd = self.makeRemoteCommand(0, "Log text")
- def eval(cmd, step_status):
- return WARNINGS
- lbs = buildstep.LoggingBuildStep(log_eval_func=eval)
- status = lbs.evaluateCommand(cmd)
- self.assertEqual(status, WARNINGS, "evaluateCommand didn't call log_eval_func or overrode its results")
-
-
-class FailingCustomStep(buildstep.LoggingBuildStep):
-
- def __init__(self, exception=buildstep.BuildStepFailed, *args, **kwargs):
- buildstep.LoggingBuildStep.__init__(self, *args, **kwargs)
- self.exception = exception
-
- @defer.inlineCallbacks
- def start(self):
- yield defer.succeed(None)
- raise self.exception()
-
-
-class TestCustomStepExecution(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_step_raining_buildstepfailed_in_start(self):
- self.setupStep(FailingCustomStep())
- self.expectOutcome(result=FAILURE, status_text=["generic"])
- return self.runStep()
-
- def test_step_raising_exception_in_start(self):
- self.setupStep(FailingCustomStep(exception=ValueError))
- self.expectOutcome(result=EXCEPTION, status_text=["generic", "exception"])
- d = self.runStep()
- @d.addCallback
- def cb(_):
- self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py
deleted file mode 100644
index 508d14a4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from buildbot.process import cache
-
-class CacheManager(unittest.TestCase):
-
- def setUp(self):
- self.caches = cache.CacheManager()
-
- def make_config(self, **kwargs):
- cfg = mock.Mock()
- cfg.caches = kwargs
- return cfg
-
- def test_get_cache_idempotency(self):
- foo_cache = self.caches.get_cache("foo", None)
- bar_cache = self.caches.get_cache("bar", None)
- foo_cache2 = self.caches.get_cache("foo", None)
- self.assertIdentical(foo_cache, foo_cache2)
- self.assertNotIdentical(foo_cache, bar_cache)
-
- def test_reconfigService(self):
- # load config with one cache loaded and the other not
- foo_cache = self.caches.get_cache("foo", None)
- d = self.caches.reconfigService(
- self.make_config(foo=5, bar=6, bing=11))
- @d.addCallback
- def check(_):
- bar_cache = self.caches.get_cache("bar", None)
- self.assertEqual((foo_cache.max_size, bar_cache.max_size),
- (5, 6))
-
- def test_get_metrics(self):
- self.caches.get_cache("foo", None)
- self.assertIn('foo', self.caches.get_metrics())
- metric = self.caches.get_metrics()['foo']
- for k in 'hits', 'refhits', 'misses', 'max_size':
- self.assertIn(k, metric)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py
deleted file mode 100644
index 1170ca66..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.application import service
-from buildbot.process import debug
-from buildbot import config
-
-class FakeManhole(service.Service):
- pass
-
-class TestDebugServices(unittest.TestCase):
-
- def setUp(self):
- self.master = mock.Mock(name='master')
- self.config = config.MasterConfig()
-
- @defer.inlineCallbacks
- def test_reconfigService_debug(self):
- # mock out PBManager
- self.master.pbmanager = pbmanager = mock.Mock()
- registration = mock.Mock(name='registration')
- registration.unregister = mock.Mock(name='unregister',
- side_effect=lambda : defer.succeed(None))
- pbmanager.register.return_value = registration
-
- ds = debug.DebugServices(self.master)
- ds.startService()
-
- # start off with no debug password
- self.config.slavePortnum = '9824'
- self.config.debugPassword = None
- yield ds.reconfigService(self.config)
-
- self.assertFalse(pbmanager.register.called)
-
- # set the password, and see it register
- self.config.debugPassword = 'seeeekrit'
- yield ds.reconfigService(self.config)
-
- self.assertTrue(pbmanager.register.called)
- self.assertEqual(pbmanager.register.call_args[0][:3],
- ('9824', 'debug', 'seeeekrit'))
- factory = pbmanager.register.call_args[0][3]
- self.assertIsInstance(factory(mock.Mock(), mock.Mock()),
- debug.DebugPerspective)
-
- # change the password, and see it re-register
- self.config.debugPassword = 'lies'
- pbmanager.register.reset_mock()
- yield ds.reconfigService(self.config)
-
- self.assertTrue(registration.unregister.called)
- self.assertTrue(pbmanager.register.called)
- self.assertEqual(pbmanager.register.call_args[0][:3],
- ('9824', 'debug', 'lies'))
-
- # remove the password, and see it unregister
- self.config.debugPassword = None
- pbmanager.register.reset_mock()
- registration.unregister.reset_mock()
- yield ds.reconfigService(self.config)
-
- self.assertTrue(registration.unregister.called)
- self.assertFalse(pbmanager.register.called)
-
- # re-register to test stopService
- self.config.debugPassword = 'confusion'
- pbmanager.register.reset_mock()
- yield ds.reconfigService(self.config)
-
- # stop the service, and see that it unregisters
- pbmanager.register.reset_mock()
- registration.unregister.reset_mock()
- yield ds.stopService()
-
- self.assertTrue(registration.unregister.called)
-
- @defer.inlineCallbacks
- def test_reconfigService_manhole(self):
- master = mock.Mock(name='master')
- ds = debug.DebugServices(master)
- ds.startService()
-
- # start off with no manhole
- yield ds.reconfigService(self.config)
-
- # set a manhole, fire it up
- self.config.manhole = manhole = FakeManhole()
- yield ds.reconfigService(self.config)
-
- self.assertTrue(manhole.running)
- self.assertIdentical(manhole.master, master)
-
- # unset it, see it stop
- self.config.manhole = None
- yield ds.reconfigService(self.config)
-
- self.assertFalse(manhole.running)
- self.assertIdentical(manhole.master, None)
-
- # re-start to test stopService
- self.config.manhole = manhole
- yield ds.reconfigService(self.config)
-
- # stop the service, and see that it unregisters
- yield ds.stopService()
-
- self.assertFalse(manhole.running)
- self.assertIdentical(manhole.master, None)
-
-
-class TestDebugPerspective(unittest.TestCase):
-
- def setUp(self):
- self.master = mock.Mock()
- self.persp = debug.DebugPerspective(self.master)
-
- def test_attached(self):
- self.assertIdentical(self.persp.attached(mock.Mock()), self.persp)
-
- def test_detached(self):
- self.persp.detached(mock.Mock()) # just shouldn't crash
-
- def test_perspective_reload(self):
- d = defer.maybeDeferred(lambda : self.persp.perspective_reload())
- def check(_):
- self.master.reconfig.assert_called_with()
- d.addCallback(check)
- return d
-
- # remaining methods require IControl adapters or other weird stuff.. TODO
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py
deleted file mode 100644
index 2724f924..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildbot.process.factory import BuildFactory, s
-from buildbot.process.buildstep import BuildStep, _BuildStepFactory
-
-class TestBuildFactory(unittest.TestCase):
-
- def test_init(self):
- step = BuildStep()
- factory = BuildFactory([step])
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep)])
-
- def test_addStep(self):
- step = BuildStep()
- factory = BuildFactory()
- factory.addStep(step)
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep)])
-
- def test_addStep_deprecated_withArguments(self):
- """
- Passing keyword arguments to L{BuildFactory.addStep} is deprecated,
- but pass the arguments to the first argument, to construct a step.
- """
- factory = BuildFactory()
- factory.addStep(BuildStep, name='test')
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep, name='test')])
- warnings = self.flushWarnings([self.test_addStep_deprecated_withArguments])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
-
- def test_addStep_deprecated(self):
- """
- Passing keyword arguments to L{BuildFactory.addStep} is deprecated,
- but pass the arguments to the first argument, to construct a step.
- """
- factory = BuildFactory()
- factory.addStep(BuildStep)
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep)])
- warnings = self.flushWarnings([self.test_addStep_deprecated])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
-
- def test_s(self):
- """
- L{s} is deprecated, but pass keyword arguments to the first argument,
- to construct a step.
- """
- stepFactory = s(BuildStep, name='test')
- self.assertEqual(stepFactory, _BuildStepFactory(BuildStep, name='test'))
- warnings = self.flushWarnings([self.test_s])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
-
- def test_addStep_notAStep(self):
- factory = BuildFactory()
- # This fails because object isn't adaptable to IBuildStepFactory
- self.assertRaises(TypeError, factory.addStep, object())
-
- def test_addStep_ArgumentsInTheWrongPlace(self):
- factory = BuildFactory()
- self.assertRaises(TypeError, factory.addStep, BuildStep(), name="name")
-
- def test_addSteps(self):
- factory = BuildFactory()
- factory.addSteps([BuildStep(), BuildStep()])
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep), _BuildStepFactory(BuildStep)])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py
deleted file mode 100644
index 49d90011..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import gc, sys
-from twisted.trial import unittest
-from twisted.internet import task
-from buildbot.process import metrics
-from buildbot.test.fake import fakemaster
-
-class TestMetricBase(unittest.TestCase):
- def setUp(self):
- self.clock = task.Clock()
- self.observer = metrics.MetricLogObserver()
- self.observer.parent = self.master = fakemaster.make_master()
- self.master.config.db['db_poll_interval'] = 60
- self.master.config.metrics = dict(log_interval=0, periodic_interval=0)
- self.observer._reactor = self.clock
- self.observer.startService()
- self.observer.reconfigService(self.master.config)
-
- def tearDown(self):
- if self.observer.running:
- self.observer.stopService()
-
-class TestMetricCountEvent(TestMetricBase):
- def testIncrement(self):
- metrics.MetricCountEvent.log('num_widgets', 1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 1)
-
- metrics.MetricCountEvent.log('num_widgets', 1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 2)
-
- def testDecrement(self):
- metrics.MetricCountEvent.log('num_widgets', 1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 1)
-
- metrics.MetricCountEvent.log('num_widgets', -1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 0)
-
- def testAbsolute(self):
- metrics.MetricCountEvent.log('num_widgets', 10, absolute=True)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 10)
-
- def testCountMethod(self):
- @metrics.countMethod('foo_called')
- def foo():
- return "foo!"
-
- for i in range(10):
- foo()
- report = self.observer.asDict()
- self.assertEquals(report['counters']['foo_called'], 10)
-
-class TestMetricTimeEvent(TestMetricBase):
- def testManualEvent(self):
- metrics.MetricTimeEvent.log('foo_time', 0.001)
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 0.001)
-
- def testTimer(self):
- clock = task.Clock()
- t = metrics.Timer('foo_time')
- t._reactor = clock
- t.start()
-
- clock.advance(5)
- t.stop()
-
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 5)
-
- def testStartStopDecorators(self):
- clock = task.Clock()
- t = metrics.Timer('foo_time')
- t._reactor = clock
-
- @t.startTimer
- def foo():
- clock.advance(5)
- return "foo!"
-
- @t.stopTimer
- def bar():
- clock.advance(5)
- return "bar!"
-
- foo()
- bar()
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 10)
-
- def testTimeMethod(self):
- clock = task.Clock()
- @metrics.timeMethod('foo_time', _reactor=clock)
- def foo():
- clock.advance(5)
- return "foo!"
- foo()
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 5)
-
- def testAverages(self):
- data = range(10)
- for i in data:
- metrics.MetricTimeEvent.log('foo_time', i)
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], sum(data)/float(len(data)))
-
-class TestPeriodicChecks(TestMetricBase):
- def testPeriodicCheck(self):
- # fake out that there's no garbage (since we can't rely on Python
- # not having any garbage while running tests)
- self.patch(gc, 'garbage', [])
-
- clock = task.Clock()
- metrics.periodicCheck(_reactor=clock)
- clock.pump([0.1, 0.1, 0.1])
-
- # We should have 0 reactor delay since we're using a fake clock
- report = self.observer.asDict()
- self.assertEquals(report['timers']['reactorDelay'], 0)
- self.assertEquals(report['counters']['gc.garbage'], 0)
- self.assertEquals(report['alarms']['gc.garbage'][0], 'OK')
-
- def testUncollectable(self):
- # make some fake garbage
- self.patch(gc, 'garbage', [ 1, 2 ])
-
- clock = task.Clock()
- metrics.periodicCheck(_reactor=clock)
- clock.pump([0.1, 0.1, 0.1])
-
- # We should have 0 reactor delay since we're using a fake clock
- report = self.observer.asDict()
- self.assertEquals(report['timers']['reactorDelay'], 0)
- self.assertEquals(report['counters']['gc.garbage'], 2)
- self.assertEquals(report['alarms']['gc.garbage'][0], 'WARN')
-
- def testGetRSS(self):
- self.assert_(metrics._get_rss() > 0)
- if sys.platform != 'linux2':
- testGetRSS.skip = "only available on linux2 platforms"
-
-class TestReconfig(TestMetricBase):
- def testReconfig(self):
- observer = self.observer
- new_config = self.master.config
-
- # starts up without running tasks
- self.assertEquals(observer.log_task, None)
- self.assertEquals(observer.periodic_task, None)
-
- # enable log_interval
- new_config.metrics = dict(log_interval=10, periodic_interval=0)
- observer.reconfigService(new_config)
- self.assert_(observer.log_task)
- self.assertEquals(observer.periodic_task, None)
-
- # disable that and enable periodic_interval
- new_config.metrics = dict(periodic_interval=10, log_interval=0)
- observer.reconfigService(new_config)
- self.assert_(observer.periodic_task)
- self.assertEquals(observer.log_task, None)
-
- # Make the periodic check run
- self.clock.pump([0.1])
-
- # disable the whole listener
- new_config.metrics = None
- observer.reconfigService(new_config)
- self.assertFalse(observer.enabled)
- self.assertEquals(observer.log_task, None)
- self.assertEquals(observer.periodic_task, None)
-
- # disable both
- new_config.metrics = dict(periodic_interval=0, log_interval=0)
- observer.reconfigService(new_config)
- self.assertEquals(observer.log_task, None)
- self.assertEquals(observer.periodic_task, None)
-
- # enable both
- new_config.metrics = dict(periodic_interval=10, log_interval=10)
- observer.reconfigService(new_config)
- self.assert_(observer.log_task)
- self.assert_(observer.periodic_task)
-
- # (service will be stopped by tearDown)
-
-class _LogObserver:
- def __init__(self):
- self.events = []
-
- def gotEvent(self, event):
- self.events.append(event)
-
-class TestReports(unittest.TestCase):
- def testMetricCountReport(self):
- handler = metrics.MetricCountHandler(None)
- handler.handle({}, metrics.MetricCountEvent('num_foo', 1))
-
- self.assertEquals("Counter num_foo: 1", handler.report())
- self.assertEquals({"counters": {"num_foo": 1}}, handler.asDict())
-
- def testMetricTimeReport(self):
- handler = metrics.MetricTimeHandler(None)
- handler.handle({}, metrics.MetricTimeEvent('time_foo', 1))
-
- self.assertEquals("Timer time_foo: 1", handler.report())
- self.assertEquals({"timers": {"time_foo": 1}}, handler.asDict())
-
- def testMetricAlarmReport(self):
- handler = metrics.MetricAlarmHandler(None)
- handler.handle({}, metrics.MetricAlarmEvent('alarm_foo', msg='Uh oh', level=metrics.ALARM_WARN))
-
- self.assertEquals("WARN alarm_foo: Uh oh", handler.report())
- self.assertEquals({"alarms": {"alarm_foo": ("WARN", "Uh oh")}}, handler.asDict())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py
deleted file mode 100644
index 040bedad..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py
+++ /dev/null
@@ -1,1407 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from zope.interface import implements
-from twisted.internet import defer
-from twisted.trial import unittest
-from twisted.python import components
-from buildbot.process.properties import Properties, WithProperties
-from buildbot.process.properties import Interpolate
-from buildbot.process.properties import _Lazy, _SourceStampDict, _Lookup
-from buildbot.process.properties import Property, PropertiesMixin, renderer
-from buildbot.interfaces import IRenderable, IProperties
-from buildbot.test.fake.fakebuild import FakeBuild
-from buildbot.test.util.config import ConfigErrorsMixin
-from buildbot.test.util.properties import ConstantRenderable
-from buildbot.test.util import compat
-
-class FakeSource:
- def __init__(self):
- self.branch = None
- self.codebase = ''
- self.project = ''
- self.repository = ''
- self.revision = None
-
- def asDict(self):
- ds = {}
- ds['branch'] = self.branch
- ds['codebase'] = self.codebase
- ds['project'] = self.project
- ds['repository'] = self.repository
- ds['revision'] = self.revision
- return ds
-
-class DeferredRenderable:
- implements (IRenderable)
- def __init__(self):
- self.d = defer.Deferred()
- def getRenderingFor(self, build):
- return self.d
- def callback(self, value):
- self.d.callback(value)
-
-class TestPropertyMap(unittest.TestCase):
- """
- Test the behavior of PropertyMap, using the external interace
- provided by WithProperties.
- """
-
- def setUp(self):
- self.props = Properties(
- prop_str='a-string',
- prop_none=None,
- prop_list=['a', 'b'],
- prop_zero=0,
- prop_one=1,
- prop_false=False,
- prop_true=True,
- prop_empty='',
- )
- self.build = FakeBuild(self.props)
-
- def doTestSimpleWithProperties(self, fmtstring, expect, **kwargs):
- d = self.build.render(WithProperties(fmtstring, **kwargs))
- d.addCallback(self.failUnlessEqual, "%s" % expect)
- return d
-
- def testSimpleStr(self):
- return self.doTestSimpleWithProperties('%(prop_str)s', 'a-string')
-
- def testSimpleNone(self):
- # None is special-cased to become an empty string
- return self.doTestSimpleWithProperties('%(prop_none)s', '')
-
- def testSimpleList(self):
- return self.doTestSimpleWithProperties('%(prop_list)s', ['a', 'b'])
-
- def testSimpleZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero)s', 0)
-
- def testSimpleOne(self):
- return self.doTestSimpleWithProperties('%(prop_one)s', 1)
-
- def testSimpleFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false)s', False)
-
- def testSimpleTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true)s', True)
-
- def testSimpleEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty)s', '')
-
- def testSimpleUnset(self):
- d = self.build.render(WithProperties('%(prop_nosuch)s'))
- return self.assertFailure(d, KeyError)
-
-
- def testColonMinusSet(self):
- return self.doTestSimpleWithProperties('%(prop_str:-missing)s', 'a-string')
-
- def testColonMinusNone(self):
- # None is special-cased here, too
- return self.doTestSimpleWithProperties('%(prop_none:-missing)s', '')
-
- def testColonMinusZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero:-missing)s', 0)
-
- def testColonMinusOne(self):
- return self.doTestSimpleWithProperties('%(prop_one:-missing)s', 1)
-
- def testColonMinusFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:-missing)s', False)
-
- def testColonMinusTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true:-missing)s', True)
-
- def testColonMinusEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty:-missing)s', '')
-
- def testColonMinusUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:-missing)s', 'missing')
-
-
- def testColonTildeSet(self):
- return self.doTestSimpleWithProperties('%(prop_str:~missing)s', 'a-string')
-
- def testColonTildeNone(self):
- # None is special-cased *differently* for ~:
- return self.doTestSimpleWithProperties('%(prop_none:~missing)s', 'missing')
-
- def testColonTildeZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero:~missing)s', 'missing')
-
- def testColonTildeOne(self):
- return self.doTestSimpleWithProperties('%(prop_one:~missing)s', 1)
-
- def testColonTildeFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:~missing)s', 'missing')
-
- def testColonTildeTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true:~missing)s', True)
-
- def testColonTildeEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty:~missing)s', 'missing')
-
- def testColonTildeUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~missing)s', 'missing')
-
-
- def testColonPlusSet(self):
- return self.doTestSimpleWithProperties('%(prop_str:+present)s', 'present')
-
- def testColonPlusNone(self):
- return self.doTestSimpleWithProperties('%(prop_none:+present)s', 'present')
-
- def testColonPlusZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero:+present)s', 'present')
-
- def testColonPlusOne(self):
- return self.doTestSimpleWithProperties('%(prop_one:+present)s', 'present')
-
- def testColonPlusFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:+present)s', 'present')
-
- def testColonPlusTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true:+present)s', 'present')
-
- def testColonPlusEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty:+present)s', 'present')
-
- def testColonPlusUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:+present)s', '')
-
- def testClearTempValues(self):
- d = self.doTestSimpleWithProperties('', '',
- prop_temp=lambda b: 'present')
- d.addCallback(lambda _:
- self.doTestSimpleWithProperties('%(prop_temp:+present)s', ''))
- return d
-
- def testTempValue(self):
- self.doTestSimpleWithProperties('%(prop_temp)s', 'present',
- prop_temp=lambda b: 'present')
-
- def testTempValueOverrides(self):
- return self.doTestSimpleWithProperties('%(prop_one)s', 2,
- prop_one=lambda b: 2)
-
- def testTempValueColonMinusSet(self):
- return self.doTestSimpleWithProperties('%(prop_one:-missing)s', 2,
- prop_one=lambda b: 2)
-
- def testTempValueColonMinusUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:-missing)s', 'temp',
- prop_nosuch=lambda b: 'temp')
-
- def testTempValueColonTildeTrueSet(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'temp',
- prop_false=lambda b: 'temp')
-
- def testTempValueColonTildeTrueUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'temp',
- prop_nosuch=lambda b: 'temp')
-
- def testTempValueColonTildeFalseFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'nontrue',
- prop_false=lambda b: False)
-
- def testTempValueColonTildeTrueFalse(self):
- return self.doTestSimpleWithProperties('%(prop_true:~nontrue)s', True,
- prop_true=lambda b: False)
-
- def testTempValueColonTildeNoneFalse(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'nontrue',
- prop_nosuch=lambda b: False)
-
-
- def testTempValueColonTildeFalseZero(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'nontrue',
- prop_false=lambda b: 0)
-
- def testTempValueColonTildeTrueZero(self):
- return self.doTestSimpleWithProperties('%(prop_true:~nontrue)s', True,
- prop_true=lambda b: 0)
-
- def testTempValueColonTildeNoneZero(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'nontrue',
- prop_nosuch=lambda b: 0)
-
- def testTempValueColonTildeFalseBlank(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'nontrue',
- prop_false=lambda b: '')
-
- def testTempValueColonTildeTrueBlank(self):
- return self.doTestSimpleWithProperties('%(prop_true:~nontrue)s', True,
- prop_true=lambda b: '')
-
- def testTempValueColonTildeNoneBlank(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'nontrue',
- prop_nosuch=lambda b: '')
-
- def testTempValuePlusSetSet(self):
- return self.doTestSimpleWithProperties('%(prop_one:+set)s', 'set',
- prop_one=lambda b: 2)
-
- def testTempValuePlusUnsetSet(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:+set)s', 'set',
- prop_nosuch=lambda b: 1)
-
-
-class TestInterpolateConfigure(unittest.TestCase, ConfigErrorsMixin):
- """
- Test that Interpolate reports erros in the interpolation string
- at configure time.
- """
-
- def test_invalid_args_and_kwargs(self):
- self.assertRaisesConfigError("Interpolate takes either positional",
- lambda : Interpolate("%s %(foo)s", 1, foo=2))
-
- def test_invalid_selector(self):
- self.assertRaisesConfigError("invalid Interpolate selector 'garbage'",
- lambda: Interpolate("%(garbage:test)s"))
-
- def test_no_selector(self):
- self.assertRaisesConfigError("invalid Interpolate substitution without selector 'garbage'",
- lambda: Interpolate("%(garbage)s"))
-
- def test_invalid_default_type(self):
- self.assertRaisesConfigError("invalid Interpolate default type '@'",
- lambda: Interpolate("%(prop:some_prop:@wacky)s"))
-
- def test_nested_invalid_selector(self):
- self.assertRaisesConfigError("invalid Interpolate selector 'garbage'",
- lambda: Interpolate("%(prop:some_prop:~%(garbage:test)s)s"))
-
- def test_colon_ternary_missing_delimeter(self):
- self.assertRaisesConfigError("invalid Interpolate ternary expression 'one' with delimiter ':'",
- lambda: Interpolate("echo '%(prop:P:?:one)s'"))
-
- def test_colon_ternary_paren_delimiter(self):
- self.assertRaisesConfigError("invalid Interpolate ternary expression 'one(:)' with delimiter ':'",
- lambda: Interpolate("echo '%(prop:P:?:one(:))s'"))
-
- def test_colon_ternary_hash_bad_delimeter(self):
- self.assertRaisesConfigError("invalid Interpolate ternary expression 'one' with delimiter '|'",
- lambda: Interpolate("echo '%(prop:P:#?|one)s'"))
-
- def test_prop_invalid_character(self):
- self.assertRaisesConfigError("Property name must be alphanumeric for prop Interpolation 'a+a'",
- lambda: Interpolate("echo '%(prop:a+a)s'"))
-
- def test_kw_invalid_character(self):
- self.assertRaisesConfigError("Keyword must be alphanumeric for kw Interpolation 'a+a'",
- lambda: Interpolate("echo '%(kw:a+a)s'"))
-
- def test_src_codebase_invalid_character(self):
- self.assertRaisesConfigError("Codebase must be alphanumeric for src Interpolation 'a+a:a'",
- lambda: Interpolate("echo '%(src:a+a:a)s'"))
-
- def test_src_attr_invalid_character(self):
- self.assertRaisesConfigError("Attribute must be alphanumeric for src Interpolation 'a:a+a'",
- lambda: Interpolate("echo '%(src:a:a+a)s'"))
-
- def test_src_missing_attr(self):
- self.assertRaisesConfigError("Must specify both codebase and attr",
- lambda: Interpolate("echo '%(src:a)s'"))
-
-
-class TestInterpolatePositional(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def test_string(self):
- command = Interpolate("test %s", "one fish")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "test one fish")
-
- def test_twoString(self):
- command = Interpolate("test %s, %s", "one fish", "two fish")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "test one fish, two fish")
-
- def test_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%s'", renderable)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'red fish'")
- renderable.callback("red fish")
- return d
-
- def test_renderable(self):
- self.props.setProperty("buildername", "blue fish", "test")
- command = Interpolate("echo '%s'", Property("buildername"))
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'blue fish'")
- return d
-
-
-
-class TestInterpolateProperties(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def test_properties(self):
- self.props.setProperty("buildername", "winbld", "test")
- command = Interpolate("echo buildby-%(prop:buildername)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-winbld")
- return d
-
- def test_properties_newline(self):
- self.props.setProperty("buildername", "winbld", "test")
- command = Interpolate("aa\n%(prop:buildername)s\nbb")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "aa\nwinbld\nbb")
- return d
-
- def test_property_not_set(self):
- command = Interpolate("echo buildby-%(prop:buildername)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-")
- return d
-
- def test_property_colon_minus(self):
- command = Interpolate("echo buildby-%(prop:buildername:-blddef)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-blddef")
- return d
-
- def test_property_colon_tilde_true(self):
- self.props.setProperty("buildername", "winbld", "test")
- command = Interpolate("echo buildby-%(prop:buildername:~blddef)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-winbld")
- return d
-
- def test_property_colon_tilde_false(self):
- self.props.setProperty("buildername", "", "test")
- command = Interpolate("echo buildby-%(prop:buildername:~blddef)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-blddef")
- return d
-
- def test_property_colon_plus(self):
- self.props.setProperty("project", "proj1", "test")
- command = Interpolate("echo %(prop:project:+projectdefined)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo projectdefined")
- return d
-
- def test_nested_property(self):
- self.props.setProperty("project", "so long!", "test")
- command = Interpolate("echo '%(prop:missing:~%(prop:project)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'so long!'")
- return d
-
- def test_property_substitute_recursively(self):
- self.props.setProperty("project", "proj1", "test")
- command = Interpolate("echo '%(prop:no_such:-%(prop:project)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'proj1'")
- return d
-
- def test_property_colon_ternary_present(self):
- self.props.setProperty("project", "proj1", "test")
- command = Interpolate("echo %(prop:project:?:defined:missing)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo defined")
- return d
-
- def test_property_colon_ternary_missing(self):
- command = Interpolate("echo %(prop:project:?|defined|missing)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo missing")
- return d
-
- def test_property_colon_ternary_hash_true(self):
- self.props.setProperty("project", "winbld", "test")
- command = Interpolate("echo buildby-%(prop:project:#?:T:F)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-T")
- return d
-
- def test_property_colon_ternary_hash_false(self):
- self.props.setProperty("project", "", "test")
- command = Interpolate("echo buildby-%(prop:project:#?|T|F)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-F")
- return d
-
- def test_property_colon_ternary_substitute_recursively_true(self):
- self.props.setProperty("P", "present", "test")
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one)s|%(prop:two)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'proj1'")
- return d
-
- def test_property_colon_ternary_substitute_recursively_false(self):
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one)s|%(prop:two)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'proj2'")
- return d
-
- def test_property_colon_ternary_substitute_recursively_delimited_true(self):
- self.props.setProperty("P", "present", "test")
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one:?|true|false)s|%(prop:two:?|false|true)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'true'")
- return d
-
- def test_property_colon_ternary_substitute_recursively_delimited_false(self):
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one:?|true|false)s|%(prop:two:?|false|true)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'false'")
- return d
-
-
-class TestInterpolateSrc(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
- sa = FakeSource()
- sb = FakeSource()
- sc = FakeSource()
-
- sa.repository = 'cvs://A..'
- sa.codebase = 'cbA'
- sa.project = "Project"
- self.build.sources['cbA'] = sa
-
- sb.repository = 'cvs://B..'
- sb.codebase = 'cbB'
- sb.project = "Project"
- self.build.sources['cbB'] = sb
-
- sc.repository = 'cvs://C..'
- sc.codebase = 'cbC'
- sc.project = None
- self.build.sources['cbC'] = sc
-
- def test_src(self):
- command = Interpolate("echo %(src:cbB:repository)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_src_src(self):
- command = Interpolate("echo %(src:cbB:repository)s %(src:cbB:project)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B.. Project")
- return d
-
- def test_src_attr_empty(self):
- command = Interpolate("echo %(src:cbC:project)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_src_attr_codebase_notfound(self):
- command = Interpolate("echo %(src:unknown_codebase:project)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_src_colon_plus_false(self):
- command = Interpolate("echo '%(src:cbD:project:+defaultrepo)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ''")
- return d
-
- def test_src_colon_plus_true(self):
- command = Interpolate("echo '%(src:cbB:project:+defaultrepo)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'defaultrepo'")
- return d
-
- def test_src_colon_minus(self):
- command = Interpolate("echo %(src:cbB:nonattr:-defaultrepo)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo defaultrepo")
- return d
-
- def test_src_colon_minus_false(self):
- command = Interpolate("echo '%(src:cbC:project:-noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ''")
- return d
-
- def test_src_colon_minus_true(self):
- command = Interpolate("echo '%(src:cbB:project:-noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'Project'")
- return d
-
- def test_src_colon_minus_codebase_notfound(self):
- command = Interpolate("echo '%(src:unknown_codebase:project:-noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'noproject'")
- return d
-
- def test_src_colon_tilde_true(self):
- command = Interpolate("echo '%(src:cbB:project:~noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'Project'")
- return d
-
- def test_src_colon_tilde_false(self):
- command = Interpolate("echo '%(src:cbC:project:~noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'noproject'")
- return d
-
- def test_src_colon_tilde_false_src_as_replacement(self):
- command = Interpolate("echo '%(src:cbC:project:~%(src:cbA:project)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'Project'")
- return d
-
- def test_src_colon_tilde_codebase_notfound(self):
- command = Interpolate("echo '%(src:unknown_codebase:project:~noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'noproject'")
- return d
-
-
-class TestInterpolateKwargs(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
- sa = FakeSource()
-
- sa.repository = 'cvs://A..'
- sa.codebase = 'cbA'
- sa.project = None
- sa.branch = "default"
- self.build.sources['cbA'] = sa
-
- def test_kwarg(self):
- command = Interpolate("echo %(kw:repository)s", repository = "cvs://A..")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A..")
- return d
-
- def test_kwarg_kwarg(self):
- command = Interpolate("echo %(kw:repository)s %(kw:branch)s",
- repository = "cvs://A..", branch = "default")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A.. default")
- return d
-
- def test_kwarg_not_mapped(self):
- command = Interpolate("echo %(kw:repository)s", project = "projectA")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_kwarg_colon_minus_not_available(self):
- command = Interpolate("echo %(kw:repository)s", project = "projectA")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_kwarg_colon_minus_not_available_default(self):
- command = Interpolate("echo %(kw:repository:-cvs://A..)s", project = "projectA")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A..")
- return d
-
- def test_kwarg_colon_minus_available(self):
- command = Interpolate("echo %(kw:repository:-cvs://A..)s", repository = "cvs://B..")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwarg_colon_tilde_true(self):
- command = Interpolate("echo %(kw:repository:~cvs://B..)s", repository = "cvs://A..")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A..")
- return d
-
- def test_kwarg_colon_tilde_false(self):
- command = Interpolate("echo %(kw:repository:~cvs://B..)s", repository = "")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwarg_colon_tilde_none(self):
- command = Interpolate("echo %(kw:repository:~cvs://B..)s", repository = None)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwarg_colon_plus_false(self):
- command = Interpolate("echo %(kw:repository:+cvs://B..)s", project = "project")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_kwarg_colon_plus_true(self):
- command = Interpolate("echo %(kw:repository:+cvs://B..)s", repository = None)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwargs_colon_minus_false_src_as_replacement(self):
- command = Interpolate("echo '%(kw:text:-%(src:cbA:branch)s)s'", notext='ddd')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'default'")
- return d
-
- def test_kwargs_renderable(self):
- command = Interpolate("echo '%(kw:test)s'", test = ConstantRenderable('testing'))
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'testing'")
- return d
-
- def test_kwargs_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%(kw:test)s'", test = renderable)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'testing'")
- renderable.callback('testing')
- return d
-
- def test_kwarg_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%(kw:project)s'", project=renderable)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'testing'")
- renderable.callback('testing')
- return d
-
- def test_nested_kwarg_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%(kw:missing:~%(kw:fishy)s)s'", missing=renderable, fishy="so long!")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'so long!'")
- renderable.callback(False)
- return d
-
-class TestWithProperties(unittest.TestCase):
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def testInvalidParams(self):
- self.assertRaises(ValueError, lambda :
- WithProperties("%s %(foo)s", 1, foo=2))
-
- def testBasic(self):
- # test basic substitution with WithProperties
- self.props.setProperty("revision", "47", "test")
- command = WithProperties("build-%s.tar.gz", "revision")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-47.tar.gz")
- return d
-
- def testDict(self):
- # test dict-style substitution with WithProperties
- self.props.setProperty("other", "foo", "test")
- command = WithProperties("build-%(other)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-foo.tar.gz")
- return d
-
- def testDictColonMinus(self):
- # test dict-style substitution with WithProperties
- self.props.setProperty("prop1", "foo", "test")
- command = WithProperties("build-%(prop1:-empty)s-%(prop2:-empty)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-foo-empty.tar.gz")
- return d
-
- def testDictColonPlus(self):
- # test dict-style substitution with WithProperties
- self.props.setProperty("prop1", "foo", "test")
- command = WithProperties("build-%(prop1:+exists)s-%(prop2:+exists)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-exists-.tar.gz")
- return d
-
- def testEmpty(self):
- # None should render as ''
- self.props.setProperty("empty", None, "test")
- command = WithProperties("build-%(empty)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-.tar.gz")
- return d
-
- def testRecursiveList(self):
- self.props.setProperty("x", 10, "test")
- self.props.setProperty("y", 20, "test")
- command = [ WithProperties("%(x)s %(y)s"), "and",
- WithProperties("%(y)s %(x)s") ]
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- ["10 20", "and", "20 10"])
- return d
-
- def testRecursiveTuple(self):
- self.props.setProperty("x", 10, "test")
- self.props.setProperty("y", 20, "test")
- command = ( WithProperties("%(x)s %(y)s"), "and",
- WithProperties("%(y)s %(x)s") )
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- ("10 20", "and", "20 10"))
- return d
-
- def testRecursiveDict(self):
- self.props.setProperty("x", 10, "test")
- self.props.setProperty("y", 20, "test")
- command = { WithProperties("%(x)s %(y)s") :
- WithProperties("%(y)s %(x)s") }
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- {"10 20" : "20 10"})
- return d
-
- def testLambdaSubst(self):
- command = WithProperties('%(foo)s', foo=lambda _: 'bar')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'bar')
- return d
-
- def testLambdaHasattr(self):
- command = WithProperties('%(foo)s',
- foo=lambda b : b.hasProperty('x') and 'x' or 'y')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'y')
- return d
-
- def testLambdaOverride(self):
- self.props.setProperty('x', 10, 'test')
- command = WithProperties('%(x)s', x=lambda _: 20)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, '20')
- return d
-
- def testLambdaCallable(self):
- self.assertRaises(ValueError, lambda: WithProperties('%(foo)s', foo='bar'))
-
- def testLambdaUseExisting(self):
- self.props.setProperty('x', 10, 'test')
- self.props.setProperty('y', 20, 'test')
- command = WithProperties('%(z)s', z=lambda props: props.getProperty('x') + props.getProperty('y'))
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, '30')
- return d
-
- def testColon(self):
- self.props.setProperty('some:property', 10, 'test')
- command = WithProperties('%(some:property:-with-default)s')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, '10')
- return d
-
- def testColon_default(self):
- command = WithProperties('%(some:property:-with-default)s')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'with-default')
- return d
-
- def testColon_colon(self):
- command = WithProperties('%(some:property:-with:default)s')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'with:default')
- return d
-
-class TestProperties(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
-
- def testDictBehavior(self):
- # note that dictionary-like behavior is deprecated and not exposed to
- # users!
- self.props.setProperty("do-tests", 1, "scheduler")
- self.props.setProperty("do-install", 2, "scheduler")
-
- self.assert_(self.props.has_key('do-tests'))
- self.failUnlessEqual(self.props['do-tests'], 1)
- self.failUnlessEqual(self.props['do-install'], 2)
- self.assertRaises(KeyError, lambda : self.props['do-nothing'])
- self.failUnlessEqual(self.props.getProperty('do-install'), 2)
- self.assertIn('do-tests', self.props)
- self.assertNotIn('missing-do-tests', self.props)
-
- def testAsList(self):
- self.props.setProperty("happiness", 7, "builder")
- self.props.setProperty("flames", True, "tester")
-
- self.assertEqual(sorted(self.props.asList()),
- [ ('flames', True, 'tester'), ('happiness', 7, 'builder') ])
-
- def testAsDict(self):
- self.props.setProperty("msi_filename", "product.msi", 'packager')
- self.props.setProperty("dmg_filename", "product.dmg", 'packager')
-
- self.assertEqual(self.props.asDict(),
- dict(msi_filename=('product.msi', 'packager'), dmg_filename=('product.dmg', 'packager')))
-
- def testUpdate(self):
- self.props.setProperty("x", 24, "old")
- newprops = { 'a' : 1, 'b' : 2 }
- self.props.update(newprops, "new")
-
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
- self.failUnlessEqual(self.props.getProperty('a'), 1)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'new')
-
- def testUpdateRuntime(self):
- self.props.setProperty("x", 24, "old")
- newprops = { 'a' : 1, 'b' : 2 }
- self.props.update(newprops, "new", runtime=True)
-
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
- self.failUnlessEqual(self.props.getProperty('a'), 1)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'new')
- self.assertEqual(self.props.runtime, set(['a', 'b']))
-
- def testUpdateFromProperties(self):
- self.props.setProperty("a", 94, "old")
- self.props.setProperty("x", 24, "old")
- newprops = Properties()
- newprops.setProperty('a', 1, "new")
- newprops.setProperty('b', 2, "new")
- self.props.updateFromProperties(newprops)
-
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
- self.failUnlessEqual(self.props.getProperty('a'), 1)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'new')
-
- def testUpdateFromPropertiesNoRuntime(self):
- self.props.setProperty("a", 94, "old")
- self.props.setProperty("b", 84, "old")
- self.props.setProperty("x", 24, "old")
- newprops = Properties()
- newprops.setProperty('a', 1, "new", runtime=True)
- newprops.setProperty('b', 2, "new", runtime=False)
- newprops.setProperty('c', 3, "new", runtime=True)
- newprops.setProperty('d', 3, "new", runtime=False)
- self.props.updateFromPropertiesNoRuntime(newprops)
-
- self.failUnlessEqual(self.props.getProperty('a'), 94)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'old')
- self.failUnlessEqual(self.props.getProperty('b'), 2)
- self.failUnlessEqual(self.props.getPropertySource('b'), 'new')
- self.failUnlessEqual(self.props.getProperty('c'), None) # not updated
- self.failUnlessEqual(self.props.getProperty('d'), 3)
- self.failUnlessEqual(self.props.getPropertySource('d'), 'new')
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
-
- @compat.usesFlushWarnings
- def test_setProperty_notJsonable(self):
- self.props.setProperty("project", ConstantRenderable('testing'), "test")
- self.props.setProperty("project", object, "test")
- self.assertEqual(len(self.flushWarnings([self.test_setProperty_notJsonable])), 2)
-
- # IProperties methods
-
- def test_getProperty(self):
- self.props.properties['p1'] = (['p', 1], 'test')
- self.assertEqual(self.props.getProperty('p1'), ['p', 1])
-
- def test_getProperty_default_None(self):
- self.assertEqual(self.props.getProperty('p1'), None)
-
- def test_getProperty_default(self):
- self.assertEqual(self.props.getProperty('p1', 2), 2)
-
- def test_hasProperty_false(self):
- self.assertFalse(self.props.hasProperty('x'))
-
- def test_hasProperty_true(self):
- self.props.properties['x'] = (False, 'test')
- self.assertTrue(self.props.hasProperty('x'))
-
- def test_has_key_false(self):
- self.assertFalse(self.props.has_key('x'))
-
- def test_setProperty(self):
- self.props.setProperty('x', 'y', 'test')
- self.assertEqual(self.props.properties['x'], ('y', 'test'))
- self.assertNotIn('x', self.props.runtime)
-
- def test_setProperty_runtime(self):
- self.props.setProperty('x', 'y', 'test', runtime=True)
- self.assertEqual(self.props.properties['x'], ('y', 'test'))
- self.assertIn('x', self.props.runtime)
-
- def test_setProperty_no_source(self):
- self.assertRaises(TypeError, lambda :
- self.props.setProperty('x', 'y'))
-
- def test_getProperties(self):
- self.assertIdentical(self.props.getProperties(), self.props)
-
- def test_getBuild(self):
- self.assertIdentical(self.props.getBuild(), self.props.build)
-
- def test_render(self):
- class Renderable(object):
- implements(IRenderable)
- def getRenderingFor(self, props):
- return props.getProperty('x') + 'z'
- self.props.setProperty('x', 'y', 'test')
- d = self.props.render(Renderable())
- d.addCallback(self.assertEqual, 'yz')
- return d
-
-
-class MyPropertiesThing(PropertiesMixin):
- set_runtime_properties = True
-
-def adaptMyProperties(mp):
- return mp.properties
-
-components.registerAdapter(adaptMyProperties, MyPropertiesThing, IProperties)
-
-
-class TestPropertiesMixin(unittest.TestCase):
-
- def setUp(self):
- self.mp = MyPropertiesThing()
- self.mp.properties = mock.Mock()
-
- def test_getProperty(self):
- self.mp.getProperty('abc')
- self.mp.properties.getProperty.assert_called_with('abc', None)
-
- def xtest_getProperty_default(self):
- self.mp.getProperty('abc', 'def')
- self.mp.properties.getProperty.assert_called_with('abc', 'def')
-
- def test_hasProperty(self):
- self.mp.properties.hasProperty.return_value = True
- self.assertTrue(self.mp.hasProperty('abc'))
- self.mp.properties.hasProperty.assert_called_with('abc')
-
- def test_has_key(self):
- self.mp.properties.hasProperty.return_value = True
- self.assertTrue(self.mp.has_key('abc'))
- self.mp.properties.hasProperty.assert_called_with('abc')
-
- def test_setProperty(self):
- self.mp.setProperty('abc', 'def', 'src')
- self.mp.properties.setProperty.assert_called_with('abc', 'def', 'src',
- runtime=True)
-
- def test_setProperty_no_source(self):
- # this compatibility is maintained for old code
- self.mp.setProperty('abc', 'def')
- self.mp.properties.setProperty.assert_called_with('abc', 'def',
- 'Unknown', runtime=True)
-
- def test_render(self):
- self.mp.render([1,2])
- self.mp.properties.render.assert_called_with([1,2])
-
-class TestProperty(unittest.TestCase):
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def testIntProperty(self):
- self.props.setProperty("do-tests", 1, "scheduler")
- value = Property("do-tests")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- 1)
- return d
-
- def testStringProperty(self):
- self.props.setProperty("do-tests", "string", "scheduler")
- value = Property("do-tests")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "string")
- return d
-
- def testMissingProperty(self):
- value = Property("do-tests")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- None)
- return d
-
- def testDefaultValue(self):
- value = Property("do-tests", default="Hello!")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "Hello!")
- return d
-
- def testDefaultValueNested(self):
- self.props.setProperty("xxx", 'yyy', "scheduler")
- value = Property("do-tests",
- default=WithProperties("a-%(xxx)s-b"))
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "a-yyy-b")
- return d
-
- def testIgnoreDefaultValue(self):
- self.props.setProperty("do-tests", "string", "scheduler")
- value = Property("do-tests", default="Hello!")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "string")
- return d
-
- def testIgnoreFalseValue(self):
- self.props.setProperty("do-tests-string", "", "scheduler")
- self.props.setProperty("do-tests-int", 0, "scheduler")
- self.props.setProperty("do-tests-list", [], "scheduler")
- self.props.setProperty("do-tests-None", None, "scheduler")
-
- value = [ Property("do-tests-string", default="Hello!"),
- Property("do-tests-int", default="Hello!"),
- Property("do-tests-list", default="Hello!"),
- Property("do-tests-None", default="Hello!") ]
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- ["Hello!"] * 4)
- return d
-
- def testDefaultWhenFalse(self):
- self.props.setProperty("do-tests-string", "", "scheduler")
- self.props.setProperty("do-tests-int", 0, "scheduler")
- self.props.setProperty("do-tests-list", [], "scheduler")
- self.props.setProperty("do-tests-None", None, "scheduler")
-
- value = [ Property("do-tests-string", default="Hello!", defaultWhenFalse=False),
- Property("do-tests-int", default="Hello!", defaultWhenFalse=False),
- Property("do-tests-list", default="Hello!", defaultWhenFalse=False),
- Property("do-tests-None", default="Hello!", defaultWhenFalse=False) ]
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- ["", 0, [], None])
- return d
-
- def testDeferredDefault(self):
- default = DeferredRenderable()
- value = Property("no-such-property", default)
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "default-value")
- default.callback("default-value")
- return d
-
-
-class TestRenderalbeAdapters(unittest.TestCase):
- """
- Tests for list, tuple and dict renderers.
- """
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
-
- def test_list_deferred(self):
- r1 = DeferredRenderable()
- r2 = DeferredRenderable()
- d = self.build.render([r1, r2])
- d.addCallback(self.failUnlessEqual,
- ["lispy", "lists"])
- r2.callback("lists")
- r1.callback("lispy")
- return d
-
-
- def test_tuple_deferred(self):
- r1 = DeferredRenderable()
- r2 = DeferredRenderable()
- d = self.build.render((r1, r2))
- d.addCallback(self.failUnlessEqual,
- ("totally", "tupled"))
- r2.callback("tupled")
- r1.callback("totally")
- return d
-
-
- def test_dict(self):
- r1 = DeferredRenderable()
- r2 = DeferredRenderable()
- k1 = DeferredRenderable()
- k2 = DeferredRenderable()
- d = self.build.render({k1: r1, k2: r2})
- d.addCallback(self.failUnlessEqual,
- {"lock": "load", "dict": "lookup"})
- k1.callback("lock")
- r1.callback("load")
- k2.callback("dict")
- r2.callback("lookup")
- return d
-
-class Renderer(unittest.TestCase):
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
-
- def test_renderer(self):
- self.props.setProperty("x", "X", "test")
- d = self.build.render(
- renderer(lambda p : 'x%sx' % p.getProperty('x')))
- d.addCallback(self.failUnlessEqual, 'xXx')
- return d
-
- def test_renderer_called(self):
- # it's tempting to try to call the decorated function. Don't do that.
- # It's not a function anymore.
- d = defer.maybeDeferred(lambda :
- self.build.render(renderer(lambda p : 'x')('y')))
- self.failUnlessFailure(d, TypeError)
- return d
-
- def test_renderer_decorator(self):
- self.props.setProperty("x", "X", "test")
- @renderer
- def rend(p):
- return 'x%sx' % p.getProperty('x')
- d = self.build.render(rend)
- d.addCallback(self.failUnlessEqual, 'xXx')
- return d
-
- def test_renderer_deferred(self):
- self.props.setProperty("x", "X", "test")
- d = self.build.render(
- renderer(lambda p : defer.succeed('y%sy' % p.getProperty('x'))))
- d.addCallback(self.failUnlessEqual, 'yXy')
- return d
-
- def test_renderer_fails(self):
- d = self.build.render(
- renderer(lambda p : defer.fail(RuntimeError("oops"))))
- self.failUnlessFailure(d, RuntimeError)
- return d
-
-class Compare(unittest.TestCase):
-
- def test_WithProperties_lambda(self):
- self.failIfEqual(WithProperties("%(key)s", key=lambda p:'val'), WithProperties("%(key)s", key=lambda p:'val'))
- def rend(p):
- return "val"
- self.failUnlessEqual(
- WithProperties("%(key)s", key=rend),
- WithProperties("%(key)s", key=rend))
- self.failIfEqual(
- WithProperties("%(key)s", key=rend),
- WithProperties("%(key)s", otherkey=rend))
-
- def test_WithProperties_positional(self):
- self.failIfEqual(
- WithProperties("%s", 'key'),
- WithProperties("%s", 'otherkey'))
- self.failUnlessEqual(
- WithProperties("%s", 'key'),
- WithProperties("%s", 'key'))
- self.failIfEqual(
- WithProperties("%s", 'key'),
- WithProperties("k%s", 'key'))
-
- def test_Interpolate_constant(self):
- self.failIfEqual(
- Interpolate('some text here'),
- Interpolate('and other text there'))
- self.failUnlessEqual(
- Interpolate('some text here'),
- Interpolate('some text here'))
-
- def test_Interpolate_positional(self):
- self.failIfEqual(
- Interpolate('%s %s', "test", "text"),
- Interpolate('%s %s', "other", "text"))
- self.failUnlessEqual(
- Interpolate('%s %s', "test", "text"),
- Interpolate('%s %s', "test", "text"))
-
- def test_Interpolate_kwarg(self):
- self.failIfEqual(
- Interpolate("%(kw:test)s", test=object(), other=2),
- Interpolate("%(kw:test)s", test=object(), other=2))
- self.failUnlessEqual(
- Interpolate('testing: %(kw:test)s', test="test", other=3),
- Interpolate('testing: %(kw:test)s', test="test", other=3))
-
- def test_renderer(self):
- self.failIfEqual(
- renderer(lambda p:'val'),
- renderer(lambda p:'val'))
- def rend(p):
- return "val"
- self.failUnlessEqual(
- renderer(rend),
- renderer(rend))
-
- def test_Lookup_simple(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'other'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
-
- def test_Lookup_default(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', default='default'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', default='default'),
- _Lookup({'test': 5, 'other': 6}, 'test', default='default'))
-
- def test_Lookup_defaultWhenFalse(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=False),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=False),
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True),
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test'),
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True))
-
- def test_Lookup_hasKey(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey=None),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'),
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='other-key'))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'),
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'))
-
- def test_Lookup_elideNoneAs(self):
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs=None),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs=''),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs='got None'),
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs=''))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs='got None'),
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs='got None'))
-
- def test_Lazy(self):
- self.failIfEqual(
- _Lazy(5),
- _Lazy(6))
- self.failUnlessEqual(
- _Lazy(5),
- _Lazy(5))
-
- def test_SourceStampDict(self):
- self.failIfEqual(
- _SourceStampDict('binary'),
- _SourceStampDict('library'))
- self.failUnlessEqual(
- _SourceStampDict('binary'),
- _SourceStampDict('binary'))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py
deleted file mode 100644
index 031f9677..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.process.users import manager, manual
-from buildbot import config
-
-class FakeUserManager(manual.UsersBase):
- pass
-
-class TestUserManager(unittest.TestCase):
- def setUp(self):
- self.master = mock.Mock()
- self.umm = manager.UserManagerManager(self.master)
- self.umm.startService()
-
- self.config = config.MasterConfig()
-
- def tearDown(self):
- self.umm.stopService()
-
- @defer.inlineCallbacks
- def test_reconfigService(self):
- # add a user manager
- um1 = FakeUserManager()
- self.config.user_managers = [ um1 ]
-
- yield self.umm.reconfigService(self.config)
-
- self.assertTrue(um1.running)
- self.assertIdentical(um1.master, self.master)
-
- # and back to nothing
- self.config.user_managers = [ ]
- yield self.umm.reconfigService(self.config)
-
- self.assertIdentical(um1.master, None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py
deleted file mode 100644
index 9b330051..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# this class is known to contain cruft and will be looked at later, so
-# no current implementation utilizes it aside from scripts.runner.
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildbot.test.fake import fakedb
-from buildbot.process.users import manual
-
-class ManualUsersMixin(object):
- """
- This class fakes out the master/db components to test the manual
- user managers located in process.users.manual.
- """
-
- class FakeMaster(object):
-
- def __init__(self):
- self.db = fakedb.FakeDBConnector(self)
- self.slavePortnum = "tcp:9989"
- self.caches = mock.Mock(name="caches")
- self.caches.get_cache = self.get_cache
-
- def get_cache(self, cache_name, miss_fn):
- c = mock.Mock(name=cache_name)
- c.get = miss_fn
- return c
-
- def setUpManualUsers(self):
- self.master = self.FakeMaster()
-
-class TestUsersBase(unittest.TestCase):
- """
- Not really sure what there is to test, aside from _setUpManualUsers getting
- self.master set.
- """
- pass
-
-class TestCommandlineUserManagerPerspective(unittest.TestCase, ManualUsersMixin):
-
- def setUp(self):
- self.setUpManualUsers()
-
- def call_perspective_commandline(self, *args):
- persp = manual.CommandlineUserManagerPerspective(self.master)
- return persp.perspective_commandline(*args)
-
- def test_perspective_commandline_add(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'git': 'x'}])
- def check_get(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- git='x'))
- d.addCallback(real_check)
- return d
- d.addCallback(check_get)
- return d
-
- def test_perspective_commandline_update(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline(
- 'update', None, None, None,
- [{'identifier':'x', 'svn':'y'}]))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- svn='y'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_update_bb(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x',
- 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline(
- 'update', 'bb_user',
- 'hashed_bb_pass', None,
- [{'identifier':'x'}]))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username='bb_user',
- bb_password='hashed_bb_pass',
- svn='x'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_update_both(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x',
- 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline(
- 'update', 'bb_user',
- 'hashed_bb_pass', None,
- [{'identifier':'x',
- 'svn':'y'}]))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username='bb_user',
- bb_password='hashed_bb_pass',
- svn='y'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_remove(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'h@c',
- 'git': 'hi <h@c>'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('remove', None,
- None, ['x'], None))
- def check(_):
- d = self.master.db.users.getUser('x')
- def real_check(res):
- self.assertEqual(res, None)
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x',
- 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('get', None, None,
- ['x'], None))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(res):
- self.assertEqual(res, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- svn='x'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get_multiple_attrs(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier': 'x',
- 'svn': 'x',
- 'git': 'x@c'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('get', None, None,
- ['x'], None))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(res):
- self.assertEqual(res, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- svn='x',
- git='x@c'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_add_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'svn':'x'}])
- def check(result):
- exp_format = "user(s) added:\nidentifier: x\nuid: 1\n\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_update_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('update', None, None, None,
- [{'identifier':'x',
- 'svn':'y'}]))
- def check(result):
- exp_format = 'user(s) updated:\nidentifier: x\n'
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_remove_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'h@c',
- 'git': 'hi <h@c>'}])
- d.addCallback(lambda _ : self.call_perspective_commandline('remove',
- None, None,
- ['h@c'],
- None))
- def check(result):
- exp_format = "user(s) removed:\nidentifier: h@c\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x@y', 'git': 'x <x@y>'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('get', None, None,
- ['x@y'], None))
- def check(result):
- exp_format = 'user(s) found:\ngit: x <x@y>\nidentifier: x@y\n' \
- 'bb_username: None\nuid: 1\n\n'
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_remove_no_match_format(self):
- d = self.call_perspective_commandline('remove', None, None, ['x'], None)
- def check(result):
- exp_format = "user(s) removed:\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get_no_match_format(self):
- d = self.call_perspective_commandline('get', None, None, ['x'], None)
- def check(result):
- exp_format = "user(s) found:\nno match found\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
-class TestCommandlineUserManager(unittest.TestCase, ManualUsersMixin):
-
- def setUp(self):
- self.setUpManualUsers()
- self.manual_component = manual.CommandlineUserManager(username="user",
- passwd="userpw",
- port="9990")
- self.manual_component.master = self.master
-
- def test_no_userpass(self):
- d = defer.maybeDeferred(lambda : manual.CommandlineUserManager())
- return self.assertFailure(d, AssertionError)
-
- def test_no_port(self):
- d = defer.maybeDeferred(lambda : manual.CommandlineUserManager(username="x",
- passwd="y"))
- return self.assertFailure(d, AssertionError)
-
- def test_service(self):
- # patch out the pbmanager's 'register' command both to be sure
- # the registration is correct and to get a copy of the factory
- registration = mock.Mock()
- registration.unregister = lambda : defer.succeed(None)
- self.master.pbmanager = mock.Mock()
- def register(portstr, user, passwd, factory):
- self.assertEqual([portstr, user, passwd],
- ['9990', 'user', 'userpw'])
- self.got_factory = factory
- return registration
- self.master.pbmanager.register = register
-
- self.manual_component.startService()
-
- persp = self.got_factory(mock.Mock(), 'user')
- self.failUnless(isinstance(persp, manual.CommandlineUserManagerPerspective))
-
- return self.manual_component.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py
deleted file mode 100644
index 3c3b7bb8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-
-from buildbot.process.users import users
-from buildbot.test.fake import fakedb
-
-class UsersTests(unittest.TestCase):
-
- def setUp(self):
- self.master = mock.Mock()
- self.master.db = self.db = fakedb.FakeDBConnector(self)
- self.test_sha = users.encrypt("cancer")
-
- def test_createUserObject_no_src(self):
- d = users.createUserObject(self.master, "Tyler Durden", None)
- def check(_):
- self.assertEqual(self.db.users.users, {})
- self.assertEqual(self.db.users.users_info, {})
- d.addCallback(check)
- return d
-
- def test_createUserObject_unrecognized_src(self):
- d = users.createUserObject(self.master, "Tyler Durden", 'blah')
- def check(_):
- self.assertEqual(self.db.users.users, {})
- self.assertEqual(self.db.users.users_info, {})
- d.addCallback(check)
- return d
-
- def test_createUserObject_git(self):
- d = users.createUserObject(self.master,
- "Tyler Durden <tyler@mayhem.net>", 'git')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='Tyler Durden <tyler@mayhem.net>',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="git",
- attr_data="Tyler Durden <tyler@mayhem.net>")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_svn(self):
- d = users.createUserObject(self.master, "tdurden", 'svn')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='tdurden',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="svn",
- attr_data="tdurden")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_hg(self):
- d = users.createUserObject(self.master,
- "Tyler Durden <tyler@mayhem.net>", 'hg')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='Tyler Durden <tyler@mayhem.net>',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="hg",
- attr_data="Tyler Durden <tyler@mayhem.net>")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_cvs(self):
- d = users.createUserObject(self.master, "tdurden", 'cvs')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='tdurden',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="cvs",
- attr_data="tdurden")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_darcs(self):
- d = users.createUserObject(self.master, "tyler@mayhem.net", 'darcs')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='tyler@mayhem.net',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="darcs",
- attr_data="tyler@mayhem.net")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_bzr(self):
- d = users.createUserObject(self.master, "Tyler Durden", 'bzr')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='Tyler Durden',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="bzr",
- attr_data="Tyler Durden")]})
- d.addCallback(check)
- return d
-
- def test_getUserContact_found(self):
- self.db.insertTestData([fakedb.User(uid=1, identifier='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='svn',
- attr_data='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data='tyler@mayhem.net')])
- d = users.getUserContact(self.master, contact_types=['email'], uid=1)
- def check(contact):
- self.assertEqual(contact, 'tyler@mayhem.net')
- d.addCallback(check)
- return d
-
- def test_getUserContact_key_not_found(self):
- self.db.insertTestData([fakedb.User(uid=1, identifier='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='svn',
- attr_data='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data='tyler@mayhem.net')])
- d = users.getUserContact(self.master, contact_types=['blargh'], uid=1)
- def check(contact):
- self.assertEqual(contact, None)
- d.addCallback(check)
- return d
-
- def test_getUserContact_uid_not_found(self):
- d = users.getUserContact(self.master, contact_types=['email'], uid=1)
- def check(contact):
- self.assertEqual(contact, None)
- d.addCallback(check)
- return d
-
- def test_check_passwd(self):
- res = users.check_passwd("cancer", self.test_sha)
- self.assertEqual(res, True)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py
deleted file mode 100644
index 70c53404..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.revlinks import RevlinkMatch, GithubRevlink, SourceforgeGitRevlink, GitwebMatch
-
-class TestGithubRevlink(unittest.TestCase):
- revision = 'b6874701b54e0043a78882b020afc86033133f91'
- url = 'https://github.com/buildbot/buildbot/commit/b6874701b54e0043a78882b020afc86033133f91'
- def testHTTPS(self):
- self.assertEqual(GithubRevlink(self.revision, 'https://github.com/buildbot/buildbot.git'),
- self.url)
-
- def testGIT(self):
- self.assertEqual(GithubRevlink(self.revision, 'git://github.com/buildbot/buildbot.git'),
- self.url)
-
- def testSSH(self):
- self.assertEqual(GithubRevlink(self.revision, 'git@github.com:buildbot/buildbot.git'),
- self.url)
-
- def testSSHuri(self):
- self.assertEqual(GithubRevlink(self.revision, 'ssh://git@github.com/buildbot/buildbot.git'),
- self.url)
-
-class TestSourceforgeGitRevlink(unittest.TestCase):
- revision = 'b99c89a2842d386accea8072ae5bb6e24aa7cf29'
- url = 'http://gemrb.git.sourceforge.net/git/gitweb.cgi?p=gemrb/gemrb;a=commit;h=b99c89a2842d386accea8072ae5bb6e24aa7cf29'
-
- def testGIT(self):
- self.assertEqual(SourceforgeGitRevlink(self.revision, 'git://gemrb.git.sourceforge.net/gitroot/gemrb/gemrb'),
- self.url)
-
- def testSSH(self):
- self.assertEqual(SourceforgeGitRevlink(self.revision, 'somebody@gemrb.git.sourceforge.net:gitroot/gemrb/gemrb'),
- self.url)
-
- def testSSHuri(self):
- self.assertEqual(SourceforgeGitRevlink(self.revision, 'ssh://somebody@gemrb.git.sourceforge.net/gitroot/gemrb/gemrb'),
- self.url)
-
-class TestRevlinkMatch(unittest.TestCase):
- def testNotmuch(self):
- revision = 'f717d2ece1836c863f9cc02abd1ff2539307cd1d'
- matcher = RevlinkMatch(['git://notmuchmail.org/git/(.*)'],
- r'http://git.notmuchmail.org/git/\1/commit/%s')
- self.assertEquals(matcher(revision, 'git://notmuchmail.org/git/notmuch'),
- 'http://git.notmuchmail.org/git/notmuch/commit/f717d2ece1836c863f9cc02abd1ff2539307cd1d')
-
- def testSingleString(self):
- revision = 'rev'
- matcher = RevlinkMatch('test', 'out%s')
- self.assertEquals(matcher(revision, 'test'), 'outrev')
-
- def testSingleUnicode(self):
- revision = 'rev'
- matcher = RevlinkMatch(u'test', 'out%s')
- self.assertEquals(matcher(revision, 'test'), 'outrev')
-
- def testTwoCaptureGroups(self):
- revision = 'rev'
- matcher = RevlinkMatch('([A-Z]*)Z([0-9]*)', r'\2-\1-%s')
- self.assertEquals(matcher(revision, 'ABCZ43'), '43-ABC-rev')
-
-class TestGitwebMatch(unittest.TestCase):
- def testOrgmode(self):
- revision = '490d6ace10e0cfe74bab21c59e4b7bd6aa3c59b8'
- matcher = GitwebMatch('git://orgmode.org/(?P<repo>.*)', 'http://orgmode.org/w/')
- self.assertEquals(matcher(revision, 'git://orgmode.org/org-mode.git'),
- 'http://orgmode.org/w/?p=org-mode.git;a=commit;h=490d6ace10e0cfe74bab21c59e4b7bd6aa3c59b8')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py
deleted file mode 100644
index 7eaa003d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py
+++ /dev/null
@@ -1,523 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import mock
-import twisted
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.schedulers import base
-from buildbot.process import properties
-from buildbot.test.util import scheduler
-from buildbot.test.fake import fakedb
-
-class BaseScheduler(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 19
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, name='testsched', builderNames=['a', 'b'],
- properties={}, codebases = {'':{}}):
- sched = self.attachScheduler(
- base.BaseScheduler(name=name, builderNames=builderNames,
- properties=properties, codebases=codebases),
- self.OBJECTID)
-
- return sched
-
- # tests
-
- def test_constructor_builderNames(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(builderNames='xxx'))
-
- def test_constructor_builderNames_unicode(self):
- self.makeScheduler(builderNames=[u'a'])
-
- def test_constructor_codebases_valid(self):
- codebases = {"codebase1": {"repository":"", "branch":"", "revision":""}}
- self.makeScheduler(codebases = codebases)
-
- def test_constructor_codebases_invalid(self):
- # scheduler only accepts codebases with at least repository set
- codebases = {"codebase1": {"dictionary":"", "that":"", "fails":""}}
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(codebases = codebases))
-
- def test_listBuilderNames(self):
- sched = self.makeScheduler(builderNames=['x', 'y'])
- self.assertEqual(sched.listBuilderNames(), ['x', 'y'])
-
- def test_getPendingBuildTimes(self):
- sched = self.makeScheduler()
- self.assertEqual(sched.getPendingBuildTimes(), [])
-
- def test_addBuildsetForLatest_defaults(self):
- sched = self.makeScheduler(name='testy', builderNames=['x'],
- properties=dict(a='b'))
- d = sched.addBuildsetForLatest(reason='because')
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='because', brids=brids,
- external_idstring=None,
- properties=[ ('a', ('b', 'Scheduler')),
- ('scheduler', ('testy', 'Scheduler')), ],
- sourcestampsetid=100),
- {'':
- dict(branch=None, revision=None, repository='', codebase='',
- project='', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_startConsumingChanges_fileIsImportant_check(self):
- sched = self.makeScheduler()
- self.assertRaises(AssertionError,
- lambda : sched.startConsumingChanges(fileIsImportant="maybe"))
-
- def do_test_change_consumption(self, kwargs, change, expected_result):
- # (expected_result should be True (important), False (unimportant), or
- # None (ignore the change))
- sched = self.makeScheduler()
- sched.startService()
-
- change_received = [ None ]
- def gotChange(got_change, got_important):
- self.assertEqual(got_change, change)
- change_received[0] = got_important
- return defer.succeed(None)
- sched.gotChange = gotChange
-
- d = sched.startConsumingChanges(**kwargs)
- def test(_):
- # check that it registered a callback
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['changes'], None)
-
- # invoke the callback with the change, and check the result
- callbacks['changes'](change)
- self.assertEqual(change_received[0], expected_result)
- d.addCallback(test)
- d.addCallback(lambda _ : sched.stopService())
- return d
-
- def test_change_consumption_defaults(self):
- # all changes are important by default
- return self.do_test_change_consumption(
- dict(),
- self.makeFakeChange(),
- True)
-
- def test_change_consumption_fileIsImportant_True(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : True),
- self.makeFakeChange(),
- True)
-
- def test_change_consumption_fileIsImportant_False(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : False),
- self.makeFakeChange(),
- False)
-
- def test_change_consumption_fileIsImportant_exception(self):
- d = self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : 1/0),
- self.makeFakeChange(),
- None)
- def check_err(_):
- self.assertEqual(1, len(self.flushLoggedErrors(ZeroDivisionError)))
- d.addCallback(check_err)
- return d
- if twisted.version.major <= 9 and sys.version_info[:2] >= (2,7):
- test_change_consumption_fileIsImportant_exception.skip = \
- "flushLoggedErrors does not work correctly on 9.0.0 and earlier with Python-2.7"
-
- def test_change_consumption_change_filter_True(self):
- cf = mock.Mock()
- cf.filter_change = lambda c : True
- return self.do_test_change_consumption(
- dict(change_filter=cf),
- self.makeFakeChange(),
- True)
-
- def test_change_consumption_change_filter_False(self):
- cf = mock.Mock()
- cf.filter_change = lambda c : False
- return self.do_test_change_consumption(
- dict(change_filter=cf),
- self.makeFakeChange(),
- None)
-
- def test_change_consumption_fileIsImportant_False_onlyImportant(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : False, onlyImportant=True),
- self.makeFakeChange(),
- None)
-
- def test_change_consumption_fileIsImportant_True_onlyImportant(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : True, onlyImportant=True),
- self.makeFakeChange(),
- True)
-
- def test_addBuilsetForLatest_args(self):
- sched = self.makeScheduler(name='xyz', builderNames=['y', 'z'])
- d = sched.addBuildsetForLatest(reason='cuz', branch='default',
- project='myp', repository='hgmo',
- external_idstring='try_1234')
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='cuz', brids=brids,
- external_idstring='try_1234',
- properties=[('scheduler', ('xyz', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision=None, repository='hgmo',
- codebase='', project='myp', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForLatest_properties(self):
- props = properties.Properties(xxx="yyy")
- sched = self.makeScheduler(name='xyz', builderNames=['y', 'z'])
- d = sched.addBuildsetForLatest(reason='cuz', branch='default',
- project='myp', repository='hgmo',
- external_idstring='try_1234', properties=props)
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='cuz', brids=brids,
- external_idstring='try_1234',
- properties=[
- ('scheduler', ('xyz', 'Scheduler')),
- ('xxx', ('yyy', 'TEST')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision=None, repository='hgmo',
- codebase='', project='myp', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForLatest_builderNames(self):
- sched = self.makeScheduler(name='xyz', builderNames=['y', 'z'])
- d = sched.addBuildsetForLatest(reason='cuz', branch='default',
- builderNames=['a', 'b'])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='cuz', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('xyz', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision=None, repository='',
- codebase='', project='', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_one_change(self):
- sched = self.makeScheduler(name='n', builderNames=['b'])
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', codebase='',
- project='world-domination'),
- ])
- d = sched.addBuildsetForChanges(reason='power', changeids=[13])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://...', codebase='',
- changeids=set([13]), project='world-domination',
- revision='9283', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_properties(self):
- props = properties.Properties(xxx="yyy")
- sched = self.makeScheduler(name='n', builderNames=['c'])
- self.db.insertTestData([
- fakedb.Change(changeid=14, branch='default', revision='123:abc',
- repository='', project='', codebase=''),
- ])
- d = sched.addBuildsetForChanges(reason='downstream', changeids=[14],
- properties=props)
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='downstream', brids=brids,
- external_idstring=None,
- properties=[
- ('scheduler', ('n', 'Scheduler')),
- ('xxx', ('yyy', 'TEST')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision='123:abc', repository='',
- project='', changeids=set([14]), sourcestampsetid=100,
- codebase='')
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_one_change_builderNames(self):
- sched = self.makeScheduler(name='n', builderNames=['b'])
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- codebase='', repository='svn://...',
- project='world-domination'),
- ])
- d = sched.addBuildsetForChanges(reason='power', changeids=[13],
- builderNames=['p'])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://...', codebase='',
- changeids=set([13]), project='world-domination',
- revision='9283', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_multiple_changes_no_codebaseGenerator(self):
- # This is a test for backwards compatibility
- # Changes from different repositories come together in one build
- sched = self.makeScheduler(name='n', builderNames=['b', 'c'])
- # No codebaseGenerator means all changes have codebase == ''
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://A..', project='knitting',
- codebase=''),
- fakedb.Change(changeid=14, branch='devel', revision='9284',
- repository='svn://B..', project='making-tea',
- codebase=''),
- fakedb.Change(changeid=15, branch='trunk', revision='9285',
- repository='svn://C..', project='world-domination',
- codebase=''),
- ])
-
- # note that the changeids are given out of order here; it should still
- # use the most recent
- d = sched.addBuildsetForChanges(reason='power', changeids=[14, 15, 13])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://C..', codebase='',
- changeids=set([13,14,15]), project='world-domination',
- revision='9285', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_multiple_changes_single_codebase(self):
- sched = self.makeScheduler(name='n', builderNames=['b', 'c'])
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', project='knitting',
- codebase=''),
- fakedb.Change(changeid=14, branch='devel', revision='9284',
- repository='svn://...', project='making-tea',
- codebase=''),
- fakedb.Change(changeid=15, branch='trunk', revision='9285',
- repository='svn://...', project='world-domination',
- codebase=''),
- ])
-
- # note that the changeids are given out of order here; it should still
- # use the most recent
- d = sched.addBuildsetForChanges(reason='power', changeids=[14, 15, 13])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://...', codebase='',
- changeids=set([13,14,15]), project='world-domination',
- revision='9285', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_codebases_set_multiple_changed_codebases(self):
- codebases = { 'cbA':dict(
- repository='svn://A..',
- branch='stable',
- revision='13579'),
- 'cbB':dict(
- repository='svn://B..',
- branch='stable',
- revision='24680'),
- 'cbC':dict(
- repository='svn://C..',
- branch='stable',
- revision='12345'),
- 'cbD':dict(
- repository='svn://D..')}
- # Scheduler gets codebases that can be used to create extra sourcestamps
- # for repositories that have no changes
- sched = self.makeScheduler(name='n', builderNames=['b', 'c'],
- codebases=codebases)
- self.db.insertTestData([
- fakedb.Change(changeid=12, branch='trunk', revision='9282',
- repository='svn://A..', project='playing',
- codebase='cbA'),
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://A..', project='knitting',
- codebase='cbA'),
- fakedb.Change(changeid=14, branch='develop', revision='9284',
- repository='svn://A..', project='making-tea',
- codebase='cbA'),
- fakedb.Change(changeid=15, branch='trunk', revision='8085',
- repository='svn://B..', project='boxing',
- codebase='cbB'),
- fakedb.Change(changeid=16, branch='develop', revision='8086',
- repository='svn://B..', project='playing soccer',
- codebase='cbB'),
- fakedb.Change(changeid=17, branch='develop', revision='8087',
- repository='svn://B..', project='swimming',
- codebase='cbB'),
- ])
-
- # note that the changeids are given out of order here; it should still
- # use the most recent for each codebase
- d = sched.addBuildsetForChanges(reason='power', changeids=[14, 12, 17, 16, 13, 15])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'cbA':
- dict(branch='develop', repository='svn://A..', codebase='cbA',
- changeids=set([12,13,14]), project='making-tea',
- revision='9284', sourcestampsetid=100),
- 'cbB':
- dict(branch='develop', repository='svn://B..', codebase='cbB',
- changeids=set([15,16,17]), project='swimming',
- revision='8087', sourcestampsetid=100),
- 'cbC':
- dict(branch='stable', repository='svn://C..', codebase='cbC',
- project='', revision='12345', sourcestampsetid=100),
- 'cbD':
- dict(branch=None, repository='svn://D..', codebase='cbD',
- project='', revision=None, sourcestampsetid=100),
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForSourceStamp(self):
- sched = self.makeScheduler(name='n', builderNames=['b'])
- d = self.db.insertTestData([
- fakedb.SourceStampSet(id=1091),
- fakedb.SourceStamp(id=91, sourcestampsetid=1091, branch='fixins',
- revision='abc', patchid=None, repository='r',
- project='p'),
- ])
- d.addCallback(lambda _ :
- sched.addBuildsetForSourceStamp(reason='whynot', setid=1091))
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='whynot', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=1091),
- {'':
- dict(branch='fixins', revision='abc', repository='r',
- project='p', codebase='', sourcestampsetid=1091)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForSourceStamp_properties(self):
- props = properties.Properties(xxx="yyy")
- sched = self.makeScheduler(name='n', builderNames=['b'])
- d = self.db.insertTestData([
- fakedb.SourceStampSet(id=1091),
- fakedb.SourceStamp(id=91, sourcestampsetid=1091, branch='fixins',
- revision='abc', patchid=None, repository='r', codebase='cb',
- project='p'),
- ])
- d.addCallback(lambda _ :
- sched.addBuildsetForSourceStamp(reason='whynot', setid=1091,
- properties=props))
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='whynot', brids=brids,
- external_idstring=None,
- properties=[
- ('scheduler', ('n', 'Scheduler')),
- ('xxx', ('yyy', 'TEST')),
- ],
- sourcestampsetid=1091),
- {'cb':
- dict(branch='fixins', revision='abc', repository='r',
- codebase='cb', project='p', sourcestampsetid=1091)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForSourceStamp_builderNames(self):
- sched = self.makeScheduler(name='n', builderNames=['k'])
- d = self.db.insertTestData([
- fakedb.SourceStampSet(id=1091),
- fakedb.SourceStamp(id=91, sourcestampsetid=1091, branch='fixins',
- revision='abc', patchid=None, repository='r', codebase='cb',
- project='p'),
- ])
- d.addCallback(lambda _ :
- sched.addBuildsetForSourceStamp(reason='whynot', setid = 1091,
- builderNames=['a', 'b']))
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='whynot', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=1091),
- {'cb':
- dict(branch='fixins', revision='abc', repository='r',
- codebase='cb', project='p', sourcestampsetid=1091)
- })
- d.addCallback(check)
- return d
-
- def test_findNewSchedulerInstance(self):
- sched = self.makeScheduler(name='n', builderNames=['k'])
- new_sched = self.makeScheduler(name='n', builderNames=['l'])
- distractor = self.makeScheduler(name='x', builderNames=['l'])
- config = mock.Mock()
- config.schedulers = dict(dist=distractor, n=new_sched)
- self.assertIdentical(sched.findNewSchedulerInstance(config), new_sched)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py
deleted file mode 100644
index db8e848e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py
+++ /dev/null
@@ -1,452 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot import config
-from buildbot.test.fake import fakedb
-from buildbot.schedulers import basic
-from buildbot.test.util import scheduler
-
-class CommonStuffMixin(object):
-
- def makeScheduler(self, klass, **kwargs_override):
- kwargs = dict(name="tsched", treeStableTimer=60,
- builderNames=['tbuild'])
- kwargs.update(kwargs_override)
- sched = self.attachScheduler(klass(**kwargs), self.OBJECTID)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
-
- # keep track of builds in self.events
- self.events = []
- def addBuildsetForChanges(reason='', external_idstring=None, changeids=[]):
- self.assertEqual(external_idstring, None)
- self.assertEqual(reason, 'scheduler') # basic schedulers all use this
- self.events.append('B%s@%d' % (`changeids`.replace(' ',''),
- self.clock.seconds()))
- return defer.succeed(None)
- sched.addBuildsetForChanges = addBuildsetForChanges
-
- # see self.assertConsumingChanges
- self.consumingChanges = None
- def startConsumingChanges(**kwargs):
- self.consumingChanges = kwargs
- return defer.succeed(None)
- sched.startConsumingChanges = startConsumingChanges
-
- return sched
-
- def assertConsumingChanges(self, **kwargs):
- self.assertEqual(self.consumingChanges, kwargs)
-
-class BaseBasicScheduler(CommonStuffMixin,
- scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 244
-
- # a custom subclass since we're testing the base class. This basically
- # re-implements SingleBranchScheduler, but with more asserts
- class Subclass(basic.BaseBasicScheduler):
- timer_started = False
- def getChangeFilter(self, *args, **kwargs):
- return kwargs.get('change_filter')
-
- def getTimerNameForChange(self, change):
- self.timer_started = True
- return "xxx"
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- assert timer_name == "xxx"
- assert objectid == BaseBasicScheduler.OBJECTID
- return self.master.db.schedulers.getChangeClassifications(objectid)
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- # tests
-
- def test_constructor_positional_exception(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.Subclass("tsched", "master", 60))
-
- def test_startService_no_treeStableTimer(self):
- cf = mock.Mock('cf')
- fII = mock.Mock('fII')
- sched = self.makeScheduler(self.Subclass, treeStableTimer=None, change_filter=cf,
- fileIsImportant=fII)
-
- self.db.schedulers.fakeClassifications(self.OBJECTID, { 20 : True })
-
- d = sched.startService(_returnDeferred=True)
-
- # check that the scheduler has started to consume changes, and the
- # classifications *have* been flushed, since they will not be used
- def check(_):
- self.assertConsumingChanges(fileIsImportant=fII, change_filter=cf,
- onlyImportant=False)
- self.db.schedulers.assertClassifications(self.OBJECTID, {})
- d.addCallback(check)
- d.addCallback(lambda _ : sched.stopService())
- return d
-
- def test_subclass_fileIsImportant(self):
- class Subclass(self.Subclass):
- def fileIsImportant(self, change):
- return False
- sched = self.makeScheduler(Subclass, onlyImportant=True)
- self.failUnlessEqual(Subclass.fileIsImportant.__get__(sched), sched.fileIsImportant)
-
- def test_startService_treeStableTimer(self):
- cf = mock.Mock()
- sched = self.makeScheduler(self.Subclass, treeStableTimer=10, change_filter=cf)
-
- self.db.schedulers.fakeClassifications(self.OBJECTID, { 20 : True })
- self.master.db.insertTestData([
- fakedb.Change(changeid=20),
- fakedb.SchedulerChange(objectid=self.OBJECTID,
- changeid=20, important=1)
- ])
-
- d = sched.startService(_returnDeferred=True)
-
- # check that the scheduler has started to consume changes, and no
- # classifications have been flushed. Furthermore, the existing
- # classification should have been acted on, so the timer should be
- # running
- def check(_):
- self.assertConsumingChanges(fileIsImportant=None, change_filter=cf,
- onlyImportant=False)
- self.db.schedulers.assertClassifications(self.OBJECTID, { 20 : True })
- self.assertTrue(sched.timer_started)
- self.assertEqual(sched.getPendingBuildTimes(), [ 10 ])
- self.clock.advance(10)
- self.assertEqual(sched.getPendingBuildTimes(), [])
- d.addCallback(check)
- d.addCallback(lambda _ : sched.stopService())
- return d
-
- def test_gotChange_no_treeStableTimer_unimportant(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=None, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), False)
- def check(_):
- self.assertEqual(self.events, [])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_no_treeStableTimer_important(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=None, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), True)
- def check(_):
- self.assertEqual(self.events, [ 'B[13]@0' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_unimportant(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=10, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), False)
- def check(_):
- self.assertEqual(self.events, [])
- d.addCallback(check)
- d.addCallback(lambda _ : self.clock.advance(10))
- d.addCallback(check) # should still be empty
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_important(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=10, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), True)
- d.addCallback(lambda _ : self.clock.advance(10))
- def check(_):
- self.assertEqual(self.events, [ 'B[13]@10' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- @defer.inlineCallbacks
- def test_gotChange_treeStableTimer_sequence(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=9, branch='master')
- self.master.db.insertTestData([
- fakedb.Change(changeid=1, branch='master', when_timestamp=1110),
- fakedb.ChangeFile(changeid=1, filename='readme.txt'),
- fakedb.Change(changeid=2, branch='master', when_timestamp=2220),
- fakedb.ChangeFile(changeid=2, filename='readme.txt'),
- fakedb.Change(changeid=3, branch='master', when_timestamp=3330),
- fakedb.ChangeFile(changeid=3, filename='readme.txt'),
- fakedb.Change(changeid=4, branch='master', when_timestamp=4440),
- fakedb.ChangeFile(changeid=4, filename='readme.txt'),
- ])
- sched.startService()
-
- self.clock.advance(2220)
-
- # this important change arrives at 2220, so the stable timer will last
- # until 2229
- yield sched.gotChange(
- self.makeFakeChange(branch='master', number=1, when=2220),
- True)
- self.assertEqual(self.events, [])
- self.assertEqual(sched.getPendingBuildTimes(), [2229])
- self.db.schedulers.assertClassifications(self.OBJECTID, { 1 : True })
-
- # but another (unimportant) change arrives before then
- self.clock.advance(6) # to 2226
- self.assertEqual(self.events, [])
-
- yield sched.gotChange(
- self.makeFakeChange(branch='master', number=2, when=2226),
- False)
- self.assertEqual(self.events, [])
- self.assertEqual(sched.getPendingBuildTimes(), [2235])
- self.db.schedulers.assertClassifications(self.OBJECTID, { 1 : True, 2 : False })
-
- self.clock.advance(3) # to 2229
- self.assertEqual(self.events, [])
-
- self.clock.advance(3) # to 2232
- self.assertEqual(self.events, [])
-
- # another important change arrives at 2232
- yield sched.gotChange(
- self.makeFakeChange(branch='master', number=3, when=2232),
- True)
- self.assertEqual(self.events, [])
- self.assertEqual(sched.getPendingBuildTimes(), [2241])
- self.db.schedulers.assertClassifications(self.OBJECTID, { 1 : True, 2 : False, 3 : True })
-
- self.clock.advance(3) # to 2235
- self.assertEqual(self.events, [])
-
- # finally, time to start the build!
- self.clock.advance(6) # to 2241
- self.assertEqual(self.events, [ 'B[1,2,3]@2241' ])
- self.assertEqual(sched.getPendingBuildTimes(), [])
- self.db.schedulers.assertClassifications(self.OBJECTID, { })
-
- yield sched.stopService()
-
-
-class SingleBranchScheduler(CommonStuffMixin,
- scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 245
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def test_constructor_branch_mandatory(self):
- self.assertRaises(config.ConfigErrors,
- lambda : basic.SingleBranchScheduler(name="tsched", treeStableTimer=60))
-
- def test_constructor_no_branch_but_filter(self):
- # this shouldn't fail
- basic.SingleBranchScheduler(name="tsched", treeStableTimer=60,
- builderNames=['a','b'], change_filter=mock.Mock())
-
- def test_constructor_branches_forbidden(self):
- self.assertRaises(config.ConfigErrors,
- lambda : basic.SingleBranchScheduler(name="tsched", treeStableTimer=60, branches='x'))
-
- def test_gotChange_treeStableTimer_important(self):
- # this looks suspiciously like the same test above, because SingleBranchScheduler
- # is about the same as the test subclass used above
- sched = self.makeScheduler(basic.SingleBranchScheduler,
- treeStableTimer=10, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), True)
- d.addCallback(lambda _ : self.clock.advance(10))
- def check(_):
- self.assertEqual(self.events, [ 'B[13]@10' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
-
-class AnyBranchScheduler(CommonStuffMixin,
- scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 246
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def test_constructor_branch_forbidden(self):
- self.assertRaises(config.ConfigErrors,
- lambda : basic.SingleBranchScheduler(name="tsched", treeStableTimer=60, branch='x'))
-
- def test_gotChange_treeStableTimer_multiple_branches(self):
- """Two changes with different branches get different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master', 'devel', 'boring'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', number=13), True))
- d.addCallback(lambda _ :
- self.assertEqual(sched.getPendingBuildTimes(), [10]))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', number=14), False))
- d.addCallback(lambda _ :
- self.assertEqual(sched.getPendingBuildTimes(), [11]))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='boring', number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='devel', number=16), True))
- d.addCallback(lambda _ :
- self.assertEqual(sorted(sched.getPendingBuildTimes()), [11,15]))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[16]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_multiple_repositories(self):
- """Two repositories, even with the same branch name, have different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="repo", number=13), True))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="repo", number=14), False))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="other_repo", number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="other_repo", number=17), True))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[15,17]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_multiple_projects(self):
- """Two projects, even with the same branch name, have different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="proj", number=13), True))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="proj", number=14), False))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="other_proj", number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="other_proj", number=17), True))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[15,17]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_multiple_codebases(self):
- """Two codebases, even with the same branch name, have different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="base", number=13), True))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="base", number=14), False))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="other_base", number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="other_base", number=17), True))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[15,17]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py
deleted file mode 100644
index 0af082a6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.schedulers import dependent, base
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot.test.util import scheduler
-from buildbot.test.fake import fakedb
-
-class Dependent(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 33
- UPSTREAM_NAME = 'uppy'
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, upstream=None):
- # build a fake upstream scheduler
- class Upstream(base.BaseScheduler):
- def __init__(self, name):
- self.name = name
- if not upstream:
- upstream = Upstream(self.UPSTREAM_NAME)
-
- sched = dependent.Dependent(name='n', builderNames=['b'],
- upstream=upstream)
- self.attachScheduler(sched, self.OBJECTID)
- return sched
-
- def assertBuildsetSubscriptions(self, bsids=None):
- self.db.state.assertState(self.OBJECTID,
- upstream_bsids=bsids)
-
- # tests
-
- # NOTE: these tests take advantage of the fact that all of the fake
- # scheduler operations are synchronous, and thus do not return a Deferred.
- # The Deferred from trigger() is completely processed before this test
- # method returns.
-
- def test_constructor_string_arg(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(upstream='foo'))
-
- def test_startService(self):
- sched = self.makeScheduler()
- sched.startService()
-
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildsets'], None)
- self.assertNotEqual(callbacks['buildset_completion'], None)
-
- d = sched.stopService()
- def check(_):
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildsets'], None)
- self.assertEqual(callbacks['buildset_completion'], None)
- d.addCallback(check)
- return d
-
- def do_test(self, scheduler_name, expect_subscription,
- result, expect_buildset):
- sched = self.makeScheduler()
- sched.startService()
- callbacks = self.master.getSubscriptionCallbacks()
-
- # pretend we saw a buildset with a matching name
- self.db.insertTestData([
- fakedb.SourceStamp(id=93, sourcestampsetid=1093, revision='555',
- branch='master', project='proj', repository='repo',
- codebase = 'cb'),
- fakedb.Buildset(id=44, sourcestampsetid=1093),
- ])
- callbacks['buildsets'](bsid=44,
- properties=dict(scheduler=(scheduler_name, 'Scheduler')))
-
- # check whether scheduler is subscribed to that buildset
- if expect_subscription:
- self.assertBuildsetSubscriptions([44])
- else:
- self.assertBuildsetSubscriptions([])
-
- # pretend that the buildset is finished
- self.db.buildsets.fakeBuildsetCompletion(bsid=44, result=result)
- callbacks['buildset_completion'](44, result)
-
- # and check whether a buildset was added in response
- if expect_buildset:
- self.db.buildsets.assertBuildsets(2)
- bsids = self.db.buildsets.allBuildsetIds()
- bsids.remove(44)
- self.db.buildsets.assertBuildset(bsids[0],
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='downstream', sourcestampsetid = 1093),
- {'cb':
- dict(revision='555', branch='master', project='proj',
- repository='repo', codebase='cb',
- sourcestampsetid = 1093)
- })
- else:
- self.db.buildsets.assertBuildsets(1) # only the one we added above
-
- def test_related_buildset_SUCCESS(self):
- return self.do_test(self.UPSTREAM_NAME, True, SUCCESS, True)
-
- def test_related_buildset_WARNINGS(self):
- return self.do_test(self.UPSTREAM_NAME, True, WARNINGS, True)
-
- def test_related_buildset_FAILURE(self):
- return self.do_test(self.UPSTREAM_NAME, True, FAILURE, False)
-
- def test_unrelated_buildset(self):
- return self.do_test('unrelated', False, SUCCESS, False)
-
- @defer.inlineCallbacks
- def test_getUpstreamBuildsets_missing(self):
- sched = self.makeScheduler()
-
- # insert some state, with more bsids than exist
- self.db.insertTestData([
- fakedb.SourceStampSet(id=99),
- fakedb.Buildset(id=11, sourcestampsetid=99),
- fakedb.Buildset(id=13, sourcestampsetid=99),
- fakedb.Object(id=self.OBJECTID),
- fakedb.ObjectState(objectid=self.OBJECTID,
- name='upstream_bsids', value_json='[11,12,13]'),
- ])
-
- # check return value (missing 12)
- self.assertEqual((yield sched._getUpstreamBuildsets()),
- [(11, 99, False, -1), (13, 99, False, -1)])
-
- # and check that it wrote the correct value back to the state
- self.db.state.assertState(self.OBJECTID, upstream_bsids=[11, 13])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py
deleted file mode 100644
index 12476224..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py
+++ /dev/null
@@ -1,506 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.schedulers.forcesched import ForceScheduler, StringParameter
-from buildbot.schedulers.forcesched import IntParameter, FixedParameter
-from buildbot.schedulers.forcesched import BooleanParameter, UserNameParameter
-from buildbot.schedulers.forcesched import ChoiceStringParameter, ValidationError
-from buildbot.schedulers.forcesched import NestedParameter, AnyPropertyParameter
-from buildbot.schedulers.forcesched import CodebaseParameter, BaseParameter
-from buildbot.test.util import scheduler
-from buildbot.test.util.config import ConfigErrorsMixin
-
-class TestForceScheduler(scheduler.SchedulerMixin, ConfigErrorsMixin, unittest.TestCase):
-
- OBJECTID = 19
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, name='testsched', builderNames=['a', 'b'],
- **kw):
- sched = self.attachScheduler(
- ForceScheduler(name=name, builderNames=builderNames,**kw),
- self.OBJECTID)
- sched.master.config = config.MasterConfig()
-
- self.assertEquals(sched.name, name)
-
- return sched
-
- # tests
-
- def test_compare_branch(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[]),
- ForceScheduler(name="testched", builderNames=[],
- branch=FixedParameter("branch","fishing/pole")))
-
-
- def test_compare_reason(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- reason=FixedParameter("reason","no fish for you!")),
- ForceScheduler(name="testched", builderNames=[],
- reason=FixedParameter("reason","thanks for the fish!")))
-
-
- def test_compare_revision(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- revision=FixedParameter("revision","fish-v1")),
- ForceScheduler(name="testched", builderNames=[],
- revision=FixedParameter("revision","fish-v2")))
-
-
- def test_compare_repository(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- repository=FixedParameter("repository","git://pond.org/fisher.git")),
- ForceScheduler(name="testched", builderNames=[],
- repository=FixedParameter("repository","svn://ocean.com/trawler/")))
-
-
- def test_compare_project(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- project=FixedParameter("project","fisher")),
- ForceScheduler(name="testched", builderNames=[],
- project=FixedParameter("project","trawler")))
-
-
- def test_compare_username(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[]),
- ForceScheduler(name="testched", builderNames=[],
- project=FixedParameter("username","The Fisher King <avallach@atlantis.al>")))
-
-
- def test_compare_properties(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- properties=[]),
- ForceScheduler(name="testched", builderNames=[],
- properties=[FixedParameter("prop","thanks for the fish!")]))
-
- def test_compare_codebases(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- codebases=['bar']),
- ForceScheduler(name="testched", builderNames=[],
- codebases=['foo']))
-
-
- @defer.inlineCallbacks
- def test_basicForce(self):
- sched = self.makeScheduler()
-
- res = yield sched.force('user', builderNames=['a'], branch='a', reason='because',revision='c',
- repository='d', project='p',
- property1_name='p1',property1_value='e',
- property2_name='p2',property2_value='f',
- property3_name='p3',property3_value='g',
- property4_name='p4',property4_value='h'
- )
- bsid,brids = res
-
- # only one builder forced, so there should only be one brid
- self.assertEqual(len(brids), 1)
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('p1', ('e', 'Force Build Form')),
- ('p2', ('f', 'Force Build Form')),
- ('p3', ('g', 'Force Build Form')),
- ('p4', ('h', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='a', revision='c', repository='d', codebase='',
- project='p', sourcestampsetid=100)
- })
-
- @defer.inlineCallbacks
- def test_force_allBuilders(self):
- sched = self.makeScheduler()
-
- res = yield sched.force('user', branch='a', reason='because',revision='c',
- repository='d', project='p',
- )
- bsid,brids = res
-
- self.assertEqual(len(brids), 2)
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- builders = ['a', 'b'],
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='a', revision='c', repository='d', codebase='',
- project='p', sourcestampsetid=100)
- })
-
- @defer.inlineCallbacks
- def test_force_someBuilders(self):
- sched = self.makeScheduler(builderNames=['a','b','c'])
-
- res = yield sched.force('user', builderNames=['a','b'],
- branch='a', reason='because',revision='c',
- repository='d', project='p',
- )
- bsid,brids = res
-
- self.assertEqual(len(brids), 2)
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- builders = ['a', 'b'],
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='a', revision='c', repository='d', codebase='',
- project='p', sourcestampsetid=100)
- })
-
- def test_bad_codebases(self):
- # cant specify both codebases and branch/revision/project/repository:
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], branch=StringParameter('name')))
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], revision=StringParameter('name')))
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], project=StringParameter('name')))
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], repository=StringParameter('name')))
-
- # codebases must be a list of either string or BaseParameter types
- self.assertRaisesConfigError("ForceScheduler: 'codebases' must be a list of strings or CodebaseParameter objects:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=[123],))
- self.assertRaisesConfigError("ForceScheduler: 'codebases' must be a list of strings or CodebaseParameter objects:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=[IntParameter('foo')],))
-
- # codebases cannot be empty
- self.assertRaisesConfigError("ForceScheduler: 'codebases' cannot be empty; use CodebaseParameter(codebase='', hide=True) if needed:",
- lambda: ForceScheduler(name='foo',
- builderNames=['bar'],
- codebases=[]))
-
- @defer.inlineCallbacks
- def test_good_codebases(self):
- sched = self.makeScheduler(codebases=['foo', CodebaseParameter('bar')])
- res = yield sched.force('user', builderNames=['a'], reason='because',
- foo_branch='a', foo_revision='c', foo_repository='d', foo_project='p',
- bar_branch='a2', bar_revision='c2', bar_repository='d2', bar_project='p2',
- property1_name='p1',property1_value='e',
- property2_name='p2',property2_value='f',
- property3_name='p3',property3_value='g',
- property4_name='p4',property4_value='h'
- )
-
- bsid,brids = res
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('p1', ('e', 'Force Build Form')),
- ('p2', ('f', 'Force Build Form')),
- ('p3', ('g', 'Force Build Form')),
- ('p4', ('h', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'foo': dict(codebase='foo', sourcestampsetid=100,
- branch='a', revision='c', repository='d', project='p', ),
- 'bar': dict(codebase='bar', sourcestampsetid=100,
- branch='a2', revision='c2', repository='d2', project='p2', ),
- })
-
- # value = the value to be sent with the parameter (ignored if req is set)
- # expect = the expected result (can be an exception type)
- # klass = the parameter class type
- # req = use this request instead of the auto-generated one based on value
- @defer.inlineCallbacks
- def do_ParameterTest(self,
- expect,
- klass,
- expectKind=None, # None=one prop, Exception=exception, dict=many props
- owner='user',
- value=None, req=None,
- **kwargs):
-
- name = kwargs.setdefault('name', 'p1')
-
- # construct one if needed
- if isinstance(klass, type):
- prop = klass(**kwargs)
- else:
- prop = klass
-
- self.assertEqual(prop.name, name)
- self.assertEqual(prop.label, kwargs.get('label', prop.name))
-
- sched = self.makeScheduler(properties=[prop])
-
- if not req:
- req = {name:value, 'reason':'because'}
- try:
- bsid, brids = yield sched.force(owner, builderNames=['a'], **req)
- except Exception,e:
- if expectKind is not Exception:
- # an exception is not expected
- raise
- if not isinstance(e, expect):
- # the exception is the wrong kind
- raise
- defer.returnValue(None) # success
-
- expect_props = [
- ('owner', ('user', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ]
-
- if expectKind is None:
- expect_props.append((name, (expect, 'Force Build Form')))
- elif expectKind is dict:
- for k,v in expect.iteritems():
- expect_props.append((k, (v, 'Force Build Form')))
- else:
- self.fail("expectKind is wrong type!")
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- external_idstring=None,
- properties=sorted(expect_props),
- sourcestampsetid=100),
- {"":
- dict(branch="", revision="", repository="", codebase='',
- project="", sourcestampsetid=100)
- })
-
- def test_StringParameter(self):
- self.do_ParameterTest(value="testedvalue", expect="testedvalue",
- klass=StringParameter)
-
- def test_IntParameter(self):
- self.do_ParameterTest(value="123", expect=123, klass=IntParameter)
-
-
- def test_FixedParameter(self):
- self.do_ParameterTest(value="123", expect="321", klass=FixedParameter,
- default="321")
-
-
- def test_BooleanParameter_True(self):
- req = dict(p1=True,reason='because')
- self.do_ParameterTest(value="123", expect=True, klass=BooleanParameter,
- req=req)
-
-
- def test_BooleanParameter_False(self):
- req = dict(p2=True,reason='because')
- self.do_ParameterTest(value="123", expect=False,
- klass=BooleanParameter, req=req)
-
-
- def test_UserNameParameter(self):
- email = "test <test@buildbot.net>"
- self.do_ParameterTest(value=email, expect=email,
- klass=UserNameParameter(),
- name="username", label="Your name:")
-
-
- def test_UserNameParameterError(self):
- for value in ["test","test@buildbot.net","<test@buildbot.net>"]:
- self.do_ParameterTest(value=value,
- expect=ValidationError,
- expectKind=Exception,
- klass=UserNameParameter(debug=False),
- name="username", label="Your name:")
-
-
- def test_ChoiceParameter(self):
- self.do_ParameterTest(value='t1', expect='t1',
- klass=ChoiceStringParameter, choices=['t1','t2'])
-
-
- def test_ChoiceParameterError(self):
- self.do_ParameterTest(value='t3',
- expect=ValidationError,
- expectKind=Exception,
- klass=ChoiceStringParameter, choices=['t1','t2'],
- debug=False)
-
- def test_ChoiceParameterError_notStrict(self):
- self.do_ParameterTest(value='t1', expect='t1',
- strict=False,
- klass=ChoiceStringParameter, choices=['t1','t2'])
-
-
- def test_ChoiceParameterMultiple(self):
- self.do_ParameterTest(value=['t1','t2'], expect=['t1','t2'],
- klass=ChoiceStringParameter,choices=['t1','t2'], multiple=True)
-
-
- def test_ChoiceParameterMultipleError(self):
- self.do_ParameterTest(value=['t1','t3'],
- expect=ValidationError,
- expectKind=Exception,
- klass=ChoiceStringParameter, choices=['t1','t2'],
- multiple=True, debug=False)
-
-
- def test_NestedParameter(self):
- fields = [
- IntParameter(name="foo")
- ]
- self.do_ParameterTest(req=dict(p1_foo='123', reason="because"),
- expect=dict(foo=123),
- klass=NestedParameter, fields=fields)
-
- def test_NestedNestedParameter(self):
- fields = [
- NestedParameter(name="inner", fields=[
- StringParameter(name='str'),
- AnyPropertyParameter(name='any')
- ]),
- IntParameter(name="foo")
- ]
- self.do_ParameterTest(req=dict(p1_foo='123',
- p1_inner_str="bar",
- p1_inner_any_name="hello",
- p1_inner_any_value="world",
- reason="because"),
- expect=dict(foo=123, inner=dict(str="bar", hello="world")),
- klass=NestedParameter, fields=fields)
-
- def test_NestedParameter_nullname(self):
- # same as above except "p1" and "any" are skipped
- fields = [
- NestedParameter(name="inner", fields=[
- StringParameter(name='str'),
- AnyPropertyParameter(name='')
- ]),
- IntParameter(name="foo"),
- NestedParameter(name='bar', fields=[
- NestedParameter(name='', fields=[AnyPropertyParameter(name='a')]),
- NestedParameter(name='', fields=[AnyPropertyParameter(name='b')])
- ])
- ]
- self.do_ParameterTest(req=dict(foo='123',
- inner_str="bar",
- inner_name="hello",
- inner_value="world",
- reason="because",
- bar_a_name="a",
- bar_a_value="7",
- bar_b_name="b",
- bar_b_value="8"),
- expect=dict(foo=123,
- inner=dict(str="bar", hello="world"),
- bar={'a':'7', 'b':'8'}),
- expectKind=dict,
- klass=NestedParameter, fields=fields, name='')
-
- def test_bad_reason(self):
- self.assertRaisesConfigError("ForceScheduler reason must be a StringParameter",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], reason="foo"))
-
- def test_bad_username(self):
- self.assertRaisesConfigError("ForceScheduler username must be a StringParameter",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo"))
-
- def test_notstring_name(self):
- self.assertRaisesConfigError("ForceScheduler name must be a unicode string:",
- lambda: ForceScheduler(name=1234, builderNames=[],
- codebases=['bar'], username="foo"))
-
- def test_emptystring_name(self):
- self.assertRaisesConfigError("ForceScheduler name must not be empty:",
- lambda: ForceScheduler(name='', builderNames=[],
- codebases=['bar'], username="foo"))
-
- def test_integer_builderNames(self):
- self.assertRaisesConfigError("ForceScheduler builderNames must be a list of strings:",
- lambda: ForceScheduler(name='testsched', builderNames=1234,
- codebases=['bar'], username="foo"))
-
- def test_listofints_builderNames(self):
- self.assertRaisesConfigError("ForceScheduler builderNames must be a list of strings:",
- lambda: ForceScheduler(name='testsched', builderNames=[1234],
- codebases=['bar'], username="foo"))
-
- def test_listofmixed_builderNames(self):
- self.assertRaisesConfigError("ForceScheduler builderNames must be a list of strings:",
- lambda: ForceScheduler(name='testsched',
- builderNames=['test', 1234],
- codebases=['bar'], username="foo"))
-
- def test_integer_properties(self):
- self.assertRaisesConfigError("ForceScheduler properties must be a list of BaseParameters:",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo",
- properties=1234))
-
- def test_listofints_properties(self):
- self.assertRaisesConfigError("ForceScheduler properties must be a list of BaseParameters:",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo",
- properties=[1234, 2345]))
-
- def test_listofmixed_properties(self):
- self.assertRaisesConfigError("ForceScheduler properties must be a list of BaseParameters:",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo",
- properties=[BaseParameter(name="test",),
- 4567]))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py
deleted file mode 100644
index 0c79730b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.schedulers import manager, base
-from buildbot import config
-
-class SchedulerManager(unittest.TestCase):
-
- def setUp(self):
- self.next_objectid = 13
- self.objectids = {}
-
- self.master = mock.Mock()
- def getObjectId(sched_name, class_name):
- k = (sched_name, class_name)
- try:
- rv = self.objectids[k]
- except:
- rv = self.objectids[k] = self.next_objectid
- self.next_objectid += 1
- return defer.succeed(rv)
- self.master.db.state.getObjectId = getObjectId
-
- self.new_config = mock.Mock()
-
- self.sm = manager.SchedulerManager(self.master)
- self.sm.startService()
-
- def tearDown(self):
- if self.sm.running:
- return self.sm.stopService()
-
- class Sched(base.BaseScheduler):
-
- # changing sch.attr should make a scheduler look "updated"
- compare_attrs = base.BaseScheduler.compare_attrs + ( 'attr', )
- already_started = False
- reconfig_count = 0
-
- def startService(self):
- assert not self.already_started
- assert self.master is not None
- assert self.objectid is not None
- self.already_started = True
- base.BaseScheduler.startService(self)
-
- def stopService(self):
- d = base.BaseScheduler.stopService(self)
- def still_set(_):
- assert self.master is not None
- assert self.objectid is not None
- d.addCallback(still_set)
- return d
-
- class ReconfigSched(config.ReconfigurableServiceMixin, Sched):
-
- def reconfigService(self, new_config):
- self.reconfig_count += 1
- new_sched = self.findNewSchedulerInstance(new_config)
- self.attr = new_sched.attr
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- class ReconfigSched2(ReconfigSched):
- pass
-
- def makeSched(self, cls, name, attr='alpha'):
- sch = cls(name=name, builderNames=['x'], properties={})
- sch.attr = attr
- return sch
-
- # tests
-
- @defer.inlineCallbacks
- def test_reconfigService_add_and_change_and_remove(self):
- sch1 = self.makeSched(self.ReconfigSched, 'sch1', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1)
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
- self.assertEqual(sch1.reconfig_count, 1)
-
- sch1_new = self.makeSched(self.ReconfigSched, 'sch1', attr='beta')
- sch2 = self.makeSched(self.ReconfigSched, 'sch2', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1_new, sch2=sch2)
-
- yield self.sm.reconfigService(self.new_config)
-
- # sch1 is still the active scheduler, and has been reconfig'd,
- # and has the correct attribute
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
- self.assertEqual(sch1.attr, 'beta')
- self.assertEqual(sch1.reconfig_count, 2)
- self.assertIdentical(sch1_new.parent, None)
- self.assertIdentical(sch1_new.master, None)
-
- self.assertIdentical(sch2.parent, self.sm)
- self.assertIdentical(sch2.master, self.master)
-
- self.new_config.schedulers = {}
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, None)
- self.assertIdentical(sch1.master, None)
-
- @defer.inlineCallbacks
- def test_reconfigService_class_name_change(self):
- sch1 = self.makeSched(self.ReconfigSched, 'sch1')
- self.new_config.schedulers = dict(sch1=sch1)
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
- self.assertEqual(sch1.reconfig_count, 1)
-
- sch1_new = self.makeSched(self.ReconfigSched2, 'sch1')
- self.new_config.schedulers = dict(sch1=sch1_new)
-
- yield self.sm.reconfigService(self.new_config)
-
- # sch1 had its class name change, so sch1_new is now the active
- # instance
- self.assertIdentical(sch1_new.parent, self.sm)
- self.assertIdentical(sch1_new.master, self.master)
-
- @defer.inlineCallbacks
- def test_reconfigService_add_and_change_and_remove_no_reconfig(self):
- sch1 = self.makeSched(self.Sched, 'sch1', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1)
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
-
- sch1_new = self.makeSched(self.Sched, 'sch1', attr='beta')
- sch2 = self.makeSched(self.Sched, 'sch2', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1_new, sch2=sch2)
-
- yield self.sm.reconfigService(self.new_config)
-
- # sch1 is not longer active, and sch1_new is
- self.assertIdentical(sch1.parent, None)
- self.assertIdentical(sch1.master, None)
- self.assertIdentical(sch1_new.parent, self.sm)
- self.assertIdentical(sch1_new.master, self.master)
- self.assertIdentical(sch2.parent, self.sm)
- self.assertIdentical(sch2.master, self.master)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py
deleted file mode 100644
index 34d6c3cb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from twisted.python import log
-from buildbot.schedulers import timed
-from buildbot.test.util import scheduler
-from buildbot.changes import filter
-from buildbot import config
-
-class Nightly(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 132
-
- # not all timezones are even multiples of 1h from GMT. This variable
- # holds the number of seconds ahead of the hour for the current timezone.
- # This is then added to the clock before each test is run (to get to 0
- # minutes past the hour) and subtracted before the time offset is reported.
- localtime_offset = time.timezone % 3600
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- sched = self.attachScheduler(timed.Nightly(**kwargs),
- self.OBJECTID)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
- self.clock.advance(self.localtime_offset) # get to 0 min past the hour
-
- # keep track of builds in self.events
- self.events = []
- def addBuildsetForLatest(reason='', external_idstring='',
- branch=None, repository='', project=''):
- self.assertIn('scheduler named', reason)
- isFirst = (self.events == [])
- self.events.append('B(%s)@%d' % (branch,
- # show the offset as seconds past the GMT hour
- self.clock.seconds() - self.localtime_offset))
- if isFirst and firstBuildDuration:
- d = defer.Deferred()
- self.clock.callLater(firstBuildDuration, d.callback, None)
- return d
- else:
- return defer.succeed(None)
- sched.addBuildsetForLatest = addBuildsetForLatest
-
- def addBuildsetForChanges(reason='', external_idstring='', changeids=[]):
- self.events.append('B%s@%d' % (`changeids`.replace(' ',''),
- # show the offset as seconds past the GMT hour
- self.clock.seconds() - self.localtime_offset))
- return defer.succeed(None)
- sched.addBuildsetForChanges = addBuildsetForChanges
-
- # see self.assertConsumingChanges
- self.consumingChanges = None
- def startConsumingChanges(**kwargs):
- self.consumingChanges = kwargs
- return defer.succeed(None)
- sched.startConsumingChanges = startConsumingChanges
-
- return sched
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def assertConsumingChanges(self, **kwargs):
- self.assertEqual(self.consumingChanges, kwargs)
-
- ## Tests
-
- def test_constructor_change_filter(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- branch=None, change_filter=filter.ChangeFilter(category_re="fo+o"))
- assert sched.change_filter
-
- def test_constructor_no_branch(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(name='test', builderNames=['test'],
- change_filter=filter.ChangeFilter(category_re="fo+o")))
-
- ## end-to-end tests: let's see the scheduler in action
-
- def test_iterations_simple(self):
- # note that Nightly works in local time, but the task.Clock() always
- # starts at midnight UTC, so be careful not to use times that are
- # timezone dependent -- stick to minutes-past-the-half-hour, as some
- # timezones are multiples of 30 minutes off from UTC
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ], branch=None,
- minute=[10, 20, 21, 40, 50, 51])
-
- # add a change classification
- self.db.schedulers.fakeClassifications(self.OBJECTID, { 19 : True })
-
- sched.startService()
-
- # check that the classification has been flushed, since this
- # invocation has not requested onlyIfChanged
- self.db.schedulers.assertClassifications(self.OBJECTID, {})
-
- self.clock.advance(0) # let it get set up
- while self.clock.seconds() < self.localtime_offset + 30*60:
- self.clock.advance(60)
- self.assertEqual(self.events, [ 'B(None)@600', 'B(None)@1200', 'B(None)@1260' ])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1260 + self.localtime_offset)
-
- d = sched.stopService()
- return d
-
- def test_iterations_simple_with_branch(self):
- # see timezone warning above
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- branch='master', minute=[5, 35])
-
- sched.startService()
-
- self.clock.advance(0)
- while self.clock.seconds() < self.localtime_offset + 10*60:
- self.clock.advance(60)
- self.assertEqual(self.events, [ 'B(master)@300' ])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=300 + self.localtime_offset)
-
- d = sched.stopService()
- return d
-
- def do_test_iterations_onlyIfChanged(self, *changes_at):
- fII = mock.Mock(name='fII')
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ], branch=None,
- minute=[5, 25, 45], onlyIfChanged=True,
- fileIsImportant=fII)
-
- sched.startService()
-
- # check that the scheduler has started to consume changes
- self.assertConsumingChanges(fileIsImportant=fII, change_filter=None,
- onlyImportant=False)
-
- # manually run the clock forward through a half-hour, allowing any
- # excitement to take place
- changes_at = list(changes_at)
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < self.localtime_offset + 30*60:
- # inject any new changes..
- while (changes_at and
- self.clock.seconds() >=
- self.localtime_offset + changes_at[0][0]):
- when, newchange, important = changes_at.pop(0)
- self.sched.gotChange(newchange, important).addErrback(log.err)
- # and advance the clock by a minute
- self.clock.advance(60)
-
- def test_iterations_onlyIfChanged_no_changes(self):
- self.do_test_iterations_onlyIfChanged()
- self.assertEqual(self.events, [])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
-
- def test_iterations_onlyIfChanged_unimp_changes(self):
- self.do_test_iterations_onlyIfChanged(
- (60, mock.Mock(), False),
- (600, mock.Mock(), False))
- self.assertEqual(self.events, [])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
-
- def test_iterations_onlyIfChanged_off_branch_changes(self):
- self.do_test_iterations_onlyIfChanged(
- (60, self.makeFakeChange(branch='testing'), True),
- (1700, self.makeFakeChange(branch='staging'), True))
- self.assertEqual(self.events, [])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
-
- def test_iterations_onlyIfChanged_mixed_changes(self):
- self.do_test_iterations_onlyIfChanged(
- (120, self.makeFakeChange(number=3, branch=None), False),
- (130, self.makeFakeChange(number=4, branch='offbranch'), True),
- (1200, self.makeFakeChange(number=5, branch=None), True),
- (1201, self.makeFakeChange(number=6, branch=None), False),
- (1202, self.makeFakeChange(number=7, branch='offbranch'), True))
- # note that the changeid list includes the unimportant changes, but not the
- # off-branch changes, and note that no build took place at 300s, as no important
- # changes had yet arrived
- self.assertEqual(self.events, [ 'B[3,5,6]@1500' ])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py
deleted file mode 100644
index 4d799aed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import time
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.schedulers import timed
-from buildbot.test.util import scheduler
-from buildbot.test.util import config
-
-class NightlyBase(scheduler.SchedulerMixin, unittest.TestCase):
- """detailed getNextBuildTime tests"""
-
- OBJECTID = 133
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- return self.attachScheduler(timed.NightlyBase(**kwargs),
- self.OBJECTID)
-
- @defer.inlineCallbacks
- def do_getNextBuildTime_test(self, sched, *expectations):
- for lastActuated, expected in expectations:
- # convert from tuples to epoch time (in local timezone)
- lastActuated_ep, expected_ep = [
- time.mktime(t + (0,) * (8 - len(t)) + (-1,))
- for t in (lastActuated, expected) ]
- got_ep = yield sched.getNextBuildTime(lastActuated_ep)
- self.assertEqual(got_ep, expected_ep,
- "%s -> %s != %s" % (lastActuated, time.localtime(got_ep),
- expected))
-
- def test_getNextBuildTime_hourly(self):
- sched = self.makeScheduler(name='test', builderNames=['test'])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0, 0), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 15, 0), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 15, 1), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 59, 1), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 59, 59), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 23, 22, 22), (2011, 1, 2, 0, 0, 0)),
- ((2011, 1, 1, 23, 59, 0), (2011, 1, 2, 0, 0, 0)),
- )
-
- def test_getNextBuildTime_minutes_single(self):
- # basically the same as .._hourly
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=4)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0, 0), (2011, 1, 1, 3, 4, 0)),
- ((2011, 1, 1, 3, 15, 0), (2011, 1, 1, 4, 4, 0)),
- )
-
- def test_getNextBuildTime_minutes_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[4, 34])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0, 0), (2011, 1, 1, 3, 4, 0)),
- ((2011, 1, 1, 3, 15, 0), (2011, 1, 1, 3, 34, 0)),
- ((2011, 1, 1, 3, 34, 0), (2011, 1, 1, 4, 4, 0)),
- ((2011, 1, 1, 3, 59, 1), (2011, 1, 1, 4, 4, 0)),
- )
-
- def test_getNextBuildTime_minutes_star(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute='*')
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 11, 30), (2011, 1, 1, 3, 12, 0)),
- ((2011, 1, 1, 3, 12, 0), (2011, 1, 1, 3, 13, 0)),
- ((2011, 1, 1, 3, 59, 0), (2011, 1, 1, 4, 0, 0)),
- )
-
- def test_getNextBuildTime_hours_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- hour=4)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0), (2011, 1, 1, 4, 0)),
- ((2011, 1, 1, 13, 0), (2011, 1, 2, 4, 0)),
- )
-
- def test_getNextBuildTime_hours_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- hour=[7, 19])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0), (2011, 1, 1, 7, 0)),
- ((2011, 1, 1, 7, 1), (2011, 1, 1, 19, 0)),
- ((2011, 1, 1, 18, 59), (2011, 1, 1, 19, 0)),
- ((2011, 1, 1, 19, 59), (2011, 1, 2, 7, 0)),
- )
-
- def test_getNextBuildTime_hours_minutes(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- hour=13, minute=19)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 11), (2011, 1, 1, 13, 19)),
- ((2011, 1, 1, 13, 19), (2011, 1, 2, 13, 19)),
- ((2011, 1, 1, 23, 59), (2011, 1, 2, 13, 19)),
- )
-
- def test_getNextBuildTime_month_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- month=3)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 2, 27, 3, 11), (2011, 3, 1, 0, 0)),
- ((2011, 3, 1, 1, 11), (2011, 3, 1, 2, 0)), # still hourly!
- )
-
- def test_getNextBuildTime_month_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- month=[4, 6])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 3, 30, 3, 11), (2011, 4, 1, 0, 0)),
- ((2011, 4, 1, 1, 11), (2011, 4, 1, 2, 0)), # still hourly!
- ((2011, 5, 29, 3, 11), (2011, 6, 1, 0, 0)),
- )
-
- def test_getNextBuildTime_month_dayOfMonth(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- month=[3, 6], dayOfMonth=[15])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 2, 12, 3, 11), (2011, 3, 15, 0, 0)),
- ((2011, 3, 12, 3, 11), (2011, 3, 15, 0, 0)),
- )
-
- def test_getNextBuildTime_dayOfMonth_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfMonth=10)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 9, 3, 0), (2011, 1, 10, 0, 0)),
- ((2011, 1, 10, 3, 0), (2011, 1, 10, 4, 0)), # still hourly!
- ((2011, 1, 30, 3, 0), (2011, 2, 10, 0, 0)),
- ((2011, 12, 30, 11, 0), (2012, 1, 10, 0, 0)),
- )
-
- def test_getNextBuildTime_dayOfMonth_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfMonth=[10, 20, 30])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 9, 22, 0), (2011, 1, 10, 0, 0)),
- ((2011, 1, 19, 22, 0), (2011, 1, 20, 0, 0)),
- ((2011, 1, 29, 22, 0), (2011, 1, 30, 0, 0)),
- ((2011, 2, 29, 22, 0), (2011, 3, 10, 0, 0)), # no Feb 30!
- )
-
- def test_getNextBuildTime_dayOfMonth_hours_minutes(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfMonth=15, hour=20, minute=30)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 13, 22, 19), (2011, 1, 15, 20, 30)),
- ((2011, 1, 15, 19, 19), (2011, 1, 15, 20, 30)),
- ((2011, 1, 15, 20, 29), (2011, 1, 15, 20, 30)),
- )
-
- def test_getNextBuildTime_dayOfWeek_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfWeek=1) # Tuesday (2011-1-1 was a Saturday)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 3, 22, 19), (2011, 1, 4, 0, 0)),
- ((2011, 1, 4, 19, 19), (2011, 1, 4, 20, 0)), # still hourly!
- )
-
- def test_getNextBuildTime_dayOfWeek_multiple_hours(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfWeek=[1,3], hour=1) # Tuesday, Thursday (2011-1-1 was a Saturday)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 3, 22, 19), (2011, 1, 4, 1, 0)),
- ((2011, 1, 4, 22, 19), (2011, 1, 6, 1, 0)),
- )
-
- def test_getNextBuildTime_dayOfWeek_dayOfMonth(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfWeek=[1,4], dayOfMonth=5, hour=1)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 3, 22, 19), (2011, 1, 4, 1, 0)), # Tues
- ((2011, 1, 4, 22, 19), (2011, 1, 5, 1, 0)), # 5th
- ((2011, 1, 5, 22, 19), (2011, 1, 7, 1, 0)), # Thurs
- )
-
-class NightlyCroniterImport(config.ConfigErrorsMixin, unittest.TestCase):
-
- def setUp(self):
- self.savedModules = sys.modules.copy()
-
- def tearDown(self):
- sys.modules.clear()
- sys.modules.update(self.savedModules)
-
- def test_error_without_dateutil(self):
- del sys.modules['buildbot.schedulers.timed']
- del sys.modules['buildbot.util']
- sys.modules["dateutil.relativedelta"] = None
- from buildbot.schedulers.timed import NightlyBase
- self.assertRaisesConfigError("python-dateutil",
- lambda: NightlyBase(name='name', builderNames=[]))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py
deleted file mode 100644
index 68b7416e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py
+++ /dev/null
@@ -1,309 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import task
-from buildbot.process import properties
-from buildbot.schedulers import timed
-from buildbot.test.fake import fakedb
-from buildbot.test.util import scheduler
-
-class NightlyTriggerable(scheduler.SchedulerMixin, unittest.TestCase):
-
- SCHEDULERID = 1327
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- sched = self.attachScheduler(timed.NightlyTriggerable(**kwargs),
- self.SCHEDULERID)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
-
- return sched
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
-
- def test_timer_noBuilds(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5])
-
- sched.startService()
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildsets(0)
-
-
- def test_timer_oneTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
-
- def test_timer_twoTriggers(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({ 'cb':
- dict(revision='myrev1', branch='br', project='p', repository='r')
- } , set_props=None)
- sched.trigger({ 'cb':
- dict(revision='myrev2', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev2', sourcestampsetid=100)
- })
-
-
- def test_timer_oneTrigger_then_noBuild(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({ 'cb':
- dict(revision='myrev', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
- self.db.buildsets.flushBuildsets()
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildsets(0)
-
-
- def test_timer_oneTriggers_then_oneTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({ 'cb':
- dict(revision='myrev1', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev1', sourcestampsetid=100)
- })
- self.db.buildsets.flushBuildsets()
-
- sched.trigger({ 'cb':
- dict(revision='myrev2', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=101),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev2', sourcestampsetid=101)
- })
-
- def test_savedTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- fakedb.ObjectState(objectid=self.SCHEDULERID, name='lastTrigger',
- value_json='[ {"cb": {"project": "p", "repository": "r", "branch": "br", "revision": "myrev"}} , {} ]'),
- ])
-
- sched.startService()
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
- def test_saveTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- ])
-
- sched.startService()
-
- d = sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, set_props=None)
-
- @d.addCallback
- def cb(_):
- self.db.state.assertState(self.SCHEDULERID, lastTrigger=[{'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, {}])
-
- return d
-
- def test_saveTrigger_noTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- ])
-
- sched.startService()
-
- d = sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- @d.addCallback
- def cb(_):
- self.db.state.assertState(self.SCHEDULERID, lastTrigger=None)
-
- return d
-
- def test_triggerProperties(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- ])
-
- sched.startService()
-
- sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, properties.Properties(testprop='test'))
-
- self.db.state.assertState(self.SCHEDULERID, lastTrigger=[{'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, {'testprop': ['test', 'TEST']}])
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ('testprop', ('test', 'TEST')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
- def test_savedProperties(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- fakedb.ObjectState(objectid=self.SCHEDULERID, name='lastTrigger',
- value_json='[ {"cb": {"project": "p", "repository": "r", "branch": "br", "revision": "myrev"}} , {"testprop": ["test", "TEST"]} ]'),
- ])
-
- sched.startService()
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ('testprop', ('test', 'TEST')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py
deleted file mode 100644
index 5139a96a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import task, defer
-from buildbot.schedulers import timed
-from buildbot import config
-
-class Periodic(unittest.TestCase):
-
- def makeScheduler(self, firstBuildDuration=0, exp_branch=None, **kwargs):
- self.sched = sched = timed.Periodic(**kwargs)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
-
- # keep track of builds in self.events
- self.events = []
- def addBuildsetForLatest(reason=None, branch=None):
- self.assertIn('Periodic scheduler named', reason)
- self.assertEqual(branch, exp_branch)
- isFirst = (self.events == [])
- self.events.append('B@%d' % self.clock.seconds())
- if isFirst and firstBuildDuration:
- d = defer.Deferred()
- self.clock.callLater(firstBuildDuration, d.callback, None)
- return d
- else:
- return defer.succeed(None)
- sched.addBuildsetForLatest = addBuildsetForLatest
-
- # handle state locally
- self.state = {}
-
- def getState(k, default):
- return defer.succeed(self.state.get(k, default))
- sched.getState = getState
-
- def setState(k, v):
- self.state[k] = v
- return defer.succeed(None)
- sched.setState = setState
-
- return sched
-
- # tests
-
- def test_constructor_invalid(self):
- self.assertRaises(config.ConfigErrors,
- lambda : timed.Periodic(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=-2))
-
- def test_iterations_simple(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < 30:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@0', 'B@13', 'B@26' ])
- self.assertEqual(self.state.get('last_build'), 26)
-
- d = sched.stopService()
- return d
-
- def test_iterations_simple_branch(self):
- sched = self.makeScheduler(exp_branch='newfeature',
- name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13, branch='newfeature')
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < 30:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@0', 'B@13', 'B@26' ])
- self.assertEqual(self.state.get('last_build'), 26)
-
- d = sched.stopService()
- return d
-
- def test_iterations_long(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=10,
- firstBuildDuration=15) # takes a while to start a build
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first (longer) build
- while self.clock.seconds() < 40:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@0', 'B@15', 'B@25', 'B@35' ])
- self.assertEqual(self.state.get('last_build'), 35)
-
- d = sched.stopService()
- return d
-
- def test_iterations_stop_while_starting_build(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13,
- firstBuildDuration=6) # takes a while to start a build
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first (longer) build
- self.clock.advance(3) # get partway into that build
-
- d = sched.stopService() # begin stopping the service
- d.addCallback(lambda _ : self.events.append('STOP@%d' % self.clock.seconds()))
-
- # run the clock out
- while self.clock.seconds() < 40:
- self.clock.advance(1)
-
- # note that the stopService completes after the first build completes, and no
- # subsequent builds occur
- self.assertEqual(self.events, [ 'B@0', 'STOP@6' ])
- self.assertEqual(self.state.get('last_build'), 0)
-
- return d
-
- def test_iterations_with_initial_state(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- self.state['last_build'] = self.clock.seconds() - 7 # so next build should start in 6s
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < 30:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@6', 'B@19' ])
- self.assertEqual(self.state.get('last_build'), 19)
-
- d = sched.stopService()
- return d
-
- def test_getNextBuildTime_None(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- # given None, build right away
- d = sched.getNextBuildTime(None)
- d.addCallback(lambda t : self.assertEqual(t, 0))
- return d
-
- def test_getNextBuildTime_given(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- # given a time, add the periodicBuildTimer to it
- d = sched.getNextBuildTime(20)
- d.addCallback(lambda t : self.assertEqual(t, 33))
- return d
-
- def test_getPendingBuildTimes(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- self.state['last_build'] = self.clock.seconds() - 10 # so next build should start in 3s
-
- sched.startService()
- self.clock.advance(0) # let it schedule the first build
- self.assertEqual(sched.getPendingBuildTimes(), [ 3.0 ])
-
- d = sched.stopService()
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py
deleted file mode 100644
index 54ecd70d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import task, defer
-from buildbot.schedulers import timed
-from buildbot.test.util import scheduler
-
-class Timed(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 928754
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- class Subclass(timed.Timed):
- def getNextBuildTime(self, lastActuation):
- self.got_lastActuation = lastActuation
- return defer.succeed((lastActuation or 1000) + 60)
- def startBuild(self):
- self.started_build = True
- return defer.succeed(None)
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- sched = self.attachScheduler(self.Subclass(**kwargs), self.OBJECTID)
- self.clock = sched._reactor = task.Clock()
- return sched
-
- # tests
-
- # note that most of the heavy-lifting for testing this class is handled by
- # the subclasses' tests, as that's the more natural place for it
-
- def test_getPendingBuildTimes(self):
- sched = self.makeScheduler(name='test', builderNames=['foo'])
-
- sched.startService()
-
- self.assertEqual(sched.got_lastActuation, None)
- self.assertEqual(sched.getPendingBuildTimes(), [ 1060 ])
-
- self.clock.advance(1065)
- self.assertTrue(sched.started_build)
- self.assertEqual(sched.getPendingBuildTimes(), [ 1120 ])
-
- d = sched.stopService()
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py
deleted file mode 100644
index eb225b5b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.schedulers import triggerable
-from buildbot.process import properties
-from buildbot.test.util import scheduler
-
-class Triggerable(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 33
-
- def setUp(self):
- self.setUpScheduler()
- self.subscription = None
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, **kwargs):
- sched = self.attachScheduler(
- triggerable.Triggerable(name='n', builderNames=['b'], **kwargs),
- self.OBJECTID)
-
- return sched
-
- # tests
-
- # NOTE: these tests take advantage of the fact that all of the fake
- # scheduler operations are synchronous, and thus do not return a Deferred.
- # The Deferred from trigger() is completely processed before this test
- # method returns.
-
- def test_trigger(self):
- sched = self.makeScheduler(codebases = {'cb':{'repository':'r'}})
- # no subscription should be in place yet
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
-
- # trigger the scheduler, exercising properties while we're at it
- set_props = properties.Properties()
- set_props.setProperty('pr', 'op', 'test')
- ss = {'revision':'myrev',
- 'branch':'br',
- 'project':'p',
- 'repository':'r',
- 'codebase':'cb' }
- d = sched.trigger({'cb': ss}, set_props=set_props)
-
- bsid = self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('pr', ('op', 'test')),
- ('scheduler', ('n', 'Scheduler')),
- ],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r',
- codebase='cb', revision='myrev', sourcestampsetid=100)
- })
- # set up a boolean so that we can know when the deferred fires
- self.fired = False
- def fired((result, brids)):
- self.assertEqual(result, 13) # 13 comes from the result below
- self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid))
- self.fired = True
- d.addCallback(fired)
-
- # check that the scheduler has subscribed to buildset changes, but
- # not fired yet
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildset_completion'], None)
- self.assertFalse(self.fired)
-
- # pretend a non-matching buildset is complete
- callbacks['buildset_completion'](bsid+27, 3)
-
- # scheduler should not have reacted
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildset_completion'], None)
- self.assertFalse(self.fired)
-
- # pretend the matching buildset is complete
- callbacks['buildset_completion'](bsid, 13)
-
- # scheduler should have reacted
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
- self.assertTrue(self.fired)
-
- def test_trigger_overlapping(self):
- sched = self.makeScheduler(codebases = {'cb':{'repository':'r'}})
-
- # no subscription should be in place yet
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
-
- # define sourcestamp
- ss = {'revision':'myrev1',
- 'branch':'br',
- 'project':'p',
- 'repository':'r',
- 'codebase':'cb' }
- # trigger the scheduler the first time
- d = sched.trigger({'cb':ss})
- bsid1 = self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev1', sourcestampsetid=100)})
- d.addCallback(lambda (res, brids) : self.assertEqual(res, 11)
- and self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid1)))
-
- # define sourcestamp
- ss = {'revision':'myrev2',
- 'branch':'br',
- 'project':'p',
- 'repository':'r',
- 'codebase':'cb' }
- # and the second time
- d = sched.trigger({'cb':ss})
- bsid2 = self.db.buildsets.assertBuildset(bsid1+1, # assumes bsid's are sequential
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)', sourcestampsetid=101),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev2', sourcestampsetid=101)})
- d.addCallback(lambda (res, brids) : self.assertEqual(res, 22)
- and self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid2)))
-
- # check that the scheduler has subscribed to buildset changes
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildset_completion'], None)
-
- # let a few buildsets complete
- callbacks['buildset_completion'](bsid2+27, 3)
- callbacks['buildset_completion'](bsid2, 22)
- callbacks['buildset_completion'](bsid2+7, 3)
- callbacks['buildset_completion'](bsid1, 11)
-
- # both should have triggered with appropriate results, and the
- # subscription should be cancelled
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
-
- def test_trigger_with_unknown_sourcestamp(self):
- # Test a scheduler with 2 repositories.
- # Trigger the scheduler with a sourcestamp that is unknown to the scheduler
- # Expected Result:
- # sourcestamp 1 for repository 1 based on configured sourcestamp
- # sourcestamp 2 for repository 2 based on configured sourcestamp
- sched = self.makeScheduler(
- codebases = {'cb':{'repository':'r', 'branch': 'branchX'},
- 'cb2':{'repository':'r2', 'branch': 'branchX'},})
-
- ss = {'repository': 'r3', 'codebase': 'cb3', 'revision': 'fixrev3',
- 'branch': 'default', 'project': 'p' }
- sched.trigger(sourcestamps = {'cb3': ss})
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='branchX', project='', repository='r', codebase='cb',
- revision=None, sourcestampsetid=100),
- 'cb2':
- dict(branch='branchX', project='', repository='r2', codebase='cb2',
- revision=None, sourcestampsetid=100),})
-
- def test_trigger_without_sourcestamps(self):
- # Test a scheduler with 2 repositories.
- # Trigger the scheduler without a sourcestamp
- # Expected Result:
- # sourcestamp 1 for repository 1 based on configured sourcestamp
- # sourcestamp 2 for repository 2 based on configured sourcestamp
- sched = self.makeScheduler(
- codebases = {'cb':{'repository':'r', 'branch': 'branchX'},
- 'cb2':{'repository':'r2', 'branch': 'branchX'},})
-
- sched.trigger(sourcestamps = None)
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='branchX', project='', repository='r', codebase='cb',
- revision=None, sourcestampsetid=100),
- 'cb2':
- dict(branch='branchX', project='', repository='r2', codebase='cb2',
- revision=None, sourcestampsetid=100),}) \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py
deleted file mode 100644
index 1aaa5b34..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py
+++ /dev/null
@@ -1,727 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import mock
-import os
-import shutil
-import cStringIO as StringIO
-import sys
-
-import twisted
-from twisted.internet import defer
-from twisted.trial import unittest
-from twisted.protocols import basic
-from buildbot.schedulers import trysched
-from buildbot.test.util import dirs
-from buildbot.test.util import scheduler
-from buildbot.util import json
-
-
-class TryBase(unittest.TestCase):
-
- def test_filterBuilderList_ok(self):
- sched = trysched.TryBase(
- name='tsched', builderNames=['a', 'b', 'c'], properties={})
- self.assertEqual(sched.filterBuilderList(['b', 'c']), ['b', 'c'])
-
- def test_filterBuilderList_bad(self):
- sched = trysched.TryBase(
- name='tsched', builderNames=['a', 'b'], properties={})
- self.assertEqual(sched.filterBuilderList(['b', 'c']), [])
-
- def test_filterBuilderList_empty(self):
- sched = trysched.TryBase(
- name='tsched', builderNames=['a', 'b'], properties={})
- self.assertEqual(sched.filterBuilderList([]), ['a', 'b'])
-
-
-class JobdirService(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.jobdir = 'jobdir'
- self.newdir = os.path.join(self.jobdir, 'new')
- self.curdir = os.path.join(self.jobdir, 'cur')
- self.tmpdir = os.path.join(self.jobdir, 'tmp')
- self.setUpDirs(self.jobdir, self.newdir, self.curdir, self.tmpdir)
-
- def tearDown(self):
- self.tearDownDirs()
-
- def test_messageReceived(self):
- svc = trysched.JobdirService(self.jobdir)
-
- # creat some new data to process
- jobdata = os.path.join(self.newdir, 'jobdata')
- with open(jobdata, "w") as f:
- f.write('JOBDATA')
-
- # stub out svc.parent.handleJobFile and .jobdir
- def handleJobFile(filename, f):
- self.assertEqual(filename, 'jobdata')
- self.assertEqual(f.read(), 'JOBDATA')
- svc.parent = mock.Mock()
- svc.parent.handleJobFile = handleJobFile
- svc.parent.jobdir = self.jobdir
-
- # run it
- svc.messageReceived('jobdata')
-
-
-class Try_Jobdir(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 23
-
- def setUp(self):
- self.setUpScheduler()
- self.jobdir = None
-
- def tearDown(self):
- self.tearDownScheduler()
- if self.jobdir:
- shutil.rmtree(self.jobdir)
-
- # tests
-
- def do_test_startService(self, jobdir, exp_jobdir):
- # set up jobdir
- self.jobdir = os.path.abspath('jobdir')
- if os.path.exists(self.jobdir):
- shutil.rmtree(self.jobdir)
- os.mkdir(self.jobdir)
-
- # build scheduler
- kwargs = dict(name="tsched", builderNames=['a'], jobdir=self.jobdir)
- sched = self.attachScheduler(
- trysched.Try_Jobdir(**kwargs), self.OBJECTID)
-
- # start it
- sched.startService()
-
- # check that it has set the basedir correctly
- self.assertEqual(sched.watcher.basedir, self.jobdir)
-
- return sched.stopService()
-
- def test_startService_reldir(self):
- return self.do_test_startService(
- 'jobdir',
- os.path.abspath('basedir/jobdir'))
-
- def test_startService_reldir_subdir(self):
- return self.do_test_startService(
- 'jobdir',
- os.path.abspath('basedir/jobdir/cur'))
-
- def test_startService_absdir(self):
- return self.do_test_startService(
- os.path.abspath('jobdir'),
- os.path.abspath('jobdir'))
-
- # parseJob
-
- def test_parseJob_empty(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['a'], jobdir='foo')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob, StringIO.StringIO(''))
-
- def test_parseJob_longer_than_netstring_MAXLENGTH(self):
- self.patch(basic.NetstringReceiver, 'MAX_LENGTH', 100)
- sched = trysched.Try_Jobdir(name='tsched', builderNames=['a'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'buildera', 'builderc'
- )
- jobstr += 'x' * 200
-
- test_temp_file = StringIO.StringIO(jobstr)
-
- self.assertRaises(trysched.BadJobfile,
- lambda : sched.parseJob(test_temp_file))
-
- def test_parseJob_invalid(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['a'], jobdir='foo')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob,
- StringIO.StringIO('this is not a netstring'))
-
- def test_parseJob_invalid_version(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['a'], jobdir='foo')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob, StringIO.StringIO('1:9,'))
-
- def makeNetstring(self, *strings):
- return ''.join(['%d:%s,' % (len(s), s) for s in strings])
-
- def test_parseJob_v1(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': '',
- 'who': '',
- 'comment': '',
- 'repository': '',
- 'properties': {},
- })
-
- def test_parseJob_v1_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '1', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v1_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', '', '', '1', 'this is my diff, -- ++, etc.'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v1_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', '', '', '1', 'this is my diff, -- ++, etc.'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v2(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '2', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': '',
- 'comment': '',
- 'repository': 'repo',
- 'properties': {},
- })
-
- def test_parseJob_v2_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '2', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v2_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '2', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v2_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '2', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v3(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '3', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': 'who',
- 'comment': '',
- 'repository': 'repo',
- 'properties': {},
- })
-
- def test_parseJob_v3_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '3', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v3_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '3', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v3_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '3', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v4(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '4', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': 'who',
- 'comment': 'comment',
- 'repository': 'repo',
- 'properties': {},
- })
-
- def test_parseJob_v4_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '4', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v4_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '4', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v4_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '4', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v5(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': 'extid', 'branch': 'trunk', 'baserev': '1234',
- 'patch_level': 1, 'patch_body': 'this is my diff, -- ++, etc.',
- 'repository': 'repo', 'project': 'proj', 'who': 'who',
- 'comment': 'comment', 'builderNames': ['buildera', 'builderc'],
- 'properties': {'foo': 'bar'},
- }))
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': 'who',
- 'comment': 'comment',
- 'repository': 'repo',
- 'properties': {'foo': 'bar'},
- })
-
- def test_parseJob_v5_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '4', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v5_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': 'extid', 'branch': 'trunk', 'baserev': '1234',
- 'patch_level': '1', 'diff': 'this is my diff, -- ++, etc.',
- 'repository': 'repo', 'project': 'proj', 'who': 'who',
- 'comment': 'comment', 'builderNames': [],
- 'properties': {'foo': 'bar'},
- }))
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v5_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': 'extid', 'branch': 'trunk', 'baserev': '1234',
- 'patch_level': '1', 'diff': 'this is my diff, -- ++, etc.',
- 'repository': 'repo', 'project': 'proj', 'who': 'who',
- 'comment': 'comment', 'builderNames': ['buildera', 'builderb'],
- 'properties': {},
- }))
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v5_invalid_json(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring('5', '{"comment": "com}')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob, StringIO.StringIO(jobstr))
-
- # handleJobFile
-
- def call_handleJobFile(self, parseJob):
- sched = self.attachScheduler(
- trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'],
- jobdir='foo'), self.OBJECTID)
- fakefile = mock.Mock()
-
- def parseJob_(f):
- assert f is fakefile
- return parseJob(f)
- sched.parseJob = parseJob_
- return sched.handleJobFile('fakefile', fakefile)
-
- def makeSampleParsedJob(self, **overrides):
- pj = dict(baserev='1234', branch='trunk',
- builderNames=['buildera', 'builderb'],
- jobid='extid', patch_body='this is my diff, -- ++, etc.',
- patch_level=1, project='proj', repository='repo', who='who',
- comment='comment', properties={})
- pj.update(overrides)
- return pj
-
- def test_handleJobFile(self):
- d = self.call_handleJobFile(lambda f: self.makeSampleParsedJob())
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who",
- external_idstring='extid',
- properties=[('scheduler', ('tsched', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='repo', codebase='',
- project='proj', revision='1234',
- patch_body='this is my diff, -- ++, etc.',
- patch_level=1, patch_subdir='',
- patch_author='who',
- patch_comment='comment',
- sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_handleJobFile_exception(self):
- def parseJob(f):
- raise trysched.BadJobfile
- d = self.call_handleJobFile(parseJob)
-
- def check(bsid):
- self.db.buildsets.assertBuildsets(0)
- self.assertEqual(
- 1, len(self.flushLoggedErrors(trysched.BadJobfile)))
- d.addCallback(check)
- return d
- if twisted.version.major <= 9 and sys.version_info[:2] >= (2, 7):
- test_handleJobFile_exception.skip = (
- "flushLoggedErrors does not work correctly on 9.0.0 "
- "and earlier with Python-2.7")
-
- def test_handleJobFile_bad_builders(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(builderNames=['xxx']))
-
- def check(_):
- self.db.buildsets.assertBuildsets(0)
- d.addCallback(check)
- return d
-
- def test_handleJobFile_subset_builders(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(builderNames=['buildera']))
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who",
- external_idstring='extid',
- properties=[('scheduler', ('tsched', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='repo', codebase='',
- project='proj', revision='1234',
- patch_body='this is my diff, -- ++, etc.',
- patch_level=1, patch_subdir='',
- patch_author='who',
- patch_comment='comment',
- sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_handleJobFile_with_try_properties(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(properties={'foo': 'bar'}))
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who",
- external_idstring='extid',
- properties=[
- ('foo', ('bar', 'try build')),
- ('scheduler', ('tsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='repo', codebase='',
- project='proj', revision='1234',
- patch_body='this is my diff, -- ++, etc.',
- patch_level=1, patch_subdir='',
- patch_author='who',
- patch_comment='comment',
- sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_handleJobFile_with_invalid_try_properties(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(properties=['foo', 'bar']))
- return self.assertFailure(d, AttributeError)
-
-
-class Try_Userpass_Perspective(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 26
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, **kwargs):
- sched = self.attachScheduler(trysched.Try_Userpass(**kwargs),
- self.OBJECTID)
- # Try will return a remote version of master.status, so give it
- # something to return
- sched.master.status = mock.Mock()
- return sched
-
- def call_perspective_try(self, *args, **kwargs):
- sched = self.makeScheduler(name='tsched', builderNames=['a', 'b'],
- port='xxx', userpass=[('a', 'b')], properties=dict(frm='schd'))
- persp = trysched.Try_Userpass_Perspective(sched, 'a')
- return persp.perspective_try(*args, **kwargs)
-
- def test_perspective_try(self):
- d = self.call_perspective_try(
- 'default', 'abcdef', (1, '-- ++'), 'repo', 'proj', ['a'],
- properties={'pr': 'op'})
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job",
- external_idstring=None,
- properties=[
- ('frm', ('schd', 'Scheduler')),
- ('pr', ('op', 'try build')),
- ('scheduler', ('tsched', 'Scheduler')),
- ],
- sourcestampsetid=100,
- ),
- {'':
- dict(branch='default', repository='repo', codebase='',
- project='proj', revision='abcdef',
- sourcestampsetid=100,
- patch_body='-- ++', patch_level=1, patch_subdir='',
- patch_author="", patch_comment="")
- })
- d.addCallback(check)
- return d
-
- def test_perspective_try_who(self):
- d = self.call_perspective_try(
- 'default', 'abcdef', (1, '-- ++'), 'repo', 'proj', ['a'],
- who='who', comment='comment', properties={'pr': 'op'})
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who (comment)",
- external_idstring=None,
- properties=[
- ('frm', ('schd', 'Scheduler')),
- ('pr', ('op', 'try build')),
- ('scheduler', ('tsched', 'Scheduler')),
- ],
- sourcestampsetid=100,
- ),
- {'':
- dict(branch='default', repository='repo', codebase='',
- project='proj', revision='abcdef',
- sourcestampsetid=100,
- patch_body='-- ++', patch_level=1, patch_subdir='',
- patch_author='who', patch_comment="comment")
- })
- d.addCallback(check)
- return d
-
- def test_perspective_try_bad_builders(self):
- d = self.call_perspective_try(
- 'default', 'abcdef', (1, '-- ++'), 'repo', 'proj', ['xxx'],
- properties={'pr': 'op'})
-
- def check(_):
- self.db.buildsets.assertBuildsets(0)
- d.addCallback(check)
- return d
-
- def test_getAvailableBuilderNames(self):
- sched = self.makeScheduler(name='tsched', builderNames=['a', 'b'],
- port='xxx', userpass=[('a', 'b')])
- persp = trysched.Try_Userpass_Perspective(sched, 'a')
- d = defer.maybeDeferred(
- lambda: persp.perspective_getAvailableBuilderNames())
-
- def check(buildernames):
- self.assertEqual(buildernames, ['a', 'b'])
- d.addCallback(check)
- return d
-
-
-class Try_Userpass(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 25
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, **kwargs):
- sched = self.attachScheduler(trysched.Try_Userpass(**kwargs),
- self.OBJECTID)
- return sched
-
- def test_service(self):
- sched = self.makeScheduler(name='tsched', builderNames=['a'],
- port='tcp:9999', userpass=[('fred', 'derf')])
- # patch out the pbmanager's 'register' command both to be sure
- # the registration is correct and to get a copy of the factory
- registration = mock.Mock()
- registration.unregister = lambda: defer.succeed(None)
- sched.master.pbmanager = mock.Mock()
-
- def register(portstr, user, passwd, factory):
- self.assertEqual([portstr, user, passwd],
- ['tcp:9999', 'fred', 'derf'])
- self.got_factory = factory
- return registration
- sched.master.pbmanager.register = register
- # start it
- sched.startService()
- # make a fake connection by invoking the factory, and check that we
- # get the correct perspective
- persp = self.got_factory(mock.Mock(), 'fred')
- self.failUnless(isinstance(persp, trysched.Try_Userpass_Perspective))
- return sched.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py
deleted file mode 100644
index 7d7d22de..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import string
-import cStringIO
-import textwrap
-from twisted.trial import unittest
-from buildbot.scripts import base
-from buildbot.test.util import dirs, misc
-from twisted.python import usage, runtime
-
-class TestIBD(dirs.DirsMixin, misc.StdoutAssertionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test')
- self.stdout = cStringIO.StringIO()
- self.setUpStdoutAssertions()
-
- def test_isBuildmasterDir_no_dir(self):
- self.assertFalse(base.isBuildmasterDir(os.path.abspath('test/nosuch')))
- self.assertInStdout('error reading')
- self.assertInStdout('invalid buildmaster directory')
-
- def test_isBuildmasterDir_no_file(self):
- self.assertFalse(base.isBuildmasterDir(os.path.abspath('test')))
- self.assertInStdout('error reading')
- self.assertInStdout('invalid buildmaster directory')
-
- def test_isBuildmasterDir_no_Application(self):
- with open(os.path.join('test', 'buildbot.tac'), 'w') as f:
- f.write("foo\nx = Application('buildslave')\nbar")
- self.assertFalse(base.isBuildmasterDir(os.path.abspath('test')))
- self.assertInStdout('unexpected content')
- self.assertInStdout('invalid buildmaster directory')
-
- def test_isBuildmasterDir_matches(self):
- with open(os.path.join('test', 'buildbot.tac'), 'w') as f:
- f.write("foo\nx = Application('buildmaster')\nbar")
- self.assertTrue(base.isBuildmasterDir(os.path.abspath('test')))
- self.assertWasQuiet()
-
-class TestTacFallback(dirs.DirsMixin, unittest.TestCase):
- """
- Tests for L{base.getConfigFileFromTac}.
- """
-
- def setUp(self):
- """
- Create a base directory.
- """
- self.basedir = os.path.abspath('basedir')
- return self.setUpDirs('basedir')
-
- def _createBuildbotTac(self, contents=None):
- """
- Create a C{buildbot.tac} that points to a given C{configfile}
- and create that file.
-
- @param configfile: Config file to point at and create.
- @type configfile: L{str}
- """
- if contents is None:
- contents = '#dummy'
- tacfile = os.path.join(self.basedir, "buildbot.tac")
- with open(tacfile, "wt") as f:
- f.write(contents)
- return tacfile
-
-
- def test_getConfigFileFromTac(self):
- """
- When L{getConfigFileFromTac} is passed a C{basedir}
- containing a C{buildbot.tac}, it reads the location
- of the config file from there.
- """
- self._createBuildbotTac("configfile='other.cfg'")
- foundConfigFile = base.getConfigFileFromTac(
- basedir=self.basedir)
- self.assertEqual(foundConfigFile, "other.cfg")
-
- def test_getConfigFileFromTac_fallback(self):
- """
- When L{getConfigFileFromTac} is passed a C{basedir}
- which doesn't contain a C{buildbot.tac},
- it returns C{master.cfg}
- """
- foundConfigFile = base.getConfigFileFromTac(
- basedir=self.basedir)
- self.assertEqual(foundConfigFile, 'master.cfg')
-
-
- def test_getConfigFileFromTac_tacWithoutConfigFile(self):
- """
- When L{getConfigFileFromTac} is passed a C{basedir}
- containing a C{buildbot.tac}, but C{buildbot.tac} doesn't
- define C{configfile}, L{getConfigFileFromTac} returns C{master.cfg}
- """
- self._createBuildbotTac()
- foundConfigFile = base.getConfigFileFromTac(
- basedir=self.basedir)
- self.assertEqual(foundConfigFile, 'master.cfg')
-
-
- def test_getConfigFileFromTac_usingFile(self):
- """
- Wehn L{getConfigFileFromTac} is passed a C{basedir}
- containing a C{buildbot.tac} which references C{__file__},
- that reference points to C{buildbot.tac}.
- """
- self._createBuildbotTac(textwrap.dedent("""
- from twisted.python.util import sibpath
- configfile = sibpath(__file__, "relative.cfg")
- """))
- foundConfigFile = base.getConfigFileFromTac(basedir=self.basedir)
- self.assertEqual(foundConfigFile, os.path.join(self.basedir, "relative.cfg"))
-
-
-
-class TestSubcommandOptions(unittest.TestCase):
-
- def fakeOptionsFile(self, **kwargs):
- self.patch(base.SubcommandOptions, 'loadOptionsFile',
- lambda self : kwargs.copy())
-
- def parse(self, cls, *args):
- self.opts = cls()
- self.opts.parseOptions(args)
- return self.opts
-
- class Bare(base.SubcommandOptions):
- optFlags = [ [ 'foo', 'f', 'Foo!' ] ]
-
- def test_bare_subclass(self):
- self.fakeOptionsFile()
- opts = self.parse(self.Bare, '-f')
- self.assertTrue(opts['foo'])
-
- class ParamsAndOptions(base.SubcommandOptions):
- optParameters = [ [ 'volume', 'v', '5', 'How Loud?' ] ]
- buildbotOptions = [ [ 'volcfg', 'volume' ] ]
-
- def test_buildbotOptions(self):
- self.fakeOptionsFile()
- opts = self.parse(self.ParamsAndOptions)
- self.assertEqual(opts['volume'], '5')
-
- def test_buildbotOptions_options(self):
- self.fakeOptionsFile(volcfg='3')
- opts = self.parse(self.ParamsAndOptions)
- self.assertEqual(opts['volume'], '3')
-
- def test_buildbotOptions_override(self):
- self.fakeOptionsFile(volcfg='3')
- opts = self.parse(self.ParamsAndOptions, '--volume', '7')
- self.assertEqual(opts['volume'], '7')
-
- class RequiredOptions(base.SubcommandOptions):
- optParameters = [ [ 'volume', 'v', None, 'How Loud?' ] ]
- requiredOptions = [ 'volume' ]
-
- def test_requiredOptions(self):
- self.fakeOptionsFile()
- self.assertRaises(usage.UsageError,
- lambda : self.parse(self.RequiredOptions))
-
-class TestLoadOptionsFile(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test', 'home')
- self.opts = base.SubcommandOptions()
- self.dir = os.path.abspath('test')
- self.home = os.path.abspath('home')
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- def do_loadOptionsFile(self, _here, exp):
- # only patch these os.path functions briefly, to
- # avoid breaking other parts of the test system
- patches = []
-
- if runtime.platformType == 'win32':
- from win32com.shell import shell
- patches.append(self.patch(shell, 'SHGetFolderPath',
- lambda *args : self.home))
- else:
- def expanduser(p):
- return p.replace('~/', self.home + '/')
- patches.append(self.patch(os.path, 'expanduser', expanduser))
-
- old_dirname = os.path.dirname
- def dirname(p):
- # bottom out at self.dir, rather than /
- if p == self.dir:
- return p
- return old_dirname(p)
- patches.append(self.patch(os.path, 'dirname', dirname))
-
- try:
- self.assertEqual(self.opts.loadOptionsFile(_here=_here), exp)
- finally:
- for p in patches:
- p.restore()
-
- def writeOptionsFile(self, dir, content, bbdir='.buildbot'):
- os.makedirs(os.path.join(dir, bbdir))
- with open(os.path.join(dir, bbdir, 'options'), 'w') as f:
- f.write(content)
-
- def test_loadOptionsFile_subdirs_not_found(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- self.do_loadOptionsFile(_here=subdir, exp={})
-
- def test_loadOptionsFile_subdirs_at_root(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- self.writeOptionsFile(self.dir, 'abc="def"')
- self.writeOptionsFile(self.home, 'abc=123') # not seen
- self.do_loadOptionsFile(_here=subdir, exp={'abc':'def'})
-
- def test_loadOptionsFile_subdirs_at_tip(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- self.writeOptionsFile(os.path.join(self.dir, 'a', 'b'), 'abc="def"')
- self.writeOptionsFile(self.dir, 'abc=123') # not seen
- self.do_loadOptionsFile(_here=subdir, exp={'abc':'def'})
-
- def test_loadOptionsFile_subdirs_at_homedir(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- # on windows, the subdir of the home (well, appdata) dir
- # is 'buildbot', not '.buildbot'
- self.writeOptionsFile(self.home, 'abc=123',
- 'buildbot' if runtime.platformType == 'win32' else '.buildbot')
- self.do_loadOptionsFile(_here=subdir, exp={'abc':123})
-
- def test_loadOptionsFile_syntax_error(self):
- self.writeOptionsFile(self.dir, 'abc=abc')
- self.assertRaises(NameError, lambda :
- self.do_loadOptionsFile(_here=self.dir, exp={}))
- self.assertInStdout('error while reading')
-
- def test_loadOptionsFile_toomany(self):
- subdir = os.path.join(self.dir, *tuple(string.lowercase))
- os.makedirs(subdir)
- self.do_loadOptionsFile(_here=subdir, exp={})
- self.assertInStdout('infinite glories')
-
- # NOTE: testing the ownership check requires patching os.stat, which causes
- # other problems since it is so heavily used.
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py
deleted file mode 100644
index c6bf3bde..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import mock
-import re
-import sys
-import os
-import textwrap
-import cStringIO
-from twisted.trial import unittest
-from buildbot.test.util import dirs, compat
-from buildbot.scripts import base, checkconfig
-
-class TestConfigLoader(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpDirs('configdir')
-
- def tearDown(self):
- return self.tearDownDirs()
-
- # tests
-
- def do_test_load(self, config='', other_files={},
- stdout_re=None, stderr_re=None):
- configFile = os.path.join('configdir', 'master.cfg')
- with open(configFile, "w") as f:
- f.write(config)
- for filename, contents in other_files.iteritems():
- if type(filename) == type(()):
- fn = os.path.join('configdir', *filename)
- dn = os.path.dirname(fn)
- if not os.path.isdir(dn):
- os.makedirs(dn)
- else:
- fn = os.path.join('configdir', filename)
- with open(fn, "w") as f:
- f.write(contents)
-
- old_stdout, old_stderr = sys.stdout, sys.stderr
- stdout = sys.stdout = cStringIO.StringIO()
- stderr = sys.stderr = cStringIO.StringIO()
- try:
- checkconfig._loadConfig(
- basedir='configdir', configFile="master.cfg", quiet=False)
- finally:
- sys.stdout, sys.stderr = old_stdout, old_stderr
- if stdout_re:
- stdout = stdout.getvalue()
- self.failUnless(stdout_re.search(stdout), stdout)
- if stderr_re:
- stderr = stderr.getvalue()
- self.failUnless(stderr_re.search(stderr), stderr)
-
- def test_success(self):
- len_sys_path = len(sys.path)
- config = textwrap.dedent("""\
- c = BuildmasterConfig = {}
- c['multiMaster'] = True
- c['schedulers'] = []
- from buildbot.config import BuilderConfig
- from buildbot.process.factory import BuildFactory
- c['builders'] = [
- BuilderConfig('testbuilder', factory=BuildFactory(),
- slavename='sl'),
- ]
- from buildbot.buildslave import BuildSlave
- c['slaves'] = [
- BuildSlave('sl', 'pass'),
- ]
- c['slavePortnum'] = 9989
- """)
- self.do_test_load(config=config,
- stdout_re=re.compile('Config file is good!'))
-
- # (regression) check that sys.path hasn't changed
- self.assertEqual(len(sys.path), len_sys_path)
-
- @compat.usesFlushLoggedErrors
- def test_failure_ImportError(self):
- config = textwrap.dedent("""\
- import test_scripts_checkconfig_does_not_exist
- """)
- self.do_test_load(config=config,
- stderr_re=re.compile(
- 'No module named test_scripts_checkconfig_does_not_exist'))
- self.flushLoggedErrors()
-
- @compat.usesFlushLoggedErrors
- def test_failure_no_slaves(self):
- config = textwrap.dedent("""\
- BuildmasterConfig={}
- """)
- self.do_test_load(config=config,
- stderr_re=re.compile('no slaves'))
- self.flushLoggedErrors()
-
- def test_success_imports(self):
- config = textwrap.dedent("""\
- from othermodule import port
- c = BuildmasterConfig = {}
- c['schedulers'] = []
- c['builders'] = []
- c['slaves'] = []
- c['slavePortnum'] = port
- """)
- other_files = { 'othermodule.py' : 'port = 9989' }
- self.do_test_load(config=config, other_files=other_files)
-
- def test_success_import_package(self):
- config = textwrap.dedent("""\
- from otherpackage.othermodule import port
- c = BuildmasterConfig = {}
- c['schedulers'] = []
- c['builders'] = []
- c['slaves'] = []
- c['slavePortnum'] = port
- """)
- other_files = {
- ('otherpackage', '__init__.py') : '',
- ('otherpackage', 'othermodule.py') : 'port = 9989',
- }
- self.do_test_load(config=config, other_files=other_files)
-
-
-class TestCheckconfig(unittest.TestCase):
-
- def setUp(self):
- self.loadConfig = mock.Mock(spec=checkconfig._loadConfig, return_value=3)
- self.patch(checkconfig, '_loadConfig', self.loadConfig)
-
- def test_checkconfig_given_dir(self):
- self.assertEqual(checkconfig.checkconfig(dict(configFile='.')), 3)
- self.loadConfig.assert_called_with(basedir='.', configFile='master.cfg', quiet=None)
-
- def test_checkconfig_given_file(self):
- config = dict(configFile='master.cfg')
- self.assertEqual(checkconfig.checkconfig(config), 3)
- self.loadConfig.assert_called_with(basedir=os.getcwd(), configFile='master.cfg', quiet=None)
-
- def test_checkconfig_quiet(self):
- config = dict(configFile='master.cfg', quiet=True)
- self.assertEqual(checkconfig.checkconfig(config), 3)
- self.loadConfig.assert_called_with(basedir=os.getcwd(), configFile='master.cfg', quiet=True)
-
- def test_checkconfig_syntaxError_quiet(self):
- """
- When C{base.getConfigFileFromTac} raises L{SyntaxError},
- C{checkconfig.checkconfig} return an error.
- """
- mockGetConfig = mock.Mock(spec=base.getConfigFileFromTac,
- side_effect=SyntaxError)
- self.patch(checkconfig, 'getConfigFileFromTac', mockGetConfig)
- config = dict(configFile='.', quiet=True)
- self.assertEqual(checkconfig.checkconfig(config), 1)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py
deleted file mode 100644
index 081a2747..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.scripts import create_master
-from buildbot.db import connector, model
-from buildbot.test.util import dirs, misc
-
-def mkconfig(**kwargs):
- config = dict(force=False, relocatable=False, config='master.cfg',
- db='sqlite:///state.sqlite', basedir=os.path.abspath('basedir'),
- quiet=False, **{'no-logrotate':False, 'log-size':'10000000',
- 'log-count':'10'})
- config.update(kwargs)
- return config
-
-class TestCreateMaster(misc.StdoutAssertionsMixin, unittest.TestCase):
-
- def setUp(self):
- # createMaster is decorated with @in_reactor, so strip that decoration
- # since the master is already running
- self.patch(create_master, 'createMaster',
- create_master.createMaster._orig)
- self.setUpStdoutAssertions()
-
- # tests
-
- def do_test_createMaster(self, config):
- # mock out everything that createMaster calls, then check that
- # they are called, in order
- functions = [ 'makeBasedir', 'makeTAC', 'makeSampleConfig',
- 'makePublicHtml', 'makeTemplatesDir', 'createDB' ]
- repls = {}
- calls = []
- for fn in functions:
- repl = repls[fn] = mock.Mock(name=fn)
- repl.side_effect = lambda config, fn=fn : calls.append(fn)
- self.patch(create_master, fn, repl)
- repls['createDB'].side_effect = (lambda config :
- calls.append(fn) or defer.succeed(None))
- d = create_master.createMaster(config)
- @d.addCallback
- def check(rc):
- self.assertEqual(rc, 0)
- self.assertEqual(calls, functions)
- for repl in repls.values():
- repl.assert_called_with(config)
- return d
-
- def test_createMaster_quiet(self):
- d = self.do_test_createMaster(mkconfig(quiet=True))
- @d.addCallback
- def check(_):
- self.assertWasQuiet()
- return d
-
- def test_createMaster_loud(self):
- d = self.do_test_createMaster(mkconfig(quiet=False))
- @d.addCallback
- def check(_):
- self.assertInStdout('buildmaster configured in')
- return d
-
-class TestCreateMasterFunctions(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test')
- self.basedir = os.path.abspath(os.path.join('test', 'basedir'))
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- def assertInTacFile(self, str):
- self.assertIn(str,
- open(os.path.join('test', 'buildbot.tac'), 'rt').read())
-
- def assertNotInTacFile(self, str):
- self.assertNotIn(str,
- open(os.path.join('test', 'buildbot.tac'), 'rt').read())
-
- def assertDBSetup(self, basedir=None, db_url='sqlite:///state.sqlite',
- verbose=True):
- # mock out the database setup
- self.db = mock.Mock()
- self.db.setup.side_effect = lambda *a, **k : defer.succeed(None)
- self.DBConnector = mock.Mock()
- self.DBConnector.return_value = self.db
- self.patch(connector, 'DBConnector', self.DBConnector)
-
- basedir = basedir or self.basedir
- self.assertEqual(
- dict(basedir=self.DBConnector.call_args[0][1],
- db_url=self.DBConnector.call_args[0][0].mkconfig.db['db_url'],
- verbose=self.db.setup.call_args[1]['verbose'],
- check_version=self.db.setup.call_args[1]['check_version'],
- ),
- dict(basedir=self.basedir,
- db_url=db_url,
- verbose=True,
- check_version=False))
-
- # tests
-
- def test_makeBasedir(self):
- self.assertFalse(os.path.exists(self.basedir))
- create_master.makeBasedir(mkconfig(basedir=self.basedir))
- self.assertTrue(os.path.exists(self.basedir))
- self.assertInStdout('mkdir %s' % (self.basedir,))
-
- def test_makeBasedir_quiet(self):
- self.assertFalse(os.path.exists(self.basedir))
- create_master.makeBasedir(mkconfig(basedir=self.basedir, quiet=True))
- self.assertTrue(os.path.exists(self.basedir))
- self.assertWasQuiet()
-
- def test_makeBasedir_existing(self):
- os.mkdir(self.basedir)
- create_master.makeBasedir(mkconfig(basedir=self.basedir))
- self.assertInStdout('updating existing installation')
-
- def test_makeTAC(self):
- create_master.makeTAC(mkconfig(basedir='test'))
- self.assertInTacFile("Application('buildmaster')")
- self.assertWasQuiet()
-
- def test_makeTAC_relocatable(self):
- create_master.makeTAC(mkconfig(basedir='test', relocatable=True))
- self.assertInTacFile("basedir = '.'") # repr() prefers ''
- self.assertWasQuiet()
-
- def test_makeTAC_no_logrotate(self):
- create_master.makeTAC(mkconfig(basedir='test', **{'no-logrotate':True}))
- self.assertNotInTacFile("import Log")
- self.assertWasQuiet()
-
- def test_makeTAC_existing_incorrect(self):
- with open(os.path.join('test', 'buildbot.tac'), 'wt') as f:
- f.write('WRONG')
- create_master.makeTAC(mkconfig(basedir='test'))
- self.assertInTacFile("WRONG")
- self.assertTrue(os.path.exists(
- os.path.join('test', 'buildbot.tac.new')))
- self.assertInStdout('not touching existing buildbot.tac')
-
- def test_makeTAC_existing_incorrect_quiet(self):
- with open(os.path.join('test', 'buildbot.tac'), 'wt') as f:
- f.write('WRONG')
- create_master.makeTAC(mkconfig(basedir='test', quiet=True))
- self.assertInTacFile("WRONG")
- self.assertWasQuiet()
-
- def test_makeTAC_existing_correct(self):
- create_master.makeTAC(mkconfig(basedir='test', quiet=True))
- create_master.makeTAC(mkconfig(basedir='test'))
- self.assertFalse(os.path.exists(
- os.path.join('test', 'buildbot.tac.new')))
- self.assertInStdout('and is correct')
-
- def test_makeSampleConfig(self):
- create_master.makeSampleConfig(mkconfig(basedir='test'))
- self.assertTrue(os.path.exists(
- os.path.join('test', 'master.cfg.sample')))
- self.assertInStdout('creating ')
-
- def test_makeSampleConfig_db(self):
- create_master.makeSampleConfig(mkconfig(basedir='test', db='XXYYZZ',
- quiet=True))
- with open(os.path.join('test', 'master.cfg.sample'), 'rt') as f:
- self.assertIn("XXYYZZ", f.read())
- self.assertWasQuiet()
-
- def test_makePublicHtml(self):
- create_master.makePublicHtml(mkconfig(basedir='test', quiet=True))
- self.assertTrue(os.path.exists(
- os.path.join('test', 'public_html', 'robots.txt')))
- self.assertWasQuiet()
-
- def test_makeTemplatesDir(self):
- create_master.makeTemplatesDir(mkconfig(basedir='test', quiet=True))
- self.assertTrue(os.path.exists(
- os.path.join('test', 'templates', 'README.txt')))
- self.assertWasQuiet()
-
- @defer.inlineCallbacks
- def test_createDB(self):
- setup = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(connector.DBConnector, 'setup', setup)
- upgrade = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(model.Model, 'upgrade', upgrade)
- yield create_master.createDB(
- mkconfig(basedir='test', quiet=True),
- _noMonkey=True)
- setup.asset_called_with(check_version=False, verbose=False)
- upgrade.assert_called()
- self.assertWasQuiet()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py
deleted file mode 100644
index 656d2005..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-from twisted.trial import unittest
-from buildbot.scripts import restart, stop, start
-from buildbot.test.util import dirs, misc
-
-def mkconfig(**kwargs):
- config = dict(quiet=False, basedir=os.path.abspath('basedir'))
- config.update(kwargs)
- return config
-
-class TestStop(misc.StdoutAssertionsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('basedir')
- with open(os.path.join('basedir', 'buildbot.tac'), 'wt') as f:
- f.write("Application('buildmaster')")
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- # tests
-
- def test_restart_not_basedir(self):
- self.assertEqual(restart.restart(mkconfig(basedir='doesntexist')), 1)
- self.assertInStdout('invalid buildmaster directory')
-
- def test_restart_stop_fails(self):
- self.patch(stop, 'stop', lambda config, wait : 1)
- self.assertEqual(restart.restart(mkconfig()), 1)
-
- def test_restart_stop_succeeds_start_fails(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 1)
- self.assertEqual(restart.restart(mkconfig()), 1)
-
- def test_restart_succeeds(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 0)
- self.assertEqual(restart.restart(mkconfig()), 0)
- self.assertInStdout('now restarting')
-
- def test_restart_succeeds_quiet(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 0)
- self.assertEqual(restart.restart(mkconfig(quiet=True)), 0)
- self.assertWasQuiet()
-
- def test_restart_clean(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 0)
- self.assertEqual(restart.restart(mkconfig(quiet=True, clean=True)), 0)
- self.assertWasQuiet()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py
deleted file mode 100644
index 0da2c7d0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py
+++ /dev/null
@@ -1,971 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import sys
-import getpass
-import mock
-import cStringIO
-from twisted.trial import unittest
-from twisted.python import usage, runtime, log
-from buildbot.scripts import base, runner
-from buildbot.test.util import misc
-
-class OptionsMixin(object):
-
- def setUpOptions(self):
- self.options_file = {}
- self.patch(base.SubcommandOptions, 'loadOptionsFile',
- lambda other_self : self.options_file)
-
- def assertOptions(self, opts, exp):
- got = dict([(k, opts[k]) for k in exp])
- if got != exp:
- msg = []
- for k in exp:
- if opts[k] != exp[k]:
- msg.append(" %s: expected %r, got %r" %
- (k, exp[k], opts[k]))
- self.fail("did not get expected options\n" + ("\n".join(msg)))
-
-
-class TestUpgradeMasterOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.UpgradeMasterOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.UpgradeMasterOptions()
- self.assertIn('buildbot upgrade-master', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = dict(quiet=False, replace=False)
- self.assertOptions(opts, exp)
-
- def test_short(self):
- opts = self.parse('-q', '-r')
- exp = dict(quiet=True, replace=True)
- self.assertOptions(opts, exp)
-
- def test_long(self):
- opts = self.parse('--quiet', '--replace')
- exp = dict(quiet=True, replace=True)
- self.assertOptions(opts, exp)
-
-
-class TestCreateMasterOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.CreateMasterOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def defaults_and(self, **kwargs):
- defaults = dict(force=False, relocatable=False, config='master.cfg',
- db='sqlite:///state.sqlite', basedir=os.getcwd(), quiet=False,
- **{'no-logrotate':False, 'log-size':'10000000',
- 'log-count':'10'})
- unk_keys = set(kwargs.keys()) - set(defaults.keys())
- assert not unk_keys, "invalid keys %s" % (unk_keys,)
- opts = defaults.copy()
- opts.update(kwargs)
- return opts
-
- def test_synopsis(self):
- opts = runner.CreateMasterOptions()
- self.assertIn('buildbot create-master', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = self.defaults_and()
- self.assertOptions(opts, exp)
-
- def test_db_quiet(self):
- opts = self.parse('-q')
- exp = self.defaults_and(quiet=True)
- self.assertOptions(opts, exp)
-
- def test_db_quiet_long(self):
- opts = self.parse('--quiet')
- exp = self.defaults_and(quiet=True)
- self.assertOptions(opts, exp)
-
- def test_force(self):
- opts = self.parse('-f')
- exp = self.defaults_and(force=True)
- self.assertOptions(opts, exp)
-
- def test_force_long(self):
- opts = self.parse('--force')
- exp = self.defaults_and(force=True)
- self.assertOptions(opts, exp)
-
- def test_relocatable(self):
- opts = self.parse('-r')
- exp = self.defaults_and(relocatable=True)
- self.assertOptions(opts, exp)
-
- def test_relocatable_long(self):
- opts = self.parse('--relocatable')
- exp = self.defaults_and(relocatable=True)
- self.assertOptions(opts, exp)
-
- def test_no_logrotate(self):
- opts = self.parse('-n')
- exp = self.defaults_and(**{'no-logrotate' : True})
- self.assertOptions(opts, exp)
-
- def test_no_logrotate_long(self):
- opts = self.parse('--no-logrotate')
- exp = self.defaults_and(**{'no-logrotate' : True})
- self.assertOptions(opts, exp)
-
- def test_config(self):
- opts = self.parse('-cxyz')
- exp = self.defaults_and(config='xyz')
- self.assertOptions(opts, exp)
-
- def test_config_long(self):
- opts = self.parse('--config=xyz')
- exp = self.defaults_and(config='xyz')
- self.assertOptions(opts, exp)
-
- def test_log_size(self):
- opts = self.parse('-s124')
- exp = self.defaults_and(**{'log-size':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_size_long(self):
- opts = self.parse('--log-size=124')
- exp = self.defaults_and(**{'log-size':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_size_noninteger(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('--log-size=1M'))
-
- def test_log_count(self):
- opts = self.parse('-l124')
- exp = self.defaults_and(**{'log-count':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_count_long(self):
- opts = self.parse('--log-count=124')
- exp = self.defaults_and(**{'log-count':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_count_noninteger(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('--log-count=M'))
-
- def test_db_long(self):
- opts = self.parse('--db=foo://bar')
- exp = self.defaults_and(db='foo://bar')
- self.assertOptions(opts, exp)
-
- def test_db_basedir(self):
- path = r'c:\foo\bar' if runtime.platformType == "win32" else '/foo/bar'
- opts = self.parse('-f', path)
- exp = self.defaults_and(force=True, basedir=path)
- self.assertOptions(opts, exp)
-
-
-class BaseTestSimpleOptions(OptionsMixin):
- # tests for options with just --quiet and a usage message
-
- commandName = None
- optionsClass = None
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = self.optionsClass()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = self.optionsClass()
- self.assertIn('buildbot %s' % self.commandName, opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = dict(quiet=False)
- self.assertOptions(opts, exp)
-
- def test_quiet(self):
- opts = self.parse('--quiet')
- exp = dict(quiet=True)
- self.assertOptions(opts, exp)
-
-
-class TestStopOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'stop'
- optionsClass = runner.StopOptions
-
-
-class TestResetartOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'restart'
- optionsClass = runner.RestartOptions
-
- def test_nodaemon(self):
- opts = self.parse('--nodaemon')
- exp = dict(nodaemon=True)
- self.assertOptions(opts, exp)
-
-
-class TestStartOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'start'
- optionsClass = runner.StartOptions
-
- def test_nodaemon(self):
- opts = self.parse('--nodaemon')
- exp = dict(nodaemon=True)
- self.assertOptions(opts, exp)
-
-
-class TestReconfigOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'reconfig'
- optionsClass = runner.ReconfigOptions
-
-
-class TestDebugClientOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.DebugClientOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.DebugClientOptions()
- self.assertIn('buildbot debugclient', opts.getSynopsis())
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_args_missing_passwd(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('-m', 'mm'))
-
- def test_options_long(self):
- opts = self.parse('--master', 'mm:9989', '--passwd', 'pp')
- exp = dict(master='mm:9989', passwd='pp')
- self.assertOptions(opts, exp)
-
- def test_positional_master_passwd(self):
- opts = self.parse('foo:9989', 'pass')
- exp = dict(master='foo:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_positional_master(self):
- opts = self.parse('-p', 'pass', 'foo:9989')
- exp = dict(master='foo:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_args_master_passwd(self):
- opts = self.parse('foo:9989', 'pass')
- exp = dict(master='foo:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_missing_both(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse())
-
- def test_missing_passwd(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('master'))
-
- def test_missing_master(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('-p', 'pass'))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError, self.parse,
- "-m", "foo", "-p", "pass")
-
- def test_options_extra_positional(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('mm', 'pp', '??'))
-
- def test_options_master(self):
- self.options_file['master'] = 'opt:9989'
- opts = self.parse('-p', 'pass')
- exp = dict(master='opt:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_options_debugMaster(self):
- self.options_file['master'] = 'not seen'
- self.options_file['debugMaster'] = 'opt:9989'
- opts = self.parse('-p', 'pass')
- exp = dict(master='opt:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
-
-class TestBaseStatusClientOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.BaseStatusClientOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_defaults(self):
- opts = self.parse('--master', 'm:20')
- exp = dict(master='m:20', username='statusClient', passwd='clientpw')
- self.assertOptions(opts, exp)
-
- def test_short(self):
- opts = self.parse('-m', 'm:20', '-u', 'u', '-p', 'p')
- exp = dict(master='m:20', username='u', passwd='p')
- self.assertOptions(opts, exp)
-
- def test_long(self):
- opts = self.parse('--master', 'm:20',
- '--username', 'u', '--passwd', 'p')
- exp = dict(master='m:20', username='u', passwd='p')
- self.assertOptions(opts, exp)
-
- def test_positional_master(self):
- opts = self.parse('--username', 'u', '--passwd', 'p', 'm:20')
- exp = dict(master='m:20', username='u', passwd='p')
- self.assertOptions(opts, exp)
-
- def test_positional_extra(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--username', 'u', '--passwd', 'p', 'm', '2'))
-
- def test_missing_master(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--username', 'u', '--passwd', 'p'))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError, self.parse, "-m foo")
-
- def test_options_masterstatus(self):
- self.options_file['master'] = 'not_seen:2'
- self.options_file['masterstatus'] = 'opt:3'
- opts = self.parse('-p', 'pass', '-u', 'user')
- exp = dict(master='opt:3', username='user', passwd='pass')
- self.assertOptions(opts, exp)
-
-
-class TestStatusLogOptions(unittest.TestCase):
-
- def test_synopsis(self):
- opts = runner.StatusLogOptions()
- self.assertIn('buildbot statuslog', opts.getSynopsis())
-
-
-class TestStatusGuiOptions(unittest.TestCase):
-
- def test_synopsis(self):
- opts = runner.StatusGuiOptions()
- self.assertIn('buildbot statusgui', opts.getSynopsis())
-
-
-class TestTryOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.TryOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def defaults_and(self, **kwargs):
- defaults = dict(connect=None, host=None, jobdir=None, username=None,
- master=None, passwd=None, who=None, comment=None, diff=None,
- patchlevel=0, baserev=None, vc=None, branch=None,
- repository=None, topfile=None, topdir=None, wait=False,
- dryrun=False, quiet=False, builders=[], properties={},
- buildbotbin='buildbot')
- # dashes make python syntax hard..
- defaults['get-builder-names'] = False
- if 'get_builder_names' in kwargs:
- kwargs['get-builder-names'] = kwargs['get_builder_names']
- del kwargs['get_builder_names']
- assert set(kwargs.keys()) <= set(defaults.keys()), "invalid keys"
- opts = defaults.copy()
- opts.update(kwargs)
- return opts
-
- def test_synopsis(self):
- opts = runner.TryOptions()
- self.assertIn('buildbot try', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = self.defaults_and()
- self.assertOptions(opts, exp)
-
- def test_properties(self):
- opts = self.parse('--properties=a=b')
- exp = self.defaults_and(properties=dict(a='b'))
- self.assertOptions(opts, exp)
-
- def test_properties_multiple_opts(self):
- opts = self.parse('--properties=X=1', '--properties=Y=2')
- exp = self.defaults_and(properties=dict(X='1', Y='2'))
- self.assertOptions(opts, exp)
-
- def test_properties_equals(self):
- opts = self.parse('--properties=X=2+2=4')
- exp = self.defaults_and(properties=dict(X='2+2=4'))
- self.assertOptions(opts, exp)
-
- def test_properties_commas(self):
- opts = self.parse('--properties=a=b,c=d')
- exp = self.defaults_and(properties=dict(a='b', c='d'))
- self.assertOptions(opts, exp)
-
- def test_property(self):
- opts = self.parse('--property=a=b')
- exp = self.defaults_and(properties=dict(a='b'))
- self.assertOptions(opts, exp)
-
- def test_property_multiple_opts(self):
- opts = self.parse('--property=X=1', '--property=Y=2')
- exp = self.defaults_and(properties=dict(X='1', Y='2'))
- self.assertOptions(opts, exp)
-
- def test_property_equals(self):
- opts = self.parse('--property=X=2+2=4')
- exp = self.defaults_and(properties=dict(X='2+2=4'))
- self.assertOptions(opts, exp)
-
- def test_property_commas(self):
- opts = self.parse('--property=a=b,c=d')
- exp = self.defaults_and(properties=dict(a='b,c=d'))
- self.assertOptions(opts, exp)
-
- def test_property_and_properties(self):
- opts = self.parse('--property=X=1', '--properties=Y=2')
- exp = self.defaults_and(properties=dict(X='1', Y='2'))
- self.assertOptions(opts, exp)
-
- def test_properties_builders_multiple(self):
- opts = self.parse('--builder=aa', '--builder=bb')
- exp = self.defaults_and(builders=['aa', 'bb'])
- self.assertOptions(opts, exp)
-
- def test_options_short(self):
- opts = self.parse(
- *'-n -q -c pb -u me -m mr:7 -w you -C comm -p 2 -b bb'.split())
- exp = self.defaults_and(dryrun=True, quiet=True, connect='pb',
- username='me', master='mr:7', who='you', comment='comm',
- patchlevel=2, builders=['bb'])
- self.assertOptions(opts, exp)
-
- def test_options_long(self):
- opts = self.parse(
- *"""--wait --dryrun --get-builder-names --quiet --connect=pb
- --host=h --jobdir=j --username=u --master=m:1234 --passwd=p
- --who=w --comment=comm --diff=d --patchlevel=7 --baserev=br
- --vc=cvs --branch=br --repository=rep --builder=bl
- --properties=a=b --topfile=Makefile --topdir=.
- --buildbotbin=.virtualenvs/buildbot/bin/buildbot""".split())
- exp = self.defaults_and(wait=True, dryrun=True, get_builder_names=True,
- quiet=True, connect='pb', host='h', jobdir='j', username='u',
- master='m:1234', passwd='p', who='w', comment='comm', diff='d',
- patchlevel=7, baserev='br', vc='cvs', branch='br',
- repository='rep', builders=['bl'], properties=dict(a='b'),
- topfile='Makefile', topdir='.',
- buildbotbin='.virtualenvs/buildbot/bin/buildbot')
- self.assertOptions(opts, exp)
-
- def test_patchlevel_inval(self):
- self.assertRaises(ValueError, lambda:
- self.parse('-p', 'a'))
-
- def test_config_builders(self):
- self.options_file['try_builders'] = ['a', 'b']
- opts = self.parse()
- self.assertOptions(opts, dict(builders=['a', 'b']))
-
- def test_config_builders_override(self):
- self.options_file['try_builders'] = ['a', 'b']
- opts = self.parse('-b', 'd') # overrides a, b
- self.assertOptions(opts, dict(builders=['d']))
-
- def test_config_old_names(self):
- self.options_file['try_masterstatus'] = 'ms'
- self.options_file['try_dir'] = 'td'
- self.options_file['try_password'] = 'pw'
- opts = self.parse()
- self.assertOptions(opts, dict(master='ms', jobdir='td', passwd='pw'))
-
- def test_config_masterstatus(self):
- self.options_file['masterstatus'] = 'ms'
- opts = self.parse()
- self.assertOptions(opts, dict(master='ms'))
-
- def test_config_masterstatus_override(self):
- self.options_file['masterstatus'] = 'ms'
- opts = self.parse('-m', 'mm')
- self.assertOptions(opts, dict(master='mm'))
-
- def test_config_options(self):
- self.options_file.update(dict(try_connect='pb', try_vc='cvs',
- try_branch='br', try_repository='rep', try_topdir='.',
- try_topfile='Makefile', try_host='h', try_username='u',
- try_jobdir='j', try_password='p', try_master='m:8', try_who='w',
- try_comment='comm', try_quiet='y', try_wait='y',
- try_buildbotbin='.virtualenvs/buildbot/bin/buildbot'))
- opts = self.parse()
- exp = self.defaults_and(wait=True, quiet=True, connect='pb', host='h',
- jobdir='j', username='u', master='m:8', passwd='p', who='w',
- comment='comm', vc='cvs', branch='br', repository='rep',
- topfile='Makefile', topdir='.',
- buildbotbin='.virtualenvs/buildbot/bin/buildbot')
- self.assertOptions(opts, exp)
-
- def test_pb_withNoMaster(self):
- """
- When 'builbot try' is asked to connect via pb, but no master is
- specified, a usage error is raised.
- """
- self.assertRaises(usage.UsageError, self.parse, '--connect=pb')
-
- def test_pb_withInvalidMaster(self):
- """
- When 'buildbot try' is asked to conncect via pb, but an invalid
- master is specified, a usage error is raised.
- """
- self.assertRaises(usage.UsageError, self.parse,
- '--connect=pb', '--master=foo')
-
-class TestSendChangeOptions(OptionsMixin, unittest.TestCase):
-
- master_and_who = ['-m', 'm:1', '-W', 'w']
-
- def setUp(self):
- self.setUpOptions()
- self.getpass_response = 'typed-password'
- self.patch(getpass, 'getpass', lambda prompt : self.getpass_response)
-
- def parse(self, *args):
- self.opts = runner.SendChangeOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.SendChangeOptions()
- self.assertIn('buildbot sendchange', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse('-m', 'm:1', '-W', 'me')
- exp = dict(master='m:1', auth=('change', 'changepw'), who='me',
- vc=None, repository='', project='', branch=None, category=None,
- revision=None, revision_file=None, property=None,
- comments='', logfile=None, when=None, revlink='',
- encoding='utf8', files=())
- self.assertOptions(opts, exp)
-
- def test_files(self):
- opts = self.parse(*self.master_and_who + ['a', 'b', 'c'])
- self.assertEqual(opts['files'], ('a', 'b', 'c'))
-
- def test_properties(self):
- opts = self.parse('--property', 'x:y', '--property', 'a:b',
- *self.master_and_who)
- self.assertEqual(opts['properties'], dict(x="y", a="b"))
-
- def test_properties_with_colon(self):
- opts = self.parse('--property', 'x:http://foo', *self.master_and_who)
- self.assertEquals(opts['properties'], dict(x='http://foo'))
-
- def test_config_file(self):
- self.options_file['master'] = 'MMM:123'
- self.options_file['who'] = 'WWW'
- self.options_file['branch'] = 'BBB'
- self.options_file['category'] = 'CCC'
- self.options_file['vc'] = 'svn'
- opts = self.parse()
- exp = dict(master='MMM:123', who='WWW',
- branch='BBB', category='CCC', vc='svn')
- self.assertOptions(opts, exp)
-
- def test_short_args(self):
- opts = self.parse(*('-m m:1 -a a:b -W W -R r -P p -b b -s git ' +
- '-C c -r r -p pn:pv -c c -F f -w 123 -l l -e e').split())
- exp = dict(master='m:1', auth=('a','b'), who='W', repository='r',
- project='p', branch='b', category='c', revision='r', vc='git',
- properties=dict(pn='pv'), comments='c', logfile='f',
- when=123.0, revlink='l', encoding='e')
- self.assertOptions(opts, exp)
-
- def test_long_args(self):
- opts = self.parse(*('--master m:1 --auth a:b --who w --repository r ' +
- '--project p --branch b --category c --revision r --vc git ' +
- '--property pn:pv --comments c --logfile f ' +
- '--when 123 --revlink l --encoding e').split())
- exp = dict(master='m:1', auth=('a', 'b'), who='w', repository='r',
- project='p', branch='b', category='c', revision='r', vc='git',
- properties=dict(pn='pv'), comments='c', logfile='f',
- when=123.0, revlink='l', encoding='e')
- self.assertOptions(opts, exp)
-
- def test_revision_file(self):
- with open('revfile', 'wt') as f:
- f.write('my-rev')
- self.addCleanup(lambda : os.unlink('revfile'))
- opts = self.parse('--revision_file', 'revfile', *self.master_and_who)
- self.assertOptions(opts, dict(revision='my-rev'))
-
- def test_invalid_when(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--when=foo', *self.master_and_who))
-
- def test_comments_overrides_logfile(self):
- opts = self.parse('--logfile', 'logs', '--comments', 'foo',
- *self.master_and_who)
- self.assertOptions(opts, dict(comments='foo'))
-
- def test_logfile(self):
- with open('comments', 'wt') as f:
- f.write('hi')
- self.addCleanup(lambda : os.unlink('comments'))
- opts = self.parse('--logfile', 'comments', *self.master_and_who)
- self.assertOptions(opts, dict(comments='hi'))
-
- def test_logfile_stdin(self):
- stdin = mock.Mock()
- stdin.read = lambda : 'hi'
- self.patch(sys, 'stdin', stdin)
- opts = self.parse('--logfile', '-', *self.master_and_who)
- self.assertOptions(opts, dict(comments='hi'))
-
- def test_auth_getpass(self):
- opts = self.parse('--auth=dustin', *self.master_and_who)
- self.assertOptions(opts, dict(auth=('dustin', 'typed-password')))
-
- def test_invalid_vcs(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--vc=foo', *self.master_and_who))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- "--who=test", "-m foo")
-
-
-class TestTryServerOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.TryServerOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.TryServerOptions()
- self.assertIn('buildbot tryserver', opts.getSynopsis())
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_with_jobdir(self):
- opts = self.parse('--jobdir', 'xyz')
- exp = dict(jobdir='xyz')
- self.assertOptions(opts, exp)
-
-
-class TestCheckConfigOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.CheckConfigOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.CheckConfigOptions()
- self.assertIn('buildbot checkconfig', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = dict(quiet=False, configFile='master.cfg')
- self.assertOptions(opts, exp)
-
- def test_configfile(self):
- opts = self.parse('foo.cfg')
- exp = dict(quiet=False, configFile='foo.cfg')
- self.assertOptions(opts, exp)
-
- def test_quiet(self):
- opts = self.parse('-q')
- exp = dict(quiet=True, configFile='master.cfg')
- self.assertOptions(opts, exp)
-
-
-class TestUserOptions(OptionsMixin, unittest.TestCase):
-
- # mandatory arguments
- extra_args = [ '--master', 'a:1',
- '--username', 'u', '--passwd', 'p' ]
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.UserOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_synopsis(self):
- opts = runner.UserOptions()
- self.assertIn('buildbot user', opts.getSynopsis())
-
- def test_master(self):
- opts = self.parse("--master", "abcd:1234",
- '--op=get', '--ids=x', '--username=u', '--passwd=p')
- self.assertOptions(opts, dict(master="abcd:1234"))
-
- def test_ids(self):
- opts = self.parse("--ids", "id1,id2,id3",
- '--op', 'get', *self.extra_args)
- self.assertEqual(opts['ids'], ['id1', 'id2', 'id3'])
-
- def test_info(self):
- opts = self.parse("--info", "git=Tyler Durden <tyler@mayhem.net>",
- '--op', 'add', *self.extra_args)
- self.assertEqual(opts['info'],
- [dict(git='Tyler Durden <tyler@mayhem.net>')])
-
- def test_info_only_id(self):
- opts = self.parse("--info", "tdurden",
- '--op', 'update', *self.extra_args)
- self.assertEqual(opts['info'], [dict(identifier='tdurden')])
-
- def test_info_with_id(self):
- opts = self.parse("--info", "tdurden:svn=marla",
- '--op', 'update', *self.extra_args)
- self.assertEqual(opts['info'], [dict(identifier='tdurden', svn='marla')])
-
- def test_info_multiple(self):
- opts = self.parse("--info", "git=Tyler Durden <tyler@mayhem.net>",
- "--info", "git=Narrator <narrator@mayhem.net>",
- '--op', 'add', *self.extra_args)
- self.assertEqual(opts['info'],
- [dict(git='Tyler Durden <tyler@mayhem.net>'),
- dict(git='Narrator <narrator@mayhem.net>')])
-
- def test_config_user_params(self):
- self.options_file['user_master'] = 'mm:99'
- self.options_file['user_username'] = 'un'
- self.options_file['user_passwd'] = 'pw'
- opts = self.parse('--op', 'get', '--ids', 'x')
- self.assertOptions(opts, dict(master='mm:99', username='un', passwd='pw'))
-
- def test_config_master(self):
- self.options_file['master'] = 'mm:99'
- opts = self.parse('--op', 'get', '--ids', 'x',
- '--username=u', '--passwd=p')
- self.assertOptions(opts, dict(master='mm:99'))
-
- def test_config_master_override(self):
- self.options_file['master'] = 'not seen'
- self.options_file['user_master'] = 'mm:99'
- opts = self.parse('--op', 'get', '--ids', 'x',
- '--username=u', '--passwd=p')
- self.assertOptions(opts, dict(master='mm:99'))
-
- def test_invalid_info(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse("--info", "foo=bar",
- '--op', 'add', *self.extra_args))
-
- def test_no_master(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('-op=foo'))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError, self.parse,'-m', 'foo')
-
- def test_no_operation(self):
- self.assertRaises(usage.UsageError, self.parse, '-m', 'a:1')
-
- def test_bad_operation(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '-m', 'a:1', '--op=mayhem')
-
- def test_no_username(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '-m', 'a:1', '--op=add')
-
- def test_no_password(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '-m', 'a:1', '-u', 'tdurden')
-
- def test_invalid_bb_username(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '--bb_username=tdurden',
- *self.extra_args)
-
- def test_invalid_bb_password(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '--bb_password=marla',
- *self.extra_args)
-
- def test_update_no_bb_username(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=update', '--bb_password=marla',
- *self.extra_args)
-
- def test_update_no_bb_password(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=update', '--bb_username=tdurden',
- *self.extra_args)
-
- def test_no_ids_info(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', *self.extra_args)
-
- def test_ids_with_add(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '--ids=id1', *self.extra_args)
-
- def test_ids_with_update(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=update', '--ids=id1', *self.extra_args)
-
- def test_no_ids_found_update(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- "--op=update", "--info=svn=x", *self.extra_args)
-
- def test_id_with_add(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- "--op=add", "--info=id:x", *self.extra_args)
-
- def test_info_with_remove(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=remove', '--info=x=v', *self.extra_args)
-
-
- def test_info_with_get(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=get', '--info=x=v', *self.extra_args)
-
-
-class TestOptions(OptionsMixin, misc.StdoutAssertionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
- self.setUpStdoutAssertions()
-
- def parse(self, *args):
- self.opts = runner.Options()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_version(self):
- try:
- self.parse('--version')
- except SystemExit, e:
- self.assertEqual(e.args[0], 0)
- self.assertInStdout('Buildbot version:')
-
- def test_verbose(self):
- self.patch(log, 'startLogging', mock.Mock())
- self.assertRaises(usage.UsageError, self.parse, "--verbose")
- log.startLogging.assert_called_once_with(sys.stderr)
-
-
-class TestRun(unittest.TestCase):
-
- class MySubCommand(usage.Options):
- subcommandFunction = 'buildbot.test.unit.test_scripts_runner.subcommandFunction'
- optFlags = [
- [ 'loud', 'l', 'be noisy' ]
- ]
- def postOptions(self):
- if self['loud']:
- raise usage.UsageError('THIS IS ME BEING LOUD')
-
- def setUp(self):
- # patch our subcommand in
- self.patch(runner.Options, 'subCommands',
- [ [ 'my', None, self.MySubCommand, 'my, my' ] ])
-
- # and patch in the callback for it
- global subcommandFunction
- subcommandFunction = mock.Mock(name='subcommandFunction',
- return_value=3)
-
- def test_run_good(self):
- self.patch(sys, 'argv', [ 'buildbot', 'my' ])
- try:
- runner.run()
- except SystemExit, e:
- self.assertEqual(e.args[0], 3)
- else:
- self.fail("didn't exit")
-
- def test_run_bad(self):
- self.patch(sys, 'argv', [ 'buildbot', 'my', '-l' ])
- stdout = cStringIO.StringIO()
- self.patch(sys, 'stdout', stdout)
- try:
- runner.run()
- except SystemExit, e:
- self.assertEqual(e.args[0], 1)
- else:
- self.fail("didn't exit")
- self.assertIn('THIS IS ME', stdout.getvalue())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py
deleted file mode 100644
index daeaab88..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import reactor, defer
-from buildbot.scripts import sendchange
-from buildbot.clients import sendchange as sendchange_client
-from buildbot.test.util import misc
-
-class TestSendChange(misc.StdoutAssertionsMixin, unittest.TestCase):
-
- class FakeSender:
- def __init__(self, testcase, master, auth, encoding=None):
- self.master = master
- self.auth = auth
- self.encoding = encoding
- self.testcase = testcase
-
- def send(self, branch, revision, comments, files, **kwargs):
- kwargs['branch'] = branch
- kwargs['revision'] = revision
- kwargs['comments'] = comments
- kwargs['files'] = files
- self.send_kwargs = kwargs
- d = defer.Deferred()
- if self.testcase.fail:
- reactor.callLater(0, d.errback, RuntimeError("oh noes"))
- else:
- reactor.callLater(0, d.callback, None)
- return d
-
- def setUp(self):
- self.fail = False # set to true to get Sender.send to fail
- def Sender_constr(*args, **kwargs):
- self.sender = self.FakeSender(self, *args, **kwargs)
- return self.sender
- self.patch(sendchange_client, 'Sender', Sender_constr)
-
- # undo the effects of @in_reactor
- self.patch(sendchange, 'sendchange', sendchange.sendchange._orig)
-
- self.setUpStdoutAssertions()
-
- def test_sendchange_config(self):
- d = sendchange.sendchange(dict(encoding='utf16', who='me',
- auth=['a', 'b'], master='m', branch='br', category='cat',
- revision='rr', properties={'a':'b'}, repository='rep',
- project='prj', vc='git', revlink='rl', when=1234.0,
- comments='comm', files=('a', 'b'), codebase='cb'))
- def check(rc):
- self.assertEqual((self.sender.master, self.sender.auth,
- self.sender.encoding, self.sender.send_kwargs,
- self.getStdout(), rc),
- ('m', ['a','b'], 'utf16', {
- 'branch': 'br',
- 'category': 'cat',
- 'codebase': 'cb',
- 'comments': 'comm',
- 'files': ('a', 'b'),
- 'project': 'prj',
- 'properties': {'a':'b'},
- 'repository': 'rep',
- 'revision': 'rr',
- 'revlink': 'rl',
- 'when': 1234.0,
- 'who': 'me',
- 'vc': 'git'},
- 'change sent successfully', 0))
- d.addCallback(check)
- return d
-
- def test_sendchange_config_no_codebase(self):
- d = sendchange.sendchange(dict(encoding='utf16', who='me',
- auth=['a', 'b'], master='m', branch='br', category='cat',
- revision='rr', properties={'a':'b'}, repository='rep',
- project='prj', vc='git', revlink='rl', when=1234.0,
- comments='comm', files=('a', 'b')))
- def check(rc):
- self.assertEqual((self.sender.master, self.sender.auth,
- self.sender.encoding, self.sender.send_kwargs,
- self.getStdout(), rc),
- ('m', ['a','b'], 'utf16', {
- 'branch': 'br',
- 'category': 'cat',
- 'codebase': None,
- 'comments': 'comm',
- 'files': ('a', 'b'),
- 'project': 'prj',
- 'properties': {'a':'b'},
- 'repository': 'rep',
- 'revision': 'rr',
- 'revlink': 'rl',
- 'when': 1234.0,
- 'who': 'me',
- 'vc': 'git'},
- 'change sent successfully', 0))
- d.addCallback(check)
- return d
-
- def test_sendchange_fail(self):
- self.fail = True
- d = sendchange.sendchange({})
- def check(rc):
- self.assertEqual((self.getStdout().split('\n')[0], rc),
- ('change not sent:', 1))
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py
deleted file mode 100644
index ddf04d9a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os, sys
-import twisted
-from twisted.python import versions
-from twisted.internet.utils import getProcessOutputAndValue
-from twisted.trial import unittest
-from buildbot.scripts import start
-from buildbot.test.util import dirs, misc, compat
-
-def mkconfig(**kwargs):
- config = {
- 'quiet': False,
- 'basedir': os.path.abspath('basedir'),
- 'nodaemon': False,
- }
- config.update(kwargs)
- return config
-
-fake_master_tac = """\
-from twisted.application import service
-from twisted.python import log
-from twisted.internet import reactor
-application = service.Application('highscore')
-class App(service.Service):
- def startService(self):
- service.Service.startService(self)
- log.msg("BuildMaster is running") # heh heh heh
- reactor.callLater(0, reactor.stop)
-app = App()
-app.setServiceParent(application)
-# isBuildmasterDir wants to see this -> Application('buildmaster')
-"""
-
-class TestStart(misc.StdoutAssertionsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('basedir')
- with open(os.path.join('basedir', 'buildbot.tac'), 'wt') as f:
- f.write(fake_master_tac)
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- # tests
-
- def test_start_not_basedir(self):
- self.assertEqual(start.start(mkconfig(basedir='doesntexist')), 1)
- self.assertInStdout('invalid buildmaster directory')
-
- def runStart(self, **config):
- args=[
- '-c',
- 'from buildbot.scripts.start import start; start(%r)' % (mkconfig(**config),),
- ]
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
- return getProcessOutputAndValue(sys.executable, args=args, env=env)
-
- def test_start_no_daemon(self):
- d = self.runStart(nodaemon=True)
- @d.addCallback
- def cb(res):
- self.assertEquals(res, ('', '', 0))
- print res
- return d
-
- def test_start_quiet(self):
- d = self.runStart(quiet=True)
- @d.addCallback
- def cb(res):
- self.assertEquals(res, ('', '', 0))
- print res
- return d
-
- @compat.skipUnlessPlatformIs('posix')
- def test_start(self):
- d = self.runStart()
- @d.addCallback
- def cb((out, err, rc)):
- self.assertEqual((rc, err), (0, ''))
- self.assertSubstring('BuildMaster is running', out)
- return d
-
- if twisted.version <= versions.Version('twisted', 9, 0, 0):
- test_start.skip = test_start_quiet.skip = "Skipping due to suprious PotentialZombieWarning."
-
- # the remainder of this script does obscene things:
- # - forks
- # - shells out to tail
- # - starts and stops the reactor
- # so testing it will be *far* more pain than is worthwhile
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py
deleted file mode 100644
index fd067afd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from buildbot.clients import text
-from buildbot.scripts import statuslog
-
-class TestStatusLog(unittest.TestCase):
-
- def test_statuslog(self):
- TextClient = mock.Mock()
- self.patch(text, 'TextClient', TextClient)
- inst = TextClient.return_value = mock.Mock(name='TextClient-instance')
-
- rc = statuslog.statuslog(dict(master='mm', passwd='pp', username='uu'))
-
- TextClient.assert_called_with('mm', passwd='pp', username='uu')
- inst.run.assert_called_with()
- self.assertEqual(rc, 0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py
deleted file mode 100644
index 07ac05b7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import time
-import signal
-from twisted.trial import unittest
-from buildbot.scripts import stop
-from buildbot.test.util import dirs, misc, compat
-
-def mkconfig(**kwargs):
- config = dict(quiet=False, clean=False, basedir=os.path.abspath('basedir'))
- config.update(kwargs)
- return config
-
-class TestStop(misc.StdoutAssertionsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('basedir')
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- # tests
-
- def do_test_stop(self, config, kill_sequence, is_running=True, **kwargs):
- with open(os.path.join('basedir', 'buildbot.tac'), 'wt') as f:
- f.write("Application('buildmaster')")
- if is_running:
- with open("basedir/twistd.pid", 'wt') as f:
- f.write('1234')
- def sleep(t):
- what, exp_t = kill_sequence.pop(0)
- self.assertEqual((what, exp_t), ('sleep', t))
- self.patch(time, 'sleep', sleep)
- def kill(pid, signal):
- exp_sig, result = kill_sequence.pop(0)
- self.assertEqual((pid,signal), (1234,exp_sig))
- if isinstance(result, Exception):
- raise result
- else:
- return result
- self.patch(os, 'kill', kill)
- rv = stop.stop(config, **kwargs)
- self.assertEqual(kill_sequence, [])
- return rv
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_not_running(self):
- rv = self.do_test_stop(mkconfig(), [], is_running=False)
- self.assertInStdout('not running')
- self.assertEqual(rv, 0)
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_dead_but_pidfile_remains(self):
- rv = self.do_test_stop(mkconfig(),
- [ (signal.SIGTERM, OSError(3, 'No such process')) ])
- self.assertEqual(rv, 0)
- self.assertFalse(os.path.exists(os.path.join('basedir', 'twistd.pid')))
- self.assertInStdout('not running')
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_dead_but_pidfile_remains_quiet(self):
- rv = self.do_test_stop(mkconfig(quiet=True),
- [ (signal.SIGTERM, OSError(3, 'No such process')) ],)
- self.assertEqual(rv, 0)
- self.assertFalse(os.path.exists(os.path.join('basedir', 'twistd.pid')))
- self.assertWasQuiet()
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_dead_but_pidfile_remains_wait(self):
- rv = self.do_test_stop(mkconfig(),
- [ (signal.SIGTERM, OSError(3, 'No such process')) ],
- wait=True)
- self.assertEqual(rv, 0)
- self.assertFalse(os.path.exists(os.path.join('basedir', 'twistd.pid')))
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_slow_death_wait(self):
- rv = self.do_test_stop(mkconfig(), [
- (signal.SIGTERM, None),
- ('sleep', 0.1),
- (0, None), # polling..
- ('sleep', 1),
- (0, None),
- ('sleep', 1),
- (0, None),
- ('sleep', 1),
- (0, OSError(3, 'No such process')),
- ],
- wait=True)
- self.assertInStdout('is dead')
- self.assertEqual(rv, 0)
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_slow_death_wait_timeout(self):
- rv = self.do_test_stop(mkconfig(), [
- (signal.SIGTERM, None),
- ('sleep', 0.1), ] +
- [ (0, None),
- ('sleep', 1), ] * 10,
- wait=True)
- self.assertInStdout('never saw process')
- self.assertEqual(rv, 1)
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_clean(self):
- rv = self.do_test_stop(mkconfig(clean=True), [
- (signal.SIGUSR1, None), ], wait=False)
- self.assertInStdout('sent SIGUSR1 to process')
- self.assertEqual(rv, 0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py
deleted file mode 100644
index 88b32aba..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from buildbot.clients import tryclient
-from buildbot.scripts import trycmd
-
-class TestStatusLog(unittest.TestCase):
-
- def test_trycmd(self):
- Try = mock.Mock()
- self.patch(tryclient, 'Try', Try)
- inst = Try.return_value = mock.Mock(name='Try-instance')
-
- rc = trycmd.trycmd(dict(cfg=1))
-
- Try.assert_called_with(dict(cfg=1))
- inst.run.assert_called_with()
- self.assertEqual(rc, 0)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py
deleted file mode 100644
index 42ff72da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import sys
-from cStringIO import StringIO
-from twisted.trial import unittest
-from buildbot.scripts import tryserver
-from buildbot.test.util import dirs
-
-class TestStatusLog(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.newdir = os.path.join('jobdir', 'new')
- self.tmpdir = os.path.join('jobdir', 'tmp')
- self.setUpDirs("jobdir", self.newdir, self.tmpdir)
-
- def test_trycmd(self):
- config = dict(jobdir='jobdir')
- inputfile = StringIO('this is my try job')
- self.patch(sys, 'stdin', inputfile)
-
- rc = tryserver.tryserver(config)
-
- self.assertEqual(rc, 0)
-
- newfiles = os.listdir(self.newdir)
- tmpfiles = os.listdir(self.tmpdir)
- self.assertEqual((len(newfiles), len(tmpfiles)),
- (1, 0))
- with open(os.path.join(self.newdir, newfiles[0]), 'rt') as f:
- self.assertEqual(f.read(), 'this is my try job')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py
deleted file mode 100644
index 1023d005..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.scripts import upgrade_master
-from buildbot import config as config_module
-from buildbot.db import connector, model
-from buildbot.test.util import dirs, misc, compat
-
-def mkconfig(**kwargs):
- config = dict(quiet=False, replace=False, basedir='test')
- config.update(kwargs)
- return config
-
-class TestUpgradeMaster(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- # createMaster is decorated with @in_reactor, so strip that decoration
- # since the master is already running
- self.patch(upgrade_master, 'upgradeMaster',
- upgrade_master.upgradeMaster._orig)
- self.setUpDirs('test')
- self.setUpStdoutAssertions()
-
- def patchFunctions(self, basedirOk=True, configOk=True):
- self.calls = []
-
- def checkBasedir(config):
- self.calls.append('checkBasedir')
- return basedirOk
- self.patch(upgrade_master, 'checkBasedir', checkBasedir)
-
- def loadConfig(config, configFileName='master.cfg'):
- self.calls.append('loadConfig')
- return config_module.MasterConfig() if configOk else False
- self.patch(upgrade_master, 'loadConfig', loadConfig)
-
- def upgradeFiles(config):
- self.calls.append('upgradeFiles')
- self.patch(upgrade_master, 'upgradeFiles', upgradeFiles)
-
- def upgradeDatabase(config, master_cfg):
- self.assertIsInstance(master_cfg, config_module.MasterConfig)
- self.calls.append('upgradeDatabase')
- self.patch(upgrade_master, 'upgradeDatabase', upgradeDatabase)
-
- # tests
-
- def test_upgradeMaster_success(self):
- self.patchFunctions()
- d = upgrade_master.upgradeMaster(mkconfig(), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 0)
- self.assertInStdout('upgrade complete')
- return d
-
- def test_upgradeMaster_quiet(self):
- self.patchFunctions()
- d = upgrade_master.upgradeMaster(mkconfig(quiet=True), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 0)
- self.assertWasQuiet()
- return d
-
- def test_upgradeMaster_bad_basedir(self):
- self.patchFunctions(basedirOk=False)
- d = upgrade_master.upgradeMaster(mkconfig(), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 1)
- return d
-
- def test_upgradeMaster_bad_config(self):
- self.patchFunctions(configOk=False)
- d = upgrade_master.upgradeMaster(mkconfig(), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 1)
- return d
-
-class TestUpgradeMasterFunctions(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test')
- self.basedir = os.path.abspath(os.path.join('test', 'basedir'))
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- def activeBasedir(self):
- with open(os.path.join('test', 'buildbot.tac'), 'wt') as f:
- f.write("Application('buildmaster')")
-
- def writeFile(self, path, contents):
- with open(path, 'wt') as f:
- f.write(contents)
-
- def readFile(self, path):
- with open(path, 'rt') as f:
- return f.read()
-
- # tests
-
- def test_checkBasedir(self):
- self.activeBasedir()
- rv = upgrade_master.checkBasedir(mkconfig())
- self.assertTrue(rv)
- self.assertInStdout('checking basedir')
-
- def test_checkBasedir_quiet(self):
- self.activeBasedir()
- rv = upgrade_master.checkBasedir(mkconfig(quiet=True))
- self.assertTrue(rv)
- self.assertWasQuiet()
-
- def test_checkBasedir_no_dir(self):
- rv = upgrade_master.checkBasedir(mkconfig(basedir='doesntexist'))
- self.assertFalse(rv)
- self.assertInStdout('invalid buildmaster directory')
-
- @compat.skipUnlessPlatformIs('posix')
- def test_checkBasedir_active_pidfile(self):
- self.activeBasedir()
- open(os.path.join('test', 'twistd.pid'), 'w').close()
- rv = upgrade_master.checkBasedir(mkconfig())
- self.assertFalse(rv)
- self.assertInStdout('still running')
-
- def test_loadConfig(self):
- @classmethod
- def loadConfig(cls, basedir, filename):
- return config_module.MasterConfig()
- self.patch(config_module.MasterConfig, 'loadConfig', loadConfig)
- cfg = upgrade_master.loadConfig(mkconfig())
- self.assertIsInstance(cfg, config_module.MasterConfig)
- self.assertInStdout('checking')
-
- def test_loadConfig_ConfigErrors(self):
- @classmethod
- def loadConfig(cls, basedir, filename):
- raise config_module.ConfigErrors(['oh noes'])
- self.patch(config_module.MasterConfig, 'loadConfig', loadConfig)
- cfg = upgrade_master.loadConfig(mkconfig())
- self.assertIdentical(cfg, None)
- self.assertInStdout('oh noes')
-
- def test_loadConfig_exception(self):
- @classmethod
- def loadConfig(cls, basedir, filename):
- raise RuntimeError()
- self.patch(config_module.MasterConfig, 'loadConfig', loadConfig)
- cfg = upgrade_master.loadConfig(mkconfig())
- self.assertIdentical(cfg, None)
- self.assertInStdout('RuntimeError')
-
- def test_installFile(self):
- self.writeFile('test/srcfile', 'source data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile')
- self.assertEqual(self.readFile('test/destfile'), 'source data')
- self.assertInStdout('creating test/destfile')
-
- def test_installFile_existing_differing(self):
- self.writeFile('test/srcfile', 'source data')
- self.writeFile('test/destfile', 'dest data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile')
- self.assertEqual(self.readFile('test/destfile'), 'dest data')
- self.assertEqual(self.readFile('test/destfile.new'), 'source data')
- self.assertInStdout('writing new contents to')
-
- def test_installFile_existing_differing_overwrite(self):
- self.writeFile('test/srcfile', 'source data')
- self.writeFile('test/destfile', 'dest data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile',
- overwrite=True)
- self.assertEqual(self.readFile('test/destfile'), 'source data')
- self.assertFalse(os.path.exists('test/destfile.new'))
- self.assertInStdout('overwriting')
-
- def test_installFile_existing_same(self):
- self.writeFile('test/srcfile', 'source data')
- self.writeFile('test/destfile', 'source data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile')
- self.assertEqual(self.readFile('test/destfile'), 'source data')
- self.assertFalse(os.path.exists('test/destfile.new'))
- self.assertWasQuiet()
-
- def test_installFile_quiet(self):
- self.writeFile('test/srcfile', 'source data')
- upgrade_master.installFile(mkconfig(quiet=True), 'test/destfile',
- 'test/srcfile')
- self.assertWasQuiet()
-
- def test_upgradeFiles(self):
- upgrade_master.upgradeFiles(mkconfig())
- for f in [
- 'test/public_html',
- 'test/public_html/bg_gradient.jpg',
- 'test/public_html/default.css',
- 'test/public_html/robots.txt',
- 'test/public_html/favicon.ico',
- 'test/templates',
- 'test/master.cfg.sample',
- ]:
- self.assertTrue(os.path.exists(f), "%s not found" % f)
- self.assertInStdout('upgrading basedir')
-
- def test_upgradeFiles_rename_index_html(self):
- os.mkdir('test/public_html')
- self.writeFile('test/public_html/index.html', 'INDEX')
- upgrade_master.upgradeFiles(mkconfig())
- self.assertFalse(os.path.exists("test/public_html/index.html"))
- self.assertEqual(self.readFile("test/templates/root.html"), 'INDEX')
- self.assertInStdout('Moving ')
-
- def test_upgradeFiles_index_html_collision(self):
- os.mkdir('test/public_html')
- self.writeFile('test/public_html/index.html', 'INDEX')
- os.mkdir('test/templates')
- self.writeFile('test/templates/root.html', 'ROOT')
- upgrade_master.upgradeFiles(mkconfig())
- self.assertTrue(os.path.exists("test/public_html/index.html"))
- self.assertEqual(self.readFile("test/templates/root.html"), 'ROOT')
- self.assertInStdout('Decide')
-
- @defer.inlineCallbacks
- def test_upgradeDatabase(self):
- setup = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(connector.DBConnector, 'setup', setup)
- upgrade = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(model.Model, 'upgrade', upgrade)
- yield upgrade_master.upgradeDatabase(
- mkconfig(basedir='test', quiet=True),
- config_module.MasterConfig())
- setup.asset_called_with(check_version=False, verbose=False)
- upgrade.assert_called()
- self.assertWasQuiet()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py
deleted file mode 100644
index 2291c50e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from buildbot.scripts import user
-from buildbot.clients import usersclient
-from buildbot.process.users import users
-
-class TestUsersClient(unittest.TestCase):
-
- class FakeUsersClient(object):
- def __init__(self, master, username="user", passwd="userpw", port=0):
- self.master = master
- self.port = port
- self.username = username
- self.passwd = passwd
- self.fail = False
-
- def send(self, op, bb_username, bb_password, ids, info):
- self.op = op
- self.bb_username = bb_username
- self.bb_password = bb_password
- self.ids = ids
- self.info = info
- d = defer.Deferred()
- if self.fail:
- reactor.callLater(0, d.errback, RuntimeError("oh noes"))
- else:
- reactor.callLater(0, d.callback, None)
- return d
-
- def setUp(self):
- def fake_UsersClient(*args):
- self.usersclient = self.FakeUsersClient(*args)
- return self.usersclient
- self.patch(usersclient, 'UsersClient', fake_UsersClient)
-
- # un-do the effects of @in_reactor
- self.patch(user, 'user', user.user._orig)
-
- def test_usersclient_send_ids(self):
- d = user.user(dict(master='a:9990', username="x",
- passwd="y", op='get', bb_username=None,
- bb_password=None, ids=['me', 'you'],
- info=None))
- def check(_):
- c = self.usersclient
- self.assertEqual((c.master, c.port, c.username, c.passwd, c.op,
- c.ids, c.info),
- ('a', 9990, "x", "y", 'get', ['me', 'you'], None))
- d.addCallback(check)
- return d
-
- def test_usersclient_send_update_info(self):
- def _fake_encrypt(passwd):
- assert passwd == 'day'
- return 'ENCRY'
- self.patch(users, 'encrypt', _fake_encrypt)
-
- d = user.user(dict(master='a:9990', username="x",
- passwd="y", op='update', bb_username='bud',
- bb_password='day', ids=None,
- info=[{'identifier':'x', 'svn':'x'}]))
- def check(_):
- c = self.usersclient
- self.assertEqual((c.master, c.port, c.username, c.passwd, c.op,
- c.bb_username, c.bb_password, c.ids, c.info),
- ('a', 9990, "x", "y", 'update', 'bud', 'ENCRY',
- None, [{'identifier':'x', 'svn':'x'}]))
- d.addCallback(check)
- return d
-
- def test_usersclient_send_add_info(self):
- d = user.user(dict(master='a:9990', username="x",
- passwd="y", op='add', bb_username=None,
- bb_password=None, ids=None,
- info=[{'git':'x <h@c>', 'irc':'aaa'}]))
- def check(_):
- c = self.usersclient
- self.assertEqual((c.master, c.port, c.username, c.passwd, c.op,
- c.bb_username, c.bb_password, c.ids, c.info),
- ('a', 9990, "x", "y", 'add', None, None, None,
- [{'identifier':'aaa',
- 'git': 'x <h@c>',
- 'irc': 'aaa'}]))
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py
deleted file mode 100644
index 3af7d505..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from buildbot.changes import changes
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot import sourcestamp
-
-class TestBuilderBuildCreation(unittest.TestCase):
-
- def test_fromSsdict_changes(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.Change(changeid=14, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.Change(changeid=15, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.Change(changeid=16, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.SourceStamp(id=234, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=14),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
- fakedb.SourceStampChange(sourcestampid=234, changeid=15),
- fakedb.SourceStampChange(sourcestampid=234, changeid=16),
- ])
- # use getSourceStamp to minimize the risk from changes to the format of
- # the ssdict
- d = master.db.sourcestamps.getSourceStamp(234)
- d.addCallback(lambda ssdict :
- sourcestamp.SourceStamp.fromSsdict(master, ssdict))
- def check(ss):
- self.assertEqual(ss.ssid, 234)
- self.assertEqual(ss.branch, 'trunk')
- self.assertEqual(ss.revision, '9284')
- self.assertEqual(ss.patch, None)
- self.assertEqual(ss.patch_info, None)
- self.assertEqual([ ch.number for ch in ss.changes],
- [13, 14, 15, 16])
- self.assertEqual(ss.project, 'world-domination')
- self.assertEqual(ss.repository, 'svn://...')
- self.assertEqual(ss.codebase, 'cb')
- d.addCallback(check)
- return d
-
- def test_fromSsdict_patch(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.Patch(id=99, subdir='/foo', patchlevel=3,
- patch_base64='LS0gKys=',
- patch_author='Professor Chaos',
- patch_comment='comment'),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb', project='world-domination',
- patchid=99),
- ])
- # use getSourceStamp to minimize the risk from changes to the format of
- # the ssdict
- d = master.db.sourcestamps.getSourceStamp(234)
- d.addCallback(lambda ssdict :
- sourcestamp.SourceStamp.fromSsdict(master, ssdict))
- def check(ss):
- self.assertEqual(ss.ssid, 234)
- self.assertEqual(ss.branch, 'trunk')
- self.assertEqual(ss.revision, '9284')
- self.assertEqual(ss.patch, (3, '-- ++', '/foo'))
- self.assertEqual(ss.patch_info, ('Professor Chaos', 'comment'))
- self.assertEqual(ss.changes, ())
- self.assertEqual(ss.project, 'world-domination')
- self.assertEqual(ss.repository, 'svn://...')
- self.assertEqual(ss.codebase, 'cb')
- d.addCallback(check)
- return d
-
- def test_fromSsdict_simple(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk', revision='9284',
- repository='svn://...', codebase = 'cb', project='world-domination'),
- ])
- # use getSourceStamp to minimize the risk from changes to the format of
- # the ssdict
- d = master.db.sourcestamps.getSourceStamp(234)
- d.addCallback(lambda ssdict :
- sourcestamp.SourceStamp.fromSsdict(master, ssdict))
- def check(ss):
- self.assertEqual(ss.ssid, 234)
- self.assertEqual(ss.branch, 'trunk')
- self.assertEqual(ss.revision, '9284')
- self.assertEqual(ss.patch, None)
- self.assertEqual(ss.patch_info, None)
- self.assertEqual(ss.changes, ())
- self.assertEqual(ss.project, 'world-domination')
- self.assertEqual(ss.repository, 'svn://...')
- self.assertEqual(ss.codebase, 'cb')
- d.addCallback(check)
- return d
-
- def test_getAbsoluteSourceStamp_from_relative(self):
- ss = sourcestamp.SourceStamp(branch='dev', revision=None,
- project='p', repository='r', codebase='cb')
- abs_ss = ss.getAbsoluteSourceStamp('abcdef')
- self.assertEqual(abs_ss.branch, 'dev')
- self.assertEqual(abs_ss.revision, 'abcdef')
- self.assertEqual(abs_ss.project, 'p')
- self.assertEqual(abs_ss.repository, 'r')
- self.assertEqual(abs_ss.codebase, 'cb')
-
- def test_getAbsoluteSourceStamp_from_absolute(self):
- ss = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb')
- abs_ss = ss.getAbsoluteSourceStamp('abcdef')
- self.assertEqual(abs_ss.branch, 'dev')
- # revision gets overridden
- self.assertEqual(abs_ss.revision, 'abcdef')
- self.assertEqual(abs_ss.project, 'p')
- self.assertEqual(abs_ss.repository, 'r')
- self.assertEqual(abs_ss.codebase, 'cb')
-
- def test_getAbsoluteSourceStamp_from_absolute_with_changes(self):
- c1 = mock.Mock()
- c1.branch = 'dev'
- c1.revision = 'xyz'
- c1.project = 'p'
- c1.repository = 'r'
- c1.codebase = 'cb'
- ss = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb', changes=[c1])
- abs_ss = ss.getAbsoluteSourceStamp('abcdef')
- self.assertEqual(abs_ss.branch, 'dev')
- # revision changes, even though changes say different - this is
- # useful for CVS, for example
- self.assertEqual(abs_ss.revision, 'abcdef')
- self.assertEqual(abs_ss.project, 'p')
- self.assertEqual(abs_ss.repository, 'r')
- self.assertEqual(abs_ss.codebase, 'cb')
-
- def test_canBeMergedWith_where_sourcestamp_do_not_both_have_changes(self):
- c1 = mock.Mock()
- c1.codebase = 'cb'
- ss1 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb', changes=[c1])
- ss2 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb', changes=[])
- self.assertFalse(ss1.canBeMergedWith(ss2))
-
- def test_canBeMergedWith_where_sourcestamp_have_different_codebases(self):
- ss1 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cbA', changes=[])
- ss2 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cbB', changes=[])
- self.assertFalse(ss1.canBeMergedWith(ss2))
-
- def test_canBeMergedWith_with_self_patched_sourcestamps(self):
- ss = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cbA', changes=[],
- patch=(1, ''))
- self.assertTrue(ss.canBeMergedWith(ss))
-
- def test_constructor_most_recent_change(self):
- chgs = [
- changes.Change('author', [], 'comments', branch='branch',
- revision='2'),
- changes.Change('author', [], 'comments', branch='branch',
- revision='3'),
- changes.Change('author', [], 'comments', branch='branch',
- revision='1'),
- ]
- for ch in chgs: # mock the DB changeid (aka build number) to match rev
- ch.number = int(ch.revision)
- ss = sourcestamp.SourceStamp(changes=chgs)
- self.assertEquals(ss.revision, '3')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py
deleted file mode 100644
index 2917f855..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-import mock
-from twisted.trial import unittest
-from buildbot.status import build
-from buildbot import interfaces
-from buildbot.test.fake import fakemaster
-from buildbot import util
-
-class FakeBuilderStatus:
- implements(interfaces.IBuilderStatus)
-
-class FakeSource(util.ComparableMixin):
- compare_attrs = ('codebase', 'revision')
- def __init__(self, codebase, revision):
- self.codebase = codebase
- self.revision = revision
-
- def clone(self):
- return FakeSource(self.codebase, self.revision)
-
- def getAbsoluteSourceStamp(self, revision):
- return FakeSource(self.codebase, revision)
-
- def __repr__(self):
- # note: this won't work for VC systems with huge 'revision' strings
- text = []
- if self.codebase:
- text.append("(%s)" % self.codebase)
- if self.revision is None:
- return text + [ "latest" ]
- text.append(str(self.revision))
- return "FakeSource(%s)" % (', '.join(text),)
-
-class TestBuildProperties(unittest.TestCase):
- """
- Test that a BuildStatus has the necessary L{IProperties} methods and that
- they delegate to its C{properties} attribute properly - so really just a
- test of the L{IProperties} adapter.
- """
-
- BUILD_NUMBER = 33
-
- def setUp(self):
- self.builder_status = FakeBuilderStatus()
- self.master = fakemaster.make_master()
- self.build_status = build.BuildStatus(self.builder_status, self.master,
- self.BUILD_NUMBER)
- self.build_status.properties = mock.Mock()
-
- def test_getProperty(self):
- self.build_status.getProperty('x')
- self.build_status.properties.getProperty.assert_called_with('x', None)
-
- def test_getProperty_default(self):
- self.build_status.getProperty('x', 'nox')
- self.build_status.properties.getProperty.assert_called_with('x', 'nox')
-
- def test_setProperty(self):
- self.build_status.setProperty('n', 'v', 's')
- self.build_status.properties.setProperty.assert_called_with('n', 'v',
- 's', runtime=True)
-
- def test_hasProperty(self):
- self.build_status.properties.hasProperty.return_value = True
- self.assertTrue(self.build_status.hasProperty('p'))
- self.build_status.properties.hasProperty.assert_called_with('p')
-
- def test_render(self):
- self.build_status.render("xyz")
- self.build_status.properties.render.assert_called_with("xyz")
-
-class TestBuildGetSourcestamps(unittest.TestCase):
- """
- Test that a BuildStatus has the necessary L{IProperties} methods and that
- they delegate to its C{properties} attribute properly - so really just a
- test of the L{IProperties} adapter.
- """
- BUILD_NUMBER = 33
-
- def setUp(self):
- self.builder_status = FakeBuilderStatus()
- self.master = fakemaster.make_master()
- self.build_status = build.BuildStatus(self.builder_status, self.master,
- self.BUILD_NUMBER)
-
- def test_getSourceStamps_no_codebases(self):
- got_revisions = {'': '1111111'}
- self.build_status.sources = [FakeSource('', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=False)]
- self.assertEqual(sourcestamps, [FakeSource('', '0000000')])
-
- def test_getSourceStamps_no_codebases_absolute(self):
- got_revisions = {'': '1111111'}
- self.build_status.sources = [FakeSource('', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=True)]
- self.assertEqual(sourcestamps, [FakeSource('', '1111111')])
-
- def test_getSourceStamps_with_codebases_absolute(self):
- got_revisions = {'lib1': '1111111', 'lib2': 'aaaaaaa'}
- self.build_status.sources = [FakeSource('lib1', '0000000'),
- FakeSource('lib2', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=True)]
- expected_sourcestamps = [FakeSource('lib1', '1111111'),
- FakeSource('lib2', 'aaaaaaa')]
- self.assertEqual(sourcestamps, expected_sourcestamps)
-
- def test_getSourceStamps_with_codebases_less_gotrevisions_absolute(self):
- got_revisions = {'lib1': '1111111', 'lib2': 'aaaaaaa'}
- self.build_status.sources = [FakeSource('lib1', '0000000'),
- FakeSource('lib2', '0000000'),
- FakeSource('lib3', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=True)]
- expected_sourcestamps = [FakeSource('lib1', '1111111'),
- FakeSource('lib2', 'aaaaaaa'),
- FakeSource('lib3', '0000000')]
- self.assertEqual(sourcestamps, expected_sourcestamps)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py
deleted file mode 100644
index 4e7a36f7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from mock import Mock
-from twisted.trial import unittest
-from buildbot.status import builder, master
-from buildbot.test.fake import fakemaster
-
-class TestBuildStatus(unittest.TestCase):
-
- # that buildstep.BuildStepStatus is never instantiated here should tell you
- # that these classes are not well isolated!
-
- def setupBuilder(self, buildername, category=None, description=None):
- m = fakemaster.make_master()
- b = builder.BuilderStatus(buildername=buildername, category=category,
- master=m, description=description)
- # Awkwardly, Status sets this member variable.
- b.basedir = os.path.abspath(self.mktemp())
- os.mkdir(b.basedir)
- # Otherwise, builder.nextBuildNumber is not defined.
- b.determineNextBuildNumber()
- # Must initialize these fields before pickling.
- b.currentBigState = 'idle'
- b.status = 'idle'
- return b
-
- def setupStatus(self, b):
- m = Mock()
- m.buildbotURL = 'http://buildbot:8010/'
- m.basedir = '/basedir'
- s = master.Status(m)
- b.status = s
- return s
-
- def testBuildCache(self):
- b = self.setupBuilder('builder_1')
- builds = []
- for i in xrange(5):
- build = b.newBuild()
- build.setProperty('propkey', 'propval%d' % i, 'test')
- builds.append(build)
- build.buildStarted(build)
- build.buildFinished()
- for build in builds:
- build2 = b.getBuild(build.number)
- self.assertTrue(build2)
- self.assertEqual(build2.number, build.number)
- self.assertEqual(build2.getProperty('propkey'),
- 'propval%d' % build.number)
- # Do another round, to make sure we're hitting the cache
- hits = b.buildCache.hits
- for build in builds:
- build2 = b.getBuild(build.number)
- self.assertTrue(build2)
- self.assertEqual(build2.number, build.number)
- self.assertEqual(build2.getProperty('propkey'),
- 'propval%d' % build.number)
- self.assertEqual(b.buildCache.hits, hits+1)
- hits = hits + 1
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py
deleted file mode 100644
index 44e2d504..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from twisted.trial import unittest
-from buildbot.status import builder, master
-from buildbot.test.fake import fakemaster
-
-class TestBuildStepStatus(unittest.TestCase):
-
- # that buildstep.BuildStepStatus is never instantiated here should tell you
- # that these classes are not well isolated!
-
- def setupBuilder(self, buildername, category=None, description=None):
- self.master = fakemaster.make_master()
- self.master.basedir = '/basedir'
-
- b = builder.BuilderStatus(buildername, self.master, category, description)
- b.master = self.master
- # Ackwardly, Status sets this member variable.
- b.basedir = os.path.abspath(self.mktemp())
- os.mkdir(b.basedir)
- # Otherwise, builder.nextBuildNumber is not defined.
- b.determineNextBuildNumber()
- return b
-
- def setupStatus(self, b):
- s = master.Status(self.master)
- b.status = s
- return s
-
- def testBuildStepNumbers(self):
- b = self.setupBuilder('builder_1')
- bs = b.newBuild()
- self.assertEquals(0, bs.getNumber())
- bss1 = bs.addStepWithName('step_1')
- self.assertEquals('step_1', bss1.getName())
- bss2 = bs.addStepWithName('step_2')
- self.assertEquals(0, bss1.asDict()['step_number'])
- self.assertEquals('step_2', bss2.getName())
- self.assertEquals(1, bss2.asDict()['step_number'])
- self.assertEquals([bss1, bss2], bs.getSteps())
-
- def testLogDict(self):
- b = self.setupBuilder('builder_1')
- self.setupStatus(b)
- bs = b.newBuild()
- bss1 = bs.addStepWithName('step_1')
- bss1.stepStarted()
- bss1.addLog('log_1')
- self.assertEquals(
- bss1.asDict()['logs'],
- [['log_1', ('http://localhost:8080/builders/builder_1/'
- 'builds/0/steps/step_1/logs/log_1')]]
- )
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py
deleted file mode 100644
index 75e93fb4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from buildbot.status import master, client
-from buildbot.test.fake import fakedb
-
-class TestStatusClientPerspective(unittest.TestCase):
-
- def makeStatusClientPersp(self):
- m = mock.Mock(name='master')
- self.db = m.db = fakedb.FakeDBConnector(self)
- m.basedir = r'C:\BASEDIR'
- s = master.Status(m)
- persp = client.StatusClientPerspective(s)
- return persp
-
- def test_getBuildSets(self):
- persp = self.makeStatusClientPersp()
- self.db.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- ])
-
- d = persp.perspective_getBuildSets()
- def check(bslist):
- self.assertEqual(len(bslist), 1)
- self.assertEqual(bslist[0][1], 91)
- self.failUnlessIsInstance(bslist[0][0], client.RemoteBuildSet)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py
deleted file mode 100644
index a2f7153f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import cStringIO, cPickle
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.status import logfile
-from buildbot.test.util import dirs
-from buildbot import config
-
-class TestLogFileProducer(unittest.TestCase):
- def make_static_logfile(self, contents):
- "make a fake logfile with the given contents"
- lf = mock.Mock()
- lf.getFile = lambda : cStringIO.StringIO(contents)
- lf.waitUntilFinished = lambda : defer.succeed(None) # already finished
- lf.runEntries = []
- return lf
-
- def test_getChunks_static_helloworld(self):
- lf = self.make_static_logfile("13:0hello world!,")
- lfp = logfile.LogFileProducer(lf, mock.Mock())
- chunks = list(lfp.getChunks())
- self.assertEqual(chunks, [ (0, 'hello world!') ])
-
- def test_getChunks_static_multichannel(self):
- lf = self.make_static_logfile("2:0a,3:1xx,2:0c,")
- lfp = logfile.LogFileProducer(lf, mock.Mock())
- chunks = list(lfp.getChunks())
- self.assertEqual(chunks, [ (0, 'a'), (1, 'xx'), (0, 'c') ])
-
- # Remainder of LogFileProduer has a wacky interface that's not
- # well-defined, so it's not tested yet
-
-class TestLogFile(unittest.TestCase, dirs.DirsMixin):
-
- def setUp(self):
- step = self.build_step_status = mock.Mock(name='build_step_status')
- self.basedir = step.build.builder.basedir = os.path.abspath('basedir')
- self.setUpDirs(self.basedir)
- self.logfile = logfile.LogFile(step, 'testlf', '123-stdio')
- self.master = self.logfile.master = mock.Mock()
- self.config = self.logfile.master.config = config.MasterConfig()
-
- def tearDown(self):
- if self.logfile.openfile:
- try:
- self.logfile.openfile.close()
- except:
- pass # oh well, we tried
- self.tearDownDirs()
-
- def pickle_and_restore(self):
- pkl = cPickle.dumps(self.logfile)
- self.logfile = cPickle.loads(pkl)
- step = self.build_step_status
- self.logfile.step = step
- self.logfile.master = self.master
- step.build.builder.basedir = self.basedir
-
- def delete_logfile(self):
- if self.logfile.openfile:
- try:
- self.logfile.openfile.close()
- except:
- pass # oh well, we tried
- os.unlink(os.path.join('basedir', '123-stdio'))
-
- # tests
-
- def test_getFilename(self):
- self.assertEqual(self.logfile.getFilename(),
- os.path.abspath(os.path.join('basedir', '123-stdio')))
-
- def test_hasContents_yes(self):
- self.assertTrue(self.logfile.hasContents())
-
- def test_hasContents_no(self):
- self.delete_logfile()
- self.assertFalse(self.logfile.hasContents())
-
- def test_hasContents_gz(self):
- self.delete_logfile()
- with open(os.path.join(self.basedir, '123-stdio.gz'), "w") as f:
- f.write("hi")
- self.assertTrue(self.logfile.hasContents())
-
- def test_hasContents_gz_pickled(self):
- self.delete_logfile()
- with open(os.path.join(self.basedir, '123-stdio.gz'), "w") as f:
- f.write("hi")
- self.pickle_and_restore()
- self.assertTrue(self.logfile.hasContents())
-
- def test_hasContents_bz2(self):
- self.delete_logfile()
- with open(os.path.join(self.basedir, '123-stdio.bz2'), "w") as f:
- f.write("hi")
- self.assertTrue(self.logfile.hasContents())
-
- def test_getName(self):
- self.assertEqual(self.logfile.getName(), 'testlf')
-
- def test_getStep(self):
- self.assertEqual(self.logfile.getStep(), self.build_step_status)
-
- def test_isFinished_no(self):
- self.assertFalse(self.logfile.isFinished())
-
- def test_isFinished_yes(self):
- self.logfile.finish()
- self.assertTrue(self.logfile.isFinished())
-
- def test_waitUntilFinished(self):
- state = []
- d = self.logfile.waitUntilFinished()
- d.addCallback(lambda _ : state.append('called'))
- self.assertEqual(state, []) # not called yet
- self.logfile.finish()
- self.assertEqual(state, ['called'])
-
- def test_getFile(self):
- # test getFile at a number of points in the life-cycle
- self.logfile.addEntry(0, 'hello, world')
- self.logfile._merge()
-
- # while still open for writing
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- self.logfile.finish()
-
- # fp is still open after finish()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- # but a fresh getFile call works, too
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- self.pickle_and_restore()
-
- # even after it is pickled
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- # ..and compressed
- self.config.logCompressionMethod = 'bz2'
- d = self.logfile.compressLog()
- def check(_):
- self.assertTrue(
- os.path.exists(os.path.join(self.basedir, '123-stdio.bz2')))
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
- d.addCallback(check)
- return d
-
- def do_test_addEntry(self, entries, expected):
- for chan, txt in entries:
- self.logfile.addEntry(chan, txt)
- self.logfile.finish()
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), expected)
-
- def test_addEntry_single(self):
- return self.do_test_addEntry([(0, 'hello, world')],
- '13:0hello, world,')
-
- def test_addEntry_run(self):
- # test that addEntry is calling merge() correctly
- return self.do_test_addEntry([ (0, c) for c in 'hello, world' ],
- '13:0hello, world,')
-
- def test_addEntry_multichan(self):
- return self.do_test_addEntry([(1, 'x'), (2, 'y'), (1, 'z')],
- '2:1x,2:2y,2:1z,')
-
- def test_addEntry_length(self):
- self.do_test_addEntry([(1, 'x'), (2, 'y')],
- '2:1x,2:2y,')
- self.assertEqual(self.logfile.length, 2)
-
- def test_addEntry_unicode(self):
- return self.do_test_addEntry([(1, u'\N{SNOWMAN}')],
- '4:1\xe2\x98\x83,') # utf-8 encoded
-
- def test_addEntry_logMaxSize(self):
- self.config.logMaxSize = 10 # not evenly divisible by chunk size
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '11:0abcdefabcd,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,')
-
- def test_addEntry_logMaxSize_ignores_header(self):
- self.config.logMaxSize = 10
- return self.do_test_addEntry([(logfile.HEADER, 'abcdef')] * 10 ,
- '61:2' + 'abcdef'*10 + ',')
-
- def test_addEntry_logMaxSize_divisor(self):
- self.config.logMaxSize = 12 # evenly divisible by chunk size
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '13:0abcdefabcdef,'
- '64:2\nOutput exceeded 12 bytes, remaining output has been '
- 'truncated\n,')
-
- def test_addEntry_logMaxTailSize(self):
- self.config.logMaxSize = 10
- self.config.logMaxTailSize = 14
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '11:0abcdefabcd,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,'
- # NOTE: this gets too few bytes; this is OK for now, and
- # easier than subdividing chunks in the tail tracking
- '31:2\nFinal 12 bytes follow below:\n,'
- '13:0abcdefabcdef,')
-
- def test_addEntry_logMaxTailSize_divisor(self):
- self.config.logMaxSize = 10
- self.config.logMaxTailSize = 12
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '11:0abcdefabcd,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,'
- '31:2\nFinal 12 bytes follow below:\n,'
- '13:0abcdefabcdef,')
-
- # TODO: test that head and tail don't discriminate between stderr and stdout
-
- def test_addEntry_chunkSize(self):
- self.logfile.chunkSize = 11
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- # note that this doesn't re-chunk everything; just shrinks
- # chunks that will exceed the maximum size
- '12:0abcdefabcde,2:0f,' * 5)
-
- def test_addEntry_big_channel(self):
- # channels larger than one digit are not allowed
- self.assertRaises(AssertionError,
- lambda : self.do_test_addEntry([(9999, 'x')], ''))
-
- def test_addEntry_finished(self):
- self.logfile.finish()
- self.assertRaises(AssertionError,
- lambda : self.do_test_addEntry([(0, 'x')], ''))
-
- def test_addEntry_merge_exception(self):
- def fail():
- raise RuntimeError("FAIL")
- self.patch(self.logfile, '_merge', fail)
- self.assertRaises(RuntimeError,
- lambda : self.do_test_addEntry([(0, 'x')], ''))
-
- def test_addEntry_watchers(self):
- watcher = mock.Mock(name='watcher')
- self.logfile.watchers.append(watcher)
- self.do_test_addEntry([(0, 'x')], '2:0x,')
- watcher.logChunk.assert_called_with(self.build_step_status.build,
- self.build_step_status, self.logfile, 0, 'x')
-
- def test_addEntry_watchers_logMaxSize(self):
- watcher = mock.Mock(name='watcher')
- self.logfile.watchers.append(watcher)
- self.config.logMaxSize = 10
- self.do_test_addEntry([(0, 'x')] * 15,
- '11:0xxxxxxxxxx,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,')
- logChunk_chunks = [ tuple(args[0][3:])
- for args in watcher.logChunk.call_args_list ]
- self.assertEqual(logChunk_chunks, [(0, 'x')] * 15)
-
- def test_addStdout(self):
- addEntry = mock.Mock()
- self.patch(self.logfile, 'addEntry', addEntry)
- self.logfile.addStdout('oot')
- addEntry.assert_called_with(0, 'oot')
-
- def test_addStderr(self):
- addEntry = mock.Mock()
- self.patch(self.logfile, 'addEntry', addEntry)
- self.logfile.addStderr('eer')
- addEntry.assert_called_with(1, 'eer')
-
- def test_addHeader(self):
- addEntry = mock.Mock()
- self.patch(self.logfile, 'addEntry', addEntry)
- self.logfile.addHeader('hed')
- addEntry.assert_called_with(2, 'hed')
-
- def do_test_compressLog(self, ext, expect_comp=True):
- self.logfile.openfile.write('xyz' * 1000)
- self.logfile.finish()
- d = self.logfile.compressLog()
- def check(_):
- st = os.stat(self.logfile.getFilename() + ext)
- if expect_comp:
- self.assertTrue(0 < st.st_size < 3000)
- else:
- self.assertTrue(st.st_size == 3000)
- d.addCallback(check)
- return d
-
- def test_compressLog_gz(self):
- self.config.logCompressionMethod = 'gz'
- return self.do_test_compressLog('.gz')
-
- def test_compressLog_bz2(self):
- self.config.logCompressionMethod = 'bz2'
- return self.do_test_compressLog('.bz2')
-
- def test_compressLog_none(self):
- self.config.logCompressionMethod = None
- return self.do_test_compressLog('', expect_comp=False)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py
deleted file mode 100644
index 3ca64247..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py
+++ /dev/null
@@ -1,816 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-from mock import Mock
-from buildbot import config
-from twisted.trial import unittest
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS, EXCEPTION
-from buildbot.status.mail import MailNotifier
-from twisted.internet import defer
-from buildbot.test.fake import fakedb
-from buildbot.test.fake.fakebuild import FakeBuildStatus
-from buildbot.process import properties
-
-py_27 = sys.version_info[0] > 2 or (sys.version_info[0] == 2
- and sys.version_info[1] >= 7)
-
-class FakeLog(object):
- def __init__(self, text):
- self.text = text
-
- def getName(self):
- return 'log-name'
-
- def getStep(self):
- class FakeStep(object):
- def getName(self):
- return 'step-name'
- return FakeStep()
-
- def getText(self):
- return self.text
-
-class FakeSource:
- def __init__(self, branch = None, revision = None, repository = None,
- codebase = None, project = None):
- self.changes = []
- self.branch = branch
- self.revision = revision
- self.repository = repository
- self.codebase = codebase
- self.project = project
- self.patch_info = None
- self.patch = None
-
-class TestMailNotifier(unittest.TestCase):
-
- def do_test_createEmail_cte(self, funnyChars, expEncoding):
- builds = [ FakeBuildStatus(name='build') ]
- msgdict = create_msgdict(funnyChars)
- mn = MailNotifier('from@example.org')
- d = mn.createEmail(msgdict, u'builder-name', u'project-name',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- cte_lines = [ l for l in m.as_string().split("\n")
- if l.startswith('Content-Transfer-Encoding:') ]
- self.assertEqual(cte_lines,
- [ 'Content-Transfer-Encoding: %s' % expEncoding ],
- `m.as_string()`)
- return d
-
- def test_createEmail_message_content_transfer_encoding_7bit(self):
- return self.do_test_createEmail_cte(u"old fashioned ascii",
- '7bit' if py_27 else 'base64')
-
- def test_createEmail_message_content_transfer_encoding_8bit(self):
- return self.do_test_createEmail_cte(u"\U0001F4A7",
- '8bit' if py_27 else 'base64')
-
- def test_createEmail_message_without_patch_and_log_contains_unicode(self):
- builds = [ FakeBuildStatus(name="build") ]
- msgdict = create_msgdict()
- mn = MailNotifier('from@example.org')
- d = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- try:
- m.as_string()
- except UnicodeEncodeError:
- self.fail('Failed to call as_string() on email message.')
- return d
-
- def test_createEmail_extraHeaders_one_build(self):
- builds = [ FakeBuildStatus(name="build") ]
- builds[0].properties = properties.Properties()
- builds[0].setProperty('hhh','vvv')
- msgdict = create_msgdict()
- mn = MailNotifier('from@example.org', extraHeaders=dict(hhh='vvv'))
- # add some Unicode to detect encoding problems
- d = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- txt = m.as_string()
- self.assertIn('hhh: vvv', txt)
- return d
-
- def test_createEmail_extraHeaders_two_builds(self):
- builds = [ FakeBuildStatus(name="build1"),
- FakeBuildStatus(name="build2") ]
- msgdict = create_msgdict()
- mn = MailNotifier('from@example.org', extraHeaders=dict(hhh='vvv'))
- d = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- txt = m.as_string()
- # note that the headers are *not* rendered
- self.assertIn('hhh: vvv', txt)
- return d
-
- def test_createEmail_message_with_patch_and_log_containing_unicode(self):
- builds = [ FakeBuildStatus(name="build") ]
- msgdict = create_msgdict()
- patches = [ ['', u'\u00E5\u00E4\u00F6', ''] ]
- msg = u'Unicode log with non-ascii (\u00E5\u00E4\u00F6).'
- # add msg twice: as unicode and already encoded
- logs = [ FakeLog(msg), FakeLog(msg.encode('utf-8')) ]
- mn = MailNotifier('from@example.org', addLogs=True)
- d = mn.createEmail(msgdict, u'builder-n\u00E5me',
- u'project-n\u00E5me', SUCCESS,
- builds, patches, logs)
- @d.addCallback
- def callback(m):
- try:
- m.as_string()
- except UnicodeEncodeError:
- self.fail('Failed to call as_string() on email message.')
- return d
-
- def test_createEmail_message_with_nonascii_patch(self):
- builds = [ FakeBuildStatus(name="build") ]
- msgdict = create_msgdict()
- patches = [ ['', '\x99\xaa', ''] ]
- logs = [ FakeLog('simple log') ]
- mn = MailNotifier('from@example.org', addLogs=True)
- d = mn.createEmail(msgdict, u'builder', u'pr', SUCCESS,
- builds, patches, logs)
- @d.addCallback
- def callback(m):
- txt = m.as_string()
- self.assertIn('application/octet-stream', txt)
- return d
-
- def test_init_enforces_categories_and_builders_are_mutually_exclusive(self):
- self.assertRaises(config.ConfigErrors,
- MailNotifier, 'from@example.org',
- categories=['fast','slow'], builders=['a','b'])
-
- def test_builderAdded_ignores_unspecified_categories(self):
- mn = MailNotifier('from@example.org', categories=['fast'])
-
- builder = Mock()
- builder.category = 'slow'
-
- self.assertEqual(None, mn.builderAdded('dummyBuilder', builder))
- self.assert_(builder not in mn.watched)
-
- def test_builderAdded_subscribes_to_all_builders_by_default(self):
- mn = MailNotifier('from@example.org')
-
- builder = Mock()
- builder.category = 'slow'
- builder2 = Mock()
- builder2.category = None
-
- self.assertEqual(mn, mn.builderAdded('dummyBuilder', builder))
- self.assertEqual(mn, mn.builderAdded('dummyBuilder2', builder2))
- self.assertTrue(builder in mn.watched)
- self.assertTrue(builder2 in mn.watched)
-
- def test_buildFinished_ignores_unspecified_builders(self):
- mn = MailNotifier('from@example.org', builders=['a','b'])
-
- build = FakeBuildStatus()
- build.builder = Mock()
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def test_buildsetFinished_sends_email(self):
- fakeBuildMessage = Mock()
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "passing", "warnings"),
- builders=["Builder1", "Builder2"])
-
- mn.buildMessage = fakeBuildMessage
-
- builder1 = Mock()
- builder1.getBuild = lambda number: build1
- builder1.name = "Builder1"
-
- build1 = FakeBuildStatus()
- build1.results = FAILURE
- build1.finished = True
- build1.reason = "testReason"
- build1.getBuilder.return_value = builder1
-
- builder2 = Mock()
- builder2.getBuild = lambda number: build2
- builder2.name = "Builder2"
-
- build2 = FakeBuildStatus()
- build2.results = FAILURE
- build2.finished = True
- build2.reason = "testReason"
- build2.getBuilder.return_value = builder1
-
- def fakeGetBuilder(buildername):
- return {"Builder1": builder1, "Builder2": builder2}[buildername]
-
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder1'),
- fakedb.Build(number=0, brid=11),
- fakedb.BuildRequest(id=12, buildsetid=99,
- buildername='Builder2'),
- fakedb.Build(number=0, brid=12),
- ])
- mn.master = self # FIXME: Should be FakeMaster
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict = Mock()
- mn.buildMessageDict.return_value = {"body":"body", "type":"text",
- "subject":"subject"}
-
- mn.buildsetFinished(99, FAILURE)
- fakeBuildMessage.assert_called_with("Buildset Complete: testReason",
- [build1, build2], SUCCESS)
-
- def test_buildsetFinished_doesnt_send_email(self):
- fakeBuildMessage = Mock()
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "warnings"),
- builders=["Builder"])
- mn.buildMessage = fakeBuildMessage
-
-
- def fakeGetBuild(number):
- return build
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
-
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus()
- build.results = SUCCESS
- build.finished = True
- build.reason = "testReason"
- build.getBuilder.return_value = builder
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- ])
- mn.master = self
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict = Mock()
- mn.buildMessageDict.return_value = {"body":"body", "type":"text",
- "subject":"subject"}
-
- mn.buildsetFinished(99, FAILURE)
- self.assertFalse(fakeBuildMessage.called)
-
- def test_getCustomMesgData_multiple_sourcestamps(self):
- self.passedAttrs = {}
- def fakeCustomMessage(attrs):
- self.passedAttrs = attrs
- return ("", "")
-
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "passing", "warnings"),
- builders=["Builder"])
-
-
- def fakeBuildMessage(name, builds, results):
- for build in builds:
- mn.buildMessageDict(name=build.getBuilder().name,
- build=build, results=build.results)
-
- mn.buildMessage = fakeBuildMessage
- mn.customMesg = fakeCustomMessage
-
- def fakeGetBuild(number):
- return build
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
-
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- ])
- mn.master = self
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus()
- build.results = FAILURE
- build.finished = True
- build.reason = "testReason"
- build.getLogs.return_value = []
- build.getBuilder.return_value = builder
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
-
- ss1 = FakeSource(revision='111222', codebase='testlib1')
- ss2 = FakeSource(revision='222333', codebase='testlib2')
- build.getSourceStamps.return_value = [ss1, ss2]
-
- mn.buildsetFinished(99, FAILURE)
-
- self.assertTrue('revision' in self.passedAttrs, "No revision entry found in attrs")
- self.assertTrue(isinstance(self.passedAttrs['revision'], dict))
- self.assertEqual(self.passedAttrs['revision']['testlib1'], '111222')
- self.assertEqual(self.passedAttrs['revision']['testlib2'], '222333')
-
- def test_getCustomMesgData_single_sourcestamp(self):
- self.passedAttrs = {}
- def fakeCustomMessage(attrs):
- self.passedAttrs = attrs
- return ("", "")
-
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "passing", "warnings"),
- builders=["Builder"])
-
-
- def fakeBuildMessage(name, builds, results):
- for build in builds:
- mn.buildMessageDict(name=build.getBuilder().name,
- build=build, results=build.results)
-
- mn.buildMessage = fakeBuildMessage
- mn.customMesg = fakeCustomMessage
-
- def fakeGetBuild(number):
- return build
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
-
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- ])
- mn.master = self
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus()
- build.results = FAILURE
- build.finished = True
- build.reason = "testReason"
- build.getLogs.return_value = []
- build.getBuilder.return_value = builder
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
-
- ss1 = FakeSource(revision='111222', codebase='testlib1')
- build.getSourceStamps.return_value = [ss1]
-
- mn.buildsetFinished(99, FAILURE)
-
- self.assertTrue('builderName' in self.passedAttrs, "No builderName entry found in attrs")
- self.assertEqual(self.passedAttrs['builderName'], 'Builder')
- self.assertTrue('revision' in self.passedAttrs, "No revision entry found in attrs")
- self.assertTrue(isinstance(self.passedAttrs['revision'], str))
- self.assertEqual(self.passedAttrs['revision'], '111222')
-
- def test_buildFinished_ignores_unspecified_categories(self):
- mn = MailNotifier('from@example.org', categories=['fast'])
-
-
- build = FakeBuildStatus(name="build")
- build.builder = Mock()
- build.builder.category = 'slow'
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def run_simple_test_sends_email_for_mode(self, mode, result):
- mock_method = Mock()
- self.patch(MailNotifier, "buildMessage", mock_method)
- mn = MailNotifier('from@example.org', mode=mode)
-
- build = FakeBuildStatus(name="build")
- mn.buildFinished('dummyBuilder', build, result)
-
- mock_method.assert_called_with('dummyBuilder', [build], result)
-
- def run_simple_test_ignores_email_for_mode(self, mode, result):
- mock_method = Mock()
- self.patch(MailNotifier, "buildMessage", mock_method)
- mn = MailNotifier('from@example.org', mode=mode)
-
- build = FakeBuildStatus(name="build")
- mn.buildFinished('dummyBuilder', build, result)
-
- self.assertFalse(mock_method.called)
-
- def test_buildFinished_mode_all_for_success(self):
- self.run_simple_test_sends_email_for_mode("all", SUCCESS)
- def test_buildFinished_mode_all_for_failure(self):
- self.run_simple_test_sends_email_for_mode("all", FAILURE)
- def test_buildFinished_mode_all_for_warnings(self):
- self.run_simple_test_sends_email_for_mode("all", WARNINGS)
- def test_buildFinished_mode_all_for_exception(self):
- self.run_simple_test_sends_email_for_mode("all", EXCEPTION)
-
- def test_buildFinished_mode_failing_for_success(self):
- self.run_simple_test_ignores_email_for_mode("failing", SUCCESS)
- def test_buildFinished_mode_failing_for_failure(self):
- self.run_simple_test_sends_email_for_mode("failing", FAILURE)
- def test_buildFinished_mode_failing_for_warnings(self):
- self.run_simple_test_ignores_email_for_mode("failing", WARNINGS)
- def test_buildFinished_mode_failing_for_exception(self):
- self.run_simple_test_ignores_email_for_mode("failing", EXCEPTION)
-
- def test_buildFinished_mode_exception_for_success(self):
- self.run_simple_test_ignores_email_for_mode("exception", SUCCESS)
- def test_buildFinished_mode_exception_for_failure(self):
- self.run_simple_test_ignores_email_for_mode("exception", FAILURE)
- def test_buildFinished_mode_exception_for_warnings(self):
- self.run_simple_test_ignores_email_for_mode("exception", WARNINGS)
- def test_buildFinished_mode_exception_for_exception(self):
- self.run_simple_test_sends_email_for_mode("exception", EXCEPTION)
-
- def test_buildFinished_mode_warnings_for_success(self):
- self.run_simple_test_ignores_email_for_mode("warnings", SUCCESS)
- def test_buildFinished_mode_warnings_for_failure(self):
- self.run_simple_test_sends_email_for_mode("warnings", FAILURE)
- def test_buildFinished_mode_warnings_for_warnings(self):
- self.run_simple_test_sends_email_for_mode("warnings", WARNINGS)
- def test_buildFinished_mode_warnings_for_exception(self):
- self.run_simple_test_ignores_email_for_mode("warnings", EXCEPTION)
-
- def test_buildFinished_mode_passing_for_success(self):
- self.run_simple_test_sends_email_for_mode("passing", SUCCESS)
- def test_buildFinished_mode_passing_for_failure(self):
- self.run_simple_test_ignores_email_for_mode("passing", FAILURE)
- def test_buildFinished_mode_passing_for_warnings(self):
- self.run_simple_test_ignores_email_for_mode("passing", WARNINGS)
- def test_buildFinished_mode_passing_for_exception(self):
- self.run_simple_test_ignores_email_for_mode("passing", EXCEPTION)
-
- def test_buildFinished_mode_failing_ignores_successful_build(self):
- mn = MailNotifier('from@example.org', mode=("failing",))
-
- build = FakeBuildStatus(name="build")
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def test_buildFinished_mode_passing_ignores_failed_build(self):
- mn = MailNotifier('from@example.org', mode=("passing",))
-
- build = FakeBuildStatus(name="build")
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
-
- def test_buildFinished_mode_problem_ignores_successful_build(self):
- mn = MailNotifier('from@example.org', mode=("problem",))
-
- build = FakeBuildStatus(name="build")
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def test_buildFinished_mode_problem_ignores_two_failed_builds_in_sequence(self):
- mn = MailNotifier('from@example.org', mode=("problem",))
-
- build = FakeBuildStatus(name="build")
- old_build = FakeBuildStatus(name="old_build")
- build.getPreviousBuild.return_value = old_build
- old_build.getResults.return_value = FAILURE
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
-
- def test_buildFinished_mode_change_ignores_first_build(self):
- mn = MailNotifier('from@example.org', mode=("change",))
-
- build = FakeBuildStatus(name="build")
- build.getPreviousBuild.return_value = None
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
-
- def test_buildFinished_mode_change_ignores_same_result_in_sequence(self):
- mn = MailNotifier('from@example.org', mode=("change",))
-
- build = FakeBuildStatus(name="build")
- old_build = FakeBuildStatus(name="old_build")
- build.getPreviousBuild.return_value = old_build
- old_build.getResults.return_value = FAILURE
-
- build2 = FakeBuildStatus(name="build2")
- old_build2 = FakeBuildStatus(name="old_build2")
- build2.getPreviousBuild.return_value = old_build2
- old_build2.getResults.return_value = SUCCESS
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build2, SUCCESS))
-
- def test_buildMessage_addLogs(self):
- mn = MailNotifier('from@example.org', mode=("change",), addLogs=True)
-
- mn.buildMessageDict = Mock()
- mn.buildMessageDict.return_value = {"body":"body", "type":"text",
- "subject":"subject"}
-
- mn.createEmail = Mock("createEmail")
-
- mn._gotRecipients = Mock("_gotReceipients")
- mn._gotRecipients.return_value = None
-
- mn.master_status = Mock()
- mn.master_status.getTitle.return_value = 'TITLE'
-
- bldr = Mock(name="builder")
- builds = [ FakeBuildStatus(name='build1'),
- FakeBuildStatus(name='build2') ]
- logs = [ FakeLog('log1'), FakeLog('log2') ]
- for b, l in zip(builds, logs):
- b.builder = bldr
- b.results = 0
- ss = Mock(name='ss')
- b.getSourceStamps.return_value = [ss]
- ss.patch = None
- ss.changes = []
- b.getLogs.return_value = [ l ]
- d = mn.buildMessage("mybldr", builds, 0)
- def check(_):
- mn.createEmail.assert_called_with(
- dict(body='body\n\nbody\n\n', type='text', subject='subject'),
- 'mybldr', 'TITLE', 0, builds, [], logs)
- d.addCallback(check)
- return d
-
- def do_test_sendToInterestedUsers(self, lookup=None, extraRecipients=[],
- sendToInterestedUsers=True,
- exp_called_with=None, exp_TO=None,
- exp_CC=None):
- from email.Message import Message
- m = Message()
-
- mn = MailNotifier(fromaddr='from@example.org',
- lookup=lookup,
- sendToInterestedUsers=sendToInterestedUsers,
- extraRecipients=extraRecipients)
- mn.sendMessage = Mock()
-
- def fakeGetBuild(number):
- return build
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus(name="build")
- build.result = FAILURE
- build.finished = True
- build.reason = "testReason"
- build.builder = builder
-
- def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
- patches=None, logs=None):
- # only concerned with m['To'] and m['CC'], which are added in
- # _got_recipients later
- return defer.succeed(m)
- mn.createEmail = fakeCreateEmail
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=1099),
- fakedb.Buildset(id=99, sourcestampsetid=1099,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- fakedb.Change(changeid=9123),
- fakedb.ChangeUser(changeid=9123, uid=1),
- fakedb.User(uid=1, identifier="tdurden"),
- fakedb.UserInfo(uid=1, attr_type='svn',
- attr_data="tdurden"),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data="tyler@mayhem.net")
- ])
-
- # fake sourcestamp with relevant user bits
- ss = Mock(name="sourcestamp")
- fake_change = Mock(name="change")
- fake_change.number = 9123
- ss.changes = [fake_change]
- ss.patch, ss.addPatch = None, None
-
- def fakeGetSSlist():
- return [ss]
- build.getSourceStamps = fakeGetSSlist
-
- def _getInterestedUsers():
- # 'narrator' in this case is the owner, which tests the lookup
- return ["narrator"]
- build.getInterestedUsers = _getInterestedUsers
-
- def _getResponsibleUsers():
- return ["Big Bob <bob@mayhem.net>"]
- build.getResponsibleUsers = _getResponsibleUsers
-
- mn.master = self # FIXME: Should be FakeMaster
- self.status = mn.master_status = mn.buildMessageDict = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict.return_value = {"body": "body", "type": "text"}
-
- mn.buildMessage(builder.name, [build], build.result)
- mn.sendMessage.assert_called_with(m, exp_called_with)
- self.assertEqual(m['To'], exp_TO)
- self.assertEqual(m['CC'], exp_CC)
-
- def test_sendToInterestedUsers_lookup(self):
- self.do_test_sendToInterestedUsers(
- lookup="example.org",
- exp_called_with=['Big Bob <bob@mayhem.net>',
- 'narrator@example.org'],
- exp_TO="Big Bob <bob@mayhem.net>, " \
- "narrator@example.org")
-
- def test_buildMessage_sendToInterestedUsers_no_lookup(self):
- self.do_test_sendToInterestedUsers(
- exp_called_with=['tyler@mayhem.net'],
- exp_TO="tyler@mayhem.net")
-
- def test_buildMessage_sendToInterestedUsers_extraRecipients(self):
- self.do_test_sendToInterestedUsers(
- extraRecipients=["marla@mayhem.net"],
- exp_called_with=['tyler@mayhem.net',
- 'marla@mayhem.net'],
- exp_TO="tyler@mayhem.net",
- exp_CC="marla@mayhem.net")
- def test_sendToInterestedUsers_False(self):
- self.do_test_sendToInterestedUsers(
- extraRecipients=["marla@mayhem.net"],
- sendToInterestedUsers=False,
- exp_called_with=['marla@mayhem.net'],
- exp_TO="marla@mayhem.net")
-
- def test_sendToInterestedUsers_two_builds(self):
- from email.Message import Message
- m = Message()
-
- mn = MailNotifier(fromaddr="from@example.org", lookup=None)
- mn.sendMessage = Mock()
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- builder = Mock()
- builder.name = "Builder"
-
- build1 = FakeBuildStatus(name="build")
- build1.result = FAILURE
- build1.finished = True
- build1.reason = "testReason"
- build1.builder = builder
-
- build2 = FakeBuildStatus(name="build")
- build2.result = FAILURE
- build2.finished = True
- build2.reason = "testReason"
- build2.builder = builder
-
- def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
- patches=None, logs=None):
- # only concerned with m['To'] and m['CC'], which are added in
- # _got_recipients later
- return defer.succeed(m)
- mn.createEmail = fakeCreateEmail
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=1099),
- fakedb.Buildset(id=99, sourcestampsetid=1099,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- fakedb.Build(number=1, brid=11),
- fakedb.Change(changeid=9123),
- fakedb.Change(changeid=9124),
- fakedb.ChangeUser(changeid=9123, uid=1),
- fakedb.ChangeUser(changeid=9124, uid=2),
- fakedb.User(uid=1, identifier="tdurden"),
- fakedb.User(uid=2, identifier="user2"),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data="tyler@mayhem.net"),
- fakedb.UserInfo(uid=2, attr_type='email',
- attr_data="user2@example.net")
- ])
-
- def _getInterestedUsers():
- # 'narrator' in this case is the owner, which tests the lookup
- return ["narrator"]
- build1.getInterestedUsers = _getInterestedUsers
- build2.getInterestedUsers = _getInterestedUsers
-
- def _getResponsibleUsers():
- return ["Big Bob <bob@mayhem.net>"]
- build1.getResponsibleUsers = _getResponsibleUsers
- build2.getResponsibleUsers = _getResponsibleUsers
-
- # fake sourcestamp with relevant user bits
- ss1 = Mock(name="sourcestamp")
- fake_change1 = Mock(name="change")
- fake_change1.number = 9123
- ss1.changes = [fake_change1]
- ss1.patch, ss1.addPatch = None, None
-
- ss2 = Mock(name="sourcestamp")
- fake_change2 = Mock(name="change")
- fake_change2.number = 9124
- ss2.changes = [fake_change2]
- ss2.patch, ss1.addPatch = None, None
-
- def fakeGetSSlist(ss):
- return lambda: [ss]
- build1.getSourceStamps = fakeGetSSlist(ss1)
- build2.getSourceStamps = fakeGetSSlist(ss2)
-
- mn.master = self # FIXME: Should be FakeMaster
- self.status = mn.master_status = mn.buildMessageDict = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict.return_value = {"body": "body", "type": "text"}
-
- mn.buildMessage(builder.name, [build1, build2], build1.result)
- self.assertEqual(m['To'], "tyler@mayhem.net, user2@example.net")
-
-def create_msgdict(funny_chars=u'\u00E5\u00E4\u00F6'):
- unibody = u'Unicode body with non-ascii (%s).' % funny_chars
- msg_dict = dict(body=unibody, type='plain')
- return msg_dict
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py
deleted file mode 100644
index 04ae5136..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.status import master, base
-from buildbot.test.fake import fakedb
-
-class FakeStatusReceiver(base.StatusReceiver):
- pass
-
-class TestStatus(unittest.TestCase):
-
- def makeStatus(self):
- m = mock.Mock(name='master')
- self.db = m.db = fakedb.FakeDBConnector(self)
- m.basedir = r'C:\BASEDIR'
- s = master.Status(m)
- return s
-
- def test_getBuildSets(self):
- s = self.makeStatus()
- self.db.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- fakedb.Buildset(id=92, sourcestampsetid=234, complete=1,
- complete_at=298297876, results=7, submitted_at=266761876,
- external_idstring='extid', reason='rsn2'),
- ])
-
- d = s.getBuildSets()
- def check(bslist):
- self.assertEqual([ bs.id for bs in bslist ], [ 91 ])
- d.addCallback(check)
- return d
-
- @defer.inlineCallbacks
- def test_reconfigService(self):
- m = mock.Mock(name='master')
- status = master.Status(m)
- status.startService()
-
- config = mock.Mock()
-
- # add a status reciever
- sr0 = FakeStatusReceiver()
- config.status = [ sr0 ]
-
- yield status.reconfigService(config)
-
- self.assertTrue(sr0.running)
- self.assertIdentical(sr0.master, m)
-
- # add a status reciever
- sr1 = FakeStatusReceiver()
- sr2 = FakeStatusReceiver()
- config.status = [ sr1, sr2 ]
-
- yield status.reconfigService(config)
-
- self.assertFalse(sr0.running)
- self.assertIdentical(sr0.master, None)
- self.assertTrue(sr1.running)
- self.assertIdentical(sr1.master, m)
- self.assertTrue(sr2.running)
- self.assertIdentical(sr2.master, m)
-
- # reconfig with those two (a regression check)
- sr1 = FakeStatusReceiver()
- sr2 = FakeStatusReceiver()
- config.status = [ sr1, sr2 ]
-
- yield status.reconfigService(config)
-
- # and back to nothing
- config.status = [ ]
- yield status.reconfigService(config)
-
- self.assertIdentical(sr0.master, None)
- self.assertIdentical(sr1.master, None)
- self.assertIdentical(sr2.master, None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py
deleted file mode 100644
index 3bf65e5d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os
-from twisted.trial import unittest
-from buildbot.test.util import dirs
-
-from buildbot.status.persistent_queue import MemoryQueue, DiskQueue, \
- IQueue, PersistentQueue, WriteFile
-
-class test_Queues(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('fake_dir')
-
- def tearDown(self):
- self.assertEqual([], os.listdir('fake_dir'))
- self.tearDownDirs()
-
- def testQueued(self):
- # Verify behavior when starting up with queued items on disk.
- WriteFile(os.path.join('fake_dir', '3'), 'foo3')
- WriteFile(os.path.join('fake_dir', '5'), 'foo5')
- WriteFile(os.path.join('fake_dir', '8'), 'foo8')
- queue = PersistentQueue(MemoryQueue(3),
- DiskQueue('fake_dir', 5, pickleFn=str, unpickleFn=str))
- self.assertEqual(['foo3', 'foo5', 'foo8'], queue.items())
- self.assertEqual(3, queue.nbItems())
- self.assertEqual(['foo3', 'foo5', 'foo8'], queue.popChunk())
-
- def _test_helper(self, q):
- self.assertTrue(IQueue.providedBy(q))
- self.assertEqual(8, q.maxItems())
- self.assertEqual(0, q.nbItems())
- self.assertEqual([], q.items())
-
- for i in range(4):
- self.assertEqual(None, q.pushItem(i), str(i))
- self.assertEqual(i + 1, q.nbItems(), str(i))
- self.assertEqual([0, 1, 2, 3], q.items())
- self.assertEqual(4, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([0, 1, 2], q.primaryQueue.items())
- self.assertEqual([3], q.secondaryQueue.items())
-
- self.assertEqual(None, q.save())
- self.assertEqual([0, 1, 2, 3], q.items())
- self.assertEqual(4, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([0, 1, 2, 3], q.secondaryQueue.items())
-
- for i in range(4):
- self.assertEqual(None, q.pushItem(i + 4), str(i + 4))
- self.assertEqual(i + 5, q.nbItems(), str(i + 4))
- self.assertEqual([0, 1, 2, 3, 4, 5, 6, 7], q.items())
- self.assertEqual(8, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([0, 1, 2], q.primaryQueue.items())
- self.assertEqual([3, 4, 5, 6, 7], q.secondaryQueue.items())
-
- self.assertEqual(0, q.pushItem(8))
- self.assertEqual(8, q.nbItems())
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.items())
- if isinstance(q, PersistentQueue):
- self.assertEqual([1, 2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([1, 2], q.popChunk(2))
- self.assertEqual([3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(6, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([3], q.popChunk(1))
- self.assertEqual([4, 5, 6, 7, 8], q.items())
- self.assertEqual(5, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual(None, q.save())
- self.assertEqual(5, q.nbItems())
- self.assertEqual([4, 5, 6, 7, 8], q.items())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual(None, q.insertBackChunk([2, 3]))
- self.assertEqual([2, 3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(7, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([0], q.insertBackChunk([0, 1]))
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(8, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([1, 2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([10, 11], q.insertBackChunk([10, 11]))
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(8, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([1, 2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.popChunk(8))
- self.assertEqual([], q.items())
- self.assertEqual(0, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([], q.secondaryQueue.items())
-
- self.assertEqual([], q.popChunk())
- self.assertEqual(0, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([], q.secondaryQueue.items())
-
- def testMemoryQueue(self):
- self._test_helper(MemoryQueue(maxItems=8))
-
- def testDiskQueue(self):
- self._test_helper(DiskQueue('fake_dir', maxItems=8))
-
- def testPersistentQueue(self):
- self._test_helper(PersistentQueue(MemoryQueue(3),
- DiskQueue('fake_dir', 5)))
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py
deleted file mode 100644
index b1abc8b9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.status import progress
-
-class TestExpectations(unittest.TestCase):
-
- def test_addNewStep(self):
- """
- http://trac.buildbot.net/ticket/2252
- """
- buildProgress = progress.BuildProgress([])
- expectations = progress.Expectations(buildProgress)
- stepProgress = progress.StepProgress("step", ["metric"])
- newProgress = progress.BuildProgress([stepProgress])
- stepProgress.start()
- stepProgress.finish()
- stepProgress.setProgress("metric", 42)
- expectations.update(newProgress)
-
-
- def test_removeOldStep(self):
- """
- http://trac.buildbot.net/ticket/2281
- """
- stepProgress = progress.StepProgress("step", ["metric"])
- oldProgress = progress.BuildProgress([stepProgress])
- expectations = progress.Expectations(oldProgress)
- buildProgress = progress.BuildProgress([])
- buildProgress.setExpectationsFrom(expectations)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py
deleted file mode 100644
index 27a0d24f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-"""
-Test Passwords
-desbuildmaster:yifux5rkzvI5w
-desbuildslave:W8SPURMnCs7Tc
-desbuildbot:IzclhyfHAq6Oc
-md5buildmaster:$apr1$pSepI8Wp$eJZcfhnpENrRlUn28wak50
-md5buildslave:$apr1$dtX6FDei$vFB5BlnR9bjQisy7v3ZaC0
-md5buildbot:$apr1$UcfsHmrF$i9fYa4OsPI3AK8UBbN3ju1
-shabuildmaster:{SHA}vpAKSO3uPt6z8KL6cqf5W5Sredk=
-shabuildslave:{SHA}sNA10GbdONwGJ+a8VGRNtEyWd9I=
-shabuildbot:{SHA}TwEDa5Q31ZhI4GLmIbE1VrrAkpk=
-"""
-
-
-from twisted.trial import unittest
-
-from buildbot.status.web.auth import HTPasswdAprAuth
-from buildbot.test.util import compat
-
-class TestHTPasswdAprAuth(unittest.TestCase):
-
- htpasswd = HTPasswdAprAuth(__file__)
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_des(self):
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('des'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('des'+key))
-
- def test_authenticate_md5(self):
- if not self.htpasswd.apr:
- raise unittest.SkipTest("libaprutil-1 not found")
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('md5'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('md5'+key))
-
- def test_authenticate_sha(self):
- if not self.htpasswd.apr:
- raise unittest.SkipTest("libaprutil-1 not found")
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('sha'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('sha'+key))
-
- def test_authenticate_unknown(self):
- if self.htpasswd.authenticate('foo', 'bar') == True:
- self.fail("authenticate succeed for 'foo:bar'")
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wopassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', '') == True:
- self.fail("authenticate succeed for %s w/o password"
- % (algo+'buildmaster'))
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wrongpassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', algo) == True:
- self.fail("authenticate succeed for %s w/ wrong password"
- % (algo+'buildmaster'))
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py
deleted file mode 100644
index d27dc193..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-"""
-Test Passwords
-desbuildmaster:yifux5rkzvI5w
-desbuildslave:W8SPURMnCs7Tc
-desbuildbot:IzclhyfHAq6Oc
-"""
-
-
-from twisted.trial import unittest
-
-from buildbot.status.web.auth import HTPasswdAuth
-from buildbot.test.util import compat
-
-class TestHTPasswdAuth(unittest.TestCase):
-
- htpasswd = HTPasswdAuth(__file__)
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_des(self):
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('des'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('des'+key))
-
- def test_authenticate_unknown(self):
- if self.htpasswd.authenticate('foo', 'bar') == True:
- self.fail("authenticate succeed for 'foo:bar'")
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wopassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', '') == True:
- self.fail("authenticate succeed for %s w/o password"
- % (algo+'buildmaster'))
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wrongpassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', algo) == True:
- self.fail("authenticate succeed for %s w/ wrong password"
- % (algo+'buildmaster'))
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py
deleted file mode 100644
index a38201a2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildbot.status.web.authz import Authz
-from buildbot.status.web.auth import IAuth, AuthBase
-
-class StubRequest(object):
- # all we need from a request is username/password
- def __init__(self, username=None, passwd=None):
- self.args = {
- 'username' : [ username ],
- 'passwd' : [ passwd ],
- }
- self.received_cookies = {}
- self.send_cookies = []
- def getUser(self):
- return ''
-
- def getPassword(self):
- return None
- def addCookie(self, key, cookie, expires, path):
- self.send_cookies.append((key, cookie, expires, path))
-
-class StubHttpAuthRequest(object):
- # all we need from a request is username/password
- def __init__(self, username, passwd):
- self.args = {}
- self.username = username
- self.passwd = passwd
-
- def getUser(self):
- return self.username
-
- def getPassword(self):
- return self.passwd
-
-class StubAuth(AuthBase):
- implements(IAuth)
- def __init__(self, user):
- self.user = user
-
- def authenticate(self, user, pw):
- return user == self.user
-class TestAuthz(unittest.TestCase):
-
- def test_actionAllowed_Defaults(self):
- "by default, nothing is allowed"
- z = Authz()
- self.failedActions = []
- self.dl = []
- for a in Authz.knownActions:
- md = z.actionAllowed(a, StubRequest('foo', 'bar'))
- def check(res):
- if res:
- self.failedActions.append(a)
- return
- md.addCallback(check)
- self.dl.append(md)
- d = defer.DeferredList(self.dl)
- def check_failed(_):
- if self.failedActions:
- raise unittest.FailTest("action(s) %s do not default to False"
- % (self.failedActions,))
- d.addCallback(check_failed)
- return d
-
- def test_actionAllowed_Positive(self):
- "'True' should always permit access"
- z = Authz(forceBuild=True)
- d = z.actionAllowed('forceBuild', StubRequest('foo', 'bar'))
- def check(res):
- self.assertEqual(res, True)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthPositive(self):
- z = Authz(auth=StubAuth('jrobinson'),
- stopBuild='auth')
- d = z.actionAllowed('stopBuild', StubRequest('jrobinson', 'bar'))
- def check(res):
- self.assertEqual(res, True)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthNegative(self):
- z = Authz(auth=StubAuth('jrobinson'),
- stopBuild='auth')
- d = z.actionAllowed('stopBuild', StubRequest('apeterson', 'bar'))
- def check(res):
- self.assertEqual(res, False)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthCallable(self):
- myargs = []
- def myAuthzFn(*args):
- myargs.extend(args)
- z = Authz(auth=StubAuth('uu'),
- stopBuild=myAuthzFn)
- d = z.actionAllowed('stopBuild', StubRequest('uu', 'shh'), 'arg', 'arg2')
- def check(res):
- self.assertEqual(myargs, ['uu', 'arg', 'arg2'])
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthCallableTrue(self):
- def myAuthzFn(*args):
- return True
- z = Authz(auth=StubAuth('uu'),
- stopBuild=myAuthzFn)
- d = z.actionAllowed('stopBuild', StubRequest('uu', 'shh'))
- def check(res):
- self.assertEqual(res, True)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthCallableFalse(self):
- def myAuthzFn(*args):
- return False
- z = Authz(auth=StubAuth('uu'),
- stopBuild=myAuthzFn)
- d = z.actionAllowed('stopBuild', StubRequest('uu', 'shh'))
- def check(res):
- self.assertEqual(res, False)
- d.addCallback(check)
- return d
-
- def test_advertiseAction_False(self):
- z = Authz(forceBuild = False)
- assert not z.advertiseAction('forceBuild',StubRequest())
-
- def test_advertiseAction_True(self):
- z = Authz(forceAllBuilds = True)
- assert z.advertiseAction('forceAllBuilds',StubRequest())
-
- def test_advertiseAction_auth(self):
- z = Authz(stopBuild = 'auth')
- assert not z.advertiseAction('stopBuild',StubRequest())
-
- def test_advertiseAction_auth_authenticated(self):
- z = Authz(auth=StubAuth('uu'),stopBuild = 'auth')
- r = StubRequest('uu','aa')
- d = z.login(r)
- def check(c):
- assert z.advertiseAction('stopBuild',r)
- d.addCallback(check)
-
- def test_advertiseAction_callable(self):
- z = Authz(auth=StubAuth('uu'), stopAllBuilds = lambda u : False)
- r = StubRequest('uu','aa')
- d = z.login(r)
- @d.addCallback
- def check(c):
- assert z.advertiseAction('stopAllBuilds',r)
- return d
-
- def test_authenticated_False(self):
- z = Authz(forceBuild = False)
- assert not z.authenticated(StubRequest())
-
- def test_authenticated_True(self):
- z = Authz(auth=StubAuth('uu'), forceBuild = True)
- r = StubRequest('uu','aa')
- d = z.login(r)
- @d.addCallback
- def check(c):
- assert z.authenticated(r)
- return d
-
- def test_authenticated_http_False(self):
- z = Authz(useHttpHeader = True)
- assert not z.authenticated(StubRequest())
-
- def test_authenticated_http_True(self):
- z = Authz(useHttpHeader = True)
- assert z.authenticated(StubHttpAuthRequest('foo', 'bar'))
-
- def test_constructor_invalidAction(self):
- self.assertRaises(ValueError, Authz, someRandomAction=3)
-
- def test_getUsername_http(self):
- z = Authz(useHttpHeader = True)
- assert z.getUsername(StubHttpAuthRequest('foo', 'bar')) == 'foo'
-
- def test_getPassword_http(self):
- z = Authz(useHttpHeader = True)
- assert z.getPassword(StubHttpAuthRequest('foo', 'bar')) == 'bar'
-
- def test_getUsername_http_missing(self):
- z = Authz(useHttpHeader = True)
- assert z.getUsername(StubRequest('foo', 'bar')) == ''
-
- def test_getPassword_http_missing(self):
- z = Authz(useHttpHeader = True)
- assert z.getPassword(StubRequest('foo', 'bar')) == None
-
- def test_getUsername_request(self):
- z = Authz()
- assert z.getUsername(StubRequest('foo', 'bar')) == 'foo'
-
- def test_getPassword_request(self):
- z = Authz()
- assert z.getPassword(StubRequest('foo', 'bar')) == 'bar'
-
- def test_advertiseAction_invalidAction(self):
- z = Authz()
- self.assertRaises(KeyError, z.advertiseAction, 'someRandomAction', StubRequest('snow', 'foo'))
-
- def test_actionAllowed_invalidAction(self):
- z = Authz()
- self.assertRaises(KeyError, z.actionAllowed, 'someRandomAction', StubRequest('snow', 'foo'))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py
deleted file mode 100644
index a7d007c0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from buildbot.status.web import base
-from twisted.internet import defer
-from twisted.trial import unittest
-
-from buildbot.test.fake.web import FakeRequest
-
-class ActionResource(unittest.TestCase):
-
- def test_ActionResource_success(self):
-
- class MyActionResource(base.ActionResource):
- def performAction(self, request):
- self.got_request = request
- return defer.succeed('http://buildbot.net')
-
- rsrc = MyActionResource()
- request = FakeRequest()
- rsrc.render(request)
- d = request.deferred
-
- def check(_):
- self.assertIdentical(rsrc.got_request, request)
- self.assertTrue(request.finished)
- self.assertIn('buildbot.net', request.written)
- self.assertEqual(request.redirected_to, 'http://buildbot.net')
- d.addCallback(check)
- return d
-
- def test_ActionResource_exception(self):
-
- class MyActionResource(base.ActionResource):
- def performAction(self, request):
- return defer.fail(RuntimeError('sacrebleu'))
-
- rsrc = MyActionResource()
- request = FakeRequest()
- rsrc.render(request)
- d = request.deferred
-
- def check(f):
- f.trap(RuntimeError)
- # pass - all good!
- d.addErrback(check)
- return d
-
-class Functions(unittest.TestCase):
-
- def do_test_getRequestCharset(self, hdr, exp):
- req = mock.Mock()
- req.getHeader.return_value = hdr
-
- self.assertEqual(base.getRequestCharset(req), exp)
-
- def fakeRequest(self, prepath):
- r = mock.Mock()
- r.prepath = prepath
- return r
-
- def test_getRequestCharset_empty(self):
- return self.do_test_getRequestCharset(None, 'utf-8')
-
- def test_getRequestCharset_specified(self):
- return self.do_test_getRequestCharset(
- 'application/x-www-form-urlencoded ; charset=ISO-8859-1',
- 'ISO-8859-1')
-
- def test_getRequestCharset_other_params(self):
- return self.do_test_getRequestCharset(
- 'application/x-www-form-urlencoded ; charset=UTF-16 ; foo=bar',
- 'UTF-16')
-
- def test_path_to_root_from_root(self):
- self.assertEqual(base.path_to_root(self.fakeRequest([])),
- './')
-
- def test_path_to_root_from_one_level(self):
- self.assertEqual(base.path_to_root(self.fakeRequest(['waterfall'])),
- './')
-
- def test_path_to_root_from_two_level(self):
- self.assertEqual(base.path_to_root(self.fakeRequest(['a', 'b'])),
- '../')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py
deleted file mode 100644
index 692ee4b4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.web import change_hook
-from buildbot.util import json
-from buildbot.test.util import compat
-from buildbot.test.fake.web import FakeRequest
-
-from twisted.trial import unittest
-
-class TestChangeHookUnconfigured(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- self.changeHook = change_hook.ChangeHookResource()
-
- # A bad URI should cause an exception inside check_hook.
- # After writing the test, it became apparent this can't happen.
- # I'll leave the test anyway
- def testDialectReMatchFail(self):
- self.request.uri = "/garbage/garbage"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "URI doesn't match change_hook regex: /garbage/garbage"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- d.addCallback(check)
- return d
-
- def testUnkownDialect(self):
- self.request.uri = "/change_hook/garbage"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "The dialect specified, 'garbage', wasn't whitelisted in change_hook"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- d.addCallback(check)
- return d
-
- def testDefaultDialect(self):
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "The dialect specified, 'base', wasn't whitelisted in change_hook"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- d.addCallback(check)
- return d
-
-class TestChangeHookConfigured(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- self.changeHook = change_hook.ChangeHookResource(dialects={'base' : True})
-
- def testDefaultDialectGetNullChange(self):
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- self.assertEquals(len(self.request.addedChanges), 1)
- change = self.request.addedChanges[0]
- self.assertEquals(change["category"], None)
- self.assertEquals(len(change["files"]), 0)
- self.assertEquals(change["repository"], None)
- self.assertEquals(change["when"], None)
- self.assertEquals(change["author"], None)
- self.assertEquals(change["revision"], None)
- self.assertEquals(change["comments"], None)
- self.assertEquals(change["project"], None)
- self.assertEquals(change["branch"], None)
- self.assertEquals(change["revlink"], None)
- self.assertEquals(len(change["properties"]), 0)
- self.assertEquals(change["revision"], None)
- d.addCallback(check_changes)
- return d
-
- # Test 'base' hook with attributes. We should get a json string representing
- # a Change object as a dictionary. All values show be set.
- def testDefaultDialectWithChange(self):
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- self.request.args = { "category" : ["mycat"],
- "files" : [json.dumps(['file1', 'file2'])],
- "repository" : ["myrepo"],
- "when" : ["1234"],
- "author" : ["Santa Claus"],
- "number" : ["2"],
- "comments" : ["a comment"],
- "project" : ["a project"],
- "at" : ["sometime"],
- "branch" : ["a branch"],
- "revlink" : ["a revlink"],
- "properties" : [json.dumps( { "prop1" : "val1", "prop2" : "val2" })],
- "revision" : ["99"] }
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- self.assertEquals(len(self.request.addedChanges), 1)
- change = self.request.addedChanges[0]
- self.assertEquals(change["category"], "mycat")
- self.assertEquals(change["repository"], "myrepo")
- self.assertEquals(change["when"], 1234)
- self.assertEquals(change["author"], "Santa Claus")
- self.assertEquals(change["src"], None)
- self.assertEquals(change["revision"], "99")
- self.assertEquals(change["comments"], "a comment")
- self.assertEquals(change["project"], "a project")
- self.assertEquals(change["branch"], "a branch")
- self.assertEquals(change["revlink"], "a revlink")
- self.assertEquals(change['properties'], dict(prop1='val1', prop2='val2'))
- self.assertEquals(change['files'], ['file1', 'file2'])
- d.addCallback(check_changes)
- return d
-
- @compat.usesFlushLoggedErrors
- def testDefaultWithNoChange(self):
- self.request = FakeRequest()
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- def namedModuleMock(name):
- if name == 'buildbot.status.web.hooks.base':
- class mock_hook_module(object):
- def getChanges(self, request, options):
- raise AssertionError
- return mock_hook_module()
- self.patch(change_hook, "namedModule", namedModuleMock)
-
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "Error processing changes."
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(500, expected)
- self.assertEqual(len(self.flushLoggedErrors(AssertionError)), 1)
-
- d.addCallback(check_changes)
- return d
-
-class TestChangeHookConfiguredBogus(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- self.changeHook = change_hook.ChangeHookResource(dialects={'garbage' : True})
-
- @compat.usesFlushLoggedErrors
- def testBogusDialect(self):
- self.request.uri = "/change_hook/garbage"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "Error processing changes."
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(500, expected)
- self.assertEqual(len(self.flushLoggedErrors()), 1)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py
deleted file mode 100644
index dabc5118..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import buildbot.status.web.change_hook as change_hook
-from buildbot.test.fake.web import FakeRequest
-from buildbot.test.util import compat
-
-from twisted.trial import unittest
-
-# Sample GITHUB commit payload from http://help.github.com/post-receive-hooks/
-# Added "modfied" and "removed", and change email
-
-gitJsonPayload = """
-{
- "before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
- "repository": {
- "url": "http://github.com/defunkt/github",
- "name": "github",
- "description": "You're lookin' at it.",
- "watchers": 5,
- "forks": 2,
- "private": 1,
- "owner": {
- "email": "fred@flinstone.org",
- "name": "defunkt"
- }
- },
- "commits": [
- {
- "id": "41a212ee83ca127e3c8cf465891ab7216a705f59",
- "url": "http://github.com/defunkt/github/commit/41a212ee83ca127e3c8cf465891ab7216a705f59",
- "author": {
- "email": "fred@flinstone.org",
- "name": "Fred Flinstone"
- },
- "message": "okay i give in",
- "timestamp": "2008-02-15T14:57:17-08:00",
- "added": ["filepath.rb"]
- },
- {
- "id": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "url": "http://github.com/defunkt/github/commit/de8251ff97ee194a289832576287d6f8ad74e3d0",
- "author": {
- "email": "fred@flinstone.org",
- "name": "Fred Flinstone"
- },
- "message": "update pricing a tad",
- "timestamp": "2008-02-15T14:36:34-08:00",
- "modified": ["modfile"],
- "removed": ["removedFile"]
- }
- ],
- "after": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "ref": "refs/heads/master"
-}
-"""
-
-gitJsonPayloadNonBranch = """
-{
- "before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
- "repository": {
- "url": "http://github.com/defunkt/github",
- "name": "github",
- "description": "You're lookin' at it.",
- "watchers": 5,
- "forks": 2,
- "private": 1,
- "owner": {
- "email": "fred@flinstone.org",
- "name": "defunkt"
- }
- },
- "commits": [
- {
- "id": "41a212ee83ca127e3c8cf465891ab7216a705f59",
- "url": "http://github.com/defunkt/github/commit/41a212ee83ca127e3c8cf465891ab7216a705f59",
- "author": {
- "email": "fred@flinstone.org",
- "name": "Fred Flinstone"
- },
- "message": "okay i give in",
- "timestamp": "2008-02-15T14:57:17-08:00",
- "added": ["filepath.rb"]
- }
- ],
- "after": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "ref": "refs/garbage/master"
-}
-"""
-
-gitJsonPayloadEmpty = """
-{
- "before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
- "repository": {
- "url": "http://github.com/defunkt/github",
- "name": "github",
- "description": "You're lookin' at it.",
- "watchers": 5,
- "forks": 2,
- "private": 1,
- "owner": {
- "email": "fred@flinstone.org",
- "name": "defunkt"
- }
- },
- "commits": [
- ],
- "after": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "ref": "refs/heads/master"
-}
-"""
-class TestChangeHookConfiguredWithGitChange(unittest.TestCase):
- def setUp(self):
- self.changeHook = change_hook.ChangeHookResource(dialects={'github' : True})
-
- # Test 'base' hook with attributes. We should get a json string representing
- # a Change object as a dictionary. All values show be set.
- def testGitWithChange(self):
- changeDict={"payload" : [gitJsonPayload]}
- self.request = FakeRequest(changeDict)
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- self.assertEquals(len(self.request.addedChanges), 2)
- change = self.request.addedChanges[0]
-
- self.assertEquals(change['files'], ['filepath.rb'])
- self.assertEquals(change["repository"], "http://github.com/defunkt/github")
- self.assertEquals(change["when"], 1203116237)
- self.assertEquals(change["who"], "Fred Flinstone <fred@flinstone.org>")
- self.assertEquals(change["revision"], '41a212ee83ca127e3c8cf465891ab7216a705f59')
- self.assertEquals(change["comments"], "okay i give in")
- self.assertEquals(change["branch"], "master")
- self.assertEquals(change["revlink"], "http://github.com/defunkt/github/commit/41a212ee83ca127e3c8cf465891ab7216a705f59")
-
- change = self.request.addedChanges[1]
- self.assertEquals(change['files'], [ 'modfile', 'removedFile' ])
- self.assertEquals(change["repository"], "http://github.com/defunkt/github")
- self.assertEquals(change["when"], 1203114994)
- self.assertEquals(change["who"], "Fred Flinstone <fred@flinstone.org>")
- self.assertEquals(change["src"], "git")
- self.assertEquals(change["revision"], 'de8251ff97ee194a289832576287d6f8ad74e3d0')
- self.assertEquals(change["comments"], "update pricing a tad")
- self.assertEquals(change["branch"], "master")
- self.assertEquals(change["revlink"], "http://github.com/defunkt/github/commit/de8251ff97ee194a289832576287d6f8ad74e3d0")
-
- d.addCallback(check_changes)
- return d
-
- @compat.usesFlushLoggedErrors
- def testGitWithNoJson(self):
- self.request = FakeRequest()
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "Error processing changes."
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(500, expected)
- self.assertEqual(len(self.flushLoggedErrors()), 1)
-
- d.addCallback(check_changes)
- return d
-
- def testGitWithNoChanges(self):
- changeDict={"payload" : [gitJsonPayloadEmpty]}
- self.request = FakeRequest(changeDict)
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "no changes found"
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
-
- d.addCallback(check_changes)
- return d
-
- def testGitWithNonBranchChanges(self):
- changeDict={"payload" : [gitJsonPayloadNonBranch]}
- self.request = FakeRequest(changeDict)
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "no changes found"
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
-
- d.addCallback(check_changes)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py
deleted file mode 100644
index 2eb30674..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright 2011 Louis Opter <kalessin@kalessin.fr>
-#
-# Written from the github change hook unit test
-
-import StringIO
-
-import buildbot.status.web.change_hook as change_hook
-from buildbot.test.fake.web import FakeRequest
-
-from twisted.trial import unittest
-
-# Sample Google Code commit payload extracted from a Google Code test project
-# {
-# "repository_path": "https://code.google.com/p/webhook-test/",
-# "project_name": "webhook-test",
-# "revision_count": 1,
-# "revisions": [
-# {
-# "added": [],
-# "parents": ["6574485e26a09a0e743e0745374056891d6a836a"],
-# "author": "Louis Opter \\u003Clouis@lse.epitech.net\\u003E",
-# "url": "http://webhook-test.googlecode.com/hg-history/68e5df283a8e751cdbf95516b20357b2c46f93d4/",
-# "timestamp": 1324082130,
-# "message": "Print a message",
-# "path_count": 1,
-# "removed": [],
-# "modified": ["/CMakeLists.txt"],
-# "revision": "68e5df283a8e751cdbf95516b20357b2c46f93d4"
-# }
-# ]
-# }
-googleCodeJsonBody = '{"repository_path":"https://code.google.com/p/webhook-test/","project_name":"webhook-test","revisions":[{"added":[],"parents":["6574485e26a09a0e743e0745374056891d6a836a"],"author":"Louis Opter \u003Clouis@lse.epitech.net\u003E","url":"http://webhook-test.googlecode.com/hg-history/68e5df283a8e751cdbf95516b20357b2c46f93d4/","timestamp":1324082130,"message":"Print a message","path_count":1,"removed":[],"modified":["/CMakeLists.txt"],"revision":"68e5df283a8e751cdbf95516b20357b2c46f93d4"}],"revision_count":1}'
-
-class TestChangeHookConfiguredWithGoogleCodeChange(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- # Google Code simply transmit the payload as an UTF-8 JSON body
- self.request.content = StringIO.StringIO(googleCodeJsonBody)
- self.request.received_headers = {
- 'Google-Code-Project-Hosting-Hook-Hmac': '85910bf93ba5c266402d9328b0c7a856',
- 'Content-Length': '509',
- 'Accept-Encoding': 'gzip',
- 'User-Agent': 'Google Code Project Hosting (+http://code.google.com/p/support/wiki/PostCommitWebHooks)',
- 'Host': 'buildbot6-lopter.dotcloud.com:19457',
- 'Content-Type': 'application/json; charset=UTF-8'
- }
-
- self.changeHook = change_hook.ChangeHookResource(dialects={
- 'googlecode': {
- 'secret_key': 'FSP3p-Ghdn4T0oqX',
- 'branch': 'test'
- }
- })
-
- # Test 'base' hook with attributes. We should get a json string representing
- # a Change object as a dictionary. All values show be set.
- def testGoogleCodeWithHgChange(self):
- self.request.uri = "/change_hook/googlecode"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- # Only one changeset has been submitted.
- self.assertEquals(len(self.request.addedChanges), 1)
-
- # First changeset.
- change = self.request.addedChanges[0]
- self.assertEquals(change['files'], ['/CMakeLists.txt'])
- self.assertEquals(change["repository"], "https://code.google.com/p/webhook-test/")
- self.assertEquals(change["when"], 1324082130)
- self.assertEquals(change["author"], "Louis Opter <louis@lse.epitech.net>")
- self.assertEquals(change["revision"], '68e5df283a8e751cdbf95516b20357b2c46f93d4')
- self.assertEquals(change["comments"], "Print a message")
- self.assertEquals(change["branch"], "test")
- self.assertEquals(change["revlink"], "http://webhook-test.googlecode.com/hg-history/68e5df283a8e751cdbf95516b20357b2c46f93d4/")
-
- d.addCallback(check_changes)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py
deleted file mode 100644
index fca1b66e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import base
-import buildbot.status.web.change_hook as change_hook
-from buildbot.test.fake.web import FakeRequest
-from buildbot.changes.manager import ChangeManager
-
-
-class TestPollingChangeHook(unittest.TestCase):
- class Subclass(base.PollingChangeSource):
- pollInterval = None
- called = False
-
- def poll(self):
- self.called = True
-
- def setUpRequest(self, args, options=True):
- self.changeHook = change_hook.ChangeHookResource(dialects={'poller' : options})
-
- self.request = FakeRequest(args=args)
- self.request.uri = "/change_hook/poller"
- self.request.method = "GET"
-
- master = self.request.site.buildbot_service.master
- master.change_svc = ChangeManager(master)
-
- self.changesrc = self.Subclass("example", None)
- self.changesrc.setServiceParent(master.change_svc)
-
- self.disabledChangesrc = self.Subclass("disabled", None)
- self.disabledChangesrc.setServiceParent(master.change_svc)
-
- anotherchangesrc = base.ChangeSource()
- anotherchangesrc.setName("notapoller")
- anotherchangesrc.setServiceParent(master.change_svc)
-
- return self.request.test_render(self.changeHook)
-
- @defer.inlineCallbacks
- def test_no_args(self):
- yield self.setUpRequest({})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, True)
-
- @defer.inlineCallbacks
- def test_no_poller(self):
- yield self.setUpRequest({"poller": ["nosuchpoller"]})
- expected = "Could not find pollers: nosuchpoller"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- self.assertEqual(self.changesrc.called, False)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_invalid_poller(self):
- yield self.setUpRequest({"poller": ["notapoller"]})
- expected = "Could not find pollers: notapoller"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- self.assertEqual(self.changesrc.called, False)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_trigger_poll(self):
- yield self.setUpRequest({"poller": ["example"]})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_allowlist_deny(self):
- yield self.setUpRequest({"poller": ["disabled"]}, options={"allowed": ["example"]})
- expected = "Could not find pollers: disabled"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- self.assertEqual(self.changesrc.called, False)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_allowlist_allow(self):
- yield self.setUpRequest({"poller": ["example"]}, options={"allowed": ["example"]})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_allowlist_all(self):
- yield self.setUpRequest({}, options={"allowed": ["example"]})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, False)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py
deleted file mode 100644
index 4abe1573..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import buildbot.status.web.base as wb
-import jinja2, re
-
-from twisted.trial import unittest
-
-class RevisionLinks(unittest.TestCase):
- """
- Test webstatus revision link filters
- """
-
- def setUp(self):
- pass
-
- def _test(self, env, should_have_links=True):
- for name in ['shortrev', 'revlink']:
- f = env.filters[name]
- for r in [None, 'repo', 'repo2', 'sub/repo']:
- self.assertNotSubstring('<a', f(None, r), 'repo: %s' % r)
- if should_have_links:
- self.assertSubstring('<a', f(1234, r), 'repo: %s' % r)
- self.assertSubstring('<a', f('deadbeef1234', r), 'repo: %s' % r)
- else:
- self.assertNotSubstring('<a', f(1234, r), 'repo: %s' % r)
- self.assertNotSubstring('<a', f('deadbeef1234', r), 'repo: %s' % r)
-
- def test_default(self):
- env = wb.createJinjaEnv()
- self._test(env, False)
-
- def test_format(self):
- env = wb.createJinjaEnv('http://myserver.net/repo/%s')
- self._test(env)
-
- def test_dict(self):
- env = wb.createJinjaEnv({None: 'http://default.net/repo/%s',
- 'repo': 'http://myserver.net/repo/%s',
- 'repo2': 'http://myserver2.net/repo/%s',
- 'sub/repo': 'http://otherserver.com/%s'})
- self._test(env)
-
- def test_callable(self):
- def my_revlink(rev, repo):
- import urllib
- if not rev:
- return None
- if not repo:
- repo = 'main'
- rev = urllib.quote(rev)
- repo = urllib.quote(repo)
- return 'http://myserver.net/repos/%s/rev/%s' % (repo, rev)
-
- env = wb.createJinjaEnv(my_revlink)
- self._test(env)
-
-
- def test_template(self):
- template_str = '''{{ rev|revlink('repo') }} - {{ rev|shortrev('repo') }}'''
- env = wb.createJinjaEnv(revlink='http://myserver.net/repo/%s')
- template = env.from_string(template_str)
-
- rev = '1234567890' * 4 # reasonably long
- html = template.render(rev=rev)
- self.assertSubstring('http://myserver.net/repo/%s' % rev, html)
- self.assertSubstring('...', html) # did it get shortened?
- self.assertEquals(html.count('<a'), 3) # one in revlink, two in shortrev
-
-
-class ChangeCommentLinks(unittest.TestCase):
- """
- Tests webstatus changecomment link filter
- """
-
- def setUp(self):
- pass
-
- def _test(self, env):
- f = env.filters['changecomment']
- for p in [None, 'project1', 'project2']:
- self.assertNotSubstring('<a', f('', p))
- self.assertNotSubstring('<a', f('There is no ticket...', p))
- self.assertSubstring('<a', f('There is a ticket #123', p))
- self.assertEquals(f('There are two tickets #123 and #456', p).count("<a"), 2)
-
-
- def test_default(self):
- env = wb.createJinjaEnv()
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f(None, ''))
- self.assertNotSubstring('<a', f(None, 'There is no ticket #123'))
- self.assertNotSubstring('<a', f('project', ''))
- self.assertNotSubstring('<a', f('project', 'There is no ticket #123'))
-
- def test_tuple2(self):
- env = wb.createJinjaEnv(
- changecommentlink=(r'#(\d+)', r'http://buildbot.net/trac/ticket/\1'))
- self._test(env)
-
- def test_tuple3(self):
- env = wb.createJinjaEnv(
- changecommentlink=(r'#(\d+)', r'http://buildbot.net/trac/ticket/\1',
- r'Ticket #\1'))
- self._test(env)
-
- def test_dict_2tuple(self):
- env = wb.createJinjaEnv(
- changecommentlink={
- None: (r'#(\d+)', r'http://server/trac/ticket/\1'),
- 'project1': (r'#(\d+)', r'http://server/trac/p1/ticket/\1'),
- 'project2': (r'#(\d+)', r'http://server/trac/p2/ticket/\1')
- })
- self._test(env)
-
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f('fixed #123', 'nonexistingproject'))
-
-
- def test_dict_3tuple(self):
- env = wb.createJinjaEnv(
- changecommentlink={
- None: (r'#(\d+)', r'http://server/trac/ticket/\1', r'Ticket #\1'),
- 'project1': (r'#(\d+)', r'http://server/trac/p1/ticket/\1', r'Ticket #\1'),
- 'project2': (r'#(\d+)', r'http://server/bugzilla/p2/ticket/\1', r'Bug #\1')
- })
- self._test(env)
-
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f('fixed #123', 'nonexistingproject'))
-
- def test_callable(self):
- r1 = re.compile(r'#(\d+)')
- r2 = re.compile(r'bug ([a-eA-E0-9]+)')
-
- r1_sub = jinja2.Markup(r'<a href="\1" title="Ticket #\1">\g<0></a>')
- r2_sub = jinja2.Markup(r'<a href="\1" title="Bug \1"><img src="\bug.png">\g<0></a>')
-
- def my_changelink(changehtml, project):
- if project == 'nonexistingproject':
- return changehtml
-
- html1 = r1.sub(r1_sub, changehtml)
- html2 = r2.sub(r2_sub, html1)
- return html2
-
- env = wb.createJinjaEnv(changecommentlink=my_changelink)
- self._test(env)
-
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f('fixed #123', 'nonexistingproject'))
-
-
-class DictLinkfilter(unittest.TestCase):
- '''test the dictlink filter used for top-level links to
- projects and repostiories'''
-
- def test_default(self):
- f = wb.dictlinkfilter(None)
-
- self.assertNotSubstring('<a', f(None))
- self.assertNotSubstring('<a', f('repo'))
- self.assertNotSubstring('<a', f('repo2'))
-
- def test_simple(self):
- f = wb.dictlinkfilter({'repo': 'http://myrepo.net'})
-
- self.assertNotSubstring('<a', f(None))
- self.assertSubstring('<a', f('repo'))
- self.assertNotSubstring('<a', f('repo2'))
- self.assertEquals(f('bah'), 'bah') # passthrough
-
- def test_callable(self):
- def my_dictlink(value):
- if len(value) == 0:
- return 'http://thevoid.net'
- if len(value) == 1:
- return 'http://highlander.net'
- if value == 'hiddenproject':
- return None
- else:
- return 'http://legion.net'
-
- f = wb.dictlinkfilter(my_dictlink)
- self.assertSubstring('thevoid', f(''))
- self.assertSubstring('highlander', f('X'))
- self.assertSubstring('legion', f('many'))
- self.assertSubstring('<a', f('many'))
- self.assertNotSubstring('<a', f('hiddenproject'))
-
-
- def test_jinjaenv(self):
- env = wb.createJinjaEnv(repositories={'a': 'http://a.net'},
- projects={'b': 'http://b.net'})
-
- self.assertSubstring('<a href="http://a.net">', env.filters['repolink']('a'))
- self.assertSubstring('<a href="http://b.net">', env.filters['projectlink']('b'))
-
-
-class EmailFilter(unittest.TestCase):
- ''' test that the email filter actually obfuscates email addresses'''
-
- def test_emailfilter(self):
- self.assertNotSubstring('me@the.net', wb.emailfilter('me@the.net'))
- self.assertSubstring('me', wb.emailfilter('me@the.net'))
- self.assertSubstring('@', wb.emailfilter('me@the.net'))
- self.assertSubstring('the.net', wb.emailfilter('me@the.net'))
-
-
-
-class UserFilter(unittest.TestCase):
- '''test commit user names filtering, should be safe from complete
- email addresses and split user/email into separate HTML instances'''
-
- def test_emailfilter(self):
- self.assertNotSubstring('me@the.net', wb.userfilter('me@the.net'))
- self.assertNotSubstring('me@the.net', wb.userfilter('Me <me@the.net>'))
-
- def test_emailfilter_split(self):
- self.assertNotSubstring('Me <me', wb.userfilter('Me <me@the.net>'))
- self.assertSubstring('me', wb.userfilter('Me <me@the.net>'))
- self.assertSubstring('the.net', wb.userfilter('Me <me@the.net>'))
- self.assertSubstring('John Doe', wb.userfilter('John Doe <me@the.net>'))
-
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py
deleted file mode 100644
index d1300ac5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py
+++ /dev/null
@@ -1,617 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-from twisted.application import internet
-from twisted.internet import task, reactor
-from buildbot.status import words
-from buildbot.test.util import compat, config
-
-class TestIrcContactChannel(unittest.TestCase):
-
- def setUp(self):
- self.bot = mock.Mock(name='IRCStatusBot-instance')
- self.bot.nickname = 'nick'
- self.bot.notify_events = { 'success' : 1, 'failure' : 1 }
-
- # fake out subscription/unsubscription
- self.subscribed = False
- def subscribe(contact):
- self.subscribed = True
- self.bot.status.subscribe = subscribe
- def unsubscribe(contact):
- self.subscribed = False
- self.bot.status.unsubscribe = unsubscribe
-
- # fake out clean shutdown
- self.bot.master = mock.Mock(name='IRCStatusBot-instance.master')
- self.bot.master.botmaster = mock.Mock(name='IRCStatusBot-instance.master.botmaster')
- self.bot.master.botmaster.shuttingDown = False
- def cleanShutdown():
- self.bot.master.botmaster.shuttingDown = True
- self.bot.master.botmaster.cleanShutdown = cleanShutdown
- def cancelCleanShutdown():
- self.bot.master.botmaster.shuttingDown = False
- self.bot.master.botmaster.cancelCleanShutdown = cancelCleanShutdown
-
- self.contact = words.IRCContact(self.bot, '#buildbot')
-
- def patch_send(self):
- self.sent = []
- def send(msg):
- self.sent.append(msg)
- self.contact.send = send
-
- def patch_act(self):
- self.actions = []
- def act(msg):
- self.actions.append(msg)
- self.contact.act = act
-
- def do_test_command(self, command, args='', who='me', clock_ticks=None,
- exp_usage=True, exp_UsageError=False, allowShutdown=False,
- shuttingDown=False):
- cmd = getattr(self.contact, 'command_' + command.upper())
-
- if exp_usage:
- self.assertTrue(hasattr(cmd, 'usage'))
-
- clock = task.Clock()
- self.patch(reactor, 'callLater', clock.callLater)
- self.patch_send()
- self.patch_act()
- self.bot.factory.allowShutdown = allowShutdown
- self.bot.master.botmaster.shuttingDown = shuttingDown
-
- if exp_UsageError:
- try:
- cmd(args, who)
- except words.UsageError:
- return
- else:
- self.fail("no UsageError")
- else:
- cmd(args, who)
- if clock_ticks:
- clock.pump(clock_ticks)
-
- # tests
-
- def test_doSilly(self):
- clock = task.Clock()
- self.patch(reactor, 'callLater', clock.callLater)
- self.patch_send()
- silly_prompt, silly_response = self.contact.silly.items()[0]
-
- self.contact.doSilly(silly_prompt)
- clock.pump([0.5] * 20)
-
- self.assertEqual(self.sent, silly_response)
-
- # TODO: remaining commands
- # (all depend on status, which interface will change soon)
-
- def test_command_mute(self):
- self.do_test_command('mute')
- self.assertTrue(self.contact.muted)
-
- def test_command_unmute(self):
- self.contact.muted = True
- self.do_test_command('unmute')
- self.assertFalse(self.contact.muted)
-
- def test_command_unmute_not_muted(self):
- self.do_test_command('unmute')
- self.assertFalse(self.contact.muted)
- self.assertIn("hadn't told me to be quiet", self.sent[0])
-
- def test_command_help_noargs(self):
- self.do_test_command('help')
- self.assertIn('help on what', self.sent[0])
-
- def test_command_help_arg(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = 'foo - bar'
- self.do_test_command('help', args='foo')
- self.assertIn('Usage: foo - bar', self.sent[0])
-
- def test_command_help_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.do_test_command('help', args='foo')
- self.assertIn('No usage info for', self.sent[0])
-
- def test_command_help_dict_command(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- None : 'foo - bar'
- }
- self.do_test_command('help', args='foo')
- self.assertIn('Usage: foo - bar', self.sent[0])
-
- def test_command_help_dict_command_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {}
- self.do_test_command('help', args='foo')
- self.assertIn("No usage info for 'foo'", self.sent[0])
-
- def test_command_help_dict_command_arg(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- 'this' : 'foo this - bar'
- }
- self.do_test_command('help', args='foo this')
- self.assertIn('Usage: foo this - bar', self.sent[0])
-
- def test_command_help_dict_command_arg_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- # nothing for arg 'this'
- ('this', 'first') : 'foo this first - bar'
- }
- self.do_test_command('help', args='foo this')
- self.assertIn("No usage info for 'foo' 'this'", self.sent[0])
-
- def test_command_help_dict_command_arg_subarg(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- ('this', 'first') : 'foo this first - bar'
- }
- self.do_test_command('help', args='foo this first')
- self.assertIn('Usage: foo this first - bar', self.sent[0])
-
- def test_command_help_dict_command_arg_subarg_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- None : 'foo - bar',
- 'this' : 'foo this - bar',
- ('this', 'first') : 'foo this first - bar'
- # nothing for subarg 'missing'
- }
- self.do_test_command('help', args='foo this missing')
- self.assertIn("No usage info for 'foo' 'this' 'missing'", self.sent[0])
-
- def test_command_help_nosuch(self):
- self.do_test_command('help', args='foo', exp_UsageError=True)
-
- def test_command_shutdown(self):
- self.do_test_command('shutdown', exp_UsageError=True)
- self.assertEqual(self.bot.factory.allowShutdown, False)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
-
- def test_command_shutdown_dissalowed(self):
- self.do_test_command('shutdown', args='check', exp_UsageError=True)
- self.assertEqual(self.bot.factory.allowShutdown, False)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
-
- def test_command_shutdown_check_running(self):
- self.do_test_command('shutdown', args='check', allowShutdown=True, shuttingDown=False)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
- self.assertIn('buildbot is running', self.sent[0])
-
- def test_command_shutdown_check_shutting_down(self):
- self.do_test_command('shutdown', args='check', allowShutdown=True, shuttingDown=True)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, True)
- self.assertIn('buildbot is shutting down', self.sent[0])
-
- def test_command_shutdown_start(self):
- self.do_test_command('shutdown', args='start', allowShutdown=True, shuttingDown=False)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, True)
-
- def test_command_shutdown_stop(self):
- self.do_test_command('shutdown', args='stop', allowShutdown=True, shuttingDown=True)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
-
- def test_command_shutdown_now(self):
- stop = mock.Mock()
- self.patch(reactor, 'stop', stop)
- self.do_test_command('shutdown', args='now', allowShutdown=True)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
- stop.assert_called_with()
-
- def test_command_source(self):
- self.do_test_command('source')
- self.assertIn('My source', self.sent[0])
-
- def test_command_commands(self):
- self.do_test_command('commands')
- self.assertIn('buildbot commands', self.sent[0])
-
- def test_command_destroy(self):
- self.do_test_command('destroy', exp_usage=False)
- self.assertEqual(self.actions, [ 'readies phasers' ])
-
- def test_command_dance(self):
- self.do_test_command('dance', clock_ticks=[1.0]*10, exp_usage=False)
- self.assertTrue(self.sent) # doesn't matter what it sent
-
- def test_send(self):
- events = []
- def msgOrNotice(dest, msg):
- events.append((dest, msg))
- self.contact.bot.msgOrNotice = msgOrNotice
-
- self.contact.send("unmuted")
- self.contact.send(u"unmuted, unicode \N{SNOWMAN}")
- self.contact.muted = True
- self.contact.send("muted")
-
- self.assertEqual(events, [
- ('#buildbot', 'unmuted'),
- ('#buildbot', 'unmuted, unicode ?'),
- ])
-
- def test_act(self):
- events = []
- def describe(dest, msg):
- events.append((dest, msg))
- self.contact.bot.describe = describe
-
- self.contact.act("unmuted")
- self.contact.act(u"unmuted, unicode \N{SNOWMAN}")
- self.contact.muted = True
- self.contact.act("muted")
-
- self.assertEqual(events, [
- ('#buildbot', 'unmuted'),
- ('#buildbot', 'unmuted, unicode ?'),
- ])
-
- def test_handleMessage_silly(self):
- silly_prompt = self.contact.silly.keys()[0]
- self.contact.doSilly = mock.Mock()
- d = self.contact.handleMessage(silly_prompt, 'me')
- @d.addCallback
- def cb(_):
- self.contact.doSilly.assert_called_with(silly_prompt)
- return d
-
- def test_handleMessage_short_command(self):
- self.contact.command_TESTY = mock.Mock()
- d = self.contact.handleMessage('testy', 'me')
- @d.addCallback
- def cb(_):
- self.contact.command_TESTY.assert_called_with('', 'me')
- return d
-
- def test_handleMessage_long_command(self):
- self.contact.command_TESTY = mock.Mock()
- d = self.contact.handleMessage('testy westy boo', 'me')
- @d.addCallback
- def cb(_):
- self.contact.command_TESTY.assert_called_with('westy boo', 'me')
- return d
-
- def test_handleMessage_excited(self):
- self.patch_send()
- d = self.contact.handleMessage('hi!', 'me')
- @d.addCallback
- def cb(_):
- self.assertEqual(len(self.sent), 1) # who cares what it says..
- return d
-
- @compat.usesFlushLoggedErrors
- def test_handleMessage_exception(self):
- self.patch_send()
- def command_TESTY(msg, who):
- raise RuntimeError("FAIL")
- self.contact.command_TESTY = command_TESTY
- d = self.contact.handleMessage('testy boom', 'me')
- @d.addCallback
- def cb(_):
- self.assertEqual(self.sent,
- [ "Something bad happened (see logs)" ])
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- return d
-
- def test_handleMessage_UsageError(self):
- self.patch_send()
- def command_TESTY(msg, who):
- raise words.UsageError("oh noes")
- self.contact.command_TESTY = command_TESTY
- d = self.contact.handleMessage('testy boom', 'me')
- @d.addCallback
- def cb(_):
- self.assertEqual(self.sent, [ "oh noes" ])
- return d
-
- def test_handleAction_ignored(self):
- self.patch_act()
- self.contact.handleAction('waves hi', 'me')
- self.assertEqual(self.actions, [])
-
- def test_handleAction_kick(self):
- self.patch_act()
- self.contact.handleAction('kicks nick', 'me')
- self.assertEqual(self.actions, ['kicks back'])
-
- def test_handleAction_stpuid(self):
- self.patch_act()
- self.contact.handleAction('stupids nick', 'me')
- self.assertEqual(self.actions, ['stupids me too'])
-
- def test_unclosed_quote(self):
- self.do_test_command('list', args='args\'', exp_UsageError=True)
- self.do_test_command('status', args='args\'', exp_UsageError=True)
- self.do_test_command('notify', args='args\'', exp_UsageError=True)
- self.do_test_command('watch', args='args\'', exp_UsageError=True)
- self.do_test_command('force', args='args\'', exp_UsageError=True)
- self.do_test_command('stop', args='args\'', exp_UsageError=True)
- self.do_test_command('last', args='args\'', exp_UsageError=True)
- self.do_test_command('help', args='args\'', exp_UsageError=True)
-
-
-class FakeContact(object):
-
- def __init__(self, bot, name):
- self.bot = bot
- self.name = name
- self.messages = []
- self.actions = []
-
- def handleMessage(self, message, user):
- self.messages.append((message, user))
-
- def handleAction(self, data, user):
- self.actions.append((data, user))
-
-
-class TestIrcStatusBot(unittest.TestCase):
-
- def setUp(self):
- self.status = mock.Mock(name='status')
-
- def makeBot(self, *args, **kwargs):
- if not args:
- args = ('nick', 'pass', ['#ch'], [], self.status, [], {})
- return words.IrcStatusBot(*args, **kwargs)
-
- def test_msgOrNotice(self):
- b = self.makeBot(noticeOnChannel=False)
- b.notice = lambda d, m : evts.append(('n', d, m))
- b.msg = lambda d, m : evts.append(('m', d, m))
-
- evts = []
- b.msgOrNotice('nick', 'hi')
- self.assertEqual(evts, [('m', 'nick', 'hi')])
-
- evts = []
- b.msgOrNotice('#chan', 'hi')
- self.assertEqual(evts, [('m', '#chan', 'hi')])
-
- b.noticeOnChannel = True
-
- evts = []
- b.msgOrNotice('#chan', 'hi')
- self.assertEqual(evts, [('n', '#chan', 'hi')])
-
- def test_getContact(self):
- b = self.makeBot()
-
- c1 = b.getContact('c1')
- c2 = b.getContact('c2')
- c1b = b.getContact('c1')
-
- self.assertIdentical(c1, c1b)
- self.assertIsInstance(c2, words.IRCContact)
-
- def test_getContact_case_insensitive(self):
- b = self.makeBot()
-
- c1 = b.getContact('c1')
- c1b = b.getContact('C1')
-
- self.assertIdentical(c1, c1b)
-
- def test_privmsg_user(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', 'nick', 'hello')
-
- c = b.getContact('jimmy')
- self.assertEqual(c.messages, [('hello', 'jimmy')])
-
- def test_privmsg_user_uppercase(self):
- b = self.makeBot('NICK', 'pass', ['#ch'], [], self.status, [], {})
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', 'NICK', 'hello')
-
- c = b.getContact('jimmy')
- self.assertEqual(c.messages, [('hello', 'jimmy')])
-
- def test_privmsg_channel_unrelated(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', '#ch', 'hello')
-
- c = b.getContact('#ch')
- self.assertEqual(c.messages, [])
-
- def test_privmsg_channel_related(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', '#ch', 'nick: hello')
-
- c = b.getContact('#ch')
- self.assertEqual(c.messages, [(' hello', 'jimmy')])
-
- def test_action_unrelated(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.action('jimmy!~foo@bar', '#ch', 'waves')
-
- c = b.getContact('#ch')
- self.assertEqual(c.actions, [])
-
- def test_action_unrelated_buildbot(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.action('jimmy!~foo@bar', '#ch', 'waves at buildbot')# b.nickname is not 'buildbot'
-
- c = b.getContact('#ch')
- self.assertEqual(c.actions, [])
-
- def test_action_related(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.action('jimmy!~foo@bar', '#ch', 'waves at nick')
-
- c = b.getContact('#ch')
- self.assertEqual(c.actions, [('waves at nick', 'jimmy')])
-
- def test_signedOn(self):
- b = self.makeBot('nick', 'pass',
- ['#ch1', dict(channel='#ch2', password='sekrits')],
- ['jimmy', 'bobby'], self.status, [], {})
- evts = []
- def msg(d, m):
- evts.append(('m', d, m))
- b.msg = msg
- def join(channel, key):
- evts.append(('k', channel, key))
- b.join = join
- b.contactClass = FakeContact
-
- b.signedOn()
-
- self.assertEqual(sorted(evts), [
- ('k', '#ch1', None),
- ('k', '#ch2', 'sekrits'),
- ('m', 'Nickserv', 'IDENTIFY pass'),
- ])
- self.assertEqual(sorted(b.contacts.keys()),
- # channels don't get added until joined() is called
- sorted(['jimmy', 'bobby']))
-
- def test_joined(self):
- b = self.makeBot()
- b.joined('#ch1')
- b.joined('#ch2')
- self.assertEqual(sorted(b.contacts.keys()),
- sorted(['#ch1', '#ch2']))
-
- def test_other(self):
- # these methods just log, but let's get them covered anyway
- b = self.makeBot()
- b.left('#ch1')
- b.kickedFrom('#ch1', 'dustin', 'go away!')
-
-
-class TestIrcStatusFactory(unittest.TestCase):
-
- def makeFactory(self, *args, **kwargs):
- if not args:
- args = ('nick', 'pass', ['ch'], [], [], {})
- return words.IrcStatusFactory(*args, **kwargs)
-
- def test_shutdown(self):
- # this is kinda lame, but the factory would be better tested
- # in an integration-test environment
- f = self.makeFactory()
- self.assertFalse(f.shuttingDown)
- f.shutdown()
- self.assertTrue(f.shuttingDown)
-
-
-class TestIRC(config.ConfigErrorsMixin, unittest.TestCase):
-
- def makeIRC(self, **kwargs):
- kwargs.setdefault('host', 'localhost')
- kwargs.setdefault('nick', 'russo')
- kwargs.setdefault('channels', ['#buildbot'])
- self.factory = None
- def TCPClient(host, port, factory):
- client = mock.Mock(name='tcp-client')
- client.host = host
- client.port = port
- client.factory = factory
- # keep for later
- self.factory = factory
- self.client = client
- return client
- self.patch(internet, 'TCPClient', TCPClient)
- return words.IRC(**kwargs)
-
- def test_constr(self):
- irc = self.makeIRC(host='foo', port=123)
- self.client.setServiceParent.assert_called_with(irc)
- self.assertEqual(self.client.host, 'foo')
- self.assertEqual(self.client.port, 123)
- self.assertIsInstance(self.client.factory, words.IrcStatusFactory)
-
- def test_constr_args(self):
- # test that the args to IRC(..) make it all the way down to
- # the IrcStatusBot class
- self.makeIRC(
- host='host',
- nick='nick',
- channels=['channels'],
- pm_to_nicks=['pm', 'to', 'nicks'],
- port=1234,
- allowForce=True,
- categories=['categories'],
- password='pass',
- notify_events={ 'successToFailure': 1, },
- noticeOnChannel=True,
- showBlameList=False,
- useRevisions=True,
- useSSL=False,
- lostDelay=10,
- failedDelay=20,
- useColors=False)
-
- # patch it up
- factory = self.factory
- proto_obj = mock.Mock(name='proto_obj')
- factory.protocol = mock.Mock(name='protocol', return_value=proto_obj)
- factory.status = 'STATUS'
-
- # run it
- p = factory.buildProtocol('address')
- self.assertIdentical(p, proto_obj)
- factory.protocol.assert_called_with(
- 'nick', 'pass', ['channels'], ['pm', 'to', 'nicks'],
- factory.status, ['categories'], { 'successToFailure': 1 },
- noticeOnChannel=True,
- useColors=False,
- useRevisions=True,
- showBlameList=False)
-
- def test_allowForce_notBool(self):
- """
- When L{IRCClient} is called with C{allowForce} not a boolean,
- a config error is reported.
- """
- self.assertRaisesConfigError("allowForce must be boolean, not",
- lambda: self.makeIRC(allowForce=object()))
-
- def test_allowShutdown_notBool(self):
- """
- When L{IRCClient} is called with C{allowShutdown} not a boolean,
- a config error is reported.
- """
- self.assertRaisesConfigError("allowShutdown must be boolean, not",
- lambda: self.makeIRC(allowShutdown=object()))
-
- def test_service(self):
- irc = self.makeIRC()
- # just put it through its paces
- irc.startService()
- return irc.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py
deleted file mode 100644
index 5b5ce6b8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import sys
-from twisted.python import failure, runtime
-from twisted.internet import error, reactor
-from twisted.trial import unittest
-from buildbot.test.util import steps
-from buildbot.status.results import SUCCESS, FAILURE, EXCEPTION
-from buildbot.steps import master
-from buildbot.process.properties import WithProperties
-from buildbot.process.properties import Interpolate
-import pprint
-
-class TestMasterShellCommand(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- if runtime.platformType == 'win32':
- self.comspec = os.environ.get('COMPSPEC')
- os.environ['COMSPEC'] = r'C:\WINDOWS\system32\cmd.exe'
- return self.setUpBuildStep()
-
- def tearDown(self):
- if runtime.platformType == 'win32':
- if self.comspec:
- os.environ['COMSPEC'] = self.comspec
- else:
- del os.environ['COMSPEC']
- return self.tearDownBuildStep()
-
- def patchSpawnProcess(self, exp_cmd, exp_argv, exp_path, exp_usePTY,
- exp_env, outputs):
- def spawnProcess(pp, cmd, argv, path, usePTY, env):
- self.assertEqual([cmd, argv, path, usePTY, env],
- [exp_cmd, exp_argv, exp_path, exp_usePTY, exp_env])
- for output in outputs:
- if output[0] == 'out':
- pp.outReceived(output[1])
- elif output[0] == 'err':
- pp.errReceived(output[1])
- elif output[0] == 'rc':
- if output[1] != 0:
- so = error.ProcessTerminated(exitCode=output[1])
- else:
- so = error.ProcessDone(None)
- pp.processEnded(failure.Failure(so))
- self.patch(reactor, 'spawnProcess', spawnProcess)
-
- def test_real_cmd(self):
- cmd = [ sys.executable, '-c', 'print "hello"' ]
- self.setupStep(
- master.MasterShellCommand(command=cmd))
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "hello\r\n")
- else:
- self.expectLogfile('stdio', "hello\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- return self.runStep()
-
- def test_real_cmd_interrupted(self):
- cmd = [ sys.executable, '-c', 'while True: pass' ]
- self.setupStep(
- master.MasterShellCommand(command=cmd))
- self.expectLogfile('stdio', "")
- if runtime.platformType == 'win32':
- # windows doesn't have signals, so we don't get 'killed'
- self.expectOutcome(result=EXCEPTION,
- status_text=["failed (1)", "interrupted"])
- else:
- self.expectOutcome(result=EXCEPTION,
- status_text=["killed (9)", "interrupted"])
- d = self.runStep()
- self.step.interrupt("KILL")
- return d
-
- def test_real_cmd_fails(self):
- cmd = [ sys.executable, '-c', 'import sys; sys.exit(1)' ]
- self.setupStep(
- master.MasterShellCommand(command=cmd))
- self.expectLogfile('stdio', "")
- self.expectOutcome(result=FAILURE, status_text=["failed (1)"])
- return self.runStep()
-
- def test_constr_args(self):
- self.setupStep(
- master.MasterShellCommand(description='x', descriptionDone='y',
- env={'a':'b'}, path=['/usr/bin'], usePTY=True,
- command='true'))
-
- self.assertEqual(self.step.describe(), ['x'])
-
- if runtime.platformType == 'win32':
- exp_argv = [ r'C:\WINDOWS\system32\cmd.exe', '/c', 'true' ]
- else:
- exp_argv = [ '/bin/sh', '-c', 'true' ]
- self.patchSpawnProcess(
- exp_cmd=exp_argv[0], exp_argv=exp_argv,
- exp_path=['/usr/bin'], exp_usePTY=True, exp_env={'a':'b'},
- outputs=[
- ('out', 'hello!\n'),
- ('err', 'world\n'),
- ('rc', 0),
- ])
- self.expectOutcome(result=SUCCESS, status_text=['y'])
- return self.runStep()
-
- def test_env_subst(self):
- cmd = [ sys.executable, '-c', 'import os; print os.environ["HELLO"]' ]
- os.environ['WORLD'] = 'hello'
- self.setupStep(
- master.MasterShellCommand(command=cmd,
- env={'HELLO': '${WORLD}'}))
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "hello\r\n")
- else:
- self.expectLogfile('stdio', "hello\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- def _restore_env(res):
- del os.environ['WORLD']
- return res
- d = self.runStep()
- d.addBoth(_restore_env)
- return d
-
- def test_env_list_subst(self):
- cmd = [ sys.executable, '-c', 'import os; print os.environ["HELLO"]' ]
- os.environ['WORLD'] = 'hello'
- os.environ['LIST'] = 'world'
- self.setupStep(
- master.MasterShellCommand(command=cmd,
- env={'HELLO': ['${WORLD}', '${LIST}']}))
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "hello;world\r\n")
- else:
- self.expectLogfile('stdio', "hello:world\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- def _restore_env(res):
- del os.environ['WORLD']
- del os.environ['LIST']
- return res
- d = self.runStep()
- d.addBoth(_restore_env)
- return d
-
- def test_prop_rendering(self):
- cmd = [ sys.executable, '-c', WithProperties(
- 'import os; print "%s"; print os.environ[\"BUILD\"]',
- 'project') ]
- self.setupStep(
- master.MasterShellCommand(command=cmd,
- env={'BUILD': WithProperties('%s', "project")}))
- self.properties.setProperty("project", "BUILDBOT-TEST", "TEST")
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "BUILDBOT-TEST\r\nBUILDBOT-TEST\r\n")
- else:
- self.expectLogfile('stdio', "BUILDBOT-TEST\nBUILDBOT-TEST\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- return self.runStep()
-
- def test_constr_args_descriptionSuffix(self):
- self.setupStep(
- master.MasterShellCommand(description='x', descriptionDone='y',
- descriptionSuffix='z',
- env={'a':'b'}, path=['/usr/bin'], usePTY=True,
- command='true'))
-
- # call twice to make sure the suffix doesn't get double added
- self.assertEqual(self.step.describe(), ['x', 'z'])
- self.assertEqual(self.step.describe(), ['x', 'z'])
-
- if runtime.platformType == 'win32':
- exp_argv = [ r'C:\WINDOWS\system32\cmd.exe', '/c', 'true' ]
- else:
- exp_argv = [ '/bin/sh', '-c', 'true' ]
- self.patchSpawnProcess(
- exp_cmd=exp_argv[0], exp_argv=exp_argv,
- exp_path=['/usr/bin'], exp_usePTY=True, exp_env={'a':'b'},
- outputs=[
- ('out', 'hello!\n'),
- ('err', 'world\n'),
- ('rc', 0),
- ])
- self.expectOutcome(result=SUCCESS, status_text=['y', 'z'])
- return self.runStep()
-
-class TestSetProperty(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_simple(self):
- self.setupStep(master.SetProperty(property="testProperty", value=Interpolate("sch=%(prop:scheduler)s, slave=%(prop:slavename)s")))
- self.properties.setProperty('scheduler', 'force', source='SetProperty', runtime=True)
- self.properties.setProperty('slavename', 'testSlave', source='SetPropery', runtime=True)
- self.expectOutcome(result=SUCCESS, status_text=["SetProperty"])
- self.expectProperty('testProperty', 'sch=force, slave=testSlave', source='SetProperty')
- return self.runStep()
-
-class TestLogRenderable(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_simple(self):
- self.setupStep(master.LogRenderable(content=Interpolate('sch=%(prop:scheduler)s, slave=%(prop:slavename)s')))
- self.properties.setProperty('scheduler', 'force', source='TestSetProperty', runtime=True)
- self.properties.setProperty('slavename', 'testSlave', source='TestSetProperty', runtime=True)
- self.expectOutcome(result=SUCCESS, status_text=['LogRenderable'])
- self.expectLogfile('Output', pprint.pformat('sch=force, slave=testSlave'))
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py
deleted file mode 100644
index 07f3edef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.test.util import steps
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.steps import maxq
-from buildbot import config
-
-class TestShellCommandExecution(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_testdir_required(self):
- self.assertRaises(config.ConfigErrors, lambda : maxq.MaxQ())
-
- def test_success(self):
- self.setupStep(
- maxq.MaxQ(testdir='x'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="run_maxq.py x")
- + ExpectShell.log('stdio', stdout='no failures\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['maxq', 'tests'])
- return self.runStep()
-
- def test_nonzero_rc_no_failures(self):
- self.setupStep(
- maxq.MaxQ(testdir='x'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="run_maxq.py x")
- + ExpectShell.log('stdio', stdout='no failures\n')
- + 2
- )
- self.expectOutcome(result=FAILURE,
- status_text=['1', 'maxq', 'failures'])
- return self.runStep()
-
- def test_failures(self):
- self.setupStep(
- maxq.MaxQ(testdir='x'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="run_maxq.py x")
- + ExpectShell.log('stdio', stdout='\nTEST FAILURE: foo\n' * 10)
- + 2
- )
- self.expectOutcome(result=FAILURE,
- status_text=['10', 'maxq', 'failures'])
- return self.runStep()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py
deleted file mode 100644
index cec98927..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.results import SUCCESS
-from buildbot.steps.package.deb import lintian
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot import config
-
-class TestDebLintian(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_fileloc(self):
- self.assertRaises(config.ConfigErrors, lambda :
- lintian.DebLintian())
-
- def test_success(self):
- self.setupStep(lintian.DebLintian('foo_0.23_i386.changes'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['lintian', '-v', 'foo_0.23_i386.changes'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Lintian'])
- return self.runStep()
-
- def test_success_suppressTags(self):
- self.setupStep(lintian.DebLintian('foo_0.23_i386.changes',
- suppressTags=['bad-distribution-in-changes-file']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['lintian', '-v', 'foo_0.23_i386.changes',
- '--suppress-tags', 'bad-distribution-in-changes-file'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Lintian'])
- return self.runStep()
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py
deleted file mode 100644
index 975b431e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import stat
-import time
-
-from twisted.trial import unittest
-from buildbot.steps.package.deb import pbuilder
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-
-class TestDebPbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_new(self):
- self.setupStep(pbuilder.DebPbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_update(self):
- self.setupStep(pbuilder.DebPbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, 0, 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--update',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_buildonly(self):
- self.setupStep(pbuilder.DebPbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, int(time.time()), 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_architecture(self):
- self.setupStep(pbuilder.DebPbuilder(architecture='amd64'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-amd64-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-amd64-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--architecture', 'amd64'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder',
- '--architecture', 'amd64', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-amd64-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_distribution(self):
- self.setupStep(pbuilder.DebPbuilder(distribution='woody'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/woody-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/woody-local-buildbot.tgz',
- '--distribution', 'woody',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/woody-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_basetgz(self):
- self.setupStep(pbuilder.DebPbuilder(basetgz='/buildbot/%(distribution)s-%(architecture)s.tgz'))
- self.expectCommands(
- Expect('stat', {'file': '/buildbot/stable-local.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/buildbot/stable-local.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/buildbot/stable-local.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_mirror(self):
- self.setupStep(pbuilder.DebPbuilder(mirror='http://apt:9999/debian'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://apt:9999/debian'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_extrapackages(self):
- self.setupStep(pbuilder.DebPbuilder(extrapackages=['buildbot']))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--extrapackages', 'buildbot'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--extrapackages', 'buildbot'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_keyring(self):
- self.setupStep(pbuilder.DebPbuilder(keyring='/builbot/buildbot.gpg'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--debootstrapopts', '--keyring=/builbot/buildbot.gpg'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_components(self):
- self.setupStep(pbuilder.DebPbuilder(components='main universe'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--components', 'main universe'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
-class TestDebCowbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_new(self):
- self.setupStep(pbuilder.DebCowbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow/'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--create',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_update(self):
- self.setupStep(pbuilder.DebCowbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow/'})
- + Expect.update('stat', [stat.S_IFDIR, 99, 99, 1, 0, 0, 99, 0, 0, 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--update',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/',])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_buildonly(self):
- self.setupStep(pbuilder.DebCowbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow/'})
- + Expect.update('stat', [stat.S_IFDIR, 99, 99, 1, 0, 0, 99, 0, int(time.time()), 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_update_reg(self):
- self.setupStep(pbuilder.DebCowbuilder(basetgz='/var/cache/pbuilder/stable-local-buildbot.cow'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, 0, 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--update',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow'])
- + 1)
- self.expectOutcome(result=FAILURE, status_text=['PBuilder update.'])
- return self.runStep()
-
- def test_buildonly_reg(self):
- self.setupStep(pbuilder.DebCowbuilder(basetgz='/var/cache/pbuilder/stable-local-buildbot.cow'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, int(time.time()), 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow'])
- + 1)
- self.expectOutcome(result=FAILURE, status_text=['pdebuild', 'failed'])
- return self.runStep()
-
-class TestUbuPbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_distribution(self):
- self.assertRaises(config.ConfigErrors, lambda :
- pbuilder.UbuPbuilder())
-
- def test_new(self):
- self.setupStep(pbuilder.UbuPbuilder(distribution='oneiric'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/oneiric-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/oneiric-local-buildbot.tgz',
- '--distribution', 'oneiric',
- '--mirror', 'http://archive.ubuntu.com/ubuntu/',
- '--components', 'main universe'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/oneiric-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
-class TestUbuCowbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_distribution(self):
- self.assertRaises(config.ConfigErrors, lambda :
- pbuilder.UbuCowbuilder())
-
- def test_new(self):
- self.setupStep(pbuilder.UbuCowbuilder(distribution='oneiric'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/oneiric-local-buildbot.cow/'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--create',
- '--basepath', '/var/cache/pbuilder/oneiric-local-buildbot.cow/',
- '--distribution', 'oneiric',
- '--mirror', 'http://archive.ubuntu.com/ubuntu/',
- '--components', 'main universe'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/oneiric-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py
deleted file mode 100644
index df0e937b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.steps.package.rpm import mock
-from buildbot.status.results import SUCCESS
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-
-class TestMock(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_root(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mock.Mock())
-
- def test_class_attrs(self):
- step = self.setupStep(mock.Mock(root='TESTROOT'))
- self.assertEqual(step.command, ['mock', '--root', 'TESTROOT'])
-
- def test_success(self):
- self.setupStep(mock.Mock(root='TESTROOT'))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/build.log', 'build/root.log',
- 'build/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT'],
- logfiles={'build.log': 'build.log',
- 'root.log': 'root.log',
- 'state.log': 'state.log'})
- +0)
- self.expectOutcome(result=SUCCESS, status_text=["'mock", '--root', "...'"])
- return self.runStep()
-
- def test_resultdir_success(self):
- self.setupStep(mock.Mock(root='TESTROOT', resultdir='RESULT'))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/RESULT/build.log',
- 'build/RESULT/root.log',
- 'build/RESULT/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT',
- '--resultdir', 'RESULT'],
- logfiles={'build.log': 'RESULT/build.log',
- 'root.log': 'RESULT/root.log',
- 'state.log': 'RESULT/state.log'})
- +0)
- self.expectOutcome(result=SUCCESS, status_text=["'mock", '--root', "...'"])
- return self.runStep()
-
-
-
-class TestMockBuildSRPM(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_spec(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mock.MockBuildSRPM(root='TESTROOT'))
-
- def test_success(self):
- self.setupStep(mock.MockBuildSRPM(root='TESTROOT', spec="foo.spec"))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/build.log', 'build/root.log',
- 'build/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT',
- '--buildsrpm', '--spec', 'foo.spec',
- '--sources', '.'],
- logfiles={'build.log': 'build.log',
- 'root.log': 'root.log',
- 'state.log': 'state.log'},)
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['mock buildsrpm'])
- return self.runStep()
-
-class TestMockRebuild(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_srpm(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mock.MockRebuild(root='TESTROOT'))
-
- def test_success(self):
- self.setupStep(mock.MockRebuild(root='TESTROOT', srpm="foo.src.rpm"))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/build.log', 'build/root.log',
- 'build/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT',
- '--rebuild', 'foo.src.rpm'],
- logfiles={'build.log': 'build.log',
- 'root.log': 'root.log',
- 'state.log': 'state.log'},)
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['mock rebuild srpm'])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py
deleted file mode 100644
index 97dee1e5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.results import SUCCESS
-from buildbot.steps.package.rpm import rpmbuild
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot import config
-
-class RpmBuild(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_specfile(self):
- self.assertRaises(config.ConfigErrors, lambda :
- rpmbuild.RpmBuild())
-
- def test_success(self):
- self.setupStep(rpmbuild.RpmBuild(specfile="foo.spec", dist=".el6"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command='rpmbuild --define "_topdir '
- '`pwd`" --define "_builddir `pwd`" --define "_rpmdir '
- '`pwd`" --define "_sourcedir `pwd`" --define "_specdir '
- '`pwd`" --define "_srcrpmdir `pwd`" --define "dist .el6" '
- '-ba foo.spec',
- usePTY='slave-config')
- + ExpectShell.log('stdio',
- stdout='lalala')
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['RPMBUILD'])
- return self.runStep()
-
- def test_autoRelease(self):
- self.setupStep(rpmbuild.RpmBuild(specfile="foo.spec", dist=".el6",
- autoRelease=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command='rpmbuild --define "_topdir '
- '`pwd`" --define "_builddir `pwd`" --define "_rpmdir `pwd`" '
- '--define "_sourcedir `pwd`" --define "_specdir `pwd`" '
- '--define "_srcrpmdir `pwd`" --define "dist .el6" '
- '--define "_release 0" -ba foo.spec',
- usePTY='slave-config')
- + ExpectShell.log('stdio',
- stdout='Your code has been rated at 10/10')
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['RPMBUILD'])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py
deleted file mode 100644
index cb36e31c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.results import SUCCESS
-from buildbot.steps.package.rpm import rpmlint
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-
-class TestRpmLint(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(rpmlint.RpmLint())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['rpmlint', '-i', '.'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Finished checking RPM/SPEC issues'])
- return self.runStep()
-
- def test_fileloc_success(self):
- self.setupStep(rpmlint.RpmLint(fileloc='RESULT'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['rpmlint', '-i', 'RESULT'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Finished checking RPM/SPEC issues'])
- return self.runStep()
-
- def test_config_success(self):
- self.setupStep(rpmlint.RpmLint(config='foo.cfg'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['rpmlint', '-i', '-f', 'foo.cfg', '.'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Finished checking RPM/SPEC issues'])
- return self.runStep()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py
deleted file mode 100644
index 4bc31cbc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py
+++ /dev/null
@@ -1,445 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS
-from buildbot.steps import python
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot import config
-
-log_output_success = '''\
-Making output directory...
-Running Sphinx v1.0.7
-loading pickled environment... not yet created
-No builder selected, using default: html
-building [html]: targets for 24 source files that are out of date
-updating environment: 24 added, 0 changed, 0 removed
-reading sources... [ 4%] index
-reading sources... [ 8%] manual/cfg-builders
-...
-copying static files... done
-dumping search index... done
-dumping object inventory... done
-build succeeded.
-'''
-
-log_output_nochange = '''\
-Running Sphinx v1.0.7
-loading pickled environment... done
-No builder selected, using default: html
-building [html]: targets for 0 source files that are out of date
-updating environment: 0 added, 0 changed, 0 removed
-looking for now-outdated files... none found
-no targets are out of date.
-'''
-
-log_output_warnings = '''\
-Running Sphinx v1.0.7
-loading pickled environment... done
-building [html]: targets for 1 source files that are out of date
-updating environment: 0 added, 1 changed, 0 removed
-reading sources... [100%] file
-
-file.rst:18: (WARNING/2) Literal block expected; none found.
-
-looking for now-outdated files... none found
-pickling environment... done
-checking consistency... done
-preparing documents... done
-writing output... [ 50%] index
-writing output... [100%] file
-
-index.rst:: WARNING: toctree contains reference to document 'preamble' that \
-doesn't have a title: no link will be generated
-writing additional files... search
-copying static files... done
-dumping search index... done
-dumping object inventory... done
-build succeeded, 2 warnings.'''
-
-warnings = '''\
-file.rst:18: (WARNING/2) Literal block expected; none found.
-index.rst:: WARNING: toctree contains reference to document 'preamble' that \
-doesn't have a title: no link will be generated\
-'''
-
-
-class PyLint(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log('stdio',
- stdout='Your code has been rated at 10/10')
- + python.PyLint.RC_OK)
- self.expectOutcome(result=SUCCESS, status_text=['pylint'])
- return self.runStep()
-
- def test_error(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'E: 12: Undefined variable \'foo\'\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_ERROR))
- self.expectOutcome(result=FAILURE,
- status_text=['pylint', 'error=1', 'warning=1',
- 'failed'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-error', 1)
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'F: 13: something really strange happened\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_FATAL))
- self.expectOutcome(result=FAILURE,
- status_text=['pylint', 'fatal=1', 'warning=1',
- 'failed'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-fatal', 1)
- return self.runStep()
-
- def test_failure_zero_returncode(self):
- # Make sure that errors result in a failed step when pylint's
- # return code is 0, e.g. when run through a wrapper script.
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'E: 12: Undefined variable \'foo\'\n'))
- + 0)
- self.expectOutcome(result=FAILURE,
- status_text=['pylint', 'error=1', 'warning=1',
- 'failed'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-error', 1)
- return self.runStep()
-
- def test_regex_text(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'C: 1:foo123: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_text_0_24(self):
- # pylint >= 0.24.0 prints out column offsets when using text format
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11,0: Bad indentation. Found 6 spaces, expected 4\n'
- 'C: 3,10:foo123: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_text_ids(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W0311: 11: Bad indentation.\n'
- 'C0111: 1:funcName: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_text_ids_0_24(self):
- # pylint >= 0.24.0 prints out column offsets when using text format
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W0311: 11,0: Bad indentation.\n'
- 'C0111: 3,10:foo123: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_parseable_ids(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('test.py:9: [W0311] Bad indentation.\n'
- 'test.py:3: [C0111, foo123] Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_parseable(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('test.py:9: [W] Bad indentation.\n'
- 'test.py:3: [C, foo123] Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
-class PyFlakes(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + 0)
- self.expectOutcome(result=SUCCESS, status_text=['pyflakes'])
- return self.runStep()
-
- def test_unused(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:1: 'bar' imported but unused\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'unused=1', 'warnings'])
- self.expectProperty('pyflakes-unused', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_undefined(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:1: undefined name 'bar'\n")
- + 1)
- self.expectOutcome(result=FAILURE,
- status_text=['pyflakes', 'undefined=1', 'failed'])
- self.expectProperty('pyflakes-undefined', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_redefs(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:2: redefinition of unused 'foo' from line 1\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'redefs=1', 'warnings'])
- self.expectProperty('pyflakes-redefs', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_importstar(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:1: 'from module import *' used; unable to detect undefined names\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'import*=1', 'warnings'])
- self.expectProperty('pyflakes-import*', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_misc(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:2: redefinition of function 'bar' from line 1\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'misc=1', 'warnings'])
- self.expectProperty('pyflakes-misc', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
-
-class TestSphinx(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_builddir_required(self):
- self.assertRaises(config.ConfigErrors, lambda :
- python.Sphinx())
-
- def test_bad_mode(self):
- self.assertRaises(config.ConfigErrors, lambda: python.Sphinx(
- sphinx_builddir="_build", mode="don't care"))
-
- def test_success(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout=log_output_success)
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["sphinx", "0 warnings"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout='oh noes!')
- + 1
- )
- self.expectOutcome(result=FAILURE, status_text=["sphinx", "0 warnings", "failed"])
- return self.runStep()
-
- def test_nochange(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout=log_output_nochange)
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["sphinx", "0 warnings"])
- return self.runStep()
-
- def test_warnings(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout=log_output_warnings)
- + 0
- )
- self.expectOutcome(result=WARNINGS,
- status_text=["sphinx", "2 warnings", "warnings"])
- self.expectLogfile("warnings", warnings)
- d = self.runStep()
- def check(_):
- self.assertEqual(self.step_statistics, { 'warnings' : 2 })
- d.addCallback(check)
- return d
-
- def test_constr_args(self):
- self.setupStep(python.Sphinx(sphinx_sourcedir='src',
- sphinx_builddir="bld",
- sphinx_builder='css',
- sphinx="/path/to/sphinx-build",
- tags=['a', 'b'],
- defines=dict(empty=None, t=True, f=False, s="str"),
- mode='full'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['/path/to/sphinx-build', '-b', 'css',
- '-t', 'a', '-t', 'b', '-D', 'empty',
- '-D', 'f=0', '-D', 's=str', '-D', 't=1',
- '-E', 'src', 'bld'])
- + ExpectShell.log('stdio',
- stdout=log_output_success)
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["sphinx", "0 warnings"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py
deleted file mode 100644
index daefb43b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.steps import python_twisted
-from buildbot.status.results import SUCCESS
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.process.properties import Property
-
-
-
-class Trial(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_run_env(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = None,
- env = {'PYTHONPATH': 'somepath'}))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'},
- env=dict(PYTHONPATH='somepath'))
- + ExpectShell.log('stdio', stdout="Ran 0 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['no tests', 'run'])
- return self.runStep()
-
- def test_run_env_supplement(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = 'path1',
- env = {'PYTHONPATH': ['path2','path3']}))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'},
- env=dict(PYTHONPATH=['path1', 'path2', 'path3']))
- + ExpectShell.log('stdio', stdout="Ran 0 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['no tests', 'run'])
- return self.runStep()
-
- def test_run_env_nodupe(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = 'path2',
- env = {'PYTHONPATH': ['path1','path2']}))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'},
- env=dict(PYTHONPATH=['path1','path2']))
- + ExpectShell.log('stdio', stdout="Ran 0 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['no tests', 'run'])
- return self.runStep()
-
- def test_run_singular(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath=None))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'})
- + ExpectShell.log('stdio', stdout="Ran 1 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['1 test', 'passed'])
- return self.runStep()
-
- def test_run_plural(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath=None))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'})
- + ExpectShell.log('stdio', stdout="Ran 2 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['2 tests', 'passed'])
- return self.runStep()
-
- def testProperties(self):
- self.setupStep(python_twisted.Trial(workdir='build',
- tests = Property('test_list'),
- testpath=None))
- self.properties.setProperty('test_list',['testname'], 'Test')
-
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'})
- + ExpectShell.log('stdio', stdout="Ran 2 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['2 tests', 'passed'])
- return self.runStep()
-
- def test_run_jobs(self):
- """
- The C{jobs} kwarg should correspond to trial's -j option (
- included since Twisted 12.3.0), and make corresponding changes to
- logfiles.
- """
- self.setupStep(python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = None,
- jobs=2))
-
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', '--jobs=2',
- 'testname'],
- usePTY="slave-config",
- logfiles={
- 'test.0.log': '_trial_temp/0/test.log',
- 'err.0.log': '_trial_temp/0/err.log',
- 'out.0.log': '_trial_temp/0/out.log',
- 'test.1.log': '_trial_temp/1/test.log',
- 'err.1.log': '_trial_temp/1/err.log',
- 'out.1.log': '_trial_temp/1/out.log',
- })
- + ExpectShell.log('stdio', stdout="Ran 1 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['1 test', 'passed'])
- return self.runStep()
-
- def test_run_jobsProperties(self):
- """
- C{jobs} should accept Properties
- """
- self.setupStep(python_twisted.Trial(workdir='build',
- tests = 'testname',
- jobs=Property('jobs_count'),
- testpath=None))
- self.properties.setProperty('jobs_count', '2', 'Test')
-
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', '--jobs=2',
- 'testname'],
- usePTY="slave-config",
- logfiles={
- 'test.0.log': '_trial_temp/0/test.log',
- 'err.0.log': '_trial_temp/0/err.log',
- 'out.0.log': '_trial_temp/0/out.log',
- 'test.1.log': '_trial_temp/1/test.log',
- 'err.1.log': '_trial_temp/1/err.log',
- 'out.1.log': '_trial_temp/1/out.log',
- })
- + ExpectShell.log('stdio', stdout="Ran 1 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['1 test', 'passed'])
- return self.runStep()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py
deleted file mode 100644
index 9f914600..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py
+++ /dev/null
@@ -1,836 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-import textwrap
-from twisted.trial import unittest
-from buildbot.steps import shell
-from buildbot.status.results import SKIPPED, SUCCESS, WARNINGS, FAILURE
-from buildbot.status.results import EXCEPTION
-from buildbot.test.util import steps, compat
-from buildbot.test.util import config as configmixin
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot.test.fake.remotecommand import ExpectRemoteRef
-from buildbot import config
-from buildbot.process import properties
-
-class TestShellCommandExecution(steps.BuildStepMixin, unittest.TestCase, configmixin.ConfigErrorsMixin):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_doStepIf_False(self):
- self.setupStep(
- shell.ShellCommand(command="echo hello", doStepIf=False))
- self.expectOutcome(result=SKIPPED,
- status_text=["'echo", "hello'", "skipped"])
- return self.runStep()
-
- def test_constructor_args_strings(self):
- step = shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=False, description="echoing",
- descriptionDone="echoed")
- self.assertEqual(step.description, ['echoing'])
- self.assertEqual(step.descriptionDone, ['echoed'])
-
- def test_constructor_args_lists(self):
- step = shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=False, description=["echoing"],
- descriptionDone=["echoed"])
- self.assertEqual(step.description, ['echoing'])
- self.assertEqual(step.descriptionDone, ['echoed'])
-
- def test_constructor_args_kwargs(self):
- # this is an ugly way to define an API, but for now check that
- # the RemoteCommand arguments are properly passed on
- step = shell.ShellCommand(workdir='build', command="echo hello",
- want_stdout=0, logEnviron=False)
- self.assertEqual(step.remote_kwargs, dict(want_stdout=0,
- logEnviron=False, workdir='build',
- usePTY='slave-config'))
-
- def test_constructor_args_validity(self):
- # this checks that an exception is raised for invalid arguments
- self.assertRaisesConfigError(
- "Invalid argument(s) passed to RemoteShellCommand: ",
- lambda: shell.ShellCommand('build', "echo Hello World",
- wrongArg1=1, wrongArg2='two'))
-
- def test_describe_no_command(self):
- step = shell.ShellCommand(workdir='build')
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
-
- def test_describe_from_empty_command(self):
- # this is more of a regression test for a potential failure, really
- step = shell.ShellCommand(workdir='build', command=' ')
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
-
- def test_describe_from_short_command(self):
- step = shell.ShellCommand(workdir='build', command="true")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'true'"],)*2)
-
- def test_describe_from_short_command_list(self):
- step = shell.ShellCommand(workdir='build', command=["true"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'true'"],)*2)
-
- def test_describe_from_med_command(self):
- step = shell.ShellCommand(command="echo hello")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'echo", "hello'"],)*2)
-
- def test_describe_from_med_command_list(self):
- step = shell.ShellCommand(command=["echo", "hello"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'echo", "hello'"],)*2)
-
- def test_describe_from_long_command(self):
- step = shell.ShellCommand(command="this is a long command")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_long_command_list(self):
- step = shell.ShellCommand(command="this is a long command".split())
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_list(self):
- step = shell.ShellCommand(command=["this", ["is", "a"], "nested"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_tuples(self):
- step = shell.ShellCommand(command=["this", ("is", "a"), "nested"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_list_empty(self):
- step = shell.ShellCommand(command=["this", [], ["is", "a"], "nested"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_list_deep(self):
- step = shell.ShellCommand(command=[["this", [[["is", ["a"]]]]]])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_custom(self):
- step = shell.ShellCommand(command="echo hello",
- description=["echoing"], descriptionDone=["echoed"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['echoing'], ['echoed']))
-
- def test_describe_with_suffix(self):
- step = shell.ShellCommand(command="echo hello", descriptionSuffix="suffix")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'echo", "hello'", 'suffix'],)*2)
-
- def test_describe_custom_with_suffix(self):
- step = shell.ShellCommand(command="echo hello",
- description=["echoing"], descriptionDone=["echoed"],
- descriptionSuffix="suffix")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['echoing', 'suffix'], ['echoed', 'suffix']))
-
- def test_describe_no_command_with_suffix(self):
- step = shell.ShellCommand(workdir='build', descriptionSuffix="suffix")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???', 'suffix'],)*2)
-
- def test_describe_unrendered_WithProperties(self):
- step = shell.ShellCommand(command=properties.WithProperties(''))
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
-
- def test_describe_unrendered_WithProperties_list(self):
- step = shell.ShellCommand(
- command=[ 'x', properties.WithProperties(''), 'y' ])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'x", "y'"],)*2)
-
- @compat.usesFlushLoggedErrors
- def test_describe_fail(self):
- step = shell.ShellCommand(command=object())
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
- # (describe is called twice, so two exceptions)
- self.assertEqual(len(self.flushLoggedErrors(TypeError)), 2)
-
- def test_run_simple(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello"))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_list(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_nested_command(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=['trial', ['-b', '-B'], 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_nested_deeply_command(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=[['trial', ['-b', ['-B']]], 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_nested_empty_command(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=['trial', [], '-b', [], 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_env(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello"),
- slave_env=dict(DEF='HERE'))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config",
- env=dict(DEF='HERE'))
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_env_override(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', env={'ABC':'123'},
- command="echo hello"),
- slave_env=dict(ABC='XXX', DEF='HERE'))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config",
- env=dict(ABC='123', DEF='HERE'))
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_usePTY(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=False))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY=False)
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_usePTY_old_slave(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=True),
- slave_version=dict(shell='1.1'))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello')
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_decodeRC(self, rc=1, results=WARNINGS, extra_text = ["warnings"]):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello",
- decodeRC={1:WARNINGS}))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config")
- + rc
- )
- self.expectOutcome(result=results, status_text=["'echo", "hello'"]+extra_text)
- return self.runStep()
-
- def test_run_decodeRC_defaults(self):
- return self.test_run_decodeRC(2, FAILURE,extra_text=["failed"])
-
- def test_run_decodeRC_defaults_0_is_failure(self):
- return self.test_run_decodeRC(0, FAILURE,extra_text=["failed"])
-
-
-
-class TreeSize(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_run_success(self):
- self.setupStep(shell.TreeSize())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['du', '-s', '-k', '.'])
- + ExpectShell.log('stdio', stdout='9292 .\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["treesize", "9292 KiB"])
- self.expectProperty('tree-size-KiB', 9292)
- return self.runStep()
-
- def test_run_misparsed(self):
- self.setupStep(shell.TreeSize())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['du', '-s', '-k', '.'])
- + ExpectShell.log('stdio', stdio='abcdef\n')
- + 0
- )
- self.expectOutcome(result=WARNINGS,
- status_text=["treesize", "unknown"])
- return self.runStep()
-
- def test_run_failed(self):
- self.setupStep(shell.TreeSize())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['du', '-s', '-k', '.'])
- + ExpectShell.log('stdio', stderr='abcdef\n')
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["treesize", "unknown"])
- return self.runStep()
-
-class SetPropertyFromCommand(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_constructor_conflict(self):
- self.assertRaises(config.ConfigErrors, lambda :
- shell.SetPropertyFromCommand(property='foo', extract_fn=lambda : None))
-
- def test_run_property(self):
- self.setupStep(shell.SetPropertyFromCommand(property="res", command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + ExpectShell.log('stdio', stdout='\n\nabcdef\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["property 'res' set"])
- self.expectProperty("res", "abcdef") # note: stripped
- self.expectLogfile('property changes', r"res: 'abcdef'")
- return self.runStep()
-
- def test_run_property_no_strip(self):
- self.setupStep(shell.SetPropertyFromCommand(property="res", command="cmd",
- strip=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + ExpectShell.log('stdio', stdout='\n\nabcdef\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["property 'res' set"])
- self.expectProperty("res", "\n\nabcdef\n")
- self.expectLogfile('property changes', r"res: '\n\nabcdef\n'")
- return self.runStep()
-
- def test_run_failure(self):
- self.setupStep(shell.SetPropertyFromCommand(property="res", command="blarg"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="blarg")
- + ExpectShell.log('stdio', stderr='cannot blarg: File not found')
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["'blarg'", "failed"])
- self.expectNoProperty("res")
- return self.runStep()
-
- def test_run_extract_fn(self):
- def extract_fn(rc, stdout, stderr):
- self.assertEqual((rc, stdout, stderr), (0, 'startend', 'STARTEND'))
- return dict(a=1, b=2)
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + ExpectShell.log('stdio', stdout='start', stderr='START')
- + ExpectShell.log('stdio', stdout='end')
- + ExpectShell.log('stdio', stderr='END')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["2 properties set"])
- self.expectLogfile('property changes', 'a: 1\nb: 2')
- self.expectProperty("a", 1)
- self.expectProperty("b", 2)
- return self.runStep()
-
- def test_run_extract_fn_cmdfail(self):
- def extract_fn(rc, stdout, stderr):
- self.assertEqual((rc, stdout, stderr), (3, '', ''))
- return dict(a=1, b=2)
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + 3
- )
- # note that extract_fn *is* called anyway
- self.expectOutcome(result=FAILURE,
- status_text=["2 properties set"])
- self.expectLogfile('property changes', 'a: 1\nb: 2')
- return self.runStep()
-
- def test_run_extract_fn_cmdfail_empty(self):
- def extract_fn(rc, stdout, stderr):
- self.assertEqual((rc, stdout, stderr), (3, '', ''))
- return dict()
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + 3
- )
- # note that extract_fn *is* called anyway, but returns no properties
- self.expectOutcome(result=FAILURE,
- status_text=["'cmd'", "failed"])
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_run_extract_fn_exception(self):
- def extract_fn(rc, stdout, stderr):
- raise RuntimeError("oh noes")
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + 0
- )
- # note that extract_fn *is* called anyway, but returns no properties
- self.expectOutcome(result=EXCEPTION,
- status_text=["setproperty", "exception"])
- d = self.runStep()
- d.addCallback(lambda _ :
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1))
- return d
-
-class SetPropertyDeprecation(unittest.TestCase):
- """
- Tests for L{shell.SetProperty}
- """
-
- def test_deprecated(self):
- """
- Accessing L{shell.SetProperty} reports a deprecation error.
- """
- shell.SetProperty
- warnings = self.flushWarnings([self.test_deprecated])
- self.assertEqual(len(warnings), 1)
- self.assertIdentical(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(warnings[0]['message'],
- "buildbot.steps.shell.SetProperty was deprecated in Buildbot 0.8.8: "
- "It has been renamed to SetPropertyFromCommand"
- )
-
-
-class Configure(unittest.TestCase):
-
- def test_class_attrs(self):
- # nothing too exciting here, but at least make sure the class is present
- step = shell.Configure()
- self.assertEqual(step.command, ['./configure'])
-
-class WarningCountingShellCommand(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_warnings(self):
- self.setupStep(shell.WarningCountingShellCommand(workdir='w',
- command=['make']))
- self.expectCommands(
- ExpectShell(workdir='w', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout='blarg success!')
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'make'"])
- self.expectProperty("warnings-count", 0)
- return self.runStep()
-
- def test_default_pattern(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio',
- stdout='normal: foo\nwarning: blarg!\nalso normal')
- + 0
- )
- self.expectOutcome(result=WARNINGS, status_text=["'make'", "warnings"])
- self.expectProperty("warnings-count", 1)
- self.expectLogfile("warnings (1)", "warning: blarg!\n")
- return self.runStep()
-
- def test_custom_pattern(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make'],
- warningPattern=r"scary:.*"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio',
- stdout='scary: foo\nwarning: bar\nscary: bar')
- + 0
- )
- self.expectOutcome(result=WARNINGS, status_text=["'make'", "warnings"])
- self.expectProperty("warnings-count", 2)
- self.expectLogfile("warnings (2)", "scary: foo\nscary: bar\n")
- return self.runStep()
-
- def test_maxWarnCount(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make'],
- maxWarnCount=9))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout='warning: noo!\n' * 10)
- + 0
- )
- self.expectOutcome(result=FAILURE, status_text=["'make'", "failed"])
- self.expectProperty("warnings-count", 10)
- return self.runStep()
-
- def test_fail_with_warnings(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout='warning: I might fail')
- + 3
- )
- self.expectOutcome(result=FAILURE, status_text=["'make'", "failed"])
- self.expectProperty("warnings-count", 1)
- self.expectLogfile("warnings (1)", "warning: I might fail\n")
- return self.runStep()
-
- def do_test_suppressions(self, step, supps_file='', stdout='',
- exp_warning_count=0, exp_warning_log='',
- exp_exception=False):
- self.setupStep(step)
-
- # Invoke the expected callbacks for the suppression file upload. Note
- # that this assumes all of the remote_* are synchronous, but can be
- # easily adapted to suit if that changes (using inlineCallbacks)
- def upload_behavior(command):
- writer = command.args['writer']
- writer.remote_write(supps_file)
- writer.remote_close()
-
- self.expectCommands(
- # step will first get the remote suppressions file
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='supps', workdir='wkdir',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(upload_behavior),
-
- # and then run the command
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout=stdout)
- + 0
- )
- if exp_exception:
- self.expectOutcome(result=EXCEPTION,
- status_text=["shell", "exception"])
- else:
- if exp_warning_count != 0:
- self.expectOutcome(result=WARNINGS,
- status_text=["'make'", "warnings"])
- self.expectLogfile("warnings (%d)" % exp_warning_count,
- exp_warning_log)
- else:
- self.expectOutcome(result=SUCCESS,
- status_text=["'make'"])
- self.expectProperty("warnings-count", exp_warning_count)
- return self.runStep()
-
- def test_suppressions(self):
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps')
- supps_file = textwrap.dedent("""\
- # example suppressions file
-
- amar.c : .*unused variable.*
- holding.c : .*invalid access to non-static.*
- """).strip()
- stdout = textwrap.dedent("""\
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- amar.c: In function 'write_record':
- amar.c:164: warning: unused variable 'x'
- amar.c:164: warning: this should show up
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- holding.c: In function 'holding_thing':
- holding.c:984: warning: invalid access to non-static 'y'
- """)
- exp_warning_log = textwrap.dedent("""\
- amar.c:164: warning: this should show up
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 1,
- exp_warning_log)
-
- def test_suppressions_directories(self):
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor)
- supps_file = textwrap.dedent("""\
- # these should be suppressed:
- amar-src/amar.c : XXX
- .*/server-src/.* : AAA
- # these should not, as the dirs do not match:
- amar.c : YYY
- server-src.* : BBB
- """).strip()
- # note that this uses the unicode smart-quotes that gcc loves so much
- stdout = textwrap.dedent(u"""\
- make: Entering directory \u2019amar-src\u2019
- amar.c:164: warning: XXX
- amar.c:165: warning: YYY
- make: Leaving directory 'amar-src'
- make: Entering directory "subdir"
- make: Entering directory 'server-src'
- make: Entering directory `one-more-dir`
- holding.c:999: warning: BBB
- holding.c:1000: warning: AAA
- """)
- exp_warning_log = textwrap.dedent("""\
- amar.c:165: warning: YYY
- holding.c:999: warning: BBB
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 2,
- exp_warning_log)
-
- def test_suppressions_directories_custom(self):
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor,
- directoryEnterPattern="^IN: (.*)",
- directoryLeavePattern="^OUT:")
- supps_file = "dir1/dir2/abc.c : .*"
- stdout = textwrap.dedent(u"""\
- IN: dir1
- IN: decoy
- OUT: decoy
- IN: dir2
- abc.c:123: warning: hello
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 0, '')
-
- def test_suppressions_linenos(self):
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor)
- supps_file = "abc.c:.*:100-199\ndef.c:.*:22"
- stdout = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:150: warning: unseen
- def.c:22: warning: unseen
- abc.c:200: warning: seen 2
- """)
- exp_warning_log = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:200: warning: seen 2
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 2,
- exp_warning_log)
-
- @compat.usesFlushLoggedErrors
- def test_suppressions_warningExtractor_exc(self):
- def warningExtractor(step, line, match):
- raise RuntimeError("oh noes")
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor)
- supps_file = 'x:y' # need at least one supp to trigger warningExtractor
- stdout = "abc.c:99: warning: seen 1"
- d = self.do_test_suppressions(step, supps_file, stdout,
- exp_exception=True)
- d.addCallback(lambda _ :
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1))
- return d
-
- def test_suppressions_addSuppression(self):
- # call addSuppression "manually" from a subclass
- class MyWCSC(shell.WarningCountingShellCommand):
- def start(self):
- self.addSuppression([('.*', '.*unseen.*', None, None)])
- return shell.WarningCountingShellCommand.start(self)
-
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = MyWCSC(command=['make'], suppressionFile='supps',
- warningExtractor=warningExtractor)
- stdout = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:150: warning: unseen
- abc.c:200: warning: seen 2
- """)
- exp_warning_log = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:200: warning: seen 2
- """)
- return self.do_test_suppressions(step, '', stdout, 2,
- exp_warning_log)
-
- def test_warnExtractFromRegexpGroups(self):
- step = shell.WarningCountingShellCommand(command=['make'])
- we = shell.WarningCountingShellCommand.warnExtractFromRegexpGroups
- line, pat, exp_file, exp_lineNo, exp_text = \
- ('foo:123:text', '(.*):(.*):(.*)', 'foo', 123, 'text')
- self.assertEqual(we(step, line, re.match(pat, line)),
- (exp_file, exp_lineNo, exp_text))
-
-class Compile(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_class_args(self):
- # since this step is just a pre-configured WarningCountingShellCommand,
- # there' not much to test!
- step = self.setupStep(shell.Compile())
- self.assertEqual(step.name, "compile")
- self.assertTrue(step.haltOnFailure)
- self.assertTrue(step.flunkOnFailure)
- self.assertEqual(step.description, ["compiling"])
- self.assertEqual(step.descriptionDone, ["compile"])
- self.assertEqual(step.command, ["make", "all"])
-
-class Test(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpBuildStep()
-
- def tearDown(self):
- self.tearDownBuildStep()
-
- def test_setTestResults(self):
- step = self.setupStep(shell.Test())
- step.setTestResults(total=10, failed=3, passed=5, warnings=3)
- self.assertEqual(self.step_statistics, {
- 'tests-total' : 10,
- 'tests-failed' : 3,
- 'tests-passed' : 5,
- 'tests-warnings' : 3,
- })
- # ensure that they're additive
- step.setTestResults(total=1, failed=2, passed=3, warnings=4)
- self.assertEqual(self.step_statistics, {
- 'tests-total' : 11,
- 'tests-failed' : 5,
- 'tests-passed' : 8,
- 'tests-warnings' : 7,
- })
-
- def test_describe_not_done(self):
- step = self.setupStep(shell.Test())
- self.assertEqual(step.describe(), ['testing'])
-
- def test_describe_done(self):
- step = self.setupStep(shell.Test())
- self.step_statistics['tests-total'] = 93
- self.step_statistics['tests-failed'] = 10
- self.step_statistics['tests-passed'] = 20
- self.step_statistics['tests-warnings'] = 30
- self.assertEqual(step.describe(done=True), [ 'test', '93 tests',
- '20 passed', '30 warnings', '10 failed'])
-
- def test_describe_done_no_total(self):
- step = self.setupStep(shell.Test())
- self.step_statistics['tests-total'] = 0
- self.step_statistics['tests-failed'] = 10
- self.step_statistics['tests-passed'] = 20
- self.step_statistics['tests-warnings'] = 30
- # describe calculates 60 = 10+20+30
- self.assertEqual(step.describe(done=True), [ 'test', '60 tests',
- '20 passed', '30 warnings', '10 failed'])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py
deleted file mode 100644
index 8052dca7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py
+++ /dev/null
@@ -1,381 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import stat
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.steps import slave
-from buildbot.status.results import SUCCESS, FAILURE, EXCEPTION
-from buildbot.process import properties, buildstep
-from buildbot.test.fake.remotecommand import Expect
-from buildbot.test.util import steps, compat
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class TestSetPropertiesFromEnv(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_simple(self):
- self.setupStep(slave.SetPropertiesFromEnv(
- variables=["one", "two", "three", "five", "six"],
- source="me"))
- self.buildslave.slave_environ = { "one": "1", "two": None, "six": "6", "FIVE" : "555" }
- self.properties.setProperty("four", 4, "them")
- self.properties.setProperty("five", 5, "them")
- self.properties.setProperty("six", 99, "them")
- self.expectOutcome(result=SUCCESS,
- status_text=["Set"])
- self.expectProperty('one', "1", source='me')
- self.expectNoProperty('two')
- self.expectNoProperty('three')
- self.expectProperty('four', 4, source='them')
- self.expectProperty('five', 5, source='them')
- self.expectProperty('six', '6', source='me')
- self.expectLogfile("properties",
- "one = '1'\nsix = '6'")
- return self.runStep()
-
- def test_case_folding(self):
- self.setupStep(slave.SetPropertiesFromEnv(
- variables=["eNv"], source="me"))
- self.buildslave.slave_environ = { "ENV": 'EE' }
- self.buildslave.slave_system = 'win32'
- self.expectOutcome(result=SUCCESS,
- status_text=["Set"])
- self.expectProperty('eNv', 'EE', source='me')
- self.expectLogfile("properties",
- "eNv = 'EE'")
- return self.runStep()
-
-
-class TestFileExists(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_found(self):
- self.setupStep(slave.FileExists(file="x"))
- self.expectCommands(
- Expect('stat', { 'file' : 'x' })
- + Expect.update('stat', [stat.S_IFREG, 99, 99])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["File found."])
- return self.runStep()
-
- def test_not_found(self):
- self.setupStep(slave.FileExists(file="x"))
- self.expectCommands(
- Expect('stat', { 'file' : 'x' })
- + Expect.update('stat', [0, 99, 99])
- + 0
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Not a file."])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.FileExists(file="x"))
- self.expectCommands(
- Expect('stat', { 'file' : 'x' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["File not found."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.FileExists(file=properties.Property("x")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.expectCommands(
- Expect('stat', { 'file' : 'XXX' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["File not found."])
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_old_version(self):
- self.setupStep(slave.FileExists(file="x"),
- slave_version=dict())
- self.expectOutcome(result=EXCEPTION,
- status_text=["FileExists", "exception"])
- d = self.runStep()
- def check(_):
- self.assertEqual(
- len(self.flushLoggedErrors(BuildSlaveTooOldError)), 1)
- d.addCallback(check)
- return d
-
-
-class TestCopyDirectory(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d"))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "s", "to", "d"])
- return self.runStep()
-
- def test_timeout(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d", timeout=300))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd', 'timeout': 300 })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "s", "to", "d"])
- return self.runStep()
-
- def test_maxTime(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d", maxTime=10))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd', 'maxTime': 10 })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "s", "to", "d"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d"))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Copying", "s", "to", "d", "failed."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.CopyDirectory(src=properties.Property("x"), dest=properties.Property("y")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.properties.setProperty('y', 'YYY', 'here')
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 'XXX', 'todir' : 'YYY' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "XXX", "to", "YYY"])
- return self.runStep()
-
-class TestRemoveDirectory(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(slave.RemoveDirectory(dir="d"))
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'd' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Deleted"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.RemoveDirectory(dir="d"))
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'd' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Delete failed."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.RemoveDirectory(dir=properties.Property("x")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'XXX' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Deleted"])
- return self.runStep()
-
-class TestMakeDirectory(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(slave.MakeDirectory(dir="d"))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Created"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.MakeDirectory(dir="d"))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Create failed."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.MakeDirectory(dir=properties.Property("x")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'XXX' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Created"])
- return self.runStep()
-
-class CompositeUser(buildstep.LoggingBuildStep, slave.CompositeStepMixin):
- def __init__(self, payload):
- self.payload = payload
- self.logEnviron=False
- buildstep.LoggingBuildStep.__init__(self)
- def start(self):
- self.addLogForRemoteCommands('stdio')
- d = self.payload(self)
- d.addCallback(self.commandComplete)
- d.addErrback(self.failed)
- def commandComplete(self,res):
- self.finished(FAILURE if res else SUCCESS)
-
-class TestCompositeStepMixin(steps.BuildStepMixin, unittest.TestCase):
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_runRemoteCommand(self):
- cmd_args = ('foo', {'bar': False})
- def testFunc(x):
- x.runRemoteCommand(*cmd_args)
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(Expect(*cmd_args)+0)
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
-
- def test_runRemoteCommandFail(self):
- cmd_args = ('foo', {'bar': False})
- @defer.inlineCallbacks
- def testFunc(x):
- yield x.runRemoteCommand(*cmd_args)
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(Expect(*cmd_args)+1)
- self.expectOutcome(result=FAILURE,
- status_text=["generic"])
- return self.runStep()
-
- def test_runRemoteCommandFailNoAbandon(self):
- cmd_args = ('foo', {'bar': False})
- @defer.inlineCallbacks
- def testFunc(x):
- res = yield x.runRemoteCommand(*cmd_args,
- **dict(abandonOnFailure=False))
- x.step_status.setText([str(res)])
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(Expect(*cmd_args)+1)
- self.expectOutcome(result=SUCCESS,
- status_text=["True"])
- return self.runStep()
-
- def test_mkdir(self):
- self.setupStep(CompositeUser(lambda x:x.runMkdir("d")))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
- return self.runStep()
-
- def test_rmdir(self):
- self.setupStep(CompositeUser(lambda x:x.runRmdir("d")))
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'd' , 'logEnviron': False})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
- return self.runStep()
-
- def test_mkdir_fail(self):
- self.setupStep(CompositeUser(lambda x:x.runMkdir("d")))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["generic"])
- return self.runStep()
-
- def test_abandonOnFailure(self):
- @defer.inlineCallbacks
- def testFunc(x):
- yield x.runMkdir("d")
- yield x.runMkdir("d")
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["generic"])
- return self.runStep()
-
- def test_notAbandonOnFailure(self):
- @defer.inlineCallbacks
- def testFunc(x):
- yield x.runMkdir("d", abandonOnFailure=False)
- yield x.runMkdir("d", abandonOnFailure=False)
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1,
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py
deleted file mode 100644
index 3260e479..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-
-from buildbot.steps.source import Source
-from buildbot.test.util import steps, sourcesteps
-
-class TestSource(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_start_alwaysUseLatest_True(self):
- step = self.setupStep(Source(alwaysUseLatest=True),
- {
- 'branch': 'other-branch',
- 'revision': 'revision',
- },
- patch = 'patch'
- )
- step.branch = 'branch'
- step.startVC = mock.Mock()
-
- step.startStep(mock.Mock())
-
- self.assertEqual(step.startVC.call_args, (('branch', None, None), {}))
-
- def test_start_alwaysUseLatest_False(self):
- step = self.setupStep(Source(),
- {
- 'branch': 'other-branch',
- 'revision': 'revision',
- },
- patch = 'patch'
- )
- step.branch = 'branch'
- step.startVC = mock.Mock()
-
- step.startStep(mock.Mock())
-
- self.assertEqual(step.startVC.call_args, (('other-branch', 'revision', 'patch'), {}))
-
- def test_start_alwaysUseLatest_False_no_branch(self):
- step = self.setupStep(Source())
- step.branch = 'branch'
- step.startVC = mock.Mock()
-
- step.startStep(mock.Mock())
-
- self.assertEqual(step.startVC.call_args, (('branch', None, None), {}))
-
- def test_start_no_codebase(self):
- step = self.setupStep(Source())
- step.branch = 'branch'
- step.startVC = mock.Mock()
- step.build.getSourceStamp = mock.Mock()
- step.build.getSourceStamp.return_value = None
-
- self.assertEqual(step.describe(), ['updating'])
- self.assertEqual(step.name, Source.name)
-
- step.startStep(mock.Mock())
- self.assertEqual(step.build.getSourceStamp.call_args[0], ('',))
-
- self.assertEqual(step.description, ['updating'])
-
- def test_start_with_codebase(self):
- step = self.setupStep(Source(codebase='codebase'))
- step.branch = 'branch'
- step.startVC = mock.Mock()
- step.build.getSourceStamp = mock.Mock()
- step.build.getSourceStamp.return_value = None
-
- self.assertEqual(step.describe(), ['updating', 'codebase'])
- self.assertEqual(step.name, Source.name + " codebase")
-
- step.startStep(mock.Mock())
- self.assertEqual(step.build.getSourceStamp.call_args[0], ('codebase',))
-
- self.assertEqual(step.describe(True), ['update', 'codebase'])
-
- def test_start_with_codebase_and_descriptionSuffix(self):
- step = self.setupStep(Source(codebase='my-code',
- descriptionSuffix='suffix'))
- step.branch = 'branch'
- step.startVC = mock.Mock()
- step.build.getSourceStamp = mock.Mock()
- step.build.getSourceStamp.return_value = None
-
- self.assertEqual(step.describe(), ['updating', 'suffix'])
- self.assertEqual(step.name, Source.name + " my-code")
-
- step.startStep(mock.Mock())
- self.assertEqual(step.build.getSourceStamp.call_args[0], ('my-code',))
-
- self.assertEqual(step.describe(True), ['update', 'suffix'])
-
-
-class TestSourceDescription(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_constructor_args_strings(self):
- step = Source(workdir='build',
- description='svn update (running)',
- descriptionDone='svn update')
- self.assertEqual(step.description, ['svn update (running)'])
- self.assertEqual(step.descriptionDone, ['svn update'])
-
- def test_constructor_args_lists(self):
- step = Source(workdir='build',
- description=['svn', 'update', '(running)'],
- descriptionDone=['svn', 'update'])
- self.assertEqual(step.description, ['svn', 'update', '(running)'])
- self.assertEqual(step.descriptionDone, ['svn', 'update'])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py
deleted file mode 100644
index e1e84dbb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py
+++ /dev/null
@@ -1,482 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import bzr
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-import os.path
-
-class TestBzr(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def test_mode_full(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_win32path(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'))
- self.build.path_module = namedModule('ntpath')
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_timeout(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh', timeout=1))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'),
- args=dict(revision='3730'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update', '-r', '3730'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_clean(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--ignored', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_clean_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clean'),
- args=dict(revision='2345'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--ignored', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update', '-r', '2345'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_clobber_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clobber'),
- args=dict(revision='3730'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk',
- '.', '-r', '3730'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_clobber_baseurl(self):
- self.setupStep(
- bzr.Bzr(baseURL='http://bzr.squid-cache.org/bzr/squid3',
- defaultBranch='trunk', mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- os.path.join('http://bzr.squid-cache.org/bzr/squid3', 'trunk'), '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_clobber_baseurl_nodefault(self):
- self.setupStep(
- bzr.Bzr(baseURL='http://bzr.squid-cache.org/bzr/squid3',
- defaultBranch='trunk', mode='full', method='clobber'),
- args=dict(branch='branches/SQUID_3_0'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- os.path.join('http://bzr.squid-cache.org/bzr/squid3', 'branches/SQUID_3_0'), '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_copy(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='build',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['bzr', 'update'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'logEnviron': True,
- 'todir': 'build'})
- + 0,
- ExpectShell(workdir='source',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_incremental_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'),
- args=dict(revision='9384'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update', '-r', '9384'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_incremental_no_existing_repo(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100\n')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100\n', 'Bzr')
- return self.runStep()
-
- def test_bad_revparse(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='oiasdfj010laksjfd')
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_bad_checkout(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + ExpectShell.log('stdio',
- stderr='failed\n')
- + 128,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py
deleted file mode 100644
index 7f39cdb5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py
+++ /dev/null
@@ -1,765 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import time
-from twisted.trial import unittest
-from buildbot.steps import shell
-from buildbot.steps.source import cvs
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect, ExpectRemoteRef
-
-def uploadString(cvsroot):
- def behavior(command):
- writer = command.args['writer']
- writer.remote_write(cvsroot + "\n")
- writer.remote_close()
- return behavior
-
-class TestCVS(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def setupStep(self, step, *args, **kwargs):
- sourcesteps.SourceStepMixin.setupStep(self, step, *args, **kwargs)
-
- # make parseGotRevision return something consistent, patching the class
- # instead of the object since a new object is constructed by runTest.
- def parseGotRevision(self, res):
- self.updateSourceProperty('got_revision',
- '2012-09-09 12:00:39 +0000')
- return res
- self.patch(cvs.CVS, 'parseGotRevision', parseGotRevision)
-
- def test_parseGotRevision(self):
- def gmtime():
- return time.struct_time((2012, 9, 9, 12, 9, 33, 6, 253, 0))
- self.patch(time, 'gmtime', gmtime)
-
- step = cvs.CVS(cvsroot="x", cvsmodule="m", mode='full', method='clean')
- props = []
- def updateSourceProperty(prop, name):
- props.append((prop, name))
- step.updateSourceProperty = updateSourceProperty
-
- self.assertEqual(step.parseGotRevision(10), 10) # passes res along
- self.assertEqual(props,
- [('got_revision', '2012-09-09 12:09:33 +0000')])
-
- def test_mode_full_clean(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_timeout(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True, timeout=1))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_branch(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- branch='branch', login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_branch_sourcestamp(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True), args={'branch':'my_branch'})
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'my_branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='fresh',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard', '--ignore'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clobber',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_copy(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='copy',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='source/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='source/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='source',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- Expect('cpdir', {'fromdir': 'source', 'todir': 'build',
- 'logEnviron': True})
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_full_copy_wrong_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='copy',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='source/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- Expect('rmdir', dict(dir='source',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'source', 'mozilla/browser/'])
- + 0,
- Expect('cpdir', {'fromdir': 'source', 'todir': 'build',
- 'logEnviron': True})
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_password_windows(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:dustin:secrets@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- # on Windows, this file does not contain the password, per
- # http://trac.buildbot.net/ticket/2355
- + Expect.behavior(uploadString(':pserver:dustin@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- branch='my_branch', login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'my_branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_special_case(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- branch='HEAD', login=True),
- args=dict(revision='2012-08-16 16:05:16 +0000'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP',
- # note, no -r HEAD here - that's the special case
- '-D', '2012-08-16 16:05:16 +0000'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch_sourcestamp(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True), args={'branch':'my_branch'})
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'my_branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_not_loggedin(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- 'login'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_no_existing_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_wrong_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_wrong_module(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_full_clean_no_existing_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + 1,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_wrong_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_no_method(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard', '--ignore'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_with_options(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True, global_options=['-q'], extra_options=['-l']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs', '-q', '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', '-l', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_with_env_logEnviron(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True, env={'abc': '123'}, logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'],
- env={'abc': '123'},
- logEnviron=False)
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'],
- env={'abc': '123'},
- logEnviron=False)
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_command_fails(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 128,
- )
-
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_cvsdiscard_fails(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='fresh',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard', '--ignore'])
- + ExpectShell.log('stdio',
- stderr='FAIL!\n')
- + 1,
- )
-
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py
deleted file mode 100644
index 4f60813d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py
+++ /dev/null
@@ -1,1457 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import git
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import config, sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-
-class TestGit(sourcesteps.SourceStepMixin, config.ConfigErrorsMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def test_mode_full_clean(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_win32path(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.build.path_module = namedModule('ntpath')
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_timeout(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- timeout=1,
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_patch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'apply', '--index', '-p', '1'],
- initialStdin='patch')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_patch_fail(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'apply', '--index', '-p', '1'],
- initialStdin='patch')
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- self.expectNoProperty('got_revision')
- return self.runStep()
-
- def test_mode_full_clean_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean', branch='test-branch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'branch', '-M', 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_parsefail(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + ExpectShell.log('stdio',
- stderr="fatal: Could not parse object "
- "'b08076bc71c7813038f2cefedff9c5b678d225a8'.\n")
- + 128,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- self.expectNoProperty('got_revision')
- return self.runStep()
-
- def test_mode_full_clean_no_existing_repo(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
-
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_no_existing_repo_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean', branch='test-branch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
-
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- '--branch', 'test-branch',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True, branch='test-branch'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- '--branch', 'test-branch',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', branch='test-branch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'branch', '-M', 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_given_revision(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental'), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'cat-file', '-e', 'abcdef01'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_fresh_submodule(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh', submodules=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'submodule', 'update', '--recursive'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'submodule', 'foreach', 'git', 'clean',
- '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_shallow(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', shallow=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone', '--depth', '1',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_no_shallow(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_retryFetch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', retryFetch=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_retryFetch_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', retryFetch=True, branch='test-branch'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'branch', '-M', 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_clobberOnFailure(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', clobberOnFailure=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_clobberOnFailure_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', clobberOnFailure=True, branch = 'test-branch'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- '--branch', 'test-branch',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_copy(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='copy'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200)),
- Expect('stat', dict(file='source/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='source',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- Expect('cpdir', {'fromdir': 'source', 'todir': 'build',
- 'logEnviron': True, 'timeout': 1200})
- + 0,
- ExpectShell(workdir='build',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_copy_shallow(self):
- self.assertRaisesConfigError("shallow only possible with mode 'full' and method 'clobber'", lambda :
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='copy', shallow=True))
-
- def test_mode_incremental_no_existing_repo(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_given_revision(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_revparse_failure(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ada95a1d') # too short
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- self.expectNoProperty('got_revision')
- return self.runStep()
-
- def test_mode_full_clobber_submodule(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', submodules=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'submodule', 'update',
- '--init', '--recursive'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_repourl(self):
- self.assertRaisesConfigError("must provide repourl", lambda :
- git.Git(mode="full"))
-
- def test_mode_full_fresh_revision(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh', progress=True), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_fresh_clobberOnFailure(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh', clobberOnFailure=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_no_method(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_with_env(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', env={'abc': '123'}))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'],
- env={'abc': '123'})
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_logEnviron(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'],
- logEnviron=False)
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=False))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_getDescription(self):
- # clone of: test_mode_incremental
- # only difference is to set the getDescription property
-
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental',
- getDescription=True))
- self.expectCommands(
- ## copied from test_mode_incremental:
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- ## plus this to test describe:
- ExpectShell(workdir='wkdir',
- command=['git', 'describe', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='Tag-1234')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- self.expectProperty('commit-description', 'Tag-1234', 'Git')
- return self.runStep()
-
- def test_getDescription_failed(self):
- # clone of: test_mode_incremental
- # only difference is to set the getDescription property
-
- # this tests when 'git describe' fails; for example, there are no
- # tags in the repository
-
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental',
- getDescription=True))
- self.expectCommands(
- ## copied from test_mode_incremental:
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- ## plus this to test describe:
- ExpectShell(workdir='wkdir',
- command=['git', 'describe', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='')
- + 128, # error, but it's suppressed
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- self.expectNoProperty('commit-description')
- return self.runStep()
-
- def setup_getDescription_test(self, setup_args, output_args, codebase=None):
- # clone of: test_mode_full_clobber
- # only difference is to set the getDescription property
-
- kwargs = {}
- if codebase is not None:
- kwargs.update(codebase=codebase)
-
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True,
- getDescription=setup_args,
- **kwargs))
-
- self.expectCommands(
- ## copied from test_mode_full_clobber:
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- ## plus this to test describe:
- ExpectShell(workdir='wkdir',
- command=['git', 'describe'] +
- output_args +
- ['HEAD'])
- + ExpectShell.log('stdio',
- stdout='Tag-1234')
- + 0,
- )
-
- if codebase:
- self.expectOutcome(result=SUCCESS, status_text=["update", codebase])
- self.expectProperty('got_revision', {codebase:'f6ad368298bd941e934a41f3babc827b2aa95a1d'}, 'Git')
- self.expectProperty('commit-description', {codebase:'Tag-1234'}, 'Git')
- else:
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- self.expectProperty('commit-description', 'Tag-1234', 'Git')
-
- def test_getDescription_empty_dict(self):
- self.setup_getDescription_test(
- setup_args = {},
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_empty_dict_with_codebase(self):
- self.setup_getDescription_test(
- setup_args = {},
- output_args = [],
- codebase = 'baz'
- )
- return self.runStep()
-
- def test_getDescription_match(self):
- self.setup_getDescription_test(
- setup_args = { 'match': 'stuff-*' },
- output_args = ['--match', 'stuff-*']
- )
- return self.runStep()
- def test_getDescription_match_false(self):
- self.setup_getDescription_test(
- setup_args = { 'match': None },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_tags(self):
- self.setup_getDescription_test(
- setup_args = { 'tags': True },
- output_args = ['--tags']
- )
- return self.runStep()
- def test_getDescription_tags_false(self):
- self.setup_getDescription_test(
- setup_args = { 'tags': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_all(self):
- self.setup_getDescription_test(
- setup_args = { 'all': True },
- output_args = ['--all']
- )
- return self.runStep()
- def test_getDescription_all_false(self):
- self.setup_getDescription_test(
- setup_args = { 'all': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_abbrev(self):
- self.setup_getDescription_test(
- setup_args = { 'abbrev': 7 },
- output_args = ['--abbrev=7']
- )
- return self.runStep()
- def test_getDescription_abbrev_zero(self):
- self.setup_getDescription_test(
- setup_args = { 'abbrev': 0 },
- output_args = ['--abbrev=0']
- )
- return self.runStep()
- def test_getDescription_abbrev_false(self):
- self.setup_getDescription_test(
- setup_args = { 'abbrev': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_dirty(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': True },
- output_args = ['--dirty']
- )
- return self.runStep()
- def test_getDescription_dirty_empty_str(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': '' },
- output_args = ['--dirty']
- )
- return self.runStep()
- def test_getDescription_dirty_str(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': 'foo' },
- output_args = ['--dirty=foo']
- )
- return self.runStep()
- def test_getDescription_dirty_false(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_contains(self):
- self.setup_getDescription_test(
- setup_args = { 'contains': True },
- output_args = ['--contains']
- )
- return self.runStep()
- def test_getDescription_contains_false(self):
- self.setup_getDescription_test(
- setup_args = { 'contains': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_candidates(self):
- self.setup_getDescription_test(
- setup_args = { 'candidates': 7 },
- output_args = ['--candidates=7']
- )
- return self.runStep()
- def test_getDescription_candidates_zero(self):
- self.setup_getDescription_test(
- setup_args = { 'candidates': 0 },
- output_args = ['--candidates=0']
- )
- return self.runStep()
- def test_getDescription_candidates_false(self):
- self.setup_getDescription_test(
- setup_args = { 'candidates': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_exact_match(self):
- self.setup_getDescription_test(
- setup_args = { 'exact-match': True },
- output_args = ['--exact-match']
- )
- return self.runStep()
- def test_getDescription_exact_match_false(self):
- self.setup_getDescription_test(
- setup_args = { 'exact-match': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_debug(self):
- self.setup_getDescription_test(
- setup_args = { 'debug': True },
- output_args = ['--debug']
- )
- return self.runStep()
- def test_getDescription_debug_false(self):
- self.setup_getDescription_test(
- setup_args = { 'debug': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_long(self):
- self.setup_getDescription_test(
- setup_args = { 'long': True },
- output_args = ['--long']
- )
- def test_getDescription_long_false(self):
- self.setup_getDescription_test(
- setup_args = { 'long': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_always(self):
- self.setup_getDescription_test(
- setup_args = { 'always': True },
- output_args = ['--always']
- )
- def test_getDescription_always_false(self):
- self.setup_getDescription_test(
- setup_args = { 'always': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_lotsa_stuff(self):
- self.setup_getDescription_test(
- setup_args = { 'match': 'stuff-*',
- 'abbrev': 6,
- 'exact-match': True},
- output_args = ['--exact-match',
- '--match', 'stuff-*',
- '--abbrev=6'],
- codebase='baz'
- )
- return self.runStep()
-
- def test_config_option(self):
- name = 'url.http://github.com.insteadOf'
- value = 'blahblah'
- self.setupStep(
- git.Git(repourl='%s/buildbot/buildbot.git' % (value,),
- mode='full', method='clean',
- config={name: value}))
- prefix = ['git', '-c', '%s=%s' % (name, value)]
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=prefix + ['--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['fetch', '-t',
- '%s/buildbot/buildbot.git' % (value,),
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['reset', '--hard',
- 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py
deleted file mode 100644
index e8543d97..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py
+++ /dev/null
@@ -1,863 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import mercurial
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-
-class TestMercurial(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def patch_slaveVersionIsOlderThan(self, result):
- self.patch(mercurial.Mercurial, 'slaveVersionIsOlderThan', lambda x, y, z: result)
-
- def test_no_repourl(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(mode="full"))
-
- def test_incorrect_mode(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='invalid'))
-
- def test_incorrect_method(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- method='invalid'))
-
- def test_incorrect_branchType(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- branchType='invalid'))
-
- def test_mode_full_clean(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_win32path(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'))
- self.build.path_module = namedModule('ntpath')
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_timeout(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- timeout=1,
- mode='full', method='clean', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_patch(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'import',
- '--no-commit', '-p', '1', '-'],
- initialStdin='patch')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_patch_fail(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'import',
- '--no-commit', '-p', '1', '-'],
- initialStdin='patch')
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_mode_full_clean_no_existing_repo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clobber', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone', '--noupdate',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='fresh', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge', '--all'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_fresh_no_existing_repo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='fresh', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_no_existing_repo_dirname(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='dirname'),
- )
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1, # does not exist
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.', '--noupdate'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
-
- def test_mode_incremental_branch_change_dirname(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org/',
- mode='incremental', branchType='dirname', defaultBranch='devel'),
- dict(branch='stable')
- )
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org/stable'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone', '--noupdate',
- 'http://hg.mozilla.org/stable', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_no_existing_repo_inrepo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1, # does not exist
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.', '--noupdate'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_existing_repo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0, # directory exists
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_existing_repo_added_files(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0, # directory exists
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + ExpectShell.log('stdio', stdout='foo\nbar/baz\n')
- + 1,
- Expect('rmdir', dict(dir=['wkdir/foo','wkdir/bar/baz'],
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_existing_repo_added_files_old_rmdir(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.patch_slaveVersionIsOlderThan(True)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0, # directory exists
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + ExpectShell.log('stdio', stdout='foo\nbar/baz\n')
- + 1,
- Expect('rmdir', dict(dir='wkdir/foo',
- logEnviron=True))
- + 0,
- Expect('rmdir', dict(dir='wkdir/bar/baz',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_given_revision(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'), dict(
- revision='abcdef01',
- ))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'abcdef01'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch_change(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'), dict(
- branch='stable',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone', '--noupdate',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'stable'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch_change_no_clobberOnBranchChange(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo',
- clobberOnBranchChange=False), dict(
- branch='stable',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'stable'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_env(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo',
- env={'abc': '123'}))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'], env={'abc': '123'})
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'], env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'], env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'],
- env={'abc': '123'})
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'], env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'], env={'abc': '123'})
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_logEnviron(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean',
- branchType='inrepo',
- logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'],
- logEnviron=False)
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=False))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'],
- logEnviron=False)
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'],
- logEnviron=False)
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_command_fails(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='fresh', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py
deleted file mode 100644
index 300ae091..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.trial import unittest
-
-from buildbot.steps.source import oldsource
-
-class SlaveSource(unittest.TestCase):
-
- def doCommandCompleteTest(self,
- cmdHasGotRevision=True,
- cmdGotRevision='rev',
- initialPropertyValue=None,
- expectedPropertyValue=None,
- expectSetProperty=True):
-
- # set up a step with getProperty and setProperty
- step = oldsource.SlaveSource(codebase='foo')
- def getProperty(prop, default=None):
- self.assert_(prop == 'got_revision')
- if initialPropertyValue is None:
- return default
- return initialPropertyValue
- step.getProperty = getProperty
-
- def setProperty(prop, value, source):
- raise RuntimeError("should not be calling setProperty directly")
- step.setProperty = setProperty
-
- def updateSourceProperty(prop, value):
- self.failUnlessEqual((prop, value),
- ('got_revision', expectedPropertyValue))
- self.propSet = True
- step.updateSourceProperty = updateSourceProperty
-
- # fake RemoteCommand, optionally with a got_revision update
- cmd = mock.Mock()
- cmd.updates = dict()
- if cmdHasGotRevision:
- cmd.updates['got_revision'] = [ cmdGotRevision ]
-
- # run the method and ensure it set something; the set asserts the
- # value is correct
- self.propSet = False
- step.commandComplete(cmd)
- self.assertEqual(self.propSet, expectSetProperty)
-
- def test_commandComplete_got_revision(self):
- self.doCommandCompleteTest(
- expectedPropertyValue='rev')
-
- def test_commandComplete_no_got_revision(self):
- self.doCommandCompleteTest(
- cmdHasGotRevision=False,
- expectSetProperty=False)
-
- def test_commandComplete_None_got_revision(self):
- self.doCommandCompleteTest(
- cmdGotRevision=None,
- expectSetProperty=False)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py
deleted file mode 100644
index 65c8739d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from twisted.internet import defer
-
-from buildbot.interfaces import IRenderable
-from buildbot.process.properties import Properties, WithProperties
-from buildbot.steps.source.oldsource import _ComputeRepositoryURL
-
-
-class SourceStamp(object):
- repository = "test"
-
-class Build(object):
- s = SourceStamp()
- props = Properties(foo = "bar")
- def getSourceStamp(self, codebase):
- assert codebase == ''
- return self.s
- def getProperties(self):
- return self.props
- def render(self, value):
- self.props.build = self
- return defer.maybeDeferred(IRenderable(value).getRenderingFor, self.props)
-
-class FakeStep(object):
- codebase = ''
-
-class RepoURL(unittest.TestCase):
- def setUp(self):
- self.build = Build()
-
- def test_backward_compatibility(self):
- url = _ComputeRepositoryURL(FakeStep(), "repourl")
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "repourl")
- return d
-
- def test_format_string(self):
- url = _ComputeRepositoryURL(FakeStep(), "http://server/%s")
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "http://server/test")
- return d
-
- def test_dict(self):
- dict = {}
- dict['test'] = "ssh://server/testrepository"
- url = _ComputeRepositoryURL(FakeStep(), dict)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "ssh://server/testrepository")
- return d
-
- def test_callable(self):
- func = lambda x: x[::-1]
- url = _ComputeRepositoryURL(FakeStep(), func)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "tset")
- return d
-
- def test_backward_compatibility_render(self):
- url = _ComputeRepositoryURL(FakeStep(), WithProperties("repourl%(foo)s"))
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "repourlbar")
- return d
-
- def test_dict_render(self):
- d = dict(test=WithProperties("repourl%(foo)s"))
- url = _ComputeRepositoryURL(FakeStep(), d)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "repourlbar")
- return d
-
- def test_callable_render(self):
- func = lambda x: WithProperties(x+"%(foo)s")
- url = _ComputeRepositoryURL(FakeStep(), func)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "testbar")
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py
deleted file mode 100644
index bb8c8a26..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildbot.steps.source import Repo
-
-class RepoURL(unittest.TestCase):
-
- def test_parse1(self):
- r = Repo()
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12"),["test/bla 564/12"])
- def test_parse2(self):
- r = Repo()
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12 repo download test/bla 564/2"),["test/bla 564/12","test/bla 564/2"])
- def test_parse3(self):
- r = Repo()
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12 repo download test/bla 564/2 test/foo 5/1"),["test/bla 564/12","test/bla 564/2","test/foo 5/1"])
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12"),["test/bla 564/12"])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py
deleted file mode 100644
index b822f01f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py
+++ /dev/null
@@ -1,423 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-# Portions Copyright 2013 Bad Dog Consulting
-
-
-from twisted.trial import unittest
-from buildbot.steps.source.p4 import P4
-from buildbot.status.results import SUCCESS
-from buildbot.test.util import sourcesteps
-from buildbot.test.util.properties import ConstantRenderable
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-import textwrap
-
-
-class TestP4(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def setupStep(self, step, args={}, patch=None, **kwargs):
- step = sourcesteps.SourceStepMixin.setupStep(self, step, args={}, patch=None, **kwargs)
- self.build.getSourceStamp().revision = args.get('revision', None)
-
- # builddir propety used to create absolute path required in perforce client spec.
- self.properties.setProperty('builddir', '/home/user/workspace', 'P4')
-
- def test_no_empty_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda: P4())
-
- def test_no_multiple_type_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4viewspec=('//depot/trunk', ''),
- p4base='//depot', p4branch='trunk',
- p4extra_views=['src', 'doc']))
-
- def test_no_p4viewspec_is_string_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4viewspec='a_bad_idea'))
-
- def test_no_p4base_has_trailing_slash_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4base='//depot/'))
-
- def test_no_p4branch_has_trailing_slash_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4base='//depot', p4branch='blah/'))
-
- def test_no_p4branch_with_no_p4base_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4branch='blah'))
-
- def test_no_p4extra_views_with_no_p4base_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4extra_views='blah'))
-
- def test_incorrect_mode(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4base='//depot',
- mode='invalid'))
-
- def test_mode_incremental_p4base_with_revision(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4base='//depot', p4branch='trunk',
- p4user='user', p4client='p4_client1', p4passwd='pass'),
- dict(revision='100',))
-
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- ''');
-
- self.expectCommands(
- ExpectShell(workdir='wkdir', # defaults to this, only changes if it has a copy mode.
- command=['p4', '-V']) # expected remote command
- + 0, # expected exit status
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'client', '-i'],
- initialStdin=client_spec)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'sync', '//depot...@100'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'changes', '-m1', '#have'])
- + ExpectShell.log('stdio',
- stdout="Change 100 on 2013/03/21 by user@machine \'duh\'")
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'P4')
- return self.runStep()
-
- def _incremental(self, client_stdin=''):
- self.expectCommands(
- ExpectShell(workdir='wkdir', # defaults to this, only changes if it has a copy mode.
- command=['p4', '-V']) # expected remote command
- + 0, # expected exit status
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'client', '-i'],
- initialStdin=client_stdin,)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'sync'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'changes', '-m1', '#have'])
- + ExpectShell.log('stdio',
- stdout="Change 100 on 2013/03/21 by user@machine \'duh\'")
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'P4')
- return self.runStep()
-
- def test_mode_incremental_p4base(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4base='//depot', p4branch='trunk',
- p4user='user', p4client='p4_client1', p4passwd='pass'))
-
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- ''')
- self._incremental(client_stdin=client_spec)
-
- def test_mode_incremental_p4base_with_p4extra_views(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4base='//depot', p4branch='trunk',
- p4extra_views=[('-//depot/trunk/test', 'test'),
- ('-//depot/trunk/doc', 'doc')],
- p4user='user', p4client='p4_client1', p4passwd='pass'))
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- \t-//depot/trunk/test/... //p4_client1/test/...
- \t-//depot/trunk/doc/... //p4_client1/doc/...
- ''')
- self._incremental(client_stdin=client_spec)
-
- def test_mode_incremental_p4viewspec(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4viewspec=[('//depot/trunk/', '')],
- p4user='user', p4client='p4_client1', p4passwd='pass'))
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- ''')
- self._incremental(client_stdin=client_spec)
-
- def _full(self, client_stdin='', p4client='p4_client1', p4user='user'):
- self.expectCommands(
- ExpectShell(workdir='wkdir', # defaults to this, only changes if it has a copy mode.
- command=['p4', '-V']) # expected remote command
- + 0, # expected exit status
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'client',
- '-i'],
- initialStdin=client_stdin)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'sync',
- '#none'])
- + 0,
-
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'sync'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'changes',
- '-m1', '#have'])
- + ExpectShell.log('stdio',
- stdout="Change 100 on 2013/03/21 by user@machine \'duh\'")
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'P4')
- return self.runStep()
-
- def test_mode_full_p4base(self):
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base='//depot', p4branch='trunk',
- p4user='user', p4client='p4_client1', p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...\n''')
- self._full(client_stdin=client_stdin)
-
- def test_mode_full_p4viewspec(self):
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4viewspec=[('//depot/main/', '')],
- p4user='user', p4client='p4_client1', p4passwd='pass'))
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/main/... //p4_client1/...\n''')
-
- self._full(client_stdin=client_stdin)
-
- def test_mode_full_renderable_p4base(self):
- # Note that the config check skips checking p4base if it's a renderable
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base=ConstantRenderable('//depot'),
- p4branch='release/1.0', p4user='user', p4client='p4_client2',
- p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client2
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/release/1.0/... //p4_client2/...\n''')
-
- self._full(client_stdin=client_stdin, p4client='p4_client2')
-
- def test_mode_full_renderable_p4client(self):
- # Note that the config check skips checking p4base if it's a renderable
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base='//depot', p4branch='trunk',
- p4user='user', p4client=ConstantRenderable('p4_client_render'),
- p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client_render
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client_render/...\n''')
-
- self._full(client_stdin=client_stdin, p4client='p4_client_render')
-
- def test_mode_full_renderable_p4branch(self):
- # Note that the config check skips checking p4base if it's a renderable
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base='//depot',
- p4branch=ConstantRenderable('render_branch'),
- p4user='user', p4client='p4_client1', p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/render_branch/... //p4_client1/...\n''')
-
- self._full(client_stdin=client_stdin)
-
- def test_mode_full_renderable_p4viewspec(self):
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full',
- p4viewspec=[(ConstantRenderable('//depot/render_trunk/'), '')],
- p4user='different_user', p4client='p4_client1',
- p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: different_user
-
- Description:
- \tCreated by different_user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/render_trunk/... //p4_client1/...\n''')
-
- self._full(client_stdin=client_stdin, p4user='different_user')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py
deleted file mode 100644
index 0baaa0ed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py
+++ /dev/null
@@ -1,613 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.steps.source import repo
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot.process.properties import Properties
-from .test_changes_gerritchangesource import TestGerritChangeSource
-from buildbot.changes.changes import Change
-import os
-
-
-class RepoURL(unittest.TestCase):
- # testcases taken from old_source/Repo test
-
- def oneTest(self, props, expected):
- p = Properties()
- p.update(props, "test")
- r = repo.RepoDownloadsFromProperties(props.keys())
- self.assertEqual(r.getRenderingFor(p), expected)
-
- def test_parse1(self):
- self.oneTest(
- {'a': "repo download test/bla 564/12"}, ["test/bla 564/12"])
-
- def test_parse2(self):
- self.oneTest(
- {'a':
- "repo download test/bla 564/12 repo download test/bla 564/2"},
- ["test/bla 564/12", "test/bla 564/2"])
- self.oneTest({'a': "repo download test/bla 564/12", 'b': "repo download test/bla 564/2"}, [
- "test/bla 564/12", "test/bla 564/2"])
-
- def test_parse3(self):
- self.oneTest({'a': "repo download test/bla 564/12 repo download test/bla 564/2 test/foo 5/1"}, [
- "test/bla 564/12", "test/bla 564/2", "test/foo 5/1"])
- self.oneTest(
- {'a': "repo download test/bla 564/12"}, ["test/bla 564/12"])
-
-
-class TestRepo(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- self.shouldRetry = False
- self.logEnviron = True
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def shouldLogEnviron(self):
- r = self.logEnviron
- self.logEnviron = False
- return r
-
- def ExpectShell(self, **kw):
- if 'workdir' not in kw:
- kw['workdir'] = 'wkdir'
- if 'logEnviron' not in kw:
- kw['logEnviron'] = self.shouldLogEnviron()
- return ExpectShell(**kw)
-
- def mySetupStep(self, **kwargs):
- if "repoDownloads" not in kwargs:
- kwargs.update(
- dict(repoDownloads=repo.RepoDownloadsFromProperties(["repo_download", "repo_download2"])))
- self.setupStep(
- repo.Repo(manifestURL='git://myrepo.com/manifest.git',
- manifestBranch="mb",
- manifestFile="mf",
- **kwargs))
- self.build.allChanges = lambda x=None: []
-
- def myRunStep(self, result=SUCCESS, status_text=["update"]):
- self.expectOutcome(result=result, status_text=status_text)
- d = self.runStep()
-
- def printlogs(res):
- text = self.step.stdio_log.getTextWithHeaders()
- if "Failure instance" in text and not self.shouldRetry:
- print text
- return res
- d.addBoth(printlogs)
- return d
-
- def expectClobber(self):
- # stat return 1 so we clobber
- self.expectCommands(
- Expect('stat', dict(file=os.path.join('wkdir', '.repo'),
- logEnviron=self.logEnviron))
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=self.logEnviron))
- + 0,
- Expect('mkdir', dict(dir='wkdir',
- logEnviron=self.logEnviron))
- + 0,
- )
-
- def expectnoClobber(self):
- # stat return 0, so nothing
- self.expectCommands(
- Expect('stat', dict(file=os.path.join('wkdir', '.repo'),
- logEnviron=self.logEnviron))
- + 0,
- )
-
- def expectRepoSync(self, which_fail=-1, breakatfail=False, syncoptions=["-c"], override_commands=[]):
- commands = [
- self.ExpectShell(
- command=[
- 'bash', '-c', self.step._getCleanupCommand()]),
- self.ExpectShell(
- command=['repo', 'init', '-u', 'git://myrepo.com/manifest.git',
- '-b', 'mb', '-m', 'mf'])
- ] + override_commands + [
- self.ExpectShell(command=['repo', 'sync'] + syncoptions),
- self.ExpectShell(
- command=['repo', 'manifest', '-r', '-o', 'manifest-original.xml'])
- ]
- for i in xrange(len(commands)):
- self.expectCommands(commands[i] + (which_fail == i and 1 or 0))
- if which_fail == i and breakatfail:
- break
-
- def test_basic(self):
- """basic first time repo sync"""
- self.mySetupStep(repoDownloads=None)
- self.expectClobber()
- self.expectRepoSync()
- return self.myRunStep(status_text=["update"])
-
- def test_update(self):
- """basic second time repo sync"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync()
- return self.myRunStep(status_text=["update"])
-
- def test_jobs(self):
- """basic first time repo sync with jobs"""
- self.mySetupStep(jobs=2)
- self.expectClobber()
- self.expectRepoSync(syncoptions=["-j2", "-c"])
- return self.myRunStep(status_text=["update"])
-
- def test_sync_all_branches(self):
- """basic first time repo sync with all branches"""
- self.mySetupStep(syncAllBranches=True)
- self.expectClobber()
- self.expectRepoSync(syncoptions=[])
- return self.myRunStep(status_text=["update"])
-
- def test_manifest_override(self):
- """repo sync with manifest_override_url property set
- download via wget
- """
- self.mySetupStep(manifestOverrideUrl=
- "http://u.rl/test.manifest",
- syncAllBranches=True)
- self.expectClobber()
- override_commands = [
- Expect(
- 'stat', dict(file=os.path.join('wkdir', 'http://u.rl/test.manifest'),
- logEnviron=False)),
- self.ExpectShell(logEnviron=False, command=['wget',
- 'http://u.rl/test.manifest',
- '-O', 'manifest_override.xml']),
- self.ExpectShell(
- logEnviron=False, workdir=os.path.join('wkdir', '.repo'),
- command=['ln', '-sf', '../manifest_override.xml',
- 'manifest.xml'])
- ]
- self.expectRepoSync(which_fail=2, syncoptions=[],
- override_commands=override_commands)
- return self.myRunStep(status_text=["update"])
-
- def test_manifest_override_local(self):
- """repo sync with manifest_override_url property set
- copied from local FS
- """
- self.mySetupStep(manifestOverrideUrl=
- "test.manifest",
- syncAllBranches=True)
- self.expectClobber()
- override_commands = [
- Expect('stat', dict(file=os.path.join('wkdir', 'test.manifest'),
- logEnviron=False)),
- self.ExpectShell(logEnviron=False,
- command=[
- 'cp', '-f', 'test.manifest', 'manifest_override.xml']),
- self.ExpectShell(logEnviron=False,
- workdir=os.path.join('wkdir', '.repo'),
- command=['ln', '-sf', '../manifest_override.xml',
- 'manifest.xml'])
- ]
- self.expectRepoSync(
- syncoptions=[], override_commands=override_commands)
- return self.myRunStep(status_text=["update"])
-
- def test_tarball(self):
- """repo sync using the tarball cache
- """
- self.mySetupStep(tarball="/tarball.tar")
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(command=['tar', '-xvf', '/tarball.tar']) + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.tar'])
- + Expect.log('stdio', stdout=str(10000))
- + 0)
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10000 + 7 * 24 * 3600))
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_create_tarball(self):
- """repo sync create the tarball if its not here
- """
- self.mySetupStep(tarball="/tarball.tgz")
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(
- command=['tar', '-z', '-xvf', '/tarball.tgz']) + 1,
- self.ExpectShell(command=['rm', '-f', '/tarball.tgz']) + 1,
- Expect('rmdir', dict(dir=os.path.join('wkdir', '.repo'),
- logEnviron=False))
- + 1)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.tgz'])
- + Expect.log('stdio', stderr="file not found!")
- + 1,
- self.ExpectShell(command=['tar', '-z',
- '-cvf', '/tarball.tgz', '.repo'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def do_test_update_tarball(self, suffix, option):
- """repo sync update the tarball cache at the end (tarball older than a week)
- """
- self.mySetupStep(tarball="/tarball." + suffix)
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(command=['tar'] + option + ['-xvf', '/tarball.' + suffix]) + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.' + suffix])
- + Expect.log('stdio', stdout=str(10000))
- + 0,
- self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10001 + 7 * 24 * 3600))
- + 0,
- self.ExpectShell(command=['tar'] + option +
- ['-cvf', '/tarball.' + suffix, '.repo'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_update_tarball(self):
- self.do_test_update_tarball("tar", [])
-
- def test_update_tarball_gz(self):
- """tarball compression variants"""
- self.do_test_update_tarball("tar.gz", ["-z"])
-
- def test_update_tarball_tgz(self):
- self.do_test_update_tarball("tgz", ["-z"])
-
- def test_update_tarball_bzip(self):
- self.do_test_update_tarball("tar.bz2", ["-j"])
-
- def test_update_tarball_lzma(self):
- self.do_test_update_tarball("tar.lzma", ["--lzma"])
-
- def test_update_tarball_lzop(self):
- self.do_test_update_tarball("tar.lzop", ["--lzop"])
-
- def test_update_tarball_fail1(self, suffix="tar", option=[]):
- """tarball extract fail -> remove the tarball + remove .repo dir
- """
- self.mySetupStep(tarball="/tarball." + suffix)
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(
- command=[
- 'tar'] + option + ['-xvf', '/tarball.' + suffix]) + 1,
- self.ExpectShell(
- command=['rm', '-f', '/tarball.tar']) + 0,
- Expect(
- 'rmdir', dict(dir=os.path.join('wkdir', '.repo'),
- logEnviron=False))
- + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.' + suffix])
- + Expect.log('stdio', stdout=str(10000))
- + 0,
- self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10001 + 7 * 24 * 3600))
- + 0,
- self.ExpectShell(command=['tar'] + option +
- ['-cvf', '/tarball.' + suffix, '.repo'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_update_tarball_fail2(self, suffix="tar", option=[]):
- """tarball update fail -> remove the tarball + continue repo download
- """
- self.mySetupStep(tarball="/tarball." + suffix)
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(command=['tar'] + option + ['-xvf', '/tarball.' + suffix]) + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.' + suffix])
- + Expect.log('stdio', stdout=str(10000))
- + 0,
- self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10001 + 7 * 24 * 3600))
- + 0,
- self.ExpectShell(command=['tar'] + option +
- ['-cvf', '/tarball.' + suffix, '.repo'])
- + 1,
- self.ExpectShell(
- command=['rm', '-f', '/tarball.tar']) + 0,
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads(self):
- """basic repo download, and check that repo_downloaded is updated"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0
- + Expect.log(
- 'stdio', stderr="test/bla refs/changes/64/564/12 -> FETCH_HEAD\n")
- + Expect.log('stdio', stderr="HEAD is now at 0123456789abcdef...\n"))
- self.expectProperty(
- "repo_downloaded", "564/12 0123456789abcdef ", "Source")
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads2(self):
- """2 repo downloads"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.build.setProperty("repo_download2",
- "repo download test/bla2 565/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0,
- self.ExpectShell(
- command=['repo', 'download', 'test/bla2', '565/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_download_manifest(self):
- """2 repo downloads, with one manifest patch"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.build.setProperty("repo_download2",
- "repo download manifest 565/12", "test")
- self.expectnoClobber()
- self.expectCommands(
- self.ExpectShell(
- command=['bash', '-c', self.step._getCleanupCommand()])
- + 0,
- self.ExpectShell(
- command=['repo', 'init', '-u', 'git://myrepo.com/manifest.git',
- '-b', 'mb', '-m', 'mf'])
- + 0,
- self.ExpectShell(
- workdir=os.path.join('wkdir', '.repo', 'manifests'),
- command=[
- 'git', 'fetch', 'git://myrepo.com/manifest.git',
- 'refs/changes/65/565/12'])
- + 0,
- self.ExpectShell(
- workdir=os.path.join('wkdir', '.repo', 'manifests'),
- command=['git', 'cherry-pick', 'FETCH_HEAD'])
- + 0,
- self.ExpectShell(command=['repo', 'sync', '-c'])
- + 0,
- self.ExpectShell(
- command=['repo', 'manifest', '-r', '-o', 'manifest-original.xml'])
- + 0)
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads_mirror_sync(self):
- """repo downloads, with mirror synchronization issues"""
- self.mySetupStep()
- self.step.mirror_sync_sleep = 0.001 # we dont really want the test to wait...
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads_change_missing(self):
- """repo downloads, with no actual mirror synchronization issues (still retries 2 times)"""
- self.mySetupStep()
- self.step.mirror_sync_sleep = 0.001 # we dont really want the test to wait...
- self.step.mirror_sync_retry = 1 # on retry once
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- )
- return self.myRunStep(result=FAILURE, status_text=["repo: change test/bla 564/12 does not exist"])
-
- def test_repo_downloads_fail1(self):
- """repo downloads, cherry-pick returns 1"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 + Expect.log("stdio", stderr="patch \n"),
- self.ExpectShell(
- command=['repo', 'forall', '-c', 'git', 'diff', 'HEAD'])
- + 0
- )
- return self.myRunStep(result=FAILURE, status_text=["download failed: test/bla 564/12"])
-
- def test_repo_downloads_fail2(self):
- """repo downloads, cherry-pick returns 0 but error in stderr"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0 +
- Expect.log("stdio", stderr="Automatic cherry-pick failed \n"),
- self.ExpectShell(
- command=['repo', 'forall', '-c', 'git', 'diff', 'HEAD'])
- + 0
- )
- return self.myRunStep(result=FAILURE, status_text=["download failed: test/bla 564/12"])
-
- def test_repo_downloads_from_change_source(self):
- """basic repo download from change source, and check that repo_downloaded is updated"""
- self.mySetupStep(repoDownloads=repo.RepoDownloadsFromChangeSource())
- chdict = TestGerritChangeSource.expected_change
- change = Change(None, None, None, properties=chdict['properties'])
- self.build.allChanges = lambda x=None: [change]
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(command=['repo', 'download', 'pr', '4321/12'])
- + 0
- + Expect.log(
- 'stdio', stderr="test/bla refs/changes/64/564/12 -> FETCH_HEAD\n")
- + Expect.log('stdio', stderr="HEAD is now at 0123456789abcdef...\n"))
- self.expectProperty(
- "repo_downloaded", "564/12 0123456789abcdef ", "Source")
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads_from_change_source_codebase(self):
- """basic repo download from change source, and check that repo_downloaded is updated"""
- self.mySetupStep(repoDownloads=repo.RepoDownloadsFromChangeSource("mycodebase"))
- chdict = TestGerritChangeSource.expected_change
- change = Change(None, None, None, properties=chdict['properties'])
- # getSourceStamp is faked by SourceStepMixin
- ss = self.build.getSourceStamp("")
- ss.changes = [change]
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(command=['repo', 'download', 'pr', '4321/12'])
- + 0
- + Expect.log(
- 'stdio', stderr="test/bla refs/changes/64/564/12 -> FETCH_HEAD\n")
- + Expect.log('stdio', stderr="HEAD is now at 0123456789abcdef...\n"))
- self.expectProperty(
- "repo_downloaded", "564/12 0123456789abcdef ", "Source")
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail1(self):
- """ fail at cleanup: ignored"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=0, breakatfail=False)
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail2(self):
- """fail at repo init: clobber"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync()
- self.shouldRetry = True
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail3(self):
- """ fail at repo sync: clobber"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=2, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync()
- self.shouldRetry = True
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail4(self):
- """fail at repo manifest: clobber"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=3, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync()
- self.shouldRetry = True
- return self.myRunStep(status_text=["update"])
-
- def test_update_doublefail(self):
- """fail at repo manifest: clobber but still fail"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=3, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync(which_fail=3, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo manifest"])
-
- def test_update_doublefail2(self):
- """fail at repo sync: clobber but still fail"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=2, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync(which_fail=2, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo sync"])
-
- def test_update_doublefail3(self):
- """fail at repo init: clobber but still fail"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo init"])
-
- def test_basic_fail(self):
- """fail at repo init: no need to re-clobber but still fail"""
- self.mySetupStep()
- self.expectClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo init"])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py
deleted file mode 100644
index b1c4e2ce..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py
+++ /dev/null
@@ -1,1477 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import svn
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.process import buildstep
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot.test.util.properties import ConstantRenderable
-from buildbot import config
-
-class TestSVN(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file1">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file2">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- svn_st_xml_corrupt = """<?xml version="1.0"?>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- svn_st_xml_empty = """<?xml version="1.0"?>
- <status>
- <target path=".">
- </target>
- </status>"""
- svn_info_stdout_xml = """<?xml version="1.0"?>
- <info>
- <entry
- kind="dir"
- path="."
- revision="100">
- <url>http://svn.red-bean.com/repos/test</url>
- <repository>
- <root>http://svn.red-bean.com/repos/test</root>
- <uuid>5e7d134a-54fb-0310-bd04-b611643e5c25</uuid>
- </repository>
- <wc-info>
- <schedule>normal</schedule>
- <depth>infinity</depth>
- </wc-info>
- <commit
- revision="90">
- <author>sally</author>
- <date>2003-01-15T23:35:12.847647Z</date>
- </commit>
- </entry>
- </info>"""
- svn_info_stdout_xml_nonintegerrevision = """<?xml version="1.0"?>
- <info>
- <entry
- kind="dir"
- path="."
- revision="a10">
- <url>http://svn.red-bean.com/repos/test</url>
- <repository>
- <root>http://svn.red-bean.com/repos/test</root>
- <uuid>5e7d134a-54fb-0310-bd04-b611643e5c25</uuid>
- </repository>
- <wc-info>
- <schedule>normal</schedule>
- <depth>infinity</depth>
- </wc-info>
- <commit
- revision="a10">
- <author>sally</author>
- <date>2003-01-15T23:35:12.847647Z</date>
- </commit>
- </entry>
- </info>"""
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def patch_slaveVersionIsOlderThan(self, result):
- self.patch(svn.SVN, 'slaveVersionIsOlderThan', lambda x, y, z: result)
-
- def test_no_repourl(self):
- self.assertRaises(config.ConfigErrors, lambda :
- svn.SVN())
-
- def test_incorrect_mode(self):
- self.assertRaises(config.ConfigErrors, lambda :
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='invalid'))
-
- def test_incorrect_method(self):
- self.assertRaises(config.ConfigErrors, lambda :
- svn.SVN(repourl='http://svn.local/app/trunk',
- method='invalid'))
-
- def test_corrupt_xml(self):
- self.setupStep(svn.SVN(repourl='http://svn.local/app/trunk'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_corrupt)
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_revision_noninteger(self):
- svnTestStep = svn.SVN(repourl='http://svn.local/app/trunk')
- self.setupStep(svnTestStep)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml_nonintegerrevision)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'a10', 'SVN')
- d = self.runStep()
- def _checkType():
- revision = self.step.getProperty('got_revision')
- self.assertRaises(ValueError, lambda: int(revision))
- d.addCallback(lambda _: _checkType())
- return d
-
- def test_revision_missing(self):
- """Fail if 'revision' tag isnt there"""
- svn_info_stdout = self.svn_info_stdout_xml.replace('entry', 'Blah')
-
- svnTestStep = svn.SVN(repourl='http://svn.local/app/trunk')
- self.setupStep(svnTestStep)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=svn_info_stdout)
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_timeout(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- timeout=1,
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_repourl_renderable(self):
- self.setupStep(
- svn.SVN(repourl=ConstantRenderable('http://svn.local/trunk'),
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_repourl_not_updatable(self):
- self.setupStep(
- svn.SVN(repourl=ConstantRenderable('http://svn.local/trunk/app'),
- mode='incremental',))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 1,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/trunk/app',
- '.', '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_repourl_not_updatable_svninfo_mismatch(self):
- self.setupStep(
- svn.SVN(repourl=ConstantRenderable('http://svn.local/trunk/app'),
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio', # expecting ../trunk/app
- stdout="""<?xml version="1.0"?><url>http://svn.local/branch/foo/app</url>""")
- + 0,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/trunk/app',
- '.', '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental'), dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_win32path(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.build.path_module = namedModule("ntpath")
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_preferLastChangedRev(self):
- """Give the last-changed rev if 'preferLastChangedRev' is set"""
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- preferLastChangedRev=True,
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '90', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_preferLastChangedRev_butMissing(self):
- """If 'preferLastChangedRev' is set, but missing, fall back
- to the regular revision value."""
- svn_info_stdout = self.svn_info_stdout_xml.replace('commit', 'Blah')
-
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- preferLastChangedRev=True,
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=svn_info_stdout)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', {'dir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout',
- 'http://svn.local/app/trunk', '.',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clobber_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clobber'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', {'dir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout',
- 'http://svn.local/app/trunk', '.',
- '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='fresh', depth='infinite'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--depth', 'infinite' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache',
- '--depth', 'infinite'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache', '--depth', 'infinite'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + ExpectShell.log('stdio', stdout='\n')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_fresh_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='fresh', depth='infinite'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--depth', 'infinite' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache',
- '--depth', 'infinite'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache', '--depth', 'infinite'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + ExpectShell.log('stdio', stdout='\n')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_fresh_keep_on_purge(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full',
- keep_on_purge=['svn_external_path/unversioned_file1']))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- ['wkdir/svn_external_path/unversioned_file2'],
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_not_updatable(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 1,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/app/trunk',
- '.', '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_not_updatable_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 1,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/app/trunk',
- '.', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean_old_rmdir(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
- self.patch_slaveVersionIsOlderThan(True)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- 'wkdir/svn_external_path/unversioned_file1',
- 'logEnviron': True})
- + 0,
- Expect('rmdir', {'dir':
- 'wkdir/svn_external_path/unversioned_file2',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean_new_rmdir(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
-
- self.patch_slaveVersionIsOlderThan(False)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- ['wkdir/svn_external_path/unversioned_file1',
- 'wkdir/svn_external_path/unversioned_file2'],
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_copy(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'todir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_copy_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'todir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_export(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='export'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='',
- command=['svn', 'export', 'source', 'wkdir'])
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_export_timeout(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- timeout=1,
- mode='full', method='export'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- timeout=1,
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- timeout=1,
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='',
- timeout=1,
- command=['svn', 'export', 'source', 'wkdir'])
- + 0,
- ExpectShell(workdir='source',
- timeout=1,
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_export_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='export'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='',
- command=['svn', 'export', '--revision', '100',
- 'source', 'wkdir'])
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_with_env(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random'],
- env={'abc': '123'}))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'],
- env={'abc': '123'})
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_logEnviron(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random'],
- logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'],
- logEnviron=False)
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=False))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_command_fails(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_bogus_svnversion(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio', stdout="""<?xml version="1.0"?><entry kind="dir" path="/a/b/c" revision="1"><url>http://svn.local/app/trunk</url></entry>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout='1x0y0')
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_rmdir_fails_clobber(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', {'dir': 'wkdir',
- 'logEnviron': True})
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_rmdir_fails_copy(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_cpdir_fails_copy(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'todir': 'wkdir',
- 'logEnviron': True})
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_rmdir_fails_purge(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full',
- keep_on_purge=['svn_external_path/unversioned_file1']))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- ['wkdir/svn_external_path/unversioned_file2'],
- 'logEnviron': True})
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
-class TestGetUnversionedFiles(unittest.TestCase):
- def test_getUnversionedFiles_does_not_list_externals(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals(["svn_external_path/unversioned_file"], unversioned_files)
-
- def test_getUnversionedFiles_does_not_list_missing(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="missing_file">
- <wc-status props="none" item="missing"></wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals([], unversioned_files)
-
- def test_getUnversionedFiles_corrupted_xml(self):
- svn_st_xml_corrupt = """<?xml version="1.0"?>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- self.assertRaises(buildstep.BuildStepFailed,
- lambda : list(svn.SVN.getUnversionedFiles(svn_st_xml_corrupt, [])))
-
- def test_getUnversionedFiles_no_path(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry>
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals([], unversioned_files)
-
- def test_getUnversionedFiles_no_item(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals(["svn_external_path/unversioned_file"], unversioned_files)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py
deleted file mode 100644
index a639b071..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-import StringIO
-from zope.interface import implements
-from twisted.trial import unittest
-from buildbot import interfaces
-from buildbot.steps import subunit
-from buildbot.process import subunitlogobserver
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-
-class StubLogObserver(mock.Mock):
- implements(interfaces.ILogObserver)
-
-class TestSetPropertiesFromEnv(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- self.logobserver = StubLogObserver()
- self.logobserver.failures = []
- self.logobserver.errors = []
- self.logobserver.skips = []
- self.logobserver.testsRun = 0
- self.logobserver.warningio = StringIO.StringIO()
- self.patch(subunitlogobserver, 'SubunitLogObserver',
- lambda : self.logobserver)
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_empty(self):
- self.setupStep(subunit.SubunitShellCommand(command='test'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="test")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["shell", "no tests", "run"])
- return self.runStep()
-
- def test_empty_error(self):
- self.setupStep(subunit.SubunitShellCommand(command='test',
- failureOnNoTests=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="test")
- + 0
- )
- self.expectOutcome(result=FAILURE,
- status_text=["shell", "no tests", "run"])
- return self.runStep()
-
- def test_warnings(self):
- self.setupStep(subunit.SubunitShellCommand(command='test'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="test")
- + 0
- )
- self.logobserver.warnings.append('not quite up to snuff (list)')
- self.logobserver.warningio.write('not quite up to snuff (io)\n')
- self.logobserver.testsRun = 3
- self.expectOutcome(result=SUCCESS, # N.B. not WARNINGS
- status_text=["shell", "3 tests", "passed"])
- # note that the warnings list is ignored..
- self.expectLogfile('warnings', 'not quite up to snuff (io)\n')
- return self.runStep()
-
- # TODO: test text2 generation?
- # TODO: tests are represented as objects?!
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py
deleted file mode 100644
index cfdcefb9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import tempfile, os
-import shutil
-import tarfile
-from twisted.trial import unittest
-
-from mock import Mock
-
-from buildbot.process.properties import Properties
-from buildbot.util import json
-from buildbot.steps import transfer
-from buildbot.status.results import SUCCESS
-from buildbot import config
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import Expect, ExpectRemoteRef
-
-class TestFileUpload(unittest.TestCase):
- def setUp(self):
- fd, self.destfile = tempfile.mkstemp()
- os.close(fd)
- os.unlink(self.destfile)
-
- def tearDown(self):
- if os.path.exists(self.destfile):
- os.unlink(self.destfile)
-
- def test_constructor_mode_type(self):
- self.assertRaises(config.ConfigErrors, lambda :
- transfer.FileUpload(slavesrc=__file__, masterdest='xyz', mode='g+rwx'))
-
- def testBasic(self):
- s = transfer.FileUpload(slavesrc=__file__, masterdest=self.destfile)
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = 1
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'uploadFile':
- self.assertEquals(kwargs['slavesrc'], __file__)
- writer = kwargs['writer']
- with open(__file__, "rb") as f:
- writer.remote_write(f.read())
- self.assert_(not os.path.exists(self.destfile))
- writer.remote_close()
- break
- else:
- self.assert_(False, "No uploadFile command found")
-
- with open(self.destfile, "rb") as dest:
- with open(__file__, "rb") as expect:
- self.assertEquals(dest.read(), expect.read())
-
- def testTimestamp(self):
- s = transfer.FileUpload(slavesrc=__file__, masterdest=self.destfile, keepstamp=True)
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = "2.13"
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
- s.start()
- timestamp = ( os.path.getatime(__file__),
- os.path.getmtime(__file__) )
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'uploadFile':
- self.assertEquals(kwargs['slavesrc'], __file__)
- writer = kwargs['writer']
- with open(__file__, "rb") as f:
- writer.remote_write(f.read())
- self.assert_(not os.path.exists(self.destfile))
- writer.remote_close()
- writer.remote_utime(timestamp)
- break
- else:
- self.assert_(False, "No uploadFile command found")
-
- desttimestamp = ( os.path.getatime(self.destfile),
- os.path.getmtime(self.destfile) )
-
- timestamp = map(int, timestamp)
- desttimestamp = map(int, desttimestamp)
-
- self.assertEquals(timestamp[0],desttimestamp[0])
- self.assertEquals(timestamp[1],desttimestamp[1])
-
- def testURL(self):
- s = transfer.FileUpload(slavesrc=__file__, masterdest=self.destfile, url="http://server/file")
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = "2.13"
-
- s.step_status = Mock()
- s.step_status.addURL = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'uploadFile':
- self.assertEquals(kwargs['slavesrc'], __file__)
- writer = kwargs['writer']
- with open(__file__, "rb") as f:
- writer.remote_write(f.read())
- self.assert_(not os.path.exists(self.destfile))
- writer.remote_close()
- break
- else:
- self.assert_(False, "No uploadFile command found")
-
- s.step_status.addURL.assert_called_once_with(
- os.path.basename(self.destfile), "http://server/file")
-
-class TestDirectoryUpload(steps.BuildStepMixin, unittest.TestCase):
- def setUp(self):
- self.destdir = os.path.abspath('destdir')
- if os.path.exists(self.destdir):
- shutil.rmtree(self.destdir)
-
- return self.setUpBuildStep()
-
- def tearDown(self):
- if os.path.exists(self.destdir):
- shutil.rmtree(self.destdir)
-
- return self.tearDownBuildStep()
-
- def testBasic(self):
- self.setupStep(
- transfer.DirectoryUpload(slavesrc="srcdir", masterdest=self.destdir))
-
- def upload_behavior(command):
- from cStringIO import StringIO
- f = StringIO()
- archive = tarfile.TarFile(fileobj=f, name='fake.tar', mode='w')
- archive.addfile(tarfile.TarInfo("test"), StringIO("Hello World!"))
- writer = command.args['writer']
- writer.remote_write(f.getvalue())
- writer.remote_unpack()
-
- self.expectCommands(
- Expect('uploadDirectory', dict(
- slavesrc="srcdir", workdir='wkdir',
- blocksize=16384, compress=None, maxsize=None,
- writer=ExpectRemoteRef(transfer._DirectoryWriter)))
- + Expect.behavior(upload_behavior)
- + 0)
-
- self.expectOutcome(result=SUCCESS, status_text=["uploading", "srcdir"])
- d = self.runStep()
- return d
-
-class TestStringDownload(unittest.TestCase):
- def testBasic(self):
- s = transfer.StringDownload("Hello World", "hello.txt")
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = 1
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'downloadFile':
- self.assertEquals(kwargs['slavedest'], 'hello.txt')
- reader = kwargs['reader']
- data = reader.remote_read(100)
- self.assertEquals(data, "Hello World")
- break
- else:
- self.assert_(False, "No downloadFile command found")
-
-class TestJSONStringDownload(unittest.TestCase):
- def testBasic(self):
- msg = dict(message="Hello World")
- s = transfer.JSONStringDownload(msg, "hello.json")
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = 1
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'downloadFile':
- self.assertEquals(kwargs['slavedest'], 'hello.json')
- reader = kwargs['reader']
- data = reader.remote_read(100)
- self.assertEquals(data, json.dumps(msg))
- break
- else:
- self.assert_(False, "No downloadFile command found")
-
-class TestJSONPropertiesDownload(unittest.TestCase):
- def testBasic(self):
- s = transfer.JSONPropertiesDownload("props.json")
- s.build = Mock()
- props = Properties()
- props.setProperty('key1', 'value1', 'test')
- s.build.getProperties.return_value = props
- s.build.getSlaveCommandVersion.return_value = 1
- ss = Mock()
- ss.asDict.return_value = dict(revision="12345")
- s.build.getSourceStamp.return_value = ss
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'downloadFile':
- self.assertEquals(kwargs['slavedest'], 'props.json')
- reader = kwargs['reader']
- data = reader.remote_read(100)
- self.assertEquals(data, json.dumps(dict(sourcestamp=ss.asDict(), properties={'key1': 'value1'})))
- break
- else:
- self.assert_(False, "No downloadFile command found")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py
deleted file mode 100644
index 245985a5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py
+++ /dev/null
@@ -1,502 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-
-from twisted.trial import unittest
-from twisted.python import failure
-from twisted.internet import defer, reactor
-from buildbot import config, interfaces
-from buildbot.process import properties
-from buildbot.status import master
-from buildbot.status.results import SUCCESS, FAILURE, EXCEPTION
-from buildbot.steps import trigger
-from buildbot.test.util import steps, compat
-from buildbot.test.fake import fakemaster, fakedb
-
-class FakeTriggerable(object):
- implements(interfaces.ITriggerableScheduler)
-
- triggered_with = None
- result = SUCCESS
- brids = {}
- exception = False
-
- def __init__(self, name):
- self.name = name
-
- def trigger(self, sourcestamps = None, set_props=None):
- self.triggered_with = (sourcestamps, set_props.properties)
- d = defer.Deferred()
- if self.exception:
- reactor.callLater(0, d.errback, RuntimeError('oh noes'))
- else:
- reactor.callLater(0, d.callback, (self.result, self.brids))
- return d
-
-
-class FakeSourceStamp(object):
-
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
-
- def asDict(self, includePatch = True):
- return self.__dict__.copy()
-
-# Magic numbers that relate brid to other build settings
-BRID_TO_BSID = lambda brid: brid+2000
-BRID_TO_BID = lambda brid: brid+3000
-BRID_TO_BUILD_NUMBER = lambda brid: brid+4000
-
-class TestTrigger(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def setupStep(self, step, sourcestampsInBuild=None, gotRevisionsInBuild=None, *args, **kwargs):
- sourcestamps = sourcestampsInBuild or []
- got_revisions = gotRevisionsInBuild or {}
-
- steps.BuildStepMixin.setupStep(self, step, *args, **kwargs)
-
- # This step reaches deeply into a number of parts of Buildbot. That
- # should be fixed!
-
- # set up a buildmaster that knows about two fake schedulers, a and b
- m = fakemaster.make_master()
- self.build.builder.botmaster = m.botmaster
- m.db = fakedb.FakeDBConnector(self)
- m.status = master.Status(m)
- m.config.buildbotURL = "baseurl/"
-
- self.scheduler_a = a = FakeTriggerable(name='a')
- self.scheduler_b = b = FakeTriggerable(name='b')
- def allSchedulers():
- return [ a, b ]
- m.allSchedulers = allSchedulers
-
- a.brids = {'A': 11}
- b.brids = {'B': 22}
-
- make_fake_br = lambda brid, name: fakedb.BuildRequest(id=brid,
- buildsetid=BRID_TO_BSID(brid),
- buildername=name)
- make_fake_build = lambda brid: fakedb.Build(brid=brid,
- id=BRID_TO_BID(brid),
- number=BRID_TO_BUILD_NUMBER(brid))
-
- m.db.insertTestData([
- make_fake_br(11, "A"),
- make_fake_br(22, "B"),
- make_fake_build(11),
- make_fake_build(22),
- ])
-
- def getAllSourceStamps():
- return sourcestamps
- self.build.getAllSourceStamps = getAllSourceStamps
- def getAllGotRevisions():
- return got_revisions
- self.build.build_status.getAllGotRevisions = getAllGotRevisions
-
- self.exp_add_sourcestamp = None
- self.exp_a_trigger = None
- self.exp_b_trigger = None
- self.exp_added_urls = []
-
- def runStep(self, expect_waitForFinish=False):
- d = steps.BuildStepMixin.runStep(self)
-
- if expect_waitForFinish:
- # the build doesn't finish until after a callLater, so this has the
- # effect of checking whether the deferred has been fired already;
- # it should not have been!
- early = []
- d.addCallback(early.append)
- self.assertEqual(early, [])
-
- def check(_):
- self.assertEqual(self.scheduler_a.triggered_with,
- self.exp_a_trigger)
- self.assertEqual(self.scheduler_b.triggered_with,
- self.exp_b_trigger)
- self.assertEqual(self.step_status.addURL.call_args_list,
- self.exp_added_urls)
-
- if self.exp_add_sourcestamp:
- self.assertEqual(self.addSourceStamp_kwargs,
- self.exp_add_sourcestamp)
- d.addCallback(check)
-
- # pause runStep's completion until after any other callLater's are done
- def wait(_):
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
- return d
- d.addCallback(wait)
-
- return d
-
- def expectTriggeredWith(self, a=None, b=None):
- self.exp_a_trigger = a
- self.exp_b_trigger = b
-
- def expectAddedSourceStamp(self, **kwargs):
- self.exp_add_sourcestamp = kwargs
-
- def expectTriggeredLinks(self, *args):
- def get_args(sch, name):
- label = lambda name, num: "%s #%d" % (name, num)
- url = lambda name, num: "baseurl/builders/%s/builds/%d" % (name, num )
-
- num = BRID_TO_BUILD_NUMBER(sch.brids[name])
-
- #returns the *args and **kwargs that will be called on addURL...
- # which is just addURL('label', 'url')
- return ( (label(name,num), url(name,num)) , {} )
-
- if 'a' in args:
- self.exp_added_urls.append(get_args(self.scheduler_a, 'A'))
- if 'b' in args:
- self.exp_added_urls.append(get_args(self.scheduler_b, 'B'))
-
-
- # tests
-
- def test_no_schedulerNames(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger())
-
- def test_sourceStamp_and_updateSourceStamp(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamp=dict(x=1), updateSourceStamp=True))
-
- def test_sourceStamps_and_updateSourceStamp(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamps=[dict(x=1), dict(x=2)],
- updateSourceStamp=True))
-
- def test_updateSourceStamp_and_alwaysUseLatest(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- updateSourceStamp=True, alwaysUseLatest=True))
-
- def test_sourceStamp_and_alwaysUseLatest(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamp=dict(x=1), alwaysUseLatest=True))
-
- def test_sourceStamps_and_alwaysUseLatest(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamps=[dict(x=1), dict(x=2)],
- alwaysUseLatest=True))
-
- def test_simple(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'], sourceStamps = {}))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({}, {}))
- return self.runStep()
-
- def test_simple_failure(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a']))
- self.scheduler_a.result = FAILURE
- # not waitForFinish, so trigger step succeeds even though the build
- # didn't fail
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({}, {}))
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_simple_exception(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a']))
- self.scheduler_a.exception = True
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=( {}, {}))
- d = self.runStep()
- def flush(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(flush)
- return d
-
- def test_bogus_scheduler(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a', 'x']))
- self.expectOutcome(result=FAILURE, status_text=['not valid scheduler:', 'x'])
- self.expectTriggeredWith(a=None) # a is not triggered!
- return self.runStep()
-
- def test_updateSourceStamp(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=True),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'':{'codebase':'',
- 'repository': 'x',
- 'revision': 23456}
- }, {}))
- return self.runStep()
-
- def test_updateSourceStamp_no_got_revision(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=True),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'':{'codebase':'',
- 'repository': 'x',
- 'revision': 11111} # uses old revision
- }, {}))
- return self.runStep()
-
- def test_not_updateSourceStamp(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=False),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'':{'codebase':'',
- 'repository': 'x',
- 'revision': 11111}
- }, {}))
- return self.runStep()
-
- def test_updateSourceStamp_multiple_repositories(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=True),
- sourcestampsInBuild = [
- FakeSourceStamp(codebase='cb1',
- revision='12345'),
- FakeSourceStamp(codebase='cb2',
- revision='12345')
- ],
- gotRevisionsInBuild = {'cb1': 23456, 'cb2': 34567},
- )
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'cb1': {'codebase':'cb1',
- 'revision':23456},
- 'cb2': {'codebase':'cb2',
- 'revision':34567}
- }, {}))
- return self.runStep()
-
- def test_updateSourceStamp_prop_false(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=properties.Property('usess')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.properties.setProperty('usess', False, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- # didn't use got_revision
- self.expectTriggeredWith(a=({'': { 'codebase':'',
- 'repository': 'x',
- 'revision': 11111
- }}, {}))
- return self.runStep()
-
- def test_updateSourceStamp_prop_true(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=properties.Property('usess')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.properties.setProperty('usess', True, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- # didn't use got_revision
- self.expectTriggeredWith(a=({'': { 'codebase':'',
- 'repository': 'x',
- 'revision': 23456
- }}, {}))
- return self.runStep()
-
- def test_alwaysUseLatest(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- alwaysUseLatest=True),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- # Do not pass setid
- self.expectTriggeredWith(b=({}, {}))
- return self.runStep()
-
- def test_alwaysUseLatest_prop_false(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- alwaysUseLatest=properties.Property('aul')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.properties.setProperty('aul', False, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- # didn't use latest
- self.expectTriggeredWith(b=({'': { 'codebase':'',
- 'repository': 'x',
- 'revision': 11111}
- }, {}))
- return self.runStep()
-
- def test_alwaysUseLatest_prop_true(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- alwaysUseLatest=properties.Property('aul')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.properties.setProperty('aul', True, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- # didn't use latest
- self.expectTriggeredWith(b=({}, {}))
- return self.runStep()
-
- def test_sourceStamp(self):
- ss = dict(revision=9876, branch='dev')
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamp=ss))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'': ss}, {}))
- return self.runStep()
-
- def test_set_of_sourceStamps(self):
- ss1 = dict(codebase='cb1', repository='r1', revision=9876, branch='dev')
- ss2 = dict(codebase='cb2',repository='r2', revision=5432, branch='dev')
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamps=[ss1,ss2]))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'cb1':ss1, 'cb2':ss2}, {}))
- return self.runStep()
-
- def test_set_of_sourceStamps_override_build(self):
- ss1 = dict(codebase='cb1', repository='r1', revision=9876, branch='dev')
- ss2 = dict(codebase='cb2',repository='r2', revision=5432, branch='dev')
- ss3 = FakeSourceStamp(codebase='cb3', repository='r3', revision=1234, branch='dev')
- ss4 = FakeSourceStamp(codebase='cb4',repository='r4', revision=2345, branch='dev')
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamps=[ss1,ss2]), sourcestampsInBuild=[ss3, ss4])
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'cb1':ss1, 'cb2':ss2}, {}))
- return self.runStep()
-
-
- def test_sourceStamp_prop(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamp=dict(revision=properties.Property('rev'),
- branch='dev')))
- self.properties.setProperty('rev', 602, 'me')
- expected_ss = dict(revision=602, branch='dev')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'': expected_ss}, {}))
- return self.runStep()
-
- def test_waitForFinish(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a', 'b'],
- waitForFinish=True))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a', 'b'])
- self.expectTriggeredWith(
- a=({}, {}),
- b=({}, {}))
- self.expectTriggeredLinks('a','b')
- return self.runStep(expect_waitForFinish=True)
-
- def test_waitForFinish_failure(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- waitForFinish=True))
- self.scheduler_a.result = FAILURE
- self.expectOutcome(result=FAILURE, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({}, {}))
- self.expectTriggeredLinks('a')
- return self.runStep(expect_waitForFinish=True)
-
- @compat.usesFlushLoggedErrors
- def test_waitForFinish_exception(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a', 'b'],
- waitForFinish=True))
- self.scheduler_b.exception = True
- self.expectOutcome(result=EXCEPTION,
- status_text=['triggered', 'a', 'b'])
- self.expectTriggeredWith(
- a=({}, {}),
- b=({}, {}))
- self.expectTriggeredLinks('a') # b doesn't return a brid
- d = self.runStep(expect_waitForFinish=True)
- def flush(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(flush)
- return d
-
- def test_set_properties(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- set_properties=dict(x=1, y=2)))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({},
- dict(x=(1, 'Trigger'), y=(2, 'Trigger'))))
- return self.runStep()
-
- def test_set_properties_prop(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- set_properties=dict(x=properties.Property('X'), y=2)))
- self.properties.setProperty('X', 'xxx', 'here')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({},
- dict(x=('xxx', 'Trigger'), y=(2, 'Trigger'))))
- return self.runStep()
-
- def test_copy_properties(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- copy_properties=['a', 'b']))
- self.properties.setProperty('a', 'A', 'AA')
- self.properties.setProperty('b', 'B', 'BB')
- self.properties.setProperty('c', 'C', 'CC')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({},
- dict(a=('A', 'Trigger'),
- b=('B', 'Trigger'))))
- return self.runStep()
-
- def test_interrupt(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- waitForFinish=True))
- self.expectOutcome(result=EXCEPTION, status_text=['interrupted'])
- self.expectTriggeredWith(a=({}, {}))
- d = self.runStep(expect_waitForFinish=True)
-
- # interrupt before the callLater representing the Triggerable
- # schedulers completes
- self.step.interrupt(failure.Failure(RuntimeError('oh noes')))
-
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py
deleted file mode 100644
index d2cfcb63..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py
+++ /dev/null
@@ -1,824 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.steps import vstudio
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot.process.properties import Property
-
-from mock import Mock
-
-real_log = r"""
-1>------ Build started: Project: lib1, Configuration: debug Win32 ------
-1>Compiling...
-1>SystemLog.cpp
-1>c:\absolute\path\to\systemlog.cpp(7) : warning C4100: 'op' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(12) : warning C4100: 'statusword' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(12) : warning C4100: 'op' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(17) : warning C4100: 'retryCounter' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(17) : warning C4100: 'op' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(22) : warning C4100: 'op' : unreferenced formal parameter
-1>Creating library...
-1>Build log was saved at "file://c:\another\absolute\path\to\debug\BuildLog.htm"
-1>lib1 - 0 error(s), 6 warning(s)
-2>------ Build started: Project: product, Configuration: debug Win32 ------
-2>Linking...
-2>LINK : fatal error LNK1168: cannot open ../../debug/directory/dllname.dll for writing
-2>Build log was saved at "file://c:\another\similar\path\to\debug\BuildLog.htm"
-2>product - 1 error(s), 0 warning(s)
-========== Build: 1 succeeded, 1 failed, 6 up-to-date, 0 skipped ==========
-"""
-
-class TestAddEnvPath(unittest.TestCase):
-
- def do_test(self, initial_env, name, value, expected_env):
- vstudio.addEnvPath(initial_env, name, value)
- self.assertEqual(initial_env, expected_env)
-
- def test_new(self):
- self.do_test({}, 'PATH', r'C:\NOTHING',
- { 'PATH' : r'C:\NOTHING;' })
-
- def test_new_semi(self):
- self.do_test({}, 'PATH', r'C:\NOTHING;',
- { 'PATH' : r'C:\NOTHING;' })
-
- def test_existing(self):
- self.do_test({'PATH' : '/bin' }, 'PATH', r'C:\NOTHING',
- { 'PATH' : r'/bin;C:\NOTHING;' })
-
- def test_existing_semi(self):
- self.do_test({'PATH' : '/bin;' }, 'PATH', r'C:\NOTHING',
- { 'PATH' : r'/bin;C:\NOTHING;' })
-
- def test_existing_both_semi(self):
- self.do_test({'PATH' : '/bin;' }, 'PATH', r'C:\NOTHING;',
- { 'PATH' : r'/bin;C:\NOTHING;' })
-
-
-class MSLogLineObserver(unittest.TestCase):
-
- def setUp(self):
- self.warnings = []
- lw = Mock()
- lw.addStdout = lambda l : self.warnings.append(l.rstrip())
-
- self.errors = []
- self.errors_stderr = []
- le = Mock()
- le.addStdout = lambda l : self.errors.append(('o', l.rstrip()))
- le.addStderr = lambda l : self.errors.append(('e', l.rstrip()))
-
- self.llo = vstudio.MSLogLineObserver(lw, le)
-
- self.progress = {}
- self.llo.step = Mock()
- self.llo.step.setProgress = \
- lambda n,prog : self.progress.__setitem__(n, prog)
-
- def receiveLines(self, *lines):
- for line in lines:
- self.llo.outLineReceived(line)
-
- def assertResult(self, nbFiles=0, nbProjects=0, nbWarnings=0, nbErrors=0,
- errors=[], warnings=[], progress={}):
- self.assertEqual(
- dict(nbFiles=self.llo.nbFiles, nbProjects=self.llo.nbProjects,
- nbWarnings=self.llo.nbWarnings,
- nbErrors=self.llo.nbErrors, errors=self.errors,
- warnings=self.warnings, progress=self.progress),
- dict(nbFiles=nbFiles, nbProjects=nbProjects, nbWarnings=nbWarnings,
- nbErrors=nbErrors, errors=errors,
- warnings=warnings, progress=progress))
-
- def test_outLineReceived_empty(self):
- self.llo.outLineReceived('abcd\r\n')
- self.assertResult()
-
- def test_outLineReceived_projects(self):
- lines = [
- "123>----- some project 1 -----",
- "123>----- some project 2 -----",
- ]
- self.receiveLines(*lines)
- self.assertResult(nbProjects=2, progress=dict(projects=2),
- errors=[ ('o', l) for l in lines ],
- warnings=lines)
-
- def test_outLineReceived_files(self):
- lines = [
- "123>SomeClass.cpp",
- "123>SomeStuff.c",
- "123>SomeStuff.h", # .h files not recognized
- ]
- self.receiveLines(*lines)
- self.assertResult(nbFiles=2, progress=dict(files=2))
-
- def test_outLineReceived_warnings(self):
- lines = [
- "abc: warning ABC123: xyz!",
- "def : warning DEF456: wxy!",
- ]
- self.receiveLines(*lines)
- self.assertResult(nbWarnings=2, progress=dict(warnings=2),
- warnings=lines)
-
- def test_outLineReceived_errors(self):
- lines = [
- "error ABC123: foo",
- " error DEF456 : bar",
- " error : bar",
- " error: bar", # NOTE: not matched
- ]
- self.receiveLines(*lines)
- self.assertResult(nbErrors=3, # note: no progress
- errors=[
- ('e', "error ABC123: foo"),
- ('e', " error DEF456 : bar"),
- ('e', " error : bar"),
- ])
-
- def test_outLineReceived_real(self):
- # based on a real logfile donated by Ben Allard
- lines = real_log.split("\n")
- self.receiveLines(*lines)
- errors = [
- ('o', '1>------ Build started: Project: lib1, Configuration: debug Win32 ------'),
- ('o', '2>------ Build started: Project: product, Configuration: debug Win32 ------'),
- ('e', '2>LINK : fatal error LNK1168: cannot open ../../debug/directory/dllname.dll for writing')
- ]
- warnings = [
- '1>------ Build started: Project: lib1, Configuration: debug Win32 ------',
- "1>c:\\absolute\\path\\to\\systemlog.cpp(7) : warning C4100: 'op' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(12) : warning C4100: 'statusword' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(12) : warning C4100: 'op' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(17) : warning C4100: 'retryCounter' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(17) : warning C4100: 'op' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(22) : warning C4100: 'op' : unreferenced formal parameter",
- '2>------ Build started: Project: product, Configuration: debug Win32 ------',
- ]
- self.assertResult(nbFiles=1, nbErrors=1, nbProjects=2, nbWarnings=6,
- progress={'files': 1, 'projects': 2, 'warnings': 6},
- errors=errors, warnings=warnings)
-
-class VCx(vstudio.VisualStudio):
-
- def start(self):
- command = ["command", "here"]
- self.setCommand(command)
- return vstudio.VisualStudio.start(self)
-
-class VisualStudio(steps.BuildStepMixin, unittest.TestCase):
- """
- Test L{VisualStudio} with a simple subclass, L{VCx}.
- """
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_default_config(self):
- vs = vstudio.VisualStudio()
- self.assertEqual(vs.config, 'release')
-
- def test_simple(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_installdir(self):
- self.setupStep(VCx(installdir=r'C:\I'))
- self.step.exp_installdir = r'C:\I'
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- d = self.runStep()
- def check_installdir(_):
- self.assertEqual(self.step.installdir, r'C:\I')
- d.addCallback(check_installdir)
- return d
-
- def test_evaluateCommand_failure(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["compile", "0 projects", "0 files", "failed"])
- return self.runStep()
-
- def test_evaluateCommand_errors(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + ExpectShell.log('stdio',
- stdout='error ABC123: foo\r\n')
- + 0
- )
- self.expectOutcome(result=FAILURE,
- status_text=["compile", "0 projects", "0 files",
- "1 errors", "failed"])
- return self.runStep()
-
- def test_evaluateCommand_warnings(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + ExpectShell.log('stdio',
- stdout='foo: warning ABC123: foo\r\n')
- + 0
- )
- self.expectOutcome(result=WARNINGS,
- status_text=["compile", "0 projects", "0 files",
- "1 warnings", "warnings"])
- return self.runStep()
-
- def test_env_setup(self):
- self.setupStep(VCx(
- INCLUDE=[ r'c:\INC1', r'c:\INC2' ],
- LIB=[ r'c:\LIB1', r'C:\LIB2' ],
- PATH=[ r'c:\P1', r'C:\P2' ]))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'],
- env=dict(
- INCLUDE=r'c:\INC1;c:\INC2;',
- LIB=r'c:\LIB1;C:\LIB2;',
- PATH=r'c:\P1;C:\P2;'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_env_setup_existing(self):
- self.setupStep(VCx(
- INCLUDE=[ r'c:\INC1', r'c:\INC2' ],
- LIB=[ r'c:\LIB1', r'C:\LIB2' ],
- PATH=[ r'c:\P1', r'C:\P2' ]))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'],
- env=dict(
- INCLUDE=r'c:\INC1;c:\INC2;',
- LIB=r'c:\LIB1;C:\LIB2;',
- PATH=r'c:\P1;C:\P2;'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_rendering(self):
- self.setupStep(VCx(
- projectfile=Property('a'),
- config=Property('b'),
- project=Property('c')))
- self.properties.setProperty('a', 'aa', 'Test')
- self.properties.setProperty('b', 'bb', 'Test')
- self.properties.setProperty('c', 'cc', 'Test')
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- d = self.runStep()
- def check_props(_):
- self.assertEqual(
- [ self.step.projectfile, self.step.config, self.step.project ],
- [ 'aa', 'bb', 'cc' ])
- d.addCallback(check_props)
- return d
-
-
-class TestVC6(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def getExpectedEnv(self, installdir, l=None, p=None, i=None):
- include = [
- installdir + r'\VC98\INCLUDE;',
- installdir + r'\VC98\ATL\INCLUDE;',
- installdir + r'\VC98\MFC\INCLUDE;',
- ]
- lib = [
- installdir + r'\VC98\LIB;',
- installdir + r'\VC98\MFC\LIB;',
- ]
- path = [
- installdir + r'\Common\msdev98\BIN;',
- installdir + r'\VC98\BIN;',
- installdir + r'\Common\TOOLS\WINNT;',
- installdir + r'\Common\TOOLS;',
- ]
- if p:
- path.insert(0, '%s;' % p)
- if i:
- include.insert(0, '%s;' % i)
- if l:
- lib.insert(0, '%s;' % l)
- return dict(
- INCLUDE = ''.join(include),
- LIB = ''.join(lib),
- PATH = ''.join(path),
- )
-
- def test_args(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'pj - cfg', '/REBUILD'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'pj - cfg', '/CLEAN'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_noproj_build(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- mode='build'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'ALL - cfg', '/BUILD'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_env_prepend(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- project='pj', PATH=['p'], INCLUDE=['i'],
- LIB=['l']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'pj - cfg', '/REBUILD',
- '/USEENV'], # note extra param
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio',
- l='l', p='p', i='i'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC7(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def getExpectedEnv(self, installdir, l=None, p=None, i=None):
- include = [
- installdir + r'\VC7\INCLUDE;',
- installdir + r'\VC7\ATLMFC\INCLUDE;',
- installdir + r'\VC7\PlatformSDK\include;',
- installdir + r'\SDK\v1.1\include;',
- ]
- lib = [
- installdir + r'\VC7\LIB;',
- installdir + r'\VC7\ATLMFC\LIB;',
- installdir + r'\VC7\PlatformSDK\lib;',
- installdir + r'\SDK\v1.1\lib;',
- ]
- path = [
- installdir + r'\Common7\IDE;',
- installdir + r'\VC7\BIN;',
- installdir + r'\Common7\Tools;',
- installdir + r'\Common7\Tools\bin;',
- ]
- if p:
- path.insert(0, '%s;' % p)
- if i:
- include.insert(0, '%s;' % i)
- if l:
- lib.insert(0, '%s;' % l)
- return dict(
- INCLUDE = ''.join(include),
- LIB = ''.join(lib),
- PATH = ''.join(path),
- )
-
- def test_args(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild', 'cfg',
- '/Project', 'pj'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Clean', 'cfg',
- '/Project', 'pj'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_noproj_build(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- mode='build'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Build', 'cfg'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_env_prepend(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- project='pj', PATH=['p'], INCLUDE=['i'],
- LIB=['l']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild', 'cfg',
- '/UseEnv', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003',
- l='l', p='p', i='i'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class VC8ExpectedEnvMixin(object):
- # used for VC8 and VC9Express
- def getExpectedEnv(self, installdir, x64=False, l=None, i=None, p=None):
- include = [
- installdir + r'\VC\INCLUDE;',
- installdir + r'\VC\ATLMFC\include;',
- installdir + r'\VC\PlatformSDK\include;',
- ]
- lib = [
- installdir + r'\VC\LIB;',
- installdir + r'\VC\ATLMFC\LIB;',
- installdir + r'\VC\PlatformSDK\lib;',
- installdir + r'\SDK\v2.0\lib;',
- ]
- path = [
- installdir + r'\Common7\IDE;',
- installdir + r'\VC\BIN;',
- installdir + r'\Common7\Tools;',
- installdir + r'\Common7\Tools\bin;',
- installdir + r'\VC\PlatformSDK\bin;',
- installdir + r'\SDK\v2.0\bin;',
- installdir + r'\VC\VCPackages;',
- r'${PATH};',
- ]
- if x64:
- path.insert(1, installdir + r'\VC\BIN\x86_amd64;')
- lib = [ lb[:-1] + r'\amd64;' for lb in lib ]
- if l:
- lib.insert(0, '%s;' % l)
- if p:
- path.insert(0, '%s;' % p)
- if i:
- include.insert(0, '%s;' % i)
- return dict(
- INCLUDE = ''.join(include),
- LIB = ''.join(lib),
- PATH = ''.join(path),
- )
-
-class TestVC8(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_args(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- project='pj', arch='arch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_args_x64(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- project='pj', arch='x64'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8',
- x64=True))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Clean',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_rendering(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- arch=Property('a')))
- self.properties.setProperty('a', 'x64', 'Test')
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild', 'cfg'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8',
- x64=True)) # property has expected effect
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- d = self.runStep()
- def check_props(_):
- self.assertEqual(self.step.arch, 'x64')
- d.addCallback(check_props)
- return d
-
-
-class TestVCExpress9(VC8ExpectedEnvMixin, steps.BuildStepMixin,
- unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_args(self):
- self.setupStep(vstudio.VCExpress9(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['vcexpress', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- # note: still uses version 8 (?!)
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VCExpress9(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['vcexpress', 'pf', '/Clean',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- # note: still uses version 8 (?!)
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_mode_build_env(self):
- self.setupStep(vstudio.VCExpress9(projectfile='pf', config='cfg',
- project='pj', mode='build', INCLUDE=['i']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['vcexpress', 'pf', '/Build',
- 'cfg', '/UseEnv', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8',
- i='i'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC9(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_installdir(self):
- self.setupStep(vstudio.VC9(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 9.0'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC10(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_installdir(self):
- self.setupStep(vstudio.VC10(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 10.0'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC11(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_installdir(self):
- self.setupStep(vstudio.VC11(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 11.0'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestMsBuild(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_build_project(self):
- self.setupStep(vstudio.MsBuild(projectfile='pf', config='cfg', platform='Win32', project='pj'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['%VCENV_BAT%', 'x86', '&&',
- 'msbuild', 'pf', '/p:Configuration=cfg', '/p:Platform=Win32',
- '/t:pj'],
- env={'VCENV_BAT': '"${VS110COMNTOOLS}..\\..\\VC\\vcvarsall.bat"'})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["built", "pj for", 'cfg|Win32'])
- return self.runStep()
-
- def test_build_solution(self):
- self.setupStep(vstudio.MsBuild(projectfile='pf', config='cfg', platform='x64'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['%VCENV_BAT%', 'x86', '&&',
- 'msbuild', 'pf', '/p:Configuration=cfg', '/p:Platform=x64'],
- env={'VCENV_BAT': '"${VS110COMNTOOLS}..\\..\\VC\\vcvarsall.bat"'})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["built", "solution for", 'cfg|x64'])
- return self.runStep()
-
-
-class Aliases(unittest.TestCase):
-
- def test_vs2003(self):
- self.assertIdentical(vstudio.VS2003, vstudio.VC7)
-
- def test_vs2005(self):
- self.assertIdentical(vstudio.VS2005, vstudio.VC8)
-
- def test_vs2008(self):
- self.assertIdentical(vstudio.VS2008, vstudio.VC9)
-
- def test_vs2010(self):
- self.assertIdentical(vstudio.VS2010, vstudio.VC10)
-
- def test_vs2012(self):
- self.assertIdentical(vstudio.VS2012, vstudio.VC11)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py
deleted file mode 100644
index 3b6a90f9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import twisted
-from twisted.trial import reporter, unittest
-from twisted.internet import utils
-from buildbot.test.util.gpo import GetProcessOutputMixin, Expect
-
-class TestGPOMixin(unittest.TestCase):
-
- # these tests use self.patch, but the SkipTest exception gets eaten, so
- # explicitly skip things here.
- if twisted.version.major <= 9 and sys.version_info[:2] == (2,7):
- skip = "unittest.TestCase.patch is not available"
-
- def runTestMethod(self, method):
- class TestCase(GetProcessOutputMixin, unittest.TestCase):
- def setUp(self):
- self.setUpGetProcessOutput()
- def runTest(self):
- return method(self)
- self.testcase = TestCase()
- result = reporter.TestResult()
- self.testcase.run(result) # This blocks
- return result
-
- def assertTestFailure(self, result, expectedFailure):
- self.assertEqual(result.errors, [])
- self.assertEqual(len(result.failures), 1)
- self.failUnless(result.failures[0][1].check(unittest.FailTest))
- if expectedFailure:
- self.assertSubstring(expectedFailure, result.failures[0][1].getErrorMessage())
-
- def assertSuccessful(self, result):
- if not result.wasSuccessful():
- output = 'expected success'
- if result.failures:
- output += ('\ntest failed: %s' %
- result.failures[0][1].getErrorMessage())
- if result.errors:
- output += ('\nerrors: %s' %
- map(lambda x: x[1].value, result.errors))
- raise self.failureException(output)
-
- self.failUnless(result.wasSuccessful())
-
- def test_patch(self):
- original_getProcessOutput = utils.getProcessOutput
- original_getProcessOutputAndValue = utils.getProcessOutputAndValue
- def method(testcase):
- testcase.expectCommands()
- self.assertEqual(utils.getProcessOutput,
- testcase.patched_getProcessOutput)
- self.assertEqual(utils.getProcessOutputAndValue,
- testcase.patched_getProcessOutputAndValue)
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
- self.assertEqual(utils.getProcessOutput,
- original_getProcessOutput)
- self.assertEqual(utils.getProcessOutputAndValue,
- original_getProcessOutputAndValue)
-
- def test_methodChaining(self):
- expect = Expect('command')
- self.assertEqual(expect, expect.exit(0))
- self.assertEqual(expect, expect.stdout("output"))
- self.assertEqual(expect, expect.stderr("error"))
-
- def test_gpo_oneCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- d = utils.getProcessOutput("command", ())
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_expectTwo_runOne(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutput("command", ())
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "assert all expected commands were run")
-
- def test_gpo_wrongCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutput("command", ())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_wrongArgs(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutput("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_missingPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutput("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_wrongPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutput("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_notCurrentPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutput("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_errorOutput(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stderr("some test"))
- d = testcase.assertFailure(utils.getProcessOutput("command", ()), [IOError])
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "got stderr: 'some test'")
-
- def test_gpo_errorOutput_errtoo(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stderr("some test"))
- d = utils.getProcessOutput("command", (), errortoo=True)
- d.addCallback(testcase.assertEqual, "some test")
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_exitIgnored(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").exit(1))
- d = utils.getProcessOutput("command", ())
- d.addCallback(self.assertEqual, '')
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_output(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout"))
- d = utils.getProcessOutput("command", ())
- d.addCallback(testcase.assertEqual, "stdout")
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_outputAndError(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout").stderr("stderr"))
- d = utils.getProcessOutput("command", (), errortoo=True)
- @d.addCallback
- def cb(res):
- testcase.assertSubstring("stdout", res)
- testcase.assertSubstring("stderr", res)
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_environ_success(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.addGetProcessOutputExpectEnv({'key': 'value'})
- d = utils.getProcessOutput("command", (), env={'key': 'value'})
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_environ_wrongValue(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.addGetProcessOutputExpectEnv({'key': 'value'})
- d = utils.getProcessOutput("command", (), env={'key': 'wrongvalue'})
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "Expected environment to have key = 'value'")
-
- def test_gpo_environ_missing(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.addGetProcessOutputExpectEnv({'key': 'value'})
- d = utils.getProcessOutput("command", ())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "Expected environment to have key = 'value'")
-
- def test_gpoav_oneCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','',0))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_expectTwo_runOne(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','',0))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "assert all expected commands were run")
-
- def test_gpoav_wrongCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_wrongArgs(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_missingPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_wrongPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_notCurrentPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_errorOutput(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stderr("some test"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','some test',0))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_exit(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").exit(1))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','',1))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_output(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(testcase.assertEqual, ("stdout",'',0))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_outputAndError(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout").stderr("stderr"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(testcase.assertEqual, ("stdout",'stderr',0))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py
deleted file mode 100644
index 8411e92c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import datetime
-
-from twisted.trial import unittest
-
-from buildbot import util
-
-class formatInterval(unittest.TestCase):
-
- def test_zero(self):
- self.assertEqual(util.formatInterval(0), "0 secs")
-
- def test_seconds_singular(self):
- self.assertEqual(util.formatInterval(1), "1 secs")
-
- def test_seconds(self):
- self.assertEqual(util.formatInterval(7), "7 secs")
-
- def test_minutes_one(self):
- self.assertEqual(util.formatInterval(60), "60 secs")
-
- def test_minutes_over_one(self):
- self.assertEqual(util.formatInterval(61), "1 mins, 1 secs")
-
- def test_minutes(self):
- self.assertEqual(util.formatInterval(300), "5 mins, 0 secs")
-
- def test_hours_one(self):
- self.assertEqual(util.formatInterval(3600), "60 mins, 0 secs")
-
- def test_hours_over_one_sec(self):
- self.assertEqual(util.formatInterval(3601), "1 hrs, 1 secs")
-
- def test_hours_over_one_min(self):
- self.assertEqual(util.formatInterval(3660), "1 hrs, 60 secs")
-
- def test_hours(self):
- self.assertEqual(util.formatInterval(7200), "2 hrs, 0 secs")
-
- def test_mixed(self):
- self.assertEqual(util.formatInterval(7392), "2 hrs, 3 mins, 12 secs")
-
-class safeTranslate(unittest.TestCase):
-
- def test_str_good(self):
- self.assertEqual(util.safeTranslate(str("full")), str("full"))
-
- def test_str_bad(self):
- self.assertEqual(util.safeTranslate(str("speed=slow;quality=high")),
- str("speed_slow_quality_high"))
-
- def test_str_pathological(self):
- # if you needed proof this wasn't for use with sensitive data
- self.assertEqual(util.safeTranslate(str("p\ath\x01ogy")),
- str("p\ath\x01ogy")) # bad chars still here!
-
- def test_unicode_good(self):
- self.assertEqual(util.safeTranslate(u"full"), str("full"))
-
- def test_unicode_bad(self):
- self.assertEqual(util.safeTranslate(unicode("speed=slow;quality=high")),
- str("speed_slow_quality_high"))
-
- def test_unicode_pathological(self):
- self.assertEqual(util.safeTranslate(u"\u0109"),
- str("\xc4\x89")) # yuck!
-
-class naturalSort(unittest.TestCase):
-
- def test_alpha(self):
- self.assertEqual(
- util.naturalSort(['x', 'aa', 'ab']),
- ['aa', 'ab', 'x'])
-
- def test_numeric(self):
- self.assertEqual(
- util.naturalSort(['1', '10', '11', '2', '20']),
- ['1', '2', '10', '11', '20'])
-
- def test_alphanum(self):
- l1 = 'aa10ab aa1ab aa10aa f a aa3 aa30 aa3a aa30a'.split()
- l2 = 'a aa1ab aa3 aa3a aa10aa aa10ab aa30 aa30a f'.split()
- self.assertEqual(util.naturalSort(l1), l2)
-
-class none_or_str(unittest.TestCase):
-
- def test_none(self):
- self.assertEqual(util.none_or_str(None), None)
-
- def test_str(self):
- self.assertEqual(util.none_or_str("hi"), "hi")
-
- def test_int(self):
- self.assertEqual(util.none_or_str(199), "199")
-
-class TimeFunctions(unittest.TestCase):
-
- def test_UTC(self):
- self.assertEqual(util.UTC.utcoffset(datetime.datetime.now()),
- datetime.timedelta(0))
- self.assertEqual(util.UTC.dst(datetime.datetime.now()),
- datetime.timedelta(0))
- self.assertEqual(util.UTC.tzname(), "UTC")
-
- def test_epoch2datetime(self):
- self.assertEqual(util.epoch2datetime(0),
- datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=util.UTC))
- self.assertEqual(util.epoch2datetime(1300000000),
- datetime.datetime(2011, 3, 13, 7, 6, 40, tzinfo=util.UTC))
-
- def test_datetime2epoch(self):
- dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=util.UTC)
- self.assertEqual(util.datetime2epoch(dt), 0)
- dt = datetime.datetime(2011, 3, 13, 7, 6, 40, tzinfo=util.UTC)
- self.assertEqual(util.datetime2epoch(dt), 1300000000)
-
-class DiffSets(unittest.TestCase):
-
- def test_empty(self):
- removed, added = util.diffSets(set([]), set([]))
- self.assertEqual((removed, added), (set([]), set([])))
-
- def test_no_lists(self):
- removed, added = util.diffSets([1, 2], [2, 3])
- self.assertEqual((removed, added), (set([1]), set([3])))
-
- def test_no_overlap(self):
- removed, added = util.diffSets(set([1, 2]), set([3, 4]))
- self.assertEqual((removed, added), (set([1, 2]), set([3, 4])))
-
- def test_no_change(self):
- removed, added = util.diffSets(set([1, 2]), set([1, 2]))
- self.assertEqual((removed, added), (set([]), set([])))
-
- def test_added(self):
- removed, added = util.diffSets(set([1, 2]), set([1, 2, 3]))
- self.assertEqual((removed, added), (set([]), set([3])))
-
- def test_removed(self):
- removed, added = util.diffSets(set([1, 2]), set([1]))
- self.assertEqual((removed, added), (set([2]), set([])))
-
-class MakeList(unittest.TestCase):
-
- def test_empty_string(self):
- self.assertEqual(util.makeList(''), [ '' ])
-
- def test_None(self):
- self.assertEqual(util.makeList(None), [ ])
-
- def test_string(self):
- self.assertEqual(util.makeList('hello'), [ 'hello' ])
-
- def test_unicode(self):
- self.assertEqual(util.makeList(u'\N{SNOWMAN}'), [ u'\N{SNOWMAN}' ])
-
- def test_list(self):
- self.assertEqual(util.makeList(['a','b']), [ 'a', 'b' ])
-
- def test_tuple(self):
- self.assertEqual(util.makeList(('a','b')), [ 'a', 'b' ])
-
- def test_copy(self):
- input = ['a', 'b']
- output = util.makeList(input)
- input.append('c')
- self.assertEqual(output, [ 'a', 'b' ])
-
-class Flatten(unittest.TestCase):
-
- def test_simple(self):
- self.assertEqual(util.flatten([1, 2, 3]), [1, 2, 3])
-
- def test_deep(self):
- self.assertEqual(util.flatten([ [ 1, 2 ], 3, [ [ 4 ] ] ]),
- [1, 2, 3, 4])
-
- def test_tuples(self):
- self.assertEqual(util.flatten([ ( 1, 2 ), 3 ]), [ (1, 2), 3 ])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py
deleted file mode 100644
index a7c34de0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from twisted.trial import unittest
-
-from buildbot import util
-
-
-class ComparableMixin(unittest.TestCase):
- class Foo(util.ComparableMixin):
- compare_attrs = ["a", "b"]
- def __init__(self, a, b, c):
- self.a, self.b, self.c = a,b,c
-
- class Bar(Foo, util.ComparableMixin):
- compare_attrs = ["b", "c"]
-
- def setUp(self):
- self.f123 = self.Foo(1, 2, 3)
- self.f124 = self.Foo(1, 2, 4)
- self.f134 = self.Foo(1, 3, 4)
- self.b123 = self.Bar(1, 2, 3)
- self.b223 = self.Bar(2, 2, 3)
- self.b213 = self.Bar(2, 1, 3)
-
- def test_equality_identity(self):
- self.assertEqual(self.f123, self.f123)
-
- def test_equality_same(self):
- another_f123 = self.Foo(1, 2, 3)
- self.assertEqual(self.f123, another_f123)
-
- def test_equality_unimportantDifferences(self):
- self.assertEqual(self.f123, self.f124)
-
- def test_equality_unimportantDifferences_subclass(self):
- # verify that the parent class's compare_attrs doesn't
- # affect the subclass
- self.assertEqual(self.b123, self.b223)
-
- def test_inequality_importantDifferences(self):
- self.assertNotEqual(self.f123, self.f134)
-
- def test_inequality_importantDifferences_subclass(self):
- self.assertNotEqual(self.b123, self.b213)
-
- def test_inequality_differentClasses(self):
- self.assertNotEqual(self.f123, self.b123)
-
- def test_inequality_sameClass_differentCompareAttrs(self):
- another_f123 = self.Foo(1, 2, 3)
- another_f123.compare_attrs = ["b", "a"]
- self.assertNotEqual(self.f123, another_f123)
-
- def test_lt_importantDifferences(self):
- assert self.f123 < self.f134
-
- def test_lt_differentClasses(self):
- assert self.b123 < self.f123
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py
deleted file mode 100644
index de3ede52..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.util import bbcollections
-
-class KeyedSets(unittest.TestCase):
-
- def setUp(self):
- self.ks = bbcollections.KeyedSets()
-
- def test_getitem_default(self):
- self.assertEqual(self.ks['x'], set())
- # remaining tests effectively cover __getitem__
-
- def test_add(self):
- self.ks.add('y', 2)
- self.assertEqual(self.ks['y'], set([2]))
-
- def test_add_twice(self):
- self.ks.add('z', 2)
- self.ks.add('z', 4)
- self.assertEqual(self.ks['z'], set([2, 4]))
-
- def test_discard_noError(self):
- self.ks.add('full', 12)
- self.ks.discard('empty', 13) # should not fail
- self.ks.discard('full', 13) # nor this
- self.assertEqual(self.ks['full'], set([12]))
-
- def test_discard_existing(self):
- self.ks.add('yarn', 'red')
- self.ks.discard('yarn', 'red')
- self.assertEqual(self.ks['yarn'], set([]))
-
- def test_contains_true(self):
- self.ks.add('yarn', 'red')
- self.assertTrue('yarn' in self.ks)
-
- def test_contains_false(self):
- self.assertFalse('yarn' in self.ks)
-
- def test_contains_setNamesNotContents(self):
- self.ks.add('yarn', 'red')
- self.assertFalse('red' in self.ks)
-
- def test_pop_exists(self):
- self.ks.add('names', 'pop')
- self.ks.add('names', 'coke')
- self.ks.add('names', 'soda')
- popped = self.ks.pop('names')
- remaining = self.ks['names']
- self.assertEqual((popped, remaining),
- (set(['pop', 'coke', 'soda']), set()))
-
- def test_pop_missing(self):
- self.assertEqual(self.ks.pop('flavors'), set())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py
deleted file mode 100644
index fa37ec29..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.python import log
-
-from buildbot.util import eventual
-
-class Eventually(unittest.TestCase):
-
- def setUp(self):
- # reset the queue to its base state
- eventual._theSimpleQueue = eventual._SimpleCallQueue()
- self.old_log_err = log.err
- self.results = []
-
- def tearDown(self):
- log.err = self.old_log_err
- return eventual.flushEventualQueue()
-
- # utility callback
- def cb(self, *args, **kwargs):
- r = args
- if kwargs: r = r + (kwargs,)
- self.results.append(r)
-
- # flush the queue and assert results
- def assertResults(self, exp):
- d = eventual.flushEventualQueue()
- def cb(_):
- self.assertEqual(self.results, exp)
- d.addCallback(cb)
- return d
-
- ## tests
-
- def test_eventually_calls(self):
- eventual.eventually(self.cb)
- return self.assertResults([()])
-
- def test_eventually_args(self):
- eventual.eventually(self.cb, 1, 2, a='a')
- return self.assertResults([(1, 2, dict(a='a'))])
-
- def test_eventually_err(self):
- # monkey-patch log.err; this is restored by tearDown
- log.err = lambda : self.results.append("err")
- def cb_fails():
- raise RuntimeError("should not cause test failure")
- eventual.eventually(cb_fails)
- return self.assertResults(['err'])
-
- def test_eventually_butNotNow(self):
- eventual.eventually(self.cb, 1)
- self.failIf(self.results != [])
- return self.assertResults([(1,)])
-
- def test_eventually_order(self):
- eventual.eventually(self.cb, 1)
- eventual.eventually(self.cb, 2)
- eventual.eventually(self.cb, 3)
- return self.assertResults([(1,), (2,), (3,)])
-
- def test_flush_waitForChainedEventuallies(self):
- def chain(n):
- self.results.append(n)
- if n <= 0: return
- eventual.eventually(chain, n-1)
- chain(3)
- # (the flush this tests is implicit in assertResults)
- return self.assertResults([3, 2, 1, 0])
-
- def test_flush_waitForTreeEventuallies(self):
- # a more complex set of eventualities
- def tree(n):
- self.results.append(n)
- if n <= 0: return
- eventual.eventually(tree, n-1)
- eventual.eventually(tree, n-1)
- tree(2)
- # (the flush this tests is implicit in assertResults)
- return self.assertResults([2, 1, 1, 0, 0, 0, 0])
-
- def test_flush_duringTurn(self):
- testd = defer.Deferred()
- def cb():
- d = eventual.flushEventualQueue()
- d.addCallback(testd.callback)
- eventual.eventually(cb)
- return testd
-
- def test_fireEventually_call(self):
- d = eventual.fireEventually(13)
- d.addCallback(self.cb)
- return self.assertResults([(13,)])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py
deleted file mode 100644
index d67e90d8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py
+++ /dev/null
@@ -1,576 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import string
-import random
-import gc
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from twisted.python import failure
-from buildbot.util import lru
-
-# construct weakref-able objects for particular keys
-def short(k):
- return set([k.upper() * 3])
-def long(k):
- return set([k.upper() * 6])
-
-class LRUCacheTest(unittest.TestCase):
-
- def setUp(self):
- lru.inv_failed = False
- self.lru = lru.LRUCache(short, 3)
-
- def tearDown(self):
- self.assertFalse(lru.inv_failed, "invariant failed; see logs")
-
- def check_result(self, r, exp, exp_hits=None, exp_misses=None,
- exp_refhits=None):
- self.assertEqual(r, exp)
- if exp_hits is not None:
- self.assertEqual(self.lru.hits, exp_hits)
- if exp_misses is not None:
- self.assertEqual(self.lru.misses, exp_misses)
- if exp_refhits is not None:
- self.assertEqual(self.lru.refhits, exp_refhits)
-
- def test_single_key(self):
- # just get an item
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
-
- # second time, it should be cached..
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, short('a'), 1, 1)
-
- def test_simple_lru_expulsion(self):
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
- val = self.lru.get('b')
- self.check_result(val, short('b'), 0, 2)
- val = self.lru.get('c')
- self.check_result(val, short('c'), 0, 3)
- val = self.lru.get('d')
- self.check_result(val, short('d'), 0, 4)
- del(val)
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, long('a'), 0, 5)
-
- # ..and that expelled B, but C is still in the cache
- val = self.lru.get('c')
- self.check_result(val, short('c'), 1, 5)
-
- def test_simple_lru_expulsion_maxsize_1(self):
- self.lru = lru.LRUCache(short, 1)
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
- val = self.lru.get('a')
- self.check_result(val, short('a'), 1, 1)
- val = self.lru.get('b')
- self.check_result(val, short('b'), 1, 2)
- del(val)
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, long('a'), 1, 3)
- del(val)
- gc.collect()
-
- # ..and that expelled B
- val = self.lru.get('b')
- self.check_result(val, long('b'), 1, 4)
-
- def test_simple_lru_expulsion_maxsize_1_null_result(self):
- # a regression test for #2011
- def miss_fn(k):
- if k == 'b':
- return None
- else:
- return short(k)
- self.lru = lru.LRUCache(miss_fn, 1)
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
- val = self.lru.get('b')
- self.check_result(val, None, 0, 2)
- del(val)
-
- # 'a' was not expelled since 'b' was None
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, short('a'), 1, 2)
-
- def test_queue_collapsing(self):
- # just to check that we're practicing with the right queue size (so
- # QUEUE_SIZE_FACTOR is 10)
- self.assertEqual(self.lru.max_queue, 30)
-
- for c in 'a' + 'x' * 27 + 'ab':
- res = self.lru.get(c)
- self.check_result(res, short('b'), 27, 3)
-
- # at this point, we should have 'x', 'a', and 'b' in the cache, and
- # 'axx..xxab' in the queue.
- self.assertEqual(len(self.lru.queue), 30)
-
- # This 'get' operation for an existing key should cause compaction
- res = self.lru.get('b')
- self.check_result(res, short('b'), 28, 3)
-
- self.assertEqual(len(self.lru.queue), 3)
-
- # expect a cached short('a')
- self.lru.miss_fn = long
- res = self.lru.get('a')
- self.check_result(res, short('a'), 29, 3)
-
- def test_all_misses(self):
- for i, c in enumerate(string.lowercase + string.uppercase):
- res = self.lru.get(c)
- self.check_result(res, short(c), 0, i+1)
-
- def test_get_exception(self):
- def fail_miss_fn(k):
- raise RuntimeError("oh noes")
- self.lru.miss_fn = fail_miss_fn
-
- got_exc = False
- try:
- self.lru.get('abc')
- except RuntimeError:
- got_exc = True
-
- self.assertEqual(got_exc, True)
-
- def test_all_hits(self):
- res = self.lru.get('a')
- self.check_result(res, short('a'), 0, 1)
-
- self.lru.miss_fn = long
- for i in xrange(100):
- res = self.lru.get('a')
- self.check_result(res, short('a'), i+1, 1)
-
- def test_weakrefs(self):
- res_a = self.lru.get('a')
- self.check_result(res_a, short('a'))
- # note that res_a keeps a reference to this value
-
- res_b = self.lru.get('b')
- self.check_result(res_b, short('b'))
- del res_b # discard reference to b
-
- # blow out the cache and the queue
- self.lru.miss_fn = long
- for c in (string.lowercase[2:] * 5):
- self.lru.get(c)
-
- # and fetch a again, expecting the cached value
- res = self.lru.get('a')
- self.check_result(res, res_a, exp_refhits=1)
-
- # but 'b' should give us a new value
- res = self.lru.get('b')
- self.check_result(res, long('b'), exp_refhits=1)
-
- def test_fuzz(self):
- chars = list(string.lowercase * 40)
- random.shuffle(chars)
- for i, c in enumerate(chars):
- res = self.lru.get(c)
- self.check_result(res, short(c))
-
- def test_set_max_size(self):
- # load up the cache with three items
- for c in 'abc':
- res = self.lru.get(c)
- self.check_result(res, short(c))
- del(res)
-
- # reset the size to 1
- self.lru.set_max_size(1)
- gc.collect()
-
- # and then expect that 'b' is no longer in the cache
- self.lru.miss_fn = long
- res = self.lru.get('b')
- self.check_result(res, long('b'))
-
- def test_miss_fn_kwargs(self):
- def keep_kwargs_miss_fn(k, **kwargs):
- return set(kwargs.keys())
- self.lru.miss_fn = keep_kwargs_miss_fn
-
- val = self.lru.get('a', a=1, b=2)
- self.check_result(val, set(['a', 'b']), 0, 1)
-
- def test_miss_fn_returns_none(self):
- calls = []
- def none_miss_fn(k):
- calls.append(k)
- return None
- self.lru.miss_fn = none_miss_fn
-
- for i in range(2):
- self.assertEqual(self.lru.get('a'), None)
-
- # check that the miss_fn was called twice
- self.assertEqual(calls, ['a', 'a'])
-
- def test_put(self):
- self.assertEqual(self.lru.get('p'), short('p'))
- self.lru.put('p', set(['P2P2']))
- self.assertEqual(self.lru.get('p'), set(['P2P2']))
-
- def test_put_nonexistent_key(self):
- self.assertEqual(self.lru.get('p'), short('p'))
- self.lru.put('q', set(['new-q']))
- self.assertEqual(self.lru.get('p'), set(['PPP']))
- self.assertEqual(self.lru.get('q'), set(['QQQ'])) # not updated
-
-
-class AsyncLRUCacheTest(unittest.TestCase):
-
- def setUp(self):
- lru.inv_failed = False
- self.lru = lru.AsyncLRUCache(self.short_miss_fn, 3)
-
- def tearDown(self):
- self.assertFalse(lru.inv_failed, "invariant failed; see logs")
-
- def short_miss_fn(self, key):
- return defer.succeed(short(key))
-
- def long_miss_fn(self, key):
- return defer.succeed(long(key))
-
- def failure_miss_fn(self, key):
- return defer.succeed(None)
-
- def check_result(self, r, exp, exp_hits=None, exp_misses=None,
- exp_refhits=None):
- self.assertEqual(r, exp)
- if exp_hits is not None:
- self.assertEqual(self.lru.hits, exp_hits)
- if exp_misses is not None:
- self.assertEqual(self.lru.misses, exp_misses)
- if exp_refhits is not None:
- self.assertEqual(self.lru.refhits, exp_refhits)
-
- # tests
-
- def test_single_key(self):
- # just get an item
- d = self.lru.get('a')
- d.addCallback(self.check_result, short('a'), 0, 1)
-
- # second time, it should be cached..
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 1, 1)
- return d
-
- def test_simple_lru_expulsion(self):
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 0, 1)
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, short('b'), 0, 2)
- d.addCallback(lambda _ :
- self.lru.get('c'))
- d.addCallback(self.check_result, short('c'), 0, 3)
- d.addCallback(lambda _ :
- self.lru.get('d'))
- d.addCallback(self.check_result, short('d'), 0, 4)
-
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, long('a'), 0, 5)
-
- # ..and that expelled B, but C is still in the cache
- d.addCallback(lambda _ :
- self.lru.get('c'))
- d.addCallback(self.check_result, short('c'), 1, 5)
- return d
-
- def test_simple_lru_expulsion_maxsize_1(self):
- self.lru = lru.AsyncLRUCache(self.short_miss_fn, 1)
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 0, 1)
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 1, 1)
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, short('b'), 1, 2)
-
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, long('a'), 1, 3)
-
- gc.collect()
-
- # ..and that expelled B
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, long('b'), 1, 4)
- return d
-
- def test_simple_lru_expulsion_maxsize_1_null_result(self):
- # a regression test for #2011
- def miss_fn(k):
- if k == 'b':
- return defer.succeed(None)
- else:
- return defer.succeed(short(k))
- self.lru = lru.AsyncLRUCache(miss_fn, 1)
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 0, 1)
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, None, 0, 2)
-
- # 'a' was not expelled since 'b' was None
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 1, 2)
-
- return d
-
- @defer.inlineCallbacks
- def test_queue_collapsing(self):
- # just to check that we're practicing with the right queue size (so
- # QUEUE_SIZE_FACTOR is 10)
- self.assertEqual(self.lru.max_queue, 30)
-
- for c in 'a' + 'x' * 27 + 'ab':
- res = yield self.lru.get(c)
- self.check_result(res, short('b'), 27, 3)
-
- # at this point, we should have 'x', 'a', and 'b' in the cache, and
- # 'axx..xxab' in the queue.
- self.assertEqual(len(self.lru.queue), 30)
-
- # This 'get' operation for an existing key should cause compaction
- res = yield self.lru.get('b')
- self.check_result(res, short('b'), 28, 3)
-
- self.assertEqual(len(self.lru.queue), 3)
-
- # expect a cached short('a')
- self.lru.miss_fn = self.long_miss_fn
- res = yield self.lru.get('a')
- self.check_result(res, short('a'), 29, 3)
-
- @defer.inlineCallbacks
- def test_all_misses(self):
- for i, c in enumerate(string.lowercase + string.uppercase):
- res = yield self.lru.get(c)
- self.check_result(res, short(c), 0, i+1)
-
- @defer.inlineCallbacks
- def test_get_exception(self):
- def fail_miss_fn(k):
- return defer.fail(RuntimeError("oh noes"))
- self.lru.miss_fn = fail_miss_fn
-
- got_exc = False
- try:
- yield self.lru.get('abc')
- except RuntimeError:
- got_exc = True
-
- self.assertEqual(got_exc, True)
-
- @defer.inlineCallbacks
- def test_all_hits(self):
- res = yield self.lru.get('a')
- self.check_result(res, short('a'), 0, 1)
-
- self.lru.miss_fn = self.long_miss_fn
- for i in xrange(100):
- res = yield self.lru.get('a')
- self.check_result(res, short('a'), i+1, 1)
-
- @defer.inlineCallbacks
- def test_weakrefs(self):
- res_a = yield self.lru.get('a')
- self.check_result(res_a, short('a'))
- # note that res_a keeps a reference to this value
-
- res_b = yield self.lru.get('b')
- self.check_result(res_b, short('b'))
- del res_b # discard reference to b
-
- # blow out the cache and the queue
- self.lru.miss_fn = self.long_miss_fn
- for c in (string.lowercase[2:] * 5):
- yield self.lru.get(c)
-
- # and fetch a again, expecting the cached value
- res = yield self.lru.get('a')
- self.check_result(res, res_a, exp_refhits=1)
-
- # but 'b' should give us a new value
- res = yield self.lru.get('b')
- self.check_result(res, long('b'), exp_refhits=1)
-
- @defer.inlineCallbacks
- def test_fuzz(self):
- chars = list(string.lowercase * 40)
- random.shuffle(chars)
- for i, c in enumerate(chars):
- res = yield self.lru.get(c)
- self.check_result(res, short(c))
-
- def test_massively_parallel(self):
- chars = list(string.lowercase * 5)
-
- misses = [ 0 ]
- def slow_short_miss_fn(key):
- d = defer.Deferred()
- misses[0] += 1
- reactor.callLater(0, lambda : d.callback(short(key)))
- return d
- self.lru.miss_fn = slow_short_miss_fn
-
- def check(c, d):
- d.addCallback(self.check_result, short(c))
- return d
- d = defer.gatherResults([
- check(c, self.lru.get(c))
- for c in chars ])
- def post_check(_):
- self.assertEqual(misses[0], 26)
- self.assertEqual(self.lru.misses, 26)
- self.assertEqual(self.lru.hits, 4*26)
- d.addCallback(post_check)
- return d
-
- def test_slow_fetch(self):
- def slower_miss_fn(k):
- d = defer.Deferred()
- reactor.callLater(0.05, lambda : d.callback(short(k)))
- return d
- self.lru.miss_fn = slower_miss_fn
-
- def do_get(test_d, k):
- d = self.lru.get(k)
- d.addCallback(self.check_result, short(k))
- d.addCallbacks(test_d.callback, test_d.errback)
-
- ds = []
- for i in range(8):
- d = defer.Deferred()
- reactor.callLater(0.02*i, do_get, d, 'x')
- ds.append(d)
-
- d = defer.gatherResults(ds)
- def check(_):
- self.assertEqual((self.lru.hits, self.lru.misses), (7, 1))
- d.addCallback(check)
- return d
-
- def test_slow_failure(self):
- def slow_fail_miss_fn(k):
- d = defer.Deferred()
- reactor.callLater(0.05,
- lambda : d.errback(failure.Failure(RuntimeError("oh noes"))))
- return d
- self.lru.miss_fn = slow_fail_miss_fn
-
- def do_get(test_d, k):
- d = self.lru.get(k)
- self.assertFailure(d, RuntimeError)
- d.addCallbacks(test_d.callback, test_d.errback)
-
- ds = []
- for i in range(8):
- d = defer.Deferred()
- reactor.callLater(0.02*i, do_get, d, 'x')
- ds.append(d)
-
- d = defer.gatherResults(ds)
- return d
-
- @defer.inlineCallbacks
- def test_set_max_size(self):
- # load up the cache with three items
- for c in 'abc':
- res = yield self.lru.get(c)
- self.check_result(res, short(c))
-
- # reset the size to 1
- self.lru.set_max_size(1)
- gc.collect()
-
- # and then expect that 'b' is no longer in the cache
- self.lru.miss_fn = self.long_miss_fn
- res = yield self.lru.get('b')
- self.check_result(res, long('b'))
-
- def test_miss_fn_kwargs(self):
- def keep_kwargs_miss_fn(k, **kwargs):
- return defer.succeed(set(kwargs.keys()))
- self.lru.miss_fn = keep_kwargs_miss_fn
-
- d = self.lru.get('a', a=1, b=2)
- d.addCallback(self.check_result, set(['a', 'b']), 0, 1)
- return d
-
- @defer.inlineCallbacks
- def test_miss_fn_returns_none(self):
- calls = []
- def none_miss_fn(k):
- calls.append(k)
- return defer.succeed(None)
- self.lru.miss_fn = none_miss_fn
-
- for i in range(2):
- self.assertEqual((yield self.lru.get('a')), None)
-
- # check that the miss_fn was called twice
- self.assertEqual(calls, ['a', 'a'])
-
- @defer.inlineCallbacks
- def test_put(self):
- self.assertEqual((yield self.lru.get('p')), short('p'))
- self.lru.put('p', set(['P2P2']))
- self.assertEqual((yield self.lru.get('p')), set(['P2P2']))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py
deleted file mode 100644
index 419ae448..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.util import maildir
-from buildbot.test.util import dirs
-
-class TestMaildirService(dirs.DirsMixin, unittest.TestCase):
- def setUp(self):
- self.maildir = os.path.abspath("maildir")
- self.newdir = os.path.join(self.maildir, "new")
- self.curdir = os.path.join(self.maildir, "cur")
- self.tmpdir = os.path.join(self.maildir, "tmp")
- self.setUpDirs(self.maildir, self.newdir, self.curdir, self.tmpdir)
-
- self.svc = None
-
- def tearDown(self):
- if self.svc and self.svc.running:
- self.svc.stopService()
- self.tearDownDirs()
-
- # tests
-
- @defer.inlineCallbacks
- def test_start_stop_repeatedly(self):
- self.svc = maildir.MaildirService(self.maildir)
- self.svc.startService()
- yield self.svc.stopService()
- self.svc.startService()
- yield self.svc.stopService()
- self.assertEqual(len(list(self.svc)), 0)
-
-
- def test_messageReceived(self):
- self.svc = maildir.MaildirService(self.maildir)
-
- # add a fake messageReceived method
- messagesReceived = []
- def messageReceived(filename):
- messagesReceived.append(filename)
- return defer.succeed(None)
- self.svc.messageReceived = messageReceived
- d = defer.maybeDeferred(self.svc.startService)
- def check_empty(_):
- self.assertEqual(messagesReceived, [])
- d.addCallback(check_empty)
- def add_msg(_):
- tmpfile = os.path.join(self.tmpdir, "newmsg")
- newfile = os.path.join(self.newdir, "newmsg")
- open(tmpfile, "w").close()
- os.rename(tmpfile, newfile)
- d.addCallback(add_msg)
- def trigger(_):
- # TODO: can we wait for a dnotify somehow, if enabled?
- return self.svc.poll()
- d.addCallback(trigger)
- def check_nonempty(_):
- self.assertEqual(messagesReceived, [ 'newmsg' ])
- d.addCallback(check_nonempty)
- return d
-
- def test_moveToCurDir(self):
- self.svc = maildir.MaildirService(self.maildir)
- tmpfile = os.path.join(self.tmpdir, "newmsg")
- newfile = os.path.join(self.newdir, "newmsg")
- open(tmpfile, "w").close()
- os.rename(tmpfile, newfile)
- self.svc.moveToCurDir("newmsg")
- self.assertEqual([ os.path.exists(os.path.join(d, "newmsg"))
- for d in (self.newdir, self.curdir, self.tmpdir) ],
- [ False, True, False ])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py
deleted file mode 100644
index 78f38144..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.util import misc
-from buildbot import util
-from twisted.python import failure
-from twisted.internet import defer, reactor
-from buildbot.test.util import compat
-from buildbot.util.eventual import eventually
-
-class deferredLocked(unittest.TestCase):
- def test_name(self):
- self.assertEqual(util.deferredLocked, misc.deferredLocked)
-
- def test_fn(self):
- l = defer.DeferredLock()
- @util.deferredLocked(l)
- def check_locked(arg1, arg2):
- self.assertEqual([l.locked, arg1, arg2], [True, 1, 2])
- return defer.succeed(None)
- d = check_locked(1, 2)
- def check_unlocked(_):
- self.assertFalse(l.locked)
- d.addCallback(check_unlocked)
- return d
-
- def test_fn_fails(self):
- l = defer.DeferredLock()
- @util.deferredLocked(l)
- def do_fail():
- return defer.fail(RuntimeError("oh noes"))
- d = do_fail()
- def check_unlocked(_):
- self.assertFalse(l.locked)
- d.addCallbacks(lambda _ : self.fail("didn't errback"),
- lambda _ : self.assertFalse(l.locked))
- return d
-
- def test_fn_exception(self):
- l = defer.DeferredLock()
- @util.deferredLocked(l)
- def do_fail():
- raise RuntimeError("oh noes")
- d = do_fail()
- def check_unlocked(_):
- self.assertFalse(l.locked)
- d.addCallbacks(lambda _ : self.fail("didn't errback"),
- lambda _ : self.assertFalse(l.locked))
- return d
-
- def test_method(self):
- testcase = self
- class C:
- @util.deferredLocked('aLock')
- def check_locked(self, arg1, arg2):
- testcase.assertEqual([self.aLock.locked, arg1, arg2], [True, 1, 2])
- return defer.succeed(None)
- obj = C()
- obj.aLock = defer.DeferredLock()
- d = obj.check_locked(1, 2)
- def check_unlocked(_):
- self.assertFalse(obj.aLock.locked)
- d.addCallback(check_unlocked)
- return d
-
-class SerializedInvocation(unittest.TestCase):
-
- def waitForQuiet(self, si):
- d = defer.Deferred()
- si._quiet = lambda : d.callback(None)
- return d
-
- # tests
-
- def test_name(self):
- self.assertEqual(util.SerializedInvocation, misc.SerializedInvocation)
-
- def testCallFolding(self):
- events = []
- def testfn():
- d = defer.Deferred()
- def done():
- events.append('TM')
- d.callback(None)
- eventually(done)
- return d
- si = misc.SerializedInvocation(testfn)
-
- # run three times - the first starts testfn, the second
- # requires a second run, and the third is folded.
- d1 = si()
- d2 = si()
- d3 = si()
-
- dq = self.waitForQuiet(si)
- d = defer.gatherResults([d1, d2, d3, dq])
- def check(_):
- self.assertEqual(events, [ 'TM', 'TM' ])
- d.addCallback(check)
- return d
-
- @compat.usesFlushLoggedErrors
- def testException(self):
- def testfn():
- d = defer.Deferred()
- reactor.callLater(0, d.errback,
- failure.Failure(RuntimeError("oh noes")))
- return d
- si = misc.SerializedInvocation(testfn)
-
- d = si()
-
- def check(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py
deleted file mode 100644
index 87173e5d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.protocols import basic
-from twisted.trial import unittest
-from buildbot.util import netstrings
-
-class NetstringParser(unittest.TestCase):
-
- def test_valid_netstrings(self):
- p = netstrings.NetstringParser()
- p.feed("5:hello,5:world,")
- self.assertEqual(p.strings, ['hello', 'world'])
-
- def test_valid_netstrings_byte_by_byte(self):
- # (this is really testing twisted's support, but oh well)
- p = netstrings.NetstringParser()
- [ p.feed(c) for c in "5:hello,5:world," ]
- self.assertEqual(p.strings, ['hello', 'world'])
-
- def test_invalid_netstring(self):
- p = netstrings.NetstringParser()
- self.assertRaises(basic.NetstringParseError,
- lambda : p.feed("5-hello!"))
-
- def test_incomplete_netstring(self):
- p = netstrings.NetstringParser()
- p.feed("11:hello world,6:foob")
- # note that the incomplete 'foobar' does not appear here
- self.assertEqual(p.strings, ['hello world'])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py
deleted file mode 100644
index 6c77e49a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.util import sautils
-
-class SAVersion(unittest.TestCase):
-
- def test_sa_version(self):
- self.failUnless(sautils.sa_version() > (0,5,0))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py
deleted file mode 100644
index 8e7adca2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from buildbot.util import state
-from buildbot.test.fake.fakemaster import make_master
-
-class FakeObject(state.StateMixin):
- name = "fake-name"
-
- def __init__(self, master):
- self.master = master
-
-class TestStateMixin(unittest.TestCase):
-
- OBJECTID = 19
-
- def setUp(self):
- self.master = make_master(wantDb=True, testcase=self)
- self.object = FakeObject(self.master)
-
- def test_getState(self):
- self.master.db.state.fakeState('fake-name', 'FakeObject',
- fav_color=['red','purple'])
- d = self.object.getState('fav_color')
- def check(res):
- self.assertEqual(res, ['red', 'purple'])
- d.addCallback(check)
- return d
-
- def test_getState_default(self):
- d = self.object.getState('fav_color', 'black')
- def check(res):
- self.assertEqual(res, 'black')
- d.addCallback(check)
- return d
-
- def test_getState_KeyError(self):
- self.master.db.state.fakeState('fake-name', 'FakeObject',
- fav_color=['red','purple'])
- d = self.object.getState('fav_book')
- def cb(_):
- self.fail("should not succeed")
- def check_exc(f):
- f.trap(KeyError)
- pass
- d.addCallbacks(cb, check_exc)
- return d
-
- def test_setState(self):
- d = self.object.setState('y', 14)
- def check(_):
- self.master.db.state.assertStateByClass('fake-name', 'FakeObject',
- y=14)
- d.addCallback(check)
- return d
-
- def test_setState_existing(self):
- self.master.db.state.fakeState('fake-name', 'FakeObject', x=13)
- d = self.object.setState('x', 14)
- def check(_):
- self.master.db.state.assertStateByClass('fake-name', 'FakeObject',
- x=14)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py
deleted file mode 100644
index 0defb18a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildbot.util import subscription
-from buildbot.test.util import compat
-
-class subscriptions(unittest.TestCase):
-
- def setUp(self):
- self.subpt = subscription.SubscriptionPoint('test_sub')
-
- def test_str(self):
- self.assertIn('test_sub', str(self.subpt))
-
- def test_subscribe_unsubscribe(self):
- state = []
- def cb(*args, **kwargs):
- state.append((args, kwargs))
-
- # subscribe
- sub = self.subpt.subscribe(cb)
- self.assertTrue(isinstance(sub, subscription.Subscription))
- self.assertEqual(state, [])
-
- # deliver
- self.subpt.deliver(1, 2, a=3, b=4)
- self.assertEqual(state, [((1,2), dict(a=3, b=4))])
- state.pop()
-
- # unsubscribe
- sub.unsubscribe()
-
- # don't receive events anymore
- self.subpt.deliver(3, 4)
- self.assertEqual(state, [])
-
- @compat.usesFlushLoggedErrors
- def test_exception(self):
- def cb(*args, **kwargs):
- raise RuntimeError('mah bucket!')
-
- # subscribe
- self.subpt.subscribe(cb)
- try:
- self.subpt.deliver()
- except RuntimeError:
- self.fail("should not have seen exception here!")
- # log.err will cause Trial to complain about this error anyway, unless
- # we clean it up
- self.assertEqual(1, len(self.flushLoggedErrors(RuntimeError)))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py
deleted file mode 100644
index e461dda6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import with_statement
-
-import os
-import shutil
-import cPickle
-from buildbot.test.util import db
-
-from buildbot.changes.changes import Change, OldChangeMaster
-
-class ChangeImportMixin(db.RealDatabaseMixin):
- """
- We have a number of tests that examine the results of importing particular
- flavors of Change objects. This class uses some pickling to make this easy
- to test.
-
- This is a subclass of RealDatabaseMixin, so do not inherit from that class
- separately!
-
- >>> self.make_pickle(self.make_change(who=u'jimmy'), self.make_change(who='johnny'))
- """
- def make_pickle(self, *changes, **kwargs):
- recode_fn = kwargs.pop('recode_fn', None)
- cm = OldChangeMaster()
- cm.changes = changes
- if recode_fn:
- recode_fn(cm)
- with open(self.changes_pickle, "wb") as f:
- cPickle.dump(cm, f)
-
- def make_change(self, **kwargs):
- return Change(**kwargs)
-
- def setUpChangeImport(self):
- self.basedir = os.path.abspath("basedir")
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- os.makedirs(self.basedir)
- self.changes_pickle = os.path.join(self.basedir, "changes.pck")
- return self.setUpRealDatabase()
-
- def tearDownChangeImport(self):
- d = self.tearDownRealDatabase()
- def rmtree(_):
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- d.addCallback(rmtree)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py
deleted file mode 100644
index 172f1584..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.internet import defer
-from twisted.trial import unittest
-from buildbot.test.fake.fakemaster import make_master
-
-class ChangeSourceMixin(object):
- """
- This class is used for testing change sources, and handles a few things:
-
- - starting and stopping a ChangeSource service
- - a fake C{self.master.addChange}, which adds its args
- to the list C{self.changes_added}
- """
-
- changesource = None
- started = False
-
- def setUpChangeSource(self):
- "Set up the mixin - returns a deferred."
- self.changes_added = []
- def addChange(**kwargs):
- # check for 8-bit strings
- for k,v in kwargs.items():
- if type(v) == type(""):
- try:
- v.decode('ascii')
- except UnicodeDecodeError:
- raise unittest.FailTest(
- "non-ascii string for key '%s': %r" % (k,v))
- self.changes_added.append(kwargs)
- return defer.succeed(mock.Mock())
- self.master = make_master(testcase=self, wantDb=True)
- self.master.addChange = addChange
- return defer.succeed(None)
-
- def tearDownChangeSource(self):
- "Tear down the mixin - returns a deferred."
- if not self.started:
- return defer.succeed(None)
- if self.changesource.running:
- return defer.maybeDeferred(self.changesource.stopService)
- return defer.succeed(None)
-
- def attachChangeSource(self, cs):
- "Set up a change source for testing; sets its .master attribute"
- self.changesource = cs
- self.changesource.master = self.master
-
- def startChangeSource(self):
- "start the change source as a service"
- self.started = True
- self.changesource.startService()
-
- def stopChangeSource(self):
- "stop the change source again; returns a deferred"
- d = self.changesource.stopService()
- def mark_stopped(_):
- self.started = False
- d.addCallback(mark_stopped)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py
deleted file mode 100644
index cf6305dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import twisted
-from twisted.python import versions, runtime
-
-def usesFlushLoggedErrors(test):
- "Decorate a test method that uses flushLoggedErrors with this decorator"
- if (sys.version_info[:2] == (2,7)
- and twisted.version <= versions.Version('twisted', 9, 0, 0)):
- test.skip = \
- "flushLoggedErrors is broken on Python==2.7 and Twisted<=9.0.0"
- return test
-
-def usesFlushWarnings(test):
- "Decorate a test method that uses flushWarnings with this decorator"
- if (sys.version_info[:2] == (2,7)
- and twisted.version <= versions.Version('twisted', 9, 0, 0)):
- test.skip = \
- "flushWarnings is broken on Python==2.7 and Twisted<=9.0.0"
- return test
-
-def skipUnlessPlatformIs(platform):
- def closure(test):
- if runtime.platformType != platform:
- test.skip = "not a %s platform" % platform
- return test
- return closure
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py
deleted file mode 100644
index 3747977e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot import config
-
-class ConfigErrorsMixin(object):
-
- def assertConfigError(self, errors, substr_or_re):
- if len(errors.errors) > 1:
- self.fail("too many errors: %s" % (errors.errors,))
- elif len(errors.errors) < 1:
- self.fail("expected error did not occur")
- elif isinstance(substr_or_re, str):
- if substr_or_re not in errors.errors[0]:
- self.fail("non-matching error: %s" % (errors.errors,))
- else:
- if not substr_or_re.search(errors.errors[0]):
- self.fail("non-matching error: %s" % (errors.errors,))
-
- def assertRaisesConfigError(self, substr_or_re, fn):
- try:
- fn()
- except config.ConfigErrors, e:
- self.assertConfigError(e, substr_or_re)
- else:
- self.fail("ConfigErrors not raised")
-
- def assertNoConfigErrors(self, errors):
- self.assertEqual(errors.errors, [])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py
deleted file mode 100644
index 159e824c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildbot.db import model
-from buildbot.test.util import db
-from buildbot.test.fake import fakemaster
-
-class FakeDBConnector(object):
- pass
-
-class ConnectorComponentMixin(db.RealDatabaseMixin):
- """
- Implements a mock DBConnector object, replete with a thread pool and a DB
- model. This includes a RealDatabaseMixin, so subclasses should not
- instantiate that class directly. The connector appears at C{self.db}, and
- the component should be attached to it as an attribute.
-
- @ivar db: fake database connector
- @ivar db.pool: DB thread pool
- @ivar db.model: DB model
- """
- def setUpConnectorComponent(self, table_names=[], basedir='basedir'):
- """Set up C{self.db}, using the given db_url and basedir."""
- d = self.setUpRealDatabase(table_names=table_names, basedir=basedir)
- def finish_setup(_):
- self.db = FakeDBConnector()
- self.db.pool = self.db_pool
- self.db.model = model.Model(self.db)
- self.db.master = fakemaster.make_master()
- d.addCallback(finish_setup)
- return d
-
- def tearDownConnectorComponent(self):
- d = self.tearDownRealDatabase()
- def finish_cleanup(_):
- self.db_pool.shutdown()
- # break some reference loops, just for fun
- del self.db.pool
- del self.db.model
- del self.db
- d.addCallback(finish_cleanup)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py
deleted file mode 100644
index 67f2ce0c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import sqlalchemy as sa
-from sqlalchemy.schema import MetaData
-from twisted.python import log
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.db import model, pool, enginestrategy
-
-def skip_for_dialect(dialect):
- """Decorator to skip a test for a particular SQLAlchemy dialect."""
- def dec(fn):
- def wrap(self, *args, **kwargs):
- if self.db_engine.dialect.name == dialect:
- raise unittest.SkipTest(
- "Not supported on dialect '%s'" % dialect)
- return fn(self, *args, **kwargs)
- return wrap
- return dec
-
-class RealDatabaseMixin(object):
- """
- A class that sets up a real database for testing. This sets self.db_url to
- the URL for the database. By default, it specifies an in-memory SQLite
- database, but if the BUILDBOT_TEST_DB_URL environment variable is set, it
- will use the specified database, being careful to clean out *all* tables in
- the database before and after the tests are run - so each test starts with
- a clean database.
-
- @ivar db_pool: a (real) DBThreadPool instance that can be used as desired
-
- @ivar db_url: the DB URL used to run these tests
-
- @ivar db_engine: the engine created for the test database
- """
-
- # Note that this class uses the production database model. A
- # re-implementation would be virtually identical and just require extra
- # work to keep synchronized.
-
- # Similarly, this class uses the production DB thread pool. This achieves
- # a few things:
- # - affords more thorough tests for the pool
- # - avoids repetitive implementation
- # - cooperates better at runtime with thread-sensitive DBAPI's
-
- def __thd_clean_database(self, conn):
- # drop the known tables, although sometimes this misses dependencies
- try:
- model.Model.metadata.drop_all(bind=conn, checkfirst=True)
- except sa.exc.ProgrammingError:
- pass
-
- # see if we can find any other tables to drop
- meta = MetaData(bind=conn)
- meta.reflect()
- meta.drop_all()
-
- def __thd_create_tables(self, conn, table_names):
- all_table_names = set(table_names)
- ordered_tables = [ t for t in model.Model.metadata.sorted_tables
- if t.name in all_table_names ]
-
- for tbl in ordered_tables:
- tbl.create(bind=conn, checkfirst=True)
-
- def setUpRealDatabase(self, table_names=[], basedir='basedir',
- want_pool=True, sqlite_memory=True):
- """
-
- Set up a database. Ordinarily sets up an engine and a pool and takes
- care of cleaning out any existing tables in the database. If
- C{want_pool} is false, then no pool will be created, and the database
- will not be cleaned.
-
- @param table_names: list of names of tables to instantiate
- @param basedir: (optional) basedir for the engine
- @param want_pool: (optional) false to not create C{self.db_pool}
- @param sqlite_memory: (optional) False to avoid using an in-memory db
- @returns: Deferred
- """
- self.__want_pool = want_pool
-
- default = 'sqlite://'
- if not sqlite_memory:
- default = "sqlite:///tmp.sqlite"
- if not os.path.exists(basedir):
- os.makedirs(basedir)
-
- self.db_url = os.environ.get('BUILDBOT_TEST_DB_URL', default)
-
- self.db_engine = enginestrategy.create_engine(self.db_url,
- basedir=basedir)
- # if the caller does not want a pool, we're done.
- if not want_pool:
- return defer.succeed(None)
-
- self.db_pool = pool.DBThreadPool(self.db_engine)
-
- log.msg("cleaning database %s" % self.db_url)
- d = self.db_pool.do(self.__thd_clean_database)
- d.addCallback(lambda _ :
- self.db_pool.do(self.__thd_create_tables, table_names))
- return d
-
- def tearDownRealDatabase(self):
- if self.__want_pool:
- return self.db_pool.do(self.__thd_clean_database)
- else:
- return defer.succeed(None)
-
- def insertTestData(self, rows):
- """Insert test data into the database for use during the test.
-
- @param rows: be a sequence of L{fakedb.Row} instances. These will be
- sorted by table dependencies, so order does not matter.
-
- @returns: Deferred
- """
- # sort the tables by dependency
- all_table_names = set([ row.table for row in rows ])
- ordered_tables = [ t for t in model.Model.metadata.sorted_tables
- if t.name in all_table_names ]
- def thd(conn):
- # insert into tables -- in order
- for tbl in ordered_tables:
- for row in [ r for r in rows if r.table == tbl.name ]:
- tbl = model.Model.metadata.tables[row.table]
- try:
- tbl.insert(bind=conn).execute(row.values)
- except:
- log.msg("while inserting %s - %s" % (row, row.values))
- raise
- return self.db_pool.do(thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py
deleted file mode 100644
index 22b5dd55..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import shutil
-from twisted.internet import defer
-
-class DirsMixin(object):
-
- _dirs = None
-
- def setUpDirs(self, *dirs):
- """Make sure C{dirs} exist and are empty, and set them up to be deleted
- in tearDown."""
- self._dirs = map(os.path.abspath, dirs)
- for dir in self._dirs:
- if os.path.exists(dir):
- shutil.rmtree(dir)
- os.makedirs(dir)
- # return a deferred to make chaining easier
- return defer.succeed(None)
-
- def tearDownDirs(self):
- for dir in self._dirs:
- if os.path.exists(dir):
- shutil.rmtree(dir)
- # return a deferred to make chaining easier
- return defer.succeed(None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py
deleted file mode 100644
index 05bb5849..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer, utils
-
-class Expect(object):
- _stdout = ""
- _stderr = ""
- _exit = 0
- _path = None
-
- def __init__(self, bin, *args):
- self._bin = bin
- self._args = args
-
- def stdout(self, stdout):
- self._stdout = stdout
- return self
-
- def stderr(self, stderr):
- self._stderr = stderr
- return self
-
- def exit(self, exit):
- self._exit = exit
- return self
-
- def path(self, path):
- self._path = path
- return self
-
- def check(self, test, bin, path, args):
- test.assertEqual(
- dict(bin=bin, path=path, args=tuple(args)),
- dict(bin=self._bin, path=self._path, args=self._args),
- "unexpected command run")
- return (self._stdout, self._stderr, self._exit)
-
- def __repr__(self):
- return "<gpo.Expect(bin=%s, args=%s)>" % (self._bin, self._args)
-
-
-class GetProcessOutputMixin:
-
- def setUpGetProcessOutput(self):
- self._gpo_patched = False
- self._expected_commands = []
- self._gpo_expect_env = {}
-
- def assertAllCommandsRan(self):
- self.assertEqual(self._expected_commands, [],
- "assert all expected commands were run")
-
- def _check_env(self, env):
- env = env or {}
- for var, value in self._gpo_expect_env.items():
- self.assertEqual(env.get(var), value,
- 'Expected environment to have %s = %r' % (var, value))
-
- def patched_getProcessOutput(self, bin, args, env=None,
- errortoo=False, path=None):
- d = self.patched_getProcessOutputAndValue(bin, args, env=env,
- path=path)
- @d.addCallback
- def cb(res):
- stdout, stderr, exit = res
- if errortoo:
- return defer.succeed(stdout + stderr)
- else:
- if stderr:
- return defer.fail(IOError("got stderr: %r" % (stderr,)))
- else:
- return defer.succeed(stdout)
- return d
-
- def patched_getProcessOutputAndValue(self, bin, args, env=None,
- path=None):
- self._check_env(env)
-
- if not self._expected_commands:
- self.fail("got command %s %s when no further commands were expected"
- % (bin, args))
-
- expect = self._expected_commands.pop(0)
- return defer.succeed(expect.check(self, bin, path, args))
-
- def _patch_gpo(self):
- if not self._gpo_patched:
- self.patch(utils, "getProcessOutput",
- self.patched_getProcessOutput)
- self.patch(utils, "getProcessOutputAndValue",
- self.patched_getProcessOutputAndValue)
- self._gpo_patched = True
-
- def addGetProcessOutputExpectEnv(self, d):
- self._gpo_expect_env.update(d)
-
- def expectCommands(self, *exp):
- """
- Add to the expected commands, along with their results. Each
- argument should be an instance of L{Expect}.
- """
- self._patch_gpo()
- self._expected_commands.extend(exp)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py
deleted file mode 100644
index 44756ffe..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import inspect
-
-class InterfaceTests(object):
-
- # assertions
-
- def assertArgSpecMatches(self, actual):
- def wrap(template):
- actual_argspec = inspect.getargspec(actual)
- template_argspec = inspect.getargspec(template)
- if actual_argspec != template_argspec:
- msg = "Expected: %s; got: %s" % (
- inspect.formatargspec(*template_argspec),
- inspect.formatargspec(*actual_argspec))
- self.fail(msg)
- return template # just in case it's useful
- return wrap
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py
deleted file mode 100644
index f482fd37..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import re
-from twisted.python import log
-
-class LoggingMixin(object):
-
- def setUpLogging(self):
- self._logEvents = []
- log.addObserver(self._logEvents.append)
- self.addCleanup(log.removeObserver, self._logEvents.append)
-
- def assertLogged(self, regexp):
- r = re.compile(regexp)
- for event in self._logEvents:
- msg = log.textFromEventDict(event)
- if msg is not None and r.search(msg):
- return
- self.fail("%r not matched in log output" % regexp)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py
deleted file mode 100644
index 42cef870..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from twisted.python import log
-from twisted.internet import defer
-import sqlalchemy as sa
-import migrate
-import migrate.versioning.api
-from buildbot.db import connector
-from buildbot.test.util import db, dirs, querylog
-from buildbot.test.fake import fakemaster
-
-
-# test_upgrade vs. migration tests
-#
-# test_upgrade is an integration test -- it tests the whole upgrade process,
-# including the code in model.py. Migrate tests are unit tests, and test a
-# single db upgrade script.
-
-class MigrateTestMixin(db.RealDatabaseMixin, dirs.DirsMixin):
-
- def setUpMigrateTest(self):
- self.basedir = os.path.abspath("basedir")
- self.setUpDirs('basedir')
-
- d = self.setUpRealDatabase()
- def make_dbc(_):
- master = fakemaster.make_master()
- self.db = connector.DBConnector(master, self.basedir)
- self.db.pool = self.db_pool
- d.addCallback(make_dbc)
- return d
-
- def tearDownMigrateTest(self):
- self.tearDownDirs()
- return self.tearDownRealDatabase()
-
- def do_test_migration(self, base_version, target_version,
- setup_thd_cb, verify_thd_cb):
- d = defer.succeed(None)
- def setup_thd(conn):
- metadata = sa.MetaData()
- table = sa.Table('migrate_version', metadata,
- sa.Column('repository_id', sa.String(250),
- primary_key=True),
- sa.Column('repository_path', sa.Text),
- sa.Column('version', sa.Integer))
- table.create(bind=conn)
- conn.execute(table.insert(),
- repository_id='Buildbot',
- repository_path=self.db.model.repo_path,
- version=base_version)
- setup_thd_cb(conn)
- d.addCallback(lambda _ : self.db.pool.do(setup_thd))
-
- def upgrade_thd(engine):
- querylog.log_from_engine(engine)
- schema = migrate.versioning.schema.ControlledSchema(engine,
- self.db.model.repo_path)
- changeset = schema.changeset(target_version)
- for version, change in changeset:
- log.msg('upgrading to schema version %d' % (version+1))
- schema.runchange(version, change, 1)
- d.addCallback(lambda _ : self.db.pool.do_with_engine(upgrade_thd))
-
- d.addCallback(lambda _ : self.db.pool.do(verify_thd_cb))
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py
deleted file mode 100644
index aeb0f63a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import sys
-import cStringIO
-
-class PatcherMixin(object):
- """
- Mix this in to get a few special-cased patching methods
- """
-
- def patch_os_uname(self, replacement):
- # twisted's 'patch' doesn't handle the case where an attribute
- # doesn't exist..
- if hasattr(os, 'uname'):
- self.patch(os, 'uname', replacement)
- else:
- def cleanup():
- del os.uname
- self.addCleanup(cleanup)
- os.uname = replacement
-
-class StdoutAssertionsMixin(object):
- """
- Mix this in to be able to assert on stdout during the test
- """
- def setUpStdoutAssertions(self):
- self.stdout = cStringIO.StringIO()
- self.patch(sys, 'stdout', self.stdout)
-
- def assertWasQuiet(self):
- self.assertEqual(self.stdout.getvalue(), '')
-
- def assertInStdout(self, exp):
- self.assertIn(exp, self.stdout.getvalue())
-
- def getStdout(self):
- return self.stdout.getvalue().strip()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py
deleted file mode 100644
index ac215744..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from twisted.internet import defer
-
-class PBManagerMixin:
- def setUpPBChangeSource(self):
- "Set up a fake self.pbmanager."
- self.registrations = []
- self.unregistrations = []
- pbm = self.pbmanager = mock.Mock()
- pbm.register = self._fake_register
-
- def _fake_register(self, portstr, username, password, factory):
- reg = mock.Mock()
- def unregister():
- self.unregistrations.append((portstr, username, password))
- return defer.succeed(None)
- reg.unregister = unregister
- self.registrations.append((portstr, username, password))
- return reg
-
- def assertNotRegistered(self):
- self.assertEqual(self.registrations, [])
-
- def assertRegistered(self, portstr, username, password):
- for ps, un, pw in self.registrations:
- if ps == portstr and username == un and pw == password:
- return
- self.fail("not registered: %r not in %s" %
- ((portstr, username, password), self.registrations))
-
- def assertUnregistered(self, portstr, username, password):
- for ps, un, pw in self.unregistrations:
- if ps == portstr and username == un and pw == password:
- return
- self.fail("still registered")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py
deleted file mode 100644
index 36b958f1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from zope.interface import implements
-from buildbot.interfaces import IRenderable
-
-class ConstantRenderable(object):
- implements(IRenderable)
- def __init__(self, value):
- self.value = value
- def getRenderingFor(self, props):
- return self.value
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py
deleted file mode 100644
index 359657a4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from __future__ import absolute_import
-import logging
-from twisted.python import log
-
-# this class bridges Python's `logging` module into Twisted's log system.
-# SqlAlchemy query logging uses `logging`, so this provides a way to enter
-# queries into the Twisted log file.
-
-class PythonToTwistedHandler(logging.Handler):
-
- def emit(self, record):
- log.msg(record.getMessage())
-
-def log_from_engine(engine):
- # add the handler *before* enabling logging, so that no "default" logger
- # is added automatically, but only do so once. This is important since
- # logging's loggers are singletons
- if not engine.logger.handlers:
- engine.logger.addHandler(PythonToTwistedHandler())
- engine.echo = True
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py
deleted file mode 100644
index 680bc48f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-from buildbot.test.fake import fakedb
-
-class FakeMaster(object):
-
- def __init__(self, basedir, db):
- self.basedir = basedir
- self.db = db
- self.changes_subscr_cb = None
- self.bset_subscr_cb = None
- self.bset_completion_subscr_cb = None
- self.caches = mock.Mock(name="caches")
- self.caches.get_cache = self.get_cache
-
- def addBuildset(self, **kwargs):
- return self.db.buildsets.addBuildset(**kwargs)
-
- # subscriptions
- # note that only one subscription of each type is supported
-
- def _makeSubscription(self, attr_to_clear):
- sub = mock.Mock()
- def unsub():
- setattr(self, attr_to_clear, None)
- sub.unsubscribe = unsub
- return sub
-
- def subscribeToChanges(self, callback):
- assert not self.changes_subscr_cb
- self.changes_subscr_cb = callback
- return self._makeSubscription('changes_subscr_cb')
-
- def subscribeToBuildsets(self, callback):
- assert not self.bset_subscr_cb
- self.bset_subscr_cb = callback
- return self._makeSubscription('bset_subscr_cb')
-
- def subscribeToBuildsetCompletions(self, callback):
- assert not self.bset_completion_subscr_cb
- self.bset_completion_subscr_cb = callback
- return self._makeSubscription('bset_completion_subscr_cb')
-
- # caches
-
- def get_cache(self, cache_name, miss_fn):
- c = mock.Mock(name=cache_name)
- c.get = miss_fn
- return c
-
- # useful assertions
-
- def getSubscriptionCallbacks(self):
- """get the subscription callbacks set on the master, in a dictionary
- with keys @{buildsets}, @{buildset_completion}, and C{changes}."""
- return dict(buildsets=self.bset_subscr_cb,
- buildset_completion=self.bset_completion_subscr_cb,
- changes=self.changes_subscr_cb)
-
-
-class SchedulerMixin(object):
- """
- This class fakes out enough of a master and the various relevant database
- connectors to test schedulers. All of the database methods have identical
- signatures to the real database connectors, but for ease of testing always
- return an already-fired Deferred, meaning that there is no need to wait for
- events to complete.
-
- This class is tightly coupled with the various L{buildbot.test.fake.fakedb}
- module. All instance variables are only available after C{attachScheduler}
- has been called.
-
- @ivar sched: scheduler instance
- @ivar master: the fake master
- @ivar db: the fake db (same as C{self.master.db}, but shorter)
- """
-
- def setUpScheduler(self):
- pass
-
- def tearDownScheduler(self):
- pass
-
- def attachScheduler(self, scheduler, objectid):
- """Set up a scheduler with a fake master and db; sets self.sched, and
- sets the master's basedir to the absolute path of 'basedir' in the test
- directory.
-
- @returns: scheduler
- """
- scheduler.objectid = objectid
-
- # set up a fake master
- db = self.db = fakedb.FakeDBConnector(self)
- self.master = FakeMaster(os.path.abspath('basedir'), db)
- scheduler.master = self.master
-
- db.insertTestData([
- fakedb.Object(id=objectid, name=scheduler.name,
- class_name='SomeScheduler'),
- ])
-
- self.sched = scheduler
- return scheduler
-
- class FakeChange:
- who = ''
- files = []
- comments = ''
- isdir=0
- links=None
- revision=None
- when=None
- branch=None
- category=None
- revlink=''
- properties={}
- repository=''
- project=''
- codebase=''
-
- def makeFakeChange(self, **kwargs):
- """Utility method to make a fake Change object with the given
- attributes"""
- ch = self.FakeChange()
- ch.__dict__.update(kwargs)
- return ch
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py
deleted file mode 100644
index df1b931b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from buildbot.test.util import steps
-
-import os
-
-class SourceStepMixin(steps.BuildStepMixin):
- """
- Support for testing source steps. Aside from the capabilities of
- L{BuildStepMixin}, this adds:
-
- - fake sourcestamps
-
- The following instance variables are available after C{setupSourceStep}, in
- addition to those made available by L{BuildStepMixin}:
-
- @ivar sourcestamp: fake SourceStamp for the build
- """
-
- def setUpSourceStep(self):
- return steps.BuildStepMixin.setUpBuildStep(self)
-
- def tearDownSourceStep(self):
- return steps.BuildStepMixin.tearDownBuildStep(self)
-
- # utilities
-
- def setupStep(self, step, args={}, patch=None, **kwargs):
- """
- Set up C{step} for testing. This calls L{BuildStepMixin}'s C{setupStep}
- and then does setup specific to a Source step.
- """
- step = steps.BuildStepMixin.setupStep(self, step, **kwargs)
-
- ss = self.sourcestamp = mock.Mock(name="sourcestamp")
- ss.ssid = 9123
- ss.branch = args.get('branch', None)
- ss.revision = args.get('revision', None)
- ss.project = ''
- ss.repository = ''
- ss.patch = patch
- ss.patch_info = None
- ss.changes = []
- self.build.path_module = os.path
- self.build.getSourceStamp = lambda x=None: ss
- return step
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py
deleted file mode 100644
index 3c70d92e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import mock
-from buildbot import interfaces
-from buildbot.process import buildstep
-from buildbot.test.fake import remotecommand, fakebuild, slave
-
-
-class BuildStepMixin(object):
- """
- Support for testing build steps. This class adds two capabilities:
-
- - patch out RemoteCommand with fake versions that check expected
- commands and produce the appropriate results
-
- - surround a step with the mock objects that it needs to execute
-
- The following instance variables are available after C{setupStep}:
-
- @ivar step: the step under test
- @ivar build: the fake build containing the step
- @ivar progress: mock progress object
- @ivar buildslave: mock buildslave object
- @ivar step_status: mock StepStatus object
- @ivar properties: build properties (L{Properties} instance)
- """
-
- def setUpBuildStep(self):
- # make an (admittedly global) reference to this test case so that
- # the fakes can call back to us
- remotecommand.FakeRemoteCommand.testcase = self
- self.patch(buildstep, 'RemoteCommand',
- remotecommand.FakeRemoteCommand)
- self.patch(buildstep, 'RemoteShellCommand',
- remotecommand.FakeRemoteShellCommand)
- self.expected_remote_commands = []
-
- def tearDownBuildStep(self):
- # delete the reference added in setUp
- del remotecommand.FakeRemoteCommand.testcase
-
- # utilities
-
- def setupStep(self, step, slave_version={'*':"99.99"}, slave_env={}):
- """
- Set up C{step} for testing. This begins by using C{step} as a factory
- to create a I{new} step instance, thereby testing that the the factory
- arguments are handled correctly. It then creates a comfortable
- environment for the slave to run in, repleate with a fake build and a
- fake slave.
-
- As a convenience, it calls the step's setDefaultWorkdir method with
- C{'wkdir'}.
-
- @param slave_version: slave version to present, as a dictionary mapping
- command name to version. A command name of '*' will apply for all
- commands.
-
- @param slave_env: environment from the slave at slave startup
- """
- factory = interfaces.IBuildStepFactory(step)
- step = self.step = factory.buildStep()
-
- # step.build
-
- b = self.build = fakebuild.FakeBuild()
- def getSlaveVersion(cmd, oldversion):
- if cmd in slave_version:
- return slave_version[cmd]
- if '*' in slave_version:
- return slave_version['*']
- return oldversion
- b.getSlaveCommandVersion = getSlaveVersion
- b.slaveEnvironment = slave_env.copy()
- step.setBuild(b)
-
- # watch for properties being set
- self.properties = interfaces.IProperties(b)
-
- # step.progress
-
- step.progress = mock.Mock(name="progress")
-
- # step.buildslave
-
- self.buildslave = step.buildslave = slave.FakeSlave()
-
- # step.step_status
-
- ss = self.step_status = mock.Mock(name="step_status")
-
- ss.status_text = None
- ss.logs = {}
-
- def ss_setText(strings):
- ss.status_text = strings
- ss.setText = ss_setText
-
- ss.getLogs = lambda : ss.logs.values()
-
- self.step_statistics = {}
- ss.setStatistic = self.step_statistics.__setitem__
- ss.getStatistic = self.step_statistics.get
- ss.hasStatistic = self.step_statistics.__contains__
-
- self.step.setStepStatus(ss)
-
- # step overrides
-
- def addLog(name):
- l = remotecommand.FakeLogFile(name, step)
- ss.logs[name] = l
- return l
- step.addLog = addLog
-
- def addHTMLLog(name, html):
- l = remotecommand.FakeLogFile(name, step)
- l.addStdout(html)
- ss.logs[name] = l
- return l
- step.addHTMLLog = addHTMLLog
-
- def addCompleteLog(name, text):
- l = remotecommand.FakeLogFile(name, step)
- l.addStdout(text)
- ss.logs[name] = l
- return l
- step.addCompleteLog = addCompleteLog
-
- step.logobservers = self.logobservers = {}
- def addLogObserver(logname, observer):
- self.logobservers.setdefault(logname, []).append(observer)
- observer.step = step
- step.addLogObserver = addLogObserver
-
- # set defaults
-
- step.setDefaultWorkdir('wkdir')
-
- # expectations
-
- self.exp_outcome = None
- self.exp_properties = {}
- self.exp_missing_properties = []
- self.exp_logfiles = {}
- self.exp_hidden = False
-
- return step
-
- def expectCommands(self, *exp):
- """
- Add to the expected remote commands, along with their results. Each
- argument should be an instance of L{Expect}.
- """
- self.expected_remote_commands.extend(exp)
-
- def expectOutcome(self, result, status_text):
- """
- Expect the given result (from L{buildbot.status.results}) and status
- text (a list).
- """
- self.exp_outcome = dict(result=result, status_text=status_text)
-
- def expectProperty(self, property, value, source=None):
- """
- Expect the given property to be set when the step is complete.
- """
- self.exp_properties[property] = (value, source)
-
- def expectNoProperty(self, property):
- """
- Expect the given property is *not* set when the step is complete
- """
- self.exp_missing_properties.append(property)
-
- def expectLogfile(self, logfile, contents):
- """
- Expect a logfile with the given contents
- """
- self.exp_logfiles[logfile] = contents
-
- def expectHidden(self, hidden):
- """
- Set whether the step is expected to be hidden.
- """
- self.exp_hidden = hidden
-
- def runStep(self):
- """
- Run the step set up with L{setupStep}, and check the results.
-
- @returns: Deferred
- """
- self.remote = mock.Mock(name="SlaveBuilder(remote)")
- # TODO: self.step.setupProgress()
- d = self.step.startStep(self.remote)
- def check(result):
- self.assertEqual(self.expected_remote_commands, [],
- "assert all expected commands were run")
- got_outcome = dict(result=result,
- status_text=self.step_status.status_text)
- self.assertEqual(got_outcome, self.exp_outcome, "expected step outcome")
- for pn, (pv, ps) in self.exp_properties.iteritems():
- self.assertTrue(self.properties.hasProperty(pn),
- "missing property '%s'" % pn)
- self.assertEqual(self.properties.getProperty(pn), pv, "property '%s'" % pn)
- if ps is not None:
- self.assertEqual(self.properties.getPropertySource(pn), ps, "property '%s' source" % pn)
- for pn in self.exp_missing_properties:
- self.assertFalse(self.properties.hasProperty(pn), "unexpected property '%s'" % pn)
- for log, contents in self.exp_logfiles.iteritems():
- self.assertEqual(self.step_status.logs[log].stdout, contents, "log '%s' contents" % log)
- self.step_status.setHidden.assert_called_once_with(self.exp_hidden)
- d.addCallback(check)
- return d
-
- # callbacks from the running step
-
- def _remotecommand_run(self, command, step, remote):
- self.assertEqual(step, self.step)
- self.assertEqual(remote, self.remote)
- got = (command.remote_command, command.args)
-
- if not self.expected_remote_commands:
- self.fail("got command %r when no further commands were expected"
- % (got,))
-
- exp = self.expected_remote_commands.pop(0)
-
- # handle any incomparable args
- for arg in exp.incomparable_args:
- self.failUnless(arg in got[1],
- "incomparable arg '%s' not received" % (arg,))
- del got[1][arg]
-
- # first check any ExpectedRemoteReference instances
- self.assertEqual((exp.remote_command, exp.args), got)
-
- # let the Expect object show any behaviors that are required
- d = exp.runBehaviors(command)
- d.addCallback(lambda _: command)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py
deleted file mode 100644
index 281c345c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import time, re, string
-import datetime
-import calendar
-from buildbot.util.misc import deferredLocked, SerializedInvocation
-
-def naturalSort(l):
- l = l[:]
- def try_int(s):
- try:
- return int(s)
- except ValueError:
- return s
- def key_func(item):
- return [try_int(s) for s in re.split('(\d+)', item)]
- # prepend integer keys to each element, sort them, then strip the keys
- keyed_l = [ (key_func(i), i) for i in l ]
- keyed_l.sort()
- l = [ i[1] for i in keyed_l ]
- return l
-
-def flatten(l):
- if l and type(l[0]) == list:
- rv = []
- for e in l:
- if type(e) == list:
- rv.extend(flatten(e))
- else:
- rv.append(e)
- return rv
- else:
- return l
-
-def now(_reactor=None):
- if _reactor and hasattr(_reactor, "seconds"):
- return _reactor.seconds()
- else:
- return time.time()
-
-def formatInterval(eta):
- eta_parts = []
- if eta > 3600:
- eta_parts.append("%d hrs" % (eta / 3600))
- eta %= 3600
- if eta > 60:
- eta_parts.append("%d mins" % (eta / 60))
- eta %= 60
- eta_parts.append("%d secs" % eta)
- return ", ".join(eta_parts)
-
-class ComparableMixin:
-
- compare_attrs = []
-
- class _None:
- pass
-
- def __hash__(self):
- alist = [self.__class__] + \
- [getattr(self, name, self._None) for name in self.compare_attrs]
- return hash(tuple(map(str, alist)))
-
- def __cmp__(self, them):
- result = cmp(type(self), type(them))
- if result:
- return result
-
- result = cmp(self.__class__.__name__, them.__class__.__name__)
- if result:
- return result
-
- result = cmp(self.compare_attrs, them.compare_attrs)
- if result:
- return result
-
- self_list = [getattr(self, name, self._None)
- for name in self.compare_attrs]
- them_list = [getattr(them, name, self._None)
- for name in self.compare_attrs]
- return cmp(self_list, them_list)
-
-def diffSets(old, new):
- if not isinstance(old, set):
- old = set(old)
- if not isinstance(new, set):
- new = set(new)
- return old - new, new - old
-
-# Remove potentially harmful characters from builder name if it is to be
-# used as the build dir.
-badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~",
- "______________________________")
-def safeTranslate(str):
- if isinstance(str, unicode):
- str = str.encode('utf8')
- return str.translate(badchars_map)
-
-def none_or_str(x):
- if x is not None and not isinstance(x, str):
- return str(x)
- return x
-
-# place a working json module at 'buildbot.util.json'. Code is adapted from
-# Paul Wise <pabs@debian.org>:
-# http://lists.debian.org/debian-python/2010/02/msg00016.html
-# json doesn't exist as a standard module until python2.6
-# However python2.6's json module is much slower than simplejson, so we prefer
-# to use simplejson if available.
-try:
- import simplejson as json
- assert json
-except ImportError:
- import json # python 2.6 or 2.7
-try:
- _tmp = json.loads
-except AttributeError:
- import warnings
- import sys
- warnings.warn("Use simplejson, not the old json module.")
- sys.modules.pop('json') # get rid of the bad json module
- import simplejson as json
-
-# changes and schedulers consider None to be a legitimate name for a branch,
-# which makes default function keyword arguments hard to handle. This value
-# is always false.
-class NotABranch:
- def __nonzero__(self):
- return False
-NotABranch = NotABranch()
-
-# time-handling methods
-
-class UTC(datetime.tzinfo):
- """Simple definition of UTC timezone"""
- def utcoffset(self, dt):
- return datetime.timedelta(0)
-
- def dst(self, dt):
- return datetime.timedelta(0)
-
- def tzname(self):
- return "UTC"
-UTC = UTC()
-
-def epoch2datetime(epoch):
- """Convert a UNIX epoch time to a datetime object, in the UTC timezone"""
- if epoch is not None:
- return datetime.datetime.fromtimestamp(epoch, tz=UTC)
-
-def datetime2epoch(dt):
- """Convert a non-naive datetime object to a UNIX epoch timestamp"""
- if dt is not None:
- return calendar.timegm(dt.utctimetuple())
-
-def makeList(input):
- if isinstance(input, basestring):
- return [ input ]
- elif input is None:
- return [ ]
- else:
- return list(input)
-
-def in_reactor(f):
- """decorate a function by running it with maybeDeferred in a reactor"""
- def wrap(*args, **kwargs):
- from twisted.internet import reactor, defer
- result = [ ]
- def async():
- d = defer.maybeDeferred(f, *args, **kwargs)
- def eb(f):
- f.printTraceback()
- d.addErrback(eb)
- def do_stop(r):
- result.append(r)
- reactor.stop()
- d.addBoth(do_stop)
- reactor.callWhenRunning(async)
- reactor.run()
- return result[0]
- wrap.__doc__ = f.__doc__
- wrap.__name__ = f.__name__
- wrap._orig = f # for tests
- return wrap
-
-__all__ = [
- 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json',
- 'safeTranslate', 'LRUCache', 'none_or_str',
- 'NotABranch', 'deferredLocked', 'SerializedInvocation', 'UTC',
- 'diffLists', 'makeList', 'in_reactor' ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py
deleted file mode 100644
index 96e0eb27..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# this is here for compatibility
-from collections import defaultdict
-assert defaultdict
-
-class KeyedSets:
- def __init__(self):
- self.d = dict()
- def add(self, key, value):
- if key not in self.d:
- self.d[key] = set()
- self.d[key].add(value)
- def discard(self, key, value):
- if key in self.d:
- self.d[key].discard(value)
- if not self.d[key]:
- del self.d[key]
- def __contains__(self, key):
- return key in self.d
- def __getitem__(self, key):
- return self.d.get(key, set())
- def pop(self, key):
- if key in self.d:
- return self.d.pop(key)
- return set()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py
deleted file mode 100644
index 21ffca58..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py
+++ /dev/null
@@ -1,311 +0,0 @@
-# Copied from croniter
-# https://github.com/taichino/croniter
-# Licensed under MIT license
-# Pyflakes warnings corrected
-
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-import re
-from time import time, mktime
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
-
-search_re = re.compile(r'^([^-]+)-([^-/]+)(/(.*))?$')
-only_int_re = re.compile(r'^\d+$')
-any_int_re = re.compile(r'^\d+')
-star_or_int_re = re.compile(r'^(\d+|\*)$')
-
-__all__ = ('croniter',)
-
-
-class croniter(object):
- RANGES = (
- (0, 59),
- (0, 23),
- (1, 31),
- (1, 12),
- (0, 6),
- (0, 59)
- )
- DAYS = (
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- )
-
- ALPHACONV = (
- { },
- { },
- { },
- { 'jan':1, 'feb':2, 'mar':3, 'apr':4, 'may':5, 'jun':6,
- 'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12 },
- { 'sun':0, 'mon':1, 'tue':2, 'wed':3, 'thu':4, 'fri':5, 'sat':0 },
- { }
- )
-
- LOWMAP = (
- {},
- {},
- {0: 1},
- {0: 1},
- {7: 0},
- {},
- )
-
- bad_length = 'Exactly 5 or 6 columns has to be specified for iterator' \
- 'expression.'
-
- def __init__(self, expr_format, start_time=time()):
- if isinstance(start_time, datetime):
- start_time = mktime(start_time.timetuple())
-
- self.cur = start_time
- self.exprs = expr_format.split()
-
- if len(self.exprs) != 5 and len(self.exprs) != 6:
- raise ValueError(self.bad_length)
-
- expanded = []
-
- for i, expr in enumerate(self.exprs):
- e_list = expr.split(',')
- res = []
-
- while len(e_list) > 0:
- e = e_list.pop()
- t = re.sub(r'^\*(/.+)$', r'%d-%d\1' % (self.RANGES[i][0],
- self.RANGES[i][1]),
- str(e))
- m = search_re.search(t)
-
- if m:
- (low, high, step) = m.group(1), m.group(2), m.group(4) or 1
-
- if not any_int_re.search(low):
- low = self.ALPHACONV[i][low.lower()]
-
- if not any_int_re.search(high):
- high = self.ALPHACONV[i][high.lower()]
-
- if (not low or not high or int(low) > int(high)
- or not only_int_re.search(str(step))):
- raise ValueError("[%s] is not acceptable" %expr_format)
-
- for j in xrange(int(low), int(high)+1):
- if j % int(step) == 0:
- e_list.append(j)
- else:
- if not star_or_int_re.search(t):
- t = self.ALPHACONV[i][t.lower()]
-
- try:
- t = int(t)
- except:
- pass
-
- if t in self.LOWMAP[i]:
- t = self.LOWMAP[i][t]
-
- if t != '*' and (int(t) < self.RANGES[i][0] or
- int(t) > self.RANGES[i][1]):
- raise ValueError("[%s] is not acceptable, out of range" % expr_format)
-
- res.append(t)
-
- res.sort()
- expanded.append(['*'] if (len(res) == 1 and res[0] == '*') else res)
- self.expanded = expanded
-
- def get_next(self, ret_type=float):
- return self._get_next(ret_type, is_prev=False)
-
- def get_prev(self, ret_type=float):
- return self._get_next(ret_type, is_prev=True)
-
- def _get_next(self, ret_type=float, is_prev=False):
- expanded = self.expanded[:]
-
- if ret_type not in (float, datetime):
- raise TypeError("Invalid ret_type, only 'float' or 'datetime' " \
- "is acceptable.")
-
- if expanded[2][0] != '*' and expanded[4][0] != '*':
- bak = expanded[4]
- expanded[4] = ['*']
- t1 = self._calc(self.cur, expanded, is_prev)
- expanded[4] = bak
- expanded[2] = ['*']
-
- t2 = self._calc(self.cur, expanded, is_prev)
- if not is_prev:
- result = t1 if t1 < t2 else t2
- else:
- result = t1 if t1 > t2 else t2
- else:
- result = self._calc(self.cur, expanded, is_prev)
- self.cur = result
-
- if ret_type == datetime:
- result = datetime.fromtimestamp(result)
- return result
-
- def _calc(self, now, expanded, is_prev):
- if is_prev:
- nearest_diff_method = self._get_prev_nearest_diff
- sign = -1
- else:
- nearest_diff_method = self._get_next_nearest_diff
- sign = 1
-
- offset = len(expanded) == 6 and 1 or 60
- dst = now = datetime.fromtimestamp(now + sign * offset)
-
- day, month, year = dst.day, dst.month, dst.year
- current_year = now.year
- DAYS = self.DAYS
-
- def proc_month(d):
- if expanded[3][0] != '*':
- diff_month = nearest_diff_method(d.month, expanded[3], 12)
- days = DAYS[month - 1]
- if month == 2 and self.is_leap(year) == True:
- days += 1
-
- reset_day = days if is_prev else 1
-
- if diff_month != None and diff_month != 0:
- if is_prev:
- d += relativedelta(months=diff_month)
- else:
- d += relativedelta(months=diff_month, day=reset_day,
- hour=0, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_day_of_month(d):
- if expanded[2][0] != '*':
- days = DAYS[month - 1]
- if month == 2 and self.is_leap(year) == True:
- days += 1
-
- diff_day = nearest_diff_method(d.day, expanded[2], days)
-
- if diff_day != None and diff_day != 0:
- if is_prev:
- d += relativedelta(days=diff_day)
- else:
- d += relativedelta(days=diff_day, hour=0, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_day_of_week(d):
- if expanded[4][0] != '*':
- diff_day_of_week = nearest_diff_method(d.isoweekday() % 7, expanded[4], 7)
- if diff_day_of_week != None and diff_day_of_week != 0:
- if is_prev:
- d += relativedelta(days=diff_day_of_week)
- else:
- d += relativedelta(days=diff_day_of_week, hour=0, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_hour(d):
- if expanded[1][0] != '*':
- diff_hour = nearest_diff_method(d.hour, expanded[1], 24)
- if diff_hour != None and diff_hour != 0:
- if is_prev:
- d += relativedelta(hours = diff_hour)
- else:
- d += relativedelta(hours = diff_hour, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_minute(d):
- if expanded[0][0] != '*':
- diff_min = nearest_diff_method(d.minute, expanded[0], 60)
- if diff_min != None and diff_min != 0:
- if is_prev:
- d += relativedelta(minutes = diff_min)
- else:
- d += relativedelta(minutes = diff_min, second=0)
- return True, d
- return False, d
-
- def proc_second(d):
- if len(expanded) == 6:
- if expanded[5][0] != '*':
- diff_sec = nearest_diff_method(d.second, expanded[5], 60)
- if diff_sec != None and diff_sec != 0:
- d += relativedelta(seconds = diff_sec)
- return True, d
- else:
- d += relativedelta(second = 0)
- return False, d
-
- if is_prev:
- procs = [proc_second,
- proc_minute,
- proc_hour,
- proc_day_of_week,
- proc_day_of_month,
- proc_month]
- else:
- procs = [proc_month,
- proc_day_of_month,
- proc_day_of_week,
- proc_hour,
- proc_minute,
- proc_second]
-
- while abs(year - current_year) <= 1:
- next = False
- for proc in procs:
- (changed, dst) = proc(dst)
- if changed:
- next = True
- break
- if next:
- continue
- return mktime(dst.timetuple())
-
- raise "failed to find prev date"
-
- def _get_next_nearest(self, x, to_check):
- small = [item for item in to_check if item < x]
- large = [item for item in to_check if item >= x]
- large.extend(small)
- return large[0]
-
- def _get_prev_nearest(self, x, to_check):
- small = [item for item in to_check if item <= x]
- large = [item for item in to_check if item > x]
- small.reverse()
- large.reverse()
- small.extend(large)
- return small[0]
-
- def _get_next_nearest_diff(self, x, to_check, range_val):
- for i, d in enumerate(to_check):
- if d >= x:
- return d - x
- return to_check[0] - x + range_val
-
- def _get_prev_nearest_diff(self, x, to_check, range_val):
- candidates = to_check[:]
- candidates.reverse()
- for d in candidates:
- if d <= x:
- return d - x
- return (candidates[0]) - x - range_val
-
- def is_leap(self, year):
- if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
- return True
- else:
- return False
-
-if __name__ == '__main__':
-
- base = datetime(2010, 1, 25)
- itr = croniter('0 0 1 * *', base)
- n1 = itr.get_next(datetime)
- print n1
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py
deleted file mode 100644
index 15fba6cf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-# copied from foolscap
-
-from twisted.internet import reactor, defer
-from twisted.python import log
-
-class _SimpleCallQueue(object):
-
- _reactor = reactor
-
- def __init__(self):
- self._events = []
- self._flushObservers = []
- self._timer = None
- self._in_turn = False
-
- def append(self, cb, args, kwargs):
- self._events.append((cb, args, kwargs))
- if not self._timer:
- self._timer = self._reactor.callLater(0, self._turn)
-
- def _turn(self):
- self._timer = None
- self._in_turn = True
- # flush all the messages that are currently in the queue. If anything
- # gets added to the queue while we're doing this, those events will
- # be put off until the next turn.
- events, self._events = self._events, []
- for cb, args, kwargs in events:
- try:
- cb(*args, **kwargs)
- except:
- log.err()
- self._in_turn = False
- if self._events and not self._timer:
- self._timer = self._reactor.callLater(0, self._turn)
- if not self._events:
- observers, self._flushObservers = self._flushObservers, []
- for o in observers:
- o.callback(None)
-
- def flush(self):
- if not self._events and not self._in_turn:
- return defer.succeed(None)
- d = defer.Deferred()
- self._flushObservers.append(d)
- return d
-
-
-_theSimpleQueue = _SimpleCallQueue()
-
-def eventually(cb, *args, **kwargs):
- _theSimpleQueue.append(cb, args, kwargs)
-
-
-def fireEventually(value=None):
- d = defer.Deferred()
- eventually(d.callback, value)
- return d
-
-def flushEventualQueue(_ignored=None):
- return _theSimpleQueue.flush()
-
-def _setReactor(r=None):
- # This sets the reactor used to schedule future events to r. If r is None
- # (the default), the reactor is reset to its default value.
- # This should only be used for unit tests.
- if r is None:
- r = reactor
- _theSimpleQueue._reactor = r
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py
deleted file mode 100644
index d7ae14b7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from weakref import WeakValueDictionary
-from itertools import ifilterfalse
-from twisted.python import log
-from twisted.internet import defer
-from collections import deque
-from collections import defaultdict
-
-
-class LRUCache(object):
- """
- A least-recently-used cache, with a fixed maximum size.
-
- See buildbot manual for more information.
- """
-
- __slots__ = ('max_size max_queue miss_fn queue cache weakrefs '
- 'refcount hits refhits misses'.split())
- sentinel = object()
- QUEUE_SIZE_FACTOR = 10
-
- def __init__(self, miss_fn, max_size=50):
- self.max_size = max_size
- self.max_queue = max_size * self.QUEUE_SIZE_FACTOR
- self.queue = deque()
- self.cache = {}
- self.weakrefs = WeakValueDictionary()
- self.hits = self.misses = self.refhits = 0
- self.refcount = defaultdict(lambda : 0)
- self.miss_fn = miss_fn
-
- def put(self, key, value):
- if key in self.cache:
- self.cache[key] = value
- self.weakrefs[key] = value
- elif key in self.weakrefs:
- self.weakrefs[key] = value
-
- def get(self, key, **miss_fn_kwargs):
- try:
- return self._get_hit(key)
- except KeyError:
- pass
-
- self.misses += 1
-
- result = self.miss_fn(key, **miss_fn_kwargs)
- if result is not None:
- self.cache[key] = result
- self.weakrefs[key] = result
- self._ref_key(key)
- self._purge()
-
- return result
-
- def keys(self):
- return self.cache.keys()
-
- def set_max_size(self, max_size):
- if self.max_size == max_size:
- return
-
- self.max_size = max_size
- self.max_queue = max_size * self.QUEUE_SIZE_FACTOR
- self._purge()
-
- def inv(self):
- global inv_failed
-
- # the keys of the queue and cache should be identical
- cache_keys = set(self.cache.keys())
- queue_keys = set(self.queue)
- if queue_keys - cache_keys:
- log.msg("INV: uncached keys in queue:", queue_keys - cache_keys)
- inv_failed = True
- if cache_keys - queue_keys:
- log.msg("INV: unqueued keys in cache:", cache_keys - queue_keys)
- inv_failed = True
-
- # refcount should always represent the number of times each key appears
- # in the queue
- exp_refcount = dict()
- for k in self.queue:
- exp_refcount[k] = exp_refcount.get(k, 0) + 1
- if exp_refcount != self.refcount:
- log.msg("INV: refcounts differ:")
- log.msg(" expected:", sorted(exp_refcount.items()))
- log.msg(" got:", sorted(self.refcount.items()))
- inv_failed = True
-
- def _ref_key(self, key):
- """Record a reference to the argument key."""
- queue = self.queue
- refcount = self.refcount
-
- queue.append(key)
- refcount[key] = refcount[key] + 1
-
- # periodically compact the queue by eliminating duplicate keys
- # while preserving order of most recent access. Note that this
- # is only required when the cache does not exceed its maximum
- # size
- if len(queue) > self.max_queue:
- refcount.clear()
- queue_appendleft = queue.appendleft
- queue_appendleft(self.sentinel)
- for k in ifilterfalse(refcount.__contains__,
- iter(queue.pop, self.sentinel)):
- queue_appendleft(k)
- refcount[k] = 1
-
- def _get_hit(self, key):
- """Try to do a value lookup from the existing cache entries."""
- try:
- result = self.cache[key]
- self.hits += 1
- self._ref_key(key)
- return result
- except KeyError:
- pass
-
- result = self.weakrefs[key]
- self.refhits += 1
- self.cache[key] = result
- self._ref_key(key)
- return result
-
- def _purge(self):
- """
- Trim the cache down to max_size by evicting the
- least-recently-used entries.
- """
- if len(self.cache) <= self.max_size:
- return
-
- cache = self.cache
- refcount = self.refcount
- queue = self.queue
- max_size = self.max_size
-
- # purge least recently used entries, using refcount to count entries
- # that appear multiple times in the queue
- while len(cache) > max_size:
- refc = 1
- while refc:
- k = queue.popleft()
- refc = refcount[k] = refcount[k] - 1
- del cache[k]
- del refcount[k]
-
-
-class AsyncLRUCache(LRUCache):
- """
- An LRU cache with asynchronous locking to ensure that in the common case of
- multiple concurrent requests for the same key, only one fetch is performed.
- """
-
- __slots__ = ['concurrent']
-
- def __init__(self, miss_fn, max_size=50):
- LRUCache.__init__(self, miss_fn, max_size=max_size)
- self.concurrent = {}
-
- def get(self, key, **miss_fn_kwargs):
- try:
- result = self._get_hit(key)
- return defer.succeed(result)
- except KeyError:
- pass
-
- concurrent = self.concurrent
- conc = concurrent.get(key)
- if conc:
- self.hits += 1
- d = defer.Deferred()
- conc.append(d)
- return d
-
- # if we're here, we've missed and need to fetch
- self.misses += 1
-
- # create a list of waiting deferreds for this key
- d = defer.Deferred()
- assert key not in concurrent
- concurrent[key] = [ d ]
-
- miss_d = self.miss_fn(key, **miss_fn_kwargs)
-
- def handle_result(result):
- if result is not None:
- self.cache[key] = result
- self.weakrefs[key] = result
-
- # reference the key once, possibly standing in for multiple
- # concurrent accesses
- self._ref_key(key)
-
- self._purge()
-
- # and fire all of the waiting Deferreds
- dlist = concurrent.pop(key)
- for d in dlist:
- d.callback(result)
-
- def handle_failure(f):
- # errback all of the waiting Deferreds
- dlist = concurrent.pop(key)
- for d in dlist:
- d.errback(f)
-
- miss_d.addCallbacks(handle_result, handle_failure)
- miss_d.addErrback(log.err)
-
- return d
-
-
-# for tests
-inv_failed = False
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py
deleted file mode 100644
index 66e895b3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-# This is a class which watches a maildir for new messages. It uses the
-# linux dirwatcher API (if available) to look for new files. The
-# .messageReceived method is invoked with the filename of the new message,
-# relative to the top of the maildir (so it will look like "new/blahblah").
-
-import os
-from twisted.python import log, runtime
-from twisted.application import service, internet
-from twisted.internet import reactor, defer
-dnotify = None
-try:
- import dnotify
-except:
- log.msg("unable to import dnotify, so Maildir will use polling instead")
-
-class NoSuchMaildir(Exception):
- pass
-
-class MaildirService(service.MultiService):
- pollinterval = 10 # only used if we don't have DNotify
-
- def __init__(self, basedir=None):
- service.MultiService.__init__(self)
- if basedir:
- self.setBasedir(basedir)
- self.files = []
- self.dnotify = None
- self.timerService = None
-
- def setBasedir(self, basedir):
- # some users of MaildirService (scheduler.Try_Jobdir, in particular)
- # don't know their basedir until setServiceParent, since it is
- # relative to the buildmaster's basedir. So let them set it late. We
- # don't actually need it until our own startService.
- self.basedir = basedir
- self.newdir = os.path.join(self.basedir, "new")
- self.curdir = os.path.join(self.basedir, "cur")
-
- def startService(self):
- service.MultiService.startService(self)
- if not os.path.isdir(self.newdir) or not os.path.isdir(self.curdir):
- raise NoSuchMaildir("invalid maildir '%s'" % self.basedir)
- try:
- if dnotify:
- # we must hold an fd open on the directory, so we can get
- # notified when it changes.
- self.dnotify = dnotify.DNotify(self.newdir,
- self.dnotify_callback,
- [dnotify.DNotify.DN_CREATE])
- except (IOError, OverflowError):
- # IOError is probably linux<2.4.19, which doesn't support
- # dnotify. OverflowError will occur on some 64-bit machines
- # because of a python bug
- log.msg("DNotify failed, falling back to polling")
- if not self.dnotify:
- self.timerService = internet.TimerService(self.pollinterval, self.poll)
- self.timerService.setServiceParent(self)
- self.poll()
-
-
- def dnotify_callback(self):
- log.msg("dnotify noticed something, now polling")
-
- # give it a moment. I found that qmail had problems when the message
- # was removed from the maildir instantly. It shouldn't, that's what
- # maildirs are made for. I wasn't able to eyeball any reason for the
- # problem, and safecat didn't behave the same way, but qmail reports
- # "Temporary_error_on_maildir_delivery" (qmail-local.c:165,
- # maildir_child() process exited with rc not in 0,2,3,4). Not sure
- # why, and I'd have to hack qmail to investigate further, so it's
- # easier to just wait a second before yanking the message out of new/
-
- reactor.callLater(0.1, self.poll)
-
-
- def stopService(self):
- if self.dnotify:
- self.dnotify.remove()
- self.dnotify = None
- if self.timerService is not None:
- self.timerService.disownServiceParent()
- self.timerService = None
- return service.MultiService.stopService(self)
-
- @defer.inlineCallbacks
- def poll(self):
- try:
- assert self.basedir
- # see what's new
- for f in self.files:
- if not os.path.isfile(os.path.join(self.newdir, f)):
- self.files.remove(f)
- newfiles = []
- for f in os.listdir(self.newdir):
- if not f in self.files:
- newfiles.append(f)
- self.files.extend(newfiles)
- for n in newfiles:
- try:
- yield self.messageReceived(n)
- except:
- log.err(None, "while reading '%s' from maildir '%s':" % (n, self.basedir))
- except Exception:
- log.err(None, "while polling maildir '%s':" % (self.basedir,))
-
- def moveToCurDir(self, filename):
- if runtime.platformType == "posix":
- # open the file before moving it, because I'm afraid that once
- # it's in cur/, someone might delete it at any moment
- path = os.path.join(self.newdir, filename)
- f = open(path, "r")
- os.rename(os.path.join(self.newdir, filename),
- os.path.join(self.curdir, filename))
- elif runtime.platformType == "win32":
- # do this backwards under windows, because you can't move a file
- # that somebody is holding open. This was causing a Permission
- # Denied error on bear's win32-twisted1.3 buildslave.
- os.rename(os.path.join(self.newdir, filename),
- os.path.join(self.curdir, filename))
- path = os.path.join(self.curdir, filename)
- f = open(path, "r")
-
- return f
-
- def messageReceived(self, filename):
- raise NotImplementedError
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py
deleted file mode 100644
index b869a5d5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-Miscellaneous utilities; these should be imported from C{buildbot.util}, not
-directly from this module.
-"""
-
-from twisted.python import log
-from twisted.internet import defer
-
-def deferredLocked(lock_or_attr):
- def decorator(fn):
- def wrapper(*args, **kwargs):
- lock = lock_or_attr
- if isinstance(lock, basestring):
- lock = getattr(args[0], lock)
- return lock.run(fn, *args, **kwargs)
- return wrapper
- return decorator
-
-class SerializedInvocation(object):
- def __init__(self, method):
- self.method = method
- self.running = False
- self.pending_deferreds = []
-
- def __call__(self):
- d = defer.Deferred()
- self.pending_deferreds.append(d)
- if not self.running:
- self.start()
- return d
-
- def start(self):
- self.running = True
- invocation_deferreds = self.pending_deferreds
- self.pending_deferreds = []
- d = self.method()
- d.addErrback(log.err, 'in invocation of %r' % (self.method,))
-
- def notify_callers(_):
- for d in invocation_deferreds:
- d.callback(None)
- d.addCallback(notify_callers)
-
- def next(_):
- self.running = False
- if self.pending_deferreds:
- self.start()
- else:
- self._quiet()
- d.addBoth(next)
-
- def _quiet(self): # hook for tests
- pass
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py
deleted file mode 100644
index 47ff0623..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.protocols import basic
-from zope.interface import implements
-from twisted.internet.interfaces import IAddress, ITransport
-
-class NullAddress(object):
- "an address for NullTransport"
- implements(IAddress)
-
-class NullTransport(object):
- "a do-nothing transport to make NetstringReceiver happy"
- implements(ITransport)
- def write(self, data): raise NotImplementedError
- def writeSequence(self, data): raise NotImplementedError
- def loseConnection(self): pass
- def getPeer(self):
- return NullAddress
- def getHost(self):
- return NullAddress
-
-class NetstringParser(basic.NetstringReceiver):
- """
- Adapts the Twisted netstring support (which assumes it is on a socket) to
- work on simple strings, too. Call the C{feed} method with arbitrary blocks
- of data, and override the C{stringReceived} method to get called for each
- embedded netstring. The default implementation collects the netstrings in
- the list C{self.strings}.
- """
-
- def __init__(self):
- # most of the complexity here is stubbing out the transport code so
- # that Twisted-10.2.0 and higher believes that this is a valid protocol
- self.makeConnection(NullTransport())
- self.strings = []
-
- def feed(self, data):
- """
- """
- self.dataReceived(data)
- # dataReceived handles errors unusually quietly!
- if self.brokenPeer:
- raise basic.NetstringParseError
-
- def stringReceived(self, string):
- self.strings.append(string)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py
deleted file mode 100644
index d05cc3da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sqlalchemy as sa
-from sqlalchemy.ext import compiler
-from sqlalchemy.sql.expression import Executable, ClauseElement
-
-# from http://www.sqlalchemy.org/docs/core/compiler.html#compiling-sub-elements-of-a-custom-expression-construct
-
-class InsertFromSelect(Executable, ClauseElement):
- def __init__(self, table, select):
- self.table = table
- self.select = select
-
-@compiler.compiles(InsertFromSelect)
-def _visit_insert_from_select(element, compiler, **kw):
- return "INSERT INTO %s %s" % (
- compiler.process(element.table, asfrom=True),
- compiler.process(element.select)
- )
-
-def sa_version():
- if hasattr(sa, '__version__'):
- def tryint(s):
- try:
- return int(s)
- except:
- return -1
- return tuple(map(tryint, sa.__version__.split('.')))
- return (0,0,0) # "it's old"
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py
deleted file mode 100644
index 509f6527..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from twisted.internet import defer
-
-class StateMixin(object):
- ## state management
-
- _objectid = None
-
- @defer.inlineCallbacks
- def getState(self, *args, **kwargs):
- # get the objectid, if not known
- if self._objectid is None:
- self._objectid = yield self.master.db.state.getObjectId(self.name,
- self.__class__.__name__)
-
- rv = yield self.master.db.state.getState(self._objectid, *args,
- **kwargs)
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def setState(self, key, value):
- # get the objectid, if not known
- if self._objectid is None:
- self._objectid = yield self.master.db.state.getObjectId(self.name,
- self.__class__.__name__)
-
- yield self.master.db.state.setState(self._objectid, key, value)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py
deleted file mode 100644
index 85ed7de4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python import failure, log
-
-class SubscriptionPoint(object):
- def __init__(self, name):
- self.name = name
- self.subscriptions = set()
-
- def __str__(self):
- return "<SubscriptionPoint '%s'>" % self.name
-
- def subscribe(self, callback):
- sub = Subscription(self, callback)
- self.subscriptions.add(sub)
- return sub
-
- def deliver(self, *args, **kwargs):
- for sub in list(self.subscriptions):
- try:
- sub.callback(*args, **kwargs)
- except:
- log.err(failure.Failure(),
- 'while invoking callback %s to %s' % (sub.callback, self))
-
- def _unsubscribe(self, subscription):
- self.subscriptions.remove(subscription)
-
-class Subscription(object):
- def __init__(self, subpt, callback):
- self.subpt = subpt
- self.callback = callback
-
- def unsubscribe(self):
- self.subpt._unsubscribe(self)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index ad3ac72d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,16 +0,0 @@
-Metadata-Version: 1.1
-Name: buildbot-slave
-Version: 0.8.8
-Summary: BuildBot Slave Daemon
-Home-page: http://buildbot.net/
-Author: Dustin J. Mitchell
-Author-email: dustin@v.igoro.us
-License: GNU GPL
-Description: See the 'buildbot' package for details
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: No Input/Output (Daemon)
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: GNU General Public License (GPL)
-Classifier: Topic :: Software Development :: Build Tools
-Classifier: Topic :: Software Development :: Testing
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 2a70b501..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-COPYING
-MANIFEST.in
-NEWS
-README
-UPGRADING
-setup.cfg
-setup.py
-bin/buildslave
-buildbot_slave.egg-info/PKG-INFO
-buildbot_slave.egg-info/SOURCES.txt
-buildbot_slave.egg-info/dependency_links.txt
-buildbot_slave.egg-info/requires.txt
-buildbot_slave.egg-info/top_level.txt
-buildslave/__init__.py
-buildslave/bot.py
-buildslave/exceptions.py
-buildslave/interfaces.py
-buildslave/pbutil.py
-buildslave/runprocess.py
-buildslave/util.py
-buildslave/commands/__init__.py
-buildslave/commands/base.py
-buildslave/commands/bk.py
-buildslave/commands/bzr.py
-buildslave/commands/cvs.py
-buildslave/commands/darcs.py
-buildslave/commands/fs.py
-buildslave/commands/git.py
-buildslave/commands/hg.py
-buildslave/commands/mtn.py
-buildslave/commands/p4.py
-buildslave/commands/registry.py
-buildslave/commands/repo.py
-buildslave/commands/shell.py
-buildslave/commands/svn.py
-buildslave/commands/transfer.py
-buildslave/commands/utils.py
-buildslave/monkeypatches/__init__.py
-buildslave/monkeypatches/bug4881.py
-buildslave/monkeypatches/bug5079.py
-buildslave/monkeypatches/testcase_assert.py
-buildslave/scripts/__init__.py
-buildslave/scripts/base.py
-buildslave/scripts/logwatcher.py
-buildslave/scripts/runner.py
-buildslave/scripts/startup.py
-buildslave/test/__init__.py
-buildslave/test/test_extra_coverage.py
-buildslave/test/fake/__init__.py
-buildslave/test/fake/remote.py
-buildslave/test/fake/runprocess.py
-buildslave/test/fake/slavebuilder.py
-buildslave/test/unit/__init__.py
-buildslave/test/unit/runprocess-scripts.py
-buildslave/test/unit/test_bot.py
-buildslave/test/unit/test_bot_BuildSlave.py
-buildslave/test/unit/test_commands_base.py
-buildslave/test/unit/test_commands_bk.py
-buildslave/test/unit/test_commands_bzr.py
-buildslave/test/unit/test_commands_cvs.py
-buildslave/test/unit/test_commands_darcs.py
-buildslave/test/unit/test_commands_fs.py
-buildslave/test/unit/test_commands_git.py
-buildslave/test/unit/test_commands_hg.py
-buildslave/test/unit/test_commands_mtn.py
-buildslave/test/unit/test_commands_p4.py
-buildslave/test/unit/test_commands_registry.py
-buildslave/test/unit/test_commands_shell.py
-buildslave/test/unit/test_commands_svn.py
-buildslave/test/unit/test_commands_transfer.py
-buildslave/test/unit/test_commands_utils.py
-buildslave/test/unit/test_runprocess.py
-buildslave/test/unit/test_scripts_base.py
-buildslave/test/unit/test_scripts_runner.py
-buildslave/test/unit/test_util.py
-buildslave/test/util/__init__.py
-buildslave/test/util/command.py
-buildslave/test/util/compat.py
-buildslave/test/util/misc.py
-buildslave/test/util/sourcecommand.py
-contrib/init-scripts/buildslave.default
-contrib/init-scripts/buildslave.init.sh
-contrib/os-x/README
-contrib/os-x/net.sourceforge.buildbot.slave.plist
-contrib/windows/buildbot_service.py
-contrib/windows/buildslave.bat
-docs/buildslave.1 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/requires.txt
deleted file mode 100644
index e1fe865a..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1 +0,0 @@
-twisted >= 8.0.0 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/scripts/buildslave b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/scripts/buildslave
deleted file mode 100644
index b189bc7e..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/scripts/buildslave
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/python
-
-from buildslave.scripts import runner
-runner.run()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 53ff275b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-buildslave
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/VERSION b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/VERSION
deleted file mode 100644
index 5c5cbb3b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.8.8 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/__init__.py
deleted file mode 100644
index 70c4b9a9..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# strategy:
-#
-# if there is a VERSION file, use its contents. otherwise, call git to
-# get a version string. if that also fails, use 'latest'.
-#
-import os
-
-version = "latest"
-
-try:
- fn = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'VERSION')
- version = open(fn).read().strip()
-
-except IOError:
- from subprocess import Popen, PIPE, STDOUT
- import re
-
- VERSION_MATCH = re.compile(r'\d+\.\d+\.\d+(\w|-)*')
-
- try:
- p = Popen(['git', 'describe', '--tags', '--always'], stdout=PIPE, stderr=STDOUT)
- out = p.communicate()[0]
-
- if (not p.returncode) and out:
- v = VERSION_MATCH.search(out)
- if v:
- version = v.group()
- except OSError:
- pass
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/bot.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/bot.py
deleted file mode 100644
index 368e547c..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/bot.py
+++ /dev/null
@@ -1,547 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os.path
-import socket
-import sys
-import signal
-
-from twisted.spread import pb
-from twisted.python import log
-from twisted.internet import error, reactor, task, defer
-from twisted.application import service, internet
-from twisted.cred import credentials
-
-import buildslave
-from buildslave.pbutil import ReconnectingPBClientFactory
-from buildslave.commands import registry, base
-from buildslave import monkeypatches
-
-class UnknownCommand(pb.Error):
- pass
-
-class SlaveBuilder(pb.Referenceable, service.Service):
-
- """This is the local representation of a single Builder: it handles a
- single kind of build (like an all-warnings build). It has a name and a
- home directory. The rest of its behavior is determined by the master.
- """
-
- stopCommandOnShutdown = True
-
- # remote is a ref to the Builder object on the master side, and is set
- # when they attach. We use it to detect when the connection to the master
- # is severed.
- remote = None
-
- # .command points to a SlaveCommand instance, and is set while the step
- # is running. We use it to implement the stopBuild method.
- command = None
-
- # .remoteStep is a ref to the master-side BuildStep object, and is set
- # when the step is started
- remoteStep = None
-
- def __init__(self, name):
- #service.Service.__init__(self) # Service has no __init__ method
- self.setName(name)
-
- def __repr__(self):
- return "<SlaveBuilder '%s' at %d>" % (self.name, id(self))
-
- def setServiceParent(self, parent):
- service.Service.setServiceParent(self, parent)
- self.bot = self.parent
- # note that self.parent will go away when the buildmaster's config
- # file changes and this Builder is removed (possibly because it has
- # been changed, so the Builder will be re-added again in a moment).
- # This may occur during a build, while a step is running.
-
- def setBuilddir(self, builddir):
- assert self.parent
- self.builddir = builddir
- self.basedir = os.path.join(self.bot.basedir, self.builddir)
- if not os.path.isdir(self.basedir):
- os.makedirs(self.basedir)
-
- def stopService(self):
- service.Service.stopService(self)
- if self.stopCommandOnShutdown:
- self.stopCommand()
-
- def activity(self):
- bot = self.parent
- if bot:
- bslave = bot.parent
- if bslave:
- bf = bslave.bf
- bf.activity()
-
- def remote_setMaster(self, remote):
- self.remote = remote
- self.remote.notifyOnDisconnect(self.lostRemote)
-
- def remote_print(self, message):
- log.msg("SlaveBuilder.remote_print(%s): message from master: %s" %
- (self.name, message))
-
- def lostRemote(self, remote):
- log.msg("lost remote")
- self.remote = None
-
- def lostRemoteStep(self, remotestep):
- log.msg("lost remote step")
- self.remoteStep = None
- if self.stopCommandOnShutdown:
- self.stopCommand()
-
- # the following are Commands that can be invoked by the master-side
- # Builder
- def remote_startBuild(self):
- """This is invoked before the first step of any new build is run. It
- doesn't do much, but masters call it so it's still here."""
- pass
-
- def remote_startCommand(self, stepref, stepId, command, args):
- """
- This gets invoked by L{buildbot.process.step.RemoteCommand.start}, as
- part of various master-side BuildSteps, to start various commands
- that actually do the build. I return nothing. Eventually I will call
- .commandComplete() to notify the master-side RemoteCommand that I'm
- done.
- """
-
- self.activity()
-
- if self.command:
- log.msg("leftover command, dropping it")
- self.stopCommand()
-
- try:
- factory = registry.getFactory(command)
- except KeyError:
- raise UnknownCommand, "unrecognized SlaveCommand '%s'" % command
- self.command = factory(self, stepId, args)
-
- log.msg(" startCommand:%s [id %s]" % (command,stepId))
- self.remoteStep = stepref
- self.remoteStep.notifyOnDisconnect(self.lostRemoteStep)
- d = self.command.doStart()
- d.addCallback(lambda res: None)
- d.addBoth(self.commandComplete)
- return None
-
- def remote_interruptCommand(self, stepId, why):
- """Halt the current step."""
- log.msg("asked to interrupt current command: %s" % why)
- self.activity()
- if not self.command:
- # TODO: just log it, a race could result in their interrupting a
- # command that wasn't actually running
- log.msg(" .. but none was running")
- return
- self.command.doInterrupt()
-
-
- def stopCommand(self):
- """Make any currently-running command die, with no further status
- output. This is used when the buildslave is shutting down or the
- connection to the master has been lost. Interrupt the command,
- silence it, and then forget about it."""
- if not self.command:
- return
- log.msg("stopCommand: halting current command %s" % self.command)
- self.command.doInterrupt() # shut up! and die!
- self.command = None # forget you!
-
- # sendUpdate is invoked by the Commands we spawn
- def sendUpdate(self, data):
- """This sends the status update to the master-side
- L{buildbot.process.step.RemoteCommand} object, giving it a sequence
- number in the process. It adds the update to a queue, and asks the
- master to acknowledge the update so it can be removed from that
- queue."""
-
- if not self.running:
- # .running comes from service.Service, and says whether the
- # service is running or not. If we aren't running, don't send any
- # status messages.
- return
- # the update[1]=0 comes from the leftover 'updateNum', which the
- # master still expects to receive. Provide it to avoid significant
- # interoperability issues between new slaves and old masters.
- if self.remoteStep:
- update = [data, 0]
- updates = [update]
- d = self.remoteStep.callRemote("update", updates)
- d.addCallback(self.ackUpdate)
- d.addErrback(self._ackFailed, "SlaveBuilder.sendUpdate")
-
- def ackUpdate(self, acknum):
- self.activity() # update the "last activity" timer
-
- def ackComplete(self, dummy):
- self.activity() # update the "last activity" timer
-
- def _ackFailed(self, why, where):
- log.msg("SlaveBuilder._ackFailed:", where)
- log.err(why) # we don't really care
-
-
- # this is fired by the Deferred attached to each Command
- def commandComplete(self, failure):
- if failure:
- log.msg("SlaveBuilder.commandFailed", self.command)
- log.err(failure)
- # failure, if present, is a failure.Failure. To send it across
- # the wire, we must turn it into a pb.CopyableFailure.
- failure = pb.CopyableFailure(failure)
- failure.unsafeTracebacks = True
- else:
- # failure is None
- log.msg("SlaveBuilder.commandComplete", self.command)
- self.command = None
- if not self.running:
- log.msg(" but we weren't running, quitting silently")
- return
- if self.remoteStep:
- self.remoteStep.dontNotifyOnDisconnect(self.lostRemoteStep)
- d = self.remoteStep.callRemote("complete", failure)
- d.addCallback(self.ackComplete)
- d.addErrback(self._ackFailed, "sendComplete")
- self.remoteStep = None
-
-
- def remote_shutdown(self):
- log.msg("slave shutting down on command from master")
- log.msg("NOTE: master is using deprecated slavebuilder.shutdown method")
- reactor.stop()
-
-
-class Bot(pb.Referenceable, service.MultiService):
- """I represent the slave-side bot."""
- usePTY = None
- name = "bot"
-
- def __init__(self, basedir, usePTY, unicode_encoding=None):
- service.MultiService.__init__(self)
- self.basedir = basedir
- self.usePTY = usePTY
- self.unicode_encoding = unicode_encoding or sys.getfilesystemencoding() or 'ascii'
- self.builders = {}
-
- def startService(self):
- assert os.path.isdir(self.basedir)
- service.MultiService.startService(self)
-
- def remote_getCommands(self):
- commands = dict([
- (n, base.command_version)
- for n in registry.getAllCommandNames()
- ])
- return commands
-
- @defer.deferredGenerator
- def remote_setBuilderList(self, wanted):
- retval = {}
- wanted_names = set([ name for (name, builddir) in wanted ])
- wanted_dirs = set([ builddir for (name, builddir) in wanted ])
- wanted_dirs.add('info')
- for (name, builddir) in wanted:
- b = self.builders.get(name, None)
- if b:
- if b.builddir != builddir:
- log.msg("changing builddir for builder %s from %s to %s" \
- % (name, b.builddir, builddir))
- b.setBuilddir(builddir)
- else:
- b = SlaveBuilder(name)
- b.usePTY = self.usePTY
- b.unicode_encoding = self.unicode_encoding
- b.setServiceParent(self)
- b.setBuilddir(builddir)
- self.builders[name] = b
- retval[name] = b
-
- # disown any builders no longer desired
- to_remove = list(set(self.builders.keys()) - wanted_names)
- dl = defer.DeferredList([
- defer.maybeDeferred(self.builders[name].disownServiceParent)
- for name in to_remove ])
- wfd = defer.waitForDeferred(dl)
- yield wfd
- wfd.getResult()
-
- # and *then* remove them from the builder list
- for name in to_remove:
- del self.builders[name]
-
- # finally warn about any leftover dirs
- for dir in os.listdir(self.basedir):
- if os.path.isdir(os.path.join(self.basedir, dir)):
- if dir not in wanted_dirs:
- log.msg("I have a leftover directory '%s' that is not "
- "being used by the buildmaster: you can delete "
- "it now" % dir)
-
- yield retval # return value
-
- def remote_print(self, message):
- log.msg("message from master:", message)
-
- def remote_getSlaveInfo(self):
- """This command retrieves data from the files in SLAVEDIR/info/* and
- sends the contents to the buildmaster. These are used to describe
- the slave and its configuration, and should be created and
- maintained by the slave administrator. They will be retrieved each
- time the master-slave connection is established.
- """
-
- files = {}
- basedir = os.path.join(self.basedir, "info")
- if os.path.isdir(basedir):
- for f in os.listdir(basedir):
- filename = os.path.join(basedir, f)
- if os.path.isfile(filename):
- files[f] = open(filename, "r").read()
- files['environ'] = os.environ.copy()
- files['system'] = os.name
- files['basedir'] = self.basedir
- return files
-
- def remote_getVersion(self):
- """Send our version back to the Master"""
- return buildslave.version
-
- def remote_shutdown(self):
- log.msg("slave shutting down on command from master")
- # there's no good way to learn that the PB response has been delivered,
- # so we'll just wait a bit, in hopes the master hears back. Masters are
- # resilinet to slaves dropping their connections, so there is no harm
- # if this timeout is too short.
- reactor.callLater(0.2, reactor.stop)
-
-class BotFactory(ReconnectingPBClientFactory):
- # 'keepaliveInterval' serves two purposes. The first is to keep the
- # connection alive: it guarantees that there will be at least some
- # traffic once every 'keepaliveInterval' seconds, which may help keep an
- # interposed NAT gateway from dropping the address mapping because it
- # thinks the connection has been abandoned. This also gives the operating
- # system a chance to notice that the master has gone away, and inform us
- # of such (although this could take several minutes).
- keepaliveInterval = None # None = do not use keepalives
-
- # 'maxDelay' determines the maximum amount of time the slave will wait
- # between connection retries
- maxDelay = 300
-
- keepaliveTimer = None
- unsafeTracebacks = 1
- perspective = None
-
- # for tests
- _reactor = reactor
-
- def __init__(self, buildmaster_host, port, keepaliveInterval, maxDelay):
- ReconnectingPBClientFactory.__init__(self)
- self.maxDelay = maxDelay
- self.keepaliveInterval = keepaliveInterval
- # NOTE: this class does not actually make the TCP connections - this information is
- # only here to print useful error messages
- self.buildmaster_host = buildmaster_host
- self.port = port
-
- def startedConnecting(self, connector):
- log.msg("Connecting to %s:%s" % (self.buildmaster_host, self.port))
- ReconnectingPBClientFactory.startedConnecting(self, connector)
- self.connector = connector
-
- def gotPerspective(self, perspective):
- log.msg("Connected to %s:%s; slave is ready" % (self.buildmaster_host, self.port))
- ReconnectingPBClientFactory.gotPerspective(self, perspective)
- self.perspective = perspective
- try:
- perspective.broker.transport.setTcpKeepAlive(1)
- except:
- log.msg("unable to set SO_KEEPALIVE")
- if not self.keepaliveInterval:
- self.keepaliveInterval = 10*60
- self.activity()
- if self.keepaliveInterval:
- log.msg("sending application-level keepalives every %d seconds" \
- % self.keepaliveInterval)
- self.startTimers()
-
- def clientConnectionFailed(self, connector, reason):
- self.connector = None
- why = reason
- if reason.check(error.ConnectionRefusedError):
- why = "Connection Refused"
- log.msg("Connection to %s:%s failed: %s" % (self.buildmaster_host, self.port, why))
- ReconnectingPBClientFactory.clientConnectionFailed(self,
- connector, reason)
-
- def clientConnectionLost(self, connector, reason):
- log.msg("Lost connection to %s:%s" % (self.buildmaster_host, self.port))
- self.connector = None
- self.stopTimers()
- self.perspective = None
- ReconnectingPBClientFactory.clientConnectionLost(self,
- connector, reason)
-
- def startTimers(self):
- assert self.keepaliveInterval
- assert not self.keepaliveTimer
-
- def doKeepalive():
- self.keepaliveTimer = None
- self.startTimers()
-
- # Send the keepalive request. If an error occurs
- # was already dropped, so just log and ignore.
- log.msg("sending app-level keepalive")
- d = self.perspective.callRemote("keepalive")
- d.addErrback(log.err, "eror sending keepalive")
- self.keepaliveTimer = self._reactor.callLater(self.keepaliveInterval,
- doKeepalive)
-
- def stopTimers(self):
- if self.keepaliveTimer:
- self.keepaliveTimer.cancel()
- self.keepaliveTimer = None
-
- def activity(self, res=None):
- """Subclass or monkey-patch this method to be alerted whenever there is
- active communication between the master and slave."""
- pass
-
- def stopFactory(self):
- ReconnectingPBClientFactory.stopFactory(self)
- self.stopTimers()
-
-
-class BuildSlave(service.MultiService):
- def __init__(self, buildmaster_host, port, name, passwd, basedir,
- keepalive, usePTY, keepaliveTimeout=None, umask=None,
- maxdelay=300, unicode_encoding=None, allow_shutdown=None):
-
- # note: keepaliveTimeout is ignored, but preserved here for
- # backward-compatibility
-
- service.MultiService.__init__(self)
- bot = Bot(basedir, usePTY, unicode_encoding=unicode_encoding)
- bot.setServiceParent(self)
- self.bot = bot
- if keepalive == 0:
- keepalive = None
- self.umask = umask
- self.basedir = basedir
-
- self.shutdown_loop = None
-
- if allow_shutdown == 'signal':
- if not hasattr(signal, 'SIGHUP'):
- raise ValueError("Can't install signal handler")
- elif allow_shutdown == 'file':
- self.shutdown_file = os.path.join(basedir, 'shutdown.stamp')
- self.shutdown_mtime = 0
-
- self.allow_shutdown = allow_shutdown
- bf = self.bf = BotFactory(buildmaster_host, port, keepalive, maxdelay)
- bf.startLogin(credentials.UsernamePassword(name, passwd), client=bot)
- self.connection = c = internet.TCPClient(buildmaster_host, port, bf)
- c.setServiceParent(self)
-
- def startService(self):
- # first, apply all monkeypatches
- monkeypatches.patch_all()
-
- log.msg("Starting BuildSlave -- version: %s" % buildslave.version)
-
- self.recordHostname(self.basedir)
- if self.umask is not None:
- os.umask(self.umask)
-
- service.MultiService.startService(self)
-
- if self.allow_shutdown == 'signal':
- log.msg("Setting up SIGHUP handler to initiate shutdown")
- signal.signal(signal.SIGHUP, self._handleSIGHUP)
- elif self.allow_shutdown == 'file':
- log.msg("Watching %s's mtime to initiate shutdown" % self.shutdown_file)
- if os.path.exists(self.shutdown_file):
- self.shutdown_mtime = os.path.getmtime(self.shutdown_file)
- self.shutdown_loop = l = task.LoopingCall(self._checkShutdownFile)
- l.start(interval=10)
-
- def stopService(self):
- self.bf.continueTrying = 0
- self.bf.stopTrying()
- if self.shutdown_loop:
- self.shutdown_loop.stop()
- self.shutdown_loop = None
- return service.MultiService.stopService(self)
-
- def recordHostname(self, basedir):
- "Record my hostname in twistd.hostname, for user convenience"
- log.msg("recording hostname in twistd.hostname")
- filename = os.path.join(basedir, "twistd.hostname")
-
- try:
- hostname = os.uname()[1] # only on unix
- except AttributeError:
- # this tends to fail on non-connected hosts, e.g., laptops
- # on planes
- hostname = socket.getfqdn()
-
- try:
- open(filename, "w").write("%s\n" % hostname)
- except:
- log.msg("failed - ignoring")
-
- def _handleSIGHUP(self, *args):
- log.msg("Initiating shutdown because we got SIGHUP")
- return self.gracefulShutdown()
-
- def _checkShutdownFile(self):
- if os.path.exists(self.shutdown_file) and \
- os.path.getmtime(self.shutdown_file) > self.shutdown_mtime:
- log.msg("Initiating shutdown because %s was touched" % self.shutdown_file)
- self.gracefulShutdown()
-
- # In case the shutdown fails, update our mtime so we don't keep
- # trying to shutdown over and over again.
- # We do want to be able to try again later if the master is
- # restarted, so we'll keep monitoring the mtime.
- self.shutdown_mtime = os.path.getmtime(self.shutdown_file)
-
- def gracefulShutdown(self):
- """Start shutting down"""
- if not self.bf.perspective:
- log.msg("No active connection, shutting down NOW")
- reactor.stop()
- return
-
- log.msg("Telling the master we want to shutdown after any running builds are finished")
- d = self.bf.perspective.callRemote("shutdown")
- def _shutdownfailed(err):
- if err.check(AttributeError):
- log.msg("Master does not support slave initiated shutdown. Upgrade master to 0.8.3 or later to use this feature.")
- else:
- log.msg('callRemote("shutdown") failed')
- log.err(err)
-
- d.addErrback(_shutdownfailed)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/base.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/base.py
deleted file mode 100644
index b18d199c..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/base.py
+++ /dev/null
@@ -1,618 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os
-from base64 import b64encode
-import sys
-import shutil
-
-from zope.interface import implements
-from twisted.internet import reactor, threads, defer
-from twisted.python import log, failure, runtime
-
-from buildslave.interfaces import ISlaveCommand
-from buildslave import runprocess
-from buildslave.exceptions import AbandonChain
-from buildslave.commands import utils
-from buildslave import util
-
-# this used to be a CVS $-style "Revision" auto-updated keyword, but since I
-# moved to Darcs as the primary repository, this is updated manually each
-# time this file is changed. The last cvs_ver that was here was 1.51 .
-command_version = "2.15"
-
-# version history:
-# >=1.17: commands are interruptable
-# >=1.28: Arch understands 'revision', added Bazaar
-# >=1.33: Source classes understand 'retry'
-# >=1.39: Source classes correctly handle changes in branch (except Git)
-# Darcs accepts 'revision' (now all do but Git) (well, and P4Sync)
-# Arch/Baz should accept 'build-config'
-# >=1.51: (release 0.7.3)
-# >= 2.1: SlaveShellCommand now accepts 'initial_stdin', 'keep_stdin_open',
-# and 'logfiles'. It now sends 'log' messages in addition to
-# stdout/stdin/header/rc. It acquired writeStdin/closeStdin methods,
-# but these are not remotely callable yet.
-# (not externally visible: ShellCommandPP has writeStdin/closeStdin.
-# ShellCommand accepts new arguments (logfiles=, initialStdin=,
-# keepStdinOpen=) and no longer accepts stdin=)
-# (release 0.7.4)
-# >= 2.2: added monotone, uploadFile, and downloadFile (release 0.7.5)
-# >= 2.3: added bzr (release 0.7.6)
-# >= 2.4: Git understands 'revision' and branches
-# >= 2.5: workaround added for remote 'hg clone --rev REV' when hg<0.9.2
-# >= 2.6: added uploadDirectory
-# >= 2.7: added usePTY option to SlaveShellCommand
-# >= 2.8: added username and password args to SVN class
-# >= 2.9: add depth arg to SVN class
-# >= 2.10: CVS can handle 'extra_options' and 'export_options'
-# >= 2.11: Arch, Bazaar, and Monotone removed
-# >= 2.12: SlaveShellCommand no longer accepts 'keep_stdin_open'
-# >= 2.13: SlaveFileUploadCommand supports option 'keepstamp'
-# >= 2.14: RemoveDirectory can delete multiple directories
-# >= 2.15: 'interruptSignal' option is added to SlaveShellCommand
-
-class Command:
- implements(ISlaveCommand)
-
- """This class defines one command that can be invoked by the build master.
- The command is executed on the slave side, and always sends back a
- completion message when it finishes. It may also send intermediate status
- as it runs (by calling builder.sendStatus). Some commands can be
- interrupted (either by the build master or a local timeout), in which
- case the step is expected to complete normally with a status message that
- indicates an error occurred.
-
- These commands are used by BuildSteps on the master side. Each kind of
- BuildStep uses a single Command. The slave must implement all the
- Commands required by the set of BuildSteps used for any given build:
- this is checked at startup time.
-
- All Commands are constructed with the same signature:
- c = CommandClass(builder, stepid, args)
- where 'builder' is the parent SlaveBuilder object, and 'args' is a
- dict that is interpreted per-command.
-
- The setup(args) method is available for setup, and is run from __init__.
-
- The Command is started with start(). This method must be implemented in a
- subclass, and it should return a Deferred. When your step is done, you
- should fire the Deferred (the results are not used). If the command is
- interrupted, it should fire the Deferred anyway.
-
- While the command runs. it may send status messages back to the
- buildmaster by calling self.sendStatus(statusdict). The statusdict is
- interpreted by the master-side BuildStep however it likes.
-
- A separate completion message is sent when the deferred fires, which
- indicates that the Command has finished, but does not carry any status
- data. If the Command needs to return an exit code of some sort, that
- should be sent as a regular status message before the deferred is fired .
- Once builder.commandComplete has been run, no more status messages may be
- sent.
-
- If interrupt() is called, the Command should attempt to shut down as
- quickly as possible. Child processes should be killed, new ones should
- not be started. The Command should send some kind of error status update,
- then complete as usual by firing the Deferred.
-
- .interrupted should be set by interrupt(), and can be tested to avoid
- sending multiple error status messages.
-
- If .running is False, the bot is shutting down (or has otherwise lost the
- connection to the master), and should not send any status messages. This
- is checked in Command.sendStatus .
-
- """
-
- # builder methods:
- # sendStatus(dict) (zero or more)
- # commandComplete() or commandInterrupted() (one, at end)
-
- debug = False
- interrupted = False
- running = False # set by Builder, cleared on shutdown or when the
- # Deferred fires
-
- _reactor = reactor
-
- def __init__(self, builder, stepId, args):
- self.builder = builder
- self.stepId = stepId # just for logging
- self.args = args
- self.startTime = None
- self.setup(args)
-
- def setup(self, args):
- """Override this in a subclass to extract items from the args dict."""
- pass
-
- def doStart(self):
- self.running = True
- self.startTime = util.now(self._reactor)
- d = defer.maybeDeferred(self.start)
- def commandComplete(res):
- self.sendStatus({"elapsed": util.now(self._reactor) - self.startTime})
- self.running = False
- return res
- d.addBoth(commandComplete)
- return d
-
- def start(self):
- """Start the command. This method should return a Deferred that will
- fire when the command has completed. The Deferred's argument will be
- ignored.
-
- This method should be overridden by subclasses."""
- raise NotImplementedError, "You must implement this in a subclass"
-
- def sendStatus(self, status):
- """Send a status update to the master."""
- if self.debug:
- log.msg("sendStatus", status)
- if not self.running:
- log.msg("would sendStatus but not .running")
- return
- self.builder.sendUpdate(status)
-
- def doInterrupt(self):
- self.running = False
- self.interrupt()
-
- def interrupt(self):
- """Override this in a subclass to allow commands to be interrupted.
- May be called multiple times, test and set self.interrupted=True if
- this matters."""
- pass
-
- # utility methods, mostly used by SlaveShellCommand and the like
-
- def _abandonOnFailure(self, rc):
- if type(rc) is not int:
- log.msg("weird, _abandonOnFailure was given rc=%s (%s)" % \
- (rc, type(rc)))
- assert isinstance(rc, int)
- if rc != 0:
- raise AbandonChain(rc)
- return rc
-
- def _sendRC(self, res):
- self.sendStatus({'rc': 0})
-
- def _checkAbandoned(self, why):
- log.msg("_checkAbandoned", why)
- why.trap(AbandonChain)
- log.msg(" abandoning chain", why.value)
- self.sendStatus({'rc': why.value.args[0]})
- return None
-
-class SourceBaseCommand(Command):
- """Abstract base class for Version Control System operations (checkout
- and update). This class extracts the following arguments from the
- dictionary received from the master:
-
- - ['workdir']: (required) the subdirectory where the buildable sources
- should be placed
-
- - ['mode']: one of update/copy/clobber/export, defaults to 'update'
-
- - ['revision']: (required) If not None, this is an int or string which indicates
- which sources (along a time-like axis) should be used.
- It is the thing you provide as the CVS -r or -D
- argument.
-
- - ['patch']: If not None, this is a tuple of (striplevel, patch)
- which contains a patch that should be applied after the
- checkout has occurred. Once applied, the tree is no
- longer eligible for use with mode='update', and it only
- makes sense to use this in conjunction with a
- ['revision'] argument. striplevel is an int, and patch
- is a string in standard unified diff format. The patch
- will be applied with 'patch -p%d <PATCH', with
- STRIPLEVEL substituted as %d. The command will fail if
- the patch process fails (rejected hunks).
-
- - ['timeout']: seconds of silence tolerated before we kill off the
- command
-
- - ['maxTime']: seconds before we kill off the command
-
- - ['retry']: If not None, this is a tuple of (delay, repeats)
- which means that any failed VC updates should be
- reattempted, up to REPEATS times, after a delay of
- DELAY seconds. This is intended to deal with slaves
- that experience transient network failures.
- """
-
- sourcedata = ""
-
- def setup(self, args):
- # if we need to parse the output, use this environment. Otherwise
- # command output will be in whatever the buildslave's native language
- # has been set to.
- self.env = os.environ.copy()
- self.env['LC_MESSAGES'] = "C"
- self.checkoutdir = args['srcdir']
- self.workdir = args['workdir']
- self.mode = args.get('mode', "update")
- self.revision = args.get('revision')
- self.patch = args.get('patch')
- self.timeout = args.get('timeout', 120)
- self.maxTime = args.get('maxTime', None)
- self.retry = args.get('retry')
- self.logEnviron = args.get('logEnviron',True)
- self._commandPaths = {}
- # VC-specific subclasses should override this to extract more args.
- # Make sure to upcall!
-
- def getCommand(self, name):
- """Wrapper around utils.getCommand that will output a resonable
- error message and raise AbandonChain if the command cannot be
- found"""
- if name not in self._commandPaths:
- try:
- self._commandPaths[name] = utils.getCommand(name)
- except RuntimeError:
- self.sendStatus({'stderr' : "could not find '%s'\n" % name})
- self.sendStatus({'stderr' : "PATH is '%s'\n" % os.environ.get('PATH', '')})
- raise AbandonChain(-1)
- return self._commandPaths[name]
-
- def start(self):
- self.sendStatus({'header': "starting " + self.header + "\n"})
- self.command = None
-
- # self.srcdir is where the VC system should put the sources
- if self.mode == "copy":
- self.srcdir = "source" # hardwired directory name, sorry
- else:
- self.srcdir = self.workdir
-
- self.sourcedatafile = os.path.join(self.builder.basedir,
- ".buildbot-sourcedata-" + b64encode(self.srcdir))
-
- # upgrade older versions to the new sourcedata location
- old_sd_path = os.path.join(self.builder.basedir, self.srcdir, ".buildbot-sourcedata")
- if os.path.exists(old_sd_path) and not os.path.exists(self.sourcedatafile):
- os.rename(old_sd_path, self.sourcedatafile)
-
- # also upgrade versions that didn't include the encoded version of the
- # source directory
- old_sd_path = os.path.join(self.builder.basedir, ".buildbot-sourcedata")
- if os.path.exists(old_sd_path) and not os.path.exists(self.sourcedatafile):
- os.rename(old_sd_path, self.sourcedatafile)
-
- d = defer.succeed(None)
- self.maybeClobber(d)
- if not (self.sourcedirIsUpdateable() and self.sourcedataMatches()):
- # the directory cannot be updated, so we have to clobber it.
- # Perhaps the master just changed modes from 'export' to
- # 'update'.
- d.addCallback(self.doClobber, self.srcdir)
-
- d.addCallback(self.doVC)
-
- if self.mode == "copy":
- d.addCallback(self.doCopy)
- if self.mode == "movecopy":
- d.addCallback(self.doCopy)
- if self.patch:
- d.addCallback(self.doPatch)
- d.addCallbacks(self._sendRC, self._checkAbandoned)
- return d
-
- def maybeClobber(self, d):
- # do we need to clobber anything?
- if self.mode in ("copy", "clobber", "export"):
- d.addCallback(self.doClobber, self.workdir)
-
- def interrupt(self):
- self.interrupted = True
- if self.command:
- self.command.kill("command interrupted")
-
- def doVC(self, res):
- if self.interrupted:
- raise AbandonChain(1)
- if self.sourcedirIsUpdateable() and self.sourcedataMatches():
- d = self.doVCUpdate()
- d.addBoth(self.maybeDoVCFallback)
- else:
- d = self.doVCFull()
- d.addBoth(self.maybeDoVCRetry)
- d.addCallback(self._abandonOnFailure)
- d.addCallback(self._handleGotRevision)
- d.addCallback(self.writeSourcedata)
- return d
-
- def sourcedataMatches(self):
- try:
- olddata = self.readSourcedata()
- if olddata != self.sourcedata:
- return False
- except IOError:
- return False
- return True
-
- def sourcedirIsPatched(self):
- return os.path.exists(os.path.join(self.builder.basedir,
- self.workdir,
- ".buildbot-patched"))
-
- def _handleGotRevision(self, res):
- d = defer.maybeDeferred(self.parseGotRevision)
- d.addCallback(lambda got_revision:
- self.sendStatus({'got_revision': got_revision}))
- return d
-
- def parseGotRevision(self):
- """Override this in a subclass. It should return a string that
- represents which revision was actually checked out, or a Deferred
- that will fire with such a string. If, in a future build, you were to
- pass this 'got_revision' string in as the 'revision' component of a
- SourceStamp, you should wind up with the same source code as this
- checkout just obtained.
-
- It is probably most useful to scan self.command.stdout for a string
- of some sort. Be sure to set keepStdout=True on the VC command that
- you run, so that you'll have something available to look at.
-
- If this information is unavailable, just return None."""
-
- return None
-
- def readSourcedata(self):
- """
- Read the sourcedata file and return its contents
-
- @returns: source data
- @raises: IOError if the file does not exist
- """
- return open(self.sourcedatafile, "r").read()
-
- def writeSourcedata(self, res):
- open(self.sourcedatafile, "w").write(self.sourcedata)
- return res
-
- def sourcedirIsUpdateable(self):
- """Returns True if the tree can be updated."""
- raise NotImplementedError("this must be implemented in a subclass")
-
- def doVCUpdate(self):
- """Returns a deferred with the steps to update a checkout."""
- raise NotImplementedError("this must be implemented in a subclass")
-
- def doVCFull(self):
- """Returns a deferred with the steps to do a fresh checkout."""
- raise NotImplementedError("this must be implemented in a subclass")
-
- def maybeDoVCFallback(self, rc):
- if type(rc) is int and rc == 0:
- return rc
- if self.interrupted:
- raise AbandonChain(1)
-
- # allow AssertionErrors to fall through, for benefit of the tests; for
- # all other errors, carry on to try the fallback
- if isinstance(rc, failure.Failure) and rc.check(AssertionError):
- return rc
-
- # Let VCS subclasses have an opportunity to handle
- # unrecoverable errors without having to clobber the repo
- self.maybeNotDoVCFallback(rc)
- msg = "update failed, clobbering and trying again"
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
- d = self.doClobber(None, self.srcdir)
- d.addCallback(self.doVCFallback2)
- return d
-
- def doVCFallback2(self, res):
- msg = "now retrying VC operation"
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
- d = self.doVCFull()
- d.addBoth(self.maybeDoVCRetry)
- d.addCallback(self._abandonOnFailure)
- return d
-
- def maybeNotDoVCFallback(self, rc):
- """Override this in a subclass if you want to detect unrecoverable
- checkout errors where clobbering the repo wouldn't help, and stop
- the current VC chain before it clobbers the repo for future builds.
-
- Use 'raise AbandonChain' to pass up a halt if you do detect such."""
- pass
-
- def maybeDoVCRetry(self, res):
- """We get here somewhere after a VC chain has finished. res could
- be::
-
- - 0: the operation was successful
- - nonzero: the operation failed. retry if possible
- - AbandonChain: the operation failed, someone else noticed. retry.
- - Failure: some other exception, re-raise
- """
-
- if isinstance(res, failure.Failure):
- if self.interrupted:
- return res # don't re-try interrupted builds
- res.trap(AbandonChain)
- else:
- if type(res) is int and res == 0:
- return res
- if self.interrupted:
- raise AbandonChain(1)
- # if we get here, we should retry, if possible
- if self.retry:
- delay, repeats = self.retry
- if repeats >= 0:
- self.retry = (delay, repeats-1)
- msg = ("update failed, trying %d more times after %d seconds"
- % (repeats, delay))
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
- d = defer.Deferred()
- # we are going to do a full checkout, so a clobber is
- # required first
- self.doClobber(d, self.workdir)
- if self.srcdir:
- self.doClobber(d, self.srcdir)
- d.addCallback(lambda res: self.doVCFull())
- d.addBoth(self.maybeDoVCRetry)
- self._reactor.callLater(delay, d.callback, None)
- return d
- return res
-
- def doClobber(self, dummy, dirname, chmodDone=False):
- d = os.path.join(self.builder.basedir, dirname)
- if runtime.platformType != "posix":
- d = threads.deferToThread(utils.rmdirRecursive, d)
- def cb(_):
- return 0 # rc=0
- def eb(f):
- self.sendStatus({'header' : 'exception from rmdirRecursive\n' + f.getTraceback()})
- return -1 # rc=-1
- d.addCallbacks(cb, eb)
- return d
- command = ["rm", "-rf", d]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=0, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
-
- self.command = c
- # sendRC=0 means the rm command will send stdout/stderr to the
- # master, but not the rc=0 when it finishes. That job is left to
- # _sendRC
- d = c.start()
- # The rm -rf may fail if there is a left-over subdir with chmod 000
- # permissions. So if we get a failure, we attempt to chmod suitable
- # permissions and re-try the rm -rf.
- if chmodDone:
- d.addCallback(self._abandonOnFailure)
- else:
- d.addCallback(lambda rc: self.doClobberTryChmodIfFail(rc, dirname))
- return d
-
- def doClobberTryChmodIfFail(self, rc, dirname):
- assert isinstance(rc, int)
- if rc == 0:
- return defer.succeed(0)
- # Attempt a recursive chmod and re-try the rm -rf after.
-
- command = ["chmod", "-Rf", "u+rwx", os.path.join(self.builder.basedir, dirname)]
- if sys.platform.startswith('freebsd'):
- # Work around a broken 'chmod -R' on FreeBSD (it tries to recurse into a
- # directory for which it doesn't have permission, before changing that
- # permission) by running 'find' instead
- command = ["find", os.path.join(self.builder.basedir, dirname),
- '-exec', 'chmod', 'u+rwx', '{}', ';' ]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=0, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
-
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- d.addCallback(lambda dummy: self.doClobber(dummy, dirname, True))
- return d
-
- def doCopy(self, res):
- # now copy tree to workdir
- fromdir = os.path.join(self.builder.basedir, self.srcdir)
- todir = os.path.join(self.builder.basedir, self.workdir)
- if runtime.platformType != "posix":
- d = threads.deferToThread(shutil.copytree, fromdir, todir)
- def cb(_):
- return 0 # rc=0
- def eb(f):
- self.sendStatus({'header' : 'exception from copytree\n' + f.getTraceback()})
- return -1 # rc=-1
- d.addCallbacks(cb, eb)
- return d
-
- if not os.path.exists(os.path.dirname(todir)):
- os.makedirs(os.path.dirname(todir))
- if os.path.exists(todir):
- # I don't think this happens, but just in case..
- log.msg("cp target '%s' already exists -- cp will not do what you think!" % todir)
-
- command = ['cp', '-R', '-P', '-p', fromdir, todir]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=False, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- return d
-
- def doPatch(self, res):
- patchlevel = self.patch[0]
- diff = self.patch[1]
- root = None
- if len(self.patch) >= 3:
- root = self.patch[2]
- command = [
- utils.getCommand("patch"),
- '-p%d' % patchlevel,
- '--remove-empty-files',
- '--force',
- '--forward',
- '-i', '.buildbot-diff',
- ]
- dir = os.path.join(self.builder.basedir, self.workdir)
- # Mark the directory so we don't try to update it later, or at least try
- # to revert first.
- open(os.path.join(dir, ".buildbot-patched"), "w").write("patched\n")
-
- # write the diff to a file, for reading later
- open(os.path.join(dir, ".buildbot-diff"), "w").write(diff)
-
- # Update 'dir' with the 'root' option. Make sure it is a subdirectory
- # of dir.
- if (root and
- os.path.abspath(os.path.join(dir, root)
- ).startswith(os.path.abspath(dir))):
- dir = os.path.join(dir, root)
-
- # now apply the patch
- c = runprocess.RunProcess(self.builder, command, dir,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- d = c.start()
-
- # clean up the temp file
- def cleanup(x):
- try:
- os.unlink(os.path.join(dir, ".buildbot-diff"))
- except:
- pass
- return x
- d.addBoth(cleanup)
-
- d.addCallback(self._abandonOnFailure)
- return d
-
- def setFileContents(self, filename, contents):
- """Put the given C{contents} in C{filename}; this is a bit more
- succinct than opening, writing, and closing, and has the advantage of
- being patchable in tests. Note that the enclosing directory is
- not automatically created, nor is this an "atomic" overwrite."""
- f = open(filename, 'w')
- f.write(contents)
- f.close()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bk.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bk.py
deleted file mode 100644
index a8e5002e..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bk.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.python import log
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-
-
-class BK(SourceBaseCommand):
- """BitKeeper-specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['bkurl'] (required): the BK repository string
- """
-
- header = "bk operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.bkurl = args['bkurl']
- self.sourcedata = '"%s\n"' % self.bkurl
-
- self.bk_args = []
- if args.get('extra_args', None) is not None:
- self.bk_args.extend(args['extra_args'])
-
- def sourcedirIsUpdateable(self):
- if os.path.exists(os.path.join(self.builder.basedir,
- self.srcdir, ".buildbot-patched")):
- return False
- return os.path.isfile(os.path.join(self.builder.basedir,
- self.srcdir, "BK/parent"))
-
- def doVCUpdate(self):
- bk = self.getCommand('bk')
- # XXX revision is never used!! - bug #1715
- # revision = self.args['revision'] or 'HEAD'
- # update: possible for mode in ('copy', 'update')
- d = os.path.join(self.builder.basedir, self.srcdir)
-
- # Revision is ignored since the BK free client doesn't support it.
- command = [bk, 'pull']
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- keepStdout=True, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
-
- def doVCFull(self):
- bk = self.getCommand('bk')
-
- revision_arg = ''
- if self.args['revision']:
- revision_arg = "-r%s" % self.args['revision']
-
- d = self.builder.basedir
-
- command = [bk, 'clone', revision_arg] + self.bk_args + \
- [self.bkurl, self.srcdir]
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- logEnviron=self.logEnviron, usePTY=False)
- self.command = c
- return c.start()
-
- def getBKVersionCommand(self):
- """
- Get the (shell) command used to determine BK revision number
- of checked-out code
-
- return: list of strings, passable as the command argument to RunProcess
- """
- bk = self.getCommand('bk')
- return [bk, "changes", "-r+", "-d:REV:"]
-
- def parseGotRevision(self):
- c = runprocess.RunProcess(self.builder,
- self.getBKVersionCommand(),
- os.path.join(self.builder.basedir, self.srcdir),
- environ=self.env, timeout=self.timeout,
- sendStdout=False, sendStderr=False, sendRC=False,
- keepStdout=True, logEnviron=self.logEnviron,
- usePTY=False)
- d = c.start()
- def _parse(res):
- r_raw = c.stdout.strip()
- try:
- r = r_raw
- except:
- msg = ("BK.parseGotRevision unable to parse output: (%s)" % r_raw)
- log.msg(msg)
- self.sendStatus({'header': msg + "\n"})
- raise ValueError(msg)
- return r
- d.addCallback(_parse)
- return d
-
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bzr.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bzr.py
deleted file mode 100644
index d64265e7..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/bzr.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-
-
-class Bzr(SourceBaseCommand):
- """bzr-specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['repourl'] (required): the Bzr repository string
- ['forceSharedRepo']: force this to a shared repo
- """
-
- header = "bzr operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.repourl = args['repourl']
- self.sourcedata = "%s\n" % self.repourl
- self.revision = self.args.get('revision')
- self.forceSharedRepo = args.get('forceSharedRepo')
-
- def sourcedirIsUpdateable(self):
- # checking out a specific revision requires a full 'bzr checkout'
- return (not self.revision and
- not self.sourcedirIsPatched() and
- os.path.isdir(os.path.join(self.builder.basedir,
- self.srcdir, ".bzr")))
-
- def start(self):
- def cont(res):
- # Continue with start() method in superclass.
- return SourceBaseCommand.start(self)
-
- if self.forceSharedRepo:
- d = self.doForceSharedRepo();
- d.addCallback(cont)
- return d
- else:
- return cont(None)
-
- def doVCUpdate(self):
- bzr = self.getCommand('bzr')
- assert not self.revision
- # update: possible for mode in ('copy', 'update')
- srcdir = os.path.join(self.builder.basedir, self.srcdir)
- command = [bzr, 'update']
- c = runprocess.RunProcess(self.builder, command, srcdir,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
-
- def doVCFull(self):
- bzr = self.getCommand('bzr')
-
- # checkout or export
- d = self.builder.basedir
- if self.mode == "export":
- # exporting in bzr requires a separate directory
- return self.doVCExport()
- # originally I added --lightweight here, but then 'bzr revno' is
- # wrong. The revno reported in 'bzr version-info' is correct,
- # however. Maybe this is a bzr bug?
- #
- # In addition, you cannot perform a 'bzr update' on a repo pulled
- # from an HTTP repository that used 'bzr checkout --lightweight'. You
- # get a "ERROR: Cannot lock: transport is read only" when you try.
- #
- # So I won't bother using --lightweight for now.
-
- command = [bzr, 'checkout']
- if self.revision:
- command.append('--revision')
- command.append(str(self.revision))
- command.append(self.repourl)
- command.append(self.srcdir)
-
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- d = c.start()
- return d
-
- def doVCExport(self):
- bzr = self.getCommand('bzr')
- tmpdir = os.path.join(self.builder.basedir, "export-temp")
- srcdir = os.path.join(self.builder.basedir, self.srcdir)
- command = [bzr, 'checkout', '--lightweight']
- if self.revision:
- command.append('--revision')
- command.append(str(self.revision))
- command.append(self.repourl)
- command.append(tmpdir)
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- d = c.start()
- def _export(res):
- command = [bzr, 'export', srcdir]
- c = runprocess.RunProcess(self.builder, command, tmpdir,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
- d.addCallback(_export)
- return d
-
- def doForceSharedRepo(self):
- bzr = self.getCommand('bzr')
-
- # Don't send stderr. When there is no shared repo, this might confuse
- # users, as they will see a bzr error message. But having no shared
- # repo is not an error, just an indication that we need to make one.
- c = runprocess.RunProcess(self.builder, [bzr, 'info', '.'],
- self.builder.basedir,
- sendStderr=False, sendRC=False,
- logEnviron=self.logEnviron,usePTY=False)
- d = c.start()
- def afterCheckSharedRepo(res):
- if type(res) is int and res != 0:
- log.msg("No shared repo found, creating it")
- # bzr info fails, try to create shared repo.
- c = runprocess.RunProcess(self.builder, [bzr, 'init-repo', '.'],
- self.builder.basedir,
- sendRC=False, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
- else:
- return defer.succeed(res)
- d.addCallback(afterCheckSharedRepo)
- return d
-
- def get_revision_number(self, out):
- # it feels like 'bzr revno' sometimes gives different results than
- # the 'revno:' line from 'bzr version-info', and the one from
- # version-info is more likely to be correct.
- for line in out.split("\n"):
- colon = line.find(":")
- if colon != -1:
- key, value = line[:colon], line[colon+2:]
- if key == "revno":
- return int(value)
- raise ValueError("unable to find revno: in bzr output: '%s'" % out)
-
- def parseGotRevision(self):
- bzr = self.getCommand('bzr')
- command = [bzr, "version-info"]
- c = runprocess.RunProcess(self.builder, command,
- os.path.join(self.builder.basedir, self.srcdir),
- environ=self.env,
- sendStdout=False, sendStderr=False, sendRC=False,
- keepStdout=True, logEnviron=self.logEnviron,
- usePTY=False)
- d = c.start()
- def _parse(res):
- try:
- return self.get_revision_number(c.stdout)
- except ValueError:
- msg =("Bzr.parseGotRevision unable to parse output "
- "of bzr version-info: '%s'" % c.stdout.strip())
- log.msg(msg)
- self.sendStatus({'header': msg + "\n"})
- return None
- d.addCallback(_parse)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/cvs.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/cvs.py
deleted file mode 100644
index b5939061..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/cvs.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import time
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-
-class CVS(SourceBaseCommand):
- """CVS-specific VC operation. In addition to the arguments handled by
- SourceBaseCommand, this command reads the following keys:
-
- ['cvsroot'] (required): the CVSROOT repository string
- ['cvsmodule'] (required): the module to be retrieved
- ['branch']: a '-r' tag or branch name to use for the checkout/update
- ['login']: a string for use as a password to 'cvs login'
- ['global_options']: a list of strings to use before the CVS verb
- ['checkout_options']: a list of strings to use after checkout,
- but before revision and branch specifiers
- ['checkout_options']: a list of strings to use after export,
- but before revision and branch specifiers
- ['extra_options']: a list of strings to use after export and checkout,
- but before revision and branch specifiers
- """
-
- header = "cvs operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.cvsroot = args['cvsroot']
- self.cvsmodule = args['cvsmodule']
- self.global_options = args.get('global_options', [])
- self.checkout_options = args.get('checkout_options', [])
- self.export_options = args.get('export_options', [])
- self.extra_options = args.get('extra_options', [])
- self.branch = args.get('branch')
- self.login = args.get('login')
- self.sourcedata = "%s\n%s\n%s\n" % (self.cvsroot, self.cvsmodule,
- self.branch)
-
- def sourcedirIsUpdateable(self):
- return (not self.sourcedirIsPatched() and
- os.path.isdir(os.path.join(self.builder.basedir,
- self.srcdir, "CVS")))
-
- def start(self):
- cvs = self.getCommand("cvs")
- if self.login is not None:
- # need to do a 'cvs login' command first
- d = self.builder.basedir
- command = ([cvs, '-d', self.cvsroot] + self.global_options
- + ['login'])
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime,
- initialStdin=self.login+"\n",
- logEnviron=self.logEnviron,usePTY=False)
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- d.addCallback(self._didLogin)
- return d
- else:
- return self._didLogin(None)
-
- def _didLogin(self, res):
- # now we really start
- return SourceBaseCommand.start(self)
-
- def doVCUpdate(self):
- cvs = self.getCommand("cvs")
- d = os.path.join(self.builder.basedir, self.srcdir)
- command = [cvs, '-z3'] + self.global_options + ['update', '-dP']
- if self.branch:
- command += ['-r', self.branch]
- if self.revision:
- command += ['-D', self.revision]
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
-
- def doVCFull(self):
- cvs = self.getCommand("cvs")
- d = self.builder.basedir
- if self.mode == "export":
- verb = "export"
- else:
- verb = "checkout"
- command = ([cvs, '-d', self.cvsroot, '-z3'] +
- self.global_options +
- [verb, '-d', self.srcdir])
-
- if verb == "checkout":
- command += self.checkout_options
- else:
- command += self.export_options
- command += self.extra_options
-
- if self.branch:
- command += ['-r', self.branch]
- if self.revision:
- command += ['-D', self.revision]
- command += [self.cvsmodule]
-
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
-
- def parseGotRevision(self):
- # CVS does not have any kind of revision stamp to speak of. We return
- # the current timestamp as a best-effort guess, but this depends upon
- # the local system having a clock that is
- # reasonably-well-synchronized with the repository.
- return time.strftime("%Y-%m-%d %H:%M:%S +0000", time.gmtime())
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/darcs.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/darcs.py
deleted file mode 100644
index be1a9c6d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/darcs.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-
-
-class Darcs(SourceBaseCommand):
- """Darcs-specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['repourl'] (required): the Darcs repository string
- """
-
- header = "darcs operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.repourl = args['repourl']
- self.sourcedata = "%s\n" % self.repourl
- self.revision = self.args.get('revision')
-
- def sourcedirIsUpdateable(self):
- # checking out a specific revision requires a full 'darcs get'
- return (not self.revision and
- not self.sourcedirIsPatched() and
- os.path.isdir(os.path.join(self.builder.basedir,
- self.srcdir, "_darcs")))
-
- def doVCUpdate(self):
- darcs = self.getCommand('darcs')
- assert not self.revision
- # update: possible for mode in ('copy', 'update')
- d = os.path.join(self.builder.basedir, self.srcdir)
- command = [darcs, 'pull', '--all', '--verbose']
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- return c.start()
-
- def doVCFull(self):
- darcs = self.getCommand('darcs')
- # checkout or export
- d = self.builder.basedir
- command = [darcs, 'get', '--verbose', '--lazy',
- '--repo-name', self.srcdir]
- if self.revision:
- # write the context to a file
- n = os.path.join(self.builder.basedir, ".darcs-context")
- f = open(n, "wb")
- f.write(self.revision)
- f.close()
- # tell Darcs to use that context
- command.append('--context')
- command.append(n)
- command.append(self.repourl)
-
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- d = c.start()
- if self.revision:
- d.addCallback(self.removeContextFile, n)
- return d
-
- def removeContextFile(self, res, n):
- os.unlink(n)
- return res
-
- def parseGotRevision(self):
- darcs = self.getCommand('darcs')
-
- # we use 'darcs context' to find out what we wound up with
- command = [darcs, "changes", "--context"]
- c = runprocess.RunProcess(self.builder, command,
- os.path.join(self.builder.basedir, self.srcdir),
- environ=self.env, timeout=self.timeout,
- sendStdout=False, sendStderr=False, sendRC=False,
- keepStdout=True, logEnviron=self.logEnviron,
- usePTY=False)
- d = c.start()
- d.addCallback(lambda res: c.stdout)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/fs.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/fs.py
deleted file mode 100644
index ae720cdf..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/fs.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import sys
-import shutil
-
-from twisted.internet import threads, defer
-from twisted.python import runtime, log
-
-from buildslave import runprocess
-from buildslave.commands import base, utils
-
-class MakeDirectory(base.Command):
-
- header = "mkdir"
-
- def start(self):
- args = self.args
- # args['dir'] is relative to Builder directory, and is required.
- assert args['dir'] is not None
- dirname = os.path.join(self.builder.basedir, args['dir'])
-
- try:
- if not os.path.isdir(dirname):
- os.makedirs(dirname)
- self.sendStatus({'rc': 0})
- except:
- self.sendStatus({'rc': 1})
-
-class RemoveDirectory(base.Command):
-
- header = "rmdir"
-
- def setup(self,args):
- self.logEnviron = args.get('logEnviron',True)
-
-
- @defer.deferredGenerator
- def start(self):
- args = self.args
- # args['dir'] is relative to Builder directory, and is required.
- assert args['dir'] is not None
- dirnames = args['dir']
-
- self.timeout = args.get('timeout', 120)
- self.maxTime = args.get('maxTime', None)
- self.rc = 0
- if type(dirnames) is list:
- assert len(dirnames) != 0
- for dirname in dirnames:
- wfd = defer.waitForDeferred(self.removeSingleDir(dirname))
- yield wfd
- res = wfd.getResult()
- # Even if single removal of single file/dir consider it as
- # failure of whole command, but continue removing other files
- # Send 'rc' to master to handle failure cases
- if res != 0:
- self.rc = res
- else:
- wfd = defer.waitForDeferred(self.removeSingleDir(dirnames))
- yield wfd
- self.rc = wfd.getResult()
-
- self.sendStatus({'rc': self.rc})
-
- def removeSingleDir(self, dirname):
- self.dir = os.path.join(self.builder.basedir, dirname)
- if runtime.platformType != "posix":
- d = threads.deferToThread(utils.rmdirRecursive, self.dir)
- def cb(_):
- return 0 # rc=0
- def eb(f):
- self.sendStatus({'header' : 'exception from rmdirRecursive\n' + f.getTraceback()})
- return -1 # rc=-1
- d.addCallbacks(cb, eb)
- else:
- d = self._clobber(None)
-
- return d
-
- def _clobber(self, dummy, chmodDone = False):
- command = ["rm", "-rf", self.dir]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=0, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
-
- self.command = c
- # sendRC=0 means the rm command will send stdout/stderr to the
- # master, but not the rc=0 when it finishes. That job is left to
- # _sendRC
- d = c.start()
- # The rm -rf may fail if there is a left-over subdir with chmod 000
- # permissions. So if we get a failure, we attempt to chmod suitable
- # permissions and re-try the rm -rf.
- if not chmodDone:
- d.addCallback(self._tryChmod)
- return d
-
- def _tryChmod(self, rc):
- assert isinstance(rc, int)
- if rc == 0:
- return defer.succeed(0)
- # Attempt a recursive chmod and re-try the rm -rf after.
-
- command = ["chmod", "-Rf", "u+rwx", os.path.join(self.builder.basedir, self.dir)]
- if sys.platform.startswith('freebsd'):
- # Work around a broken 'chmod -R' on FreeBSD (it tries to recurse into a
- # directory for which it doesn't have permission, before changing that
- # permission) by running 'find' instead
- command = ["find", os.path.join(self.builder.basedir, self.dir),
- '-exec', 'chmod', 'u+rwx', '{}', ';' ]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=0, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
-
- self.command = c
- d = c.start()
- d.addCallback(lambda dummy: self._clobber(dummy, True))
- return d
-
-class CopyDirectory(base.Command):
-
- header = "cpdir"
-
- def setup(self,args):
- self.logEnviron = args.get('logEnviron',True)
-
- def start(self):
- args = self.args
- # args['todir'] is relative to Builder directory, and is required.
- # args['fromdir'] is relative to Builder directory, and is required.
- assert args['todir'] is not None
- assert args['fromdir'] is not None
-
- fromdir = os.path.join(self.builder.basedir, args['fromdir'])
- todir = os.path.join(self.builder.basedir, args['todir'])
-
- self.timeout = args.get('timeout', 1200)
- self.maxTime = args.get('maxTime', None)
-
- if runtime.platformType != "posix":
- d = threads.deferToThread(shutil.copytree, fromdir, todir)
- def cb(_):
- return 0 # rc=0
- def eb(f):
- self.sendStatus({'header' : 'exception from copytree\n' + f.getTraceback()})
- return -1 # rc=-1
- d.addCallbacks(cb, eb)
- @d.addCallback
- def send_rc(rc):
- self.sendStatus({'rc' : rc})
- else:
- if not os.path.exists(os.path.dirname(todir)):
- os.makedirs(os.path.dirname(todir))
- if os.path.exists(todir):
- # I don't think this happens, but just in case..
- log.msg("cp target '%s' already exists -- cp will not do what you think!" % todir)
-
- command = ['cp', '-R', '-P', '-p', fromdir, todir]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=False, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
-
- d.addCallbacks(self._sendRC, self._checkAbandoned)
- return d
-
-class Move(base.Command):
-
- header = "mv"
-
- def setup(self,args):
- self.logEnviron = args.get('logEnviron',True)
-
- def start(self):
- args = self.args
- # args['todir'] is relative to Builder directory, and is required.
- # args['fromdir'] is relative to Builder directory, and is required.
- assert args['todir'] is not None
- assert args['fromdir'] is not None
-
- fromdir = os.path.join(self.builder.basedir, args['fromdir'])
- todir = args['todir']
-
- self.timeout = args.get('timeout', 1200)
- self.maxTime = args.get('maxTime', None)
-
- if runtime.platformType != "posix":
- d = threads.deferToThread(shutil.move, fromdir, todir)
- def cb(_):
- return 0 # rc=0
- def eb(f):
- self.sendStatus({'header' : 'exception from move\n' + f.getTraceback()})
- return -1 # rc=-1
- d.addCallbacks(cb, eb)
- @d.addCallback
- def send_rc(rc):
- self.sendStatus({'rc' : rc})
- else:
- if not os.path.exists(os.path.dirname(todir)):
- os.makedirs(os.path.dirname(todir))
-
- command = ['mv', fromdir, todir]
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=False, timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
-
- d.addCallbacks(self._sendRC, self._checkAbandoned)
- return d
-
-class StatFile(base.Command):
-
- header = "stat"
-
- def start(self):
- args = self.args
- # args['dir'] is relative to Builder directory, and is required.
- assert args['file'] is not None
- filename = os.path.join(self.builder.basedir, args['file'])
-
- try:
- stat = os.stat(filename)
- self.sendStatus({'stat': tuple(stat)})
- self.sendStatus({'rc': 0})
- except:
- self.sendStatus({'rc': 1})
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/git.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/git.py
deleted file mode 100644
index abef42ba..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/git.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.internet import defer
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-from buildslave.commands.base import AbandonChain
-
-
-class Git(SourceBaseCommand):
- """Git specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['repourl'] (required): the upstream GIT repository string
- ['branch'] (optional): which version (i.e. branch or tag)
- to retrieve. Default: "master".
- ['submodules'] (optional): whether to initialize and update
- submodules. Default: False.
- ['ignore_ignores'] (optional): ignore ignores when purging changes
- (default true)
- ['reference'] (optional): use this reference repository
- to fetch objects.
- ['gerrit_branch'] (optional): which virtual branch to retrieve.
- ['progress'] (optional): have git output progress markers,
- avoiding timeouts for long fetches;
- requires Git 1.7.2 or later.
- ['shallow'] (optional): if true, use shallow clones that do not
- also fetch history
- """
-
- header = "git operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.repourl = args['repourl']
- self.branch = args.get('branch')
- if not self.branch:
- self.branch = "master"
- self.sourcedata = "%s %s\n" % (self.repourl, self.branch)
- self.submodules = args.get('submodules')
- self.ignore_ignores = args.get('ignore_ignores', True)
- self.reference = args.get('reference', None)
- self.gerrit_branch = args.get('gerrit_branch', None)
-
- def _fullSrcdir(self):
- return os.path.join(self.builder.basedir, self.srcdir)
-
- def sourcedirIsUpdateable(self):
- return os.path.isdir(os.path.join(self._fullSrcdir(), ".git"))
-
- def _dovccmd(self, command, cb=None, stopOnFail=True, **kwargs):
- git = self.getCommand("git")
- c = runprocess.RunProcess(self.builder, [git] + command, self._fullSrcdir(),
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False, **kwargs)
- self.command = c
- d = c.start()
- if cb:
- if stopOnFail:
- d.addCallback(self._abandonOnFailure)
- d.addCallback(cb)
- return d
-
- def sourcedataMatches(self):
- # If the repourl matches the sourcedata file, then we can say that the
- # sourcedata matches. We can ignore branch changes, since Git can work
- # with many branches fetched, and we deal with it properly in
- # doVCUpdate. So, basically, as long as the file exists, consider it
- # to match
- try:
- self.readSourcedata()
- except IOError:
- return False
- return True
-
- def _cleanSubmodules(self, res):
- command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
- if self.ignore_ignores:
- command.append('-x')
- return self._dovccmd(command)
-
- def _updateSubmodules(self, res):
- return self._dovccmd(['submodule', 'update'], self._cleanSubmodules)
-
- def _initSubmodules(self, res):
- if self.submodules:
- return self._dovccmd(['submodule', 'init'], self._updateSubmodules)
- else:
- return defer.succeed(0)
-
- def _didHeadCheckout(self, res):
- # Rename branch, so that the repo will have the expected branch name
- # For further information about this, see the commit message
- command = ['branch', '-M', self.branch]
- return self._dovccmd(command, self._initSubmodules, False)
-
- def _didFetch(self, res):
- if self.revision:
- head = self.revision
- else:
- head = 'FETCH_HEAD'
-
- # That is not sufficient. git will leave unversioned files and empty
- # directories. Clean them up manually in _didReset.
- command = ['reset', '--hard', head]
- return self._dovccmd(command, self._didHeadCheckout)
-
- def maybeNotDoVCFallback(self, res):
- # If we were unable to find the branch/SHA on the remote,
- # clobbering the repo won't help any, so just abort the chain
- if hasattr(self.command, 'stderr'):
- if "Couldn't find remote ref" in self.command.stderr:
- raise AbandonChain(-1)
-
- # Update first runs "git clean", removing local changes,
- # if the branch to be checked out has changed. This, combined
- # with the later "git reset" equates clobbering the repo,
- # but it's much more efficient.
- def doVCUpdate(self):
- try:
- # Check to see if our branch has changed
- diffbranch = self.sourcedata != self.readSourcedata()
- except IOError:
- diffbranch = False
- if diffbranch or self.sourcedirIsPatched():
- command = ['clean', '-f', '-d']
- if self.ignore_ignores:
- command.append('-x')
- return self._dovccmd(command, self._didClean)
- return self._didClean(None)
-
- def _doFetch(self, dummy, branch):
- # The plus will make sure the repo is moved to the branch's
- # head even if it is not a simple "fast-forward"
- command = ['fetch', '-t', self.repourl, '+%s' % branch]
- # If the 'progress' option is set, tell git fetch to output
- # progress information to the log. This can solve issues with
- # long fetches killed due to lack of output, but only works
- # with Git 1.7.2 or later.
- if self.args.get('progress'):
- command.append('--progress')
- self.sendStatus({"header": "fetching branch %s from %s\n"
- % (branch, self.repourl)})
- return self._dovccmd(command, self._didFetch, keepStderr=True)
-
- def _didClean(self, dummy):
- branch = self.gerrit_branch or self.branch
-
- # After a clean, try to use the given revision if we have one.
- if self.revision:
- # We know what revision we want. See if we have it.
- d = self._dovccmd(['reset', '--hard', self.revision],
- self._initSubmodules)
- # If we are unable to reset to the specified version, we
- # must do a fetch first and retry.
- d.addErrback(self._doFetch, branch)
- return d
- else:
- # No known revision, go grab the latest.
- return self._doFetch(None, branch)
-
- def _didInit(self, res):
- # If we have a reference repository specified, we need to also set that
- # up after the 'git init'.
- if self.reference:
- git_alts_path = os.path.join(self._fullSrcdir(), '.git', 'objects', 'info', 'alternates')
- git_alts_content = os.path.join(self.reference, 'objects')
- self.setFileContents(git_alts_path, git_alts_content)
- return self.doVCUpdate()
-
- def doVCFull(self):
- git = self.getCommand("git")
-
- # If they didn't ask for a specific revision, we can get away with a
- # shallow clone.
- if not self.args.get('revision') and self.args.get('shallow'):
- cmd = [git, 'clone', '--depth', '1']
- # If we have a reference repository, pass it to the clone command
- if self.reference:
- cmd.extend(['--reference', self.reference])
- cmd.extend([self.repourl, self._fullSrcdir()])
- c = runprocess.RunProcess(self.builder, cmd, self.builder.basedir,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- cmdexec = c.start()
- cmdexec.addCallback(self._didInit)
- return cmdexec
- else:
- os.makedirs(self._fullSrcdir())
- return self._dovccmd(['init'], self._didInit)
-
- def parseGotRevision(self):
- command = ['rev-parse', 'HEAD']
- def _parse(res):
- hash = self.command.stdout.strip()
- if len(hash) != 40:
- return None
- return hash
- return self._dovccmd(command, _parse, keepStdout=True)
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/hg.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/hg.py
deleted file mode 100644
index a7182c98..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/hg.py
+++ /dev/null
@@ -1,285 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os, re
-
-from twisted.python import log, runtime
-
-from buildslave.commands.base import SourceBaseCommand, AbandonChain
-from buildslave import runprocess
-from buildslave.util import remove_userpassword
-
-
-class Mercurial(SourceBaseCommand):
- """Mercurial specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['repourl'] (required): the Mercurial repository string
- ['clobberOnBranchChange']: Document me. See ticket #462.
- """
-
- header = "mercurial operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.repourl = args['repourl']
- self.clobberOnBranchChange = args.get('clobberOnBranchChange', True)
- self.sourcedata = "%s\n" % self.repourl
- self.branchType = args.get('branchType', 'dirname')
- self.stdout = ""
- self.stderr = ""
- self.clobbercount = 0 # n times we've clobbered
-
- def sourcedirIsUpdateable(self):
- return os.path.isdir(os.path.join(self.builder.basedir,
- self.srcdir, ".hg"))
-
- def doVCUpdate(self):
- hg = self.getCommand('hg')
- d = os.path.join(self.builder.basedir, self.srcdir)
- command = [hg, 'pull', '--verbose', self.repourl]
- c = runprocess.RunProcess(self.builder, command, d,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, keepStdout=True,
- logEnviron=self.logEnviron, usePTY=False)
- self.command = c
- d = c.start()
- d.addCallback(self._handleEmptyUpdate)
- d.addCallback(self._update)
- return d
-
- def _handleEmptyUpdate(self, res):
- if type(res) is int and res == 1:
- if self.command.stdout.find("no changes found") != -1:
- # 'hg pull', when it doesn't have anything to do, exits with
- # rc=1, and there appears to be no way to shut this off. It
- # emits a distinctive message to stdout, though. So catch
- # this and pretend that it completed successfully.
- return 0
- return res
-
- def doVCFull(self):
- hg = self.getCommand('hg')
- command = [hg, 'clone', '--verbose', '--noupdate']
-
- # if got revision, clobbering and in dirname, only clone to specific revision
- # (otherwise, do full clone to re-use .hg dir for subsequent builds)
- if self.args.get('revision') and self.mode == 'clobber' and self.branchType == 'dirname':
- command.extend(['--rev', self.args.get('revision')])
- command.extend([self.repourl, self.srcdir])
-
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, logEnviron=self.logEnviron,
- usePTY=False)
- self.command = c
- cmd1 = c.start()
- cmd1.addCallback(self._update)
- return cmd1
-
- def _clobber(self, dummy, dirname):
- self.clobbercount += 1
-
- if self.clobbercount > 3:
- raise Exception, "Too many clobber attempts. Aborting step"
-
- def _vcfull(res):
- return self.doVCFull()
-
- c = self.doClobber(dummy, dirname)
- c.addCallback(_vcfull)
-
- return c
-
- def _purge(self, dummy, dirname):
- hg = self.getCommand('hg')
- d = os.path.join(self.builder.basedir, self.srcdir)
- purge = [hg, 'purge', '--all']
- purgeCmd = runprocess.RunProcess(self.builder, purge, d,
- keepStdout=True, keepStderr=True,
- logEnviron=self.logEnviron, usePTY=False)
-
- def _clobber(res):
- if res != 0:
- # purge failed, we need to switch to a classic clobber
- msg = "'hg purge' failed: %s\n%s. Clobbering." % (purgeCmd.stdout, purgeCmd.stderr)
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
-
- return self._clobber(dummy, dirname)
-
- # Purge was a success, then we need to update
- return res
-
- p = purgeCmd.start()
- p.addCallback(_clobber)
- return p
-
- def _update(self, res):
- hg = self.getCommand('hg')
- if res != 0:
- return res
-
- # compare current branch to update
- self.update_branch = self.args.get('branch', 'default')
-
- d = os.path.join(self.builder.basedir, self.srcdir)
- parentscmd = [hg, 'identify', '--num', '--branch']
- cmd = runprocess.RunProcess(self.builder, parentscmd, d,
- sendRC=False, timeout=self.timeout, keepStdout=True,
- keepStderr=True, logEnviron=self.logEnviron,
- usePTY=False)
-
- self.clobber = None
-
- def _parseIdentify(res):
- if res != 0:
- msg = "'hg identify' failed."
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
- raise AbandonChain(-1)
-
- log.msg('Output: %s' % cmd.stdout)
-
- match = re.search(r'^(.+) (.+)$', cmd.stdout)
- if not match:
- msg = "'hg identify' did not give a recognizable output"
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
- raise AbandonChain(-1)
-
- rev = match.group(1)
- current_branch = match.group(2)
-
- if rev == '-1':
- msg = "Fresh hg repo, don't worry about in-repo branch name"
- log.msg(msg)
-
- elif self.sourcedirIsPatched():
- self.clobber = self._purge
-
- elif self.update_branch != current_branch:
- msg = "Working dir is on in-repo branch '%s' and build needs '%s'." % (current_branch, self.update_branch)
- if self.clobberOnBranchChange:
- msg += ' Cloberring.'
- else:
- msg += ' Updating.'
-
- self.sendStatus({'header': msg + "\n"})
- log.msg(msg)
-
- # Clobbers only if clobberOnBranchChange is set
- if self.clobberOnBranchChange:
- self.clobber = self._purge
-
- else:
- msg = "Working dir on same in-repo branch as build (%s)." % (current_branch)
- log.msg(msg)
-
- return 0
-
- def _checkRepoURL(res):
- hg = self.getCommand('hg')
- parentscmd = [hg, 'paths', 'default']
- cmd2 = runprocess.RunProcess(self.builder, parentscmd, d,
- keepStdout=True, keepStderr=True, usePTY=False,
- timeout=self.timeout, sendRC=False,
- logEnviron=self.logEnviron)
-
- def _parseRepoURL(res):
- if res == 1:
- if "not found!" == cmd2.stderr.strip():
- msg = "hg default path not set. Not checking repo url for clobber test"
- log.msg(msg)
- return 0
- else:
- msg = "'hg paths default' failed."
- log.msg(msg)
- return 1
-
- oldurl = cmd2.stdout.strip()
-
- log.msg("Repo cloned from: '%s'" % oldurl)
-
- if runtime.platformType == 'win32':
- oldurl = oldurl.lower().replace('\\', '/')
- repourl = self.repourl.lower().replace('\\', '/')
- else:
- repourl = self.repourl
-
- if repourl.startswith('file://'):
- repourl = repourl.split('file://')[1]
- if oldurl.startswith('file://'):
- oldurl = oldurl.split('file://')[1]
-
- oldurl = remove_userpassword(oldurl)
- repourl = remove_userpassword(repourl)
-
- if oldurl.rstrip('/') != repourl.rstrip('/'):
- self.clobber = self._clobber
- msg = "RepoURL changed from '%s' in wc to '%s' in update. Clobbering" % (oldurl, repourl)
- log.msg(msg)
-
- return 0
-
- c = cmd2.start()
- c.addCallback(_parseRepoURL)
- return c
-
- def _maybeClobber(res):
- if self.clobber:
- msg = "Clobber flag set. Doing clobbering"
- log.msg(msg)
-
- return self.clobber(None, self.srcdir)
-
- return 0
-
- c = cmd.start()
- c.addCallback(_parseIdentify)
- c.addCallback(_checkRepoURL)
- c.addCallback(_maybeClobber)
- c.addCallback(self._update2)
- return c
-
- def _update2(self, res):
- hg = self.getCommand('hg')
- updatecmd=[hg, 'update', '--clean', '--repository', self.srcdir]
- if self.args.get('revision'):
- updatecmd.extend(['--rev', self.args['revision']])
- else:
- updatecmd.extend(['--rev', self.args.get('branch', 'default')])
- self.command = runprocess.RunProcess(self.builder, updatecmd,
- self.builder.basedir, sendRC=False,
- timeout=self.timeout, maxTime=self.maxTime,
- logEnviron=self.logEnviron, usePTY=False)
- return self.command.start()
-
- def parseGotRevision(self):
- hg = self.getCommand('hg')
- # we use 'hg parents' to find out what we wound up with
- command = [hg, "parents", "--template", "{node}\\n"] # get full rev id
- c = runprocess.RunProcess(self.builder, command,
- os.path.join(self.builder.basedir, self.srcdir),
- environ=self.env, timeout=self.timeout,
- sendRC=False,
- keepStdout=True, usePTY=False,
- logEnviron=self.logEnviron)
- d = c.start()
- def _parse(res):
- m = re.search(r'^(\w+)', c.stdout)
- return m.group(1)
- d.addCallback(_parse)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/mtn.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/mtn.py
deleted file mode 100644
index 99cae5d4..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/mtn.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-#from buildslave.util import remove_userpassword
-
-class MonotoneError(Exception):
- """Error class for this module."""
-
-
-class Monotone(SourceBaseCommand):
- """Monotone specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['repourl'] (required): the Monotone repository string
- ['branch'] (required): which branch to retrieve.
-
- ['revision'] (optional): which revision (revision selector)
- to retrieve.
- ['progress'] (optional): have mtn output progress markers,
- avoiding timeouts for long fetches;
- """
-
- header = "monotone operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
-
- self.repourl = args['repourl']
- self.branch = args['branch']
-
- self.revision = args.get('revision', None)
- self.progress = args.get('progress', False)
-
- self._pull_timeout = args.get("timeout")
-
- self.sourcedata = "%s?%s" % (self.repourl, self.branch)
- self.stdout = ""
- self.stderr = ""
- self.database = os.path.join(self.builder.basedir, 'db.mtn')
- self.mtn = self.getCommand("mtn")
-
- def start(self):
- def cont(res):
- # Continue with start() method in superclass.
- return SourceBaseCommand.start(self)
-
- d = self._checkDb();
- d.addCallback(cont)
- return d
-
- def doVCUpdate(self):
- return self._dovccmd(self._update, True)
-
- def doVCFull(self):
- return self._dovccmd(self._checkout, True)
-
- def _fullSrcdir(self):
- return os.path.join(self.builder.basedir, self.srcdir)
-
- def sourcedirIsUpdateable(self):
- return os.path.isdir(os.path.join(self._fullSrcdir(), "_MTN"))
-
- def _dovccmd(self, fn, dopull, cb=None, **kwargs):
- if dopull:
- command = [self.mtn, 'pull', self.sourcedata,
- '--db', self.database]
- if self.progress:
- command.extend(['--ticker=dot'])
- else:
- command.extend(['--ticker=none'])
- c = runprocess.RunProcess(self.builder, command,
- self.builder.basedir,
- environ=self.env, sendRC=False,
- timeout=self.timeout,
- maxTime=self.maxTime,
- keepStdout=True, usePTY=False,
- logEnviron=self.logEnviron)
- self.sendStatus({"header": "pulling %s from %s\n"
- % (self.branch, self.sourcedata)})
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- d.addCallback(fn)
- else:
- d = fn(None)
- if cb:
- d.addCallback(cb)
- return d
-
- def _update(self, res):
- command = [self.mtn, 'update',
- '--db', self.database]
- if self.revision:
- command.extend(['--revision', self.revision])
- else:
- command.extend(["-r", "h:" + self.branch])
- command.extend(["-b", self.branch])
- c = runprocess.RunProcess(self.builder, command, self._fullSrcdir(),
- environ=self.env, sendRC=False,
- timeout=self.timeout, maxTime=self.maxTime,
- keepStdout=True, usePTY=False,
- logEnviron=self.logEnviron)
- d = c.start()
- return d
-
- def _checkout(self, res):
- command = [self.mtn, 'checkout', self._fullSrcdir(),
- '--db', self.database]
- if self.revision:
- command.extend(['--revision', self.revision])
- command.extend(['--branch', self.branch])
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- environ=self.env, sendRC=False,
- timeout=self.timeout, maxTime=self.maxTime,
- keepStdout=True, usePTY=False,
- logEnviron=self.logEnviron)
- d = c.start()
- return d
-
- def _checkDb(self):
- # Don't send stderr. When there is no database, this might confuse
- # users, as they will see a mtn error message. But having no database
- # repo is not an error, just an indication that we need to pull one.
- c = runprocess.RunProcess(self.builder, [self.mtn, 'db', 'info',
- '--db', self.database],
- self.builder.basedir,
- environ=self.env, sendRC=False,
- keepStdout=True, sendStderr=False,
- usePTY=False, logEnviron=self.logEnviron)
- d = c.start()
- def afterCheckRepo(res, cdi):
- if type(res) is int and res != 0:
- log.msg("No database found, creating it")
- # mtn info fails, try to create shared repo.
- # We'll be doing an initial pull, so up the timeout to
- # 3 hours to make sure it will have time to complete.
- self._pull_timeout = max(self._pull_timeout, 3 * 60 * 60)
- c = runprocess.RunProcess(self.builder, [self.mtn, 'db', 'init',
- '--db', self.database],
- self.builder.basedir,
- environ=self.env,
- sendRC=False, usePTY=False,
- logEnviron=self.logEnviron)
- self.command = c
- return c.start()
- elif cdi.stdout.find("(migration needed)") > 0:
- log.msg("Older format database found, migrating it")
- # mtn info fails, try to create shared repo.
- c = runprocess.RunProcess(self.builder, [self.mtn,
- 'db', 'migrate',
- '--db', self.database],
- self.builder.basedir,
- environ=self.env,
- sendRC=False, usePTY=False,
- logEnviron=self.logEnviron)
- self.command = c
- return c.start()
- elif cdi.stdout.find("(too new, cannot use)") > 0:
- raise MonotoneError, "The database is of a newer format than mtn can handle... Abort!"
- else:
- return defer.succeed(res)
- d.addCallback(afterCheckRepo, c)
- return d
-
- def parseGotRevision(self):
- def _parse(res):
- hash = self.command.stdout.strip()
- if len(hash) != 40:
- return None
- return hash
- return self._dovccmd(self._get_base_revision, False, _parse)
-
- def _get_base_revision(self, res):
- c = runprocess.RunProcess(self.builder,
- [self.mtn, 'automate', 'select', 'w:'],
- self._fullSrcdir(),
- sendRC=False,
- timeout=self.timeout, maxTime=self.maxTime,
- keepStdout=True, usePTY=False,
- logEnviron=self.logEnviron)
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/p4.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/p4.py
deleted file mode 100644
index 7aa17d8e..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/p4.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os, re
-
-from twisted.python import log
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-from buildslave.util import Obfuscated
-
-
-class P4Base(SourceBaseCommand):
- """Base class for P4 source-updaters
-
- ['p4port'] (required): host:port for server to access
- ['p4user'] (optional): user to use for access
- ['p4passwd'] (optional): passwd to try for the user
- ['p4client'] (optional): client spec to use
- """
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.p4port = args['p4port']
- self.p4client = args['p4client']
- self.p4user = args['p4user']
- self.p4passwd = args['p4passwd']
-
- def parseGotRevision(self):
- # Executes a p4 command that will give us the latest changelist number
- # of any file under the current (or default) client:
- command = ['p4']
- if self.p4port:
- command.extend(['-p', self.p4port])
- if self.p4user:
- command.extend(['-u', self.p4user])
- if self.p4passwd:
- command.extend(['-P', Obfuscated(self.p4passwd, "XXXXXXXX")])
- if self.p4client:
- command.extend(['-c', self.p4client])
- # add '-s submitted' for bug #626
- command.extend(['changes', '-s', 'submitted', '-m', '1', '#have'])
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- environ=self.env, timeout=self.timeout,
- maxTime=self.maxTime, sendStdout=True,
- sendRC=False, keepStdout=True,
- usePTY=False, logEnviron=self.logEnviron)
- self.command = c
- d = c.start()
-
- def _parse(res):
- # 'p4 -c clien-name change -m 1 "#have"' will produce an output like:
- # "Change 28147 on 2008/04/07 by p4user@hostname..."
- # The number after "Change" is the one we want.
- m = re.match('Change\s+(\d+)\s+', c.stdout)
- if m:
- return m.group(1)
- return None
- d.addCallback(_parse)
- return d
-
-
-class P4(P4Base):
- """A P4 source-updater.
-
- ['p4port'] (required): host:port for server to access
- ['p4user'] (required): user to use for access
- ['p4passwd'] (required): passwd to try for the user
- ['p4client'] (required): client spec to use
- ['p4extra_views'] (required): additional client views to use
- ['p4base'] (required): view into the Perforce depot without branch name or trailing "..."
- ['p4line_end'] (optional): value of the LineEnd client specification property
- """
-
- header = "p4"
-
- def setup(self, args):
- P4Base.setup(self, args)
- self.p4base = args['p4base']
- self.p4extra_views = args['p4extra_views']
- self.p4line_end = args.get('p4line_end', None)
- self.p4mode = args['mode']
- self.p4branch = args['branch']
-
- # sourcedata is encoded to utf-8, since otherwise unicode strings
- # appear with a leading "u", causing comparisons to fail. In
- # retrospect, comparing str() output is not the best technique!
- def enc(x):
- if isinstance(x, unicode):
- return x.encode('utf8')
- return x
- self.sourcedata = str([
- enc(x) for x in [
- # Perforce server.
- self.p4port,
-
- # Client spec.
- self.p4client,
-
- # Depot side of view spec.
- self.p4base,
- self.p4branch,
- self.p4extra_views,
- self.p4line_end,
-
- # Local side of view spec (srcdir is made from these).
- self.builder.basedir,
- self.mode,
- self.workdir
- ]])
-
-
- def sourcedirIsUpdateable(self):
- # We assume our client spec is still around.
- # We just say we aren't updateable if the dir doesn't exist so we
- # don't get ENOENT checking the sourcedata.
- return (not self.sourcedirIsPatched() and
- os.path.isdir(os.path.join(self.builder.basedir,
- self.srcdir)))
-
- def doVCUpdate(self):
- return self._doP4Sync(force=False)
-
- def _doP4Sync(self, force):
- command = ['p4']
-
- if self.p4port:
- command.extend(['-p', self.p4port])
- if self.p4user:
- command.extend(['-u', self.p4user])
- if self.p4passwd:
- command.extend(['-P', Obfuscated(self.p4passwd, "XXXXXXXX")])
- if self.p4client:
- command.extend(['-c', self.p4client])
- command.extend(['sync'])
- if force:
- command.extend(['-f'])
- if self.revision:
- command.extend(['@' + str(self.revision)])
- env = {}
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- environ=env, sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, usePTY=False,
- logEnviron=self.logEnviron)
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- return d
-
-
- def doVCFull(self):
- env = {}
- command = ['p4']
- client_spec = ''
- client_spec += "Client: %s\n\n" % self.p4client
- client_spec += "Owner: %s\n\n" % self.p4user
- client_spec += "Description:\n\tCreated by %s\n\n" % self.p4user
- client_spec += "Root:\t%s\n\n" % self.builder.basedir
- client_spec += "Options:\tallwrite rmdir\n\n"
- if self.p4line_end:
- client_spec += "LineEnd:\t%s\n\n" % self.p4line_end
- else:
- client_spec += "LineEnd:\tlocal\n\n"
-
- # Setup a view
- client_spec += "View:\n\t%s" % (self.p4base)
- if self.p4branch:
- client_spec += "%s/" % (self.p4branch)
- client_spec += "... //%s/%s/...\n" % (self.p4client, self.srcdir)
- if self.p4extra_views:
- for k, v in self.p4extra_views:
- client_spec += "\t%s/... //%s/%s%s/...\n" % (k, self.p4client,
- self.srcdir, v)
- if self.p4port:
- command.extend(['-p', self.p4port])
- if self.p4user:
- command.extend(['-u', self.p4user])
- if self.p4passwd:
- command.extend(['-P', Obfuscated(self.p4passwd, "XXXXXXXX")])
- command.extend(['client', '-i'])
- log.msg(client_spec)
-
- # from bdbaddog in github comments:
- # I'm pretty sure the issue is that perforce client specs can't be
- # non-ascii (unless you configure at initial config to be unicode). I
- # floated a question to perforce mailing list. From reading the
- # internationalization notes..
- # http://www.perforce.com/perforce/doc.092/user/i18nnotes.txt
- # I'm 90% sure that's the case.
- # (http://github.com/bdbaddog/buildbot/commit/8420149b2b804efcf5f81a13e18aa62da0424d21)
-
- # Clean client spec to plain ascii
- client_spec=client_spec.encode('ascii','ignore')
-
- c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
- environ=env, sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, initialStdin=client_spec,
- usePTY=False, logEnviron=self.logEnviron)
- self.command = c
- d = c.start()
- d.addCallback(self._abandonOnFailure)
- d.addCallback(lambda _: self._doP4Sync(force=True))
- return d
-
- def parseGotRevision(self):
- if self.revision:
- return str(self.revision)
- else:
- return P4Base.parseGotRevision(self)
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/registry.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/registry.py
deleted file mode 100644
index 22dc3ee6..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/registry.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python import reflect
-
-commandRegistry = {
- # command name : fully qualified factory name (callable)
- "shell" : "buildslave.commands.shell.SlaveShellCommand",
- "uploadFile" : "buildslave.commands.transfer.SlaveFileUploadCommand",
- "uploadDirectory" : "buildslave.commands.transfer.SlaveDirectoryUploadCommand",
- "downloadFile" : "buildslave.commands.transfer.SlaveFileDownloadCommand",
- "downloadDirectory" : "buildslave.commands.transfer.SlaveDirectoryDownloadCommand",
- "svn" : "buildslave.commands.svn.SVN",
- "bk" : "buildslave.commands.bk.BK",
- "cvs" : "buildslave.commands.cvs.CVS",
- "darcs" : "buildslave.commands.darcs.Darcs",
- "git" : "buildslave.commands.git.Git",
- "repo" : "buildslave.commands.repo.Repo",
- "bzr" : "buildslave.commands.bzr.Bzr",
- "hg" : "buildslave.commands.hg.Mercurial",
- "p4" : "buildslave.commands.p4.P4",
- "mtn" : "buildslave.commands.mtn.Monotone",
- "mkdir" : "buildslave.commands.fs.MakeDirectory",
- "rmdir" : "buildslave.commands.fs.RemoveDirectory",
- "cpdir" : "buildslave.commands.fs.CopyDirectory",
- "mv" : "buildslave.commands.fs.Move",
- "stat" : "buildslave.commands.fs.StatFile",
-}
-
-def getFactory(command):
- factory_name = commandRegistry[command]
- factory = reflect.namedObject(factory_name)
- return factory
-
-def getAllCommandNames():
- return commandRegistry.keys()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/repo.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/repo.py
deleted file mode 100644
index b445fa33..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/repo.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import re
-import textwrap
-
-from twisted.internet import defer
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-from buildslave.commands.base import AbandonChain
-
-
-class Repo(SourceBaseCommand):
- """Repo specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['manifest_url'] (required): The manifests repo repository.
- ['manifest_branch'] (optional): Which manifest repo version (i.e. branch or tag)
- to retrieve. Default: "master".
- ['manifest_file'] (optional): Which manifest file to use. Default: "default.xml".
- ['manifest_override_url'] (optional): Which manifest file to use as an overide. Default: None.
- This is usually set by forced build to build over a known working base
- ['tarball'] (optional): The tarball base to accelerate the fetch.
- ['repo_downloads'] (optional): Repo downloads to do. Computer from GerritChangeSource
- and forced build properties.
- ['jobs'] (optional): number of connections to run in parallel
- repo tool will use while syncing
- """
-
- header = "repo operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.manifest_url = args.get('manifest_url')
- self.manifest_branch = args.get('manifest_branch')
- self.manifest_file = args.get('manifest_file')
- self.manifest_override_url = args.get('manifest_override_url')
- self.tarball = args.get('tarball')
- self.repo_downloads = args.get('repo_downloads')
- # we're using string instead of an array here, because it will be transferred back
- # to the master as string anyway and using eval() could have security implications.
- self.repo_downloaded = ""
- self.jobs = args.get('jobs')
-
- self.sourcedata = "%s %s" % (self.manifest_url, self.manifest_file)
- self.re_change = re.compile(".* refs/changes/\d\d/(\d+)/(\d+) -> FETCH_HEAD$")
- self.re_head = re.compile("^HEAD is now at ([0-9a-f]+)...")
-
- def _fullSrcdir(self):
- return os.path.join(self.builder.basedir, self.srcdir)
-
- def sourcedirIsUpdateable(self):
- print os.path.join(self._fullSrcdir(), ".repo")
- print os.path.isdir(os.path.join(self._fullSrcdir(), ".repo"))
- return os.path.isdir(os.path.join(self._fullSrcdir(), ".repo"))
-
- def _repoCmd(self, command, cb=None, abandonOnFailure=True, **kwargs):
- repo = self.getCommand("repo")
- c = runprocess.RunProcess(self.builder, [repo] + command, self._fullSrcdir(),
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, usePTY=False,
- logEnviron=self.logEnviron, **kwargs)
- self.command = c
- d = c.start()
- if cb:
- if abandonOnFailure:
- d.addCallback(self._abandonOnFailure)
- d.addCallback(cb)
- return d
-
- def _Cmd(self, cmds, callback, abandonOnFailure=True):
- c = runprocess.RunProcess(self.builder, cmds, self._fullSrcdir(),
- sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, usePTY=False,
- logEnviron=self.logEnviron)
- self.command = c
- d = c.start()
- if abandonOnFailure:
- d.addCallback(self._abandonOnFailure)
- d.addCallback(callback)
- return d
-
- def sourcedataMatches(self):
- try:
- olddata = self.readSourcedata()
- return olddata == self.sourcedata
- except IOError:
- return False
-
- def doVCFull(self):
- os.makedirs(self._fullSrcdir())
- if self.tarball and os.path.exists(self.tarball):
- return self._Cmd(['tar', '-xvzf', self.tarball], self._doPreInitCleanUp)
- else:
- return self._doInit(None)
-
- def _doInit(self,res):
- # on fresh init, this file may confuse repo.
- if os.path.exists(os.path.join(self._fullSrcdir(), ".repo/project.list")):
- os.unlink(os.path.join(self._fullSrcdir(), ".repo/project.list"))
- return self._repoCmd(['init', '-u', self.manifest_url, '-b', self.manifest_branch, '-m', self.manifest_file], self._didInit)
-
- def _didInit(self, res):
- return self.doVCUpdate()
-
- def doVCUpdate(self):
- if self.repo_downloads:
- self.sendStatus({'header': "will download:\n" + "repo download "+ "\nrepo download ".join(self.repo_downloads) + "\n"})
- return self._doPreSyncCleanUp(None)
-
- # a simple shell script to gather all cleanup tweaks...
- # doing them one by one just complicate the stuff
- # and messup the stdio log
- def _cleanupCommand(self):
- command = textwrap.dedent("""\
- set -v
- if [ -d .repo/manifests ]
- then
- # repo just refuse to run if manifest is messed up
- # so ensure we are in a known state
- cd .repo/manifests
- git fetch origin
- git reset --hard remotes/origin/%(manifest_branch)s
- git config branch.default.merge %(manifest_branch)s
- cd ..
- ln -sf manifests/%(manifest_file)s manifest.xml
- cd ..
- fi
- repo forall -c rm -f .git/index.lock
- repo forall -c git clean -f -d -x 2>/dev/null
- repo forall -c git reset --hard HEAD 2>/dev/null
- """) % self.__dict__
- return "\n".join([ s.strip() for s in command.splitlines()])
-
- def _doPreInitCleanUp(self, dummy):
- command = self._cleanupCommand()
- return self._Cmd(["bash", "-c", command], self._doInit, abandonOnFailure=False)
-
- def _doPreSyncCleanUp(self, dummy):
- command = self._cleanupCommand()
- return self._Cmd(["bash", "-c", command], self._doManifestOveride, abandonOnFailure=False)
-
- def _doManifestOveride(self, dummy):
- if self.manifest_override_url:
- self.sendStatus({"header": "overriding manifest with %s\n" %(self.manifest_override_url)})
- if os.path.exists(os.path.join(self._fullSrcdir(), self.manifest_override_url)):
- os.system("cd %s; cp -f %s manifest_override.xml"%(self._fullSrcdir(),self.manifest_override_url))
- else:
- command = ["wget", self.manifest_override_url, '-O', 'manifest_override.xml']
- return self._Cmd(command, self._doSync)
- return self._doSync(None)
-
- def _doSync(self, dummy):
- if self.manifest_override_url:
- os.system("cd %s/.repo; ln -sf ../manifest_override.xml manifest.xml"%(self._fullSrcdir()))
- command = ['sync']
- if self.jobs:
- command.append('-j' + str(self.jobs))
- self.sendStatus({"header": "synching manifest %s from branch %s from %s\n"
- % (self.manifest_file, self.manifest_branch, self.manifest_url)})
- return self._repoCmd(command, self._didSync)
-
- def _didSync(self, dummy):
- if self.tarball and not os.path.exists(self.tarball):
- return self._Cmd(['tar', '-cvzf', self.tarball, ".repo"], self._doManifest)
- else:
- return self._doManifest(None)
-
- def _doManifest(self, dummy):
- command = ['manifest', '-r', '-o', 'manifest-original.xml']
- return self._repoCmd(command, self._doDownload, abandonOnFailure=False)
-
-
- def _doDownload(self, dummy):
- if hasattr(self.command, 'stderr') and self.command.stderr:
- if "Automatic cherry-pick failed" in self.command.stderr or "Automatic revert failed" in self.command.stderr:
- command = ['forall','-c' ,'git' ,'diff', 'HEAD']
- self.cherry_pick_failed = True
- return self._repoCmd(command, self._DownloadAbandon, abandonOnFailure = False, keepStderr=True) # call again
-
- lines = self.command.stderr.split('\n')
- if len(lines) > 2:
- match1 = self.re_change.match(lines[1])
- match2 = self.re_head.match(lines[-2])
- if match1 and match2:
- self.repo_downloaded += "%s/%s %s " % (match1.group(1), match1.group(2), match2.group(1))
-
- if self.repo_downloads:
- # download each changeset while the self.download variable is not empty
- download = self.repo_downloads.pop(0)
- command = ['download'] + download.split(' ')
- self.sendStatus({"header": "downloading changeset %s\n"
- % (download)})
- return self._repoCmd(command, self._doDownload, abandonOnFailure = False, keepStderr=True) # call again
-
- if self.repo_downloaded:
- self.sendStatus({"repo_downloaded": self.repo_downloaded[:-1]})
- return defer.succeed(0)
-
- def maybeNotDoVCFallback(self, res):
- # If we were unable to find the branch/SHA on the remote,
- # clobbering the repo won't help any, so just abort the chain
- if hasattr(self.command, 'stderr'):
- if "Couldn't find remote ref" in self.command.stderr:
- raise AbandonChain(-1)
- if hasattr(self, 'cherry_pick_failed') or "Automatic cherry-pick failed" in self.command.stderr:
- raise AbandonChain(-1)
- def _DownloadAbandon(self,dummy):
- self.sendStatus({"header": "abandonned due to merge failure\n"})
- raise AbandonChain(-1)
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/shell.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/shell.py
deleted file mode 100644
index be85eb9d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/shell.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from buildslave.commands import base
-from buildslave import runprocess
-
-class SlaveShellCommand(base.Command):
- def start(self):
- args = self.args
- # args['workdir'] is relative to Builder directory, and is required.
- assert args['workdir'] is not None
- workdir = os.path.join(self.builder.basedir, args['workdir'])
-
- c = runprocess.RunProcess(
- self.builder,
- args['command'],
- workdir,
- environ=args.get('env'),
- timeout=args.get('timeout', None),
- maxTime=args.get('maxTime', None),
- sendStdout=args.get('want_stdout', True),
- sendStderr=args.get('want_stderr', True),
- sendRC=True,
- initialStdin=args.get('initial_stdin'),
- logfiles=args.get('logfiles', {}),
- usePTY=args.get('usePTY', "slave-config"),
- logEnviron=args.get('logEnviron', True),
- )
- if args.get('interruptSignal'):
- c.interruptSignal = args['interruptSignal']
- c._reactor = self._reactor
- self.command = c
- d = self.command.start()
- return d
-
- def interrupt(self):
- self.interrupted = True
- self.command.kill("command interrupted")
-
- def writeStdin(self, data):
- self.command.writeStdin(data)
-
- def closeStdin(self):
- self.command.closeStdin()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/svn.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/svn.py
deleted file mode 100644
index f1c051d7..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/svn.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from xml.dom.minidom import parseString
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildslave.commands.base import SourceBaseCommand
-from buildslave import runprocess
-from buildslave.commands import utils
-from buildslave.util import Obfuscated
-
-class SVN(SourceBaseCommand):
- """Subversion-specific VC operation. In addition to the arguments
- handled by SourceBaseCommand, this command reads the following keys:
-
- ['svnurl'] (required): the SVN repository string
- ['username']: Username passed to the svn command
- ['password']: Password passed to the svn command
- ['keep_on_purge']: Files and directories to keep between updates
- ['ignore_ignores']: Ignore ignores when purging changes
- ['always_purge']: Always purge local changes after each build
- ['depth']: Pass depth argument to subversion 1.5+
- """
-
- header = "svn operation"
-
- def setup(self, args):
- SourceBaseCommand.setup(self, args)
- self.svnurl = args['svnurl']
- self.sourcedata = "%s\n" % self.svnurl
- self.keep_on_purge = args.get('keep_on_purge', [])
- self.keep_on_purge.append(".buildbot-sourcedata")
- self.ignore_ignores = args.get('ignore_ignores', True)
- self.always_purge = args.get('always_purge', False)
-
- self.exported_rev = 'HEAD'
-
- self.svn_args = []
- if args.has_key('username'):
- self.svn_args.extend(["--username", args['username']])
- if args.has_key('password'):
- self.svn_args.extend(["--password", Obfuscated(args['password'], "XXXX")])
- if args.get('extra_args', None) is not None:
- self.svn_args.extend(args['extra_args'])
-
- if args.has_key('depth'):
- self.svn_args.extend(["--depth",args['depth']])
-
- def _dovccmd(self, command, args, rootdir=None, cb=None, **kwargs):
- svn = self.getCommand("svn")
- if rootdir is None:
- rootdir = os.path.join(self.builder.basedir, self.srcdir)
- fullCmd = [svn, command, '--non-interactive', '--no-auth-cache']
- fullCmd.extend(self.svn_args)
- fullCmd.extend(args)
- c = runprocess.RunProcess(self.builder, fullCmd, rootdir,
- environ=self.env, sendRC=False, timeout=self.timeout,
- maxTime=self.maxTime, usePTY=False,
- logEnviron=self.logEnviron, **kwargs)
- self.command = c
- d = c.start()
- if cb:
- d.addCallback(self._abandonOnFailure)
- d.addCallback(cb)
- return d
-
- def sourcedirIsUpdateable(self):
- return os.path.isdir(os.path.join(self.builder.basedir,
- self.srcdir, ".svn"))
-
- def doVCUpdate(self):
- if self.sourcedirIsPatched() or self.always_purge:
- return self._purgeAndUpdate()
- revision = self.args['revision'] or 'HEAD'
- # update: possible for mode in ('copy', 'update')
- return self._dovccmd('update', ['--revision', str(revision)])
-
- def doVCFull(self):
- revision = self.args['revision'] or 'HEAD'
- args = ['--revision', str(revision), "%s@%s" % (self.svnurl, str(revision)), self.srcdir]
-
- if self.mode == 'export':
- if revision == 'HEAD': return self.doSVNExport()
- else: command = 'export'
- else:
- # mode=='clobber', or copy/update on a broken workspace
- command = 'checkout'
- return self._dovccmd(command, args, rootdir=self.builder.basedir)
-
- def doSVNExport(self):
- ''' Since svnversion cannot be used on a svn export, we find the HEAD
- revision from the repository and pass it to the --revision arg'''
-
- def parseInfo(res):
- answer = [i.split(': ') for i in self.command.stdout.splitlines() if i]
- answer = dict(answer)
- self.exported_rev = answer['Revision']
- return self.exported_rev
-
- def exportCmd(res):
- args = ['--revision', str(res), self.svnurl, self.srcdir]
- return self._dovccmd('export', args, rootdir=self.builder.basedir)
-
- svn_info_d = self._dovccmd('info', (self.svnurl,), rootdir=self.builder.basedir, keepStdout=True)
-
- svn_info_d.addCallbacks(parseInfo, self._abandonOnFailure)
- svn_info_d.addCallbacks(exportCmd)
-
- return svn_info_d
-
- def _purgeAndUpdate(self):
- """svn revert has several corner cases that make it unpractical.
-
- Use the Force instead and delete everything that shows up in status."""
- args = ['--xml']
- if self.ignore_ignores:
- args.append('--no-ignore')
- return self._dovccmd('status', args, keepStdout=True, sendStdout=False,
- cb=self._purgeAndUpdate2)
-
- @staticmethod
- def getUnversionedFiles(stdout, keep_on_purge):
- """Delete everything that shown up on status."""
- result_xml = parseString(stdout)
- for entry in result_xml.getElementsByTagName('entry'):
- (wc_status,) = entry.getElementsByTagName('wc-status')
- if wc_status.getAttribute('item') == 'external':
- continue
- if wc_status.getAttribute('item') == 'missing':
- continue
- filename = entry.getAttribute('path')
- if filename in keep_on_purge:
- continue
- yield filename
-
- def _purgeAndUpdate2(self, res):
- for filename in self.getUnversionedFiles(self.command.stdout, self.keep_on_purge):
- filepath = os.path.join(self.builder.basedir, self.workdir,
- filename)
- self.sendStatus({'stdout': "%s\n" % filepath})
- if os.path.isfile(filepath):
- os.chmod(filepath, 0700)
- os.remove(filepath)
- else:
- utils.rmdirRecursive(filepath)
- # Now safe to update.
- revision = self.args['revision'] or 'HEAD'
- return self._dovccmd('update', ['--revision', str(revision)],
- keepStdout=True)
-
- def getSvnVersionCommand(self):
- """
- Get the (shell) command used to determine SVN revision number
- of checked-out code
-
- return: list of strings, passable as the command argument to RunProcess
- """
- # svn checkout operations finish with 'Checked out revision 16657.'
- # svn update operations finish the line 'At revision 16654.'
- # But we don't use those. Instead, run 'svnversion'.
- svnversion_command = utils.getCommand("svnversion")
- # older versions of 'svnversion' (1.1.4) require the WC_PATH
- # argument, newer ones (1.3.1) do not.
- return [svnversion_command, "."]
-
- def parseGotRevision(self):
- if self.mode == 'export':
- ss_rev = self.args['revision']
- got_revision = ss_rev and ss_rev or self.exported_rev
- return defer.succeed(got_revision)
-
- c = runprocess.RunProcess(self.builder,
- self.getSvnVersionCommand(),
- os.path.join(self.builder.basedir, self.srcdir),
- environ=self.env, timeout=self.timeout,
- sendStdout=False, sendStderr=False, sendRC=False,
- keepStdout=True, usePTY=False,
- logEnviron=self.logEnviron)
- d = c.start()
- def _parse(res):
- r_raw = c.stdout.strip()
- # Extract revision from the version "number" string
- r = r_raw.rstrip('MSP')
- r = r.split(':')[-1]
- got_version = None
- try:
- got_version = int(r)
- except ValueError:
- msg =("SVN.parseGotRevision unable to parse output "
- "of svnversion: '%s'" % r_raw)
- log.msg(msg)
- self.sendStatus({'header': msg + "\n"})
- return got_version
- d.addCallback(_parse)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/transfer.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/transfer.py
deleted file mode 100644
index e51e8b90..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/transfer.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os, tarfile, tempfile
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildslave.commands.base import Command
-
-class TransferCommand(Command):
-
- def finished(self, res):
- if self.debug:
- log.msg('finished: stderr=%r, rc=%r' % (self.stderr, self.rc))
-
- # don't use self.sendStatus here, since we may no longer be running
- # if we have been interrupted
- upd = {'rc': self.rc}
- if self.stderr:
- upd['stderr'] = self.stderr
- self.builder.sendUpdate(upd)
- return res
-
- def interrupt(self):
- if self.debug:
- log.msg('interrupted')
- if self.interrupted:
- return
- self.rc = 1
- self.interrupted = True
- # now we wait for the next trip around the loop. It abandon the file
- # when it sees self.interrupted set.
-
-
-class SlaveFileUploadCommand(TransferCommand):
- """
- Upload a file from slave to build master
- Arguments:
-
- - ['workdir']: base directory to use
- - ['slavesrc']: name of the slave-side file to read from
- - ['writer']: RemoteReference to a transfer._FileWriter object
- - ['maxsize']: max size (in bytes) of file to write
- - ['blocksize']: max size for each data block
- - ['keepstamp']: whether to preserve file modified and accessed times
- """
- debug = False
-
- def setup(self, args):
- self.workdir = args['workdir']
- self.filename = args['slavesrc']
- self.writer = args['writer']
- self.remaining = args['maxsize']
- self.blocksize = args['blocksize']
- self.keepstamp = args.get('keepstamp', False)
- self.stderr = None
- self.rc = 0
-
- def start(self):
- if self.debug:
- log.msg('SlaveFileUploadCommand started')
-
- # Open file
- self.path = os.path.join(self.builder.basedir,
- self.workdir,
- os.path.expanduser(self.filename))
- accessed_modified = None
- try:
- if self.keepstamp:
- accessed_modified = (os.path.getatime(self.path),
- os.path.getmtime(self.path))
-
- self.fp = open(self.path, 'rb')
- if self.debug:
- log.msg("Opened '%s' for upload" % self.path)
- except:
- self.fp = None
- self.stderr = "Cannot open file '%s' for upload" % self.path
- self.rc = 1
- if self.debug:
- log.msg("Cannot open file '%s' for upload" % self.path)
-
- self.sendStatus({'header': "sending %s" % self.path})
-
- d = defer.Deferred()
- self._reactor.callLater(0, self._loop, d)
- def _close_ok(res):
- self.fp = None
- d1 = self.writer.callRemote("close")
- def _utime_ok(res):
- return self.writer.callRemote("utime", accessed_modified)
- if self.keepstamp:
- d1.addCallback(_utime_ok)
- return d1
- def _close_err(f):
- self.rc = 1
- self.fp = None
- # call remote's close(), but keep the existing failure
- d1 = self.writer.callRemote("close")
- def eb(f2):
- log.msg("ignoring error from remote close():")
- log.err(f2)
- d1.addErrback(eb)
- d1.addBoth(lambda _ : f) # always return _loop failure
- return d1
-
- d.addCallbacks(_close_ok, _close_err)
- d.addBoth(self.finished)
- return d
-
- def _loop(self, fire_when_done):
- d = defer.maybeDeferred(self._writeBlock)
- def _done(finished):
- if finished:
- fire_when_done.callback(None)
- else:
- self._loop(fire_when_done)
- def _err(why):
- fire_when_done.errback(why)
- d.addCallbacks(_done, _err)
- return None
-
- def _writeBlock(self):
- """Write a block of data to the remote writer"""
-
- if self.interrupted or self.fp is None:
- if self.debug:
- log.msg('SlaveFileUploadCommand._writeBlock(): end')
- return True
-
- length = self.blocksize
- if self.remaining is not None and length > self.remaining:
- length = self.remaining
-
- if length <= 0:
- if self.stderr is None:
- self.stderr = 'Maximum filesize reached, truncating file \'%s\'' \
- % self.path
- self.rc = 1
- data = ''
- else:
- data = self.fp.read(length)
-
- if self.debug:
- log.msg('SlaveFileUploadCommand._writeBlock(): '+
- 'allowed=%d readlen=%d' % (length, len(data)))
- if len(data) == 0:
- log.msg("EOF: callRemote(close)")
- return True
-
- if self.remaining is not None:
- self.remaining = self.remaining - len(data)
- assert self.remaining >= 0
- d = self.writer.callRemote('write', data)
- d.addCallback(lambda res: False)
- return d
-
-
-class SlaveDirectoryUploadCommand(SlaveFileUploadCommand):
- debug = False
-
- def setup(self, args):
- self.workdir = args['workdir']
- self.dirname = args['slavesrc']
- self.writer = args['writer']
- self.remaining = args['maxsize']
- self.blocksize = args['blocksize']
- self.compress = args['compress']
- self.stderr = None
- self.rc = 0
-
- def start(self):
- if self.debug:
- log.msg('SlaveDirectoryUploadCommand started')
-
- self.path = os.path.join(self.builder.basedir,
- self.workdir,
- os.path.expanduser(self.dirname))
- if self.debug:
- log.msg("path: %r" % self.path)
-
- # Create temporary archive
- fd, self.tarname = tempfile.mkstemp()
- fileobj = os.fdopen(fd, 'w')
- if self.compress == 'bz2':
- mode='w|bz2'
- elif self.compress == 'gz':
- mode='w|gz'
- else:
- mode = 'w'
- archive = tarfile.open(name=self.tarname, mode=mode, fileobj=fileobj)
- archive.add(self.path, '')
- archive.close()
- fileobj.close()
-
- # Transfer it
- self.fp = open(self.tarname, 'rb')
-
- self.sendStatus({'header': "sending %s" % self.path})
-
- d = defer.Deferred()
- self._reactor.callLater(0, self._loop, d)
- def unpack(res):
- d1 = self.writer.callRemote("unpack")
- def unpack_err(f):
- self.rc = 1
- return f
- d1.addErrback(unpack_err)
- d1.addCallback(lambda ignored: res)
- return d1
- d.addCallback(unpack)
- d.addBoth(self.finished)
- return d
-
- def finished(self, res):
- self.fp.close()
- os.remove(self.tarname)
- return TransferCommand.finished(self, res)
-
-
-class SlaveFileDownloadCommand(TransferCommand):
- """
- Download a file from master to slave
- Arguments:
-
- - ['workdir']: base directory to use
- - ['slavedest']: name of the slave-side file to be created
- - ['reader']: RemoteReference to a transfer._FileReader object
- - ['maxsize']: max size (in bytes) of file to write
- - ['blocksize']: max size for each data block
- - ['mode']: access mode for the new file
- """
- debug = False
-
- def setup(self, args):
- self.workdir = args['workdir']
- self.filename = args['slavedest']
- self.reader = args['reader']
- self.bytes_remaining = args['maxsize']
- self.blocksize = args['blocksize']
- self.mode = args['mode']
- self.stderr = None
- self.rc = 0
-
- def start(self):
- if self.debug:
- log.msg('SlaveFileDownloadCommand starting')
-
- # Open file
- self.path = os.path.join(self.builder.basedir,
- self.workdir,
- os.path.expanduser(self.filename))
-
- dirname = os.path.dirname(self.path)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
-
- try:
- self.fp = open(self.path, 'wb')
- if self.debug:
- log.msg("Opened '%s' for download" % self.path)
- if self.mode is not None:
- # note: there is a brief window during which the new file
- # will have the buildslave's default (umask) mode before we
- # set the new one. Don't use this mode= feature to keep files
- # private: use the buildslave's umask for that instead. (it
- # is possible to call os.umask() before and after the open()
- # call, but cleaning up from exceptions properly is more of a
- # nuisance that way).
- os.chmod(self.path, self.mode)
- except IOError:
- # TODO: this still needs cleanup
- self.fp = None
- self.stderr = "Cannot open file '%s' for download" % self.path
- self.rc = 1
- if self.debug:
- log.msg("Cannot open file '%s' for download" % self.path)
-
- d = defer.Deferred()
- self._reactor.callLater(0, self._loop, d)
- def _close(res):
- # close the file, but pass through any errors from _loop
- d1 = self.reader.callRemote('close')
- d1.addErrback(log.err, 'while trying to close reader')
- d1.addCallback(lambda ignored: res)
- return d1
- d.addBoth(_close)
- d.addBoth(self.finished)
- return d
-
- def _loop(self, fire_when_done):
- d = defer.maybeDeferred(self._readBlock)
- def _done(finished):
- if finished:
- fire_when_done.callback(None)
- else:
- self._loop(fire_when_done)
- def _err(why):
- fire_when_done.errback(why)
- d.addCallbacks(_done, _err)
- return None
-
- def _readBlock(self):
- """Read a block of data from the remote reader."""
-
- if self.interrupted or self.fp is None:
- if self.debug:
- log.msg('SlaveFileDownloadCommand._readBlock(): end')
- return True
-
- length = self.blocksize
- if self.bytes_remaining is not None and length > self.bytes_remaining:
- length = self.bytes_remaining
-
- if length <= 0:
- if self.stderr is None:
- self.stderr = "Maximum filesize reached, truncating file '%s'" \
- % self.path
- self.rc = 1
- return True
- else:
- d = self.reader.callRemote('read', length)
- d.addCallback(self._writeData)
- return d
-
- def _writeData(self, data):
- if self.debug:
- log.msg('SlaveFileDownloadCommand._readBlock(): readlen=%d' %
- len(data))
- if len(data) == 0:
- return True
-
- if self.bytes_remaining is not None:
- self.bytes_remaining = self.bytes_remaining - len(data)
- assert self.bytes_remaining >= 0
- self.fp.write(data)
- return False
-
- def finished(self, res):
- if self.fp is not None:
- self.fp.close()
-
- return TransferCommand.finished(self, res)
-
-class SlaveDirectoryDownloadCommand(SlaveFileDownloadCommand):
- debug = False
-
- def setup(self, args):
- self.workdir = args['workdir']
-
- self.dirname = os.path.expanduser(args['slavedest'])
- self.reader = args['reader']
- self.bytes_remaining = args['maxsize']
- self.blocksize = args['blocksize']
- self.compress = args['compress']
- self.mode = args['mode']
- self.stderr = None
- self.rc = 0
-
- def start(self):
- if self.debug:
- log.msg('SlaveDirectoryDownloadCommand starting')
-
- if not os.path.exists(self.dirname):
- os.makedirs(self.dirname)
-
- try:
- fd, self.tarname = tempfile.mkstemp()
- self.fp = os.fdopen(fd, 'w')
- if self.debug:
- log.msg("Opened '%s' for download" % self.tarname)
- except IOError:
- # TODO: this still needs cleanup
- self.fp = None
- self.stderr = "Cannot open file '%s' for download" % self.tarname
- self.rc = 1
- if self.debug:
- log.msg("Cannot open file '%s' for download" % self.tarname)
-
- d = defer.Deferred()
- self._reactor.callLater(0, self._loop, d)
- def _close(res):
- # close the file, but pass through any errors from _loop
- d1 = self.reader.callRemote('close')
- d1.addErrback(log.err, 'while trying to close reader')
- d1.addCallback(lambda ignored: res)
- return d1
- d.addBoth(_close)
- d.addBoth(self.finished)
- return d
-
- def finished(self, res):
- if self.fp is not None:
- self.fp.close()
-
- # decompress
- if self.compress == 'bz2':
- mode='r|bz2'
- elif self.compress == 'gz':
- mode='r|gz'
- else:
- mode = 'r'
- if not hasattr(tarfile.TarFile, 'extractall'):
- tarfile.TarFile.extractall = _extractall
- archive = tarfile.open(name=self.tarname, mode=mode)
- archive.extractall(path=self.dirname)
- archive.close()
- os.remove(self.tarname)
-
- # note: there is a brief window during which the new file
- # will have the buildslave's default (umask) mode before we
- # set the new one. Don't use this mode= feature to keep files
- # private: use the buildslave's umask for that instead. (it
- # is possible to call os.umask() before and after the open()
- # call, but cleaning up from exceptions properly is more of a
- # nuisance that way).
- if self.mode is not None:
- for f in os.listdir(self.dirname):
- full_f = os.path.join(self.dirname, f)
- os.chmod(full_f, self.mode)
-
- return TransferCommand.finished(self, res)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/utils.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/utils.py
deleted file mode 100644
index 6483a597..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/utils.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-from twisted.python import log
-from twisted.python.procutils import which
-from twisted.python import runtime
-
-def getCommand(name):
- possibles = which(name)
- if not possibles:
- raise RuntimeError("Couldn't find executable for '%s'" % name)
- #
- # Under windows, if there is more than one executable "thing"
- # that matches (e.g. *.bat, *.cmd and *.exe), we not just use
- # the first in alphabet (*.bat/*.cmd) if there is a *.exe.
- # e.g. under MSysGit/Windows, there is both a git.cmd and a
- # git.exe on path, but we want the git.exe, since the git.cmd
- # does not seem to work properly with regard to errors raised
- # and catched in buildbot slave command (vcs.py)
- #
- if runtime.platformType == 'win32' and len(possibles) > 1:
- possibles_exe = which(name + ".exe")
- if possibles_exe:
- return possibles_exe[0]
- return possibles[0]
-
-# this just keeps pyflakes happy on non-Windows systems
-if runtime.platformType != 'win32':
- WindowsError = RuntimeError
-
-if runtime.platformType == 'win32':
- def rmdirRecursive(dir):
- """This is a replacement for shutil.rmtree that works better under
- windows. Thanks to Bear at the OSAF for the code."""
- if not os.path.exists(dir):
- return
-
- if os.path.islink(dir) or os.path.isfile(dir):
- os.remove(dir)
- return
-
- # Verify the directory is read/write/execute for the current user
- os.chmod(dir, 0700)
-
- # os.listdir below only returns a list of unicode filenames if the parameter is unicode
- # Thus, if a non-unicode-named dir contains a unicode filename, that filename will get garbled.
- # So force dir to be unicode.
- if not isinstance(dir, unicode):
- try:
- dir = unicode(dir, "utf-8")
- except:
- log.err("rmdirRecursive: decoding from UTF-8 failed (ignoring)")
-
- try:
- list = os.listdir(dir)
- except WindowsError, e:
- msg = ("rmdirRecursive: unable to listdir %s (%s). Trying to "
- "remove like a dir" % (dir, e.strerror.decode('mbcs')))
- log.msg(msg.encode('utf-8'))
- os.rmdir(dir)
- return
-
- for name in list:
- full_name = os.path.join(dir, name)
- # on Windows, if we don't have write permission we can't remove
- # the file/directory either, so turn that on
- if os.name == 'nt':
- if not os.access(full_name, os.W_OK):
- # I think this is now redundant, but I don't have an NT
- # machine to test on, so I'm going to leave it in place
- # -warner
- os.chmod(full_name, 0600)
-
- if os.path.islink(full_name):
- os.remove(full_name) # as suggested in bug #792
- elif os.path.isdir(full_name):
- rmdirRecursive(full_name)
- else:
- if os.path.isfile(full_name):
- os.chmod(full_name, 0700)
- os.remove(full_name)
- os.rmdir(dir)
-else:
- # use rmtree on POSIX
- import shutil
- rmdirRecursive = shutil.rmtree
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/exceptions.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/exceptions.py
deleted file mode 100644
index ab7aa62f..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/exceptions.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-class AbandonChain(Exception):
- """A series of chained steps can raise this exception to indicate that
- one of the intermediate RunProcesses has failed, such that there is no
- point in running the remainder. 'rc' should be the non-zero exit code of
- the failing ShellCommand."""
-
- def __repr__(self):
- return "<AbandonChain rc=%s>" % self.args[0]
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/interfaces.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/interfaces.py
deleted file mode 100644
index fe2eaad0..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/interfaces.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-from zope.interface import Interface
-
-class ISlaveCommand(Interface):
- """This interface is implemented by all of the buildslave's Command
- subclasses. It specifies how the buildslave can start, interrupt, and
- query the various Commands running on behalf of the buildmaster."""
-
- def __init__(builder, stepId, args):
- """Create the Command. 'builder' is a reference to the parent
- buildbot.bot.SlaveBuilder instance, which will be used to send status
- updates (by calling builder.sendStatus). 'stepId' is a random string
- which helps correlate slave logs with the master. 'args' is a dict of
- arguments that comes from the master-side BuildStep, with contents
- that are specific to the individual Command subclass.
-
- This method is not intended to be subclassed."""
-
- def setup(args):
- """This method is provided for subclasses to override, to extract
- parameters from the 'args' dictionary. The default implemention does
- nothing. It will be called from __init__"""
-
- def start():
- """Begin the command, and return a Deferred.
-
- While the command runs, it should send status updates to the
- master-side BuildStep by calling self.sendStatus(status). The
- 'status' argument is typically a dict with keys like 'stdout',
- 'stderr', and 'rc'.
-
- When the step completes, it should fire the Deferred (the results are
- not used). If an exception occurs during execution, it may also
- errback the deferred, however any reasonable errors should be trapped
- and indicated with a non-zero 'rc' status rather than raising an
- exception. Exceptions should indicate problems within the buildbot
- itself, not problems in the project being tested.
-
- """
-
- def interrupt():
- """This is called to tell the Command that the build is being stopped
- and therefore the command should be terminated as quickly as
- possible. The command may continue to send status updates, up to and
- including an 'rc' end-of-command update (which should indicate an
- error condition). The Command's deferred should still be fired when
- the command has finally completed.
-
- If the build is being stopped because the slave it shutting down or
- because the connection to the buildmaster has been lost, the status
- updates will simply be discarded. The Command does not need to be
- aware of this.
-
- Child shell processes should be killed. Simple ShellCommand classes
- can just insert a header line indicating that the process will be
- killed, then os.kill() the child."""
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/__init__.py
deleted file mode 100644
index a71d3868..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/__init__.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import twisted
-from twisted.python import versions
-
-def patch_bug4881():
- # this patch doesn't apply (or even import!) on Windows
- import sys
- if sys.platform == 'win32':
- return
-
- # this bug was only present in Twisted-10.2.0
- if twisted.version == versions.Version('twisted', 10, 2, 0):
- from buildslave.monkeypatches import bug4881
- bug4881.patch()
-
-def patch_bug5079():
- # this bug will hopefully be patched in Twisted-12.0.0
- if twisted.version < versions.Version('twisted', 12, 0, 0):
- from buildslave.monkeypatches import bug5079
- bug5079.patch()
-
-def patch_testcase_assert_raises_regexp():
- # pythons before 2.7 does not have TestCase.assertRaisesRegexp() method
- # add our local implementation if needed
- import sys
- if sys.version_info[:2] < (2,7):
- from buildslave.monkeypatches import testcase_assert
- testcase_assert.patch()
-
-def patch_all(for_tests=False):
- patch_bug4881()
- patch_bug5079()
-
- if for_tests:
- patch_testcase_assert_raises_regexp()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug4881.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug4881.py
deleted file mode 100644
index aaa4bba3..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug4881.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# coding=utf-8
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-from twisted.internet import process
-from twisted.python import log
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/4881")
- process._listOpenFDs = _listOpenFDs
-
-#############################################################################
-# Everything below this line was taken verbatim from Twisted, except as
-# annotated.
-
-########
-# r31474:trunk/LICENSE
-
-# Copyright (c) 2001-2010
-# Allen Short
-# Andy Gayton
-# Andrew Bennetts
-# Antoine Pitrou
-# Apple Computer, Inc.
-# Benjamin Bruheim
-# Bob Ippolito
-# Canonical Limited
-# Christopher Armstrong
-# David Reid
-# Donovan Preston
-# Eric Mangold
-# Eyal Lotem
-# Itamar Shtull-Trauring
-# James Knight
-# Jason A. Mobarak
-# Jean-Paul Calderone
-# Jessica McKellar
-# Jonathan Jacobs
-# Jonathan Lange
-# Jonathan D. Simms
-# Jürgen Hermann
-# Kevin Horn
-# Kevin Turner
-# Mary Gardiner
-# Matthew Lefkowitz
-# Massachusetts Institute of Technology
-# Moshe Zadka
-# Paul Swartz
-# Pavel Pergamenshchik
-# Ralph Meijer
-# Sean Riley
-# Software Freedom Conservancy
-# Travis B. Hartwell
-# Thijs Triemstra
-# Thomas Herve
-# Timothy Allen
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-########
-# r31474:trunk/twisted/internet/process.py
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-class _FDDetector(object):
- """
- This class contains the logic necessary to decide which of the available
- system techniques should be used to detect the open file descriptors for
- the current process. The chosen technique gets monkey-patched into the
- _listOpenFDs method of this class so that the detection only needs to occur
- once.
-
- @ivars listdir: The implementation of listdir to use. This gets overwritten
- by the test cases.
- @ivars getpid: The implementation of getpid to use, returns the PID of the
- running process.
- @ivars openfile: The implementation of open() to use, by default the Python
- builtin.
- """
- # So that we can unit test this
- listdir = os.listdir
- getpid = os.getpid
- openfile = open
-
-
- def _listOpenFDs(self):
- """
- Figure out which implementation to use, then run it.
- """
- self._listOpenFDs = self._getImplementation()
- return self._listOpenFDs()
-
-
- def _getImplementation(self):
- """
- Check if /dev/fd works, if so, use that. Otherwise, check if
- /proc/%d/fd exists, if so use that.
-
- Otherwise, ask resource.getrlimit, if that throws an exception, then
- fallback to _fallbackFDImplementation.
- """
- try:
- self.listdir("/dev/fd")
- if self._checkDevFDSanity(): # FreeBSD support :-)
- return self._devFDImplementation
- else:
- return self._fallbackFDImplementation
- except:
- try:
- self.listdir("/proc/%d/fd" % (self.getpid(),))
- return self._procFDImplementation
- except:
- try:
- self._resourceFDImplementation() # Imports resource
- return self._resourceFDImplementation
- except:
- return self._fallbackFDImplementation
-
-
- def _checkDevFDSanity(self):
- """
- Returns true iff opening a file modifies the fds visible
- in /dev/fd, as it should on a sane platform.
- """
- start = self.listdir("/dev/fd")
- self.openfile("/dev/null", "r") # changed in Buildbot to hush pyflakes
- end = self.listdir("/dev/fd")
- return start != end
-
-
- def _devFDImplementation(self):
- """
- Simple implementation for systems where /dev/fd actually works.
- See: http://www.freebsd.org/cgi/man.cgi?fdescfs
- """
- dname = "/dev/fd"
- result = [int(fd) for fd in os.listdir(dname)]
- return result
-
-
- def _procFDImplementation(self):
- """
- Simple implementation for systems where /proc/pid/fd exists (we assume
- it works).
- """
- dname = "/proc/%d/fd" % (os.getpid(),)
- return [int(fd) for fd in os.listdir(dname)]
-
-
- def _resourceFDImplementation(self):
- """
- Fallback implementation where the resource module can inform us about
- how many FDs we can expect.
-
- Note that on OS-X we expect to be using the /dev/fd implementation.
- """
- import resource
- maxfds = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + 1
- # OS-X reports 9223372036854775808. That's a lot of fds
- # to close
- if maxfds > 1024:
- maxfds = 1024
- return xrange(maxfds)
-
-
- def _fallbackFDImplementation(self):
- """
- Fallback-fallback implementation where we just assume that we need to
- close 256 FDs.
- """
- maxfds = 256
- return xrange(maxfds)
-
-
-detector = _FDDetector()
-
-def _listOpenFDs():
- """
- Use the global detector object to figure out which FD implementation to
- use.
- """
- return detector._listOpenFDs()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug5079.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug5079.py
deleted file mode 100644
index 30202323..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/bug5079.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.spread import pb
-from twisted.python import log
-from twisted.spread.interfaces import IJellyable
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/5079")
- if not hasattr(pb, '_JellyableAvatarMixin'):
- log.msg("..patch not applicable; please file a bug at buildbot.net")
- else:
- pb._JellyableAvatarMixin._cbLogin = _fixed_cbLogin
-
-def _fixed_cbLogin(self, (interface, avatar, logout)):
- """
- Ensure that the avatar to be returned to the client is jellyable and
- set up disconnection notification to call the realm's logout object.
- """
- if not IJellyable.providedBy(avatar):
- avatar = pb.AsReferenceable(avatar, "perspective")
-
- puid = avatar.processUniqueID()
-
- # only call logout once, whether the connection is dropped (disconnect)
- # or a logout occurs (cleanup), and be careful to drop the reference to
- # it in either case
- logout = [ logout ]
- def maybeLogout():
- if not logout: return
- fn = logout[0]
- del logout[0]
- fn()
- self.broker._localCleanup[puid] = maybeLogout
- self.broker.notifyOnDisconnect(maybeLogout)
-
- return avatar
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/testcase_assert.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/testcase_assert.py
deleted file mode 100644
index 765e8a3a..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/monkeypatches/testcase_assert.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import re
-import unittest
-
-
-def _assertRaisesRegexp(self, expected_exception, expected_regexp,
- callable_obj, *args, **kwds):
- """
- Asserts that the message in a raised exception matches a regexp.
-
- This is a simple clone of unittest.TestCase.assertRaisesRegexp() method
- introduced in python 2.7. The goal for this function is to behave exactly
- as assertRaisesRegexp() in standard library.
- """
- exception = None
- try:
- callable_obj(*args, **kwds)
- except expected_exception, ex: # let unexpected exceptions pass through
- exception = ex
-
- if exception == None:
- self.fail("%s not raised" % str(expected_exception.__name__))
-
- if isinstance(expected_regexp, basestring):
- expected_regexp = re.compile(expected_regexp)
-
- if not expected_regexp.search(str(exception)):
- self.fail('"%s" does not match "%s"' %
- (expected_regexp.pattern, str(exception)))
-
-
-def patch():
- unittest.TestCase.assertRaisesRegexp = _assertRaisesRegexp
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/pbutil.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/pbutil.py
deleted file mode 100644
index 2792e2f2..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/pbutil.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-"""Base classes handy for use with PB clients.
-"""
-
-from twisted.spread import pb
-
-from twisted.spread.pb import PBClientFactory
-from twisted.internet import protocol, reactor
-from twisted.python import log
-from twisted.cred import error
-
-class ReconnectingPBClientFactory(PBClientFactory,
- protocol.ReconnectingClientFactory):
- """Reconnecting client factory for PB brokers.
-
- Like PBClientFactory, but if the connection fails or is lost, the factory
- will attempt to reconnect.
-
- Instead of using f.getRootObject (which gives a Deferred that can only
- be fired once), override the gotRootObject method.
-
- Instead of using the newcred f.login (which is also one-shot), call
- f.startLogin() with the credentials and client, and override the
- gotPerspective method.
-
- gotRootObject and gotPerspective will be called each time the object is
- received (once per successful connection attempt). You will probably want
- to use obj.notifyOnDisconnect to find out when the connection is lost.
-
- If an authorization error occurs, failedToGetPerspective() will be
- invoked.
-
- To use me, subclass, then hand an instance to a connector (like
- TCPClient).
- """
-
- # hung connections wait for a relatively long time, since a busy master may
- # take a while to get back to us.
- hungConnectionTimer = None
- HUNG_CONNECTION_TIMEOUT = 120
-
- def clientConnectionFailed(self, connector, reason):
- PBClientFactory.clientConnectionFailed(self, connector, reason)
- if self.continueTrying:
- self.connector = connector
- self.retry()
-
- def clientConnectionLost(self, connector, reason):
- PBClientFactory.clientConnectionLost(self, connector, reason,
- reconnecting=True)
- RCF = protocol.ReconnectingClientFactory
- RCF.clientConnectionLost(self, connector, reason)
-
- def startedConnecting(self, connector):
- self.startHungConnectionTimer(connector)
-
- def clientConnectionMade(self, broker):
- self.resetDelay()
- PBClientFactory.clientConnectionMade(self, broker)
- self.doLogin(self._root, broker)
- self.gotRootObject(self._root)
-
- # newcred methods
-
- def login(self, *args):
- raise RuntimeError, "login is one-shot: use startLogin instead"
-
- def startLogin(self, credentials, client=None):
- self._credentials = credentials
- self._client = client
-
- def doLogin(self, root, broker):
- # newcred login()
- d = self._cbSendUsername(root, self._credentials.username,
- self._credentials.password, self._client)
- d.addCallbacks(self.gotPerspective, self.failedToGetPerspective,
- errbackArgs=(broker,))
-
- # timer for hung connections
-
- def startHungConnectionTimer(self, connector):
- self.stopHungConnectionTimer()
- def hungConnection():
- log.msg("connection attempt timed out (is the port number correct?)")
- self.hungConnectionTimer = None
- connector.disconnect()
- # (this will trigger the retry)
- self.hungConnectionTimer = reactor.callLater(self.HUNG_CONNECTION_TIMEOUT, hungConnection)
-
- def stopHungConnectionTimer(self):
- if self.hungConnectionTimer:
- self.hungConnectionTimer.cancel()
- self.hungConnectionTimer = None
-
- # methods to override
-
- def gotPerspective(self, perspective):
- """The remote avatar or perspective (obtained each time this factory
- connects) is now available."""
- self.stopHungConnectionTimer()
-
- def gotRootObject(self, root):
- """The remote root object (obtained each time this factory connects)
- is now available. This method will be called each time the connection
- is established and the object reference is retrieved."""
- self.stopHungConnectionTimer()
-
- def failedToGetPerspective(self, why, broker):
- """The login process failed, most likely because of an authorization
- failure (bad password), but it is also possible that we lost the new
- connection before we managed to send our credentials.
- """
- log.msg("ReconnectingPBClientFactory.failedToGetPerspective")
- self.stopHungConnectionTimer()
- # put something useful in the logs
- if why.check(pb.PBConnectionLost):
- log.msg("we lost the brand-new connection")
- # fall through
- elif why.check(error.UnauthorizedLogin):
- log.msg("unauthorized login; check slave name and password")
- # fall through
- else:
- log.err(why, 'While trying to connect:')
- self.stopTrying()
- reactor.stop()
- return
-
- # lose the current connection, which will trigger a retry
- broker.transport.loseConnection()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/runprocess.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/runprocess.py
deleted file mode 100644
index 7dd8dc7b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/runprocess.py
+++ /dev/null
@@ -1,859 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-"""
-Support for running 'shell commands'
-"""
-
-import sys
-import os
-import signal
-import types
-import re
-import subprocess
-import traceback
-import stat
-from collections import deque
-from tempfile import NamedTemporaryFile
-
-from twisted.python import runtime, log
-from twisted.python.win32 import quoteArguments
-from twisted.internet import reactor, defer, protocol, task, error
-
-from buildslave import util
-from buildslave.exceptions import AbandonChain
-
-if runtime.platformType == 'posix':
- from twisted.internet.process import Process
-
-def shell_quote(cmd_list):
- # attempt to quote cmd_list such that a shell will properly re-interpret
- # it. The pipes module is only available on UNIX, and Windows "shell"
- # quoting is indescribably convoluted - so much so that it's not clear it's
- # reversible. Also, the quote function is undocumented (although it looks
- # like it will be documentd soon: http://bugs.python.org/issue9723).
- # Finally, it has a nasty bug in some versions where an empty string is not
- # quoted.
- #
- # So:
- # - use pipes.quote on UNIX, handling '' as a special case
- # - use Python's repr() on Windows, as a best effort
- if runtime.platformType == 'win32':
- return " ".join([ `e` for e in cmd_list ])
- else:
- import pipes
- def quote(e):
- if not e:
- return '""'
- return pipes.quote(e)
- return " ".join([ quote(e) for e in cmd_list ])
-
-class LogFileWatcher:
- POLL_INTERVAL = 2
-
- def __init__(self, command, name, logfile, follow=False):
- self.command = command
- self.name = name
- self.logfile = logfile
-
- log.msg("LogFileWatcher created to watch %s" % logfile)
- # we are created before the ShellCommand starts. If the logfile we're
- # supposed to be watching already exists, record its size and
- # ctime/mtime so we can tell when it starts to change.
- self.old_logfile_stats = self.statFile()
- self.started = False
-
- # follow the file, only sending back lines
- # added since we started watching
- self.follow = follow
-
- # every 2 seconds we check on the file again
- self.poller = task.LoopingCall(self.poll)
-
- def start(self):
- self.poller.start(self.POLL_INTERVAL).addErrback(self._cleanupPoll)
-
- def _cleanupPoll(self, err):
- log.err(err, msg="Polling error")
- self.poller = None
-
- def stop(self):
- self.poll()
- if self.poller is not None:
- self.poller.stop()
- if self.started:
- self.f.close()
-
- def statFile(self):
- if os.path.exists(self.logfile):
- s = os.stat(self.logfile)
- return (s[stat.ST_CTIME], s[stat.ST_MTIME], s[stat.ST_SIZE])
- return None
-
- def poll(self):
- if not self.started:
- s = self.statFile()
- if s == self.old_logfile_stats:
- return # not started yet
- if not s:
- # the file was there, but now it's deleted. Forget about the
- # initial state, clearly the process has deleted the logfile
- # in preparation for creating a new one.
- self.old_logfile_stats = None
- return # no file to work with
- self.f = open(self.logfile, "rb")
- # if we only want new lines, seek to
- # where we stat'd so we only find new
- # lines
- if self.follow:
- self.f.seek(s[2], 0)
- self.started = True
- self.f.seek(self.f.tell(), 0)
- while True:
- data = self.f.read(10000)
- if not data:
- return
- self.command.addLogfile(self.name, data)
-
-
-if runtime.platformType == 'posix':
- class ProcGroupProcess(Process):
- """Simple subclass of Process to also make the spawned process a process
- group leader, so we can kill all members of the process group."""
-
- def _setupChild(self, *args, **kwargs):
- Process._setupChild(self, *args, **kwargs)
-
- # this will cause the child to be the leader of its own process group;
- # it's also spelled setpgrp() on BSD, but this spelling seems to work
- # everywhere
- os.setpgid(0, 0)
-
-
-class RunProcessPP(protocol.ProcessProtocol):
- debug = False
-
- def __init__(self, command):
- self.command = command
- self.pending_stdin = ""
- self.stdin_finished = False
- self.killed = False
-
- def setStdin(self, data):
- assert not self.connected
- self.pending_stdin = data
-
- def connectionMade(self):
- if self.debug:
- log.msg("RunProcessPP.connectionMade")
-
- if self.command.useProcGroup:
- if self.debug:
- log.msg(" recording pid %d as subprocess pgid"
- % (self.transport.pid,))
- self.transport.pgid = self.transport.pid
-
- if self.pending_stdin:
- if self.debug: log.msg(" writing to stdin")
- self.transport.write(self.pending_stdin)
- if self.debug: log.msg(" closing stdin")
- self.transport.closeStdin()
-
- def outReceived(self, data):
- if self.debug:
- log.msg("RunProcessPP.outReceived")
- self.command.addStdout(data)
-
- def errReceived(self, data):
- if self.debug:
- log.msg("RunProcessPP.errReceived")
- self.command.addStderr(data)
-
- def processEnded(self, status_object):
- if self.debug:
- log.msg("RunProcessPP.processEnded", status_object)
- # status_object is a Failure wrapped around an
- # error.ProcessTerminated or and error.ProcessDone.
- # requires twisted >= 1.0.4 to overcome a bug in process.py
- sig = status_object.value.signal
- rc = status_object.value.exitCode
-
- # sometimes, even when we kill a process, GetExitCodeProcess will still return
- # a zero exit status. So we force it. See
- # http://stackoverflow.com/questions/2061735/42-passed-to-terminateprocess-sometimes-getexitcodeprocess-returns-0
- if self.killed and rc == 0:
- log.msg("process was killed, but exited with status 0; faking a failure")
- # windows returns '1' even for signalled failures, while POSIX returns -1
- if runtime.platformType == 'win32':
- rc = 1
- else:
- rc = -1
- self.command.finished(sig, rc)
-
-
-class RunProcess:
- """
- This is a helper class, used by slave commands to run programs in a child
- shell.
- """
-
- notreally = False
- BACKUP_TIMEOUT = 5
- interruptSignal = "KILL"
- CHUNK_LIMIT = 128*1024
-
- # Don't send any data until at least BUFFER_SIZE bytes have been collected
- # or BUFFER_TIMEOUT elapsed
- BUFFER_SIZE = 64*1024
- BUFFER_TIMEOUT = 5
-
- # For sending elapsed time:
- startTime = None
- elapsedTime = None
-
- # For scheduling future events
- _reactor = reactor
-
- # I wish we had easy access to CLOCK_MONOTONIC in Python:
- # http://www.opengroup.org/onlinepubs/000095399/functions/clock_getres.html
- # Then changes to the system clock during a run wouldn't effect the "elapsed
- # time" results.
-
- def __init__(self, builder, command,
- workdir, environ=None,
- sendStdout=True, sendStderr=True, sendRC=True,
- timeout=None, maxTime=None, initialStdin=None,
- keepStdout=False, keepStderr=False,
- logEnviron=True, logfiles={}, usePTY="slave-config",
- useProcGroup=True):
- """
-
- @param keepStdout: if True, we keep a copy of all the stdout text
- that we've seen. This copy is available in
- self.stdout, which can be read after the command
- has finished.
- @param keepStderr: same, for stderr
-
- @param usePTY: "slave-config" -> use the SlaveBuilder's usePTY;
- otherwise, true to use a PTY, false to not use a PTY.
-
- @param useProcGroup: (default True) use a process group for non-PTY
- process invocations
- """
-
- self.builder = builder
-
- # We need to take unicode commands and arguments and encode them using
- # the appropriate encoding for the slave. This is mostly platform
- # specific, but can be overridden in the slave's buildbot.tac file.
- #
- # Encoding the command line here ensures that the called executables
- # receive arguments as bytestrings encoded with an appropriate
- # platform-specific encoding. It also plays nicely with twisted's
- # spawnProcess which checks that arguments are regular strings or
- # unicode strings that can be encoded as ascii (which generates a
- # warning).
- def to_str(cmd):
- if isinstance(cmd, (tuple, list)):
- for i, a in enumerate(cmd):
- if isinstance(a, unicode):
- cmd[i] = a.encode(self.builder.unicode_encoding)
- elif isinstance(cmd, unicode):
- cmd = cmd.encode(self.builder.unicode_encoding)
- return cmd
-
- self.command = to_str(util.Obfuscated.get_real(command))
- self.fake_command = to_str(util.Obfuscated.get_fake(command))
-
- self.sendStdout = sendStdout
- self.sendStderr = sendStderr
- self.sendRC = sendRC
- self.logfiles = logfiles
- self.workdir = workdir
- self.process = None
- if not os.path.exists(workdir):
- os.makedirs(workdir)
- if environ:
- for key, v in environ.iteritems():
- if isinstance(v, list):
- # Need to do os.pathsep translation. We could either do that
- # by replacing all incoming ':'s with os.pathsep, or by
- # accepting lists. I like lists better.
- # If it's not a string, treat it as a sequence to be
- # turned in to a string.
- environ[key] = os.pathsep.join(environ[key])
-
- if environ.has_key('PYTHONPATH'):
- environ['PYTHONPATH'] += os.pathsep + "${PYTHONPATH}"
-
- # do substitution on variable values matching pattern: ${name}
- p = re.compile('\${([0-9a-zA-Z_]*)}')
- def subst(match):
- return os.environ.get(match.group(1), "")
- newenv = {}
- for key in os.environ.keys():
- # setting a key to None will delete it from the slave environment
- if key not in environ or environ[key] is not None:
- newenv[key] = os.environ[key]
- for key, v in environ.iteritems():
- if v is not None:
- if not isinstance(v, basestring):
- raise RuntimeError("'env' values must be strings or "
- "lists; key '%s' is incorrect" % (key,))
- newenv[key] = p.sub(subst, v)
-
- self.environ = newenv
- else: # not environ
- self.environ = os.environ.copy()
- self.initialStdin = initialStdin
- self.logEnviron = logEnviron
- self.timeout = timeout
- self.timer = None
- self.maxTime = maxTime
- self.maxTimer = None
- self.keepStdout = keepStdout
- self.keepStderr = keepStderr
-
- self.buffered = deque()
- self.buflen = 0
- self.buftimer = None
-
- if usePTY == "slave-config":
- self.usePTY = self.builder.usePTY
- else:
- self.usePTY = usePTY
-
- # usePTY=True is a convenience for cleaning up all children and
- # grandchildren of a hung command. Fall back to usePTY=False on systems
- # and in situations where ptys cause problems. PTYs are posix-only,
- # and for .closeStdin to matter, we must use a pipe, not a PTY
- if runtime.platformType != "posix" or initialStdin is not None:
- if self.usePTY and usePTY != "slave-config":
- self.sendStatus({'header': "WARNING: disabling usePTY for this command"})
- self.usePTY = False
-
- # use an explicit process group on POSIX, noting that usePTY always implies
- # a process group.
- if runtime.platformType != 'posix':
- useProcGroup = False
- elif self.usePTY:
- useProcGroup = True
- self.useProcGroup = useProcGroup
-
- self.logFileWatchers = []
- for name,filevalue in self.logfiles.items():
- filename = filevalue
- follow = False
-
- # check for a dictionary of options
- # filename is required, others are optional
- if type(filevalue) == dict:
- filename = filevalue['filename']
- follow = filevalue.get('follow', False)
-
- w = LogFileWatcher(self, name,
- os.path.join(self.workdir, filename),
- follow=follow)
- self.logFileWatchers.append(w)
-
- def __repr__(self):
- return "<%s '%s'>" % (self.__class__.__name__, self.fake_command)
-
- def sendStatus(self, status):
- self.builder.sendUpdate(status)
-
- def start(self):
- # return a Deferred which fires (with the exit code) when the command
- # completes
- if self.keepStdout:
- self.stdout = ""
- if self.keepStderr:
- self.stderr = ""
- self.deferred = defer.Deferred()
- try:
- self._startCommand()
- except:
- log.msg("error in RunProcess._startCommand")
- log.err()
- self._addToBuffers('stderr', "error in RunProcess._startCommand\n")
- self._addToBuffers('stderr', traceback.format_exc())
- self._sendBuffers()
- # pretend it was a shell error
- self.deferred.errback(AbandonChain(-1))
- return self.deferred
-
- def _startCommand(self):
- # ensure workdir exists
- if not os.path.isdir(self.workdir):
- os.makedirs(self.workdir)
- log.msg("RunProcess._startCommand")
- if self.notreally:
- self._addToBuffers('header', "command '%s' in dir %s" % \
- (self.fake_command, self.workdir))
- self._addToBuffers('header', "(not really)\n")
- self.finished(None, 0)
- return
-
- self.pp = RunProcessPP(self)
-
- self.using_comspec = False
- if type(self.command) in types.StringTypes:
- if runtime.platformType == 'win32':
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += [self.command]
- self.using_comspec = True
- else:
- # for posix, use /bin/sh. for other non-posix, well, doesn't
- # hurt to try
- argv = ['/bin/sh', '-c', self.command]
- display = self.fake_command
- else:
- # On windows, CreateProcess requires an absolute path to the executable.
- # When we call spawnProcess below, we pass argv[0] as the executable.
- # So, for .exe's that we have absolute paths to, we can call directly
- # Otherwise, we should run under COMSPEC (usually cmd.exe) to
- # handle path searching, etc.
- if runtime.platformType == 'win32' and not \
- (self.command[0].lower().endswith(".exe") and os.path.isabs(self.command[0])):
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += list(self.command)
- self.using_comspec = True
- else:
- argv = self.command
- # Attempt to format this for use by a shell, although the process isn't perfect
- display = shell_quote(self.fake_command)
-
- # $PWD usually indicates the current directory; spawnProcess may not
- # update this value, though, so we set it explicitly here. This causes
- # weird problems (bug #456) on msys, though..
- if not self.environ.get('MACHTYPE', None) == 'i686-pc-msys':
- self.environ['PWD'] = os.path.abspath(self.workdir)
-
- # self.stdin is handled in RunProcessPP.connectionMade
-
- log.msg(" " + display)
- self._addToBuffers('header', display+"\n")
-
- # then comes the secondary information
- msg = " in dir %s" % (self.workdir,)
- if self.timeout:
- if self.timeout == 1:
- unit = "sec"
- else:
- unit = "secs"
- msg += " (timeout %d %s)" % (self.timeout, unit)
- if self.maxTime:
- if self.maxTime == 1:
- unit = "sec"
- else:
- unit = "secs"
- msg += " (maxTime %d %s)" % (self.maxTime, unit)
- log.msg(" " + msg)
- self._addToBuffers('header', msg+"\n")
-
- msg = " watching logfiles %s" % (self.logfiles,)
- log.msg(" " + msg)
- self._addToBuffers('header', msg+"\n")
-
- # then the obfuscated command array for resolving unambiguity
- msg = " argv: %s" % (self.fake_command,)
- log.msg(" " + msg)
- self._addToBuffers('header', msg+"\n")
-
- # then the environment, since it sometimes causes problems
- if self.logEnviron:
- msg = " environment:\n"
- env_names = self.environ.keys()
- env_names.sort()
- for name in env_names:
- msg += " %s=%s\n" % (name, self.environ[name])
- log.msg(" environment: %s" % (self.environ,))
- self._addToBuffers('header', msg)
-
- if self.initialStdin:
- msg = " writing %d bytes to stdin" % len(self.initialStdin)
- log.msg(" " + msg)
- self._addToBuffers('header', msg+"\n")
-
- msg = " using PTY: %s" % bool(self.usePTY)
- log.msg(" " + msg)
- self._addToBuffers('header', msg+"\n")
-
- # put data into stdin and close it, if necessary. This will be
- # buffered until connectionMade is called
- if self.initialStdin:
- self.pp.setStdin(self.initialStdin)
-
- self.startTime = util.now(self._reactor)
-
- # start the process
-
- self.process = self._spawnProcess(
- self.pp, argv[0], argv,
- self.environ,
- self.workdir,
- usePTY=self.usePTY)
-
- # set up timeouts
-
- if self.timeout:
- self.timer = self._reactor.callLater(self.timeout, self.doTimeout)
-
- if self.maxTime:
- self.maxTimer = self._reactor.callLater(self.maxTime, self.doMaxTimeout)
-
- for w in self.logFileWatchers:
- w.start()
-
- def _spawnProcess(self, processProtocol, executable, args=(), env={},
- path=None, uid=None, gid=None, usePTY=False, childFDs=None):
- """private implementation of reactor.spawnProcess, to allow use of
- L{ProcGroupProcess}"""
-
- # use the ProcGroupProcess class, if available
- if runtime.platformType == 'posix':
- if self.useProcGroup and not usePTY:
- return ProcGroupProcess(reactor, executable, args, env, path,
- processProtocol, uid, gid, childFDs)
-
- # fall back
- if self.using_comspec:
- return self._spawnAsBatch(processProtocol, executable, args, env,
- path, usePTY=usePTY)
- else:
- return reactor.spawnProcess(processProtocol, executable, args, env,
- path, usePTY=usePTY)
-
- def _spawnAsBatch(self, processProtocol, executable, args, env,
- path, usePTY):
- """A cheat that routes around the impedance mismatch between
- twisted and cmd.exe with respect to escaping quotes"""
-
- tf = NamedTemporaryFile(dir='.',suffix=".bat",delete=False)
- #echo off hides this cheat from the log files.
- tf.write( "@echo off\n" )
- if type(self.command) in types.StringTypes:
- tf.write( self.command )
- else:
- def maybe_escape_pipes(arg):
- if arg != '|':
- return arg.replace('|','^|')
- else:
- return '|'
- cmd = [maybe_escape_pipes(arg) for arg in self.command]
- tf.write( quoteArguments(cmd) )
- tf.close()
-
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += [tf.name]
-
- def unlink_temp(result):
- os.unlink(tf.name)
- return result
- self.deferred.addBoth(unlink_temp)
-
- return reactor.spawnProcess(processProtocol, executable, argv, env,
- path, usePTY=usePTY)
-
- def _chunkForSend(self, data):
- """
- limit the chunks that we send over PB to 128k, since it has a hardwired
- string-size limit of 640k.
- """
- LIMIT = self.CHUNK_LIMIT
- for i in range(0, len(data), LIMIT):
- yield data[i:i+LIMIT]
-
- def _collapseMsg(self, msg):
- """
- Take msg, which is a dictionary of lists of output chunks, and
- concatentate all the chunks into a single string
- """
- retval = {}
- for log in msg:
- data = "".join(msg[log])
- if isinstance(log, tuple) and log[0] == 'log':
- retval['log'] = (log[1], data)
- else:
- retval[log] = data
- return retval
-
- def _sendMessage(self, msg):
- """
- Collapse and send msg to the master
- """
- if not msg:
- return
- msg = self._collapseMsg(msg)
- self.sendStatus(msg)
-
- def _bufferTimeout(self):
- self.buftimer = None
- self._sendBuffers()
-
- def _sendBuffers(self):
- """
- Send all the content in our buffers.
- """
- msg = {}
- msg_size = 0
- lastlog = None
- logdata = []
- while self.buffered:
- # Grab the next bits from the buffer
- logname, data = self.buffered.popleft()
-
- # If this log is different than the last one, then we have to send
- # out the message so far. This is because the message is
- # transferred as a dictionary, which makes the ordering of keys
- # unspecified, and makes it impossible to interleave data from
- # different logs. A future enhancement could be to change the
- # master to support a list of (logname, data) tuples instead of a
- # dictionary.
- # On our first pass through this loop lastlog is None
- if lastlog is None:
- lastlog = logname
- elif logname != lastlog:
- self._sendMessage(msg)
- msg = {}
- msg_size = 0
- lastlog = logname
-
- logdata = msg.setdefault(logname, [])
-
- # Chunkify the log data to make sure we're not sending more than
- # CHUNK_LIMIT at a time
- for chunk in self._chunkForSend(data):
- if len(chunk) == 0: continue
- logdata.append(chunk)
- msg_size += len(chunk)
- if msg_size >= self.CHUNK_LIMIT:
- # We've gone beyond the chunk limit, so send out our
- # message. At worst this results in a message slightly
- # larger than (2*CHUNK_LIMIT)-1
- self._sendMessage(msg)
- msg = {}
- logdata = msg.setdefault(logname, [])
- msg_size = 0
- self.buflen = 0
- if logdata:
- self._sendMessage(msg)
- if self.buftimer:
- if self.buftimer.active():
- self.buftimer.cancel()
- self.buftimer = None
-
- def _addToBuffers(self, logname, data):
- """
- Add data to the buffer for logname
- Start a timer to send the buffers if BUFFER_TIMEOUT elapses.
- If adding data causes the buffer size to grow beyond BUFFER_SIZE, then
- the buffers will be sent.
- """
- n = len(data)
-
- self.buflen += n
- self.buffered.append((logname, data))
- if self.buflen > self.BUFFER_SIZE:
- self._sendBuffers()
- elif not self.buftimer:
- self.buftimer = self._reactor.callLater(self.BUFFER_TIMEOUT, self._bufferTimeout)
-
- def addStdout(self, data):
- if self.sendStdout:
- self._addToBuffers('stdout', data)
-
- if self.keepStdout:
- self.stdout += data
- if self.timer:
- self.timer.reset(self.timeout)
-
- def addStderr(self, data):
- if self.sendStderr:
- self._addToBuffers('stderr', data)
-
- if self.keepStderr:
- self.stderr += data
- if self.timer:
- self.timer.reset(self.timeout)
-
- def addLogfile(self, name, data):
- self._addToBuffers( ('log', name), data)
-
- if self.timer:
- self.timer.reset(self.timeout)
-
- def finished(self, sig, rc):
- self.elapsedTime = util.now(self._reactor) - self.startTime
- log.msg("command finished with signal %s, exit code %s, elapsedTime: %0.6f" % (sig,rc,self.elapsedTime))
- for w in self.logFileWatchers:
- # this will send the final updates
- w.stop()
- self._sendBuffers()
- if sig is not None:
- rc = -1
- if self.sendRC:
- if sig is not None:
- self.sendStatus(
- {'header': "process killed by signal %d\n" % sig})
- self.sendStatus({'rc': rc})
- self.sendStatus({'header': "elapsedTime=%0.6f\n" % self.elapsedTime})
- if self.timer:
- self.timer.cancel()
- self.timer = None
- if self.maxTimer:
- self.maxTimer.cancel()
- self.maxTimer = None
- if self.buftimer:
- self.buftimer.cancel()
- self.buftimer = None
- d = self.deferred
- self.deferred = None
- if d:
- d.callback(rc)
- else:
- log.msg("Hey, command %s finished twice" % self)
-
- def failed(self, why):
- self._sendBuffers()
- log.msg("RunProcess.failed: command failed: %s" % (why,))
- if self.timer:
- self.timer.cancel()
- self.timer = None
- if self.maxTimer:
- self.maxTimer.cancel()
- self.maxTimer = None
- if self.buftimer:
- self.buftimer.cancel()
- self.buftimer = None
- d = self.deferred
- self.deferred = None
- if d:
- d.errback(why)
- else:
- log.msg("Hey, command %s finished twice" % self)
-
- def doTimeout(self):
- self.timer = None
- msg = "command timed out: %d seconds without output" % self.timeout
- self.kill(msg)
-
- def doMaxTimeout(self):
- self.maxTimer = None
- msg = "command timed out: %d seconds elapsed" % self.maxTime
- self.kill(msg)
-
- def kill(self, msg):
- # This may be called by the timeout, or when the user has decided to
- # abort this build.
- self._sendBuffers()
- if self.timer:
- self.timer.cancel()
- self.timer = None
- if self.maxTimer:
- self.maxTimer.cancel()
- self.maxTimer = None
- if self.buftimer:
- self.buftimer.cancel()
- self.buftimer = None
- msg += ", attempting to kill"
- log.msg(msg)
- self.sendStatus({'header': "\n" + msg + "\n"})
-
- # let the PP know that we are killing it, so that it can ensure that
- # the exit status comes out right
- self.pp.killed = True
-
- # keep track of whether we believe we've successfully killed something
- hit = 0
-
- # try signalling the process group
- if not hit and self.useProcGroup and runtime.platformType == "posix":
- sig = getattr(signal, "SIG"+ self.interruptSignal, None)
-
- if sig is None:
- log.msg("signal module is missing SIG%s" % self.interruptSignal)
- elif not hasattr(os, "kill"):
- log.msg("os module is missing the 'kill' function")
- elif self.process.pgid is None:
- log.msg("self.process has no pgid")
- else:
- log.msg("trying to kill process group %d" %
- (self.process.pgid,))
- try:
- os.kill(-self.process.pgid, sig)
- log.msg(" signal %s sent successfully" % sig)
- self.process.pgid = None
- hit = 1
- except OSError:
- log.msg('failed to kill process group (ignored): %s' %
- (sys.exc_info()[1],))
- # probably no-such-process, maybe because there is no process
- # group
- pass
-
- elif runtime.platformType == "win32":
- if self.interruptSignal == None:
- log.msg("self.interruptSignal==None, only pretending to kill child")
- elif self.process.pid is not None:
- log.msg("using TASKKILL /F PID /T to kill pid %s" % self.process.pid)
- subprocess.check_call("TASKKILL /F /PID %s /T" % self.process.pid)
- log.msg("taskkill'd pid %s" % self.process.pid)
- hit = 1
-
- # try signalling the process itself (works on Windows too, sorta)
- if not hit:
- try:
- log.msg("trying process.signalProcess('%s')" % (self.interruptSignal,))
- self.process.signalProcess(self.interruptSignal)
- log.msg(" signal %s sent successfully" % (self.interruptSignal,))
- hit = 1
- except OSError:
- log.err("from process.signalProcess:")
- # could be no-such-process, because they finished very recently
- pass
- except error.ProcessExitedAlready:
- log.msg("Process exited already - can't kill")
- # the process has already exited, and likely finished() has
- # been called already or will be called shortly
- pass
-
- if not hit:
- log.msg("signalProcess/os.kill failed both times")
-
- if runtime.platformType == "posix":
- # we only do this under posix because the win32eventreactor
- # blocks here until the process has terminated, while closing
- # stderr. This is weird.
- self.pp.transport.loseConnection()
-
- if self.deferred:
- # finished ought to be called momentarily. Just in case it doesn't,
- # set a timer which will abandon the command.
- self.timer = self._reactor.callLater(self.BACKUP_TIMEOUT,
- self.doBackupTimeout)
-
- def doBackupTimeout(self):
- log.msg("we tried to kill the process, and it wouldn't die.."
- " finish anyway")
- self.timer = None
- self.sendStatus({'header': "SIGKILL failed to kill process\n"})
- if self.sendRC:
- self.sendStatus({'header': "using fake rc=-1\n"})
- self.sendStatus({'rc': -1})
- self.failed(RuntimeError("SIGKILL failed to kill process"))
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/base.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/base.py
deleted file mode 100644
index 78722a63..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/base.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-
-def isBuildslaveDir(dir):
- def print_error(error_message):
- print "%s\ninvalid buildslave directory '%s'" % (error_message, dir)
-
- buildbot_tac = os.path.join(dir, "buildbot.tac")
- try:
- contents = open(buildbot_tac).read()
- except IOError, exception:
- print_error("error reading '%s': %s" % \
- (buildbot_tac, exception.strerror))
- return False
-
- if "Application('buildslave')" not in contents:
- print_error("unexpected content in '%s'" % buildbot_tac)
- return False
-
- return True
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/logwatcher.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/logwatcher.py
deleted file mode 100644
index ff3e1193..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/logwatcher.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os
-from twisted.python.failure import Failure
-from twisted.internet import defer, reactor, protocol, error
-from twisted.protocols.basic import LineOnlyReceiver
-
-class FakeTransport:
- disconnecting = False
-
-class BuildmasterTimeoutError(Exception):
- pass
-class BuildslaveTimeoutError(Exception):
- pass
-class ReconfigError(Exception):
- pass
-class BuildSlaveDetectedError(Exception):
- pass
-
-class TailProcess(protocol.ProcessProtocol):
- def outReceived(self, data):
- self.lw.dataReceived(data)
- def errReceived(self, data):
- print "ERR: '%s'" % (data,)
-
-
-class LogWatcher(LineOnlyReceiver):
- POLL_INTERVAL = 0.1
- TIMEOUT_DELAY = 10.0
- delimiter = os.linesep
-
- def __init__(self, logfile):
- self.logfile = logfile
- self.in_reconfig = False
- self.transport = FakeTransport()
- self.pp = TailProcess()
- self.pp.lw = self
- self.processtype = "buildmaster"
- self.timer = None
-
- def start(self):
- # If the log file doesn't exist, create it now.
- if not os.path.exists(self.logfile):
- open(self.logfile, 'a').close()
-
- # return a Deferred that fires when the reconfig process has
- # finished. It errbacks with TimeoutError if the finish line has not
- # been seen within 10 seconds, and with ReconfigError if the error
- # line was seen. If the logfile could not be opened, it errbacks with
- # an IOError.
- self.p = reactor.spawnProcess(self.pp, "/usr/bin/tail",
- ("tail", "-f", "-n", "0", self.logfile),
- env=os.environ,
- )
- self.running = True
- d = defer.maybeDeferred(self._start)
- return d
-
- def _start(self):
- self.d = defer.Deferred()
- self.timer = reactor.callLater(self.TIMEOUT_DELAY, self.timeout)
- return self.d
-
- def timeout(self):
- self.timer = None
- if self.processtype == "buildmaster":
- e = BuildmasterTimeoutError()
- else:
- e = BuildslaveTimeoutError()
- self.finished(Failure(e))
-
- def finished(self, results):
- try:
- self.p.signalProcess("KILL")
- except error.ProcessExitedAlready:
- pass
- if self.timer:
- self.timer.cancel()
- self.timer = None
- self.running = False
- self.in_reconfig = False
- self.d.callback(results)
-
- def lineReceived(self, line):
- if not self.running:
- return
- if "Log opened." in line:
- self.in_reconfig = True
- if "loading configuration from" in line:
- self.in_reconfig = True
- if "Creating BuildSlave" in line:
- self.processtype = "buildslave"
-
- if self.in_reconfig:
- print line
-
- if "message from master: attached" in line:
- return self.finished("buildslave")
- if "I will keep using the previous config file" in line:
- return self.finished(Failure(ReconfigError()))
- if "configuration update complete" in line:
- return self.finished("buildmaster")
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/runner.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/runner.py
deleted file mode 100644
index 19882a0f..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/runner.py
+++ /dev/null
@@ -1,465 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# N.B.: don't import anything that might pull in a reactor yet. Some of our
-# subcommands want to load modules that need the gtk reactor.
-import os, sys, re, time
-from buildslave.scripts import base
-from twisted.python import usage
-
-# the create/start/stop commands should all be run as the same user,
-# preferably a separate 'buildbot' account.
-
-# Note that the terms 'options' and 'config' are used interchangeably here - in
-# fact, they are interchanged several times. Caveat legator.
-
-class Maker:
- def __init__(self, config):
- self.config = config
- self.basedir = config['basedir']
- self.force = config.get('force', False)
- self.quiet = config['quiet']
-
- def mkdir(self):
- if os.path.exists(self.basedir):
- if not self.quiet:
- print "updating existing installation"
- return
- if not self.quiet:
- print "mkdir", self.basedir
- os.mkdir(self.basedir)
-
- def mkinfo(self):
- path = os.path.join(self.basedir, "info")
- if not os.path.exists(path):
- if not self.quiet:
- print "mkdir", path
- os.mkdir(path)
- created = False
- admin = os.path.join(path, "admin")
- if not os.path.exists(admin):
- if not self.quiet:
- print "Creating info/admin, you need to edit it appropriately"
- f = open(admin, "wt")
- f.write("Your Name Here <admin@youraddress.invalid>\n")
- f.close()
- created = True
- host = os.path.join(path, "host")
- if not os.path.exists(host):
- if not self.quiet:
- print "Creating info/host, you need to edit it appropriately"
- f = open(host, "wt")
- f.write("Please put a description of this build host here\n")
- f.close()
- created = True
- access_uri = os.path.join(path, "access_uri")
- if not os.path.exists(access_uri):
- if not self.quiet:
- print "Not creating info/access_uri - add it if you wish"
- if created and not self.quiet:
- print "Please edit the files in %s appropriately." % path
-
- def chdir(self):
- if not self.quiet:
- print "chdir", self.basedir
- os.chdir(self.basedir)
-
- def makeTAC(self, contents, secret=False):
- tacfile = "buildbot.tac"
- if os.path.exists(tacfile):
- oldcontents = open(tacfile, "rt").read()
- if oldcontents == contents:
- if not self.quiet:
- print "buildbot.tac already exists and is correct"
- return
- if not self.quiet:
- print "not touching existing buildbot.tac"
- print "creating buildbot.tac.new instead"
- tacfile = "buildbot.tac.new"
- f = open(tacfile, "wt")
- f.write(contents)
- f.close()
- if secret:
- os.chmod(tacfile, 0600)
-
-slaveTACTemplate = ["""
-import os
-
-from twisted.application import service
-from buildslave.bot import BuildSlave
-
-basedir = r'%(basedir)s'
-rotateLength = %(log-size)s
-maxRotatedFiles = %(log-count)s
-
-# if this is a relocatable tac file, get the directory containing the TAC
-if basedir == '.':
- import os.path
- basedir = os.path.abspath(os.path.dirname(__file__))
-
-# note: this line is matched against to check that this is a buildslave
-# directory; do not edit it.
-application = service.Application('buildslave')
-""",
-"""
-try:
- from twisted.python.logfile import LogFile
- from twisted.python.log import ILogObserver, FileLogObserver
- logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
- maxRotatedFiles=maxRotatedFiles)
- application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
-except ImportError:
- # probably not yet twisted 8.2.0 and beyond, can't set log yet
- pass
-""",
-"""
-buildmaster_host = '%(host)s'
-port = %(port)d
-slavename = '%(name)s'
-passwd = '%(passwd)s'
-keepalive = %(keepalive)d
-usepty = %(usepty)d
-umask = %(umask)s
-maxdelay = %(maxdelay)d
-allow_shutdown = %(allow-shutdown)s
-
-s = BuildSlave(buildmaster_host, port, slavename, passwd, basedir,
- keepalive, usepty, umask=umask, maxdelay=maxdelay,
- allow_shutdown=allow_shutdown)
-s.setServiceParent(application)
-
-"""]
-
-def createSlave(config):
- m = Maker(config)
- m.mkdir()
- m.chdir()
- if config['relocatable']:
- config['basedir'] = '.'
- try:
- master = config['master']
- port = None
- host, port = re.search(r'^([^:]+)(?:[:](\d+))?', master).groups()
- if port == None:
- port = '9989'
- config['host'] = host
- config['port'] = int(port)
- except:
- print "unparseable master location '%s'" % master
- print " expecting something more like localhost:8007 or localhost"
- raise
-
- asd = config['allow-shutdown']
- if asd:
- config['allow-shutdown'] = "'%s'" % asd
-
- if config['no-logrotate']:
- slaveTAC = "".join([slaveTACTemplate[0]] + slaveTACTemplate[2:])
- else:
- slaveTAC = "".join(slaveTACTemplate)
- contents = slaveTAC % config
-
- m.makeTAC(contents, secret=True)
- m.mkinfo()
-
- if not m.quiet:
- print "buildslave configured in %s" % m.basedir
-
-
-class SlaveNotRunning(Exception):
- """
- raised when trying to stop slave process that is not running
- """
-
-
-def stopSlave(basedir, quiet, signame="TERM"):
- """
- Stop slave process by sending it a signal.
-
- Using the specified basedir path, read slave process's pid file and
- try to terminate that process with specified signal.
-
- @param basedir: buildslave basedir path
- @param quite: if False, don't print any messages to stdout
- @param signame: signal to send to the slave process
-
- @raise SlaveNotRunning: if slave pid file is not found
- """
- import signal
-
- os.chdir(basedir)
- try:
- f = open("twistd.pid", "rt")
- except:
- raise SlaveNotRunning()
-
- pid = int(f.read().strip())
- signum = getattr(signal, "SIG"+signame)
- timer = 0
- try:
- os.kill(pid, signum)
- except OSError, e:
- if e.errno != 3:
- raise
-
- time.sleep(0.1)
- while timer < 10:
- # poll once per second until twistd.pid goes away, up to 10 seconds
- try:
- os.kill(pid, 0)
- except OSError:
- if not quiet:
- print "buildslave process %d is dead" % pid
- return
- timer += 1
- time.sleep(1)
- if not quiet:
- print "never saw process go away"
-
-
-def stop(config, signame="TERM"):
- quiet = config['quiet']
- basedir = config['basedir']
-
- if not base.isBuildslaveDir(basedir):
- sys.exit(1)
-
- try:
- stopSlave(basedir, quiet, signame)
- except SlaveNotRunning:
- if not quiet:
- print "buildslave not running"
-
-
-def restart(config):
- quiet = config['quiet']
-
- if not base.isBuildslaveDir(config['basedir']):
- sys.exit(1)
-
- from buildslave.scripts.startup import start
- try:
- stopSlave(config['basedir'], quiet)
- except SlaveNotRunning:
- if not quiet:
- print "no old buildslave process found to stop"
- if not quiet:
- print "now restarting buildslave process.."
- start(config)
-
-
-class MakerBase(usage.Options):
- optFlags = [
- ['help', 'h', "Display this message"],
- ["quiet", "q", "Do not emit the commands being run"],
- ]
-
- longdesc = """
- Operates upon the specified <basedir> (or the current directory, if not
- specified).
- """
-
- opt_h = usage.Options.opt_help
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['basedir'] = args[0]
- else:
- # Use the current directory if no basedir was specified.
- self['basedir'] = os.getcwd()
- if len(args) > 1:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- self['basedir'] = os.path.abspath(self['basedir'])
-
-class StartOptions(MakerBase):
- optFlags = [
- ['quiet', 'q', "Don't display startup log messages"],
- ['nodaemon', None, "Don't daemonize (stay in foreground)"],
- ]
- def getSynopsis(self):
- return "Usage: buildslave start [<basedir>]"
-
-class StopOptions(MakerBase):
- def getSynopsis(self):
- return "Usage: buildslave stop [<basedir>]"
-
-class RestartOptions(MakerBase):
- optFlags = [
- ['quiet', 'q', "Don't display startup log messages"],
- ['nodaemon', None, "Don't daemonize (stay in foreground)"],
- ]
- def getSynopsis(self):
- return "Usage: buildslave restart [<basedir>]"
-
-class UpgradeSlaveOptions(MakerBase):
- optFlags = [
- ]
- optParameters = [
- ]
-
- def getSynopsis(self):
- return "Usage: buildslave upgrade-slave [<basedir>]"
-
- longdesc = """
- This command takes an existing buildslave working directory and
- upgrades it to the current version.
- """
-
-def upgradeSlave(config):
- basedir = os.path.expanduser(config['basedir'])
-
- if not base.isBuildslaveDir(basedir):
- sys.exit(1)
-
- buildbot_tac = open(os.path.join(basedir, "buildbot.tac")).read()
- new_buildbot_tac = buildbot_tac.replace(
- "from buildbot.slave.bot import BuildSlave",
- "from buildslave.bot import BuildSlave")
- if new_buildbot_tac != buildbot_tac:
- open(os.path.join(basedir, "buildbot.tac"), "w").write(new_buildbot_tac)
- print "buildbot.tac updated"
- else:
- print "No changes made"
-
- return 0
-
-
-class CreateSlaveOptions(MakerBase):
- optFlags = [
- ["force", "f", "Re-use an existing directory"],
- ["relocatable", "r",
- "Create a relocatable buildbot.tac"],
- ["no-logrotate", "n",
- "Do not permit buildmaster rotate logs by itself"]
- ]
- optParameters = [
- ["keepalive", "k", 600,
- "Interval at which keepalives should be sent (in seconds)"],
- ["usepty", None, 0,
- "(1 or 0) child processes should be run in a pty (default 0)"],
- ["umask", None, "None",
- "controls permissions of generated files. Use --umask=022 to be world-readable"],
- ["maxdelay", None, 300,
- "Maximum time between connection attempts"],
- ["log-size", "s", "10000000",
- "size at which to rotate twisted log files"],
- ["log-count", "l", "10",
- "limit the number of kept old twisted log files (None for unlimited)"],
- ["allow-shutdown", "a", None,
- "Allows the buildslave to initiate a graceful shutdown. One of "
- "'signal' or 'file'"]
- ]
-
- longdesc = """
- This command creates a buildslave working directory and buildbot.tac
- file. The bot will use the <name> and <passwd> arguments to authenticate
- itself when connecting to the master. All commands are run in a
- build-specific subdirectory of <basedir>. <master> is a string of the
- form 'hostname[:port]', and specifies where the buildmaster can be reached.
- port defaults to 9989
-
- The appropriate values for <name>, <passwd>, and <master> should be
- provided to you by the buildmaster administrator. You must choose <basedir>
- yourself.
- """
-
- def getSynopsis(self):
- return "Usage: buildslave create-slave [options] <basedir> <master> <name> <passwd>"
-
- def parseArgs(self, *args):
- if len(args) != 4:
- raise usage.UsageError("incorrect number of arguments")
- basedir, master, name, passwd = args
- if master[:5] == "http:":
- raise usage.UsageError("<master> is not a URL - do not use URL")
- self['basedir'] = basedir
- self['master'] = master
- self['name'] = name
- self['passwd'] = passwd
-
- def postOptions(self):
- MakerBase.postOptions(self)
-
- # check and convert numeric parameters
- for argument in ["usepty", "keepalive", "maxdelay", "log-size"]:
- try:
- self[argument] = int(self[argument])
- except ValueError:
- raise usage.UsageError("%s parameter needs to be an number" \
- % argument)
-
- if not re.match('^\d+$', self['log-count']) and \
- self['log-count'] != 'None':
- raise usage.UsageError("log-count parameter needs to be an number"
- " or None")
-
-class Options(usage.Options):
- synopsis = "Usage: buildslave <command> [command options]"
-
- subCommands = [
- # the following are all admin commands
- ['create-slave', None, CreateSlaveOptions,
- "Create and populate a directory for a new buildslave"],
- ['upgrade-slave', None, UpgradeSlaveOptions,
- "Upgrade an existing buildslave directory for the current version"],
- ['start', None, StartOptions, "Start a buildslave"],
- ['stop', None, StopOptions, "Stop a buildslave"],
- ['restart', None, RestartOptions,
- "Restart a buildslave"],
- ]
-
- def opt_version(self):
- import buildslave
- print "Buildslave version: %s" % buildslave.version
- usage.Options.opt_version(self)
-
- def opt_verbose(self):
- from twisted.python import log
- log.startLogging(sys.stderr)
-
- def postOptions(self):
- if not hasattr(self, 'subOptions'):
- raise usage.UsageError("must specify a command")
-
-
-def run():
- config = Options()
- try:
- config.parseOptions()
- except usage.error, e:
- print "%s: %s" % (sys.argv[0], e)
- print
- c = getattr(config, 'subOptions', config)
- print str(c)
- sys.exit(1)
-
- command = config.subCommand
- so = config.subOptions
-
- if command == "create-slave":
- createSlave(so)
- elif command == "upgrade-slave":
- upgradeSlave(so)
- elif command == "start":
- from buildslave.scripts.startup import start
- start(so)
- elif command == "stop":
- stop(so)
- elif command == "restart":
- restart(so)
- sys.exit(0)
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/startup.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/startup.py
deleted file mode 100644
index dc414fc3..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/scripts/startup.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-
-import os, sys, time
-from buildslave.scripts import base
-
-class Follower:
- def follow(self):
- from twisted.internet import reactor
- from buildslave.scripts.logwatcher import LogWatcher
- self.rc = 0
- print "Following twistd.log until startup finished.."
- lw = LogWatcher("twistd.log")
- d = lw.start()
- d.addCallbacks(self._success, self._failure)
- reactor.run()
- return self.rc
-
- def _success(self, processtype):
- from twisted.internet import reactor
- print "The %s appears to have (re)started correctly." % processtype
- self.rc = 0
- reactor.stop()
-
- def _failure(self, why):
- from twisted.internet import reactor
- from buildslave.scripts.logwatcher import BuildmasterTimeoutError, \
- ReconfigError, BuildslaveTimeoutError, BuildSlaveDetectedError
- if why.check(BuildmasterTimeoutError):
- print """
-The buildslave took more than 10 seconds to start, so we were unable to
-confirm that it started correctly. Please 'tail twistd.log' and look for a
-line that says 'configuration update complete' to verify correct startup.
-"""
- elif why.check(BuildslaveTimeoutError):
- print """
-The buildslave took more than 10 seconds to start and/or connect to the
-buildslave, so we were unable to confirm that it started and connected
-correctly. Please 'tail twistd.log' and look for a line that says 'message
-from master: attached' to verify correct startup. If you see a bunch of
-messages like 'will retry in 6 seconds', your buildslave might not have the
-correct hostname or portnumber for the buildslave, or the buildslave might
-not be running. If you see messages like
- 'Failure: twisted.cred.error.UnauthorizedLogin'
-then your buildslave might be using the wrong botname or password. Please
-correct these problems and then restart the buildslave.
-"""
- elif why.check(ReconfigError):
- print """
-The buildslave appears to have encountered an error in the master.cfg config
-file during startup. It is probably running with an empty configuration right
-now. Please inspect and fix master.cfg, then restart the buildslave.
-"""
- elif why.check(BuildSlaveDetectedError):
- print """
-Buildslave is starting up, not following logfile.
-"""
- else:
- print """
-Unable to confirm that the buildslave started correctly. You may need to
-stop it, fix the config file, and restart.
-"""
- print why
- self.rc = 1
- reactor.stop()
-
-
-def start(config):
- if not base.isBuildslaveDir(config['basedir']):
- sys.exit(1)
-
- os.chdir(config['basedir'])
- if config['quiet'] or config['nodaemon']:
- return launch(config)
-
- # we probably can't do this os.fork under windows
- from twisted.python.runtime import platformType
- if platformType == "win32":
- return launch(config)
-
- # fork a child to launch the daemon, while the parent process tails the
- # logfile
- if os.fork():
- # this is the parent
- rc = Follower().follow()
- sys.exit(rc)
- # this is the child: give the logfile-watching parent a chance to start
- # watching it before we start the daemon
- time.sleep(0.2)
- launch(config)
-
-def launch(config):
- sys.path.insert(0, os.path.abspath(os.getcwd()))
-
- # see if we can launch the application without actually having to
- # spawn twistd, since spawning processes correctly is a real hassle
- # on windows.
- from twisted.python.runtime import platformType
- argv = ["twistd",
- "--no_save",
- "--logfile=twistd.log", # windows doesn't use the same default
- "--python=buildbot.tac"]
- if config['nodaemon']:
- argv.extend(['--nodaemon'])
- sys.argv = argv
-
- # this is copied from bin/twistd. twisted-2.0.0 through 2.4.0 use
- # _twistw.run . Twisted-2.5.0 and later use twistd.run, even for
- # windows.
- from twisted import __version__
- major, minor, ignored = __version__.split(".", 2)
- major = int(major)
- minor = int(minor)
- if (platformType == "win32" and (major == 2 and minor < 5)):
- from twisted.scripts import _twistw
- run = _twistw.run
- else:
- from twisted.scripts import twistd
- run = twistd.run
- run()
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/__init__.py
deleted file mode 100644
index fa07f533..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/__init__.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-
-import twisted
-from twisted.trial import unittest
-from buildslave import monkeypatches
-
-# apply the same patches the slave does when it starts
-monkeypatches.patch_all(for_tests=True)
-
-def add_debugging_monkeypatches():
- """
- DO NOT CALL THIS DIRECTLY
-
- This adds a few "harmless" monkeypatches which make it easier to debug
- failing tests.
- """
- from twisted.application.service import Service
- old_startService = Service.startService
- old_stopService = Service.stopService
- def startService(self):
- assert not self.running
- return old_startService(self)
- def stopService(self):
- assert self.running
- return old_stopService(self)
- Service.startService = startService
- Service.stopService = stopService
-
- # versions of Twisted before 9.0.0 did not have a UnitTest.patch that worked
- # on Python-2.7
- if twisted.version.major <= 9 and sys.version_info[:2] == (2,7):
- def nopatch(self, *args):
- raise unittest.SkipTest('unittest.TestCase.patch is not available')
- unittest.TestCase.patch = nopatch
-
-add_debugging_monkeypatches()
-
-__all__ = []
-
-# import mock so we bail out early if it's not installed
-try:
- import mock
- mock = mock
-except ImportError:
- raise ImportError("Buildbot tests require the 'mock' module; "
- "try 'pip install mock'")
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/remote.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/remote.py
deleted file mode 100644
index 017a6710..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/remote.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.internet import defer
-
-class FakeRemote:
- """
- Wrap a local object to make it look like it's remote
- """
- def __init__(self, original, method_prefix="remote_"):
- self.original = original
- self.method_prefix = method_prefix
-
- def callRemote(self, meth, *args, **kwargs):
- fn = getattr(self.original, self.method_prefix + meth)
- return defer.maybeDeferred(fn, *args, **kwargs)
-
- def notifyOnDisconnect(self, what): pass
- def dontNotifyOnDisconnect(self, what): pass
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/runprocess.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/runprocess.py
deleted file mode 100644
index e74aed38..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/runprocess.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.python import failure
-from twisted.internet import defer
-
-class Expect:
- """
- An expected instantiation of RunProcess. Usually used within a RunProcess
- expect invocation:
-
- rp.expect(
- Expect("echo", "bar", usePTY=False)
- + { 'stdout' : 'hello!!' }
- + { 'rc' : 13 }
- + 13 # for a callback with rc=13; or
- + Failure(..), # for a failure
- Expect(..) + .. ,
- ...
- )
-
- Note that the default values are accepted for all keyword arguments if they
- are not omitted.
- """
- def __init__(self, command, workdir, **kwargs):
- self.kwargs = dict(command=command, workdir=workdir)
- self.kwargs.update(kwargs)
-
- self.result = None
- self.status_updates = []
-
- def __add__(self, other):
- if isinstance(other, dict):
- self.status_updates.append(other)
- elif isinstance(other, int):
- self.result = ( 'c', other )
- elif isinstance(other, failure.Failure):
- self.result = ( 'e', other )
- else:
- raise ValueError("invalid expectation '%r'" % (other,))
- return self
-
- def __str__(self):
- other_kwargs = self.kwargs.copy()
- del other_kwargs['command']
- del other_kwargs['workdir']
- return "Command: %s\n workdir: %s\n kwargs: %s\n result: %s\n" % (
- self.kwargs['command'], self.kwargs['workdir'],
- other_kwargs, self.result)
-
-
-class FakeRunProcess:
- """
- A fake version of L{buildslave.runprocess.RunProcess} which will
- simulate running external processes without actually running them (which is
- very fragile in tests!)
-
- This class is first programmed with the set of instances that are expected,
- and with their expected results. It will raise an AssertionError if the
- expected behavior is not seen.
-
- Note that this handles sendStderr/sendStdout and keepStderr/keepStdout properly.
- """
-
- @classmethod
- def expect(cls, *expectations):
- """
- Set the expectations for this test run
- """
- cls._expectations = list(expectations)
- # list the first expectation last, so we can pop it
- cls._expectations.reverse()
-
- @classmethod
- def test_done(cls):
- """
- Indicate that this test is finished; if any expected instantiations
- have not taken place, this will raise the appropriate AssertionError.
- """
- if cls._expectations:
- raise AssertionError("%d expected instances not created" % len(cls._expectations))
- del cls._expectations
-
- def __init__(self, builder, command, workdir, **kwargs):
- kwargs['command'] = command
- kwargs['workdir'] = workdir
-
- # the default values for the constructor kwargs; if we got a default
- # value in **kwargs and didn't expect anything, well count that as OK
- default_values = dict(environ=None,
- sendStdout=True, sendStderr=True, sendRC=True,
- timeout=None, maxTime=None, initialStdin=None,
- keepStdout=False, keepStderr=False,
- logEnviron=True, logfiles={}, usePTY="slave-config")
-
- if not self._expectations:
- raise AssertionError("unexpected instantiation: %s" % (kwargs,))
- exp = self._exp = self._expectations.pop()
- if exp.kwargs != kwargs:
- msg = [ ]
- for key in sorted(list(set(exp.kwargs.keys()) | set(kwargs.keys()))):
- if key not in exp.kwargs:
- if key in default_values:
- if default_values[key] == kwargs[key]:
- continue # default values are expected
- msg.append('%s: expected default (%r),\n got %r' %
- (key, default_values[key], kwargs[key]))
- else:
- msg.append('%s: unexpected arg, value = %r' % (key, kwargs[key]))
- elif key not in kwargs:
- msg.append('%s: did not get expected arg' % (key,))
- elif exp.kwargs[key] != kwargs[key]:
- msg.append('%s: expected %r,\n got %r' % (key, exp.kwargs[key], kwargs[key]))
- if msg:
- msg.insert(0, 'did not get expected __init__ arguments for\n '
- + " ".join(map(repr, kwargs.get('command', ['unknown command']))))
- self._expectations[:] = [] # don't expect any more instances, since we're failing
- raise AssertionError("\n".join(msg))
-
- self._builder = builder
- self.stdout = ''
- self.stderr = ''
-
- def start(self):
- # figure out the stdio-related parameters
- keepStdout = self._exp.kwargs.get('keepStdout', False)
- keepStderr = self._exp.kwargs.get('keepStderr', False)
- sendStdout = self._exp.kwargs.get('sendStdout', True)
- sendStderr = self._exp.kwargs.get('sendStderr', True)
- if keepStdout:
- self.stdout = ''
- if keepStderr:
- self.stderr = ''
- finish_immediately = True
-
- # send the updates, accounting for the stdio parameters
- for upd in self._exp.status_updates:
- if 'stdout' in upd:
- if keepStdout:
- self.stdout += upd['stdout']
- if not sendStdout:
- del upd['stdout']
- if 'stderr' in upd:
- if keepStderr:
- self.stderr += upd['stderr']
- if not sendStderr:
- del upd['stderr']
- if 'wait' in upd:
- finish_immediately = False
- continue # don't send this update
- if not upd:
- continue
- self._builder.sendUpdate(upd)
-
- d = self.run_deferred = defer.Deferred()
-
- if finish_immediately:
- self._finished()
-
- return d
-
- def _finished(self):
- if self._exp.result[0] == 'e':
- self.run_deferred.errback(self._exp.result[1])
- else:
- self.run_deferred.callback(self._exp.result[1])
-
- def kill(self, reason):
- self._builder.sendUpdate({'hdr' : 'killing'})
- self._builder.sendUpdate({'rc' : -1})
- self.run_deferred.callback(-1)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/slavebuilder.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/slavebuilder.py
deleted file mode 100644
index 5623b1b3..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/fake/slavebuilder.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import pprint
-
-class FakeSlaveBuilder:
- """
- Simulates a SlaveBuilder, but just records the updates from sendUpdate
- in its updates attribute. Call show() to get a pretty-printed string
- showing the updates. Set debug to True to show updates as they happen.
- """
- debug = False
- def __init__(self, usePTY=False, basedir="/slavebuilder/basedir"):
- self.updates = []
- self.basedir = basedir
- self.usePTY = usePTY
- self.unicode_encoding = 'utf-8'
-
- def sendUpdate(self, data):
- if self.debug:
- print "FakeSlaveBuilder.sendUpdate", data
- self.updates.append(data)
-
- def show(self):
- return pprint.pformat(self.updates)
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/test_extra_coverage.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/test_extra_coverage.py
deleted file mode 100644
index c803988d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/test_extra_coverage.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# this file imports a number of source files that are not
-# included in the coverage because none of the tests import
-# them; this results in a more accurate total coverage percent.
-
-modules = [] # for the benefit of pyflakes
-
-from buildslave.scripts import logwatcher, runner, startup
-modules.extend([logwatcher, runner, startup])
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/runprocess-scripts.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/runprocess-scripts.py
deleted file mode 100644
index 05715cb4..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/runprocess-scripts.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-# This file contains scripts run by the test_runprocess tests. Note that since
-# this code runs in a different Python interpreter, it does not necessarily
-# have access to any of the Buildbot source. Functions here should be kept
-# very simple!
-
-import sys
-import os
-import time
-import select
-import signal
-
-# utils
-
-def write_pidfile(pidfile):
- pidfile_tmp = pidfile + "~"
- f = open(pidfile_tmp, "w")
- f.write(str(os.getpid()))
- f.close()
- os.rename(pidfile_tmp, pidfile)
-
-def sleep_forever():
- signal.alarm(110) # die after 110 seconds
- while True:
- time.sleep(10)
-
-def wait_for_parent_death():
- while True:
- ppid = os.getppid()
- if ppid == 1:
- return
- # on some systems, getppid will keep returning
- # a dead pid, so check it for liveness
- try:
- os.kill(ppid, 0)
- except OSError: # Probably ENOSUCH
- return
-
-script_fns = {}
-def script(fn):
- script_fns[fn.func_name] = fn
- return fn
-
-# scripts
-
-@script
-def write_pidfile_and_sleep():
- pidfile = sys.argv[2]
- write_pidfile(pidfile)
- sleep_forever()
-
-@script
-def spawn_child():
- parent_pidfile, child_pidfile = sys.argv[2:]
- if os.fork() == 0:
- write_pidfile(child_pidfile)
- else:
- write_pidfile(parent_pidfile)
- sleep_forever()
-
-@script
-def double_fork():
- # when using a PTY, the child process will get SIGHUP when the
- # parent process exits, so ignore that.
- signal.signal(signal.SIGHUP, signal.SIG_IGN)
- parent_pidfile, child_pidfile = sys.argv[2:]
- if os.fork() == 0:
- wait_for_parent_death()
- write_pidfile(child_pidfile)
- sleep_forever()
- else:
- write_pidfile(parent_pidfile)
- sys.exit(0)
-
-@script
-def assert_stdin_closed():
- # EOF counts as readable data, so we should see stdin in the readable list,
- # although it may not appear immediately, and select may return early
- bail_at = time.time() + 10
- while True:
- r, w, x = select.select([0], [], [], 0.01)
- if r == [0]: return # succcess!
- if time.time() > bail_at:
- assert False # failure :(
-
-# make sure this process dies if necessary
-
-if not hasattr(signal, 'alarm'):
- signal.alarm = lambda t : None
-signal.alarm(110) # die after 110 seconds
-
-# dispatcher
-
-script_fns[sys.argv[1]]()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot.py
deleted file mode 100644
index 24a97ea7..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot.py
+++ /dev/null
@@ -1,379 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import shutil
-import mock
-
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, task
-from twisted.python import failure, log
-
-from buildslave.test.util import command, compat
-from buildslave.test.fake.remote import FakeRemote
-from buildslave.test.fake.runprocess import Expect
-import buildslave
-from buildslave import bot
-
-class TestBot(unittest.TestCase):
-
- def setUp(self):
- self.basedir = os.path.abspath("basedir")
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- os.makedirs(self.basedir)
-
- self.real_bot = bot.Bot(self.basedir, False)
- self.real_bot.startService()
-
- self.bot = FakeRemote(self.real_bot)
-
- def tearDown(self):
- d = defer.succeed(None)
- if self.real_bot and self.real_bot.running:
- d.addCallback(lambda _ : self.real_bot.stopService())
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- return d
-
- def test_getCommands(self):
- d = self.bot.callRemote("getCommands")
- def check(cmds):
- # just check that 'shell' is present..
- self.assertTrue('shell' in cmds)
- d.addCallback(check)
- return d
-
- def test_getVersion(self):
- d = self.bot.callRemote("getVersion")
- def check(vers):
- self.assertEqual(vers, buildslave.version)
- d.addCallback(check)
- return d
-
- def test_getSlaveInfo(self):
- infodir = os.path.join(self.basedir, "info")
- os.makedirs(infodir)
- open(os.path.join(infodir, "admin"), "w").write("testy!")
- open(os.path.join(infodir, "foo"), "w").write("bar")
- open(os.path.join(infodir, "environ"), "w").write("something else")
-
- d = self.bot.callRemote("getSlaveInfo")
- def check(info):
- self.assertEqual(info, dict(admin='testy!', foo='bar', environ=os.environ, system=os.name, basedir=self.basedir))
- d.addCallback(check)
- return d
-
- def test_getSlaveInfo_nodir(self):
- d = self.bot.callRemote("getSlaveInfo")
- def check(info):
- self.assertEqual(set(info.keys()), set(['environ','system','basedir']))
- d.addCallback(check)
- return d
-
- def test_setBuilderList_empty(self):
- d = self.bot.callRemote("setBuilderList", [])
- def check(builders):
- self.assertEqual(builders, {})
- d.addCallback(check)
- return d
-
- def test_setBuilderList_single(self):
- d = self.bot.callRemote("setBuilderList", [ ('mybld', 'myblddir') ])
- def check(builders):
- self.assertEqual(builders.keys(), ['mybld'])
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
- # note that we test the SlaveBuilder instance below
- d.addCallback(check)
- return d
-
- def test_setBuilderList_updates(self):
- d = defer.succeed(None)
-
- slavebuilders = {}
-
- def add_my(_):
- d = self.bot.callRemote("setBuilderList", [
- ('mybld', 'myblddir') ])
- def check(builders):
- self.assertEqual(builders.keys(), ['mybld'])
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
- slavebuilders['my'] = builders['mybld']
- d.addCallback(check)
- return d
- d.addCallback(add_my)
-
- def add_your(_):
- d = self.bot.callRemote("setBuilderList", [
- ('mybld', 'myblddir'), ('yourbld', 'yourblddir') ])
- def check(builders):
- self.assertEqual(sorted(builders.keys()), sorted(['mybld', 'yourbld']))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir')))
- # 'my' should still be the same slavebuilder object
- self.assertEqual(id(slavebuilders['my']), id(builders['mybld']))
- slavebuilders['your'] = builders['yourbld']
- d.addCallback(check)
- return d
- d.addCallback(add_your)
-
- def remove_my(_):
- d = self.bot.callRemote("setBuilderList", [
- ('yourbld', 'yourblddir2') ]) # note new builddir
- def check(builders):
- self.assertEqual(sorted(builders.keys()), sorted(['yourbld']))
- # note that build dirs are not deleted..
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir')))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir2')))
- # 'your' should still be the same slavebuilder object
- self.assertEqual(id(slavebuilders['your']), id(builders['yourbld']))
- d.addCallback(check)
- return d
- d.addCallback(remove_my)
-
- def add_and_remove(_):
- d = self.bot.callRemote("setBuilderList", [
- ('theirbld', 'theirblddir') ])
- def check(builders):
- self.assertEqual(sorted(builders.keys()), sorted(['theirbld']))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'myblddir')))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'yourblddir')))
- self.assertTrue(os.path.exists(os.path.join(self.basedir, 'theirblddir')))
- d.addCallback(check)
- return d
- d.addCallback(add_and_remove)
-
- return d
-
- def test_shutdown(self):
- d1 = defer.Deferred()
- self.patch(reactor, "stop", lambda : d1.callback(None))
- d2 = self.bot.callRemote("shutdown")
- # don't return until both the shutdown method has returned, and
- # reactor.stop has been called
- return defer.gatherResults([d1, d2])
-
-class FakeStep(object):
- "A fake master-side BuildStep that records its activities."
- def __init__(self):
- self.finished_d = defer.Deferred()
- self.actions = []
-
- def wait_for_finish(self):
- return self.finished_d
-
- def remote_update(self, updates):
- for update in updates:
- if 'elapsed' in update[0]:
- update[0]['elapsed'] = 1
- self.actions.append(["update", updates])
-
- def remote_complete(self, f):
- self.actions.append(["complete", f])
- self.finished_d.callback(None)
-
-class TestSlaveBuilder(command.CommandTestMixin, unittest.TestCase):
-
- @defer.deferredGenerator
- def setUp(self):
- self.basedir = os.path.abspath("basedir")
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- os.makedirs(self.basedir)
-
- self.bot = bot.Bot(self.basedir, False)
- self.bot.startService()
-
- # get a SlaveBuilder object from the bot and wrap it as a fake remote
- wfd = defer.waitForDeferred(
- self.bot.remote_setBuilderList([('sb', 'sb')]))
- yield wfd
- builders = wfd.getResult()
- self.sb = FakeRemote(builders['sb'])
-
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- d = defer.succeed(None)
- if self.bot and self.bot.running:
- d.addCallback(lambda _ : self.bot.stopService())
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- return d
-
- def test_print(self):
- return self.sb.callRemote("print", "Hello, SlaveBuilder.")
-
- def test_setMaster(self):
- # not much to check here - what the SlaveBuilder does with the
- # master is not part of the interface (and, in fact, it does very little)
- return self.sb.callRemote("setMaster", mock.Mock())
-
- def test_shutdown(self):
- # don't *actually* shut down the reactor - that would be silly
- stop = mock.Mock()
- self.patch(reactor, "stop", stop)
- d = self.sb.callRemote("shutdown")
- def check(_):
- self.assertTrue(stop.called)
- d.addCallback(check)
- return d
-
- def test_startBuild(self):
- return self.sb.callRemote("startBuild")
-
- def test_startCommand(self):
- # set up a fake step to receive updates
- st = FakeStep()
-
- # patch runprocess to handle the 'echo', below
- self.patch_runprocess(
- Expect([ 'echo', 'hello' ], os.path.join(self.basedir, 'sb', 'workdir'))
- + { 'hdr' : 'headers' } + { 'stdout' : 'hello\n' } + { 'rc' : 0 }
- + 0,
- )
-
- d = defer.succeed(None)
- def do_start(_):
- return self.sb.callRemote("startCommand", FakeRemote(st),
- "13", "shell", dict(
- command=[ 'echo', 'hello' ],
- workdir='workdir',
- ))
- d.addCallback(do_start)
- d.addCallback(lambda _ : st.wait_for_finish())
- def check(_):
- self.assertEqual(st.actions, [
- ['update', [[{'hdr': 'headers'}, 0]]],
- ['update', [[{'stdout': 'hello\n'}, 0]]],
- ['update', [[{'rc': 0}, 0]]],
- ['update', [[{'elapsed': 1}, 0]]],
- ['complete', None],
- ])
- d.addCallback(check)
- return d
-
- def test_startCommand_interruptCommand(self):
- # set up a fake step to receive updates
- st = FakeStep()
-
- # patch runprocess to pretend to sleep (it will really just hang forever,
- # except that we interrupt it)
- self.patch_runprocess(
- Expect([ 'sleep', '10' ], os.path.join(self.basedir, 'sb', 'workdir'))
- + { 'hdr' : 'headers' }
- + { 'wait' : True }
- )
-
- d = defer.succeed(None)
- def do_start(_):
- return self.sb.callRemote("startCommand", FakeRemote(st),
- "13", "shell", dict(
- command=[ 'sleep', '10' ],
- workdir='workdir',
- ))
- d.addCallback(do_start)
-
- # wait a jiffy..
- def do_wait(_):
- d = defer.Deferred()
- reactor.callLater(0.01, d.callback, None)
- return d
- d.addCallback(do_wait)
-
- # and then interrupt the step
- def do_interrupt(_):
- return self.sb.callRemote("interruptCommand", "13", "tl/dr")
- d.addCallback(do_interrupt)
-
- d.addCallback(lambda _ : st.wait_for_finish())
- def check(_):
- self.assertEqual(st.actions, [
- ['update', [[{'hdr': 'headers'}, 0]]],
- ['update', [[{'hdr': 'killing'}, 0]]],
- ['update', [[{'rc': -1}, 0]]],
- ['complete', None],
- ])
- d.addCallback(check)
- return d
-
- def test_startCommand_failure(self):
- # similar to test_startCommand, but leave out some args so the slave
- # generates a failure
-
- # set up a fake step to receive updates
- st = FakeStep()
-
- # patch the log.err, otherwise trial will think something *actually* failed
- self.patch(log, "err", lambda f : None)
-
- d = defer.succeed(None)
- def do_start(_):
- return self.sb.callRemote("startCommand", FakeRemote(st),
- "13", "shell", dict(
- workdir='workdir',
- ))
- d.addCallback(do_start)
- d.addCallback(lambda _ : st.wait_for_finish())
- def check(_):
- self.assertEqual(st.actions[1][0], 'complete')
- self.assertTrue(isinstance(st.actions[1][1], failure.Failure))
- d.addCallback(check)
- return d
-
-class TestBotFactory(unittest.TestCase):
-
- def setUp(self):
- self.bf = bot.BotFactory('mstr', 9010, 35, 200)
-
- # tests
-
- def test_timers(self):
- clock = self.bf._reactor = task.Clock()
-
- calls = []
- def callRemote(method):
- calls.append(clock.seconds())
- self.assertEqual(method, 'keepalive')
- # simulate the response taking a few seconds
- d = defer.Deferred()
- clock.callLater(5, d.callback, None)
- return d
- self.bf.perspective = mock.Mock()
- self.bf.perspective.callRemote = callRemote
-
- self.bf.startTimers()
- clock.callLater(100, self.bf.stopTimers)
-
- clock.pump(( 1 for _ in xrange(150)))
- self.assertEqual(calls, [ 35, 70 ])
-
- @compat.usesFlushLoggedErrors
- def test_timers_exception(self):
- clock = self.bf._reactor = task.Clock()
-
- self.bf.perspective = mock.Mock()
- def callRemote(method):
- return defer.fail(RuntimeError("oh noes"))
- self.bf.perspective.callRemote = callRemote
-
- self.bf.startTimers()
- clock.advance(35)
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
-
-# note that the BuildSlave class is tested in test_bot_BuildSlave
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot_BuildSlave.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot_BuildSlave.py
deleted file mode 100644
index 80d46cc7..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_bot_BuildSlave.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import shutil
-import socket
-
-from twisted.trial import unittest
-from twisted.spread import pb
-from twisted.internet import reactor, defer
-from twisted.cred import checkers, portal
-from zope.interface import implements
-
-from buildslave import bot
-from buildslave.test.util import misc
-
-from mock import Mock
-
-# I don't see any simple way to test the PB equipment without actually setting
-# up a TCP connection. This just tests that the PB code will connect and can
-# execute a basic ping. The rest is done without TCP (or PB) in other test modules.
-
-class MasterPerspective(pb.Avatar):
- def __init__(self, on_keepalive=None):
- self.on_keepalive = on_keepalive
-
- def perspective_keepalive(self):
- if self.on_keepalive:
- on_keepalive, self.on_keepalive = self.on_keepalive, None
- on_keepalive()
-
-class MasterRealm:
- def __init__(self, perspective, on_attachment):
- self.perspective = perspective
- self.on_attachment = on_attachment
-
- implements(portal.IRealm)
- def requestAvatar(self, avatarId, mind, *interfaces):
- assert pb.IPerspective in interfaces
- self.mind = mind
- self.perspective.mind = mind
- d = defer.succeed(None)
- if self.on_attachment:
- d.addCallback(lambda _: self.on_attachment(mind))
- def returnAvatar(_):
- return pb.IPerspective, self.perspective, lambda: None
- d.addCallback(returnAvatar)
- return d
-
- def shutdown(self):
- return self.mind.broker.transport.loseConnection()
-
-class TestBuildSlave(misc.PatcherMixin, unittest.TestCase):
-
- def setUp(self):
- self.realm = None
- self.buildslave = None
- self.listeningport = None
-
- self.basedir = os.path.abspath("basedir")
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- os.makedirs(self.basedir)
-
- def tearDown(self):
- d = defer.succeed(None)
- if self.realm:
- d.addCallback(lambda _ : self.realm.shutdown())
- if self.buildslave and self.buildslave.running:
- d.addCallback(lambda _ : self.buildslave.stopService())
- if self.listeningport:
- d.addCallback(lambda _ : self.listeningport.stopListening())
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- return d
-
- def start_master(self, perspective, on_attachment=None):
- self.realm = MasterRealm(perspective, on_attachment)
- p = portal.Portal(self.realm)
- p.registerChecker(
- checkers.InMemoryUsernamePasswordDatabaseDontUse(testy="westy"))
- self.listeningport = reactor.listenTCP(0, pb.PBServerFactory(p), interface='127.0.0.1')
- # return the dynamically allocated port number
- return self.listeningport.getHost().port
-
- def test_constructor_minimal(self):
- # only required arguments
- bot.BuildSlave('mstr', 9010, 'me', 'pwd', '/s', 10, False)
-
- def test_constructor_083_tac(self):
- # invocation as made from default 083 tac files
- bot.BuildSlave('mstr', 9010, 'me', 'pwd', '/s', 10, False,
- umask=0123, maxdelay=10)
-
- def test_constructor_full(self):
- # invocation with all args
- bot.BuildSlave('mstr', 9010, 'me', 'pwd', '/s', 10, False,
- umask=0123, maxdelay=10, keepaliveTimeout=10,
- unicode_encoding='utf8', allow_shutdown=True)
-
- def test_buildslave_print(self):
- d = defer.Deferred()
-
- # set up to call print when we are attached, and chain the results onto
- # the deferred for the whole test
- def call_print(mind):
- print_d = mind.callRemote("print", "Hi, slave.")
- print_d.addCallbacks(d.callback, d.errback)
-
- # start up the master and slave
- persp = MasterPerspective()
- port = self.start_master(persp, on_attachment=call_print)
- self.buildslave = bot.BuildSlave("127.0.0.1", port,
- "testy", "westy", self.basedir,
- keepalive=0, usePTY=False, umask=022)
- self.buildslave.startService()
-
- # and wait for the result of the print
- return d
-
- def test_recordHostname_uname(self):
- self.patch_os_uname(lambda : [ 0, 'test-hostname.domain.com' ])
-
- self.buildslave = bot.BuildSlave("127.0.0.1", 9999,
- "testy", "westy", self.basedir,
- keepalive=0, usePTY=False, umask=022)
- self.buildslave.recordHostname(self.basedir)
- self.assertEqual(open(os.path.join(self.basedir, "twistd.hostname")).read().strip(),
- 'test-hostname.domain.com')
-
- def test_recordHostname_getfqdn(self):
- def missing():
- raise AttributeError
- self.patch_os_uname(missing)
- self.patch(socket, "getfqdn", lambda : 'test-hostname.domain.com')
-
- self.buildslave = bot.BuildSlave("127.0.0.1", 9999,
- "testy", "westy", self.basedir,
- keepalive=0, usePTY=False, umask=022)
- self.buildslave.recordHostname(self.basedir)
- self.assertEqual(open(os.path.join(self.basedir, "twistd.hostname")).read().strip(),
- 'test-hostname.domain.com')
-
- def test_buildslave_graceful_shutdown(self):
- """Test that running the build slave's gracefulShutdown method results
- in a call to the master's shutdown method"""
- d = defer.Deferred()
-
- fakepersp = Mock()
- called = []
- def fakeCallRemote(*args):
- called.append(args)
- d1 = defer.succeed(None)
- return d1
- fakepersp.callRemote = fakeCallRemote
-
- # set up to call shutdown when we are attached, and chain the results onto
- # the deferred for the whole test
- def call_shutdown(mind):
- self.buildslave.bf.perspective = fakepersp
- shutdown_d = self.buildslave.gracefulShutdown()
- shutdown_d.addCallbacks(d.callback, d.errback)
-
- persp = MasterPerspective()
- port = self.start_master(persp, on_attachment=call_shutdown)
-
- self.buildslave = bot.BuildSlave("127.0.0.1", port,
- "testy", "westy", self.basedir,
- keepalive=0, usePTY=False, umask=022)
-
- self.buildslave.startService()
-
- def check(ign):
- self.assertEquals(called, [('shutdown',)])
- d.addCallback(check)
-
- return d
-
- def test_buildslave_shutdown(self):
- """Test watching an existing shutdown_file results in gracefulShutdown
- being called."""
-
- buildslave = bot.BuildSlave("127.0.0.1", 1234,
- "testy", "westy", self.basedir,
- keepalive=0, usePTY=False, umask=022,
- allow_shutdown='file')
-
- # Mock out gracefulShutdown
- buildslave.gracefulShutdown = Mock()
-
- # Mock out os.path methods
- exists = Mock()
- mtime = Mock()
-
- self.patch(os.path, 'exists', exists)
- self.patch(os.path, 'getmtime', mtime)
-
- # Pretend that the shutdown file doesn't exist
- mtime.return_value = 0
- exists.return_value = False
-
- buildslave._checkShutdownFile()
-
- # We shouldn't have called gracefulShutdown
- self.assertEquals(buildslave.gracefulShutdown.call_count, 0)
-
- # Pretend that the file exists now, with an mtime of 2
- exists.return_value = True
- mtime.return_value = 2
- buildslave._checkShutdownFile()
-
- # Now we should have changed gracefulShutdown
- self.assertEquals(buildslave.gracefulShutdown.call_count, 1)
-
- # Bump the mtime again, and make sure we call shutdown again
- mtime.return_value = 3
- buildslave._checkShutdownFile()
- self.assertEquals(buildslave.gracefulShutdown.call_count, 2)
-
- # Try again, we shouldn't call shutdown another time
- buildslave._checkShutdownFile()
- self.assertEquals(buildslave.gracefulShutdown.call_count, 2)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_base.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_base.py
deleted file mode 100644
index 0385cc3a..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_base.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildslave.test.util.command import CommandTestMixin
-from buildslave.commands.base import Command
-
-# set up a fake Command subclass to test the handling in Command. Think of
-# this as testing Command's subclassability.
-
-class DummyCommand(Command):
-
- def setup(self, args):
- self.setup_done = True
- self.interrupted = False
- self.started = False
-
- def start(self):
- self.started = True
- self.sendStatus(self.args)
- self.cmd_deferred = defer.Deferred()
- return self.cmd_deferred
-
- def interrupt(self):
- self.interrupted = True
- self.finishCommand()
-
- def finishCommand(self):
- d = self.cmd_deferred
- self.cmd_deferred = None
- d.callback(None)
-
- def failCommand(self):
- d = self.cmd_deferred
- self.cmd_deferred = None
- d.errback(RuntimeError("forced failure"))
-
-class TestDummyCommand(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def assertState(self, setup_done, running, started, interrupted, msg=None):
- self.assertEqual(
- {
- 'setup_done' : self.cmd.setup_done,
- 'running' : self.cmd.running,
- 'started' : self.cmd.started,
- 'interrupted' : self.cmd.interrupted,
- }, {
- 'setup_done' : setup_done,
- 'running' : running,
- 'started' : started,
- 'interrupted' : interrupted,
- }, msg)
-
- def test_run(self):
- cmd = self.make_command(DummyCommand, { 'stdout' : 'yay' })
- self.assertState(True, False, False, False, "setup called by constructor")
-
- # start the command
- d = self.run_command()
- self.assertState(True, True, True, False, "started and running both set")
-
- # allow the command to finish and check the result
- cmd.finishCommand()
- def check(_):
- self.assertState(True, False, True, False, "started and not running when done")
- d.addCallback(check)
-
- def checkresult(_):
- self.assertUpdates([ { 'stdout' : 'yay' } ], "updates processed")
- d.addCallback(checkresult)
- return d
-
- def test_run_failure(self):
- cmd = self.make_command(DummyCommand, {})
- self.assertState(True, False, False, False, "setup called by constructor")
-
- # start the command
- d = self.run_command()
- self.assertState(True, True, True, False, "started and running both set")
-
- # fail the command with an exception, and check the result
- cmd.failCommand()
- def check(_):
- self.assertState(True, False, True, False, "started and not running when done")
- d.addErrback(check)
-
- def checkresult(_):
- self.assertUpdates([ {} ], "updates processed")
- d.addCallback(checkresult)
- return d
-
- def test_run_interrupt(self):
- cmd = self.make_command(DummyCommand, {})
- self.assertState(True, False, False, False, "setup called by constructor")
-
- # start the command
- d = self.run_command()
- self.assertState(True, True, True, False, "started and running both set")
-
- # interrupt the command
- cmd.doInterrupt()
- self.assertTrue(cmd.interrupted)
-
- def check(_):
- self.assertState(True, False, True, True, "finishes with interrupted set")
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bk.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bk.py
deleted file mode 100644
index da3cc352..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bk.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import bk
-
-class TestBK(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.patch_getCommand('bk', 'path/to/bk')
- self.clean_environ()
- self.make_command(bk.BK, dict(
- workdir='workdir',
- mode='copy',
- revision='1.114',
- bkurl='http://bkdemo.bkbits.net/bk_demo1',
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect(['path/to/bk', 'clone', '-r1.114',
- 'http://bkdemo.bkbits.net/bk_demo1', 'source'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/bk', 'changes', '-r+', '-d:REV:'],
- self.basedir_source,
- sendRC=False, usePTY=False, timeout=120, sendStderr=False,
- sendStdout=False, keepStdout=True, environ=exp_environ)
- + { 'stdout' : '1.114\n' } # TODO: is this what BK outputs?
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- # TODO: why the extra quotes?
- d.addCallback(self.check_sourcedata, '"http://bkdemo.bkbits.net/bk_demo1\n"')
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bzr.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bzr.py
deleted file mode 100644
index d8663acc..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_bzr.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import textwrap
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import bzr
-
-class TestBzr(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.patch_getCommand('bzr', 'path/to/bzr')
- self.clean_environ()
- self.make_command(bzr.Bzr, dict(
- workdir='workdir',
- mode='copy',
- revision='12',
- repourl='http://bazaar.launchpad.net/~bzr/bzr-gtk/trunk',
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- verinfo = textwrap.dedent("""\
- revision-id: pqm@pqm.ubuntu.com-20071211175118-s94sizduj201hrs5
- date: 2007-12-11 17:51:18 +0000
- build-date: 2007-12-13 13:14:51 +1000
- revno: 3104
- branch-nick: bzr.dev
- """)
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/bzr', 'checkout', '--revision', '12',
- 'http://bazaar.launchpad.net/~bzr/bzr-gtk/trunk', 'source' ],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/bzr', 'version-info'],
- self.basedir_source,
- sendRC=False, usePTY=False, keepStdout=True,
- environ=exp_environ, sendStderr=False, sendStdout=False)
- + { 'stdout' : verinfo }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://bazaar.launchpad.net/~bzr/bzr-gtk/trunk\n")
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_cvs.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_cvs.py
deleted file mode 100644
index c7d040c9..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_cvs.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import cvs
-
-class TestCVS(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.patch_getCommand('cvs', 'path/to/cvs')
- self.clean_environ()
- self.make_command(cvs.CVS, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- cvsroot=':pserver:anoncvs@anoncvs.NetBSD.org:/cvsroot',
- cvsmodule='htdocs',
- ))
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/cvs', '-d', ':pserver:anoncvs@anoncvs.NetBSD.org:/cvsroot',
- '-z3', 'checkout', '-d', 'source', 'htdocs' ],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata,
- ":pserver:anoncvs@anoncvs.NetBSD.org:/cvsroot\nhtdocs\nNone\n")
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_darcs.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_darcs.py
deleted file mode 100644
index e6953e31..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_darcs.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import darcs
-
-class TestDarcs(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.patch_getCommand('darcs', 'path/to/darcs')
- self.clean_environ()
- self.make_command(darcs.Darcs, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl='http://darcs.net',
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/darcs', 'get', '--verbose', '--lazy',
- '--repo-name', 'source', 'http://darcs.net'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/darcs', 'changes', '--context' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- environ=exp_environ, sendStderr=False, sendStdout=False)
- + { 'stdout' : example_changes }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://darcs.net\n")
- return d
-
-example_changes = """\
-
-Context:
-
-[Resolve issue1874: recognise network tests on cabal test command line.
-Eric Kow <kowey@darcs.net>**20100611102251
- Ignore-this: 59a455ef26b5df9a3bdd356e1e37854e
-]
-
-[haddocks for SelectChanges
-Florent Becker <florent.becker@ens-lyon.org>**20100610140023
- Ignore-this: c4203f746fc6278dc5290332e3625283
-]
-
-[better message when skipping already decided patches
-Florent Becker <florent.becker@ens-lyon.org>**20100531065630
- Ignore-this: 426675973555e75086781f0c54fbf925
-]
-
-[Accept issue1871: darcs record . failure for changes in subdir.
-Eric Kow <kowey@darcs.net>**20100609145047
- Ignore-this: dd942b980dd3006bfa5d176ec5cfdf99
-]
-
-[Extend the issue1014 test to check that named patches are not duplicated.
-Petr Rockai <me@mornfall.net>**20100607185041
- Ignore-this: 383ff17461076a798193b6c0c2427bba
-]
-
-[Haddock merge2FL and fastRemoveFL in Patch.Depends.
-Petr Rockai <me@mornfall.net>**20100607184849
- Ignore-this: cd6e79c4e404820d4f0ae94a53aed8c1
-]
-
-[Limit index updates to relevant subtree in a few cases.
-Petr Rockai <me@mornfall.net>**20100509102248
- Ignore-this: fea041133d039cecead73935f0cd6762
-]
-
-[Fix a bunch of "unused" warnings.
-Petr Rockai <me@mornfall.net>**20100607194111
- Ignore-this: 1fec82080eca9c3f10b690ee0ef81e34
-]
-
-[Shorten issue1210 test name.
-Eric Kow <kowey@darcs.net>**20100608090708
- Ignore-this: 57ff2a1cbb9795f80ae3d81e19717a9e
-]
-
-[Add test for issue1210: global cache gets recorded in _darcs/prefs/sources
-builes.adolfo@googlemail.com**20100608010902
- Ignore-this: bc02ada910927be93dd4a5cc9826d20d
-]
-
-[Fix typo in the BSD version of date arithmetic (testsuite).
-Petr Rockai <me@mornfall.net>**20100608062802
- Ignore-this: fdfb7aef46966a18edc2f7e93c0118f0
-]
-
-[Let's try to work with BSD date as well.
-Petr Rockai <me@mornfall.net>**20100608061631
- Ignore-this: 628e6f15e8f8d6801a3f1dd6c8605e17
-]
-
-[Fix a race condition in the match-date test.
-Petr Rockai <me@mornfall.net>**20100607223257
- Ignore-this: 4c6452bfdee6c03eb95abcd646add90f
-]
-"""
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_fs.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_fs.py
deleted file mode 100644
index 393d0029..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_fs.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import shutil
-from twisted.trial import unittest
-
-from buildslave.test.util.command import CommandTestMixin
-from buildslave.commands import fs
-from twisted.python import runtime
-from buildslave.commands import utils
-
-class TestRemoveDirectory(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.make_command(fs.RemoveDirectory, dict(
- dir='workdir',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertFalse(os.path.exists(os.path.abspath(os.path.join(self.basedir,'workdir'))))
- self.assertIn({'rc': 0},
- self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_simple_exception(self):
- if runtime.platformType == "posix":
- return # we only use rmdirRecursive on windows
- def fail(dir):
- raise RuntimeError("oh noes")
- self.patch(utils, 'rmdirRecursive', fail)
- self.make_command(fs.RemoveDirectory, dict(
- dir='workdir',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertIn({'rc': -1}, self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_multiple_dirs(self):
- self.make_command(fs.RemoveDirectory, dict(
- dir=['workdir', 'sourcedir'],
- ), True)
- d = self.run_command()
-
- def check(_):
- for dirname in ['workdir', 'sourcedir']:
- self.assertFalse(os.path.exists(os.path.abspath(os.path.join(self.basedir, dirname))))
- self.assertIn({'rc': 0},
- self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
-
-class TestCopyDirectory(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.make_command(fs.CopyDirectory, dict(
- fromdir='workdir',
- todir='copy',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertTrue(os.path.exists(os.path.abspath(os.path.join(self.basedir,'copy'))))
- self.assertIn({'rc': 0}, # this may ignore a 'header' : '..', which is OK
- self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_simple_exception(self):
- if runtime.platformType == "posix":
- return # we only use rmdirRecursive on windows
- def fail(src, dest):
- raise RuntimeError("oh noes")
- self.patch(shutil, 'copytree', fail)
- self.make_command(fs.CopyDirectory, dict(
- fromdir='workdir',
- todir='copy',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertIn({'rc': -1},
- self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
-
-class TestMakeDirectory(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.make_command(fs.MakeDirectory, dict(
- dir='test-dir',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertTrue(os.path.exists(os.path.abspath(os.path.join(self.basedir,'test-dir'))))
- self.assertUpdates(
- [{'rc': 0}],
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_already_exists(self):
- self.make_command(fs.MakeDirectory, dict(
- dir='workdir',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertUpdates(
- [{'rc': 0}],
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_existing_file(self):
- self.make_command(fs.MakeDirectory, dict(
- dir='test-file',
- ), True)
- open(os.path.join(self.basedir, 'test-file'), "w")
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([{'rc': 1}], self.builder.show())
- d.addErrback(check)
- return d
-
-class TestStatFile(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_non_existant(self):
- self.make_command(fs.StatFile, dict(
- file='no-such-file',
- ), True)
- d = self.run_command()
-
- def check(_):
- self.assertUpdates(
- [{'rc': 1}],
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_directory(self):
- self.make_command(fs.StatFile, dict(
- file='workdir',
- ), True)
- d = self.run_command()
-
- def check(_):
- import stat
- self.assertTrue(stat.S_ISDIR(self.get_updates()[0]['stat'][stat.ST_MODE]))
- self.assertIn({'rc': 0},
- self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
-
- def test_file(self):
- self.make_command(fs.StatFile, dict(
- file='test-file',
- ), True)
- open(os.path.join(self.basedir, 'test-file'), "w")
-
- d = self.run_command()
-
- def check(_):
- import stat
- self.assertTrue(stat.S_ISREG(self.get_updates()[0]['stat'][stat.ST_MODE]))
- self.assertIn({'rc': 0},
- self.get_updates(),
- self.builder.show())
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_git.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_git.py
deleted file mode 100644
index e22c733c..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_git.py
+++ /dev/null
@@ -1,701 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import git
-
-class TestGit(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def patch_sourcedirIsUpdateable(self, result):
- self.cmd.sourcedirIsUpdateable = lambda : result
-
- # tests
-
- def test_run_mode_copy_fresh_sourcedir(self):
- "Test a basic invocation with mode=copy and no existing sourcedir"
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- # no sourcedata -> will do fresh checkout
- initial_sourcedata = None,
- )
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- # TODO: capture makedirs invocation here
- Expect([ 'path/to/git', 'init'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
-
- def test_run_mode_copy_update_sourcedir(self):
- """test a copy where the sourcedata indicates that the source directory
- can be updated"""
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl='git://github.com/djmitche/buildbot.git',
- progress=True, # added here for better coverage
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master',
- '--progress' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_mode_copy_nonexistant_ref(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- branch='bogusref',
- repourl='git://github.com/djmitche/buildbot.git',
- ))
- self.patch_sourcedirIsUpdateable(True)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'clean', '-f', '-d', '-x'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+bogusref' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : "fatal: Couldn't find remote ref bogusref\n" }
- + { 'rc': 128 }
- + 128,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- return d
-
- def test_run_mode_copy_gerrit_branch(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- branch='local-branch',
- gerrit_branch='real-branch',
- repourl='git://github.com/djmitche/buildbot.git',
- ))
- self.patch_sourcedirIsUpdateable(True)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'clean', '-f', '-d', '-x'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+real-branch' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'local-branch'], # note, not the same branch
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- return d
-
- def test_run_mode_update_fresh(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(False)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'init'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_mode_update_existing(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- expects = [
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_mode_update_existing_known_rev(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision='abcdef01',
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- expects = [
- Expect(['path/to/git', 'reset', '--hard', 'abcdef01'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_mode_update_existing_unknown_rev(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision='abcdef01',
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- expects = [
- Expect(['path/to/git', 'reset', '--hard', 'abcdef01'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 1,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'abcdef01'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_with_reference(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- reference='/other/repo',
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(False)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'init'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'setFileContents',
- os.path.join(self.basedir_workdir,
- *'.git/objects/info/alternates'.split('/')),
- os.path.join('/other/repo', 'objects'), ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_with_shallow_and_rev(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision='deadbeef',
- shallow=True,
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(False)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'init'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'deadbeef'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_with_shallow(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- shallow=True,
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(False)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect(['path/to/git', 'clone', '--depth', '1',
- 'git://github.com/djmitche/buildbot.git',
- self.basedir_workdir],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_with_shallow_and_reference(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- shallow=True,
- reference="/some/repo",
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(False)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect(['path/to/git', 'clone', '--depth', '1',
- '--reference', '/some/repo', # note: no ../objects
- 'git://github.com/djmitche/buildbot.git',
- self.basedir_workdir],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'setFileContents',
- os.path.join(self.basedir_workdir,
- *'.git/objects/info/alternates'.split('/')),
- os.path.join('/some/repo', 'objects'), ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_run_with_submodules(self):
- self.patch_getCommand('git', 'path/to/git')
- self.clean_environ()
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- submodules=True,
- repourl='git://github.com/djmitche/buildbot.git',
- ),
- initial_sourcedata = "git://github.com/djmitche/buildbot.git master\n",
- )
- self.patch_sourcedirIsUpdateable(False)
-
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/git', 'init'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'fetch', '-t',
- 'git://github.com/djmitche/buildbot.git', '+master' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStderr=True)
- + { 'stderr' : '' }
- + 0,
- Expect(['path/to/git', 'reset', '--hard', 'FETCH_HEAD'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/git', 'branch', '-M', 'master'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'submodule', 'init' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'submodule', 'update' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'submodule', 'foreach',
- 'git', 'clean', '-f', '-d', '-x'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'path/to/git', 'rev-parse', 'HEAD' ],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True)
- + { 'stdout' : '4026d33b0532b11f36b0875f63699adfa8ee8662\n' }
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "git://github.com/djmitche/buildbot.git master\n")
- return d
-
- def test_sourcedataMatches_no_file(self):
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl='git://github.com/djmitche/buildbot.git',
- ), initial_sourcedata=None)
- self.assertFalse(self.cmd.sourcedataMatches())
-
- def test_sourcedataMatches_ok(self):
- self.make_command(git.Git, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl='git://github.com/djmitche/buildbot.git',
- # git command doesn't care what the contents of the sourcedata file is
- ), initial_sourcedata='xyz')
- self.assertTrue(self.cmd.sourcedataMatches())
-
- def do_test_parseGotRevision(self, stdout, exp):
- self.make_command(git.Git, dict(
- workdir='workdir',
- repourl='git://github.com/djmitche/buildbot.git',
- ))
- def _dovccmd(cmd, callback, keepStdout=False):
- self.assertTrue(keepStdout)
- self.cmd.command = mock.Mock()
- self.cmd.command.stdout = stdout
- d = defer.succeed(None)
- d.addCallback(callback)
- return d
- self.cmd._dovccmd = _dovccmd
-
- d = self.cmd.parseGotRevision()
- def check(res):
- self.assertEqual(res, exp)
- d.addCallback(check)
- return d
-
- def test_parseGotRevision_bogus(self):
- return self.do_test_parseGotRevision("fatal: Couldn't find revision 1234\n", None)
-
- def test_parseGotRevision_wrong_length(self):
- return self.do_test_parseGotRevision("\n1234abcd\n", None)
-
- def test_parseGotRevision_ok(self):
- return self.do_test_parseGotRevision(
- "\n4026d33b0532b11f36b0875f63699adfa8ee8662\n",
- "4026d33b0532b11f36b0875f63699adfa8ee8662")
-
- # TODO: gerrit_branch
- # TODO: consolidate Expect objects
- # TODO: ignore_ignores (w/ submodules)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_hg.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_hg.py
deleted file mode 100644
index ed90cf42..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_hg.py
+++ /dev/null
@@ -1,327 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import hg
-
-class TestMercurial(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def patch_sourcedirIsUpdateable(self, result):
- self.cmd.sourcedirIsUpdateable = lambda : result
-
- def test_simple(self):
- self.patch_getCommand('hg', 'path/to/hg')
- self.clean_environ()
- self.make_command(hg.Mercurial, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl='http://bitbucket.org/nicolas17/pyboinc',
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect(['path/to/hg', 'clone', '--verbose', '--noupdate',
- 'http://bitbucket.org/nicolas17/pyboinc', 'source'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'identify', '--num', '--branch'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : '-1 default\n' }
- + 0,
- Expect(['path/to/hg', 'paths', 'default'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : 'http://bitbucket.org/nicolas17/pyboinc\n' }
- + 0,
- Expect(['path/to/hg', 'update', '--clean', '--repository',
- 'source', '--rev', 'default'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'parents', '--template', '{node}\\n'],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'b7ddc0b638fa11cdac7c0345c40c6f76d8a7166d' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://bitbucket.org/nicolas17/pyboinc\n")
- return d
-
- def test_update_existing(self):
- self.patch_getCommand('hg', 'path/to/hg')
- self.clean_environ()
- self.make_command(hg.Mercurial, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- repourl='http://bitbucket.org/nicolas17/pyboinc',
- ),
- initial_sourcedata = "http://bitbucket.org/nicolas17/pyboinc\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect(['path/to/hg', 'pull', '--verbose', 'http://bitbucket.org/nicolas17/pyboinc'],
- self.basedir_workdir,
- sendRC=False, timeout=120, keepStdout=True, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'identify', '--num', '--branch'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : '-1 default\n' }
- + 0,
- Expect(['path/to/hg', 'paths', 'default'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : 'http://bitbucket.org/nicolas17/pyboinc\n' }
- + 0,
- Expect(['path/to/hg', 'update', '--clean', '--repository',
- 'workdir', '--rev', 'default'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'parents', '--template', '{node}\\n'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'b7ddc0b638fa11cdac7c0345c40c6f76d8a7166d' }
- + 0,
- ]
- self.patch_runprocess(*expects)
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://bitbucket.org/nicolas17/pyboinc\n")
- return d
-
-
- def test_update_existing_change_branch(self):
- self.patch_getCommand('hg', 'path/to/hg')
- self.clean_environ()
- self.make_command(hg.Mercurial, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- branch='stable',
- repourl='http://bitbucket.org/nicolas17/pyboinc',
- clobberOnBranchChange=True,
- ),
- initial_sourcedata = "http://bitbucket.org/nicolas17/pyboinc\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect(['path/to/hg', 'pull', '--verbose', 'http://bitbucket.org/nicolas17/pyboinc'],
- self.basedir_workdir,
- sendRC=False, timeout=120, keepStdout=True, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'identify', '--num', '--branch'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : '1 default\n' }
- + 0,
- Expect(['path/to/hg', 'paths', 'default'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : 'http://bitbucket.org/nicolas17/pyboinc\n' }
- + 0,
- Expect(['path/to/hg', 'purge', '--all'],
- self.basedir_workdir,
- keepStdout=True, keepStderr=True, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'update', '--clean', '--repository',
- 'workdir', '--rev', 'stable'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'parents', '--template', '{node}\\n'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'b7ddc0b638fa11cdac7c0345c40c6f76d8a7166d' }
- + 0,
-
- ]
- self.patch_runprocess(*expects)
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://bitbucket.org/nicolas17/pyboinc\n")
- return d
-
- def test_update_handle_emptyupdate(self):
- self.patch_getCommand('hg', 'path/to/hg')
- self.clean_environ()
- self.make_command(hg.Mercurial, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- repourl='http://bitbucket.org/nicolas17/pyboinc',
- ),
- initial_sourcedata = "http://bitbucket.org/nicolas17/pyboinc\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect(['path/to/hg', 'pull', '--verbose', 'http://bitbucket.org/nicolas17/pyboinc'],
- self.basedir_workdir,
- sendRC=False, timeout=120, keepStdout=True, usePTY=False)
- + 1,
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect(['path/to/hg', 'clone', '--verbose', '--noupdate',
- 'http://bitbucket.org/nicolas17/pyboinc', 'workdir'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'identify', '--num', '--branch'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : '-1 default\n' }
- + 0,
- Expect(['path/to/hg', 'paths', 'default'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : 'http://bitbucket.org/nicolas17/pyboinc\n' }
- + 0,
- Expect(['path/to/hg', 'update', '--clean', '--repository',
- 'workdir', '--rev', 'default'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'parents', '--template', '{node}\\n'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'b7ddc0b638fa11cdac7c0345c40c6f76d8a7166d' }
- + 0,
- ]
- self.patch_runprocess(*expects)
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://bitbucket.org/nicolas17/pyboinc\n")
- return d
-
- def test_update_existing_change_branch_purge_fail(self):
- self.patch_getCommand('hg', 'path/to/hg')
- self.clean_environ()
- self.make_command(hg.Mercurial, dict(
- workdir='workdir',
- mode='update',
- revision="abcdef01",
- branch='stable',
- repourl='http://bitbucket.org/nicolas17/pyboinc',
- clobberOnBranchChange=True,
- ),
- initial_sourcedata = "http://bitbucket.org/nicolas17/pyboinc\n",
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect(['path/to/hg', 'pull', '--verbose', 'http://bitbucket.org/nicolas17/pyboinc'],
- self.basedir_workdir,
- sendRC=False, timeout=120, keepStdout=True, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'identify', '--num', '--branch'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : '1 default\n' }
- + 0,
- Expect(['path/to/hg', 'paths', 'default'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : 'http://bitbucket.org/nicolas17/pyboinc\n' }
- + 0,
- Expect(['path/to/hg', 'purge', '--all'],
- self.basedir_workdir,
- keepStdout=True, keepStderr=True, usePTY=False)
- + 1,
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect(['path/to/hg', 'clone', '--verbose', '--noupdate',
- 'http://bitbucket.org/nicolas17/pyboinc', 'workdir'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'identify', '--num', '--branch'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : '-1 default\n' }
- + 0,
- Expect(['path/to/hg', 'paths', 'default'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- keepStderr=True)
- + { 'stdout' : 'http://bitbucket.org/nicolas17/pyboinc\n' }
- + 0,
- Expect(['path/to/hg', 'update', '--clean', '--repository',
- 'workdir', '--rev', 'abcdef01'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'update', '--clean', '--repository',
- 'workdir', '--rev', 'abcdef01'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect(['path/to/hg', 'parents', '--template', '{node}\\n'],
- self.basedir_workdir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'b7ddc0b638fa11cdac7c0345c40c6f76d8a7166d' }
- + 0,
-
- ]
- self.patch_runprocess(*expects)
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://bitbucket.org/nicolas17/pyboinc\n")
- return d
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_mtn.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_mtn.py
deleted file mode 100644
index 0987ad47..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_mtn.py
+++ /dev/null
@@ -1,527 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import mock
-
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import mtn
-
-class TestMonotone(SourceCommandTestMixin, unittest.TestCase):
- repourl='mtn://code.monotone.ca/sandbox'
- branch='ca.monotone.sandbox.buildbot'
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def patch_sourcedirIsUpdateable(self, result):
- self.cmd.sourcedirIsUpdateable = lambda : result
-
-
- def test_no_db(self):
- "Test a basic invocation with mode=copy and no existing sourcedir"
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl=self.repourl,
- branch=self.branch
- ),
- # no sourcedata -> will do fresh checkout
- initial_sourcedata = None,
- )
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect(['path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 1,
- Expect(['path/to/mtn', 'db', 'init',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- sendRC=False, usePTY=False,
- environ=exp_environ) + 1,
- Expect([ 'clobber', 'workdir' ],
- self.basedir) + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir) + 0,
- Expect(['path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=none'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'checkout', self.basedir_source,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--branch', 'ca.monotone.sandbox.buildbot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_source,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
-
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_db_needs_migrating(self):
- "Test a basic invocation with mode=copy and no existing sourcedir"
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl=self.repourl,
- branch=self.branch
- ),
- # no sourcedata -> will do fresh checkout
- initial_sourcedata = None,
- )
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn') ],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ)
- + { 'stdout' : 'blah blah (migration needed)\n' }
- + 0,
- Expect([ 'path/to/mtn', 'db', 'migrate',
- '--db', os.path.join(self.basedir, 'db.mtn') ],
- self.basedir,
- sendRC=False, usePTY=False,
- environ=exp_environ) + 0,
- Expect([ 'clobber', 'workdir' ],
- self.basedir) + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir) + 0,
- Expect(['path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=none'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'checkout', self.basedir_source,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--branch', 'ca.monotone.sandbox.buildbot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_source,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
-
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_db_too_new(self):
- "Test a basic invocation with mode=copy and no existing sourcedir"
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl=self.repourl,
- branch=self.branch
- ),
- # no sourcedata -> will do fresh checkout
- initial_sourcedata = None,
- )
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn') ],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ)
- + { 'stdout' : 'blah blah (too new, cannot use)\n' }
- + 0
- ]
-
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- return self.assertFailure(d, mtn.MonotoneError)
-
- def test_run_mode_copy_fresh_sourcedir(self):
- "Test a basic invocation with mode=copy and no existing sourcedir"
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl=self.repourl,
- branch=self.branch
- ),
- # no sourcedata -> will do fresh checkout
- initial_sourcedata = None,
- )
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect(['path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 0,
- Expect([ 'clobber', 'workdir' ],
- self.basedir) + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir) + 0,
- Expect(['path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=none'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'checkout', self.basedir_source,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--branch', 'ca.monotone.sandbox.buildbot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_source,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
-
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_run_mode_copy_update_sourcedir(self):
- """test a copy where the sourcedata indicates that the source directory
- can be updated"""
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- repourl=self.repourl,
- branch=self.branch,
- progress=True, # added here for better coverage
- ),
- initial_sourcedata = self.repourl+"?"+self.branch
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 0,
- Expect([ 'clobber', 'workdir' ],
- self.basedir) + 0,
- Expect([ 'path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=dot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'update',
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '-r', 'h:ca.monotone.sandbox.buildbot',
- '-b', 'ca.monotone.sandbox.buildbot'],
- self.basedir_source,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_source,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_run_mode_update_fresh(self):
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- repourl=self.repourl,
- branch=self.branch,
- progress=True, # added here for better coverage
- ),
- initial_sourcedata = self.repourl+"?"+self.branch
- )
- self.patch_sourcedirIsUpdateable(False)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 0,
- Expect([ 'clobber', 'workdir' ],
- self.basedir) + 0,
- Expect([ 'path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=dot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'checkout', self.basedir_workdir,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--branch', 'ca.monotone.sandbox.buildbot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_run_mode_update_existing(self):
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='update',
- revision=None,
- repourl=self.repourl,
- branch=self.branch,
- progress=True, # added here for better coverage
- ),
- initial_sourcedata = self.repourl+"?"+self.branch
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=dot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'update',
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '-r', 'h:ca.monotone.sandbox.buildbot',
- '-b', 'ca.monotone.sandbox.buildbot'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_run_mode_update_existing_known_rev(self):
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='update',
- revision='abcdef01',
- repourl=self.repourl,
- branch=self.branch,
- progress=True, # added here for better coverage
- ),
- initial_sourcedata = self.repourl+"?"+self.branch
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=dot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'update',
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--revision', 'abcdef01',
- '-b', 'ca.monotone.sandbox.buildbot'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
- def test_run_mode_update_existing_unknown_rev(self):
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.clean_environ()
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- mode='update',
- revision='abcdef01',
- repourl=self.repourl,
- branch=self.branch,
- progress=True, # added here for better coverage
- ),
- initial_sourcedata = self.repourl+"?"+self.branch
- )
- self.patch_sourcedirIsUpdateable(True)
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'path/to/mtn', 'db', 'info',
- '--db', os.path.join(self.basedir, 'db.mtn')],
- self.basedir,
- keepStdout=True, sendRC=False, sendStderr=False,
- usePTY=False, environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=dot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect([ 'path/to/mtn', 'update',
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--revision', 'abcdef01',
- '-b', 'ca.monotone.sandbox.buildbot'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 1,
- Expect([ 'clobber', 'workdir' ],
- self.basedir) + 0,
- Expect([ 'path/to/mtn', 'pull', self.repourl+"?"+self.branch,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--ticker=dot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'checkout', self.basedir_workdir,
- '--db', os.path.join(self.basedir, 'db.mtn'),
- '--revision', 'abcdef01',
- '--branch', 'ca.monotone.sandbox.buildbot'],
- self.basedir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False,
- environ=exp_environ) + 0,
- Expect(['path/to/mtn', 'automate', 'select', 'w:'],
- self.basedir_workdir,
- keepStdout=True, sendRC=False, timeout=120, usePTY=False)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, self.repourl+"?"+self.branch)
- return d
-
-# Testing parseGotRevision
- def do_test_parseGotRevision(self, stdout, exp):
- self.patch_getCommand('mtn', 'path/to/mtn')
- self.make_command(mtn.Monotone, dict(
- workdir='workdir',
- repourl=self.repourl,
- branch=self.branch
- ))
- def _dovccmd(fn, dopull, callback=None, keepStdout=False):
- #self.assertTrue(keepStdout)
- self.cmd.command = mock.Mock()
- self.cmd.command.stdout = stdout
- d = defer.succeed(None)
- d.addCallback(callback)
- return d
- self.cmd._dovccmd = _dovccmd
- self.cmd.srcdir = self.cmd.workdir
-
- d = self.cmd.parseGotRevision()
- def check(res):
- self.assertEqual(res, exp)
- d.addCallback(check)
- return d
-
- def test_parseGotRevision_bogus(self):
- return self.do_test_parseGotRevision("mtn: misuse: no match for selection '1234'\n", None)
-
- def test_parseGotRevision_wrong_length(self):
- return self.do_test_parseGotRevision("\n1234abcd\n", None)
-
- def test_parseGotRevision_ok(self):
- return self.do_test_parseGotRevision(
- "\n4026d33b0532b11f36b0875f63699adfa8ee8662\n",
- "4026d33b0532b11f36b0875f63699adfa8ee8662")
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_p4.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_p4.py
deleted file mode 100644
index efceb74d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_p4.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import p4
-from buildslave.util import Obfuscated
-
-class TestP4(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.patch_getCommand('p4', 'path/to/p4')
- self.clean_environ()
- self.make_command(p4.P4, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- p4port='p4dserv:1666',
- p4client='buildbot_test_10',
- p4user='jimmy',
- p4passwd='hushnow',
- p4base='//mydepot/myproj/',
- branch='mytrunk',
- p4extra_views=[],
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- # can't use textwrap.dedent here, because in 2.4 it converts \t to 8x' '
- client_spec = """\
-Client: buildbot_test_10
-
-Owner: jimmy
-
-Description:
-\tCreated by jimmy
-
-Root:\t%s
-
-Options:\tallwrite rmdir
-
-LineEnd:\tlocal
-
-View:
-\t//mydepot/myproj/mytrunk/... //buildbot_test_10/source/...
-""" % self.basedir
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect(['p4', '-p', 'p4dserv:1666', '-u', 'jimmy', '-P',
- Obfuscated('hushnow', 'XXXXXXXX'), 'client', '-i'],
- self.basedir,
- # TODO: empty env?
- sendRC=False, timeout=120, usePTY=False, environ={},
- initialStdin=client_spec)
- + 0,
- Expect(['p4', '-p', 'p4dserv:1666', '-u', 'jimmy', '-P',
- Obfuscated('hushnow', 'XXXXXXXX'), '-c', 'buildbot_test_10', 'sync', '-f'],
- self.basedir,
- # TODO: empty env?
- sendRC=False, timeout=120, usePTY=False, environ={})
- + 0,
- Expect(['p4', '-p', 'p4dserv:1666', '-u', 'jimmy', '-P',
- Obfuscated('hushnow', 'XXXXXXXX'), '-c', 'buildbot_test_10', 'changes',
- '-s', 'submitted', '-m', '1', '#have'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'Change 28147 on 2008/04/07 by p4user@hostname\n' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "['p4dserv:1666', 'buildbot_test_10', " +
- "'//mydepot/myproj/', 'mytrunk', [], None, %s, 'copy', 'workdir']"
- % `self.basedir`)
- return d
-
- def test_simple_unicode_args(self):
- self.patch_getCommand('p4', 'path/to/p4')
- self.clean_environ()
- self.make_command(p4.P4, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- p4port=u'p4dserv:1666\N{SNOWMAN}',
- p4client=u'buildbot_test_10\N{SNOWMAN}',
- p4user='jimmy',
- p4passwd='hushnow',
- p4base=u'//mydepot/myproj/\N{SNOWMAN}',
- branch=u'mytrunk\N{SNOWMAN}',
- p4extra_views=[],
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- # can't use textwrap.dedent here, because in 2.4 it converts \t to 8x' '
- client_spec = """\
-Client: buildbot_test_10
-
-Owner: jimmy
-
-Description:
-\tCreated by jimmy
-
-Root:\t%s
-
-Options:\tallwrite rmdir
-
-LineEnd:\tlocal
-
-View:
-\t//mydepot/myproj/mytrunk/... //buildbot_test_10/source/...
-""" % self.basedir
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect(['p4', '-p', u'p4dserv:1666\N{SNOWMAN}', '-u', 'jimmy', '-P',
- Obfuscated('hushnow', 'XXXXXXXX'), 'client', '-i'],
- self.basedir,
- # TODO: empty env?
- sendRC=False, timeout=120, usePTY=False, environ={},
- initialStdin=client_spec)
- + 0,
- Expect(['p4', '-p', u'p4dserv:1666\N{SNOWMAN}', '-u', 'jimmy', '-P',
- Obfuscated('hushnow', 'XXXXXXXX'), '-c',
- u'buildbot_test_10\N{SNOWMAN}', 'sync', '-f'],
- self.basedir,
- # TODO: empty env?
- sendRC=False, timeout=120, usePTY=False, environ={})
- + 0,
- Expect(['p4', '-p', u'p4dserv:1666\N{SNOWMAN}', '-u', 'jimmy', '-P',
- Obfuscated('hushnow', 'XXXXXXXX'), '-c',
- u'buildbot_test_10\N{SNOWMAN}', 'changes',
- '-s', 'submitted', '-m', '1', '#have'],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ,
- keepStdout=True)
- + { 'stdout' : 'Change 28147 on 2008/04/07 by p4user@hostname\n' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata,
- "['p4dserv:1666\\xe2\\x98\\x83', "
- "'buildbot_test_10\\xe2\\x98\\x83', "
- "'//mydepot/myproj/\\xe2\\x98\\x83', "
- "'mytrunk\\xe2\\x98\\x83', [], None, %s, 'copy', "
- "'workdir']"
- % `self.basedir`)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_registry.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_registry.py
deleted file mode 100644
index c451246e..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_registry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.commands import registry
-from buildslave.commands import shell
-
-class Registry(unittest.TestCase):
-
- def test_getFactory(self):
- factory = registry.getFactory('shell')
- self.assertEqual(factory, shell.SlaveShellCommand)
-
- def test_getFactory_KeyError(self):
- self.assertRaises(KeyError, lambda : registry.getFactory('nosuchcommand'))
-
- def test_getAllCommandNames(self):
- self.failUnless('shell' in registry.getAllCommandNames())
-
- def test_all_commands_exist(self):
- # if this doesn't raise a KeyError, then we're good
- for n in registry.getAllCommandNames():
- registry.getFactory(n)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_shell.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_shell.py
deleted file mode 100644
index e5dcac4a..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_shell.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.command import CommandTestMixin
-from buildslave.commands import shell
-
-class TestSlaveShellCommand(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.make_command(shell.SlaveShellCommand, dict(
- command=[ 'echo', 'hello' ],
- workdir='workdir',
- ))
-
- self.patch_runprocess(
- Expect([ 'echo', 'hello' ], self.basedir_workdir)
- + { 'hdr' : 'headers' } + { 'stdout' : 'hello\n' } + { 'rc' : 0 }
- + 0,
- )
-
- d = self.run_command()
-
- # note that SlaveShellCommand does not add any extra updates of it own
- def check(_):
- self.assertUpdates(
- [{'hdr': 'headers'}, {'stdout': 'hello\n'}, {'rc': 0}],
- self.builder.show())
- d.addCallback(check)
- return d
-
- # TODO: test all functionality that SlaveShellCommand adds atop RunProcess
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_svn.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_svn.py
deleted file mode 100644
index fae28588..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_svn.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave.test.fake.runprocess import Expect
-from buildslave.test.util.sourcecommand import SourceCommandTestMixin
-from buildslave.commands import svn
-
-class TestSVN(SourceCommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- def tearDown(self):
- self.tearDownCommand()
-
- def test_simple(self):
- self.patch_getCommand('svn', 'path/to/svn')
- self.patch_getCommand('svnversion', 'path/to/svnversion')
- self.clean_environ()
- self.make_command(svn.SVN, dict(
- workdir='workdir',
- mode='copy',
- revision=None,
- svnurl='http://svn.local/app/trunk',
- ))
-
- exp_environ = dict(PWD='.', LC_MESSAGES='C')
- expects = [
- Expect([ 'clobber', 'workdir' ],
- self.basedir)
- + 0,
- Expect([ 'clobber', 'source' ],
- self.basedir)
- + 0,
- Expect([ 'path/to/svn', 'checkout', '--non-interactive', '--no-auth-cache',
- '--revision', 'HEAD', 'http://svn.local/app/trunk@HEAD', 'source' ],
- self.basedir,
- sendRC=False, timeout=120, usePTY=False, environ=exp_environ)
- + 0,
- Expect([ 'path/to/svnversion', '.' ],
- self.basedir_source,
- sendRC=False, timeout=120, usePTY=False, keepStdout=True,
- environ=exp_environ, sendStderr=False, sendStdout=False)
- + { 'stdout' : '9753\n' }
- + 0,
- Expect([ 'copy', 'source', 'workdir'],
- self.basedir)
- + 0,
- ]
- self.patch_runprocess(*expects)
-
- d = self.run_command()
- d.addCallback(self.check_sourcedata, "http://svn.local/app/trunk\n")
- return d
-
-
-class TestGetUnversionedFiles(unittest.TestCase):
- def test_getUnversionedFiles_does_not_list_externals(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals(["svn_external_path/unversioned_file"], unversioned_files)
-
- def test_getUnversionedFiles_does_not_list_missing(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="missing_file">
- <wc-status props="none" item="missing"></wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals([], unversioned_files)
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_transfer.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_transfer.py
deleted file mode 100644
index 45dc7779..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_transfer.py
+++ /dev/null
@@ -1,527 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import sys
-import shutil
-import tarfile
-import StringIO
-
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from twisted.python import runtime, failure
-
-from buildslave.test.fake.remote import FakeRemote
-from buildslave.test.util.command import CommandTestMixin
-from buildslave.commands import transfer
-
-class FakeMasterMethods(object):
- # a fake to represent any of:
- # - FileWriter
- # - FileDirectoryWriter
- # - FileReader
- def __init__(self, add_update):
- self.add_update = add_update
-
- self.delay_write = False
- self.count_writes = False
- self.keep_data = False
- self.write_out_of_space_at = None
-
- self.delay_read = False
- self.count_reads = False
-
- self.unpack_fail = False
-
- self.written = False
- self.read = False
- self.data = ''
-
- def remote_write(self, data):
- if self.write_out_of_space_at is not None:
- self.write_out_of_space_at -= len(data)
- if self.write_out_of_space_at <= 0:
- f = failure.Failure(RuntimeError("out of space"))
- return defer.fail(f)
- if self.count_writes:
- self.add_update('write %d' % len(data))
- elif not self.written:
- self.add_update('write(s)')
- self.written = True
-
- if self.keep_data:
- self.data += data
-
- if self.delay_write:
- d = defer.Deferred()
- reactor.callLater(0.01, d.callback, None)
- return d
-
- def remote_read(self, length):
- if self.count_reads:
- self.add_update('read %d' % length)
- elif not self.read:
- self.add_update('read(s)')
- self.read = True
-
- if not self.data:
- return ''
-
- slice, self.data = self.data[:length], self.data[length:]
- if self.delay_read:
- d = defer.Deferred()
- reactor.callLater(0.01, d.callback, slice)
- return d
- else:
- return slice
-
- def remote_unpack(self):
- self.add_update('unpack')
- if self.unpack_fail:
- return defer.fail(failure.Failure(RuntimeError("out of space")))
-
- def remote_utime(self,accessed_modified):
- self.add_update('utime - %s' % accessed_modified[0])
-
- def remote_close(self):
- self.add_update('close')
-
-class TestUploadFile(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- self.fakemaster = FakeMasterMethods(self.add_update)
-
- # write 180 bytes of data to upload
- self.datadir = os.path.join(self.basedir, 'workdir')
- if os.path.exists(self.datadir):
- shutil.rmtree(self.datadir)
- os.makedirs(self.datadir)
-
- self.datafile = os.path.join(self.datadir, 'data')
- # note: use of 'wb' here ensures newlines aren't translated on the upload
- open(self.datafile, "wb").write("this is some data\n" * 10)
-
- def tearDown(self):
- self.tearDownCommand()
-
- if os.path.exists(self.datadir):
- shutil.rmtree(self.datadir)
-
- def test_simple(self):
- self.fakemaster.count_writes = True # get actual byte counts
-
- self.make_command(transfer.SlaveFileUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=1000,
- blocksize=64,
- keepstamp=False,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datafile},
- 'write 64', 'write 64', 'write 52', 'close',
- {'rc': 0}
- ])
- d.addCallback(check)
- return d
-
- def test_truncated(self):
- self.fakemaster.count_writes = True # get actual byte counts
-
- self.make_command(transfer.SlaveFileUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=100,
- blocksize=64,
- keepstamp=False,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datafile},
- 'write 64', 'write 36', 'close',
- {'rc': 1,
- 'stderr': "Maximum filesize reached, truncating file '%s'" % self.datafile}
- ])
- d.addCallback(check)
- return d
-
- def test_missing(self):
- self.make_command(transfer.SlaveFileUploadCommand, dict(
- workdir='workdir',
- slavesrc='data-nosuch',
- writer=FakeRemote(self.fakemaster),
- maxsize=100,
- blocksize=64,
- keepstamp=False,
- ))
-
- d = self.run_command()
-
- def check(_):
- df = self.datafile + "-nosuch"
- self.assertUpdates([
- {'header': 'sending %s' % df},
- 'close',
- {'rc': 1,
- 'stderr': "Cannot open file '%s' for upload" % df}
- ])
- d.addCallback(check)
- return d
-
- def test_out_of_space(self):
- self.fakemaster.write_out_of_space_at = 70
- self.fakemaster.count_writes = True # get actual byte counts
-
- self.make_command(transfer.SlaveFileUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=1000,
- blocksize=64,
- keepstamp=False,
- ))
-
- d = self.run_command()
- self.assertFailure(d, RuntimeError)
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datafile},
- 'write 64', 'close',
- {'rc': 1}
- ])
- d.addCallback(check)
- return d
-
- def test_interrupted(self):
- self.fakemaster.delay_write = True # write veery slowly
-
- self.make_command(transfer.SlaveFileUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=100,
- blocksize=2,
- keepstamp=False,
- ))
-
- d = self.run_command()
-
- # wait a jiffy..
- interrupt_d = defer.Deferred()
- reactor.callLater(0.01, interrupt_d.callback, None)
-
- # and then interrupt the step
- def do_interrupt(_):
- return self.cmd.interrupt()
- interrupt_d.addCallback(do_interrupt)
-
- dl = defer.DeferredList([d, interrupt_d])
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datafile},
- 'write(s)', 'close', {'rc': 1}
- ])
- dl.addCallback(check)
- return dl
-
- def test_timestamp(self):
- self.fakemaster.count_writes = True # get actual byte counts
- timestamp = ( os.path.getatime(self.datafile),
- os.path.getmtime(self.datafile) )
-
- self.make_command(transfer.SlaveFileUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=1000,
- blocksize=64,
- keepstamp=True,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datafile},
- 'write 64', 'write 64', 'write 52',
- 'close','utime - %s' % timestamp[0],
- {'rc': 0}
- ])
- d.addCallback(check)
- return d
-
-class TestSlaveDirectoryUpload(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- self.fakemaster = FakeMasterMethods(self.add_update)
-
- # write a directory to upload
- self.datadir = os.path.join(self.basedir, 'workdir', 'data')
- if os.path.exists(self.datadir):
- shutil.rmtree(self.datadir)
- os.makedirs(self.datadir)
- open(os.path.join(self.datadir, "aa"), "wb").write("lots of a" * 100)
- open(os.path.join(self.datadir, "bb"), "wb").write("and a little b" * 17)
-
- def tearDown(self):
- self.tearDownCommand()
-
- if os.path.exists(self.datadir):
- shutil.rmtree(self.datadir)
-
- def test_simple(self, compress=None):
- self.fakemaster.keep_data = True
-
- self.make_command(transfer.SlaveDirectoryUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=None,
- blocksize=512,
- compress=compress,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datadir},
- 'write(s)', 'unpack', # note no 'close"
- {'rc': 0}
- ])
- d.addCallback(check)
-
- def check_tarfile(_):
- f = StringIO.StringIO(self.fakemaster.data)
- a = tarfile.open(fileobj=f, name='check.tar')
- exp_names = [ '.', 'aa', 'bb' ]
- got_names = [ n.rstrip('/') for n in a.getnames() ]
- got_names = sorted([ n or '.' for n in got_names ]) # py27 uses '' instead of '.'
- self.assertEqual(got_names, exp_names, "expected archive contents")
- a.close()
- f.close()
- d.addCallback(check_tarfile)
-
- return d
-
- # try it again with bz2 and gzip
- def test_simple_bz2(self):
- return self.test_simple('bz2')
- def test_simple_gz(self):
- return self.test_simple('gz')
-
- # except bz2 can't operate in stream mode on py24
- if sys.version_info[:2] <= (2,4):
- test_simple_bz2.skip = "bz2 stream decompression not supported on Python-2.4"
-
- def test_out_of_space_unpack(self):
- self.fakemaster.keep_data = True
- self.fakemaster.unpack_fail = True
-
- self.make_command(transfer.SlaveDirectoryUploadCommand, dict(
- workdir='workdir',
- slavesrc='data',
- writer=FakeRemote(self.fakemaster),
- maxsize=None,
- blocksize=512,
- compress=None
- ))
-
- d = self.run_command()
- self.assertFailure(d, RuntimeError)
-
- def check(_):
- self.assertUpdates([
- {'header': 'sending %s' % self.datadir},
- 'write(s)', 'unpack',
- {'rc': 1}
- ])
- d.addCallback(check)
-
- return d
-
- # this is just a subclass of SlaveUpload, so the remaining permutations
- # are already tested
-
-class TestDownloadFile(CommandTestMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpCommand()
-
- self.fakemaster = FakeMasterMethods(self.add_update)
-
- # the command will write to the basedir, so make sure it exists
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- os.makedirs(self.basedir)
-
- def tearDown(self):
- self.tearDownCommand()
-
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
-
- def test_simple(self):
- self.fakemaster.count_reads = True # get actual byte counts
- self.fakemaster.data = test_data = '1234' * 13
- assert(len(self.fakemaster.data) == 52)
-
- self.make_command(transfer.SlaveFileDownloadCommand, dict(
- workdir='.',
- slavedest='data',
- reader=FakeRemote(self.fakemaster),
- maxsize=None,
- blocksize=32,
- mode=0777,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- 'read 32', 'read 32', 'read 32', 'close',
- {'rc': 0}
- ])
- datafile = os.path.join(self.basedir, 'data')
- self.assertTrue(os.path.exists(datafile))
- self.assertEqual(open(datafile).read(), test_data)
- if runtime.platformType != 'win32':
- self.assertEqual(os.stat(datafile).st_mode & 0777, 0777)
- d.addCallback(check)
- return d
-
- def test_mkdir(self):
- self.fakemaster.data = test_data = 'hi'
-
- self.make_command(transfer.SlaveFileDownloadCommand, dict(
- workdir='workdir',
- slavedest=os.path.join('subdir', 'data'),
- reader=FakeRemote(self.fakemaster),
- maxsize=None,
- blocksize=32,
- mode=0777,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- 'read(s)', 'close',
- {'rc': 0}
- ])
- datafile = os.path.join(self.basedir, 'workdir', 'subdir', 'data')
- self.assertTrue(os.path.exists(datafile))
- self.assertEqual(open(datafile).read(), test_data)
- d.addCallback(check)
- return d
-
- def test_failure(self):
- self.fakemaster.data = 'hi'
-
- os.makedirs(os.path.join(self.basedir, 'dir'))
- self.make_command(transfer.SlaveFileDownloadCommand, dict(
- workdir='.',
- slavedest='dir', ## but that's a directory!
- reader=FakeRemote(self.fakemaster),
- maxsize=None,
- blocksize=32,
- mode=0777,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- 'close',
- {'rc': 1,
- 'stderr': "Cannot open file '%s' for download"
- % os.path.join(self.basedir, '.', 'dir')}
- ])
- d.addCallback(check)
- return d
-
-
- def test_truncated(self):
- self.fakemaster.data = test_data = 'tenchars--' * 10
-
- self.make_command(transfer.SlaveFileDownloadCommand, dict(
- workdir='.',
- slavedest='data',
- reader=FakeRemote(self.fakemaster),
- maxsize=50,
- blocksize=32,
- mode=0777,
- ))
-
- d = self.run_command()
-
- def check(_):
- self.assertUpdates([
- 'read(s)', 'close',
- {'rc': 1,
- 'stderr': "Maximum filesize reached, truncating file '%s'"
- % os.path.join(self.basedir, '.', 'data')}
- ])
- datafile = os.path.join(self.basedir, 'data')
- self.assertTrue(os.path.exists(datafile))
- self.assertEqual(open(datafile).read(), test_data[:50])
- d.addCallback(check)
- return d
-
- def test_interrupted(self):
- self.fakemaster.data = 'tenchars--' * 100 # 1k
- self.fakemaster.delay_read = True # read veery slowly
-
- self.make_command(transfer.SlaveFileDownloadCommand, dict(
- workdir='.',
- slavedest='data',
- reader=FakeRemote(self.fakemaster),
- maxsize=100,
- blocksize=2,
- mode=0777,
- ))
-
- d = self.run_command()
-
- # wait a jiffy..
- interrupt_d = defer.Deferred()
- reactor.callLater(0.01, interrupt_d.callback, None)
-
- # and then interrupt the step
- def do_interrupt(_):
- return self.cmd.interrupt()
- interrupt_d.addCallback(do_interrupt)
-
- dl = defer.DeferredList([d, interrupt_d])
- def check(_):
- self.assertUpdates([
- 'read(s)', 'close', {'rc': 1}
- ])
- dl.addCallback(check)
- return dl
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_utils.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_utils.py
deleted file mode 100644
index 2dae394d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_commands_utils.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os, sys
-import shutil
-
-from twisted.trial import unittest
-from twisted.python import runtime
-import twisted.python.procutils
-
-from buildslave.commands import utils
-
-class GetCommand(unittest.TestCase):
-
- def setUp(self):
- # monkey-patch 'which' to return something appropriate
- self.which_results = {}
- def which(arg):
- return self.which_results.get(arg, [])
- self.patch(twisted.python.procutils, 'which', which)
- # note that utils.py currently imports which by name, so we
- # patch it there, too
- self.patch(utils, 'which', which)
-
- def set_which_results(self, results):
- self.which_results = results
-
- def test_getCommand_empty(self):
- self.set_which_results({
- 'xeyes' : [],
- })
- self.assertRaises(RuntimeError, lambda : utils.getCommand('xeyes'))
-
- def test_getCommand_single(self):
- self.set_which_results({
- 'xeyes' : [ '/usr/bin/xeyes' ],
- })
- self.assertEqual(utils.getCommand('xeyes'), '/usr/bin/xeyes')
-
- def test_getCommand_multi(self):
- self.set_which_results({
- 'xeyes' : [ '/usr/bin/xeyes', '/usr/X11/bin/xeyes' ],
- })
- self.assertEqual(utils.getCommand('xeyes'), '/usr/bin/xeyes')
-
- def test_getCommand_single_exe(self):
- self.set_which_results({
- 'xeyes' : [ '/usr/bin/xeyes' ],
- # it should not select this option, since only one matched
- # to begin with
- 'xeyes.exe' : [ r'c:\program files\xeyes.exe' ],
- })
- self.assertEqual(utils.getCommand('xeyes'), '/usr/bin/xeyes')
-
- def test_getCommand_multi_exe(self):
- self.set_which_results({
- 'xeyes' : [ r'c:\program files\xeyes.com', r'c:\program files\xeyes.exe' ],
- 'xeyes.exe' : [ r'c:\program files\xeyes.exe' ],
- })
- # this one will work out differently depending on platform..
- if runtime.platformType == 'win32':
- self.assertEqual(utils.getCommand('xeyes'), r'c:\program files\xeyes.exe')
- else:
- self.assertEqual(utils.getCommand('xeyes'), r'c:\program files\xeyes.com')
-
-class RmdirRecursive(unittest.TestCase):
-
- # this is more complicated than you'd think because Twisted doesn't
- # rmdir its test directory very well, either..
-
- def setUp(self):
- self.target = 'testdir'
- try:
- if os.path.exists(self.target):
- shutil.rmtree(self.target)
- except:
- # this test will probably fail anyway
- e = sys.exc_info()[0]
- raise unittest.SkipTest("could not clean before test: %s" % (e,))
-
- # fill it with some files
- os.mkdir(os.path.join(self.target))
- open( os.path.join(self.target, "a"), "w")
- os.mkdir(os.path.join(self.target, "d"))
- open( os.path.join(self.target, "d", "a"), "w")
- os.mkdir(os.path.join(self.target, "d", "d"))
- open( os.path.join(self.target, "d", "d", "a"), "w")
-
- def tearDown(self):
- try:
- if os.path.exists(self.target):
- shutil.rmtree(self.target)
- except:
- print "\n(target directory was not removed by test, and cleanup failed too)\n"
- raise
-
- def test_rmdirRecursive_easy(self):
- utils.rmdirRecursive(self.target)
- self.assertFalse(os.path.exists(self.target))
-
- def test_rmdirRecursive_symlink(self):
- # this was intended as a regression test for #792, but doesn't seem
- # to trigger it. It can't hurt to check it, all the same.
- if runtime.platformType == 'win32':
- raise unittest.SkipTest("no symlinks on this platform")
- os.mkdir("noperms")
- open("noperms/x", "w")
- os.chmod("noperms/x", 0)
- try:
- os.symlink("../noperms", os.path.join(self.target, "link"))
- utils.rmdirRecursive(self.target)
- # that shouldn't delete the target of the symlink
- self.assertTrue(os.path.exists("noperms"))
- finally:
- # even Twisted can't clean this up very well, so try hard to
- # clean it up ourselves..
- os.chmod("noperms/x", 0777)
- os.unlink("noperms/x")
- os.rmdir("noperms")
-
- self.assertFalse(os.path.exists(self.target))
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_runprocess.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_runprocess.py
deleted file mode 100644
index 17226fa4..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_runprocess.py
+++ /dev/null
@@ -1,700 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import re
-import os
-import time
-import signal
-
-from twisted.trial import unittest
-from twisted.internet import task, defer, reactor
-from twisted.python import runtime, util, log
-
-from buildslave.test.util.misc import nl, BasedirMixin
-from buildslave.test.util import compat
-from buildslave.test.fake.slavebuilder import FakeSlaveBuilder
-from buildslave.exceptions import AbandonChain
-from buildslave import runprocess, util as bsutil
-
-def stdoutCommand(output):
- return [sys.executable, '-c', 'import sys; sys.stdout.write("%s\\n")' % output]
-
-def stderrCommand(output):
- return [sys.executable, '-c', 'import sys; sys.stderr.write("%s\\n")' % output]
-
-def sleepCommand(dur):
- return [sys.executable, '-c', 'import time; time.sleep(%d)' % dur]
-
-def scriptCommand(function, *args):
- runprocess_scripts = util.sibpath(__file__, 'runprocess-scripts.py')
- return [sys.executable, runprocess_scripts, function] + list(args)
-
-# windows returns rc 1, because exit status cannot indicate "signalled";
-# posix returns rc -1 for "signalled"
-FATAL_RC = -1
-if runtime.platformType == 'win32':
- FATAL_RC = 1
-
-# We would like to see debugging output in the test.log
-runprocess.RunProcessPP.debug = True
-
-class TestRunProcess(BasedirMixin, unittest.TestCase):
- def setUp(self):
- self.setUpBasedir()
-
- def tearDown(self):
- self.tearDownBasedir()
-
- def testCommandEncoding(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, u'abcd', self.basedir)
- self.assertIsInstance(s.command, str)
- self.assertIsInstance(s.fake_command, str)
-
- def testCommandEncodingList(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, [ u'abcd', 'efg' ], self.basedir)
- self.assertIsInstance(s.command[0], str)
- self.assertIsInstance(s.fake_command[0], str)
-
- def testCommandEncodingObfuscated(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b,
- [ bsutil.Obfuscated(u'abcd', u'ABCD') ],
- self.basedir)
- self.assertIsInstance(s.command[0], str)
- self.assertIsInstance(s.fake_command[0], str)
-
- def testStart(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('hello\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testNoStdout(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir, sendStdout=False)
-
- d = s.start()
- def check(ign):
- self.failIf({'stdout': nl('hello\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testKeepStdout(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir, keepStdout=True)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('hello\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- self.failUnlessEquals(s.stdout, nl('hello\n'))
- d.addCallback(check)
- return d
-
- def testStderr(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stderrCommand("hello"), self.basedir)
-
- d = s.start()
- def check(ign):
- self.failIf({'stderr': nl('hello\n')} not in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testNoStderr(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stderrCommand("hello"), self.basedir, sendStderr=False)
-
- d = s.start()
- def check(ign):
- self.failIf({'stderr': nl('hello\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testKeepStderr(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stderrCommand("hello"), self.basedir, keepStderr=True)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stderr': nl('hello\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- self.failUnlessEquals(s.stderr, nl('hello\n'))
- d.addCallback(check)
- return d
-
- def testStringCommand(self):
- b = FakeSlaveBuilder(False, self.basedir)
- # careful! This command must execute the same on windows and UNIX
- s = runprocess.RunProcess(b, 'echo hello', self.basedir)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('hello\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testMultiWordStringCommand(self):
- b = FakeSlaveBuilder(False, self.basedir)
- # careful! This command must execute the same on windows and UNIX
- s = runprocess.RunProcess(b, 'echo Happy Days and Jubilation',
- self.basedir)
-
- # no quoting occurs
- exp = nl('Happy Days and Jubilation\n')
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': exp} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testMultiWordStringCommandQuotes(self):
- b = FakeSlaveBuilder(False, self.basedir)
- # careful! This command must execute the same on windows and UNIX
- s = runprocess.RunProcess(b, 'echo "Happy Days and Jubilation"',
- self.basedir)
-
- if runtime.platformType == "win32":
- # echo doesn't parse out the quotes, so they come through in the
- # output
- exp = nl('"Happy Days and Jubilation"\n')
- else:
- exp = nl('Happy Days and Jubilation\n')
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': exp} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testMultiWordCommand(self):
- b = FakeSlaveBuilder(False, self.basedir)
- # careful! This command must execute the same on windows and UNIX
- s = runprocess.RunProcess(b, ['echo', 'Happy Days and Jubilation'],
- self.basedir)
-
- if runtime.platformType == "win32":
- # Twisted adds quotes to all arguments, and echo doesn't remove
- # them, so they appear in the output.
- exp = nl('"Happy Days and Jubilation"\n')
- else:
- exp = nl('Happy Days and Jubilation\n')
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': exp} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- @compat.skipUnlessPlatformIs("win32")
- def testPipeEmbedded(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, ['echo', 'escaped|pipe'],
- self.basedir)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('escaped|pipe\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- @compat.skipUnlessPlatformIs("win32")
- def testPipeAlone(self):
- b = FakeSlaveBuilder(False, self.basedir)
- #this is highly contrived, but it proves the point.
- cmd = stdoutCommand("b\\na")
- cmd[0] = cmd[0].replace(".exe","")
- cmd.extend(['|','sort'])
- s = runprocess.RunProcess(b, cmd, self.basedir)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('a\nb\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- @compat.skipUnlessPlatformIs("win32")
- def testPipeString(self):
- b = FakeSlaveBuilder(False, self.basedir)
- #this is highly contrived, but it proves the point.
- cmd = sys.executable + ' -c "import sys; sys.stdout.write(\'b\\na\\n\')" | sort'
- s = runprocess.RunProcess(b, cmd, self.basedir)
-
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('a\nb\n')} in b.updates, b.show())
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- def testCommandTimeout(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, sleepCommand(10), self.basedir, timeout=5)
- clock = task.Clock()
- s._reactor = clock
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('hello\n')} not in b.updates, b.show())
- self.failUnless({'rc': FATAL_RC} in b.updates, b.show())
- d.addCallback(check)
- clock.advance(6)
- return d
-
- def testCommandMaxTime(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, sleepCommand(10), self.basedir, maxTime=5)
- clock = task.Clock()
- s._reactor = clock
- d = s.start()
- def check(ign):
- self.failUnless({'stdout': nl('hello\n')} not in b.updates, b.show())
- self.failUnless({'rc': FATAL_RC} in b.updates, b.show())
- d.addCallback(check)
- clock.advance(6) # should knock out maxTime
- return d
-
- @compat.skipUnlessPlatformIs("posix")
- def test_stdin_closed(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b,
- scriptCommand('assert_stdin_closed'),
- self.basedir,
- usePTY=False, # if usePTY=True, stdin is never closed
- logEnviron=False)
- d = s.start()
- def check(ign):
- self.failUnless({'rc': 0} in b.updates, b.show())
- d.addCallback(check)
- return d
-
- @compat.usesFlushLoggedErrors
- def test_startCommand_exception(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, ['whatever'], self.basedir)
-
- # set up to cause an exception in _startCommand
- def _startCommand(*args, **kwargs):
- raise RuntimeError()
- s._startCommand = _startCommand
-
- d = s.start()
- def check(err):
- err.trap(AbandonChain)
- stderr = []
- # Here we're checking that the exception starting up the command
- # actually gets propogated back to the master in stderr.
- for u in b.updates:
- if 'stderr' in u:
- stderr.append(u['stderr'])
- stderr = "".join(stderr)
- self.failUnless("RuntimeError" in stderr, stderr)
- d.addBoth(check)
- d.addBoth(lambda _ : self.flushLoggedErrors())
- return d
-
- def testLogEnviron(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir,
- environ={"FOO": "BAR"})
-
- d = s.start()
- def check(ign):
- headers = "".join([update.values()[0] for update in b.updates if update.keys() == ["header"] ])
- self.failUnless("FOO=BAR" in headers, "got:\n" + headers)
- d.addCallback(check)
- return d
-
- def testNoLogEnviron(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir,
- environ={"FOO": "BAR"}, logEnviron=False)
-
- d = s.start()
- def check(ign):
- headers = "".join([update.values()[0] for update in b.updates if update.keys() == ["header"] ])
- self.failUnless("FOO=BAR" not in headers, "got:\n" + headers)
- d.addCallback(check)
- return d
-
- def testEnvironExpandVar(self):
- b = FakeSlaveBuilder(False, self.basedir)
- environ = {"EXPND": "-${PATH}-",
- "DOESNT_EXPAND": "-${---}-",
- "DOESNT_FIND": "-${DOESNT_EXISTS}-"}
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir, environ=environ)
-
- d = s.start()
- def check(ign):
- headers = "".join([update.values()[0] for update in b.updates if update.keys() == ["header"] ])
- self.failUnless("EXPND=-$" not in headers, "got:\n" + headers)
- self.failUnless("DOESNT_FIND=--" in headers, "got:\n" + headers)
- self.failUnless("DOESNT_EXPAND=-${---}-" in headers, "got:\n" + headers)
- d.addCallback(check)
- return d
-
- def testUnsetEnvironVar(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir,
- environ={"PATH":None})
-
- d = s.start()
- def check(ign):
- headers = "".join([update.values()[0] for update in b.updates if update.keys() == ["header"] ])
- self.failUnless(not re.match('\bPATH=',headers), "got:\n" + headers)
- d.addCallback(check)
- return d
-
- def testEnvironPythonPath(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir,
- environ={"PYTHONPATH":'a'})
-
- d = s.start()
- def check(ign):
- headers = "".join([update.values()[0] for update in b.updates if update.keys() == ["header"] ])
- self.failUnless(not re.match('\bPYTHONPATH=a%s' % (os.pathsep),headers),
- "got:\n" + headers)
- d.addCallback(check)
- return d
-
- def testEnvironArray(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir,
- environ={"FOO":['a', 'b']})
-
- d = s.start()
- def check(ign):
- headers = "".join([update.values()[0] for update in b.updates if update.keys() == ["header"] ])
- self.failUnless(not re.match('\bFOO=a%sb\b' % (os.pathsep),headers),
- "got:\n" + headers)
- d.addCallback(check)
- return d
-
- def testEnvironInt(self):
- b = FakeSlaveBuilder(False, self.basedir)
- self.assertRaises(RuntimeError, lambda :
- runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir,
- environ={"BUILD_NUMBER":13}))
-
-
-class TestPOSIXKilling(BasedirMixin, unittest.TestCase):
-
- if runtime.platformType != "posix":
- skip = "not a POSIX platform"
-
- def setUp(self):
- self.pidfiles = []
- self.setUpBasedir()
-
- def tearDown(self):
- # make sure all of the subprocesses are dead
- for pidfile in self.pidfiles:
- if not os.path.exists(pidfile): continue
- pid = open(pidfile).read()
- if not pid: return
- pid = int(pid)
- try: os.kill(pid, signal.SIGKILL)
- except OSError: pass
-
- # and clean up leftover pidfiles
- for pidfile in self.pidfiles:
- if os.path.exists(pidfile):
- os.unlink(pidfile)
-
- self.tearDownBasedir()
-
- def newPidfile(self):
- pidfile = os.path.abspath("test-%d.pid" % len(self.pidfiles))
- if os.path.exists(pidfile):
- os.unlink(pidfile)
- self.pidfiles.append(pidfile)
- return pidfile
-
- def waitForPidfile(self, pidfile):
- # wait for a pidfile, and return the pid via a Deferred
- until = time.time() + 10
- d = defer.Deferred()
- def poll():
- if reactor.seconds() > until:
- d.errback(RuntimeError("pidfile %s never appeared" % pidfile))
- return
- if os.path.exists(pidfile):
- try:
- pid = int(open(pidfile).read())
- except:
- pid = None
-
- if pid is not None:
- d.callback(pid)
- return
- reactor.callLater(0.01, poll)
- poll() # poll right away
- return d
-
- def assertAlive(self, pid):
- try:
- os.kill(pid, 0)
- except OSError:
- self.fail("pid %d still alive" % (pid,))
-
- def assertDead(self, pid, timeout=5):
- log.msg("checking pid %r" % (pid,))
- def check():
- try:
- os.kill(pid, 0)
- except OSError:
- return True # dead
- return False # alive
-
- # check immediately
- if check(): return
-
- # poll every 100'th of a second; this allows us to test for
- # processes that have been killed, but where the signal hasn't
- # been delivered yet
- until = time.time() + timeout
- while time.time() < until:
- time.sleep(0.01)
- if check():
- return
- self.fail("pid %d still alive after %ds" % (pid, timeout))
-
- # tests
-
- def test_simple_interruptSignal(self):
- return self.test_simple('TERM')
-
- def test_simple(self, interruptSignal=None):
-
- # test a simple process that just sleeps waiting to die
- pidfile = self.newPidfile()
- self.pid = None
-
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b,
- scriptCommand('write_pidfile_and_sleep', pidfile),
- self.basedir)
- if interruptSignal is not None:
- s.interruptSignal = interruptSignal
- runproc_d = s.start()
-
- pidfile_d = self.waitForPidfile(pidfile)
-
- def check_alive(pid):
- self.pid = pid # for use in check_dead
- # test that the process is still alive
- self.assertAlive(pid)
- # and tell the RunProcess object to kill it
- s.kill("diaf")
- pidfile_d.addCallback(check_alive)
-
- def check_dead(_):
- self.assertDead(self.pid)
- runproc_d.addCallback(check_dead)
- return defer.gatherResults([pidfile_d, runproc_d])
-
- def test_pgroup_usePTY(self):
- return self.do_test_pgroup(usePTY=True)
-
- def test_pgroup_no_usePTY(self):
- return self.do_test_pgroup(usePTY=False)
-
- def test_pgroup_no_usePTY_no_pgroup(self):
- # note that this configuration is not *used*, but that it is
- # still supported, and correctly fails to kill the child process
- return self.do_test_pgroup(usePTY=False, useProcGroup=False,
- expectChildSurvival=True)
-
- def do_test_pgroup(self, usePTY, useProcGroup=True,
- expectChildSurvival=False):
- # test that a process group gets killed
- parent_pidfile = self.newPidfile()
- self.parent_pid = None
- child_pidfile = self.newPidfile()
- self.child_pid = None
-
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b,
- scriptCommand('spawn_child', parent_pidfile, child_pidfile),
- self.basedir,
- usePTY=usePTY,
- useProcGroup=useProcGroup)
- runproc_d = s.start()
-
- # wait for both processes to start up, then call s.kill
- parent_pidfile_d = self.waitForPidfile(parent_pidfile)
- child_pidfile_d = self.waitForPidfile(child_pidfile)
- pidfiles_d = defer.gatherResults([parent_pidfile_d, child_pidfile_d])
- def got_pids(pids):
- self.parent_pid, self.child_pid = pids
- pidfiles_d.addCallback(got_pids)
- def kill(_):
- s.kill("diaf")
- pidfiles_d.addCallback(kill)
-
- # check that both processes are dead after RunProcess is done
- d = defer.gatherResults([pidfiles_d, runproc_d])
- def check_dead(_):
- self.assertDead(self.parent_pid)
- if expectChildSurvival:
- self.assertAlive(self.child_pid)
- else:
- self.assertDead(self.child_pid)
- d.addCallback(check_dead)
- return d
-
- def test_double_fork_usePTY(self):
- return self.do_test_double_fork(usePTY=True)
-
- def test_double_fork_no_usePTY(self):
- return self.do_test_double_fork(usePTY=False)
-
- def test_double_fork_no_usePTY_no_pgroup(self):
- # note that this configuration is not *used*, but that it is
- # still supported, and correctly fails to kill the child process
- return self.do_test_double_fork(usePTY=False, useProcGroup=False,
- expectChildSurvival=True)
-
- def do_test_double_fork(self, usePTY, useProcGroup=True,
- expectChildSurvival=False):
- # when a spawned process spawns another process, and then dies itself
- # (either intentionally or accidentally), we should be able to clean up
- # the child.
- parent_pidfile = self.newPidfile()
- self.parent_pid = None
- child_pidfile = self.newPidfile()
- self.child_pid = None
-
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b,
- scriptCommand('double_fork', parent_pidfile, child_pidfile),
- self.basedir,
- usePTY=usePTY,
- useProcGroup=useProcGroup)
- runproc_d = s.start()
-
- # wait for both processes to start up, then call s.kill
- parent_pidfile_d = self.waitForPidfile(parent_pidfile)
- child_pidfile_d = self.waitForPidfile(child_pidfile)
- pidfiles_d = defer.gatherResults([parent_pidfile_d, child_pidfile_d])
- def got_pids(pids):
- self.parent_pid, self.child_pid = pids
- pidfiles_d.addCallback(got_pids)
- def kill(_):
- s.kill("diaf")
- pidfiles_d.addCallback(kill)
-
- # check that both processes are dead after RunProcess is done
- d = defer.gatherResults([pidfiles_d, runproc_d])
- def check_dead(_):
- self.assertDead(self.parent_pid)
- if expectChildSurvival:
- self.assertAlive(self.child_pid)
- else:
- self.assertDead(self.child_pid)
- d.addCallback(check_dead)
- return d
-
-class TestLogging(BasedirMixin, unittest.TestCase):
- def setUp(self):
- self.setUpBasedir()
-
- def tearDown(self):
- self.tearDownBasedir()
-
- def testSendStatus(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
- s.sendStatus({'stdout': nl('hello\n')})
- self.failUnlessEqual(b.updates, [{'stdout': nl('hello\n')}], b.show())
-
- def testSendBuffered(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
- s._addToBuffers('stdout', 'hello ')
- s._addToBuffers('stdout', 'world')
- s._sendBuffers()
- self.failUnlessEqual(b.updates, [{'stdout': 'hello world'}], b.show())
-
- def testSendBufferedInterleaved(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
- s._addToBuffers('stdout', 'hello ')
- s._addToBuffers('stderr', 'DIEEEEEEE')
- s._addToBuffers('stdout', 'world')
- s._sendBuffers()
- self.failUnlessEqual(b.updates, [
- {'stdout': 'hello '},
- {'stderr': 'DIEEEEEEE'},
- {'stdout': 'world'},
- ])
-
- def testSendChunked(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
- data = "x" * (runprocess.RunProcess.CHUNK_LIMIT * 3 / 2)
- s._addToBuffers('stdout', data)
- s._sendBuffers()
- self.failUnlessEqual(len(b.updates), 2)
-
- def testSendNotimeout(self):
- b = FakeSlaveBuilder(False, self.basedir)
- s = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
- data = "x" * (runprocess.RunProcess.BUFFER_SIZE + 1)
- s._addToBuffers('stdout', data)
- self.failUnlessEqual(len(b.updates), 1)
-
-class TestLogFileWatcher(BasedirMixin, unittest.TestCase):
- def setUp(self):
- self.setUpBasedir()
-
- def tearDown(self):
- self.tearDownBasedir()
-
- def makeRP(self):
- b = FakeSlaveBuilder(False, self.basedir)
- rp = runprocess.RunProcess(b, stdoutCommand('hello'), self.basedir)
- return rp
-
- def test_statFile_missing(self):
- rp = self.makeRP()
- if os.path.exists('statfile.log'):
- os.remove('statfile.log')
- lf = runprocess.LogFileWatcher(rp, 'test', 'statfile.log', False)
- self.assertFalse(lf.statFile(), "statfile.log doesn't exist")
-
- def test_statFile_exists(self):
- rp = self.makeRP()
- open('statfile.log', 'w').write('hi')
- lf = runprocess.LogFileWatcher(rp, 'test', 'statfile.log', False)
- st = lf.statFile()
- self.assertEqual(st and st[2], 2, "statfile.log exists and size is correct")
- os.remove('statfile.log')
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_base.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_base.py
deleted file mode 100644
index 68daff20..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_base.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import cStringIO
-from twisted.trial import unittest
-from buildslave.scripts import base
-from buildslave.test.util import misc
-
-class TestIsBuildslaveDir(misc.OpenFileMixin, unittest.TestCase):
- """Test buildslave.scripts.base.isBuildslaveDir()"""
-
- def setUp(self):
- # capture output to stdout
- self.mocked_stdout = cStringIO.StringIO()
- self.patch(sys, "stdout", self.mocked_stdout)
-
- def assertReadErrorMessage(self, strerror):
- self.assertEqual(self.mocked_stdout.getvalue(),
- "error reading 'testdir/buildbot.tac': %s\n"
- "invalid buildslave directory 'testdir'\n" % strerror,
- "unexpected error message on stdout")
-
- def test_open_error(self):
- """Test that open() errors are handled."""
-
- # patch open() to raise IOError
- self.setUpOpenError(1, "open-error", "dummy")
-
- # check that isBuildslaveDir() flags directory as invalid
- self.assertFalse(base.isBuildslaveDir("testdir"))
-
- # check that correct error message was printed to stdout
- self.assertReadErrorMessage("open-error")
-
- # check that open() was called with correct path
- self.open.assert_called_once_with("testdir/buildbot.tac")
-
- def test_read_error(self):
- """Test that read() errors on buildbot.tac file are handled."""
-
- # patch open() to return file object that raises IOError on read()
- self.setUpReadError(1, "read-error", "dummy")
-
- # check that isBuildslaveDir() flags directory as invalid
- self.assertFalse(base.isBuildslaveDir("testdir"))
-
- # check that correct error message was printed to stdout
- self.assertReadErrorMessage("read-error")
-
- # check that open() was called with correct path
- self.open.assert_called_once_with("testdir/buildbot.tac")
-
- def test_unexpected_tac_contents(self):
- """Test that unexpected contents in buildbot.tac is handled."""
-
- # patch open() to return file with unexpected contents
- self.setUpOpen("dummy-contents")
-
- # check that isBuildslaveDir() flags directory as invalid
- self.assertFalse(base.isBuildslaveDir("testdir"))
-
- # check that correct error message was printed to stdout
- self.assertEqual(self.mocked_stdout.getvalue(),
- "unexpected content in 'testdir/buildbot.tac'\n"
- "invalid buildslave directory 'testdir'\n",
- "unexpected error message on stdout")
- # check that open() was called with correct path
- self.open.assert_called_once_with("testdir/buildbot.tac")
-
- def test_slavedir_good(self):
- """Test checking valid buildslave directory."""
-
- # patch open() to return file with valid buildslave tac contents
- self.setUpOpen("Application('buildslave')")
-
- # check that isBuildslaveDir() flags directory as good
- self.assertTrue(base.isBuildslaveDir("testdir"))
-
- # check that open() was called with correct path
- self.open.assert_called_once_with("testdir/buildbot.tac")
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_runner.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_runner.py
deleted file mode 100644
index 5656d97c..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_scripts_runner.py
+++ /dev/null
@@ -1,306 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import time
-import mock
-import errno
-import signal
-from twisted.trial import unittest
-from twisted.python import usage
-from buildslave.scripts import runner, base
-from buildslave.scripts import startup
-from buildslave.test.util import misc
-
-
-class IsBuildslaveDirMixin:
- """
- Mixin for setting up mocked base.isBuildslaveDir() function
- """
- def setupUpIsBuildslaveDir(self, return_value):
- self.isBuildslaveDir = mock.Mock(return_value=return_value)
- self.patch(base, "isBuildslaveDir", self.isBuildslaveDir)
-
-
-class TestStopSlave(misc.OpenFileMixin,
- misc.StdoutAssertionsMixin,
- unittest.TestCase):
- """
- Test buildslave.scripts.runner.stopSlave()
- """
- PID = 9876
- def setUp(self):
- self.setUpStdoutAssertions()
-
- # patch os.chdir() to do nothing
- self.patch(os, "chdir", mock.Mock())
-
- def test_no_pid_file(self):
- """
- test calling stopSlave() when no pid file is present
- """
-
- # patch open() to raise 'file not found' exception
- self.setUpOpenError(2)
-
- # check that stop() raises SlaveNotRunning exception
- self.assertRaises(runner.SlaveNotRunning,
- runner.stopSlave, None, False)
-
- def test_successful_stop(self):
- """
- test stopSlave() on a successful slave stop
- """
-
- def emulated_kill(pid, sig):
- if sig == 0:
- # when probed if a signal can be send to the process
- # emulate that it is dead with 'No such process' error
- raise OSError(errno.ESRCH, "dummy")
-
- # patch open() to return a pid file
- self.setUpOpen(str(self.PID))
-
- # patch os.kill to emulate successful kill
- mocked_kill = mock.Mock(side_effect=emulated_kill)
- self.patch(os, "kill", mocked_kill)
-
- # don't waste time
- self.patch(time, "sleep", mock.Mock())
-
- # check that stopSlave() sends expected signal to right PID
- # and print correct message to stdout
- runner.stopSlave(None, False)
- mocked_kill.assert_has_calls([mock.call(self.PID, signal.SIGTERM),
- mock.call(self.PID, 0)])
- self.assertStdoutEqual("buildslave process %s is dead\n" % self.PID)
-
-
-class TestStop(IsBuildslaveDirMixin,
- misc.StdoutAssertionsMixin,
- unittest.TestCase):
- """
- Test buildslave.scripts.runner.stop()
- """
- config = {"basedir": "dummy", "quiet": False}
-
- def setUp(self):
- # patch basedir check to always succeed
- self.setupUpIsBuildslaveDir(True)
-
- def test_no_slave_running(self):
- """
- test calling stop() when no slave is running
- """
- self.setUpStdoutAssertions()
-
- # patch stopSlave() to raise an exception
- mock_stopSlave = mock.Mock(side_effect=runner.SlaveNotRunning())
- self.patch(runner, "stopSlave", mock_stopSlave)
-
- runner.stop(self.config)
- self.assertStdoutEqual("buildslave not running\n")
-
- def test_successful_stop(self):
- """
- test calling stop() when slave is running
- """
- # patch stopSlave() to do nothing
- mock_stopSlave = mock.Mock()
- self.patch(runner, "stopSlave", mock_stopSlave)
-
- runner.stop(self.config)
- mock_stopSlave.assert_called_once_with(self.config["basedir"],
- self.config["quiet"],
- "TERM")
-
-
-class TestRestart(IsBuildslaveDirMixin,
- misc.StdoutAssertionsMixin,
- unittest.TestCase):
- """
- Test buildslave.scripts.runner.restart()
- """
- config = {"basedir": "dummy", "quiet": False}
-
- def setUp(self):
- self.setUpStdoutAssertions()
-
- # patch basedir check to always succeed
- self.setupUpIsBuildslaveDir(True)
-
- # patch startup.start() to do nothing
- self.start = mock.Mock()
- self.patch(startup, "start", self.start)
-
- def test_no_slave_running(self):
- """
- test calling restart() when no slave is running
- """
- # patch stopSlave() to raise an exception
- mock_stopSlave = mock.Mock(side_effect=runner.SlaveNotRunning())
- self.patch(runner, "stopSlave", mock_stopSlave)
-
- # check that restart() calls start() and prints correct messages
- runner.restart(self.config)
- self.start.assert_called_once_with(self.config)
- self.assertStdoutEqual("no old buildslave process found to stop\n"
- "now restarting buildslave process..\n")
-
-
- def test_restart(self):
- """
- test calling restart() when slave is running
- """
- # patch stopSlave() to do nothing
- mock_stopSlave = mock.Mock()
- self.patch(runner, "stopSlave", mock_stopSlave)
-
- # check that restart() calls start() and prints correct messages
- runner.restart(self.config)
- self.assertStdoutEqual("now restarting buildslave process..\n")
- self.start.assert_called_once_with(self.config)
-
-
-class TestUpgradeSlave(IsBuildslaveDirMixin, unittest.TestCase):
- """
- Test buildslave.scripts.runner.upgradeSlave()
- """
-
- def test_upgradeSlave_bad_basedir(self):
- """
- test calling upgradeSlave() with bad base directory
- """
- # override isBuildslaveDir() to always fail
- self.setupUpIsBuildslaveDir(False)
-
- # call upgradeSlave() and check that SystemExit exception is raised
- config = {"basedir" : "dummy"}
- exception = self.assertRaises(SystemExit, runner.upgradeSlave, config)
-
- # check exit code
- self.assertEqual(exception.code, 1, "unexpected exit code")
-
- # check that isBuildslaveDir was called with correct argument
- self.isBuildslaveDir.assert_called_once_with("dummy")
-
-
-class OptionsMixin(object):
- def assertOptions(self, opts, exp):
- got = dict([(k, opts[k]) for k in exp])
- if got != exp:
- msg = []
- for k in exp:
- if opts[k] != exp[k]:
- msg.append(" %s: expected %r, got %r" %
- (k, exp[k], opts[k]))
- self.fail("did not get expected options\n" + ("\n".join(msg)))
-
-
-class TestCreateSlaveOptions(OptionsMixin, unittest.TestCase):
- """
- Test buildslave.scripts.runner.CreateSlaveOptions class.
- """
-
- req_args = ["bdir", "mstr", "name", "pswd"]
-
- def parse(self, *args):
- opts = runner.CreateSlaveOptions()
- opts.parseOptions(args)
- return opts
-
- def test_defaults(self):
- self.assertRaisesRegexp(usage.UsageError,
- "incorrect number of arguments",
- self.parse)
-
- def test_synopsis(self):
- opts = runner.CreateSlaveOptions()
- self.assertIn('buildslave create-slave', opts.getSynopsis())
-
- def test_min_args(self):
-
- # patch runner.MakerBase.postOptions() so that 'basedir'
- # argument will not be converted to absolute path
- self.patch(runner.MakerBase, "postOptions", mock.Mock())
-
- self.assertOptions(self.parse(*self.req_args),
- dict(basedir="bdir", master="mstr",
- name="name", passwd="pswd"))
-
- def test_all_args(self):
-
- # patch runner.MakerBase.postOptions() so that 'basedir'
- # argument will not be converted to absolute path
- self.patch(runner.MakerBase, "postOptions", mock.Mock())
-
- opts = self.parse("--force", "--relocatable", "--no-logrotate",
- "--keepalive=4", "--usepty=0", "--umask=022",
- "--maxdelay=3", "--log-size=2", "--log-count=1",
- "--allow-shutdown=file", *self.req_args)
- self.assertOptions(opts,
- {"force" : True,
- "relocatable" : True,
- "no-logrotate" : True,
- "usepty" : 0,
- "umask" : "022",
- "maxdelay" : 3,
- "log-size" : 2,
- "log-count" : "1",
- "allow-shutdown" : "file",
- "basedir" : "bdir",
- "master" : "mstr",
- "name" : "name",
- "passwd" : "pswd"})
-
- def test_master_url(self):
- self.assertRaisesRegexp(usage.UsageError,
- "<master> is not a URL - do not use URL",
- self.parse, "a", "http://b.c", "d", "e")
-
- def test_inv_keepalive(self):
- self.assertRaisesRegexp(usage.UsageError,
- "keepalive parameter needs to be an number",
- self.parse, "--keepalive=X", *self.req_args)
-
- def test_inv_usepty(self):
- self.assertRaisesRegexp(usage.UsageError,
- "usepty parameter needs to be an number",
- self.parse, "--usepty=X", *self.req_args)
-
- def test_inv_maxdelay(self):
- self.assertRaisesRegexp(usage.UsageError,
- "maxdelay parameter needs to be an number",
- self.parse, "--maxdelay=X", *self.req_args)
-
- def test_inv_log_size(self):
- self.assertRaisesRegexp(usage.UsageError,
- "log-size parameter needs to be an number",
- self.parse, "--log-size=X", *self.req_args)
-
- def test_inv_log_count(self):
- self.assertRaisesRegexp(usage.UsageError,
- "log-count parameter needs to be an number or None",
- self.parse, "--log-count=X", *self.req_args)
-
- def test_too_few_args(self):
- self.assertRaisesRegexp(usage.UsageError,
- "incorrect number of arguments",
- self.parse, "arg1", "arg2")
-
- def test_too_many_args(self):
- self.assertRaisesRegexp(usage.UsageError,
- "incorrect number of arguments",
- self.parse, "extra_arg", *self.req_args)
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_util.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_util.py
deleted file mode 100644
index 738e6e45..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/test_util.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from twisted.trial import unittest
-
-from buildslave import util
-
-class remove_userpassword(unittest.TestCase):
-
- def assertUrl(self, real_url, expected_url):
- new_url = util.remove_userpassword(real_url)
- self.assertEqual(expected_url, new_url)
-
- def test_url_with_no_user_and_password(self):
- self.assertUrl('http://myurl.com/myrepo', 'http://myurl.com/myrepo')
-
- def test_url_with_user_and_password(self):
- self.assertUrl('http://myuser:mypass@myurl.com/myrepo', 'http://myurl.com/myrepo')
-
- def test_another_url_with_no_user_and_password(self):
- self.assertUrl('http://myurl2.com/myrepo2', 'http://myurl2.com/myrepo2')
-
- def test_another_url_with_user_and_password(self):
- self.assertUrl('http://myuser2:mypass2@myurl2.com/myrepo2', 'http://myurl2.com/myrepo2')
-
- def test_with_different_protocol_without_user_and_password(self):
- self.assertUrl('ssh://myurl3.com/myrepo3', 'ssh://myurl3.com/myrepo3')
-
- def test_with_different_protocol_with_user_and_password(self):
- self.assertUrl('ssh://myuser3:mypass3@myurl3.com/myrepo3', 'ssh://myurl3.com/myrepo3')
-
- def test_file_path(self):
- self.assertUrl('/home/me/repos/my-repo', '/home/me/repos/my-repo')
-
- def test_win32file_path(self):
- self.assertUrl('c:\\repos\\my-repo', 'c:\\repos\\my-repo')
-
-class TestObfuscated(unittest.TestCase):
- def testSimple(self):
- c = util.Obfuscated('real', '****')
- self.failUnlessEqual(str(c), '****')
- self.failUnlessEqual(repr(c), "'****'")
-
- def testObfuscatedCommand(self):
- cmd = ['echo', util.Obfuscated('password', '*******')]
-
- self.failUnlessEqual(['echo', 'password'], util.Obfuscated.get_real(cmd))
- self.failUnlessEqual(['echo', '*******'], util.Obfuscated.get_fake(cmd))
-
- def testObfuscatedNonString(self):
- cmd = ['echo', 1]
- self.failUnlessEqual(['echo', '1'], util.Obfuscated.get_real(cmd))
- self.failUnlessEqual(['echo', '1'], util.Obfuscated.get_fake(cmd))
-
- def testObfuscatedNonList(self):
- cmd = 1
- self.failUnlessEqual(1, util.Obfuscated.get_real(cmd))
- self.failUnlessEqual(1, util.Obfuscated.get_fake(cmd))
-
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/__init__.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/command.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/command.py
deleted file mode 100644
index 7b3ec420..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/command.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import shutil
-
-from buildslave.test.fake import slavebuilder, runprocess
-from buildslave.commands import utils
-import buildslave.runprocess
-
-class CommandTestMixin:
- """
- Support for testing Command subclasses.
- """
-
- def setUpCommand(self):
- """
- Get things ready to test a Command
-
- Sets:
- self.basedir -- the basedir (an abs path)
- self.basedir_workdir -- os.path.join(self.basedir, 'workdir')
- self.basedir_source -- os.path.join(self.basedir, 'source')
- """
- self.basedir = os.path.abspath('basedir')
- self.basedir_workdir = os.path.join(self.basedir, 'workdir')
- self.basedir_source = os.path.join(self.basedir, 'source')
-
- # clean up the basedir unconditionally
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
-
- def tearDownCommand(self):
- """
- Call this from the tearDown method to clean up any leftover workdirs and do
- any additional cleanup required.
- """
- # clean up the basedir unconditionally
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
-
- # finish up the runprocess
- if hasattr(self, 'runprocess_patched') and self.runprocess_patched:
- runprocess.FakeRunProcess.test_done()
-
- def make_command(self, cmdclass, args, makedirs=False):
- """
- Create a new command object, creating the necessary arguments. The
- cmdclass argument is the Command class, and args is the args dict
- to pass to its constructor.
-
- This always creates the SlaveBuilder with a basedir (self.basedir). If
- makedirs is true, it will create the basedir and a workdir directory
- inside (named 'workdir').
-
- The resulting command is returned, but as a side-effect, the following
- attributes are set:
-
- self.cmd -- the command
- self.builder -- the (fake) SlaveBuilder
- """
-
- # set up the workdir and basedir
- if makedirs:
- basedir_abs = os.path.abspath(os.path.join(self.basedir))
- workdir_abs = os.path.abspath(os.path.join(self.basedir, 'workdir'))
- if os.path.exists(basedir_abs):
- shutil.rmtree(basedir_abs)
- os.makedirs(workdir_abs)
-
- b = self.builder = slavebuilder.FakeSlaveBuilder(basedir=self.basedir)
- self.cmd = cmdclass(b, 'fake-stepid', args)
-
- return self.cmd
-
- def run_command(self):
- """
- Run the command created by make_command. Returns a deferred that will fire
- on success or failure.
- """
- return self.cmd.doStart()
-
- def get_updates(self):
- """
- Return the updates made so far
- """
- return self.builder.updates
-
- def assertUpdates(self, updates, msg=None):
- """
- Asserts that self.get_updates() matches updates, ignoring elapsed time data
- """
- my_updates = []
- for update in self.get_updates():
- try:
- if update.has_key('elapsed'):
- continue
- except:
- pass
- my_updates.append(update)
- self.assertEqual(my_updates, updates, msg)
-
- def add_update(self, upd):
- self.builder.updates.append(upd)
-
- def patch_runprocess(self, *expectations):
- """
- Patch a fake RunProcess class in, and set the given expectations.
- """
- self.patch(buildslave.runprocess, 'RunProcess', runprocess.FakeRunProcess)
- buildslave.runprocess.RunProcess.expect(*expectations)
- self.runprocess_patched = True
-
- def patch_getCommand(self, name, result):
- """
- Patch utils.getCommand to return RESULT for NAME
- """
- old_getCommand = utils.getCommand
- def new_getCommand(n):
- if n == name: return result
- return old_getCommand(n)
- self.patch(utils, 'getCommand', new_getCommand)
-
- def clean_environ(self):
- """
- Temporarily clean out os.environ to { 'PWD' : '.' }
- """
- self.patch(os, 'environ', { 'PWD' : '.' })
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/compat.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/compat.py
deleted file mode 100644
index 59799c8d..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/compat.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import sys
-import twisted
-from twisted.python import versions, runtime
-
-def usesFlushLoggedErrors(test):
- "Decorate a test method that uses flushLoggedErrors with this decorator"
- if (sys.version_info[:2] == (2,7)
- and twisted.version <= versions.Version('twisted', 9, 0, 0)):
- test.skip = \
- "flushLoggedErrors is broken on Python==2.7 and Twisted<=9.0.0"
- return test
-
-def skipUnlessPlatformIs(platform):
- def closure(test):
- if runtime.platformType != platform:
- test.skip = "not a %s platform" % platform
- return test
- return closure
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/misc.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/misc.py
deleted file mode 100644
index f1521769..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/misc.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import os
-import sys
-import mock
-import shutil
-import __builtin__
-import cStringIO
-
-def nl(s):
- """Convert the given string to the native newline format, assuming it is
- already in normal UNIX newline format (\n). Use this to create the
- appropriate expectation in a failUnlessEqual"""
- if not isinstance(s, basestring):
- return s
- return s.replace('\n', os.linesep)
-
-class BasedirMixin(object):
- """Mix this in and call setUpBasedir and tearDownBasedir to set up
- a clean basedir with a name given in self.basedir."""
-
- def setUpBasedir(self):
- self.basedir = "test-basedir"
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
-
- def tearDownBasedir(self):
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
-
-class PatcherMixin(object):
- """
- Mix this in to get a few special-cased patching methods
- """
-
- def patch_os_uname(self, replacement):
- # twisted's 'patch' doesn't handle the case where an attribute
- # doesn't exist..
- if hasattr(os, 'uname'):
- self.patch(os, 'uname', replacement)
- else:
- def cleanup():
- del os.uname
- self.addCleanup(cleanup)
- os.uname = replacement
-
-
-class OpenFileMixin:
- """
- Mixin for patching open() to simulate successful reads and I/O errors.
- """
- def setUpOpen(self, file_contents):
- """
- patch open() to return file object with provided contents.
-
- @param file_contents: contents that will be returned by file object's
- read() method
- """
- # create mocked file object that returns 'file_contents' on read()
- self.fileobj = mock.Mock()
- self.fileobj.read = mock.Mock(return_value=file_contents)
-
- # patch open() to return mocked object
- self.open = mock.Mock(return_value=self.fileobj)
- self.patch(__builtin__, "open", self.open)
-
- def setUpOpenError(self, errno, strerror="dummy-msg",
- filename="dummy-file"):
- """
- patch open() to raise IOError
-
- @param errno: exception's errno value
- @param strerror: exception's strerror value
- @param filename: exception's filename value
- """
- self.open = mock.Mock(side_effect=IOError(errno, strerror, filename))
- self.patch(__builtin__, "open", self.open)
-
- def setUpReadError(self, errno, strerror="dummy-msg",
- filename="dummy-file"):
- """
- patch open() to return a file object that will raise IOError on read()
-
- @param errno: exception's errno value
- @param strerror: exception's strerror value
- @param filename: exception's filename value
-
- """
- self.fileobj = mock.Mock()
- self.fileobj.read = mock.Mock(side_effect=IOError(errno, strerror,
- filename))
- self.open = mock.Mock(return_value=self.fileobj)
- self.patch(__builtin__, "open", self.open)
-
-
-class StdoutAssertionsMixin(object):
- """
- Mix this in to be able to assert on stdout during the test
- """
- def setUpStdoutAssertions(self):
- self.stdout = cStringIO.StringIO()
- self.patch(sys, 'stdout', self.stdout)
-
- def assertWasQuiet(self):
- self.assertEqual(self.stdout.getvalue(), '')
-
- def assertInStdout(self, exp):
- self.assertIn(exp, self.stdout.getvalue())
-
- def assertStdoutEqual(self, exp, msg=None):
- self.assertEqual(exp, self.stdout.getvalue(), msg)
-
- def getStdout(self):
- return self.stdout.getvalue().strip()
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/sourcecommand.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/sourcecommand.py
deleted file mode 100644
index a73c18c5..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/util/sourcecommand.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-from buildslave import runprocess
-from buildslave.test.util import command
-
-class SourceCommandTestMixin(command.CommandTestMixin):
- """
- Support for testing Source Commands; an extension of CommandTestMixin
- """
-
- def make_command(self, cmdclass, args, makedirs=False, initial_sourcedata=''):
- """
- Same as the parent class method, but this also adds some source-specific
- patches:
-
- * writeSourcedata - writes to self.sourcedata (self is the TestCase)
- * readSourcedata - reads from self.sourcedata
- * doClobber - invokes RunProcess(['clobber', DIRECTORY])
- * doCopy - invokes RunProcess(['copy', cmd.srcdir, cmd.workdir])
- """
-
- cmd = command.CommandTestMixin.make_command(self, cmdclass, args, makedirs)
-
- # note that these patches are to an *instance*, not a class, so there
- # is no need to use self.patch() to reverse them
-
- self.sourcedata = initial_sourcedata
- def readSourcedata():
- if self.sourcedata is None:
- raise IOError("File not found")
- return self.sourcedata
- cmd.readSourcedata = readSourcedata
-
- def writeSourcedata(res):
- self.sourcedata = cmd.sourcedata
- return res
- cmd.writeSourcedata = writeSourcedata
-
- # patch out a bunch of actions with invocations of RunProcess that will
- # end up being Expect-able by the tests.
-
- def doClobber(_, dirname):
- r = runprocess.RunProcess(self.builder,
- [ 'clobber', dirname ],
- self.builder.basedir)
- return r.start()
- cmd.doClobber = doClobber
-
- def doCopy(_):
- r = runprocess.RunProcess(self.builder,
- [ 'copy', cmd.srcdir, cmd.workdir ],
- self.builder.basedir)
- return r.start()
- cmd.doCopy = doCopy
-
- def setFileContents(filename, contents):
- r = runprocess.RunProcess(self.builder,
- [ 'setFileContents', filename, contents ],
- self.builder.basedir)
- return r.start()
- cmd.setFileContents = setFileContents
-
-
- def check_sourcedata(self, _, expected_sourcedata):
- """
- Assert that the sourcedata (from the patched functions - see
- make_command) is correct. Use this as a deferred callback.
- """
- self.assertEqual(self.sourcedata, expected_sourcedata)
- return _
diff --git a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/util.py b/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/util.py
deleted file mode 100644
index 26aba0ad..00000000
--- a/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/util.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# This file is part of Buildbot. Buildbot is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright Buildbot Team Members
-
-import types
-import time
-
-def remove_userpassword(url):
- if '@' not in url:
- return url
- if '://' not in url:
- return url
-
- # urlparse would've been nice, but doesn't support ssh... sigh
- protocol_url = url.split('://')
- protocol = protocol_url[0]
- repo_url = protocol_url[1].split('@')[-1]
-
- return protocol + '://' + repo_url
-
-
-def now(_reactor=None):
- if _reactor and hasattr(_reactor, "seconds"):
- return _reactor.seconds()
- else:
- return time.time()
-
-class Obfuscated:
- """An obfuscated string in a command"""
- def __init__(self, real, fake):
- self.real = real
- self.fake = fake
-
- def __str__(self):
- return self.fake
-
- def __repr__(self):
- return `self.fake`
-
- def __eq__(self, other):
- return other.__class__ is self.__class__ and \
- other.real == self.real and \
- other.fake == self.fake
-
- @staticmethod
- def to_text(s):
- if isinstance(s, (str, unicode)):
- return s
- else:
- return str(s)
-
- @staticmethod
- def get_real(command):
- rv = command
- if type(command) == types.ListType:
- rv = []
- for elt in command:
- if isinstance(elt, Obfuscated):
- rv.append(elt.real)
- else:
- rv.append(Obfuscated.to_text(elt))
- return rv
-
- @staticmethod
- def get_fake(command):
- rv = command
- if type(command) == types.ListType:
- rv = []
- for elt in command:
- if isinstance(elt, Obfuscated):
- rv.append(elt.fake)
- else:
- rv.append(Obfuscated.to_text(elt))
- return rv
-
diff --git a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index f0b40db6..00000000
--- a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,100 +0,0 @@
-Metadata-Version: 1.1
-Name: decorator
-Version: 3.4.0
-Summary: Better living through Python with decorators
-Home-page: http://pypi.python.org/pypi/decorator
-Author: Michele Simionato
-Author-email: michele.simionato@gmail.com
-License: BSD License
-Description: Decorator module
- =================
-
-
- :Author: Michele Simionato
- :E-mail: michele.simionato@gmail.com
- :Requires: Python 2.4+
- :Download page: http://pypi.python.org/pypi/decorator
- :Installation: ``easy_install decorator``
- :License: BSD license
-
- Installation
- -------------
-
- If you are lazy, just perform
-
- $ easy_install decorator
-
- which will install just the module on your system. Notice that
- Python 3 requires the easy_install version of the distribute_ project.
-
- If you prefer to install the full distribution from source, including
- the documentation, download the tarball_, unpack it and run
-
- $ python setup.py install
-
- in the main directory, possibly as superuser.
-
- .. _tarball: http://pypi.python.org/pypi/decorator
- .. _distribute: http://packages.python.org/distribute/
-
- Testing
- --------
-
- For Python 2.5, 2.6, 2.7 run
-
- $ python documentation.py
-
- for Python 3.X run
-
- $ python documentation3.py
-
- You will see a few innocuous errors with Python 2.5, because some
- inner details such as the introduction of the ArgSpec namedtuple and
- Thread.__repr__ changed. You may safely ignore them.
-
- You cannot run the tests in Python 2.4, since there is a test using
- the with statement, but the decorator module is expected to work
- anyway (it has been used in production with Python 2.4 for years). My
- plan is to keep supporting all Python versions >= 2.4 in the core
- module, but I will keep the documentation and the tests updated only
- for the latest Python versions in both the 2.X and 3.X branches.
-
- Finally, notice that you may run into trouble if in your system there
- is an older version of the decorator module; in such a case remove the
- old version.
-
- Documentation
- --------------
-
- There are various versions of the documentation:
-
- - `HTML version (Python 2)`_
- - `PDF version (Python 2)`_
-
- - `HTML version (Python 3)`_
- - `PDF version (Python 3)`_
-
- .. _HTML version (Python 2): http://micheles.googlecode.com/hg/decorator/documentation.html
- .. _PDF version (Python 2): http://micheles.googlecode.com/hg/decorator/documentation.pdf
- .. _HTML version (Python 3): http://micheles.googlecode.com/hg/decorator/documentation3.html
- .. _PDF version (Python 3): http://micheles.googlecode.com/hg/decorator/documentation3.pdf
-
- Repository
- ---------------
-
- The project is hosted on GoogleCode as a Mercurial repository. You
- can look at the source here:
-
- http://code.google.com/p/micheles/source/browse/#hg%2Fdecorator
-
-Keywords: decorators generic utility
-Platform: All
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Natural Language :: English
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Utilities
diff --git a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 670da167..00000000
--- a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-MANIFEST.in
-README.txt
-documentation.py
-documentation3.py
-setup.cfg
-setup.py
-src/decorator.py
-src/decorator.egg-info/PKG-INFO
-src/decorator.egg-info/SOURCES.txt
-src/decorator.egg-info/dependency_links.txt
-src/decorator.egg-info/not-zip-safe
-src/decorator.egg-info/top_level.txt \ No newline at end of file
diff --git a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 3fe18a4d..00000000
--- a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-decorator
diff --git a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/decorator.py b/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/decorator.py
deleted file mode 100755
index e0039148..00000000
--- a/lib/python2.7/site-packages/decorator-3.4.0-py2.7.egg/decorator.py
+++ /dev/null
@@ -1,251 +0,0 @@
-########################## LICENCE ###############################
-
-# Copyright (c) 2005-2012, Michele Simionato
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-
-# Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# Redistributions in bytecode form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-# DAMAGE.
-
-"""
-Decorator module, see http://pypi.python.org/pypi/decorator
-for the documentation.
-"""
-
-__version__ = '3.4.0'
-
-__all__ = ["decorator", "FunctionMaker", "contextmanager"]
-
-import sys, re, inspect
-if sys.version >= '3':
- from inspect import getfullargspec
- def get_init(cls):
- return cls.__init__
-else:
- class getfullargspec(object):
- "A quick and dirty replacement for getfullargspec for Python 2.X"
- def __init__(self, f):
- self.args, self.varargs, self.varkw, self.defaults = \
- inspect.getargspec(f)
- self.kwonlyargs = []
- self.kwonlydefaults = None
- def __iter__(self):
- yield self.args
- yield self.varargs
- yield self.varkw
- yield self.defaults
- def get_init(cls):
- return cls.__init__.im_func
-
-DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(')
-
-# basic functionality
-class FunctionMaker(object):
- """
- An object with the ability to create functions with a given signature.
- It has attributes name, doc, module, signature, defaults, dict and
- methods update and make.
- """
- def __init__(self, func=None, name=None, signature=None,
- defaults=None, doc=None, module=None, funcdict=None):
- self.shortsignature = signature
- if func:
- # func can be a class or a callable, but not an instance method
- self.name = func.__name__
- if self.name == '<lambda>': # small hack for lambda functions
- self.name = '_lambda_'
- self.doc = func.__doc__
- self.module = func.__module__
- if inspect.isfunction(func):
- argspec = getfullargspec(func)
- self.annotations = getattr(func, '__annotations__', {})
- for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
- 'kwonlydefaults'):
- setattr(self, a, getattr(argspec, a))
- for i, arg in enumerate(self.args):
- setattr(self, 'arg%d' % i, arg)
- if sys.version < '3': # easy way
- self.shortsignature = self.signature = \
- inspect.formatargspec(
- formatvalue=lambda val: "", *argspec)[1:-1]
- else: # Python 3 way
- allargs = list(self.args)
- allshortargs = list(self.args)
- if self.varargs:
- allargs.append('*' + self.varargs)
- allshortargs.append('*' + self.varargs)
- elif self.kwonlyargs:
- allargs.append('*') # single star syntax
- for a in self.kwonlyargs:
- allargs.append('%s=None' % a)
- allshortargs.append('%s=%s' % (a, a))
- if self.varkw:
- allargs.append('**' + self.varkw)
- allshortargs.append('**' + self.varkw)
- self.signature = ', '.join(allargs)
- self.shortsignature = ', '.join(allshortargs)
- self.dict = func.__dict__.copy()
- # func=None happens when decorating a caller
- if name:
- self.name = name
- if signature is not None:
- self.signature = signature
- if defaults:
- self.defaults = defaults
- if doc:
- self.doc = doc
- if module:
- self.module = module
- if funcdict:
- self.dict = funcdict
- # check existence required attributes
- assert hasattr(self, 'name')
- if not hasattr(self, 'signature'):
- raise TypeError('You are decorating a non function: %s' % func)
-
- def update(self, func, **kw):
- "Update the signature of func with the data in self"
- func.__name__ = self.name
- func.__doc__ = getattr(self, 'doc', None)
- func.__dict__ = getattr(self, 'dict', {})
- func.func_defaults = getattr(self, 'defaults', ())
- func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
- func.__annotations__ = getattr(self, 'annotations', None)
- callermodule = sys._getframe(3).f_globals.get('__name__', '?')
- func.__module__ = getattr(self, 'module', callermodule)
- func.__dict__.update(kw)
-
- def make(self, src_templ, evaldict=None, addsource=False, **attrs):
- "Make a new function from a given template and update the signature"
- src = src_templ % vars(self) # expand name and signature
- evaldict = evaldict or {}
- mo = DEF.match(src)
- if mo is None:
- raise SyntaxError('not a valid function template\n%s' % src)
- name = mo.group(1) # extract the function name
- names = set([name] + [arg.strip(' *') for arg in
- self.shortsignature.split(',')])
- for n in names:
- if n in ('_func_', '_call_'):
- raise NameError('%s is overridden in\n%s' % (n, src))
- if not src.endswith('\n'): # add a newline just for safety
- src += '\n' # this is needed in old versions of Python
- try:
- code = compile(src, '<string>', 'single')
- # print >> sys.stderr, 'Compiling %s' % src
- exec code in evaldict
- except:
- print >> sys.stderr, 'Error in generated code:'
- print >> sys.stderr, src
- raise
- func = evaldict[name]
- if addsource:
- attrs['__source__'] = src
- self.update(func, **attrs)
- return func
-
- @classmethod
- def create(cls, obj, body, evaldict, defaults=None,
- doc=None, module=None, addsource=True, **attrs):
- """
- Create a function from the strings name, signature and body.
- evaldict is the evaluation dictionary. If addsource is true an attribute
- __source__ is added to the result. The attributes attrs are added,
- if any.
- """
- if isinstance(obj, str): # "name(signature)"
- name, rest = obj.strip().split('(', 1)
- signature = rest[:-1] #strip a right parens
- func = None
- else: # a function
- name = None
- signature = None
- func = obj
- self = cls(func, name, signature, defaults, doc, module)
- ibody = '\n'.join(' ' + line for line in body.splitlines())
- return self.make('def %(name)s(%(signature)s):\n' + ibody,
- evaldict, addsource, **attrs)
-
-def decorator(caller, func=None):
- """
- decorator(caller) converts a caller function into a decorator;
- decorator(caller, func) decorates a function using a caller.
- """
- if func is not None: # returns a decorated function
- evaldict = func.func_globals.copy()
- evaldict['_call_'] = caller
- evaldict['_func_'] = func
- return FunctionMaker.create(
- func, "return _call_(_func_, %(shortsignature)s)",
- evaldict, undecorated=func, __wrapped__=func)
- else: # returns a decorator
- if inspect.isclass(caller):
- name = caller.__name__.lower()
- callerfunc = get_init(caller)
- doc = 'decorator(%s) converts functions/generators into ' \
- 'factories of %s objects' % (caller.__name__, caller.__name__)
- fun = getfullargspec(callerfunc).args[1] # second arg
- elif inspect.isfunction(caller):
- name = '_lambda_' if caller.__name__ == '<lambda>' \
- else caller.__name__
- callerfunc = caller
- doc = caller.__doc__
- fun = getfullargspec(callerfunc).args[0] # first arg
- else: # assume caller is an object with a __call__ method
- name = caller.__class__.__name__.lower()
- callerfunc = caller.__call__.im_func
- doc = caller.__call__.__doc__
- fun = getfullargspec(callerfunc).args[1] # second arg
- evaldict = callerfunc.func_globals.copy()
- evaldict['_call_'] = caller
- evaldict['decorator'] = decorator
- return FunctionMaker.create(
- '%s(%s)' % (name, fun),
- 'return decorator(_call_, %s)' % fun,
- evaldict, undecorated=caller, __wrapped__=caller,
- doc=doc, module=caller.__module__)
-
-######################### contextmanager ########################
-
-def __call__(self, func):
- 'Context manager decorator'
- return FunctionMaker.create(
- func, "with _self_: return _func_(%(shortsignature)s)",
- dict(_self_=self, _func_=func), __wrapped__=func)
-
-try: # Python >= 3.2
-
- from contextlib import _GeneratorContextManager
- ContextManager = type(
- 'ContextManager', (_GeneratorContextManager,), dict(__call__=__call__))
-
-except ImportError: # Python >= 2.5
-
- from contextlib import GeneratorContextManager
- def __init__(self, f, *a, **k):
- return GeneratorContextManager.__init__(self, f(*a, **k))
- ContextManager = type(
- 'ContextManager', (GeneratorContextManager,),
- dict(__call__=__call__, __init__=__init__))
-
-contextmanager = decorator(ContextManager)
diff --git a/lib/python2.7/site-packages/easy-install.pth b/lib/python2.7/site-packages/easy-install.pth
deleted file mode 100644
index 108d9ec0..00000000
--- a/lib/python2.7/site-packages/easy-install.pth
+++ /dev/null
@@ -1,13 +0,0 @@
-import sys; sys.__plen = len(sys.path)
-./Jinja2-2.6-py2.7.egg
-./Twisted-12.2.0-py2.7-linux-x86_64.egg
-./Tempita-0.5.1-py2.7.egg
-./decorator-3.4.0-py2.7.egg
-./sqlalchemy_migrate-0.7.2-py2.7.egg
-./SQLAlchemy-0.7.0-py2.7-linux-x86_64.egg
-./python_dateutil-1.5-py2.7.egg
-./setuptools-0.6c11-py2.7.egg
-./buildbot-0.8.8-py2.7.egg
-./buildbot_slave-0.8.8-py2.7.egg
-./requests-2.13.0-py2.7.egg
-import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
diff --git a/lib/python2.7/site-packages/easy_install b/lib/python2.7/site-packages/easy_install
deleted file mode 100755
index 246fe248..00000000
--- a/lib/python2.7/site-packages/easy_install
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/python2.7
-# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
-__requires__ = 'setuptools==0.6c11'
-import sys
-from pkg_resources import load_entry_point
-
-sys.exit(
- load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install')()
-)
diff --git a/lib/python2.7/site-packages/easy_install-2.7 b/lib/python2.7/site-packages/easy_install-2.7
deleted file mode 100755
index 08d762b5..00000000
--- a/lib/python2.7/site-packages/easy_install-2.7
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/python2.7
-# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install-2.7'
-__requires__ = 'setuptools==0.6c11'
-import sys
-from pkg_resources import load_entry_point
-
-sys.exit(
- load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install-2.7')()
-)
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 725c2da6..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,12 +0,0 @@
-Metadata-Version: 1.0
-Name: python-dateutil
-Version: 1.5
-Summary: Extensions to the standard python 2.3+ datetime module
-Home-page: http://labix.org/python-dateutil
-Author: Gustavo Niemeyer
-Author-email: gustavo@niemeyer.net
-License: PSF License
-Description: The dateutil module provides powerful extensions to the standard
- datetime module, available in Python 2.3+.
-
-Platform: UNKNOWN
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index 9bc046b3..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-LICENSE
-MANIFEST.in
-Makefile
-NEWS
-README
-example.py
-setup.cfg
-setup.py
-test.py
-updatezinfo.py
-dateutil/__init__.py
-dateutil/easter.py
-dateutil/parser.py
-dateutil/relativedelta.py
-dateutil/rrule.py
-dateutil/tz.py
-dateutil/tzwin.py
-dateutil/zoneinfo/__init__.py
-dateutil/zoneinfo/zoneinfo-2010g.tar.gz
-python_dateutil.egg-info/PKG-INFO
-python_dateutil.egg-info/SOURCES.txt
-python_dateutil.egg-info/dependency_links.txt
-python_dateutil.egg-info/not-zip-safe
-python_dateutil.egg-info/top_level.txt
-sandbox/rrulewrapper.py
-sandbox/scheduler.py \ No newline at end of file
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 66501480..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-dateutil
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/__init__.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/__init__.py
deleted file mode 100755
index 290814cf..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"""
-Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-__version__ = "1.5"
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/easter.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/easter.py
deleted file mode 100755
index d7944104..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/easter.py
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-import datetime
-
-__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"]
-
-EASTER_JULIAN = 1
-EASTER_ORTHODOX = 2
-EASTER_WESTERN = 3
-
-def easter(year, method=EASTER_WESTERN):
- """
- This method was ported from the work done by GM Arts,
- on top of the algorithm by Claus Tondering, which was
- based in part on the algorithm of Ouding (1940), as
- quoted in "Explanatory Supplement to the Astronomical
- Almanac", P. Kenneth Seidelmann, editor.
-
- This algorithm implements three different easter
- calculation methods:
-
- 1 - Original calculation in Julian calendar, valid in
- dates after 326 AD
- 2 - Original method, with date converted to Gregorian
- calendar, valid in years 1583 to 4099
- 3 - Revised method, in Gregorian calendar, valid in
- years 1583 to 4099 as well
-
- These methods are represented by the constants:
-
- EASTER_JULIAN = 1
- EASTER_ORTHODOX = 2
- EASTER_WESTERN = 3
-
- The default method is method 3.
-
- More about the algorithm may be found at:
-
- http://users.chariot.net.au/~gmarts/eastalg.htm
-
- and
-
- http://www.tondering.dk/claus/calendar.html
-
- """
-
- if not (1 <= method <= 3):
- raise ValueError, "invalid method"
-
- # g - Golden year - 1
- # c - Century
- # h - (23 - Epact) mod 30
- # i - Number of days from March 21 to Paschal Full Moon
- # j - Weekday for PFM (0=Sunday, etc)
- # p - Number of days from March 21 to Sunday on or before PFM
- # (-6 to 28 methods 1 & 3, to 56 for method 2)
- # e - Extra days to add for method 2 (converting Julian
- # date to Gregorian date)
-
- y = year
- g = y % 19
- e = 0
- if method < 3:
- # Old method
- i = (19*g+15)%30
- j = (y+y//4+i)%7
- if method == 2:
- # Extra dates to convert Julian to Gregorian date
- e = 10
- if y > 1600:
- e = e+y//100-16-(y//100-16)//4
- else:
- # New method
- c = y//100
- h = (c-c//4-(8*c+13)//25+19*g+15)%30
- i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11))
- j = (y+y//4+i+2-c+c//4)%7
-
- # p can be from -6 to 56 corresponding to dates 22 March to 23 May
- # (later dates apply to method 2, although 23 May never actually occurs)
- p = i-j+e
- d = 1+(p+27+(p+6)//40)%31
- m = 3+(p+26)//30
- return datetime.date(int(y),int(m),int(d))
-
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/parser.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/parser.py
deleted file mode 100755
index 5d824e41..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/parser.py
+++ /dev/null
@@ -1,886 +0,0 @@
-# -*- coding:iso-8859-1 -*-
-"""
-Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-import datetime
-import string
-import time
-import sys
-import os
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-import relativedelta
-import tz
-
-
-__all__ = ["parse", "parserinfo"]
-
-
-# Some pointers:
-#
-# http://www.cl.cam.ac.uk/~mgk25/iso-time.html
-# http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html
-# http://www.w3.org/TR/NOTE-datetime
-# http://ringmaster.arc.nasa.gov/tools/time_formats.html
-# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm
-# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html
-
-
-class _timelex(object):
-
- def __init__(self, instream):
- if isinstance(instream, basestring):
- instream = StringIO(instream)
- self.instream = instream
- self.wordchars = ('abcdfeghijklmnopqrstuvwxyz'
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'
- 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
- 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ')
- self.numchars = '0123456789'
- self.whitespace = ' \t\r\n'
- self.charstack = []
- self.tokenstack = []
- self.eof = False
-
- def get_token(self):
- if self.tokenstack:
- return self.tokenstack.pop(0)
- seenletters = False
- token = None
- state = None
- wordchars = self.wordchars
- numchars = self.numchars
- whitespace = self.whitespace
- while not self.eof:
- if self.charstack:
- nextchar = self.charstack.pop(0)
- else:
- nextchar = self.instream.read(1)
- while nextchar == '\x00':
- nextchar = self.instream.read(1)
- if not nextchar:
- self.eof = True
- break
- elif not state:
- token = nextchar
- if nextchar in wordchars:
- state = 'a'
- elif nextchar in numchars:
- state = '0'
- elif nextchar in whitespace:
- token = ' '
- break # emit token
- else:
- break # emit token
- elif state == 'a':
- seenletters = True
- if nextchar in wordchars:
- token += nextchar
- elif nextchar == '.':
- token += nextchar
- state = 'a.'
- else:
- self.charstack.append(nextchar)
- break # emit token
- elif state == '0':
- if nextchar in numchars:
- token += nextchar
- elif nextchar == '.':
- token += nextchar
- state = '0.'
- else:
- self.charstack.append(nextchar)
- break # emit token
- elif state == 'a.':
- seenletters = True
- if nextchar == '.' or nextchar in wordchars:
- token += nextchar
- elif nextchar in numchars and token[-1] == '.':
- token += nextchar
- state = '0.'
- else:
- self.charstack.append(nextchar)
- break # emit token
- elif state == '0.':
- if nextchar == '.' or nextchar in numchars:
- token += nextchar
- elif nextchar in wordchars and token[-1] == '.':
- token += nextchar
- state = 'a.'
- else:
- self.charstack.append(nextchar)
- break # emit token
- if (state in ('a.', '0.') and
- (seenletters or token.count('.') > 1 or token[-1] == '.')):
- l = token.split('.')
- token = l[0]
- for tok in l[1:]:
- self.tokenstack.append('.')
- if tok:
- self.tokenstack.append(tok)
- return token
-
- def __iter__(self):
- return self
-
- def next(self):
- token = self.get_token()
- if token is None:
- raise StopIteration
- return token
-
- def split(cls, s):
- return list(cls(s))
- split = classmethod(split)
-
-
-class _resultbase(object):
-
- def __init__(self):
- for attr in self.__slots__:
- setattr(self, attr, None)
-
- def _repr(self, classname):
- l = []
- for attr in self.__slots__:
- value = getattr(self, attr)
- if value is not None:
- l.append("%s=%s" % (attr, `value`))
- return "%s(%s)" % (classname, ", ".join(l))
-
- def __repr__(self):
- return self._repr(self.__class__.__name__)
-
-
-class parserinfo(object):
-
- # m from a.m/p.m, t from ISO T separator
- JUMP = [" ", ".", ",", ";", "-", "/", "'",
- "at", "on", "and", "ad", "m", "t", "of",
- "st", "nd", "rd", "th"]
-
- WEEKDAYS = [("Mon", "Monday"),
- ("Tue", "Tuesday"),
- ("Wed", "Wednesday"),
- ("Thu", "Thursday"),
- ("Fri", "Friday"),
- ("Sat", "Saturday"),
- ("Sun", "Sunday")]
- MONTHS = [("Jan", "January"),
- ("Feb", "February"),
- ("Mar", "March"),
- ("Apr", "April"),
- ("May", "May"),
- ("Jun", "June"),
- ("Jul", "July"),
- ("Aug", "August"),
- ("Sep", "September"),
- ("Oct", "October"),
- ("Nov", "November"),
- ("Dec", "December")]
- HMS = [("h", "hour", "hours"),
- ("m", "minute", "minutes"),
- ("s", "second", "seconds")]
- AMPM = [("am", "a"),
- ("pm", "p")]
- UTCZONE = ["UTC", "GMT", "Z"]
- PERTAIN = ["of"]
- TZOFFSET = {}
-
- def __init__(self, dayfirst=False, yearfirst=False):
- self._jump = self._convert(self.JUMP)
- self._weekdays = self._convert(self.WEEKDAYS)
- self._months = self._convert(self.MONTHS)
- self._hms = self._convert(self.HMS)
- self._ampm = self._convert(self.AMPM)
- self._utczone = self._convert(self.UTCZONE)
- self._pertain = self._convert(self.PERTAIN)
-
- self.dayfirst = dayfirst
- self.yearfirst = yearfirst
-
- self._year = time.localtime().tm_year
- self._century = self._year//100*100
-
- def _convert(self, lst):
- dct = {}
- for i in range(len(lst)):
- v = lst[i]
- if isinstance(v, tuple):
- for v in v:
- dct[v.lower()] = i
- else:
- dct[v.lower()] = i
- return dct
-
- def jump(self, name):
- return name.lower() in self._jump
-
- def weekday(self, name):
- if len(name) >= 3:
- try:
- return self._weekdays[name.lower()]
- except KeyError:
- pass
- return None
-
- def month(self, name):
- if len(name) >= 3:
- try:
- return self._months[name.lower()]+1
- except KeyError:
- pass
- return None
-
- def hms(self, name):
- try:
- return self._hms[name.lower()]
- except KeyError:
- return None
-
- def ampm(self, name):
- try:
- return self._ampm[name.lower()]
- except KeyError:
- return None
-
- def pertain(self, name):
- return name.lower() in self._pertain
-
- def utczone(self, name):
- return name.lower() in self._utczone
-
- def tzoffset(self, name):
- if name in self._utczone:
- return 0
- return self.TZOFFSET.get(name)
-
- def convertyear(self, year):
- if year < 100:
- year += self._century
- if abs(year-self._year) >= 50:
- if year < self._year:
- year += 100
- else:
- year -= 100
- return year
-
- def validate(self, res):
- # move to info
- if res.year is not None:
- res.year = self.convertyear(res.year)
- if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z':
- res.tzname = "UTC"
- res.tzoffset = 0
- elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname):
- res.tzoffset = 0
- return True
-
-
-class parser(object):
-
- def __init__(self, info=None):
- self.info = info or parserinfo()
-
- def parse(self, timestr, default=None,
- ignoretz=False, tzinfos=None,
- **kwargs):
- if not default:
- default = datetime.datetime.now().replace(hour=0, minute=0,
- second=0, microsecond=0)
- res = self._parse(timestr, **kwargs)
- if res is None:
- raise ValueError, "unknown string format"
- repl = {}
- for attr in ["year", "month", "day", "hour",
- "minute", "second", "microsecond"]:
- value = getattr(res, attr)
- if value is not None:
- repl[attr] = value
- ret = default.replace(**repl)
- if res.weekday is not None and not res.day:
- ret = ret+relativedelta.relativedelta(weekday=res.weekday)
- if not ignoretz:
- if callable(tzinfos) or tzinfos and res.tzname in tzinfos:
- if callable(tzinfos):
- tzdata = tzinfos(res.tzname, res.tzoffset)
- else:
- tzdata = tzinfos.get(res.tzname)
- if isinstance(tzdata, datetime.tzinfo):
- tzinfo = tzdata
- elif isinstance(tzdata, basestring):
- tzinfo = tz.tzstr(tzdata)
- elif isinstance(tzdata, int):
- tzinfo = tz.tzoffset(res.tzname, tzdata)
- else:
- raise ValueError, "offset must be tzinfo subclass, " \
- "tz string, or int offset"
- ret = ret.replace(tzinfo=tzinfo)
- elif res.tzname and res.tzname in time.tzname:
- ret = ret.replace(tzinfo=tz.tzlocal())
- elif res.tzoffset == 0:
- ret = ret.replace(tzinfo=tz.tzutc())
- elif res.tzoffset:
- ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset))
- return ret
-
- class _result(_resultbase):
- __slots__ = ["year", "month", "day", "weekday",
- "hour", "minute", "second", "microsecond",
- "tzname", "tzoffset"]
-
- def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False):
- info = self.info
- if dayfirst is None:
- dayfirst = info.dayfirst
- if yearfirst is None:
- yearfirst = info.yearfirst
- res = self._result()
- l = _timelex.split(timestr)
- try:
-
- # year/month/day list
- ymd = []
-
- # Index of the month string in ymd
- mstridx = -1
-
- len_l = len(l)
- i = 0
- while i < len_l:
-
- # Check if it's a number
- try:
- value_repr = l[i]
- value = float(value_repr)
- except ValueError:
- value = None
-
- if value is not None:
- # Token is a number
- len_li = len(l[i])
- i += 1
- if (len(ymd) == 3 and len_li in (2, 4)
- and (i >= len_l or (l[i] != ':' and
- info.hms(l[i]) is None))):
- # 19990101T23[59]
- s = l[i-1]
- res.hour = int(s[:2])
- if len_li == 4:
- res.minute = int(s[2:])
- elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6):
- # YYMMDD or HHMMSS[.ss]
- s = l[i-1]
- if not ymd and l[i-1].find('.') == -1:
- ymd.append(info.convertyear(int(s[:2])))
- ymd.append(int(s[2:4]))
- ymd.append(int(s[4:]))
- else:
- # 19990101T235959[.59]
- res.hour = int(s[:2])
- res.minute = int(s[2:4])
- res.second, res.microsecond = _parsems(s[4:])
- elif len_li == 8:
- # YYYYMMDD
- s = l[i-1]
- ymd.append(int(s[:4]))
- ymd.append(int(s[4:6]))
- ymd.append(int(s[6:]))
- elif len_li in (12, 14):
- # YYYYMMDDhhmm[ss]
- s = l[i-1]
- ymd.append(int(s[:4]))
- ymd.append(int(s[4:6]))
- ymd.append(int(s[6:8]))
- res.hour = int(s[8:10])
- res.minute = int(s[10:12])
- if len_li == 14:
- res.second = int(s[12:])
- elif ((i < len_l and info.hms(l[i]) is not None) or
- (i+1 < len_l and l[i] == ' ' and
- info.hms(l[i+1]) is not None)):
- # HH[ ]h or MM[ ]m or SS[.ss][ ]s
- if l[i] == ' ':
- i += 1
- idx = info.hms(l[i])
- while True:
- if idx == 0:
- res.hour = int(value)
- if value%1:
- res.minute = int(60*(value%1))
- elif idx == 1:
- res.minute = int(value)
- if value%1:
- res.second = int(60*(value%1))
- elif idx == 2:
- res.second, res.microsecond = \
- _parsems(value_repr)
- i += 1
- if i >= len_l or idx == 2:
- break
- # 12h00
- try:
- value_repr = l[i]
- value = float(value_repr)
- except ValueError:
- break
- else:
- i += 1
- idx += 1
- if i < len_l:
- newidx = info.hms(l[i])
- if newidx is not None:
- idx = newidx
- elif i+1 < len_l and l[i] == ':':
- # HH:MM[:SS[.ss]]
- res.hour = int(value)
- i += 1
- value = float(l[i])
- res.minute = int(value)
- if value%1:
- res.second = int(60*(value%1))
- i += 1
- if i < len_l and l[i] == ':':
- res.second, res.microsecond = _parsems(l[i+1])
- i += 2
- elif i < len_l and l[i] in ('-', '/', '.'):
- sep = l[i]
- ymd.append(int(value))
- i += 1
- if i < len_l and not info.jump(l[i]):
- try:
- # 01-01[-01]
- ymd.append(int(l[i]))
- except ValueError:
- # 01-Jan[-01]
- value = info.month(l[i])
- if value is not None:
- ymd.append(value)
- assert mstridx == -1
- mstridx = len(ymd)-1
- else:
- return None
- i += 1
- if i < len_l and l[i] == sep:
- # We have three members
- i += 1
- value = info.month(l[i])
- if value is not None:
- ymd.append(value)
- mstridx = len(ymd)-1
- assert mstridx == -1
- else:
- ymd.append(int(l[i]))
- i += 1
- elif i >= len_l or info.jump(l[i]):
- if i+1 < len_l and info.ampm(l[i+1]) is not None:
- # 12 am
- res.hour = int(value)
- if res.hour < 12 and info.ampm(l[i+1]) == 1:
- res.hour += 12
- elif res.hour == 12 and info.ampm(l[i+1]) == 0:
- res.hour = 0
- i += 1
- else:
- # Year, month or day
- ymd.append(int(value))
- i += 1
- elif info.ampm(l[i]) is not None:
- # 12am
- res.hour = int(value)
- if res.hour < 12 and info.ampm(l[i]) == 1:
- res.hour += 12
- elif res.hour == 12 and info.ampm(l[i]) == 0:
- res.hour = 0
- i += 1
- elif not fuzzy:
- return None
- else:
- i += 1
- continue
-
- # Check weekday
- value = info.weekday(l[i])
- if value is not None:
- res.weekday = value
- i += 1
- continue
-
- # Check month name
- value = info.month(l[i])
- if value is not None:
- ymd.append(value)
- assert mstridx == -1
- mstridx = len(ymd)-1
- i += 1
- if i < len_l:
- if l[i] in ('-', '/'):
- # Jan-01[-99]
- sep = l[i]
- i += 1
- ymd.append(int(l[i]))
- i += 1
- if i < len_l and l[i] == sep:
- # Jan-01-99
- i += 1
- ymd.append(int(l[i]))
- i += 1
- elif (i+3 < len_l and l[i] == l[i+2] == ' '
- and info.pertain(l[i+1])):
- # Jan of 01
- # In this case, 01 is clearly year
- try:
- value = int(l[i+3])
- except ValueError:
- # Wrong guess
- pass
- else:
- # Convert it here to become unambiguous
- ymd.append(info.convertyear(value))
- i += 4
- continue
-
- # Check am/pm
- value = info.ampm(l[i])
- if value is not None:
- if value == 1 and res.hour < 12:
- res.hour += 12
- elif value == 0 and res.hour == 12:
- res.hour = 0
- i += 1
- continue
-
- # Check for a timezone name
- if (res.hour is not None and len(l[i]) <= 5 and
- res.tzname is None and res.tzoffset is None and
- not [x for x in l[i] if x not in string.ascii_uppercase]):
- res.tzname = l[i]
- res.tzoffset = info.tzoffset(res.tzname)
- i += 1
-
- # Check for something like GMT+3, or BRST+3. Notice
- # that it doesn't mean "I am 3 hours after GMT", but
- # "my time +3 is GMT". If found, we reverse the
- # logic so that timezone parsing code will get it
- # right.
- if i < len_l and l[i] in ('+', '-'):
- l[i] = ('+', '-')[l[i] == '+']
- res.tzoffset = None
- if info.utczone(res.tzname):
- # With something like GMT+3, the timezone
- # is *not* GMT.
- res.tzname = None
-
- continue
-
- # Check for a numbered timezone
- if res.hour is not None and l[i] in ('+', '-'):
- signal = (-1,1)[l[i] == '+']
- i += 1
- len_li = len(l[i])
- if len_li == 4:
- # -0300
- res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60
- elif i+1 < len_l and l[i+1] == ':':
- # -03:00
- res.tzoffset = int(l[i])*3600+int(l[i+2])*60
- i += 2
- elif len_li <= 2:
- # -[0]3
- res.tzoffset = int(l[i][:2])*3600
- else:
- return None
- i += 1
- res.tzoffset *= signal
-
- # Look for a timezone name between parenthesis
- if (i+3 < len_l and
- info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and
- 3 <= len(l[i+2]) <= 5 and
- not [x for x in l[i+2]
- if x not in string.ascii_uppercase]):
- # -0300 (BRST)
- res.tzname = l[i+2]
- i += 4
- continue
-
- # Check jumps
- if not (info.jump(l[i]) or fuzzy):
- return None
-
- i += 1
-
- # Process year/month/day
- len_ymd = len(ymd)
- if len_ymd > 3:
- # More than three members!?
- return None
- elif len_ymd == 1 or (mstridx != -1 and len_ymd == 2):
- # One member, or two members with a month string
- if mstridx != -1:
- res.month = ymd[mstridx]
- del ymd[mstridx]
- if len_ymd > 1 or mstridx == -1:
- if ymd[0] > 31:
- res.year = ymd[0]
- else:
- res.day = ymd[0]
- elif len_ymd == 2:
- # Two members with numbers
- if ymd[0] > 31:
- # 99-01
- res.year, res.month = ymd
- elif ymd[1] > 31:
- # 01-99
- res.month, res.year = ymd
- elif dayfirst and ymd[1] <= 12:
- # 13-01
- res.day, res.month = ymd
- else:
- # 01-13
- res.month, res.day = ymd
- if len_ymd == 3:
- # Three members
- if mstridx == 0:
- res.month, res.day, res.year = ymd
- elif mstridx == 1:
- if ymd[0] > 31 or (yearfirst and ymd[2] <= 31):
- # 99-Jan-01
- res.year, res.month, res.day = ymd
- else:
- # 01-Jan-01
- # Give precendence to day-first, since
- # two-digit years is usually hand-written.
- res.day, res.month, res.year = ymd
- elif mstridx == 2:
- # WTF!?
- if ymd[1] > 31:
- # 01-99-Jan
- res.day, res.year, res.month = ymd
- else:
- # 99-01-Jan
- res.year, res.day, res.month = ymd
- else:
- if ymd[0] > 31 or \
- (yearfirst and ymd[1] <= 12 and ymd[2] <= 31):
- # 99-01-01
- res.year, res.month, res.day = ymd
- elif ymd[0] > 12 or (dayfirst and ymd[1] <= 12):
- # 13-01-01
- res.day, res.month, res.year = ymd
- else:
- # 01-13-01
- res.month, res.day, res.year = ymd
-
- except (IndexError, ValueError, AssertionError):
- return None
-
- if not info.validate(res):
- return None
- return res
-
-DEFAULTPARSER = parser()
-def parse(timestr, parserinfo=None, **kwargs):
- if parserinfo:
- return parser(parserinfo).parse(timestr, **kwargs)
- else:
- return DEFAULTPARSER.parse(timestr, **kwargs)
-
-
-class _tzparser(object):
-
- class _result(_resultbase):
-
- __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset",
- "start", "end"]
-
- class _attr(_resultbase):
- __slots__ = ["month", "week", "weekday",
- "yday", "jyday", "day", "time"]
-
- def __repr__(self):
- return self._repr("")
-
- def __init__(self):
- _resultbase.__init__(self)
- self.start = self._attr()
- self.end = self._attr()
-
- def parse(self, tzstr):
- res = self._result()
- l = _timelex.split(tzstr)
- try:
-
- len_l = len(l)
-
- i = 0
- while i < len_l:
- # BRST+3[BRDT[+2]]
- j = i
- while j < len_l and not [x for x in l[j]
- if x in "0123456789:,-+"]:
- j += 1
- if j != i:
- if not res.stdabbr:
- offattr = "stdoffset"
- res.stdabbr = "".join(l[i:j])
- else:
- offattr = "dstoffset"
- res.dstabbr = "".join(l[i:j])
- i = j
- if (i < len_l and
- (l[i] in ('+', '-') or l[i][0] in "0123456789")):
- if l[i] in ('+', '-'):
- # Yes, that's right. See the TZ variable
- # documentation.
- signal = (1,-1)[l[i] == '+']
- i += 1
- else:
- signal = -1
- len_li = len(l[i])
- if len_li == 4:
- # -0300
- setattr(res, offattr,
- (int(l[i][:2])*3600+int(l[i][2:])*60)*signal)
- elif i+1 < len_l and l[i+1] == ':':
- # -03:00
- setattr(res, offattr,
- (int(l[i])*3600+int(l[i+2])*60)*signal)
- i += 2
- elif len_li <= 2:
- # -[0]3
- setattr(res, offattr,
- int(l[i][:2])*3600*signal)
- else:
- return None
- i += 1
- if res.dstabbr:
- break
- else:
- break
-
- if i < len_l:
- for j in range(i, len_l):
- if l[j] == ';': l[j] = ','
-
- assert l[i] == ','
-
- i += 1
-
- if i >= len_l:
- pass
- elif (8 <= l.count(',') <= 9 and
- not [y for x in l[i:] if x != ','
- for y in x if y not in "0123456789"]):
- # GMT0BST,3,0,30,3600,10,0,26,7200[,3600]
- for x in (res.start, res.end):
- x.month = int(l[i])
- i += 2
- if l[i] == '-':
- value = int(l[i+1])*-1
- i += 1
- else:
- value = int(l[i])
- i += 2
- if value:
- x.week = value
- x.weekday = (int(l[i])-1)%7
- else:
- x.day = int(l[i])
- i += 2
- x.time = int(l[i])
- i += 2
- if i < len_l:
- if l[i] in ('-','+'):
- signal = (-1,1)[l[i] == "+"]
- i += 1
- else:
- signal = 1
- res.dstoffset = (res.stdoffset+int(l[i]))*signal
- elif (l.count(',') == 2 and l[i:].count('/') <= 2 and
- not [y for x in l[i:] if x not in (',','/','J','M',
- '.','-',':')
- for y in x if y not in "0123456789"]):
- for x in (res.start, res.end):
- if l[i] == 'J':
- # non-leap year day (1 based)
- i += 1
- x.jyday = int(l[i])
- elif l[i] == 'M':
- # month[-.]week[-.]weekday
- i += 1
- x.month = int(l[i])
- i += 1
- assert l[i] in ('-', '.')
- i += 1
- x.week = int(l[i])
- if x.week == 5:
- x.week = -1
- i += 1
- assert l[i] in ('-', '.')
- i += 1
- x.weekday = (int(l[i])-1)%7
- else:
- # year day (zero based)
- x.yday = int(l[i])+1
-
- i += 1
-
- if i < len_l and l[i] == '/':
- i += 1
- # start time
- len_li = len(l[i])
- if len_li == 4:
- # -0300
- x.time = (int(l[i][:2])*3600+int(l[i][2:])*60)
- elif i+1 < len_l and l[i+1] == ':':
- # -03:00
- x.time = int(l[i])*3600+int(l[i+2])*60
- i += 2
- if i+1 < len_l and l[i+1] == ':':
- i += 2
- x.time += int(l[i])
- elif len_li <= 2:
- # -[0]3
- x.time = (int(l[i][:2])*3600)
- else:
- return None
- i += 1
-
- assert i == len_l or l[i] == ','
-
- i += 1
-
- assert i >= len_l
-
- except (IndexError, ValueError, AssertionError):
- return None
-
- return res
-
-
-DEFAULTTZPARSER = _tzparser()
-def _parsetz(tzstr):
- return DEFAULTTZPARSER.parse(tzstr)
-
-
-def _parsems(value):
- """Parse a I[.F] seconds value into (seconds, microseconds)."""
- if "." not in value:
- return int(value), 0
- else:
- i, f = value.split(".")
- return int(i), int(f.ljust(6, "0")[:6])
-
-
-# vim:ts=4:sw=4:et
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/relativedelta.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/relativedelta.py
deleted file mode 100755
index 0c72a818..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/relativedelta.py
+++ /dev/null
@@ -1,432 +0,0 @@
-"""
-Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-import datetime
-import calendar
-
-__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
-
-class weekday(object):
- __slots__ = ["weekday", "n"]
-
- def __init__(self, weekday, n=None):
- self.weekday = weekday
- self.n = n
-
- def __call__(self, n):
- if n == self.n:
- return self
- else:
- return self.__class__(self.weekday, n)
-
- def __eq__(self, other):
- try:
- if self.weekday != other.weekday or self.n != other.n:
- return False
- except AttributeError:
- return False
- return True
-
- def __repr__(self):
- s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
- if not self.n:
- return s
- else:
- return "%s(%+d)" % (s, self.n)
-
-MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)])
-
-class relativedelta:
- """
-The relativedelta type is based on the specification of the excelent
-work done by M.-A. Lemburg in his mx.DateTime extension. However,
-notice that this type does *NOT* implement the same algorithm as
-his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
-
-There's two different ways to build a relativedelta instance. The
-first one is passing it two date/datetime classes:
-
- relativedelta(datetime1, datetime2)
-
-And the other way is to use the following keyword arguments:
-
- year, month, day, hour, minute, second, microsecond:
- Absolute information.
-
- years, months, weeks, days, hours, minutes, seconds, microseconds:
- Relative information, may be negative.
-
- weekday:
- One of the weekday instances (MO, TU, etc). These instances may
- receive a parameter N, specifying the Nth weekday, which could
- be positive or negative (like MO(+1) or MO(-2). Not specifying
- it is the same as specifying +1. You can also use an integer,
- where 0=MO.
-
- leapdays:
- Will add given days to the date found, if year is a leap
- year, and the date found is post 28 of february.
-
- yearday, nlyearday:
- Set the yearday or the non-leap year day (jump leap days).
- These are converted to day/month/leapdays information.
-
-Here is the behavior of operations with relativedelta:
-
-1) Calculate the absolute year, using the 'year' argument, or the
- original datetime year, if the argument is not present.
-
-2) Add the relative 'years' argument to the absolute year.
-
-3) Do steps 1 and 2 for month/months.
-
-4) Calculate the absolute day, using the 'day' argument, or the
- original datetime day, if the argument is not present. Then,
- subtract from the day until it fits in the year and month
- found after their operations.
-
-5) Add the relative 'days' argument to the absolute day. Notice
- that the 'weeks' argument is multiplied by 7 and added to
- 'days'.
-
-6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds,
- microsecond/microseconds.
-
-7) If the 'weekday' argument is present, calculate the weekday,
- with the given (wday, nth) tuple. wday is the index of the
- weekday (0-6, 0=Mon), and nth is the number of weeks to add
- forward or backward, depending on its signal. Notice that if
- the calculated date is already Monday, for example, using
- (0, 1) or (0, -1) won't change the day.
- """
-
- def __init__(self, dt1=None, dt2=None,
- years=0, months=0, days=0, leapdays=0, weeks=0,
- hours=0, minutes=0, seconds=0, microseconds=0,
- year=None, month=None, day=None, weekday=None,
- yearday=None, nlyearday=None,
- hour=None, minute=None, second=None, microsecond=None):
- if dt1 and dt2:
- if not isinstance(dt1, datetime.date) or \
- not isinstance(dt2, datetime.date):
- raise TypeError, "relativedelta only diffs datetime/date"
- if type(dt1) is not type(dt2):
- if not isinstance(dt1, datetime.datetime):
- dt1 = datetime.datetime.fromordinal(dt1.toordinal())
- elif not isinstance(dt2, datetime.datetime):
- dt2 = datetime.datetime.fromordinal(dt2.toordinal())
- self.years = 0
- self.months = 0
- self.days = 0
- self.leapdays = 0
- self.hours = 0
- self.minutes = 0
- self.seconds = 0
- self.microseconds = 0
- self.year = None
- self.month = None
- self.day = None
- self.weekday = None
- self.hour = None
- self.minute = None
- self.second = None
- self.microsecond = None
- self._has_time = 0
-
- months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month)
- self._set_months(months)
- dtm = self.__radd__(dt2)
- if dt1 < dt2:
- while dt1 > dtm:
- months += 1
- self._set_months(months)
- dtm = self.__radd__(dt2)
- else:
- while dt1 < dtm:
- months -= 1
- self._set_months(months)
- dtm = self.__radd__(dt2)
- delta = dt1 - dtm
- self.seconds = delta.seconds+delta.days*86400
- self.microseconds = delta.microseconds
- else:
- self.years = years
- self.months = months
- self.days = days+weeks*7
- self.leapdays = leapdays
- self.hours = hours
- self.minutes = minutes
- self.seconds = seconds
- self.microseconds = microseconds
- self.year = year
- self.month = month
- self.day = day
- self.hour = hour
- self.minute = minute
- self.second = second
- self.microsecond = microsecond
-
- if type(weekday) is int:
- self.weekday = weekdays[weekday]
- else:
- self.weekday = weekday
-
- yday = 0
- if nlyearday:
- yday = nlyearday
- elif yearday:
- yday = yearday
- if yearday > 59:
- self.leapdays = -1
- if yday:
- ydayidx = [31,59,90,120,151,181,212,243,273,304,334,366]
- for idx, ydays in enumerate(ydayidx):
- if yday <= ydays:
- self.month = idx+1
- if idx == 0:
- self.day = yday
- else:
- self.day = yday-ydayidx[idx-1]
- break
- else:
- raise ValueError, "invalid year day (%d)" % yday
-
- self._fix()
-
- def _fix(self):
- if abs(self.microseconds) > 999999:
- s = self.microseconds//abs(self.microseconds)
- div, mod = divmod(self.microseconds*s, 1000000)
- self.microseconds = mod*s
- self.seconds += div*s
- if abs(self.seconds) > 59:
- s = self.seconds//abs(self.seconds)
- div, mod = divmod(self.seconds*s, 60)
- self.seconds = mod*s
- self.minutes += div*s
- if abs(self.minutes) > 59:
- s = self.minutes//abs(self.minutes)
- div, mod = divmod(self.minutes*s, 60)
- self.minutes = mod*s
- self.hours += div*s
- if abs(self.hours) > 23:
- s = self.hours//abs(self.hours)
- div, mod = divmod(self.hours*s, 24)
- self.hours = mod*s
- self.days += div*s
- if abs(self.months) > 11:
- s = self.months//abs(self.months)
- div, mod = divmod(self.months*s, 12)
- self.months = mod*s
- self.years += div*s
- if (self.hours or self.minutes or self.seconds or self.microseconds or
- self.hour is not None or self.minute is not None or
- self.second is not None or self.microsecond is not None):
- self._has_time = 1
- else:
- self._has_time = 0
-
- def _set_months(self, months):
- self.months = months
- if abs(self.months) > 11:
- s = self.months//abs(self.months)
- div, mod = divmod(self.months*s, 12)
- self.months = mod*s
- self.years = div*s
- else:
- self.years = 0
-
- def __radd__(self, other):
- if not isinstance(other, datetime.date):
- raise TypeError, "unsupported type for add operation"
- elif self._has_time and not isinstance(other, datetime.datetime):
- other = datetime.datetime.fromordinal(other.toordinal())
- year = (self.year or other.year)+self.years
- month = self.month or other.month
- if self.months:
- assert 1 <= abs(self.months) <= 12
- month += self.months
- if month > 12:
- year += 1
- month -= 12
- elif month < 1:
- year -= 1
- month += 12
- day = min(calendar.monthrange(year, month)[1],
- self.day or other.day)
- repl = {"year": year, "month": month, "day": day}
- for attr in ["hour", "minute", "second", "microsecond"]:
- value = getattr(self, attr)
- if value is not None:
- repl[attr] = value
- days = self.days
- if self.leapdays and month > 2 and calendar.isleap(year):
- days += self.leapdays
- ret = (other.replace(**repl)
- + datetime.timedelta(days=days,
- hours=self.hours,
- minutes=self.minutes,
- seconds=self.seconds,
- microseconds=self.microseconds))
- if self.weekday:
- weekday, nth = self.weekday.weekday, self.weekday.n or 1
- jumpdays = (abs(nth)-1)*7
- if nth > 0:
- jumpdays += (7-ret.weekday()+weekday)%7
- else:
- jumpdays += (ret.weekday()-weekday)%7
- jumpdays *= -1
- ret += datetime.timedelta(days=jumpdays)
- return ret
-
- def __rsub__(self, other):
- return self.__neg__().__radd__(other)
-
- def __add__(self, other):
- if not isinstance(other, relativedelta):
- raise TypeError, "unsupported type for add operation"
- return relativedelta(years=other.years+self.years,
- months=other.months+self.months,
- days=other.days+self.days,
- hours=other.hours+self.hours,
- minutes=other.minutes+self.minutes,
- seconds=other.seconds+self.seconds,
- microseconds=other.microseconds+self.microseconds,
- leapdays=other.leapdays or self.leapdays,
- year=other.year or self.year,
- month=other.month or self.month,
- day=other.day or self.day,
- weekday=other.weekday or self.weekday,
- hour=other.hour or self.hour,
- minute=other.minute or self.minute,
- second=other.second or self.second,
- microsecond=other.second or self.microsecond)
-
- def __sub__(self, other):
- if not isinstance(other, relativedelta):
- raise TypeError, "unsupported type for sub operation"
- return relativedelta(years=other.years-self.years,
- months=other.months-self.months,
- days=other.days-self.days,
- hours=other.hours-self.hours,
- minutes=other.minutes-self.minutes,
- seconds=other.seconds-self.seconds,
- microseconds=other.microseconds-self.microseconds,
- leapdays=other.leapdays or self.leapdays,
- year=other.year or self.year,
- month=other.month or self.month,
- day=other.day or self.day,
- weekday=other.weekday or self.weekday,
- hour=other.hour or self.hour,
- minute=other.minute or self.minute,
- second=other.second or self.second,
- microsecond=other.second or self.microsecond)
-
- def __neg__(self):
- return relativedelta(years=-self.years,
- months=-self.months,
- days=-self.days,
- hours=-self.hours,
- minutes=-self.minutes,
- seconds=-self.seconds,
- microseconds=-self.microseconds,
- leapdays=self.leapdays,
- year=self.year,
- month=self.month,
- day=self.day,
- weekday=self.weekday,
- hour=self.hour,
- minute=self.minute,
- second=self.second,
- microsecond=self.microsecond)
-
- def __nonzero__(self):
- return not (not self.years and
- not self.months and
- not self.days and
- not self.hours and
- not self.minutes and
- not self.seconds and
- not self.microseconds and
- not self.leapdays and
- self.year is None and
- self.month is None and
- self.day is None and
- self.weekday is None and
- self.hour is None and
- self.minute is None and
- self.second is None and
- self.microsecond is None)
-
- def __mul__(self, other):
- f = float(other)
- return relativedelta(years=self.years*f,
- months=self.months*f,
- days=self.days*f,
- hours=self.hours*f,
- minutes=self.minutes*f,
- seconds=self.seconds*f,
- microseconds=self.microseconds*f,
- leapdays=self.leapdays,
- year=self.year,
- month=self.month,
- day=self.day,
- weekday=self.weekday,
- hour=self.hour,
- minute=self.minute,
- second=self.second,
- microsecond=self.microsecond)
-
- def __eq__(self, other):
- if not isinstance(other, relativedelta):
- return False
- if self.weekday or other.weekday:
- if not self.weekday or not other.weekday:
- return False
- if self.weekday.weekday != other.weekday.weekday:
- return False
- n1, n2 = self.weekday.n, other.weekday.n
- if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)):
- return False
- return (self.years == other.years and
- self.months == other.months and
- self.days == other.days and
- self.hours == other.hours and
- self.minutes == other.minutes and
- self.seconds == other.seconds and
- self.leapdays == other.leapdays and
- self.year == other.year and
- self.month == other.month and
- self.day == other.day and
- self.hour == other.hour and
- self.minute == other.minute and
- self.second == other.second and
- self.microsecond == other.microsecond)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __div__(self, other):
- return self.__mul__(1/float(other))
-
- def __repr__(self):
- l = []
- for attr in ["years", "months", "days", "leapdays",
- "hours", "minutes", "seconds", "microseconds"]:
- value = getattr(self, attr)
- if value:
- l.append("%s=%+d" % (attr, value))
- for attr in ["year", "month", "day", "weekday",
- "hour", "minute", "second", "microsecond"]:
- value = getattr(self, attr)
- if value is not None:
- l.append("%s=%s" % (attr, `value`))
- return "%s(%s)" % (self.__class__.__name__, ", ".join(l))
-
-# vim:ts=4:sw=4:et
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py
deleted file mode 100755
index 6bd83cad..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-"""
-Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-import itertools
-import datetime
-import calendar
-import thread
-import sys
-
-__all__ = ["rrule", "rruleset", "rrulestr",
- "YEARLY", "MONTHLY", "WEEKLY", "DAILY",
- "HOURLY", "MINUTELY", "SECONDLY",
- "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
-
-# Every mask is 7 days longer to handle cross-year weekly periods.
-M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+
- [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7)
-M365MASK = list(M366MASK)
-M29, M30, M31 = range(1,30), range(1,31), range(1,32)
-MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
-MDAY365MASK = list(MDAY366MASK)
-M29, M30, M31 = range(-29,0), range(-30,0), range(-31,0)
-NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
-NMDAY365MASK = list(NMDAY366MASK)
-M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366)
-M365RANGE = (0,31,59,90,120,151,181,212,243,273,304,334,365)
-WDAYMASK = [0,1,2,3,4,5,6]*55
-del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31]
-MDAY365MASK = tuple(MDAY365MASK)
-M365MASK = tuple(M365MASK)
-
-(YEARLY,
- MONTHLY,
- WEEKLY,
- DAILY,
- HOURLY,
- MINUTELY,
- SECONDLY) = range(7)
-
-# Imported on demand.
-easter = None
-parser = None
-
-class weekday(object):
- __slots__ = ["weekday", "n"]
-
- def __init__(self, weekday, n=None):
- if n == 0:
- raise ValueError, "Can't create weekday with n == 0"
- self.weekday = weekday
- self.n = n
-
- def __call__(self, n):
- if n == self.n:
- return self
- else:
- return self.__class__(self.weekday, n)
-
- def __eq__(self, other):
- try:
- if self.weekday != other.weekday or self.n != other.n:
- return False
- except AttributeError:
- return False
- return True
-
- def __repr__(self):
- s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
- if not self.n:
- return s
- else:
- return "%s(%+d)" % (s, self.n)
-
-MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)])
-
-class rrulebase:
- def __init__(self, cache=False):
- if cache:
- self._cache = []
- self._cache_lock = thread.allocate_lock()
- self._cache_gen = self._iter()
- self._cache_complete = False
- else:
- self._cache = None
- self._cache_complete = False
- self._len = None
-
- def __iter__(self):
- if self._cache_complete:
- return iter(self._cache)
- elif self._cache is None:
- return self._iter()
- else:
- return self._iter_cached()
-
- def _iter_cached(self):
- i = 0
- gen = self._cache_gen
- cache = self._cache
- acquire = self._cache_lock.acquire
- release = self._cache_lock.release
- while gen:
- if i == len(cache):
- acquire()
- if self._cache_complete:
- break
- try:
- for j in range(10):
- cache.append(gen.next())
- except StopIteration:
- self._cache_gen = gen = None
- self._cache_complete = True
- break
- release()
- yield cache[i]
- i += 1
- while i < self._len:
- yield cache[i]
- i += 1
-
- def __getitem__(self, item):
- if self._cache_complete:
- return self._cache[item]
- elif isinstance(item, slice):
- if item.step and item.step < 0:
- return list(iter(self))[item]
- else:
- return list(itertools.islice(self,
- item.start or 0,
- item.stop or sys.maxint,
- item.step or 1))
- elif item >= 0:
- gen = iter(self)
- try:
- for i in range(item+1):
- res = gen.next()
- except StopIteration:
- raise IndexError
- return res
- else:
- return list(iter(self))[item]
-
- def __contains__(self, item):
- if self._cache_complete:
- return item in self._cache
- else:
- for i in self:
- if i == item:
- return True
- elif i > item:
- return False
- return False
-
- # __len__() introduces a large performance penality.
- def count(self):
- if self._len is None:
- for x in self: pass
- return self._len
-
- def before(self, dt, inc=False):
- if self._cache_complete:
- gen = self._cache
- else:
- gen = self
- last = None
- if inc:
- for i in gen:
- if i > dt:
- break
- last = i
- else:
- for i in gen:
- if i >= dt:
- break
- last = i
- return last
-
- def after(self, dt, inc=False):
- if self._cache_complete:
- gen = self._cache
- else:
- gen = self
- if inc:
- for i in gen:
- if i >= dt:
- return i
- else:
- for i in gen:
- if i > dt:
- return i
- return None
-
- def between(self, after, before, inc=False):
- if self._cache_complete:
- gen = self._cache
- else:
- gen = self
- started = False
- l = []
- if inc:
- for i in gen:
- if i > before:
- break
- elif not started:
- if i >= after:
- started = True
- l.append(i)
- else:
- l.append(i)
- else:
- for i in gen:
- if i >= before:
- break
- elif not started:
- if i > after:
- started = True
- l.append(i)
- else:
- l.append(i)
- return l
-
-class rrule(rrulebase):
- def __init__(self, freq, dtstart=None,
- interval=1, wkst=None, count=None, until=None, bysetpos=None,
- bymonth=None, bymonthday=None, byyearday=None, byeaster=None,
- byweekno=None, byweekday=None,
- byhour=None, byminute=None, bysecond=None,
- cache=False):
- rrulebase.__init__(self, cache)
- global easter
- if not dtstart:
- dtstart = datetime.datetime.now().replace(microsecond=0)
- elif not isinstance(dtstart, datetime.datetime):
- dtstart = datetime.datetime.fromordinal(dtstart.toordinal())
- else:
- dtstart = dtstart.replace(microsecond=0)
- self._dtstart = dtstart
- self._tzinfo = dtstart.tzinfo
- self._freq = freq
- self._interval = interval
- self._count = count
- if until and not isinstance(until, datetime.datetime):
- until = datetime.datetime.fromordinal(until.toordinal())
- self._until = until
- if wkst is None:
- self._wkst = calendar.firstweekday()
- elif type(wkst) is int:
- self._wkst = wkst
- else:
- self._wkst = wkst.weekday
- if bysetpos is None:
- self._bysetpos = None
- elif type(bysetpos) is int:
- if bysetpos == 0 or not (-366 <= bysetpos <= 366):
- raise ValueError("bysetpos must be between 1 and 366, "
- "or between -366 and -1")
- self._bysetpos = (bysetpos,)
- else:
- self._bysetpos = tuple(bysetpos)
- for pos in self._bysetpos:
- if pos == 0 or not (-366 <= pos <= 366):
- raise ValueError("bysetpos must be between 1 and 366, "
- "or between -366 and -1")
- if not (byweekno or byyearday or bymonthday or
- byweekday is not None or byeaster is not None):
- if freq == YEARLY:
- if not bymonth:
- bymonth = dtstart.month
- bymonthday = dtstart.day
- elif freq == MONTHLY:
- bymonthday = dtstart.day
- elif freq == WEEKLY:
- byweekday = dtstart.weekday()
- # bymonth
- if not bymonth:
- self._bymonth = None
- elif type(bymonth) is int:
- self._bymonth = (bymonth,)
- else:
- self._bymonth = tuple(bymonth)
- # byyearday
- if not byyearday:
- self._byyearday = None
- elif type(byyearday) is int:
- self._byyearday = (byyearday,)
- else:
- self._byyearday = tuple(byyearday)
- # byeaster
- if byeaster is not None:
- if not easter:
- from dateutil import easter
- if type(byeaster) is int:
- self._byeaster = (byeaster,)
- else:
- self._byeaster = tuple(byeaster)
- else:
- self._byeaster = None
- # bymonthay
- if not bymonthday:
- self._bymonthday = ()
- self._bynmonthday = ()
- elif type(bymonthday) is int:
- if bymonthday < 0:
- self._bynmonthday = (bymonthday,)
- self._bymonthday = ()
- else:
- self._bymonthday = (bymonthday,)
- self._bynmonthday = ()
- else:
- self._bymonthday = tuple([x for x in bymonthday if x > 0])
- self._bynmonthday = tuple([x for x in bymonthday if x < 0])
- # byweekno
- if byweekno is None:
- self._byweekno = None
- elif type(byweekno) is int:
- self._byweekno = (byweekno,)
- else:
- self._byweekno = tuple(byweekno)
- # byweekday / bynweekday
- if byweekday is None:
- self._byweekday = None
- self._bynweekday = None
- elif type(byweekday) is int:
- self._byweekday = (byweekday,)
- self._bynweekday = None
- elif hasattr(byweekday, "n"):
- if not byweekday.n or freq > MONTHLY:
- self._byweekday = (byweekday.weekday,)
- self._bynweekday = None
- else:
- self._bynweekday = ((byweekday.weekday, byweekday.n),)
- self._byweekday = None
- else:
- self._byweekday = []
- self._bynweekday = []
- for wday in byweekday:
- if type(wday) is int:
- self._byweekday.append(wday)
- elif not wday.n or freq > MONTHLY:
- self._byweekday.append(wday.weekday)
- else:
- self._bynweekday.append((wday.weekday, wday.n))
- self._byweekday = tuple(self._byweekday)
- self._bynweekday = tuple(self._bynweekday)
- if not self._byweekday:
- self._byweekday = None
- elif not self._bynweekday:
- self._bynweekday = None
- # byhour
- if byhour is None:
- if freq < HOURLY:
- self._byhour = (dtstart.hour,)
- else:
- self._byhour = None
- elif type(byhour) is int:
- self._byhour = (byhour,)
- else:
- self._byhour = tuple(byhour)
- # byminute
- if byminute is None:
- if freq < MINUTELY:
- self._byminute = (dtstart.minute,)
- else:
- self._byminute = None
- elif type(byminute) is int:
- self._byminute = (byminute,)
- else:
- self._byminute = tuple(byminute)
- # bysecond
- if bysecond is None:
- if freq < SECONDLY:
- self._bysecond = (dtstart.second,)
- else:
- self._bysecond = None
- elif type(bysecond) is int:
- self._bysecond = (bysecond,)
- else:
- self._bysecond = tuple(bysecond)
-
- if self._freq >= HOURLY:
- self._timeset = None
- else:
- self._timeset = []
- for hour in self._byhour:
- for minute in self._byminute:
- for second in self._bysecond:
- self._timeset.append(
- datetime.time(hour, minute, second,
- tzinfo=self._tzinfo))
- self._timeset.sort()
- self._timeset = tuple(self._timeset)
-
- def _iter(self):
- year, month, day, hour, minute, second, weekday, yearday, _ = \
- self._dtstart.timetuple()
-
- # Some local variables to speed things up a bit
- freq = self._freq
- interval = self._interval
- wkst = self._wkst
- until = self._until
- bymonth = self._bymonth
- byweekno = self._byweekno
- byyearday = self._byyearday
- byweekday = self._byweekday
- byeaster = self._byeaster
- bymonthday = self._bymonthday
- bynmonthday = self._bynmonthday
- bysetpos = self._bysetpos
- byhour = self._byhour
- byminute = self._byminute
- bysecond = self._bysecond
-
- ii = _iterinfo(self)
- ii.rebuild(year, month)
-
- getdayset = {YEARLY:ii.ydayset,
- MONTHLY:ii.mdayset,
- WEEKLY:ii.wdayset,
- DAILY:ii.ddayset,
- HOURLY:ii.ddayset,
- MINUTELY:ii.ddayset,
- SECONDLY:ii.ddayset}[freq]
-
- if freq < HOURLY:
- timeset = self._timeset
- else:
- gettimeset = {HOURLY:ii.htimeset,
- MINUTELY:ii.mtimeset,
- SECONDLY:ii.stimeset}[freq]
- if ((freq >= HOURLY and
- self._byhour and hour not in self._byhour) or
- (freq >= MINUTELY and
- self._byminute and minute not in self._byminute) or
- (freq >= SECONDLY and
- self._bysecond and second not in self._bysecond)):
- timeset = ()
- else:
- timeset = gettimeset(hour, minute, second)
-
- total = 0
- count = self._count
- while True:
- # Get dayset with the right frequency
- dayset, start, end = getdayset(year, month, day)
-
- # Do the "hard" work ;-)
- filtered = False
- for i in dayset[start:end]:
- if ((bymonth and ii.mmask[i] not in bymonth) or
- (byweekno and not ii.wnomask[i]) or
- (byweekday and ii.wdaymask[i] not in byweekday) or
- (ii.nwdaymask and not ii.nwdaymask[i]) or
- (byeaster and not ii.eastermask[i]) or
- ((bymonthday or bynmonthday) and
- ii.mdaymask[i] not in bymonthday and
- ii.nmdaymask[i] not in bynmonthday) or
- (byyearday and
- ((i < ii.yearlen and i+1 not in byyearday
- and -ii.yearlen+i not in byyearday) or
- (i >= ii.yearlen and i+1-ii.yearlen not in byyearday
- and -ii.nextyearlen+i-ii.yearlen
- not in byyearday)))):
- dayset[i] = None
- filtered = True
-
- # Output results
- if bysetpos and timeset:
- poslist = []
- for pos in bysetpos:
- if pos < 0:
- daypos, timepos = divmod(pos, len(timeset))
- else:
- daypos, timepos = divmod(pos-1, len(timeset))
- try:
- i = [x for x in dayset[start:end]
- if x is not None][daypos]
- time = timeset[timepos]
- except IndexError:
- pass
- else:
- date = datetime.date.fromordinal(ii.yearordinal+i)
- res = datetime.datetime.combine(date, time)
- if res not in poslist:
- poslist.append(res)
- poslist.sort()
- for res in poslist:
- if until and res > until:
- self._len = total
- return
- elif res >= self._dtstart:
- total += 1
- yield res
- if count:
- count -= 1
- if not count:
- self._len = total
- return
- else:
- for i in dayset[start:end]:
- if i is not None:
- date = datetime.date.fromordinal(ii.yearordinal+i)
- for time in timeset:
- res = datetime.datetime.combine(date, time)
- if until and res > until:
- self._len = total
- return
- elif res >= self._dtstart:
- total += 1
- yield res
- if count:
- count -= 1
- if not count:
- self._len = total
- return
-
- # Handle frequency and interval
- fixday = False
- if freq == YEARLY:
- year += interval
- if year > datetime.MAXYEAR:
- self._len = total
- return
- ii.rebuild(year, month)
- elif freq == MONTHLY:
- month += interval
- if month > 12:
- div, mod = divmod(month, 12)
- month = mod
- year += div
- if month == 0:
- month = 12
- year -= 1
- if year > datetime.MAXYEAR:
- self._len = total
- return
- ii.rebuild(year, month)
- elif freq == WEEKLY:
- if wkst > weekday:
- day += -(weekday+1+(6-wkst))+self._interval*7
- else:
- day += -(weekday-wkst)+self._interval*7
- weekday = wkst
- fixday = True
- elif freq == DAILY:
- day += interval
- fixday = True
- elif freq == HOURLY:
- if filtered:
- # Jump to one iteration before next day
- hour += ((23-hour)//interval)*interval
- while True:
- hour += interval
- div, mod = divmod(hour, 24)
- if div:
- hour = mod
- day += div
- fixday = True
- if not byhour or hour in byhour:
- break
- timeset = gettimeset(hour, minute, second)
- elif freq == MINUTELY:
- if filtered:
- # Jump to one iteration before next day
- minute += ((1439-(hour*60+minute))//interval)*interval
- while True:
- minute += interval
- div, mod = divmod(minute, 60)
- if div:
- minute = mod
- hour += div
- div, mod = divmod(hour, 24)
- if div:
- hour = mod
- day += div
- fixday = True
- filtered = False
- if ((not byhour or hour in byhour) and
- (not byminute or minute in byminute)):
- break
- timeset = gettimeset(hour, minute, second)
- elif freq == SECONDLY:
- if filtered:
- # Jump to one iteration before next day
- second += (((86399-(hour*3600+minute*60+second))
- //interval)*interval)
- while True:
- second += self._interval
- div, mod = divmod(second, 60)
- if div:
- second = mod
- minute += div
- div, mod = divmod(minute, 60)
- if div:
- minute = mod
- hour += div
- div, mod = divmod(hour, 24)
- if div:
- hour = mod
- day += div
- fixday = True
- if ((not byhour or hour in byhour) and
- (not byminute or minute in byminute) and
- (not bysecond or second in bysecond)):
- break
- timeset = gettimeset(hour, minute, second)
-
- if fixday and day > 28:
- daysinmonth = calendar.monthrange(year, month)[1]
- if day > daysinmonth:
- while day > daysinmonth:
- day -= daysinmonth
- month += 1
- if month == 13:
- month = 1
- year += 1
- if year > datetime.MAXYEAR:
- self._len = total
- return
- daysinmonth = calendar.monthrange(year, month)[1]
- ii.rebuild(year, month)
-
-class _iterinfo(object):
- __slots__ = ["rrule", "lastyear", "lastmonth",
- "yearlen", "nextyearlen", "yearordinal", "yearweekday",
- "mmask", "mrange", "mdaymask", "nmdaymask",
- "wdaymask", "wnomask", "nwdaymask", "eastermask"]
-
- def __init__(self, rrule):
- for attr in self.__slots__:
- setattr(self, attr, None)
- self.rrule = rrule
-
- def rebuild(self, year, month):
- # Every mask is 7 days longer to handle cross-year weekly periods.
- rr = self.rrule
- if year != self.lastyear:
- self.yearlen = 365+calendar.isleap(year)
- self.nextyearlen = 365+calendar.isleap(year+1)
- firstyday = datetime.date(year, 1, 1)
- self.yearordinal = firstyday.toordinal()
- self.yearweekday = firstyday.weekday()
-
- wday = datetime.date(year, 1, 1).weekday()
- if self.yearlen == 365:
- self.mmask = M365MASK
- self.mdaymask = MDAY365MASK
- self.nmdaymask = NMDAY365MASK
- self.wdaymask = WDAYMASK[wday:]
- self.mrange = M365RANGE
- else:
- self.mmask = M366MASK
- self.mdaymask = MDAY366MASK
- self.nmdaymask = NMDAY366MASK
- self.wdaymask = WDAYMASK[wday:]
- self.mrange = M366RANGE
-
- if not rr._byweekno:
- self.wnomask = None
- else:
- self.wnomask = [0]*(self.yearlen+7)
- #no1wkst = firstwkst = self.wdaymask.index(rr._wkst)
- no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7
- if no1wkst >= 4:
- no1wkst = 0
- # Number of days in the year, plus the days we got
- # from last year.
- wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7
- else:
- # Number of days in the year, minus the days we
- # left in last year.
- wyearlen = self.yearlen-no1wkst
- div, mod = divmod(wyearlen, 7)
- numweeks = div+mod//4
- for n in rr._byweekno:
- if n < 0:
- n += numweeks+1
- if not (0 < n <= numweeks):
- continue
- if n > 1:
- i = no1wkst+(n-1)*7
- if no1wkst != firstwkst:
- i -= 7-firstwkst
- else:
- i = no1wkst
- for j in range(7):
- self.wnomask[i] = 1
- i += 1
- if self.wdaymask[i] == rr._wkst:
- break
- if 1 in rr._byweekno:
- # Check week number 1 of next year as well
- # TODO: Check -numweeks for next year.
- i = no1wkst+numweeks*7
- if no1wkst != firstwkst:
- i -= 7-firstwkst
- if i < self.yearlen:
- # If week starts in next year, we
- # don't care about it.
- for j in range(7):
- self.wnomask[i] = 1
- i += 1
- if self.wdaymask[i] == rr._wkst:
- break
- if no1wkst:
- # Check last week number of last year as
- # well. If no1wkst is 0, either the year
- # started on week start, or week number 1
- # got days from last year, so there are no
- # days from last year's last week number in
- # this year.
- if -1 not in rr._byweekno:
- lyearweekday = datetime.date(year-1,1,1).weekday()
- lno1wkst = (7-lyearweekday+rr._wkst)%7
- lyearlen = 365+calendar.isleap(year-1)
- if lno1wkst >= 4:
- lno1wkst = 0
- lnumweeks = 52+(lyearlen+
- (lyearweekday-rr._wkst)%7)%7//4
- else:
- lnumweeks = 52+(self.yearlen-no1wkst)%7//4
- else:
- lnumweeks = -1
- if lnumweeks in rr._byweekno:
- for i in range(no1wkst):
- self.wnomask[i] = 1
-
- if (rr._bynweekday and
- (month != self.lastmonth or year != self.lastyear)):
- ranges = []
- if rr._freq == YEARLY:
- if rr._bymonth:
- for month in rr._bymonth:
- ranges.append(self.mrange[month-1:month+1])
- else:
- ranges = [(0, self.yearlen)]
- elif rr._freq == MONTHLY:
- ranges = [self.mrange[month-1:month+1]]
- if ranges:
- # Weekly frequency won't get here, so we may not
- # care about cross-year weekly periods.
- self.nwdaymask = [0]*self.yearlen
- for first, last in ranges:
- last -= 1
- for wday, n in rr._bynweekday:
- if n < 0:
- i = last+(n+1)*7
- i -= (self.wdaymask[i]-wday)%7
- else:
- i = first+(n-1)*7
- i += (7-self.wdaymask[i]+wday)%7
- if first <= i <= last:
- self.nwdaymask[i] = 1
-
- if rr._byeaster:
- self.eastermask = [0]*(self.yearlen+7)
- eyday = easter.easter(year).toordinal()-self.yearordinal
- for offset in rr._byeaster:
- self.eastermask[eyday+offset] = 1
-
- self.lastyear = year
- self.lastmonth = month
-
- def ydayset(self, year, month, day):
- return range(self.yearlen), 0, self.yearlen
-
- def mdayset(self, year, month, day):
- set = [None]*self.yearlen
- start, end = self.mrange[month-1:month+1]
- for i in range(start, end):
- set[i] = i
- return set, start, end
-
- def wdayset(self, year, month, day):
- # We need to handle cross-year weeks here.
- set = [None]*(self.yearlen+7)
- i = datetime.date(year, month, day).toordinal()-self.yearordinal
- start = i
- for j in range(7):
- set[i] = i
- i += 1
- #if (not (0 <= i < self.yearlen) or
- # self.wdaymask[i] == self.rrule._wkst):
- # This will cross the year boundary, if necessary.
- if self.wdaymask[i] == self.rrule._wkst:
- break
- return set, start, i
-
- def ddayset(self, year, month, day):
- set = [None]*self.yearlen
- i = datetime.date(year, month, day).toordinal()-self.yearordinal
- set[i] = i
- return set, i, i+1
-
- def htimeset(self, hour, minute, second):
- set = []
- rr = self.rrule
- for minute in rr._byminute:
- for second in rr._bysecond:
- set.append(datetime.time(hour, minute, second,
- tzinfo=rr._tzinfo))
- set.sort()
- return set
-
- def mtimeset(self, hour, minute, second):
- set = []
- rr = self.rrule
- for second in rr._bysecond:
- set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo))
- set.sort()
- return set
-
- def stimeset(self, hour, minute, second):
- return (datetime.time(hour, minute, second,
- tzinfo=self.rrule._tzinfo),)
-
-
-class rruleset(rrulebase):
-
- class _genitem:
- def __init__(self, genlist, gen):
- try:
- self.dt = gen()
- genlist.append(self)
- except StopIteration:
- pass
- self.genlist = genlist
- self.gen = gen
-
- def next(self):
- try:
- self.dt = self.gen()
- except StopIteration:
- self.genlist.remove(self)
-
- def __cmp__(self, other):
- return cmp(self.dt, other.dt)
-
- def __init__(self, cache=False):
- rrulebase.__init__(self, cache)
- self._rrule = []
- self._rdate = []
- self._exrule = []
- self._exdate = []
-
- def rrule(self, rrule):
- self._rrule.append(rrule)
-
- def rdate(self, rdate):
- self._rdate.append(rdate)
-
- def exrule(self, exrule):
- self._exrule.append(exrule)
-
- def exdate(self, exdate):
- self._exdate.append(exdate)
-
- def _iter(self):
- rlist = []
- self._rdate.sort()
- self._genitem(rlist, iter(self._rdate).next)
- for gen in [iter(x).next for x in self._rrule]:
- self._genitem(rlist, gen)
- rlist.sort()
- exlist = []
- self._exdate.sort()
- self._genitem(exlist, iter(self._exdate).next)
- for gen in [iter(x).next for x in self._exrule]:
- self._genitem(exlist, gen)
- exlist.sort()
- lastdt = None
- total = 0
- while rlist:
- ritem = rlist[0]
- if not lastdt or lastdt != ritem.dt:
- while exlist and exlist[0] < ritem:
- exlist[0].next()
- exlist.sort()
- if not exlist or ritem != exlist[0]:
- total += 1
- yield ritem.dt
- lastdt = ritem.dt
- ritem.next()
- rlist.sort()
- self._len = total
-
-class _rrulestr:
-
- _freq_map = {"YEARLY": YEARLY,
- "MONTHLY": MONTHLY,
- "WEEKLY": WEEKLY,
- "DAILY": DAILY,
- "HOURLY": HOURLY,
- "MINUTELY": MINUTELY,
- "SECONDLY": SECONDLY}
-
- _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6}
-
- def _handle_int(self, rrkwargs, name, value, **kwargs):
- rrkwargs[name.lower()] = int(value)
-
- def _handle_int_list(self, rrkwargs, name, value, **kwargs):
- rrkwargs[name.lower()] = [int(x) for x in value.split(',')]
-
- _handle_INTERVAL = _handle_int
- _handle_COUNT = _handle_int
- _handle_BYSETPOS = _handle_int_list
- _handle_BYMONTH = _handle_int_list
- _handle_BYMONTHDAY = _handle_int_list
- _handle_BYYEARDAY = _handle_int_list
- _handle_BYEASTER = _handle_int_list
- _handle_BYWEEKNO = _handle_int_list
- _handle_BYHOUR = _handle_int_list
- _handle_BYMINUTE = _handle_int_list
- _handle_BYSECOND = _handle_int_list
-
- def _handle_FREQ(self, rrkwargs, name, value, **kwargs):
- rrkwargs["freq"] = self._freq_map[value]
-
- def _handle_UNTIL(self, rrkwargs, name, value, **kwargs):
- global parser
- if not parser:
- from dateutil import parser
- try:
- rrkwargs["until"] = parser.parse(value,
- ignoretz=kwargs.get("ignoretz"),
- tzinfos=kwargs.get("tzinfos"))
- except ValueError:
- raise ValueError, "invalid until date"
-
- def _handle_WKST(self, rrkwargs, name, value, **kwargs):
- rrkwargs["wkst"] = self._weekday_map[value]
-
- def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg):
- l = []
- for wday in value.split(','):
- for i in range(len(wday)):
- if wday[i] not in '+-0123456789':
- break
- n = wday[:i] or None
- w = wday[i:]
- if n: n = int(n)
- l.append(weekdays[self._weekday_map[w]](n))
- rrkwargs["byweekday"] = l
-
- _handle_BYDAY = _handle_BYWEEKDAY
-
- def _parse_rfc_rrule(self, line,
- dtstart=None,
- cache=False,
- ignoretz=False,
- tzinfos=None):
- if line.find(':') != -1:
- name, value = line.split(':')
- if name != "RRULE":
- raise ValueError, "unknown parameter name"
- else:
- value = line
- rrkwargs = {}
- for pair in value.split(';'):
- name, value = pair.split('=')
- name = name.upper()
- value = value.upper()
- try:
- getattr(self, "_handle_"+name)(rrkwargs, name, value,
- ignoretz=ignoretz,
- tzinfos=tzinfos)
- except AttributeError:
- raise ValueError, "unknown parameter '%s'" % name
- except (KeyError, ValueError):
- raise ValueError, "invalid '%s': %s" % (name, value)
- return rrule(dtstart=dtstart, cache=cache, **rrkwargs)
-
- def _parse_rfc(self, s,
- dtstart=None,
- cache=False,
- unfold=False,
- forceset=False,
- compatible=False,
- ignoretz=False,
- tzinfos=None):
- global parser
- if compatible:
- forceset = True
- unfold = True
- s = s.upper()
- if not s.strip():
- raise ValueError, "empty string"
- if unfold:
- lines = s.splitlines()
- i = 0
- while i < len(lines):
- line = lines[i].rstrip()
- if not line:
- del lines[i]
- elif i > 0 and line[0] == " ":
- lines[i-1] += line[1:]
- del lines[i]
- else:
- i += 1
- else:
- lines = s.split()
- if (not forceset and len(lines) == 1 and
- (s.find(':') == -1 or s.startswith('RRULE:'))):
- return self._parse_rfc_rrule(lines[0], cache=cache,
- dtstart=dtstart, ignoretz=ignoretz,
- tzinfos=tzinfos)
- else:
- rrulevals = []
- rdatevals = []
- exrulevals = []
- exdatevals = []
- for line in lines:
- if not line:
- continue
- if line.find(':') == -1:
- name = "RRULE"
- value = line
- else:
- name, value = line.split(':', 1)
- parms = name.split(';')
- if not parms:
- raise ValueError, "empty property name"
- name = parms[0]
- parms = parms[1:]
- if name == "RRULE":
- for parm in parms:
- raise ValueError, "unsupported RRULE parm: "+parm
- rrulevals.append(value)
- elif name == "RDATE":
- for parm in parms:
- if parm != "VALUE=DATE-TIME":
- raise ValueError, "unsupported RDATE parm: "+parm
- rdatevals.append(value)
- elif name == "EXRULE":
- for parm in parms:
- raise ValueError, "unsupported EXRULE parm: "+parm
- exrulevals.append(value)
- elif name == "EXDATE":
- for parm in parms:
- if parm != "VALUE=DATE-TIME":
- raise ValueError, "unsupported RDATE parm: "+parm
- exdatevals.append(value)
- elif name == "DTSTART":
- for parm in parms:
- raise ValueError, "unsupported DTSTART parm: "+parm
- if not parser:
- from dateutil import parser
- dtstart = parser.parse(value, ignoretz=ignoretz,
- tzinfos=tzinfos)
- else:
- raise ValueError, "unsupported property: "+name
- if (forceset or len(rrulevals) > 1 or
- rdatevals or exrulevals or exdatevals):
- if not parser and (rdatevals or exdatevals):
- from dateutil import parser
- set = rruleset(cache=cache)
- for value in rrulevals:
- set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- for value in rdatevals:
- for datestr in value.split(','):
- set.rdate(parser.parse(datestr,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- for value in exrulevals:
- set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- for value in exdatevals:
- for datestr in value.split(','):
- set.exdate(parser.parse(datestr,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- if compatible and dtstart:
- set.rdate(dtstart)
- return set
- else:
- return self._parse_rfc_rrule(rrulevals[0],
- dtstart=dtstart,
- cache=cache,
- ignoretz=ignoretz,
- tzinfos=tzinfos)
-
- def __call__(self, s, **kwargs):
- return self._parse_rfc(s, **kwargs)
-
-rrulestr = _rrulestr()
-
-# vim:ts=4:sw=4:et
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tz.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tz.py
deleted file mode 100755
index 0e28d6b3..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tz.py
+++ /dev/null
@@ -1,951 +0,0 @@
-"""
-Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-import datetime
-import struct
-import time
-import sys
-import os
-
-relativedelta = None
-parser = None
-rrule = None
-
-__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
- "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]
-
-try:
- from dateutil.tzwin import tzwin, tzwinlocal
-except (ImportError, OSError):
- tzwin, tzwinlocal = None, None
-
-ZERO = datetime.timedelta(0)
-EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
-
-class tzutc(datetime.tzinfo):
-
- def utcoffset(self, dt):
- return ZERO
-
- def dst(self, dt):
- return ZERO
-
- def tzname(self, dt):
- return "UTC"
-
- def __eq__(self, other):
- return (isinstance(other, tzutc) or
- (isinstance(other, tzoffset) and other._offset == ZERO))
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return "%s()" % self.__class__.__name__
-
- __reduce__ = object.__reduce__
-
-class tzoffset(datetime.tzinfo):
-
- def __init__(self, name, offset):
- self._name = name
- self._offset = datetime.timedelta(seconds=offset)
-
- def utcoffset(self, dt):
- return self._offset
-
- def dst(self, dt):
- return ZERO
-
- def tzname(self, dt):
- return self._name
-
- def __eq__(self, other):
- return (isinstance(other, tzoffset) and
- self._offset == other._offset)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return "%s(%s, %s)" % (self.__class__.__name__,
- `self._name`,
- self._offset.days*86400+self._offset.seconds)
-
- __reduce__ = object.__reduce__
-
-class tzlocal(datetime.tzinfo):
-
- _std_offset = datetime.timedelta(seconds=-time.timezone)
- if time.daylight:
- _dst_offset = datetime.timedelta(seconds=-time.altzone)
- else:
- _dst_offset = _std_offset
-
- def utcoffset(self, dt):
- if self._isdst(dt):
- return self._dst_offset
- else:
- return self._std_offset
-
- def dst(self, dt):
- if self._isdst(dt):
- return self._dst_offset-self._std_offset
- else:
- return ZERO
-
- def tzname(self, dt):
- return time.tzname[self._isdst(dt)]
-
- def _isdst(self, dt):
- # We can't use mktime here. It is unstable when deciding if
- # the hour near to a change is DST or not.
- #
- # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour,
- # dt.minute, dt.second, dt.weekday(), 0, -1))
- # return time.localtime(timestamp).tm_isdst
- #
- # The code above yields the following result:
- #
- #>>> import tz, datetime
- #>>> t = tz.tzlocal()
- #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
- #'BRDT'
- #>>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname()
- #'BRST'
- #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
- #'BRST'
- #>>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname()
- #'BRDT'
- #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
- #'BRDT'
- #
- # Here is a more stable implementation:
- #
- timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400
- + dt.hour * 3600
- + dt.minute * 60
- + dt.second)
- return time.localtime(timestamp+time.timezone).tm_isdst
-
- def __eq__(self, other):
- if not isinstance(other, tzlocal):
- return False
- return (self._std_offset == other._std_offset and
- self._dst_offset == other._dst_offset)
- return True
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return "%s()" % self.__class__.__name__
-
- __reduce__ = object.__reduce__
-
-class _ttinfo(object):
- __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"]
-
- def __init__(self):
- for attr in self.__slots__:
- setattr(self, attr, None)
-
- def __repr__(self):
- l = []
- for attr in self.__slots__:
- value = getattr(self, attr)
- if value is not None:
- l.append("%s=%s" % (attr, `value`))
- return "%s(%s)" % (self.__class__.__name__, ", ".join(l))
-
- def __eq__(self, other):
- if not isinstance(other, _ttinfo):
- return False
- return (self.offset == other.offset and
- self.delta == other.delta and
- self.isdst == other.isdst and
- self.abbr == other.abbr and
- self.isstd == other.isstd and
- self.isgmt == other.isgmt)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __getstate__(self):
- state = {}
- for name in self.__slots__:
- state[name] = getattr(self, name, None)
- return state
-
- def __setstate__(self, state):
- for name in self.__slots__:
- if name in state:
- setattr(self, name, state[name])
-
-class tzfile(datetime.tzinfo):
-
- # http://www.twinsun.com/tz/tz-link.htm
- # ftp://elsie.nci.nih.gov/pub/tz*.tar.gz
-
- def __init__(self, fileobj):
- if isinstance(fileobj, basestring):
- self._filename = fileobj
- fileobj = open(fileobj)
- elif hasattr(fileobj, "name"):
- self._filename = fileobj.name
- else:
- self._filename = `fileobj`
-
- # From tzfile(5):
- #
- # The time zone information files used by tzset(3)
- # begin with the magic characters "TZif" to identify
- # them as time zone information files, followed by
- # sixteen bytes reserved for future use, followed by
- # six four-byte values of type long, written in a
- # ``standard'' byte order (the high-order byte
- # of the value is written first).
-
- if fileobj.read(4) != "TZif":
- raise ValueError, "magic not found"
-
- fileobj.read(16)
-
- (
- # The number of UTC/local indicators stored in the file.
- ttisgmtcnt,
-
- # The number of standard/wall indicators stored in the file.
- ttisstdcnt,
-
- # The number of leap seconds for which data is
- # stored in the file.
- leapcnt,
-
- # The number of "transition times" for which data
- # is stored in the file.
- timecnt,
-
- # The number of "local time types" for which data
- # is stored in the file (must not be zero).
- typecnt,
-
- # The number of characters of "time zone
- # abbreviation strings" stored in the file.
- charcnt,
-
- ) = struct.unpack(">6l", fileobj.read(24))
-
- # The above header is followed by tzh_timecnt four-byte
- # values of type long, sorted in ascending order.
- # These values are written in ``standard'' byte order.
- # Each is used as a transition time (as returned by
- # time(2)) at which the rules for computing local time
- # change.
-
- if timecnt:
- self._trans_list = struct.unpack(">%dl" % timecnt,
- fileobj.read(timecnt*4))
- else:
- self._trans_list = []
-
- # Next come tzh_timecnt one-byte values of type unsigned
- # char; each one tells which of the different types of
- # ``local time'' types described in the file is associated
- # with the same-indexed transition time. These values
- # serve as indices into an array of ttinfo structures that
- # appears next in the file.
-
- if timecnt:
- self._trans_idx = struct.unpack(">%dB" % timecnt,
- fileobj.read(timecnt))
- else:
- self._trans_idx = []
-
- # Each ttinfo structure is written as a four-byte value
- # for tt_gmtoff of type long, in a standard byte
- # order, followed by a one-byte value for tt_isdst
- # and a one-byte value for tt_abbrind. In each
- # structure, tt_gmtoff gives the number of
- # seconds to be added to UTC, tt_isdst tells whether
- # tm_isdst should be set by localtime(3), and
- # tt_abbrind serves as an index into the array of
- # time zone abbreviation characters that follow the
- # ttinfo structure(s) in the file.
-
- ttinfo = []
-
- for i in range(typecnt):
- ttinfo.append(struct.unpack(">lbb", fileobj.read(6)))
-
- abbr = fileobj.read(charcnt)
-
- # Then there are tzh_leapcnt pairs of four-byte
- # values, written in standard byte order; the
- # first value of each pair gives the time (as
- # returned by time(2)) at which a leap second
- # occurs; the second gives the total number of
- # leap seconds to be applied after the given time.
- # The pairs of values are sorted in ascending order
- # by time.
-
- # Not used, for now
- if leapcnt:
- leap = struct.unpack(">%dl" % (leapcnt*2),
- fileobj.read(leapcnt*8))
-
- # Then there are tzh_ttisstdcnt standard/wall
- # indicators, each stored as a one-byte value;
- # they tell whether the transition times associated
- # with local time types were specified as standard
- # time or wall clock time, and are used when
- # a time zone file is used in handling POSIX-style
- # time zone environment variables.
-
- if ttisstdcnt:
- isstd = struct.unpack(">%db" % ttisstdcnt,
- fileobj.read(ttisstdcnt))
-
- # Finally, there are tzh_ttisgmtcnt UTC/local
- # indicators, each stored as a one-byte value;
- # they tell whether the transition times associated
- # with local time types were specified as UTC or
- # local time, and are used when a time zone file
- # is used in handling POSIX-style time zone envi-
- # ronment variables.
-
- if ttisgmtcnt:
- isgmt = struct.unpack(">%db" % ttisgmtcnt,
- fileobj.read(ttisgmtcnt))
-
- # ** Everything has been read **
-
- # Build ttinfo list
- self._ttinfo_list = []
- for i in range(typecnt):
- gmtoff, isdst, abbrind = ttinfo[i]
- # Round to full-minutes if that's not the case. Python's
- # datetime doesn't accept sub-minute timezones. Check
- # http://python.org/sf/1447945 for some information.
- gmtoff = (gmtoff+30)//60*60
- tti = _ttinfo()
- tti.offset = gmtoff
- tti.delta = datetime.timedelta(seconds=gmtoff)
- tti.isdst = isdst
- tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)]
- tti.isstd = (ttisstdcnt > i and isstd[i] != 0)
- tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0)
- self._ttinfo_list.append(tti)
-
- # Replace ttinfo indexes for ttinfo objects.
- trans_idx = []
- for idx in self._trans_idx:
- trans_idx.append(self._ttinfo_list[idx])
- self._trans_idx = tuple(trans_idx)
-
- # Set standard, dst, and before ttinfos. before will be
- # used when a given time is before any transitions,
- # and will be set to the first non-dst ttinfo, or to
- # the first dst, if all of them are dst.
- self._ttinfo_std = None
- self._ttinfo_dst = None
- self._ttinfo_before = None
- if self._ttinfo_list:
- if not self._trans_list:
- self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0]
- else:
- for i in range(timecnt-1,-1,-1):
- tti = self._trans_idx[i]
- if not self._ttinfo_std and not tti.isdst:
- self._ttinfo_std = tti
- elif not self._ttinfo_dst and tti.isdst:
- self._ttinfo_dst = tti
- if self._ttinfo_std and self._ttinfo_dst:
- break
- else:
- if self._ttinfo_dst and not self._ttinfo_std:
- self._ttinfo_std = self._ttinfo_dst
-
- for tti in self._ttinfo_list:
- if not tti.isdst:
- self._ttinfo_before = tti
- break
- else:
- self._ttinfo_before = self._ttinfo_list[0]
-
- # Now fix transition times to become relative to wall time.
- #
- # I'm not sure about this. In my tests, the tz source file
- # is setup to wall time, and in the binary file isstd and
- # isgmt are off, so it should be in wall time. OTOH, it's
- # always in gmt time. Let me know if you have comments
- # about this.
- laststdoffset = 0
- self._trans_list = list(self._trans_list)
- for i in range(len(self._trans_list)):
- tti = self._trans_idx[i]
- if not tti.isdst:
- # This is std time.
- self._trans_list[i] += tti.offset
- laststdoffset = tti.offset
- else:
- # This is dst time. Convert to std.
- self._trans_list[i] += laststdoffset
- self._trans_list = tuple(self._trans_list)
-
- def _find_ttinfo(self, dt, laststd=0):
- timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400
- + dt.hour * 3600
- + dt.minute * 60
- + dt.second)
- idx = 0
- for trans in self._trans_list:
- if timestamp < trans:
- break
- idx += 1
- else:
- return self._ttinfo_std
- if idx == 0:
- return self._ttinfo_before
- if laststd:
- while idx > 0:
- tti = self._trans_idx[idx-1]
- if not tti.isdst:
- return tti
- idx -= 1
- else:
- return self._ttinfo_std
- else:
- return self._trans_idx[idx-1]
-
- def utcoffset(self, dt):
- if not self._ttinfo_std:
- return ZERO
- return self._find_ttinfo(dt).delta
-
- def dst(self, dt):
- if not self._ttinfo_dst:
- return ZERO
- tti = self._find_ttinfo(dt)
- if not tti.isdst:
- return ZERO
-
- # The documentation says that utcoffset()-dst() must
- # be constant for every dt.
- return tti.delta-self._find_ttinfo(dt, laststd=1).delta
-
- # An alternative for that would be:
- #
- # return self._ttinfo_dst.offset-self._ttinfo_std.offset
- #
- # However, this class stores historical changes in the
- # dst offset, so I belive that this wouldn't be the right
- # way to implement this.
-
- def tzname(self, dt):
- if not self._ttinfo_std:
- return None
- return self._find_ttinfo(dt).abbr
-
- def __eq__(self, other):
- if not isinstance(other, tzfile):
- return False
- return (self._trans_list == other._trans_list and
- self._trans_idx == other._trans_idx and
- self._ttinfo_list == other._ttinfo_list)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-
- def __repr__(self):
- return "%s(%s)" % (self.__class__.__name__, `self._filename`)
-
- def __reduce__(self):
- if not os.path.isfile(self._filename):
- raise ValueError, "Unpickable %s class" % self.__class__.__name__
- return (self.__class__, (self._filename,))
-
-class tzrange(datetime.tzinfo):
-
- def __init__(self, stdabbr, stdoffset=None,
- dstabbr=None, dstoffset=None,
- start=None, end=None):
- global relativedelta
- if not relativedelta:
- from dateutil import relativedelta
- self._std_abbr = stdabbr
- self._dst_abbr = dstabbr
- if stdoffset is not None:
- self._std_offset = datetime.timedelta(seconds=stdoffset)
- else:
- self._std_offset = ZERO
- if dstoffset is not None:
- self._dst_offset = datetime.timedelta(seconds=dstoffset)
- elif dstabbr and stdoffset is not None:
- self._dst_offset = self._std_offset+datetime.timedelta(hours=+1)
- else:
- self._dst_offset = ZERO
- if dstabbr and start is None:
- self._start_delta = relativedelta.relativedelta(
- hours=+2, month=4, day=1, weekday=relativedelta.SU(+1))
- else:
- self._start_delta = start
- if dstabbr and end is None:
- self._end_delta = relativedelta.relativedelta(
- hours=+1, month=10, day=31, weekday=relativedelta.SU(-1))
- else:
- self._end_delta = end
-
- def utcoffset(self, dt):
- if self._isdst(dt):
- return self._dst_offset
- else:
- return self._std_offset
-
- def dst(self, dt):
- if self._isdst(dt):
- return self._dst_offset-self._std_offset
- else:
- return ZERO
-
- def tzname(self, dt):
- if self._isdst(dt):
- return self._dst_abbr
- else:
- return self._std_abbr
-
- def _isdst(self, dt):
- if not self._start_delta:
- return False
- year = datetime.datetime(dt.year,1,1)
- start = year+self._start_delta
- end = year+self._end_delta
- dt = dt.replace(tzinfo=None)
- if start < end:
- return dt >= start and dt < end
- else:
- return dt >= start or dt < end
-
- def __eq__(self, other):
- if not isinstance(other, tzrange):
- return False
- return (self._std_abbr == other._std_abbr and
- self._dst_abbr == other._dst_abbr and
- self._std_offset == other._std_offset and
- self._dst_offset == other._dst_offset and
- self._start_delta == other._start_delta and
- self._end_delta == other._end_delta)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return "%s(...)" % self.__class__.__name__
-
- __reduce__ = object.__reduce__
-
-class tzstr(tzrange):
-
- def __init__(self, s):
- global parser
- if not parser:
- from dateutil import parser
- self._s = s
-
- res = parser._parsetz(s)
- if res is None:
- raise ValueError, "unknown string format"
-
- # Here we break the compatibility with the TZ variable handling.
- # GMT-3 actually *means* the timezone -3.
- if res.stdabbr in ("GMT", "UTC"):
- res.stdoffset *= -1
-
- # We must initialize it first, since _delta() needs
- # _std_offset and _dst_offset set. Use False in start/end
- # to avoid building it two times.
- tzrange.__init__(self, res.stdabbr, res.stdoffset,
- res.dstabbr, res.dstoffset,
- start=False, end=False)
-
- if not res.dstabbr:
- self._start_delta = None
- self._end_delta = None
- else:
- self._start_delta = self._delta(res.start)
- if self._start_delta:
- self._end_delta = self._delta(res.end, isend=1)
-
- def _delta(self, x, isend=0):
- kwargs = {}
- if x.month is not None:
- kwargs["month"] = x.month
- if x.weekday is not None:
- kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week)
- if x.week > 0:
- kwargs["day"] = 1
- else:
- kwargs["day"] = 31
- elif x.day:
- kwargs["day"] = x.day
- elif x.yday is not None:
- kwargs["yearday"] = x.yday
- elif x.jyday is not None:
- kwargs["nlyearday"] = x.jyday
- if not kwargs:
- # Default is to start on first sunday of april, and end
- # on last sunday of october.
- if not isend:
- kwargs["month"] = 4
- kwargs["day"] = 1
- kwargs["weekday"] = relativedelta.SU(+1)
- else:
- kwargs["month"] = 10
- kwargs["day"] = 31
- kwargs["weekday"] = relativedelta.SU(-1)
- if x.time is not None:
- kwargs["seconds"] = x.time
- else:
- # Default is 2AM.
- kwargs["seconds"] = 7200
- if isend:
- # Convert to standard time, to follow the documented way
- # of working with the extra hour. See the documentation
- # of the tzinfo class.
- delta = self._dst_offset-self._std_offset
- kwargs["seconds"] -= delta.seconds+delta.days*86400
- return relativedelta.relativedelta(**kwargs)
-
- def __repr__(self):
- return "%s(%s)" % (self.__class__.__name__, `self._s`)
-
-class _tzicalvtzcomp:
- def __init__(self, tzoffsetfrom, tzoffsetto, isdst,
- tzname=None, rrule=None):
- self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom)
- self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto)
- self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom
- self.isdst = isdst
- self.tzname = tzname
- self.rrule = rrule
-
-class _tzicalvtz(datetime.tzinfo):
- def __init__(self, tzid, comps=[]):
- self._tzid = tzid
- self._comps = comps
- self._cachedate = []
- self._cachecomp = []
-
- def _find_comp(self, dt):
- if len(self._comps) == 1:
- return self._comps[0]
- dt = dt.replace(tzinfo=None)
- try:
- return self._cachecomp[self._cachedate.index(dt)]
- except ValueError:
- pass
- lastcomp = None
- lastcompdt = None
- for comp in self._comps:
- if not comp.isdst:
- # Handle the extra hour in DST -> STD
- compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True)
- else:
- compdt = comp.rrule.before(dt, inc=True)
- if compdt and (not lastcompdt or lastcompdt < compdt):
- lastcompdt = compdt
- lastcomp = comp
- if not lastcomp:
- # RFC says nothing about what to do when a given
- # time is before the first onset date. We'll look for the
- # first standard component, or the first component, if
- # none is found.
- for comp in self._comps:
- if not comp.isdst:
- lastcomp = comp
- break
- else:
- lastcomp = comp[0]
- self._cachedate.insert(0, dt)
- self._cachecomp.insert(0, lastcomp)
- if len(self._cachedate) > 10:
- self._cachedate.pop()
- self._cachecomp.pop()
- return lastcomp
-
- def utcoffset(self, dt):
- return self._find_comp(dt).tzoffsetto
-
- def dst(self, dt):
- comp = self._find_comp(dt)
- if comp.isdst:
- return comp.tzoffsetdiff
- else:
- return ZERO
-
- def tzname(self, dt):
- return self._find_comp(dt).tzname
-
- def __repr__(self):
- return "<tzicalvtz %s>" % `self._tzid`
-
- __reduce__ = object.__reduce__
-
-class tzical:
- def __init__(self, fileobj):
- global rrule
- if not rrule:
- from dateutil import rrule
-
- if isinstance(fileobj, basestring):
- self._s = fileobj
- fileobj = open(fileobj)
- elif hasattr(fileobj, "name"):
- self._s = fileobj.name
- else:
- self._s = `fileobj`
-
- self._vtz = {}
-
- self._parse_rfc(fileobj.read())
-
- def keys(self):
- return self._vtz.keys()
-
- def get(self, tzid=None):
- if tzid is None:
- keys = self._vtz.keys()
- if len(keys) == 0:
- raise ValueError, "no timezones defined"
- elif len(keys) > 1:
- raise ValueError, "more than one timezone available"
- tzid = keys[0]
- return self._vtz.get(tzid)
-
- def _parse_offset(self, s):
- s = s.strip()
- if not s:
- raise ValueError, "empty offset"
- if s[0] in ('+', '-'):
- signal = (-1,+1)[s[0]=='+']
- s = s[1:]
- else:
- signal = +1
- if len(s) == 4:
- return (int(s[:2])*3600+int(s[2:])*60)*signal
- elif len(s) == 6:
- return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal
- else:
- raise ValueError, "invalid offset: "+s
-
- def _parse_rfc(self, s):
- lines = s.splitlines()
- if not lines:
- raise ValueError, "empty string"
-
- # Unfold
- i = 0
- while i < len(lines):
- line = lines[i].rstrip()
- if not line:
- del lines[i]
- elif i > 0 and line[0] == " ":
- lines[i-1] += line[1:]
- del lines[i]
- else:
- i += 1
-
- tzid = None
- comps = []
- invtz = False
- comptype = None
- for line in lines:
- if not line:
- continue
- name, value = line.split(':', 1)
- parms = name.split(';')
- if not parms:
- raise ValueError, "empty property name"
- name = parms[0].upper()
- parms = parms[1:]
- if invtz:
- if name == "BEGIN":
- if value in ("STANDARD", "DAYLIGHT"):
- # Process component
- pass
- else:
- raise ValueError, "unknown component: "+value
- comptype = value
- founddtstart = False
- tzoffsetfrom = None
- tzoffsetto = None
- rrulelines = []
- tzname = None
- elif name == "END":
- if value == "VTIMEZONE":
- if comptype:
- raise ValueError, \
- "component not closed: "+comptype
- if not tzid:
- raise ValueError, \
- "mandatory TZID not found"
- if not comps:
- raise ValueError, \
- "at least one component is needed"
- # Process vtimezone
- self._vtz[tzid] = _tzicalvtz(tzid, comps)
- invtz = False
- elif value == comptype:
- if not founddtstart:
- raise ValueError, \
- "mandatory DTSTART not found"
- if tzoffsetfrom is None:
- raise ValueError, \
- "mandatory TZOFFSETFROM not found"
- if tzoffsetto is None:
- raise ValueError, \
- "mandatory TZOFFSETFROM not found"
- # Process component
- rr = None
- if rrulelines:
- rr = rrule.rrulestr("\n".join(rrulelines),
- compatible=True,
- ignoretz=True,
- cache=True)
- comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto,
- (comptype == "DAYLIGHT"),
- tzname, rr)
- comps.append(comp)
- comptype = None
- else:
- raise ValueError, \
- "invalid component end: "+value
- elif comptype:
- if name == "DTSTART":
- rrulelines.append(line)
- founddtstart = True
- elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"):
- rrulelines.append(line)
- elif name == "TZOFFSETFROM":
- if parms:
- raise ValueError, \
- "unsupported %s parm: %s "%(name, parms[0])
- tzoffsetfrom = self._parse_offset(value)
- elif name == "TZOFFSETTO":
- if parms:
- raise ValueError, \
- "unsupported TZOFFSETTO parm: "+parms[0]
- tzoffsetto = self._parse_offset(value)
- elif name == "TZNAME":
- if parms:
- raise ValueError, \
- "unsupported TZNAME parm: "+parms[0]
- tzname = value
- elif name == "COMMENT":
- pass
- else:
- raise ValueError, "unsupported property: "+name
- else:
- if name == "TZID":
- if parms:
- raise ValueError, \
- "unsupported TZID parm: "+parms[0]
- tzid = value
- elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"):
- pass
- else:
- raise ValueError, "unsupported property: "+name
- elif name == "BEGIN" and value == "VTIMEZONE":
- tzid = None
- comps = []
- invtz = True
-
- def __repr__(self):
- return "%s(%s)" % (self.__class__.__name__, `self._s`)
-
-if sys.platform != "win32":
- TZFILES = ["/etc/localtime", "localtime"]
- TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"]
-else:
- TZFILES = []
- TZPATHS = []
-
-def gettz(name=None):
- tz = None
- if not name:
- try:
- name = os.environ["TZ"]
- except KeyError:
- pass
- if name is None or name == ":":
- for filepath in TZFILES:
- if not os.path.isabs(filepath):
- filename = filepath
- for path in TZPATHS:
- filepath = os.path.join(path, filename)
- if os.path.isfile(filepath):
- break
- else:
- continue
- if os.path.isfile(filepath):
- try:
- tz = tzfile(filepath)
- break
- except (IOError, OSError, ValueError):
- pass
- else:
- tz = tzlocal()
- else:
- if name.startswith(":"):
- name = name[:-1]
- if os.path.isabs(name):
- if os.path.isfile(name):
- tz = tzfile(name)
- else:
- tz = None
- else:
- for path in TZPATHS:
- filepath = os.path.join(path, name)
- if not os.path.isfile(filepath):
- filepath = filepath.replace(' ','_')
- if not os.path.isfile(filepath):
- continue
- try:
- tz = tzfile(filepath)
- break
- except (IOError, OSError, ValueError):
- pass
- else:
- tz = None
- if tzwin:
- try:
- tz = tzwin(name)
- except OSError:
- pass
- if not tz:
- from dateutil.zoneinfo import gettz
- tz = gettz(name)
- if not tz:
- for c in name:
- # name must have at least one offset to be a tzstr
- if c in "0123456789":
- try:
- tz = tzstr(name)
- except ValueError:
- pass
- break
- else:
- if name in ("GMT", "UTC"):
- tz = tzutc()
- elif name in time.tzname:
- tz = tzlocal()
- return tz
-
-# vim:ts=4:sw=4:et
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tzwin.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tzwin.py
deleted file mode 100755
index 073e0ff6..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/tzwin.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# This code was originally contributed by Jeffrey Harris.
-import datetime
-import struct
-import _winreg
-
-__author__ = "Jeffrey Harris & Gustavo Niemeyer <gustavo@niemeyer.net>"
-
-__all__ = ["tzwin", "tzwinlocal"]
-
-ONEWEEK = datetime.timedelta(7)
-
-TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
-TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
-TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
-
-def _settzkeyname():
- global TZKEYNAME
- handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
- try:
- _winreg.OpenKey(handle, TZKEYNAMENT).Close()
- TZKEYNAME = TZKEYNAMENT
- except WindowsError:
- TZKEYNAME = TZKEYNAME9X
- handle.Close()
-
-_settzkeyname()
-
-class tzwinbase(datetime.tzinfo):
- """tzinfo class based on win32's timezones available in the registry."""
-
- def utcoffset(self, dt):
- if self._isdst(dt):
- return datetime.timedelta(minutes=self._dstoffset)
- else:
- return datetime.timedelta(minutes=self._stdoffset)
-
- def dst(self, dt):
- if self._isdst(dt):
- minutes = self._dstoffset - self._stdoffset
- return datetime.timedelta(minutes=minutes)
- else:
- return datetime.timedelta(0)
-
- def tzname(self, dt):
- if self._isdst(dt):
- return self._dstname
- else:
- return self._stdname
-
- def list():
- """Return a list of all time zones known to the system."""
- handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
- tzkey = _winreg.OpenKey(handle, TZKEYNAME)
- result = [_winreg.EnumKey(tzkey, i)
- for i in range(_winreg.QueryInfoKey(tzkey)[0])]
- tzkey.Close()
- handle.Close()
- return result
- list = staticmethod(list)
-
- def display(self):
- return self._display
-
- def _isdst(self, dt):
- dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek,
- self._dsthour, self._dstminute,
- self._dstweeknumber)
- dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek,
- self._stdhour, self._stdminute,
- self._stdweeknumber)
- if dston < dstoff:
- return dston <= dt.replace(tzinfo=None) < dstoff
- else:
- return not dstoff <= dt.replace(tzinfo=None) < dston
-
-
-class tzwin(tzwinbase):
-
- def __init__(self, name):
- self._name = name
-
- handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
- tzkey = _winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name))
- keydict = valuestodict(tzkey)
- tzkey.Close()
- handle.Close()
-
- self._stdname = keydict["Std"].encode("iso-8859-1")
- self._dstname = keydict["Dlt"].encode("iso-8859-1")
-
- self._display = keydict["Display"]
-
- # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
- tup = struct.unpack("=3l16h", keydict["TZI"])
- self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1
- self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1
-
- (self._stdmonth,
- self._stddayofweek, # Sunday = 0
- self._stdweeknumber, # Last = 5
- self._stdhour,
- self._stdminute) = tup[4:9]
-
- (self._dstmonth,
- self._dstdayofweek, # Sunday = 0
- self._dstweeknumber, # Last = 5
- self._dsthour,
- self._dstminute) = tup[12:17]
-
- def __repr__(self):
- return "tzwin(%s)" % repr(self._name)
-
- def __reduce__(self):
- return (self.__class__, (self._name,))
-
-
-class tzwinlocal(tzwinbase):
-
- def __init__(self):
-
- handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
-
- tzlocalkey = _winreg.OpenKey(handle, TZLOCALKEYNAME)
- keydict = valuestodict(tzlocalkey)
- tzlocalkey.Close()
-
- self._stdname = keydict["StandardName"].encode("iso-8859-1")
- self._dstname = keydict["DaylightName"].encode("iso-8859-1")
-
- try:
- tzkey = _winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname))
- _keydict = valuestodict(tzkey)
- self._display = _keydict["Display"]
- tzkey.Close()
- except OSError:
- self._display = None
-
- handle.Close()
-
- self._stdoffset = -keydict["Bias"]-keydict["StandardBias"]
- self._dstoffset = self._stdoffset-keydict["DaylightBias"]
-
-
- # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
- tup = struct.unpack("=8h", keydict["StandardStart"])
-
- (self._stdmonth,
- self._stddayofweek, # Sunday = 0
- self._stdweeknumber, # Last = 5
- self._stdhour,
- self._stdminute) = tup[1:6]
-
- tup = struct.unpack("=8h", keydict["DaylightStart"])
-
- (self._dstmonth,
- self._dstdayofweek, # Sunday = 0
- self._dstweeknumber, # Last = 5
- self._dsthour,
- self._dstminute) = tup[1:6]
-
- def __reduce__(self):
- return (self.__class__, ())
-
-def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
- """dayofweek == 0 means Sunday, whichweek 5 means last instance"""
- first = datetime.datetime(year, month, 1, hour, minute)
- weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1))
- for n in xrange(whichweek):
- dt = weekdayone+(whichweek-n)*ONEWEEK
- if dt.month == month:
- return dt
-
-def valuestodict(key):
- """Convert a registry key's values to a dictionary."""
- dict = {}
- size = _winreg.QueryInfoKey(key)[1]
- for i in range(size):
- data = _winreg.EnumValue(key, i)
- dict[data[0]] = data[1]
- return dict
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/__init__.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/__init__.py
deleted file mode 100755
index 9bed6264..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/__init__.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""
-Copyright (c) 2003-2005 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-from dateutil.tz import tzfile
-from tarfile import TarFile
-import os
-
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-__all__ = ["setcachesize", "gettz", "rebuild"]
-
-CACHE = []
-CACHESIZE = 10
-
-class tzfile(tzfile):
- def __reduce__(self):
- return (gettz, (self._filename,))
-
-def getzoneinfofile():
- filenames = os.listdir(os.path.join(os.path.dirname(__file__)))
- filenames.sort()
- filenames.reverse()
- for entry in filenames:
- if entry.startswith("zoneinfo") and ".tar." in entry:
- return os.path.join(os.path.dirname(__file__), entry)
- return None
-
-ZONEINFOFILE = getzoneinfofile()
-
-del getzoneinfofile
-
-def setcachesize(size):
- global CACHESIZE, CACHE
- CACHESIZE = size
- del CACHE[size:]
-
-def gettz(name):
- tzinfo = None
- if ZONEINFOFILE:
- for cachedname, tzinfo in CACHE:
- if cachedname == name:
- break
- else:
- tf = TarFile.open(ZONEINFOFILE)
- try:
- zonefile = tf.extractfile(name)
- except KeyError:
- tzinfo = None
- else:
- tzinfo = tzfile(zonefile)
- tf.close()
- CACHE.insert(0, (name, tzinfo))
- del CACHE[CACHESIZE:]
- return tzinfo
-
-def rebuild(filename, tag=None, format="gz"):
- import tempfile, shutil
- tmpdir = tempfile.mkdtemp()
- zonedir = os.path.join(tmpdir, "zoneinfo")
- moduledir = os.path.dirname(__file__)
- if tag: tag = "-"+tag
- targetname = "zoneinfo%s.tar.%s" % (tag, format)
- try:
- tf = TarFile.open(filename)
- for name in tf.getnames():
- if not (name.endswith(".sh") or
- name.endswith(".tab") or
- name == "leapseconds"):
- tf.extract(name, tmpdir)
- filepath = os.path.join(tmpdir, name)
- os.system("zic -d %s %s" % (zonedir, filepath))
- tf.close()
- target = os.path.join(moduledir, targetname)
- for entry in os.listdir(moduledir):
- if entry.startswith("zoneinfo") and ".tar." in entry:
- os.unlink(os.path.join(moduledir, entry))
- tf = TarFile.open(target, "w:%s" % format)
- for entry in os.listdir(zonedir):
- entrypath = os.path.join(zonedir, entry)
- tf.add(entrypath, entry)
- tf.close()
- finally:
- shutil.rmtree(tmpdir)
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/zoneinfo-2010g.tar.gz b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/zoneinfo-2010g.tar.gz
deleted file mode 100644
index 8bd4f964..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/zoneinfo/zoneinfo-2010g.tar.gz
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 0c1c47bb..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,1453 +0,0 @@
-Metadata-Version: 1.1
-Name: requests
-Version: 2.13.0
-Summary: Python HTTP for Humans.
-Home-page: http://python-requests.org
-Author: Kenneth Reitz
-Author-email: me@kennethreitz.com
-License: Apache 2.0
-Description: Requests: HTTP for Humans
- =========================
-
- .. image:: https://img.shields.io/pypi/v/requests.svg
- :target: https://pypi.python.org/pypi/requests
-
- .. image:: https://img.shields.io/pypi/l/requests.svg
- :target: https://pypi.python.org/pypi/requests
-
- .. image:: https://img.shields.io/pypi/wheel/requests.svg
- :target: https://pypi.python.org/pypi/requests
-
- .. image:: https://img.shields.io/pypi/pyversions/requests.svg
- :target: https://pypi.python.org/pypi/requests
-
- .. image:: https://travis-ci.org/kennethreitz/requests.svg?branch=master
- :target: https://travis-ci.org/kennethreitz/requests
-
- .. image:: https://codecov.io/github/kennethreitz/requests/coverage.svg?branch=master
- :target: https://codecov.io/github/kennethreitz/requests
- :alt: codecov.io
-
- .. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg
- :target: https://saythanks.io/to/kennethreitz
-
-
-
- Requests is the only *Non-GMO* HTTP library for Python, safe for human
- consumption.
-
- **Warning:** Recreational use of other HTTP libraries may result in dangerous side-effects,
- including: security vulnerabilities, verbose code, reinventing the wheel,
- constantly reading documentation, depression, headaches, or even death.
-
- Behold, the power of Requests:
-
- .. code-block:: python
-
- >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
- >>> r.status_code
- 200
- >>> r.headers['content-type']
- 'application/json; charset=utf8'
- >>> r.encoding
- 'utf-8'
- >>> r.text
- u'{"type":"User"...'
- >>> r.json()
- {u'disk_usage': 368627, u'private_gists': 484, ...}
-
- See `the similar code, sans Requests <https://gist.github.com/973705>`_.
-
- .. image:: http://docs.python-requests.org/en/master/_static/requests-sidebar.png
- :target: http://docs.python-requests.org/
-
-
- Requests allows you to send *organic, grass-fed* HTTP/1.1 requests, without the
- need for manual labor. There's no need to manually add query strings to your
- URLs, or to form-encode your POST data. Keep-alive and HTTP connection pooling
- are 100% automatic, powered by `urllib3 <https://github.com/shazow/urllib3>`_,
- which is embedded within Requests.
-
- Besides, all the cool kids are doing it. Requests is one of the most
- downloaded Python packages of all time, pulling in over 7,000,000 downloads
- every month. You don't want to be left out!
-
- Feature Support
- ---------------
-
- Requests is ready for today's web.
-
- - International Domains and URLs
- - Keep-Alive & Connection Pooling
- - Sessions with Cookie Persistence
- - Browser-style SSL Verification
- - Basic/Digest Authentication
- - Elegant Key/Value Cookies
- - Automatic Decompression
- - Automatic Content Decoding
- - Unicode Response Bodies
- - Multipart File Uploads
- - HTTP(S) Proxy Support
- - Connection Timeouts
- - Streaming Downloads
- - ``.netrc`` Support
- - Chunked Requests
- - Thread-safety
-
- Requests officially supports Python 2.6–2.7 & 3.3–3.7, and runs great on PyPy.
-
- Installation
- ------------
-
- To install Requests, simply:
-
- .. code-block:: bash
-
- $ pip install requests
- ✨ðŸ°âœ¨
-
- Satisfaction, guaranteed.
-
- Documentation
- -------------
-
- Fantastic documentation is available at http://docs.python-requests.org/, for a limited time only.
-
-
- How to Contribute
- -----------------
-
- #. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug. There is a `Contributor Friendly`_ tag for issues that should be ideal for people who are not very familiar with the codebase yet.
- #. Fork `the repository`_ on GitHub to start making your changes to the **master** branch (or branch off of it).
- #. Write a test which shows that the bug was fixed or that the feature works as expected.
- #. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to AUTHORS_.
-
- .. _`the repository`: http://github.com/kennethreitz/requests
- .. _AUTHORS: https://github.com/kennethreitz/requests/blob/master/AUTHORS.rst
- .. _Contributor Friendly: https://github.com/kennethreitz/requests/issues?direction=desc&labels=Contributor+Friendly&page=1&sort=updated&state=open
-
-
- .. :changelog:
-
- Release History
- ---------------
-
- 2.13.0 (2017-01-24)
- +++++++++++++++++++
-
- **Features**
-
- - Only load the ``idna`` library when we've determined we need it. This will
- save some memory for users.
-
- **Miscellaneous**
-
- - Updated bundled urllib3 to 1.20.
- - Updated bundled idna to 2.2.
-
- 2.12.5 (2017-01-18)
- +++++++++++++++++++
-
- **Bugfixes**
-
- - Fixed an issue with JSON encoding detection, specifically detecting
- big-endian UTF-32 with BOM.
-
- 2.12.4 (2016-12-14)
- +++++++++++++++++++
-
- **Bugfixes**
-
- - Fixed regression from 2.12.2 where non-string types were rejected in the
- basic auth parameters. While support for this behaviour has been readded,
- the behaviour is deprecated and will be removed in the future.
-
- 2.12.3 (2016-12-01)
- +++++++++++++++++++
-
- **Bugfixes**
-
- - Fixed regression from v2.12.1 for URLs with schemes that begin with "http".
- These URLs have historically been processed as though they were HTTP-schemed
- URLs, and so have had parameters added. This was removed in v2.12.2 in an
- overzealous attempt to resolve problems with IDNA-encoding those URLs. This
- change was reverted: the other fixes for IDNA-encoding have been judged to
- be sufficient to return to the behaviour Requests had before v2.12.0.
-
- 2.12.2 (2016-11-30)
- +++++++++++++++++++
-
- **Bugfixes**
-
- - Fixed several issues with IDNA-encoding URLs that are technically invalid but
- which are widely accepted. Requests will now attempt to IDNA-encode a URL if
- it can but, if it fails, and the host contains only ASCII characters, it will
- be passed through optimistically. This will allow users to opt-in to using
- IDNA2003 themselves if they want to, and will also allow technically invalid
- but still common hostnames.
- - Fixed an issue where URLs with leading whitespace would raise
- ``InvalidSchema`` errors.
- - Fixed an issue where some URLs without the HTTP or HTTPS schemes would still
- have HTTP URL preparation applied to them.
- - Fixed an issue where Unicode strings could not be used in basic auth.
- - Fixed an issue encountered by some Requests plugins where constructing a
- Response object would cause ``Response.content`` to raise an
- ``AttributeError``.
-
- 2.12.1 (2016-11-16)
- +++++++++++++++++++
-
- **Bugfixes**
-
- - Updated setuptools 'security' extra for the new PyOpenSSL backend in urllib3.
-
- **Miscellaneous**
-
- - Updated bundled urllib3 to 1.19.1.
-
- 2.12.0 (2016-11-15)
- +++++++++++++++++++
-
- **Improvements**
-
- - Updated support for internationalized domain names from IDNA2003 to IDNA2008.
- This updated support is required for several forms of IDNs and is mandatory
- for .de domains.
- - Much improved heuristics for guessing content lengths: Requests will no
- longer read an entire ``StringIO`` into memory.
- - Much improved logic for recalculating ``Content-Length`` headers for
- ``PreparedRequest`` objects.
- - Improved tolerance for file-like objects that have no ``tell`` method but
- do have a ``seek`` method.
- - Anything that is a subclass of ``Mapping`` is now treated like a dictionary
- by the ``data=`` keyword argument.
- - Requests now tolerates empty passwords in proxy credentials, rather than
- stripping the credentials.
- - If a request is made with a file-like object as the body and that request is
- redirected with a 307 or 308 status code, Requests will now attempt to
- rewind the body object so it can be replayed.
-
- **Bugfixes**
-
- - When calling ``response.close``, the call to ``close`` will be propagated
- through to non-urllib3 backends.
- - Fixed issue where the ``ALL_PROXY`` environment variable would be preferred
- over scheme-specific variables like ``HTTP_PROXY``.
- - Fixed issue where non-UTF8 reason phrases got severely mangled by falling
- back to decoding using ISO 8859-1 instead.
- - Fixed a bug where Requests would not correctly correlate cookies set when
- using custom Host headers if those Host headers did not use the native
- string type for the platform.
-
- **Miscellaneous**
-
- - Updated bundled urllib3 to 1.19.
- - Updated bundled certifi certs to 2016.09.26.
-
- 2.11.1 (2016-08-17)
- +++++++++++++++++++
-
- **Bugfixes**
-
- - Fixed a bug when using ``iter_content`` with ``decode_unicode=True`` for
- streamed bodies would raise ``AttributeError``. This bug was introduced in
- 2.11.
- - Strip Content-Type and Transfer-Encoding headers from the header block when
- following a redirect that transforms the verb from POST/PUT to GET.
-
- 2.11.0 (2016-08-08)
- +++++++++++++++++++
-
- **Improvements**
-
- - Added support for the ``ALL_PROXY`` environment variable.
- - Reject header values that contain leading whitespace or newline characters to
- reduce risk of header smuggling.
-
- **Bugfixes**
-
- - Fixed occasional ``TypeError`` when attempting to decode a JSON response that
- occurred in an error case. Now correctly returns a ``ValueError``.
- - Requests would incorrectly ignore a non-CIDR IP address in the ``NO_PROXY``
- environment variables: Requests now treats it as a specific IP.
- - Fixed a bug when sending JSON data that could cause us to encounter obscure
- OpenSSL errors in certain network conditions (yes, really).
- - Added type checks to ensure that ``iter_content`` only accepts integers and
- ``None`` for chunk sizes.
- - Fixed issue where responses whose body had not been fully consumed would have
- the underlying connection closed but not returned to the connection pool,
- which could cause Requests to hang in situations where the ``HTTPAdapter``
- had been configured to use a blocking connection pool.
-
- **Miscellaneous**
-
- - Updated bundled urllib3 to 1.16.
- - Some previous releases accidentally accepted non-strings as acceptable header values. This release does not.
-
- 2.10.0 (2016-04-29)
- +++++++++++++++++++
-
- **New Features**
-
- - SOCKS Proxy Support! (requires PySocks; ``$ pip install requests[socks]``)
-
- **Miscellaneous**
-
- - Updated bundled urllib3 to 1.15.1.
-
- 2.9.2 (2016-04-29)
- ++++++++++++++++++
-
- **Improvements**
-
- - Change built-in CaseInsensitiveDict (used for headers) to use OrderedDict
- as its underlying datastore.
-
- **Bugfixes**
-
- - Don't use redirect_cache if allow_redirects=False
- - When passed objects that throw exceptions from ``tell()``, send them via
- chunked transfer encoding instead of failing.
- - Raise a ProxyError for proxy related connection issues.
-
- 2.9.1 (2015-12-21)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Resolve regression introduced in 2.9.0 that made it impossible to send binary
- strings as bodies in Python 3.
- - Fixed errors when calculating cookie expiration dates in certain locales.
-
- **Miscellaneous**
-
- - Updated bundled urllib3 to 1.13.1.
-
- 2.9.0 (2015-12-15)
- ++++++++++++++++++
-
- **Minor Improvements** (Backwards compatible)
-
- - The ``verify`` keyword argument now supports being passed a path to a
- directory of CA certificates, not just a single-file bundle.
- - Warnings are now emitted when sending files opened in text mode.
- - Added the 511 Network Authentication Required status code to the status code
- registry.
-
- **Bugfixes**
-
- - For file-like objects that are not seeked to the very beginning, we now
- send the content length for the number of bytes we will actually read, rather
- than the total size of the file, allowing partial file uploads.
- - When uploading file-like objects, if they are empty or have no obvious
- content length we set ``Transfer-Encoding: chunked`` rather than
- ``Content-Length: 0``.
- - We correctly receive the response in buffered mode when uploading chunked
- bodies.
- - We now handle being passed a query string as a bytestring on Python 3, by
- decoding it as UTF-8.
- - Sessions are now closed in all cases (exceptional and not) when using the
- functional API rather than leaking and waiting for the garbage collector to
- clean them up.
- - Correctly handle digest auth headers with a malformed ``qop`` directive that
- contains no token, by treating it the same as if no ``qop`` directive was
- provided at all.
- - Minor performance improvements when removing specific cookies by name.
-
- **Miscellaneous**
-
- - Updated urllib3 to 1.13.
-
- 2.8.1 (2015-10-13)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Update certificate bundle to match ``certifi`` 2015.9.6.2's weak certificate
- bundle.
- - Fix a bug in 2.8.0 where requests would raise ``ConnectTimeout`` instead of
- ``ConnectionError``
- - When using the PreparedRequest flow, requests will now correctly respect the
- ``json`` parameter. Broken in 2.8.0.
- - When using the PreparedRequest flow, requests will now correctly handle a
- Unicode-string method name on Python 2. Broken in 2.8.0.
-
- 2.8.0 (2015-10-05)
- ++++++++++++++++++
-
- **Minor Improvements** (Backwards Compatible)
-
- - Requests now supports per-host proxies. This allows the ``proxies``
- dictionary to have entries of the form
- ``{'<scheme>://<hostname>': '<proxy>'}``. Host-specific proxies will be used
- in preference to the previously-supported scheme-specific ones, but the
- previous syntax will continue to work.
- - ``Response.raise_for_status`` now prints the URL that failed as part of the
- exception message.
- - ``requests.utils.get_netrc_auth`` now takes an ``raise_errors`` kwarg,
- defaulting to ``False``. When ``True``, errors parsing ``.netrc`` files cause
- exceptions to be thrown.
- - Change to bundled projects import logic to make it easier to unbundle
- requests downstream.
- - Changed the default User-Agent string to avoid leaking data on Linux: now
- contains only the requests version.
-
- **Bugfixes**
-
- - The ``json`` parameter to ``post()`` and friends will now only be used if
- neither ``data`` nor ``files`` are present, consistent with the
- documentation.
- - We now ignore empty fields in the ``NO_PROXY`` environment variable.
- - Fixed problem where ``httplib.BadStatusLine`` would get raised if combining
- ``stream=True`` with ``contextlib.closing``.
- - Prevented bugs where we would attempt to return the same connection back to
- the connection pool twice when sending a Chunked body.
- - Miscellaneous minor internal changes.
- - Digest Auth support is now thread safe.
-
- **Updates**
-
- - Updated urllib3 to 1.12.
-
- 2.7.0 (2015-05-03)
- ++++++++++++++++++
-
- This is the first release that follows our new release process. For more, see
- `our documentation
- <http://docs.python-requests.org/en/latest/community/release-process/>`_.
-
- **Bugfixes**
-
- - Updated urllib3 to 1.10.4, resolving several bugs involving chunked transfer
- encoding and response framing.
-
- 2.6.2 (2015-04-23)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Fix regression where compressed data that was sent as chunked data was not
- properly decompressed. (#2561)
-
- 2.6.1 (2015-04-22)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Remove VendorAlias import machinery introduced in v2.5.2.
-
- - Simplify the PreparedRequest.prepare API: We no longer require the user to
- pass an empty list to the hooks keyword argument. (c.f. #2552)
-
- - Resolve redirects now receives and forwards all of the original arguments to
- the adapter. (#2503)
-
- - Handle UnicodeDecodeErrors when trying to deal with a unicode URL that
- cannot be encoded in ASCII. (#2540)
-
- - Populate the parsed path of the URI field when performing Digest
- Authentication. (#2426)
-
- - Copy a PreparedRequest's CookieJar more reliably when it is not an instance
- of RequestsCookieJar. (#2527)
-
- 2.6.0 (2015-03-14)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - CVE-2015-2296: Fix handling of cookies on redirect. Previously a cookie
- without a host value set would use the hostname for the redirected URL
- exposing requests users to session fixation attacks and potentially cookie
- stealing. This was disclosed privately by Matthew Daley of
- `BugFuzz <https://bugfuzz.com>`_. This affects all versions of requests from
- v2.1.0 to v2.5.3 (inclusive on both ends).
-
- - Fix error when requests is an ``install_requires`` dependency and ``python
- setup.py test`` is run. (#2462)
-
- - Fix error when urllib3 is unbundled and requests continues to use the
- vendored import location.
-
- - Include fixes to ``urllib3``'s header handling.
-
- - Requests' handling of unvendored dependencies is now more restrictive.
-
- **Features and Improvements**
-
- - Support bytearrays when passed as parameters in the ``files`` argument.
- (#2468)
-
- - Avoid data duplication when creating a request with ``str``, ``bytes``, or
- ``bytearray`` input to the ``files`` argument.
-
- 2.5.3 (2015-02-24)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Revert changes to our vendored certificate bundle. For more context see
- (#2455, #2456, and http://bugs.python.org/issue23476)
-
- 2.5.2 (2015-02-23)
- ++++++++++++++++++
-
- **Features and Improvements**
-
- - Add sha256 fingerprint support. (`shazow/urllib3#540`_)
-
- - Improve the performance of headers. (`shazow/urllib3#544`_)
-
- **Bugfixes**
-
- - Copy pip's import machinery. When downstream redistributors remove
- requests.packages.urllib3 the import machinery will continue to let those
- same symbols work. Example usage in requests' documentation and 3rd-party
- libraries relying on the vendored copies of urllib3 will work without having
- to fallback to the system urllib3.
-
- - Attempt to quote parts of the URL on redirect if unquoting and then quoting
- fails. (#2356)
-
- - Fix filename type check for multipart form-data uploads. (#2411)
-
- - Properly handle the case where a server issuing digest authentication
- challenges provides both auth and auth-int qop-values. (#2408)
-
- - Fix a socket leak. (`shazow/urllib3#549`_)
-
- - Fix multiple ``Set-Cookie`` headers properly. (`shazow/urllib3#534`_)
-
- - Disable the built-in hostname verification. (`shazow/urllib3#526`_)
-
- - Fix the behaviour of decoding an exhausted stream. (`shazow/urllib3#535`_)
-
- **Security**
-
- - Pulled in an updated ``cacert.pem``.
-
- - Drop RC4 from the default cipher list. (`shazow/urllib3#551`_)
-
- .. _shazow/urllib3#551: https://github.com/shazow/urllib3/pull/551
- .. _shazow/urllib3#549: https://github.com/shazow/urllib3/pull/549
- .. _shazow/urllib3#544: https://github.com/shazow/urllib3/pull/544
- .. _shazow/urllib3#540: https://github.com/shazow/urllib3/pull/540
- .. _shazow/urllib3#535: https://github.com/shazow/urllib3/pull/535
- .. _shazow/urllib3#534: https://github.com/shazow/urllib3/pull/534
- .. _shazow/urllib3#526: https://github.com/shazow/urllib3/pull/526
-
- 2.5.1 (2014-12-23)
- ++++++++++++++++++
-
- **Behavioural Changes**
-
- - Only catch HTTPErrors in raise_for_status (#2382)
-
- **Bugfixes**
-
- - Handle LocationParseError from urllib3 (#2344)
- - Handle file-like object filenames that are not strings (#2379)
- - Unbreak HTTPDigestAuth handler. Allow new nonces to be negotiated (#2389)
-
- 2.5.0 (2014-12-01)
- ++++++++++++++++++
-
- **Improvements**
-
- - Allow usage of urllib3's Retry object with HTTPAdapters (#2216)
- - The ``iter_lines`` method on a response now accepts a delimiter with which
- to split the content (#2295)
-
- **Behavioural Changes**
-
- - Add deprecation warnings to functions in requests.utils that will be removed
- in 3.0 (#2309)
- - Sessions used by the functional API are always closed (#2326)
- - Restrict requests to HTTP/1.1 and HTTP/1.0 (stop accepting HTTP/0.9) (#2323)
-
- **Bugfixes**
-
- - Only parse the URL once (#2353)
- - Allow Content-Length header to always be overridden (#2332)
- - Properly handle files in HTTPDigestAuth (#2333)
- - Cap redirect_cache size to prevent memory abuse (#2299)
- - Fix HTTPDigestAuth handling of redirects after authenticating successfully
- (#2253)
- - Fix crash with custom method parameter to Session.request (#2317)
- - Fix how Link headers are parsed using the regular expression library (#2271)
-
- **Documentation**
-
- - Add more references for interlinking (#2348)
- - Update CSS for theme (#2290)
- - Update width of buttons and sidebar (#2289)
- - Replace references of Gittip with Gratipay (#2282)
- - Add link to changelog in sidebar (#2273)
-
- 2.4.3 (2014-10-06)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Unicode URL improvements for Python 2.
- - Re-order JSON param for backwards compat.
- - Automatically defrag authentication schemes from host/pass URIs. (`#2249 <https://github.com/kennethreitz/requests/issues/2249>`_)
-
-
- 2.4.2 (2014-10-05)
- ++++++++++++++++++
-
- **Improvements**
-
- - FINALLY! Add json parameter for uploads! (`#2258 <https://github.com/kennethreitz/requests/pull/2258>`_)
- - Support for bytestring URLs on Python 3.x (`#2238 <https://github.com/kennethreitz/requests/pull/2238>`_)
-
- **Bugfixes**
-
- - Avoid getting stuck in a loop (`#2244 <https://github.com/kennethreitz/requests/pull/2244>`_)
- - Multiple calls to iter* fail with unhelpful error. (`#2240 <https://github.com/kennethreitz/requests/issues/2240>`_, `#2241 <https://github.com/kennethreitz/requests/issues/2241>`_)
-
- **Documentation**
-
- - Correct redirection introduction (`#2245 <https://github.com/kennethreitz/requests/pull/2245/>`_)
- - Added example of how to send multiple files in one request. (`#2227 <https://github.com/kennethreitz/requests/pull/2227/>`_)
- - Clarify how to pass a custom set of CAs (`#2248 <https://github.com/kennethreitz/requests/pull/2248/>`_)
-
-
-
- 2.4.1 (2014-09-09)
- ++++++++++++++++++
-
- - Now has a "security" package extras set, ``$ pip install requests[security]``
- - Requests will now use Certifi if it is available.
- - Capture and re-raise urllib3 ProtocolError
- - Bugfix for responses that attempt to redirect to themselves forever (wtf?).
-
-
- 2.4.0 (2014-08-29)
- ++++++++++++++++++
-
- **Behavioral Changes**
-
- - ``Connection: keep-alive`` header is now sent automatically.
-
- **Improvements**
-
- - Support for connect timeouts! Timeout now accepts a tuple (connect, read) which is used to set individual connect and read timeouts.
- - Allow copying of PreparedRequests without headers/cookies.
- - Updated bundled urllib3 version.
- - Refactored settings loading from environment -- new `Session.merge_environment_settings`.
- - Handle socket errors in iter_content.
-
-
- 2.3.0 (2014-05-16)
- ++++++++++++++++++
-
- **API Changes**
-
- - New ``Response`` property ``is_redirect``, which is true when the
- library could have processed this response as a redirection (whether
- or not it actually did).
- - The ``timeout`` parameter now affects requests with both ``stream=True`` and
- ``stream=False`` equally.
- - The change in v2.0.0 to mandate explicit proxy schemes has been reverted.
- Proxy schemes now default to ``http://``.
- - The ``CaseInsensitiveDict`` used for HTTP headers now behaves like a normal
- dictionary when references as string or viewed in the interpreter.
-
- **Bugfixes**
-
- - No longer expose Authorization or Proxy-Authorization headers on redirect.
- Fix CVE-2014-1829 and CVE-2014-1830 respectively.
- - Authorization is re-evaluated each redirect.
- - On redirect, pass url as native strings.
- - Fall-back to autodetected encoding for JSON when Unicode detection fails.
- - Headers set to ``None`` on the ``Session`` are now correctly not sent.
- - Correctly honor ``decode_unicode`` even if it wasn't used earlier in the same
- response.
- - Stop advertising ``compress`` as a supported Content-Encoding.
- - The ``Response.history`` parameter is now always a list.
- - Many, many ``urllib3`` bugfixes.
-
- 2.2.1 (2014-01-23)
- ++++++++++++++++++
-
- **Bugfixes**
-
- - Fixes incorrect parsing of proxy credentials that contain a literal or encoded '#' character.
- - Assorted urllib3 fixes.
-
- 2.2.0 (2014-01-09)
- ++++++++++++++++++
-
- **API Changes**
-
- - New exception: ``ContentDecodingError``. Raised instead of ``urllib3``
- ``DecodeError`` exceptions.
-
- **Bugfixes**
-
- - Avoid many many exceptions from the buggy implementation of ``proxy_bypass`` on OS X in Python 2.6.
- - Avoid crashing when attempting to get authentication credentials from ~/.netrc when running as a user without a home directory.
- - Use the correct pool size for pools of connections to proxies.
- - Fix iteration of ``CookieJar`` objects.
- - Ensure that cookies are persisted over redirect.
- - Switch back to using chardet, since it has merged with charade.
-
- 2.1.0 (2013-12-05)
- ++++++++++++++++++
-
- - Updated CA Bundle, of course.
- - Cookies set on individual Requests through a ``Session`` (e.g. via ``Session.get()``) are no longer persisted to the ``Session``.
- - Clean up connections when we hit problems during chunked upload, rather than leaking them.
- - Return connections to the pool when a chunked upload is successful, rather than leaking it.
- - Match the HTTPbis recommendation for HTTP 301 redirects.
- - Prevent hanging when using streaming uploads and Digest Auth when a 401 is received.
- - Values of headers set by Requests are now always the native string type.
- - Fix previously broken SNI support.
- - Fix accessing HTTP proxies using proxy authentication.
- - Unencode HTTP Basic usernames and passwords extracted from URLs.
- - Support for IP address ranges for no_proxy environment variable
- - Parse headers correctly when users override the default ``Host:`` header.
- - Avoid munging the URL in case of case-sensitive servers.
- - Looser URL handling for non-HTTP/HTTPS urls.
- - Accept unicode methods in Python 2.6 and 2.7.
- - More resilient cookie handling.
- - Make ``Response`` objects pickleable.
- - Actually added MD5-sess to Digest Auth instead of pretending to like last time.
- - Updated internal urllib3.
- - Fixed @Lukasa's lack of taste.
-
- 2.0.1 (2013-10-24)
- ++++++++++++++++++
-
- - Updated included CA Bundle with new mistrusts and automated process for the future
- - Added MD5-sess to Digest Auth
- - Accept per-file headers in multipart file POST messages.
- - Fixed: Don't send the full URL on CONNECT messages.
- - Fixed: Correctly lowercase a redirect scheme.
- - Fixed: Cookies not persisted when set via functional API.
- - Fixed: Translate urllib3 ProxyError into a requests ProxyError derived from ConnectionError.
- - Updated internal urllib3 and chardet.
-
- 2.0.0 (2013-09-24)
- ++++++++++++++++++
-
- **API Changes:**
-
- - Keys in the Headers dictionary are now native strings on all Python versions,
- i.e. bytestrings on Python 2, unicode on Python 3.
- - Proxy URLs now *must* have an explicit scheme. A ``MissingSchema`` exception
- will be raised if they don't.
- - Timeouts now apply to read time if ``Stream=False``.
- - ``RequestException`` is now a subclass of ``IOError``, not ``RuntimeError``.
- - Added new method to ``PreparedRequest`` objects: ``PreparedRequest.copy()``.
- - Added new method to ``Session`` objects: ``Session.update_request()``. This
- method updates a ``Request`` object with the data (e.g. cookies) stored on
- the ``Session``.
- - Added new method to ``Session`` objects: ``Session.prepare_request()``. This
- method updates and prepares a ``Request`` object, and returns the
- corresponding ``PreparedRequest`` object.
- - Added new method to ``HTTPAdapter`` objects: ``HTTPAdapter.proxy_headers()``.
- This should not be called directly, but improves the subclass interface.
- - ``httplib.IncompleteRead`` exceptions caused by incorrect chunked encoding
- will now raise a Requests ``ChunkedEncodingError`` instead.
- - Invalid percent-escape sequences now cause a Requests ``InvalidURL``
- exception to be raised.
- - HTTP 208 no longer uses reason phrase ``"im_used"``. Correctly uses
- ``"already_reported"``.
- - HTTP 226 reason added (``"im_used"``).
-
- **Bugfixes:**
-
- - Vastly improved proxy support, including the CONNECT verb. Special thanks to
- the many contributors who worked towards this improvement.
- - Cookies are now properly managed when 401 authentication responses are
- received.
- - Chunked encoding fixes.
- - Support for mixed case schemes.
- - Better handling of streaming downloads.
- - Retrieve environment proxies from more locations.
- - Minor cookies fixes.
- - Improved redirect behaviour.
- - Improved streaming behaviour, particularly for compressed data.
- - Miscellaneous small Python 3 text encoding bugs.
- - ``.netrc`` no longer overrides explicit auth.
- - Cookies set by hooks are now correctly persisted on Sessions.
- - Fix problem with cookies that specify port numbers in their host field.
- - ``BytesIO`` can be used to perform streaming uploads.
- - More generous parsing of the ``no_proxy`` environment variable.
- - Non-string objects can be passed in data values alongside files.
-
- 1.2.3 (2013-05-25)
- ++++++++++++++++++
-
- - Simple packaging fix
-
-
- 1.2.2 (2013-05-23)
- ++++++++++++++++++
-
- - Simple packaging fix
-
-
- 1.2.1 (2013-05-20)
- ++++++++++++++++++
-
- - 301 and 302 redirects now change the verb to GET for all verbs, not just
- POST, improving browser compatibility.
- - Python 3.3.2 compatibility
- - Always percent-encode location headers
- - Fix connection adapter matching to be most-specific first
- - new argument to the default connection adapter for passing a block argument
- - prevent a KeyError when there's no link headers
-
- 1.2.0 (2013-03-31)
- ++++++++++++++++++
-
- - Fixed cookies on sessions and on requests
- - Significantly change how hooks are dispatched - hooks now receive all the
- arguments specified by the user when making a request so hooks can make a
- secondary request with the same parameters. This is especially necessary for
- authentication handler authors
- - certifi support was removed
- - Fixed bug where using OAuth 1 with body ``signature_type`` sent no data
- - Major proxy work thanks to @Lukasa including parsing of proxy authentication
- from the proxy url
- - Fix DigestAuth handling too many 401s
- - Update vendored urllib3 to include SSL bug fixes
- - Allow keyword arguments to be passed to ``json.loads()`` via the
- ``Response.json()`` method
- - Don't send ``Content-Length`` header by default on ``GET`` or ``HEAD``
- requests
- - Add ``elapsed`` attribute to ``Response`` objects to time how long a request
- took.
- - Fix ``RequestsCookieJar``
- - Sessions and Adapters are now picklable, i.e., can be used with the
- multiprocessing library
- - Update charade to version 1.0.3
-
- The change in how hooks are dispatched will likely cause a great deal of
- issues.
-
- 1.1.0 (2013-01-10)
- ++++++++++++++++++
-
- - CHUNKED REQUESTS
- - Support for iterable response bodies
- - Assume servers persist redirect params
- - Allow explicit content types to be specified for file data
- - Make merge_kwargs case-insensitive when looking up keys
-
- 1.0.3 (2012-12-18)
- ++++++++++++++++++
-
- - Fix file upload encoding bug
- - Fix cookie behavior
-
- 1.0.2 (2012-12-17)
- ++++++++++++++++++
-
- - Proxy fix for HTTPAdapter.
-
- 1.0.1 (2012-12-17)
- ++++++++++++++++++
-
- - Cert verification exception bug.
- - Proxy fix for HTTPAdapter.
-
- 1.0.0 (2012-12-17)
- ++++++++++++++++++
-
- - Massive Refactor and Simplification
- - Switch to Apache 2.0 license
- - Swappable Connection Adapters
- - Mountable Connection Adapters
- - Mutable ProcessedRequest chain
- - /s/prefetch/stream
- - Removal of all configuration
- - Standard library logging
- - Make Response.json() callable, not property.
- - Usage of new charade project, which provides python 2 and 3 simultaneous chardet.
- - Removal of all hooks except 'response'
- - Removal of all authentication helpers (OAuth, Kerberos)
-
- This is not a backwards compatible change.
-
- 0.14.2 (2012-10-27)
- +++++++++++++++++++
-
- - Improved mime-compatible JSON handling
- - Proxy fixes
- - Path hack fixes
- - Case-Insensitive Content-Encoding headers
- - Support for CJK parameters in form posts
-
-
- 0.14.1 (2012-10-01)
- +++++++++++++++++++
-
- - Python 3.3 Compatibility
- - Simply default accept-encoding
- - Bugfixes
-
-
- 0.14.0 (2012-09-02)
- ++++++++++++++++++++
-
- - No more iter_content errors if already downloaded.
-
- 0.13.9 (2012-08-25)
- +++++++++++++++++++
-
- - Fix for OAuth + POSTs
- - Remove exception eating from dispatch_hook
- - General bugfixes
-
- 0.13.8 (2012-08-21)
- +++++++++++++++++++
-
- - Incredible Link header support :)
-
- 0.13.7 (2012-08-19)
- +++++++++++++++++++
-
- - Support for (key, value) lists everywhere.
- - Digest Authentication improvements.
- - Ensure proxy exclusions work properly.
- - Clearer UnicodeError exceptions.
- - Automatic casting of URLs to strings (fURL and such)
- - Bugfixes.
-
- 0.13.6 (2012-08-06)
- +++++++++++++++++++
-
- - Long awaited fix for hanging connections!
-
- 0.13.5 (2012-07-27)
- +++++++++++++++++++
-
- - Packaging fix
-
- 0.13.4 (2012-07-27)
- +++++++++++++++++++
-
- - GSSAPI/Kerberos authentication!
- - App Engine 2.7 Fixes!
- - Fix leaking connections (from urllib3 update)
- - OAuthlib path hack fix
- - OAuthlib URL parameters fix.
-
- 0.13.3 (2012-07-12)
- +++++++++++++++++++
-
- - Use simplejson if available.
- - Do not hide SSLErrors behind Timeouts.
- - Fixed param handling with urls containing fragments.
- - Significantly improved information in User Agent.
- - client certificates are ignored when verify=False
-
- 0.13.2 (2012-06-28)
- +++++++++++++++++++
-
- - Zero dependencies (once again)!
- - New: Response.reason
- - Sign querystring parameters in OAuth 1.0
- - Client certificates no longer ignored when verify=False
- - Add openSUSE certificate support
-
- 0.13.1 (2012-06-07)
- +++++++++++++++++++
-
- - Allow passing a file or file-like object as data.
- - Allow hooks to return responses that indicate errors.
- - Fix Response.text and Response.json for body-less responses.
-
- 0.13.0 (2012-05-29)
- +++++++++++++++++++
-
- - Removal of Requests.async in favor of `grequests <https://github.com/kennethreitz/grequests>`_
- - Allow disabling of cookie persistence.
- - New implementation of safe_mode
- - cookies.get now supports default argument
- - Session cookies not saved when Session.request is called with return_response=False
- - Env: no_proxy support.
- - RequestsCookieJar improvements.
- - Various bug fixes.
-
- 0.12.1 (2012-05-08)
- +++++++++++++++++++
-
- - New ``Response.json`` property.
- - Ability to add string file uploads.
- - Fix out-of-range issue with iter_lines.
- - Fix iter_content default size.
- - Fix POST redirects containing files.
-
- 0.12.0 (2012-05-02)
- +++++++++++++++++++
-
- - EXPERIMENTAL OAUTH SUPPORT!
- - Proper CookieJar-backed cookies interface with awesome dict-like interface.
- - Speed fix for non-iterated content chunks.
- - Move ``pre_request`` to a more usable place.
- - New ``pre_send`` hook.
- - Lazily encode data, params, files.
- - Load system Certificate Bundle if ``certify`` isn't available.
- - Cleanups, fixes.
-
- 0.11.2 (2012-04-22)
- +++++++++++++++++++
-
- - Attempt to use the OS's certificate bundle if ``certifi`` isn't available.
- - Infinite digest auth redirect fix.
- - Multi-part file upload improvements.
- - Fix decoding of invalid %encodings in URLs.
- - If there is no content in a response don't throw an error the second time that content is attempted to be read.
- - Upload data on redirects.
-
- 0.11.1 (2012-03-30)
- +++++++++++++++++++
-
- * POST redirects now break RFC to do what browsers do: Follow up with a GET.
- * New ``strict_mode`` configuration to disable new redirect behavior.
-
-
- 0.11.0 (2012-03-14)
- +++++++++++++++++++
-
- * Private SSL Certificate support
- * Remove select.poll from Gevent monkeypatching
- * Remove redundant generator for chunked transfer encoding
- * Fix: Response.ok raises Timeout Exception in safe_mode
-
- 0.10.8 (2012-03-09)
- +++++++++++++++++++
-
- * Generate chunked ValueError fix
- * Proxy configuration by environment variables
- * Simplification of iter_lines.
- * New `trust_env` configuration for disabling system/environment hints.
- * Suppress cookie errors.
-
- 0.10.7 (2012-03-07)
- +++++++++++++++++++
-
- * `encode_uri` = False
-
- 0.10.6 (2012-02-25)
- +++++++++++++++++++
-
- * Allow '=' in cookies.
-
- 0.10.5 (2012-02-25)
- +++++++++++++++++++
-
- * Response body with 0 content-length fix.
- * New async.imap.
- * Don't fail on netrc.
-
-
- 0.10.4 (2012-02-20)
- +++++++++++++++++++
-
- * Honor netrc.
-
- 0.10.3 (2012-02-20)
- +++++++++++++++++++
-
- * HEAD requests don't follow redirects anymore.
- * raise_for_status() doesn't raise for 3xx anymore.
- * Make Session objects picklable.
- * ValueError for invalid schema URLs.
-
- 0.10.2 (2012-01-15)
- +++++++++++++++++++
-
- * Vastly improved URL quoting.
- * Additional allowed cookie key values.
- * Attempted fix for "Too many open files" Error
- * Replace unicode errors on first pass, no need for second pass.
- * Append '/' to bare-domain urls before query insertion.
- * Exceptions now inherit from RuntimeError.
- * Binary uploads + auth fix.
- * Bugfixes.
-
-
- 0.10.1 (2012-01-23)
- +++++++++++++++++++
-
- * PYTHON 3 SUPPORT!
- * Dropped 2.5 Support. (*Backwards Incompatible*)
-
- 0.10.0 (2012-01-21)
- +++++++++++++++++++
-
- * ``Response.content`` is now bytes-only. (*Backwards Incompatible*)
- * New ``Response.text`` is unicode-only.
- * If no ``Response.encoding`` is specified and ``chardet`` is available, ``Response.text`` will guess an encoding.
- * Default to ISO-8859-1 (Western) encoding for "text" subtypes.
- * Removal of `decode_unicode`. (*Backwards Incompatible*)
- * New multiple-hooks system.
- * New ``Response.register_hook`` for registering hooks within the pipeline.
- * ``Response.url`` is now Unicode.
-
- 0.9.3 (2012-01-18)
- ++++++++++++++++++
-
- * SSL verify=False bugfix (apparent on windows machines).
-
- 0.9.2 (2012-01-18)
- ++++++++++++++++++
-
- * Asynchronous async.send method.
- * Support for proper chunk streams with boundaries.
- * session argument for Session classes.
- * Print entire hook tracebacks, not just exception instance.
- * Fix response.iter_lines from pending next line.
- * Fix but in HTTP-digest auth w/ URI having query strings.
- * Fix in Event Hooks section.
- * Urllib3 update.
-
-
- 0.9.1 (2012-01-06)
- ++++++++++++++++++
-
- * danger_mode for automatic Response.raise_for_status()
- * Response.iter_lines refactor
-
- 0.9.0 (2011-12-28)
- ++++++++++++++++++
-
- * verify ssl is default.
-
-
- 0.8.9 (2011-12-28)
- ++++++++++++++++++
-
- * Packaging fix.
-
-
- 0.8.8 (2011-12-28)
- ++++++++++++++++++
-
- * SSL CERT VERIFICATION!
- * Release of Cerifi: Mozilla's cert list.
- * New 'verify' argument for SSL requests.
- * Urllib3 update.
-
- 0.8.7 (2011-12-24)
- ++++++++++++++++++
-
- * iter_lines last-line truncation fix
- * Force safe_mode for async requests
- * Handle safe_mode exceptions more consistently
- * Fix iteration on null responses in safe_mode
-
- 0.8.6 (2011-12-18)
- ++++++++++++++++++
-
- * Socket timeout fixes.
- * Proxy Authorization support.
-
- 0.8.5 (2011-12-14)
- ++++++++++++++++++
-
- * Response.iter_lines!
-
- 0.8.4 (2011-12-11)
- ++++++++++++++++++
-
- * Prefetch bugfix.
- * Added license to installed version.
-
- 0.8.3 (2011-11-27)
- ++++++++++++++++++
-
- * Converted auth system to use simpler callable objects.
- * New session parameter to API methods.
- * Display full URL while logging.
-
- 0.8.2 (2011-11-19)
- ++++++++++++++++++
-
- * New Unicode decoding system, based on over-ridable `Response.encoding`.
- * Proper URL slash-quote handling.
- * Cookies with ``[``, ``]``, and ``_`` allowed.
-
- 0.8.1 (2011-11-15)
- ++++++++++++++++++
-
- * URL Request path fix
- * Proxy fix.
- * Timeouts fix.
-
- 0.8.0 (2011-11-13)
- ++++++++++++++++++
-
- * Keep-alive support!
- * Complete removal of Urllib2
- * Complete removal of Poster
- * Complete removal of CookieJars
- * New ConnectionError raising
- * Safe_mode for error catching
- * prefetch parameter for request methods
- * OPTION method
- * Async pool size throttling
- * File uploads send real names
- * Vendored in urllib3
-
- 0.7.6 (2011-11-07)
- ++++++++++++++++++
-
- * Digest authentication bugfix (attach query data to path)
-
- 0.7.5 (2011-11-04)
- ++++++++++++++++++
-
- * Response.content = None if there was an invalid response.
- * Redirection auth handling.
-
- 0.7.4 (2011-10-26)
- ++++++++++++++++++
-
- * Session Hooks fix.
-
- 0.7.3 (2011-10-23)
- ++++++++++++++++++
-
- * Digest Auth fix.
-
-
- 0.7.2 (2011-10-23)
- ++++++++++++++++++
-
- * PATCH Fix.
-
-
- 0.7.1 (2011-10-23)
- ++++++++++++++++++
-
- * Move away from urllib2 authentication handling.
- * Fully Remove AuthManager, AuthObject, &c.
- * New tuple-based auth system with handler callbacks.
-
-
- 0.7.0 (2011-10-22)
- ++++++++++++++++++
-
- * Sessions are now the primary interface.
- * Deprecated InvalidMethodException.
- * PATCH fix.
- * New config system (no more global settings).
-
-
- 0.6.6 (2011-10-19)
- ++++++++++++++++++
-
- * Session parameter bugfix (params merging).
-
-
- 0.6.5 (2011-10-18)
- ++++++++++++++++++
-
- * Offline (fast) test suite.
- * Session dictionary argument merging.
-
-
- 0.6.4 (2011-10-13)
- ++++++++++++++++++
-
- * Automatic decoding of unicode, based on HTTP Headers.
- * New ``decode_unicode`` setting.
- * Removal of ``r.read/close`` methods.
- * New ``r.faw`` interface for advanced response usage.*
- * Automatic expansion of parameterized headers.
-
-
- 0.6.3 (2011-10-13)
- ++++++++++++++++++
-
- * Beautiful ``requests.async`` module, for making async requests w/ gevent.
-
-
- 0.6.2 (2011-10-09)
- ++++++++++++++++++
-
- * GET/HEAD obeys allow_redirects=False.
-
-
- 0.6.1 (2011-08-20)
- ++++++++++++++++++
-
- * Enhanced status codes experience ``\o/``
- * Set a maximum number of redirects (``settings.max_redirects``)
- * Full Unicode URL support
- * Support for protocol-less redirects.
- * Allow for arbitrary request types.
- * Bugfixes
-
-
- 0.6.0 (2011-08-17)
- ++++++++++++++++++
-
- * New callback hook system
- * New persistent sessions object and context manager
- * Transparent Dict-cookie handling
- * Status code reference object
- * Removed Response.cached
- * Added Response.request
- * All args are kwargs
- * Relative redirect support
- * HTTPError handling improvements
- * Improved https testing
- * Bugfixes
-
-
- 0.5.1 (2011-07-23)
- ++++++++++++++++++
-
- * International Domain Name Support!
- * Access headers without fetching entire body (``read()``)
- * Use lists as dicts for parameters
- * Add Forced Basic Authentication
- * Forced Basic is default authentication type
- * ``python-requests.org`` default User-Agent header
- * CaseInsensitiveDict lower-case caching
- * Response.history bugfix
-
-
- 0.5.0 (2011-06-21)
- ++++++++++++++++++
-
- * PATCH Support
- * Support for Proxies
- * HTTPBin Test Suite
- * Redirect Fixes
- * settings.verbose stream writing
- * Querystrings for all methods
- * URLErrors (Connection Refused, Timeout, Invalid URLs) are treated as explicitly raised
- ``r.requests.get('hwe://blah'); r.raise_for_status()``
-
-
- 0.4.1 (2011-05-22)
- ++++++++++++++++++
-
- * Improved Redirection Handling
- * New 'allow_redirects' param for following non-GET/HEAD Redirects
- * Settings module refactoring
-
-
- 0.4.0 (2011-05-15)
- ++++++++++++++++++
-
- * Response.history: list of redirected responses
- * Case-Insensitive Header Dictionaries!
- * Unicode URLs
-
-
- 0.3.4 (2011-05-14)
- ++++++++++++++++++
-
- * Urllib2 HTTPAuthentication Recursion fix (Basic/Digest)
- * Internal Refactor
- * Bytes data upload Bugfix
-
-
-
- 0.3.3 (2011-05-12)
- ++++++++++++++++++
-
- * Request timeouts
- * Unicode url-encoded data
- * Settings context manager and module
-
-
- 0.3.2 (2011-04-15)
- ++++++++++++++++++
-
- * Automatic Decompression of GZip Encoded Content
- * AutoAuth Support for Tupled HTTP Auth
-
-
- 0.3.1 (2011-04-01)
- ++++++++++++++++++
-
- * Cookie Changes
- * Response.read()
- * Poster fix
-
-
- 0.3.0 (2011-02-25)
- ++++++++++++++++++
-
- * Automatic Authentication API Change
- * Smarter Query URL Parameterization
- * Allow file uploads and POST data together
- * New Authentication Manager System
- - Simpler Basic HTTP System
- - Supports all build-in urllib2 Auths
- - Allows for custom Auth Handlers
-
-
- 0.2.4 (2011-02-19)
- ++++++++++++++++++
-
- * Python 2.5 Support
- * PyPy-c v1.4 Support
- * Auto-Authentication tests
- * Improved Request object constructor
-
- 0.2.3 (2011-02-15)
- ++++++++++++++++++
-
- * New HTTPHandling Methods
- - Response.__nonzero__ (false if bad HTTP Status)
- - Response.ok (True if expected HTTP Status)
- - Response.error (Logged HTTPError if bad HTTP Status)
- - Response.raise_for_status() (Raises stored HTTPError)
-
-
- 0.2.2 (2011-02-14)
- ++++++++++++++++++
-
- * Still handles request in the event of an HTTPError. (Issue #2)
- * Eventlet and Gevent Monkeypatch support.
- * Cookie Support (Issue #1)
-
-
- 0.2.1 (2011-02-14)
- ++++++++++++++++++
-
- * Added file attribute to POST and PUT requests for multipart-encode file uploads.
- * Added Request.url attribute for context and redirects
-
-
- 0.2.0 (2011-02-14)
- ++++++++++++++++++
-
- * Birth!
-
-
- 0.0.1 (2011-02-13)
- ++++++++++++++++++
-
- * Frustration
- * Conception
-
-
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Natural Language :: English
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index da330a35..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-HISTORY.rst
-LICENSE
-MANIFEST.in
-NOTICE
-README.rst
-setup.cfg
-setup.py
-requests/__init__.py
-requests/_internal_utils.py
-requests/adapters.py
-requests/api.py
-requests/auth.py
-requests/cacert.pem
-requests/certs.py
-requests/compat.py
-requests/cookies.py
-requests/exceptions.py
-requests/hooks.py
-requests/models.py
-requests/sessions.py
-requests/status_codes.py
-requests/structures.py
-requests/utils.py
-requests.egg-info/PKG-INFO
-requests.egg-info/SOURCES.txt
-requests.egg-info/dependency_links.txt
-requests.egg-info/not-zip-safe
-requests.egg-info/requires.txt
-requests.egg-info/top_level.txt
-requests/packages/__init__.py
-requests/packages/chardet/__init__.py
-requests/packages/chardet/big5freq.py
-requests/packages/chardet/big5prober.py
-requests/packages/chardet/chardetect.py
-requests/packages/chardet/chardistribution.py
-requests/packages/chardet/charsetgroupprober.py
-requests/packages/chardet/charsetprober.py
-requests/packages/chardet/codingstatemachine.py
-requests/packages/chardet/compat.py
-requests/packages/chardet/constants.py
-requests/packages/chardet/cp949prober.py
-requests/packages/chardet/escprober.py
-requests/packages/chardet/escsm.py
-requests/packages/chardet/eucjpprober.py
-requests/packages/chardet/euckrfreq.py
-requests/packages/chardet/euckrprober.py
-requests/packages/chardet/euctwfreq.py
-requests/packages/chardet/euctwprober.py
-requests/packages/chardet/gb2312freq.py
-requests/packages/chardet/gb2312prober.py
-requests/packages/chardet/hebrewprober.py
-requests/packages/chardet/jisfreq.py
-requests/packages/chardet/jpcntx.py
-requests/packages/chardet/langbulgarianmodel.py
-requests/packages/chardet/langcyrillicmodel.py
-requests/packages/chardet/langgreekmodel.py
-requests/packages/chardet/langhebrewmodel.py
-requests/packages/chardet/langhungarianmodel.py
-requests/packages/chardet/langthaimodel.py
-requests/packages/chardet/latin1prober.py
-requests/packages/chardet/mbcharsetprober.py
-requests/packages/chardet/mbcsgroupprober.py
-requests/packages/chardet/mbcssm.py
-requests/packages/chardet/sbcharsetprober.py
-requests/packages/chardet/sbcsgroupprober.py
-requests/packages/chardet/sjisprober.py
-requests/packages/chardet/universaldetector.py
-requests/packages/chardet/utf8prober.py
-requests/packages/idna/__init__.py
-requests/packages/idna/codec.py
-requests/packages/idna/compat.py
-requests/packages/idna/core.py
-requests/packages/idna/idnadata.py
-requests/packages/idna/intranges.py
-requests/packages/idna/uts46data.py
-requests/packages/urllib3/__init__.py
-requests/packages/urllib3/_collections.py
-requests/packages/urllib3/connection.py
-requests/packages/urllib3/connectionpool.py
-requests/packages/urllib3/exceptions.py
-requests/packages/urllib3/fields.py
-requests/packages/urllib3/filepost.py
-requests/packages/urllib3/poolmanager.py
-requests/packages/urllib3/request.py
-requests/packages/urllib3/response.py
-requests/packages/urllib3/contrib/__init__.py
-requests/packages/urllib3/contrib/appengine.py
-requests/packages/urllib3/contrib/ntlmpool.py
-requests/packages/urllib3/contrib/pyopenssl.py
-requests/packages/urllib3/contrib/socks.py
-requests/packages/urllib3/packages/__init__.py
-requests/packages/urllib3/packages/ordered_dict.py
-requests/packages/urllib3/packages/six.py
-requests/packages/urllib3/packages/backports/__init__.py
-requests/packages/urllib3/packages/backports/makefile.py
-requests/packages/urllib3/packages/ssl_match_hostname/__init__.py
-requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py
-requests/packages/urllib3/util/__init__.py
-requests/packages/urllib3/util/connection.py
-requests/packages/urllib3/util/request.py
-requests/packages/urllib3/util/response.py
-requests/packages/urllib3/util/retry.py
-requests/packages/urllib3/util/selectors.py
-requests/packages/urllib3/util/ssl_.py
-requests/packages/urllib3/util/timeout.py
-requests/packages/urllib3/util/url.py
-requests/packages/urllib3/util/wait.py \ No newline at end of file
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/requires.txt
deleted file mode 100644
index 7afa2c01..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-
-[security]
-pyOpenSSL>=0.14
-cryptography>=1.3.4
-idna>=2.0.0
-
-[socks]
-PySocks>=1.5.6, !=1.5.7
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index f2293605..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-requests
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/__init__.py
deleted file mode 100644
index 1665d4b9..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/__init__.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# __
-# /__) _ _ _ _ _/ _
-# / ( (- (/ (/ (- _) / _)
-# /
-
-"""
-Requests HTTP library
-~~~~~~~~~~~~~~~~~~~~~
-
-Requests is an HTTP library, written in Python, for human beings. Basic GET
-usage:
-
- >>> import requests
- >>> r = requests.get('https://www.python.org')
- >>> r.status_code
- 200
- >>> 'Python is a programming language' in r.content
- True
-
-... or POST:
-
- >>> payload = dict(key1='value1', key2='value2')
- >>> r = requests.post('http://httpbin.org/post', data=payload)
- >>> print(r.text)
- {
- ...
- "form": {
- "key2": "value2",
- "key1": "value1"
- },
- ...
- }
-
-The other HTTP methods are supported - see `requests.api`. Full documentation
-is at <http://python-requests.org>.
-
-:copyright: (c) 2016 by Kenneth Reitz.
-:license: Apache 2.0, see LICENSE for more details.
-"""
-
-__title__ = 'requests'
-__version__ = '2.13.0'
-__build__ = 0x021300
-__author__ = 'Kenneth Reitz'
-__license__ = 'Apache 2.0'
-__copyright__ = 'Copyright 2016 Kenneth Reitz'
-
-# Attempt to enable urllib3's SNI support, if possible
-try:
- from .packages.urllib3.contrib import pyopenssl
- pyopenssl.inject_into_urllib3()
-except ImportError:
- pass
-
-import warnings
-
-# urllib3's DependencyWarnings should be silenced.
-from .packages.urllib3.exceptions import DependencyWarning
-warnings.simplefilter('ignore', DependencyWarning)
-
-from . import utils
-from .models import Request, Response, PreparedRequest
-from .api import request, get, head, post, patch, put, delete, options
-from .sessions import session, Session
-from .status_codes import codes
-from .exceptions import (
- RequestException, Timeout, URLRequired,
- TooManyRedirects, HTTPError, ConnectionError,
- FileModeWarning, ConnectTimeout, ReadTimeout
-)
-
-# Set default logging handler to avoid "No handler found" warnings.
-import logging
-try: # Python 2.7+
- from logging import NullHandler
-except ImportError:
- class NullHandler(logging.Handler):
- def emit(self, record):
- pass
-
-logging.getLogger(__name__).addHandler(NullHandler())
-
-# FileModeWarnings go off per the default.
-warnings.simplefilter('default', FileModeWarning, append=True)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/_internal_utils.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/_internal_utils.py
deleted file mode 100644
index 759d9a56..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/_internal_utils.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests._internal_utils
-~~~~~~~~~~~~~~
-
-Provides utility functions that are consumed internally by Requests
-which depend on extremely few external helpers (such as compat)
-"""
-
-from .compat import is_py2, builtin_str, str
-
-
-def to_native_string(string, encoding='ascii'):
- """Given a string object, regardless of type, returns a representation of
- that string in the native string type, encoding and decoding where
- necessary. This assumes ASCII unless told otherwise.
- """
- if isinstance(string, builtin_str):
- out = string
- else:
- if is_py2:
- out = string.encode(encoding)
- else:
- out = string.decode(encoding)
-
- return out
-
-
-def unicode_is_ascii(u_string):
- """Determine if unicode string only contains ASCII characters.
-
- :param str u_string: unicode string to check. Must be unicode
- and not Python 2 `str`.
- :rtype: bool
- """
- assert isinstance(u_string, str)
- try:
- u_string.encode('ascii')
- return True
- except UnicodeEncodeError:
- return False
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/adapters.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/adapters.py
deleted file mode 100644
index 2475879c..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/adapters.py
+++ /dev/null
@@ -1,503 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.adapters
-~~~~~~~~~~~~~~~~~
-
-This module contains the transport adapters that Requests uses to define
-and maintain connections.
-"""
-
-import os.path
-import socket
-
-from .models import Response
-from .packages.urllib3.poolmanager import PoolManager, proxy_from_url
-from .packages.urllib3.response import HTTPResponse
-from .packages.urllib3.util import Timeout as TimeoutSauce
-from .packages.urllib3.util.retry import Retry
-from .compat import urlparse, basestring
-from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers,
- prepend_scheme_if_needed, get_auth_from_url, urldefragauth,
- select_proxy, to_native_string)
-from .structures import CaseInsensitiveDict
-from .packages.urllib3.exceptions import ClosedPoolError
-from .packages.urllib3.exceptions import ConnectTimeoutError
-from .packages.urllib3.exceptions import HTTPError as _HTTPError
-from .packages.urllib3.exceptions import MaxRetryError
-from .packages.urllib3.exceptions import NewConnectionError
-from .packages.urllib3.exceptions import ProxyError as _ProxyError
-from .packages.urllib3.exceptions import ProtocolError
-from .packages.urllib3.exceptions import ReadTimeoutError
-from .packages.urllib3.exceptions import SSLError as _SSLError
-from .packages.urllib3.exceptions import ResponseError
-from .cookies import extract_cookies_to_jar
-from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
- ProxyError, RetryError, InvalidSchema)
-from .auth import _basic_auth_str
-
-try:
- from .packages.urllib3.contrib.socks import SOCKSProxyManager
-except ImportError:
- def SOCKSProxyManager(*args, **kwargs):
- raise InvalidSchema("Missing dependencies for SOCKS support.")
-
-DEFAULT_POOLBLOCK = False
-DEFAULT_POOLSIZE = 10
-DEFAULT_RETRIES = 0
-DEFAULT_POOL_TIMEOUT = None
-
-
-class BaseAdapter(object):
- """The Base Transport Adapter"""
-
- def __init__(self):
- super(BaseAdapter, self).__init__()
-
- def send(self, request, stream=False, timeout=None, verify=True,
- cert=None, proxies=None):
- """Sends PreparedRequest object. Returns Response object.
-
- :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
- :param stream: (optional) Whether to stream the request content.
- :param timeout: (optional) How long to wait for the server to send
- data before giving up, as a float, or a :ref:`(connect timeout,
- read timeout) <timeouts>` tuple.
- :type timeout: float or tuple
- :param verify: (optional) Whether to verify SSL certificates.
- :param cert: (optional) Any user-provided SSL certificate to be trusted.
- :param proxies: (optional) The proxies dictionary to apply to the request.
- """
- raise NotImplementedError
-
- def close(self):
- """Cleans up adapter specific items."""
- raise NotImplementedError
-
-
-class HTTPAdapter(BaseAdapter):
- """The built-in HTTP Adapter for urllib3.
-
- Provides a general-case interface for Requests sessions to contact HTTP and
- HTTPS urls by implementing the Transport Adapter interface. This class will
- usually be created by the :class:`Session <Session>` class under the
- covers.
-
- :param pool_connections: The number of urllib3 connection pools to cache.
- :param pool_maxsize: The maximum number of connections to save in the pool.
- :param max_retries: The maximum number of retries each connection
- should attempt. Note, this applies only to failed DNS lookups, socket
- connections and connection timeouts, never to requests where data has
- made it to the server. By default, Requests does not retry failed
- connections. If you need granular control over the conditions under
- which we retry a request, import urllib3's ``Retry`` class and pass
- that instead.
- :param pool_block: Whether the connection pool should block for connections.
-
- Usage::
-
- >>> import requests
- >>> s = requests.Session()
- >>> a = requests.adapters.HTTPAdapter(max_retries=3)
- >>> s.mount('http://', a)
- """
- __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize',
- '_pool_block']
-
- def __init__(self, pool_connections=DEFAULT_POOLSIZE,
- pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES,
- pool_block=DEFAULT_POOLBLOCK):
- if max_retries == DEFAULT_RETRIES:
- self.max_retries = Retry(0, read=False)
- else:
- self.max_retries = Retry.from_int(max_retries)
- self.config = {}
- self.proxy_manager = {}
-
- super(HTTPAdapter, self).__init__()
-
- self._pool_connections = pool_connections
- self._pool_maxsize = pool_maxsize
- self._pool_block = pool_block
-
- self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
-
- def __getstate__(self):
- return dict((attr, getattr(self, attr, None)) for attr in
- self.__attrs__)
-
- def __setstate__(self, state):
- # Can't handle by adding 'proxy_manager' to self.__attrs__ because
- # self.poolmanager uses a lambda function, which isn't pickleable.
- self.proxy_manager = {}
- self.config = {}
-
- for attr, value in state.items():
- setattr(self, attr, value)
-
- self.init_poolmanager(self._pool_connections, self._pool_maxsize,
- block=self._pool_block)
-
- def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs):
- """Initializes a urllib3 PoolManager.
-
- This method should not be called from user code, and is only
- exposed for use when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param connections: The number of urllib3 connection pools to cache.
- :param maxsize: The maximum number of connections to save in the pool.
- :param block: Block when no free connections are available.
- :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
- """
- # save these values for pickling
- self._pool_connections = connections
- self._pool_maxsize = maxsize
- self._pool_block = block
-
- self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize,
- block=block, strict=True, **pool_kwargs)
-
- def proxy_manager_for(self, proxy, **proxy_kwargs):
- """Return urllib3 ProxyManager for the given proxy.
-
- This method should not be called from user code, and is only
- exposed for use when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param proxy: The proxy to return a urllib3 ProxyManager for.
- :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
- :returns: ProxyManager
- :rtype: requests.packages.urllib3.ProxyManager
- """
- if proxy in self.proxy_manager:
- manager = self.proxy_manager[proxy]
- elif proxy.lower().startswith('socks'):
- username, password = get_auth_from_url(proxy)
- manager = self.proxy_manager[proxy] = SOCKSProxyManager(
- proxy,
- username=username,
- password=password,
- num_pools=self._pool_connections,
- maxsize=self._pool_maxsize,
- block=self._pool_block,
- **proxy_kwargs
- )
- else:
- proxy_headers = self.proxy_headers(proxy)
- manager = self.proxy_manager[proxy] = proxy_from_url(
- proxy,
- proxy_headers=proxy_headers,
- num_pools=self._pool_connections,
- maxsize=self._pool_maxsize,
- block=self._pool_block,
- **proxy_kwargs)
-
- return manager
-
- def cert_verify(self, conn, url, verify, cert):
- """Verify a SSL certificate. This method should not be called from user
- code, and is only exposed for use when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param conn: The urllib3 connection object associated with the cert.
- :param url: The requested URL.
- :param verify: Whether we should actually verify the certificate.
- :param cert: The SSL certificate to verify.
- """
- if url.lower().startswith('https') and verify:
-
- cert_loc = None
-
- # Allow self-specified cert location.
- if verify is not True:
- cert_loc = verify
-
- if not cert_loc:
- cert_loc = DEFAULT_CA_BUNDLE_PATH
-
- if not cert_loc:
- raise Exception("Could not find a suitable SSL CA certificate bundle.")
-
- conn.cert_reqs = 'CERT_REQUIRED'
-
- if not os.path.isdir(cert_loc):
- conn.ca_certs = cert_loc
- else:
- conn.ca_cert_dir = cert_loc
- else:
- conn.cert_reqs = 'CERT_NONE'
- conn.ca_certs = None
- conn.ca_cert_dir = None
-
- if cert:
- if not isinstance(cert, basestring):
- conn.cert_file = cert[0]
- conn.key_file = cert[1]
- else:
- conn.cert_file = cert
-
- def build_response(self, req, resp):
- """Builds a :class:`Response <requests.Response>` object from a urllib3
- response. This should not be called from user code, and is only exposed
- for use when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
-
- :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
- :param resp: The urllib3 response object.
- :rtype: requests.Response
- """
- response = Response()
-
- # Fallback to None if there's no status_code, for whatever reason.
- response.status_code = getattr(resp, 'status', None)
-
- # Make headers case-insensitive.
- response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {}))
-
- # Set encoding.
- response.encoding = get_encoding_from_headers(response.headers)
- response.raw = resp
- response.reason = response.raw.reason
-
- if isinstance(req.url, bytes):
- response.url = req.url.decode('utf-8')
- else:
- response.url = req.url
-
- # Add new cookies from the server.
- extract_cookies_to_jar(response.cookies, req, resp)
-
- # Give the Response some context.
- response.request = req
- response.connection = self
-
- return response
-
- def get_connection(self, url, proxies=None):
- """Returns a urllib3 connection for the given URL. This should not be
- called from user code, and is only exposed for use when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param url: The URL to connect to.
- :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
- :rtype: requests.packages.urllib3.ConnectionPool
- """
- proxy = select_proxy(url, proxies)
-
- if proxy:
- proxy = prepend_scheme_if_needed(proxy, 'http')
- proxy_manager = self.proxy_manager_for(proxy)
- conn = proxy_manager.connection_from_url(url)
- else:
- # Only scheme should be lower case
- parsed = urlparse(url)
- url = parsed.geturl()
- conn = self.poolmanager.connection_from_url(url)
-
- return conn
-
- def close(self):
- """Disposes of any internal state.
-
- Currently, this closes the PoolManager and any active ProxyManager,
- which closes any pooled connections.
- """
- self.poolmanager.clear()
- for proxy in self.proxy_manager.values():
- proxy.clear()
-
- def request_url(self, request, proxies):
- """Obtain the url to use when making the final request.
-
- If the message is being sent through a HTTP proxy, the full URL has to
- be used. Otherwise, we should only use the path portion of the URL.
-
- This should not be called from user code, and is only exposed for use
- when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
- :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
- :rtype: str
- """
- proxy = select_proxy(request.url, proxies)
- scheme = urlparse(request.url).scheme
-
- is_proxied_http_request = (proxy and scheme != 'https')
- using_socks_proxy = False
- if proxy:
- proxy_scheme = urlparse(proxy).scheme.lower()
- using_socks_proxy = proxy_scheme.startswith('socks')
-
- url = request.path_url
- if is_proxied_http_request and not using_socks_proxy:
- url = urldefragauth(request.url)
-
- return url
-
- def add_headers(self, request, **kwargs):
- """Add any headers needed by the connection. As of v2.0 this does
- nothing by default, but is left for overriding by users that subclass
- the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- This should not be called from user code, and is only exposed for use
- when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
- :param kwargs: The keyword arguments from the call to send().
- """
- pass
-
- def proxy_headers(self, proxy):
- """Returns a dictionary of the headers to add to any request sent
- through a proxy. This works with urllib3 magic to ensure that they are
- correctly sent to the proxy, rather than in a tunnelled request if
- CONNECT is being used.
-
- This should not be called from user code, and is only exposed for use
- when subclassing the
- :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
-
- :param proxies: The url of the proxy being used for this request.
- :rtype: dict
- """
- headers = {}
- username, password = get_auth_from_url(proxy)
-
- if username:
- headers['Proxy-Authorization'] = _basic_auth_str(username,
- password)
-
- return headers
-
- def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
- """Sends PreparedRequest object. Returns Response object.
-
- :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
- :param stream: (optional) Whether to stream the request content.
- :param timeout: (optional) How long to wait for the server to send
- data before giving up, as a float, or a :ref:`(connect timeout,
- read timeout) <timeouts>` tuple.
- :type timeout: float or tuple
- :param verify: (optional) Whether to verify SSL certificates.
- :param cert: (optional) Any user-provided SSL certificate to be trusted.
- :param proxies: (optional) The proxies dictionary to apply to the request.
- :rtype: requests.Response
- """
-
- conn = self.get_connection(request.url, proxies)
-
- self.cert_verify(conn, request.url, verify, cert)
- url = self.request_url(request, proxies)
- self.add_headers(request)
-
- chunked = not (request.body is None or 'Content-Length' in request.headers)
-
- if isinstance(timeout, tuple):
- try:
- connect, read = timeout
- timeout = TimeoutSauce(connect=connect, read=read)
- except ValueError as e:
- # this may raise a string formatting error.
- err = ("Invalid timeout {0}. Pass a (connect, read) "
- "timeout tuple, or a single float to set "
- "both timeouts to the same value".format(timeout))
- raise ValueError(err)
- else:
- timeout = TimeoutSauce(connect=timeout, read=timeout)
-
- try:
- if not chunked:
- resp = conn.urlopen(
- method=request.method,
- url=url,
- body=request.body,
- headers=request.headers,
- redirect=False,
- assert_same_host=False,
- preload_content=False,
- decode_content=False,
- retries=self.max_retries,
- timeout=timeout
- )
-
- # Send the request.
- else:
- if hasattr(conn, 'proxy_pool'):
- conn = conn.proxy_pool
-
- low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
-
- try:
- low_conn.putrequest(request.method,
- url,
- skip_accept_encoding=True)
-
- for header, value in request.headers.items():
- low_conn.putheader(header, value)
-
- low_conn.endheaders()
-
- for i in request.body:
- low_conn.send(hex(len(i))[2:].encode('utf-8'))
- low_conn.send(b'\r\n')
- low_conn.send(i)
- low_conn.send(b'\r\n')
- low_conn.send(b'0\r\n\r\n')
-
- # Receive the response from the server
- try:
- # For Python 2.7+ versions, use buffering of HTTP
- # responses
- r = low_conn.getresponse(buffering=True)
- except TypeError:
- # For compatibility with Python 2.6 versions and back
- r = low_conn.getresponse()
-
- resp = HTTPResponse.from_httplib(
- r,
- pool=conn,
- connection=low_conn,
- preload_content=False,
- decode_content=False
- )
- except:
- # If we hit any problems here, clean up the connection.
- # Then, reraise so that we can handle the actual exception.
- low_conn.close()
- raise
-
- except (ProtocolError, socket.error) as err:
- raise ConnectionError(err, request=request)
-
- except MaxRetryError as e:
- if isinstance(e.reason, ConnectTimeoutError):
- # TODO: Remove this in 3.0.0: see #2811
- if not isinstance(e.reason, NewConnectionError):
- raise ConnectTimeout(e, request=request)
-
- if isinstance(e.reason, ResponseError):
- raise RetryError(e, request=request)
-
- if isinstance(e.reason, _ProxyError):
- raise ProxyError(e, request=request)
-
- raise ConnectionError(e, request=request)
-
- except ClosedPoolError as e:
- raise ConnectionError(e, request=request)
-
- except _ProxyError as e:
- raise ProxyError(e)
-
- except (_SSLError, _HTTPError) as e:
- if isinstance(e, _SSLError):
- raise SSLError(e, request=request)
- elif isinstance(e, ReadTimeoutError):
- raise ReadTimeout(e, request=request)
- else:
- raise
-
- return self.build_response(request, resp)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/api.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/api.py
deleted file mode 100644
index 16fd1e94..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/api.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.api
-~~~~~~~~~~~~
-
-This module implements the Requests API.
-
-:copyright: (c) 2012 by Kenneth Reitz.
-:license: Apache2, see LICENSE for more details.
-"""
-
-from . import sessions
-
-
-def request(method, url, **kwargs):
- """Constructs and sends a :class:`Request <Request>`.
-
- :param method: method for the new :class:`Request` object.
- :param url: URL for the new :class:`Request` object.
- :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param json: (optional) json data to send in the body of the :class:`Request`.
- :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
- :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
- :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
- ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
- or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
- defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
- to add for the file.
- :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
- :param timeout: (optional) How long to wait for the server to send data
- before giving up, as a float, or a :ref:`(connect timeout, read
- timeout) <timeouts>` tuple.
- :type timeout: float or tuple
- :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
- :type allow_redirects: bool
- :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
- :param verify: (optional) whether the SSL cert will be verified. A CA_BUNDLE path can also be provided. Defaults to ``True``.
- :param stream: (optional) if ``False``, the response content will be immediately downloaded.
- :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
-
- Usage::
-
- >>> import requests
- >>> req = requests.request('GET', 'http://httpbin.org/get')
- <Response [200]>
- """
-
- # By using the 'with' statement we are sure the session is closed, thus we
- # avoid leaving sockets open which can trigger a ResourceWarning in some
- # cases, and look like a memory leak in others.
- with sessions.Session() as session:
- return session.request(method=method, url=url, **kwargs)
-
-
-def get(url, params=None, **kwargs):
- """Sends a GET request.
-
- :param url: URL for the new :class:`Request` object.
- :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- kwargs.setdefault('allow_redirects', True)
- return request('get', url, params=params, **kwargs)
-
-
-def options(url, **kwargs):
- """Sends a OPTIONS request.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- kwargs.setdefault('allow_redirects', True)
- return request('options', url, **kwargs)
-
-
-def head(url, **kwargs):
- """Sends a HEAD request.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- kwargs.setdefault('allow_redirects', False)
- return request('head', url, **kwargs)
-
-
-def post(url, data=None, json=None, **kwargs):
- """Sends a POST request.
-
- :param url: URL for the new :class:`Request` object.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param json: (optional) json data to send in the body of the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- return request('post', url, data=data, json=json, **kwargs)
-
-
-def put(url, data=None, **kwargs):
- """Sends a PUT request.
-
- :param url: URL for the new :class:`Request` object.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param json: (optional) json data to send in the body of the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- return request('put', url, data=data, **kwargs)
-
-
-def patch(url, data=None, **kwargs):
- """Sends a PATCH request.
-
- :param url: URL for the new :class:`Request` object.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param json: (optional) json data to send in the body of the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- return request('patch', url, data=data, **kwargs)
-
-
-def delete(url, **kwargs):
- """Sends a DELETE request.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :return: :class:`Response <Response>` object
- :rtype: requests.Response
- """
-
- return request('delete', url, **kwargs)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/auth.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/auth.py
deleted file mode 100644
index 510846d6..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/auth.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.auth
-~~~~~~~~~~~~~
-
-This module contains the authentication handlers for Requests.
-"""
-
-import os
-import re
-import time
-import hashlib
-import threading
-import warnings
-
-from base64 import b64encode
-
-from .compat import urlparse, str, basestring
-from .cookies import extract_cookies_to_jar
-from ._internal_utils import to_native_string
-from .utils import parse_dict_header
-from .status_codes import codes
-
-CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'
-CONTENT_TYPE_MULTI_PART = 'multipart/form-data'
-
-
-def _basic_auth_str(username, password):
- """Returns a Basic Auth string."""
-
- # "I want us to put a big-ol' comment on top of it that
- # says that this behaviour is dumb but we need to preserve
- # it because people are relying on it."
- # - Lukasa
- #
- # These are here solely to maintain backwards compatibility
- # for things like ints. This will be removed in 3.0.0.
- if not isinstance(username, basestring):
- warnings.warn(
- "Non-string usernames will no longer be supported in Requests "
- "3.0.0. Please convert the object you've passed in ({0!r}) to "
- "a string or bytes object in the near future to avoid "
- "problems.".format(username),
- category=DeprecationWarning,
- )
- username = str(username)
-
- if not isinstance(password, basestring):
- warnings.warn(
- "Non-string passwords will no longer be supported in Requests "
- "3.0.0. Please convert the object you've passed in ({0!r}) to "
- "a string or bytes object in the near future to avoid "
- "problems.".format(password),
- category=DeprecationWarning,
- )
- password = str(password)
- # -- End Removal --
-
- if isinstance(username, str):
- username = username.encode('latin1')
-
- if isinstance(password, str):
- password = password.encode('latin1')
-
- authstr = 'Basic ' + to_native_string(
- b64encode(b':'.join((username, password))).strip()
- )
-
- return authstr
-
-
-class AuthBase(object):
- """Base class that all auth implementations derive from"""
-
- def __call__(self, r):
- raise NotImplementedError('Auth hooks must be callable.')
-
-
-class HTTPBasicAuth(AuthBase):
- """Attaches HTTP Basic Authentication to the given Request object."""
-
- def __init__(self, username, password):
- self.username = username
- self.password = password
-
- def __eq__(self, other):
- return all([
- self.username == getattr(other, 'username', None),
- self.password == getattr(other, 'password', None)
- ])
-
- def __ne__(self, other):
- return not self == other
-
- def __call__(self, r):
- r.headers['Authorization'] = _basic_auth_str(self.username, self.password)
- return r
-
-
-class HTTPProxyAuth(HTTPBasicAuth):
- """Attaches HTTP Proxy Authentication to a given Request object."""
-
- def __call__(self, r):
- r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password)
- return r
-
-
-class HTTPDigestAuth(AuthBase):
- """Attaches HTTP Digest Authentication to the given Request object."""
-
- def __init__(self, username, password):
- self.username = username
- self.password = password
- # Keep state in per-thread local storage
- self._thread_local = threading.local()
-
- def init_per_thread_state(self):
- # Ensure state is initialized just once per-thread
- if not hasattr(self._thread_local, 'init'):
- self._thread_local.init = True
- self._thread_local.last_nonce = ''
- self._thread_local.nonce_count = 0
- self._thread_local.chal = {}
- self._thread_local.pos = None
- self._thread_local.num_401_calls = None
-
- def build_digest_header(self, method, url):
- """
- :rtype: str
- """
-
- realm = self._thread_local.chal['realm']
- nonce = self._thread_local.chal['nonce']
- qop = self._thread_local.chal.get('qop')
- algorithm = self._thread_local.chal.get('algorithm')
- opaque = self._thread_local.chal.get('opaque')
- hash_utf8 = None
-
- if algorithm is None:
- _algorithm = 'MD5'
- else:
- _algorithm = algorithm.upper()
- # lambdas assume digest modules are imported at the top level
- if _algorithm == 'MD5' or _algorithm == 'MD5-SESS':
- def md5_utf8(x):
- if isinstance(x, str):
- x = x.encode('utf-8')
- return hashlib.md5(x).hexdigest()
- hash_utf8 = md5_utf8
- elif _algorithm == 'SHA':
- def sha_utf8(x):
- if isinstance(x, str):
- x = x.encode('utf-8')
- return hashlib.sha1(x).hexdigest()
- hash_utf8 = sha_utf8
-
- KD = lambda s, d: hash_utf8("%s:%s" % (s, d))
-
- if hash_utf8 is None:
- return None
-
- # XXX not implemented yet
- entdig = None
- p_parsed = urlparse(url)
- #: path is request-uri defined in RFC 2616 which should not be empty
- path = p_parsed.path or "/"
- if p_parsed.query:
- path += '?' + p_parsed.query
-
- A1 = '%s:%s:%s' % (self.username, realm, self.password)
- A2 = '%s:%s' % (method, path)
-
- HA1 = hash_utf8(A1)
- HA2 = hash_utf8(A2)
-
- if nonce == self._thread_local.last_nonce:
- self._thread_local.nonce_count += 1
- else:
- self._thread_local.nonce_count = 1
- ncvalue = '%08x' % self._thread_local.nonce_count
- s = str(self._thread_local.nonce_count).encode('utf-8')
- s += nonce.encode('utf-8')
- s += time.ctime().encode('utf-8')
- s += os.urandom(8)
-
- cnonce = (hashlib.sha1(s).hexdigest()[:16])
- if _algorithm == 'MD5-SESS':
- HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce))
-
- if not qop:
- respdig = KD(HA1, "%s:%s" % (nonce, HA2))
- elif qop == 'auth' or 'auth' in qop.split(','):
- noncebit = "%s:%s:%s:%s:%s" % (
- nonce, ncvalue, cnonce, 'auth', HA2
- )
- respdig = KD(HA1, noncebit)
- else:
- # XXX handle auth-int.
- return None
-
- self._thread_local.last_nonce = nonce
-
- # XXX should the partial digests be encoded too?
- base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \
- 'response="%s"' % (self.username, realm, nonce, path, respdig)
- if opaque:
- base += ', opaque="%s"' % opaque
- if algorithm:
- base += ', algorithm="%s"' % algorithm
- if entdig:
- base += ', digest="%s"' % entdig
- if qop:
- base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce)
-
- return 'Digest %s' % (base)
-
- def handle_redirect(self, r, **kwargs):
- """Reset num_401_calls counter on redirects."""
- if r.is_redirect:
- self._thread_local.num_401_calls = 1
-
- def handle_401(self, r, **kwargs):
- """
- Takes the given response and tries digest-auth, if needed.
-
- :rtype: requests.Response
- """
-
- if self._thread_local.pos is not None:
- # Rewind the file position indicator of the body to where
- # it was to resend the request.
- r.request.body.seek(self._thread_local.pos)
- s_auth = r.headers.get('www-authenticate', '')
-
- if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2:
-
- self._thread_local.num_401_calls += 1
- pat = re.compile(r'digest ', flags=re.IGNORECASE)
- self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1))
-
- # Consume content and release the original connection
- # to allow our new request to reuse the same one.
- r.content
- r.close()
- prep = r.request.copy()
- extract_cookies_to_jar(prep._cookies, r.request, r.raw)
- prep.prepare_cookies(prep._cookies)
-
- prep.headers['Authorization'] = self.build_digest_header(
- prep.method, prep.url)
- _r = r.connection.send(prep, **kwargs)
- _r.history.append(r)
- _r.request = prep
-
- return _r
-
- self._thread_local.num_401_calls = 1
- return r
-
- def __call__(self, r):
- # Initialize per-thread state, if needed
- self.init_per_thread_state()
- # If we have a saved nonce, skip the 401
- if self._thread_local.last_nonce:
- r.headers['Authorization'] = self.build_digest_header(r.method, r.url)
- try:
- self._thread_local.pos = r.body.tell()
- except AttributeError:
- # In the case of HTTPDigestAuth being reused and the body of
- # the previous request was a file-like object, pos has the
- # file position of the previous body. Ensure it's set to
- # None.
- self._thread_local.pos = None
- r.register_hook('response', self.handle_401)
- r.register_hook('response', self.handle_redirect)
- self._thread_local.num_401_calls = 1
-
- return r
-
- def __eq__(self, other):
- return all([
- self.username == getattr(other, 'username', None),
- self.password == getattr(other, 'password', None)
- ])
-
- def __ne__(self, other):
- return not self == other
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cacert.pem b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cacert.pem
deleted file mode 100644
index 108f9d63..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cacert.pem
+++ /dev/null
@@ -1,5689 +0,0 @@
-
-# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
-# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
-# Label: "GlobalSign Root CA"
-# Serial: 4835703278459707669005204
-# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
-# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
-# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
-MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
-aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
-jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
-xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
-1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
-snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
-U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
-9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
-AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
-yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
-38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
-AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
-DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
-HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
-# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
-# Label: "GlobalSign Root CA - R2"
-# Serial: 4835703278459682885658125
-# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30
-# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe
-# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
-MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
-v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
-eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
-tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
-C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
-zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
-mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
-V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
-bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
-3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
-J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
-291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
-ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
-AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Label: "Verisign Class 3 Public Primary Certification Authority - G3"
-# Serial: 206684696279472310254277870180966723415
-# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09
-# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6
-# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
-cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
-LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
-aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
-VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
-aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
-bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
-IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
-N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
-KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
-kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
-CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
-Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
-imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
-2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
-DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
-/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
-F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
-TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Label: "Entrust.net Premium 2048 Secure Server CA"
-# Serial: 946069240
-# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
-# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
-# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
-RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
-bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
-IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
-MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
-LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
-YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
-A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
-K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
-sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
-MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
-XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
-HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
-4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
-HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
-j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
-U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
-zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
-u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
-bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
-fF6adulZkMV8gzURZVE=
------END CERTIFICATE-----
-
-# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
-# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
-# Label: "Baltimore CyberTrust Root"
-# Serial: 33554617
-# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
-# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
-# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
-DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
-ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
-VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
-mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
-IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
-mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
-XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
-dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
-jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
-BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
-DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
-9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
-jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
-Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
-ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
-R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Label: "AddTrust Low-Value Services Root"
-# Serial: 1
-# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc
-# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d
-# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7
------BEGIN CERTIFICATE-----
-MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
-MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
-VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
-CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
-tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
-dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
-PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
-+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
-BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
-ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
-IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
-7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
-43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
-eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
-pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
-WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
-# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
-# Label: "AddTrust External Root"
-# Serial: 1
-# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f
-# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68
-# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Label: "AddTrust Public Services Root"
-# Serial: 1
-# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f
-# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5
-# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
-MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
-ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
-BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
-6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
-GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
-dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
-1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
-62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
-BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
-AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
-MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
-cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
-b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
-IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
-iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
-GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
-4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
-XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Label: "AddTrust Qualified Certificates Root"
-# Serial: 1
-# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb
-# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf
-# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16
------BEGIN CERTIFICATE-----
-MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
-MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
-EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
-BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
-xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
-87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
-2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
-WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
-0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
-A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
-pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
-ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
-aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
-hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
-hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
-dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
-P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
-iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
-xqE=
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
-# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
-# Label: "Entrust Root Certification Authority"
-# Serial: 1164660820
-# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
-# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
-# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
------BEGIN CERTIFICATE-----
-MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
-Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
-KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
-NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
-NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
-ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
-BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
-Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
-4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
-KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
-rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
-94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
-sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
-gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
-kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
-vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
-A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
-O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
-AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
-9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
-eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
-0vdXcDazv/wor3ElhVsT/h5/WrQ8
------END CERTIFICATE-----
-
-# Issuer: O=RSA Security Inc OU=RSA Security 2048 V3
-# Subject: O=RSA Security Inc OU=RSA Security 2048 V3
-# Label: "RSA Security 2048 v3"
-# Serial: 13297492616345471454730593562152402946
-# MD5 Fingerprint: 77:0d:19:b1:21:fd:00:42:9c:3e:0c:a5:dd:0b:02:8e
-# SHA1 Fingerprint: 25:01:90:19:cf:fb:d9:99:1c:b7:68:25:74:8d:94:5f:30:93:95:42
-# SHA256 Fingerprint: af:8b:67:62:a1:e5:28:22:81:61:a9:5d:5c:55:9e:e2:66:27:8f:75:d7:9e:83:01:89:a5:03:50:6a:bd:6b:4c
------BEGIN CERTIFICATE-----
-MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
-MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
-dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
-BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
-MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
-eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
-/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
-wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
-AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
-PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
-AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
-MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
-HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
-Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
-f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
-rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
-6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
-7CAFYd4=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.
-# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.
-# Label: "GeoTrust Global CA"
-# Serial: 144470
-# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5
-# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12
-# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
-# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
-# Label: "GeoTrust Global CA 2"
-# Serial: 1
-# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9
-# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d
-# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85
------BEGIN CERTIFICATE-----
-MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
-IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
-PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
-Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
-TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
-5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
-S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
-2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
-FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
-EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
-EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
-/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
-A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
-abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
-I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
-4iIprn2DQKi6bA==
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
-# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
-# Label: "GeoTrust Universal CA"
-# Serial: 1
-# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48
-# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79
-# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12
------BEGIN CERTIFICATE-----
-MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
-c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
-BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
-IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
-VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
-cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
-QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
-F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
-c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
-mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
-VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
-teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
-f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
-Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
-nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
-/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
-MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
-9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
-aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
-IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
-ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
-uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
-Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
-QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
-koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
-ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
-DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
-bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
-# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
-# Label: "GeoTrust Universal CA 2"
-# Serial: 1
-# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7
-# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79
-# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b
------BEGIN CERTIFICATE-----
-MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
-c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
-VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
-c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
-WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
-FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
-XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
-se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
-KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
-IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
-y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
-hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
-QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
-Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
-HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
-KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
-dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
-L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
-Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
-ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
-T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
-GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
-1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
-OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
-6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
-QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
------END CERTIFICATE-----
-
-# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
-# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
-# Label: "Visa eCommerce Root"
-# Serial: 25952180776285836048024890241505565794
-# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02
-# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62
-# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22
------BEGIN CERTIFICATE-----
-MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
-MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
-cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
-bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
-CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
-dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
-cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
-2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
-lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
-ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
-299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
-vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
-dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
-AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
-zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
-LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
-7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
-++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
-398znM/jra6O1I7mT1GvFpLgXPYHDw==
------END CERTIFICATE-----
-
-# Issuer: CN=Certum CA O=Unizeto Sp. z o.o.
-# Subject: CN=Certum CA O=Unizeto Sp. z o.o.
-# Label: "Certum Root CA"
-# Serial: 65568
-# MD5 Fingerprint: 2c:8f:9f:66:1d:18:90:b1:47:26:9d:8e:86:82:8c:a9
-# SHA1 Fingerprint: 62:52:dc:40:f7:11:43:a2:2f:de:9e:f7:34:8e:06:42:51:b1:81:18
-# SHA256 Fingerprint: d8:e0:fe:bc:1d:b2:e3:8d:00:94:0f:37:d2:7d:41:34:4d:99:3e:73:4b:99:d5:65:6d:97:78:d4:d8:14:36:24
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
-MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
-QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
-MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
-jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
-ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
-ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
-Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
-AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
-HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
-uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
-TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
-xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
-CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
-O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
-6GAqm4VKQPNriiTsBhYscw==
------END CERTIFICATE-----
-
-# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
-# Subject: CN=AAA Certificate Services O=Comodo CA Limited
-# Label: "Comodo AAA Services root"
-# Serial: 1
-# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
-# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
-# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
------BEGIN CERTIFICATE-----
-MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
-YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
-MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
-BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
-GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
-BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
-3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
-YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
-rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
-ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
-oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
-MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
-QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
-b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
-AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
-GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
-Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
-G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
-l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
-smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
------END CERTIFICATE-----
-
-# Issuer: CN=Secure Certificate Services O=Comodo CA Limited
-# Subject: CN=Secure Certificate Services O=Comodo CA Limited
-# Label: "Comodo Secure Services root"
-# Serial: 1
-# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd
-# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1
-# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8
------BEGIN CERTIFICATE-----
-MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
-ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
-fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
-BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
-cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
-HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
-CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
-3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
-6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
-HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
-EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
-Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
-Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
-DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
-5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
-Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
-gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
-aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
-izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
------END CERTIFICATE-----
-
-# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited
-# Subject: CN=Trusted Certificate Services O=Comodo CA Limited
-# Label: "Comodo Trusted Services root"
-# Serial: 1
-# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27
-# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd
-# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
-aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
-MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
-BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
-VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
-fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
-TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
-fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
-1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
-kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
-A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
-ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
-dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
-Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
-HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
-pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
-jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
-xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
-dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
-# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
-# Label: "QuoVadis Root CA"
-# Serial: 985026699
-# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24
-# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9
-# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73
------BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
-MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
-IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
-dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
-li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
-rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
-WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
-F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
-xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
-Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
-dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
-ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
-IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
-c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
-ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
-Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
-KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
-KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
-y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
-dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
-VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
-fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
-7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
-cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
-mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
-xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
-SnQ2+Q==
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 2"
-# Serial: 1289
-# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b
-# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7
-# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86
------BEGIN CERTIFICATE-----
-MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
-GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
-b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
-BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
-YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
-GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
-Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
-WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
-rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
-+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
-ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
-Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
-PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
-/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
-oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
-yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
-EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
-A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
-MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
-ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
-BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
-g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
-fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
-WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
-B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
-hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
-TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
-mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
-ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
-4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
-8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 3"
-# Serial: 1478
-# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf
-# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85
-# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35
------BEGIN CERTIFICATE-----
-MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
-GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
-b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
-BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
-YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
-V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
-4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
-H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
-8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
-vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
-mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
-btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
-T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
-WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
-c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
-4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
-VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
-CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
-aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
-aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
-dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
-czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
-A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
-Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
-7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
-d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
-+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
-4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
-t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
-DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
-k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
-zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
-Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
-mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
-4SVhM7JZG+Ju1zdXtg2pEto=
------END CERTIFICATE-----
-
-# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1
-# Subject: O=SECOM Trust.net OU=Security Communication RootCA1
-# Label: "Security Communication Root CA"
-# Serial: 0
-# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a
-# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7
-# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c
------BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
-MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
-dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
-WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
-VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
-9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
-DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
-Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
-QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
-xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
-A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
-kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
-Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
-Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
-JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
-RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
------END CERTIFICATE-----
-
-# Issuer: CN=Sonera Class2 CA O=Sonera
-# Subject: CN=Sonera Class2 CA O=Sonera
-# Label: "Sonera Class 2 Root CA"
-# Serial: 29
-# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb
-# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27
-# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
-MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
-MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
-BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
-Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
-5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
-3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
-vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
-8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
-DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
-MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
-zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
-3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
-FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
-Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
-ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
------END CERTIFICATE-----
-
-# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
-# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
-# Label: "UTN USERFirst Hardware Root CA"
-# Serial: 91374294542884704022267039221184531197
-# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39
-# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7
-# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37
------BEGIN CERTIFICATE-----
-MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
-lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
-SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
-A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
-MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
-d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
-cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
-0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
-M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
-MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
-oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
-DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
-oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
-dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
-bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
-BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
-//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
-CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
-CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
-3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
-KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
------END CERTIFICATE-----
-
-# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Label: "Camerfirma Chambers of Commerce Root"
-# Serial: 0
-# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84
-# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1
-# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
-b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
-MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
-ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
-IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
-AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
-unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
-BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
-7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
-0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
-roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
-A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
-aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
-26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
-BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
-EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
-BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
-aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
-AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
-p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
-1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
-XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
-eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
-tGWaIZDgqtCYvDi1czyL+Nw=
------END CERTIFICATE-----
-
-# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Label: "Camerfirma Global Chambersign Root"
-# Serial: 0
-# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19
-# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9
-# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed
------BEGIN CERTIFICATE-----
-MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
-YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
-MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
-NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
-A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
-A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
-Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
-QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
-eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
-B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
-z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
-AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
-ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
-TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
-MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
-VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
-VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
-bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
-AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
-bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
-ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
-VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
-ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
-AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
------END CERTIFICATE-----
-
-# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
-# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
-# Label: "XRamp Global CA Root"
-# Serial: 107108908803651509692980124233745014957
-# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
-# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
-# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
------BEGIN CERTIFICATE-----
-MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
-gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
-MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
-UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
-NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
-dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
-dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
-38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
-KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
-DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
-qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
-JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
-PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
-BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
-jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
-eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
-ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
-vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
-qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
-IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
-i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
-O+7ETPTsJ3xCwnR8gooJybQDJbw=
------END CERTIFICATE-----
-
-# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
-# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
-# Label: "Go Daddy Class 2 CA"
-# Serial: 0
-# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
-# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
-# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
------BEGIN CERTIFICATE-----
-MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
-MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
-YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
-MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
-ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
-MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
-ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
-PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
-wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
-EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
-avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
-YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
-sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
-/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
-IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
-OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
-TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
-HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
-dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
-ReYNnyicsbkqWletNw+vHX/bvZ8=
------END CERTIFICATE-----
-
-# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
-# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
-# Label: "Starfield Class 2 CA"
-# Serial: 0
-# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
-# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
-# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
-MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
-U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
-NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
-ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
-ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
-DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
-8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
-+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
-X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
-K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
-1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
-A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
-zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
-YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
-bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
-DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
-L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
-eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
-xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
-VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
-WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Label: "StartCom Certification Authority"
-# Serial: 1
-# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16
-# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f
-# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea
------BEGIN CERTIFICATE-----
-MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
-FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
-ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
-LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
-BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
-Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
-dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
-cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
-YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
-dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
-bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
-YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
-TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
-9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
-jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
-FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
-ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
-ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
-EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
-L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
-yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
-O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
-um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
-NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
------END CERTIFICATE-----
-
-# Issuer: O=Government Root Certification Authority
-# Subject: O=Government Root Certification Authority
-# Label: "Taiwan GRCA"
-# Serial: 42023070807708724159991140556527066870
-# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e
-# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9
-# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3
------BEGIN CERTIFICATE-----
-MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
-MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
-PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
-IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
-gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
-yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
-F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
-jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
-ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
-VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
-YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
-EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
-Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
-DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
-MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
-UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
-TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
-qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
-ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
-JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
-hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
-EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
-nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
-udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
-ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
-LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
-pYYsfPQS
------END CERTIFICATE-----
-
-# Issuer: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
-# Subject: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
-# Label: "Swisscom Root CA 1"
-# Serial: 122348795730808398873664200247279986742
-# MD5 Fingerprint: f8:38:7c:77:88:df:2c:16:68:2e:c2:e2:52:4b:b8:f9
-# SHA1 Fingerprint: 5f:3a:fc:0a:8b:64:f6:86:67:34:74:df:7e:a9:a2:fe:f9:fa:7a:51
-# SHA256 Fingerprint: 21:db:20:12:36:60:bb:2e:d4:18:20:5d:a1:1e:e7:a8:5a:65:e2:bc:6e:55:b5:af:7e:78:99:c8:a2:66:d9:2e
------BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
-MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
-Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
-AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
-Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
-m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
-FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
-TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
-EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
-kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
-HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
-vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
-19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
-L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
-bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
-JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
-FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
-BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
-K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
-ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
-Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
-sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
-3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
-ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
-mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
-b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
-rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
-hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
-zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
-MBr1mmz0DlP5OlvRHA==
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Assured ID Root CA"
-# Serial: 17154717934120587862167794914071425081
-# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
-# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
-# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
------BEGIN CERTIFICATE-----
-MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
-b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
-cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
-JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
-mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
-wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
-VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
-AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
-AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
-pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
-dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
-fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
-NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
-H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
-+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Global Root CA"
-# Serial: 10944719598952040374951832963794454346
-# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
-# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
-# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
------BEGIN CERTIFICATE-----
-MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
-CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
-nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
-43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
-T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
-gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
-TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
-DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
-hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
-06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
-PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
-YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
-CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert High Assurance EV Root CA"
-# Serial: 3553400076410547919724730734378100087
-# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
-# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
-# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
-
-# Issuer: CN=Class 2 Primary CA O=Certplus
-# Subject: CN=Class 2 Primary CA O=Certplus
-# Label: "Certplus Class 2 Primary CA"
-# Serial: 177770208045934040241468760488327595043
-# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b
-# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb
-# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb
------BEGIN CERTIFICATE-----
-MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
-PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
-cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
-MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
-IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
-ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
-VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
-kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
-EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
-H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
-HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
-DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
-QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
-Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
-AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
-yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
-FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
-ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
-kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
-l7+ijrRU
------END CERTIFICATE-----
-
-# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co.
-# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co.
-# Label: "DST Root CA X3"
-# Serial: 91299735575339953335919266965803778155
-# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5
-# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13
-# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39
------BEGIN CERTIFICATE-----
-MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
-rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
-OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
-xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
-7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
-aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
-SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
-ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
-AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
-R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
-JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
-Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
------END CERTIFICATE-----
-
-# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
-# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
-# Label: "DST ACES CA X6"
-# Serial: 17771143917277623872238992636097467865
-# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8
-# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d
-# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40
------BEGIN CERTIFICATE-----
-MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
-ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
-MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
-VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
-FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
-ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
-gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
-fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
-ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
-ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
-MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
-c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
-dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
-aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
-hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
-QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
-h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
-nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
-rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
-9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
------END CERTIFICATE-----
-
-# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
-# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
-# Label: "SwissSign Gold CA - G2"
-# Serial: 13492815561806991280
-# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93
-# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61
-# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95
------BEGIN CERTIFICATE-----
-MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
-BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
-biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
-MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
-d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
-76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
-bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
-6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
-emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
-MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
-MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
-MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
-FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
-aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
-gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
-qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
-lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
-8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
-L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
-45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
-UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
-O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
-bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
-GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
-77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
-hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
-92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
-Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
-ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
-Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
------END CERTIFICATE-----
-
-# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG
-# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG
-# Label: "SwissSign Silver CA - G2"
-# Serial: 5700383053117599563
-# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13
-# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb
-# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5
------BEGIN CERTIFICATE-----
-MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
-BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
-IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
-RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
-U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
-MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
-Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
-YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
-nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
-6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
-eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
-c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
-MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
-HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
-jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
-5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
-rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
-F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
-wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
-cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
-AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
-WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
-xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
-2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
-IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
-aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
-em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
-dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
-OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
-hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
-tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
-# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
-# Label: "GeoTrust Primary Certification Authority"
-# Serial: 32798226551256963324313806436981982369
-# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf
-# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96
-# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
-MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
-AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
-ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
-7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
-kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
-mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
-KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
-6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
-4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
-oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
-UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
-AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA"
-# Serial: 69529181992039203566298953787712940909
-# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12
-# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81
-# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f
------BEGIN CERTIFICATE-----
-MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
-NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
-LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
-A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
-W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
-3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
-6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
-Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
-NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
-r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
-DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
-YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
-/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
-LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
-jVaMaA==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Class 3 Public Primary Certification Authority - G5"
-# Serial: 33037644167568058970164719475676101450
-# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c
-# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5
-# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df
------BEGIN CERTIFICATE-----
-MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
-nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
-t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
-SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
-BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
-rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
-NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
-BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
-MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
-p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
-5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
-WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
-4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
-hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
------END CERTIFICATE-----
-
-# Issuer: CN=SecureTrust CA O=SecureTrust Corporation
-# Subject: CN=SecureTrust CA O=SecureTrust Corporation
-# Label: "SecureTrust CA"
-# Serial: 17199774589125277788362757014266862032
-# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1
-# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11
-# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73
------BEGIN CERTIFICATE-----
-MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
-MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
-cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
-Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
-0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
-wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
-7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
-8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
-BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
-JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
-NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
-6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
-3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
-D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
-CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
-3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
------END CERTIFICATE-----
-
-# Issuer: CN=Secure Global CA O=SecureTrust Corporation
-# Subject: CN=Secure Global CA O=SecureTrust Corporation
-# Label: "Secure Global CA"
-# Serial: 9751836167731051554232119481456978597
-# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de
-# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b
-# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69
------BEGIN CERTIFICATE-----
-MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
-MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
-Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
-iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
-/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
-jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
-HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
-sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
-gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
-KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
-AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
-URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
-H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
-I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
-iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
-f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
------END CERTIFICATE-----
-
-# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
-# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
-# Label: "COMODO Certification Authority"
-# Serial: 104350513648249232941998508985834464573
-# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
-# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
-# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
-gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
-BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
-MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
-YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
-RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
-UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
-2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
-Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
-+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
-DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
-nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
-/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
-PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
-QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
-SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
-IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
-RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
-zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
-BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
-ZQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
-# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
-# Label: "Network Solutions Certificate Authority"
-# Serial: 116697915152937497490437556386812487904
-# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e
-# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce
-# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c
------BEGIN CERTIFICATE-----
-MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
-MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
-MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
-dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
-UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
-ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
-c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
-OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
-mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
-BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
-qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
-gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
-bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
-dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
-6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
-h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
-/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
-wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
-pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
------END CERTIFICATE-----
-
-# Issuer: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
-# Subject: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
-# Label: "WellsSecure Public Root Certificate Authority"
-# Serial: 1
-# MD5 Fingerprint: 15:ac:a5:c2:92:2d:79:bc:e8:7f:cb:67:ed:02:cf:36
-# SHA1 Fingerprint: e7:b4:f6:9d:61:ec:90:69:db:7e:90:a7:40:1a:3c:f4:7d:4f:e8:ee
-# SHA256 Fingerprint: a7:12:72:ae:aa:a3:cf:e8:72:7f:7f:b3:9f:0f:b3:d1:e5:42:6e:90:60:b0:6e:e6:f1:3e:9a:3c:58:33:cd:43
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
-IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
-cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
-MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
-bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
-DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
-WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
-Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
-HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
-z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
-SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
-AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
-KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
-AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
-BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
-VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
-ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
-ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
-/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
-A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
-k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
-iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
-2G0xffX8oRAHh84vWdw+WNs=
------END CERTIFICATE-----
-
-# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
-# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
-# Label: "COMODO ECC Certification Authority"
-# Serial: 41578283867086692638256921589707938090
-# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
-# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
-# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
------BEGIN CERTIFICATE-----
-MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
-MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
-BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
-IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
-MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
-ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
-T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
-biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
-FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
-cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
-BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
-fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
-GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
------END CERTIFICATE-----
-
-# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
-# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
-# Label: "Security Communication EV RootCA1"
-# Serial: 0
-# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3
-# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d
-# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37
------BEGIN CERTIFICATE-----
-MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
-MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
-IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
-bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
-RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
-zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
-bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
-MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
-VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
-OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
-tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
-q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
-EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
-Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
-VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
------END CERTIFICATE-----
-
-# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
-# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
-# Label: "OISTE WISeKey Global Root GA CA"
-# Serial: 86718877871133159090080555911823548314
-# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93
-# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9
-# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5
------BEGIN CERTIFICATE-----
-MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
-ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
-aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
-ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
-NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
-A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
-VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
-SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
-VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
-w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
-mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
-4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
-4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
-EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
-SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
-ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
-vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
-hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
-Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
-/L7fCg0=
------END CERTIFICATE-----
-
-# Issuer: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
-# Subject: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
-# Label: "Microsec e-Szigno Root CA"
-# Serial: 272122594155480254301341951808045322001
-# MD5 Fingerprint: f0:96:b6:2f:c5:10:d5:67:8e:83:25:32:e8:5e:2e:e5
-# SHA1 Fingerprint: 23:88:c9:d3:71:cc:9e:96:3d:ff:7d:3c:a7:ce:fc:d6:25:ec:19:0d
-# SHA256 Fingerprint: 32:7a:3d:76:1a:ba:de:a0:34:eb:99:84:06:27:5c:b1:a4:77:6e:fd:ae:2f:df:6d:01:68:ea:1c:4f:55:67:d0
------BEGIN CERTIFICATE-----
-MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw
-cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy
-b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z
-ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4
-NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN
-TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p
-Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u
-uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+
-LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA
-vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770
-Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx
-62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB
-AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw
-LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP
-BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB
-AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov
-MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5
-ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
-AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT
-AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh
-ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo
-AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa
-AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln
-bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p
-Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP
-PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv
-Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB
-EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu
-w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj
-cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV
-HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI
-VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS
-BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS
-b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS
-8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds
-ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl
-7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
-86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR
-hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/
-MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
------END CERTIFICATE-----
-
-# Issuer: CN=Certigna O=Dhimyotis
-# Subject: CN=Certigna O=Dhimyotis
-# Label: "Certigna"
-# Serial: 18364802974209362175
-# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff
-# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97
-# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d
------BEGIN CERTIFICATE-----
-MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
-BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
-DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
-BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
-QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
-gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
-zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
-130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
-JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
-ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
-AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
-AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
-9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
-bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
-fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
-HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
-t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
-WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
------END CERTIFICATE-----
-
-# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
-# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
-# Label: "Deutsche Telekom Root CA 2"
-# Serial: 38
-# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08
-# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf
-# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3
------BEGIN CERTIFICATE-----
-MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
-MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
-IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
-IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
-RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
-U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
-IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
-ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
-QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
-rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
-NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
-QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
-txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
-BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
-AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
-tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
-IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
-6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
-xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
-Cm26OWMohpLzGITY+9HPBVZkVw==
------END CERTIFICATE-----
-
-# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc
-# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc
-# Label: "Cybertrust Global Root"
-# Serial: 4835703278459682877484360
-# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1
-# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6
-# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3
------BEGIN CERTIFICATE-----
-MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG
-A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh
-bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE
-ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS
-b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5
-7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS
-J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y
-HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP
-t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz
-FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY
-XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
-MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw
-hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js
-MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA
-A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj
-Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx
-XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o
-omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc
-A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
-WL1WMRJOEcgh4LMRkWXbtKaIOM5V
------END CERTIFICATE-----
-
-# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
-# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
-# Label: "ePKI Root Certification Authority"
-# Serial: 28956088682735189655030529057352760477
-# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3
-# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0
-# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5
------BEGIN CERTIFICATE-----
-MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
-MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
-ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
-IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
-SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
-SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
-ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
-DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
-TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
-fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
-sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
-WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
-nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
-dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
-NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
-AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
-MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
-ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
-uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
-PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
-JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
-gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
-j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
-5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
-o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
-/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
-Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
-W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
-hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
------END CERTIFICATE-----
-
-# Issuer: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
-# Subject: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
-# Label: "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3"
-# Serial: 17
-# MD5 Fingerprint: ed:41:f5:8c:50:c5:2b:9c:73:e6:ee:6c:eb:c2:a8:26
-# SHA1 Fingerprint: 1b:4b:39:61:26:27:6b:64:91:a2:68:6d:d7:02:43:21:2d:1f:1d:96
-# SHA256 Fingerprint: e4:c7:34:30:d7:a5:b5:09:25:df:43:37:0a:0d:21:6e:9a:79:b9:d6:db:83:73:a0:c6:9e:b1:cc:31:c7:c5:2a
------BEGIN CERTIFICATE-----
-MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
-MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
-bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
-VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
-YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
-dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
-ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
-Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
-GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
-aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
-QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
-xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
-aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
-IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
-gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
-O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
-fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
-lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
-hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
-AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
-NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
-wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
-7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
-gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
-oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
-yZyQ2uypQjyttgI=
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327
-# Subject: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327
-# Label: "Buypass Class 2 CA 1"
-# Serial: 1
-# MD5 Fingerprint: b8:08:9a:f0:03:cc:1b:0d:c8:6c:0b:76:a1:75:64:23
-# SHA1 Fingerprint: a0:a1:ab:90:c9:fc:84:7b:3b:12:61:e8:97:7d:5f:d3:22:61:d3:cc
-# SHA256 Fingerprint: 0f:4e:9c:dd:26:4b:02:55:50:d1:70:80:63:40:21:4f:e9:44:34:c9:b0:2f:69:7e:c7:10:fc:5f:ea:fb:5e:38
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
-Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL
-MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
-VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0
-ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX
-l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB
-HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B
-5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3
-WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP
-gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+
-DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu
-BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs
-h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk
-LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
------END CERTIFICATE-----
-
-# Issuer: O=certSIGN OU=certSIGN ROOT CA
-# Subject: O=certSIGN OU=certSIGN ROOT CA
-# Label: "certSIGN ROOT CA"
-# Serial: 35210227249154
-# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17
-# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b
-# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb
------BEGIN CERTIFICATE-----
-MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
-AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
-QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
-MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
-0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
-UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
-RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
-OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
-JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
-AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
-BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
-LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
-MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
-44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
-Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
-i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
-9u6wWk5JRFRYX0KD
------END CERTIFICATE-----
-
-# Issuer: CN=CNNIC ROOT O=CNNIC
-# Subject: CN=CNNIC ROOT O=CNNIC
-# Label: "CNNIC ROOT"
-# Serial: 1228079105
-# MD5 Fingerprint: 21:bc:82:ab:49:c4:13:3b:4b:b2:2b:5c:6b:90:9c:19
-# SHA1 Fingerprint: 8b:af:4c:9b:1d:f0:2a:92:f7:da:12:8e:b9:1b:ac:f4:98:60:4b:6f
-# SHA256 Fingerprint: e2:83:93:77:3d:a8:45:a6:79:f2:08:0c:c7:fb:44:a3:b7:a1:c3:79:2c:b7:eb:77:29:fd:cb:6a:8d:99:ae:a7
------BEGIN CERTIFICATE-----
-MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
-TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
-MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
-Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
-IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
-dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
-V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
-GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
-v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
-AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
-Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
-76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
-OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
-ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
-yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
-buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
-2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
------END CERTIFICATE-----
-
-# Issuer: O=Japanese Government OU=ApplicationCA
-# Subject: O=Japanese Government OU=ApplicationCA
-# Label: "ApplicationCA - Japanese Government"
-# Serial: 49
-# MD5 Fingerprint: 7e:23:4e:5b:a7:a5:b4:25:e9:00:07:74:11:62:ae:d6
-# SHA1 Fingerprint: 7f:8a:b0:cf:d0:51:87:6a:66:f3:36:0f:47:c8:8d:8c:d3:35:fc:74
-# SHA256 Fingerprint: 2d:47:43:7d:e1:79:51:21:5a:12:f3:c5:8e:51:c7:29:a5:80:26:ef:1f:cc:0a:5f:b3:d9:dc:01:2f:60:0d:19
------BEGIN CERTIFICATE-----
-MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
-MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
-b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
-AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
-aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
-j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
-f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
-IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
-FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
-QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
-/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
-k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
-MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
-seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
-hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
-eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
-DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
-B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
-rosot4LKGAfmt1t06SAZf7IbiVQ=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
-# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
-# Label: "GeoTrust Primary Certification Authority - G3"
-# Serial: 28809105769928564313984085209975885599
-# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05
-# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd
-# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4
------BEGIN CERTIFICATE-----
-MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
-BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
-MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
-BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
-+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
-hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
-5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
-JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
-DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
-huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
-AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
-zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
-kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
-SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
-spki4cErx5z481+oghLrGREt
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA - G2"
-# Serial: 71758320672825410020661621085256472406
-# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f
-# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12
-# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57
------BEGIN CERTIFICATE-----
-MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
-IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
-BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
-MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
-d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
-YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
-dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
-BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
-papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
-DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
-KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
-XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA - G3"
-# Serial: 127614157056681299805556476275995414779
-# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31
-# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2
-# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
-Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
-LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
-MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
-ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
-gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
-YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
-b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
-9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
-zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
-OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
-2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
-oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
-KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
-m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
-MdRAGmI0Nj81Aa6sY6A=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
-# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
-# Label: "GeoTrust Primary Certification Authority - G2"
-# Serial: 80682863203381065782177908751794619243
-# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a
-# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0
-# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66
------BEGIN CERTIFICATE-----
-MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
-MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
-KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
-MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
-BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
-NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
-BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
-MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
-So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
-tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
-CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
-qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
-rD6ogRLQy7rQkgu2npaqBA+K
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Universal Root Certification Authority"
-# Serial: 85209574734084581917763752644031726877
-# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19
-# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54
-# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c
------BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
-vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
-ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
-IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
-IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
-bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
-9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
-H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
-LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
-/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
-rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
-WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
-exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
-DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
-sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
-seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
-4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
-BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
-lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
-7M2CYfE45k+XmCpajQ==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Class 3 Public Primary Certification Authority - G4"
-# Serial: 63143484348153506665311985501458640051
-# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41
-# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a
-# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79
------BEGIN CERTIFICATE-----
-MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
-U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
-SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
-biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
-GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
-fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
-AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
-aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
-aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
-kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
-4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
-FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
-# Subject: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
-# Label: "NetLock Arany (Class Gold) Főtanúsítvány"
-# Serial: 80544274841616
-# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88
-# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91
-# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
-EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
-MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
-cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
-dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
-pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
-b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
-IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
-lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
-AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
-VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
-ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
-BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
-AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
-U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
-bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
-+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
-bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
-uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
-XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
------END CERTIFICATE-----
-
-# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
-# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
-# Label: "Staat der Nederlanden Root CA - G2"
-# Serial: 10000012
-# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a
-# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16
-# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f
------BEGIN CERTIFICATE-----
-MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
-DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
-ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
-b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
-qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
-uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
-Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
-pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
-5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
-UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
-GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
-5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
-6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
-eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
-B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
-BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
-L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
-SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
-CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
-5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
-IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
-gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
-+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
-vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
-bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
-N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
-Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
-ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
-# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
-# Label: "Hongkong Post Root CA 1"
-# Serial: 1000
-# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca
-# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58
-# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2
------BEGIN CERTIFICATE-----
-MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
-FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
-Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
-A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
-b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
-jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
-PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
-ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
-nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
-q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
-MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
-mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
-7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
-oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
-EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
-fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
-AmvZWg==
------END CERTIFICATE-----
-
-# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
-# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
-# Label: "SecureSign RootCA11"
-# Serial: 1
-# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26
-# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3
-# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12
------BEGIN CERTIFICATE-----
-MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
-MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
-A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
-MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
-Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
-QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
-i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
-h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
-MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
-UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
-8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
-h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
-VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
-AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
-KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
-X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
-QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
-pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
-QSdJQO7e5iNEOdyhIta6A/I=
------END CERTIFICATE-----
-
-# Issuer: CN=ACEDICOM Root O=EDICOM OU=PKI
-# Subject: CN=ACEDICOM Root O=EDICOM OU=PKI
-# Label: "ACEDICOM Root"
-# Serial: 7029493972724711941
-# MD5 Fingerprint: 42:81:a0:e2:1c:e3:55:10:de:55:89:42:65:96:22:e6
-# SHA1 Fingerprint: e0:b4:32:2e:b2:f6:a5:68:b6:54:53:84:48:18:4a:50:36:87:43:84
-# SHA256 Fingerprint: 03:95:0f:b4:9a:53:1f:3e:19:91:94:23:98:df:a9:e0:ea:32:d7:ba:1c:dd:9b:c8:5d:b5:7e:d9:40:0b:43:4a
------BEGIN CERTIFICATE-----
-MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE
-AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x
-CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW
-MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF
-RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
-AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7
-09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7
-XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P
-Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK
-t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb
-X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28
-MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU
-fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI
-2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH
-K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae
-ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP
-BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ
-MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw
-RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
-bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm
-fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3
-gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe
-I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i
-5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi
-ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn
-MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ
-o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6
-zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN
-GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt
-r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK
-Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==
------END CERTIFICATE-----
-
-# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
-# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
-# Label: "Microsec e-Szigno Root CA 2009"
-# Serial: 14014712776195784473
-# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1
-# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e
-# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78
------BEGIN CERTIFICATE-----
-MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
-VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
-ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
-CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
-OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
-FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
-Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
-dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
-kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
-cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
-fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
-N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
-xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
-+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
-A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
-Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
-SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
-mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
-ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
-tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
-2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
-HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
-# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
-# Label: "GlobalSign Root CA - R3"
-# Serial: 4835703278459759426209954
-# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
-# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
-# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
------BEGIN CERTIFICATE-----
-MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
-MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
-RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
-gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
-KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
-QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
-XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
-LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
-RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
-jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
-6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
-mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
-Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
-WD9f
------END CERTIFICATE-----
-
-# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
-# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
-# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
-# Serial: 6047274297262753887
-# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3
-# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa
-# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef
------BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
-BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
-cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
-MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
-Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
-thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
-cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
-L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
-NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
-X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
-m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
-Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
-EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
-KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
-6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
-OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
-VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
-VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
-cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
-ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
-AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
-661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
-am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
-ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
-PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
-3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
-SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
-3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
-ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
-StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
-Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
-jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
------END CERTIFICATE-----
-
-# Issuer: CN=Izenpe.com O=IZENPE S.A.
-# Subject: CN=Izenpe.com O=IZENPE S.A.
-# Label: "Izenpe.com"
-# Serial: 917563065490389241595536686991402621
-# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73
-# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19
-# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f
------BEGIN CERTIFICATE-----
-MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
-MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
-ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
-VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
-b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
-scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
-xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
-LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
-uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
-yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
-JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
-rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
-BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
-hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
-QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
-HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
-Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
-QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
-BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
-MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
-A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
-laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
-awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
-JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
-LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
-VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
-LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
-UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
-QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
-naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
-QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
------END CERTIFICATE-----
-
-# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
-# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
-# Label: "Chambers of Commerce Root - 2008"
-# Serial: 11806822484801597146
-# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7
-# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c
-# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0
------BEGIN CERTIFICATE-----
-MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
-VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
-IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
-MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
-IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
-MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
-dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
-EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
-MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
-28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
-VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
-DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
-5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
-ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
-Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
-UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
-+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
-Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
-ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
-hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
-HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
-+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
-YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
-L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
-ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
-IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
-HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
-DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
-PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
-5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
-glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
-FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
-pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
-xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
-tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
-jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
-fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
-OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
-d0jQ
------END CERTIFICATE-----
-
-# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
-# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
-# Label: "Global Chambersign Root - 2008"
-# Serial: 14541511773111788494
-# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3
-# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c
-# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca
------BEGIN CERTIFICATE-----
-MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
-VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
-IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
-MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
-aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
-MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
-cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
-A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
-BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
-KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
-G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
-zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
-ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
-HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
-Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
-yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
-beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
-6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
-wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
-zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
-BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
-ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
-ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
-cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
-YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
-CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
-KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
-hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
-UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
-X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
-fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
-a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
-Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
-SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
-AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
-M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
-v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
-09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
------END CERTIFICATE-----
-
-# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
-# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
-# Label: "Go Daddy Root Certificate Authority - G2"
-# Serial: 0
-# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
-# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
-# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
-NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
-AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
-E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
-/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
-DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
-GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
-tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
-AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
-FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
-WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
-9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
-gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
-2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
-LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
-4uJEvlz36hz1
------END CERTIFICATE-----
-
-# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Label: "Starfield Root Certificate Authority - G2"
-# Serial: 0
-# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
-# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
-# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
-ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
-MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
-aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
-Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
-nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
-HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
-Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
-dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
-HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
-CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
-sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
-4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
-8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
-pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
-mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
------END CERTIFICATE-----
-
-# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Label: "Starfield Services Root Certificate Authority - G2"
-# Serial: 0
-# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
-# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
-# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
------BEGIN CERTIFICATE-----
-MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
-ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
-MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
-VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
-ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
-dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
-OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
-8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
-Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
-hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
-6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
-DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
-AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
-bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
-ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
-qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
-iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
-0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
-sSi6
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
-# Subject: CN=AffirmTrust Commercial O=AffirmTrust
-# Label: "AffirmTrust Commercial"
-# Serial: 8608355977964138876
-# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
-# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
-# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
------BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
-Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
-ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
-MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
-yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
-VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
-nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
-XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
-vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
-Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
-N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
-nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Networking O=AffirmTrust
-# Subject: CN=AffirmTrust Networking O=AffirmTrust
-# Label: "AffirmTrust Networking"
-# Serial: 8957382827206547757
-# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
-# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
-# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
------BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
-YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
-kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
-QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
-6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
-yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
-QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
-tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
-QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
-Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
-olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
-x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Premium O=AffirmTrust
-# Subject: CN=AffirmTrust Premium O=AffirmTrust
-# Label: "AffirmTrust Premium"
-# Serial: 7893706540734352110
-# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
-# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
-# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
------BEGIN CERTIFICATE-----
-MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
-dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
-A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
-cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
-qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
-JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
-+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
-s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
-HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
-70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
-V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
-qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
-5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
-C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
-OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
-FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
-KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
-Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
-8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
-MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
-0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
-u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
-u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
-YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
-GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
-RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
-KeC2uAloGRwYQw==
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
-# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
-# Label: "AffirmTrust Premium ECC"
-# Serial: 8401224907861490260
-# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
-# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
-# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
------BEGIN CERTIFICATE-----
-MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
-VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
-cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
-BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
-VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
-0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
-ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
-A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
-aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
-flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
-# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
-# Label: "Certum Trusted Network CA"
-# Serial: 279744
-# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
-# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
-# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
------BEGIN CERTIFICATE-----
-MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
-MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
-ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
-cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
-WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
-Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
-IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
-UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
-TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
-BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
-kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
-AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
-sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
-I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
-J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
-VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
-03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
------END CERTIFICATE-----
-
-# Issuer: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
-# Subject: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
-# Label: "Certinomis - Autorité Racine"
-# Serial: 1
-# MD5 Fingerprint: 7f:30:78:8c:03:e3:ca:c9:0a:e2:c9:ea:1e:aa:55:1a
-# SHA1 Fingerprint: 2e:14:da:ec:28:f0:fa:1e:8e:38:9a:4e:ab:eb:26:c0:0a:d3:83:c3
-# SHA256 Fingerprint: fc:bf:e2:88:62:06:f7:2b:27:59:3c:8b:07:02:97:e1:2d:76:9e:d1:0e:d7:93:07:05:a8:09:8e:ff:c1:4d:17
------BEGIN CERTIFICATE-----
-MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
-MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
-BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
-Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
-cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
-aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
-F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
-8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
-rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
-/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
-7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
-28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
-lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
-nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
-0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
-5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
-WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
-jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
-KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
-ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
-OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
-619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
-2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
-o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
-nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
-5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
-pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
-dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
-BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
------END CERTIFICATE-----
-
-# Issuer: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA
-# Subject: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA
-# Label: "Root CA Generalitat Valenciana"
-# Serial: 994436456
-# MD5 Fingerprint: 2c:8c:17:5e:b1:54:ab:93:17:b5:36:5a:db:d1:c6:f2
-# SHA1 Fingerprint: a0:73:e5:c5:bd:43:61:0d:86:4c:21:13:0a:85:58:57:cc:9c:ea:46
-# SHA256 Fingerprint: 8c:4e:df:d0:43:48:f3:22:96:9e:7e:29:a4:cd:4d:ca:00:46:55:06:1c:16:e1:b0:76:42:2e:f3:42:ad:63:0e
------BEGIN CERTIFICATE-----
-MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF
-UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ
-R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN
-MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G
-A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw
-JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+
-WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj
-SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl
-u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy
-A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk
-Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7
-MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr
-aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC
-IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A
-cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA
-YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA
-bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA
-bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
-aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA
-aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA
-ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA
-YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA
-ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA
-LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6
-Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y
-eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw
-CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G
-A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu
-Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn
-lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt
-b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg
-9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF
-ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC
-IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
------END CERTIFICATE-----
-
-# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
-# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
-# Label: "TWCA Root Certification Authority"
-# Serial: 1
-# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79
-# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48
-# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44
------BEGIN CERTIFICATE-----
-MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
-MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
-V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
-WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
-LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
-AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
-K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
-RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
-rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
-3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
-hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
-MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
-XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
-lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
-aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
-YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
------END CERTIFICATE-----
-
-# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
-# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
-# Label: "Security Communication RootCA2"
-# Serial: 0
-# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43
-# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74
-# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
-DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
-dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
-YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
-OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
-zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
-VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
-hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
-ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
-awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
-OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
-DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
-coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
-okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
-t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
-1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
-SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
------END CERTIFICATE-----
-
-# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
-# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
-# Label: "Hellenic Academic and Research Institutions RootCA 2011"
-# Serial: 0
-# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9
-# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d
-# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71
------BEGIN CERTIFICATE-----
-MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
-RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
-dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
-YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
-NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
-EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
-cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
-c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
-dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
-fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
-bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
-75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
-FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
-HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
-5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
-b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
-A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
-6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
-TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
-dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
-Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
-l7WdmplNsDz4SgCbZN2fOUvRJ9e4
------END CERTIFICATE-----
-
-# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
-# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
-# Label: "Actalis Authentication Root CA"
-# Serial: 6271844772424770508
-# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6
-# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac
-# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66
------BEGIN CERTIFICATE-----
-MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
-BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
-MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
-IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
-SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
-ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
-UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
-4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
-KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
-gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
-rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
-51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
-be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
-KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
-v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
-fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
-jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
-ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
-ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
-e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
-jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
-WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
-SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
-pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
-X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
-fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
-K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
-ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
-LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
-LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
------END CERTIFICATE-----
-
-# Issuer: O=Trustis Limited OU=Trustis FPS Root CA
-# Subject: O=Trustis Limited OU=Trustis FPS Root CA
-# Label: "Trustis FPS Root CA"
-# Serial: 36053640375399034304724988975563710553
-# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d
-# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04
-# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d
------BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
-MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
-ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
-MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
-MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
-AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
-iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
-vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
-0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
-OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
-BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
-FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
-GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
-zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
-1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
-f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
-jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
-ZetX2fNXlrtIzYE=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Label: "StartCom Certification Authority"
-# Serial: 45
-# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16
-# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0
-# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11
------BEGIN CERTIFICATE-----
-MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
-F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
-ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
-ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
-aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
-YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
-c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
-d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
-CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
-wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
-Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
-0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
-pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
-CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
-P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
-1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
-KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
-JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
-8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
-fyWl8kgAwKQB2j8=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd.
-# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd.
-# Label: "StartCom Certification Authority G2"
-# Serial: 59
-# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64
-# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17
-# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95
------BEGIN CERTIFICATE-----
-MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
-OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
-A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
-JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
-vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
-D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
-Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
-RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
-HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
-nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
-0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
-UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
-Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
-TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
-BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
-2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
-UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
-6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
-9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
-HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
-wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
-XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
-IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
-hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
-so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
-# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
-# Label: "Buypass Class 2 Root CA"
-# Serial: 2
-# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29
-# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99
-# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
-Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
-TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
-HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
-BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
-6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
-L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
-1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
-MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
-QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
-arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
-Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
-FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
-P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
-9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
-uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
-9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
-A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
-OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
-+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
-KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
-DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
-H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
-I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
-5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
-3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
-Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
-# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
-# Label: "Buypass Class 3 Root CA"
-# Serial: 2
-# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec
-# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57
-# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
-Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
-TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
-HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
-BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
-ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
-N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
-tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
-0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
-/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
-KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
-zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
-O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
-34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
-K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
-Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
-QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
-cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
-IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
-HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
-O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
-033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
-dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
-kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
-3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
-u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
-4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
------END CERTIFICATE-----
-
-# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
-# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
-# Label: "T-TeleSec GlobalRoot Class 3"
-# Serial: 1
-# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef
-# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1
-# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd
------BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
-KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
-BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
-YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
-OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
-aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
-ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
-8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
-RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
-hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
-ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
-EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
-QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
-A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
-WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
-1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
-6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
-91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
-e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
-TpPDpFQUWw==
------END CERTIFICATE-----
-
-# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
-# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
-# Label: "EE Certification Centre Root CA"
-# Serial: 112324828676200291871926431888494945866
-# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f
-# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7
-# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76
------BEGIN CERTIFICATE-----
-MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
-MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
-czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
-CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
-MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
-ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
-b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
-euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
-bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
-WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
-MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
-1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
-VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
-zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
-BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
-BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
-v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
-E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
-uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
-iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
-GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
------END CERTIFICATE-----
-
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
-# Label: "TURKTRUST Certificate Services Provider Root 2007"
-# Serial: 1
-# MD5 Fingerprint: 2b:70:20:56:86:82:a0:18:c8:07:53:12:28:70:21:72
-# SHA1 Fingerprint: f1:7f:6f:b6:31:dc:99:e3:a3:c8:7f:fe:1c:f1:81:10:88:d9:60:33
-# SHA256 Fingerprint: 97:8c:d9:66:f2:fa:a0:7b:a7:aa:95:00:d9:c0:2e:9d:77:f2:cd:ad:a6:ad:6b:a7:4a:f4:b9:1c:66:59:3c:50
------BEGIN CERTIFICATE-----
-MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc
-UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS
-S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
-SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx
-OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry
-b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC
-VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE
-sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F
-ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY
-KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG
-+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG
-HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P
-IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M
-733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk
-Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW
-AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
-aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5
-mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa
-XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ
-qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
------END CERTIFICATE-----
-
-# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
-# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
-# Label: "D-TRUST Root Class 3 CA 2 2009"
-# Serial: 623603
-# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f
-# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0
-# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1
------BEGIN CERTIFICATE-----
-MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
-ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
-HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
-UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
-tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
-ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
-lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
-/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
-A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
-A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
-dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
-MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
-cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
-L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
-BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
-acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
-o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
-zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
-PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
-Johw1+qRzT65ysCQblrGXnRl11z+o+I=
------END CERTIFICATE-----
-
-# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
-# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
-# Label: "D-TRUST Root Class 3 CA 2 EV 2009"
-# Serial: 623604
-# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6
-# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83
-# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
-NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
-BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
-ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
-3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
-qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
-p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
-HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
-ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
-HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
-Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
-c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
-RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
-dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
-Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
-3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
-nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
-CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
-xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
-KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
------END CERTIFICATE-----
-
-# Issuer: CN=Autoridad de Certificacion Raiz del Estado Venezolano O=Sistema Nacional de Certificacion Electronica OU=Superintendencia de Servicios de Certificacion Electronica
-# Subject: CN=PSCProcert O=Sistema Nacional de Certificacion Electronica OU=Proveedor de Certificados PROCERT
-# Label: "PSCProcert"
-# Serial: 11
-# MD5 Fingerprint: e6:24:e9:12:01:ae:0c:de:8e:85:c4:ce:a3:12:dd:ec
-# SHA1 Fingerprint: 70:c1:8d:74:b4:28:81:0a:e4:fd:a5:75:d7:01:9f:99:b0:3d:50:74
-# SHA256 Fingerprint: 3c:fc:3c:14:d1:f6:84:ff:17:e3:8c:43:ca:44:0c:00:b9:67:ec:93:3e:8b:fe:06:4c:a1:d7:2c:90:f2:ad:b0
------BEGIN CERTIFICATE-----
-MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1
-dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
-YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
-dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
-aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
-IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
-KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw
-MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy
-b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx
-KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG
-A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u
-aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9
-7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74
-BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G
-ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9
-JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0
-PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2
-0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
-0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/
-6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m
-v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7
-K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev
-bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw
-MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w
-MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD
-gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0
-b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh
-bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0
-cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp
-ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg
-ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq
-hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD
-AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w
-MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag
-RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t
-UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl
-cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
-Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG
-AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN
-AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS
-1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB
-3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv
-Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh
-HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm
-pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz
-sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE
-qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb
-mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9
-opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H
-YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
------END CERTIFICATE-----
-
-# Issuer: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
-# Subject: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
-# Label: "China Internet Network Information Center EV Certificates Root"
-# Serial: 1218379777
-# MD5 Fingerprint: 55:5d:63:00:97:bd:6a:97:f5:67:ab:4b:fb:6e:63:15
-# SHA1 Fingerprint: 4f:99:aa:93:fb:2b:d1:37:26:a1:99:4a:ce:7f:f0:05:f2:93:5d:1e
-# SHA256 Fingerprint: 1c:01:c6:f4:db:b2:fe:fc:22:55:8b:2b:ca:32:56:3f:49:84:4a:cf:c3:2b:7b:e4:b0:ff:59:9f:9e:8c:7a:f7
------BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
-Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
-Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
-aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
-Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
-SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
-aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
-ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
-7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
-DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
-zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
-hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
-4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
-gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
-NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
-FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
-j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
-52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
-echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
-ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
-zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
-wy39FCqQmbkHzJ8=
------END CERTIFICATE-----
-
-# Issuer: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
-# Subject: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
-# Label: "Swisscom Root CA 2"
-# Serial: 40698052477090394928831521023204026294
-# MD5 Fingerprint: 5b:04:69:ec:a5:83:94:63:18:a7:86:d0:e4:f2:6e:19
-# SHA1 Fingerprint: 77:47:4f:c6:30:e4:0f:4c:47:64:3f:84:ba:b8:c6:95:4a:8a:41:ec
-# SHA256 Fingerprint: f0:9b:12:2c:71:14:f4:a0:9b:d4:ea:4f:4a:99:d5:58:b4:6e:4c:25:cd:81:14:0d:29:c0:56:13:91:4c:38:41
------BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
-MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
-Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
-AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
-Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
-jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
-0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
-2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
-ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
-y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
-tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
-6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
-uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
-acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
-k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
-VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
-FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
-BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
-b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
-fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
-/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
-REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
-srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
-aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
-woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
-Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
-t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
-8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
-9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
-wSsSnqaeG8XmDtkx2Q==
------END CERTIFICATE-----
-
-# Issuer: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
-# Subject: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
-# Label: "Swisscom Root EV CA 2"
-# Serial: 322973295377129385374608406479535262296
-# MD5 Fingerprint: 7b:30:34:9f:dd:0a:4b:6b:35:ca:31:51:28:5d:ae:ec
-# SHA1 Fingerprint: e7:a1:90:29:d3:d5:52:dc:0d:0f:c6:92:d3:ea:88:0d:15:2e:1a:6b
-# SHA256 Fingerprint: d9:5f:ea:3c:a4:ee:dc:e7:4c:d7:6e:75:fc:6d:1f:f6:2c:44:1f:0f:a8:bc:77:f0:34:b1:9e:5d:b2:58:01:5d
------BEGIN CERTIFICATE-----
-MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
-ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
-dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
-IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
-VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
-dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
-MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
-UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
-1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
-oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
-HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
-5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
-idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
-OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
-NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
-46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
-UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
-7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
-A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
-MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
-bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
-XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
-PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
-Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
-WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
-Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
-7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
-nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
-vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
-WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
-fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
-I+2ksx0WckNLIOFZfsLorSa/ovc=
------END CERTIFICATE-----
-
-# Issuer: CN=CA Disig Root R1 O=Disig a.s.
-# Subject: CN=CA Disig Root R1 O=Disig a.s.
-# Label: "CA Disig Root R1"
-# Serial: 14052245610670616104
-# MD5 Fingerprint: be:ec:11:93:9a:f5:69:21:bc:d7:c1:c0:67:89:cc:2a
-# SHA1 Fingerprint: 8e:1c:74:f8:a6:20:b9:e5:8a:f4:61:fa:ec:2b:47:56:51:1a:52:c6
-# SHA256 Fingerprint: f9:6f:23:f4:c3:e7:9c:07:7a:46:98:8d:5a:f5:90:06:76:a0:f0:39:cb:64:5d:d1:75:49:b2:16:c8:24:40:ce
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
-MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
-D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
-OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
-fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
-IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
-oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
-/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
-rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
-3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
-7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
-yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
-qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
-hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
-xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
-SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
-HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
-emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
-AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
-7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
-DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
-F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
-a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
-Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
------END CERTIFICATE-----
-
-# Issuer: CN=CA Disig Root R2 O=Disig a.s.
-# Subject: CN=CA Disig Root R2 O=Disig a.s.
-# Label: "CA Disig Root R2"
-# Serial: 10572350602393338211
-# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03
-# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71
-# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
-MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
-NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
-PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
-x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
-QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
-yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
-QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
-H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
-QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
-i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
-nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
-rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
-hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
-tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
-GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
-lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
-+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
-TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
-nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
-gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
-G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
-zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
-L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
------END CERTIFICATE-----
-
-# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
-# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
-# Label: "ACCVRAIZ1"
-# Serial: 6828503384748696800
-# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02
-# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17
-# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13
------BEGIN CERTIFICATE-----
-MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
-AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
-CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
-BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
-VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
-qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
-HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
-G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
-lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
-IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
-0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
-k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
-4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
-m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
-cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
-uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
-KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
-ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
-AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
-VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
-VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
-CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
-cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
-QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
-7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
-cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
-QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
-czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
-aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
-aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
-DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
-BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
-D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
-JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
-AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
-vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
-tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
-7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
-I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
-h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
-d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
-pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
------END CERTIFICATE-----
-
-# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
-# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
-# Label: "TWCA Global Root CA"
-# Serial: 3262
-# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96
-# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65
-# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b
------BEGIN CERTIFICATE-----
-MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
-EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
-VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
-NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
-B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
-10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
-0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
-MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
-zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
-46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
-yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
-laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
-oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
-BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
-qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
-4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
-1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
-LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
-H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
-RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
-nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
-15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
-6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
-nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
-wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
-aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
-KwbQBM0=
------END CERTIFICATE-----
-
-# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera
-# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera
-# Label: "TeliaSonera Root CA v1"
-# Serial: 199041966741090107964904287217786801558
-# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c
-# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37
-# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89
------BEGIN CERTIFICATE-----
-MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
-NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
-b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
-VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
-VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
-7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
-Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
-/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
-81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
-dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
-Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
-sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
-pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
-slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
-arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
-VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
-9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
-dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
-0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
-TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
-Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
-Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
-OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
-vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
-t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
-HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
-SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
------END CERTIFICATE-----
-
-# Issuer: CN=E-Tugra Certification Authority O=E-TuÄŸra EBG BiliÅŸim Teknolojileri ve Hizmetleri A.Åž. OU=E-Tugra Sertifikasyon Merkezi
-# Subject: CN=E-Tugra Certification Authority O=E-TuÄŸra EBG BiliÅŸim Teknolojileri ve Hizmetleri A.Åž. OU=E-Tugra Sertifikasyon Merkezi
-# Label: "E-Tugra Certification Authority"
-# Serial: 7667447206703254355
-# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49
-# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39
-# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c
------BEGIN CERTIFICATE-----
-MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
-BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
-aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
-BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
-Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
-MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
-BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
-em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
-ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
-B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
-D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
-Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
-q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
-k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
-fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
-dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
-ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
-zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
-rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
-U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
-Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
-XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
-Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
-HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
-GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
-77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
-+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
-vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
-FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
-yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
-AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
-y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
-NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
------END CERTIFICATE-----
-
-# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
-# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
-# Label: "T-TeleSec GlobalRoot Class 2"
-# Serial: 1
-# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a
-# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9
-# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52
------BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
-KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
-BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
-YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
-OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
-aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
-ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
-AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
-FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
-1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
-jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
-wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
-QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
-WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
-NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
-uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
-IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
-g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
-9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
-BSeOE6Fuwg==
------END CERTIFICATE-----
-
-# Issuer: CN=Atos TrustedRoot 2011 O=Atos
-# Subject: CN=Atos TrustedRoot 2011 O=Atos
-# Label: "Atos TrustedRoot 2011"
-# Serial: 6643877497813316402
-# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56
-# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21
-# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
-AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
-EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
-FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
-REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
-Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
-VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
-SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
-4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
-cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
-eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
-HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
-A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
-DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
-vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
-DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
-maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
-lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
-KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 1 G3"
-# Serial: 687049649626669250736271037606554624078720034195
-# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab
-# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67
-# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74
------BEGIN CERTIFICATE-----
-MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
-BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
-BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
-MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
-wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
-rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
-68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
-4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
-UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
-abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
-3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
-KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
-hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
-Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
-zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
-ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
-MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
-cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
-qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
-YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
-b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
-8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
-NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
-ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
-q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
-nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 2 G3"
-# Serial: 390156079458959257446133169266079962026824725800
-# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06
-# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36
-# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40
------BEGIN CERTIFICATE-----
-MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
-BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
-BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
-MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
-qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
-n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
-c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
-O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
-o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
-IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
-IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
-8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
-vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
-7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
-cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
-ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
-AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
-roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
-W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
-lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
-+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
-csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
-dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
-KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
-HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
-WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 3 G3"
-# Serial: 268090761170461462463995952157327242137089239581
-# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7
-# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d
-# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46
------BEGIN CERTIFICATE-----
-MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
-BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
-BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
-MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
-/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
-FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
-U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
-ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
-FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
-A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
-eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
-sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
-VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
-A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
-ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
-ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
-KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
-FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
-oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
-u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
-0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
-3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
-8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
-DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
-PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
-ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Assured ID Root G2"
-# Serial: 15385348160840213938643033620894905419
-# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d
-# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f
-# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85
------BEGIN CERTIFICATE-----
-MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
-b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
-cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
-n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
-biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
-EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
-bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
-YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
-AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
-BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
-QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
-0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
-lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
-B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
-ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
-IhNzbM8m9Yop5w==
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Assured ID Root G3"
-# Serial: 15459312981008553731928384953135426796
-# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb
-# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89
-# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2
------BEGIN CERTIFICATE-----
-MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
-CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
-ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
-RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
-UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
-Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
-hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
-Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
-RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
-AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
-JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
-6pZjamVFkpUBtA==
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Global Root G2"
-# Serial: 4293743540046975378534879503202253541
-# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
-# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
-# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
------BEGIN CERTIFICATE-----
-MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
-MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
-2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
-1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
-q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
-tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
-vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
-BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
-5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
-1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
-NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
-Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
-8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
-pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
-MrY=
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Global Root G3"
-# Serial: 7089244469030293291760083333884364146
-# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
-# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
-# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
------BEGIN CERTIFICATE-----
-MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
-CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
-ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
-Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
-EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
-IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
-K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
-fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
-Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
-BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
-AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
-oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
-sycX
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Trusted Root G4"
-# Serial: 7451500558977370777930084869016614236
-# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49
-# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4
-# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88
------BEGIN CERTIFICATE-----
-MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
-RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
-UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
-Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
-ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
-xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
-ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
-DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
-jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
-CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
-EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
-fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
-uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
-chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
-9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
-ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
-SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
-+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
-fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
-sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
-cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
-0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
-4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
-r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
-/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
-gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
------END CERTIFICATE-----
-
-# Issuer: CN=Certification Authority of WoSign O=WoSign CA Limited
-# Subject: CN=Certification Authority of WoSign O=WoSign CA Limited
-# Label: "WoSign"
-# Serial: 125491772294754854453622855443212256657
-# MD5 Fingerprint: a1:f2:f9:b5:d2:c8:7a:74:b8:f3:05:f1:d7:e1:84:8d
-# SHA1 Fingerprint: b9:42:94:bf:91:ea:8f:b6:4b:e6:10:97:c7:fb:00:13:59:b6:76:cb
-# SHA256 Fingerprint: 4b:22:d5:a6:ae:c9:9f:3c:db:79:aa:5e:c0:68:38:47:9c:d5:ec:ba:71:64:f7:f2:2d:c1:d6:5f:63:d8:57:08
------BEGIN CERTIFICATE-----
-MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
-BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
-MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
-b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN
-rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U
-fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc
-f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2
-ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M
-x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR
-aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch
-zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar
-uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K
-mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA
-Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv
-HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H
-EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
-LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ
-MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e
-JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN
-g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp
-dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab
-R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ
-PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce
-xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+
-J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl
-OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT
-ee5Ehr7XHuQe+w==
------END CERTIFICATE-----
-
-# Issuer: CN=CA 沃通根è¯ä¹¦ O=WoSign CA Limited
-# Subject: CN=CA 沃通根è¯ä¹¦ O=WoSign CA Limited
-# Label: "WoSign China"
-# Serial: 106921963437422998931660691310149453965
-# MD5 Fingerprint: 78:83:5b:52:16:76:c4:24:3b:83:78:e8:ac:da:9a:93
-# SHA1 Fingerprint: 16:32:47:8d:89:f9:21:3a:92:00:85:63:f5:a4:a7:d3:12:40:8a:d6
-# SHA256 Fingerprint: d6:f0:34:bd:94:aa:23:3f:02:97:ec:a4:24:5b:28:39:73:e4:47:aa:59:0f:31:0c:77:f4:8f:df:83:11:22:54
------BEGIN CERTIFICATE-----
-MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV
-BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw
-MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl
-ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r
-D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1
-9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf
-v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk
-UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L
-NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb
-+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V
-qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K
-yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G
-AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK
-J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC
-AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4
-WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
-yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj
-/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6
-jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2
-ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX
-X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n
-FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D
-u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l
-O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le
-ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1
-2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ==
------END CERTIFICATE-----
-
-# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited
-# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited
-# Label: "COMODO RSA Certification Authority"
-# Serial: 101909084537582093308941363524873193117
-# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18
-# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4
-# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34
------BEGIN CERTIFICATE-----
-MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
-hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
-BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
-MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
-EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
-Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
-6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
-pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
-9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
-/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
-Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
-+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
-qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
-SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
-u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
-Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
-crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
-FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
-/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
-wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
-4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
-2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
-FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
-CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
-boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
-jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
-S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
-QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
-0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
-NVOFBkpdn627G190
------END CERTIFICATE-----
-
-# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
-# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
-# Label: "USERTrust RSA Certification Authority"
-# Serial: 2645093764781058787591871645665788717
-# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
-# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
-# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
------BEGIN CERTIFICATE-----
-MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
-iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
-cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
-BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
-MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
-BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
-aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
-dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
-3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
-tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
-Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
-VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
-79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
-c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
-Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
-c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
-UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
-Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
-BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
-A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
-Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
-VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
-ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
-8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
-iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
-Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
-XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
-qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
-VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
-L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
-jjxDah2nGN59PRbxYvnKkKj9
------END CERTIFICATE-----
-
-# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
-# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
-# Label: "USERTrust ECC Certification Authority"
-# Serial: 123013823720199481456569720443997572134
-# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1
-# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0
-# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a
------BEGIN CERTIFICATE-----
-MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
-MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
-eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
-JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
-MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
-Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
-VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
-I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
-o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
-A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
-zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
-RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
-# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
-# Label: "GlobalSign ECC Root CA - R4"
-# Serial: 14367148294922964480859022125800977897474
-# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e
-# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb
-# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c
------BEGIN CERTIFICATE-----
-MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
-MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
-bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
-DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
-QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
-FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
-uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
-kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
-ewv4n4Q=
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
-# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
-# Label: "GlobalSign ECC Root CA - R5"
-# Serial: 32785792099990507226680698011560947931244
-# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08
-# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa
-# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24
------BEGIN CERTIFICATE-----
-MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
-MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
-bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
-DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
-QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
-MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
-8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
-hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
-KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
-515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
-xwy8p2Fp8fc74SrL+SvzZpA3
------END CERTIFICATE-----
-
-# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden
-# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden
-# Label: "Staat der Nederlanden Root CA - G3"
-# Serial: 10003001
-# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37
-# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc
-# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28
------BEGIN CERTIFICATE-----
-MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX
-DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
-ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
-b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP
-cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW
-IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX
-xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy
-KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR
-9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az
-5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8
-6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7
-Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP
-bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt
-BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt
-XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF
-MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd
-INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
-U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp
-LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8
-Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp
-gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh
-/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw
-0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A
-fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq
-4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR
-1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/
-QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM
-94B7IWcnMFk=
------END CERTIFICATE-----
-
-# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden
-# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden
-# Label: "Staat der Nederlanden EV Root CA"
-# Serial: 10000013
-# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba
-# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb
-# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a
------BEGIN CERTIFICATE-----
-MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y
-MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg
-TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS
-b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS
-M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC
-UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d
-Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p
-rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l
-pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb
-j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC
-KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS
-/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X
-cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH
-1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP
-px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
-/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7
-MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
-eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u
-2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS
-v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC
-wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy
-CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e
-vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6
-Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa
-Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL
-eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8
-FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc
-7uzXLg==
------END CERTIFICATE-----
-
-# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
-# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
-# Label: "IdenTrust Commercial Root CA 1"
-# Serial: 13298821034946342390520003877796839426
-# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7
-# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25
-# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae
------BEGIN CERTIFICATE-----
-MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
-MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
-VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
-MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
-JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
-3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
-+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
-S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
-bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
-T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
-vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
-Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
-dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
-c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
-l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
-iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
-ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
-6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
-LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
-nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
-+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
-W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
-AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
-l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
-4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
-mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
-7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
------END CERTIFICATE-----
-
-# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
-# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
-# Label: "IdenTrust Public Sector Root CA 1"
-# Serial: 13298821034946342390521976156843933698
-# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba
-# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd
-# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f
------BEGIN CERTIFICATE-----
-MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
-MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
-VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
-MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
-MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
-ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
-RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
-bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
-/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
-3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
-EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
-9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
-GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
-2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
-WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
-W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
-AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
-t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
-DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
-TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
-lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
-mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
-WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
-+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
-tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
-GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
-8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
-# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
-# Label: "Entrust Root Certification Authority - G2"
-# Serial: 1246989352
-# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2
-# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4
-# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39
------BEGIN CERTIFICATE-----
-MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
-cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
-IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
-dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
-NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
-dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
-dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
-aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
-RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
-cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
-wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
-U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
-jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
-BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
-jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
-Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
-1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
-nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
-VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
-# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
-# Label: "Entrust Root Certification Authority - EC1"
-# Serial: 51543124481930649114116133369
-# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc
-# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47
-# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5
------BEGIN CERTIFICATE-----
-MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
-d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
-dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
-RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
-MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
-VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
-L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
-Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
-A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
-ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
-Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
-R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
-hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
------END CERTIFICATE-----
-
-# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority
-# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority
-# Label: "CFCA EV ROOT"
-# Serial: 407555286
-# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30
-# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83
-# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd
------BEGIN CERTIFICATE-----
-MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
-TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
-MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
-aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
-T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
-sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
-TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
-/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
-7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
-EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
-hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
-a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
-aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
-TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
-PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
-cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
-tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
-BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
-ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
-ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
-jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
-ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
-P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
-xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
-Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
-5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
-/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
-AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
-5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
------END CERTIFICATE-----
-
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-# Serial: 156233699172481
-# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e
-# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb
-# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78
------BEGIN CERTIFICATE-----
-MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE
-BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn
-aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg
-QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg
-SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0
-MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD
-VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
-dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom
-/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR
-Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3
-4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z
-5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0
-hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID
-AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX
-SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l
-VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
-URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf
-peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF
-Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW
-+qtB4Uu2NQvAmxU=
------END CERTIFICATE-----
-
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6"
-# Serial: 138134509972618
-# MD5 Fingerprint: f8:c5:ee:2a:6b:be:95:8d:08:f7:25:4a:ea:71:3e:46
-# SHA1 Fingerprint: 8a:5c:8c:ee:a5:03:e6:05:56:ba:d8:1b:d4:f6:c9:b0:ed:e5:2f:e0
-# SHA256 Fingerprint: 8d:e7:86:55:e1:be:7f:78:47:80:0b:93:f6:94:d2:1d:36:8c:c0:6e:03:3e:7f:ab:04:bb:5e:b9:9d:a6:b7:00
------BEGIN CERTIFICATE-----
-MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQG
-EwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdp
-IMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBB
-LsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBI
-aXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5MDQxMFoXDTIzMTIx
-NjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBLBgNV
-BAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2
-ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVs
-ZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdsGjW6L0UlqMACprx9MfMkU1x
-eHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a2uqsxgbPJQ1BgfbBOCK9
-+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EEDwnS3/faA
-z1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0p
-u5FbHH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6p
-lVxiSvgNZ1GpryHV+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMB
-AAGjQjBAMB0GA1UdDgQWBBTdVRcT9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8E
-BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb1gNl0Oq
-FlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3RfdCaqaXKGDsC
-QC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy
-o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKID
-gI6tflEATseWhvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm
-9ocJV612ph1jmv3XZch4gyt1O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsG
-tAuYSyher4hYyw==
------END CERTIFICATE-----
-
-# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
-# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
-# Label: "Certinomis - Root CA"
-# Serial: 1
-# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f
-# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8
-# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58
------BEGIN CERTIFICATE-----
-MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET
-MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb
-BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz
-MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx
-FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g
-Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2
-fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl
-LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV
-WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF
-TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb
-5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc
-CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri
-wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ
-wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG
-m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4
-F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng
-WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0
-2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
-AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/
-0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw
-F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS
-g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj
-qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN
-h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/
-ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V
-btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj
-Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ
-8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW
-gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE=
------END CERTIFICATE-----
-
-# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
-# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
-# Label: "OISTE WISeKey Global Root GB CA"
-# Serial: 157768595616588414422159278966750757568
-# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d
-# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed
-# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6
------BEGIN CERTIFICATE-----
-MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
-MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
-Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
-YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
-CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
-b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
-bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
-HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
-WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
-1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
-u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
-99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
-M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
-BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
-cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
-gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
-ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
-aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
-Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
------END CERTIFICATE-----
-
-# Issuer: CN=Certification Authority of WoSign G2 O=WoSign CA Limited
-# Subject: CN=Certification Authority of WoSign G2 O=WoSign CA Limited
-# Label: "Certification Authority of WoSign G2"
-# Serial: 142423943073812161787490648904721057092
-# MD5 Fingerprint: c8:1c:7d:19:aa:cb:71:93:f2:50:f8:52:a8:1e:ba:60
-# SHA1 Fingerprint: fb:ed:dc:90:65:b7:27:20:37:bc:55:0c:9c:56:de:bb:f2:78:94:e1
-# SHA256 Fingerprint: d4:87:a5:6f:83:b0:74:82:e8:5e:96:33:94:c1:ec:c2:c9:e5:1d:09:03:ee:94:6b:02:c3:01:58:1e:d9:9e:16
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBY
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNV
-BAMTJENlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDEx
-MDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgxCzAJBgNVBAYTAkNOMRowGAYDVQQK
-ExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPX
-JYY1kBaiXW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgO
-gHzKtB0TiGsOqCR3A9DuW/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg
-5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg95k4ot+vElbGs/V6r+kHLXZ1L3PR8du9n
-fwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BKv0mUYQs4kI9dJGwlezt5
-2eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJ
-KoZIhvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8
-fHulwqZm46qwtyeYP0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G
-3CE4Q3RM+zD4F3LBMvzIkRfEzFg3TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yy
-SrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu+sif/a+RZQp4OBXllxcU3fng
-LDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+7Q9LGOHSJDy7
-XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg=
------END CERTIFICATE-----
-
-# Issuer: CN=CA WoSign ECC Root O=WoSign CA Limited
-# Subject: CN=CA WoSign ECC Root O=WoSign CA Limited
-# Label: "CA WoSign ECC Root"
-# Serial: 138625735294506723296996289575837012112
-# MD5 Fingerprint: 80:c6:53:ee:61:82:28:72:f0:ff:21:b9:17:ca:b2:20
-# SHA1 Fingerprint: d2:7a:d2:be:ed:94:c0:a1:3c:c7:25:21:ea:5d:71:be:81:19:f3:2b
-# SHA256 Fingerprint: 8b:45:da:1c:06:f7:91:eb:0c:ab:f2:6b:e5:88:f5:fb:23:16:5c:2e:61:4b:f8:85:56:2d:0d:ce:50:b2:9b:02
------BEGIN CERTIFICATE-----
-MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQsw
-CQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMT
-EkNBIFdvU2lnbiBFQ0MgUm9vdDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4
-NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEb
-MBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACID
-YgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiUt5v8
-KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES
-1ns2o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
-FgQUqv3VWqP2h4syhf3RMluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB
-1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0Daupn75OcsqF1NnstTJFGG+rrQIwfcf3
-aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYua/GRspBl9JrmkO5K
------END CERTIFICATE-----
-
-# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
-# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
-# Label: "SZAFIR ROOT CA2"
-# Serial: 357043034767186914217277344587386743377558296292
-# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99
-# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de
-# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe
------BEGIN CERTIFICATE-----
-MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
-BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
-ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
-NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
-cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg
-Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN
-QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT
-3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw
-3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6
-3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5
-BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN
-XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF
-AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw
-8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG
-nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
-oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
-d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
-LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
------END CERTIFICATE-----
-
-# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
-# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
-# Label: "Certum Trusted Network CA 2"
-# Serial: 44979900017204383099463764357512596969
-# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2
-# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92
-# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04
------BEGIN CERTIFICATE-----
-MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
-gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
-QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
-A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
-OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
-VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
-b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
-DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
-0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
-OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
-fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
-Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
-o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
-sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
-OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
-Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
-adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
-3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
-AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
-F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
-CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
-XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
-djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
-WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
-AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
-P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
-b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
-XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
-5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
-DrW5viSP
------END CERTIFICATE-----
-
-# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
-# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
-# Label: "Hellenic Academic and Research Institutions RootCA 2015"
-# Serial: 0
-# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce
-# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6
-# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36
------BEGIN CERTIFICATE-----
-MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix
-DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k
-IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT
-N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v
-dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG
-A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh
-ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx
-QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
-dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA
-4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0
-AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10
-4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C
-ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV
-9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD
-gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6
-Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq
-NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko
-LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
-Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd
-ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I
-XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI
-M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot
-9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V
-Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea
-j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh
-X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ
-l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf
-bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4
-pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK
-e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0
-vm9qp/UsQu0yrbYhnr68
------END CERTIFICATE-----
-
-# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
-# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
-# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015"
-# Serial: 0
-# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef
-# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66
-# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33
------BEGIN CERTIFICATE-----
-MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN
-BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
-c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl
-bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv
-b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ
-BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj
-YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5
-MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0
-dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg
-QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa
-jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi
-C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep
-lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof
-TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
------END CERTIFICATE-----
-
-# Issuer: CN=Certplus Root CA G1 O=Certplus
-# Subject: CN=Certplus Root CA G1 O=Certplus
-# Label: "Certplus Root CA G1"
-# Serial: 1491911565779898356709731176965615564637713
-# MD5 Fingerprint: 7f:09:9c:f7:d9:b9:5c:69:69:56:d5:37:3e:14:0d:42
-# SHA1 Fingerprint: 22:fd:d0:b7:fd:a2:4e:0d:ac:49:2c:a0:ac:a6:7b:6a:1f:e3:f7:66
-# SHA256 Fingerprint: 15:2a:40:2b:fc:df:2c:d5:48:05:4d:22:75:b3:9c:7f:ca:3e:c0:97:80:78:b0:f0:ea:76:e5:61:a6:c7:43:3e
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA
-MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy
-dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa
-MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy
-dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a
-iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt
-6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP
-0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f
-6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE
-EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN
-1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc
-h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT
-mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV
-4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO
-WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud
-DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd
-Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq
-hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
-66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7
-/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS
-S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j
-2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R
-Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr
-RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy
-6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV
-V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5
-g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl
-++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
------END CERTIFICATE-----
-
-# Issuer: CN=Certplus Root CA G2 O=Certplus
-# Subject: CN=Certplus Root CA G2 O=Certplus
-# Label: "Certplus Root CA G2"
-# Serial: 1492087096131536844209563509228951875861589
-# MD5 Fingerprint: a7:ee:c4:78:2d:1b:ee:2d:b9:29:ce:d6:a7:96:32:31
-# SHA1 Fingerprint: 4f:65:8e:1f:e9:06:d8:28:02:e9:54:47:41:c9:54:25:5d:69:cc:1a
-# SHA256 Fingerprint: 6c:c0:50:41:e6:44:5e:74:69:6c:4c:fb:c9:f8:0f:54:3b:7e:ab:bb:44:b4:ce:6f:78:7c:6a:99:71:c4:2f:17
------BEGIN CERTIFICATE-----
-MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x
-CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs
-dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x
-CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs
-dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat
-93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x
-Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P
-AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj
-FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG
-SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch
-p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal
-U5ORGpOucGpnutee5WEaXw==
------END CERTIFICATE-----
-
-# Issuer: CN=OpenTrust Root CA G1 O=OpenTrust
-# Subject: CN=OpenTrust Root CA G1 O=OpenTrust
-# Label: "OpenTrust Root CA G1"
-# Serial: 1492036577811947013770400127034825178844775
-# MD5 Fingerprint: 76:00:cc:81:29:cd:55:5e:88:6a:7a:2e:f7:4d:39:da
-# SHA1 Fingerprint: 79:91:e8:34:f7:e2:ee:dd:08:95:01:52:e9:55:2d:14:e9:58:d5:7e
-# SHA256 Fingerprint: 56:c7:71:28:d9:8c:18:d9:1b:4c:fd:ff:bc:25:ee:91:03:d4:75:8e:a2:ab:ad:82:6a:90:f3:45:7d:46:0e:b4
------BEGIN CERTIFICATE-----
-MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA
-MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
-ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw
-MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
-T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b
-wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX
-/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0
-77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP
-uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx
-p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx
-Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2
-TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W
-G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw
-vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY
-EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1
-2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw
-DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
-PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf
-gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS
-FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0
-V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P
-XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I
-i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t
-TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91
-09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky
-Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ
-AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj
-1oxx
------END CERTIFICATE-----
-
-# Issuer: CN=OpenTrust Root CA G2 O=OpenTrust
-# Subject: CN=OpenTrust Root CA G2 O=OpenTrust
-# Label: "OpenTrust Root CA G2"
-# Serial: 1492012448042702096986875987676935573415441
-# MD5 Fingerprint: 57:24:b6:59:24:6b:ae:c8:fe:1c:0c:20:f2:c0:4e:eb
-# SHA1 Fingerprint: 79:5f:88:60:c5:ab:7c:3d:92:e6:cb:f4:8d:e1:45:cd:11:ef:60:0b
-# SHA256 Fingerprint: 27:99:58:29:fe:6a:75:15:c1:bf:e8:48:f9:c4:76:1d:b1:6c:22:59:29:25:7b:f4:0d:08:94:f2:9e:a8:ba:f2
------BEGIN CERTIFICATE-----
-MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA
-MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
-ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw
-MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
-T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh
-/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e
-CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6
-1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE
-FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS
-gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X
-G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy
-YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH
-vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4
-t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/
-gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3
-5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w
-DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
-Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0
-nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT
-RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT
-wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2
-t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa
-TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2
-o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU
-3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA
-iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f
-WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM
-S1IK
------END CERTIFICATE-----
-
-# Issuer: CN=OpenTrust Root CA G3 O=OpenTrust
-# Subject: CN=OpenTrust Root CA G3 O=OpenTrust
-# Label: "OpenTrust Root CA G3"
-# Serial: 1492104908271485653071219941864171170455615
-# MD5 Fingerprint: 21:37:b4:17:16:92:7b:67:46:70:a9:96:d7:a8:13:24
-# SHA1 Fingerprint: 6e:26:64:f3:56:bf:34:55:bf:d1:93:3f:7c:01:de:d8:13:da:8a:a6
-# SHA256 Fingerprint: b7:c3:62:31:70:6e:81:07:8c:36:7c:b8:96:19:8f:1e:32:08:dd:92:69:49:dd:8f:57:09:a4:10:f7:5b:62:92
------BEGIN CERTIFICATE-----
-MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx
-CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U
-cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow
-QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl
-blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm
-3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d
-oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G
-A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5
-DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK
-BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q
-j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx
-4nxp5V2a+EEfOzmTk51V6s2N8fvB
------END CERTIFICATE-----
-
-# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
-# Subject: CN=ISRG Root X1 O=Internet Security Research Group
-# Label: "ISRG Root X1"
-# Serial: 172886928669790476064670243504169061120
-# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
-# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
-# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
-WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
-ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
-h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
-0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
-A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
-T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
-B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
-B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
-KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
-OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
-jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
-qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
-rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
-hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
-ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
-3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
-NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
-ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
-TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
-jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
-oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
-4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
-mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
-emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
------END CERTIFICATE-----
-# Issuer: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Subject: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Label: "Entrust.net Secure Server CA"
-# Serial: 927650371
-# MD5 Fingerprint: df:f2:80:73:cc:f1:e6:61:73:fc:f5:42:e9:c5:7c:ee
-# SHA1 Fingerprint: 99:a6:9b:e6:1a:fe:88:6b:4d:2b:82:00:7c:b8:54:fc:31:7e:15:39
-# SHA256 Fingerprint: 62:f2:40:27:8c:56:4c:4d:d8:bf:7d:9d:4f:6f:36:6e:a8:94:d2:2f:5f:34:d9:89:a9:83:ac:ec:2f:ff:ed:50
------BEGIN CERTIFICATE-----
-MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
-VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
-ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
-KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
-ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
-MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
-ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
-b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
-bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
-U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
-A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
-I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
-wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
-AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
-oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
-BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
-dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
-MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
-b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
-dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
-MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
-E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
-MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
-hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
-95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
-2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
------END CERTIFICATE-----
-
-# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority
-# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority
-# Label: "ValiCert Class 2 VA"
-# Serial: 1
-# MD5 Fingerprint: a9:23:75:9b:ba:49:36:6e:31:c2:db:f2:e7:66:ba:87
-# SHA1 Fingerprint: 31:7a:2a:d0:7f:2b:33:5e:f5:a1:c3:4e:4b:57:e8:b7:d8:f1:fc:a6
-# SHA256 Fingerprint: 58:d0:17:27:9c:d4:dc:63:ab:dd:b1:96:a6:c9:90:6c:30:c4:e0:87:83:ea:e8:c1:60:99:54:d6:93:55:59:6b
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
-NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
-dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
-WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
-v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
-UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
-IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
-W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Expressz (Class C) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Subject: CN=NetLock Expressz (Class C) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Label: "NetLock Express (Class C) Root"
-# Serial: 104
-# MD5 Fingerprint: 4f:eb:f1:f0:70:c2:80:63:5d:58:9f:da:12:3c:a9:c4
-# SHA1 Fingerprint: e3:92:51:2f:0a:cf:f5:05:df:f6:de:06:7f:75:37:e1:65:ea:57:4b
-# SHA256 Fingerprint: 0b:5e:ed:4e:84:64:03:cf:55:e0:65:84:84:40:ed:2a:82:75:8b:f5:b9:aa:1f:25:3d:46:13:cf:a0:80:ff:3f
------BEGIN CERTIFICATE-----
-MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD
-EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X
-DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw
-DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u
-c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr
-TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN
-BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA
-OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC
-2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW
-RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P
-AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW
-ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0
-YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz
-b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO
-ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB
-IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs
-b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
-ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s
-YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg
-a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g
-SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0
-aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg
-YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg
-Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY
-ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g
-pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4
-Fp1hBWeAyNDYpQcCNJgEjTME1A==
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Uzleti (Class B) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Subject: CN=NetLock Uzleti (Class B) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Label: "NetLock Business (Class B) Root"
-# Serial: 105
-# MD5 Fingerprint: 39:16:aa:b9:6a:41:e1:14:69:df:9e:6c:3b:72:dc:b6
-# SHA1 Fingerprint: 87:9f:4b:ee:05:df:98:58:3b:e3:60:d6:33:e7:0d:3f:fe:98:71:af
-# SHA256 Fingerprint: 39:df:7b:68:2b:7b:93:8f:84:71:54:81:cc:de:8d:60:d8:f2:2e:c5:98:87:7d:0a:aa:c1:2b:59:18:2b:03:12
------BEGIN CERTIFICATE-----
-MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD
-EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05
-OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G
-A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
-Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l
-dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG
-SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK
-gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX
-iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc
-Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E
-BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G
-SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu
-b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh
-bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv
-Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln
-aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0
-IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
-c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph
-biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo
-ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP
-UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj
-YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo
-dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA
-bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06
-sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa
-n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS
-NitjrFgBazMpUIaD8QFI
------END CERTIFICATE-----
-
-# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority
-# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority
-# Label: "RSA Root Certificate 1"
-# Serial: 1
-# MD5 Fingerprint: a2:6f:53:b7:ee:40:db:4a:68:e7:fa:18:d9:10:4b:72
-# SHA1 Fingerprint: 69:bd:8c:f4:9c:d3:00:fb:59:2e:17:93:ca:55:6a:f3:ec:aa:35:fb
-# SHA256 Fingerprint: bc:23:f9:8a:31:3c:b9:2d:e3:bb:fc:3a:5a:9f:44:61:ac:39:49:4c:4a:e1:5a:9e:9d:f1:31:e9:9b:73:01:9a
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy
-NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD
-cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs
-2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY
-JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE
-Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ
-n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
-PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
------END CERTIFICATE-----
-
-# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority
-# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority
-# Label: "ValiCert Class 1 VA"
-# Serial: 1
-# MD5 Fingerprint: 65:58:ab:15:ad:57:6c:1e:a8:a7:b5:69:ac:bf:ff:eb
-# SHA1 Fingerprint: e5:df:74:3c:b6:01:c4:9b:98:43:dc:ab:8c:e8:6a:81:10:9f:e4:8e
-# SHA256 Fingerprint: f4:c1:49:55:1a:30:13:a3:5b:c7:bf:fe:17:a7:f3:44:9b:c1:ab:5b:5a:0a:e7:4b:06:c2:3b:90:00:4c:01:04
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy
-NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y
-LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+
-TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y
-TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0
-LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW
-I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
-nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
------END CERTIFICATE-----
-
-# Issuer: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc.
-# Subject: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc.
-# Label: "Equifax Secure eBusiness CA 1"
-# Serial: 4
-# MD5 Fingerprint: 64:9c:ef:2e:44:fc:c6:8f:52:07:d0:51:73:8f:cb:3d
-# SHA1 Fingerprint: da:40:18:8b:91:89:a3:ed:ee:ae:da:97:fe:2f:9d:f5:b7:d1:8a:41
-# SHA256 Fingerprint: cf:56:ff:46:a4:a1:86:10:9d:d9:65:84:b5:ee:b5:8a:51:0c:42:75:b0:e5:f9:4f:40:bb:ae:86:5e:19:f6:73
------BEGIN CERTIFICATE-----
-MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
-ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
-MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
-LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
-RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
-WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
-Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
-AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
-eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
-zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
-WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
-/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
-# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
-# Label: "Equifax Secure Global eBusiness CA"
-# Serial: 1
-# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc
-# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45
-# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07
------BEGIN CERTIFICATE-----
-MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
-ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
-MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
-dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
-c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
-UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
-58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
-o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
-MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
-aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
-A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
-Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
-8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
------END CERTIFICATE-----
-
-# Issuer: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Subject: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Label: "Thawte Premium Server CA"
-# Serial: 1
-# MD5 Fingerprint: 06:9f:69:79:16:66:90:02:1b:8c:8c:a2:c3:07:6f:3a
-# SHA1 Fingerprint: 62:7f:8d:78:27:65:63:99:d2:7d:7f:90:44:c9:fe:b3:f3:3e:fa:9a
-# SHA256 Fingerprint: ab:70:36:36:5c:71:54:aa:29:c2:c2:9f:5d:41:91:16:3b:16:2a:22:25:01:13:57:d5:6d:07:ff:a7:bc:1f:72
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
-FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
-VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
-biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
-dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
-MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
-MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
-A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
-b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
-cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
-VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
-ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
-uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
-9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
-hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
-pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
------END CERTIFICATE-----
-
-# Issuer: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Subject: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Label: "Thawte Server CA"
-# Serial: 1
-# MD5 Fingerprint: c5:70:c4:a2:ed:53:78:0c:c8:10:53:81:64:cb:d0:1d
-# SHA1 Fingerprint: 23:e5:94:94:51:95:f2:41:48:03:b4:d5:64:d2:a3:a3:f5:d8:8b:8c
-# SHA256 Fingerprint: b4:41:0b:73:e2:e6:ea:ca:47:fb:c4:2f:8f:a4:01:8a:f4:38:1d:c5:4c:fa:a8:44:50:46:1e:ed:09:45:4d:e9
------BEGIN CERTIFICATE-----
-MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
-FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
-VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
-biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
-MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
-MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
-DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
-dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
-cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
-DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
-gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
-yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
-L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
-EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
-7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
-QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
-qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
------END CERTIFICATE-----
-
-# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Label: "Verisign Class 3 Public Primary Certification Authority"
-# Serial: 149843929435818692848040365716851702463
-# MD5 Fingerprint: 10:fc:63:5d:f6:26:3e:0d:f3:25:be:5f:79:cd:67:67
-# SHA1 Fingerprint: 74:2c:31:92:e6:07:e4:24:eb:45:49:54:2b:e1:bb:c5:3e:61:74:e2
-# SHA256 Fingerprint: e7:68:56:34:ef:ac:f6:9a:ce:93:9a:6b:25:5b:7b:4f:ab:ef:42:93:5b:50:a2:65:ac:b5:cb:60:27:e4:4e:70
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
-lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
-AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
------END CERTIFICATE-----
-
-# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Label: "Verisign Class 3 Public Primary Certification Authority"
-# Serial: 80507572722862485515306429940691309246
-# MD5 Fingerprint: ef:5a:f1:33:ef:f1:cd:bb:51:02:ee:12:14:4b:96:c4
-# SHA1 Fingerprint: a1:db:63:93:91:6f:17:e4:18:55:09:40:04:15:c7:02:40:b0:ae:6b
-# SHA256 Fingerprint: a4:b6:b3:99:6f:c2:f3:06:b3:fd:86:81:bd:63:41:3d:8c:50:09:cc:4f:a3:29:c2:cc:f0:e2:fa:1b:14:03:05
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
-2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
-2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
------END CERTIFICATE-----
-
-# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network
-# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network
-# Label: "Verisign Class 3 Public Primary Certification Authority - G2"
-# Serial: 167285380242319648451154478808036881606
-# MD5 Fingerprint: a2:33:9b:4c:74:78:73:d4:6c:e7:c1:f3:8d:cb:5c:e9
-# SHA1 Fingerprint: 85:37:1c:a6:e5:50:14:3d:ce:28:03:47:1b:de:3a:09:e8:f8:77:0f
-# SHA256 Fingerprint: 83:ce:3c:12:29:68:8a:59:3d:48:5f:81:97:3c:0f:91:95:43:1e:da:37:cc:5e:36:43:0e:79:c7:a8:88:63:8b
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
-BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
-c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
-MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
-emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
-DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
-FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
-UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
-YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
-MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
-pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
-13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
-AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
-U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
-F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
-oJ2daZH9
------END CERTIFICATE-----
-
-# Issuer: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc.
-# Subject: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc.
-# Label: "GTE CyberTrust Global Root"
-# Serial: 421
-# MD5 Fingerprint: ca:3d:d3:68:f1:03:5c:d0:32:fa:b8:2b:59:e8:5a:db
-# SHA1 Fingerprint: 97:81:79:50:d8:1c:96:70:cc:34:d8:09:cf:79:44:31:36:7e:f4:74
-# SHA256 Fingerprint: a5:31:25:18:8d:21:10:aa:96:4b:02:c7:b7:c6:da:32:03:17:08:94:e5:fb:71:ff:fb:66:67:d5:e6:81:0a:36
------BEGIN CERTIFICATE-----
-MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD
-VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv
-bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv
-b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
-cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
-b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH
-iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS
-r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4
-04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r
-GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9
-3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P
-lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
------END CERTIFICATE-----
-
-# Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
-# Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
-# Label: "Equifax Secure Certificate Authority"
-# Serial: 903804111
-# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4
-# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a
-# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
-UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
-dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
-MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
-dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
-BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
-cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
-AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
-MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
-aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
-ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
-IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
-MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
-A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
-7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
-1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
------END CERTIFICATE-----
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/certs.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/certs.py
deleted file mode 100644
index f922b99d..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/certs.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-requests.certs
-~~~~~~~~~~~~~~
-
-This module returns the preferred default CA certificate bundle.
-
-If you are packaging Requests, e.g., for a Linux distribution or a managed
-environment, you can change the definition of where() to return a separately
-packaged CA bundle.
-"""
-import os.path
-
-try:
- from certifi import where
-except ImportError:
- def where():
- """Return the preferred certificate bundle."""
- # vendored bundle inside Requests
- return os.path.join(os.path.dirname(__file__), 'cacert.pem')
-
-if __name__ == '__main__':
- print(where())
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/compat.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/compat.py
deleted file mode 100644
index f88e600d..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/compat.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.compat
-~~~~~~~~~~~~~~~
-
-This module handles import compatibility issues between Python 2 and
-Python 3.
-"""
-
-from .packages import chardet
-
-import sys
-
-# -------
-# Pythons
-# -------
-
-# Syntax sugar.
-_ver = sys.version_info
-
-#: Python 2.x?
-is_py2 = (_ver[0] == 2)
-
-#: Python 3.x?
-is_py3 = (_ver[0] == 3)
-
-try:
- import simplejson as json
-except (ImportError, SyntaxError):
- # simplejson does not support Python 3.2, it throws a SyntaxError
- # because of u'...' Unicode literals.
- import json
-
-# ---------
-# Specifics
-# ---------
-
-if is_py2:
- from urllib import quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, proxy_bypass
- from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
- from urllib2 import parse_http_list
- import cookielib
- from Cookie import Morsel
- from StringIO import StringIO
- from .packages.urllib3.packages.ordered_dict import OrderedDict
-
- builtin_str = str
- bytes = str
- str = unicode
- basestring = basestring
- numeric_types = (int, long, float)
- integer_types = (int, long)
-
-elif is_py3:
- from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
- from urllib.request import parse_http_list, getproxies, proxy_bypass
- from http import cookiejar as cookielib
- from http.cookies import Morsel
- from io import StringIO
- from collections import OrderedDict
-
- builtin_str = str
- str = str
- bytes = bytes
- basestring = (str, bytes)
- numeric_types = (int, float)
- integer_types = (int,)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cookies.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cookies.py
deleted file mode 100644
index 856fd45e..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/cookies.py
+++ /dev/null
@@ -1,542 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.cookies
-~~~~~~~~~~~~~~~~
-
-Compatibility code to be able to use `cookielib.CookieJar` with requests.
-
-requests.utils imports from here, so be careful with imports.
-"""
-
-import copy
-import time
-import calendar
-import collections
-
-from ._internal_utils import to_native_string
-from .compat import cookielib, urlparse, urlunparse, Morsel
-
-try:
- import threading
- # grr, pyflakes: this fixes "redefinition of unused 'threading'"
- threading
-except ImportError:
- import dummy_threading as threading
-
-
-class MockRequest(object):
- """Wraps a `requests.Request` to mimic a `urllib2.Request`.
-
- The code in `cookielib.CookieJar` expects this interface in order to correctly
- manage cookie policies, i.e., determine whether a cookie can be set, given the
- domains of the request and the cookie.
-
- The original request object is read-only. The client is responsible for collecting
- the new headers via `get_new_headers()` and interpreting them appropriately. You
- probably want `get_cookie_header`, defined below.
- """
-
- def __init__(self, request):
- self._r = request
- self._new_headers = {}
- self.type = urlparse(self._r.url).scheme
-
- def get_type(self):
- return self.type
-
- def get_host(self):
- return urlparse(self._r.url).netloc
-
- def get_origin_req_host(self):
- return self.get_host()
-
- def get_full_url(self):
- # Only return the response's URL if the user hadn't set the Host
- # header
- if not self._r.headers.get('Host'):
- return self._r.url
- # If they did set it, retrieve it and reconstruct the expected domain
- host = to_native_string(self._r.headers['Host'], encoding='utf-8')
- parsed = urlparse(self._r.url)
- # Reconstruct the URL as we expect it
- return urlunparse([
- parsed.scheme, host, parsed.path, parsed.params, parsed.query,
- parsed.fragment
- ])
-
- def is_unverifiable(self):
- return True
-
- def has_header(self, name):
- return name in self._r.headers or name in self._new_headers
-
- def get_header(self, name, default=None):
- return self._r.headers.get(name, self._new_headers.get(name, default))
-
- def add_header(self, key, val):
- """cookielib has no legitimate use for this method; add it back if you find one."""
- raise NotImplementedError("Cookie headers should be added with add_unredirected_header()")
-
- def add_unredirected_header(self, name, value):
- self._new_headers[name] = value
-
- def get_new_headers(self):
- return self._new_headers
-
- @property
- def unverifiable(self):
- return self.is_unverifiable()
-
- @property
- def origin_req_host(self):
- return self.get_origin_req_host()
-
- @property
- def host(self):
- return self.get_host()
-
-
-class MockResponse(object):
- """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
-
- ...what? Basically, expose the parsed HTTP headers from the server response
- the way `cookielib` expects to see them.
- """
-
- def __init__(self, headers):
- """Make a MockResponse for `cookielib` to read.
-
- :param headers: a httplib.HTTPMessage or analogous carrying the headers
- """
- self._headers = headers
-
- def info(self):
- return self._headers
-
- def getheaders(self, name):
- self._headers.getheaders(name)
-
-
-def extract_cookies_to_jar(jar, request, response):
- """Extract the cookies from the response into a CookieJar.
-
- :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar)
- :param request: our own requests.Request object
- :param response: urllib3.HTTPResponse object
- """
- if not (hasattr(response, '_original_response') and
- response._original_response):
- return
- # the _original_response field is the wrapped httplib.HTTPResponse object,
- req = MockRequest(request)
- # pull out the HTTPMessage with the headers and put it in the mock:
- res = MockResponse(response._original_response.msg)
- jar.extract_cookies(res, req)
-
-
-def get_cookie_header(jar, request):
- """
- Produce an appropriate Cookie header string to be sent with `request`, or None.
-
- :rtype: str
- """
- r = MockRequest(request)
- jar.add_cookie_header(r)
- return r.get_new_headers().get('Cookie')
-
-
-def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
- """Unsets a cookie by name, by default over all domains and paths.
-
- Wraps CookieJar.clear(), is O(n).
- """
- clearables = []
- for cookie in cookiejar:
- if cookie.name != name:
- continue
- if domain is not None and domain != cookie.domain:
- continue
- if path is not None and path != cookie.path:
- continue
- clearables.append((cookie.domain, cookie.path, cookie.name))
-
- for domain, path, name in clearables:
- cookiejar.clear(domain, path, name)
-
-
-class CookieConflictError(RuntimeError):
- """There are two cookies that meet the criteria specified in the cookie jar.
- Use .get and .set and include domain and path args in order to be more specific.
- """
-
-
-class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
- """Compatibility class; is a cookielib.CookieJar, but exposes a dict
- interface.
-
- This is the CookieJar we create by default for requests and sessions that
- don't specify one, since some clients may expect response.cookies and
- session.cookies to support dict operations.
-
- Requests does not use the dict interface internally; it's just for
- compatibility with external client code. All requests code should work
- out of the box with externally provided instances of ``CookieJar``, e.g.
- ``LWPCookieJar`` and ``FileCookieJar``.
-
- Unlike a regular CookieJar, this class is pickleable.
-
- .. warning:: dictionary operations that are normally O(1) may be O(n).
- """
-
- def get(self, name, default=None, domain=None, path=None):
- """Dict-like get() that also supports optional domain and path args in
- order to resolve naming collisions from using one cookie jar over
- multiple domains.
-
- .. warning:: operation is O(n), not O(1).
- """
- try:
- return self._find_no_duplicates(name, domain, path)
- except KeyError:
- return default
-
- def set(self, name, value, **kwargs):
- """Dict-like set() that also supports optional domain and path args in
- order to resolve naming collisions from using one cookie jar over
- multiple domains.
- """
- # support client code that unsets cookies by assignment of a None value:
- if value is None:
- remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path'))
- return
-
- if isinstance(value, Morsel):
- c = morsel_to_cookie(value)
- else:
- c = create_cookie(name, value, **kwargs)
- self.set_cookie(c)
- return c
-
- def iterkeys(self):
- """Dict-like iterkeys() that returns an iterator of names of cookies
- from the jar.
-
- .. seealso:: itervalues() and iteritems().
- """
- for cookie in iter(self):
- yield cookie.name
-
- def keys(self):
- """Dict-like keys() that returns a list of names of cookies from the
- jar.
-
- .. seealso:: values() and items().
- """
- return list(self.iterkeys())
-
- def itervalues(self):
- """Dict-like itervalues() that returns an iterator of values of cookies
- from the jar.
-
- .. seealso:: iterkeys() and iteritems().
- """
- for cookie in iter(self):
- yield cookie.value
-
- def values(self):
- """Dict-like values() that returns a list of values of cookies from the
- jar.
-
- .. seealso:: keys() and items().
- """
- return list(self.itervalues())
-
- def iteritems(self):
- """Dict-like iteritems() that returns an iterator of name-value tuples
- from the jar.
-
- .. seealso:: iterkeys() and itervalues().
- """
- for cookie in iter(self):
- yield cookie.name, cookie.value
-
- def items(self):
- """Dict-like items() that returns a list of name-value tuples from the
- jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
- vanilla python dict of key value pairs.
-
- .. seealso:: keys() and values().
- """
- return list(self.iteritems())
-
- def list_domains(self):
- """Utility method to list all the domains in the jar."""
- domains = []
- for cookie in iter(self):
- if cookie.domain not in domains:
- domains.append(cookie.domain)
- return domains
-
- def list_paths(self):
- """Utility method to list all the paths in the jar."""
- paths = []
- for cookie in iter(self):
- if cookie.path not in paths:
- paths.append(cookie.path)
- return paths
-
- def multiple_domains(self):
- """Returns True if there are multiple domains in the jar.
- Returns False otherwise.
-
- :rtype: bool
- """
- domains = []
- for cookie in iter(self):
- if cookie.domain is not None and cookie.domain in domains:
- return True
- domains.append(cookie.domain)
- return False # there is only one domain in jar
-
- def get_dict(self, domain=None, path=None):
- """Takes as an argument an optional domain and path and returns a plain
- old Python dict of name-value pairs of cookies that meet the
- requirements.
-
- :rtype: dict
- """
- dictionary = {}
- for cookie in iter(self):
- if (domain is None or cookie.domain == domain) and (path is None
- or cookie.path == path):
- dictionary[cookie.name] = cookie.value
- return dictionary
-
- def __contains__(self, name):
- try:
- return super(RequestsCookieJar, self).__contains__(name)
- except CookieConflictError:
- return True
-
- def __getitem__(self, name):
- """Dict-like __getitem__() for compatibility with client code. Throws
- exception if there are more than one cookie with name. In that case,
- use the more explicit get() method instead.
-
- .. warning:: operation is O(n), not O(1).
- """
- return self._find_no_duplicates(name)
-
- def __setitem__(self, name, value):
- """Dict-like __setitem__ for compatibility with client code. Throws
- exception if there is already a cookie of that name in the jar. In that
- case, use the more explicit set() method instead.
- """
- self.set(name, value)
-
- def __delitem__(self, name):
- """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s
- ``remove_cookie_by_name()``.
- """
- remove_cookie_by_name(self, name)
-
- def set_cookie(self, cookie, *args, **kwargs):
- if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'):
- cookie.value = cookie.value.replace('\\"', '')
- return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs)
-
- def update(self, other):
- """Updates this jar with cookies from another CookieJar or dict-like"""
- if isinstance(other, cookielib.CookieJar):
- for cookie in other:
- self.set_cookie(copy.copy(cookie))
- else:
- super(RequestsCookieJar, self).update(other)
-
- def _find(self, name, domain=None, path=None):
- """Requests uses this method internally to get cookie values.
-
- If there are conflicting cookies, _find arbitrarily chooses one.
- See _find_no_duplicates if you want an exception thrown if there are
- conflicting cookies.
-
- :param name: a string containing name of cookie
- :param domain: (optional) string containing domain of cookie
- :param path: (optional) string containing path of cookie
- :return: cookie.value
- """
- for cookie in iter(self):
- if cookie.name == name:
- if domain is None or cookie.domain == domain:
- if path is None or cookie.path == path:
- return cookie.value
-
- raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
-
- def _find_no_duplicates(self, name, domain=None, path=None):
- """Both ``__get_item__`` and ``get`` call this function: it's never
- used elsewhere in Requests.
-
- :param name: a string containing name of cookie
- :param domain: (optional) string containing domain of cookie
- :param path: (optional) string containing path of cookie
- :raises KeyError: if cookie is not found
- :raises CookieConflictError: if there are multiple cookies
- that match name and optionally domain and path
- :return: cookie.value
- """
- toReturn = None
- for cookie in iter(self):
- if cookie.name == name:
- if domain is None or cookie.domain == domain:
- if path is None or cookie.path == path:
- if toReturn is not None: # if there are multiple cookies that meet passed in criteria
- raise CookieConflictError('There are multiple cookies with name, %r' % (name))
- toReturn = cookie.value # we will eventually return this as long as no cookie conflict
-
- if toReturn:
- return toReturn
- raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
-
- def __getstate__(self):
- """Unlike a normal CookieJar, this class is pickleable."""
- state = self.__dict__.copy()
- # remove the unpickleable RLock object
- state.pop('_cookies_lock')
- return state
-
- def __setstate__(self, state):
- """Unlike a normal CookieJar, this class is pickleable."""
- self.__dict__.update(state)
- if '_cookies_lock' not in self.__dict__:
- self._cookies_lock = threading.RLock()
-
- def copy(self):
- """Return a copy of this RequestsCookieJar."""
- new_cj = RequestsCookieJar()
- new_cj.update(self)
- return new_cj
-
-
-def _copy_cookie_jar(jar):
- if jar is None:
- return None
-
- if hasattr(jar, 'copy'):
- # We're dealing with an instance of RequestsCookieJar
- return jar.copy()
- # We're dealing with a generic CookieJar instance
- new_jar = copy.copy(jar)
- new_jar.clear()
- for cookie in jar:
- new_jar.set_cookie(copy.copy(cookie))
- return new_jar
-
-
-def create_cookie(name, value, **kwargs):
- """Make a cookie from underspecified parameters.
-
- By default, the pair of `name` and `value` will be set for the domain ''
- and sent on every request (this is sometimes called a "supercookie").
- """
- result = dict(
- version=0,
- name=name,
- value=value,
- port=None,
- domain='',
- path='/',
- secure=False,
- expires=None,
- discard=True,
- comment=None,
- comment_url=None,
- rest={'HttpOnly': None},
- rfc2109=False,)
-
- badargs = set(kwargs) - set(result)
- if badargs:
- err = 'create_cookie() got unexpected keyword arguments: %s'
- raise TypeError(err % list(badargs))
-
- result.update(kwargs)
- result['port_specified'] = bool(result['port'])
- result['domain_specified'] = bool(result['domain'])
- result['domain_initial_dot'] = result['domain'].startswith('.')
- result['path_specified'] = bool(result['path'])
-
- return cookielib.Cookie(**result)
-
-
-def morsel_to_cookie(morsel):
- """Convert a Morsel object into a Cookie containing the one k/v pair."""
-
- expires = None
- if morsel['max-age']:
- try:
- expires = int(time.time() + int(morsel['max-age']))
- except ValueError:
- raise TypeError('max-age: %s must be integer' % morsel['max-age'])
- elif morsel['expires']:
- time_template = '%a, %d-%b-%Y %H:%M:%S GMT'
- expires = calendar.timegm(
- time.strptime(morsel['expires'], time_template)
- )
- return create_cookie(
- comment=morsel['comment'],
- comment_url=bool(morsel['comment']),
- discard=False,
- domain=morsel['domain'],
- expires=expires,
- name=morsel.key,
- path=morsel['path'],
- port=None,
- rest={'HttpOnly': morsel['httponly']},
- rfc2109=False,
- secure=bool(morsel['secure']),
- value=morsel.value,
- version=morsel['version'] or 0,
- )
-
-
-def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):
- """Returns a CookieJar from a key/value dictionary.
-
- :param cookie_dict: Dict of key/values to insert into CookieJar.
- :param cookiejar: (optional) A cookiejar to add the cookies to.
- :param overwrite: (optional) If False, will not replace cookies
- already in the jar with new ones.
- """
- if cookiejar is None:
- cookiejar = RequestsCookieJar()
-
- if cookie_dict is not None:
- names_from_jar = [cookie.name for cookie in cookiejar]
- for name in cookie_dict:
- if overwrite or (name not in names_from_jar):
- cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
-
- return cookiejar
-
-
-def merge_cookies(cookiejar, cookies):
- """Add cookies to cookiejar and returns a merged CookieJar.
-
- :param cookiejar: CookieJar object to add the cookies to.
- :param cookies: Dictionary or CookieJar object to be added.
- """
- if not isinstance(cookiejar, cookielib.CookieJar):
- raise ValueError('You can only merge into CookieJar')
-
- if isinstance(cookies, dict):
- cookiejar = cookiejar_from_dict(
- cookies, cookiejar=cookiejar, overwrite=False)
- elif isinstance(cookies, cookielib.CookieJar):
- try:
- cookiejar.update(cookies)
- except AttributeError:
- for cookie_in_jar in cookies:
- cookiejar.set_cookie(cookie_in_jar)
-
- return cookiejar
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/exceptions.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/exceptions.py
deleted file mode 100644
index 0658e7ec..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/exceptions.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.exceptions
-~~~~~~~~~~~~~~~~~~~
-
-This module contains the set of Requests' exceptions.
-"""
-from .packages.urllib3.exceptions import HTTPError as BaseHTTPError
-
-
-class RequestException(IOError):
- """There was an ambiguous exception that occurred while handling your
- request.
- """
-
- def __init__(self, *args, **kwargs):
- """Initialize RequestException with `request` and `response` objects."""
- response = kwargs.pop('response', None)
- self.response = response
- self.request = kwargs.pop('request', None)
- if (response is not None and not self.request and
- hasattr(response, 'request')):
- self.request = self.response.request
- super(RequestException, self).__init__(*args, **kwargs)
-
-
-class HTTPError(RequestException):
- """An HTTP error occurred."""
-
-
-class ConnectionError(RequestException):
- """A Connection error occurred."""
-
-
-class ProxyError(ConnectionError):
- """A proxy error occurred."""
-
-
-class SSLError(ConnectionError):
- """An SSL error occurred."""
-
-
-class Timeout(RequestException):
- """The request timed out.
-
- Catching this error will catch both
- :exc:`~requests.exceptions.ConnectTimeout` and
- :exc:`~requests.exceptions.ReadTimeout` errors.
- """
-
-
-class ConnectTimeout(ConnectionError, Timeout):
- """The request timed out while trying to connect to the remote server.
-
- Requests that produced this error are safe to retry.
- """
-
-
-class ReadTimeout(Timeout):
- """The server did not send any data in the allotted amount of time."""
-
-
-class URLRequired(RequestException):
- """A valid URL is required to make a request."""
-
-
-class TooManyRedirects(RequestException):
- """Too many redirects."""
-
-
-class MissingSchema(RequestException, ValueError):
- """The URL schema (e.g. http or https) is missing."""
-
-
-class InvalidSchema(RequestException, ValueError):
- """See defaults.py for valid schemas."""
-
-
-class InvalidURL(RequestException, ValueError):
- """The URL provided was somehow invalid."""
-
-
-class InvalidHeader(RequestException, ValueError):
- """The header value provided was somehow invalid."""
-
-
-class ChunkedEncodingError(RequestException):
- """The server declared chunked encoding but sent an invalid chunk."""
-
-
-class ContentDecodingError(RequestException, BaseHTTPError):
- """Failed to decode response content"""
-
-
-class StreamConsumedError(RequestException, TypeError):
- """The content for this response was already consumed"""
-
-
-class RetryError(RequestException):
- """Custom retries logic failed"""
-
-class UnrewindableBodyError(RequestException):
- """Requests encountered an error when trying to rewind a body"""
-
-# Warnings
-
-
-class RequestsWarning(Warning):
- """Base warning for Requests."""
- pass
-
-
-class FileModeWarning(RequestsWarning, DeprecationWarning):
- """A file was opened in text mode, but Requests determined its binary length."""
- pass
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/hooks.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/hooks.py
deleted file mode 100644
index 32b32de7..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/hooks.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.hooks
-~~~~~~~~~~~~~~
-
-This module provides the capabilities for the Requests hooks system.
-
-Available hooks:
-
-``response``:
- The response generated from a Request.
-"""
-HOOKS = ['response']
-
-
-def default_hooks():
- return dict((event, []) for event in HOOKS)
-
-# TODO: response is the only one
-
-
-def dispatch_hook(key, hooks, hook_data, **kwargs):
- """Dispatches a hook dictionary on a given piece of data."""
- hooks = hooks or dict()
- hooks = hooks.get(key)
- if hooks:
- if hasattr(hooks, '__call__'):
- hooks = [hooks]
- for hook in hooks:
- _hook_data = hook(hook_data, **kwargs)
- if _hook_data is not None:
- hook_data = _hook_data
- return hook_data
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/models.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/models.py
deleted file mode 100644
index d1a9c868..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/models.py
+++ /dev/null
@@ -1,922 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.models
-~~~~~~~~~~~~~~~
-
-This module contains the primary objects that power Requests.
-"""
-
-import collections
-import datetime
-import sys
-
-# Import encoding now, to avoid implicit import later.
-# Implicit import within threads may cause LookupError when standard library is in a ZIP,
-# such as in Embedded Python. See https://github.com/kennethreitz/requests/issues/3578.
-import encodings.idna
-
-from io import BytesIO, UnsupportedOperation
-from .hooks import default_hooks
-from .structures import CaseInsensitiveDict
-
-from .auth import HTTPBasicAuth
-from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar
-from .packages.urllib3.fields import RequestField
-from .packages.urllib3.filepost import encode_multipart_formdata
-from .packages.urllib3.util import parse_url
-from .packages.urllib3.exceptions import (
- DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)
-from .exceptions import (
- HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,
- ContentDecodingError, ConnectionError, StreamConsumedError)
-from ._internal_utils import to_native_string, unicode_is_ascii
-from .utils import (
- guess_filename, get_auth_from_url, requote_uri,
- stream_decode_response_unicode, to_key_val_list, parse_header_links,
- iter_slices, guess_json_utf, super_len, check_header_validity)
-from .compat import (
- cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO,
- is_py2, chardet, builtin_str, basestring)
-from .compat import json as complexjson
-from .status_codes import codes
-
-#: The set of HTTP status codes that indicate an automatically
-#: processable redirect.
-REDIRECT_STATI = (
- codes.moved, # 301
- codes.found, # 302
- codes.other, # 303
- codes.temporary_redirect, # 307
- codes.permanent_redirect, # 308
-)
-
-DEFAULT_REDIRECT_LIMIT = 30
-CONTENT_CHUNK_SIZE = 10 * 1024
-ITER_CHUNK_SIZE = 512
-
-
-class RequestEncodingMixin(object):
- @property
- def path_url(self):
- """Build the path URL to use."""
-
- url = []
-
- p = urlsplit(self.url)
-
- path = p.path
- if not path:
- path = '/'
-
- url.append(path)
-
- query = p.query
- if query:
- url.append('?')
- url.append(query)
-
- return ''.join(url)
-
- @staticmethod
- def _encode_params(data):
- """Encode parameters in a piece of data.
-
- Will successfully encode parameters when passed as a dict or a list of
- 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
- if parameters are supplied as a dict.
- """
-
- if isinstance(data, (str, bytes)):
- return data
- elif hasattr(data, 'read'):
- return data
- elif hasattr(data, '__iter__'):
- result = []
- for k, vs in to_key_val_list(data):
- if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
- vs = [vs]
- for v in vs:
- if v is not None:
- result.append(
- (k.encode('utf-8') if isinstance(k, str) else k,
- v.encode('utf-8') if isinstance(v, str) else v))
- return urlencode(result, doseq=True)
- else:
- return data
-
- @staticmethod
- def _encode_files(files, data):
- """Build the body for a multipart/form-data request.
-
- Will successfully encode files when passed as a dict or a list of
- tuples. Order is retained if data is a list of tuples but arbitrary
- if parameters are supplied as a dict.
- The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
- or 4-tuples (filename, fileobj, contentype, custom_headers).
- """
- if (not files):
- raise ValueError("Files must be provided.")
- elif isinstance(data, basestring):
- raise ValueError("Data must not be a string.")
-
- new_fields = []
- fields = to_key_val_list(data or {})
- files = to_key_val_list(files or {})
-
- for field, val in fields:
- if isinstance(val, basestring) or not hasattr(val, '__iter__'):
- val = [val]
- for v in val:
- if v is not None:
- # Don't call str() on bytestrings: in Py3 it all goes wrong.
- if not isinstance(v, bytes):
- v = str(v)
-
- new_fields.append(
- (field.decode('utf-8') if isinstance(field, bytes) else field,
- v.encode('utf-8') if isinstance(v, str) else v))
-
- for (k, v) in files:
- # support for explicit filename
- ft = None
- fh = None
- if isinstance(v, (tuple, list)):
- if len(v) == 2:
- fn, fp = v
- elif len(v) == 3:
- fn, fp, ft = v
- else:
- fn, fp, ft, fh = v
- else:
- fn = guess_filename(v) or k
- fp = v
-
- if isinstance(fp, (str, bytes, bytearray)):
- fdata = fp
- else:
- fdata = fp.read()
-
- rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
- rf.make_multipart(content_type=ft)
- new_fields.append(rf)
-
- body, content_type = encode_multipart_formdata(new_fields)
-
- return body, content_type
-
-
-class RequestHooksMixin(object):
- def register_hook(self, event, hook):
- """Properly register a hook."""
-
- if event not in self.hooks:
- raise ValueError('Unsupported event specified, with event name "%s"' % (event))
-
- if isinstance(hook, collections.Callable):
- self.hooks[event].append(hook)
- elif hasattr(hook, '__iter__'):
- self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable))
-
- def deregister_hook(self, event, hook):
- """Deregister a previously registered hook.
- Returns True if the hook existed, False if not.
- """
-
- try:
- self.hooks[event].remove(hook)
- return True
- except ValueError:
- return False
-
-
-class Request(RequestHooksMixin):
- """A user-created :class:`Request <Request>` object.
-
- Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.
-
- :param method: HTTP method to use.
- :param url: URL to send.
- :param headers: dictionary of headers to send.
- :param files: dictionary of {filename: fileobject} files to multipart upload.
- :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place.
- :param json: json for the body to attach to the request (if files or data is not specified).
- :param params: dictionary of URL parameters to append to the URL.
- :param auth: Auth handler or (user, pass) tuple.
- :param cookies: dictionary or CookieJar of cookies to attach to this request.
- :param hooks: dictionary of callback hooks, for internal usage.
-
- Usage::
-
- >>> import requests
- >>> req = requests.Request('GET', 'http://httpbin.org/get')
- >>> req.prepare()
- <PreparedRequest [GET]>
- """
-
- def __init__(self, method=None, url=None, headers=None, files=None,
- data=None, params=None, auth=None, cookies=None, hooks=None, json=None):
-
- # Default empty dicts for dict params.
- data = [] if data is None else data
- files = [] if files is None else files
- headers = {} if headers is None else headers
- params = {} if params is None else params
- hooks = {} if hooks is None else hooks
-
- self.hooks = default_hooks()
- for (k, v) in list(hooks.items()):
- self.register_hook(event=k, hook=v)
-
- self.method = method
- self.url = url
- self.headers = headers
- self.files = files
- self.data = data
- self.json = json
- self.params = params
- self.auth = auth
- self.cookies = cookies
-
- def __repr__(self):
- return '<Request [%s]>' % (self.method)
-
- def prepare(self):
- """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it."""
- p = PreparedRequest()
- p.prepare(
- method=self.method,
- url=self.url,
- headers=self.headers,
- files=self.files,
- data=self.data,
- json=self.json,
- params=self.params,
- auth=self.auth,
- cookies=self.cookies,
- hooks=self.hooks,
- )
- return p
-
-
-class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
- """The fully mutable :class:`PreparedRequest <PreparedRequest>` object,
- containing the exact bytes that will be sent to the server.
-
- Generated from either a :class:`Request <Request>` object or manually.
-
- Usage::
-
- >>> import requests
- >>> req = requests.Request('GET', 'http://httpbin.org/get')
- >>> r = req.prepare()
- <PreparedRequest [GET]>
-
- >>> s = requests.Session()
- >>> s.send(r)
- <Response [200]>
- """
-
- def __init__(self):
- #: HTTP verb to send to the server.
- self.method = None
- #: HTTP URL to send the request to.
- self.url = None
- #: dictionary of HTTP headers.
- self.headers = None
- # The `CookieJar` used to create the Cookie header will be stored here
- # after prepare_cookies is called
- self._cookies = None
- #: request body to send to the server.
- self.body = None
- #: dictionary of callback hooks, for internal usage.
- self.hooks = default_hooks()
- #: integer denoting starting position of a readable file-like body.
- self._body_position = None
-
- def prepare(self, method=None, url=None, headers=None, files=None,
- data=None, params=None, auth=None, cookies=None, hooks=None, json=None):
- """Prepares the entire request with the given parameters."""
-
- self.prepare_method(method)
- self.prepare_url(url, params)
- self.prepare_headers(headers)
- self.prepare_cookies(cookies)
- self.prepare_body(data, files, json)
- self.prepare_auth(auth, url)
-
- # Note that prepare_auth must be last to enable authentication schemes
- # such as OAuth to work on a fully prepared request.
-
- # This MUST go after prepare_auth. Authenticators could add a hook
- self.prepare_hooks(hooks)
-
- def __repr__(self):
- return '<PreparedRequest [%s]>' % (self.method)
-
- def copy(self):
- p = PreparedRequest()
- p.method = self.method
- p.url = self.url
- p.headers = self.headers.copy() if self.headers is not None else None
- p._cookies = _copy_cookie_jar(self._cookies)
- p.body = self.body
- p.hooks = self.hooks
- p._body_position = self._body_position
- return p
-
- def prepare_method(self, method):
- """Prepares the given HTTP method."""
- self.method = method
- if self.method is not None:
- self.method = to_native_string(self.method.upper())
-
- @staticmethod
- def _get_idna_encoded_host(host):
- try:
- from .packages import idna
- except ImportError:
- # tolerate the possibility of downstream repackagers unvendoring `requests`
- # For more information, read: packages/__init__.py
- import idna
- sys.modules['requests.packages.idna'] = idna
-
- try:
- host = idna.encode(host, uts46=True).decode('utf-8')
- except idna.IDNAError:
- raise UnicodeError
- return host
-
- def prepare_url(self, url, params):
- """Prepares the given HTTP URL."""
- #: Accept objects that have string representations.
- #: We're unable to blindly call unicode/str functions
- #: as this will include the bytestring indicator (b'')
- #: on python 3.x.
- #: https://github.com/kennethreitz/requests/pull/2238
- if isinstance(url, bytes):
- url = url.decode('utf8')
- else:
- url = unicode(url) if is_py2 else str(url)
-
- # Remove leading whitespaces from url
- url = url.lstrip()
-
- # Don't do any URL preparation for non-HTTP schemes like `mailto`,
- # `data` etc to work around exceptions from `url_parse`, which
- # handles RFC 3986 only.
- if ':' in url and not url.lower().startswith('http'):
- self.url = url
- return
-
- # Support for unicode domain names and paths.
- try:
- scheme, auth, host, port, path, query, fragment = parse_url(url)
- except LocationParseError as e:
- raise InvalidURL(*e.args)
-
- if not scheme:
- error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?")
- error = error.format(to_native_string(url, 'utf8'))
-
- raise MissingSchema(error)
-
- if not host:
- raise InvalidURL("Invalid URL %r: No host supplied" % url)
-
- # In general, we want to try IDNA encoding the hostname if the string contains
- # non-ASCII characters. This allows users to automatically get the correct IDNA
- # behaviour. For strings containing only ASCII characters, we need to also verify
- # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
- if not unicode_is_ascii(host):
- try:
- host = self._get_idna_encoded_host(host)
- except UnicodeError:
- raise InvalidURL('URL has an invalid label.')
- elif host.startswith(u'*'):
- raise InvalidURL('URL has an invalid label.')
-
- # Carefully reconstruct the network location
- netloc = auth or ''
- if netloc:
- netloc += '@'
- netloc += host
- if port:
- netloc += ':' + str(port)
-
- # Bare domains aren't valid URLs.
- if not path:
- path = '/'
-
- if is_py2:
- if isinstance(scheme, str):
- scheme = scheme.encode('utf-8')
- if isinstance(netloc, str):
- netloc = netloc.encode('utf-8')
- if isinstance(path, str):
- path = path.encode('utf-8')
- if isinstance(query, str):
- query = query.encode('utf-8')
- if isinstance(fragment, str):
- fragment = fragment.encode('utf-8')
-
- if isinstance(params, (str, bytes)):
- params = to_native_string(params)
-
- enc_params = self._encode_params(params)
- if enc_params:
- if query:
- query = '%s&%s' % (query, enc_params)
- else:
- query = enc_params
-
- url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
- self.url = url
-
- def prepare_headers(self, headers):
- """Prepares the given HTTP headers."""
-
- self.headers = CaseInsensitiveDict()
- if headers:
- for header in headers.items():
- # Raise exception on invalid header value.
- check_header_validity(header)
- name, value = header
- self.headers[to_native_string(name)] = value
-
- def prepare_body(self, data, files, json=None):
- """Prepares the given HTTP body data."""
-
- # Check if file, fo, generator, iterator.
- # If not, run through normal process.
-
- # Nottin' on you.
- body = None
- content_type = None
-
- if not data and json is not None:
- # urllib3 requires a bytes-like body. Python 2's json.dumps
- # provides this natively, but Python 3 gives a Unicode string.
- content_type = 'application/json'
- body = complexjson.dumps(json)
- if not isinstance(body, bytes):
- body = body.encode('utf-8')
-
- is_stream = all([
- hasattr(data, '__iter__'),
- not isinstance(data, (basestring, list, tuple, collections.Mapping))
- ])
-
- try:
- length = super_len(data)
- except (TypeError, AttributeError, UnsupportedOperation):
- length = None
-
- if is_stream:
- body = data
-
- if getattr(body, 'tell', None) is not None:
- # Record the current file position before reading.
- # This will allow us to rewind a file in the event
- # of a redirect.
- try:
- self._body_position = body.tell()
- except (IOError, OSError):
- # This differentiates from None, allowing us to catch
- # a failed `tell()` later when trying to rewind the body
- self._body_position = object()
-
- if files:
- raise NotImplementedError('Streamed bodies and files are mutually exclusive.')
-
- if length:
- self.headers['Content-Length'] = builtin_str(length)
- else:
- self.headers['Transfer-Encoding'] = 'chunked'
- else:
- # Multi-part file uploads.
- if files:
- (body, content_type) = self._encode_files(files, data)
- else:
- if data:
- body = self._encode_params(data)
- if isinstance(data, basestring) or hasattr(data, 'read'):
- content_type = None
- else:
- content_type = 'application/x-www-form-urlencoded'
-
- self.prepare_content_length(body)
-
- # Add content-type if it wasn't explicitly provided.
- if content_type and ('content-type' not in self.headers):
- self.headers['Content-Type'] = content_type
-
- self.body = body
-
- def prepare_content_length(self, body):
- """Prepare Content-Length header based on request method and body"""
- if body is not None:
- length = super_len(body)
- if length:
- # If length exists, set it. Otherwise, we fallback
- # to Transfer-Encoding: chunked.
- self.headers['Content-Length'] = builtin_str(length)
- elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None:
- # Set Content-Length to 0 for methods that can have a body
- # but don't provide one. (i.e. not GET or HEAD)
- self.headers['Content-Length'] = '0'
-
- def prepare_auth(self, auth, url=''):
- """Prepares the given HTTP auth data."""
-
- # If no Auth is explicitly provided, extract it from the URL first.
- if auth is None:
- url_auth = get_auth_from_url(self.url)
- auth = url_auth if any(url_auth) else None
-
- if auth:
- if isinstance(auth, tuple) and len(auth) == 2:
- # special-case basic HTTP auth
- auth = HTTPBasicAuth(*auth)
-
- # Allow auth to make its changes.
- r = auth(self)
-
- # Update self to reflect the auth changes.
- self.__dict__.update(r.__dict__)
-
- # Recompute Content-Length
- self.prepare_content_length(self.body)
-
- def prepare_cookies(self, cookies):
- """Prepares the given HTTP cookie data.
-
- This function eventually generates a ``Cookie`` header from the
- given cookies using cookielib. Due to cookielib's design, the header
- will not be regenerated if it already exists, meaning this function
- can only be called once for the life of the
- :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls
- to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
- header is removed beforehand.
- """
- if isinstance(cookies, cookielib.CookieJar):
- self._cookies = cookies
- else:
- self._cookies = cookiejar_from_dict(cookies)
-
- cookie_header = get_cookie_header(self._cookies, self)
- if cookie_header is not None:
- self.headers['Cookie'] = cookie_header
-
- def prepare_hooks(self, hooks):
- """Prepares the given hooks."""
- # hooks can be passed as None to the prepare method and to this
- # method. To prevent iterating over None, simply use an empty list
- # if hooks is False-y
- hooks = hooks or []
- for event in hooks:
- self.register_hook(event, hooks[event])
-
-
-class Response(object):
- """The :class:`Response <Response>` object, which contains a
- server's response to an HTTP request.
- """
-
- __attrs__ = [
- '_content', 'status_code', 'headers', 'url', 'history',
- 'encoding', 'reason', 'cookies', 'elapsed', 'request'
- ]
-
- def __init__(self):
- super(Response, self).__init__()
-
- self._content = False
- self._content_consumed = False
-
- #: Integer Code of responded HTTP Status, e.g. 404 or 200.
- self.status_code = None
-
- #: Case-insensitive Dictionary of Response Headers.
- #: For example, ``headers['content-encoding']`` will return the
- #: value of a ``'Content-Encoding'`` response header.
- self.headers = CaseInsensitiveDict()
-
- #: File-like object representation of response (for advanced usage).
- #: Use of ``raw`` requires that ``stream=True`` be set on the request.
- # This requirement does not apply for use internally to Requests.
- self.raw = None
-
- #: Final URL location of Response.
- self.url = None
-
- #: Encoding to decode with when accessing r.text.
- self.encoding = None
-
- #: A list of :class:`Response <Response>` objects from
- #: the history of the Request. Any redirect responses will end
- #: up here. The list is sorted from the oldest to the most recent request.
- self.history = []
-
- #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
- self.reason = None
-
- #: A CookieJar of Cookies the server sent back.
- self.cookies = cookiejar_from_dict({})
-
- #: The amount of time elapsed between sending the request
- #: and the arrival of the response (as a timedelta).
- #: This property specifically measures the time taken between sending
- #: the first byte of the request and finishing parsing the headers. It
- #: is therefore unaffected by consuming the response content or the
- #: value of the ``stream`` keyword argument.
- self.elapsed = datetime.timedelta(0)
-
- #: The :class:`PreparedRequest <PreparedRequest>` object to which this
- #: is a response.
- self.request = None
-
- def __getstate__(self):
- # Consume everything; accessing the content attribute makes
- # sure the content has been fully read.
- if not self._content_consumed:
- self.content
-
- return dict(
- (attr, getattr(self, attr, None))
- for attr in self.__attrs__
- )
-
- def __setstate__(self, state):
- for name, value in state.items():
- setattr(self, name, value)
-
- # pickled objects do not have .raw
- setattr(self, '_content_consumed', True)
- setattr(self, 'raw', None)
-
- def __repr__(self):
- return '<Response [%s]>' % (self.status_code)
-
- def __bool__(self):
- """Returns true if :attr:`status_code` is 'OK'."""
- return self.ok
-
- def __nonzero__(self):
- """Returns true if :attr:`status_code` is 'OK'."""
- return self.ok
-
- def __iter__(self):
- """Allows you to use a response as an iterator."""
- return self.iter_content(128)
-
- @property
- def ok(self):
- try:
- self.raise_for_status()
- except HTTPError:
- return False
- return True
-
- @property
- def is_redirect(self):
- """True if this Response is a well-formed HTTP redirect that could have
- been processed automatically (by :meth:`Session.resolve_redirects`).
- """
- return ('location' in self.headers and self.status_code in REDIRECT_STATI)
-
- @property
- def is_permanent_redirect(self):
- """True if this Response one of the permanent versions of redirect"""
- return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect))
-
- @property
- def apparent_encoding(self):
- """The apparent encoding, provided by the chardet library"""
- return chardet.detect(self.content)['encoding']
-
- def iter_content(self, chunk_size=1, decode_unicode=False):
- """Iterates over the response data. When stream=True is set on the
- request, this avoids reading the content at once into memory for
- large responses. The chunk size is the number of bytes it should
- read into memory. This is not necessarily the length of each item
- returned as decoding can take place.
-
- chunk_size must be of type int or None. A value of None will
- function differently depending on the value of `stream`.
- stream=True will read data as it arrives in whatever size the
- chunks are received. If stream=False, data is returned as
- a single chunk.
-
- If decode_unicode is True, content will be decoded using the best
- available encoding based on the response.
- """
-
- def generate():
- # Special case for urllib3.
- if hasattr(self.raw, 'stream'):
- try:
- for chunk in self.raw.stream(chunk_size, decode_content=True):
- yield chunk
- except ProtocolError as e:
- raise ChunkedEncodingError(e)
- except DecodeError as e:
- raise ContentDecodingError(e)
- except ReadTimeoutError as e:
- raise ConnectionError(e)
- else:
- # Standard file-like object.
- while True:
- chunk = self.raw.read(chunk_size)
- if not chunk:
- break
- yield chunk
-
- self._content_consumed = True
-
- if self._content_consumed and isinstance(self._content, bool):
- raise StreamConsumedError()
- elif chunk_size is not None and not isinstance(chunk_size, int):
- raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size))
- # simulate reading small chunks of the content
- reused_chunks = iter_slices(self._content, chunk_size)
-
- stream_chunks = generate()
-
- chunks = reused_chunks if self._content_consumed else stream_chunks
-
- if decode_unicode:
- chunks = stream_decode_response_unicode(chunks, self)
-
- return chunks
-
- def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None):
- """Iterates over the response data, one line at a time. When
- stream=True is set on the request, this avoids reading the
- content at once into memory for large responses.
-
- .. note:: This method is not reentrant safe.
- """
-
- pending = None
-
- for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode):
-
- if pending is not None:
- chunk = pending + chunk
-
- if delimiter:
- lines = chunk.split(delimiter)
- else:
- lines = chunk.splitlines()
-
- if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
- pending = lines.pop()
- else:
- pending = None
-
- for line in lines:
- yield line
-
- if pending is not None:
- yield pending
-
- @property
- def content(self):
- """Content of the response, in bytes."""
-
- if self._content is False:
- # Read the contents.
- if self._content_consumed:
- raise RuntimeError(
- 'The content for this response was already consumed')
-
- if self.status_code == 0 or self.raw is None:
- self._content = None
- else:
- self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
-
- self._content_consumed = True
- # don't need to release the connection; that's been handled by urllib3
- # since we exhausted the data.
- return self._content
-
- @property
- def text(self):
- """Content of the response, in unicode.
-
- If Response.encoding is None, encoding will be guessed using
- ``chardet``.
-
- The encoding of the response content is determined based solely on HTTP
- headers, following RFC 2616 to the letter. If you can take advantage of
- non-HTTP knowledge to make a better guess at the encoding, you should
- set ``r.encoding`` appropriately before accessing this property.
- """
-
- # Try charset from content-type
- content = None
- encoding = self.encoding
-
- if not self.content:
- return str('')
-
- # Fallback to auto-detected encoding.
- if self.encoding is None:
- encoding = self.apparent_encoding
-
- # Decode unicode from given encoding.
- try:
- content = str(self.content, encoding, errors='replace')
- except (LookupError, TypeError):
- # A LookupError is raised if the encoding was not found which could
- # indicate a misspelling or similar mistake.
- #
- # A TypeError can be raised if encoding is None
- #
- # So we try blindly encoding.
- content = str(self.content, errors='replace')
-
- return content
-
- def json(self, **kwargs):
- """Returns the json-encoded content of a response, if any.
-
- :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
- :raises ValueError: If the response body does not contain valid json.
- """
-
- if not self.encoding and self.content and len(self.content) > 3:
- # No encoding set. JSON RFC 4627 section 3 states we should expect
- # UTF-8, -16 or -32. Detect which one to use; If the detection or
- # decoding fails, fall back to `self.text` (using chardet to make
- # a best guess).
- encoding = guess_json_utf(self.content)
- if encoding is not None:
- try:
- return complexjson.loads(
- self.content.decode(encoding), **kwargs
- )
- except UnicodeDecodeError:
- # Wrong UTF codec detected; usually because it's not UTF-8
- # but some other 8-bit codec. This is an RFC violation,
- # and the server didn't bother to tell us what codec *was*
- # used.
- pass
- return complexjson.loads(self.text, **kwargs)
-
- @property
- def links(self):
- """Returns the parsed header links of the response, if any."""
-
- header = self.headers.get('link')
-
- # l = MultiDict()
- l = {}
-
- if header:
- links = parse_header_links(header)
-
- for link in links:
- key = link.get('rel') or link.get('url')
- l[key] = link
-
- return l
-
- def raise_for_status(self):
- """Raises stored :class:`HTTPError`, if one occurred."""
-
- http_error_msg = ''
- if isinstance(self.reason, bytes):
- # We attempt to decode utf-8 first because some servers
- # choose to localize their reason strings. If the string
- # isn't utf-8, we fall back to iso-8859-1 for all other
- # encodings. (See PR #3538)
- try:
- reason = self.reason.decode('utf-8')
- except UnicodeDecodeError:
- reason = self.reason.decode('iso-8859-1')
- else:
- reason = self.reason
-
- if 400 <= self.status_code < 500:
- http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
-
- elif 500 <= self.status_code < 600:
- http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)
-
- if http_error_msg:
- raise HTTPError(http_error_msg, response=self)
-
- def close(self):
- """Releases the connection back to the pool. Once this method has been
- called the underlying ``raw`` object must not be accessed again.
-
- *Note: Should not normally need to be called explicitly.*
- """
- if not self._content_consumed:
- self.raw.close()
-
- release_conn = getattr(self.raw, 'release_conn', None)
- if release_conn is not None:
- release_conn()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/__init__.py
deleted file mode 100644
index 971c2ad0..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/__init__.py
+++ /dev/null
@@ -1,36 +0,0 @@
-'''
-Debian and other distributions "unbundle" requests' vendored dependencies, and
-rewrite all imports to use the global versions of ``urllib3`` and ``chardet``.
-The problem with this is that not only requests itself imports those
-dependencies, but third-party code outside of the distros' control too.
-
-In reaction to these problems, the distro maintainers replaced
-``requests.packages`` with a magical "stub module" that imports the correct
-modules. The implementations were varying in quality and all had severe
-problems. For example, a symlink (or hardlink) that links the correct modules
-into place introduces problems regarding object identity, since you now have
-two modules in `sys.modules` with the same API, but different identities::
-
- requests.packages.urllib3 is not urllib3
-
-With version ``2.5.2``, requests started to maintain its own stub, so that
-distro-specific breakage would be reduced to a minimum, even though the whole
-issue is not requests' fault in the first place. See
-https://github.com/kennethreitz/requests/pull/2375 for the corresponding pull
-request.
-'''
-
-from __future__ import absolute_import
-import sys
-
-try:
- from . import urllib3
-except ImportError:
- import urllib3
- sys.modules['%s.urllib3' % __name__] = urllib3
-
-try:
- from . import chardet
-except ImportError:
- import chardet
- sys.modules['%s.chardet' % __name__] = chardet
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/__init__.py
deleted file mode 100644
index 82c2a48d..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/__init__.py
+++ /dev/null
@@ -1,32 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-__version__ = "2.3.0"
-from sys import version_info
-
-
-def detect(aBuf):
- if ((version_info < (3, 0) and isinstance(aBuf, unicode)) or
- (version_info >= (3, 0) and not isinstance(aBuf, bytes))):
- raise ValueError('Expected a bytes object, not a unicode object')
-
- from . import universaldetector
- u = universaldetector.UniversalDetector()
- u.reset()
- u.feed(aBuf)
- u.close()
- return u.result
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5freq.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5freq.py
deleted file mode 100644
index 65bffc04..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5freq.py
+++ /dev/null
@@ -1,925 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# Big5 frequency table
-# by Taiwan's Mandarin Promotion Council
-# <http://www.edu.tw:81/mandr/>
-#
-# 128 --> 0.42261
-# 256 --> 0.57851
-# 512 --> 0.74851
-# 1024 --> 0.89384
-# 2048 --> 0.97583
-#
-# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98
-# Random Distribution Ration = 512/(5401-512)=0.105
-#
-# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR
-
-BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75
-
-#Char to FreqOrder table
-BIG5_TABLE_SIZE = 5376
-
-Big5CharToFreqOrder = (
- 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16
-3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32
-1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48
- 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64
-3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80
-4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96
-5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112
- 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128
- 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144
- 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160
-2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176
-1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192
-3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208
- 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224
-1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240
-3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256
-2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272
- 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288
-3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304
-1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320
-5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336
- 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352
-5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368
-1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384
- 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400
- 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416
-3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432
-3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448
- 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464
-2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480
-2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496
- 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512
- 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528
-3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544
-1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560
-1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576
-1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592
-2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608
- 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624
-4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640
-1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656
-5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672
-2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688
- 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704
- 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720
- 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736
- 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752
-5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768
- 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784
-1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800
- 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816
- 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832
-5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848
-1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864
- 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880
-3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896
-4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912
-3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928
- 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944
- 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960
-1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976
-4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992
-3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008
-3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024
-2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040
-5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056
-3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072
-5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088
-1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104
-2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120
-1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136
- 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152
-1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168
-4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184
-3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200
- 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216
- 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232
- 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248
-2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264
-5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280
-1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296
-2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312
-1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328
-1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344
-5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360
-5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376
-5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392
-3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408
-4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424
-4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440
-2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456
-5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472
-3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488
- 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504
-5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520
-5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536
-1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552
-2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568
-3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584
-4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600
-5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616
-3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632
-4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648
-1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664
-1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680
-4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696
-1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712
- 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728
-1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744
-1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760
-3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776
- 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792
-5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808
-2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824
-1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840
-1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856
-5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872
- 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888
-4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904
- 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920
-2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936
- 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952
-1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968
-1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984
- 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000
-4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016
-4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032
-1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048
-3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064
-5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080
-5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096
-1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112
-2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128
-1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144
-3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160
-2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176
-3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192
-2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208
-4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224
-4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240
-3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256
- 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272
-3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288
- 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304
-3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320
-4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336
-3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352
-1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368
-5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384
- 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400
-5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416
-1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432
- 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448
-4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464
-4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480
- 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496
-2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512
-2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528
-3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544
-1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560
-4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576
-2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592
-1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608
-1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624
-2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640
-3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656
-1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672
-5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688
-1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704
-4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720
-1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736
- 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752
-1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768
-4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784
-4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800
-2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816
-1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832
-4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848
- 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864
-5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880
-2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896
-3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912
-4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928
- 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944
-5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960
-5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976
-1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992
-4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008
-4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024
-2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040
-3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056
-3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072
-2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088
-1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104
-4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120
-3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136
-3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152
-2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168
-4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184
-5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200
-3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216
-2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232
-3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248
-1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264
-2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280
-3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296
-4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312
-2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328
-2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344
-5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360
-1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376
-2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392
-1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408
-3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424
-4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440
-2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456
-3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472
-3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488
-2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504
-4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520
-2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536
-3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552
-4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568
-5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584
-3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600
- 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616
-1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632
-4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648
-1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664
-4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680
-5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696
- 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712
-5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728
-5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744
-2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760
-3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776
-2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792
-2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808
- 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824
-1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840
-4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856
-3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872
-3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888
- 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904
-2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920
- 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936
-2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952
-4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968
-1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984
-4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000
-1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016
-3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032
- 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048
-3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064
-5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080
-5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096
-3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112
-3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128
-1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144
-2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160
-5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176
-1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192
-1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208
-3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224
- 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240
-1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256
-4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272
-5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288
-2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304
-3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320
- 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336
-1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352
-2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368
-2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384
-5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400
-5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416
-5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432
-2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448
-2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464
-1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480
-4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496
-3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512
-3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528
-4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544
-4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560
-2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576
-2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592
-5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608
-4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624
-5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640
-4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656
- 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672
- 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688
-1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704
-3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720
-4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736
-1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752
-5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768
-2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784
-2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800
-3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816
-5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832
-1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848
-3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864
-5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880
-1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896
-5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912
-2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928
-3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944
-2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960
-3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976
-3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992
-3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008
-4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024
- 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040
-2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056
-4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072
-3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088
-5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104
-1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120
-5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136
- 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152
-1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168
- 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184
-4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200
-1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216
-4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232
-1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248
- 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264
-3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280
-4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296
-5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312
- 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328
-3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344
- 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360
-2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 #last 512
-#Everything below is of no interest for detection purpose
-2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, # 5392
-2500,3034,3800,5803,5804,2195,4814,5805,2163,5806,5807,5808,5809,5810,5811,5812, # 5408
-5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828, # 5424
-5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844, # 5440
-5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860, # 5456
-5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876, # 5472
-5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892, # 5488
-5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908, # 5504
-5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924, # 5520
-5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940, # 5536
-5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,5956, # 5552
-5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972, # 5568
-5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984,5985,5986,5987,5988, # 5584
-5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004, # 5600
-6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020, # 5616
-6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036, # 5632
-6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052, # 5648
-6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068, # 5664
-6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084, # 5680
-6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100, # 5696
-6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116, # 5712
-6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132, # 5728
-6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148, # 5744
-6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164, # 5760
-6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180, # 5776
-6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196, # 5792
-6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212, # 5808
-6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,3670,6224,6225,6226,6227, # 5824
-6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243, # 5840
-6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259, # 5856
-6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275, # 5872
-6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,4815,6286,6287,6288,6289,6290, # 5888
-6291,6292,4816,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305, # 5904
-6306,6307,6308,6309,6310,6311,4817,4818,6312,6313,6314,6315,6316,6317,6318,4819, # 5920
-6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334, # 5936
-6335,6336,6337,4820,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349, # 5952
-6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365, # 5968
-6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381, # 5984
-6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397, # 6000
-6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,3441,6411,6412, # 6016
-6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,4440,6426,6427, # 6032
-6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443, # 6048
-6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,4821,6455,6456,6457,6458, # 6064
-6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474, # 6080
-6475,6476,6477,3947,3948,6478,6479,6480,6481,3272,4441,6482,6483,6484,6485,4442, # 6096
-6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,4822,6497,6498,6499,6500, # 6112
-6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516, # 6128
-6517,6518,6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532, # 6144
-6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548, # 6160
-6549,6550,6551,6552,6553,6554,6555,6556,2784,6557,4823,6558,6559,6560,6561,6562, # 6176
-6563,6564,6565,6566,6567,6568,6569,3949,6570,6571,6572,4824,6573,6574,6575,6576, # 6192
-6577,6578,6579,6580,6581,6582,6583,4825,6584,6585,6586,3950,2785,6587,6588,6589, # 6208
-6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605, # 6224
-6606,6607,6608,6609,6610,6611,6612,4826,6613,6614,6615,4827,6616,6617,6618,6619, # 6240
-6620,6621,6622,6623,6624,6625,4164,6626,6627,6628,6629,6630,6631,6632,6633,6634, # 6256
-3547,6635,4828,6636,6637,6638,6639,6640,6641,6642,3951,2984,6643,6644,6645,6646, # 6272
-6647,6648,6649,4165,6650,4829,6651,6652,4830,6653,6654,6655,6656,6657,6658,6659, # 6288
-6660,6661,6662,4831,6663,6664,6665,6666,6667,6668,6669,6670,6671,4166,6672,4832, # 6304
-3952,6673,6674,6675,6676,4833,6677,6678,6679,4167,6680,6681,6682,3198,6683,6684, # 6320
-6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,4834,6698,6699, # 6336
-6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715, # 6352
-6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731, # 6368
-6732,6733,6734,4443,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,4444, # 6384
-6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761, # 6400
-6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777, # 6416
-6778,6779,6780,6781,4168,6782,6783,3442,6784,6785,6786,6787,6788,6789,6790,6791, # 6432
-4169,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806, # 6448
-6807,6808,6809,6810,6811,4835,6812,6813,6814,4445,6815,6816,4446,6817,6818,6819, # 6464
-6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,6835, # 6480
-3548,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,4836,6847,6848,6849, # 6496
-6850,6851,6852,6853,6854,3953,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864, # 6512
-6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,3199,6878,6879, # 6528
-6880,6881,6882,4447,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894, # 6544
-6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,4170,6905,6906,6907,6908,6909, # 6560
-6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,6925, # 6576
-6926,6927,4837,6928,6929,6930,6931,6932,6933,6934,6935,6936,3346,6937,6938,4838, # 6592
-6939,6940,6941,4448,6942,6943,6944,6945,6946,4449,6947,6948,6949,6950,6951,6952, # 6608
-6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968, # 6624
-6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984, # 6640
-6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,3671,6995,6996,6997,6998,4839, # 6656
-6999,7000,7001,7002,3549,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013, # 6672
-7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029, # 6688
-7030,4840,7031,7032,7033,7034,7035,7036,7037,7038,4841,7039,7040,7041,7042,7043, # 6704
-7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059, # 6720
-7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,2985,7071,7072,7073,7074, # 6736
-7075,7076,7077,7078,7079,7080,4842,7081,7082,7083,7084,7085,7086,7087,7088,7089, # 6752
-7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105, # 6768
-7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,4450,7119,7120, # 6784
-7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136, # 6800
-7137,7138,7139,7140,7141,7142,7143,4843,7144,7145,7146,7147,7148,7149,7150,7151, # 6816
-7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167, # 6832
-7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183, # 6848
-7184,7185,7186,7187,7188,4171,4172,7189,7190,7191,7192,7193,7194,7195,7196,7197, # 6864
-7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213, # 6880
-7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229, # 6896
-7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245, # 6912
-7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261, # 6928
-7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277, # 6944
-7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293, # 6960
-7294,7295,7296,4844,7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308, # 6976
-7309,7310,7311,7312,7313,7314,7315,7316,4451,7317,7318,7319,7320,7321,7322,7323, # 6992
-7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339, # 7008
-7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,4173,7354, # 7024
-7355,4845,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369, # 7040
-7370,7371,7372,7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385, # 7056
-7386,7387,7388,4846,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400, # 7072
-7401,7402,7403,7404,7405,3672,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415, # 7088
-7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431, # 7104
-7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447, # 7120
-7448,7449,7450,7451,7452,7453,4452,7454,3200,7455,7456,7457,7458,7459,7460,7461, # 7136
-7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,4847,7475,7476, # 7152
-7477,3133,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491, # 7168
-7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,3347,7503,7504,7505,7506, # 7184
-7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,4848, # 7200
-7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537, # 7216
-7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,3801,4849,7550,7551, # 7232
-7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, # 7248
-7568,7569,3035,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582, # 7264
-7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598, # 7280
-7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614, # 7296
-7615,7616,4850,7617,7618,3802,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628, # 7312
-7629,7630,7631,7632,4851,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643, # 7328
-7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659, # 7344
-7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,4453,7671,7672,7673,7674, # 7360
-7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690, # 7376
-7691,7692,7693,7694,7695,7696,7697,3443,7698,7699,7700,7701,7702,4454,7703,7704, # 7392
-7705,7706,7707,7708,7709,7710,7711,7712,7713,2472,7714,7715,7716,7717,7718,7719, # 7408
-7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,3954,7732,7733,7734, # 7424
-7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750, # 7440
-3134,7751,7752,4852,7753,7754,7755,4853,7756,7757,7758,7759,7760,4174,7761,7762, # 7456
-7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778, # 7472
-7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794, # 7488
-7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,4854,7806,7807,7808,7809, # 7504
-7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825, # 7520
-4855,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, # 7536
-7841,7842,7843,7844,7845,7846,7847,3955,7848,7849,7850,7851,7852,7853,7854,7855, # 7552
-7856,7857,7858,7859,7860,3444,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870, # 7568
-7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886, # 7584
-7887,7888,7889,7890,7891,4175,7892,7893,7894,7895,7896,4856,4857,7897,7898,7899, # 7600
-7900,2598,7901,7902,7903,7904,7905,7906,7907,7908,4455,7909,7910,7911,7912,7913, # 7616
-7914,3201,7915,7916,7917,7918,7919,7920,7921,4858,7922,7923,7924,7925,7926,7927, # 7632
-7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943, # 7648
-7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7958,7959, # 7664
-7960,7961,7962,7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973,7974,7975, # 7680
-7976,7977,7978,7979,7980,7981,4859,7982,7983,7984,7985,7986,7987,7988,7989,7990, # 7696
-7991,7992,7993,7994,7995,7996,4860,7997,7998,7999,8000,8001,8002,8003,8004,8005, # 7712
-8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,8016,4176,8017,8018,8019,8020, # 7728
-8021,8022,8023,4861,8024,8025,8026,8027,8028,8029,8030,8031,8032,8033,8034,8035, # 7744
-8036,4862,4456,8037,8038,8039,8040,4863,8041,8042,8043,8044,8045,8046,8047,8048, # 7760
-8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,8064, # 7776
-8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080, # 7792
-8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096, # 7808
-8097,8098,8099,4864,4177,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110, # 7824
-8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,4178,8121,8122,8123,8124,8125, # 7840
-8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141, # 7856
-8142,8143,8144,8145,4865,4866,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155, # 7872
-8156,8157,8158,8159,8160,8161,8162,8163,8164,8165,4179,8166,8167,8168,8169,8170, # 7888
-8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,4457,8182,8183,8184,8185, # 7904
-8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201, # 7920
-8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213,8214,8215,8216,8217, # 7936
-8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233, # 7952
-8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249, # 7968
-8250,8251,8252,8253,8254,8255,8256,3445,8257,8258,8259,8260,8261,8262,4458,8263, # 7984
-8264,8265,8266,8267,8268,8269,8270,8271,8272,4459,8273,8274,8275,8276,3550,8277, # 8000
-8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,4460,8290,8291,8292, # 8016
-8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,4867, # 8032
-8308,8309,8310,8311,8312,3551,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322, # 8048
-8323,8324,8325,8326,4868,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337, # 8064
-8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353, # 8080
-8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,4869,4461,8364,8365,8366,8367, # 8096
-8368,8369,8370,4870,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382, # 8112
-8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398, # 8128
-8399,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,4871,8411,8412,8413, # 8144
-8414,8415,8416,8417,8418,8419,8420,8421,8422,4462,8423,8424,8425,8426,8427,8428, # 8160
-8429,8430,8431,8432,8433,2986,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443, # 8176
-8444,8445,8446,8447,8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459, # 8192
-8460,8461,8462,8463,8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475, # 8208
-8476,8477,8478,4180,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490, # 8224
-8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506, # 8240
-8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522, # 8256
-8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538, # 8272
-8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554, # 8288
-8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,4872,8565,8566,8567,8568,8569, # 8304
-8570,8571,8572,8573,4873,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584, # 8320
-8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600, # 8336
-8601,8602,8603,8604,8605,3803,8606,8607,8608,8609,8610,8611,8612,8613,4874,3804, # 8352
-8614,8615,8616,8617,8618,8619,8620,8621,3956,8622,8623,8624,8625,8626,8627,8628, # 8368
-8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,2865,8639,8640,8641,8642,8643, # 8384
-8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,4463,8657,8658, # 8400
-8659,4875,4876,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672, # 8416
-8673,8674,8675,8676,8677,8678,8679,8680,8681,4464,8682,8683,8684,8685,8686,8687, # 8432
-8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, # 8448
-8704,8705,8706,8707,8708,8709,2261,8710,8711,8712,8713,8714,8715,8716,8717,8718, # 8464
-8719,8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,4181, # 8480
-8734,8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749, # 8496
-8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,4877,8764, # 8512
-8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,8780, # 8528
-8781,8782,8783,8784,8785,8786,8787,8788,4878,8789,4879,8790,8791,8792,4880,8793, # 8544
-8794,8795,8796,8797,8798,8799,8800,8801,4881,8802,8803,8804,8805,8806,8807,8808, # 8560
-8809,8810,8811,8812,8813,8814,8815,3957,8816,8817,8818,8819,8820,8821,8822,8823, # 8576
-8824,8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839, # 8592
-8840,8841,8842,8843,8844,8845,8846,8847,4882,8848,8849,8850,8851,8852,8853,8854, # 8608
-8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,8870, # 8624
-8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,3202,8885, # 8640
-8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8901, # 8656
-8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917, # 8672
-8918,8919,8920,8921,8922,8923,8924,4465,8925,8926,8927,8928,8929,8930,8931,8932, # 8688
-4883,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,2214,8944,8945,8946, # 8704
-8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,8960,8961,8962, # 8720
-8963,8964,8965,4884,8966,8967,8968,8969,8970,8971,8972,8973,8974,8975,8976,8977, # 8736
-8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,8990,8991,8992,4885, # 8752
-8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,9008, # 8768
-9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,4182,9022,9023, # 8784
-9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039, # 8800
-9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,9053,9054,9055, # 8816
-9056,9057,9058,9059,9060,9061,9062,9063,4886,9064,9065,9066,9067,9068,9069,4887, # 8832
-9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,9083,9084,9085, # 8848
-9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9101, # 8864
-9102,9103,9104,9105,9106,9107,9108,9109,9110,9111,9112,9113,9114,9115,9116,9117, # 8880
-9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133, # 8896
-9134,9135,9136,9137,9138,9139,9140,9141,3958,9142,9143,9144,9145,9146,9147,9148, # 8912
-9149,9150,9151,4888,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,9163, # 8928
-9164,9165,9166,9167,9168,9169,9170,9171,9172,9173,9174,9175,4889,9176,9177,9178, # 8944
-9179,9180,9181,9182,9183,9184,9185,9186,9187,9188,9189,9190,9191,9192,9193,9194, # 8960
-9195,9196,9197,9198,9199,9200,9201,9202,9203,4890,9204,9205,9206,9207,9208,9209, # 8976
-9210,9211,9212,9213,9214,9215,9216,9217,9218,9219,9220,9221,9222,4466,9223,9224, # 8992
-9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240, # 9008
-9241,9242,9243,9244,9245,4891,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255, # 9024
-9256,9257,4892,9258,9259,9260,9261,4893,4894,9262,9263,9264,9265,9266,9267,9268, # 9040
-9269,9270,9271,9272,9273,4467,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283, # 9056
-9284,9285,3673,9286,9287,9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298, # 9072
-9299,9300,9301,9302,9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314, # 9088
-9315,9316,9317,9318,9319,9320,9321,9322,4895,9323,9324,9325,9326,9327,9328,9329, # 9104
-9330,9331,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345, # 9120
-9346,9347,4468,9348,9349,9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360, # 9136
-9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9372,9373,4896,9374,4469, # 9152
-9375,9376,9377,9378,9379,4897,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389, # 9168
-9390,9391,9392,9393,9394,9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405, # 9184
-9406,4470,9407,2751,9408,9409,3674,3552,9410,9411,9412,9413,9414,9415,9416,9417, # 9200
-9418,9419,9420,9421,4898,9422,9423,9424,9425,9426,9427,9428,9429,3959,9430,9431, # 9216
-9432,9433,9434,9435,9436,4471,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446, # 9232
-9447,9448,9449,9450,3348,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461, # 9248
-9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,4899,9473,9474,9475,9476, # 9264
-9477,4900,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,3349,9489,9490, # 9280
-9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506, # 9296
-9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,4901,9521, # 9312
-9522,9523,9524,9525,9526,4902,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536, # 9328
-9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,9551,9552, # 9344
-9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568, # 9360
-9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584, # 9376
-3805,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599, # 9392
-9600,9601,9602,4903,9603,9604,9605,9606,9607,4904,9608,9609,9610,9611,9612,9613, # 9408
-9614,4905,9615,9616,9617,9618,9619,9620,9621,9622,9623,9624,9625,9626,9627,9628, # 9424
-9629,9630,9631,9632,4906,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643, # 9440
-4907,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658, # 9456
-9659,9660,9661,9662,9663,9664,9665,9666,9667,9668,9669,9670,9671,9672,4183,9673, # 9472
-9674,9675,9676,9677,4908,9678,9679,9680,9681,4909,9682,9683,9684,9685,9686,9687, # 9488
-9688,9689,9690,4910,9691,9692,9693,3675,9694,9695,9696,2945,9697,9698,9699,9700, # 9504
-9701,9702,9703,9704,9705,4911,9706,9707,9708,9709,9710,9711,9712,9713,9714,9715, # 9520
-9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731, # 9536
-9732,9733,9734,9735,4912,9736,9737,9738,9739,9740,4913,9741,9742,9743,9744,9745, # 9552
-9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,4914,9759,9760, # 9568
-9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776, # 9584
-9777,9778,9779,9780,9781,9782,4915,9783,9784,9785,9786,9787,9788,9789,9790,9791, # 9600
-9792,9793,4916,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806, # 9616
-9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822, # 9632
-9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838, # 9648
-9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854, # 9664
-9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,4917,9869, # 9680
-9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885, # 9696
-9886,9887,9888,9889,9890,9891,9892,4472,9893,9894,9895,9896,9897,3806,9898,9899, # 9712
-9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,4918, # 9728
-9915,9916,9917,4919,9918,9919,9920,9921,4184,9922,9923,9924,9925,9926,9927,9928, # 9744
-9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944, # 9760
-9945,9946,4920,9947,9948,9949,9950,9951,9952,9953,9954,9955,4185,9956,9957,9958, # 9776
-9959,9960,9961,9962,9963,9964,9965,4921,9966,9967,9968,4473,9969,9970,9971,9972, # 9792
-9973,9974,9975,9976,9977,4474,9978,9979,9980,9981,9982,9983,9984,9985,9986,9987, # 9808
-9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001,10002,10003, # 9824
-10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019, # 9840
-10020,10021,4922,10022,4923,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032,10033, # 9856
-10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,4924, # 9872
-10049,10050,10051,10052,10053,10054,10055,10056,10057,10058,10059,10060,10061,10062,10063,10064, # 9888
-10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080, # 9904
-10081,10082,10083,10084,10085,10086,10087,4475,10088,10089,10090,10091,10092,10093,10094,10095, # 9920
-10096,10097,4476,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110, # 9936
-10111,2174,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125, # 9952
-10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,3807, # 9968
-4186,4925,10141,10142,10143,10144,10145,10146,10147,4477,4187,10148,10149,10150,10151,10152, # 9984
-10153,4188,10154,10155,10156,10157,10158,10159,10160,10161,4926,10162,10163,10164,10165,10166, #10000
-10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182, #10016
-10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,3203,10193,10194,10195,10196,10197, #10032
-10198,10199,10200,4478,10201,10202,10203,10204,4479,10205,10206,10207,10208,10209,10210,10211, #10048
-10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227, #10064
-10228,10229,10230,10231,10232,10233,10234,4927,10235,10236,10237,10238,10239,10240,10241,10242, #10080
-10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258, #10096
-10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,4480, #10112
-4928,4929,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,10286,10287, #10128
-10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303, #10144
-10304,10305,10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319, #10160
-10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,10334,4930, #10176
-10335,10336,10337,10338,10339,10340,10341,10342,4931,10343,10344,10345,10346,10347,10348,10349, #10192
-10350,10351,10352,10353,10354,10355,3088,10356,2786,10357,10358,10359,10360,4189,10361,10362, #10208
-10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,4932,10376,10377, #10224
-10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10392,4933, #10240
-10393,10394,10395,4934,10396,10397,10398,10399,10400,10401,10402,10403,10404,10405,10406,10407, #10256
-10408,10409,10410,10411,10412,3446,10413,10414,10415,10416,10417,10418,10419,10420,10421,10422, #10272
-10423,4935,10424,10425,10426,10427,10428,10429,10430,4936,10431,10432,10433,10434,10435,10436, #10288
-10437,10438,10439,10440,10441,10442,10443,4937,10444,10445,10446,10447,4481,10448,10449,10450, #10304
-10451,10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,10466, #10320
-10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482, #10336
-10483,10484,10485,10486,10487,10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498, #10352
-10499,10500,10501,10502,10503,10504,10505,4938,10506,10507,10508,10509,10510,2552,10511,10512, #10368
-10513,10514,10515,10516,3447,10517,10518,10519,10520,10521,10522,10523,10524,10525,10526,10527, #10384
-10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543, #10400
-4482,10544,4939,10545,10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557, #10416
-10558,10559,10560,10561,10562,10563,10564,10565,10566,10567,3676,4483,10568,10569,10570,10571, #10432
-10572,3448,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,10586, #10448
-10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602, #10464
-10603,10604,10605,10606,10607,10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618, #10480
-10619,10620,10621,10622,10623,10624,10625,10626,10627,4484,10628,10629,10630,10631,10632,4940, #10496
-10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,10648, #10512
-10649,10650,10651,10652,10653,10654,10655,10656,4941,10657,10658,10659,2599,10660,10661,10662, #10528
-10663,10664,10665,10666,3089,10667,10668,10669,10670,10671,10672,10673,10674,10675,10676,10677, #10544
-10678,10679,10680,4942,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692, #10560
-10693,10694,10695,10696,10697,4485,10698,10699,10700,10701,10702,10703,10704,4943,10705,3677, #10576
-10706,10707,10708,10709,10710,10711,10712,4944,10713,10714,10715,10716,10717,10718,10719,10720, #10592
-10721,10722,10723,10724,10725,10726,10727,10728,4945,10729,10730,10731,10732,10733,10734,10735, #10608
-10736,10737,10738,10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751, #10624
-10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,4946,10762,10763,10764,10765,10766, #10640
-10767,4947,4948,10768,10769,10770,10771,10772,10773,10774,10775,10776,10777,10778,10779,10780, #10656
-10781,10782,10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796, #10672
-10797,10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,10812, #10688
-10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,10824,10825,10826,10827,10828, #10704
-10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844, #10720
-10845,10846,10847,10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860, #10736
-10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,10874,10875,10876, #10752
-10877,10878,4486,10879,10880,10881,10882,10883,10884,10885,4949,10886,10887,10888,10889,10890, #10768
-10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906, #10784
-10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,4487,10920,10921, #10800
-10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,4950,10933,10934,10935,10936, #10816
-10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,4488,10950,10951, #10832
-10952,10953,10954,10955,10956,10957,10958,10959,4190,10960,10961,10962,10963,10964,10965,10966, #10848
-10967,10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,10980,10981,10982, #10864
-10983,10984,10985,10986,10987,10988,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998, #10880
-10999,11000,11001,11002,11003,11004,11005,11006,3960,11007,11008,11009,11010,11011,11012,11013, #10896
-11014,11015,11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029, #10912
-11030,11031,11032,4951,11033,11034,11035,11036,11037,11038,11039,11040,11041,11042,11043,11044, #10928
-11045,11046,11047,4489,11048,11049,11050,11051,4952,11052,11053,11054,11055,11056,11057,11058, #10944
-4953,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,11070,11071,4954,11072, #10960
-11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088, #10976
-11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,11102,11103,11104, #10992
-11105,11106,11107,11108,11109,11110,11111,11112,11113,11114,11115,3808,11116,11117,11118,11119, #11008
-11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,4955, #11024
-11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150, #11040
-11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,4956,11162,11163,11164,11165, #11056
-11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,4957, #11072
-11181,11182,11183,11184,11185,11186,4958,11187,11188,11189,11190,11191,11192,11193,11194,11195, #11088
-11196,11197,11198,11199,11200,3678,11201,11202,11203,11204,11205,11206,4191,11207,11208,11209, #11104
-11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,11220,11221,11222,11223,11224,11225, #11120
-11226,11227,11228,11229,11230,11231,11232,11233,11234,11235,11236,11237,11238,11239,11240,11241, #11136
-11242,11243,11244,11245,11246,11247,11248,11249,11250,11251,4959,11252,11253,11254,11255,11256, #11152
-11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272, #11168
-11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288, #11184
-11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304, #11200
-11305,11306,11307,11308,11309,11310,11311,11312,11313,11314,3679,11315,11316,11317,11318,4490, #11216
-11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334, #11232
-11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,4960,11348,11349, #11248
-11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365, #11264
-11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,3961,4961,11378,11379, #11280
-11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395, #11296
-11396,11397,4192,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410, #11312
-11411,4962,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425, #11328
-11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441, #11344
-11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457, #11360
-11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,4963,11470,11471,4491, #11376
-11472,11473,11474,11475,4964,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486, #11392
-11487,11488,11489,11490,11491,11492,4965,11493,11494,11495,11496,11497,11498,11499,11500,11501, #11408
-11502,11503,11504,11505,11506,11507,11508,11509,11510,11511,11512,11513,11514,11515,11516,11517, #11424
-11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,3962,11530,11531,11532, #11440
-11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548, #11456
-11549,11550,11551,11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564, #11472
-4193,4194,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578, #11488
-11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,4966,4195,11592, #11504
-11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,3090,11605,11606,11607, #11520
-11608,11609,11610,4967,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622, #11536
-11623,11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638, #11552
-11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654, #11568
-11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670, #11584
-11671,11672,11673,11674,4968,11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685, #11600
-11686,11687,11688,11689,11690,11691,11692,11693,3809,11694,11695,11696,11697,11698,11699,11700, #11616
-11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,11711,11712,11713,11714,11715,11716, #11632
-11717,11718,3553,11719,11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,4969, #11648
-11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,4492,11741,11742,11743,11744,11745, #11664
-11746,11747,11748,11749,11750,11751,11752,4970,11753,11754,11755,11756,11757,11758,11759,11760, #11680
-11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,11776, #11696
-11777,11778,11779,11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,4971,11791, #11712
-11792,11793,11794,11795,11796,11797,4972,11798,11799,11800,11801,11802,11803,11804,11805,11806, #11728
-11807,11808,11809,11810,4973,11811,11812,11813,11814,11815,11816,11817,11818,11819,11820,11821, #11744
-11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,3680,3810,11835, #11760
-11836,4974,11837,11838,11839,11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850, #11776
-11851,11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,11864,11865,11866, #11792
-11867,11868,11869,11870,11871,11872,11873,11874,11875,11876,11877,11878,11879,11880,11881,11882, #11808
-11883,11884,4493,11885,11886,11887,11888,11889,11890,11891,11892,11893,11894,11895,11896,11897, #11824
-11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913, #11840
-11914,11915,4975,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928, #11856
-11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944, #11872
-11945,11946,11947,11948,11949,4976,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959, #11888
-11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975, #11904
-11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,4196,11988,11989,11990, #11920
-11991,11992,4977,11993,11994,11995,11996,11997,11998,11999,12000,12001,12002,12003,12004,12005, #11936
-12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021, #11952
-12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037, #11968
-12038,12039,12040,12041,12042,12043,12044,12045,12046,12047,12048,12049,12050,12051,12052,12053, #11984
-12054,12055,12056,12057,12058,12059,12060,12061,4978,12062,12063,12064,12065,12066,12067,12068, #12000
-12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,12083,12084, #12016
-12085,12086,12087,12088,12089,12090,12091,12092,12093,12094,12095,12096,12097,12098,12099,12100, #12032
-12101,12102,12103,12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,12116, #12048
-12117,12118,12119,12120,12121,12122,12123,4979,12124,12125,12126,12127,12128,4197,12129,12130, #12064
-12131,12132,12133,12134,12135,12136,12137,12138,12139,12140,12141,12142,12143,12144,12145,12146, #12080
-12147,12148,12149,12150,12151,12152,12153,12154,4980,12155,12156,12157,12158,12159,12160,4494, #12096
-12161,12162,12163,12164,3811,12165,12166,12167,12168,12169,4495,12170,12171,4496,12172,12173, #12112
-12174,12175,12176,3812,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188, #12128
-12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200,12201,12202,12203,12204, #12144
-12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,12215,12216,12217,12218,12219,12220, #12160
-12221,4981,12222,12223,12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235, #12176
-4982,12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,4983,12246,12247,12248,12249, #12192
-4984,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,12260,12261,12262,12263,12264, #12208
-4985,12265,4497,12266,12267,12268,12269,12270,12271,12272,12273,12274,12275,12276,12277,12278, #12224
-12279,12280,12281,12282,12283,12284,12285,12286,12287,4986,12288,12289,12290,12291,12292,12293, #12240
-12294,12295,12296,2473,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,12308, #12256
-12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,3963,12320,12321,12322,12323, #12272
-12324,12325,12326,12327,12328,12329,12330,12331,12332,4987,12333,12334,12335,12336,12337,12338, #12288
-12339,12340,12341,12342,12343,12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354, #12304
-12355,12356,12357,12358,12359,3964,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, #12320
-12370,3965,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, #12336
-12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400, #12352
-12401,12402,12403,12404,12405,12406,12407,12408,4988,12409,12410,12411,12412,12413,12414,12415, #12368
-12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, #12384
-12432,12433,12434,12435,12436,12437,12438,3554,12439,12440,12441,12442,12443,12444,12445,12446, #12400
-12447,12448,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, #12416
-12463,12464,4989,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477, #12432
-12478,12479,12480,4990,12481,12482,12483,12484,12485,12486,12487,12488,12489,4498,12490,12491, #12448
-12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, #12464
-12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523, #12480
-12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12539, #12496
-12540,12541,12542,12543,12544,12545,12546,12547,12548,12549,12550,12551,4991,12552,12553,12554, #12512
-12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570, #12528
-12571,12572,12573,12574,12575,12576,12577,12578,3036,12579,12580,12581,12582,12583,3966,12584, #12544
-12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,12599,12600, #12560
-12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616, #12576
-12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632, #12592
-12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,4499,12647, #12608
-12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663, #12624
-12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679, #12640
-12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,12695, #12656
-12696,12697,12698,4992,12699,12700,12701,12702,12703,12704,12705,12706,12707,12708,12709,12710, #12672
-12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726, #12688
-12727,12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,12740,12741,12742, #12704
-12743,12744,12745,12746,12747,12748,12749,12750,12751,12752,12753,12754,12755,12756,12757,12758, #12720
-12759,12760,12761,12762,12763,12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774, #12736
-12775,12776,12777,12778,4993,2175,12779,12780,12781,12782,12783,12784,12785,12786,4500,12787, #12752
-12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,12803, #12768
-12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, #12784
-12820,12821,12822,12823,12824,12825,12826,4198,3967,12827,12828,12829,12830,12831,12832,12833, #12800
-12834,12835,12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849, #12816
-12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,4199,12862,12863,12864, #12832
-12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,12875,12876,12877,12878,12879,12880, #12848
-12881,12882,12883,12884,12885,12886,12887,4501,12888,12889,12890,12891,12892,12893,12894,12895, #12864
-12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911, #12880
-12912,4994,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926, #12896
-12927,12928,12929,12930,12931,12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942, #12912
-12943,12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,1772,12957, #12928
-12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,12971,12972,12973, #12944
-12974,12975,12976,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,12989, #12960
-12990,12991,12992,12993,12994,12995,12996,12997,4502,12998,4503,12999,13000,13001,13002,13003, #12976
-4504,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018, #12992
-13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,3449,13030,13031,13032,13033, #13008
-13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049, #13024
-13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065, #13040
-13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081, #13056
-13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093,13094,13095,13096,13097, #13072
-13098,13099,13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113, #13088
-13114,13115,13116,13117,13118,3968,13119,4995,13120,13121,13122,13123,13124,13125,13126,13127, #13104
-4505,13128,13129,13130,13131,13132,13133,13134,4996,4506,13135,13136,13137,13138,13139,4997, #13120
-13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,13151,13152,13153,13154,13155, #13136
-13156,13157,13158,13159,4998,13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170, #13152
-13171,13172,13173,13174,13175,13176,4999,13177,13178,13179,13180,13181,13182,13183,13184,13185, #13168
-13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,13199,13200,13201, #13184
-13202,13203,13204,13205,13206,5000,13207,13208,13209,13210,13211,13212,13213,13214,13215,13216, #13200
-13217,13218,13219,13220,13221,13222,13223,13224,13225,13226,13227,4200,5001,13228,13229,13230, #13216
-13231,13232,13233,13234,13235,13236,13237,13238,13239,13240,3969,13241,13242,13243,13244,3970, #13232
-13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,13259,13260, #13248
-13261,13262,13263,13264,13265,13266,13267,13268,3450,13269,13270,13271,13272,13273,13274,13275, #13264
-13276,5002,13277,13278,13279,13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290, #13280
-13291,13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,3813,13303,13304,13305, #13296
-13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321, #13312
-13322,13323,13324,13325,13326,13327,13328,4507,13329,13330,13331,13332,13333,13334,13335,13336, #13328
-13337,13338,13339,13340,13341,5003,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351, #13344
-13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367, #13360
-5004,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382, #13376
-13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398, #13392
-13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414, #13408
-13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430, #13424
-13431,13432,4508,13433,13434,13435,4201,13436,13437,13438,13439,13440,13441,13442,13443,13444, #13440
-13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,5005,13458,13459, #13456
-13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,4509,13471,13472,13473,13474, #13472
-13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490, #13488
-13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506, #13504
-13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522, #13520
-13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538, #13536
-13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554, #13552
-13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570, #13568
-13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586, #13584
-13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602, #13600
-13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618, #13616
-13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634, #13632
-13635,13636,13637,13638,13639,13640,13641,13642,5006,13643,13644,13645,13646,13647,13648,13649, #13648
-13650,13651,5007,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664, #13664
-13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680, #13680
-13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696, #13696
-13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712, #13712
-13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728, #13728
-13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744, #13744
-13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760, #13760
-13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,3273,13775, #13776
-13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791, #13792
-13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807, #13808
-13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823, #13824
-13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839, #13840
-13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855, #13856
-13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871, #13872
-13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887, #13888
-13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903, #13904
-13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919, #13920
-13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935, #13936
-13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951, #13952
-13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967, #13968
-13968,13969,13970,13971,13972) #13973
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5prober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5prober.py
deleted file mode 100644
index becce81e..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/big5prober.py
+++ /dev/null
@@ -1,42 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import Big5DistributionAnalysis
-from .mbcssm import Big5SMModel
-
-
-class Big5Prober(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(Big5SMModel)
- self._mDistributionAnalyzer = Big5DistributionAnalysis()
- self.reset()
-
- def get_charset_name(self):
- return "Big5"
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardetect.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardetect.py
deleted file mode 100644
index ffe892f2..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardetect.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-"""
-Script which takes one or more file paths and reports on their detected
-encodings
-
-Example::
-
- % chardetect somefile someotherfile
- somefile: windows-1252 with confidence 0.5
- someotherfile: ascii with confidence 1.0
-
-If no paths are provided, it takes its input from stdin.
-
-"""
-
-from __future__ import absolute_import, print_function, unicode_literals
-
-import argparse
-import sys
-from io import open
-
-from chardet import __version__
-from chardet.universaldetector import UniversalDetector
-
-
-def description_of(lines, name='stdin'):
- """
- Return a string describing the probable encoding of a file or
- list of strings.
-
- :param lines: The lines to get the encoding of.
- :type lines: Iterable of bytes
- :param name: Name of file or collection of lines
- :type name: str
- """
- u = UniversalDetector()
- for line in lines:
- u.feed(line)
- u.close()
- result = u.result
- if result['encoding']:
- return '{0}: {1} with confidence {2}'.format(name, result['encoding'],
- result['confidence'])
- else:
- return '{0}: no result'.format(name)
-
-
-def main(argv=None):
- '''
- Handles command line arguments and gets things started.
-
- :param argv: List of arguments, as if specified on the command-line.
- If None, ``sys.argv[1:]`` is used instead.
- :type argv: list of str
- '''
- # Get command line arguments
- parser = argparse.ArgumentParser(
- description="Takes one or more file paths and reports their detected \
- encodings",
- formatter_class=argparse.ArgumentDefaultsHelpFormatter,
- conflict_handler='resolve')
- parser.add_argument('input',
- help='File whose encoding we would like to determine.',
- type=argparse.FileType('rb'), nargs='*',
- default=[sys.stdin])
- parser.add_argument('--version', action='version',
- version='%(prog)s {0}'.format(__version__))
- args = parser.parse_args(argv)
-
- for f in args.input:
- if f.isatty():
- print("You are running chardetect interactively. Press " +
- "CTRL-D twice at the start of a blank line to signal the " +
- "end of your input. If you want help, run chardetect " +
- "--help\n", file=sys.stderr)
- print(description_of(f, f.name))
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardistribution.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardistribution.py
deleted file mode 100644
index 4e64a00b..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/chardistribution.py
+++ /dev/null
@@ -1,231 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .euctwfreq import (EUCTWCharToFreqOrder, EUCTW_TABLE_SIZE,
- EUCTW_TYPICAL_DISTRIBUTION_RATIO)
-from .euckrfreq import (EUCKRCharToFreqOrder, EUCKR_TABLE_SIZE,
- EUCKR_TYPICAL_DISTRIBUTION_RATIO)
-from .gb2312freq import (GB2312CharToFreqOrder, GB2312_TABLE_SIZE,
- GB2312_TYPICAL_DISTRIBUTION_RATIO)
-from .big5freq import (Big5CharToFreqOrder, BIG5_TABLE_SIZE,
- BIG5_TYPICAL_DISTRIBUTION_RATIO)
-from .jisfreq import (JISCharToFreqOrder, JIS_TABLE_SIZE,
- JIS_TYPICAL_DISTRIBUTION_RATIO)
-from .compat import wrap_ord
-
-ENOUGH_DATA_THRESHOLD = 1024
-SURE_YES = 0.99
-SURE_NO = 0.01
-MINIMUM_DATA_THRESHOLD = 3
-
-
-class CharDistributionAnalysis:
- def __init__(self):
- # Mapping table to get frequency order from char order (get from
- # GetOrder())
- self._mCharToFreqOrder = None
- self._mTableSize = None # Size of above table
- # This is a constant value which varies from language to language,
- # used in calculating confidence. See
- # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html
- # for further detail.
- self._mTypicalDistributionRatio = None
- self.reset()
-
- def reset(self):
- """reset analyser, clear any state"""
- # If this flag is set to True, detection is done and conclusion has
- # been made
- self._mDone = False
- self._mTotalChars = 0 # Total characters encountered
- # The number of characters whose frequency order is less than 512
- self._mFreqChars = 0
-
- def feed(self, aBuf, aCharLen):
- """feed a character with known length"""
- if aCharLen == 2:
- # we only care about 2-bytes character in our distribution analysis
- order = self.get_order(aBuf)
- else:
- order = -1
- if order >= 0:
- self._mTotalChars += 1
- # order is valid
- if order < self._mTableSize:
- if 512 > self._mCharToFreqOrder[order]:
- self._mFreqChars += 1
-
- def get_confidence(self):
- """return confidence based on existing data"""
- # if we didn't receive any character in our consideration range,
- # return negative answer
- if self._mTotalChars <= 0 or self._mFreqChars <= MINIMUM_DATA_THRESHOLD:
- return SURE_NO
-
- if self._mTotalChars != self._mFreqChars:
- r = (self._mFreqChars / ((self._mTotalChars - self._mFreqChars)
- * self._mTypicalDistributionRatio))
- if r < SURE_YES:
- return r
-
- # normalize confidence (we don't want to be 100% sure)
- return SURE_YES
-
- def got_enough_data(self):
- # It is not necessary to receive all data to draw conclusion.
- # For charset detection, certain amount of data is enough
- return self._mTotalChars > ENOUGH_DATA_THRESHOLD
-
- def get_order(self, aBuf):
- # We do not handle characters based on the original encoding string,
- # but convert this encoding string to a number, here called order.
- # This allows multiple encodings of a language to share one frequency
- # table.
- return -1
-
-
-class EUCTWDistributionAnalysis(CharDistributionAnalysis):
- def __init__(self):
- CharDistributionAnalysis.__init__(self)
- self._mCharToFreqOrder = EUCTWCharToFreqOrder
- self._mTableSize = EUCTW_TABLE_SIZE
- self._mTypicalDistributionRatio = EUCTW_TYPICAL_DISTRIBUTION_RATIO
-
- def get_order(self, aBuf):
- # for euc-TW encoding, we are interested
- # first byte range: 0xc4 -- 0xfe
- # second byte range: 0xa1 -- 0xfe
- # no validation needed here. State machine has done that
- first_char = wrap_ord(aBuf[0])
- if first_char >= 0xC4:
- return 94 * (first_char - 0xC4) + wrap_ord(aBuf[1]) - 0xA1
- else:
- return -1
-
-
-class EUCKRDistributionAnalysis(CharDistributionAnalysis):
- def __init__(self):
- CharDistributionAnalysis.__init__(self)
- self._mCharToFreqOrder = EUCKRCharToFreqOrder
- self._mTableSize = EUCKR_TABLE_SIZE
- self._mTypicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO
-
- def get_order(self, aBuf):
- # for euc-KR encoding, we are interested
- # first byte range: 0xb0 -- 0xfe
- # second byte range: 0xa1 -- 0xfe
- # no validation needed here. State machine has done that
- first_char = wrap_ord(aBuf[0])
- if first_char >= 0xB0:
- return 94 * (first_char - 0xB0) + wrap_ord(aBuf[1]) - 0xA1
- else:
- return -1
-
-
-class GB2312DistributionAnalysis(CharDistributionAnalysis):
- def __init__(self):
- CharDistributionAnalysis.__init__(self)
- self._mCharToFreqOrder = GB2312CharToFreqOrder
- self._mTableSize = GB2312_TABLE_SIZE
- self._mTypicalDistributionRatio = GB2312_TYPICAL_DISTRIBUTION_RATIO
-
- def get_order(self, aBuf):
- # for GB2312 encoding, we are interested
- # first byte range: 0xb0 -- 0xfe
- # second byte range: 0xa1 -- 0xfe
- # no validation needed here. State machine has done that
- first_char, second_char = wrap_ord(aBuf[0]), wrap_ord(aBuf[1])
- if (first_char >= 0xB0) and (second_char >= 0xA1):
- return 94 * (first_char - 0xB0) + second_char - 0xA1
- else:
- return -1
-
-
-class Big5DistributionAnalysis(CharDistributionAnalysis):
- def __init__(self):
- CharDistributionAnalysis.__init__(self)
- self._mCharToFreqOrder = Big5CharToFreqOrder
- self._mTableSize = BIG5_TABLE_SIZE
- self._mTypicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO
-
- def get_order(self, aBuf):
- # for big5 encoding, we are interested
- # first byte range: 0xa4 -- 0xfe
- # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe
- # no validation needed here. State machine has done that
- first_char, second_char = wrap_ord(aBuf[0]), wrap_ord(aBuf[1])
- if first_char >= 0xA4:
- if second_char >= 0xA1:
- return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63
- else:
- return 157 * (first_char - 0xA4) + second_char - 0x40
- else:
- return -1
-
-
-class SJISDistributionAnalysis(CharDistributionAnalysis):
- def __init__(self):
- CharDistributionAnalysis.__init__(self)
- self._mCharToFreqOrder = JISCharToFreqOrder
- self._mTableSize = JIS_TABLE_SIZE
- self._mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO
-
- def get_order(self, aBuf):
- # for sjis encoding, we are interested
- # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe
- # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe
- # no validation needed here. State machine has done that
- first_char, second_char = wrap_ord(aBuf[0]), wrap_ord(aBuf[1])
- if (first_char >= 0x81) and (first_char <= 0x9F):
- order = 188 * (first_char - 0x81)
- elif (first_char >= 0xE0) and (first_char <= 0xEF):
- order = 188 * (first_char - 0xE0 + 31)
- else:
- return -1
- order = order + second_char - 0x40
- if second_char > 0x7F:
- order = -1
- return order
-
-
-class EUCJPDistributionAnalysis(CharDistributionAnalysis):
- def __init__(self):
- CharDistributionAnalysis.__init__(self)
- self._mCharToFreqOrder = JISCharToFreqOrder
- self._mTableSize = JIS_TABLE_SIZE
- self._mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO
-
- def get_order(self, aBuf):
- # for euc-JP encoding, we are interested
- # first byte range: 0xa0 -- 0xfe
- # second byte range: 0xa1 -- 0xfe
- # no validation needed here. State machine has done that
- char = wrap_ord(aBuf[0])
- if char >= 0xA0:
- return 94 * (char - 0xA1) + wrap_ord(aBuf[1]) - 0xa1
- else:
- return -1
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetgroupprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetgroupprober.py
deleted file mode 100644
index 85e7a1c6..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetgroupprober.py
+++ /dev/null
@@ -1,106 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from . import constants
-import sys
-from .charsetprober import CharSetProber
-
-
-class CharSetGroupProber(CharSetProber):
- def __init__(self):
- CharSetProber.__init__(self)
- self._mActiveNum = 0
- self._mProbers = []
- self._mBestGuessProber = None
-
- def reset(self):
- CharSetProber.reset(self)
- self._mActiveNum = 0
- for prober in self._mProbers:
- if prober:
- prober.reset()
- prober.active = True
- self._mActiveNum += 1
- self._mBestGuessProber = None
-
- def get_charset_name(self):
- if not self._mBestGuessProber:
- self.get_confidence()
- if not self._mBestGuessProber:
- return None
-# self._mBestGuessProber = self._mProbers[0]
- return self._mBestGuessProber.get_charset_name()
-
- def feed(self, aBuf):
- for prober in self._mProbers:
- if not prober:
- continue
- if not prober.active:
- continue
- st = prober.feed(aBuf)
- if not st:
- continue
- if st == constants.eFoundIt:
- self._mBestGuessProber = prober
- return self.get_state()
- elif st == constants.eNotMe:
- prober.active = False
- self._mActiveNum -= 1
- if self._mActiveNum <= 0:
- self._mState = constants.eNotMe
- return self.get_state()
- return self.get_state()
-
- def get_confidence(self):
- st = self.get_state()
- if st == constants.eFoundIt:
- return 0.99
- elif st == constants.eNotMe:
- return 0.01
- bestConf = 0.0
- self._mBestGuessProber = None
- for prober in self._mProbers:
- if not prober:
- continue
- if not prober.active:
- if constants._debug:
- sys.stderr.write(prober.get_charset_name()
- + ' not active\n')
- continue
- cf = prober.get_confidence()
- if constants._debug:
- sys.stderr.write('%s confidence = %s\n' %
- (prober.get_charset_name(), cf))
- if bestConf < cf:
- bestConf = cf
- self._mBestGuessProber = prober
- if not self._mBestGuessProber:
- return 0.0
- return bestConf
-# else:
-# self._mBestGuessProber = self._mProbers[0]
-# return self._mBestGuessProber.get_confidence()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetprober.py
deleted file mode 100644
index 97581712..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/charsetprober.py
+++ /dev/null
@@ -1,62 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from . import constants
-import re
-
-
-class CharSetProber:
- def __init__(self):
- pass
-
- def reset(self):
- self._mState = constants.eDetecting
-
- def get_charset_name(self):
- return None
-
- def feed(self, aBuf):
- pass
-
- def get_state(self):
- return self._mState
-
- def get_confidence(self):
- return 0.0
-
- def filter_high_bit_only(self, aBuf):
- aBuf = re.sub(b'([\x00-\x7F])+', b' ', aBuf)
- return aBuf
-
- def filter_without_english_letters(self, aBuf):
- aBuf = re.sub(b'([A-Za-z])+', b' ', aBuf)
- return aBuf
-
- def filter_with_english_letters(self, aBuf):
- # TODO
- return aBuf
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/codingstatemachine.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/codingstatemachine.py
deleted file mode 100644
index 8dd8c917..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/codingstatemachine.py
+++ /dev/null
@@ -1,61 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .constants import eStart
-from .compat import wrap_ord
-
-
-class CodingStateMachine:
- def __init__(self, sm):
- self._mModel = sm
- self._mCurrentBytePos = 0
- self._mCurrentCharLen = 0
- self.reset()
-
- def reset(self):
- self._mCurrentState = eStart
-
- def next_state(self, c):
- # for each byte we get its class
- # if it is first byte, we also get byte length
- # PY3K: aBuf is a byte stream, so c is an int, not a byte
- byteCls = self._mModel['classTable'][wrap_ord(c)]
- if self._mCurrentState == eStart:
- self._mCurrentBytePos = 0
- self._mCurrentCharLen = self._mModel['charLenTable'][byteCls]
- # from byte's class and stateTable, we get its next state
- curr_state = (self._mCurrentState * self._mModel['classFactor']
- + byteCls)
- self._mCurrentState = self._mModel['stateTable'][curr_state]
- self._mCurrentBytePos += 1
- return self._mCurrentState
-
- def get_current_charlen(self):
- return self._mCurrentCharLen
-
- def get_coding_state_machine(self):
- return self._mModel['name']
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/compat.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/compat.py
deleted file mode 100644
index d9e30add..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/compat.py
+++ /dev/null
@@ -1,34 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# Contributor(s):
-# Ian Cordasco - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-import sys
-
-
-if sys.version_info < (3, 0):
- base_str = (str, unicode)
-else:
- base_str = (bytes, str)
-
-
-def wrap_ord(a):
- if sys.version_info < (3, 0) and isinstance(a, base_str):
- return ord(a)
- else:
- return a
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/constants.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/constants.py
deleted file mode 100644
index e4d148b3..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/constants.py
+++ /dev/null
@@ -1,39 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-_debug = 0
-
-eDetecting = 0
-eFoundIt = 1
-eNotMe = 2
-
-eStart = 0
-eError = 1
-eItsMe = 2
-
-SHORTCUT_THRESHOLD = 0.95
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/cp949prober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/cp949prober.py
deleted file mode 100644
index ff4272f8..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/cp949prober.py
+++ /dev/null
@@ -1,44 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import EUCKRDistributionAnalysis
-from .mbcssm import CP949SMModel
-
-
-class CP949Prober(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(CP949SMModel)
- # NOTE: CP949 is a superset of EUC-KR, so the distribution should be
- # not different.
- self._mDistributionAnalyzer = EUCKRDistributionAnalysis()
- self.reset()
-
- def get_charset_name(self):
- return "CP949"
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escprober.py
deleted file mode 100644
index 80a844ff..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escprober.py
+++ /dev/null
@@ -1,86 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from . import constants
-from .escsm import (HZSMModel, ISO2022CNSMModel, ISO2022JPSMModel,
- ISO2022KRSMModel)
-from .charsetprober import CharSetProber
-from .codingstatemachine import CodingStateMachine
-from .compat import wrap_ord
-
-
-class EscCharSetProber(CharSetProber):
- def __init__(self):
- CharSetProber.__init__(self)
- self._mCodingSM = [
- CodingStateMachine(HZSMModel),
- CodingStateMachine(ISO2022CNSMModel),
- CodingStateMachine(ISO2022JPSMModel),
- CodingStateMachine(ISO2022KRSMModel)
- ]
- self.reset()
-
- def reset(self):
- CharSetProber.reset(self)
- for codingSM in self._mCodingSM:
- if not codingSM:
- continue
- codingSM.active = True
- codingSM.reset()
- self._mActiveSM = len(self._mCodingSM)
- self._mDetectedCharset = None
-
- def get_charset_name(self):
- return self._mDetectedCharset
-
- def get_confidence(self):
- if self._mDetectedCharset:
- return 0.99
- else:
- return 0.00
-
- def feed(self, aBuf):
- for c in aBuf:
- # PY3K: aBuf is a byte array, so c is an int, not a byte
- for codingSM in self._mCodingSM:
- if not codingSM:
- continue
- if not codingSM.active:
- continue
- codingState = codingSM.next_state(wrap_ord(c))
- if codingState == constants.eError:
- codingSM.active = False
- self._mActiveSM -= 1
- if self._mActiveSM <= 0:
- self._mState = constants.eNotMe
- return self.get_state()
- elif codingState == constants.eItsMe:
- self._mState = constants.eFoundIt
- self._mDetectedCharset = codingSM.get_coding_state_machine() # nopep8
- return self.get_state()
-
- return self.get_state()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escsm.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escsm.py
deleted file mode 100644
index bd302b4c..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/escsm.py
+++ /dev/null
@@ -1,242 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .constants import eStart, eError, eItsMe
-
-HZ_cls = (
-1,0,0,0,0,0,0,0, # 00 - 07
-0,0,0,0,0,0,0,0, # 08 - 0f
-0,0,0,0,0,0,0,0, # 10 - 17
-0,0,0,1,0,0,0,0, # 18 - 1f
-0,0,0,0,0,0,0,0, # 20 - 27
-0,0,0,0,0,0,0,0, # 28 - 2f
-0,0,0,0,0,0,0,0, # 30 - 37
-0,0,0,0,0,0,0,0, # 38 - 3f
-0,0,0,0,0,0,0,0, # 40 - 47
-0,0,0,0,0,0,0,0, # 48 - 4f
-0,0,0,0,0,0,0,0, # 50 - 57
-0,0,0,0,0,0,0,0, # 58 - 5f
-0,0,0,0,0,0,0,0, # 60 - 67
-0,0,0,0,0,0,0,0, # 68 - 6f
-0,0,0,0,0,0,0,0, # 70 - 77
-0,0,0,4,0,5,2,0, # 78 - 7f
-1,1,1,1,1,1,1,1, # 80 - 87
-1,1,1,1,1,1,1,1, # 88 - 8f
-1,1,1,1,1,1,1,1, # 90 - 97
-1,1,1,1,1,1,1,1, # 98 - 9f
-1,1,1,1,1,1,1,1, # a0 - a7
-1,1,1,1,1,1,1,1, # a8 - af
-1,1,1,1,1,1,1,1, # b0 - b7
-1,1,1,1,1,1,1,1, # b8 - bf
-1,1,1,1,1,1,1,1, # c0 - c7
-1,1,1,1,1,1,1,1, # c8 - cf
-1,1,1,1,1,1,1,1, # d0 - d7
-1,1,1,1,1,1,1,1, # d8 - df
-1,1,1,1,1,1,1,1, # e0 - e7
-1,1,1,1,1,1,1,1, # e8 - ef
-1,1,1,1,1,1,1,1, # f0 - f7
-1,1,1,1,1,1,1,1, # f8 - ff
-)
-
-HZ_st = (
-eStart,eError, 3,eStart,eStart,eStart,eError,eError,# 00-07
-eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,# 08-0f
-eItsMe,eItsMe,eError,eError,eStart,eStart, 4,eError,# 10-17
- 5,eError, 6,eError, 5, 5, 4,eError,# 18-1f
- 4,eError, 4, 4, 4,eError, 4,eError,# 20-27
- 4,eItsMe,eStart,eStart,eStart,eStart,eStart,eStart,# 28-2f
-)
-
-HZCharLenTable = (0, 0, 0, 0, 0, 0)
-
-HZSMModel = {'classTable': HZ_cls,
- 'classFactor': 6,
- 'stateTable': HZ_st,
- 'charLenTable': HZCharLenTable,
- 'name': "HZ-GB-2312"}
-
-ISO2022CN_cls = (
-2,0,0,0,0,0,0,0, # 00 - 07
-0,0,0,0,0,0,0,0, # 08 - 0f
-0,0,0,0,0,0,0,0, # 10 - 17
-0,0,0,1,0,0,0,0, # 18 - 1f
-0,0,0,0,0,0,0,0, # 20 - 27
-0,3,0,0,0,0,0,0, # 28 - 2f
-0,0,0,0,0,0,0,0, # 30 - 37
-0,0,0,0,0,0,0,0, # 38 - 3f
-0,0,0,4,0,0,0,0, # 40 - 47
-0,0,0,0,0,0,0,0, # 48 - 4f
-0,0,0,0,0,0,0,0, # 50 - 57
-0,0,0,0,0,0,0,0, # 58 - 5f
-0,0,0,0,0,0,0,0, # 60 - 67
-0,0,0,0,0,0,0,0, # 68 - 6f
-0,0,0,0,0,0,0,0, # 70 - 77
-0,0,0,0,0,0,0,0, # 78 - 7f
-2,2,2,2,2,2,2,2, # 80 - 87
-2,2,2,2,2,2,2,2, # 88 - 8f
-2,2,2,2,2,2,2,2, # 90 - 97
-2,2,2,2,2,2,2,2, # 98 - 9f
-2,2,2,2,2,2,2,2, # a0 - a7
-2,2,2,2,2,2,2,2, # a8 - af
-2,2,2,2,2,2,2,2, # b0 - b7
-2,2,2,2,2,2,2,2, # b8 - bf
-2,2,2,2,2,2,2,2, # c0 - c7
-2,2,2,2,2,2,2,2, # c8 - cf
-2,2,2,2,2,2,2,2, # d0 - d7
-2,2,2,2,2,2,2,2, # d8 - df
-2,2,2,2,2,2,2,2, # e0 - e7
-2,2,2,2,2,2,2,2, # e8 - ef
-2,2,2,2,2,2,2,2, # f0 - f7
-2,2,2,2,2,2,2,2, # f8 - ff
-)
-
-ISO2022CN_st = (
-eStart, 3,eError,eStart,eStart,eStart,eStart,eStart,# 00-07
-eStart,eError,eError,eError,eError,eError,eError,eError,# 08-0f
-eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,# 10-17
-eItsMe,eItsMe,eItsMe,eError,eError,eError, 4,eError,# 18-1f
-eError,eError,eError,eItsMe,eError,eError,eError,eError,# 20-27
- 5, 6,eError,eError,eError,eError,eError,eError,# 28-2f
-eError,eError,eError,eItsMe,eError,eError,eError,eError,# 30-37
-eError,eError,eError,eError,eError,eItsMe,eError,eStart,# 38-3f
-)
-
-ISO2022CNCharLenTable = (0, 0, 0, 0, 0, 0, 0, 0, 0)
-
-ISO2022CNSMModel = {'classTable': ISO2022CN_cls,
- 'classFactor': 9,
- 'stateTable': ISO2022CN_st,
- 'charLenTable': ISO2022CNCharLenTable,
- 'name': "ISO-2022-CN"}
-
-ISO2022JP_cls = (
-2,0,0,0,0,0,0,0, # 00 - 07
-0,0,0,0,0,0,2,2, # 08 - 0f
-0,0,0,0,0,0,0,0, # 10 - 17
-0,0,0,1,0,0,0,0, # 18 - 1f
-0,0,0,0,7,0,0,0, # 20 - 27
-3,0,0,0,0,0,0,0, # 28 - 2f
-0,0,0,0,0,0,0,0, # 30 - 37
-0,0,0,0,0,0,0,0, # 38 - 3f
-6,0,4,0,8,0,0,0, # 40 - 47
-0,9,5,0,0,0,0,0, # 48 - 4f
-0,0,0,0,0,0,0,0, # 50 - 57
-0,0,0,0,0,0,0,0, # 58 - 5f
-0,0,0,0,0,0,0,0, # 60 - 67
-0,0,0,0,0,0,0,0, # 68 - 6f
-0,0,0,0,0,0,0,0, # 70 - 77
-0,0,0,0,0,0,0,0, # 78 - 7f
-2,2,2,2,2,2,2,2, # 80 - 87
-2,2,2,2,2,2,2,2, # 88 - 8f
-2,2,2,2,2,2,2,2, # 90 - 97
-2,2,2,2,2,2,2,2, # 98 - 9f
-2,2,2,2,2,2,2,2, # a0 - a7
-2,2,2,2,2,2,2,2, # a8 - af
-2,2,2,2,2,2,2,2, # b0 - b7
-2,2,2,2,2,2,2,2, # b8 - bf
-2,2,2,2,2,2,2,2, # c0 - c7
-2,2,2,2,2,2,2,2, # c8 - cf
-2,2,2,2,2,2,2,2, # d0 - d7
-2,2,2,2,2,2,2,2, # d8 - df
-2,2,2,2,2,2,2,2, # e0 - e7
-2,2,2,2,2,2,2,2, # e8 - ef
-2,2,2,2,2,2,2,2, # f0 - f7
-2,2,2,2,2,2,2,2, # f8 - ff
-)
-
-ISO2022JP_st = (
-eStart, 3,eError,eStart,eStart,eStart,eStart,eStart,# 00-07
-eStart,eStart,eError,eError,eError,eError,eError,eError,# 08-0f
-eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,# 10-17
-eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,# 18-1f
-eError, 5,eError,eError,eError, 4,eError,eError,# 20-27
-eError,eError,eError, 6,eItsMe,eError,eItsMe,eError,# 28-2f
-eError,eError,eError,eError,eError,eError,eItsMe,eItsMe,# 30-37
-eError,eError,eError,eItsMe,eError,eError,eError,eError,# 38-3f
-eError,eError,eError,eError,eItsMe,eError,eStart,eStart,# 40-47
-)
-
-ISO2022JPCharLenTable = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-
-ISO2022JPSMModel = {'classTable': ISO2022JP_cls,
- 'classFactor': 10,
- 'stateTable': ISO2022JP_st,
- 'charLenTable': ISO2022JPCharLenTable,
- 'name': "ISO-2022-JP"}
-
-ISO2022KR_cls = (
-2,0,0,0,0,0,0,0, # 00 - 07
-0,0,0,0,0,0,0,0, # 08 - 0f
-0,0,0,0,0,0,0,0, # 10 - 17
-0,0,0,1,0,0,0,0, # 18 - 1f
-0,0,0,0,3,0,0,0, # 20 - 27
-0,4,0,0,0,0,0,0, # 28 - 2f
-0,0,0,0,0,0,0,0, # 30 - 37
-0,0,0,0,0,0,0,0, # 38 - 3f
-0,0,0,5,0,0,0,0, # 40 - 47
-0,0,0,0,0,0,0,0, # 48 - 4f
-0,0,0,0,0,0,0,0, # 50 - 57
-0,0,0,0,0,0,0,0, # 58 - 5f
-0,0,0,0,0,0,0,0, # 60 - 67
-0,0,0,0,0,0,0,0, # 68 - 6f
-0,0,0,0,0,0,0,0, # 70 - 77
-0,0,0,0,0,0,0,0, # 78 - 7f
-2,2,2,2,2,2,2,2, # 80 - 87
-2,2,2,2,2,2,2,2, # 88 - 8f
-2,2,2,2,2,2,2,2, # 90 - 97
-2,2,2,2,2,2,2,2, # 98 - 9f
-2,2,2,2,2,2,2,2, # a0 - a7
-2,2,2,2,2,2,2,2, # a8 - af
-2,2,2,2,2,2,2,2, # b0 - b7
-2,2,2,2,2,2,2,2, # b8 - bf
-2,2,2,2,2,2,2,2, # c0 - c7
-2,2,2,2,2,2,2,2, # c8 - cf
-2,2,2,2,2,2,2,2, # d0 - d7
-2,2,2,2,2,2,2,2, # d8 - df
-2,2,2,2,2,2,2,2, # e0 - e7
-2,2,2,2,2,2,2,2, # e8 - ef
-2,2,2,2,2,2,2,2, # f0 - f7
-2,2,2,2,2,2,2,2, # f8 - ff
-)
-
-ISO2022KR_st = (
-eStart, 3,eError,eStart,eStart,eStart,eError,eError,# 00-07
-eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,# 08-0f
-eItsMe,eItsMe,eError,eError,eError, 4,eError,eError,# 10-17
-eError,eError,eError,eError, 5,eError,eError,eError,# 18-1f
-eError,eError,eError,eItsMe,eStart,eStart,eStart,eStart,# 20-27
-)
-
-ISO2022KRCharLenTable = (0, 0, 0, 0, 0, 0)
-
-ISO2022KRSMModel = {'classTable': ISO2022KR_cls,
- 'classFactor': 6,
- 'stateTable': ISO2022KR_st,
- 'charLenTable': ISO2022KRCharLenTable,
- 'name': "ISO-2022-KR"}
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/eucjpprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/eucjpprober.py
deleted file mode 100644
index 8e64fdcc..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/eucjpprober.py
+++ /dev/null
@@ -1,90 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-import sys
-from . import constants
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import EUCJPDistributionAnalysis
-from .jpcntx import EUCJPContextAnalysis
-from .mbcssm import EUCJPSMModel
-
-
-class EUCJPProber(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(EUCJPSMModel)
- self._mDistributionAnalyzer = EUCJPDistributionAnalysis()
- self._mContextAnalyzer = EUCJPContextAnalysis()
- self.reset()
-
- def reset(self):
- MultiByteCharSetProber.reset(self)
- self._mContextAnalyzer.reset()
-
- def get_charset_name(self):
- return "EUC-JP"
-
- def feed(self, aBuf):
- aLen = len(aBuf)
- for i in range(0, aLen):
- # PY3K: aBuf is a byte array, so aBuf[i] is an int, not a byte
- codingState = self._mCodingSM.next_state(aBuf[i])
- if codingState == constants.eError:
- if constants._debug:
- sys.stderr.write(self.get_charset_name()
- + ' prober hit error at byte ' + str(i)
- + '\n')
- self._mState = constants.eNotMe
- break
- elif codingState == constants.eItsMe:
- self._mState = constants.eFoundIt
- break
- elif codingState == constants.eStart:
- charLen = self._mCodingSM.get_current_charlen()
- if i == 0:
- self._mLastChar[1] = aBuf[0]
- self._mContextAnalyzer.feed(self._mLastChar, charLen)
- self._mDistributionAnalyzer.feed(self._mLastChar, charLen)
- else:
- self._mContextAnalyzer.feed(aBuf[i - 1:i + 1], charLen)
- self._mDistributionAnalyzer.feed(aBuf[i - 1:i + 1],
- charLen)
-
- self._mLastChar[0] = aBuf[aLen - 1]
-
- if self.get_state() == constants.eDetecting:
- if (self._mContextAnalyzer.got_enough_data() and
- (self.get_confidence() > constants.SHORTCUT_THRESHOLD)):
- self._mState = constants.eFoundIt
-
- return self.get_state()
-
- def get_confidence(self):
- contxtCf = self._mContextAnalyzer.get_confidence()
- distribCf = self._mDistributionAnalyzer.get_confidence()
- return max(contxtCf, distribCf)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrfreq.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrfreq.py
deleted file mode 100644
index a179e4c2..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrfreq.py
+++ /dev/null
@@ -1,596 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# Sampling from about 20M text materials include literature and computer technology
-
-# 128 --> 0.79
-# 256 --> 0.92
-# 512 --> 0.986
-# 1024 --> 0.99944
-# 2048 --> 0.99999
-#
-# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24
-# Random Distribution Ration = 512 / (2350-512) = 0.279.
-#
-# Typical Distribution Ratio
-
-EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0
-
-EUCKR_TABLE_SIZE = 2352
-
-# Char to FreqOrder table ,
-EUCKRCharToFreqOrder = ( \
- 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87,
-1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398,
-1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734,
- 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739,
- 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622,
- 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750,
-1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856,
- 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205,
- 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779,
-1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19,
-1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567,
-1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797,
-1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802,
-1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899,
- 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818,
-1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409,
-1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697,
-1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770,
-1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723,
- 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416,
-1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300,
- 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083,
- 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857,
-1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871,
- 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420,
-1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885,
- 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889,
- 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893,
-1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317,
-1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841,
-1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910,
-1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610,
- 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375,
-1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939,
- 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870,
- 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934,
-1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888,
-1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950,
-1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065,
-1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002,
-1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965,
-1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467,
- 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285,
- 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7,
- 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979,
-1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985,
- 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994,
-1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250,
- 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824,
- 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003,
-2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745,
- 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61,
- 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023,
-2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032,
-2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912,
-2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224,
- 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012,
- 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050,
-2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681,
- 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414,
-1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068,
-2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075,
-1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850,
-2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606,
-2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449,
-1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452,
- 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112,
-2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121,
-2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130,
- 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274,
- 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139,
-2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721,
-1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298,
-2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463,
-2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747,
-2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285,
-2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187,
-2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10,
-2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350,
-1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201,
-2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972,
-2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219,
-2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233,
-2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242,
-2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247,
-1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178,
-1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255,
-2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259,
-1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262,
-2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702,
-1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273,
- 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541,
-2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117,
- 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187,
-2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800,
- 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312,
-2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229,
-2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315,
- 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484,
-2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170,
-1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335,
- 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601,
-1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395,
-2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354,
-1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476,
-2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035,
- 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498,
-2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310,
-1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389,
-2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504,
-1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505,
-2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145,
-1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624,
- 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700,
-2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221,
-2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377,
- 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448,
- 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485,
-1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705,
-1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465,
- 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471,
-2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997,
-2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486,
- 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494,
- 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771,
- 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323,
-2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491,
- 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510,
- 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519,
-2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532,
-2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199,
- 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544,
-2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247,
-1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441,
- 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562,
-2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362,
-2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583,
-2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465,
- 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431,
- 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151,
- 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596,
-2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406,
-2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611,
-2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619,
-1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628,
-2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042,
- 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256
-#Everything below is of no interest for detection purpose
-2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,
-2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,
-2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,
-2691,2692,2693,2694,2695,2696,2697,2698,2699,1542, 880,2700,2701,2702,2703,2704,
-2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,
-2721,2722,2723,2724,2725,1543,2726,2727,2728,2729,2730,2731,2732,1544,2733,2734,
-2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,
-2751,2752,2753,2754,1545,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,
-2766,1546,2767,1547,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,
-2780,2781,2782,2783,2784,2785,2786,1548,2787,2788,2789,1109,2790,2791,2792,2793,
-2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,
-2810,2811,2812,1329,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,
-2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,
-2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,
-1549,2857,2858,2859,2860,1550,2861,2862,1551,2863,2864,2865,2866,2867,2868,2869,
-2870,2871,2872,2873,2874,1110,1330,2875,2876,2877,2878,2879,2880,2881,2882,2883,
-2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,
-2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,
-2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,1331,
-2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,1552,2944,2945,
-2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,
-2962,2963,2964,1252,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,
-2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,
-2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,
-3009,3010,3011,3012,1553,3013,3014,3015,3016,3017,1554,3018,1332,3019,3020,3021,
-3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,
-3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,1555,3051,3052,
-3053,1556,1557,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,
-3067,1558,3068,3069,3070,3071,3072,3073,3074,3075,3076,1559,3077,3078,3079,3080,
-3081,3082,3083,1253,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,
-3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,1152,3109,3110,
-3111,3112,3113,1560,3114,3115,3116,3117,1111,3118,3119,3120,3121,3122,3123,3124,
-3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,
-3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,
-3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,
-3173,3174,3175,3176,1333,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,
-3188,3189,1561,3190,3191,1334,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,
-3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,
-3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,
-3234,1562,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,
-3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264,
-3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,1563,3278,3279,
-3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295,
-3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,
-3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327,
-3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343,
-3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,
-3360,3361,3362,3363,3364,1335,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374,
-3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,1336,3388,3389,
-3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403,3404,3405,
-3406,3407,3408,3409,3410,3411,3412,3413,3414,1337,3415,3416,3417,3418,3419,1338,
-3420,3421,3422,1564,1565,3423,3424,3425,3426,3427,3428,3429,3430,3431,1254,3432,
-3433,3434,1339,3435,3436,3437,3438,3439,1566,3440,3441,3442,3443,3444,3445,3446,
-3447,3448,3449,3450,3451,3452,3453,3454,1255,3455,3456,3457,3458,3459,1567,1191,
-3460,1568,1569,3461,3462,3463,1570,3464,3465,3466,3467,3468,1571,3469,3470,3471,
-3472,3473,1572,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,
-1340,3487,3488,3489,3490,3491,3492,1021,3493,3494,3495,3496,3497,3498,1573,3499,
-1341,3500,3501,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,1342,3512,3513,
-3514,3515,3516,1574,1343,3517,3518,3519,1575,3520,1576,3521,3522,3523,3524,3525,
-3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,
-3542,3543,3544,3545,3546,3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557,
-3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,
-3574,3575,3576,3577,3578,3579,3580,1577,3581,3582,1578,3583,3584,3585,3586,3587,
-3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,
-3604,1579,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,
-3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,1580,3630,3631,1581,3632,
-3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3643,3644,3645,3646,3647,3648,
-3649,3650,3651,3652,3653,3654,3655,3656,1582,3657,3658,3659,3660,3661,3662,3663,
-3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,
-3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,
-3696,3697,3698,3699,3700,1192,3701,3702,3703,3704,1256,3705,3706,3707,3708,1583,
-1257,3709,3710,3711,3712,3713,3714,3715,3716,1584,3717,3718,3719,3720,3721,3722,
-3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,
-3739,3740,3741,3742,3743,3744,3745,1344,3746,3747,3748,3749,3750,3751,3752,3753,
-3754,3755,3756,1585,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,1586,3767,
-3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,1345,3779,3780,3781,3782,
-3783,3784,3785,3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,1346,1587,3796,
-3797,1588,3798,3799,3800,3801,3802,3803,3804,3805,3806,1347,3807,3808,3809,3810,
-3811,1589,3812,3813,3814,3815,3816,3817,3818,3819,3820,3821,1590,3822,3823,1591,
-1348,3824,3825,3826,3827,3828,3829,3830,1592,3831,3832,1593,3833,3834,3835,3836,
-3837,3838,3839,3840,3841,3842,3843,3844,1349,3845,3846,3847,3848,3849,3850,3851,
-3852,3853,3854,3855,3856,3857,3858,1594,3859,3860,3861,3862,3863,3864,3865,3866,
-3867,3868,3869,1595,3870,3871,3872,3873,1596,3874,3875,3876,3877,3878,3879,3880,
-3881,3882,3883,3884,3885,3886,1597,3887,3888,3889,3890,3891,3892,3893,3894,3895,
-1598,3896,3897,3898,1599,1600,3899,1350,3900,1351,3901,3902,1352,3903,3904,3905,
-3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,
-3922,3923,3924,1258,3925,3926,3927,3928,3929,3930,3931,1193,3932,1601,3933,3934,
-3935,3936,3937,3938,3939,3940,3941,3942,3943,1602,3944,3945,3946,3947,3948,1603,
-3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,
-3965,1604,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,1353,3978,
-3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,1354,3992,3993,
-3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,
-4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,1355,4024,
-4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,
-1605,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,
-4056,4057,4058,4059,4060,1606,4061,4062,4063,4064,1607,4065,4066,4067,4068,4069,
-4070,4071,4072,4073,4074,4075,4076,1194,4077,4078,1608,4079,4080,4081,4082,4083,
-4084,4085,4086,4087,1609,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,
-4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,1259,4109,4110,4111,4112,4113,
-4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,1195,4125,4126,4127,1610,
-4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,1356,4138,4139,4140,4141,4142,
-4143,4144,1611,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157,
-4158,4159,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4170,4171,4172,4173,
-4174,4175,4176,4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,
-4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,
-4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,1612,4220,
-4221,4222,4223,4224,4225,4226,4227,1357,4228,1613,4229,4230,4231,4232,4233,4234,
-4235,4236,4237,4238,4239,4240,4241,4242,4243,1614,4244,4245,4246,4247,4248,4249,
-4250,4251,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,
-4266,4267,4268,4269,4270,1196,1358,4271,4272,4273,4274,4275,4276,4277,4278,4279,
-4280,4281,4282,4283,4284,4285,4286,4287,1615,4288,4289,4290,4291,4292,4293,4294,
-4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310,
-4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,
-4327,4328,4329,4330,4331,4332,4333,4334,1616,4335,4336,4337,4338,4339,4340,4341,
-4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357,
-4358,4359,4360,1617,4361,4362,4363,4364,4365,1618,4366,4367,4368,4369,4370,4371,
-4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,
-4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,
-4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,1619,4417,4418,
-4419,4420,4421,4422,4423,4424,4425,1112,4426,4427,4428,4429,4430,1620,4431,4432,
-4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,1260,1261,4443,4444,4445,4446,
-4447,4448,4449,4450,4451,4452,4453,4454,4455,1359,4456,4457,4458,4459,4460,4461,
-4462,4463,4464,4465,1621,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,
-4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,1055,4490,4491,
-4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,
-4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,1622,4519,4520,4521,1623,
-4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,1360,4536,
-4537,4538,4539,4540,4541,4542,4543, 975,4544,4545,4546,4547,4548,4549,4550,4551,
-4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,
-4568,4569,4570,4571,1624,4572,4573,4574,4575,4576,1625,4577,4578,4579,4580,4581,
-4582,4583,4584,1626,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,1627,
-4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,
-4612,4613,4614,4615,1628,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,
-4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,
-4643,4644,4645,4646,4647,4648,4649,1361,4650,4651,4652,4653,4654,4655,4656,4657,
-4658,4659,4660,4661,1362,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,
-4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,1629,4683,4684,4685,4686,4687,
-1630,4688,4689,4690,4691,1153,4692,4693,4694,1113,4695,4696,4697,4698,4699,4700,
-4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,1197,4712,4713,4714,4715,
-4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,
-4732,4733,4734,4735,1631,4736,1632,4737,4738,4739,4740,4741,4742,4743,4744,1633,
-4745,4746,4747,4748,4749,1262,4750,4751,4752,4753,4754,1363,4755,4756,4757,4758,
-4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,1634,4769,4770,4771,4772,4773,
-4774,4775,4776,4777,4778,1635,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,
-4789,1636,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,
-4804,4805,4806,1637,4807,4808,4809,1638,4810,4811,4812,4813,4814,4815,4816,4817,
-4818,1639,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832,
-4833,1077,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,
-4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,
-4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,
-4880,4881,4882,4883,1640,4884,4885,1641,4886,4887,4888,4889,4890,4891,4892,4893,
-4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,
-4910,4911,1642,4912,4913,4914,1364,4915,4916,4917,4918,4919,4920,4921,4922,4923,
-4924,4925,4926,4927,4928,4929,4930,4931,1643,4932,4933,4934,4935,4936,4937,4938,
-4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,
-4955,4956,4957,4958,4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,
-4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,1644,4981,4982,4983,4984,1645,
-4985,4986,1646,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,
-5000,5001,5002,5003,5004,5005,1647,5006,1648,5007,5008,5009,5010,5011,5012,1078,
-5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027,5028,
-1365,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,1649,5040,5041,5042,
-5043,5044,5045,1366,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,1650,5056,
-5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072,
-5073,5074,5075,5076,5077,1651,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087,
-5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,
-5104,5105,5106,5107,5108,5109,5110,1652,5111,5112,5113,5114,5115,5116,5117,5118,
-1367,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,1653,5130,5131,5132,
-5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,
-5149,1368,5150,1654,5151,1369,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161,
-5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177,
-5178,1370,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,
-5193,5194,5195,5196,5197,5198,1655,5199,5200,5201,5202,1656,5203,5204,5205,5206,
-1371,5207,1372,5208,5209,5210,5211,1373,5212,5213,1374,5214,5215,5216,5217,5218,
-5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,
-5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,1657,5248,5249,
-5250,5251,1658,1263,5252,5253,5254,5255,5256,1375,5257,5258,5259,5260,5261,5262,
-5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,
-5279,5280,5281,5282,5283,1659,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,
-5294,5295,5296,5297,5298,5299,5300,1660,5301,5302,5303,5304,5305,5306,5307,5308,
-5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,1376,5322,5323,
-5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,1198,5334,5335,5336,5337,5338,
-5339,5340,5341,5342,5343,1661,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353,
-5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,
-5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,
-5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,1264,5399,5400,
-5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,1662,5413,5414,5415,
-5416,1663,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,
-5431,5432,5433,5434,5435,5436,5437,5438,1664,5439,5440,5441,5442,5443,5444,5445,
-5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,
-5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,
-5478,1154,5479,5480,5481,5482,5483,5484,5485,1665,5486,5487,5488,5489,5490,5491,
-5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507,
-5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,
-5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,
-5540,5541,5542,5543,5544,5545,5546,5547,5548,1377,5549,5550,5551,5552,5553,5554,
-5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,
-1114,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,
-5586,5587,5588,5589,5590,5591,5592,1378,5593,5594,5595,5596,5597,5598,5599,5600,
-5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,1379,5615,
-5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,
-5632,5633,5634,1380,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,
-5647,5648,5649,1381,1056,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,
-1666,5661,5662,5663,5664,5665,5666,5667,5668,1667,5669,1668,5670,5671,5672,5673,
-5674,5675,5676,5677,5678,1155,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,
-5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,1669,5699,5700,5701,5702,5703,
-5704,5705,1670,5706,5707,5708,5709,5710,1671,5711,5712,5713,5714,1382,5715,5716,
-5717,5718,5719,5720,5721,5722,5723,5724,5725,1672,5726,5727,1673,1674,5728,5729,
-5730,5731,5732,5733,5734,5735,5736,1675,5737,5738,5739,5740,5741,5742,5743,5744,
-1676,5745,5746,5747,5748,5749,5750,5751,1383,5752,5753,5754,5755,5756,5757,5758,
-5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,1677,5769,5770,5771,5772,5773,
-1678,5774,5775,5776, 998,5777,5778,5779,5780,5781,5782,5783,5784,5785,1384,5786,
-5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,5800,1679,5801,
-5802,5803,1115,1116,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815,
-5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831,
-5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847,
-5848,5849,5850,5851,5852,5853,5854,5855,1680,5856,5857,5858,5859,5860,5861,5862,
-5863,5864,1681,5865,5866,5867,1682,5868,5869,5870,5871,5872,5873,5874,5875,5876,
-5877,5878,5879,1683,5880,1684,5881,5882,5883,5884,1685,5885,5886,5887,5888,5889,
-5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,
-5906,5907,1686,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,
-5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,1687,
-5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,
-5952,1688,1689,5953,1199,5954,5955,5956,5957,5958,5959,5960,5961,1690,5962,5963,
-5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,
-5980,5981,1385,5982,1386,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,
-5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,
-6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,
-6026,6027,1265,6028,6029,1691,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,
-6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,
-6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071,
-6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,1692,6085,6086,
-6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102,
-6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118,
-6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,1693,6132,6133,
-6134,6135,6136,1694,6137,6138,6139,6140,6141,1695,6142,6143,6144,6145,6146,6147,
-6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,
-6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,
-6180,6181,6182,6183,6184,6185,1696,6186,6187,6188,6189,6190,6191,6192,6193,6194,
-6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,
-6211,6212,6213,6214,6215,6216,6217,6218,6219,1697,6220,6221,6222,6223,6224,6225,
-6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,
-6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,1698,6254,6255,6256,
-6257,6258,6259,6260,6261,6262,6263,1200,6264,6265,6266,6267,6268,6269,6270,6271, #1024
-6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287,
-6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,1699,
-6303,6304,1700,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317,
-6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,
-6334,6335,6336,6337,6338,6339,1701,6340,6341,6342,6343,6344,1387,6345,6346,6347,
-6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,
-6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,
-6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,
-6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,
-6412,6413,1702,6414,6415,6416,6417,6418,6419,6420,6421,6422,1703,6423,6424,6425,
-6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,1704,6439,6440,
-6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,
-6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,
-6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,
-6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,1266,
-6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,
-6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535,
-6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551,
-1705,1706,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,
-6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581,
-6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,
-6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613,
-6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629,
-6630,6631,6632,6633,6634,6635,6636,6637,1388,6638,6639,6640,6641,6642,6643,6644,
-1707,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659,
-6660,6661,6662,6663,1708,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674,
-1201,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,
-6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,
-6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721,
-6722,6723,6724,6725,1389,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736,
-1390,1709,6737,6738,6739,6740,6741,6742,1710,6743,6744,6745,6746,1391,6747,6748,
-6749,6750,6751,6752,6753,6754,6755,6756,6757,1392,6758,6759,6760,6761,6762,6763,
-6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779,
-6780,1202,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6794,
-6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,1711,
-6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820,6821,6822,6823,6824,6825,
-6826,6827,6828,6829,6830,6831,6832,6833,6834,6835,6836,1393,6837,6838,6839,6840,
-6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856,
-6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872,
-6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,
-6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,1712,6903,
-6904,6905,6906,6907,6908,6909,6910,1713,6911,6912,6913,6914,6915,6916,6917,6918,
-6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,
-6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,
-6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,
-6967,6968,6969,6970,6971,6972,6973,6974,1714,6975,6976,6977,6978,6979,6980,6981,
-6982,6983,6984,6985,6986,6987,6988,1394,6989,6990,6991,6992,6993,6994,6995,6996,
-6997,6998,6999,7000,1715,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,
-7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,
-7028,1716,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,
-7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,
-7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074,
-7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090,
-7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106,
-7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,
-7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,
-7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,
-7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170,
-7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,
-7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,
-7203,7204,7205,7206,7207,1395,7208,7209,7210,7211,7212,7213,1717,7214,7215,7216,
-7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231,7232,
-7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245,7246,7247,7248,
-7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,
-7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,
-7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,7296,
-7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308,7309,7310,7311,7312,
-7313,1718,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,
-7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343,
-7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,7359,
-7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,7374,7375,
-7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,
-7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,7404,7405,7406,7407,
-7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423,
-7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,
-7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,
-7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,
-7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,
-7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,
-7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,
-7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,
-7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,
-7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,
-7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583,
-7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599,
-7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615,
-7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,
-7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647,
-7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663,
-7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,
-7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,
-7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,
-7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,
-7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,
-7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,
-7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,
-7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,
-7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,
-7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,
-7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,
-7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,
-7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,
-7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,
-7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,
-7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,
-7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935,
-7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,
-7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,
-7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,
-7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,
-8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,
-8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031,
-8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,
-8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,
-8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,
-8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,
-8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,
-8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127,
-8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,
-8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,
-8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,
-8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,
-8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,
-8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,
-8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,
-8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,
-8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,
-8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,
-8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,
-8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,
-8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,8333,8334,8335,
-8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,
-8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,
-8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,
-8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,
-8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,
-8416,8417,8418,8419,8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,
-8432,8433,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,
-8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,
-8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,
-8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,
-8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,8510,8511,
-8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,
-8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8540,8541,8542,8543,
-8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,
-8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,
-8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,
-8592,8593,8594,8595,8596,8597,8598,8599,8600,8601,8602,8603,8604,8605,8606,8607,
-8608,8609,8610,8611,8612,8613,8614,8615,8616,8617,8618,8619,8620,8621,8622,8623,
-8624,8625,8626,8627,8628,8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,
-8640,8641,8642,8643,8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,
-8656,8657,8658,8659,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,
-8672,8673,8674,8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,
-8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,
-8704,8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,
-8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,
-8736,8737,8738,8739,8740,8741)
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrprober.py
deleted file mode 100644
index 5982a46b..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euckrprober.py
+++ /dev/null
@@ -1,42 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import EUCKRDistributionAnalysis
-from .mbcssm import EUCKRSMModel
-
-
-class EUCKRProber(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(EUCKRSMModel)
- self._mDistributionAnalyzer = EUCKRDistributionAnalysis()
- self.reset()
-
- def get_charset_name(self):
- return "EUC-KR"
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwfreq.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwfreq.py
deleted file mode 100644
index 576e7504..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwfreq.py
+++ /dev/null
@@ -1,428 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# EUCTW frequency table
-# Converted from big5 work
-# by Taiwan's Mandarin Promotion Council
-# <http:#www.edu.tw:81/mandr/>
-
-# 128 --> 0.42261
-# 256 --> 0.57851
-# 512 --> 0.74851
-# 1024 --> 0.89384
-# 2048 --> 0.97583
-#
-# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98
-# Random Distribution Ration = 512/(5401-512)=0.105
-#
-# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR
-
-EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75
-
-# Char to FreqOrder table ,
-EUCTW_TABLE_SIZE = 8102
-
-EUCTWCharToFreqOrder = (
- 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742
-3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758
-1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774
- 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790
-3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806
-4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822
-7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838
- 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854
- 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870
- 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886
-2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902
-1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918
-3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934
- 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950
-1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966
-3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982
-2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998
- 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014
-3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030
-1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046
-7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062
- 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078
-7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094
-1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110
- 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126
- 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142
-3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158
-3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174
- 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190
-2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206
-2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222
- 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238
- 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254
-3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270
-1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286
-1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302
-1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318
-2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334
- 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350
-4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366
-1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382
-7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398
-2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414
- 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430
- 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446
- 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462
- 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478
-7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494
- 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510
-1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526
- 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542
- 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558
-7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574
-1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590
- 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606
-3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622
-4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638
-3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654
- 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670
- 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686
-1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702
-4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718
-3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734
-3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750
-2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766
-7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782
-3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798
-7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814
-1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830
-2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846
-1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862
- 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878
-1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894
-4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910
-3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926
- 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942
- 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958
- 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974
-2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990
-7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006
-1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022
-2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038
-1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054
-1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070
-7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086
-7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102
-7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118
-3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134
-4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150
-1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166
-7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182
-2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198
-7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214
-3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230
-3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246
-7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262
-2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278
-7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294
- 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310
-4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326
-2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342
-7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358
-3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374
-2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390
-2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406
- 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422
-2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438
-1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454
-1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470
-2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486
-1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502
-7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518
-7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534
-2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550
-4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566
-1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582
-7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598
- 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614
-4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630
- 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646
-2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662
- 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678
-1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694
-1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710
- 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726
-3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742
-3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758
-1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774
-3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790
-7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806
-7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822
-1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838
-2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854
-1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870
-3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886
-2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902
-3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918
-2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934
-4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950
-4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966
-3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982
- 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998
-3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014
- 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030
-3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046
-3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062
-3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078
-1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094
-7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110
- 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126
-7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142
-1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158
- 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174
-4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190
-3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206
- 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222
-2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238
-2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254
-3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270
-1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286
-4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302
-2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318
-1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334
-1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350
-2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366
-3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382
-1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398
-7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414
-1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430
-4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446
-1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462
- 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478
-1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494
-3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510
-3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526
-2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542
-1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558
-4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574
- 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590
-7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606
-2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622
-3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638
-4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654
- 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670
-7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686
-7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702
-1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718
-4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734
-3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750
-2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766
-3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782
-3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798
-2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814
-1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830
-4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846
-3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862
-3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878
-2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894
-4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910
-7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926
-3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942
-2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958
-3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974
-1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990
-2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006
-3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022
-4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038
-2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054
-2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070
-7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086
-1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102
-2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118
-1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134
-3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150
-4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166
-2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182
-3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198
-3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214
-2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230
-4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246
-2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262
-3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278
-4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294
-7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310
-3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326
- 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342
-1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358
-4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374
-1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390
-4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406
-7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422
- 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438
-7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454
-2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470
-1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486
-1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502
-3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518
- 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534
- 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550
- 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566
-3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582
-2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598
- 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614
-7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630
-1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646
-3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662
-7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678
-1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694
-7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710
-4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726
-1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742
-2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758
-2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774
-4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790
- 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806
- 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822
-3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838
-3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854
-1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870
-2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886
-7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902
-1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918
-1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934
-3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950
- 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966
-1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982
-4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998
-7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014
-2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030
-3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046
- 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062
-1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078
-2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094
-2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110
-7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126
-7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142
-7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158
-2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174
-2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190
-1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206
-4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222
-3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238
-3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254
-4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270
-4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286
-2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302
-2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318
-7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334
-4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350
-7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366
-2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382
-1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398
-3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414
-4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430
-2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446
- 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462
-2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478
-1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494
-2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510
-2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526
-4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542
-7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558
-1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574
-3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590
-7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606
-1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622
-8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638
-2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654
-8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670
-2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686
-2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702
-8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718
-8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734
-8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750
- 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766
-8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782
-4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798
-3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814
-8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830
-1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846
-8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862
- 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878
-1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894
- 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910
-4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926
-1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942
-4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958
-1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974
- 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990
-3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006
-4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022
-8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038
- 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054
-3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070
- 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086
-2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102
-#Everything below is of no interest for detection purpose
-2515,1613,4582,8119,3312,3866,2516,8120,4058,8121,1637,4059,2466,4583,3867,8122, # 8118
-2493,3016,3734,8123,8124,2192,8125,8126,2162,8127,8128,8129,8130,8131,8132,8133, # 8134
-8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,8144,8145,8146,8147,8148,8149, # 8150
-8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8160,8161,8162,8163,8164,8165, # 8166
-8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181, # 8182
-8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197, # 8198
-8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213, # 8214
-8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229, # 8230
-8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245, # 8246
-8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,8258,8259,8260,8261, # 8262
-8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277, # 8278
-8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,8290,8291,8292,8293, # 8294
-8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,8308,8309, # 8310
-8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325, # 8326
-8326,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341, # 8342
-8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357, # 8358
-8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373, # 8374
-8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389, # 8390
-8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,8405, # 8406
-8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421, # 8422
-8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,8435,8436,8437, # 8438
-8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,8450,8451,8452,8453, # 8454
-8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8468,8469, # 8470
-8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,8480,8481,8482,8483,8484,8485, # 8486
-8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501, # 8502
-8502,8503,8504,8505,8506,8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517, # 8518
-8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533, # 8534
-8534,8535,8536,8537,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549, # 8550
-8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565, # 8566
-8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581, # 8582
-8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597, # 8598
-8598,8599,8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613, # 8614
-8614,8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629, # 8630
-8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,8645, # 8646
-8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,8660,8661, # 8662
-8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,8675,8676,8677, # 8678
-8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693, # 8694
-8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,8708,8709, # 8710
-8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,8723,8724,8725, # 8726
-8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741) # 8742
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwprober.py
deleted file mode 100644
index fe652fe3..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/euctwprober.py
+++ /dev/null
@@ -1,41 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import EUCTWDistributionAnalysis
-from .mbcssm import EUCTWSMModel
-
-class EUCTWProber(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(EUCTWSMModel)
- self._mDistributionAnalyzer = EUCTWDistributionAnalysis()
- self.reset()
-
- def get_charset_name(self):
- return "EUC-TW"
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312freq.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312freq.py
deleted file mode 100644
index 1238f510..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312freq.py
+++ /dev/null
@@ -1,472 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# GB2312 most frequently used character table
-#
-# Char to FreqOrder table , from hz6763
-
-# 512 --> 0.79 -- 0.79
-# 1024 --> 0.92 -- 0.13
-# 2048 --> 0.98 -- 0.06
-# 6768 --> 1.00 -- 0.02
-#
-# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79
-# Random Distribution Ration = 512 / (3755 - 512) = 0.157
-#
-# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR
-
-GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9
-
-GB2312_TABLE_SIZE = 3760
-
-GB2312CharToFreqOrder = (
-1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205,
-2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842,
-2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409,
- 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670,
-1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820,
-1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585,
- 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566,
-1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575,
-2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853,
-3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061,
- 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155,
-1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406,
- 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816,
-2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606,
- 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023,
-2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414,
-1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513,
-3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052,
- 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570,
-1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575,
- 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250,
-2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506,
-1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26,
-3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835,
-1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686,
-2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054,
-1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894,
- 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105,
-3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403,
-3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694,
- 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873,
-3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940,
- 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121,
-1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648,
-3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992,
-2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233,
-1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157,
- 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807,
-1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094,
-4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258,
- 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478,
-3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152,
-3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909,
- 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272,
-1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221,
-2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252,
-1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301,
-1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254,
- 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070,
-3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461,
-3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360,
-4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124,
- 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535,
-3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243,
-1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713,
-1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071,
-4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442,
- 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946,
- 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257,
-3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180,
-1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427,
- 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781,
-1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724,
-2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937,
- 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943,
- 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789,
- 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552,
-3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246,
-4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451,
-3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310,
- 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860,
-2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297,
-2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780,
-2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745,
- 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936,
-2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032,
- 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657,
- 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414,
- 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976,
-3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436,
-2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254,
-2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536,
-1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238,
- 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059,
-2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741,
- 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447,
- 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601,
-1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269,
-1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894,
- 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173,
- 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994,
-1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956,
-2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437,
-3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154,
-2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240,
-2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143,
-2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634,
-3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472,
-1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541,
-1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143,
-2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312,
-1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414,
-3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754,
-1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424,
-1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302,
-3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739,
- 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004,
-2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484,
-1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739,
-4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535,
-1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641,
-1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307,
-3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573,
-1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533,
- 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965,
- 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99,
-1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280,
- 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505,
-1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012,
-1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039,
- 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982,
-3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530,
-4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392,
-3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656,
-2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220,
-2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766,
-1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535,
-3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728,
-2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338,
-1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627,
-1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885,
- 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411,
-2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671,
-2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162,
-3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774,
-4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524,
-3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346,
- 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040,
-3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188,
-2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280,
-1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131,
- 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947,
- 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970,
-3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814,
-4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557,
-2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997,
-1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972,
-1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369,
- 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376,
-1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480,
-3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610,
- 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128,
- 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769,
-1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207,
- 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392,
-1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623,
- 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782,
-2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650,
- 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478,
-2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773,
-2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007,
-1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323,
-1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598,
-2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961,
- 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302,
-1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409,
-1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683,
-2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191,
-2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616,
-3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302,
-1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774,
-4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147,
- 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731,
- 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464,
-3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377,
-1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315,
- 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557,
-3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903,
-1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060,
-4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261,
-1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092,
-2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810,
-1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708,
- 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658,
-1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871,
-3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503,
- 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229,
-2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112,
- 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504,
-1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389,
-1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27,
-1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542,
-3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861,
-2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845,
-3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700,
-3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469,
-3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582,
- 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999,
-2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274,
- 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020,
-2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601,
- 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628,
-1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31,
- 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668,
- 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778,
-1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169,
-3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667,
-3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881,
-1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276,
-1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320,
-3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751,
-2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432,
-2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772,
-1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843,
-3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116,
- 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904,
-4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652,
-1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664,
-2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770,
-3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283,
-3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626,
-1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713,
- 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333,
- 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062,
-2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555,
- 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014,
-1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510,
- 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015,
-1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459,
-1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390,
-1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238,
-1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232,
-1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624,
- 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189,
- 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, # last 512
-#Everything below is of no interest for detection purpose
-5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636,
-5509,3257,5510,5973,5445,5872,4941,4403,3174,4627,5873,6276,2286,4230,5446,5874,
-5122,6102,6103,4162,5447,5123,5323,4849,6277,3980,3851,5066,4246,5774,5067,6278,
-3001,2807,5695,3346,5775,5974,5158,5448,6487,5975,5976,5776,3598,6279,5696,4806,
-4211,4154,6280,6488,6489,6490,6281,4212,5037,3374,4171,6491,4562,4807,4722,4827,
-5977,6104,4532,4079,5159,5324,5160,4404,3858,5359,5875,3975,4288,4610,3486,4512,
-5325,3893,5360,6282,6283,5560,2522,4231,5978,5186,5449,2569,3878,6284,5401,3578,
-4415,6285,4656,5124,5979,2506,4247,4449,3219,3417,4334,4969,4329,6492,4576,4828,
-4172,4416,4829,5402,6286,3927,3852,5361,4369,4830,4477,4867,5876,4173,6493,6105,
-4657,6287,6106,5877,5450,6494,4155,4868,5451,3700,5629,4384,6288,6289,5878,3189,
-4881,6107,6290,6495,4513,6496,4692,4515,4723,5100,3356,6497,6291,3810,4080,5561,
-3570,4430,5980,6498,4355,5697,6499,4724,6108,6109,3764,4050,5038,5879,4093,3226,
-6292,5068,5217,4693,3342,5630,3504,4831,4377,4466,4309,5698,4431,5777,6293,5778,
-4272,3706,6110,5326,3752,4676,5327,4273,5403,4767,5631,6500,5699,5880,3475,5039,
-6294,5562,5125,4348,4301,4482,4068,5126,4593,5700,3380,3462,5981,5563,3824,5404,
-4970,5511,3825,4738,6295,6501,5452,4516,6111,5881,5564,6502,6296,5982,6503,4213,
-4163,3454,6504,6112,4009,4450,6113,4658,6297,6114,3035,6505,6115,3995,4904,4739,
-4563,4942,4110,5040,3661,3928,5362,3674,6506,5292,3612,4791,5565,4149,5983,5328,
-5259,5021,4725,4577,4564,4517,4364,6298,5405,4578,5260,4594,4156,4157,5453,3592,
-3491,6507,5127,5512,4709,4922,5984,5701,4726,4289,6508,4015,6116,5128,4628,3424,
-4241,5779,6299,4905,6509,6510,5454,5702,5780,6300,4365,4923,3971,6511,5161,3270,
-3158,5985,4100, 867,5129,5703,6117,5363,3695,3301,5513,4467,6118,6512,5455,4232,
-4242,4629,6513,3959,4478,6514,5514,5329,5986,4850,5162,5566,3846,4694,6119,5456,
-4869,5781,3779,6301,5704,5987,5515,4710,6302,5882,6120,4392,5364,5705,6515,6121,
-6516,6517,3736,5988,5457,5989,4695,2457,5883,4551,5782,6303,6304,6305,5130,4971,
-6122,5163,6123,4870,3263,5365,3150,4871,6518,6306,5783,5069,5706,3513,3498,4409,
-5330,5632,5366,5458,5459,3991,5990,4502,3324,5991,5784,3696,4518,5633,4119,6519,
-4630,5634,4417,5707,4832,5992,3418,6124,5993,5567,4768,5218,6520,4595,3458,5367,
-6125,5635,6126,4202,6521,4740,4924,6307,3981,4069,4385,6308,3883,2675,4051,3834,
-4302,4483,5568,5994,4972,4101,5368,6309,5164,5884,3922,6127,6522,6523,5261,5460,
-5187,4164,5219,3538,5516,4111,3524,5995,6310,6311,5369,3181,3386,2484,5188,3464,
-5569,3627,5708,6524,5406,5165,4677,4492,6312,4872,4851,5885,4468,5996,6313,5709,
-5710,6128,2470,5886,6314,5293,4882,5785,3325,5461,5101,6129,5711,5786,6525,4906,
-6526,6527,4418,5887,5712,4808,2907,3701,5713,5888,6528,3765,5636,5331,6529,6530,
-3593,5889,3637,4943,3692,5714,5787,4925,6315,6130,5462,4405,6131,6132,6316,5262,
-6531,6532,5715,3859,5716,5070,4696,5102,3929,5788,3987,4792,5997,6533,6534,3920,
-4809,5000,5998,6535,2974,5370,6317,5189,5263,5717,3826,6536,3953,5001,4883,3190,
-5463,5890,4973,5999,4741,6133,6134,3607,5570,6000,4711,3362,3630,4552,5041,6318,
-6001,2950,2953,5637,4646,5371,4944,6002,2044,4120,3429,6319,6537,5103,4833,6538,
-6539,4884,4647,3884,6003,6004,4758,3835,5220,5789,4565,5407,6540,6135,5294,4697,
-4852,6320,6321,3206,4907,6541,6322,4945,6542,6136,6543,6323,6005,4631,3519,6544,
-5891,6545,5464,3784,5221,6546,5571,4659,6547,6324,6137,5190,6548,3853,6549,4016,
-4834,3954,6138,5332,3827,4017,3210,3546,4469,5408,5718,3505,4648,5790,5131,5638,
-5791,5465,4727,4318,6325,6326,5792,4553,4010,4698,3439,4974,3638,4335,3085,6006,
-5104,5042,5166,5892,5572,6327,4356,4519,5222,5573,5333,5793,5043,6550,5639,5071,
-4503,6328,6139,6551,6140,3914,3901,5372,6007,5640,4728,4793,3976,3836,4885,6552,
-4127,6553,4451,4102,5002,6554,3686,5105,6555,5191,5072,5295,4611,5794,5296,6556,
-5893,5264,5894,4975,5466,5265,4699,4976,4370,4056,3492,5044,4886,6557,5795,4432,
-4769,4357,5467,3940,4660,4290,6141,4484,4770,4661,3992,6329,4025,4662,5022,4632,
-4835,4070,5297,4663,4596,5574,5132,5409,5895,6142,4504,5192,4664,5796,5896,3885,
-5575,5797,5023,4810,5798,3732,5223,4712,5298,4084,5334,5468,6143,4052,4053,4336,
-4977,4794,6558,5335,4908,5576,5224,4233,5024,4128,5469,5225,4873,6008,5045,4729,
-4742,4633,3675,4597,6559,5897,5133,5577,5003,5641,5719,6330,6560,3017,2382,3854,
-4406,4811,6331,4393,3964,4946,6561,2420,3722,6562,4926,4378,3247,1736,4442,6332,
-5134,6333,5226,3996,2918,5470,4319,4003,4598,4743,4744,4485,3785,3902,5167,5004,
-5373,4394,5898,6144,4874,1793,3997,6334,4085,4214,5106,5642,4909,5799,6009,4419,
-4189,3330,5899,4165,4420,5299,5720,5227,3347,6145,4081,6335,2876,3930,6146,3293,
-3786,3910,3998,5900,5300,5578,2840,6563,5901,5579,6147,3531,5374,6564,6565,5580,
-4759,5375,6566,6148,3559,5643,6336,6010,5517,6337,6338,5721,5902,3873,6011,6339,
-6567,5518,3868,3649,5722,6568,4771,4947,6569,6149,4812,6570,2853,5471,6340,6341,
-5644,4795,6342,6012,5723,6343,5724,6013,4349,6344,3160,6150,5193,4599,4514,4493,
-5168,4320,6345,4927,3666,4745,5169,5903,5005,4928,6346,5725,6014,4730,4203,5046,
-4948,3395,5170,6015,4150,6016,5726,5519,6347,5047,3550,6151,6348,4197,4310,5904,
-6571,5581,2965,6152,4978,3960,4291,5135,6572,5301,5727,4129,4026,5905,4853,5728,
-5472,6153,6349,4533,2700,4505,5336,4678,3583,5073,2994,4486,3043,4554,5520,6350,
-6017,5800,4487,6351,3931,4103,5376,6352,4011,4321,4311,4190,5136,6018,3988,3233,
-4350,5906,5645,4198,6573,5107,3432,4191,3435,5582,6574,4139,5410,6353,5411,3944,
-5583,5074,3198,6575,6354,4358,6576,5302,4600,5584,5194,5412,6577,6578,5585,5413,
-5303,4248,5414,3879,4433,6579,4479,5025,4854,5415,6355,4760,4772,3683,2978,4700,
-3797,4452,3965,3932,3721,4910,5801,6580,5195,3551,5907,3221,3471,3029,6019,3999,
-5908,5909,5266,5267,3444,3023,3828,3170,4796,5646,4979,4259,6356,5647,5337,3694,
-6357,5648,5338,4520,4322,5802,3031,3759,4071,6020,5586,4836,4386,5048,6581,3571,
-4679,4174,4949,6154,4813,3787,3402,3822,3958,3215,3552,5268,4387,3933,4950,4359,
-6021,5910,5075,3579,6358,4234,4566,5521,6359,3613,5049,6022,5911,3375,3702,3178,
-4911,5339,4521,6582,6583,4395,3087,3811,5377,6023,6360,6155,4027,5171,5649,4421,
-4249,2804,6584,2270,6585,4000,4235,3045,6156,5137,5729,4140,4312,3886,6361,4330,
-6157,4215,6158,3500,3676,4929,4331,3713,4930,5912,4265,3776,3368,5587,4470,4855,
-3038,4980,3631,6159,6160,4132,4680,6161,6362,3923,4379,5588,4255,6586,4121,6587,
-6363,4649,6364,3288,4773,4774,6162,6024,6365,3543,6588,4274,3107,3737,5050,5803,
-4797,4522,5589,5051,5730,3714,4887,5378,4001,4523,6163,5026,5522,4701,4175,2791,
-3760,6589,5473,4224,4133,3847,4814,4815,4775,3259,5416,6590,2738,6164,6025,5304,
-3733,5076,5650,4816,5590,6591,6165,6592,3934,5269,6593,3396,5340,6594,5804,3445,
-3602,4042,4488,5731,5732,3525,5591,4601,5196,6166,6026,5172,3642,4612,3202,4506,
-4798,6366,3818,5108,4303,5138,5139,4776,3332,4304,2915,3415,4434,5077,5109,4856,
-2879,5305,4817,6595,5913,3104,3144,3903,4634,5341,3133,5110,5651,5805,6167,4057,
-5592,2945,4371,5593,6596,3474,4182,6367,6597,6168,4507,4279,6598,2822,6599,4777,
-4713,5594,3829,6169,3887,5417,6170,3653,5474,6368,4216,2971,5228,3790,4579,6369,
-5733,6600,6601,4951,4746,4555,6602,5418,5475,6027,3400,4665,5806,6171,4799,6028,
-5052,6172,3343,4800,4747,5006,6370,4556,4217,5476,4396,5229,5379,5477,3839,5914,
-5652,5807,4714,3068,4635,5808,6173,5342,4192,5078,5419,5523,5734,6174,4557,6175,
-4602,6371,6176,6603,5809,6372,5735,4260,3869,5111,5230,6029,5112,6177,3126,4681,
-5524,5915,2706,3563,4748,3130,6178,4018,5525,6604,6605,5478,4012,4837,6606,4534,
-4193,5810,4857,3615,5479,6030,4082,3697,3539,4086,5270,3662,4508,4931,5916,4912,
-5811,5027,3888,6607,4397,3527,3302,3798,2775,2921,2637,3966,4122,4388,4028,4054,
-1633,4858,5079,3024,5007,3982,3412,5736,6608,3426,3236,5595,3030,6179,3427,3336,
-3279,3110,6373,3874,3039,5080,5917,5140,4489,3119,6374,5812,3405,4494,6031,4666,
-4141,6180,4166,6032,5813,4981,6609,5081,4422,4982,4112,3915,5653,3296,3983,6375,
-4266,4410,5654,6610,6181,3436,5082,6611,5380,6033,3819,5596,4535,5231,5306,5113,
-6612,4952,5918,4275,3113,6613,6376,6182,6183,5814,3073,4731,4838,5008,3831,6614,
-4888,3090,3848,4280,5526,5232,3014,5655,5009,5737,5420,5527,6615,5815,5343,5173,
-5381,4818,6616,3151,4953,6617,5738,2796,3204,4360,2989,4281,5739,5174,5421,5197,
-3132,5141,3849,5142,5528,5083,3799,3904,4839,5480,2880,4495,3448,6377,6184,5271,
-5919,3771,3193,6034,6035,5920,5010,6036,5597,6037,6378,6038,3106,5422,6618,5423,
-5424,4142,6619,4889,5084,4890,4313,5740,6620,3437,5175,5307,5816,4199,5198,5529,
-5817,5199,5656,4913,5028,5344,3850,6185,2955,5272,5011,5818,4567,4580,5029,5921,
-3616,5233,6621,6622,6186,4176,6039,6379,6380,3352,5200,5273,2908,5598,5234,3837,
-5308,6623,6624,5819,4496,4323,5309,5201,6625,6626,4983,3194,3838,4167,5530,5922,
-5274,6381,6382,3860,3861,5599,3333,4292,4509,6383,3553,5481,5820,5531,4778,6187,
-3955,3956,4324,4389,4218,3945,4325,3397,2681,5923,4779,5085,4019,5482,4891,5382,
-5383,6040,4682,3425,5275,4094,6627,5310,3015,5483,5657,4398,5924,3168,4819,6628,
-5925,6629,5532,4932,4613,6041,6630,4636,6384,4780,4204,5658,4423,5821,3989,4683,
-5822,6385,4954,6631,5345,6188,5425,5012,5384,3894,6386,4490,4104,6632,5741,5053,
-6633,5823,5926,5659,5660,5927,6634,5235,5742,5824,4840,4933,4820,6387,4859,5928,
-4955,6388,4143,3584,5825,5346,5013,6635,5661,6389,5014,5484,5743,4337,5176,5662,
-6390,2836,6391,3268,6392,6636,6042,5236,6637,4158,6638,5744,5663,4471,5347,3663,
-4123,5143,4293,3895,6639,6640,5311,5929,5826,3800,6189,6393,6190,5664,5348,3554,
-3594,4749,4603,6641,5385,4801,6043,5827,4183,6642,5312,5426,4761,6394,5665,6191,
-4715,2669,6643,6644,5533,3185,5427,5086,5930,5931,5386,6192,6044,6645,4781,4013,
-5745,4282,4435,5534,4390,4267,6045,5746,4984,6046,2743,6193,3501,4087,5485,5932,
-5428,4184,4095,5747,4061,5054,3058,3862,5933,5600,6646,5144,3618,6395,3131,5055,
-5313,6396,4650,4956,3855,6194,3896,5202,4985,4029,4225,6195,6647,5828,5486,5829,
-3589,3002,6648,6397,4782,5276,6649,6196,6650,4105,3803,4043,5237,5830,6398,4096,
-3643,6399,3528,6651,4453,3315,4637,6652,3984,6197,5535,3182,3339,6653,3096,2660,
-6400,6654,3449,5934,4250,4236,6047,6401,5831,6655,5487,3753,4062,5832,6198,6199,
-6656,3766,6657,3403,4667,6048,6658,4338,2897,5833,3880,2797,3780,4326,6659,5748,
-5015,6660,5387,4351,5601,4411,6661,3654,4424,5935,4339,4072,5277,4568,5536,6402,
-6662,5238,6663,5349,5203,6200,5204,6201,5145,4536,5016,5056,4762,5834,4399,4957,
-6202,6403,5666,5749,6664,4340,6665,5936,5177,5667,6666,6667,3459,4668,6404,6668,
-6669,4543,6203,6670,4276,6405,4480,5537,6671,4614,5205,5668,6672,3348,2193,4763,
-6406,6204,5937,5602,4177,5669,3419,6673,4020,6205,4443,4569,5388,3715,3639,6407,
-6049,4058,6206,6674,5938,4544,6050,4185,4294,4841,4651,4615,5488,6207,6408,6051,
-5178,3241,3509,5835,6208,4958,5836,4341,5489,5278,6209,2823,5538,5350,5206,5429,
-6675,4638,4875,4073,3516,4684,4914,4860,5939,5603,5389,6052,5057,3237,5490,3791,
-6676,6409,6677,4821,4915,4106,5351,5058,4243,5539,4244,5604,4842,4916,5239,3028,
-3716,5837,5114,5605,5390,5940,5430,6210,4332,6678,5540,4732,3667,3840,6053,4305,
-3408,5670,5541,6410,2744,5240,5750,6679,3234,5606,6680,5607,5671,3608,4283,4159,
-4400,5352,4783,6681,6411,6682,4491,4802,6211,6412,5941,6413,6414,5542,5751,6683,
-4669,3734,5942,6684,6415,5943,5059,3328,4670,4144,4268,6685,6686,6687,6688,4372,
-3603,6689,5944,5491,4373,3440,6416,5543,4784,4822,5608,3792,4616,5838,5672,3514,
-5391,6417,4892,6690,4639,6691,6054,5673,5839,6055,6692,6056,5392,6212,4038,5544,
-5674,4497,6057,6693,5840,4284,5675,4021,4545,5609,6418,4454,6419,6213,4113,4472,
-5314,3738,5087,5279,4074,5610,4959,4063,3179,4750,6058,6420,6214,3476,4498,4716,
-5431,4960,4685,6215,5241,6694,6421,6216,6695,5841,5945,6422,3748,5946,5179,3905,
-5752,5545,5947,4374,6217,4455,6423,4412,6218,4803,5353,6696,3832,5280,6219,4327,
-4702,6220,6221,6059,4652,5432,6424,3749,4751,6425,5753,4986,5393,4917,5948,5030,
-5754,4861,4733,6426,4703,6697,6222,4671,5949,4546,4961,5180,6223,5031,3316,5281,
-6698,4862,4295,4934,5207,3644,6427,5842,5950,6428,6429,4570,5843,5282,6430,6224,
-5088,3239,6060,6699,5844,5755,6061,6431,2701,5546,6432,5115,5676,4039,3993,3327,
-4752,4425,5315,6433,3941,6434,5677,4617,4604,3074,4581,6225,5433,6435,6226,6062,
-4823,5756,5116,6227,3717,5678,4717,5845,6436,5679,5846,6063,5847,6064,3977,3354,
-6437,3863,5117,6228,5547,5394,4499,4524,6229,4605,6230,4306,4500,6700,5951,6065,
-3693,5952,5089,4366,4918,6701,6231,5548,6232,6702,6438,4704,5434,6703,6704,5953,
-4168,6705,5680,3420,6706,5242,4407,6066,3812,5757,5090,5954,4672,4525,3481,5681,
-4618,5395,5354,5316,5955,6439,4962,6707,4526,6440,3465,4673,6067,6441,5682,6708,
-5435,5492,5758,5683,4619,4571,4674,4804,4893,4686,5493,4753,6233,6068,4269,6442,
-6234,5032,4705,5146,5243,5208,5848,6235,6443,4963,5033,4640,4226,6236,5849,3387,
-6444,6445,4436,4437,5850,4843,5494,4785,4894,6709,4361,6710,5091,5956,3331,6237,
-4987,5549,6069,6711,4342,3517,4473,5317,6070,6712,6071,4706,6446,5017,5355,6713,
-6714,4988,5436,6447,4734,5759,6715,4735,4547,4456,4754,6448,5851,6449,6450,3547,
-5852,5318,6451,6452,5092,4205,6716,6238,4620,4219,5611,6239,6072,4481,5760,5957,
-5958,4059,6240,6453,4227,4537,6241,5761,4030,4186,5244,5209,3761,4457,4876,3337,
-5495,5181,6242,5959,5319,5612,5684,5853,3493,5854,6073,4169,5613,5147,4895,6074,
-5210,6717,5182,6718,3830,6243,2798,3841,6075,6244,5855,5614,3604,4606,5496,5685,
-5118,5356,6719,6454,5960,5357,5961,6720,4145,3935,4621,5119,5962,4261,6721,6455,
-4786,5963,4375,4582,6245,6246,6247,6076,5437,4877,5856,3376,4380,6248,4160,6722,
-5148,6456,5211,6457,6723,4718,6458,6724,6249,5358,4044,3297,6459,6250,5857,5615,
-5497,5245,6460,5498,6725,6251,6252,5550,3793,5499,2959,5396,6461,6462,4572,5093,
-5500,5964,3806,4146,6463,4426,5762,5858,6077,6253,4755,3967,4220,5965,6254,4989,
-5501,6464,4352,6726,6078,4764,2290,5246,3906,5438,5283,3767,4964,2861,5763,5094,
-6255,6256,4622,5616,5859,5860,4707,6727,4285,4708,4824,5617,6257,5551,4787,5212,
-4965,4935,4687,6465,6728,6466,5686,6079,3494,4413,2995,5247,5966,5618,6729,5967,
-5764,5765,5687,5502,6730,6731,6080,5397,6467,4990,6258,6732,4538,5060,5619,6733,
-4719,5688,5439,5018,5149,5284,5503,6734,6081,4607,6259,5120,3645,5861,4583,6260,
-4584,4675,5620,4098,5440,6261,4863,2379,3306,4585,5552,5689,4586,5285,6735,4864,
-6736,5286,6082,6737,4623,3010,4788,4381,4558,5621,4587,4896,3698,3161,5248,4353,
-4045,6262,3754,5183,4588,6738,6263,6739,6740,5622,3936,6741,6468,6742,6264,5095,
-6469,4991,5968,6743,4992,6744,6083,4897,6745,4256,5766,4307,3108,3968,4444,5287,
-3889,4343,6084,4510,6085,4559,6086,4898,5969,6746,5623,5061,4919,5249,5250,5504,
-5441,6265,5320,4878,3242,5862,5251,3428,6087,6747,4237,5624,5442,6266,5553,4539,
-6748,2585,3533,5398,4262,6088,5150,4736,4438,6089,6267,5505,4966,6749,6268,6750,
-6269,5288,5554,3650,6090,6091,4624,6092,5690,6751,5863,4270,5691,4277,5555,5864,
-6752,5692,4720,4865,6470,5151,4688,4825,6753,3094,6754,6471,3235,4653,6755,5213,
-5399,6756,3201,4589,5865,4967,6472,5866,6473,5019,3016,6757,5321,4756,3957,4573,
-6093,4993,5767,4721,6474,6758,5625,6759,4458,6475,6270,6760,5556,4994,5214,5252,
-6271,3875,5768,6094,5034,5506,4376,5769,6761,2120,6476,5253,5770,6762,5771,5970,
-3990,5971,5557,5558,5772,6477,6095,2787,4641,5972,5121,6096,6097,6272,6763,3703,
-5867,5507,6273,4206,6274,4789,6098,6764,3619,3646,3833,3804,2394,3788,4936,3978,
-4866,4899,6099,6100,5559,6478,6765,3599,5868,6101,5869,5870,6275,6766,4527,6767)
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312prober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312prober.py
deleted file mode 100644
index 0325a2d8..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/gb2312prober.py
+++ /dev/null
@@ -1,41 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import GB2312DistributionAnalysis
-from .mbcssm import GB2312SMModel
-
-class GB2312Prober(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(GB2312SMModel)
- self._mDistributionAnalyzer = GB2312DistributionAnalysis()
- self.reset()
-
- def get_charset_name(self):
- return "GB2312"
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/hebrewprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/hebrewprober.py
deleted file mode 100644
index ba225c5e..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/hebrewprober.py
+++ /dev/null
@@ -1,283 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Shy Shalom
-# Portions created by the Initial Developer are Copyright (C) 2005
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .charsetprober import CharSetProber
-from .constants import eNotMe, eDetecting
-from .compat import wrap_ord
-
-# This prober doesn't actually recognize a language or a charset.
-# It is a helper prober for the use of the Hebrew model probers
-
-### General ideas of the Hebrew charset recognition ###
-#
-# Four main charsets exist in Hebrew:
-# "ISO-8859-8" - Visual Hebrew
-# "windows-1255" - Logical Hebrew
-# "ISO-8859-8-I" - Logical Hebrew
-# "x-mac-hebrew" - ?? Logical Hebrew ??
-#
-# Both "ISO" charsets use a completely identical set of code points, whereas
-# "windows-1255" and "x-mac-hebrew" are two different proper supersets of
-# these code points. windows-1255 defines additional characters in the range
-# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific
-# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6.
-# x-mac-hebrew defines similar additional code points but with a different
-# mapping.
-#
-# As far as an average Hebrew text with no diacritics is concerned, all four
-# charsets are identical with respect to code points. Meaning that for the
-# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters
-# (including final letters).
-#
-# The dominant difference between these charsets is their directionality.
-# "Visual" directionality means that the text is ordered as if the renderer is
-# not aware of a BIDI rendering algorithm. The renderer sees the text and
-# draws it from left to right. The text itself when ordered naturally is read
-# backwards. A buffer of Visual Hebrew generally looks like so:
-# "[last word of first line spelled backwards] [whole line ordered backwards
-# and spelled backwards] [first word of first line spelled backwards]
-# [end of line] [last word of second line] ... etc' "
-# adding punctuation marks, numbers and English text to visual text is
-# naturally also "visual" and from left to right.
-#
-# "Logical" directionality means the text is ordered "naturally" according to
-# the order it is read. It is the responsibility of the renderer to display
-# the text from right to left. A BIDI algorithm is used to place general
-# punctuation marks, numbers and English text in the text.
-#
-# Texts in x-mac-hebrew are almost impossible to find on the Internet. From
-# what little evidence I could find, it seems that its general directionality
-# is Logical.
-#
-# To sum up all of the above, the Hebrew probing mechanism knows about two
-# charsets:
-# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are
-# backwards while line order is natural. For charset recognition purposes
-# the line order is unimportant (In fact, for this implementation, even
-# word order is unimportant).
-# Logical Hebrew - "windows-1255" - normal, naturally ordered text.
-#
-# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be
-# specifically identified.
-# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew
-# that contain special punctuation marks or diacritics is displayed with
-# some unconverted characters showing as question marks. This problem might
-# be corrected using another model prober for x-mac-hebrew. Due to the fact
-# that x-mac-hebrew texts are so rare, writing another model prober isn't
-# worth the effort and performance hit.
-#
-#### The Prober ####
-#
-# The prober is divided between two SBCharSetProbers and a HebrewProber,
-# all of which are managed, created, fed data, inquired and deleted by the
-# SBCSGroupProber. The two SBCharSetProbers identify that the text is in
-# fact some kind of Hebrew, Logical or Visual. The final decision about which
-# one is it is made by the HebrewProber by combining final-letter scores
-# with the scores of the two SBCharSetProbers to produce a final answer.
-#
-# The SBCSGroupProber is responsible for stripping the original text of HTML
-# tags, English characters, numbers, low-ASCII punctuation characters, spaces
-# and new lines. It reduces any sequence of such characters to a single space.
-# The buffer fed to each prober in the SBCS group prober is pure text in
-# high-ASCII.
-# The two SBCharSetProbers (model probers) share the same language model:
-# Win1255Model.
-# The first SBCharSetProber uses the model normally as any other
-# SBCharSetProber does, to recognize windows-1255, upon which this model was
-# built. The second SBCharSetProber is told to make the pair-of-letter
-# lookup in the language model backwards. This in practice exactly simulates
-# a visual Hebrew model using the windows-1255 logical Hebrew model.
-#
-# The HebrewProber is not using any language model. All it does is look for
-# final-letter evidence suggesting the text is either logical Hebrew or visual
-# Hebrew. Disjointed from the model probers, the results of the HebrewProber
-# alone are meaningless. HebrewProber always returns 0.00 as confidence
-# since it never identifies a charset by itself. Instead, the pointer to the
-# HebrewProber is passed to the model probers as a helper "Name Prober".
-# When the Group prober receives a positive identification from any prober,
-# it asks for the name of the charset identified. If the prober queried is a
-# Hebrew model prober, the model prober forwards the call to the
-# HebrewProber to make the final decision. In the HebrewProber, the
-# decision is made according to the final-letters scores maintained and Both
-# model probers scores. The answer is returned in the form of the name of the
-# charset identified, either "windows-1255" or "ISO-8859-8".
-
-# windows-1255 / ISO-8859-8 code points of interest
-FINAL_KAF = 0xea
-NORMAL_KAF = 0xeb
-FINAL_MEM = 0xed
-NORMAL_MEM = 0xee
-FINAL_NUN = 0xef
-NORMAL_NUN = 0xf0
-FINAL_PE = 0xf3
-NORMAL_PE = 0xf4
-FINAL_TSADI = 0xf5
-NORMAL_TSADI = 0xf6
-
-# Minimum Visual vs Logical final letter score difference.
-# If the difference is below this, don't rely solely on the final letter score
-# distance.
-MIN_FINAL_CHAR_DISTANCE = 5
-
-# Minimum Visual vs Logical model score difference.
-# If the difference is below this, don't rely at all on the model score
-# distance.
-MIN_MODEL_DISTANCE = 0.01
-
-VISUAL_HEBREW_NAME = "ISO-8859-8"
-LOGICAL_HEBREW_NAME = "windows-1255"
-
-
-class HebrewProber(CharSetProber):
- def __init__(self):
- CharSetProber.__init__(self)
- self._mLogicalProber = None
- self._mVisualProber = None
- self.reset()
-
- def reset(self):
- self._mFinalCharLogicalScore = 0
- self._mFinalCharVisualScore = 0
- # The two last characters seen in the previous buffer,
- # mPrev and mBeforePrev are initialized to space in order to simulate
- # a word delimiter at the beginning of the data
- self._mPrev = ' '
- self._mBeforePrev = ' '
- # These probers are owned by the group prober.
-
- def set_model_probers(self, logicalProber, visualProber):
- self._mLogicalProber = logicalProber
- self._mVisualProber = visualProber
-
- def is_final(self, c):
- return wrap_ord(c) in [FINAL_KAF, FINAL_MEM, FINAL_NUN, FINAL_PE,
- FINAL_TSADI]
-
- def is_non_final(self, c):
- # The normal Tsadi is not a good Non-Final letter due to words like
- # 'lechotet' (to chat) containing an apostrophe after the tsadi. This
- # apostrophe is converted to a space in FilterWithoutEnglishLetters
- # causing the Non-Final tsadi to appear at an end of a word even
- # though this is not the case in the original text.
- # The letters Pe and Kaf rarely display a related behavior of not being
- # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak'
- # for example legally end with a Non-Final Pe or Kaf. However, the
- # benefit of these letters as Non-Final letters outweighs the damage
- # since these words are quite rare.
- return wrap_ord(c) in [NORMAL_KAF, NORMAL_MEM, NORMAL_NUN, NORMAL_PE]
-
- def feed(self, aBuf):
- # Final letter analysis for logical-visual decision.
- # Look for evidence that the received buffer is either logical Hebrew
- # or visual Hebrew.
- # The following cases are checked:
- # 1) A word longer than 1 letter, ending with a final letter. This is
- # an indication that the text is laid out "naturally" since the
- # final letter really appears at the end. +1 for logical score.
- # 2) A word longer than 1 letter, ending with a Non-Final letter. In
- # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi,
- # should not end with the Non-Final form of that letter. Exceptions
- # to this rule are mentioned above in isNonFinal(). This is an
- # indication that the text is laid out backwards. +1 for visual
- # score
- # 3) A word longer than 1 letter, starting with a final letter. Final
- # letters should not appear at the beginning of a word. This is an
- # indication that the text is laid out backwards. +1 for visual
- # score.
- #
- # The visual score and logical score are accumulated throughout the
- # text and are finally checked against each other in GetCharSetName().
- # No checking for final letters in the middle of words is done since
- # that case is not an indication for either Logical or Visual text.
- #
- # We automatically filter out all 7-bit characters (replace them with
- # spaces) so the word boundary detection works properly. [MAP]
-
- if self.get_state() == eNotMe:
- # Both model probers say it's not them. No reason to continue.
- return eNotMe
-
- aBuf = self.filter_high_bit_only(aBuf)
-
- for cur in aBuf:
- if cur == ' ':
- # We stand on a space - a word just ended
- if self._mBeforePrev != ' ':
- # next-to-last char was not a space so self._mPrev is not a
- # 1 letter word
- if self.is_final(self._mPrev):
- # case (1) [-2:not space][-1:final letter][cur:space]
- self._mFinalCharLogicalScore += 1
- elif self.is_non_final(self._mPrev):
- # case (2) [-2:not space][-1:Non-Final letter][
- # cur:space]
- self._mFinalCharVisualScore += 1
- else:
- # Not standing on a space
- if ((self._mBeforePrev == ' ') and
- (self.is_final(self._mPrev)) and (cur != ' ')):
- # case (3) [-2:space][-1:final letter][cur:not space]
- self._mFinalCharVisualScore += 1
- self._mBeforePrev = self._mPrev
- self._mPrev = cur
-
- # Forever detecting, till the end or until both model probers return
- # eNotMe (handled above)
- return eDetecting
-
- def get_charset_name(self):
- # Make the decision: is it Logical or Visual?
- # If the final letter score distance is dominant enough, rely on it.
- finalsub = self._mFinalCharLogicalScore - self._mFinalCharVisualScore
- if finalsub >= MIN_FINAL_CHAR_DISTANCE:
- return LOGICAL_HEBREW_NAME
- if finalsub <= -MIN_FINAL_CHAR_DISTANCE:
- return VISUAL_HEBREW_NAME
-
- # It's not dominant enough, try to rely on the model scores instead.
- modelsub = (self._mLogicalProber.get_confidence()
- - self._mVisualProber.get_confidence())
- if modelsub > MIN_MODEL_DISTANCE:
- return LOGICAL_HEBREW_NAME
- if modelsub < -MIN_MODEL_DISTANCE:
- return VISUAL_HEBREW_NAME
-
- # Still no good, back to final letter distance, maybe it'll save the
- # day.
- if finalsub < 0.0:
- return VISUAL_HEBREW_NAME
-
- # (finalsub > 0 - Logical) or (don't know what to do) default to
- # Logical.
- return LOGICAL_HEBREW_NAME
-
- def get_state(self):
- # Remain active as long as any of the model probers are active.
- if (self._mLogicalProber.get_state() == eNotMe) and \
- (self._mVisualProber.get_state() == eNotMe):
- return eNotMe
- return eDetecting
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jisfreq.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jisfreq.py
deleted file mode 100644
index 064345b0..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jisfreq.py
+++ /dev/null
@@ -1,569 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# Sampling from about 20M text materials include literature and computer technology
-#
-# Japanese frequency table, applied to both S-JIS and EUC-JP
-# They are sorted in order.
-
-# 128 --> 0.77094
-# 256 --> 0.85710
-# 512 --> 0.92635
-# 1024 --> 0.97130
-# 2048 --> 0.99431
-#
-# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58
-# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191
-#
-# Typical Distribution Ratio, 25% of IDR
-
-JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0
-
-# Char to FreqOrder table ,
-JIS_TABLE_SIZE = 4368
-
-JISCharToFreqOrder = (
- 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16
-3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32
-1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48
-2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64
-2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80
-5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96
-1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112
-5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128
-5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144
-5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160
-5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176
-5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192
-5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208
-1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224
-1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240
-1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256
-2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272
-3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288
-3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304
- 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320
- 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336
-1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352
- 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368
-5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384
- 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400
- 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416
- 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432
- 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448
- 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464
-5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480
-5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496
-5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512
-4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528
-5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544
-5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560
-5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576
-5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592
-5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608
-5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624
-5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640
-5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656
-5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672
-3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688
-5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704
-5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720
-5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736
-5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752
-5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768
-5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784
-5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800
-5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816
-5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832
-5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848
-5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864
-5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880
-5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896
-5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912
-5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928
-5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944
-5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960
-5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976
-5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992
-5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008
-5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024
-5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040
-5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056
-5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072
-5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088
-5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104
-5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120
-5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136
-5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152
-5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168
-5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184
-5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200
-5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216
-5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232
-5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248
-5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264
-5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280
-5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296
-6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312
-6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328
-6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344
-6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360
-6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376
-6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392
-6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408
-6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424
-4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440
- 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456
- 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472
-1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488
-1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504
- 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520
-3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536
-3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552
- 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568
-3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584
-3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600
- 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616
-2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632
- 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648
-3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664
-1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680
- 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696
-1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712
- 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728
-2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744
-2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760
-2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776
-2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792
-1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808
-1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824
-1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840
-1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856
-2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872
-1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888
-2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904
-1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920
-1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936
-1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952
-1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968
-1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984
-1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000
- 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016
- 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032
-1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048
-2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064
-2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080
-2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096
-3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112
-3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128
- 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144
-3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160
-1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176
- 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192
-2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208
-1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224
- 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240
-3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256
-4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272
-2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288
-1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304
-2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320
-1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336
- 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352
- 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368
-1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384
-2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400
-2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416
-2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432
-3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448
-1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464
-2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480
- 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496
- 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512
- 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528
-1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544
-2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560
- 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576
-1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592
-1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608
- 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624
-1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640
-1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656
-1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672
- 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688
-2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704
- 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720
-2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736
-3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752
-2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768
-1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784
-6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800
-1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816
-2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832
-1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848
- 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864
- 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880
-3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896
-3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912
-1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928
-1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944
-1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960
-1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976
- 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992
- 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008
-2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024
- 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040
-3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056
-2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072
- 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088
-1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104
-2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120
- 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136
-1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152
- 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168
-4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184
-2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200
-1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216
- 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232
-1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248
-2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264
- 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280
-6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296
-1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312
-1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328
-2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344
-3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360
- 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376
-3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392
-1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408
- 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424
-1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440
- 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456
-3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472
- 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488
-2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504
- 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520
-4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536
-2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552
-1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568
-1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584
-1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600
- 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616
-1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632
-3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648
-1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664
-3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680
- 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696
- 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712
- 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728
-2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744
-1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760
- 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776
-1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792
- 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808
-1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824
- 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840
- 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856
- 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872
-1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888
-1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904
-2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920
-4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936
- 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952
-1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968
- 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984
-1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000
-3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016
-1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032
-2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048
-2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064
-1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080
-1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096
-2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112
- 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128
-2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144
-1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160
-1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176
-1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192
-1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208
-3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224
-2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240
-2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256
- 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272
-3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288
-3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304
-1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320
-2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336
-1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352
-2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512
-#Everything below is of no interest for detection purpose
-2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, # 4384
-6199,6200,6201,6202,6203,6204,6205,4670,6206,6207,6208,6209,6210,6211,6212,6213, # 4400
-6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229, # 4416
-6230,6231,6232,6233,6234,6235,6236,6237,3187,6238,6239,3969,6240,6241,6242,6243, # 4432
-6244,4671,6245,6246,4672,6247,6248,4133,6249,6250,4364,6251,2923,2556,2613,4673, # 4448
-4365,3970,6252,6253,6254,6255,4674,6256,6257,6258,2768,2353,4366,4675,4676,3188, # 4464
-4367,3463,6259,4134,4677,4678,6260,2267,6261,3842,3332,4368,3543,6262,6263,6264, # 4480
-3013,1954,1928,4135,4679,6265,6266,2478,3091,6267,4680,4369,6268,6269,1699,6270, # 4496
-3544,4136,4681,6271,4137,6272,4370,2804,6273,6274,2593,3971,3972,4682,6275,2236, # 4512
-4683,6276,6277,4684,6278,6279,4138,3973,4685,6280,6281,3258,6282,6283,6284,6285, # 4528
-3974,4686,2841,3975,6286,6287,3545,6288,6289,4139,4687,4140,6290,4141,6291,4142, # 4544
-6292,6293,3333,6294,6295,6296,4371,6297,3399,6298,6299,4372,3976,6300,6301,6302, # 4560
-4373,6303,6304,3843,3731,6305,4688,4374,6306,6307,3259,2294,6308,3732,2530,4143, # 4576
-6309,4689,6310,6311,6312,3048,6313,6314,4690,3733,2237,6315,6316,2282,3334,6317, # 4592
-6318,3844,6319,6320,4691,6321,3400,4692,6322,4693,6323,3049,6324,4375,6325,3977, # 4608
-6326,6327,6328,3546,6329,4694,3335,6330,4695,4696,6331,6332,6333,6334,4376,3978, # 4624
-6335,4697,3979,4144,6336,3980,4698,6337,6338,6339,6340,6341,4699,4700,4701,6342, # 4640
-6343,4702,6344,6345,4703,6346,6347,4704,6348,4705,4706,3135,6349,4707,6350,4708, # 4656
-6351,4377,6352,4709,3734,4145,6353,2506,4710,3189,6354,3050,4711,3981,6355,3547, # 4672
-3014,4146,4378,3735,2651,3845,3260,3136,2224,1986,6356,3401,6357,4712,2594,3627, # 4688
-3137,2573,3736,3982,4713,3628,4714,4715,2682,3629,4716,6358,3630,4379,3631,6359, # 4704
-6360,6361,3983,6362,6363,6364,6365,4147,3846,4717,6366,6367,3737,2842,6368,4718, # 4720
-2628,6369,3261,6370,2386,6371,6372,3738,3984,4719,3464,4720,3402,6373,2924,3336, # 4736
-4148,2866,6374,2805,3262,4380,2704,2069,2531,3138,2806,2984,6375,2769,6376,4721, # 4752
-4722,3403,6377,6378,3548,6379,6380,2705,3092,1979,4149,2629,3337,2889,6381,3338, # 4768
-4150,2557,3339,4381,6382,3190,3263,3739,6383,4151,4723,4152,2558,2574,3404,3191, # 4784
-6384,6385,4153,6386,4724,4382,6387,6388,4383,6389,6390,4154,6391,4725,3985,6392, # 4800
-3847,4155,6393,6394,6395,6396,6397,3465,6398,4384,6399,6400,6401,6402,6403,6404, # 4816
-4156,6405,6406,6407,6408,2123,6409,6410,2326,3192,4726,6411,6412,6413,6414,4385, # 4832
-4157,6415,6416,4158,6417,3093,3848,6418,3986,6419,6420,3849,6421,6422,6423,4159, # 4848
-6424,6425,4160,6426,3740,6427,6428,6429,6430,3987,6431,4727,6432,2238,6433,6434, # 4864
-4386,3988,6435,6436,3632,6437,6438,2843,6439,6440,6441,6442,3633,6443,2958,6444, # 4880
-6445,3466,6446,2364,4387,3850,6447,4388,2959,3340,6448,3851,6449,4728,6450,6451, # 4896
-3264,4729,6452,3193,6453,4389,4390,2706,3341,4730,6454,3139,6455,3194,6456,3051, # 4912
-2124,3852,1602,4391,4161,3853,1158,3854,4162,3989,4392,3990,4731,4732,4393,2040, # 4928
-4163,4394,3265,6457,2807,3467,3855,6458,6459,6460,3991,3468,4733,4734,6461,3140, # 4944
-2960,6462,4735,6463,6464,6465,6466,4736,4737,4738,4739,6467,6468,4164,2403,3856, # 4960
-6469,6470,2770,2844,6471,4740,6472,6473,6474,6475,6476,6477,6478,3195,6479,4741, # 4976
-4395,6480,2867,6481,4742,2808,6482,2493,4165,6483,6484,6485,6486,2295,4743,6487, # 4992
-6488,6489,3634,6490,6491,6492,6493,6494,6495,6496,2985,4744,6497,6498,4745,6499, # 5008
-6500,2925,3141,4166,6501,6502,4746,6503,6504,4747,6505,6506,6507,2890,6508,6509, # 5024
-6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,3469,4167,6520,6521,6522,4748, # 5040
-4396,3741,4397,4749,4398,3342,2125,4750,6523,4751,4752,4753,3052,6524,2961,4168, # 5056
-6525,4754,6526,4755,4399,2926,4169,6527,3857,6528,4400,4170,6529,4171,6530,6531, # 5072
-2595,6532,6533,6534,6535,3635,6536,6537,6538,6539,6540,6541,6542,4756,6543,6544, # 5088
-6545,6546,6547,6548,4401,6549,6550,6551,6552,4402,3405,4757,4403,6553,6554,6555, # 5104
-4172,3742,6556,6557,6558,3992,3636,6559,6560,3053,2726,6561,3549,4173,3054,4404, # 5120
-6562,6563,3993,4405,3266,3550,2809,4406,6564,6565,6566,4758,4759,6567,3743,6568, # 5136
-4760,3744,4761,3470,6569,6570,6571,4407,6572,3745,4174,6573,4175,2810,4176,3196, # 5152
-4762,6574,4177,6575,6576,2494,2891,3551,6577,6578,3471,6579,4408,6580,3015,3197, # 5168
-6581,3343,2532,3994,3858,6582,3094,3406,4409,6583,2892,4178,4763,4410,3016,4411, # 5184
-6584,3995,3142,3017,2683,6585,4179,6586,6587,4764,4412,6588,6589,4413,6590,2986, # 5200
-6591,2962,3552,6592,2963,3472,6593,6594,4180,4765,6595,6596,2225,3267,4414,6597, # 5216
-3407,3637,4766,6598,6599,3198,6600,4415,6601,3859,3199,6602,3473,4767,2811,4416, # 5232
-1856,3268,3200,2575,3996,3997,3201,4417,6603,3095,2927,6604,3143,6605,2268,6606, # 5248
-3998,3860,3096,2771,6607,6608,3638,2495,4768,6609,3861,6610,3269,2745,4769,4181, # 5264
-3553,6611,2845,3270,6612,6613,6614,3862,6615,6616,4770,4771,6617,3474,3999,4418, # 5280
-4419,6618,3639,3344,6619,4772,4182,6620,2126,6621,6622,6623,4420,4773,6624,3018, # 5296
-6625,4774,3554,6626,4183,2025,3746,6627,4184,2707,6628,4421,4422,3097,1775,4185, # 5312
-3555,6629,6630,2868,6631,6632,4423,6633,6634,4424,2414,2533,2928,6635,4186,2387, # 5328
-6636,4775,6637,4187,6638,1891,4425,3202,3203,6639,6640,4776,6641,3345,6642,6643, # 5344
-3640,6644,3475,3346,3641,4000,6645,3144,6646,3098,2812,4188,3642,3204,6647,3863, # 5360
-3476,6648,3864,6649,4426,4001,6650,6651,6652,2576,6653,4189,4777,6654,6655,6656, # 5376
-2846,6657,3477,3205,4002,6658,4003,6659,3347,2252,6660,6661,6662,4778,6663,6664, # 5392
-6665,6666,6667,6668,6669,4779,4780,2048,6670,3478,3099,6671,3556,3747,4004,6672, # 5408
-6673,6674,3145,4005,3748,6675,6676,6677,6678,6679,3408,6680,6681,6682,6683,3206, # 5424
-3207,6684,6685,4781,4427,6686,4782,4783,4784,6687,6688,6689,4190,6690,6691,3479, # 5440
-6692,2746,6693,4428,6694,6695,6696,6697,6698,6699,4785,6700,6701,3208,2727,6702, # 5456
-3146,6703,6704,3409,2196,6705,4429,6706,6707,6708,2534,1996,6709,6710,6711,2747, # 5472
-6712,6713,6714,4786,3643,6715,4430,4431,6716,3557,6717,4432,4433,6718,6719,6720, # 5488
-6721,3749,6722,4006,4787,6723,6724,3644,4788,4434,6725,6726,4789,2772,6727,6728, # 5504
-6729,6730,6731,2708,3865,2813,4435,6732,6733,4790,4791,3480,6734,6735,6736,6737, # 5520
-4436,3348,6738,3410,4007,6739,6740,4008,6741,6742,4792,3411,4191,6743,6744,6745, # 5536
-6746,6747,3866,6748,3750,6749,6750,6751,6752,6753,6754,6755,3867,6756,4009,6757, # 5552
-4793,4794,6758,2814,2987,6759,6760,6761,4437,6762,6763,6764,6765,3645,6766,6767, # 5568
-3481,4192,6768,3751,6769,6770,2174,6771,3868,3752,6772,6773,6774,4193,4795,4438, # 5584
-3558,4796,4439,6775,4797,6776,6777,4798,6778,4799,3559,4800,6779,6780,6781,3482, # 5600
-6782,2893,6783,6784,4194,4801,4010,6785,6786,4440,6787,4011,6788,6789,6790,6791, # 5616
-6792,6793,4802,6794,6795,6796,4012,6797,6798,6799,6800,3349,4803,3483,6801,4804, # 5632
-4195,6802,4013,6803,6804,4196,6805,4014,4015,6806,2847,3271,2848,6807,3484,6808, # 5648
-6809,6810,4441,6811,4442,4197,4443,3272,4805,6812,3412,4016,1579,6813,6814,4017, # 5664
-6815,3869,6816,2964,6817,4806,6818,6819,4018,3646,6820,6821,4807,4019,4020,6822, # 5680
-6823,3560,6824,6825,4021,4444,6826,4198,6827,6828,4445,6829,6830,4199,4808,6831, # 5696
-6832,6833,3870,3019,2458,6834,3753,3413,3350,6835,4809,3871,4810,3561,4446,6836, # 5712
-6837,4447,4811,4812,6838,2459,4448,6839,4449,6840,6841,4022,3872,6842,4813,4814, # 5728
-6843,6844,4815,4200,4201,4202,6845,4023,6846,6847,4450,3562,3873,6848,6849,4816, # 5744
-4817,6850,4451,4818,2139,6851,3563,6852,6853,3351,6854,6855,3352,4024,2709,3414, # 5760
-4203,4452,6856,4204,6857,6858,3874,3875,6859,6860,4819,6861,6862,6863,6864,4453, # 5776
-3647,6865,6866,4820,6867,6868,6869,6870,4454,6871,2869,6872,6873,4821,6874,3754, # 5792
-6875,4822,4205,6876,6877,6878,3648,4206,4455,6879,4823,6880,4824,3876,6881,3055, # 5808
-4207,6882,3415,6883,6884,6885,4208,4209,6886,4210,3353,6887,3354,3564,3209,3485, # 5824
-2652,6888,2728,6889,3210,3755,6890,4025,4456,6891,4825,6892,6893,6894,6895,4211, # 5840
-6896,6897,6898,4826,6899,6900,4212,6901,4827,6902,2773,3565,6903,4828,6904,6905, # 5856
-6906,6907,3649,3650,6908,2849,3566,6909,3567,3100,6910,6911,6912,6913,6914,6915, # 5872
-4026,6916,3355,4829,3056,4457,3756,6917,3651,6918,4213,3652,2870,6919,4458,6920, # 5888
-2438,6921,6922,3757,2774,4830,6923,3356,4831,4832,6924,4833,4459,3653,2507,6925, # 5904
-4834,2535,6926,6927,3273,4027,3147,6928,3568,6929,6930,6931,4460,6932,3877,4461, # 5920
-2729,3654,6933,6934,6935,6936,2175,4835,2630,4214,4028,4462,4836,4215,6937,3148, # 5936
-4216,4463,4837,4838,4217,6938,6939,2850,4839,6940,4464,6941,6942,6943,4840,6944, # 5952
-4218,3274,4465,6945,6946,2710,6947,4841,4466,6948,6949,2894,6950,6951,4842,6952, # 5968
-4219,3057,2871,6953,6954,6955,6956,4467,6957,2711,6958,6959,6960,3275,3101,4843, # 5984
-6961,3357,3569,6962,4844,6963,6964,4468,4845,3570,6965,3102,4846,3758,6966,4847, # 6000
-3878,4848,4849,4029,6967,2929,3879,4850,4851,6968,6969,1733,6970,4220,6971,6972, # 6016
-6973,6974,6975,6976,4852,6977,6978,6979,6980,6981,6982,3759,6983,6984,6985,3486, # 6032
-3487,6986,3488,3416,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,4853, # 6048
-6998,6999,4030,7000,7001,3211,7002,7003,4221,7004,7005,3571,4031,7006,3572,7007, # 6064
-2614,4854,2577,7008,7009,2965,3655,3656,4855,2775,3489,3880,4222,4856,3881,4032, # 6080
-3882,3657,2730,3490,4857,7010,3149,7011,4469,4858,2496,3491,4859,2283,7012,7013, # 6096
-7014,2365,4860,4470,7015,7016,3760,7017,7018,4223,1917,7019,7020,7021,4471,7022, # 6112
-2776,4472,7023,7024,7025,7026,4033,7027,3573,4224,4861,4034,4862,7028,7029,1929, # 6128
-3883,4035,7030,4473,3058,7031,2536,3761,3884,7032,4036,7033,2966,2895,1968,4474, # 6144
-3276,4225,3417,3492,4226,2105,7034,7035,1754,2596,3762,4227,4863,4475,3763,4864, # 6160
-3764,2615,2777,3103,3765,3658,3418,4865,2296,3766,2815,7036,7037,7038,3574,2872, # 6176
-3277,4476,7039,4037,4477,7040,7041,4038,7042,7043,7044,7045,7046,7047,2537,7048, # 6192
-7049,7050,7051,7052,7053,7054,4478,7055,7056,3767,3659,4228,3575,7057,7058,4229, # 6208
-7059,7060,7061,3660,7062,3212,7063,3885,4039,2460,7064,7065,7066,7067,7068,7069, # 6224
-7070,7071,7072,7073,7074,4866,3768,4867,7075,7076,7077,7078,4868,3358,3278,2653, # 6240
-7079,7080,4479,3886,7081,7082,4869,7083,7084,7085,7086,7087,7088,2538,7089,7090, # 6256
-7091,4040,3150,3769,4870,4041,2896,3359,4230,2930,7092,3279,7093,2967,4480,3213, # 6272
-4481,3661,7094,7095,7096,7097,7098,7099,7100,7101,7102,2461,3770,7103,7104,4231, # 6288
-3151,7105,7106,7107,4042,3662,7108,7109,4871,3663,4872,4043,3059,7110,7111,7112, # 6304
-3493,2988,7113,4873,7114,7115,7116,3771,4874,7117,7118,4232,4875,7119,3576,2336, # 6320
-4876,7120,4233,3419,4044,4877,4878,4482,4483,4879,4484,4234,7121,3772,4880,1045, # 6336
-3280,3664,4881,4882,7122,7123,7124,7125,4883,7126,2778,7127,4485,4486,7128,4884, # 6352
-3214,3887,7129,7130,3215,7131,4885,4045,7132,7133,4046,7134,7135,7136,7137,7138, # 6368
-7139,7140,7141,7142,7143,4235,7144,4886,7145,7146,7147,4887,7148,7149,7150,4487, # 6384
-4047,4488,7151,7152,4888,4048,2989,3888,7153,3665,7154,4049,7155,7156,7157,7158, # 6400
-7159,7160,2931,4889,4890,4489,7161,2631,3889,4236,2779,7162,7163,4891,7164,3060, # 6416
-7165,1672,4892,7166,4893,4237,3281,4894,7167,7168,3666,7169,3494,7170,7171,4050, # 6432
-7172,7173,3104,3360,3420,4490,4051,2684,4052,7174,4053,7175,7176,7177,2253,4054, # 6448
-7178,7179,4895,7180,3152,3890,3153,4491,3216,7181,7182,7183,2968,4238,4492,4055, # 6464
-7184,2990,7185,2479,7186,7187,4493,7188,7189,7190,7191,7192,4896,7193,4897,2969, # 6480
-4494,4898,7194,3495,7195,7196,4899,4495,7197,3105,2731,7198,4900,7199,7200,7201, # 6496
-4056,7202,3361,7203,7204,4496,4901,4902,7205,4497,7206,7207,2315,4903,7208,4904, # 6512
-7209,4905,2851,7210,7211,3577,7212,3578,4906,7213,4057,3667,4907,7214,4058,2354, # 6528
-3891,2376,3217,3773,7215,7216,7217,7218,7219,4498,7220,4908,3282,2685,7221,3496, # 6544
-4909,2632,3154,4910,7222,2337,7223,4911,7224,7225,7226,4912,4913,3283,4239,4499, # 6560
-7227,2816,7228,7229,7230,7231,7232,7233,7234,4914,4500,4501,7235,7236,7237,2686, # 6576
-7238,4915,7239,2897,4502,7240,4503,7241,2516,7242,4504,3362,3218,7243,7244,7245, # 6592
-4916,7246,7247,4505,3363,7248,7249,7250,7251,3774,4506,7252,7253,4917,7254,7255, # 6608
-3284,2991,4918,4919,3219,3892,4920,3106,3497,4921,7256,7257,7258,4922,7259,4923, # 6624
-3364,4507,4508,4059,7260,4240,3498,7261,7262,4924,7263,2992,3893,4060,3220,7264, # 6640
-7265,7266,7267,7268,7269,4509,3775,7270,2817,7271,4061,4925,4510,3776,7272,4241, # 6656
-4511,3285,7273,7274,3499,7275,7276,7277,4062,4512,4926,7278,3107,3894,7279,7280, # 6672
-4927,7281,4513,7282,7283,3668,7284,7285,4242,4514,4243,7286,2058,4515,4928,4929, # 6688
-4516,7287,3286,4244,7288,4517,7289,7290,7291,3669,7292,7293,4930,4931,4932,2355, # 6704
-4933,7294,2633,4518,7295,4245,7296,7297,4519,7298,7299,4520,4521,4934,7300,4246, # 6720
-4522,7301,7302,7303,3579,7304,4247,4935,7305,4936,7306,7307,7308,7309,3777,7310, # 6736
-4523,7311,7312,7313,4248,3580,7314,4524,3778,4249,7315,3581,7316,3287,7317,3221, # 6752
-7318,4937,7319,7320,7321,7322,7323,7324,4938,4939,7325,4525,7326,7327,7328,4063, # 6768
-7329,7330,4940,7331,7332,4941,7333,4526,7334,3500,2780,1741,4942,2026,1742,7335, # 6784
-7336,3582,4527,2388,7337,7338,7339,4528,7340,4250,4943,7341,7342,7343,4944,7344, # 6800
-7345,7346,3020,7347,4945,7348,7349,7350,7351,3895,7352,3896,4064,3897,7353,7354, # 6816
-7355,4251,7356,7357,3898,7358,3779,7359,3780,3288,7360,7361,4529,7362,4946,4530, # 6832
-2027,7363,3899,4531,4947,3222,3583,7364,4948,7365,7366,7367,7368,4949,3501,4950, # 6848
-3781,4951,4532,7369,2517,4952,4252,4953,3155,7370,4954,4955,4253,2518,4533,7371, # 6864
-7372,2712,4254,7373,7374,7375,3670,4956,3671,7376,2389,3502,4065,7377,2338,7378, # 6880
-7379,7380,7381,3061,7382,4957,7383,7384,7385,7386,4958,4534,7387,7388,2993,7389, # 6896
-3062,7390,4959,7391,7392,7393,4960,3108,4961,7394,4535,7395,4962,3421,4536,7396, # 6912
-4963,7397,4964,1857,7398,4965,7399,7400,2176,3584,4966,7401,7402,3422,4537,3900, # 6928
-3585,7403,3782,7404,2852,7405,7406,7407,4538,3783,2654,3423,4967,4539,7408,3784, # 6944
-3586,2853,4540,4541,7409,3901,7410,3902,7411,7412,3785,3109,2327,3903,7413,7414, # 6960
-2970,4066,2932,7415,7416,7417,3904,3672,3424,7418,4542,4543,4544,7419,4968,7420, # 6976
-7421,4255,7422,7423,7424,7425,7426,4067,7427,3673,3365,4545,7428,3110,2559,3674, # 6992
-7429,7430,3156,7431,7432,3503,7433,3425,4546,7434,3063,2873,7435,3223,4969,4547, # 7008
-4548,2898,4256,4068,7436,4069,3587,3786,2933,3787,4257,4970,4971,3788,7437,4972, # 7024
-3064,7438,4549,7439,7440,7441,7442,7443,4973,3905,7444,2874,7445,7446,7447,7448, # 7040
-3021,7449,4550,3906,3588,4974,7450,7451,3789,3675,7452,2578,7453,4070,7454,7455, # 7056
-7456,4258,3676,7457,4975,7458,4976,4259,3790,3504,2634,4977,3677,4551,4260,7459, # 7072
-7460,7461,7462,3907,4261,4978,7463,7464,7465,7466,4979,4980,7467,7468,2213,4262, # 7088
-7469,7470,7471,3678,4981,7472,2439,7473,4263,3224,3289,7474,3908,2415,4982,7475, # 7104
-4264,7476,4983,2655,7477,7478,2732,4552,2854,2875,7479,7480,4265,7481,4553,4984, # 7120
-7482,7483,4266,7484,3679,3366,3680,2818,2781,2782,3367,3589,4554,3065,7485,4071, # 7136
-2899,7486,7487,3157,2462,4072,4555,4073,4985,4986,3111,4267,2687,3368,4556,4074, # 7152
-3791,4268,7488,3909,2783,7489,2656,1962,3158,4557,4987,1963,3159,3160,7490,3112, # 7168
-4988,4989,3022,4990,4991,3792,2855,7491,7492,2971,4558,7493,7494,4992,7495,7496, # 7184
-7497,7498,4993,7499,3426,4559,4994,7500,3681,4560,4269,4270,3910,7501,4075,4995, # 7200
-4271,7502,7503,4076,7504,4996,7505,3225,4997,4272,4077,2819,3023,7506,7507,2733, # 7216
-4561,7508,4562,7509,3369,3793,7510,3590,2508,7511,7512,4273,3113,2994,2616,7513, # 7232
-7514,7515,7516,7517,7518,2820,3911,4078,2748,7519,7520,4563,4998,7521,7522,7523, # 7248
-7524,4999,4274,7525,4564,3682,2239,4079,4565,7526,7527,7528,7529,5000,7530,7531, # 7264
-5001,4275,3794,7532,7533,7534,3066,5002,4566,3161,7535,7536,4080,7537,3162,7538, # 7280
-7539,4567,7540,7541,7542,7543,7544,7545,5003,7546,4568,7547,7548,7549,7550,7551, # 7296
-7552,7553,7554,7555,7556,5004,7557,7558,7559,5005,7560,3795,7561,4569,7562,7563, # 7312
-7564,2821,3796,4276,4277,4081,7565,2876,7566,5006,7567,7568,2900,7569,3797,3912, # 7328
-7570,7571,7572,4278,7573,7574,7575,5007,7576,7577,5008,7578,7579,4279,2934,7580, # 7344
-7581,5009,7582,4570,7583,4280,7584,7585,7586,4571,4572,3913,7587,4573,3505,7588, # 7360
-5010,7589,7590,7591,7592,3798,4574,7593,7594,5011,7595,4281,7596,7597,7598,4282, # 7376
-5012,7599,7600,5013,3163,7601,5014,7602,3914,7603,7604,2734,4575,4576,4577,7605, # 7392
-7606,7607,7608,7609,3506,5015,4578,7610,4082,7611,2822,2901,2579,3683,3024,4579, # 7408
-3507,7612,4580,7613,3226,3799,5016,7614,7615,7616,7617,7618,7619,7620,2995,3290, # 7424
-7621,4083,7622,5017,7623,7624,7625,7626,7627,4581,3915,7628,3291,7629,5018,7630, # 7440
-7631,7632,7633,4084,7634,7635,3427,3800,7636,7637,4582,7638,5019,4583,5020,7639, # 7456
-3916,7640,3801,5021,4584,4283,7641,7642,3428,3591,2269,7643,2617,7644,4585,3592, # 7472
-7645,4586,2902,7646,7647,3227,5022,7648,4587,7649,4284,7650,7651,7652,4588,2284, # 7488
-7653,5023,7654,7655,7656,4589,5024,3802,7657,7658,5025,3508,4590,7659,7660,7661, # 7504
-1969,5026,7662,7663,3684,1821,2688,7664,2028,2509,4285,7665,2823,1841,7666,2689, # 7520
-3114,7667,3917,4085,2160,5027,5028,2972,7668,5029,7669,7670,7671,3593,4086,7672, # 7536
-4591,4087,5030,3803,7673,7674,7675,7676,7677,7678,7679,4286,2366,4592,4593,3067, # 7552
-2328,7680,7681,4594,3594,3918,2029,4287,7682,5031,3919,3370,4288,4595,2856,7683, # 7568
-3509,7684,7685,5032,5033,7686,7687,3804,2784,7688,7689,7690,7691,3371,7692,7693, # 7584
-2877,5034,7694,7695,3920,4289,4088,7696,7697,7698,5035,7699,5036,4290,5037,5038, # 7600
-5039,7700,7701,7702,5040,5041,3228,7703,1760,7704,5042,3229,4596,2106,4089,7705, # 7616
-4597,2824,5043,2107,3372,7706,4291,4090,5044,7707,4091,7708,5045,3025,3805,4598, # 7632
-4292,4293,4294,3373,7709,4599,7710,5046,7711,7712,5047,5048,3806,7713,7714,7715, # 7648
-5049,7716,7717,7718,7719,4600,5050,7720,7721,7722,5051,7723,4295,3429,7724,7725, # 7664
-7726,7727,3921,7728,3292,5052,4092,7729,7730,7731,7732,7733,7734,7735,5053,5054, # 7680
-7736,7737,7738,7739,3922,3685,7740,7741,7742,7743,2635,5055,7744,5056,4601,7745, # 7696
-7746,2560,7747,7748,7749,7750,3923,7751,7752,7753,7754,7755,4296,2903,7756,7757, # 7712
-7758,7759,7760,3924,7761,5057,4297,7762,7763,5058,4298,7764,4093,7765,7766,5059, # 7728
-3925,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,3595,7777,4299,5060,4094, # 7744
-7778,3293,5061,7779,7780,4300,7781,7782,4602,7783,3596,7784,7785,3430,2367,7786, # 7760
-3164,5062,5063,4301,7787,7788,4095,5064,5065,7789,3374,3115,7790,7791,7792,7793, # 7776
-7794,7795,7796,3597,4603,7797,7798,3686,3116,3807,5066,7799,7800,5067,7801,7802, # 7792
-4604,4302,5068,4303,4096,7803,7804,3294,7805,7806,5069,4605,2690,7807,3026,7808, # 7808
-7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824, # 7824
-7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, # 7840
-7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856, # 7856
-7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872, # 7872
-7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888, # 7888
-7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904, # 7904
-7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920, # 7920
-7921,7922,7923,7924,3926,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, # 7936
-7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, # 7952
-7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, # 7968
-7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, # 7984
-7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, # 8000
-8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, # 8016
-8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, # 8032
-8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, # 8048
-8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, # 8064
-8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, # 8080
-8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, # 8096
-8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, # 8112
-8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, # 8128
-8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, # 8144
-8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, # 8160
-8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, # 8176
-8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, # 8192
-8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, # 8208
-8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, # 8224
-8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, # 8240
-8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, # 8256
-8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271) # 8272
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jpcntx.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jpcntx.py
deleted file mode 100644
index 59aeb6a8..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/jpcntx.py
+++ /dev/null
@@ -1,227 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .compat import wrap_ord
-
-NUM_OF_CATEGORY = 6
-DONT_KNOW = -1
-ENOUGH_REL_THRESHOLD = 100
-MAX_REL_THRESHOLD = 1000
-MINIMUM_DATA_THRESHOLD = 4
-
-# This is hiragana 2-char sequence table, the number in each cell represents its frequency category
-jp2CharContext = (
-(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1),
-(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4),
-(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2),
-(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4),
-(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
-(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4),
-(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
-(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3),
-(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
-(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4),
-(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4),
-(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3),
-(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3),
-(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3),
-(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4),
-(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3),
-(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4),
-(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3),
-(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5),
-(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3),
-(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5),
-(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4),
-(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4),
-(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3),
-(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3),
-(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3),
-(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5),
-(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4),
-(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5),
-(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3),
-(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4),
-(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4),
-(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4),
-(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1),
-(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0),
-(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3),
-(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0),
-(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3),
-(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3),
-(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5),
-(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4),
-(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5),
-(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3),
-(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3),
-(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3),
-(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3),
-(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4),
-(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4),
-(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2),
-(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3),
-(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3),
-(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3),
-(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3),
-(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4),
-(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3),
-(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4),
-(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3),
-(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3),
-(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4),
-(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4),
-(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3),
-(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4),
-(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4),
-(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3),
-(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4),
-(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4),
-(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4),
-(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3),
-(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2),
-(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2),
-(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3),
-(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3),
-(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5),
-(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3),
-(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4),
-(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4),
-(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4),
-(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
-(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3),
-(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1),
-(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2),
-(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3),
-(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1),
-)
-
-class JapaneseContextAnalysis:
- def __init__(self):
- self.reset()
-
- def reset(self):
- self._mTotalRel = 0 # total sequence received
- # category counters, each interger counts sequence in its category
- self._mRelSample = [0] * NUM_OF_CATEGORY
- # if last byte in current buffer is not the last byte of a character,
- # we need to know how many bytes to skip in next buffer
- self._mNeedToSkipCharNum = 0
- self._mLastCharOrder = -1 # The order of previous char
- # If this flag is set to True, detection is done and conclusion has
- # been made
- self._mDone = False
-
- def feed(self, aBuf, aLen):
- if self._mDone:
- return
-
- # The buffer we got is byte oriented, and a character may span in more than one
- # buffers. In case the last one or two byte in last buffer is not
- # complete, we record how many byte needed to complete that character
- # and skip these bytes here. We can choose to record those bytes as
- # well and analyse the character once it is complete, but since a
- # character will not make much difference, by simply skipping
- # this character will simply our logic and improve performance.
- i = self._mNeedToSkipCharNum
- while i < aLen:
- order, charLen = self.get_order(aBuf[i:i + 2])
- i += charLen
- if i > aLen:
- self._mNeedToSkipCharNum = i - aLen
- self._mLastCharOrder = -1
- else:
- if (order != -1) and (self._mLastCharOrder != -1):
- self._mTotalRel += 1
- if self._mTotalRel > MAX_REL_THRESHOLD:
- self._mDone = True
- break
- self._mRelSample[jp2CharContext[self._mLastCharOrder][order]] += 1
- self._mLastCharOrder = order
-
- def got_enough_data(self):
- return self._mTotalRel > ENOUGH_REL_THRESHOLD
-
- def get_confidence(self):
- # This is just one way to calculate confidence. It works well for me.
- if self._mTotalRel > MINIMUM_DATA_THRESHOLD:
- return (self._mTotalRel - self._mRelSample[0]) / self._mTotalRel
- else:
- return DONT_KNOW
-
- def get_order(self, aBuf):
- return -1, 1
-
-class SJISContextAnalysis(JapaneseContextAnalysis):
- def __init__(self):
- self.charset_name = "SHIFT_JIS"
-
- def get_charset_name(self):
- return self.charset_name
-
- def get_order(self, aBuf):
- if not aBuf:
- return -1, 1
- # find out current char's byte length
- first_char = wrap_ord(aBuf[0])
- if ((0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC)):
- charLen = 2
- if (first_char == 0x87) or (0xFA <= first_char <= 0xFC):
- self.charset_name = "CP932"
- else:
- charLen = 1
-
- # return its order if it is hiragana
- if len(aBuf) > 1:
- second_char = wrap_ord(aBuf[1])
- if (first_char == 202) and (0x9F <= second_char <= 0xF1):
- return second_char - 0x9F, charLen
-
- return -1, charLen
-
-class EUCJPContextAnalysis(JapaneseContextAnalysis):
- def get_order(self, aBuf):
- if not aBuf:
- return -1, 1
- # find out current char's byte length
- first_char = wrap_ord(aBuf[0])
- if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE):
- charLen = 2
- elif first_char == 0x8F:
- charLen = 3
- else:
- charLen = 1
-
- # return its order if it is hiragana
- if len(aBuf) > 1:
- second_char = wrap_ord(aBuf[1])
- if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3):
- return second_char - 0xA1, charLen
-
- return -1, charLen
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langbulgarianmodel.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langbulgarianmodel.py
deleted file mode 100644
index e5788fc6..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langbulgarianmodel.py
+++ /dev/null
@@ -1,229 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# 255: Control characters that usually does not exist in any text
-# 254: Carriage/Return
-# 253: symbol (punctuation) that does not belong to word
-# 252: 0 - 9
-
-# Character Mapping Table:
-# this table is modified base on win1251BulgarianCharToOrderMap, so
-# only number <64 is sure valid
-
-Latin5_BulgarianCharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40
-110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50
-253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60
-116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70
-194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80
-210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90
- 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0
- 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0
- 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0
- 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0
- 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0
- 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0
-)
-
-win1251BulgarianCharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40
-110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50
-253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60
-116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70
-206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80
-221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90
- 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0
- 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0
- 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0
- 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0
- 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0
- 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0
-)
-
-# Model Table:
-# total sequences: 100%
-# first 512 sequences: 96.9392%
-# first 1024 sequences:3.0618%
-# rest sequences: 0.2992%
-# negative sequences: 0.0020%
-BulgarianLangModel = (
-0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2,
-3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1,
-0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0,
-0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0,
-0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0,
-1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0,
-0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0,
-0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3,
-2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,
-3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,
-3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2,
-1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0,
-3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1,
-1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0,
-2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2,
-2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0,
-3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2,
-1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0,
-2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2,
-2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,
-3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2,
-1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0,
-2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2,
-2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0,
-2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2,
-1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0,
-2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2,
-1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0,
-3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2,
-1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0,
-3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1,
-1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0,
-2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1,
-1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0,
-2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2,
-1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,
-2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1,
-1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0,
-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,
-1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2,
-1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1,
-2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2,
-1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,
-2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2,
-1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
-1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1,
-0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2,
-1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
-2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1,
-1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,
-1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1,
-0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
-1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1,
-0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,
-0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
-2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0,
-1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,
-0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
-0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,
-1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1,
-1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,
-1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-)
-
-Latin5BulgarianModel = {
- 'charToOrderMap': Latin5_BulgarianCharToOrderMap,
- 'precedenceMatrix': BulgarianLangModel,
- 'mTypicalPositiveRatio': 0.969392,
- 'keepEnglishLetter': False,
- 'charsetName': "ISO-8859-5"
-}
-
-Win1251BulgarianModel = {
- 'charToOrderMap': win1251BulgarianCharToOrderMap,
- 'precedenceMatrix': BulgarianLangModel,
- 'mTypicalPositiveRatio': 0.969392,
- 'keepEnglishLetter': False,
- 'charsetName': "windows-1251"
-}
-
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langcyrillicmodel.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langcyrillicmodel.py
deleted file mode 100644
index a86f54bd..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langcyrillicmodel.py
+++ /dev/null
@@ -1,329 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# KOI8-R language model
-# Character Mapping Table:
-KOI8R_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40
-155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50
-253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60
- 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80
-207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90
-223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0
-238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0
- 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0
- 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0
- 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0
- 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0
-)
-
-win1251_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40
-155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50
-253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60
- 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,
-207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,
-223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,
-239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253,
- 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35,
- 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43,
- 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15,
- 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16,
-)
-
-latin5_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40
-155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50
-253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60
- 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,
-207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,
-223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,
- 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35,
- 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43,
- 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15,
- 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16,
-239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255,
-)
-
-macCyrillic_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40
-155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50
-253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60
- 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70
- 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35,
- 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43,
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,
-207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,
-223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,
-239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16,
- 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15,
- 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255,
-)
-
-IBM855_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40
-155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50
-253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60
- 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70
-191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205,
-206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70,
- 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219,
-220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229,
-230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243,
- 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248,
- 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249,
-250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255,
-)
-
-IBM866_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40
-155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50
-253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60
- 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70
- 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35,
- 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43,
- 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15,
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,
-207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,
-223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,
- 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16,
-239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255,
-)
-
-# Model Table:
-# total sequences: 100%
-# first 512 sequences: 97.6601%
-# first 1024 sequences: 2.3389%
-# rest sequences: 0.1237%
-# negative sequences: 0.0009%
-RussianLangModel = (
-0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2,
-3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1,
-0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1,
-0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
-3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0,
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1,
-1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
-2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1,
-1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0,
-2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1,
-1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,
-3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1,
-1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0,
-2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2,
-1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1,
-1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1,
-1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,
-2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1,
-1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0,
-3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2,
-1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,
-2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1,
-1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0,
-2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0,
-0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1,
-1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0,
-1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1,
-1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0,
-3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1,
-2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1,
-3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1,
-1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,
-1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1,
-0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
-2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1,
-1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0,
-1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1,
-0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1,
-1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
-2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2,
-2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1,
-1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0,
-1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0,
-2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,
-1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,
-0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,
-2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1,
-1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1,
-1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,
-0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
-0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1,
-0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
-1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,
-0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,
-0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
-1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,
-0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,
-2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,
-0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
-)
-
-Koi8rModel = {
- 'charToOrderMap': KOI8R_CharToOrderMap,
- 'precedenceMatrix': RussianLangModel,
- 'mTypicalPositiveRatio': 0.976601,
- 'keepEnglishLetter': False,
- 'charsetName': "KOI8-R"
-}
-
-Win1251CyrillicModel = {
- 'charToOrderMap': win1251_CharToOrderMap,
- 'precedenceMatrix': RussianLangModel,
- 'mTypicalPositiveRatio': 0.976601,
- 'keepEnglishLetter': False,
- 'charsetName': "windows-1251"
-}
-
-Latin5CyrillicModel = {
- 'charToOrderMap': latin5_CharToOrderMap,
- 'precedenceMatrix': RussianLangModel,
- 'mTypicalPositiveRatio': 0.976601,
- 'keepEnglishLetter': False,
- 'charsetName': "ISO-8859-5"
-}
-
-MacCyrillicModel = {
- 'charToOrderMap': macCyrillic_CharToOrderMap,
- 'precedenceMatrix': RussianLangModel,
- 'mTypicalPositiveRatio': 0.976601,
- 'keepEnglishLetter': False,
- 'charsetName': "MacCyrillic"
-};
-
-Ibm866Model = {
- 'charToOrderMap': IBM866_CharToOrderMap,
- 'precedenceMatrix': RussianLangModel,
- 'mTypicalPositiveRatio': 0.976601,
- 'keepEnglishLetter': False,
- 'charsetName': "IBM866"
-}
-
-Ibm855Model = {
- 'charToOrderMap': IBM855_CharToOrderMap,
- 'precedenceMatrix': RussianLangModel,
- 'mTypicalPositiveRatio': 0.976601,
- 'keepEnglishLetter': False,
- 'charsetName': "IBM855"
-}
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langgreekmodel.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langgreekmodel.py
deleted file mode 100644
index ddb58376..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langgreekmodel.py
+++ /dev/null
@@ -1,225 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# 255: Control characters that usually does not exist in any text
-# 254: Carriage/Return
-# 253: symbol (punctuation) that does not belong to word
-# 252: 0 - 9
-
-# Character Mapping Table:
-Latin7_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40
- 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50
-253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60
- 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90
-253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0
-253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0
-110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0
- 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0
-124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0
- 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0
-)
-
-win1253_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40
- 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50
-253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60
- 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90
-253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0
-253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0
-110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0
- 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0
-124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0
- 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0
-)
-
-# Model Table:
-# total sequences: 100%
-# first 512 sequences: 98.2851%
-# first 1024 sequences:1.7001%
-# rest sequences: 0.0359%
-# negative sequences: 0.0148%
-GreekLangModel = (
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0,
-3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,
-0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0,
-2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0,
-0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0,
-2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0,
-2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0,
-0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0,
-2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0,
-0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0,
-3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0,
-3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0,
-2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0,
-2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0,
-0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0,
-0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0,
-0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2,
-0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,
-0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2,
-0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0,
-0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2,
-0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2,
-0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,
-0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2,
-0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0,
-0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0,
-0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0,
-0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,
-0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0,
-0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2,
-0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0,
-0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2,
-0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0,
-0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2,
-0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,
-0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2,
-0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,
-0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1,
-0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,
-0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2,
-0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
-0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2,
-0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2,
-0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,
-0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,
-0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,
-0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0,
-0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0,
-0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-)
-
-Latin7GreekModel = {
- 'charToOrderMap': Latin7_CharToOrderMap,
- 'precedenceMatrix': GreekLangModel,
- 'mTypicalPositiveRatio': 0.982851,
- 'keepEnglishLetter': False,
- 'charsetName': "ISO-8859-7"
-}
-
-Win1253GreekModel = {
- 'charToOrderMap': win1253_CharToOrderMap,
- 'precedenceMatrix': GreekLangModel,
- 'mTypicalPositiveRatio': 0.982851,
- 'keepEnglishLetter': False,
- 'charsetName': "windows-1253"
-}
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhebrewmodel.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhebrewmodel.py
deleted file mode 100644
index 75f2bc7f..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhebrewmodel.py
+++ /dev/null
@@ -1,201 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Simon Montagu
-# Portions created by the Initial Developer are Copyright (C) 2005
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-# Shoshannah Forbes - original C code (?)
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# 255: Control characters that usually does not exist in any text
-# 254: Carriage/Return
-# 253: symbol (punctuation) that does not belong to word
-# 252: 0 - 9
-
-# Windows-1255 language model
-# Character Mapping Table:
-win1255_CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40
- 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50
-253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60
- 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70
-124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214,
-215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221,
- 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227,
-106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234,
- 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237,
-238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250,
- 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23,
- 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253,
-)
-
-# Model Table:
-# total sequences: 100%
-# first 512 sequences: 98.4004%
-# first 1024 sequences: 1.5981%
-# rest sequences: 0.087%
-# negative sequences: 0.0015%
-HebrewLangModel = (
-0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0,
-3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,
-1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,
-1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3,
-1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2,
-1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2,
-1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2,
-0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2,
-0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2,
-1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,
-3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2,
-0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1,
-0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0,
-0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,
-0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2,
-0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,
-3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2,
-0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2,
-0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2,
-0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2,
-0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1,
-0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2,
-0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0,
-3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2,
-0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2,
-0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2,
-0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0,
-1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2,
-0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,
-3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0,
-0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3,
-0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,
-0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
-0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0,
-0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,
-0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0,
-2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0,
-0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1,
-0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,
-0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,
-0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1,
-1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1,
-0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1,
-2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1,
-1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1,
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1,
-2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1,
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1,
-1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1,
-2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,
-0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1,
-1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1,
-0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0,
-)
-
-Win1255HebrewModel = {
- 'charToOrderMap': win1255_CharToOrderMap,
- 'precedenceMatrix': HebrewLangModel,
- 'mTypicalPositiveRatio': 0.984004,
- 'keepEnglishLetter': False,
- 'charsetName': "windows-1255"
-}
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhungarianmodel.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhungarianmodel.py
deleted file mode 100644
index 49d2f0fe..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langhungarianmodel.py
+++ /dev/null
@@ -1,225 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# 255: Control characters that usually does not exist in any text
-# 254: Carriage/Return
-# 253: symbol (punctuation) that does not belong to word
-# 252: 0 - 9
-
-# Character Mapping Table:
-Latin2_HungarianCharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47,
- 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253,
-253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8,
- 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253,
-159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,
-175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,
-191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205,
- 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,
-221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231,
-232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241,
- 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85,
-245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253,
-)
-
-win1250HungarianCharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47,
- 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253,
-253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8,
- 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253,
-161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
-177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190,
-191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205,
- 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,
-221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231,
-232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241,
- 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87,
-245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253,
-)
-
-# Model Table:
-# total sequences: 100%
-# first 512 sequences: 94.7368%
-# first 1024 sequences:5.2623%
-# rest sequences: 0.8894%
-# negative sequences: 0.0009%
-HungarianLangModel = (
-0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
-3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2,
-3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,
-3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3,
-0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
-3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2,
-0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0,
-3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,
-3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,
-3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2,
-0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
-2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1,
-0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
-3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0,
-1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0,
-1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0,
-1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1,
-3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1,
-2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1,
-2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1,
-2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1,
-2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0,
-2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1,
-3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1,
-2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1,
-2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1,
-2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,
-1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1,
-1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1,
-3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0,
-1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1,
-1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1,
-2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1,
-2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0,
-2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1,
-3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1,
-2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1,
-1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0,
-1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0,
-2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1,
-2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,
-1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0,
-1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1,
-2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0,
-1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0,
-1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0,
-2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1,
-2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1,
-2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1,
-1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1,
-1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1,
-1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0,
-0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0,
-2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1,
-2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1,
-1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1,
-2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,
-1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0,
-1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0,
-2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0,
-2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1,
-2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0,
-1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,
-2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0,
-0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
-1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,
-0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,
-1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
-0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
-2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
-0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
-)
-
-Latin2HungarianModel = {
- 'charToOrderMap': Latin2_HungarianCharToOrderMap,
- 'precedenceMatrix': HungarianLangModel,
- 'mTypicalPositiveRatio': 0.947368,
- 'keepEnglishLetter': True,
- 'charsetName': "ISO-8859-2"
-}
-
-Win1250HungarianModel = {
- 'charToOrderMap': win1250HungarianCharToOrderMap,
- 'precedenceMatrix': HungarianLangModel,
- 'mTypicalPositiveRatio': 0.947368,
- 'keepEnglishLetter': True,
- 'charsetName': "windows-1250"
-}
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langthaimodel.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langthaimodel.py
deleted file mode 100644
index 0508b1b1..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/langthaimodel.py
+++ /dev/null
@@ -1,200 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Communicator client code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-# 255: Control characters that usually does not exist in any text
-# 254: Carriage/Return
-# 253: symbol (punctuation) that does not belong to word
-# 252: 0 - 9
-
-# The following result for thai was collected from a limited sample (1M).
-
-# Character Mapping Table:
-TIS620CharToOrderMap = (
-255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20
-252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30
-253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40
-188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50
-253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60
- 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70
-209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222,
-223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235,
-236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57,
- 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54,
- 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63,
- 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244,
- 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247,
- 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253,
-)
-
-# Model Table:
-# total sequences: 100%
-# first 512 sequences: 92.6386%
-# first 1024 sequences:7.3177%
-# rest sequences: 1.0230%
-# negative sequences: 0.0436%
-ThaiLangModel = (
-0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3,
-0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2,
-3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3,
-0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1,
-3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2,
-3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1,
-3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2,
-3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1,
-3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1,
-3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,
-3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1,
-2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1,
-3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1,
-0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,
-3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1,
-0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,
-3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2,
-1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0,
-3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3,
-3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0,
-1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2,
-0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,
-2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3,
-0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0,
-3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1,
-2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,
-3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2,
-0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2,
-3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
-3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0,
-2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
-3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1,
-2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1,
-3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1,
-3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0,
-3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1,
-3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1,
-3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1,
-1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2,
-0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
-3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3,
-0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,
-3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0,
-3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1,
-1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0,
-3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1,
-3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2,
-0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0,
-0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0,
-1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1,
-1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1,
-3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1,
-0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
-0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0,
-0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,
-3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0,
-3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0,
-0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1,
-0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0,
-0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1,
-0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,
-0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0,
-0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1,
-0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,
-3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0,
-0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0,
-0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,
-3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1,
-2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,
-0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0,
-3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0,
-0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,
-2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0,
-1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3,
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,
-1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,
-1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,
-1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-)
-
-TIS620ThaiModel = {
- 'charToOrderMap': TIS620CharToOrderMap,
- 'precedenceMatrix': ThaiLangModel,
- 'mTypicalPositiveRatio': 0.926386,
- 'keepEnglishLetter': False,
- 'charsetName': "TIS-620"
-}
-
-# flake8: noqa
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/latin1prober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/latin1prober.py
deleted file mode 100644
index eef35735..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/latin1prober.py
+++ /dev/null
@@ -1,139 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .charsetprober import CharSetProber
-from .constants import eNotMe
-from .compat import wrap_ord
-
-FREQ_CAT_NUM = 4
-
-UDF = 0 # undefined
-OTH = 1 # other
-ASC = 2 # ascii capital letter
-ASS = 3 # ascii small letter
-ACV = 4 # accent capital vowel
-ACO = 5 # accent capital other
-ASV = 6 # accent small vowel
-ASO = 7 # accent small other
-CLASS_NUM = 8 # total classes
-
-Latin1_CharToClass = (
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F
- OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47
- ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F
- ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57
- ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F
- OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67
- ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F
- ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77
- ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F
- OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87
- OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F
- UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97
- OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7
- OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF
- ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7
- ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF
- ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7
- ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF
- ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7
- ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF
- ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7
- ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF
-)
-
-# 0 : illegal
-# 1 : very unlikely
-# 2 : normal
-# 3 : very likely
-Latin1ClassModel = (
- # UDF OTH ASC ASS ACV ACO ASV ASO
- 0, 0, 0, 0, 0, 0, 0, 0, # UDF
- 0, 3, 3, 3, 3, 3, 3, 3, # OTH
- 0, 3, 3, 3, 3, 3, 3, 3, # ASC
- 0, 3, 3, 3, 1, 1, 3, 3, # ASS
- 0, 3, 3, 3, 1, 2, 1, 2, # ACV
- 0, 3, 3, 3, 3, 3, 3, 3, # ACO
- 0, 3, 1, 3, 1, 1, 1, 3, # ASV
- 0, 3, 1, 3, 1, 1, 3, 3, # ASO
-)
-
-
-class Latin1Prober(CharSetProber):
- def __init__(self):
- CharSetProber.__init__(self)
- self.reset()
-
- def reset(self):
- self._mLastCharClass = OTH
- self._mFreqCounter = [0] * FREQ_CAT_NUM
- CharSetProber.reset(self)
-
- def get_charset_name(self):
- return "windows-1252"
-
- def feed(self, aBuf):
- aBuf = self.filter_with_english_letters(aBuf)
- for c in aBuf:
- charClass = Latin1_CharToClass[wrap_ord(c)]
- freq = Latin1ClassModel[(self._mLastCharClass * CLASS_NUM)
- + charClass]
- if freq == 0:
- self._mState = eNotMe
- break
- self._mFreqCounter[freq] += 1
- self._mLastCharClass = charClass
-
- return self.get_state()
-
- def get_confidence(self):
- if self.get_state() == eNotMe:
- return 0.01
-
- total = sum(self._mFreqCounter)
- if total < 0.01:
- confidence = 0.0
- else:
- confidence = ((self._mFreqCounter[3] - self._mFreqCounter[1] * 20.0)
- / total)
- if confidence < 0.0:
- confidence = 0.0
- # lower the confidence of latin1 so that other more accurate
- # detector can take priority.
- confidence = confidence * 0.73
- return confidence
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcharsetprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcharsetprober.py
deleted file mode 100644
index bb42f2fb..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcharsetprober.py
+++ /dev/null
@@ -1,86 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-# Proofpoint, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-import sys
-from . import constants
-from .charsetprober import CharSetProber
-
-
-class MultiByteCharSetProber(CharSetProber):
- def __init__(self):
- CharSetProber.__init__(self)
- self._mDistributionAnalyzer = None
- self._mCodingSM = None
- self._mLastChar = [0, 0]
-
- def reset(self):
- CharSetProber.reset(self)
- if self._mCodingSM:
- self._mCodingSM.reset()
- if self._mDistributionAnalyzer:
- self._mDistributionAnalyzer.reset()
- self._mLastChar = [0, 0]
-
- def get_charset_name(self):
- pass
-
- def feed(self, aBuf):
- aLen = len(aBuf)
- for i in range(0, aLen):
- codingState = self._mCodingSM.next_state(aBuf[i])
- if codingState == constants.eError:
- if constants._debug:
- sys.stderr.write(self.get_charset_name()
- + ' prober hit error at byte ' + str(i)
- + '\n')
- self._mState = constants.eNotMe
- break
- elif codingState == constants.eItsMe:
- self._mState = constants.eFoundIt
- break
- elif codingState == constants.eStart:
- charLen = self._mCodingSM.get_current_charlen()
- if i == 0:
- self._mLastChar[1] = aBuf[0]
- self._mDistributionAnalyzer.feed(self._mLastChar, charLen)
- else:
- self._mDistributionAnalyzer.feed(aBuf[i - 1:i + 1],
- charLen)
-
- self._mLastChar[0] = aBuf[aLen - 1]
-
- if self.get_state() == constants.eDetecting:
- if (self._mDistributionAnalyzer.got_enough_data() and
- (self.get_confidence() > constants.SHORTCUT_THRESHOLD)):
- self._mState = constants.eFoundIt
-
- return self.get_state()
-
- def get_confidence(self):
- return self._mDistributionAnalyzer.get_confidence()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcsgroupprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcsgroupprober.py
deleted file mode 100644
index 03c9dcf3..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcsgroupprober.py
+++ /dev/null
@@ -1,54 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-# Proofpoint, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .charsetgroupprober import CharSetGroupProber
-from .utf8prober import UTF8Prober
-from .sjisprober import SJISProber
-from .eucjpprober import EUCJPProber
-from .gb2312prober import GB2312Prober
-from .euckrprober import EUCKRProber
-from .cp949prober import CP949Prober
-from .big5prober import Big5Prober
-from .euctwprober import EUCTWProber
-
-
-class MBCSGroupProber(CharSetGroupProber):
- def __init__(self):
- CharSetGroupProber.__init__(self)
- self._mProbers = [
- UTF8Prober(),
- SJISProber(),
- EUCJPProber(),
- GB2312Prober(),
- EUCKRProber(),
- CP949Prober(),
- Big5Prober(),
- EUCTWProber()
- ]
- self.reset()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcssm.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcssm.py
deleted file mode 100644
index efe678ca..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/mbcssm.py
+++ /dev/null
@@ -1,572 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .constants import eStart, eError, eItsMe
-
-# BIG5
-
-BIG5_cls = (
- 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value
- 1,1,1,1,1,1,0,0, # 08 - 0f
- 1,1,1,1,1,1,1,1, # 10 - 17
- 1,1,1,0,1,1,1,1, # 18 - 1f
- 1,1,1,1,1,1,1,1, # 20 - 27
- 1,1,1,1,1,1,1,1, # 28 - 2f
- 1,1,1,1,1,1,1,1, # 30 - 37
- 1,1,1,1,1,1,1,1, # 38 - 3f
- 2,2,2,2,2,2,2,2, # 40 - 47
- 2,2,2,2,2,2,2,2, # 48 - 4f
- 2,2,2,2,2,2,2,2, # 50 - 57
- 2,2,2,2,2,2,2,2, # 58 - 5f
- 2,2,2,2,2,2,2,2, # 60 - 67
- 2,2,2,2,2,2,2,2, # 68 - 6f
- 2,2,2,2,2,2,2,2, # 70 - 77
- 2,2,2,2,2,2,2,1, # 78 - 7f
- 4,4,4,4,4,4,4,4, # 80 - 87
- 4,4,4,4,4,4,4,4, # 88 - 8f
- 4,4,4,4,4,4,4,4, # 90 - 97
- 4,4,4,4,4,4,4,4, # 98 - 9f
- 4,3,3,3,3,3,3,3, # a0 - a7
- 3,3,3,3,3,3,3,3, # a8 - af
- 3,3,3,3,3,3,3,3, # b0 - b7
- 3,3,3,3,3,3,3,3, # b8 - bf
- 3,3,3,3,3,3,3,3, # c0 - c7
- 3,3,3,3,3,3,3,3, # c8 - cf
- 3,3,3,3,3,3,3,3, # d0 - d7
- 3,3,3,3,3,3,3,3, # d8 - df
- 3,3,3,3,3,3,3,3, # e0 - e7
- 3,3,3,3,3,3,3,3, # e8 - ef
- 3,3,3,3,3,3,3,3, # f0 - f7
- 3,3,3,3,3,3,3,0 # f8 - ff
-)
-
-BIG5_st = (
- eError,eStart,eStart, 3,eError,eError,eError,eError,#00-07
- eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,#08-0f
- eError,eStart,eStart,eStart,eStart,eStart,eStart,eStart#10-17
-)
-
-Big5CharLenTable = (0, 1, 1, 2, 0)
-
-Big5SMModel = {'classTable': BIG5_cls,
- 'classFactor': 5,
- 'stateTable': BIG5_st,
- 'charLenTable': Big5CharLenTable,
- 'name': 'Big5'}
-
-# CP949
-
-CP949_cls = (
- 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f
- 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f
- 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f
- 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f
- 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f
- 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f
- 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f
- 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f
- 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f
- 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f
- 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af
- 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf
- 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf
- 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df
- 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef
- 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff
-)
-
-CP949_st = (
-#cls= 0 1 2 3 4 5 6 7 8 9 # previous state =
- eError,eStart, 3,eError,eStart,eStart, 4, 5,eError, 6, # eStart
- eError,eError,eError,eError,eError,eError,eError,eError,eError,eError, # eError
- eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe, # eItsMe
- eError,eError,eStart,eStart,eError,eError,eError,eStart,eStart,eStart, # 3
- eError,eError,eStart,eStart,eStart,eStart,eStart,eStart,eStart,eStart, # 4
- eError,eStart,eStart,eStart,eStart,eStart,eStart,eStart,eStart,eStart, # 5
- eError,eStart,eStart,eStart,eStart,eError,eError,eStart,eStart,eStart, # 6
-)
-
-CP949CharLenTable = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2)
-
-CP949SMModel = {'classTable': CP949_cls,
- 'classFactor': 10,
- 'stateTable': CP949_st,
- 'charLenTable': CP949CharLenTable,
- 'name': 'CP949'}
-
-# EUC-JP
-
-EUCJP_cls = (
- 4,4,4,4,4,4,4,4, # 00 - 07
- 4,4,4,4,4,4,5,5, # 08 - 0f
- 4,4,4,4,4,4,4,4, # 10 - 17
- 4,4,4,5,4,4,4,4, # 18 - 1f
- 4,4,4,4,4,4,4,4, # 20 - 27
- 4,4,4,4,4,4,4,4, # 28 - 2f
- 4,4,4,4,4,4,4,4, # 30 - 37
- 4,4,4,4,4,4,4,4, # 38 - 3f
- 4,4,4,4,4,4,4,4, # 40 - 47
- 4,4,4,4,4,4,4,4, # 48 - 4f
- 4,4,4,4,4,4,4,4, # 50 - 57
- 4,4,4,4,4,4,4,4, # 58 - 5f
- 4,4,4,4,4,4,4,4, # 60 - 67
- 4,4,4,4,4,4,4,4, # 68 - 6f
- 4,4,4,4,4,4,4,4, # 70 - 77
- 4,4,4,4,4,4,4,4, # 78 - 7f
- 5,5,5,5,5,5,5,5, # 80 - 87
- 5,5,5,5,5,5,1,3, # 88 - 8f
- 5,5,5,5,5,5,5,5, # 90 - 97
- 5,5,5,5,5,5,5,5, # 98 - 9f
- 5,2,2,2,2,2,2,2, # a0 - a7
- 2,2,2,2,2,2,2,2, # a8 - af
- 2,2,2,2,2,2,2,2, # b0 - b7
- 2,2,2,2,2,2,2,2, # b8 - bf
- 2,2,2,2,2,2,2,2, # c0 - c7
- 2,2,2,2,2,2,2,2, # c8 - cf
- 2,2,2,2,2,2,2,2, # d0 - d7
- 2,2,2,2,2,2,2,2, # d8 - df
- 0,0,0,0,0,0,0,0, # e0 - e7
- 0,0,0,0,0,0,0,0, # e8 - ef
- 0,0,0,0,0,0,0,0, # f0 - f7
- 0,0,0,0,0,0,0,5 # f8 - ff
-)
-
-EUCJP_st = (
- 3, 4, 3, 5,eStart,eError,eError,eError,#00-07
- eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,#08-0f
- eItsMe,eItsMe,eStart,eError,eStart,eError,eError,eError,#10-17
- eError,eError,eStart,eError,eError,eError, 3,eError,#18-1f
- 3,eError,eError,eError,eStart,eStart,eStart,eStart#20-27
-)
-
-EUCJPCharLenTable = (2, 2, 2, 3, 1, 0)
-
-EUCJPSMModel = {'classTable': EUCJP_cls,
- 'classFactor': 6,
- 'stateTable': EUCJP_st,
- 'charLenTable': EUCJPCharLenTable,
- 'name': 'EUC-JP'}
-
-# EUC-KR
-
-EUCKR_cls = (
- 1,1,1,1,1,1,1,1, # 00 - 07
- 1,1,1,1,1,1,0,0, # 08 - 0f
- 1,1,1,1,1,1,1,1, # 10 - 17
- 1,1,1,0,1,1,1,1, # 18 - 1f
- 1,1,1,1,1,1,1,1, # 20 - 27
- 1,1,1,1,1,1,1,1, # 28 - 2f
- 1,1,1,1,1,1,1,1, # 30 - 37
- 1,1,1,1,1,1,1,1, # 38 - 3f
- 1,1,1,1,1,1,1,1, # 40 - 47
- 1,1,1,1,1,1,1,1, # 48 - 4f
- 1,1,1,1,1,1,1,1, # 50 - 57
- 1,1,1,1,1,1,1,1, # 58 - 5f
- 1,1,1,1,1,1,1,1, # 60 - 67
- 1,1,1,1,1,1,1,1, # 68 - 6f
- 1,1,1,1,1,1,1,1, # 70 - 77
- 1,1,1,1,1,1,1,1, # 78 - 7f
- 0,0,0,0,0,0,0,0, # 80 - 87
- 0,0,0,0,0,0,0,0, # 88 - 8f
- 0,0,0,0,0,0,0,0, # 90 - 97
- 0,0,0,0,0,0,0,0, # 98 - 9f
- 0,2,2,2,2,2,2,2, # a0 - a7
- 2,2,2,2,2,3,3,3, # a8 - af
- 2,2,2,2,2,2,2,2, # b0 - b7
- 2,2,2,2,2,2,2,2, # b8 - bf
- 2,2,2,2,2,2,2,2, # c0 - c7
- 2,3,2,2,2,2,2,2, # c8 - cf
- 2,2,2,2,2,2,2,2, # d0 - d7
- 2,2,2,2,2,2,2,2, # d8 - df
- 2,2,2,2,2,2,2,2, # e0 - e7
- 2,2,2,2,2,2,2,2, # e8 - ef
- 2,2,2,2,2,2,2,2, # f0 - f7
- 2,2,2,2,2,2,2,0 # f8 - ff
-)
-
-EUCKR_st = (
- eError,eStart, 3,eError,eError,eError,eError,eError,#00-07
- eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,eStart,eStart #08-0f
-)
-
-EUCKRCharLenTable = (0, 1, 2, 0)
-
-EUCKRSMModel = {'classTable': EUCKR_cls,
- 'classFactor': 4,
- 'stateTable': EUCKR_st,
- 'charLenTable': EUCKRCharLenTable,
- 'name': 'EUC-KR'}
-
-# EUC-TW
-
-EUCTW_cls = (
- 2,2,2,2,2,2,2,2, # 00 - 07
- 2,2,2,2,2,2,0,0, # 08 - 0f
- 2,2,2,2,2,2,2,2, # 10 - 17
- 2,2,2,0,2,2,2,2, # 18 - 1f
- 2,2,2,2,2,2,2,2, # 20 - 27
- 2,2,2,2,2,2,2,2, # 28 - 2f
- 2,2,2,2,2,2,2,2, # 30 - 37
- 2,2,2,2,2,2,2,2, # 38 - 3f
- 2,2,2,2,2,2,2,2, # 40 - 47
- 2,2,2,2,2,2,2,2, # 48 - 4f
- 2,2,2,2,2,2,2,2, # 50 - 57
- 2,2,2,2,2,2,2,2, # 58 - 5f
- 2,2,2,2,2,2,2,2, # 60 - 67
- 2,2,2,2,2,2,2,2, # 68 - 6f
- 2,2,2,2,2,2,2,2, # 70 - 77
- 2,2,2,2,2,2,2,2, # 78 - 7f
- 0,0,0,0,0,0,0,0, # 80 - 87
- 0,0,0,0,0,0,6,0, # 88 - 8f
- 0,0,0,0,0,0,0,0, # 90 - 97
- 0,0,0,0,0,0,0,0, # 98 - 9f
- 0,3,4,4,4,4,4,4, # a0 - a7
- 5,5,1,1,1,1,1,1, # a8 - af
- 1,1,1,1,1,1,1,1, # b0 - b7
- 1,1,1,1,1,1,1,1, # b8 - bf
- 1,1,3,1,3,3,3,3, # c0 - c7
- 3,3,3,3,3,3,3,3, # c8 - cf
- 3,3,3,3,3,3,3,3, # d0 - d7
- 3,3,3,3,3,3,3,3, # d8 - df
- 3,3,3,3,3,3,3,3, # e0 - e7
- 3,3,3,3,3,3,3,3, # e8 - ef
- 3,3,3,3,3,3,3,3, # f0 - f7
- 3,3,3,3,3,3,3,0 # f8 - ff
-)
-
-EUCTW_st = (
- eError,eError,eStart, 3, 3, 3, 4,eError,#00-07
- eError,eError,eError,eError,eError,eError,eItsMe,eItsMe,#08-0f
- eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eStart,eError,#10-17
- eStart,eStart,eStart,eError,eError,eError,eError,eError,#18-1f
- 5,eError,eError,eError,eStart,eError,eStart,eStart,#20-27
- eStart,eError,eStart,eStart,eStart,eStart,eStart,eStart #28-2f
-)
-
-EUCTWCharLenTable = (0, 0, 1, 2, 2, 2, 3)
-
-EUCTWSMModel = {'classTable': EUCTW_cls,
- 'classFactor': 7,
- 'stateTable': EUCTW_st,
- 'charLenTable': EUCTWCharLenTable,
- 'name': 'x-euc-tw'}
-
-# GB2312
-
-GB2312_cls = (
- 1,1,1,1,1,1,1,1, # 00 - 07
- 1,1,1,1,1,1,0,0, # 08 - 0f
- 1,1,1,1,1,1,1,1, # 10 - 17
- 1,1,1,0,1,1,1,1, # 18 - 1f
- 1,1,1,1,1,1,1,1, # 20 - 27
- 1,1,1,1,1,1,1,1, # 28 - 2f
- 3,3,3,3,3,3,3,3, # 30 - 37
- 3,3,1,1,1,1,1,1, # 38 - 3f
- 2,2,2,2,2,2,2,2, # 40 - 47
- 2,2,2,2,2,2,2,2, # 48 - 4f
- 2,2,2,2,2,2,2,2, # 50 - 57
- 2,2,2,2,2,2,2,2, # 58 - 5f
- 2,2,2,2,2,2,2,2, # 60 - 67
- 2,2,2,2,2,2,2,2, # 68 - 6f
- 2,2,2,2,2,2,2,2, # 70 - 77
- 2,2,2,2,2,2,2,4, # 78 - 7f
- 5,6,6,6,6,6,6,6, # 80 - 87
- 6,6,6,6,6,6,6,6, # 88 - 8f
- 6,6,6,6,6,6,6,6, # 90 - 97
- 6,6,6,6,6,6,6,6, # 98 - 9f
- 6,6,6,6,6,6,6,6, # a0 - a7
- 6,6,6,6,6,6,6,6, # a8 - af
- 6,6,6,6,6,6,6,6, # b0 - b7
- 6,6,6,6,6,6,6,6, # b8 - bf
- 6,6,6,6,6,6,6,6, # c0 - c7
- 6,6,6,6,6,6,6,6, # c8 - cf
- 6,6,6,6,6,6,6,6, # d0 - d7
- 6,6,6,6,6,6,6,6, # d8 - df
- 6,6,6,6,6,6,6,6, # e0 - e7
- 6,6,6,6,6,6,6,6, # e8 - ef
- 6,6,6,6,6,6,6,6, # f0 - f7
- 6,6,6,6,6,6,6,0 # f8 - ff
-)
-
-GB2312_st = (
- eError,eStart,eStart,eStart,eStart,eStart, 3,eError,#00-07
- eError,eError,eError,eError,eError,eError,eItsMe,eItsMe,#08-0f
- eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,eStart,#10-17
- 4,eError,eStart,eStart,eError,eError,eError,eError,#18-1f
- eError,eError, 5,eError,eError,eError,eItsMe,eError,#20-27
- eError,eError,eStart,eStart,eStart,eStart,eStart,eStart #28-2f
-)
-
-# To be accurate, the length of class 6 can be either 2 or 4.
-# But it is not necessary to discriminate between the two since
-# it is used for frequency analysis only, and we are validing
-# each code range there as well. So it is safe to set it to be
-# 2 here.
-GB2312CharLenTable = (0, 1, 1, 1, 1, 1, 2)
-
-GB2312SMModel = {'classTable': GB2312_cls,
- 'classFactor': 7,
- 'stateTable': GB2312_st,
- 'charLenTable': GB2312CharLenTable,
- 'name': 'GB2312'}
-
-# Shift_JIS
-
-SJIS_cls = (
- 1,1,1,1,1,1,1,1, # 00 - 07
- 1,1,1,1,1,1,0,0, # 08 - 0f
- 1,1,1,1,1,1,1,1, # 10 - 17
- 1,1,1,0,1,1,1,1, # 18 - 1f
- 1,1,1,1,1,1,1,1, # 20 - 27
- 1,1,1,1,1,1,1,1, # 28 - 2f
- 1,1,1,1,1,1,1,1, # 30 - 37
- 1,1,1,1,1,1,1,1, # 38 - 3f
- 2,2,2,2,2,2,2,2, # 40 - 47
- 2,2,2,2,2,2,2,2, # 48 - 4f
- 2,2,2,2,2,2,2,2, # 50 - 57
- 2,2,2,2,2,2,2,2, # 58 - 5f
- 2,2,2,2,2,2,2,2, # 60 - 67
- 2,2,2,2,2,2,2,2, # 68 - 6f
- 2,2,2,2,2,2,2,2, # 70 - 77
- 2,2,2,2,2,2,2,1, # 78 - 7f
- 3,3,3,3,3,2,2,3, # 80 - 87
- 3,3,3,3,3,3,3,3, # 88 - 8f
- 3,3,3,3,3,3,3,3, # 90 - 97
- 3,3,3,3,3,3,3,3, # 98 - 9f
- #0xa0 is illegal in sjis encoding, but some pages does
- #contain such byte. We need to be more error forgiven.
- 2,2,2,2,2,2,2,2, # a0 - a7
- 2,2,2,2,2,2,2,2, # a8 - af
- 2,2,2,2,2,2,2,2, # b0 - b7
- 2,2,2,2,2,2,2,2, # b8 - bf
- 2,2,2,2,2,2,2,2, # c0 - c7
- 2,2,2,2,2,2,2,2, # c8 - cf
- 2,2,2,2,2,2,2,2, # d0 - d7
- 2,2,2,2,2,2,2,2, # d8 - df
- 3,3,3,3,3,3,3,3, # e0 - e7
- 3,3,3,3,3,4,4,4, # e8 - ef
- 3,3,3,3,3,3,3,3, # f0 - f7
- 3,3,3,3,3,0,0,0) # f8 - ff
-
-
-SJIS_st = (
- eError,eStart,eStart, 3,eError,eError,eError,eError,#00-07
- eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,#08-0f
- eItsMe,eItsMe,eError,eError,eStart,eStart,eStart,eStart #10-17
-)
-
-SJISCharLenTable = (0, 1, 1, 2, 0, 0)
-
-SJISSMModel = {'classTable': SJIS_cls,
- 'classFactor': 6,
- 'stateTable': SJIS_st,
- 'charLenTable': SJISCharLenTable,
- 'name': 'Shift_JIS'}
-
-# UCS2-BE
-
-UCS2BE_cls = (
- 0,0,0,0,0,0,0,0, # 00 - 07
- 0,0,1,0,0,2,0,0, # 08 - 0f
- 0,0,0,0,0,0,0,0, # 10 - 17
- 0,0,0,3,0,0,0,0, # 18 - 1f
- 0,0,0,0,0,0,0,0, # 20 - 27
- 0,3,3,3,3,3,0,0, # 28 - 2f
- 0,0,0,0,0,0,0,0, # 30 - 37
- 0,0,0,0,0,0,0,0, # 38 - 3f
- 0,0,0,0,0,0,0,0, # 40 - 47
- 0,0,0,0,0,0,0,0, # 48 - 4f
- 0,0,0,0,0,0,0,0, # 50 - 57
- 0,0,0,0,0,0,0,0, # 58 - 5f
- 0,0,0,0,0,0,0,0, # 60 - 67
- 0,0,0,0,0,0,0,0, # 68 - 6f
- 0,0,0,0,0,0,0,0, # 70 - 77
- 0,0,0,0,0,0,0,0, # 78 - 7f
- 0,0,0,0,0,0,0,0, # 80 - 87
- 0,0,0,0,0,0,0,0, # 88 - 8f
- 0,0,0,0,0,0,0,0, # 90 - 97
- 0,0,0,0,0,0,0,0, # 98 - 9f
- 0,0,0,0,0,0,0,0, # a0 - a7
- 0,0,0,0,0,0,0,0, # a8 - af
- 0,0,0,0,0,0,0,0, # b0 - b7
- 0,0,0,0,0,0,0,0, # b8 - bf
- 0,0,0,0,0,0,0,0, # c0 - c7
- 0,0,0,0,0,0,0,0, # c8 - cf
- 0,0,0,0,0,0,0,0, # d0 - d7
- 0,0,0,0,0,0,0,0, # d8 - df
- 0,0,0,0,0,0,0,0, # e0 - e7
- 0,0,0,0,0,0,0,0, # e8 - ef
- 0,0,0,0,0,0,0,0, # f0 - f7
- 0,0,0,0,0,0,4,5 # f8 - ff
-)
-
-UCS2BE_st = (
- 5, 7, 7,eError, 4, 3,eError,eError,#00-07
- eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,#08-0f
- eItsMe,eItsMe, 6, 6, 6, 6,eError,eError,#10-17
- 6, 6, 6, 6, 6,eItsMe, 6, 6,#18-1f
- 6, 6, 6, 6, 5, 7, 7,eError,#20-27
- 5, 8, 6, 6,eError, 6, 6, 6,#28-2f
- 6, 6, 6, 6,eError,eError,eStart,eStart #30-37
-)
-
-UCS2BECharLenTable = (2, 2, 2, 0, 2, 2)
-
-UCS2BESMModel = {'classTable': UCS2BE_cls,
- 'classFactor': 6,
- 'stateTable': UCS2BE_st,
- 'charLenTable': UCS2BECharLenTable,
- 'name': 'UTF-16BE'}
-
-# UCS2-LE
-
-UCS2LE_cls = (
- 0,0,0,0,0,0,0,0, # 00 - 07
- 0,0,1,0,0,2,0,0, # 08 - 0f
- 0,0,0,0,0,0,0,0, # 10 - 17
- 0,0,0,3,0,0,0,0, # 18 - 1f
- 0,0,0,0,0,0,0,0, # 20 - 27
- 0,3,3,3,3,3,0,0, # 28 - 2f
- 0,0,0,0,0,0,0,0, # 30 - 37
- 0,0,0,0,0,0,0,0, # 38 - 3f
- 0,0,0,0,0,0,0,0, # 40 - 47
- 0,0,0,0,0,0,0,0, # 48 - 4f
- 0,0,0,0,0,0,0,0, # 50 - 57
- 0,0,0,0,0,0,0,0, # 58 - 5f
- 0,0,0,0,0,0,0,0, # 60 - 67
- 0,0,0,0,0,0,0,0, # 68 - 6f
- 0,0,0,0,0,0,0,0, # 70 - 77
- 0,0,0,0,0,0,0,0, # 78 - 7f
- 0,0,0,0,0,0,0,0, # 80 - 87
- 0,0,0,0,0,0,0,0, # 88 - 8f
- 0,0,0,0,0,0,0,0, # 90 - 97
- 0,0,0,0,0,0,0,0, # 98 - 9f
- 0,0,0,0,0,0,0,0, # a0 - a7
- 0,0,0,0,0,0,0,0, # a8 - af
- 0,0,0,0,0,0,0,0, # b0 - b7
- 0,0,0,0,0,0,0,0, # b8 - bf
- 0,0,0,0,0,0,0,0, # c0 - c7
- 0,0,0,0,0,0,0,0, # c8 - cf
- 0,0,0,0,0,0,0,0, # d0 - d7
- 0,0,0,0,0,0,0,0, # d8 - df
- 0,0,0,0,0,0,0,0, # e0 - e7
- 0,0,0,0,0,0,0,0, # e8 - ef
- 0,0,0,0,0,0,0,0, # f0 - f7
- 0,0,0,0,0,0,4,5 # f8 - ff
-)
-
-UCS2LE_st = (
- 6, 6, 7, 6, 4, 3,eError,eError,#00-07
- eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe,#08-0f
- eItsMe,eItsMe, 5, 5, 5,eError,eItsMe,eError,#10-17
- 5, 5, 5,eError, 5,eError, 6, 6,#18-1f
- 7, 6, 8, 8, 5, 5, 5,eError,#20-27
- 5, 5, 5,eError,eError,eError, 5, 5,#28-2f
- 5, 5, 5,eError, 5,eError,eStart,eStart #30-37
-)
-
-UCS2LECharLenTable = (2, 2, 2, 2, 2, 2)
-
-UCS2LESMModel = {'classTable': UCS2LE_cls,
- 'classFactor': 6,
- 'stateTable': UCS2LE_st,
- 'charLenTable': UCS2LECharLenTable,
- 'name': 'UTF-16LE'}
-
-# UTF-8
-
-UTF8_cls = (
- 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value
- 1,1,1,1,1,1,0,0, # 08 - 0f
- 1,1,1,1,1,1,1,1, # 10 - 17
- 1,1,1,0,1,1,1,1, # 18 - 1f
- 1,1,1,1,1,1,1,1, # 20 - 27
- 1,1,1,1,1,1,1,1, # 28 - 2f
- 1,1,1,1,1,1,1,1, # 30 - 37
- 1,1,1,1,1,1,1,1, # 38 - 3f
- 1,1,1,1,1,1,1,1, # 40 - 47
- 1,1,1,1,1,1,1,1, # 48 - 4f
- 1,1,1,1,1,1,1,1, # 50 - 57
- 1,1,1,1,1,1,1,1, # 58 - 5f
- 1,1,1,1,1,1,1,1, # 60 - 67
- 1,1,1,1,1,1,1,1, # 68 - 6f
- 1,1,1,1,1,1,1,1, # 70 - 77
- 1,1,1,1,1,1,1,1, # 78 - 7f
- 2,2,2,2,3,3,3,3, # 80 - 87
- 4,4,4,4,4,4,4,4, # 88 - 8f
- 4,4,4,4,4,4,4,4, # 90 - 97
- 4,4,4,4,4,4,4,4, # 98 - 9f
- 5,5,5,5,5,5,5,5, # a0 - a7
- 5,5,5,5,5,5,5,5, # a8 - af
- 5,5,5,5,5,5,5,5, # b0 - b7
- 5,5,5,5,5,5,5,5, # b8 - bf
- 0,0,6,6,6,6,6,6, # c0 - c7
- 6,6,6,6,6,6,6,6, # c8 - cf
- 6,6,6,6,6,6,6,6, # d0 - d7
- 6,6,6,6,6,6,6,6, # d8 - df
- 7,8,8,8,8,8,8,8, # e0 - e7
- 8,8,8,8,8,9,8,8, # e8 - ef
- 10,11,11,11,11,11,11,11, # f0 - f7
- 12,13,13,13,14,15,0,0 # f8 - ff
-)
-
-UTF8_st = (
- eError,eStart,eError,eError,eError,eError, 12, 10,#00-07
- 9, 11, 8, 7, 6, 5, 4, 3,#08-0f
- eError,eError,eError,eError,eError,eError,eError,eError,#10-17
- eError,eError,eError,eError,eError,eError,eError,eError,#18-1f
- eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,#20-27
- eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,#28-2f
- eError,eError, 5, 5, 5, 5,eError,eError,#30-37
- eError,eError,eError,eError,eError,eError,eError,eError,#38-3f
- eError,eError,eError, 5, 5, 5,eError,eError,#40-47
- eError,eError,eError,eError,eError,eError,eError,eError,#48-4f
- eError,eError, 7, 7, 7, 7,eError,eError,#50-57
- eError,eError,eError,eError,eError,eError,eError,eError,#58-5f
- eError,eError,eError,eError, 7, 7,eError,eError,#60-67
- eError,eError,eError,eError,eError,eError,eError,eError,#68-6f
- eError,eError, 9, 9, 9, 9,eError,eError,#70-77
- eError,eError,eError,eError,eError,eError,eError,eError,#78-7f
- eError,eError,eError,eError,eError, 9,eError,eError,#80-87
- eError,eError,eError,eError,eError,eError,eError,eError,#88-8f
- eError,eError, 12, 12, 12, 12,eError,eError,#90-97
- eError,eError,eError,eError,eError,eError,eError,eError,#98-9f
- eError,eError,eError,eError,eError, 12,eError,eError,#a0-a7
- eError,eError,eError,eError,eError,eError,eError,eError,#a8-af
- eError,eError, 12, 12, 12,eError,eError,eError,#b0-b7
- eError,eError,eError,eError,eError,eError,eError,eError,#b8-bf
- eError,eError,eStart,eStart,eStart,eStart,eError,eError,#c0-c7
- eError,eError,eError,eError,eError,eError,eError,eError #c8-cf
-)
-
-UTF8CharLenTable = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6)
-
-UTF8SMModel = {'classTable': UTF8_cls,
- 'classFactor': 16,
- 'stateTable': UTF8_st,
- 'charLenTable': UTF8CharLenTable,
- 'name': 'UTF-8'}
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcharsetprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcharsetprober.py
deleted file mode 100644
index 37291bd2..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcharsetprober.py
+++ /dev/null
@@ -1,120 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-import sys
-from . import constants
-from .charsetprober import CharSetProber
-from .compat import wrap_ord
-
-SAMPLE_SIZE = 64
-SB_ENOUGH_REL_THRESHOLD = 1024
-POSITIVE_SHORTCUT_THRESHOLD = 0.95
-NEGATIVE_SHORTCUT_THRESHOLD = 0.05
-SYMBOL_CAT_ORDER = 250
-NUMBER_OF_SEQ_CAT = 4
-POSITIVE_CAT = NUMBER_OF_SEQ_CAT - 1
-#NEGATIVE_CAT = 0
-
-
-class SingleByteCharSetProber(CharSetProber):
- def __init__(self, model, reversed=False, nameProber=None):
- CharSetProber.__init__(self)
- self._mModel = model
- # TRUE if we need to reverse every pair in the model lookup
- self._mReversed = reversed
- # Optional auxiliary prober for name decision
- self._mNameProber = nameProber
- self.reset()
-
- def reset(self):
- CharSetProber.reset(self)
- # char order of last character
- self._mLastOrder = 255
- self._mSeqCounters = [0] * NUMBER_OF_SEQ_CAT
- self._mTotalSeqs = 0
- self._mTotalChar = 0
- # characters that fall in our sampling range
- self._mFreqChar = 0
-
- def get_charset_name(self):
- if self._mNameProber:
- return self._mNameProber.get_charset_name()
- else:
- return self._mModel['charsetName']
-
- def feed(self, aBuf):
- if not self._mModel['keepEnglishLetter']:
- aBuf = self.filter_without_english_letters(aBuf)
- aLen = len(aBuf)
- if not aLen:
- return self.get_state()
- for c in aBuf:
- order = self._mModel['charToOrderMap'][wrap_ord(c)]
- if order < SYMBOL_CAT_ORDER:
- self._mTotalChar += 1
- if order < SAMPLE_SIZE:
- self._mFreqChar += 1
- if self._mLastOrder < SAMPLE_SIZE:
- self._mTotalSeqs += 1
- if not self._mReversed:
- i = (self._mLastOrder * SAMPLE_SIZE) + order
- model = self._mModel['precedenceMatrix'][i]
- else: # reverse the order of the letters in the lookup
- i = (order * SAMPLE_SIZE) + self._mLastOrder
- model = self._mModel['precedenceMatrix'][i]
- self._mSeqCounters[model] += 1
- self._mLastOrder = order
-
- if self.get_state() == constants.eDetecting:
- if self._mTotalSeqs > SB_ENOUGH_REL_THRESHOLD:
- cf = self.get_confidence()
- if cf > POSITIVE_SHORTCUT_THRESHOLD:
- if constants._debug:
- sys.stderr.write('%s confidence = %s, we have a'
- 'winner\n' %
- (self._mModel['charsetName'], cf))
- self._mState = constants.eFoundIt
- elif cf < NEGATIVE_SHORTCUT_THRESHOLD:
- if constants._debug:
- sys.stderr.write('%s confidence = %s, below negative'
- 'shortcut threshhold %s\n' %
- (self._mModel['charsetName'], cf,
- NEGATIVE_SHORTCUT_THRESHOLD))
- self._mState = constants.eNotMe
-
- return self.get_state()
-
- def get_confidence(self):
- r = 0.01
- if self._mTotalSeqs > 0:
- r = ((1.0 * self._mSeqCounters[POSITIVE_CAT]) / self._mTotalSeqs
- / self._mModel['mTypicalPositiveRatio'])
- r = r * self._mFreqChar / self._mTotalChar
- if r >= 1.0:
- r = 0.99
- return r
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcsgroupprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcsgroupprober.py
deleted file mode 100644
index 1b6196cd..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sbcsgroupprober.py
+++ /dev/null
@@ -1,69 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from .charsetgroupprober import CharSetGroupProber
-from .sbcharsetprober import SingleByteCharSetProber
-from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel,
- Latin5CyrillicModel, MacCyrillicModel,
- Ibm866Model, Ibm855Model)
-from .langgreekmodel import Latin7GreekModel, Win1253GreekModel
-from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel
-from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel
-from .langthaimodel import TIS620ThaiModel
-from .langhebrewmodel import Win1255HebrewModel
-from .hebrewprober import HebrewProber
-
-
-class SBCSGroupProber(CharSetGroupProber):
- def __init__(self):
- CharSetGroupProber.__init__(self)
- self._mProbers = [
- SingleByteCharSetProber(Win1251CyrillicModel),
- SingleByteCharSetProber(Koi8rModel),
- SingleByteCharSetProber(Latin5CyrillicModel),
- SingleByteCharSetProber(MacCyrillicModel),
- SingleByteCharSetProber(Ibm866Model),
- SingleByteCharSetProber(Ibm855Model),
- SingleByteCharSetProber(Latin7GreekModel),
- SingleByteCharSetProber(Win1253GreekModel),
- SingleByteCharSetProber(Latin5BulgarianModel),
- SingleByteCharSetProber(Win1251BulgarianModel),
- SingleByteCharSetProber(Latin2HungarianModel),
- SingleByteCharSetProber(Win1250HungarianModel),
- SingleByteCharSetProber(TIS620ThaiModel),
- ]
- hebrewProber = HebrewProber()
- logicalHebrewProber = SingleByteCharSetProber(Win1255HebrewModel,
- False, hebrewProber)
- visualHebrewProber = SingleByteCharSetProber(Win1255HebrewModel, True,
- hebrewProber)
- hebrewProber.set_model_probers(logicalHebrewProber, visualHebrewProber)
- self._mProbers.extend([hebrewProber, logicalHebrewProber,
- visualHebrewProber])
-
- self.reset()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sjisprober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sjisprober.py
deleted file mode 100644
index cd0e9e70..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/sjisprober.py
+++ /dev/null
@@ -1,91 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-import sys
-from .mbcharsetprober import MultiByteCharSetProber
-from .codingstatemachine import CodingStateMachine
-from .chardistribution import SJISDistributionAnalysis
-from .jpcntx import SJISContextAnalysis
-from .mbcssm import SJISSMModel
-from . import constants
-
-
-class SJISProber(MultiByteCharSetProber):
- def __init__(self):
- MultiByteCharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(SJISSMModel)
- self._mDistributionAnalyzer = SJISDistributionAnalysis()
- self._mContextAnalyzer = SJISContextAnalysis()
- self.reset()
-
- def reset(self):
- MultiByteCharSetProber.reset(self)
- self._mContextAnalyzer.reset()
-
- def get_charset_name(self):
- return self._mContextAnalyzer.get_charset_name()
-
- def feed(self, aBuf):
- aLen = len(aBuf)
- for i in range(0, aLen):
- codingState = self._mCodingSM.next_state(aBuf[i])
- if codingState == constants.eError:
- if constants._debug:
- sys.stderr.write(self.get_charset_name()
- + ' prober hit error at byte ' + str(i)
- + '\n')
- self._mState = constants.eNotMe
- break
- elif codingState == constants.eItsMe:
- self._mState = constants.eFoundIt
- break
- elif codingState == constants.eStart:
- charLen = self._mCodingSM.get_current_charlen()
- if i == 0:
- self._mLastChar[1] = aBuf[0]
- self._mContextAnalyzer.feed(self._mLastChar[2 - charLen:],
- charLen)
- self._mDistributionAnalyzer.feed(self._mLastChar, charLen)
- else:
- self._mContextAnalyzer.feed(aBuf[i + 1 - charLen:i + 3
- - charLen], charLen)
- self._mDistributionAnalyzer.feed(aBuf[i - 1:i + 1],
- charLen)
-
- self._mLastChar[0] = aBuf[aLen - 1]
-
- if self.get_state() == constants.eDetecting:
- if (self._mContextAnalyzer.got_enough_data() and
- (self.get_confidence() > constants.SHORTCUT_THRESHOLD)):
- self._mState = constants.eFoundIt
-
- return self.get_state()
-
- def get_confidence(self):
- contxtCf = self._mContextAnalyzer.get_confidence()
- distribCf = self._mDistributionAnalyzer.get_confidence()
- return max(contxtCf, distribCf)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/universaldetector.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/universaldetector.py
deleted file mode 100644
index 476522b9..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/universaldetector.py
+++ /dev/null
@@ -1,170 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is Mozilla Universal charset detector code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-# Shy Shalom - original C code
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from . import constants
-import sys
-import codecs
-from .latin1prober import Latin1Prober # windows-1252
-from .mbcsgroupprober import MBCSGroupProber # multi-byte character sets
-from .sbcsgroupprober import SBCSGroupProber # single-byte character sets
-from .escprober import EscCharSetProber # ISO-2122, etc.
-import re
-
-MINIMUM_THRESHOLD = 0.20
-ePureAscii = 0
-eEscAscii = 1
-eHighbyte = 2
-
-
-class UniversalDetector:
- def __init__(self):
- self._highBitDetector = re.compile(b'[\x80-\xFF]')
- self._escDetector = re.compile(b'(\033|~{)')
- self._mEscCharSetProber = None
- self._mCharSetProbers = []
- self.reset()
-
- def reset(self):
- self.result = {'encoding': None, 'confidence': 0.0}
- self.done = False
- self._mStart = True
- self._mGotData = False
- self._mInputState = ePureAscii
- self._mLastChar = b''
- if self._mEscCharSetProber:
- self._mEscCharSetProber.reset()
- for prober in self._mCharSetProbers:
- prober.reset()
-
- def feed(self, aBuf):
- if self.done:
- return
-
- aLen = len(aBuf)
- if not aLen:
- return
-
- if not self._mGotData:
- # If the data starts with BOM, we know it is UTF
- if aBuf[:3] == codecs.BOM_UTF8:
- # EF BB BF UTF-8 with BOM
- self.result = {'encoding': "UTF-8-SIG", 'confidence': 1.0}
- elif aBuf[:4] == codecs.BOM_UTF32_LE:
- # FF FE 00 00 UTF-32, little-endian BOM
- self.result = {'encoding': "UTF-32LE", 'confidence': 1.0}
- elif aBuf[:4] == codecs.BOM_UTF32_BE:
- # 00 00 FE FF UTF-32, big-endian BOM
- self.result = {'encoding': "UTF-32BE", 'confidence': 1.0}
- elif aBuf[:4] == b'\xFE\xFF\x00\x00':
- # FE FF 00 00 UCS-4, unusual octet order BOM (3412)
- self.result = {
- 'encoding': "X-ISO-10646-UCS-4-3412",
- 'confidence': 1.0
- }
- elif aBuf[:4] == b'\x00\x00\xFF\xFE':
- # 00 00 FF FE UCS-4, unusual octet order BOM (2143)
- self.result = {
- 'encoding': "X-ISO-10646-UCS-4-2143",
- 'confidence': 1.0
- }
- elif aBuf[:2] == codecs.BOM_LE:
- # FF FE UTF-16, little endian BOM
- self.result = {'encoding': "UTF-16LE", 'confidence': 1.0}
- elif aBuf[:2] == codecs.BOM_BE:
- # FE FF UTF-16, big endian BOM
- self.result = {'encoding': "UTF-16BE", 'confidence': 1.0}
-
- self._mGotData = True
- if self.result['encoding'] and (self.result['confidence'] > 0.0):
- self.done = True
- return
-
- if self._mInputState == ePureAscii:
- if self._highBitDetector.search(aBuf):
- self._mInputState = eHighbyte
- elif ((self._mInputState == ePureAscii) and
- self._escDetector.search(self._mLastChar + aBuf)):
- self._mInputState = eEscAscii
-
- self._mLastChar = aBuf[-1:]
-
- if self._mInputState == eEscAscii:
- if not self._mEscCharSetProber:
- self._mEscCharSetProber = EscCharSetProber()
- if self._mEscCharSetProber.feed(aBuf) == constants.eFoundIt:
- self.result = {'encoding': self._mEscCharSetProber.get_charset_name(),
- 'confidence': self._mEscCharSetProber.get_confidence()}
- self.done = True
- elif self._mInputState == eHighbyte:
- if not self._mCharSetProbers:
- self._mCharSetProbers = [MBCSGroupProber(), SBCSGroupProber(),
- Latin1Prober()]
- for prober in self._mCharSetProbers:
- if prober.feed(aBuf) == constants.eFoundIt:
- self.result = {'encoding': prober.get_charset_name(),
- 'confidence': prober.get_confidence()}
- self.done = True
- break
-
- def close(self):
- if self.done:
- return
- if not self._mGotData:
- if constants._debug:
- sys.stderr.write('no data received!\n')
- return
- self.done = True
-
- if self._mInputState == ePureAscii:
- self.result = {'encoding': 'ascii', 'confidence': 1.0}
- return self.result
-
- if self._mInputState == eHighbyte:
- proberConfidence = None
- maxProberConfidence = 0.0
- maxProber = None
- for prober in self._mCharSetProbers:
- if not prober:
- continue
- proberConfidence = prober.get_confidence()
- if proberConfidence > maxProberConfidence:
- maxProberConfidence = proberConfidence
- maxProber = prober
- if maxProber and (maxProberConfidence > MINIMUM_THRESHOLD):
- self.result = {'encoding': maxProber.get_charset_name(),
- 'confidence': maxProber.get_confidence()}
- return self.result
-
- if constants._debug:
- sys.stderr.write('no probers hit minimum threshhold\n')
- for prober in self._mCharSetProbers[0].mProbers:
- if not prober:
- continue
- sys.stderr.write('%s confidence = %s\n' %
- (prober.get_charset_name(),
- prober.get_confidence()))
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/utf8prober.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/utf8prober.py
deleted file mode 100644
index 1c0bb5d8..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/chardet/utf8prober.py
+++ /dev/null
@@ -1,76 +0,0 @@
-######################## BEGIN LICENSE BLOCK ########################
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Mark Pilgrim - port to Python
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA
-######################### END LICENSE BLOCK #########################
-
-from . import constants
-from .charsetprober import CharSetProber
-from .codingstatemachine import CodingStateMachine
-from .mbcssm import UTF8SMModel
-
-ONE_CHAR_PROB = 0.5
-
-
-class UTF8Prober(CharSetProber):
- def __init__(self):
- CharSetProber.__init__(self)
- self._mCodingSM = CodingStateMachine(UTF8SMModel)
- self.reset()
-
- def reset(self):
- CharSetProber.reset(self)
- self._mCodingSM.reset()
- self._mNumOfMBChar = 0
-
- def get_charset_name(self):
- return "utf-8"
-
- def feed(self, aBuf):
- for c in aBuf:
- codingState = self._mCodingSM.next_state(c)
- if codingState == constants.eError:
- self._mState = constants.eNotMe
- break
- elif codingState == constants.eItsMe:
- self._mState = constants.eFoundIt
- break
- elif codingState == constants.eStart:
- if self._mCodingSM.get_current_charlen() >= 2:
- self._mNumOfMBChar += 1
-
- if self.get_state() == constants.eDetecting:
- if self.get_confidence() > constants.SHORTCUT_THRESHOLD:
- self._mState = constants.eFoundIt
-
- return self.get_state()
-
- def get_confidence(self):
- unlike = 0.99
- if self._mNumOfMBChar < 6:
- for i in range(0, self._mNumOfMBChar):
- unlike = unlike * ONE_CHAR_PROB
- return 1.0 - unlike
- else:
- return unlike
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/__init__.py
deleted file mode 100644
index bb67a43f..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .core import *
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/codec.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/codec.py
deleted file mode 100644
index 98c65ead..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/codec.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from .core import encode, decode, alabel, ulabel, IDNAError
-import codecs
-import re
-
-_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]')
-
-class Codec(codecs.Codec):
-
- def encode(self, data, errors='strict'):
-
- if errors != 'strict':
- raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
-
- if not data:
- return "", 0
-
- return encode(data), len(data)
-
- def decode(self, data, errors='strict'):
-
- if errors != 'strict':
- raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
-
- if not data:
- return u"", 0
-
- return decode(data), len(data)
-
-class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
- def _buffer_encode(self, data, errors, final):
- if errors != 'strict':
- raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
-
- if not data:
- return ("", 0)
-
- labels = _unicode_dots_re.split(data)
- trailing_dot = u''
- if labels:
- if not labels[-1]:
- trailing_dot = '.'
- del labels[-1]
- elif not final:
- # Keep potentially unfinished label until the next call
- del labels[-1]
- if labels:
- trailing_dot = '.'
-
- result = []
- size = 0
- for label in labels:
- result.append(alabel(label))
- if size:
- size += 1
- size += len(label)
-
- # Join with U+002E
- result = ".".join(result) + trailing_dot
- size += len(trailing_dot)
- return (result, size)
-
-class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
- def _buffer_decode(self, data, errors, final):
- if errors != 'strict':
- raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
-
- if not data:
- return (u"", 0)
-
- # IDNA allows decoding to operate on Unicode strings, too.
- if isinstance(data, unicode):
- labels = _unicode_dots_re.split(data)
- else:
- # Must be ASCII string
- data = str(data)
- unicode(data, "ascii")
- labels = data.split(".")
-
- trailing_dot = u''
- if labels:
- if not labels[-1]:
- trailing_dot = u'.'
- del labels[-1]
- elif not final:
- # Keep potentially unfinished label until the next call
- del labels[-1]
- if labels:
- trailing_dot = u'.'
-
- result = []
- size = 0
- for label in labels:
- result.append(ulabel(label))
- if size:
- size += 1
- size += len(label)
-
- result = u".".join(result) + trailing_dot
- size += len(trailing_dot)
- return (result, size)
-
-
-class StreamWriter(Codec, codecs.StreamWriter):
- pass
-
-class StreamReader(Codec, codecs.StreamReader):
- pass
-
-def getregentry():
- return codecs.CodecInfo(
- name='idna',
- encode=Codec().encode,
- decode=Codec().decode,
- incrementalencoder=IncrementalEncoder,
- incrementaldecoder=IncrementalDecoder,
- streamwriter=StreamWriter,
- streamreader=StreamReader,
- )
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/compat.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/compat.py
deleted file mode 100644
index 4d47f336..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/compat.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from .core import *
-from .codec import *
-
-def ToASCII(label):
- return encode(label)
-
-def ToUnicode(label):
- return decode(label)
-
-def nameprep(s):
- raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol")
-
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/core.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/core.py
deleted file mode 100644
index ff3b38d6..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/core.py
+++ /dev/null
@@ -1,387 +0,0 @@
-from . import idnadata
-import bisect
-import unicodedata
-import re
-import sys
-from .intranges import intranges_contain
-
-_virama_combining_class = 9
-_alabel_prefix = b'xn--'
-_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]')
-
-if sys.version_info[0] == 3:
- unicode = str
- unichr = chr
-
-class IDNAError(UnicodeError):
- """ Base exception for all IDNA-encoding related problems """
- pass
-
-
-class IDNABidiError(IDNAError):
- """ Exception when bidirectional requirements are not satisfied """
- pass
-
-
-class InvalidCodepoint(IDNAError):
- """ Exception when a disallowed or unallocated codepoint is used """
- pass
-
-
-class InvalidCodepointContext(IDNAError):
- """ Exception when the codepoint is not valid in the context it is used """
- pass
-
-
-def _combining_class(cp):
- return unicodedata.combining(unichr(cp))
-
-def _is_script(cp, script):
- return intranges_contain(ord(cp), idnadata.scripts[script])
-
-def _punycode(s):
- return s.encode('punycode')
-
-def _unot(s):
- return 'U+{0:04X}'.format(s)
-
-
-def valid_label_length(label):
-
- if len(label) > 63:
- return False
- return True
-
-
-def valid_string_length(label, trailing_dot):
-
- if len(label) > (254 if trailing_dot else 253):
- return False
- return True
-
-
-def check_bidi(label, check_ltr=False):
-
- # Bidi rules should only be applied if string contains RTL characters
- bidi_label = False
- for (idx, cp) in enumerate(label, 1):
- direction = unicodedata.bidirectional(cp)
- if direction == '':
- # String likely comes from a newer version of Unicode
- raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx))
- if direction in ['R', 'AL', 'AN']:
- bidi_label = True
- break
- if not bidi_label and not check_ltr:
- return True
-
- # Bidi rule 1
- direction = unicodedata.bidirectional(label[0])
- if direction in ['R', 'AL']:
- rtl = True
- elif direction == 'L':
- rtl = False
- else:
- raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label)))
-
- valid_ending = False
- number_type = False
- for (idx, cp) in enumerate(label, 1):
- direction = unicodedata.bidirectional(cp)
-
- if rtl:
- # Bidi rule 2
- if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
- raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx))
- # Bidi rule 3
- if direction in ['R', 'AL', 'EN', 'AN']:
- valid_ending = True
- elif direction != 'NSM':
- valid_ending = False
- # Bidi rule 4
- if direction in ['AN', 'EN']:
- if not number_type:
- number_type = direction
- else:
- if number_type != direction:
- raise IDNABidiError('Can not mix numeral types in a right-to-left label')
- else:
- # Bidi rule 5
- if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
- raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx))
- # Bidi rule 6
- if direction in ['L', 'EN']:
- valid_ending = True
- elif direction != 'NSM':
- valid_ending = False
-
- if not valid_ending:
- raise IDNABidiError('Label ends with illegal codepoint directionality')
-
- return True
-
-
-def check_initial_combiner(label):
-
- if unicodedata.category(label[0])[0] == 'M':
- raise IDNAError('Label begins with an illegal combining character')
- return True
-
-
-def check_hyphen_ok(label):
-
- if label[2:4] == '--':
- raise IDNAError('Label has disallowed hyphens in 3rd and 4th position')
- if label[0] == '-' or label[-1] == '-':
- raise IDNAError('Label must not start or end with a hyphen')
- return True
-
-
-def check_nfc(label):
-
- if unicodedata.normalize('NFC', label) != label:
- raise IDNAError('Label must be in Normalization Form C')
-
-
-def valid_contextj(label, pos):
-
- cp_value = ord(label[pos])
-
- if cp_value == 0x200c:
-
- if pos > 0:
- if _combining_class(ord(label[pos - 1])) == _virama_combining_class:
- return True
-
- ok = False
- for i in range(pos-1, -1, -1):
- joining_type = idnadata.joining_types.get(ord(label[i]))
- if joining_type == 'T':
- continue
- if joining_type in ['L', 'D']:
- ok = True
- break
-
- if not ok:
- return False
-
- ok = False
- for i in range(pos+1, len(label)):
- joining_type = idnadata.joining_types.get(ord(label[i]))
- if joining_type == 'T':
- continue
- if joining_type in ['R', 'D']:
- ok = True
- break
- return ok
-
- if cp_value == 0x200d:
-
- if pos > 0:
- if _combining_class(ord(label[pos - 1])) == _virama_combining_class:
- return True
- return False
-
- else:
-
- return False
-
-
-def valid_contexto(label, pos, exception=False):
-
- cp_value = ord(label[pos])
-
- if cp_value == 0x00b7:
- if 0 < pos < len(label)-1:
- if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c:
- return True
- return False
-
- elif cp_value == 0x0375:
- if pos < len(label)-1 and len(label) > 1:
- return _is_script(label[pos + 1], 'Greek')
- return False
-
- elif cp_value == 0x05f3 or cp_value == 0x05f4:
- if pos > 0:
- return _is_script(label[pos - 1], 'Hebrew')
- return False
-
- elif cp_value == 0x30fb:
- for cp in label:
- if cp == u'\u30fb':
- continue
- if not _is_script(cp, 'Hiragana') and not _is_script(cp, 'Katakana') and not _is_script(cp, 'Han'):
- return False
- return True
-
- elif 0x660 <= cp_value <= 0x669:
- for cp in label:
- if 0x6f0 <= ord(cp) <= 0x06f9:
- return False
- return True
-
- elif 0x6f0 <= cp_value <= 0x6f9:
- for cp in label:
- if 0x660 <= ord(cp) <= 0x0669:
- return False
- return True
-
-
-def check_label(label):
-
- if isinstance(label, (bytes, bytearray)):
- label = label.decode('utf-8')
- if len(label) == 0:
- raise IDNAError('Empty Label')
-
- check_nfc(label)
- check_hyphen_ok(label)
- check_initial_combiner(label)
-
- for (pos, cp) in enumerate(label):
- cp_value = ord(cp)
- if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']):
- continue
- elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']):
- if not valid_contextj(label, pos):
- raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label)))
- elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']):
- if not valid_contexto(label, pos):
- raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label)))
- else:
- raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
-
- check_bidi(label)
-
-
-def alabel(label):
-
- try:
- label = label.encode('ascii')
- try:
- ulabel(label)
- except:
- raise IDNAError('The label {0} is not a valid A-label'.format(label))
- if not valid_label_length(label):
- raise IDNAError('Label too long')
- return label
- except UnicodeError:
- pass
-
- if not label:
- raise IDNAError('No Input')
-
- label = unicode(label)
- check_label(label)
- label = _punycode(label)
- label = _alabel_prefix + label
-
- if not valid_label_length(label):
- raise IDNAError('Label too long')
-
- return label
-
-
-def ulabel(label):
-
- if not isinstance(label, (bytes, bytearray)):
- try:
- label = label.encode('ascii')
- except UnicodeError:
- check_label(label)
- return label
-
- label = label.lower()
- if label.startswith(_alabel_prefix):
- label = label[len(_alabel_prefix):]
- else:
- check_label(label)
- return label.decode('ascii')
-
- label = label.decode('punycode')
- check_label(label)
- return label
-
-
-def uts46_remap(domain, std3_rules=True, transitional=False):
- """Re-map the characters in the string according to UTS46 processing."""
- from .uts46data import uts46data
- output = u""
- try:
- for pos, char in enumerate(domain):
- code_point = ord(char)
- uts46row = uts46data[code_point if code_point < 256 else
- bisect.bisect_left(uts46data, (code_point, "Z")) - 1]
- status = uts46row[1]
- replacement = uts46row[2] if len(uts46row) == 3 else None
- if (status == "V" or
- (status == "D" and not transitional) or
- (status == "3" and std3_rules and replacement is None)):
- output += char
- elif replacement is not None and (status == "M" or
- (status == "3" and std3_rules) or
- (status == "D" and transitional)):
- output += replacement
- elif status != "I":
- raise IndexError()
- return unicodedata.normalize("NFC", output)
- except IndexError:
- raise InvalidCodepoint(
- "Codepoint {0} not allowed at position {1} in {2}".format(
- _unot(code_point), pos + 1, repr(domain)))
-
-
-def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False):
-
- if isinstance(s, (bytes, bytearray)):
- s = s.decode("ascii")
- if uts46:
- s = uts46_remap(s, std3_rules, transitional)
- trailing_dot = False
- result = []
- if strict:
- labels = s.split('.')
- else:
- labels = _unicode_dots_re.split(s)
- while labels and not labels[0]:
- del labels[0]
- if not labels:
- raise IDNAError('Empty domain')
- if labels[-1] == '':
- del labels[-1]
- trailing_dot = True
- for label in labels:
- result.append(alabel(label))
- if trailing_dot:
- result.append(b'')
- s = b'.'.join(result)
- if not valid_string_length(s, trailing_dot):
- raise IDNAError('Domain too long')
- return s
-
-
-def decode(s, strict=False, uts46=False, std3_rules=False):
-
- if isinstance(s, (bytes, bytearray)):
- s = s.decode("ascii")
- if uts46:
- s = uts46_remap(s, std3_rules, False)
- trailing_dot = False
- result = []
- if not strict:
- labels = _unicode_dots_re.split(s)
- else:
- labels = s.split(u'.')
- while labels and not labels[0]:
- del labels[0]
- if not labels:
- raise IDNAError('Empty domain')
- if not labels[-1]:
- del labels[-1]
- trailing_dot = True
- for label in labels:
- result.append(ulabel(label))
- if trailing_dot:
- result.append(u'')
- return u'.'.join(result)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/idnadata.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/idnadata.py
deleted file mode 100644
index 2bffe527..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/idnadata.py
+++ /dev/null
@@ -1,1584 +0,0 @@
-# This file is automatically generated by build-idnadata.py
-
-scripts = {
- 'Greek': (
- (0x370, 0x374),
- (0x375, 0x378),
- (0x37a, 0x37e),
- (0x384, 0x385),
- (0x386, 0x387),
- (0x388, 0x38b),
- (0x38c, 0x38d),
- (0x38e, 0x3a2),
- (0x3a3, 0x3e2),
- (0x3f0, 0x400),
- (0x1d26, 0x1d2b),
- (0x1d5d, 0x1d62),
- (0x1d66, 0x1d6b),
- (0x1dbf, 0x1dc0),
- (0x1f00, 0x1f16),
- (0x1f18, 0x1f1e),
- (0x1f20, 0x1f46),
- (0x1f48, 0x1f4e),
- (0x1f50, 0x1f58),
- (0x1f59, 0x1f5a),
- (0x1f5b, 0x1f5c),
- (0x1f5d, 0x1f5e),
- (0x1f5f, 0x1f7e),
- (0x1f80, 0x1fb5),
- (0x1fb6, 0x1fc5),
- (0x1fc6, 0x1fd4),
- (0x1fd6, 0x1fdc),
- (0x1fdd, 0x1ff0),
- (0x1ff2, 0x1ff5),
- (0x1ff6, 0x1fff),
- (0x2126, 0x2127),
- (0x10140, 0x1018b),
- (0x1d200, 0x1d246),
- ),
- 'Han': (
- (0x2e80, 0x2e9a),
- (0x2e9b, 0x2ef4),
- (0x2f00, 0x2fd6),
- (0x3005, 0x3006),
- (0x3007, 0x3008),
- (0x3021, 0x302a),
- (0x3038, 0x303c),
- (0x3400, 0x4db6),
- (0x4e00, 0x9fcd),
- (0xf900, 0xfa6e),
- (0xfa70, 0xfada),
- (0x20000, 0x2a6d7),
- (0x2a700, 0x2b735),
- (0x2b740, 0x2b81e),
- (0x2f800, 0x2fa1e),
- ),
- 'Hebrew': (
- (0x591, 0x5c8),
- (0x5d0, 0x5eb),
- (0x5f0, 0x5f5),
- (0xfb1d, 0xfb37),
- (0xfb38, 0xfb3d),
- (0xfb3e, 0xfb3f),
- (0xfb40, 0xfb42),
- (0xfb43, 0xfb45),
- (0xfb46, 0xfb50),
- ),
- 'Hiragana': (
- (0x3041, 0x3097),
- (0x309d, 0x30a0),
- (0x1b001, 0x1b002),
- (0x1f200, 0x1f201),
- ),
- 'Katakana': (
- (0x30a1, 0x30fb),
- (0x30fd, 0x3100),
- (0x31f0, 0x3200),
- (0x32d0, 0x32ff),
- (0x3300, 0x3358),
- (0xff66, 0xff70),
- (0xff71, 0xff9e),
- (0x1b000, 0x1b001),
- ),
-}
-joining_types = {
- 0x600: 'U',
- 0x601: 'U',
- 0x602: 'U',
- 0x603: 'U',
- 0x604: 'U',
- 0x608: 'U',
- 0x60b: 'U',
- 0x620: 'D',
- 0x621: 'U',
- 0x622: 'R',
- 0x623: 'R',
- 0x624: 'R',
- 0x625: 'R',
- 0x626: 'D',
- 0x627: 'R',
- 0x628: 'D',
- 0x629: 'R',
- 0x62a: 'D',
- 0x62b: 'D',
- 0x62c: 'D',
- 0x62d: 'D',
- 0x62e: 'D',
- 0x62f: 'R',
- 0x630: 'R',
- 0x631: 'R',
- 0x632: 'R',
- 0x633: 'D',
- 0x634: 'D',
- 0x635: 'D',
- 0x636: 'D',
- 0x637: 'D',
- 0x638: 'D',
- 0x639: 'D',
- 0x63a: 'D',
- 0x63b: 'D',
- 0x63c: 'D',
- 0x63d: 'D',
- 0x63e: 'D',
- 0x63f: 'D',
- 0x640: 'C',
- 0x641: 'D',
- 0x642: 'D',
- 0x643: 'D',
- 0x644: 'D',
- 0x645: 'D',
- 0x646: 'D',
- 0x647: 'D',
- 0x648: 'R',
- 0x649: 'D',
- 0x64a: 'D',
- 0x66e: 'D',
- 0x66f: 'D',
- 0x671: 'R',
- 0x672: 'R',
- 0x673: 'R',
- 0x674: 'U',
- 0x675: 'R',
- 0x676: 'R',
- 0x677: 'R',
- 0x678: 'D',
- 0x679: 'D',
- 0x67a: 'D',
- 0x67b: 'D',
- 0x67c: 'D',
- 0x67d: 'D',
- 0x67e: 'D',
- 0x67f: 'D',
- 0x680: 'D',
- 0x681: 'D',
- 0x682: 'D',
- 0x683: 'D',
- 0x684: 'D',
- 0x685: 'D',
- 0x686: 'D',
- 0x687: 'D',
- 0x688: 'R',
- 0x689: 'R',
- 0x68a: 'R',
- 0x68b: 'R',
- 0x68c: 'R',
- 0x68d: 'R',
- 0x68e: 'R',
- 0x68f: 'R',
- 0x690: 'R',
- 0x691: 'R',
- 0x692: 'R',
- 0x693: 'R',
- 0x694: 'R',
- 0x695: 'R',
- 0x696: 'R',
- 0x697: 'R',
- 0x698: 'R',
- 0x699: 'R',
- 0x69a: 'D',
- 0x69b: 'D',
- 0x69c: 'D',
- 0x69d: 'D',
- 0x69e: 'D',
- 0x69f: 'D',
- 0x6a0: 'D',
- 0x6a1: 'D',
- 0x6a2: 'D',
- 0x6a3: 'D',
- 0x6a4: 'D',
- 0x6a5: 'D',
- 0x6a6: 'D',
- 0x6a7: 'D',
- 0x6a8: 'D',
- 0x6a9: 'D',
- 0x6aa: 'D',
- 0x6ab: 'D',
- 0x6ac: 'D',
- 0x6ad: 'D',
- 0x6ae: 'D',
- 0x6af: 'D',
- 0x6b0: 'D',
- 0x6b1: 'D',
- 0x6b2: 'D',
- 0x6b3: 'D',
- 0x6b4: 'D',
- 0x6b5: 'D',
- 0x6b6: 'D',
- 0x6b7: 'D',
- 0x6b8: 'D',
- 0x6b9: 'D',
- 0x6ba: 'D',
- 0x6bb: 'D',
- 0x6bc: 'D',
- 0x6bd: 'D',
- 0x6be: 'D',
- 0x6bf: 'D',
- 0x6c0: 'R',
- 0x6c1: 'D',
- 0x6c2: 'D',
- 0x6c3: 'R',
- 0x6c4: 'R',
- 0x6c5: 'R',
- 0x6c6: 'R',
- 0x6c7: 'R',
- 0x6c8: 'R',
- 0x6c9: 'R',
- 0x6ca: 'R',
- 0x6cb: 'R',
- 0x6cc: 'D',
- 0x6cd: 'R',
- 0x6ce: 'D',
- 0x6cf: 'R',
- 0x6d0: 'D',
- 0x6d1: 'D',
- 0x6d2: 'R',
- 0x6d3: 'R',
- 0x6d5: 'R',
- 0x6dd: 'U',
- 0x6ee: 'R',
- 0x6ef: 'R',
- 0x6fa: 'D',
- 0x6fb: 'D',
- 0x6fc: 'D',
- 0x6ff: 'D',
- 0x710: 'R',
- 0x712: 'D',
- 0x713: 'D',
- 0x714: 'D',
- 0x715: 'R',
- 0x716: 'R',
- 0x717: 'R',
- 0x718: 'R',
- 0x719: 'R',
- 0x71a: 'D',
- 0x71b: 'D',
- 0x71c: 'D',
- 0x71d: 'D',
- 0x71e: 'R',
- 0x71f: 'D',
- 0x720: 'D',
- 0x721: 'D',
- 0x722: 'D',
- 0x723: 'D',
- 0x724: 'D',
- 0x725: 'D',
- 0x726: 'D',
- 0x727: 'D',
- 0x728: 'R',
- 0x729: 'D',
- 0x72a: 'R',
- 0x72b: 'D',
- 0x72c: 'R',
- 0x72d: 'D',
- 0x72e: 'D',
- 0x72f: 'R',
- 0x74d: 'R',
- 0x74e: 'D',
- 0x74f: 'D',
- 0x750: 'D',
- 0x751: 'D',
- 0x752: 'D',
- 0x753: 'D',
- 0x754: 'D',
- 0x755: 'D',
- 0x756: 'D',
- 0x757: 'D',
- 0x758: 'D',
- 0x759: 'R',
- 0x75a: 'R',
- 0x75b: 'R',
- 0x75c: 'D',
- 0x75d: 'D',
- 0x75e: 'D',
- 0x75f: 'D',
- 0x760: 'D',
- 0x761: 'D',
- 0x762: 'D',
- 0x763: 'D',
- 0x764: 'D',
- 0x765: 'D',
- 0x766: 'D',
- 0x767: 'D',
- 0x768: 'D',
- 0x769: 'D',
- 0x76a: 'D',
- 0x76b: 'R',
- 0x76c: 'R',
- 0x76d: 'D',
- 0x76e: 'D',
- 0x76f: 'D',
- 0x770: 'D',
- 0x771: 'R',
- 0x772: 'D',
- 0x773: 'R',
- 0x774: 'R',
- 0x775: 'D',
- 0x776: 'D',
- 0x777: 'D',
- 0x778: 'R',
- 0x779: 'R',
- 0x77a: 'D',
- 0x77b: 'D',
- 0x77c: 'D',
- 0x77d: 'D',
- 0x77e: 'D',
- 0x77f: 'D',
- 0x7ca: 'D',
- 0x7cb: 'D',
- 0x7cc: 'D',
- 0x7cd: 'D',
- 0x7ce: 'D',
- 0x7cf: 'D',
- 0x7d0: 'D',
- 0x7d1: 'D',
- 0x7d2: 'D',
- 0x7d3: 'D',
- 0x7d4: 'D',
- 0x7d5: 'D',
- 0x7d6: 'D',
- 0x7d7: 'D',
- 0x7d8: 'D',
- 0x7d9: 'D',
- 0x7da: 'D',
- 0x7db: 'D',
- 0x7dc: 'D',
- 0x7dd: 'D',
- 0x7de: 'D',
- 0x7df: 'D',
- 0x7e0: 'D',
- 0x7e1: 'D',
- 0x7e2: 'D',
- 0x7e3: 'D',
- 0x7e4: 'D',
- 0x7e5: 'D',
- 0x7e6: 'D',
- 0x7e7: 'D',
- 0x7e8: 'D',
- 0x7e9: 'D',
- 0x7ea: 'D',
- 0x7fa: 'C',
- 0x840: 'R',
- 0x841: 'D',
- 0x842: 'D',
- 0x843: 'D',
- 0x844: 'D',
- 0x845: 'D',
- 0x846: 'R',
- 0x847: 'D',
- 0x848: 'D',
- 0x849: 'R',
- 0x84a: 'D',
- 0x84b: 'D',
- 0x84c: 'D',
- 0x84d: 'D',
- 0x84e: 'D',
- 0x84f: 'R',
- 0x850: 'D',
- 0x851: 'D',
- 0x852: 'D',
- 0x853: 'D',
- 0x854: 'R',
- 0x855: 'D',
- 0x856: 'U',
- 0x857: 'U',
- 0x858: 'U',
- 0x8a0: 'D',
- 0x8a2: 'D',
- 0x8a3: 'D',
- 0x8a4: 'D',
- 0x8a5: 'D',
- 0x8a6: 'D',
- 0x8a7: 'D',
- 0x8a8: 'D',
- 0x8a9: 'D',
- 0x8aa: 'R',
- 0x8ab: 'R',
- 0x8ac: 'R',
- 0x1806: 'U',
- 0x1807: 'D',
- 0x180a: 'C',
- 0x180e: 'U',
- 0x1820: 'D',
- 0x1821: 'D',
- 0x1822: 'D',
- 0x1823: 'D',
- 0x1824: 'D',
- 0x1825: 'D',
- 0x1826: 'D',
- 0x1827: 'D',
- 0x1828: 'D',
- 0x1829: 'D',
- 0x182a: 'D',
- 0x182b: 'D',
- 0x182c: 'D',
- 0x182d: 'D',
- 0x182e: 'D',
- 0x182f: 'D',
- 0x1830: 'D',
- 0x1831: 'D',
- 0x1832: 'D',
- 0x1833: 'D',
- 0x1834: 'D',
- 0x1835: 'D',
- 0x1836: 'D',
- 0x1837: 'D',
- 0x1838: 'D',
- 0x1839: 'D',
- 0x183a: 'D',
- 0x183b: 'D',
- 0x183c: 'D',
- 0x183d: 'D',
- 0x183e: 'D',
- 0x183f: 'D',
- 0x1840: 'D',
- 0x1841: 'D',
- 0x1842: 'D',
- 0x1843: 'D',
- 0x1844: 'D',
- 0x1845: 'D',
- 0x1846: 'D',
- 0x1847: 'D',
- 0x1848: 'D',
- 0x1849: 'D',
- 0x184a: 'D',
- 0x184b: 'D',
- 0x184c: 'D',
- 0x184d: 'D',
- 0x184e: 'D',
- 0x184f: 'D',
- 0x1850: 'D',
- 0x1851: 'D',
- 0x1852: 'D',
- 0x1853: 'D',
- 0x1854: 'D',
- 0x1855: 'D',
- 0x1856: 'D',
- 0x1857: 'D',
- 0x1858: 'D',
- 0x1859: 'D',
- 0x185a: 'D',
- 0x185b: 'D',
- 0x185c: 'D',
- 0x185d: 'D',
- 0x185e: 'D',
- 0x185f: 'D',
- 0x1860: 'D',
- 0x1861: 'D',
- 0x1862: 'D',
- 0x1863: 'D',
- 0x1864: 'D',
- 0x1865: 'D',
- 0x1866: 'D',
- 0x1867: 'D',
- 0x1868: 'D',
- 0x1869: 'D',
- 0x186a: 'D',
- 0x186b: 'D',
- 0x186c: 'D',
- 0x186d: 'D',
- 0x186e: 'D',
- 0x186f: 'D',
- 0x1870: 'D',
- 0x1871: 'D',
- 0x1872: 'D',
- 0x1873: 'D',
- 0x1874: 'D',
- 0x1875: 'D',
- 0x1876: 'D',
- 0x1877: 'D',
- 0x1880: 'U',
- 0x1881: 'U',
- 0x1882: 'U',
- 0x1883: 'U',
- 0x1884: 'U',
- 0x1885: 'U',
- 0x1886: 'U',
- 0x1887: 'D',
- 0x1888: 'D',
- 0x1889: 'D',
- 0x188a: 'D',
- 0x188b: 'D',
- 0x188c: 'D',
- 0x188d: 'D',
- 0x188e: 'D',
- 0x188f: 'D',
- 0x1890: 'D',
- 0x1891: 'D',
- 0x1892: 'D',
- 0x1893: 'D',
- 0x1894: 'D',
- 0x1895: 'D',
- 0x1896: 'D',
- 0x1897: 'D',
- 0x1898: 'D',
- 0x1899: 'D',
- 0x189a: 'D',
- 0x189b: 'D',
- 0x189c: 'D',
- 0x189d: 'D',
- 0x189e: 'D',
- 0x189f: 'D',
- 0x18a0: 'D',
- 0x18a1: 'D',
- 0x18a2: 'D',
- 0x18a3: 'D',
- 0x18a4: 'D',
- 0x18a5: 'D',
- 0x18a6: 'D',
- 0x18a7: 'D',
- 0x18a8: 'D',
- 0x18aa: 'D',
- 0x200c: 'U',
- 0x200d: 'C',
- 0x2066: 'U',
- 0x2067: 'U',
- 0x2068: 'U',
- 0x2069: 'U',
- 0xa840: 'D',
- 0xa841: 'D',
- 0xa842: 'D',
- 0xa843: 'D',
- 0xa844: 'D',
- 0xa845: 'D',
- 0xa846: 'D',
- 0xa847: 'D',
- 0xa848: 'D',
- 0xa849: 'D',
- 0xa84a: 'D',
- 0xa84b: 'D',
- 0xa84c: 'D',
- 0xa84d: 'D',
- 0xa84e: 'D',
- 0xa84f: 'D',
- 0xa850: 'D',
- 0xa851: 'D',
- 0xa852: 'D',
- 0xa853: 'D',
- 0xa854: 'D',
- 0xa855: 'D',
- 0xa856: 'D',
- 0xa857: 'D',
- 0xa858: 'D',
- 0xa859: 'D',
- 0xa85a: 'D',
- 0xa85b: 'D',
- 0xa85c: 'D',
- 0xa85d: 'D',
- 0xa85e: 'D',
- 0xa85f: 'D',
- 0xa860: 'D',
- 0xa861: 'D',
- 0xa862: 'D',
- 0xa863: 'D',
- 0xa864: 'D',
- 0xa865: 'D',
- 0xa866: 'D',
- 0xa867: 'D',
- 0xa868: 'D',
- 0xa869: 'D',
- 0xa86a: 'D',
- 0xa86b: 'D',
- 0xa86c: 'D',
- 0xa86d: 'D',
- 0xa86e: 'D',
- 0xa86f: 'D',
- 0xa870: 'D',
- 0xa871: 'D',
- 0xa872: 'L',
- 0xa873: 'U',
-}
-codepoint_classes = {
- 'PVALID': (
- (0x2d, 0x2e),
- (0x30, 0x3a),
- (0x61, 0x7b),
- (0xdf, 0xf7),
- (0xf8, 0x100),
- (0x101, 0x102),
- (0x103, 0x104),
- (0x105, 0x106),
- (0x107, 0x108),
- (0x109, 0x10a),
- (0x10b, 0x10c),
- (0x10d, 0x10e),
- (0x10f, 0x110),
- (0x111, 0x112),
- (0x113, 0x114),
- (0x115, 0x116),
- (0x117, 0x118),
- (0x119, 0x11a),
- (0x11b, 0x11c),
- (0x11d, 0x11e),
- (0x11f, 0x120),
- (0x121, 0x122),
- (0x123, 0x124),
- (0x125, 0x126),
- (0x127, 0x128),
- (0x129, 0x12a),
- (0x12b, 0x12c),
- (0x12d, 0x12e),
- (0x12f, 0x130),
- (0x131, 0x132),
- (0x135, 0x136),
- (0x137, 0x139),
- (0x13a, 0x13b),
- (0x13c, 0x13d),
- (0x13e, 0x13f),
- (0x142, 0x143),
- (0x144, 0x145),
- (0x146, 0x147),
- (0x148, 0x149),
- (0x14b, 0x14c),
- (0x14d, 0x14e),
- (0x14f, 0x150),
- (0x151, 0x152),
- (0x153, 0x154),
- (0x155, 0x156),
- (0x157, 0x158),
- (0x159, 0x15a),
- (0x15b, 0x15c),
- (0x15d, 0x15e),
- (0x15f, 0x160),
- (0x161, 0x162),
- (0x163, 0x164),
- (0x165, 0x166),
- (0x167, 0x168),
- (0x169, 0x16a),
- (0x16b, 0x16c),
- (0x16d, 0x16e),
- (0x16f, 0x170),
- (0x171, 0x172),
- (0x173, 0x174),
- (0x175, 0x176),
- (0x177, 0x178),
- (0x17a, 0x17b),
- (0x17c, 0x17d),
- (0x17e, 0x17f),
- (0x180, 0x181),
- (0x183, 0x184),
- (0x185, 0x186),
- (0x188, 0x189),
- (0x18c, 0x18e),
- (0x192, 0x193),
- (0x195, 0x196),
- (0x199, 0x19c),
- (0x19e, 0x19f),
- (0x1a1, 0x1a2),
- (0x1a3, 0x1a4),
- (0x1a5, 0x1a6),
- (0x1a8, 0x1a9),
- (0x1aa, 0x1ac),
- (0x1ad, 0x1ae),
- (0x1b0, 0x1b1),
- (0x1b4, 0x1b5),
- (0x1b6, 0x1b7),
- (0x1b9, 0x1bc),
- (0x1bd, 0x1c4),
- (0x1ce, 0x1cf),
- (0x1d0, 0x1d1),
- (0x1d2, 0x1d3),
- (0x1d4, 0x1d5),
- (0x1d6, 0x1d7),
- (0x1d8, 0x1d9),
- (0x1da, 0x1db),
- (0x1dc, 0x1de),
- (0x1df, 0x1e0),
- (0x1e1, 0x1e2),
- (0x1e3, 0x1e4),
- (0x1e5, 0x1e6),
- (0x1e7, 0x1e8),
- (0x1e9, 0x1ea),
- (0x1eb, 0x1ec),
- (0x1ed, 0x1ee),
- (0x1ef, 0x1f1),
- (0x1f5, 0x1f6),
- (0x1f9, 0x1fa),
- (0x1fb, 0x1fc),
- (0x1fd, 0x1fe),
- (0x1ff, 0x200),
- (0x201, 0x202),
- (0x203, 0x204),
- (0x205, 0x206),
- (0x207, 0x208),
- (0x209, 0x20a),
- (0x20b, 0x20c),
- (0x20d, 0x20e),
- (0x20f, 0x210),
- (0x211, 0x212),
- (0x213, 0x214),
- (0x215, 0x216),
- (0x217, 0x218),
- (0x219, 0x21a),
- (0x21b, 0x21c),
- (0x21d, 0x21e),
- (0x21f, 0x220),
- (0x221, 0x222),
- (0x223, 0x224),
- (0x225, 0x226),
- (0x227, 0x228),
- (0x229, 0x22a),
- (0x22b, 0x22c),
- (0x22d, 0x22e),
- (0x22f, 0x230),
- (0x231, 0x232),
- (0x233, 0x23a),
- (0x23c, 0x23d),
- (0x23f, 0x241),
- (0x242, 0x243),
- (0x247, 0x248),
- (0x249, 0x24a),
- (0x24b, 0x24c),
- (0x24d, 0x24e),
- (0x24f, 0x2b0),
- (0x2b9, 0x2c2),
- (0x2c6, 0x2d2),
- (0x2ec, 0x2ed),
- (0x2ee, 0x2ef),
- (0x300, 0x340),
- (0x342, 0x343),
- (0x346, 0x34f),
- (0x350, 0x370),
- (0x371, 0x372),
- (0x373, 0x374),
- (0x377, 0x378),
- (0x37b, 0x37e),
- (0x390, 0x391),
- (0x3ac, 0x3cf),
- (0x3d7, 0x3d8),
- (0x3d9, 0x3da),
- (0x3db, 0x3dc),
- (0x3dd, 0x3de),
- (0x3df, 0x3e0),
- (0x3e1, 0x3e2),
- (0x3e3, 0x3e4),
- (0x3e5, 0x3e6),
- (0x3e7, 0x3e8),
- (0x3e9, 0x3ea),
- (0x3eb, 0x3ec),
- (0x3ed, 0x3ee),
- (0x3ef, 0x3f0),
- (0x3f3, 0x3f4),
- (0x3f8, 0x3f9),
- (0x3fb, 0x3fd),
- (0x430, 0x460),
- (0x461, 0x462),
- (0x463, 0x464),
- (0x465, 0x466),
- (0x467, 0x468),
- (0x469, 0x46a),
- (0x46b, 0x46c),
- (0x46d, 0x46e),
- (0x46f, 0x470),
- (0x471, 0x472),
- (0x473, 0x474),
- (0x475, 0x476),
- (0x477, 0x478),
- (0x479, 0x47a),
- (0x47b, 0x47c),
- (0x47d, 0x47e),
- (0x47f, 0x480),
- (0x481, 0x482),
- (0x483, 0x488),
- (0x48b, 0x48c),
- (0x48d, 0x48e),
- (0x48f, 0x490),
- (0x491, 0x492),
- (0x493, 0x494),
- (0x495, 0x496),
- (0x497, 0x498),
- (0x499, 0x49a),
- (0x49b, 0x49c),
- (0x49d, 0x49e),
- (0x49f, 0x4a0),
- (0x4a1, 0x4a2),
- (0x4a3, 0x4a4),
- (0x4a5, 0x4a6),
- (0x4a7, 0x4a8),
- (0x4a9, 0x4aa),
- (0x4ab, 0x4ac),
- (0x4ad, 0x4ae),
- (0x4af, 0x4b0),
- (0x4b1, 0x4b2),
- (0x4b3, 0x4b4),
- (0x4b5, 0x4b6),
- (0x4b7, 0x4b8),
- (0x4b9, 0x4ba),
- (0x4bb, 0x4bc),
- (0x4bd, 0x4be),
- (0x4bf, 0x4c0),
- (0x4c2, 0x4c3),
- (0x4c4, 0x4c5),
- (0x4c6, 0x4c7),
- (0x4c8, 0x4c9),
- (0x4ca, 0x4cb),
- (0x4cc, 0x4cd),
- (0x4ce, 0x4d0),
- (0x4d1, 0x4d2),
- (0x4d3, 0x4d4),
- (0x4d5, 0x4d6),
- (0x4d7, 0x4d8),
- (0x4d9, 0x4da),
- (0x4db, 0x4dc),
- (0x4dd, 0x4de),
- (0x4df, 0x4e0),
- (0x4e1, 0x4e2),
- (0x4e3, 0x4e4),
- (0x4e5, 0x4e6),
- (0x4e7, 0x4e8),
- (0x4e9, 0x4ea),
- (0x4eb, 0x4ec),
- (0x4ed, 0x4ee),
- (0x4ef, 0x4f0),
- (0x4f1, 0x4f2),
- (0x4f3, 0x4f4),
- (0x4f5, 0x4f6),
- (0x4f7, 0x4f8),
- (0x4f9, 0x4fa),
- (0x4fb, 0x4fc),
- (0x4fd, 0x4fe),
- (0x4ff, 0x500),
- (0x501, 0x502),
- (0x503, 0x504),
- (0x505, 0x506),
- (0x507, 0x508),
- (0x509, 0x50a),
- (0x50b, 0x50c),
- (0x50d, 0x50e),
- (0x50f, 0x510),
- (0x511, 0x512),
- (0x513, 0x514),
- (0x515, 0x516),
- (0x517, 0x518),
- (0x519, 0x51a),
- (0x51b, 0x51c),
- (0x51d, 0x51e),
- (0x51f, 0x520),
- (0x521, 0x522),
- (0x523, 0x524),
- (0x525, 0x526),
- (0x527, 0x528),
- (0x559, 0x55a),
- (0x561, 0x587),
- (0x591, 0x5be),
- (0x5bf, 0x5c0),
- (0x5c1, 0x5c3),
- (0x5c4, 0x5c6),
- (0x5c7, 0x5c8),
- (0x5d0, 0x5eb),
- (0x5f0, 0x5f3),
- (0x610, 0x61b),
- (0x620, 0x640),
- (0x641, 0x660),
- (0x66e, 0x675),
- (0x679, 0x6d4),
- (0x6d5, 0x6dd),
- (0x6df, 0x6e9),
- (0x6ea, 0x6f0),
- (0x6fa, 0x700),
- (0x710, 0x74b),
- (0x74d, 0x7b2),
- (0x7c0, 0x7f6),
- (0x800, 0x82e),
- (0x840, 0x85c),
- (0x8a0, 0x8a1),
- (0x8a2, 0x8ad),
- (0x8e4, 0x8ff),
- (0x900, 0x958),
- (0x960, 0x964),
- (0x966, 0x970),
- (0x971, 0x978),
- (0x979, 0x980),
- (0x981, 0x984),
- (0x985, 0x98d),
- (0x98f, 0x991),
- (0x993, 0x9a9),
- (0x9aa, 0x9b1),
- (0x9b2, 0x9b3),
- (0x9b6, 0x9ba),
- (0x9bc, 0x9c5),
- (0x9c7, 0x9c9),
- (0x9cb, 0x9cf),
- (0x9d7, 0x9d8),
- (0x9e0, 0x9e4),
- (0x9e6, 0x9f2),
- (0xa01, 0xa04),
- (0xa05, 0xa0b),
- (0xa0f, 0xa11),
- (0xa13, 0xa29),
- (0xa2a, 0xa31),
- (0xa32, 0xa33),
- (0xa35, 0xa36),
- (0xa38, 0xa3a),
- (0xa3c, 0xa3d),
- (0xa3e, 0xa43),
- (0xa47, 0xa49),
- (0xa4b, 0xa4e),
- (0xa51, 0xa52),
- (0xa5c, 0xa5d),
- (0xa66, 0xa76),
- (0xa81, 0xa84),
- (0xa85, 0xa8e),
- (0xa8f, 0xa92),
- (0xa93, 0xaa9),
- (0xaaa, 0xab1),
- (0xab2, 0xab4),
- (0xab5, 0xaba),
- (0xabc, 0xac6),
- (0xac7, 0xaca),
- (0xacb, 0xace),
- (0xad0, 0xad1),
- (0xae0, 0xae4),
- (0xae6, 0xaf0),
- (0xb01, 0xb04),
- (0xb05, 0xb0d),
- (0xb0f, 0xb11),
- (0xb13, 0xb29),
- (0xb2a, 0xb31),
- (0xb32, 0xb34),
- (0xb35, 0xb3a),
- (0xb3c, 0xb45),
- (0xb47, 0xb49),
- (0xb4b, 0xb4e),
- (0xb56, 0xb58),
- (0xb5f, 0xb64),
- (0xb66, 0xb70),
- (0xb71, 0xb72),
- (0xb82, 0xb84),
- (0xb85, 0xb8b),
- (0xb8e, 0xb91),
- (0xb92, 0xb96),
- (0xb99, 0xb9b),
- (0xb9c, 0xb9d),
- (0xb9e, 0xba0),
- (0xba3, 0xba5),
- (0xba8, 0xbab),
- (0xbae, 0xbba),
- (0xbbe, 0xbc3),
- (0xbc6, 0xbc9),
- (0xbca, 0xbce),
- (0xbd0, 0xbd1),
- (0xbd7, 0xbd8),
- (0xbe6, 0xbf0),
- (0xc01, 0xc04),
- (0xc05, 0xc0d),
- (0xc0e, 0xc11),
- (0xc12, 0xc29),
- (0xc2a, 0xc34),
- (0xc35, 0xc3a),
- (0xc3d, 0xc45),
- (0xc46, 0xc49),
- (0xc4a, 0xc4e),
- (0xc55, 0xc57),
- (0xc58, 0xc5a),
- (0xc60, 0xc64),
- (0xc66, 0xc70),
- (0xc82, 0xc84),
- (0xc85, 0xc8d),
- (0xc8e, 0xc91),
- (0xc92, 0xca9),
- (0xcaa, 0xcb4),
- (0xcb5, 0xcba),
- (0xcbc, 0xcc5),
- (0xcc6, 0xcc9),
- (0xcca, 0xcce),
- (0xcd5, 0xcd7),
- (0xcde, 0xcdf),
- (0xce0, 0xce4),
- (0xce6, 0xcf0),
- (0xcf1, 0xcf3),
- (0xd02, 0xd04),
- (0xd05, 0xd0d),
- (0xd0e, 0xd11),
- (0xd12, 0xd3b),
- (0xd3d, 0xd45),
- (0xd46, 0xd49),
- (0xd4a, 0xd4f),
- (0xd57, 0xd58),
- (0xd60, 0xd64),
- (0xd66, 0xd70),
- (0xd7a, 0xd80),
- (0xd82, 0xd84),
- (0xd85, 0xd97),
- (0xd9a, 0xdb2),
- (0xdb3, 0xdbc),
- (0xdbd, 0xdbe),
- (0xdc0, 0xdc7),
- (0xdca, 0xdcb),
- (0xdcf, 0xdd5),
- (0xdd6, 0xdd7),
- (0xdd8, 0xde0),
- (0xdf2, 0xdf4),
- (0xe01, 0xe33),
- (0xe34, 0xe3b),
- (0xe40, 0xe4f),
- (0xe50, 0xe5a),
- (0xe81, 0xe83),
- (0xe84, 0xe85),
- (0xe87, 0xe89),
- (0xe8a, 0xe8b),
- (0xe8d, 0xe8e),
- (0xe94, 0xe98),
- (0xe99, 0xea0),
- (0xea1, 0xea4),
- (0xea5, 0xea6),
- (0xea7, 0xea8),
- (0xeaa, 0xeac),
- (0xead, 0xeb3),
- (0xeb4, 0xeba),
- (0xebb, 0xebe),
- (0xec0, 0xec5),
- (0xec6, 0xec7),
- (0xec8, 0xece),
- (0xed0, 0xeda),
- (0xede, 0xee0),
- (0xf00, 0xf01),
- (0xf0b, 0xf0c),
- (0xf18, 0xf1a),
- (0xf20, 0xf2a),
- (0xf35, 0xf36),
- (0xf37, 0xf38),
- (0xf39, 0xf3a),
- (0xf3e, 0xf43),
- (0xf44, 0xf48),
- (0xf49, 0xf4d),
- (0xf4e, 0xf52),
- (0xf53, 0xf57),
- (0xf58, 0xf5c),
- (0xf5d, 0xf69),
- (0xf6a, 0xf6d),
- (0xf71, 0xf73),
- (0xf74, 0xf75),
- (0xf7a, 0xf81),
- (0xf82, 0xf85),
- (0xf86, 0xf93),
- (0xf94, 0xf98),
- (0xf99, 0xf9d),
- (0xf9e, 0xfa2),
- (0xfa3, 0xfa7),
- (0xfa8, 0xfac),
- (0xfad, 0xfb9),
- (0xfba, 0xfbd),
- (0xfc6, 0xfc7),
- (0x1000, 0x104a),
- (0x1050, 0x109e),
- (0x10d0, 0x10fb),
- (0x10fd, 0x1100),
- (0x1200, 0x1249),
- (0x124a, 0x124e),
- (0x1250, 0x1257),
- (0x1258, 0x1259),
- (0x125a, 0x125e),
- (0x1260, 0x1289),
- (0x128a, 0x128e),
- (0x1290, 0x12b1),
- (0x12b2, 0x12b6),
- (0x12b8, 0x12bf),
- (0x12c0, 0x12c1),
- (0x12c2, 0x12c6),
- (0x12c8, 0x12d7),
- (0x12d8, 0x1311),
- (0x1312, 0x1316),
- (0x1318, 0x135b),
- (0x135d, 0x1360),
- (0x1380, 0x1390),
- (0x13a0, 0x13f5),
- (0x1401, 0x166d),
- (0x166f, 0x1680),
- (0x1681, 0x169b),
- (0x16a0, 0x16eb),
- (0x1700, 0x170d),
- (0x170e, 0x1715),
- (0x1720, 0x1735),
- (0x1740, 0x1754),
- (0x1760, 0x176d),
- (0x176e, 0x1771),
- (0x1772, 0x1774),
- (0x1780, 0x17b4),
- (0x17b6, 0x17d4),
- (0x17d7, 0x17d8),
- (0x17dc, 0x17de),
- (0x17e0, 0x17ea),
- (0x1810, 0x181a),
- (0x1820, 0x1878),
- (0x1880, 0x18ab),
- (0x18b0, 0x18f6),
- (0x1900, 0x191d),
- (0x1920, 0x192c),
- (0x1930, 0x193c),
- (0x1946, 0x196e),
- (0x1970, 0x1975),
- (0x1980, 0x19ac),
- (0x19b0, 0x19ca),
- (0x19d0, 0x19da),
- (0x1a00, 0x1a1c),
- (0x1a20, 0x1a5f),
- (0x1a60, 0x1a7d),
- (0x1a7f, 0x1a8a),
- (0x1a90, 0x1a9a),
- (0x1aa7, 0x1aa8),
- (0x1b00, 0x1b4c),
- (0x1b50, 0x1b5a),
- (0x1b6b, 0x1b74),
- (0x1b80, 0x1bf4),
- (0x1c00, 0x1c38),
- (0x1c40, 0x1c4a),
- (0x1c4d, 0x1c7e),
- (0x1cd0, 0x1cd3),
- (0x1cd4, 0x1cf7),
- (0x1d00, 0x1d2c),
- (0x1d2f, 0x1d30),
- (0x1d3b, 0x1d3c),
- (0x1d4e, 0x1d4f),
- (0x1d6b, 0x1d78),
- (0x1d79, 0x1d9b),
- (0x1dc0, 0x1de7),
- (0x1dfc, 0x1e00),
- (0x1e01, 0x1e02),
- (0x1e03, 0x1e04),
- (0x1e05, 0x1e06),
- (0x1e07, 0x1e08),
- (0x1e09, 0x1e0a),
- (0x1e0b, 0x1e0c),
- (0x1e0d, 0x1e0e),
- (0x1e0f, 0x1e10),
- (0x1e11, 0x1e12),
- (0x1e13, 0x1e14),
- (0x1e15, 0x1e16),
- (0x1e17, 0x1e18),
- (0x1e19, 0x1e1a),
- (0x1e1b, 0x1e1c),
- (0x1e1d, 0x1e1e),
- (0x1e1f, 0x1e20),
- (0x1e21, 0x1e22),
- (0x1e23, 0x1e24),
- (0x1e25, 0x1e26),
- (0x1e27, 0x1e28),
- (0x1e29, 0x1e2a),
- (0x1e2b, 0x1e2c),
- (0x1e2d, 0x1e2e),
- (0x1e2f, 0x1e30),
- (0x1e31, 0x1e32),
- (0x1e33, 0x1e34),
- (0x1e35, 0x1e36),
- (0x1e37, 0x1e38),
- (0x1e39, 0x1e3a),
- (0x1e3b, 0x1e3c),
- (0x1e3d, 0x1e3e),
- (0x1e3f, 0x1e40),
- (0x1e41, 0x1e42),
- (0x1e43, 0x1e44),
- (0x1e45, 0x1e46),
- (0x1e47, 0x1e48),
- (0x1e49, 0x1e4a),
- (0x1e4b, 0x1e4c),
- (0x1e4d, 0x1e4e),
- (0x1e4f, 0x1e50),
- (0x1e51, 0x1e52),
- (0x1e53, 0x1e54),
- (0x1e55, 0x1e56),
- (0x1e57, 0x1e58),
- (0x1e59, 0x1e5a),
- (0x1e5b, 0x1e5c),
- (0x1e5d, 0x1e5e),
- (0x1e5f, 0x1e60),
- (0x1e61, 0x1e62),
- (0x1e63, 0x1e64),
- (0x1e65, 0x1e66),
- (0x1e67, 0x1e68),
- (0x1e69, 0x1e6a),
- (0x1e6b, 0x1e6c),
- (0x1e6d, 0x1e6e),
- (0x1e6f, 0x1e70),
- (0x1e71, 0x1e72),
- (0x1e73, 0x1e74),
- (0x1e75, 0x1e76),
- (0x1e77, 0x1e78),
- (0x1e79, 0x1e7a),
- (0x1e7b, 0x1e7c),
- (0x1e7d, 0x1e7e),
- (0x1e7f, 0x1e80),
- (0x1e81, 0x1e82),
- (0x1e83, 0x1e84),
- (0x1e85, 0x1e86),
- (0x1e87, 0x1e88),
- (0x1e89, 0x1e8a),
- (0x1e8b, 0x1e8c),
- (0x1e8d, 0x1e8e),
- (0x1e8f, 0x1e90),
- (0x1e91, 0x1e92),
- (0x1e93, 0x1e94),
- (0x1e95, 0x1e9a),
- (0x1e9c, 0x1e9e),
- (0x1e9f, 0x1ea0),
- (0x1ea1, 0x1ea2),
- (0x1ea3, 0x1ea4),
- (0x1ea5, 0x1ea6),
- (0x1ea7, 0x1ea8),
- (0x1ea9, 0x1eaa),
- (0x1eab, 0x1eac),
- (0x1ead, 0x1eae),
- (0x1eaf, 0x1eb0),
- (0x1eb1, 0x1eb2),
- (0x1eb3, 0x1eb4),
- (0x1eb5, 0x1eb6),
- (0x1eb7, 0x1eb8),
- (0x1eb9, 0x1eba),
- (0x1ebb, 0x1ebc),
- (0x1ebd, 0x1ebe),
- (0x1ebf, 0x1ec0),
- (0x1ec1, 0x1ec2),
- (0x1ec3, 0x1ec4),
- (0x1ec5, 0x1ec6),
- (0x1ec7, 0x1ec8),
- (0x1ec9, 0x1eca),
- (0x1ecb, 0x1ecc),
- (0x1ecd, 0x1ece),
- (0x1ecf, 0x1ed0),
- (0x1ed1, 0x1ed2),
- (0x1ed3, 0x1ed4),
- (0x1ed5, 0x1ed6),
- (0x1ed7, 0x1ed8),
- (0x1ed9, 0x1eda),
- (0x1edb, 0x1edc),
- (0x1edd, 0x1ede),
- (0x1edf, 0x1ee0),
- (0x1ee1, 0x1ee2),
- (0x1ee3, 0x1ee4),
- (0x1ee5, 0x1ee6),
- (0x1ee7, 0x1ee8),
- (0x1ee9, 0x1eea),
- (0x1eeb, 0x1eec),
- (0x1eed, 0x1eee),
- (0x1eef, 0x1ef0),
- (0x1ef1, 0x1ef2),
- (0x1ef3, 0x1ef4),
- (0x1ef5, 0x1ef6),
- (0x1ef7, 0x1ef8),
- (0x1ef9, 0x1efa),
- (0x1efb, 0x1efc),
- (0x1efd, 0x1efe),
- (0x1eff, 0x1f08),
- (0x1f10, 0x1f16),
- (0x1f20, 0x1f28),
- (0x1f30, 0x1f38),
- (0x1f40, 0x1f46),
- (0x1f50, 0x1f58),
- (0x1f60, 0x1f68),
- (0x1f70, 0x1f71),
- (0x1f72, 0x1f73),
- (0x1f74, 0x1f75),
- (0x1f76, 0x1f77),
- (0x1f78, 0x1f79),
- (0x1f7a, 0x1f7b),
- (0x1f7c, 0x1f7d),
- (0x1fb0, 0x1fb2),
- (0x1fb6, 0x1fb7),
- (0x1fc6, 0x1fc7),
- (0x1fd0, 0x1fd3),
- (0x1fd6, 0x1fd8),
- (0x1fe0, 0x1fe3),
- (0x1fe4, 0x1fe8),
- (0x1ff6, 0x1ff7),
- (0x214e, 0x214f),
- (0x2184, 0x2185),
- (0x2c30, 0x2c5f),
- (0x2c61, 0x2c62),
- (0x2c65, 0x2c67),
- (0x2c68, 0x2c69),
- (0x2c6a, 0x2c6b),
- (0x2c6c, 0x2c6d),
- (0x2c71, 0x2c72),
- (0x2c73, 0x2c75),
- (0x2c76, 0x2c7c),
- (0x2c81, 0x2c82),
- (0x2c83, 0x2c84),
- (0x2c85, 0x2c86),
- (0x2c87, 0x2c88),
- (0x2c89, 0x2c8a),
- (0x2c8b, 0x2c8c),
- (0x2c8d, 0x2c8e),
- (0x2c8f, 0x2c90),
- (0x2c91, 0x2c92),
- (0x2c93, 0x2c94),
- (0x2c95, 0x2c96),
- (0x2c97, 0x2c98),
- (0x2c99, 0x2c9a),
- (0x2c9b, 0x2c9c),
- (0x2c9d, 0x2c9e),
- (0x2c9f, 0x2ca0),
- (0x2ca1, 0x2ca2),
- (0x2ca3, 0x2ca4),
- (0x2ca5, 0x2ca6),
- (0x2ca7, 0x2ca8),
- (0x2ca9, 0x2caa),
- (0x2cab, 0x2cac),
- (0x2cad, 0x2cae),
- (0x2caf, 0x2cb0),
- (0x2cb1, 0x2cb2),
- (0x2cb3, 0x2cb4),
- (0x2cb5, 0x2cb6),
- (0x2cb7, 0x2cb8),
- (0x2cb9, 0x2cba),
- (0x2cbb, 0x2cbc),
- (0x2cbd, 0x2cbe),
- (0x2cbf, 0x2cc0),
- (0x2cc1, 0x2cc2),
- (0x2cc3, 0x2cc4),
- (0x2cc5, 0x2cc6),
- (0x2cc7, 0x2cc8),
- (0x2cc9, 0x2cca),
- (0x2ccb, 0x2ccc),
- (0x2ccd, 0x2cce),
- (0x2ccf, 0x2cd0),
- (0x2cd1, 0x2cd2),
- (0x2cd3, 0x2cd4),
- (0x2cd5, 0x2cd6),
- (0x2cd7, 0x2cd8),
- (0x2cd9, 0x2cda),
- (0x2cdb, 0x2cdc),
- (0x2cdd, 0x2cde),
- (0x2cdf, 0x2ce0),
- (0x2ce1, 0x2ce2),
- (0x2ce3, 0x2ce5),
- (0x2cec, 0x2ced),
- (0x2cee, 0x2cf2),
- (0x2cf3, 0x2cf4),
- (0x2d00, 0x2d26),
- (0x2d27, 0x2d28),
- (0x2d2d, 0x2d2e),
- (0x2d30, 0x2d68),
- (0x2d7f, 0x2d97),
- (0x2da0, 0x2da7),
- (0x2da8, 0x2daf),
- (0x2db0, 0x2db7),
- (0x2db8, 0x2dbf),
- (0x2dc0, 0x2dc7),
- (0x2dc8, 0x2dcf),
- (0x2dd0, 0x2dd7),
- (0x2dd8, 0x2ddf),
- (0x2de0, 0x2e00),
- (0x2e2f, 0x2e30),
- (0x3005, 0x3008),
- (0x302a, 0x302e),
- (0x303c, 0x303d),
- (0x3041, 0x3097),
- (0x3099, 0x309b),
- (0x309d, 0x309f),
- (0x30a1, 0x30fb),
- (0x30fc, 0x30ff),
- (0x3105, 0x312e),
- (0x31a0, 0x31bb),
- (0x31f0, 0x3200),
- (0x3400, 0x4db6),
- (0x4e00, 0x9fcd),
- (0xa000, 0xa48d),
- (0xa4d0, 0xa4fe),
- (0xa500, 0xa60d),
- (0xa610, 0xa62c),
- (0xa641, 0xa642),
- (0xa643, 0xa644),
- (0xa645, 0xa646),
- (0xa647, 0xa648),
- (0xa649, 0xa64a),
- (0xa64b, 0xa64c),
- (0xa64d, 0xa64e),
- (0xa64f, 0xa650),
- (0xa651, 0xa652),
- (0xa653, 0xa654),
- (0xa655, 0xa656),
- (0xa657, 0xa658),
- (0xa659, 0xa65a),
- (0xa65b, 0xa65c),
- (0xa65d, 0xa65e),
- (0xa65f, 0xa660),
- (0xa661, 0xa662),
- (0xa663, 0xa664),
- (0xa665, 0xa666),
- (0xa667, 0xa668),
- (0xa669, 0xa66a),
- (0xa66b, 0xa66c),
- (0xa66d, 0xa670),
- (0xa674, 0xa67e),
- (0xa67f, 0xa680),
- (0xa681, 0xa682),
- (0xa683, 0xa684),
- (0xa685, 0xa686),
- (0xa687, 0xa688),
- (0xa689, 0xa68a),
- (0xa68b, 0xa68c),
- (0xa68d, 0xa68e),
- (0xa68f, 0xa690),
- (0xa691, 0xa692),
- (0xa693, 0xa694),
- (0xa695, 0xa696),
- (0xa697, 0xa698),
- (0xa69f, 0xa6e6),
- (0xa6f0, 0xa6f2),
- (0xa717, 0xa720),
- (0xa723, 0xa724),
- (0xa725, 0xa726),
- (0xa727, 0xa728),
- (0xa729, 0xa72a),
- (0xa72b, 0xa72c),
- (0xa72d, 0xa72e),
- (0xa72f, 0xa732),
- (0xa733, 0xa734),
- (0xa735, 0xa736),
- (0xa737, 0xa738),
- (0xa739, 0xa73a),
- (0xa73b, 0xa73c),
- (0xa73d, 0xa73e),
- (0xa73f, 0xa740),
- (0xa741, 0xa742),
- (0xa743, 0xa744),
- (0xa745, 0xa746),
- (0xa747, 0xa748),
- (0xa749, 0xa74a),
- (0xa74b, 0xa74c),
- (0xa74d, 0xa74e),
- (0xa74f, 0xa750),
- (0xa751, 0xa752),
- (0xa753, 0xa754),
- (0xa755, 0xa756),
- (0xa757, 0xa758),
- (0xa759, 0xa75a),
- (0xa75b, 0xa75c),
- (0xa75d, 0xa75e),
- (0xa75f, 0xa760),
- (0xa761, 0xa762),
- (0xa763, 0xa764),
- (0xa765, 0xa766),
- (0xa767, 0xa768),
- (0xa769, 0xa76a),
- (0xa76b, 0xa76c),
- (0xa76d, 0xa76e),
- (0xa76f, 0xa770),
- (0xa771, 0xa779),
- (0xa77a, 0xa77b),
- (0xa77c, 0xa77d),
- (0xa77f, 0xa780),
- (0xa781, 0xa782),
- (0xa783, 0xa784),
- (0xa785, 0xa786),
- (0xa787, 0xa789),
- (0xa78c, 0xa78d),
- (0xa78e, 0xa78f),
- (0xa791, 0xa792),
- (0xa793, 0xa794),
- (0xa7a1, 0xa7a2),
- (0xa7a3, 0xa7a4),
- (0xa7a5, 0xa7a6),
- (0xa7a7, 0xa7a8),
- (0xa7a9, 0xa7aa),
- (0xa7fa, 0xa828),
- (0xa840, 0xa874),
- (0xa880, 0xa8c5),
- (0xa8d0, 0xa8da),
- (0xa8e0, 0xa8f8),
- (0xa8fb, 0xa8fc),
- (0xa900, 0xa92e),
- (0xa930, 0xa954),
- (0xa980, 0xa9c1),
- (0xa9cf, 0xa9da),
- (0xaa00, 0xaa37),
- (0xaa40, 0xaa4e),
- (0xaa50, 0xaa5a),
- (0xaa60, 0xaa77),
- (0xaa7a, 0xaa7c),
- (0xaa80, 0xaac3),
- (0xaadb, 0xaade),
- (0xaae0, 0xaaf0),
- (0xaaf2, 0xaaf7),
- (0xab01, 0xab07),
- (0xab09, 0xab0f),
- (0xab11, 0xab17),
- (0xab20, 0xab27),
- (0xab28, 0xab2f),
- (0xabc0, 0xabeb),
- (0xabec, 0xabee),
- (0xabf0, 0xabfa),
- (0xac00, 0xd7a4),
- (0xfa0e, 0xfa10),
- (0xfa11, 0xfa12),
- (0xfa13, 0xfa15),
- (0xfa1f, 0xfa20),
- (0xfa21, 0xfa22),
- (0xfa23, 0xfa25),
- (0xfa27, 0xfa2a),
- (0xfb1e, 0xfb1f),
- (0xfe20, 0xfe27),
- (0xfe73, 0xfe74),
- (0x10000, 0x1000c),
- (0x1000d, 0x10027),
- (0x10028, 0x1003b),
- (0x1003c, 0x1003e),
- (0x1003f, 0x1004e),
- (0x10050, 0x1005e),
- (0x10080, 0x100fb),
- (0x101fd, 0x101fe),
- (0x10280, 0x1029d),
- (0x102a0, 0x102d1),
- (0x10300, 0x1031f),
- (0x10330, 0x10341),
- (0x10342, 0x1034a),
- (0x10380, 0x1039e),
- (0x103a0, 0x103c4),
- (0x103c8, 0x103d0),
- (0x10428, 0x1049e),
- (0x104a0, 0x104aa),
- (0x10800, 0x10806),
- (0x10808, 0x10809),
- (0x1080a, 0x10836),
- (0x10837, 0x10839),
- (0x1083c, 0x1083d),
- (0x1083f, 0x10856),
- (0x10900, 0x10916),
- (0x10920, 0x1093a),
- (0x10980, 0x109b8),
- (0x109be, 0x109c0),
- (0x10a00, 0x10a04),
- (0x10a05, 0x10a07),
- (0x10a0c, 0x10a14),
- (0x10a15, 0x10a18),
- (0x10a19, 0x10a34),
- (0x10a38, 0x10a3b),
- (0x10a3f, 0x10a40),
- (0x10a60, 0x10a7d),
- (0x10b00, 0x10b36),
- (0x10b40, 0x10b56),
- (0x10b60, 0x10b73),
- (0x10c00, 0x10c49),
- (0x11000, 0x11047),
- (0x11066, 0x11070),
- (0x11080, 0x110bb),
- (0x110d0, 0x110e9),
- (0x110f0, 0x110fa),
- (0x11100, 0x11135),
- (0x11136, 0x11140),
- (0x11180, 0x111c5),
- (0x111d0, 0x111da),
- (0x11680, 0x116b8),
- (0x116c0, 0x116ca),
- (0x12000, 0x1236f),
- (0x13000, 0x1342f),
- (0x16800, 0x16a39),
- (0x16f00, 0x16f45),
- (0x16f50, 0x16f7f),
- (0x16f8f, 0x16fa0),
- (0x1b000, 0x1b002),
- (0x20000, 0x2a6d7),
- (0x2a700, 0x2b735),
- (0x2b740, 0x2b81e),
- ),
- 'CONTEXTJ': (
- (0x200c, 0x200e),
- ),
- 'CONTEXTO': (
- (0xb7, 0xb8),
- (0x375, 0x376),
- (0x5f3, 0x5f5),
- (0x660, 0x66a),
- (0x6f0, 0x6fa),
- (0x30fb, 0x30fc),
- ),
-}
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/intranges.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/intranges.py
deleted file mode 100644
index ee8a175d..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/intranges.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Given a list of integers, made up of (hopefully) a small number of long runs
-of consecutive integers, compute a representation of the form
-((start1, end1), (start2, end2) ...). Then answer the question "was x present
-in the original list?" in time O(log(# runs)).
-"""
-
-import bisect
-
-def intranges_from_list(list_):
- """Represent a list of integers as a sequence of ranges:
- ((start_0, end_0), (start_1, end_1), ...), such that the original
- integers are exactly those x such that start_i <= x < end_i for some i.
- """
-
- sorted_list = sorted(list_)
- ranges = []
- last_write = -1
- for i in range(len(sorted_list)):
- if i+1 < len(sorted_list):
- if sorted_list[i] == sorted_list[i+1]-1:
- continue
- current_range = sorted_list[last_write+1:i+1]
- range_tuple = (current_range[0], current_range[-1] + 1)
- ranges.append(range_tuple)
- last_write = i
-
- return tuple(ranges)
-
-
-def intranges_contain(int_, ranges):
- """Determine if `int_` falls into one of the ranges in `ranges`."""
- tuple_ = (int_, int_)
- pos = bisect.bisect_left(ranges, tuple_)
- # we could be immediately ahead of a tuple (start, end)
- # with start < int_ <= end
- if pos > 0:
- left, right = ranges[pos-1]
- if left <= int_ < right:
- return True
- # or we could be immediately behind a tuple (int_, end)
- if pos < len(ranges):
- left, _ = ranges[pos]
- if left == int_:
- return True
- return False
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/uts46data.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/uts46data.py
deleted file mode 100644
index 48da8408..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/idna/uts46data.py
+++ /dev/null
@@ -1,7633 +0,0 @@
-# This file is automatically generated by tools/build-uts46data.py
-# vim: set fileencoding=utf-8 :
-
-"""IDNA Mapping Table from UTS46."""
-
-
-def _seg_0():
- return [
- (0x0, '3'),
- (0x1, '3'),
- (0x2, '3'),
- (0x3, '3'),
- (0x4, '3'),
- (0x5, '3'),
- (0x6, '3'),
- (0x7, '3'),
- (0x8, '3'),
- (0x9, '3'),
- (0xA, '3'),
- (0xB, '3'),
- (0xC, '3'),
- (0xD, '3'),
- (0xE, '3'),
- (0xF, '3'),
- (0x10, '3'),
- (0x11, '3'),
- (0x12, '3'),
- (0x13, '3'),
- (0x14, '3'),
- (0x15, '3'),
- (0x16, '3'),
- (0x17, '3'),
- (0x18, '3'),
- (0x19, '3'),
- (0x1A, '3'),
- (0x1B, '3'),
- (0x1C, '3'),
- (0x1D, '3'),
- (0x1E, '3'),
- (0x1F, '3'),
- (0x20, '3'),
- (0x21, '3'),
- (0x22, '3'),
- (0x23, '3'),
- (0x24, '3'),
- (0x25, '3'),
- (0x26, '3'),
- (0x27, '3'),
- (0x28, '3'),
- (0x29, '3'),
- (0x2A, '3'),
- (0x2B, '3'),
- (0x2C, '3'),
- (0x2D, 'V'),
- (0x2E, 'V'),
- (0x2F, '3'),
- (0x30, 'V'),
- (0x31, 'V'),
- (0x32, 'V'),
- (0x33, 'V'),
- (0x34, 'V'),
- (0x35, 'V'),
- (0x36, 'V'),
- (0x37, 'V'),
- (0x38, 'V'),
- (0x39, 'V'),
- (0x3A, '3'),
- (0x3B, '3'),
- (0x3C, '3'),
- (0x3D, '3'),
- (0x3E, '3'),
- (0x3F, '3'),
- (0x40, '3'),
- (0x41, 'M', u'a'),
- (0x42, 'M', u'b'),
- (0x43, 'M', u'c'),
- (0x44, 'M', u'd'),
- (0x45, 'M', u'e'),
- (0x46, 'M', u'f'),
- (0x47, 'M', u'g'),
- (0x48, 'M', u'h'),
- (0x49, 'M', u'i'),
- (0x4A, 'M', u'j'),
- (0x4B, 'M', u'k'),
- (0x4C, 'M', u'l'),
- (0x4D, 'M', u'm'),
- (0x4E, 'M', u'n'),
- (0x4F, 'M', u'o'),
- (0x50, 'M', u'p'),
- (0x51, 'M', u'q'),
- (0x52, 'M', u'r'),
- (0x53, 'M', u's'),
- (0x54, 'M', u't'),
- (0x55, 'M', u'u'),
- (0x56, 'M', u'v'),
- (0x57, 'M', u'w'),
- (0x58, 'M', u'x'),
- (0x59, 'M', u'y'),
- (0x5A, 'M', u'z'),
- (0x5B, '3'),
- (0x5C, '3'),
- (0x5D, '3'),
- (0x5E, '3'),
- (0x5F, '3'),
- (0x60, '3'),
- (0x61, 'V'),
- (0x62, 'V'),
- (0x63, 'V'),
- ]
-
-def _seg_1():
- return [
- (0x64, 'V'),
- (0x65, 'V'),
- (0x66, 'V'),
- (0x67, 'V'),
- (0x68, 'V'),
- (0x69, 'V'),
- (0x6A, 'V'),
- (0x6B, 'V'),
- (0x6C, 'V'),
- (0x6D, 'V'),
- (0x6E, 'V'),
- (0x6F, 'V'),
- (0x70, 'V'),
- (0x71, 'V'),
- (0x72, 'V'),
- (0x73, 'V'),
- (0x74, 'V'),
- (0x75, 'V'),
- (0x76, 'V'),
- (0x77, 'V'),
- (0x78, 'V'),
- (0x79, 'V'),
- (0x7A, 'V'),
- (0x7B, '3'),
- (0x7C, '3'),
- (0x7D, '3'),
- (0x7E, '3'),
- (0x7F, '3'),
- (0x80, 'X'),
- (0x81, 'X'),
- (0x82, 'X'),
- (0x83, 'X'),
- (0x84, 'X'),
- (0x85, 'X'),
- (0x86, 'X'),
- (0x87, 'X'),
- (0x88, 'X'),
- (0x89, 'X'),
- (0x8A, 'X'),
- (0x8B, 'X'),
- (0x8C, 'X'),
- (0x8D, 'X'),
- (0x8E, 'X'),
- (0x8F, 'X'),
- (0x90, 'X'),
- (0x91, 'X'),
- (0x92, 'X'),
- (0x93, 'X'),
- (0x94, 'X'),
- (0x95, 'X'),
- (0x96, 'X'),
- (0x97, 'X'),
- (0x98, 'X'),
- (0x99, 'X'),
- (0x9A, 'X'),
- (0x9B, 'X'),
- (0x9C, 'X'),
- (0x9D, 'X'),
- (0x9E, 'X'),
- (0x9F, 'X'),
- (0xA0, '3', u' '),
- (0xA1, 'V'),
- (0xA2, 'V'),
- (0xA3, 'V'),
- (0xA4, 'V'),
- (0xA5, 'V'),
- (0xA6, 'V'),
- (0xA7, 'V'),
- (0xA8, '3', u' ̈'),
- (0xA9, 'V'),
- (0xAA, 'M', u'a'),
- (0xAB, 'V'),
- (0xAC, 'V'),
- (0xAD, 'I'),
- (0xAE, 'V'),
- (0xAF, '3', u' Ì„'),
- (0xB0, 'V'),
- (0xB1, 'V'),
- (0xB2, 'M', u'2'),
- (0xB3, 'M', u'3'),
- (0xB4, '3', u' Ì'),
- (0xB5, 'M', u'μ'),
- (0xB6, 'V'),
- (0xB7, 'V'),
- (0xB8, '3', u' ̧'),
- (0xB9, 'M', u'1'),
- (0xBA, 'M', u'o'),
- (0xBB, 'V'),
- (0xBC, 'M', u'1â„4'),
- (0xBD, 'M', u'1â„2'),
- (0xBE, 'M', u'3â„4'),
- (0xBF, 'V'),
- (0xC0, 'M', u'à'),
- (0xC1, 'M', u'á'),
- (0xC2, 'M', u'â'),
- (0xC3, 'M', u'ã'),
- (0xC4, 'M', u'ä'),
- (0xC5, 'M', u'Ã¥'),
- (0xC6, 'M', u'æ'),
- (0xC7, 'M', u'ç'),
- ]
-
-def _seg_2():
- return [
- (0xC8, 'M', u'è'),
- (0xC9, 'M', u'é'),
- (0xCA, 'M', u'ê'),
- (0xCB, 'M', u'ë'),
- (0xCC, 'M', u'ì'),
- (0xCD, 'M', u'í'),
- (0xCE, 'M', u'î'),
- (0xCF, 'M', u'ï'),
- (0xD0, 'M', u'ð'),
- (0xD1, 'M', u'ñ'),
- (0xD2, 'M', u'ò'),
- (0xD3, 'M', u'ó'),
- (0xD4, 'M', u'ô'),
- (0xD5, 'M', u'õ'),
- (0xD6, 'M', u'ö'),
- (0xD7, 'V'),
- (0xD8, 'M', u'ø'),
- (0xD9, 'M', u'ù'),
- (0xDA, 'M', u'ú'),
- (0xDB, 'M', u'û'),
- (0xDC, 'M', u'ü'),
- (0xDD, 'M', u'ý'),
- (0xDE, 'M', u'þ'),
- (0xDF, 'D', u'ss'),
- (0xE0, 'V'),
- (0xE1, 'V'),
- (0xE2, 'V'),
- (0xE3, 'V'),
- (0xE4, 'V'),
- (0xE5, 'V'),
- (0xE6, 'V'),
- (0xE7, 'V'),
- (0xE8, 'V'),
- (0xE9, 'V'),
- (0xEA, 'V'),
- (0xEB, 'V'),
- (0xEC, 'V'),
- (0xED, 'V'),
- (0xEE, 'V'),
- (0xEF, 'V'),
- (0xF0, 'V'),
- (0xF1, 'V'),
- (0xF2, 'V'),
- (0xF3, 'V'),
- (0xF4, 'V'),
- (0xF5, 'V'),
- (0xF6, 'V'),
- (0xF7, 'V'),
- (0xF8, 'V'),
- (0xF9, 'V'),
- (0xFA, 'V'),
- (0xFB, 'V'),
- (0xFC, 'V'),
- (0xFD, 'V'),
- (0xFE, 'V'),
- (0xFF, 'V'),
- (0x100, 'M', u'Ä'),
- (0x101, 'V'),
- (0x102, 'M', u'ă'),
- (0x103, 'V'),
- (0x104, 'M', u'Ä…'),
- (0x105, 'V'),
- (0x106, 'M', u'ć'),
- (0x107, 'V'),
- (0x108, 'M', u'ĉ'),
- (0x109, 'V'),
- (0x10A, 'M', u'Ä‹'),
- (0x10B, 'V'),
- (0x10C, 'M', u'Ä'),
- (0x10D, 'V'),
- (0x10E, 'M', u'Ä'),
- (0x10F, 'V'),
- (0x110, 'M', u'Ä‘'),
- (0x111, 'V'),
- (0x112, 'M', u'Ä“'),
- (0x113, 'V'),
- (0x114, 'M', u'Ä•'),
- (0x115, 'V'),
- (0x116, 'M', u'Ä—'),
- (0x117, 'V'),
- (0x118, 'M', u'Ä™'),
- (0x119, 'V'),
- (0x11A, 'M', u'Ä›'),
- (0x11B, 'V'),
- (0x11C, 'M', u'Ä'),
- (0x11D, 'V'),
- (0x11E, 'M', u'ÄŸ'),
- (0x11F, 'V'),
- (0x120, 'M', u'Ä¡'),
- (0x121, 'V'),
- (0x122, 'M', u'Ä£'),
- (0x123, 'V'),
- (0x124, 'M', u'Ä¥'),
- (0x125, 'V'),
- (0x126, 'M', u'ħ'),
- (0x127, 'V'),
- (0x128, 'M', u'Ä©'),
- (0x129, 'V'),
- (0x12A, 'M', u'Ä«'),
- (0x12B, 'V'),
- ]
-
-def _seg_3():
- return [
- (0x12C, 'M', u'Ä­'),
- (0x12D, 'V'),
- (0x12E, 'M', u'į'),
- (0x12F, 'V'),
- (0x130, 'M', u'i̇'),
- (0x131, 'V'),
- (0x132, 'M', u'ij'),
- (0x134, 'M', u'ĵ'),
- (0x135, 'V'),
- (0x136, 'M', u'Ä·'),
- (0x137, 'V'),
- (0x139, 'M', u'ĺ'),
- (0x13A, 'V'),
- (0x13B, 'M', u'ļ'),
- (0x13C, 'V'),
- (0x13D, 'M', u'ľ'),
- (0x13E, 'V'),
- (0x13F, 'M', u'l·'),
- (0x141, 'M', u'Å‚'),
- (0x142, 'V'),
- (0x143, 'M', u'Å„'),
- (0x144, 'V'),
- (0x145, 'M', u'ņ'),
- (0x146, 'V'),
- (0x147, 'M', u'ň'),
- (0x148, 'V'),
- (0x149, 'M', u'ʼn'),
- (0x14A, 'M', u'Å‹'),
- (0x14B, 'V'),
- (0x14C, 'M', u'Å'),
- (0x14D, 'V'),
- (0x14E, 'M', u'Å'),
- (0x14F, 'V'),
- (0x150, 'M', u'Å‘'),
- (0x151, 'V'),
- (0x152, 'M', u'Å“'),
- (0x153, 'V'),
- (0x154, 'M', u'Å•'),
- (0x155, 'V'),
- (0x156, 'M', u'Å—'),
- (0x157, 'V'),
- (0x158, 'M', u'Å™'),
- (0x159, 'V'),
- (0x15A, 'M', u'Å›'),
- (0x15B, 'V'),
- (0x15C, 'M', u'Å'),
- (0x15D, 'V'),
- (0x15E, 'M', u'ÅŸ'),
- (0x15F, 'V'),
- (0x160, 'M', u'Å¡'),
- (0x161, 'V'),
- (0x162, 'M', u'Å£'),
- (0x163, 'V'),
- (0x164, 'M', u'Å¥'),
- (0x165, 'V'),
- (0x166, 'M', u'ŧ'),
- (0x167, 'V'),
- (0x168, 'M', u'Å©'),
- (0x169, 'V'),
- (0x16A, 'M', u'Å«'),
- (0x16B, 'V'),
- (0x16C, 'M', u'Å­'),
- (0x16D, 'V'),
- (0x16E, 'M', u'ů'),
- (0x16F, 'V'),
- (0x170, 'M', u'ű'),
- (0x171, 'V'),
- (0x172, 'M', u'ų'),
- (0x173, 'V'),
- (0x174, 'M', u'ŵ'),
- (0x175, 'V'),
- (0x176, 'M', u'Å·'),
- (0x177, 'V'),
- (0x178, 'M', u'ÿ'),
- (0x179, 'M', u'ź'),
- (0x17A, 'V'),
- (0x17B, 'M', u'ż'),
- (0x17C, 'V'),
- (0x17D, 'M', u'ž'),
- (0x17E, 'V'),
- (0x17F, 'M', u's'),
- (0x180, 'V'),
- (0x181, 'M', u'É“'),
- (0x182, 'M', u'ƃ'),
- (0x183, 'V'),
- (0x184, 'M', u'Æ…'),
- (0x185, 'V'),
- (0x186, 'M', u'É”'),
- (0x187, 'M', u'ƈ'),
- (0x188, 'V'),
- (0x189, 'M', u'É–'),
- (0x18A, 'M', u'É—'),
- (0x18B, 'M', u'ƌ'),
- (0x18C, 'V'),
- (0x18E, 'M', u'Ç'),
- (0x18F, 'M', u'É™'),
- (0x190, 'M', u'É›'),
- (0x191, 'M', u'Æ’'),
- (0x192, 'V'),
- (0x193, 'M', u'É '),
- ]
-
-def _seg_4():
- return [
- (0x194, 'M', u'É£'),
- (0x195, 'V'),
- (0x196, 'M', u'É©'),
- (0x197, 'M', u'ɨ'),
- (0x198, 'M', u'Æ™'),
- (0x199, 'V'),
- (0x19C, 'M', u'ɯ'),
- (0x19D, 'M', u'ɲ'),
- (0x19E, 'V'),
- (0x19F, 'M', u'ɵ'),
- (0x1A0, 'M', u'Æ¡'),
- (0x1A1, 'V'),
- (0x1A2, 'M', u'Æ£'),
- (0x1A3, 'V'),
- (0x1A4, 'M', u'Æ¥'),
- (0x1A5, 'V'),
- (0x1A6, 'M', u'Ê€'),
- (0x1A7, 'M', u'ƨ'),
- (0x1A8, 'V'),
- (0x1A9, 'M', u'ʃ'),
- (0x1AA, 'V'),
- (0x1AC, 'M', u'Æ­'),
- (0x1AD, 'V'),
- (0x1AE, 'M', u'ʈ'),
- (0x1AF, 'M', u'Æ°'),
- (0x1B0, 'V'),
- (0x1B1, 'M', u'ÊŠ'),
- (0x1B2, 'M', u'Ê‹'),
- (0x1B3, 'M', u'Æ´'),
- (0x1B4, 'V'),
- (0x1B5, 'M', u'ƶ'),
- (0x1B6, 'V'),
- (0x1B7, 'M', u'Ê’'),
- (0x1B8, 'M', u'ƹ'),
- (0x1B9, 'V'),
- (0x1BC, 'M', u'ƽ'),
- (0x1BD, 'V'),
- (0x1C4, 'M', u'dž'),
- (0x1C7, 'M', u'lj'),
- (0x1CA, 'M', u'nj'),
- (0x1CD, 'M', u'ÇŽ'),
- (0x1CE, 'V'),
- (0x1CF, 'M', u'Ç'),
- (0x1D0, 'V'),
- (0x1D1, 'M', u'Ç’'),
- (0x1D2, 'V'),
- (0x1D3, 'M', u'Ç”'),
- (0x1D4, 'V'),
- (0x1D5, 'M', u'Ç–'),
- (0x1D6, 'V'),
- (0x1D7, 'M', u'ǘ'),
- (0x1D8, 'V'),
- (0x1D9, 'M', u'Çš'),
- (0x1DA, 'V'),
- (0x1DB, 'M', u'ǜ'),
- (0x1DC, 'V'),
- (0x1DE, 'M', u'ÇŸ'),
- (0x1DF, 'V'),
- (0x1E0, 'M', u'Ç¡'),
- (0x1E1, 'V'),
- (0x1E2, 'M', u'Ç£'),
- (0x1E3, 'V'),
- (0x1E4, 'M', u'Ç¥'),
- (0x1E5, 'V'),
- (0x1E6, 'M', u'ǧ'),
- (0x1E7, 'V'),
- (0x1E8, 'M', u'Ç©'),
- (0x1E9, 'V'),
- (0x1EA, 'M', u'Ç«'),
- (0x1EB, 'V'),
- (0x1EC, 'M', u'Ç­'),
- (0x1ED, 'V'),
- (0x1EE, 'M', u'ǯ'),
- (0x1EF, 'V'),
- (0x1F1, 'M', u'dz'),
- (0x1F4, 'M', u'ǵ'),
- (0x1F5, 'V'),
- (0x1F6, 'M', u'Æ•'),
- (0x1F7, 'M', u'Æ¿'),
- (0x1F8, 'M', u'ǹ'),
- (0x1F9, 'V'),
- (0x1FA, 'M', u'Ç»'),
- (0x1FB, 'V'),
- (0x1FC, 'M', u'ǽ'),
- (0x1FD, 'V'),
- (0x1FE, 'M', u'Ç¿'),
- (0x1FF, 'V'),
- (0x200, 'M', u'È'),
- (0x201, 'V'),
- (0x202, 'M', u'ȃ'),
- (0x203, 'V'),
- (0x204, 'M', u'È…'),
- (0x205, 'V'),
- (0x206, 'M', u'ȇ'),
- (0x207, 'V'),
- (0x208, 'M', u'ȉ'),
- (0x209, 'V'),
- (0x20A, 'M', u'È‹'),
- (0x20B, 'V'),
- (0x20C, 'M', u'È'),
- ]
-
-def _seg_5():
- return [
- (0x20D, 'V'),
- (0x20E, 'M', u'È'),
- (0x20F, 'V'),
- (0x210, 'M', u'È‘'),
- (0x211, 'V'),
- (0x212, 'M', u'È“'),
- (0x213, 'V'),
- (0x214, 'M', u'È•'),
- (0x215, 'V'),
- (0x216, 'M', u'È—'),
- (0x217, 'V'),
- (0x218, 'M', u'È™'),
- (0x219, 'V'),
- (0x21A, 'M', u'È›'),
- (0x21B, 'V'),
- (0x21C, 'M', u'È'),
- (0x21D, 'V'),
- (0x21E, 'M', u'ÈŸ'),
- (0x21F, 'V'),
- (0x220, 'M', u'Æž'),
- (0x221, 'V'),
- (0x222, 'M', u'È£'),
- (0x223, 'V'),
- (0x224, 'M', u'È¥'),
- (0x225, 'V'),
- (0x226, 'M', u'ȧ'),
- (0x227, 'V'),
- (0x228, 'M', u'È©'),
- (0x229, 'V'),
- (0x22A, 'M', u'È«'),
- (0x22B, 'V'),
- (0x22C, 'M', u'È­'),
- (0x22D, 'V'),
- (0x22E, 'M', u'ȯ'),
- (0x22F, 'V'),
- (0x230, 'M', u'ȱ'),
- (0x231, 'V'),
- (0x232, 'M', u'ȳ'),
- (0x233, 'V'),
- (0x23A, 'M', u'â±¥'),
- (0x23B, 'M', u'ȼ'),
- (0x23C, 'V'),
- (0x23D, 'M', u'Æš'),
- (0x23E, 'M', u'ⱦ'),
- (0x23F, 'V'),
- (0x241, 'M', u'É‚'),
- (0x242, 'V'),
- (0x243, 'M', u'Æ€'),
- (0x244, 'M', u'ʉ'),
- (0x245, 'M', u'ʌ'),
- (0x246, 'M', u'ɇ'),
- (0x247, 'V'),
- (0x248, 'M', u'ɉ'),
- (0x249, 'V'),
- (0x24A, 'M', u'É‹'),
- (0x24B, 'V'),
- (0x24C, 'M', u'É'),
- (0x24D, 'V'),
- (0x24E, 'M', u'É'),
- (0x24F, 'V'),
- (0x2B0, 'M', u'h'),
- (0x2B1, 'M', u'ɦ'),
- (0x2B2, 'M', u'j'),
- (0x2B3, 'M', u'r'),
- (0x2B4, 'M', u'ɹ'),
- (0x2B5, 'M', u'É»'),
- (0x2B6, 'M', u'Ê'),
- (0x2B7, 'M', u'w'),
- (0x2B8, 'M', u'y'),
- (0x2B9, 'V'),
- (0x2D8, '3', u' ̆'),
- (0x2D9, '3', u' ̇'),
- (0x2DA, '3', u' ÌŠ'),
- (0x2DB, '3', u' ̨'),
- (0x2DC, '3', u' ̃'),
- (0x2DD, '3', u' Ì‹'),
- (0x2DE, 'V'),
- (0x2E0, 'M', u'É£'),
- (0x2E1, 'M', u'l'),
- (0x2E2, 'M', u's'),
- (0x2E3, 'M', u'x'),
- (0x2E4, 'M', u'Ê•'),
- (0x2E5, 'V'),
- (0x340, 'M', u'Ì€'),
- (0x341, 'M', u'Ì'),
- (0x342, 'V'),
- (0x343, 'M', u'Ì“'),
- (0x344, 'M', u'̈Ì'),
- (0x345, 'M', u'ι'),
- (0x346, 'V'),
- (0x34F, 'I'),
- (0x350, 'V'),
- (0x370, 'M', u'ͱ'),
- (0x371, 'V'),
- (0x372, 'M', u'ͳ'),
- (0x373, 'V'),
- (0x374, 'M', u'ʹ'),
- (0x375, 'V'),
- (0x376, 'M', u'Í·'),
- (0x377, 'V'),
- ]
-
-def _seg_6():
- return [
- (0x378, 'X'),
- (0x37A, '3', u' ι'),
- (0x37B, 'V'),
- (0x37E, '3', u';'),
- (0x37F, 'X'),
- (0x384, '3', u' Ì'),
- (0x385, '3', u' ̈Ì'),
- (0x386, 'M', u'ά'),
- (0x387, 'M', u'·'),
- (0x388, 'M', u'έ'),
- (0x389, 'M', u'ή'),
- (0x38A, 'M', u'ί'),
- (0x38B, 'X'),
- (0x38C, 'M', u'ό'),
- (0x38D, 'X'),
- (0x38E, 'M', u'Ï'),
- (0x38F, 'M', u'ÏŽ'),
- (0x390, 'V'),
- (0x391, 'M', u'α'),
- (0x392, 'M', u'β'),
- (0x393, 'M', u'γ'),
- (0x394, 'M', u'δ'),
- (0x395, 'M', u'ε'),
- (0x396, 'M', u'ζ'),
- (0x397, 'M', u'η'),
- (0x398, 'M', u'θ'),
- (0x399, 'M', u'ι'),
- (0x39A, 'M', u'κ'),
- (0x39B, 'M', u'λ'),
- (0x39C, 'M', u'μ'),
- (0x39D, 'M', u'ν'),
- (0x39E, 'M', u'ξ'),
- (0x39F, 'M', u'ο'),
- (0x3A0, 'M', u'Ï€'),
- (0x3A1, 'M', u'Ï'),
- (0x3A2, 'X'),
- (0x3A3, 'M', u'σ'),
- (0x3A4, 'M', u'Ï„'),
- (0x3A5, 'M', u'Ï…'),
- (0x3A6, 'M', u'φ'),
- (0x3A7, 'M', u'χ'),
- (0x3A8, 'M', u'ψ'),
- (0x3A9, 'M', u'ω'),
- (0x3AA, 'M', u'ÏŠ'),
- (0x3AB, 'M', u'Ï‹'),
- (0x3AC, 'V'),
- (0x3C2, 'D', u'σ'),
- (0x3C3, 'V'),
- (0x3CF, 'M', u'Ï—'),
- (0x3D0, 'M', u'β'),
- (0x3D1, 'M', u'θ'),
- (0x3D2, 'M', u'Ï…'),
- (0x3D3, 'M', u'Ï'),
- (0x3D4, 'M', u'Ï‹'),
- (0x3D5, 'M', u'φ'),
- (0x3D6, 'M', u'Ï€'),
- (0x3D7, 'V'),
- (0x3D8, 'M', u'Ï™'),
- (0x3D9, 'V'),
- (0x3DA, 'M', u'Ï›'),
- (0x3DB, 'V'),
- (0x3DC, 'M', u'Ï'),
- (0x3DD, 'V'),
- (0x3DE, 'M', u'ÏŸ'),
- (0x3DF, 'V'),
- (0x3E0, 'M', u'Ï¡'),
- (0x3E1, 'V'),
- (0x3E2, 'M', u'Ï£'),
- (0x3E3, 'V'),
- (0x3E4, 'M', u'Ï¥'),
- (0x3E5, 'V'),
- (0x3E6, 'M', u'ϧ'),
- (0x3E7, 'V'),
- (0x3E8, 'M', u'Ï©'),
- (0x3E9, 'V'),
- (0x3EA, 'M', u'Ï«'),
- (0x3EB, 'V'),
- (0x3EC, 'M', u'Ï­'),
- (0x3ED, 'V'),
- (0x3EE, 'M', u'ϯ'),
- (0x3EF, 'V'),
- (0x3F0, 'M', u'κ'),
- (0x3F1, 'M', u'Ï'),
- (0x3F2, 'M', u'σ'),
- (0x3F3, 'V'),
- (0x3F4, 'M', u'θ'),
- (0x3F5, 'M', u'ε'),
- (0x3F6, 'V'),
- (0x3F7, 'M', u'ϸ'),
- (0x3F8, 'V'),
- (0x3F9, 'M', u'σ'),
- (0x3FA, 'M', u'Ï»'),
- (0x3FB, 'V'),
- (0x3FD, 'M', u'Í»'),
- (0x3FE, 'M', u'ͼ'),
- (0x3FF, 'M', u'ͽ'),
- (0x400, 'M', u'Ñ'),
- (0x401, 'M', u'Ñ‘'),
- (0x402, 'M', u'Ñ’'),
- (0x403, 'M', u'Ñ“'),
- ]
-
-def _seg_7():
- return [
- (0x404, 'M', u'Ñ”'),
- (0x405, 'M', u'Ñ•'),
- (0x406, 'M', u'Ñ–'),
- (0x407, 'M', u'Ñ—'),
- (0x408, 'M', u'ј'),
- (0x409, 'M', u'Ñ™'),
- (0x40A, 'M', u'Ñš'),
- (0x40B, 'M', u'Ñ›'),
- (0x40C, 'M', u'ќ'),
- (0x40D, 'M', u'Ñ'),
- (0x40E, 'M', u'Ñž'),
- (0x40F, 'M', u'ÑŸ'),
- (0x410, 'M', u'а'),
- (0x411, 'M', u'б'),
- (0x412, 'M', u'в'),
- (0x413, 'M', u'г'),
- (0x414, 'M', u'д'),
- (0x415, 'M', u'е'),
- (0x416, 'M', u'ж'),
- (0x417, 'M', u'з'),
- (0x418, 'M', u'и'),
- (0x419, 'M', u'й'),
- (0x41A, 'M', u'к'),
- (0x41B, 'M', u'л'),
- (0x41C, 'M', u'м'),
- (0x41D, 'M', u'н'),
- (0x41E, 'M', u'о'),
- (0x41F, 'M', u'п'),
- (0x420, 'M', u'Ñ€'),
- (0x421, 'M', u'Ñ'),
- (0x422, 'M', u'Ñ‚'),
- (0x423, 'M', u'у'),
- (0x424, 'M', u'Ñ„'),
- (0x425, 'M', u'Ñ…'),
- (0x426, 'M', u'ц'),
- (0x427, 'M', u'ч'),
- (0x428, 'M', u'ш'),
- (0x429, 'M', u'щ'),
- (0x42A, 'M', u'ÑŠ'),
- (0x42B, 'M', u'Ñ‹'),
- (0x42C, 'M', u'ь'),
- (0x42D, 'M', u'Ñ'),
- (0x42E, 'M', u'ÑŽ'),
- (0x42F, 'M', u'Ñ'),
- (0x430, 'V'),
- (0x460, 'M', u'Ñ¡'),
- (0x461, 'V'),
- (0x462, 'M', u'Ñ£'),
- (0x463, 'V'),
- (0x464, 'M', u'Ñ¥'),
- (0x465, 'V'),
- (0x466, 'M', u'ѧ'),
- (0x467, 'V'),
- (0x468, 'M', u'Ñ©'),
- (0x469, 'V'),
- (0x46A, 'M', u'Ñ«'),
- (0x46B, 'V'),
- (0x46C, 'M', u'Ñ­'),
- (0x46D, 'V'),
- (0x46E, 'M', u'ѯ'),
- (0x46F, 'V'),
- (0x470, 'M', u'ѱ'),
- (0x471, 'V'),
- (0x472, 'M', u'ѳ'),
- (0x473, 'V'),
- (0x474, 'M', u'ѵ'),
- (0x475, 'V'),
- (0x476, 'M', u'Ñ·'),
- (0x477, 'V'),
- (0x478, 'M', u'ѹ'),
- (0x479, 'V'),
- (0x47A, 'M', u'Ñ»'),
- (0x47B, 'V'),
- (0x47C, 'M', u'ѽ'),
- (0x47D, 'V'),
- (0x47E, 'M', u'Ñ¿'),
- (0x47F, 'V'),
- (0x480, 'M', u'Ò'),
- (0x481, 'V'),
- (0x48A, 'M', u'Ò‹'),
- (0x48B, 'V'),
- (0x48C, 'M', u'Ò'),
- (0x48D, 'V'),
- (0x48E, 'M', u'Ò'),
- (0x48F, 'V'),
- (0x490, 'M', u'Ò‘'),
- (0x491, 'V'),
- (0x492, 'M', u'Ò“'),
- (0x493, 'V'),
- (0x494, 'M', u'Ò•'),
- (0x495, 'V'),
- (0x496, 'M', u'Ò—'),
- (0x497, 'V'),
- (0x498, 'M', u'Ò™'),
- (0x499, 'V'),
- (0x49A, 'M', u'Ò›'),
- (0x49B, 'V'),
- (0x49C, 'M', u'Ò'),
- (0x49D, 'V'),
- (0x49E, 'M', u'ÒŸ'),
- ]
-
-def _seg_8():
- return [
- (0x49F, 'V'),
- (0x4A0, 'M', u'Ò¡'),
- (0x4A1, 'V'),
- (0x4A2, 'M', u'Ò£'),
- (0x4A3, 'V'),
- (0x4A4, 'M', u'Ò¥'),
- (0x4A5, 'V'),
- (0x4A6, 'M', u'Ò§'),
- (0x4A7, 'V'),
- (0x4A8, 'M', u'Ò©'),
- (0x4A9, 'V'),
- (0x4AA, 'M', u'Ò«'),
- (0x4AB, 'V'),
- (0x4AC, 'M', u'Ò­'),
- (0x4AD, 'V'),
- (0x4AE, 'M', u'Ò¯'),
- (0x4AF, 'V'),
- (0x4B0, 'M', u'Ò±'),
- (0x4B1, 'V'),
- (0x4B2, 'M', u'Ò³'),
- (0x4B3, 'V'),
- (0x4B4, 'M', u'Òµ'),
- (0x4B5, 'V'),
- (0x4B6, 'M', u'Ò·'),
- (0x4B7, 'V'),
- (0x4B8, 'M', u'Ò¹'),
- (0x4B9, 'V'),
- (0x4BA, 'M', u'Ò»'),
- (0x4BB, 'V'),
- (0x4BC, 'M', u'Ò½'),
- (0x4BD, 'V'),
- (0x4BE, 'M', u'Ò¿'),
- (0x4BF, 'V'),
- (0x4C0, 'X'),
- (0x4C1, 'M', u'Ó‚'),
- (0x4C2, 'V'),
- (0x4C3, 'M', u'Ó„'),
- (0x4C4, 'V'),
- (0x4C5, 'M', u'Ó†'),
- (0x4C6, 'V'),
- (0x4C7, 'M', u'Óˆ'),
- (0x4C8, 'V'),
- (0x4C9, 'M', u'ÓŠ'),
- (0x4CA, 'V'),
- (0x4CB, 'M', u'ӌ'),
- (0x4CC, 'V'),
- (0x4CD, 'M', u'ÓŽ'),
- (0x4CE, 'V'),
- (0x4D0, 'M', u'Ó‘'),
- (0x4D1, 'V'),
- (0x4D2, 'M', u'Ó“'),
- (0x4D3, 'V'),
- (0x4D4, 'M', u'Ó•'),
- (0x4D5, 'V'),
- (0x4D6, 'M', u'Ó—'),
- (0x4D7, 'V'),
- (0x4D8, 'M', u'Ó™'),
- (0x4D9, 'V'),
- (0x4DA, 'M', u'Ó›'),
- (0x4DB, 'V'),
- (0x4DC, 'M', u'Ó'),
- (0x4DD, 'V'),
- (0x4DE, 'M', u'ÓŸ'),
- (0x4DF, 'V'),
- (0x4E0, 'M', u'Ó¡'),
- (0x4E1, 'V'),
- (0x4E2, 'M', u'Ó£'),
- (0x4E3, 'V'),
- (0x4E4, 'M', u'Ó¥'),
- (0x4E5, 'V'),
- (0x4E6, 'M', u'Ó§'),
- (0x4E7, 'V'),
- (0x4E8, 'M', u'Ó©'),
- (0x4E9, 'V'),
- (0x4EA, 'M', u'Ó«'),
- (0x4EB, 'V'),
- (0x4EC, 'M', u'Ó­'),
- (0x4ED, 'V'),
- (0x4EE, 'M', u'Ó¯'),
- (0x4EF, 'V'),
- (0x4F0, 'M', u'Ó±'),
- (0x4F1, 'V'),
- (0x4F2, 'M', u'Ó³'),
- (0x4F3, 'V'),
- (0x4F4, 'M', u'Óµ'),
- (0x4F5, 'V'),
- (0x4F6, 'M', u'Ó·'),
- (0x4F7, 'V'),
- (0x4F8, 'M', u'Ó¹'),
- (0x4F9, 'V'),
- (0x4FA, 'M', u'Ó»'),
- (0x4FB, 'V'),
- (0x4FC, 'M', u'Ó½'),
- (0x4FD, 'V'),
- (0x4FE, 'M', u'Ó¿'),
- (0x4FF, 'V'),
- (0x500, 'M', u'Ô'),
- (0x501, 'V'),
- (0x502, 'M', u'Ôƒ'),
- (0x503, 'V'),
- ]
-
-def _seg_9():
- return [
- (0x504, 'M', u'Ô…'),
- (0x505, 'V'),
- (0x506, 'M', u'Ô‡'),
- (0x507, 'V'),
- (0x508, 'M', u'Ô‰'),
- (0x509, 'V'),
- (0x50A, 'M', u'Ô‹'),
- (0x50B, 'V'),
- (0x50C, 'M', u'Ô'),
- (0x50D, 'V'),
- (0x50E, 'M', u'Ô'),
- (0x50F, 'V'),
- (0x510, 'M', u'Ô‘'),
- (0x511, 'V'),
- (0x512, 'M', u'Ô“'),
- (0x513, 'V'),
- (0x514, 'M', u'Ô•'),
- (0x515, 'V'),
- (0x516, 'M', u'Ô—'),
- (0x517, 'V'),
- (0x518, 'M', u'Ô™'),
- (0x519, 'V'),
- (0x51A, 'M', u'Ô›'),
- (0x51B, 'V'),
- (0x51C, 'M', u'Ô'),
- (0x51D, 'V'),
- (0x51E, 'M', u'ÔŸ'),
- (0x51F, 'V'),
- (0x520, 'M', u'Ô¡'),
- (0x521, 'V'),
- (0x522, 'M', u'Ô£'),
- (0x523, 'V'),
- (0x524, 'M', u'Ô¥'),
- (0x525, 'V'),
- (0x526, 'M', u'Ô§'),
- (0x527, 'V'),
- (0x528, 'X'),
- (0x531, 'M', u'Õ¡'),
- (0x532, 'M', u'Õ¢'),
- (0x533, 'M', u'Õ£'),
- (0x534, 'M', u'Õ¤'),
- (0x535, 'M', u'Õ¥'),
- (0x536, 'M', u'Õ¦'),
- (0x537, 'M', u'Õ§'),
- (0x538, 'M', u'Õ¨'),
- (0x539, 'M', u'Õ©'),
- (0x53A, 'M', u'Õª'),
- (0x53B, 'M', u'Õ«'),
- (0x53C, 'M', u'Õ¬'),
- (0x53D, 'M', u'Õ­'),
- (0x53E, 'M', u'Õ®'),
- (0x53F, 'M', u'Õ¯'),
- (0x540, 'M', u'Õ°'),
- (0x541, 'M', u'Õ±'),
- (0x542, 'M', u'Õ²'),
- (0x543, 'M', u'Õ³'),
- (0x544, 'M', u'Õ´'),
- (0x545, 'M', u'Õµ'),
- (0x546, 'M', u'Õ¶'),
- (0x547, 'M', u'Õ·'),
- (0x548, 'M', u'Õ¸'),
- (0x549, 'M', u'Õ¹'),
- (0x54A, 'M', u'Õº'),
- (0x54B, 'M', u'Õ»'),
- (0x54C, 'M', u'Õ¼'),
- (0x54D, 'M', u'Õ½'),
- (0x54E, 'M', u'Õ¾'),
- (0x54F, 'M', u'Õ¿'),
- (0x550, 'M', u'Ö€'),
- (0x551, 'M', u'Ö'),
- (0x552, 'M', u'Ö‚'),
- (0x553, 'M', u'Öƒ'),
- (0x554, 'M', u'Ö„'),
- (0x555, 'M', u'Ö…'),
- (0x556, 'M', u'Ö†'),
- (0x557, 'X'),
- (0x559, 'V'),
- (0x560, 'X'),
- (0x561, 'V'),
- (0x587, 'M', u'Õ¥Ö‚'),
- (0x588, 'X'),
- (0x589, 'V'),
- (0x58B, 'X'),
- (0x58F, 'V'),
- (0x590, 'X'),
- (0x591, 'V'),
- (0x5C8, 'X'),
- (0x5D0, 'V'),
- (0x5EB, 'X'),
- (0x5F0, 'V'),
- (0x5F5, 'X'),
- (0x606, 'V'),
- (0x61C, 'X'),
- (0x61E, 'V'),
- (0x675, 'M', u'اٴ'),
- (0x676, 'M', u'وٴ'),
- (0x677, 'M', u'Û‡Ù´'),
- (0x678, 'M', u'يٴ'),
- (0x679, 'V'),
- (0x6DD, 'X'),
- ]
-
-def _seg_10():
- return [
- (0x6DE, 'V'),
- (0x70E, 'X'),
- (0x710, 'V'),
- (0x74B, 'X'),
- (0x74D, 'V'),
- (0x7B2, 'X'),
- (0x7C0, 'V'),
- (0x7FB, 'X'),
- (0x800, 'V'),
- (0x82E, 'X'),
- (0x830, 'V'),
- (0x83F, 'X'),
- (0x840, 'V'),
- (0x85C, 'X'),
- (0x85E, 'V'),
- (0x85F, 'X'),
- (0x8A0, 'V'),
- (0x8A1, 'X'),
- (0x8A2, 'V'),
- (0x8AD, 'X'),
- (0x8E4, 'V'),
- (0x8FF, 'X'),
- (0x900, 'V'),
- (0x958, 'M', u'क़'),
- (0x959, 'M', u'ख़'),
- (0x95A, 'M', u'ग़'),
- (0x95B, 'M', u'ज़'),
- (0x95C, 'M', u'ड़'),
- (0x95D, 'M', u'ढ़'),
- (0x95E, 'M', u'फ़'),
- (0x95F, 'M', u'य़'),
- (0x960, 'V'),
- (0x978, 'X'),
- (0x979, 'V'),
- (0x980, 'X'),
- (0x981, 'V'),
- (0x984, 'X'),
- (0x985, 'V'),
- (0x98D, 'X'),
- (0x98F, 'V'),
- (0x991, 'X'),
- (0x993, 'V'),
- (0x9A9, 'X'),
- (0x9AA, 'V'),
- (0x9B1, 'X'),
- (0x9B2, 'V'),
- (0x9B3, 'X'),
- (0x9B6, 'V'),
- (0x9BA, 'X'),
- (0x9BC, 'V'),
- (0x9C5, 'X'),
- (0x9C7, 'V'),
- (0x9C9, 'X'),
- (0x9CB, 'V'),
- (0x9CF, 'X'),
- (0x9D7, 'V'),
- (0x9D8, 'X'),
- (0x9DC, 'M', u'ড়'),
- (0x9DD, 'M', u'ঢ়'),
- (0x9DE, 'X'),
- (0x9DF, 'M', u'য়'),
- (0x9E0, 'V'),
- (0x9E4, 'X'),
- (0x9E6, 'V'),
- (0x9FC, 'X'),
- (0xA01, 'V'),
- (0xA04, 'X'),
- (0xA05, 'V'),
- (0xA0B, 'X'),
- (0xA0F, 'V'),
- (0xA11, 'X'),
- (0xA13, 'V'),
- (0xA29, 'X'),
- (0xA2A, 'V'),
- (0xA31, 'X'),
- (0xA32, 'V'),
- (0xA33, 'M', u'ਲ਼'),
- (0xA34, 'X'),
- (0xA35, 'V'),
- (0xA36, 'M', u'ਸ਼'),
- (0xA37, 'X'),
- (0xA38, 'V'),
- (0xA3A, 'X'),
- (0xA3C, 'V'),
- (0xA3D, 'X'),
- (0xA3E, 'V'),
- (0xA43, 'X'),
- (0xA47, 'V'),
- (0xA49, 'X'),
- (0xA4B, 'V'),
- (0xA4E, 'X'),
- (0xA51, 'V'),
- (0xA52, 'X'),
- (0xA59, 'M', u'ਖ਼'),
- (0xA5A, 'M', u'ਗ਼'),
- (0xA5B, 'M', u'ਜ਼'),
- (0xA5C, 'V'),
- (0xA5D, 'X'),
- (0xA5E, 'M', u'ਫ਼'),
- (0xA5F, 'X'),
- ]
-
-def _seg_11():
- return [
- (0xA66, 'V'),
- (0xA76, 'X'),
- (0xA81, 'V'),
- (0xA84, 'X'),
- (0xA85, 'V'),
- (0xA8E, 'X'),
- (0xA8F, 'V'),
- (0xA92, 'X'),
- (0xA93, 'V'),
- (0xAA9, 'X'),
- (0xAAA, 'V'),
- (0xAB1, 'X'),
- (0xAB2, 'V'),
- (0xAB4, 'X'),
- (0xAB5, 'V'),
- (0xABA, 'X'),
- (0xABC, 'V'),
- (0xAC6, 'X'),
- (0xAC7, 'V'),
- (0xACA, 'X'),
- (0xACB, 'V'),
- (0xACE, 'X'),
- (0xAD0, 'V'),
- (0xAD1, 'X'),
- (0xAE0, 'V'),
- (0xAE4, 'X'),
- (0xAE6, 'V'),
- (0xAF2, 'X'),
- (0xB01, 'V'),
- (0xB04, 'X'),
- (0xB05, 'V'),
- (0xB0D, 'X'),
- (0xB0F, 'V'),
- (0xB11, 'X'),
- (0xB13, 'V'),
- (0xB29, 'X'),
- (0xB2A, 'V'),
- (0xB31, 'X'),
- (0xB32, 'V'),
- (0xB34, 'X'),
- (0xB35, 'V'),
- (0xB3A, 'X'),
- (0xB3C, 'V'),
- (0xB45, 'X'),
- (0xB47, 'V'),
- (0xB49, 'X'),
- (0xB4B, 'V'),
- (0xB4E, 'X'),
- (0xB56, 'V'),
- (0xB58, 'X'),
- (0xB5C, 'M', u'ଡ଼'),
- (0xB5D, 'M', u'ଢ଼'),
- (0xB5E, 'X'),
- (0xB5F, 'V'),
- (0xB64, 'X'),
- (0xB66, 'V'),
- (0xB78, 'X'),
- (0xB82, 'V'),
- (0xB84, 'X'),
- (0xB85, 'V'),
- (0xB8B, 'X'),
- (0xB8E, 'V'),
- (0xB91, 'X'),
- (0xB92, 'V'),
- (0xB96, 'X'),
- (0xB99, 'V'),
- (0xB9B, 'X'),
- (0xB9C, 'V'),
- (0xB9D, 'X'),
- (0xB9E, 'V'),
- (0xBA0, 'X'),
- (0xBA3, 'V'),
- (0xBA5, 'X'),
- (0xBA8, 'V'),
- (0xBAB, 'X'),
- (0xBAE, 'V'),
- (0xBBA, 'X'),
- (0xBBE, 'V'),
- (0xBC3, 'X'),
- (0xBC6, 'V'),
- (0xBC9, 'X'),
- (0xBCA, 'V'),
- (0xBCE, 'X'),
- (0xBD0, 'V'),
- (0xBD1, 'X'),
- (0xBD7, 'V'),
- (0xBD8, 'X'),
- (0xBE6, 'V'),
- (0xBFB, 'X'),
- (0xC01, 'V'),
- (0xC04, 'X'),
- (0xC05, 'V'),
- (0xC0D, 'X'),
- (0xC0E, 'V'),
- (0xC11, 'X'),
- (0xC12, 'V'),
- (0xC29, 'X'),
- (0xC2A, 'V'),
- (0xC34, 'X'),
- (0xC35, 'V'),
- ]
-
-def _seg_12():
- return [
- (0xC3A, 'X'),
- (0xC3D, 'V'),
- (0xC45, 'X'),
- (0xC46, 'V'),
- (0xC49, 'X'),
- (0xC4A, 'V'),
- (0xC4E, 'X'),
- (0xC55, 'V'),
- (0xC57, 'X'),
- (0xC58, 'V'),
- (0xC5A, 'X'),
- (0xC60, 'V'),
- (0xC64, 'X'),
- (0xC66, 'V'),
- (0xC70, 'X'),
- (0xC78, 'V'),
- (0xC80, 'X'),
- (0xC82, 'V'),
- (0xC84, 'X'),
- (0xC85, 'V'),
- (0xC8D, 'X'),
- (0xC8E, 'V'),
- (0xC91, 'X'),
- (0xC92, 'V'),
- (0xCA9, 'X'),
- (0xCAA, 'V'),
- (0xCB4, 'X'),
- (0xCB5, 'V'),
- (0xCBA, 'X'),
- (0xCBC, 'V'),
- (0xCC5, 'X'),
- (0xCC6, 'V'),
- (0xCC9, 'X'),
- (0xCCA, 'V'),
- (0xCCE, 'X'),
- (0xCD5, 'V'),
- (0xCD7, 'X'),
- (0xCDE, 'V'),
- (0xCDF, 'X'),
- (0xCE0, 'V'),
- (0xCE4, 'X'),
- (0xCE6, 'V'),
- (0xCF0, 'X'),
- (0xCF1, 'V'),
- (0xCF3, 'X'),
- (0xD02, 'V'),
- (0xD04, 'X'),
- (0xD05, 'V'),
- (0xD0D, 'X'),
- (0xD0E, 'V'),
- (0xD11, 'X'),
- (0xD12, 'V'),
- (0xD3B, 'X'),
- (0xD3D, 'V'),
- (0xD45, 'X'),
- (0xD46, 'V'),
- (0xD49, 'X'),
- (0xD4A, 'V'),
- (0xD4F, 'X'),
- (0xD57, 'V'),
- (0xD58, 'X'),
- (0xD60, 'V'),
- (0xD64, 'X'),
- (0xD66, 'V'),
- (0xD76, 'X'),
- (0xD79, 'V'),
- (0xD80, 'X'),
- (0xD82, 'V'),
- (0xD84, 'X'),
- (0xD85, 'V'),
- (0xD97, 'X'),
- (0xD9A, 'V'),
- (0xDB2, 'X'),
- (0xDB3, 'V'),
- (0xDBC, 'X'),
- (0xDBD, 'V'),
- (0xDBE, 'X'),
- (0xDC0, 'V'),
- (0xDC7, 'X'),
- (0xDCA, 'V'),
- (0xDCB, 'X'),
- (0xDCF, 'V'),
- (0xDD5, 'X'),
- (0xDD6, 'V'),
- (0xDD7, 'X'),
- (0xDD8, 'V'),
- (0xDE0, 'X'),
- (0xDF2, 'V'),
- (0xDF5, 'X'),
- (0xE01, 'V'),
- (0xE33, 'M', u'à¹à¸²'),
- (0xE34, 'V'),
- (0xE3B, 'X'),
- (0xE3F, 'V'),
- (0xE5C, 'X'),
- (0xE81, 'V'),
- (0xE83, 'X'),
- (0xE84, 'V'),
- (0xE85, 'X'),
- (0xE87, 'V'),
- ]
-
-def _seg_13():
- return [
- (0xE89, 'X'),
- (0xE8A, 'V'),
- (0xE8B, 'X'),
- (0xE8D, 'V'),
- (0xE8E, 'X'),
- (0xE94, 'V'),
- (0xE98, 'X'),
- (0xE99, 'V'),
- (0xEA0, 'X'),
- (0xEA1, 'V'),
- (0xEA4, 'X'),
- (0xEA5, 'V'),
- (0xEA6, 'X'),
- (0xEA7, 'V'),
- (0xEA8, 'X'),
- (0xEAA, 'V'),
- (0xEAC, 'X'),
- (0xEAD, 'V'),
- (0xEB3, 'M', u'à»àº²'),
- (0xEB4, 'V'),
- (0xEBA, 'X'),
- (0xEBB, 'V'),
- (0xEBE, 'X'),
- (0xEC0, 'V'),
- (0xEC5, 'X'),
- (0xEC6, 'V'),
- (0xEC7, 'X'),
- (0xEC8, 'V'),
- (0xECE, 'X'),
- (0xED0, 'V'),
- (0xEDA, 'X'),
- (0xEDC, 'M', u'ຫນ'),
- (0xEDD, 'M', u'ຫມ'),
- (0xEDE, 'V'),
- (0xEE0, 'X'),
- (0xF00, 'V'),
- (0xF0C, 'M', u'་'),
- (0xF0D, 'V'),
- (0xF43, 'M', u'གྷ'),
- (0xF44, 'V'),
- (0xF48, 'X'),
- (0xF49, 'V'),
- (0xF4D, 'M', u'ཌྷ'),
- (0xF4E, 'V'),
- (0xF52, 'M', u'དྷ'),
- (0xF53, 'V'),
- (0xF57, 'M', u'བྷ'),
- (0xF58, 'V'),
- (0xF5C, 'M', u'ཛྷ'),
- (0xF5D, 'V'),
- (0xF69, 'M', u'ཀྵ'),
- (0xF6A, 'V'),
- (0xF6D, 'X'),
- (0xF71, 'V'),
- (0xF73, 'M', u'ཱི'),
- (0xF74, 'V'),
- (0xF75, 'M', u'ཱུ'),
- (0xF76, 'M', u'ྲྀ'),
- (0xF77, 'M', u'ྲཱྀ'),
- (0xF78, 'M', u'ླྀ'),
- (0xF79, 'M', u'ླཱྀ'),
- (0xF7A, 'V'),
- (0xF81, 'M', u'ཱྀ'),
- (0xF82, 'V'),
- (0xF93, 'M', u'ྒྷ'),
- (0xF94, 'V'),
- (0xF98, 'X'),
- (0xF99, 'V'),
- (0xF9D, 'M', u'ྜྷ'),
- (0xF9E, 'V'),
- (0xFA2, 'M', u'ྡྷ'),
- (0xFA3, 'V'),
- (0xFA7, 'M', u'ྦྷ'),
- (0xFA8, 'V'),
- (0xFAC, 'M', u'ྫྷ'),
- (0xFAD, 'V'),
- (0xFB9, 'M', u'à¾à¾µ'),
- (0xFBA, 'V'),
- (0xFBD, 'X'),
- (0xFBE, 'V'),
- (0xFCD, 'X'),
- (0xFCE, 'V'),
- (0xFDB, 'X'),
- (0x1000, 'V'),
- (0x10A0, 'X'),
- (0x10C7, 'M', u'â´§'),
- (0x10C8, 'X'),
- (0x10CD, 'M', u'â´­'),
- (0x10CE, 'X'),
- (0x10D0, 'V'),
- (0x10FC, 'M', u'ნ'),
- (0x10FD, 'V'),
- (0x115F, 'X'),
- (0x1161, 'V'),
- (0x1249, 'X'),
- (0x124A, 'V'),
- (0x124E, 'X'),
- (0x1250, 'V'),
- (0x1257, 'X'),
- (0x1258, 'V'),
- ]
-
-def _seg_14():
- return [
- (0x1259, 'X'),
- (0x125A, 'V'),
- (0x125E, 'X'),
- (0x1260, 'V'),
- (0x1289, 'X'),
- (0x128A, 'V'),
- (0x128E, 'X'),
- (0x1290, 'V'),
- (0x12B1, 'X'),
- (0x12B2, 'V'),
- (0x12B6, 'X'),
- (0x12B8, 'V'),
- (0x12BF, 'X'),
- (0x12C0, 'V'),
- (0x12C1, 'X'),
- (0x12C2, 'V'),
- (0x12C6, 'X'),
- (0x12C8, 'V'),
- (0x12D7, 'X'),
- (0x12D8, 'V'),
- (0x1311, 'X'),
- (0x1312, 'V'),
- (0x1316, 'X'),
- (0x1318, 'V'),
- (0x135B, 'X'),
- (0x135D, 'V'),
- (0x137D, 'X'),
- (0x1380, 'V'),
- (0x139A, 'X'),
- (0x13A0, 'V'),
- (0x13F5, 'X'),
- (0x1400, 'V'),
- (0x1680, 'X'),
- (0x1681, 'V'),
- (0x169D, 'X'),
- (0x16A0, 'V'),
- (0x16F1, 'X'),
- (0x1700, 'V'),
- (0x170D, 'X'),
- (0x170E, 'V'),
- (0x1715, 'X'),
- (0x1720, 'V'),
- (0x1737, 'X'),
- (0x1740, 'V'),
- (0x1754, 'X'),
- (0x1760, 'V'),
- (0x176D, 'X'),
- (0x176E, 'V'),
- (0x1771, 'X'),
- (0x1772, 'V'),
- (0x1774, 'X'),
- (0x1780, 'V'),
- (0x17B4, 'X'),
- (0x17B6, 'V'),
- (0x17DE, 'X'),
- (0x17E0, 'V'),
- (0x17EA, 'X'),
- (0x17F0, 'V'),
- (0x17FA, 'X'),
- (0x1800, 'V'),
- (0x1806, 'X'),
- (0x1807, 'V'),
- (0x180B, 'I'),
- (0x180E, 'X'),
- (0x1810, 'V'),
- (0x181A, 'X'),
- (0x1820, 'V'),
- (0x1878, 'X'),
- (0x1880, 'V'),
- (0x18AB, 'X'),
- (0x18B0, 'V'),
- (0x18F6, 'X'),
- (0x1900, 'V'),
- (0x191D, 'X'),
- (0x1920, 'V'),
- (0x192C, 'X'),
- (0x1930, 'V'),
- (0x193C, 'X'),
- (0x1940, 'V'),
- (0x1941, 'X'),
- (0x1944, 'V'),
- (0x196E, 'X'),
- (0x1970, 'V'),
- (0x1975, 'X'),
- (0x1980, 'V'),
- (0x19AC, 'X'),
- (0x19B0, 'V'),
- (0x19CA, 'X'),
- (0x19D0, 'V'),
- (0x19DB, 'X'),
- (0x19DE, 'V'),
- (0x1A1C, 'X'),
- (0x1A1E, 'V'),
- (0x1A5F, 'X'),
- (0x1A60, 'V'),
- (0x1A7D, 'X'),
- (0x1A7F, 'V'),
- (0x1A8A, 'X'),
- (0x1A90, 'V'),
- (0x1A9A, 'X'),
- ]
-
-def _seg_15():
- return [
- (0x1AA0, 'V'),
- (0x1AAE, 'X'),
- (0x1B00, 'V'),
- (0x1B4C, 'X'),
- (0x1B50, 'V'),
- (0x1B7D, 'X'),
- (0x1B80, 'V'),
- (0x1BF4, 'X'),
- (0x1BFC, 'V'),
- (0x1C38, 'X'),
- (0x1C3B, 'V'),
- (0x1C4A, 'X'),
- (0x1C4D, 'V'),
- (0x1C80, 'X'),
- (0x1CC0, 'V'),
- (0x1CC8, 'X'),
- (0x1CD0, 'V'),
- (0x1CF7, 'X'),
- (0x1D00, 'V'),
- (0x1D2C, 'M', u'a'),
- (0x1D2D, 'M', u'æ'),
- (0x1D2E, 'M', u'b'),
- (0x1D2F, 'V'),
- (0x1D30, 'M', u'd'),
- (0x1D31, 'M', u'e'),
- (0x1D32, 'M', u'Ç'),
- (0x1D33, 'M', u'g'),
- (0x1D34, 'M', u'h'),
- (0x1D35, 'M', u'i'),
- (0x1D36, 'M', u'j'),
- (0x1D37, 'M', u'k'),
- (0x1D38, 'M', u'l'),
- (0x1D39, 'M', u'm'),
- (0x1D3A, 'M', u'n'),
- (0x1D3B, 'V'),
- (0x1D3C, 'M', u'o'),
- (0x1D3D, 'M', u'È£'),
- (0x1D3E, 'M', u'p'),
- (0x1D3F, 'M', u'r'),
- (0x1D40, 'M', u't'),
- (0x1D41, 'M', u'u'),
- (0x1D42, 'M', u'w'),
- (0x1D43, 'M', u'a'),
- (0x1D44, 'M', u'É'),
- (0x1D45, 'M', u'É‘'),
- (0x1D46, 'M', u'á´‚'),
- (0x1D47, 'M', u'b'),
- (0x1D48, 'M', u'd'),
- (0x1D49, 'M', u'e'),
- (0x1D4A, 'M', u'É™'),
- (0x1D4B, 'M', u'É›'),
- (0x1D4C, 'M', u'ɜ'),
- (0x1D4D, 'M', u'g'),
- (0x1D4E, 'V'),
- (0x1D4F, 'M', u'k'),
- (0x1D50, 'M', u'm'),
- (0x1D51, 'M', u'Å‹'),
- (0x1D52, 'M', u'o'),
- (0x1D53, 'M', u'É”'),
- (0x1D54, 'M', u'á´–'),
- (0x1D55, 'M', u'á´—'),
- (0x1D56, 'M', u'p'),
- (0x1D57, 'M', u't'),
- (0x1D58, 'M', u'u'),
- (0x1D59, 'M', u'á´'),
- (0x1D5A, 'M', u'ɯ'),
- (0x1D5B, 'M', u'v'),
- (0x1D5C, 'M', u'á´¥'),
- (0x1D5D, 'M', u'β'),
- (0x1D5E, 'M', u'γ'),
- (0x1D5F, 'M', u'δ'),
- (0x1D60, 'M', u'φ'),
- (0x1D61, 'M', u'χ'),
- (0x1D62, 'M', u'i'),
- (0x1D63, 'M', u'r'),
- (0x1D64, 'M', u'u'),
- (0x1D65, 'M', u'v'),
- (0x1D66, 'M', u'β'),
- (0x1D67, 'M', u'γ'),
- (0x1D68, 'M', u'Ï'),
- (0x1D69, 'M', u'φ'),
- (0x1D6A, 'M', u'χ'),
- (0x1D6B, 'V'),
- (0x1D78, 'M', u'н'),
- (0x1D79, 'V'),
- (0x1D9B, 'M', u'É’'),
- (0x1D9C, 'M', u'c'),
- (0x1D9D, 'M', u'É•'),
- (0x1D9E, 'M', u'ð'),
- (0x1D9F, 'M', u'ɜ'),
- (0x1DA0, 'M', u'f'),
- (0x1DA1, 'M', u'ÉŸ'),
- (0x1DA2, 'M', u'É¡'),
- (0x1DA3, 'M', u'É¥'),
- (0x1DA4, 'M', u'ɨ'),
- (0x1DA5, 'M', u'É©'),
- (0x1DA6, 'M', u'ɪ'),
- (0x1DA7, 'M', u'áµ»'),
- (0x1DA8, 'M', u'Ê'),
- (0x1DA9, 'M', u'É­'),
- ]
-
-def _seg_16():
- return [
- (0x1DAA, 'M', u'ᶅ'),
- (0x1DAB, 'M', u'ÊŸ'),
- (0x1DAC, 'M', u'ɱ'),
- (0x1DAD, 'M', u'É°'),
- (0x1DAE, 'M', u'ɲ'),
- (0x1DAF, 'M', u'ɳ'),
- (0x1DB0, 'M', u'É´'),
- (0x1DB1, 'M', u'ɵ'),
- (0x1DB2, 'M', u'ɸ'),
- (0x1DB3, 'M', u'Ê‚'),
- (0x1DB4, 'M', u'ʃ'),
- (0x1DB5, 'M', u'Æ«'),
- (0x1DB6, 'M', u'ʉ'),
- (0x1DB7, 'M', u'ÊŠ'),
- (0x1DB8, 'M', u'ᴜ'),
- (0x1DB9, 'M', u'Ê‹'),
- (0x1DBA, 'M', u'ʌ'),
- (0x1DBB, 'M', u'z'),
- (0x1DBC, 'M', u'Ê'),
- (0x1DBD, 'M', u'Ê‘'),
- (0x1DBE, 'M', u'Ê’'),
- (0x1DBF, 'M', u'θ'),
- (0x1DC0, 'V'),
- (0x1DE7, 'X'),
- (0x1DFC, 'V'),
- (0x1E00, 'M', u'á¸'),
- (0x1E01, 'V'),
- (0x1E02, 'M', u'ḃ'),
- (0x1E03, 'V'),
- (0x1E04, 'M', u'ḅ'),
- (0x1E05, 'V'),
- (0x1E06, 'M', u'ḇ'),
- (0x1E07, 'V'),
- (0x1E08, 'M', u'ḉ'),
- (0x1E09, 'V'),
- (0x1E0A, 'M', u'ḋ'),
- (0x1E0B, 'V'),
- (0x1E0C, 'M', u'á¸'),
- (0x1E0D, 'V'),
- (0x1E0E, 'M', u'á¸'),
- (0x1E0F, 'V'),
- (0x1E10, 'M', u'ḑ'),
- (0x1E11, 'V'),
- (0x1E12, 'M', u'ḓ'),
- (0x1E13, 'V'),
- (0x1E14, 'M', u'ḕ'),
- (0x1E15, 'V'),
- (0x1E16, 'M', u'ḗ'),
- (0x1E17, 'V'),
- (0x1E18, 'M', u'ḙ'),
- (0x1E19, 'V'),
- (0x1E1A, 'M', u'ḛ'),
- (0x1E1B, 'V'),
- (0x1E1C, 'M', u'á¸'),
- (0x1E1D, 'V'),
- (0x1E1E, 'M', u'ḟ'),
- (0x1E1F, 'V'),
- (0x1E20, 'M', u'ḡ'),
- (0x1E21, 'V'),
- (0x1E22, 'M', u'ḣ'),
- (0x1E23, 'V'),
- (0x1E24, 'M', u'ḥ'),
- (0x1E25, 'V'),
- (0x1E26, 'M', u'ḧ'),
- (0x1E27, 'V'),
- (0x1E28, 'M', u'ḩ'),
- (0x1E29, 'V'),
- (0x1E2A, 'M', u'ḫ'),
- (0x1E2B, 'V'),
- (0x1E2C, 'M', u'ḭ'),
- (0x1E2D, 'V'),
- (0x1E2E, 'M', u'ḯ'),
- (0x1E2F, 'V'),
- (0x1E30, 'M', u'ḱ'),
- (0x1E31, 'V'),
- (0x1E32, 'M', u'ḳ'),
- (0x1E33, 'V'),
- (0x1E34, 'M', u'ḵ'),
- (0x1E35, 'V'),
- (0x1E36, 'M', u'ḷ'),
- (0x1E37, 'V'),
- (0x1E38, 'M', u'ḹ'),
- (0x1E39, 'V'),
- (0x1E3A, 'M', u'ḻ'),
- (0x1E3B, 'V'),
- (0x1E3C, 'M', u'ḽ'),
- (0x1E3D, 'V'),
- (0x1E3E, 'M', u'ḿ'),
- (0x1E3F, 'V'),
- (0x1E40, 'M', u'á¹'),
- (0x1E41, 'V'),
- (0x1E42, 'M', u'ṃ'),
- (0x1E43, 'V'),
- (0x1E44, 'M', u'á¹…'),
- (0x1E45, 'V'),
- (0x1E46, 'M', u'ṇ'),
- (0x1E47, 'V'),
- (0x1E48, 'M', u'ṉ'),
- (0x1E49, 'V'),
- (0x1E4A, 'M', u'ṋ'),
- ]
-
-def _seg_17():
- return [
- (0x1E4B, 'V'),
- (0x1E4C, 'M', u'á¹'),
- (0x1E4D, 'V'),
- (0x1E4E, 'M', u'á¹'),
- (0x1E4F, 'V'),
- (0x1E50, 'M', u'ṑ'),
- (0x1E51, 'V'),
- (0x1E52, 'M', u'ṓ'),
- (0x1E53, 'V'),
- (0x1E54, 'M', u'ṕ'),
- (0x1E55, 'V'),
- (0x1E56, 'M', u'á¹—'),
- (0x1E57, 'V'),
- (0x1E58, 'M', u'á¹™'),
- (0x1E59, 'V'),
- (0x1E5A, 'M', u'á¹›'),
- (0x1E5B, 'V'),
- (0x1E5C, 'M', u'á¹'),
- (0x1E5D, 'V'),
- (0x1E5E, 'M', u'ṟ'),
- (0x1E5F, 'V'),
- (0x1E60, 'M', u'ṡ'),
- (0x1E61, 'V'),
- (0x1E62, 'M', u'á¹£'),
- (0x1E63, 'V'),
- (0x1E64, 'M', u'á¹¥'),
- (0x1E65, 'V'),
- (0x1E66, 'M', u'ṧ'),
- (0x1E67, 'V'),
- (0x1E68, 'M', u'ṩ'),
- (0x1E69, 'V'),
- (0x1E6A, 'M', u'ṫ'),
- (0x1E6B, 'V'),
- (0x1E6C, 'M', u'á¹­'),
- (0x1E6D, 'V'),
- (0x1E6E, 'M', u'ṯ'),
- (0x1E6F, 'V'),
- (0x1E70, 'M', u'á¹±'),
- (0x1E71, 'V'),
- (0x1E72, 'M', u'á¹³'),
- (0x1E73, 'V'),
- (0x1E74, 'M', u'á¹µ'),
- (0x1E75, 'V'),
- (0x1E76, 'M', u'á¹·'),
- (0x1E77, 'V'),
- (0x1E78, 'M', u'á¹¹'),
- (0x1E79, 'V'),
- (0x1E7A, 'M', u'á¹»'),
- (0x1E7B, 'V'),
- (0x1E7C, 'M', u'á¹½'),
- (0x1E7D, 'V'),
- (0x1E7E, 'M', u'ṿ'),
- (0x1E7F, 'V'),
- (0x1E80, 'M', u'áº'),
- (0x1E81, 'V'),
- (0x1E82, 'M', u'ẃ'),
- (0x1E83, 'V'),
- (0x1E84, 'M', u'ẅ'),
- (0x1E85, 'V'),
- (0x1E86, 'M', u'ẇ'),
- (0x1E87, 'V'),
- (0x1E88, 'M', u'ẉ'),
- (0x1E89, 'V'),
- (0x1E8A, 'M', u'ẋ'),
- (0x1E8B, 'V'),
- (0x1E8C, 'M', u'áº'),
- (0x1E8D, 'V'),
- (0x1E8E, 'M', u'áº'),
- (0x1E8F, 'V'),
- (0x1E90, 'M', u'ẑ'),
- (0x1E91, 'V'),
- (0x1E92, 'M', u'ẓ'),
- (0x1E93, 'V'),
- (0x1E94, 'M', u'ẕ'),
- (0x1E95, 'V'),
- (0x1E9A, 'M', u'aʾ'),
- (0x1E9B, 'M', u'ṡ'),
- (0x1E9C, 'V'),
- (0x1E9E, 'M', u'ss'),
- (0x1E9F, 'V'),
- (0x1EA0, 'M', u'ạ'),
- (0x1EA1, 'V'),
- (0x1EA2, 'M', u'ả'),
- (0x1EA3, 'V'),
- (0x1EA4, 'M', u'ấ'),
- (0x1EA5, 'V'),
- (0x1EA6, 'M', u'ầ'),
- (0x1EA7, 'V'),
- (0x1EA8, 'M', u'ẩ'),
- (0x1EA9, 'V'),
- (0x1EAA, 'M', u'ẫ'),
- (0x1EAB, 'V'),
- (0x1EAC, 'M', u'ậ'),
- (0x1EAD, 'V'),
- (0x1EAE, 'M', u'ắ'),
- (0x1EAF, 'V'),
- (0x1EB0, 'M', u'ằ'),
- (0x1EB1, 'V'),
- (0x1EB2, 'M', u'ẳ'),
- (0x1EB3, 'V'),
- ]
-
-def _seg_18():
- return [
- (0x1EB4, 'M', u'ẵ'),
- (0x1EB5, 'V'),
- (0x1EB6, 'M', u'ặ'),
- (0x1EB7, 'V'),
- (0x1EB8, 'M', u'ẹ'),
- (0x1EB9, 'V'),
- (0x1EBA, 'M', u'ẻ'),
- (0x1EBB, 'V'),
- (0x1EBC, 'M', u'ẽ'),
- (0x1EBD, 'V'),
- (0x1EBE, 'M', u'ế'),
- (0x1EBF, 'V'),
- (0x1EC0, 'M', u'á»'),
- (0x1EC1, 'V'),
- (0x1EC2, 'M', u'ể'),
- (0x1EC3, 'V'),
- (0x1EC4, 'M', u'á»…'),
- (0x1EC5, 'V'),
- (0x1EC6, 'M', u'ệ'),
- (0x1EC7, 'V'),
- (0x1EC8, 'M', u'ỉ'),
- (0x1EC9, 'V'),
- (0x1ECA, 'M', u'ị'),
- (0x1ECB, 'V'),
- (0x1ECC, 'M', u'á»'),
- (0x1ECD, 'V'),
- (0x1ECE, 'M', u'á»'),
- (0x1ECF, 'V'),
- (0x1ED0, 'M', u'ố'),
- (0x1ED1, 'V'),
- (0x1ED2, 'M', u'ồ'),
- (0x1ED3, 'V'),
- (0x1ED4, 'M', u'ổ'),
- (0x1ED5, 'V'),
- (0x1ED6, 'M', u'á»—'),
- (0x1ED7, 'V'),
- (0x1ED8, 'M', u'á»™'),
- (0x1ED9, 'V'),
- (0x1EDA, 'M', u'á»›'),
- (0x1EDB, 'V'),
- (0x1EDC, 'M', u'á»'),
- (0x1EDD, 'V'),
- (0x1EDE, 'M', u'ở'),
- (0x1EDF, 'V'),
- (0x1EE0, 'M', u'ỡ'),
- (0x1EE1, 'V'),
- (0x1EE2, 'M', u'ợ'),
- (0x1EE3, 'V'),
- (0x1EE4, 'M', u'ụ'),
- (0x1EE5, 'V'),
- (0x1EE6, 'M', u'ủ'),
- (0x1EE7, 'V'),
- (0x1EE8, 'M', u'ứ'),
- (0x1EE9, 'V'),
- (0x1EEA, 'M', u'ừ'),
- (0x1EEB, 'V'),
- (0x1EEC, 'M', u'á»­'),
- (0x1EED, 'V'),
- (0x1EEE, 'M', u'ữ'),
- (0x1EEF, 'V'),
- (0x1EF0, 'M', u'á»±'),
- (0x1EF1, 'V'),
- (0x1EF2, 'M', u'ỳ'),
- (0x1EF3, 'V'),
- (0x1EF4, 'M', u'ỵ'),
- (0x1EF5, 'V'),
- (0x1EF6, 'M', u'á»·'),
- (0x1EF7, 'V'),
- (0x1EF8, 'M', u'ỹ'),
- (0x1EF9, 'V'),
- (0x1EFA, 'M', u'á»»'),
- (0x1EFB, 'V'),
- (0x1EFC, 'M', u'ỽ'),
- (0x1EFD, 'V'),
- (0x1EFE, 'M', u'ỿ'),
- (0x1EFF, 'V'),
- (0x1F08, 'M', u'á¼€'),
- (0x1F09, 'M', u'á¼'),
- (0x1F0A, 'M', u'ἂ'),
- (0x1F0B, 'M', u'ἃ'),
- (0x1F0C, 'M', u'ἄ'),
- (0x1F0D, 'M', u'á¼…'),
- (0x1F0E, 'M', u'ἆ'),
- (0x1F0F, 'M', u'ἇ'),
- (0x1F10, 'V'),
- (0x1F16, 'X'),
- (0x1F18, 'M', u'á¼'),
- (0x1F19, 'M', u'ἑ'),
- (0x1F1A, 'M', u'á¼’'),
- (0x1F1B, 'M', u'ἓ'),
- (0x1F1C, 'M', u'á¼”'),
- (0x1F1D, 'M', u'ἕ'),
- (0x1F1E, 'X'),
- (0x1F20, 'V'),
- (0x1F28, 'M', u'á¼ '),
- (0x1F29, 'M', u'ἡ'),
- (0x1F2A, 'M', u'á¼¢'),
- (0x1F2B, 'M', u'á¼£'),
- (0x1F2C, 'M', u'ἤ'),
- (0x1F2D, 'M', u'á¼¥'),
- ]
-
-def _seg_19():
- return [
- (0x1F2E, 'M', u'ἦ'),
- (0x1F2F, 'M', u'ἧ'),
- (0x1F30, 'V'),
- (0x1F38, 'M', u'á¼°'),
- (0x1F39, 'M', u'á¼±'),
- (0x1F3A, 'M', u'á¼²'),
- (0x1F3B, 'M', u'á¼³'),
- (0x1F3C, 'M', u'á¼´'),
- (0x1F3D, 'M', u'á¼µ'),
- (0x1F3E, 'M', u'ἶ'),
- (0x1F3F, 'M', u'á¼·'),
- (0x1F40, 'V'),
- (0x1F46, 'X'),
- (0x1F48, 'M', u'á½€'),
- (0x1F49, 'M', u'á½'),
- (0x1F4A, 'M', u'ὂ'),
- (0x1F4B, 'M', u'ὃ'),
- (0x1F4C, 'M', u'ὄ'),
- (0x1F4D, 'M', u'á½…'),
- (0x1F4E, 'X'),
- (0x1F50, 'V'),
- (0x1F58, 'X'),
- (0x1F59, 'M', u'ὑ'),
- (0x1F5A, 'X'),
- (0x1F5B, 'M', u'ὓ'),
- (0x1F5C, 'X'),
- (0x1F5D, 'M', u'ὕ'),
- (0x1F5E, 'X'),
- (0x1F5F, 'M', u'á½—'),
- (0x1F60, 'V'),
- (0x1F68, 'M', u'á½ '),
- (0x1F69, 'M', u'ὡ'),
- (0x1F6A, 'M', u'á½¢'),
- (0x1F6B, 'M', u'á½£'),
- (0x1F6C, 'M', u'ὤ'),
- (0x1F6D, 'M', u'á½¥'),
- (0x1F6E, 'M', u'ὦ'),
- (0x1F6F, 'M', u'ὧ'),
- (0x1F70, 'V'),
- (0x1F71, 'M', u'ά'),
- (0x1F72, 'V'),
- (0x1F73, 'M', u'έ'),
- (0x1F74, 'V'),
- (0x1F75, 'M', u'ή'),
- (0x1F76, 'V'),
- (0x1F77, 'M', u'ί'),
- (0x1F78, 'V'),
- (0x1F79, 'M', u'ό'),
- (0x1F7A, 'V'),
- (0x1F7B, 'M', u'Ï'),
- (0x1F7C, 'V'),
- (0x1F7D, 'M', u'ÏŽ'),
- (0x1F7E, 'X'),
- (0x1F80, 'M', u'ἀι'),
- (0x1F81, 'M', u'á¼Î¹'),
- (0x1F82, 'M', u'ἂι'),
- (0x1F83, 'M', u'ἃι'),
- (0x1F84, 'M', u'ἄι'),
- (0x1F85, 'M', u'ἅι'),
- (0x1F86, 'M', u'ἆι'),
- (0x1F87, 'M', u'ἇι'),
- (0x1F88, 'M', u'ἀι'),
- (0x1F89, 'M', u'á¼Î¹'),
- (0x1F8A, 'M', u'ἂι'),
- (0x1F8B, 'M', u'ἃι'),
- (0x1F8C, 'M', u'ἄι'),
- (0x1F8D, 'M', u'ἅι'),
- (0x1F8E, 'M', u'ἆι'),
- (0x1F8F, 'M', u'ἇι'),
- (0x1F90, 'M', u'ἠι'),
- (0x1F91, 'M', u'ἡι'),
- (0x1F92, 'M', u'ἢι'),
- (0x1F93, 'M', u'ἣι'),
- (0x1F94, 'M', u'ἤι'),
- (0x1F95, 'M', u'ἥι'),
- (0x1F96, 'M', u'ἦι'),
- (0x1F97, 'M', u'ἧι'),
- (0x1F98, 'M', u'ἠι'),
- (0x1F99, 'M', u'ἡι'),
- (0x1F9A, 'M', u'ἢι'),
- (0x1F9B, 'M', u'ἣι'),
- (0x1F9C, 'M', u'ἤι'),
- (0x1F9D, 'M', u'ἥι'),
- (0x1F9E, 'M', u'ἦι'),
- (0x1F9F, 'M', u'ἧι'),
- (0x1FA0, 'M', u'ὠι'),
- (0x1FA1, 'M', u'ὡι'),
- (0x1FA2, 'M', u'ὢι'),
- (0x1FA3, 'M', u'ὣι'),
- (0x1FA4, 'M', u'ὤι'),
- (0x1FA5, 'M', u'ὥι'),
- (0x1FA6, 'M', u'ὦι'),
- (0x1FA7, 'M', u'ὧι'),
- (0x1FA8, 'M', u'ὠι'),
- (0x1FA9, 'M', u'ὡι'),
- (0x1FAA, 'M', u'ὢι'),
- (0x1FAB, 'M', u'ὣι'),
- (0x1FAC, 'M', u'ὤι'),
- (0x1FAD, 'M', u'ὥι'),
- (0x1FAE, 'M', u'ὦι'),
- ]
-
-def _seg_20():
- return [
- (0x1FAF, 'M', u'ὧι'),
- (0x1FB0, 'V'),
- (0x1FB2, 'M', u'ὰι'),
- (0x1FB3, 'M', u'αι'),
- (0x1FB4, 'M', u'άι'),
- (0x1FB5, 'X'),
- (0x1FB6, 'V'),
- (0x1FB7, 'M', u'ᾶι'),
- (0x1FB8, 'M', u'á¾°'),
- (0x1FB9, 'M', u'á¾±'),
- (0x1FBA, 'M', u'á½°'),
- (0x1FBB, 'M', u'ά'),
- (0x1FBC, 'M', u'αι'),
- (0x1FBD, '3', u' Ì“'),
- (0x1FBE, 'M', u'ι'),
- (0x1FBF, '3', u' Ì“'),
- (0x1FC0, '3', u' Í‚'),
- (0x1FC1, '3', u' ̈͂'),
- (0x1FC2, 'M', u'ὴι'),
- (0x1FC3, 'M', u'ηι'),
- (0x1FC4, 'M', u'ήι'),
- (0x1FC5, 'X'),
- (0x1FC6, 'V'),
- (0x1FC7, 'M', u'ῆι'),
- (0x1FC8, 'M', u'á½²'),
- (0x1FC9, 'M', u'έ'),
- (0x1FCA, 'M', u'á½´'),
- (0x1FCB, 'M', u'ή'),
- (0x1FCC, 'M', u'ηι'),
- (0x1FCD, '3', u' Ì“Ì€'),
- (0x1FCE, '3', u' Ì“Ì'),
- (0x1FCF, '3', u' Ì“Í‚'),
- (0x1FD0, 'V'),
- (0x1FD3, 'M', u'Î'),
- (0x1FD4, 'X'),
- (0x1FD6, 'V'),
- (0x1FD8, 'M', u'á¿'),
- (0x1FD9, 'M', u'á¿‘'),
- (0x1FDA, 'M', u'ὶ'),
- (0x1FDB, 'M', u'ί'),
- (0x1FDC, 'X'),
- (0x1FDD, '3', u' ̔̀'),
- (0x1FDE, '3', u' Ì”Ì'),
- (0x1FDF, '3', u' ̔͂'),
- (0x1FE0, 'V'),
- (0x1FE3, 'M', u'ΰ'),
- (0x1FE4, 'V'),
- (0x1FE8, 'M', u'á¿ '),
- (0x1FE9, 'M', u'á¿¡'),
- (0x1FEA, 'M', u'ὺ'),
- (0x1FEB, 'M', u'Ï'),
- (0x1FEC, 'M', u'á¿¥'),
- (0x1FED, '3', u' ̈̀'),
- (0x1FEE, '3', u' ̈Ì'),
- (0x1FEF, '3', u'`'),
- (0x1FF0, 'X'),
- (0x1FF2, 'M', u'ὼι'),
- (0x1FF3, 'M', u'ωι'),
- (0x1FF4, 'M', u'ώι'),
- (0x1FF5, 'X'),
- (0x1FF6, 'V'),
- (0x1FF7, 'M', u'ῶι'),
- (0x1FF8, 'M', u'ὸ'),
- (0x1FF9, 'M', u'ό'),
- (0x1FFA, 'M', u'á½¼'),
- (0x1FFB, 'M', u'ÏŽ'),
- (0x1FFC, 'M', u'ωι'),
- (0x1FFD, '3', u' Ì'),
- (0x1FFE, '3', u' Ì”'),
- (0x1FFF, 'X'),
- (0x2000, '3', u' '),
- (0x200B, 'I'),
- (0x200C, 'D', u''),
- (0x200E, 'X'),
- (0x2010, 'V'),
- (0x2011, 'M', u'â€'),
- (0x2012, 'V'),
- (0x2017, '3', u' ̳'),
- (0x2018, 'V'),
- (0x2024, 'X'),
- (0x2027, 'V'),
- (0x2028, 'X'),
- (0x202F, '3', u' '),
- (0x2030, 'V'),
- (0x2033, 'M', u'′′'),
- (0x2034, 'M', u'′′′'),
- (0x2035, 'V'),
- (0x2036, 'M', u'‵‵'),
- (0x2037, 'M', u'‵‵‵'),
- (0x2038, 'V'),
- (0x203C, '3', u'!!'),
- (0x203D, 'V'),
- (0x203E, '3', u' Ì…'),
- (0x203F, 'V'),
- (0x2047, '3', u'??'),
- (0x2048, '3', u'?!'),
- (0x2049, '3', u'!?'),
- (0x204A, 'V'),
- (0x2057, 'M', u'′′′′'),
- (0x2058, 'V'),
- ]
-
-def _seg_21():
- return [
- (0x205F, '3', u' '),
- (0x2060, 'I'),
- (0x2061, 'X'),
- (0x2064, 'I'),
- (0x2065, 'X'),
- (0x2070, 'M', u'0'),
- (0x2071, 'M', u'i'),
- (0x2072, 'X'),
- (0x2074, 'M', u'4'),
- (0x2075, 'M', u'5'),
- (0x2076, 'M', u'6'),
- (0x2077, 'M', u'7'),
- (0x2078, 'M', u'8'),
- (0x2079, 'M', u'9'),
- (0x207A, '3', u'+'),
- (0x207B, 'M', u'−'),
- (0x207C, '3', u'='),
- (0x207D, '3', u'('),
- (0x207E, '3', u')'),
- (0x207F, 'M', u'n'),
- (0x2080, 'M', u'0'),
- (0x2081, 'M', u'1'),
- (0x2082, 'M', u'2'),
- (0x2083, 'M', u'3'),
- (0x2084, 'M', u'4'),
- (0x2085, 'M', u'5'),
- (0x2086, 'M', u'6'),
- (0x2087, 'M', u'7'),
- (0x2088, 'M', u'8'),
- (0x2089, 'M', u'9'),
- (0x208A, '3', u'+'),
- (0x208B, 'M', u'−'),
- (0x208C, '3', u'='),
- (0x208D, '3', u'('),
- (0x208E, '3', u')'),
- (0x208F, 'X'),
- (0x2090, 'M', u'a'),
- (0x2091, 'M', u'e'),
- (0x2092, 'M', u'o'),
- (0x2093, 'M', u'x'),
- (0x2094, 'M', u'É™'),
- (0x2095, 'M', u'h'),
- (0x2096, 'M', u'k'),
- (0x2097, 'M', u'l'),
- (0x2098, 'M', u'm'),
- (0x2099, 'M', u'n'),
- (0x209A, 'M', u'p'),
- (0x209B, 'M', u's'),
- (0x209C, 'M', u't'),
- (0x209D, 'X'),
- (0x20A0, 'V'),
- (0x20A8, 'M', u'rs'),
- (0x20A9, 'V'),
- (0x20BB, 'X'),
- (0x20D0, 'V'),
- (0x20F1, 'X'),
- (0x2100, '3', u'a/c'),
- (0x2101, '3', u'a/s'),
- (0x2102, 'M', u'c'),
- (0x2103, 'M', u'°c'),
- (0x2104, 'V'),
- (0x2105, '3', u'c/o'),
- (0x2106, '3', u'c/u'),
- (0x2107, 'M', u'É›'),
- (0x2108, 'V'),
- (0x2109, 'M', u'°f'),
- (0x210A, 'M', u'g'),
- (0x210B, 'M', u'h'),
- (0x210F, 'M', u'ħ'),
- (0x2110, 'M', u'i'),
- (0x2112, 'M', u'l'),
- (0x2114, 'V'),
- (0x2115, 'M', u'n'),
- (0x2116, 'M', u'no'),
- (0x2117, 'V'),
- (0x2119, 'M', u'p'),
- (0x211A, 'M', u'q'),
- (0x211B, 'M', u'r'),
- (0x211E, 'V'),
- (0x2120, 'M', u'sm'),
- (0x2121, 'M', u'tel'),
- (0x2122, 'M', u'tm'),
- (0x2123, 'V'),
- (0x2124, 'M', u'z'),
- (0x2125, 'V'),
- (0x2126, 'M', u'ω'),
- (0x2127, 'V'),
- (0x2128, 'M', u'z'),
- (0x2129, 'V'),
- (0x212A, 'M', u'k'),
- (0x212B, 'M', u'Ã¥'),
- (0x212C, 'M', u'b'),
- (0x212D, 'M', u'c'),
- (0x212E, 'V'),
- (0x212F, 'M', u'e'),
- (0x2131, 'M', u'f'),
- (0x2132, 'X'),
- (0x2133, 'M', u'm'),
- (0x2134, 'M', u'o'),
- (0x2135, 'M', u'×'),
- ]
-
-def _seg_22():
- return [
- (0x2136, 'M', u'ב'),
- (0x2137, 'M', u'×’'),
- (0x2138, 'M', u'ד'),
- (0x2139, 'M', u'i'),
- (0x213A, 'V'),
- (0x213B, 'M', u'fax'),
- (0x213C, 'M', u'Ï€'),
- (0x213D, 'M', u'γ'),
- (0x213F, 'M', u'Ï€'),
- (0x2140, 'M', u'∑'),
- (0x2141, 'V'),
- (0x2145, 'M', u'd'),
- (0x2147, 'M', u'e'),
- (0x2148, 'M', u'i'),
- (0x2149, 'M', u'j'),
- (0x214A, 'V'),
- (0x2150, 'M', u'1â„7'),
- (0x2151, 'M', u'1â„9'),
- (0x2152, 'M', u'1â„10'),
- (0x2153, 'M', u'1â„3'),
- (0x2154, 'M', u'2â„3'),
- (0x2155, 'M', u'1â„5'),
- (0x2156, 'M', u'2â„5'),
- (0x2157, 'M', u'3â„5'),
- (0x2158, 'M', u'4â„5'),
- (0x2159, 'M', u'1â„6'),
- (0x215A, 'M', u'5â„6'),
- (0x215B, 'M', u'1â„8'),
- (0x215C, 'M', u'3â„8'),
- (0x215D, 'M', u'5â„8'),
- (0x215E, 'M', u'7â„8'),
- (0x215F, 'M', u'1â„'),
- (0x2160, 'M', u'i'),
- (0x2161, 'M', u'ii'),
- (0x2162, 'M', u'iii'),
- (0x2163, 'M', u'iv'),
- (0x2164, 'M', u'v'),
- (0x2165, 'M', u'vi'),
- (0x2166, 'M', u'vii'),
- (0x2167, 'M', u'viii'),
- (0x2168, 'M', u'ix'),
- (0x2169, 'M', u'x'),
- (0x216A, 'M', u'xi'),
- (0x216B, 'M', u'xii'),
- (0x216C, 'M', u'l'),
- (0x216D, 'M', u'c'),
- (0x216E, 'M', u'd'),
- (0x216F, 'M', u'm'),
- (0x2170, 'M', u'i'),
- (0x2171, 'M', u'ii'),
- (0x2172, 'M', u'iii'),
- (0x2173, 'M', u'iv'),
- (0x2174, 'M', u'v'),
- (0x2175, 'M', u'vi'),
- (0x2176, 'M', u'vii'),
- (0x2177, 'M', u'viii'),
- (0x2178, 'M', u'ix'),
- (0x2179, 'M', u'x'),
- (0x217A, 'M', u'xi'),
- (0x217B, 'M', u'xii'),
- (0x217C, 'M', u'l'),
- (0x217D, 'M', u'c'),
- (0x217E, 'M', u'd'),
- (0x217F, 'M', u'm'),
- (0x2180, 'V'),
- (0x2183, 'X'),
- (0x2184, 'V'),
- (0x2189, 'M', u'0â„3'),
- (0x218A, 'X'),
- (0x2190, 'V'),
- (0x222C, 'M', u'∫∫'),
- (0x222D, 'M', u'∫∫∫'),
- (0x222E, 'V'),
- (0x222F, 'M', u'∮∮'),
- (0x2230, 'M', u'∮∮∮'),
- (0x2231, 'V'),
- (0x2260, '3'),
- (0x2261, 'V'),
- (0x226E, '3'),
- (0x2270, 'V'),
- (0x2329, 'M', u'〈'),
- (0x232A, 'M', u'〉'),
- (0x232B, 'V'),
- (0x23F4, 'X'),
- (0x2400, 'V'),
- (0x2427, 'X'),
- (0x2440, 'V'),
- (0x244B, 'X'),
- (0x2460, 'M', u'1'),
- (0x2461, 'M', u'2'),
- (0x2462, 'M', u'3'),
- (0x2463, 'M', u'4'),
- (0x2464, 'M', u'5'),
- (0x2465, 'M', u'6'),
- (0x2466, 'M', u'7'),
- (0x2467, 'M', u'8'),
- (0x2468, 'M', u'9'),
- (0x2469, 'M', u'10'),
- (0x246A, 'M', u'11'),
- (0x246B, 'M', u'12'),
- ]
-
-def _seg_23():
- return [
- (0x246C, 'M', u'13'),
- (0x246D, 'M', u'14'),
- (0x246E, 'M', u'15'),
- (0x246F, 'M', u'16'),
- (0x2470, 'M', u'17'),
- (0x2471, 'M', u'18'),
- (0x2472, 'M', u'19'),
- (0x2473, 'M', u'20'),
- (0x2474, '3', u'(1)'),
- (0x2475, '3', u'(2)'),
- (0x2476, '3', u'(3)'),
- (0x2477, '3', u'(4)'),
- (0x2478, '3', u'(5)'),
- (0x2479, '3', u'(6)'),
- (0x247A, '3', u'(7)'),
- (0x247B, '3', u'(8)'),
- (0x247C, '3', u'(9)'),
- (0x247D, '3', u'(10)'),
- (0x247E, '3', u'(11)'),
- (0x247F, '3', u'(12)'),
- (0x2480, '3', u'(13)'),
- (0x2481, '3', u'(14)'),
- (0x2482, '3', u'(15)'),
- (0x2483, '3', u'(16)'),
- (0x2484, '3', u'(17)'),
- (0x2485, '3', u'(18)'),
- (0x2486, '3', u'(19)'),
- (0x2487, '3', u'(20)'),
- (0x2488, 'X'),
- (0x249C, '3', u'(a)'),
- (0x249D, '3', u'(b)'),
- (0x249E, '3', u'(c)'),
- (0x249F, '3', u'(d)'),
- (0x24A0, '3', u'(e)'),
- (0x24A1, '3', u'(f)'),
- (0x24A2, '3', u'(g)'),
- (0x24A3, '3', u'(h)'),
- (0x24A4, '3', u'(i)'),
- (0x24A5, '3', u'(j)'),
- (0x24A6, '3', u'(k)'),
- (0x24A7, '3', u'(l)'),
- (0x24A8, '3', u'(m)'),
- (0x24A9, '3', u'(n)'),
- (0x24AA, '3', u'(o)'),
- (0x24AB, '3', u'(p)'),
- (0x24AC, '3', u'(q)'),
- (0x24AD, '3', u'(r)'),
- (0x24AE, '3', u'(s)'),
- (0x24AF, '3', u'(t)'),
- (0x24B0, '3', u'(u)'),
- (0x24B1, '3', u'(v)'),
- (0x24B2, '3', u'(w)'),
- (0x24B3, '3', u'(x)'),
- (0x24B4, '3', u'(y)'),
- (0x24B5, '3', u'(z)'),
- (0x24B6, 'M', u'a'),
- (0x24B7, 'M', u'b'),
- (0x24B8, 'M', u'c'),
- (0x24B9, 'M', u'd'),
- (0x24BA, 'M', u'e'),
- (0x24BB, 'M', u'f'),
- (0x24BC, 'M', u'g'),
- (0x24BD, 'M', u'h'),
- (0x24BE, 'M', u'i'),
- (0x24BF, 'M', u'j'),
- (0x24C0, 'M', u'k'),
- (0x24C1, 'M', u'l'),
- (0x24C2, 'M', u'm'),
- (0x24C3, 'M', u'n'),
- (0x24C4, 'M', u'o'),
- (0x24C5, 'M', u'p'),
- (0x24C6, 'M', u'q'),
- (0x24C7, 'M', u'r'),
- (0x24C8, 'M', u's'),
- (0x24C9, 'M', u't'),
- (0x24CA, 'M', u'u'),
- (0x24CB, 'M', u'v'),
- (0x24CC, 'M', u'w'),
- (0x24CD, 'M', u'x'),
- (0x24CE, 'M', u'y'),
- (0x24CF, 'M', u'z'),
- (0x24D0, 'M', u'a'),
- (0x24D1, 'M', u'b'),
- (0x24D2, 'M', u'c'),
- (0x24D3, 'M', u'd'),
- (0x24D4, 'M', u'e'),
- (0x24D5, 'M', u'f'),
- (0x24D6, 'M', u'g'),
- (0x24D7, 'M', u'h'),
- (0x24D8, 'M', u'i'),
- (0x24D9, 'M', u'j'),
- (0x24DA, 'M', u'k'),
- (0x24DB, 'M', u'l'),
- (0x24DC, 'M', u'm'),
- (0x24DD, 'M', u'n'),
- (0x24DE, 'M', u'o'),
- (0x24DF, 'M', u'p'),
- (0x24E0, 'M', u'q'),
- (0x24E1, 'M', u'r'),
- (0x24E2, 'M', u's'),
- ]
-
-def _seg_24():
- return [
- (0x24E3, 'M', u't'),
- (0x24E4, 'M', u'u'),
- (0x24E5, 'M', u'v'),
- (0x24E6, 'M', u'w'),
- (0x24E7, 'M', u'x'),
- (0x24E8, 'M', u'y'),
- (0x24E9, 'M', u'z'),
- (0x24EA, 'M', u'0'),
- (0x24EB, 'V'),
- (0x2700, 'X'),
- (0x2701, 'V'),
- (0x2A0C, 'M', u'∫∫∫∫'),
- (0x2A0D, 'V'),
- (0x2A74, '3', u'::='),
- (0x2A75, '3', u'=='),
- (0x2A76, '3', u'==='),
- (0x2A77, 'V'),
- (0x2ADC, 'M', u'â«Ì¸'),
- (0x2ADD, 'V'),
- (0x2B4D, 'X'),
- (0x2B50, 'V'),
- (0x2B5A, 'X'),
- (0x2C00, 'M', u'â°°'),
- (0x2C01, 'M', u'â°±'),
- (0x2C02, 'M', u'â°²'),
- (0x2C03, 'M', u'â°³'),
- (0x2C04, 'M', u'â°´'),
- (0x2C05, 'M', u'â°µ'),
- (0x2C06, 'M', u'â°¶'),
- (0x2C07, 'M', u'â°·'),
- (0x2C08, 'M', u'â°¸'),
- (0x2C09, 'M', u'â°¹'),
- (0x2C0A, 'M', u'â°º'),
- (0x2C0B, 'M', u'â°»'),
- (0x2C0C, 'M', u'â°¼'),
- (0x2C0D, 'M', u'â°½'),
- (0x2C0E, 'M', u'â°¾'),
- (0x2C0F, 'M', u'â°¿'),
- (0x2C10, 'M', u'â±€'),
- (0x2C11, 'M', u'â±'),
- (0x2C12, 'M', u'ⱂ'),
- (0x2C13, 'M', u'ⱃ'),
- (0x2C14, 'M', u'ⱄ'),
- (0x2C15, 'M', u'â±…'),
- (0x2C16, 'M', u'ⱆ'),
- (0x2C17, 'M', u'ⱇ'),
- (0x2C18, 'M', u'ⱈ'),
- (0x2C19, 'M', u'ⱉ'),
- (0x2C1A, 'M', u'ⱊ'),
- (0x2C1B, 'M', u'ⱋ'),
- (0x2C1C, 'M', u'ⱌ'),
- (0x2C1D, 'M', u'â±'),
- (0x2C1E, 'M', u'ⱎ'),
- (0x2C1F, 'M', u'â±'),
- (0x2C20, 'M', u'â±'),
- (0x2C21, 'M', u'ⱑ'),
- (0x2C22, 'M', u'â±’'),
- (0x2C23, 'M', u'ⱓ'),
- (0x2C24, 'M', u'â±”'),
- (0x2C25, 'M', u'ⱕ'),
- (0x2C26, 'M', u'â±–'),
- (0x2C27, 'M', u'â±—'),
- (0x2C28, 'M', u'ⱘ'),
- (0x2C29, 'M', u'â±™'),
- (0x2C2A, 'M', u'ⱚ'),
- (0x2C2B, 'M', u'â±›'),
- (0x2C2C, 'M', u'ⱜ'),
- (0x2C2D, 'M', u'â±'),
- (0x2C2E, 'M', u'ⱞ'),
- (0x2C2F, 'X'),
- (0x2C30, 'V'),
- (0x2C5F, 'X'),
- (0x2C60, 'M', u'ⱡ'),
- (0x2C61, 'V'),
- (0x2C62, 'M', u'É«'),
- (0x2C63, 'M', u'áµ½'),
- (0x2C64, 'M', u'ɽ'),
- (0x2C65, 'V'),
- (0x2C67, 'M', u'ⱨ'),
- (0x2C68, 'V'),
- (0x2C69, 'M', u'ⱪ'),
- (0x2C6A, 'V'),
- (0x2C6B, 'M', u'ⱬ'),
- (0x2C6C, 'V'),
- (0x2C6D, 'M', u'É‘'),
- (0x2C6E, 'M', u'ɱ'),
- (0x2C6F, 'M', u'É'),
- (0x2C70, 'M', u'É’'),
- (0x2C71, 'V'),
- (0x2C72, 'M', u'â±³'),
- (0x2C73, 'V'),
- (0x2C75, 'M', u'ⱶ'),
- (0x2C76, 'V'),
- (0x2C7C, 'M', u'j'),
- (0x2C7D, 'M', u'v'),
- (0x2C7E, 'M', u'È¿'),
- (0x2C7F, 'M', u'É€'),
- (0x2C80, 'M', u'â²'),
- (0x2C81, 'V'),
- (0x2C82, 'M', u'ⲃ'),
- ]
-
-def _seg_25():
- return [
- (0x2C83, 'V'),
- (0x2C84, 'M', u'â²…'),
- (0x2C85, 'V'),
- (0x2C86, 'M', u'ⲇ'),
- (0x2C87, 'V'),
- (0x2C88, 'M', u'ⲉ'),
- (0x2C89, 'V'),
- (0x2C8A, 'M', u'ⲋ'),
- (0x2C8B, 'V'),
- (0x2C8C, 'M', u'â²'),
- (0x2C8D, 'V'),
- (0x2C8E, 'M', u'â²'),
- (0x2C8F, 'V'),
- (0x2C90, 'M', u'ⲑ'),
- (0x2C91, 'V'),
- (0x2C92, 'M', u'ⲓ'),
- (0x2C93, 'V'),
- (0x2C94, 'M', u'ⲕ'),
- (0x2C95, 'V'),
- (0x2C96, 'M', u'â²—'),
- (0x2C97, 'V'),
- (0x2C98, 'M', u'â²™'),
- (0x2C99, 'V'),
- (0x2C9A, 'M', u'â²›'),
- (0x2C9B, 'V'),
- (0x2C9C, 'M', u'â²'),
- (0x2C9D, 'V'),
- (0x2C9E, 'M', u'ⲟ'),
- (0x2C9F, 'V'),
- (0x2CA0, 'M', u'ⲡ'),
- (0x2CA1, 'V'),
- (0x2CA2, 'M', u'â²£'),
- (0x2CA3, 'V'),
- (0x2CA4, 'M', u'â²¥'),
- (0x2CA5, 'V'),
- (0x2CA6, 'M', u'ⲧ'),
- (0x2CA7, 'V'),
- (0x2CA8, 'M', u'ⲩ'),
- (0x2CA9, 'V'),
- (0x2CAA, 'M', u'ⲫ'),
- (0x2CAB, 'V'),
- (0x2CAC, 'M', u'â²­'),
- (0x2CAD, 'V'),
- (0x2CAE, 'M', u'ⲯ'),
- (0x2CAF, 'V'),
- (0x2CB0, 'M', u'â²±'),
- (0x2CB1, 'V'),
- (0x2CB2, 'M', u'â²³'),
- (0x2CB3, 'V'),
- (0x2CB4, 'M', u'â²µ'),
- (0x2CB5, 'V'),
- (0x2CB6, 'M', u'â²·'),
- (0x2CB7, 'V'),
- (0x2CB8, 'M', u'â²¹'),
- (0x2CB9, 'V'),
- (0x2CBA, 'M', u'â²»'),
- (0x2CBB, 'V'),
- (0x2CBC, 'M', u'â²½'),
- (0x2CBD, 'V'),
- (0x2CBE, 'M', u'ⲿ'),
- (0x2CBF, 'V'),
- (0x2CC0, 'M', u'â³'),
- (0x2CC1, 'V'),
- (0x2CC2, 'M', u'ⳃ'),
- (0x2CC3, 'V'),
- (0x2CC4, 'M', u'â³…'),
- (0x2CC5, 'V'),
- (0x2CC6, 'M', u'ⳇ'),
- (0x2CC7, 'V'),
- (0x2CC8, 'M', u'ⳉ'),
- (0x2CC9, 'V'),
- (0x2CCA, 'M', u'ⳋ'),
- (0x2CCB, 'V'),
- (0x2CCC, 'M', u'â³'),
- (0x2CCD, 'V'),
- (0x2CCE, 'M', u'â³'),
- (0x2CCF, 'V'),
- (0x2CD0, 'M', u'ⳑ'),
- (0x2CD1, 'V'),
- (0x2CD2, 'M', u'ⳓ'),
- (0x2CD3, 'V'),
- (0x2CD4, 'M', u'ⳕ'),
- (0x2CD5, 'V'),
- (0x2CD6, 'M', u'â³—'),
- (0x2CD7, 'V'),
- (0x2CD8, 'M', u'â³™'),
- (0x2CD9, 'V'),
- (0x2CDA, 'M', u'â³›'),
- (0x2CDB, 'V'),
- (0x2CDC, 'M', u'â³'),
- (0x2CDD, 'V'),
- (0x2CDE, 'M', u'ⳟ'),
- (0x2CDF, 'V'),
- (0x2CE0, 'M', u'ⳡ'),
- (0x2CE1, 'V'),
- (0x2CE2, 'M', u'â³£'),
- (0x2CE3, 'V'),
- (0x2CEB, 'M', u'ⳬ'),
- (0x2CEC, 'V'),
- (0x2CED, 'M', u'â³®'),
- ]
-
-def _seg_26():
- return [
- (0x2CEE, 'V'),
- (0x2CF2, 'M', u'â³³'),
- (0x2CF3, 'V'),
- (0x2CF4, 'X'),
- (0x2CF9, 'V'),
- (0x2D26, 'X'),
- (0x2D27, 'V'),
- (0x2D28, 'X'),
- (0x2D2D, 'V'),
- (0x2D2E, 'X'),
- (0x2D30, 'V'),
- (0x2D68, 'X'),
- (0x2D6F, 'M', u'ⵡ'),
- (0x2D70, 'V'),
- (0x2D71, 'X'),
- (0x2D7F, 'V'),
- (0x2D97, 'X'),
- (0x2DA0, 'V'),
- (0x2DA7, 'X'),
- (0x2DA8, 'V'),
- (0x2DAF, 'X'),
- (0x2DB0, 'V'),
- (0x2DB7, 'X'),
- (0x2DB8, 'V'),
- (0x2DBF, 'X'),
- (0x2DC0, 'V'),
- (0x2DC7, 'X'),
- (0x2DC8, 'V'),
- (0x2DCF, 'X'),
- (0x2DD0, 'V'),
- (0x2DD7, 'X'),
- (0x2DD8, 'V'),
- (0x2DDF, 'X'),
- (0x2DE0, 'V'),
- (0x2E3C, 'X'),
- (0x2E80, 'V'),
- (0x2E9A, 'X'),
- (0x2E9B, 'V'),
- (0x2E9F, 'M', u'æ¯'),
- (0x2EA0, 'V'),
- (0x2EF3, 'M', u'龟'),
- (0x2EF4, 'X'),
- (0x2F00, 'M', u'一'),
- (0x2F01, 'M', u'丨'),
- (0x2F02, 'M', u'丶'),
- (0x2F03, 'M', u'丿'),
- (0x2F04, 'M', u'ä¹™'),
- (0x2F05, 'M', u'亅'),
- (0x2F06, 'M', u'二'),
- (0x2F07, 'M', u'亠'),
- (0x2F08, 'M', u'人'),
- (0x2F09, 'M', u'å„¿'),
- (0x2F0A, 'M', u'å…¥'),
- (0x2F0B, 'M', u'å…«'),
- (0x2F0C, 'M', u'冂'),
- (0x2F0D, 'M', u'冖'),
- (0x2F0E, 'M', u'冫'),
- (0x2F0F, 'M', u'几'),
- (0x2F10, 'M', u'凵'),
- (0x2F11, 'M', u'刀'),
- (0x2F12, 'M', u'力'),
- (0x2F13, 'M', u'勹'),
- (0x2F14, 'M', u'匕'),
- (0x2F15, 'M', u'匚'),
- (0x2F16, 'M', u'匸'),
- (0x2F17, 'M', u'å'),
- (0x2F18, 'M', u'åœ'),
- (0x2F19, 'M', u'å©'),
- (0x2F1A, 'M', u'厂'),
- (0x2F1B, 'M', u'厶'),
- (0x2F1C, 'M', u'åˆ'),
- (0x2F1D, 'M', u'å£'),
- (0x2F1E, 'M', u'å›—'),
- (0x2F1F, 'M', u'土'),
- (0x2F20, 'M', u'士'),
- (0x2F21, 'M', u'夂'),
- (0x2F22, 'M', u'夊'),
- (0x2F23, 'M', u'夕'),
- (0x2F24, 'M', u'大'),
- (0x2F25, 'M', u'女'),
- (0x2F26, 'M', u'å­'),
- (0x2F27, 'M', u'宀'),
- (0x2F28, 'M', u'寸'),
- (0x2F29, 'M', u'å°'),
- (0x2F2A, 'M', u'å°¢'),
- (0x2F2B, 'M', u'å°¸'),
- (0x2F2C, 'M', u'å±®'),
- (0x2F2D, 'M', u'å±±'),
- (0x2F2E, 'M', u'å·›'),
- (0x2F2F, 'M', u'å·¥'),
- (0x2F30, 'M', u'å·±'),
- (0x2F31, 'M', u'å·¾'),
- (0x2F32, 'M', u'å¹²'),
- (0x2F33, 'M', u'幺'),
- (0x2F34, 'M', u'广'),
- (0x2F35, 'M', u'å»´'),
- (0x2F36, 'M', u'廾'),
- (0x2F37, 'M', u'弋'),
- (0x2F38, 'M', u'弓'),
- (0x2F39, 'M', u'å½'),
- ]
-
-def _seg_27():
- return [
- (0x2F3A, 'M', u'彡'),
- (0x2F3B, 'M', u'å½³'),
- (0x2F3C, 'M', u'心'),
- (0x2F3D, 'M', u'戈'),
- (0x2F3E, 'M', u'戶'),
- (0x2F3F, 'M', u'手'),
- (0x2F40, 'M', u'支'),
- (0x2F41, 'M', u'æ”´'),
- (0x2F42, 'M', u'æ–‡'),
- (0x2F43, 'M', u'æ–—'),
- (0x2F44, 'M', u'æ–¤'),
- (0x2F45, 'M', u'æ–¹'),
- (0x2F46, 'M', u'æ— '),
- (0x2F47, 'M', u'æ—¥'),
- (0x2F48, 'M', u'æ›°'),
- (0x2F49, 'M', u'月'),
- (0x2F4A, 'M', u'木'),
- (0x2F4B, 'M', u'欠'),
- (0x2F4C, 'M', u'æ­¢'),
- (0x2F4D, 'M', u'æ­¹'),
- (0x2F4E, 'M', u'殳'),
- (0x2F4F, 'M', u'毋'),
- (0x2F50, 'M', u'比'),
- (0x2F51, 'M', u'毛'),
- (0x2F52, 'M', u'æ°'),
- (0x2F53, 'M', u'æ°”'),
- (0x2F54, 'M', u'æ°´'),
- (0x2F55, 'M', u'ç«'),
- (0x2F56, 'M', u'爪'),
- (0x2F57, 'M', u'父'),
- (0x2F58, 'M', u'爻'),
- (0x2F59, 'M', u'爿'),
- (0x2F5A, 'M', u'片'),
- (0x2F5B, 'M', u'牙'),
- (0x2F5C, 'M', u'牛'),
- (0x2F5D, 'M', u'犬'),
- (0x2F5E, 'M', u'玄'),
- (0x2F5F, 'M', u'玉'),
- (0x2F60, 'M', u'瓜'),
- (0x2F61, 'M', u'瓦'),
- (0x2F62, 'M', u'甘'),
- (0x2F63, 'M', u'生'),
- (0x2F64, 'M', u'用'),
- (0x2F65, 'M', u'ç”°'),
- (0x2F66, 'M', u'ç–‹'),
- (0x2F67, 'M', u'ç–’'),
- (0x2F68, 'M', u'癶'),
- (0x2F69, 'M', u'白'),
- (0x2F6A, 'M', u'çš®'),
- (0x2F6B, 'M', u'çš¿'),
- (0x2F6C, 'M', u'ç›®'),
- (0x2F6D, 'M', u'矛'),
- (0x2F6E, 'M', u'矢'),
- (0x2F6F, 'M', u'石'),
- (0x2F70, 'M', u'示'),
- (0x2F71, 'M', u'禸'),
- (0x2F72, 'M', u'禾'),
- (0x2F73, 'M', u'ç©´'),
- (0x2F74, 'M', u'ç«‹'),
- (0x2F75, 'M', u'竹'),
- (0x2F76, 'M', u'ç±³'),
- (0x2F77, 'M', u'糸'),
- (0x2F78, 'M', u'缶'),
- (0x2F79, 'M', u'网'),
- (0x2F7A, 'M', u'羊'),
- (0x2F7B, 'M', u'ç¾½'),
- (0x2F7C, 'M', u'è€'),
- (0x2F7D, 'M', u'而'),
- (0x2F7E, 'M', u'耒'),
- (0x2F7F, 'M', u'耳'),
- (0x2F80, 'M', u'è¿'),
- (0x2F81, 'M', u'肉'),
- (0x2F82, 'M', u'臣'),
- (0x2F83, 'M', u'自'),
- (0x2F84, 'M', u'至'),
- (0x2F85, 'M', u'臼'),
- (0x2F86, 'M', u'舌'),
- (0x2F87, 'M', u'舛'),
- (0x2F88, 'M', u'舟'),
- (0x2F89, 'M', u'艮'),
- (0x2F8A, 'M', u'色'),
- (0x2F8B, 'M', u'艸'),
- (0x2F8C, 'M', u'è™'),
- (0x2F8D, 'M', u'虫'),
- (0x2F8E, 'M', u'è¡€'),
- (0x2F8F, 'M', u'行'),
- (0x2F90, 'M', u'è¡£'),
- (0x2F91, 'M', u'襾'),
- (0x2F92, 'M', u'見'),
- (0x2F93, 'M', u'角'),
- (0x2F94, 'M', u'言'),
- (0x2F95, 'M', u'è°·'),
- (0x2F96, 'M', u'豆'),
- (0x2F97, 'M', u'豕'),
- (0x2F98, 'M', u'豸'),
- (0x2F99, 'M', u'è²'),
- (0x2F9A, 'M', u'赤'),
- (0x2F9B, 'M', u'èµ°'),
- (0x2F9C, 'M', u'足'),
- (0x2F9D, 'M', u'身'),
- ]
-
-def _seg_28():
- return [
- (0x2F9E, 'M', u'車'),
- (0x2F9F, 'M', u'è¾›'),
- (0x2FA0, 'M', u'è¾°'),
- (0x2FA1, 'M', u'è¾µ'),
- (0x2FA2, 'M', u'é‚‘'),
- (0x2FA3, 'M', u'é…‰'),
- (0x2FA4, 'M', u'釆'),
- (0x2FA5, 'M', u'里'),
- (0x2FA6, 'M', u'金'),
- (0x2FA7, 'M', u'é•·'),
- (0x2FA8, 'M', u'é–€'),
- (0x2FA9, 'M', u'阜'),
- (0x2FAA, 'M', u'隶'),
- (0x2FAB, 'M', u'éš¹'),
- (0x2FAC, 'M', u'雨'),
- (0x2FAD, 'M', u'é‘'),
- (0x2FAE, 'M', u'éž'),
- (0x2FAF, 'M', u'é¢'),
- (0x2FB0, 'M', u'é©'),
- (0x2FB1, 'M', u'韋'),
- (0x2FB2, 'M', u'韭'),
- (0x2FB3, 'M', u'音'),
- (0x2FB4, 'M', u'é '),
- (0x2FB5, 'M', u'風'),
- (0x2FB6, 'M', u'飛'),
- (0x2FB7, 'M', u'食'),
- (0x2FB8, 'M', u'首'),
- (0x2FB9, 'M', u'香'),
- (0x2FBA, 'M', u'馬'),
- (0x2FBB, 'M', u'骨'),
- (0x2FBC, 'M', u'高'),
- (0x2FBD, 'M', u'é«Ÿ'),
- (0x2FBE, 'M', u'鬥'),
- (0x2FBF, 'M', u'鬯'),
- (0x2FC0, 'M', u'鬲'),
- (0x2FC1, 'M', u'鬼'),
- (0x2FC2, 'M', u'é­š'),
- (0x2FC3, 'M', u'é³¥'),
- (0x2FC4, 'M', u'é¹µ'),
- (0x2FC5, 'M', u'鹿'),
- (0x2FC6, 'M', u'麥'),
- (0x2FC7, 'M', u'麻'),
- (0x2FC8, 'M', u'黃'),
- (0x2FC9, 'M', u'é»'),
- (0x2FCA, 'M', u'黑'),
- (0x2FCB, 'M', u'黹'),
- (0x2FCC, 'M', u'黽'),
- (0x2FCD, 'M', u'鼎'),
- (0x2FCE, 'M', u'鼓'),
- (0x2FCF, 'M', u'é¼ '),
- (0x2FD0, 'M', u'é¼»'),
- (0x2FD1, 'M', u'齊'),
- (0x2FD2, 'M', u'é½’'),
- (0x2FD3, 'M', u'é¾'),
- (0x2FD4, 'M', u'龜'),
- (0x2FD5, 'M', u'é¾ '),
- (0x2FD6, 'X'),
- (0x3000, '3', u' '),
- (0x3001, 'V'),
- (0x3002, 'M', u'.'),
- (0x3003, 'V'),
- (0x3036, 'M', u'〒'),
- (0x3037, 'V'),
- (0x3038, 'M', u'å'),
- (0x3039, 'M', u'å„'),
- (0x303A, 'M', u'å…'),
- (0x303B, 'V'),
- (0x3040, 'X'),
- (0x3041, 'V'),
- (0x3097, 'X'),
- (0x3099, 'V'),
- (0x309B, '3', u' ã‚™'),
- (0x309C, '3', u' ã‚š'),
- (0x309D, 'V'),
- (0x309F, 'M', u'より'),
- (0x30A0, 'V'),
- (0x30FF, 'M', u'コト'),
- (0x3100, 'X'),
- (0x3105, 'V'),
- (0x312E, 'X'),
- (0x3131, 'M', u'á„€'),
- (0x3132, 'M', u'á„'),
- (0x3133, 'M', u'ᆪ'),
- (0x3134, 'M', u'á„‚'),
- (0x3135, 'M', u'ᆬ'),
- (0x3136, 'M', u'ᆭ'),
- (0x3137, 'M', u'ᄃ'),
- (0x3138, 'M', u'á„„'),
- (0x3139, 'M', u'á„…'),
- (0x313A, 'M', u'ᆰ'),
- (0x313B, 'M', u'ᆱ'),
- (0x313C, 'M', u'ᆲ'),
- (0x313D, 'M', u'ᆳ'),
- (0x313E, 'M', u'ᆴ'),
- (0x313F, 'M', u'ᆵ'),
- (0x3140, 'M', u'á„š'),
- (0x3141, 'M', u'ᄆ'),
- (0x3142, 'M', u'ᄇ'),
- (0x3143, 'M', u'ᄈ'),
- (0x3144, 'M', u'á„¡'),
- ]
-
-def _seg_29():
- return [
- (0x3145, 'M', u'ᄉ'),
- (0x3146, 'M', u'á„Š'),
- (0x3147, 'M', u'á„‹'),
- (0x3148, 'M', u'ᄌ'),
- (0x3149, 'M', u'á„'),
- (0x314A, 'M', u'á„Ž'),
- (0x314B, 'M', u'á„'),
- (0x314C, 'M', u'á„'),
- (0x314D, 'M', u'á„‘'),
- (0x314E, 'M', u'á„’'),
- (0x314F, 'M', u'á…¡'),
- (0x3150, 'M', u'á…¢'),
- (0x3151, 'M', u'á…£'),
- (0x3152, 'M', u'á…¤'),
- (0x3153, 'M', u'á…¥'),
- (0x3154, 'M', u'á…¦'),
- (0x3155, 'M', u'á…§'),
- (0x3156, 'M', u'á…¨'),
- (0x3157, 'M', u'á…©'),
- (0x3158, 'M', u'á…ª'),
- (0x3159, 'M', u'á…«'),
- (0x315A, 'M', u'á…¬'),
- (0x315B, 'M', u'á…­'),
- (0x315C, 'M', u'á…®'),
- (0x315D, 'M', u'á…¯'),
- (0x315E, 'M', u'á…°'),
- (0x315F, 'M', u'á…±'),
- (0x3160, 'M', u'á…²'),
- (0x3161, 'M', u'á…³'),
- (0x3162, 'M', u'á…´'),
- (0x3163, 'M', u'á…µ'),
- (0x3164, 'X'),
- (0x3165, 'M', u'á„”'),
- (0x3166, 'M', u'á„•'),
- (0x3167, 'M', u'ᇇ'),
- (0x3168, 'M', u'ᇈ'),
- (0x3169, 'M', u'ᇌ'),
- (0x316A, 'M', u'ᇎ'),
- (0x316B, 'M', u'ᇓ'),
- (0x316C, 'M', u'ᇗ'),
- (0x316D, 'M', u'ᇙ'),
- (0x316E, 'M', u'ᄜ'),
- (0x316F, 'M', u'á‡'),
- (0x3170, 'M', u'ᇟ'),
- (0x3171, 'M', u'á„'),
- (0x3172, 'M', u'á„ž'),
- (0x3173, 'M', u'á„ '),
- (0x3174, 'M', u'á„¢'),
- (0x3175, 'M', u'á„£'),
- (0x3176, 'M', u'ᄧ'),
- (0x3177, 'M', u'á„©'),
- (0x3178, 'M', u'á„«'),
- (0x3179, 'M', u'ᄬ'),
- (0x317A, 'M', u'á„­'),
- (0x317B, 'M', u'á„®'),
- (0x317C, 'M', u'ᄯ'),
- (0x317D, 'M', u'ᄲ'),
- (0x317E, 'M', u'ᄶ'),
- (0x317F, 'M', u'á…€'),
- (0x3180, 'M', u'á…‡'),
- (0x3181, 'M', u'ᅌ'),
- (0x3182, 'M', u'ᇱ'),
- (0x3183, 'M', u'ᇲ'),
- (0x3184, 'M', u'á…—'),
- (0x3185, 'M', u'á…˜'),
- (0x3186, 'M', u'á…™'),
- (0x3187, 'M', u'ᆄ'),
- (0x3188, 'M', u'ᆅ'),
- (0x3189, 'M', u'ᆈ'),
- (0x318A, 'M', u'ᆑ'),
- (0x318B, 'M', u'ᆒ'),
- (0x318C, 'M', u'ᆔ'),
- (0x318D, 'M', u'ᆞ'),
- (0x318E, 'M', u'ᆡ'),
- (0x318F, 'X'),
- (0x3190, 'V'),
- (0x3192, 'M', u'一'),
- (0x3193, 'M', u'二'),
- (0x3194, 'M', u'三'),
- (0x3195, 'M', u'å››'),
- (0x3196, 'M', u'上'),
- (0x3197, 'M', u'中'),
- (0x3198, 'M', u'下'),
- (0x3199, 'M', u'甲'),
- (0x319A, 'M', u'ä¹™'),
- (0x319B, 'M', u'丙'),
- (0x319C, 'M', u'ä¸'),
- (0x319D, 'M', u'天'),
- (0x319E, 'M', u'地'),
- (0x319F, 'M', u'人'),
- (0x31A0, 'V'),
- (0x31BB, 'X'),
- (0x31C0, 'V'),
- (0x31E4, 'X'),
- (0x31F0, 'V'),
- (0x3200, '3', u'(á„€)'),
- (0x3201, '3', u'(á„‚)'),
- (0x3202, '3', u'(ᄃ)'),
- (0x3203, '3', u'(á„…)'),
- (0x3204, '3', u'(ᄆ)'),
- ]
-
-def _seg_30():
- return [
- (0x3205, '3', u'(ᄇ)'),
- (0x3206, '3', u'(ᄉ)'),
- (0x3207, '3', u'(á„‹)'),
- (0x3208, '3', u'(ᄌ)'),
- (0x3209, '3', u'(á„Ž)'),
- (0x320A, '3', u'(á„)'),
- (0x320B, '3', u'(á„)'),
- (0x320C, '3', u'(á„‘)'),
- (0x320D, '3', u'(á„’)'),
- (0x320E, '3', u'(ê°€)'),
- (0x320F, '3', u'(나)'),
- (0x3210, '3', u'(다)'),
- (0x3211, '3', u'(ë¼)'),
- (0x3212, '3', u'(마)'),
- (0x3213, '3', u'(ë°”)'),
- (0x3214, '3', u'(사)'),
- (0x3215, '3', u'(ì•„)'),
- (0x3216, '3', u'(ìž)'),
- (0x3217, '3', u'(ì°¨)'),
- (0x3218, '3', u'(ì¹´)'),
- (0x3219, '3', u'(타)'),
- (0x321A, '3', u'(파)'),
- (0x321B, '3', u'(하)'),
- (0x321C, '3', u'(주)'),
- (0x321D, '3', u'(오전)'),
- (0x321E, '3', u'(오후)'),
- (0x321F, 'X'),
- (0x3220, '3', u'(一)'),
- (0x3221, '3', u'(二)'),
- (0x3222, '3', u'(三)'),
- (0x3223, '3', u'(å››)'),
- (0x3224, '3', u'(五)'),
- (0x3225, '3', u'(å…­)'),
- (0x3226, '3', u'(七)'),
- (0x3227, '3', u'(å…«)'),
- (0x3228, '3', u'(ä¹)'),
- (0x3229, '3', u'(å)'),
- (0x322A, '3', u'(月)'),
- (0x322B, '3', u'(ç«)'),
- (0x322C, '3', u'(æ°´)'),
- (0x322D, '3', u'(木)'),
- (0x322E, '3', u'(金)'),
- (0x322F, '3', u'(土)'),
- (0x3230, '3', u'(æ—¥)'),
- (0x3231, '3', u'(æ ª)'),
- (0x3232, '3', u'(有)'),
- (0x3233, '3', u'(社)'),
- (0x3234, '3', u'(å)'),
- (0x3235, '3', u'(特)'),
- (0x3236, '3', u'(財)'),
- (0x3237, '3', u'(ç¥)'),
- (0x3238, '3', u'(労)'),
- (0x3239, '3', u'(代)'),
- (0x323A, '3', u'(呼)'),
- (0x323B, '3', u'(å­¦)'),
- (0x323C, '3', u'(監)'),
- (0x323D, '3', u'(ä¼)'),
- (0x323E, '3', u'(資)'),
- (0x323F, '3', u'(å”)'),
- (0x3240, '3', u'(祭)'),
- (0x3241, '3', u'(休)'),
- (0x3242, '3', u'(自)'),
- (0x3243, '3', u'(至)'),
- (0x3244, 'M', u'å•'),
- (0x3245, 'M', u'å¹¼'),
- (0x3246, 'M', u'æ–‡'),
- (0x3247, 'M', u'ç®'),
- (0x3248, 'V'),
- (0x3250, 'M', u'pte'),
- (0x3251, 'M', u'21'),
- (0x3252, 'M', u'22'),
- (0x3253, 'M', u'23'),
- (0x3254, 'M', u'24'),
- (0x3255, 'M', u'25'),
- (0x3256, 'M', u'26'),
- (0x3257, 'M', u'27'),
- (0x3258, 'M', u'28'),
- (0x3259, 'M', u'29'),
- (0x325A, 'M', u'30'),
- (0x325B, 'M', u'31'),
- (0x325C, 'M', u'32'),
- (0x325D, 'M', u'33'),
- (0x325E, 'M', u'34'),
- (0x325F, 'M', u'35'),
- (0x3260, 'M', u'á„€'),
- (0x3261, 'M', u'á„‚'),
- (0x3262, 'M', u'ᄃ'),
- (0x3263, 'M', u'á„…'),
- (0x3264, 'M', u'ᄆ'),
- (0x3265, 'M', u'ᄇ'),
- (0x3266, 'M', u'ᄉ'),
- (0x3267, 'M', u'á„‹'),
- (0x3268, 'M', u'ᄌ'),
- (0x3269, 'M', u'á„Ž'),
- (0x326A, 'M', u'á„'),
- (0x326B, 'M', u'á„'),
- (0x326C, 'M', u'á„‘'),
- (0x326D, 'M', u'á„’'),
- (0x326E, 'M', u'ê°€'),
- (0x326F, 'M', u'나'),
- ]
-
-def _seg_31():
- return [
- (0x3270, 'M', u'다'),
- (0x3271, 'M', u'ë¼'),
- (0x3272, 'M', u'마'),
- (0x3273, 'M', u'ë°”'),
- (0x3274, 'M', u'사'),
- (0x3275, 'M', u'ì•„'),
- (0x3276, 'M', u'ìž'),
- (0x3277, 'M', u'ì°¨'),
- (0x3278, 'M', u'ì¹´'),
- (0x3279, 'M', u'타'),
- (0x327A, 'M', u'파'),
- (0x327B, 'M', u'하'),
- (0x327C, 'M', u'참고'),
- (0x327D, 'M', u'주ì˜'),
- (0x327E, 'M', u'ìš°'),
- (0x327F, 'V'),
- (0x3280, 'M', u'一'),
- (0x3281, 'M', u'二'),
- (0x3282, 'M', u'三'),
- (0x3283, 'M', u'å››'),
- (0x3284, 'M', u'五'),
- (0x3285, 'M', u'å…­'),
- (0x3286, 'M', u'七'),
- (0x3287, 'M', u'å…«'),
- (0x3288, 'M', u'ä¹'),
- (0x3289, 'M', u'å'),
- (0x328A, 'M', u'月'),
- (0x328B, 'M', u'ç«'),
- (0x328C, 'M', u'æ°´'),
- (0x328D, 'M', u'木'),
- (0x328E, 'M', u'金'),
- (0x328F, 'M', u'土'),
- (0x3290, 'M', u'æ—¥'),
- (0x3291, 'M', u'æ ª'),
- (0x3292, 'M', u'有'),
- (0x3293, 'M', u'社'),
- (0x3294, 'M', u'å'),
- (0x3295, 'M', u'特'),
- (0x3296, 'M', u'財'),
- (0x3297, 'M', u'ç¥'),
- (0x3298, 'M', u'労'),
- (0x3299, 'M', u'秘'),
- (0x329A, 'M', u'ç”·'),
- (0x329B, 'M', u'女'),
- (0x329C, 'M', u'é©'),
- (0x329D, 'M', u'優'),
- (0x329E, 'M', u'å°'),
- (0x329F, 'M', u'注'),
- (0x32A0, 'M', u'é …'),
- (0x32A1, 'M', u'休'),
- (0x32A2, 'M', u'写'),
- (0x32A3, 'M', u'æ­£'),
- (0x32A4, 'M', u'上'),
- (0x32A5, 'M', u'中'),
- (0x32A6, 'M', u'下'),
- (0x32A7, 'M', u'å·¦'),
- (0x32A8, 'M', u'å³'),
- (0x32A9, 'M', u'医'),
- (0x32AA, 'M', u'å®—'),
- (0x32AB, 'M', u'å­¦'),
- (0x32AC, 'M', u'監'),
- (0x32AD, 'M', u'ä¼'),
- (0x32AE, 'M', u'資'),
- (0x32AF, 'M', u'å”'),
- (0x32B0, 'M', u'夜'),
- (0x32B1, 'M', u'36'),
- (0x32B2, 'M', u'37'),
- (0x32B3, 'M', u'38'),
- (0x32B4, 'M', u'39'),
- (0x32B5, 'M', u'40'),
- (0x32B6, 'M', u'41'),
- (0x32B7, 'M', u'42'),
- (0x32B8, 'M', u'43'),
- (0x32B9, 'M', u'44'),
- (0x32BA, 'M', u'45'),
- (0x32BB, 'M', u'46'),
- (0x32BC, 'M', u'47'),
- (0x32BD, 'M', u'48'),
- (0x32BE, 'M', u'49'),
- (0x32BF, 'M', u'50'),
- (0x32C0, 'M', u'1月'),
- (0x32C1, 'M', u'2月'),
- (0x32C2, 'M', u'3月'),
- (0x32C3, 'M', u'4月'),
- (0x32C4, 'M', u'5月'),
- (0x32C5, 'M', u'6月'),
- (0x32C6, 'M', u'7月'),
- (0x32C7, 'M', u'8月'),
- (0x32C8, 'M', u'9月'),
- (0x32C9, 'M', u'10月'),
- (0x32CA, 'M', u'11月'),
- (0x32CB, 'M', u'12月'),
- (0x32CC, 'M', u'hg'),
- (0x32CD, 'M', u'erg'),
- (0x32CE, 'M', u'ev'),
- (0x32CF, 'M', u'ltd'),
- (0x32D0, 'M', u'ã‚¢'),
- (0x32D1, 'M', u'イ'),
- (0x32D2, 'M', u'ウ'),
- (0x32D3, 'M', u'エ'),
- ]
-
-def _seg_32():
- return [
- (0x32D4, 'M', u'オ'),
- (0x32D5, 'M', u'ã‚«'),
- (0x32D6, 'M', u'ã‚­'),
- (0x32D7, 'M', u'ク'),
- (0x32D8, 'M', u'ケ'),
- (0x32D9, 'M', u'コ'),
- (0x32DA, 'M', u'サ'),
- (0x32DB, 'M', u'ã‚·'),
- (0x32DC, 'M', u'ス'),
- (0x32DD, 'M', u'ã‚»'),
- (0x32DE, 'M', u'ソ'),
- (0x32DF, 'M', u'ã‚¿'),
- (0x32E0, 'M', u'ãƒ'),
- (0x32E1, 'M', u'ツ'),
- (0x32E2, 'M', u'テ'),
- (0x32E3, 'M', u'ト'),
- (0x32E4, 'M', u'ナ'),
- (0x32E5, 'M', u'ニ'),
- (0x32E6, 'M', u'ヌ'),
- (0x32E7, 'M', u'ãƒ'),
- (0x32E8, 'M', u'ノ'),
- (0x32E9, 'M', u'ãƒ'),
- (0x32EA, 'M', u'ヒ'),
- (0x32EB, 'M', u'フ'),
- (0x32EC, 'M', u'ヘ'),
- (0x32ED, 'M', u'ホ'),
- (0x32EE, 'M', u'マ'),
- (0x32EF, 'M', u'ミ'),
- (0x32F0, 'M', u'ム'),
- (0x32F1, 'M', u'メ'),
- (0x32F2, 'M', u'モ'),
- (0x32F3, 'M', u'ヤ'),
- (0x32F4, 'M', u'ユ'),
- (0x32F5, 'M', u'ヨ'),
- (0x32F6, 'M', u'ラ'),
- (0x32F7, 'M', u'リ'),
- (0x32F8, 'M', u'ル'),
- (0x32F9, 'M', u'レ'),
- (0x32FA, 'M', u'ロ'),
- (0x32FB, 'M', u'ワ'),
- (0x32FC, 'M', u'ヰ'),
- (0x32FD, 'M', u'ヱ'),
- (0x32FE, 'M', u'ヲ'),
- (0x32FF, 'X'),
- (0x3300, 'M', u'アパート'),
- (0x3301, 'M', u'アルファ'),
- (0x3302, 'M', u'アンペア'),
- (0x3303, 'M', u'アール'),
- (0x3304, 'M', u'イニング'),
- (0x3305, 'M', u'インãƒ'),
- (0x3306, 'M', u'ウォン'),
- (0x3307, 'M', u'エスクード'),
- (0x3308, 'M', u'エーカー'),
- (0x3309, 'M', u'オンス'),
- (0x330A, 'M', u'オーム'),
- (0x330B, 'M', u'カイリ'),
- (0x330C, 'M', u'カラット'),
- (0x330D, 'M', u'カロリー'),
- (0x330E, 'M', u'ガロン'),
- (0x330F, 'M', u'ガンマ'),
- (0x3310, 'M', u'ギガ'),
- (0x3311, 'M', u'ギニー'),
- (0x3312, 'M', u'キュリー'),
- (0x3313, 'M', u'ギルダー'),
- (0x3314, 'M', u'キロ'),
- (0x3315, 'M', u'キログラム'),
- (0x3316, 'M', u'キロメートル'),
- (0x3317, 'M', u'キロワット'),
- (0x3318, 'M', u'グラム'),
- (0x3319, 'M', u'グラムトン'),
- (0x331A, 'M', u'クルゼイロ'),
- (0x331B, 'M', u'クローãƒ'),
- (0x331C, 'M', u'ケース'),
- (0x331D, 'M', u'コルナ'),
- (0x331E, 'M', u'コーãƒ'),
- (0x331F, 'M', u'サイクル'),
- (0x3320, 'M', u'サンãƒãƒ¼ãƒ '),
- (0x3321, 'M', u'シリング'),
- (0x3322, 'M', u'センãƒ'),
- (0x3323, 'M', u'セント'),
- (0x3324, 'M', u'ダース'),
- (0x3325, 'M', u'デシ'),
- (0x3326, 'M', u'ドル'),
- (0x3327, 'M', u'トン'),
- (0x3328, 'M', u'ナノ'),
- (0x3329, 'M', u'ノット'),
- (0x332A, 'M', u'ãƒã‚¤ãƒ„'),
- (0x332B, 'M', u'パーセント'),
- (0x332C, 'M', u'パーツ'),
- (0x332D, 'M', u'ãƒãƒ¼ãƒ¬ãƒ«'),
- (0x332E, 'M', u'ピアストル'),
- (0x332F, 'M', u'ピクル'),
- (0x3330, 'M', u'ピコ'),
- (0x3331, 'M', u'ビル'),
- (0x3332, 'M', u'ファラッド'),
- (0x3333, 'M', u'フィート'),
- (0x3334, 'M', u'ブッシェル'),
- (0x3335, 'M', u'フラン'),
- (0x3336, 'M', u'ヘクタール'),
- (0x3337, 'M', u'ペソ'),
- ]
-
-def _seg_33():
- return [
- (0x3338, 'M', u'ペニヒ'),
- (0x3339, 'M', u'ヘルツ'),
- (0x333A, 'M', u'ペンス'),
- (0x333B, 'M', u'ページ'),
- (0x333C, 'M', u'ベータ'),
- (0x333D, 'M', u'ãƒã‚¤ãƒ³ãƒˆ'),
- (0x333E, 'M', u'ボルト'),
- (0x333F, 'M', u'ホン'),
- (0x3340, 'M', u'ãƒãƒ³ãƒ‰'),
- (0x3341, 'M', u'ホール'),
- (0x3342, 'M', u'ホーン'),
- (0x3343, 'M', u'マイクロ'),
- (0x3344, 'M', u'マイル'),
- (0x3345, 'M', u'マッãƒ'),
- (0x3346, 'M', u'マルク'),
- (0x3347, 'M', u'マンション'),
- (0x3348, 'M', u'ミクロン'),
- (0x3349, 'M', u'ミリ'),
- (0x334A, 'M', u'ミリãƒãƒ¼ãƒ«'),
- (0x334B, 'M', u'メガ'),
- (0x334C, 'M', u'メガトン'),
- (0x334D, 'M', u'メートル'),
- (0x334E, 'M', u'ヤード'),
- (0x334F, 'M', u'ヤール'),
- (0x3350, 'M', u'ユアン'),
- (0x3351, 'M', u'リットル'),
- (0x3352, 'M', u'リラ'),
- (0x3353, 'M', u'ルピー'),
- (0x3354, 'M', u'ルーブル'),
- (0x3355, 'M', u'レム'),
- (0x3356, 'M', u'レントゲン'),
- (0x3357, 'M', u'ワット'),
- (0x3358, 'M', u'0点'),
- (0x3359, 'M', u'1点'),
- (0x335A, 'M', u'2点'),
- (0x335B, 'M', u'3点'),
- (0x335C, 'M', u'4点'),
- (0x335D, 'M', u'5点'),
- (0x335E, 'M', u'6点'),
- (0x335F, 'M', u'7点'),
- (0x3360, 'M', u'8点'),
- (0x3361, 'M', u'9点'),
- (0x3362, 'M', u'10点'),
- (0x3363, 'M', u'11点'),
- (0x3364, 'M', u'12点'),
- (0x3365, 'M', u'13点'),
- (0x3366, 'M', u'14点'),
- (0x3367, 'M', u'15点'),
- (0x3368, 'M', u'16点'),
- (0x3369, 'M', u'17点'),
- (0x336A, 'M', u'18点'),
- (0x336B, 'M', u'19点'),
- (0x336C, 'M', u'20点'),
- (0x336D, 'M', u'21点'),
- (0x336E, 'M', u'22点'),
- (0x336F, 'M', u'23点'),
- (0x3370, 'M', u'24点'),
- (0x3371, 'M', u'hpa'),
- (0x3372, 'M', u'da'),
- (0x3373, 'M', u'au'),
- (0x3374, 'M', u'bar'),
- (0x3375, 'M', u'ov'),
- (0x3376, 'M', u'pc'),
- (0x3377, 'M', u'dm'),
- (0x3378, 'M', u'dm2'),
- (0x3379, 'M', u'dm3'),
- (0x337A, 'M', u'iu'),
- (0x337B, 'M', u'å¹³æˆ'),
- (0x337C, 'M', u'昭和'),
- (0x337D, 'M', u'大正'),
- (0x337E, 'M', u'明治'),
- (0x337F, 'M', u'æ ªå¼ä¼šç¤¾'),
- (0x3380, 'M', u'pa'),
- (0x3381, 'M', u'na'),
- (0x3382, 'M', u'μa'),
- (0x3383, 'M', u'ma'),
- (0x3384, 'M', u'ka'),
- (0x3385, 'M', u'kb'),
- (0x3386, 'M', u'mb'),
- (0x3387, 'M', u'gb'),
- (0x3388, 'M', u'cal'),
- (0x3389, 'M', u'kcal'),
- (0x338A, 'M', u'pf'),
- (0x338B, 'M', u'nf'),
- (0x338C, 'M', u'μf'),
- (0x338D, 'M', u'μg'),
- (0x338E, 'M', u'mg'),
- (0x338F, 'M', u'kg'),
- (0x3390, 'M', u'hz'),
- (0x3391, 'M', u'khz'),
- (0x3392, 'M', u'mhz'),
- (0x3393, 'M', u'ghz'),
- (0x3394, 'M', u'thz'),
- (0x3395, 'M', u'μl'),
- (0x3396, 'M', u'ml'),
- (0x3397, 'M', u'dl'),
- (0x3398, 'M', u'kl'),
- (0x3399, 'M', u'fm'),
- (0x339A, 'M', u'nm'),
- (0x339B, 'M', u'μm'),
- ]
-
-def _seg_34():
- return [
- (0x339C, 'M', u'mm'),
- (0x339D, 'M', u'cm'),
- (0x339E, 'M', u'km'),
- (0x339F, 'M', u'mm2'),
- (0x33A0, 'M', u'cm2'),
- (0x33A1, 'M', u'm2'),
- (0x33A2, 'M', u'km2'),
- (0x33A3, 'M', u'mm3'),
- (0x33A4, 'M', u'cm3'),
- (0x33A5, 'M', u'm3'),
- (0x33A6, 'M', u'km3'),
- (0x33A7, 'M', u'm∕s'),
- (0x33A8, 'M', u'm∕s2'),
- (0x33A9, 'M', u'pa'),
- (0x33AA, 'M', u'kpa'),
- (0x33AB, 'M', u'mpa'),
- (0x33AC, 'M', u'gpa'),
- (0x33AD, 'M', u'rad'),
- (0x33AE, 'M', u'rad∕s'),
- (0x33AF, 'M', u'rad∕s2'),
- (0x33B0, 'M', u'ps'),
- (0x33B1, 'M', u'ns'),
- (0x33B2, 'M', u'μs'),
- (0x33B3, 'M', u'ms'),
- (0x33B4, 'M', u'pv'),
- (0x33B5, 'M', u'nv'),
- (0x33B6, 'M', u'μv'),
- (0x33B7, 'M', u'mv'),
- (0x33B8, 'M', u'kv'),
- (0x33B9, 'M', u'mv'),
- (0x33BA, 'M', u'pw'),
- (0x33BB, 'M', u'nw'),
- (0x33BC, 'M', u'μw'),
- (0x33BD, 'M', u'mw'),
- (0x33BE, 'M', u'kw'),
- (0x33BF, 'M', u'mw'),
- (0x33C0, 'M', u'kω'),
- (0x33C1, 'M', u'mω'),
- (0x33C2, 'X'),
- (0x33C3, 'M', u'bq'),
- (0x33C4, 'M', u'cc'),
- (0x33C5, 'M', u'cd'),
- (0x33C6, 'M', u'c∕kg'),
- (0x33C7, 'X'),
- (0x33C8, 'M', u'db'),
- (0x33C9, 'M', u'gy'),
- (0x33CA, 'M', u'ha'),
- (0x33CB, 'M', u'hp'),
- (0x33CC, 'M', u'in'),
- (0x33CD, 'M', u'kk'),
- (0x33CE, 'M', u'km'),
- (0x33CF, 'M', u'kt'),
- (0x33D0, 'M', u'lm'),
- (0x33D1, 'M', u'ln'),
- (0x33D2, 'M', u'log'),
- (0x33D3, 'M', u'lx'),
- (0x33D4, 'M', u'mb'),
- (0x33D5, 'M', u'mil'),
- (0x33D6, 'M', u'mol'),
- (0x33D7, 'M', u'ph'),
- (0x33D8, 'X'),
- (0x33D9, 'M', u'ppm'),
- (0x33DA, 'M', u'pr'),
- (0x33DB, 'M', u'sr'),
- (0x33DC, 'M', u'sv'),
- (0x33DD, 'M', u'wb'),
- (0x33DE, 'M', u'v∕m'),
- (0x33DF, 'M', u'a∕m'),
- (0x33E0, 'M', u'1æ—¥'),
- (0x33E1, 'M', u'2æ—¥'),
- (0x33E2, 'M', u'3æ—¥'),
- (0x33E3, 'M', u'4æ—¥'),
- (0x33E4, 'M', u'5æ—¥'),
- (0x33E5, 'M', u'6æ—¥'),
- (0x33E6, 'M', u'7æ—¥'),
- (0x33E7, 'M', u'8æ—¥'),
- (0x33E8, 'M', u'9æ—¥'),
- (0x33E9, 'M', u'10æ—¥'),
- (0x33EA, 'M', u'11æ—¥'),
- (0x33EB, 'M', u'12æ—¥'),
- (0x33EC, 'M', u'13æ—¥'),
- (0x33ED, 'M', u'14æ—¥'),
- (0x33EE, 'M', u'15æ—¥'),
- (0x33EF, 'M', u'16æ—¥'),
- (0x33F0, 'M', u'17æ—¥'),
- (0x33F1, 'M', u'18æ—¥'),
- (0x33F2, 'M', u'19æ—¥'),
- (0x33F3, 'M', u'20æ—¥'),
- (0x33F4, 'M', u'21æ—¥'),
- (0x33F5, 'M', u'22æ—¥'),
- (0x33F6, 'M', u'23æ—¥'),
- (0x33F7, 'M', u'24æ—¥'),
- (0x33F8, 'M', u'25æ—¥'),
- (0x33F9, 'M', u'26æ—¥'),
- (0x33FA, 'M', u'27æ—¥'),
- (0x33FB, 'M', u'28æ—¥'),
- (0x33FC, 'M', u'29æ—¥'),
- (0x33FD, 'M', u'30æ—¥'),
- (0x33FE, 'M', u'31æ—¥'),
- (0x33FF, 'M', u'gal'),
- ]
-
-def _seg_35():
- return [
- (0x3400, 'V'),
- (0x4DB6, 'X'),
- (0x4DC0, 'V'),
- (0x9FCD, 'X'),
- (0xA000, 'V'),
- (0xA48D, 'X'),
- (0xA490, 'V'),
- (0xA4C7, 'X'),
- (0xA4D0, 'V'),
- (0xA62C, 'X'),
- (0xA640, 'M', u'ê™'),
- (0xA641, 'V'),
- (0xA642, 'M', u'ꙃ'),
- (0xA643, 'V'),
- (0xA644, 'M', u'ê™…'),
- (0xA645, 'V'),
- (0xA646, 'M', u'ꙇ'),
- (0xA647, 'V'),
- (0xA648, 'M', u'ꙉ'),
- (0xA649, 'V'),
- (0xA64A, 'M', u'ꙋ'),
- (0xA64B, 'V'),
- (0xA64C, 'M', u'ê™'),
- (0xA64D, 'V'),
- (0xA64E, 'M', u'ê™'),
- (0xA64F, 'V'),
- (0xA650, 'M', u'ꙑ'),
- (0xA651, 'V'),
- (0xA652, 'M', u'ꙓ'),
- (0xA653, 'V'),
- (0xA654, 'M', u'ꙕ'),
- (0xA655, 'V'),
- (0xA656, 'M', u'ê™—'),
- (0xA657, 'V'),
- (0xA658, 'M', u'ê™™'),
- (0xA659, 'V'),
- (0xA65A, 'M', u'ê™›'),
- (0xA65B, 'V'),
- (0xA65C, 'M', u'ê™'),
- (0xA65D, 'V'),
- (0xA65E, 'M', u'ꙟ'),
- (0xA65F, 'V'),
- (0xA660, 'M', u'ꙡ'),
- (0xA661, 'V'),
- (0xA662, 'M', u'ꙣ'),
- (0xA663, 'V'),
- (0xA664, 'M', u'ꙥ'),
- (0xA665, 'V'),
- (0xA666, 'M', u'ꙧ'),
- (0xA667, 'V'),
- (0xA668, 'M', u'ꙩ'),
- (0xA669, 'V'),
- (0xA66A, 'M', u'ꙫ'),
- (0xA66B, 'V'),
- (0xA66C, 'M', u'ê™­'),
- (0xA66D, 'V'),
- (0xA680, 'M', u'êš'),
- (0xA681, 'V'),
- (0xA682, 'M', u'ꚃ'),
- (0xA683, 'V'),
- (0xA684, 'M', u'êš…'),
- (0xA685, 'V'),
- (0xA686, 'M', u'ꚇ'),
- (0xA687, 'V'),
- (0xA688, 'M', u'ꚉ'),
- (0xA689, 'V'),
- (0xA68A, 'M', u'êš‹'),
- (0xA68B, 'V'),
- (0xA68C, 'M', u'êš'),
- (0xA68D, 'V'),
- (0xA68E, 'M', u'êš'),
- (0xA68F, 'V'),
- (0xA690, 'M', u'êš‘'),
- (0xA691, 'V'),
- (0xA692, 'M', u'êš“'),
- (0xA693, 'V'),
- (0xA694, 'M', u'êš•'),
- (0xA695, 'V'),
- (0xA696, 'M', u'êš—'),
- (0xA697, 'V'),
- (0xA698, 'X'),
- (0xA69F, 'V'),
- (0xA6F8, 'X'),
- (0xA700, 'V'),
- (0xA722, 'M', u'ꜣ'),
- (0xA723, 'V'),
- (0xA724, 'M', u'ꜥ'),
- (0xA725, 'V'),
- (0xA726, 'M', u'ꜧ'),
- (0xA727, 'V'),
- (0xA728, 'M', u'ꜩ'),
- (0xA729, 'V'),
- (0xA72A, 'M', u'ꜫ'),
- (0xA72B, 'V'),
- (0xA72C, 'M', u'ꜭ'),
- (0xA72D, 'V'),
- (0xA72E, 'M', u'ꜯ'),
- (0xA72F, 'V'),
- (0xA732, 'M', u'ꜳ'),
- (0xA733, 'V'),
- ]
-
-def _seg_36():
- return [
- (0xA734, 'M', u'ꜵ'),
- (0xA735, 'V'),
- (0xA736, 'M', u'ꜷ'),
- (0xA737, 'V'),
- (0xA738, 'M', u'ꜹ'),
- (0xA739, 'V'),
- (0xA73A, 'M', u'ꜻ'),
- (0xA73B, 'V'),
- (0xA73C, 'M', u'ꜽ'),
- (0xA73D, 'V'),
- (0xA73E, 'M', u'ꜿ'),
- (0xA73F, 'V'),
- (0xA740, 'M', u'ê'),
- (0xA741, 'V'),
- (0xA742, 'M', u'êƒ'),
- (0xA743, 'V'),
- (0xA744, 'M', u'ê…'),
- (0xA745, 'V'),
- (0xA746, 'M', u'ê‡'),
- (0xA747, 'V'),
- (0xA748, 'M', u'ê‰'),
- (0xA749, 'V'),
- (0xA74A, 'M', u'ê‹'),
- (0xA74B, 'V'),
- (0xA74C, 'M', u'ê'),
- (0xA74D, 'V'),
- (0xA74E, 'M', u'ê'),
- (0xA74F, 'V'),
- (0xA750, 'M', u'ê‘'),
- (0xA751, 'V'),
- (0xA752, 'M', u'ê“'),
- (0xA753, 'V'),
- (0xA754, 'M', u'ê•'),
- (0xA755, 'V'),
- (0xA756, 'M', u'ê—'),
- (0xA757, 'V'),
- (0xA758, 'M', u'ê™'),
- (0xA759, 'V'),
- (0xA75A, 'M', u'ê›'),
- (0xA75B, 'V'),
- (0xA75C, 'M', u'ê'),
- (0xA75D, 'V'),
- (0xA75E, 'M', u'êŸ'),
- (0xA75F, 'V'),
- (0xA760, 'M', u'ê¡'),
- (0xA761, 'V'),
- (0xA762, 'M', u'ê£'),
- (0xA763, 'V'),
- (0xA764, 'M', u'ê¥'),
- (0xA765, 'V'),
- (0xA766, 'M', u'ê§'),
- (0xA767, 'V'),
- (0xA768, 'M', u'ê©'),
- (0xA769, 'V'),
- (0xA76A, 'M', u'ê«'),
- (0xA76B, 'V'),
- (0xA76C, 'M', u'ê­'),
- (0xA76D, 'V'),
- (0xA76E, 'M', u'ê¯'),
- (0xA76F, 'V'),
- (0xA770, 'M', u'ê¯'),
- (0xA771, 'V'),
- (0xA779, 'M', u'êº'),
- (0xA77A, 'V'),
- (0xA77B, 'M', u'ê¼'),
- (0xA77C, 'V'),
- (0xA77D, 'M', u'áµ¹'),
- (0xA77E, 'M', u'ê¿'),
- (0xA77F, 'V'),
- (0xA780, 'M', u'êž'),
- (0xA781, 'V'),
- (0xA782, 'M', u'ꞃ'),
- (0xA783, 'V'),
- (0xA784, 'M', u'êž…'),
- (0xA785, 'V'),
- (0xA786, 'M', u'ꞇ'),
- (0xA787, 'V'),
- (0xA78B, 'M', u'ꞌ'),
- (0xA78C, 'V'),
- (0xA78D, 'M', u'É¥'),
- (0xA78E, 'V'),
- (0xA78F, 'X'),
- (0xA790, 'M', u'êž‘'),
- (0xA791, 'V'),
- (0xA792, 'M', u'êž“'),
- (0xA793, 'V'),
- (0xA794, 'X'),
- (0xA7A0, 'M', u'êž¡'),
- (0xA7A1, 'V'),
- (0xA7A2, 'M', u'ꞣ'),
- (0xA7A3, 'V'),
- (0xA7A4, 'M', u'ꞥ'),
- (0xA7A5, 'V'),
- (0xA7A6, 'M', u'ꞧ'),
- (0xA7A7, 'V'),
- (0xA7A8, 'M', u'êž©'),
- (0xA7A9, 'V'),
- (0xA7AA, 'M', u'ɦ'),
- (0xA7AB, 'X'),
- (0xA7F8, 'M', u'ħ'),
- ]
-
-def _seg_37():
- return [
- (0xA7F9, 'M', u'Å“'),
- (0xA7FA, 'V'),
- (0xA82C, 'X'),
- (0xA830, 'V'),
- (0xA83A, 'X'),
- (0xA840, 'V'),
- (0xA878, 'X'),
- (0xA880, 'V'),
- (0xA8C5, 'X'),
- (0xA8CE, 'V'),
- (0xA8DA, 'X'),
- (0xA8E0, 'V'),
- (0xA8FC, 'X'),
- (0xA900, 'V'),
- (0xA954, 'X'),
- (0xA95F, 'V'),
- (0xA97D, 'X'),
- (0xA980, 'V'),
- (0xA9CE, 'X'),
- (0xA9CF, 'V'),
- (0xA9DA, 'X'),
- (0xA9DE, 'V'),
- (0xA9E0, 'X'),
- (0xAA00, 'V'),
- (0xAA37, 'X'),
- (0xAA40, 'V'),
- (0xAA4E, 'X'),
- (0xAA50, 'V'),
- (0xAA5A, 'X'),
- (0xAA5C, 'V'),
- (0xAA7C, 'X'),
- (0xAA80, 'V'),
- (0xAAC3, 'X'),
- (0xAADB, 'V'),
- (0xAAF7, 'X'),
- (0xAB01, 'V'),
- (0xAB07, 'X'),
- (0xAB09, 'V'),
- (0xAB0F, 'X'),
- (0xAB11, 'V'),
- (0xAB17, 'X'),
- (0xAB20, 'V'),
- (0xAB27, 'X'),
- (0xAB28, 'V'),
- (0xAB2F, 'X'),
- (0xABC0, 'V'),
- (0xABEE, 'X'),
- (0xABF0, 'V'),
- (0xABFA, 'X'),
- (0xAC00, 'V'),
- (0xD7A4, 'X'),
- (0xD7B0, 'V'),
- (0xD7C7, 'X'),
- (0xD7CB, 'V'),
- (0xD7FC, 'X'),
- (0xF900, 'M', u'豈'),
- (0xF901, 'M', u'æ›´'),
- (0xF902, 'M', u'車'),
- (0xF903, 'M', u'賈'),
- (0xF904, 'M', u'滑'),
- (0xF905, 'M', u'串'),
- (0xF906, 'M', u'å¥'),
- (0xF907, 'M', u'龜'),
- (0xF909, 'M', u'契'),
- (0xF90A, 'M', u'金'),
- (0xF90B, 'M', u'å–‡'),
- (0xF90C, 'M', u'奈'),
- (0xF90D, 'M', u'懶'),
- (0xF90E, 'M', u'癩'),
- (0xF90F, 'M', u'ç¾…'),
- (0xF910, 'M', u'蘿'),
- (0xF911, 'M', u'螺'),
- (0xF912, 'M', u'裸'),
- (0xF913, 'M', u'é‚'),
- (0xF914, 'M', u'樂'),
- (0xF915, 'M', u'æ´›'),
- (0xF916, 'M', u'烙'),
- (0xF917, 'M', u'çž'),
- (0xF918, 'M', u'è½'),
- (0xF919, 'M', u'é…ª'),
- (0xF91A, 'M', u'駱'),
- (0xF91B, 'M', u'亂'),
- (0xF91C, 'M', u'åµ'),
- (0xF91D, 'M', u'欄'),
- (0xF91E, 'M', u'爛'),
- (0xF91F, 'M', u'蘭'),
- (0xF920, 'M', u'鸞'),
- (0xF921, 'M', u'åµ'),
- (0xF922, 'M', u'æ¿«'),
- (0xF923, 'M', u'è—'),
- (0xF924, 'M', u'襤'),
- (0xF925, 'M', u'拉'),
- (0xF926, 'M', u'臘'),
- (0xF927, 'M', u'è Ÿ'),
- (0xF928, 'M', u'廊'),
- (0xF929, 'M', u'朗'),
- (0xF92A, 'M', u'浪'),
- (0xF92B, 'M', u'狼'),
- (0xF92C, 'M', u'郎'),
- (0xF92D, 'M', u'來'),
- ]
-
-def _seg_38():
- return [
- (0xF92E, 'M', u'冷'),
- (0xF92F, 'M', u'å‹ž'),
- (0xF930, 'M', u'æ“„'),
- (0xF931, 'M', u'æ«“'),
- (0xF932, 'M', u'çˆ'),
- (0xF933, 'M', u'盧'),
- (0xF934, 'M', u'è€'),
- (0xF935, 'M', u'蘆'),
- (0xF936, 'M', u'虜'),
- (0xF937, 'M', u'è·¯'),
- (0xF938, 'M', u'露'),
- (0xF939, 'M', u'é­¯'),
- (0xF93A, 'M', u'é·º'),
- (0xF93B, 'M', u'碌'),
- (0xF93C, 'M', u'祿'),
- (0xF93D, 'M', u'綠'),
- (0xF93E, 'M', u'è‰'),
- (0xF93F, 'M', u'錄'),
- (0xF940, 'M', u'鹿'),
- (0xF941, 'M', u'è«–'),
- (0xF942, 'M', u'壟'),
- (0xF943, 'M', u'弄'),
- (0xF944, 'M', u'ç± '),
- (0xF945, 'M', u'è¾'),
- (0xF946, 'M', u'牢'),
- (0xF947, 'M', u'磊'),
- (0xF948, 'M', u'賂'),
- (0xF949, 'M', u'é›·'),
- (0xF94A, 'M', u'壘'),
- (0xF94B, 'M', u'å±¢'),
- (0xF94C, 'M', u'樓'),
- (0xF94D, 'M', u'æ·š'),
- (0xF94E, 'M', u'æ¼'),
- (0xF94F, 'M', u'ç´¯'),
- (0xF950, 'M', u'縷'),
- (0xF951, 'M', u'陋'),
- (0xF952, 'M', u'å‹’'),
- (0xF953, 'M', u'è‚‹'),
- (0xF954, 'M', u'凜'),
- (0xF955, 'M', u'凌'),
- (0xF956, 'M', u'稜'),
- (0xF957, 'M', u'綾'),
- (0xF958, 'M', u'è±'),
- (0xF959, 'M', u'陵'),
- (0xF95A, 'M', u'讀'),
- (0xF95B, 'M', u'æ‹'),
- (0xF95C, 'M', u'樂'),
- (0xF95D, 'M', u'諾'),
- (0xF95E, 'M', u'丹'),
- (0xF95F, 'M', u'寧'),
- (0xF960, 'M', u'怒'),
- (0xF961, 'M', u'率'),
- (0xF962, 'M', u'ç•°'),
- (0xF963, 'M', u'北'),
- (0xF964, 'M', u'磻'),
- (0xF965, 'M', u'便'),
- (0xF966, 'M', u'復'),
- (0xF967, 'M', u'ä¸'),
- (0xF968, 'M', u'泌'),
- (0xF969, 'M', u'數'),
- (0xF96A, 'M', u'ç´¢'),
- (0xF96B, 'M', u'åƒ'),
- (0xF96C, 'M', u'å¡ž'),
- (0xF96D, 'M', u'çœ'),
- (0xF96E, 'M', u'葉'),
- (0xF96F, 'M', u'說'),
- (0xF970, 'M', u'殺'),
- (0xF971, 'M', u'è¾°'),
- (0xF972, 'M', u'沈'),
- (0xF973, 'M', u'拾'),
- (0xF974, 'M', u'è‹¥'),
- (0xF975, 'M', u'掠'),
- (0xF976, 'M', u'ç•¥'),
- (0xF977, 'M', u'亮'),
- (0xF978, 'M', u'å…©'),
- (0xF979, 'M', u'凉'),
- (0xF97A, 'M', u'æ¢'),
- (0xF97B, 'M', u'糧'),
- (0xF97C, 'M', u'良'),
- (0xF97D, 'M', u'è«’'),
- (0xF97E, 'M', u'é‡'),
- (0xF97F, 'M', u'勵'),
- (0xF980, 'M', u'å‘‚'),
- (0xF981, 'M', u'女'),
- (0xF982, 'M', u'廬'),
- (0xF983, 'M', u'æ—…'),
- (0xF984, 'M', u'濾'),
- (0xF985, 'M', u'礪'),
- (0xF986, 'M', u'é–­'),
- (0xF987, 'M', u'驪'),
- (0xF988, 'M', u'麗'),
- (0xF989, 'M', u'黎'),
- (0xF98A, 'M', u'力'),
- (0xF98B, 'M', u'曆'),
- (0xF98C, 'M', u'æ­·'),
- (0xF98D, 'M', u'è½¢'),
- (0xF98E, 'M', u'å¹´'),
- (0xF98F, 'M', u'æ†'),
- (0xF990, 'M', u'戀'),
- (0xF991, 'M', u'æ’š'),
- ]
-
-def _seg_39():
- return [
- (0xF992, 'M', u'æ¼£'),
- (0xF993, 'M', u'ç…‰'),
- (0xF994, 'M', u'ç’‰'),
- (0xF995, 'M', u'秊'),
- (0xF996, 'M', u'ç·´'),
- (0xF997, 'M', u'è¯'),
- (0xF998, 'M', u'輦'),
- (0xF999, 'M', u'è“®'),
- (0xF99A, 'M', u'連'),
- (0xF99B, 'M', u'éŠ'),
- (0xF99C, 'M', u'列'),
- (0xF99D, 'M', u'劣'),
- (0xF99E, 'M', u'å’½'),
- (0xF99F, 'M', u'烈'),
- (0xF9A0, 'M', u'裂'),
- (0xF9A1, 'M', u'說'),
- (0xF9A2, 'M', u'廉'),
- (0xF9A3, 'M', u'念'),
- (0xF9A4, 'M', u'æ»'),
- (0xF9A5, 'M', u'æ®®'),
- (0xF9A6, 'M', u'ç°¾'),
- (0xF9A7, 'M', u'çµ'),
- (0xF9A8, 'M', u'令'),
- (0xF9A9, 'M', u'囹'),
- (0xF9AA, 'M', u'寧'),
- (0xF9AB, 'M', u'嶺'),
- (0xF9AC, 'M', u'怜'),
- (0xF9AD, 'M', u'玲'),
- (0xF9AE, 'M', u'ç‘©'),
- (0xF9AF, 'M', u'羚'),
- (0xF9B0, 'M', u'è†'),
- (0xF9B1, 'M', u'鈴'),
- (0xF9B2, 'M', u'零'),
- (0xF9B3, 'M', u'éˆ'),
- (0xF9B4, 'M', u'é ˜'),
- (0xF9B5, 'M', u'例'),
- (0xF9B6, 'M', u'禮'),
- (0xF9B7, 'M', u'醴'),
- (0xF9B8, 'M', u'隸'),
- (0xF9B9, 'M', u'惡'),
- (0xF9BA, 'M', u'了'),
- (0xF9BB, 'M', u'僚'),
- (0xF9BC, 'M', u'寮'),
- (0xF9BD, 'M', u'å°¿'),
- (0xF9BE, 'M', u'æ–™'),
- (0xF9BF, 'M', u'樂'),
- (0xF9C0, 'M', u'燎'),
- (0xF9C1, 'M', u'療'),
- (0xF9C2, 'M', u'蓼'),
- (0xF9C3, 'M', u'é¼'),
- (0xF9C4, 'M', u'é¾'),
- (0xF9C5, 'M', u'暈'),
- (0xF9C6, 'M', u'阮'),
- (0xF9C7, 'M', u'劉'),
- (0xF9C8, 'M', u'æ»'),
- (0xF9C9, 'M', u'柳'),
- (0xF9CA, 'M', u'æµ'),
- (0xF9CB, 'M', u'溜'),
- (0xF9CC, 'M', u'ç‰'),
- (0xF9CD, 'M', u'ç•™'),
- (0xF9CE, 'M', u'ç¡«'),
- (0xF9CF, 'M', u'ç´'),
- (0xF9D0, 'M', u'é¡ž'),
- (0xF9D1, 'M', u'å…­'),
- (0xF9D2, 'M', u'戮'),
- (0xF9D3, 'M', u'陸'),
- (0xF9D4, 'M', u'倫'),
- (0xF9D5, 'M', u'å´™'),
- (0xF9D6, 'M', u'æ·ª'),
- (0xF9D7, 'M', u'輪'),
- (0xF9D8, 'M', u'律'),
- (0xF9D9, 'M', u'æ…„'),
- (0xF9DA, 'M', u'æ —'),
- (0xF9DB, 'M', u'率'),
- (0xF9DC, 'M', u'隆'),
- (0xF9DD, 'M', u'利'),
- (0xF9DE, 'M', u'å'),
- (0xF9DF, 'M', u'å±¥'),
- (0xF9E0, 'M', u'易'),
- (0xF9E1, 'M', u'æŽ'),
- (0xF9E2, 'M', u'梨'),
- (0xF9E3, 'M', u'æ³¥'),
- (0xF9E4, 'M', u'ç†'),
- (0xF9E5, 'M', u'ç—¢'),
- (0xF9E6, 'M', u'ç½¹'),
- (0xF9E7, 'M', u'è£'),
- (0xF9E8, 'M', u'裡'),
- (0xF9E9, 'M', u'里'),
- (0xF9EA, 'M', u'離'),
- (0xF9EB, 'M', u'匿'),
- (0xF9EC, 'M', u'溺'),
- (0xF9ED, 'M', u'å'),
- (0xF9EE, 'M', u'ç‡'),
- (0xF9EF, 'M', u'ç’˜'),
- (0xF9F0, 'M', u'è—º'),
- (0xF9F1, 'M', u'隣'),
- (0xF9F2, 'M', u'é±—'),
- (0xF9F3, 'M', u'麟'),
- (0xF9F4, 'M', u'æž—'),
- (0xF9F5, 'M', u'æ·‹'),
- ]
-
-def _seg_40():
- return [
- (0xF9F6, 'M', u'臨'),
- (0xF9F7, 'M', u'ç«‹'),
- (0xF9F8, 'M', u'笠'),
- (0xF9F9, 'M', u'ç²’'),
- (0xF9FA, 'M', u'ç‹€'),
- (0xF9FB, 'M', u'ç‚™'),
- (0xF9FC, 'M', u'è­˜'),
- (0xF9FD, 'M', u'什'),
- (0xF9FE, 'M', u'茶'),
- (0xF9FF, 'M', u'刺'),
- (0xFA00, 'M', u'切'),
- (0xFA01, 'M', u'度'),
- (0xFA02, 'M', u'æ‹“'),
- (0xFA03, 'M', u'ç³–'),
- (0xFA04, 'M', u'å®…'),
- (0xFA05, 'M', u'æ´ž'),
- (0xFA06, 'M', u'æš´'),
- (0xFA07, 'M', u'è¼»'),
- (0xFA08, 'M', u'行'),
- (0xFA09, 'M', u'é™'),
- (0xFA0A, 'M', u'見'),
- (0xFA0B, 'M', u'廓'),
- (0xFA0C, 'M', u'å…€'),
- (0xFA0D, 'M', u'å—€'),
- (0xFA0E, 'V'),
- (0xFA10, 'M', u'å¡š'),
- (0xFA11, 'V'),
- (0xFA12, 'M', u'æ™´'),
- (0xFA13, 'V'),
- (0xFA15, 'M', u'凞'),
- (0xFA16, 'M', u'猪'),
- (0xFA17, 'M', u'益'),
- (0xFA18, 'M', u'礼'),
- (0xFA19, 'M', u'神'),
- (0xFA1A, 'M', u'祥'),
- (0xFA1B, 'M', u'ç¦'),
- (0xFA1C, 'M', u'é–'),
- (0xFA1D, 'M', u'ç²¾'),
- (0xFA1E, 'M', u'ç¾½'),
- (0xFA1F, 'V'),
- (0xFA20, 'M', u'蘒'),
- (0xFA21, 'V'),
- (0xFA22, 'M', u'諸'),
- (0xFA23, 'V'),
- (0xFA25, 'M', u'逸'),
- (0xFA26, 'M', u'都'),
- (0xFA27, 'V'),
- (0xFA2A, 'M', u'飯'),
- (0xFA2B, 'M', u'飼'),
- (0xFA2C, 'M', u'館'),
- (0xFA2D, 'M', u'鶴'),
- (0xFA2E, 'M', u'郞'),
- (0xFA2F, 'M', u'éš·'),
- (0xFA30, 'M', u'ä¾®'),
- (0xFA31, 'M', u'僧'),
- (0xFA32, 'M', u'å…'),
- (0xFA33, 'M', u'勉'),
- (0xFA34, 'M', u'勤'),
- (0xFA35, 'M', u'å‘'),
- (0xFA36, 'M', u'å–'),
- (0xFA37, 'M', u'嘆'),
- (0xFA38, 'M', u'器'),
- (0xFA39, 'M', u'å¡€'),
- (0xFA3A, 'M', u'墨'),
- (0xFA3B, 'M', u'層'),
- (0xFA3C, 'M', u'å±®'),
- (0xFA3D, 'M', u'æ‚”'),
- (0xFA3E, 'M', u'æ…¨'),
- (0xFA3F, 'M', u'憎'),
- (0xFA40, 'M', u'懲'),
- (0xFA41, 'M', u'æ•'),
- (0xFA42, 'M', u'æ—¢'),
- (0xFA43, 'M', u'æš‘'),
- (0xFA44, 'M', u'梅'),
- (0xFA45, 'M', u'æµ·'),
- (0xFA46, 'M', u'渚'),
- (0xFA47, 'M', u'æ¼¢'),
- (0xFA48, 'M', u'ç…®'),
- (0xFA49, 'M', u'爫'),
- (0xFA4A, 'M', u'ç¢'),
- (0xFA4B, 'M', u'碑'),
- (0xFA4C, 'M', u'社'),
- (0xFA4D, 'M', u'祉'),
- (0xFA4E, 'M', u'祈'),
- (0xFA4F, 'M', u'ç¥'),
- (0xFA50, 'M', u'祖'),
- (0xFA51, 'M', u'ç¥'),
- (0xFA52, 'M', u'ç¦'),
- (0xFA53, 'M', u'禎'),
- (0xFA54, 'M', u'ç©€'),
- (0xFA55, 'M', u'çª'),
- (0xFA56, 'M', u'節'),
- (0xFA57, 'M', u'ç·´'),
- (0xFA58, 'M', u'縉'),
- (0xFA59, 'M', u'ç¹'),
- (0xFA5A, 'M', u'ç½²'),
- (0xFA5B, 'M', u'者'),
- (0xFA5C, 'M', u'臭'),
- (0xFA5D, 'M', u'艹'),
- (0xFA5F, 'M', u'è‘—'),
- ]
-
-def _seg_41():
- return [
- (0xFA60, 'M', u'è¤'),
- (0xFA61, 'M', u'視'),
- (0xFA62, 'M', u'è¬'),
- (0xFA63, 'M', u'謹'),
- (0xFA64, 'M', u'賓'),
- (0xFA65, 'M', u'è´ˆ'),
- (0xFA66, 'M', u'辶'),
- (0xFA67, 'M', u'逸'),
- (0xFA68, 'M', u'難'),
- (0xFA69, 'M', u'響'),
- (0xFA6A, 'M', u'é »'),
- (0xFA6B, 'M', u'æµ'),
- (0xFA6C, 'M', u'𤋮'),
- (0xFA6D, 'M', u'舘'),
- (0xFA6E, 'X'),
- (0xFA70, 'M', u'並'),
- (0xFA71, 'M', u'况'),
- (0xFA72, 'M', u'å…¨'),
- (0xFA73, 'M', u'ä¾€'),
- (0xFA74, 'M', u'å……'),
- (0xFA75, 'M', u'冀'),
- (0xFA76, 'M', u'勇'),
- (0xFA77, 'M', u'勺'),
- (0xFA78, 'M', u'å–'),
- (0xFA79, 'M', u'å••'),
- (0xFA7A, 'M', u'å–™'),
- (0xFA7B, 'M', u'å—¢'),
- (0xFA7C, 'M', u'å¡š'),
- (0xFA7D, 'M', u'墳'),
- (0xFA7E, 'M', u'奄'),
- (0xFA7F, 'M', u'奔'),
- (0xFA80, 'M', u'å©¢'),
- (0xFA81, 'M', u'嬨'),
- (0xFA82, 'M', u'å»’'),
- (0xFA83, 'M', u'å»™'),
- (0xFA84, 'M', u'彩'),
- (0xFA85, 'M', u'å¾­'),
- (0xFA86, 'M', u'惘'),
- (0xFA87, 'M', u'æ…Ž'),
- (0xFA88, 'M', u'愈'),
- (0xFA89, 'M', u'憎'),
- (0xFA8A, 'M', u'æ… '),
- (0xFA8B, 'M', u'懲'),
- (0xFA8C, 'M', u'戴'),
- (0xFA8D, 'M', u'æ„'),
- (0xFA8E, 'M', u'æœ'),
- (0xFA8F, 'M', u'æ‘’'),
- (0xFA90, 'M', u'æ•–'),
- (0xFA91, 'M', u'æ™´'),
- (0xFA92, 'M', u'朗'),
- (0xFA93, 'M', u'望'),
- (0xFA94, 'M', u'æ–'),
- (0xFA95, 'M', u'æ­¹'),
- (0xFA96, 'M', u'殺'),
- (0xFA97, 'M', u'æµ'),
- (0xFA98, 'M', u'æ»›'),
- (0xFA99, 'M', u'滋'),
- (0xFA9A, 'M', u'æ¼¢'),
- (0xFA9B, 'M', u'瀞'),
- (0xFA9C, 'M', u'ç…®'),
- (0xFA9D, 'M', u'瞧'),
- (0xFA9E, 'M', u'爵'),
- (0xFA9F, 'M', u'犯'),
- (0xFAA0, 'M', u'猪'),
- (0xFAA1, 'M', u'瑱'),
- (0xFAA2, 'M', u'甆'),
- (0xFAA3, 'M', u'ç”»'),
- (0xFAA4, 'M', u'ç˜'),
- (0xFAA5, 'M', u'瘟'),
- (0xFAA6, 'M', u'益'),
- (0xFAA7, 'M', u'ç››'),
- (0xFAA8, 'M', u'ç›´'),
- (0xFAA9, 'M', u'çŠ'),
- (0xFAAA, 'M', u'ç€'),
- (0xFAAB, 'M', u'磌'),
- (0xFAAC, 'M', u'窱'),
- (0xFAAD, 'M', u'節'),
- (0xFAAE, 'M', u'ç±»'),
- (0xFAAF, 'M', u'çµ›'),
- (0xFAB0, 'M', u'ç·´'),
- (0xFAB1, 'M', u'ç¼¾'),
- (0xFAB2, 'M', u'者'),
- (0xFAB3, 'M', u'è’'),
- (0xFAB4, 'M', u'è¯'),
- (0xFAB5, 'M', u'è¹'),
- (0xFAB6, 'M', u'è¥'),
- (0xFAB7, 'M', u'覆'),
- (0xFAB8, 'M', u'視'),
- (0xFAB9, 'M', u'調'),
- (0xFABA, 'M', u'諸'),
- (0xFABB, 'M', u'è«‹'),
- (0xFABC, 'M', u'è¬'),
- (0xFABD, 'M', u'諾'),
- (0xFABE, 'M', u'è«­'),
- (0xFABF, 'M', u'謹'),
- (0xFAC0, 'M', u'變'),
- (0xFAC1, 'M', u'è´ˆ'),
- (0xFAC2, 'M', u'輸'),
- (0xFAC3, 'M', u'é²'),
- (0xFAC4, 'M', u'醙'),
- ]
-
-def _seg_42():
- return [
- (0xFAC5, 'M', u'鉶'),
- (0xFAC6, 'M', u'陼'),
- (0xFAC7, 'M', u'難'),
- (0xFAC8, 'M', u'é–'),
- (0xFAC9, 'M', u'韛'),
- (0xFACA, 'M', u'響'),
- (0xFACB, 'M', u'é ‹'),
- (0xFACC, 'M', u'é »'),
- (0xFACD, 'M', u'鬒'),
- (0xFACE, 'M', u'龜'),
- (0xFACF, 'M', u'𢡊'),
- (0xFAD0, 'M', u'𢡄'),
- (0xFAD1, 'M', u'ð£•'),
- (0xFAD2, 'M', u'ã®'),
- (0xFAD3, 'M', u'䀘'),
- (0xFAD4, 'M', u'䀹'),
- (0xFAD5, 'M', u'𥉉'),
- (0xFAD6, 'M', u'ð¥³'),
- (0xFAD7, 'M', u'𧻓'),
- (0xFAD8, 'M', u'齃'),
- (0xFAD9, 'M', u'龎'),
- (0xFADA, 'X'),
- (0xFB00, 'M', u'ff'),
- (0xFB01, 'M', u'fi'),
- (0xFB02, 'M', u'fl'),
- (0xFB03, 'M', u'ffi'),
- (0xFB04, 'M', u'ffl'),
- (0xFB05, 'M', u'st'),
- (0xFB07, 'X'),
- (0xFB13, 'M', u'Õ´Õ¶'),
- (0xFB14, 'M', u'Õ´Õ¥'),
- (0xFB15, 'M', u'Õ´Õ«'),
- (0xFB16, 'M', u'Õ¾Õ¶'),
- (0xFB17, 'M', u'Õ´Õ­'),
- (0xFB18, 'X'),
- (0xFB1D, 'M', u'×™Ö´'),
- (0xFB1E, 'V'),
- (0xFB1F, 'M', u'ײַ'),
- (0xFB20, 'M', u'×¢'),
- (0xFB21, 'M', u'×'),
- (0xFB22, 'M', u'ד'),
- (0xFB23, 'M', u'×”'),
- (0xFB24, 'M', u'×›'),
- (0xFB25, 'M', u'ל'),
- (0xFB26, 'M', u'×'),
- (0xFB27, 'M', u'ר'),
- (0xFB28, 'M', u'ת'),
- (0xFB29, '3', u'+'),
- (0xFB2A, 'M', u'ש×'),
- (0xFB2B, 'M', u'שׂ'),
- (0xFB2C, 'M', u'שּ×'),
- (0xFB2D, 'M', u'שּׂ'),
- (0xFB2E, 'M', u'×Ö·'),
- (0xFB2F, 'M', u'×Ö¸'),
- (0xFB30, 'M', u'×Ö¼'),
- (0xFB31, 'M', u'בּ'),
- (0xFB32, 'M', u'×’Ö¼'),
- (0xFB33, 'M', u'דּ'),
- (0xFB34, 'M', u'×”Ö¼'),
- (0xFB35, 'M', u'וּ'),
- (0xFB36, 'M', u'×–Ö¼'),
- (0xFB37, 'X'),
- (0xFB38, 'M', u'טּ'),
- (0xFB39, 'M', u'×™Ö¼'),
- (0xFB3A, 'M', u'ךּ'),
- (0xFB3B, 'M', u'×›Ö¼'),
- (0xFB3C, 'M', u'לּ'),
- (0xFB3D, 'X'),
- (0xFB3E, 'M', u'מּ'),
- (0xFB3F, 'X'),
- (0xFB40, 'M', u'× Ö¼'),
- (0xFB41, 'M', u'סּ'),
- (0xFB42, 'X'),
- (0xFB43, 'M', u'×£Ö¼'),
- (0xFB44, 'M', u'פּ'),
- (0xFB45, 'X'),
- (0xFB46, 'M', u'צּ'),
- (0xFB47, 'M', u'קּ'),
- (0xFB48, 'M', u'רּ'),
- (0xFB49, 'M', u'שּ'),
- (0xFB4A, 'M', u'תּ'),
- (0xFB4B, 'M', u'וֹ'),
- (0xFB4C, 'M', u'בֿ'),
- (0xFB4D, 'M', u'×›Ö¿'),
- (0xFB4E, 'M', u'פֿ'),
- (0xFB4F, 'M', u'×ל'),
- (0xFB50, 'M', u'Ù±'),
- (0xFB52, 'M', u'Ù»'),
- (0xFB56, 'M', u'Ù¾'),
- (0xFB5A, 'M', u'Ú€'),
- (0xFB5E, 'M', u'Ùº'),
- (0xFB62, 'M', u'Ù¿'),
- (0xFB66, 'M', u'Ù¹'),
- (0xFB6A, 'M', u'Ú¤'),
- (0xFB6E, 'M', u'Ú¦'),
- (0xFB72, 'M', u'Ú„'),
- (0xFB76, 'M', u'Úƒ'),
- (0xFB7A, 'M', u'Ú†'),
- (0xFB7E, 'M', u'Ú‡'),
- (0xFB82, 'M', u'Ú'),
- ]
-
-def _seg_43():
- return [
- (0xFB84, 'M', u'ڌ'),
- (0xFB86, 'M', u'ÚŽ'),
- (0xFB88, 'M', u'Úˆ'),
- (0xFB8A, 'M', u'Ú˜'),
- (0xFB8C, 'M', u'Ú‘'),
- (0xFB8E, 'M', u'Ú©'),
- (0xFB92, 'M', u'Ú¯'),
- (0xFB96, 'M', u'Ú³'),
- (0xFB9A, 'M', u'Ú±'),
- (0xFB9E, 'M', u'Úº'),
- (0xFBA0, 'M', u'Ú»'),
- (0xFBA4, 'M', u'Û€'),
- (0xFBA6, 'M', u'Û'),
- (0xFBAA, 'M', u'Ú¾'),
- (0xFBAE, 'M', u'Û’'),
- (0xFBB0, 'M', u'Û“'),
- (0xFBB2, 'V'),
- (0xFBC2, 'X'),
- (0xFBD3, 'M', u'Ú­'),
- (0xFBD7, 'M', u'Û‡'),
- (0xFBD9, 'M', u'Û†'),
- (0xFBDB, 'M', u'Ûˆ'),
- (0xFBDD, 'M', u'Û‡Ù´'),
- (0xFBDE, 'M', u'Û‹'),
- (0xFBE0, 'M', u'Û…'),
- (0xFBE2, 'M', u'Û‰'),
- (0xFBE4, 'M', u'Û'),
- (0xFBE8, 'M', u'Ù‰'),
- (0xFBEA, 'M', u'ئا'),
- (0xFBEC, 'M', u'ئە'),
- (0xFBEE, 'M', u'ئو'),
- (0xFBF0, 'M', u'ئۇ'),
- (0xFBF2, 'M', u'ئۆ'),
- (0xFBF4, 'M', u'ئۈ'),
- (0xFBF6, 'M', u'ئÛ'),
- (0xFBF9, 'M', u'ئى'),
- (0xFBFC, 'M', u'ی'),
- (0xFC00, 'M', u'ئج'),
- (0xFC01, 'M', u'ئح'),
- (0xFC02, 'M', u'ئم'),
- (0xFC03, 'M', u'ئى'),
- (0xFC04, 'M', u'ئي'),
- (0xFC05, 'M', u'بج'),
- (0xFC06, 'M', u'بح'),
- (0xFC07, 'M', u'بخ'),
- (0xFC08, 'M', u'بم'),
- (0xFC09, 'M', u'بى'),
- (0xFC0A, 'M', u'بي'),
- (0xFC0B, 'M', u'تج'),
- (0xFC0C, 'M', u'تح'),
- (0xFC0D, 'M', u'تخ'),
- (0xFC0E, 'M', u'تم'),
- (0xFC0F, 'M', u'تى'),
- (0xFC10, 'M', u'تي'),
- (0xFC11, 'M', u'ثج'),
- (0xFC12, 'M', u'ثم'),
- (0xFC13, 'M', u'ثى'),
- (0xFC14, 'M', u'ثي'),
- (0xFC15, 'M', u'جح'),
- (0xFC16, 'M', u'جم'),
- (0xFC17, 'M', u'حج'),
- (0xFC18, 'M', u'حم'),
- (0xFC19, 'M', u'خج'),
- (0xFC1A, 'M', u'خح'),
- (0xFC1B, 'M', u'خم'),
- (0xFC1C, 'M', u'سج'),
- (0xFC1D, 'M', u'سح'),
- (0xFC1E, 'M', u'سخ'),
- (0xFC1F, 'M', u'سم'),
- (0xFC20, 'M', u'صح'),
- (0xFC21, 'M', u'صم'),
- (0xFC22, 'M', u'ضج'),
- (0xFC23, 'M', u'ضح'),
- (0xFC24, 'M', u'ضخ'),
- (0xFC25, 'M', u'ضم'),
- (0xFC26, 'M', u'طح'),
- (0xFC27, 'M', u'طم'),
- (0xFC28, 'M', u'ظم'),
- (0xFC29, 'M', u'عج'),
- (0xFC2A, 'M', u'عم'),
- (0xFC2B, 'M', u'غج'),
- (0xFC2C, 'M', u'غم'),
- (0xFC2D, 'M', u'Ùج'),
- (0xFC2E, 'M', u'ÙØ­'),
- (0xFC2F, 'M', u'ÙØ®'),
- (0xFC30, 'M', u'ÙÙ…'),
- (0xFC31, 'M', u'ÙÙ‰'),
- (0xFC32, 'M', u'ÙÙŠ'),
- (0xFC33, 'M', u'قح'),
- (0xFC34, 'M', u'قم'),
- (0xFC35, 'M', u'قى'),
- (0xFC36, 'M', u'قي'),
- (0xFC37, 'M', u'كا'),
- (0xFC38, 'M', u'كج'),
- (0xFC39, 'M', u'كح'),
- (0xFC3A, 'M', u'كخ'),
- (0xFC3B, 'M', u'كل'),
- (0xFC3C, 'M', u'كم'),
- (0xFC3D, 'M', u'كى'),
- (0xFC3E, 'M', u'كي'),
- ]
-
-def _seg_44():
- return [
- (0xFC3F, 'M', u'لج'),
- (0xFC40, 'M', u'لح'),
- (0xFC41, 'M', u'لخ'),
- (0xFC42, 'M', u'لم'),
- (0xFC43, 'M', u'لى'),
- (0xFC44, 'M', u'لي'),
- (0xFC45, 'M', u'مج'),
- (0xFC46, 'M', u'مح'),
- (0xFC47, 'M', u'مخ'),
- (0xFC48, 'M', u'مم'),
- (0xFC49, 'M', u'مى'),
- (0xFC4A, 'M', u'مي'),
- (0xFC4B, 'M', u'نج'),
- (0xFC4C, 'M', u'نح'),
- (0xFC4D, 'M', u'نخ'),
- (0xFC4E, 'M', u'نم'),
- (0xFC4F, 'M', u'نى'),
- (0xFC50, 'M', u'ني'),
- (0xFC51, 'M', u'هج'),
- (0xFC52, 'M', u'هم'),
- (0xFC53, 'M', u'هى'),
- (0xFC54, 'M', u'هي'),
- (0xFC55, 'M', u'يج'),
- (0xFC56, 'M', u'يح'),
- (0xFC57, 'M', u'يخ'),
- (0xFC58, 'M', u'يم'),
- (0xFC59, 'M', u'يى'),
- (0xFC5A, 'M', u'يي'),
- (0xFC5B, 'M', u'ذٰ'),
- (0xFC5C, 'M', u'رٰ'),
- (0xFC5D, 'M', u'ىٰ'),
- (0xFC5E, '3', u' ٌّ'),
- (0xFC5F, '3', u' ÙÙ‘'),
- (0xFC60, '3', u' ÙŽÙ‘'),
- (0xFC61, '3', u' ÙÙ‘'),
- (0xFC62, '3', u' ÙÙ‘'),
- (0xFC63, '3', u' ّٰ'),
- (0xFC64, 'M', u'ئر'),
- (0xFC65, 'M', u'ئز'),
- (0xFC66, 'M', u'ئم'),
- (0xFC67, 'M', u'ئن'),
- (0xFC68, 'M', u'ئى'),
- (0xFC69, 'M', u'ئي'),
- (0xFC6A, 'M', u'بر'),
- (0xFC6B, 'M', u'بز'),
- (0xFC6C, 'M', u'بم'),
- (0xFC6D, 'M', u'بن'),
- (0xFC6E, 'M', u'بى'),
- (0xFC6F, 'M', u'بي'),
- (0xFC70, 'M', u'تر'),
- (0xFC71, 'M', u'تز'),
- (0xFC72, 'M', u'تم'),
- (0xFC73, 'M', u'تن'),
- (0xFC74, 'M', u'تى'),
- (0xFC75, 'M', u'تي'),
- (0xFC76, 'M', u'ثر'),
- (0xFC77, 'M', u'ثز'),
- (0xFC78, 'M', u'ثم'),
- (0xFC79, 'M', u'ثن'),
- (0xFC7A, 'M', u'ثى'),
- (0xFC7B, 'M', u'ثي'),
- (0xFC7C, 'M', u'ÙÙ‰'),
- (0xFC7D, 'M', u'ÙÙŠ'),
- (0xFC7E, 'M', u'قى'),
- (0xFC7F, 'M', u'قي'),
- (0xFC80, 'M', u'كا'),
- (0xFC81, 'M', u'كل'),
- (0xFC82, 'M', u'كم'),
- (0xFC83, 'M', u'كى'),
- (0xFC84, 'M', u'كي'),
- (0xFC85, 'M', u'لم'),
- (0xFC86, 'M', u'لى'),
- (0xFC87, 'M', u'لي'),
- (0xFC88, 'M', u'ما'),
- (0xFC89, 'M', u'مم'),
- (0xFC8A, 'M', u'نر'),
- (0xFC8B, 'M', u'نز'),
- (0xFC8C, 'M', u'نم'),
- (0xFC8D, 'M', u'نن'),
- (0xFC8E, 'M', u'نى'),
- (0xFC8F, 'M', u'ني'),
- (0xFC90, 'M', u'ىٰ'),
- (0xFC91, 'M', u'ير'),
- (0xFC92, 'M', u'يز'),
- (0xFC93, 'M', u'يم'),
- (0xFC94, 'M', u'ين'),
- (0xFC95, 'M', u'يى'),
- (0xFC96, 'M', u'يي'),
- (0xFC97, 'M', u'ئج'),
- (0xFC98, 'M', u'ئح'),
- (0xFC99, 'M', u'ئخ'),
- (0xFC9A, 'M', u'ئم'),
- (0xFC9B, 'M', u'ئه'),
- (0xFC9C, 'M', u'بج'),
- (0xFC9D, 'M', u'بح'),
- (0xFC9E, 'M', u'بخ'),
- (0xFC9F, 'M', u'بم'),
- (0xFCA0, 'M', u'به'),
- (0xFCA1, 'M', u'تج'),
- (0xFCA2, 'M', u'تح'),
- ]
-
-def _seg_45():
- return [
- (0xFCA3, 'M', u'تخ'),
- (0xFCA4, 'M', u'تم'),
- (0xFCA5, 'M', u'ته'),
- (0xFCA6, 'M', u'ثم'),
- (0xFCA7, 'M', u'جح'),
- (0xFCA8, 'M', u'جم'),
- (0xFCA9, 'M', u'حج'),
- (0xFCAA, 'M', u'حم'),
- (0xFCAB, 'M', u'خج'),
- (0xFCAC, 'M', u'خم'),
- (0xFCAD, 'M', u'سج'),
- (0xFCAE, 'M', u'سح'),
- (0xFCAF, 'M', u'سخ'),
- (0xFCB0, 'M', u'سم'),
- (0xFCB1, 'M', u'صح'),
- (0xFCB2, 'M', u'صخ'),
- (0xFCB3, 'M', u'صم'),
- (0xFCB4, 'M', u'ضج'),
- (0xFCB5, 'M', u'ضح'),
- (0xFCB6, 'M', u'ضخ'),
- (0xFCB7, 'M', u'ضم'),
- (0xFCB8, 'M', u'طح'),
- (0xFCB9, 'M', u'ظم'),
- (0xFCBA, 'M', u'عج'),
- (0xFCBB, 'M', u'عم'),
- (0xFCBC, 'M', u'غج'),
- (0xFCBD, 'M', u'غم'),
- (0xFCBE, 'M', u'Ùج'),
- (0xFCBF, 'M', u'ÙØ­'),
- (0xFCC0, 'M', u'ÙØ®'),
- (0xFCC1, 'M', u'ÙÙ…'),
- (0xFCC2, 'M', u'قح'),
- (0xFCC3, 'M', u'قم'),
- (0xFCC4, 'M', u'كج'),
- (0xFCC5, 'M', u'كح'),
- (0xFCC6, 'M', u'كخ'),
- (0xFCC7, 'M', u'كل'),
- (0xFCC8, 'M', u'كم'),
- (0xFCC9, 'M', u'لج'),
- (0xFCCA, 'M', u'لح'),
- (0xFCCB, 'M', u'لخ'),
- (0xFCCC, 'M', u'لم'),
- (0xFCCD, 'M', u'له'),
- (0xFCCE, 'M', u'مج'),
- (0xFCCF, 'M', u'مح'),
- (0xFCD0, 'M', u'مخ'),
- (0xFCD1, 'M', u'مم'),
- (0xFCD2, 'M', u'نج'),
- (0xFCD3, 'M', u'نح'),
- (0xFCD4, 'M', u'نخ'),
- (0xFCD5, 'M', u'نم'),
- (0xFCD6, 'M', u'نه'),
- (0xFCD7, 'M', u'هج'),
- (0xFCD8, 'M', u'هم'),
- (0xFCD9, 'M', u'هٰ'),
- (0xFCDA, 'M', u'يج'),
- (0xFCDB, 'M', u'يح'),
- (0xFCDC, 'M', u'يخ'),
- (0xFCDD, 'M', u'يم'),
- (0xFCDE, 'M', u'يه'),
- (0xFCDF, 'M', u'ئم'),
- (0xFCE0, 'M', u'ئه'),
- (0xFCE1, 'M', u'بم'),
- (0xFCE2, 'M', u'به'),
- (0xFCE3, 'M', u'تم'),
- (0xFCE4, 'M', u'ته'),
- (0xFCE5, 'M', u'ثم'),
- (0xFCE6, 'M', u'ثه'),
- (0xFCE7, 'M', u'سم'),
- (0xFCE8, 'M', u'سه'),
- (0xFCE9, 'M', u'شم'),
- (0xFCEA, 'M', u'شه'),
- (0xFCEB, 'M', u'كل'),
- (0xFCEC, 'M', u'كم'),
- (0xFCED, 'M', u'لم'),
- (0xFCEE, 'M', u'نم'),
- (0xFCEF, 'M', u'نه'),
- (0xFCF0, 'M', u'يم'),
- (0xFCF1, 'M', u'يه'),
- (0xFCF2, 'M', u'Ù€ÙŽÙ‘'),
- (0xFCF3, 'M', u'Ù€ÙÙ‘'),
- (0xFCF4, 'M', u'Ù€ÙÙ‘'),
- (0xFCF5, 'M', u'طى'),
- (0xFCF6, 'M', u'طي'),
- (0xFCF7, 'M', u'عى'),
- (0xFCF8, 'M', u'عي'),
- (0xFCF9, 'M', u'غى'),
- (0xFCFA, 'M', u'غي'),
- (0xFCFB, 'M', u'سى'),
- (0xFCFC, 'M', u'سي'),
- (0xFCFD, 'M', u'شى'),
- (0xFCFE, 'M', u'شي'),
- (0xFCFF, 'M', u'حى'),
- (0xFD00, 'M', u'حي'),
- (0xFD01, 'M', u'جى'),
- (0xFD02, 'M', u'جي'),
- (0xFD03, 'M', u'خى'),
- (0xFD04, 'M', u'خي'),
- (0xFD05, 'M', u'صى'),
- (0xFD06, 'M', u'صي'),
- ]
-
-def _seg_46():
- return [
- (0xFD07, 'M', u'ضى'),
- (0xFD08, 'M', u'ضي'),
- (0xFD09, 'M', u'شج'),
- (0xFD0A, 'M', u'شح'),
- (0xFD0B, 'M', u'شخ'),
- (0xFD0C, 'M', u'شم'),
- (0xFD0D, 'M', u'شر'),
- (0xFD0E, 'M', u'سر'),
- (0xFD0F, 'M', u'صر'),
- (0xFD10, 'M', u'ضر'),
- (0xFD11, 'M', u'طى'),
- (0xFD12, 'M', u'طي'),
- (0xFD13, 'M', u'عى'),
- (0xFD14, 'M', u'عي'),
- (0xFD15, 'M', u'غى'),
- (0xFD16, 'M', u'غي'),
- (0xFD17, 'M', u'سى'),
- (0xFD18, 'M', u'سي'),
- (0xFD19, 'M', u'شى'),
- (0xFD1A, 'M', u'شي'),
- (0xFD1B, 'M', u'حى'),
- (0xFD1C, 'M', u'حي'),
- (0xFD1D, 'M', u'جى'),
- (0xFD1E, 'M', u'جي'),
- (0xFD1F, 'M', u'خى'),
- (0xFD20, 'M', u'خي'),
- (0xFD21, 'M', u'صى'),
- (0xFD22, 'M', u'صي'),
- (0xFD23, 'M', u'ضى'),
- (0xFD24, 'M', u'ضي'),
- (0xFD25, 'M', u'شج'),
- (0xFD26, 'M', u'شح'),
- (0xFD27, 'M', u'شخ'),
- (0xFD28, 'M', u'شم'),
- (0xFD29, 'M', u'شر'),
- (0xFD2A, 'M', u'سر'),
- (0xFD2B, 'M', u'صر'),
- (0xFD2C, 'M', u'ضر'),
- (0xFD2D, 'M', u'شج'),
- (0xFD2E, 'M', u'شح'),
- (0xFD2F, 'M', u'شخ'),
- (0xFD30, 'M', u'شم'),
- (0xFD31, 'M', u'سه'),
- (0xFD32, 'M', u'شه'),
- (0xFD33, 'M', u'طم'),
- (0xFD34, 'M', u'سج'),
- (0xFD35, 'M', u'سح'),
- (0xFD36, 'M', u'سخ'),
- (0xFD37, 'M', u'شج'),
- (0xFD38, 'M', u'شح'),
- (0xFD39, 'M', u'شخ'),
- (0xFD3A, 'M', u'طم'),
- (0xFD3B, 'M', u'ظم'),
- (0xFD3C, 'M', u'اً'),
- (0xFD3E, 'V'),
- (0xFD40, 'X'),
- (0xFD50, 'M', u'تجم'),
- (0xFD51, 'M', u'تحج'),
- (0xFD53, 'M', u'تحم'),
- (0xFD54, 'M', u'تخم'),
- (0xFD55, 'M', u'تمج'),
- (0xFD56, 'M', u'تمح'),
- (0xFD57, 'M', u'تمخ'),
- (0xFD58, 'M', u'جمح'),
- (0xFD5A, 'M', u'حمي'),
- (0xFD5B, 'M', u'حمى'),
- (0xFD5C, 'M', u'سحج'),
- (0xFD5D, 'M', u'سجح'),
- (0xFD5E, 'M', u'سجى'),
- (0xFD5F, 'M', u'سمح'),
- (0xFD61, 'M', u'سمج'),
- (0xFD62, 'M', u'سمم'),
- (0xFD64, 'M', u'صحح'),
- (0xFD66, 'M', u'صمم'),
- (0xFD67, 'M', u'شحم'),
- (0xFD69, 'M', u'شجي'),
- (0xFD6A, 'M', u'شمخ'),
- (0xFD6C, 'M', u'شمم'),
- (0xFD6E, 'M', u'ضحى'),
- (0xFD6F, 'M', u'ضخم'),
- (0xFD71, 'M', u'طمح'),
- (0xFD73, 'M', u'طمم'),
- (0xFD74, 'M', u'طمي'),
- (0xFD75, 'M', u'عجم'),
- (0xFD76, 'M', u'عمم'),
- (0xFD78, 'M', u'عمى'),
- (0xFD79, 'M', u'غمم'),
- (0xFD7A, 'M', u'غمي'),
- (0xFD7B, 'M', u'غمى'),
- (0xFD7C, 'M', u'Ùخم'),
- (0xFD7E, 'M', u'قمح'),
- (0xFD7F, 'M', u'قمم'),
- (0xFD80, 'M', u'لحم'),
- (0xFD81, 'M', u'لحي'),
- (0xFD82, 'M', u'لحى'),
- (0xFD83, 'M', u'لجج'),
- (0xFD85, 'M', u'لخم'),
- (0xFD87, 'M', u'لمح'),
- (0xFD89, 'M', u'محج'),
- (0xFD8A, 'M', u'محم'),
- ]
-
-def _seg_47():
- return [
- (0xFD8B, 'M', u'محي'),
- (0xFD8C, 'M', u'مجح'),
- (0xFD8D, 'M', u'مجم'),
- (0xFD8E, 'M', u'مخج'),
- (0xFD8F, 'M', u'مخم'),
- (0xFD90, 'X'),
- (0xFD92, 'M', u'مجخ'),
- (0xFD93, 'M', u'همج'),
- (0xFD94, 'M', u'همم'),
- (0xFD95, 'M', u'نحم'),
- (0xFD96, 'M', u'نحى'),
- (0xFD97, 'M', u'نجم'),
- (0xFD99, 'M', u'نجى'),
- (0xFD9A, 'M', u'نمي'),
- (0xFD9B, 'M', u'نمى'),
- (0xFD9C, 'M', u'يمم'),
- (0xFD9E, 'M', u'بخي'),
- (0xFD9F, 'M', u'تجي'),
- (0xFDA0, 'M', u'تجى'),
- (0xFDA1, 'M', u'تخي'),
- (0xFDA2, 'M', u'تخى'),
- (0xFDA3, 'M', u'تمي'),
- (0xFDA4, 'M', u'تمى'),
- (0xFDA5, 'M', u'جمي'),
- (0xFDA6, 'M', u'جحى'),
- (0xFDA7, 'M', u'جمى'),
- (0xFDA8, 'M', u'سخى'),
- (0xFDA9, 'M', u'صحي'),
- (0xFDAA, 'M', u'شحي'),
- (0xFDAB, 'M', u'ضحي'),
- (0xFDAC, 'M', u'لجي'),
- (0xFDAD, 'M', u'لمي'),
- (0xFDAE, 'M', u'يحي'),
- (0xFDAF, 'M', u'يجي'),
- (0xFDB0, 'M', u'يمي'),
- (0xFDB1, 'M', u'ممي'),
- (0xFDB2, 'M', u'قمي'),
- (0xFDB3, 'M', u'نحي'),
- (0xFDB4, 'M', u'قمح'),
- (0xFDB5, 'M', u'لحم'),
- (0xFDB6, 'M', u'عمي'),
- (0xFDB7, 'M', u'كمي'),
- (0xFDB8, 'M', u'نجح'),
- (0xFDB9, 'M', u'مخي'),
- (0xFDBA, 'M', u'لجم'),
- (0xFDBB, 'M', u'كمم'),
- (0xFDBC, 'M', u'لجم'),
- (0xFDBD, 'M', u'نجح'),
- (0xFDBE, 'M', u'جحي'),
- (0xFDBF, 'M', u'حجي'),
- (0xFDC0, 'M', u'مجي'),
- (0xFDC1, 'M', u'Ùمي'),
- (0xFDC2, 'M', u'بحي'),
- (0xFDC3, 'M', u'كمم'),
- (0xFDC4, 'M', u'عجم'),
- (0xFDC5, 'M', u'صمم'),
- (0xFDC6, 'M', u'سخي'),
- (0xFDC7, 'M', u'نجي'),
- (0xFDC8, 'X'),
- (0xFDF0, 'M', u'صلے'),
- (0xFDF1, 'M', u'قلے'),
- (0xFDF2, 'M', u'الله'),
- (0xFDF3, 'M', u'اكبر'),
- (0xFDF4, 'M', u'محمد'),
- (0xFDF5, 'M', u'صلعم'),
- (0xFDF6, 'M', u'رسول'),
- (0xFDF7, 'M', u'عليه'),
- (0xFDF8, 'M', u'وسلم'),
- (0xFDF9, 'M', u'صلى'),
- (0xFDFA, '3', u'صلى الله عليه وسلم'),
- (0xFDFB, '3', u'جل جلاله'),
- (0xFDFC, 'M', u'ریال'),
- (0xFDFD, 'V'),
- (0xFDFE, 'X'),
- (0xFE00, 'I'),
- (0xFE10, '3', u','),
- (0xFE11, 'M', u'ã€'),
- (0xFE12, 'X'),
- (0xFE13, '3', u':'),
- (0xFE14, '3', u';'),
- (0xFE15, '3', u'!'),
- (0xFE16, '3', u'?'),
- (0xFE17, 'M', u'〖'),
- (0xFE18, 'M', u'〗'),
- (0xFE19, 'X'),
- (0xFE20, 'V'),
- (0xFE27, 'X'),
- (0xFE31, 'M', u'—'),
- (0xFE32, 'M', u'–'),
- (0xFE33, '3', u'_'),
- (0xFE35, '3', u'('),
- (0xFE36, '3', u')'),
- (0xFE37, '3', u'{'),
- (0xFE38, '3', u'}'),
- (0xFE39, 'M', u'〔'),
- (0xFE3A, 'M', u'〕'),
- (0xFE3B, 'M', u'ã€'),
- (0xFE3C, 'M', u'】'),
- (0xFE3D, 'M', u'《'),
- (0xFE3E, 'M', u'》'),
- ]
-
-def _seg_48():
- return [
- (0xFE3F, 'M', u'〈'),
- (0xFE40, 'M', u'〉'),
- (0xFE41, 'M', u'「'),
- (0xFE42, 'M', u'ã€'),
- (0xFE43, 'M', u'『'),
- (0xFE44, 'M', u'ã€'),
- (0xFE45, 'V'),
- (0xFE47, '3', u'['),
- (0xFE48, '3', u']'),
- (0xFE49, '3', u' Ì…'),
- (0xFE4D, '3', u'_'),
- (0xFE50, '3', u','),
- (0xFE51, 'M', u'ã€'),
- (0xFE52, 'X'),
- (0xFE54, '3', u';'),
- (0xFE55, '3', u':'),
- (0xFE56, '3', u'?'),
- (0xFE57, '3', u'!'),
- (0xFE58, 'M', u'—'),
- (0xFE59, '3', u'('),
- (0xFE5A, '3', u')'),
- (0xFE5B, '3', u'{'),
- (0xFE5C, '3', u'}'),
- (0xFE5D, 'M', u'〔'),
- (0xFE5E, 'M', u'〕'),
- (0xFE5F, '3', u'#'),
- (0xFE60, '3', u'&'),
- (0xFE61, '3', u'*'),
- (0xFE62, '3', u'+'),
- (0xFE63, 'M', u'-'),
- (0xFE64, '3', u'<'),
- (0xFE65, '3', u'>'),
- (0xFE66, '3', u'='),
- (0xFE67, 'X'),
- (0xFE68, '3', u'\\'),
- (0xFE69, '3', u'$'),
- (0xFE6A, '3', u'%'),
- (0xFE6B, '3', u'@'),
- (0xFE6C, 'X'),
- (0xFE70, '3', u' Ù‹'),
- (0xFE71, 'M', u'ـً'),
- (0xFE72, '3', u' ٌ'),
- (0xFE73, 'V'),
- (0xFE74, '3', u' Ù'),
- (0xFE75, 'X'),
- (0xFE76, '3', u' ÙŽ'),
- (0xFE77, 'M', u'Ù€ÙŽ'),
- (0xFE78, '3', u' Ù'),
- (0xFE79, 'M', u'Ù€Ù'),
- (0xFE7A, '3', u' Ù'),
- (0xFE7B, 'M', u'Ù€Ù'),
- (0xFE7C, '3', u' Ù‘'),
- (0xFE7D, 'M', u'ـّ'),
- (0xFE7E, '3', u' Ù’'),
- (0xFE7F, 'M', u'ـْ'),
- (0xFE80, 'M', u'Ø¡'),
- (0xFE81, 'M', u'Ø¢'),
- (0xFE83, 'M', u'Ø£'),
- (0xFE85, 'M', u'ؤ'),
- (0xFE87, 'M', u'Ø¥'),
- (0xFE89, 'M', u'ئ'),
- (0xFE8D, 'M', u'ا'),
- (0xFE8F, 'M', u'ب'),
- (0xFE93, 'M', u'Ø©'),
- (0xFE95, 'M', u'ت'),
- (0xFE99, 'M', u'Ø«'),
- (0xFE9D, 'M', u'ج'),
- (0xFEA1, 'M', u'Ø­'),
- (0xFEA5, 'M', u'Ø®'),
- (0xFEA9, 'M', u'د'),
- (0xFEAB, 'M', u'Ø°'),
- (0xFEAD, 'M', u'ر'),
- (0xFEAF, 'M', u'ز'),
- (0xFEB1, 'M', u'س'),
- (0xFEB5, 'M', u'Ø´'),
- (0xFEB9, 'M', u'ص'),
- (0xFEBD, 'M', u'ض'),
- (0xFEC1, 'M', u'Ø·'),
- (0xFEC5, 'M', u'ظ'),
- (0xFEC9, 'M', u'ع'),
- (0xFECD, 'M', u'غ'),
- (0xFED1, 'M', u'Ù'),
- (0xFED5, 'M', u'Ù‚'),
- (0xFED9, 'M', u'Ùƒ'),
- (0xFEDD, 'M', u'Ù„'),
- (0xFEE1, 'M', u'Ù…'),
- (0xFEE5, 'M', u'Ù†'),
- (0xFEE9, 'M', u'Ù‡'),
- (0xFEED, 'M', u'Ùˆ'),
- (0xFEEF, 'M', u'Ù‰'),
- (0xFEF1, 'M', u'ÙŠ'),
- (0xFEF5, 'M', u'لآ'),
- (0xFEF7, 'M', u'لأ'),
- (0xFEF9, 'M', u'لإ'),
- (0xFEFB, 'M', u'لا'),
- (0xFEFD, 'X'),
- (0xFEFF, 'I'),
- (0xFF00, 'X'),
- (0xFF01, '3', u'!'),
- (0xFF02, '3', u'"'),
- ]
-
-def _seg_49():
- return [
- (0xFF03, '3', u'#'),
- (0xFF04, '3', u'$'),
- (0xFF05, '3', u'%'),
- (0xFF06, '3', u'&'),
- (0xFF07, '3', u'\''),
- (0xFF08, '3', u'('),
- (0xFF09, '3', u')'),
- (0xFF0A, '3', u'*'),
- (0xFF0B, '3', u'+'),
- (0xFF0C, '3', u','),
- (0xFF0D, 'M', u'-'),
- (0xFF0E, 'M', u'.'),
- (0xFF0F, '3', u'/'),
- (0xFF10, 'M', u'0'),
- (0xFF11, 'M', u'1'),
- (0xFF12, 'M', u'2'),
- (0xFF13, 'M', u'3'),
- (0xFF14, 'M', u'4'),
- (0xFF15, 'M', u'5'),
- (0xFF16, 'M', u'6'),
- (0xFF17, 'M', u'7'),
- (0xFF18, 'M', u'8'),
- (0xFF19, 'M', u'9'),
- (0xFF1A, '3', u':'),
- (0xFF1B, '3', u';'),
- (0xFF1C, '3', u'<'),
- (0xFF1D, '3', u'='),
- (0xFF1E, '3', u'>'),
- (0xFF1F, '3', u'?'),
- (0xFF20, '3', u'@'),
- (0xFF21, 'M', u'a'),
- (0xFF22, 'M', u'b'),
- (0xFF23, 'M', u'c'),
- (0xFF24, 'M', u'd'),
- (0xFF25, 'M', u'e'),
- (0xFF26, 'M', u'f'),
- (0xFF27, 'M', u'g'),
- (0xFF28, 'M', u'h'),
- (0xFF29, 'M', u'i'),
- (0xFF2A, 'M', u'j'),
- (0xFF2B, 'M', u'k'),
- (0xFF2C, 'M', u'l'),
- (0xFF2D, 'M', u'm'),
- (0xFF2E, 'M', u'n'),
- (0xFF2F, 'M', u'o'),
- (0xFF30, 'M', u'p'),
- (0xFF31, 'M', u'q'),
- (0xFF32, 'M', u'r'),
- (0xFF33, 'M', u's'),
- (0xFF34, 'M', u't'),
- (0xFF35, 'M', u'u'),
- (0xFF36, 'M', u'v'),
- (0xFF37, 'M', u'w'),
- (0xFF38, 'M', u'x'),
- (0xFF39, 'M', u'y'),
- (0xFF3A, 'M', u'z'),
- (0xFF3B, '3', u'['),
- (0xFF3C, '3', u'\\'),
- (0xFF3D, '3', u']'),
- (0xFF3E, '3', u'^'),
- (0xFF3F, '3', u'_'),
- (0xFF40, '3', u'`'),
- (0xFF41, 'M', u'a'),
- (0xFF42, 'M', u'b'),
- (0xFF43, 'M', u'c'),
- (0xFF44, 'M', u'd'),
- (0xFF45, 'M', u'e'),
- (0xFF46, 'M', u'f'),
- (0xFF47, 'M', u'g'),
- (0xFF48, 'M', u'h'),
- (0xFF49, 'M', u'i'),
- (0xFF4A, 'M', u'j'),
- (0xFF4B, 'M', u'k'),
- (0xFF4C, 'M', u'l'),
- (0xFF4D, 'M', u'm'),
- (0xFF4E, 'M', u'n'),
- (0xFF4F, 'M', u'o'),
- (0xFF50, 'M', u'p'),
- (0xFF51, 'M', u'q'),
- (0xFF52, 'M', u'r'),
- (0xFF53, 'M', u's'),
- (0xFF54, 'M', u't'),
- (0xFF55, 'M', u'u'),
- (0xFF56, 'M', u'v'),
- (0xFF57, 'M', u'w'),
- (0xFF58, 'M', u'x'),
- (0xFF59, 'M', u'y'),
- (0xFF5A, 'M', u'z'),
- (0xFF5B, '3', u'{'),
- (0xFF5C, '3', u'|'),
- (0xFF5D, '3', u'}'),
- (0xFF5E, '3', u'~'),
- (0xFF5F, 'M', u'⦅'),
- (0xFF60, 'M', u'⦆'),
- (0xFF61, 'M', u'.'),
- (0xFF62, 'M', u'「'),
- (0xFF63, 'M', u'ã€'),
- (0xFF64, 'M', u'ã€'),
- (0xFF65, 'M', u'・'),
- (0xFF66, 'M', u'ヲ'),
- ]
-
-def _seg_50():
- return [
- (0xFF67, 'M', u'ã‚¡'),
- (0xFF68, 'M', u'ã‚£'),
- (0xFF69, 'M', u'ã‚¥'),
- (0xFF6A, 'M', u'ェ'),
- (0xFF6B, 'M', u'ã‚©'),
- (0xFF6C, 'M', u'ャ'),
- (0xFF6D, 'M', u'ュ'),
- (0xFF6E, 'M', u'ョ'),
- (0xFF6F, 'M', u'ッ'),
- (0xFF70, 'M', u'ー'),
- (0xFF71, 'M', u'ã‚¢'),
- (0xFF72, 'M', u'イ'),
- (0xFF73, 'M', u'ウ'),
- (0xFF74, 'M', u'エ'),
- (0xFF75, 'M', u'オ'),
- (0xFF76, 'M', u'ã‚«'),
- (0xFF77, 'M', u'ã‚­'),
- (0xFF78, 'M', u'ク'),
- (0xFF79, 'M', u'ケ'),
- (0xFF7A, 'M', u'コ'),
- (0xFF7B, 'M', u'サ'),
- (0xFF7C, 'M', u'ã‚·'),
- (0xFF7D, 'M', u'ス'),
- (0xFF7E, 'M', u'ã‚»'),
- (0xFF7F, 'M', u'ソ'),
- (0xFF80, 'M', u'ã‚¿'),
- (0xFF81, 'M', u'ãƒ'),
- (0xFF82, 'M', u'ツ'),
- (0xFF83, 'M', u'テ'),
- (0xFF84, 'M', u'ト'),
- (0xFF85, 'M', u'ナ'),
- (0xFF86, 'M', u'ニ'),
- (0xFF87, 'M', u'ヌ'),
- (0xFF88, 'M', u'ãƒ'),
- (0xFF89, 'M', u'ノ'),
- (0xFF8A, 'M', u'ãƒ'),
- (0xFF8B, 'M', u'ヒ'),
- (0xFF8C, 'M', u'フ'),
- (0xFF8D, 'M', u'ヘ'),
- (0xFF8E, 'M', u'ホ'),
- (0xFF8F, 'M', u'マ'),
- (0xFF90, 'M', u'ミ'),
- (0xFF91, 'M', u'ム'),
- (0xFF92, 'M', u'メ'),
- (0xFF93, 'M', u'モ'),
- (0xFF94, 'M', u'ヤ'),
- (0xFF95, 'M', u'ユ'),
- (0xFF96, 'M', u'ヨ'),
- (0xFF97, 'M', u'ラ'),
- (0xFF98, 'M', u'リ'),
- (0xFF99, 'M', u'ル'),
- (0xFF9A, 'M', u'レ'),
- (0xFF9B, 'M', u'ロ'),
- (0xFF9C, 'M', u'ワ'),
- (0xFF9D, 'M', u'ン'),
- (0xFF9E, 'M', u'ã‚™'),
- (0xFF9F, 'M', u'ã‚š'),
- (0xFFA0, 'X'),
- (0xFFA1, 'M', u'á„€'),
- (0xFFA2, 'M', u'á„'),
- (0xFFA3, 'M', u'ᆪ'),
- (0xFFA4, 'M', u'á„‚'),
- (0xFFA5, 'M', u'ᆬ'),
- (0xFFA6, 'M', u'ᆭ'),
- (0xFFA7, 'M', u'ᄃ'),
- (0xFFA8, 'M', u'á„„'),
- (0xFFA9, 'M', u'á„…'),
- (0xFFAA, 'M', u'ᆰ'),
- (0xFFAB, 'M', u'ᆱ'),
- (0xFFAC, 'M', u'ᆲ'),
- (0xFFAD, 'M', u'ᆳ'),
- (0xFFAE, 'M', u'ᆴ'),
- (0xFFAF, 'M', u'ᆵ'),
- (0xFFB0, 'M', u'á„š'),
- (0xFFB1, 'M', u'ᄆ'),
- (0xFFB2, 'M', u'ᄇ'),
- (0xFFB3, 'M', u'ᄈ'),
- (0xFFB4, 'M', u'á„¡'),
- (0xFFB5, 'M', u'ᄉ'),
- (0xFFB6, 'M', u'á„Š'),
- (0xFFB7, 'M', u'á„‹'),
- (0xFFB8, 'M', u'ᄌ'),
- (0xFFB9, 'M', u'á„'),
- (0xFFBA, 'M', u'á„Ž'),
- (0xFFBB, 'M', u'á„'),
- (0xFFBC, 'M', u'á„'),
- (0xFFBD, 'M', u'á„‘'),
- (0xFFBE, 'M', u'á„’'),
- (0xFFBF, 'X'),
- (0xFFC2, 'M', u'á…¡'),
- (0xFFC3, 'M', u'á…¢'),
- (0xFFC4, 'M', u'á…£'),
- (0xFFC5, 'M', u'á…¤'),
- (0xFFC6, 'M', u'á…¥'),
- (0xFFC7, 'M', u'á…¦'),
- (0xFFC8, 'X'),
- (0xFFCA, 'M', u'á…§'),
- (0xFFCB, 'M', u'á…¨'),
- (0xFFCC, 'M', u'á…©'),
- (0xFFCD, 'M', u'á…ª'),
- ]
-
-def _seg_51():
- return [
- (0xFFCE, 'M', u'á…«'),
- (0xFFCF, 'M', u'á…¬'),
- (0xFFD0, 'X'),
- (0xFFD2, 'M', u'á…­'),
- (0xFFD3, 'M', u'á…®'),
- (0xFFD4, 'M', u'á…¯'),
- (0xFFD5, 'M', u'á…°'),
- (0xFFD6, 'M', u'á…±'),
- (0xFFD7, 'M', u'á…²'),
- (0xFFD8, 'X'),
- (0xFFDA, 'M', u'á…³'),
- (0xFFDB, 'M', u'á…´'),
- (0xFFDC, 'M', u'á…µ'),
- (0xFFDD, 'X'),
- (0xFFE0, 'M', u'¢'),
- (0xFFE1, 'M', u'£'),
- (0xFFE2, 'M', u'¬'),
- (0xFFE3, '3', u' Ì„'),
- (0xFFE4, 'M', u'¦'),
- (0xFFE5, 'M', u'Â¥'),
- (0xFFE6, 'M', u'â‚©'),
- (0xFFE7, 'X'),
- (0xFFE8, 'M', u'│'),
- (0xFFE9, 'M', u'â†'),
- (0xFFEA, 'M', u'↑'),
- (0xFFEB, 'M', u'→'),
- (0xFFEC, 'M', u'↓'),
- (0xFFED, 'M', u'â– '),
- (0xFFEE, 'M', u'â—‹'),
- (0xFFEF, 'X'),
- (0x10000, 'V'),
- (0x1000C, 'X'),
- (0x1000D, 'V'),
- (0x10027, 'X'),
- (0x10028, 'V'),
- (0x1003B, 'X'),
- (0x1003C, 'V'),
- (0x1003E, 'X'),
- (0x1003F, 'V'),
- (0x1004E, 'X'),
- (0x10050, 'V'),
- (0x1005E, 'X'),
- (0x10080, 'V'),
- (0x100FB, 'X'),
- (0x10100, 'V'),
- (0x10103, 'X'),
- (0x10107, 'V'),
- (0x10134, 'X'),
- (0x10137, 'V'),
- (0x1018B, 'X'),
- (0x10190, 'V'),
- (0x1019C, 'X'),
- (0x101D0, 'V'),
- (0x101FE, 'X'),
- (0x10280, 'V'),
- (0x1029D, 'X'),
- (0x102A0, 'V'),
- (0x102D1, 'X'),
- (0x10300, 'V'),
- (0x1031F, 'X'),
- (0x10320, 'V'),
- (0x10324, 'X'),
- (0x10330, 'V'),
- (0x1034B, 'X'),
- (0x10380, 'V'),
- (0x1039E, 'X'),
- (0x1039F, 'V'),
- (0x103C4, 'X'),
- (0x103C8, 'V'),
- (0x103D6, 'X'),
- (0x10400, 'M', u'ð¨'),
- (0x10401, 'M', u'ð©'),
- (0x10402, 'M', u'ðª'),
- (0x10403, 'M', u'ð«'),
- (0x10404, 'M', u'ð¬'),
- (0x10405, 'M', u'ð­'),
- (0x10406, 'M', u'ð®'),
- (0x10407, 'M', u'ð¯'),
- (0x10408, 'M', u'ð°'),
- (0x10409, 'M', u'ð±'),
- (0x1040A, 'M', u'ð²'),
- (0x1040B, 'M', u'ð³'),
- (0x1040C, 'M', u'ð´'),
- (0x1040D, 'M', u'ðµ'),
- (0x1040E, 'M', u'ð¶'),
- (0x1040F, 'M', u'ð·'),
- (0x10410, 'M', u'ð¸'),
- (0x10411, 'M', u'ð¹'),
- (0x10412, 'M', u'ðº'),
- (0x10413, 'M', u'ð»'),
- (0x10414, 'M', u'ð¼'),
- (0x10415, 'M', u'ð½'),
- (0x10416, 'M', u'ð¾'),
- (0x10417, 'M', u'ð¿'),
- (0x10418, 'M', u'ð‘€'),
- (0x10419, 'M', u'ð‘'),
- (0x1041A, 'M', u'ð‘‚'),
- (0x1041B, 'M', u'ð‘ƒ'),
- (0x1041C, 'M', u'ð‘„'),
- (0x1041D, 'M', u'ð‘…'),
- ]
-
-def _seg_52():
- return [
- (0x1041E, 'M', u'ð‘†'),
- (0x1041F, 'M', u'ð‘‡'),
- (0x10420, 'M', u'ð‘ˆ'),
- (0x10421, 'M', u'ð‘‰'),
- (0x10422, 'M', u'ð‘Š'),
- (0x10423, 'M', u'ð‘‹'),
- (0x10424, 'M', u'ð‘Œ'),
- (0x10425, 'M', u'ð‘'),
- (0x10426, 'M', u'ð‘Ž'),
- (0x10427, 'M', u'ð‘'),
- (0x10428, 'V'),
- (0x1049E, 'X'),
- (0x104A0, 'V'),
- (0x104AA, 'X'),
- (0x10800, 'V'),
- (0x10806, 'X'),
- (0x10808, 'V'),
- (0x10809, 'X'),
- (0x1080A, 'V'),
- (0x10836, 'X'),
- (0x10837, 'V'),
- (0x10839, 'X'),
- (0x1083C, 'V'),
- (0x1083D, 'X'),
- (0x1083F, 'V'),
- (0x10856, 'X'),
- (0x10857, 'V'),
- (0x10860, 'X'),
- (0x10900, 'V'),
- (0x1091C, 'X'),
- (0x1091F, 'V'),
- (0x1093A, 'X'),
- (0x1093F, 'V'),
- (0x10940, 'X'),
- (0x10980, 'V'),
- (0x109B8, 'X'),
- (0x109BE, 'V'),
- (0x109C0, 'X'),
- (0x10A00, 'V'),
- (0x10A04, 'X'),
- (0x10A05, 'V'),
- (0x10A07, 'X'),
- (0x10A0C, 'V'),
- (0x10A14, 'X'),
- (0x10A15, 'V'),
- (0x10A18, 'X'),
- (0x10A19, 'V'),
- (0x10A34, 'X'),
- (0x10A38, 'V'),
- (0x10A3B, 'X'),
- (0x10A3F, 'V'),
- (0x10A48, 'X'),
- (0x10A50, 'V'),
- (0x10A59, 'X'),
- (0x10A60, 'V'),
- (0x10A80, 'X'),
- (0x10B00, 'V'),
- (0x10B36, 'X'),
- (0x10B39, 'V'),
- (0x10B56, 'X'),
- (0x10B58, 'V'),
- (0x10B73, 'X'),
- (0x10B78, 'V'),
- (0x10B80, 'X'),
- (0x10C00, 'V'),
- (0x10C49, 'X'),
- (0x10E60, 'V'),
- (0x10E7F, 'X'),
- (0x11000, 'V'),
- (0x1104E, 'X'),
- (0x11052, 'V'),
- (0x11070, 'X'),
- (0x11080, 'V'),
- (0x110BD, 'X'),
- (0x110BE, 'V'),
- (0x110C2, 'X'),
- (0x110D0, 'V'),
- (0x110E9, 'X'),
- (0x110F0, 'V'),
- (0x110FA, 'X'),
- (0x11100, 'V'),
- (0x11135, 'X'),
- (0x11136, 'V'),
- (0x11144, 'X'),
- (0x11180, 'V'),
- (0x111C9, 'X'),
- (0x111D0, 'V'),
- (0x111DA, 'X'),
- (0x11680, 'V'),
- (0x116B8, 'X'),
- (0x116C0, 'V'),
- (0x116CA, 'X'),
- (0x12000, 'V'),
- (0x1236F, 'X'),
- (0x12400, 'V'),
- (0x12463, 'X'),
- (0x12470, 'V'),
- (0x12474, 'X'),
- (0x13000, 'V'),
- (0x1342F, 'X'),
- ]
-
-def _seg_53():
- return [
- (0x16800, 'V'),
- (0x16A39, 'X'),
- (0x16F00, 'V'),
- (0x16F45, 'X'),
- (0x16F50, 'V'),
- (0x16F7F, 'X'),
- (0x16F8F, 'V'),
- (0x16FA0, 'X'),
- (0x1B000, 'V'),
- (0x1B002, 'X'),
- (0x1D000, 'V'),
- (0x1D0F6, 'X'),
- (0x1D100, 'V'),
- (0x1D127, 'X'),
- (0x1D129, 'V'),
- (0x1D15E, 'M', u'ð…—ð…¥'),
- (0x1D15F, 'M', u'ð…˜ð…¥'),
- (0x1D160, 'M', u'ð…˜ð…¥ð…®'),
- (0x1D161, 'M', u'ð…˜ð…¥ð…¯'),
- (0x1D162, 'M', u'ð…˜ð…¥ð…°'),
- (0x1D163, 'M', u'ð…˜ð…¥ð…±'),
- (0x1D164, 'M', u'ð…˜ð…¥ð…²'),
- (0x1D165, 'V'),
- (0x1D173, 'X'),
- (0x1D17B, 'V'),
- (0x1D1BB, 'M', u'ð†¹ð…¥'),
- (0x1D1BC, 'M', u'ð†ºð…¥'),
- (0x1D1BD, 'M', u'ð†¹ð…¥ð…®'),
- (0x1D1BE, 'M', u'ð†ºð…¥ð…®'),
- (0x1D1BF, 'M', u'ð†¹ð…¥ð…¯'),
- (0x1D1C0, 'M', u'ð†ºð…¥ð…¯'),
- (0x1D1C1, 'V'),
- (0x1D1DE, 'X'),
- (0x1D200, 'V'),
- (0x1D246, 'X'),
- (0x1D300, 'V'),
- (0x1D357, 'X'),
- (0x1D360, 'V'),
- (0x1D372, 'X'),
- (0x1D400, 'M', u'a'),
- (0x1D401, 'M', u'b'),
- (0x1D402, 'M', u'c'),
- (0x1D403, 'M', u'd'),
- (0x1D404, 'M', u'e'),
- (0x1D405, 'M', u'f'),
- (0x1D406, 'M', u'g'),
- (0x1D407, 'M', u'h'),
- (0x1D408, 'M', u'i'),
- (0x1D409, 'M', u'j'),
- (0x1D40A, 'M', u'k'),
- (0x1D40B, 'M', u'l'),
- (0x1D40C, 'M', u'm'),
- (0x1D40D, 'M', u'n'),
- (0x1D40E, 'M', u'o'),
- (0x1D40F, 'M', u'p'),
- (0x1D410, 'M', u'q'),
- (0x1D411, 'M', u'r'),
- (0x1D412, 'M', u's'),
- (0x1D413, 'M', u't'),
- (0x1D414, 'M', u'u'),
- (0x1D415, 'M', u'v'),
- (0x1D416, 'M', u'w'),
- (0x1D417, 'M', u'x'),
- (0x1D418, 'M', u'y'),
- (0x1D419, 'M', u'z'),
- (0x1D41A, 'M', u'a'),
- (0x1D41B, 'M', u'b'),
- (0x1D41C, 'M', u'c'),
- (0x1D41D, 'M', u'd'),
- (0x1D41E, 'M', u'e'),
- (0x1D41F, 'M', u'f'),
- (0x1D420, 'M', u'g'),
- (0x1D421, 'M', u'h'),
- (0x1D422, 'M', u'i'),
- (0x1D423, 'M', u'j'),
- (0x1D424, 'M', u'k'),
- (0x1D425, 'M', u'l'),
- (0x1D426, 'M', u'm'),
- (0x1D427, 'M', u'n'),
- (0x1D428, 'M', u'o'),
- (0x1D429, 'M', u'p'),
- (0x1D42A, 'M', u'q'),
- (0x1D42B, 'M', u'r'),
- (0x1D42C, 'M', u's'),
- (0x1D42D, 'M', u't'),
- (0x1D42E, 'M', u'u'),
- (0x1D42F, 'M', u'v'),
- (0x1D430, 'M', u'w'),
- (0x1D431, 'M', u'x'),
- (0x1D432, 'M', u'y'),
- (0x1D433, 'M', u'z'),
- (0x1D434, 'M', u'a'),
- (0x1D435, 'M', u'b'),
- (0x1D436, 'M', u'c'),
- (0x1D437, 'M', u'd'),
- (0x1D438, 'M', u'e'),
- (0x1D439, 'M', u'f'),
- (0x1D43A, 'M', u'g'),
- (0x1D43B, 'M', u'h'),
- (0x1D43C, 'M', u'i'),
- ]
-
-def _seg_54():
- return [
- (0x1D43D, 'M', u'j'),
- (0x1D43E, 'M', u'k'),
- (0x1D43F, 'M', u'l'),
- (0x1D440, 'M', u'm'),
- (0x1D441, 'M', u'n'),
- (0x1D442, 'M', u'o'),
- (0x1D443, 'M', u'p'),
- (0x1D444, 'M', u'q'),
- (0x1D445, 'M', u'r'),
- (0x1D446, 'M', u's'),
- (0x1D447, 'M', u't'),
- (0x1D448, 'M', u'u'),
- (0x1D449, 'M', u'v'),
- (0x1D44A, 'M', u'w'),
- (0x1D44B, 'M', u'x'),
- (0x1D44C, 'M', u'y'),
- (0x1D44D, 'M', u'z'),
- (0x1D44E, 'M', u'a'),
- (0x1D44F, 'M', u'b'),
- (0x1D450, 'M', u'c'),
- (0x1D451, 'M', u'd'),
- (0x1D452, 'M', u'e'),
- (0x1D453, 'M', u'f'),
- (0x1D454, 'M', u'g'),
- (0x1D455, 'X'),
- (0x1D456, 'M', u'i'),
- (0x1D457, 'M', u'j'),
- (0x1D458, 'M', u'k'),
- (0x1D459, 'M', u'l'),
- (0x1D45A, 'M', u'm'),
- (0x1D45B, 'M', u'n'),
- (0x1D45C, 'M', u'o'),
- (0x1D45D, 'M', u'p'),
- (0x1D45E, 'M', u'q'),
- (0x1D45F, 'M', u'r'),
- (0x1D460, 'M', u's'),
- (0x1D461, 'M', u't'),
- (0x1D462, 'M', u'u'),
- (0x1D463, 'M', u'v'),
- (0x1D464, 'M', u'w'),
- (0x1D465, 'M', u'x'),
- (0x1D466, 'M', u'y'),
- (0x1D467, 'M', u'z'),
- (0x1D468, 'M', u'a'),
- (0x1D469, 'M', u'b'),
- (0x1D46A, 'M', u'c'),
- (0x1D46B, 'M', u'd'),
- (0x1D46C, 'M', u'e'),
- (0x1D46D, 'M', u'f'),
- (0x1D46E, 'M', u'g'),
- (0x1D46F, 'M', u'h'),
- (0x1D470, 'M', u'i'),
- (0x1D471, 'M', u'j'),
- (0x1D472, 'M', u'k'),
- (0x1D473, 'M', u'l'),
- (0x1D474, 'M', u'm'),
- (0x1D475, 'M', u'n'),
- (0x1D476, 'M', u'o'),
- (0x1D477, 'M', u'p'),
- (0x1D478, 'M', u'q'),
- (0x1D479, 'M', u'r'),
- (0x1D47A, 'M', u's'),
- (0x1D47B, 'M', u't'),
- (0x1D47C, 'M', u'u'),
- (0x1D47D, 'M', u'v'),
- (0x1D47E, 'M', u'w'),
- (0x1D47F, 'M', u'x'),
- (0x1D480, 'M', u'y'),
- (0x1D481, 'M', u'z'),
- (0x1D482, 'M', u'a'),
- (0x1D483, 'M', u'b'),
- (0x1D484, 'M', u'c'),
- (0x1D485, 'M', u'd'),
- (0x1D486, 'M', u'e'),
- (0x1D487, 'M', u'f'),
- (0x1D488, 'M', u'g'),
- (0x1D489, 'M', u'h'),
- (0x1D48A, 'M', u'i'),
- (0x1D48B, 'M', u'j'),
- (0x1D48C, 'M', u'k'),
- (0x1D48D, 'M', u'l'),
- (0x1D48E, 'M', u'm'),
- (0x1D48F, 'M', u'n'),
- (0x1D490, 'M', u'o'),
- (0x1D491, 'M', u'p'),
- (0x1D492, 'M', u'q'),
- (0x1D493, 'M', u'r'),
- (0x1D494, 'M', u's'),
- (0x1D495, 'M', u't'),
- (0x1D496, 'M', u'u'),
- (0x1D497, 'M', u'v'),
- (0x1D498, 'M', u'w'),
- (0x1D499, 'M', u'x'),
- (0x1D49A, 'M', u'y'),
- (0x1D49B, 'M', u'z'),
- (0x1D49C, 'M', u'a'),
- (0x1D49D, 'X'),
- (0x1D49E, 'M', u'c'),
- (0x1D49F, 'M', u'd'),
- (0x1D4A0, 'X'),
- ]
-
-def _seg_55():
- return [
- (0x1D4A2, 'M', u'g'),
- (0x1D4A3, 'X'),
- (0x1D4A5, 'M', u'j'),
- (0x1D4A6, 'M', u'k'),
- (0x1D4A7, 'X'),
- (0x1D4A9, 'M', u'n'),
- (0x1D4AA, 'M', u'o'),
- (0x1D4AB, 'M', u'p'),
- (0x1D4AC, 'M', u'q'),
- (0x1D4AD, 'X'),
- (0x1D4AE, 'M', u's'),
- (0x1D4AF, 'M', u't'),
- (0x1D4B0, 'M', u'u'),
- (0x1D4B1, 'M', u'v'),
- (0x1D4B2, 'M', u'w'),
- (0x1D4B3, 'M', u'x'),
- (0x1D4B4, 'M', u'y'),
- (0x1D4B5, 'M', u'z'),
- (0x1D4B6, 'M', u'a'),
- (0x1D4B7, 'M', u'b'),
- (0x1D4B8, 'M', u'c'),
- (0x1D4B9, 'M', u'd'),
- (0x1D4BA, 'X'),
- (0x1D4BB, 'M', u'f'),
- (0x1D4BC, 'X'),
- (0x1D4BD, 'M', u'h'),
- (0x1D4BE, 'M', u'i'),
- (0x1D4BF, 'M', u'j'),
- (0x1D4C0, 'M', u'k'),
- (0x1D4C1, 'M', u'l'),
- (0x1D4C2, 'M', u'm'),
- (0x1D4C3, 'M', u'n'),
- (0x1D4C4, 'X'),
- (0x1D4C5, 'M', u'p'),
- (0x1D4C6, 'M', u'q'),
- (0x1D4C7, 'M', u'r'),
- (0x1D4C8, 'M', u's'),
- (0x1D4C9, 'M', u't'),
- (0x1D4CA, 'M', u'u'),
- (0x1D4CB, 'M', u'v'),
- (0x1D4CC, 'M', u'w'),
- (0x1D4CD, 'M', u'x'),
- (0x1D4CE, 'M', u'y'),
- (0x1D4CF, 'M', u'z'),
- (0x1D4D0, 'M', u'a'),
- (0x1D4D1, 'M', u'b'),
- (0x1D4D2, 'M', u'c'),
- (0x1D4D3, 'M', u'd'),
- (0x1D4D4, 'M', u'e'),
- (0x1D4D5, 'M', u'f'),
- (0x1D4D6, 'M', u'g'),
- (0x1D4D7, 'M', u'h'),
- (0x1D4D8, 'M', u'i'),
- (0x1D4D9, 'M', u'j'),
- (0x1D4DA, 'M', u'k'),
- (0x1D4DB, 'M', u'l'),
- (0x1D4DC, 'M', u'm'),
- (0x1D4DD, 'M', u'n'),
- (0x1D4DE, 'M', u'o'),
- (0x1D4DF, 'M', u'p'),
- (0x1D4E0, 'M', u'q'),
- (0x1D4E1, 'M', u'r'),
- (0x1D4E2, 'M', u's'),
- (0x1D4E3, 'M', u't'),
- (0x1D4E4, 'M', u'u'),
- (0x1D4E5, 'M', u'v'),
- (0x1D4E6, 'M', u'w'),
- (0x1D4E7, 'M', u'x'),
- (0x1D4E8, 'M', u'y'),
- (0x1D4E9, 'M', u'z'),
- (0x1D4EA, 'M', u'a'),
- (0x1D4EB, 'M', u'b'),
- (0x1D4EC, 'M', u'c'),
- (0x1D4ED, 'M', u'd'),
- (0x1D4EE, 'M', u'e'),
- (0x1D4EF, 'M', u'f'),
- (0x1D4F0, 'M', u'g'),
- (0x1D4F1, 'M', u'h'),
- (0x1D4F2, 'M', u'i'),
- (0x1D4F3, 'M', u'j'),
- (0x1D4F4, 'M', u'k'),
- (0x1D4F5, 'M', u'l'),
- (0x1D4F6, 'M', u'm'),
- (0x1D4F7, 'M', u'n'),
- (0x1D4F8, 'M', u'o'),
- (0x1D4F9, 'M', u'p'),
- (0x1D4FA, 'M', u'q'),
- (0x1D4FB, 'M', u'r'),
- (0x1D4FC, 'M', u's'),
- (0x1D4FD, 'M', u't'),
- (0x1D4FE, 'M', u'u'),
- (0x1D4FF, 'M', u'v'),
- (0x1D500, 'M', u'w'),
- (0x1D501, 'M', u'x'),
- (0x1D502, 'M', u'y'),
- (0x1D503, 'M', u'z'),
- (0x1D504, 'M', u'a'),
- (0x1D505, 'M', u'b'),
- (0x1D506, 'X'),
- (0x1D507, 'M', u'd'),
- ]
-
-def _seg_56():
- return [
- (0x1D508, 'M', u'e'),
- (0x1D509, 'M', u'f'),
- (0x1D50A, 'M', u'g'),
- (0x1D50B, 'X'),
- (0x1D50D, 'M', u'j'),
- (0x1D50E, 'M', u'k'),
- (0x1D50F, 'M', u'l'),
- (0x1D510, 'M', u'm'),
- (0x1D511, 'M', u'n'),
- (0x1D512, 'M', u'o'),
- (0x1D513, 'M', u'p'),
- (0x1D514, 'M', u'q'),
- (0x1D515, 'X'),
- (0x1D516, 'M', u's'),
- (0x1D517, 'M', u't'),
- (0x1D518, 'M', u'u'),
- (0x1D519, 'M', u'v'),
- (0x1D51A, 'M', u'w'),
- (0x1D51B, 'M', u'x'),
- (0x1D51C, 'M', u'y'),
- (0x1D51D, 'X'),
- (0x1D51E, 'M', u'a'),
- (0x1D51F, 'M', u'b'),
- (0x1D520, 'M', u'c'),
- (0x1D521, 'M', u'd'),
- (0x1D522, 'M', u'e'),
- (0x1D523, 'M', u'f'),
- (0x1D524, 'M', u'g'),
- (0x1D525, 'M', u'h'),
- (0x1D526, 'M', u'i'),
- (0x1D527, 'M', u'j'),
- (0x1D528, 'M', u'k'),
- (0x1D529, 'M', u'l'),
- (0x1D52A, 'M', u'm'),
- (0x1D52B, 'M', u'n'),
- (0x1D52C, 'M', u'o'),
- (0x1D52D, 'M', u'p'),
- (0x1D52E, 'M', u'q'),
- (0x1D52F, 'M', u'r'),
- (0x1D530, 'M', u's'),
- (0x1D531, 'M', u't'),
- (0x1D532, 'M', u'u'),
- (0x1D533, 'M', u'v'),
- (0x1D534, 'M', u'w'),
- (0x1D535, 'M', u'x'),
- (0x1D536, 'M', u'y'),
- (0x1D537, 'M', u'z'),
- (0x1D538, 'M', u'a'),
- (0x1D539, 'M', u'b'),
- (0x1D53A, 'X'),
- (0x1D53B, 'M', u'd'),
- (0x1D53C, 'M', u'e'),
- (0x1D53D, 'M', u'f'),
- (0x1D53E, 'M', u'g'),
- (0x1D53F, 'X'),
- (0x1D540, 'M', u'i'),
- (0x1D541, 'M', u'j'),
- (0x1D542, 'M', u'k'),
- (0x1D543, 'M', u'l'),
- (0x1D544, 'M', u'm'),
- (0x1D545, 'X'),
- (0x1D546, 'M', u'o'),
- (0x1D547, 'X'),
- (0x1D54A, 'M', u's'),
- (0x1D54B, 'M', u't'),
- (0x1D54C, 'M', u'u'),
- (0x1D54D, 'M', u'v'),
- (0x1D54E, 'M', u'w'),
- (0x1D54F, 'M', u'x'),
- (0x1D550, 'M', u'y'),
- (0x1D551, 'X'),
- (0x1D552, 'M', u'a'),
- (0x1D553, 'M', u'b'),
- (0x1D554, 'M', u'c'),
- (0x1D555, 'M', u'd'),
- (0x1D556, 'M', u'e'),
- (0x1D557, 'M', u'f'),
- (0x1D558, 'M', u'g'),
- (0x1D559, 'M', u'h'),
- (0x1D55A, 'M', u'i'),
- (0x1D55B, 'M', u'j'),
- (0x1D55C, 'M', u'k'),
- (0x1D55D, 'M', u'l'),
- (0x1D55E, 'M', u'm'),
- (0x1D55F, 'M', u'n'),
- (0x1D560, 'M', u'o'),
- (0x1D561, 'M', u'p'),
- (0x1D562, 'M', u'q'),
- (0x1D563, 'M', u'r'),
- (0x1D564, 'M', u's'),
- (0x1D565, 'M', u't'),
- (0x1D566, 'M', u'u'),
- (0x1D567, 'M', u'v'),
- (0x1D568, 'M', u'w'),
- (0x1D569, 'M', u'x'),
- (0x1D56A, 'M', u'y'),
- (0x1D56B, 'M', u'z'),
- (0x1D56C, 'M', u'a'),
- (0x1D56D, 'M', u'b'),
- (0x1D56E, 'M', u'c'),
- ]
-
-def _seg_57():
- return [
- (0x1D56F, 'M', u'd'),
- (0x1D570, 'M', u'e'),
- (0x1D571, 'M', u'f'),
- (0x1D572, 'M', u'g'),
- (0x1D573, 'M', u'h'),
- (0x1D574, 'M', u'i'),
- (0x1D575, 'M', u'j'),
- (0x1D576, 'M', u'k'),
- (0x1D577, 'M', u'l'),
- (0x1D578, 'M', u'm'),
- (0x1D579, 'M', u'n'),
- (0x1D57A, 'M', u'o'),
- (0x1D57B, 'M', u'p'),
- (0x1D57C, 'M', u'q'),
- (0x1D57D, 'M', u'r'),
- (0x1D57E, 'M', u's'),
- (0x1D57F, 'M', u't'),
- (0x1D580, 'M', u'u'),
- (0x1D581, 'M', u'v'),
- (0x1D582, 'M', u'w'),
- (0x1D583, 'M', u'x'),
- (0x1D584, 'M', u'y'),
- (0x1D585, 'M', u'z'),
- (0x1D586, 'M', u'a'),
- (0x1D587, 'M', u'b'),
- (0x1D588, 'M', u'c'),
- (0x1D589, 'M', u'd'),
- (0x1D58A, 'M', u'e'),
- (0x1D58B, 'M', u'f'),
- (0x1D58C, 'M', u'g'),
- (0x1D58D, 'M', u'h'),
- (0x1D58E, 'M', u'i'),
- (0x1D58F, 'M', u'j'),
- (0x1D590, 'M', u'k'),
- (0x1D591, 'M', u'l'),
- (0x1D592, 'M', u'm'),
- (0x1D593, 'M', u'n'),
- (0x1D594, 'M', u'o'),
- (0x1D595, 'M', u'p'),
- (0x1D596, 'M', u'q'),
- (0x1D597, 'M', u'r'),
- (0x1D598, 'M', u's'),
- (0x1D599, 'M', u't'),
- (0x1D59A, 'M', u'u'),
- (0x1D59B, 'M', u'v'),
- (0x1D59C, 'M', u'w'),
- (0x1D59D, 'M', u'x'),
- (0x1D59E, 'M', u'y'),
- (0x1D59F, 'M', u'z'),
- (0x1D5A0, 'M', u'a'),
- (0x1D5A1, 'M', u'b'),
- (0x1D5A2, 'M', u'c'),
- (0x1D5A3, 'M', u'd'),
- (0x1D5A4, 'M', u'e'),
- (0x1D5A5, 'M', u'f'),
- (0x1D5A6, 'M', u'g'),
- (0x1D5A7, 'M', u'h'),
- (0x1D5A8, 'M', u'i'),
- (0x1D5A9, 'M', u'j'),
- (0x1D5AA, 'M', u'k'),
- (0x1D5AB, 'M', u'l'),
- (0x1D5AC, 'M', u'm'),
- (0x1D5AD, 'M', u'n'),
- (0x1D5AE, 'M', u'o'),
- (0x1D5AF, 'M', u'p'),
- (0x1D5B0, 'M', u'q'),
- (0x1D5B1, 'M', u'r'),
- (0x1D5B2, 'M', u's'),
- (0x1D5B3, 'M', u't'),
- (0x1D5B4, 'M', u'u'),
- (0x1D5B5, 'M', u'v'),
- (0x1D5B6, 'M', u'w'),
- (0x1D5B7, 'M', u'x'),
- (0x1D5B8, 'M', u'y'),
- (0x1D5B9, 'M', u'z'),
- (0x1D5BA, 'M', u'a'),
- (0x1D5BB, 'M', u'b'),
- (0x1D5BC, 'M', u'c'),
- (0x1D5BD, 'M', u'd'),
- (0x1D5BE, 'M', u'e'),
- (0x1D5BF, 'M', u'f'),
- (0x1D5C0, 'M', u'g'),
- (0x1D5C1, 'M', u'h'),
- (0x1D5C2, 'M', u'i'),
- (0x1D5C3, 'M', u'j'),
- (0x1D5C4, 'M', u'k'),
- (0x1D5C5, 'M', u'l'),
- (0x1D5C6, 'M', u'm'),
- (0x1D5C7, 'M', u'n'),
- (0x1D5C8, 'M', u'o'),
- (0x1D5C9, 'M', u'p'),
- (0x1D5CA, 'M', u'q'),
- (0x1D5CB, 'M', u'r'),
- (0x1D5CC, 'M', u's'),
- (0x1D5CD, 'M', u't'),
- (0x1D5CE, 'M', u'u'),
- (0x1D5CF, 'M', u'v'),
- (0x1D5D0, 'M', u'w'),
- (0x1D5D1, 'M', u'x'),
- (0x1D5D2, 'M', u'y'),
- ]
-
-def _seg_58():
- return [
- (0x1D5D3, 'M', u'z'),
- (0x1D5D4, 'M', u'a'),
- (0x1D5D5, 'M', u'b'),
- (0x1D5D6, 'M', u'c'),
- (0x1D5D7, 'M', u'd'),
- (0x1D5D8, 'M', u'e'),
- (0x1D5D9, 'M', u'f'),
- (0x1D5DA, 'M', u'g'),
- (0x1D5DB, 'M', u'h'),
- (0x1D5DC, 'M', u'i'),
- (0x1D5DD, 'M', u'j'),
- (0x1D5DE, 'M', u'k'),
- (0x1D5DF, 'M', u'l'),
- (0x1D5E0, 'M', u'm'),
- (0x1D5E1, 'M', u'n'),
- (0x1D5E2, 'M', u'o'),
- (0x1D5E3, 'M', u'p'),
- (0x1D5E4, 'M', u'q'),
- (0x1D5E5, 'M', u'r'),
- (0x1D5E6, 'M', u's'),
- (0x1D5E7, 'M', u't'),
- (0x1D5E8, 'M', u'u'),
- (0x1D5E9, 'M', u'v'),
- (0x1D5EA, 'M', u'w'),
- (0x1D5EB, 'M', u'x'),
- (0x1D5EC, 'M', u'y'),
- (0x1D5ED, 'M', u'z'),
- (0x1D5EE, 'M', u'a'),
- (0x1D5EF, 'M', u'b'),
- (0x1D5F0, 'M', u'c'),
- (0x1D5F1, 'M', u'd'),
- (0x1D5F2, 'M', u'e'),
- (0x1D5F3, 'M', u'f'),
- (0x1D5F4, 'M', u'g'),
- (0x1D5F5, 'M', u'h'),
- (0x1D5F6, 'M', u'i'),
- (0x1D5F7, 'M', u'j'),
- (0x1D5F8, 'M', u'k'),
- (0x1D5F9, 'M', u'l'),
- (0x1D5FA, 'M', u'm'),
- (0x1D5FB, 'M', u'n'),
- (0x1D5FC, 'M', u'o'),
- (0x1D5FD, 'M', u'p'),
- (0x1D5FE, 'M', u'q'),
- (0x1D5FF, 'M', u'r'),
- (0x1D600, 'M', u's'),
- (0x1D601, 'M', u't'),
- (0x1D602, 'M', u'u'),
- (0x1D603, 'M', u'v'),
- (0x1D604, 'M', u'w'),
- (0x1D605, 'M', u'x'),
- (0x1D606, 'M', u'y'),
- (0x1D607, 'M', u'z'),
- (0x1D608, 'M', u'a'),
- (0x1D609, 'M', u'b'),
- (0x1D60A, 'M', u'c'),
- (0x1D60B, 'M', u'd'),
- (0x1D60C, 'M', u'e'),
- (0x1D60D, 'M', u'f'),
- (0x1D60E, 'M', u'g'),
- (0x1D60F, 'M', u'h'),
- (0x1D610, 'M', u'i'),
- (0x1D611, 'M', u'j'),
- (0x1D612, 'M', u'k'),
- (0x1D613, 'M', u'l'),
- (0x1D614, 'M', u'm'),
- (0x1D615, 'M', u'n'),
- (0x1D616, 'M', u'o'),
- (0x1D617, 'M', u'p'),
- (0x1D618, 'M', u'q'),
- (0x1D619, 'M', u'r'),
- (0x1D61A, 'M', u's'),
- (0x1D61B, 'M', u't'),
- (0x1D61C, 'M', u'u'),
- (0x1D61D, 'M', u'v'),
- (0x1D61E, 'M', u'w'),
- (0x1D61F, 'M', u'x'),
- (0x1D620, 'M', u'y'),
- (0x1D621, 'M', u'z'),
- (0x1D622, 'M', u'a'),
- (0x1D623, 'M', u'b'),
- (0x1D624, 'M', u'c'),
- (0x1D625, 'M', u'd'),
- (0x1D626, 'M', u'e'),
- (0x1D627, 'M', u'f'),
- (0x1D628, 'M', u'g'),
- (0x1D629, 'M', u'h'),
- (0x1D62A, 'M', u'i'),
- (0x1D62B, 'M', u'j'),
- (0x1D62C, 'M', u'k'),
- (0x1D62D, 'M', u'l'),
- (0x1D62E, 'M', u'm'),
- (0x1D62F, 'M', u'n'),
- (0x1D630, 'M', u'o'),
- (0x1D631, 'M', u'p'),
- (0x1D632, 'M', u'q'),
- (0x1D633, 'M', u'r'),
- (0x1D634, 'M', u's'),
- (0x1D635, 'M', u't'),
- (0x1D636, 'M', u'u'),
- ]
-
-def _seg_59():
- return [
- (0x1D637, 'M', u'v'),
- (0x1D638, 'M', u'w'),
- (0x1D639, 'M', u'x'),
- (0x1D63A, 'M', u'y'),
- (0x1D63B, 'M', u'z'),
- (0x1D63C, 'M', u'a'),
- (0x1D63D, 'M', u'b'),
- (0x1D63E, 'M', u'c'),
- (0x1D63F, 'M', u'd'),
- (0x1D640, 'M', u'e'),
- (0x1D641, 'M', u'f'),
- (0x1D642, 'M', u'g'),
- (0x1D643, 'M', u'h'),
- (0x1D644, 'M', u'i'),
- (0x1D645, 'M', u'j'),
- (0x1D646, 'M', u'k'),
- (0x1D647, 'M', u'l'),
- (0x1D648, 'M', u'm'),
- (0x1D649, 'M', u'n'),
- (0x1D64A, 'M', u'o'),
- (0x1D64B, 'M', u'p'),
- (0x1D64C, 'M', u'q'),
- (0x1D64D, 'M', u'r'),
- (0x1D64E, 'M', u's'),
- (0x1D64F, 'M', u't'),
- (0x1D650, 'M', u'u'),
- (0x1D651, 'M', u'v'),
- (0x1D652, 'M', u'w'),
- (0x1D653, 'M', u'x'),
- (0x1D654, 'M', u'y'),
- (0x1D655, 'M', u'z'),
- (0x1D656, 'M', u'a'),
- (0x1D657, 'M', u'b'),
- (0x1D658, 'M', u'c'),
- (0x1D659, 'M', u'd'),
- (0x1D65A, 'M', u'e'),
- (0x1D65B, 'M', u'f'),
- (0x1D65C, 'M', u'g'),
- (0x1D65D, 'M', u'h'),
- (0x1D65E, 'M', u'i'),
- (0x1D65F, 'M', u'j'),
- (0x1D660, 'M', u'k'),
- (0x1D661, 'M', u'l'),
- (0x1D662, 'M', u'm'),
- (0x1D663, 'M', u'n'),
- (0x1D664, 'M', u'o'),
- (0x1D665, 'M', u'p'),
- (0x1D666, 'M', u'q'),
- (0x1D667, 'M', u'r'),
- (0x1D668, 'M', u's'),
- (0x1D669, 'M', u't'),
- (0x1D66A, 'M', u'u'),
- (0x1D66B, 'M', u'v'),
- (0x1D66C, 'M', u'w'),
- (0x1D66D, 'M', u'x'),
- (0x1D66E, 'M', u'y'),
- (0x1D66F, 'M', u'z'),
- (0x1D670, 'M', u'a'),
- (0x1D671, 'M', u'b'),
- (0x1D672, 'M', u'c'),
- (0x1D673, 'M', u'd'),
- (0x1D674, 'M', u'e'),
- (0x1D675, 'M', u'f'),
- (0x1D676, 'M', u'g'),
- (0x1D677, 'M', u'h'),
- (0x1D678, 'M', u'i'),
- (0x1D679, 'M', u'j'),
- (0x1D67A, 'M', u'k'),
- (0x1D67B, 'M', u'l'),
- (0x1D67C, 'M', u'm'),
- (0x1D67D, 'M', u'n'),
- (0x1D67E, 'M', u'o'),
- (0x1D67F, 'M', u'p'),
- (0x1D680, 'M', u'q'),
- (0x1D681, 'M', u'r'),
- (0x1D682, 'M', u's'),
- (0x1D683, 'M', u't'),
- (0x1D684, 'M', u'u'),
- (0x1D685, 'M', u'v'),
- (0x1D686, 'M', u'w'),
- (0x1D687, 'M', u'x'),
- (0x1D688, 'M', u'y'),
- (0x1D689, 'M', u'z'),
- (0x1D68A, 'M', u'a'),
- (0x1D68B, 'M', u'b'),
- (0x1D68C, 'M', u'c'),
- (0x1D68D, 'M', u'd'),
- (0x1D68E, 'M', u'e'),
- (0x1D68F, 'M', u'f'),
- (0x1D690, 'M', u'g'),
- (0x1D691, 'M', u'h'),
- (0x1D692, 'M', u'i'),
- (0x1D693, 'M', u'j'),
- (0x1D694, 'M', u'k'),
- (0x1D695, 'M', u'l'),
- (0x1D696, 'M', u'm'),
- (0x1D697, 'M', u'n'),
- (0x1D698, 'M', u'o'),
- (0x1D699, 'M', u'p'),
- (0x1D69A, 'M', u'q'),
- ]
-
-def _seg_60():
- return [
- (0x1D69B, 'M', u'r'),
- (0x1D69C, 'M', u's'),
- (0x1D69D, 'M', u't'),
- (0x1D69E, 'M', u'u'),
- (0x1D69F, 'M', u'v'),
- (0x1D6A0, 'M', u'w'),
- (0x1D6A1, 'M', u'x'),
- (0x1D6A2, 'M', u'y'),
- (0x1D6A3, 'M', u'z'),
- (0x1D6A4, 'M', u'ı'),
- (0x1D6A5, 'M', u'È·'),
- (0x1D6A6, 'X'),
- (0x1D6A8, 'M', u'α'),
- (0x1D6A9, 'M', u'β'),
- (0x1D6AA, 'M', u'γ'),
- (0x1D6AB, 'M', u'δ'),
- (0x1D6AC, 'M', u'ε'),
- (0x1D6AD, 'M', u'ζ'),
- (0x1D6AE, 'M', u'η'),
- (0x1D6AF, 'M', u'θ'),
- (0x1D6B0, 'M', u'ι'),
- (0x1D6B1, 'M', u'κ'),
- (0x1D6B2, 'M', u'λ'),
- (0x1D6B3, 'M', u'μ'),
- (0x1D6B4, 'M', u'ν'),
- (0x1D6B5, 'M', u'ξ'),
- (0x1D6B6, 'M', u'ο'),
- (0x1D6B7, 'M', u'Ï€'),
- (0x1D6B8, 'M', u'Ï'),
- (0x1D6B9, 'M', u'θ'),
- (0x1D6BA, 'M', u'σ'),
- (0x1D6BB, 'M', u'Ï„'),
- (0x1D6BC, 'M', u'Ï…'),
- (0x1D6BD, 'M', u'φ'),
- (0x1D6BE, 'M', u'χ'),
- (0x1D6BF, 'M', u'ψ'),
- (0x1D6C0, 'M', u'ω'),
- (0x1D6C1, 'M', u'∇'),
- (0x1D6C2, 'M', u'α'),
- (0x1D6C3, 'M', u'β'),
- (0x1D6C4, 'M', u'γ'),
- (0x1D6C5, 'M', u'δ'),
- (0x1D6C6, 'M', u'ε'),
- (0x1D6C7, 'M', u'ζ'),
- (0x1D6C8, 'M', u'η'),
- (0x1D6C9, 'M', u'θ'),
- (0x1D6CA, 'M', u'ι'),
- (0x1D6CB, 'M', u'κ'),
- (0x1D6CC, 'M', u'λ'),
- (0x1D6CD, 'M', u'μ'),
- (0x1D6CE, 'M', u'ν'),
- (0x1D6CF, 'M', u'ξ'),
- (0x1D6D0, 'M', u'ο'),
- (0x1D6D1, 'M', u'Ï€'),
- (0x1D6D2, 'M', u'Ï'),
- (0x1D6D3, 'M', u'σ'),
- (0x1D6D5, 'M', u'Ï„'),
- (0x1D6D6, 'M', u'Ï…'),
- (0x1D6D7, 'M', u'φ'),
- (0x1D6D8, 'M', u'χ'),
- (0x1D6D9, 'M', u'ψ'),
- (0x1D6DA, 'M', u'ω'),
- (0x1D6DB, 'M', u'∂'),
- (0x1D6DC, 'M', u'ε'),
- (0x1D6DD, 'M', u'θ'),
- (0x1D6DE, 'M', u'κ'),
- (0x1D6DF, 'M', u'φ'),
- (0x1D6E0, 'M', u'Ï'),
- (0x1D6E1, 'M', u'Ï€'),
- (0x1D6E2, 'M', u'α'),
- (0x1D6E3, 'M', u'β'),
- (0x1D6E4, 'M', u'γ'),
- (0x1D6E5, 'M', u'δ'),
- (0x1D6E6, 'M', u'ε'),
- (0x1D6E7, 'M', u'ζ'),
- (0x1D6E8, 'M', u'η'),
- (0x1D6E9, 'M', u'θ'),
- (0x1D6EA, 'M', u'ι'),
- (0x1D6EB, 'M', u'κ'),
- (0x1D6EC, 'M', u'λ'),
- (0x1D6ED, 'M', u'μ'),
- (0x1D6EE, 'M', u'ν'),
- (0x1D6EF, 'M', u'ξ'),
- (0x1D6F0, 'M', u'ο'),
- (0x1D6F1, 'M', u'Ï€'),
- (0x1D6F2, 'M', u'Ï'),
- (0x1D6F3, 'M', u'θ'),
- (0x1D6F4, 'M', u'σ'),
- (0x1D6F5, 'M', u'Ï„'),
- (0x1D6F6, 'M', u'Ï…'),
- (0x1D6F7, 'M', u'φ'),
- (0x1D6F8, 'M', u'χ'),
- (0x1D6F9, 'M', u'ψ'),
- (0x1D6FA, 'M', u'ω'),
- (0x1D6FB, 'M', u'∇'),
- (0x1D6FC, 'M', u'α'),
- (0x1D6FD, 'M', u'β'),
- (0x1D6FE, 'M', u'γ'),
- (0x1D6FF, 'M', u'δ'),
- (0x1D700, 'M', u'ε'),
- ]
-
-def _seg_61():
- return [
- (0x1D701, 'M', u'ζ'),
- (0x1D702, 'M', u'η'),
- (0x1D703, 'M', u'θ'),
- (0x1D704, 'M', u'ι'),
- (0x1D705, 'M', u'κ'),
- (0x1D706, 'M', u'λ'),
- (0x1D707, 'M', u'μ'),
- (0x1D708, 'M', u'ν'),
- (0x1D709, 'M', u'ξ'),
- (0x1D70A, 'M', u'ο'),
- (0x1D70B, 'M', u'Ï€'),
- (0x1D70C, 'M', u'Ï'),
- (0x1D70D, 'M', u'σ'),
- (0x1D70F, 'M', u'Ï„'),
- (0x1D710, 'M', u'Ï…'),
- (0x1D711, 'M', u'φ'),
- (0x1D712, 'M', u'χ'),
- (0x1D713, 'M', u'ψ'),
- (0x1D714, 'M', u'ω'),
- (0x1D715, 'M', u'∂'),
- (0x1D716, 'M', u'ε'),
- (0x1D717, 'M', u'θ'),
- (0x1D718, 'M', u'κ'),
- (0x1D719, 'M', u'φ'),
- (0x1D71A, 'M', u'Ï'),
- (0x1D71B, 'M', u'Ï€'),
- (0x1D71C, 'M', u'α'),
- (0x1D71D, 'M', u'β'),
- (0x1D71E, 'M', u'γ'),
- (0x1D71F, 'M', u'δ'),
- (0x1D720, 'M', u'ε'),
- (0x1D721, 'M', u'ζ'),
- (0x1D722, 'M', u'η'),
- (0x1D723, 'M', u'θ'),
- (0x1D724, 'M', u'ι'),
- (0x1D725, 'M', u'κ'),
- (0x1D726, 'M', u'λ'),
- (0x1D727, 'M', u'μ'),
- (0x1D728, 'M', u'ν'),
- (0x1D729, 'M', u'ξ'),
- (0x1D72A, 'M', u'ο'),
- (0x1D72B, 'M', u'Ï€'),
- (0x1D72C, 'M', u'Ï'),
- (0x1D72D, 'M', u'θ'),
- (0x1D72E, 'M', u'σ'),
- (0x1D72F, 'M', u'Ï„'),
- (0x1D730, 'M', u'Ï…'),
- (0x1D731, 'M', u'φ'),
- (0x1D732, 'M', u'χ'),
- (0x1D733, 'M', u'ψ'),
- (0x1D734, 'M', u'ω'),
- (0x1D735, 'M', u'∇'),
- (0x1D736, 'M', u'α'),
- (0x1D737, 'M', u'β'),
- (0x1D738, 'M', u'γ'),
- (0x1D739, 'M', u'δ'),
- (0x1D73A, 'M', u'ε'),
- (0x1D73B, 'M', u'ζ'),
- (0x1D73C, 'M', u'η'),
- (0x1D73D, 'M', u'θ'),
- (0x1D73E, 'M', u'ι'),
- (0x1D73F, 'M', u'κ'),
- (0x1D740, 'M', u'λ'),
- (0x1D741, 'M', u'μ'),
- (0x1D742, 'M', u'ν'),
- (0x1D743, 'M', u'ξ'),
- (0x1D744, 'M', u'ο'),
- (0x1D745, 'M', u'Ï€'),
- (0x1D746, 'M', u'Ï'),
- (0x1D747, 'M', u'σ'),
- (0x1D749, 'M', u'Ï„'),
- (0x1D74A, 'M', u'Ï…'),
- (0x1D74B, 'M', u'φ'),
- (0x1D74C, 'M', u'χ'),
- (0x1D74D, 'M', u'ψ'),
- (0x1D74E, 'M', u'ω'),
- (0x1D74F, 'M', u'∂'),
- (0x1D750, 'M', u'ε'),
- (0x1D751, 'M', u'θ'),
- (0x1D752, 'M', u'κ'),
- (0x1D753, 'M', u'φ'),
- (0x1D754, 'M', u'Ï'),
- (0x1D755, 'M', u'Ï€'),
- (0x1D756, 'M', u'α'),
- (0x1D757, 'M', u'β'),
- (0x1D758, 'M', u'γ'),
- (0x1D759, 'M', u'δ'),
- (0x1D75A, 'M', u'ε'),
- (0x1D75B, 'M', u'ζ'),
- (0x1D75C, 'M', u'η'),
- (0x1D75D, 'M', u'θ'),
- (0x1D75E, 'M', u'ι'),
- (0x1D75F, 'M', u'κ'),
- (0x1D760, 'M', u'λ'),
- (0x1D761, 'M', u'μ'),
- (0x1D762, 'M', u'ν'),
- (0x1D763, 'M', u'ξ'),
- (0x1D764, 'M', u'ο'),
- (0x1D765, 'M', u'Ï€'),
- (0x1D766, 'M', u'Ï'),
- ]
-
-def _seg_62():
- return [
- (0x1D767, 'M', u'θ'),
- (0x1D768, 'M', u'σ'),
- (0x1D769, 'M', u'Ï„'),
- (0x1D76A, 'M', u'Ï…'),
- (0x1D76B, 'M', u'φ'),
- (0x1D76C, 'M', u'χ'),
- (0x1D76D, 'M', u'ψ'),
- (0x1D76E, 'M', u'ω'),
- (0x1D76F, 'M', u'∇'),
- (0x1D770, 'M', u'α'),
- (0x1D771, 'M', u'β'),
- (0x1D772, 'M', u'γ'),
- (0x1D773, 'M', u'δ'),
- (0x1D774, 'M', u'ε'),
- (0x1D775, 'M', u'ζ'),
- (0x1D776, 'M', u'η'),
- (0x1D777, 'M', u'θ'),
- (0x1D778, 'M', u'ι'),
- (0x1D779, 'M', u'κ'),
- (0x1D77A, 'M', u'λ'),
- (0x1D77B, 'M', u'μ'),
- (0x1D77C, 'M', u'ν'),
- (0x1D77D, 'M', u'ξ'),
- (0x1D77E, 'M', u'ο'),
- (0x1D77F, 'M', u'Ï€'),
- (0x1D780, 'M', u'Ï'),
- (0x1D781, 'M', u'σ'),
- (0x1D783, 'M', u'Ï„'),
- (0x1D784, 'M', u'Ï…'),
- (0x1D785, 'M', u'φ'),
- (0x1D786, 'M', u'χ'),
- (0x1D787, 'M', u'ψ'),
- (0x1D788, 'M', u'ω'),
- (0x1D789, 'M', u'∂'),
- (0x1D78A, 'M', u'ε'),
- (0x1D78B, 'M', u'θ'),
- (0x1D78C, 'M', u'κ'),
- (0x1D78D, 'M', u'φ'),
- (0x1D78E, 'M', u'Ï'),
- (0x1D78F, 'M', u'Ï€'),
- (0x1D790, 'M', u'α'),
- (0x1D791, 'M', u'β'),
- (0x1D792, 'M', u'γ'),
- (0x1D793, 'M', u'δ'),
- (0x1D794, 'M', u'ε'),
- (0x1D795, 'M', u'ζ'),
- (0x1D796, 'M', u'η'),
- (0x1D797, 'M', u'θ'),
- (0x1D798, 'M', u'ι'),
- (0x1D799, 'M', u'κ'),
- (0x1D79A, 'M', u'λ'),
- (0x1D79B, 'M', u'μ'),
- (0x1D79C, 'M', u'ν'),
- (0x1D79D, 'M', u'ξ'),
- (0x1D79E, 'M', u'ο'),
- (0x1D79F, 'M', u'Ï€'),
- (0x1D7A0, 'M', u'Ï'),
- (0x1D7A1, 'M', u'θ'),
- (0x1D7A2, 'M', u'σ'),
- (0x1D7A3, 'M', u'Ï„'),
- (0x1D7A4, 'M', u'Ï…'),
- (0x1D7A5, 'M', u'φ'),
- (0x1D7A6, 'M', u'χ'),
- (0x1D7A7, 'M', u'ψ'),
- (0x1D7A8, 'M', u'ω'),
- (0x1D7A9, 'M', u'∇'),
- (0x1D7AA, 'M', u'α'),
- (0x1D7AB, 'M', u'β'),
- (0x1D7AC, 'M', u'γ'),
- (0x1D7AD, 'M', u'δ'),
- (0x1D7AE, 'M', u'ε'),
- (0x1D7AF, 'M', u'ζ'),
- (0x1D7B0, 'M', u'η'),
- (0x1D7B1, 'M', u'θ'),
- (0x1D7B2, 'M', u'ι'),
- (0x1D7B3, 'M', u'κ'),
- (0x1D7B4, 'M', u'λ'),
- (0x1D7B5, 'M', u'μ'),
- (0x1D7B6, 'M', u'ν'),
- (0x1D7B7, 'M', u'ξ'),
- (0x1D7B8, 'M', u'ο'),
- (0x1D7B9, 'M', u'Ï€'),
- (0x1D7BA, 'M', u'Ï'),
- (0x1D7BB, 'M', u'σ'),
- (0x1D7BD, 'M', u'Ï„'),
- (0x1D7BE, 'M', u'Ï…'),
- (0x1D7BF, 'M', u'φ'),
- (0x1D7C0, 'M', u'χ'),
- (0x1D7C1, 'M', u'ψ'),
- (0x1D7C2, 'M', u'ω'),
- (0x1D7C3, 'M', u'∂'),
- (0x1D7C4, 'M', u'ε'),
- (0x1D7C5, 'M', u'θ'),
- (0x1D7C6, 'M', u'κ'),
- (0x1D7C7, 'M', u'φ'),
- (0x1D7C8, 'M', u'Ï'),
- (0x1D7C9, 'M', u'Ï€'),
- (0x1D7CA, 'M', u'Ï'),
- (0x1D7CC, 'X'),
- (0x1D7CE, 'M', u'0'),
- ]
-
-def _seg_63():
- return [
- (0x1D7CF, 'M', u'1'),
- (0x1D7D0, 'M', u'2'),
- (0x1D7D1, 'M', u'3'),
- (0x1D7D2, 'M', u'4'),
- (0x1D7D3, 'M', u'5'),
- (0x1D7D4, 'M', u'6'),
- (0x1D7D5, 'M', u'7'),
- (0x1D7D6, 'M', u'8'),
- (0x1D7D7, 'M', u'9'),
- (0x1D7D8, 'M', u'0'),
- (0x1D7D9, 'M', u'1'),
- (0x1D7DA, 'M', u'2'),
- (0x1D7DB, 'M', u'3'),
- (0x1D7DC, 'M', u'4'),
- (0x1D7DD, 'M', u'5'),
- (0x1D7DE, 'M', u'6'),
- (0x1D7DF, 'M', u'7'),
- (0x1D7E0, 'M', u'8'),
- (0x1D7E1, 'M', u'9'),
- (0x1D7E2, 'M', u'0'),
- (0x1D7E3, 'M', u'1'),
- (0x1D7E4, 'M', u'2'),
- (0x1D7E5, 'M', u'3'),
- (0x1D7E6, 'M', u'4'),
- (0x1D7E7, 'M', u'5'),
- (0x1D7E8, 'M', u'6'),
- (0x1D7E9, 'M', u'7'),
- (0x1D7EA, 'M', u'8'),
- (0x1D7EB, 'M', u'9'),
- (0x1D7EC, 'M', u'0'),
- (0x1D7ED, 'M', u'1'),
- (0x1D7EE, 'M', u'2'),
- (0x1D7EF, 'M', u'3'),
- (0x1D7F0, 'M', u'4'),
- (0x1D7F1, 'M', u'5'),
- (0x1D7F2, 'M', u'6'),
- (0x1D7F3, 'M', u'7'),
- (0x1D7F4, 'M', u'8'),
- (0x1D7F5, 'M', u'9'),
- (0x1D7F6, 'M', u'0'),
- (0x1D7F7, 'M', u'1'),
- (0x1D7F8, 'M', u'2'),
- (0x1D7F9, 'M', u'3'),
- (0x1D7FA, 'M', u'4'),
- (0x1D7FB, 'M', u'5'),
- (0x1D7FC, 'M', u'6'),
- (0x1D7FD, 'M', u'7'),
- (0x1D7FE, 'M', u'8'),
- (0x1D7FF, 'M', u'9'),
- (0x1D800, 'X'),
- (0x1EE00, 'M', u'ا'),
- (0x1EE01, 'M', u'ب'),
- (0x1EE02, 'M', u'ج'),
- (0x1EE03, 'M', u'د'),
- (0x1EE04, 'X'),
- (0x1EE05, 'M', u'Ùˆ'),
- (0x1EE06, 'M', u'ز'),
- (0x1EE07, 'M', u'Ø­'),
- (0x1EE08, 'M', u'Ø·'),
- (0x1EE09, 'M', u'ÙŠ'),
- (0x1EE0A, 'M', u'Ùƒ'),
- (0x1EE0B, 'M', u'Ù„'),
- (0x1EE0C, 'M', u'Ù…'),
- (0x1EE0D, 'M', u'Ù†'),
- (0x1EE0E, 'M', u'س'),
- (0x1EE0F, 'M', u'ع'),
- (0x1EE10, 'M', u'Ù'),
- (0x1EE11, 'M', u'ص'),
- (0x1EE12, 'M', u'Ù‚'),
- (0x1EE13, 'M', u'ر'),
- (0x1EE14, 'M', u'Ø´'),
- (0x1EE15, 'M', u'ت'),
- (0x1EE16, 'M', u'Ø«'),
- (0x1EE17, 'M', u'Ø®'),
- (0x1EE18, 'M', u'Ø°'),
- (0x1EE19, 'M', u'ض'),
- (0x1EE1A, 'M', u'ظ'),
- (0x1EE1B, 'M', u'غ'),
- (0x1EE1C, 'M', u'Ù®'),
- (0x1EE1D, 'M', u'Úº'),
- (0x1EE1E, 'M', u'Ú¡'),
- (0x1EE1F, 'M', u'Ù¯'),
- (0x1EE20, 'X'),
- (0x1EE21, 'M', u'ب'),
- (0x1EE22, 'M', u'ج'),
- (0x1EE23, 'X'),
- (0x1EE24, 'M', u'Ù‡'),
- (0x1EE25, 'X'),
- (0x1EE27, 'M', u'Ø­'),
- (0x1EE28, 'X'),
- (0x1EE29, 'M', u'ÙŠ'),
- (0x1EE2A, 'M', u'Ùƒ'),
- (0x1EE2B, 'M', u'Ù„'),
- (0x1EE2C, 'M', u'Ù…'),
- (0x1EE2D, 'M', u'Ù†'),
- (0x1EE2E, 'M', u'س'),
- (0x1EE2F, 'M', u'ع'),
- (0x1EE30, 'M', u'Ù'),
- (0x1EE31, 'M', u'ص'),
- (0x1EE32, 'M', u'Ù‚'),
- ]
-
-def _seg_64():
- return [
- (0x1EE33, 'X'),
- (0x1EE34, 'M', u'Ø´'),
- (0x1EE35, 'M', u'ت'),
- (0x1EE36, 'M', u'Ø«'),
- (0x1EE37, 'M', u'Ø®'),
- (0x1EE38, 'X'),
- (0x1EE39, 'M', u'ض'),
- (0x1EE3A, 'X'),
- (0x1EE3B, 'M', u'غ'),
- (0x1EE3C, 'X'),
- (0x1EE42, 'M', u'ج'),
- (0x1EE43, 'X'),
- (0x1EE47, 'M', u'Ø­'),
- (0x1EE48, 'X'),
- (0x1EE49, 'M', u'ÙŠ'),
- (0x1EE4A, 'X'),
- (0x1EE4B, 'M', u'Ù„'),
- (0x1EE4C, 'X'),
- (0x1EE4D, 'M', u'Ù†'),
- (0x1EE4E, 'M', u'س'),
- (0x1EE4F, 'M', u'ع'),
- (0x1EE50, 'X'),
- (0x1EE51, 'M', u'ص'),
- (0x1EE52, 'M', u'Ù‚'),
- (0x1EE53, 'X'),
- (0x1EE54, 'M', u'Ø´'),
- (0x1EE55, 'X'),
- (0x1EE57, 'M', u'Ø®'),
- (0x1EE58, 'X'),
- (0x1EE59, 'M', u'ض'),
- (0x1EE5A, 'X'),
- (0x1EE5B, 'M', u'غ'),
- (0x1EE5C, 'X'),
- (0x1EE5D, 'M', u'Úº'),
- (0x1EE5E, 'X'),
- (0x1EE5F, 'M', u'Ù¯'),
- (0x1EE60, 'X'),
- (0x1EE61, 'M', u'ب'),
- (0x1EE62, 'M', u'ج'),
- (0x1EE63, 'X'),
- (0x1EE64, 'M', u'Ù‡'),
- (0x1EE65, 'X'),
- (0x1EE67, 'M', u'Ø­'),
- (0x1EE68, 'M', u'Ø·'),
- (0x1EE69, 'M', u'ÙŠ'),
- (0x1EE6A, 'M', u'Ùƒ'),
- (0x1EE6B, 'X'),
- (0x1EE6C, 'M', u'Ù…'),
- (0x1EE6D, 'M', u'Ù†'),
- (0x1EE6E, 'M', u'س'),
- (0x1EE6F, 'M', u'ع'),
- (0x1EE70, 'M', u'Ù'),
- (0x1EE71, 'M', u'ص'),
- (0x1EE72, 'M', u'Ù‚'),
- (0x1EE73, 'X'),
- (0x1EE74, 'M', u'Ø´'),
- (0x1EE75, 'M', u'ت'),
- (0x1EE76, 'M', u'Ø«'),
- (0x1EE77, 'M', u'Ø®'),
- (0x1EE78, 'X'),
- (0x1EE79, 'M', u'ض'),
- (0x1EE7A, 'M', u'ظ'),
- (0x1EE7B, 'M', u'غ'),
- (0x1EE7C, 'M', u'Ù®'),
- (0x1EE7D, 'X'),
- (0x1EE7E, 'M', u'Ú¡'),
- (0x1EE7F, 'X'),
- (0x1EE80, 'M', u'ا'),
- (0x1EE81, 'M', u'ب'),
- (0x1EE82, 'M', u'ج'),
- (0x1EE83, 'M', u'د'),
- (0x1EE84, 'M', u'Ù‡'),
- (0x1EE85, 'M', u'Ùˆ'),
- (0x1EE86, 'M', u'ز'),
- (0x1EE87, 'M', u'Ø­'),
- (0x1EE88, 'M', u'Ø·'),
- (0x1EE89, 'M', u'ÙŠ'),
- (0x1EE8A, 'X'),
- (0x1EE8B, 'M', u'Ù„'),
- (0x1EE8C, 'M', u'Ù…'),
- (0x1EE8D, 'M', u'Ù†'),
- (0x1EE8E, 'M', u'س'),
- (0x1EE8F, 'M', u'ع'),
- (0x1EE90, 'M', u'Ù'),
- (0x1EE91, 'M', u'ص'),
- (0x1EE92, 'M', u'Ù‚'),
- (0x1EE93, 'M', u'ر'),
- (0x1EE94, 'M', u'Ø´'),
- (0x1EE95, 'M', u'ت'),
- (0x1EE96, 'M', u'Ø«'),
- (0x1EE97, 'M', u'Ø®'),
- (0x1EE98, 'M', u'Ø°'),
- (0x1EE99, 'M', u'ض'),
- (0x1EE9A, 'M', u'ظ'),
- (0x1EE9B, 'M', u'غ'),
- (0x1EE9C, 'X'),
- (0x1EEA1, 'M', u'ب'),
- (0x1EEA2, 'M', u'ج'),
- (0x1EEA3, 'M', u'د'),
- (0x1EEA4, 'X'),
- ]
-
-def _seg_65():
- return [
- (0x1EEA5, 'M', u'Ùˆ'),
- (0x1EEA6, 'M', u'ز'),
- (0x1EEA7, 'M', u'Ø­'),
- (0x1EEA8, 'M', u'Ø·'),
- (0x1EEA9, 'M', u'ÙŠ'),
- (0x1EEAA, 'X'),
- (0x1EEAB, 'M', u'Ù„'),
- (0x1EEAC, 'M', u'Ù…'),
- (0x1EEAD, 'M', u'Ù†'),
- (0x1EEAE, 'M', u'س'),
- (0x1EEAF, 'M', u'ع'),
- (0x1EEB0, 'M', u'Ù'),
- (0x1EEB1, 'M', u'ص'),
- (0x1EEB2, 'M', u'Ù‚'),
- (0x1EEB3, 'M', u'ر'),
- (0x1EEB4, 'M', u'Ø´'),
- (0x1EEB5, 'M', u'ت'),
- (0x1EEB6, 'M', u'Ø«'),
- (0x1EEB7, 'M', u'Ø®'),
- (0x1EEB8, 'M', u'Ø°'),
- (0x1EEB9, 'M', u'ض'),
- (0x1EEBA, 'M', u'ظ'),
- (0x1EEBB, 'M', u'غ'),
- (0x1EEBC, 'X'),
- (0x1EEF0, 'V'),
- (0x1EEF2, 'X'),
- (0x1F000, 'V'),
- (0x1F02C, 'X'),
- (0x1F030, 'V'),
- (0x1F094, 'X'),
- (0x1F0A0, 'V'),
- (0x1F0AF, 'X'),
- (0x1F0B1, 'V'),
- (0x1F0BF, 'X'),
- (0x1F0C1, 'V'),
- (0x1F0D0, 'X'),
- (0x1F0D1, 'V'),
- (0x1F0E0, 'X'),
- (0x1F101, '3', u'0,'),
- (0x1F102, '3', u'1,'),
- (0x1F103, '3', u'2,'),
- (0x1F104, '3', u'3,'),
- (0x1F105, '3', u'4,'),
- (0x1F106, '3', u'5,'),
- (0x1F107, '3', u'6,'),
- (0x1F108, '3', u'7,'),
- (0x1F109, '3', u'8,'),
- (0x1F10A, '3', u'9,'),
- (0x1F10B, 'X'),
- (0x1F110, '3', u'(a)'),
- (0x1F111, '3', u'(b)'),
- (0x1F112, '3', u'(c)'),
- (0x1F113, '3', u'(d)'),
- (0x1F114, '3', u'(e)'),
- (0x1F115, '3', u'(f)'),
- (0x1F116, '3', u'(g)'),
- (0x1F117, '3', u'(h)'),
- (0x1F118, '3', u'(i)'),
- (0x1F119, '3', u'(j)'),
- (0x1F11A, '3', u'(k)'),
- (0x1F11B, '3', u'(l)'),
- (0x1F11C, '3', u'(m)'),
- (0x1F11D, '3', u'(n)'),
- (0x1F11E, '3', u'(o)'),
- (0x1F11F, '3', u'(p)'),
- (0x1F120, '3', u'(q)'),
- (0x1F121, '3', u'(r)'),
- (0x1F122, '3', u'(s)'),
- (0x1F123, '3', u'(t)'),
- (0x1F124, '3', u'(u)'),
- (0x1F125, '3', u'(v)'),
- (0x1F126, '3', u'(w)'),
- (0x1F127, '3', u'(x)'),
- (0x1F128, '3', u'(y)'),
- (0x1F129, '3', u'(z)'),
- (0x1F12A, 'M', u'〔s〕'),
- (0x1F12B, 'M', u'c'),
- (0x1F12C, 'M', u'r'),
- (0x1F12D, 'M', u'cd'),
- (0x1F12E, 'M', u'wz'),
- (0x1F12F, 'X'),
- (0x1F130, 'M', u'a'),
- (0x1F131, 'M', u'b'),
- (0x1F132, 'M', u'c'),
- (0x1F133, 'M', u'd'),
- (0x1F134, 'M', u'e'),
- (0x1F135, 'M', u'f'),
- (0x1F136, 'M', u'g'),
- (0x1F137, 'M', u'h'),
- (0x1F138, 'M', u'i'),
- (0x1F139, 'M', u'j'),
- (0x1F13A, 'M', u'k'),
- (0x1F13B, 'M', u'l'),
- (0x1F13C, 'M', u'm'),
- (0x1F13D, 'M', u'n'),
- (0x1F13E, 'M', u'o'),
- (0x1F13F, 'M', u'p'),
- (0x1F140, 'M', u'q'),
- (0x1F141, 'M', u'r'),
- (0x1F142, 'M', u's'),
- ]
-
-def _seg_66():
- return [
- (0x1F143, 'M', u't'),
- (0x1F144, 'M', u'u'),
- (0x1F145, 'M', u'v'),
- (0x1F146, 'M', u'w'),
- (0x1F147, 'M', u'x'),
- (0x1F148, 'M', u'y'),
- (0x1F149, 'M', u'z'),
- (0x1F14A, 'M', u'hv'),
- (0x1F14B, 'M', u'mv'),
- (0x1F14C, 'M', u'sd'),
- (0x1F14D, 'M', u'ss'),
- (0x1F14E, 'M', u'ppv'),
- (0x1F14F, 'M', u'wc'),
- (0x1F150, 'V'),
- (0x1F16A, 'M', u'mc'),
- (0x1F16B, 'M', u'md'),
- (0x1F16C, 'X'),
- (0x1F170, 'V'),
- (0x1F190, 'M', u'dj'),
- (0x1F191, 'V'),
- (0x1F19B, 'X'),
- (0x1F1E6, 'V'),
- (0x1F200, 'M', u'ã»ã‹'),
- (0x1F201, 'M', u'ココ'),
- (0x1F202, 'M', u'サ'),
- (0x1F203, 'X'),
- (0x1F210, 'M', u'手'),
- (0x1F211, 'M', u'å­—'),
- (0x1F212, 'M', u'åŒ'),
- (0x1F213, 'M', u'デ'),
- (0x1F214, 'M', u'二'),
- (0x1F215, 'M', u'多'),
- (0x1F216, 'M', u'解'),
- (0x1F217, 'M', u'天'),
- (0x1F218, 'M', u'交'),
- (0x1F219, 'M', u'映'),
- (0x1F21A, 'M', u'ç„¡'),
- (0x1F21B, 'M', u'æ–™'),
- (0x1F21C, 'M', u'å‰'),
- (0x1F21D, 'M', u'後'),
- (0x1F21E, 'M', u'å†'),
- (0x1F21F, 'M', u'æ–°'),
- (0x1F220, 'M', u'åˆ'),
- (0x1F221, 'M', u'終'),
- (0x1F222, 'M', u'生'),
- (0x1F223, 'M', u'販'),
- (0x1F224, 'M', u'声'),
- (0x1F225, 'M', u'å¹'),
- (0x1F226, 'M', u'æ¼”'),
- (0x1F227, 'M', u'投'),
- (0x1F228, 'M', u'æ•'),
- (0x1F229, 'M', u'一'),
- (0x1F22A, 'M', u'三'),
- (0x1F22B, 'M', u'éŠ'),
- (0x1F22C, 'M', u'å·¦'),
- (0x1F22D, 'M', u'中'),
- (0x1F22E, 'M', u'å³'),
- (0x1F22F, 'M', u'指'),
- (0x1F230, 'M', u'èµ°'),
- (0x1F231, 'M', u'打'),
- (0x1F232, 'M', u'ç¦'),
- (0x1F233, 'M', u'空'),
- (0x1F234, 'M', u'åˆ'),
- (0x1F235, 'M', u'満'),
- (0x1F236, 'M', u'有'),
- (0x1F237, 'M', u'月'),
- (0x1F238, 'M', u'申'),
- (0x1F239, 'M', u'割'),
- (0x1F23A, 'M', u'å–¶'),
- (0x1F23B, 'X'),
- (0x1F240, 'M', u'〔本〕'),
- (0x1F241, 'M', u'〔三〕'),
- (0x1F242, 'M', u'〔二〕'),
- (0x1F243, 'M', u'〔安〕'),
- (0x1F244, 'M', u'〔点〕'),
- (0x1F245, 'M', u'〔打〕'),
- (0x1F246, 'M', u'〔盗〕'),
- (0x1F247, 'M', u'〔å‹ã€•'),
- (0x1F248, 'M', u'〔敗〕'),
- (0x1F249, 'X'),
- (0x1F250, 'M', u'å¾—'),
- (0x1F251, 'M', u'å¯'),
- (0x1F252, 'X'),
- (0x1F300, 'V'),
- (0x1F321, 'X'),
- (0x1F330, 'V'),
- (0x1F336, 'X'),
- (0x1F337, 'V'),
- (0x1F37D, 'X'),
- (0x1F380, 'V'),
- (0x1F394, 'X'),
- (0x1F3A0, 'V'),
- (0x1F3C5, 'X'),
- (0x1F3C6, 'V'),
- (0x1F3CB, 'X'),
- (0x1F3E0, 'V'),
- (0x1F3F1, 'X'),
- (0x1F400, 'V'),
- (0x1F43F, 'X'),
- (0x1F440, 'V'),
- ]
-
-def _seg_67():
- return [
- (0x1F441, 'X'),
- (0x1F442, 'V'),
- (0x1F4F8, 'X'),
- (0x1F4F9, 'V'),
- (0x1F4FD, 'X'),
- (0x1F500, 'V'),
- (0x1F53E, 'X'),
- (0x1F540, 'V'),
- (0x1F544, 'X'),
- (0x1F550, 'V'),
- (0x1F568, 'X'),
- (0x1F5FB, 'V'),
- (0x1F641, 'X'),
- (0x1F645, 'V'),
- (0x1F650, 'X'),
- (0x1F680, 'V'),
- (0x1F6C6, 'X'),
- (0x1F700, 'V'),
- (0x1F774, 'X'),
- (0x20000, 'V'),
- (0x2A6D7, 'X'),
- (0x2A700, 'V'),
- (0x2B735, 'X'),
- (0x2B740, 'V'),
- (0x2B81E, 'X'),
- (0x2F800, 'M', u'丽'),
- (0x2F801, 'M', u'丸'),
- (0x2F802, 'M', u'ä¹'),
- (0x2F803, 'M', u'ð „¢'),
- (0x2F804, 'M', u'ä½ '),
- (0x2F805, 'M', u'ä¾®'),
- (0x2F806, 'M', u'ä¾»'),
- (0x2F807, 'M', u'倂'),
- (0x2F808, 'M', u'åº'),
- (0x2F809, 'M', u'å‚™'),
- (0x2F80A, 'M', u'僧'),
- (0x2F80B, 'M', u'åƒ'),
- (0x2F80C, 'M', u'ã’ž'),
- (0x2F80D, 'M', u'𠘺'),
- (0x2F80E, 'M', u'å…'),
- (0x2F80F, 'M', u'å…”'),
- (0x2F810, 'M', u'å…¤'),
- (0x2F811, 'M', u'å…·'),
- (0x2F812, 'M', u'𠔜'),
- (0x2F813, 'M', u'ã’¹'),
- (0x2F814, 'M', u'å…§'),
- (0x2F815, 'M', u'å†'),
- (0x2F816, 'M', u'ð •‹'),
- (0x2F817, 'M', u'冗'),
- (0x2F818, 'M', u'冤'),
- (0x2F819, 'M', u'仌'),
- (0x2F81A, 'M', u'冬'),
- (0x2F81B, 'M', u'况'),
- (0x2F81C, 'M', u'𩇟'),
- (0x2F81D, 'M', u'凵'),
- (0x2F81E, 'M', u'刃'),
- (0x2F81F, 'M', u'ã“Ÿ'),
- (0x2F820, 'M', u'刻'),
- (0x2F821, 'M', u'剆'),
- (0x2F822, 'M', u'割'),
- (0x2F823, 'M', u'剷'),
- (0x2F824, 'M', u'㔕'),
- (0x2F825, 'M', u'勇'),
- (0x2F826, 'M', u'勉'),
- (0x2F827, 'M', u'勤'),
- (0x2F828, 'M', u'勺'),
- (0x2F829, 'M', u'包'),
- (0x2F82A, 'M', u'匆'),
- (0x2F82B, 'M', u'北'),
- (0x2F82C, 'M', u'å‰'),
- (0x2F82D, 'M', u'å‘'),
- (0x2F82E, 'M', u'åš'),
- (0x2F82F, 'M', u'å³'),
- (0x2F830, 'M', u'å½'),
- (0x2F831, 'M', u'å¿'),
- (0x2F834, 'M', u'𠨬'),
- (0x2F835, 'M', u'ç°'),
- (0x2F836, 'M', u'åŠ'),
- (0x2F837, 'M', u'åŸ'),
- (0x2F838, 'M', u'ð ­£'),
- (0x2F839, 'M', u'å«'),
- (0x2F83A, 'M', u'å±'),
- (0x2F83B, 'M', u'å†'),
- (0x2F83C, 'M', u'å’ž'),
- (0x2F83D, 'M', u'å¸'),
- (0x2F83E, 'M', u'呈'),
- (0x2F83F, 'M', u'周'),
- (0x2F840, 'M', u'å’¢'),
- (0x2F841, 'M', u'哶'),
- (0x2F842, 'M', u'å”'),
- (0x2F843, 'M', u'å•“'),
- (0x2F844, 'M', u'å•£'),
- (0x2F845, 'M', u'å–„'),
- (0x2F847, 'M', u'å–™'),
- (0x2F848, 'M', u'å–«'),
- (0x2F849, 'M', u'å–³'),
- (0x2F84A, 'M', u'å—‚'),
- (0x2F84B, 'M', u'圖'),
- (0x2F84C, 'M', u'嘆'),
- (0x2F84D, 'M', u'圗'),
- ]
-
-def _seg_68():
- return [
- (0x2F84E, 'M', u'噑'),
- (0x2F84F, 'M', u'å™´'),
- (0x2F850, 'M', u'切'),
- (0x2F851, 'M', u'壮'),
- (0x2F852, 'M', u'城'),
- (0x2F853, 'M', u'埴'),
- (0x2F854, 'M', u'å '),
- (0x2F855, 'M', u'åž‹'),
- (0x2F856, 'M', u'å ²'),
- (0x2F857, 'M', u'å ±'),
- (0x2F858, 'M', u'墬'),
- (0x2F859, 'M', u'𡓤'),
- (0x2F85A, 'M', u'売'),
- (0x2F85B, 'M', u'壷'),
- (0x2F85C, 'M', u'夆'),
- (0x2F85D, 'M', u'多'),
- (0x2F85E, 'M', u'夢'),
- (0x2F85F, 'M', u'奢'),
- (0x2F860, 'M', u'𡚨'),
- (0x2F861, 'M', u'𡛪'),
- (0x2F862, 'M', u'姬'),
- (0x2F863, 'M', u'娛'),
- (0x2F864, 'M', u'娧'),
- (0x2F865, 'M', u'姘'),
- (0x2F866, 'M', u'婦'),
- (0x2F867, 'M', u'ã›®'),
- (0x2F868, 'X'),
- (0x2F869, 'M', u'嬈'),
- (0x2F86A, 'M', u'嬾'),
- (0x2F86C, 'M', u'𡧈'),
- (0x2F86D, 'M', u'寃'),
- (0x2F86E, 'M', u'寘'),
- (0x2F86F, 'M', u'寧'),
- (0x2F870, 'M', u'寳'),
- (0x2F871, 'M', u'𡬘'),
- (0x2F872, 'M', u'寿'),
- (0x2F873, 'M', u'å°†'),
- (0x2F874, 'X'),
- (0x2F875, 'M', u'å°¢'),
- (0x2F876, 'M', u'ãž'),
- (0x2F877, 'M', u'å± '),
- (0x2F878, 'M', u'å±®'),
- (0x2F879, 'M', u'å³€'),
- (0x2F87A, 'M', u'å²'),
- (0x2F87B, 'M', u'ð¡·¤'),
- (0x2F87C, 'M', u'嵃'),
- (0x2F87D, 'M', u'ð¡·¦'),
- (0x2F87E, 'M', u'åµ®'),
- (0x2F87F, 'M', u'嵫'),
- (0x2F880, 'M', u'åµ¼'),
- (0x2F881, 'M', u'å·¡'),
- (0x2F882, 'M', u'å·¢'),
- (0x2F883, 'M', u'ã ¯'),
- (0x2F884, 'M', u'å·½'),
- (0x2F885, 'M', u'帨'),
- (0x2F886, 'M', u'帽'),
- (0x2F887, 'M', u'幩'),
- (0x2F888, 'M', u'ã¡¢'),
- (0x2F889, 'M', u'𢆃'),
- (0x2F88A, 'M', u'㡼'),
- (0x2F88B, 'M', u'庰'),
- (0x2F88C, 'M', u'庳'),
- (0x2F88D, 'M', u'庶'),
- (0x2F88E, 'M', u'廊'),
- (0x2F88F, 'M', u'𪎒'),
- (0x2F890, 'M', u'廾'),
- (0x2F891, 'M', u'𢌱'),
- (0x2F893, 'M', u'èˆ'),
- (0x2F894, 'M', u'å¼¢'),
- (0x2F896, 'M', u'㣇'),
- (0x2F897, 'M', u'𣊸'),
- (0x2F898, 'M', u'𦇚'),
- (0x2F899, 'M', u'å½¢'),
- (0x2F89A, 'M', u'彫'),
- (0x2F89B, 'M', u'㣣'),
- (0x2F89C, 'M', u'徚'),
- (0x2F89D, 'M', u'å¿'),
- (0x2F89E, 'M', u'å¿—'),
- (0x2F89F, 'M', u'忹'),
- (0x2F8A0, 'M', u'æ‚'),
- (0x2F8A1, 'M', u'㤺'),
- (0x2F8A2, 'M', u'㤜'),
- (0x2F8A3, 'M', u'æ‚”'),
- (0x2F8A4, 'M', u'𢛔'),
- (0x2F8A5, 'M', u'惇'),
- (0x2F8A6, 'M', u'æ…ˆ'),
- (0x2F8A7, 'M', u'慌'),
- (0x2F8A8, 'M', u'æ…Ž'),
- (0x2F8A9, 'M', u'慌'),
- (0x2F8AA, 'M', u'æ…º'),
- (0x2F8AB, 'M', u'憎'),
- (0x2F8AC, 'M', u'憲'),
- (0x2F8AD, 'M', u'憤'),
- (0x2F8AE, 'M', u'憯'),
- (0x2F8AF, 'M', u'懞'),
- (0x2F8B0, 'M', u'懲'),
- (0x2F8B1, 'M', u'懶'),
- (0x2F8B2, 'M', u'æˆ'),
- (0x2F8B3, 'M', u'戛'),
- (0x2F8B4, 'M', u'æ‰'),
- ]
-
-def _seg_69():
- return [
- (0x2F8B5, 'M', u'抱'),
- (0x2F8B6, 'M', u'æ‹”'),
- (0x2F8B7, 'M', u'æ'),
- (0x2F8B8, 'M', u'𢬌'),
- (0x2F8B9, 'M', u'挽'),
- (0x2F8BA, 'M', u'拼'),
- (0x2F8BB, 'M', u'æ¨'),
- (0x2F8BC, 'M', u'掃'),
- (0x2F8BD, 'M', u'æ¤'),
- (0x2F8BE, 'M', u'𢯱'),
- (0x2F8BF, 'M', u'æ¢'),
- (0x2F8C0, 'M', u'æ…'),
- (0x2F8C1, 'M', u'掩'),
- (0x2F8C2, 'M', u'㨮'),
- (0x2F8C3, 'M', u'æ‘©'),
- (0x2F8C4, 'M', u'摾'),
- (0x2F8C5, 'M', u'æ’'),
- (0x2F8C6, 'M', u'æ‘·'),
- (0x2F8C7, 'M', u'㩬'),
- (0x2F8C8, 'M', u'æ•'),
- (0x2F8C9, 'M', u'敬'),
- (0x2F8CA, 'M', u'𣀊'),
- (0x2F8CB, 'M', u'æ—£'),
- (0x2F8CC, 'M', u'書'),
- (0x2F8CD, 'M', u'晉'),
- (0x2F8CE, 'M', u'㬙'),
- (0x2F8CF, 'M', u'æš‘'),
- (0x2F8D0, 'M', u'㬈'),
- (0x2F8D1, 'M', u'㫤'),
- (0x2F8D2, 'M', u'冒'),
- (0x2F8D3, 'M', u'冕'),
- (0x2F8D4, 'M', u'最'),
- (0x2F8D5, 'M', u'暜'),
- (0x2F8D6, 'M', u'è‚­'),
- (0x2F8D7, 'M', u'ä™'),
- (0x2F8D8, 'M', u'朗'),
- (0x2F8D9, 'M', u'望'),
- (0x2F8DA, 'M', u'朡'),
- (0x2F8DB, 'M', u'æž'),
- (0x2F8DC, 'M', u'æ“'),
- (0x2F8DD, 'M', u'ð£ƒ'),
- (0x2F8DE, 'M', u'ã­‰'),
- (0x2F8DF, 'M', u'柺'),
- (0x2F8E0, 'M', u'æž…'),
- (0x2F8E1, 'M', u'æ¡’'),
- (0x2F8E2, 'M', u'梅'),
- (0x2F8E3, 'M', u'𣑭'),
- (0x2F8E4, 'M', u'梎'),
- (0x2F8E5, 'M', u'æ Ÿ'),
- (0x2F8E6, 'M', u'椔'),
- (0x2F8E7, 'M', u'ã®'),
- (0x2F8E8, 'M', u'楂'),
- (0x2F8E9, 'M', u'榣'),
- (0x2F8EA, 'M', u'槪'),
- (0x2F8EB, 'M', u'檨'),
- (0x2F8EC, 'M', u'𣚣'),
- (0x2F8ED, 'M', u'æ«›'),
- (0x2F8EE, 'M', u'ã°˜'),
- (0x2F8EF, 'M', u'次'),
- (0x2F8F0, 'M', u'𣢧'),
- (0x2F8F1, 'M', u'æ­”'),
- (0x2F8F2, 'M', u'㱎'),
- (0x2F8F3, 'M', u'æ­²'),
- (0x2F8F4, 'M', u'殟'),
- (0x2F8F5, 'M', u'殺'),
- (0x2F8F6, 'M', u'æ®»'),
- (0x2F8F7, 'M', u'ð£ª'),
- (0x2F8F8, 'M', u'ð¡´‹'),
- (0x2F8F9, 'M', u'𣫺'),
- (0x2F8FA, 'M', u'汎'),
- (0x2F8FB, 'M', u'𣲼'),
- (0x2F8FC, 'M', u'沿'),
- (0x2F8FD, 'M', u'æ³'),
- (0x2F8FE, 'M', u'汧'),
- (0x2F8FF, 'M', u'æ´–'),
- (0x2F900, 'M', u'æ´¾'),
- (0x2F901, 'M', u'æµ·'),
- (0x2F902, 'M', u'æµ'),
- (0x2F903, 'M', u'浩'),
- (0x2F904, 'M', u'浸'),
- (0x2F905, 'M', u'涅'),
- (0x2F906, 'M', u'𣴞'),
- (0x2F907, 'M', u'æ´´'),
- (0x2F908, 'M', u'港'),
- (0x2F909, 'M', u'æ¹®'),
- (0x2F90A, 'M', u'ã´³'),
- (0x2F90B, 'M', u'滋'),
- (0x2F90C, 'M', u'滇'),
- (0x2F90D, 'M', u'𣻑'),
- (0x2F90E, 'M', u'æ·¹'),
- (0x2F90F, 'M', u'æ½®'),
- (0x2F910, 'M', u'𣽞'),
- (0x2F911, 'M', u'𣾎'),
- (0x2F912, 'M', u'濆'),
- (0x2F913, 'M', u'瀹'),
- (0x2F914, 'M', u'瀞'),
- (0x2F915, 'M', u'瀛'),
- (0x2F916, 'M', u'㶖'),
- (0x2F917, 'M', u'çŠ'),
- (0x2F918, 'M', u'ç½'),
- ]
-
-def _seg_70():
- return [
- (0x2F919, 'M', u'ç·'),
- (0x2F91A, 'M', u'ç‚­'),
- (0x2F91B, 'M', u'𠔥'),
- (0x2F91C, 'M', u'ç……'),
- (0x2F91D, 'M', u'𤉣'),
- (0x2F91E, 'M', u'熜'),
- (0x2F91F, 'X'),
- (0x2F920, 'M', u'爨'),
- (0x2F921, 'M', u'爵'),
- (0x2F922, 'M', u'ç‰'),
- (0x2F923, 'M', u'𤘈'),
- (0x2F924, 'M', u'犀'),
- (0x2F925, 'M', u'犕'),
- (0x2F926, 'M', u'𤜵'),
- (0x2F927, 'M', u'𤠔'),
- (0x2F928, 'M', u'çº'),
- (0x2F929, 'M', u'王'),
- (0x2F92A, 'M', u'㺬'),
- (0x2F92B, 'M', u'玥'),
- (0x2F92C, 'M', u'㺸'),
- (0x2F92E, 'M', u'瑇'),
- (0x2F92F, 'M', u'瑜'),
- (0x2F930, 'M', u'瑱'),
- (0x2F931, 'M', u'ç’…'),
- (0x2F932, 'M', u'ç“Š'),
- (0x2F933, 'M', u'ã¼›'),
- (0x2F934, 'M', u'甤'),
- (0x2F935, 'M', u'𤰶'),
- (0x2F936, 'M', u'甾'),
- (0x2F937, 'M', u'𤲒'),
- (0x2F938, 'M', u'ç•°'),
- (0x2F939, 'M', u'𢆟'),
- (0x2F93A, 'M', u'ç˜'),
- (0x2F93B, 'M', u'𤾡'),
- (0x2F93C, 'M', u'𤾸'),
- (0x2F93D, 'M', u'ð¥„'),
- (0x2F93E, 'M', u'㿼'),
- (0x2F93F, 'M', u'䀈'),
- (0x2F940, 'M', u'ç›´'),
- (0x2F941, 'M', u'𥃳'),
- (0x2F942, 'M', u'𥃲'),
- (0x2F943, 'M', u'𥄙'),
- (0x2F944, 'M', u'𥄳'),
- (0x2F945, 'M', u'眞'),
- (0x2F946, 'M', u'真'),
- (0x2F948, 'M', u'çŠ'),
- (0x2F949, 'M', u'䀹'),
- (0x2F94A, 'M', u'çž‹'),
- (0x2F94B, 'M', u'ä†'),
- (0x2F94C, 'M', u'ä‚–'),
- (0x2F94D, 'M', u'ð¥'),
- (0x2F94E, 'M', u'ç¡Ž'),
- (0x2F94F, 'M', u'碌'),
- (0x2F950, 'M', u'磌'),
- (0x2F951, 'M', u'䃣'),
- (0x2F952, 'M', u'𥘦'),
- (0x2F953, 'M', u'祖'),
- (0x2F954, 'M', u'𥚚'),
- (0x2F955, 'M', u'𥛅'),
- (0x2F956, 'M', u'ç¦'),
- (0x2F957, 'M', u'秫'),
- (0x2F958, 'M', u'䄯'),
- (0x2F959, 'M', u'ç©€'),
- (0x2F95A, 'M', u'ç©Š'),
- (0x2F95B, 'M', u'ç©'),
- (0x2F95C, 'M', u'𥥼'),
- (0x2F95D, 'M', u'𥪧'),
- (0x2F95F, 'X'),
- (0x2F960, 'M', u'䈂'),
- (0x2F961, 'M', u'𥮫'),
- (0x2F962, 'M', u'篆'),
- (0x2F963, 'M', u'築'),
- (0x2F964, 'M', u'䈧'),
- (0x2F965, 'M', u'𥲀'),
- (0x2F966, 'M', u'ç³’'),
- (0x2F967, 'M', u'䊠'),
- (0x2F968, 'M', u'糨'),
- (0x2F969, 'M', u'ç³£'),
- (0x2F96A, 'M', u'ç´€'),
- (0x2F96B, 'M', u'𥾆'),
- (0x2F96C, 'M', u'çµ£'),
- (0x2F96D, 'M', u'äŒ'),
- (0x2F96E, 'M', u'ç·‡'),
- (0x2F96F, 'M', u'縂'),
- (0x2F970, 'M', u'ç¹…'),
- (0x2F971, 'M', u'䌴'),
- (0x2F972, 'M', u'𦈨'),
- (0x2F973, 'M', u'𦉇'),
- (0x2F974, 'M', u'ä™'),
- (0x2F975, 'M', u'𦋙'),
- (0x2F976, 'M', u'罺'),
- (0x2F977, 'M', u'𦌾'),
- (0x2F978, 'M', u'羕'),
- (0x2F979, 'M', u'翺'),
- (0x2F97A, 'M', u'者'),
- (0x2F97B, 'M', u'𦓚'),
- (0x2F97C, 'M', u'𦔣'),
- (0x2F97D, 'M', u'è '),
- (0x2F97E, 'M', u'𦖨'),
- (0x2F97F, 'M', u'è°'),
- ]
-
-def _seg_71():
- return [
- (0x2F980, 'M', u'ð£Ÿ'),
- (0x2F981, 'M', u'ä•'),
- (0x2F982, 'M', u'育'),
- (0x2F983, 'M', u'脃'),
- (0x2F984, 'M', u'ä‹'),
- (0x2F985, 'M', u'脾'),
- (0x2F986, 'M', u'媵'),
- (0x2F987, 'M', u'𦞧'),
- (0x2F988, 'M', u'𦞵'),
- (0x2F989, 'M', u'𣎓'),
- (0x2F98A, 'M', u'𣎜'),
- (0x2F98B, 'M', u'èˆ'),
- (0x2F98C, 'M', u'舄'),
- (0x2F98D, 'M', u'辞'),
- (0x2F98E, 'M', u'ä‘«'),
- (0x2F98F, 'M', u'芑'),
- (0x2F990, 'M', u'芋'),
- (0x2F991, 'M', u'èŠ'),
- (0x2F992, 'M', u'劳'),
- (0x2F993, 'M', u'花'),
- (0x2F994, 'M', u'芳'),
- (0x2F995, 'M', u'芽'),
- (0x2F996, 'M', u'苦'),
- (0x2F997, 'M', u'𦬼'),
- (0x2F998, 'M', u'è‹¥'),
- (0x2F999, 'M', u'èŒ'),
- (0x2F99A, 'M', u'è£'),
- (0x2F99B, 'M', u'莭'),
- (0x2F99C, 'M', u'茣'),
- (0x2F99D, 'M', u'莽'),
- (0x2F99E, 'M', u'è§'),
- (0x2F99F, 'M', u'è‘—'),
- (0x2F9A0, 'M', u'è“'),
- (0x2F9A1, 'M', u'èŠ'),
- (0x2F9A2, 'M', u'èŒ'),
- (0x2F9A3, 'M', u'èœ'),
- (0x2F9A4, 'M', u'𦰶'),
- (0x2F9A5, 'M', u'𦵫'),
- (0x2F9A6, 'M', u'𦳕'),
- (0x2F9A7, 'M', u'䔫'),
- (0x2F9A8, 'M', u'蓱'),
- (0x2F9A9, 'M', u'蓳'),
- (0x2F9AA, 'M', u'è”–'),
- (0x2F9AB, 'M', u'ð§Š'),
- (0x2F9AC, 'M', u'蕤'),
- (0x2F9AD, 'M', u'𦼬'),
- (0x2F9AE, 'M', u'ä•'),
- (0x2F9AF, 'M', u'ä•¡'),
- (0x2F9B0, 'M', u'𦾱'),
- (0x2F9B1, 'M', u'𧃒'),
- (0x2F9B2, 'M', u'ä•«'),
- (0x2F9B3, 'M', u'è™'),
- (0x2F9B4, 'M', u'虜'),
- (0x2F9B5, 'M', u'虧'),
- (0x2F9B6, 'M', u'虩'),
- (0x2F9B7, 'M', u'èš©'),
- (0x2F9B8, 'M', u'蚈'),
- (0x2F9B9, 'M', u'蜎'),
- (0x2F9BA, 'M', u'蛢'),
- (0x2F9BB, 'M', u'è¹'),
- (0x2F9BC, 'M', u'蜨'),
- (0x2F9BD, 'M', u'è«'),
- (0x2F9BE, 'M', u'螆'),
- (0x2F9BF, 'X'),
- (0x2F9C0, 'M', u'蟡'),
- (0x2F9C1, 'M', u'è '),
- (0x2F9C2, 'M', u'ä—¹'),
- (0x2F9C3, 'M', u'è¡ '),
- (0x2F9C4, 'M', u'è¡£'),
- (0x2F9C5, 'M', u'𧙧'),
- (0x2F9C6, 'M', u'裗'),
- (0x2F9C7, 'M', u'裞'),
- (0x2F9C8, 'M', u'䘵'),
- (0x2F9C9, 'M', u'裺'),
- (0x2F9CA, 'M', u'ã’»'),
- (0x2F9CB, 'M', u'𧢮'),
- (0x2F9CC, 'M', u'𧥦'),
- (0x2F9CD, 'M', u'äš¾'),
- (0x2F9CE, 'M', u'䛇'),
- (0x2F9CF, 'M', u'誠'),
- (0x2F9D0, 'M', u'è«­'),
- (0x2F9D1, 'M', u'變'),
- (0x2F9D2, 'M', u'豕'),
- (0x2F9D3, 'M', u'𧲨'),
- (0x2F9D4, 'M', u'貫'),
- (0x2F9D5, 'M', u'è³'),
- (0x2F9D6, 'M', u'è´›'),
- (0x2F9D7, 'M', u'èµ·'),
- (0x2F9D8, 'M', u'𧼯'),
- (0x2F9D9, 'M', u'ð  „'),
- (0x2F9DA, 'M', u'è·‹'),
- (0x2F9DB, 'M', u'趼'),
- (0x2F9DC, 'M', u'è·°'),
- (0x2F9DD, 'M', u'𠣞'),
- (0x2F9DE, 'M', u'è»”'),
- (0x2F9DF, 'M', u'輸'),
- (0x2F9E0, 'M', u'𨗒'),
- (0x2F9E1, 'M', u'𨗭'),
- (0x2F9E2, 'M', u'é‚”'),
- (0x2F9E3, 'M', u'郱'),
- ]
-
-def _seg_72():
- return [
- (0x2F9E4, 'M', u'é„‘'),
- (0x2F9E5, 'M', u'𨜮'),
- (0x2F9E6, 'M', u'é„›'),
- (0x2F9E7, 'M', u'鈸'),
- (0x2F9E8, 'M', u'é‹—'),
- (0x2F9E9, 'M', u'鋘'),
- (0x2F9EA, 'M', u'鉼'),
- (0x2F9EB, 'M', u'é¹'),
- (0x2F9EC, 'M', u'é•'),
- (0x2F9ED, 'M', u'𨯺'),
- (0x2F9EE, 'M', u'é–‹'),
- (0x2F9EF, 'M', u'䦕'),
- (0x2F9F0, 'M', u'é–·'),
- (0x2F9F1, 'M', u'𨵷'),
- (0x2F9F2, 'M', u'䧦'),
- (0x2F9F3, 'M', u'雃'),
- (0x2F9F4, 'M', u'嶲'),
- (0x2F9F5, 'M', u'霣'),
- (0x2F9F6, 'M', u'ð©……'),
- (0x2F9F7, 'M', u'𩈚'),
- (0x2F9F8, 'M', u'ä©®'),
- (0x2F9F9, 'M', u'䩶'),
- (0x2F9FA, 'M', u'韠'),
- (0x2F9FB, 'M', u'ð©Š'),
- (0x2F9FC, 'M', u'䪲'),
- (0x2F9FD, 'M', u'ð©’–'),
- (0x2F9FE, 'M', u'é ‹'),
- (0x2FA00, 'M', u'é ©'),
- (0x2FA01, 'M', u'ð©–¶'),
- (0x2FA02, 'M', u'飢'),
- (0x2FA03, 'M', u'䬳'),
- (0x2FA04, 'M', u'餩'),
- (0x2FA05, 'M', u'馧'),
- (0x2FA06, 'M', u'駂'),
- (0x2FA07, 'M', u'駾'),
- (0x2FA08, 'M', u'䯎'),
- (0x2FA09, 'M', u'𩬰'),
- (0x2FA0A, 'M', u'鬒'),
- (0x2FA0B, 'M', u'é±€'),
- (0x2FA0C, 'M', u'é³½'),
- (0x2FA0D, 'M', u'䳎'),
- (0x2FA0E, 'M', u'ä³­'),
- (0x2FA0F, 'M', u'鵧'),
- (0x2FA10, 'M', u'𪃎'),
- (0x2FA11, 'M', u'䳸'),
- (0x2FA12, 'M', u'𪄅'),
- (0x2FA13, 'M', u'𪈎'),
- (0x2FA14, 'M', u'𪊑'),
- (0x2FA15, 'M', u'麻'),
- (0x2FA16, 'M', u'äµ–'),
- (0x2FA17, 'M', u'黹'),
- (0x2FA18, 'M', u'黾'),
- (0x2FA19, 'M', u'é¼…'),
- (0x2FA1A, 'M', u'é¼'),
- (0x2FA1B, 'M', u'é¼–'),
- (0x2FA1C, 'M', u'é¼»'),
- (0x2FA1D, 'M', u'𪘀'),
- (0x2FA1E, 'X'),
- (0xE0100, 'I'),
- (0xE01F0, 'X'),
- ]
-
-uts46data = tuple(
- _seg_0()
- + _seg_1()
- + _seg_2()
- + _seg_3()
- + _seg_4()
- + _seg_5()
- + _seg_6()
- + _seg_7()
- + _seg_8()
- + _seg_9()
- + _seg_10()
- + _seg_11()
- + _seg_12()
- + _seg_13()
- + _seg_14()
- + _seg_15()
- + _seg_16()
- + _seg_17()
- + _seg_18()
- + _seg_19()
- + _seg_20()
- + _seg_21()
- + _seg_22()
- + _seg_23()
- + _seg_24()
- + _seg_25()
- + _seg_26()
- + _seg_27()
- + _seg_28()
- + _seg_29()
- + _seg_30()
- + _seg_31()
- + _seg_32()
- + _seg_33()
- + _seg_34()
- + _seg_35()
- + _seg_36()
- + _seg_37()
- + _seg_38()
- + _seg_39()
- + _seg_40()
- + _seg_41()
- + _seg_42()
- + _seg_43()
- + _seg_44()
- + _seg_45()
- + _seg_46()
- + _seg_47()
- + _seg_48()
- + _seg_49()
- + _seg_50()
- + _seg_51()
- + _seg_52()
- + _seg_53()
- + _seg_54()
- + _seg_55()
- + _seg_56()
- + _seg_57()
- + _seg_58()
- + _seg_59()
- + _seg_60()
- + _seg_61()
- + _seg_62()
- + _seg_63()
- + _seg_64()
- + _seg_65()
- + _seg_66()
- + _seg_67()
- + _seg_68()
- + _seg_69()
- + _seg_70()
- + _seg_71()
- + _seg_72()
-)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/__init__.py
deleted file mode 100644
index ac3ff838..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/__init__.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-urllib3 - Thread-safe connection pooling and re-using.
-"""
-
-from __future__ import absolute_import
-import warnings
-
-from .connectionpool import (
- HTTPConnectionPool,
- HTTPSConnectionPool,
- connection_from_url
-)
-
-from . import exceptions
-from .filepost import encode_multipart_formdata
-from .poolmanager import PoolManager, ProxyManager, proxy_from_url
-from .response import HTTPResponse
-from .util.request import make_headers
-from .util.url import get_host
-from .util.timeout import Timeout
-from .util.retry import Retry
-
-
-# Set default logging handler to avoid "No handler found" warnings.
-import logging
-try: # Python 2.7+
- from logging import NullHandler
-except ImportError:
- class NullHandler(logging.Handler):
- def emit(self, record):
- pass
-
-__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)'
-__license__ = 'MIT'
-__version__ = '1.20'
-
-__all__ = (
- 'HTTPConnectionPool',
- 'HTTPSConnectionPool',
- 'PoolManager',
- 'ProxyManager',
- 'HTTPResponse',
- 'Retry',
- 'Timeout',
- 'add_stderr_logger',
- 'connection_from_url',
- 'disable_warnings',
- 'encode_multipart_formdata',
- 'get_host',
- 'make_headers',
- 'proxy_from_url',
-)
-
-logging.getLogger(__name__).addHandler(NullHandler())
-
-
-def add_stderr_logger(level=logging.DEBUG):
- """
- Helper for quickly adding a StreamHandler to the logger. Useful for
- debugging.
-
- Returns the handler after adding it.
- """
- # This method needs to be in this __init__.py to get the __name__ correct
- # even if urllib3 is vendored within another package.
- logger = logging.getLogger(__name__)
- handler = logging.StreamHandler()
- handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
- logger.addHandler(handler)
- logger.setLevel(level)
- logger.debug('Added a stderr logging handler to logger: %s', __name__)
- return handler
-
-
-# ... Clean up.
-del NullHandler
-
-
-# All warning filters *must* be appended unless you're really certain that they
-# shouldn't be: otherwise, it's very hard for users to use most Python
-# mechanisms to silence them.
-# SecurityWarning's always go off by default.
-warnings.simplefilter('always', exceptions.SecurityWarning, append=True)
-# SubjectAltNameWarning's should go off once per host
-warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True)
-# InsecurePlatformWarning's don't vary between requests, so we keep it default.
-warnings.simplefilter('default', exceptions.InsecurePlatformWarning,
- append=True)
-# SNIMissingWarnings should go off only once.
-warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True)
-
-
-def disable_warnings(category=exceptions.HTTPWarning):
- """
- Helper for quickly disabling all urllib3 warnings.
- """
- warnings.simplefilter('ignore', category)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/_collections.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/_collections.py
deleted file mode 100644
index 77cee017..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/_collections.py
+++ /dev/null
@@ -1,324 +0,0 @@
-from __future__ import absolute_import
-from collections import Mapping, MutableMapping
-try:
- from threading import RLock
-except ImportError: # Platform-specific: No threads available
- class RLock:
- def __enter__(self):
- pass
-
- def __exit__(self, exc_type, exc_value, traceback):
- pass
-
-
-try: # Python 2.7+
- from collections import OrderedDict
-except ImportError:
- from .packages.ordered_dict import OrderedDict
-from .packages.six import iterkeys, itervalues, PY3
-
-
-__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict']
-
-
-_Null = object()
-
-
-class RecentlyUsedContainer(MutableMapping):
- """
- Provides a thread-safe dict-like container which maintains up to
- ``maxsize`` keys while throwing away the least-recently-used keys beyond
- ``maxsize``.
-
- :param maxsize:
- Maximum number of recent elements to retain.
-
- :param dispose_func:
- Every time an item is evicted from the container,
- ``dispose_func(value)`` is called. Callback which will get called
- """
-
- ContainerCls = OrderedDict
-
- def __init__(self, maxsize=10, dispose_func=None):
- self._maxsize = maxsize
- self.dispose_func = dispose_func
-
- self._container = self.ContainerCls()
- self.lock = RLock()
-
- def __getitem__(self, key):
- # Re-insert the item, moving it to the end of the eviction line.
- with self.lock:
- item = self._container.pop(key)
- self._container[key] = item
- return item
-
- def __setitem__(self, key, value):
- evicted_value = _Null
- with self.lock:
- # Possibly evict the existing value of 'key'
- evicted_value = self._container.get(key, _Null)
- self._container[key] = value
-
- # If we didn't evict an existing value, we might have to evict the
- # least recently used item from the beginning of the container.
- if len(self._container) > self._maxsize:
- _key, evicted_value = self._container.popitem(last=False)
-
- if self.dispose_func and evicted_value is not _Null:
- self.dispose_func(evicted_value)
-
- def __delitem__(self, key):
- with self.lock:
- value = self._container.pop(key)
-
- if self.dispose_func:
- self.dispose_func(value)
-
- def __len__(self):
- with self.lock:
- return len(self._container)
-
- def __iter__(self):
- raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')
-
- def clear(self):
- with self.lock:
- # Copy pointers to all values, then wipe the mapping
- values = list(itervalues(self._container))
- self._container.clear()
-
- if self.dispose_func:
- for value in values:
- self.dispose_func(value)
-
- def keys(self):
- with self.lock:
- return list(iterkeys(self._container))
-
-
-class HTTPHeaderDict(MutableMapping):
- """
- :param headers:
- An iterable of field-value pairs. Must not contain multiple field names
- when compared case-insensitively.
-
- :param kwargs:
- Additional field-value pairs to pass in to ``dict.update``.
-
- A ``dict`` like container for storing HTTP Headers.
-
- Field names are stored and compared case-insensitively in compliance with
- RFC 7230. Iteration provides the first case-sensitive key seen for each
- case-insensitive pair.
-
- Using ``__setitem__`` syntax overwrites fields that compare equal
- case-insensitively in order to maintain ``dict``'s api. For fields that
- compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
- in a loop.
-
- If multiple fields that are equal case-insensitively are passed to the
- constructor or ``.update``, the behavior is undefined and some will be
- lost.
-
- >>> headers = HTTPHeaderDict()
- >>> headers.add('Set-Cookie', 'foo=bar')
- >>> headers.add('set-cookie', 'baz=quxx')
- >>> headers['content-length'] = '7'
- >>> headers['SET-cookie']
- 'foo=bar, baz=quxx'
- >>> headers['Content-Length']
- '7'
- """
-
- def __init__(self, headers=None, **kwargs):
- super(HTTPHeaderDict, self).__init__()
- self._container = OrderedDict()
- if headers is not None:
- if isinstance(headers, HTTPHeaderDict):
- self._copy_from(headers)
- else:
- self.extend(headers)
- if kwargs:
- self.extend(kwargs)
-
- def __setitem__(self, key, val):
- self._container[key.lower()] = (key, val)
- return self._container[key.lower()]
-
- def __getitem__(self, key):
- val = self._container[key.lower()]
- return ', '.join(val[1:])
-
- def __delitem__(self, key):
- del self._container[key.lower()]
-
- def __contains__(self, key):
- return key.lower() in self._container
-
- def __eq__(self, other):
- if not isinstance(other, Mapping) and not hasattr(other, 'keys'):
- return False
- if not isinstance(other, type(self)):
- other = type(self)(other)
- return (dict((k.lower(), v) for k, v in self.itermerged()) ==
- dict((k.lower(), v) for k, v in other.itermerged()))
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- if not PY3: # Python 2
- iterkeys = MutableMapping.iterkeys
- itervalues = MutableMapping.itervalues
-
- __marker = object()
-
- def __len__(self):
- return len(self._container)
-
- def __iter__(self):
- # Only provide the originally cased names
- for vals in self._container.values():
- yield vals[0]
-
- def pop(self, key, default=__marker):
- '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
- If key is not found, d is returned if given, otherwise KeyError is raised.
- '''
- # Using the MutableMapping function directly fails due to the private marker.
- # Using ordinary dict.pop would expose the internal structures.
- # So let's reinvent the wheel.
- try:
- value = self[key]
- except KeyError:
- if default is self.__marker:
- raise
- return default
- else:
- del self[key]
- return value
-
- def discard(self, key):
- try:
- del self[key]
- except KeyError:
- pass
-
- def add(self, key, val):
- """Adds a (name, value) pair, doesn't overwrite the value if it already
- exists.
-
- >>> headers = HTTPHeaderDict(foo='bar')
- >>> headers.add('Foo', 'baz')
- >>> headers['foo']
- 'bar, baz'
- """
- key_lower = key.lower()
- new_vals = key, val
- # Keep the common case aka no item present as fast as possible
- vals = self._container.setdefault(key_lower, new_vals)
- if new_vals is not vals:
- # new_vals was not inserted, as there was a previous one
- if isinstance(vals, list):
- # If already several items got inserted, we have a list
- vals.append(val)
- else:
- # vals should be a tuple then, i.e. only one item so far
- # Need to convert the tuple to list for further extension
- self._container[key_lower] = [vals[0], vals[1], val]
-
- def extend(self, *args, **kwargs):
- """Generic import function for any type of header-like object.
- Adapted version of MutableMapping.update in order to insert items
- with self.add instead of self.__setitem__
- """
- if len(args) > 1:
- raise TypeError("extend() takes at most 1 positional "
- "arguments ({0} given)".format(len(args)))
- other = args[0] if len(args) >= 1 else ()
-
- if isinstance(other, HTTPHeaderDict):
- for key, val in other.iteritems():
- self.add(key, val)
- elif isinstance(other, Mapping):
- for key in other:
- self.add(key, other[key])
- elif hasattr(other, "keys"):
- for key in other.keys():
- self.add(key, other[key])
- else:
- for key, value in other:
- self.add(key, value)
-
- for key, value in kwargs.items():
- self.add(key, value)
-
- def getlist(self, key):
- """Returns a list of all the values for the named field. Returns an
- empty list if the key doesn't exist."""
- try:
- vals = self._container[key.lower()]
- except KeyError:
- return []
- else:
- if isinstance(vals, tuple):
- return [vals[1]]
- else:
- return vals[1:]
-
- # Backwards compatibility for httplib
- getheaders = getlist
- getallmatchingheaders = getlist
- iget = getlist
-
- def __repr__(self):
- return "%s(%s)" % (type(self).__name__, dict(self.itermerged()))
-
- def _copy_from(self, other):
- for key in other:
- val = other.getlist(key)
- if isinstance(val, list):
- # Don't need to convert tuples
- val = list(val)
- self._container[key.lower()] = [key] + val
-
- def copy(self):
- clone = type(self)()
- clone._copy_from(self)
- return clone
-
- def iteritems(self):
- """Iterate over all header lines, including duplicate ones."""
- for key in self:
- vals = self._container[key.lower()]
- for val in vals[1:]:
- yield vals[0], val
-
- def itermerged(self):
- """Iterate over all headers, merging duplicate ones together."""
- for key in self:
- val = self._container[key.lower()]
- yield val[0], ', '.join(val[1:])
-
- def items(self):
- return list(self.iteritems())
-
- @classmethod
- def from_httplib(cls, message): # Python 2
- """Read headers from a Python 2 httplib message object."""
- # python2.7 does not expose a proper API for exporting multiheaders
- # efficiently. This function re-reads raw lines from the message
- # object and extracts the multiheaders properly.
- headers = []
-
- for line in message.headers:
- if line.startswith((' ', '\t')):
- key, value = headers[-1]
- headers[-1] = (key, value + '\r\n' + line.rstrip())
- continue
-
- key, value = line.split(':', 1)
- headers.append((key, value.strip()))
-
- return cls(headers)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connection.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connection.py
deleted file mode 100644
index 9f06c395..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connection.py
+++ /dev/null
@@ -1,369 +0,0 @@
-from __future__ import absolute_import
-import datetime
-import logging
-import os
-import sys
-import socket
-from socket import error as SocketError, timeout as SocketTimeout
-import warnings
-from .packages import six
-from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection
-from .packages.six.moves.http_client import HTTPException # noqa: F401
-
-try: # Compiled with SSL?
- import ssl
- BaseSSLError = ssl.SSLError
-except (ImportError, AttributeError): # Platform-specific: No SSL.
- ssl = None
-
- class BaseSSLError(BaseException):
- pass
-
-
-try: # Python 3:
- # Not a no-op, we're adding this to the namespace so it can be imported.
- ConnectionError = ConnectionError
-except NameError: # Python 2:
- class ConnectionError(Exception):
- pass
-
-
-from .exceptions import (
- NewConnectionError,
- ConnectTimeoutError,
- SubjectAltNameWarning,
- SystemTimeWarning,
-)
-from .packages.ssl_match_hostname import match_hostname, CertificateError
-
-from .util.ssl_ import (
- resolve_cert_reqs,
- resolve_ssl_version,
- assert_fingerprint,
- create_urllib3_context,
- ssl_wrap_socket
-)
-
-
-from .util import connection
-
-from ._collections import HTTPHeaderDict
-
-log = logging.getLogger(__name__)
-
-port_by_scheme = {
- 'http': 80,
- 'https': 443,
-}
-
-# When updating RECENT_DATE, move it to
-# within two years of the current date, and no
-# earlier than 6 months ago.
-RECENT_DATE = datetime.date(2016, 1, 1)
-
-
-class DummyConnection(object):
- """Used to detect a failed ConnectionCls import."""
- pass
-
-
-class HTTPConnection(_HTTPConnection, object):
- """
- Based on httplib.HTTPConnection but provides an extra constructor
- backwards-compatibility layer between older and newer Pythons.
-
- Additional keyword parameters are used to configure attributes of the connection.
- Accepted parameters include:
-
- - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
- - ``source_address``: Set the source address for the current connection.
-
- .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x
-
- - ``socket_options``: Set specific options on the underlying socket. If not specified, then
- defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
- Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
-
- For example, if you wish to enable TCP Keep Alive in addition to the defaults,
- you might pass::
-
- HTTPConnection.default_socket_options + [
- (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
- ]
-
- Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
- """
-
- default_port = port_by_scheme['http']
-
- #: Disable Nagle's algorithm by default.
- #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``
- default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
-
- #: Whether this connection verifies the host's certificate.
- is_verified = False
-
- def __init__(self, *args, **kw):
- if six.PY3: # Python 3
- kw.pop('strict', None)
-
- # Pre-set source_address in case we have an older Python like 2.6.
- self.source_address = kw.get('source_address')
-
- if sys.version_info < (2, 7): # Python 2.6
- # _HTTPConnection on Python 2.6 will balk at this keyword arg, but
- # not newer versions. We can still use it when creating a
- # connection though, so we pop it *after* we have saved it as
- # self.source_address.
- kw.pop('source_address', None)
-
- #: The socket options provided by the user. If no options are
- #: provided, we use the default options.
- self.socket_options = kw.pop('socket_options', self.default_socket_options)
-
- # Superclass also sets self.source_address in Python 2.7+.
- _HTTPConnection.__init__(self, *args, **kw)
-
- def _new_conn(self):
- """ Establish a socket connection and set nodelay settings on it.
-
- :return: New socket connection.
- """
- extra_kw = {}
- if self.source_address:
- extra_kw['source_address'] = self.source_address
-
- if self.socket_options:
- extra_kw['socket_options'] = self.socket_options
-
- try:
- conn = connection.create_connection(
- (self.host, self.port), self.timeout, **extra_kw)
-
- except SocketTimeout as e:
- raise ConnectTimeoutError(
- self, "Connection to %s timed out. (connect timeout=%s)" %
- (self.host, self.timeout))
-
- except SocketError as e:
- raise NewConnectionError(
- self, "Failed to establish a new connection: %s" % e)
-
- return conn
-
- def _prepare_conn(self, conn):
- self.sock = conn
- # the _tunnel_host attribute was added in python 2.6.3 (via
- # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do
- # not have them.
- if getattr(self, '_tunnel_host', None):
- # TODO: Fix tunnel so it doesn't depend on self.sock state.
- self._tunnel()
- # Mark this connection as not reusable
- self.auto_open = 0
-
- def connect(self):
- conn = self._new_conn()
- self._prepare_conn(conn)
-
- def request_chunked(self, method, url, body=None, headers=None):
- """
- Alternative to the common request method, which sends the
- body with chunked encoding and not as one block
- """
- headers = HTTPHeaderDict(headers if headers is not None else {})
- skip_accept_encoding = 'accept-encoding' in headers
- skip_host = 'host' in headers
- self.putrequest(
- method,
- url,
- skip_accept_encoding=skip_accept_encoding,
- skip_host=skip_host
- )
- for header, value in headers.items():
- self.putheader(header, value)
- if 'transfer-encoding' not in headers:
- self.putheader('Transfer-Encoding', 'chunked')
- self.endheaders()
-
- if body is not None:
- stringish_types = six.string_types + (six.binary_type,)
- if isinstance(body, stringish_types):
- body = (body,)
- for chunk in body:
- if not chunk:
- continue
- if not isinstance(chunk, six.binary_type):
- chunk = chunk.encode('utf8')
- len_str = hex(len(chunk))[2:]
- self.send(len_str.encode('utf-8'))
- self.send(b'\r\n')
- self.send(chunk)
- self.send(b'\r\n')
-
- # After the if clause, to always have a closed body
- self.send(b'0\r\n\r\n')
-
-
-class HTTPSConnection(HTTPConnection):
- default_port = port_by_scheme['https']
-
- ssl_version = None
-
- def __init__(self, host, port=None, key_file=None, cert_file=None,
- strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
- ssl_context=None, **kw):
-
- HTTPConnection.__init__(self, host, port, strict=strict,
- timeout=timeout, **kw)
-
- self.key_file = key_file
- self.cert_file = cert_file
- self.ssl_context = ssl_context
-
- # Required property for Google AppEngine 1.9.0 which otherwise causes
- # HTTPS requests to go out as HTTP. (See Issue #356)
- self._protocol = 'https'
-
- def connect(self):
- conn = self._new_conn()
- self._prepare_conn(conn)
-
- if self.ssl_context is None:
- self.ssl_context = create_urllib3_context(
- ssl_version=resolve_ssl_version(None),
- cert_reqs=resolve_cert_reqs(None),
- )
-
- self.sock = ssl_wrap_socket(
- sock=conn,
- keyfile=self.key_file,
- certfile=self.cert_file,
- ssl_context=self.ssl_context,
- )
-
-
-class VerifiedHTTPSConnection(HTTPSConnection):
- """
- Based on httplib.HTTPSConnection but wraps the socket with
- SSL certification.
- """
- cert_reqs = None
- ca_certs = None
- ca_cert_dir = None
- ssl_version = None
- assert_fingerprint = None
-
- def set_cert(self, key_file=None, cert_file=None,
- cert_reqs=None, ca_certs=None,
- assert_hostname=None, assert_fingerprint=None,
- ca_cert_dir=None):
- """
- This method should only be called once, before the connection is used.
- """
- # If cert_reqs is not provided, we can try to guess. If the user gave
- # us a cert database, we assume they want to use it: otherwise, if
- # they gave us an SSL Context object we should use whatever is set for
- # it.
- if cert_reqs is None:
- if ca_certs or ca_cert_dir:
- cert_reqs = 'CERT_REQUIRED'
- elif self.ssl_context is not None:
- cert_reqs = self.ssl_context.verify_mode
-
- self.key_file = key_file
- self.cert_file = cert_file
- self.cert_reqs = cert_reqs
- self.assert_hostname = assert_hostname
- self.assert_fingerprint = assert_fingerprint
- self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
- self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
-
- def connect(self):
- # Add certificate verification
- conn = self._new_conn()
-
- hostname = self.host
- if getattr(self, '_tunnel_host', None):
- # _tunnel_host was added in Python 2.6.3
- # (See: http://hg.python.org/cpython/rev/0f57b30a152f)
-
- self.sock = conn
- # Calls self._set_hostport(), so self.host is
- # self._tunnel_host below.
- self._tunnel()
- # Mark this connection as not reusable
- self.auto_open = 0
-
- # Override the host with the one we're requesting data from.
- hostname = self._tunnel_host
-
- is_time_off = datetime.date.today() < RECENT_DATE
- if is_time_off:
- warnings.warn((
- 'System time is way off (before {0}). This will probably '
- 'lead to SSL verification errors').format(RECENT_DATE),
- SystemTimeWarning
- )
-
- # Wrap socket using verification with the root certs in
- # trusted_root_certs
- if self.ssl_context is None:
- self.ssl_context = create_urllib3_context(
- ssl_version=resolve_ssl_version(self.ssl_version),
- cert_reqs=resolve_cert_reqs(self.cert_reqs),
- )
-
- context = self.ssl_context
- context.verify_mode = resolve_cert_reqs(self.cert_reqs)
- self.sock = ssl_wrap_socket(
- sock=conn,
- keyfile=self.key_file,
- certfile=self.cert_file,
- ca_certs=self.ca_certs,
- ca_cert_dir=self.ca_cert_dir,
- server_hostname=hostname,
- ssl_context=context)
-
- if self.assert_fingerprint:
- assert_fingerprint(self.sock.getpeercert(binary_form=True),
- self.assert_fingerprint)
- elif context.verify_mode != ssl.CERT_NONE \
- and self.assert_hostname is not False:
- cert = self.sock.getpeercert()
- if not cert.get('subjectAltName', ()):
- warnings.warn((
- 'Certificate for {0} has no `subjectAltName`, falling back to check for a '
- '`commonName` for now. This feature is being removed by major browsers and '
- 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 '
- 'for details.)'.format(hostname)),
- SubjectAltNameWarning
- )
- _match_hostname(cert, self.assert_hostname or hostname)
-
- self.is_verified = (
- context.verify_mode == ssl.CERT_REQUIRED or
- self.assert_fingerprint is not None
- )
-
-
-def _match_hostname(cert, asserted_hostname):
- try:
- match_hostname(cert, asserted_hostname)
- except CertificateError as e:
- log.error(
- 'Certificate did not match expected hostname: %s. '
- 'Certificate: %s', asserted_hostname, cert
- )
- # Add cert to exception and reraise so client code can inspect
- # the cert when catching the exception, if they want to
- e._peer_cert = cert
- raise
-
-
-if ssl:
- # Make a copy for testing.
- UnverifiedHTTPSConnection = HTTPSConnection
- HTTPSConnection = VerifiedHTTPSConnection
-else:
- HTTPSConnection = DummyConnection
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connectionpool.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connectionpool.py
deleted file mode 100644
index b4f1166a..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/connectionpool.py
+++ /dev/null
@@ -1,899 +0,0 @@
-from __future__ import absolute_import
-import errno
-import logging
-import sys
-import warnings
-
-from socket import error as SocketError, timeout as SocketTimeout
-import socket
-
-
-from .exceptions import (
- ClosedPoolError,
- ProtocolError,
- EmptyPoolError,
- HeaderParsingError,
- HostChangedError,
- LocationValueError,
- MaxRetryError,
- ProxyError,
- ReadTimeoutError,
- SSLError,
- TimeoutError,
- InsecureRequestWarning,
- NewConnectionError,
-)
-from .packages.ssl_match_hostname import CertificateError
-from .packages import six
-from .packages.six.moves import queue
-from .connection import (
- port_by_scheme,
- DummyConnection,
- HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection,
- HTTPException, BaseSSLError,
-)
-from .request import RequestMethods
-from .response import HTTPResponse
-
-from .util.connection import is_connection_dropped
-from .util.request import set_file_position
-from .util.response import assert_header_parsing
-from .util.retry import Retry
-from .util.timeout import Timeout
-from .util.url import get_host, Url
-
-
-if six.PY2:
- # Queue is imported for side effects on MS Windows
- import Queue as _unused_module_Queue # noqa: F401
-
-xrange = six.moves.xrange
-
-log = logging.getLogger(__name__)
-
-_Default = object()
-
-
-# Pool objects
-class ConnectionPool(object):
- """
- Base class for all connection pools, such as
- :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.
- """
-
- scheme = None
- QueueCls = queue.LifoQueue
-
- def __init__(self, host, port=None):
- if not host:
- raise LocationValueError("No host specified.")
-
- self.host = _ipv6_host(host).lower()
- self.port = port
-
- def __str__(self):
- return '%s(host=%r, port=%r)' % (type(self).__name__,
- self.host, self.port)
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.close()
- # Return False to re-raise any potential exceptions
- return False
-
- def close(self):
- """
- Close all pooled connections and disable the pool.
- """
- pass
-
-
-# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
-_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK])
-
-
-class HTTPConnectionPool(ConnectionPool, RequestMethods):
- """
- Thread-safe connection pool for one host.
-
- :param host:
- Host used for this HTTP Connection (e.g. "localhost"), passed into
- :class:`httplib.HTTPConnection`.
-
- :param port:
- Port used for this HTTP Connection (None is equivalent to 80), passed
- into :class:`httplib.HTTPConnection`.
-
- :param strict:
- Causes BadStatusLine to be raised if the status line can't be parsed
- as a valid HTTP/1.0 or 1.1 status line, passed into
- :class:`httplib.HTTPConnection`.
-
- .. note::
- Only works in Python 2. This parameter is ignored in Python 3.
-
- :param timeout:
- Socket timeout in seconds for each individual connection. This can
- be a float or integer, which sets the timeout for the HTTP request,
- or an instance of :class:`urllib3.util.Timeout` which gives you more
- fine-grained control over request timeouts. After the constructor has
- been parsed, this is always a `urllib3.util.Timeout` object.
-
- :param maxsize:
- Number of connections to save that can be reused. More than 1 is useful
- in multithreaded situations. If ``block`` is set to False, more
- connections will be created but they will not be saved once they've
- been used.
-
- :param block:
- If set to True, no more than ``maxsize`` connections will be used at
- a time. When no free connections are available, the call will block
- until a connection has been released. This is a useful side effect for
- particular multithreaded situations where one does not want to use more
- than maxsize connections per host to prevent flooding.
-
- :param headers:
- Headers to include with all requests, unless other headers are given
- explicitly.
-
- :param retries:
- Retry configuration to use by default with requests in this pool.
-
- :param _proxy:
- Parsed proxy URL, should not be used directly, instead, see
- :class:`urllib3.connectionpool.ProxyManager`"
-
- :param _proxy_headers:
- A dictionary with proxy headers, should not be used directly,
- instead, see :class:`urllib3.connectionpool.ProxyManager`"
-
- :param \\**conn_kw:
- Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,
- :class:`urllib3.connection.HTTPSConnection` instances.
- """
-
- scheme = 'http'
- ConnectionCls = HTTPConnection
- ResponseCls = HTTPResponse
-
- def __init__(self, host, port=None, strict=False,
- timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False,
- headers=None, retries=None,
- _proxy=None, _proxy_headers=None,
- **conn_kw):
- ConnectionPool.__init__(self, host, port)
- RequestMethods.__init__(self, headers)
-
- self.strict = strict
-
- if not isinstance(timeout, Timeout):
- timeout = Timeout.from_float(timeout)
-
- if retries is None:
- retries = Retry.DEFAULT
-
- self.timeout = timeout
- self.retries = retries
-
- self.pool = self.QueueCls(maxsize)
- self.block = block
-
- self.proxy = _proxy
- self.proxy_headers = _proxy_headers or {}
-
- # Fill the queue up so that doing get() on it will block properly
- for _ in xrange(maxsize):
- self.pool.put(None)
-
- # These are mostly for testing and debugging purposes.
- self.num_connections = 0
- self.num_requests = 0
- self.conn_kw = conn_kw
-
- if self.proxy:
- # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.
- # We cannot know if the user has added default socket options, so we cannot replace the
- # list.
- self.conn_kw.setdefault('socket_options', [])
-
- def _new_conn(self):
- """
- Return a fresh :class:`HTTPConnection`.
- """
- self.num_connections += 1
- log.debug("Starting new HTTP connection (%d): %s",
- self.num_connections, self.host)
-
- conn = self.ConnectionCls(host=self.host, port=self.port,
- timeout=self.timeout.connect_timeout,
- strict=self.strict, **self.conn_kw)
- return conn
-
- def _get_conn(self, timeout=None):
- """
- Get a connection. Will return a pooled connection if one is available.
-
- If no connections are available and :prop:`.block` is ``False``, then a
- fresh connection is returned.
-
- :param timeout:
- Seconds to wait before giving up and raising
- :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and
- :prop:`.block` is ``True``.
- """
- conn = None
- try:
- conn = self.pool.get(block=self.block, timeout=timeout)
-
- except AttributeError: # self.pool is None
- raise ClosedPoolError(self, "Pool is closed.")
-
- except queue.Empty:
- if self.block:
- raise EmptyPoolError(self,
- "Pool reached maximum size and no more "
- "connections are allowed.")
- pass # Oh well, we'll create a new connection then
-
- # If this is a persistent connection, check if it got disconnected
- if conn and is_connection_dropped(conn):
- log.debug("Resetting dropped connection: %s", self.host)
- conn.close()
- if getattr(conn, 'auto_open', 1) == 0:
- # This is a proxied connection that has been mutated by
- # httplib._tunnel() and cannot be reused (since it would
- # attempt to bypass the proxy)
- conn = None
-
- return conn or self._new_conn()
-
- def _put_conn(self, conn):
- """
- Put a connection back into the pool.
-
- :param conn:
- Connection object for the current host and port as returned by
- :meth:`._new_conn` or :meth:`._get_conn`.
-
- If the pool is already full, the connection is closed and discarded
- because we exceeded maxsize. If connections are discarded frequently,
- then maxsize should be increased.
-
- If the pool is closed, then the connection will be closed and discarded.
- """
- try:
- self.pool.put(conn, block=False)
- return # Everything is dandy, done.
- except AttributeError:
- # self.pool is None.
- pass
- except queue.Full:
- # This should never happen if self.block == True
- log.warning(
- "Connection pool is full, discarding connection: %s",
- self.host)
-
- # Connection never got put back into the pool, close it.
- if conn:
- conn.close()
-
- def _validate_conn(self, conn):
- """
- Called right before a request is made, after the socket is created.
- """
- pass
-
- def _prepare_proxy(self, conn):
- # Nothing to do for HTTP connections.
- pass
-
- def _get_timeout(self, timeout):
- """ Helper that always returns a :class:`urllib3.util.Timeout` """
- if timeout is _Default:
- return self.timeout.clone()
-
- if isinstance(timeout, Timeout):
- return timeout.clone()
- else:
- # User passed us an int/float. This is for backwards compatibility,
- # can be removed later
- return Timeout.from_float(timeout)
-
- def _raise_timeout(self, err, url, timeout_value):
- """Is the error actually a timeout? Will raise a ReadTimeout or pass"""
-
- if isinstance(err, SocketTimeout):
- raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
-
- # See the above comment about EAGAIN in Python 3. In Python 2 we have
- # to specifically catch it and throw the timeout error
- if hasattr(err, 'errno') and err.errno in _blocking_errnos:
- raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
-
- # Catch possible read timeouts thrown as SSL errors. If not the
- # case, rethrow the original. We need to do this because of:
- # http://bugs.python.org/issue10272
- if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6
- raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
-
- def _make_request(self, conn, method, url, timeout=_Default, chunked=False,
- **httplib_request_kw):
- """
- Perform a request on a given urllib connection object taken from our
- pool.
-
- :param conn:
- a connection from one of our connection pools
-
- :param timeout:
- Socket timeout in seconds for the request. This can be a
- float or integer, which will set the same timeout value for
- the socket connect and the socket read, or an instance of
- :class:`urllib3.util.Timeout`, which gives you more fine-grained
- control over your timeouts.
- """
- self.num_requests += 1
-
- timeout_obj = self._get_timeout(timeout)
- timeout_obj.start_connect()
- conn.timeout = timeout_obj.connect_timeout
-
- # Trigger any extra validation we need to do.
- try:
- self._validate_conn(conn)
- except (SocketTimeout, BaseSSLError) as e:
- # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.
- self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
- raise
-
- # conn.request() calls httplib.*.request, not the method in
- # urllib3.request. It also calls makefile (recv) on the socket.
- if chunked:
- conn.request_chunked(method, url, **httplib_request_kw)
- else:
- conn.request(method, url, **httplib_request_kw)
-
- # Reset the timeout for the recv() on the socket
- read_timeout = timeout_obj.read_timeout
-
- # App Engine doesn't have a sock attr
- if getattr(conn, 'sock', None):
- # In Python 3 socket.py will catch EAGAIN and return None when you
- # try and read into the file pointer created by http.client, which
- # instead raises a BadStatusLine exception. Instead of catching
- # the exception and assuming all BadStatusLine exceptions are read
- # timeouts, check for a zero timeout before making the request.
- if read_timeout == 0:
- raise ReadTimeoutError(
- self, url, "Read timed out. (read timeout=%s)" % read_timeout)
- if read_timeout is Timeout.DEFAULT_TIMEOUT:
- conn.sock.settimeout(socket.getdefaulttimeout())
- else: # None or a value
- conn.sock.settimeout(read_timeout)
-
- # Receive the response from the server
- try:
- try: # Python 2.7, use buffering of HTTP responses
- httplib_response = conn.getresponse(buffering=True)
- except TypeError: # Python 2.6 and older, Python 3
- try:
- httplib_response = conn.getresponse()
- except Exception as e:
- # Remove the TypeError from the exception chain in Python 3;
- # otherwise it looks like a programming error was the cause.
- six.raise_from(e, None)
- except (SocketTimeout, BaseSSLError, SocketError) as e:
- self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
- raise
-
- # AppEngine doesn't have a version attr.
- http_version = getattr(conn, '_http_vsn_str', 'HTTP/?')
- log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port,
- method, url, http_version, httplib_response.status,
- httplib_response.length)
-
- try:
- assert_header_parsing(httplib_response.msg)
- except HeaderParsingError as hpe: # Platform-specific: Python 3
- log.warning(
- 'Failed to parse headers (url=%s): %s',
- self._absolute_url(url), hpe, exc_info=True)
-
- return httplib_response
-
- def _absolute_url(self, path):
- return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url
-
- def close(self):
- """
- Close all pooled connections and disable the pool.
- """
- # Disable access to the pool
- old_pool, self.pool = self.pool, None
-
- try:
- while True:
- conn = old_pool.get(block=False)
- if conn:
- conn.close()
-
- except queue.Empty:
- pass # Done.
-
- def is_same_host(self, url):
- """
- Check if the given ``url`` is a member of the same host as this
- connection pool.
- """
- if url.startswith('/'):
- return True
-
- # TODO: Add optional support for socket.gethostbyname checking.
- scheme, host, port = get_host(url)
-
- host = _ipv6_host(host).lower()
-
- # Use explicit default port for comparison when none is given
- if self.port and not port:
- port = port_by_scheme.get(scheme)
- elif not self.port and port == port_by_scheme.get(scheme):
- port = None
-
- return (scheme, host, port) == (self.scheme, self.host, self.port)
-
- def urlopen(self, method, url, body=None, headers=None, retries=None,
- redirect=True, assert_same_host=True, timeout=_Default,
- pool_timeout=None, release_conn=None, chunked=False,
- body_pos=None, **response_kw):
- """
- Get a connection from the pool and perform an HTTP request. This is the
- lowest level call for making a request, so you'll need to specify all
- the raw details.
-
- .. note::
-
- More commonly, it's appropriate to use a convenience method provided
- by :class:`.RequestMethods`, such as :meth:`request`.
-
- .. note::
-
- `release_conn` will only behave as expected if
- `preload_content=False` because we want to make
- `preload_content=False` the default behaviour someday soon without
- breaking backwards compatibility.
-
- :param method:
- HTTP request method (such as GET, POST, PUT, etc.)
-
- :param body:
- Data to send in the request body (useful for creating
- POST requests, see HTTPConnectionPool.post_url for
- more convenience).
-
- :param headers:
- Dictionary of custom headers to send, such as User-Agent,
- If-None-Match, etc. If None, pool headers are used. If provided,
- these headers completely replace any pool-specific headers.
-
- :param retries:
- Configure the number of retries to allow before raising a
- :class:`~urllib3.exceptions.MaxRetryError` exception.
-
- Pass ``None`` to retry until you receive a response. Pass a
- :class:`~urllib3.util.retry.Retry` object for fine-grained control
- over different types of retries.
- Pass an integer number to retry connection errors that many times,
- but no other types of errors. Pass zero to never retry.
-
- If ``False``, then retries are disabled and any exception is raised
- immediately. Also, instead of raising a MaxRetryError on redirects,
- the redirect response will be returned.
-
- :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
-
- :param redirect:
- If True, automatically handle redirects (status codes 301, 302,
- 303, 307, 308). Each redirect counts as a retry. Disabling retries
- will disable redirect, too.
-
- :param assert_same_host:
- If ``True``, will make sure that the host of the pool requests is
- consistent else will raise HostChangedError. When False, you can
- use the pool on an HTTP proxy and request foreign hosts.
-
- :param timeout:
- If specified, overrides the default timeout for this one
- request. It may be a float (in seconds) or an instance of
- :class:`urllib3.util.Timeout`.
-
- :param pool_timeout:
- If set and the pool is set to block=True, then this method will
- block for ``pool_timeout`` seconds and raise EmptyPoolError if no
- connection is available within the time period.
-
- :param release_conn:
- If False, then the urlopen call will not release the connection
- back into the pool once a response is received (but will release if
- you read the entire contents of the response such as when
- `preload_content=True`). This is useful if you're not preloading
- the response's content immediately. You will need to call
- ``r.release_conn()`` on the response ``r`` to return the connection
- back into the pool. If None, it takes the value of
- ``response_kw.get('preload_content', True)``.
-
- :param chunked:
- If True, urllib3 will send the body using chunked transfer
- encoding. Otherwise, urllib3 will send the body using the standard
- content-length form. Defaults to False.
-
- :param int body_pos:
- Position to seek to in file-like body in the event of a retry or
- redirect. Typically this won't need to be set because urllib3 will
- auto-populate the value when needed.
-
- :param \\**response_kw:
- Additional parameters are passed to
- :meth:`urllib3.response.HTTPResponse.from_httplib`
- """
- if headers is None:
- headers = self.headers
-
- if not isinstance(retries, Retry):
- retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
-
- if release_conn is None:
- release_conn = response_kw.get('preload_content', True)
-
- # Check host
- if assert_same_host and not self.is_same_host(url):
- raise HostChangedError(self, url, retries)
-
- conn = None
-
- # Track whether `conn` needs to be released before
- # returning/raising/recursing. Update this variable if necessary, and
- # leave `release_conn` constant throughout the function. That way, if
- # the function recurses, the original value of `release_conn` will be
- # passed down into the recursive call, and its value will be respected.
- #
- # See issue #651 [1] for details.
- #
- # [1] <https://github.com/shazow/urllib3/issues/651>
- release_this_conn = release_conn
-
- # Merge the proxy headers. Only do this in HTTP. We have to copy the
- # headers dict so we can safely change it without those changes being
- # reflected in anyone else's copy.
- if self.scheme == 'http':
- headers = headers.copy()
- headers.update(self.proxy_headers)
-
- # Must keep the exception bound to a separate variable or else Python 3
- # complains about UnboundLocalError.
- err = None
-
- # Keep track of whether we cleanly exited the except block. This
- # ensures we do proper cleanup in finally.
- clean_exit = False
-
- # Rewind body position, if needed. Record current position
- # for future rewinds in the event of a redirect/retry.
- body_pos = set_file_position(body, body_pos)
-
- try:
- # Request a connection from the queue.
- timeout_obj = self._get_timeout(timeout)
- conn = self._get_conn(timeout=pool_timeout)
-
- conn.timeout = timeout_obj.connect_timeout
-
- is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None)
- if is_new_proxy_conn:
- self._prepare_proxy(conn)
-
- # Make the request on the httplib connection object.
- httplib_response = self._make_request(conn, method, url,
- timeout=timeout_obj,
- body=body, headers=headers,
- chunked=chunked)
-
- # If we're going to release the connection in ``finally:``, then
- # the response doesn't need to know about the connection. Otherwise
- # it will also try to release it and we'll have a double-release
- # mess.
- response_conn = conn if not release_conn else None
-
- # Pass method to Response for length checking
- response_kw['request_method'] = method
-
- # Import httplib's response into our own wrapper object
- response = self.ResponseCls.from_httplib(httplib_response,
- pool=self,
- connection=response_conn,
- retries=retries,
- **response_kw)
-
- # Everything went great!
- clean_exit = True
-
- except queue.Empty:
- # Timed out by queue.
- raise EmptyPoolError(self, "No pool connections are available.")
-
- except (BaseSSLError, CertificateError) as e:
- # Close the connection. If a connection is reused on which there
- # was a Certificate error, the next request will certainly raise
- # another Certificate error.
- clean_exit = False
- raise SSLError(e)
-
- except SSLError:
- # Treat SSLError separately from BaseSSLError to preserve
- # traceback.
- clean_exit = False
- raise
-
- except (TimeoutError, HTTPException, SocketError, ProtocolError) as e:
- # Discard the connection for these exceptions. It will be
- # be replaced during the next _get_conn() call.
- clean_exit = False
-
- if isinstance(e, (SocketError, NewConnectionError)) and self.proxy:
- e = ProxyError('Cannot connect to proxy.', e)
- elif isinstance(e, (SocketError, HTTPException)):
- e = ProtocolError('Connection aborted.', e)
-
- retries = retries.increment(method, url, error=e, _pool=self,
- _stacktrace=sys.exc_info()[2])
- retries.sleep()
-
- # Keep track of the error for the retry warning.
- err = e
-
- finally:
- if not clean_exit:
- # We hit some kind of exception, handled or otherwise. We need
- # to throw the connection away unless explicitly told not to.
- # Close the connection, set the variable to None, and make sure
- # we put the None back in the pool to avoid leaking it.
- conn = conn and conn.close()
- release_this_conn = True
-
- if release_this_conn:
- # Put the connection back to be reused. If the connection is
- # expired then it will be None, which will get replaced with a
- # fresh connection during _get_conn.
- self._put_conn(conn)
-
- if not conn:
- # Try again
- log.warning("Retrying (%r) after connection "
- "broken by '%r': %s", retries, err, url)
- return self.urlopen(method, url, body, headers, retries,
- redirect, assert_same_host,
- timeout=timeout, pool_timeout=pool_timeout,
- release_conn=release_conn, body_pos=body_pos,
- **response_kw)
-
- # Handle redirect?
- redirect_location = redirect and response.get_redirect_location()
- if redirect_location:
- if response.status == 303:
- method = 'GET'
-
- try:
- retries = retries.increment(method, url, response=response, _pool=self)
- except MaxRetryError:
- if retries.raise_on_redirect:
- # Release the connection for this response, since we're not
- # returning it to be released manually.
- response.release_conn()
- raise
- return response
-
- retries.sleep_for_retry(response)
- log.debug("Redirecting %s -> %s", url, redirect_location)
- return self.urlopen(
- method, redirect_location, body, headers,
- retries=retries, redirect=redirect,
- assert_same_host=assert_same_host,
- timeout=timeout, pool_timeout=pool_timeout,
- release_conn=release_conn, body_pos=body_pos,
- **response_kw)
-
- # Check if we should retry the HTTP response.
- has_retry_after = bool(response.getheader('Retry-After'))
- if retries.is_retry(method, response.status, has_retry_after):
- try:
- retries = retries.increment(method, url, response=response, _pool=self)
- except MaxRetryError:
- if retries.raise_on_status:
- # Release the connection for this response, since we're not
- # returning it to be released manually.
- response.release_conn()
- raise
- return response
- retries.sleep(response)
- log.debug("Retry: %s", url)
- return self.urlopen(
- method, url, body, headers,
- retries=retries, redirect=redirect,
- assert_same_host=assert_same_host,
- timeout=timeout, pool_timeout=pool_timeout,
- release_conn=release_conn,
- body_pos=body_pos, **response_kw)
-
- return response
-
-
-class HTTPSConnectionPool(HTTPConnectionPool):
- """
- Same as :class:`.HTTPConnectionPool`, but HTTPS.
-
- When Python is compiled with the :mod:`ssl` module, then
- :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates,
- instead of :class:`.HTTPSConnection`.
-
- :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``,
- ``assert_hostname`` and ``host`` in this order to verify connections.
- If ``assert_hostname`` is False, no verification is done.
-
- The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``,
- ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is
- available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade
- the connection socket into an SSL socket.
- """
-
- scheme = 'https'
- ConnectionCls = HTTPSConnection
-
- def __init__(self, host, port=None,
- strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1,
- block=False, headers=None, retries=None,
- _proxy=None, _proxy_headers=None,
- key_file=None, cert_file=None, cert_reqs=None,
- ca_certs=None, ssl_version=None,
- assert_hostname=None, assert_fingerprint=None,
- ca_cert_dir=None, **conn_kw):
-
- HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize,
- block, headers, retries, _proxy, _proxy_headers,
- **conn_kw)
-
- if ca_certs and cert_reqs is None:
- cert_reqs = 'CERT_REQUIRED'
-
- self.key_file = key_file
- self.cert_file = cert_file
- self.cert_reqs = cert_reqs
- self.ca_certs = ca_certs
- self.ca_cert_dir = ca_cert_dir
- self.ssl_version = ssl_version
- self.assert_hostname = assert_hostname
- self.assert_fingerprint = assert_fingerprint
-
- def _prepare_conn(self, conn):
- """
- Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket`
- and establish the tunnel if proxy is used.
- """
-
- if isinstance(conn, VerifiedHTTPSConnection):
- conn.set_cert(key_file=self.key_file,
- cert_file=self.cert_file,
- cert_reqs=self.cert_reqs,
- ca_certs=self.ca_certs,
- ca_cert_dir=self.ca_cert_dir,
- assert_hostname=self.assert_hostname,
- assert_fingerprint=self.assert_fingerprint)
- conn.ssl_version = self.ssl_version
- return conn
-
- def _prepare_proxy(self, conn):
- """
- Establish tunnel connection early, because otherwise httplib
- would improperly set Host: header to proxy's IP:port.
- """
- # Python 2.7+
- try:
- set_tunnel = conn.set_tunnel
- except AttributeError: # Platform-specific: Python 2.6
- set_tunnel = conn._set_tunnel
-
- if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older
- set_tunnel(self.host, self.port)
- else:
- set_tunnel(self.host, self.port, self.proxy_headers)
-
- conn.connect()
-
- def _new_conn(self):
- """
- Return a fresh :class:`httplib.HTTPSConnection`.
- """
- self.num_connections += 1
- log.debug("Starting new HTTPS connection (%d): %s",
- self.num_connections, self.host)
-
- if not self.ConnectionCls or self.ConnectionCls is DummyConnection:
- raise SSLError("Can't connect to HTTPS URL because the SSL "
- "module is not available.")
-
- actual_host = self.host
- actual_port = self.port
- if self.proxy is not None:
- actual_host = self.proxy.host
- actual_port = self.proxy.port
-
- conn = self.ConnectionCls(host=actual_host, port=actual_port,
- timeout=self.timeout.connect_timeout,
- strict=self.strict, **self.conn_kw)
-
- return self._prepare_conn(conn)
-
- def _validate_conn(self, conn):
- """
- Called right before a request is made, after the socket is created.
- """
- super(HTTPSConnectionPool, self)._validate_conn(conn)
-
- # Force connect early to allow us to validate the connection.
- if not getattr(conn, 'sock', None): # AppEngine might not have `.sock`
- conn.connect()
-
- if not conn.is_verified:
- warnings.warn((
- 'Unverified HTTPS request is being made. '
- 'Adding certificate verification is strongly advised. See: '
- 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html'
- '#ssl-warnings'),
- InsecureRequestWarning)
-
-
-def connection_from_url(url, **kw):
- """
- Given a url, return an :class:`.ConnectionPool` instance of its host.
-
- This is a shortcut for not having to parse out the scheme, host, and port
- of the url before creating an :class:`.ConnectionPool` instance.
-
- :param url:
- Absolute URL string that must include the scheme. Port is optional.
-
- :param \\**kw:
- Passes additional parameters to the constructor of the appropriate
- :class:`.ConnectionPool`. Useful for specifying things like
- timeout, maxsize, headers, etc.
-
- Example::
-
- >>> conn = connection_from_url('http://google.com/')
- >>> r = conn.request('GET', '/')
- """
- scheme, host, port = get_host(url)
- port = port or port_by_scheme.get(scheme, 80)
- if scheme == 'https':
- return HTTPSConnectionPool(host, port=port, **kw)
- else:
- return HTTPConnectionPool(host, port=port, **kw)
-
-
-def _ipv6_host(host):
- """
- Process IPv6 address literals
- """
-
- # httplib doesn't like it when we include brackets in IPv6 addresses
- # Specifically, if we include brackets but also pass the port then
- # httplib crazily doubles up the square brackets on the Host header.
- # Instead, we need to make sure we never pass ``None`` as the port.
- # However, for backward compatibility reasons we can't actually
- # *assert* that. See http://bugs.python.org/issue28539
- #
- # Also if an IPv6 address literal has a zone identifier, the
- # percent sign might be URIencoded, convert it back into ASCII
- if host.startswith('[') and host.endswith(']'):
- host = host.replace('%25', '%').strip('[]')
- return host
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/appengine.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/appengine.py
deleted file mode 100644
index 814b0222..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/appengine.py
+++ /dev/null
@@ -1,296 +0,0 @@
-"""
-This module provides a pool manager that uses Google App Engine's
-`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
-
-Example usage::
-
- from urllib3 import PoolManager
- from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox
-
- if is_appengine_sandbox():
- # AppEngineManager uses AppEngine's URLFetch API behind the scenes
- http = AppEngineManager()
- else:
- # PoolManager uses a socket-level API behind the scenes
- http = PoolManager()
-
- r = http.request('GET', 'https://google.com/')
-
-There are `limitations <https://cloud.google.com/appengine/docs/python/\
-urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be
-the best choice for your application. There are three options for using
-urllib3 on Google App Engine:
-
-1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is
- cost-effective in many circumstances as long as your usage is within the
- limitations.
-2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets.
- Sockets also have `limitations and restrictions
- <https://cloud.google.com/appengine/docs/python/sockets/\
- #limitations-and-restrictions>`_ and have a lower free quota than URLFetch.
- To use sockets, be sure to specify the following in your ``app.yaml``::
-
- env_variables:
- GAE_USE_SOCKETS_HTTPLIB : 'true'
-
-3. If you are using `App Engine Flexible
-<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard
-:class:`PoolManager` without any configuration or special environment variables.
-"""
-
-from __future__ import absolute_import
-import logging
-import os
-import warnings
-from ..packages.six.moves.urllib.parse import urljoin
-
-from ..exceptions import (
- HTTPError,
- HTTPWarning,
- MaxRetryError,
- ProtocolError,
- TimeoutError,
- SSLError
-)
-
-from ..packages.six import BytesIO
-from ..request import RequestMethods
-from ..response import HTTPResponse
-from ..util.timeout import Timeout
-from ..util.retry import Retry
-
-try:
- from google.appengine.api import urlfetch
-except ImportError:
- urlfetch = None
-
-
-log = logging.getLogger(__name__)
-
-
-class AppEnginePlatformWarning(HTTPWarning):
- pass
-
-
-class AppEnginePlatformError(HTTPError):
- pass
-
-
-class AppEngineManager(RequestMethods):
- """
- Connection manager for Google App Engine sandbox applications.
-
- This manager uses the URLFetch service directly instead of using the
- emulated httplib, and is subject to URLFetch limitations as described in
- the App Engine documentation `here
- <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
-
- Notably it will raise an :class:`AppEnginePlatformError` if:
- * URLFetch is not available.
- * If you attempt to use this on App Engine Flexible, as full socket
- support is available.
- * If a request size is more than 10 megabytes.
- * If a response size is more than 32 megabtyes.
- * If you use an unsupported request method such as OPTIONS.
-
- Beyond those cases, it will raise normal urllib3 errors.
- """
-
- def __init__(self, headers=None, retries=None, validate_certificate=True,
- urlfetch_retries=True):
- if not urlfetch:
- raise AppEnginePlatformError(
- "URLFetch is not available in this environment.")
-
- if is_prod_appengine_mvms():
- raise AppEnginePlatformError(
- "Use normal urllib3.PoolManager instead of AppEngineManager"
- "on Managed VMs, as using URLFetch is not necessary in "
- "this environment.")
-
- warnings.warn(
- "urllib3 is using URLFetch on Google App Engine sandbox instead "
- "of sockets. To use sockets directly instead of URLFetch see "
- "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.",
- AppEnginePlatformWarning)
-
- RequestMethods.__init__(self, headers)
- self.validate_certificate = validate_certificate
- self.urlfetch_retries = urlfetch_retries
-
- self.retries = retries or Retry.DEFAULT
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- # Return False to re-raise any potential exceptions
- return False
-
- def urlopen(self, method, url, body=None, headers=None,
- retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT,
- **response_kw):
-
- retries = self._get_retries(retries, redirect)
-
- try:
- follow_redirects = (
- redirect and
- retries.redirect != 0 and
- retries.total)
- response = urlfetch.fetch(
- url,
- payload=body,
- method=method,
- headers=headers or {},
- allow_truncated=False,
- follow_redirects=self.urlfetch_retries and follow_redirects,
- deadline=self._get_absolute_timeout(timeout),
- validate_certificate=self.validate_certificate,
- )
- except urlfetch.DeadlineExceededError as e:
- raise TimeoutError(self, e)
-
- except urlfetch.InvalidURLError as e:
- if 'too large' in str(e):
- raise AppEnginePlatformError(
- "URLFetch request too large, URLFetch only "
- "supports requests up to 10mb in size.", e)
- raise ProtocolError(e)
-
- except urlfetch.DownloadError as e:
- if 'Too many redirects' in str(e):
- raise MaxRetryError(self, url, reason=e)
- raise ProtocolError(e)
-
- except urlfetch.ResponseTooLargeError as e:
- raise AppEnginePlatformError(
- "URLFetch response too large, URLFetch only supports"
- "responses up to 32mb in size.", e)
-
- except urlfetch.SSLCertificateError as e:
- raise SSLError(e)
-
- except urlfetch.InvalidMethodError as e:
- raise AppEnginePlatformError(
- "URLFetch does not support method: %s" % method, e)
-
- http_response = self._urlfetch_response_to_http_response(
- response, retries=retries, **response_kw)
-
- # Handle redirect?
- redirect_location = redirect and http_response.get_redirect_location()
- if redirect_location:
- # Check for redirect response
- if (self.urlfetch_retries and retries.raise_on_redirect):
- raise MaxRetryError(self, url, "too many redirects")
- else:
- if http_response.status == 303:
- method = 'GET'
-
- try:
- retries = retries.increment(method, url, response=http_response, _pool=self)
- except MaxRetryError:
- if retries.raise_on_redirect:
- raise MaxRetryError(self, url, "too many redirects")
- return http_response
-
- retries.sleep_for_retry(http_response)
- log.debug("Redirecting %s -> %s", url, redirect_location)
- redirect_url = urljoin(url, redirect_location)
- return self.urlopen(
- method, redirect_url, body, headers,
- retries=retries, redirect=redirect,
- timeout=timeout, **response_kw)
-
- # Check if we should retry the HTTP response.
- has_retry_after = bool(http_response.getheader('Retry-After'))
- if retries.is_retry(method, http_response.status, has_retry_after):
- retries = retries.increment(
- method, url, response=http_response, _pool=self)
- log.debug("Retry: %s", url)
- retries.sleep(http_response)
- return self.urlopen(
- method, url,
- body=body, headers=headers,
- retries=retries, redirect=redirect,
- timeout=timeout, **response_kw)
-
- return http_response
-
- def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw):
-
- if is_prod_appengine():
- # Production GAE handles deflate encoding automatically, but does
- # not remove the encoding header.
- content_encoding = urlfetch_resp.headers.get('content-encoding')
-
- if content_encoding == 'deflate':
- del urlfetch_resp.headers['content-encoding']
-
- transfer_encoding = urlfetch_resp.headers.get('transfer-encoding')
- # We have a full response's content,
- # so let's make sure we don't report ourselves as chunked data.
- if transfer_encoding == 'chunked':
- encodings = transfer_encoding.split(",")
- encodings.remove('chunked')
- urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings)
-
- return HTTPResponse(
- # In order for decoding to work, we must present the content as
- # a file-like object.
- body=BytesIO(urlfetch_resp.content),
- headers=urlfetch_resp.headers,
- status=urlfetch_resp.status_code,
- **response_kw
- )
-
- def _get_absolute_timeout(self, timeout):
- if timeout is Timeout.DEFAULT_TIMEOUT:
- return None # Defer to URLFetch's default.
- if isinstance(timeout, Timeout):
- if timeout._read is not None or timeout._connect is not None:
- warnings.warn(
- "URLFetch does not support granular timeout settings, "
- "reverting to total or default URLFetch timeout.",
- AppEnginePlatformWarning)
- return timeout.total
- return timeout
-
- def _get_retries(self, retries, redirect):
- if not isinstance(retries, Retry):
- retries = Retry.from_int(
- retries, redirect=redirect, default=self.retries)
-
- if retries.connect or retries.read or retries.redirect:
- warnings.warn(
- "URLFetch only supports total retries and does not "
- "recognize connect, read, or redirect retry parameters.",
- AppEnginePlatformWarning)
-
- return retries
-
-
-def is_appengine():
- return (is_local_appengine() or
- is_prod_appengine() or
- is_prod_appengine_mvms())
-
-
-def is_appengine_sandbox():
- return is_appengine() and not is_prod_appengine_mvms()
-
-
-def is_local_appengine():
- return ('APPENGINE_RUNTIME' in os.environ and
- 'Development/' in os.environ['SERVER_SOFTWARE'])
-
-
-def is_prod_appengine():
- return ('APPENGINE_RUNTIME' in os.environ and
- 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and
- not is_prod_appengine_mvms())
-
-
-def is_prod_appengine_mvms():
- return os.environ.get('GAE_VM', False) == 'true'
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/ntlmpool.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/ntlmpool.py
deleted file mode 100644
index 642e99ed..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/ntlmpool.py
+++ /dev/null
@@ -1,112 +0,0 @@
-"""
-NTLM authenticating pool, contributed by erikcederstran
-
-Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
-"""
-from __future__ import absolute_import
-
-from logging import getLogger
-from ntlm import ntlm
-
-from .. import HTTPSConnectionPool
-from ..packages.six.moves.http_client import HTTPSConnection
-
-
-log = getLogger(__name__)
-
-
-class NTLMConnectionPool(HTTPSConnectionPool):
- """
- Implements an NTLM authentication version of an urllib3 connection pool
- """
-
- scheme = 'https'
-
- def __init__(self, user, pw, authurl, *args, **kwargs):
- """
- authurl is a random URL on the server that is protected by NTLM.
- user is the Windows user, probably in the DOMAIN\\username format.
- pw is the password for the user.
- """
- super(NTLMConnectionPool, self).__init__(*args, **kwargs)
- self.authurl = authurl
- self.rawuser = user
- user_parts = user.split('\\', 1)
- self.domain = user_parts[0].upper()
- self.user = user_parts[1]
- self.pw = pw
-
- def _new_conn(self):
- # Performs the NTLM handshake that secures the connection. The socket
- # must be kept open while requests are performed.
- self.num_connections += 1
- log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s',
- self.num_connections, self.host, self.authurl)
-
- headers = {}
- headers['Connection'] = 'Keep-Alive'
- req_header = 'Authorization'
- resp_header = 'www-authenticate'
-
- conn = HTTPSConnection(host=self.host, port=self.port)
-
- # Send negotiation message
- headers[req_header] = (
- 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser))
- log.debug('Request headers: %s', headers)
- conn.request('GET', self.authurl, None, headers)
- res = conn.getresponse()
- reshdr = dict(res.getheaders())
- log.debug('Response status: %s %s', res.status, res.reason)
- log.debug('Response headers: %s', reshdr)
- log.debug('Response data: %s [...]', res.read(100))
-
- # Remove the reference to the socket, so that it can not be closed by
- # the response object (we want to keep the socket open)
- res.fp = None
-
- # Server should respond with a challenge message
- auth_header_values = reshdr[resp_header].split(', ')
- auth_header_value = None
- for s in auth_header_values:
- if s[:5] == 'NTLM ':
- auth_header_value = s[5:]
- if auth_header_value is None:
- raise Exception('Unexpected %s response header: %s' %
- (resp_header, reshdr[resp_header]))
-
- # Send authentication message
- ServerChallenge, NegotiateFlags = \
- ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value)
- auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge,
- self.user,
- self.domain,
- self.pw,
- NegotiateFlags)
- headers[req_header] = 'NTLM %s' % auth_msg
- log.debug('Request headers: %s', headers)
- conn.request('GET', self.authurl, None, headers)
- res = conn.getresponse()
- log.debug('Response status: %s %s', res.status, res.reason)
- log.debug('Response headers: %s', dict(res.getheaders()))
- log.debug('Response data: %s [...]', res.read()[:100])
- if res.status != 200:
- if res.status == 401:
- raise Exception('Server rejected request: wrong '
- 'username or password')
- raise Exception('Wrong server response: %s %s' %
- (res.status, res.reason))
-
- res.fp = None
- log.debug('Connection established')
- return conn
-
- def urlopen(self, method, url, body=None, headers=None, retries=3,
- redirect=True, assert_same_host=True):
- if headers is None:
- headers = {}
- headers['Connection'] = 'Keep-Alive'
- return super(NTLMConnectionPool, self).urlopen(method, url, body,
- headers, retries,
- redirect,
- assert_same_host)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/pyopenssl.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/pyopenssl.py
deleted file mode 100644
index eb4d4765..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/pyopenssl.py
+++ /dev/null
@@ -1,450 +0,0 @@
-"""
-SSL with SNI_-support for Python 2. Follow these instructions if you would
-like to verify SSL certificates in Python 2. Note, the default libraries do
-*not* do certificate checking; you need to do additional work to validate
-certificates yourself.
-
-This needs the following packages installed:
-
-* pyOpenSSL (tested with 16.0.0)
-* cryptography (minimum 1.3.4, from pyopenssl)
-* idna (minimum 2.0, from cryptography)
-
-However, pyopenssl depends on cryptography, which depends on idna, so while we
-use all three directly here we end up having relatively few packages required.
-
-You can install them with the following command:
-
- pip install pyopenssl cryptography idna
-
-To activate certificate checking, call
-:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
-before you begin making HTTP requests. This can be done in a ``sitecustomize``
-module, or at any other time before your application begins using ``urllib3``,
-like this::
-
- try:
- import urllib3.contrib.pyopenssl
- urllib3.contrib.pyopenssl.inject_into_urllib3()
- except ImportError:
- pass
-
-Now you can use :mod:`urllib3` as you normally would, and it will support SNI
-when the required modules are installed.
-
-Activating this module also has the positive side effect of disabling SSL/TLS
-compression in Python 2 (see `CRIME attack`_).
-
-If you want to configure the default list of supported cipher suites, you can
-set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.
-
-.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
-.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
-"""
-from __future__ import absolute_import
-
-import OpenSSL.SSL
-from cryptography import x509
-from cryptography.hazmat.backends.openssl import backend as openssl_backend
-from cryptography.hazmat.backends.openssl.x509 import _Certificate
-
-from socket import timeout, error as SocketError
-from io import BytesIO
-
-try: # Platform-specific: Python 2
- from socket import _fileobject
-except ImportError: # Platform-specific: Python 3
- _fileobject = None
- from ..packages.backports.makefile import backport_makefile
-
-import logging
-import ssl
-import six
-import sys
-
-from .. import util
-
-__all__ = ['inject_into_urllib3', 'extract_from_urllib3']
-
-# SNI always works.
-HAS_SNI = True
-
-# Map from urllib3 to PyOpenSSL compatible parameter-values.
-_openssl_versions = {
- ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD,
- ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
-}
-
-if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):
- _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD
-
-if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
- _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD
-
-try:
- _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})
-except AttributeError:
- pass
-
-_stdlib_to_openssl_verify = {
- ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
- ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
- ssl.CERT_REQUIRED:
- OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
-}
-_openssl_to_stdlib_verify = dict(
- (v, k) for k, v in _stdlib_to_openssl_verify.items()
-)
-
-# OpenSSL will only write 16K at a time
-SSL_WRITE_BLOCKSIZE = 16384
-
-orig_util_HAS_SNI = util.HAS_SNI
-orig_util_SSLContext = util.ssl_.SSLContext
-
-
-log = logging.getLogger(__name__)
-
-
-def inject_into_urllib3():
- 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.'
-
- _validate_dependencies_met()
-
- util.ssl_.SSLContext = PyOpenSSLContext
- util.HAS_SNI = HAS_SNI
- util.ssl_.HAS_SNI = HAS_SNI
- util.IS_PYOPENSSL = True
- util.ssl_.IS_PYOPENSSL = True
-
-
-def extract_from_urllib3():
- 'Undo monkey-patching by :func:`inject_into_urllib3`.'
-
- util.ssl_.SSLContext = orig_util_SSLContext
- util.HAS_SNI = orig_util_HAS_SNI
- util.ssl_.HAS_SNI = orig_util_HAS_SNI
- util.IS_PYOPENSSL = False
- util.ssl_.IS_PYOPENSSL = False
-
-
-def _validate_dependencies_met():
- """
- Verifies that PyOpenSSL's package-level dependencies have been met.
- Throws `ImportError` if they are not met.
- """
- # Method added in `cryptography==1.1`; not available in older versions
- from cryptography.x509.extensions import Extensions
- if getattr(Extensions, "get_extension_for_class", None) is None:
- raise ImportError("'cryptography' module missing required functionality. "
- "Try upgrading to v1.3.4 or newer.")
-
- # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
- # attribute is only present on those versions.
- from OpenSSL.crypto import X509
- x509 = X509()
- if getattr(x509, "_x509", None) is None:
- raise ImportError("'pyOpenSSL' module missing required functionality. "
- "Try upgrading to v0.14 or newer.")
-
-
-def _dnsname_to_stdlib(name):
- """
- Converts a dNSName SubjectAlternativeName field to the form used by the
- standard library on the given Python version.
-
- Cryptography produces a dNSName as a unicode string that was idna-decoded
- from ASCII bytes. We need to idna-encode that string to get it back, and
- then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib
- uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).
- """
- def idna_encode(name):
- """
- Borrowed wholesale from the Python Cryptography Project. It turns out
- that we can't just safely call `idna.encode`: it can explode for
- wildcard names. This avoids that problem.
- """
- import idna
-
- for prefix in [u'*.', u'.']:
- if name.startswith(prefix):
- name = name[len(prefix):]
- return prefix.encode('ascii') + idna.encode(name)
- return idna.encode(name)
-
- name = idna_encode(name)
- if sys.version_info >= (3, 0):
- name = name.decode('utf-8')
- return name
-
-
-def get_subj_alt_name(peer_cert):
- """
- Given an PyOpenSSL certificate, provides all the subject alternative names.
- """
- # Pass the cert to cryptography, which has much better APIs for this.
- # This is technically using private APIs, but should work across all
- # relevant versions until PyOpenSSL gets something proper for this.
- cert = _Certificate(openssl_backend, peer_cert._x509)
-
- # We want to find the SAN extension. Ask Cryptography to locate it (it's
- # faster than looping in Python)
- try:
- ext = cert.extensions.get_extension_for_class(
- x509.SubjectAlternativeName
- ).value
- except x509.ExtensionNotFound:
- # No such extension, return the empty list.
- return []
- except (x509.DuplicateExtension, x509.UnsupportedExtension,
- x509.UnsupportedGeneralNameType, UnicodeError) as e:
- # A problem has been found with the quality of the certificate. Assume
- # no SAN field is present.
- log.warning(
- "A problem was encountered with the certificate that prevented "
- "urllib3 from finding the SubjectAlternativeName field. This can "
- "affect certificate validation. The error was %s",
- e,
- )
- return []
-
- # We want to return dNSName and iPAddress fields. We need to cast the IPs
- # back to strings because the match_hostname function wants them as
- # strings.
- # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8
- # decoded. This is pretty frustrating, but that's what the standard library
- # does with certificates, and so we need to attempt to do the same.
- names = [
- ('DNS', _dnsname_to_stdlib(name))
- for name in ext.get_values_for_type(x509.DNSName)
- ]
- names.extend(
- ('IP Address', str(name))
- for name in ext.get_values_for_type(x509.IPAddress)
- )
-
- return names
-
-
-class WrappedSocket(object):
- '''API-compatibility wrapper for Python OpenSSL's Connection-class.
-
- Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
- collector of pypy.
- '''
-
- def __init__(self, connection, socket, suppress_ragged_eofs=True):
- self.connection = connection
- self.socket = socket
- self.suppress_ragged_eofs = suppress_ragged_eofs
- self._makefile_refs = 0
- self._closed = False
-
- def fileno(self):
- return self.socket.fileno()
-
- # Copy-pasted from Python 3.5 source code
- def _decref_socketios(self):
- if self._makefile_refs > 0:
- self._makefile_refs -= 1
- if self._closed:
- self.close()
-
- def recv(self, *args, **kwargs):
- try:
- data = self.connection.recv(*args, **kwargs)
- except OpenSSL.SSL.SysCallError as e:
- if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
- return b''
- else:
- raise SocketError(str(e))
- except OpenSSL.SSL.ZeroReturnError as e:
- if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
- return b''
- else:
- raise
- except OpenSSL.SSL.WantReadError:
- rd = util.wait_for_read(self.socket, self.socket.gettimeout())
- if not rd:
- raise timeout('The read operation timed out')
- else:
- return self.recv(*args, **kwargs)
- else:
- return data
-
- def recv_into(self, *args, **kwargs):
- try:
- return self.connection.recv_into(*args, **kwargs)
- except OpenSSL.SSL.SysCallError as e:
- if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
- return 0
- else:
- raise SocketError(str(e))
- except OpenSSL.SSL.ZeroReturnError as e:
- if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
- return 0
- else:
- raise
- except OpenSSL.SSL.WantReadError:
- rd = util.wait_for_read(self.socket, self.socket.gettimeout())
- if not rd:
- raise timeout('The read operation timed out')
- else:
- return self.recv_into(*args, **kwargs)
-
- def settimeout(self, timeout):
- return self.socket.settimeout(timeout)
-
- def _send_until_done(self, data):
- while True:
- try:
- return self.connection.send(data)
- except OpenSSL.SSL.WantWriteError:
- wr = util.wait_for_write(self.socket, self.socket.gettimeout())
- if not wr:
- raise timeout()
- continue
-
- def sendall(self, data):
- total_sent = 0
- while total_sent < len(data):
- sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE])
- total_sent += sent
-
- def shutdown(self):
- # FIXME rethrow compatible exceptions should we ever use this
- self.connection.shutdown()
-
- def close(self):
- if self._makefile_refs < 1:
- try:
- self._closed = True
- return self.connection.close()
- except OpenSSL.SSL.Error:
- return
- else:
- self._makefile_refs -= 1
-
- def getpeercert(self, binary_form=False):
- x509 = self.connection.get_peer_certificate()
-
- if not x509:
- return x509
-
- if binary_form:
- return OpenSSL.crypto.dump_certificate(
- OpenSSL.crypto.FILETYPE_ASN1,
- x509)
-
- return {
- 'subject': (
- (('commonName', x509.get_subject().CN),),
- ),
- 'subjectAltName': get_subj_alt_name(x509)
- }
-
- def _reuse(self):
- self._makefile_refs += 1
-
- def _drop(self):
- if self._makefile_refs < 1:
- self.close()
- else:
- self._makefile_refs -= 1
-
-
-if _fileobject: # Platform-specific: Python 2
- def makefile(self, mode, bufsize=-1):
- self._makefile_refs += 1
- return _fileobject(self, mode, bufsize, close=True)
-else: # Platform-specific: Python 3
- makefile = backport_makefile
-
-WrappedSocket.makefile = makefile
-
-
-class PyOpenSSLContext(object):
- """
- I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible
- for translating the interface of the standard library ``SSLContext`` object
- to calls into PyOpenSSL.
- """
- def __init__(self, protocol):
- self.protocol = _openssl_versions[protocol]
- self._ctx = OpenSSL.SSL.Context(self.protocol)
- self._options = 0
- self.check_hostname = False
-
- @property
- def options(self):
- return self._options
-
- @options.setter
- def options(self, value):
- self._options = value
- self._ctx.set_options(value)
-
- @property
- def verify_mode(self):
- return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]
-
- @verify_mode.setter
- def verify_mode(self, value):
- self._ctx.set_verify(
- _stdlib_to_openssl_verify[value],
- _verify_callback
- )
-
- def set_default_verify_paths(self):
- self._ctx.set_default_verify_paths()
-
- def set_ciphers(self, ciphers):
- if isinstance(ciphers, six.text_type):
- ciphers = ciphers.encode('utf-8')
- self._ctx.set_cipher_list(ciphers)
-
- def load_verify_locations(self, cafile=None, capath=None, cadata=None):
- if cafile is not None:
- cafile = cafile.encode('utf-8')
- if capath is not None:
- capath = capath.encode('utf-8')
- self._ctx.load_verify_locations(cafile, capath)
- if cadata is not None:
- self._ctx.load_verify_locations(BytesIO(cadata))
-
- def load_cert_chain(self, certfile, keyfile=None, password=None):
- self._ctx.use_certificate_file(certfile)
- if password is not None:
- self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password)
- self._ctx.use_privatekey_file(keyfile or certfile)
-
- def wrap_socket(self, sock, server_side=False,
- do_handshake_on_connect=True, suppress_ragged_eofs=True,
- server_hostname=None):
- cnx = OpenSSL.SSL.Connection(self._ctx, sock)
-
- if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3
- server_hostname = server_hostname.encode('utf-8')
-
- if server_hostname is not None:
- cnx.set_tlsext_host_name(server_hostname)
-
- cnx.set_connect_state()
-
- while True:
- try:
- cnx.do_handshake()
- except OpenSSL.SSL.WantReadError:
- rd = util.wait_for_read(sock, sock.gettimeout())
- if not rd:
- raise timeout('select timed out')
- continue
- except OpenSSL.SSL.Error as e:
- raise ssl.SSLError('bad handshake: %r' % e)
- break
-
- return WrappedSocket(cnx, sock)
-
-
-def _verify_callback(cnx, x509, err_no, err_depth, return_code):
- return err_no == 0
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/socks.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/socks.py
deleted file mode 100644
index 39e92fde..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/contrib/socks.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-This module contains provisional support for SOCKS proxies from within
-urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and
-SOCKS5. To enable its functionality, either install PySocks or install this
-module with the ``socks`` extra.
-
-The SOCKS implementation supports the full range of urllib3 features. It also
-supports the following SOCKS features:
-
-- SOCKS4
-- SOCKS4a
-- SOCKS5
-- Usernames and passwords for the SOCKS proxy
-
-Known Limitations:
-
-- Currently PySocks does not support contacting remote websites via literal
- IPv6 addresses. Any such connection attempt will fail. You must use a domain
- name.
-- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any
- such connection attempt will fail.
-"""
-from __future__ import absolute_import
-
-try:
- import socks
-except ImportError:
- import warnings
- from ..exceptions import DependencyWarning
-
- warnings.warn((
- 'SOCKS support in urllib3 requires the installation of optional '
- 'dependencies: specifically, PySocks. For more information, see '
- 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies'
- ),
- DependencyWarning
- )
- raise
-
-from socket import error as SocketError, timeout as SocketTimeout
-
-from ..connection import (
- HTTPConnection, HTTPSConnection
-)
-from ..connectionpool import (
- HTTPConnectionPool, HTTPSConnectionPool
-)
-from ..exceptions import ConnectTimeoutError, NewConnectionError
-from ..poolmanager import PoolManager
-from ..util.url import parse_url
-
-try:
- import ssl
-except ImportError:
- ssl = None
-
-
-class SOCKSConnection(HTTPConnection):
- """
- A plain-text HTTP connection that connects via a SOCKS proxy.
- """
- def __init__(self, *args, **kwargs):
- self._socks_options = kwargs.pop('_socks_options')
- super(SOCKSConnection, self).__init__(*args, **kwargs)
-
- def _new_conn(self):
- """
- Establish a new connection via the SOCKS proxy.
- """
- extra_kw = {}
- if self.source_address:
- extra_kw['source_address'] = self.source_address
-
- if self.socket_options:
- extra_kw['socket_options'] = self.socket_options
-
- try:
- conn = socks.create_connection(
- (self.host, self.port),
- proxy_type=self._socks_options['socks_version'],
- proxy_addr=self._socks_options['proxy_host'],
- proxy_port=self._socks_options['proxy_port'],
- proxy_username=self._socks_options['username'],
- proxy_password=self._socks_options['password'],
- proxy_rdns=self._socks_options['rdns'],
- timeout=self.timeout,
- **extra_kw
- )
-
- except SocketTimeout as e:
- raise ConnectTimeoutError(
- self, "Connection to %s timed out. (connect timeout=%s)" %
- (self.host, self.timeout))
-
- except socks.ProxyError as e:
- # This is fragile as hell, but it seems to be the only way to raise
- # useful errors here.
- if e.socket_err:
- error = e.socket_err
- if isinstance(error, SocketTimeout):
- raise ConnectTimeoutError(
- self,
- "Connection to %s timed out. (connect timeout=%s)" %
- (self.host, self.timeout)
- )
- else:
- raise NewConnectionError(
- self,
- "Failed to establish a new connection: %s" % error
- )
- else:
- raise NewConnectionError(
- self,
- "Failed to establish a new connection: %s" % e
- )
-
- except SocketError as e: # Defensive: PySocks should catch all these.
- raise NewConnectionError(
- self, "Failed to establish a new connection: %s" % e)
-
- return conn
-
-
-# We don't need to duplicate the Verified/Unverified distinction from
-# urllib3/connection.py here because the HTTPSConnection will already have been
-# correctly set to either the Verified or Unverified form by that module. This
-# means the SOCKSHTTPSConnection will automatically be the correct type.
-class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):
- pass
-
-
-class SOCKSHTTPConnectionPool(HTTPConnectionPool):
- ConnectionCls = SOCKSConnection
-
-
-class SOCKSHTTPSConnectionPool(HTTPSConnectionPool):
- ConnectionCls = SOCKSHTTPSConnection
-
-
-class SOCKSProxyManager(PoolManager):
- """
- A version of the urllib3 ProxyManager that routes connections via the
- defined SOCKS proxy.
- """
- pool_classes_by_scheme = {
- 'http': SOCKSHTTPConnectionPool,
- 'https': SOCKSHTTPSConnectionPool,
- }
-
- def __init__(self, proxy_url, username=None, password=None,
- num_pools=10, headers=None, **connection_pool_kw):
- parsed = parse_url(proxy_url)
-
- if parsed.scheme == 'socks5':
- socks_version = socks.PROXY_TYPE_SOCKS5
- rdns = False
- elif parsed.scheme == 'socks5h':
- socks_version = socks.PROXY_TYPE_SOCKS5
- rdns = True
- elif parsed.scheme == 'socks4':
- socks_version = socks.PROXY_TYPE_SOCKS4
- rdns = False
- elif parsed.scheme == 'socks4a':
- socks_version = socks.PROXY_TYPE_SOCKS4
- rdns = True
- else:
- raise ValueError(
- "Unable to determine SOCKS version from %s" % proxy_url
- )
-
- self.proxy_url = proxy_url
-
- socks_options = {
- 'socks_version': socks_version,
- 'proxy_host': parsed.host,
- 'proxy_port': parsed.port,
- 'username': username,
- 'password': password,
- 'rdns': rdns
- }
- connection_pool_kw['_socks_options'] = socks_options
-
- super(SOCKSProxyManager, self).__init__(
- num_pools, headers, **connection_pool_kw
- )
-
- self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/exceptions.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/exceptions.py
deleted file mode 100644
index 6c4be581..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/exceptions.py
+++ /dev/null
@@ -1,246 +0,0 @@
-from __future__ import absolute_import
-from .packages.six.moves.http_client import (
- IncompleteRead as httplib_IncompleteRead
-)
-# Base Exceptions
-
-
-class HTTPError(Exception):
- "Base exception used by this module."
- pass
-
-
-class HTTPWarning(Warning):
- "Base warning used by this module."
- pass
-
-
-class PoolError(HTTPError):
- "Base exception for errors caused within a pool."
- def __init__(self, pool, message):
- self.pool = pool
- HTTPError.__init__(self, "%s: %s" % (pool, message))
-
- def __reduce__(self):
- # For pickling purposes.
- return self.__class__, (None, None)
-
-
-class RequestError(PoolError):
- "Base exception for PoolErrors that have associated URLs."
- def __init__(self, pool, url, message):
- self.url = url
- PoolError.__init__(self, pool, message)
-
- def __reduce__(self):
- # For pickling purposes.
- return self.__class__, (None, self.url, None)
-
-
-class SSLError(HTTPError):
- "Raised when SSL certificate fails in an HTTPS connection."
- pass
-
-
-class ProxyError(HTTPError):
- "Raised when the connection to a proxy fails."
- pass
-
-
-class DecodeError(HTTPError):
- "Raised when automatic decoding based on Content-Type fails."
- pass
-
-
-class ProtocolError(HTTPError):
- "Raised when something unexpected happens mid-request/response."
- pass
-
-
-#: Renamed to ProtocolError but aliased for backwards compatibility.
-ConnectionError = ProtocolError
-
-
-# Leaf Exceptions
-
-class MaxRetryError(RequestError):
- """Raised when the maximum number of retries is exceeded.
-
- :param pool: The connection pool
- :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
- :param string url: The requested Url
- :param exceptions.Exception reason: The underlying error
-
- """
-
- def __init__(self, pool, url, reason=None):
- self.reason = reason
-
- message = "Max retries exceeded with url: %s (Caused by %r)" % (
- url, reason)
-
- RequestError.__init__(self, pool, url, message)
-
-
-class HostChangedError(RequestError):
- "Raised when an existing pool gets a request for a foreign host."
-
- def __init__(self, pool, url, retries=3):
- message = "Tried to open a foreign host with url: %s" % url
- RequestError.__init__(self, pool, url, message)
- self.retries = retries
-
-
-class TimeoutStateError(HTTPError):
- """ Raised when passing an invalid state to a timeout """
- pass
-
-
-class TimeoutError(HTTPError):
- """ Raised when a socket timeout error occurs.
-
- Catching this error will catch both :exc:`ReadTimeoutErrors
- <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`.
- """
- pass
-
-
-class ReadTimeoutError(TimeoutError, RequestError):
- "Raised when a socket timeout occurs while receiving data from a server"
- pass
-
-
-# This timeout error does not have a URL attached and needs to inherit from the
-# base HTTPError
-class ConnectTimeoutError(TimeoutError):
- "Raised when a socket timeout occurs while connecting to a server"
- pass
-
-
-class NewConnectionError(ConnectTimeoutError, PoolError):
- "Raised when we fail to establish a new connection. Usually ECONNREFUSED."
- pass
-
-
-class EmptyPoolError(PoolError):
- "Raised when a pool runs out of connections and no more are allowed."
- pass
-
-
-class ClosedPoolError(PoolError):
- "Raised when a request enters a pool after the pool has been closed."
- pass
-
-
-class LocationValueError(ValueError, HTTPError):
- "Raised when there is something wrong with a given URL input."
- pass
-
-
-class LocationParseError(LocationValueError):
- "Raised when get_host or similar fails to parse the URL input."
-
- def __init__(self, location):
- message = "Failed to parse: %s" % location
- HTTPError.__init__(self, message)
-
- self.location = location
-
-
-class ResponseError(HTTPError):
- "Used as a container for an error reason supplied in a MaxRetryError."
- GENERIC_ERROR = 'too many error responses'
- SPECIFIC_ERROR = 'too many {status_code} error responses'
-
-
-class SecurityWarning(HTTPWarning):
- "Warned when perfoming security reducing actions"
- pass
-
-
-class SubjectAltNameWarning(SecurityWarning):
- "Warned when connecting to a host with a certificate missing a SAN."
- pass
-
-
-class InsecureRequestWarning(SecurityWarning):
- "Warned when making an unverified HTTPS request."
- pass
-
-
-class SystemTimeWarning(SecurityWarning):
- "Warned when system time is suspected to be wrong"
- pass
-
-
-class InsecurePlatformWarning(SecurityWarning):
- "Warned when certain SSL configuration is not available on a platform."
- pass
-
-
-class SNIMissingWarning(HTTPWarning):
- "Warned when making a HTTPS request without SNI available."
- pass
-
-
-class DependencyWarning(HTTPWarning):
- """
- Warned when an attempt is made to import a module with missing optional
- dependencies.
- """
- pass
-
-
-class ResponseNotChunked(ProtocolError, ValueError):
- "Response needs to be chunked in order to read it as chunks."
- pass
-
-
-class BodyNotHttplibCompatible(HTTPError):
- """
- Body should be httplib.HTTPResponse like (have an fp attribute which
- returns raw chunks) for read_chunked().
- """
- pass
-
-
-class IncompleteRead(HTTPError, httplib_IncompleteRead):
- """
- Response length doesn't match expected Content-Length
-
- Subclass of http_client.IncompleteRead to allow int value
- for `partial` to avoid creating large objects on streamed
- reads.
- """
- def __init__(self, partial, expected):
- super(IncompleteRead, self).__init__(partial, expected)
-
- def __repr__(self):
- return ('IncompleteRead(%i bytes read, '
- '%i more expected)' % (self.partial, self.expected))
-
-
-class InvalidHeader(HTTPError):
- "The header provided was somehow invalid."
- pass
-
-
-class ProxySchemeUnknown(AssertionError, ValueError):
- "ProxyManager does not support the supplied scheme"
- # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.
-
- def __init__(self, scheme):
- message = "Not supported proxy scheme %s" % scheme
- super(ProxySchemeUnknown, self).__init__(message)
-
-
-class HeaderParsingError(HTTPError):
- "Raised by assert_header_parsing, but we convert it to a log.warning statement."
- def __init__(self, defects, unparsed_data):
- message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data)
- super(HeaderParsingError, self).__init__(message)
-
-
-class UnrewindableBodyError(HTTPError):
- "urllib3 encountered an error when trying to rewind a body"
- pass
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/fields.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/fields.py
deleted file mode 100644
index 19b0ae0c..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/fields.py
+++ /dev/null
@@ -1,178 +0,0 @@
-from __future__ import absolute_import
-import email.utils
-import mimetypes
-
-from .packages import six
-
-
-def guess_content_type(filename, default='application/octet-stream'):
- """
- Guess the "Content-Type" of a file.
-
- :param filename:
- The filename to guess the "Content-Type" of using :mod:`mimetypes`.
- :param default:
- If no "Content-Type" can be guessed, default to `default`.
- """
- if filename:
- return mimetypes.guess_type(filename)[0] or default
- return default
-
-
-def format_header_param(name, value):
- """
- Helper function to format and quote a single header parameter.
-
- Particularly useful for header parameters which might contain
- non-ASCII values, like file names. This follows RFC 2231, as
- suggested by RFC 2388 Section 4.4.
-
- :param name:
- The name of the parameter, a string expected to be ASCII only.
- :param value:
- The value of the parameter, provided as a unicode string.
- """
- if not any(ch in value for ch in '"\\\r\n'):
- result = '%s="%s"' % (name, value)
- try:
- result.encode('ascii')
- except (UnicodeEncodeError, UnicodeDecodeError):
- pass
- else:
- return result
- if not six.PY3 and isinstance(value, six.text_type): # Python 2:
- value = value.encode('utf-8')
- value = email.utils.encode_rfc2231(value, 'utf-8')
- value = '%s*=%s' % (name, value)
- return value
-
-
-class RequestField(object):
- """
- A data container for request body parameters.
-
- :param name:
- The name of this request field.
- :param data:
- The data/value body.
- :param filename:
- An optional filename of the request field.
- :param headers:
- An optional dict-like object of headers to initially use for the field.
- """
- def __init__(self, name, data, filename=None, headers=None):
- self._name = name
- self._filename = filename
- self.data = data
- self.headers = {}
- if headers:
- self.headers = dict(headers)
-
- @classmethod
- def from_tuples(cls, fieldname, value):
- """
- A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
-
- Supports constructing :class:`~urllib3.fields.RequestField` from
- parameter of key/value strings AND key/filetuple. A filetuple is a
- (filename, data, MIME type) tuple where the MIME type is optional.
- For example::
-
- 'foo': 'bar',
- 'fakefile': ('foofile.txt', 'contents of foofile'),
- 'realfile': ('barfile.txt', open('realfile').read()),
- 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
- 'nonamefile': 'contents of nonamefile field',
-
- Field names and filenames must be unicode.
- """
- if isinstance(value, tuple):
- if len(value) == 3:
- filename, data, content_type = value
- else:
- filename, data = value
- content_type = guess_content_type(filename)
- else:
- filename = None
- content_type = None
- data = value
-
- request_param = cls(fieldname, data, filename=filename)
- request_param.make_multipart(content_type=content_type)
-
- return request_param
-
- def _render_part(self, name, value):
- """
- Overridable helper function to format a single header parameter.
-
- :param name:
- The name of the parameter, a string expected to be ASCII only.
- :param value:
- The value of the parameter, provided as a unicode string.
- """
- return format_header_param(name, value)
-
- def _render_parts(self, header_parts):
- """
- Helper function to format and quote a single header.
-
- Useful for single headers that are composed of multiple items. E.g.,
- 'Content-Disposition' fields.
-
- :param header_parts:
- A sequence of (k, v) typles or a :class:`dict` of (k, v) to format
- as `k1="v1"; k2="v2"; ...`.
- """
- parts = []
- iterable = header_parts
- if isinstance(header_parts, dict):
- iterable = header_parts.items()
-
- for name, value in iterable:
- if value is not None:
- parts.append(self._render_part(name, value))
-
- return '; '.join(parts)
-
- def render_headers(self):
- """
- Renders the headers for this request field.
- """
- lines = []
-
- sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location']
- for sort_key in sort_keys:
- if self.headers.get(sort_key, False):
- lines.append('%s: %s' % (sort_key, self.headers[sort_key]))
-
- for header_name, header_value in self.headers.items():
- if header_name not in sort_keys:
- if header_value:
- lines.append('%s: %s' % (header_name, header_value))
-
- lines.append('\r\n')
- return '\r\n'.join(lines)
-
- def make_multipart(self, content_disposition=None, content_type=None,
- content_location=None):
- """
- Makes this request field into a multipart request field.
-
- This method overrides "Content-Disposition", "Content-Type" and
- "Content-Location" headers to the request parameter.
-
- :param content_type:
- The 'Content-Type' of the request body.
- :param content_location:
- The 'Content-Location' of the request body.
-
- """
- self.headers['Content-Disposition'] = content_disposition or 'form-data'
- self.headers['Content-Disposition'] += '; '.join([
- '', self._render_parts(
- (('name', self._name), ('filename', self._filename))
- )
- ])
- self.headers['Content-Type'] = content_type
- self.headers['Content-Location'] = content_location
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/filepost.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/filepost.py
deleted file mode 100644
index cd11cee4..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/filepost.py
+++ /dev/null
@@ -1,94 +0,0 @@
-from __future__ import absolute_import
-import codecs
-
-from uuid import uuid4
-from io import BytesIO
-
-from .packages import six
-from .packages.six import b
-from .fields import RequestField
-
-writer = codecs.lookup('utf-8')[3]
-
-
-def choose_boundary():
- """
- Our embarrassingly-simple replacement for mimetools.choose_boundary.
- """
- return uuid4().hex
-
-
-def iter_field_objects(fields):
- """
- Iterate over fields.
-
- Supports list of (k, v) tuples and dicts, and lists of
- :class:`~urllib3.fields.RequestField`.
-
- """
- if isinstance(fields, dict):
- i = six.iteritems(fields)
- else:
- i = iter(fields)
-
- for field in i:
- if isinstance(field, RequestField):
- yield field
- else:
- yield RequestField.from_tuples(*field)
-
-
-def iter_fields(fields):
- """
- .. deprecated:: 1.6
-
- Iterate over fields.
-
- The addition of :class:`~urllib3.fields.RequestField` makes this function
- obsolete. Instead, use :func:`iter_field_objects`, which returns
- :class:`~urllib3.fields.RequestField` objects.
-
- Supports list of (k, v) tuples and dicts.
- """
- if isinstance(fields, dict):
- return ((k, v) for k, v in six.iteritems(fields))
-
- return ((k, v) for k, v in fields)
-
-
-def encode_multipart_formdata(fields, boundary=None):
- """
- Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
-
- :param fields:
- Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
-
- :param boundary:
- If not specified, then a random boundary will be generated using
- :func:`mimetools.choose_boundary`.
- """
- body = BytesIO()
- if boundary is None:
- boundary = choose_boundary()
-
- for field in iter_field_objects(fields):
- body.write(b('--%s\r\n' % (boundary)))
-
- writer(body).write(field.render_headers())
- data = field.data
-
- if isinstance(data, int):
- data = str(data) # Backwards compatibility
-
- if isinstance(data, six.text_type):
- writer(body).write(data)
- else:
- body.write(data)
-
- body.write(b'\r\n')
-
- body.write(b('--%s--\r\n' % (boundary)))
-
- content_type = str('multipart/form-data; boundary=%s' % boundary)
-
- return body.getvalue(), content_type
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/__init__.py
deleted file mode 100644
index 170e974c..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from __future__ import absolute_import
-
-from . import ssl_match_hostname
-
-__all__ = ('ssl_match_hostname', )
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/makefile.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/makefile.py
deleted file mode 100644
index 75b80dcf..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/backports/makefile.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-backports.makefile
-~~~~~~~~~~~~~~~~~~
-
-Backports the Python 3 ``socket.makefile`` method for use with anything that
-wants to create a "fake" socket object.
-"""
-import io
-
-from socket import SocketIO
-
-
-def backport_makefile(self, mode="r", buffering=None, encoding=None,
- errors=None, newline=None):
- """
- Backport of ``socket.makefile`` from Python 3.5.
- """
- if not set(mode) <= set(["r", "w", "b"]):
- raise ValueError(
- "invalid mode %r (only r, w, b allowed)" % (mode,)
- )
- writing = "w" in mode
- reading = "r" in mode or not writing
- assert reading or writing
- binary = "b" in mode
- rawmode = ""
- if reading:
- rawmode += "r"
- if writing:
- rawmode += "w"
- raw = SocketIO(self, rawmode)
- self._makefile_refs += 1
- if buffering is None:
- buffering = -1
- if buffering < 0:
- buffering = io.DEFAULT_BUFFER_SIZE
- if buffering == 0:
- if not binary:
- raise ValueError("unbuffered streams must be binary")
- return raw
- if reading and writing:
- buffer = io.BufferedRWPair(raw, raw, buffering)
- elif reading:
- buffer = io.BufferedReader(raw, buffering)
- else:
- assert writing
- buffer = io.BufferedWriter(raw, buffering)
- if binary:
- return buffer
- text = io.TextIOWrapper(buffer, encoding, errors, newline)
- text.mode = mode
- return text
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ordered_dict.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ordered_dict.py
deleted file mode 100644
index 4479363c..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ordered_dict.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
-# Passes Python2.7's test suite and incorporates all the latest updates.
-# Copyright 2009 Raymond Hettinger, released under the MIT License.
-# http://code.activestate.com/recipes/576693/
-try:
- from thread import get_ident as _get_ident
-except ImportError:
- from dummy_thread import get_ident as _get_ident
-
-try:
- from _abcoll import KeysView, ValuesView, ItemsView
-except ImportError:
- pass
-
-
-class OrderedDict(dict):
- 'Dictionary that remembers insertion order'
- # An inherited dict maps keys to values.
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
- # The remaining methods are order-aware.
- # Big-O running times for all methods are the same as for regular dictionaries.
-
- # The internal self.__map dictionary maps keys to links in a doubly linked list.
- # The circular doubly linked list starts and ends with a sentinel element.
- # The sentinel element never gets deleted (this simplifies the algorithm).
- # Each link is stored as a list of length three: [PREV, NEXT, KEY].
-
- def __init__(self, *args, **kwds):
- '''Initialize an ordered dictionary. Signature is the same as for
- regular dictionaries, but keyword arguments are not recommended
- because their insertion order is arbitrary.
-
- '''
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__root
- except AttributeError:
- self.__root = root = [] # sentinel node
- root[:] = [root, root, None]
- self.__map = {}
- self.__update(*args, **kwds)
-
- def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
- 'od.__setitem__(i, y) <==> od[i]=y'
- # Setting a new item creates a new link which goes at the end of the linked
- # list, and the inherited dictionary is updated with the new key/value pair.
- if key not in self:
- root = self.__root
- last = root[0]
- last[1] = root[0] = self.__map[key] = [last, root, key]
- dict_setitem(self, key, value)
-
- def __delitem__(self, key, dict_delitem=dict.__delitem__):
- 'od.__delitem__(y) <==> del od[y]'
- # Deleting an existing item uses self.__map to find the link which is
- # then removed by updating the links in the predecessor and successor nodes.
- dict_delitem(self, key)
- link_prev, link_next, key = self.__map.pop(key)
- link_prev[1] = link_next
- link_next[0] = link_prev
-
- def __iter__(self):
- 'od.__iter__() <==> iter(od)'
- root = self.__root
- curr = root[1]
- while curr is not root:
- yield curr[2]
- curr = curr[1]
-
- def __reversed__(self):
- 'od.__reversed__() <==> reversed(od)'
- root = self.__root
- curr = root[0]
- while curr is not root:
- yield curr[2]
- curr = curr[0]
-
- def clear(self):
- 'od.clear() -> None. Remove all items from od.'
- try:
- for node in self.__map.itervalues():
- del node[:]
- root = self.__root
- root[:] = [root, root, None]
- self.__map.clear()
- except AttributeError:
- pass
- dict.clear(self)
-
- def popitem(self, last=True):
- '''od.popitem() -> (k, v), return and remove a (key, value) pair.
- Pairs are returned in LIFO order if last is true or FIFO order if false.
-
- '''
- if not self:
- raise KeyError('dictionary is empty')
- root = self.__root
- if last:
- link = root[0]
- link_prev = link[0]
- link_prev[1] = root
- root[0] = link_prev
- else:
- link = root[1]
- link_next = link[1]
- root[1] = link_next
- link_next[0] = root
- key = link[2]
- del self.__map[key]
- value = dict.pop(self, key)
- return key, value
-
- # -- the following methods do not depend on the internal structure --
-
- def keys(self):
- 'od.keys() -> list of keys in od'
- return list(self)
-
- def values(self):
- 'od.values() -> list of values in od'
- return [self[key] for key in self]
-
- def items(self):
- 'od.items() -> list of (key, value) pairs in od'
- return [(key, self[key]) for key in self]
-
- def iterkeys(self):
- 'od.iterkeys() -> an iterator over the keys in od'
- return iter(self)
-
- def itervalues(self):
- 'od.itervalues -> an iterator over the values in od'
- for k in self:
- yield self[k]
-
- def iteritems(self):
- 'od.iteritems -> an iterator over the (key, value) items in od'
- for k in self:
- yield (k, self[k])
-
- def update(*args, **kwds):
- '''od.update(E, **F) -> None. Update od from dict/iterable E and F.
-
- If E is a dict instance, does: for k in E: od[k] = E[k]
- If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
- Or if E is an iterable of items, does: for k, v in E: od[k] = v
- In either case, this is followed by: for k, v in F.items(): od[k] = v
-
- '''
- if len(args) > 2:
- raise TypeError('update() takes at most 2 positional '
- 'arguments (%d given)' % (len(args),))
- elif not args:
- raise TypeError('update() takes at least 1 argument (0 given)')
- self = args[0]
- # Make progressively weaker assumptions about "other"
- other = ()
- if len(args) == 2:
- other = args[1]
- if isinstance(other, dict):
- for key in other:
- self[key] = other[key]
- elif hasattr(other, 'keys'):
- for key in other.keys():
- self[key] = other[key]
- else:
- for key, value in other:
- self[key] = value
- for key, value in kwds.items():
- self[key] = value
-
- __update = update # let subclasses override update without breaking __init__
-
- __marker = object()
-
- def pop(self, key, default=__marker):
- '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
- If key is not found, d is returned if given, otherwise KeyError is raised.
-
- '''
- if key in self:
- result = self[key]
- del self[key]
- return result
- if default is self.__marker:
- raise KeyError(key)
- return default
-
- def setdefault(self, key, default=None):
- 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
- if key in self:
- return self[key]
- self[key] = default
- return default
-
- def __repr__(self, _repr_running={}):
- 'od.__repr__() <==> repr(od)'
- call_key = id(self), _get_ident()
- if call_key in _repr_running:
- return '...'
- _repr_running[call_key] = 1
- try:
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
- finally:
- del _repr_running[call_key]
-
- def __reduce__(self):
- 'Return state information for pickling'
- items = [[k, self[k]] for k in self]
- inst_dict = vars(self).copy()
- for k in vars(OrderedDict()):
- inst_dict.pop(k, None)
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def copy(self):
- 'od.copy() -> a shallow copy of od'
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
- and values equal to v (which defaults to None).
-
- '''
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
- while comparison to a regular mapping is order-insensitive.
-
- '''
- if isinstance(other, OrderedDict):
- return len(self)==len(other) and self.items() == other.items()
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
-
- # -- the following methods are only used in Python 2.7 --
-
- def viewkeys(self):
- "od.viewkeys() -> a set-like object providing a view on od's keys"
- return KeysView(self)
-
- def viewvalues(self):
- "od.viewvalues() -> an object providing a view on od's values"
- return ValuesView(self)
-
- def viewitems(self):
- "od.viewitems() -> a set-like object providing a view on od's items"
- return ItemsView(self)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/six.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/six.py
deleted file mode 100644
index 190c0239..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/six.py
+++ /dev/null
@@ -1,868 +0,0 @@
-"""Utilities for writing code that runs on Python 2 and 3"""
-
-# Copyright (c) 2010-2015 Benjamin Peterson
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from __future__ import absolute_import
-
-import functools
-import itertools
-import operator
-import sys
-import types
-
-__author__ = "Benjamin Peterson <benjamin@python.org>"
-__version__ = "1.10.0"
-
-
-# Useful for very coarse version differentiation.
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
-PY34 = sys.version_info[0:2] >= (3, 4)
-
-if PY3:
- string_types = str,
- integer_types = int,
- class_types = type,
- text_type = str
- binary_type = bytes
-
- MAXSIZE = sys.maxsize
-else:
- string_types = basestring,
- integer_types = (int, long)
- class_types = (type, types.ClassType)
- text_type = unicode
- binary_type = str
-
- if sys.platform.startswith("java"):
- # Jython always uses 32 bits.
- MAXSIZE = int((1 << 31) - 1)
- else:
- # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
- class X(object):
-
- def __len__(self):
- return 1 << 31
- try:
- len(X())
- except OverflowError:
- # 32-bit
- MAXSIZE = int((1 << 31) - 1)
- else:
- # 64-bit
- MAXSIZE = int((1 << 63) - 1)
- del X
-
-
-def _add_doc(func, doc):
- """Add documentation to a function."""
- func.__doc__ = doc
-
-
-def _import_module(name):
- """Import module, returning the module after the last dot."""
- __import__(name)
- return sys.modules[name]
-
-
-class _LazyDescr(object):
-
- def __init__(self, name):
- self.name = name
-
- def __get__(self, obj, tp):
- result = self._resolve()
- setattr(obj, self.name, result) # Invokes __set__.
- try:
- # This is a bit ugly, but it avoids running this again by
- # removing this descriptor.
- delattr(obj.__class__, self.name)
- except AttributeError:
- pass
- return result
-
-
-class MovedModule(_LazyDescr):
-
- def __init__(self, name, old, new=None):
- super(MovedModule, self).__init__(name)
- if PY3:
- if new is None:
- new = name
- self.mod = new
- else:
- self.mod = old
-
- def _resolve(self):
- return _import_module(self.mod)
-
- def __getattr__(self, attr):
- _module = self._resolve()
- value = getattr(_module, attr)
- setattr(self, attr, value)
- return value
-
-
-class _LazyModule(types.ModuleType):
-
- def __init__(self, name):
- super(_LazyModule, self).__init__(name)
- self.__doc__ = self.__class__.__doc__
-
- def __dir__(self):
- attrs = ["__doc__", "__name__"]
- attrs += [attr.name for attr in self._moved_attributes]
- return attrs
-
- # Subclasses should override this
- _moved_attributes = []
-
-
-class MovedAttribute(_LazyDescr):
-
- def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
- super(MovedAttribute, self).__init__(name)
- if PY3:
- if new_mod is None:
- new_mod = name
- self.mod = new_mod
- if new_attr is None:
- if old_attr is None:
- new_attr = name
- else:
- new_attr = old_attr
- self.attr = new_attr
- else:
- self.mod = old_mod
- if old_attr is None:
- old_attr = name
- self.attr = old_attr
-
- def _resolve(self):
- module = _import_module(self.mod)
- return getattr(module, self.attr)
-
-
-class _SixMetaPathImporter(object):
-
- """
- A meta path importer to import six.moves and its submodules.
-
- This class implements a PEP302 finder and loader. It should be compatible
- with Python 2.5 and all existing versions of Python3
- """
-
- def __init__(self, six_module_name):
- self.name = six_module_name
- self.known_modules = {}
-
- def _add_module(self, mod, *fullnames):
- for fullname in fullnames:
- self.known_modules[self.name + "." + fullname] = mod
-
- def _get_module(self, fullname):
- return self.known_modules[self.name + "." + fullname]
-
- def find_module(self, fullname, path=None):
- if fullname in self.known_modules:
- return self
- return None
-
- def __get_module(self, fullname):
- try:
- return self.known_modules[fullname]
- except KeyError:
- raise ImportError("This loader does not know module " + fullname)
-
- def load_module(self, fullname):
- try:
- # in case of a reload
- return sys.modules[fullname]
- except KeyError:
- pass
- mod = self.__get_module(fullname)
- if isinstance(mod, MovedModule):
- mod = mod._resolve()
- else:
- mod.__loader__ = self
- sys.modules[fullname] = mod
- return mod
-
- def is_package(self, fullname):
- """
- Return true, if the named module is a package.
-
- We need this method to get correct spec objects with
- Python 3.4 (see PEP451)
- """
- return hasattr(self.__get_module(fullname), "__path__")
-
- def get_code(self, fullname):
- """Return None
-
- Required, if is_package is implemented"""
- self.__get_module(fullname) # eventually raises ImportError
- return None
- get_source = get_code # same as get_code
-
-_importer = _SixMetaPathImporter(__name__)
-
-
-class _MovedItems(_LazyModule):
-
- """Lazy loading of moved objects"""
- __path__ = [] # mark as package
-
-
-_moved_attributes = [
- MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
- MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
- MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
- MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
- MovedAttribute("intern", "__builtin__", "sys"),
- MovedAttribute("map", "itertools", "builtins", "imap", "map"),
- MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
- MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
- MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
- MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
- MovedAttribute("reduce", "__builtin__", "functools"),
- MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
- MovedAttribute("StringIO", "StringIO", "io"),
- MovedAttribute("UserDict", "UserDict", "collections"),
- MovedAttribute("UserList", "UserList", "collections"),
- MovedAttribute("UserString", "UserString", "collections"),
- MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
- MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
- MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
- MovedModule("builtins", "__builtin__"),
- MovedModule("configparser", "ConfigParser"),
- MovedModule("copyreg", "copy_reg"),
- MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
- MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
- MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
- MovedModule("http_cookies", "Cookie", "http.cookies"),
- MovedModule("html_entities", "htmlentitydefs", "html.entities"),
- MovedModule("html_parser", "HTMLParser", "html.parser"),
- MovedModule("http_client", "httplib", "http.client"),
- MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
- MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
- MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
- MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
- MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
- MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
- MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
- MovedModule("cPickle", "cPickle", "pickle"),
- MovedModule("queue", "Queue"),
- MovedModule("reprlib", "repr"),
- MovedModule("socketserver", "SocketServer"),
- MovedModule("_thread", "thread", "_thread"),
- MovedModule("tkinter", "Tkinter"),
- MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
- MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
- MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
- MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
- MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
- MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
- MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
- MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
- MovedModule("tkinter_colorchooser", "tkColorChooser",
- "tkinter.colorchooser"),
- MovedModule("tkinter_commondialog", "tkCommonDialog",
- "tkinter.commondialog"),
- MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
- MovedModule("tkinter_font", "tkFont", "tkinter.font"),
- MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
- MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
- "tkinter.simpledialog"),
- MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
- MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
- MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
- MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
- MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
- MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
-]
-# Add windows specific modules.
-if sys.platform == "win32":
- _moved_attributes += [
- MovedModule("winreg", "_winreg"),
- ]
-
-for attr in _moved_attributes:
- setattr(_MovedItems, attr.name, attr)
- if isinstance(attr, MovedModule):
- _importer._add_module(attr, "moves." + attr.name)
-del attr
-
-_MovedItems._moved_attributes = _moved_attributes
-
-moves = _MovedItems(__name__ + ".moves")
-_importer._add_module(moves, "moves")
-
-
-class Module_six_moves_urllib_parse(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_parse"""
-
-
-_urllib_parse_moved_attributes = [
- MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
- MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
- MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
- MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
- MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
- MovedAttribute("urljoin", "urlparse", "urllib.parse"),
- MovedAttribute("urlparse", "urlparse", "urllib.parse"),
- MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
- MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
- MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
- MovedAttribute("quote", "urllib", "urllib.parse"),
- MovedAttribute("quote_plus", "urllib", "urllib.parse"),
- MovedAttribute("unquote", "urllib", "urllib.parse"),
- MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
- MovedAttribute("urlencode", "urllib", "urllib.parse"),
- MovedAttribute("splitquery", "urllib", "urllib.parse"),
- MovedAttribute("splittag", "urllib", "urllib.parse"),
- MovedAttribute("splituser", "urllib", "urllib.parse"),
- MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
- MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
- MovedAttribute("uses_params", "urlparse", "urllib.parse"),
- MovedAttribute("uses_query", "urlparse", "urllib.parse"),
- MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
-]
-for attr in _urllib_parse_moved_attributes:
- setattr(Module_six_moves_urllib_parse, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
- "moves.urllib_parse", "moves.urllib.parse")
-
-
-class Module_six_moves_urllib_error(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_error"""
-
-
-_urllib_error_moved_attributes = [
- MovedAttribute("URLError", "urllib2", "urllib.error"),
- MovedAttribute("HTTPError", "urllib2", "urllib.error"),
- MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
-]
-for attr in _urllib_error_moved_attributes:
- setattr(Module_six_moves_urllib_error, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
- "moves.urllib_error", "moves.urllib.error")
-
-
-class Module_six_moves_urllib_request(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_request"""
-
-
-_urllib_request_moved_attributes = [
- MovedAttribute("urlopen", "urllib2", "urllib.request"),
- MovedAttribute("install_opener", "urllib2", "urllib.request"),
- MovedAttribute("build_opener", "urllib2", "urllib.request"),
- MovedAttribute("pathname2url", "urllib", "urllib.request"),
- MovedAttribute("url2pathname", "urllib", "urllib.request"),
- MovedAttribute("getproxies", "urllib", "urllib.request"),
- MovedAttribute("Request", "urllib2", "urllib.request"),
- MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
- MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
- MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
- MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
- MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
- MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
- MovedAttribute("FileHandler", "urllib2", "urllib.request"),
- MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
- MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
- MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
- MovedAttribute("urlretrieve", "urllib", "urllib.request"),
- MovedAttribute("urlcleanup", "urllib", "urllib.request"),
- MovedAttribute("URLopener", "urllib", "urllib.request"),
- MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
- MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
-]
-for attr in _urllib_request_moved_attributes:
- setattr(Module_six_moves_urllib_request, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
- "moves.urllib_request", "moves.urllib.request")
-
-
-class Module_six_moves_urllib_response(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_response"""
-
-
-_urllib_response_moved_attributes = [
- MovedAttribute("addbase", "urllib", "urllib.response"),
- MovedAttribute("addclosehook", "urllib", "urllib.response"),
- MovedAttribute("addinfo", "urllib", "urllib.response"),
- MovedAttribute("addinfourl", "urllib", "urllib.response"),
-]
-for attr in _urllib_response_moved_attributes:
- setattr(Module_six_moves_urllib_response, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
- "moves.urllib_response", "moves.urllib.response")
-
-
-class Module_six_moves_urllib_robotparser(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_robotparser"""
-
-
-_urllib_robotparser_moved_attributes = [
- MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
-]
-for attr in _urllib_robotparser_moved_attributes:
- setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
- "moves.urllib_robotparser", "moves.urllib.robotparser")
-
-
-class Module_six_moves_urllib(types.ModuleType):
-
- """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
- __path__ = [] # mark as package
- parse = _importer._get_module("moves.urllib_parse")
- error = _importer._get_module("moves.urllib_error")
- request = _importer._get_module("moves.urllib_request")
- response = _importer._get_module("moves.urllib_response")
- robotparser = _importer._get_module("moves.urllib_robotparser")
-
- def __dir__(self):
- return ['parse', 'error', 'request', 'response', 'robotparser']
-
-_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
- "moves.urllib")
-
-
-def add_move(move):
- """Add an item to six.moves."""
- setattr(_MovedItems, move.name, move)
-
-
-def remove_move(name):
- """Remove item from six.moves."""
- try:
- delattr(_MovedItems, name)
- except AttributeError:
- try:
- del moves.__dict__[name]
- except KeyError:
- raise AttributeError("no such move, %r" % (name,))
-
-
-if PY3:
- _meth_func = "__func__"
- _meth_self = "__self__"
-
- _func_closure = "__closure__"
- _func_code = "__code__"
- _func_defaults = "__defaults__"
- _func_globals = "__globals__"
-else:
- _meth_func = "im_func"
- _meth_self = "im_self"
-
- _func_closure = "func_closure"
- _func_code = "func_code"
- _func_defaults = "func_defaults"
- _func_globals = "func_globals"
-
-
-try:
- advance_iterator = next
-except NameError:
- def advance_iterator(it):
- return it.next()
-next = advance_iterator
-
-
-try:
- callable = callable
-except NameError:
- def callable(obj):
- return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
-
-
-if PY3:
- def get_unbound_function(unbound):
- return unbound
-
- create_bound_method = types.MethodType
-
- def create_unbound_method(func, cls):
- return func
-
- Iterator = object
-else:
- def get_unbound_function(unbound):
- return unbound.im_func
-
- def create_bound_method(func, obj):
- return types.MethodType(func, obj, obj.__class__)
-
- def create_unbound_method(func, cls):
- return types.MethodType(func, None, cls)
-
- class Iterator(object):
-
- def next(self):
- return type(self).__next__(self)
-
- callable = callable
-_add_doc(get_unbound_function,
- """Get the function out of a possibly unbound function""")
-
-
-get_method_function = operator.attrgetter(_meth_func)
-get_method_self = operator.attrgetter(_meth_self)
-get_function_closure = operator.attrgetter(_func_closure)
-get_function_code = operator.attrgetter(_func_code)
-get_function_defaults = operator.attrgetter(_func_defaults)
-get_function_globals = operator.attrgetter(_func_globals)
-
-
-if PY3:
- def iterkeys(d, **kw):
- return iter(d.keys(**kw))
-
- def itervalues(d, **kw):
- return iter(d.values(**kw))
-
- def iteritems(d, **kw):
- return iter(d.items(**kw))
-
- def iterlists(d, **kw):
- return iter(d.lists(**kw))
-
- viewkeys = operator.methodcaller("keys")
-
- viewvalues = operator.methodcaller("values")
-
- viewitems = operator.methodcaller("items")
-else:
- def iterkeys(d, **kw):
- return d.iterkeys(**kw)
-
- def itervalues(d, **kw):
- return d.itervalues(**kw)
-
- def iteritems(d, **kw):
- return d.iteritems(**kw)
-
- def iterlists(d, **kw):
- return d.iterlists(**kw)
-
- viewkeys = operator.methodcaller("viewkeys")
-
- viewvalues = operator.methodcaller("viewvalues")
-
- viewitems = operator.methodcaller("viewitems")
-
-_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
-_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
-_add_doc(iteritems,
- "Return an iterator over the (key, value) pairs of a dictionary.")
-_add_doc(iterlists,
- "Return an iterator over the (key, [values]) pairs of a dictionary.")
-
-
-if PY3:
- def b(s):
- return s.encode("latin-1")
-
- def u(s):
- return s
- unichr = chr
- import struct
- int2byte = struct.Struct(">B").pack
- del struct
- byte2int = operator.itemgetter(0)
- indexbytes = operator.getitem
- iterbytes = iter
- import io
- StringIO = io.StringIO
- BytesIO = io.BytesIO
- _assertCountEqual = "assertCountEqual"
- if sys.version_info[1] <= 1:
- _assertRaisesRegex = "assertRaisesRegexp"
- _assertRegex = "assertRegexpMatches"
- else:
- _assertRaisesRegex = "assertRaisesRegex"
- _assertRegex = "assertRegex"
-else:
- def b(s):
- return s
- # Workaround for standalone backslash
-
- def u(s):
- return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
- unichr = unichr
- int2byte = chr
-
- def byte2int(bs):
- return ord(bs[0])
-
- def indexbytes(buf, i):
- return ord(buf[i])
- iterbytes = functools.partial(itertools.imap, ord)
- import StringIO
- StringIO = BytesIO = StringIO.StringIO
- _assertCountEqual = "assertItemsEqual"
- _assertRaisesRegex = "assertRaisesRegexp"
- _assertRegex = "assertRegexpMatches"
-_add_doc(b, """Byte literal""")
-_add_doc(u, """Text literal""")
-
-
-def assertCountEqual(self, *args, **kwargs):
- return getattr(self, _assertCountEqual)(*args, **kwargs)
-
-
-def assertRaisesRegex(self, *args, **kwargs):
- return getattr(self, _assertRaisesRegex)(*args, **kwargs)
-
-
-def assertRegex(self, *args, **kwargs):
- return getattr(self, _assertRegex)(*args, **kwargs)
-
-
-if PY3:
- exec_ = getattr(moves.builtins, "exec")
-
- def reraise(tp, value, tb=None):
- if value is None:
- value = tp()
- if value.__traceback__ is not tb:
- raise value.with_traceback(tb)
- raise value
-
-else:
- def exec_(_code_, _globs_=None, _locs_=None):
- """Execute code in a namespace."""
- if _globs_ is None:
- frame = sys._getframe(1)
- _globs_ = frame.f_globals
- if _locs_ is None:
- _locs_ = frame.f_locals
- del frame
- elif _locs_ is None:
- _locs_ = _globs_
- exec("""exec _code_ in _globs_, _locs_""")
-
- exec_("""def reraise(tp, value, tb=None):
- raise tp, value, tb
-""")
-
-
-if sys.version_info[:2] == (3, 2):
- exec_("""def raise_from(value, from_value):
- if from_value is None:
- raise value
- raise value from from_value
-""")
-elif sys.version_info[:2] > (3, 2):
- exec_("""def raise_from(value, from_value):
- raise value from from_value
-""")
-else:
- def raise_from(value, from_value):
- raise value
-
-
-print_ = getattr(moves.builtins, "print", None)
-if print_ is None:
- def print_(*args, **kwargs):
- """The new-style print function for Python 2.4 and 2.5."""
- fp = kwargs.pop("file", sys.stdout)
- if fp is None:
- return
-
- def write(data):
- if not isinstance(data, basestring):
- data = str(data)
- # If the file has an encoding, encode unicode with it.
- if (isinstance(fp, file) and
- isinstance(data, unicode) and
- fp.encoding is not None):
- errors = getattr(fp, "errors", None)
- if errors is None:
- errors = "strict"
- data = data.encode(fp.encoding, errors)
- fp.write(data)
- want_unicode = False
- sep = kwargs.pop("sep", None)
- if sep is not None:
- if isinstance(sep, unicode):
- want_unicode = True
- elif not isinstance(sep, str):
- raise TypeError("sep must be None or a string")
- end = kwargs.pop("end", None)
- if end is not None:
- if isinstance(end, unicode):
- want_unicode = True
- elif not isinstance(end, str):
- raise TypeError("end must be None or a string")
- if kwargs:
- raise TypeError("invalid keyword arguments to print()")
- if not want_unicode:
- for arg in args:
- if isinstance(arg, unicode):
- want_unicode = True
- break
- if want_unicode:
- newline = unicode("\n")
- space = unicode(" ")
- else:
- newline = "\n"
- space = " "
- if sep is None:
- sep = space
- if end is None:
- end = newline
- for i, arg in enumerate(args):
- if i:
- write(sep)
- write(arg)
- write(end)
-if sys.version_info[:2] < (3, 3):
- _print = print_
-
- def print_(*args, **kwargs):
- fp = kwargs.get("file", sys.stdout)
- flush = kwargs.pop("flush", False)
- _print(*args, **kwargs)
- if flush and fp is not None:
- fp.flush()
-
-_add_doc(reraise, """Reraise an exception.""")
-
-if sys.version_info[0:2] < (3, 4):
- def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
- updated=functools.WRAPPER_UPDATES):
- def wrapper(f):
- f = functools.wraps(wrapped, assigned, updated)(f)
- f.__wrapped__ = wrapped
- return f
- return wrapper
-else:
- wraps = functools.wraps
-
-
-def with_metaclass(meta, *bases):
- """Create a base class with a metaclass."""
- # This requires a bit of explanation: the basic idea is to make a dummy
- # metaclass for one level of class instantiation that replaces itself with
- # the actual metaclass.
- class metaclass(meta):
-
- def __new__(cls, name, this_bases, d):
- return meta(name, bases, d)
- return type.__new__(metaclass, 'temporary_class', (), {})
-
-
-def add_metaclass(metaclass):
- """Class decorator for creating a class with a metaclass."""
- def wrapper(cls):
- orig_vars = cls.__dict__.copy()
- slots = orig_vars.get('__slots__')
- if slots is not None:
- if isinstance(slots, str):
- slots = [slots]
- for slots_var in slots:
- orig_vars.pop(slots_var)
- orig_vars.pop('__dict__', None)
- orig_vars.pop('__weakref__', None)
- return metaclass(cls.__name__, cls.__bases__, orig_vars)
- return wrapper
-
-
-def python_2_unicode_compatible(klass):
- """
- A decorator that defines __unicode__ and __str__ methods under Python 2.
- Under Python 3 it does nothing.
-
- To support Python 2 and 3 with a single code base, define a __str__ method
- returning text and apply this decorator to the class.
- """
- if PY2:
- if '__str__' not in klass.__dict__:
- raise ValueError("@python_2_unicode_compatible cannot be applied "
- "to %s because it doesn't define __str__()." %
- klass.__name__)
- klass.__unicode__ = klass.__str__
- klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
- return klass
-
-
-# Complete the moves implementation.
-# This code is at the end of this module to speed up module loading.
-# Turn this module into a package.
-__path__ = [] # required for PEP 302 and PEP 451
-__package__ = __name__ # see PEP 366 @ReservedAssignment
-if globals().get("__spec__") is not None:
- __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
-# Remove other six meta path importers, since they cause problems. This can
-# happen if six is removed from sys.modules and then reloaded. (Setuptools does
-# this for some reason.)
-if sys.meta_path:
- for i, importer in enumerate(sys.meta_path):
- # Here's some real nastiness: Another "instance" of the six module might
- # be floating around. Therefore, we can't use isinstance() to check for
- # the six meta path importer, since the other six instance will have
- # inserted an importer with different class.
- if (type(importer).__name__ == "_SixMetaPathImporter" and
- importer.name == __name__):
- del sys.meta_path[i]
- break
- del i, importer
-# Finally, add the importer to the meta path import hook.
-sys.meta_path.append(_importer)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py
deleted file mode 100644
index d6594eb2..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sys
-
-try:
- # Our match_hostname function is the same as 3.5's, so we only want to
- # import the match_hostname function if it's at least that good.
- if sys.version_info < (3, 5):
- raise ImportError("Fallback to vendored code")
-
- from ssl import CertificateError, match_hostname
-except ImportError:
- try:
- # Backport of the function from a pypi module
- from backports.ssl_match_hostname import CertificateError, match_hostname
- except ImportError:
- # Our vendored copy
- from ._implementation import CertificateError, match_hostname
-
-# Not needed, but documenting what we provide.
-__all__ = ('CertificateError', 'match_hostname')
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py
deleted file mode 100644
index 1fd42f38..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py
+++ /dev/null
@@ -1,157 +0,0 @@
-"""The match_hostname() function from Python 3.3.3, essential when using SSL."""
-
-# Note: This file is under the PSF license as the code comes from the python
-# stdlib. http://docs.python.org/3/license.html
-
-import re
-import sys
-
-# ipaddress has been backported to 2.6+ in pypi. If it is installed on the
-# system, use it to handle IPAddress ServerAltnames (this was added in
-# python-3.5) otherwise only do DNS matching. This allows
-# backports.ssl_match_hostname to continue to be used all the way back to
-# python-2.4.
-try:
- import ipaddress
-except ImportError:
- ipaddress = None
-
-__version__ = '3.5.0.1'
-
-
-class CertificateError(ValueError):
- pass
-
-
-def _dnsname_match(dn, hostname, max_wildcards=1):
- """Matching according to RFC 6125, section 6.4.3
-
- http://tools.ietf.org/html/rfc6125#section-6.4.3
- """
- pats = []
- if not dn:
- return False
-
- # Ported from python3-syntax:
- # leftmost, *remainder = dn.split(r'.')
- parts = dn.split(r'.')
- leftmost = parts[0]
- remainder = parts[1:]
-
- wildcards = leftmost.count('*')
- if wildcards > max_wildcards:
- # Issue #17980: avoid denials of service by refusing more
- # than one wildcard per fragment. A survey of established
- # policy among SSL implementations showed it to be a
- # reasonable choice.
- raise CertificateError(
- "too many wildcards in certificate DNS name: " + repr(dn))
-
- # speed up common case w/o wildcards
- if not wildcards:
- return dn.lower() == hostname.lower()
-
- # RFC 6125, section 6.4.3, subitem 1.
- # The client SHOULD NOT attempt to match a presented identifier in which
- # the wildcard character comprises a label other than the left-most label.
- if leftmost == '*':
- # When '*' is a fragment by itself, it matches a non-empty dotless
- # fragment.
- pats.append('[^.]+')
- elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
- # RFC 6125, section 6.4.3, subitem 3.
- # The client SHOULD NOT attempt to match a presented identifier
- # where the wildcard character is embedded within an A-label or
- # U-label of an internationalized domain name.
- pats.append(re.escape(leftmost))
- else:
- # Otherwise, '*' matches any dotless string, e.g. www*
- pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
-
- # add the remaining fragments, ignore any wildcards
- for frag in remainder:
- pats.append(re.escape(frag))
-
- pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
- return pat.match(hostname)
-
-
-def _to_unicode(obj):
- if isinstance(obj, str) and sys.version_info < (3,):
- obj = unicode(obj, encoding='ascii', errors='strict')
- return obj
-
-def _ipaddress_match(ipname, host_ip):
- """Exact matching of IP addresses.
-
- RFC 6125 explicitly doesn't define an algorithm for this
- (section 1.7.2 - "Out of Scope").
- """
- # OpenSSL may add a trailing newline to a subjectAltName's IP address
- # Divergence from upstream: ipaddress can't handle byte str
- ip = ipaddress.ip_address(_to_unicode(ipname).rstrip())
- return ip == host_ip
-
-
-def match_hostname(cert, hostname):
- """Verify that *cert* (in decoded format as returned by
- SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
- rules are followed, but IP addresses are not accepted for *hostname*.
-
- CertificateError is raised on failure. On success, the function
- returns nothing.
- """
- if not cert:
- raise ValueError("empty or no certificate, match_hostname needs a "
- "SSL socket or SSL context with either "
- "CERT_OPTIONAL or CERT_REQUIRED")
- try:
- # Divergence from upstream: ipaddress can't handle byte str
- host_ip = ipaddress.ip_address(_to_unicode(hostname))
- except ValueError:
- # Not an IP address (common case)
- host_ip = None
- except UnicodeError:
- # Divergence from upstream: Have to deal with ipaddress not taking
- # byte strings. addresses should be all ascii, so we consider it not
- # an ipaddress in this case
- host_ip = None
- except AttributeError:
- # Divergence from upstream: Make ipaddress library optional
- if ipaddress is None:
- host_ip = None
- else:
- raise
- dnsnames = []
- san = cert.get('subjectAltName', ())
- for key, value in san:
- if key == 'DNS':
- if host_ip is None and _dnsname_match(value, hostname):
- return
- dnsnames.append(value)
- elif key == 'IP Address':
- if host_ip is not None and _ipaddress_match(value, host_ip):
- return
- dnsnames.append(value)
- if not dnsnames:
- # The subject is only checked when there is no dNSName entry
- # in subjectAltName
- for sub in cert.get('subject', ()):
- for key, value in sub:
- # XXX according to RFC 2818, the most specific Common Name
- # must be used.
- if key == 'commonName':
- if _dnsname_match(value, hostname):
- return
- dnsnames.append(value)
- if len(dnsnames) > 1:
- raise CertificateError("hostname %r "
- "doesn't match either of %s"
- % (hostname, ', '.join(map(repr, dnsnames))))
- elif len(dnsnames) == 1:
- raise CertificateError("hostname %r "
- "doesn't match %r"
- % (hostname, dnsnames[0]))
- else:
- raise CertificateError("no appropriate commonName or "
- "subjectAltName fields were found")
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/poolmanager.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/poolmanager.py
deleted file mode 100644
index cc5a00e4..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/poolmanager.py
+++ /dev/null
@@ -1,363 +0,0 @@
-from __future__ import absolute_import
-import collections
-import functools
-import logging
-
-from ._collections import RecentlyUsedContainer
-from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool
-from .connectionpool import port_by_scheme
-from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown
-from .packages.six.moves.urllib.parse import urljoin
-from .request import RequestMethods
-from .util.url import parse_url
-from .util.retry import Retry
-
-
-__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url']
-
-
-log = logging.getLogger(__name__)
-
-SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs',
- 'ssl_version', 'ca_cert_dir', 'ssl_context')
-
-# The base fields to use when determining what pool to get a connection from;
-# these do not rely on the ``connection_pool_kw`` and can be determined by the
-# URL and potentially the ``urllib3.connection.port_by_scheme`` dictionary.
-#
-# All custom key schemes should include the fields in this key at a minimum.
-BasePoolKey = collections.namedtuple('BasePoolKey', ('scheme', 'host', 'port'))
-
-# The fields to use when determining what pool to get a HTTP and HTTPS
-# connection from. All additional fields must be present in the PoolManager's
-# ``connection_pool_kw`` instance variable.
-HTTPPoolKey = collections.namedtuple(
- 'HTTPPoolKey', BasePoolKey._fields + ('timeout', 'retries', 'strict',
- 'block', 'source_address')
-)
-HTTPSPoolKey = collections.namedtuple(
- 'HTTPSPoolKey', HTTPPoolKey._fields + SSL_KEYWORDS
-)
-
-
-def _default_key_normalizer(key_class, request_context):
- """
- Create a pool key of type ``key_class`` for a request.
-
- According to RFC 3986, both the scheme and host are case-insensitive.
- Therefore, this function normalizes both before constructing the pool
- key for an HTTPS request. If you wish to change this behaviour, provide
- alternate callables to ``key_fn_by_scheme``.
-
- :param key_class:
- The class to use when constructing the key. This should be a namedtuple
- with the ``scheme`` and ``host`` keys at a minimum.
-
- :param request_context:
- A dictionary-like object that contain the context for a request.
- It should contain a key for each field in the :class:`HTTPPoolKey`
- """
- context = {}
- for key in key_class._fields:
- context[key] = request_context.get(key)
- context['scheme'] = context['scheme'].lower()
- context['host'] = context['host'].lower()
- return key_class(**context)
-
-
-# A dictionary that maps a scheme to a callable that creates a pool key.
-# This can be used to alter the way pool keys are constructed, if desired.
-# Each PoolManager makes a copy of this dictionary so they can be configured
-# globally here, or individually on the instance.
-key_fn_by_scheme = {
- 'http': functools.partial(_default_key_normalizer, HTTPPoolKey),
- 'https': functools.partial(_default_key_normalizer, HTTPSPoolKey),
-}
-
-pool_classes_by_scheme = {
- 'http': HTTPConnectionPool,
- 'https': HTTPSConnectionPool,
-}
-
-
-class PoolManager(RequestMethods):
- """
- Allows for arbitrary requests while transparently keeping track of
- necessary connection pools for you.
-
- :param num_pools:
- Number of connection pools to cache before discarding the least
- recently used pool.
-
- :param headers:
- Headers to include with all requests, unless other headers are given
- explicitly.
-
- :param \\**connection_pool_kw:
- Additional parameters are used to create fresh
- :class:`urllib3.connectionpool.ConnectionPool` instances.
-
- Example::
-
- >>> manager = PoolManager(num_pools=2)
- >>> r = manager.request('GET', 'http://google.com/')
- >>> r = manager.request('GET', 'http://google.com/mail')
- >>> r = manager.request('GET', 'http://yahoo.com/')
- >>> len(manager.pools)
- 2
-
- """
-
- proxy = None
-
- def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
- RequestMethods.__init__(self, headers)
- self.connection_pool_kw = connection_pool_kw
- self.pools = RecentlyUsedContainer(num_pools,
- dispose_func=lambda p: p.close())
-
- # Locally set the pool classes and keys so other PoolManagers can
- # override them.
- self.pool_classes_by_scheme = pool_classes_by_scheme
- self.key_fn_by_scheme = key_fn_by_scheme.copy()
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.clear()
- # Return False to re-raise any potential exceptions
- return False
-
- def _new_pool(self, scheme, host, port):
- """
- Create a new :class:`ConnectionPool` based on host, port and scheme.
-
- This method is used to actually create the connection pools handed out
- by :meth:`connection_from_url` and companion methods. It is intended
- to be overridden for customization.
- """
- pool_cls = self.pool_classes_by_scheme[scheme]
- kwargs = self.connection_pool_kw
- if scheme == 'http':
- kwargs = self.connection_pool_kw.copy()
- for kw in SSL_KEYWORDS:
- kwargs.pop(kw, None)
-
- return pool_cls(host, port, **kwargs)
-
- def clear(self):
- """
- Empty our store of pools and direct them all to close.
-
- This will not affect in-flight connections, but they will not be
- re-used after completion.
- """
- self.pools.clear()
-
- def connection_from_host(self, host, port=None, scheme='http'):
- """
- Get a :class:`ConnectionPool` based on the host, port, and scheme.
-
- If ``port`` isn't given, it will be derived from the ``scheme`` using
- ``urllib3.connectionpool.port_by_scheme``.
- """
-
- if not host:
- raise LocationValueError("No host specified.")
-
- request_context = self.connection_pool_kw.copy()
- request_context['scheme'] = scheme or 'http'
- if not port:
- port = port_by_scheme.get(request_context['scheme'].lower(), 80)
- request_context['port'] = port
- request_context['host'] = host
-
- return self.connection_from_context(request_context)
-
- def connection_from_context(self, request_context):
- """
- Get a :class:`ConnectionPool` based on the request context.
-
- ``request_context`` must at least contain the ``scheme`` key and its
- value must be a key in ``key_fn_by_scheme`` instance variable.
- """
- scheme = request_context['scheme'].lower()
- pool_key_constructor = self.key_fn_by_scheme[scheme]
- pool_key = pool_key_constructor(request_context)
-
- return self.connection_from_pool_key(pool_key)
-
- def connection_from_pool_key(self, pool_key):
- """
- Get a :class:`ConnectionPool` based on the provided pool key.
-
- ``pool_key`` should be a namedtuple that only contains immutable
- objects. At a minimum it must have the ``scheme``, ``host``, and
- ``port`` fields.
- """
- with self.pools.lock:
- # If the scheme, host, or port doesn't match existing open
- # connections, open a new ConnectionPool.
- pool = self.pools.get(pool_key)
- if pool:
- return pool
-
- # Make a fresh ConnectionPool of the desired type
- pool = self._new_pool(pool_key.scheme, pool_key.host, pool_key.port)
- self.pools[pool_key] = pool
-
- return pool
-
- def connection_from_url(self, url):
- """
- Similar to :func:`urllib3.connectionpool.connection_from_url` but
- doesn't pass any additional parameters to the
- :class:`urllib3.connectionpool.ConnectionPool` constructor.
-
- Additional parameters are taken from the :class:`.PoolManager`
- constructor.
- """
- u = parse_url(url)
- return self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
-
- def urlopen(self, method, url, redirect=True, **kw):
- """
- Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen`
- with custom cross-host redirect logic and only sends the request-uri
- portion of the ``url``.
-
- The given ``url`` parameter must be absolute, such that an appropriate
- :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
- """
- u = parse_url(url)
- conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
-
- kw['assert_same_host'] = False
- kw['redirect'] = False
- if 'headers' not in kw:
- kw['headers'] = self.headers
-
- if self.proxy is not None and u.scheme == "http":
- response = conn.urlopen(method, url, **kw)
- else:
- response = conn.urlopen(method, u.request_uri, **kw)
-
- redirect_location = redirect and response.get_redirect_location()
- if not redirect_location:
- return response
-
- # Support relative URLs for redirecting.
- redirect_location = urljoin(url, redirect_location)
-
- # RFC 7231, Section 6.4.4
- if response.status == 303:
- method = 'GET'
-
- retries = kw.get('retries')
- if not isinstance(retries, Retry):
- retries = Retry.from_int(retries, redirect=redirect)
-
- try:
- retries = retries.increment(method, url, response=response, _pool=conn)
- except MaxRetryError:
- if retries.raise_on_redirect:
- raise
- return response
-
- kw['retries'] = retries
- kw['redirect'] = redirect
-
- log.info("Redirecting %s -> %s", url, redirect_location)
- return self.urlopen(method, redirect_location, **kw)
-
-
-class ProxyManager(PoolManager):
- """
- Behaves just like :class:`PoolManager`, but sends all requests through
- the defined proxy, using the CONNECT method for HTTPS URLs.
-
- :param proxy_url:
- The URL of the proxy to be used.
-
- :param proxy_headers:
- A dictionary contaning headers that will be sent to the proxy. In case
- of HTTP they are being sent with each request, while in the
- HTTPS/CONNECT case they are sent only once. Could be used for proxy
- authentication.
-
- Example:
- >>> proxy = urllib3.ProxyManager('http://localhost:3128/')
- >>> r1 = proxy.request('GET', 'http://google.com/')
- >>> r2 = proxy.request('GET', 'http://httpbin.org/')
- >>> len(proxy.pools)
- 1
- >>> r3 = proxy.request('GET', 'https://httpbin.org/')
- >>> r4 = proxy.request('GET', 'https://twitter.com/')
- >>> len(proxy.pools)
- 3
-
- """
-
- def __init__(self, proxy_url, num_pools=10, headers=None,
- proxy_headers=None, **connection_pool_kw):
-
- if isinstance(proxy_url, HTTPConnectionPool):
- proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host,
- proxy_url.port)
- proxy = parse_url(proxy_url)
- if not proxy.port:
- port = port_by_scheme.get(proxy.scheme, 80)
- proxy = proxy._replace(port=port)
-
- if proxy.scheme not in ("http", "https"):
- raise ProxySchemeUnknown(proxy.scheme)
-
- self.proxy = proxy
- self.proxy_headers = proxy_headers or {}
-
- connection_pool_kw['_proxy'] = self.proxy
- connection_pool_kw['_proxy_headers'] = self.proxy_headers
-
- super(ProxyManager, self).__init__(
- num_pools, headers, **connection_pool_kw)
-
- def connection_from_host(self, host, port=None, scheme='http'):
- if scheme == "https":
- return super(ProxyManager, self).connection_from_host(
- host, port, scheme)
-
- return super(ProxyManager, self).connection_from_host(
- self.proxy.host, self.proxy.port, self.proxy.scheme)
-
- def _set_proxy_headers(self, url, headers=None):
- """
- Sets headers needed by proxies: specifically, the Accept and Host
- headers. Only sets headers not provided by the user.
- """
- headers_ = {'Accept': '*/*'}
-
- netloc = parse_url(url).netloc
- if netloc:
- headers_['Host'] = netloc
-
- if headers:
- headers_.update(headers)
- return headers_
-
- def urlopen(self, method, url, redirect=True, **kw):
- "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
- u = parse_url(url)
-
- if u.scheme == "http":
- # For proxied HTTPS requests, httplib sets the necessary headers
- # on the CONNECT to the proxy. For HTTP, we'll definitely
- # need to set 'Host' at the very least.
- headers = kw.get('headers', self.headers)
- kw['headers'] = self._set_proxy_headers(url, headers)
-
- return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
-
-
-def proxy_from_url(url, **kw):
- return ProxyManager(proxy_url=url, **kw)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/request.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/request.py
deleted file mode 100644
index c0fddff0..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/request.py
+++ /dev/null
@@ -1,148 +0,0 @@
-from __future__ import absolute_import
-
-from .filepost import encode_multipart_formdata
-from .packages.six.moves.urllib.parse import urlencode
-
-
-__all__ = ['RequestMethods']
-
-
-class RequestMethods(object):
- """
- Convenience mixin for classes who implement a :meth:`urlopen` method, such
- as :class:`~urllib3.connectionpool.HTTPConnectionPool` and
- :class:`~urllib3.poolmanager.PoolManager`.
-
- Provides behavior for making common types of HTTP request methods and
- decides which type of request field encoding to use.
-
- Specifically,
-
- :meth:`.request_encode_url` is for sending requests whose fields are
- encoded in the URL (such as GET, HEAD, DELETE).
-
- :meth:`.request_encode_body` is for sending requests whose fields are
- encoded in the *body* of the request using multipart or www-form-urlencoded
- (such as for POST, PUT, PATCH).
-
- :meth:`.request` is for making any kind of request, it will look up the
- appropriate encoding format and use one of the above two methods to make
- the request.
-
- Initializer parameters:
-
- :param headers:
- Headers to include with all requests, unless other headers are given
- explicitly.
- """
-
- _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS'])
-
- def __init__(self, headers=None):
- self.headers = headers or {}
-
- def urlopen(self, method, url, body=None, headers=None,
- encode_multipart=True, multipart_boundary=None,
- **kw): # Abstract
- raise NotImplemented("Classes extending RequestMethods must implement "
- "their own ``urlopen`` method.")
-
- def request(self, method, url, fields=None, headers=None, **urlopen_kw):
- """
- Make a request using :meth:`urlopen` with the appropriate encoding of
- ``fields`` based on the ``method`` used.
-
- This is a convenience method that requires the least amount of manual
- effort. It can be used in most situations, while still having the
- option to drop down to more specific methods when necessary, such as
- :meth:`request_encode_url`, :meth:`request_encode_body`,
- or even the lowest level :meth:`urlopen`.
- """
- method = method.upper()
-
- if method in self._encode_url_methods:
- return self.request_encode_url(method, url, fields=fields,
- headers=headers,
- **urlopen_kw)
- else:
- return self.request_encode_body(method, url, fields=fields,
- headers=headers,
- **urlopen_kw)
-
- def request_encode_url(self, method, url, fields=None, headers=None,
- **urlopen_kw):
- """
- Make a request using :meth:`urlopen` with the ``fields`` encoded in
- the url. This is useful for request methods like GET, HEAD, DELETE, etc.
- """
- if headers is None:
- headers = self.headers
-
- extra_kw = {'headers': headers}
- extra_kw.update(urlopen_kw)
-
- if fields:
- url += '?' + urlencode(fields)
-
- return self.urlopen(method, url, **extra_kw)
-
- def request_encode_body(self, method, url, fields=None, headers=None,
- encode_multipart=True, multipart_boundary=None,
- **urlopen_kw):
- """
- Make a request using :meth:`urlopen` with the ``fields`` encoded in
- the body. This is useful for request methods like POST, PUT, PATCH, etc.
-
- When ``encode_multipart=True`` (default), then
- :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode
- the payload with the appropriate content type. Otherwise
- :meth:`urllib.urlencode` is used with the
- 'application/x-www-form-urlencoded' content type.
-
- Multipart encoding must be used when posting files, and it's reasonably
- safe to use it in other times too. However, it may break request
- signing, such as with OAuth.
-
- Supports an optional ``fields`` parameter of key/value strings AND
- key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
- the MIME type is optional. For example::
-
- fields = {
- 'foo': 'bar',
- 'fakefile': ('foofile.txt', 'contents of foofile'),
- 'realfile': ('barfile.txt', open('realfile').read()),
- 'typedfile': ('bazfile.bin', open('bazfile').read(),
- 'image/jpeg'),
- 'nonamefile': 'contents of nonamefile field',
- }
-
- When uploading a file, providing a filename (the first parameter of the
- tuple) is optional but recommended to best mimick behavior of browsers.
-
- Note that if ``headers`` are supplied, the 'Content-Type' header will
- be overwritten because it depends on the dynamic random boundary string
- which is used to compose the body of the request. The random boundary
- string can be explicitly set with the ``multipart_boundary`` parameter.
- """
- if headers is None:
- headers = self.headers
-
- extra_kw = {'headers': {}}
-
- if fields:
- if 'body' in urlopen_kw:
- raise TypeError(
- "request got values for both 'fields' and 'body', can only specify one.")
-
- if encode_multipart:
- body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary)
- else:
- body, content_type = urlencode(fields), 'application/x-www-form-urlencoded'
-
- extra_kw['body'] = body
- extra_kw['headers'] = {'Content-Type': content_type}
-
- extra_kw['headers'].update(headers)
- extra_kw.update(urlopen_kw)
-
- return self.urlopen(method, url, **extra_kw)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/response.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/response.py
deleted file mode 100644
index 6f1b63c8..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/response.py
+++ /dev/null
@@ -1,618 +0,0 @@
-from __future__ import absolute_import
-from contextlib import contextmanager
-import zlib
-import io
-import logging
-from socket import timeout as SocketTimeout
-from socket import error as SocketError
-
-from ._collections import HTTPHeaderDict
-from .exceptions import (
- BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError,
- ResponseNotChunked, IncompleteRead, InvalidHeader
-)
-from .packages.six import string_types as basestring, binary_type, PY3
-from .packages.six.moves import http_client as httplib
-from .connection import HTTPException, BaseSSLError
-from .util.response import is_fp_closed, is_response_to_head
-
-log = logging.getLogger(__name__)
-
-
-class DeflateDecoder(object):
-
- def __init__(self):
- self._first_try = True
- self._data = binary_type()
- self._obj = zlib.decompressobj()
-
- def __getattr__(self, name):
- return getattr(self._obj, name)
-
- def decompress(self, data):
- if not data:
- return data
-
- if not self._first_try:
- return self._obj.decompress(data)
-
- self._data += data
- try:
- return self._obj.decompress(data)
- except zlib.error:
- self._first_try = False
- self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
- try:
- return self.decompress(self._data)
- finally:
- self._data = None
-
-
-class GzipDecoder(object):
-
- def __init__(self):
- self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
-
- def __getattr__(self, name):
- return getattr(self._obj, name)
-
- def decompress(self, data):
- if not data:
- return data
- return self._obj.decompress(data)
-
-
-def _get_decoder(mode):
- if mode == 'gzip':
- return GzipDecoder()
-
- return DeflateDecoder()
-
-
-class HTTPResponse(io.IOBase):
- """
- HTTP Response container.
-
- Backwards-compatible to httplib's HTTPResponse but the response ``body`` is
- loaded and decoded on-demand when the ``data`` property is accessed. This
- class is also compatible with the Python standard library's :mod:`io`
- module, and can hence be treated as a readable object in the context of that
- framework.
-
- Extra parameters for behaviour not present in httplib.HTTPResponse:
-
- :param preload_content:
- If True, the response's body will be preloaded during construction.
-
- :param decode_content:
- If True, attempts to decode specific content-encoding's based on headers
- (like 'gzip' and 'deflate') will be skipped and raw data will be used
- instead.
-
- :param original_response:
- When this HTTPResponse wrapper is generated from an httplib.HTTPResponse
- object, it's convenient to include the original for debug purposes. It's
- otherwise unused.
-
- :param retries:
- The retries contains the last :class:`~urllib3.util.retry.Retry` that
- was used during the request.
-
- :param enforce_content_length:
- Enforce content length checking. Body returned by server must match
- value of Content-Length header, if present. Otherwise, raise error.
- """
-
- CONTENT_DECODERS = ['gzip', 'deflate']
- REDIRECT_STATUSES = [301, 302, 303, 307, 308]
-
- def __init__(self, body='', headers=None, status=0, version=0, reason=None,
- strict=0, preload_content=True, decode_content=True,
- original_response=None, pool=None, connection=None,
- retries=None, enforce_content_length=False, request_method=None):
-
- if isinstance(headers, HTTPHeaderDict):
- self.headers = headers
- else:
- self.headers = HTTPHeaderDict(headers)
- self.status = status
- self.version = version
- self.reason = reason
- self.strict = strict
- self.decode_content = decode_content
- self.retries = retries
- self.enforce_content_length = enforce_content_length
-
- self._decoder = None
- self._body = None
- self._fp = None
- self._original_response = original_response
- self._fp_bytes_read = 0
-
- if body and isinstance(body, (basestring, binary_type)):
- self._body = body
-
- self._pool = pool
- self._connection = connection
-
- if hasattr(body, 'read'):
- self._fp = body
-
- # Are we using the chunked-style of transfer encoding?
- self.chunked = False
- self.chunk_left = None
- tr_enc = self.headers.get('transfer-encoding', '').lower()
- # Don't incur the penalty of creating a list and then discarding it
- encodings = (enc.strip() for enc in tr_enc.split(","))
- if "chunked" in encodings:
- self.chunked = True
-
- # Determine length of response
- self.length_remaining = self._init_length(request_method)
-
- # If requested, preload the body.
- if preload_content and not self._body:
- self._body = self.read(decode_content=decode_content)
-
- def get_redirect_location(self):
- """
- Should we redirect and where to?
-
- :returns: Truthy redirect location string if we got a redirect status
- code and valid location. ``None`` if redirect status and no
- location. ``False`` if not a redirect status code.
- """
- if self.status in self.REDIRECT_STATUSES:
- return self.headers.get('location')
-
- return False
-
- def release_conn(self):
- if not self._pool or not self._connection:
- return
-
- self._pool._put_conn(self._connection)
- self._connection = None
-
- @property
- def data(self):
- # For backwords-compat with earlier urllib3 0.4 and earlier.
- if self._body:
- return self._body
-
- if self._fp:
- return self.read(cache_content=True)
-
- @property
- def connection(self):
- return self._connection
-
- def tell(self):
- """
- Obtain the number of bytes pulled over the wire so far. May differ from
- the amount of content returned by :meth:``HTTPResponse.read`` if bytes
- are encoded on the wire (e.g, compressed).
- """
- return self._fp_bytes_read
-
- def _init_length(self, request_method):
- """
- Set initial length value for Response content if available.
- """
- length = self.headers.get('content-length')
-
- if length is not None and self.chunked:
- # This Response will fail with an IncompleteRead if it can't be
- # received as chunked. This method falls back to attempt reading
- # the response before raising an exception.
- log.warning("Received response with both Content-Length and "
- "Transfer-Encoding set. This is expressly forbidden "
- "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
- "attempting to process response as Transfer-Encoding: "
- "chunked.")
- return None
-
- elif length is not None:
- try:
- # RFC 7230 section 3.3.2 specifies multiple content lengths can
- # be sent in a single Content-Length header
- # (e.g. Content-Length: 42, 42). This line ensures the values
- # are all valid ints and that as long as the `set` length is 1,
- # all values are the same. Otherwise, the header is invalid.
- lengths = set([int(val) for val in length.split(',')])
- if len(lengths) > 1:
- raise InvalidHeader("Content-Length contained multiple "
- "unmatching values (%s)" % length)
- length = lengths.pop()
- except ValueError:
- length = None
- else:
- if length < 0:
- length = None
-
- # Convert status to int for comparison
- # In some cases, httplib returns a status of "_UNKNOWN"
- try:
- status = int(self.status)
- except ValueError:
- status = 0
-
- # Check for responses that shouldn't include a body
- if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD':
- length = 0
-
- return length
-
- def _init_decoder(self):
- """
- Set-up the _decoder attribute if necessary.
- """
- # Note: content-encoding value should be case-insensitive, per RFC 7230
- # Section 3.2
- content_encoding = self.headers.get('content-encoding', '').lower()
- if self._decoder is None and content_encoding in self.CONTENT_DECODERS:
- self._decoder = _get_decoder(content_encoding)
-
- def _decode(self, data, decode_content, flush_decoder):
- """
- Decode the data passed in and potentially flush the decoder.
- """
- try:
- if decode_content and self._decoder:
- data = self._decoder.decompress(data)
- except (IOError, zlib.error) as e:
- content_encoding = self.headers.get('content-encoding', '').lower()
- raise DecodeError(
- "Received response with content-encoding: %s, but "
- "failed to decode it." % content_encoding, e)
-
- if flush_decoder and decode_content:
- data += self._flush_decoder()
-
- return data
-
- def _flush_decoder(self):
- """
- Flushes the decoder. Should only be called if the decoder is actually
- being used.
- """
- if self._decoder:
- buf = self._decoder.decompress(b'')
- return buf + self._decoder.flush()
-
- return b''
-
- @contextmanager
- def _error_catcher(self):
- """
- Catch low-level python exceptions, instead re-raising urllib3
- variants, so that low-level exceptions are not leaked in the
- high-level api.
-
- On exit, release the connection back to the pool.
- """
- clean_exit = False
-
- try:
- try:
- yield
-
- except SocketTimeout:
- # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
- # there is yet no clean way to get at it from this context.
- raise ReadTimeoutError(self._pool, None, 'Read timed out.')
-
- except BaseSSLError as e:
- # FIXME: Is there a better way to differentiate between SSLErrors?
- if 'read operation timed out' not in str(e): # Defensive:
- # This shouldn't happen but just in case we're missing an edge
- # case, let's avoid swallowing SSL errors.
- raise
-
- raise ReadTimeoutError(self._pool, None, 'Read timed out.')
-
- except (HTTPException, SocketError) as e:
- # This includes IncompleteRead.
- raise ProtocolError('Connection broken: %r' % e, e)
-
- # If no exception is thrown, we should avoid cleaning up
- # unnecessarily.
- clean_exit = True
- finally:
- # If we didn't terminate cleanly, we need to throw away our
- # connection.
- if not clean_exit:
- # The response may not be closed but we're not going to use it
- # anymore so close it now to ensure that the connection is
- # released back to the pool.
- if self._original_response:
- self._original_response.close()
-
- # Closing the response may not actually be sufficient to close
- # everything, so if we have a hold of the connection close that
- # too.
- if self._connection:
- self._connection.close()
-
- # If we hold the original response but it's closed now, we should
- # return the connection back to the pool.
- if self._original_response and self._original_response.isclosed():
- self.release_conn()
-
- def read(self, amt=None, decode_content=None, cache_content=False):
- """
- Similar to :meth:`httplib.HTTPResponse.read`, but with two additional
- parameters: ``decode_content`` and ``cache_content``.
-
- :param amt:
- How much of the content to read. If specified, caching is skipped
- because it doesn't make sense to cache partial content as the full
- response.
-
- :param decode_content:
- If True, will attempt to decode the body based on the
- 'content-encoding' header.
-
- :param cache_content:
- If True, will save the returned data such that the same result is
- returned despite of the state of the underlying file object. This
- is useful if you want the ``.data`` property to continue working
- after having ``.read()`` the file object. (Overridden if ``amt`` is
- set.)
- """
- self._init_decoder()
- if decode_content is None:
- decode_content = self.decode_content
-
- if self._fp is None:
- return
-
- flush_decoder = False
- data = None
-
- with self._error_catcher():
- if amt is None:
- # cStringIO doesn't like amt=None
- data = self._fp.read()
- flush_decoder = True
- else:
- cache_content = False
- data = self._fp.read(amt)
- if amt != 0 and not data: # Platform-specific: Buggy versions of Python.
- # Close the connection when no data is returned
- #
- # This is redundant to what httplib/http.client _should_
- # already do. However, versions of python released before
- # December 15, 2012 (http://bugs.python.org/issue16298) do
- # not properly close the connection in all cases. There is
- # no harm in redundantly calling close.
- self._fp.close()
- flush_decoder = True
- if self.enforce_content_length and self.length_remaining not in (0, None):
- # This is an edge case that httplib failed to cover due
- # to concerns of backward compatibility. We're
- # addressing it here to make sure IncompleteRead is
- # raised during streaming, so all calls with incorrect
- # Content-Length are caught.
- raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
-
- if data:
- self._fp_bytes_read += len(data)
- if self.length_remaining is not None:
- self.length_remaining -= len(data)
-
- data = self._decode(data, decode_content, flush_decoder)
-
- if cache_content:
- self._body = data
-
- return data
-
- def stream(self, amt=2**16, decode_content=None):
- """
- A generator wrapper for the read() method. A call will block until
- ``amt`` bytes have been read from the connection or until the
- connection is closed.
-
- :param amt:
- How much of the content to read. The generator will return up to
- much data per iteration, but may return less. This is particularly
- likely when using compressed data. However, the empty string will
- never be returned.
-
- :param decode_content:
- If True, will attempt to decode the body based on the
- 'content-encoding' header.
- """
- if self.chunked and self.supports_chunked_reads():
- for line in self.read_chunked(amt, decode_content=decode_content):
- yield line
- else:
- while not is_fp_closed(self._fp):
- data = self.read(amt=amt, decode_content=decode_content)
-
- if data:
- yield data
-
- @classmethod
- def from_httplib(ResponseCls, r, **response_kw):
- """
- Given an :class:`httplib.HTTPResponse` instance ``r``, return a
- corresponding :class:`urllib3.response.HTTPResponse` object.
-
- Remaining parameters are passed to the HTTPResponse constructor, along
- with ``original_response=r``.
- """
- headers = r.msg
-
- if not isinstance(headers, HTTPHeaderDict):
- if PY3: # Python 3
- headers = HTTPHeaderDict(headers.items())
- else: # Python 2
- headers = HTTPHeaderDict.from_httplib(headers)
-
- # HTTPResponse objects in Python 3 don't have a .strict attribute
- strict = getattr(r, 'strict', 0)
- resp = ResponseCls(body=r,
- headers=headers,
- status=r.status,
- version=r.version,
- reason=r.reason,
- strict=strict,
- original_response=r,
- **response_kw)
- return resp
-
- # Backwards-compatibility methods for httplib.HTTPResponse
- def getheaders(self):
- return self.headers
-
- def getheader(self, name, default=None):
- return self.headers.get(name, default)
-
- # Overrides from io.IOBase
- def close(self):
- if not self.closed:
- self._fp.close()
-
- if self._connection:
- self._connection.close()
-
- @property
- def closed(self):
- if self._fp is None:
- return True
- elif hasattr(self._fp, 'isclosed'):
- return self._fp.isclosed()
- elif hasattr(self._fp, 'closed'):
- return self._fp.closed
- else:
- return True
-
- def fileno(self):
- if self._fp is None:
- raise IOError("HTTPResponse has no file to get a fileno from")
- elif hasattr(self._fp, "fileno"):
- return self._fp.fileno()
- else:
- raise IOError("The file-like object this HTTPResponse is wrapped "
- "around has no file descriptor")
-
- def flush(self):
- if self._fp is not None and hasattr(self._fp, 'flush'):
- return self._fp.flush()
-
- def readable(self):
- # This method is required for `io` module compatibility.
- return True
-
- def readinto(self, b):
- # This method is required for `io` module compatibility.
- temp = self.read(len(b))
- if len(temp) == 0:
- return 0
- else:
- b[:len(temp)] = temp
- return len(temp)
-
- def supports_chunked_reads(self):
- """
- Checks if the underlying file-like object looks like a
- httplib.HTTPResponse object. We do this by testing for the fp
- attribute. If it is present we assume it returns raw chunks as
- processed by read_chunked().
- """
- return hasattr(self._fp, 'fp')
-
- def _update_chunk_length(self):
- # First, we'll figure out length of a chunk and then
- # we'll try to read it from socket.
- if self.chunk_left is not None:
- return
- line = self._fp.fp.readline()
- line = line.split(b';', 1)[0]
- try:
- self.chunk_left = int(line, 16)
- except ValueError:
- # Invalid chunked protocol response, abort.
- self.close()
- raise httplib.IncompleteRead(line)
-
- def _handle_chunk(self, amt):
- returned_chunk = None
- if amt is None:
- chunk = self._fp._safe_read(self.chunk_left)
- returned_chunk = chunk
- self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
- self.chunk_left = None
- elif amt < self.chunk_left:
- value = self._fp._safe_read(amt)
- self.chunk_left = self.chunk_left - amt
- returned_chunk = value
- elif amt == self.chunk_left:
- value = self._fp._safe_read(amt)
- self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
- self.chunk_left = None
- returned_chunk = value
- else: # amt > self.chunk_left
- returned_chunk = self._fp._safe_read(self.chunk_left)
- self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
- self.chunk_left = None
- return returned_chunk
-
- def read_chunked(self, amt=None, decode_content=None):
- """
- Similar to :meth:`HTTPResponse.read`, but with an additional
- parameter: ``decode_content``.
-
- :param decode_content:
- If True, will attempt to decode the body based on the
- 'content-encoding' header.
- """
- self._init_decoder()
- # FIXME: Rewrite this method and make it a class with a better structured logic.
- if not self.chunked:
- raise ResponseNotChunked(
- "Response is not chunked. "
- "Header 'transfer-encoding: chunked' is missing.")
- if not self.supports_chunked_reads():
- raise BodyNotHttplibCompatible(
- "Body should be httplib.HTTPResponse like. "
- "It should have have an fp attribute which returns raw chunks.")
-
- # Don't bother reading the body of a HEAD request.
- if self._original_response and is_response_to_head(self._original_response):
- self._original_response.close()
- return
-
- with self._error_catcher():
- while True:
- self._update_chunk_length()
- if self.chunk_left == 0:
- break
- chunk = self._handle_chunk(amt)
- decoded = self._decode(chunk, decode_content=decode_content,
- flush_decoder=False)
- if decoded:
- yield decoded
-
- if decode_content:
- # On CPython and PyPy, we should never need to flush the
- # decoder. However, on Jython we *might* need to, so
- # lets defensively do it anyway.
- decoded = self._flush_decoder()
- if decoded: # Platform-specific: Jython.
- yield decoded
-
- # Chunk content ends with \r\n: discard it.
- while True:
- line = self._fp.fp.readline()
- if not line:
- # Some sites may not end with '\r\n'.
- break
- if line == b'\r\n':
- break
-
- # We read everything; close the "file".
- if self._original_response:
- self._original_response.close()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/__init__.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/__init__.py
deleted file mode 100644
index 5ced5a44..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/__init__.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from __future__ import absolute_import
-# For backwards compatibility, provide imports that used to be here.
-from .connection import is_connection_dropped
-from .request import make_headers
-from .response import is_fp_closed
-from .ssl_ import (
- SSLContext,
- HAS_SNI,
- IS_PYOPENSSL,
- assert_fingerprint,
- resolve_cert_reqs,
- resolve_ssl_version,
- ssl_wrap_socket,
-)
-from .timeout import (
- current_time,
- Timeout,
-)
-
-from .retry import Retry
-from .url import (
- get_host,
- parse_url,
- split_first,
- Url,
-)
-from .wait import (
- wait_for_read,
- wait_for_write
-)
-
-__all__ = (
- 'HAS_SNI',
- 'IS_PYOPENSSL',
- 'SSLContext',
- 'Retry',
- 'Timeout',
- 'Url',
- 'assert_fingerprint',
- 'current_time',
- 'is_connection_dropped',
- 'is_fp_closed',
- 'get_host',
- 'parse_url',
- 'make_headers',
- 'resolve_cert_reqs',
- 'resolve_ssl_version',
- 'split_first',
- 'ssl_wrap_socket',
- 'wait_for_read',
- 'wait_for_write'
-)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/connection.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/connection.py
deleted file mode 100644
index bf699cfd..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/connection.py
+++ /dev/null
@@ -1,130 +0,0 @@
-from __future__ import absolute_import
-import socket
-from .wait import wait_for_read
-from .selectors import HAS_SELECT, SelectorError
-
-
-def is_connection_dropped(conn): # Platform-specific
- """
- Returns True if the connection is dropped and should be closed.
-
- :param conn:
- :class:`httplib.HTTPConnection` object.
-
- Note: For platforms like AppEngine, this will always return ``False`` to
- let the platform handle connection recycling transparently for us.
- """
- sock = getattr(conn, 'sock', False)
- if sock is False: # Platform-specific: AppEngine
- return False
- if sock is None: # Connection already closed (such as by httplib).
- return True
-
- if not HAS_SELECT:
- return False
-
- try:
- return bool(wait_for_read(sock, timeout=0.0))
- except SelectorError:
- return True
-
-
-# This function is copied from socket.py in the Python 2.7 standard
-# library test suite. Added to its signature is only `socket_options`.
-# One additional modification is that we avoid binding to IPv6 servers
-# discovered in DNS if the system doesn't have IPv6 functionality.
-def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
- source_address=None, socket_options=None):
- """Connect to *address* and return the socket object.
-
- Convenience function. Connect to *address* (a 2-tuple ``(host,
- port)``) and return the socket object. Passing the optional
- *timeout* parameter will set the timeout on the socket instance
- before attempting to connect. If no *timeout* is supplied, the
- global default timeout setting returned by :func:`getdefaulttimeout`
- is used. If *source_address* is set it must be a tuple of (host, port)
- for the socket to bind as a source address before making the connection.
- An host of '' or port 0 tells the OS to use the default.
- """
-
- host, port = address
- if host.startswith('['):
- host = host.strip('[]')
- err = None
-
- # Using the value from allowed_gai_family() in the context of getaddrinfo lets
- # us select whether to work with IPv4 DNS records, IPv6 records, or both.
- # The original create_connection function always returns all records.
- family = allowed_gai_family()
-
- for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
- af, socktype, proto, canonname, sa = res
- sock = None
- try:
- sock = socket.socket(af, socktype, proto)
-
- # If provided, set socket level options before connecting.
- _set_socket_options(sock, socket_options)
-
- if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
- sock.settimeout(timeout)
- if source_address:
- sock.bind(source_address)
- sock.connect(sa)
- return sock
-
- except socket.error as e:
- err = e
- if sock is not None:
- sock.close()
- sock = None
-
- if err is not None:
- raise err
-
- raise socket.error("getaddrinfo returns an empty list")
-
-
-def _set_socket_options(sock, options):
- if options is None:
- return
-
- for opt in options:
- sock.setsockopt(*opt)
-
-
-def allowed_gai_family():
- """This function is designed to work in the context of
- getaddrinfo, where family=socket.AF_UNSPEC is the default and
- will perform a DNS search for both IPv6 and IPv4 records."""
-
- family = socket.AF_INET
- if HAS_IPV6:
- family = socket.AF_UNSPEC
- return family
-
-
-def _has_ipv6(host):
- """ Returns True if the system can bind an IPv6 address. """
- sock = None
- has_ipv6 = False
-
- if socket.has_ipv6:
- # has_ipv6 returns true if cPython was compiled with IPv6 support.
- # It does not tell us if the system has IPv6 support enabled. To
- # determine that we must bind to an IPv6 address.
- # https://github.com/shazow/urllib3/pull/611
- # https://bugs.python.org/issue658327
- try:
- sock = socket.socket(socket.AF_INET6)
- sock.bind((host, 0))
- has_ipv6 = True
- except Exception:
- pass
-
- if sock:
- sock.close()
- return has_ipv6
-
-
-HAS_IPV6 = _has_ipv6('::1')
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/request.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/request.py
deleted file mode 100644
index 974fc40a..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/request.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from __future__ import absolute_import
-from base64 import b64encode
-
-from ..packages.six import b, integer_types
-from ..exceptions import UnrewindableBodyError
-
-ACCEPT_ENCODING = 'gzip,deflate'
-_FAILEDTELL = object()
-
-
-def make_headers(keep_alive=None, accept_encoding=None, user_agent=None,
- basic_auth=None, proxy_basic_auth=None, disable_cache=None):
- """
- Shortcuts for generating request headers.
-
- :param keep_alive:
- If ``True``, adds 'connection: keep-alive' header.
-
- :param accept_encoding:
- Can be a boolean, list, or string.
- ``True`` translates to 'gzip,deflate'.
- List will get joined by comma.
- String will be used as provided.
-
- :param user_agent:
- String representing the user-agent you want, such as
- "python-urllib3/0.6"
-
- :param basic_auth:
- Colon-separated username:password string for 'authorization: basic ...'
- auth header.
-
- :param proxy_basic_auth:
- Colon-separated username:password string for 'proxy-authorization: basic ...'
- auth header.
-
- :param disable_cache:
- If ``True``, adds 'cache-control: no-cache' header.
-
- Example::
-
- >>> make_headers(keep_alive=True, user_agent="Batman/1.0")
- {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
- >>> make_headers(accept_encoding=True)
- {'accept-encoding': 'gzip,deflate'}
- """
- headers = {}
- if accept_encoding:
- if isinstance(accept_encoding, str):
- pass
- elif isinstance(accept_encoding, list):
- accept_encoding = ','.join(accept_encoding)
- else:
- accept_encoding = ACCEPT_ENCODING
- headers['accept-encoding'] = accept_encoding
-
- if user_agent:
- headers['user-agent'] = user_agent
-
- if keep_alive:
- headers['connection'] = 'keep-alive'
-
- if basic_auth:
- headers['authorization'] = 'Basic ' + \
- b64encode(b(basic_auth)).decode('utf-8')
-
- if proxy_basic_auth:
- headers['proxy-authorization'] = 'Basic ' + \
- b64encode(b(proxy_basic_auth)).decode('utf-8')
-
- if disable_cache:
- headers['cache-control'] = 'no-cache'
-
- return headers
-
-
-def set_file_position(body, pos):
- """
- If a position is provided, move file to that point.
- Otherwise, we'll attempt to record a position for future use.
- """
- if pos is not None:
- rewind_body(body, pos)
- elif getattr(body, 'tell', None) is not None:
- try:
- pos = body.tell()
- except (IOError, OSError):
- # This differentiates from None, allowing us to catch
- # a failed `tell()` later when trying to rewind the body.
- pos = _FAILEDTELL
-
- return pos
-
-
-def rewind_body(body, body_pos):
- """
- Attempt to rewind body to a certain position.
- Primarily used for request redirects and retries.
-
- :param body:
- File-like object that supports seek.
-
- :param int pos:
- Position to seek to in file.
- """
- body_seek = getattr(body, 'seek', None)
- if body_seek is not None and isinstance(body_pos, integer_types):
- try:
- body_seek(body_pos)
- except (IOError, OSError):
- raise UnrewindableBodyError("An error occured when rewinding request "
- "body for redirect/retry.")
- elif body_pos is _FAILEDTELL:
- raise UnrewindableBodyError("Unable to record file position for rewinding "
- "request body during a redirect/retry.")
- else:
- raise ValueError("body_pos must be of type integer, "
- "instead it was %s." % type(body_pos))
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/response.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/response.py
deleted file mode 100644
index 67cf730a..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/response.py
+++ /dev/null
@@ -1,81 +0,0 @@
-from __future__ import absolute_import
-from ..packages.six.moves import http_client as httplib
-
-from ..exceptions import HeaderParsingError
-
-
-def is_fp_closed(obj):
- """
- Checks whether a given file-like object is closed.
-
- :param obj:
- The file-like object to check.
- """
-
- try:
- # Check `isclosed()` first, in case Python3 doesn't set `closed`.
- # GH Issue #928
- return obj.isclosed()
- except AttributeError:
- pass
-
- try:
- # Check via the official file-like-object way.
- return obj.closed
- except AttributeError:
- pass
-
- try:
- # Check if the object is a container for another file-like object that
- # gets released on exhaustion (e.g. HTTPResponse).
- return obj.fp is None
- except AttributeError:
- pass
-
- raise ValueError("Unable to determine whether fp is closed.")
-
-
-def assert_header_parsing(headers):
- """
- Asserts whether all headers have been successfully parsed.
- Extracts encountered errors from the result of parsing headers.
-
- Only works on Python 3.
-
- :param headers: Headers to verify.
- :type headers: `httplib.HTTPMessage`.
-
- :raises urllib3.exceptions.HeaderParsingError:
- If parsing errors are found.
- """
-
- # This will fail silently if we pass in the wrong kind of parameter.
- # To make debugging easier add an explicit check.
- if not isinstance(headers, httplib.HTTPMessage):
- raise TypeError('expected httplib.Message, got {0}.'.format(
- type(headers)))
-
- defects = getattr(headers, 'defects', None)
- get_payload = getattr(headers, 'get_payload', None)
-
- unparsed_data = None
- if get_payload: # Platform-specific: Python 3.
- unparsed_data = get_payload()
-
- if defects or unparsed_data:
- raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
-
-
-def is_response_to_head(response):
- """
- Checks whether the request of a response has been a HEAD-request.
- Handles the quirks of AppEngine.
-
- :param conn:
- :type conn: :class:`httplib.HTTPResponse`
- """
- # FIXME: Can we do this somehow without accessing private httplib _method?
- method = response._method
- if isinstance(method, int): # Platform-specific: Appengine
- return method == 3
- return method.upper() == 'HEAD'
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/retry.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/retry.py
deleted file mode 100644
index c9e7d287..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/retry.py
+++ /dev/null
@@ -1,389 +0,0 @@
-from __future__ import absolute_import
-import time
-import logging
-from collections import namedtuple
-from itertools import takewhile
-import email
-import re
-
-from ..exceptions import (
- ConnectTimeoutError,
- MaxRetryError,
- ProtocolError,
- ReadTimeoutError,
- ResponseError,
- InvalidHeader,
-)
-from ..packages import six
-
-
-log = logging.getLogger(__name__)
-
-# Data structure for representing the metadata of requests that result in a retry.
-RequestHistory = namedtuple('RequestHistory', ["method", "url", "error",
- "status", "redirect_location"])
-
-
-class Retry(object):
- """ Retry configuration.
-
- Each retry attempt will create a new Retry object with updated values, so
- they can be safely reused.
-
- Retries can be defined as a default for a pool::
-
- retries = Retry(connect=5, read=2, redirect=5)
- http = PoolManager(retries=retries)
- response = http.request('GET', 'http://example.com/')
-
- Or per-request (which overrides the default for the pool)::
-
- response = http.request('GET', 'http://example.com/', retries=Retry(10))
-
- Retries can be disabled by passing ``False``::
-
- response = http.request('GET', 'http://example.com/', retries=False)
-
- Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
- retries are disabled, in which case the causing exception will be raised.
-
- :param int total:
- Total number of retries to allow. Takes precedence over other counts.
-
- Set to ``None`` to remove this constraint and fall back on other
- counts. It's a good idea to set this to some sensibly-high value to
- account for unexpected edge cases and avoid infinite retry loops.
-
- Set to ``0`` to fail on the first retry.
-
- Set to ``False`` to disable and imply ``raise_on_redirect=False``.
-
- :param int connect:
- How many connection-related errors to retry on.
-
- These are errors raised before the request is sent to the remote server,
- which we assume has not triggered the server to process the request.
-
- Set to ``0`` to fail on the first retry of this type.
-
- :param int read:
- How many times to retry on read errors.
-
- These errors are raised after the request was sent to the server, so the
- request may have side-effects.
-
- Set to ``0`` to fail on the first retry of this type.
-
- :param int redirect:
- How many redirects to perform. Limit this to avoid infinite redirect
- loops.
-
- A redirect is a HTTP response with a status code 301, 302, 303, 307 or
- 308.
-
- Set to ``0`` to fail on the first retry of this type.
-
- Set to ``False`` to disable and imply ``raise_on_redirect=False``.
-
- :param iterable method_whitelist:
- Set of uppercased HTTP method verbs that we should retry on.
-
- By default, we only retry on methods which are considered to be
- idempotent (multiple requests with the same parameters end with the
- same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`.
-
- Set to a ``False`` value to retry on any verb.
-
- :param iterable status_forcelist:
- A set of integer HTTP status codes that we should force a retry on.
- A retry is initiated if the request method is in ``method_whitelist``
- and the response status code is in ``status_forcelist``.
-
- By default, this is disabled with ``None``.
-
- :param float backoff_factor:
- A backoff factor to apply between attempts after the second try
- (most errors are resolved immediately by a second try without a
- delay). urllib3 will sleep for::
-
- {backoff factor} * (2 ^ ({number of total retries} - 1))
-
- seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
- for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
- than :attr:`Retry.BACKOFF_MAX`.
-
- By default, backoff is disabled (set to 0).
-
- :param bool raise_on_redirect: Whether, if the number of redirects is
- exhausted, to raise a MaxRetryError, or to return a response with a
- response code in the 3xx range.
-
- :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
- whether we should raise an exception, or return a response,
- if status falls in ``status_forcelist`` range and retries have
- been exhausted.
-
- :param tuple history: The history of the request encountered during
- each call to :meth:`~Retry.increment`. The list is in the order
- the requests occurred. Each list item is of class :class:`RequestHistory`.
-
- :param bool respect_retry_after_header:
- Whether to respect Retry-After header on status codes defined as
- :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
-
- """
-
- DEFAULT_METHOD_WHITELIST = frozenset([
- 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE'])
-
- RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
-
- #: Maximum backoff time.
- BACKOFF_MAX = 120
-
- def __init__(self, total=10, connect=None, read=None, redirect=None,
- method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None,
- backoff_factor=0, raise_on_redirect=True, raise_on_status=True,
- history=None, respect_retry_after_header=True):
-
- self.total = total
- self.connect = connect
- self.read = read
-
- if redirect is False or total is False:
- redirect = 0
- raise_on_redirect = False
-
- self.redirect = redirect
- self.status_forcelist = status_forcelist or set()
- self.method_whitelist = method_whitelist
- self.backoff_factor = backoff_factor
- self.raise_on_redirect = raise_on_redirect
- self.raise_on_status = raise_on_status
- self.history = history or tuple()
- self.respect_retry_after_header = respect_retry_after_header
-
- def new(self, **kw):
- params = dict(
- total=self.total,
- connect=self.connect, read=self.read, redirect=self.redirect,
- method_whitelist=self.method_whitelist,
- status_forcelist=self.status_forcelist,
- backoff_factor=self.backoff_factor,
- raise_on_redirect=self.raise_on_redirect,
- raise_on_status=self.raise_on_status,
- history=self.history,
- )
- params.update(kw)
- return type(self)(**params)
-
- @classmethod
- def from_int(cls, retries, redirect=True, default=None):
- """ Backwards-compatibility for the old retries format."""
- if retries is None:
- retries = default if default is not None else cls.DEFAULT
-
- if isinstance(retries, Retry):
- return retries
-
- redirect = bool(redirect) and None
- new_retries = cls(retries, redirect=redirect)
- log.debug("Converted retries value: %r -> %r", retries, new_retries)
- return new_retries
-
- def get_backoff_time(self):
- """ Formula for computing the current backoff
-
- :rtype: float
- """
- # We want to consider only the last consecutive errors sequence (Ignore redirects).
- consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None,
- reversed(self.history))))
- if consecutive_errors_len <= 1:
- return 0
-
- backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
- return min(self.BACKOFF_MAX, backoff_value)
-
- def parse_retry_after(self, retry_after):
- # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
- if re.match(r"^\s*[0-9]+\s*$", retry_after):
- seconds = int(retry_after)
- else:
- retry_date_tuple = email.utils.parsedate(retry_after)
- if retry_date_tuple is None:
- raise InvalidHeader("Invalid Retry-After header: %s" % retry_after)
- retry_date = time.mktime(retry_date_tuple)
- seconds = retry_date - time.time()
-
- if seconds < 0:
- seconds = 0
-
- return seconds
-
- def get_retry_after(self, response):
- """ Get the value of Retry-After in seconds. """
-
- retry_after = response.getheader("Retry-After")
-
- if retry_after is None:
- return None
-
- return self.parse_retry_after(retry_after)
-
- def sleep_for_retry(self, response=None):
- retry_after = self.get_retry_after(response)
- if retry_after:
- time.sleep(retry_after)
- return True
-
- return False
-
- def _sleep_backoff(self):
- backoff = self.get_backoff_time()
- if backoff <= 0:
- return
- time.sleep(backoff)
-
- def sleep(self, response=None):
- """ Sleep between retry attempts.
-
- This method will respect a server's ``Retry-After`` response header
- and sleep the duration of the time requested. If that is not present, it
- will use an exponential backoff. By default, the backoff factor is 0 and
- this method will return immediately.
- """
-
- if response:
- slept = self.sleep_for_retry(response)
- if slept:
- return
-
- self._sleep_backoff()
-
- def _is_connection_error(self, err):
- """ Errors when we're fairly sure that the server did not receive the
- request, so it should be safe to retry.
- """
- return isinstance(err, ConnectTimeoutError)
-
- def _is_read_error(self, err):
- """ Errors that occur after the request has been started, so we should
- assume that the server began processing it.
- """
- return isinstance(err, (ReadTimeoutError, ProtocolError))
-
- def _is_method_retryable(self, method):
- """ Checks if a given HTTP method should be retried upon, depending if
- it is included on the method whitelist.
- """
- if self.method_whitelist and method.upper() not in self.method_whitelist:
- return False
-
- return True
-
- def is_retry(self, method, status_code, has_retry_after=False):
- """ Is this method/status code retryable? (Based on whitelists and control
- variables such as the number of total retries to allow, whether to
- respect the Retry-After header, whether this header is present, and
- whether the returned status code is on the list of status codes to
- be retried upon on the presence of the aforementioned header)
- """
- if not self._is_method_retryable(method):
- return False
-
- if self.status_forcelist and status_code in self.status_forcelist:
- return True
-
- return (self.total and self.respect_retry_after_header and
- has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES))
-
- def is_exhausted(self):
- """ Are we out of retries? """
- retry_counts = (self.total, self.connect, self.read, self.redirect)
- retry_counts = list(filter(None, retry_counts))
- if not retry_counts:
- return False
-
- return min(retry_counts) < 0
-
- def increment(self, method=None, url=None, response=None, error=None,
- _pool=None, _stacktrace=None):
- """ Return a new Retry object with incremented retry counters.
-
- :param response: A response object, or None, if the server did not
- return a response.
- :type response: :class:`~urllib3.response.HTTPResponse`
- :param Exception error: An error encountered during the request, or
- None if the response was received successfully.
-
- :return: A new ``Retry`` object.
- """
- if self.total is False and error:
- # Disabled, indicate to re-raise the error.
- raise six.reraise(type(error), error, _stacktrace)
-
- total = self.total
- if total is not None:
- total -= 1
-
- connect = self.connect
- read = self.read
- redirect = self.redirect
- cause = 'unknown'
- status = None
- redirect_location = None
-
- if error and self._is_connection_error(error):
- # Connect retry?
- if connect is False:
- raise six.reraise(type(error), error, _stacktrace)
- elif connect is not None:
- connect -= 1
-
- elif error and self._is_read_error(error):
- # Read retry?
- if read is False or not self._is_method_retryable(method):
- raise six.reraise(type(error), error, _stacktrace)
- elif read is not None:
- read -= 1
-
- elif response and response.get_redirect_location():
- # Redirect retry?
- if redirect is not None:
- redirect -= 1
- cause = 'too many redirects'
- redirect_location = response.get_redirect_location()
- status = response.status
-
- else:
- # Incrementing because of a server error like a 500 in
- # status_forcelist and a the given method is in the whitelist
- cause = ResponseError.GENERIC_ERROR
- if response and response.status:
- cause = ResponseError.SPECIFIC_ERROR.format(
- status_code=response.status)
- status = response.status
-
- history = self.history + (RequestHistory(method, url, error, status, redirect_location),)
-
- new_retry = self.new(
- total=total,
- connect=connect, read=read, redirect=redirect,
- history=history)
-
- if new_retry.is_exhausted():
- raise MaxRetryError(_pool, url, error or ResponseError(cause))
-
- log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
-
- return new_retry
-
- def __repr__(self):
- return ('{cls.__name__}(total={self.total}, connect={self.connect}, '
- 'read={self.read}, redirect={self.redirect})').format(
- cls=type(self), self=self)
-
-
-# For backwards compatibility (equivalent to pre-v1.9):
-Retry.DEFAULT = Retry(3)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/selectors.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/selectors.py
deleted file mode 100644
index 51208b69..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/selectors.py
+++ /dev/null
@@ -1,524 +0,0 @@
-# Backport of selectors.py from Python 3.5+ to support Python < 3.4
-# Also has the behavior specified in PEP 475 which is to retry syscalls
-# in the case of an EINTR error. This module is required because selectors34
-# does not follow this behavior and instead returns that no dile descriptor
-# events have occurred rather than retry the syscall. The decision to drop
-# support for select.devpoll is made to maintain 100% test coverage.
-
-import errno
-import math
-import select
-from collections import namedtuple, Mapping
-
-import time
-try:
- monotonic = time.monotonic
-except (AttributeError, ImportError): # Python 3.3<
- monotonic = time.time
-
-EVENT_READ = (1 << 0)
-EVENT_WRITE = (1 << 1)
-
-HAS_SELECT = True # Variable that shows whether the platform has a selector.
-_SYSCALL_SENTINEL = object() # Sentinel in case a system call returns None.
-
-
-class SelectorError(Exception):
- def __init__(self, errcode):
- super(SelectorError, self).__init__()
- self.errno = errcode
-
- def __repr__(self):
- return "<SelectorError errno={0}>".format(self.errno)
-
- def __str__(self):
- return self.__repr__()
-
-
-def _fileobj_to_fd(fileobj):
- """ Return a file descriptor from a file object. If
- given an integer will simply return that integer back. """
- if isinstance(fileobj, int):
- fd = fileobj
- else:
- try:
- fd = int(fileobj.fileno())
- except (AttributeError, TypeError, ValueError):
- raise ValueError("Invalid file object: {0!r}".format(fileobj))
- if fd < 0:
- raise ValueError("Invalid file descriptor: {0}".format(fd))
- return fd
-
-
-def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):
- """ Wrapper function for syscalls that could fail due to EINTR.
- All functions should be retried if there is time left in the timeout
- in accordance with PEP 475. """
- timeout = kwargs.get("timeout", None)
- if timeout is None:
- expires = None
- recalc_timeout = False
- else:
- timeout = float(timeout)
- if timeout < 0.0: # Timeout less than 0 treated as no timeout.
- expires = None
- else:
- expires = monotonic() + timeout
-
- args = list(args)
- if recalc_timeout and "timeout" not in kwargs:
- raise ValueError(
- "Timeout must be in args or kwargs to be recalculated")
-
- result = _SYSCALL_SENTINEL
- while result is _SYSCALL_SENTINEL:
- try:
- result = func(*args, **kwargs)
- # OSError is thrown by select.select
- # IOError is thrown by select.epoll.poll
- # select.error is thrown by select.poll.poll
- # Aren't we thankful for Python 3.x rework for exceptions?
- except (OSError, IOError, select.error) as e:
- # select.error wasn't a subclass of OSError in the past.
- errcode = None
- if hasattr(e, "errno"):
- errcode = e.errno
- elif hasattr(e, "args"):
- errcode = e.args[0]
-
- # Also test for the Windows equivalent of EINTR.
- is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and
- errcode == errno.WSAEINTR))
-
- if is_interrupt:
- if expires is not None:
- current_time = monotonic()
- if current_time > expires:
- raise OSError(errno=errno.ETIMEDOUT)
- if recalc_timeout:
- if "timeout" in kwargs:
- kwargs["timeout"] = expires - current_time
- continue
- if errcode:
- raise SelectorError(errcode)
- else:
- raise
- return result
-
-
-SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
-
-
-class _SelectorMapping(Mapping):
- """ Mapping of file objects to selector keys """
-
- def __init__(self, selector):
- self._selector = selector
-
- def __len__(self):
- return len(self._selector._fd_to_key)
-
- def __getitem__(self, fileobj):
- try:
- fd = self._selector._fileobj_lookup(fileobj)
- return self._selector._fd_to_key[fd]
- except KeyError:
- raise KeyError("{0!r} is not registered.".format(fileobj))
-
- def __iter__(self):
- return iter(self._selector._fd_to_key)
-
-
-class BaseSelector(object):
- """ Abstract Selector class
-
- A selector supports registering file objects to be monitored
- for specific I/O events.
-
- A file object is a file descriptor or any object with a
- `fileno()` method. An arbitrary object can be attached to the
- file object which can be used for example to store context info,
- a callback, etc.
-
- A selector can use various implementations (select(), poll(), epoll(),
- and kqueue()) depending on the platform. The 'DefaultSelector' class uses
- the most efficient implementation for the current platform.
- """
- def __init__(self):
- # Maps file descriptors to keys.
- self._fd_to_key = {}
-
- # Read-only mapping returned by get_map()
- self._map = _SelectorMapping(self)
-
- def _fileobj_lookup(self, fileobj):
- """ Return a file descriptor from a file object.
- This wraps _fileobj_to_fd() to do an exhaustive
- search in case the object is invalid but we still
- have it in our map. Used by unregister() so we can
- unregister an object that was previously registered
- even if it is closed. It is also used by _SelectorMapping
- """
- try:
- return _fileobj_to_fd(fileobj)
- except ValueError:
-
- # Search through all our mapped keys.
- for key in self._fd_to_key.values():
- if key.fileobj is fileobj:
- return key.fd
-
- # Raise ValueError after all.
- raise
-
- def register(self, fileobj, events, data=None):
- """ Register a file object for a set of events to monitor. """
- if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):
- raise ValueError("Invalid events: {0!r}".format(events))
-
- key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
-
- if key.fd in self._fd_to_key:
- raise KeyError("{0!r} (FD {1}) is already registered"
- .format(fileobj, key.fd))
-
- self._fd_to_key[key.fd] = key
- return key
-
- def unregister(self, fileobj):
- """ Unregister a file object from being monitored. """
- try:
- key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))
- except KeyError:
- raise KeyError("{0!r} is not registered".format(fileobj))
- return key
-
- def modify(self, fileobj, events, data=None):
- """ Change a registered file object monitored events and data. """
- # NOTE: Some subclasses optimize this operation even further.
- try:
- key = self._fd_to_key[self._fileobj_lookup(fileobj)]
- except KeyError:
- raise KeyError("{0!r} is not registered".format(fileobj))
-
- if events != key.events:
- self.unregister(fileobj)
- key = self.register(fileobj, events, data)
-
- elif data != key.data:
- # Use a shortcut to update the data.
- key = key._replace(data=data)
- self._fd_to_key[key.fd] = key
-
- return key
-
- def select(self, timeout=None):
- """ Perform the actual selection until some monitored file objects
- are ready or the timeout expires. """
- raise NotImplementedError()
-
- def close(self):
- """ Close the selector. This must be called to ensure that all
- underlying resources are freed. """
- self._fd_to_key.clear()
- self._map = None
-
- def get_key(self, fileobj):
- """ Return the key associated with a registered file object. """
- mapping = self.get_map()
- if mapping is None:
- raise RuntimeError("Selector is closed")
- try:
- return mapping[fileobj]
- except KeyError:
- raise KeyError("{0!r} is not registered".format(fileobj))
-
- def get_map(self):
- """ Return a mapping of file objects to selector keys """
- return self._map
-
- def _key_from_fd(self, fd):
- """ Return the key associated to a given file descriptor
- Return None if it is not found. """
- try:
- return self._fd_to_key[fd]
- except KeyError:
- return None
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- self.close()
-
-
-# Almost all platforms have select.select()
-if hasattr(select, "select"):
- class SelectSelector(BaseSelector):
- """ Select-based selector. """
- def __init__(self):
- super(SelectSelector, self).__init__()
- self._readers = set()
- self._writers = set()
-
- def register(self, fileobj, events, data=None):
- key = super(SelectSelector, self).register(fileobj, events, data)
- if events & EVENT_READ:
- self._readers.add(key.fd)
- if events & EVENT_WRITE:
- self._writers.add(key.fd)
- return key
-
- def unregister(self, fileobj):
- key = super(SelectSelector, self).unregister(fileobj)
- self._readers.discard(key.fd)
- self._writers.discard(key.fd)
- return key
-
- def _select(self, r, w, timeout=None):
- """ Wrapper for select.select because timeout is a positional arg """
- return select.select(r, w, [], timeout)
-
- def select(self, timeout=None):
- # Selecting on empty lists on Windows errors out.
- if not len(self._readers) and not len(self._writers):
- return []
-
- timeout = None if timeout is None else max(timeout, 0.0)
- ready = []
- r, w, _ = _syscall_wrapper(self._select, True, self._readers,
- self._writers, timeout)
- r = set(r)
- w = set(w)
- for fd in r | w:
- events = 0
- if fd in r:
- events |= EVENT_READ
- if fd in w:
- events |= EVENT_WRITE
-
- key = self._key_from_fd(fd)
- if key:
- ready.append((key, events & key.events))
- return ready
-
-
-if hasattr(select, "poll"):
- class PollSelector(BaseSelector):
- """ Poll-based selector """
- def __init__(self):
- super(PollSelector, self).__init__()
- self._poll = select.poll()
-
- def register(self, fileobj, events, data=None):
- key = super(PollSelector, self).register(fileobj, events, data)
- event_mask = 0
- if events & EVENT_READ:
- event_mask |= select.POLLIN
- if events & EVENT_WRITE:
- event_mask |= select.POLLOUT
- self._poll.register(key.fd, event_mask)
- return key
-
- def unregister(self, fileobj):
- key = super(PollSelector, self).unregister(fileobj)
- self._poll.unregister(key.fd)
- return key
-
- def _wrap_poll(self, timeout=None):
- """ Wrapper function for select.poll.poll() so that
- _syscall_wrapper can work with only seconds. """
- if timeout is not None:
- if timeout <= 0:
- timeout = 0
- else:
- # select.poll.poll() has a resolution of 1 millisecond,
- # round away from zero to wait *at least* timeout seconds.
- timeout = math.ceil(timeout * 1e3)
-
- result = self._poll.poll(timeout)
- return result
-
- def select(self, timeout=None):
- ready = []
- fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
- for fd, event_mask in fd_events:
- events = 0
- if event_mask & ~select.POLLIN:
- events |= EVENT_WRITE
- if event_mask & ~select.POLLOUT:
- events |= EVENT_READ
-
- key = self._key_from_fd(fd)
- if key:
- ready.append((key, events & key.events))
-
- return ready
-
-
-if hasattr(select, "epoll"):
- class EpollSelector(BaseSelector):
- """ Epoll-based selector """
- def __init__(self):
- super(EpollSelector, self).__init__()
- self._epoll = select.epoll()
-
- def fileno(self):
- return self._epoll.fileno()
-
- def register(self, fileobj, events, data=None):
- key = super(EpollSelector, self).register(fileobj, events, data)
- events_mask = 0
- if events & EVENT_READ:
- events_mask |= select.EPOLLIN
- if events & EVENT_WRITE:
- events_mask |= select.EPOLLOUT
- _syscall_wrapper(self._epoll.register, False, key.fd, events_mask)
- return key
-
- def unregister(self, fileobj):
- key = super(EpollSelector, self).unregister(fileobj)
- try:
- _syscall_wrapper(self._epoll.unregister, False, key.fd)
- except SelectorError:
- # This can occur when the fd was closed since registry.
- pass
- return key
-
- def select(self, timeout=None):
- if timeout is not None:
- if timeout <= 0:
- timeout = 0.0
- else:
- # select.epoll.poll() has a resolution of 1 millisecond
- # but luckily takes seconds so we don't need a wrapper
- # like PollSelector. Just for better rounding.
- timeout = math.ceil(timeout * 1e3) * 1e-3
- timeout = float(timeout)
- else:
- timeout = -1.0 # epoll.poll() must have a float.
-
- # We always want at least 1 to ensure that select can be called
- # with no file descriptors registered. Otherwise will fail.
- max_events = max(len(self._fd_to_key), 1)
-
- ready = []
- fd_events = _syscall_wrapper(self._epoll.poll, True,
- timeout=timeout,
- maxevents=max_events)
- for fd, event_mask in fd_events:
- events = 0
- if event_mask & ~select.EPOLLIN:
- events |= EVENT_WRITE
- if event_mask & ~select.EPOLLOUT:
- events |= EVENT_READ
-
- key = self._key_from_fd(fd)
- if key:
- ready.append((key, events & key.events))
- return ready
-
- def close(self):
- self._epoll.close()
- super(EpollSelector, self).close()
-
-
-if hasattr(select, "kqueue"):
- class KqueueSelector(BaseSelector):
- """ Kqueue / Kevent-based selector """
- def __init__(self):
- super(KqueueSelector, self).__init__()
- self._kqueue = select.kqueue()
-
- def fileno(self):
- return self._kqueue.fileno()
-
- def register(self, fileobj, events, data=None):
- key = super(KqueueSelector, self).register(fileobj, events, data)
- if events & EVENT_READ:
- kevent = select.kevent(key.fd,
- select.KQ_FILTER_READ,
- select.KQ_EV_ADD)
-
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
-
- if events & EVENT_WRITE:
- kevent = select.kevent(key.fd,
- select.KQ_FILTER_WRITE,
- select.KQ_EV_ADD)
-
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
-
- return key
-
- def unregister(self, fileobj):
- key = super(KqueueSelector, self).unregister(fileobj)
- if key.events & EVENT_READ:
- kevent = select.kevent(key.fd,
- select.KQ_FILTER_READ,
- select.KQ_EV_DELETE)
- try:
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
- except SelectorError:
- pass
- if key.events & EVENT_WRITE:
- kevent = select.kevent(key.fd,
- select.KQ_FILTER_WRITE,
- select.KQ_EV_DELETE)
- try:
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
- except SelectorError:
- pass
-
- return key
-
- def select(self, timeout=None):
- if timeout is not None:
- timeout = max(timeout, 0)
-
- max_events = len(self._fd_to_key) * 2
- ready_fds = {}
-
- kevent_list = _syscall_wrapper(self._kqueue.control, True,
- None, max_events, timeout)
-
- for kevent in kevent_list:
- fd = kevent.ident
- event_mask = kevent.filter
- events = 0
- if event_mask == select.KQ_FILTER_READ:
- events |= EVENT_READ
- if event_mask == select.KQ_FILTER_WRITE:
- events |= EVENT_WRITE
-
- key = self._key_from_fd(fd)
- if key:
- if key.fd not in ready_fds:
- ready_fds[key.fd] = (key, events & key.events)
- else:
- old_events = ready_fds[key.fd][1]
- ready_fds[key.fd] = (key, (events | old_events) & key.events)
-
- return list(ready_fds.values())
-
- def close(self):
- self._kqueue.close()
- super(KqueueSelector, self).close()
-
-
-# Choose the best implementation, roughly:
-# kqueue == epoll > poll > select. Devpoll not supported. (See above)
-# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
-if 'KqueueSelector' in globals(): # Platform-specific: Mac OS and BSD
- DefaultSelector = KqueueSelector
-elif 'EpollSelector' in globals(): # Platform-specific: Linux
- DefaultSelector = EpollSelector
-elif 'PollSelector' in globals(): # Platform-specific: Linux
- DefaultSelector = PollSelector
-elif 'SelectSelector' in globals(): # Platform-specific: Windows
- DefaultSelector = SelectSelector
-else: # Platform-specific: AppEngine
- def no_selector(_):
- raise ValueError("Platform does not have a selector")
- DefaultSelector = no_selector
- HAS_SELECT = False
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py
deleted file mode 100644
index c4c55df6..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py
+++ /dev/null
@@ -1,336 +0,0 @@
-from __future__ import absolute_import
-import errno
-import warnings
-import hmac
-
-from binascii import hexlify, unhexlify
-from hashlib import md5, sha1, sha256
-
-from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning
-
-
-SSLContext = None
-HAS_SNI = False
-IS_PYOPENSSL = False
-
-# Maps the length of a digest to a possible hash function producing this digest
-HASHFUNC_MAP = {
- 32: md5,
- 40: sha1,
- 64: sha256,
-}
-
-
-def _const_compare_digest_backport(a, b):
- """
- Compare two digests of equal length in constant time.
-
- The digests must be of type str/bytes.
- Returns True if the digests match, and False otherwise.
- """
- result = abs(len(a) - len(b))
- for l, r in zip(bytearray(a), bytearray(b)):
- result |= l ^ r
- return result == 0
-
-
-_const_compare_digest = getattr(hmac, 'compare_digest',
- _const_compare_digest_backport)
-
-
-try: # Test for SSL features
- import ssl
- from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23
- from ssl import HAS_SNI # Has SNI?
-except ImportError:
- pass
-
-
-try:
- from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION
-except ImportError:
- OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000
- OP_NO_COMPRESSION = 0x20000
-
-# A secure default.
-# Sources for more information on TLS ciphers:
-#
-# - https://wiki.mozilla.org/Security/Server_Side_TLS
-# - https://www.ssllabs.com/projects/best-practices/index.html
-# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
-#
-# The general intent is:
-# - Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE),
-# - prefer ECDHE over DHE for better performance,
-# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and
-# security,
-# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common,
-# - disable NULL authentication, MD5 MACs and DSS for security reasons.
-DEFAULT_CIPHERS = ':'.join([
- 'ECDH+AESGCM',
- 'ECDH+CHACHA20',
- 'DH+AESGCM',
- 'DH+CHACHA20',
- 'ECDH+AES256',
- 'DH+AES256',
- 'ECDH+AES128',
- 'DH+AES',
- 'RSA+AESGCM',
- 'RSA+AES',
- '!aNULL',
- '!eNULL',
- '!MD5',
-])
-
-try:
- from ssl import SSLContext # Modern SSL?
-except ImportError:
- import sys
-
- class SSLContext(object): # Platform-specific: Python 2 & 3.1
- supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or
- (3, 2) <= sys.version_info)
-
- def __init__(self, protocol_version):
- self.protocol = protocol_version
- # Use default values from a real SSLContext
- self.check_hostname = False
- self.verify_mode = ssl.CERT_NONE
- self.ca_certs = None
- self.options = 0
- self.certfile = None
- self.keyfile = None
- self.ciphers = None
-
- def load_cert_chain(self, certfile, keyfile):
- self.certfile = certfile
- self.keyfile = keyfile
-
- def load_verify_locations(self, cafile=None, capath=None):
- self.ca_certs = cafile
-
- if capath is not None:
- raise SSLError("CA directories not supported in older Pythons")
-
- def set_ciphers(self, cipher_suite):
- if not self.supports_set_ciphers:
- raise TypeError(
- 'Your version of Python does not support setting '
- 'a custom cipher suite. Please upgrade to Python '
- '2.7, 3.2, or later if you need this functionality.'
- )
- self.ciphers = cipher_suite
-
- def wrap_socket(self, socket, server_hostname=None, server_side=False):
- warnings.warn(
- 'A true SSLContext object is not available. This prevents '
- 'urllib3 from configuring SSL appropriately and may cause '
- 'certain SSL connections to fail. You can upgrade to a newer '
- 'version of Python to solve this. For more information, see '
- 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html'
- '#ssl-warnings',
- InsecurePlatformWarning
- )
- kwargs = {
- 'keyfile': self.keyfile,
- 'certfile': self.certfile,
- 'ca_certs': self.ca_certs,
- 'cert_reqs': self.verify_mode,
- 'ssl_version': self.protocol,
- 'server_side': server_side,
- }
- if self.supports_set_ciphers: # Platform-specific: Python 2.7+
- return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
- else: # Platform-specific: Python 2.6
- return wrap_socket(socket, **kwargs)
-
-
-def assert_fingerprint(cert, fingerprint):
- """
- Checks if given fingerprint matches the supplied certificate.
-
- :param cert:
- Certificate as bytes object.
- :param fingerprint:
- Fingerprint as string of hexdigits, can be interspersed by colons.
- """
-
- fingerprint = fingerprint.replace(':', '').lower()
- digest_length = len(fingerprint)
- hashfunc = HASHFUNC_MAP.get(digest_length)
- if not hashfunc:
- raise SSLError(
- 'Fingerprint of invalid length: {0}'.format(fingerprint))
-
- # We need encode() here for py32; works on py2 and p33.
- fingerprint_bytes = unhexlify(fingerprint.encode())
-
- cert_digest = hashfunc(cert).digest()
-
- if not _const_compare_digest(cert_digest, fingerprint_bytes):
- raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".'
- .format(fingerprint, hexlify(cert_digest)))
-
-
-def resolve_cert_reqs(candidate):
- """
- Resolves the argument to a numeric constant, which can be passed to
- the wrap_socket function/method from the ssl module.
- Defaults to :data:`ssl.CERT_NONE`.
- If given a string it is assumed to be the name of the constant in the
- :mod:`ssl` module or its abbrevation.
- (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
- If it's neither `None` nor a string we assume it is already the numeric
- constant which can directly be passed to wrap_socket.
- """
- if candidate is None:
- return CERT_NONE
-
- if isinstance(candidate, str):
- res = getattr(ssl, candidate, None)
- if res is None:
- res = getattr(ssl, 'CERT_' + candidate)
- return res
-
- return candidate
-
-
-def resolve_ssl_version(candidate):
- """
- like resolve_cert_reqs
- """
- if candidate is None:
- return PROTOCOL_SSLv23
-
- if isinstance(candidate, str):
- res = getattr(ssl, candidate, None)
- if res is None:
- res = getattr(ssl, 'PROTOCOL_' + candidate)
- return res
-
- return candidate
-
-
-def create_urllib3_context(ssl_version=None, cert_reqs=None,
- options=None, ciphers=None):
- """All arguments have the same meaning as ``ssl_wrap_socket``.
-
- By default, this function does a lot of the same work that
- ``ssl.create_default_context`` does on Python 3.4+. It:
-
- - Disables SSLv2, SSLv3, and compression
- - Sets a restricted set of server ciphers
-
- If you wish to enable SSLv3, you can do::
-
- from urllib3.util import ssl_
- context = ssl_.create_urllib3_context()
- context.options &= ~ssl_.OP_NO_SSLv3
-
- You can do the same to enable compression (substituting ``COMPRESSION``
- for ``SSLv3`` in the last line above).
-
- :param ssl_version:
- The desired protocol version to use. This will default to
- PROTOCOL_SSLv23 which will negotiate the highest protocol that both
- the server and your installation of OpenSSL support.
- :param cert_reqs:
- Whether to require the certificate verification. This defaults to
- ``ssl.CERT_REQUIRED``.
- :param options:
- Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
- ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``.
- :param ciphers:
- Which cipher suites to allow the server to select.
- :returns:
- Constructed SSLContext object with specified options
- :rtype: SSLContext
- """
- context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23)
-
- # Setting the default here, as we may have no ssl module on import
- cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
-
- if options is None:
- options = 0
- # SSLv2 is easily broken and is considered harmful and dangerous
- options |= OP_NO_SSLv2
- # SSLv3 has several problems and is now dangerous
- options |= OP_NO_SSLv3
- # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
- # (issue #309)
- options |= OP_NO_COMPRESSION
-
- context.options |= options
-
- if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6
- context.set_ciphers(ciphers or DEFAULT_CIPHERS)
-
- context.verify_mode = cert_reqs
- if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2
- # We do our own verification, including fingerprints and alternative
- # hostnames. So disable it here
- context.check_hostname = False
- return context
-
-
-def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
- ca_certs=None, server_hostname=None,
- ssl_version=None, ciphers=None, ssl_context=None,
- ca_cert_dir=None):
- """
- All arguments except for server_hostname, ssl_context, and ca_cert_dir have
- the same meaning as they do when using :func:`ssl.wrap_socket`.
-
- :param server_hostname:
- When SNI is supported, the expected hostname of the certificate
- :param ssl_context:
- A pre-made :class:`SSLContext` object. If none is provided, one will
- be created using :func:`create_urllib3_context`.
- :param ciphers:
- A string of ciphers we wish the client to support. This is not
- supported on Python 2.6 as the ssl module does not support it.
- :param ca_cert_dir:
- A directory containing CA certificates in multiple separate files, as
- supported by OpenSSL's -CApath flag or the capath argument to
- SSLContext.load_verify_locations().
- """
- context = ssl_context
- if context is None:
- # Note: This branch of code and all the variables in it are no longer
- # used by urllib3 itself. We should consider deprecating and removing
- # this code.
- context = create_urllib3_context(ssl_version, cert_reqs,
- ciphers=ciphers)
-
- if ca_certs or ca_cert_dir:
- try:
- context.load_verify_locations(ca_certs, ca_cert_dir)
- except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2
- raise SSLError(e)
- # Py33 raises FileNotFoundError which subclasses OSError
- # These are not equivalent unless we check the errno attribute
- except OSError as e: # Platform-specific: Python 3.3 and beyond
- if e.errno == errno.ENOENT:
- raise SSLError(e)
- raise
- elif getattr(context, 'load_default_certs', None) is not None:
- # try to load OS default certs; works well on Windows (require Python3.4+)
- context.load_default_certs()
-
- if certfile:
- context.load_cert_chain(certfile, keyfile)
- if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI
- return context.wrap_socket(sock, server_hostname=server_hostname)
-
- warnings.warn(
- 'An HTTPS request has been made, but the SNI (Subject Name '
- 'Indication) extension to TLS is not available on this platform. '
- 'This may cause the server to present an incorrect TLS '
- 'certificate, which can cause validation failures. You can upgrade to '
- 'a newer version of Python to solve this. For more information, see '
- 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html'
- '#ssl-warnings',
- SNIMissingWarning
- )
- return context.wrap_socket(sock)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/timeout.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/timeout.py
deleted file mode 100644
index cec817e6..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/timeout.py
+++ /dev/null
@@ -1,242 +0,0 @@
-from __future__ import absolute_import
-# The default socket timeout, used by httplib to indicate that no timeout was
-# specified by the user
-from socket import _GLOBAL_DEFAULT_TIMEOUT
-import time
-
-from ..exceptions import TimeoutStateError
-
-# A sentinel value to indicate that no timeout was specified by the user in
-# urllib3
-_Default = object()
-
-
-# Use time.monotonic if available.
-current_time = getattr(time, "monotonic", time.time)
-
-
-class Timeout(object):
- """ Timeout configuration.
-
- Timeouts can be defined as a default for a pool::
-
- timeout = Timeout(connect=2.0, read=7.0)
- http = PoolManager(timeout=timeout)
- response = http.request('GET', 'http://example.com/')
-
- Or per-request (which overrides the default for the pool)::
-
- response = http.request('GET', 'http://example.com/', timeout=Timeout(10))
-
- Timeouts can be disabled by setting all the parameters to ``None``::
-
- no_timeout = Timeout(connect=None, read=None)
- response = http.request('GET', 'http://example.com/, timeout=no_timeout)
-
-
- :param total:
- This combines the connect and read timeouts into one; the read timeout
- will be set to the time leftover from the connect attempt. In the
- event that both a connect timeout and a total are specified, or a read
- timeout and a total are specified, the shorter timeout will be applied.
-
- Defaults to None.
-
- :type total: integer, float, or None
-
- :param connect:
- The maximum amount of time to wait for a connection attempt to a server
- to succeed. Omitting the parameter will default the connect timeout to
- the system default, probably `the global default timeout in socket.py
- <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
- None will set an infinite timeout for connection attempts.
-
- :type connect: integer, float, or None
-
- :param read:
- The maximum amount of time to wait between consecutive
- read operations for a response from the server. Omitting
- the parameter will default the read timeout to the system
- default, probably `the global default timeout in socket.py
- <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
- None will set an infinite timeout.
-
- :type read: integer, float, or None
-
- .. note::
-
- Many factors can affect the total amount of time for urllib3 to return
- an HTTP response.
-
- For example, Python's DNS resolver does not obey the timeout specified
- on the socket. Other factors that can affect total request time include
- high CPU load, high swap, the program running at a low priority level,
- or other behaviors.
-
- In addition, the read and total timeouts only measure the time between
- read operations on the socket connecting the client and the server,
- not the total amount of time for the request to return a complete
- response. For most requests, the timeout is raised because the server
- has not sent the first byte in the specified time. This is not always
- the case; if a server streams one byte every fifteen seconds, a timeout
- of 20 seconds will not trigger, even though the request will take
- several minutes to complete.
-
- If your goal is to cut off any request after a set amount of wall clock
- time, consider having a second "watcher" thread to cut off a slow
- request.
- """
-
- #: A sentinel object representing the default timeout value
- DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT
-
- def __init__(self, total=None, connect=_Default, read=_Default):
- self._connect = self._validate_timeout(connect, 'connect')
- self._read = self._validate_timeout(read, 'read')
- self.total = self._validate_timeout(total, 'total')
- self._start_connect = None
-
- def __str__(self):
- return '%s(connect=%r, read=%r, total=%r)' % (
- type(self).__name__, self._connect, self._read, self.total)
-
- @classmethod
- def _validate_timeout(cls, value, name):
- """ Check that a timeout attribute is valid.
-
- :param value: The timeout value to validate
- :param name: The name of the timeout attribute to validate. This is
- used to specify in error messages.
- :return: The validated and casted version of the given value.
- :raises ValueError: If it is a numeric value less than or equal to
- zero, or the type is not an integer, float, or None.
- """
- if value is _Default:
- return cls.DEFAULT_TIMEOUT
-
- if value is None or value is cls.DEFAULT_TIMEOUT:
- return value
-
- if isinstance(value, bool):
- raise ValueError("Timeout cannot be a boolean value. It must "
- "be an int, float or None.")
- try:
- float(value)
- except (TypeError, ValueError):
- raise ValueError("Timeout value %s was %s, but it must be an "
- "int, float or None." % (name, value))
-
- try:
- if value <= 0:
- raise ValueError("Attempted to set %s timeout to %s, but the "
- "timeout cannot be set to a value less "
- "than or equal to 0." % (name, value))
- except TypeError: # Python 3
- raise ValueError("Timeout value %s was %s, but it must be an "
- "int, float or None." % (name, value))
-
- return value
-
- @classmethod
- def from_float(cls, timeout):
- """ Create a new Timeout from a legacy timeout value.
-
- The timeout value used by httplib.py sets the same timeout on the
- connect(), and recv() socket requests. This creates a :class:`Timeout`
- object that sets the individual timeouts to the ``timeout`` value
- passed to this function.
-
- :param timeout: The legacy timeout value.
- :type timeout: integer, float, sentinel default object, or None
- :return: Timeout object
- :rtype: :class:`Timeout`
- """
- return Timeout(read=timeout, connect=timeout)
-
- def clone(self):
- """ Create a copy of the timeout object
-
- Timeout properties are stored per-pool but each request needs a fresh
- Timeout object to ensure each one has its own start/stop configured.
-
- :return: a copy of the timeout object
- :rtype: :class:`Timeout`
- """
- # We can't use copy.deepcopy because that will also create a new object
- # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to
- # detect the user default.
- return Timeout(connect=self._connect, read=self._read,
- total=self.total)
-
- def start_connect(self):
- """ Start the timeout clock, used during a connect() attempt
-
- :raises urllib3.exceptions.TimeoutStateError: if you attempt
- to start a timer that has been started already.
- """
- if self._start_connect is not None:
- raise TimeoutStateError("Timeout timer has already been started.")
- self._start_connect = current_time()
- return self._start_connect
-
- def get_connect_duration(self):
- """ Gets the time elapsed since the call to :meth:`start_connect`.
-
- :return: Elapsed time.
- :rtype: float
- :raises urllib3.exceptions.TimeoutStateError: if you attempt
- to get duration for a timer that hasn't been started.
- """
- if self._start_connect is None:
- raise TimeoutStateError("Can't get connect duration for timer "
- "that has not started.")
- return current_time() - self._start_connect
-
- @property
- def connect_timeout(self):
- """ Get the value to use when setting a connection timeout.
-
- This will be a positive float or integer, the value None
- (never timeout), or the default system timeout.
-
- :return: Connect timeout.
- :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
- """
- if self.total is None:
- return self._connect
-
- if self._connect is None or self._connect is self.DEFAULT_TIMEOUT:
- return self.total
-
- return min(self._connect, self.total)
-
- @property
- def read_timeout(self):
- """ Get the value for the read timeout.
-
- This assumes some time has elapsed in the connection timeout and
- computes the read timeout appropriately.
-
- If self.total is set, the read timeout is dependent on the amount of
- time taken by the connect timeout. If the connection time has not been
- established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be
- raised.
-
- :return: Value to use for the read timeout.
- :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
- :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect`
- has not yet been called on this object.
- """
- if (self.total is not None and
- self.total is not self.DEFAULT_TIMEOUT and
- self._read is not None and
- self._read is not self.DEFAULT_TIMEOUT):
- # In case the connect timeout has not yet been established.
- if self._start_connect is None:
- return self._read
- return max(0, min(self.total - self.get_connect_duration(),
- self._read))
- elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT:
- return max(0, self.total - self.get_connect_duration())
- else:
- return self._read
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/url.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/url.py
deleted file mode 100644
index 61a326e4..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/url.py
+++ /dev/null
@@ -1,226 +0,0 @@
-from __future__ import absolute_import
-from collections import namedtuple
-
-from ..exceptions import LocationParseError
-
-
-url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment']
-
-
-class Url(namedtuple('Url', url_attrs)):
- """
- Datastructure for representing an HTTP URL. Used as a return value for
- :func:`parse_url`. Both the scheme and host are normalized as they are
- both case-insensitive according to RFC 3986.
- """
- __slots__ = ()
-
- def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None,
- query=None, fragment=None):
- if path and not path.startswith('/'):
- path = '/' + path
- if scheme:
- scheme = scheme.lower()
- if host:
- host = host.lower()
- return super(Url, cls).__new__(cls, scheme, auth, host, port, path,
- query, fragment)
-
- @property
- def hostname(self):
- """For backwards-compatibility with urlparse. We're nice like that."""
- return self.host
-
- @property
- def request_uri(self):
- """Absolute path including the query string."""
- uri = self.path or '/'
-
- if self.query is not None:
- uri += '?' + self.query
-
- return uri
-
- @property
- def netloc(self):
- """Network location including host and port"""
- if self.port:
- return '%s:%d' % (self.host, self.port)
- return self.host
-
- @property
- def url(self):
- """
- Convert self into a url
-
- This function should more or less round-trip with :func:`.parse_url`. The
- returned url may not be exactly the same as the url inputted to
- :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
- with a blank port will have : removed).
-
- Example: ::
-
- >>> U = parse_url('http://google.com/mail/')
- >>> U.url
- 'http://google.com/mail/'
- >>> Url('http', 'username:password', 'host.com', 80,
- ... '/path', 'query', 'fragment').url
- 'http://username:password@host.com:80/path?query#fragment'
- """
- scheme, auth, host, port, path, query, fragment = self
- url = ''
-
- # We use "is not None" we want things to happen with empty strings (or 0 port)
- if scheme is not None:
- url += scheme + '://'
- if auth is not None:
- url += auth + '@'
- if host is not None:
- url += host
- if port is not None:
- url += ':' + str(port)
- if path is not None:
- url += path
- if query is not None:
- url += '?' + query
- if fragment is not None:
- url += '#' + fragment
-
- return url
-
- def __str__(self):
- return self.url
-
-
-def split_first(s, delims):
- """
- Given a string and an iterable of delimiters, split on the first found
- delimiter. Return two split parts and the matched delimiter.
-
- If not found, then the first part is the full input string.
-
- Example::
-
- >>> split_first('foo/bar?baz', '?/=')
- ('foo', 'bar?baz', '/')
- >>> split_first('foo/bar?baz', '123')
- ('foo/bar?baz', '', None)
-
- Scales linearly with number of delims. Not ideal for large number of delims.
- """
- min_idx = None
- min_delim = None
- for d in delims:
- idx = s.find(d)
- if idx < 0:
- continue
-
- if min_idx is None or idx < min_idx:
- min_idx = idx
- min_delim = d
-
- if min_idx is None or min_idx < 0:
- return s, '', None
-
- return s[:min_idx], s[min_idx + 1:], min_delim
-
-
-def parse_url(url):
- """
- Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
- performed to parse incomplete urls. Fields not provided will be None.
-
- Partly backwards-compatible with :mod:`urlparse`.
-
- Example::
-
- >>> parse_url('http://google.com/mail/')
- Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
- >>> parse_url('google.com:80')
- Url(scheme=None, host='google.com', port=80, path=None, ...)
- >>> parse_url('/foo?bar')
- Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
- """
-
- # While this code has overlap with stdlib's urlparse, it is much
- # simplified for our needs and less annoying.
- # Additionally, this implementations does silly things to be optimal
- # on CPython.
-
- if not url:
- # Empty
- return Url()
-
- scheme = None
- auth = None
- host = None
- port = None
- path = None
- fragment = None
- query = None
-
- # Scheme
- if '://' in url:
- scheme, url = url.split('://', 1)
-
- # Find the earliest Authority Terminator
- # (http://tools.ietf.org/html/rfc3986#section-3.2)
- url, path_, delim = split_first(url, ['/', '?', '#'])
-
- if delim:
- # Reassemble the path
- path = delim + path_
-
- # Auth
- if '@' in url:
- # Last '@' denotes end of auth part
- auth, url = url.rsplit('@', 1)
-
- # IPv6
- if url and url[0] == '[':
- host, url = url.split(']', 1)
- host += ']'
-
- # Port
- if ':' in url:
- _host, port = url.split(':', 1)
-
- if not host:
- host = _host
-
- if port:
- # If given, ports must be integers. No whitespace, no plus or
- # minus prefixes, no non-integer digits such as ^2 (superscript).
- if not port.isdigit():
- raise LocationParseError(url)
- try:
- port = int(port)
- except ValueError:
- raise LocationParseError(url)
- else:
- # Blank ports are cool, too. (rfc3986#section-3.2.3)
- port = None
-
- elif not host and url:
- host = url
-
- if not path:
- return Url(scheme, auth, host, port, path, query, fragment)
-
- # Fragment
- if '#' in path:
- path, fragment = path.split('#', 1)
-
- # Query
- if '?' in path:
- path, query = path.split('?', 1)
-
- return Url(scheme, auth, host, port, path, query, fragment)
-
-
-def get_host(url):
- """
- Deprecated. Use :func:`parse_url` instead.
- """
- p = parse_url(url)
- return p.scheme or 'http', p.hostname, p.port
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/wait.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/wait.py
deleted file mode 100644
index cb396e50..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/packages/urllib3/util/wait.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from .selectors import (
- HAS_SELECT,
- DefaultSelector,
- EVENT_READ,
- EVENT_WRITE
-)
-
-
-def _wait_for_io_events(socks, events, timeout=None):
- """ Waits for IO events to be available from a list of sockets
- or optionally a single socket if passed in. Returns a list of
- sockets that can be interacted with immediately. """
- if not HAS_SELECT:
- raise ValueError('Platform does not have a selector')
- if not isinstance(socks, list):
- # Probably just a single socket.
- if hasattr(socks, "fileno"):
- socks = [socks]
- # Otherwise it might be a non-list iterable.
- else:
- socks = list(socks)
- with DefaultSelector() as selector:
- for sock in socks:
- selector.register(sock, events)
- return [key[0].fileobj for key in
- selector.select(timeout) if key[1] & events]
-
-
-def wait_for_read(socks, timeout=None):
- """ Waits for reading to be available from a list of sockets
- or optionally a single socket if passed in. Returns a list of
- sockets that can be read from immediately. """
- return _wait_for_io_events(socks, EVENT_READ, timeout)
-
-
-def wait_for_write(socks, timeout=None):
- """ Waits for writing to be available from a list of sockets
- or optionally a single socket if passed in. Returns a list of
- sockets that can be written to immediately. """
- return _wait_for_io_events(socks, EVENT_WRITE, timeout)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/sessions.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/sessions.py
deleted file mode 100644
index 7983282a..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/sessions.py
+++ /dev/null
@@ -1,725 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.session
-~~~~~~~~~~~~~~~~
-
-This module provides a Session object to manage and persist settings across
-requests (cookies, auth, proxies).
-"""
-import os
-from collections import Mapping
-from datetime import datetime
-
-from .auth import _basic_auth_str
-from .compat import cookielib, OrderedDict, urljoin, urlparse
-from .cookies import (
- cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
-from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
-from .hooks import default_hooks, dispatch_hook
-from ._internal_utils import to_native_string
-from .utils import to_key_val_list, default_headers
-from .exceptions import (
- TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError)
-from .packages.urllib3._collections import RecentlyUsedContainer
-from .structures import CaseInsensitiveDict
-
-from .adapters import HTTPAdapter
-
-from .utils import (
- requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies,
- get_auth_from_url, rewind_body
-)
-
-from .status_codes import codes
-
-# formerly defined here, reexposed here for backward compatibility
-from .models import REDIRECT_STATI
-
-REDIRECT_CACHE_SIZE = 1000
-
-
-def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
- """Determines appropriate setting for a given request, taking into account
- the explicit setting on that request, and the setting in the session. If a
- setting is a dictionary, they will be merged together using `dict_class`
- """
-
- if session_setting is None:
- return request_setting
-
- if request_setting is None:
- return session_setting
-
- # Bypass if not a dictionary (e.g. verify)
- if not (
- isinstance(session_setting, Mapping) and
- isinstance(request_setting, Mapping)
- ):
- return request_setting
-
- merged_setting = dict_class(to_key_val_list(session_setting))
- merged_setting.update(to_key_val_list(request_setting))
-
- # Remove keys that are set to None. Extract keys first to avoid altering
- # the dictionary during iteration.
- none_keys = [k for (k, v) in merged_setting.items() if v is None]
- for key in none_keys:
- del merged_setting[key]
-
- return merged_setting
-
-
-def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
- """Properly merges both requests and session hooks.
-
- This is necessary because when request_hooks == {'response': []}, the
- merge breaks Session hooks entirely.
- """
- if session_hooks is None or session_hooks.get('response') == []:
- return request_hooks
-
- if request_hooks is None or request_hooks.get('response') == []:
- return session_hooks
-
- return merge_setting(request_hooks, session_hooks, dict_class)
-
-
-class SessionRedirectMixin(object):
- def resolve_redirects(self, resp, req, stream=False, timeout=None,
- verify=True, cert=None, proxies=None, **adapter_kwargs):
- """Receives a Response. Returns a generator of Responses."""
-
- i = 0
- hist = [] # keep track of history
-
- while resp.is_redirect:
- prepared_request = req.copy()
-
- if i > 0:
- # Update history and keep track of redirects.
- hist.append(resp)
- new_hist = list(hist)
- resp.history = new_hist
-
- try:
- resp.content # Consume socket so it can be released
- except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
- resp.raw.read(decode_content=False)
-
- if i >= self.max_redirects:
- raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp)
-
- # Release the connection back into the pool.
- resp.close()
-
- url = resp.headers['location']
-
- # Handle redirection without scheme (see: RFC 1808 Section 4)
- if url.startswith('//'):
- parsed_rurl = urlparse(resp.url)
- url = '%s:%s' % (parsed_rurl.scheme, url)
-
- # The scheme should be lower case...
- parsed = urlparse(url)
- url = parsed.geturl()
-
- # Facilitate relative 'location' headers, as allowed by RFC 7231.
- # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
- # Compliant with RFC3986, we percent encode the url.
- if not parsed.netloc:
- url = urljoin(resp.url, requote_uri(url))
- else:
- url = requote_uri(url)
-
- prepared_request.url = to_native_string(url)
- # Cache the url, unless it redirects to itself.
- if resp.is_permanent_redirect and req.url != prepared_request.url:
- self.redirect_cache[req.url] = prepared_request.url
-
- self.rebuild_method(prepared_request, resp)
-
- # https://github.com/kennethreitz/requests/issues/1084
- if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect):
- # https://github.com/kennethreitz/requests/issues/3490
- purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding')
- for header in purged_headers:
- prepared_request.headers.pop(header, None)
- prepared_request.body = None
-
- headers = prepared_request.headers
- try:
- del headers['Cookie']
- except KeyError:
- pass
-
- # Extract any cookies sent on the response to the cookiejar
- # in the new request. Because we've mutated our copied prepared
- # request, use the old one that we haven't yet touched.
- extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)
- merge_cookies(prepared_request._cookies, self.cookies)
- prepared_request.prepare_cookies(prepared_request._cookies)
-
- # Rebuild auth and proxy information.
- proxies = self.rebuild_proxies(prepared_request, proxies)
- self.rebuild_auth(prepared_request, resp)
-
- # A failed tell() sets `_body_position` to `object()`. This non-None
- # value ensures `rewindable` will be True, allowing us to raise an
- # UnrewindableBodyError, instead of hanging the connection.
- rewindable = (
- prepared_request._body_position is not None and
- ('Content-Length' in headers or 'Transfer-Encoding' in headers)
- )
-
- # Attempt to rewind consumed file-like object.
- if rewindable:
- rewind_body(prepared_request)
-
- # Override the original request.
- req = prepared_request
-
- resp = self.send(
- req,
- stream=stream,
- timeout=timeout,
- verify=verify,
- cert=cert,
- proxies=proxies,
- allow_redirects=False,
- **adapter_kwargs
- )
-
- extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
-
- i += 1
- yield resp
-
- def rebuild_auth(self, prepared_request, response):
- """When being redirected we may want to strip authentication from the
- request to avoid leaking credentials. This method intelligently removes
- and reapplies authentication where possible to avoid credential loss.
- """
- headers = prepared_request.headers
- url = prepared_request.url
-
- if 'Authorization' in headers:
- # If we get redirected to a new host, we should strip out any
- # authentication headers.
- original_parsed = urlparse(response.request.url)
- redirect_parsed = urlparse(url)
-
- if (original_parsed.hostname != redirect_parsed.hostname):
- del headers['Authorization']
-
- # .netrc might have more auth for us on our new host.
- new_auth = get_netrc_auth(url) if self.trust_env else None
- if new_auth is not None:
- prepared_request.prepare_auth(new_auth)
-
- return
-
- def rebuild_proxies(self, prepared_request, proxies):
- """This method re-evaluates the proxy configuration by considering the
- environment variables. If we are redirected to a URL covered by
- NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
- proxy keys for this URL (in case they were stripped by a previous
- redirect).
-
- This method also replaces the Proxy-Authorization header where
- necessary.
-
- :rtype: dict
- """
- headers = prepared_request.headers
- url = prepared_request.url
- scheme = urlparse(url).scheme
- new_proxies = proxies.copy() if proxies is not None else {}
-
- if self.trust_env and not should_bypass_proxies(url):
- environ_proxies = get_environ_proxies(url)
-
- proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
-
- if proxy:
- new_proxies.setdefault(scheme, proxy)
-
- if 'Proxy-Authorization' in headers:
- del headers['Proxy-Authorization']
-
- try:
- username, password = get_auth_from_url(new_proxies[scheme])
- except KeyError:
- username, password = None, None
-
- if username and password:
- headers['Proxy-Authorization'] = _basic_auth_str(username, password)
-
- return new_proxies
-
- def rebuild_method(self, prepared_request, response):
- """When being redirected we may want to change the method of the request
- based on certain specs or browser behavior.
- """
- method = prepared_request.method
-
- # http://tools.ietf.org/html/rfc7231#section-6.4.4
- if response.status_code == codes.see_other and method != 'HEAD':
- method = 'GET'
-
- # Do what the browsers do, despite standards...
- # First, turn 302s into GETs.
- if response.status_code == codes.found and method != 'HEAD':
- method = 'GET'
-
- # Second, if a POST is responded to with a 301, turn it into a GET.
- # This bizarre behaviour is explained in Issue 1704.
- if response.status_code == codes.moved and method == 'POST':
- method = 'GET'
-
- prepared_request.method = method
-
-
-class Session(SessionRedirectMixin):
- """A Requests session.
-
- Provides cookie persistence, connection-pooling, and configuration.
-
- Basic Usage::
-
- >>> import requests
- >>> s = requests.Session()
- >>> s.get('http://httpbin.org/get')
- <Response [200]>
-
- Or as a context manager::
-
- >>> with requests.Session() as s:
- >>> s.get('http://httpbin.org/get')
- <Response [200]>
- """
-
- __attrs__ = [
- 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify',
- 'cert', 'prefetch', 'adapters', 'stream', 'trust_env',
- 'max_redirects',
- ]
-
- def __init__(self):
-
- #: A case-insensitive dictionary of headers to be sent on each
- #: :class:`Request <Request>` sent from this
- #: :class:`Session <Session>`.
- self.headers = default_headers()
-
- #: Default Authentication tuple or object to attach to
- #: :class:`Request <Request>`.
- self.auth = None
-
- #: Dictionary mapping protocol or protocol and host to the URL of the proxy
- #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
- #: be used on each :class:`Request <Request>`.
- self.proxies = {}
-
- #: Event-handling hooks.
- self.hooks = default_hooks()
-
- #: Dictionary of querystring data to attach to each
- #: :class:`Request <Request>`. The dictionary values may be lists for
- #: representing multivalued query parameters.
- self.params = {}
-
- #: Stream response content default.
- self.stream = False
-
- #: SSL Verification default.
- self.verify = True
-
- #: SSL client certificate default.
- self.cert = None
-
- #: Maximum number of redirects allowed. If the request exceeds this
- #: limit, a :class:`TooManyRedirects` exception is raised.
- #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
- #: 30.
- self.max_redirects = DEFAULT_REDIRECT_LIMIT
-
- #: Trust environment settings for proxy configuration, default
- #: authentication and similar.
- self.trust_env = True
-
- #: A CookieJar containing all currently outstanding cookies set on this
- #: session. By default it is a
- #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but
- #: may be any other ``cookielib.CookieJar`` compatible object.
- self.cookies = cookiejar_from_dict({})
-
- # Default connection adapters.
- self.adapters = OrderedDict()
- self.mount('https://', HTTPAdapter())
- self.mount('http://', HTTPAdapter())
-
- # Only store 1000 redirects to prevent using infinite memory
- self.redirect_cache = RecentlyUsedContainer(REDIRECT_CACHE_SIZE)
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- self.close()
-
- def prepare_request(self, request):
- """Constructs a :class:`PreparedRequest <PreparedRequest>` for
- transmission and returns it. The :class:`PreparedRequest` has settings
- merged from the :class:`Request <Request>` instance and those of the
- :class:`Session`.
-
- :param request: :class:`Request` instance to prepare with this
- session's settings.
- :rtype: requests.PreparedRequest
- """
- cookies = request.cookies or {}
-
- # Bootstrap CookieJar.
- if not isinstance(cookies, cookielib.CookieJar):
- cookies = cookiejar_from_dict(cookies)
-
- # Merge with session cookies
- merged_cookies = merge_cookies(
- merge_cookies(RequestsCookieJar(), self.cookies), cookies)
-
- # Set environment's basic authentication if not explicitly set.
- auth = request.auth
- if self.trust_env and not auth and not self.auth:
- auth = get_netrc_auth(request.url)
-
- p = PreparedRequest()
- p.prepare(
- method=request.method.upper(),
- url=request.url,
- files=request.files,
- data=request.data,
- json=request.json,
- headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict),
- params=merge_setting(request.params, self.params),
- auth=merge_setting(auth, self.auth),
- cookies=merged_cookies,
- hooks=merge_hooks(request.hooks, self.hooks),
- )
- return p
-
- def request(self, method, url,
- params=None,
- data=None,
- headers=None,
- cookies=None,
- files=None,
- auth=None,
- timeout=None,
- allow_redirects=True,
- proxies=None,
- hooks=None,
- stream=None,
- verify=None,
- cert=None,
- json=None):
- """Constructs a :class:`Request <Request>`, prepares it and sends it.
- Returns :class:`Response <Response>` object.
-
- :param method: method for the new :class:`Request` object.
- :param url: URL for the new :class:`Request` object.
- :param params: (optional) Dictionary or bytes to be sent in the query
- string for the :class:`Request`.
- :param data: (optional) Dictionary, bytes, or file-like object to send
- in the body of the :class:`Request`.
- :param json: (optional) json to send in the body of the
- :class:`Request`.
- :param headers: (optional) Dictionary of HTTP Headers to send with the
- :class:`Request`.
- :param cookies: (optional) Dict or CookieJar object to send with the
- :class:`Request`.
- :param files: (optional) Dictionary of ``'filename': file-like-objects``
- for multipart encoding upload.
- :param auth: (optional) Auth tuple or callable to enable
- Basic/Digest/Custom HTTP Auth.
- :param timeout: (optional) How long to wait for the server to send
- data before giving up, as a float, or a :ref:`(connect timeout,
- read timeout) <timeouts>` tuple.
- :type timeout: float or tuple
- :param allow_redirects: (optional) Set to True by default.
- :type allow_redirects: bool
- :param proxies: (optional) Dictionary mapping protocol or protocol and
- hostname to the URL of the proxy.
- :param stream: (optional) whether to immediately download the response
- content. Defaults to ``False``.
- :param verify: (optional) whether the SSL cert will be verified.
- A CA_BUNDLE path can also be provided. Defaults to ``True``.
- :param cert: (optional) if String, path to ssl client cert file (.pem).
- If Tuple, ('cert', 'key') pair.
- :rtype: requests.Response
- """
- # Create the Request.
- req = Request(
- method = method.upper(),
- url = url,
- headers = headers,
- files = files,
- data = data or {},
- json = json,
- params = params or {},
- auth = auth,
- cookies = cookies,
- hooks = hooks,
- )
- prep = self.prepare_request(req)
-
- proxies = proxies or {}
-
- settings = self.merge_environment_settings(
- prep.url, proxies, stream, verify, cert
- )
-
- # Send the request.
- send_kwargs = {
- 'timeout': timeout,
- 'allow_redirects': allow_redirects,
- }
- send_kwargs.update(settings)
- resp = self.send(prep, **send_kwargs)
-
- return resp
-
- def get(self, url, **kwargs):
- """Sends a GET request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- kwargs.setdefault('allow_redirects', True)
- return self.request('GET', url, **kwargs)
-
- def options(self, url, **kwargs):
- """Sends a OPTIONS request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- kwargs.setdefault('allow_redirects', True)
- return self.request('OPTIONS', url, **kwargs)
-
- def head(self, url, **kwargs):
- """Sends a HEAD request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- kwargs.setdefault('allow_redirects', False)
- return self.request('HEAD', url, **kwargs)
-
- def post(self, url, data=None, json=None, **kwargs):
- """Sends a POST request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param json: (optional) json to send in the body of the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- return self.request('POST', url, data=data, json=json, **kwargs)
-
- def put(self, url, data=None, **kwargs):
- """Sends a PUT request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- return self.request('PUT', url, data=data, **kwargs)
-
- def patch(self, url, data=None, **kwargs):
- """Sends a PATCH request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- return self.request('PATCH', url, data=data, **kwargs)
-
- def delete(self, url, **kwargs):
- """Sends a DELETE request. Returns :class:`Response` object.
-
- :param url: URL for the new :class:`Request` object.
- :param \*\*kwargs: Optional arguments that ``request`` takes.
- :rtype: requests.Response
- """
-
- return self.request('DELETE', url, **kwargs)
-
- def send(self, request, **kwargs):
- """
- Send a given PreparedRequest.
-
- :rtype: requests.Response
- """
- # Set defaults that the hooks can utilize to ensure they always have
- # the correct parameters to reproduce the previous request.
- kwargs.setdefault('stream', self.stream)
- kwargs.setdefault('verify', self.verify)
- kwargs.setdefault('cert', self.cert)
- kwargs.setdefault('proxies', self.proxies)
-
- # It's possible that users might accidentally send a Request object.
- # Guard against that specific failure case.
- if isinstance(request, Request):
- raise ValueError('You can only send PreparedRequests.')
-
- # Set up variables needed for resolve_redirects and dispatching of hooks
- allow_redirects = kwargs.pop('allow_redirects', True)
- stream = kwargs.get('stream')
- hooks = request.hooks
-
- # Resolve URL in redirect cache, if available.
- if allow_redirects:
- checked_urls = set()
- while request.url in self.redirect_cache:
- checked_urls.add(request.url)
- new_url = self.redirect_cache.get(request.url)
- if new_url in checked_urls:
- break
- request.url = new_url
-
- # Get the appropriate adapter to use
- adapter = self.get_adapter(url=request.url)
-
- # Start time (approximately) of the request
- start = datetime.utcnow()
-
- # Send the request
- r = adapter.send(request, **kwargs)
-
- # Total elapsed time of the request (approximately)
- r.elapsed = datetime.utcnow() - start
-
- # Response manipulation hooks
- r = dispatch_hook('response', hooks, r, **kwargs)
-
- # Persist cookies
- if r.history:
-
- # If the hooks create history then we want those cookies too
- for resp in r.history:
- extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
-
- extract_cookies_to_jar(self.cookies, request, r.raw)
-
- # Redirect resolving generator.
- gen = self.resolve_redirects(r, request, **kwargs)
-
- # Resolve redirects if allowed.
- history = [resp for resp in gen] if allow_redirects else []
-
- # Shuffle things around if there's history.
- if history:
- # Insert the first (original) request at the start
- history.insert(0, r)
- # Get the last request made
- r = history.pop()
- r.history = history
-
- if not stream:
- r.content
-
- return r
-
- def merge_environment_settings(self, url, proxies, stream, verify, cert):
- """
- Check the environment and merge it with some settings.
-
- :rtype: dict
- """
- # Gather clues from the surrounding environment.
- if self.trust_env:
- # Set environment's proxies.
- env_proxies = get_environ_proxies(url) or {}
- for (k, v) in env_proxies.items():
- proxies.setdefault(k, v)
-
- # Look for requests environment configuration and be compatible
- # with cURL.
- if verify is True or verify is None:
- verify = (os.environ.get('REQUESTS_CA_BUNDLE') or
- os.environ.get('CURL_CA_BUNDLE'))
-
- # Merge all the kwargs.
- proxies = merge_setting(proxies, self.proxies)
- stream = merge_setting(stream, self.stream)
- verify = merge_setting(verify, self.verify)
- cert = merge_setting(cert, self.cert)
-
- return {'verify': verify, 'proxies': proxies, 'stream': stream,
- 'cert': cert}
-
- def get_adapter(self, url):
- """
- Returns the appropriate connection adapter for the given URL.
-
- :rtype: requests.adapters.BaseAdapter
- """
- for (prefix, adapter) in self.adapters.items():
-
- if url.lower().startswith(prefix):
- return adapter
-
- # Nothing matches :-/
- raise InvalidSchema("No connection adapters were found for '%s'" % url)
-
- def close(self):
- """Closes all adapters and as such the session"""
- for v in self.adapters.values():
- v.close()
-
- def mount(self, prefix, adapter):
- """Registers a connection adapter to a prefix.
-
- Adapters are sorted in descending order by key length.
- """
- self.adapters[prefix] = adapter
- keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
-
- for key in keys_to_move:
- self.adapters[key] = self.adapters.pop(key)
-
- def __getstate__(self):
- state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__)
- state['redirect_cache'] = dict(self.redirect_cache)
- return state
-
- def __setstate__(self, state):
- redirect_cache = state.pop('redirect_cache', {})
- for attr, value in state.items():
- setattr(self, attr, value)
-
- self.redirect_cache = RecentlyUsedContainer(REDIRECT_CACHE_SIZE)
- for redirect, to in redirect_cache.items():
- self.redirect_cache[redirect] = to
-
-
-def session():
- """
- Returns a :class:`Session` for context-management.
-
- :rtype: Session
- """
-
- return Session()
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/status_codes.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/status_codes.py
deleted file mode 100644
index db2986bb..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/status_codes.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from .structures import LookupDict
-
-_codes = {
-
- # Informational.
- 100: ('continue',),
- 101: ('switching_protocols',),
- 102: ('processing',),
- 103: ('checkpoint',),
- 122: ('uri_too_long', 'request_uri_too_long'),
- 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),
- 201: ('created',),
- 202: ('accepted',),
- 203: ('non_authoritative_info', 'non_authoritative_information'),
- 204: ('no_content',),
- 205: ('reset_content', 'reset'),
- 206: ('partial_content', 'partial'),
- 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
- 208: ('already_reported',),
- 226: ('im_used',),
-
- # Redirection.
- 300: ('multiple_choices',),
- 301: ('moved_permanently', 'moved', '\\o-'),
- 302: ('found',),
- 303: ('see_other', 'other'),
- 304: ('not_modified',),
- 305: ('use_proxy',),
- 306: ('switch_proxy',),
- 307: ('temporary_redirect', 'temporary_moved', 'temporary'),
- 308: ('permanent_redirect',
- 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0
-
- # Client Error.
- 400: ('bad_request', 'bad'),
- 401: ('unauthorized',),
- 402: ('payment_required', 'payment'),
- 403: ('forbidden',),
- 404: ('not_found', '-o-'),
- 405: ('method_not_allowed', 'not_allowed'),
- 406: ('not_acceptable',),
- 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
- 408: ('request_timeout', 'timeout'),
- 409: ('conflict',),
- 410: ('gone',),
- 411: ('length_required',),
- 412: ('precondition_failed', 'precondition'),
- 413: ('request_entity_too_large',),
- 414: ('request_uri_too_large',),
- 415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
- 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
- 417: ('expectation_failed',),
- 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
- 421: ('misdirected_request',),
- 422: ('unprocessable_entity', 'unprocessable'),
- 423: ('locked',),
- 424: ('failed_dependency', 'dependency'),
- 425: ('unordered_collection', 'unordered'),
- 426: ('upgrade_required', 'upgrade'),
- 428: ('precondition_required', 'precondition'),
- 429: ('too_many_requests', 'too_many'),
- 431: ('header_fields_too_large', 'fields_too_large'),
- 444: ('no_response', 'none'),
- 449: ('retry_with', 'retry'),
- 450: ('blocked_by_windows_parental_controls', 'parental_controls'),
- 451: ('unavailable_for_legal_reasons', 'legal_reasons'),
- 499: ('client_closed_request',),
-
- # Server Error.
- 500: ('internal_server_error', 'server_error', '/o\\', '✗'),
- 501: ('not_implemented',),
- 502: ('bad_gateway',),
- 503: ('service_unavailable', 'unavailable'),
- 504: ('gateway_timeout',),
- 505: ('http_version_not_supported', 'http_version'),
- 506: ('variant_also_negotiates',),
- 507: ('insufficient_storage',),
- 509: ('bandwidth_limit_exceeded', 'bandwidth'),
- 510: ('not_extended',),
- 511: ('network_authentication_required', 'network_auth', 'network_authentication'),
-}
-
-codes = LookupDict(name='status_codes')
-
-for code, titles in _codes.items():
- for title in titles:
- setattr(codes, title, code)
- if not title.startswith('\\'):
- setattr(codes, title.upper(), code)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/structures.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/structures.py
deleted file mode 100644
index 05d2b3f5..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/structures.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.structures
-~~~~~~~~~~~~~~~~~~~
-
-Data structures that power Requests.
-"""
-
-import collections
-
-from .compat import OrderedDict
-
-
-class CaseInsensitiveDict(collections.MutableMapping):
- """A case-insensitive ``dict``-like object.
-
- Implements all methods and operations of
- ``collections.MutableMapping`` as well as dict's ``copy``. Also
- provides ``lower_items``.
-
- All keys are expected to be strings. The structure remembers the
- case of the last key to be set, and ``iter(instance)``,
- ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
- will contain case-sensitive keys. However, querying and contains
- testing is case insensitive::
-
- cid = CaseInsensitiveDict()
- cid['Accept'] = 'application/json'
- cid['aCCEPT'] == 'application/json' # True
- list(cid) == ['Accept'] # True
-
- For example, ``headers['content-encoding']`` will return the
- value of a ``'Content-Encoding'`` response header, regardless
- of how the header name was originally stored.
-
- If the constructor, ``.update``, or equality comparison
- operations are given keys that have equal ``.lower()``s, the
- behavior is undefined.
- """
-
- def __init__(self, data=None, **kwargs):
- self._store = OrderedDict()
- if data is None:
- data = {}
- self.update(data, **kwargs)
-
- def __setitem__(self, key, value):
- # Use the lowercased key for lookups, but store the actual
- # key alongside the value.
- self._store[key.lower()] = (key, value)
-
- def __getitem__(self, key):
- return self._store[key.lower()][1]
-
- def __delitem__(self, key):
- del self._store[key.lower()]
-
- def __iter__(self):
- return (casedkey for casedkey, mappedvalue in self._store.values())
-
- def __len__(self):
- return len(self._store)
-
- def lower_items(self):
- """Like iteritems(), but with all lowercase keys."""
- return (
- (lowerkey, keyval[1])
- for (lowerkey, keyval)
- in self._store.items()
- )
-
- def __eq__(self, other):
- if isinstance(other, collections.Mapping):
- other = CaseInsensitiveDict(other)
- else:
- return NotImplemented
- # Compare insensitively
- return dict(self.lower_items()) == dict(other.lower_items())
-
- # Copy is required
- def copy(self):
- return CaseInsensitiveDict(self._store.values())
-
- def __repr__(self):
- return str(dict(self.items()))
-
-
-class LookupDict(dict):
- """Dictionary lookup object."""
-
- def __init__(self, name=None):
- self.name = name
- super(LookupDict, self).__init__()
-
- def __repr__(self):
- return '<lookup \'%s\'>' % (self.name)
-
- def __getitem__(self, key):
- # We allow fall-through here, so values default to None
-
- return self.__dict__.get(key, None)
-
- def get(self, key, default=None):
- return self.__dict__.get(key, default)
diff --git a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/utils.py b/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/utils.py
deleted file mode 100644
index 47325090..00000000
--- a/lib/python2.7/site-packages/requests-2.13.0-py2.7.egg/requests/utils.py
+++ /dev/null
@@ -1,827 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-requests.utils
-~~~~~~~~~~~~~~
-
-This module provides utility functions that are used within Requests
-that are also useful for external consumption.
-"""
-
-import cgi
-import codecs
-import collections
-import io
-import os
-import re
-import socket
-import struct
-import warnings
-
-from . import __version__
-from . import certs
-# to_native_string is unused here, but imported here for backwards compatibility
-from ._internal_utils import to_native_string
-from .compat import parse_http_list as _parse_list_header
-from .compat import (
- quote, urlparse, bytes, str, OrderedDict, unquote, getproxies,
- proxy_bypass, urlunparse, basestring, integer_types)
-from .cookies import RequestsCookieJar, cookiejar_from_dict
-from .structures import CaseInsensitiveDict
-from .exceptions import (
- InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError)
-
-_hush_pyflakes = (RequestsCookieJar,)
-
-NETRC_FILES = ('.netrc', '_netrc')
-
-DEFAULT_CA_BUNDLE_PATH = certs.where()
-
-
-def dict_to_sequence(d):
- """Returns an internal sequence dictionary update."""
-
- if hasattr(d, 'items'):
- d = d.items()
-
- return d
-
-
-def super_len(o):
- total_length = None
- current_position = 0
-
- if hasattr(o, '__len__'):
- total_length = len(o)
-
- elif hasattr(o, 'len'):
- total_length = o.len
-
- elif hasattr(o, 'fileno'):
- try:
- fileno = o.fileno()
- except io.UnsupportedOperation:
- pass
- else:
- total_length = os.fstat(fileno).st_size
-
- # Having used fstat to determine the file length, we need to
- # confirm that this file was opened up in binary mode.
- if 'b' not in o.mode:
- warnings.warn((
- "Requests has determined the content-length for this "
- "request using the binary size of the file: however, the "
- "file has been opened in text mode (i.e. without the 'b' "
- "flag in the mode). This may lead to an incorrect "
- "content-length. In Requests 3.0, support will be removed "
- "for files in text mode."),
- FileModeWarning
- )
-
- if hasattr(o, 'tell'):
- try:
- current_position = o.tell()
- except (OSError, IOError):
- # This can happen in some weird situations, such as when the file
- # is actually a special file descriptor like stdin. In this
- # instance, we don't know what the length is, so set it to zero and
- # let requests chunk it instead.
- if total_length is not None:
- current_position = total_length
- else:
- if hasattr(o, 'seek') and total_length is None:
- # StringIO and BytesIO have seek but no useable fileno
-
- # seek to end of file
- o.seek(0, 2)
- total_length = o.tell()
-
- # seek back to current position to support
- # partially read file-like objects
- o.seek(current_position or 0)
-
- if total_length is None:
- total_length = 0
-
- return max(0, total_length - current_position)
-
-
-def get_netrc_auth(url, raise_errors=False):
- """Returns the Requests tuple auth for a given url from netrc."""
-
- try:
- from netrc import netrc, NetrcParseError
-
- netrc_path = None
-
- for f in NETRC_FILES:
- try:
- loc = os.path.expanduser('~/{0}'.format(f))
- except KeyError:
- # os.path.expanduser can fail when $HOME is undefined and
- # getpwuid fails. See http://bugs.python.org/issue20164 &
- # https://github.com/kennethreitz/requests/issues/1846
- return
-
- if os.path.exists(loc):
- netrc_path = loc
- break
-
- # Abort early if there isn't one.
- if netrc_path is None:
- return
-
- ri = urlparse(url)
-
- # Strip port numbers from netloc. This weird `if...encode`` dance is
- # used for Python 3.2, which doesn't support unicode literals.
- splitstr = b':'
- if isinstance(url, str):
- splitstr = splitstr.decode('ascii')
- host = ri.netloc.split(splitstr)[0]
-
- try:
- _netrc = netrc(netrc_path).authenticators(host)
- if _netrc:
- # Return with login / password
- login_i = (0 if _netrc[0] else 1)
- return (_netrc[login_i], _netrc[2])
- except (NetrcParseError, IOError):
- # If there was a parsing error or a permissions issue reading the file,
- # we'll just skip netrc auth unless explicitly asked to raise errors.
- if raise_errors:
- raise
-
- # AppEngine hackiness.
- except (ImportError, AttributeError):
- pass
-
-
-def guess_filename(obj):
- """Tries to guess the filename of the given object."""
- name = getattr(obj, 'name', None)
- if (name and isinstance(name, basestring) and name[0] != '<' and
- name[-1] != '>'):
- return os.path.basename(name)
-
-
-def from_key_val_list(value):
- """Take an object and test to see if it can be represented as a
- dictionary. Unless it can not be represented as such, return an
- OrderedDict, e.g.,
-
- ::
-
- >>> from_key_val_list([('key', 'val')])
- OrderedDict([('key', 'val')])
- >>> from_key_val_list('string')
- ValueError: need more than 1 value to unpack
- >>> from_key_val_list({'key': 'val'})
- OrderedDict([('key', 'val')])
-
- :rtype: OrderedDict
- """
- if value is None:
- return None
-
- if isinstance(value, (str, bytes, bool, int)):
- raise ValueError('cannot encode objects that are not 2-tuples')
-
- return OrderedDict(value)
-
-
-def to_key_val_list(value):
- """Take an object and test to see if it can be represented as a
- dictionary. If it can be, return a list of tuples, e.g.,
-
- ::
-
- >>> to_key_val_list([('key', 'val')])
- [('key', 'val')]
- >>> to_key_val_list({'key': 'val'})
- [('key', 'val')]
- >>> to_key_val_list('string')
- ValueError: cannot encode objects that are not 2-tuples.
-
- :rtype: list
- """
- if value is None:
- return None
-
- if isinstance(value, (str, bytes, bool, int)):
- raise ValueError('cannot encode objects that are not 2-tuples')
-
- if isinstance(value, collections.Mapping):
- value = value.items()
-
- return list(value)
-
-
-# From mitsuhiko/werkzeug (used with permission).
-def parse_list_header(value):
- """Parse lists as described by RFC 2068 Section 2.
-
- In particular, parse comma-separated lists where the elements of
- the list may include quoted-strings. A quoted-string could
- contain a comma. A non-quoted string could have quotes in the
- middle. Quotes are removed automatically after parsing.
-
- It basically works like :func:`parse_set_header` just that items
- may appear multiple times and case sensitivity is preserved.
-
- The return value is a standard :class:`list`:
-
- >>> parse_list_header('token, "quoted value"')
- ['token', 'quoted value']
-
- To create a header from the :class:`list` again, use the
- :func:`dump_header` function.
-
- :param value: a string with a list header.
- :return: :class:`list`
- :rtype: list
- """
- result = []
- for item in _parse_list_header(value):
- if item[:1] == item[-1:] == '"':
- item = unquote_header_value(item[1:-1])
- result.append(item)
- return result
-
-
-# From mitsuhiko/werkzeug (used with permission).
-def parse_dict_header(value):
- """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
- convert them into a python dict:
-
- >>> d = parse_dict_header('foo="is a fish", bar="as well"')
- >>> type(d) is dict
- True
- >>> sorted(d.items())
- [('bar', 'as well'), ('foo', 'is a fish')]
-
- If there is no value for a key it will be `None`:
-
- >>> parse_dict_header('key_without_value')
- {'key_without_value': None}
-
- To create a header from the :class:`dict` again, use the
- :func:`dump_header` function.
-
- :param value: a string with a dict header.
- :return: :class:`dict`
- :rtype: dict
- """
- result = {}
- for item in _parse_list_header(value):
- if '=' not in item:
- result[item] = None
- continue
- name, value = item.split('=', 1)
- if value[:1] == value[-1:] == '"':
- value = unquote_header_value(value[1:-1])
- result[name] = value
- return result
-
-
-# From mitsuhiko/werkzeug (used with permission).
-def unquote_header_value(value, is_filename=False):
- r"""Unquotes a header value. (Reversal of :func:`quote_header_value`).
- This does not use the real unquoting but what browsers are actually
- using for quoting.
-
- :param value: the header value to unquote.
- :rtype: str
- """
- if value and value[0] == value[-1] == '"':
- # this is not the real unquoting, but fixing this so that the
- # RFC is met will result in bugs with internet explorer and
- # probably some other browsers as well. IE for example is
- # uploading files with "C:\foo\bar.txt" as filename
- value = value[1:-1]
-
- # if this is a filename and the starting characters look like
- # a UNC path, then just return the value without quotes. Using the
- # replace sequence below on a UNC path has the effect of turning
- # the leading double slash into a single slash and then
- # _fix_ie_filename() doesn't work correctly. See #458.
- if not is_filename or value[:2] != '\\\\':
- return value.replace('\\\\', '\\').replace('\\"', '"')
- return value
-
-
-def dict_from_cookiejar(cj):
- """Returns a key/value dictionary from a CookieJar.
-
- :param cj: CookieJar object to extract cookies from.
- :rtype: dict
- """
-
- cookie_dict = {}
-
- for cookie in cj:
- cookie_dict[cookie.name] = cookie.value
-
- return cookie_dict
-
-
-def add_dict_to_cookiejar(cj, cookie_dict):
- """Returns a CookieJar from a key/value dictionary.
-
- :param cj: CookieJar to insert cookies into.
- :param cookie_dict: Dict of key/values to insert into CookieJar.
- :rtype: CookieJar
- """
-
- return cookiejar_from_dict(cookie_dict, cj)
-
-
-def get_encodings_from_content(content):
- """Returns encodings from given content string.
-
- :param content: bytestring to extract encodings from.
- """
- warnings.warn((
- 'In requests 3.0, get_encodings_from_content will be removed. For '
- 'more information, please see the discussion on issue #2266. (This'
- ' warning should only appear once.)'),
- DeprecationWarning)
-
- charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I)
- pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I)
- xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')
-
- return (charset_re.findall(content) +
- pragma_re.findall(content) +
- xml_re.findall(content))
-
-
-def get_encoding_from_headers(headers):
- """Returns encodings from given HTTP Header Dict.
-
- :param headers: dictionary to extract encoding from.
- :rtype: str
- """
-
- content_type = headers.get('content-type')
-
- if not content_type:
- return None
-
- content_type, params = cgi.parse_header(content_type)
-
- if 'charset' in params:
- return params['charset'].strip("'\"")
-
- if 'text' in content_type:
- return 'ISO-8859-1'
-
-
-def stream_decode_response_unicode(iterator, r):
- """Stream decodes a iterator."""
-
- if r.encoding is None:
- for item in iterator:
- yield item
- return
-
- decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace')
- for chunk in iterator:
- rv = decoder.decode(chunk)
- if rv:
- yield rv
- rv = decoder.decode(b'', final=True)
- if rv:
- yield rv
-
-
-def iter_slices(string, slice_length):
- """Iterate over slices of a string."""
- pos = 0
- if slice_length is None or slice_length <= 0:
- slice_length = len(string)
- while pos < len(string):
- yield string[pos:pos + slice_length]
- pos += slice_length
-
-
-def get_unicode_from_response(r):
- """Returns the requested content back in unicode.
-
- :param r: Response object to get unicode content from.
-
- Tried:
-
- 1. charset from content-type
- 2. fall back and replace all unicode characters
-
- :rtype: str
- """
- warnings.warn((
- 'In requests 3.0, get_unicode_from_response will be removed. For '
- 'more information, please see the discussion on issue #2266. (This'
- ' warning should only appear once.)'),
- DeprecationWarning)
-
- tried_encodings = []
-
- # Try charset from content-type
- encoding = get_encoding_from_headers(r.headers)
-
- if encoding:
- try:
- return str(r.content, encoding)
- except UnicodeError:
- tried_encodings.append(encoding)
-
- # Fall back:
- try:
- return str(r.content, encoding, errors='replace')
- except TypeError:
- return r.content
-
-
-# The unreserved URI characters (RFC 3986)
-UNRESERVED_SET = frozenset(
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- + "0123456789-._~")
-
-
-def unquote_unreserved(uri):
- """Un-escape any percent-escape sequences in a URI that are unreserved
- characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
-
- :rtype: str
- """
- parts = uri.split('%')
- for i in range(1, len(parts)):
- h = parts[i][0:2]
- if len(h) == 2 and h.isalnum():
- try:
- c = chr(int(h, 16))
- except ValueError:
- raise InvalidURL("Invalid percent-escape sequence: '%s'" % h)
-
- if c in UNRESERVED_SET:
- parts[i] = c + parts[i][2:]
- else:
- parts[i] = '%' + parts[i]
- else:
- parts[i] = '%' + parts[i]
- return ''.join(parts)
-
-
-def requote_uri(uri):
- """Re-quote the given URI.
-
- This function passes the given URI through an unquote/quote cycle to
- ensure that it is fully and consistently quoted.
-
- :rtype: str
- """
- safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
- safe_without_percent = "!#$&'()*+,/:;=?@[]~"
- try:
- # Unquote only the unreserved characters
- # Then quote only illegal characters (do not quote reserved,
- # unreserved, or '%')
- return quote(unquote_unreserved(uri), safe=safe_with_percent)
- except InvalidURL:
- # We couldn't unquote the given URI, so let's try quoting it, but
- # there may be unquoted '%'s in the URI. We need to make sure they're
- # properly quoted so they do not cause issues elsewhere.
- return quote(uri, safe=safe_without_percent)
-
-
-def address_in_network(ip, net):
- """This function allows you to check if on IP belongs to a network subnet
-
- Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
- returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
-
- :rtype: bool
- """
- ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0]
- netaddr, bits = net.split('/')
- netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0]
- network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask
- return (ipaddr & netmask) == (network & netmask)
-
-
-def dotted_netmask(mask):
- """Converts mask from /xx format to xxx.xxx.xxx.xxx
-
- Example: if mask is 24 function returns 255.255.255.0
-
- :rtype: str
- """
- bits = 0xffffffff ^ (1 << 32 - mask) - 1
- return socket.inet_ntoa(struct.pack('>I', bits))
-
-
-def is_ipv4_address(string_ip):
- """
- :rtype: bool
- """
- try:
- socket.inet_aton(string_ip)
- except socket.error:
- return False
- return True
-
-
-def is_valid_cidr(string_network):
- """
- Very simple check of the cidr format in no_proxy variable.
-
- :rtype: bool
- """
- if string_network.count('/') == 1:
- try:
- mask = int(string_network.split('/')[1])
- except ValueError:
- return False
-
- if mask < 1 or mask > 32:
- return False
-
- try:
- socket.inet_aton(string_network.split('/')[0])
- except socket.error:
- return False
- else:
- return False
- return True
-
-
-def should_bypass_proxies(url):
- """
- Returns whether we should bypass proxies or not.
-
- :rtype: bool
- """
- get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper())
-
- # First check whether no_proxy is defined. If it is, check that the URL
- # we're getting isn't in the no_proxy list.
- no_proxy = get_proxy('no_proxy')
- netloc = urlparse(url).netloc
-
- if no_proxy:
- # We need to check whether we match here. We need to see if we match
- # the end of the netloc, both with and without the port.
- no_proxy = (
- host for host in no_proxy.replace(' ', '').split(',') if host
- )
-
- ip = netloc.split(':')[0]
- if is_ipv4_address(ip):
- for proxy_ip in no_proxy:
- if is_valid_cidr(proxy_ip):
- if address_in_network(ip, proxy_ip):
- return True
- elif ip == proxy_ip:
- # If no_proxy ip was defined in plain IP notation instead of cidr notation &
- # matches the IP of the index
- return True
- else:
- for host in no_proxy:
- if netloc.endswith(host) or netloc.split(':')[0].endswith(host):
- # The URL does match something in no_proxy, so we don't want
- # to apply the proxies on this URL.
- return True
-
- # If the system proxy settings indicate that this URL should be bypassed,
- # don't proxy.
- # The proxy_bypass function is incredibly buggy on OS X in early versions
- # of Python 2.6, so allow this call to fail. Only catch the specific
- # exceptions we've seen, though: this call failing in other ways can reveal
- # legitimate problems.
- try:
- bypass = proxy_bypass(netloc)
- except (TypeError, socket.gaierror):
- bypass = False
-
- if bypass:
- return True
-
- return False
-
-
-def get_environ_proxies(url):
- """
- Return a dict of environment proxies.
-
- :rtype: dict
- """
- if should_bypass_proxies(url):
- return {}
- else:
- return getproxies()
-
-
-def select_proxy(url, proxies):
- """Select a proxy for the url, if applicable.
-
- :param url: The url being for the request
- :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
- """
- proxies = proxies or {}
- urlparts = urlparse(url)
- if urlparts.hostname is None:
- return proxies.get(urlparts.scheme, proxies.get('all'))
-
- proxy_keys = [
- urlparts.scheme + '://' + urlparts.hostname,
- urlparts.scheme,
- 'all://' + urlparts.hostname,
- 'all',
- ]
- proxy = None
- for proxy_key in proxy_keys:
- if proxy_key in proxies:
- proxy = proxies[proxy_key]
- break
-
- return proxy
-
-
-def default_user_agent(name="python-requests"):
- """
- Return a string representing the default user agent.
-
- :rtype: str
- """
- return '%s/%s' % (name, __version__)
-
-
-def default_headers():
- """
- :rtype: requests.structures.CaseInsensitiveDict
- """
- return CaseInsensitiveDict({
- 'User-Agent': default_user_agent(),
- 'Accept-Encoding': ', '.join(('gzip', 'deflate')),
- 'Accept': '*/*',
- 'Connection': 'keep-alive',
- })
-
-
-def parse_header_links(value):
- """Return a dict of parsed link headers proxies.
-
- i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"
-
- :rtype: list
- """
-
- links = []
-
- replace_chars = ' \'"'
-
- for val in re.split(', *<', value):
- try:
- url, params = val.split(';', 1)
- except ValueError:
- url, params = val, ''
-
- link = {'url': url.strip('<> \'"')}
-
- for param in params.split(';'):
- try:
- key, value = param.split('=')
- except ValueError:
- break
-
- link[key.strip(replace_chars)] = value.strip(replace_chars)
-
- links.append(link)
-
- return links
-
-
-# Null bytes; no need to recreate these on each call to guess_json_utf
-_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3
-_null2 = _null * 2
-_null3 = _null * 3
-
-
-def guess_json_utf(data):
- """
- :rtype: str
- """
- # JSON always starts with two ASCII characters, so detection is as
- # easy as counting the nulls and from their location and count
- # determine the encoding. Also detect a BOM, if present.
- sample = data[:4]
- if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
- return 'utf-32' # BOM included
- if sample[:3] == codecs.BOM_UTF8:
- return 'utf-8-sig' # BOM included, MS style (discouraged)
- if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
- return 'utf-16' # BOM included
- nullcount = sample.count(_null)
- if nullcount == 0:
- return 'utf-8'
- if nullcount == 2:
- if sample[::2] == _null2: # 1st and 3rd are null
- return 'utf-16-be'
- if sample[1::2] == _null2: # 2nd and 4th are null
- return 'utf-16-le'
- # Did not detect 2 valid UTF-16 ascii-range characters
- if nullcount == 3:
- if sample[:3] == _null3:
- return 'utf-32-be'
- if sample[1:] == _null3:
- return 'utf-32-le'
- # Did not detect a valid UTF-32 ascii-range character
- return None
-
-
-def prepend_scheme_if_needed(url, new_scheme):
- """Given a URL that may or may not have a scheme, prepend the given scheme.
- Does not replace a present scheme with the one provided as an argument.
-
- :rtype: str
- """
- scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme)
-
- # urlparse is a finicky beast, and sometimes decides that there isn't a
- # netloc present. Assume that it's being over-cautious, and switch netloc
- # and path if urlparse decided there was no netloc.
- if not netloc:
- netloc, path = path, netloc
-
- return urlunparse((scheme, netloc, path, params, query, fragment))
-
-
-def get_auth_from_url(url):
- """Given a url with authentication components, extract them into a tuple of
- username,password.
-
- :rtype: (str,str)
- """
- parsed = urlparse(url)
-
- try:
- auth = (unquote(parsed.username), unquote(parsed.password))
- except (AttributeError, TypeError):
- auth = ('', '')
-
- return auth
-
-
-# Moved outside of function to avoid recompile every call
-_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$')
-_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$')
-
-def check_header_validity(header):
- """Verifies that header value is a string which doesn't contain
- leading whitespace or return characters. This prevents unintended
- header injection.
-
- :param header: tuple, in the format (name, value).
- """
- name, value = header
-
- if isinstance(value, bytes):
- pat = _CLEAN_HEADER_REGEX_BYTE
- else:
- pat = _CLEAN_HEADER_REGEX_STR
- try:
- if not pat.match(value):
- raise InvalidHeader("Invalid return character or leading space in header: %s" % name)
- except TypeError:
- raise InvalidHeader("Header value %s must be of type str or bytes, "
- "not %s" % (value, type(value)))
-
-
-def urldefragauth(url):
- """
- Given a url remove the fragment and the authentication part.
-
- :rtype: str
- """
- scheme, netloc, path, params, query, fragment = urlparse(url)
-
- # see func:`prepend_scheme_if_needed`
- if not netloc:
- netloc, path = path, netloc
-
- netloc = netloc.rsplit('@', 1)[-1]
-
- return urlunparse((scheme, netloc, path, params, query, ''))
-
-def rewind_body(prepared_request):
- """Move file pointer back to its recorded starting position
- so it can be read again on redirect.
- """
- body_seek = getattr(prepared_request.body, 'seek', None)
- if body_seek is not None and isinstance(prepared_request._body_position, integer_types):
- try:
- body_seek(prepared_request._body_position)
- except (IOError, OSError):
- raise UnrewindableBodyError("An error occured when rewinding request "
- "body for redirect.")
- else:
- raise UnrewindableBodyError("Unable to rewind request body for redirect.")
diff --git a/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg b/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg
deleted file mode 100644
index 8a51424a..00000000
--- a/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/setuptools.pth b/lib/python2.7/site-packages/setuptools.pth
deleted file mode 100644
index d36d92cb..00000000
--- a/lib/python2.7/site-packages/setuptools.pth
+++ /dev/null
@@ -1 +0,0 @@
-./setuptools-0.6c11-py2.7.egg
diff --git a/lib/python2.7/site-packages/site.py b/lib/python2.7/site-packages/site.py
deleted file mode 100644
index 80e084b2..00000000
--- a/lib/python2.7/site-packages/site.py
+++ /dev/null
@@ -1,82 +0,0 @@
-def __boot():
- import sys, imp, os, os.path
- PYTHONPATH = os.environ.get('PYTHONPATH')
- if PYTHONPATH is None or (sys.platform=='win32' and not PYTHONPATH):
- PYTHONPATH = []
- else:
- PYTHONPATH = PYTHONPATH.split(os.pathsep)
-
- pic = getattr(sys,'path_importer_cache',{})
- stdpath = sys.path[len(PYTHONPATH):]
- mydir = os.path.dirname(__file__)
- #print "searching",stdpath,sys.path
-
- for item in stdpath:
- if item==mydir or not item:
- continue # skip if current dir. on Windows, or my own directory
- importer = pic.get(item)
- if importer is not None:
- loader = importer.find_module('site')
- if loader is not None:
- # This should actually reload the current module
- loader.load_module('site')
- break
- else:
- try:
- stream, path, descr = imp.find_module('site',[item])
- except ImportError:
- continue
- if stream is None:
- continue
- try:
- # This should actually reload the current module
- imp.load_module('site',stream,path,descr)
- finally:
- stream.close()
- break
- else:
- raise ImportError("Couldn't find the real 'site' module")
-
- #print "loaded", __file__
-
- known_paths = dict([(makepath(item)[1],1) for item in sys.path]) # 2.2 comp
-
- oldpos = getattr(sys,'__egginsert',0) # save old insertion position
- sys.__egginsert = 0 # and reset the current one
-
- for item in PYTHONPATH:
- addsitedir(item)
-
- sys.__egginsert += oldpos # restore effective old position
-
- d,nd = makepath(stdpath[0])
- insert_at = None
- new_path = []
-
- for item in sys.path:
- p,np = makepath(item)
-
- if np==nd and insert_at is None:
- # We've hit the first 'system' path entry, so added entries go here
- insert_at = len(new_path)
-
- if np in known_paths or insert_at is None:
- new_path.append(item)
- else:
- # new path after the insert point, back-insert it
- new_path.insert(insert_at, item)
- insert_at += 1
-
- sys.path[:] = new_path
-
-if __name__=='site':
- __boot()
- del __boot
-
-
-
-
-
-
-
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 68af59fe..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,54 +0,0 @@
-Metadata-Version: 1.0
-Name: sqlalchemy-migrate
-Version: 0.7.2
-Summary: Database schema migration for SQLAlchemy
-Home-page: http://code.google.com/p/sqlalchemy-migrate/
-Author: Jan Dittberner
-Author-email: jan@dittberner.info
-License: MIT
-Description: Inspired by Ruby on Rails' migrations, Migrate provides a way to deal with
- database schema changes in `SQLAlchemy <http://sqlalchemy.org>`_ projects.
-
- Migrate extends SQLAlchemy to have database changeset handling. It provides a
- database change repository mechanism which can be used from the command line as
- well as from inside python code.
-
- Help
- ------
-
- Sphinx documentation is available at the project page `packages.python.org
- <http://packages.python.org/sqlalchemy-migrate/>`_.
-
- Users and developers can be found at #sqlalchemy-migrate on Freenode IRC
- network and at the public users mailing list `migrate-users
- <http://groups.google.com/group/migrate-users>`_.
-
- New releases and major changes are announced at the public announce mailing
- list `migrate-announce <http://groups.google.com/group/migrate-announce>`_
- and at the Python package index `sqlalchemy-migrate
- <http://pypi.python.org/pypi/sqlalchemy-migrate>`_.
-
- Homepage is located at `code.google.com
- <http://code.google.com/p/sqlalchemy-migrate/>`_
-
- You can also clone a current `development version
- <http://code.google.com/p/sqlalchemy-migrate/source/checkout>`_ from the
- project's `mercurial <http://mercurial.selenic.com/>`_ trunk.
-
- Tests and Bugs
- ------------------
-
- To run automated tests:
-
- * Copy test_db.cfg.tmpl to test_db.cfg
- * Edit test_db.cfg with database connection strings suitable for running tests.
- (Use empty databases.)
- * $ pip install -r test-req.pip
- * $ python setup.py develop
- * $ nosetests
-
- Please report any issues with sqlalchemy-migrate to the issue tracker at
- `code.google.com issues
- <http://code.google.com/p/sqlalchemy-migrate/issues/list>`_
-
-Platform: UNKNOWN
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index ae57cb2a..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-MANIFEST.in
-README
-setup.cfg
-setup.py
-docs/Makefile
-docs/api.rst
-docs/changelog.rst
-docs/changeset.rst
-docs/conf.py
-docs/credits.rst
-docs/download.rst
-docs/faq.rst
-docs/glossary.rst
-docs/index.rst
-docs/tools.rst
-docs/versioning.rst
-docs/historical/ProjectDesignDecisionsAutomation.trac
-docs/historical/ProjectDesignDecisionsScriptFormat.trac
-docs/historical/ProjectDesignDecisionsVersioning.trac
-docs/historical/ProjectDetailedDesign.trac
-docs/historical/ProjectGoals.trac
-docs/historical/ProjectProposal.txt
-docs/historical/RepositoryFormat.trac
-docs/historical/RepositoryFormat2.trac
-docs/theme/almodovar.css
-docs/theme/layout.css
-docs/theme/layout.html
-migrate/__init__.py
-migrate/exceptions.py
-migrate/changeset/__init__.py
-migrate/changeset/ansisql.py
-migrate/changeset/constraint.py
-migrate/changeset/schema.py
-migrate/changeset/databases/__init__.py
-migrate/changeset/databases/firebird.py
-migrate/changeset/databases/mysql.py
-migrate/changeset/databases/oracle.py
-migrate/changeset/databases/postgres.py
-migrate/changeset/databases/sqlite.py
-migrate/changeset/databases/visitor.py
-migrate/tests/__init__.py
-migrate/tests/changeset/__init__.py
-migrate/tests/changeset/test_changeset.py
-migrate/tests/changeset/test_constraint.py
-migrate/tests/fixture/__init__.py
-migrate/tests/fixture/base.py
-migrate/tests/fixture/database.py
-migrate/tests/fixture/models.py
-migrate/tests/fixture/pathed.py
-migrate/tests/fixture/shell.py
-migrate/tests/fixture/warnings.py
-migrate/tests/integrated/__init__.py
-migrate/tests/integrated/test_docs.py
-migrate/tests/versioning/__init__.py
-migrate/tests/versioning/test_api.py
-migrate/tests/versioning/test_cfgparse.py
-migrate/tests/versioning/test_database.py
-migrate/tests/versioning/test_genmodel.py
-migrate/tests/versioning/test_keyedinstance.py
-migrate/tests/versioning/test_pathed.py
-migrate/tests/versioning/test_repository.py
-migrate/tests/versioning/test_runchangeset.py
-migrate/tests/versioning/test_schema.py
-migrate/tests/versioning/test_schemadiff.py
-migrate/tests/versioning/test_script.py
-migrate/tests/versioning/test_shell.py
-migrate/tests/versioning/test_template.py
-migrate/tests/versioning/test_util.py
-migrate/tests/versioning/test_version.py
-migrate/versioning/__init__.py
-migrate/versioning/api.py
-migrate/versioning/cfgparse.py
-migrate/versioning/config.py
-migrate/versioning/genmodel.py
-migrate/versioning/migrate_repository.py
-migrate/versioning/pathed.py
-migrate/versioning/repository.py
-migrate/versioning/schema.py
-migrate/versioning/schemadiff.py
-migrate/versioning/shell.py
-migrate/versioning/template.py
-migrate/versioning/version.py
-migrate/versioning/script/__init__.py
-migrate/versioning/script/base.py
-migrate/versioning/script/py.py
-migrate/versioning/script/sql.py
-migrate/versioning/templates/__init__.py
-migrate/versioning/templates/manage/default.py_tmpl
-migrate/versioning/templates/manage/pylons.py_tmpl
-migrate/versioning/templates/repository/__init__.py
-migrate/versioning/templates/repository/default/README
-migrate/versioning/templates/repository/default/__init__.py
-migrate/versioning/templates/repository/default/migrate.cfg
-migrate/versioning/templates/repository/default/versions/__init__.py
-migrate/versioning/templates/repository/pylons/README
-migrate/versioning/templates/repository/pylons/__init__.py
-migrate/versioning/templates/repository/pylons/migrate.cfg
-migrate/versioning/templates/repository/pylons/versions/__init__.py
-migrate/versioning/templates/script/__init__.py
-migrate/versioning/templates/script/default.py_tmpl
-migrate/versioning/templates/script/pylons.py_tmpl
-migrate/versioning/templates/sql_script/default.py_tmpl
-migrate/versioning/templates/sql_script/pylons.py_tmpl
-migrate/versioning/util/__init__.py
-migrate/versioning/util/importpath.py
-migrate/versioning/util/keyedinstance.py
-sqlalchemy_migrate.egg-info/PKG-INFO
-sqlalchemy_migrate.egg-info/SOURCES.txt
-sqlalchemy_migrate.egg-info/dependency_links.txt
-sqlalchemy_migrate.egg-info/entry_points.txt
-sqlalchemy_migrate.egg-info/requires.txt
-sqlalchemy_migrate.egg-info/top_level.txt \ No newline at end of file
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/entry_points.txt b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/entry_points.txt
deleted file mode 100644
index 8d3a7be5..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/entry_points.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-
- [console_scripts]
- migrate = migrate.versioning.shell:main
- migrate-repository = migrate.versioning.migrate_repository:main
- \ No newline at end of file
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/requires.txt
deleted file mode 100644
index cdbb727b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-SQLAlchemy >= 0.6
-decorator
-Tempita >= 0.4
-setuptools
-
-[docs]
-sphinx >= 0.5 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 219f6a58..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-migrate
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/__init__.py
deleted file mode 100755
index 0cfdb726..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""
- SQLAlchemy migrate provides two APIs :mod:`migrate.versioning` for
- database schema version and repository management and
- :mod:`migrate.changeset` that allows to define database schema changes
- using Python.
-"""
-
-from migrate.versioning import *
-from migrate.changeset import *
-
-__version__ = '0.7.2'
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/__init__.py
deleted file mode 100755
index 80ea152d..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""
- This module extends SQLAlchemy and provides additional DDL [#]_
- support.
-
- .. [#] SQL Data Definition Language
-"""
-import re
-import warnings
-
-import sqlalchemy
-from sqlalchemy import __version__ as _sa_version
-
-warnings.simplefilter('always', DeprecationWarning)
-
-_sa_version = tuple(int(re.match("\d+", x).group(0)) for x in _sa_version.split("."))
-SQLA_07 = _sa_version >= (0, 7)
-
-del re
-del _sa_version
-
-from migrate.changeset.schema import *
-from migrate.changeset.constraint import *
-
-sqlalchemy.schema.Table.__bases__ += (ChangesetTable, )
-sqlalchemy.schema.Column.__bases__ += (ChangesetColumn, )
-sqlalchemy.schema.Index.__bases__ += (ChangesetIndex, )
-
-sqlalchemy.schema.DefaultClause.__bases__ += (ChangesetDefaultClause, )
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/ansisql.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/ansisql.py
deleted file mode 100755
index 9ded5605..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/ansisql.py
+++ /dev/null
@@ -1,292 +0,0 @@
-"""
- Extensions to SQLAlchemy for altering existing tables.
-
- At the moment, this isn't so much based off of ANSI as much as
- things that just happen to work with multiple databases.
-"""
-import StringIO
-
-import sqlalchemy as sa
-from sqlalchemy.schema import SchemaVisitor
-from sqlalchemy.engine.default import DefaultDialect
-from sqlalchemy.sql import ClauseElement
-from sqlalchemy.schema import (ForeignKeyConstraint,
- PrimaryKeyConstraint,
- CheckConstraint,
- UniqueConstraint,
- Index)
-
-from migrate import exceptions
-from migrate.changeset import constraint
-
-from sqlalchemy.schema import AddConstraint, DropConstraint
-from sqlalchemy.sql.compiler import DDLCompiler
-SchemaGenerator = SchemaDropper = DDLCompiler
-
-
-class AlterTableVisitor(SchemaVisitor):
- """Common operations for ``ALTER TABLE`` statements."""
-
- # engine.Compiler looks for .statement
- # when it spawns off a new compiler
- statement = ClauseElement()
-
- def append(self, s):
- """Append content to the SchemaIterator's query buffer."""
-
- self.buffer.write(s)
-
- def execute(self):
- """Execute the contents of the SchemaIterator's buffer."""
- try:
- return self.connection.execute(self.buffer.getvalue())
- finally:
- self.buffer.truncate(0)
-
- def __init__(self, dialect, connection, **kw):
- self.connection = connection
- self.buffer = StringIO.StringIO()
- self.preparer = dialect.identifier_preparer
- self.dialect = dialect
-
- def traverse_single(self, elem):
- ret = super(AlterTableVisitor, self).traverse_single(elem)
- if ret:
- # adapt to 0.6 which uses a string-returning
- # object
- self.append(" %s" % ret)
-
- def _to_table(self, param):
- """Returns the table object for the given param object."""
- if isinstance(param, (sa.Column, sa.Index, sa.schema.Constraint)):
- ret = param.table
- else:
- ret = param
- return ret
-
- def start_alter_table(self, param):
- """Returns the start of an ``ALTER TABLE`` SQL-Statement.
-
- Use the param object to determine the table name and use it
- for building the SQL statement.
-
- :param param: object to determine the table from
- :type param: :class:`sqlalchemy.Column`, :class:`sqlalchemy.Index`,
- :class:`sqlalchemy.schema.Constraint`, :class:`sqlalchemy.Table`,
- or string (table name)
- """
- table = self._to_table(param)
- self.append('\nALTER TABLE %s ' % self.preparer.format_table(table))
- return table
-
-
-class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator):
- """Extends ansisql generator for column creation (alter table add col)"""
-
- def visit_column(self, column):
- """Create a column (table already exists).
-
- :param column: column object
- :type column: :class:`sqlalchemy.Column` instance
- """
- if column.default is not None:
- self.traverse_single(column.default)
-
- table = self.start_alter_table(column)
- self.append("ADD ")
- self.append(self.get_column_specification(column))
-
- for cons in column.constraints:
- self.traverse_single(cons)
- self.execute()
-
- # ALTER TABLE STATEMENTS
-
- # add indexes and unique constraints
- if column.index_name:
- Index(column.index_name,column).create()
- elif column.unique_name:
- constraint.UniqueConstraint(column,
- name=column.unique_name).create()
-
- # SA bounds FK constraints to table, add manually
- for fk in column.foreign_keys:
- self.add_foreignkey(fk.constraint)
-
- # add primary key constraint if needed
- if column.primary_key_name:
- cons = constraint.PrimaryKeyConstraint(column,
- name=column.primary_key_name)
- cons.create()
-
- def add_foreignkey(self, fk):
- self.connection.execute(AddConstraint(fk))
-
-class ANSIColumnDropper(AlterTableVisitor, SchemaDropper):
- """Extends ANSI SQL dropper for column dropping (``ALTER TABLE
- DROP COLUMN``).
- """
-
- def visit_column(self, column):
- """Drop a column from its table.
-
- :param column: the column object
- :type column: :class:`sqlalchemy.Column`
- """
- table = self.start_alter_table(column)
- self.append('DROP COLUMN %s' % self.preparer.format_column(column))
- self.execute()
-
-
-class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator):
- """Manages changes to existing schema elements.
-
- Note that columns are schema elements; ``ALTER TABLE ADD COLUMN``
- is in SchemaGenerator.
-
- All items may be renamed. Columns can also have many of their properties -
- type, for example - changed.
-
- Each function is passed a tuple, containing (object, name); where
- object is a type of object you'd expect for that function
- (ie. table for visit_table) and name is the object's new
- name. NONE means the name is unchanged.
- """
-
- def visit_table(self, table):
- """Rename a table. Other ops aren't supported."""
- self.start_alter_table(table)
- self.append("RENAME TO %s" % self.preparer.quote(table.new_name,
- table.quote))
- self.execute()
-
- def visit_index(self, index):
- """Rename an index"""
- if hasattr(self, '_validate_identifier'):
- # SA <= 0.6.3
- self.append("ALTER INDEX %s RENAME TO %s" % (
- self.preparer.quote(
- self._validate_identifier(
- index.name, True), index.quote),
- self.preparer.quote(
- self._validate_identifier(
- index.new_name, True), index.quote)))
- else:
- # SA >= 0.6.5
- self.append("ALTER INDEX %s RENAME TO %s" % (
- self.preparer.quote(
- self._index_identifier(
- index.name), index.quote),
- self.preparer.quote(
- self._index_identifier(
- index.new_name), index.quote)))
- self.execute()
-
- def visit_column(self, delta):
- """Rename/change a column."""
- # ALTER COLUMN is implemented as several ALTER statements
- keys = delta.keys()
- if 'type' in keys:
- self._run_subvisit(delta, self._visit_column_type)
- if 'nullable' in keys:
- self._run_subvisit(delta, self._visit_column_nullable)
- if 'server_default' in keys:
- # Skip 'default': only handle server-side defaults, others
- # are managed by the app, not the db.
- self._run_subvisit(delta, self._visit_column_default)
- if 'name' in keys:
- self._run_subvisit(delta, self._visit_column_name, start_alter=False)
-
- def _run_subvisit(self, delta, func, start_alter=True):
- """Runs visit method based on what needs to be changed on column"""
- table = self._to_table(delta.table)
- col_name = delta.current_name
- if start_alter:
- self.start_alter_column(table, col_name)
- ret = func(table, delta.result_column, delta)
- self.execute()
-
- def start_alter_column(self, table, col_name):
- """Starts ALTER COLUMN"""
- self.start_alter_table(table)
- self.append("ALTER COLUMN %s " % self.preparer.quote(col_name, table.quote))
-
- def _visit_column_nullable(self, table, column, delta):
- nullable = delta['nullable']
- if nullable:
- self.append("DROP NOT NULL")
- else:
- self.append("SET NOT NULL")
-
- def _visit_column_default(self, table, column, delta):
- default_text = self.get_column_default_string(column)
- if default_text is not None:
- self.append("SET DEFAULT %s" % default_text)
- else:
- self.append("DROP DEFAULT")
-
- def _visit_column_type(self, table, column, delta):
- type_ = delta['type']
- type_text = str(type_.compile(dialect=self.dialect))
- self.append("TYPE %s" % type_text)
-
- def _visit_column_name(self, table, column, delta):
- self.start_alter_table(table)
- col_name = self.preparer.quote(delta.current_name, table.quote)
- new_name = self.preparer.format_column(delta.result_column)
- self.append('RENAME COLUMN %s TO %s' % (col_name, new_name))
-
-
-class ANSIConstraintCommon(AlterTableVisitor):
- """
- Migrate's constraints require a separate creation function from
- SA's: Migrate's constraints are created independently of a table;
- SA's are created at the same time as the table.
- """
-
- def get_constraint_name(self, cons):
- """Gets a name for the given constraint.
-
- If the name is already set it will be used otherwise the
- constraint's :meth:`autoname <migrate.changeset.constraint.ConstraintChangeset.autoname>`
- method is used.
-
- :param cons: constraint object
- """
- if cons.name is not None:
- ret = cons.name
- else:
- ret = cons.name = cons.autoname()
- return self.preparer.quote(ret, cons.quote)
-
- def visit_migrate_primary_key_constraint(self, *p, **k):
- self._visit_constraint(*p, **k)
-
- def visit_migrate_foreign_key_constraint(self, *p, **k):
- self._visit_constraint(*p, **k)
-
- def visit_migrate_check_constraint(self, *p, **k):
- self._visit_constraint(*p, **k)
-
- def visit_migrate_unique_constraint(self, *p, **k):
- self._visit_constraint(*p, **k)
-
-class ANSIConstraintGenerator(ANSIConstraintCommon, SchemaGenerator):
- def _visit_constraint(self, constraint):
- constraint.name = self.get_constraint_name(constraint)
- self.append(self.process(AddConstraint(constraint)))
- self.execute()
-
-class ANSIConstraintDropper(ANSIConstraintCommon, SchemaDropper):
- def _visit_constraint(self, constraint):
- constraint.name = self.get_constraint_name(constraint)
- self.append(self.process(DropConstraint(constraint, cascade=constraint.cascade)))
- self.execute()
-
-
-class ANSIDialect(DefaultDialect):
- columngenerator = ANSIColumnGenerator
- columndropper = ANSIColumnDropper
- schemachanger = ANSISchemaChanger
- constraintgenerator = ANSIConstraintGenerator
- constraintdropper = ANSIConstraintDropper
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/constraint.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/constraint.py
deleted file mode 100755
index 96407bd7..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/constraint.py
+++ /dev/null
@@ -1,199 +0,0 @@
-"""
- This module defines standalone schema constraint classes.
-"""
-from sqlalchemy import schema
-
-from migrate.exceptions import *
-
-class ConstraintChangeset(object):
- """Base class for Constraint classes."""
-
- def _normalize_columns(self, cols, table_name=False):
- """Given: column objects or names; return col names and
- (maybe) a table"""
- colnames = []
- table = None
- for col in cols:
- if isinstance(col, schema.Column):
- if col.table is not None and table is None:
- table = col.table
- if table_name:
- col = '.'.join((col.table.name, col.name))
- else:
- col = col.name
- colnames.append(col)
- return colnames, table
-
- def __do_imports(self, visitor_name, *a, **kw):
- engine = kw.pop('engine', self.table.bind)
- from migrate.changeset.databases.visitor import (get_engine_visitor,
- run_single_visitor)
- visitorcallable = get_engine_visitor(engine, visitor_name)
- run_single_visitor(engine, visitorcallable, self, *a, **kw)
-
- def create(self, *a, **kw):
- """Create the constraint in the database.
-
- :param engine: the database engine to use. If this is \
- :keyword:`None` the instance's engine will be used
- :type engine: :class:`sqlalchemy.engine.base.Engine`
- :param connection: reuse connection istead of creating new one.
- :type connection: :class:`sqlalchemy.engine.base.Connection` instance
- """
- # TODO: set the parent here instead of in __init__
- self.__do_imports('constraintgenerator', *a, **kw)
-
- def drop(self, *a, **kw):
- """Drop the constraint from the database.
-
- :param engine: the database engine to use. If this is
- :keyword:`None` the instance's engine will be used
- :param cascade: Issue CASCADE drop if database supports it
- :type engine: :class:`sqlalchemy.engine.base.Engine`
- :type cascade: bool
- :param connection: reuse connection istead of creating new one.
- :type connection: :class:`sqlalchemy.engine.base.Connection` instance
- :returns: Instance with cleared columns
- """
- self.cascade = kw.pop('cascade', False)
- self.__do_imports('constraintdropper', *a, **kw)
- # the spirit of Constraint objects is that they
- # are immutable (just like in a DB. they're only ADDed
- # or DROPped).
- #self.columns.clear()
- return self
-
-
-class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
- """Construct PrimaryKeyConstraint
-
- Migrate's additional parameters:
-
- :param cols: Columns in constraint.
- :param table: If columns are passed as strings, this kw is required
- :type table: Table instance
- :type cols: strings or Column instances
- """
-
- __migrate_visit_name__ = 'migrate_primary_key_constraint'
-
- def __init__(self, *cols, **kwargs):
- colnames, table = self._normalize_columns(cols)
- table = kwargs.pop('table', table)
- super(PrimaryKeyConstraint, self).__init__(*colnames, **kwargs)
- if table is not None:
- self._set_parent(table)
-
-
- def autoname(self):
- """Mimic the database's automatic constraint names"""
- return "%s_pkey" % self.table.name
-
-
-class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint):
- """Construct ForeignKeyConstraint
-
- Migrate's additional parameters:
-
- :param columns: Columns in constraint
- :param refcolumns: Columns that this FK reffers to in another table.
- :param table: If columns are passed as strings, this kw is required
- :type table: Table instance
- :type columns: list of strings or Column instances
- :type refcolumns: list of strings or Column instances
- """
-
- __migrate_visit_name__ = 'migrate_foreign_key_constraint'
-
- def __init__(self, columns, refcolumns, *args, **kwargs):
- colnames, table = self._normalize_columns(columns)
- table = kwargs.pop('table', table)
- refcolnames, reftable = self._normalize_columns(refcolumns,
- table_name=True)
- super(ForeignKeyConstraint, self).__init__(colnames, refcolnames, *args,
- **kwargs)
- if table is not None:
- self._set_parent(table)
-
- @property
- def referenced(self):
- return [e.column for e in self.elements]
-
- @property
- def reftable(self):
- return self.referenced[0].table
-
- def autoname(self):
- """Mimic the database's automatic constraint names"""
- if hasattr(self.columns, 'keys'):
- # SA <= 0.5
- firstcol = self.columns[self.columns.keys()[0]]
- ret = "%(table)s_%(firstcolumn)s_fkey" % dict(
- table=firstcol.table.name,
- firstcolumn=firstcol.name,)
- else:
- # SA >= 0.6
- ret = "%(table)s_%(firstcolumn)s_fkey" % dict(
- table=self.table.name,
- firstcolumn=self.columns[0],)
- return ret
-
-
-class CheckConstraint(ConstraintChangeset, schema.CheckConstraint):
- """Construct CheckConstraint
-
- Migrate's additional parameters:
-
- :param sqltext: Plain SQL text to check condition
- :param columns: If not name is applied, you must supply this kw\
- to autoname constraint
- :param table: If columns are passed as strings, this kw is required
- :type table: Table instance
- :type columns: list of Columns instances
- :type sqltext: string
- """
-
- __migrate_visit_name__ = 'migrate_check_constraint'
-
- def __init__(self, sqltext, *args, **kwargs):
- cols = kwargs.pop('columns', [])
- if not cols and not kwargs.get('name', False):
- raise InvalidConstraintError('You must either set "name"'
- 'parameter or "columns" to autogenarate it.')
- colnames, table = self._normalize_columns(cols)
- table = kwargs.pop('table', table)
- schema.CheckConstraint.__init__(self, sqltext, *args, **kwargs)
- if table is not None:
- self._set_parent(table)
- self.colnames = colnames
-
- def autoname(self):
- return "%(table)s_%(cols)s_check" % \
- dict(table=self.table.name, cols="_".join(self.colnames))
-
-
-class UniqueConstraint(ConstraintChangeset, schema.UniqueConstraint):
- """Construct UniqueConstraint
-
- Migrate's additional parameters:
-
- :param cols: Columns in constraint.
- :param table: If columns are passed as strings, this kw is required
- :type table: Table instance
- :type cols: strings or Column instances
-
- .. versionadded:: 0.6.0
- """
-
- __migrate_visit_name__ = 'migrate_unique_constraint'
-
- def __init__(self, *cols, **kwargs):
- self.colnames, table = self._normalize_columns(cols)
- table = kwargs.pop('table', table)
- super(UniqueConstraint, self).__init__(*self.colnames, **kwargs)
- if table is not None:
- self._set_parent(table)
-
- def autoname(self):
- """Mimic the database's automatic constraint names"""
- return "%s_%s_key" % (self.table.name, self.colnames[0])
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/__init__.py
deleted file mode 100755
index 85469183..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
- This module contains database dialect specific changeset
- implementations.
-"""
-__all__ = [
- 'postgres',
- 'sqlite',
- 'mysql',
- 'oracle',
-]
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/firebird.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/firebird.py
deleted file mode 100755
index 226728b9..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/firebird.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
- Firebird database specific implementations of changeset classes.
-"""
-from sqlalchemy.databases import firebird as sa_base
-from sqlalchemy.schema import PrimaryKeyConstraint
-from migrate import exceptions
-from migrate.changeset import ansisql
-
-
-FBSchemaGenerator = sa_base.FBDDLCompiler
-
-class FBColumnGenerator(FBSchemaGenerator, ansisql.ANSIColumnGenerator):
- """Firebird column generator implementation."""
-
-
-class FBColumnDropper(ansisql.ANSIColumnDropper):
- """Firebird column dropper implementation."""
-
- def visit_column(self, column):
- """Firebird supports 'DROP col' instead of 'DROP COLUMN col' syntax
-
- Drop primary key and unique constraints if dropped column is referencing it."""
- if column.primary_key:
- if column.table.primary_key.columns.contains_column(column):
- column.table.primary_key.drop()
- # TODO: recreate primary key if it references more than this column
-
- for index in column.table.indexes:
- # "column in index.columns" causes problems as all
- # column objects compare equal and return a SQL expression
- if column.name in [col.name for col in index.columns]:
- index.drop()
- # TODO: recreate index if it references more than this column
-
- for cons in column.table.constraints:
- if isinstance(cons,PrimaryKeyConstraint):
- # will be deleted only when the column its on
- # is deleted!
- continue
-
- should_drop = column.name in cons.columns
- if should_drop:
- self.start_alter_table(column)
- self.append("DROP CONSTRAINT ")
- self.append(self.preparer.format_constraint(cons))
- self.execute()
- # TODO: recreate unique constraint if it refenrences more than this column
-
- self.start_alter_table(column)
- self.append('DROP %s' % self.preparer.format_column(column))
- self.execute()
-
-
-class FBSchemaChanger(ansisql.ANSISchemaChanger):
- """Firebird schema changer implementation."""
-
- def visit_table(self, table):
- """Rename table not supported"""
- raise exceptions.NotSupportedError(
- "Firebird does not support renaming tables.")
-
- def _visit_column_name(self, table, column, delta):
- self.start_alter_table(table)
- col_name = self.preparer.quote(delta.current_name, table.quote)
- new_name = self.preparer.format_column(delta.result_column)
- self.append('ALTER COLUMN %s TO %s' % (col_name, new_name))
-
- def _visit_column_nullable(self, table, column, delta):
- """Changing NULL is not supported"""
- # TODO: http://www.firebirdfaq.org/faq103/
- raise exceptions.NotSupportedError(
- "Firebird does not support altering NULL bevahior.")
-
-
-class FBConstraintGenerator(ansisql.ANSIConstraintGenerator):
- """Firebird constraint generator implementation."""
-
-
-class FBConstraintDropper(ansisql.ANSIConstraintDropper):
- """Firebird constaint dropper implementation."""
-
- def cascade_constraint(self, constraint):
- """Cascading constraints is not supported"""
- raise exceptions.NotSupportedError(
- "Firebird does not support cascading constraints")
-
-
-class FBDialect(ansisql.ANSIDialect):
- columngenerator = FBColumnGenerator
- columndropper = FBColumnDropper
- schemachanger = FBSchemaChanger
- constraintgenerator = FBConstraintGenerator
- constraintdropper = FBConstraintDropper
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/mysql.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/mysql.py
deleted file mode 100755
index 6987b4bb..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/mysql.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
- MySQL database specific implementations of changeset classes.
-"""
-
-from sqlalchemy.databases import mysql as sa_base
-from sqlalchemy import types as sqltypes
-
-from migrate import exceptions
-from migrate.changeset import ansisql
-
-
-MySQLSchemaGenerator = sa_base.MySQLDDLCompiler
-
-class MySQLColumnGenerator(MySQLSchemaGenerator, ansisql.ANSIColumnGenerator):
- pass
-
-
-class MySQLColumnDropper(ansisql.ANSIColumnDropper):
- pass
-
-
-class MySQLSchemaChanger(MySQLSchemaGenerator, ansisql.ANSISchemaChanger):
-
- def visit_column(self, delta):
- table = delta.table
- colspec = self.get_column_specification(delta.result_column)
- if delta.result_column.autoincrement:
- primary_keys = [c for c in table.primary_key.columns
- if (c.autoincrement and
- isinstance(c.type, sqltypes.Integer) and
- not c.foreign_keys)]
-
- if primary_keys:
- first = primary_keys.pop(0)
- if first.name == delta.current_name:
- colspec += " AUTO_INCREMENT"
- old_col_name = self.preparer.quote(delta.current_name, table.quote)
-
- self.start_alter_table(table)
-
- self.append("CHANGE COLUMN %s " % old_col_name)
- self.append(colspec)
- self.execute()
-
- def visit_index(self, param):
- # If MySQL can do this, I can't find how
- raise exceptions.NotSupportedError("MySQL cannot rename indexes")
-
-
-class MySQLConstraintGenerator(ansisql.ANSIConstraintGenerator):
- pass
-
-
-class MySQLConstraintDropper(MySQLSchemaGenerator, ansisql.ANSIConstraintDropper):
- def visit_migrate_check_constraint(self, *p, **k):
- raise exceptions.NotSupportedError("MySQL does not support CHECK"
- " constraints, use triggers instead.")
-
-
-class MySQLDialect(ansisql.ANSIDialect):
- columngenerator = MySQLColumnGenerator
- columndropper = MySQLColumnDropper
- schemachanger = MySQLSchemaChanger
- constraintgenerator = MySQLConstraintGenerator
- constraintdropper = MySQLConstraintDropper
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/oracle.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/oracle.py
deleted file mode 100755
index 2f16b5b5..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/oracle.py
+++ /dev/null
@@ -1,108 +0,0 @@
-"""
- Oracle database specific implementations of changeset classes.
-"""
-import sqlalchemy as sa
-from sqlalchemy.databases import oracle as sa_base
-
-from migrate import exceptions
-from migrate.changeset import ansisql
-
-
-OracleSchemaGenerator = sa_base.OracleDDLCompiler
-
-
-class OracleColumnGenerator(OracleSchemaGenerator, ansisql.ANSIColumnGenerator):
- pass
-
-
-class OracleColumnDropper(ansisql.ANSIColumnDropper):
- pass
-
-
-class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger):
-
- def get_column_specification(self, column, **kwargs):
- # Ignore the NOT NULL generated
- override_nullable = kwargs.pop('override_nullable', None)
- if override_nullable:
- orig = column.nullable
- column.nullable = True
- ret = super(OracleSchemaChanger, self).get_column_specification(
- column, **kwargs)
- if override_nullable:
- column.nullable = orig
- return ret
-
- def visit_column(self, delta):
- keys = delta.keys()
-
- if 'name' in keys:
- self._run_subvisit(delta,
- self._visit_column_name,
- start_alter=False)
-
- if len(set(('type', 'nullable', 'server_default')).intersection(keys)):
- self._run_subvisit(delta,
- self._visit_column_change,
- start_alter=False)
-
- def _visit_column_change(self, table, column, delta):
- # Oracle cannot drop a default once created, but it can set it
- # to null. We'll do that if default=None
- # http://forums.oracle.com/forums/message.jspa?messageID=1273234#1273234
- dropdefault_hack = (column.server_default is None \
- and 'server_default' in delta.keys())
- # Oracle apparently doesn't like it when we say "not null" if
- # the column's already not null. Fudge it, so we don't need a
- # new function
- notnull_hack = ((not column.nullable) \
- and ('nullable' not in delta.keys()))
- # We need to specify NULL if we're removing a NOT NULL
- # constraint
- null_hack = (column.nullable and ('nullable' in delta.keys()))
-
- if dropdefault_hack:
- column.server_default = sa.PassiveDefault(sa.sql.null())
- if notnull_hack:
- column.nullable = True
- colspec = self.get_column_specification(column,
- override_nullable=null_hack)
- if null_hack:
- colspec += ' NULL'
- if notnull_hack:
- column.nullable = False
- if dropdefault_hack:
- column.server_default = None
-
- self.start_alter_table(table)
- self.append("MODIFY (")
- self.append(colspec)
- self.append(")")
-
-
-class OracleConstraintCommon(object):
-
- def get_constraint_name(self, cons):
- # Oracle constraints can't guess their name like other DBs
- if not cons.name:
- raise exceptions.NotSupportedError(
- "Oracle constraint names must be explicitly stated")
- return cons.name
-
-
-class OracleConstraintGenerator(OracleConstraintCommon,
- ansisql.ANSIConstraintGenerator):
- pass
-
-
-class OracleConstraintDropper(OracleConstraintCommon,
- ansisql.ANSIConstraintDropper):
- pass
-
-
-class OracleDialect(ansisql.ANSIDialect):
- columngenerator = OracleColumnGenerator
- columndropper = OracleColumnDropper
- schemachanger = OracleSchemaChanger
- constraintgenerator = OracleConstraintGenerator
- constraintdropper = OracleConstraintDropper
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/postgres.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/postgres.py
deleted file mode 100755
index 10ea094c..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/postgres.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""
- `PostgreSQL`_ database specific implementations of changeset classes.
-
- .. _`PostgreSQL`: http://www.postgresql.org/
-"""
-from migrate.changeset import ansisql
-
-from sqlalchemy.databases import postgresql as sa_base
-PGSchemaGenerator = sa_base.PGDDLCompiler
-
-
-class PGColumnGenerator(PGSchemaGenerator, ansisql.ANSIColumnGenerator):
- """PostgreSQL column generator implementation."""
- pass
-
-
-class PGColumnDropper(ansisql.ANSIColumnDropper):
- """PostgreSQL column dropper implementation."""
- pass
-
-
-class PGSchemaChanger(ansisql.ANSISchemaChanger):
- """PostgreSQL schema changer implementation."""
- pass
-
-
-class PGConstraintGenerator(ansisql.ANSIConstraintGenerator):
- """PostgreSQL constraint generator implementation."""
- pass
-
-
-class PGConstraintDropper(ansisql.ANSIConstraintDropper):
- """PostgreSQL constaint dropper implementation."""
- pass
-
-
-class PGDialect(ansisql.ANSIDialect):
- columngenerator = PGColumnGenerator
- columndropper = PGColumnDropper
- schemachanger = PGSchemaChanger
- constraintgenerator = PGConstraintGenerator
- constraintdropper = PGConstraintDropper
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/sqlite.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/sqlite.py
deleted file mode 100755
index 5ddd3f17..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/sqlite.py
+++ /dev/null
@@ -1,153 +0,0 @@
-"""
- `SQLite`_ database specific implementations of changeset classes.
-
- .. _`SQLite`: http://www.sqlite.org/
-"""
-from UserDict import DictMixin
-from copy import copy
-
-from sqlalchemy.databases import sqlite as sa_base
-
-from migrate import exceptions
-from migrate.changeset import ansisql
-
-
-SQLiteSchemaGenerator = sa_base.SQLiteDDLCompiler
-
-
-class SQLiteCommon(object):
-
- def _not_supported(self, op):
- raise exceptions.NotSupportedError("SQLite does not support "
- "%s; see http://www.sqlite.org/lang_altertable.html" % op)
-
-
-class SQLiteHelper(SQLiteCommon):
-
- def recreate_table(self,table,column=None,delta=None):
- table_name = self.preparer.format_table(table)
-
- # we remove all indexes so as not to have
- # problems during copy and re-create
- for index in table.indexes:
- index.drop()
-
- self.append('ALTER TABLE %s RENAME TO migration_tmp' % table_name)
- self.execute()
-
- insertion_string = self._modify_table(table, column, delta)
-
- table.create(bind=self.connection)
- self.append(insertion_string % {'table_name': table_name})
- self.execute()
- self.append('DROP TABLE migration_tmp')
- self.execute()
-
- def visit_column(self, delta):
- if isinstance(delta, DictMixin):
- column = delta.result_column
- table = self._to_table(delta.table)
- else:
- column = delta
- table = self._to_table(column.table)
- self.recreate_table(table,column,delta)
-
-class SQLiteColumnGenerator(SQLiteSchemaGenerator,
- ansisql.ANSIColumnGenerator,
- # at the end so we get the normal
- # visit_column by default
- SQLiteHelper,
- SQLiteCommon
- ):
- """SQLite ColumnGenerator"""
-
- def _modify_table(self, table, column, delta):
- columns = ' ,'.join(map(
- self.preparer.format_column,
- [c for c in table.columns if c.name!=column.name]))
- return ('INSERT INTO %%(table_name)s (%(cols)s) '
- 'SELECT %(cols)s from migration_tmp')%{'cols':columns}
-
- def visit_column(self,column):
- if column.foreign_keys:
- SQLiteHelper.visit_column(self,column)
- else:
- super(SQLiteColumnGenerator,self).visit_column(column)
-
-class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper):
- """SQLite ColumnDropper"""
-
- def _modify_table(self, table, column, delta):
-
- columns = ' ,'.join(map(self.preparer.format_column, table.columns))
- return 'INSERT INTO %(table_name)s SELECT ' + columns + \
- ' from migration_tmp'
-
- def visit_column(self,column):
- # For SQLite, we *have* to remove the column here so the table
- # is re-created properly.
- column.remove_from_table(column.table,unset_table=False)
- super(SQLiteColumnDropper,self).visit_column(column)
-
-
-class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger):
- """SQLite SchemaChanger"""
-
- def _modify_table(self, table, column, delta):
- return 'INSERT INTO %(table_name)s SELECT * from migration_tmp'
-
- def visit_index(self, index):
- """Does not support ALTER INDEX"""
- self._not_supported('ALTER INDEX')
-
-
-class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator, SQLiteHelper, SQLiteCommon):
-
- def visit_migrate_primary_key_constraint(self, constraint):
- tmpl = "CREATE UNIQUE INDEX %s ON %s ( %s )"
- cols = ', '.join(map(self.preparer.format_column, constraint.columns))
- tname = self.preparer.format_table(constraint.table)
- name = self.get_constraint_name(constraint)
- msg = tmpl % (name, tname, cols)
- self.append(msg)
- self.execute()
-
- def _modify_table(self, table, column, delta):
- return 'INSERT INTO %(table_name)s SELECT * from migration_tmp'
-
- def visit_migrate_foreign_key_constraint(self, *p, **k):
- self.recreate_table(p[0].table)
-
- def visit_migrate_unique_constraint(self, *p, **k):
- self.recreate_table(p[0].table)
-
-
-class SQLiteConstraintDropper(ansisql.ANSIColumnDropper,
- SQLiteCommon,
- ansisql.ANSIConstraintCommon):
-
- def visit_migrate_primary_key_constraint(self, constraint):
- tmpl = "DROP INDEX %s "
- name = self.get_constraint_name(constraint)
- msg = tmpl % (name)
- self.append(msg)
- self.execute()
-
- def visit_migrate_foreign_key_constraint(self, *p, **k):
- self._not_supported('ALTER TABLE DROP CONSTRAINT')
-
- def visit_migrate_check_constraint(self, *p, **k):
- self._not_supported('ALTER TABLE DROP CONSTRAINT')
-
- def visit_migrate_unique_constraint(self, *p, **k):
- self._not_supported('ALTER TABLE DROP CONSTRAINT')
-
-
-# TODO: technically primary key is a NOT NULL + UNIQUE constraint, should add NOT NULL to index
-
-class SQLiteDialect(ansisql.ANSIDialect):
- columngenerator = SQLiteColumnGenerator
- columndropper = SQLiteColumnDropper
- schemachanger = SQLiteSchemaChanger
- constraintgenerator = SQLiteConstraintGenerator
- constraintdropper = SQLiteConstraintDropper
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/visitor.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/visitor.py
deleted file mode 100755
index 228b4d3f..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/databases/visitor.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""
- Module for visitor class mapping.
-"""
-import sqlalchemy as sa
-
-from migrate.changeset import ansisql
-from migrate.changeset.databases import (sqlite,
- postgres,
- mysql,
- oracle,
- firebird)
-
-
-# Map SA dialects to the corresponding Migrate extensions
-DIALECTS = {
- "default": ansisql.ANSIDialect,
- "sqlite": sqlite.SQLiteDialect,
- "postgres": postgres.PGDialect,
- "postgresql": postgres.PGDialect,
- "mysql": mysql.MySQLDialect,
- "oracle": oracle.OracleDialect,
- "firebird": firebird.FBDialect,
-}
-
-
-def get_engine_visitor(engine, name):
- """
- Get the visitor implementation for the given database engine.
-
- :param engine: SQLAlchemy Engine
- :param name: Name of the visitor
- :type name: string
- :type engine: Engine
- :returns: visitor
- """
- # TODO: link to supported visitors
- return get_dialect_visitor(engine.dialect, name)
-
-
-def get_dialect_visitor(sa_dialect, name):
- """
- Get the visitor implementation for the given dialect.
-
- Finds the visitor implementation based on the dialect class and
- returns and instance initialized with the given name.
-
- Binds dialect specific preparer to visitor.
- """
-
- # map sa dialect to migrate dialect and return visitor
- sa_dialect_name = getattr(sa_dialect, 'name', 'default')
- migrate_dialect_cls = DIALECTS[sa_dialect_name]
- visitor = getattr(migrate_dialect_cls, name)
-
- # bind preparer
- visitor.preparer = sa_dialect.preparer(sa_dialect)
-
- return visitor
-
-def run_single_visitor(engine, visitorcallable, element,
- connection=None, **kwargs):
- """Taken from :meth:`sqlalchemy.engine.base.Engine._run_single_visitor`
- with support for migrate visitors.
- """
- if connection is None:
- conn = engine.contextual_connect(close_with_result=False)
- else:
- conn = connection
- visitor = visitorcallable(engine.dialect, conn)
- try:
- if hasattr(element, '__migrate_visit_name__'):
- fn = getattr(visitor, 'visit_' + element.__migrate_visit_name__)
- else:
- fn = getattr(visitor, 'visit_' + element.__visit_name__)
- fn(element, **kwargs)
- finally:
- if connection is None:
- conn.close()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/schema.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/schema.py
deleted file mode 100755
index c467cc53..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/changeset/schema.py
+++ /dev/null
@@ -1,655 +0,0 @@
-"""
- Schema module providing common schema operations.
-"""
-import warnings
-
-from UserDict import DictMixin
-
-import sqlalchemy
-
-from sqlalchemy.schema import ForeignKeyConstraint
-from sqlalchemy.schema import UniqueConstraint
-
-from migrate.exceptions import *
-from migrate.changeset import SQLA_07
-from migrate.changeset.databases.visitor import (get_engine_visitor,
- run_single_visitor)
-
-
-__all__ = [
- 'create_column',
- 'drop_column',
- 'alter_column',
- 'rename_table',
- 'rename_index',
- 'ChangesetTable',
- 'ChangesetColumn',
- 'ChangesetIndex',
- 'ChangesetDefaultClause',
- 'ColumnDelta',
-]
-
-def create_column(column, table=None, *p, **kw):
- """Create a column, given the table.
-
- API to :meth:`ChangesetColumn.create`.
- """
- if table is not None:
- return table.create_column(column, *p, **kw)
- return column.create(*p, **kw)
-
-
-def drop_column(column, table=None, *p, **kw):
- """Drop a column, given the table.
-
- API to :meth:`ChangesetColumn.drop`.
- """
- if table is not None:
- return table.drop_column(column, *p, **kw)
- return column.drop(*p, **kw)
-
-
-def rename_table(table, name, engine=None, **kw):
- """Rename a table.
-
- If Table instance is given, engine is not used.
-
- API to :meth:`ChangesetTable.rename`.
-
- :param table: Table to be renamed.
- :param name: New name for Table.
- :param engine: Engine instance.
- :type table: string or Table instance
- :type name: string
- :type engine: obj
- """
- table = _to_table(table, engine)
- table.rename(name, **kw)
-
-
-def rename_index(index, name, table=None, engine=None, **kw):
- """Rename an index.
-
- If Index instance is given,
- table and engine are not used.
-
- API to :meth:`ChangesetIndex.rename`.
-
- :param index: Index to be renamed.
- :param name: New name for index.
- :param table: Table to which Index is reffered.
- :param engine: Engine instance.
- :type index: string or Index instance
- :type name: string
- :type table: string or Table instance
- :type engine: obj
- """
- index = _to_index(index, table, engine)
- index.rename(name, **kw)
-
-
-def alter_column(*p, **k):
- """Alter a column.
-
- This is a helper function that creates a :class:`ColumnDelta` and
- runs it.
-
- :argument column:
- The name of the column to be altered or a
- :class:`ChangesetColumn` column representing it.
-
- :param table:
- A :class:`~sqlalchemy.schema.Table` or table name to
- for the table where the column will be changed.
-
- :param engine:
- The :class:`~sqlalchemy.engine.base.Engine` to use for table
- reflection and schema alterations.
-
- :returns: A :class:`ColumnDelta` instance representing the change.
-
-
- """
-
- if 'table' not in k and isinstance(p[0], sqlalchemy.Column):
- k['table'] = p[0].table
- if 'engine' not in k:
- k['engine'] = k['table'].bind
-
- # deprecation
- if len(p) >= 2 and isinstance(p[1], sqlalchemy.Column):
- warnings.warn(
- "Passing a Column object to alter_column is deprecated."
- " Just pass in keyword parameters instead.",
- MigrateDeprecationWarning
- )
- engine = k['engine']
-
- # enough tests seem to break when metadata is always altered
- # that this crutch has to be left in until they can be sorted
- # out
- k['alter_metadata']=True
-
- delta = ColumnDelta(*p, **k)
-
- visitorcallable = get_engine_visitor(engine, 'schemachanger')
- engine._run_visitor(visitorcallable, delta)
-
- return delta
-
-
-def _to_table(table, engine=None):
- """Return if instance of Table, else construct new with metadata"""
- if isinstance(table, sqlalchemy.Table):
- return table
-
- # Given: table name, maybe an engine
- meta = sqlalchemy.MetaData()
- if engine is not None:
- meta.bind = engine
- return sqlalchemy.Table(table, meta)
-
-
-def _to_index(index, table=None, engine=None):
- """Return if instance of Index, else construct new with metadata"""
- if isinstance(index, sqlalchemy.Index):
- return index
-
- # Given: index name; table name required
- table = _to_table(table, engine)
- ret = sqlalchemy.Index(index)
- ret.table = table
- return ret
-
-
-class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
- """Extracts the differences between two columns/column-parameters
-
- May receive parameters arranged in several different ways:
-
- * **current_column, new_column, \*p, \*\*kw**
- Additional parameters can be specified to override column
- differences.
-
- * **current_column, \*p, \*\*kw**
- Additional parameters alter current_column. Table name is extracted
- from current_column object.
- Name is changed to current_column.name from current_name,
- if current_name is specified.
-
- * **current_col_name, \*p, \*\*kw**
- Table kw must specified.
-
- :param table: Table at which current Column should be bound to.\
- If table name is given, reflection will be used.
- :type table: string or Table instance
-
- :param metadata: A :class:`MetaData` instance to store
- reflected table names
-
- :param engine: When reflecting tables, either engine or metadata must \
- be specified to acquire engine object.
- :type engine: :class:`Engine` instance
- :returns: :class:`ColumnDelta` instance provides interface for altered attributes to \
- `result_column` through :func:`dict` alike object.
-
- * :class:`ColumnDelta`.result_column is altered column with new attributes
-
- * :class:`ColumnDelta`.current_name is current name of column in db
-
-
- """
-
- # Column attributes that can be altered
- diff_keys = ('name', 'type', 'primary_key', 'nullable',
- 'server_onupdate', 'server_default', 'autoincrement')
- diffs = dict()
- __visit_name__ = 'column'
-
- def __init__(self, *p, **kw):
- # 'alter_metadata' is not a public api. It exists purely
- # as a crutch until the tests that fail when 'alter_metadata'
- # behaviour always happens can be sorted out
- self.alter_metadata = kw.pop("alter_metadata", False)
-
- self.meta = kw.pop("metadata", None)
- self.engine = kw.pop("engine", None)
-
- # Things are initialized differently depending on how many column
- # parameters are given. Figure out how many and call the appropriate
- # method.
- if len(p) >= 1 and isinstance(p[0], sqlalchemy.Column):
- # At least one column specified
- if len(p) >= 2 and isinstance(p[1], sqlalchemy.Column):
- # Two columns specified
- diffs = self.compare_2_columns(*p, **kw)
- else:
- # Exactly one column specified
- diffs = self.compare_1_column(*p, **kw)
- else:
- # Zero columns specified
- if not len(p) or not isinstance(p[0], basestring):
- raise ValueError("First argument must be column name")
- diffs = self.compare_parameters(*p, **kw)
-
- self.apply_diffs(diffs)
-
- def __repr__(self):
- return '<ColumnDelta altermetadata=%r, %s>' % (
- self.alter_metadata,
- super(ColumnDelta, self).__repr__()
- )
-
- def __getitem__(self, key):
- if key not in self.keys():
- raise KeyError("No such diff key, available: %s" % self.diffs )
- return getattr(self.result_column, key)
-
- def __setitem__(self, key, value):
- if key not in self.keys():
- raise KeyError("No such diff key, available: %s" % self.diffs )
- setattr(self.result_column, key, value)
-
- def __delitem__(self, key):
- raise NotImplementedError
-
- def keys(self):
- return self.diffs.keys()
-
- def compare_parameters(self, current_name, *p, **k):
- """Compares Column objects with reflection"""
- self.table = k.pop('table')
- self.result_column = self._table.c.get(current_name)
- if len(p):
- k = self._extract_parameters(p, k, self.result_column)
- return k
-
- def compare_1_column(self, col, *p, **k):
- """Compares one Column object"""
- self.table = k.pop('table', None)
- if self.table is None:
- self.table = col.table
- self.result_column = col
- if len(p):
- k = self._extract_parameters(p, k, self.result_column)
- return k
-
- def compare_2_columns(self, old_col, new_col, *p, **k):
- """Compares two Column objects"""
- self.process_column(new_col)
- self.table = k.pop('table', None)
- # we cannot use bool() on table in SA06
- if self.table is None:
- self.table = old_col.table
- if self.table is None:
- new_col.table
- self.result_column = old_col
-
- # set differences
- # leave out some stuff for later comp
- for key in (set(self.diff_keys) - set(('type',))):
- val = getattr(new_col, key, None)
- if getattr(self.result_column, key, None) != val:
- k.setdefault(key, val)
-
- # inspect types
- if not self.are_column_types_eq(self.result_column.type, new_col.type):
- k.setdefault('type', new_col.type)
-
- if len(p):
- k = self._extract_parameters(p, k, self.result_column)
- return k
-
- def apply_diffs(self, diffs):
- """Populate dict and column object with new values"""
- self.diffs = diffs
- for key in self.diff_keys:
- if key in diffs:
- setattr(self.result_column, key, diffs[key])
-
- self.process_column(self.result_column)
-
- # create an instance of class type if not yet
- if 'type' in diffs and callable(self.result_column.type):
- self.result_column.type = self.result_column.type()
-
- # add column to the table
- if self.table is not None and self.alter_metadata:
- self.result_column.add_to_table(self.table)
-
- def are_column_types_eq(self, old_type, new_type):
- """Compares two types to be equal"""
- ret = old_type.__class__ == new_type.__class__
-
- # String length is a special case
- if ret and isinstance(new_type, sqlalchemy.types.String):
- ret = (getattr(old_type, 'length', None) == \
- getattr(new_type, 'length', None))
- return ret
-
- def _extract_parameters(self, p, k, column):
- """Extracts data from p and modifies diffs"""
- p = list(p)
- while len(p):
- if isinstance(p[0], basestring):
- k.setdefault('name', p.pop(0))
- elif isinstance(p[0], sqlalchemy.types.AbstractType):
- k.setdefault('type', p.pop(0))
- elif callable(p[0]):
- p[0] = p[0]()
- else:
- break
-
- if len(p):
- new_col = column.copy_fixed()
- new_col._init_items(*p)
- k = self.compare_2_columns(column, new_col, **k)
- return k
-
- def process_column(self, column):
- """Processes default values for column"""
- # XXX: this is a snippet from SA processing of positional parameters
- toinit = list()
-
- if column.server_default is not None:
- if isinstance(column.server_default, sqlalchemy.FetchedValue):
- toinit.append(column.server_default)
- else:
- toinit.append(sqlalchemy.DefaultClause(column.server_default))
- if column.server_onupdate is not None:
- if isinstance(column.server_onupdate, FetchedValue):
- toinit.append(column.server_default)
- else:
- toinit.append(sqlalchemy.DefaultClause(column.server_onupdate,
- for_update=True))
- if toinit:
- column._init_items(*toinit)
-
- def _get_table(self):
- return getattr(self, '_table', None)
-
- def _set_table(self, table):
- if isinstance(table, basestring):
- if self.alter_metadata:
- if not self.meta:
- raise ValueError("metadata must be specified for table"
- " reflection when using alter_metadata")
- meta = self.meta
- if self.engine:
- meta.bind = self.engine
- else:
- if not self.engine and not self.meta:
- raise ValueError("engine or metadata must be specified"
- " to reflect tables")
- if not self.engine:
- self.engine = self.meta.bind
- meta = sqlalchemy.MetaData(bind=self.engine)
- self._table = sqlalchemy.Table(table, meta, autoload=True)
- elif isinstance(table, sqlalchemy.Table):
- self._table = table
- if not self.alter_metadata:
- self._table.meta = sqlalchemy.MetaData(bind=self._table.bind)
- def _get_result_column(self):
- return getattr(self, '_result_column', None)
-
- def _set_result_column(self, column):
- """Set Column to Table based on alter_metadata evaluation."""
- self.process_column(column)
- if not hasattr(self, 'current_name'):
- self.current_name = column.name
- if self.alter_metadata:
- self._result_column = column
- else:
- self._result_column = column.copy_fixed()
-
- table = property(_get_table, _set_table)
- result_column = property(_get_result_column, _set_result_column)
-
-
-class ChangesetTable(object):
- """Changeset extensions to SQLAlchemy tables."""
-
- def create_column(self, column, *p, **kw):
- """Creates a column.
-
- The column parameter may be a column definition or the name of
- a column in this table.
-
- API to :meth:`ChangesetColumn.create`
-
- :param column: Column to be created
- :type column: Column instance or string
- """
- if not isinstance(column, sqlalchemy.Column):
- # It's a column name
- column = getattr(self.c, str(column))
- column.create(table=self, *p, **kw)
-
- def drop_column(self, column, *p, **kw):
- """Drop a column, given its name or definition.
-
- API to :meth:`ChangesetColumn.drop`
-
- :param column: Column to be droped
- :type column: Column instance or string
- """
- if not isinstance(column, sqlalchemy.Column):
- # It's a column name
- try:
- column = getattr(self.c, str(column))
- except AttributeError:
- # That column isn't part of the table. We don't need
- # its entire definition to drop the column, just its
- # name, so create a dummy column with the same name.
- column = sqlalchemy.Column(str(column), sqlalchemy.Integer())
- column.drop(table=self, *p, **kw)
-
- def rename(self, name, connection=None, **kwargs):
- """Rename this table.
-
- :param name: New name of the table.
- :type name: string
- :param connection: reuse connection istead of creating new one.
- :type connection: :class:`sqlalchemy.engine.base.Connection` instance
- """
- engine = self.bind
- self.new_name = name
- visitorcallable = get_engine_visitor(engine, 'schemachanger')
- run_single_visitor(engine, visitorcallable, self, connection, **kwargs)
-
- # Fix metadata registration
- self.name = name
- self.deregister()
- self._set_parent(self.metadata)
-
- def _meta_key(self):
- """Get the meta key for this table."""
- return sqlalchemy.schema._get_table_key(self.name, self.schema)
-
- def deregister(self):
- """Remove this table from its metadata"""
- if SQLA_07:
- self.metadata._remove_table(self.name, self.schema)
- else:
- key = self._meta_key()
- meta = self.metadata
- if key in meta.tables:
- del meta.tables[key]
-
-
-class ChangesetColumn(object):
- """Changeset extensions to SQLAlchemy columns."""
-
- def alter(self, *p, **k):
- """Makes a call to :func:`alter_column` for the column this
- method is called on.
- """
- if 'table' not in k:
- k['table'] = self.table
- if 'engine' not in k:
- k['engine'] = k['table'].bind
- return alter_column(self, *p, **k)
-
- def create(self, table=None, index_name=None, unique_name=None,
- primary_key_name=None, populate_default=True, connection=None, **kwargs):
- """Create this column in the database.
-
- Assumes the given table exists. ``ALTER TABLE ADD COLUMN``,
- for most databases.
-
- :param table: Table instance to create on.
- :param index_name: Creates :class:`ChangesetIndex` on this column.
- :param unique_name: Creates :class:\
-`~migrate.changeset.constraint.UniqueConstraint` on this column.
- :param primary_key_name: Creates :class:\
-`~migrate.changeset.constraint.PrimaryKeyConstraint` on this column.
- :param populate_default: If True, created column will be \
-populated with defaults
- :param connection: reuse connection istead of creating new one.
- :type table: Table instance
- :type index_name: string
- :type unique_name: string
- :type primary_key_name: string
- :type populate_default: bool
- :type connection: :class:`sqlalchemy.engine.base.Connection` instance
-
- :returns: self
- """
- self.populate_default = populate_default
- self.index_name = index_name
- self.unique_name = unique_name
- self.primary_key_name = primary_key_name
- for cons in ('index_name', 'unique_name', 'primary_key_name'):
- self._check_sanity_constraints(cons)
-
- self.add_to_table(table)
- engine = self.table.bind
- visitorcallable = get_engine_visitor(engine, 'columngenerator')
- engine._run_visitor(visitorcallable, self, connection, **kwargs)
-
- # TODO: reuse existing connection
- if self.populate_default and self.default is not None:
- stmt = table.update().values({self: engine._execute_default(self.default)})
- engine.execute(stmt)
-
- return self
-
- def drop(self, table=None, connection=None, **kwargs):
- """Drop this column from the database, leaving its table intact.
-
- ``ALTER TABLE DROP COLUMN``, for most databases.
-
- :param connection: reuse connection istead of creating new one.
- :type connection: :class:`sqlalchemy.engine.base.Connection` instance
- """
- if table is not None:
- self.table = table
- engine = self.table.bind
- visitorcallable = get_engine_visitor(engine, 'columndropper')
- engine._run_visitor(visitorcallable, self, connection, **kwargs)
- self.remove_from_table(self.table, unset_table=False)
- self.table = None
- return self
-
- def add_to_table(self, table):
- if table is not None and self.table is None:
- if SQLA_07:
- table.append_column(self)
- else:
- self._set_parent(table)
-
- def _col_name_in_constraint(self,cons,name):
- return False
-
- def remove_from_table(self, table, unset_table=True):
- # TODO: remove primary keys, constraints, etc
- if unset_table:
- self.table = None
-
- to_drop = set()
- for index in table.indexes:
- columns = []
- for col in index.columns:
- if col.name!=self.name:
- columns.append(col)
- if columns:
- index.columns=columns
- else:
- to_drop.add(index)
- table.indexes = table.indexes - to_drop
-
- to_drop = set()
- for cons in table.constraints:
- # TODO: deal with other types of constraint
- if isinstance(cons,(ForeignKeyConstraint,
- UniqueConstraint)):
- for col_name in cons.columns:
- if not isinstance(col_name,basestring):
- col_name = col_name.name
- if self.name==col_name:
- to_drop.add(cons)
- table.constraints = table.constraints - to_drop
-
- if table.c.contains_column(self):
- if SQLA_07:
- table._columns.remove(self)
- else:
- table.c.remove(self)
-
- # TODO: this is fixed in 0.6
- def copy_fixed(self, **kw):
- """Create a copy of this ``Column``, with all attributes."""
- return sqlalchemy.Column(self.name, self.type, self.default,
- key=self.key,
- primary_key=self.primary_key,
- nullable=self.nullable,
- quote=self.quote,
- index=self.index,
- unique=self.unique,
- onupdate=self.onupdate,
- autoincrement=self.autoincrement,
- server_default=self.server_default,
- server_onupdate=self.server_onupdate,
- *[c.copy(**kw) for c in self.constraints])
-
- def _check_sanity_constraints(self, name):
- """Check if constraints names are correct"""
- obj = getattr(self, name)
- if (getattr(self, name[:-5]) and not obj):
- raise InvalidConstraintError("Column.create() accepts index_name,"
- " primary_key_name and unique_name to generate constraints")
- if not isinstance(obj, basestring) and obj is not None:
- raise InvalidConstraintError(
- "%s argument for column must be constraint name" % name)
-
-
-class ChangesetIndex(object):
- """Changeset extensions to SQLAlchemy Indexes."""
-
- __visit_name__ = 'index'
-
- def rename(self, name, connection=None, **kwargs):
- """Change the name of an index.
-
- :param name: New name of the Index.
- :type name: string
- :param connection: reuse connection istead of creating new one.
- :type connection: :class:`sqlalchemy.engine.base.Connection` instance
- """
- engine = self.table.bind
- self.new_name = name
- visitorcallable = get_engine_visitor(engine, 'schemachanger')
- engine._run_visitor(visitorcallable, self, connection, **kwargs)
- self.name = name
-
-
-class ChangesetDefaultClause(object):
- """Implements comparison between :class:`DefaultClause` instances"""
-
- def __eq__(self, other):
- if isinstance(other, self.__class__):
- if self.arg == other.arg:
- return True
-
- def __ne__(self, other):
- return not self.__eq__(other)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/exceptions.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/exceptions.py
deleted file mode 100755
index cb8c4094..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/exceptions.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""
- Provide exception classes for :mod:`migrate`
-"""
-
-
-class Error(Exception):
- """Error base class."""
-
-
-class ApiError(Error):
- """Base class for API errors."""
-
-
-class KnownError(ApiError):
- """A known error condition."""
-
-
-class UsageError(ApiError):
- """A known error condition where help should be displayed."""
-
-
-class ControlledSchemaError(Error):
- """Base class for controlled schema errors."""
-
-
-class InvalidVersionError(ControlledSchemaError):
- """Invalid version number."""
-
-
-class DatabaseNotControlledError(ControlledSchemaError):
- """Database should be under version control, but it's not."""
-
-
-class DatabaseAlreadyControlledError(ControlledSchemaError):
- """Database shouldn't be under version control, but it is"""
-
-
-class WrongRepositoryError(ControlledSchemaError):
- """This database is under version control by another repository."""
-
-
-class NoSuchTableError(ControlledSchemaError):
- """The table does not exist."""
-
-
-class PathError(Error):
- """Base class for path errors."""
-
-
-class PathNotFoundError(PathError):
- """A path with no file was required; found a file."""
-
-
-class PathFoundError(PathError):
- """A path with a file was required; found no file."""
-
-
-class RepositoryError(Error):
- """Base class for repository errors."""
-
-
-class InvalidRepositoryError(RepositoryError):
- """Invalid repository error."""
-
-
-class ScriptError(Error):
- """Base class for script errors."""
-
-
-class InvalidScriptError(ScriptError):
- """Invalid script error."""
-
-
-class InvalidVersionError(Error):
- """Invalid version error."""
-
-# migrate.changeset
-
-class NotSupportedError(Error):
- """Not supported error"""
-
-
-class InvalidConstraintError(Error):
- """Invalid constraint error"""
-
-class MigrateDeprecationWarning(DeprecationWarning):
- """Warning for deprecated features in Migrate"""
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/__init__.py
deleted file mode 100755
index 803323ee..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# make this package available during imports as long as we support <python2.5
-import sys
-import os
-sys.path.append(os.path.dirname(os.path.abspath(__file__)))
-
-
-from unittest import TestCase
-import migrate
-
-
-class TestVersionDefined(TestCase):
- def test_version(self):
- """Test for migrate.__version__"""
- self.assertTrue(isinstance(migrate.__version__, basestring))
- self.assertTrue(len(migrate.__version__) > 0)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_changeset.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_changeset.py
deleted file mode 100755
index e1166f43..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_changeset.py
+++ /dev/null
@@ -1,910 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import sqlalchemy
-import warnings
-
-from sqlalchemy import *
-
-from migrate import changeset, exceptions
-from migrate.changeset import *
-from migrate.changeset.schema import ColumnDelta
-from migrate.tests import fixture
-from migrate.tests.fixture.warnings import catch_warnings
-
-class TestAddDropColumn(fixture.DB):
- """Test add/drop column through all possible interfaces
- also test for constraints
- """
- level = fixture.DB.CONNECT
- table_name = 'tmp_adddropcol'
- table_int = 0
-
- def _setup(self, url):
- super(TestAddDropColumn, self)._setup(url)
- self.meta = MetaData()
- self.table = Table(self.table_name, self.meta,
- Column('id', Integer, unique=True),
- )
- self.meta.bind = self.engine
- if self.engine.has_table(self.table.name):
- self.table.drop()
- self.table.create()
-
- def _teardown(self):
- if self.engine.has_table(self.table.name):
- self.table.drop()
- self.meta.clear()
- super(TestAddDropColumn,self)._teardown()
-
- def run_(self, create_column_func, drop_column_func, *col_p, **col_k):
- col_name = 'data'
-
- def assert_numcols(num_of_expected_cols):
- # number of cols should be correct in table object and in database
- self.refresh_table(self.table_name)
- result = len(self.table.c)
-
- self.assertEquals(result, num_of_expected_cols),
- if col_k.get('primary_key', None):
- # new primary key: check its length too
- result = len(self.table.primary_key)
- self.assertEquals(result, num_of_expected_cols)
-
- # we have 1 columns and there is no data column
- assert_numcols(1)
- self.assertTrue(getattr(self.table.c, 'data', None) is None)
- if len(col_p) == 0:
- col_p = [String(40)]
- col = Column(col_name, *col_p, **col_k)
- create_column_func(col)
- assert_numcols(2)
- # data column exists
- self.assert_(self.table.c.data.type.length, 40)
-
- col2 = self.table.c.data
- drop_column_func(col2)
- assert_numcols(1)
-
- @fixture.usedb()
- def test_undefined(self):
- """Add/drop columns not yet defined in the table"""
- def add_func(col):
- return create_column(col, self.table)
- def drop_func(col):
- return drop_column(col, self.table)
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_defined(self):
- """Add/drop columns already defined in the table"""
- def add_func(col):
- self.meta.clear()
- self.table = Table(self.table_name, self.meta,
- Column('id', Integer, primary_key=True),
- col,
- )
- return create_column(col)
- def drop_func(col):
- return drop_column(col)
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_method_bound(self):
- """Add/drop columns via column methods; columns bound to a table
- ie. no table parameter passed to function
- """
- def add_func(col):
- self.assert_(col.table is None, col.table)
- self.table.append_column(col)
- return col.create()
- def drop_func(col):
- #self.assert_(col.table is None,col.table)
- #self.table.append_column(col)
- return col.drop()
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_method_notbound(self):
- """Add/drop columns via column methods; columns not bound to a table"""
- def add_func(col):
- return col.create(self.table)
- def drop_func(col):
- return col.drop(self.table)
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_tablemethod_obj(self):
- """Add/drop columns via table methods; by column object"""
- def add_func(col):
- return self.table.create_column(col)
- def drop_func(col):
- return self.table.drop_column(col)
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_tablemethod_name(self):
- """Add/drop columns via table methods; by column name"""
- def add_func(col):
- # must be bound to table
- self.table.append_column(col)
- return self.table.create_column(col.name)
- def drop_func(col):
- # Not necessarily bound to table
- return self.table.drop_column(col.name)
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_byname(self):
- """Add/drop columns via functions; by table object and column name"""
- def add_func(col):
- self.table.append_column(col)
- return create_column(col.name, self.table)
- def drop_func(col):
- return drop_column(col.name, self.table)
- return self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_drop_column_not_in_table(self):
- """Drop column by name"""
- def add_func(col):
- return self.table.create_column(col)
- def drop_func(col):
- if SQLA_07:
- self.table._columns.remove(col)
- else:
- self.table.c.remove(col)
- return self.table.drop_column(col.name)
- self.run_(add_func, drop_func)
-
- @fixture.usedb()
- def test_fk(self):
- """Can create columns with foreign keys"""
- # create FK's target
- reftable = Table('tmp_ref', self.meta,
- Column('id', Integer, primary_key=True),
- )
- if self.engine.has_table(reftable.name):
- reftable.drop()
- reftable.create()
-
- # create column with fk
- col = Column('data', Integer, ForeignKey(reftable.c.id))
- col.create(self.table)
-
- # check if constraint is added
- for cons in self.table.constraints:
- if isinstance(cons, sqlalchemy.schema.ForeignKeyConstraint):
- break
- else:
- self.fail('No constraint found')
-
- # TODO: test on db level if constraints work
-
- if SQLA_07:
- self.assertEqual(reftable.c.id.name,
- list(col.foreign_keys)[0].column.name)
- else:
- self.assertEqual(reftable.c.id.name,
- col.foreign_keys[0].column.name)
- col.drop(self.table)
-
- if self.engine.has_table(reftable.name):
- reftable.drop()
-
- @fixture.usedb(not_supported='sqlite')
- def test_pk(self):
- """Can create columns with primary key"""
- col = Column('data', Integer, nullable=False)
- self.assertRaises(exceptions.InvalidConstraintError,
- col.create, self.table, primary_key_name=True)
- col.create(self.table, primary_key_name='data_pkey')
-
- # check if constraint was added (cannot test on objects)
- self.table.insert(values={'data': 4}).execute()
- try:
- self.table.insert(values={'data': 4}).execute()
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
- else:
- self.fail()
-
- col.drop()
-
- @fixture.usedb(not_supported='mysql')
- def test_check(self):
- """Can create columns with check constraint"""
- col = Column('data',
- Integer,
- sqlalchemy.schema.CheckConstraint('data > 4'))
- col.create(self.table)
-
- # check if constraint was added (cannot test on objects)
- self.table.insert(values={'data': 5}).execute()
- try:
- self.table.insert(values={'data': 3}).execute()
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
- else:
- self.fail()
-
- col.drop()
-
- @fixture.usedb()
- def test_unique_constraint(self):
- self.assertRaises(exceptions.InvalidConstraintError,
- Column('data', Integer, unique=True).create, self.table)
-
- col = Column('data', Integer)
- col.create(self.table, unique_name='data_unique')
-
- # check if constraint was added (cannot test on objects)
- self.table.insert(values={'data': 5}).execute()
- try:
- self.table.insert(values={'data': 5}).execute()
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
- else:
- self.fail()
-
- col.drop(self.table)
-
-# TODO: remove already attached columns with indexes, uniques, pks, fks ..
-
- def _check_index(self,expected):
- if 'mysql' in self.engine.name or 'postgres' in self.engine.name:
- for index in tuple(
- Table(self.table.name, MetaData(),
- autoload=True, autoload_with=self.engine).indexes
- ):
- if index.name=='ix_data':
- break
- self.assertEqual(expected,index.unique)
-
- @fixture.usedb()
- def test_index(self):
- col = Column('data', Integer)
- col.create(self.table, index_name='ix_data')
-
- self._check_index(False)
-
- col.drop()
-
- @fixture.usedb()
- def test_index_unique(self):
- # shows how to create a unique index
- col = Column('data', Integer)
- col.create(self.table)
- Index('ix_data', col, unique=True).create(bind=self.engine)
-
- # check if index was added
- self.table.insert(values={'data': 5}).execute()
- try:
- self.table.insert(values={'data': 5}).execute()
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
- else:
- self.fail()
-
- self._check_index(True)
-
- col.drop()
-
- @fixture.usedb()
- def test_server_defaults(self):
- """Can create columns with server_default values"""
- col = Column('data', String(244), server_default='foobar')
- col.create(self.table)
-
- self.table.insert(values={'id': 10}).execute()
- row = self._select_row()
- self.assertEqual(u'foobar', row['data'])
-
- col.drop()
-
- @fixture.usedb()
- def test_populate_default(self):
- """Test populate_default=True"""
- def default():
- return 'foobar'
- col = Column('data', String(244), default=default)
- col.create(self.table, populate_default=True)
-
- self.table.insert(values={'id': 10}).execute()
- row = self._select_row()
- self.assertEqual(u'foobar', row['data'])
-
- col.drop()
-
- # TODO: test sequence
- # TODO: test quoting
- # TODO: test non-autoname constraints
-
- @fixture.usedb()
- def test_drop_doesnt_delete_other_indexes(self):
- # add two indexed columns
- self.table.drop()
- self.meta.clear()
- self.table = Table(
- self.table_name, self.meta,
- Column('id', Integer, primary_key=True),
- Column('d1', String(10), index=True),
- Column('d2', String(10), index=True),
- )
- self.table.create()
-
- # paranoid check
- self.refresh_table()
- self.assertEqual(
- sorted([i.name for i in self.table.indexes]),
- [u'ix_tmp_adddropcol_d1', u'ix_tmp_adddropcol_d2']
- )
-
- # delete one
- self.table.c.d2.drop()
-
- # ensure the other index is still there
- self.refresh_table()
- self.assertEqual(
- sorted([i.name for i in self.table.indexes]),
- [u'ix_tmp_adddropcol_d1']
- )
-
- def _actual_foreign_keys(self):
- from sqlalchemy.schema import ForeignKeyConstraint
- result = []
- for cons in self.table.constraints:
- if isinstance(cons,ForeignKeyConstraint):
- col_names = []
- for col_name in cons.columns:
- if not isinstance(col_name,basestring):
- col_name = col_name.name
- col_names.append(col_name)
- result.append(col_names)
- result.sort()
- return result
-
- @fixture.usedb()
- def test_drop_with_foreign_keys(self):
- self.table.drop()
- self.meta.clear()
-
- # create FK's target
- reftable = Table('tmp_ref', self.meta,
- Column('id', Integer, primary_key=True),
- )
- if self.engine.has_table(reftable.name):
- reftable.drop()
- reftable.create()
-
- # add a table with two foreign key columns
- self.table = Table(
- self.table_name, self.meta,
- Column('id', Integer, primary_key=True),
- Column('r1', Integer, ForeignKey('tmp_ref.id')),
- Column('r2', Integer, ForeignKey('tmp_ref.id')),
- )
- self.table.create()
-
- # paranoid check
- self.assertEqual([['r1'],['r2']],
- self._actual_foreign_keys())
-
- # delete one
- self.table.c.r2.drop()
-
- # check remaining foreign key is there
- self.assertEqual([['r1']],
- self._actual_foreign_keys())
-
- @fixture.usedb()
- def test_drop_with_complex_foreign_keys(self):
- from sqlalchemy.schema import ForeignKeyConstraint
- from sqlalchemy.schema import UniqueConstraint
-
- self.table.drop()
- self.meta.clear()
-
- # create FK's target
- reftable = Table('tmp_ref', self.meta,
- Column('id', Integer, primary_key=True),
- Column('jd', Integer),
- UniqueConstraint('id','jd')
- )
- if self.engine.has_table(reftable.name):
- reftable.drop()
- reftable.create()
-
- # add a table with a complex foreign key constraint
- self.table = Table(
- self.table_name, self.meta,
- Column('id', Integer, primary_key=True),
- Column('r1', Integer),
- Column('r2', Integer),
- ForeignKeyConstraint(['r1','r2'],
- [reftable.c.id,reftable.c.jd],
- name='test_fk')
- )
- self.table.create()
-
- # paranoid check
- self.assertEqual([['r1','r2']],
- self._actual_foreign_keys())
-
- # delete one
- self.table.c.r2.drop()
-
- # check the constraint is gone, since part of it
- # is no longer there - if people hit this,
- # they may be confused, maybe we should raise an error
- # and insist that the constraint is deleted first, separately?
- self.assertEqual([],
- self._actual_foreign_keys())
-
-class TestRename(fixture.DB):
- """Tests for table and index rename methods"""
- level = fixture.DB.CONNECT
- meta = MetaData()
-
- def _setup(self, url):
- super(TestRename, self)._setup(url)
- self.meta.bind = self.engine
-
- @fixture.usedb(not_supported='firebird')
- def test_rename_table(self):
- """Tables can be renamed"""
- c_name = 'col_1'
- table_name1 = 'name_one'
- table_name2 = 'name_two'
- index_name1 = 'x' + table_name1
- index_name2 = 'x' + table_name2
-
- self.meta.clear()
- self.column = Column(c_name, Integer)
- self.table = Table(table_name1, self.meta, self.column)
- self.index = Index(index_name1, self.column, unique=False)
-
- if self.engine.has_table(self.table.name):
- self.table.drop()
- if self.engine.has_table(table_name2):
- tmp = Table(table_name2, self.meta, autoload=True)
- tmp.drop()
- tmp.deregister()
- del tmp
- self.table.create()
-
- def assert_table_name(expected, skip_object_check=False):
- """Refresh a table via autoload
- SA has changed some since this test was written; we now need to do
- meta.clear() upon reloading a table - clear all rather than a
- select few. So, this works only if we're working with one table at
- a time (else, others will vanish too).
- """
- if not skip_object_check:
- # Table object check
- self.assertEquals(self.table.name,expected)
- newname = self.table.name
- else:
- # we know the object's name isn't consistent: just assign it
- newname = expected
- # Table DB check
- self.meta.clear()
- self.table = Table(newname, self.meta, autoload=True)
- self.assertEquals(self.table.name, expected)
-
- def assert_index_name(expected, skip_object_check=False):
- if not skip_object_check:
- # Index object check
- self.assertEquals(self.index.name, expected)
- else:
- # object is inconsistent
- self.index.name = expected
- # TODO: Index DB check
-
- def add_table_to_meta(name):
- # trigger the case where table_name2 needs to be
- # removed from the metadata in ChangesetTable.deregister()
- tmp = Table(name, self.meta, Column(c_name, Integer))
- tmp.create()
- tmp.drop()
-
- try:
- # Table renames
- assert_table_name(table_name1)
- add_table_to_meta(table_name2)
- rename_table(self.table, table_name2)
- assert_table_name(table_name2)
- self.table.rename(table_name1)
- assert_table_name(table_name1)
-
- # test by just the string
- rename_table(table_name1, table_name2, engine=self.engine)
- assert_table_name(table_name2, True) # object not updated
-
- # Index renames
- if self.url.startswith('sqlite') or self.url.startswith('mysql'):
- self.assertRaises(exceptions.NotSupportedError,
- self.index.rename, index_name2)
- else:
- assert_index_name(index_name1)
- rename_index(self.index, index_name2, engine=self.engine)
- assert_index_name(index_name2)
- self.index.rename(index_name1)
- assert_index_name(index_name1)
-
- # test by just the string
- rename_index(index_name1, index_name2, engine=self.engine)
- assert_index_name(index_name2, True)
-
- finally:
- if self.table.exists():
- self.table.drop()
-
-
-class TestColumnChange(fixture.DB):
- level = fixture.DB.CONNECT
- table_name = 'tmp_colchange'
-
- def _setup(self, url):
- super(TestColumnChange, self)._setup(url)
- self.meta = MetaData(self.engine)
- self.table = Table(self.table_name, self.meta,
- Column('id', Integer, primary_key=True),
- Column('data', String(40), server_default=DefaultClause("tluafed"),
- nullable=True),
- )
- if self.table.exists():
- self.table.drop()
- try:
- self.table.create()
- except sqlalchemy.exceptions.SQLError, e:
- # SQLite: database schema has changed
- if not self.url.startswith('sqlite://'):
- raise
-
- def _teardown(self):
- if self.table.exists():
- try:
- self.table.drop(self.engine)
- except sqlalchemy.exceptions.SQLError,e:
- # SQLite: database schema has changed
- if not self.url.startswith('sqlite://'):
- raise
- super(TestColumnChange, self)._teardown()
-
- @fixture.usedb()
- def test_rename(self):
- """Can rename a column"""
- def num_rows(col, content):
- return len(list(self.table.select(col == content).execute()))
- # Table content should be preserved in changed columns
- content = "fgsfds"
- self.engine.execute(self.table.insert(), data=content, id=42)
- self.assertEquals(num_rows(self.table.c.data, content), 1)
-
- # ...as a function, given a column object and the new name
- alter_column('data', name='data2', table=self.table)
- self.refresh_table()
- alter_column(self.table.c.data2, name='atad')
- self.refresh_table(self.table.name)
- self.assert_('data' not in self.table.c.keys())
- self.assert_('atad' in self.table.c.keys())
- self.assertEquals(num_rows(self.table.c.atad, content), 1)
-
- # ...as a method, given a new name
- self.table.c.atad.alter(name='data')
- self.refresh_table(self.table.name)
- self.assert_('atad' not in self.table.c.keys())
- self.table.c.data # Should not raise exception
- self.assertEquals(num_rows(self.table.c.data, content), 1)
-
- # ...as a function, given a new object
- alter_column(self.table.c.data,
- name = 'atad', type=String(40),
- server_default=self.table.c.data.server_default)
- self.refresh_table(self.table.name)
- self.assert_('data' not in self.table.c.keys())
- self.table.c.atad # Should not raise exception
- self.assertEquals(num_rows(self.table.c.atad, content), 1)
-
- # ...as a method, given a new object
- self.table.c.atad.alter(
- name='data',type=String(40),
- server_default=self.table.c.atad.server_default
- )
- self.refresh_table(self.table.name)
- self.assert_('atad' not in self.table.c.keys())
- self.table.c.data # Should not raise exception
- self.assertEquals(num_rows(self.table.c.data,content), 1)
-
- @fixture.usedb()
- def test_type(self):
- # Test we can change a column's type
-
- # Just the new type
- self.table.c.data.alter(type=String(43))
- self.refresh_table(self.table.name)
- self.assert_(isinstance(self.table.c.data.type, String))
- self.assertEquals(self.table.c.data.type.length, 43)
-
- # Different type
- self.assert_(isinstance(self.table.c.id.type, Integer))
- self.assertEquals(self.table.c.id.nullable, False)
-
- if not self.engine.name == 'firebird':
- self.table.c.id.alter(type=String(20))
- self.assertEquals(self.table.c.id.nullable, False)
- self.refresh_table(self.table.name)
- self.assert_(isinstance(self.table.c.id.type, String))
-
- @fixture.usedb()
- def test_default(self):
- """Can change a column's server_default value (DefaultClauses only)
- Only DefaultClauses are changed here: others are managed by the
- application / by SA
- """
- self.assertEquals(self.table.c.data.server_default.arg, 'tluafed')
-
- # Just the new default
- default = 'my_default'
- self.table.c.data.alter(server_default=DefaultClause(default))
- self.refresh_table(self.table.name)
- #self.assertEquals(self.table.c.data.server_default.arg,default)
- # TextClause returned by autoload
- self.assert_(default in str(self.table.c.data.server_default.arg))
- self.engine.execute(self.table.insert(), id=12)
- row = self._select_row()
- self.assertEqual(row['data'], default)
-
- # Column object
- default = 'your_default'
- self.table.c.data.alter(type=String(40), server_default=DefaultClause(default))
- self.refresh_table(self.table.name)
- self.assert_(default in str(self.table.c.data.server_default.arg))
-
- # Drop/remove default
- self.table.c.data.alter(server_default=None)
- self.assertEqual(self.table.c.data.server_default, None)
-
- self.refresh_table(self.table.name)
- # server_default isn't necessarily None for Oracle
- #self.assert_(self.table.c.data.server_default is None,self.table.c.data.server_default)
- self.engine.execute(self.table.insert(), id=11)
- row = self.table.select(self.table.c.id == 11).execution_options(autocommit=True).execute().fetchone()
- self.assert_(row['data'] is None, row['data'])
-
- @fixture.usedb(not_supported='firebird')
- def test_null(self):
- """Can change a column's null constraint"""
- self.assertEquals(self.table.c.data.nullable, True)
-
- # Full column
- self.table.c.data.alter(type=String(40), nullable=False)
- self.table.nullable = None
- self.refresh_table(self.table.name)
- self.assertEquals(self.table.c.data.nullable, False)
-
- # Just the new status
- self.table.c.data.alter(nullable=True)
- self.refresh_table(self.table.name)
- self.assertEquals(self.table.c.data.nullable, True)
-
- @fixture.usedb()
- def test_alter_deprecated(self):
- try:
- # py 2.4 compatability :-/
- cw = catch_warnings(record=True)
- w = cw.__enter__()
-
- warnings.simplefilter("always")
- self.table.c.data.alter(Column('data', String(100)))
-
- self.assertEqual(len(w),1)
- self.assertTrue(issubclass(w[-1].category,
- MigrateDeprecationWarning))
- self.assertEqual(
- 'Passing a Column object to alter_column is deprecated. '
- 'Just pass in keyword parameters instead.',
- str(w[-1].message))
- finally:
- cw.__exit__()
-
- @fixture.usedb()
- def test_alter_returns_delta(self):
- """Test if alter constructs return delta"""
-
- delta = self.table.c.data.alter(type=String(100))
- self.assert_('type' in delta)
-
- @fixture.usedb()
- def test_alter_all(self):
- """Tests all alter changes at one time"""
- # test for each db separately
- # since currently some dont support everything
-
- # test pre settings
- self.assertEqual(self.table.c.data.nullable, True)
- self.assertEqual(self.table.c.data.server_default.arg, 'tluafed')
- self.assertEqual(self.table.c.data.name, 'data')
- self.assertTrue(isinstance(self.table.c.data.type, String))
- self.assertTrue(self.table.c.data.type.length, 40)
-
- kw = dict(nullable=False,
- server_default='foobar',
- name='data_new',
- type=String(50))
- if self.engine.name == 'firebird':
- del kw['nullable']
- self.table.c.data.alter(**kw)
-
- # test altered objects
- self.assertEqual(self.table.c.data.server_default.arg, 'foobar')
- if not self.engine.name == 'firebird':
- self.assertEqual(self.table.c.data.nullable, False)
- self.assertEqual(self.table.c.data.name, 'data_new')
- self.assertEqual(self.table.c.data.type.length, 50)
-
- self.refresh_table(self.table.name)
-
- # test post settings
- if not self.engine.name == 'firebird':
- self.assertEqual(self.table.c.data_new.nullable, False)
- self.assertEqual(self.table.c.data_new.name, 'data_new')
- self.assertTrue(isinstance(self.table.c.data_new.type, String))
- self.assertTrue(self.table.c.data_new.type.length, 50)
-
- # insert data and assert default
- self.table.insert(values={'id': 10}).execute()
- row = self._select_row()
- self.assertEqual(u'foobar', row['data_new'])
-
-
-class TestColumnDelta(fixture.DB):
- """Tests ColumnDelta class"""
-
- level = fixture.DB.CONNECT
- table_name = 'tmp_coldelta'
- table_int = 0
-
- def _setup(self, url):
- super(TestColumnDelta, self)._setup(url)
- self.meta = MetaData()
- self.table = Table(self.table_name, self.meta,
- Column('ids', String(10)),
- )
- self.meta.bind = self.engine
- if self.engine.has_table(self.table.name):
- self.table.drop()
- self.table.create()
-
- def _teardown(self):
- if self.engine.has_table(self.table.name):
- self.table.drop()
- self.meta.clear()
- super(TestColumnDelta,self)._teardown()
-
- def mkcol(self, name='id', type=String, *p, **k):
- return Column(name, type, *p, **k)
-
- def verify(self, expected, original, *p, **k):
- self.delta = ColumnDelta(original, *p, **k)
- result = self.delta.keys()
- result.sort()
- self.assertEquals(expected, result)
- return self.delta
-
- def test_deltas_two_columns(self):
- """Testing ColumnDelta with two columns"""
- col_orig = self.mkcol(primary_key=True)
- col_new = self.mkcol(name='ids', primary_key=True)
- self.verify([], col_orig, col_orig)
- self.verify(['name'], col_orig, col_orig, 'ids')
- self.verify(['name'], col_orig, col_orig, name='ids')
- self.verify(['name'], col_orig, col_new)
- self.verify(['name', 'type'], col_orig, col_new, type=String)
-
- # Type comparisons
- self.verify([], self.mkcol(type=String), self.mkcol(type=String))
- self.verify(['type'], self.mkcol(type=String), self.mkcol(type=Integer))
- self.verify(['type'], self.mkcol(type=String), self.mkcol(type=String(42)))
- self.verify([], self.mkcol(type=String(42)), self.mkcol(type=String(42)))
- self.verify(['type'], self.mkcol(type=String(24)), self.mkcol(type=String(42)))
- self.verify(['type'], self.mkcol(type=String(24)), self.mkcol(type=Text(24)))
-
- # Other comparisons
- self.verify(['primary_key'], self.mkcol(nullable=False), self.mkcol(primary_key=True))
-
- # PK implies nullable=False
- self.verify(['nullable', 'primary_key'], self.mkcol(nullable=True), self.mkcol(primary_key=True))
- self.verify([], self.mkcol(primary_key=True), self.mkcol(primary_key=True))
- self.verify(['nullable'], self.mkcol(nullable=True), self.mkcol(nullable=False))
- self.verify([], self.mkcol(nullable=True), self.mkcol(nullable=True))
- self.verify([], self.mkcol(server_default=None), self.mkcol(server_default=None))
- self.verify([], self.mkcol(server_default='42'), self.mkcol(server_default='42'))
-
- # test server default
- delta = self.verify(['server_default'], self.mkcol(), self.mkcol('id', String, DefaultClause('foobar')))
- self.assertEqual(delta['server_default'].arg, 'foobar')
-
- self.verify([], self.mkcol(server_default='foobar'), self.mkcol('id', String, DefaultClause('foobar')))
- self.verify(['type'], self.mkcol(server_default='foobar'), self.mkcol('id', Text, DefaultClause('foobar')))
-
- col = self.mkcol(server_default='foobar')
- self.verify(['type'], col, self.mkcol('id', Text, DefaultClause('foobar')), alter_metadata=True)
- self.assert_(isinstance(col.type, Text))
-
- col = self.mkcol()
- self.verify(['name', 'server_default', 'type'], col, self.mkcol('beep', Text, DefaultClause('foobar')),
- alter_metadata=True)
- self.assert_(isinstance(col.type, Text))
- self.assertEqual(col.name, 'beep')
- self.assertEqual(col.server_default.arg, 'foobar')
-
- @fixture.usedb()
- def test_deltas_zero_columns(self):
- """Testing ColumnDelta with zero columns"""
-
- self.verify(['name'], 'ids', table=self.table, name='hey')
-
- # test reflection
- self.verify(['type'], 'ids', table=self.table.name, type=String(80), engine=self.engine)
- self.verify(['type'], 'ids', table=self.table.name, type=String(80), metadata=self.meta)
-
- self.meta.clear()
- delta = self.verify(['type'], 'ids', table=self.table.name, type=String(80), metadata=self.meta,
- alter_metadata=True)
- self.assert_(self.table.name in self.meta)
- self.assertEqual(delta.result_column.type.length, 80)
- self.assertEqual(self.meta.tables.get(self.table.name).c.ids.type.length, 80)
-
- # test defaults
- self.meta.clear()
- self.verify(['server_default'], 'ids', table=self.table.name, server_default='foobar',
- metadata=self.meta,
- alter_metadata=True)
- self.meta.tables.get(self.table.name).c.ids.server_default.arg == 'foobar'
-
- # test missing parameters
- self.assertRaises(ValueError, ColumnDelta, table=self.table.name)
- self.assertRaises(ValueError, ColumnDelta, 'ids', table=self.table.name, alter_metadata=True)
- self.assertRaises(ValueError, ColumnDelta, 'ids', table=self.table.name, alter_metadata=False)
-
- def test_deltas_one_column(self):
- """Testing ColumnDelta with one column"""
- col_orig = self.mkcol(primary_key=True)
-
- self.verify([], col_orig)
- self.verify(['name'], col_orig, 'ids')
- # Parameters are always executed, even if they're 'unchanged'
- # (We can't assume given column is up-to-date)
- self.verify(['name', 'primary_key', 'type'], col_orig, 'id', Integer, primary_key=True)
- self.verify(['name', 'primary_key', 'type'], col_orig, name='id', type=Integer, primary_key=True)
-
- # Change name, given an up-to-date definition and the current name
- delta = self.verify(['name'], col_orig, name='blah')
- self.assertEquals(delta.get('name'), 'blah')
- self.assertEquals(delta.current_name, 'id')
-
- col_orig = self.mkcol(primary_key=True)
- self.verify(['name', 'type'], col_orig, name='id12', type=Text, alter_metadata=True)
- self.assert_(isinstance(col_orig.type, Text))
- self.assertEqual(col_orig.name, 'id12')
-
- # test server default
- col_orig = self.mkcol(primary_key=True)
- delta = self.verify(['server_default'], col_orig, DefaultClause('foobar'))
- self.assertEqual(delta['server_default'].arg, 'foobar')
-
- delta = self.verify(['server_default'], col_orig, server_default=DefaultClause('foobar'))
- self.assertEqual(delta['server_default'].arg, 'foobar')
-
- # no change
- col_orig = self.mkcol(server_default=DefaultClause('foobar'))
- delta = self.verify(['type'], col_orig, DefaultClause('foobar'), type=PickleType)
- self.assert_(isinstance(delta.result_column.type, PickleType))
-
- # TODO: test server on update
- # TODO: test bind metadata
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_constraint.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_constraint.py
deleted file mode 100755
index f36698d0..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/changeset/test_constraint.py
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from sqlalchemy import *
-from sqlalchemy.util import *
-from sqlalchemy.exc import *
-
-from migrate.exceptions import *
-from migrate.changeset import *
-
-from migrate.tests import fixture
-
-
-class CommonTestConstraint(fixture.DB):
- """helper functions to test constraints.
-
- we just create a fresh new table and make sure everything is
- as required.
- """
-
- def _setup(self, url):
- super(CommonTestConstraint, self)._setup(url)
- self._create_table()
-
- def _teardown(self):
- if hasattr(self, 'table') and self.engine.has_table(self.table.name):
- self.table.drop()
- super(CommonTestConstraint, self)._teardown()
-
- def _create_table(self):
- self._connect(self.url)
- self.meta = MetaData(self.engine)
- self.tablename = 'mytable'
- self.table = Table(self.tablename, self.meta,
- Column(u'id', Integer, nullable=False),
- Column(u'fkey', Integer, nullable=False),
- mysql_engine='InnoDB')
- if self.engine.has_table(self.table.name):
- self.table.drop()
- self.table.create()
-
- # make sure we start at zero
- self.assertEquals(len(self.table.primary_key), 0)
- self.assert_(isinstance(self.table.primary_key,
- schema.PrimaryKeyConstraint), self.table.primary_key.__class__)
-
-
-class TestConstraint(CommonTestConstraint):
- level = fixture.DB.CONNECT
-
- def _define_pk(self, *cols):
- # Add a pk by creating a PK constraint
- if (self.engine.name in ('oracle', 'firebird')):
- # Can't drop Oracle PKs without an explicit name
- pk = PrimaryKeyConstraint(table=self.table, name='temp_pk_key', *cols)
- else:
- pk = PrimaryKeyConstraint(table=self.table, *cols)
- self.compare_columns_equal(pk.columns, cols)
- pk.create()
- self.refresh_table()
- if not self.url.startswith('sqlite'):
- self.compare_columns_equal(self.table.primary_key, cols, ['type', 'autoincrement'])
-
- # Drop the PK constraint
- #if (self.engine.name in ('oracle', 'firebird')):
- # # Apparently Oracle PK names aren't introspected
- # pk.name = self.table.primary_key.name
- pk.drop()
- self.refresh_table()
- self.assertEquals(len(self.table.primary_key), 0)
- self.assert_(isinstance(self.table.primary_key, schema.PrimaryKeyConstraint))
- return pk
-
- @fixture.usedb(not_supported='sqlite')
- def test_define_fk(self):
- """FK constraints can be defined, created, and dropped"""
- # FK target must be unique
- pk = PrimaryKeyConstraint(self.table.c.id, table=self.table, name="pkid")
- pk.create()
-
- # Add a FK by creating a FK constraint
- if SQLA_07:
- self.assertEquals(list(self.table.c.fkey.foreign_keys), [])
- else:
- self.assertEquals(self.table.c.fkey.foreign_keys._list, [])
- fk = ForeignKeyConstraint([self.table.c.fkey],
- [self.table.c.id],
- name="fk_id_fkey",
- ondelete="CASCADE")
- if SQLA_07:
- self.assert_(list(self.table.c.fkey.foreign_keys) is not [])
- else:
- self.assert_(self.table.c.fkey.foreign_keys._list is not [])
- for key in fk.columns:
- self.assertEquals(key, self.table.c.fkey.name)
- self.assertEquals([e.column for e in fk.elements], [self.table.c.id])
- self.assertEquals(list(fk.referenced), [self.table.c.id])
-
- if self.url.startswith('mysql'):
- # MySQL FKs need an index
- index = Index('index_name', self.table.c.fkey)
- index.create()
- fk.create()
-
- # test for ondelete/onupdate
- if SQLA_07:
- fkey = list(self.table.c.fkey.foreign_keys)[0]
- else:
- fkey = self.table.c.fkey.foreign_keys._list[0]
- self.assertEquals(fkey.ondelete, "CASCADE")
- # TODO: test on real db if it was set
-
- self.refresh_table()
- if SQLA_07:
- self.assert_(list(self.table.c.fkey.foreign_keys) is not [])
- else:
- self.assert_(self.table.c.fkey.foreign_keys._list is not [])
-
- fk.drop()
- self.refresh_table()
- if SQLA_07:
- self.assertEquals(list(self.table.c.fkey.foreign_keys), [])
- else:
- self.assertEquals(self.table.c.fkey.foreign_keys._list, [])
-
- @fixture.usedb()
- def test_define_pk(self):
- """PK constraints can be defined, created, and dropped"""
- self._define_pk(self.table.c.fkey)
-
- @fixture.usedb()
- def test_define_pk_multi(self):
- """Multicolumn PK constraints can be defined, created, and dropped"""
- self._define_pk(self.table.c.id, self.table.c.fkey)
-
- @fixture.usedb(not_supported=['firebird'])
- def test_drop_cascade(self):
- """Drop constraint cascaded"""
- pk = PrimaryKeyConstraint('fkey', table=self.table, name="id_pkey")
- pk.create()
- self.refresh_table()
-
- # Drop the PK constraint forcing cascade
- pk.drop(cascade=True)
-
- # TODO: add real assertion if it was added
-
- @fixture.usedb(supported=['mysql'])
- def test_fail_mysql_check_constraints(self):
- """Check constraints raise NotSupported for mysql on drop"""
- cons = CheckConstraint('id > 3', name="id_check", table=self.table)
- cons.create()
- self.refresh_table()
-
- try:
- cons.drop()
- except NotSupportedError:
- pass
- else:
- self.fail()
-
- @fixture.usedb(not_supported=['sqlite', 'mysql'])
- def test_named_check_constraints(self):
- """Check constraints can be defined, created, and dropped"""
- self.assertRaises(InvalidConstraintError, CheckConstraint, 'id > 3')
- cons = CheckConstraint('id > 3', name="id_check", table=self.table)
- cons.create()
- self.refresh_table()
-
- self.table.insert(values={'id': 4, 'fkey': 1}).execute()
- try:
- self.table.insert(values={'id': 1, 'fkey': 1}).execute()
- except (IntegrityError, ProgrammingError):
- pass
- else:
- self.fail()
-
- # Remove the name, drop the constraint; it should succeed
- cons.drop()
- self.refresh_table()
- self.table.insert(values={'id': 2, 'fkey': 2}).execute()
- self.table.insert(values={'id': 1, 'fkey': 2}).execute()
-
-
-class TestAutoname(CommonTestConstraint):
- """Every method tests for a type of constraint wether it can autoname
- itself and if you can pass object instance and names to classes.
- """
- level = fixture.DB.CONNECT
-
- @fixture.usedb(not_supported=['oracle', 'firebird'])
- def test_autoname_pk(self):
- """PrimaryKeyConstraints can guess their name if None is given"""
- # Don't supply a name; it should create one
- cons = PrimaryKeyConstraint(self.table.c.id)
- cons.create()
- self.refresh_table()
- if not self.url.startswith('sqlite'):
- # TODO: test for index for sqlite
- self.compare_columns_equal(cons.columns, self.table.primary_key, ['autoincrement', 'type'])
-
- # Remove the name, drop the constraint; it should succeed
- cons.name = None
- cons.drop()
- self.refresh_table()
- self.assertEquals(list(), list(self.table.primary_key))
-
- # test string names
- cons = PrimaryKeyConstraint('id', table=self.table)
- cons.create()
- self.refresh_table()
- if not self.url.startswith('sqlite'):
- # TODO: test for index for sqlite
- self.compare_columns_equal(cons.columns, self.table.primary_key)
- cons.name = None
- cons.drop()
-
- @fixture.usedb(not_supported=['oracle', 'sqlite', 'firebird'])
- def test_autoname_fk(self):
- """ForeignKeyConstraints can guess their name if None is given"""
- cons = PrimaryKeyConstraint(self.table.c.id)
- cons.create()
-
- cons = ForeignKeyConstraint([self.table.c.fkey], [self.table.c.id])
- cons.create()
- self.refresh_table()
- if SQLA_07:
- list(self.table.c.fkey.foreign_keys)[0].column is self.table.c.id
- else:
- self.table.c.fkey.foreign_keys[0].column is self.table.c.id
-
- # Remove the name, drop the constraint; it should succeed
- cons.name = None
- cons.drop()
- self.refresh_table()
- if SQLA_07:
- self.assertEquals(list(self.table.c.fkey.foreign_keys), list())
- else:
- self.assertEquals(self.table.c.fkey.foreign_keys._list, list())
-
- # test string names
- cons = ForeignKeyConstraint(['fkey'], ['%s.id' % self.tablename], table=self.table)
- cons.create()
- self.refresh_table()
- if SQLA_07:
- list(self.table.c.fkey.foreign_keys)[0].column is self.table.c.id
- else:
- self.table.c.fkey.foreign_keys[0].column is self.table.c.id
-
- # Remove the name, drop the constraint; it should succeed
- cons.name = None
- cons.drop()
-
- @fixture.usedb(not_supported=['oracle', 'sqlite', 'mysql'])
- def test_autoname_check(self):
- """CheckConstraints can guess their name if None is given"""
- cons = CheckConstraint('id > 3', columns=[self.table.c.id])
- cons.create()
- self.refresh_table()
-
- if not self.engine.name == 'mysql':
- self.table.insert(values={'id': 4, 'fkey': 1}).execute()
- try:
- self.table.insert(values={'id': 1, 'fkey': 2}).execute()
- except (IntegrityError, ProgrammingError):
- pass
- else:
- self.fail()
-
- # Remove the name, drop the constraint; it should succeed
- cons.name = None
- cons.drop()
- self.refresh_table()
- self.table.insert(values={'id': 2, 'fkey': 2}).execute()
- self.table.insert(values={'id': 1, 'fkey': 3}).execute()
-
- @fixture.usedb(not_supported=['oracle', 'sqlite'])
- def test_autoname_unique(self):
- """UniqueConstraints can guess their name if None is given"""
- cons = UniqueConstraint(self.table.c.fkey)
- cons.create()
- self.refresh_table()
-
- self.table.insert(values={'fkey': 4, 'id': 1}).execute()
- try:
- self.table.insert(values={'fkey': 4, 'id': 2}).execute()
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
- else:
- self.fail()
-
- # Remove the name, drop the constraint; it should succeed
- cons.name = None
- cons.drop()
- self.refresh_table()
- self.table.insert(values={'fkey': 4, 'id': 2}).execute()
- self.table.insert(values={'fkey': 4, 'id': 1}).execute()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/__init__.py
deleted file mode 100755
index 09fc2caa..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import unittest2
-
-def main(imports=None):
- if imports:
- global suite
- suite = suite(imports)
- defaultTest='fixture.suite'
- else:
- defaultTest=None
- return unittest2.TestProgram(defaultTest=defaultTest)
-
-from base import Base
-from migrate.tests.fixture.pathed import Pathed
-from shell import Shell
-from database import DB,usedb
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/base.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/base.py
deleted file mode 100755
index 67aabf8c..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/base.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-import unittest2
-
-class Base(unittest2.TestCase):
-
- def setup_method(self,func=None):
- self.setUp()
-
- def teardown_method(self,func=None):
- self.tearDown()
-
- def assertEqualsIgnoreWhitespace(self, v1, v2):
- """Compares two strings that should be\
- identical except for whitespace
- """
- def strip_whitespace(s):
- return re.sub(r'\s', '', s)
-
- line1 = strip_whitespace(v1)
- line2 = strip_whitespace(v2)
-
- self.assertEqual(line1, line2, "%s != %s" % (v1, v2))
-
- def ignoreErrors(self, func, *p,**k):
- """Call a function, ignoring any exceptions"""
- try:
- func(*p,**k)
- except:
- pass
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/database.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/database.py
deleted file mode 100755
index e6e410a6..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/database.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import logging
-from decorator import decorator
-
-from sqlalchemy import create_engine, Table, MetaData
-from sqlalchemy.orm import create_session
-from sqlalchemy.pool import StaticPool
-
-from migrate.changeset.schema import ColumnDelta
-from migrate.versioning.util import Memoize
-
-from migrate.tests.fixture.base import Base
-from migrate.tests.fixture.pathed import Pathed
-
-
-log = logging.getLogger(__name__)
-
-@Memoize
-def readurls():
- """read URLs from config file return a list"""
- # TODO: remove tmpfile since sqlite can store db in memory
- filename = 'test_db.cfg'
- ret = list()
- tmpfile = Pathed.tmp()
- fullpath = os.path.join(os.curdir, filename)
-
- try:
- fd = open(fullpath)
- except IOError:
- raise IOError("""You must specify the databases to use for testing!
-Copy %(filename)s.tmpl to %(filename)s and edit your database URLs.""" % locals())
-
- for line in fd:
- if line.startswith('#'):
- continue
- line = line.replace('__tmp__', tmpfile).strip()
- ret.append(line)
- fd.close()
- return ret
-
-def is_supported(url, supported, not_supported):
- db = url.split(':', 1)[0]
-
- if supported is not None:
- if isinstance(supported, basestring):
- return supported == db
- else:
- return db in supported
- elif not_supported is not None:
- if isinstance(not_supported, basestring):
- return not_supported != db
- else:
- return not (db in not_supported)
- return True
-
-
-def usedb(supported=None, not_supported=None):
- """Decorates tests to be run with a database connection
- These tests are run once for each available database
-
- @param supported: run tests for ONLY these databases
- @param not_supported: run tests for all databases EXCEPT these
-
- If both supported and not_supported are empty, all dbs are assumed
- to be supported
- """
- if supported is not None and not_supported is not None:
- raise AssertionError("Can't specify both supported and not_supported in fixture.db()")
-
- urls = readurls()
- my_urls = [url for url in urls if is_supported(url, supported, not_supported)]
-
- @decorator
- def dec(f, self, *a, **kw):
- failed_for = []
- fail = False
- for url in my_urls:
- try:
- log.debug("Running test with engine %s", url)
- try:
- try:
- self._setup(url)
- except Exception,e:
- setup_exception=e
- else:
- setup_exception=None
- f(self, *a, **kw)
- finally:
- try:
- self._teardown()
- except Exception,e:
- teardown_exception=e
- else:
- teardown_exception=None
- if setup_exception or teardown_exception:
- raise RuntimeError((
- 'Exception during _setup/_teardown:\n'
- 'setup: %r\n'
- 'teardown: %r\n'
- )%(setup_exception,teardown_exception))
- except Exception,e:
- failed_for.append(url)
- fail = True
- for url in failed_for:
- log.error('Failed for %s', url)
- if fail:
- # cause the failure :-)
- raise
- return dec
-
-
-class DB(Base):
- # Constants: connection level
- NONE = 0 # No connection; just set self.url
- CONNECT = 1 # Connect; no transaction
- TXN = 2 # Everything in a transaction
-
- level = TXN
-
- def _engineInfo(self, url=None):
- if url is None:
- url = self.url
- return url
-
- def _setup(self, url):
- self._connect(url)
- # make sure there are no tables lying around
- meta = MetaData(self.engine, reflect=True)
- meta.drop_all()
-
- def _teardown(self):
- self._disconnect()
-
- def _connect(self, url):
- self.url = url
- # TODO: seems like 0.5.x branch does not work with engine.dispose and staticpool
- #self.engine = create_engine(url, echo=True, poolclass=StaticPool)
- self.engine = create_engine(url, echo=True)
- # silence the logger added by SA, nose adds its own!
- logging.getLogger('sqlalchemy').handlers=[]
- self.meta = MetaData(bind=self.engine)
- if self.level < self.CONNECT:
- return
- #self.session = create_session(bind=self.engine)
- if self.level < self.TXN:
- return
- #self.txn = self.session.begin()
-
- def _disconnect(self):
- if hasattr(self, 'txn'):
- self.txn.rollback()
- if hasattr(self, 'session'):
- self.session.close()
- #if hasattr(self,'conn'):
- # self.conn.close()
- self.engine.dispose()
-
- def _supported(self, url):
- db = url.split(':',1)[0]
- func = getattr(self, self._TestCase__testMethodName)
- if hasattr(func, 'supported'):
- return db in func.supported
- if hasattr(func, 'not_supported'):
- return not (db in func.not_supported)
- # Neither list assigned; assume all are supported
- return True
-
- def _not_supported(self, url):
- return not self._supported(url)
-
- def _select_row(self):
- """Select rows, used in multiple tests"""
- return self.table.select().execution_options(
- autocommit=True).execute().fetchone()
-
- def refresh_table(self, name=None):
- """Reload the table from the database
- Assumes we're working with only a single table, self.table, and
- metadata self.meta
-
- Working w/ multiple tables is not possible, as tables can only be
- reloaded with meta.clear()
- """
- if name is None:
- name = self.table.name
- self.meta.clear()
- self.table = Table(name, self.meta, autoload=True)
-
- def compare_columns_equal(self, columns1, columns2, ignore=None):
- """Loop through all columns and compare them"""
- def key(column):
- return column.name
- for c1, c2 in zip(sorted(columns1, key=key), sorted(columns2, key=key)):
- diffs = ColumnDelta(c1, c2).diffs
- if ignore:
- for key in ignore:
- diffs.pop(key, None)
- if diffs:
- self.fail("Comparing %s to %s failed: %s" % (columns1, columns2, diffs))
-
-# TODO: document engine.dispose and write tests
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/models.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/models.py
deleted file mode 100755
index ee764299..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/models.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from sqlalchemy import *
-
-# test rundiffs in shell
-meta_old_rundiffs = MetaData()
-meta_rundiffs = MetaData()
-meta = MetaData()
-
-tmp_account_rundiffs = Table('tmp_account_rundiffs', meta_rundiffs,
- Column('id', Integer, primary_key=True),
- Column('login', Text()),
- Column('passwd', Text()),
-)
-
-tmp_sql_table = Table('tmp_sql_table', meta, Column('id', Integer))
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/pathed.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/pathed.py
deleted file mode 100755
index b36aa086..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/pathed.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import sys
-import shutil
-import tempfile
-
-from migrate.tests.fixture import base
-
-
-class Pathed(base.Base):
- # Temporary files
-
- _tmpdir = tempfile.mkdtemp()
-
- def setUp(self):
- super(Pathed, self).setUp()
- self.temp_usable_dir = tempfile.mkdtemp()
- sys.path.append(self.temp_usable_dir)
-
- def tearDown(self):
- super(Pathed, self).tearDown()
- try:
- sys.path.remove(self.temp_usable_dir)
- except:
- pass # w00t?
- Pathed.purge(self.temp_usable_dir)
-
- @classmethod
- def _tmp(cls, prefix='', suffix=''):
- """Generate a temporary file name that doesn't exist
- All filenames are generated inside a temporary directory created by
- tempfile.mkdtemp(); only the creating user has access to this directory.
- It should be secure to return a nonexistant temp filename in this
- directory, unless the user is messing with their own files.
- """
- file, ret = tempfile.mkstemp(suffix,prefix,cls._tmpdir)
- os.close(file)
- os.remove(ret)
- return ret
-
- @classmethod
- def tmp(cls, *p, **k):
- return cls._tmp(*p, **k)
-
- @classmethod
- def tmp_py(cls, *p, **k):
- return cls._tmp(suffix='.py', *p, **k)
-
- @classmethod
- def tmp_sql(cls, *p, **k):
- return cls._tmp(suffix='.sql', *p, **k)
-
- @classmethod
- def tmp_named(cls, name):
- return os.path.join(cls._tmpdir, name)
-
- @classmethod
- def tmp_repos(cls, *p, **k):
- return cls._tmp(*p, **k)
-
- @classmethod
- def purge(cls, path):
- """Removes this path if it exists, in preparation for tests
- Careful - all tests should take place in /tmp.
- We don't want to accidentally wipe stuff out...
- """
- if os.path.exists(path):
- if os.path.isdir(path):
- shutil.rmtree(path)
- else:
- os.remove(path)
- if path.endswith('.py'):
- pyc = path + 'c'
- if os.path.exists(pyc):
- os.remove(pyc)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/shell.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/shell.py
deleted file mode 100755
index a724c9aa..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/shell.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import sys
-import logging
-
-from scripttest import TestFileEnvironment
-
-from migrate.tests.fixture.pathed import *
-
-
-log = logging.getLogger(__name__)
-
-class Shell(Pathed):
- """Base class for command line tests"""
-
- def setUp(self):
- super(Shell, self).setUp()
- migrate_path = os.path.dirname(sys.executable)
- # PATH to migrate development script folder
- log.debug('PATH for ScriptTest: %s', migrate_path)
- self.env = TestFileEnvironment(
- base_path=os.path.join(self.temp_usable_dir, 'env'),
- script_path=[migrate_path],
- )
-
- def run_version(self, repos_path):
- result = self.env.run('migrate version %s' % repos_path)
- return int(result.stdout.strip())
-
- def run_db_version(self, url, repos_path):
- result = self.env.run('migrate db_version %s %s' % (url, repos_path))
- return int(result.stdout.strip())
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/warnings.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/warnings.py
deleted file mode 100755
index 346c6a2a..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/fixture/warnings.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# lifted from Python 2.6, so we can use it in Python 2.5
-import sys
-
-class WarningMessage(object):
-
- """Holds the result of a single showwarning() call."""
-
- _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
- "line")
-
- def __init__(self, message, category, filename, lineno, file=None,
- line=None):
- local_values = locals()
- for attr in self._WARNING_DETAILS:
- setattr(self, attr, local_values[attr])
- if category:
- self._category_name = category.__name__
- else:
- self._category_name = None
-
- def __str__(self):
- return ("{message : %r, category : %r, filename : %r, lineno : %s, "
- "line : %r}" % (self.message, self._category_name,
- self.filename, self.lineno, self.line))
-
-
-class catch_warnings(object):
-
- """A context manager that copies and restores the warnings filter upon
- exiting the context.
-
- The 'record' argument specifies whether warnings should be captured by a
- custom implementation of warnings.showwarning() and be appended to a list
- returned by the context manager. Otherwise None is returned by the context
- manager. The objects appended to the list are arguments whose attributes
- mirror the arguments to showwarning().
-
- The 'module' argument is to specify an alternative module to the module
- named 'warnings' and imported under that name. This argument is only useful
- when testing the warnings module itself.
-
- """
-
- def __init__(self, record=False, module=None):
- """Specify whether to record warnings and if an alternative module
- should be used other than sys.modules['warnings'].
-
- For compatibility with Python 3.0, please consider all arguments to be
- keyword-only.
-
- """
- self._record = record
- if module is None:
- self._module = sys.modules['warnings']
- else:
- self._module = module
- self._entered = False
-
- def __repr__(self):
- args = []
- if self._record:
- args.append("record=True")
- if self._module is not sys.modules['warnings']:
- args.append("module=%r" % self._module)
- name = type(self).__name__
- return "%s(%s)" % (name, ", ".join(args))
-
- def __enter__(self):
- if self._entered:
- raise RuntimeError("Cannot enter %r twice" % self)
- self._entered = True
- self._filters = self._module.filters
- self._module.filters = self._filters[:]
- self._showwarning = self._module.showwarning
- if self._record:
- log = []
- def showwarning(*args, **kwargs):
- log.append(WarningMessage(*args, **kwargs))
- self._module.showwarning = showwarning
- return log
- else:
- return None
-
- def __exit__(self, *exc_info):
- if not self._entered:
- raise RuntimeError("Cannot exit %r without entering first" % self)
- self._module.filters = self._filters
- self._module.showwarning = self._showwarning
-
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/test_docs.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/test_docs.py
deleted file mode 100755
index 6aed0712..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/integrated/test_docs.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import doctest
-import os
-
-
-from migrate.tests import fixture
-
-# Collect tests for all handwritten docs: doc/*.rst
-
-dir = ('..','..','..','docs')
-absdir = (os.path.dirname(os.path.abspath(__file__)),)+dir
-dirpath = os.path.join(*absdir)
-files = [f for f in os.listdir(dirpath) if f.endswith('.rst')]
-paths = [os.path.join(*(dir+(f,))) for f in files]
-assert len(paths) > 0
-suite = doctest.DocFileSuite(*paths)
-
-def test_docs():
- suite.debug()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_api.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_api.py
deleted file mode 100755
index 855c49c8..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_api.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-from migrate.exceptions import *
-from migrate.versioning import api
-
-from migrate.tests.fixture.pathed import *
-from migrate.tests.fixture import models
-from migrate.tests import fixture
-
-
-class TestAPI(Pathed):
-
- def test_help(self):
- self.assertTrue(isinstance(api.help('help'), basestring))
- self.assertRaises(UsageError, api.help)
- self.assertRaises(UsageError, api.help, 'foobar')
- self.assert_(isinstance(api.help('create'), str))
-
- # test that all commands return some text
- for cmd in api.__all__:
- content = api.help(cmd)
- self.assertTrue(content)
-
- def test_create(self):
- tmprepo = self.tmp_repos()
- api.create(tmprepo, 'temp')
-
- # repository already exists
- self.assertRaises(KnownError, api.create, tmprepo, 'temp')
-
- def test_script(self):
- repo = self.tmp_repos()
- api.create(repo, 'temp')
- api.script('first version', repo)
-
- def test_script_sql(self):
- repo = self.tmp_repos()
- api.create(repo, 'temp')
- api.script_sql('postgres', 'desc', repo)
-
- def test_version(self):
- repo = self.tmp_repos()
- api.create(repo, 'temp')
- api.version(repo)
-
- def test_version_control(self):
- repo = self.tmp_repos()
- api.create(repo, 'temp')
- api.version_control('sqlite:///', repo)
- api.version_control('sqlite:///', unicode(repo))
-
- def test_source(self):
- repo = self.tmp_repos()
- api.create(repo, 'temp')
- api.script('first version', repo)
- api.script_sql('default', 'desc', repo)
-
- # no repository
- self.assertRaises(UsageError, api.source, 1)
-
- # stdout
- out = api.source(1, dest=None, repository=repo)
- self.assertTrue(out)
-
- # file
- out = api.source(1, dest=self.tmp_repos(), repository=repo)
- self.assertFalse(out)
-
- def test_manage(self):
- output = api.manage(os.path.join(self.temp_usable_dir, 'manage.py'))
-
-
-class TestSchemaAPI(fixture.DB, Pathed):
-
- def _setup(self, url):
- super(TestSchemaAPI, self)._setup(url)
- self.repo = self.tmp_repos()
- api.create(self.repo, 'temp')
- self.schema = api.version_control(url, self.repo)
-
- def _teardown(self):
- self.schema = api.drop_version_control(self.url, self.repo)
- super(TestSchemaAPI, self)._teardown()
-
- @fixture.usedb()
- def test_workflow(self):
- self.assertEqual(api.db_version(self.url, self.repo), 0)
- api.script('First Version', self.repo)
- self.assertEqual(api.db_version(self.url, self.repo), 0)
- api.upgrade(self.url, self.repo, 1)
- self.assertEqual(api.db_version(self.url, self.repo), 1)
- api.downgrade(self.url, self.repo, 0)
- self.assertEqual(api.db_version(self.url, self.repo), 0)
- api.test(self.url, self.repo)
- self.assertEqual(api.db_version(self.url, self.repo), 0)
-
- # preview
- # TODO: test output
- out = api.upgrade(self.url, self.repo, preview_py=True)
- out = api.upgrade(self.url, self.repo, preview_sql=True)
-
- api.upgrade(self.url, self.repo, 1)
- api.script_sql('default', 'desc', self.repo)
- self.assertRaises(UsageError, api.upgrade, self.url, self.repo, 2, preview_py=True)
- out = api.upgrade(self.url, self.repo, 2, preview_sql=True)
-
- # cant upgrade to version 1, already at version 1
- self.assertEqual(api.db_version(self.url, self.repo), 1)
- self.assertRaises(KnownError, api.upgrade, self.url, self.repo, 0)
-
- @fixture.usedb()
- def test_compare_model_to_db(self):
- diff = api.compare_model_to_db(self.url, self.repo, models.meta)
-
- @fixture.usedb()
- def test_create_model(self):
- model = api.create_model(self.url, self.repo)
-
- @fixture.usedb()
- def test_make_update_script_for_model(self):
- model = api.make_update_script_for_model(self.url, self.repo, models.meta_old_rundiffs, models.meta_rundiffs)
-
- @fixture.usedb()
- def test_update_db_from_model(self):
- model = api.update_db_from_model(self.url, self.repo, models.meta_rundiffs)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_cfgparse.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_cfgparse.py
deleted file mode 100755
index 27f52cd6..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_cfgparse.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-from migrate.versioning import cfgparse
-from migrate.versioning.repository import *
-from migrate.versioning.template import Template
-from migrate.tests import fixture
-
-
-class TestConfigParser(fixture.Base):
-
- def test_to_dict(self):
- """Correctly interpret config results as dictionaries"""
- parser = cfgparse.Parser(dict(default_value=42))
- self.assert_(len(parser.sections()) == 0)
- parser.add_section('section')
- parser.set('section','option','value')
- self.assertEqual(parser.get('section', 'option'), 'value')
- self.assertEqual(parser.to_dict()['section']['option'], 'value')
-
- def test_table_config(self):
- """We should be able to specify the table to be used with a repository"""
- default_text = Repository.prepare_config(Template().get_repository(),
- 'repository_name', {})
- specified_text = Repository.prepare_config(Template().get_repository(),
- 'repository_name', {'version_table': '_other_table'})
- self.assertNotEquals(default_text, specified_text)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_database.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_database.py
deleted file mode 100755
index 525385fd..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_database.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from sqlalchemy import select
-from migrate.tests import fixture
-
-class TestConnect(fixture.DB):
- level=fixture.DB.TXN
-
- @fixture.usedb()
- def test_connect(self):
- """Connect to the database successfully"""
- # Connection is done in fixture.DB setup; make sure we can do stuff
- select(['42'],bind=self.engine).execute()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_genmodel.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_genmodel.py
deleted file mode 100755
index eeefe8a3..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_genmodel.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import os
-
-import sqlalchemy
-from sqlalchemy import *
-from nose.tools import eq_
-
-from migrate.versioning import genmodel, schemadiff
-from migrate.changeset import schema
-
-from migrate.tests import fixture
-
-
-class TestSchemaDiff(fixture.DB):
- table_name = 'tmp_schemadiff'
- level = fixture.DB.CONNECT
-
- def _setup(self, url):
- super(TestSchemaDiff, self)._setup(url)
- self.meta = MetaData(self.engine, reflect=True)
- self.meta.drop_all() # in case junk tables are lying around in the test database
- self.meta = MetaData(self.engine, reflect=True) # needed if we just deleted some tables
- self.table = Table(self.table_name, self.meta,
- Column('id',Integer(), primary_key=True),
- Column('name', UnicodeText()),
- Column('data', UnicodeText()),
- )
-
- def _teardown(self):
- if self.table.exists():
- self.meta = MetaData(self.engine, reflect=True)
- self.meta.drop_all()
- super(TestSchemaDiff, self)._teardown()
-
- def _applyLatestModel(self):
- diff = schemadiff.getDiffOfModelAgainstDatabase(self.meta, self.engine, excludeTables=['migrate_version'])
- genmodel.ModelGenerator(diff,self.engine).runB2A()
-
- @fixture.usedb()
- def test_functional(self):
-
- def assertDiff(isDiff, tablesMissingInDatabase, tablesMissingInModel, tablesWithDiff):
- diff = schemadiff.getDiffOfModelAgainstDatabase(self.meta, self.engine, excludeTables=['migrate_version'])
- eq_(
- (diff.tables_missing_from_B,
- diff.tables_missing_from_A,
- diff.tables_different.keys(),
- bool(diff)),
- (tablesMissingInDatabase,
- tablesMissingInModel,
- tablesWithDiff,
- isDiff)
- )
-
- # Model is defined but database is empty.
- assertDiff(True, [self.table_name], [], [])
-
- # Check Python upgrade and downgrade of database from updated model.
- diff = schemadiff.getDiffOfModelAgainstDatabase(self.meta, self.engine, excludeTables=['migrate_version'])
- decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff,self.engine).genB2AMigration()
-
- # Feature test for a recent SQLa feature;
- # expect different output in that case.
- if repr(String()) == 'String()':
- self.assertEqualsIgnoreWhitespace(decls, '''
- from migrate.changeset import schema
- pre_meta = MetaData()
- post_meta = MetaData()
- tmp_schemadiff = Table('tmp_schemadiff', post_meta,
- Column('id', Integer, primary_key=True, nullable=False),
- Column('name', UnicodeText),
- Column('data', UnicodeText),
- )
- ''')
- else:
- self.assertEqualsIgnoreWhitespace(decls, '''
- from migrate.changeset import schema
- pre_meta = MetaData()
- post_meta = MetaData()
- tmp_schemadiff = Table('tmp_schemadiff', post_meta,
- Column('id', Integer, primary_key=True, nullable=False),
- Column('name', UnicodeText(length=None)),
- Column('data', UnicodeText(length=None)),
- )
- ''')
-
- # Create table in database, now model should match database.
- self._applyLatestModel()
- assertDiff(False, [], [], [])
-
- # Check Python code gen from database.
- diff = schemadiff.getDiffOfModelAgainstDatabase(MetaData(), self.engine, excludeTables=['migrate_version'])
- src = genmodel.ModelGenerator(diff,self.engine).genBDefinition()
-
- exec src in locals()
-
- c1 = Table('tmp_schemadiff', self.meta, autoload=True).c
- c2 = tmp_schemadiff.c
- self.compare_columns_equal(c1, c2, ['type'])
- # TODO: get rid of ignoring type
-
- if not self.engine.name == 'oracle':
- # Add data, later we'll make sure it's still present.
- result = self.engine.execute(self.table.insert(), id=1, name=u'mydata')
- dataId = result.inserted_primary_key[0]
-
- # Modify table in model (by removing it and adding it back to model)
- # Drop column data, add columns data2 and data3.
- self.meta.remove(self.table)
- self.table = Table(self.table_name,self.meta,
- Column('id',Integer(),primary_key=True),
- Column('name',UnicodeText(length=None)),
- Column('data2',Integer(),nullable=True),
- Column('data3',Integer(),nullable=True),
- )
- assertDiff(True, [], [], [self.table_name])
-
- # Apply latest model changes and find no more diffs.
- self._applyLatestModel()
- assertDiff(False, [], [], [])
-
- # Drop column data3, add data4
- self.meta.remove(self.table)
- self.table = Table(self.table_name,self.meta,
- Column('id',Integer(),primary_key=True),
- Column('name',UnicodeText(length=None)),
- Column('data2',Integer(),nullable=True),
- Column('data4',Float(),nullable=True),
- )
- assertDiff(True, [], [], [self.table_name])
-
- diff = schemadiff.getDiffOfModelAgainstDatabase(
- self.meta, self.engine, excludeTables=['migrate_version'])
- decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff,self.engine).genB2AMigration(indent='')
-
- # decls have changed since genBDefinition
- exec decls in locals()
- # migration commands expect a namespace containing migrate_engine
- migrate_engine = self.engine
- # run the migration up and down
- exec upgradeCommands in locals()
- assertDiff(False, [], [], [])
-
- exec decls in locals()
- exec downgradeCommands in locals()
- assertDiff(True, [], [], [self.table_name])
-
- exec decls in locals()
- exec upgradeCommands in locals()
- assertDiff(False, [], [], [])
-
- if not self.engine.name == 'oracle':
- # Make sure data is still present.
- result = self.engine.execute(self.table.select(self.table.c.id==dataId))
- rows = result.fetchall()
- eq_(len(rows), 1)
- eq_(rows[0].name, 'mydata')
-
- # Add data, later we'll make sure it's still present.
- result = self.engine.execute(self.table.insert(), id=2, name=u'mydata2', data2=123)
- dataId2 = result.inserted_primary_key[0]
-
- # Change column type in model.
- self.meta.remove(self.table)
- self.table = Table(self.table_name,self.meta,
- Column('id',Integer(),primary_key=True),
- Column('name',UnicodeText(length=None)),
- Column('data2',String(255),nullable=True),
- )
-
- # XXX test type diff
- return
-
- assertDiff(True, [], [], [self.table_name])
-
- # Apply latest model changes and find no more diffs.
- self._applyLatestModel()
- assertDiff(False, [], [], [])
-
- if not self.engine.name == 'oracle':
- # Make sure data is still present.
- result = self.engine.execute(self.table.select(self.table.c.id==dataId2))
- rows = result.fetchall()
- self.assertEquals(len(rows), 1)
- self.assertEquals(rows[0].name, 'mydata2')
- self.assertEquals(rows[0].data2, '123')
-
- # Delete data, since we're about to make a required column.
- # Not even using sqlalchemy.PassiveDefault helps because we're doing explicit column select.
- self.engine.execute(self.table.delete(), id=dataId)
-
- if not self.engine.name == 'firebird':
- # Change column nullable in model.
- self.meta.remove(self.table)
- self.table = Table(self.table_name,self.meta,
- Column('id',Integer(),primary_key=True),
- Column('name',UnicodeText(length=None)),
- Column('data2',String(255),nullable=False),
- )
- assertDiff(True, [], [], [self.table_name]) # TODO test nullable diff
-
- # Apply latest model changes and find no more diffs.
- self._applyLatestModel()
- assertDiff(False, [], [], [])
-
- # Remove table from model.
- self.meta.remove(self.table)
- assertDiff(True, [], [self.table_name], [])
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_keyedinstance.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_keyedinstance.py
deleted file mode 100755
index b2f87ac4..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_keyedinstance.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-from migrate.tests import fixture
-from migrate.versioning.util.keyedinstance import *
-
-class TestKeydInstance(fixture.Base):
- def test_unique(self):
- """UniqueInstance should produce unique object instances"""
- class Uniq1(KeyedInstance):
- @classmethod
- def _key(cls,key):
- return str(key)
- def __init__(self,value):
- self.value=value
- class Uniq2(KeyedInstance):
- @classmethod
- def _key(cls,key):
- return str(key)
- def __init__(self,value):
- self.value=value
-
- a10 = Uniq1('a')
-
- # Different key: different instance
- b10 = Uniq1('b')
- self.assert_(a10 is not b10)
-
- # Different class: different instance
- a20 = Uniq2('a')
- self.assert_(a10 is not a20)
-
- # Same key/class: same instance
- a11 = Uniq1('a')
- self.assert_(a10 is a11)
-
- # __init__ is called
- self.assertEquals(a10.value,'a')
-
- # clear() causes us to forget all existing instances
- Uniq1.clear()
- a12 = Uniq1('a')
- self.assert_(a10 is not a12)
-
- self.assertRaises(NotImplementedError, KeyedInstance._key)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_pathed.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_pathed.py
deleted file mode 100755
index 7616e9d7..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_pathed.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from migrate.tests import fixture
-from migrate.versioning.pathed import *
-
-class TestPathed(fixture.Base):
- def test_parent_path(self):
- """Default parent_path should behave correctly"""
- filepath='/fgsfds/moot.py'
- dirpath='/fgsfds/moot'
- sdirpath='/fgsfds/moot/'
-
- result='/fgsfds'
- self.assert_(result==Pathed._parent_path(filepath))
- self.assert_(result==Pathed._parent_path(dirpath))
- self.assert_(result==Pathed._parent_path(sdirpath))
-
- def test_new(self):
- """Pathed(path) shouldn't create duplicate objects of the same path"""
- path='/fgsfds'
- class Test(Pathed):
- attr=None
- o1=Test(path)
- o2=Test(path)
- self.assert_(isinstance(o1,Test))
- self.assert_(o1.path==path)
- self.assert_(o1 is o2)
- o1.attr='herring'
- self.assert_(o2.attr=='herring')
- o2.attr='shrubbery'
- self.assert_(o1.attr=='shrubbery')
-
- def test_parent(self):
- """Parents should be fetched correctly"""
- class Parent(Pathed):
- parent=None
- children=0
- def _init_child(self,child,path):
- """Keep a tally of children.
- (A real class might do something more interesting here)
- """
- self.__class__.children+=1
-
- class Child(Pathed):
- parent=Parent
-
- path='/fgsfds/moot.py'
- parent_path='/fgsfds'
- object=Child(path)
- self.assert_(isinstance(object,Child))
- self.assert_(isinstance(object.parent,Parent))
- self.assert_(object.path==path)
- self.assert_(object.parent.path==parent_path)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_repository.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_repository.py
deleted file mode 100755
index a926f2c2..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_repository.py
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import shutil
-
-from migrate import exceptions
-from migrate.versioning.repository import *
-from migrate.versioning.script import *
-from nose.tools import raises
-
-from migrate.tests import fixture
-from datetime import datetime
-
-
-class TestRepository(fixture.Pathed):
- def test_create(self):
- """Repositories are created successfully"""
- path = self.tmp_repos()
- name = 'repository_name'
-
- # Creating a repository that doesn't exist should succeed
- repo = Repository.create(path, name)
- config_path = repo.config.path
- manage_path = os.path.join(repo.path, 'manage.py')
- self.assert_(repo)
-
- # Files should actually be created
- self.assert_(os.path.exists(path))
- self.assert_(os.path.exists(config_path))
- self.assert_(os.path.exists(manage_path))
-
- # Can't create it again: it already exists
- self.assertRaises(exceptions.PathFoundError, Repository.create, path, name)
- return path
-
- def test_load(self):
- """We should be able to load information about an existing repository"""
- # Create a repository to load
- path = self.test_create()
- repos = Repository(path)
-
- self.assert_(repos)
- self.assert_(repos.config)
- self.assert_(repos.config.get('db_settings', 'version_table'))
-
- # version_table's default isn't none
- self.assertNotEquals(repos.config.get('db_settings', 'version_table'), 'None')
-
- def test_load_notfound(self):
- """Nonexistant repositories shouldn't be loaded"""
- path = self.tmp_repos()
- self.assert_(not os.path.exists(path))
- self.assertRaises(exceptions.InvalidRepositoryError, Repository, path)
-
- def test_load_invalid(self):
- """Invalid repos shouldn't be loaded"""
- # Here, invalid=empty directory. There may be other conditions too,
- # but we shouldn't need to test all of them
- path = self.tmp_repos()
- os.mkdir(path)
- self.assertRaises(exceptions.InvalidRepositoryError, Repository, path)
-
-
-class TestVersionedRepository(fixture.Pathed):
- """Tests on an existing repository with a single python script"""
-
- def setUp(self):
- super(TestVersionedRepository, self).setUp()
- Repository.clear()
- self.path_repos = self.tmp_repos()
- Repository.create(self.path_repos, 'repository_name')
-
- def test_version(self):
- """We should correctly detect the version of a repository"""
- repos = Repository(self.path_repos)
-
- # Get latest version, or detect if a specified version exists
- self.assertEquals(repos.latest, 0)
- # repos.latest isn't an integer, but a VerNum
- # (so we can't just assume the following tests are correct)
- self.assert_(repos.latest >= 0)
- self.assert_(repos.latest < 1)
-
- # Create a script and test again
- repos.create_script('')
- self.assertEquals(repos.latest, 1)
- self.assert_(repos.latest >= 0)
- self.assert_(repos.latest >= 1)
- self.assert_(repos.latest < 2)
-
- # Create a new script and test again
- repos.create_script('')
- self.assertEquals(repos.latest, 2)
- self.assert_(repos.latest >= 0)
- self.assert_(repos.latest >= 1)
- self.assert_(repos.latest >= 2)
- self.assert_(repos.latest < 3)
-
-
- def test_timestmap_numbering_version(self):
- repos = Repository(self.path_repos)
- repos.config.set('db_settings', 'use_timestamp_numbering', 'True')
-
- # Get latest version, or detect if a specified version exists
- self.assertEquals(repos.latest, 0)
- # repos.latest isn't an integer, but a VerNum
- # (so we can't just assume the following tests are correct)
- self.assert_(repos.latest >= 0)
- self.assert_(repos.latest < 1)
-
- # Create a script and test again
- now = int(datetime.utcnow().strftime('%Y%m%d%H%M%S'))
- repos.create_script('')
- print repos.latest
- self.assertEquals(repos.latest, now)
-
- def test_source(self):
- """Get a script object by version number and view its source"""
- # Load repository and commit script
- repo = Repository(self.path_repos)
- repo.create_script('')
- repo.create_script_sql('postgres', 'foo bar')
-
- # Source is valid: script must have an upgrade function
- # (not a very thorough test, but should be plenty)
- source = repo.version(1).script().source()
- self.assertTrue(source.find('def upgrade') >= 0)
-
- import pprint; pprint.pprint(repo.version(2).sql)
- source = repo.version(2).script('postgres', 'upgrade').source()
- self.assertEqual(source.strip(), '')
-
- def test_latestversion(self):
- """Repository.version() (no params) returns the latest version"""
- repos = Repository(self.path_repos)
- repos.create_script('')
- self.assert_(repos.version(repos.latest) is repos.version())
- self.assert_(repos.version() is not None)
-
- def test_changeset(self):
- """Repositories can create changesets properly"""
- # Create a nonzero-version repository of empty scripts
- repos = Repository(self.path_repos)
- for i in range(10):
- repos.create_script('')
-
- def check_changeset(params, length):
- """Creates and verifies a changeset"""
- changeset = repos.changeset('postgres', *params)
- self.assertEquals(len(changeset), length)
- self.assertTrue(isinstance(changeset, Changeset))
- uniq = list()
- # Changesets are iterable
- for version, change in changeset:
- self.assert_(isinstance(change, BaseScript))
- # Changes aren't identical
- self.assert_(id(change) not in uniq)
- uniq.append(id(change))
- return changeset
-
- # Upgrade to a specified version...
- cs = check_changeset((0, 10), 10)
- self.assertEquals(cs.keys().pop(0),0 ) # 0 -> 1: index is starting version
- self.assertEquals(cs.keys().pop(), 9) # 9 -> 10: index is starting version
- self.assertEquals(cs.start, 0) # starting version
- self.assertEquals(cs.end, 10) # ending version
- check_changeset((0, 1), 1)
- check_changeset((0, 5), 5)
- check_changeset((0, 0), 0)
- check_changeset((5, 5), 0)
- check_changeset((10, 10), 0)
- check_changeset((5, 10), 5)
-
- # Can't request a changeset of higher version than this repository
- self.assertRaises(Exception, repos.changeset, 'postgres', 5, 11)
- self.assertRaises(Exception, repos.changeset, 'postgres', -1, 5)
-
- # Upgrade to the latest version...
- cs = check_changeset((0,), 10)
- self.assertEquals(cs.keys().pop(0), 0)
- self.assertEquals(cs.keys().pop(), 9)
- self.assertEquals(cs.start, 0)
- self.assertEquals(cs.end, 10)
- check_changeset((1,), 9)
- check_changeset((5,), 5)
- check_changeset((9,), 1)
- check_changeset((10,), 0)
-
- # run changes
- cs.run('postgres', 'upgrade')
-
- # Can't request a changeset of higher/lower version than this repository
- self.assertRaises(Exception, repos.changeset, 'postgres', 11)
- self.assertRaises(Exception, repos.changeset, 'postgres', -1)
-
- # Downgrade
- cs = check_changeset((10, 0),10)
- self.assertEquals(cs.keys().pop(0), 10) # 10 -> 9
- self.assertEquals(cs.keys().pop(), 1) # 1 -> 0
- self.assertEquals(cs.start, 10)
- self.assertEquals(cs.end, 0)
- check_changeset((10, 5), 5)
- check_changeset((5, 0), 5)
-
- def test_many_versions(self):
- """Test what happens when lots of versions are created"""
- repos = Repository(self.path_repos)
- for i in range(1001):
- repos.create_script('')
-
- # since we normally create 3 digit ones, let's see if we blow up
- self.assert_(os.path.exists('%s/versions/1000.py' % self.path_repos))
- self.assert_(os.path.exists('%s/versions/1001.py' % self.path_repos))
-
-
-# TODO: test manage file
-# TODO: test changeset
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_runchangeset.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_runchangeset.py
deleted file mode 100755
index 52b02151..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_runchangeset.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os,shutil
-
-from migrate.tests import fixture
-from migrate.versioning.schema import *
-from migrate.versioning import script
-
-
-class TestRunChangeset(fixture.Pathed,fixture.DB):
- level=fixture.DB.CONNECT
- def _setup(self, url):
- super(TestRunChangeset, self)._setup(url)
- Repository.clear()
- self.path_repos=self.tmp_repos()
- # Create repository, script
- Repository.create(self.path_repos,'repository_name')
-
- @fixture.usedb()
- def test_changeset_run(self):
- """Running a changeset against a repository gives expected results"""
- repos=Repository(self.path_repos)
- for i in range(10):
- repos.create_script('')
- try:
- ControlledSchema(self.engine,repos).drop()
- except:
- pass
- db=ControlledSchema.create(self.engine,repos)
-
- # Scripts are empty; we'll check version # correctness.
- # (Correct application of their content is checked elsewhere)
- self.assertEquals(db.version,0)
- db.upgrade(1)
- self.assertEquals(db.version,1)
- db.upgrade(5)
- self.assertEquals(db.version,5)
- db.upgrade(5)
- self.assertEquals(db.version,5)
- db.upgrade(None) # Latest is implied
- self.assertEquals(db.version,10)
- self.assertRaises(Exception,db.upgrade,11)
- self.assertEquals(db.version,10)
- db.upgrade(9)
- self.assertEquals(db.version,9)
- db.upgrade(0)
- self.assertEquals(db.version,0)
- self.assertRaises(Exception,db.upgrade,-1)
- self.assertEquals(db.version,0)
- #changeset = repos.changeset(self.url,0)
- db.drop()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schema.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schema.py
deleted file mode 100755
index 8b0033c6..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schema.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import shutil
-
-from migrate import exceptions
-from migrate.versioning.schema import *
-from migrate.versioning import script, schemadiff
-
-from sqlalchemy import *
-
-from migrate.tests import fixture
-
-
-class TestControlledSchema(fixture.Pathed, fixture.DB):
- # Transactions break postgres in this test; we'll clean up after ourselves
- level = fixture.DB.CONNECT
-
- def setUp(self):
- super(TestControlledSchema, self).setUp()
- self.path_repos = self.temp_usable_dir + '/repo/'
- self.repos = Repository.create(self.path_repos, 'repo_name')
-
- def _setup(self, url):
- self.setUp()
- super(TestControlledSchema, self)._setup(url)
- self.cleanup()
-
- def _teardown(self):
- super(TestControlledSchema, self)._teardown()
- self.cleanup()
- self.tearDown()
-
- def cleanup(self):
- # drop existing version table if necessary
- try:
- ControlledSchema(self.engine, self.repos).drop()
- except:
- # No table to drop; that's fine, be silent
- pass
-
- def tearDown(self):
- self.cleanup()
- super(TestControlledSchema, self).tearDown()
-
- @fixture.usedb()
- def test_version_control(self):
- """Establish version control on a particular database"""
- # Establish version control on this database
- dbcontrol = ControlledSchema.create(self.engine, self.repos)
-
- # Trying to create another DB this way fails: table exists
- self.assertRaises(exceptions.DatabaseAlreadyControlledError,
- ControlledSchema.create, self.engine, self.repos)
-
- # We can load a controlled DB this way, too
- dbcontrol0 = ControlledSchema(self.engine, self.repos)
- self.assertEquals(dbcontrol, dbcontrol0)
-
- # We can also use a repository path, instead of a repository
- dbcontrol0 = ControlledSchema(self.engine, self.repos.path)
- self.assertEquals(dbcontrol, dbcontrol0)
-
- # We don't have to use the same connection
- engine = create_engine(self.url)
- dbcontrol0 = ControlledSchema(engine, self.repos.path)
- self.assertEquals(dbcontrol, dbcontrol0)
-
- # Clean up:
- dbcontrol.drop()
-
- # Attempting to drop vc from a db without it should fail
- self.assertRaises(exceptions.DatabaseNotControlledError, dbcontrol.drop)
-
- # No table defined should raise error
- self.assertRaises(exceptions.DatabaseNotControlledError,
- ControlledSchema, self.engine, self.repos)
-
- @fixture.usedb()
- def test_version_control_specified(self):
- """Establish version control with a specified version"""
- # Establish version control on this database
- version = 0
- dbcontrol = ControlledSchema.create(self.engine, self.repos, version)
- self.assertEquals(dbcontrol.version, version)
-
- # Correct when we load it, too
- dbcontrol = ControlledSchema(self.engine, self.repos)
- self.assertEquals(dbcontrol.version, version)
-
- dbcontrol.drop()
-
- # Now try it with a nonzero value
- version = 10
- for i in range(version):
- self.repos.create_script('')
- self.assertEquals(self.repos.latest, version)
-
- # Test with some mid-range value
- dbcontrol = ControlledSchema.create(self.engine,self.repos, 5)
- self.assertEquals(dbcontrol.version, 5)
- dbcontrol.drop()
-
- # Test with max value
- dbcontrol = ControlledSchema.create(self.engine, self.repos, version)
- self.assertEquals(dbcontrol.version, version)
- dbcontrol.drop()
-
- @fixture.usedb()
- def test_version_control_invalid(self):
- """Try to establish version control with an invalid version"""
- versions = ('Thirteen', '-1', -1, '' , 13)
- # A fresh repository doesn't go up to version 13 yet
- for version in versions:
- #self.assertRaises(ControlledSchema.InvalidVersionError,
- # Can't have custom errors with assertRaises...
- try:
- ControlledSchema.create(self.engine, self.repos, version)
- self.assert_(False, repr(version))
- except exceptions.InvalidVersionError:
- pass
-
- @fixture.usedb()
- def test_changeset(self):
- """Create changeset from controlled schema"""
- dbschema = ControlledSchema.create(self.engine, self.repos)
-
- # empty schema doesn't have changesets
- cs = dbschema.changeset()
- self.assertEqual(cs, {})
-
- for i in range(5):
- self.repos.create_script('')
- self.assertEquals(self.repos.latest, 5)
-
- cs = dbschema.changeset(5)
- self.assertEqual(len(cs), 5)
-
- # cleanup
- dbschema.drop()
-
- @fixture.usedb()
- def test_upgrade_runchange(self):
- dbschema = ControlledSchema.create(self.engine, self.repos)
-
- for i in range(10):
- self.repos.create_script('')
-
- self.assertEquals(self.repos.latest, 10)
-
- dbschema.upgrade(10)
-
- self.assertRaises(ValueError, dbschema.upgrade, 'a')
- self.assertRaises(exceptions.InvalidVersionError, dbschema.runchange, 20, '', 1)
-
- # TODO: test for table version in db
-
- # cleanup
- dbschema.drop()
-
- @fixture.usedb()
- def test_create_model(self):
- """Test workflow to generate create_model"""
- model = ControlledSchema.create_model(self.engine, self.repos, declarative=False)
- self.assertTrue(isinstance(model, basestring))
-
- model = ControlledSchema.create_model(self.engine, self.repos.path, declarative=True)
- self.assertTrue(isinstance(model, basestring))
-
- @fixture.usedb()
- def test_compare_model_to_db(self):
- meta = self.construct_model()
-
- diff = ControlledSchema.compare_model_to_db(self.engine, meta, self.repos)
- self.assertTrue(isinstance(diff, schemadiff.SchemaDiff))
-
- diff = ControlledSchema.compare_model_to_db(self.engine, meta, self.repos.path)
- self.assertTrue(isinstance(diff, schemadiff.SchemaDiff))
- meta.drop_all(self.engine)
-
- @fixture.usedb()
- def test_update_db_from_model(self):
- dbschema = ControlledSchema.create(self.engine, self.repos)
-
- meta = self.construct_model()
-
- dbschema.update_db_from_model(meta)
-
- # TODO: test for table version in db
-
- # cleanup
- dbschema.drop()
- meta.drop_all(self.engine)
-
- def construct_model(self):
- meta = MetaData()
-
- user = Table('temp_model_schema', meta, Column('id', Integer), Column('user', String(245)))
-
- return meta
-
- # TODO: test how are tables populated in db
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schemadiff.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schemadiff.py
deleted file mode 100755
index 0bfa902b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_schemadiff.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import os
-
-from sqlalchemy import *
-from nose.tools import eq_
-
-from migrate.versioning import schemadiff
-
-from migrate.tests import fixture
-
-class SchemaDiffBase(fixture.DB):
-
- level = fixture.DB.CONNECT
-
- def _make_table(self,*cols,**kw):
- self.table = Table('xtable', self.meta,
- Column('id',Integer(), primary_key=True),
- *cols
- )
- if kw.get('create',True):
- self.table.create()
-
- def _assert_diff(self,col_A,col_B):
- self._make_table(col_A)
- self.meta.clear()
- self._make_table(col_B,create=False)
- diff = self._run_diff()
- # print diff
- self.assertTrue(diff)
- eq_(1,len(diff.tables_different))
- td = diff.tables_different.values()[0]
- eq_(1,len(td.columns_different))
- cd = td.columns_different.values()[0]
- eq_(('Schema diffs:\n'
- ' table with differences: xtable\n'
- ' column with differences: data\n'
- ' model: %r\n'
- ' database: %r')%(
- cd.col_A,
- cd.col_B
- ),str(diff))
-
-class Test_getDiffOfModelAgainstDatabase(SchemaDiffBase):
-
- def _run_diff(self,**kw):
- return schemadiff.getDiffOfModelAgainstDatabase(
- self.meta, self.engine, **kw
- )
-
- @fixture.usedb()
- def test_table_missing_in_db(self):
- self._make_table(create=False)
- diff = self._run_diff()
- self.assertTrue(diff)
- eq_('Schema diffs:\n tables missing from database: xtable',
- str(diff))
-
- @fixture.usedb()
- def test_table_missing_in_model(self):
- self._make_table()
- self.meta.clear()
- diff = self._run_diff()
- self.assertTrue(diff)
- eq_('Schema diffs:\n tables missing from model: xtable',
- str(diff))
-
- @fixture.usedb()
- def test_column_missing_in_db(self):
- # db
- Table('xtable', self.meta,
- Column('id',Integer(), primary_key=True),
- ).create()
- self.meta.clear()
- # model
- self._make_table(
- Column('xcol',Integer()),
- create=False
- )
- # run diff
- diff = self._run_diff()
- self.assertTrue(diff)
- eq_('Schema diffs:\n'
- ' table with differences: xtable\n'
- ' database missing these columns: xcol',
- str(diff))
-
- @fixture.usedb()
- def test_column_missing_in_model(self):
- # db
- self._make_table(
- Column('xcol',Integer()),
- )
- self.meta.clear()
- # model
- self._make_table(
- create=False
- )
- # run diff
- diff = self._run_diff()
- self.assertTrue(diff)
- eq_('Schema diffs:\n'
- ' table with differences: xtable\n'
- ' model missing these columns: xcol',
- str(diff))
-
- @fixture.usedb()
- def test_exclude_tables(self):
- # db
- Table('ytable', self.meta,
- Column('id',Integer(), primary_key=True),
- ).create()
- Table('ztable', self.meta,
- Column('id',Integer(), primary_key=True),
- ).create()
- self.meta.clear()
- # model
- self._make_table(
- create=False
- )
- Table('ztable', self.meta,
- Column('id',Integer(), primary_key=True),
- )
- # run diff
- diff = self._run_diff(excludeTables=('xtable','ytable'))
- # ytable only in database
- # xtable only in model
- # ztable identical on both
- # ...so we expect no diff!
- self.assertFalse(diff)
- eq_('No schema diffs',str(diff))
-
- @fixture.usedb()
- def test_identical_just_pk(self):
- self._make_table()
- diff = self._run_diff()
- self.assertFalse(diff)
- eq_('No schema diffs',str(diff))
-
-
- @fixture.usedb()
- def test_different_type(self):
- self._assert_diff(
- Column('data', String(10)),
- Column('data', Integer()),
- )
-
- @fixture.usedb()
- def test_int_vs_float(self):
- self._assert_diff(
- Column('data', Integer()),
- Column('data', Float()),
- )
-
- @fixture.usedb()
- def test_float_vs_numeric(self):
- self._assert_diff(
- Column('data', Float()),
- Column('data', Numeric()),
- )
-
- @fixture.usedb()
- def test_numeric_precision(self):
- self._assert_diff(
- Column('data', Numeric(precision=5)),
- Column('data', Numeric(precision=6)),
- )
-
- @fixture.usedb()
- def test_numeric_scale(self):
- self._assert_diff(
- Column('data', Numeric(precision=6,scale=0)),
- Column('data', Numeric(precision=6,scale=1)),
- )
-
- @fixture.usedb()
- def test_string_length(self):
- self._assert_diff(
- Column('data', String(10)),
- Column('data', String(20)),
- )
-
- @fixture.usedb()
- def test_integer_identical(self):
- self._make_table(
- Column('data', Integer()),
- )
- diff = self._run_diff()
- eq_('No schema diffs',str(diff))
- self.assertFalse(diff)
-
- @fixture.usedb()
- def test_string_identical(self):
- self._make_table(
- Column('data', String(10)),
- )
- diff = self._run_diff()
- eq_('No schema diffs',str(diff))
- self.assertFalse(diff)
-
- @fixture.usedb()
- def test_text_identical(self):
- self._make_table(
- Column('data', Text(255)),
- )
- diff = self._run_diff()
- eq_('No schema diffs',str(diff))
- self.assertFalse(diff)
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_script.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_script.py
deleted file mode 100755
index 53ef9293..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_script.py
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import sys
-import shutil
-
-from migrate import exceptions
-from migrate.versioning import version, repository
-from migrate.versioning.script import *
-from migrate.versioning.util import *
-
-from migrate.tests import fixture
-from migrate.tests.fixture.models import tmp_sql_table
-
-
-class TestBaseScript(fixture.Pathed):
-
- def test_all(self):
- """Testing all basic BaseScript operations"""
- # verify / source / run
- src = self.tmp()
- open(src, 'w').close()
- bscript = BaseScript(src)
- BaseScript.verify(src)
- self.assertEqual(bscript.source(), '')
- self.assertRaises(NotImplementedError, bscript.run, 'foobar')
-
-
-class TestPyScript(fixture.Pathed, fixture.DB):
- cls = PythonScript
- def test_create(self):
- """We can create a migration script"""
- path = self.tmp_py()
- # Creating a file that doesn't exist should succeed
- self.cls.create(path)
- self.assert_(os.path.exists(path))
- # Created file should be a valid script (If not, raises an error)
- self.cls.verify(path)
- # Can't create it again: it already exists
- self.assertRaises(exceptions.PathFoundError,self.cls.create,path)
-
- @fixture.usedb(supported='sqlite')
- def test_run(self):
- script_path = self.tmp_py()
- pyscript = PythonScript.create(script_path)
- pyscript.run(self.engine, 1)
- pyscript.run(self.engine, -1)
-
- self.assertRaises(exceptions.ScriptError, pyscript.run, self.engine, 0)
- self.assertRaises(exceptions.ScriptError, pyscript._func, 'foobar')
-
- # clean pyc file
- os.remove(script_path + 'c')
-
- # test deprecated upgrade/downgrade with no arguments
- contents = open(script_path, 'r').read()
- f = open(script_path, 'w')
- f.write(contents.replace("upgrade(migrate_engine)", "upgrade()"))
- f.close()
-
- pyscript = PythonScript(script_path)
- pyscript._module = None
- try:
- pyscript.run(self.engine, 1)
- pyscript.run(self.engine, -1)
- except exceptions.ScriptError:
- pass
- else:
- self.fail()
-
- def test_verify_notfound(self):
- """Correctly verify a python migration script: nonexistant file"""
- path = self.tmp_py()
- self.assertFalse(os.path.exists(path))
- # Fails on empty path
- self.assertRaises(exceptions.InvalidScriptError,self.cls.verify,path)
- self.assertRaises(exceptions.InvalidScriptError,self.cls,path)
-
- def test_verify_invalidpy(self):
- """Correctly verify a python migration script: invalid python file"""
- path=self.tmp_py()
- # Create empty file
- f = open(path,'w')
- f.write("def fail")
- f.close()
- self.assertRaises(Exception,self.cls.verify_module,path)
- # script isn't verified on creation, but on module reference
- py = self.cls(path)
- self.assertRaises(Exception,(lambda x: x.module),py)
-
- def test_verify_nofuncs(self):
- """Correctly verify a python migration script: valid python file; no upgrade func"""
- path = self.tmp_py()
- # Create empty file
- f = open(path, 'w')
- f.write("def zergling():\n\tprint 'rush'")
- f.close()
- self.assertRaises(exceptions.InvalidScriptError, self.cls.verify_module, path)
- # script isn't verified on creation, but on module reference
- py = self.cls(path)
- self.assertRaises(exceptions.InvalidScriptError,(lambda x: x.module),py)
-
- @fixture.usedb(supported='sqlite')
- def test_preview_sql(self):
- """Preview SQL abstract from ORM layer (sqlite)"""
- path = self.tmp_py()
-
- f = open(path, 'w')
- content = '''
-from migrate import *
-from sqlalchemy import *
-
-metadata = MetaData()
-
-UserGroup = Table('Link', metadata,
- Column('link1ID', Integer),
- Column('link2ID', Integer),
- UniqueConstraint('link1ID', 'link2ID'))
-
-def upgrade(migrate_engine):
- metadata.create_all(migrate_engine)
- '''
- f.write(content)
- f.close()
-
- pyscript = self.cls(path)
- SQL = pyscript.preview_sql(self.url, 1)
- self.assertEqualsIgnoreWhitespace("""
- CREATE TABLE "Link"
- ("link1ID" INTEGER,
- "link2ID" INTEGER,
- UNIQUE ("link1ID", "link2ID"))
- """, SQL)
- # TODO: test: No SQL should be executed!
-
- def test_verify_success(self):
- """Correctly verify a python migration script: success"""
- path = self.tmp_py()
- # Succeeds after creating
- self.cls.create(path)
- self.cls.verify(path)
-
- # test for PythonScript.make_update_script_for_model
-
- @fixture.usedb()
- def test_make_update_script_for_model(self):
- """Construct script source from differences of two models"""
-
- self.setup_model_params()
- self.write_file(self.first_model_path, self.base_source)
- self.write_file(self.second_model_path, self.base_source + self.model_source)
-
- source_script = self.pyscript.make_update_script_for_model(
- engine=self.engine,
- oldmodel=load_model('testmodel_first:meta'),
- model=load_model('testmodel_second:meta'),
- repository=self.repo_path,
- )
-
- self.assertTrue("['User'].create()" in source_script)
- self.assertTrue("['User'].drop()" in source_script)
-
- @fixture.usedb()
- def test_make_update_script_for_equal_models(self):
- """Try to make update script from two identical models"""
-
- self.setup_model_params()
- self.write_file(self.first_model_path, self.base_source + self.model_source)
- self.write_file(self.second_model_path, self.base_source + self.model_source)
-
- source_script = self.pyscript.make_update_script_for_model(
- engine=self.engine,
- oldmodel=load_model('testmodel_first:meta'),
- model=load_model('testmodel_second:meta'),
- repository=self.repo_path,
- )
-
- self.assertFalse('User.create()' in source_script)
- self.assertFalse('User.drop()' in source_script)
-
- @fixture.usedb()
- def test_make_update_script_direction(self):
- """Check update scripts go in the right direction"""
-
- self.setup_model_params()
- self.write_file(self.first_model_path, self.base_source)
- self.write_file(self.second_model_path, self.base_source + self.model_source)
-
- source_script = self.pyscript.make_update_script_for_model(
- engine=self.engine,
- oldmodel=load_model('testmodel_first:meta'),
- model=load_model('testmodel_second:meta'),
- repository=self.repo_path,
- )
-
- self.assertTrue(0
- < source_script.find('upgrade')
- < source_script.find("['User'].create()")
- < source_script.find('downgrade')
- < source_script.find("['User'].drop()"))
-
- def setup_model_params(self):
- self.script_path = self.tmp_py()
- self.repo_path = self.tmp()
- self.first_model_path = os.path.join(self.temp_usable_dir, 'testmodel_first.py')
- self.second_model_path = os.path.join(self.temp_usable_dir, 'testmodel_second.py')
-
- self.base_source = """from sqlalchemy import *\nmeta = MetaData()\n"""
- self.model_source = """
-User = Table('User', meta,
- Column('id', Integer, primary_key=True),
- Column('login', Unicode(40)),
- Column('passwd', String(40)),
-)"""
-
- self.repo = repository.Repository.create(self.repo_path, 'repo')
- self.pyscript = PythonScript.create(self.script_path)
- sys.modules.pop('testmodel_first', None)
- sys.modules.pop('testmodel_second', None)
-
- def write_file(self, path, contents):
- f = open(path, 'w')
- f.write(contents)
- f.close()
-
-
-class TestSqlScript(fixture.Pathed, fixture.DB):
-
- @fixture.usedb()
- def test_error(self):
- """Test if exception is raised on wrong script source"""
- src = self.tmp()
-
- f = open(src, 'w')
- f.write("""foobar""")
- f.close()
-
- sqls = SqlScript(src)
- self.assertRaises(Exception, sqls.run, self.engine)
-
- @fixture.usedb()
- def test_success(self):
- """Test sucessful SQL execution"""
- # cleanup and prepare python script
- tmp_sql_table.metadata.drop_all(self.engine, checkfirst=True)
- script_path = self.tmp_py()
- pyscript = PythonScript.create(script_path)
-
- # populate python script
- contents = open(script_path, 'r').read()
- contents = contents.replace("pass", "tmp_sql_table.create(migrate_engine)")
- contents = 'from migrate.tests.fixture.models import tmp_sql_table\n' + contents
- f = open(script_path, 'w')
- f.write(contents)
- f.close()
-
- # write SQL script from python script preview
- pyscript = PythonScript(script_path)
- src = self.tmp()
- f = open(src, 'w')
- f.write(pyscript.preview_sql(self.url, 1))
- f.close()
-
- # run the change
- sqls = SqlScript(src)
- sqls.run(self.engine, executemany=False)
- tmp_sql_table.metadata.drop_all(self.engine, checkfirst=True)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_shell.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_shell.py
deleted file mode 100755
index e24c4323..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_shell.py
+++ /dev/null
@@ -1,556 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import sys
-import tempfile
-
-from cStringIO import StringIO
-from sqlalchemy import MetaData, Table
-from nose.plugins.skip import SkipTest
-
-from migrate.exceptions import *
-from migrate.versioning.repository import Repository
-from migrate.versioning import genmodel, shell, api
-from migrate.tests.fixture import Shell, DB, usedb
-from migrate.tests.fixture import models
-
-
-class TestShellCommands(Shell):
- """Tests migrate.py commands"""
-
- def test_help(self):
- """Displays default help dialog"""
- self.assertEqual(self.env.run('migrate -h').returncode, 0)
- self.assertEqual(self.env.run('migrate --help').returncode, 0)
- self.assertEqual(self.env.run('migrate help').returncode, 0)
-
- def test_help_commands(self):
- """Display help on a specific command"""
- # we can only test that we get some output
- for cmd in api.__all__:
- result = self.env.run('migrate help %s' % cmd)
- self.assertTrue(isinstance(result.stdout, basestring))
- self.assertTrue(result.stdout)
- self.assertFalse(result.stderr)
-
- def test_shutdown_logging(self):
- """Try to shutdown logging output"""
- repos = self.tmp_repos()
- result = self.env.run('migrate create %s repository_name' % repos)
- result = self.env.run('migrate version %s --disable_logging' % repos)
- self.assertEqual(result.stdout, '')
- result = self.env.run('migrate version %s -q' % repos)
- self.assertEqual(result.stdout, '')
-
- # TODO: assert logging messages to 0
- shell.main(['version', repos], logging=False)
-
- def test_main_with_runpy(self):
- if sys.version_info[:2] == (2, 4):
- raise SkipTest("runpy is not part of python2.4")
- from runpy import run_module
- try:
- original = sys.argv
- sys.argv=['X','--help']
-
- run_module('migrate.versioning.shell', run_name='__main__')
-
- finally:
- sys.argv = original
-
- def _check_error(self,args,code,expected,**kw):
- original = sys.stderr
- try:
- actual = StringIO()
- sys.stderr = actual
- try:
- shell.main(args,**kw)
- except SystemExit, e:
- self.assertEqual(code,e.args[0])
- else:
- self.fail('No exception raised')
- finally:
- sys.stderr = original
- actual = actual.getvalue()
- self.assertTrue(expected in actual,'%r not in:\n"""\n%s\n"""'%(expected,actual))
-
- def test_main(self):
- """Test main() function"""
- repos = self.tmp_repos()
- shell.main(['help'])
- shell.main(['help', 'create'])
- shell.main(['create', 'repo_name', '--preview_sql'], repository=repos)
- shell.main(['version', '--', '--repository=%s' % repos])
- shell.main(['version', '-d', '--repository=%s' % repos, '--version=2'])
-
- self._check_error(['foobar'],2,'error: Invalid command foobar')
- self._check_error(['create', 'f', 'o', 'o'],2,'error: Too many arguments for command create: o')
- self._check_error(['create'],2,'error: Not enough arguments for command create: name, repository not specified')
- self._check_error(['create', 'repo_name'],2,'already exists', repository=repos)
-
- def test_create(self):
- """Repositories are created successfully"""
- repos = self.tmp_repos()
-
- # Creating a file that doesn't exist should succeed
- result = self.env.run('migrate create %s repository_name' % repos)
-
- # Files should actually be created
- self.assert_(os.path.exists(repos))
-
- # The default table should not be None
- repos_ = Repository(repos)
- self.assertNotEquals(repos_.config.get('db_settings', 'version_table'), 'None')
-
- # Can't create it again: it already exists
- result = self.env.run('migrate create %s repository_name' % repos,
- expect_error=True)
- self.assertEqual(result.returncode, 2)
-
- def test_script(self):
- """We can create a migration script via the command line"""
- repos = self.tmp_repos()
- result = self.env.run('migrate create %s repository_name' % repos)
-
- result = self.env.run('migrate script --repository=%s Desc' % repos)
- self.assert_(os.path.exists('%s/versions/001_Desc.py' % repos))
-
- result = self.env.run('migrate script More %s' % repos)
- self.assert_(os.path.exists('%s/versions/002_More.py' % repos))
-
- result = self.env.run('migrate script "Some Random name" %s' % repos)
- self.assert_(os.path.exists('%s/versions/003_Some_Random_name.py' % repos))
-
- def test_script_sql(self):
- """We can create a migration sql script via the command line"""
- repos = self.tmp_repos()
- result = self.env.run('migrate create %s repository_name' % repos)
-
- result = self.env.run('migrate script_sql mydb foo %s' % repos)
- self.assert_(os.path.exists('%s/versions/001_foo_mydb_upgrade.sql' % repos))
- self.assert_(os.path.exists('%s/versions/001_foo_mydb_downgrade.sql' % repos))
-
- # Test creating a second
- result = self.env.run('migrate script_sql postgres foo --repository=%s' % repos)
- self.assert_(os.path.exists('%s/versions/002_foo_postgres_upgrade.sql' % repos))
- self.assert_(os.path.exists('%s/versions/002_foo_postgres_downgrade.sql' % repos))
-
- # TODO: test --previews
-
- def test_manage(self):
- """Create a project management script"""
- script = self.tmp_py()
- self.assert_(not os.path.exists(script))
-
- # No attempt is made to verify correctness of the repository path here
- result = self.env.run('migrate manage %s --repository=/bla/' % script)
- self.assert_(os.path.exists(script))
-
-
-class TestShellRepository(Shell):
- """Shell commands on an existing repository/python script"""
-
- def setUp(self):
- """Create repository, python change script"""
- super(TestShellRepository, self).setUp()
- self.path_repos = self.tmp_repos()
- result = self.env.run('migrate create %s repository_name' % self.path_repos)
-
- def test_version(self):
- """Correctly detect repository version"""
- # Version: 0 (no scripts yet); successful execution
- result = self.env.run('migrate version --repository=%s' % self.path_repos)
- self.assertEqual(result.stdout.strip(), "0")
-
- # Also works as a positional param
- result = self.env.run('migrate version %s' % self.path_repos)
- self.assertEqual(result.stdout.strip(), "0")
-
- # Create a script and version should increment
- result = self.env.run('migrate script Desc %s' % self.path_repos)
- result = self.env.run('migrate version %s' % self.path_repos)
- self.assertEqual(result.stdout.strip(), "1")
-
- def test_source(self):
- """Correctly fetch a script's source"""
- result = self.env.run('migrate script Desc --repository=%s' % self.path_repos)
-
- filename = '%s/versions/001_Desc.py' % self.path_repos
- source = open(filename).read()
- self.assert_(source.find('def upgrade') >= 0)
-
- # Version is now 1
- result = self.env.run('migrate version %s' % self.path_repos)
- self.assertEqual(result.stdout.strip(), "1")
-
- # Output/verify the source of version 1
- result = self.env.run('migrate source 1 --repository=%s' % self.path_repos)
- self.assertEqual(result.stdout.strip(), source.strip())
-
- # We can also send the source to a file... test that too
- result = self.env.run('migrate source 1 %s --repository=%s' %
- (filename, self.path_repos))
- self.assert_(os.path.exists(filename))
- fd = open(filename)
- result = fd.read()
- self.assert_(result.strip() == source.strip())
-
-
-class TestShellDatabase(Shell, DB):
- """Commands associated with a particular database"""
- # We'll need to clean up after ourself, since the shell creates its own txn;
- # we need to connect to the DB to see if things worked
-
- level = DB.CONNECT
-
- @usedb()
- def test_version_control(self):
- """Ensure we can set version control on a database"""
- path_repos = repos = self.tmp_repos()
- url = self.url
- result = self.env.run('migrate create %s repository_name' % repos)
-
- result = self.env.run('migrate drop_version_control %(url)s %(repos)s'\
- % locals(), expect_error=True)
- self.assertEqual(result.returncode, 1)
- result = self.env.run('migrate version_control %(url)s %(repos)s' % locals())
-
- # Clean up
- result = self.env.run('migrate drop_version_control %(url)s %(repos)s' % locals())
- # Attempting to drop vc from a database without it should fail
- result = self.env.run('migrate drop_version_control %(url)s %(repos)s'\
- % locals(), expect_error=True)
- self.assertEqual(result.returncode, 1)
-
- @usedb()
- def test_wrapped_kwargs(self):
- """Commands with default arguments set by manage.py"""
- path_repos = repos = self.tmp_repos()
- url = self.url
- result = self.env.run('migrate create --name=repository_name %s' % repos)
- result = self.env.run('migrate drop_version_control %(url)s %(repos)s' % locals(), expect_error=True)
- self.assertEqual(result.returncode, 1)
- result = self.env.run('migrate version_control %(url)s %(repos)s' % locals())
-
- result = self.env.run('migrate drop_version_control %(url)s %(repos)s' % locals())
-
- @usedb()
- def test_version_control_specified(self):
- """Ensure we can set version control to a particular version"""
- path_repos = self.tmp_repos()
- url = self.url
- result = self.env.run('migrate create --name=repository_name %s' % path_repos)
- result = self.env.run('migrate drop_version_control %(url)s %(path_repos)s' % locals(), expect_error=True)
- self.assertEqual(result.returncode, 1)
-
- # Fill the repository
- path_script = self.tmp_py()
- version = 2
- for i in range(version):
- result = self.env.run('migrate script Desc --repository=%s' % path_repos)
-
- # Repository version is correct
- result = self.env.run('migrate version %s' % path_repos)
- self.assertEqual(result.stdout.strip(), str(version))
-
- # Apply versioning to DB
- result = self.env.run('migrate version_control %(url)s %(path_repos)s %(version)s' % locals())
-
- # Test db version number (should start at 2)
- result = self.env.run('migrate db_version %(url)s %(path_repos)s' % locals())
- self.assertEqual(result.stdout.strip(), str(version))
-
- # Clean up
- result = self.env.run('migrate drop_version_control %(url)s %(path_repos)s' % locals())
-
- @usedb()
- def test_upgrade(self):
- """Can upgrade a versioned database"""
- # Create a repository
- repos_name = 'repos_name'
- repos_path = self.tmp()
- result = self.env.run('migrate create %(repos_path)s %(repos_name)s' % locals())
- self.assertEquals(self.run_version(repos_path), 0)
-
- # Version the DB
- result = self.env.run('migrate drop_version_control %s %s' % (self.url, repos_path), expect_error=True)
- result = self.env.run('migrate version_control %s %s' % (self.url, repos_path))
-
- # Upgrades with latest version == 0
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
- result = self.env.run('migrate upgrade %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
- result = self.env.run('migrate upgrade %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
- result = self.env.run('migrate upgrade %s %s 1' % (self.url, repos_path), expect_error=True)
- self.assertEquals(result.returncode, 1)
- result = self.env.run('migrate upgrade %s %s -1' % (self.url, repos_path), expect_error=True)
- self.assertEquals(result.returncode, 2)
-
- # Add a script to the repository; upgrade the db
- result = self.env.run('migrate script Desc --repository=%s' % (repos_path))
- self.assertEquals(self.run_version(repos_path), 1)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- # Test preview
- result = self.env.run('migrate upgrade %s %s 0 --preview_sql' % (self.url, repos_path))
- result = self.env.run('migrate upgrade %s %s 0 --preview_py' % (self.url, repos_path))
-
- result = self.env.run('migrate upgrade %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_db_version(self.url, repos_path), 1)
-
- # Downgrade must have a valid version specified
- result = self.env.run('migrate downgrade %s %s' % (self.url, repos_path), expect_error=True)
- self.assertEquals(result.returncode, 2)
- result = self.env.run('migrate downgrade %s %s -1' % (self.url, repos_path), expect_error=True)
- self.assertEquals(result.returncode, 2)
- result = self.env.run('migrate downgrade %s %s 2' % (self.url, repos_path), expect_error=True)
- self.assertEquals(result.returncode, 2)
- self.assertEquals(self.run_db_version(self.url, repos_path), 1)
-
- result = self.env.run('migrate downgrade %s %s 0' % (self.url, repos_path))
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- result = self.env.run('migrate downgrade %s %s 1' % (self.url, repos_path), expect_error=True)
- self.assertEquals(result.returncode, 2)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- result = self.env.run('migrate drop_version_control %s %s' % (self.url, repos_path))
-
- def _run_test_sqlfile(self, upgrade_script, downgrade_script):
- # TODO: add test script that checks if db really changed
- repos_path = self.tmp()
- repos_name = 'repos'
-
- result = self.env.run('migrate create %s %s' % (repos_path, repos_name))
- result = self.env.run('migrate drop_version_control %s %s' % (self.url, repos_path), expect_error=True)
- result = self.env.run('migrate version_control %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_version(repos_path), 0)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- beforeCount = len(os.listdir(os.path.join(repos_path, 'versions'))) # hmm, this number changes sometimes based on running from svn
- result = self.env.run('migrate script_sql %s --repository=%s' % ('postgres', repos_path))
- self.assertEquals(self.run_version(repos_path), 1)
- self.assertEquals(len(os.listdir(os.path.join(repos_path, 'versions'))), beforeCount + 2)
-
- open('%s/versions/001_postgres_upgrade.sql' % repos_path, 'a').write(upgrade_script)
- open('%s/versions/001_postgres_downgrade.sql' % repos_path, 'a').write(downgrade_script)
-
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
- self.assertRaises(Exception, self.engine.text('select * from t_table').execute)
-
- result = self.env.run('migrate upgrade %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_db_version(self.url, repos_path), 1)
- self.engine.text('select * from t_table').execute()
-
- result = self.env.run('migrate downgrade %s %s 0' % (self.url, repos_path))
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
- self.assertRaises(Exception, self.engine.text('select * from t_table').execute)
-
- # The tests below are written with some postgres syntax, but the stuff
- # being tested (.sql files) ought to work with any db.
- @usedb(supported='postgres')
- def test_sqlfile(self):
- upgrade_script = """
- create table t_table (
- id serial,
- primary key(id)
- );
- """
- downgrade_script = """
- drop table t_table;
- """
- self.meta.drop_all()
- self._run_test_sqlfile(upgrade_script, downgrade_script)
-
- @usedb(supported='postgres')
- def test_sqlfile_comment(self):
- upgrade_script = """
- -- Comments in SQL break postgres autocommit
- create table t_table (
- id serial,
- primary key(id)
- );
- """
- downgrade_script = """
- -- Comments in SQL break postgres autocommit
- drop table t_table;
- """
- self._run_test_sqlfile(upgrade_script, downgrade_script)
-
- @usedb()
- def test_command_test(self):
- repos_name = 'repos_name'
- repos_path = self.tmp()
-
- result = self.env.run('migrate create repository_name --repository=%s' % repos_path)
- result = self.env.run('migrate drop_version_control %s %s' % (self.url, repos_path), expect_error=True)
- result = self.env.run('migrate version_control %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_version(repos_path), 0)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- # Empty script should succeed
- result = self.env.run('migrate script Desc %s' % repos_path)
- result = self.env.run('migrate test %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_version(repos_path), 1)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- # Error script should fail
- script_path = self.tmp_py()
- script_text='''
- from sqlalchemy import *
- from migrate import *
-
- def upgrade():
- print 'fgsfds'
- raise Exception()
-
- def downgrade():
- print 'sdfsgf'
- raise Exception()
- '''.replace("\n ", "\n")
- file = open(script_path, 'w')
- file.write(script_text)
- file.close()
-
- result = self.env.run('migrate test %s %s bla' % (self.url, repos_path), expect_error=True)
- self.assertEqual(result.returncode, 2)
- self.assertEquals(self.run_version(repos_path), 1)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- # Nonempty script using migrate_engine should succeed
- script_path = self.tmp_py()
- script_text = '''
- from sqlalchemy import *
- from migrate import *
-
- from migrate.changeset import schema
-
- meta = MetaData(migrate_engine)
- account = Table('account', meta,
- Column('id', Integer, primary_key=True),
- Column('login', Text),
- Column('passwd', Text),
- )
- def upgrade():
- # Upgrade operations go here. Don't create your own engine; use the engine
- # named 'migrate_engine' imported from migrate.
- meta.create_all()
-
- def downgrade():
- # Operations to reverse the above upgrade go here.
- meta.drop_all()
- '''.replace("\n ", "\n")
- file = open(script_path, 'w')
- file.write(script_text)
- file.close()
- result = self.env.run('migrate test %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_version(repos_path), 1)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- @usedb()
- def test_rundiffs_in_shell(self):
- # This is a variant of the test_schemadiff tests but run through the shell level.
- # These shell tests are hard to debug (since they keep forking processes)
- # so they shouldn't replace the lower-level tests.
- repos_name = 'repos_name'
- repos_path = self.tmp()
- script_path = self.tmp_py()
- model_module = 'migrate.tests.fixture.models:meta_rundiffs'
- old_model_module = 'migrate.tests.fixture.models:meta_old_rundiffs'
-
- # Create empty repository.
- self.meta = MetaData(self.engine, reflect=True)
- self.meta.reflect()
- self.meta.drop_all() # in case junk tables are lying around in the test database
-
- result = self.env.run('migrate create %s %s' % (repos_path, repos_name))
- result = self.env.run('migrate drop_version_control %s %s' % (self.url, repos_path), expect_error=True)
- result = self.env.run('migrate version_control %s %s' % (self.url, repos_path))
- self.assertEquals(self.run_version(repos_path), 0)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0)
-
- # Setup helper script.
- result = self.env.run('migrate manage %s --repository=%s --url=%s --model=%s'\
- % (script_path, repos_path, self.url, model_module))
- self.assert_(os.path.exists(script_path))
-
- # Model is defined but database is empty.
- result = self.env.run('migrate compare_model_to_db %s %s --model=%s' \
- % (self.url, repos_path, model_module))
- self.assert_("tables missing from database: tmp_account_rundiffs" in result.stdout)
-
- # Test Deprecation
- result = self.env.run('migrate compare_model_to_db %s %s --model=%s' \
- % (self.url, repos_path, model_module.replace(":", ".")), expect_error=True)
- self.assertEqual(result.returncode, 0)
- self.assertTrue("DeprecationWarning" in result.stderr)
- self.assert_("tables missing from database: tmp_account_rundiffs" in result.stdout)
-
- # Update db to latest model.
- result = self.env.run('migrate update_db_from_model %s %s %s'\
- % (self.url, repos_path, model_module))
- self.assertEquals(self.run_version(repos_path), 0)
- self.assertEquals(self.run_db_version(self.url, repos_path), 0) # version did not get bumped yet because new version not yet created
-
- result = self.env.run('migrate compare_model_to_db %s %s %s'\
- % (self.url, repos_path, model_module))
- self.assert_("No schema diffs" in result.stdout)
-
- result = self.env.run('migrate drop_version_control %s %s' % (self.url, repos_path), expect_error=True)
- result = self.env.run('migrate version_control %s %s' % (self.url, repos_path))
-
- result = self.env.run('migrate create_model %s %s' % (self.url, repos_path))
- temp_dict = dict()
- exec result.stdout in temp_dict
-
- # TODO: breaks on SA06 and SA05 - in need of total refactor - use different approach
-
- # TODO: compare whole table
- self.compare_columns_equal(models.tmp_account_rundiffs.c, temp_dict['tmp_account_rundiffs'].c, ['type'])
- ##self.assertTrue("""tmp_account_rundiffs = Table('tmp_account_rundiffs', meta,
- ##Column('id', Integer(), primary_key=True, nullable=False),
- ##Column('login', String(length=None, convert_unicode=False, assert_unicode=None)),
- ##Column('passwd', String(length=None, convert_unicode=False, assert_unicode=None))""" in result.stdout)
-
- ## We're happy with db changes, make first db upgrade script to go from version 0 -> 1.
- #result = self.env.run('migrate make_update_script_for_model', expect_error=True)
- #self.assertTrue('Not enough arguments' in result.stderr)
-
- #result_script = self.env.run('migrate make_update_script_for_model %s %s %s %s'\
- #% (self.url, repos_path, old_model_module, model_module))
- #self.assertEqualsIgnoreWhitespace(result_script.stdout,
- #'''from sqlalchemy import *
- #from migrate import *
-
- #from migrate.changeset import schema
-
- #meta = MetaData()
- #tmp_account_rundiffs = Table('tmp_account_rundiffs', meta,
- #Column('id', Integer(), primary_key=True, nullable=False),
- #Column('login', Text(length=None, convert_unicode=False, assert_unicode=None, unicode_error=None, _warn_on_bytestring=False)),
- #Column('passwd', Text(length=None, convert_unicode=False, assert_unicode=None, unicode_error=None, _warn_on_bytestring=False)),
- #)
-
- #def upgrade(migrate_engine):
- ## Upgrade operations go here. Don't create your own engine; bind migrate_engine
- ## to your metadata
- #meta.bind = migrate_engine
- #tmp_account_rundiffs.create()
-
- #def downgrade(migrate_engine):
- ## Operations to reverse the above upgrade go here.
- #meta.bind = migrate_engine
- #tmp_account_rundiffs.drop()''')
-
- ## Save the upgrade script.
- #result = self.env.run('migrate script Desc %s' % repos_path)
- #upgrade_script_path = '%s/versions/001_Desc.py' % repos_path
- #open(upgrade_script_path, 'w').write(result_script.stdout)
-
- #result = self.env.run('migrate compare_model_to_db %s %s %s'\
- #% (self.url, repos_path, model_module))
- #self.assert_("No schema diffs" in result.stdout)
-
- self.meta.drop_all() # in case junk tables are lying around in the test database
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_template.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_template.py
deleted file mode 100755
index 16bdc36b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_template.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-import os
-import shutil
-
-import migrate.versioning.templates
-from migrate.versioning.template import *
-from migrate.versioning import api
-
-from migrate.tests import fixture
-
-
-class TestTemplate(fixture.Pathed):
- def test_templates(self):
- """We can find the path to all repository templates"""
- path = str(Template())
- self.assert_(os.path.exists(path))
-
- def test_repository(self):
- """We can find the path to the default repository"""
- path = Template().get_repository()
- self.assert_(os.path.exists(path))
-
- def test_script(self):
- """We can find the path to the default migration script"""
- path = Template().get_script()
- self.assert_(os.path.exists(path))
-
- def test_custom_templates_and_themes(self):
- """Users can define their own templates with themes"""
- new_templates_dir = os.path.join(self.temp_usable_dir, 'templates')
- manage_tmpl_file = os.path.join(new_templates_dir, 'manage/custom.py_tmpl')
- repository_tmpl_file = os.path.join(new_templates_dir, 'repository/custom/README')
- script_tmpl_file = os.path.join(new_templates_dir, 'script/custom.py_tmpl')
- sql_script_tmpl_file = os.path.join(new_templates_dir, 'sql_script/custom.py_tmpl')
-
- MANAGE_CONTENTS = 'print "manage.py"'
- README_CONTENTS = 'MIGRATE README!'
- SCRIPT_FILE_CONTENTS = 'print "script.py"'
- new_repo_dest = self.tmp_repos()
- new_manage_dest = self.tmp_py()
-
- # make new templates dir
- shutil.copytree(migrate.versioning.templates.__path__[0], new_templates_dir)
- shutil.copytree(os.path.join(new_templates_dir, 'repository/default'),
- os.path.join(new_templates_dir, 'repository/custom'))
-
- # edit templates
- f = open(manage_tmpl_file, 'w').write(MANAGE_CONTENTS)
- f = open(repository_tmpl_file, 'w').write(README_CONTENTS)
- f = open(script_tmpl_file, 'w').write(SCRIPT_FILE_CONTENTS)
- f = open(sql_script_tmpl_file, 'w').write(SCRIPT_FILE_CONTENTS)
-
- # create repository, manage file and python script
- kw = {}
- kw['templates_path'] = new_templates_dir
- kw['templates_theme'] = 'custom'
- api.create(new_repo_dest, 'repo_name', **kw)
- api.script('test', new_repo_dest, **kw)
- api.script_sql('postgres', 'foo', new_repo_dest, **kw)
- api.manage(new_manage_dest, **kw)
-
- # assert changes
- self.assertEqual(open(new_manage_dest).read(), MANAGE_CONTENTS)
- self.assertEqual(open(os.path.join(new_repo_dest, 'manage.py')).read(), MANAGE_CONTENTS)
- self.assertEqual(open(os.path.join(new_repo_dest, 'README')).read(), README_CONTENTS)
- self.assertEqual(open(os.path.join(new_repo_dest, 'versions/001_test.py')).read(), SCRIPT_FILE_CONTENTS)
- self.assertEqual(open(os.path.join(new_repo_dest, 'versions/002_foo_postgres_downgrade.sql')).read(), SCRIPT_FILE_CONTENTS)
- self.assertEqual(open(os.path.join(new_repo_dest, 'versions/002_foo_postgres_upgrade.sql')).read(), SCRIPT_FILE_CONTENTS)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_util.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_util.py
deleted file mode 100755
index 28015d0c..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_util.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-
-from sqlalchemy import *
-
-from migrate.exceptions import MigrateDeprecationWarning
-from migrate.tests import fixture
-from migrate.tests.fixture.warnings import catch_warnings
-from migrate.versioning.util import *
-
-import warnings
-
-class TestUtil(fixture.Pathed):
-
- def test_construct_engine(self):
- """Construct engine the smart way"""
- url = 'sqlite://'
-
- engine = construct_engine(url)
- self.assert_(engine.name == 'sqlite')
-
- # keyword arg
- engine = construct_engine(url, engine_arg_encoding='utf-8')
- self.assertEquals(engine.dialect.encoding, 'utf-8')
-
- # dict
- engine = construct_engine(url, engine_dict={'encoding': 'utf-8'})
- self.assertEquals(engine.dialect.encoding, 'utf-8')
-
- # engine parameter
- engine_orig = create_engine('sqlite://')
- engine = construct_engine(engine_orig)
- self.assertEqual(engine, engine_orig)
-
- # test precedance
- engine = construct_engine(url, engine_dict={'encoding': 'iso-8859-1'},
- engine_arg_encoding='utf-8')
- self.assertEquals(engine.dialect.encoding, 'utf-8')
-
- # deprecated echo=True parameter
- try:
- # py 2.4 compatability :-/
- cw = catch_warnings(record=True)
- w = cw.__enter__()
-
- warnings.simplefilter("always")
- engine = construct_engine(url, echo='True')
- self.assertTrue(engine.echo)
-
- self.assertEqual(len(w),1)
- self.assertTrue(issubclass(w[-1].category,
- MigrateDeprecationWarning))
- self.assertEqual(
- 'echo=True parameter is deprecated, pass '
- 'engine_arg_echo=True or engine_dict={"echo": True}',
- str(w[-1].message))
-
- finally:
- cw.__exit__()
-
- # unsupported argument
- self.assertRaises(ValueError, construct_engine, 1)
-
- def test_asbool(self):
- """test asbool parsing"""
- result = asbool(True)
- self.assertEqual(result, True)
-
- result = asbool(False)
- self.assertEqual(result, False)
-
- result = asbool('y')
- self.assertEqual(result, True)
-
- result = asbool('n')
- self.assertEqual(result, False)
-
- self.assertRaises(ValueError, asbool, 'test')
- self.assertRaises(ValueError, asbool, object)
-
-
- def test_load_model(self):
- """load model from dotted name"""
- model_path = os.path.join(self.temp_usable_dir, 'test_load_model.py')
-
- f = open(model_path, 'w')
- f.write("class FakeFloat(int): pass")
- f.close()
-
- try:
- # py 2.4 compatability :-/
- cw = catch_warnings(record=True)
- w = cw.__enter__()
-
- warnings.simplefilter("always")
-
- # deprecated spelling
- FakeFloat = load_model('test_load_model.FakeFloat')
- self.assert_(isinstance(FakeFloat(), int))
-
- self.assertEqual(len(w),1)
- self.assertTrue(issubclass(w[-1].category,
- MigrateDeprecationWarning))
- self.assertEqual(
- 'model should be in form of module.model:User '
- 'and not module.model.User',
- str(w[-1].message))
-
- finally:
- cw.__exit__()
-
- FakeFloat = load_model('test_load_model:FakeFloat')
- self.assert_(isinstance(FakeFloat(), int))
-
- FakeFloat = load_model(FakeFloat)
- self.assert_(isinstance(FakeFloat(), int))
-
- def test_guess_obj_type(self):
- """guess object type from string"""
- result = guess_obj_type('7')
- self.assertEqual(result, 7)
-
- result = guess_obj_type('y')
- self.assertEqual(result, True)
-
- result = guess_obj_type('test')
- self.assertEqual(result, 'test')
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_version.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_version.py
deleted file mode 100755
index 253642fc..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/tests/versioning/test_version.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from migrate.exceptions import *
-from migrate.versioning.version import *
-
-from migrate.tests import fixture
-
-
-class TestVerNum(fixture.Base):
- def test_invalid(self):
- """Disallow invalid version numbers"""
- versions = ('-1', -1, 'Thirteen', '')
- for version in versions:
- self.assertRaises(ValueError, VerNum, version)
-
- def test_str(self):
- """Test str and repr version numbers"""
- self.assertEqual(str(VerNum(2)), '2')
- self.assertEqual(repr(VerNum(2)), '<VerNum(2)>')
-
- def test_is(self):
- """Two version with the same number should be equal"""
- a = VerNum(1)
- b = VerNum(1)
- self.assert_(a is b)
-
- self.assertEqual(VerNum(VerNum(2)), VerNum(2))
-
- def test_add(self):
- self.assertEqual(VerNum(1) + VerNum(1), VerNum(2))
- self.assertEqual(VerNum(1) + 1, 2)
- self.assertEqual(VerNum(1) + 1, '2')
- self.assert_(isinstance(VerNum(1) + 1, VerNum))
-
- def test_sub(self):
- self.assertEqual(VerNum(1) - 1, 0)
- self.assert_(isinstance(VerNum(1) - 1, VerNum))
- self.assertRaises(ValueError, lambda: VerNum(0) - 1)
-
- def test_eq(self):
- """Two versions are equal"""
- self.assertEqual(VerNum(1), VerNum('1'))
- self.assertEqual(VerNum(1), 1)
- self.assertEqual(VerNum(1), '1')
- self.assertNotEqual(VerNum(1), 2)
-
- def test_ne(self):
- self.assert_(VerNum(1) != 2)
- self.assertFalse(VerNum(1) != 1)
-
- def test_lt(self):
- self.assertFalse(VerNum(1) < 1)
- self.assert_(VerNum(1) < 2)
- self.assertFalse(VerNum(2) < 1)
-
- def test_le(self):
- self.assert_(VerNum(1) <= 1)
- self.assert_(VerNum(1) <= 2)
- self.assertFalse(VerNum(2) <= 1)
-
- def test_gt(self):
- self.assertFalse(VerNum(1) > 1)
- self.assertFalse(VerNum(1) > 2)
- self.assert_(VerNum(2) > 1)
-
- def test_ge(self):
- self.assert_(VerNum(1) >= 1)
- self.assert_(VerNum(2) >= 1)
- self.assertFalse(VerNum(1) >= 2)
-
-
-class TestVersion(fixture.Pathed):
-
- def setUp(self):
- super(TestVersion, self).setUp()
-
- def test_str_to_filename(self):
- self.assertEquals(str_to_filename(''), '')
- self.assertEquals(str_to_filename('__'), '_')
- self.assertEquals(str_to_filename('a'), 'a')
- self.assertEquals(str_to_filename('Abc Def'), 'Abc_Def')
- self.assertEquals(str_to_filename('Abc "D" Ef'), 'Abc_D_Ef')
- self.assertEquals(str_to_filename("Abc's Stuff"), 'Abc_s_Stuff')
- self.assertEquals(str_to_filename("a b"), 'a_b')
- self.assertEquals(str_to_filename("a.b to c"), 'a_b_to_c')
-
- def test_collection(self):
- """Let's see how we handle versions collection"""
- coll = Collection(self.temp_usable_dir)
- coll.create_new_python_version("foo bar")
- coll.create_new_sql_version("postgres", "foo bar")
- coll.create_new_sql_version("sqlite", "foo bar")
- coll.create_new_python_version("")
-
- self.assertEqual(coll.latest, 4)
- self.assertEqual(len(coll.versions), 4)
- self.assertEqual(coll.version(4), coll.version(coll.latest))
-
- coll2 = Collection(self.temp_usable_dir)
- self.assertEqual(coll.versions, coll2.versions)
-
- Collection.clear()
-
- def test_old_repository(self):
- open(os.path.join(self.temp_usable_dir, '1'), 'w')
- self.assertRaises(Exception, Collection, self.temp_usable_dir)
-
- #TODO: def test_collection_unicode(self):
- # pass
-
- def test_create_new_python_version(self):
- coll = Collection(self.temp_usable_dir)
- coll.create_new_python_version("'")
-
- ver = coll.version()
- self.assert_(ver.script().source())
-
- def test_create_new_sql_version(self):
- coll = Collection(self.temp_usable_dir)
- coll.create_new_sql_version("sqlite", "foo bar")
-
- ver = coll.version()
- ver_up = ver.script('sqlite', 'upgrade')
- ver_down = ver.script('sqlite', 'downgrade')
- ver_up.source()
- ver_down.source()
-
- def test_selection(self):
- """Verify right sql script is selected"""
-
- # Create empty directory.
- path = self.tmp_repos()
- os.mkdir(path)
-
- # Create files -- files must be present or you'll get an exception later.
- python_file = '001_initial_.py'
- sqlite_upgrade_file = '001_sqlite_upgrade.sql'
- default_upgrade_file = '001_default_upgrade.sql'
- for file_ in [sqlite_upgrade_file, default_upgrade_file, python_file]:
- filepath = '%s/%s' % (path, file_)
- open(filepath, 'w').close()
-
- ver = Version(1, path, [sqlite_upgrade_file])
- self.assertEquals(os.path.basename(ver.script('sqlite', 'upgrade').path), sqlite_upgrade_file)
-
- ver = Version(1, path, [default_upgrade_file])
- self.assertEquals(os.path.basename(ver.script('default', 'upgrade').path), default_upgrade_file)
-
- ver = Version(1, path, [sqlite_upgrade_file, default_upgrade_file])
- self.assertEquals(os.path.basename(ver.script('sqlite', 'upgrade').path), sqlite_upgrade_file)
-
- ver = Version(1, path, [sqlite_upgrade_file, default_upgrade_file, python_file])
- self.assertEquals(os.path.basename(ver.script('postgres', 'upgrade').path), default_upgrade_file)
-
- ver = Version(1, path, [sqlite_upgrade_file, python_file])
- self.assertEquals(os.path.basename(ver.script('postgres', 'upgrade').path), python_file)
-
- def test_bad_version(self):
- ver = Version(1, self.temp_usable_dir, [])
- self.assertRaises(ScriptError, ver.add_script, '123.sql')
-
- pyscript = os.path.join(self.temp_usable_dir, 'bla.py')
- open(pyscript, 'w')
- ver.add_script(pyscript)
- self.assertRaises(ScriptError, ver.add_script, 'bla.py')
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/__init__.py
deleted file mode 100755
index 8b5a7363..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-"""
- This package provides functionality to create and manage
- repositories of database schema changesets and to apply these
- changesets to databases.
-"""
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/api.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/api.py
deleted file mode 100755
index 570dc086..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/api.py
+++ /dev/null
@@ -1,384 +0,0 @@
-"""
- This module provides an external API to the versioning system.
-
- .. versionchanged:: 0.6.0
- :func:`migrate.versioning.api.test` and schema diff functions
- changed order of positional arguments so all accept `url` and `repository`
- as first arguments.
-
- .. versionchanged:: 0.5.4
- ``--preview_sql`` displays source file when using SQL scripts.
- If Python script is used, it runs the action with mocked engine and
- returns captured SQL statements.
-
- .. versionchanged:: 0.5.4
- Deprecated ``--echo`` parameter in favour of new
- :func:`migrate.versioning.util.construct_engine` behavior.
-"""
-
-# Dear migrate developers,
-#
-# please do not comment this module using sphinx syntax because its
-# docstrings are presented as user help and most users cannot
-# interpret sphinx annotated ReStructuredText.
-#
-# Thanks,
-# Jan Dittberner
-
-import sys
-import inspect
-import logging
-
-from migrate import exceptions
-from migrate.versioning import (repository, schema, version,
- script as script_) # command name conflict
-from migrate.versioning.util import catch_known_errors, with_engine
-
-
-log = logging.getLogger(__name__)
-command_desc = {
- 'help': 'displays help on a given command',
- 'create': 'create an empty repository at the specified path',
- 'script': 'create an empty change Python script',
- 'script_sql': 'create empty change SQL scripts for given database',
- 'version': 'display the latest version available in a repository',
- 'db_version': 'show the current version of the repository under version control',
- 'source': 'display the Python code for a particular version in this repository',
- 'version_control': 'mark a database as under this repository\'s version control',
- 'upgrade': 'upgrade a database to a later version',
- 'downgrade': 'downgrade a database to an earlier version',
- 'drop_version_control': 'removes version control from a database',
- 'manage': 'creates a Python script that runs Migrate with a set of default values',
- 'test': 'performs the upgrade and downgrade command on the given database',
- 'compare_model_to_db': 'compare MetaData against the current database state',
- 'create_model': 'dump the current database as a Python model to stdout',
- 'make_update_script_for_model': 'create a script changing the old MetaData to the new (current) MetaData',
- 'update_db_from_model': 'modify the database to match the structure of the current MetaData',
-}
-__all__ = command_desc.keys()
-
-Repository = repository.Repository
-ControlledSchema = schema.ControlledSchema
-VerNum = version.VerNum
-PythonScript = script_.PythonScript
-SqlScript = script_.SqlScript
-
-
-# deprecated
-def help(cmd=None, **opts):
- """%prog help COMMAND
-
- Displays help on a given command.
- """
- if cmd is None:
- raise exceptions.UsageError(None)
- try:
- func = globals()[cmd]
- except:
- raise exceptions.UsageError(
- "'%s' isn't a valid command. Try 'help COMMAND'" % cmd)
- ret = func.__doc__
- if sys.argv[0]:
- ret = ret.replace('%prog', sys.argv[0])
- return ret
-
-@catch_known_errors
-def create(repository, name, **opts):
- """%prog create REPOSITORY_PATH NAME [--table=TABLE]
-
- Create an empty repository at the specified path.
-
- You can specify the version_table to be used; by default, it is
- 'migrate_version'. This table is created in all version-controlled
- databases.
- """
- repo_path = Repository.create(repository, name, **opts)
-
-
-@catch_known_errors
-def script(description, repository, **opts):
- """%prog script DESCRIPTION REPOSITORY_PATH
-
- Create an empty change script using the next unused version number
- appended with the given description.
-
- For instance, manage.py script "Add initial tables" creates:
- repository/versions/001_Add_initial_tables.py
- """
- repo = Repository(repository)
- repo.create_script(description, **opts)
-
-
-@catch_known_errors
-def script_sql(database, description, repository, **opts):
- """%prog script_sql DATABASE DESCRIPTION REPOSITORY_PATH
-
- Create empty change SQL scripts for given DATABASE, where DATABASE
- is either specific ('postgresql', 'mysql', 'oracle', 'sqlite', etc.)
- or generic ('default').
-
- For instance, manage.py script_sql postgresql description creates:
- repository/versions/001_description_postgresql_upgrade.sql and
- repository/versions/001_description_postgresql_downgrade.sql
- """
- repo = Repository(repository)
- repo.create_script_sql(database, description, **opts)
-
-
-def version(repository, **opts):
- """%prog version REPOSITORY_PATH
-
- Display the latest version available in a repository.
- """
- repo = Repository(repository)
- return repo.latest
-
-
-@with_engine
-def db_version(url, repository, **opts):
- """%prog db_version URL REPOSITORY_PATH
-
- Show the current version of the repository with the given
- connection string, under version control of the specified
- repository.
-
- The url should be any valid SQLAlchemy connection string.
- """
- engine = opts.pop('engine')
- schema = ControlledSchema(engine, repository)
- return schema.version
-
-
-def source(version, dest=None, repository=None, **opts):
- """%prog source VERSION [DESTINATION] --repository=REPOSITORY_PATH
-
- Display the Python code for a particular version in this
- repository. Save it to the file at DESTINATION or, if omitted,
- send to stdout.
- """
- if repository is None:
- raise exceptions.UsageError("A repository must be specified")
- repo = Repository(repository)
- ret = repo.version(version).script().source()
- if dest is not None:
- dest = open(dest, 'w')
- dest.write(ret)
- dest.close()
- ret = None
- return ret
-
-
-def upgrade(url, repository, version=None, **opts):
- """%prog upgrade URL REPOSITORY_PATH [VERSION] [--preview_py|--preview_sql]
-
- Upgrade a database to a later version.
-
- This runs the upgrade() function defined in your change scripts.
-
- By default, the database is updated to the latest available
- version. You may specify a version instead, if you wish.
-
- You may preview the Python or SQL code to be executed, rather than
- actually executing it, using the appropriate 'preview' option.
- """
- err = "Cannot upgrade a database of version %s to version %s. "\
- "Try 'downgrade' instead."
- return _migrate(url, repository, version, upgrade=True, err=err, **opts)
-
-
-def downgrade(url, repository, version, **opts):
- """%prog downgrade URL REPOSITORY_PATH VERSION [--preview_py|--preview_sql]
-
- Downgrade a database to an earlier version.
-
- This is the reverse of upgrade; this runs the downgrade() function
- defined in your change scripts.
-
- You may preview the Python or SQL code to be executed, rather than
- actually executing it, using the appropriate 'preview' option.
- """
- err = "Cannot downgrade a database of version %s to version %s. "\
- "Try 'upgrade' instead."
- return _migrate(url, repository, version, upgrade=False, err=err, **opts)
-
-@with_engine
-def test(url, repository, **opts):
- """%prog test URL REPOSITORY_PATH [VERSION]
-
- Performs the upgrade and downgrade option on the given
- database. This is not a real test and may leave the database in a
- bad state. You should therefore better run the test on a copy of
- your database.
- """
- engine = opts.pop('engine')
- repos = Repository(repository)
-
- # Upgrade
- log.info("Upgrading...")
- script = repos.version(None).script(engine.name, 'upgrade')
- script.run(engine, 1)
- log.info("done")
-
- log.info("Downgrading...")
- script = repos.version(None).script(engine.name, 'downgrade')
- script.run(engine, -1)
- log.info("done")
- log.info("Success")
-
-
-@with_engine
-def version_control(url, repository, version=None, **opts):
- """%prog version_control URL REPOSITORY_PATH [VERSION]
-
- Mark a database as under this repository's version control.
-
- Once a database is under version control, schema changes should
- only be done via change scripts in this repository.
-
- This creates the table version_table in the database.
-
- The url should be any valid SQLAlchemy connection string.
-
- By default, the database begins at version 0 and is assumed to be
- empty. If the database is not empty, you may specify a version at
- which to begin instead. No attempt is made to verify this
- version's correctness - the database schema is expected to be
- identical to what it would be if the database were created from
- scratch.
- """
- engine = opts.pop('engine')
- ControlledSchema.create(engine, repository, version)
-
-
-@with_engine
-def drop_version_control(url, repository, **opts):
- """%prog drop_version_control URL REPOSITORY_PATH
-
- Removes version control from a database.
- """
- engine = opts.pop('engine')
- schema = ControlledSchema(engine, repository)
- schema.drop()
-
-
-def manage(file, **opts):
- """%prog manage FILENAME [VARIABLES...]
-
- Creates a script that runs Migrate with a set of default values.
-
- For example::
-
- %prog manage manage.py --repository=/path/to/repository \
---url=sqlite:///project.db
-
- would create the script manage.py. The following two commands
- would then have exactly the same results::
-
- python manage.py version
- %prog version --repository=/path/to/repository
- """
- Repository.create_manage_file(file, **opts)
-
-
-@with_engine
-def compare_model_to_db(url, repository, model, **opts):
- """%prog compare_model_to_db URL REPOSITORY_PATH MODEL
-
- Compare the current model (assumed to be a module level variable
- of type sqlalchemy.MetaData) against the current database.
-
- NOTE: This is EXPERIMENTAL.
- """ # TODO: get rid of EXPERIMENTAL label
- engine = opts.pop('engine')
- return ControlledSchema.compare_model_to_db(engine, model, repository)
-
-
-@with_engine
-def create_model(url, repository, **opts):
- """%prog create_model URL REPOSITORY_PATH [DECLERATIVE=True]
-
- Dump the current database as a Python model to stdout.
-
- NOTE: This is EXPERIMENTAL.
- """ # TODO: get rid of EXPERIMENTAL label
- engine = opts.pop('engine')
- declarative = opts.get('declarative', False)
- return ControlledSchema.create_model(engine, repository, declarative)
-
-
-@catch_known_errors
-@with_engine
-def make_update_script_for_model(url, repository, oldmodel, model, **opts):
- """%prog make_update_script_for_model URL OLDMODEL MODEL REPOSITORY_PATH
-
- Create a script changing the old Python model to the new (current)
- Python model, sending to stdout.
-
- NOTE: This is EXPERIMENTAL.
- """ # TODO: get rid of EXPERIMENTAL label
- engine = opts.pop('engine')
- return PythonScript.make_update_script_for_model(
- engine, oldmodel, model, repository, **opts)
-
-
-@with_engine
-def update_db_from_model(url, repository, model, **opts):
- """%prog update_db_from_model URL REPOSITORY_PATH MODEL
-
- Modify the database to match the structure of the current Python
- model. This also sets the db_version number to the latest in the
- repository.
-
- NOTE: This is EXPERIMENTAL.
- """ # TODO: get rid of EXPERIMENTAL label
- engine = opts.pop('engine')
- schema = ControlledSchema(engine, repository)
- schema.update_db_from_model(model)
-
-@with_engine
-def _migrate(url, repository, version, upgrade, err, **opts):
- engine = opts.pop('engine')
- url = str(engine.url)
- schema = ControlledSchema(engine, repository)
- version = _migrate_version(schema, version, upgrade, err)
-
- changeset = schema.changeset(version)
- for ver, change in changeset:
- nextver = ver + changeset.step
- log.info('%s -> %s... ', ver, nextver)
-
- if opts.get('preview_sql'):
- if isinstance(change, PythonScript):
- log.info(change.preview_sql(url, changeset.step, **opts))
- elif isinstance(change, SqlScript):
- log.info(change.source())
-
- elif opts.get('preview_py'):
- if not isinstance(change, PythonScript):
- raise exceptions.UsageError("Python source can be only displayed"
- " for python migration files")
- source_ver = max(ver, nextver)
- module = schema.repository.version(source_ver).script().module
- funcname = upgrade and "upgrade" or "downgrade"
- func = getattr(module, funcname)
- log.info(inspect.getsource(func))
- else:
- schema.runchange(ver, change, changeset.step)
- log.info('done')
-
-
-def _migrate_version(schema, version, upgrade, err):
- if version is None:
- return version
- # Version is specified: ensure we're upgrading in the right direction
- # (current version < target version for upgrading; reverse for down)
- version = VerNum(version)
- cur = schema.version
- if upgrade is not None:
- if upgrade:
- direction = cur <= version
- else:
- direction = cur >= version
- if not direction:
- raise exceptions.KnownError(err % (cur, version))
- return version
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/cfgparse.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/cfgparse.py
deleted file mode 100755
index ff27d672..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/cfgparse.py
+++ /dev/null
@@ -1,27 +0,0 @@
-"""
- Configuration parser module.
-"""
-
-from ConfigParser import ConfigParser
-
-from migrate.versioning.config import *
-from migrate.versioning import pathed
-
-
-class Parser(ConfigParser):
- """A project configuration file."""
-
- def to_dict(self, sections=None):
- """It's easier to access config values like dictionaries"""
- return self._sections
-
-
-class Config(pathed.Pathed, Parser):
- """Configuration class."""
-
- def __init__(self, path, *p, **k):
- """Confirm the config file exists; read it."""
- self.require_found(path)
- pathed.Pathed.__init__(self, path)
- Parser.__init__(self, *p, **k)
- self.read(path)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/config.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/config.py
deleted file mode 100755
index 2429fd8b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/config.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-from sqlalchemy.util import OrderedDict
-
-
-__all__ = ['databases', 'operations']
-
-databases = ('sqlite', 'postgres', 'mysql', 'oracle', 'mssql', 'firebird')
-
-# Map operation names to function names
-operations = OrderedDict()
-operations['upgrade'] = 'upgrade'
-operations['downgrade'] = 'downgrade'
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/genmodel.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/genmodel.py
deleted file mode 100755
index 85df6276..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/genmodel.py
+++ /dev/null
@@ -1,285 +0,0 @@
-"""
-Code to generate a Python model from a database or differences
-between a model and database.
-
-Some of this is borrowed heavily from the AutoCode project at:
-http://code.google.com/p/sqlautocode/
-"""
-
-import sys
-import logging
-
-import sqlalchemy
-
-import migrate
-import migrate.changeset
-
-
-log = logging.getLogger(__name__)
-HEADER = """
-## File autogenerated by genmodel.py
-
-from sqlalchemy import *
-meta = MetaData()
-"""
-
-DECLARATIVE_HEADER = """
-## File autogenerated by genmodel.py
-
-from sqlalchemy import *
-from sqlalchemy.ext import declarative
-
-Base = declarative.declarative_base()
-"""
-
-
-class ModelGenerator(object):
- """Various transformations from an A, B diff.
-
- In the implementation, A tends to be called the model and B
- the database (although this is not true of all diffs).
- The diff is directionless, but transformations apply the diff
- in a particular direction, described in the method name.
- """
-
- def __init__(self, diff, engine, declarative=False):
- self.diff = diff
- self.engine = engine
- self.declarative = declarative
-
- def column_repr(self, col):
- kwarg = []
- if col.key != col.name:
- kwarg.append('key')
- if col.primary_key:
- col.primary_key = True # otherwise it dumps it as 1
- kwarg.append('primary_key')
- if not col.nullable:
- kwarg.append('nullable')
- if col.onupdate:
- kwarg.append('onupdate')
- if col.default:
- if col.primary_key:
- # I found that PostgreSQL automatically creates a
- # default value for the sequence, but let's not show
- # that.
- pass
- else:
- kwarg.append('default')
- args = ['%s=%r' % (k, getattr(col, k)) for k in kwarg]
-
- # crs: not sure if this is good idea, but it gets rid of extra
- # u''
- name = col.name.encode('utf8')
-
- type_ = col.type
- for cls in col.type.__class__.__mro__:
- if cls.__module__ == 'sqlalchemy.types' and \
- not cls.__name__.isupper():
- if cls is not type_.__class__:
- type_ = cls()
- break
-
- type_repr = repr(type_)
- if type_repr.endswith('()'):
- type_repr = type_repr[:-2]
-
- constraints = [repr(cn) for cn in col.constraints]
-
- data = {
- 'name': name,
- 'commonStuff': ', '.join([type_repr] + constraints + args),
- }
-
- if self.declarative:
- return """%(name)s = Column(%(commonStuff)s)""" % data
- else:
- return """Column(%(name)r, %(commonStuff)s)""" % data
-
- def _getTableDefn(self, table, metaName='meta'):
- out = []
- tableName = table.name
- if self.declarative:
- out.append("class %(table)s(Base):" % {'table': tableName})
- out.append(" __tablename__ = '%(table)s'\n" %
- {'table': tableName})
- for col in table.columns:
- out.append(" %s" % self.column_repr(col))
- out.append('\n')
- else:
- out.append("%(table)s = Table('%(table)s', %(meta)s," %
- {'table': tableName, 'meta': metaName})
- for col in table.columns:
- out.append(" %s," % self.column_repr(col))
- out.append(")\n")
- return out
-
- def _get_tables(self,missingA=False,missingB=False,modified=False):
- to_process = []
- for bool_,names,metadata in (
- (missingA,self.diff.tables_missing_from_A,self.diff.metadataB),
- (missingB,self.diff.tables_missing_from_B,self.diff.metadataA),
- (modified,self.diff.tables_different,self.diff.metadataA),
- ):
- if bool_:
- for name in names:
- yield metadata.tables.get(name)
-
- def genBDefinition(self):
- """Generates the source code for a definition of B.
-
- Assumes a diff where A is empty.
-
- Was: toPython. Assume database (B) is current and model (A) is empty.
- """
-
- out = []
- if self.declarative:
- out.append(DECLARATIVE_HEADER)
- else:
- out.append(HEADER)
- out.append("")
- for table in self._get_tables(missingA=True):
- out.extend(self._getTableDefn(table))
- return '\n'.join(out)
-
- def genB2AMigration(self, indent=' '):
- '''Generate a migration from B to A.
-
- Was: toUpgradeDowngradePython
- Assume model (A) is most current and database (B) is out-of-date.
- '''
-
- decls = ['from migrate.changeset import schema',
- 'pre_meta = MetaData()',
- 'post_meta = MetaData()',
- ]
- upgradeCommands = ['pre_meta.bind = migrate_engine',
- 'post_meta.bind = migrate_engine']
- downgradeCommands = list(upgradeCommands)
-
- for tn in self.diff.tables_missing_from_A:
- pre_table = self.diff.metadataB.tables[tn]
- decls.extend(self._getTableDefn(pre_table, metaName='pre_meta'))
- upgradeCommands.append(
- "pre_meta.tables[%(table)r].drop()" % {'table': tn})
- downgradeCommands.append(
- "pre_meta.tables[%(table)r].create()" % {'table': tn})
-
- for tn in self.diff.tables_missing_from_B:
- post_table = self.diff.metadataA.tables[tn]
- decls.extend(self._getTableDefn(post_table, metaName='post_meta'))
- upgradeCommands.append(
- "post_meta.tables[%(table)r].create()" % {'table': tn})
- downgradeCommands.append(
- "post_meta.tables[%(table)r].drop()" % {'table': tn})
-
- for (tn, td) in self.diff.tables_different.iteritems():
- if td.columns_missing_from_A or td.columns_different:
- pre_table = self.diff.metadataB.tables[tn]
- decls.extend(self._getTableDefn(
- pre_table, metaName='pre_meta'))
- if td.columns_missing_from_B or td.columns_different:
- post_table = self.diff.metadataA.tables[tn]
- decls.extend(self._getTableDefn(
- post_table, metaName='post_meta'))
-
- for col in td.columns_missing_from_A:
- upgradeCommands.append(
- 'pre_meta.tables[%r].columns[%r].drop()' % (tn, col))
- downgradeCommands.append(
- 'pre_meta.tables[%r].columns[%r].create()' % (tn, col))
- for col in td.columns_missing_from_B:
- upgradeCommands.append(
- 'post_meta.tables[%r].columns[%r].create()' % (tn, col))
- downgradeCommands.append(
- 'post_meta.tables[%r].columns[%r].drop()' % (tn, col))
- for modelCol, databaseCol, modelDecl, databaseDecl in td.columns_different:
- upgradeCommands.append(
- 'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
- tn, modelCol.name, databaseCol.name))
- downgradeCommands.append(
- 'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
- tn, modelCol.name, databaseCol.name))
-
- return (
- '\n'.join(decls),
- '\n'.join('%s%s' % (indent, line) for line in upgradeCommands),
- '\n'.join('%s%s' % (indent, line) for line in downgradeCommands))
-
- def _db_can_handle_this_change(self,td):
- """Check if the database can handle going from B to A."""
-
- if (td.columns_missing_from_B
- and not td.columns_missing_from_A
- and not td.columns_different):
- # Even sqlite can handle column additions.
- return True
- else:
- return not self.engine.url.drivername.startswith('sqlite')
-
- def runB2A(self):
- """Goes from B to A.
-
- Was: applyModel. Apply model (A) to current database (B).
- """
-
- meta = sqlalchemy.MetaData(self.engine)
-
- for table in self._get_tables(missingA=True):
- table = table.tometadata(meta)
- table.drop()
- for table in self._get_tables(missingB=True):
- table = table.tometadata(meta)
- table.create()
- for modelTable in self._get_tables(modified=True):
- tableName = modelTable.name
- modelTable = modelTable.tometadata(meta)
- dbTable = self.diff.metadataB.tables[tableName]
-
- td = self.diff.tables_different[tableName]
-
- if self._db_can_handle_this_change(td):
-
- for col in td.columns_missing_from_B:
- modelTable.columns[col].create()
- for col in td.columns_missing_from_A:
- dbTable.columns[col].drop()
- # XXX handle column changes here.
- else:
- # Sqlite doesn't support drop column, so you have to
- # do more: create temp table, copy data to it, drop
- # old table, create new table, copy data back.
- #
- # I wonder if this is guaranteed to be unique?
- tempName = '_temp_%s' % modelTable.name
-
- def getCopyStatement():
- preparer = self.engine.dialect.preparer
- commonCols = []
- for modelCol in modelTable.columns:
- if modelCol.name in dbTable.columns:
- commonCols.append(modelCol.name)
- commonColsStr = ', '.join(commonCols)
- return 'INSERT INTO %s (%s) SELECT %s FROM %s' % \
- (tableName, commonColsStr, commonColsStr, tempName)
-
- # Move the data in one transaction, so that we don't
- # leave the database in a nasty state.
- connection = self.engine.connect()
- trans = connection.begin()
- try:
- connection.execute(
- 'CREATE TEMPORARY TABLE %s as SELECT * from %s' % \
- (tempName, modelTable.name))
- # make sure the drop takes place inside our
- # transaction with the bind parameter
- modelTable.drop(bind=connection)
- modelTable.create(bind=connection)
- connection.execute(getCopyStatement())
- connection.execute('DROP TABLE %s' % tempName)
- trans.commit()
- except:
- trans.rollback()
- raise
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/migrate_repository.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/migrate_repository.py
deleted file mode 100755
index 53833bbc..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/migrate_repository.py
+++ /dev/null
@@ -1,100 +0,0 @@
-"""
- Script to migrate repository from sqlalchemy <= 0.4.4 to the new
- repository schema. This shouldn't use any other migrate modules, so
- that it can work in any version.
-"""
-
-import os
-import sys
-import logging
-
-log = logging.getLogger(__name__)
-
-
-def usage():
- """Gives usage information."""
- print """Usage: %(prog)s repository-to-migrate
-
- Upgrade your repository to the new flat format.
-
- NOTE: You should probably make a backup before running this.
- """ % {'prog': sys.argv[0]}
-
- sys.exit(1)
-
-
-def delete_file(filepath):
- """Deletes a file and prints a message."""
- log.info('Deleting file: %s' % filepath)
- os.remove(filepath)
-
-
-def move_file(src, tgt):
- """Moves a file and prints a message."""
- log.info('Moving file %s to %s' % (src, tgt))
- if os.path.exists(tgt):
- raise Exception(
- 'Cannot move file %s because target %s already exists' % \
- (src, tgt))
- os.rename(src, tgt)
-
-
-def delete_directory(dirpath):
- """Delete a directory and print a message."""
- log.info('Deleting directory: %s' % dirpath)
- os.rmdir(dirpath)
-
-
-def migrate_repository(repos):
- """Does the actual migration to the new repository format."""
- log.info('Migrating repository at: %s to new format' % repos)
- versions = '%s/versions' % repos
- dirs = os.listdir(versions)
- # Only use int's in list.
- numdirs = [int(dirname) for dirname in dirs if dirname.isdigit()]
- numdirs.sort() # Sort list.
- for dirname in numdirs:
- origdir = '%s/%s' % (versions, dirname)
- log.info('Working on directory: %s' % origdir)
- files = os.listdir(origdir)
- files.sort()
- for filename in files:
- # Delete compiled Python files.
- if filename.endswith('.pyc') or filename.endswith('.pyo'):
- delete_file('%s/%s' % (origdir, filename))
-
- # Delete empty __init__.py files.
- origfile = '%s/__init__.py' % origdir
- if os.path.exists(origfile) and len(open(origfile).read()) == 0:
- delete_file(origfile)
-
- # Move sql upgrade scripts.
- if filename.endswith('.sql'):
- version, dbms, operation = filename.split('.', 3)[0:3]
- origfile = '%s/%s' % (origdir, filename)
- # For instance: 2.postgres.upgrade.sql ->
- # 002_postgres_upgrade.sql
- tgtfile = '%s/%03d_%s_%s.sql' % (
- versions, int(version), dbms, operation)
- move_file(origfile, tgtfile)
-
- # Move Python upgrade script.
- pyfile = '%s.py' % dirname
- pyfilepath = '%s/%s' % (origdir, pyfile)
- if os.path.exists(pyfilepath):
- tgtfile = '%s/%03d.py' % (versions, int(dirname))
- move_file(pyfilepath, tgtfile)
-
- # Try to remove directory. Will fail if it's not empty.
- delete_directory(origdir)
-
-
-def main():
- """Main function to be called when using this script."""
- if len(sys.argv) != 2:
- usage()
- migrate_repository(sys.argv[1])
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/pathed.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/pathed.py
deleted file mode 100755
index fbee0e46..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/pathed.py
+++ /dev/null
@@ -1,75 +0,0 @@
-"""
- A path/directory class.
-"""
-
-import os
-import shutil
-import logging
-
-from migrate import exceptions
-from migrate.versioning.config import *
-from migrate.versioning.util import KeyedInstance
-
-
-log = logging.getLogger(__name__)
-
-class Pathed(KeyedInstance):
- """
- A class associated with a path/directory tree.
-
- Only one instance of this class may exist for a particular file;
- __new__ will return an existing instance if possible
- """
- parent = None
-
- @classmethod
- def _key(cls, path):
- return str(path)
-
- def __init__(self, path):
- self.path = path
- if self.__class__.parent is not None:
- self._init_parent(path)
-
- def _init_parent(self, path):
- """Try to initialize this object's parent, if it has one"""
- parent_path = self.__class__._parent_path(path)
- self.parent = self.__class__.parent(parent_path)
- log.debug("Getting parent %r:%r" % (self.__class__.parent, parent_path))
- self.parent._init_child(path, self)
-
- def _init_child(self, child, path):
- """Run when a child of this object is initialized.
-
- Parameters: the child object; the path to this object (its
- parent)
- """
-
- @classmethod
- def _parent_path(cls, path):
- """
- Fetch the path of this object's parent from this object's path.
- """
- # os.path.dirname(), but strip directories like files (like
- # unix basename)
- #
- # Treat directories like files...
- if path[-1] == '/':
- path = path[:-1]
- ret = os.path.dirname(path)
- return ret
-
- @classmethod
- def require_notfound(cls, path):
- """Ensures a given path does not already exist"""
- if os.path.exists(path):
- raise exceptions.PathFoundError(path)
-
- @classmethod
- def require_found(cls, path):
- """Ensures a given path already exists"""
- if not os.path.exists(path):
- raise exceptions.PathNotFoundError(path)
-
- def __str__(self):
- return self.path
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/repository.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/repository.py
deleted file mode 100755
index 6e2f678f..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/repository.py
+++ /dev/null
@@ -1,242 +0,0 @@
-"""
- SQLAlchemy migrate repository management.
-"""
-import os
-import shutil
-import string
-import logging
-
-from pkg_resources import resource_filename
-from tempita import Template as TempitaTemplate
-
-from migrate import exceptions
-from migrate.versioning import version, pathed, cfgparse
-from migrate.versioning.template import Template
-from migrate.versioning.config import *
-
-
-log = logging.getLogger(__name__)
-
-class Changeset(dict):
- """A collection of changes to be applied to a database.
-
- Changesets are bound to a repository and manage a set of
- scripts from that repository.
-
- Behaves like a dict, for the most part. Keys are ordered based on step value.
- """
-
- def __init__(self, start, *changes, **k):
- """
- Give a start version; step must be explicitly stated.
- """
- self.step = k.pop('step', 1)
- self.start = version.VerNum(start)
- self.end = self.start
- for change in changes:
- self.add(change)
-
- def __iter__(self):
- return iter(self.items())
-
- def keys(self):
- """
- In a series of upgrades x -> y, keys are version x. Sorted.
- """
- ret = super(Changeset, self).keys()
- # Reverse order if downgrading
- ret.sort(reverse=(self.step < 1))
- return ret
-
- def values(self):
- return [self[k] for k in self.keys()]
-
- def items(self):
- return zip(self.keys(), self.values())
-
- def add(self, change):
- """Add new change to changeset"""
- key = self.end
- self.end += self.step
- self[key] = change
-
- def run(self, *p, **k):
- """Run the changeset scripts"""
- for version, script in self:
- script.run(*p, **k)
-
-
-class Repository(pathed.Pathed):
- """A project's change script repository"""
-
- _config = 'migrate.cfg'
- _versions = 'versions'
-
- def __init__(self, path):
- log.debug('Loading repository %s...' % path)
- self.verify(path)
- super(Repository, self).__init__(path)
- self.config = cfgparse.Config(os.path.join(self.path, self._config))
- self.versions = version.Collection(os.path.join(self.path,
- self._versions))
- log.debug('Repository %s loaded successfully' % path)
- log.debug('Config: %r' % self.config.to_dict())
-
- @classmethod
- def verify(cls, path):
- """
- Ensure the target path is a valid repository.
-
- :raises: :exc:`InvalidRepositoryError <migrate.exceptions.InvalidRepositoryError>`
- """
- # Ensure the existence of required files
- try:
- cls.require_found(path)
- cls.require_found(os.path.join(path, cls._config))
- cls.require_found(os.path.join(path, cls._versions))
- except exceptions.PathNotFoundError, e:
- raise exceptions.InvalidRepositoryError(path)
-
- @classmethod
- def prepare_config(cls, tmpl_dir, name, options=None):
- """
- Prepare a project configuration file for a new project.
-
- :param tmpl_dir: Path to Repository template
- :param config_file: Name of the config file in Repository template
- :param name: Repository name
- :type tmpl_dir: string
- :type config_file: string
- :type name: string
- :returns: Populated config file
- """
- if options is None:
- options = {}
- options.setdefault('version_table', 'migrate_version')
- options.setdefault('repository_id', name)
- options.setdefault('required_dbs', [])
- options.setdefault('use_timestamp_numbering', False)
-
- tmpl = open(os.path.join(tmpl_dir, cls._config)).read()
- ret = TempitaTemplate(tmpl).substitute(options)
-
- # cleanup
- del options['__template_name__']
-
- return ret
-
- @classmethod
- def create(cls, path, name, **opts):
- """Create a repository at a specified path"""
- cls.require_notfound(path)
- theme = opts.pop('templates_theme', None)
- t_path = opts.pop('templates_path', None)
-
- # Create repository
- tmpl_dir = Template(t_path).get_repository(theme=theme)
- shutil.copytree(tmpl_dir, path)
-
- # Edit config defaults
- config_text = cls.prepare_config(tmpl_dir, name, options=opts)
- fd = open(os.path.join(path, cls._config), 'w')
- fd.write(config_text)
- fd.close()
-
- opts['repository_name'] = name
-
- # Create a management script
- manager = os.path.join(path, 'manage.py')
- Repository.create_manage_file(manager, templates_theme=theme,
- templates_path=t_path, **opts)
-
- return cls(path)
-
- def create_script(self, description, **k):
- """API to :meth:`migrate.versioning.version.Collection.create_new_python_version`"""
-
- k['use_timestamp_numbering'] = self.use_timestamp_numbering
- self.versions.create_new_python_version(description, **k)
-
- def create_script_sql(self, database, description, **k):
- """API to :meth:`migrate.versioning.version.Collection.create_new_sql_version`"""
- k['use_timestamp_numbering'] = self.use_timestamp_numbering
- self.versions.create_new_sql_version(database, description, **k)
-
- @property
- def latest(self):
- """API to :attr:`migrate.versioning.version.Collection.latest`"""
- return self.versions.latest
-
- @property
- def version_table(self):
- """Returns version_table name specified in config"""
- return self.config.get('db_settings', 'version_table')
-
- @property
- def id(self):
- """Returns repository id specified in config"""
- return self.config.get('db_settings', 'repository_id')
-
- @property
- def use_timestamp_numbering(self):
- """Returns use_timestamp_numbering specified in config"""
- if self.config.has_option('db_settings', 'use_timestamp_numbering'):
- return self.config.getboolean('db_settings', 'use_timestamp_numbering')
- return False
-
- def version(self, *p, **k):
- """API to :attr:`migrate.versioning.version.Collection.version`"""
- return self.versions.version(*p, **k)
-
- @classmethod
- def clear(cls):
- # TODO: deletes repo
- super(Repository, cls).clear()
- version.Collection.clear()
-
- def changeset(self, database, start, end=None):
- """Create a changeset to migrate this database from ver. start to end/latest.
-
- :param database: name of database to generate changeset
- :param start: version to start at
- :param end: version to end at (latest if None given)
- :type database: string
- :type start: int
- :type end: int
- :returns: :class:`Changeset instance <migration.versioning.repository.Changeset>`
- """
- start = version.VerNum(start)
-
- if end is None:
- end = self.latest
- else:
- end = version.VerNum(end)
-
- if start <= end:
- step = 1
- range_mod = 1
- op = 'upgrade'
- else:
- step = -1
- range_mod = 0
- op = 'downgrade'
-
- versions = range(start + range_mod, end + range_mod, step)
- changes = [self.version(v).script(database, op) for v in versions]
- ret = Changeset(start, step=step, *changes)
- return ret
-
- @classmethod
- def create_manage_file(cls, file_, **opts):
- """Create a project management script (manage.py)
-
- :param file_: Destination file to be written
- :param opts: Options that are passed to :func:`migrate.versioning.shell.main`
- """
- mng_file = Template(opts.pop('templates_path', None))\
- .get_manage(theme=opts.pop('templates_theme', None))
-
- tmpl = open(mng_file).read()
- fd = open(file_, 'w')
- fd.write(TempitaTemplate(tmpl).substitute(opts))
- fd.close()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schema.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schema.py
deleted file mode 100755
index e4d93653..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schema.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""
- Database schema version management.
-"""
-import sys
-import logging
-
-from sqlalchemy import (Table, Column, MetaData, String, Text, Integer,
- create_engine)
-from sqlalchemy.sql import and_
-from sqlalchemy import exceptions as sa_exceptions
-from sqlalchemy.sql import bindparam
-
-from migrate import exceptions
-from migrate.changeset import SQLA_07
-from migrate.versioning import genmodel, schemadiff
-from migrate.versioning.repository import Repository
-from migrate.versioning.util import load_model
-from migrate.versioning.version import VerNum
-
-
-log = logging.getLogger(__name__)
-
-class ControlledSchema(object):
- """A database under version control"""
-
- def __init__(self, engine, repository):
- if isinstance(repository, basestring):
- repository = Repository(repository)
- self.engine = engine
- self.repository = repository
- self.meta = MetaData(engine)
- self.load()
-
- def __eq__(self, other):
- """Compare two schemas by repositories and versions"""
- return (self.repository is other.repository \
- and self.version == other.version)
-
- def load(self):
- """Load controlled schema version info from DB"""
- tname = self.repository.version_table
- try:
- if not hasattr(self, 'table') or self.table is None:
- self.table = Table(tname, self.meta, autoload=True)
-
- result = self.engine.execute(self.table.select(
- self.table.c.repository_id == str(self.repository.id)))
-
- data = list(result)[0]
- except:
- cls, exc, tb = sys.exc_info()
- raise exceptions.DatabaseNotControlledError, exc.__str__(), tb
-
- self.version = data['version']
- return data
-
- def drop(self):
- """
- Remove version control from a database.
- """
- if SQLA_07:
- try:
- self.table.drop()
- except sa_exceptions.DatabaseError:
- raise exceptions.DatabaseNotControlledError(str(self.table))
- else:
- try:
- self.table.drop()
- except (sa_exceptions.SQLError):
- raise exceptions.DatabaseNotControlledError(str(self.table))
-
- def changeset(self, version=None):
- """API to Changeset creation.
-
- Uses self.version for start version and engine.name
- to get database name.
- """
- database = self.engine.name
- start_ver = self.version
- changeset = self.repository.changeset(database, start_ver, version)
- return changeset
-
- def runchange(self, ver, change, step):
- startver = ver
- endver = ver + step
- # Current database version must be correct! Don't run if corrupt!
- if self.version != startver:
- raise exceptions.InvalidVersionError("%s is not %s" % \
- (self.version, startver))
- # Run the change
- change.run(self.engine, step)
-
- # Update/refresh database version
- self.update_repository_table(startver, endver)
- self.load()
-
- def update_repository_table(self, startver, endver):
- """Update version_table with new information"""
- update = self.table.update(and_(self.table.c.version == int(startver),
- self.table.c.repository_id == str(self.repository.id)))
- self.engine.execute(update, version=int(endver))
-
- def upgrade(self, version=None):
- """
- Upgrade (or downgrade) to a specified version, or latest version.
- """
- changeset = self.changeset(version)
- for ver, change in changeset:
- self.runchange(ver, change, changeset.step)
-
- def update_db_from_model(self, model):
- """
- Modify the database to match the structure of the current Python model.
- """
- model = load_model(model)
-
- diff = schemadiff.getDiffOfModelAgainstDatabase(
- model, self.engine, excludeTables=[self.repository.version_table]
- )
- genmodel.ModelGenerator(diff,self.engine).runB2A()
-
- self.update_repository_table(self.version, int(self.repository.latest))
-
- self.load()
-
- @classmethod
- def create(cls, engine, repository, version=None):
- """
- Declare a database to be under a repository's version control.
-
- :raises: :exc:`DatabaseAlreadyControlledError`
- :returns: :class:`ControlledSchema`
- """
- # Confirm that the version # is valid: positive, integer,
- # exists in repos
- if isinstance(repository, basestring):
- repository = Repository(repository)
- version = cls._validate_version(repository, version)
- table = cls._create_table_version(engine, repository, version)
- # TODO: history table
- # Load repository information and return
- return cls(engine, repository)
-
- @classmethod
- def _validate_version(cls, repository, version):
- """
- Ensures this is a valid version number for this repository.
-
- :raises: :exc:`InvalidVersionError` if invalid
- :return: valid version number
- """
- if version is None:
- version = 0
- try:
- version = VerNum(version) # raises valueerror
- if version < 0 or version > repository.latest:
- raise ValueError()
- except ValueError:
- raise exceptions.InvalidVersionError(version)
- return version
-
- @classmethod
- def _create_table_version(cls, engine, repository, version):
- """
- Creates the versioning table in a database.
-
- :raises: :exc:`DatabaseAlreadyControlledError`
- """
- # Create tables
- tname = repository.version_table
- meta = MetaData(engine)
-
- table = Table(
- tname, meta,
- Column('repository_id', String(250), primary_key=True),
- Column('repository_path', Text),
- Column('version', Integer), )
-
- # there can be multiple repositories/schemas in the same db
- if not table.exists():
- table.create()
-
- # test for existing repository_id
- s = table.select(table.c.repository_id == bindparam("repository_id"))
- result = engine.execute(s, repository_id=repository.id)
- if result.fetchone():
- raise exceptions.DatabaseAlreadyControlledError
-
- # Insert data
- engine.execute(table.insert().values(
- repository_id=repository.id,
- repository_path=repository.path,
- version=int(version)))
- return table
-
- @classmethod
- def compare_model_to_db(cls, engine, model, repository):
- """
- Compare the current model against the current database.
- """
- if isinstance(repository, basestring):
- repository = Repository(repository)
- model = load_model(model)
-
- diff = schemadiff.getDiffOfModelAgainstDatabase(
- model, engine, excludeTables=[repository.version_table])
- return diff
-
- @classmethod
- def create_model(cls, engine, repository, declarative=False):
- """
- Dump the current database as a Python model.
- """
- if isinstance(repository, basestring):
- repository = Repository(repository)
-
- diff = schemadiff.getDiffOfModelAgainstDatabase(
- MetaData(), engine, excludeTables=[repository.version_table]
- )
- return genmodel.ModelGenerator(diff, engine, declarative).genBDefinition()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schemadiff.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schemadiff.py
deleted file mode 100755
index 04cf83e6..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/schemadiff.py
+++ /dev/null
@@ -1,292 +0,0 @@
-"""
- Schema differencing support.
-"""
-
-import logging
-import sqlalchemy
-
-from sqlalchemy.types import Float
-
-log = logging.getLogger(__name__)
-
-def getDiffOfModelAgainstDatabase(metadata, engine, excludeTables=None):
- """
- Return differences of model against database.
-
- :return: object which will evaluate to :keyword:`True` if there \
- are differences else :keyword:`False`.
- """
- db_metadata = sqlalchemy.MetaData(engine, reflect=True)
-
- # sqlite will include a dynamically generated 'sqlite_sequence' table if
- # there are autoincrement sequences in the database; this should not be
- # compared.
- if engine.dialect.name == 'sqlite':
- if 'sqlite_sequence' in db_metadata.tables:
- db_metadata.remove(db_metadata.tables['sqlite_sequence'])
-
- return SchemaDiff(metadata, db_metadata,
- labelA='model',
- labelB='database',
- excludeTables=excludeTables)
-
-
-def getDiffOfModelAgainstModel(metadataA, metadataB, excludeTables=None):
- """
- Return differences of model against another model.
-
- :return: object which will evaluate to :keyword:`True` if there \
- are differences else :keyword:`False`.
- """
- return SchemaDiff(metadataA, metadataB, excludeTables)
-
-
-class ColDiff(object):
- """
- Container for differences in one :class:`~sqlalchemy.schema.Column`
- between two :class:`~sqlalchemy.schema.Table` instances, ``A``
- and ``B``.
-
- .. attribute:: col_A
-
- The :class:`~sqlalchemy.schema.Column` object for A.
-
- .. attribute:: col_B
-
- The :class:`~sqlalchemy.schema.Column` object for B.
-
- .. attribute:: type_A
-
- The most generic type of the :class:`~sqlalchemy.schema.Column`
- object in A.
-
- .. attribute:: type_B
-
- The most generic type of the :class:`~sqlalchemy.schema.Column`
- object in A.
-
- """
-
- diff = False
-
- def __init__(self,col_A,col_B):
- self.col_A = col_A
- self.col_B = col_B
-
- self.type_A = col_A.type
- self.type_B = col_B.type
-
- self.affinity_A = self.type_A._type_affinity
- self.affinity_B = self.type_B._type_affinity
-
- if self.affinity_A is not self.affinity_B:
- self.diff = True
- return
-
- if isinstance(self.type_A,Float) or isinstance(self.type_B,Float):
- if not (isinstance(self.type_A,Float) and isinstance(self.type_B,Float)):
- self.diff=True
- return
-
- for attr in ('precision','scale','length'):
- A = getattr(self.type_A,attr,None)
- B = getattr(self.type_B,attr,None)
- if not (A is None or B is None) and A!=B:
- self.diff=True
- return
-
- def __nonzero__(self):
- return self.diff
-
-class TableDiff(object):
- """
- Container for differences in one :class:`~sqlalchemy.schema.Table`
- between two :class:`~sqlalchemy.schema.MetaData` instances, ``A``
- and ``B``.
-
- .. attribute:: columns_missing_from_A
-
- A sequence of column names that were found in B but weren't in
- A.
-
- .. attribute:: columns_missing_from_B
-
- A sequence of column names that were found in A but weren't in
- B.
-
- .. attribute:: columns_different
-
- A dictionary containing information about columns that were
- found to be different.
- It maps column names to a :class:`ColDiff` objects describing the
- differences found.
- """
- __slots__ = (
- 'columns_missing_from_A',
- 'columns_missing_from_B',
- 'columns_different',
- )
-
- def __nonzero__(self):
- return bool(
- self.columns_missing_from_A or
- self.columns_missing_from_B or
- self.columns_different
- )
-
-class SchemaDiff(object):
- """
- Compute the difference between two :class:`~sqlalchemy.schema.MetaData`
- objects.
-
- The string representation of a :class:`SchemaDiff` will summarise
- the changes found between the two
- :class:`~sqlalchemy.schema.MetaData` objects.
-
- The length of a :class:`SchemaDiff` will give the number of
- changes found, enabling it to be used much like a boolean in
- expressions.
-
- :param metadataA:
- First :class:`~sqlalchemy.schema.MetaData` to compare.
-
- :param metadataB:
- Second :class:`~sqlalchemy.schema.MetaData` to compare.
-
- :param labelA:
- The label to use in messages about the first
- :class:`~sqlalchemy.schema.MetaData`.
-
- :param labelB:
- The label to use in messages about the second
- :class:`~sqlalchemy.schema.MetaData`.
-
- :param excludeTables:
- A sequence of table names to exclude.
-
- .. attribute:: tables_missing_from_A
-
- A sequence of table names that were found in B but weren't in
- A.
-
- .. attribute:: tables_missing_from_B
-
- A sequence of table names that were found in A but weren't in
- B.
-
- .. attribute:: tables_different
-
- A dictionary containing information about tables that were found
- to be different.
- It maps table names to a :class:`TableDiff` objects describing the
- differences found.
- """
-
- def __init__(self,
- metadataA, metadataB,
- labelA='metadataA',
- labelB='metadataB',
- excludeTables=None):
-
- self.metadataA, self.metadataB = metadataA, metadataB
- self.labelA, self.labelB = labelA, labelB
- self.label_width = max(len(labelA),len(labelB))
- excludeTables = set(excludeTables or [])
-
- A_table_names = set(metadataA.tables.keys())
- B_table_names = set(metadataB.tables.keys())
-
- self.tables_missing_from_A = sorted(
- B_table_names - A_table_names - excludeTables
- )
- self.tables_missing_from_B = sorted(
- A_table_names - B_table_names - excludeTables
- )
-
- self.tables_different = {}
- for table_name in A_table_names.intersection(B_table_names):
-
- td = TableDiff()
-
- A_table = metadataA.tables[table_name]
- B_table = metadataB.tables[table_name]
-
- A_column_names = set(A_table.columns.keys())
- B_column_names = set(B_table.columns.keys())
-
- td.columns_missing_from_A = sorted(
- B_column_names - A_column_names
- )
-
- td.columns_missing_from_B = sorted(
- A_column_names - B_column_names
- )
-
- td.columns_different = {}
-
- for col_name in A_column_names.intersection(B_column_names):
-
- cd = ColDiff(
- A_table.columns.get(col_name),
- B_table.columns.get(col_name)
- )
-
- if cd:
- td.columns_different[col_name]=cd
-
- # XXX - index and constraint differences should
- # be checked for here
-
- if td:
- self.tables_different[table_name]=td
-
- def __str__(self):
- ''' Summarize differences. '''
- out = []
- column_template =' %%%is: %%r' % self.label_width
-
- for names,label in (
- (self.tables_missing_from_A,self.labelA),
- (self.tables_missing_from_B,self.labelB),
- ):
- if names:
- out.append(
- ' tables missing from %s: %s' % (
- label,', '.join(sorted(names))
- )
- )
-
- for name,td in sorted(self.tables_different.items()):
- out.append(
- ' table with differences: %s' % name
- )
- for names,label in (
- (td.columns_missing_from_A,self.labelA),
- (td.columns_missing_from_B,self.labelB),
- ):
- if names:
- out.append(
- ' %s missing these columns: %s' % (
- label,', '.join(sorted(names))
- )
- )
- for name,cd in td.columns_different.items():
- out.append(' column with differences: %s' % name)
- out.append(column_template % (self.labelA,cd.col_A))
- out.append(column_template % (self.labelB,cd.col_B))
-
- if out:
- out.insert(0, 'Schema diffs:')
- return '\n'.join(out)
- else:
- return 'No schema diffs'
-
- def __len__(self):
- """
- Used in bool evaluation, return of 0 means no diffs.
- """
- return (
- len(self.tables_missing_from_A) +
- len(self.tables_missing_from_B) +
- len(self.tables_different)
- )
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/__init__.py
deleted file mode 100755
index c788edaa..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from migrate.versioning.script.base import BaseScript
-from migrate.versioning.script.py import PythonScript
-from migrate.versioning.script.sql import SqlScript
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/base.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/base.py
deleted file mode 100755
index 42872352..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/base.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import logging
-
-from migrate import exceptions
-from migrate.versioning.config import operations
-from migrate.versioning import pathed
-
-
-log = logging.getLogger(__name__)
-
-class BaseScript(pathed.Pathed):
- """Base class for other types of scripts.
- All scripts have the following properties:
-
- source (script.source())
- The source code of the script
- version (script.version())
- The version number of the script
- operations (script.operations())
- The operations defined by the script: upgrade(), downgrade() or both.
- Returns a tuple of operations.
- Can also check for an operation with ex. script.operation(Script.ops.up)
- """ # TODO: sphinxfy this and implement it correctly
-
- def __init__(self, path):
- log.debug('Loading script %s...' % path)
- self.verify(path)
- super(BaseScript, self).__init__(path)
- log.debug('Script %s loaded successfully' % path)
-
- @classmethod
- def verify(cls, path):
- """Ensure this is a valid script
- This version simply ensures the script file's existence
-
- :raises: :exc:`InvalidScriptError <migrate.exceptions.InvalidScriptError>`
- """
- try:
- cls.require_found(path)
- except:
- raise exceptions.InvalidScriptError(path)
-
- def source(self):
- """:returns: source code of the script.
- :rtype: string
- """
- fd = open(self.path)
- ret = fd.read()
- fd.close()
- return ret
-
- def run(self, engine):
- """Core of each BaseScript subclass.
- This method executes the script.
- """
- raise NotImplementedError()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/py.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/py.py
deleted file mode 100755
index 3a090d49..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/py.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import shutil
-import warnings
-import logging
-import inspect
-from StringIO import StringIO
-
-import migrate
-from migrate.versioning import genmodel, schemadiff
-from migrate.versioning.config import operations
-from migrate.versioning.template import Template
-from migrate.versioning.script import base
-from migrate.versioning.util import import_path, load_model, with_engine
-from migrate.exceptions import MigrateDeprecationWarning, InvalidScriptError, ScriptError
-
-log = logging.getLogger(__name__)
-__all__ = ['PythonScript']
-
-
-class PythonScript(base.BaseScript):
- """Base for Python scripts"""
-
- @classmethod
- def create(cls, path, **opts):
- """Create an empty migration script at specified path
-
- :returns: :class:`PythonScript instance <migrate.versioning.script.py.PythonScript>`"""
- cls.require_notfound(path)
-
- src = Template(opts.pop('templates_path', None)).get_script(theme=opts.pop('templates_theme', None))
- shutil.copy(src, path)
-
- return cls(path)
-
- @classmethod
- def make_update_script_for_model(cls, engine, oldmodel,
- model, repository, **opts):
- """Create a migration script based on difference between two SA models.
-
- :param repository: path to migrate repository
- :param oldmodel: dotted.module.name:SAClass or SAClass object
- :param model: dotted.module.name:SAClass or SAClass object
- :param engine: SQLAlchemy engine
- :type repository: string or :class:`Repository instance <migrate.versioning.repository.Repository>`
- :type oldmodel: string or Class
- :type model: string or Class
- :type engine: Engine instance
- :returns: Upgrade / Downgrade script
- :rtype: string
- """
-
- if isinstance(repository, basestring):
- # oh dear, an import cycle!
- from migrate.versioning.repository import Repository
- repository = Repository(repository)
-
- oldmodel = load_model(oldmodel)
- model = load_model(model)
-
- # Compute differences.
- diff = schemadiff.getDiffOfModelAgainstModel(
- model,
- oldmodel,
- excludeTables=[repository.version_table])
- # TODO: diff can be False (there is no difference?)
- decls, upgradeCommands, downgradeCommands = \
- genmodel.ModelGenerator(diff,engine).genB2AMigration()
-
- # Store differences into file.
- src = Template(opts.pop('templates_path', None)).get_script(opts.pop('templates_theme', None))
- f = open(src)
- contents = f.read()
- f.close()
-
- # generate source
- search = 'def upgrade(migrate_engine):'
- contents = contents.replace(search, '\n\n'.join((decls, search)), 1)
- if upgradeCommands:
- contents = contents.replace(' pass', upgradeCommands, 1)
- if downgradeCommands:
- contents = contents.replace(' pass', downgradeCommands, 1)
- return contents
-
- @classmethod
- def verify_module(cls, path):
- """Ensure path is a valid script
-
- :param path: Script location
- :type path: string
- :raises: :exc:`InvalidScriptError <migrate.exceptions.InvalidScriptError>`
- :returns: Python module
- """
- # Try to import and get the upgrade() func
- module = import_path(path)
- try:
- assert callable(module.upgrade)
- except Exception, e:
- raise InvalidScriptError(path + ': %s' % str(e))
- return module
-
- def preview_sql(self, url, step, **args):
- """Mocks SQLAlchemy Engine to store all executed calls in a string
- and runs :meth:`PythonScript.run <migrate.versioning.script.py.PythonScript.run>`
-
- :returns: SQL file
- """
- buf = StringIO()
- args['engine_arg_strategy'] = 'mock'
- args['engine_arg_executor'] = lambda s, p = '': buf.write(str(s) + p)
-
- @with_engine
- def go(url, step, **kw):
- engine = kw.pop('engine')
- self.run(engine, step)
- return buf.getvalue()
-
- return go(url, step, **args)
-
- def run(self, engine, step):
- """Core method of Script file.
- Exectues :func:`update` or :func:`downgrade` functions
-
- :param engine: SQLAlchemy Engine
- :param step: Operation to run
- :type engine: string
- :type step: int
- """
- if step > 0:
- op = 'upgrade'
- elif step < 0:
- op = 'downgrade'
- else:
- raise ScriptError("%d is not a valid step" % step)
-
- funcname = base.operations[op]
- script_func = self._func(funcname)
-
- # check for old way of using engine
- if not inspect.getargspec(script_func)[0]:
- raise TypeError("upgrade/downgrade functions must accept engine"
- " parameter (since version 0.5.4)")
-
- script_func(engine)
-
- @property
- def module(self):
- """Calls :meth:`migrate.versioning.script.py.verify_module`
- and returns it.
- """
- if not hasattr(self, '_module'):
- self._module = self.verify_module(self.path)
- return self._module
-
- def _func(self, funcname):
- if not hasattr(self.module, funcname):
- msg = "Function '%s' is not defined in this script"
- raise ScriptError(msg % funcname)
- return getattr(self.module, funcname)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/sql.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/sql.py
deleted file mode 100755
index ed807641..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/script/sql.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import logging
-import shutil
-
-from migrate.versioning.script import base
-from migrate.versioning.template import Template
-
-
-log = logging.getLogger(__name__)
-
-class SqlScript(base.BaseScript):
- """A file containing plain SQL statements."""
-
- @classmethod
- def create(cls, path, **opts):
- """Create an empty migration script at specified path
-
- :returns: :class:`SqlScript instance <migrate.versioning.script.sql.SqlScript>`"""
- cls.require_notfound(path)
-
- src = Template(opts.pop('templates_path', None)).get_sql_script(theme=opts.pop('templates_theme', None))
- shutil.copy(src, path)
- return cls(path)
-
- # TODO: why is step parameter even here?
- def run(self, engine, step=None, executemany=True):
- """Runs SQL script through raw dbapi execute call"""
- text = self.source()
- # Don't rely on SA's autocommit here
- # (SA uses .startswith to check if a commit is needed. What if script
- # starts with a comment?)
- conn = engine.connect()
- try:
- trans = conn.begin()
- try:
- # HACK: SQLite doesn't allow multiple statements through
- # its execute() method, but it provides executescript() instead
- dbapi = conn.engine.raw_connection()
- if executemany and getattr(dbapi, 'executescript', None):
- dbapi.executescript(text)
- else:
- conn.execute(text)
- trans.commit()
- except:
- trans.rollback()
- raise
- finally:
- conn.close()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/shell.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/shell.py
deleted file mode 100755
index ad7b6798..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/shell.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""The migrate command-line tool."""
-
-import sys
-import inspect
-import logging
-from optparse import OptionParser, BadOptionError
-
-from migrate import exceptions
-from migrate.versioning import api
-from migrate.versioning.config import *
-from migrate.versioning.util import asbool
-
-
-alias = dict(
- s=api.script,
- vc=api.version_control,
- dbv=api.db_version,
- v=api.version,
-)
-
-def alias_setup():
- global alias
- for key, val in alias.iteritems():
- setattr(api, key, val)
-alias_setup()
-
-
-class PassiveOptionParser(OptionParser):
-
- def _process_args(self, largs, rargs, values):
- """little hack to support all --some_option=value parameters"""
-
- while rargs:
- arg = rargs[0]
- if arg == "--":
- del rargs[0]
- return
- elif arg[0:2] == "--":
- # if parser does not know about the option
- # pass it along (make it anonymous)
- try:
- opt = arg.split('=', 1)[0]
- self._match_long_opt(opt)
- except BadOptionError:
- largs.append(arg)
- del rargs[0]
- else:
- self._process_long_opt(rargs, values)
- elif arg[:1] == "-" and len(arg) > 1:
- self._process_short_opts(rargs, values)
- elif self.allow_interspersed_args:
- largs.append(arg)
- del rargs[0]
-
-def main(argv=None, **kwargs):
- """Shell interface to :mod:`migrate.versioning.api`.
-
- kwargs are default options that can be overriden with passing
- --some_option as command line option
-
- :param disable_logging: Let migrate configure logging
- :type disable_logging: bool
- """
- if argv is not None:
- argv = argv
- else:
- argv = list(sys.argv[1:])
- commands = list(api.__all__)
- commands.sort()
-
- usage = """%%prog COMMAND ...
-
- Available commands:
- %s
-
- Enter "%%prog help COMMAND" for information on a particular command.
- """ % '\n\t'.join(["%s - %s" % (command.ljust(28), api.command_desc.get(command)) for command in commands])
-
- parser = PassiveOptionParser(usage=usage)
- parser.add_option("-d", "--debug",
- action="store_true",
- dest="debug",
- default=False,
- help="Shortcut to turn on DEBUG mode for logging")
- parser.add_option("-q", "--disable_logging",
- action="store_true",
- dest="disable_logging",
- default=False,
- help="Use this option to disable logging configuration")
- help_commands = ['help', '-h', '--help']
- HELP = False
-
- try:
- command = argv.pop(0)
- if command in help_commands:
- HELP = True
- command = argv.pop(0)
- except IndexError:
- parser.print_help()
- return
-
- command_func = getattr(api, command, None)
- if command_func is None or command.startswith('_'):
- parser.error("Invalid command %s" % command)
-
- parser.set_usage(inspect.getdoc(command_func))
- f_args, f_varargs, f_kwargs, f_defaults = inspect.getargspec(command_func)
- for arg in f_args:
- parser.add_option(
- "--%s" % arg,
- dest=arg,
- action='store',
- type="string")
-
- # display help of the current command
- if HELP:
- parser.print_help()
- return
-
- options, args = parser.parse_args(argv)
-
- # override kwargs with anonymous parameters
- override_kwargs = dict()
- for arg in list(args):
- if arg.startswith('--'):
- args.remove(arg)
- if '=' in arg:
- opt, value = arg[2:].split('=', 1)
- else:
- opt = arg[2:]
- value = True
- override_kwargs[opt] = value
-
- # override kwargs with options if user is overwriting
- for key, value in options.__dict__.iteritems():
- if value is not None:
- override_kwargs[key] = value
-
- # arguments that function accepts without passed kwargs
- f_required = list(f_args)
- candidates = dict(kwargs)
- candidates.update(override_kwargs)
- for key, value in candidates.iteritems():
- if key in f_args:
- f_required.remove(key)
-
- # map function arguments to parsed arguments
- for arg in args:
- try:
- kw = f_required.pop(0)
- except IndexError:
- parser.error("Too many arguments for command %s: %s" % (command,
- arg))
- kwargs[kw] = arg
-
- # apply overrides
- kwargs.update(override_kwargs)
-
- # configure options
- for key, value in options.__dict__.iteritems():
- kwargs.setdefault(key, value)
-
- # configure logging
- if not asbool(kwargs.pop('disable_logging', False)):
- # filter to log =< INFO into stdout and rest to stderr
- class SingleLevelFilter(logging.Filter):
- def __init__(self, min=None, max=None):
- self.min = min or 0
- self.max = max or 100
-
- def filter(self, record):
- return self.min <= record.levelno <= self.max
-
- logger = logging.getLogger()
- h1 = logging.StreamHandler(sys.stdout)
- f1 = SingleLevelFilter(max=logging.INFO)
- h1.addFilter(f1)
- h2 = logging.StreamHandler(sys.stderr)
- f2 = SingleLevelFilter(min=logging.WARN)
- h2.addFilter(f2)
- logger.addHandler(h1)
- logger.addHandler(h2)
-
- if options.debug:
- logger.setLevel(logging.DEBUG)
- else:
- logger.setLevel(logging.INFO)
-
- log = logging.getLogger(__name__)
-
- # check if all args are given
- try:
- num_defaults = len(f_defaults)
- except TypeError:
- num_defaults = 0
- f_args_default = f_args[len(f_args) - num_defaults:]
- required = list(set(f_required) - set(f_args_default))
- if required:
- parser.error("Not enough arguments for command %s: %s not specified" \
- % (command, ', '.join(required)))
-
- # handle command
- try:
- ret = command_func(**kwargs)
- if ret is not None:
- log.info(ret)
- except (exceptions.UsageError, exceptions.KnownError), e:
- parser.error(e.args[0])
-
-if __name__ == "__main__":
- main()
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/template.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/template.py
deleted file mode 100755
index 182898a6..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/template.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import shutil
-import sys
-
-from pkg_resources import resource_filename
-
-from migrate.versioning.config import *
-from migrate.versioning import pathed
-
-
-class Collection(pathed.Pathed):
- """A collection of templates of a specific type"""
- _mask = None
-
- def get_path(self, file):
- return os.path.join(self.path, str(file))
-
-
-class RepositoryCollection(Collection):
- _mask = '%s'
-
-class ScriptCollection(Collection):
- _mask = '%s.py_tmpl'
-
-class ManageCollection(Collection):
- _mask = '%s.py_tmpl'
-
-class SQLScriptCollection(Collection):
- _mask = '%s.py_tmpl'
-
-class Template(pathed.Pathed):
- """Finds the paths/packages of various Migrate templates.
-
- :param path: Templates are loaded from migrate package
- if `path` is not provided.
- """
- pkg = 'migrate.versioning.templates'
-
- def __new__(cls, path=None):
- if path is None:
- path = cls._find_path(cls.pkg)
- return super(Template, cls).__new__(cls, path)
-
- def __init__(self, path=None):
- if path is None:
- path = Template._find_path(self.pkg)
- super(Template, self).__init__(path)
- self.repository = RepositoryCollection(os.path.join(path, 'repository'))
- self.script = ScriptCollection(os.path.join(path, 'script'))
- self.manage = ManageCollection(os.path.join(path, 'manage'))
- self.sql_script = SQLScriptCollection(os.path.join(path, 'sql_script'))
-
- @classmethod
- def _find_path(cls, pkg):
- """Returns absolute path to dotted python package."""
- tmp_pkg = pkg.rsplit('.', 1)
-
- if len(tmp_pkg) != 1:
- return resource_filename(tmp_pkg[0], tmp_pkg[1])
- else:
- return resource_filename(tmp_pkg[0], '')
-
- def _get_item(self, collection, theme=None):
- """Locates and returns collection.
-
- :param collection: name of collection to locate
- :param type_: type of subfolder in collection (defaults to "_default")
- :returns: (package, source)
- :rtype: str, str
- """
- item = getattr(self, collection)
- theme_mask = getattr(item, '_mask')
- theme = theme_mask % (theme or 'default')
- return item.get_path(theme)
-
- def get_repository(self, *a, **kw):
- """Calls self._get_item('repository', *a, **kw)"""
- return self._get_item('repository', *a, **kw)
-
- def get_script(self, *a, **kw):
- """Calls self._get_item('script', *a, **kw)"""
- return self._get_item('script', *a, **kw)
-
- def get_sql_script(self, *a, **kw):
- """Calls self._get_item('sql_script', *a, **kw)"""
- return self._get_item('sql_script', *a, **kw)
-
- def get_manage(self, *a, **kw):
- """Calls self._get_item('manage', *a, **kw)"""
- return self._get_item('manage', *a, **kw)
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/default.py_tmpl b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/default.py_tmpl
deleted file mode 100644
index f6d75c50..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/default.py_tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env python
-from migrate.versioning.shell import main
-
-{{py:
-_vars = locals().copy()
-del _vars['__template_name__']
-_vars.pop('repository_name', None)
-defaults = ", ".join(["%s='%s'" % var for var in _vars.iteritems()])
-}}
-
-if __name__ == '__main__':
- main({{ defaults }})
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/pylons.py_tmpl b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/pylons.py_tmpl
deleted file mode 100644
index cc2f7885..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/manage/pylons.py_tmpl
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-import sys
-
-from sqlalchemy import engine_from_config
-from paste.deploy.loadwsgi import ConfigLoader
-
-from migrate.versioning.shell import main
-from {{ locals().pop('repository_name') }}.model import migrations
-
-
-if '-c' in sys.argv:
- pos = sys.argv.index('-c')
- conf_path = sys.argv[pos + 1]
- del sys.argv[pos:pos + 2]
-else:
- conf_path = 'development.ini'
-
-{{py:
-_vars = locals().copy()
-del _vars['__template_name__']
-defaults = ", ".join(["%s='%s'" % var for var in _vars.iteritems()])
-}}
-
-conf_dict = ConfigLoader(conf_path).parser._sections['app:main']
-
-# migrate supports passing url as an existing Engine instance (since 0.6.0)
-# usage: migrate -c path/to/config.ini COMMANDS
-if __name__ == '__main__':
- main(url=engine_from_config(conf_dict), repository=migrations.__path__[0],{{ defaults }})
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/README b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/README
deleted file mode 100644
index 6218f8ca..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/README
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a database migration repository.
-
-More information at
-http://code.google.com/p/sqlalchemy-migrate/
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/migrate.cfg b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/migrate.cfg
deleted file mode 100644
index dae06123..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/migrate.cfg
+++ /dev/null
@@ -1,25 +0,0 @@
-[db_settings]
-# Used to identify which repository this database is versioned under.
-# You can use the name of your project.
-repository_id={{ locals().pop('repository_id') }}
-
-# The name of the database table used to track the schema version.
-# This name shouldn't already be used by your project.
-# If this is changed once a database is under version control, you'll need to
-# change the table name in each database too.
-version_table={{ locals().pop('version_table') }}
-
-# When committing a change script, Migrate will attempt to generate the
-# sql for all supported databases; normally, if one of them fails - probably
-# because you don't have that database installed - it is ignored and the
-# commit continues, perhaps ending successfully.
-# Databases in this list MUST compile successfully during a commit, or the
-# entire commit will fail. List the databases your application will actually
-# be using to ensure your updates to that database work properly.
-# This must be a list; example: ['postgres','sqlite']
-required_dbs={{ locals().pop('required_dbs') }}
-
-# When creating new change scripts, Migrate will stamp the new script with
-# a version number. By default this is latest_version + 1. You can set this
-# to 'true' to tell Migrate to use the UTC timestamp instead.
-use_timestamp_numbering={{ locals().pop('use_timestamp_numbering') }}
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/versions/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/versions/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/default/versions/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/README b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/README
deleted file mode 100644
index 6218f8ca..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/README
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a database migration repository.
-
-More information at
-http://code.google.com/p/sqlalchemy-migrate/
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/migrate.cfg b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/migrate.cfg
deleted file mode 100644
index dae06123..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/migrate.cfg
+++ /dev/null
@@ -1,25 +0,0 @@
-[db_settings]
-# Used to identify which repository this database is versioned under.
-# You can use the name of your project.
-repository_id={{ locals().pop('repository_id') }}
-
-# The name of the database table used to track the schema version.
-# This name shouldn't already be used by your project.
-# If this is changed once a database is under version control, you'll need to
-# change the table name in each database too.
-version_table={{ locals().pop('version_table') }}
-
-# When committing a change script, Migrate will attempt to generate the
-# sql for all supported databases; normally, if one of them fails - probably
-# because you don't have that database installed - it is ignored and the
-# commit continues, perhaps ending successfully.
-# Databases in this list MUST compile successfully during a commit, or the
-# entire commit will fail. List the databases your application will actually
-# be using to ensure your updates to that database work properly.
-# This must be a list; example: ['postgres','sqlite']
-required_dbs={{ locals().pop('required_dbs') }}
-
-# When creating new change scripts, Migrate will stamp the new script with
-# a version number. By default this is latest_version + 1. You can set this
-# to 'true' to tell Migrate to use the UTC timestamp instead.
-use_timestamp_numbering={{ locals().pop('use_timestamp_numbering') }}
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/versions/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/versions/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/repository/pylons/versions/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/__init__.py
deleted file mode 100755
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/default.py_tmpl b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/default.py_tmpl
deleted file mode 100644
index 58d874bf..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/default.py_tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-from sqlalchemy import *
-from migrate import *
-
-
-def upgrade(migrate_engine):
- # Upgrade operations go here. Don't create your own engine; bind
- # migrate_engine to your metadata
- pass
-
-
-def downgrade(migrate_engine):
- # Operations to reverse the above upgrade go here.
- pass
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/pylons.py_tmpl b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/pylons.py_tmpl
deleted file mode 100644
index 58d874bf..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/script/pylons.py_tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-from sqlalchemy import *
-from migrate import *
-
-
-def upgrade(migrate_engine):
- # Upgrade operations go here. Don't create your own engine; bind
- # migrate_engine to your metadata
- pass
-
-
-def downgrade(migrate_engine):
- # Operations to reverse the above upgrade go here.
- pass
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/default.py_tmpl b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/default.py_tmpl
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/default.py_tmpl
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/pylons.py_tmpl b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/pylons.py_tmpl
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/templates/sql_script/pylons.py_tmpl
+++ /dev/null
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/__init__.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/__init__.py
deleted file mode 100755
index 9b79f409..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/__init__.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-""".. currentmodule:: migrate.versioning.util"""
-
-import warnings
-import logging
-from decorator import decorator
-from pkg_resources import EntryPoint
-
-from sqlalchemy import create_engine
-from sqlalchemy.engine import Engine
-from sqlalchemy.pool import StaticPool
-
-from migrate import exceptions
-from migrate.versioning.util.keyedinstance import KeyedInstance
-from migrate.versioning.util.importpath import import_path
-
-
-log = logging.getLogger(__name__)
-
-def load_model(dotted_name):
- """Import module and use module-level variable".
-
- :param dotted_name: path to model in form of string: ``some.python.module:Class``
-
- .. versionchanged:: 0.5.4
-
- """
- if isinstance(dotted_name, basestring):
- if ':' not in dotted_name:
- # backwards compatibility
- warnings.warn('model should be in form of module.model:User '
- 'and not module.model.User', exceptions.MigrateDeprecationWarning)
- dotted_name = ':'.join(dotted_name.rsplit('.', 1))
- return EntryPoint.parse('x=%s' % dotted_name).load(False)
- else:
- # Assume it's already loaded.
- return dotted_name
-
-def asbool(obj):
- """Do everything to use object as bool"""
- if isinstance(obj, basestring):
- obj = obj.strip().lower()
- if obj in ['true', 'yes', 'on', 'y', 't', '1']:
- return True
- elif obj in ['false', 'no', 'off', 'n', 'f', '0']:
- return False
- else:
- raise ValueError("String is not true/false: %r" % obj)
- if obj in (True, False):
- return bool(obj)
- else:
- raise ValueError("String is not true/false: %r" % obj)
-
-def guess_obj_type(obj):
- """Do everything to guess object type from string
-
- Tries to convert to `int`, `bool` and finally returns if not succeded.
-
- .. versionadded: 0.5.4
- """
-
- result = None
-
- try:
- result = int(obj)
- except:
- pass
-
- if result is None:
- try:
- result = asbool(obj)
- except:
- pass
-
- if result is not None:
- return result
- else:
- return obj
-
-@decorator
-def catch_known_errors(f, *a, **kw):
- """Decorator that catches known api errors
-
- .. versionadded: 0.5.4
- """
-
- try:
- return f(*a, **kw)
- except exceptions.PathFoundError, e:
- raise exceptions.KnownError("The path %s already exists" % e.args[0])
-
-def construct_engine(engine, **opts):
- """.. versionadded:: 0.5.4
-
- Constructs and returns SQLAlchemy engine.
-
- Currently, there are 2 ways to pass create_engine options to :mod:`migrate.versioning.api` functions:
-
- :param engine: connection string or a existing engine
- :param engine_dict: python dictionary of options to pass to `create_engine`
- :param engine_arg_*: keyword parameters to pass to `create_engine` (evaluated with :func:`migrate.versioning.util.guess_obj_type`)
- :type engine_dict: dict
- :type engine: string or Engine instance
- :type engine_arg_*: string
- :returns: SQLAlchemy Engine
-
- .. note::
-
- keyword parameters override ``engine_dict`` values.
-
- """
- if isinstance(engine, Engine):
- return engine
- elif not isinstance(engine, basestring):
- raise ValueError("you need to pass either an existing engine or a database uri")
-
- # get options for create_engine
- if opts.get('engine_dict') and isinstance(opts['engine_dict'], dict):
- kwargs = opts['engine_dict']
- else:
- kwargs = dict()
-
- # DEPRECATED: handle echo the old way
- echo = asbool(opts.get('echo', False))
- if echo:
- warnings.warn('echo=True parameter is deprecated, pass '
- 'engine_arg_echo=True or engine_dict={"echo": True}',
- exceptions.MigrateDeprecationWarning)
- kwargs['echo'] = echo
-
- # parse keyword arguments
- for key, value in opts.iteritems():
- if key.startswith('engine_arg_'):
- kwargs[key[11:]] = guess_obj_type(value)
-
- log.debug('Constructing engine')
- # TODO: return create_engine(engine, poolclass=StaticPool, **kwargs)
- # seems like 0.5.x branch does not work with engine.dispose and staticpool
- return create_engine(engine, **kwargs)
-
-@decorator
-def with_engine(f, *a, **kw):
- """Decorator for :mod:`migrate.versioning.api` functions
- to safely close resources after function usage.
-
- Passes engine parameters to :func:`construct_engine` and
- resulting parameter is available as kw['engine'].
-
- Engine is disposed after wrapped function is executed.
-
- .. versionadded: 0.6.0
- """
- url = a[0]
- engine = construct_engine(url, **kw)
-
- try:
- kw['engine'] = engine
- return f(*a, **kw)
- finally:
- if isinstance(engine, Engine):
- log.debug('Disposing SQLAlchemy engine %s', engine)
- engine.dispose()
-
-
-class Memoize:
- """Memoize(fn) - an instance which acts like fn but memoizes its arguments
- Will only work on functions with non-mutable arguments
-
- ActiveState Code 52201
- """
- def __init__(self, fn):
- self.fn = fn
- self.memo = {}
-
- def __call__(self, *args):
- if not self.memo.has_key(args):
- self.memo[args] = self.fn(*args)
- return self.memo[args]
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/importpath.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/importpath.py
deleted file mode 100755
index 59b57f14..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/importpath.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import os
-import sys
-
-def import_path(fullpath):
- """ Import a file with full path specification. Allows one to
- import from anywhere, something __import__ does not do.
- """
- # http://zephyrfalcon.org/weblog/arch_d7_2002_08_31.html
- path, filename = os.path.split(fullpath)
- filename, ext = os.path.splitext(filename)
- sys.path.append(path)
- module = __import__(filename)
- reload(module) # Might be out of date during tests
- del sys.path[-1]
- return module
-
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/keyedinstance.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/keyedinstance.py
deleted file mode 100755
index 3f6cb916..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/util/keyedinstance.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-class KeyedInstance(object):
- """A class whose instances have a unique identifier of some sort
- No two instances with the same unique ID should exist - if we try to create
- a second instance, the first should be returned.
- """
-
- _instances = dict()
-
- def __new__(cls, *p, **k):
- instances = cls._instances
- clskey = str(cls)
- if clskey not in instances:
- instances[clskey] = dict()
- instances = instances[clskey]
-
- key = cls._key(*p, **k)
- if key not in instances:
- instances[key] = super(KeyedInstance, cls).__new__(cls)
- return instances[key]
-
- @classmethod
- def _key(cls, *p, **k):
- """Given a unique identifier, return a dictionary key
- This should be overridden by child classes, to specify which parameters
- should determine an object's uniqueness
- """
- raise NotImplementedError()
-
- @classmethod
- def clear(cls):
- # Allow cls.clear() as well as uniqueInstance.clear(cls)
- if str(cls) in cls._instances:
- del cls._instances[str(cls)]
diff --git a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/version.py b/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/version.py
deleted file mode 100755
index d5a5be98..00000000
--- a/lib/python2.7/site-packages/sqlalchemy_migrate-0.7.2-py2.7.egg/migrate/versioning/version.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os
-import re
-import shutil
-import logging
-
-from migrate import exceptions
-from migrate.versioning import pathed, script
-from datetime import datetime
-
-
-log = logging.getLogger(__name__)
-
-class VerNum(object):
- """A version number that behaves like a string and int at the same time"""
-
- _instances = dict()
-
- def __new__(cls, value):
- val = str(value)
- if val not in cls._instances:
- cls._instances[val] = super(VerNum, cls).__new__(cls)
- ret = cls._instances[val]
- return ret
-
- def __init__(self,value):
- self.value = str(int(value))
- if self < 0:
- raise ValueError("Version number cannot be negative")
-
- def __add__(self, value):
- ret = int(self) + int(value)
- return VerNum(ret)
-
- def __sub__(self, value):
- return self + (int(value) * -1)
-
- def __cmp__(self, value):
- return int(self) - int(value)
-
- def __repr__(self):
- return "<VerNum(%s)>" % self.value
-
- def __str__(self):
- return str(self.value)
-
- def __int__(self):
- return int(self.value)
-
-
-class Collection(pathed.Pathed):
- """A collection of versioning scripts in a repository"""
-
- FILENAME_WITH_VERSION = re.compile(r'^(\d{3,}).*')
-
- def __init__(self, path):
- """Collect current version scripts in repository
- and store them in self.versions
- """
- super(Collection, self).__init__(path)
-
- # Create temporary list of files, allowing skipped version numbers.
- files = os.listdir(path)
- if '1' in files:
- # deprecation
- raise Exception('It looks like you have a repository in the old '
- 'format (with directories for each version). '
- 'Please convert repository before proceeding.')
-
- tempVersions = dict()
- for filename in files:
- match = self.FILENAME_WITH_VERSION.match(filename)
- if match:
- num = int(match.group(1))
- tempVersions.setdefault(num, []).append(filename)
- else:
- pass # Must be a helper file or something, let's ignore it.
-
- # Create the versions member where the keys
- # are VerNum's and the values are Version's.
- self.versions = dict()
- for num, files in tempVersions.items():
- self.versions[VerNum(num)] = Version(num, path, files)
-
- @property
- def latest(self):
- """:returns: Latest version in Collection"""
- return max([VerNum(0)] + self.versions.keys())
-
- def _next_ver_num(self, use_timestamp_numbering):
- if use_timestamp_numbering == True:
- return VerNum(int(datetime.utcnow().strftime('%Y%m%d%H%M%S')))
- else:
- return self.latest + 1
-
- def create_new_python_version(self, description, **k):
- """Create Python files for new version"""
- ver = self._next_ver_num(k.pop('use_timestamp_numbering', False))
- extra = str_to_filename(description)
-
- if extra:
- if extra == '_':
- extra = ''
- elif not extra.startswith('_'):
- extra = '_%s' % extra
-
- filename = '%03d%s.py' % (ver, extra)
- filepath = self._version_path(filename)
-
- script.PythonScript.create(filepath, **k)
- self.versions[ver] = Version(ver, self.path, [filename])
-
- def create_new_sql_version(self, database, description, **k):
- """Create SQL files for new version"""
- ver = self._next_ver_num(k.pop('use_timestamp_numbering', False))
- self.versions[ver] = Version(ver, self.path, [])
-
- extra = str_to_filename(description)
-
- if extra:
- if extra == '_':
- extra = ''
- elif not extra.startswith('_'):
- extra = '_%s' % extra
-
- # Create new files.
- for op in ('upgrade', 'downgrade'):
- filename = '%03d%s_%s_%s.sql' % (ver, extra, database, op)
- filepath = self._version_path(filename)
- script.SqlScript.create(filepath, **k)
- self.versions[ver].add_script(filepath)
-
- def version(self, vernum=None):
- """Returns latest Version if vernum is not given.
- Otherwise, returns wanted version"""
- if vernum is None:
- vernum = self.latest
- return self.versions[VerNum(vernum)]
-
- @classmethod
- def clear(cls):
- super(Collection, cls).clear()
-
- def _version_path(self, ver):
- """Returns path of file in versions repository"""
- return os.path.join(self.path, str(ver))
-
-
-class Version(object):
- """A single version in a collection
- :param vernum: Version Number
- :param path: Path to script files
- :param filelist: List of scripts
- :type vernum: int, VerNum
- :type path: string
- :type filelist: list
- """
-
- def __init__(self, vernum, path, filelist):
- self.version = VerNum(vernum)
-
- # Collect scripts in this folder
- self.sql = dict()
- self.python = None
-
- for script in filelist:
- self.add_script(os.path.join(path, script))
-
- def script(self, database=None, operation=None):
- """Returns SQL or Python Script"""
- for db in (database, 'default'):
- # Try to return a .sql script first
- try:
- return self.sql[db][operation]
- except KeyError:
- continue # No .sql script exists
-
- # TODO: maybe add force Python parameter?
- ret = self.python
-
- assert ret is not None, \
- "There is no script for %d version" % self.version
- return ret
-
- def add_script(self, path):
- """Add script to Collection/Version"""
- if path.endswith(Extensions.py):
- self._add_script_py(path)
- elif path.endswith(Extensions.sql):
- self._add_script_sql(path)
-
- SQL_FILENAME = re.compile(r'^.*\.sql')
-
- def _add_script_sql(self, path):
- basename = os.path.basename(path)
- match = self.SQL_FILENAME.match(basename)
-
- if match:
- basename = basename.replace('.sql', '')
- parts = basename.split('_')
- if len(parts) < 3:
- raise exceptions.ScriptError(
- "Invalid SQL script name %s " % basename + \
- "(needs to be ###_description_database_operation.sql)")
- version = parts[0]
- op = parts[-1]
- dbms = parts[-2]
- else:
- raise exceptions.ScriptError(
- "Invalid SQL script name %s " % basename + \
- "(needs to be ###_description_database_operation.sql)")
-
- # File the script into a dictionary
- self.sql.setdefault(dbms, {})[op] = script.SqlScript(path)
-
- def _add_script_py(self, path):
- if self.python is not None:
- raise exceptions.ScriptError('You can only have one Python script '
- 'per version, but you have: %s and %s' % (self.python, path))
- self.python = script.PythonScript(path)
-
-
-class Extensions:
- """A namespace for file extensions"""
- py = 'py'
- sql = 'sql'
-
-def str_to_filename(s):
- """Replaces spaces, (double and single) quotes
- and double underscores to underscores
- """
-
- s = s.replace(' ', '_').replace('"', '_').replace("'", '_').replace(".", "_")
- while '__' in s:
- s = s.replace('__', '_')
- return s
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO
deleted file mode 100644
index 06be973c..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/PKG-INFO
+++ /dev/null
@@ -1,275 +0,0 @@
-Metadata-Version: 1.0
-Name: zope.interface
-Version: 3.6.4
-Summary: Interfaces for Python
-Home-page: http://pypi.python.org/pypi/zope.interface
-Author: Zope Foundation and Contributors
-Author-email: zope-dev@zope.org
-License: ZPL 2.1
-Description: ``zope.interface`` README
- =========================
-
- This package is intended to be independently reusable in any Python
- project. It is maintained by the `Zope Toolkit project
- <http://docs.zope.org/zopetoolkit/>`_.
-
- This package provides an implementation of "object interfaces" for Python.
- Interfaces are a mechanism for labeling objects as conforming to a given
- API or contract. So, this package can be considered as implementation of
- the `Design By Contract`_ methodology support in Python.
-
- .. _Design By Contract: http://en.wikipedia.org/wiki/Design_by_contract
-
- For detailed documentation, please see http://docs.zope.org/zope.interface
-
- ``zope.interface Changelog``
- ============================
-
- 3.6.4 (2011-07-04)
- ------------------
-
- - LP 804951: InterfaceClass instances were unhashable under Python 3.x.
-
- 3.6.3 (2011-05-26)
- ------------------
-
- - LP #570942: Now correctly compare interfaces from different modules but
- with the same names.
-
- 3.6.2 (2011-05-17)
- ------------------
-
- - Moved detailed documentation out-of-line from PyPI page, linking instead to
- http://docs.zope.org/zope.interface .
-
- - Fixes for small issues when running tests under Python 3.2 using
- ``zope.testrunner``.
-
- - LP # 675064: Specify return value type for C optimizations module init
- under Python 3: undeclared value caused warnings, and segfaults on some
- 64 bit architectures.
-
- - setup.py now raises RuntimeError if you don't have Distutils installed when
- running under Python 3.
-
- 3.6.1 (2010-05-03)
- ------------------
-
- - A non-ASCII character in the changelog made 3.6.0 uninstallable on
- Python 3 systems with another default encoding than UTF-8.
-
- - Fixed compiler warnings under GCC 4.3.3.
-
- 3.6.0 (2010-04-29)
- ------------------
-
- - LP #185974: Clear the cache used by ``Specificaton.get`` inside
- ``Specification.changed``. Thanks to Jacob Holm for the patch.
-
- - Added support for Python 3.1. Contributors:
-
- Lennart Regebro
- Martin v Loewis
- Thomas Lotze
- Wolfgang Schnerring
-
- The 3.1 support is completely backwards compatible. However, the implements
- syntax used under Python 2.X does not work under 3.X, since it depends on
- how metaclasses are implemented and this has changed. Instead it now supports
- a decorator syntax (also under Python 2.X)::
-
- class Foo:
- implements(IFoo)
- ...
-
- can now also be written::
-
- @implementor(IFoo):
- class Foo:
- ...
-
- There are 2to3 fixers available to do this change automatically in the
- zope.fixers package.
-
- - Python 2.3 is no longer supported.
-
-
- 3.5.4 (2009-12-23)
- ------------------
-
- - Use the standard Python doctest module instead of zope.testing.doctest, which
- has been deprecated.
-
-
- 3.5.3 (2009-12-08)
- ------------------
-
- - Fix an edge case: make providedBy() work when a class has '__provides__' in
- its __slots__ (see http://thread.gmane.org/gmane.comp.web.zope.devel/22490)
-
-
- 3.5.2 (2009-07-01)
- ------------------
-
- - BaseAdapterRegistry.unregister, unsubscribe: Remove empty portions of
- the data structures when something is removed. This avoids leaving
- references to global objects (interfaces) that may be slated for
- removal from the calling application.
-
-
- 3.5.1 (2009-03-18)
- ------------------
-
- - verifyObject: use getattr instead of hasattr to test for object attributes
- in order to let exceptions other than AttributeError raised by properties
- propagate to the caller
-
- - Add Sphinx-based documentation building to the package buildout
- configuration. Use the ``bin/docs`` command after buildout.
-
- - Improve package description a bit. Unify changelog entries formatting.
-
- - Change package's mailing list address to zope-dev at zope.org as
- zope3-dev at zope.org is now retired.
-
-
- 3.5.0 (2008-10-26)
- ------------------
-
- - Fixed declaration of _zope_interface_coptimizations, it's not a top level
- package.
-
- - Add a DocTestSuite for odd.py module, so their tests are run.
-
- - Allow to bootstrap on Jython.
-
- - Fix https://bugs.launchpad.net/zope3/3.3/+bug/98388: ISpecification
- was missing a declaration for __iro__.
-
- - Added optional code optimizations support, which allows the building
- of C code optimizations to fail (Jython).
-
- - Replaced `_flatten` with a non-recursive implementation, effectively making
- it 3x faster.
-
-
- 3.4.1 (2007-10-02)
- ------------------
-
- - Fixed a setup bug that prevented installation from source on systems
- without setuptools.
-
-
- 3.4.0 (2007-07-19)
- ------------------
-
- - Final release for 3.4.0.
-
-
- 3.4.0b3 (2007-05-22)
- --------------------
-
-
- - Objects with picky custom comparison methods couldn't be added to
- component registries. Now, when checking whether an object is
- already registered, identity comparison is used.
-
-
- 3.3.0.1 (2007-01-03)
- --------------------
-
- - Made a reference to OverflowWarning, which disappeared in Python
- 2.5, conditional.
-
-
- 3.3.0 (2007/01/03)
- ------------------
-
- New Features
- ++++++++++++
-
- - The adapter-lookup algorithim was refactored to make it
- much simpler and faster.
-
- Also, more of the adapter-lookup logic is implemented in C, making
- debugging of application code easier, since there is less
- infrastructre code to step through.
-
- - We now treat objects without interface declarations as if they
- declared that they provide zope.interface.Interface.
-
- - There are a number of richer new adapter-registration interfaces
- that provide greater control and introspection.
-
- - Added a new interface decorator to zope.interface that allows the
- setting of tagged values on an interface at definition time (see
- zope.interface.taggedValue).
-
- Bug Fixes
- +++++++++
-
- - A bug in multi-adapter lookup sometimes caused incorrect adapters to
- be returned.
-
-
- 3.2.0.2 (2006-04-15)
- --------------------
-
- - Fix packaging bug: 'package_dir' must be a *relative* path.
-
-
- 3.2.0.1 (2006-04-14)
- --------------------
-
- - Packaging change: suppress inclusion of 'setup.cfg' in 'sdist' builds.
-
-
- 3.2.0 (2006-01-05)
- ------------------
-
- - Corresponds to the verison of the zope.interface package shipped as part of
- the Zope 3.2.0 release.
-
-
- 3.1.0 (2005-10-03)
- ------------------
-
- - Corresponds to the verison of the zope.interface package shipped as part of
- the Zope 3.1.0 release.
-
- - Made attribute resolution order consistent with component lookup order,
- i.e. new-style class MRO semantics.
-
- - Deprecated 'isImplementedBy' and 'isImplementedByInstancesOf' APIs in
- favor of 'implementedBy' and 'providedBy'.
-
-
- 3.0.1 (2005-07-27)
- ------------------
-
- - Corresponds to the verison of the zope.interface package shipped as part of
- the Zope X3.0.1 release.
-
- - Fixed a bug reported by James Knight, which caused adapter registries
- to fail occasionally to reflect declaration changes.
-
-
- 3.0.0 (2004-11-07)
- ------------------
-
- - Corresponds to the verison of the zope.interface package shipped as part of
- the Zope X3.0.0 release.
-
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: Zope Public License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2.4
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
-Classifier: Programming Language :: Python :: 3.2
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt
deleted file mode 100644
index fe69ee9e..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/SOURCES.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-.bzrignore
-CHANGES.txt
-COPYRIGHT.txt
-LICENSE.txt
-README.txt
-bootstrap.py
-build_ext_2.py
-build_ext_3.py
-buildout.cfg
-setup.cfg
-setup.py
-src/zope/__init__.py
-src/zope.interface.egg-info/PKG-INFO
-src/zope.interface.egg-info/SOURCES.txt
-src/zope.interface.egg-info/dependency_links.txt
-src/zope.interface.egg-info/namespace_packages.txt
-src/zope.interface.egg-info/not-zip-safe
-src/zope.interface.egg-info/requires.txt
-src/zope.interface.egg-info/top_level.txt
-src/zope/interface/README.ru.txt
-src/zope/interface/README.txt
-src/zope/interface/__init__.py
-src/zope/interface/_flatten.py
-src/zope/interface/_zope_interface_coptimizations.c
-src/zope/interface/adapter.py
-src/zope/interface/adapter.ru.txt
-src/zope/interface/adapter.txt
-src/zope/interface/advice.py
-src/zope/interface/declarations.py
-src/zope/interface/document.py
-src/zope/interface/exceptions.py
-src/zope/interface/human.ru.txt
-src/zope/interface/human.txt
-src/zope/interface/index.txt
-src/zope/interface/interface.py
-src/zope/interface/interfaces.py
-src/zope/interface/ro.py
-src/zope/interface/verify.py
-src/zope/interface/verify.txt
-src/zope/interface/common/__init__.py
-src/zope/interface/common/idatetime.py
-src/zope/interface/common/interfaces.py
-src/zope/interface/common/mapping.py
-src/zope/interface/common/sequence.py
-src/zope/interface/common/tests/__init__.py
-src/zope/interface/common/tests/basemapping.py
-src/zope/interface/common/tests/test_idatetime.py
-src/zope/interface/common/tests/test_import_interfaces.py
-src/zope/interface/tests/__init__.py
-src/zope/interface/tests/dummy.py
-src/zope/interface/tests/foodforthought.txt
-src/zope/interface/tests/ifoo.py
-src/zope/interface/tests/m1.py
-src/zope/interface/tests/m2.py
-src/zope/interface/tests/odd.py
-src/zope/interface/tests/test_adapter.py
-src/zope/interface/tests/test_advice.py
-src/zope/interface/tests/test_declarations.py
-src/zope/interface/tests/test_document.py
-src/zope/interface/tests/test_element.py
-src/zope/interface/tests/test_interface.py
-src/zope/interface/tests/test_odd_declarations.py
-src/zope/interface/tests/test_sorting.py
-src/zope/interface/tests/test_verify.py
-src/zope/interface/tests/unitfixtures.py \ No newline at end of file
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/namespace_packages.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/namespace_packages.txt
deleted file mode 100644
index 66179d49..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-zope
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt
deleted file mode 100644
index 73277eba..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/native_libs.txt
+++ /dev/null
@@ -1 +0,0 @@
-zope/interface/_zope_interface_coptimizations.so
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe
deleted file mode 100644
index 8b137891..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt
deleted file mode 100644
index 943afdc1..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/requires.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-setuptools
-
-[docs]
-z3c.recipe.sphinxdoc \ No newline at end of file
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt
deleted file mode 100644
index 66179d49..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/EGG-INFO/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-zope
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/__init__.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/__init__.py
deleted file mode 100644
index 2e2033b3..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# this is a namespace package
-try:
- import pkg_resources
- pkg_resources.declare_namespace(__name__)
-except ImportError:
- import pkgutil
- __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.ru.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.ru.txt
deleted file mode 100644
index 7c0dd637..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.ru.txt
+++ /dev/null
@@ -1,803 +0,0 @@
-==========
-ИнтерфейÑÑ‹
-==========
-
-.. contents::
-
-ИнтерфейÑÑ‹ - Ñто объекты Ñпецифицирующие (документирующие) внешнее поведение
-объектов которые их "предоÑтавлÑÑŽÑ‚". ИнтерфейÑÑ‹ определÑÑŽÑ‚ поведение через
-Ñледующие ÑоÑтавлÑющие:
-
-- Ðеформальную документацию в Ñтроках документации
-
-- ÐžÐ¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð²
-
-- Инварианты - уÑловиÑ, которые должны ÑоблюдатьÑÑ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð² предоÑтавлÑющих
- интерфейÑ
-
-ÐžÐ¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð² опиÑывают конкретные атрибуты. Они определÑÑŽÑ‚
-Ð¸Ð¼Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° и предоÑтавлÑÑŽÑ‚ документацию и Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹
-атрибута. ÐžÐ¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð² могут быть заданы неÑколькими путÑми
-как мы увидим ниже.
-
-Определение интерфейÑов
-=======================
-
-ИнтерфейÑÑ‹ определÑÑŽÑ‚ÑÑ Ñ Ð¸Ñпользованием ключевого Ñлова class::
-
- >>> import zope.interface
- >>> class IFoo(zope.interface.Interface):
- ... """Foo blah blah"""
- ...
- ... x = zope.interface.Attribute("""X blah blah""")
- ...
- ... def bar(q, r=None):
- ... """bar blah blah"""
-
-Ð’ примере выше мы Ñоздали Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ `IFoo`. Мы наÑледуем его от
-клаÑÑа `zope.interface.Interface`, который ÑвлÑетÑÑ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑким интерфейÑом
-Ð´Ð»Ñ Ð²Ñех интерфейÑов, как `object` - Ñто родительÑкий клаÑÑ Ð´Ð»Ñ Ð²Ñех новых
-клаÑÑов [#create]_. Данный Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð½Ðµ ÑвлÑетÑÑ ÐºÐ»Ð°ÑÑом, а ÑвлÑетÑÑ
-ИнтерфейÑом, ÑкземплÑром `InterfaceClass`::
-
- >>> type(IFoo)
- <class 'zope.interface.interface.InterfaceClass'>
-
-Мы можем запроÑить у интерфейÑа его документацию::
-
- >>> IFoo.__doc__
- 'Foo blah blah'
-
-и его имÑ::
-
- >>> IFoo.__name__
- 'IFoo'
-
-и даже модуль в котором он определен::
-
- >>> IFoo.__module__
- '__main__'
-
-Ðаш Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñет два атрибута:
-
-`x`
- Это проÑÑ‚ÐµÐ¹ÑˆÐ°Ñ Ñ„Ð¾Ñ€Ð¼Ð° Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð². ОпределÑÑŽÑ‚ÑÑ Ð¸Ð¼Ñ
- и Ñтрока документации. Формально здеÑÑŒ не определÑетÑÑ Ð½Ð¸Ñ‡ÐµÐ³Ð¾ более.
-
-`bar`
- Это метод. Методы определÑÑŽÑ‚ÑÑ ÐºÐ°Ðº обычные функции. Метод - Ñто проÑто
- атрибут который должен быть вызываемым Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼ Ñигнатуры,
- предоÑтавлÑемой определением функции.
-
- Ðадо отметить, что аргумент `self` не указываетÑÑ Ð´Ð»Ñ `bar`. ИнтерфейÑ
- документирует как объект *иÑпользуетÑÑ*. Когда методы ÑкземплÑров клаÑÑов
- вызываютÑÑ Ð¼Ñ‹ не передаем аргумент `self`, таким образом аргумент `self`
- не включаетÑÑ Ð¸ в Ñигнатуру интерфейÑа. Ðргумент `self` в методах
- ÑкземплÑров клаÑÑов на Ñамом деле деталь реализации ÑкземплÑров клаÑÑов
- в Python. Другие объекты кроме ÑкземплÑров клаÑÑов могут предоÑтавлÑÑ‚ÑŒ
- интерфейÑÑ‹ и их методы могут не быть методами ÑкземплÑров клаÑÑов. ДлÑ
- примера модули могут предоÑтавлÑÑ‚ÑŒ интерфейÑÑ‹ и их методы обычно проÑто
- функции. Даже ÑкземплÑры могут иметь методы не ÑвлÑющиеÑÑ Ð¼ÐµÑ‚Ð¾Ð´Ð°Ð¼Ð¸
- ÑкземплÑров клаÑÑа.
-
-Мы можем получить доÑтуп к атрибутам определенным интерфейÑом иÑпользуÑ
-ÑинтакÑÐ¸Ñ Ð´Ð¾Ñтупа к Ñлементам маÑÑива::
-
- >>> x = IFoo['x']
- >>> type(x)
- <class 'zope.interface.interface.Attribute'>
- >>> x.__name__
- 'x'
- >>> x.__doc__
- 'X blah blah'
-
- >>> IFoo.get('x').__name__
- 'x'
-
- >>> IFoo.get('y')
-
-Можно иÑпользовать `in` Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñодержит ли интерфейÑ
-определенное имÑ::
-
- >>> 'x' in IFoo
- True
-
-Мы можем иÑпользовать итератор Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов что бы получить вÑе имена
-которые интерфейÑÑ‹ определÑÑŽÑ‚::
-
- >>> names = list(IFoo)
- >>> names.sort()
- >>> names
- ['bar', 'x']
-
-Ðадо помнить, что интерфейÑÑ‹ не ÑвлÑÑŽÑ‚ÑÑ ÐºÐ»Ð°ÑÑами. Мы не можем получить
-доÑтуп к определениÑм атрибутов через доÑтуп к атрибутам интерфейÑов::
-
- >>> IFoo.x
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- AttributeError: 'InterfaceClass' object has no attribute 'x'
-
-Методы также предоÑтавлÑÑŽÑ‚ доÑтуп к Ñигнатуре метода::
-
- >>> bar = IFoo['bar']
- >>> bar.getSignatureString()
- '(q, r=None)'
-
-ОбъÑвление интерфейÑов
-======================
-
-Определив Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¼Ñ‹ можем теперь *объÑвить*, что объекты предоÑтавлÑÑŽÑ‚ их.
-Перед опиÑанием деталей определим некоторые термины:
-
-*предоÑтавлÑÑ‚ÑŒ*
- Мы говорим, что объекты *предоÑтавлÑÑŽÑ‚* интерфейÑÑ‹. ЕÑли объект
- предоÑтавлÑет интерфейÑ, тогда Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ñпецифицирует поведение объекта.
- Другими Ñловами, интерфейÑÑ‹ Ñпецифицируют поведение объектов которые
- предоÑтавлÑÑŽÑ‚ их.
-
-*реализовать*
- Мы обычно говорим что клаÑÑÑ‹ *реализуют* интерфейÑÑ‹. ЕÑли клаÑÑ
- реализует интерфейÑ, тогда ÑкземплÑры Ñтого клаÑÑа предоÑтавлÑÑŽÑ‚
- данный интерфейÑ. Объекты предоÑтавлÑÑŽÑ‚ интерфейÑÑ‹ которые их клаÑÑÑ‹
- реализуют [#factory]_. (Объекты также могут предоÑтавлÑÑ‚ÑŒ интерфейÑÑ‹ напрÑмую
- Ð¿Ð»ÑŽÑ Ðº тем которые реализуют их клаÑÑÑ‹.)
-
- Важно помнить, что клаÑÑÑ‹ обычно не предоÑтавлÑÑŽÑ‚ интерфейÑÑ‹ которые
- они реализуют.
-
- Мы можем обобщить Ñто до фабрик. Ð”Ð»Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾ вызываемого объекта мы можем
- объÑвить что он производит объекты которые предоÑтавлÑÑŽÑ‚ какие-либо
- интерфейÑÑ‹ Ñказав, что фабрика реализует данные интерфейÑÑ‹.
-
-Теперь поÑле того как мы определили Ñти термины мы можем поговорить об
-API Ð´Ð»Ñ Ð¾Ð±ÑŠÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов.
-
-ОбъÑвление реализуемых интерфейÑов
-----------------------------------
-
-Ðаиболее чаÑто иÑпользуемый путь Ð´Ð»Ñ Ð¾Ð±ÑŠÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов - Ñто иÑпользование
-функции implements в определении клаÑÑа::
-
- >>> class Foo:
- ... zope.interface.implements(IFoo)
- ...
- ... def __init__(self, x=None):
- ... self.x = x
- ...
- ... def bar(self, q, r=None):
- ... return q, r, self.x
- ...
- ... def __repr__(self):
- ... return "Foo(%s)" % self.x
-
-Ð’ Ñтом примере мы объÑвили, что `Foo` реализует `IFoo`. Это значит, что
-ÑкземплÑры `Foo` предоÑтавлÑÑŽÑ‚ `IFoo`. ПоÑле данного объÑÐ²Ð»ÐµÐ½Ð¸Ñ ÐµÑÑ‚ÑŒ
-неÑколько путей Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð° объÑвлений. Во-первых мы можем ÑпроÑить
-что Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½ клаÑÑом::
-
- >>> IFoo.implementedBy(Foo)
- True
-
-Также мы можем ÑпроÑить еÑли Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ñ€ÐµÐ´Ð¾ÑтавлÑетÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸ клаÑÑа::
-
- >>> foo = Foo()
- >>> IFoo.providedBy(foo)
- True
-
-Конечно `Foo` не предоÑтавлÑет `IFoo`, он реализует его::
-
- >>> IFoo.providedBy(Foo)
- False
-
-Мы можем также узнать какие интерфейÑÑ‹ реализуютÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸::
-
- >>> list(zope.interface.implementedBy(Foo))
- [<InterfaceClass __main__.IFoo>]
-
-Это ошибка Ñпрашивать про интерфейÑÑ‹ реализуемые не вызываемым объектом::
-
- >>> IFoo.implementedBy(foo)
- Traceback (most recent call last):
- ...
- TypeError: ('ImplementedBy called for non-factory', Foo(None))
-
- >>> list(zope.interface.implementedBy(foo))
- Traceback (most recent call last):
- ...
- TypeError: ('ImplementedBy called for non-factory', Foo(None))
-
-Также можно узнать какие интерфейÑÑ‹ предоÑтавлÑÑŽÑ‚ÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸::
-
- >>> list(zope.interface.providedBy(foo))
- [<InterfaceClass __main__.IFoo>]
- >>> list(zope.interface.providedBy(Foo))
- []
-
-Мы можем объÑвить интерфейÑÑ‹ реализуемые другими фабриками (кроме клаÑÑов).
-Это можно Ñделать иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð´ÐµÐºÐ¾Ñ€Ð°Ñ‚Ð¾Ñ€ `implementer` (в Ñтиле Python 2.4).
-Ð”Ð»Ñ Ð²ÐµÑ€Ñий Python ниже 2.4 Ñто будет выглÑдеть Ñледующим образом::
-
- >>> def yfoo(y):
- ... foo = Foo()
- ... foo.y = y
- ... return foo
- >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
-
- >>> list(zope.interface.implementedBy(yfoo))
- [<InterfaceClass __main__.IFoo>]
-
-Ðадо заметить, что декоратор implementer может модифицировать Ñвои аргументы.
-Ð’Ñ‹Ð·Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ñторона не должна предполагать, что вÑегда будет ÑоздаватьÑÑ
-новый объект.
-
-XXX: Double check and update these version numbers, and translate to russian:
-
-In zope.interface 3.5.1 and lower, the implementor decorator can not
-be used for classes, but in 3.5.2 and higher it can:
-
- >>> Foo = zope.interface.implementer(IFoo)(Foo)
- >>> list(zope.interface.providedBy(Foo()))
- [<InterfaceClass __main__.IFoo>]
-
-Note that class decorators using the @implementor(IFoo) syntax are only
-supported in Python 2.6 and later.
-
-
-ОбъÑвление предоÑтавлÑемых интерфейÑов
---------------------------------------
-
-Мы можем объÑвлÑÑ‚ÑŒ интерфейÑÑ‹ напрÑмую предоÑтавлÑемые объектами. Предположим
-что мы хотим документировать что делает метод `__init__` клаÑÑа `Foo`. Это
-*точно* не чаÑÑ‚ÑŒ `IFoo`. Обычно мы не должны напрÑмую вызывать метод `__init__`
-Ð´Ð»Ñ ÑкземплÑров Foo. Скорее метод `__init__` ÑвлÑетÑÑ Ñ‡Ð°Ñтью метода `__call__`
-клаÑÑа `Foo`::
-
- >>> class IFooFactory(zope.interface.Interface):
- ... """Create foos"""
- ...
- ... def __call__(x=None):
- ... """Create a foo
- ...
- ... The argument provides the initial value for x ...
- ... """
-
-У Ð½Ð°Ñ ÐµÑÑ‚ÑŒ клаÑÑ Ð¿Ñ€ÐµÐ´Ð¾ÑтавлÑющий данный интерфейÑ, таким образом мы можем
-объÑвить Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ»Ð°ÑÑа::
-
- >>> zope.interface.directlyProvides(Foo, IFooFactory)
-
-Теперь мы видим, что Foo уже предоÑтавлÑет интерфейÑÑ‹::
-
- >>> list(zope.interface.providedBy(Foo))
- [<InterfaceClass __main__.IFooFactory>]
- >>> IFooFactory.providedBy(Foo)
- True
-
-ОбъÑвление интерфейÑов клаÑÑа доÑтаточно чаÑÑ‚Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¸ Ð´Ð»Ñ Ð½ÐµÐµ еÑÑ‚ÑŒ
-ÑÐ¿ÐµÑ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ð±ÑŠÑÐ²Ð»ÐµÐ½Ð¸Ñ `classProvides`, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет объÑвлÑÑ‚ÑŒ
-интерфейÑÑ‹ при определении клаÑÑа::
-
- >>> class Foo2:
- ... zope.interface.implements(IFoo)
- ... zope.interface.classProvides(IFooFactory)
- ...
- ... def __init__(self, x=None):
- ... self.x = x
- ...
- ... def bar(self, q, r=None):
- ... return q, r, self.x
- ...
- ... def __repr__(self):
- ... return "Foo(%s)" % self.x
-
- >>> list(zope.interface.providedBy(Foo2))
- [<InterfaceClass __main__.IFooFactory>]
- >>> IFooFactory.providedBy(Foo2)
- True
-
-ÐŸÐ¾Ñ…Ð¾Ð¶Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ `moduleProvides` поддерживает объÑвление интерфейÑов при
-определении модулÑ. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð° Ñмотрите иÑпользование вызова
-`moduleProvides` в `zope.interface.__init__`, который объÑвлÑет, что
-пакет `zope.interface` предоÑтавлÑет `IInterfaceDeclaration`.
-
-Иногда мы хотим объÑвить интерфейÑÑ‹ ÑкземплÑров, даже еÑли Ñти ÑкземплÑры
-уже берут интерфейÑÑ‹ от Ñвоих клаÑÑов. Предположим, что мы Ñоздаем новый
-Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ `ISpecial`::
-
- >>> class ISpecial(zope.interface.Interface):
- ... reason = zope.interface.Attribute("Reason why we're special")
- ... def brag():
- ... "Brag about being special"
-
-Мы можем Ñделать Ñозданный ÑкземплÑÑ€ foo Ñпециальным предоÑтавив атрибуты
-`reason` и `brag`::
-
- >>> foo.reason = 'I just am'
- >>> def brag():
- ... return "I'm special!"
- >>> foo.brag = brag
- >>> foo.reason
- 'I just am'
- >>> foo.brag()
- "I'm special!"
-
-и объÑвив интерфейÑ::
-
- >>> zope.interface.directlyProvides(foo, ISpecial)
-
-таким образом новый Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°ÐµÑ‚ÑÑ Ð² ÑпиÑок предоÑтавлÑемых интерфейÑов::
-
- >>> ISpecial.providedBy(foo)
- True
- >>> list(zope.interface.providedBy(foo))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
-Мы также можем определить, что интерфейÑÑ‹ напрÑмую предоÑтавлÑÑŽÑ‚ÑÑ
-объектами::
-
- >>> list(zope.interface.directlyProvidedBy(foo))
- [<InterfaceClass __main__.ISpecial>]
-
- >>> newfoo = Foo()
- >>> list(zope.interface.directlyProvidedBy(newfoo))
- []
-
-ÐаÑледуемые объÑвлениÑ
-----------------------
-
-Обычно объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð½Ð°ÑледуютÑÑ::
-
- >>> class SpecialFoo(Foo):
- ... zope.interface.implements(ISpecial)
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
- >>> list(zope.interface.implementedBy(SpecialFoo))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
- >>> list(zope.interface.providedBy(SpecialFoo()))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
-Иногда мы не хотим наÑледовать объÑвлениÑ. Ð’ Ñтом Ñлучае мы можем
-иÑпользовать `implementsOnly` вмеÑто `implements`::
-
- >>> class Special(Foo):
- ... zope.interface.implementsOnly(ISpecial)
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
- >>> list(zope.interface.implementedBy(Special))
- [<InterfaceClass __main__.ISpecial>]
-
- >>> list(zope.interface.providedBy(Special()))
- [<InterfaceClass __main__.ISpecial>]
-
-Внешние объÑвлениÑ
-------------------
-
-Обычно мы Ñоздаем объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ как чаÑÑ‚ÑŒ объÑÐ²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»Ð°ÑÑа. Иногда
-мы можем захотеть Ñоздать объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð²Ð½Ðµ объÑÐ²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»Ð°ÑÑа. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°,
-мы можем хотеть объÑвить интерфейÑÑ‹ Ð´Ð»Ñ ÐºÐ»Ð°ÑÑов которые пиÑали не мы.
-Ð”Ð»Ñ Ñтого может иÑпользоватьÑÑ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ `classImplements`::
-
- >>> class C:
- ... pass
-
- >>> zope.interface.classImplements(C, IFoo)
- >>> list(zope.interface.implementedBy(C))
- [<InterfaceClass __main__.IFoo>]
-
-Мы можем иÑпользовать `classImplementsOnly` Ð´Ð»Ñ Ð¸ÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ð°Ñледуемых
-интерфейÑов::
-
- >>> class C(Foo):
- ... pass
-
- >>> zope.interface.classImplementsOnly(C, ISpecial)
- >>> list(zope.interface.implementedBy(C))
- [<InterfaceClass __main__.ISpecial>]
-
-Объекты объÑвлений
-------------------
-
-Когда мы объÑвлÑем интерфейÑÑ‹ мы Ñоздаем объект *объÑвлениÑ*. Когда мы
-запрашиваем объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÐµÑ‚ÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚ объÑвлениÑ::
-
- >>> type(zope.interface.implementedBy(Special))
- <class 'zope.interface.declarations.Implements'>
-
-Объекты объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸ объекты интерфейÑов во многом похожи друг на друга.
-Ðа Ñамом деле они даже имеют общий базовый клаÑÑ. Важно понÑÑ‚ÑŒ, что они могут
-иÑпользоватьÑÑ Ñ‚Ð°Ð¼ где в объÑвлениÑÑ… ожидаютÑÑ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹ÑÑ‹. Вот проÑтой
-пример::
-
- >>> class Special2(Foo):
- ... zope.interface.implementsOnly(
- ... zope.interface.implementedBy(Foo),
- ... ISpecial,
- ... )
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
-ОбъÑвление здеÑÑŒ практичеÑки такое же как
-``zope.interface.implements(ISpecial)``, отличие только в порÑдке
-интерфейÑов в итоговом объÑвлениÑ::
-
- >>> list(zope.interface.implementedBy(Special2))
- [<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>]
-
-ÐаÑледование интерфейÑов
-========================
-
-ИнтерфейÑÑ‹ могут раÑширÑÑ‚ÑŒ другие интерфейÑÑ‹. Они делают Ñто проÑто
-Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ Ñти интерфейÑÑ‹ как базовые::
-
- >>> class IBlat(zope.interface.Interface):
- ... """Blat blah blah"""
- ...
- ... y = zope.interface.Attribute("y blah blah")
- ... def eek():
- ... """eek blah blah"""
-
- >>> IBlat.__bases__
- (<InterfaceClass zope.interface.Interface>,)
-
- >>> class IBaz(IFoo, IBlat):
- ... """Baz blah"""
- ... def eek(a=1):
- ... """eek in baz blah"""
- ...
-
- >>> IBaz.__bases__
- (<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.IBlat>)
-
- >>> names = list(IBaz)
- >>> names.sort()
- >>> names
- ['bar', 'eek', 'x', 'y']
-
-Заметим, что `IBaz` переопределÑет eek::
-
- >>> IBlat['eek'].__doc__
- 'eek blah blah'
- >>> IBaz['eek'].__doc__
- 'eek in baz blah'
-
-Мы были оÑторожны переопределÑÑ eek ÑовмеÑтимым путем. Когда интерфейÑ
-раÑширÑетÑÑ, раÑширенный Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть ÑовмеÑтимым [#compat]_ Ñ
-раÑширÑемыми интерфейÑами.
-
-Мы можем запроÑить раÑширÑет ли один из интерфейÑов другой::
-
- >>> IBaz.extends(IFoo)
- True
- >>> IBlat.extends(IFoo)
- False
-
-Заметим, что интерфейÑÑ‹ не раÑширÑÑŽÑ‚ Ñами ÑебÑ::
-
- >>> IBaz.extends(IBaz)
- False
-
-Иногда мы можем хотеть что бы они раÑширÑли Ñами ÑебÑ, но вмеÑто Ñтого
-мы можем иÑпользовать `isOrExtends`::
-
- >>> IBaz.isOrExtends(IBaz)
- True
- >>> IBaz.isOrExtends(IFoo)
- True
- >>> IFoo.isOrExtends(IBaz)
- False
-
-Когда мы применÑем итерацию к интерфейÑу мы получаем вÑе имена которые он
-определÑет Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¸Ð¼ÐµÐ½Ð° определенные Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²Ñ‹Ñ… интерфейÑов. Иногда
-мы хотим получить *только* имена определенные интерфейÑом напрÑмую.
-Ð”Ð»Ñ Ñтого мы иÑпользуем метод `names`::
-
- >>> list(IBaz.names())
- ['eek']
-
-ÐаÑледование в Ñлучае Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð²
---------------------------------------------
-
-Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¼Ð¾Ð¶ÐµÑ‚ переопределÑÑ‚ÑŒ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð² из базовых интерфейÑов.
-ЕÑли два базовых интерфейÑа определÑÑŽÑ‚ один и тот же атрибут атрибут
-наÑледуетÑÑ Ð¾Ñ‚ более Ñпецифичного интерфейÑа. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°::
-
- >>> class IBase(zope.interface.Interface):
- ...
- ... def foo():
- ... "base foo doc"
-
- >>> class IBase1(IBase):
- ... pass
-
- >>> class IBase2(IBase):
- ...
- ... def foo():
- ... "base2 foo doc"
-
- >>> class ISub(IBase1, IBase2):
- ... pass
-
-Определение ISub Ð´Ð»Ñ foo будет из IBase2 Ñ‚.к. IBase2 более Ñпецифичен длÑ
-IBase::
-
- >>> ISub['foo'].__doc__
- 'base2 foo doc'
-
-Заметим, что Ñто отличаетÑÑ Ð¾Ñ‚ поиÑка в глубину.
-
-Иногда полезно узнать, что Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñет атрибут напрÑмую. Мы можем
-иÑпользовать метод direct Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð½Ð°Ð¿Ñ€Ñмую определенных атрибутов::
-
- >>> IBase.direct('foo').__doc__
- 'base foo doc'
-
- >>> ISub.direct('foo')
-
-Спецификации
-------------
-
-ИнтерфейÑÑ‹ и объÑÐ²Ð»ÐµÐ½Ð¸Ñ - Ñто Ñпециальные Ñлучаи Ñпецификаций. ОпиÑание
-выше Ð´Ð»Ñ Ð½Ð°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов можно применить и к объÑвлениÑм и
-к ÑпецификациÑм. ОбъÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñ„Ð°ÐºÑ‚Ð¸Ñ‡ÐµÑки раÑширÑÑŽÑ‚ интерфейÑÑ‹ которые они
-объÑвлÑÑŽÑ‚::
-
- >>> class Baz(object):
- ... zope.interface.implements(IBaz)
-
- >>> baz_implements = zope.interface.implementedBy(Baz)
- >>> baz_implements.__bases__
- (<InterfaceClass __main__.IBaz>, <implementedBy ...object>)
-
- >>> baz_implements.extends(IFoo)
- True
-
- >>> baz_implements.isOrExtends(IFoo)
- True
- >>> baz_implements.isOrExtends(baz_implements)
- True
-
-Спецификации (интерфейÑÑ‹ и объÑвлениÑ) предоÑтавлÑÑŽÑ‚ атрибут `__sro__`
-который опиÑывает Ñпецификацию и вÑех ее предков::
-
- >>> baz_implements.__sro__
- (<implementedBy __main__.Baz>,
- <InterfaceClass __main__.IBaz>,
- <InterfaceClass __main__.IFoo>,
- <InterfaceClass __main__.IBlat>,
- <InterfaceClass zope.interface.Interface>,
- <implementedBy ...object>)
-
-Помеченные значениÑ
-===================
-
-ИнтерфейÑÑ‹ и опиÑÐ°Ð½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð² поддерживают механизм раÑширениÑ
-заимÑтвованный из UML и называемый "помеченные значениÑ" который позволÑет
-ÑохранÑÑ‚ÑŒ дополнительные данные::
-
- >>> IFoo.setTaggedValue('date-modified', '2004-04-01')
- >>> IFoo.setTaggedValue('author', 'Jim Fulton')
- >>> IFoo.getTaggedValue('date-modified')
- '2004-04-01'
- >>> IFoo.queryTaggedValue('date-modified')
- '2004-04-01'
- >>> IFoo.queryTaggedValue('datemodified')
- >>> tags = list(IFoo.getTaggedValueTags())
- >>> tags.sort()
- >>> tags
- ['author', 'date-modified']
-
-Ðтрибуты функций конвертируютÑÑ Ð² помеченные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð³Ð´Ð° ÑоздаютÑÑ
-Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð² метода::
-
- >>> class IBazFactory(zope.interface.Interface):
- ... def __call__():
- ... "create one"
- ... __call__.return_type = IBaz
-
- >>> IBazFactory['__call__'].getTaggedValue('return_type')
- <InterfaceClass __main__.IBaz>
-
-Помеченные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð°ÐºÐ¶Ðµ могут быть определены внутри определениÑ
-интерфейÑа::
-
- >>> class IWithTaggedValues(zope.interface.Interface):
- ... zope.interface.taggedValue('squish', 'squash')
- >>> IWithTaggedValues.getTaggedValue('squish')
- 'squash'
-
-Инварианты
-==========
-
-ИнтерфейÑÑ‹ могут опиÑывать уÑÐ»Ð¾Ð²Ð¸Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ должны быть Ñоблюдены Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð²
-которые их предоÑтавлÑÑŽÑ‚. Эти уÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð¿Ð¸ÑываютÑÑ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¾Ð´Ð¸Ð½ или более
-инвариантов. Инварианты - Ñто вызываемые объекты которые будут вызваны
-Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð¼ предоÑтавлÑющим Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð² качеÑтве параметра. Инвариант
-должен выкинуть иÑключение `Invalid` еÑли уÑловие не Ñоблюдено. Ðапример::
-
- >>> class RangeError(zope.interface.Invalid):
- ... """A range has invalid limits"""
- ... def __repr__(self):
- ... return "RangeError(%r)" % self.args
-
- >>> def range_invariant(ob):
- ... if ob.max < ob.min:
- ... raise RangeError(ob)
-
-Определив Ñтот инвариант мы можем иÑпользовать его в определении интерфейÑов::
-
- >>> class IRange(zope.interface.Interface):
- ... min = zope.interface.Attribute("Lower bound")
- ... max = zope.interface.Attribute("Upper bound")
- ...
- ... zope.interface.invariant(range_invariant)
-
-ИнтерфейÑÑ‹ имеют метод Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ Ñвоих инвариантов::
-
- >>> class Range(object):
- ... zope.interface.implements(IRange)
- ...
- ... def __init__(self, min, max):
- ... self.min, self.max = min, max
- ...
- ... def __repr__(self):
- ... return "Range(%s, %s)" % (self.min, self.max)
-
- >>> IRange.validateInvariants(Range(1,2))
- >>> IRange.validateInvariants(Range(1,1))
- >>> IRange.validateInvariants(Range(2,1))
- Traceback (most recent call last):
- ...
- RangeError: Range(2, 1)
-
-Ð’ Ñлучае неÑкольких инвариантов мы можем захотеть оÑтановить проверку поÑле
-первой ошибки. ЕÑли мы передадим в `validateInvariants` пуÑтой ÑпиÑок тогда
-будет выкинуто единÑтвенное иÑключение `Invalid` Ñо ÑпиÑком иÑключений
-как аргументом::
-
- >>> from zope.interface.exceptions import Invalid
- >>> errors = []
- >>> try:
- ... IRange.validateInvariants(Range(2,1), errors)
- ... except Invalid, e:
- ... str(e)
- '[RangeError(Range(2, 1))]'
-
-И ÑпиÑок будет заполнен индивидуальными иÑключениÑми::
-
- >>> errors
- [RangeError(Range(2, 1))]
-
- >>> del errors[:]
-
-ÐдаптациÑ
-=========
-
-ИнтерфейÑÑ‹ могут быть вызваны Ð´Ð»Ñ Ð¾ÑущеÑÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð°Ñ†Ð¸Ð¸. Эта Ñемантика
-оÑнована на функции adapt из PEP 246. ЕÑли объект не может быть адаптирован
-будет выкинут TypeError::
-
- >>> class I(zope.interface.Interface):
- ... pass
-
- >>> I(0)
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
-
-только еÑли альтернативное значение не передано как второй аргумент::
-
- >>> I(0, 'bob')
- 'bob'
-
-ЕÑли объект уже реализует нужный Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¾Ð½ будет возвращен::
-
- >>> class C(object):
- ... zope.interface.implements(I)
-
- >>> obj = C()
- >>> I(obj) is obj
- True
-
-ЕÑли объект реализует __conform__, тогда она будет иÑпользована::
-
- >>> class C(object):
- ... zope.interface.implements(I)
- ... def __conform__(self, proto):
- ... return 0
-
- >>> I(C())
- 0
-
-Также еÑли приÑутÑтвуют функции Ð´Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° адаптации (Ñм. __adapt__) они будут
-иÑпользованы::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> def adapt_0_to_42(iface, obj):
- ... if obj == 0:
- ... return 42
-
- >>> adapter_hooks.append(adapt_0_to_42)
- >>> I(0)
- 42
-
- >>> adapter_hooks.remove(adapt_0_to_42)
- >>> I(0)
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
-
-
-__adapt__
----------
-
- >>> class I(zope.interface.Interface):
- ... pass
-
-ИнтерфейÑÑ‹ реализуют метод __adapt__ из PEP 246. Этот метод обычно не
-вызываетÑÑ Ð½Ð°Ð¿Ñ€Ñмую. Он вызываетÑÑ Ð°Ñ€Ñ…Ð¸Ñ‚ÐµÐºÑ‚ÑƒÑ€Ð¾Ð¹ адаптации из PEP 246 и методом
-__call__ интерфейÑов. Метод адаптации отвечает за адаптацию объекта к
-получателю. ВерÑÐ¸Ñ Ð¿Ð¾ умолчанию возвращает None::
-
- >>> I.__adapt__(0)
-
-еÑли только переданный объект не предоÑтавлÑет нужный интерфейÑ::
-
- >>> class C(object):
- ... zope.interface.implements(I)
-
- >>> obj = C()
- >>> I.__adapt__(obj) is obj
- True
-
-Функции Ð´Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° адаптации могут быть добавлены (или удалены) длÑ
-предоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð°Ñ†Ð¸Ð¸ "на заказ". Мы уÑтановим глупую функцию котораÑ
-адаптирует 0 к 42. Мы уÑтанавливаем функцию проÑто добавлÑÑ ÐµÐµ к ÑпиÑку
-adapter_hooks::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> def adapt_0_to_42(iface, obj):
- ... if obj == 0:
- ... return 42
-
- >>> adapter_hooks.append(adapt_0_to_42)
- >>> I.__adapt__(0)
- 42
-
-Функции должны возвращать либо адаптер, либо None еÑли адаптер не найден.
-Функции могут быть удалены удалением их из ÑпиÑка::
-
- >>> adapter_hooks.remove(adapt_0_to_42)
- >>> I.__adapt__(0)
-
-
-.. [#create] ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¿Ñ€Ð¸Ñ‡Ð¸Ð½Ð° по которой мы наÑледуемÑÑ Ð¾Ñ‚ `Interface` - Ñто
- что бы быть уверенными в том, что ключевое Ñлово class будет
- Ñоздавать интерфейÑ, а не клаÑÑ.
-
- ЕÑÑ‚ÑŒ возможноÑÑ‚ÑŒ Ñоздать интерфейÑÑ‹ вызвав Ñпециальный
- клаÑÑ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа напрÑмую. Ð”ÐµÐ»Ð°Ñ Ñто, возможно (и в редких
- ÑлучаÑÑ… полезно) Ñоздать интерфейÑÑ‹ которые не наÑледуютÑÑ
- от `Interface`. Однако иÑпользование Ñтой техники выходит
- за рамки данного документа.
-
-.. [#factory] КлаÑÑÑ‹ - Ñто фабрики. Они могут быть вызваны Ð´Ð»Ñ ÑозданиÑ
- Ñвоих ÑкземплÑров. Мы ожидаем что в итоге мы раÑширим
- концепцию реализации на другие типы фабрик, таким образом
- мы Ñможем объÑвлÑÑ‚ÑŒ интерфейÑÑ‹ предоÑтавлÑемые Ñозданными
- фабриками объектами.
-
-.. [#compat] Цель - заменÑемоÑÑ‚ÑŒ. Объект который предоÑтавлÑет раÑширенный
- Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть заменÑем в качеÑтве объектов которые
- предоÑтавлÑÑŽÑ‚ раÑширÑемый интерфейÑ. Ð’ нашем примере объект
- который предоÑтавлÑет IBaz должен быть иÑпользуемым и
- в Ñлучае еÑли ожидаетÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚ который предоÑтавлÑет IBlat.
-
- Ð ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа не требует Ñтого. Ðо возможно в дальнейшем
- она должна будет делать какие-либо проверки.
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt
deleted file mode 100644
index e5bc7b34..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt
+++ /dev/null
@@ -1,829 +0,0 @@
-==========
-Interfaces
-==========
-
-Interfaces are objects that specify (document) the external behavior
-of objects that "provide" them. An interface specifies behavior
-through:
-
-- Informal documentation in a doc string
-
-- Attribute definitions
-
-- Invariants, which are conditions that must hold for objects that
- provide the interface
-
-Attribute definitions specify specific attributes. They define the
-attribute name and provide documentation and constraints of attribute
-values. Attribute definitions can take a number of forms, as we'll
-see below.
-
-Defining interfaces
-===================
-
-Interfaces are defined using Python class statements::
-
- >>> import zope.interface
- >>> class IFoo(zope.interface.Interface):
- ... """Foo blah blah"""
- ...
- ... x = zope.interface.Attribute("""X blah blah""")
- ...
- ... def bar(q, r=None):
- ... """bar blah blah"""
-
-In the example above, we've created an interface, `IFoo`. We
-subclassed `zope.interface.Interface`, which is an ancestor interface for
-all interfaces, much as `object` is an ancestor of all new-style
-classes [#create]_. The interface is not a class, it's an Interface,
-an instance of `InterfaceClass`::
-
- >>> type(IFoo)
- <class 'zope.interface.interface.InterfaceClass'>
-
-We can ask for the interface's documentation::
-
- >>> IFoo.__doc__
- 'Foo blah blah'
-
-and its name::
-
- >>> IFoo.__name__
- 'IFoo'
-
-and even its module::
-
- >>> IFoo.__module__
- '__main__'
-
-The interface defined two attributes:
-
-`x`
- This is the simplest form of attribute definition. It has a name
- and a doc string. It doesn't formally specify anything else.
-
-`bar`
- This is a method. A method is defined via a function definition. A
- method is simply an attribute constrained to be a callable with a
- particular signature, as provided by the function definition.
-
- Note that `bar` doesn't take a `self` argument. Interfaces document
- how an object is *used*. When calling instance methods, you don't
- pass a `self` argument, so a `self` argument isn't included in the
- interface signature. The `self` argument in instance methods is
- really an implementation detail of Python instances. Other objects,
- besides instances can provide interfaces and their methods might not
- be instance methods. For example, modules can provide interfaces and
- their methods are usually just functions. Even instances can have
- methods that are not instance methods.
-
-You can access the attributes defined by an interface using mapping
-syntax::
-
- >>> x = IFoo['x']
- >>> type(x)
- <class 'zope.interface.interface.Attribute'>
- >>> x.__name__
- 'x'
- >>> x.__doc__
- 'X blah blah'
-
- >>> IFoo.get('x').__name__
- 'x'
-
- >>> IFoo.get('y')
-
-You can use `in` to determine if an interface defines a name::
-
- >>> 'x' in IFoo
- True
-
-You can iterate over interfaces to get the names they define::
-
- >>> names = list(IFoo)
- >>> names.sort()
- >>> names
- ['bar', 'x']
-
-Remember that interfaces aren't classes. You can't access attribute
-definitions as attributes of interfaces::
-
- >>> IFoo.x
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- AttributeError: 'InterfaceClass' object has no attribute 'x'
-
-Methods provide access to the method signature::
-
- >>> bar = IFoo['bar']
- >>> bar.getSignatureString()
- '(q, r=None)'
-
-TODO
- Methods really should have a better API. This is something that
- needs to be improved.
-
-Declaring interfaces
-====================
-
-Having defined interfaces, we can *declare* that objects provide
-them. Before we describe the details, lets define some terms:
-
-*provide*
- We say that objects *provide* interfaces. If an object provides an
- interface, then the interface specifies the behavior of the
- object. In other words, interfaces specify the behavior of the
- objects that provide them.
-
-*implement*
- We normally say that classes *implement* interfaces. If a class
- implements an interface, then the instances of the class provide
- the interface. Objects provide interfaces that their classes
- implement [#factory]_. (Objects can provide interfaces directly,
- in addition to what their classes implement.)
-
- It is important to note that classes don't usually provide the
- interfaces that they implement.
-
- We can generalize this to factories. For any callable object we
- can declare that it produces objects that provide some interfaces
- by saying that the factory implements the interfaces.
-
-Now that we've defined these terms, we can talk about the API for
-declaring interfaces.
-
-Declaring implemented interfaces
---------------------------------
-
-The most common way to declare interfaces is using the implements
-function in a class statement::
-
- >>> class Foo:
- ... zope.interface.implements(IFoo)
- ...
- ... def __init__(self, x=None):
- ... self.x = x
- ...
- ... def bar(self, q, r=None):
- ... return q, r, self.x
- ...
- ... def __repr__(self):
- ... return "Foo(%s)" % self.x
-
-
-In this example, we declared that `Foo` implements `IFoo`. This means
-that instances of `Foo` provide `IFoo`. Having made this declaration,
-there are several ways we can introspect the declarations. First, we
-can ask an interface whether it is implemented by a class::
-
- >>> IFoo.implementedBy(Foo)
- True
-
-And we can ask whether an interface is provided by an object::
-
- >>> foo = Foo()
- >>> IFoo.providedBy(foo)
- True
-
-Of course, `Foo` doesn't provide `IFoo`, it implements it::
-
- >>> IFoo.providedBy(Foo)
- False
-
-We can also ask what interfaces are implemented by an object::
-
- >>> list(zope.interface.implementedBy(Foo))
- [<InterfaceClass __main__.IFoo>]
-
-It's an error to ask for interfaces implemented by a non-callable
-object::
-
- >>> IFoo.implementedBy(foo)
- Traceback (most recent call last):
- ...
- TypeError: ('ImplementedBy called for non-factory', Foo(None))
-
- >>> list(zope.interface.implementedBy(foo))
- Traceback (most recent call last):
- ...
- TypeError: ('ImplementedBy called for non-factory', Foo(None))
-
-Similarly, we can ask what interfaces are provided by an object::
-
- >>> list(zope.interface.providedBy(foo))
- [<InterfaceClass __main__.IFoo>]
- >>> list(zope.interface.providedBy(Foo))
- []
-
-We can declare interfaces implemented by other factories (besides
-classes). We do this using a Python-2.4-style decorator named
-`implementer`. In versions of Python before 2.4, this looks like::
-
- >>> def yfoo(y):
- ... foo = Foo()
- ... foo.y = y
- ... return foo
- >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
-
- >>> list(zope.interface.implementedBy(yfoo))
- [<InterfaceClass __main__.IFoo>]
-
-Note that the implementer decorator may modify it's argument. Callers
-should not assume that a new object is created.
-
-Using implementer also works on callable objects. This is used by
-zope.formlib, as an example.
-
- >>> class yfactory:
- ... def __call__(self, y):
- ... foo = Foo()
- ... foo.y = y
- ... return foo
- >>> yfoo = yfactory()
- >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
-
- >>> list(zope.interface.implementedBy(yfoo))
- [<InterfaceClass __main__.IFoo>]
-
-XXX: Double check and update these version numbers:
-
-In zope.interface 3.5.2 and lower, the implementor decorator can not
-be used for classes, but in 3.6.0 and higher it can:
-
- >>> Foo = zope.interface.implementer(IFoo)(Foo)
- >>> list(zope.interface.providedBy(Foo()))
- [<InterfaceClass __main__.IFoo>]
-
-Note that class decorators using the @implementor(IFoo) syntax are only
-supported in Python 2.6 and later.
-
-
-Declaring provided interfaces
------------------------------
-
-We can declare interfaces directly provided by objects. Suppose that
-we want to document what the `__init__` method of the `Foo` class
-does. It's not *really* part of `IFoo`. You wouldn't normally call
-the `__init__` method on Foo instances. Rather, the `__init__` method
-is part of the `Foo`'s `__call__` method::
-
- >>> class IFooFactory(zope.interface.Interface):
- ... """Create foos"""
- ...
- ... def __call__(x=None):
- ... """Create a foo
- ...
- ... The argument provides the initial value for x ...
- ... """
-
-It's the class that provides this interface, so we declare the
-interface on the class::
-
- >>> zope.interface.directlyProvides(Foo, IFooFactory)
-
-And then, we'll see that Foo provides some interfaces::
-
- >>> list(zope.interface.providedBy(Foo))
- [<InterfaceClass __main__.IFooFactory>]
- >>> IFooFactory.providedBy(Foo)
- True
-
-Declaring class interfaces is common enough that there's a special
-declaration function for it, `classProvides`, that allows the
-declaration from within a class statement::
-
- >>> class Foo2:
- ... zope.interface.implements(IFoo)
- ... zope.interface.classProvides(IFooFactory)
- ...
- ... def __init__(self, x=None):
- ... self.x = x
- ...
- ... def bar(self, q, r=None):
- ... return q, r, self.x
- ...
- ... def __repr__(self):
- ... return "Foo(%s)" % self.x
-
- >>> list(zope.interface.providedBy(Foo2))
- [<InterfaceClass __main__.IFooFactory>]
- >>> IFooFactory.providedBy(Foo2)
- True
-
-There's a similar function, `moduleProvides`, that supports interface
-declarations from within module definitions. For example, see the use
-of `moduleProvides` call in `zope.interface.__init__`, which declares that
-the package `zope.interface` provides `IInterfaceDeclaration`.
-
-Sometimes, we want to declare interfaces on instances, even though
-those instances get interfaces from their classes. Suppose we create
-a new interface, `ISpecial`::
-
- >>> class ISpecial(zope.interface.Interface):
- ... reason = zope.interface.Attribute("Reason why we're special")
- ... def brag():
- ... "Brag about being special"
-
-We can make an existing foo instance special by providing `reason`
-and `brag` attributes::
-
- >>> foo.reason = 'I just am'
- >>> def brag():
- ... return "I'm special!"
- >>> foo.brag = brag
- >>> foo.reason
- 'I just am'
- >>> foo.brag()
- "I'm special!"
-
-and by declaring the interface::
-
- >>> zope.interface.directlyProvides(foo, ISpecial)
-
-then the new interface is included in the provided interfaces::
-
- >>> ISpecial.providedBy(foo)
- True
- >>> list(zope.interface.providedBy(foo))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
-We can find out what interfaces are directly provided by an object::
-
- >>> list(zope.interface.directlyProvidedBy(foo))
- [<InterfaceClass __main__.ISpecial>]
-
- >>> newfoo = Foo()
- >>> list(zope.interface.directlyProvidedBy(newfoo))
- []
-
-Inherited declarations
-----------------------
-
-Normally, declarations are inherited::
-
- >>> class SpecialFoo(Foo):
- ... zope.interface.implements(ISpecial)
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
- >>> list(zope.interface.implementedBy(SpecialFoo))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
- >>> list(zope.interface.providedBy(SpecialFoo()))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
-Sometimes, you don't want to inherit declarations. In that case, you
-can use `implementsOnly`, instead of `implements`::
-
- >>> class Special(Foo):
- ... zope.interface.implementsOnly(ISpecial)
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
- >>> list(zope.interface.implementedBy(Special))
- [<InterfaceClass __main__.ISpecial>]
-
- >>> list(zope.interface.providedBy(Special()))
- [<InterfaceClass __main__.ISpecial>]
-
-External declarations
----------------------
-
-Normally, we make implementation declarations as part of a class
-definition. Sometimes, we may want to make declarations from outside
-the class definition. For example, we might want to declare interfaces
-for classes that we didn't write. The function `classImplements` can
-be used for this purpose::
-
- >>> class C:
- ... pass
-
- >>> zope.interface.classImplements(C, IFoo)
- >>> list(zope.interface.implementedBy(C))
- [<InterfaceClass __main__.IFoo>]
-
-We can use `classImplementsOnly` to exclude inherited interfaces::
-
- >>> class C(Foo):
- ... pass
-
- >>> zope.interface.classImplementsOnly(C, ISpecial)
- >>> list(zope.interface.implementedBy(C))
- [<InterfaceClass __main__.ISpecial>]
-
-
-
-Declaration Objects
--------------------
-
-When we declare interfaces, we create *declaration* objects. When we
-query declarations, declaration objects are returned::
-
- >>> type(zope.interface.implementedBy(Special))
- <class 'zope.interface.declarations.Implements'>
-
-Declaration objects and interface objects are similar in many ways. In
-fact, they share a common base class. The important thing to realize
-about them is that they can be used where interfaces are expected in
-declarations. Here's a silly example::
-
- >>> class Special2(Foo):
- ... zope.interface.implementsOnly(
- ... zope.interface.implementedBy(Foo),
- ... ISpecial,
- ... )
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
-The declaration here is almost the same as
-``zope.interface.implements(ISpecial)``, except that the order of
-interfaces in the resulting declaration is different::
-
- >>> list(zope.interface.implementedBy(Special2))
- [<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>]
-
-
-Interface Inheritance
-=====================
-
-Interfaces can extend other interfaces. They do this simply by listing
-the other interfaces as base interfaces::
-
- >>> class IBlat(zope.interface.Interface):
- ... """Blat blah blah"""
- ...
- ... y = zope.interface.Attribute("y blah blah")
- ... def eek():
- ... """eek blah blah"""
-
- >>> IBlat.__bases__
- (<InterfaceClass zope.interface.Interface>,)
-
- >>> class IBaz(IFoo, IBlat):
- ... """Baz blah"""
- ... def eek(a=1):
- ... """eek in baz blah"""
- ...
-
- >>> IBaz.__bases__
- (<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.IBlat>)
-
- >>> names = list(IBaz)
- >>> names.sort()
- >>> names
- ['bar', 'eek', 'x', 'y']
-
-Note that `IBaz` overrides eek::
-
- >>> IBlat['eek'].__doc__
- 'eek blah blah'
- >>> IBaz['eek'].__doc__
- 'eek in baz blah'
-
-We were careful to override eek in a compatible way. When extending
-an interface, the extending interface should be compatible [#compat]_
-with the extended interfaces.
-
-We can ask whether one interface extends another::
-
- >>> IBaz.extends(IFoo)
- True
- >>> IBlat.extends(IFoo)
- False
-
-Note that interfaces don't extend themselves::
-
- >>> IBaz.extends(IBaz)
- False
-
-Sometimes we wish they did, but we can, instead use `isOrExtends`::
-
- >>> IBaz.isOrExtends(IBaz)
- True
- >>> IBaz.isOrExtends(IFoo)
- True
- >>> IFoo.isOrExtends(IBaz)
- False
-
-When we iterate over an interface, we get all of the names it defines,
-including names defined by base interfaces. Sometimes, we want *just*
-the names defined by the interface directly. We bane use the `names`
-method for that::
-
- >>> list(IBaz.names())
- ['eek']
-
-Inheritance of attribute specifications
----------------------------------------
-
-An interface may override attribute definitions from base interfaces.
-If two base interfaces define the same attribute, the attribute is
-inherited from the most specific interface. For example, with::
-
- >>> class IBase(zope.interface.Interface):
- ...
- ... def foo():
- ... "base foo doc"
-
- >>> class IBase1(IBase):
- ... pass
-
- >>> class IBase2(IBase):
- ...
- ... def foo():
- ... "base2 foo doc"
-
- >>> class ISub(IBase1, IBase2):
- ... pass
-
-ISub's definition of foo is the one from IBase2, since IBase2 is more
-specific that IBase::
-
- >>> ISub['foo'].__doc__
- 'base2 foo doc'
-
-Note that this differs from a depth-first search.
-
-Sometimes, it's useful to ask whether an interface defines an
-attribute directly. You can use the direct method to get a directly
-defined definitions::
-
- >>> IBase.direct('foo').__doc__
- 'base foo doc'
-
- >>> ISub.direct('foo')
-
-Specifications
---------------
-
-Interfaces and declarations are both special cases of specifications.
-What we described above for interface inheritance applies to both
-declarations and specifications. Declarations actually extend the
-interfaces that they declare::
-
- >>> class Baz(object):
- ... zope.interface.implements(IBaz)
-
- >>> baz_implements = zope.interface.implementedBy(Baz)
- >>> baz_implements.__bases__
- (<InterfaceClass __main__.IBaz>, <implementedBy ...object>)
-
- >>> baz_implements.extends(IFoo)
- True
-
- >>> baz_implements.isOrExtends(IFoo)
- True
- >>> baz_implements.isOrExtends(baz_implements)
- True
-
-Specifications (interfaces and declarations) provide an `__sro__`
-that lists the specification and all of it's ancestors::
-
- >>> baz_implements.__sro__
- (<implementedBy __main__.Baz>,
- <InterfaceClass __main__.IBaz>,
- <InterfaceClass __main__.IFoo>,
- <InterfaceClass __main__.IBlat>,
- <InterfaceClass zope.interface.Interface>,
- <implementedBy ...object>)
-
-
-Tagged Values
-=============
-
-Interfaces and attribute descriptions support an extension mechanism,
-borrowed from UML, called "tagged values" that lets us store extra
-data::
-
- >>> IFoo.setTaggedValue('date-modified', '2004-04-01')
- >>> IFoo.setTaggedValue('author', 'Jim Fulton')
- >>> IFoo.getTaggedValue('date-modified')
- '2004-04-01'
- >>> IFoo.queryTaggedValue('date-modified')
- '2004-04-01'
- >>> IFoo.queryTaggedValue('datemodified')
- >>> tags = list(IFoo.getTaggedValueTags())
- >>> tags.sort()
- >>> tags
- ['author', 'date-modified']
-
-Function attributes are converted to tagged values when method
-attribute definitions are created::
-
- >>> class IBazFactory(zope.interface.Interface):
- ... def __call__():
- ... "create one"
- ... __call__.return_type = IBaz
-
- >>> IBazFactory['__call__'].getTaggedValue('return_type')
- <InterfaceClass __main__.IBaz>
-
-Tagged values can also be defined from within an interface definition::
-
- >>> class IWithTaggedValues(zope.interface.Interface):
- ... zope.interface.taggedValue('squish', 'squash')
- >>> IWithTaggedValues.getTaggedValue('squish')
- 'squash'
-
-Invariants
-==========
-
-Interfaces can express conditions that must hold for objects that
-provide them. These conditions are expressed using one or more
-invariants. Invariants are callable objects that will be called with
-an object that provides an interface. An invariant raises an `Invalid`
-exception if the condition doesn't hold. Here's an example::
-
- >>> class RangeError(zope.interface.Invalid):
- ... """A range has invalid limits"""
- ... def __repr__(self):
- ... return "RangeError(%r)" % self.args
-
- >>> def range_invariant(ob):
- ... if ob.max < ob.min:
- ... raise RangeError(ob)
-
-Given this invariant, we can use it in an interface definition::
-
- >>> class IRange(zope.interface.Interface):
- ... min = zope.interface.Attribute("Lower bound")
- ... max = zope.interface.Attribute("Upper bound")
- ...
- ... zope.interface.invariant(range_invariant)
-
-Interfaces have a method for checking their invariants::
-
- >>> class Range(object):
- ... zope.interface.implements(IRange)
- ...
- ... def __init__(self, min, max):
- ... self.min, self.max = min, max
- ...
- ... def __repr__(self):
- ... return "Range(%s, %s)" % (self.min, self.max)
-
- >>> IRange.validateInvariants(Range(1,2))
- >>> IRange.validateInvariants(Range(1,1))
- >>> IRange.validateInvariants(Range(2,1))
- Traceback (most recent call last):
- ...
- RangeError: Range(2, 1)
-
-If you have multiple invariants, you may not want to stop checking
-after the first error. If you pass a list to `validateInvariants`,
-then a single `Invalid` exception will be raised with the list of
-exceptions as it's argument::
-
- >>> from zope.interface.exceptions import Invalid
- >>> errors = []
- >>> try:
- ... IRange.validateInvariants(Range(2,1), errors)
- ... except Invalid, e:
- ... str(e)
- '[RangeError(Range(2, 1))]'
-
-And the list will be filled with the individual exceptions::
-
- >>> errors
- [RangeError(Range(2, 1))]
-
-
- >>> del errors[:]
-
-Adaptation
-==========
-
-Interfaces can be called to perform adaptation.
-
-The semantics are based on those of the PEP 246 adapt function.
-
-If an object cannot be adapted, then a TypeError is raised::
-
- >>> class I(zope.interface.Interface):
- ... pass
-
- >>> I(0)
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
-
-
-
-unless an alternate value is provided as a second positional argument::
-
- >>> I(0, 'bob')
- 'bob'
-
-If an object already implements the interface, then it will be returned::
-
- >>> class C(object):
- ... zope.interface.implements(I)
-
- >>> obj = C()
- >>> I(obj) is obj
- True
-
-If an object implements __conform__, then it will be used::
-
- >>> class C(object):
- ... zope.interface.implements(I)
- ... def __conform__(self, proto):
- ... return 0
-
- >>> I(C())
- 0
-
-Adapter hooks (see __adapt__) will also be used, if present::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> def adapt_0_to_42(iface, obj):
- ... if obj == 0:
- ... return 42
-
- >>> adapter_hooks.append(adapt_0_to_42)
- >>> I(0)
- 42
-
- >>> adapter_hooks.remove(adapt_0_to_42)
- >>> I(0)
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
-
-__adapt__
----------
-
- >>> class I(zope.interface.Interface):
- ... pass
-
-Interfaces implement the PEP 246 __adapt__ method.
-
-This method is normally not called directly. It is called by the PEP
-246 adapt framework and by the interface __call__ operator.
-
-The adapt method is responsible for adapting an object to the
-reciever.
-
-The default version returns None::
-
- >>> I.__adapt__(0)
-
-unless the object given provides the interface::
-
- >>> class C(object):
- ... zope.interface.implements(I)
-
- >>> obj = C()
- >>> I.__adapt__(obj) is obj
- True
-
-Adapter hooks can be provided (or removed) to provide custom
-adaptation. We'll install a silly hook that adapts 0 to 42.
-We install a hook by simply adding it to the adapter_hooks
-list::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> def adapt_0_to_42(iface, obj):
- ... if obj == 0:
- ... return 42
-
- >>> adapter_hooks.append(adapt_0_to_42)
- >>> I.__adapt__(0)
- 42
-
-Hooks must either return an adapter, or None if no adapter can
-be found.
-
-Hooks can be uninstalled by removing them from the list::
-
- >>> adapter_hooks.remove(adapt_0_to_42)
- >>> I.__adapt__(0)
-
-
-.. [#create] The main reason we subclass `Interface` is to cause the
- Python class statement to create an interface, rather
- than a class.
-
- It's possible to create interfaces by calling a special
- interface class directly. Doing this, it's possible
- (and, on rare occasions, useful) to create interfaces
- that don't descend from `Interface`. Using this
- technique is beyond the scope of this document.
-
-.. [#factory] Classes are factories. They can be called to create
- their instances. We expect that we will eventually
- extend the concept of implementation to other kinds of
- factories, so that we can declare the interfaces
- provided by the objects created.
-
-.. [#compat] The goal is substitutability. An object that provides an
- extending interface should be substitutable for an object
- that provides the extended interface. In our example, an
- object that provides IBaz should be usable whereever an
- object that provides IBlat is expected.
-
- The interface implementation doesn't enforce this.
- but maybe it should do some checks.
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/__init__.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/__init__.py
deleted file mode 100644
index 8b05f6be..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/__init__.py
+++ /dev/null
@@ -1,79 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interfaces
-
-This package implements the Python "scarecrow" proposal.
-
-The package exports two objects, `Interface` and `Attribute` directly. It also
-exports several helper methods. Interface is used to create an interface with
-a class statement, as in:
-
- class IMyInterface(Interface):
- '''Interface documentation
- '''
-
- def meth(arg1, arg2):
- '''Documentation for meth
- '''
-
- # Note that there is no self argument
-
-To find out what you can do with interfaces, see the interface
-interface, `IInterface` in the `interfaces` module.
-
-The package has several public modules:
-
- o `declarations` provides utilities to declare interfaces on objects. It
- also provides a wide range of helpful utilities that aid in managing
- declared interfaces. Most of its public names are however imported here.
-
- o `document` has a utility for documenting an interface as structured text.
-
- o `exceptions` has the interface-defined exceptions
-
- o `interfaces` contains a list of all public interfaces for this package.
-
- o `verify` has utilities for verifying implementations of interfaces.
-
-See the module doc strings for more information.
-"""
-__docformat__ = 'restructuredtext'
-
-from zope.interface.interface import Interface, _wire
-
-# Need to actually get the interface elements to implement the right interfaces
-_wire()
-del _wire
-
-from zope.interface.interface import Attribute, invariant, taggedValue
-
-from zope.interface.declarations import providedBy, implementedBy
-from zope.interface.declarations import classImplements, classImplementsOnly
-from zope.interface.declarations import directlyProvidedBy, directlyProvides
-from zope.interface.declarations import alsoProvides, provider
-from zope.interface.declarations import implementer, implementer_only
-from zope.interface.declarations import implements, implementsOnly
-from zope.interface.declarations import classProvides, moduleProvides
-from zope.interface.declarations import noLongerProvides, Declaration
-from zope.interface.exceptions import Invalid
-
-# The following are to make spec pickles cleaner
-from zope.interface.declarations import Provides
-
-
-from zope.interface.interfaces import IInterfaceDeclaration
-
-moduleProvides(IInterfaceDeclaration)
-
-__all__ = ('Interface', 'Attribute') + tuple(IInterfaceDeclaration)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_flatten.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_flatten.py
deleted file mode 100644
index a80c2de4..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_flatten.py
+++ /dev/null
@@ -1,35 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Adapter-style interface registry
-
-See Adapter class.
-"""
-from zope.interface import Declaration
-
-def _flatten(implements, include_None=0):
-
- try:
- r = implements.flattened()
- except AttributeError:
- if implements is None:
- r=()
- else:
- r = Declaration(implements).flattened()
-
- if not include_None:
- return r
-
- r = list(r)
- r.append(None)
- return r
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.c b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.c
deleted file mode 100644
index 7b0f8166..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.c
+++ /dev/null
@@ -1,1682 +0,0 @@
-/*###########################################################################
- #
- # Copyright (c) 2003 Zope Foundation and Contributors.
- # All Rights Reserved.
- #
- # This software is subject to the provisions of the Zope Public License,
- # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
- # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
- # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
- # FOR A PARTICULAR PURPOSE.
- #
- ############################################################################*/
-
-#include "Python.h"
-#include "structmember.h"
-
-#define TYPE(O) ((PyTypeObject*)(O))
-#define OBJECT(O) ((PyObject*)(O))
-#define CLASSIC(O) ((PyClassObject*)(O))
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(a, b) PyObject_HEAD_INIT(a) b,
-#endif
-#ifndef Py_TYPE
-#define Py_TYPE(o) ((o)->ob_type)
-#endif
-
-static PyObject *str__dict__, *str__implemented__, *strextends;
-static PyObject *BuiltinImplementationSpecifications, *str__provides__;
-static PyObject *str__class__, *str__providedBy__;
-static PyObject *empty, *fallback, *str_implied, *str_cls, *str_implements;
-static PyObject *str__conform__, *str_call_conform, *adapter_hooks;
-static PyObject *str_uncached_lookup, *str_uncached_lookupAll;
-static PyObject *str_uncached_subscriptions;
-static PyObject *str_registry, *strro, *str_generation, *strchanged;
-
-static PyTypeObject *Implements;
-
-static int imported_declarations = 0;
-
-static int
-import_declarations(void)
-{
- PyObject *declarations, *i;
-
- declarations = PyImport_ImportModule("zope.interface.declarations");
- if (declarations == NULL)
- return -1;
-
- BuiltinImplementationSpecifications = PyObject_GetAttrString(
- declarations, "BuiltinImplementationSpecifications");
- if (BuiltinImplementationSpecifications == NULL)
- return -1;
-
- empty = PyObject_GetAttrString(declarations, "_empty");
- if (empty == NULL)
- return -1;
-
- fallback = PyObject_GetAttrString(declarations, "implementedByFallback");
- if (fallback == NULL)
- return -1;
-
-
-
- i = PyObject_GetAttrString(declarations, "Implements");
- if (i == NULL)
- return -1;
-
- if (! PyType_Check(i))
- {
- PyErr_SetString(PyExc_TypeError,
- "zope.interface.declarations.Implements is not a type");
- return -1;
- }
-
- Implements = (PyTypeObject *)i;
-
- Py_DECREF(declarations);
-
- imported_declarations = 1;
- return 0;
-}
-
-static PyTypeObject SpecType; /* Forward */
-
-static PyObject *
-implementedByFallback(PyObject *cls)
-{
- if (imported_declarations == 0 && import_declarations() < 0)
- return NULL;
-
- return PyObject_CallFunctionObjArgs(fallback, cls, NULL);
-}
-
-static PyObject *
-implementedBy(PyObject *ignored, PyObject *cls)
-{
- /* Fast retrieval of implements spec, if possible, to optimize
- common case. Use fallback code if we get stuck.
- */
-
- PyObject *dict = NULL, *spec;
-
- if (PyType_Check(cls))
- {
- dict = TYPE(cls)->tp_dict;
- Py_XINCREF(dict);
- }
-
- if (dict == NULL)
- dict = PyObject_GetAttr(cls, str__dict__);
-
- if (dict == NULL)
- {
- /* Probably a security proxied class, use more expensive fallback code */
- PyErr_Clear();
- return implementedByFallback(cls);
- }
-
- spec = PyObject_GetItem(dict, str__implemented__);
- Py_DECREF(dict);
- if (spec)
- {
- if (imported_declarations == 0 && import_declarations() < 0)
- return NULL;
-
- if (PyObject_TypeCheck(spec, Implements))
- return spec;
-
- /* Old-style declaration, use more expensive fallback code */
- Py_DECREF(spec);
- return implementedByFallback(cls);
- }
-
- PyErr_Clear();
-
- /* Maybe we have a builtin */
- if (imported_declarations == 0 && import_declarations() < 0)
- return NULL;
-
- spec = PyDict_GetItem(BuiltinImplementationSpecifications, cls);
- if (spec != NULL)
- {
- Py_INCREF(spec);
- return spec;
- }
-
- /* We're stuck, use fallback */
- return implementedByFallback(cls);
-}
-
-static PyObject *
-getObjectSpecification(PyObject *ignored, PyObject *ob)
-{
- PyObject *cls, *result;
-
- result = PyObject_GetAttr(ob, str__provides__);
- if (result != NULL && PyObject_TypeCheck(result, &SpecType))
- return result;
-
- PyErr_Clear();
-
- /* We do a getattr here so as not to be defeated by proxies */
- cls = PyObject_GetAttr(ob, str__class__);
- if (cls == NULL)
- {
- PyErr_Clear();
- if (imported_declarations == 0 && import_declarations() < 0)
- return NULL;
- Py_INCREF(empty);
- return empty;
- }
-
- result = implementedBy(NULL, cls);
- Py_DECREF(cls);
-
- return result;
-}
-
-static PyObject *
-providedBy(PyObject *ignored, PyObject *ob)
-{
- PyObject *result, *cls, *cp;
-
- result = PyObject_GetAttr(ob, str__providedBy__);
- if (result == NULL)
- {
- PyErr_Clear();
- return getObjectSpecification(NULL, ob);
- }
-
-
- /* We want to make sure we have a spec. We can't do a type check
- because we may have a proxy, so we'll just try to get the
- only attribute.
- */
- if (PyObject_TypeCheck(result, &SpecType)
- ||
- PyObject_HasAttr(result, strextends)
- )
- return result;
-
- /*
- The object's class doesn't understand descriptors.
- Sigh. We need to get an object descriptor, but we have to be
- careful. We want to use the instance's __provides__,l if
- there is one, but only if it didn't come from the class.
- */
- Py_DECREF(result);
-
- cls = PyObject_GetAttr(ob, str__class__);
- if (cls == NULL)
- return NULL;
-
- result = PyObject_GetAttr(ob, str__provides__);
- if (result == NULL)
- {
- /* No __provides__, so just fall back to implementedBy */
- PyErr_Clear();
- result = implementedBy(NULL, cls);
- Py_DECREF(cls);
- return result;
- }
-
- cp = PyObject_GetAttr(cls, str__provides__);
- if (cp == NULL)
- {
- /* The the class has no provides, assume we're done: */
- PyErr_Clear();
- Py_DECREF(cls);
- return result;
- }
-
- if (cp == result)
- {
- /*
- Oops, we got the provides from the class. This means
- the object doesn't have it's own. We should use implementedBy
- */
- Py_DECREF(result);
- result = implementedBy(NULL, cls);
- }
-
- Py_DECREF(cls);
- Py_DECREF(cp);
-
- return result;
-}
-
-/*
- Get an attribute from an inst dict. Return a borrowed reference.
-
- This has a number of advantages:
-
- - It avoids layers of Python api
-
- - It doesn't waste time looking for descriptors
-
- - It fails wo raising an exception, although that shouldn't really
- matter.
-
-*/
-static PyObject *
-inst_attr(PyObject *self, PyObject *name)
-{
- PyObject **dictp, *v;
-
- dictp = _PyObject_GetDictPtr(self);
- if (dictp && *dictp && (v = PyDict_GetItem(*dictp, name)))
- return v;
- PyErr_SetObject(PyExc_AttributeError, name);
- return NULL;
-}
-
-
-static PyObject *
-Spec_extends(PyObject *self, PyObject *other)
-{
- PyObject *implied;
-
- implied = inst_attr(self, str_implied);
- if (implied == NULL)
- return NULL;
-
-#ifdef Py_True
- if (PyDict_GetItem(implied, other) != NULL)
- {
- Py_INCREF(Py_True);
- return Py_True;
- }
- Py_INCREF(Py_False);
- return Py_False;
-#else
- return PyInt_FromLong(PyDict_GetItem(implied, other) != NULL);
-#endif
-}
-
-static char Spec_extends__doc__[] =
-"Test whether a specification is or extends another"
-;
-
-static char Spec_providedBy__doc__[] =
-"Test whether an interface is implemented by the specification"
-;
-
-static PyObject *
-Spec_call(PyObject *self, PyObject *args, PyObject *kw)
-{
- PyObject *spec;
-
- if (! PyArg_ParseTuple(args, "O", &spec))
- return NULL;
- return Spec_extends(self, spec);
-}
-
-static PyObject *
-Spec_providedBy(PyObject *self, PyObject *ob)
-{
- PyObject *decl, *item;
-
- decl = providedBy(NULL, ob);
- if (decl == NULL)
- return NULL;
-
- if (PyObject_TypeCheck(decl, &SpecType))
- item = Spec_extends(decl, self);
- else
- /* decl is probably a security proxy. We have to go the long way
- around.
- */
- item = PyObject_CallFunctionObjArgs(decl, self, NULL);
-
- Py_DECREF(decl);
- return item;
-}
-
-
-static char Spec_implementedBy__doc__[] =
-"Test whether the specification is implemented by a class or factory.\n"
-"Raise TypeError if argument is neither a class nor a callable."
-;
-
-static PyObject *
-Spec_implementedBy(PyObject *self, PyObject *cls)
-{
- PyObject *decl, *item;
-
- decl = implementedBy(NULL, cls);
- if (decl == NULL)
- return NULL;
-
- if (PyObject_TypeCheck(decl, &SpecType))
- item = Spec_extends(decl, self);
- else
- item = PyObject_CallFunctionObjArgs(decl, self, NULL);
-
- Py_DECREF(decl);
- return item;
-}
-
-static struct PyMethodDef Spec_methods[] = {
- {"providedBy",
- (PyCFunction)Spec_providedBy, METH_O,
- Spec_providedBy__doc__},
- {"implementedBy",
- (PyCFunction)Spec_implementedBy, METH_O,
- Spec_implementedBy__doc__},
- {"isOrExtends", (PyCFunction)Spec_extends, METH_O,
- Spec_extends__doc__},
-
- {NULL, NULL} /* sentinel */
-};
-
-static PyTypeObject SpecType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_interface_coptimizations."
- "SpecificationBase",
- /* tp_basicsize */ 0,
- /* tp_itemsize */ 0,
- /* tp_dealloc */ (destructor)0,
- /* tp_print */ (printfunc)0,
- /* tp_getattr */ (getattrfunc)0,
- /* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ 0,
- /* tp_repr */ (reprfunc)0,
- /* tp_as_number */ 0,
- /* tp_as_sequence */ 0,
- /* tp_as_mapping */ 0,
- /* tp_hash */ (hashfunc)0,
- /* tp_call */ (ternaryfunc)Spec_call,
- /* tp_str */ (reprfunc)0,
- /* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
- /* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- "Base type for Specification objects",
- /* tp_traverse */ (traverseproc)0,
- /* tp_clear */ (inquiry)0,
- /* tp_richcompare */ (richcmpfunc)0,
- /* tp_weaklistoffset */ (long)0,
- /* tp_iter */ (getiterfunc)0,
- /* tp_iternext */ (iternextfunc)0,
- /* tp_methods */ Spec_methods,
-};
-
-static PyObject *
-OSD_descr_get(PyObject *self, PyObject *inst, PyObject *cls)
-{
- PyObject *provides;
-
- if (inst == NULL)
- return getObjectSpecification(NULL, cls);
-
- provides = PyObject_GetAttr(inst, str__provides__);
- if (provides != NULL)
- return provides;
- PyErr_Clear();
- return implementedBy(NULL, cls);
-}
-
-static PyTypeObject OSDType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_interface_coptimizations."
- "ObjectSpecificationDescriptor",
- /* tp_basicsize */ 0,
- /* tp_itemsize */ 0,
- /* tp_dealloc */ (destructor)0,
- /* tp_print */ (printfunc)0,
- /* tp_getattr */ (getattrfunc)0,
- /* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ 0,
- /* tp_repr */ (reprfunc)0,
- /* tp_as_number */ 0,
- /* tp_as_sequence */ 0,
- /* tp_as_mapping */ 0,
- /* tp_hash */ (hashfunc)0,
- /* tp_call */ (ternaryfunc)0,
- /* tp_str */ (reprfunc)0,
- /* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
- /* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT
- | Py_TPFLAGS_BASETYPE ,
- "Object Specification Descriptor",
- /* tp_traverse */ (traverseproc)0,
- /* tp_clear */ (inquiry)0,
- /* tp_richcompare */ (richcmpfunc)0,
- /* tp_weaklistoffset */ (long)0,
- /* tp_iter */ (getiterfunc)0,
- /* tp_iternext */ (iternextfunc)0,
- /* tp_methods */ 0,
- /* tp_members */ 0,
- /* tp_getset */ 0,
- /* tp_base */ 0,
- /* tp_dict */ 0, /* internal use */
- /* tp_descr_get */ (descrgetfunc)OSD_descr_get,
-};
-
-static PyObject *
-CPB_descr_get(PyObject *self, PyObject *inst, PyObject *cls)
-{
- PyObject *mycls, *implements;
-
- mycls = inst_attr(self, str_cls);
- if (mycls == NULL)
- return NULL;
-
- if (cls == mycls)
- {
- if (inst == NULL)
- {
- Py_INCREF(self);
- return OBJECT(self);
- }
-
- implements = inst_attr(self, str_implements);
- Py_XINCREF(implements);
- return implements;
- }
-
- PyErr_SetObject(PyExc_AttributeError, str__provides__);
- return NULL;
-}
-
-static PyTypeObject CPBType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_interface_coptimizations."
- "ClassProvidesBase",
- /* tp_basicsize */ 0,
- /* tp_itemsize */ 0,
- /* tp_dealloc */ (destructor)0,
- /* tp_print */ (printfunc)0,
- /* tp_getattr */ (getattrfunc)0,
- /* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ 0,
- /* tp_repr */ (reprfunc)0,
- /* tp_as_number */ 0,
- /* tp_as_sequence */ 0,
- /* tp_as_mapping */ 0,
- /* tp_hash */ (hashfunc)0,
- /* tp_call */ (ternaryfunc)0,
- /* tp_str */ (reprfunc)0,
- /* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
- /* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- "C Base class for ClassProvides",
- /* tp_traverse */ (traverseproc)0,
- /* tp_clear */ (inquiry)0,
- /* tp_richcompare */ (richcmpfunc)0,
- /* tp_weaklistoffset */ (long)0,
- /* tp_iter */ (getiterfunc)0,
- /* tp_iternext */ (iternextfunc)0,
- /* tp_methods */ 0,
- /* tp_members */ 0,
- /* tp_getset */ 0,
- /* tp_base */ &SpecType,
- /* tp_dict */ 0, /* internal use */
- /* tp_descr_get */ (descrgetfunc)CPB_descr_get,
-};
-
-/* ==================================================================== */
-/* ========== Begin: __call__ and __adapt__ =========================== */
-
-/*
- def __adapt__(self, obj):
- """Adapt an object to the reciever
- """
- if self.providedBy(obj):
- return obj
-
- for hook in adapter_hooks:
- adapter = hook(self, obj)
- if adapter is not None:
- return adapter
-
-
-*/
-static PyObject *
-__adapt__(PyObject *self, PyObject *obj)
-{
- PyObject *decl, *args, *adapter;
- int implements, i, l;
-
- decl = providedBy(NULL, obj);
- if (decl == NULL)
- return NULL;
-
- if (PyObject_TypeCheck(decl, &SpecType))
- {
- PyObject *implied;
-
- implied = inst_attr(decl, str_implied);
- if (implied == NULL)
- {
- Py_DECREF(decl);
- return NULL;
- }
-
- implements = PyDict_GetItem(implied, self) != NULL;
- Py_DECREF(decl);
- }
- else
- {
- /* decl is probably a security proxy. We have to go the long way
- around.
- */
- PyObject *r;
- r = PyObject_CallFunctionObjArgs(decl, self, NULL);
- Py_DECREF(decl);
- if (r == NULL)
- return NULL;
- implements = PyObject_IsTrue(r);
- Py_DECREF(r);
- }
-
- if (implements)
- {
- Py_INCREF(obj);
- return obj;
- }
-
- l = PyList_GET_SIZE(adapter_hooks);
- args = PyTuple_New(2);
- if (args == NULL)
- return NULL;
- Py_INCREF(self);
- PyTuple_SET_ITEM(args, 0, self);
- Py_INCREF(obj);
- PyTuple_SET_ITEM(args, 1, obj);
- for (i = 0; i < l; i++)
- {
- adapter = PyObject_CallObject(PyList_GET_ITEM(adapter_hooks, i), args);
- if (adapter == NULL || adapter != Py_None)
- {
- Py_DECREF(args);
- return adapter;
- }
- Py_DECREF(adapter);
- }
-
- Py_DECREF(args);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static struct PyMethodDef ib_methods[] = {
- {"__adapt__", (PyCFunction)__adapt__, METH_O,
- "Adapt an object to the reciever"},
- {NULL, NULL} /* sentinel */
-};
-
-/*
- def __call__(self, obj, alternate=_marker):
- conform = getattr(obj, '__conform__', None)
- if conform is not None:
- adapter = self._call_conform(conform)
- if adapter is not None:
- return adapter
-
- adapter = self.__adapt__(obj)
-
- if adapter is not None:
- return adapter
- elif alternate is not _marker:
- return alternate
- else:
- raise TypeError("Could not adapt", obj, self)
-*/
-static PyObject *
-ib_call(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- PyObject *conform, *obj, *alternate=NULL, *adapter;
-
- static char *kwlist[] = {"obj", "alternate", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist,
- &obj, &alternate))
- return NULL;
-
- conform = PyObject_GetAttr(obj, str__conform__);
- if (conform != NULL)
- {
- adapter = PyObject_CallMethodObjArgs(self, str_call_conform,
- conform, NULL);
- Py_DECREF(conform);
- if (adapter == NULL || adapter != Py_None)
- return adapter;
- Py_DECREF(adapter);
- }
- else
- PyErr_Clear();
-
- adapter = __adapt__(self, obj);
- if (adapter == NULL || adapter != Py_None)
- return adapter;
- Py_DECREF(adapter);
-
- if (alternate != NULL)
- {
- Py_INCREF(alternate);
- return alternate;
- }
-
- adapter = Py_BuildValue("sOO", "Could not adapt", obj, self);
- if (adapter != NULL)
- {
- PyErr_SetObject(PyExc_TypeError, adapter);
- Py_DECREF(adapter);
- }
- return NULL;
-}
-
-static PyTypeObject InterfaceBase = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_zope_interface_coptimizations."
- "InterfaceBase",
- /* tp_basicsize */ 0,
- /* tp_itemsize */ 0,
- /* tp_dealloc */ (destructor)0,
- /* tp_print */ (printfunc)0,
- /* tp_getattr */ (getattrfunc)0,
- /* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ 0,
- /* tp_repr */ (reprfunc)0,
- /* tp_as_number */ 0,
- /* tp_as_sequence */ 0,
- /* tp_as_mapping */ 0,
- /* tp_hash */ (hashfunc)0,
- /* tp_call */ (ternaryfunc)ib_call,
- /* tp_str */ (reprfunc)0,
- /* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
- /* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT
- | Py_TPFLAGS_BASETYPE ,
- /* tp_doc */ "Interface base type providing __call__ and __adapt__",
- /* tp_traverse */ (traverseproc)0,
- /* tp_clear */ (inquiry)0,
- /* tp_richcompare */ (richcmpfunc)0,
- /* tp_weaklistoffset */ (long)0,
- /* tp_iter */ (getiterfunc)0,
- /* tp_iternext */ (iternextfunc)0,
- /* tp_methods */ ib_methods,
-};
-
-/* =================== End: __call__ and __adapt__ ==================== */
-/* ==================================================================== */
-
-/* ==================================================================== */
-/* ========================== Begin: Lookup Bases ===================== */
-
-typedef struct {
- PyObject_HEAD
- PyObject *_cache;
- PyObject *_mcache;
- PyObject *_scache;
-} lookup;
-
-typedef struct {
- PyObject_HEAD
- PyObject *_cache;
- PyObject *_mcache;
- PyObject *_scache;
- PyObject *_verify_ro;
- PyObject *_verify_generations;
-} verify;
-
-static int
-lookup_traverse(lookup *self, visitproc visit, void *arg)
-{
- int vret;
-
- if (self->_cache) {
- vret = visit(self->_cache, arg);
- if (vret != 0)
- return vret;
- }
-
- if (self->_mcache) {
- vret = visit(self->_mcache, arg);
- if (vret != 0)
- return vret;
- }
-
- if (self->_scache) {
- vret = visit(self->_scache, arg);
- if (vret != 0)
- return vret;
- }
-
- return 0;
-}
-
-static int
-lookup_clear(lookup *self)
-{
- Py_CLEAR(self->_cache);
- Py_CLEAR(self->_mcache);
- Py_CLEAR(self->_scache);
- return 0;
-}
-
-static void
-lookup_dealloc(lookup *self)
-{
- lookup_clear(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-/*
- def changed(self, ignored=None):
- self._cache.clear()
- self._mcache.clear()
- self._scache.clear()
-*/
-static PyObject *
-lookup_changed(lookup *self, PyObject *ignored)
-{
- lookup_clear(self);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#define ASSURE_DICT(N) if (N == NULL) { N = PyDict_New(); \
- if (N == NULL) return NULL; \
- }
-
-/*
- def _getcache(self, provided, name):
- cache = self._cache.get(provided)
- if cache is None:
- cache = {}
- self._cache[provided] = cache
- if name:
- c = cache.get(name)
- if c is None:
- c = {}
- cache[name] = c
- cache = c
- return cache
-*/
-static PyObject *
-_subcache(PyObject *cache, PyObject *key)
-{
- PyObject *subcache;
-
- subcache = PyDict_GetItem(cache, key);
- if (subcache == NULL)
- {
- int status;
-
- subcache = PyDict_New();
- if (subcache == NULL)
- return NULL;
- status = PyDict_SetItem(cache, key, subcache);
- Py_DECREF(subcache);
- if (status < 0)
- return NULL;
- }
-
- return subcache;
-}
-static PyObject *
-_getcache(lookup *self, PyObject *provided, PyObject *name)
-{
- PyObject *cache;
-
- ASSURE_DICT(self->_cache);
- cache = _subcache(self->_cache, provided);
- if (cache == NULL)
- return NULL;
-
- if (name != NULL && PyObject_IsTrue(name))
- cache = _subcache(cache, name);
-
- return cache;
-}
-
-
-/*
- def lookup(self, required, provided, name=u'', default=None):
- cache = self._getcache(provided, name)
- if len(required) == 1:
- result = cache.get(required[0], _not_in_mapping)
- else:
- result = cache.get(tuple(required), _not_in_mapping)
-
- if result is _not_in_mapping:
- result = self._uncached_lookup(required, provided, name)
- if len(required) == 1:
- cache[required[0]] = result
- else:
- cache[tuple(required)] = result
-
- if result is None:
- return default
-
- return result
-*/
-static PyObject *
-tuplefy(PyObject *v)
-{
- if (! PyTuple_Check(v))
- {
- v = PyObject_CallFunctionObjArgs(OBJECT(&PyTuple_Type), v, NULL);
- if (v == NULL)
- return NULL;
- }
- else
- Py_INCREF(v);
-
- return v;
-}
-static PyObject *
-_lookup(lookup *self,
- PyObject *required, PyObject *provided, PyObject *name,
- PyObject *default_)
-{
- PyObject *result, *key, *cache;
-
- cache = _getcache(self, provided, name);
- if (cache == NULL)
- return NULL;
-
- required = tuplefy(required);
- if (required == NULL)
- return NULL;
-
- if (PyTuple_GET_SIZE(required) == 1)
- key = PyTuple_GET_ITEM(required, 0);
- else
- key = required;
-
- result = PyDict_GetItem(cache, key);
- if (result == NULL)
- {
- int status;
-
- result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookup,
- required, provided, name, NULL);
- if (result == NULL)
- {
- Py_DECREF(required);
- return NULL;
- }
- status = PyDict_SetItem(cache, key, result);
- Py_DECREF(required);
- if (status < 0)
- {
- Py_DECREF(result);
- return NULL;
- }
- }
- else
- {
- Py_INCREF(result);
- Py_DECREF(required);
- }
-
- if (result == Py_None && default_ != NULL)
- {
- Py_DECREF(Py_None);
- Py_INCREF(default_);
- return default_;
- }
-
- return result;
-}
-static PyObject *
-lookup_lookup(lookup *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", "name", "default", NULL};
- PyObject *required, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &required, &provided, &name, &default_))
- return NULL;
-
- return _lookup(self, required, provided, name, default_);
-}
-
-
-/*
- def lookup1(self, required, provided, name=u'', default=None):
- cache = self._getcache(provided, name)
- result = cache.get(required, _not_in_mapping)
- if result is _not_in_mapping:
- return self.lookup((required, ), provided, name, default)
-
- if result is None:
- return default
-
- return result
-*/
-static PyObject *
-_lookup1(lookup *self,
- PyObject *required, PyObject *provided, PyObject *name,
- PyObject *default_)
-{
- PyObject *result, *cache;
-
- cache = _getcache(self, provided, name);
- if (cache == NULL)
- return NULL;
-
- result = PyDict_GetItem(cache, required);
- if (result == NULL)
- {
- PyObject *tup;
-
- tup = PyTuple_New(1);
- if (tup == NULL)
- return NULL;
- Py_INCREF(required);
- PyTuple_SET_ITEM(tup, 0, required);
- result = _lookup(self, tup, provided, name, default_);
- Py_DECREF(tup);
- }
- else
- Py_INCREF(result);
-
- return result;
-}
-static PyObject *
-lookup_lookup1(lookup *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", "name", "default", NULL};
- PyObject *required, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &required, &provided, &name, &default_))
- return NULL;
-
- return _lookup1(self, required, provided, name, default_);
-}
-
-/*
- def adapter_hook(self, provided, object, name=u'', default=None):
- required = providedBy(object)
- cache = self._getcache(provided, name)
- factory = cache.get(required, _not_in_mapping)
- if factory is _not_in_mapping:
- factory = self.lookup((required, ), provided, name)
-
- if factory is not None:
- result = factory(object)
- if result is not None:
- return result
-
- return default
-*/
-static PyObject *
-_adapter_hook(lookup *self,
- PyObject *provided, PyObject *object, PyObject *name,
- PyObject *default_)
-{
- PyObject *required, *factory, *result;
-
- required = providedBy(NULL, object);
- if (required == NULL)
- return NULL;
-
- factory = _lookup1(self, required, provided, name, Py_None);
- Py_DECREF(required);
- if (factory == NULL)
- return NULL;
-
- if (factory != Py_None)
- {
- result = PyObject_CallFunctionObjArgs(factory, object, NULL);
- Py_DECREF(factory);
- if (result == NULL || result != Py_None)
- return result;
- }
- else
- result = factory; /* None */
-
- if (default_ == NULL || default_ == result) /* No default specified, */
- return result; /* Return None. result is owned None */
-
- Py_DECREF(result);
- Py_INCREF(default_);
-
- return default_;
-}
-static PyObject *
-lookup_adapter_hook(lookup *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"provided", "object", "name", "default", NULL};
- PyObject *object, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &provided, &object, &name, &default_))
- return NULL;
-
- return _adapter_hook(self, provided, object, name, default_);
-}
-
-static PyObject *
-lookup_queryAdapter(lookup *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"object", "provided", "name", "default", NULL};
- PyObject *object, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &object, &provided, &name, &default_))
- return NULL;
-
- return _adapter_hook(self, provided, object, name, default_);
-}
-
-/*
- def lookupAll(self, required, provided):
- cache = self._mcache.get(provided)
- if cache is None:
- cache = {}
- self._mcache[provided] = cache
-
- required = tuple(required)
- result = cache.get(required, _not_in_mapping)
- if result is _not_in_mapping:
- result = self._uncached_lookupAll(required, provided)
- cache[required] = result
-
- return result
-*/
-static PyObject *
-_lookupAll(lookup *self, PyObject *required, PyObject *provided)
-{
- PyObject *cache, *result;
-
- ASSURE_DICT(self->_mcache);
- cache = _subcache(self->_mcache, provided);
- if (cache == NULL)
- return NULL;
-
- required = tuplefy(required);
- if (required == NULL)
- return NULL;
-
- result = PyDict_GetItem(cache, required);
- if (result == NULL)
- {
- int status;
-
- result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookupAll,
- required, provided, NULL);
- if (result == NULL)
- {
- Py_DECREF(required);
- return NULL;
- }
- status = PyDict_SetItem(cache, required, result);
- Py_DECREF(required);
- if (status < 0)
- {
- Py_DECREF(result);
- return NULL;
- }
- }
- else
- {
- Py_INCREF(result);
- Py_DECREF(required);
- }
-
- return result;
-}
-static PyObject *
-lookup_lookupAll(lookup *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", NULL};
- PyObject *required, *provided;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
- &required, &provided))
- return NULL;
-
- return _lookupAll(self, required, provided);
-}
-
-/*
- def subscriptions(self, required, provided):
- cache = self._scache.get(provided)
- if cache is None:
- cache = {}
- self._scache[provided] = cache
-
- required = tuple(required)
- result = cache.get(required, _not_in_mapping)
- if result is _not_in_mapping:
- result = self._uncached_subscriptions(required, provided)
- cache[required] = result
-
- return result
-*/
-static PyObject *
-_subscriptions(lookup *self, PyObject *required, PyObject *provided)
-{
- PyObject *cache, *result;
-
- ASSURE_DICT(self->_scache);
- cache = _subcache(self->_scache, provided);
- if (cache == NULL)
- return NULL;
-
- required = tuplefy(required);
- if (required == NULL)
- return NULL;
-
- result = PyDict_GetItem(cache, required);
- if (result == NULL)
- {
- int status;
-
- result = PyObject_CallMethodObjArgs(
- OBJECT(self), str_uncached_subscriptions,
- required, provided, NULL);
- if (result == NULL)
- {
- Py_DECREF(required);
- return NULL;
- }
- status = PyDict_SetItem(cache, required, result);
- Py_DECREF(required);
- if (status < 0)
- {
- Py_DECREF(result);
- return NULL;
- }
- }
- else
- {
- Py_INCREF(result);
- Py_DECREF(required);
- }
-
- return result;
-}
-static PyObject *
-lookup_subscriptions(lookup *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", NULL};
- PyObject *required, *provided;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
- &required, &provided))
- return NULL;
-
- return _subscriptions(self, required, provided);
-}
-
-static struct PyMethodDef lookup_methods[] = {
- {"changed", (PyCFunction)lookup_changed, METH_O, ""},
- {"lookup", (PyCFunction)lookup_lookup, METH_KEYWORDS, ""},
- {"lookup1", (PyCFunction)lookup_lookup1, METH_KEYWORDS, ""},
- {"queryAdapter", (PyCFunction)lookup_queryAdapter, METH_KEYWORDS, ""},
- {"adapter_hook", (PyCFunction)lookup_adapter_hook, METH_KEYWORDS, ""},
- {"lookupAll", (PyCFunction)lookup_lookupAll, METH_KEYWORDS, ""},
- {"subscriptions", (PyCFunction)lookup_subscriptions, METH_KEYWORDS, ""},
- {NULL, NULL} /* sentinel */
-};
-
-static PyTypeObject LookupBase = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_zope_interface_coptimizations."
- "LookupBase",
- /* tp_basicsize */ sizeof(lookup),
- /* tp_itemsize */ 0,
- /* tp_dealloc */ (destructor)&lookup_dealloc,
- /* tp_print */ (printfunc)0,
- /* tp_getattr */ (getattrfunc)0,
- /* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ 0,
- /* tp_repr */ (reprfunc)0,
- /* tp_as_number */ 0,
- /* tp_as_sequence */ 0,
- /* tp_as_mapping */ 0,
- /* tp_hash */ (hashfunc)0,
- /* tp_call */ (ternaryfunc)0,
- /* tp_str */ (reprfunc)0,
- /* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
- /* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT
- | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC,
- /* tp_doc */ "",
- /* tp_traverse */ (traverseproc)lookup_traverse,
- /* tp_clear */ (inquiry)lookup_clear,
- /* tp_richcompare */ (richcmpfunc)0,
- /* tp_weaklistoffset */ (long)0,
- /* tp_iter */ (getiterfunc)0,
- /* tp_iternext */ (iternextfunc)0,
- /* tp_methods */ lookup_methods,
-};
-
-static int
-verifying_traverse(verify *self, visitproc visit, void *arg)
-{
- int vret;
-
- vret = lookup_traverse((lookup *)self, visit, arg);
- if (vret != 0)
- return vret;
-
- if (self->_verify_ro) {
- vret = visit(self->_verify_ro, arg);
- if (vret != 0)
- return vret;
- }
- if (self->_verify_generations) {
- vret = visit(self->_verify_generations, arg);
- if (vret != 0)
- return vret;
- }
-
- return 0;
-}
-
-static int
-verifying_clear(verify *self)
-{
- lookup_clear((lookup *)self);
- Py_CLEAR(self->_verify_generations);
- Py_CLEAR(self->_verify_ro);
- return 0;
-}
-
-
-static void
-verifying_dealloc(verify *self)
-{
- verifying_clear(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-/*
- def changed(self, originally_changed):
- super(VerifyingBasePy, self).changed(originally_changed)
- self._verify_ro = self._registry.ro[1:]
- self._verify_generations = [r._generation for r in self._verify_ro]
-*/
-static PyObject *
-_generations_tuple(PyObject *ro)
-{
- int i, l;
- PyObject *generations;
-
- l = PyTuple_GET_SIZE(ro);
- generations = PyTuple_New(l);
- for (i=0; i < l; i++)
- {
- PyObject *generation;
-
- generation = PyObject_GetAttr(PyTuple_GET_ITEM(ro, i), str_generation);
- if (generation == NULL)
- {
- Py_DECREF(generations);
- return NULL;
- }
- PyTuple_SET_ITEM(generations, i, generation);
- }
-
- return generations;
-}
-static PyObject *
-verifying_changed(verify *self, PyObject *ignored)
-{
- PyObject *t, *ro;
-
- verifying_clear(self);
-
- t = PyObject_GetAttr(OBJECT(self), str_registry);
- if (t == NULL)
- return NULL;
- ro = PyObject_GetAttr(t, strro);
- Py_DECREF(t);
- if (ro == NULL)
- return NULL;
-
- t = PyObject_CallFunctionObjArgs(OBJECT(&PyTuple_Type), ro, NULL);
- Py_DECREF(ro);
- if (t == NULL)
- return NULL;
-
- ro = PyTuple_GetSlice(t, 1, PyTuple_GET_SIZE(t));
- Py_DECREF(t);
- if (ro == NULL)
- return NULL;
-
- self->_verify_generations = _generations_tuple(ro);
- if (self->_verify_generations == NULL)
- {
- Py_DECREF(ro);
- return NULL;
- }
-
- self->_verify_ro = ro;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
- def _verify(self):
- if ([r._generation for r in self._verify_ro]
- != self._verify_generations):
- self.changed(None)
-*/
-static int
-_verify(verify *self)
-{
- PyObject *changed_result;
-
- if (self->_verify_ro != NULL && self->_verify_generations != NULL)
- {
- PyObject *generations;
- int changed;
-
- generations = _generations_tuple(self->_verify_ro);
- if (generations == NULL)
- return -1;
-
- changed = PyObject_RichCompareBool(self->_verify_generations,
- generations, Py_NE);
- Py_DECREF(generations);
- if (changed == -1)
- return -1;
-
- if (changed == 0)
- return 0;
- }
-
- changed_result = PyObject_CallMethodObjArgs(OBJECT(self), strchanged,
- Py_None, NULL);
- if (changed_result == NULL)
- return -1;
-
- Py_DECREF(changed_result);
- return 0;
-}
-
-static PyObject *
-verifying_lookup(verify *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", "name", "default", NULL};
- PyObject *required, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &required, &provided, &name, &default_))
- return NULL;
-
- if (_verify(self) < 0)
- return NULL;
-
- return _lookup((lookup *)self, required, provided, name, default_);
-}
-
-static PyObject *
-verifying_lookup1(verify *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", "name", "default", NULL};
- PyObject *required, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &required, &provided, &name, &default_))
- return NULL;
-
- if (_verify(self) < 0)
- return NULL;
-
- return _lookup1((lookup *)self, required, provided, name, default_);
-}
-
-static PyObject *
-verifying_adapter_hook(verify *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"provided", "object", "name", "default", NULL};
- PyObject *object, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &provided, &object, &name, &default_))
- return NULL;
-
- if (_verify(self) < 0)
- return NULL;
-
- return _adapter_hook((lookup *)self, provided, object, name, default_);
-}
-
-static PyObject *
-verifying_queryAdapter(verify *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"object", "provided", "name", "default", NULL};
- PyObject *object, *provided, *name=NULL, *default_=NULL;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
- &object, &provided, &name, &default_))
- return NULL;
-
- if (_verify(self) < 0)
- return NULL;
-
- return _adapter_hook((lookup *)self, provided, object, name, default_);
-}
-
-static PyObject *
-verifying_lookupAll(verify *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", NULL};
- PyObject *required, *provided;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
- &required, &provided))
- return NULL;
-
- if (_verify(self) < 0)
- return NULL;
-
- return _lookupAll((lookup *)self, required, provided);
-}
-
-static PyObject *
-verifying_subscriptions(verify *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"required", "provided", NULL};
- PyObject *required, *provided;
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
- &required, &provided))
- return NULL;
-
- if (_verify(self) < 0)
- return NULL;
-
- return _subscriptions((lookup *)self, required, provided);
-}
-
-static struct PyMethodDef verifying_methods[] = {
- {"changed", (PyCFunction)verifying_changed, METH_O, ""},
- {"lookup", (PyCFunction)verifying_lookup, METH_KEYWORDS, ""},
- {"lookup1", (PyCFunction)verifying_lookup1, METH_KEYWORDS, ""},
- {"queryAdapter", (PyCFunction)verifying_queryAdapter, METH_KEYWORDS, ""},
- {"adapter_hook", (PyCFunction)verifying_adapter_hook, METH_KEYWORDS, ""},
- {"lookupAll", (PyCFunction)verifying_lookupAll, METH_KEYWORDS, ""},
- {"subscriptions", (PyCFunction)verifying_subscriptions, METH_KEYWORDS, ""},
- {NULL, NULL} /* sentinel */
-};
-
-static PyTypeObject VerifyingBase = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_zope_interface_coptimizations."
- "VerifyingBase",
- /* tp_basicsize */ sizeof(verify),
- /* tp_itemsize */ 0,
- /* tp_dealloc */ (destructor)&verifying_dealloc,
- /* tp_print */ (printfunc)0,
- /* tp_getattr */ (getattrfunc)0,
- /* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ 0,
- /* tp_repr */ (reprfunc)0,
- /* tp_as_number */ 0,
- /* tp_as_sequence */ 0,
- /* tp_as_mapping */ 0,
- /* tp_hash */ (hashfunc)0,
- /* tp_call */ (ternaryfunc)0,
- /* tp_str */ (reprfunc)0,
- /* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
- /* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT
- | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC,
- /* tp_doc */ "",
- /* tp_traverse */ (traverseproc)verifying_traverse,
- /* tp_clear */ (inquiry)verifying_clear,
- /* tp_richcompare */ (richcmpfunc)0,
- /* tp_weaklistoffset */ (long)0,
- /* tp_iter */ (getiterfunc)0,
- /* tp_iternext */ (iternextfunc)0,
- /* tp_methods */ verifying_methods,
- /* tp_members */ 0,
- /* tp_getset */ 0,
- /* tp_base */ &LookupBase,
-};
-
-/* ========================== End: Lookup Bases ======================= */
-/* ==================================================================== */
-
-
-
-static struct PyMethodDef m_methods[] = {
- {"implementedBy", (PyCFunction)implementedBy, METH_O,
- "Interfaces implemented by a class or factory.\n"
- "Raises TypeError if argument is neither a class nor a callable."},
- {"getObjectSpecification", (PyCFunction)getObjectSpecification, METH_O,
- "Get an object's interfaces (internal api)"},
- {"providedBy", (PyCFunction)providedBy, METH_O,
- "Get an object's interfaces"},
-
- {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
-};
-
-#if PY_MAJOR_VERSION >= 3
-static char module_doc[] = "C optimizations for zope.interface\n\n";
-
-static struct PyModuleDef _zic_module = {
- PyModuleDef_HEAD_INIT,
- "_zope_interface_coptimizations",
- module_doc,
- -1,
- m_methods,
- NULL,
- NULL,
- NULL,
- NULL
-};
-#endif
-
-static PyObject *
-init(void)
-{
- PyObject *m;
-
-#if PY_MAJOR_VERSION < 3
-#define DEFINE_STRING(S) \
- if(! (str ## S = PyString_FromString(# S))) return NULL
-#else
-#define DEFINE_STRING(S) \
- if(! (str ## S = PyUnicode_FromString(# S))) return NULL
-#endif
-
- DEFINE_STRING(__dict__);
- DEFINE_STRING(__implemented__);
- DEFINE_STRING(__provides__);
- DEFINE_STRING(__class__);
- DEFINE_STRING(__providedBy__);
- DEFINE_STRING(extends);
- DEFINE_STRING(_implied);
- DEFINE_STRING(_implements);
- DEFINE_STRING(_cls);
- DEFINE_STRING(__conform__);
- DEFINE_STRING(_call_conform);
- DEFINE_STRING(_uncached_lookup);
- DEFINE_STRING(_uncached_lookupAll);
- DEFINE_STRING(_uncached_subscriptions);
- DEFINE_STRING(_registry);
- DEFINE_STRING(_generation);
- DEFINE_STRING(ro);
- DEFINE_STRING(changed);
-#undef DEFINE_STRING
- adapter_hooks = PyList_New(0);
- if (adapter_hooks == NULL)
- return NULL;
-
- /* Initialize types: */
- SpecType.tp_new = PyBaseObject_Type.tp_new;
- if (PyType_Ready(&SpecType) < 0)
- return NULL;
- OSDType.tp_new = PyBaseObject_Type.tp_new;
- if (PyType_Ready(&OSDType) < 0)
- return NULL;
- CPBType.tp_new = PyBaseObject_Type.tp_new;
- if (PyType_Ready(&CPBType) < 0)
- return NULL;
-
- InterfaceBase.tp_new = PyBaseObject_Type.tp_new;
- if (PyType_Ready(&InterfaceBase) < 0)
- return NULL;
-
- LookupBase.tp_new = PyBaseObject_Type.tp_new;
- if (PyType_Ready(&LookupBase) < 0)
- return NULL;
-
- VerifyingBase.tp_new = PyBaseObject_Type.tp_new;
- if (PyType_Ready(&VerifyingBase) < 0)
- return NULL;
-
- #if PY_MAJOR_VERSION < 3
- /* Create the module and add the functions */
- m = Py_InitModule3("_zope_interface_coptimizations", m_methods,
- "C optimizations for zope.interface\n\n");
- #else
- m = PyModule_Create(&_zic_module);
- #endif
- if (m == NULL)
- return NULL;
-
- /* Add types: */
- if (PyModule_AddObject(m, "SpecificationBase", OBJECT(&SpecType)) < 0)
- return NULL;
- if (PyModule_AddObject(m, "ObjectSpecificationDescriptor",
- (PyObject *)&OSDType) < 0)
- return NULL;
- if (PyModule_AddObject(m, "ClassProvidesBase", OBJECT(&CPBType)) < 0)
- return NULL;
- if (PyModule_AddObject(m, "InterfaceBase", OBJECT(&InterfaceBase)) < 0)
- return NULL;
- if (PyModule_AddObject(m, "LookupBase", OBJECT(&LookupBase)) < 0)
- return NULL;
- if (PyModule_AddObject(m, "VerifyingBase", OBJECT(&VerifyingBase)) < 0)
- return NULL;
- if (PyModule_AddObject(m, "adapter_hooks", adapter_hooks) < 0)
- return NULL;
- return m;
-}
-
-PyMODINIT_FUNC
-#if PY_MAJOR_VERSION < 3
-init_zope_interface_coptimizations(void)
-{
- init();
-}
-#else
-PyInit__zope_interface_coptimizations(void)
-{
- return init();
-}
-#endif
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.py
deleted file mode 100644
index d3b45539..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/_zope_interface_coptimizations.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def __bootstrap__():
- global __bootstrap__, __loader__, __file__
- import sys, pkg_resources, imp
- __file__ = pkg_resources.resource_filename(__name__,'_zope_interface_coptimizations.so')
- __loader__ = None; del __bootstrap__, __loader__
- imp.load_dynamic(__name__,__file__)
-__bootstrap__()
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py
deleted file mode 100644
index 2ad145bf..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py
+++ /dev/null
@@ -1,692 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Adapter management
-"""
-
-import weakref
-from zope.interface import providedBy, Interface, ro
-
-_marker = object
-class BaseAdapterRegistry(object):
-
- # List of methods copied from lookup sub-objects:
- _delegated = ('lookup', 'queryMultiAdapter', 'lookup1', 'queryAdapter',
- 'adapter_hook', 'lookupAll', 'names',
- 'subscriptions', 'subscribers')
-
- # All registries maintain a generation that can be used by verifying
- # registries
- _generation = 0
-
- def __init__(self, bases=()):
-
- # The comments here could be improved. Possibly this bit needs
- # explaining in a separate document, as the comments here can
- # be quite confusing. /regebro
-
- # {order -> {required -> {provided -> {name -> value}}}}
- # Here "order" is actually an index in a list, "required" and
- # "provided" are interfaces, and "required" is really a nested
- # key. So, for example:
- # for order == 0 (that is, self._adapters[0]), we have:
- # {provided -> {name -> value}}
- # but for order == 2 (that is, self._adapters[2]), we have:
- # {r1 -> {r2 -> {provided -> {name -> value}}}}
- #
- self._adapters = []
-
- # {order -> {required -> {provided -> {name -> [value]}}}}
- # where the remarks about adapters above apply
- self._subscribers = []
-
- # Set, with a reference count, keeping track of the interfaces
- # for which we have provided components:
- self._provided = {}
-
- # Create ``_v_lookup`` object to perform lookup. We make this a
- # separate object to to make it easier to implement just the
- # lookup functionality in C. This object keeps track of cache
- # invalidation data in two kinds of registries.
-
- # Invalidating registries have caches that are invalidated
- # when they or their base registies change. An invalidating
- # registry can only have invalidating registries as bases.
- # See LookupBasePy below for the pertinent logic.
-
- # Verifying registies can't rely on getting invalidation messages,
- # so have to check the generations of base registries to determine
- # if their cache data are current. See VerifyingBasePy below
- # for the pertinent object.
- self._createLookup()
-
- # Setting the bases causes the registries described above
- # to be initialized (self._setBases -> self.changed ->
- # self._v_lookup.changed).
-
- self.__bases__ = bases
-
- def _setBases(self, bases):
- self.__dict__['__bases__'] = bases
- self.ro = ro.ro(self)
- self.changed(self)
-
- __bases__ = property(lambda self: self.__dict__['__bases__'],
- lambda self, bases: self._setBases(bases),
- )
-
- def _createLookup(self):
- self._v_lookup = self.LookupClass(self)
- for name in self._delegated:
- self.__dict__[name] = getattr(self._v_lookup, name)
-
- def changed(self, originally_changed):
- self._generation += 1
- self._v_lookup.changed(originally_changed)
-
- def register(self, required, provided, name, value):
- if value is None:
- self.unregister(required, provided, name, value)
- return
-
- required = tuple(map(_convert_None_to_Interface, required))
- name = _normalize_name(name)
- order = len(required)
- byorder = self._adapters
- while len(byorder) <= order:
- byorder.append({})
- components = byorder[order]
- key = required + (provided,)
-
- for k in key:
- d = components.get(k)
- if d is None:
- d = {}
- components[k] = d
- components = d
-
- if components.get(name) is value:
- return
-
- components[name] = value
-
- n = self._provided.get(provided, 0) + 1
- self._provided[provided] = n
- if n == 1:
- self._v_lookup.add_extendor(provided)
-
- self.changed(self)
-
- def registered(self, required, provided, name=u''):
- required = tuple(map(_convert_None_to_Interface, required))
- name = _normalize_name(name)
- order = len(required)
- byorder = self._adapters
- if len(byorder) <= order:
- return None
-
- components = byorder[order]
- key = required + (provided,)
-
- for k in key:
- d = components.get(k)
- if d is None:
- return None
- components = d
-
- return components.get(name)
-
- def unregister(self, required, provided, name, value=None):
- required = tuple(map(_convert_None_to_Interface, required))
- order = len(required)
- byorder = self._adapters
- if order >= len(byorder):
- return False
- components = byorder[order]
- key = required + (provided,)
-
- # Keep track of how we got to `components`:
- lookups = []
- # Keep track of how we got to `components`:
- lookups = []
- for k in key:
- d = components.get(k)
- if d is None:
- return
- lookups.append((components, k))
- components = d
-
- old = components.get(name)
- if old is None:
- return
- if (value is not None) and (old is not value):
- return
-
- del components[name]
- if not components:
- # Clean out empty containers, since we don't want our keys
- # to reference global objects (interfaces) unnecessarily.
- # This is often a problem when an interface is slated for
- # removal; a hold-over entry in the registry can make it
- # difficult to remove such interfaces.
- for comp, k in reversed(lookups):
- d = comp[k]
- if d:
- break
- else:
- del comp[k]
- while byorder and not byorder[-1]:
- del byorder[-1]
- n = self._provided[provided] - 1
- if n == 0:
- del self._provided[provided]
- self._v_lookup.remove_extendor(provided)
- else:
- self._provided[provided] = n
-
- self.changed(self)
-
- def subscribe(self, required, provided, value):
- required = tuple(map(_convert_None_to_Interface, required))
- name = u''
- order = len(required)
- byorder = self._subscribers
- while len(byorder) <= order:
- byorder.append({})
- components = byorder[order]
- key = required + (provided,)
-
- for k in key:
- d = components.get(k)
- if d is None:
- d = {}
- components[k] = d
- components = d
-
- components[name] = components.get(name, ()) + (value, )
-
- if provided is not None:
- n = self._provided.get(provided, 0) + 1
- self._provided[provided] = n
- if n == 1:
- self._v_lookup.add_extendor(provided)
-
- self.changed(self)
-
- def unsubscribe(self, required, provided, value=None):
- required = tuple(map(_convert_None_to_Interface, required))
- order = len(required)
- byorder = self._subscribers
- if order >= len(byorder):
- return
- components = byorder[order]
- key = required + (provided,)
-
- # Keep track of how we got to `components`:
- lookups = []
- # Keep track of how we got to `components`:
- lookups = []
- for k in key:
- d = components.get(k)
- if d is None:
- return
- lookups.append((components, k))
- components = d
-
- old = components.get(u'')
- if not old:
- return
-
- if value is None:
- new = ()
- else:
- new = tuple([v for v in old if v is not value])
-
- if new == old:
- return
-
- if new:
- components[u''] = new
- else:
- # Instead of setting components[u''] = new, we clean out
- # empty containers, since we don't want our keys to
- # reference global objects (interfaces) unnecessarily. This
- # is often a problem when an interface is slated for
- # removal; a hold-over entry in the registry can make it
- # difficult to remove such interfaces.
- if u'' in components:
- del components[u'']
- for comp, k in reversed(lookups):
- d = comp[k]
- if d:
- break
- else:
- del comp[k]
- while byorder and not byorder[-1]:
- del byorder[-1]
-
- if provided is not None:
- n = self._provided[provided] + len(new) - len(old)
- if n == 0:
- del self._provided[provided]
- self._v_lookup.remove_extendor(provided)
-
- self.changed(self)
-
- # XXX hack to fake out twisted's use of a private api. We need to get them
- # to use the new registed method.
- def get(self, _):
- class XXXTwistedFakeOut:
- selfImplied = {}
- return XXXTwistedFakeOut
-
-
-_not_in_mapping = object()
-class LookupBasePy(object):
-
- def __init__(self):
- self._cache = {}
- self._mcache = {}
- self._scache = {}
-
- def changed(self, ignored=None):
- self._cache.clear()
- self._mcache.clear()
- self._scache.clear()
-
- def _getcache(self, provided, name):
- cache = self._cache.get(provided)
- if cache is None:
- cache = {}
- self._cache[provided] = cache
- if name:
- c = cache.get(name)
- if c is None:
- c = {}
- cache[name] = c
- cache = c
- return cache
-
- def lookup(self, required, provided, name=u'', default=None):
- cache = self._getcache(provided, name)
- if len(required) == 1:
- result = cache.get(required[0], _not_in_mapping)
- else:
- result = cache.get(tuple(required), _not_in_mapping)
-
- if result is _not_in_mapping:
- result = self._uncached_lookup(required, provided, name)
- if len(required) == 1:
- cache[required[0]] = result
- else:
- cache[tuple(required)] = result
-
- if result is None:
- return default
-
- return result
-
- def lookup1(self, required, provided, name=u'', default=None):
- cache = self._getcache(provided, name)
- result = cache.get(required, _not_in_mapping)
- if result is _not_in_mapping:
- return self.lookup((required, ), provided, name, default)
-
- if result is None:
- return default
-
- return result
-
- def queryAdapter(self, object, provided, name=u'', default=None):
- return self.adapter_hook(provided, object, name, default)
-
- def adapter_hook(self, provided, object, name=u'', default=None):
- required = providedBy(object)
- cache = self._getcache(provided, name)
- factory = cache.get(required, _not_in_mapping)
- if factory is _not_in_mapping:
- factory = self.lookup((required, ), provided, name)
-
- if factory is not None:
- result = factory(object)
- if result is not None:
- return result
-
- return default
-
- def lookupAll(self, required, provided):
- cache = self._mcache.get(provided)
- if cache is None:
- cache = {}
- self._mcache[provided] = cache
-
- required = tuple(required)
- result = cache.get(required, _not_in_mapping)
- if result is _not_in_mapping:
- result = self._uncached_lookupAll(required, provided)
- cache[required] = result
-
- return result
-
-
- def subscriptions(self, required, provided):
- cache = self._scache.get(provided)
- if cache is None:
- cache = {}
- self._scache[provided] = cache
-
- required = tuple(required)
- result = cache.get(required, _not_in_mapping)
- if result is _not_in_mapping:
- result = self._uncached_subscriptions(required, provided)
- cache[required] = result
-
- return result
-
-LookupBase = LookupBasePy
-
-class VerifyingBasePy(LookupBasePy):
-
- def changed(self, originally_changed):
- LookupBasePy.changed(self, originally_changed)
- self._verify_ro = self._registry.ro[1:]
- self._verify_generations = [r._generation for r in self._verify_ro]
-
- def _verify(self):
- if ([r._generation for r in self._verify_ro]
- != self._verify_generations):
- self.changed(None)
-
- def _getcache(self, provided, name):
- self._verify()
- return LookupBasePy._getcache(self, provided, name)
-
- def lookupAll(self, required, provided):
- self._verify()
- return LookupBasePy.lookupAll(self, required, provided)
-
- def subscriptions(self, required, provided):
- self._verify()
- return LookupBasePy.subscriptions(self, required, provided)
-
-VerifyingBase = VerifyingBasePy
-
-
-try:
- import _zope_interface_coptimizations
-except ImportError:
- pass
-else:
- from _zope_interface_coptimizations import LookupBase, VerifyingBase
-
-class AdapterLookupBase(object):
-
- def __init__(self, registry):
- self._registry = registry
- self._required = {}
- self.init_extendors()
- super(AdapterLookupBase, self).__init__()
-
- def changed(self, ignored=None):
- super(AdapterLookupBase, self).changed(None)
- for r in self._required.keys():
- r = r()
- if r is not None:
- r.unsubscribe(self)
- self._required.clear()
-
-
- # Extendors
- # ---------
-
- # When given an target interface for an adapter lookup, we need to consider
- # adapters for interfaces that extend the target interface. This is
- # what the extendors dictionary is about. It tells us all of the
- # interfaces that extend an interface for which there are adapters
- # registered.
-
- # We could separate this by order and name, thus reducing the
- # number of provided interfaces to search at run time. The tradeoff,
- # however, is that we have to store more information. For example,
- # is the same interface is provided for multiple names and if the
- # interface extends many interfaces, we'll have to keep track of
- # a fair bit of information for each name. It's better to
- # be space efficient here and be time efficient in the cache
- # implementation.
-
- # TODO: add invalidation when a provided interface changes, in case
- # the interface's __iro__ has changed. This is unlikely enough that
- # we'll take our chances for now.
-
- def init_extendors(self):
- self._extendors = {}
- for p in self._registry._provided:
- self.add_extendor(p)
-
- def add_extendor(self, provided):
- _extendors = self._extendors
- for i in provided.__iro__:
- extendors = _extendors.get(i, ())
- _extendors[i] = (
- [e for e in extendors if provided.isOrExtends(e)]
- +
- [provided]
- +
- [e for e in extendors if not provided.isOrExtends(e)]
- )
-
- def remove_extendor(self, provided):
- _extendors = self._extendors
- for i in provided.__iro__:
- _extendors[i] = [e for e in _extendors.get(i, ())
- if e != provided]
-
-
- def _subscribe(self, *required):
- _refs = self._required
- for r in required:
- ref = r.weakref()
- if ref not in _refs:
- r.subscribe(self)
- _refs[ref] = 1
-
- def _uncached_lookup(self, required, provided, name=u''):
- result = None
- order = len(required)
- for registry in self._registry.ro:
- byorder = registry._adapters
- if order >= len(byorder):
- continue
-
- extendors = registry._v_lookup._extendors.get(provided)
- if not extendors:
- continue
-
- components = byorder[order]
- result = _lookup(components, required, extendors, name, 0,
- order)
- if result is not None:
- break
-
- self._subscribe(*required)
-
- return result
-
- def queryMultiAdapter(self, objects, provided, name=u'', default=None):
- factory = self.lookup(map(providedBy, objects), provided, name)
- if factory is None:
- return default
-
- result = factory(*objects)
- if result is None:
- return default
-
- return result
-
- def _uncached_lookupAll(self, required, provided):
- order = len(required)
- result = {}
- for registry in reversed(self._registry.ro):
- byorder = registry._adapters
- if order >= len(byorder):
- continue
- extendors = registry._v_lookup._extendors.get(provided)
- if not extendors:
- continue
- components = byorder[order]
- _lookupAll(components, required, extendors, result, 0, order)
-
- self._subscribe(*required)
-
- return tuple(result.iteritems())
-
- def names(self, required, provided):
- return [c[0] for c in self.lookupAll(required, provided)]
-
- def _uncached_subscriptions(self, required, provided):
- order = len(required)
- result = []
- for registry in reversed(self._registry.ro):
- byorder = registry._subscribers
- if order >= len(byorder):
- continue
-
- if provided is None:
- extendors = (provided, )
- else:
- extendors = registry._v_lookup._extendors.get(provided)
- if extendors is None:
- continue
-
- _subscriptions(byorder[order], required, extendors, u'',
- result, 0, order)
-
- self._subscribe(*required)
-
- return result
-
- def subscribers(self, objects, provided):
- subscriptions = self.subscriptions(map(providedBy, objects), provided)
- if provided is None:
- result = ()
- for subscription in subscriptions:
- subscription(*objects)
- else:
- result = []
- for subscription in subscriptions:
- subscriber = subscription(*objects)
- if subscriber is not None:
- result.append(subscriber)
- return result
-
-class AdapterLookup(AdapterLookupBase, LookupBase):
- pass
-
-class AdapterRegistry(BaseAdapterRegistry):
-
- LookupClass = AdapterLookup
-
- def __init__(self, bases=()):
- # AdapterRegisties are invalidating registries, so
- # we need to keep track of out invalidating subregistries.
- self._v_subregistries = weakref.WeakKeyDictionary()
-
- super(AdapterRegistry, self).__init__(bases)
-
- def _addSubregistry(self, r):
- self._v_subregistries[r] = 1
-
- def _removeSubregistry(self, r):
- if r in self._v_subregistries:
- del self._v_subregistries[r]
-
- def _setBases(self, bases):
- old = self.__dict__.get('__bases__', ())
- for r in old:
- if r not in bases:
- r._removeSubregistry(self)
- for r in bases:
- if r not in old:
- r._addSubregistry(self)
-
- super(AdapterRegistry, self)._setBases(bases)
-
- def changed(self, originally_changed):
- super(AdapterRegistry, self).changed(originally_changed)
-
- for sub in self._v_subregistries.keys():
- sub.changed(originally_changed)
-
-
-class VerifyingAdapterLookup(AdapterLookupBase, VerifyingBase):
- pass
-
-class VerifyingAdapterRegistry(BaseAdapterRegistry):
-
- LookupClass = VerifyingAdapterLookup
-
-def _convert_None_to_Interface(x):
- if x is None:
- return Interface
- else:
- return x
-
-def _normalize_name(name):
- if isinstance(name, basestring):
- return unicode(name)
-
- raise TypeError("name must be a regular or unicode string")
-
-def _lookup(components, specs, provided, name, i, l):
- if i < l:
- for spec in specs[i].__sro__:
- comps = components.get(spec)
- if comps:
- r = _lookup(comps, specs, provided, name, i+1, l)
- if r is not None:
- return r
- else:
- for iface in provided:
- comps = components.get(iface)
- if comps:
- r = comps.get(name)
- if r is not None:
- return r
-
- return None
-
-def _lookupAll(components, specs, provided, result, i, l):
- if i < l:
- for spec in reversed(specs[i].__sro__):
- comps = components.get(spec)
- if comps:
- _lookupAll(comps, specs, provided, result, i+1, l)
- else:
- for iface in reversed(provided):
- comps = components.get(iface)
- if comps:
- result.update(comps)
-
-def _subscriptions(components, specs, provided, name, result, i, l):
- if i < l:
- for spec in reversed(specs[i].__sro__):
- comps = components.get(spec)
- if comps:
- _subscriptions(comps, specs, provided, name, result, i+1, l)
- else:
- for iface in reversed(provided):
- comps = components.get(iface)
- if comps:
- comps = comps.get(name)
- if comps:
- result.extend(comps)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.ru.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.ru.txt
deleted file mode 100644
index 30c2782b..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.ru.txt
+++ /dev/null
@@ -1,540 +0,0 @@
-================
-РееÑÑ‚Ñ€ адаптеров
-================
-
-.. contents::
-
-РееÑтры адаптеров предоÑтавлÑÑŽÑ‚ возможноÑÑ‚ÑŒ Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации объектов которые
-завиÑÑÑ‚ от одной, или неÑкольких Ñпецификаций интерфейÑов и предоÑтавлÑÑŽÑ‚
-(возможно не напрÑмую) какой-либо интерфейÑ. Ð’ дополнение, региÑтрации имеют
-имена. (Можно думать об именах как о Ñпецификаторах предоÑтавлÑемого
-интерфейÑа.)
-
-Термин "ÑÐ¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа" ÑÑылаетÑÑ Ð¸ на интерфейÑÑ‹ и на определениÑ
-интерфейÑов, такие как Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов реализованных некоторым клаÑÑом.
-
-Одиночные адаптеры
-==================
-
-Давайте раÑÑмотрим проÑтой пример иÑпользующий единÑтвенную требуемую
-Ñпецификацию::
-
- >>> from zope.interface.adapter import AdapterRegistry
- >>> import zope.interface
-
- >>> class IR1(zope.interface.Interface):
- ... pass
- >>> class IP1(zope.interface.Interface):
- ... pass
- >>> class IP2(IP1):
- ... pass
-
- >>> registry = AdapterRegistry()
-
-Мы зарегиÑтрируем объект который завиÑит от IR1 и "предоÑтавлÑет" IP2::
-
- >>> registry.register([IR1], IP2, '', 12)
-
-ПоÑле региÑтрации мы можем запроÑить объект Ñнова::
-
- >>> registry.lookup([IR1], IP2, '')
- 12
-
-Заметьте, что мы иÑпользуем целое в Ñтом примере. Ð’ реальных приложениÑÑ… вы
-можете иÑпользовать объекты которые на Ñамом деле завиÑÑÑ‚ или предоÑтавлÑÑŽÑ‚
-интерфейÑÑ‹. РееÑÑ‚Ñ€ не заботитьÑÑ Ð¾ том, что региÑтрируетÑÑ Ð¸ таким образом мы
-можем иÑпользовать целые, или Ñтроки что бы упроÑтить наши примеры. ЗдеÑÑŒ еÑÑ‚ÑŒ
-одно иÑключение. РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ None удалÑет региÑтрацию Ð´Ð»Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾
-зарегиÑтрированного прежде значениÑ.
-
-ЕÑли объект завиÑит от Ñпецификации он может быть запрошен Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ
-Ñпецификации ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñ€Ð°ÑширÑет Ñпецификацию от которой он завиÑит::
-
- >>> class IR2(IR1):
- ... pass
- >>> registry.lookup([IR2], IP2, '')
- 12
-
-Мы можем иÑпользовать клаÑÑ Ñ€ÐµÐ°Ð»Ð¸Ð·ÑƒÑŽÑ‰Ð¸Ð¹ Ñпецификацию Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа объекта::
-
- >>> class C2:
- ... zope.interface.implements(IR2)
-
- >>> registry.lookup([zope.interface.implementedBy(C2)], IP2, '')
- 12
-
-и объект может быть запрошен Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов которые предоÑтавлÑемый объектом
-Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ñ€Ð°ÑширÑет::
-
- >>> registry.lookup([IR1], IP1, '')
- 12
- >>> registry.lookup([IR2], IP1, '')
- 12
-
-Ðо еÑли вы требуете Ñпецификацию ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ раÑширÑет Ñпецификацию от которой
-завиÑит объект, вы не получите ничего::
-
- >>> registry.lookup([zope.interface.Interface], IP1, '')
-
-Между прочим, вы можете передать значение по умолчанию при запроÑе::
-
- >>> registry.lookup([zope.interface.Interface], IP1, '', 42)
- 42
-
-ЕÑли вы пробуете получить Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¹ объект не предоÑтавлÑет вы также
-не получите ничего::
-
- >>> class IP3(IP2):
- ... pass
- >>> registry.lookup([IR1], IP3, '')
-
-Ð’Ñ‹ также не получите ничего еÑли вы иÑпользуете неверное имÑ::
-
- >>> registry.lookup([IR1], IP1, 'bob')
- >>> registry.register([IR1], IP2, 'bob', "Bob's 12")
- >>> registry.lookup([IR1], IP1, 'bob')
- "Bob's 12"
-
-Ð’Ñ‹ можете не иÑпользовать Ð¸Ð¼Ñ Ð¿Ñ€Ð¸ запроÑе::
-
- >>> registry.lookup([IR1], IP1)
- 12
-
-ЕÑли мы региÑтрируем объект который предоÑтавлÑет IP1::
-
- >>> registry.register([IR1], IP1, '', 11)
-
-тогда Ñтот объект будет иметь преимущеÑтво перед O(12)::
-
- >>> registry.lookup([IR1], IP1, '')
- 11
-
-Также, еÑли мы региÑтрируем объект Ð´Ð»Ñ IR2 тогда он будет иметь преимущеÑтво
-когда иÑпользуетÑÑ IR2::
-
- >>> registry.register([IR2], IP1, '', 21)
- >>> registry.lookup([IR2], IP1, '')
- 21
-
-ПоиÑк того, что (еÑли вообще что-то) зарегиÑтрировано
------------------------------------------------------
-
-Мы можем ÑпроÑить еÑÑ‚ÑŒ-ли адаптер зарегиÑтрированный Ð´Ð»Ñ Ð½Ð°Ð±Ð¾Ñ€Ð° интерфейÑов.
-Это отличаетÑÑ Ð¾Ñ‚ обычного запроÑа так как здеÑÑŒ мы ищем точное Ñовпадение::
-
- >>> print registry.registered([IR1], IP1)
- 11
-
- >>> print registry.registered([IR1], IP2)
- 12
-
- >>> print registry.registered([IR1], IP2, 'bob')
- Bob's 12
-
-
- >>> print registry.registered([IR2], IP1)
- 21
-
- >>> print registry.registered([IR2], IP2)
- None
-
-Ð’ поÑледнем примере, None был возвращен потому, что Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ интерфейÑа
-ничего не было зарегиÑтрировано.
-
-lookup1
--------
-
-Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¾Ð´Ð¸Ð½Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ адаптера - Ñто наиболее чаÑÑ‚Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¸ Ð´Ð»Ñ Ð½ÐµÐµ еÑÑ‚ÑŒ
-ÑÐ¿ÐµÑ†Ð¸Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð»ÑƒÑ‡Ð°ÐµÑ‚ на вход единÑтвенный
-требуемый интерфейÑ::
-
- >>> registry.lookup1(IR2, IP1, '')
- 21
- >>> registry.lookup1(IR2, IP1)
- 21
-
-ÐÐ´Ð°Ð¿Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° практике
----------------------
-
-РееÑÑ‚Ñ€ адаптеров предназначен Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ адаптации когда один объект
-реализующий Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð¸Ñ€ÑƒÐµÑ‚ÑÑ Ðº другому объекту который поддерживает
-другой интерфейÑ. РееÑÑ‚Ñ€ адаптеров также поддерживает вычиÑление адаптеров. Ð’
-Ñтом Ñлучае мы должны региÑтрировать фабрики Ð´Ð»Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð¾Ð²::
-
- >>> class IR(zope.interface.Interface):
- ... pass
-
- >>> class X:
- ... zope.interface.implements(IR)
-
- >>> class Y:
- ... zope.interface.implements(IP1)
- ... def __init__(self, context):
- ... self.context = context
-
- >>> registry.register([IR], IP1, '', Y)
-
-Ð’ Ñтом Ñлучае мы региÑтрируем клаÑÑ ÐºÐ°Ðº фабрику. Теперь мы можем вызвать
-`queryAdapter` Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ объекта::
-
- >>> x = X()
- >>> y = registry.queryAdapter(x, IP1)
- >>> y.__class__.__name__
- 'Y'
- >>> y.context is x
- True
-
-Мы также можем региÑтрировать и запрашивать по имени::
-
- >>> class Y2(Y):
- ... pass
-
- >>> registry.register([IR], IP1, 'bob', Y2)
- >>> y = registry.queryAdapter(x, IP1, 'bob')
- >>> y.__class__.__name__
- 'Y2'
- >>> y.context is x
- True
-
-Когда фабрика Ð´Ð»Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð° возвращает `None` - Ñто раÑÑматриваетÑÑ ÐºÐ°Ðº еÑли бы
-адаптер не был найден. Это позволÑет нам избежать адаптации (по желанию) и дает
-возможноÑÑ‚ÑŒ фабрике адаптера определить возможна ли Ð°Ð´Ð°Ð¿Ñ‚Ð°Ñ†Ð¸Ñ Ð¾ÑновываÑÑÑŒ на
-ÑоÑтоÑнии объекта который адаптируетÑÑ::
-
- >>> def factory(context):
- ... if context.name == 'object':
- ... return 'adapter'
- ... return None
-
- >>> class Object(object):
- ... zope.interface.implements(IR)
- ... name = 'object'
-
- >>> registry.register([IR], IP1, 'conditional', factory)
- >>> obj = Object()
- >>> registry.queryAdapter(obj, IP1, 'conditional')
- 'adapter'
- >>> obj.name = 'no object'
- >>> registry.queryAdapter(obj, IP1, 'conditional') is None
- True
- >>> registry.queryAdapter(obj, IP1, 'conditional', 'default')
- 'default'
-
-Ðльтернативный метод Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð°ÐºÐ¾Ð¹ же функциональноÑти как и
-`queryAdapter()` - Ñто `adapter_hook()`::
-
- >>> y = registry.adapter_hook(IP1, x)
- >>> y.__class__.__name__
- 'Y'
- >>> y.context is x
- True
- >>> y = registry.adapter_hook(IP1, x, 'bob')
- >>> y.__class__.__name__
- 'Y2'
- >>> y.context is x
- True
-
-`adapter_hook()` проÑто менÑет порÑдок аргументов Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° и интерфейÑа. Это
-иÑпользуетÑÑ Ð´Ð»Ñ Ð²ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°Ð½Ð¸Ñ Ð² механизм вызовов интерфейÑов.
-
-Ðдаптеры по умолчанию
----------------------
-
-Иногда вы можете захотеть предоÑтавить адаптер который не будет ничего
-адаптировать. Ð”Ð»Ñ Ñтого нужно передать None как требуемый интерфейÑ::
-
- >>> registry.register([None], IP1, '', 1)
-
-поÑле Ñтого вы можете иÑпользовать Ñтот адаптер Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñов Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… у
-Ð²Ð°Ñ Ð½ÐµÑ‚ конкретного адаптера::
-
- >>> class IQ(zope.interface.Interface):
- ... pass
- >>> registry.lookup([IQ], IP1, '')
- 1
-
-Конечно, конкретные адаптеры вÑе еще иÑпользуютÑÑ ÐºÐ¾Ð³Ð´Ð° необходимо::
-
- >>> registry.lookup([IR2], IP1, '')
- 21
-
-Ðдаптеры клаÑÑов
-----------------
-
-Ð’Ñ‹ можете региÑтрировать адаптеры Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ð¹ клаÑÑов, что будет похоже на
-региÑтрацию их Ð´Ð»Ñ ÐºÐ»Ð°ÑÑов::
-
- >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', 'C21')
- >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
- 'C21'
-
-Ðдаптеры Ð´Ð»Ñ Ñловарей
----------------------
-
-Ð’ какой-то момент было невозможно региÑтрировать адаптеры оÑнованные на
-ÑловарÑÑ… из-за ошибки. Давайте удоÑтоверимÑÑ Ñ‡Ñ‚Ð¾ Ñто теперь работает::
-
- >>> adapter = {}
- >>> registry.register((), IQ, '', adapter)
- >>> registry.lookup((), IQ, '') is adapter
- True
-
-Удаление региÑтрации
---------------------
-
-Ð’Ñ‹ можете удалить региÑтрацию региÑÑ‚Ñ€Ð¸Ñ€ÑƒÑ None вмеÑто объекта::
-
- >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', None)
- >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
- 21
-
-Конечно Ñто значит, что None не может быть зарегиÑтрирован. Это иÑключение к
-утверждению выше о том, что рееÑÑ‚Ñ€ не заботитьÑÑ Ð¾ том, что региÑтрируетÑÑ.
-
-Мульти-адаптеры
-===============
-
-Ð’Ñ‹ можете адаптировать неÑколько Ñпецификаций::
-
- >>> registry.register([IR1, IQ], IP2, '', '1q2')
- >>> registry.lookup([IR1, IQ], IP2, '')
- '1q2'
- >>> registry.lookup([IR2, IQ], IP1, '')
- '1q2'
-
- >>> class IS(zope.interface.Interface):
- ... pass
- >>> registry.lookup([IR2, IS], IP1, '')
-
- >>> class IQ2(IQ):
- ... pass
-
- >>> registry.lookup([IR2, IQ2], IP1, '')
- '1q2'
-
- >>> registry.register([IR1, IQ2], IP2, '', '1q22')
- >>> registry.lookup([IR2, IQ2], IP1, '')
- '1q22'
-
-Мульти-адаптациÑ
-----------------
-
-Ð’Ñ‹ можете адаптировать неÑколько объектов::
-
- >>> class Q:
- ... zope.interface.implements(IQ)
-
-Как и Ñ Ð¾Ð´Ð¸Ð½Ð¾Ñ‡Ð½Ñ‹Ð¼Ð¸ адаптерами, мы региÑтрируем фабрику ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÐµÑ‚
-клаÑÑ::
-
- >>> class IM(zope.interface.Interface):
- ... pass
- >>> class M:
- ... zope.interface.implements(IM)
- ... def __init__(self, x, q):
- ... self.x, self.q = x, q
- >>> registry.register([IR, IQ], IM, '', M)
-
-И затем мы можем вызвать `queryMultiAdapter` Ð´Ð»Ñ Ð²Ñ‹Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð°::
-
- >>> q = Q()
- >>> m = registry.queryMultiAdapter((x, q), IM)
- >>> m.__class__.__name__
- 'M'
- >>> m.x is x and m.q is q
- True
-
-и, конечно, мы можем иÑпользовать имена::
-
- >>> class M2(M):
- ... pass
- >>> registry.register([IR, IQ], IM, 'bob', M2)
- >>> m = registry.queryMultiAdapter((x, q), IM, 'bob')
- >>> m.__class__.__name__
- 'M2'
- >>> m.x is x and m.q is q
- True
-
-Ðдаптеры по умолчанию
----------------------
-
-Как и Ð´Ð»Ñ Ð¾Ð´Ð¸Ð½Ð¾Ñ‡Ð½Ñ‹Ñ… адаптеров вы можете определить адаптер по умолчанию передав
-None вмеÑто *первой* Ñпецификации::
-
- >>> registry.register([None, IQ], IP2, '', 'q2')
- >>> registry.lookup([IS, IQ], IP2, '')
- 'q2'
-
-Ðулевые адаптеры
-================
-
-Ð’Ñ‹ можете также адаптировать без Ñпецификации::
-
- >>> registry.register([], IP2, '', 2)
- >>> registry.lookup([], IP2, '')
- 2
- >>> registry.lookup([], IP1, '')
- 2
-
-ПеречиÑление именованных адаптеров
-----------------------------------
-
-Ðдаптеры имеют имена. Иногда Ñто полезно Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñех именованных
-адаптеров Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ интерфейÑа::
-
- >>> adapters = list(registry.lookupAll([IR1], IP1))
- >>> adapters.sort()
- >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
-
-Это работает также и Ð´Ð»Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸-адаптеров::
-
- >>> registry.register([IR1, IQ2], IP2, 'bob', '1q2 for bob')
- >>> adapters = list(registry.lookupAll([IR2, IQ2], IP1))
- >>> adapters.sort()
- >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
-
-И даже Ð´Ð»Ñ Ð½ÑƒÐ»ÐµÐ²Ñ‹Ñ… адаптеров::
-
- >>> registry.register([], IP2, 'bob', 3)
- >>> adapters = list(registry.lookupAll([], IP1))
- >>> adapters.sort()
- >>> assert adapters == [(u'', 2), (u'bob', 3)]
-
-ПодпиÑки
-========
-
-Обычно мы хотим запроÑить объект который наиболее близко ÑоответÑтвует
-Ñпецификации. Иногда мы хотим получить вÑе объекты которые ÑоответÑтвуют
-какой-либо Ñпецификации. Мы иÑпользуем подпиÑки Ð´Ð»Ñ Ñтого. Мы подпиÑываем
-объекты Ð´Ð»Ñ Ñпецификаций и затем позже находим вÑе подпиÑанные объекты::
-
- >>> registry.subscribe([IR1], IP2, 'sub12 1')
- >>> registry.subscriptions([IR1], IP2)
- ['sub12 1']
-
-Заметьте, что в отличие от обычных адаптеров подпиÑки не имеют имен.
-
-Ð’Ñ‹ можете иметь неÑколько подпиÑчиков Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð¹ Ñпецификации::
-
- >>> registry.subscribe([IR1], IP2, 'sub12 2')
- >>> registry.subscriptions([IR1], IP2)
- ['sub12 1', 'sub12 2']
-
-ЕÑли подпиÑчики зарегиÑтрированы Ð´Ð»Ñ Ð¾Ð´Ð½Ð¸Ñ… и тех же требуемых интерфейÑов, они
-возвращаютÑÑ Ð² порÑдке определениÑ.
-
-Ð’Ñ‹ можете зарегиÑтрировать подпиÑчики Ð´Ð»Ñ Ð²Ñех Ñпецификаций иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ None::
-
- >>> registry.subscribe([None], IP1, 'sub_1')
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2']
-
-Заметьте, что новый подпиÑчик возвращаетÑÑ Ð¿ÐµÑ€Ð²Ñ‹Ð¼. ПодпиÑчики определенные
-Ð´Ð»Ñ Ð¼ÐµÐ½ÐµÐµ общих требуемых интерфейÑов возвращаютÑÑ Ð¿ÐµÑ€ÐµÐ´ подпиÑчиками
-Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ общих интерфейÑов.
-
-ПодпиÑки могут ÑмешиватьÑÑ Ð¼ÐµÐ¶Ð´Ñƒ неÑколькими ÑовмеÑтимыми ÑпецификациÑми::
-
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2']
- >>> registry.subscribe([IR1], IP1, 'sub11')
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2', 'sub11']
- >>> registry.subscribe([IR2], IP2, 'sub22')
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2', 'sub11', 'sub22']
- >>> registry.subscriptions([IR2], IP2)
- ['sub12 1', 'sub12 2', 'sub22']
-
-ПодпиÑки могут ÑущеÑтвовать Ð´Ð»Ñ Ð½ÐµÑкольких Ñпецификаций::
-
- >>> registry.subscribe([IR1, IQ], IP2, 'sub1q2')
- >>> registry.subscriptions([IR1, IQ], IP2)
- ['sub1q2']
-
-Как и Ñ Ð¾Ð´Ð¸Ð½Ð¾Ñ‡Ð½Ñ‹Ð¼Ð¸ подпиÑчиками и адаптерами без подпиÑок, вы можете определить
-None Ð´Ð»Ñ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ требуемого интерфейÑа, что бы задать значение по умолчанию::
-
- >>> registry.subscribe([None, IQ], IP2, 'sub_q2')
- >>> registry.subscriptions([IS, IQ], IP2)
- ['sub_q2']
- >>> registry.subscriptions([IR1, IQ], IP2)
- ['sub_q2', 'sub1q2']
-
-Ð’Ñ‹ можете Ñоздать подпиÑки которые незавиÑимы от любых Ñпецификаций::
-
- >>> list(registry.subscriptions([], IP1))
- []
-
- >>> registry.subscribe([], IP2, 'sub2')
- >>> registry.subscriptions([], IP1)
- ['sub2']
- >>> registry.subscribe([], IP1, 'sub1')
- >>> registry.subscriptions([], IP1)
- ['sub2', 'sub1']
- >>> registry.subscriptions([], IP2)
- ['sub2']
-
-Удаление региÑтрации подпиÑчиков
---------------------------------
-
-Мы можем удалÑÑ‚ÑŒ региÑтрацию подпиÑчиков. При удалении региÑтрации подпиÑчика
-мы можем удалить региÑтрацию заданного адаптера::
-
- >>> registry.unsubscribe([IR1], IP1, 'sub11')
- >>> registry.subscriptions([IR1], IP1)
- ['sub_1', 'sub12 1', 'sub12 2']
-
-ЕÑли мы не задаем никакого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð³Ð´Ð° подпиÑки будут удалены Ð´Ð»Ñ Ð²Ñех
-подпиÑчиков Ñовпадающих Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñ‹Ð¼ интерфейÑом::
-
- >>> registry.unsubscribe([IR1], IP2)
- >>> registry.subscriptions([IR1], IP1)
- ['sub_1']
-
-Ðдаптеры подпиÑки
------------------
-
-Обычно мы региÑтрируем фабрики Ð´Ð»Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð¾Ð² которые затем позволÑÑŽÑ‚ нам
-вычиÑлÑÑ‚ÑŒ адаптеры, но Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñками мы получаем неÑколько адаптеров. Это пример
-подпиÑчика Ð´Ð»Ñ Ð½ÐµÑкольких объектов::
-
- >>> registry.subscribe([IR, IQ], IM, M)
- >>> registry.subscribe([IR, IQ], IM, M2)
-
- >>> subscribers = registry.subscribers((x, q), IM)
- >>> len(subscribers)
- 2
- >>> class_names = [s.__class__.__name__ for s in subscribers]
- >>> class_names.sort()
- >>> class_names
- ['M', 'M2']
- >>> [(s.x is x and s.q is q) for s in subscribers]
- [True, True]
-
-подпиÑчики фабрик адаптеров не могут возвращать None::
-
- >>> def M3(x, y):
- ... return None
-
- >>> registry.subscribe([IR, IQ], IM, M3)
- >>> subscribers = registry.subscribers((x, q), IM)
- >>> len(subscribers)
- 2
-
-Обработчики
------------
-
-Обработчик - Ñто подпиÑÐ°Ð½Ð½Ð°Ñ Ñ„Ð°Ð±Ñ€Ð¸ÐºÐ° ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ возвращает нормального
-значениÑ. Она возвращает None. Обработчик отличаетÑÑ Ð¾Ñ‚ адаптеров тем, что он
-делает вÑÑŽ работу когда вызываетÑÑ Ñ„Ð°Ð±Ñ€Ð¸ÐºÐ°.
-
-Ð”Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации обработчика надо проÑто передать None как предоÑтавлÑемый
-интерфейÑ::
-
- >>> def handler(event):
- ... print 'handler', event
-
- >>> registry.subscribe([IR1], None, handler)
- >>> registry.subscriptions([IR1], None) == [handler]
- True
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.txt
deleted file mode 100644
index 298a8622..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.txt
+++ /dev/null
@@ -1,543 +0,0 @@
-================
-Adapter Registry
-================
-
-Adapter registries provide a way to register objects that depend on
-one or more interface specifications and provide (perhaps indirectly)
-some interface. In addition, the registrations have names. (You can
-think of the names as qualifiers of the provided interfaces.)
-
-The term "interface specification" refers both to interfaces and to
-interface declarations, such as declarations of interfaces implemented
-by a class.
-
-
-Single Adapters
-===============
-
-Let's look at a simple example, using a single required specification::
-
- >>> from zope.interface.adapter import AdapterRegistry
- >>> import zope.interface
-
- >>> class IR1(zope.interface.Interface):
- ... pass
- >>> class IP1(zope.interface.Interface):
- ... pass
- >>> class IP2(IP1):
- ... pass
-
- >>> registry = AdapterRegistry()
-
-We'll register an object that depends on IR1 and "provides" IP2::
-
- >>> registry.register([IR1], IP2, '', 12)
-
-Given the registration, we can look it up again::
-
- >>> registry.lookup([IR1], IP2, '')
- 12
-
-Note that we used an integer in the example. In real applications,
-one would use some objects that actually depend on or provide
-interfaces. The registry doesn't care about what gets registered, so
-we'll use integers and strings to keep the examples simple. There is
-one exception. Registering a value of None unregisters any
-previously-registered value.
-
-If an object depends on a specification, it can be looked up with a
-specification that extends the specification that it depends on::
-
- >>> class IR2(IR1):
- ... pass
- >>> registry.lookup([IR2], IP2, '')
- 12
-
-We can use a class implementation specification to look up the object::
-
- >>> class C2:
- ... zope.interface.implements(IR2)
-
- >>> registry.lookup([zope.interface.implementedBy(C2)], IP2, '')
- 12
-
-
-and it can be looked up for interfaces that its provided interface
-extends::
-
- >>> registry.lookup([IR1], IP1, '')
- 12
- >>> registry.lookup([IR2], IP1, '')
- 12
-
-But if you require a specification that doesn't extend the specification the
-object depends on, you won't get anything::
-
- >>> registry.lookup([zope.interface.Interface], IP1, '')
-
-By the way, you can pass a default value to lookup::
-
- >>> registry.lookup([zope.interface.Interface], IP1, '', 42)
- 42
-
-If you try to get an interface the object doesn't provide, you also
-won't get anything::
-
- >>> class IP3(IP2):
- ... pass
- >>> registry.lookup([IR1], IP3, '')
-
-You also won't get anything if you use the wrong name::
-
- >>> registry.lookup([IR1], IP1, 'bob')
- >>> registry.register([IR1], IP2, 'bob', "Bob's 12")
- >>> registry.lookup([IR1], IP1, 'bob')
- "Bob's 12"
-
-You can leave the name off when doing a lookup::
-
- >>> registry.lookup([IR1], IP1)
- 12
-
-If we register an object that provides IP1::
-
- >>> registry.register([IR1], IP1, '', 11)
-
-then that object will be prefered over O(12)::
-
- >>> registry.lookup([IR1], IP1, '')
- 11
-
-Also, if we register an object for IR2, then that will be prefered
-when using IR2::
-
- >>> registry.register([IR2], IP1, '', 21)
- >>> registry.lookup([IR2], IP1, '')
- 21
-
-Finding out what, if anything, is registered
---------------------------------------------
-
-We can ask if there is an adapter registered for a collection of
-interfaces. This is different than lookup, because it looks for an
-exact match.
-
- >>> print registry.registered([IR1], IP1)
- 11
-
- >>> print registry.registered([IR1], IP2)
- 12
-
- >>> print registry.registered([IR1], IP2, 'bob')
- Bob's 12
-
-
- >>> print registry.registered([IR2], IP1)
- 21
-
- >>> print registry.registered([IR2], IP2)
- None
-
-In the last example, None was returned because nothing was registered
-exactly for the given interfaces.
-
-lookup1
--------
-
-Lookup of single adapters is common enough that there is a specialized
-version of lookup that takes a single required interface::
-
- >>> registry.lookup1(IR2, IP1, '')
- 21
- >>> registry.lookup1(IR2, IP1)
- 21
-
-Actual Adaptation
------------------
-
-The adapter registry is intended to support adaptation, where one
-object that implements an interface is adapted to another object that
-supports a different interface. The adapter registry supports the
-computation of adapters. In this case, we have to register adapter
-factories::
-
- >>> class IR(zope.interface.Interface):
- ... pass
-
- >>> class X:
- ... zope.interface.implements(IR)
-
- >>> class Y:
- ... zope.interface.implements(IP1)
- ... def __init__(self, context):
- ... self.context = context
-
- >>> registry.register([IR], IP1, '', Y)
-
-In this case, we registered a class as the factory. Now we can call
-`queryAdapter` to get the adapted object::
-
- >>> x = X()
- >>> y = registry.queryAdapter(x, IP1)
- >>> y.__class__.__name__
- 'Y'
- >>> y.context is x
- True
-
-We can register and lookup by name too::
-
- >>> class Y2(Y):
- ... pass
-
- >>> registry.register([IR], IP1, 'bob', Y2)
- >>> y = registry.queryAdapter(x, IP1, 'bob')
- >>> y.__class__.__name__
- 'Y2'
- >>> y.context is x
- True
-
-When the adapter factory produces `None`, then this is treated as if no
-adapter has been found. This allows us to prevent adaptation (when desired)
-and let the adapter factory determine whether adaptation is possible based on
-the state of the object being adapted.
-
- >>> def factory(context):
- ... if context.name == 'object':
- ... return 'adapter'
- ... return None
-
- >>> class Object(object):
- ... zope.interface.implements(IR)
- ... name = 'object'
-
- >>> registry.register([IR], IP1, 'conditional', factory)
- >>> obj = Object()
- >>> registry.queryAdapter(obj, IP1, 'conditional')
- 'adapter'
- >>> obj.name = 'no object'
- >>> registry.queryAdapter(obj, IP1, 'conditional') is None
- True
- >>> registry.queryAdapter(obj, IP1, 'conditional', 'default')
- 'default'
-
-An alternate method that provides the same function as `queryAdapter()` is
-`adapter_hook()`::
-
- >>> y = registry.adapter_hook(IP1, x)
- >>> y.__class__.__name__
- 'Y'
- >>> y.context is x
- True
- >>> y = registry.adapter_hook(IP1, x, 'bob')
- >>> y.__class__.__name__
- 'Y2'
- >>> y.context is x
- True
-
-The `adapter_hook()` simply switches the order of the object and
-interface arguments. It is used to hook into the interface call
-mechanism.
-
-
-Default Adapters
-----------------
-
-Sometimes, you want to provide an adapter that will adapt anything.
-For that, provide None as the required interface::
-
- >>> registry.register([None], IP1, '', 1)
-
-then we can use that adapter for interfaces we don't have specific
-adapters for::
-
- >>> class IQ(zope.interface.Interface):
- ... pass
- >>> registry.lookup([IQ], IP1, '')
- 1
-
-Of course, specific adapters are still used when applicable::
-
- >>> registry.lookup([IR2], IP1, '')
- 21
-
-Class adapters
---------------
-
-You can register adapters for class declarations, which is almost the
-same as registering them for a class::
-
- >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', 'C21')
- >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
- 'C21'
-
-Dict adapters
--------------
-
-At some point it was impossible to register dictionary-based adapters due a
-bug. Let's make sure this works now:
-
- >>> adapter = {}
- >>> registry.register((), IQ, '', adapter)
- >>> registry.lookup((), IQ, '') is adapter
- True
-
-Unregistering
--------------
-
-You can unregister by registering None, rather than an object::
-
- >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', None)
- >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
- 21
-
-Of course, this means that None can't be registered. This is an
-exception to the statement, made earlier, that the registry doesn't
-care what gets registered.
-
-Multi-adapters
-==============
-
-You can adapt multiple specifications::
-
- >>> registry.register([IR1, IQ], IP2, '', '1q2')
- >>> registry.lookup([IR1, IQ], IP2, '')
- '1q2'
- >>> registry.lookup([IR2, IQ], IP1, '')
- '1q2'
-
- >>> class IS(zope.interface.Interface):
- ... pass
- >>> registry.lookup([IR2, IS], IP1, '')
-
- >>> class IQ2(IQ):
- ... pass
-
- >>> registry.lookup([IR2, IQ2], IP1, '')
- '1q2'
-
- >>> registry.register([IR1, IQ2], IP2, '', '1q22')
- >>> registry.lookup([IR2, IQ2], IP1, '')
- '1q22'
-
-Multi-adaptation
-----------------
-
-You can adapt multiple objects::
-
- >>> class Q:
- ... zope.interface.implements(IQ)
-
-As with single adapters, we register a factory, which is often a class::
-
- >>> class IM(zope.interface.Interface):
- ... pass
- >>> class M:
- ... zope.interface.implements(IM)
- ... def __init__(self, x, q):
- ... self.x, self.q = x, q
- >>> registry.register([IR, IQ], IM, '', M)
-
-And then we can call `queryMultiAdapter` to compute an adapter::
-
- >>> q = Q()
- >>> m = registry.queryMultiAdapter((x, q), IM)
- >>> m.__class__.__name__
- 'M'
- >>> m.x is x and m.q is q
- True
-
-and, of course, we can use names::
-
- >>> class M2(M):
- ... pass
- >>> registry.register([IR, IQ], IM, 'bob', M2)
- >>> m = registry.queryMultiAdapter((x, q), IM, 'bob')
- >>> m.__class__.__name__
- 'M2'
- >>> m.x is x and m.q is q
- True
-
-Default Adapters
-----------------
-
-As with single adapters, you can define default adapters by specifying
-None for the *first* specification::
-
- >>> registry.register([None, IQ], IP2, '', 'q2')
- >>> registry.lookup([IS, IQ], IP2, '')
- 'q2'
-
-Null Adapters
-=============
-
-You can also adapt no specification::
-
- >>> registry.register([], IP2, '', 2)
- >>> registry.lookup([], IP2, '')
- 2
- >>> registry.lookup([], IP1, '')
- 2
-
-Listing named adapters
-----------------------
-
-Adapters are named. Sometimes, it's useful to get all of the named
-adapters for given interfaces::
-
- >>> adapters = list(registry.lookupAll([IR1], IP1))
- >>> adapters.sort()
- >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
-
-This works for multi-adapters too::
-
- >>> registry.register([IR1, IQ2], IP2, 'bob', '1q2 for bob')
- >>> adapters = list(registry.lookupAll([IR2, IQ2], IP1))
- >>> adapters.sort()
- >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
-
-And even null adapters::
-
- >>> registry.register([], IP2, 'bob', 3)
- >>> adapters = list(registry.lookupAll([], IP1))
- >>> adapters.sort()
- >>> assert adapters == [(u'', 2), (u'bob', 3)]
-
-Subscriptions
-=============
-
-Normally, we want to look up an object that most-closely matches a
-specification. Sometimes, we want to get all of the objects that
-match some specification. We use subscriptions for this. We
-subscribe objects against specifications and then later find all of
-the subscribed objects::
-
- >>> registry.subscribe([IR1], IP2, 'sub12 1')
- >>> registry.subscriptions([IR1], IP2)
- ['sub12 1']
-
-Note that, unlike regular adapters, subscriptions are unnamed.
-
-You can have multiple subscribers for the same specification::
-
- >>> registry.subscribe([IR1], IP2, 'sub12 2')
- >>> registry.subscriptions([IR1], IP2)
- ['sub12 1', 'sub12 2']
-
-If subscribers are registered for the same required interfaces, they
-are returned in the order of definition.
-
-You can register subscribers for all specifications using None::
-
- >>> registry.subscribe([None], IP1, 'sub_1')
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2']
-
-Note that the new subscriber is returned first. Subscribers defined
-for less general required interfaces are returned before subscribers
-for more general interfaces.
-
-Subscriptions may be combined over multiple compatible specifications::
-
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2']
- >>> registry.subscribe([IR1], IP1, 'sub11')
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2', 'sub11']
- >>> registry.subscribe([IR2], IP2, 'sub22')
- >>> registry.subscriptions([IR2], IP1)
- ['sub_1', 'sub12 1', 'sub12 2', 'sub11', 'sub22']
- >>> registry.subscriptions([IR2], IP2)
- ['sub12 1', 'sub12 2', 'sub22']
-
-Subscriptions can be on multiple specifications::
-
- >>> registry.subscribe([IR1, IQ], IP2, 'sub1q2')
- >>> registry.subscriptions([IR1, IQ], IP2)
- ['sub1q2']
-
-As with single subscriptions and non-subscription adapters, you can
-specify None for the first required interface, to specify a default::
-
- >>> registry.subscribe([None, IQ], IP2, 'sub_q2')
- >>> registry.subscriptions([IS, IQ], IP2)
- ['sub_q2']
- >>> registry.subscriptions([IR1, IQ], IP2)
- ['sub_q2', 'sub1q2']
-
-You can have subscriptions that are indepenent of any specifications::
-
- >>> list(registry.subscriptions([], IP1))
- []
-
- >>> registry.subscribe([], IP2, 'sub2')
- >>> registry.subscriptions([], IP1)
- ['sub2']
- >>> registry.subscribe([], IP1, 'sub1')
- >>> registry.subscriptions([], IP1)
- ['sub2', 'sub1']
- >>> registry.subscriptions([], IP2)
- ['sub2']
-
-Unregistering subscribers
--------------------------
-
-We can unregister subscribers. When unregistering a subscriber, we
-can unregister a specific subscriber::
-
- >>> registry.unsubscribe([IR1], IP1, 'sub11')
- >>> registry.subscriptions([IR1], IP1)
- ['sub_1', 'sub12 1', 'sub12 2']
-
-If we don't specify a value, then all subscribers matching the given
-interfaces will be unsubscribed:
-
- >>> registry.unsubscribe([IR1], IP2)
- >>> registry.subscriptions([IR1], IP1)
- ['sub_1']
-
-
-Subscription adapters
----------------------
-
-We normally register adapter factories, which then allow us to compute
-adapters, but with subscriptions, we get multiple adapters. Here's an
-example of multiple-object subscribers::
-
- >>> registry.subscribe([IR, IQ], IM, M)
- >>> registry.subscribe([IR, IQ], IM, M2)
-
- >>> subscribers = registry.subscribers((x, q), IM)
- >>> len(subscribers)
- 2
- >>> class_names = [s.__class__.__name__ for s in subscribers]
- >>> class_names.sort()
- >>> class_names
- ['M', 'M2']
- >>> [(s.x is x and s.q is q) for s in subscribers]
- [True, True]
-
-adapter factory subcribers can't return None values::
-
- >>> def M3(x, y):
- ... return None
-
- >>> registry.subscribe([IR, IQ], IM, M3)
- >>> subscribers = registry.subscribers((x, q), IM)
- >>> len(subscribers)
- 2
-
-Handlers
---------
-
-A handler is a subscriber factory that doesn't produce any normal
-output. It returns None. A handler is unlike adapters in that it does
-all of its work when the factory is called.
-
-To register a handler, simply provide None as the provided interface::
-
- >>> def handler(event):
- ... print 'handler', event
-
- >>> registry.subscribe([IR1], None, handler)
- >>> registry.subscriptions([IR1], None) == [handler]
- True
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/advice.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/advice.py
deleted file mode 100644
index d23818ee..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/advice.py
+++ /dev/null
@@ -1,201 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Class advice.
-
-This module was adapted from 'protocols.advice', part of the Python
-Enterprise Application Kit (PEAK). Please notify the PEAK authors
-(pje@telecommunity.com and tsarna@sarna.org) if bugs are found or
-Zope-specific changes are required, so that the PEAK version of this module
-can be kept in sync.
-
-PEAK is a Python application framework that interoperates with (but does
-not require) Zope 3 and Twisted. It provides tools for manipulating UML
-models, object-relational persistence, aspect-oriented programming, and more.
-Visit the PEAK home page at http://peak.telecommunity.com for more information.
-"""
-
-from types import FunctionType
-try:
- from types import ClassType
- __python3 = False
-except ImportError:
- __python3 = True
-
-import sys
-
-def getFrameInfo(frame):
- """Return (kind,module,locals,globals) for a frame
-
- 'kind' is one of "exec", "module", "class", "function call", or "unknown".
- """
-
- f_locals = frame.f_locals
- f_globals = frame.f_globals
-
- sameNamespace = f_locals is f_globals
- hasModule = '__module__' in f_locals
- hasName = '__name__' in f_globals
-
- sameName = hasModule and hasName
- sameName = sameName and f_globals['__name__']==f_locals['__module__']
-
- module = hasName and sys.modules.get(f_globals['__name__']) or None
-
- namespaceIsModule = module and module.__dict__ is f_globals
-
- if not namespaceIsModule:
- # some kind of funky exec
- kind = "exec"
- elif sameNamespace and not hasModule:
- kind = "module"
- elif sameName and not sameNamespace:
- kind = "class"
- elif not sameNamespace:
- kind = "function call"
- else:
- # How can you have f_locals is f_globals, and have '__module__' set?
- # This is probably module-level code, but with a '__module__' variable.
- kind = "unknown"
- return kind, module, f_locals, f_globals
-
-
-def addClassAdvisor(callback, depth=2):
- """Set up 'callback' to be passed the containing class upon creation
-
- This function is designed to be called by an "advising" function executed
- in a class suite. The "advising" function supplies a callback that it
- wishes to have executed when the containing class is created. The
- callback will be given one argument: the newly created containing class.
- The return value of the callback will be used in place of the class, so
- the callback should return the input if it does not wish to replace the
- class.
-
- The optional 'depth' argument to this function determines the number of
- frames between this function and the targeted class suite. 'depth'
- defaults to 2, since this skips this function's frame and one calling
- function frame. If you use this function from a function called directly
- in the class suite, the default will be correct, otherwise you will need
- to determine the correct depth yourself.
-
- This function works by installing a special class factory function in
- place of the '__metaclass__' of the containing class. Therefore, only
- callbacks *after* the last '__metaclass__' assignment in the containing
- class will be executed. Be sure that classes using "advising" functions
- declare any '__metaclass__' *first*, to ensure all callbacks are run."""
-
- frame = sys._getframe(depth)
- kind, module, caller_locals, caller_globals = getFrameInfo(frame)
-
- # This causes a problem when zope interfaces are used from doctest.
- # In these cases, kind == "exec".
- #
- #if kind != "class":
- # raise SyntaxError(
- # "Advice must be in the body of a class statement"
- # )
-
- previousMetaclass = caller_locals.get('__metaclass__')
- if __python3:
- defaultMetaclass = caller_globals.get('__metaclass__', type)
- else:
- defaultMetaclass = caller_globals.get('__metaclass__', ClassType)
-
-
- def advise(name, bases, cdict):
-
- if '__metaclass__' in cdict:
- del cdict['__metaclass__']
-
- if previousMetaclass is None:
- if bases:
- # find best metaclass or use global __metaclass__ if no bases
- meta = determineMetaclass(bases)
- else:
- meta = defaultMetaclass
-
- elif isClassAdvisor(previousMetaclass):
- # special case: we can't compute the "true" metaclass here,
- # so we need to invoke the previous metaclass and let it
- # figure it out for us (and apply its own advice in the process)
- meta = previousMetaclass
-
- else:
- meta = determineMetaclass(bases, previousMetaclass)
-
- newClass = meta(name,bases,cdict)
-
- # this lets the callback replace the class completely, if it wants to
- return callback(newClass)
-
- # introspection data only, not used by inner function
- advise.previousMetaclass = previousMetaclass
- advise.callback = callback
-
- # install the advisor
- caller_locals['__metaclass__'] = advise
-
-
-def isClassAdvisor(ob):
- """True if 'ob' is a class advisor function"""
- return isinstance(ob,FunctionType) and hasattr(ob,'previousMetaclass')
-
-
-def determineMetaclass(bases, explicit_mc=None):
- """Determine metaclass from 1+ bases and optional explicit __metaclass__"""
-
- meta = [getattr(b,'__class__',type(b)) for b in bases]
-
- if explicit_mc is not None:
- # The explicit metaclass needs to be verified for compatibility
- # as well, and allowed to resolve the incompatible bases, if any
- meta.append(explicit_mc)
-
- if len(meta)==1:
- # easy case
- return meta[0]
-
- candidates = minimalBases(meta) # minimal set of metaclasses
-
- if not candidates:
- # they're all "classic" classes
- assert(not __python3) # This should not happen under Python 3
- return ClassType
-
- elif len(candidates)>1:
- # We could auto-combine, but for now we won't...
- raise TypeError("Incompatible metatypes",bases)
-
- # Just one, return it
- return candidates[0]
-
-
-def minimalBases(classes):
- """Reduce a list of base classes to its ordered minimum equivalent"""
-
- if not __python3:
- classes = [c for c in classes if c is not ClassType]
- candidates = []
-
- for m in classes:
- for n in classes:
- if issubclass(n,m) and m is not n:
- break
- else:
- # m has no subclasses in 'classes'
- if m in candidates:
- candidates.remove(m) # ensure that we're later in the list
- candidates.append(m)
-
- return candidates
-
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/__init__.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/__init__.py
deleted file mode 100644
index b711d360..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-#
-# This file is necessary to make this directory a package.
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/idatetime.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/idatetime.py
deleted file mode 100644
index e8700af9..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/idatetime.py
+++ /dev/null
@@ -1,575 +0,0 @@
-##############################################################################
-# Copyright (c) 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-##############################################################################
-"""Datetime interfaces.
-
-This module is called idatetime because if it were called datetime the import
-of the real datetime would fail.
-"""
-
-from zope.interface import Interface, Attribute
-from zope.interface import classImplements
-
-from datetime import timedelta, date, datetime, time, tzinfo
-
-
-class ITimeDeltaClass(Interface):
- """This is the timedelta class interface."""
-
- min = Attribute("The most negative timedelta object")
-
- max = Attribute("The most positive timedelta object")
-
- resolution = Attribute(
- "The smallest difference between non-equal timedelta objects")
-
-
-class ITimeDelta(ITimeDeltaClass):
- """Represent the difference between two datetime objects.
-
- Supported operators:
-
- - add, subtract timedelta
- - unary plus, minus, abs
- - compare to timedelta
- - multiply, divide by int/long
-
- In addition, datetime supports subtraction of two datetime objects
- returning a timedelta, and addition or subtraction of a datetime
- and a timedelta giving a datetime.
-
- Representation: (days, seconds, microseconds).
- """
-
- days = Attribute("Days between -999999999 and 999999999 inclusive")
-
- seconds = Attribute("Seconds between 0 and 86399 inclusive")
-
- microseconds = Attribute("Microseconds between 0 and 999999 inclusive")
-
-
-class IDateClass(Interface):
- """This is the date class interface."""
-
- min = Attribute("The earliest representable date")
-
- max = Attribute("The latest representable date")
-
- resolution = Attribute(
- "The smallest difference between non-equal date objects")
-
- def today():
- """Return the current local time.
-
- This is equivalent to date.fromtimestamp(time.time())"""
-
- def fromtimestamp(timestamp):
- """Return the local date from a POSIX timestamp (like time.time())
-
- This may raise ValueError, if the timestamp is out of the range of
- values supported by the platform C localtime() function. It's common
- for this to be restricted to years from 1970 through 2038. Note that
- on non-POSIX systems that include leap seconds in their notion of a
- timestamp, leap seconds are ignored by fromtimestamp().
- """
-
- def fromordinal(ordinal):
- """Return the date corresponding to the proleptic Gregorian ordinal.
-
- January 1 of year 1 has ordinal 1. ValueError is raised unless
- 1 <= ordinal <= date.max.toordinal().
- For any date d, date.fromordinal(d.toordinal()) == d.
- """
-
-
-class IDate(IDateClass):
- """Represents a date (year, month and day) in an idealized calendar.
-
- Operators:
-
- __repr__, __str__
- __cmp__, __hash__
- __add__, __radd__, __sub__ (add/radd only with timedelta arg)
- """
-
- year = Attribute("Between MINYEAR and MAXYEAR inclusive.")
-
- month = Attribute("Between 1 and 12 inclusive")
-
- day = Attribute(
- "Between 1 and the number of days in the given month of the given year.")
-
- def replace(year, month, day):
- """Return a date with the same value.
-
- Except for those members given new values by whichever keyword
- arguments are specified. For example, if d == date(2002, 12, 31), then
- d.replace(day=26) == date(2000, 12, 26).
- """
-
- def timetuple():
- """Return a 9-element tuple of the form returned by time.localtime().
-
- The hours, minutes and seconds are 0, and the DST flag is -1.
- d.timetuple() is equivalent to
- (d.year, d.month, d.day, 0, 0, 0, d.weekday(), d.toordinal() -
- date(d.year, 1, 1).toordinal() + 1, -1)
- """
-
- def toordinal():
- """Return the proleptic Gregorian ordinal of the date
-
- January 1 of year 1 has ordinal 1. For any date object d,
- date.fromordinal(d.toordinal()) == d.
- """
-
- def weekday():
- """Return the day of the week as an integer.
-
- Monday is 0 and Sunday is 6. For example,
- date(2002, 12, 4).weekday() == 2, a Wednesday.
-
- See also isoweekday().
- """
-
- def isoweekday():
- """Return the day of the week as an integer.
-
- Monday is 1 and Sunday is 7. For example,
- date(2002, 12, 4).isoweekday() == 3, a Wednesday.
-
- See also weekday(), isocalendar().
- """
-
- def isocalendar():
- """Return a 3-tuple, (ISO year, ISO week number, ISO weekday).
-
- The ISO calendar is a widely used variant of the Gregorian calendar.
- See http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good
- explanation.
-
- The ISO year consists of 52 or 53 full weeks, and where a week starts
- on a Monday and ends on a Sunday. The first week of an ISO year is the
- first (Gregorian) calendar week of a year containing a Thursday. This
- is called week number 1, and the ISO year of that Thursday is the same
- as its Gregorian year.
-
- For example, 2004 begins on a Thursday, so the first week of ISO year
- 2004 begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004, so
- that date(2003, 12, 29).isocalendar() == (2004, 1, 1) and
- date(2004, 1, 4).isocalendar() == (2004, 1, 7).
- """
-
- def isoformat():
- """Return a string representing the date in ISO 8601 format.
-
- This is 'YYYY-MM-DD'.
- For example, date(2002, 12, 4).isoformat() == '2002-12-04'.
- """
-
- def __str__():
- """For a date d, str(d) is equivalent to d.isoformat()."""
-
- def ctime():
- """Return a string representing the date.
-
- For example date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002'.
- d.ctime() is equivalent to time.ctime(time.mktime(d.timetuple()))
- on platforms where the native C ctime() function
- (which time.ctime() invokes, but which date.ctime() does not invoke)
- conforms to the C standard.
- """
-
- def strftime(format):
- """Return a string representing the date.
-
- Controlled by an explicit format string. Format codes referring to
- hours, minutes or seconds will see 0 values.
- """
-
-
-class IDateTimeClass(Interface):
- """This is the datetime class interface."""
-
- min = Attribute("The earliest representable datetime")
-
- max = Attribute("The latest representable datetime")
-
- resolution = Attribute(
- "The smallest possible difference between non-equal datetime objects")
-
- def today():
- """Return the current local datetime, with tzinfo None.
-
- This is equivalent to datetime.fromtimestamp(time.time()).
- See also now(), fromtimestamp().
- """
-
- def now(tz=None):
- """Return the current local date and time.
-
- If optional argument tz is None or not specified, this is like today(),
- but, if possible, supplies more precision than can be gotten from going
- through a time.time() timestamp (for example, this may be possible on
- platforms supplying the C gettimeofday() function).
-
- Else tz must be an instance of a class tzinfo subclass, and the current
- date and time are converted to tz's time zone. In this case the result
- is equivalent to tz.fromutc(datetime.utcnow().replace(tzinfo=tz)).
-
- See also today(), utcnow().
- """
-
- def utcnow():
- """Return the current UTC date and time, with tzinfo None.
-
- This is like now(), but returns the current UTC date and time, as a
- naive datetime object.
-
- See also now().
- """
-
- def fromtimestamp(timestamp, tz=None):
- """Return the local date and time corresponding to the POSIX timestamp.
-
- Same as is returned by time.time(). If optional argument tz is None or
- not specified, the timestamp is converted to the platform's local date
- and time, and the returned datetime object is naive.
-
- Else tz must be an instance of a class tzinfo subclass, and the
- timestamp is converted to tz's time zone. In this case the result is
- equivalent to
- tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz)).
-
- fromtimestamp() may raise ValueError, if the timestamp is out of the
- range of values supported by the platform C localtime() or gmtime()
- functions. It's common for this to be restricted to years in 1970
- through 2038. Note that on non-POSIX systems that include leap seconds
- in their notion of a timestamp, leap seconds are ignored by
- fromtimestamp(), and then it's possible to have two timestamps
- differing by a second that yield identical datetime objects.
-
- See also utcfromtimestamp().
- """
-
- def utcfromtimestamp(timestamp):
- """Return the UTC datetime from the POSIX timestamp with tzinfo None.
-
- This may raise ValueError, if the timestamp is out of the range of
- values supported by the platform C gmtime() function. It's common for
- this to be restricted to years in 1970 through 2038.
-
- See also fromtimestamp().
- """
-
- def fromordinal(ordinal):
- """Return the datetime from the proleptic Gregorian ordinal.
-
- January 1 of year 1 has ordinal 1. ValueError is raised unless
- 1 <= ordinal <= datetime.max.toordinal().
- The hour, minute, second and microsecond of the result are all 0, and
- tzinfo is None.
- """
-
- def combine(date, time):
- """Return a new datetime object.
-
- Its date members are equal to the given date object's, and whose time
- and tzinfo members are equal to the given time object's. For any
- datetime object d, d == datetime.combine(d.date(), d.timetz()).
- If date is a datetime object, its time and tzinfo members are ignored.
- """
-
-
-class IDateTime(IDate, IDateTimeClass):
- """Object contains all the information from a date object and a time object.
- """
-
- year = Attribute("Year between MINYEAR and MAXYEAR inclusive")
-
- month = Attribute("Month between 1 and 12 inclusive")
-
- day = Attribute(
- "Day between 1 and the number of days in the given month of the year")
-
- hour = Attribute("Hour in range(24)")
-
- minute = Attribute("Minute in range(60)")
-
- second = Attribute("Second in range(60)")
-
- microsecond = Attribute("Microsecond in range(1000000)")
-
- tzinfo = Attribute(
- """The object passed as the tzinfo argument to the datetime constructor
- or None if none was passed""")
-
- def date():
- """Return date object with same year, month and day."""
-
- def time():
- """Return time object with same hour, minute, second, microsecond.
-
- tzinfo is None. See also method timetz().
- """
-
- def timetz():
- """Return time object with same hour, minute, second, microsecond,
- and tzinfo.
-
- See also method time().
- """
-
- def replace(year, month, day, hour, minute, second, microsecond, tzinfo):
- """Return a datetime with the same members, except for those members
- given new values by whichever keyword arguments are specified.
-
- Note that tzinfo=None can be specified to create a naive datetime from
- an aware datetime with no conversion of date and time members.
- """
-
- def astimezone(tz):
- """Return a datetime object with new tzinfo member tz, adjusting the
- date and time members so the result is the same UTC time as self, but
- in tz's local time.
-
- tz must be an instance of a tzinfo subclass, and its utcoffset() and
- dst() methods must not return None. self must be aware (self.tzinfo
- must not be None, and self.utcoffset() must not return None).
-
- If self.tzinfo is tz, self.astimezone(tz) is equal to self: no
- adjustment of date or time members is performed. Else the result is
- local time in time zone tz, representing the same UTC time as self:
- after astz = dt.astimezone(tz), astz - astz.utcoffset()
- will usually have the same date and time members as dt - dt.utcoffset().
- The discussion of class tzinfo explains the cases at Daylight Saving
- Time transition boundaries where this cannot be achieved (an issue only
- if tz models both standard and daylight time).
-
- If you merely want to attach a time zone object tz to a datetime dt
- without adjustment of date and time members, use dt.replace(tzinfo=tz).
- If you merely want to remove the time zone object from an aware
- datetime dt without conversion of date and time members, use
- dt.replace(tzinfo=None).
-
- Note that the default tzinfo.fromutc() method can be overridden in a
- tzinfo subclass to effect the result returned by astimezone().
- """
-
- def utcoffset():
- """Return the timezone offset in minutes east of UTC (negative west of
- UTC)."""
-
- def dst():
- """Return 0 if DST is not in effect, or the DST offset (in minutes
- eastward) if DST is in effect.
- """
-
- def tzname():
- """Return the timezone name."""
-
- def timetuple():
- """Return a 9-element tuple of the form returned by time.localtime()."""
-
- def utctimetuple():
- """Return UTC time tuple compatilble with time.gmtimr()."""
-
- def toordinal():
- """Return the proleptic Gregorian ordinal of the date.
-
- The same as self.date().toordinal().
- """
-
- def weekday():
- """Return the day of the week as an integer.
-
- Monday is 0 and Sunday is 6. The same as self.date().weekday().
- See also isoweekday().
- """
-
- def isoweekday():
- """Return the day of the week as an integer.
-
- Monday is 1 and Sunday is 7. The same as self.date().isoweekday.
- See also weekday(), isocalendar().
- """
-
- def isocalendar():
- """Return a 3-tuple, (ISO year, ISO week number, ISO weekday).
-
- The same as self.date().isocalendar().
- """
-
- def isoformat(sep='T'):
- """Return a string representing the date and time in ISO 8601 format.
-
- YYYY-MM-DDTHH:MM:SS.mmmmmm or YYYY-MM-DDTHH:MM:SS if microsecond is 0
-
- If utcoffset() does not return None, a 6-character string is appended,
- giving the UTC offset in (signed) hours and minutes:
-
- YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or YYYY-MM-DDTHH:MM:SS+HH:MM
- if microsecond is 0.
-
- The optional argument sep (default 'T') is a one-character separator,
- placed between the date and time portions of the result.
- """
-
- def __str__():
- """For a datetime instance d, str(d) is equivalent to d.isoformat(' ').
- """
-
- def ctime():
- """Return a string representing the date and time.
-
- datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'.
- d.ctime() is equivalent to time.ctime(time.mktime(d.timetuple())) on
- platforms where the native C ctime() function (which time.ctime()
- invokes, but which datetime.ctime() does not invoke) conforms to the
- C standard.
- """
-
- def strftime(format):
- """Return a string representing the date and time.
-
- This is controlled by an explicit format string.
- """
-
-
-class ITimeClass(Interface):
- """This is the time class interface."""
-
- min = Attribute("The earliest representable time")
-
- max = Attribute("The latest representable time")
-
- resolution = Attribute(
- "The smallest possible difference between non-equal time objects")
-
-
-class ITime(ITimeClass):
- """Represent time with time zone.
-
- Operators:
-
- __repr__, __str__
- __cmp__, __hash__
- """
-
- hour = Attribute("Hour in range(24)")
-
- minute = Attribute("Minute in range(60)")
-
- second = Attribute("Second in range(60)")
-
- microsecond = Attribute("Microsecond in range(1000000)")
-
- tzinfo = Attribute(
- """The object passed as the tzinfo argument to the time constructor
- or None if none was passed.""")
-
- def replace(hour, minute, second, microsecond, tzinfo):
- """Return a time with the same value.
-
- Except for those members given new values by whichever keyword
- arguments are specified. Note that tzinfo=None can be specified
- to create a naive time from an aware time, without conversion of the
- time members.
- """
-
- def isoformat():
- """Return a string representing the time in ISO 8601 format.
-
- That is HH:MM:SS.mmmmmm or, if self.microsecond is 0, HH:MM:SS
- If utcoffset() does not return None, a 6-character string is appended,
- giving the UTC offset in (signed) hours and minutes:
- HH:MM:SS.mmmmmm+HH:MM or, if self.microsecond is 0, HH:MM:SS+HH:MM
- """
-
- def __str__():
- """For a time t, str(t) is equivalent to t.isoformat()."""
-
- def strftime(format):
- """Return a string representing the time.
-
- This is controlled by an explicit format string.
- """
-
- def utcoffset():
- """Return the timezone offset in minutes east of UTC (negative west of
- UTC).
-
- If tzinfo is None, returns None, else returns
- self.tzinfo.utcoffset(None), and raises an exception if the latter
- doesn't return None or a timedelta object representing a whole number
- of minutes with magnitude less than one day.
- """
-
- def dst():
- """Return 0 if DST is not in effect, or the DST offset (in minutes
- eastward) if DST is in effect.
-
- If tzinfo is None, returns None, else returns self.tzinfo.dst(None),
- and raises an exception if the latter doesn't return None, or a
- timedelta object representing a whole number of minutes with
- magnitude less than one day.
- """
-
- def tzname():
- """Return the timezone name.
-
- If tzinfo is None, returns None, else returns self.tzinfo.tzname(None),
- or raises an exception if the latter doesn't return None or a string
- object.
- """
-
-
-class ITZInfo(Interface):
- """Time zone info class.
- """
-
- def utcoffset(dt):
- """Return offset of local time from UTC, in minutes east of UTC.
-
- If local time is west of UTC, this should be negative.
- Note that this is intended to be the total offset from UTC;
- for example, if a tzinfo object represents both time zone and DST
- adjustments, utcoffset() should return their sum. If the UTC offset
- isn't known, return None. Else the value returned must be a timedelta
- object specifying a whole number of minutes in the range -1439 to 1439
- inclusive (1440 = 24*60; the magnitude of the offset must be less
- than one day).
- """
-
- def dst(dt):
- """Return the daylight saving time (DST) adjustment, in minutes east
- of UTC, or None if DST information isn't known.
- """
-
- def tzname(dt):
- """Return the time zone name corresponding to the datetime object as
- a string.
- """
-
- def fromutc(dt):
- """Return an equivalent datetime in self's local time."""
-
-
-classImplements(timedelta, ITimeDelta)
-classImplements(date, IDate)
-classImplements(datetime, IDateTime)
-classImplements(time, ITime)
-classImplements(tzinfo, ITZInfo)
-
-## directlyProvides(timedelta, ITimeDeltaClass)
-## directlyProvides(date, IDateClass)
-## directlyProvides(datetime, IDateTimeClass)
-## directlyProvides(time, ITimeClass)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/interfaces.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/interfaces.py
deleted file mode 100644
index 47e9de7a..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/interfaces.py
+++ /dev/null
@@ -1,102 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interfaces for standard python exceptions
-"""
-from zope.interface import Interface
-from zope.interface import classImplements
-
-class IException(Interface): pass
-class IStandardError(IException): pass
-class IWarning(IException): pass
-class ISyntaxError(IStandardError): pass
-class ILookupError(IStandardError): pass
-class IValueError(IStandardError): pass
-class IRuntimeError(IStandardError): pass
-class IArithmeticError(IStandardError): pass
-class IAssertionError(IStandardError): pass
-class IAttributeError(IStandardError): pass
-class IDeprecationWarning(IWarning): pass
-class IEOFError(IStandardError): pass
-class IEnvironmentError(IStandardError): pass
-class IFloatingPointError(IArithmeticError): pass
-class IIOError(IEnvironmentError): pass
-class IImportError(IStandardError): pass
-class IIndentationError(ISyntaxError): pass
-class IIndexError(ILookupError): pass
-class IKeyError(ILookupError): pass
-class IKeyboardInterrupt(IStandardError): pass
-class IMemoryError(IStandardError): pass
-class INameError(IStandardError): pass
-class INotImplementedError(IRuntimeError): pass
-class IOSError(IEnvironmentError): pass
-class IOverflowError(IArithmeticError): pass
-class IOverflowWarning(IWarning): pass
-class IReferenceError(IStandardError): pass
-class IRuntimeWarning(IWarning): pass
-class IStopIteration(IException): pass
-class ISyntaxWarning(IWarning): pass
-class ISystemError(IStandardError): pass
-class ISystemExit(IException): pass
-class ITabError(IIndentationError): pass
-class ITypeError(IStandardError): pass
-class IUnboundLocalError(INameError): pass
-class IUnicodeError(IValueError): pass
-class IUserWarning(IWarning): pass
-class IZeroDivisionError(IArithmeticError): pass
-
-classImplements(ArithmeticError, IArithmeticError)
-classImplements(AssertionError, IAssertionError)
-classImplements(AttributeError, IAttributeError)
-classImplements(DeprecationWarning, IDeprecationWarning)
-classImplements(EnvironmentError, IEnvironmentError)
-classImplements(EOFError, IEOFError)
-classImplements(Exception, IException)
-classImplements(FloatingPointError, IFloatingPointError)
-classImplements(ImportError, IImportError)
-classImplements(IndentationError, IIndentationError)
-classImplements(IndexError, IIndexError)
-classImplements(IOError, IIOError)
-classImplements(KeyboardInterrupt, IKeyboardInterrupt)
-classImplements(KeyError, IKeyError)
-classImplements(LookupError, ILookupError)
-classImplements(MemoryError, IMemoryError)
-classImplements(NameError, INameError)
-classImplements(NotImplementedError, INotImplementedError)
-classImplements(OSError, IOSError)
-classImplements(OverflowError, IOverflowError)
-try:
- classImplements(OverflowWarning, IOverflowWarning)
-except NameError:
- pass # OverflowWarning was removed in Python 2.5
-classImplements(ReferenceError, IReferenceError)
-classImplements(RuntimeError, IRuntimeError)
-classImplements(RuntimeWarning, IRuntimeWarning)
-try:
- classImplements(StandardError, IStandardError)
-except NameError:
- pass # StandardError does not exist in Python 3
-classImplements(StopIteration, IStopIteration)
-classImplements(SyntaxError, ISyntaxError)
-classImplements(SyntaxWarning, ISyntaxWarning)
-classImplements(SystemError, ISystemError)
-classImplements(SystemExit, ISystemExit)
-classImplements(TabError, ITabError)
-classImplements(TypeError, ITypeError)
-classImplements(UnboundLocalError, IUnboundLocalError)
-classImplements(UnicodeError, IUnicodeError)
-classImplements(UserWarning, IUserWarning)
-classImplements(ValueError, IValueError)
-classImplements(Warning, IWarning)
-classImplements(ZeroDivisionError, IZeroDivisionError)
-
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/mapping.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/mapping.py
deleted file mode 100644
index 139715f2..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/mapping.py
+++ /dev/null
@@ -1,125 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Mapping Interfaces
-"""
-from zope.interface import Interface
-
-class IItemMapping(Interface):
- """Simplest readable mapping object
- """
-
- def __getitem__(key):
- """Get a value for a key
-
- A KeyError is raised if there is no value for the key.
- """
-
-
-class IReadMapping(IItemMapping):
- """Basic mapping interface
- """
-
- def get(key, default=None):
- """Get a value for a key
-
- The default is returned if there is no value for the key.
- """
-
- def __contains__(key):
- """Tell if a key exists in the mapping."""
-
-
-class IWriteMapping(Interface):
- """Mapping methods for changing data"""
-
- def __delitem__(key):
- """Delete a value from the mapping using the key."""
-
- def __setitem__(key, value):
- """Set a new item in the mapping."""
-
-
-class IEnumerableMapping(IReadMapping):
- """Mapping objects whose items can be enumerated.
- """
-
- def keys():
- """Return the keys of the mapping object.
- """
-
- def __iter__():
- """Return an iterator for the keys of the mapping object.
- """
-
- def values():
- """Return the values of the mapping object.
- """
-
- def items():
- """Return the items of the mapping object.
- """
-
- def __len__():
- """Return the number of items.
- """
-
-class IMapping(IWriteMapping, IEnumerableMapping):
- ''' Simple mapping interface '''
-
-class IIterableMapping(IEnumerableMapping):
-
- def iterkeys():
- "iterate over keys; equivalent to __iter__"
-
- def itervalues():
- "iterate over values"
-
- def iteritems():
- "iterate over items"
-
-class IClonableMapping(Interface):
-
- def copy():
- "return copy of dict"
-
-class IExtendedReadMapping(IIterableMapping):
-
- def has_key(key):
- """Tell if a key exists in the mapping; equivalent to __contains__"""
-
-class IExtendedWriteMapping(IWriteMapping):
-
- def clear():
- "delete all items"
-
- def update(d):
- " Update D from E: for k in E.keys(): D[k] = E[k]"
-
- def setdefault(key, default=None):
- "D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"
-
- def pop(k, *args):
- """remove specified key and return the corresponding value
- *args may contain a single default value, or may not be supplied.
- If key is not found, default is returned if given, otherwise
- KeyError is raised"""
-
- def popitem():
- """remove and return some (key, value) pair as a
- 2-tuple; but raise KeyError if mapping is empty"""
-
-class IFullMapping(
- IExtendedReadMapping, IExtendedWriteMapping, IClonableMapping, IMapping):
- ''' Full mapping interface ''' # IMapping included so tests for IMapping
- # succeed with IFullMapping
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/sequence.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/sequence.py
deleted file mode 100644
index 223a94eb..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/sequence.py
+++ /dev/null
@@ -1,160 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Sequence Interfaces
-"""
-__docformat__ = 'restructuredtext'
-from zope import interface
-
-class IMinimalSequence(interface.Interface):
- """Most basic sequence interface.
-
- All sequences are iterable. This requires at least one of the
- following:
-
- - a `__getitem__()` method that takes a single argument; interger
- values starting at 0 must be supported, and `IndexError` should
- be raised for the first index for which there is no value, or
-
- - an `__iter__()` method that returns an iterator as defined in
- the Python documentation (http://docs.python.org/lib/typeiter.html).
-
- """
-
- def __getitem__(index):
- """`x.__getitem__(index)` <==> `x[index]`
-
- Declaring this interface does not specify whether `__getitem__`
- supports slice objects."""
-
-class IFiniteSequence(IMinimalSequence):
-
- def __len__():
- """`x.__len__()` <==> `len(x)`"""
-
-class IReadSequence(IFiniteSequence):
- """read interface shared by tuple and list"""
-
- def __contains__(item):
- """`x.__contains__(item)` <==> `item in x`"""
-
- def __lt__(other):
- """`x.__lt__(other)` <==> `x < other`"""
-
- def __le__(other):
- """`x.__le__(other)` <==> `x <= other`"""
-
- def __eq__(other):
- """`x.__eq__(other)` <==> `x == other`"""
-
- def __ne__(other):
- """`x.__ne__(other)` <==> `x != other`"""
-
- def __gt__(other):
- """`x.__gt__(other)` <==> `x > other`"""
-
- def __ge__(other):
- """`x.__ge__(other)` <==> `x >= other`"""
-
- def __add__(other):
- """`x.__add__(other)` <==> `x + other`"""
-
- def __mul__(n):
- """`x.__mul__(n)` <==> `x * n`"""
-
- def __rmul__(n):
- """`x.__rmul__(n)` <==> `n * x`"""
-
- def __getslice__(i, j):
- """`x.__getslice__(i, j)` <==> `x[i:j]`
-
- Use of negative indices is not supported.
-
- Deprecated since Python 2.0 but still a part of `UserList`.
- """
-
-class IExtendedReadSequence(IReadSequence):
- """Full read interface for lists"""
-
- def count(item):
- """Return number of occurrences of value"""
-
- def index(item, *args):
- """Return first index of value
-
- `L.index(value, [start, [stop]])` -> integer"""
-
-class IUniqueMemberWriteSequence(interface.Interface):
- """The write contract for a sequence that may enforce unique members"""
-
- def __setitem__(index, item):
- """`x.__setitem__(index, item)` <==> `x[index] = item`
-
- Declaring this interface does not specify whether `__setitem__`
- supports slice objects.
- """
-
- def __delitem__(index):
- """`x.__delitem__(index)` <==> `del x[index]`
-
- Declaring this interface does not specify whether `__delitem__`
- supports slice objects.
- """
-
- def __setslice__(i, j, other):
- """`x.__setslice__(i, j, other)` <==> `x[i:j]=other`
-
- Use of negative indices is not supported.
-
- Deprecated since Python 2.0 but still a part of `UserList`.
- """
-
- def __delslice__(i, j):
- """`x.__delslice__(i, j)` <==> `del x[i:j]`
-
- Use of negative indices is not supported.
-
- Deprecated since Python 2.0 but still a part of `UserList`.
- """
- def __iadd__(y):
- """`x.__iadd__(y)` <==> `x += y`"""
-
- def append(item):
- """Append item to end"""
-
- def insert(index, item):
- """Insert item before index"""
-
- def pop(index=-1):
- """Remove and return item at index (default last)"""
-
- def remove(item):
- """Remove first occurrence of value"""
-
- def reverse():
- """Reverse *IN PLACE*"""
-
- def sort(cmpfunc=None):
- """Stable sort *IN PLACE*; `cmpfunc(x, y)` -> -1, 0, 1"""
-
- def extend(iterable):
- """Extend list by appending elements from the iterable"""
-
-class IWriteSequence(IUniqueMemberWriteSequence):
- """Full write contract for sequences"""
-
- def __imul__(n):
- """`x.__imul__(n)` <==> `x *= n`"""
-
-class ISequence(IReadSequence, IWriteSequence):
- """Full sequence contract"""
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/__init__.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/__init__.py
deleted file mode 100644
index b711d360..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-#
-# This file is necessary to make this directory a package.
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/basemapping.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/basemapping.py
deleted file mode 100644
index 66f0ee43..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/basemapping.py
+++ /dev/null
@@ -1,107 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Base Mapping tests
-"""
-from operator import __getitem__
-
-def testIReadMapping(self, inst, state, absent):
- for key in state:
- self.assertEqual(inst[key], state[key])
- self.assertEqual(inst.get(key, None), state[key])
- self.failUnless(key in inst)
-
- for key in absent:
- self.assertEqual(inst.get(key, None), None)
- self.assertEqual(inst.get(key), None)
- self.assertEqual(inst.get(key, self), self)
- self.assertRaises(KeyError, __getitem__, inst, key)
-
-
-def test_keys(self, inst, state):
- # Return the keys of the mapping object
- inst_keys = list(inst.keys()); inst_keys.sort()
- state_keys = list(state.keys()) ; state_keys.sort()
- self.assertEqual(inst_keys, state_keys)
-
-def test_iter(self, inst, state):
- # Return the keys of the mapping object
- inst_keys = list(inst); inst_keys.sort()
- state_keys = list(state.keys()) ; state_keys.sort()
- self.assertEqual(inst_keys, state_keys)
-
-def test_values(self, inst, state):
- # Return the values of the mapping object
- inst_values = list(inst.values()); inst_values.sort()
- state_values = list(state.values()) ; state_values.sort()
- self.assertEqual(inst_values, state_values)
-
-def test_items(self, inst, state):
- # Return the items of the mapping object
- inst_items = list(inst.items()); inst_items.sort()
- state_items = list(state.items()) ; state_items.sort()
- self.assertEqual(inst_items, state_items)
-
-def test___len__(self, inst, state):
- # Return the number of items
- self.assertEqual(len(inst), len(state))
-
-def testIEnumerableMapping(self, inst, state):
- test_keys(self, inst, state)
- test_items(self, inst, state)
- test_values(self, inst, state)
- test___len__(self, inst, state)
-
-
-class BaseTestIReadMapping(object):
- def testIReadMapping(self):
- inst = self._IReadMapping__sample()
- state = self._IReadMapping__stateDict()
- absent = self._IReadMapping__absentKeys()
- testIReadMapping(self, inst, state, absent)
-
-
-class BaseTestIEnumerableMapping(BaseTestIReadMapping):
- # Mapping objects whose items can be enumerated
- def test_keys(self):
- # Return the keys of the mapping object
- inst = self._IEnumerableMapping__sample()
- state = self._IEnumerableMapping__stateDict()
- test_keys(self, inst, state)
-
- def test_values(self):
- # Return the values of the mapping object
- inst = self._IEnumerableMapping__sample()
- state = self._IEnumerableMapping__stateDict()
- test_values(self, inst, state)
-
- def test_items(self):
- # Return the items of the mapping object
- inst = self._IEnumerableMapping__sample()
- state = self._IEnumerableMapping__stateDict()
- test_items(self, inst, state)
-
- def test___len__(self):
- # Return the number of items
- inst = self._IEnumerableMapping__sample()
- state = self._IEnumerableMapping__stateDict()
- test___len__(self, inst, state)
-
- def _IReadMapping__stateDict(self):
- return self._IEnumerableMapping__stateDict()
-
- def _IReadMapping__sample(self):
- return self._IEnumerableMapping__sample()
-
- def _IReadMapping__absentKeys(self):
- return self._IEnumerableMapping__absentKeys()
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_idatetime.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_idatetime.py
deleted file mode 100644
index 60f377ea..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_idatetime.py
+++ /dev/null
@@ -1,47 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test for datetime interfaces
-"""
-
-import unittest
-
-from zope.interface.verify import verifyObject, verifyClass
-from zope.interface.common.idatetime import ITimeDelta, ITimeDeltaClass
-from zope.interface.common.idatetime import IDate, IDateClass
-from zope.interface.common.idatetime import IDateTime, IDateTimeClass
-from zope.interface.common.idatetime import ITime, ITimeClass, ITZInfo
-from datetime import timedelta, date, datetime, time, tzinfo
-
-class TestDateTimeInterfaces(unittest.TestCase):
-
- def test_interfaces(self):
- verifyObject(ITimeDelta, timedelta(minutes=20))
- verifyObject(IDate, date(2000, 1, 2))
- verifyObject(IDateTime, datetime(2000, 1, 2, 10, 20))
- verifyObject(ITime, time(20, 30, 15, 1234))
- verifyObject(ITZInfo, tzinfo())
- verifyClass(ITimeDeltaClass, timedelta)
- verifyClass(IDateClass, date)
- verifyClass(IDateTimeClass, datetime)
- verifyClass(ITimeClass, time)
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestDateTimeInterfaces))
- return suite
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_import_interfaces.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_import_interfaces.py
deleted file mode 100644
index 1473a533..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/common/tests/test_import_interfaces.py
+++ /dev/null
@@ -1,29 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-import doctest
-import unittest
-
-def test_interface_import():
- """
- >>> import zope.interface.common.interfaces
- """
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocTestSuite(),
- ))
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
-
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/declarations.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/declarations.py
deleted file mode 100644
index 3ee27c41..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/declarations.py
+++ /dev/null
@@ -1,1395 +0,0 @@
-##############################################################################
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-##############################################################################
-"""Implementation of interface declarations
-
-There are three flavors of declarations:
-
- - Declarations are used to simply name declared interfaces.
-
- - ImplementsDeclarations are used to express the interfaces that a
- class implements (that instances of the class provides).
-
- Implements specifications support inheriting interfaces.
-
- - ProvidesDeclarations are used to express interfaces directly
- provided by objects.
-
-"""
-__docformat__ = 'restructuredtext'
-
-import sys
-import weakref
-from zope.interface.interface import InterfaceClass, Specification
-from zope.interface.interface import SpecificationBase
-from types import ModuleType, MethodType, FunctionType
-from zope.interface.advice import addClassAdvisor
-
-# Registry of class-implementation specifications
-BuiltinImplementationSpecifications = {}
-
-class Declaration(Specification):
- """Interface declarations"""
-
- def __init__(self, *interfaces):
- Specification.__init__(self, _normalizeargs(interfaces))
-
- def changed(self, originally_changed):
- Specification.changed(self, originally_changed)
- try:
- del self._v_attrs
- except AttributeError:
- pass
-
- def __contains__(self, interface):
- """Test whether an interface is in the specification
-
- for example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration(I2, I3)
- >>> spec = Declaration(I4, spec)
- >>> int(I1 in spec)
- 0
- >>> int(I2 in spec)
- 1
- >>> int(I3 in spec)
- 1
- >>> int(I4 in spec)
- 1
- """
- return self.extends(interface) and interface in self.interfaces()
-
- def __iter__(self):
- """Return an iterator for the interfaces in the specification
-
- for example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration(I2, I3)
- >>> spec = Declaration(I4, spec)
- >>> i = iter(spec)
- >>> [x.getName() for x in i]
- ['I4', 'I2', 'I3']
- >>> list(i)
- []
- """
- return self.interfaces()
-
- def flattened(self):
- """Return an iterator of all included and extended interfaces
-
- for example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration(I2, I3)
- >>> spec = Declaration(I4, spec)
- >>> i = spec.flattened()
- >>> [x.getName() for x in i]
- ['I4', 'I2', 'I1', 'I3', 'Interface']
- >>> list(i)
- []
-
- """
- return iter(self.__iro__)
-
- def __sub__(self, other):
- """Remove interfaces from a specification
-
- Examples:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration()
- >>> [iface.getName() for iface in spec]
- []
- >>> spec -= I1
- >>> [iface.getName() for iface in spec]
- []
- >>> spec -= Declaration(I1, I2)
- >>> [iface.getName() for iface in spec]
- []
- >>> spec = Declaration(I2, I4)
- >>> [iface.getName() for iface in spec]
- ['I2', 'I4']
- >>> [iface.getName() for iface in spec - I4]
- ['I2']
- >>> [iface.getName() for iface in spec - I1]
- ['I4']
- >>> [iface.getName() for iface
- ... in spec - Declaration(I3, I4)]
- ['I2']
-
- """
-
- return Declaration(
- *[i for i in self.interfaces()
- if not [j for j in other.interfaces()
- if i.extends(j, 0)]
- ]
- )
-
- def __add__(self, other):
- """Add two specifications or a specification and an interface
-
- Examples:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration()
- >>> [iface.getName() for iface in spec]
- []
- >>> [iface.getName() for iface in spec+I1]
- ['I1']
- >>> [iface.getName() for iface in I1+spec]
- ['I1']
- >>> spec2 = spec
- >>> spec += I1
- >>> [iface.getName() for iface in spec]
- ['I1']
- >>> [iface.getName() for iface in spec2]
- []
- >>> spec2 += Declaration(I3, I4)
- >>> [iface.getName() for iface in spec2]
- ['I3', 'I4']
- >>> [iface.getName() for iface in spec+spec2]
- ['I1', 'I3', 'I4']
- >>> [iface.getName() for iface in spec2+spec]
- ['I3', 'I4', 'I1']
-
- """
-
- seen = {}
- result = []
- for i in self.interfaces():
- if i not in seen:
- seen[i] = 1
- result.append(i)
- for i in other.interfaces():
- if i not in seen:
- seen[i] = 1
- result.append(i)
-
- return Declaration(*result)
-
- __radd__ = __add__
-
-
-##############################################################################
-#
-# Implementation specifications
-#
-# These specify interfaces implemented by instances of classes
-
-class Implements(Declaration):
-
- # class whose specification should be used as additional base
- inherit = None
-
- # interfaces actually declared for a class
- declared = ()
-
- __name__ = '?'
-
- def __repr__(self):
- return '<implementedBy %s>' % (self.__name__)
-
- def __reduce__(self):
- return implementedBy, (self.inherit, )
-
-def implementedByFallback(cls):
- """Return the interfaces implemented for a class' instances
-
- The value returned is an IDeclaration.
-
- for example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> class C1(object):
- ... implements(I2)
- >>> class C2(C1):
- ... implements(I3)
- >>> [i.getName() for i in implementedBy(C2)]
- ['I3', 'I2']
-
- Really, any object should be able to receive a successful answer, even
- an instance:
-
- >>> class Callable(object):
- ... def __call__(self):
- ... return self
-
- >>> implementedBy(Callable())
- <implementedBy zope.interface.declarations.?>
-
- Note that the name of the spec ends with a '?', because the `Callable`
- instance does not have a `__name__` attribute.
- """
- # This also manages storage of implementation specifications
-
- try:
- spec = cls.__dict__.get('__implemented__')
- except AttributeError:
-
- # we can't get the class dict. This is probably due to a
- # security proxy. If this is the case, then probably no
- # descriptor was installed for the class.
-
- # We don't want to depend directly on zope.security in
- # zope.interface, but we'll try to make reasonable
- # accommodations in an indirect way.
-
- # We'll check to see if there's an implements:
-
- spec = getattr(cls, '__implemented__', None)
- if spec is None:
- # There's no spec stred in the class. Maybe its a builtin:
- spec = BuiltinImplementationSpecifications.get(cls)
- if spec is not None:
- return spec
- return _empty
-
- if spec.__class__ == Implements:
- # we defaulted to _empty or there was a spec. Good enough.
- # Return it.
- return spec
-
- # TODO: need old style __implements__ compatibility?
- # Hm, there's an __implemented__, but it's not a spec. Must be
- # an old-style declaration. Just compute a spec for it
- return Declaration(*_normalizeargs((spec, )))
-
- if isinstance(spec, Implements):
- return spec
-
- if spec is None:
- spec = BuiltinImplementationSpecifications.get(cls)
- if spec is not None:
- return spec
-
- # TODO: need old style __implements__ compatibility?
- if spec is not None:
- # old-style __implemented__ = foo declaration
- spec = (spec, ) # tuplefy, as it might be just an int
- spec = Implements(*_normalizeargs(spec))
- spec.inherit = None # old-style implies no inherit
- del cls.__implemented__ # get rid of the old-style declaration
- else:
- try:
- bases = cls.__bases__
- except AttributeError:
- if not callable(cls):
- raise TypeError("ImplementedBy called for non-factory", cls)
- bases = ()
-
- spec = Implements(*[implementedBy(c) for c in bases])
- spec.inherit = cls
-
- spec.__name__ = (getattr(cls, '__module__', '?') or '?') + \
- '.' + (getattr(cls, '__name__', '?') or '?')
-
- try:
- cls.__implemented__ = spec
- if not hasattr(cls, '__providedBy__'):
- cls.__providedBy__ = objectSpecificationDescriptor
-
- if (isinstance(cls, DescriptorAwareMetaClasses)
- and
- '__provides__' not in cls.__dict__):
- # Make sure we get a __provides__ descriptor
- cls.__provides__ = ClassProvides(
- cls,
- getattr(cls, '__class__', type(cls)),
- )
-
- except TypeError:
- if not isinstance(cls, type):
- raise TypeError("ImplementedBy called for non-type", cls)
- BuiltinImplementationSpecifications[cls] = spec
-
- return spec
-
-implementedBy = implementedByFallback
-
-def classImplementsOnly(cls, *interfaces):
- """Declare the only interfaces implemented by instances of a class
-
- The arguments after the class are one or more interfaces or interface
- specifications (``IDeclaration`` objects).
-
- The interfaces given (including the interfaces in the specifications)
- replace any previous declarations.
-
- Consider the following example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(Interface): pass
- ...
- >>> class A(object):
- ... implements(I3)
- >>> class B(object):
- ... implements(I4)
- >>> class C(A, B):
- ... pass
- >>> classImplementsOnly(C, I1, I2)
- >>> [i.getName() for i in implementedBy(C)]
- ['I1', 'I2']
-
- Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
- whatever interfaces instances of ``A`` and ``B`` implement.
- """
- spec = implementedBy(cls)
- spec.declared = ()
- spec.inherit = None
- classImplements(cls, *interfaces)
-
-def classImplements(cls, *interfaces):
- """Declare additional interfaces implemented for instances of a class
-
- The arguments after the class are one or more interfaces or
- interface specifications (``IDeclaration`` objects).
-
- The interfaces given (including the interfaces in the specifications)
- are added to any interfaces previously declared.
-
- Consider the following example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(Interface): pass
- ...
- >>> class I5(Interface): pass
- ...
- >>> class A(object):
- ... implements(I3)
- >>> class B(object):
- ... implements(I4)
- >>> class C(A, B):
- ... pass
- >>> classImplements(C, I1, I2)
- >>> [i.getName() for i in implementedBy(C)]
- ['I1', 'I2', 'I3', 'I4']
- >>> classImplements(C, I5)
- >>> [i.getName() for i in implementedBy(C)]
- ['I1', 'I2', 'I5', 'I3', 'I4']
-
- Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever
- interfaces instances of ``A`` and ``B`` provide.
- """
-
- spec = implementedBy(cls)
- spec.declared += tuple(_normalizeargs(interfaces))
-
- # compute the bases
- bases = []
- seen = {}
- for b in spec.declared:
- if b not in seen:
- seen[b] = 1
- bases.append(b)
-
- if spec.inherit is not None:
-
- for c in spec.inherit.__bases__:
- b = implementedBy(c)
- if b not in seen:
- seen[b] = 1
- bases.append(b)
-
- spec.__bases__ = tuple(bases)
-
-def _implements_advice(cls):
- interfaces, classImplements = cls.__dict__['__implements_advice_data__']
- del cls.__implements_advice_data__
- classImplements(cls, *interfaces)
- return cls
-
-
-class implementer:
-
- def __init__(self, *interfaces):
- self.interfaces = interfaces
-
- def __call__(self, ob):
- if isinstance(ob, DescriptorAwareMetaClasses):
- classImplements(ob, *self.interfaces)
- return ob
-
- spec = Implements(*self.interfaces)
- try:
- ob.__implemented__ = spec
- except AttributeError:
- raise TypeError("Can't declare implements", ob)
- return ob
-
-class implementer_only:
-
- def __init__(self, *interfaces):
- self.interfaces = interfaces
-
- def __call__(self, ob):
- if isinstance(ob, (FunctionType, MethodType)):
- # XXX Does this decorator make sense for anything but classes?
- # I don't think so. There can be no inheritance of interfaces
- # on a method pr function....
- raise ValueError('The implementor_only decorator is not '
- 'supported for methods or functions.')
- else:
- # Assume it's a class:
- classImplementsOnly(ob, *self.interfaces)
- return ob
-
-def _implements(name, interfaces, classImplements):
- frame = sys._getframe(2)
- locals = frame.f_locals
-
- # Try to make sure we were called from a class def. In 2.2.0 we can't
- # check for __module__ since it doesn't seem to be added to the locals
- # until later on.
- if (locals is frame.f_globals) or (
- ('__module__' not in locals) and sys.version_info[:3] > (2, 2, 0)):
- raise TypeError(name+" can be used only from a class definition.")
-
- if '__implements_advice_data__' in locals:
- raise TypeError(name+" can be used only once in a class definition.")
-
- locals['__implements_advice_data__'] = interfaces, classImplements
- addClassAdvisor(_implements_advice, depth=3)
-
-def implements(*interfaces):
- """Declare interfaces implemented by instances of a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- The interfaces given (including the interfaces in the
- specifications) are added to any interfaces previously
- declared.
-
- Previous declarations include declarations for base classes
- unless implementsOnly was used.
-
- This function is provided for convenience. It provides a more
- convenient way to call classImplements. For example::
-
- implements(I1)
-
- is equivalent to calling::
-
- classImplements(C, I1)
-
- after the class has been created.
-
- Consider the following example::
-
-
- >>> from zope.interface import Interface
- >>> class IA1(Interface): pass
- ...
- >>> class IA2(Interface): pass
- ...
- >>> class IB(Interface): pass
- ...
- >>> class IC(Interface): pass
- ...
- >>> class A(object):
- ... implements(IA1, IA2)
- >>> class B(object):
- ... implements(IB)
-
- >>> class C(A, B):
- ... implements(IC)
-
- >>> ob = C()
- >>> int(IA1 in providedBy(ob))
- 1
- >>> int(IA2 in providedBy(ob))
- 1
- >>> int(IB in providedBy(ob))
- 1
- >>> int(IC in providedBy(ob))
- 1
-
- Instances of ``C`` implement ``I1``, ``I2``, and whatever interfaces
- instances of ``A`` and ``B`` implement.
-
- """
- _implements("implements", interfaces, classImplements)
-
-def implementsOnly(*interfaces):
- """Declare the only interfaces implemented by instances of a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- Previous declarations including declarations for base classes
- are overridden.
-
- This function is provided for convenience. It provides a more
- convenient way to call classImplementsOnly. For example::
-
- implementsOnly(I1)
-
- is equivalent to calling::
-
- classImplementsOnly(I1)
-
- after the class has been created.
-
- Consider the following example::
-
- >>> from zope.interface import Interface
- >>> class IA1(Interface): pass
- ...
- >>> class IA2(Interface): pass
- ...
- >>> class IB(Interface): pass
- ...
- >>> class IC(Interface): pass
- ...
- >>> class A(object):
- ... implements(IA1, IA2)
- >>> class B(object):
- ... implements(IB)
-
- >>> class C(A, B):
- ... implementsOnly(IC)
-
- >>> ob = C()
- >>> int(IA1 in providedBy(ob))
- 0
- >>> int(IA2 in providedBy(ob))
- 0
- >>> int(IB in providedBy(ob))
- 0
- >>> int(IC in providedBy(ob))
- 1
-
-
- Instances of ``C`` implement ``IC``, regardless of what
- instances of ``A`` and ``B`` implement.
-
- """
- _implements("implementsOnly", interfaces, classImplementsOnly)
-
-##############################################################################
-#
-# Instance declarations
-
-class Provides(Declaration): # Really named ProvidesClass
- """Implement __provides__, the instance-specific specification
-
- When an object is pickled, we pickle the interfaces that it implements.
- """
-
- def __init__(self, cls, *interfaces):
- self.__args = (cls, ) + interfaces
- self._cls = cls
- Declaration.__init__(self, *(interfaces + (implementedBy(cls), )))
-
- def __reduce__(self):
- return Provides, self.__args
-
- __module__ = 'zope.interface'
-
- def __get__(self, inst, cls):
- """Make sure that a class __provides__ doesn't leak to an instance
-
- For example:
-
- >>> from zope.interface import Interface
- >>> class IFooFactory(Interface): pass
- ...
-
- >>> class C(object):
- ... pass
-
- >>> C.__provides__ = ProvidesClass(C, IFooFactory)
- >>> [i.getName() for i in C.__provides__]
- ['IFooFactory']
- >>> getattr(C(), '__provides__', 0)
- 0
-
- """
- if inst is None and cls is self._cls:
- # We were accessed through a class, so we are the class'
- # provides spec. Just return this object, but only if we are
- # being called on the same class that we were defined for:
- return self
-
- raise AttributeError('__provides__')
-
-ProvidesClass = Provides
-
-# Registry of instance declarations
-# This is a memory optimization to allow objects to share specifications.
-InstanceDeclarations = weakref.WeakValueDictionary()
-
-def Provides(*interfaces):
- """Cache instance declarations
-
- Instance declarations are shared among instances that have the same
- declaration. The declarations are cached in a weak value dictionary.
-
- (Note that, in the examples below, we are going to make assertions about
- the size of the weakvalue dictionary. For the assertions to be
- meaningful, we need to force garbage collection to make sure garbage
- objects are, indeed, removed from the system. Depending on how Python
- is run, we may need to make multiple calls to be sure. We provide a
- collect function to help with this:
-
- >>> import gc
- >>> def collect():
- ... for i in range(4):
- ... gc.collect()
-
- )
-
- >>> collect()
- >>> before = len(InstanceDeclarations)
-
- >>> class C(object):
- ... pass
-
- >>> from zope.interface import Interface
- >>> class I(Interface):
- ... pass
-
- >>> c1 = C()
- >>> c2 = C()
-
- >>> len(InstanceDeclarations) == before
- 1
-
- >>> directlyProvides(c1, I)
- >>> len(InstanceDeclarations) == before + 1
- 1
-
- >>> directlyProvides(c2, I)
- >>> len(InstanceDeclarations) == before + 1
- 1
-
- >>> del c1
- >>> collect()
- >>> len(InstanceDeclarations) == before + 1
- 1
-
- >>> del c2
- >>> collect()
- >>> len(InstanceDeclarations) == before
- 1
- """
-
- spec = InstanceDeclarations.get(interfaces)
- if spec is None:
- spec = ProvidesClass(*interfaces)
- InstanceDeclarations[interfaces] = spec
-
- return spec
-Provides.__safe_for_unpickling__ = True
-
-try:
- from types import ClassType
- DescriptorAwareMetaClasses = ClassType, type
-except ImportError: # Python 3
- DescriptorAwareMetaClasses = (type,)
-
-def directlyProvides(object, *interfaces):
- """Declare interfaces declared directly for an object
-
- The arguments after the object are one or more interfaces or interface
- specifications (``IDeclaration`` objects).
-
- The interfaces given (including the interfaces in the specifications)
- replace interfaces previously declared for the object.
-
- Consider the following example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class IA1(Interface): pass
- ...
- >>> class IA2(Interface): pass
- ...
- >>> class IB(Interface): pass
- ...
- >>> class IC(Interface): pass
- ...
- >>> class A(object):
- ... implements(IA1, IA2)
- >>> class B(object):
- ... implements(IB)
-
- >>> class C(A, B):
- ... implements(IC)
-
- >>> ob = C()
- >>> directlyProvides(ob, I1, I2)
- >>> int(I1 in providedBy(ob))
- 1
- >>> int(I2 in providedBy(ob))
- 1
- >>> int(IA1 in providedBy(ob))
- 1
- >>> int(IA2 in providedBy(ob))
- 1
- >>> int(IB in providedBy(ob))
- 1
- >>> int(IC in providedBy(ob))
- 1
-
- The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
- instances have been declared for instances of ``C``.
-
- To remove directly provided interfaces, use ``directlyProvidedBy`` and
- subtract the unwanted interfaces. For example:
-
- >>> directlyProvides(ob, directlyProvidedBy(ob)-I2)
- >>> int(I1 in providedBy(ob))
- 1
- >>> int(I2 in providedBy(ob))
- 0
-
- removes I2 from the interfaces directly provided by ``ob``. The object,
- ``ob`` no longer directly provides ``I2``, although it might still
- provide ``I2`` if it's class implements ``I2``.
-
- To add directly provided interfaces, use ``directlyProvidedBy`` and
- include additional interfaces. For example:
-
- >>> int(I2 in providedBy(ob))
- 0
- >>> directlyProvides(ob, directlyProvidedBy(ob), I2)
-
- adds ``I2`` to the interfaces directly provided by ob::
-
- >>> int(I2 in providedBy(ob))
- 1
-
- """
-
- # We need to avoid setting this attribute on meta classes that
- # don't support descriptors.
- # We can do away with this check when we get rid of the old EC
- cls = getattr(object, '__class__', None)
- if cls is not None and getattr(cls, '__class__', None) is cls:
- # It's a meta class (well, at least it it could be an extension class)
- if not isinstance(object, DescriptorAwareMetaClasses):
- raise TypeError("Attempt to make an interface declaration on a "
- "non-descriptor-aware class")
-
- interfaces = _normalizeargs(interfaces)
- if cls is None:
- cls = type(object)
-
- issub = False
- for damc in DescriptorAwareMetaClasses:
- if issubclass(cls, damc):
- issub = True
- break
- if issub:
- # we have a class or type. We'll use a special descriptor
- # that provides some extra caching
- object.__provides__ = ClassProvides(object, cls, *interfaces)
- else:
- object.__provides__ = Provides(cls, *interfaces)
-
-
-def alsoProvides(object, *interfaces):
- """Declare interfaces declared directly for an object
-
- The arguments after the object are one or more interfaces or interface
- specifications (``IDeclaration`` objects).
-
- The interfaces given (including the interfaces in the specifications) are
- added to the interfaces previously declared for the object.
-
- Consider the following example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class IA1(Interface): pass
- ...
- >>> class IA2(Interface): pass
- ...
- >>> class IB(Interface): pass
- ...
- >>> class IC(Interface): pass
- ...
- >>> class A(object):
- ... implements(IA1, IA2)
- >>> class B(object):
- ... implements(IB)
-
- >>> class C(A, B):
- ... implements(IC)
-
- >>> ob = C()
- >>> directlyProvides(ob, I1)
- >>> int(I1 in providedBy(ob))
- 1
- >>> int(I2 in providedBy(ob))
- 0
- >>> int(IA1 in providedBy(ob))
- 1
- >>> int(IA2 in providedBy(ob))
- 1
- >>> int(IB in providedBy(ob))
- 1
- >>> int(IC in providedBy(ob))
- 1
-
- >>> alsoProvides(ob, I2)
- >>> int(I1 in providedBy(ob))
- 1
- >>> int(I2 in providedBy(ob))
- 1
- >>> int(IA1 in providedBy(ob))
- 1
- >>> int(IA2 in providedBy(ob))
- 1
- >>> int(IB in providedBy(ob))
- 1
- >>> int(IC in providedBy(ob))
- 1
-
- The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
- instances have been declared for instances of ``C``. Notice that the
- alsoProvides just extends the provided interfaces.
- """
- directlyProvides(object, directlyProvidedBy(object), *interfaces)
-
-def noLongerProvides(object, interface):
- """
- This removes a directly provided interface from an object.
- Consider the following two interfaces:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
-
- ``I1`` is provided through the class, ``I2`` is directly provided
- by the object:
-
- >>> class C(object):
- ... implements(I1)
- >>> c = C()
- >>> alsoProvides(c, I2)
- >>> I2.providedBy(c)
- True
-
- Remove I2 from c again:
-
- >>> noLongerProvides(c, I2)
- >>> I2.providedBy(c)
- False
-
- Removing an interface that is provided through the class is not possible:
-
- >>> noLongerProvides(c, I1)
- Traceback (most recent call last):
- ...
- ValueError: Can only remove directly provided interfaces.
-
- """
- directlyProvides(object, directlyProvidedBy(object)-interface)
- if interface.providedBy(object):
- raise ValueError("Can only remove directly provided interfaces.")
-
-class ClassProvidesBasePy(object):
-
- def __get__(self, inst, cls):
- if cls is self._cls:
- # We only work if called on the class we were defined for
-
- if inst is None:
- # We were accessed through a class, so we are the class'
- # provides spec. Just return this object as is:
- return self
-
- return self._implements
-
- raise AttributeError('__provides__')
-
-ClassProvidesBase = ClassProvidesBasePy
-
-# Try to get C base:
-try:
- import _zope_interface_coptimizations
-except ImportError:
- pass
-else:
- from _zope_interface_coptimizations import ClassProvidesBase
-
-
-class ClassProvides(Declaration, ClassProvidesBase):
- """Special descriptor for class __provides__
-
- The descriptor caches the implementedBy info, so that
- we can get declarations for objects without instance-specific
- interfaces a bit quicker.
-
- For example:
-
- >>> from zope.interface import Interface
- >>> class IFooFactory(Interface):
- ... pass
- >>> class IFoo(Interface):
- ... pass
- >>> class C(object):
- ... implements(IFoo)
- ... classProvides(IFooFactory)
- >>> [i.getName() for i in C.__provides__]
- ['IFooFactory']
-
- >>> [i.getName() for i in C().__provides__]
- ['IFoo']
- """
-
- def __init__(self, cls, metacls, *interfaces):
- self._cls = cls
- self._implements = implementedBy(cls)
- self.__args = (cls, metacls, ) + interfaces
- Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
-
- def __reduce__(self):
- return self.__class__, self.__args
-
- # Copy base-class method for speed
- __get__ = ClassProvidesBase.__get__
-
-def directlyProvidedBy(object):
- """Return the interfaces directly provided by the given object
-
- The value returned is an ``IDeclaration``.
- """
- provides = getattr(object, "__provides__", None)
- if (provides is None # no spec
- or
- # We might have gotten the implements spec, as an
- # optimization. If so, it's like having only one base, that we
- # lop off to exclude class-supplied declarations:
- isinstance(provides, Implements)
- ):
- return _empty
-
- # Strip off the class part of the spec:
- return Declaration(provides.__bases__[:-1])
-
-def classProvides(*interfaces):
- """Declare interfaces provided directly by a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface specifications
- (``IDeclaration`` objects).
-
- The given interfaces (including the interfaces in the specifications)
- are used to create the class's direct-object interface specification.
- An error will be raised if the module class has an direct interface
- specification. In other words, it is an error to call this function more
- than once in a class definition.
-
- Note that the given interfaces have nothing to do with the interfaces
- implemented by instances of the class.
-
- This function is provided for convenience. It provides a more convenient
- way to call directlyProvides for a class. For example::
-
- classProvides(I1)
-
- is equivalent to calling::
-
- directlyProvides(theclass, I1)
-
- after the class has been created.
-
- For example:
-
- >>> from zope.interface import Interface
- >>> class IFoo(Interface): pass
- ...
- >>> class IFooFactory(Interface): pass
- ...
- >>> class C(object):
- ... implements(IFoo)
- ... classProvides(IFooFactory)
- >>> [i.getName() for i in C.__providedBy__]
- ['IFooFactory']
- >>> [i.getName() for i in C().__providedBy__]
- ['IFoo']
-
- if equivalent to:
-
- >>> from zope.interface import Interface
- >>> class IFoo(Interface): pass
- ...
- >>> class IFooFactory(Interface): pass
- ...
- >>> class C(object):
- ... implements(IFoo)
- >>> directlyProvides(C, IFooFactory)
- >>> [i.getName() for i in C.__providedBy__]
- ['IFooFactory']
- >>> [i.getName() for i in C().__providedBy__]
- ['IFoo']
-
- """
- frame = sys._getframe(1)
- locals = frame.f_locals
-
- # Try to make sure we were called from a class def
- if (locals is frame.f_globals) or ('__module__' not in locals):
- raise TypeError("classProvides can be used only from a class definition.")
-
- if '__provides__' in locals:
- raise TypeError(
- "classProvides can only be used once in a class definition.")
-
- locals["__provides__"] = _normalizeargs(interfaces)
-
- addClassAdvisor(_classProvides_advice, depth=2)
-
-def _classProvides_advice(cls):
- interfaces = cls.__dict__['__provides__']
- del cls.__provides__
- directlyProvides(cls, *interfaces)
- return cls
-
-class provider:
- """Class decorator version of classProvides"""
-
- def __init__(self, *interfaces):
- self.interfaces = interfaces
-
- def __call__(self, ob):
- directlyProvides(ob, *self.interfaces)
- return ob
-
-def moduleProvides(*interfaces):
- """Declare interfaces provided by a module
-
- This function is used in a module definition.
-
- The arguments are one or more interfaces or interface specifications
- (``IDeclaration`` objects).
-
- The given interfaces (including the interfaces in the specifications) are
- used to create the module's direct-object interface specification. An
- error will be raised if the module already has an interface specification.
- In other words, it is an error to call this function more than once in a
- module definition.
-
- This function is provided for convenience. It provides a more convenient
- way to call directlyProvides. For example::
-
- moduleImplements(I1)
-
- is equivalent to::
-
- directlyProvides(sys.modules[__name__], I1)
- """
- frame = sys._getframe(1)
- locals = frame.f_locals
-
- # Try to make sure we were called from a class def
- if (locals is not frame.f_globals) or ('__name__' not in locals):
- raise TypeError(
- "moduleProvides can only be used from a module definition.")
-
- if '__provides__' in locals:
- raise TypeError(
- "moduleProvides can only be used once in a module definition.")
-
- locals["__provides__"] = Provides(ModuleType,
- *_normalizeargs(interfaces))
-
-##############################################################################
-#
-# Declaration querying support
-
-def ObjectSpecification(direct, cls):
- """Provide object specifications
-
- These combine information for the object and for it's classes.
-
- For example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I31(I3): pass
- ...
- >>> class I4(Interface): pass
- ...
- >>> class I5(Interface): pass
- ...
- >>> class A(object):
- ... implements(I1)
- >>> class B(object): __implemented__ = I2
- ...
- >>> class C(A, B):
- ... implements(I31)
- >>> c = C()
- >>> directlyProvides(c, I4)
- >>> [i.getName() for i in providedBy(c)]
- ['I4', 'I31', 'I1', 'I2']
- >>> [i.getName() for i in providedBy(c).flattened()]
- ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
- >>> int(I1 in providedBy(c))
- 1
- >>> int(I3 in providedBy(c))
- 0
- >>> int(providedBy(c).extends(I3))
- 1
- >>> int(providedBy(c).extends(I31))
- 1
- >>> int(providedBy(c).extends(I5))
- 0
- >>> class COnly(A, B):
- ... implementsOnly(I31)
- >>> class D(COnly):
- ... implements(I5)
- >>> c = D()
- >>> directlyProvides(c, I4)
- >>> [i.getName() for i in providedBy(c)]
- ['I4', 'I5', 'I31']
- >>> [i.getName() for i in providedBy(c).flattened()]
- ['I4', 'I5', 'I31', 'I3', 'Interface']
- >>> int(I1 in providedBy(c))
- 0
- >>> int(I3 in providedBy(c))
- 0
- >>> int(providedBy(c).extends(I3))
- 1
- >>> int(providedBy(c).extends(I1))
- 0
- >>> int(providedBy(c).extends(I31))
- 1
- >>> int(providedBy(c).extends(I5))
- 1
- """
-
- return Provides(cls, direct)
-
-def getObjectSpecification(ob):
-
- provides = getattr(ob, '__provides__', None)
- if provides is not None:
- if isinstance(provides, SpecificationBase):
- return provides
-
- try:
- cls = ob.__class__
- except AttributeError:
- # We can't get the class, so just consider provides
- return _empty
-
- return implementedBy(cls)
-
-def providedBy(ob):
-
- # Here we have either a special object, an old-style declaration
- # or a descriptor
-
- # Try to get __providedBy__
- try:
- r = ob.__providedBy__
- except AttributeError:
- # Not set yet. Fall back to lower-level thing that computes it
- return getObjectSpecification(ob)
-
- try:
- # We might have gotten a descriptor from an instance of a
- # class (like an ExtensionClass) that doesn't support
- # descriptors. We'll make sure we got one by trying to get
- # the only attribute, which all specs have.
- r.extends
-
- except AttributeError:
-
- # The object's class doesn't understand descriptors.
- # Sigh. We need to get an object descriptor, but we have to be
- # careful. We want to use the instance's __provides__, if
- # there is one, but only if it didn't come from the class.
-
- try:
- r = ob.__provides__
- except AttributeError:
- # No __provides__, so just fall back to implementedBy
- return implementedBy(ob.__class__)
-
- # We need to make sure we got the __provides__ from the
- # instance. We'll do this by making sure we don't get the same
- # thing from the class:
-
- try:
- cp = ob.__class__.__provides__
- except AttributeError:
- # The ob doesn't have a class or the class has no
- # provides, assume we're done:
- return r
-
- if r is cp:
- # Oops, we got the provides from the class. This means
- # the object doesn't have it's own. We should use implementedBy
- return implementedBy(ob.__class__)
-
- return r
-
-class ObjectSpecificationDescriptorPy(object):
- """Implement the `__providedBy__` attribute
-
- The `__providedBy__` attribute computes the interfaces peovided by
- an object.
- """
-
- def __get__(self, inst, cls):
- """Get an object specification for an object
-
- For example:
-
- >>> from zope.interface import Interface
- >>> class IFoo(Interface): pass
- ...
- >>> class IFooFactory(Interface): pass
- ...
- >>> class C(object):
- ... implements(IFoo)
- ... classProvides(IFooFactory)
- >>> [i.getName() for i in C.__providedBy__]
- ['IFooFactory']
- >>> [i.getName() for i in C().__providedBy__]
- ['IFoo']
-
- """
-
- # Get an ObjectSpecification bound to either an instance or a class,
- # depending on how we were accessed.
-
- if inst is None:
- return getObjectSpecification(cls)
-
- provides = getattr(inst, '__provides__', None)
- if provides is not None:
- return provides
-
- return implementedBy(cls)
-
-ObjectSpecificationDescriptor = ObjectSpecificationDescriptorPy
-
-##############################################################################
-
-def _normalizeargs(sequence, output = None):
- """Normalize declaration arguments
-
- Normalization arguments might contain Declarions, tuples, or single
- interfaces.
-
- Anything but individial interfaces or implements specs will be expanded.
- """
- if output is None:
- output = []
-
- cls = sequence.__class__
- if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
- output.append(sequence)
- else:
- for v in sequence:
- _normalizeargs(v, output)
-
- return output
-
-_empty = Declaration()
-
-try:
- import _zope_interface_coptimizations
-except ImportError:
- pass
-else:
- from _zope_interface_coptimizations import implementedBy, providedBy
- from _zope_interface_coptimizations import getObjectSpecification
- from _zope_interface_coptimizations import ObjectSpecificationDescriptor
-
-objectSpecificationDescriptor = ObjectSpecificationDescriptor()
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/document.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/document.py
deleted file mode 100644
index ba93bed2..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/document.py
+++ /dev/null
@@ -1,105 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-""" Pretty-Print an Interface object as structured text (Yum)
-
-This module provides a function, asStructuredText, for rendering an
-interface as structured text.
-"""
-import zope.interface
-
-def asStructuredText(I, munge=0):
- """ Output structured text format. Note, this will whack any existing
- 'structured' format of the text. """
-
- r = [I.getName()]
- outp = r.append
- level = 1
-
- if I.getDoc():
- outp(_justify_and_indent(_trim_doc_string(I.getDoc()), level))
-
- bases = [base
- for base in I.__bases__
- if base is not zope.interface.Interface
- ]
- if bases:
- outp(_justify_and_indent("This interface extends:", level, munge))
- level += 1
- for b in bases:
- item = "o %s" % b.getName()
- outp(_justify_and_indent(_trim_doc_string(item), level, munge))
- level -= 1
-
- namesAndDescriptions = I.namesAndDescriptions()
- namesAndDescriptions.sort()
-
- outp(_justify_and_indent("Attributes:", level, munge))
- level += 1
- for name, desc in namesAndDescriptions:
- if not hasattr(desc, 'getSignatureString'): # ugh...
- item = "%s -- %s" % (desc.getName(),
- desc.getDoc() or 'no documentation')
- outp(_justify_and_indent(_trim_doc_string(item), level, munge))
- level -= 1
-
- outp(_justify_and_indent("Methods:", level, munge))
- level += 1
- for name, desc in namesAndDescriptions:
- if hasattr(desc, 'getSignatureString'): # ugh...
- item = "%s%s -- %s" % (desc.getName(),
- desc.getSignatureString(),
- desc.getDoc() or 'no documentation')
- outp(_justify_and_indent(_trim_doc_string(item), level, munge))
-
- return "\n\n".join(r) + "\n\n"
-
-
-def _trim_doc_string(text):
- """ Trims a doc string to make it format
- correctly with structured text. """
-
- lines = text.replace('\r\n', '\n').split('\n')
- nlines = [lines.pop(0)]
- if lines:
- min_indent = min([len(line) - len(line.lstrip())
- for line in lines])
- for line in lines:
- nlines.append(line[min_indent:])
-
- return '\n'.join(nlines)
-
-
-def _justify_and_indent(text, level, munge=0, width=72):
- """ indent and justify text, rejustify (munge) if specified """
-
- indent = " " * level
-
- if munge:
- lines = []
- line = indent
- text = text.split()
-
- for word in text:
- line = ' '.join([line, word])
- if len(line) > width:
- lines.append(line)
- line = indent
- else:
- lines.append(line)
-
- return '\n'.join(lines)
-
- else:
- return indent + \
- text.strip().replace("\r\n", "\n") .replace("\n", "\n" + indent)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/exceptions.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/exceptions.py
deleted file mode 100644
index e9a4788d..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/exceptions.py
+++ /dev/null
@@ -1,67 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interface-specific exceptions
-"""
-
-class Invalid(Exception):
- """A specification is violated
- """
-
-class DoesNotImplement(Invalid):
- """ This object does not implement """
- def __init__(self, interface):
- self.interface = interface
-
- def __str__(self):
- return """An object does not implement interface %(interface)s
-
- """ % self.__dict__
-
-class BrokenImplementation(Invalid):
- """An attribute is not completely implemented.
- """
-
- def __init__(self, interface, name):
- self.interface=interface
- self.name=name
-
- def __str__(self):
- return """An object has failed to implement interface %(interface)s
-
- The %(name)s attribute was not provided.
- """ % self.__dict__
-
-class BrokenMethodImplementation(Invalid):
- """An method is not completely implemented.
- """
-
- def __init__(self, method, mess):
- self.method=method
- self.mess=mess
-
- def __str__(self):
- return """The implementation of %(method)s violates its contract
- because %(mess)s.
- """ % self.__dict__
-
-class InvalidInterface(Exception):
- """The interface has invalid contents
- """
-
-class BadImplements(TypeError):
- """An implementation assertion is invalid
-
- because it doesn't contain an interface or a sequence of valid
- implementation assertions.
- """
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.ru.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.ru.txt
deleted file mode 100644
index a149072c..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.ru.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-===============================
-ИÑпользование рееÑтра адаптеров
-===============================
-
-Данный документ Ñодержит небольшую демонÑтрацию пакета ``zope.interface`` и его
-рееÑтра адаптеров. Документ раÑÑчитывалÑÑ ÐºÐ°Ðº конкретный, но более узкий пример
-того как иÑпользовать интерфейÑÑ‹ и адаптеры вне Zope 3.
-
-Сначала нам необходимо импортировать пакет Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñами::
-
- >>> import zope.interface
-
-Теперь мы разработаем Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð»Ñ Ð½Ð°ÑˆÐµÐ³Ð¾ объекта - проÑтого файла. Ðаш файл
-будет Ñодержать вÑего один атрибут - body, в котором фактичеÑки будет Ñохранено
-Ñодержимое файла::
-
- >>> class IFile(zope.interface.Interface):
- ...
- ... body = zope.interface.Attribute(u'Содержимое файла.')
- ...
-
-Ð”Ð»Ñ ÑтатиÑтики нам чаÑто необходимо знать размер файла. Ðо было бы неÑколько
-топорно реализовывать определение размера прÑмо Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° файла, Ñ‚.к. размер
-больше отноÑитÑÑ Ðº мета-данным. Таким образом мы Ñоздаем еще один Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð»Ñ
-предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° какого-либо объекта::
-
- >>> class ISize(zope.interface.Interface):
- ...
- ... def getSize():
- ... 'Return the size of an object.'
- ...
-
-Теперь мы должны Ñоздать клаÑÑ Ñ€ÐµÐ°Ð»Ð¸Ð·ÑƒÑŽÑ‰Ð¸Ð¹ наш файл. Ðеобходимо что бы наш
-объект хранил информацию о том, что он реализует Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ `IFile`. Мы также
-Ñоздаем атрибут Ñ Ñодержимым файла по умолчанию (Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð¾Ñ‰ÐµÐ½Ð¸Ñ Ð½Ð°ÑˆÐµÐ³Ð¾
-примера)::
-
- >>> class File(object):
- ...
- ... zope.interface.implements(IFile)
- ... body = 'foo bar'
- ...
-
-Дальше мы Ñоздаем адаптер, который будет предоÑтавлÑÑ‚ÑŒ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ `ISize`
-Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ Ð»ÑŽÐ±Ð¾Ð¹ объект предоÑтавлÑющий Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ `IFile`. По Ñоглашению мы
-иÑпользуем атрибут `__used_for__` Ð´Ð»Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа который как мы
-ожидаем предоÑтавлÑет адаптируемый объект, `IFile` в нашем Ñлучае. Ðа Ñамом
-деле Ñтот атрибут иÑпользуетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ. Ð’ Ñлучае еÑли
-адаптер иÑпользуетÑÑ Ð´Ð»Ñ Ð½ÐµÑкольких интерфейÑов можно указать их вÑе в виде
-кортежа.
-
-ОпÑÑ‚ÑŒ же по Ñоглашению конÑтруктор адаптера получает один аргумент - context
-(контекÑÑ‚). Ð’ нашем Ñлучае контекÑÑ‚ - Ñто ÑкземплÑÑ€ `IFile` (объект,
-предоÑтавлÑющий `IFile`) который иÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð· него размера.
-Так же по Ñоглашению контекÑÑ‚ ÑохранÑетÑÑ Ð° адаптере в атрибуте Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼
-`context`. Twisted комьюнити ÑÑылаетÑÑ Ð½Ð° контекÑÑ‚ как на объект `original`.
-Таким образом можно также дать аргументу любое подходÑщее имÑ, например
-`file`::
-
- >>> class FileSize(object):
- ...
- ... zope.interface.implements(ISize)
- ... __used_for__ = IFile
- ...
- ... def __init__(self, context):
- ... self.context = context
- ...
- ... def getSize(self):
- ... return len(self.context.body)
- ...
-
-Теперь когда мы напиÑали наш адаптер мы должны зарегиÑтрировать его в рееÑтре
-адаптеров, что бы его можно было запроÑить когда он понадобитÑÑ. ЗдеÑÑŒ нет
-какого-либо глобального рееÑтра адаптеров, таким образом мы должны
-ÑамоÑтоÑтельно Ñоздать Ð´Ð»Ñ Ð½Ð°ÑˆÐµÐ³Ð¾ примера рееÑÑ‚Ñ€::
-
- >>> from zope.interface.adapter import AdapterRegistry
- >>> registry = AdapterRegistry()
-
-РееÑÑ‚Ñ€ Ñодержит отображение того, что адаптер реализует на оÑнове другого
-интерфейÑа который предоÑтавлÑет объект. ПоÑтому дальше мы региÑтрируем адаптер
-который адаптирует Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ `IFile` к интерфейÑу `ISize`. Первый аргумент к
-методу `register()` рееÑтра - Ñто ÑпиÑок адаптируемых интерфейÑов. Ð’ нашем
-Ñлучае мы имеем только один адаптируемый Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ - `IFile`. СпиÑок
-интерфейÑов имеет ÑмыÑл Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð½Ñ†ÐµÐ¿Ñ†Ð¸Ð¸ мульти-адаптеров, которые
-требуют неÑкольких оригинальных объектов Ð´Ð»Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð°Ñ†Ð¸Ð¸ к новому интерфейÑу. Ð’
-Ñтой Ñитуации конÑтруктор адаптера будет требовать новый аргумент Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾
-оригинального интерфейÑа.
-
-Второй аргумент метода `register()` - Ñто Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¹ предоÑтавлÑет
-адаптер, в нашем Ñлучае `ISize`. Третий аргумент - Ð¸Ð¼Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð°. Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð½Ð°Ð¼ не
-важно Ð¸Ð¼Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð° и мы передаем его как пуÑтую Ñтроку. Обычно имена полезны
-еÑли иÑпользуютÑÑ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ñ‹ Ð´Ð»Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ð³Ð¾ набора интерфейÑов, но в различных
-ÑитуациÑÑ…. ПоÑледний аргумент - Ñто клаÑÑ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð°::
-
- >>> registry.register([IFile], ISize, '', FileSize)
-
-Теперь мы можем иÑпользовать рееÑÑ‚Ñ€ Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа адаптера::
-
- >>> registry.lookup1(IFile, ISize, '')
- <class '__main__.FileSize'>
-
-Попробуем более практичный пример. Создадим ÑкземплÑÑ€ `File` и Ñоздадим адаптер
-иÑпользующий Ð·Ð°Ð¿Ñ€Ð¾Ñ Ñ€ÐµÐµÑтра. Затем мы увидим возвращает ли адаптер корректный
-размер при вызове `getSize()`::
-
- >>> file = File()
- >>> size = registry.lookup1(IFile, ISize, '')(file)
- >>> size.getSize()
- 7
-
-Ðа Ñамом деле Ñто не очень практично, Ñ‚.к. нам нужно Ñамим передавать вÑе
-аргументы методу запроÑа. СущеÑтвует некоторый ÑинтакÑичеÑкий леденец который
-позволÑет нам получить ÑкземплÑÑ€ адаптера проÑто вызвав `ISize(file)`. Что бы
-иÑпользовать Ñту функциональноÑÑ‚ÑŒ нам понадобитÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ наш рееÑÑ‚Ñ€ к ÑпиÑку
-adapter_hooks, который находитÑÑ Ð² модуле Ñ Ð°Ð´Ð°Ð¿Ñ‚ÐµÑ€Ð°Ð¼Ð¸. Этот ÑпиÑок хранит
-коллекцию вызываемых объектов которые вызываютÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки когда вызываетÑÑ
-IFoo(obj); их предназначение - найти адаптеры которые реализуют Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð»Ñ
-определенного ÑкземплÑра контекÑта.
-
-Ðеобходимо реализовать Ñвою ÑобÑтвенную функцию Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка адаптера; данный
-пример опиÑывает одну из проÑтейших функций Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ Ñ€ÐµÐµÑтром, но
-также можно реализовать поиÑковые функции которые, например, иÑпользуют
-кÑширование, или адаптеры ÑохранÑемые в базе. Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð¸Ñка должна принимать
-желаемый на выходе Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ (в нашем Ñлучае `ISize`) как первый аргумент и
-контекÑÑ‚ Ð´Ð»Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð°Ñ†Ð¸Ð¸ (`file`) как второй. Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° вернуть адаптер,
-Ñ‚.е. ÑкземплÑÑ€ `FileSize`::
-
- >>> def hook(provided, object):
- ... adapter = registry.lookup1(zope.interface.providedBy(object),
- ... provided, '')
- ... return adapter(object)
- ...
-
-Теперь мы проÑто добавлÑем нашу функцию к ÑпиÑку `adapter_hooks`::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> adapter_hooks.append(hook)
-
-Как только Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·Ð°Ñ€ÐµÐ³Ð¸Ñтрирована мы можем иÑпользовать желаемый ÑинтакÑиÑ::
-
- >>> size = ISize(file)
- >>> size.getSize()
- 7
-
-ПоÑле нам нужно прибратьÑÑ Ð·Ð° Ñобой, что бы другие получили чиÑтый ÑпиÑок
-`adaper_hooks` поÑле наÑ::
-
- >>> adapter_hooks.remove(hook)
-
-Это вÑе. ЗдеÑÑŒ намеренно отложена диÑкуÑÑÐ¸Ñ Ð¾Ð± именованных и мульти-адаптерах,
-Ñ‚.к. данный текÑÑ‚ раÑÑчитан как практичеÑкое и проÑтое введение в интерфейÑÑ‹ и
-адаптеры Zope 3. Ð”Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации имеет ÑмыÑл прочитать
-`adapter.txt` из пакета `zope.interface`, что бы получить более формальное,
-Ñправочное и полное трактование пакета. Внимание: многие жаловалиÑÑŒ, что
-`adapter.txt` приводит их мозг к раÑплавленному ÑоÑтоÑнию!
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.txt
deleted file mode 100644
index 749b87da..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/human.txt
+++ /dev/null
@@ -1,152 +0,0 @@
-==========================
-Using the Adapter Registry
-==========================
-
-This is a small demonstration of the ``zope.interface`` package including its
-adapter registry. It is intended to provide a concrete but narrow example on
-how to use interfaces and adapters outside of Zope 3.
-
-First we have to import the interface package::
-
- >>> import zope.interface
-
-We now develop an interface for our object, which is a simple file in this
-case. For now we simply support one attribute, the body, which contains the
-actual file contents::
-
- >>> class IFile(zope.interface.Interface):
- ...
- ... body = zope.interface.Attribute('Contents of the file.')
- ...
-
-For statistical reasons we often want to know the size of a file. However, it
-would be clumsy to implement the size directly in the file object, since the
-size really represents meta-data. Thus we create another interface that
-provides the size of something::
-
- >>> class ISize(zope.interface.Interface):
- ...
- ... def getSize():
- ... 'Return the size of an object.'
- ...
-
-Now we need to implement the file. It is essential that the object states
-that it implements the `IFile` interface. We also provide a default body
-value (just to make things simpler for this example)::
-
- >>> class File(object):
- ...
- ... zope.interface.implements(IFile)
- ... body = 'foo bar'
- ...
-
-Next we implement an adapter that can provide the `ISize` interface given any
-object providing `IFile`. By convention we use `__used_for__` to specify the
-interface that we expect the adapted object to provide, in our case
-`IFile`. However, this attribute is not used for anything. If you have
-multiple interfaces for which an adapter is used, just specify the interfaces
-via a tuple.
-
-Again by convention, the constructor of an adapter takes one argument, the
-context. The context in this case is an instance of `File` (providing `IFile`)
-that is used to extract the size from. Also by convention the context is
-stored in an attribute named `context` on the adapter. The twisted community
-refers to the context as the `original` object. However, you may feel free to
-use a specific argument name, such as `file`::
-
- >>> class FileSize(object):
- ...
- ... zope.interface.implements(ISize)
- ... __used_for__ = IFile
- ...
- ... def __init__(self, context):
- ... self.context = context
- ...
- ... def getSize(self):
- ... return len(self.context.body)
- ...
-
-Now that we have written our adapter, we have to register it with an adapter
-registry, so that it can be looked up when needed. There is no such thing as a
-global registry; thus we have to instantiate one for our example manually::
-
- >>> from zope.interface.adapter import AdapterRegistry
- >>> registry = AdapterRegistry()
-
-
-The registry keeps a map of what adapters implement based on another
-interface, the object already provides. Therefore, we next have to register an
-adapter that adapts from `IFile` to `ISize`. The first argument to
-the registry's `register()` method is a list of original interfaces.In our
-cause we have only one original interface, `IFile`. A list makes sense, since
-the interface package has the concept of multi-adapters, which are adapters
-that require multiple objects to adapt to a new interface. In these
-situations, your adapter constructor will require an argument for each
-specified interface.
-
-The second argument is the interface the adapter provides, in our case
-`ISize`. The third argument is the name of the adapter. Since we do not care
-about names, we simply leave it as an empty string. Names are commonly useful,
-if you have adapters for the same set of interfaces, but they are useful in
-different situations. The last argument is simply the adapter class::
-
- >>> registry.register([IFile], ISize, '', FileSize)
-
-You can now use the the registry to lookup the adapter::
-
- >>> registry.lookup1(IFile, ISize, '')
- <class '__main__.FileSize'>
-
-Let's get a little bit more practical. Let's create a `File` instance and
-create the adapter using a registry lookup. Then we see whether the adapter
-returns the correct size by calling `getSize()`::
-
- >>> file = File()
- >>> size = registry.lookup1(IFile, ISize, '')(file)
- >>> size.getSize()
- 7
-
-However, this is not very practical, since I have to manually pass in the
-arguments to the lookup method. There is some syntactic candy that will allow
-us to get an adapter instance by simply calling `ISize(file)`. To make use of
-this functionality, we need to add our registry to the adapter_hooks list,
-which is a member of the adapters module. This list stores a collection of
-callables that are automatically invoked when IFoo(obj) is called; their
-purpose is to locate adapters that implement an interface for a certain
-context instance.
-
-You are required to implement your own adapter hook; this example covers one
-of the simplest hooks that use the registry, but you could implement one that
-used an adapter cache or persistent adapters, for instance. The helper hook is
-required to expect as first argument the desired output interface (for us
-`ISize`) and as the second argument the context of the adapter (here
-`file`). The function returns an adapter, i.e. a `FileSize` instance::
-
- >>> def hook(provided, object):
- ... adapter = registry.lookup1(zope.interface.providedBy(object),
- ... provided, '')
- ... return adapter(object)
- ...
-
-We now just add the hook to an `adapter_hooks` list::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> adapter_hooks.append(hook)
-
-Once the hook is registered, you can use the desired syntax::
-
- >>> size = ISize(file)
- >>> size.getSize()
- 7
-
-Now we have to cleanup after ourselves, so that others after us have a clean
-`adapter_hooks` list::
-
- >>> adapter_hooks.remove(hook)
-
-That's it. I have intentionally left out a discussion of named adapters and
-multi-adapters, since this text is intended as a practical and simple
-introduction to Zope 3 interfaces and adapters. You might want to read the
-`adapter.txt` in the `zope.interface` package for a more formal, referencial
-and complete treatment of the package. Warning: People have reported that
-`adapter.txt` makes their brain feel soft!
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/index.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/index.txt
deleted file mode 100644
index 3c499b52..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/index.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Welcome to zope.interface's documentation!
-==========================================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- README
- adapter
- human
- verify
-
-По-руÑÑки
-=========
-
-.. toctree::
- :maxdepth: 2
-
- README.ru
- adapter.ru
- human.ru
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interface.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interface.py
deleted file mode 100644
index 6b2d5133..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interface.py
+++ /dev/null
@@ -1,833 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interface object implementation
-"""
-from __future__ import generators
-
-import sys
-from types import FunctionType
-import weakref
-
-from zope.interface.exceptions import Invalid
-from zope.interface.ro import ro
-
-
-CO_VARARGS = 4
-CO_VARKEYWORDS = 8
-TAGGED_DATA = '__interface_tagged_values__'
-
-_decorator_non_return = object()
-
-def invariant(call):
- f_locals = sys._getframe(1).f_locals
- tags = f_locals.setdefault(TAGGED_DATA, {})
- invariants = tags.setdefault('invariants', [])
- invariants.append(call)
- return _decorator_non_return
-
-
-def taggedValue(key, value):
- """Attaches a tagged value to an interface at definition time."""
- f_locals = sys._getframe(1).f_locals
- tagged_values = f_locals.setdefault(TAGGED_DATA, {})
- tagged_values[key] = value
- return _decorator_non_return
-
-
-class Element(object):
-
- # We can't say this yet because we don't have enough
- # infrastructure in place.
- #
- #implements(IElement)
-
- def __init__(self, __name__, __doc__=''):
- """Create an 'attribute' description
- """
- if not __doc__ and __name__.find(' ') >= 0:
- __doc__ = __name__
- __name__ = None
-
- self.__name__=__name__
- self.__doc__=__doc__
- self.__tagged_values = {}
-
- def getName(self):
- """ Returns the name of the object. """
- return self.__name__
-
- def getDoc(self):
- """ Returns the documentation for the object. """
- return self.__doc__
-
- def getTaggedValue(self, tag):
- """ Returns the value associated with 'tag'. """
- return self.__tagged_values[tag]
-
- def queryTaggedValue(self, tag, default=None):
- """ Returns the value associated with 'tag'. """
- return self.__tagged_values.get(tag, default)
-
- def getTaggedValueTags(self):
- """ Returns a list of all tags. """
- return self.__tagged_values.keys()
-
- def setTaggedValue(self, tag, value):
- """ Associates 'value' with 'key'. """
- self.__tagged_values[tag] = value
-
-class SpecificationBasePy(object):
-
- def providedBy(self, ob):
- """Is the interface implemented by an object
-
- >>> from zope.interface import *
- >>> class I1(Interface):
- ... pass
- >>> class C(object):
- ... implements(I1)
- >>> c = C()
- >>> class X(object):
- ... pass
- >>> x = X()
- >>> I1.providedBy(x)
- False
- >>> I1.providedBy(C)
- False
- >>> I1.providedBy(c)
- True
- >>> directlyProvides(x, I1)
- >>> I1.providedBy(x)
- True
- >>> directlyProvides(C, I1)
- >>> I1.providedBy(C)
- True
-
- """
- spec = providedBy(ob)
- return self in spec._implied
-
- def implementedBy(self, cls):
- """Test whether the specification is implemented by a class or factory.
- Raise TypeError if argument is neither a class nor a callable."""
- spec = implementedBy(cls)
- return self in spec._implied
-
- def isOrExtends(self, interface):
- """Is the interface the same as or extend the given interface
-
- Examples::
-
- >>> from zope.interface import Interface
- >>> from zope.interface.declarations import Declaration
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration()
- >>> int(spec.extends(Interface))
- 1
- >>> spec = Declaration(I2)
- >>> int(spec.extends(Interface))
- 1
- >>> int(spec.extends(I1))
- 1
- >>> int(spec.extends(I2))
- 1
- >>> int(spec.extends(I3))
- 0
- >>> int(spec.extends(I4))
- 0
-
- """
- return interface in self._implied
-
- __call__ = isOrExtends
-
-SpecificationBase = SpecificationBasePy
-try:
- from _zope_interface_coptimizations import SpecificationBase
-except ImportError:
- pass
-
-_marker = object()
-class InterfaceBasePy(object):
- """Base class that wants to be replaced with a C base :)
- """
-
- def __call__(self, obj, alternate=_marker):
- """Adapt an object to the interface
- """
- conform = getattr(obj, '__conform__', None)
- if conform is not None:
- adapter = self._call_conform(conform)
- if adapter is not None:
- return adapter
-
- adapter = self.__adapt__(obj)
-
- if adapter is not None:
- return adapter
- elif alternate is not _marker:
- return alternate
- else:
- raise TypeError("Could not adapt", obj, self)
-
- def __adapt__(self, obj):
- """Adapt an object to the reciever
- """
- if self.providedBy(obj):
- return obj
-
- for hook in adapter_hooks:
- adapter = hook(self, obj)
- if adapter is not None:
- return adapter
-
-
-InterfaceBase = InterfaceBasePy
-try:
- from _zope_interface_coptimizations import InterfaceBase
-except ImportError:
- pass
-
-
-adapter_hooks = []
-try:
- from _zope_interface_coptimizations import adapter_hooks
-except ImportError:
- pass
-
-
-class Specification(SpecificationBase):
- """Specifications
-
- An interface specification is used to track interface declarations
- and component registrations.
-
- This class is a base class for both interfaces themselves and for
- interface specifications (declarations).
-
- Specifications are mutable. If you reassign their cases, their
- relations with other specifications are adjusted accordingly.
-
- For example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface):
- ... pass
- >>> class I2(I1):
- ... pass
- >>> class I3(I2):
- ... pass
-
- >>> [i.__name__ for i in I1.__bases__]
- ['Interface']
-
- >>> [i.__name__ for i in I2.__bases__]
- ['I1']
-
- >>> I3.extends(I1)
- 1
-
- >>> I2.__bases__ = (Interface, )
-
- >>> [i.__name__ for i in I2.__bases__]
- ['Interface']
-
- >>> I3.extends(I1)
- 0
-
- """
-
- # Copy some base class methods for speed
- isOrExtends = SpecificationBase.isOrExtends
- providedBy = SpecificationBase.providedBy
-
- def __init__(self, bases=()):
- self._implied = {}
- self.dependents = weakref.WeakKeyDictionary()
- self.__bases__ = tuple(bases)
-
- def subscribe(self, dependent):
- self.dependents[dependent] = self.dependents.get(dependent, 0) + 1
-
- def unsubscribe(self, dependent):
- n = self.dependents.get(dependent, 0) - 1
- if not n:
- del self.dependents[dependent]
- elif n > 0:
- self.dependents[dependent] = n
- else:
- raise KeyError(dependent)
-
- def __setBases(self, bases):
- # Register ourselves as a dependent of our old bases
- for b in self.__bases__:
- b.unsubscribe(self)
-
- # Register ourselves as a dependent of our bases
- self.__dict__['__bases__'] = bases
- for b in bases:
- b.subscribe(self)
-
- self.changed(self)
-
- __bases__ = property(
-
- lambda self: self.__dict__.get('__bases__', ()),
- __setBases,
- )
-
- def changed(self, originally_changed):
- """We, or something we depend on, have changed
- """
- try:
- del self._v_attrs
- except AttributeError:
- pass
-
- implied = self._implied
- implied.clear()
-
- ancestors = ro(self)
-
- try:
- if Interface not in ancestors:
- ancestors.append(Interface)
- except NameError:
- pass # defining Interface itself
-
- self.__sro__ = tuple(ancestors)
- self.__iro__ = tuple([ancestor for ancestor in ancestors
- if isinstance(ancestor, InterfaceClass)
- ])
-
- for ancestor in ancestors:
- # We directly imply our ancestors:
- implied[ancestor] = ()
-
- # Now, advise our dependents of change:
- for dependent in self.dependents.keys():
- dependent.changed(originally_changed)
-
-
- def interfaces(self):
- """Return an iterator for the interfaces in the specification
-
- for example::
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Specification((I2, I3))
- >>> spec = Specification((I4, spec))
- >>> i = spec.interfaces()
- >>> [x.getName() for x in i]
- ['I4', 'I2', 'I3']
- >>> list(i)
- []
- """
- seen = {}
- for base in self.__bases__:
- for interface in base.interfaces():
- if interface not in seen:
- seen[interface] = 1
- yield interface
-
-
- def extends(self, interface, strict=True):
- """Does the specification extend the given interface?
-
- Test whether an interface in the specification extends the
- given interface
-
- Examples::
-
- >>> from zope.interface import Interface
- >>> from zope.interface.declarations import Declaration
- >>> class I1(Interface): pass
- ...
- >>> class I2(I1): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(I3): pass
- ...
- >>> spec = Declaration()
- >>> int(spec.extends(Interface))
- 1
- >>> spec = Declaration(I2)
- >>> int(spec.extends(Interface))
- 1
- >>> int(spec.extends(I1))
- 1
- >>> int(spec.extends(I2))
- 1
- >>> int(spec.extends(I3))
- 0
- >>> int(spec.extends(I4))
- 0
- >>> I2.extends(I2)
- 0
- >>> I2.extends(I2, False)
- 1
- >>> I2.extends(I2, strict=False)
- 1
-
- """
- return ((interface in self._implied)
- and
- ((not strict) or (self != interface))
- )
-
- def weakref(self, callback=None):
- return weakref.ref(self, callback)
-
- def get(self, name, default=None):
- """Query for an attribute description
- """
- try:
- attrs = self._v_attrs
- except AttributeError:
- attrs = self._v_attrs = {}
- attr = attrs.get(name)
- if attr is None:
- for iface in self.__iro__:
- attr = iface.direct(name)
- if attr is not None:
- attrs[name] = attr
- break
-
- if attr is None:
- return default
- else:
- return attr
-
-class InterfaceClass(Element, InterfaceBase, Specification):
- """Prototype (scarecrow) Interfaces Implementation."""
-
- # We can't say this yet because we don't have enough
- # infrastructure in place.
- #
- #implements(IInterface)
-
- def __init__(self, name, bases=(), attrs=None, __doc__=None,
- __module__=None):
-
- if attrs is None:
- attrs = {}
-
- if __module__ is None:
- __module__ = attrs.get('__module__')
- if isinstance(__module__, str):
- del attrs['__module__']
- else:
- try:
- # Figure out what module defined the interface.
- # This is how cPython figures out the module of
- # a class, but of course it does it in C. :-/
- __module__ = sys._getframe(1).f_globals['__name__']
- except (AttributeError, KeyError):
- pass
-
- self.__module__ = __module__
-
- d = attrs.get('__doc__')
- if d is not None:
- if not isinstance(d, Attribute):
- if __doc__ is None:
- __doc__ = d
- del attrs['__doc__']
-
- if __doc__ is None:
- __doc__ = ''
-
- Element.__init__(self, name, __doc__)
-
- tagged_data = attrs.pop(TAGGED_DATA, None)
- if tagged_data is not None:
- for key, val in tagged_data.items():
- self.setTaggedValue(key, val)
-
- for base in bases:
- if not isinstance(base, InterfaceClass):
- raise TypeError('Expected base interfaces')
-
- Specification.__init__(self, bases)
-
- # Make sure that all recorded attributes (and methods) are of type
- # `Attribute` and `Method`
- for name, attr in attrs.items():
- if name == '__locals__':
- # This happens under Python 3 sometimes, not sure why. /regebro
- continue
- if isinstance(attr, Attribute):
- attr.interface = self
- if not attr.__name__:
- attr.__name__ = name
- elif isinstance(attr, FunctionType):
- attrs[name] = fromFunction(attr, self, name=name)
- elif attr is _decorator_non_return:
- del attrs[name]
- else:
- raise InvalidInterface("Concrete attribute, " + name)
-
- self.__attrs = attrs
-
- self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
-
- def interfaces(self):
- """Return an iterator for the interfaces in the specification
-
- for example::
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>>
- >>> i = I1.interfaces()
- >>> [x.getName() for x in i]
- ['I1']
- >>> list(i)
- []
- """
- yield self
-
- def getBases(self):
- return self.__bases__
-
- def isEqualOrExtendedBy(self, other):
- """Same interface or extends?"""
- return self == other or other.extends(self)
-
- def names(self, all=False):
- """Return the attribute names defined by the interface."""
- if not all:
- return self.__attrs.keys()
-
- r = self.__attrs.copy()
-
- for base in self.__bases__:
- r.update(dict.fromkeys(base.names(all)))
-
- return r.keys()
-
- def __iter__(self):
- return iter(self.names(all=True))
-
- def namesAndDescriptions(self, all=False):
- """Return attribute names and descriptions defined by interface."""
- if not all:
- return self.__attrs.items()
-
- r = {}
- for base in self.__bases__[::-1]:
- r.update(dict(base.namesAndDescriptions(all)))
-
- r.update(self.__attrs)
-
- return r.items()
-
- def getDescriptionFor(self, name):
- """Return the attribute description for the given name."""
- r = self.get(name)
- if r is not None:
- return r
-
- raise KeyError(name)
-
- __getitem__ = getDescriptionFor
-
- def __contains__(self, name):
- return self.get(name) is not None
-
- def direct(self, name):
- return self.__attrs.get(name)
-
- def queryDescriptionFor(self, name, default=None):
- return self.get(name, default)
-
- def deferred(self):
- """Return a defered class corresponding to the interface."""
- if hasattr(self, "_deferred"): return self._deferred
-
- klass={}
- exec "class %s: pass" % self.__name__ in klass
- klass=klass[self.__name__]
-
- self.__d(klass)
-
- self._deferred=klass
-
- return klass
-
- def validateInvariants(self, obj, errors=None):
- """validate object to defined invariants."""
- for call in self.queryTaggedValue('invariants', []):
- try:
- call(obj)
- except Invalid, e:
- if errors is None:
- raise
- else:
- errors.append(e)
- for base in self.__bases__:
- try:
- base.validateInvariants(obj, errors)
- except Invalid:
- if errors is None:
- raise
- if errors:
- raise Invalid(errors)
-
- def _getInterface(self, ob, name):
- """Retrieve a named interface."""
- return None
-
- def __d(self, klass):
- for k, v in self.__attrs.items():
- if isinstance(v, Method) and not (k in klass.__dict__):
- setattr(klass, k, v)
-
- for b in self.__bases__:
- b.__d(klass)
-
- def __repr__(self):
- try:
- return self._v_repr
- except AttributeError:
- name = self.__name__
- m = self.__module__
- if m:
- name = '%s.%s' % (m, name)
- r = "<%s %s>" % (self.__class__.__name__, name)
- self._v_repr = r
- return r
-
- def _call_conform(self, conform):
- try:
- return conform(self)
- except TypeError:
- # We got a TypeError. It might be an error raised by
- # the __conform__ implementation, or *we* may have
- # made the TypeError by calling an unbound method
- # (object is a class). In the later case, we behave
- # as though there is no __conform__ method. We can
- # detect this case by checking whether there is more
- # than one traceback object in the traceback chain:
- if sys.exc_info()[2].tb_next is not None:
- # There is more than one entry in the chain, so
- # reraise the error:
- raise
- # This clever trick is from Phillip Eby
-
- return None
-
- def __reduce__(self):
- return self.__name__
-
- def __cmp(self, o1, o2):
- # Yes, I did mean to name this __cmp, rather than __cmp__.
- # It is a private method used by __lt__ and __gt__.
- # I don't want to override __eq__ because I want the default
- # __eq__, which is really fast.
- """Make interfaces sortable
-
- TODO: It would ne nice if:
-
- More specific interfaces should sort before less specific ones.
- Otherwise, sort on name and module.
-
- But this is too complicated, and we're going to punt on it
- for now.
-
- For now, sort on interface and module name.
-
- None is treated as a pseudo interface that implies the loosest
- contact possible, no contract. For that reason, all interfaces
- sort before None.
-
- """
- if o1 is None:
- return 1
- if o2 is None:
- return -1
-
- n1 = (getattr(o1, '__name__', ''), getattr(o1, '__module__', ''))
- n2 = (getattr(o2, '__name__', ''), getattr(o2, '__module__', ''))
-
- # This spelling works under Python3, which doesn't have cmp().
- return (n1 > n2) - (n1 < n2)
-
- def __hash__(self):
- return hash((self.__name__, self.__module__))
-
- def __eq__(self, other):
- c = self.__cmp(self, other)
- return c == 0
-
- def __ne__(self, other):
- c = self.__cmp(self, other)
- return c != 0
-
- def __lt__(self, other):
- c = self.__cmp(self, other)
- return c < 0
-
- def __le__(self, other):
- c = self.__cmp(self, other)
- return c <= 0
-
- def __gt__(self, other):
- c = self.__cmp(self, other)
- return c > 0
-
- def __ge__(self, other):
- c = self.__cmp(self, other)
- return c >= 0
-
-
-Interface = InterfaceClass("Interface", __module__ = 'zope.interface')
-
-class Attribute(Element):
- """Attribute descriptions
- """
-
- # We can't say this yet because we don't have enough
- # infrastructure in place.
- #
- # implements(IAttribute)
-
- interface = None
-
-
-class Method(Attribute):
- """Method interfaces
-
- The idea here is that you have objects that describe methods.
- This provides an opportunity for rich meta-data.
- """
-
- # We can't say this yet because we don't have enough
- # infrastructure in place.
- #
- # implements(IMethod)
-
- def __call__(self, *args, **kw):
- raise BrokenImplementation(self.interface, self.__name__)
-
- def getSignatureInfo(self):
- return {'positional': self.positional,
- 'required': self.required,
- 'optional': self.optional,
- 'varargs': self.varargs,
- 'kwargs': self.kwargs,
- }
-
- def getSignatureString(self):
- sig = []
- for v in self.positional:
- sig.append(v)
- if v in self.optional.keys():
- sig[-1] += "=" + `self.optional[v]`
- if self.varargs:
- sig.append("*" + self.varargs)
- if self.kwargs:
- sig.append("**" + self.kwargs)
-
- return "(%s)" % ", ".join(sig)
-
-
-def fromFunction(func, interface=None, imlevel=0, name=None):
- name = name or func.__name__
- method = Method(name, func.__doc__)
- defaults = func.func_defaults or ()
- code = func.func_code
- # Number of positional arguments
- na = code.co_argcount-imlevel
- names = code.co_varnames[imlevel:]
- opt = {}
- # Number of required arguments
- nr = na-len(defaults)
- if nr < 0:
- defaults=defaults[-nr:]
- nr = 0
-
- # Determine the optional arguments.
- opt.update(dict(zip(names[nr:], defaults)))
-
- method.positional = names[:na]
- method.required = names[:nr]
- method.optional = opt
-
- argno = na
-
- # Determine the function's variable argument's name (i.e. *args)
- if code.co_flags & CO_VARARGS:
- method.varargs = names[argno]
- argno = argno + 1
- else:
- method.varargs = None
-
- # Determine the function's keyword argument's name (i.e. **kw)
- if code.co_flags & CO_VARKEYWORDS:
- method.kwargs = names[argno]
- else:
- method.kwargs = None
-
- method.interface = interface
-
- for key, value in func.__dict__.items():
- method.setTaggedValue(key, value)
-
- return method
-
-
-def fromMethod(meth, interface=None, name=None):
- func = meth.im_func
- return fromFunction(func, interface, imlevel=1, name=name)
-
-
-# Now we can create the interesting interfaces and wire them up:
-def _wire():
- from zope.interface.declarations import classImplements
-
- from zope.interface.interfaces import IAttribute
- classImplements(Attribute, IAttribute)
-
- from zope.interface.interfaces import IMethod
- classImplements(Method, IMethod)
-
- from zope.interface.interfaces import IInterface
- classImplements(InterfaceClass, IInterface)
-
- from zope.interface.interfaces import ISpecification
- classImplements(Specification, ISpecification)
-
-# We import this here to deal with module dependencies.
-from zope.interface.declarations import implementedBy
-from zope.interface.declarations import providedBy
-from zope.interface.exceptions import InvalidInterface
-from zope.interface.exceptions import BrokenImplementation
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interfaces.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interfaces.py
deleted file mode 100644
index 9a37c061..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/interfaces.py
+++ /dev/null
@@ -1,746 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interface Package Interfaces
-"""
-__docformat__ = 'restructuredtext'
-
-
-from zope.interface import Interface
-from zope.interface.interface import Attribute
-
-class IElement(Interface):
- """Objects that have basic documentation and tagged values.
- """
-
- __name__ = Attribute('__name__', 'The object name')
- __doc__ = Attribute('__doc__', 'The object doc string')
-
- def getTaggedValue(tag):
- """Returns the value associated with `tag`.
-
- Raise a `KeyError` of the tag isn't set.
- """
-
- def queryTaggedValue(tag, default=None):
- """Returns the value associated with `tag`.
-
- Return the default value of the tag isn't set.
- """
-
- def getTaggedValueTags():
- """Returns a list of all tags."""
-
- def setTaggedValue(tag, value):
- """Associates `value` with `key`."""
-
-
-class IAttribute(IElement):
- """Attribute descriptors"""
-
- interface = Attribute('interface',
- 'Stores the interface instance in which the '
- 'attribute is located.')
-
-
-class IMethod(IAttribute):
- """Method attributes"""
-
- def getSignatureInfo():
- """Returns the signature information.
-
- This method returns a dictionary with the following keys:
-
- o `positional` - All positional arguments.
-
- o `required` - A list of all required arguments.
-
- o `optional` - A list of all optional arguments.
-
- o `varargs` - The name of the varargs argument.
-
- o `kwargs` - The name of the kwargs argument.
- """
-
- def getSignatureString():
- """Return a signature string suitable for inclusion in documentation.
-
- This method returns the function signature string. For example, if you
- have `func(a, b, c=1, d='f')`, then the signature string is `(a, b,
- c=1, d='f')`.
- """
-
-class ISpecification(Interface):
- """Object Behavioral specifications"""
-
- def extends(other, strict=True):
- """Test whether a specification extends another
-
- The specification extends other if it has other as a base
- interface or if one of it's bases extends other.
-
- If strict is false, then the specification extends itself.
- """
-
- def isOrExtends(other):
- """Test whether the specification is or extends another
- """
-
- def weakref(callback=None):
- """Return a weakref to the specification
-
- This method is, regrettably, needed to allow weakrefs to be
- computed to security-proxied specifications. While the
- zope.interface package does not require zope.security or
- zope.proxy, it has to be able to coexist with it.
-
- """
-
- __bases__ = Attribute("""Base specifications
-
- A tuple if specifications from which this specification is
- directly derived.
-
- """)
-
- __sro__ = Attribute("""Specification-resolution order
-
- A tuple of the specification and all of it's ancestor
- specifications from most specific to least specific.
-
- (This is similar to the method-resolution order for new-style classes.)
- """)
-
- __iro__ = Attribute("""Interface-resolution order
-
- A tuple of the of the specification's ancestor interfaces from
- most specific to least specific. The specification itself is
- included if it is an interface.
-
- (This is similar to the method-resolution order for new-style classes.)
- """)
-
- def get(name, default=None):
- """Look up the description for a name
-
- If the named attribute is not defined, the default is
- returned.
- """
-
-
-class IInterface(ISpecification, IElement):
- """Interface objects
-
- Interface objects describe the behavior of an object by containing
- useful information about the object. This information includes:
-
- o Prose documentation about the object. In Python terms, this
- is called the "doc string" of the interface. In this element,
- you describe how the object works in prose language and any
- other useful information about the object.
-
- o Descriptions of attributes. Attribute descriptions include
- the name of the attribute and prose documentation describing
- the attributes usage.
-
- o Descriptions of methods. Method descriptions can include:
-
- - Prose "doc string" documentation about the method and its
- usage.
-
- - A description of the methods arguments; how many arguments
- are expected, optional arguments and their default values,
- the position or arguments in the signature, whether the
- method accepts arbitrary arguments and whether the method
- accepts arbitrary keyword arguments.
-
- o Optional tagged data. Interface objects (and their attributes and
- methods) can have optional, application specific tagged data
- associated with them. Examples uses for this are examples,
- security assertions, pre/post conditions, and other possible
- information you may want to associate with an Interface or its
- attributes.
-
- Not all of this information is mandatory. For example, you may
- only want the methods of your interface to have prose
- documentation and not describe the arguments of the method in
- exact detail. Interface objects are flexible and let you give or
- take any of these components.
-
- Interfaces are created with the Python class statement using
- either Interface.Interface or another interface, as in::
-
- from zope.interface import Interface
-
- class IMyInterface(Interface):
- '''Interface documentation'''
-
- def meth(arg1, arg2):
- '''Documentation for meth'''
-
- # Note that there is no self argument
-
- class IMySubInterface(IMyInterface):
- '''Interface documentation'''
-
- def meth2():
- '''Documentation for meth2'''
-
- You use interfaces in two ways:
-
- o You assert that your object implement the interfaces.
-
- There are several ways that you can assert that an object
- implements an interface:
-
- 1. Call zope.interface.implements in your class definition.
-
- 2. Call zope.interfaces.directlyProvides on your object.
-
- 3. Call 'zope.interface.classImplements' to assert that instances
- of a class implement an interface.
-
- For example::
-
- from zope.interface import classImplements
-
- classImplements(some_class, some_interface)
-
- This approach is useful when it is not an option to modify
- the class source. Note that this doesn't affect what the
- class itself implements, but only what its instances
- implement.
-
- o You query interface meta-data. See the IInterface methods and
- attributes for details.
-
- """
-
- def providedBy(object):
- """Test whether the interface is implemented by the object
-
- Return true of the object asserts that it implements the
- interface, including asserting that it implements an extended
- interface.
- """
-
- def implementedBy(class_):
- """Test whether the interface is implemented by instances of the class
-
- Return true of the class asserts that its instances implement the
- interface, including asserting that they implement an extended
- interface.
- """
-
- def names(all=False):
- """Get the interface attribute names
-
- Return a sequence of the names of the attributes, including
- methods, included in the interface definition.
-
- Normally, only directly defined attributes are included. If
- a true positional or keyword argument is given, then
- attributes defined by base classes will be included.
- """
-
- def namesAndDescriptions(all=False):
- """Get the interface attribute names and descriptions
-
- Return a sequence of the names and descriptions of the
- attributes, including methods, as name-value pairs, included
- in the interface definition.
-
- Normally, only directly defined attributes are included. If
- a true positional or keyword argument is given, then
- attributes defined by base classes will be included.
- """
-
- def __getitem__(name):
- """Get the description for a name
-
- If the named attribute is not defined, a KeyError is raised.
- """
-
- def direct(name):
- """Get the description for the name if it was defined by the interface
-
- If the interface doesn't define the name, returns None.
- """
-
- def validateInvariants(obj, errors=None):
- """Validate invariants
-
- Validate object to defined invariants. If errors is None,
- raises first Invalid error; if errors is a list, appends all errors
- to list, then raises Invalid with the errors as the first element
- of the "args" tuple."""
-
- def __contains__(name):
- """Test whether the name is defined by the interface"""
-
- def __iter__():
- """Return an iterator over the names defined by the interface
-
- The names iterated include all of the names defined by the
- interface directly and indirectly by base interfaces.
- """
-
- __module__ = Attribute("""The name of the module defining the interface""")
-
-class IDeclaration(ISpecification):
- """Interface declaration
-
- Declarations are used to express the interfaces implemented by
- classes or provided by objects.
- """
-
- def __contains__(interface):
- """Test whether an interface is in the specification
-
- Return true if the given interface is one of the interfaces in
- the specification and false otherwise.
- """
-
- def __iter__():
- """Return an iterator for the interfaces in the specification
- """
-
- def flattened():
- """Return an iterator of all included and extended interfaces
-
- An iterator is returned for all interfaces either included in
- or extended by interfaces included in the specifications
- without duplicates. The interfaces are in "interface
- resolution order". The interface resolution order is such that
- base interfaces are listed after interfaces that extend them
- and, otherwise, interfaces are included in the order that they
- were defined in the specification.
- """
-
- def __sub__(interfaces):
- """Create an interface specification with some interfaces excluded
-
- The argument can be an interface or an interface
- specifications. The interface or interfaces given in a
- specification are subtracted from the interface specification.
-
- Removing an interface that is not in the specification does
- not raise an error. Doing so has no effect.
-
- Removing an interface also removes sub-interfaces of the interface.
-
- """
-
- def __add__(interfaces):
- """Create an interface specification with some interfaces added
-
- The argument can be an interface or an interface
- specifications. The interface or interfaces given in a
- specification are added to the interface specification.
-
- Adding an interface that is already in the specification does
- not raise an error. Doing so has no effect.
- """
-
- def __nonzero__():
- """Return a true value of the interface specification is non-empty
- """
-
-class IInterfaceDeclaration(Interface):
- """Declare and check the interfaces of objects
-
- The functions defined in this interface are used to declare the
- interfaces that objects provide and to query the interfaces that have
- been declared.
-
- Interfaces can be declared for objects in two ways:
-
- - Interfaces are declared for instances of the object's class
-
- - Interfaces are declared for the object directly.
-
- The interfaces declared for an object are, therefore, the union of
- interfaces declared for the object directly and the interfaces
- declared for instances of the object's class.
-
- Note that we say that a class implements the interfaces provided
- by it's instances. An instance can also provide interfaces
- directly. The interfaces provided by an object are the union of
- the interfaces provided directly and the interfaces implemented by
- the class.
- """
-
- def providedBy(ob):
- """Return the interfaces provided by an object
-
- This is the union of the interfaces directly provided by an
- object and interfaces implemented by it's class.
-
- The value returned is an IDeclaration.
- """
-
- def implementedBy(class_):
- """Return the interfaces implemented for a class' instances
-
- The value returned is an IDeclaration.
- """
-
- def classImplements(class_, *interfaces):
- """Declare additional interfaces implemented for instances of a class
-
- The arguments after the class are one or more interfaces or
- interface specifications (IDeclaration objects).
-
- The interfaces given (including the interfaces in the
- specifications) are added to any interfaces previously
- declared.
-
- Consider the following example::
-
- class C(A, B):
- ...
-
- classImplements(C, I1, I2)
-
-
- Instances of ``C`` provide ``I1``, ``I2``, and whatever interfaces
- instances of ``A`` and ``B`` provide.
- """
-
- def implementer(*interfaces):
- """Create a decorator for declaring interfaces implemented by a facory
-
- A callable is returned that makes an implements declaration on
- objects passed to it.
- """
-
- def classImplementsOnly(class_, *interfaces):
- """Declare the only interfaces implemented by instances of a class
-
- The arguments after the class are one or more interfaces or
- interface specifications (IDeclaration objects).
-
- The interfaces given (including the interfaces in the
- specifications) replace any previous declarations.
-
- Consider the following example::
-
- class C(A, B):
- ...
-
- classImplements(C, IA, IB. IC)
- classImplementsOnly(C. I1, I2)
-
- Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
- whatever interfaces instances of ``A`` and ``B`` implement.
- """
-
- def implementer_only(*interfaces):
- """Create a decorator for declaring the only interfaces implemented
-
- A callable is returned that makes an implements declaration on
- objects passed to it.
- """
-
- def directlyProvidedBy(object):
- """Return the interfaces directly provided by the given object
-
- The value returned is an IDeclaration.
- """
-
- def directlyProvides(object, *interfaces):
- """Declare interfaces declared directly for an object
-
- The arguments after the object are one or more interfaces or
- interface specifications (IDeclaration objects).
-
- The interfaces given (including the interfaces in the
- specifications) replace interfaces previously
- declared for the object.
-
- Consider the following example::
-
- class C(A, B):
- ...
-
- ob = C()
- directlyProvides(ob, I1, I2)
-
- The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
- instances have been declared for instances of ``C``.
-
- To remove directly provided interfaces, use ``directlyProvidedBy`` and
- subtract the unwanted interfaces. For example::
-
- directlyProvides(ob, directlyProvidedBy(ob)-I2)
-
- removes I2 from the interfaces directly provided by
- ``ob``. The object, ``ob`` no longer directly provides ``I2``,
- although it might still provide ``I2`` if it's class
- implements ``I2``.
-
- To add directly provided interfaces, use ``directlyProvidedBy`` and
- include additional interfaces. For example::
-
- directlyProvides(ob, directlyProvidedBy(ob), I2)
-
- adds I2 to the interfaces directly provided by ob.
- """
-
- def alsoProvides(object, *interfaces):
- """Declare additional interfaces directly for an object::
-
- alsoProvides(ob, I1)
-
- is equivalent to::
-
- directlyProvides(ob, directlyProvidedBy(ob), I1)
- """
-
- def noLongerProvides(object, interface):
- """Remove an interface from the list of an object's directly
- provided interfaces::
-
- noLongerProvides(ob, I1)
-
- is equivalent to::
-
- directlyProvides(ob, directlyProvidedBy(ob)-I1)
-
- with the exception that if ``I1`` is an interface that is
- provided by ``ob`` through the class's implementation,
- ValueError is raised.
- """
-
- def implements(*interfaces):
- """Declare interfaces implemented by instances of a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- The interfaces given (including the interfaces in the
- specifications) are added to any interfaces previously
- declared.
-
- Previous declarations include declarations for base classes
- unless implementsOnly was used.
-
- This function is provided for convenience. It provides a more
- convenient way to call classImplements. For example::
-
- implements(I1)
-
- is equivalent to calling::
-
- classImplements(C, I1)
-
- after the class has been created.
-
- Consider the following example::
-
- class C(A, B):
- implements(I1, I2)
-
-
- Instances of ``C`` implement ``I1``, ``I2``, and whatever interfaces
- instances of ``A`` and ``B`` implement.
- """
-
- def implementsOnly(*interfaces):
- """Declare the only interfaces implemented by instances of a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- Previous declarations including declarations for base classes
- are overridden.
-
- This function is provided for convenience. It provides a more
- convenient way to call classImplementsOnly. For example::
-
- implementsOnly(I1)
-
- is equivalent to calling::
-
- classImplementsOnly(I1)
-
- after the class has been created.
-
- Consider the following example::
-
- class C(A, B):
- implementsOnly(I1, I2)
-
-
- Instances of ``C`` implement ``I1``, ``I2``, regardless of what
- instances of ``A`` and ``B`` implement.
- """
-
- def classProvides(*interfaces):
- """Declare interfaces provided directly by a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- The given interfaces (including the interfaces in the
- specifications) are used to create the class's direct-object
- interface specification. An error will be raised if the module
- class has an direct interface specification. In other words, it is
- an error to call this function more than once in a class
- definition.
-
- Note that the given interfaces have nothing to do with the
- interfaces implemented by instances of the class.
-
- This function is provided for convenience. It provides a more
- convenient way to call directlyProvides for a class. For example::
-
- classProvides(I1)
-
- is equivalent to calling::
-
- directlyProvides(theclass, I1)
-
- after the class has been created.
- """
- def provider(*interfaces):
- """A class decorator version of classProvides"""
-
- def moduleProvides(*interfaces):
- """Declare interfaces provided by a module
-
- This function is used in a module definition.
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- The given interfaces (including the interfaces in the
- specifications) are used to create the module's direct-object
- interface specification. An error will be raised if the module
- already has an interface specification. In other words, it is
- an error to call this function more than once in a module
- definition.
-
- This function is provided for convenience. It provides a more
- convenient way to call directlyProvides for a module. For example::
-
- moduleImplements(I1)
-
- is equivalent to::
-
- directlyProvides(sys.modules[__name__], I1)
- """
-
- def Declaration(*interfaces):
- """Create an interface specification
-
- The arguments are one or more interfaces or interface
- specifications (IDeclaration objects).
-
- A new interface specification (IDeclaration) with
- the given interfaces is returned.
- """
-
-class IAdapterRegistry(Interface):
- """Provide an interface-based registry for adapters
-
- This registry registers objects that are in some sense "from" a
- sequence of specification to an interface and a name.
-
- No specific semantics are assumed for the registered objects,
- however, the most common application will be to register factories
- that adapt objects providing required specifications to a provided
- interface.
- """
-
- def register(required, provided, name, value):
- """Register a value
-
- A value is registered for a *sequence* of required specifications, a
- provided interface, and a name.
- """
-
- def registered(required, provided, name=u''):
- """Return the component registered for the given interfaces and name
-
- Unlike the lookup method, this methods won't retrieve
- components registered for more specific required interfaces or
- less specific provided interfaces.
-
- If no component was registered exactly for the given
- interfaces and name, then None is returned.
-
- """
-
- def lookup(required, provided, name='', default=None):
- """Lookup a value
-
- A value is looked up based on a *sequence* of required
- specifications, a provided interface, and a name.
- """
-
- def queryMultiAdapter(objects, provided, name=u'', default=None):
- """Adapt a sequence of objects to a named, provided, interface
- """
-
- def lookup1(required, provided, name=u'', default=None):
- """Lookup a value using a single required interface
-
- A value is looked up based on a single required
- specifications, a provided interface, and a name.
- """
-
- def queryAdapter(object, provided, name=u'', default=None):
- """Adapt an object using a registered adapter factory.
- """
-
- def adapter_hook(provided, object, name=u'', default=None):
- """Adapt an object using a registered adapter factory.
- """
-
- def lookupAll(required, provided):
- """Find all adapters from the required to the provided interfaces
-
- An iterable object is returned that provides name-value two-tuples.
- """
-
- def names(required, provided):
- """Return the names for which there are registered objects
- """
-
- def subscribe(required, provided, subscriber, name=u''):
- """Register a subscriber
-
- A subscriber is registered for a *sequence* of required
- specifications, a provided interface, and a name.
-
- Multiple subscribers may be registered for the same (or
- equivalent) interfaces.
- """
-
- def subscriptions(required, provided, name=u''):
- """Get a sequence of subscribers
-
- Subscribers for a *sequence* of required interfaces, and a provided
- interface are returned.
- """
-
- def subscribers(objects, provided, name=u''):
- """Get a sequence of subscription adapters
- """
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/ro.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/ro.py
deleted file mode 100644
index 47a7ea2b..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/ro.py
+++ /dev/null
@@ -1,69 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Compute a resolution order for an object and its bases
-"""
-__docformat__ = 'restructuredtext'
-
-
-def ro(object):
- """Compute a "resolution order" for an object
- """
- return mergeOrderings([_flatten(object)])
-
-def mergeOrderings(orderings, seen=None):
- """Merge multiple orderings so that within-ordering order is preserved
-
- Orderings are constrained in such a way that if an object appears
- in two or more orderings, then the suffix that begins with the
- object must be in both orderings.
-
- For example:
-
- >>> _mergeOrderings([
- ... ['x', 'y', 'z'],
- ... ['q', 'z'],
- ... [1, 3, 5],
- ... ['z']
- ... ])
- ['x', 'y', 'q', 1, 3, 5, 'z']
-
- """
-
- if seen is None:
- seen = {}
- result = []
- orderings.reverse()
- for ordering in orderings:
- ordering = list(ordering)
- ordering.reverse()
- for o in ordering:
- if o not in seen:
- seen[o] = 1
- result.append(o)
-
- result.reverse()
- return result
-
-def _flatten(ob):
- result = [ob]
- i = 0
- for ob in iter(result):
- i += 1
- # The recursive calls can be avoided by inserting the base classes
- # into the dynamically growing list directly after the currently
- # considered object; the iterator makes sure this will keep working
- # in the future, since it cannot rely on the length of the list
- # by definition.
- result[i:i] = ob.__bases__
- return result
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/__init__.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/__init__.py
deleted file mode 100644
index 1cf24e65..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import os
-import unittest
-
-def additional_tests():
- suites = unittest.TestSuite()
- for file in os.listdir(os.path.dirname(__file__)):
- if file.endswith('.py') and file!='__init__.py':
- name = os.path.splitext(file)[0]
- module = __import__('.'.join((__name__, name)), globals(),
- locals(), [name])
- if hasattr(module, 'test_suite'):
- suites.addTests(module.test_suite())
- return suites
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/dummy.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/dummy.py
deleted file mode 100644
index f5564da3..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/dummy.py
+++ /dev/null
@@ -1,22 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Dummy Module
-"""
-from zope.interface import moduleProvides
-from zope.interface.tests.ifoo import IFoo
-
-moduleProvides(IFoo)
-
-def bar(baz):
- pass
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/foodforthought.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/foodforthought.txt
deleted file mode 100644
index 45d961be..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/foodforthought.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-================================
-Food-based subscription examples
-================================
-
-
-This file gives more subscription examples using a cooking-based example::
-
- >>> from zope.interface.adapter import AdapterRegistry
- >>> registry = AdapterRegistry()
-
- >>> import zope.interface
- >>> class IAnimal(zope.interface.Interface):
- ... pass
- >>> class IPoultry(IAnimal):
- ... pass
- >>> class IChicken(IPoultry):
- ... pass
- >>> class ISeafood(IAnimal):
- ... pass
-
-Adapting to some other interface for which there is no
-subscription adapter returns an empty sequence::
-
- >>> class IRecipe(zope.interface.Interface):
- ... pass
- >>> class ISausages(IRecipe):
- ... pass
- >>> class INoodles(IRecipe):
- ... pass
- >>> class IKFC(IRecipe):
- ... pass
-
- >>> list(registry.subscriptions([IPoultry], IRecipe))
- []
-
-unless we define a subscription::
-
- >>> registry.subscribe([IAnimal], ISausages, 'sausages')
- >>> list(registry.subscriptions([IPoultry], ISausages))
- ['sausages']
-
-And define another subscription adapter::
-
- >>> registry.subscribe([IPoultry], INoodles, 'noodles')
- >>> meals = list(registry.subscriptions([IPoultry], IRecipe))
- >>> meals.sort()
- >>> meals
- ['noodles', 'sausages']
-
- >>> registry.subscribe([IChicken], IKFC, 'kfc')
- >>> meals = list(registry.subscriptions([IChicken], IRecipe))
- >>> meals.sort()
- >>> meals
- ['kfc', 'noodles', 'sausages']
-
-And the answer for poultry hasn't changed::
-
- >>> meals = list(registry.subscriptions([IPoultry], IRecipe))
- >>> meals.sort()
- >>> meals
- ['noodles', 'sausages']
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/ifoo.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/ifoo.py
deleted file mode 100644
index 29a78779..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/ifoo.py
+++ /dev/null
@@ -1,26 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""IFoo test module
-"""
-from zope.interface import Interface
-
-class IFoo(Interface):
- """
- Dummy interface for unit tests.
- """
-
- def bar(baz):
- """
- Just a note.
- """
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m1.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m1.py
deleted file mode 100644
index d311fb40..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m1.py
+++ /dev/null
@@ -1,21 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test module that declares an interface
-"""
-from zope.interface import Interface, moduleProvides
-
-class I1(Interface): pass
-class I2(Interface): pass
-
-moduleProvides(I1, I2)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m2.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m2.py
deleted file mode 100644
index 511cd9ce..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/m2.py
+++ /dev/null
@@ -1,15 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test module that doesn't declare an interface
-"""
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/odd.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/odd.py
deleted file mode 100644
index 04ffa31f..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/odd.py
+++ /dev/null
@@ -1,129 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Odd meta class that doesn't subclass type.
-
-This is used for testing support for ExtensionClass in new interfaces.
-
- >>> class A(object):
- ... __metaclass__ = MetaClass
- ... a = 1
- ...
- >>> A.__name__
- 'A'
- >>> A.__bases__ == (object,)
- True
- >>> class B(object):
- ... __metaclass__ = MetaClass
- ... b = 1
- ...
- >>> class C(A, B): pass
- ...
- >>> C.__name__
- 'C'
- >>> int(C.__bases__ == (A, B))
- 1
- >>> a = A()
- >>> aa = A()
- >>> a.a
- 1
- >>> aa.a
- 1
- >>> aa.a = 2
- >>> a.a
- 1
- >>> aa.a
- 2
- >>> c = C()
- >>> c.a
- 1
- >>> c.b
- 1
- >>> c.b = 2
- >>> c.b
- 2
- >>> C.c = 1
- >>> c.c
- 1
- >>> import sys
- >>> if sys.version[0] == '2': # This test only makes sense under Python 2.x
- ... from types import ClassType
- ... assert not isinstance(C, (type, ClassType))
-
- >>> int(C.__class__.__class__ is C.__class__)
- 1
-"""
-
-# class OddClass is an odd meta class
-
-class MetaMetaClass(type):
-
- def __getattribute__(self, name):
- if name == '__class__':
- return self
- return type.__getattribute__(self, name)
-
-
-class MetaClass(object):
- """Odd classes
- """
- __metaclass__ = MetaMetaClass
-
- def __init__(self, name, bases, dict):
- self.__name__ = name
- self.__bases__ = bases
- self.__dict__.update(dict)
-
- def __call__(self):
- return OddInstance(self)
-
- def __getattr__(self, name):
- for b in self.__bases__:
- v = getattr(b, name, self)
- if v is not self:
- return v
- raise AttributeError(name)
-
- def __repr__(self):
- return "<odd class %s at %s>" % (self.__name__, hex(id(self)))
-
-class OddInstance(object):
-
- def __init__(self, cls):
- self.__dict__['__class__'] = cls
-
- def __getattribute__(self, name):
- dict = object.__getattribute__(self, '__dict__')
- if name == '__dict__':
- return dict
- v = dict.get(name, self)
- if v is not self:
- return v
- return getattr(dict['__class__'], name)
-
- def __setattr__(self, name, v):
- self.__dict__[name] = v
-
- def __delattr__(self, name):
- del self.__dict__[name]
-
- def __repr__(self):
- return "<odd %s instance at %s>" % (
- self.__class__.__name__, hex(id(self)))
-
-
-
-# DocTest:
-if __name__ == "__main__":
- import doctest, __main__
- doctest.testmod(__main__, isprivate=lambda *a: False)
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_adapter.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_adapter.py
deleted file mode 100644
index 30a85982..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_adapter.py
+++ /dev/null
@@ -1,412 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Adapter registry tests
-"""
-import doctest
-import unittest
-import zope.interface
-from zope.interface.adapter import AdapterRegistry
-
-
-class IF0(zope.interface.Interface):
- pass
-class IF1(IF0):
- pass
-
-class IB0(zope.interface.Interface):
- pass
-class IB1(IB0):
- pass
-
-class IR0(zope.interface.Interface):
- pass
-class IR1(IR0):
- pass
-
-def test_multi_adapter_get_best_match():
- """
- >>> registry = AdapterRegistry()
-
- >>> class IB2(IB0):
- ... pass
- >>> class IB3(IB2, IB1):
- ... pass
- >>> class IB4(IB1, IB2):
- ... pass
-
- >>> registry.register([None, IB1], IR0, '', 'A1')
- >>> registry.register([None, IB0], IR0, '', 'A0')
- >>> registry.register([None, IB2], IR0, '', 'A2')
-
- >>> registry.lookup((IF1, IB1), IR0, '')
- 'A1'
- >>> registry.lookup((IF1, IB2), IR0, '')
- 'A2'
- >>> registry.lookup((IF1, IB0), IR0, '')
- 'A0'
- >>> registry.lookup((IF1, IB3), IR0, '')
- 'A2'
- >>> registry.lookup((IF1, IB4), IR0, '')
- 'A1'
- """
-
-def test_multi_adapter_lookupAll_get_best_matches():
- """
- >>> registry = AdapterRegistry()
-
- >>> class IB2(IB0):
- ... pass
- >>> class IB3(IB2, IB1):
- ... pass
- >>> class IB4(IB1, IB2):
- ... pass
-
- >>> registry.register([None, IB1], IR0, '', 'A1')
- >>> registry.register([None, IB0], IR0, '', 'A0')
- >>> registry.register([None, IB2], IR0, '', 'A2')
-
- >>> tuple(registry.lookupAll((IF1, IB1), IR0))[0][1]
- 'A1'
- >>> tuple(registry.lookupAll((IF1, IB2), IR0))[0][1]
- 'A2'
- >>> tuple(registry.lookupAll((IF1, IB0), IR0))[0][1]
- 'A0'
- >>> tuple(registry.lookupAll((IF1, IB3), IR0))[0][1]
- 'A2'
- >>> tuple(registry.lookupAll((IF1, IB4), IR0))[0][1]
- 'A1'
- """
-
-
-def test_multi_adapter_w_default():
- """
- >>> registry = AdapterRegistry()
-
- >>> registry.register([None, None], IB1, 'bob', 'A0')
-
- >>> registry.lookup((IF1, IR1), IB0, 'bob')
- 'A0'
-
- >>> registry.register([None, IR0], IB1, 'bob', 'A1')
-
- >>> registry.lookup((IF1, IR1), IB0, 'bob')
- 'A1'
-
- >>> registry.lookup((IF1, IR1), IB0, 'bruce')
-
- >>> registry.register([None, IR1], IB1, 'bob', 'A2')
- >>> registry.lookup((IF1, IR1), IB0, 'bob')
- 'A2'
- """
-
-def test_multi_adapter_w_inherited_and_multiple_registrations():
- """
- >>> registry = AdapterRegistry()
-
- >>> class IX(zope.interface.Interface):
- ... pass
-
- >>> registry.register([IF0, IR0], IB1, 'bob', 'A1')
- >>> registry.register([IF1, IX], IB1, 'bob', 'AX')
-
- >>> registry.lookup((IF1, IR1), IB0, 'bob')
- 'A1'
- """
-
-def test_named_adapter_with_default():
- """Query a named simple adapter
-
- >>> registry = AdapterRegistry()
-
- If we ask for a named adapter, we won't get a result unless there
- is a named adapter, even if the object implements the interface:
-
- >>> registry.lookup([IF1], IF0, 'bob')
-
- >>> registry.register([None], IB1, 'bob', 'A1')
- >>> registry.lookup([IF1], IB0, 'bob')
- 'A1'
-
- >>> registry.lookup([IF1], IB0, 'bruce')
-
- >>> registry.register([None], IB0, 'bob', 'A2')
- >>> registry.lookup([IF1], IB0, 'bob')
- 'A2'
- """
-
-def test_multi_adapter_gets_closest_provided():
- """
- >>> registry = AdapterRegistry()
- >>> registry.register([IF1, IR0], IB0, 'bob', 'A1')
- >>> registry.register((IF1, IR0), IB1, 'bob', 'A2')
- >>> registry.lookup((IF1, IR1), IB0, 'bob')
- 'A1'
-
- >>> registry = AdapterRegistry()
- >>> registry.register([IF1, IR0], IB1, 'bob', 'A2')
- >>> registry.register([IF1, IR0], IB0, 'bob', 'A1')
- >>> registry.lookup([IF1, IR0], IB0, 'bob')
- 'A1'
-
- >>> registry = AdapterRegistry()
- >>> registry.register([IF1, IR0], IB0, 'bob', 'A1')
- >>> registry.register([IF1, IR1], IB1, 'bob', 'A2')
- >>> registry.lookup([IF1, IR1], IB0, 'bob')
- 'A2'
-
- >>> registry = AdapterRegistry()
- >>> registry.register([IF1, IR1], IB1, 'bob', 2)
- >>> registry.register([IF1, IR0], IB0, 'bob', 1)
- >>> registry.lookup([IF1, IR1], IB0, 'bob')
- 2
- """
-
-def test_multi_adapter_check_non_default_dont_hide_default():
- """
- >>> registry = AdapterRegistry()
-
- >>> class IX(zope.interface.Interface):
- ... pass
-
-
- >>> registry.register([None, IR0], IB0, 'bob', 1)
- >>> registry.register([IF1, IX], IB0, 'bob', 2)
- >>> registry.lookup([IF1, IR1], IB0, 'bob')
- 1
- """
-
-def test_adapter_hook_with_factory_producing_None():
- """
- >>> registry = AdapterRegistry()
- >>> default = object()
-
- >>> class Object1(object):
- ... zope.interface.implements(IF0)
- >>> class Object2(object):
- ... zope.interface.implements(IF0)
-
- >>> def factory(context):
- ... if isinstance(context, Object1):
- ... return 'adapter'
- ... return None
-
- >>> registry.register([IF0], IB0, '', factory)
-
- >>> registry.adapter_hook(IB0, Object1())
- 'adapter'
- >>> registry.adapter_hook(IB0, Object2()) is None
- True
- >>> registry.adapter_hook(IB0, Object2(), default=default) is default
- True
- """
-
-def test_adapter_registry_update_upon_interface_bases_change():
- """
- Let's first create a adapter registry and a simple adaptation hook:
-
- >>> globalRegistry = AdapterRegistry()
-
- >>> def _hook(iface, ob, lookup=globalRegistry.lookup1):
- ... factory = lookup(zope.interface.providedBy(ob), iface)
- ... if factory is None:
- ... return None
- ... else:
- ... return factory(ob)
-
- >>> zope.interface.interface.adapter_hooks.append(_hook)
-
- Now we create some interfaces and an implementation:
-
- >>> class IX(zope.interface.Interface):
- ... pass
-
- >>> class IY(zope.interface.Interface):
- ... pass
-
- >>> class X(object):
- ... pass
-
- >>> class Y(object):
- ... zope.interface.implements(IY)
- ... def __init__(self, original):
- ... self.original=original
-
- and register an adapter:
-
- >>> globalRegistry.register((IX,), IY, '', Y)
-
- at first, we still expect the adapter lookup from `X` to `IY` to fail:
-
- >>> IY(X()) #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt',
- <zope.interface.tests.test_adapter.X object at ...>,
- <InterfaceClass zope.interface.tests.test_adapter.IY>)
-
- But after we declare an interface on the class `X`, it should pass:
-
- >>> zope.interface.classImplementsOnly(X, IX)
-
- >>> IY(X()) #doctest: +ELLIPSIS
- <zope.interface.tests.test_adapter.Y object at ...>
-
- >>> hook = zope.interface.interface.adapter_hooks.pop()
- """
-
-
-def test_changing_declarations():
- """
-
- If we change declarations for a class, those adapter lookup should
- eflect the changes:
-
- >>> class I1(zope.interface.Interface):
- ... pass
- >>> class I2(zope.interface.Interface):
- ... pass
-
- >>> registry = AdapterRegistry()
- >>> registry.register([I1], I2, '', 42)
-
- >>> class C:
- ... pass
-
- >>> registry.lookup([zope.interface.implementedBy(C)], I2, '')
-
- >>> zope.interface.classImplements(C, I1)
-
- >>> registry.lookup([zope.interface.implementedBy(C)], I2, '')
- 42
- """
-
-def test_correct_multi_adapter_lookup():
- """
- >>> registry = AdapterRegistry()
- >>> registry.register([IF0, IB1], IR0, '', 'A01')
- >>> registry.register([IF1, IB0], IR0, '', 'A10')
- >>> registry.lookup((IF1, IB1), IR0, '')
- 'A10'
- """
-
-def test_duplicate_bases():
- """
-There was a bug that caused problems if a spec had multiple bases:
-
- >>> class I(zope.interface.Interface):
- ... pass
- >>> class I2(I, I):
- ... pass
- >>> registry = AdapterRegistry()
- >>> registry.register([I2], IR0, 'x', 'X')
- >>> registry.lookup((I2, ), IR0, 'x')
- 'X'
- >>> registry.register([I2], IR0, 'y', 'Y')
- >>> registry.lookup((I2, ), IR0, 'x')
- 'X'
- >>> registry.lookup((I2, ), IR0, 'y')
- 'Y'
-"""
-
-def test_register_objects_with_cmp():
- """
- The registry should never use == as that will tend to fail when
- objects are picky about what they are compared with:
-
- >>> class Picky:
- ... def __cmp__(self, other):
- ... raise TypeError("I\'m too picky for comparison!")
- >>> class I(zope.interface.Interface):
- ... pass
- >>> class I2(I, I):
- ... pass
-
- >>> registry = AdapterRegistry()
- >>> picky = Picky()
- >>> registry.register([I2], IR0, '', picky)
- >>> registry.unregister([I2], IR0, '', picky)
-
- >>> registry.subscribe([I2], IR0, picky)
- >>> registry.unsubscribe([I2], IR0, picky)
-
- """
-
-def test_unregister_cleans_up_empties():
- """
- >>> class I(zope.interface.Interface):
- ... pass
- >>> class IP(zope.interface.Interface):
- ... pass
- >>> class C(object):
- ... pass
-
- >>> registry = AdapterRegistry()
-
- >>> registry.register([], IP, '', C)
- >>> registry.register([I], IP, '', C)
- >>> registry.register([I], IP, 'name', C)
- >>> registry.register([I, I], IP, '', C)
- >>> len(registry._adapters)
- 3
- >>> map(len, registry._adapters)
- [1, 1, 1]
-
- >>> registry.unregister([], IP, '', C)
- >>> registry.unregister([I], IP, '', C)
- >>> registry.unregister([I], IP, 'name', C)
- >>> registry.unregister([I, I], IP, '', C)
- >>> registry._adapters
- []
-
- """
-
-def test_unsubscribe_cleans_up_empties():
- """
- >>> class I1(zope.interface.Interface):
- ... pass
- >>> class I2(zope.interface.Interface):
- ... pass
- >>> class IP(zope.interface.Interface):
- ... pass
-
- >>> registry = AdapterRegistry()
- >>> def handler(event):
- ... pass
-
- >>> registry.subscribe([I1], I1, handler)
- >>> registry.subscribe([I2], I1, handler)
- >>> len(registry._subscribers)
- 2
- >>> map(len, registry._subscribers)
- [0, 2]
-
- >>> registry.unsubscribe([I1], I1, handler)
- >>> registry.unsubscribe([I2], I1, handler)
- >>> registry._subscribers
- []
-
- """
-
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocFileSuite('../adapter.txt', '../adapter.ru.txt',
- '../human.txt', '../human.ru.txt',
- 'foodforthought.txt',
- globs={'__name__': '__main__'}),
- doctest.DocTestSuite(),
- ))
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_advice.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_advice.py
deleted file mode 100644
index f21252e0..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_advice.py
+++ /dev/null
@@ -1,185 +0,0 @@
-
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Tests for advice
-
-This module was adapted from 'protocols.tests.advice', part of the Python
-Enterprise Application Kit (PEAK). Please notify the PEAK authors
-(pje@telecommunity.com and tsarna@sarna.org) if bugs are found or
-Zope-specific changes are required, so that the PEAK version of this module
-can be kept in sync.
-
-PEAK is a Python application framework that interoperates with (but does
-not require) Zope 3 and Twisted. It provides tools for manipulating UML
-models, object-relational persistence, aspect-oriented programming, and more.
-Visit the PEAK home page at http://peak.telecommunity.com for more information.
-"""
-
-import unittest
-from unittest import TestCase, makeSuite, TestSuite
-from zope.interface.advice import addClassAdvisor, determineMetaclass
-from zope.interface.advice import getFrameInfo
-import sys
-
-def ping(log, value):
-
- def pong(klass):
- log.append((value,klass))
- return [klass]
-
- addClassAdvisor(pong)
-
-try:
- from types import ClassType
-
- class ClassicClass:
- __metaclass__ = ClassType
- classLevelFrameInfo = getFrameInfo(sys._getframe())
-except ImportError:
- pass
-
-class NewStyleClass:
- __metaclass__ = type
- classLevelFrameInfo = getFrameInfo(sys._getframe())
-
-moduleLevelFrameInfo = getFrameInfo(sys._getframe())
-
-class FrameInfoTest(TestCase):
-
- classLevelFrameInfo = getFrameInfo(sys._getframe())
-
- def checkModuleInfo(self):
- kind, module, f_locals, f_globals = moduleLevelFrameInfo
- self.assertEquals(kind, "module")
- for d in module.__dict__, f_locals, f_globals:
- self.assert_(d is globals())
-
- def checkClassicClassInfo(self):
- kind, module, f_locals, f_globals = ClassicClass.classLevelFrameInfo
- self.assertEquals(kind, "class")
-
- self.assert_(f_locals is ClassicClass.__dict__) # ???
- for d in module.__dict__, f_globals:
- self.assert_(d is globals())
-
- def checkNewStyleClassInfo(self):
- kind, module, f_locals, f_globals = NewStyleClass.classLevelFrameInfo
- self.assertEquals(kind, "class")
-
- for d in module.__dict__, f_globals:
- self.assert_(d is globals())
-
- def checkCallInfo(self):
- kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
- self.assertEquals(kind, "function call")
- self.assert_(f_locals is locals()) # ???
- for d in module.__dict__, f_globals:
- self.assert_(d is globals())
-
-
-class AdviceTests(TestCase):
-
- def checkOrder(self):
- log = []
- class Foo(object):
- ping(log, 1)
- ping(log, 2)
- ping(log, 3)
-
- # Strip the list nesting
- for i in 1,2,3:
- self.assert_(isinstance(Foo, list))
- Foo, = Foo
-
- self.assertEquals(log, [(1, Foo), (2, [Foo]), (3, [[Foo]])])
-
- def TODOcheckOutside(self):
- # Disabled because the check does not work with doctest tests.
- try:
- ping([], 1)
- except SyntaxError:
- pass
- else:
- raise AssertionError(
- "Should have detected advice outside class body"
- )
-
- def checkDoubleType(self):
- if sys.hexversion >= 0x02030000:
- return # you can't duplicate bases in 2.3
- class aType(type,type):
- ping([],1)
- aType, = aType
- self.assert_(aType.__class__ is type)
-
- def checkSingleExplicitMeta(self):
-
- class M(type):
- pass
-
- class C(M):
- __metaclass__ = M
- ping([],1)
-
- C, = C
- self.assert_(C.__class__ is M)
-
-
- def checkMixedMetas(self):
-
- class M1(type): pass
- class M2(type): pass
-
- class B1: __metaclass__ = M1
- class B2: __metaclass__ = M2
-
- try:
- class C(B1,B2):
- ping([],1)
- except TypeError:
- pass
- else:
- raise AssertionError("Should have gotten incompatibility error")
-
- class M3(M1,M2): pass
-
- class C(B1,B2):
- __metaclass__ = M3
- ping([],1)
-
- self.assert_(isinstance(C,list))
- C, = C
- self.assert_(isinstance(C,M3))
-
- def checkMetaOfClass(self):
-
- class metameta(type):
- pass
-
- class meta(type):
- __metaclass__ = metameta
-
- self.assertEquals(determineMetaclass((meta, type)), metameta)
-
-TestClasses = (AdviceTests, FrameInfoTest)
-
-def test_suite():
- if sys.version[0] == '2':
- return TestSuite([makeSuite(t,'check') for t in TestClasses])
- else:
- # Advise metaclasses doesn't work in Python 3
- return TestSuite([])
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_declarations.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_declarations.py
deleted file mode 100644
index 6c8455c7..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_declarations.py
+++ /dev/null
@@ -1,428 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test the new API for making and checking interface declarations
-"""
-import doctest
-import unittest
-
-from zope.interface import Interface, implements
-from zope.interface import directlyProvides, providedBy
-from zope.interface import classImplements, implementedBy, implementsOnly
-
-class I1(Interface): pass
-class I2(Interface): pass
-class I3(Interface): pass
-class I4(Interface): pass
-class I5(Interface): pass
-
-class A(object):
- implements(I1)
-class B(object):
- implements(I2)
-class C(A, B):
- implements(I3)
-
-class COnly(A, B):
- implementsOnly(I3)
-
-class COnly_old(A, B):
- __implemented__ = I3
-
-class D(COnly):
- implements(I5)
-
-def test_ObjectSpecification_Simple():
- """
- >>> c = C()
- >>> directlyProvides(c, I4)
- >>> [i.__name__ for i in providedBy(c)]
- ['I4', 'I3', 'I1', 'I2']
- """
-
-def test_ObjectSpecification_Simple_w_only():
- """
- >>> c = COnly()
- >>> directlyProvides(c, I4)
- >>> [i.__name__ for i in providedBy(c)]
- ['I4', 'I3']
- """
-
-def test_ObjectSpecification_Simple_old_style():
- """
- >>> c = COnly_old()
- >>> directlyProvides(c, I4)
- >>> [i.__name__ for i in providedBy(c)]
- ['I4', 'I3']
- """
-
-
-class Test(unittest.TestCase):
-
- # Note that most of the tests are in the doc strings of the
- # declarations module.
-
- def test_backward_compat(self):
-
- class C1(object): __implemented__ = I1
- class C2(C1): __implemented__ = I2, I5
- class C3(C2): __implemented__ = I3, C2.__implemented__
-
- self.assert_(C3.__implemented__.__class__ is tuple)
-
- self.assertEqual(
- [i.getName() for i in providedBy(C3())],
- ['I3', 'I2', 'I5'],
- )
-
- class C4(C3):
- implements(I4)
-
- self.assertEqual(
- [i.getName() for i in providedBy(C4())],
- ['I4', 'I3', 'I2', 'I5'],
- )
-
- self.assertEqual(
- [i.getName() for i in C4.__implemented__],
- ['I4', 'I3', 'I2', 'I5'],
- )
-
- # Note that C3.__implemented__ should now be a sequence of interfaces
- self.assertEqual(
- [i.getName() for i in C3.__implemented__],
- ['I3', 'I2', 'I5'],
- )
- self.failIf(C3.__implemented__.__class__ is tuple)
-
- def test_module(self):
- from zope.interface.tests import m1, m2
- #import zope.interface.tests.m2
- directlyProvides(m2,
- m1.I1,
- m1.I2,
- )
- self.assertEqual(list(providedBy(m1)),
- list(providedBy(m2)),
- )
-
- def test_builtins(self):
- # Setup
-
- intspec = implementedBy(int)
- olddeclared = intspec.declared
-
- classImplements(int, I1)
- class myint(int):
- implements(I2)
-
- x = 42
- self.assertEqual([i.getName() for i in providedBy(x)],
- ['I1'])
-
- x = myint(42)
- directlyProvides(x, I3)
- self.assertEqual([i.getName() for i in providedBy(x)],
- ['I3', 'I2', 'I1'])
-
- # cleanup
- intspec.declared = olddeclared
- classImplements(int)
-
- x = 42
- self.assertEqual([i.getName() for i in providedBy(x)],
- [])
-
-
-def test_signature_w_no_class_interfaces():
- """
- >>> from zope.interface import *
- >>> class C(object):
- ... pass
- >>> c = C()
- >>> list(providedBy(c))
- []
-
- >>> class I(Interface):
- ... pass
- >>> directlyProvides(c, I)
- >>> list(providedBy(c)) == list(directlyProvidedBy(c))
- 1
- """
-
-def test_classImplement_on_deeply_nested_classes():
- """This test is in response to a bug found, which is why it's a bit
- contrived
-
- >>> from zope.interface import *
- >>> class B1(object):
- ... pass
- >>> class B2(B1):
- ... pass
- >>> class B3(B2):
- ... pass
- >>> class D(object):
- ... implements()
- >>> class S(B3, D):
- ... implements()
-
- This failed due to a bug in the code for finding __providedBy__
- descriptors for old-style classes.
-
- """
-
-def test_pickle_provides_specs():
- """
- >>> from pickle import dumps, loads
- >>> a = A()
- >>> I2.providedBy(a)
- 0
- >>> directlyProvides(a, I2)
- >>> I2.providedBy(a)
- 1
- >>> a2 = loads(dumps(a))
- >>> I2.providedBy(a2)
- 1
-
- """
-
-def test_that_we_dont_inherit_class_provides():
- """
- >>> from zope.interface import classProvides
- >>> class X(object):
- ... classProvides(I1)
- >>> class Y(X):
- ... pass
- >>> [i.__name__ for i in X.__provides__]
- ['I1']
- >>> Y.__provides__
- Traceback (most recent call last):
- ...
- AttributeError: __provides__
-
- """
-
-def test_that_we_dont_inherit_provides_optimizations():
- """
-
- When we make a declaration for a class, we install a __provides__
- descriptors that provides a default for instances that don't have
- instance-specific declarations:
-
- >>> class A(object):
- ... implements(I1)
-
- >>> class B(object):
- ... implements(I2)
-
- >>> [i.__name__ for i in A().__provides__]
- ['I1']
- >>> [i.__name__ for i in B().__provides__]
- ['I2']
-
- But it's important that we don't use this for subclasses without
- declarations. This would cause incorrect results:
-
- >>> class X(A, B):
- ... pass
-
- >>> X().__provides__
- Traceback (most recent call last):
- ...
- AttributeError: __provides__
-
- However, if we "induce" a declaration, by calling implementedBy
- (even indirectly through providedBy):
-
- >>> [i.__name__ for i in providedBy(X())]
- ['I1', 'I2']
-
-
- then the optimization will work:
-
- >>> [i.__name__ for i in X().__provides__]
- ['I1', 'I2']
-
- """
-
-def test_classProvides_before_implements():
- """Special descriptor for class __provides__
-
- The descriptor caches the implementedBy info, so that
- we can get declarations for objects without instance-specific
- interfaces a bit quicker.
-
- For example::
-
- >>> from zope.interface import Interface, classProvides
- >>> class IFooFactory(Interface):
- ... pass
- >>> class IFoo(Interface):
- ... pass
- >>> class C(object):
- ... classProvides(IFooFactory)
- ... implements(IFoo)
- >>> [i.getName() for i in C.__provides__]
- ['IFooFactory']
-
- >>> [i.getName() for i in C().__provides__]
- ['IFoo']
- """
-
-def test_getting_spec_for_proxied_builtin_class():
- """
-
- In general, we should be able to get a spec
- for a proxied class if someone has declared or
- asked for a spec before.
-
- We don't want to depend on proxies in this (zope.interface)
- package, but we do want to work with proxies. Proxies have the
- effect that a class's __dict__ cannot be gotten. Further, for
- built-in classes, we can't save, and thus, cannot get, any class
- attributes. We'll emulate this by treating a plain object as a class:
-
- >>> cls = object()
-
- We'll create an implements specification:
-
- >>> import zope.interface.declarations
- >>> impl = zope.interface.declarations.Implements(I1, I2)
-
- Now, we'll emulate a declaration for a built-in type by putting
- it in BuiltinImplementationSpecifications:
-
- >>> zope.interface.declarations.BuiltinImplementationSpecifications[
- ... cls] = impl
-
- Now, we should be able to get it back:
-
- >>> implementedBy(cls) is impl
- True
-
- Of course, we don't want to leave it there. :)
-
- >>> del zope.interface.declarations.BuiltinImplementationSpecifications[
- ... cls]
-
- """
-
-def test_declaration_get():
- """
- We can get definitions from a declaration:
-
- >>> import zope.interface
- >>> class I1(zope.interface.Interface):
- ... a11 = zope.interface.Attribute('a11')
- ... a12 = zope.interface.Attribute('a12')
- >>> class I2(zope.interface.Interface):
- ... a21 = zope.interface.Attribute('a21')
- ... a22 = zope.interface.Attribute('a22')
- ... a12 = zope.interface.Attribute('a212')
- >>> class I11(I1):
- ... a11 = zope.interface.Attribute('a111')
-
- >>> decl = zope.interface.Declaration(I11, I2)
- >>> decl.get('a11') is I11.get('a11')
- True
- >>> decl.get('a12') is I1.get('a12')
- True
- >>> decl.get('a21') is I2.get('a21')
- True
- >>> decl.get('a22') is I2.get('a22')
- True
- >>> decl.get('a')
- >>> decl.get('a', 42)
- 42
-
- We get None even with no interfaces:
-
- >>> decl = zope.interface.Declaration()
- >>> decl.get('a11')
- >>> decl.get('a11', 42)
- 42
-
- We get new data if e change interface bases:
-
- >>> decl.__bases__ = I11, I2
- >>> decl.get('a11') is I11.get('a11')
- True
- """
-
-def test_classImplements_after_classImplementsOnly_issue_402():
- """http://www.zope.org/Collectors/Zope3-dev/402
-
->>> from zope.interface import *
->>> class I1(Interface):
-... pass
->>> class I2(Interface):
-... pass
->>> class C:
-... implements(I1)
->>> class C2:
-... implementsOnly(I2)
->>> class I3(Interface):
-... pass
-
->>> [i.__name__ for i in providedBy(C2()).__iro__]
-['I2', 'Interface']
-
->>> classImplements(C2, I3)
->>> [i.__name__ for i in providedBy(C2()).__iro__]
-['I2', 'I3', 'Interface']
-
->>> class I4(Interface):
-... pass
->>> classImplements(C2, I4)
->>> [i.__name__ for i in providedBy(C2()).__iro__]
-['I2', 'I3', 'I4', 'Interface']
-
-
-"""
-
-def test_picklability_of_implements_specifications():
- """
-
- Sometimes, we need to pickle implements specs. We should be able
- to do so as long as the class is picklable.
-
- >>> import pickle
- >>> pickle.loads(pickle.dumps(implementedBy(C))) is implementedBy(C)
- True
-
-
- """
-
-def test_provided_by_with_slots():
- """
-
- This is an edge case: if the __slots__ of a class contain '__provides__',
- using providedBy() on that class should still work (this occurs, for
- example, when providing an adapter for a concrete class.)
-
- >>> import zope.interface
- >>> class Slotted(object):
- ... __slots__ = ('__provides__')
- >>> class IFoo(zope.interface.Interface):
- ... pass
- >>> IFoo.providedBy(Slotted)
- False
-
- """
-
-def test_suite():
- return unittest.TestSuite((
- unittest.makeSuite(Test),
- doctest.DocTestSuite("zope.interface.declarations"),
- doctest.DocTestSuite(),
- ))
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_document.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_document.py
deleted file mode 100644
index a2653b3f..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_document.py
+++ /dev/null
@@ -1,69 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Documentation tests.
-"""
-from unittest import TestCase, main, makeSuite
-
-from zope.interface import Interface, Attribute
-
-class Test(TestCase):
-
- def testBlech(self):
- from zope.interface.document import asStructuredText
-
- self.assertEqual(asStructuredText(I2), '''\
-I2
-
- I2 doc
-
- This interface extends:
-
- o _I1
-
- Attributes:
-
- a1 -- no documentation
-
- a2 -- a2 doc
-
- Methods:
-
- f21() -- f21 doc
-
- f22() -- no documentation
-
- f23() -- f23 doc
-
-''')
-
-
-def test_suite():
- return makeSuite(Test)
-
-class _I1(Interface):
- def f11(): pass
- def f12(): pass
-
-class I2(_I1):
- "I2 doc"
-
- a1 = Attribute('a1')
- a2 = Attribute('a2', 'a2 doc')
-
- def f21(): "f21 doc"
- def f22(): pass
- def f23(): "f23 doc"
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_element.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_element.py
deleted file mode 100644
index 66724a67..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_element.py
+++ /dev/null
@@ -1,41 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test Element meta-class.
-"""
-
-import unittest
-from zope.interface.interface import Element
-
-class TestElement(unittest.TestCase):
-
- def test_taggedValues(self):
- """Test that we can update tagged values of more than one element
- """
-
- e1 = Element("foo")
- e2 = Element("bar")
- e1.setTaggedValue("x", 1)
- e2.setTaggedValue("x", 2)
- self.assertEqual(e1.getTaggedValue("x"), 1)
- self.assertEqual(e2.getTaggedValue("x"), 2)
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestElement))
- return suite
-
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_interface.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_interface.py
deleted file mode 100644
index 226e59c8..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_interface.py
+++ /dev/null
@@ -1,473 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test Interface implementation
-"""
-import doctest
-import unittest
-import sys
-
-class InterfaceTests(unittest.TestCase):
-
- def _makeDerivedInterface(self):
- from zope.interface import Interface
- from zope.interface import Attribute
- class _I1(Interface):
-
- a1 = Attribute("This is an attribute")
-
- def f11():
- pass
- def f12():
- pass
- f12.optional = 1
-
- class _I1_(_I1):
- pass
-
- class _I1__(_I1_):
- pass
-
- class _I2(_I1__):
- def f21():
- pass
- def f22():
- pass
- f23 = f22
-
- return _I2
-
- def testInterfaceSetOnAttributes(self):
- from zope.interface.tests.unitfixtures import FooInterface
- self.assertEqual(FooInterface['foobar'].interface,
- FooInterface)
- self.assertEqual(FooInterface['aMethod'].interface,
- FooInterface)
-
- def testClassImplements(self):
- from zope.interface.tests.unitfixtures import A
- from zope.interface.tests.unitfixtures import B
- from zope.interface.tests.unitfixtures import C
- from zope.interface.tests.unitfixtures import D
- from zope.interface.tests.unitfixtures import E
- from zope.interface.tests.unitfixtures import I1
- from zope.interface.tests.unitfixtures import I2
- from zope.interface.tests.unitfixtures import IC
- self.assert_(IC.implementedBy(C))
-
- self.assert_(I1.implementedBy(A))
- self.assert_(I1.implementedBy(B))
- self.assert_(not I1.implementedBy(C))
- self.assert_(I1.implementedBy(D))
- self.assert_(I1.implementedBy(E))
-
- self.assert_(not I2.implementedBy(A))
- self.assert_(I2.implementedBy(B))
- self.assert_(not I2.implementedBy(C))
-
- # No longer after interfacegeddon
- # self.assert_(not I2.implementedBy(D))
-
- self.assert_(not I2.implementedBy(E))
-
- def testUtil(self):
- from zope.interface import implementedBy
- from zope.interface import providedBy
- from zope.interface.tests.unitfixtures import A
- from zope.interface.tests.unitfixtures import B
- from zope.interface.tests.unitfixtures import C
- from zope.interface.tests.unitfixtures import I1
- from zope.interface.tests.unitfixtures import I2
- from zope.interface.tests.unitfixtures import IC
- self.assert_(IC in implementedBy(C))
- self.assert_(I1 in implementedBy(A))
- self.assert_(not I1 in implementedBy(C))
- self.assert_(I2 in implementedBy(B))
- self.assert_(not I2 in implementedBy(C))
-
- self.assert_(IC in providedBy(C()))
- self.assert_(I1 in providedBy(A()))
- self.assert_(not I1 in providedBy(C()))
- self.assert_(I2 in providedBy(B()))
- self.assert_(not I2 in providedBy(C()))
-
-
- def testObjectImplements(self):
- from zope.interface.tests.unitfixtures import A
- from zope.interface.tests.unitfixtures import B
- from zope.interface.tests.unitfixtures import C
- from zope.interface.tests.unitfixtures import D
- from zope.interface.tests.unitfixtures import E
- from zope.interface.tests.unitfixtures import I1
- from zope.interface.tests.unitfixtures import I2
- from zope.interface.tests.unitfixtures import IC
- self.assert_(IC.providedBy(C()))
-
- self.assert_(I1.providedBy(A()))
- self.assert_(I1.providedBy(B()))
- self.assert_(not I1.providedBy(C()))
- self.assert_(I1.providedBy(D()))
- self.assert_(I1.providedBy(E()))
-
- self.assert_(not I2.providedBy(A()))
- self.assert_(I2.providedBy(B()))
- self.assert_(not I2.providedBy(C()))
-
- # Not after interface geddon
- # self.assert_(not I2.providedBy(D()))
-
- self.assert_(not I2.providedBy(E()))
-
- def testDeferredClass(self):
- from zope.interface.tests.unitfixtures import A
- from zope.interface.exceptions import BrokenImplementation
- a = A()
- self.assertRaises(BrokenImplementation, a.ma)
-
-
- def testInterfaceExtendsInterface(self):
- from zope.interface.tests.unitfixtures import BazInterface
- from zope.interface.tests.unitfixtures import BarInterface
- from zope.interface.tests.unitfixtures import BobInterface
- from zope.interface.tests.unitfixtures import FunInterface
- self.assert_(BazInterface.extends(BobInterface))
- self.assert_(BazInterface.extends(BarInterface))
- self.assert_(BazInterface.extends(FunInterface))
- self.assert_(not BobInterface.extends(FunInterface))
- self.assert_(not BobInterface.extends(BarInterface))
- self.assert_(BarInterface.extends(FunInterface))
- self.assert_(not BarInterface.extends(BazInterface))
-
- def testVerifyImplementation(self):
- from zope.interface.verify import verifyClass
- from zope.interface import Interface
- from zope.interface.tests.unitfixtures import Foo
- from zope.interface.tests.unitfixtures import FooInterface
- from zope.interface.tests.unitfixtures import I1
- self.assert_(verifyClass(FooInterface, Foo))
- self.assert_(Interface.providedBy(I1))
-
- def test_names(self):
- iface = self._makeDerivedInterface()
- names = list(iface.names())
- names.sort()
- self.assertEqual(names, ['f21', 'f22', 'f23'])
- all = list(iface.names(all=True))
- all.sort()
- self.assertEqual(all, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23'])
-
- def test_namesAndDescriptions(self):
- iface = self._makeDerivedInterface()
- names = [nd[0] for nd in iface.namesAndDescriptions()]
- names.sort()
- self.assertEqual(names, ['f21', 'f22', 'f23'])
- names = [nd[0] for nd in iface.namesAndDescriptions(1)]
- names.sort()
- self.assertEqual(names, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23'])
-
- for name, d in iface.namesAndDescriptions(1):
- self.assertEqual(name, d.__name__)
-
- def test_getDescriptionFor(self):
- iface = self._makeDerivedInterface()
- self.assertEqual(iface.getDescriptionFor('f11').__name__, 'f11')
- self.assertEqual(iface.getDescriptionFor('f22').__name__, 'f22')
- self.assertEqual(iface.queryDescriptionFor('f33', self), self)
- self.assertRaises(KeyError, iface.getDescriptionFor, 'f33')
-
- def test___getitem__(self):
- iface = self._makeDerivedInterface()
- self.assertEqual(iface['f11'].__name__, 'f11')
- self.assertEqual(iface['f22'].__name__, 'f22')
- self.assertEqual(iface.get('f33', self), self)
- self.assertRaises(KeyError, iface.__getitem__, 'f33')
-
- def test___contains__(self):
- iface = self._makeDerivedInterface()
- self.failUnless('f11' in iface)
- self.failIf('f33' in iface)
-
- def test___iter__(self):
- iface = self._makeDerivedInterface()
- names = list(iter(iface))
- names.sort()
- self.assertEqual(names, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23'])
-
- def testAttr(self):
- iface = self._makeDerivedInterface()
- description = iface.getDescriptionFor('a1')
- self.assertEqual(description.__name__, 'a1')
- self.assertEqual(description.__doc__, 'This is an attribute')
-
- def testFunctionAttributes(self):
- # Make sure function attributes become tagged values.
- from zope.interface import Interface
- class ITest(Interface):
- def method():
- pass
- method.optional = 1
-
- method = ITest['method']
- self.assertEqual(method.getTaggedValue('optional'), 1)
-
- def testInvariant(self):
- from zope.interface.exceptions import Invalid
- from zope.interface import directlyProvides
- from zope.interface.tests.unitfixtures import BarGreaterThanFoo
- from zope.interface.tests.unitfixtures import ifFooThenBar
- from zope.interface.tests.unitfixtures import IInvariant
- from zope.interface.tests.unitfixtures import InvariantC
- from zope.interface.tests.unitfixtures import ISubInvariant
- # set up
- o = InvariantC()
- directlyProvides(o, IInvariant)
- # a helper
- def errorsEqual(self, o, error_len, error_msgs, iface=None):
- if iface is None:
- iface = IInvariant
- self.assertRaises(Invalid, iface.validateInvariants, o)
- e = []
- try:
- iface.validateInvariants(o, e)
- except Invalid, error:
- self.assertEquals(error.args[0], e)
- else:
- self._assert(0) # validateInvariants should always raise
- # Invalid
- self.assertEquals(len(e), error_len)
- msgs = [error.args[0] for error in e]
- msgs.sort()
- for msg in msgs:
- self.assertEquals(msg, error_msgs.pop(0))
- # the tests
- self.assertEquals(IInvariant.getTaggedValue('invariants'),
- [ifFooThenBar])
- self.assertEquals(IInvariant.validateInvariants(o), None)
- o.bar = 27
- self.assertEquals(IInvariant.validateInvariants(o), None)
- o.foo = 42
- self.assertEquals(IInvariant.validateInvariants(o), None)
- del o.bar
- errorsEqual(self, o, 1, ['If Foo, then Bar!'])
- # nested interfaces with invariants:
- self.assertEquals(ISubInvariant.getTaggedValue('invariants'),
- [BarGreaterThanFoo])
- o = InvariantC()
- directlyProvides(o, ISubInvariant)
- o.foo = 42
- # even though the interface has changed, we should still only have one
- # error.
- errorsEqual(self, o, 1, ['If Foo, then Bar!'], ISubInvariant)
- # however, if we set foo to 0 (Boolean False) and bar to a negative
- # number then we'll get the new error
- o.foo = 2
- o.bar = 1
- errorsEqual(self, o, 1, ['Please, Boo MUST be greater than Foo!'],
- ISubInvariant)
- # and if we set foo to a positive number and boo to 0, we'll
- # get both errors!
- o.foo = 1
- o.bar = 0
- errorsEqual(self, o, 2, ['If Foo, then Bar!',
- 'Please, Boo MUST be greater than Foo!'],
- ISubInvariant)
- # for a happy ending, we'll make the invariants happy
- o.foo = 1
- o.bar = 2
- self.assertEquals(IInvariant.validateInvariants(o), None) # woohoo
- # now we'll do two invariants on the same interface,
- # just to make sure that a small
- # multi-invariant interface is at least minimally tested.
- o = InvariantC()
- directlyProvides(o, IInvariant)
- o.foo = 42
- old_invariants = IInvariant.getTaggedValue('invariants')
- invariants = old_invariants[:]
- invariants.append(BarGreaterThanFoo) # if you really need to mutate,
- # then this would be the way to do it. Probably a bad idea, though. :-)
- IInvariant.setTaggedValue('invariants', invariants)
- #
- # even though the interface has changed, we should still only have one
- # error.
- errorsEqual(self, o, 1, ['If Foo, then Bar!'])
- # however, if we set foo to 0 (Boolean False) and bar to a negative
- # number then we'll get the new error
- o.foo = 2
- o.bar = 1
- errorsEqual(self, o, 1, ['Please, Boo MUST be greater than Foo!'])
- # and if we set foo to a positive number and boo to 0, we'll
- # get both errors!
- o.foo = 1
- o.bar = 0
- errorsEqual(self, o, 2, ['If Foo, then Bar!',
- 'Please, Boo MUST be greater than Foo!'])
- # for another happy ending, we'll make the invariants happy again
- o.foo = 1
- o.bar = 2
- self.assertEquals(IInvariant.validateInvariants(o), None) # bliss
- # clean up
- IInvariant.setTaggedValue('invariants', old_invariants)
-
- def test___doc___element(self):
- from zope.interface import Interface
- from zope.interface import Attribute
- class I(Interface):
- "xxx"
-
- self.assertEqual(I.__doc__, "xxx")
- self.assertEqual(list(I), [])
-
- class I(Interface):
- "xxx"
-
- __doc__ = Attribute('the doc')
-
- self.assertEqual(I.__doc__, "")
- self.assertEqual(list(I), ['__doc__'])
-
- def testIssue228(self):
- from zope.interface import Interface
- # Test for http://collector.zope.org/Zope3-dev/228
- if sys.version[0] == '3':
- # No old style classes in Python 3, so the test becomes moot.
- return
- class I(Interface):
- "xxx"
- class Bad:
- __providedBy__ = None
- # Old style classes don't have a '__class__' attribute
- self.failUnlessRaises(AttributeError, I.providedBy, Bad)
-
- def test_comparison_with_None(self):
- from zope.interface import Interface
-
- class IEmpty(Interface):
- pass
-
- self.failUnless(IEmpty < None)
- self.failUnless(IEmpty <= None)
- self.failIf(IEmpty == None)
- self.failUnless(IEmpty != None)
- self.failIf(IEmpty >= None)
- self.failIf(IEmpty > None)
-
- self.failIf(None < IEmpty)
- self.failIf(None <= IEmpty)
- self.failIf(None == IEmpty)
- self.failUnless(None != IEmpty)
- self.failUnless(None >= IEmpty)
- self.failUnless(None > IEmpty)
-
- def test_comparison_with_same_instance(self):
- from zope.interface import Interface
-
- class IEmpty(Interface):
- pass
-
- self.failIf(IEmpty < IEmpty)
- self.failUnless(IEmpty <= IEmpty)
- self.failUnless(IEmpty == IEmpty)
- self.failIf(IEmpty != IEmpty)
- self.failUnless(IEmpty >= IEmpty)
- self.failIf(IEmpty > IEmpty)
-
- def test_hash(self):
- from zope.interface import Interface
-
- class IEmpty(Interface):
- pass
-
- self.assertEqual(hash(IEmpty),
- hash((IEmpty.__name__, IEmpty.__module__)))
-
-
-if sys.version_info >= (2, 4):
-
- def test_invariant_as_decorator():
- """Invaiants can be deined in line
-
- >>> from zope.interface.exceptions import Invalid
- >>> from zope.interface import Interface
- >>> from zope.interface import Attribute
- >>> from zope.interface import implements
- >>> from zope.interface import invariant
- >>> class IRange(Interface):
- ... min = Attribute("Lower bound")
- ... max = Attribute("Upper bound")
- ...
- ... @invariant
- ... def range_invariant(ob):
- ... if ob.max < ob.min:
- ... raise Invalid('max < min')
-
-
- >>> class Range(object):
- ... implements(IRange)
- ...
- ... def __init__(self, min, max):
- ... self.min, self.max = min, max
-
- >>> from zope.interface.exceptions import Invalid
- >>> IRange.validateInvariants(Range(1,2))
- >>> IRange.validateInvariants(Range(1,1))
- >>> try:
- ... IRange.validateInvariants(Range(2,1))
- ... except Invalid, e:
- ... str(e)
- 'max < min'
-
-
- """
-
-
-def test_description_cache_management():
- """ See https://bugs.launchpad.net/zope.interface/+bug/185974
-
-There was a bug where the cache used by Specification.get() was not
-cleared when the bases were changed.
-
- >>> from zope.interface import Interface
- >>> from zope.interface import Attribute
- >>> class I1(Interface):
- ... a = Attribute('a')
-
- >>> class I2(I1):
- ... pass
-
- >>> class I3(I2):
- ... pass
-
- >>> I3.get('a') is I1.get('a')
- True
- >>> I2.__bases__ = (Interface,)
- >>> I3.get('a') is None
- True
- """
-
-
-def test_suite():
- suite = unittest.makeSuite(InterfaceTests)
- suite.addTest(doctest.DocTestSuite("zope.interface.interface"))
- if sys.version_info >= (2, 4):
- suite.addTest(doctest.DocTestSuite())
- suite.addTest(doctest.DocFileSuite(
- '../README.txt',
- globs={'__name__': '__main__'},
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ))
- suite.addTest(doctest.DocFileSuite(
- '../README.ru.txt',
- globs={'__name__': '__main__'},
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ))
- return suite
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_odd_declarations.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_odd_declarations.py
deleted file mode 100644
index bce47653..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_odd_declarations.py
+++ /dev/null
@@ -1,216 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test interface declarations against ExtensionClass-like classes.
-
-These tests are to make sure we do something sane in the presence of
-classic ExtensionClass classes and instances.
-"""
-import doctest
-import unittest
-
-from zope.interface.tests import odd
-from zope.interface import Interface, implements, classProvides
-from zope.interface import directlyProvides, providedBy, directlyProvidedBy
-from zope.interface import classImplements, classImplementsOnly, implementedBy
-
-class I1(Interface): pass
-class I2(Interface): pass
-class I3(Interface): pass
-class I31(I3): pass
-class I4(Interface): pass
-class I5(Interface): pass
-
-class Odd(object): __metaclass__ = odd.MetaClass
-
-class B(Odd): __implemented__ = I2
-
-
-# TODO: We are going to need more magic to make classProvides work with odd
-# classes. This will work in the next iteration. For now, we'll use
-# a different mechanism.
-
-# from zope.interface import classProvides
-
-class A(Odd):
- pass
-classImplements(A, I1)
-
-class C(A, B):
- pass
-classImplements(C, I31)
-
-
-class Test(unittest.TestCase):
-
- def test_ObjectSpecification(self):
- c = C()
- directlyProvides(c, I4)
- self.assertEqual([i.getName() for i in providedBy(c)],
- ['I4', 'I31', 'I1', 'I2']
- )
- self.assertEqual([i.getName() for i in providedBy(c).flattened()],
- ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
- )
- self.assert_(I1 in providedBy(c))
- self.failIf(I3 in providedBy(c))
- self.assert_(providedBy(c).extends(I3))
- self.assert_(providedBy(c).extends(I31))
- self.failIf(providedBy(c).extends(I5))
-
- class COnly(A, B):
- pass
- classImplementsOnly(COnly, I31)
-
- class D(COnly):
- pass
- classImplements(D, I5)
-
- classImplements(D, I5)
-
- c = D()
- directlyProvides(c, I4)
- self.assertEqual([i.getName() for i in providedBy(c)],
- ['I4', 'I5', 'I31'])
- self.assertEqual([i.getName() for i in providedBy(c).flattened()],
- ['I4', 'I5', 'I31', 'I3', 'Interface'])
- self.failIf(I1 in providedBy(c))
- self.failIf(I3 in providedBy(c))
- self.assert_(providedBy(c).extends(I3))
- self.failIf(providedBy(c).extends(I1))
- self.assert_(providedBy(c).extends(I31))
- self.assert_(providedBy(c).extends(I5))
-
- class COnly(A, B): __implemented__ = I31
- class D(COnly):
- pass
- classImplements(D, I5)
-
- classImplements(D, I5)
- c = D()
- directlyProvides(c, I4)
- self.assertEqual([i.getName() for i in providedBy(c)],
- ['I4', 'I5', 'I31'])
- self.assertEqual([i.getName() for i in providedBy(c).flattened()],
- ['I4', 'I5', 'I31', 'I3', 'Interface'])
- self.failIf(I1 in providedBy(c))
- self.failIf(I3 in providedBy(c))
- self.assert_(providedBy(c).extends(I3))
- self.failIf(providedBy(c).extends(I1))
- self.assert_(providedBy(c).extends(I31))
- self.assert_(providedBy(c).extends(I5))
-
- def test_classImplements(self):
- class A(Odd):
- implements(I3)
-
- class B(Odd):
- implements(I4)
-
- class C(A, B):
- pass
- classImplements(C, I1, I2)
- self.assertEqual([i.getName() for i in implementedBy(C)],
- ['I1', 'I2', 'I3', 'I4'])
- classImplements(C, I5)
- self.assertEqual([i.getName() for i in implementedBy(C)],
- ['I1', 'I2', 'I5', 'I3', 'I4'])
-
- def test_classImplementsOnly(self):
- class A(Odd):
- implements(I3)
-
- class B(Odd):
- implements(I4)
-
- class C(A, B):
- pass
- classImplementsOnly(C, I1, I2)
- self.assertEqual([i.__name__ for i in implementedBy(C)],
- ['I1', 'I2'])
-
-
- def test_directlyProvides(self):
- class IA1(Interface): pass
- class IA2(Interface): pass
- class IB(Interface): pass
- class IC(Interface): pass
- class A(Odd):
- pass
- classImplements(A, IA1, IA2)
-
- class B(Odd):
- pass
- classImplements(B, IB)
-
- class C(A, B):
- pass
- classImplements(C, IC)
-
-
- ob = C()
- directlyProvides(ob, I1, I2)
- self.assert_(I1 in providedBy(ob))
- self.assert_(I2 in providedBy(ob))
- self.assert_(IA1 in providedBy(ob))
- self.assert_(IA2 in providedBy(ob))
- self.assert_(IB in providedBy(ob))
- self.assert_(IC in providedBy(ob))
-
- directlyProvides(ob, directlyProvidedBy(ob)-I2)
- self.assert_(I1 in providedBy(ob))
- self.failIf(I2 in providedBy(ob))
- self.failIf(I2 in providedBy(ob))
- directlyProvides(ob, directlyProvidedBy(ob), I2)
- self.assert_(I2 in providedBy(ob))
-
- def test_directlyProvides_fails_for_odd_class(self):
- self.assertRaises(TypeError, directlyProvides, C, I5)
-
- # see above
- def TODO_test_classProvides_fails_for_odd_class(self):
- try:
- class A(Odd):
- classProvides(I1)
- except TypeError:
- pass # Sucess
- self.assert_(False,
- "Shouldn't be able to use directlyProvides on odd class."
- )
-
- def test_implementedBy(self):
- class I2(I1): pass
-
- class C1(Odd):
- pass
- classImplements(C1, I2)
-
- class C2(C1):
- pass
- classImplements(C2, I3)
-
- self.assertEqual([i.getName() for i in implementedBy(C2)],
- ['I3', 'I2'])
-
-
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(Test))
- suite.addTest(doctest.DocTestSuite(odd))
- return suite
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_sorting.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_sorting.py
deleted file mode 100644
index af60f88b..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_sorting.py
+++ /dev/null
@@ -1,55 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test interface sorting
-"""
-
-from unittest import TestCase, TestSuite, main, makeSuite
-
-from zope.interface import Interface
-
-class I1(Interface): pass
-class I2(I1): pass
-class I3(I1): pass
-class I4(Interface): pass
-class I5(I4): pass
-class I6(I2): pass
-
-
-class Test(TestCase):
-
- def test(self):
- l = [I1, I3, I5, I6, I4, I2]
- l.sort()
- self.assertEqual(l, [I1, I2, I3, I4, I5, I6])
-
- def test_w_None(self):
- l = [I1, None, I3, I5, I6, I4, I2]
- l.sort()
- self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None])
-
- def test_w_equal_names(self):
- # interfaces with equal names but different modules should sort by
- # module name
- from zope.interface.tests.m1 import I1 as m1_I1
- l = [I1, m1_I1]
- l.sort()
- self.assertEqual(l, [m1_I1, I1])
-
-def test_suite():
- return TestSuite((
- makeSuite(Test),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_verify.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_verify.py
deleted file mode 100644
index 1e2282fb..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/test_verify.py
+++ /dev/null
@@ -1,200 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interface Verify tests
-"""
-import doctest
-import unittest
-
-from zope.interface import Interface, implements, classImplements, Attribute
-from zope.interface.verify import verifyClass, verifyObject
-from zope.interface.exceptions import DoesNotImplement, BrokenImplementation
-from zope.interface.exceptions import BrokenMethodImplementation
-
-class Test(unittest.TestCase):
-
- def testNotImplemented(self):
-
- class C(object): pass
-
- class I(Interface): pass
-
- self.assertRaises(DoesNotImplement, verifyClass, I, C)
-
- classImplements(C, I)
-
- verifyClass(I, C)
-
- def testMissingAttr(self):
-
- class I(Interface):
- def f(): pass
-
- class C(object):
- implements(I)
-
- self.assertRaises(BrokenImplementation, verifyClass, I, C)
-
- C.f=lambda self: None
-
- verifyClass(I, C)
-
- def testMissingAttr_with_Extended_Interface(self):
-
- class II(Interface):
- def f():
- pass
-
- class I(II):
- pass
-
- class C(object):
- implements(I)
-
- self.assertRaises(BrokenImplementation, verifyClass, I, C)
-
- C.f=lambda self: None
-
- verifyClass(I, C)
-
- def testWrongArgs(self):
-
- class I(Interface):
- def f(a): pass
-
- class C(object):
- def f(self, b): pass
-
- implements(I)
-
- # We no longer require names to match.
- #self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
-
- C.f=lambda self, a: None
-
- verifyClass(I, C)
-
- C.f=lambda self, **kw: None
-
- self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
-
- C.f=lambda self, a, *args: None
-
- verifyClass(I, C)
-
- C.f=lambda self, a, *args, **kw: None
-
- verifyClass(I, C)
-
- C.f=lambda self, *args: None
-
- verifyClass(I, C)
-
- def testExtraArgs(self):
-
- class I(Interface):
- def f(a): pass
-
- class C(object):
- def f(self, a, b): pass
-
- implements(I)
-
- self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
-
- C.f=lambda self, a: None
-
- verifyClass(I, C)
-
- C.f=lambda self, a, b=None: None
-
- verifyClass(I, C)
-
- def testNoVar(self):
-
- class I(Interface):
- def f(a, *args): pass
-
- class C(object):
- def f(self, a): pass
-
- implements(I)
-
- self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
-
- C.f=lambda self, a, *foo: None
-
- verifyClass(I, C)
-
- def testNoKW(self):
-
- class I(Interface):
- def f(a, **args): pass
-
- class C(object):
- def f(self, a): pass
-
- implements(I)
-
- self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
-
- C.f=lambda self, a, **foo: None
-
- verifyClass(I, C)
-
- def testModule(self):
-
- from zope.interface.tests.ifoo import IFoo
- from zope.interface.tests import dummy
-
- verifyObject(IFoo, dummy)
-
- def testMethodForAttr(self):
-
- class IFoo(Interface):
- foo = Attribute("The foo Attribute")
-
-
- class Foo:
- implements(IFoo)
-
- def foo(self):
- pass
-
- verifyClass(IFoo, Foo)
-
- def testNonMethodForMethod(self):
-
- class IBar(Interface):
- def foo():
- pass
-
- class Bar:
- implements(IBar)
-
- foo = 1
-
- self.assertRaises(BrokenMethodImplementation, verifyClass, IBar, Bar)
-
-
-def test_suite():
- loader=unittest.TestLoader()
- return unittest.TestSuite((
- doctest.DocFileSuite(
- '../verify.txt',
- optionflags=doctest.NORMALIZE_WHITESPACE),
- loader.loadTestsFromTestCase(Test),
- ))
-
-if __name__=='__main__':
- unittest.TextTestRunner().run(test_suite())
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/unitfixtures.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/unitfixtures.py
deleted file mode 100644
index c47eaf0d..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/tests/unitfixtures.py
+++ /dev/null
@@ -1,140 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Unit Test Fixtures
-"""
-from zope.interface import Interface, invariant
-from zope.interface.interface import Attribute
-from zope.interface.exceptions import Invalid
-
-class mytest(Interface):
- pass
-
-class C(object):
- def m1(self, a, b):
- "return 1"
- return 1
-
- def m2(self, a, b):
- "return 2"
- return 2
-
-# testInstancesOfClassImplements
-
-# YAGNI IC=Interface.impliedInterface(C)
-class IC(Interface):
- def m1(a, b):
- "return 1"
-
- def m2(a, b):
- "return 2"
-
-
-
-C.__implemented__=IC
-
-class I1(Interface):
- def ma():
- "blah"
-
-class I2(I1): pass
-
-class I3(Interface): pass
-
-class I4(Interface): pass
-
-class A(I1.deferred()):
- __implemented__=I1
-
-class B(object):
- __implemented__=I2, I3
-
-class D(A, B): pass
-
-class E(A, B):
- __implemented__ = A.__implemented__, C.__implemented__
-
-
-class FooInterface(Interface):
- """ This is an Abstract Base Class """
-
- foobar = Attribute("fuzzed over beyond all recognition")
-
- def aMethod(foo, bar, bingo):
- """ This is aMethod """
-
- def anotherMethod(foo=6, bar="where you get sloshed", bingo=(1,3,)):
- """ This is anotherMethod """
-
- def wammy(zip, *argues):
- """ yadda yadda """
-
- def useless(**keywords):
- """ useless code is fun! """
-
-class Foo(object):
- """ A concrete class """
-
- __implemented__ = FooInterface,
-
- foobar = "yeah"
-
- def aMethod(self, foo, bar, bingo):
- """ This is aMethod """
- return "barf!"
-
- def anotherMethod(self, foo=6, bar="where you get sloshed", bingo=(1,3,)):
- """ This is anotherMethod """
- return "barf!"
-
- def wammy(self, zip, *argues):
- """ yadda yadda """
- return "barf!"
-
- def useless(self, **keywords):
- """ useless code is fun! """
- return "barf!"
-
-foo_instance = Foo()
-
-class Blah(object):
- pass
-
-new = Interface.__class__
-FunInterface = new('FunInterface')
-BarInterface = new('BarInterface', [FunInterface])
-BobInterface = new('BobInterface')
-BazInterface = new('BazInterface', [BobInterface, BarInterface])
-
-# fixtures for invariant tests
-def ifFooThenBar(obj):
- if getattr(obj, 'foo', None) and not getattr(obj, 'bar', None):
- raise Invalid('If Foo, then Bar!')
-class IInvariant(Interface):
- foo = Attribute('foo')
- bar = Attribute('bar; must eval to Boolean True if foo does')
- invariant(ifFooThenBar)
-def BarGreaterThanFoo(obj):
- foo = getattr(obj, 'foo', None)
- bar = getattr(obj, 'bar', None)
- if foo is not None and isinstance(foo, type(bar)):
- # type checking should be handled elsewhere (like, say,
- # schema); these invariants should be intra-interface
- # constraints. This is a hacky way to do it, maybe, but you
- # get the idea
- if not bar > foo:
- raise Invalid('Please, Boo MUST be greater than Foo!')
-class ISubInvariant(IInvariant):
- invariant(BarGreaterThanFoo)
-class InvariantC(object):
- pass
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.py
deleted file mode 100644
index da60b6ea..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.py
+++ /dev/null
@@ -1,115 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Verify interface implementations
-"""
-from zope.interface.exceptions import BrokenImplementation, DoesNotImplement
-from zope.interface.exceptions import BrokenMethodImplementation
-from types import FunctionType, MethodType
-from zope.interface.interface import fromMethod, fromFunction, Method
-import sys
-
-# This will be monkey-patched when running under Zope 2, so leave this
-# here:
-MethodTypes = (MethodType, )
-
-
-def _verify(iface, candidate, tentative=0, vtype=None):
- """Verify that 'candidate' might correctly implements 'iface'.
-
- This involves:
-
- o Making sure the candidate defines all the necessary methods
-
- o Making sure the methods have the correct signature
-
- o Making sure the candidate asserts that it implements the interface
-
- Note that this isn't the same as verifying that the class does
- implement the interface.
-
- If optional tentative is true, suppress the "is implemented by" test.
- """
-
- if vtype == 'c':
- tester = iface.implementedBy
- else:
- tester = iface.providedBy
-
- if not tentative and not tester(candidate):
- raise DoesNotImplement(iface)
-
- # Here the `desc` is either an `Attribute` or `Method` instance
- for name, desc in iface.namesAndDescriptions(1):
- try:
- attr = getattr(candidate, name)
- except AttributeError:
- if (not isinstance(desc, Method)) and vtype == 'c':
- # We can't verify non-methods on classes, since the
- # class may provide attrs in it's __init__.
- continue
-
- raise BrokenImplementation(iface, name)
-
- if not isinstance(desc, Method):
- # If it's not a method, there's nothing else we can test
- continue
-
- if isinstance(attr, FunctionType):
- if sys.version[0] == '3' and isinstance(candidate, type):
- # This is an "unbound method" in Python 3.
- meth = fromFunction(attr, iface, name=name, imlevel=1)
- else:
- # Nope, just a normal function
- meth = fromFunction(attr, iface, name=name)
- elif (isinstance(attr, MethodTypes)
- and type(attr.im_func) is FunctionType):
- meth = fromMethod(attr, iface, name)
- else:
- if not callable(attr):
- raise BrokenMethodImplementation(name, "Not a method")
- # sigh, it's callable, but we don't know how to intrspect it, so
- # we have to give it a pass.
- continue
-
- # Make sure that the required and implemented method signatures are
- # the same.
- desc = desc.getSignatureInfo()
- meth = meth.getSignatureInfo()
-
- mess = _incompat(desc, meth)
- if mess:
- raise BrokenMethodImplementation(name, mess)
-
- return True
-
-def verifyClass(iface, candidate, tentative=0):
- return _verify(iface, candidate, tentative, vtype='c')
-
-def verifyObject(iface, candidate, tentative=0):
- return _verify(iface, candidate, tentative, vtype='o')
-
-def _incompat(required, implemented):
- #if (required['positional'] !=
- # implemented['positional'][:len(required['positional'])]
- # and implemented['kwargs'] is None):
- # return 'imlementation has different argument names'
- if len(implemented['required']) > len(required['required']):
- return 'implementation requires too many arguments'
- if ((len(implemented['positional']) < len(required['positional']))
- and not implemented['varargs']):
- return "implementation doesn't allow enough arguments"
- if required['kwargs'] and not implemented['kwargs']:
- return "implementation doesn't support keyword arguments"
- if required['varargs'] and not implemented['varargs']:
- return "implementation doesn't support variable arguments"
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.txt
deleted file mode 100644
index 7eec6d22..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/verify.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-===================================
-Verifying interface implementations
-===================================
-
-The ``zope.interface.verify`` module provides functions that test whether a
-given interface is implemented by a class or provided by an object, resp.
-
-
-Verifying classes
-=================
-
-This is covered by unit tests defined in ``zope.interface.tests.test_verify``.
-
-
-Verifying objects
-=================
-
-An object provides an interface if
-
-- either its class declares that it implements the interfaces, or the object
- declares that it directly provides the interface
-
-- the object defines all the methods required by the interface
-
-- all the methods have the correct signature
-
-- the object defines all non-method attributes required by the interface
-
-This doctest currently covers only the latter item.
-
-Testing for attributes
-----------------------
-
-Attributes of the object, be they defined by its class or added by its
-``__init__`` method, will be recognized:
-
->>> from zope.interface import Interface, Attribute, implements
->>> from zope.interface.exceptions import BrokenImplementation
->>> class IFoo(Interface):
-... x = Attribute("The X attribute")
-... y = Attribute("The Y attribute")
-
->>> class Foo(object):
-... implements(IFoo)
-... x = 1
-... def __init__(self):
-... self.y = 2
-
->>> from zope.interface.verify import verifyObject
->>> verifyObject(IFoo, Foo())
-True
-
-If either attribute is missing, verification will fail:
-
->>> class Foo(object):
-... implements(IFoo)
-... x = 1
-
->>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-... verifyObject(IFoo, Foo())
-... except BrokenImplementation, e:
-... print str(e)
-An object has failed to implement interface <InterfaceClass ...IFoo>
-<BLANKLINE>
- The y attribute was not provided.
-<BLANKLINE>
-
->>> class Foo(object):
-... implements(IFoo)
-... def __init__(self):
-... self.y = 2
-
->>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-... verifyObject(IFoo, Foo())
-... except BrokenImplementation, e:
-... print str(e)
-An object has failed to implement interface <InterfaceClass ...IFoo>
-<BLANKLINE>
- The x attribute was not provided.
-<BLANKLINE>
-
-If an attribute is implemented as a property that raises an AttributeError
-when trying to get its value, the attribute is considered missing:
-
->>> class IFoo(Interface):
-... x = Attribute('The X attribute')
-
->>> class Foo(object):
-... implements(IFoo)
-... @property
-... def x(self):
-... raise AttributeError
-
->>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-... verifyObject(IFoo, Foo())
-... except BrokenImplementation, e:
-... print str(e)
-An object has failed to implement interface <InterfaceClass ...IFoo>
-<BLANKLINE>
- The x attribute was not provided.
-<BLANKLINE>
-
-Any other exception raised by a property will propagate to the caller of
-``verifyObject``:
-
->>> class Foo(object):
-... implements(IFoo)
-... @property
-... def x(self):
-... raise Exception
-
->>> verifyObject(IFoo, Foo())
-Traceback (most recent call last):
-Exception
-
-Of course, broken properties that are not required by the interface don't do
-any harm:
-
->>> class Foo(object):
-... implements(IFoo)
-... x = 1
-... @property
-... def y(self):
-... raise Exception
-
->>> verifyObject(IFoo, Foo())
-True
diff --git a/yocto-autobuilder-setup b/yocto-autobuilder-setup
deleted file mode 100644
index b84d42b7..00000000
--- a/yocto-autobuilder-setup
+++ /dev/null
@@ -1,200 +0,0 @@
-# Yocto Build Server Setup Script
-# Elizabeth Flanagan <pidge@toganlabs.com>
-#
-# Copyright (C) 2011-2017 Intel Corp.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-#########################################
-# buildbot update wants to parse the config
-# So, we export bogus values just to get the
-# config to parse
-#########################################
-
-export WORKERBASEDIR=`pwd`/yocto-worker
-export PUBLISH_BUILDS=False
-export PUBLISH_SOURCE_MIRROR=False
-export PUBLISH_SSTATE=False
-export SSTATE_PUBLISH_DIR="/tmp/yocto-autobuilder/sstate_mirror"
-export SOURCE_PUBLISH_DIR="/tmp/yocto-autobuilder/source"
-export DL_DIR="/tmp/yocto-autobuilder/downloads"
-export SSTATE_DIR="/tmp/yocto-autobuilder/sstate"
-export BUILD_PUBLISH_DIR="/tmp/yocto-autobuilder/builds"
-export RELEASE_PUBLISH_DIR="/tmp/yocto-autobuilder/releases"
-export BUILD_HISTORY_COLLECT=False
-export SOURCE_DL_DIR="/tmp/yocto-autobuilder/downloads"
-export SOURCE_SSTATE_DIR="/tmp/yocto-autobuilder/sstate"
-export LSB_SSTATE_DIR="/tmp/yocto-autobuilder/lsb-sstate"
-export CLEAN_SOURCE_DIR=False
-export BUILD_HISTORY_DIR="/tmp/yocto-autobuilder/buildhistory"
-export BUILD_HISTORY_REPO="file:////tmp/yocto-autobuilder/buildhistory-repo"
-export EMGD_DRIVER_DIR="/tmp/yocto-autobuilder/emgd-driver"
-export ADTREPO_POPULATE=False
-export ADTREPO_GENERATE_INSTALLER=False
-export ADTREPO_DEV_POPULATE=False
-export ADTREPO_GENERATE_DEV_INSTALLER=True
-export ADTREPO_URL="http://adtrepo.yoctoproject.org/"
-export ADTREPO_PATH="/srv/www/vhosts/adtrepo.yoctoproject.org/"
-export ADTREPO_DEV_URL="http://adtrepo-dev.yoctoproject.org/"
-export ADTREPO_DEV_PATH="/srv/www/vhosts/adtrepo-dev/"
-export PATH=`pwd`/bin:$PATH
-export YOCTO_AB_CONFIG=`pwd`/buildset-config/yoctoAB.conf
-export RESOLVED_TRIGGERED_HEAD=True
-export OPTIMIZED_GIT_CLONE=False
-export OGIT_TRASH_DIR=/tmp/yocto-autobuilder/git/trash
-export OGIT_TRASH_CRON_TIME="0 0 * * *"
-export OGIT_TRASH_NICE_LEVEL="19"
-if ! HOST_ADDR=$(hostname -I 2> /dev/null); then
- HOST_ADDR=$(hostname -i)
-fi
-
-##########################
-#
-# Check to see if we've got a username/password set
-#
-##########################
-if [ ! -f "${PWD}/yocto-controller/buildbot.tac" ]; then
- echo ""
- echo "Creating yocto-controller/buildbot.tac from an example buildbot.tac"
- echo ""
- /bin/cp yocto-controller/buildbot.tac.example yocto-controller/buildbot.tac
-fi
-
-if [ ! -f "${PWD}/yocto-worker/buildbot.tac" ]; then
- echo ""
- echo "Creating yocto-worker/buildbot.tac from an example buildbot.tac"
- echo ""
- /bin/cp yocto-worker/buildbot.tac.example yocto-worker/buildbot.tac
-fi
-
-
-if [ ! -f "${PWD}/yocto-controller/controller.cfg" ]; then
- echo ""
- echo "Creating yocto-controller/controller.cfg from an example controller.cfg"
- echo ""
- /bin/cp yocto-controller/controller.cfg.example yocto-controller/controller.cfg
-fi
-
-if [ "${PWD}/yocto-controller/controller.cfg" ]; then
- config_check=`cat ${PWD}/yocto-controller/controller.cfg|grep "<PASS>"`
-fi
-
-USERSITE="`python2 -m site --user-site`"
-ABPTHPATH="${USERSITE}/autobuilder.pth"
-if [ ! -f "${ABPTHPATH}" ]; then
- echo "Adding autobuilder modules to ${ABPTHPATH}"
- mkdir -p ${USERSITE}
- cat ${PWD}/autobuilder.pth.in | sed "s@<YPABDIR>@${PWD}@g" > ${ABPTHPATH}
-fi
-
-#########################################
-#
-# I dislike people touching my .bashrc
-# so, let's warn here that they should add
-# this to their env
-#
-#########################################
-echo "#########################################################################"
-echo " Setting envvars. "
-echo " In the future though please add the following to your shell environment: "
-echo " PATH=${PWD}/bin:"'$PATH'
-echo " YOCTO_AB_CONFIG=${PWD}/buildset-config/yoctoAB.conf"
-echo ""
-echo " If you don't, you should source this script everytime you want start the "
-echo " autobuilder."
-
-##########################
-#
-# Check to see if we've got an autobuilder.conf
-#
-##########################
-if [ ! -f "./config/autobuilder.conf" ]; then
- echo ""
- echo "Creating config/autobuilder.conf from an example autobuilder.conf"
- echo ""
- /bin/cp config/autobuilder.conf.example config/autobuilder.conf
-fi
-
-if [ ! -d "./buildset-config" ]; then
- echo ""
- echo "Creating buildset-config from buildset-config.controller"
- echo ""
- /bin/cp -R buildset-config.controller buildset-config
-fi
-
-
-if [ -n "${config_check:+x}" ]; then
- echo ""
- echo " You've not setup the autobuilder before. Generating a server/client password"
- echo " combo for you."
- password=`cat /dev/urandom|tr -dc "a-zA-Z0-9"|fold -w 9|head -n1`
- echo " Client/Server Password = $password "
- echo ""
- echo " Modifying the following files with this password:"
- echo ""
- echo " ${PWD}/yocto-controller/controller.cfg "
- sed -i "s/<PASS>/$password/g" ${PWD}/yocto-controller/controller.cfg
- echo " ${PWD}/yocto-controller/buildbot.tac "
- sed -i "s/<PASS>/$password/g" ${PWD}/yocto-controller/buildbot.tac
- echo " ${PWD}/yocto-worker/buildbot.tac "
- sed -i "s/<PASS>/$password/g" ${PWD}/yocto-worker/buildbot.tac
-
- echo ""
- echo " Updating worker-init script used for google cloud building. "
- sed -i "s/<HOST_ADDR>/$HOST_ADDR/" ${PWD}/bin/worker-init
- sed -i "s/<PASS>/$password/" ${PWD}/bin/worker-init
- echo ""
- echo " If you wish to use your own generated username and password please "
- echo " modify the above files as needed. Please see the README for more "
- echo " information. "
- echo ""
- htpath=${PWD}/.htpasswd
-
- if [ ! -f $htpath ]; then
- touch $htpath
- upassword=`cat /dev/urandom|tr -dc "a-zA-Z0-9"|fold -w 8|head -n1`
- echo " Generating an .htpasswd file using your current username and $upassword at ${PWD}/.htpasswd"
- ./bin/htpasswd -b $htpath $USER $upassword
- fi
- sed -i "s?<HTPASSWDPATH>?$htpath?g" ${PWD}/yocto-controller/controller.cfg
- echo "#########################################################################"
- echo ""
- echo " Please modify ${PWD}/config/autobuilder.conf if you wish to specify "
- echo " a different location in which to publish build artifacts, etc."
- echo ""
- echo "#########################################################################"
- echo ""
- echo " Ready to start the yocto autobuilder."
- echo ""
- echo " The yocto-autobuilder runs buildbot 0.8.8 with some modifications and"
- echo " a different git fetcher (yoctogit.py)"
- echo ""
- echo "#########################################################################"
- buildbot upgrade-master ${PWD}/yocto-controller
- ################
- #
- # We touch this because we know they've at least run this once
- #
- ################
- touch ${PWD}/.setupdone
-fi
-
-echo " To start the autobuilder:"
-echo " ./yocto-start-autobuilder <worker|controller|both>"
-echo ""
-echo " To stop the autobuilder:"
-echo " ./yocto-stop-autobuilder <worker|controller|both>"
-echo ""
diff --git a/yocto-controller/Makefile b/yocto-controller/Makefile
deleted file mode 100755
index e90cc2f1..00000000
--- a/yocto-controller/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-
-# This is a simple makefile which lives in a buildmaster
-# directory (next to the buildbot.tac file). It allows you to start/stop the
-# master by doing 'make start' or 'make stop'.
-
-# The 'reconfig' target will tell a buildmaster to reload its config file.
-
-start:
- twistd --no_save -y buildbot.tac
-
-stop:
- if [ -e twistd.pid ]; \
- then kill `cat twistd.pid`; \
- else echo "Nothing to stop."; \
- fi
-
-reconfig:
- if [ -e twistd.pid ]; \
- then kill -HUP `cat twistd.pid`; \
- else echo "Nothing to reconfig."; \
- fi
-
-log:
- if [ -e twistd.log ]; \
- then tail -f twistd.log; \
- else echo "Nothing to tail."; \
- fi
-
diff --git a/yocto-controller/buildbot.tac.example b/yocto-controller/buildbot.tac.example
deleted file mode 100644
index a9617a9f..00000000
--- a/yocto-controller/buildbot.tac.example
+++ /dev/null
@@ -1,32 +0,0 @@
-import os
-
-from twisted.application import service
-from buildbot.master import BuildMaster
-
-basedir = r'.'
-rotateLength = 10000000
-maxRotatedFiles = 99
-
-# if this is a relocatable tac file, get the directory containing the TAC
-if basedir == '.':
- import os.path
- basedir = os.path.abspath(os.path.dirname(__file__))
-
-application = service.Application('buildmaster')
-try:
- from twisted.python.logfile import LogFile
- from twisted.python.log import ILogObserver, FileLogObserver
- logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
- maxRotatedFiles=maxRotatedFiles)
- application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
-except ImportError:
- # probably not yet twisted 8.2.0 and beyond, can't set log yet
- pass
-
-configfile = r'controller.cfg'
-
-m = BuildMaster(basedir, configfile)
-m.setServiceParent(application)
-m.log_rotation.rotateLength = rotateLength
-m.log_rotation.maxRotatedFiles = maxRotatedFiles
-
diff --git a/yocto-controller/buildbot.tac.standard b/yocto-controller/buildbot.tac.standard
deleted file mode 100644
index c9682acb..00000000
--- a/yocto-controller/buildbot.tac.standard
+++ /dev/null
@@ -1,32 +0,0 @@
-import os
-
-from twisted.application import service
-from buildbot.master import BuildMaster
-
-basedir = '.'
-
-rotateLength = '10000000'
-maxRotatedFiles = '10'
-configfile = 'master.cfg'
-
-# Default umask for server
-umask = None
-
-# if this is a relocatable tac file, get the directory containing the TAC
-if basedir == '.':
- import os.path
- basedir = os.path.abspath(os.path.dirname(__file__))
-
-# note: this line is matched against to check that this is a buildmaster
-# directory; do not edit it.
-application = service.Application('buildmaster')
-from twisted.python.logfile import LogFile
-from twisted.python.log import ILogObserver, FileLogObserver
-logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
- maxRotatedFiles=maxRotatedFiles)
-application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
-
-m = BuildMaster(basedir, configfile, umask)
-m.setServiceParent(application)
-m.log_rotation.rotateLength = rotateLength
-m.log_rotation.maxRotatedFiles = maxRotatedFiles
diff --git a/yocto-controller/controller.cfg.example b/yocto-controller/controller.cfg.example
deleted file mode 100644
index 5962e751..00000000
--- a/yocto-controller/controller.cfg.example
+++ /dev/null
@@ -1,150 +0,0 @@
-# -*- python -*-
-# ex: set syntax=python:
-
-# This is the dictionary that the buildmaster pays attention to. We also use
-# a shorter alias to save typing.
-
-c = BuildmasterConfig = {}
-
-####################
-# PROJECT IDENTITY #
-####################
-
-c['debugPassword'] = "<PASS>"
-
-# the 'title' string will appear at the top of this buildbot
-# installation's html.WebStatus home page (linked to the
-# 'titleURL') and is embedded in the title of the waterfall HTML page.
-
-c['title'] = "The Yocto Autobuilder"
-c['titleURL'] = "https://localhost:8010"
-
-# the 'buildbotURL' string should point to the location where the buildbot's
-# internal web server (usually the html.WebStatus page) is visible. This
-# typically uses the port number set in the Waterfall 'status' entry, but
-# with an externally-visible host name which the buildbot cannot figure out
-# without some help.
-
-c['buildbotURL'] = "http://localhost:8010"
-
-################
-# BUILDWORKERS #
-################
-
-# The 'workers' list defines the set of recognized buildworkers. Each element
-# is a BuildWorker object (renamed from the BuildSlave buildbot terminology),
-# specifying a unique worker name and your debug password "<PASS>". The same
-# worker name and password must be configured on the worker. The BuildWorker
-# object can also take an optional max_builds for the number of builds you
-# wish to run on each builder.
-#
-# To get multiple buildworkers add another BuildWorker entry to c['workers'].
-# Your main builder that will run the nightly trigger buildset should have
-# at least 2 build workers running. An example is below:
-#
-# c['workers'] = [BuildWorker("builder1", "<PASS>", max_builds=3),
-# BuildWorker("builder2", "<PASS>", max_builds=3),]
-
-from buildbot.buildslave import BuildSlave as BuildWorker
-c['workers'] = [BuildWorker("example-worker", "<PASS>", max_builds=3),]
-
-# 'workerPortnum' defines the TCP port to listen on for connections from
-# workers. This must match the value configured into the buildworkers
-# (with their --master option)
-
-c['workerPortnum'] = 9989
-
-##################
-# STATUS TARGETS #
-##################
-
-# 'status' is a list of Status Targets. The results of each build will be
-# pushed to these targets. buildbot/status/*.py has a variety to choose from,
-# including web pages, email senders, and IRC bots.
-
-c['status'] = []
-from buildbot.status.html import WebStatus
-from buildbot.status.web.authz import Authz
-from buildbot.status.web.auth import HTPasswdAuth
-authz_cfg=Authz(auth=HTPasswdAuth('<HTPASSWDPATH>'),
- forceBuild = 'auth',
- stopBuild = 'auth',
- stopAllBuilds = 'auth',
- cancelAllPendingBuilds = 'auth',
- cancelPendingBuild = 'auth',
- gracefulShutdown = 'auth',
- forceAllBuilds = False,
- stopChange = False,
- cleanShutdown = 'auth',
- showUsersPage = 'auth',
- pauseSlave = 'auth',
- pingBuilder = False)
-c['status'].append(WebStatus(http_port=8010, authz=authz_cfg))
-
-##########
-# CONFIG #
-##########
-
-#import yoctoABConfig
-#reload(yoctoABConfig)
-#
-from Autobuilder import Autobuilder
-yocto_buildsets = Autobuilder()
-yocto_buildsets.parseConfig()
-yocto_buildsets.createBuildsets()
-#
-from config import *
-yocto_sources = YOCTO_SOURCES
-yocto_sched = YOCTO_SCHED
-yocto_builders = YOCTO_BUILDERS
-yocto_projname = YOCTO_PROJNAME
-yocto_projurl = YOCTO_PROJURL
-#
-c['builders'] = yocto_builders
-c['change_source'] = yocto_sources
-c['schedulers'] = yocto_sched
-c['projectName'] = yocto_projname
-c['projectURL'] = yocto_projurl
-
-##########
-# DB URL #
-##########
-
-# This specifies what database buildbot uses to store its state. You can leave
-# this at its default for all but the largest installations.
-
-c['db'] = {'db_url' : "sqlite:///state.sqlite",}
-
-############
-# POINTERS #
-############
-
-# Point outdated buildbot terminology at our updated terms
-
-c['slavePortnum'] = c['workerPortnum']; del c['workerPortnum']
-c['slaves'] = c['workers']; del c['workers']
-
-###############
-# YOCTOMAILER #
-###############
-
-#from YoctoMailer import YoctoMailNotifier
-#import Yocto_Message_Formatter
-
-#c['status'].append(YoctoMailNotifier(fromaddr="autobuilder@localhost",
-# sendToInterestedUsers=False,
-# yoctorepos=['git://git.yoctoproject.org/poky'],
-# branches=['master', 'dylan', 'danny', 'dora', 'daisy', 'dizzy', 'fido'],
-# mode='failing',
-# extraRecipients=["root@localhost"],
-# messageFormatter=Yocto_Message_Formatter.message_formatter))
-
-##############
-# WIKILOGGER #
-##############
-
-#from autobuilder.status import wikilog
-#wiki = wikilog.WikiLog("https://mymediawikihost.tld/wiki/api.php",
-# "WikiUser", "verysecurepassword", "LogPageTitle",
-# "cluster name")
-#c['status'].append(wiki)
diff --git a/yocto-controller/public_html/bg_gradient.jpg b/yocto-controller/public_html/bg_gradient.jpg
deleted file mode 100644
index 6c2e5ddf..00000000
--- a/yocto-controller/public_html/bg_gradient.jpg
+++ /dev/null
Binary files differ
diff --git a/yocto-controller/public_html/default.css b/yocto-controller/public_html/default.css
deleted file mode 100644
index 452105fe..00000000
--- a/yocto-controller/public_html/default.css
+++ /dev/null
@@ -1,546 +0,0 @@
-body.interface {
- margin-left: 30px;
- margin-right: 30px;
- margin-top: 20px;
- margin-bottom: 50px;
- padding: 0;
- background: url(bg_gradient.jpg) repeat-x;
- font-family: Verdana, sans-serif;
- font-size: 10px;
- background-color: #fff;
- color: #333;
-}
-
-a:link,a:visited,a:active {
- color: #444;
-}
-
-table {
- border-spacing: 1px 1px;
-}
-
-table td {
- padding: 3px 4px 3px 4px;
- text-align: center;
-}
-
-.Project {
- min-width: 6em;
-}
-
-.LastBuild,.Activity {
- padding: 0 0 0 4px;
-}
-
-.LastBuild,.Activity,.Builder,.BuildStep {
- min-width: 5em;
-}
-
-/* Chromium Specific styles */
-div.BuildResultInfo {
- color: #444;
-}
-
-div.Announcement {
- margin-bottom: 1em;
-}
-
-div.Announcement>a:hover {
- color: black;
-}
-
-div.Announcement>div.Notice {
- background-color: #afdaff;
- padding: 0.5em;
- font-size: 16px;
- text-align: center;
-}
-
-div.Announcement>div.Open {
- border: 3px solid #8fdf5f;
- padding: 0.5em;
- font-size: 16px;
- text-align: center;
-}
-
-div.Announcement>div.Closed {
- border: 5px solid #e98080;
- padding: 0.5em;
- font-size: 24px;
- font-weight: bold;
- text-align: center;
-}
-
-td.Time {
- color: #000;
- border-bottom: 1px solid #aaa;
- background-color: #eee;
-}
-
-td.Activity,td.Change,td.Builder {
- color: #333333;
- background-color: #CCCCCC;
-}
-
-td.Change {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-td.Event {
- color: #777;
- background-color: #ddd;
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-td.Activity {
- border-top-left-radius: 10px;
- -webkit-border-top-left-radius: 10px;
- -moz-border-radius-topleft: 10px;
- min-height: 20px;
- padding: 2px 0 2px 0;
-}
-
-td.idle,td.waiting,td.offline,td.building {
- border-top-left-radius: 0px;
- -webkit-border-top-left-radius: 0px;
- -moz-border-radius-topleft: 0px;
-}
-
-.LastBuild {
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- border-top-right-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topright: 5px;
-}
-
-/* Console view styles */
-td.DevRev {
- padding: 4px 8px 4px 8px;
- color: #333333;
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- background-color: #eee;
- width: 1%;
-}
-
-td.DevRevCollapse {
- border-bottom-left-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
-}
-
-td.DevName {
- padding: 4px 8px 4px 8px;
- color: #333333;
- background-color: #eee;
- width: 1%;
- text-align: left;
-}
-
-td.DevStatus {
- padding: 4px 4px 4px 4px;
- color: #333333;
- background-color: #eee;
-}
-
-td.DevSlave {
- padding: 4px 4px 4px 4px;
- color: #333333;
- background-color: #eee;
-}
-
-td.first {
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
-}
-
-td.last {
- border-top-right-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topright: 5px;
-}
-
-td.DevStatusCategory {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-width: 1px;
- border-style: solid;
-}
-
-td.DevStatusCollapse {
- border-bottom-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
-}
-
-td.DevDetails {
- font-weight: normal;
- padding: 8px 8px 8px 8px;
- color: #333333;
- background-color: #eee;
- text-align: left;
-}
-
-td.DevDetails li a {
- padding-right: 5px;
-}
-
-td.DevComment {
- font-weight: normal;
- padding: 8px 8px 8px 8px;
- color: #333333;
- border-bottom-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- border-bottom-left-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
- background-color: #eee;
- text-align: left;
-}
-
-td.Alt {
- background-color: #ddd;
-}
-
-.legend {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- width: 100px;
- max-width: 100px;
- text-align: center;
- padding: 2px 2px 2px 2px;
- height: 14px;
- white-space: nowrap;
-}
-
-.DevStatusBox {
- text-align: center;
- height: 20px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.DevStatusBox a {
- opacity: 0.85;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- display: block;
- width: 90%;
- height: 20px;
- line-height: 20px;
- margin-left: auto;
- margin-right: auto;
-}
-
-.DevSlaveBox {
- text-align: center;
- height: 10px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.DevSlaveBox a {
- opacity: 0.85;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- display: block;
- width: 90%;
- height: 10px;
- line-height: 20px;
- margin-left: auto;
- margin-right: auto;
-}
-
-a.noround {
- border-radius: 0px;
- -webkit-border-radius: 0px;
- -moz-border-radius: 0px;
- position: relative;
- margin-top: -8px;
- margin-bottom: -8px;
- height: 36px;
- border-top-width: 0;
- border-bottom-width: 0;
-}
-
-a.begin {
- border-top-width: 1px;
- position: relative;
- margin-top: 0px;
- margin-bottom: -7px;
- height: 27px;
- border-top-left-radius: 4px;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topleft: 4px;
- border-top-right-radius: 4px;
- -webkit-border-top-right-radius: 4px;
- -moz-border-radius-topright: 4px;
-}
-
-a.end {
- border-bottom-width: 1px;
- position: relative;
- margin-top: -7px;
- margin-bottom: 0px;
- height: 27px;
- border-bottom-left-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -moz-border-radius-bottomleft: 4px;
- border-bottom-right-radius: 4px;
- -webkit-border-bottom-right-radius: 4px;
- -moz-border-radius-bottomright: 4px;
-}
-
-.center_align {
- text-align: center;
-}
-
-.right_align {
- text-align: right;
-}
-
-.left_align {
- text-align: left;
-}
-
-div.BuildWaterfall {
- border-radius: 2px;
- -webkit-border-radius: 2px;
- -moz-border-radius: 2px;
- position: absolute;
- left: 0px;
- top: 0px;
- background-color: #FFFFFF;
- padding: 2px 2px 2px 2px;
- float: left;
- display: none;
- border-width: 1px;
- border-style: solid;
-}
-
-/* LastBuild, BuildStep states */
-.success {
- color: #000;
- background-color: #5CE65C;
- /* background-color: #8d4; */
- border-color: #4F8530;
-}
-
-.failure {
- color: #000;
- background-color: #e88;
- border-color: #A77272;
-}
-
-.warnings {
- color: #FFFFFF;
- background-color: #fa3;
- border-color: #C29D46;
-}
-
-.skipped {
- color: #000;
- background: #AADDEE;
- border-color: #AADDEE;
-}
-
-.exception,.retry {
- color: #FFFFFF;
- background-color: #c6c;
- border-color: #ACA0B3;
-}
-
-.start {
- color: #000;
- background-color: #ccc;
- border-color: #ccc;
-}
-
-.running,.waiting,td.building {
- color: #000;
- background-color: #fd3;
- border-color: #C5C56D;
-}
-
-.offline,td.offline {
- color: #FFFFFF;
- background-color: #777777;
- border-color: #dddddd;
-}
-
-
-.start {
- border-bottom-left-radius: 10px;
- -webkit-border-bottom-left-radius: 10px;
- -moz-border-radius-bottomleft: 10px;
- border-bottom-right-radius: 10px;
- -webkit-border-bottom-right-radius: 10px;
- -moz-border-radius-bottomright: 10px;
-}
-
-.notstarted {
- border-width: 1px;
- border-style: solid;
- border-color: #aaa;
- background-color: #fff;
-}
-
-.closed {
- background-color: #ff0000;
-}
-
-.closed .large {
- font-size: 1.5em;
- font-weight: bolder;
-}
-
-td.Project a:hover,td.start a:hover {
- color: #000;
-}
-
-.mini-box {
- text-align: center;
- height: 20px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.mini-box a {
- border-radius: 0;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- display: block;
- width: 100%;
- height: 20px;
- line-height: 20px;
- margin-top: -30px;
-}
-
-.mini-closed {
- -box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border: 4px solid red;
-}
-
-/* grid styles */
-table.Grid {
- border-collapse: collapse;
-}
-
-table.Grid tr td {
- padding: 0.2em;
- margin: 0px;
- text-align: center;
-}
-
-table.Grid tr td.title {
- font-size: 90%;
- border-right: 1px gray solid;
- border-bottom: 1px gray solid;
-}
-
-table.Grid tr td.sourcestamp {
- font-size: 90%;
-}
-
-table.Grid tr td.builder {
- text-align: right;
- font-size: 90%;
-}
-
-table.Grid tr td.build {
- border: 1px gray solid;
-}
-
-/* column container */
-div.column {
- margin: 0 2em 2em 0;
- float: left;
-}
-
-/* info tables */
-table.info {
- border-spacing: 1px;
-}
-
-table.info td {
- padding: 0.1em 1em 0.1em 1em;
- text-align: center;
-}
-
-table.info th {
- padding: 0.2em 1.5em 0.2em 1.5em;
- text-align: center;
-}
-
-table.info td.left {
- text-align: left
-}
-
-.alt {
- background-color: #f6f6f6;
-}
-
-li {
- padding: 0.1em 1em 0.1em 1em;
-}
-
-.result {
- padding: 0.3em 1em 0.3em 1em;
-}
-
-/* log view */
-.log * {
- vlink: #800080;
- font-family: "Courier New", courier, monotype, monospace;
-}
-
-span.stdout {
- color: black;
-}
-
-span.stderr {
- color: red;
-}
-
-span.header {
- color: blue;
-}
-
-/* revision & email */
-.revision .full {
- display: none;
-}
-
-.user .email {
- display: none;
-}
-
-/* change comments (use regular colors here) */
-pre.comments>a:link,pre.comments>a:visited {
- color: blue;
-}
-
-pre.comments>a:active {
- color: purple;
-}
diff --git a/yocto-controller/public_html/favicon.ico b/yocto-controller/public_html/favicon.ico
deleted file mode 100644
index b0b0845d..00000000
--- a/yocto-controller/public_html/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/yocto-controller/public_html/robots.txt b/yocto-controller/public_html/robots.txt
deleted file mode 100644
index b139adea..00000000
--- a/yocto-controller/public_html/robots.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-User-agent: *
-Disallow: /waterfall
-Disallow: /builders
-Disallow: /changes
-Disallow: /buildslaves
-Disallow: /schedulers
-Disallow: /one_line_per_build
-Disallow: /builders
-Disallow: /grid
-Disallow: /tgrid
diff --git a/yocto-controller/templates/README.txt b/yocto-controller/templates/README.txt
deleted file mode 100644
index 78201578..00000000
--- a/yocto-controller/templates/README.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is the directory to place customized templates for webstatus.
-
-You can find the sources for the templates used in:
-buildbot/status/web/templates
-
-You can copy any of those files to this directory, make changes, and buildbot will automatically
-use your modified templates.
-
-Also of note is that you will not need to restart/reconfig buildbot master to have these changes take effect.
-
-The syntax of the templates is Jinja2:
-http://jinja.pocoo.org/ \ No newline at end of file
diff --git a/yocto-controller/yoctoABConfig.py b/yocto-controller/yoctoABConfig.py
deleted file mode 100644
index ea937d4f..00000000
--- a/yocto-controller/yoctoABConfig.py
+++ /dev/null
@@ -1,20 +0,0 @@
-'''
-Created on Dec 29, 2012
-
-__author__ = "Elizabeth 'pidge' Flanagan"
-__copyright__ = "Copyright 2012-2013, Intel Corp."
-__credits__ = ["Elizabeth Flanagan"]
-__license__ = "GPL"
-__version__ = "2.0"
-__maintainer__ = "Elizabeth Flanagan"
-__email__ = "elizabeth.flanagan@intel.com"
-'''
-
-if __name__ == '__main__':
- from Autobuilder import Autobuilder
-
-
- yocto_buildsets = Autobuilder()
- yocto_buildsets.parseConfig()
- yocto_buildsets.createBuildsets()
-
diff --git a/yocto-start-autobuilder b/yocto-start-autobuilder
deleted file mode 100755
index 85b748d5..00000000
--- a/yocto-start-autobuilder
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python
-#
-# Yocto Build Server Start Script
-# Elizabeth Flanagan <elizabeth.flanagan@intel.com>
-#
-##
-# Copyright (C) 2011-2012 Intel Corp.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import os, sys, optparse, subprocess, datetime
-from socket import gethostname
-import ConfigParser
-
-usage = """%prog [options] controller|worker|both
-
-Start a yocto buildbot autobuilder instance.
-"""
-
-parser = optparse.OptionParser(usage=usage)
-options, args = parser.parse_args( sys.argv )
-
-if len(args) != 2 or (sys.argv[1] != "both" and sys.argv[1] != "controller" and sys.argv[1] != "worker") :
- parser.error("""
- You must specify if you wish to start controller, worker or both.
-
- """ + usage )
-AB_BASE=os.path.dirname(os.path.abspath(sys.argv[0]))
-
-################################################################################
-#
-# We need to check if they've run setup before. If they haven't, we fail out.
-#
-################################################################################
-if os.path.isfile(os.path.join(AB_BASE, ".setupdone")):
-
- from ConfigParser import SafeConfigParser
-
- parser = SafeConfigParser()
- parser.read('config/autobuilder.conf')
- print
- print "Reading " + os.path.join(AB_BASE, "config/autobuilder.conf")
- print
- os.environ["WORKERBASEDIR"] = AB_BASE.strip('"') + "/yocto-worker"
- print ' Setting %s to %s' % ("WORKERBASEDIR", AB_BASE + "/yocto-worker")
- for section_name in parser.sections():
- for name, value in parser.items(section_name):
- print ' Setting %s to %s' % (name.upper(), value)
- os.environ[name.upper()] = value.strip('"').strip("'")
- if os.environ[name.upper()].endswith("_DIR"):
- if not os.path.exists(value):
- try:
- os.mkdirs(value)
- print ' Creating %s at %s' % (name.upper(), value)
- except:
- pass
- print
-
- if sys.argv[1] == "controller" or sys.argv[1] == "both":
- os.chdir(os.path.join(AB_BASE, "yocto-controller"))
- subprocess.call(["make", "start"])
- os.chdir(AB_BASE)
-
- if sys.argv[1] == "worker" or sys.argv[1] == "both":
- if os.environ["PRSERV_HOST"] and os.environ["PRSERV_HOST"] == "localhost":
- os.chdir(AB_BASE)
- subprocess.call([os.path.join(AB_BASE, "ab-prserv"), "start"])
- os.chdir(os.path.join(AB_BASE, "yocto-worker"))
- subprocess.call(["make", "start"])
- os.chdir(AB_BASE)
- if os.environ["OPTIMIZED_GIT_CLONE"] == "True":
- os.chdir(AB_BASE)
- janitor_log = open('yocto-worker/janitor.log', 'a')
- janitor_log.write('[ janitor started: %s ]' % datetime.datetime.now())
- janitor_log.write('\n')
- subprocess.Popen("python bin/buildworker-janitor " + os.path.join(AB_BASE, "config/autobuilder.conf"),
- shell=True, stdin=None,
- stdout=janitor_log,
- stderr=janitor_log,
- close_fds=True)
- janitor_log.close()
-else:
- print "You have not sourced ./yocto-autobuilder-setup. Please do so first!"
- print ""
- print " . ./yocto-autobuilder-setup"
- sys.exit(1)
-
diff --git a/yocto-stop-autobuilder b/yocto-stop-autobuilder
deleted file mode 100755
index c19db23e..00000000
--- a/yocto-stop-autobuilder
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-#
-# Yocto Build Server Stop Script
-# Elizabeth Flanagan <elizabeth.flanagan@intel.com>
-#
-##
-# Copyright (C) 2011-2012 Intel Corp.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import os, sys, optparse, subprocess, signal, time
-from socket import gethostname
-from ConfigParser import SafeConfigParser
-
-usage = """%prog [options] controller|worker|both
-
-Stop a yocto buildbot autobuilder instance.
-"""
-
-parser = optparse.OptionParser(usage=usage)
-options, args = parser.parse_args( sys.argv )
-
-if len(args) != 2 or (sys.argv[1] != "both" and sys.argv[1] != "controller" and sys.argv[1] != "worker") :
- parser.error("""
- You must specify if you wish to stop controller, worker or both.
-
- """ + usage )
-
-AB_BASE=os.path.dirname(os.path.abspath(sys.argv[0]))
-
-parser = SafeConfigParser()
-parser.read('config/autobuilder.conf')
-os.environ["WORKERBASEDIR"] = AB_BASE.strip('"') + "/yocto-worker"
-print ' Setting %s to %s' % ("WORKERBASEDIR", AB_BASE + "/yocto-worker")
-for section_name in parser.sections():
- for name, value in parser.items(section_name):
- os.environ[name.upper()] = value.strip('"').strip("'")
-
-
-def killpid(pidfile):
- if os.path.exists(pidfile) and os.path.isfile(pidfile):
- print("A prior PID file exists. Attempting to kill.")
- with open(pidfile, 'r') as f:
- pid=f.readline()
- try:
- os.kill(int(pid), signal.SIGKILL)
- # We need to sleep for a second or two just to give the SIGKILL time
- time.sleep(2)
- except OSError as ex:
- print("""We weren't able to kill the owner of %s, trying again.""" % pidfile)
- pass
- # Check if the process that we killed is alive.
- try:
- os.kill(int(pid), 0)
- raise Exception("""wasn't able to kill the process
- HINT:use signal.SIGKILL or signal.SIGABORT""")
- except OSError as ex:
- pass
- elif os.path.exists(pidfile) and not os.path.isfile(pidfile):
- raise Exception(pidfile + """ is a directory. Remove it to continue.""")
- try:
- os.unlink(pidfile)
- except:
- pass
-
-if sys.argv[1] == "controller" or sys.argv[1] == "both":
- os.chdir(os.path.join(AB_BASE, "yocto-controller"))
- subprocess.call(["make", "stop"])
- os.chdir(AB_BASE)
-
-
-if sys.argv[1] == "worker" or sys.argv[1] == "both":
- if os.environ["PRSERV_HOST"] and os.environ["PRSERV_HOST"] == "localhost":
- os.chdir(AB_BASE)
- subprocess.call([os.path.join(AB_BASE, "ab-prserv"), "stop"])
-
- os.chdir(os.path.join(AB_BASE, "yocto-worker"))
- subprocess.call(["make", "stop"])
- os.chdir(AB_BASE)
- tmpfile = '/tmp/.buildworker-janitor'+os.getcwd().replace('/', '-')
- killpid(tmpfile)
-
diff --git a/yocto-worker/Makefile b/yocto-worker/Makefile
deleted file mode 100644
index e90cc2f1..00000000
--- a/yocto-worker/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-
-# This is a simple makefile which lives in a buildmaster
-# directory (next to the buildbot.tac file). It allows you to start/stop the
-# master by doing 'make start' or 'make stop'.
-
-# The 'reconfig' target will tell a buildmaster to reload its config file.
-
-start:
- twistd --no_save -y buildbot.tac
-
-stop:
- if [ -e twistd.pid ]; \
- then kill `cat twistd.pid`; \
- else echo "Nothing to stop."; \
- fi
-
-reconfig:
- if [ -e twistd.pid ]; \
- then kill -HUP `cat twistd.pid`; \
- else echo "Nothing to reconfig."; \
- fi
-
-log:
- if [ -e twistd.log ]; \
- then tail -f twistd.log; \
- else echo "Nothing to tail."; \
- fi
-
diff --git a/yocto-worker/buildbot.tac.example b/yocto-worker/buildbot.tac.example
deleted file mode 100644
index c6839aa8..00000000
--- a/yocto-worker/buildbot.tac.example
+++ /dev/null
@@ -1,49 +0,0 @@
-import os
-
-from twisted.application import service
-from buildslave.bot import BuildSlave
-
-basedir = r'.'
-rotateLength = 10000000
-maxRotatedFiles = 10
-
-# if this is a relocatable tac file, get the directory containing the TAC
-if basedir == '.':
- import os.path
- basedir = os.path.abspath(os.path.dirname(__file__))
-
-# note: this line is matched against to check that this is a buildslave
-# directory; do not edit it.
-application = service.Application('buildslave')
-
-try:
- from twisted.python.logfile import LogFile
- from twisted.python.log import ILogObserver, FileLogObserver
- logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
- maxRotatedFiles=maxRotatedFiles)
- application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
-except ImportError:
- # probably not yet twisted 8.2.0 and beyond, can't set log yet
- pass
-
-###################
-# WORKER SETTINGS #
-###################
-
-buildmaster_host = 'localhost' #example: 'builder1.myproject.org'
-port = 9989 # same value as workerPortNum
-workername = 'example-worker' # same as c['workers'] example-worker
-passwd = '<PASS>' # same as c['workers'] <PASS>
-keepalive = 600
-usepty = 0
-umask = 022
-maxdelay = 300
-
-####################
-# /WORKER SETTINGS #
-####################
-
-s = BuildSlave(buildmaster_host, port, workername, passwd, basedir,
- keepalive, usepty, umask=umask, maxdelay=maxdelay)
-s.setServiceParent(application)
-